From 434d6067d9c0f11f7473fc853c170d88e80e2590 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Tue, 22 Sep 2020 02:25:22 +0200 Subject: [PATCH] Imported Upstream version 1.5.1 --- AUTHORS | 20 + CHANGELOG | 92 + KNOWN_ISSUES | 8 + LICENSE | 35 + Makefile | 349 + README.md | 13 + Vagrantfile | 129 + bin/cpplint.py | 2725 + bin/protoc-gen-pbrpc | 4 + bin/protoc-gen-pbrpccpp | 4 + bin/toggle_jcip_annnotations.sh | 78 + bin/umount.xtreemfs | 12 + bin/xtfs_benchmark | 54 + bin/xtfs_chstatus | 46 + bin/xtfs_cleanup | 46 + bin/xtfs_mrcdbtool | 46 + bin/xtfs_remove_osd | 46 + bin/xtfs_scrub | 46 + contrib/benchmark/benchmark.sh | 403 + contrib/benchmark/drop_caches | 3 + .../filter_files.xslt | 69 + contrib/ganglia-plugin/.project | 17 + contrib/ganglia-plugin/.pydevproject | 10 + contrib/ganglia-plugin/README.txt | 6 + .../config-files/xtfs-dir.pyconf | 61 + .../config-files/xtfs-mrc.pyconf | 56 + .../config-files/xtfs-osd.pyconf | 107 + contrib/ganglia-plugin/src/xtfs-dir-plugin.py | 250 + contrib/ganglia-plugin/src/xtfs-mrc-plugin.py | 221 + contrib/ganglia-plugin/src/xtfs-osd-plugin.py | 477 + contrib/osd-health/osd_health_check.sh | 37 + .../BabuDB_replication_plugin.jar | Bin 0 -> 757620 bytes contrib/server-repl-plugin/LICENSE | 32 + contrib/server-repl-plugin/README | 3 + .../server-repl-plugin/config/dir.properties | 82 + .../server-repl-plugin/config/mrc.properties | 82 + .../update_BabuDB_replication_plugin_jar.sh | 60 + contrib/travis/parse_results.py | 34 + contrib/vagrant/provision.sh | 7 + contrib/xtreemfs-osd-farm/xtreemfs-osd-farm | 223 + cpp/CMakeLists.txt | 397 + cpp/Doxyfile | 1623 + cpp/cmake/FindValgrind.cmake | 18 + cpp/cpp_prj/.dep.inc | 5 + cpp/cpp_prj/cpp_prj-Makefile.mk | 128 + cpp/cpp_prj/nbproject/Makefile-Default.mk | 66 + cpp/cpp_prj/nbproject/Makefile-impl.mk | 133 + cpp/cpp_prj/nbproject/Makefile-variables.mk | 16 + cpp/cpp_prj/nbproject/Package-Default.bash | 74 + cpp/cpp_prj/nbproject/configurations.xml | 137 + .../nbproject/private/configurations.xml | 21 + .../nbproject/private/private.properties | 0 cpp/cpp_prj/nbproject/private/private.xml | 7 + cpp/cpp_prj/nbproject/project.properties | 0 cpp/cpp_prj/nbproject/project.xml | 23 + cpp/generated/include/Common.pb.cc | 438 + cpp/generated/include/Common.pb.h | 212 + cpp/generated/include/PBRPC.pb.cc | 111 + cpp/generated/include/PBRPC.pb.h | 78 + cpp/generated/pbrpc/Ping.pb.cc | 1529 + cpp/generated/pbrpc/Ping.pb.h | 911 + cpp/generated/pbrpc/PingServiceClient.h | 79 + cpp/generated/pbrpc/PingServiceConstants.h | 18 + cpp/generated/pbrpc/RPC.pb.cc | 2293 + cpp/generated/pbrpc/RPC.pb.h | 1687 + cpp/generated/xtreemfs/DIR.pb.cc | 5586 ++ cpp/generated/xtreemfs/DIR.pb.h | 3602 ++ cpp/generated/xtreemfs/DIRServiceClient.h | 405 + cpp/generated/xtreemfs/DIRServiceConstants.h | 32 + cpp/generated/xtreemfs/GlobalTypes.pb.cc | 3991 ++ cpp/generated/xtreemfs/GlobalTypes.pb.h | 2713 + cpp/generated/xtreemfs/MRC.pb.cc | 18740 ++++++ cpp/generated/xtreemfs/MRC.pb.h | 14469 +++++ cpp/generated/xtreemfs/MRCServiceClient.h | 981 + cpp/generated/xtreemfs/MRCServiceConstants.h | 57 + cpp/generated/xtreemfs/OSD.pb.cc | 13946 +++++ cpp/generated/xtreemfs/OSD.pb.h | 9181 +++ cpp/generated/xtreemfs/OSDServiceClient.h | 838 + cpp/generated/xtreemfs/OSDServiceConstants.h | 51 + cpp/generated/xtreemfs/get_request_message.cc | 420 + cpp/generated/xtreemfs/get_request_message.h | 24 + cpp/include/cbfs/cbfs_adapter.h | 274 + cpp/include/cbfs/cbfs_enumeration_context.h | 39 + cpp/include/cbfs/cbfs_options.h | 51 + cpp/include/fuse/cached_directory_entries.h | 31 + cpp/include/fuse/fuse_adapter.h | 160 + cpp/include/fuse/fuse_operations.h | 106 + cpp/include/fuse/fuse_options.h | 70 + cpp/include/json/json-forwards.h | 249 + cpp/include/json/json.h | 1856 + cpp/include/ld_preload/environment.h | 47 + cpp/include/ld_preload/misc.h | 58 + cpp/include/ld_preload/open_file_table.h | 61 + cpp/include/ld_preload/passthrough.h | 79 + cpp/include/ld_preload/path.h | 29 + cpp/include/ld_preload/preload.h | 39 + cpp/include/ld_preload/preload_options.h | 45 + cpp/include/libxtreemfs/async_write_buffer.h | 90 + cpp/include/libxtreemfs/async_write_handler.h | 300 + cpp/include/libxtreemfs/client.h | 192 + .../libxtreemfs/client_implementation.h | 184 + .../libxtreemfs/container_uuid_iterator.h | 73 + .../libxtreemfs/execute_sync_request.h | 117 + cpp/include/libxtreemfs/file_handle.h | 249 + .../libxtreemfs/file_handle_implementation.h | 384 + cpp/include/libxtreemfs/file_info.h | 348 + cpp/include/libxtreemfs/helper.h | 153 + cpp/include/libxtreemfs/interrupt.h | 36 + cpp/include/libxtreemfs/metadata_cache.h | 198 + .../libxtreemfs/metadata_cache_entry.h | 45 + cpp/include/libxtreemfs/object_cache.h | 152 + cpp/include/libxtreemfs/options.h | 326 + cpp/include/libxtreemfs/pbrpc_url.h | 82 + .../libxtreemfs/simple_uuid_iterator.h | 42 + cpp/include/libxtreemfs/stripe_translator.h | 97 + cpp/include/libxtreemfs/system_user_mapping.h | 66 + .../libxtreemfs/system_user_mapping_unix.h | 46 + .../libxtreemfs/system_user_mapping_windows.h | 24 + cpp/include/libxtreemfs/typedefs.h | 55 + cpp/include/libxtreemfs/user_mapping.h | 74 + .../libxtreemfs/user_mapping_gridmap.h | 120 + .../libxtreemfs/user_mapping_gridmap_globus.h | 28 + .../user_mapping_gridmap_unicore.h | 44 + cpp/include/libxtreemfs/user_mapping_unix.h | 46 + cpp/include/libxtreemfs/uuid_cache.h | 41 + cpp/include/libxtreemfs/uuid_container.h | 63 + cpp/include/libxtreemfs/uuid_item.h | 54 + cpp/include/libxtreemfs/uuid_iterator.h | 84 + cpp/include/libxtreemfs/uuid_resolver.h | 58 + cpp/include/libxtreemfs/version_management.h | 13 + cpp/include/libxtreemfs/vivaldi.h | 121 + cpp/include/libxtreemfs/vivaldi_node.h | 73 + cpp/include/libxtreemfs/volume.h | 523 + .../libxtreemfs/volume_implementation.h | 406 + cpp/include/libxtreemfs/xcap_handler.h | 29 + cpp/include/libxtreemfs/xtreemfs_exception.h | 153 + cpp/include/lsfs.xtreemfs/lsfs_options.h | 59 + cpp/include/mkfs.xtreemfs/mkfs_options.h | 116 + cpp/include/rmfs.xtreemfs/rmfs_options.h | 62 + cpp/include/rpc/abstract_socket_channel.h | 52 + cpp/include/rpc/callback_interface.h | 65 + cpp/include/rpc/client.h | 160 + cpp/include/rpc/client_connection.h | 161 + cpp/include/rpc/client_request.h | 211 + .../rpc/client_request_callback_interface.h | 25 + cpp/include/rpc/grid_ssl_socket_channel.h | 105 + cpp/include/rpc/record_marker.h | 43 + cpp/include/rpc/ssl_options.h | 117 + cpp/include/rpc/ssl_socket_channel.h | 104 + cpp/include/rpc/sync_callback.h | 96 + cpp/include/rpc/tcp_socket_channel.h | 72 + cpp/include/util/annotations.h | 48 + cpp/include/util/error_log.h | 57 + cpp/include/util/logging.h | 68 + cpp/include/util/synchronized_queue.h | 61 + cpp/include/util/zipf_generator.h | 45 + cpp/include/xtfsutil/xtfsutil_server.h | 244 + cpp/src/cbfs/cbfs_adapter.cpp | 1208 + cpp/src/cbfs/cbfs_enumeration_context.cpp | 21 + cpp/src/cbfs/cbfs_options.cpp | 109 + cpp/src/cbfs/mount.xtreemfs.cpp | 90 + .../example_libxtreemfs.cpp | 119 + .../example_replication.cpp | 171 + cpp/src/fuse/fuse_adapter.cpp | 1618 + cpp/src/fuse/fuse_operations.cpp | 407 + cpp/src/fuse/fuse_options.cpp | 261 + cpp/src/fuse/mount.xtreemfs.cpp | 283 + cpp/src/json/jsoncpp.cpp | 4230 ++ cpp/src/ld_preload/environment.cpp | 118 + cpp/src/ld_preload/functions.cpp | 377 + cpp/src/ld_preload/misc.cpp | 97 + cpp/src/ld_preload/open_file_table.cpp | 101 + cpp/src/ld_preload/passthrough.cpp | 94 + cpp/src/ld_preload/path.cpp | 38 + cpp/src/ld_preload/preload.cpp | 300 + cpp/src/ld_preload/preload_options.cpp | 94 + cpp/src/libxtreemfs/async_write_buffer.cpp | 58 + cpp/src/libxtreemfs/async_write_handler.cpp | 663 + cpp/src/libxtreemfs/client.cpp | 69 + cpp/src/libxtreemfs/client_implementation.cpp | 567 + .../libxtreemfs/container_uuid_iterator.cpp | 56 + cpp/src/libxtreemfs/execute_sync_request.cpp | 478 + .../file_handle_implementation.cpp | 1293 + cpp/src/libxtreemfs/file_info.cpp | 505 + cpp/src/libxtreemfs/helper.cpp | 583 + cpp/src/libxtreemfs/interrupt.cpp | 35 + cpp/src/libxtreemfs/metadata_cache.cpp | 1008 + cpp/src/libxtreemfs/metadata_cache_entry.cpp | 22 + cpp/src/libxtreemfs/object_cache.cpp | 271 + cpp/src/libxtreemfs/options.cpp | 730 + cpp/src/libxtreemfs/pbrpc_url.cpp | 117 + cpp/src/libxtreemfs/simple_uuid_iterator.cpp | 114 + cpp/src/libxtreemfs/stripe_translator.cpp | 77 + cpp/src/libxtreemfs/system_user_mapping.cpp | 43 + .../libxtreemfs/system_user_mapping_unix.cpp | 295 + .../system_user_mapping_windows.cpp | 57 + cpp/src/libxtreemfs/user_mapping.cpp | 39 + cpp/src/libxtreemfs/user_mapping_gridmap.cpp | 216 + .../user_mapping_gridmap_globus.cpp | 107 + .../user_mapping_gridmap_unicore.cpp | 154 + cpp/src/libxtreemfs/uuid_cache.cpp | 78 + cpp/src/libxtreemfs/uuid_container.cpp | 82 + cpp/src/libxtreemfs/uuid_iterator.cpp | 85 + cpp/src/libxtreemfs/vivaldi.cpp | 498 + cpp/src/libxtreemfs/vivaldi_node.cpp | 263 + cpp/src/libxtreemfs/volume_implementation.cpp | 1603 + cpp/src/lsfs.xtreemfs/lsfs.xtreemfs.cpp | 100 + cpp/src/lsfs.xtreemfs/lsfs_options.cpp | 116 + cpp/src/mkfs.xtreemfs/mkfs.xtreemfs.cpp | 239 + cpp/src/mkfs.xtreemfs/mkfs_options.cpp | 280 + cpp/src/rmfs.xtreemfs/rmfs.xtreemfs.cpp | 141 + cpp/src/rmfs.xtreemfs/rmfs_options.cpp | 127 + cpp/src/rpc/client.cpp | 845 + cpp/src/rpc/client_connection.cpp | 608 + cpp/src/rpc/client_request.cpp | 113 + cpp/src/rpc/record_marker.cpp | 60 + cpp/src/rpc/sync_callback.cpp | 77 + cpp/src/util/error_log.cpp | 31 + cpp/src/util/logging.cpp | 175 + cpp/src/util/zipf_generator.cpp | 76 + cpp/src/xtfsutil/xtfsutil.cpp | 1298 + cpp/src/xtfsutil/xtfsutil_server.cpp | 805 + cpp/test/common/drop_rules.h | 131 + cpp/test/common/test_environment.cpp | 108 + cpp/test/common/test_environment.h | 59 + cpp/test/common/test_rpc_server.h | 590 + cpp/test/common/test_rpc_server_dir.cpp | 144 + cpp/test/common/test_rpc_server_dir.h | 72 + cpp/test/common/test_rpc_server_mrc.cpp | 146 + cpp/test/common/test_rpc_server_mrc.h | 82 + cpp/test/common/test_rpc_server_osd.cpp | 146 + cpp/test/common/test_rpc_server_osd.h | 97 + cpp/test/fuse/fuse_options_test.cpp | 84 + cpp/test/ld_preload/cp.sh | 4 + cpp/test/ld_preload/preload_test.cpp | 71 + cpp/test/ld_preload/preload_test.sh | 4 + cpp/test/ld_preload/setfattr.sh | 4 + .../libxtreemfs/async_write_handler_test.cpp | 249 + .../client_implementation_test.cpp | 180 + cpp/test/libxtreemfs/helper_test.cpp | 92 + cpp/test/libxtreemfs/metadata_cache_test.cpp | 335 + cpp/test/libxtreemfs/object_cache_test.cpp | 292 + cpp/test/libxtreemfs/options_test.cpp | 91 + cpp/test/libxtreemfs/pbprpc_url_test.cpp | 222 + .../system_user_mapping_unix_test.cpp | 206 + .../user_mapping_gridmap_globus_test.cpp | 137 + .../user_mapping_gridmap_unicore_test.cpp | 224 + cpp/test/libxtreemfs/uuid_iterator_test.cpp | 337 + .../volume_implementation_test.cpp | 1042 + cpp/test/rpc/client_ssl_test.cpp | 1199 + cpp/test/rpc/client_test.cpp | 167 + cpp/thirdparty/gtest-1.7.0/CHANGES | 157 + cpp/thirdparty/gtest-1.7.0/CMakeLists.txt | 252 + cpp/thirdparty/gtest-1.7.0/CONTRIBUTORS | 37 + cpp/thirdparty/gtest-1.7.0/LICENSE | 28 + cpp/thirdparty/gtest-1.7.0/Makefile.am | 306 + cpp/thirdparty/gtest-1.7.0/Makefile.in | 1360 + cpp/thirdparty/gtest-1.7.0/README | 435 + cpp/thirdparty/gtest-1.7.0/aclocal.m4 | 1198 + .../gtest-1.7.0/build-aux/config.guess | 1530 + .../gtest-1.7.0/build-aux/config.h.in | 69 + .../gtest-1.7.0/build-aux/config.sub | 1773 + cpp/thirdparty/gtest-1.7.0/build-aux/depcomp | 688 + .../gtest-1.7.0/build-aux/install-sh | 527 + .../gtest-1.7.0/build-aux/ltmain.sh | 9661 +++ cpp/thirdparty/gtest-1.7.0/build-aux/missing | 331 + .../gtest-1.7.0/cmake/internal_utils.cmake | 227 + .../gtest-1.7.0/codegear/gtest.cbproj | 138 + .../gtest-1.7.0/codegear/gtest.groupproj | 54 + .../gtest-1.7.0/codegear/gtest_all.cc | 38 + .../gtest-1.7.0/codegear/gtest_link.cc | 40 + .../gtest-1.7.0/codegear/gtest_main.cbproj | 82 + .../codegear/gtest_unittest.cbproj | 88 + cpp/thirdparty/gtest-1.7.0/configure | 18222 ++++++ cpp/thirdparty/gtest-1.7.0/configure.ac | 68 + .../gtest-1.7.0/fused-src/gtest/gtest-all.cc | 9592 +++ .../gtest-1.7.0/fused-src/gtest/gtest.h | 20061 +++++++ .../gtest-1.7.0/fused-src/gtest/gtest_main.cc | 38 + .../include/gtest/gtest-death-test.h | 294 + .../gtest-1.7.0/include/gtest/gtest-message.h | 250 + .../include/gtest/gtest-param-test.h | 1421 + .../include/gtest/gtest-param-test.h.pump | 487 + .../include/gtest/gtest-printers.h | 855 + .../gtest-1.7.0/include/gtest/gtest-spi.h | 232 + .../include/gtest/gtest-test-part.h | 179 + .../include/gtest/gtest-typed-test.h | 259 + .../gtest-1.7.0/include/gtest/gtest.h | 2291 + .../include/gtest/gtest_pred_impl.h | 358 + .../gtest-1.7.0/include/gtest/gtest_prod.h | 58 + .../internal/gtest-death-test-internal.h | 319 + .../include/gtest/internal/gtest-filepath.h | 206 + .../include/gtest/internal/gtest-internal.h | 1158 + .../include/gtest/internal/gtest-linked_ptr.h | 233 + .../internal/gtest-param-util-generated.h | 5143 ++ .../gtest-param-util-generated.h.pump | 301 + .../include/gtest/internal/gtest-param-util.h | 619 + .../include/gtest/internal/gtest-port.h | 1947 + .../include/gtest/internal/gtest-string.h | 167 + .../include/gtest/internal/gtest-tuple.h | 1012 + .../include/gtest/internal/gtest-tuple.h.pump | 339 + .../include/gtest/internal/gtest-type-util.h | 3331 ++ .../gtest/internal/gtest-type-util.h.pump | 297 + cpp/thirdparty/gtest-1.7.0/m4/acx_pthread.m4 | 363 + cpp/thirdparty/gtest-1.7.0/m4/gtest.m4 | 74 + cpp/thirdparty/gtest-1.7.0/m4/libtool.m4 | 8001 +++ cpp/thirdparty/gtest-1.7.0/m4/ltoptions.m4 | 384 + cpp/thirdparty/gtest-1.7.0/m4/ltsugar.m4 | 123 + cpp/thirdparty/gtest-1.7.0/m4/ltversion.m4 | 23 + cpp/thirdparty/gtest-1.7.0/m4/lt~obsolete.m4 | 98 + cpp/thirdparty/gtest-1.7.0/make/Makefile | 82 + cpp/thirdparty/gtest-1.7.0/msvc/gtest-md.sln | 45 + .../gtest-1.7.0/msvc/gtest-md.vcproj | 126 + cpp/thirdparty/gtest-1.7.0/msvc/gtest.sln | 45 + cpp/thirdparty/gtest-1.7.0/msvc/gtest.vcproj | 126 + .../gtest-1.7.0/msvc/gtest_main-md.vcproj | 129 + .../gtest-1.7.0/msvc/gtest_main.vcproj | 129 + .../msvc/gtest_prod_test-md.vcproj | 164 + .../gtest-1.7.0/msvc/gtest_prod_test.vcproj | 164 + .../gtest-1.7.0/msvc/gtest_unittest-md.vcproj | 147 + .../gtest-1.7.0/msvc/gtest_unittest.vcproj | 147 + .../gtest-1.7.0/samples/prime_tables.h | 123 + cpp/thirdparty/gtest-1.7.0/samples/sample1.cc | 68 + cpp/thirdparty/gtest-1.7.0/samples/sample1.h | 43 + .../gtest-1.7.0/samples/sample10_unittest.cc | 144 + .../gtest-1.7.0/samples/sample1_unittest.cc | 153 + cpp/thirdparty/gtest-1.7.0/samples/sample2.cc | 56 + cpp/thirdparty/gtest-1.7.0/samples/sample2.h | 85 + .../gtest-1.7.0/samples/sample2_unittest.cc | 109 + .../gtest-1.7.0/samples/sample3-inl.h | 172 + .../gtest-1.7.0/samples/sample3_unittest.cc | 151 + cpp/thirdparty/gtest-1.7.0/samples/sample4.cc | 46 + cpp/thirdparty/gtest-1.7.0/samples/sample4.h | 53 + .../gtest-1.7.0/samples/sample4_unittest.cc | 45 + .../gtest-1.7.0/samples/sample5_unittest.cc | 199 + .../gtest-1.7.0/samples/sample6_unittest.cc | 224 + .../gtest-1.7.0/samples/sample7_unittest.cc | 130 + .../gtest-1.7.0/samples/sample8_unittest.cc | 173 + .../gtest-1.7.0/samples/sample9_unittest.cc | 160 + .../gtest-1.7.0/scripts/fuse_gtest_files.py | 250 + .../scripts/gen_gtest_pred_impl.py | 730 + .../gtest-1.7.0/scripts/gtest-config.in | 274 + cpp/thirdparty/gtest-1.7.0/scripts/pump.py | 855 + .../gtest-1.7.0/scripts/test/Makefile | 59 + cpp/thirdparty/gtest-1.7.0/src/gtest-all.cc | 48 + .../gtest-1.7.0/src/gtest-death-test.cc | 1344 + .../gtest-1.7.0/src/gtest-filepath.cc | 382 + .../gtest-1.7.0/src/gtest-internal-inl.h | 1218 + cpp/thirdparty/gtest-1.7.0/src/gtest-port.cc | 805 + .../gtest-1.7.0/src/gtest-printers.cc | 363 + .../gtest-1.7.0/src/gtest-test-part.cc | 110 + .../gtest-1.7.0/src/gtest-typed-test.cc | 110 + cpp/thirdparty/gtest-1.7.0/src/gtest.cc | 5015 ++ cpp/thirdparty/gtest-1.7.0/src/gtest_main.cc | 38 + .../test/gtest-death-test_ex_test.cc | 93 + .../gtest-1.7.0/test/gtest-death-test_test.cc | 1367 + .../gtest-1.7.0/test/gtest-filepath_test.cc | 680 + .../gtest-1.7.0/test/gtest-linked_ptr_test.cc | 154 + .../gtest-1.7.0/test/gtest-listener_test.cc | 310 + .../gtest-1.7.0/test/gtest-message_test.cc | 159 + .../gtest-1.7.0/test/gtest-options_test.cc | 215 + .../test/gtest-param-test2_test.cc | 65 + .../gtest-1.7.0/test/gtest-param-test_test.cc | 904 + .../gtest-1.7.0/test/gtest-param-test_test.h | 57 + .../gtest-1.7.0/test/gtest-port_test.cc | 1253 + .../gtest-1.7.0/test/gtest-printers_test.cc | 1566 + .../gtest-1.7.0/test/gtest-test-part_test.cc | 208 + .../gtest-1.7.0/test/gtest-tuple_test.cc | 320 + .../test/gtest-typed-test2_test.cc | 45 + .../gtest-1.7.0/test/gtest-typed-test_test.cc | 360 + .../gtest-1.7.0/test/gtest-typed-test_test.h | 66 + .../test/gtest-unittest-api_test.cc | 341 + .../gtest-1.7.0/test/gtest_all_test.cc | 47 + .../test/gtest_break_on_failure_unittest.py | 212 + .../test/gtest_break_on_failure_unittest_.cc | 88 + .../test/gtest_catch_exceptions_test.py | 237 + .../test/gtest_catch_exceptions_test_.cc | 311 + .../gtest-1.7.0/test/gtest_color_test.py | 130 + .../gtest-1.7.0/test/gtest_color_test_.cc | 71 + .../gtest-1.7.0/test/gtest_env_var_test.py | 103 + .../gtest-1.7.0/test/gtest_env_var_test_.cc | 126 + .../test/gtest_environment_test.cc | 192 + .../gtest-1.7.0/test/gtest_filter_unittest.py | 633 + .../test/gtest_filter_unittest_.cc | 140 + .../gtest-1.7.0/test/gtest_help_test.py | 172 + .../gtest-1.7.0/test/gtest_help_test_.cc | 46 + .../test/gtest_list_tests_unittest.py | 207 + .../test/gtest_list_tests_unittest_.cc | 157 + .../gtest-1.7.0/test/gtest_main_unittest.cc | 45 + .../test/gtest_no_test_unittest.cc | 56 + .../gtest-1.7.0/test/gtest_output_test.py | 335 + .../gtest-1.7.0/test/gtest_output_test_.cc | 1034 + .../test/gtest_output_test_golden_lin.txt | 720 + .../test/gtest_pred_impl_unittest.cc | 2427 + .../test/gtest_premature_exit_test.cc | 141 + .../gtest-1.7.0/test/gtest_prod_test.cc | 57 + .../gtest-1.7.0/test/gtest_repeat_test.cc | 253 + .../gtest-1.7.0/test/gtest_shuffle_test.py | 325 + .../gtest-1.7.0/test/gtest_shuffle_test_.cc | 103 + .../test/gtest_sole_header_test.cc | 57 + .../gtest-1.7.0/test/gtest_stress_test.cc | 256 + .../gtest-1.7.0/test/gtest_test_utils.py | 320 + .../test/gtest_throw_on_failure_ex_test.cc | 92 + .../test/gtest_throw_on_failure_test.py | 171 + .../test/gtest_throw_on_failure_test_.cc | 72 + .../test/gtest_uninitialized_test.py | 70 + .../test/gtest_uninitialized_test_.cc | 43 + .../gtest-1.7.0/test/gtest_unittest.cc | 7415 +++ .../test/gtest_xml_outfile1_test_.cc | 49 + .../test/gtest_xml_outfile2_test_.cc | 49 + .../test/gtest_xml_outfiles_test.py | 132 + .../test/gtest_xml_output_unittest.py | 307 + .../test/gtest_xml_output_unittest_.cc | 181 + .../gtest-1.7.0/test/gtest_xml_test_utils.py | 194 + cpp/thirdparty/gtest-1.7.0/test/production.cc | 36 + cpp/thirdparty/gtest-1.7.0/test/production.h | 55 + .../xcode/Config/DebugProject.xcconfig | 30 + .../xcode/Config/FrameworkTarget.xcconfig | 17 + .../gtest-1.7.0/xcode/Config/General.xcconfig | 41 + .../xcode/Config/ReleaseProject.xcconfig | 32 + .../xcode/Config/StaticLibraryTarget.xcconfig | 18 + .../xcode/Config/TestTarget.xcconfig | 8 + .../gtest-1.7.0/xcode/Resources/Info.plist | 30 + .../xcode/Samples/FrameworkSample/Info.plist | 28 + .../WidgetFramework.xcodeproj/project.pbxproj | 457 + .../xcode/Samples/FrameworkSample/runtests.sh | 62 + .../xcode/Samples/FrameworkSample/widget.cc | 63 + .../xcode/Samples/FrameworkSample/widget.h | 59 + .../Samples/FrameworkSample/widget_test.cc | 68 + .../gtest-1.7.0/xcode/Scripts/runtests.sh | 65 + .../xcode/Scripts/versiongenerate.py | 100 + .../xcode/gtest.xcodeproj/project.pbxproj | 1135 + cpp/thirdparty/protobuf-2.5.0/CHANGES.txt | 528 + .../protobuf-2.5.0/CONTRIBUTORS.txt | 90 + cpp/thirdparty/protobuf-2.5.0/COPYING.txt | 33 + cpp/thirdparty/protobuf-2.5.0/INSTALL.txt | 237 + cpp/thirdparty/protobuf-2.5.0/Makefile.am | 225 + cpp/thirdparty/protobuf-2.5.0/Makefile.in | 1041 + cpp/thirdparty/protobuf-2.5.0/README.txt | 152 + cpp/thirdparty/protobuf-2.5.0/aclocal.m4 | 1020 + cpp/thirdparty/protobuf-2.5.0/autogen.sh | 41 + cpp/thirdparty/protobuf-2.5.0/config.guess | 1530 + cpp/thirdparty/protobuf-2.5.0/config.h.in | 149 + cpp/thirdparty/protobuf-2.5.0/config.sub | 1773 + cpp/thirdparty/protobuf-2.5.0/configure | 19494 +++++++ cpp/thirdparty/protobuf-2.5.0/configure.ac | 150 + cpp/thirdparty/protobuf-2.5.0/depcomp | 688 + .../protobuf-2.5.0/editors/README.txt | 5 + .../protobuf-2.5.0/editors/proto.vim | 105 + .../protobuf-2.5.0/editors/protobuf-mode.el | 220 + .../protobuf-2.5.0/examples/AddPerson.java | 95 + .../protobuf-2.5.0/examples/ListPeople.java | 50 + .../protobuf-2.5.0/examples/Makefile | 58 + .../protobuf-2.5.0/examples/README.txt | 29 + .../protobuf-2.5.0/examples/add_person.cc | 95 + .../protobuf-2.5.0/examples/add_person.py | 58 + .../protobuf-2.5.0/examples/addressbook.proto | 30 + .../protobuf-2.5.0/examples/list_people.cc | 68 + .../protobuf-2.5.0/examples/list_people.py | 38 + .../generate_descriptor_proto.sh | 33 + cpp/thirdparty/protobuf-2.5.0/gtest/CHANGES | 130 + .../protobuf-2.5.0/gtest/CMakeLists.txt | 250 + .../protobuf-2.5.0/gtest/CONTRIBUTORS | 37 + cpp/thirdparty/protobuf-2.5.0/gtest/LICENSE | 28 + .../protobuf-2.5.0/gtest/Makefile.am | 305 + .../protobuf-2.5.0/gtest/Makefile.in | 1360 + cpp/thirdparty/protobuf-2.5.0/gtest/README | 434 + .../protobuf-2.5.0/gtest/aclocal.m4 | 1198 + .../gtest/build-aux/config.guess | 1530 + .../gtest/build-aux/config.h.in | 69 + .../protobuf-2.5.0/gtest/build-aux/config.sub | 1773 + .../protobuf-2.5.0/gtest/build-aux/depcomp | 688 + .../protobuf-2.5.0/gtest/build-aux/install-sh | 527 + .../protobuf-2.5.0/gtest/build-aux/ltmain.sh | 9661 +++ .../protobuf-2.5.0/gtest/build-aux/missing | 331 + .../gtest/cmake/internal_utils.cmake | 227 + .../gtest/codegear/gtest.cbproj | 138 + .../gtest/codegear/gtest.groupproj | 54 + .../gtest/codegear/gtest_all.cc | 38 + .../gtest/codegear/gtest_link.cc | 40 + .../gtest/codegear/gtest_main.cbproj | 82 + .../gtest/codegear/gtest_unittest.cbproj | 88 + cpp/thirdparty/protobuf-2.5.0/gtest/configure | 18222 ++++++ .../protobuf-2.5.0/gtest/configure.ac | 68 + .../gtest/fused-src/gtest/gtest-all.cc | 9251 +++ .../gtest/fused-src/gtest/gtest.h | 20012 +++++++ .../gtest/fused-src/gtest/gtest_main.cc | 38 + .../gtest/include/gtest/gtest-death-test.h | 294 + .../gtest/include/gtest/gtest-message.h | 230 + .../gtest/include/gtest/gtest-param-test.h | 1421 + .../include/gtest/gtest-param-test.h.pump | 487 + .../gtest/include/gtest/gtest-printers.h | 855 + .../gtest/include/gtest/gtest-spi.h | 232 + .../gtest/include/gtest/gtest-test-part.h | 179 + .../gtest/include/gtest/gtest-typed-test.h | 259 + .../gtest/include/gtest/gtest.h | 2236 + .../gtest/include/gtest/gtest_pred_impl.h | 358 + .../gtest/include/gtest/gtest_prod.h | 58 + .../internal/gtest-death-test-internal.h | 319 + .../include/gtest/internal/gtest-filepath.h | 206 + .../include/gtest/internal/gtest-internal.h | 1171 + .../include/gtest/internal/gtest-linked_ptr.h | 233 + .../internal/gtest-param-util-generated.h | 5143 ++ .../gtest-param-util-generated.h.pump | 301 + .../include/gtest/internal/gtest-param-util.h | 619 + .../gtest/include/gtest/internal/gtest-port.h | 1947 + .../include/gtest/internal/gtest-string.h | 180 + .../include/gtest/internal/gtest-tuple.h | 1012 + .../include/gtest/internal/gtest-tuple.h.pump | 339 + .../include/gtest/internal/gtest-type-util.h | 3332 ++ .../gtest/internal/gtest-type-util.h.pump | 298 + .../protobuf-2.5.0/gtest/m4/acx_pthread.m4 | 363 + .../protobuf-2.5.0/gtest/m4/gtest.m4 | 74 + .../protobuf-2.5.0/gtest/m4/libtool.m4 | 8001 +++ .../protobuf-2.5.0/gtest/m4/ltoptions.m4 | 384 + .../protobuf-2.5.0/gtest/m4/ltsugar.m4 | 123 + .../protobuf-2.5.0/gtest/m4/ltversion.m4 | 23 + .../protobuf-2.5.0/gtest/m4/lt~obsolete.m4 | 98 + .../protobuf-2.5.0/gtest/make/Makefile | 80 + .../protobuf-2.5.0/gtest/msvc/gtest-md.sln | 45 + .../protobuf-2.5.0/gtest/msvc/gtest-md.vcproj | 126 + .../protobuf-2.5.0/gtest/msvc/gtest.sln | 45 + .../protobuf-2.5.0/gtest/msvc/gtest.vcproj | 126 + .../gtest/msvc/gtest_main-md.vcproj | 129 + .../gtest/msvc/gtest_main.vcproj | 129 + .../gtest/msvc/gtest_prod_test-md.vcproj | 164 + .../gtest/msvc/gtest_prod_test.vcproj | 164 + .../gtest/msvc/gtest_unittest-md.vcproj | 147 + .../gtest/msvc/gtest_unittest.vcproj | 147 + .../gtest/samples/prime_tables.h | 123 + .../protobuf-2.5.0/gtest/samples/sample1.cc | 68 + .../protobuf-2.5.0/gtest/samples/sample1.h | 43 + .../gtest/samples/sample10_unittest.cc | 144 + .../gtest/samples/sample1_unittest.cc | 153 + .../protobuf-2.5.0/gtest/samples/sample2.cc | 56 + .../protobuf-2.5.0/gtest/samples/sample2.h | 85 + .../gtest/samples/sample2_unittest.cc | 109 + .../gtest/samples/sample3-inl.h | 172 + .../gtest/samples/sample3_unittest.cc | 151 + .../protobuf-2.5.0/gtest/samples/sample4.cc | 46 + .../protobuf-2.5.0/gtest/samples/sample4.h | 53 + .../gtest/samples/sample4_unittest.cc | 45 + .../gtest/samples/sample5_unittest.cc | 199 + .../gtest/samples/sample6_unittest.cc | 224 + .../gtest/samples/sample7_unittest.cc | 130 + .../gtest/samples/sample8_unittest.cc | 173 + .../gtest/samples/sample9_unittest.cc | 160 + .../gtest/scripts/fuse_gtest_files.py | 250 + .../gtest/scripts/gen_gtest_pred_impl.py | 730 + .../gtest/scripts/gtest-config.in | 274 + .../protobuf-2.5.0/gtest/scripts/pump.py | 855 + .../gtest/scripts/test/Makefile | 59 + .../protobuf-2.5.0/gtest/src/gtest-all.cc | 48 + .../gtest/src/gtest-death-test.cc | 1341 + .../gtest/src/gtest-filepath.cc | 381 + .../gtest/src/gtest-internal-inl.h | 1056 + .../protobuf-2.5.0/gtest/src/gtest-port.cc | 805 + .../gtest/src/gtest-printers.cc | 364 + .../gtest/src/gtest-test-part.cc | 110 + .../gtest/src/gtest-typed-test.cc | 110 + .../protobuf-2.5.0/gtest/src/gtest.cc | 4838 ++ .../protobuf-2.5.0/gtest/src/gtest_main.cc | 38 + .../gtest/test/gtest-death-test_ex_test.cc | 93 + .../gtest/test/gtest-death-test_test.cc | 1368 + .../gtest/test/gtest-filepath_test.cc | 680 + .../gtest/test/gtest-linked_ptr_test.cc | 154 + .../gtest/test/gtest-listener_test.cc | 310 + .../gtest/test/gtest-message_test.cc | 159 + .../gtest/test/gtest-options_test.cc | 215 + .../gtest/test/gtest-param-test2_test.cc | 65 + .../gtest/test/gtest-param-test_test.cc | 897 + .../gtest/test/gtest-param-test_test.h | 57 + .../gtest/test/gtest-port_test.cc | 1253 + .../gtest/test/gtest-printers_test.cc | 1561 + .../gtest/test/gtest-test-part_test.cc | 208 + .../gtest/test/gtest-tuple_test.cc | 320 + .../gtest/test/gtest-typed-test2_test.cc | 45 + .../gtest/test/gtest-typed-test_test.cc | 360 + .../gtest/test/gtest-typed-test_test.h | 66 + .../gtest/test/gtest-unittest-api_test.cc | 341 + .../gtest/test/gtest_all_test.cc | 47 + .../test/gtest_break_on_failure_unittest.py | 218 + .../test/gtest_break_on_failure_unittest_.cc | 88 + .../gtest/test/gtest_catch_exceptions_test.py | 223 + .../test/gtest_catch_exceptions_test_.cc | 311 + .../gtest/test/gtest_color_test.py | 130 + .../gtest/test/gtest_color_test_.cc | 71 + .../gtest/test/gtest_env_var_test.py | 103 + .../gtest/test/gtest_env_var_test_.cc | 126 + .../gtest/test/gtest_environment_test.cc | 192 + .../gtest/test/gtest_filter_unittest.py | 633 + .../gtest/test/gtest_filter_unittest_.cc | 140 + .../gtest/test/gtest_help_test.py | 172 + .../gtest/test/gtest_help_test_.cc | 46 + .../gtest/test/gtest_list_tests_unittest.py | 177 + .../gtest/test/gtest_list_tests_unittest_.cc | 85 + .../gtest/test/gtest_main_unittest.cc | 45 + .../gtest/test/gtest_no_test_unittest.cc | 56 + .../gtest/test/gtest_output_test.py | 335 + .../gtest/test/gtest_output_test_.cc | 1034 + .../test/gtest_output_test_golden_lin.txt | 725 + .../gtest/test/gtest_pred_impl_unittest.cc | 2427 + .../gtest/test/gtest_prod_test.cc | 57 + .../gtest/test/gtest_repeat_test.cc | 253 + .../gtest/test/gtest_shuffle_test.py | 325 + .../gtest/test/gtest_shuffle_test_.cc | 103 + .../gtest/test/gtest_sole_header_test.cc | 57 + .../gtest/test/gtest_stress_test.cc | 256 + .../gtest/test/gtest_test_utils.py | 305 + .../test/gtest_throw_on_failure_ex_test.cc | 92 + .../gtest/test/gtest_throw_on_failure_test.py | 171 + .../test/gtest_throw_on_failure_test_.cc | 72 + .../gtest/test/gtest_uninitialized_test.py | 70 + .../gtest/test/gtest_uninitialized_test_.cc | 43 + .../gtest/test/gtest_unittest.cc | 7240 +++ .../gtest/test/gtest_xml_outfile1_test_.cc | 49 + .../gtest/test/gtest_xml_outfile2_test_.cc | 49 + .../gtest/test/gtest_xml_outfiles_test.py | 132 + .../gtest/test/gtest_xml_output_unittest.py | 284 + .../gtest/test/gtest_xml_output_unittest_.cc | 177 + .../gtest/test/gtest_xml_test_utils.py | 190 + .../protobuf-2.5.0/gtest/test/production.cc | 36 + .../protobuf-2.5.0/gtest/test/production.h | 55 + .../gtest/xcode/Config/DebugProject.xcconfig | 30 + .../xcode/Config/FrameworkTarget.xcconfig | 17 + .../gtest/xcode/Config/General.xcconfig | 41 + .../xcode/Config/ReleaseProject.xcconfig | 32 + .../xcode/Config/StaticLibraryTarget.xcconfig | 18 + .../gtest/xcode/Config/TestTarget.xcconfig | 8 + .../gtest/xcode/Resources/Info.plist | 30 + .../xcode/Samples/FrameworkSample/Info.plist | 28 + .../WidgetFramework.xcodeproj/project.pbxproj | 457 + .../xcode/Samples/FrameworkSample/runtests.sh | 62 + .../xcode/Samples/FrameworkSample/widget.cc | 63 + .../xcode/Samples/FrameworkSample/widget.h | 59 + .../Samples/FrameworkSample/widget_test.cc | 68 + .../gtest/xcode/Scripts/runtests.sh | 65 + .../gtest/xcode/Scripts/versiongenerate.py | 100 + .../xcode/gtest.xcodeproj/project.pbxproj | 1084 + cpp/thirdparty/protobuf-2.5.0/install-sh | 527 + cpp/thirdparty/protobuf-2.5.0/java/README.txt | 96 + cpp/thirdparty/protobuf-2.5.0/java/pom.xml | 205 + .../com/google/protobuf/AbstractMessage.java | 930 + .../google/protobuf/AbstractMessageLite.java | 343 + .../com/google/protobuf/AbstractParser.java | 261 + .../google/protobuf/BlockingRpcChannel.java | 51 + .../com/google/protobuf/BlockingService.java | 64 + .../google/protobuf/BoundedByteString.java | 163 + .../java/com/google/protobuf/ByteString.java | 970 + .../com/google/protobuf/CodedInputStream.java | 920 + .../google/protobuf/CodedOutputStream.java | 1111 + .../java/com/google/protobuf/Descriptors.java | 1970 + .../com/google/protobuf/DynamicMessage.java | 482 + .../google/protobuf/ExtensionRegistry.java | 266 + .../protobuf/ExtensionRegistryLite.java | 185 + .../java/com/google/protobuf/FieldSet.java | 861 + .../com/google/protobuf/GeneratedMessage.java | 1939 + .../google/protobuf/GeneratedMessageLite.java | 797 + .../java/com/google/protobuf/Internal.java | 153 + .../InvalidProtocolBufferException.java | 114 + .../java/com/google/protobuf/LazyField.java | 210 + .../google/protobuf/LazyStringArrayList.java | 178 + .../com/google/protobuf/LazyStringList.java | 81 + .../google/protobuf/LiteralByteString.java | 349 + .../java/com/google/protobuf/Message.java | 237 + .../java/com/google/protobuf/MessageLite.java | 319 + .../google/protobuf/MessageLiteOrBuilder.java | 60 + .../com/google/protobuf/MessageOrBuilder.java | 129 + .../main/java/com/google/protobuf/Parser.java | 259 + .../google/protobuf/ProtocolMessageEnum.java | 58 + .../google/protobuf/RepeatedFieldBuilder.java | 696 + .../com/google/protobuf/RopeByteString.java | 943 + .../java/com/google/protobuf/RpcCallback.java | 47 + .../java/com/google/protobuf/RpcChannel.java | 71 + .../com/google/protobuf/RpcController.java | 118 + .../java/com/google/protobuf/RpcUtil.java | 135 + .../java/com/google/protobuf/Service.java | 117 + .../com/google/protobuf/ServiceException.java | 52 + .../google/protobuf/SingleFieldBuilder.java | 241 + .../com/google/protobuf/SmallSortedMap.java | 618 + .../java/com/google/protobuf/TextFormat.java | 1559 + .../UninitializedMessageException.java | 99 + .../com/google/protobuf/UnknownFieldSet.java | 978 + .../protobuf/UnmodifiableLazyStringList.java | 152 + .../main/java/com/google/protobuf/Utf8.java | 349 + .../java/com/google/protobuf/WireFormat.java | 163 + .../google/protobuf/AbstractMessageTest.java | 509 + .../protobuf/BoundedByteStringTest.java | 68 + .../com/google/protobuf/ByteStringTest.java | 692 + .../google/protobuf/CodedInputStreamTest.java | 528 + .../protobuf/CodedOutputStreamTest.java | 317 + .../google/protobuf/DeprecatedFieldTest.java | 80 + .../com/google/protobuf/DescriptorsTest.java | 648 + .../google/protobuf/DynamicMessageTest.java | 264 + .../protobuf/ForceFieldBuildersPreRun.java | 48 + .../google/protobuf/GeneratedMessageTest.java | 1146 + .../com/google/protobuf/IsValidUtf8Test.java | 180 + .../google/protobuf/IsValidUtf8TestUtil.java | 421 + .../protobuf/LazyStringArrayListTest.java | 162 + .../protobuf/LazyStringEndToEndTest.java | 143 + .../java/com/google/protobuf/LiteTest.java | 148 + .../protobuf/LiteralByteStringTest.java | 396 + .../java/com/google/protobuf/MessageTest.java | 353 + .../google/protobuf/NestedBuildersTest.java | 185 + .../java/com/google/protobuf/ParserTest.java | 375 + .../protobuf/RepeatedFieldBuilderTest.java | 190 + .../protobuf/RopeByteStringSubstringTest.java | 97 + .../google/protobuf/RopeByteStringTest.java | 115 + .../java/com/google/protobuf/ServiceTest.java | 320 + .../protobuf/SingleFieldBuilderTest.java | 155 + .../google/protobuf/SmallSortedMapTest.java | 420 + .../google/protobuf/TestBadIdentifiers.java | 63 + .../java/com/google/protobuf/TestUtil.java | 3955 ++ .../com/google/protobuf/TextFormatTest.java | 786 + .../google/protobuf/UnknownFieldSetTest.java | 437 + .../UnmodifiableLazyStringListTest.java | 152 + .../com/google/protobuf/WireFormatTest.java | 580 + .../google/protobuf/multiple_files_test.proto | 71 + .../protobuf/nested_builders_test.proto | 53 + .../google/protobuf/nested_extension.proto | 45 + .../protobuf/nested_extension_lite.proto | 48 + .../protobuf/non_nested_extension.proto | 48 + .../protobuf/non_nested_extension_lite.proto | 50 + .../protobuf/test_bad_identifiers.proto | 108 + cpp/thirdparty/protobuf-2.5.0/ltmain.sh | 9661 +++ .../protobuf-2.5.0/m4/ac_system_extensions.m4 | 37 + .../protobuf-2.5.0/m4/acx_check_suncc.m4 | 74 + .../protobuf-2.5.0/m4/acx_pthread.m4 | 397 + cpp/thirdparty/protobuf-2.5.0/m4/libtool.m4 | 8001 +++ cpp/thirdparty/protobuf-2.5.0/m4/ltoptions.m4 | 384 + cpp/thirdparty/protobuf-2.5.0/m4/ltsugar.m4 | 123 + cpp/thirdparty/protobuf-2.5.0/m4/ltversion.m4 | 23 + .../protobuf-2.5.0/m4/lt~obsolete.m4 | 98 + cpp/thirdparty/protobuf-2.5.0/m4/stl_hash.m4 | 72 + cpp/thirdparty/protobuf-2.5.0/missing | 331 + .../protobuf-2.5.0/protobuf-lite.pc.in | 13 + cpp/thirdparty/protobuf-2.5.0/protobuf.pc.in | 14 + .../protobuf-2.5.0/python/README.txt | 101 + .../protobuf-2.5.0/python/ez_setup.py | 283 + .../protobuf-2.5.0/python/google/__init__.py | 1 + .../python/google/protobuf/__init__.py | 0 .../python/google/protobuf/descriptor.py | 713 + .../google/protobuf/descriptor_database.py | 120 + .../python/google/protobuf/descriptor_pool.py | 527 + .../google/protobuf/internal/__init__.py | 0 .../protobuf/internal/api_implementation.py | 87 + .../google/protobuf/internal/containers.py | 269 + .../google/protobuf/internal/cpp_message.py | 663 + .../google/protobuf/internal/decoder.py | 720 + .../internal/descriptor_database_test.py | 63 + .../protobuf/internal/descriptor_pool_test.py | 220 + .../protobuf/internal/descriptor_test.py | 613 + .../google/protobuf/internal/encoder.py | 769 + .../protobuf/internal/enum_type_wrapper.py | 89 + .../protobuf/internal/factory_test1.proto | 55 + .../protobuf/internal/factory_test2.proto | 77 + .../protobuf/internal/generator_test.py | 269 + .../protobuf/internal/message_cpp_test.py | 45 + .../protobuf/internal/message_factory_test.py | 113 + .../protobuf/internal/message_listener.py | 78 + .../google/protobuf/internal/message_test.py | 494 + .../protobuf/internal/more_extensions.proto | 58 + .../internal/more_extensions_dynamic.proto | 49 + .../protobuf/internal/more_messages.proto | 51 + .../protobuf/internal/python_message.py | 1150 + .../internal/reflection_cpp_generated_test.py | 91 + .../protobuf/internal/reflection_test.py | 2671 + .../internal/service_reflection_test.py | 136 + .../internal/test_bad_identifiers.proto | 52 + .../google/protobuf/internal/test_util.py | 651 + .../protobuf/internal/text_format_test.py | 617 + .../google/protobuf/internal/type_checkers.py | 286 + .../protobuf/internal/unknown_fields_test.py | 170 + .../google/protobuf/internal/wire_format.py | 268 + .../protobuf/internal/wire_format_test.py | 253 + .../python/google/protobuf/message.py | 280 + .../python/google/protobuf/message_factory.py | 113 + .../google/protobuf/pyext/python-proto2.cc | 1717 + .../protobuf/pyext/python_descriptor.cc | 337 + .../google/protobuf/pyext/python_descriptor.h | 87 + .../google/protobuf/pyext/python_protobuf.cc | 63 + .../google/protobuf/pyext/python_protobuf.h | 57 + .../python/google/protobuf/reflection.py | 169 + .../python/google/protobuf/service.py | 226 + .../google/protobuf/service_reflection.py | 284 + .../python/google/protobuf/text_format.py | 739 + cpp/thirdparty/protobuf-2.5.0/python/mox.py | 1401 + cpp/thirdparty/protobuf-2.5.0/python/setup.py | 196 + .../protobuf-2.5.0/python/stubout.py | 140 + cpp/thirdparty/protobuf-2.5.0/src/Makefile.am | 395 + cpp/thirdparty/protobuf-2.5.0/src/Makefile.in | 3121 + .../protobuf/compiler/code_generator.cc | 80 + .../google/protobuf/compiler/code_generator.h | 142 + .../compiler/command_line_interface.cc | 1437 + .../compiler/command_line_interface.h | 353 + .../command_line_interface_unittest.cc | 1560 + .../compiler/cpp/cpp_bootstrap_unittest.cc | 158 + .../google/protobuf/compiler/cpp/cpp_enum.cc | 258 + .../google/protobuf/compiler/cpp/cpp_enum.h | 101 + .../protobuf/compiler/cpp/cpp_enum_field.cc | 366 + .../protobuf/compiler/cpp/cpp_enum_field.h | 105 + .../protobuf/compiler/cpp/cpp_extension.cc | 210 + .../protobuf/compiler/cpp/cpp_extension.h | 86 + .../google/protobuf/compiler/cpp/cpp_field.cc | 142 + .../google/protobuf/compiler/cpp/cpp_field.h | 177 + .../google/protobuf/compiler/cpp/cpp_file.cc | 652 + .../google/protobuf/compiler/cpp/cpp_file.h | 99 + .../protobuf/compiler/cpp/cpp_generator.cc | 124 + .../protobuf/compiler/cpp/cpp_generator.h | 72 + .../protobuf/compiler/cpp/cpp_helpers.cc | 438 + .../protobuf/compiler/cpp/cpp_helpers.h | 186 + .../protobuf/compiler/cpp/cpp_message.cc | 2020 + .../protobuf/compiler/cpp/cpp_message.h | 171 + .../compiler/cpp/cpp_message_field.cc | 298 + .../protobuf/compiler/cpp/cpp_message_field.h | 104 + .../protobuf/compiler/cpp/cpp_options.h | 58 + .../compiler/cpp/cpp_plugin_unittest.cc | 121 + .../compiler/cpp/cpp_primitive_field.cc | 387 + .../compiler/cpp/cpp_primitive_field.h | 105 + .../protobuf/compiler/cpp/cpp_service.cc | 334 + .../protobuf/compiler/cpp/cpp_service.h | 119 + .../protobuf/compiler/cpp/cpp_string_field.cc | 491 + .../protobuf/compiler/cpp/cpp_string_field.h | 108 + .../cpp/cpp_test_bad_identifiers.proto | 123 + .../protobuf/compiler/cpp/cpp_unittest.cc | 1354 + .../protobuf/compiler/cpp/cpp_unittest.h | 51 + .../src/google/protobuf/compiler/importer.cc | 459 + .../src/google/protobuf/compiler/importer.h | 304 + .../protobuf/compiler/importer_unittest.cc | 600 + .../compiler/java/java_doc_comment.cc | 236 + .../protobuf/compiler/java/java_doc_comment.h | 69 + .../java/java_doc_comment_unittest.cc | 66 + .../protobuf/compiler/java/java_enum.cc | 271 + .../google/protobuf/compiler/java/java_enum.h | 86 + .../protobuf/compiler/java/java_enum_field.cc | 603 + .../protobuf/compiler/java/java_enum_field.h | 123 + .../protobuf/compiler/java/java_extension.cc | 218 + .../protobuf/compiler/java/java_extension.h | 77 + .../protobuf/compiler/java/java_field.cc | 137 + .../protobuf/compiler/java/java_field.h | 109 + .../protobuf/compiler/java/java_file.cc | 490 + .../google/protobuf/compiler/java/java_file.h | 101 + .../protobuf/compiler/java/java_generator.cc | 128 + .../protobuf/compiler/java/java_generator.h | 72 + .../protobuf/compiler/java/java_helpers.cc | 500 + .../protobuf/compiler/java/java_helpers.h | 220 + .../protobuf/compiler/java/java_message.cc | 1435 + .../protobuf/compiler/java/java_message.h | 112 + .../compiler/java/java_message_field.cc | 974 + .../compiler/java/java_message_field.h | 136 + .../compiler/java/java_plugin_unittest.cc | 122 + .../compiler/java/java_primitive_field.cc | 787 + .../compiler/java/java_primitive_field.h | 123 + .../protobuf/compiler/java/java_service.cc | 453 + .../protobuf/compiler/java/java_service.h | 113 + .../compiler/java/java_string_field.cc | 726 + .../compiler/java/java_string_field.h | 122 + .../src/google/protobuf/compiler/main.cc | 61 + .../protobuf/compiler/mock_code_generator.cc | 241 + .../protobuf/compiler/mock_code_generator.h | 117 + .../google/protobuf/compiler/package_info.h | 64 + .../src/google/protobuf/compiler/parser.cc | 1611 + .../src/google/protobuf/compiler/parser.h | 477 + .../protobuf/compiler/parser_unittest.cc | 2374 + .../src/google/protobuf/compiler/plugin.cc | 163 + .../src/google/protobuf/compiler/plugin.h | 72 + .../src/google/protobuf/compiler/plugin.pb.cc | 1090 + .../src/google/protobuf/compiler/plugin.pb.h | 856 + .../src/google/protobuf/compiler/plugin.proto | 147 + .../compiler/python/python_generator.cc | 1157 + .../compiler/python/python_generator.h | 161 + .../compiler/python/python_plugin_unittest.cc | 116 + .../google/protobuf/compiler/subprocess.cc | 463 + .../src/google/protobuf/compiler/subprocess.h | 108 + .../google/protobuf/compiler/test_plugin.cc | 51 + .../protobuf/compiler/zip_output_unittest.sh | 91 + .../google/protobuf/compiler/zip_writer.cc | 218 + .../src/google/protobuf/compiler/zip_writer.h | 93 + .../src/google/protobuf/descriptor.cc | 4949 ++ .../src/google/protobuf/descriptor.h | 1521 + .../src/google/protobuf/descriptor.pb.cc | 8146 +++ .../src/google/protobuf/descriptor.pb.h | 5992 ++ .../src/google/protobuf/descriptor.proto | 620 + .../google/protobuf/descriptor_database.cc | 541 + .../src/google/protobuf/descriptor_database.h | 367 + .../protobuf/descriptor_database_unittest.cc | 748 + .../google/protobuf/descriptor_unittest.cc | 4656 ++ .../src/google/protobuf/dynamic_message.cc | 571 + .../src/google/protobuf/dynamic_message.h | 136 + .../protobuf/dynamic_message_unittest.cc | 166 + .../src/google/protobuf/extension_set.cc | 1461 + .../src/google/protobuf/extension_set.h | 1007 + .../google/protobuf/extension_set_heavy.cc | 711 + .../google/protobuf/extension_set_unittest.cc | 726 + .../protobuf/generated_enum_reflection.h | 85 + .../protobuf/generated_message_reflection.cc | 1293 + .../protobuf/generated_message_reflection.h | 419 + .../generated_message_reflection_unittest.cc | 484 + .../google/protobuf/generated_message_util.cc | 54 + .../google/protobuf/generated_message_util.h | 77 + .../src/google/protobuf/io/coded_stream.cc | 857 + .../src/google/protobuf/io/coded_stream.h | 1136 + .../src/google/protobuf/io/coded_stream_inl.h | 68 + .../protobuf/io/coded_stream_unittest.cc | 1191 + .../src/google/protobuf/io/gzip_stream.cc | 326 + .../src/google/protobuf/io/gzip_stream.h | 209 + .../protobuf/io/gzip_stream_unittest.sh | 44 + .../src/google/protobuf/io/package_info.h | 54 + .../src/google/protobuf/io/printer.cc | 198 + .../src/google/protobuf/io/printer.h | 136 + .../google/protobuf/io/printer_unittest.cc | 285 + .../src/google/protobuf/io/tokenizer.cc | 1091 + .../src/google/protobuf/io/tokenizer.h | 384 + .../google/protobuf/io/tokenizer_unittest.cc | 1001 + .../google/protobuf/io/zero_copy_stream.cc | 48 + .../src/google/protobuf/io/zero_copy_stream.h | 238 + .../protobuf/io/zero_copy_stream_impl.cc | 471 + .../protobuf/io/zero_copy_stream_impl.h | 357 + .../protobuf/io/zero_copy_stream_impl_lite.cc | 393 + .../protobuf/io/zero_copy_stream_impl_lite.h | 340 + .../protobuf/io/zero_copy_stream_unittest.cc | 944 + .../src/google/protobuf/lite_unittest.cc | 185 + .../src/google/protobuf/message.cc | 358 + .../src/google/protobuf/message.h | 837 + .../src/google/protobuf/message_lite.cc | 334 + .../src/google/protobuf/message_lite.h | 246 + .../src/google/protobuf/message_unittest.cc | 354 + .../src/google/protobuf/package_info.h | 64 + .../src/google/protobuf/reflection_ops.cc | 267 + .../src/google/protobuf/reflection_ops.h | 81 + .../protobuf/reflection_ops_unittest.cc | 405 + .../src/google/protobuf/repeated_field.cc | 87 + .../src/google/protobuf/repeated_field.h | 1519 + .../repeated_field_reflection_unittest.cc | 195 + .../protobuf/repeated_field_unittest.cc | 1357 + .../src/google/protobuf/service.cc | 46 + .../src/google/protobuf/service.h | 291 + .../src/google/protobuf/stubs/atomicops.h | 206 + .../stubs/atomicops_internals_arm_gcc.h | 151 + .../stubs/atomicops_internals_arm_qnx.h | 146 + .../atomicops_internals_atomicword_compat.h | 122 + .../stubs/atomicops_internals_macosx.h | 225 + .../stubs/atomicops_internals_mips_gcc.h | 187 + .../stubs/atomicops_internals_pnacl.h | 73 + .../stubs/atomicops_internals_x86_gcc.cc | 137 + .../stubs/atomicops_internals_x86_gcc.h | 293 + .../stubs/atomicops_internals_x86_msvc.cc | 112 + .../stubs/atomicops_internals_x86_msvc.h | 150 + .../src/google/protobuf/stubs/common.cc | 395 + .../src/google/protobuf/stubs/common.h | 1223 + .../google/protobuf/stubs/common_unittest.cc | 357 + .../src/google/protobuf/stubs/hash.h | 232 + .../src/google/protobuf/stubs/map-util.h | 143 + .../src/google/protobuf/stubs/once.cc | 99 + .../src/google/protobuf/stubs/once.h | 148 + .../google/protobuf/stubs/once_unittest.cc | 253 + .../google/protobuf/stubs/platform_macros.h | 70 + .../src/google/protobuf/stubs/stl_util.h | 121 + .../src/google/protobuf/stubs/stringprintf.cc | 175 + .../src/google/protobuf/stubs/stringprintf.h | 76 + .../protobuf/stubs/stringprintf_unittest.cc | 152 + .../protobuf/stubs/structurally_valid.cc | 536 + .../stubs/structurally_valid_unittest.cc | 40 + .../src/google/protobuf/stubs/strutil.cc | 1211 + .../src/google/protobuf/stubs/strutil.h | 467 + .../google/protobuf/stubs/strutil_unittest.cc | 83 + .../src/google/protobuf/stubs/substitute.cc | 134 + .../src/google/protobuf/stubs/substitute.h | 170 + .../src/google/protobuf/stubs/template_util.h | 138 + .../protobuf/stubs/template_util_unittest.cc | 130 + .../src/google/protobuf/stubs/type_traits.h | 336 + .../protobuf/stubs/type_traits_unittest.cc | 628 + .../src/google/protobuf/test_util.cc | 3047 + .../src/google/protobuf/test_util.h | 193 + .../src/google/protobuf/test_util_lite.cc | 1548 + .../src/google/protobuf/test_util_lite.h | 101 + .../google/protobuf/testdata/golden_message | Bin 0 -> 509 bytes .../testdata/golden_packed_fields_message | Bin 0 -> 142 bytes .../testdata/text_format_unittest_data.txt | 128 + .../text_format_unittest_extensions_data.txt | 128 + .../src/google/protobuf/testing/file.cc | 176 + .../src/google/protobuf/testing/file.h | 83 + .../src/google/protobuf/testing/googletest.cc | 255 + .../src/google/protobuf/testing/googletest.h | 102 + .../src/google/protobuf/testing/zcgunzip.cc | 73 + .../src/google/protobuf/testing/zcgzip.cc | 79 + .../src/google/protobuf/text_format.cc | 1521 + .../src/google/protobuf/text_format.h | 369 + .../google/protobuf/text_format_unittest.cc | 1248 + .../src/google/protobuf/unittest.proto | 719 + .../protobuf/unittest_custom_options.proto | 387 + .../unittest_embed_optimize_for.proto | 50 + .../src/google/protobuf/unittest_empty.proto | 37 + .../unittest_enormous_descriptor.proto | 1046 + .../src/google/protobuf/unittest_import.proto | 64 + .../protobuf/unittest_import_lite.proto | 51 + .../protobuf/unittest_import_public.proto | 40 + .../unittest_import_public_lite.proto | 42 + .../src/google/protobuf/unittest_lite.proto | 360 + .../unittest_lite_imports_nonlite.proto | 43 + .../src/google/protobuf/unittest_mset.proto | 72 + .../unittest_no_generic_services.proto | 52 + .../protobuf/unittest_optimize_for.proto | 61 + .../src/google/protobuf/unknown_field_set.cc | 266 + .../src/google/protobuf/unknown_field_set.h | 311 + .../protobuf/unknown_field_set_unittest.cc | 594 + .../src/google/protobuf/wire_format.cc | 1063 + .../src/google/protobuf/wire_format.h | 308 + .../src/google/protobuf/wire_format_lite.cc | 361 + .../src/google/protobuf/wire_format_lite.h | 622 + .../google/protobuf/wire_format_lite_inl.h | 776 + .../google/protobuf/wire_format_unittest.cc | 978 + .../protobuf-2.5.0/src/solaris/libstdc++.la | 51 + .../protobuf-2.5.0/vsprojects/config.h | 29 + .../vsprojects/convert2008to2005.sh | 20 + .../vsprojects/extract_includes.bat | 49 + .../vsprojects/libprotobuf-lite.vcproj | 302 + .../vsprojects/libprotobuf.vcproj | 462 + .../vsprojects/libprotoc.vcproj | 426 + .../vsprojects/lite-test.vcproj | 305 + .../protobuf-2.5.0/vsprojects/protobuf.sln | 92 + .../protobuf-2.5.0/vsprojects/protoc.vcproj | 192 + .../protobuf-2.5.0/vsprojects/readme.txt | 114 + .../vsprojects/test_plugin.vcproj | 209 + .../protobuf-2.5.0/vsprojects/tests.vcproj | 681 + cpp/valgrind.supp | 328 + etc/init.d/generate_initd_scripts.sh | 37 + etc/init.d/xtreemfs-service.template | 161 + etc/xos/xtreemfs/datacentermap.example | 7 + etc/xos/xtreemfs/default_dir | 9 + etc/xos/xtreemfs/dirconfig.properties | 154 + etc/xos/xtreemfs/mrcconfig.properties | 190 + etc/xos/xtreemfs/osdconfig.properties | 130 + etc/xos/xtreemfs/snmp.acl | 38 + interface/Makefile | 57 + interface/include/Common.proto | 44 + interface/include/PBRPC.proto | 49 + interface/pbrpc/Ping.proto | 77 + interface/pbrpc/RPC.proto | 167 + interface/xtreemfs/DIR.proto | 281 + interface/xtreemfs/GlobalTypes.proto | 288 + interface/xtreemfs/MRC.proto | 823 + interface/xtreemfs/OSD.proto | 582 + java/flease/build-1.6.5.xml | 75 + java/flease/build.xml | 75 + java/flease/eclipse-project/.classpath | 10 + java/flease/eclipse-project/.project | 18 + java/flease/manifest.mf | 3 + java/flease/nbproject/build-impl-1.6.5.xml | 892 + java/flease/nbproject/build-impl.xml | 1054 + java/flease/nbproject/genfiles.properties | 11 + .../nbproject/private/config.properties | 0 .../nbproject/private/private.properties | 6 + java/flease/nbproject/private/private.xml | 5 + .../private/profiler/configurations.xml | 141 + java/flease/nbproject/profiler-build-impl.xml | 131 + java/flease/nbproject/project.properties | 73 + java/flease/nbproject/project.xml | 24 + java/flease/nbproject/protobuf-build.cfg.xml | 2 + java/flease/nbproject/protobuf-build.xml | 24 + .../xtreemfs/foundation/flease/Flease.java | 93 + .../foundation/flease/FleaseConfig.java | 191 + .../foundation/flease/FleaseFuture.java | 59 + .../flease/FleaseMessageSenderInterface.java | 22 + .../foundation/flease/FleaseStage.java | 691 + .../foundation/flease/FleaseStats.java | 122 + .../flease/FleaseStatusListener.java | 22 + .../FleaseViewChangeListenerInterface.java | 21 + .../flease/MasterEpochHandlerInterface.java | 25 + .../flease/SimpleMasterEpochHandler.java | 145 + .../flease/UDPFleaseCommunicator.java | 270 + .../flease/acceptor/FleaseAcceptor.java | 412 + .../flease/acceptor/FleaseAcceptorCell.java | 147 + .../flease/acceptor/FleaseInstance.java | 114 + .../flease/acceptor/LearnEventListener.java | 20 + .../comm/FleaseCommunicationInterface.java | 23 + .../foundation/flease/comm/FleaseMessage.java | 460 + .../flease/comm/ProposalNumber.java | 98 + .../flease/comm/tcp/EchoClient.java | 97 + .../flease/comm/tcp/EchoServer.java | 107 + .../flease/comm/tcp/NIOConnection.java | 63 + .../foundation/flease/comm/tcp/NIOServer.java | 51 + .../foundation/flease/comm/tcp/TCPClient.java | 250 + .../flease/comm/tcp/TCPCommunicator.java | 557 + .../flease/comm/tcp/TCPConnection.java | 140 + .../comm/tcp/TCPFleaseCommunicator.java | 234 + .../flease/proposer/CellAction.java | 131 + .../flease/proposer/FleaseException.java | 32 + .../flease/proposer/FleaseListener.java | 21 + .../proposer/FleaseLocalQueueInterface.java | 19 + .../flease/proposer/FleaseProposer.java | 1197 + .../flease/proposer/FleaseProposerCell.java | 331 + .../foundation/flease/sim/Communicator.java | 311 + .../flease/sim/DelayedDelivery.java | 224 + .../foundation/flease/sim/FleaseMultiSim.java | 231 + .../foundation/flease/sim/FleaseSim.java | 223 + .../foundation/flease/FleaseStageTest.java | 231 + .../foundation/flease/MasterEpochTest.java | 280 + .../flease/acceptor/FleaseAcceptorTest.java | 164 + .../flease/comm/FleaseMessageTest.java | 80 + .../flease/proposer/FleaseProposerTest.java | 328 + java/foundation/build-1.6.5.xml | 75 + java/foundation/build-before-profiler.xml | 74 + java/foundation/build.xml | 89 + java/foundation/eclipse-project/.classpath | 11 + java/foundation/eclipse-project/.project | 17 + .../foundation/nbproject/build-impl-1.6.5.xml | 682 + java/foundation/nbproject/build-impl.xml | 687 + java/foundation/nbproject/genfiles.properties | 11 + .../nbproject/profiler-build-impl.xml | 131 + java/foundation/nbproject/project.properties | 82 + java/foundation/nbproject/project.xml | 22 + .../org/xtreemfs/foundation/ClientLease.java | 154 + .../xtreemfs/foundation/CrashReporter.java | 102 + .../src/org/xtreemfs/foundation/LRUCache.java | 33 + .../foundation/LifeCycleListener.java | 25 + .../xtreemfs/foundation/LifeCycleThread.java | 167 + .../org/xtreemfs/foundation/SSLOptions.java | 407 + .../xtreemfs/foundation/TimeServerClient.java | 32 + .../src/org/xtreemfs/foundation/TimeSync.java | 464 + .../foundation/VersionManagement.java | 43 + .../foundation/buffer/ASCIIString.java | 107 + .../foundation/buffer/BufferPool.java | 324 + .../foundation/buffer/ReusableBuffer.java | 724 + .../checksums/ChecksumAlgorithm.java | 56 + .../foundation/checksums/ChecksumFactory.java | 150 + .../checksums/ChecksumProvider.java | 57 + .../checksums/StringChecksumAlgorithm.java | 26 + .../checksums/algorithms/Adler32.java | 34 + .../checksums/algorithms/CRC32.java | 34 + .../algorithms/JavaChecksumAlgorithm.java | 99 + .../checksums/algorithms/JavaHash.java | 104 + .../foundation/checksums/algorithms/SDBM.java | 117 + .../provider/JavaChecksumProvider.java | 53 + .../foundation/json/JSONCharBufferString.java | 59 + .../foundation/json/JSONException.java | 38 + .../xtreemfs/foundation/json/JSONInput.java | 46 + .../xtreemfs/foundation/json/JSONParser.java | 329 + .../xtreemfs/foundation/json/JSONString.java | 81 + .../xtreemfs/foundation/logging/Logging.java | 274 + .../xtreemfs/foundation/logging/Utils.java | 39 + .../foundation/monitoring/ListMonitoring.java | 20 + .../foundation/monitoring/Monitoring.java | 164 + .../monitoring/MonitoringEvent.java | 55 + .../monitoring/MonitoringListener.java | 48 + .../foundation/monitoring/MonitoringLog.java | 50 + .../monitoring/NumberMonitoring.java | 187 + .../xtreemfs/foundation/pbrpc/Schemes.java | 34 + .../foundation/pbrpc/channels/ChannelIO.java | 153 + .../pbrpc/channels/SSLChannelIO.java | 768 + .../channels/SSLHandshakeOnlyChannelIO.java | 647 + .../pbrpc/client/PBRPCException.java | 86 + .../pbrpc/client/RPCAuthentication.java | 30 + .../pbrpc/client/RPCClientConnection.java | 230 + .../pbrpc/client/RPCClientRequest.java | 182 + .../pbrpc/client/RPCNIOSocketClient.java | 806 + .../foundation/pbrpc/client/RPCResponse.java | 160 + .../client/RPCResponseAvailableListener.java | 23 + .../pbrpc/client/RPCResponseListener.java | 24 + .../pbrpc/generatedinterfaces/PBRPC.java | 98 + .../pbrpc/generatedinterfaces/Ping.java | 2991 + .../PingServiceClient.java | 56 + .../PingServiceConstants.java | 32 + .../pbrpc/generatedinterfaces/RPC.java | 6305 ++ .../pbrpc/server/RPCNIOSocketServer.java | 787 + .../server/RPCNIOSocketServerConnection.java | 235 + .../server/RPCServerConnectionInterface.java | 28 + .../pbrpc/server/RPCServerInterface.java | 19 + .../pbrpc/server/RPCServerRequest.java | 132 + .../server/RPCServerRequestListener.java | 19 + .../pbrpc/server/RPCServerResponse.java | 84 + .../pbrpc/server/RPCUDPSocketServer.java | 255 + .../foundation/pbrpc/server/UDPMessage.java | 61 + .../foundation/pbrpc/utils/ErrorUtils.java | 50 + .../pbrpc/utils/PBRPCDatagramPacket.java | 72 + .../foundation/pbrpc/utils/RecordMarker.java | 73 + .../utils/ReusableBufferInputStream.java | 46 + .../utils/ReusableBufferOutputStream.java | 111 + .../org/xtreemfs/foundation/trace/Tracer.java | 110 + .../xtreemfs/foundation/util/CLIParser.java | 137 + .../xtreemfs/foundation/util/CLOption.java | 212 + .../foundation/util/CLOptionParser.java | 130 + .../org/xtreemfs/foundation/util/FSUtils.java | 132 + .../util/InvalidUsageException.java | 47 + .../xtreemfs/foundation/util/OutputUtils.java | 264 + .../foundation/util/PBRPCServiceURL.java | 82 + .../xtreemfs/foundation/util/PingServer.java | 91 + .../foundation/buffer/BufferPoolTest.java | 155 + .../foundation/buffer/ReusableBufferTest.java | 176 + .../checksums/ChecksumFactoryTest.java | 261 + .../StringChecksumAlgorithmTest.java | 71 + .../pbrpc/PBRPCClientServerTest.java | 363 + .../pbrpc/PBRPCDatagramPacketTest.java | 66 + .../test/foundation/pbrpc/PBRPCTest.java | 255 + .../pbrpc/RPCNIOSocketServerTest.java | 377 + .../pbrpc/RPCUDPSocketServerTest.java | 96 + .../test/foundation/util/OutputUtilsTest.java | 65 + .../foundation/util/PBRPCServiceURLTest.java | 56 + java/init_eclipse_projects_linux.sh | 25 + java/init_eclipse_projects_windows.bat | 22 + java/lib/BabuDB.jar | Bin 0 -> 701320 bytes java/lib/commons-codec-1.3.jar | Bin 0 -> 46725 bytes java/lib/jdmkrt.jar | Bin 0 -> 2549806 bytes java/lib/jdmktk.jar | Bin 0 -> 679104 bytes java/lib/protobuf-java-2.5.0.jar | Bin 0 -> 532453 bytes .../test/commons-httpclient-3.0.1-contrib.jar | Bin 0 -> 23437 bytes java/lib/test/commons-httpclient-3.0.1.jar | Bin 0 -> 279781 bytes java/lib/test/commons-logging-1.1.jar | Bin 0 -> 52915 bytes java/lib/test/hamcrest-core-1.3.jar | Bin 0 -> 45024 bytes java/lib/test/junit-4.11.jar | Bin 0 -> 245039 bytes java/pbrpcgen/build.xml | 74 + java/pbrpcgen/eclipse-project/.classpath | 7 + java/pbrpcgen/eclipse-project/.project | 17 + java/pbrpcgen/manifest.mf | 3 + java/pbrpcgen/nbproject/build-impl.xml | 1040 + java/pbrpcgen/nbproject/genfiles.properties | 8 + .../nbproject/private/private.properties | 6 + java/pbrpcgen/nbproject/private/private.xml | 3 + java/pbrpcgen/nbproject/project.properties | 76 + java/pbrpcgen/nbproject/project.xml | 15 + .../protobuf/compiler/PluginProtos.java | 4121 ++ .../pbrpc/generatedinterfaces/PBRPC.java | 98 + .../pbrpcgen/RPCCPPSourceGenerator.java | 586 + .../xtreemfs/pbrpcgen/RPCSourceGenerator.java | 424 + java/servers/build-1.6.5.xml | 85 + java/servers/build-before-profiler.xml | 74 + java/servers/build.xml | 85 + java/servers/eclipse-project/.classpath | 19 + .../.classpath_WITH_BabuDB_project_reference | 18 + java/servers/eclipse-project/.project | 19 + java/servers/nbproject/build-impl-1.6.5.xml | 682 + java/servers/nbproject/build-impl.xml | 1068 + java/servers/nbproject/genfiles.properties | 11 + .../servers/nbproject/profiler-build-impl.xml | 131 + java/servers/nbproject/project.properties | 101 + java/servers/nbproject/project.xml | 33 + .../src/org/xtreemfs/common/Capability.java | 201 + .../org/xtreemfs/common/GlobalConstants.java | 26 + .../org/xtreemfs/common/HeartbeatThread.java | 623 + .../org/xtreemfs/common/KeyValuePairs.java | 60 + .../common/ReplicaUpdatePolicies.java | 33 + .../xtreemfs/common/ServiceAvailability.java | 174 + .../common/auth/AuthenticationException.java | 25 + .../common/auth/AuthenticationProvider.java | 45 + .../auth/FederationIdX509AuthProvider.java | 200 + .../common/auth/NullAuthProvider.java | 32 + .../common/auth/SimpleX509AuthProvider.java | 111 + .../xtreemfs/common/auth/UserCredentials.java | 53 + .../common/benchmark/AbstractBenchmark.java | 97 + .../common/benchmark/BenchmarkConfig.java | 857 + .../common/benchmark/BenchmarkFactory.java | 50 + .../benchmark/BenchmarkFailedException.java | 70 + .../common/benchmark/BenchmarkResult.java | 145 + .../common/benchmark/BenchmarkUtils.java | 29 + .../common/benchmark/ClientManager.java | 65 + .../xtreemfs/common/benchmark/Controller.java | 326 + .../common/benchmark/FilebasedBenchmark.java | 33 + .../benchmark/FilebasedReadBenchmark.java | 70 + .../benchmark/FilebasedWriteBenchmark.java | 74 + .../benchmark/RandomOffsetbasedBenchmark.java | 112 + .../common/benchmark/RandomReadBenchmark.java | 47 + .../benchmark/RandomWriteBenchmark.java | 54 + .../common/benchmark/SequentialBenchmark.java | 37 + .../benchmark/SequentialReadBenchmark.java | 61 + .../benchmark/SequentialWriteBenchmark.java | 74 + .../UnalignedSequentialWriteBenchmark.java | 61 + .../UncaughtExceptionHandlerBenchmark.java | 50 + .../common/benchmark/VolumeManager.java | 455 + .../xtreemfs/common/clients/CachedXAttr.java | 50 + .../org/xtreemfs/common/clients/Client.java | 268 + .../src/org/xtreemfs/common/clients/File.java | 555 + .../clients/InvalidChecksumException.java | 23 + .../common/clients/RandomAccessFile.java | 716 + .../org/xtreemfs/common/clients/Replica.java | 182 + .../org/xtreemfs/common/clients/Volume.java | 885 + .../common/clients/internal/ObjectMapper.java | 99 + .../common/clients/internal/OpenFileList.java | 226 + .../clients/internal/RAID0ObjectMapper.java | 89 + .../common/clients/io/ByteMapper.java | 34 + .../common/clients/io/ByteMapperFactory.java | 21 + .../common/clients/io/ByteMapperRAID0.java | 152 + .../common/clients/io/ObjectStore.java | 33 + .../common/clients/io/RandomAccessFile.java | 970 + .../org/xtreemfs/common/config/Config.java | 171 + .../common/config/PolicyClassLoader.java | 444 + .../common/config/PolicyContainer.java | 66 + .../common/config/RemoteConfigHelper.java | 83 + .../xtreemfs/common/config/ServiceConfig.java | 786 + .../common/libxtreemfs/AdminClient.java | 161 + .../common/libxtreemfs/AdminFileHandle.java | 132 + .../common/libxtreemfs/AdminVolume.java | 82 + .../common/libxtreemfs/AsyncWriteBuffer.java | 110 + .../common/libxtreemfs/AsyncWriteHandler.java | 349 + .../xtreemfs/common/libxtreemfs/Client.java | 333 + .../common/libxtreemfs/ClientFactory.java | 91 + .../libxtreemfs/ClientImplementation.java | 1037 + .../common/libxtreemfs/FileHandle.java | 306 + .../libxtreemfs/FileHandleImplementation.java | 1380 + .../xtreemfs/common/libxtreemfs/FileInfo.java | 667 + .../xtreemfs/common/libxtreemfs/Helper.java | 333 + .../common/libxtreemfs/MetadataCache.java | 1074 + .../libxtreemfs/MetadataCacheEntry.java | 100 + .../xtreemfs/common/libxtreemfs/Options.java | 272 + .../PeriodicFileSizeUpdateThread.java | 69 + .../PeriodicXcapRenewalThread.java | 69 + .../common/libxtreemfs/RPCCaller.java | 314 + .../common/libxtreemfs/ReadOperation.java | 59 + .../common/libxtreemfs/StripeTranslator.java | 40 + .../libxtreemfs/StripeTranslatorRaid0.java | 53 + .../xtreemfs/common/libxtreemfs/Tupel.java | 32 + .../common/libxtreemfs/UUIDIterator.java | 190 + .../common/libxtreemfs/UUIDResolver.java | 48 + .../xtreemfs/common/libxtreemfs/Volume.java | 788 + .../libxtreemfs/VolumeImplementation.java | 1776 + .../common/libxtreemfs/WriteOperation.java | 58 + .../AddressToUUIDNotFoundException.java | 14 + .../InternalServerErrorException.java | 26 + .../exceptions/InvalidChecksumException.java | 17 + .../exceptions/InvalidViewException.java | 23 + .../exceptions/PosixErrorException.java | 32 + .../UUIDIteratorListIsEmpyException.java | 19 + .../exceptions/UUIDNotInXlocSetException.java | 24 + .../exceptions/VolumeNotFoundException.java | 24 + .../exceptions/XtreemFSException.java | 28 + .../xtreemfs/common/monitoring/DirImpl.java | 101 + .../common/monitoring/GeneralImpl.java | 223 + .../xtreemfs/common/monitoring/MrcImpl.java | 69 + .../xtreemfs/common/monitoring/OsdImpl.java | 204 + .../common/monitoring/StatusMonitor.java | 423 + .../common/monitoring/XTREEMFS_MIBImpl.java | 81 + .../common/monitoring/generatedcode/Dir.java | 69 + .../monitoring/generatedcode/DirMBean.java | 27 + .../monitoring/generatedcode/DirMeta.java | 247 + .../monitoring/generatedcode/General.java | 212 + .../generatedcode/GeneralMBean.java | 82 + .../monitoring/generatedcode/GeneralMeta.java | 423 + .../common/monitoring/generatedcode/Mrc.java | 56 + .../monitoring/generatedcode/MrcMBean.java | 22 + .../monitoring/generatedcode/MrcMeta.java | 232 + .../common/monitoring/generatedcode/Osd.java | 199 + .../monitoring/generatedcode/OsdMBean.java | 77 + .../monitoring/generatedcode/OsdMeta.java | 411 + .../generatedcode/XTREEMFS_MIB.java | 526 + .../generatedcode/XTREEMFS_MIBOidTable.java | 62 + .../common/statusserver/BabuDBStatusPage.java | 87 + .../common/statusserver/PrintStackTrace.java | 53 + .../common/statusserver/StatusServer.java | 155 + .../statusserver/StatusServerHelper.java | 116 + .../statusserver/StatusServerModule.java | 69 + .../org/xtreemfs/common/util/NetUtils.java | 197 + .../org/xtreemfs/common/uuids/Mapping.java | 33 + .../xtreemfs/common/uuids/ServiceUUID.java | 197 + .../xtreemfs/common/uuids/UUIDCacheEntry.java | 95 + .../xtreemfs/common/uuids/UUIDResolver.java | 376 + .../common/uuids/UnknownUUIDException.java | 23 + .../xloc/InvalidXLocationsException.java | 21 + .../org/xtreemfs/common/xloc/RAID0Impl.java | 111 + .../src/org/xtreemfs/common/xloc/Replica.java | 160 + .../common/xloc/ReplicationFlags.java | 104 + .../xloc/ReplicationPolicyImplementation.java | 38 + .../common/xloc/StripingPolicyImpl.java | 124 + .../org/xtreemfs/common/xloc/XLocations.java | 137 + java/servers/src/org/xtreemfs/dir/DIR.java | 86 + .../src/org/xtreemfs/dir/DIRClient.java | 463 + .../src/org/xtreemfs/dir/DIRConfig.java | 171 + .../src/org/xtreemfs/dir/DIRRequest.java | 107 + .../xtreemfs/dir/DIRRequestDispatcher.java | 597 + .../org/xtreemfs/dir/DIRStatusListener.java | 28 + .../org/xtreemfs/dir/MonitoringThread.java | 141 + .../org/xtreemfs/dir/ReplicaStatusPage.java | 154 + .../src/org/xtreemfs/dir/StatusPage.java | 394 + .../org/xtreemfs/dir/VivaldiClientMap.java | 106 + .../org/xtreemfs/dir/VivaldiStatusPage.java | 191 + .../dir/data/AddressMappingRecord.java | 154 + .../dir/data/AddressMappingRecords.java | 97 + .../dir/data/ConfigurationRecord.java | 123 + .../org/xtreemfs/dir/data/ServiceRecord.java | 203 + .../org/xtreemfs/dir/data/ServiceRecords.java | 101 + .../dir/discovery/DiscoveryMsgThread.java | 104 + .../dir/discovery/DiscoveryUtils.java | 111 + .../xtreemfs/dir/operations/DIROperation.java | 199 + .../DeleteAddressMappingOperation.java | 76 + .../DeregisterServiceOperation.java | 79 + .../GetAddressMappingOperation.java | 108 + .../operations/GetConfigurationOperation.java | 75 + .../operations/GetGlobalTimeOperation.java | 58 + .../operations/GetServiceByNameOperation.java | 95 + .../operations/GetServiceByUuidOperation.java | 83 + .../GetServicesByTypeOperation.java | 98 + .../operations/RegisterServiceOperation.java | 171 + .../operations/ServiceOfflineOperation.java | 89 + .../SetAddressMappingOperation.java | 133 + .../operations/SetConfigurationOperation.java | 141 + .../UpdateVivaldiClientOperation.java | 63 + .../src/org/xtreemfs/dir/templates/d3.js | 4762 ++ .../src/org/xtreemfs/dir/templates/d3.v3.js | 8580 +++ .../dir/templates/replica_status.html | 383 + .../org/xtreemfs/dir/templates/status.html | 138 + .../org/xtreemfs/dir/templates/vivaldi.html | 540 + .../src/org/xtreemfs/mrc/ErrorRecord.java | 82 + java/servers/src/org/xtreemfs/mrc/MRC.java | 107 + .../src/org/xtreemfs/mrc/MRCConfig.java | 153 + .../src/org/xtreemfs/mrc/MRCException.java | 25 + .../org/xtreemfs/mrc/MRCPolicyContainer.java | 148 + .../src/org/xtreemfs/mrc/MRCRequest.java | 115 + .../xtreemfs/mrc/MRCRequestDispatcher.java | 952 + .../org/xtreemfs/mrc/MRCStatusListener.java | 24 + .../org/xtreemfs/mrc/MRCStatusManager.java | 187 + .../src/org/xtreemfs/mrc/RequestDetails.java | 42 + .../src/org/xtreemfs/mrc/StatusPage.java | 129 + .../src/org/xtreemfs/mrc/UserException.java | 42 + .../xtreemfs/mrc/ac/FileAccessManager.java | 184 + .../org/xtreemfs/mrc/ac/FileAccessPolicy.java | 237 + .../mrc/ac/POSIXFileAccessPolicy.java | 688 + .../mrc/ac/VolumeACLFileAccessPolicy.java | 124 + .../mrc/ac/YesToAnyoneFileAccessPolicy.java | 97 + .../xtreemfs/mrc/database/AtomicDBUpdate.java | 34 + .../mrc/database/DBAccessResultListener.java | 16 + .../mrc/database/DatabaseException.java | 52 + .../mrc/database/DatabaseResultSet.java | 27 + .../mrc/database/ReplicationManager.java | 28 + .../xtreemfs/mrc/database/StorageManager.java | 152 + .../mrc/database/VolumeChangeListener.java | 21 + .../org/xtreemfs/mrc/database/VolumeInfo.java | 154 + .../xtreemfs/mrc/database/VolumeManager.java | 226 + .../babudb/AtomicBabuDBSnapshotUpdate.java | 39 + .../database/babudb/AtomicBabuDBUpdate.java | 139 + .../babudb/BabuDBRequestListenerWrapper.java | 44 + .../babudb/BabuDBSnapshotStorageManager.java | 580 + .../babudb/BabuDBSnapshotVolumeInfo.java | 148 + .../database/babudb/BabuDBStorageHelper.java | 592 + .../database/babudb/BabuDBStorageManager.java | 1070 + .../mrc/database/babudb/BabuDBVolumeInfo.java | 221 + .../database/babudb/BabuDBVolumeManager.java | 594 + .../babudb/TransactionalBabuDBUpdate.java | 75 + .../org/xtreemfs/mrc/metadata/ACLEntry.java | 17 + .../mrc/metadata/BufferBackedACLEntry.java | 58 + .../metadata/BufferBackedFileMetadata.java | 349 + .../metadata/BufferBackedIndexMetadata.java | 66 + .../mrc/metadata/BufferBackedMetadata.java | 71 + .../mrc/metadata/BufferBackedRCMetadata.java | 270 + .../metadata/BufferBackedStripingPolicy.java | 74 + .../mrc/metadata/BufferBackedXAttr.java | 77 + .../mrc/metadata/BufferBackedXLoc.java | 141 + .../mrc/metadata/BufferBackedXLocList.java | 149 + .../xtreemfs/mrc/metadata/FileMetadata.java | 77 + .../mrc/metadata/ReplicationPolicy.java | 38 + .../xtreemfs/mrc/metadata/StripingPolicy.java | 40 + .../src/org/xtreemfs/mrc/metadata/XAttr.java | 22 + .../src/org/xtreemfs/mrc/metadata/XLoc.java | 54 + .../org/xtreemfs/mrc/metadata/XLocList.java | 57 + .../mrc/operations/AccessOperation.java | 82 + .../mrc/operations/AddReplicaOperation.java | 213 + .../operations/CheckFileListOperation.java | 97 + .../mrc/operations/CheckpointOperation.java | 54 + .../mrc/operations/CreateDirOperation.java | 99 + .../mrc/operations/CreateLinkOperation.java | 109 + .../operations/CreateSymLinkOperation.java | 92 + .../mrc/operations/CreateVolumeOperation.java | 187 + .../mrc/operations/DeleteOperation.java | 155 + .../mrc/operations/DeleteVolumeOperation.java | 102 + .../mrc/operations/DumpDBOperation.java | 137 + .../mrc/operations/FSetAttrOperation.java | 117 + .../GetFileCredentialsOperation.java | 91 + .../operations/GetLocalVolumesOperation.java | 79 + .../operations/GetSuitableOSDsOperation.java | 102 + .../mrc/operations/GetXAttrOperation.java | 85 + .../mrc/operations/GetXAttrsOperation.java | 127 + .../mrc/operations/GetXLocListOperation.java | 103 + .../mrc/operations/GetXLocSetOperation.java | 120 + .../operations/InternalDebugOperation.java | 90 + .../xtreemfs/mrc/operations/MRCOperation.java | 151 + .../mrc/operations/MoveOperation.java | 339 + .../mrc/operations/OpenOperation.java | 352 + .../operations/ReadDirAndStatOperation.java | 216 + .../mrc/operations/ReadLinkOperation.java | 71 + .../operations/RemoveReplicaOperation.java | 266 + .../mrc/operations/RemoveXAttrOperation.java | 94 + .../mrc/operations/RenewOperation.java | 61 + .../mrc/operations/RestoreDBOperation.java | 183 + .../mrc/operations/RestoreFileOperation.java | 117 + .../operations/SetReadOnlyXattrOperation.java | 88 + .../SetReplicaUpdatePolicyOperation.java | 133 + .../mrc/operations/SetXAttrOperation.java | 116 + .../mrc/operations/SetattrOperation.java | 236 + .../mrc/operations/ShutdownOperation.java | 45 + .../mrc/operations/StatFSOperation.java | 97 + .../mrc/operations/StatOperation.java | 105 + .../mrc/operations/TruncateOperation.java | 99 + .../operations/UpdateFileSizeOperation.java | 257 + .../mrc/osdselection/DCMapPolicyBase.java | 194 + .../mrc/osdselection/FQDNPolicyBase.java | 70 + .../mrc/osdselection/FilterDefaultPolicy.java | 217 + .../mrc/osdselection/FilterFQDNPolicy.java | 114 + .../mrc/osdselection/FilterUUIDPolicy.java | 98 + .../mrc/osdselection/GroupDCMapPolicy.java | 141 + .../mrc/osdselection/GroupFQDNPolicy.java | 129 + .../mrc/osdselection/Inet4AddressMatcher.java | 65 + .../mrc/osdselection/InetAddressMatcher.java | 21 + .../mrc/osdselection/OSDSelectionPolicy.java | 66 + .../mrc/osdselection/OSDStatusManager.java | 348 + .../mrc/osdselection/PolicyHelper.java | 85 + .../mrc/osdselection/SortDCMapPolicy.java | 85 + .../mrc/osdselection/SortFQDNPolicy.java | 72 + .../SortHostRoundRobinPolicy.java | 66 + .../mrc/osdselection/SortRandomPolicy.java | 49 + .../mrc/osdselection/SortReversePolicy.java | 44 + .../mrc/osdselection/SortUUIDPolicy.java | 55 + .../mrc/osdselection/SortVivaldiPolicy.java | 115 + .../mrc/osdselection/VolumeOSDFilter.java | 257 + .../mrc/stages/InternalCallbackInterface.java | 19 + .../stages/InternalCallbackMRCRequest.java | 39 + .../src/org/xtreemfs/mrc/stages/MRCStage.java | 182 + .../mrc/stages/MRCStageCallbackInterface.java | 18 + .../mrc/stages/OnCloseReplicationThread.java | 127 + .../xtreemfs/mrc/stages/ProcessingStage.java | 378 + .../mrc/stages/XLocSetCoordinator.java | 866 + .../stages/XLocSetCoordinatorCallback.java | 21 + .../org/xtreemfs/mrc/stages/XLocSetLock.java | 33 + .../org/xtreemfs/mrc/templates/status.html | 148 + .../src/org/xtreemfs/mrc/utils/Converter.java | 510 + .../org/xtreemfs/mrc/utils/DBAdminHelper.java | 459 + .../src/org/xtreemfs/mrc/utils/MRCHelper.java | 917 + .../src/org/xtreemfs/mrc/utils/Path.java | 149 + .../org/xtreemfs/mrc/utils/PathResolver.java | 107 + .../src/org/xtreemfs/osd/AdvisoryLock.java | 100 + .../src/org/xtreemfs/osd/ErrorCodes.java | 85 + .../org/xtreemfs/osd/InternalObjectData.java | 52 + .../src/org/xtreemfs/osd/LocationsCache.java | 68 + java/servers/src/org/xtreemfs/osd/OSD.java | 100 + .../src/org/xtreemfs/osd/OSDConfig.java | 294 + .../src/org/xtreemfs/osd/OSDRequest.java | 239 + .../xtreemfs/osd/OSDRequestDispatcher.java | 1090 + .../org/xtreemfs/osd/OSDStatusListener.java | 32 + .../src/org/xtreemfs/osd/OpenFileTable.java | 504 + .../osd/ReplicatedFileStatusJSON.java | 92 + .../osd/ReplicatedFileStatusPage.java | 108 + .../src/org/xtreemfs/osd/StatusPage.java | 285 + .../src/org/xtreemfs/osd/drain/OSDDrain.java | 1382 + .../xtreemfs/osd/drain/OSDDrainException.java | 109 + .../osd/operations/CheckObjectOperation.java | 196 + .../CleanupGetResultsOperation.java | 65 + .../operations/CleanupGetStatusOperation.java | 64 + .../operations/CleanupIsRunningOperation.java | 64 + .../osd/operations/CleanupStartOperation.java | 67 + .../osd/operations/CleanupStopOperation.java | 62 + .../CleanupVersionsStartOperation.java | 63 + .../osd/operations/DeleteOperation.java | 209 + .../osd/operations/EventCloseFile.java | 149 + .../operations/EventCreateFileVersion.java | 67 + .../xtreemfs/osd/operations/EventGmax.java | 71 + .../operations/EventInsertPaddingObject.java | 81 + .../osd/operations/EventPingFile.java | 55 + .../osd/operations/EventRWRStatus.java | 66 + .../osd/operations/EventWriteObject.java | 84 + .../operations/FleaseMessageOperation.java | 63 + .../operations/GetFileIDListOperation.java | 96 + .../osd/operations/GetObjectSetOperation.java | 111 + .../InternalGetFileSizeOperation.java | 209 + .../operations/InternalGetGmaxOperation.java | 95 + ...ernalRWRAuthStateInvalidatedOperation.java | 147 + .../InternalRWRAuthStateOperation.java | 108 + .../operations/InternalRWRFetchOperation.java | 115 + .../InternalRWRStatusOperation.java | 104 + .../InternalRWRTruncateOperation.java | 137 + .../InternalRWRUpdateOperation.java | 135 + .../operations/InternalTruncateOperation.java | 107 + .../InvalidateXLocSetOperation.java | 133 + .../osd/operations/KeepFileOpenOperation.java | 92 + .../osd/operations/LocalReadOperation.java | 187 + .../osd/operations/LockAcquireOperation.java | 108 + .../osd/operations/LockCheckOperation.java | 100 + .../osd/operations/LockReleaseOperation.java | 106 + .../xtreemfs/osd/operations/OSDOperation.java | 117 + .../osd/operations/RWRNotifyOperation.java | 113 + .../osd/operations/ReadOperation.java | 348 + .../osd/operations/RepairObjectOperation.java | 104 + .../osd/operations/RequestTimeHelper.java | 50 + .../osd/operations/ShutdownOperation.java | 73 + .../osd/operations/TruncateOperation.java | 260 + .../osd/operations/VivaldiPingOperation.java | 102 + .../osd/operations/WriteOperation.java | 228 + .../osd/replication/ObjectDissemination.java | 365 + .../xtreemfs/osd/replication/ObjectSet.java | 386 + .../osd/replication/ReplicatingFile.java | 893 + .../selection/ObjectSetOSDSelection.java | 48 + .../selection/RandomOSDSelection.java | 29 + .../selection/RandomObjectSelection.java | 29 + .../selection/RarestFirstObjectSelection.java | 176 + .../selection/RoundRobinOSDSelection.java | 91 + .../selection/SequentialObjectSelection.java | 61 + .../MasqueradingTransferStrategy.java | 268 + .../transferStrategies/RandomStrategy.java | 74 + .../RandomStrategyWithoutObjectSets.java | 73 + .../RarestFirstStrategy.java | 73 + .../SequentialPrefetchingStrategy.java | 116 + .../SequentialStrategy.java | 85 + .../transferStrategies/TransferStrategy.java | 248 + .../rwre/CoordinatedReplicaUpdatePolicy.java | 503 + .../osd/rwre/FleaseMasterEpochThread.java | 81 + .../xtreemfs/osd/rwre/ObjectFetchRecord.java | 116 + .../xtreemfs/osd/rwre/RWReplicationStage.java | 1532 + .../osd/rwre/RedirectToMasterException.java | 28 + .../osd/rwre/ReplicaUpdatePolicy.java | 185 + .../osd/rwre/ReplicatedFileState.java | 373 + .../org/xtreemfs/osd/rwre/RetryException.java | 20 + .../xtreemfs/osd/rwre/WaR1UpdatePolicy.java | 40 + .../xtreemfs/osd/rwre/WaRaUpdatePolicy.java | 45 + .../xtreemfs/osd/rwre/WqRqUpdatePolicy.java | 44 + .../xtreemfs/osd/stages/DeletionStage.java | 219 + .../org/xtreemfs/osd/stages/PreprocStage.java | 851 + .../xtreemfs/osd/stages/ReplicationStage.java | 217 + .../src/org/xtreemfs/osd/stages/Stage.java | 226 + .../org/xtreemfs/osd/stages/StorageStage.java | 294 + .../org/xtreemfs/osd/stages/VivaldiStage.java | 870 + .../xtreemfs/osd/storage/CleanupThread.java | 573 + .../osd/storage/CleanupVersionsThread.java | 332 + .../org/xtreemfs/osd/storage/CowPolicy.java | 138 + .../xtreemfs/osd/storage/FileMetadata.java | 207 + .../osd/storage/HashStorageLayout.java | 1436 + .../xtreemfs/osd/storage/MetadataCache.java | 39 + .../osd/storage/ObjectInformation.java | 205 + .../storage/RealSingleFileStorageLayout.java | 535 + .../osd/storage/SingleFileStorageLayout.java | 529 + .../xtreemfs/osd/storage/StorageLayout.java | 506 + .../xtreemfs/osd/storage/StorageThread.java | 1022 + .../xtreemfs/osd/storage/VersionTable.java | 308 + .../org/xtreemfs/osd/templates/status.html | 172 + .../org/xtreemfs/osd/vivaldi/VivaldiNode.java | 266 + .../xtreemfs/osd/vivaldi/ZipfGenerator.java | 102 + .../pbrpc/generatedinterfaces/Common.java | 699 + .../pbrpc/generatedinterfaces/DIR.java | 13773 +++++ .../generatedinterfaces/DIRServiceClient.java | 238 + .../DIRServiceConstants.java | 74 + .../generatedinterfaces/GlobalTypes.java | 10943 ++++ .../pbrpc/generatedinterfaces/MRC.java | 48656 ++++++++++++++++ .../generatedinterfaces/MRCServiceClient.java | 563 + .../MRCServiceConstants.java | 149 + .../pbrpc/generatedinterfaces/OSD.java | 33462 +++++++++++ .../generatedinterfaces/OSDServiceClient.java | 485 + .../OSDServiceConstants.java | 131 + .../sandbox/BenchmarkStorageLayouts.java | 139 + .../xtreemfs/sandbox/CleanupDemoVolume.java | 204 + .../src/org/xtreemfs/sandbox/DBViewer.java | 83 + .../org/xtreemfs/sandbox/DemoScrubber.java | 421 + .../sandbox/DemoScrubberFileInfo.java | 74 + .../sandbox/ExampleLibxtreemfsWithSSL.java | 142 + .../sandbox/LocalX509AuthProvider.java | 110 + .../org/xtreemfs/sandbox/ThroughputTest.java | 248 + .../sandbox/ThroughputTest.properties | 29 + .../sandbox/compile-DirectIOReader.txt | 9 + .../sandbox/dir_replication_test.java | 713 + .../sandbox/mrc_replication_test.java | 530 + .../src/org/xtreemfs/sandbox/sliceTest.java | 47 + .../xtreemfs/sandbox/tests/CreateConfig.java | 60 + .../xtreemfs/sandbox/tests/FcntlLockTest.java | 14 + .../sandbox/tests/JavaClientTest.java | 99 + .../xtreemfs/sandbox/tests/MRCStressTest.java | 115 + .../xtreemfs/sandbox/tests/OSDTestClient.java | 466 + .../tests/ReplicatedTortureXtreemFS.java | 378 + .../sandbox/tests/TortureLocalFS.java | 232 + .../sandbox/tests/TortureXtreemFS.java | 330 + .../xtreemfs/sandbox/tests/rwrepl_test.java | 205 + .../org/xtreemfs/sandbox/writeTruncTest.java | 63 + .../org/xtreemfs/utils/DefaultDirConfig.java | 110 + .../src/org/xtreemfs/utils/discover_dir.java | 31 + .../servers/src/org/xtreemfs/utils/utils.java | 215 + .../utils/xtfs_benchmark/CLIOptions.java | 487 + .../UncaughtExceptionHandlerBenchmark.java | 40 + .../utils/xtfs_benchmark/xtfs_benchmark.java | 189 + .../src/org/xtreemfs/utils/xtfs_chstatus.java | 219 + .../org/xtreemfs/utils/xtfs_cleanup_osd.java | 276 + .../org/xtreemfs/utils/xtfs_mrcdbtool.java | 191 + .../org/xtreemfs/utils/xtfs_remove_osd.java | 339 + .../utils/xtfs_scrub/FileScrubber.java | 341 + .../xtreemfs/utils/xtfs_scrub/xtfs_scrub.java | 496 + .../xtreemfs/common/clients/ClientTest.java | 207 + .../common/clients/ReplicatedClientTest.java | 126 + .../internal/RAID0ObjectMapperTest.java | 158 + .../common/libxtreemfs/ClientTest.java | 382 + .../common/libxtreemfs/FileHandleTest.java | 846 + .../libxtreemfs/FileSizeUpdateThreadTest.java | 131 + .../common/libxtreemfs/MetadataCacheTest.java | 801 + .../common/libxtreemfs/RPCCallerTest.java | 200 + .../libxtreemfs/ReadOnlyReplicationTest.java | 163 + .../libxtreemfs/StripeTranslatorTest.java | 96 + .../common/libxtreemfs/UUIDIteratorTest.java | 128 + .../common/libxtreemfs/UUIDResolverTest.java | 140 + .../common/libxtreemfs/VolumeTest.java | 990 + .../common/statusserver/StatusServerTest.java | 55 + .../ExternalIntegrationTest.java | 425 + .../test/org/xtreemfs/test/SetupUtils.java | 458 + .../org/xtreemfs/test/TestEnvironment.java | 466 + .../test/org/xtreemfs/test/TestHelper.java | 15 + .../xtreemfs/test/common/CapabilityTest.java | 68 + .../benchmark/ControllerIntegrationTest.java | 556 + .../common/monitoring/DIRMonitoringTest.java | 223 + .../monitoring/GeneralMonitoringTest.java | 305 + .../common/monitoring/MRCMonitoringTest.java | 235 + .../common/monitoring/OSDMonitoringTest.java | 179 + .../common/striping/LocationsCacheTest.java | 135 + .../test/common/striping/LocationsTest.java | 175 + .../test/common/striping/RAID0Test.java | 206 + .../test/common/uuid/UUIDResolverTest.java | 97 + .../org/xtreemfs/test/dir/DIRClientTest.java | 233 + .../test/org/xtreemfs/test/dir/DIRTest.java | 303 + .../test/mrc/BabuDBStorageManagerTest.java | 548 + .../test/mrc/BufferBackedMetadataTest.java | 391 + .../test/org/xtreemfs/test/mrc/MRCTest.java | 1472 + .../org/xtreemfs/test/mrc/OSDPolicyTest.java | 613 + .../test/mrc/SetReadOnlyXattrTest.java | 141 + .../test/mrc/SetReplicaUpdatePolicyTest.java | 187 + .../org/xtreemfs/test/mrc/SnapshotTest.java | 443 + .../test/mrc/VersionedXLocSetTest.java | 583 + .../xtreemfs/test/osd/AdvisoryLocksTest.java | 257 + .../org/xtreemfs/test/osd/CleanupTest.java | 361 + .../xtreemfs/test/osd/ClientLeaseTest.java | 321 + .../org/xtreemfs/test/osd/CowPolicyTest.java | 94 + .../xtreemfs/test/osd/FastDeleteOpenFile.java | 136 + .../test/osd/OSDDataIntegrityTest.java | 443 + .../org/xtreemfs/test/osd/OSDDrainTest.java | 490 + .../org/xtreemfs/test/osd/OSDRangeReads.java | 286 + .../xtreemfs/test/osd/OSDTruncateTest.java | 422 + .../test/osd/SimpleVivaldiStageTest.java | 124 + .../xtreemfs/test/osd/StorageLayoutTest.java | 332 + .../xtreemfs/test/osd/StorageStageTest.java | 492 + .../org/xtreemfs/test/osd/StripingTest.java | 762 + .../xtreemfs/test/osd/StripingTestCOW.java | 296 + .../test/osd/VersionManagementTest.java | 356 + .../xtreemfs/test/osd/VersionTableTest.java | 113 + .../test/osd/replication/ObjectSetTest.java | 250 + .../replication/ReadWriteReplicationTest.java | 177 + .../osd/replication/ReplicationRAFTest.java | 699 + .../test/osd/replication/ReplicationTest.java | 594 + .../replication/ServiceAvailabilityTest.java | 124 + .../replication/TransferStrategiesTest.java | 429 + .../FixWrongMasterEpochDirectoryTest.java | 73 + .../osd/rwre/RWQuorumReplicationTest.java | 297 + .../osd/rwre/RWReplicationFailureTest.java | 189 + .../test/osd/rwre/RWReplicationTest.java | 297 + .../test/org/xtreemfs/utils/ScrubberTest.java | 514 + man/man1/lsfs.xtreemfs.1 | 68 + man/man1/mkfs.xtreemfs.1 | 145 + man/man1/mount.xtreemfs.1 | 189 + man/man1/rmfs.xtreemfs.1 | 75 + man/man1/umount.xtreemfs.1 | 23 + man/man1/xtfs_chstatus.1 | 45 + man/man1/xtfs_cleanup.1 | 75 + man/man1/xtfs_mrcdbtool.1 | 51 + man/man1/xtfs_remove_osd.1 | 66 + man/man1/xtfs_scrub.1 | 62 + man/man1/xtfsutil.1 | 199 + packaging/generate_uuid | 25 + packaging/postinstall_setup.sh | 78 + snmp/README.txt | 8 + snmp/generatedcode.sh | 16 + snmp/jdmk.acl | 38 + snmp/mib_core.txt | 375 + snmp/xtreemfs-mib.txt | 315 + tests/.project | 17 + tests/.pydevproject | 7 + tests/certs/Client.key | 15 + tests/certs/Client.p12 | Bin 0 -> 1669 bytes tests/certs/Client.pem | 16 + tests/certs/Client.req | 12 + tests/certs/DIR.key | 15 + tests/certs/DIR.p12 | Bin 0 -> 1669 bytes tests/certs/DIR.pem | 16 + tests/certs/DIR.req | 12 + tests/certs/MRC.key | 15 + tests/certs/MRC.p12 | Bin 0 -> 1669 bytes tests/certs/MRC.pem | 16 + tests/certs/MRC.req | 12 + tests/certs/OSD.key | 15 + tests/certs/OSD.p12 | Bin 0 -> 1669 bytes tests/certs/OSD.pem | 16 + tests/certs/OSD.req | 12 + tests/certs/client_ssl_test/CA_Chain.pem | 42 + .../certs/client_ssl_test/CA_Intermediate.key | 16 + .../certs/client_ssl_test/CA_Intermediate.pem | 14 + .../certs/client_ssl_test/CA_Intermediate.req | 11 + .../certs/client_ssl_test/CA_Intermediate.srl | 1 + tests/certs/client_ssl_test/CA_Leaf.key | 16 + tests/certs/client_ssl_test/CA_Leaf.pem | 14 + tests/certs/client_ssl_test/CA_Leaf.req | 11 + tests/certs/client_ssl_test/CA_Leaf.srl | 1 + tests/certs/client_ssl_test/CA_Root.key | 16 + tests/certs/client_ssl_test/CA_Root.pem | 14 + tests/certs/client_ssl_test/CA_Root.req | 11 + tests/certs/client_ssl_test/CA_Root.srl | 1 + tests/certs/client_ssl_test/Client_Leaf.key | 16 + tests/certs/client_ssl_test/Client_Leaf.p12 | Bin 0 -> 1670 bytes tests/certs/client_ssl_test/Client_Leaf.pem | 14 + tests/certs/client_ssl_test/Client_Leaf.req | 11 + .../client_ssl_test/Client_Leaf_Chain.p12 | Bin 0 -> 3470 bytes .../client_ssl_test/Client_Leaf_Leaf.p12 | Bin 0 -> 2288 bytes .../client_ssl_test/Client_Leaf_Root.p12 | Bin 0 -> 2288 bytes tests/certs/client_ssl_test/Client_Root.key | 16 + tests/certs/client_ssl_test/Client_Root.p12 | Bin 0 -> 1670 bytes tests/certs/client_ssl_test/Client_Root.pem | 14 + tests/certs/client_ssl_test/Client_Root.req | 11 + .../client_ssl_test/Client_Root_Chain.p12 | Bin 0 -> 3470 bytes .../client_ssl_test/Client_Root_Leaf.p12 | Bin 0 -> 2288 bytes .../client_ssl_test/Client_Root_Root.p12 | Bin 0 -> 2288 bytes tests/certs/client_ssl_test/DIR_Leaf.key | 16 + tests/certs/client_ssl_test/DIR_Leaf.p12 | Bin 0 -> 1656 bytes tests/certs/client_ssl_test/DIR_Leaf.pem | 14 + tests/certs/client_ssl_test/DIR_Leaf.req | 11 + tests/certs/client_ssl_test/DIR_Root.key | 16 + tests/certs/client_ssl_test/DIR_Root.p12 | Bin 0 -> 1656 bytes tests/certs/client_ssl_test/DIR_Root.pem | 14 + tests/certs/client_ssl_test/DIR_Root.req | 11 + tests/certs/client_ssl_test/MRC_Leaf.key | 16 + tests/certs/client_ssl_test/MRC_Leaf.p12 | Bin 0 -> 1656 bytes tests/certs/client_ssl_test/MRC_Leaf.pem | 14 + tests/certs/client_ssl_test/MRC_Leaf.req | 11 + tests/certs/client_ssl_test/MRC_Root.key | 16 + tests/certs/client_ssl_test/MRC_Root.p12 | Bin 0 -> 1656 bytes tests/certs/client_ssl_test/MRC_Root.pem | 14 + tests/certs/client_ssl_test/MRC_Root.req | 11 + tests/certs/client_ssl_test/OSD_Leaf.key | 16 + tests/certs/client_ssl_test/OSD_Leaf.p12 | Bin 0 -> 1656 bytes tests/certs/client_ssl_test/OSD_Leaf.pem | 14 + tests/certs/client_ssl_test/OSD_Leaf.req | 11 + tests/certs/client_ssl_test/OSD_Root.key | 16 + tests/certs/client_ssl_test/OSD_Root.p12 | Bin 0 -> 1656 bytes tests/certs/client_ssl_test/OSD_Root.pem | 14 + tests/certs/client_ssl_test/OSD_Root.req | 11 + tests/certs/client_ssl_test/README | 60 + tests/certs/client_ssl_test/trusted_leaf.jks | Bin 0 -> 603 bytes tests/certs/client_ssl_test/trusted_root.jks | Bin 0 -> 603 bytes tests/certs/trusted.jks | Bin 0 -> 720 bytes tests/config_parser.py | 155 + tests/configs/dirconfig_no_ssl.test | 110 + .../configs/dirconfig_ssl_ignore_errors.test | 115 + tests/configs/dirconfig_ssl_long_chain.test | 115 + .../dirconfig_ssl_no_verification.test | 115 + tests/configs/dirconfig_ssl_short_chain.test | 115 + tests/configs/dirconfig_ssl_version.test | 115 + .../configs/dirconfig_ssl_version_sslv3.test | 115 + .../configs/dirconfig_ssl_version_tlsv1.test | 115 + .../configs/dirconfig_ssl_version_tlsv11.test | 115 + .../configs/dirconfig_ssl_version_tlsv12.test | 115 + tests/configs/mrcconfig_no_ssl.test | 173 + .../configs/mrcconfig_ssl_ignore_errors.test | 167 + tests/configs/mrcconfig_ssl_long_chain.test | 167 + .../mrcconfig_ssl_no_verification.test | 167 + tests/configs/mrcconfig_ssl_short_chain.test | 167 + tests/configs/mrcconfig_ssl_version.test | 167 + .../configs/mrcconfig_ssl_version_sslv3.test | 167 + .../configs/mrcconfig_ssl_version_tlsv1.test | 167 + .../configs/mrcconfig_ssl_version_tlsv11.test | 167 + .../configs/mrcconfig_ssl_version_tlsv12.test | 167 + tests/configs/osdconfig_no_ssl.test | 99 + .../configs/osdconfig_ssl_ignore_errors.test | 100 + tests/configs/osdconfig_ssl_long_chain.test | 100 + .../osdconfig_ssl_no_verification.test | 100 + tests/configs/osdconfig_ssl_short_chain.test | 100 + tests/configs/osdconfig_ssl_version.test | 100 + .../configs/osdconfig_ssl_version_sslv3.test | 100 + .../configs/osdconfig_ssl_version_tlsv1.test | 100 + .../configs/osdconfig_ssl_version_tlsv11.test | 100 + .../configs/osdconfig_ssl_version_tlsv12.test | 100 + tests/cronjob/run_xtreemfs_tests.sh | 155 + tests/kill_running_servers.sh | 17 + tests/test_config.py | 333 + tests/test_scripts/01_simple_metadata.py | 154 + tests/test_scripts/02_erichs_ddwrite.py | 63 + .../03_erichs_data_integrity_test.py | 39 + tests/test_scripts/05_findgreptar.sh | 18 + tests/test_scripts/09_fsx.py | 48 + tests/test_scripts/10_bonnie.py | 40 + tests/test_scripts/11_iozone_diagnostic.py | 39 + tests/test_scripts/12_iozone_throughput.py | 38 + tests/test_scripts/13_dbench.py | 51 + tests/test_scripts/14_xtfs_benchmark.sh | 17 + tests/test_scripts/15_makextreemfs.py | 53 + tests/test_scripts/16_iozone_multithread.py | 39 + tests/test_scripts/17_bonnie_multithread.py | 41 + tests/test_scripts/18_view_renewal.py | 132 + tests/test_scripts/cpp_unit_tests.sh | 22 + tests/test_scripts/cpp_unit_tests_valgrind.sh | 95 + tests/test_scripts/dbench-client.txt.gz | Bin 0 -> 1880893 bytes tests/test_scripts/fsx.sh | 13 + tests/test_scripts/hadoop2_test.sh | 250 + tests/test_scripts/hadoop_ssl_test.sh | 195 + tests/test_scripts/hadoop_test.sh | 216 + tests/test_scripts/junit_tests.sh | 147 + tests/test_scripts/marked_block.pl | 196 + tests/test_scripts/marked_block_helper.pl | 196 + .../pjd-fstest-20090130-RC_XtreemFS/LICENSE | 27 + .../pjd-fstest-20090130-RC_XtreemFS/Makefile | 16 + .../pjd-fstest-20090130-RC_XtreemFS/README | 28 + .../README.XtreemFS | 14 + .../pjd-fstest-20090130-RC_XtreemFS/bogus.t | 4 + .../pjd-fstest-20090130-RC_XtreemFS/fstest.c | 1173 + .../mkfifo/00.t | 73 + .../mkfifo/01.t | 18 + .../mkfifo/02.t | 13 + .../mkfifo/03.t | 23 + .../mkfifo/04.t | 16 + .../mkfifo/05.t | 29 + .../mkfifo/06.t | 29 + .../mkfifo/07.t | 19 + .../mkfifo/08.t | 34 + .../mkfifo/09.t | 27 + .../mkfifo/10.t | 53 + .../mkfifo/11.t | 36 + .../mkfifo/12.t | 12 + .../tests/chflags/00.t | 178 + .../tests/chflags/01.t | 20 + .../tests/chflags/02.t | 18 + .../tests/chflags/03.t | 25 + .../tests/chflags/04.t | 19 + .../tests/chflags/05.t | 35 + .../tests/chflags/06.t | 21 + .../tests/chflags/07.t | 54 + .../tests/chflags/08.t | 70 + .../tests/chflags/09.t | 82 + .../tests/chflags/10.t | 62 + .../tests/chflags/11.t | 70 + .../tests/chflags/12.t | 43 + .../tests/chflags/13.t | 14 + .../tests/chmod/00.t | 161 + .../tests/chmod/01.t | 18 + .../tests/chmod/02.t.length | 15 + .../tests/chmod/03.t | 24 + .../tests/chmod/04.t | 17 + .../tests/chmod/05.t | 31 + .../tests/chmod/06.t | 19 + .../tests/chmod/07.t | 31 + .../tests/chmod/08.t | 59 + .../tests/chmod/09.t | 37 + .../tests/chmod/10.t | 12 + .../tests/chmod/11.t | 53 + .../tests/chown/00.t | 376 + .../tests/chown/01.t | 18 + .../tests/chown/02.t.length | 15 + .../tests/chown/03.t | 24 + .../tests/chown/04.t | 17 + .../tests/chown/05.t | 32 + .../tests/chown/06.t | 19 + .../tests/chown/07.t | 28 + .../tests/chown/08.t | 53 + .../tests/chown/09.t | 37 + .../tests/chown/10.t | 12 + .../tests/conf | 8 + .../tests/link/00.t | 151 + .../tests/link/01.t | 22 + .../tests/link/02.t.length | 23 + .../tests/link/03.t | 32 + .../tests/link/04.t | 20 + .../tests/link/05.t | 41 + .../tests/link/06.t | 43 + .../tests/link/07.t | 41 + .../tests/link/08.t | 24 + .../tests/link/09.t | 18 + .../tests/link/10.t | 32 + .../tests/link/11.t | 41 + .../tests/link/12.t | 55 + .../tests/link/13.t | 56 + .../tests/link/14.t | 34 + .../tests/link/15.t | 38 + .../tests/link/16.t | 39 + .../tests/link/17.t | 20 + .../tests/misc.sh | 157 + .../tests/mkdir/00.t | 73 + .../tests/mkdir/01.t | 18 + .../tests/mkdir/02.t.length | 13 + .../tests/mkdir/03.t | 23 + .../tests/mkdir/04.t | 16 + .../tests/mkdir/05.t | 29 + .../tests/mkdir/06.t | 29 + .../tests/mkdir/07.t | 19 + .../tests/mkdir/08.t | 53 + .../tests/mkdir/09.t | 34 + .../tests/mkdir/10.t | 27 + .../tests/mkdir/11.t | 36 + .../tests/mkdir/12.t | 12 + .../tests/open/00.t | 99 + .../tests/open/01.t | 18 + .../tests/open/02.t.length | 14 + .../tests/open/03.t | 24 + .../tests/open/04.t | 17 + .../tests/open/05.t | 29 + .../tests/open/06.t | 102 + .../tests/open/07.t | 45 + .../tests/open/08.t | 19 + .../tests/open/09.t | 53 + .../tests/open/10.t | 45 + .../tests/open/11.t | 39 + .../tests/open/12.t | 19 + .../tests/open/13.t | 24 + .../tests/open/14.t | 37 + .../tests/open/15.t | 32 + .../tests/open/16.t | 29 + .../tests/open/17.t | 15 + .../tests/open/18.t | 25 + .../tests/open/19.t | 37 + .../tests/open/20.t | 25 + .../tests/open/21.t | 12 + .../tests/open/22.t | 27 + .../tests/open/23.t | 24 + .../tests/rename/00.t | 141 + .../tests/rename/01.t.length | 21 + .../tests/rename/02.t | 28 + .../tests/rename/03.t | 20 + .../tests/rename/04.t | 43 + .../tests/rename/05.t | 41 + .../tests/rename/06.t | 50 + .../tests/rename/07.t | 95 + .../tests/rename/08.t | 95 + .../tests/rename/09.t | 94 + .../tests/rename/10.t | 243 + .../tests/rename/11.t | 24 + .../tests/rename/12.t | 22 + .../tests/rename/13.t | 34 + .../tests/rename/14.t | 34 + .../tests/rename/15.t | 45 + .../tests/rename/16.t | 37 + .../tests/rename/17.t | 20 + .../tests/rename/18.t | 22 + .../tests/rename/19.t | 30 + .../tests/rename/20.t | 35 + .../tests/rmdir/00.t | 28 + .../tests/rmdir/01.t | 30 + .../tests/rmdir/02.t.length | 14 + .../tests/rmdir/03.t | 24 + .../tests/rmdir/04.t | 17 + .../tests/rmdir/05.t | 19 + .../tests/rmdir/06.t | 36 + .../tests/rmdir/07.t | 27 + .../tests/rmdir/08.t | 27 + .../tests/rmdir/09.t | 49 + .../tests/rmdir/10.t | 52 + .../tests/rmdir/11.t | 40 + .../tests/rmdir/12.t | 29 + .../tests/rmdir/13.t | 27 + .../tests/rmdir/14.t | 32 + .../tests/rmdir/15.t | 12 + .../tests/symlink/00.t | 32 + .../tests/symlink/01.t | 18 + .../tests/symlink/02.t.length | 20 + .../tests/symlink/03.t | 28 + .../tests/symlink/04.t | 16 + .../tests/symlink/05.t | 34 + .../tests/symlink/06.t | 34 + .../tests/symlink/07.t | 19 + .../tests/symlink/08.t | 23 + .../tests/symlink/09.t | 53 + .../tests/symlink/10.t | 37 + .../tests/symlink/11.t | 36 + .../tests/symlink/12.t | 18 + .../tests/truncate/00.t | 51 + .../tests/truncate/01.t | 18 + .../tests/truncate/02.t.length | 15 + .../tests/truncate/03.t | 24 + .../tests/truncate/04.t | 17 + .../tests/truncate/05.t | 32 + .../tests/truncate/06.t | 24 + .../tests/truncate/07.t | 19 + .../tests/truncate/08.t | 59 + .../tests/truncate/09.t | 15 + .../tests/truncate/10.t | 37 + .../tests/truncate/11.t | 23 + .../tests/truncate/12.t | 27 + .../tests/truncate/13.t | 16 + .../tests/truncate/14.t | 12 + .../tests/unlink/00.t | 115 + .../tests/unlink/01.t | 18 + .../tests/unlink/02.t.length | 14 + .../tests/unlink/03.t | 24 + .../tests/unlink/04.t | 17 + .../tests/unlink/05.t | 27 + .../tests/unlink/06.t | 27 + .../tests/unlink/07.t | 19 + .../tests/unlink/08.t | 28 + .../tests/unlink/09.t | 49 + .../tests/unlink/10.t | 52 + .../tests/unlink/11.t | 68 + .../tests/unlink/12.t | 32 + .../tests/unlink/13.t | 12 + .../pjd-fstest-20090130-RC_XtreemFS/xacl/00.t | 105 + .../pjd-fstest-20090130-RC_XtreemFS/xacl/01.t | 83 + .../pjd-fstest-20090130-RC_XtreemFS/xacl/02.t | 144 + .../pjd-fstest-20090130-RC_XtreemFS/xacl/03.t | 136 + .../pjd-fstest-20090130-RC_XtreemFS/xacl/04.t | 114 + .../pjd-fstest-20090130-RC_XtreemFS/xacl/05.t | 77 + .../pjd-fstest-20090130-RC_XtreemFS/xacl/06.t | 124 + tests/test_scripts/posix_test_suite.sh | 63 + .../ronly_replication_add_delete_replica.sh | 123 + tests/test_scripts/system_chstatus_test.sh | 53 + tests/test_scripts/system_cleanup_test.sh | 30 + .../system_mkfs_lsfs_rmfs_test.sh | 40 + tests/test_scripts/system_mrcdbtool_test.sh | 24 + tests/test_scripts/system_scrub_test.sh | 66 + tests/test_scripts/system_snap_test.sh | 142 + tests/test_scripts/test_flocks.sh | 34 + tests/test_scripts/test_xattrs.sh | 25 + tests/test_server.py | 329 + tests/test_volume.py | 159 + tests/utils/ltp-fsx.c | 1083 + tests/xstartserv | 281 + tests/xtestenv | 563 + 2103 files changed, 928962 insertions(+) create mode 100644 AUTHORS create mode 100644 CHANGELOG create mode 100644 KNOWN_ISSUES create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 Vagrantfile create mode 100755 bin/cpplint.py create mode 100755 bin/protoc-gen-pbrpc create mode 100755 bin/protoc-gen-pbrpccpp create mode 100755 bin/toggle_jcip_annnotations.sh create mode 100755 bin/umount.xtreemfs create mode 100755 bin/xtfs_benchmark create mode 100755 bin/xtfs_chstatus create mode 100755 bin/xtfs_cleanup create mode 100755 bin/xtfs_mrcdbtool create mode 100755 bin/xtfs_remove_osd create mode 100755 bin/xtfs_scrub create mode 100755 contrib/benchmark/benchmark.sh create mode 100755 contrib/benchmark/drop_caches create mode 100644 contrib/filter-MRC-dump-with-XSLT/filter_files.xslt create mode 100644 contrib/ganglia-plugin/.project create mode 100644 contrib/ganglia-plugin/.pydevproject create mode 100644 contrib/ganglia-plugin/README.txt create mode 100644 contrib/ganglia-plugin/config-files/xtfs-dir.pyconf create mode 100644 contrib/ganglia-plugin/config-files/xtfs-mrc.pyconf create mode 100644 contrib/ganglia-plugin/config-files/xtfs-osd.pyconf create mode 100644 contrib/ganglia-plugin/src/xtfs-dir-plugin.py create mode 100644 contrib/ganglia-plugin/src/xtfs-mrc-plugin.py create mode 100644 contrib/ganglia-plugin/src/xtfs-osd-plugin.py create mode 100755 contrib/osd-health/osd_health_check.sh create mode 100644 contrib/server-repl-plugin/BabuDB_replication_plugin.jar create mode 100644 contrib/server-repl-plugin/LICENSE create mode 100644 contrib/server-repl-plugin/README create mode 100644 contrib/server-repl-plugin/config/dir.properties create mode 100644 contrib/server-repl-plugin/config/mrc.properties create mode 100755 contrib/server-repl-plugin/update_BabuDB_replication_plugin_jar.sh create mode 100755 contrib/travis/parse_results.py create mode 100644 contrib/vagrant/provision.sh create mode 100755 contrib/xtreemfs-osd-farm/xtreemfs-osd-farm create mode 100644 cpp/CMakeLists.txt create mode 100644 cpp/Doxyfile create mode 100644 cpp/cmake/FindValgrind.cmake create mode 100644 cpp/cpp_prj/.dep.inc create mode 100644 cpp/cpp_prj/cpp_prj-Makefile.mk create mode 100644 cpp/cpp_prj/nbproject/Makefile-Default.mk create mode 100644 cpp/cpp_prj/nbproject/Makefile-impl.mk create mode 100644 cpp/cpp_prj/nbproject/Makefile-variables.mk create mode 100644 cpp/cpp_prj/nbproject/Package-Default.bash create mode 100644 cpp/cpp_prj/nbproject/configurations.xml create mode 100644 cpp/cpp_prj/nbproject/private/configurations.xml create mode 100644 cpp/cpp_prj/nbproject/private/private.properties create mode 100644 cpp/cpp_prj/nbproject/private/private.xml create mode 100644 cpp/cpp_prj/nbproject/project.properties create mode 100644 cpp/cpp_prj/nbproject/project.xml create mode 100644 cpp/generated/include/Common.pb.cc create mode 100644 cpp/generated/include/Common.pb.h create mode 100644 cpp/generated/include/PBRPC.pb.cc create mode 100644 cpp/generated/include/PBRPC.pb.h create mode 100644 cpp/generated/pbrpc/Ping.pb.cc create mode 100644 cpp/generated/pbrpc/Ping.pb.h create mode 100644 cpp/generated/pbrpc/PingServiceClient.h create mode 100644 cpp/generated/pbrpc/PingServiceConstants.h create mode 100644 cpp/generated/pbrpc/RPC.pb.cc create mode 100644 cpp/generated/pbrpc/RPC.pb.h create mode 100644 cpp/generated/xtreemfs/DIR.pb.cc create mode 100644 cpp/generated/xtreemfs/DIR.pb.h create mode 100644 cpp/generated/xtreemfs/DIRServiceClient.h create mode 100644 cpp/generated/xtreemfs/DIRServiceConstants.h create mode 100644 cpp/generated/xtreemfs/GlobalTypes.pb.cc create mode 100644 cpp/generated/xtreemfs/GlobalTypes.pb.h create mode 100644 cpp/generated/xtreemfs/MRC.pb.cc create mode 100644 cpp/generated/xtreemfs/MRC.pb.h create mode 100644 cpp/generated/xtreemfs/MRCServiceClient.h create mode 100644 cpp/generated/xtreemfs/MRCServiceConstants.h create mode 100644 cpp/generated/xtreemfs/OSD.pb.cc create mode 100644 cpp/generated/xtreemfs/OSD.pb.h create mode 100644 cpp/generated/xtreemfs/OSDServiceClient.h create mode 100644 cpp/generated/xtreemfs/OSDServiceConstants.h create mode 100644 cpp/generated/xtreemfs/get_request_message.cc create mode 100644 cpp/generated/xtreemfs/get_request_message.h create mode 100644 cpp/include/cbfs/cbfs_adapter.h create mode 100644 cpp/include/cbfs/cbfs_enumeration_context.h create mode 100644 cpp/include/cbfs/cbfs_options.h create mode 100644 cpp/include/fuse/cached_directory_entries.h create mode 100644 cpp/include/fuse/fuse_adapter.h create mode 100644 cpp/include/fuse/fuse_operations.h create mode 100644 cpp/include/fuse/fuse_options.h create mode 100644 cpp/include/json/json-forwards.h create mode 100644 cpp/include/json/json.h create mode 100644 cpp/include/ld_preload/environment.h create mode 100644 cpp/include/ld_preload/misc.h create mode 100644 cpp/include/ld_preload/open_file_table.h create mode 100644 cpp/include/ld_preload/passthrough.h create mode 100644 cpp/include/ld_preload/path.h create mode 100644 cpp/include/ld_preload/preload.h create mode 100644 cpp/include/ld_preload/preload_options.h create mode 100644 cpp/include/libxtreemfs/async_write_buffer.h create mode 100644 cpp/include/libxtreemfs/async_write_handler.h create mode 100644 cpp/include/libxtreemfs/client.h create mode 100644 cpp/include/libxtreemfs/client_implementation.h create mode 100644 cpp/include/libxtreemfs/container_uuid_iterator.h create mode 100644 cpp/include/libxtreemfs/execute_sync_request.h create mode 100644 cpp/include/libxtreemfs/file_handle.h create mode 100644 cpp/include/libxtreemfs/file_handle_implementation.h create mode 100644 cpp/include/libxtreemfs/file_info.h create mode 100644 cpp/include/libxtreemfs/helper.h create mode 100644 cpp/include/libxtreemfs/interrupt.h create mode 100644 cpp/include/libxtreemfs/metadata_cache.h create mode 100644 cpp/include/libxtreemfs/metadata_cache_entry.h create mode 100644 cpp/include/libxtreemfs/object_cache.h create mode 100644 cpp/include/libxtreemfs/options.h create mode 100644 cpp/include/libxtreemfs/pbrpc_url.h create mode 100644 cpp/include/libxtreemfs/simple_uuid_iterator.h create mode 100644 cpp/include/libxtreemfs/stripe_translator.h create mode 100644 cpp/include/libxtreemfs/system_user_mapping.h create mode 100644 cpp/include/libxtreemfs/system_user_mapping_unix.h create mode 100644 cpp/include/libxtreemfs/system_user_mapping_windows.h create mode 100644 cpp/include/libxtreemfs/typedefs.h create mode 100644 cpp/include/libxtreemfs/user_mapping.h create mode 100644 cpp/include/libxtreemfs/user_mapping_gridmap.h create mode 100644 cpp/include/libxtreemfs/user_mapping_gridmap_globus.h create mode 100644 cpp/include/libxtreemfs/user_mapping_gridmap_unicore.h create mode 100644 cpp/include/libxtreemfs/user_mapping_unix.h create mode 100644 cpp/include/libxtreemfs/uuid_cache.h create mode 100644 cpp/include/libxtreemfs/uuid_container.h create mode 100644 cpp/include/libxtreemfs/uuid_item.h create mode 100644 cpp/include/libxtreemfs/uuid_iterator.h create mode 100644 cpp/include/libxtreemfs/uuid_resolver.h create mode 100644 cpp/include/libxtreemfs/version_management.h create mode 100644 cpp/include/libxtreemfs/vivaldi.h create mode 100644 cpp/include/libxtreemfs/vivaldi_node.h create mode 100644 cpp/include/libxtreemfs/volume.h create mode 100644 cpp/include/libxtreemfs/volume_implementation.h create mode 100644 cpp/include/libxtreemfs/xcap_handler.h create mode 100644 cpp/include/libxtreemfs/xtreemfs_exception.h create mode 100644 cpp/include/lsfs.xtreemfs/lsfs_options.h create mode 100644 cpp/include/mkfs.xtreemfs/mkfs_options.h create mode 100644 cpp/include/rmfs.xtreemfs/rmfs_options.h create mode 100644 cpp/include/rpc/abstract_socket_channel.h create mode 100644 cpp/include/rpc/callback_interface.h create mode 100644 cpp/include/rpc/client.h create mode 100644 cpp/include/rpc/client_connection.h create mode 100644 cpp/include/rpc/client_request.h create mode 100644 cpp/include/rpc/client_request_callback_interface.h create mode 100644 cpp/include/rpc/grid_ssl_socket_channel.h create mode 100644 cpp/include/rpc/record_marker.h create mode 100644 cpp/include/rpc/ssl_options.h create mode 100644 cpp/include/rpc/ssl_socket_channel.h create mode 100644 cpp/include/rpc/sync_callback.h create mode 100644 cpp/include/rpc/tcp_socket_channel.h create mode 100644 cpp/include/util/annotations.h create mode 100644 cpp/include/util/error_log.h create mode 100644 cpp/include/util/logging.h create mode 100644 cpp/include/util/synchronized_queue.h create mode 100644 cpp/include/util/zipf_generator.h create mode 100644 cpp/include/xtfsutil/xtfsutil_server.h create mode 100644 cpp/src/cbfs/cbfs_adapter.cpp create mode 100644 cpp/src/cbfs/cbfs_enumeration_context.cpp create mode 100644 cpp/src/cbfs/cbfs_options.cpp create mode 100644 cpp/src/cbfs/mount.xtreemfs.cpp create mode 100644 cpp/src/example_libxtreemfs/example_libxtreemfs.cpp create mode 100644 cpp/src/example_libxtreemfs/example_replication.cpp create mode 100644 cpp/src/fuse/fuse_adapter.cpp create mode 100644 cpp/src/fuse/fuse_operations.cpp create mode 100644 cpp/src/fuse/fuse_options.cpp create mode 100644 cpp/src/fuse/mount.xtreemfs.cpp create mode 100644 cpp/src/json/jsoncpp.cpp create mode 100644 cpp/src/ld_preload/environment.cpp create mode 100644 cpp/src/ld_preload/functions.cpp create mode 100644 cpp/src/ld_preload/misc.cpp create mode 100644 cpp/src/ld_preload/open_file_table.cpp create mode 100644 cpp/src/ld_preload/passthrough.cpp create mode 100644 cpp/src/ld_preload/path.cpp create mode 100644 cpp/src/ld_preload/preload.cpp create mode 100644 cpp/src/ld_preload/preload_options.cpp create mode 100644 cpp/src/libxtreemfs/async_write_buffer.cpp create mode 100644 cpp/src/libxtreemfs/async_write_handler.cpp create mode 100644 cpp/src/libxtreemfs/client.cpp create mode 100644 cpp/src/libxtreemfs/client_implementation.cpp create mode 100644 cpp/src/libxtreemfs/container_uuid_iterator.cpp create mode 100644 cpp/src/libxtreemfs/execute_sync_request.cpp create mode 100644 cpp/src/libxtreemfs/file_handle_implementation.cpp create mode 100644 cpp/src/libxtreemfs/file_info.cpp create mode 100644 cpp/src/libxtreemfs/helper.cpp create mode 100644 cpp/src/libxtreemfs/interrupt.cpp create mode 100644 cpp/src/libxtreemfs/metadata_cache.cpp create mode 100644 cpp/src/libxtreemfs/metadata_cache_entry.cpp create mode 100644 cpp/src/libxtreemfs/object_cache.cpp create mode 100644 cpp/src/libxtreemfs/options.cpp create mode 100644 cpp/src/libxtreemfs/pbrpc_url.cpp create mode 100644 cpp/src/libxtreemfs/simple_uuid_iterator.cpp create mode 100644 cpp/src/libxtreemfs/stripe_translator.cpp create mode 100644 cpp/src/libxtreemfs/system_user_mapping.cpp create mode 100644 cpp/src/libxtreemfs/system_user_mapping_unix.cpp create mode 100644 cpp/src/libxtreemfs/system_user_mapping_windows.cpp create mode 100644 cpp/src/libxtreemfs/user_mapping.cpp create mode 100644 cpp/src/libxtreemfs/user_mapping_gridmap.cpp create mode 100644 cpp/src/libxtreemfs/user_mapping_gridmap_globus.cpp create mode 100644 cpp/src/libxtreemfs/user_mapping_gridmap_unicore.cpp create mode 100644 cpp/src/libxtreemfs/uuid_cache.cpp create mode 100644 cpp/src/libxtreemfs/uuid_container.cpp create mode 100644 cpp/src/libxtreemfs/uuid_iterator.cpp create mode 100644 cpp/src/libxtreemfs/vivaldi.cpp create mode 100644 cpp/src/libxtreemfs/vivaldi_node.cpp create mode 100644 cpp/src/libxtreemfs/volume_implementation.cpp create mode 100644 cpp/src/lsfs.xtreemfs/lsfs.xtreemfs.cpp create mode 100644 cpp/src/lsfs.xtreemfs/lsfs_options.cpp create mode 100644 cpp/src/mkfs.xtreemfs/mkfs.xtreemfs.cpp create mode 100644 cpp/src/mkfs.xtreemfs/mkfs_options.cpp create mode 100644 cpp/src/rmfs.xtreemfs/rmfs.xtreemfs.cpp create mode 100644 cpp/src/rmfs.xtreemfs/rmfs_options.cpp create mode 100644 cpp/src/rpc/client.cpp create mode 100644 cpp/src/rpc/client_connection.cpp create mode 100644 cpp/src/rpc/client_request.cpp create mode 100644 cpp/src/rpc/record_marker.cpp create mode 100644 cpp/src/rpc/sync_callback.cpp create mode 100644 cpp/src/util/error_log.cpp create mode 100644 cpp/src/util/logging.cpp create mode 100644 cpp/src/util/zipf_generator.cpp create mode 100644 cpp/src/xtfsutil/xtfsutil.cpp create mode 100644 cpp/src/xtfsutil/xtfsutil_server.cpp create mode 100644 cpp/test/common/drop_rules.h create mode 100644 cpp/test/common/test_environment.cpp create mode 100644 cpp/test/common/test_environment.h create mode 100644 cpp/test/common/test_rpc_server.h create mode 100644 cpp/test/common/test_rpc_server_dir.cpp create mode 100644 cpp/test/common/test_rpc_server_dir.h create mode 100644 cpp/test/common/test_rpc_server_mrc.cpp create mode 100644 cpp/test/common/test_rpc_server_mrc.h create mode 100644 cpp/test/common/test_rpc_server_osd.cpp create mode 100644 cpp/test/common/test_rpc_server_osd.h create mode 100644 cpp/test/fuse/fuse_options_test.cpp create mode 100755 cpp/test/ld_preload/cp.sh create mode 100644 cpp/test/ld_preload/preload_test.cpp create mode 100755 cpp/test/ld_preload/preload_test.sh create mode 100755 cpp/test/ld_preload/setfattr.sh create mode 100644 cpp/test/libxtreemfs/async_write_handler_test.cpp create mode 100644 cpp/test/libxtreemfs/client_implementation_test.cpp create mode 100644 cpp/test/libxtreemfs/helper_test.cpp create mode 100644 cpp/test/libxtreemfs/metadata_cache_test.cpp create mode 100644 cpp/test/libxtreemfs/object_cache_test.cpp create mode 100644 cpp/test/libxtreemfs/options_test.cpp create mode 100644 cpp/test/libxtreemfs/pbprpc_url_test.cpp create mode 100644 cpp/test/libxtreemfs/system_user_mapping_unix_test.cpp create mode 100644 cpp/test/libxtreemfs/user_mapping_gridmap_globus_test.cpp create mode 100644 cpp/test/libxtreemfs/user_mapping_gridmap_unicore_test.cpp create mode 100644 cpp/test/libxtreemfs/uuid_iterator_test.cpp create mode 100644 cpp/test/libxtreemfs/volume_implementation_test.cpp create mode 100644 cpp/test/rpc/client_ssl_test.cpp create mode 100644 cpp/test/rpc/client_test.cpp create mode 100644 cpp/thirdparty/gtest-1.7.0/CHANGES create mode 100644 cpp/thirdparty/gtest-1.7.0/CMakeLists.txt create mode 100644 cpp/thirdparty/gtest-1.7.0/CONTRIBUTORS create mode 100644 cpp/thirdparty/gtest-1.7.0/LICENSE create mode 100644 cpp/thirdparty/gtest-1.7.0/Makefile.am create mode 100644 cpp/thirdparty/gtest-1.7.0/Makefile.in create mode 100644 cpp/thirdparty/gtest-1.7.0/README create mode 100644 cpp/thirdparty/gtest-1.7.0/aclocal.m4 create mode 100755 cpp/thirdparty/gtest-1.7.0/build-aux/config.guess create mode 100644 cpp/thirdparty/gtest-1.7.0/build-aux/config.h.in create mode 100755 cpp/thirdparty/gtest-1.7.0/build-aux/config.sub create mode 100755 cpp/thirdparty/gtest-1.7.0/build-aux/depcomp create mode 100755 cpp/thirdparty/gtest-1.7.0/build-aux/install-sh create mode 100644 cpp/thirdparty/gtest-1.7.0/build-aux/ltmain.sh create mode 100755 cpp/thirdparty/gtest-1.7.0/build-aux/missing create mode 100644 cpp/thirdparty/gtest-1.7.0/cmake/internal_utils.cmake create mode 100644 cpp/thirdparty/gtest-1.7.0/codegear/gtest.cbproj create mode 100644 cpp/thirdparty/gtest-1.7.0/codegear/gtest.groupproj create mode 100644 cpp/thirdparty/gtest-1.7.0/codegear/gtest_all.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/codegear/gtest_link.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/codegear/gtest_main.cbproj create mode 100644 cpp/thirdparty/gtest-1.7.0/codegear/gtest_unittest.cbproj create mode 100755 cpp/thirdparty/gtest-1.7.0/configure create mode 100644 cpp/thirdparty/gtest-1.7.0/configure.ac create mode 100644 cpp/thirdparty/gtest-1.7.0/fused-src/gtest/gtest-all.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/fused-src/gtest/gtest.h create mode 100644 cpp/thirdparty/gtest-1.7.0/fused-src/gtest/gtest_main.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/gtest-death-test.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/gtest-message.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/gtest-param-test.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/gtest-param-test.h.pump create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/gtest-printers.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/gtest-spi.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/gtest-test-part.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/gtest-typed-test.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/gtest.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/gtest_pred_impl.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/gtest_prod.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-filepath.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-internal.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h.pump create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-param-util.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-port.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-string.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-tuple.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-tuple.h.pump create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-type-util.h create mode 100644 cpp/thirdparty/gtest-1.7.0/include/gtest/internal/gtest-type-util.h.pump create mode 100644 cpp/thirdparty/gtest-1.7.0/m4/acx_pthread.m4 create mode 100644 cpp/thirdparty/gtest-1.7.0/m4/gtest.m4 create mode 100644 cpp/thirdparty/gtest-1.7.0/m4/libtool.m4 create mode 100644 cpp/thirdparty/gtest-1.7.0/m4/ltoptions.m4 create mode 100644 cpp/thirdparty/gtest-1.7.0/m4/ltsugar.m4 create mode 100644 cpp/thirdparty/gtest-1.7.0/m4/ltversion.m4 create mode 100644 cpp/thirdparty/gtest-1.7.0/m4/lt~obsolete.m4 create mode 100644 cpp/thirdparty/gtest-1.7.0/make/Makefile create mode 100755 cpp/thirdparty/gtest-1.7.0/msvc/gtest-md.sln create mode 100755 cpp/thirdparty/gtest-1.7.0/msvc/gtest-md.vcproj create mode 100755 cpp/thirdparty/gtest-1.7.0/msvc/gtest.sln create mode 100755 cpp/thirdparty/gtest-1.7.0/msvc/gtest.vcproj create mode 100755 cpp/thirdparty/gtest-1.7.0/msvc/gtest_main-md.vcproj create mode 100755 cpp/thirdparty/gtest-1.7.0/msvc/gtest_main.vcproj create mode 100755 cpp/thirdparty/gtest-1.7.0/msvc/gtest_prod_test-md.vcproj create mode 100755 cpp/thirdparty/gtest-1.7.0/msvc/gtest_prod_test.vcproj create mode 100755 cpp/thirdparty/gtest-1.7.0/msvc/gtest_unittest-md.vcproj create mode 100755 cpp/thirdparty/gtest-1.7.0/msvc/gtest_unittest.vcproj create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/prime_tables.h create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample1.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample1.h create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample10_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample1_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample2.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample2.h create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample2_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample3-inl.h create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample3_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample4.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample4.h create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample4_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample5_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample6_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample7_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample8_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/samples/sample9_unittest.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/scripts/fuse_gtest_files.py create mode 100755 cpp/thirdparty/gtest-1.7.0/scripts/gen_gtest_pred_impl.py create mode 100755 cpp/thirdparty/gtest-1.7.0/scripts/gtest-config.in create mode 100755 cpp/thirdparty/gtest-1.7.0/scripts/pump.py create mode 100644 cpp/thirdparty/gtest-1.7.0/scripts/test/Makefile create mode 100644 cpp/thirdparty/gtest-1.7.0/src/gtest-all.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/src/gtest-death-test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/src/gtest-filepath.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/src/gtest-internal-inl.h create mode 100644 cpp/thirdparty/gtest-1.7.0/src/gtest-port.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/src/gtest-printers.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/src/gtest-test-part.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/src/gtest-typed-test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/src/gtest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/src/gtest_main.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-death-test_ex_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-death-test_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-filepath_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-linked_ptr_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-listener_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-message_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-options_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-param-test2_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-param-test_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-param-test_test.h create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-port_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-printers_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-test-part_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-tuple_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test2_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test_test.h create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest-unittest-api_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_all_test.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_break_on_failure_unittest.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_break_on_failure_unittest_.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_catch_exceptions_test.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_catch_exceptions_test_.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_color_test.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_color_test_.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_env_var_test.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_env_var_test_.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_environment_test.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_filter_unittest.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_filter_unittest_.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_help_test.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_help_test_.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_list_tests_unittest.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_list_tests_unittest_.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_main_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_no_test_unittest.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_output_test.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_output_test_.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_output_test_golden_lin.txt create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_pred_impl_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_premature_exit_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_prod_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_repeat_test.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_shuffle_test.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_shuffle_test_.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_sole_header_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_stress_test.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_test_utils.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_ex_test.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_test.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_test_.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_uninitialized_test.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_uninitialized_test_.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_unittest.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfile1_test_.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfile2_test_.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfiles_test.py create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_xml_output_unittest.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/gtest_xml_output_unittest_.cc create mode 100755 cpp/thirdparty/gtest-1.7.0/test/gtest_xml_test_utils.py create mode 100644 cpp/thirdparty/gtest-1.7.0/test/production.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/test/production.h create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Config/DebugProject.xcconfig create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Config/FrameworkTarget.xcconfig create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Config/General.xcconfig create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Config/ReleaseProject.xcconfig create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Config/StaticLibraryTarget.xcconfig create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Config/TestTarget.xcconfig create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Resources/Info.plist create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/Info.plist create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/runtests.sh create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget.h create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget_test.cc create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/Scripts/runtests.sh create mode 100755 cpp/thirdparty/gtest-1.7.0/xcode/Scripts/versiongenerate.py create mode 100644 cpp/thirdparty/gtest-1.7.0/xcode/gtest.xcodeproj/project.pbxproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/CHANGES.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/CONTRIBUTORS.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/COPYING.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/INSTALL.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/Makefile.am create mode 100644 cpp/thirdparty/protobuf-2.5.0/Makefile.in create mode 100644 cpp/thirdparty/protobuf-2.5.0/README.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/aclocal.m4 create mode 100755 cpp/thirdparty/protobuf-2.5.0/autogen.sh create mode 100755 cpp/thirdparty/protobuf-2.5.0/config.guess create mode 100644 cpp/thirdparty/protobuf-2.5.0/config.h.in create mode 100755 cpp/thirdparty/protobuf-2.5.0/config.sub create mode 100755 cpp/thirdparty/protobuf-2.5.0/configure create mode 100644 cpp/thirdparty/protobuf-2.5.0/configure.ac create mode 100755 cpp/thirdparty/protobuf-2.5.0/depcomp create mode 100644 cpp/thirdparty/protobuf-2.5.0/editors/README.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/editors/proto.vim create mode 100644 cpp/thirdparty/protobuf-2.5.0/editors/protobuf-mode.el create mode 100644 cpp/thirdparty/protobuf-2.5.0/examples/AddPerson.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/examples/ListPeople.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/examples/Makefile create mode 100644 cpp/thirdparty/protobuf-2.5.0/examples/README.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/examples/add_person.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/examples/add_person.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/examples/addressbook.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/examples/list_people.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/examples/list_people.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/generate_descriptor_proto.sh create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/CHANGES create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/CMakeLists.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/CONTRIBUTORS create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/LICENSE create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/Makefile.am create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/Makefile.in create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/README create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/aclocal.m4 create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.guess create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.h.in create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.sub create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/depcomp create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/install-sh create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/ltmain.sh create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/missing create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/cmake/internal_utils.cmake create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest.cbproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest.groupproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_all.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_link.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_main.cbproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_unittest.cbproj create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/configure create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/configure.ac create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest-all.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest_main.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-death-test.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-message.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-param-test.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-param-test.h.pump create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-printers.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-spi.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-test-part.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-typed-test.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest_pred_impl.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest_prod.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-death-test-internal.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-filepath.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-internal.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-linked_ptr.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util-generated.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util-generated.h.pump create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-port.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-string.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-tuple.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-tuple.h.pump create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-type-util.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-type-util.h.pump create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/m4/acx_pthread.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/m4/gtest.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/m4/libtool.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltoptions.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltsugar.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltversion.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/m4/lt~obsolete.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/make/Makefile create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest-md.sln create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest-md.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest.sln create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_main-md.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_main.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_prod_test-md.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_prod_test.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_unittest-md.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_unittest.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/prime_tables.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample10_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample3-inl.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample3_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample5_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample6_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample7_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample8_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample9_unittest.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/scripts/fuse_gtest_files.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/scripts/gen_gtest_pred_impl.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/scripts/gtest-config.in create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/scripts/pump.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/scripts/test/Makefile create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-all.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-death-test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-filepath.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-internal-inl.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-port.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-printers.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-test-part.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-typed-test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest_main.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-death-test_ex_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-death-test_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-filepath_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-linked_ptr_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-listener_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-message_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-options_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test2_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test_test.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-port_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-printers_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-test-part_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-tuple_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test2_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test_test.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-unittest-api_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_all_test.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_break_on_failure_unittest.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_break_on_failure_unittest_.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_catch_exceptions_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_catch_exceptions_test_.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_color_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_color_test_.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_env_var_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_env_var_test_.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_environment_test.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_filter_unittest.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_filter_unittest_.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_help_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_help_test_.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_list_tests_unittest.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_list_tests_unittest_.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_main_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_no_test_unittest.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test_.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test_golden_lin.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_pred_impl_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_prod_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_repeat_test.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_shuffle_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_shuffle_test_.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_sole_header_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_stress_test.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_test_utils.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_ex_test.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_test_.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_uninitialized_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_uninitialized_test_.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfile1_test_.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfile2_test_.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfiles_test.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_output_unittest.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_output_unittest_.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_test_utils.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/production.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/test/production.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/DebugProject.xcconfig create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/FrameworkTarget.xcconfig create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/General.xcconfig create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/ReleaseProject.xcconfig create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/StaticLibraryTarget.xcconfig create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/TestTarget.xcconfig create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Resources/Info.plist create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/Info.plist create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/runtests.sh create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget_test.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Scripts/runtests.sh create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Scripts/versiongenerate.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/gtest/xcode/gtest.xcodeproj/project.pbxproj create mode 100755 cpp/thirdparty/protobuf-2.5.0/install-sh create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/README.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/pom.xml create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractMessage.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractMessageLite.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractParser.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BlockingService.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BoundedByteString.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ByteString.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/CodedInputStream.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/CodedOutputStream.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Descriptors.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/DynamicMessage.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ExtensionRegistry.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/FieldSet.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/GeneratedMessage.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Internal.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyField.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyStringArrayList.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyStringList.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LiteralByteString.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Message.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageLite.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageOrBuilder.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Parser.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RopeByteString.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcCallback.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcChannel.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcController.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcUtil.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Service.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ServiceException.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/SmallSortedMap.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/TextFormat.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UninitializedMessageException.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UnknownFieldSet.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Utf8.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/WireFormat.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/AbstractMessageTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ByteStringTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DescriptorsTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DynamicMessageTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LiteTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/MessageTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/NestedBuildersTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ParserTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RopeByteStringTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ServiceTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TestUtil.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TextFormatTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/WireFormatTest.java create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/multiple_files_test.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_builders_test.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_extension.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_extension_lite.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/non_nested_extension.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/ltmain.sh create mode 100644 cpp/thirdparty/protobuf-2.5.0/m4/ac_system_extensions.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/m4/acx_check_suncc.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/m4/acx_pthread.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/m4/libtool.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/m4/ltoptions.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/m4/ltsugar.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/m4/ltversion.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/m4/lt~obsolete.m4 create mode 100644 cpp/thirdparty/protobuf-2.5.0/m4/stl_hash.m4 create mode 100755 cpp/thirdparty/protobuf-2.5.0/missing create mode 100644 cpp/thirdparty/protobuf-2.5.0/protobuf-lite.pc.in create mode 100644 cpp/thirdparty/protobuf-2.5.0/protobuf.pc.in create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/README.txt create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/ez_setup.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/__init__.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/__init__.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor_database.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor_pool.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/__init__.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/api_implementation.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/containers.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/cpp_message.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/decoder.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_database_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_pool_test.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_test.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/encoder.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/enum_type_wrapper.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/factory_test1.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/factory_test2.proto create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/generator_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_cpp_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_factory_test.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_listener.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_extensions.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_extensions_dynamic.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_messages.proto create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/python_message.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/reflection_cpp_generated_test.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/reflection_test.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/service_reflection_test.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/test_bad_identifiers.proto create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/test_util.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/text_format_test.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/type_checkers.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/unknown_fields_test.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/wire_format.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/wire_format_test.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/message.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/message_factory.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python-proto2.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_descriptor.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_descriptor.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_protobuf.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_protobuf.h create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/reflection.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/service.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/service_reflection.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/text_format.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/mox.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/setup.py create mode 100755 cpp/thirdparty/protobuf-2.5.0/python/stubout.py create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/Makefile.am create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/Makefile.in create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/code_generator.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/code_generator.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum_field.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum_field.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_extension.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_extension.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_field.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_field.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_file.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_file.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_generator.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_generator.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_helpers.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_helpers.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message_field.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message_field.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_options.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_primitive_field.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_service.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_service.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_string_field.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_string_field.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_unittest.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum_field.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum_field.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_extension.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_extension.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_field.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_field.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_file.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_file.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_generator.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_generator.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_helpers.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_helpers.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message_field.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message_field.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_plugin_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_primitive_field.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_primitive_field.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_service.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_service.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_string_field.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_string_field.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/main.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/mock_code_generator.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/mock_code_generator.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/package_info.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.pb.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.pb.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_generator.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_generator.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_plugin_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/subprocess.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/subprocess.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/test_plugin.cc create mode 100755 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_output_unittest.sh create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_writer.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_writer.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.pb.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.pb.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set_heavy.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_enum_reflection.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_util.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_util.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream_inl.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream.h create mode 100755 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream_unittest.sh create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/package_info.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl_lite.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl_lite.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/lite_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_lite.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_lite.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/package_info.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field_reflection_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/service.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/service.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_macosx.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_pnacl.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/hash.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/map-util.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/platform_macros.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stl_util.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/structurally_valid.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/structurally_valid_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/substitute.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/substitute.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/template_util.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/template_util_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/type_traits.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/type_traits_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util_lite.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util_lite.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/golden_message create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/golden_packed_fields_message create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/text_format_unittest_data.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/file.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/file.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/googletest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/googletest.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/zcgunzip.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/zcgzip.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_custom_options.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_embed_optimize_for.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_empty.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_enormous_descriptor.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_lite.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_public.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_public_lite.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_lite.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_lite_imports_nonlite.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_mset.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_no_generic_services.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_optimize_for.proto create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite_inl.h create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_unittest.cc create mode 100644 cpp/thirdparty/protobuf-2.5.0/src/solaris/libstdc++.la create mode 100644 cpp/thirdparty/protobuf-2.5.0/vsprojects/config.h create mode 100755 cpp/thirdparty/protobuf-2.5.0/vsprojects/convert2008to2005.sh create mode 100755 cpp/thirdparty/protobuf-2.5.0/vsprojects/extract_includes.bat create mode 100644 cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotobuf-lite.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotobuf.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotoc.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/vsprojects/lite-test.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/vsprojects/protobuf.sln create mode 100644 cpp/thirdparty/protobuf-2.5.0/vsprojects/protoc.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/vsprojects/readme.txt create mode 100755 cpp/thirdparty/protobuf-2.5.0/vsprojects/test_plugin.vcproj create mode 100644 cpp/thirdparty/protobuf-2.5.0/vsprojects/tests.vcproj create mode 100644 cpp/valgrind.supp create mode 100755 etc/init.d/generate_initd_scripts.sh create mode 100644 etc/init.d/xtreemfs-service.template create mode 100644 etc/xos/xtreemfs/datacentermap.example create mode 100644 etc/xos/xtreemfs/default_dir create mode 100644 etc/xos/xtreemfs/dirconfig.properties create mode 100644 etc/xos/xtreemfs/mrcconfig.properties create mode 100644 etc/xos/xtreemfs/osdconfig.properties create mode 100644 etc/xos/xtreemfs/snmp.acl create mode 100644 interface/Makefile create mode 100644 interface/include/Common.proto create mode 100644 interface/include/PBRPC.proto create mode 100644 interface/pbrpc/Ping.proto create mode 100644 interface/pbrpc/RPC.proto create mode 100644 interface/xtreemfs/DIR.proto create mode 100644 interface/xtreemfs/GlobalTypes.proto create mode 100644 interface/xtreemfs/MRC.proto create mode 100644 interface/xtreemfs/OSD.proto create mode 100644 java/flease/build-1.6.5.xml create mode 100644 java/flease/build.xml create mode 100644 java/flease/eclipse-project/.classpath create mode 100644 java/flease/eclipse-project/.project create mode 100644 java/flease/manifest.mf create mode 100644 java/flease/nbproject/build-impl-1.6.5.xml create mode 100644 java/flease/nbproject/build-impl.xml create mode 100644 java/flease/nbproject/genfiles.properties create mode 100644 java/flease/nbproject/private/config.properties create mode 100644 java/flease/nbproject/private/private.properties create mode 100644 java/flease/nbproject/private/private.xml create mode 100644 java/flease/nbproject/private/profiler/configurations.xml create mode 100644 java/flease/nbproject/profiler-build-impl.xml create mode 100644 java/flease/nbproject/project.properties create mode 100644 java/flease/nbproject/project.xml create mode 100644 java/flease/nbproject/protobuf-build.cfg.xml create mode 100644 java/flease/nbproject/protobuf-build.xml create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/Flease.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/FleaseConfig.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/FleaseFuture.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/FleaseMessageSenderInterface.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/FleaseStage.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/FleaseStats.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/FleaseStatusListener.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/FleaseViewChangeListenerInterface.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/MasterEpochHandlerInterface.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/SimpleMasterEpochHandler.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/UDPFleaseCommunicator.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptor.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptorCell.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseInstance.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/acceptor/LearnEventListener.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/comm/FleaseCommunicationInterface.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/comm/FleaseMessage.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/comm/ProposalNumber.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/EchoClient.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/EchoServer.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/NIOConnection.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/NIOServer.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPClient.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPCommunicator.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPConnection.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPFleaseCommunicator.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/proposer/CellAction.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseException.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseListener.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseLocalQueueInterface.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseProposer.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseProposerCell.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/sim/Communicator.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/sim/DelayedDelivery.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/sim/FleaseMultiSim.java create mode 100644 java/flease/src/org/xtreemfs/foundation/flease/sim/FleaseSim.java create mode 100644 java/flease/test/org/xtreemfs/foundation/flease/FleaseStageTest.java create mode 100644 java/flease/test/org/xtreemfs/foundation/flease/MasterEpochTest.java create mode 100644 java/flease/test/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptorTest.java create mode 100644 java/flease/test/org/xtreemfs/foundation/flease/comm/FleaseMessageTest.java create mode 100644 java/flease/test/org/xtreemfs/foundation/flease/proposer/FleaseProposerTest.java create mode 100644 java/foundation/build-1.6.5.xml create mode 100644 java/foundation/build-before-profiler.xml create mode 100644 java/foundation/build.xml create mode 100644 java/foundation/eclipse-project/.classpath create mode 100644 java/foundation/eclipse-project/.project create mode 100644 java/foundation/nbproject/build-impl-1.6.5.xml create mode 100644 java/foundation/nbproject/build-impl.xml create mode 100644 java/foundation/nbproject/genfiles.properties create mode 100644 java/foundation/nbproject/profiler-build-impl.xml create mode 100644 java/foundation/nbproject/project.properties create mode 100644 java/foundation/nbproject/project.xml create mode 100644 java/foundation/src/org/xtreemfs/foundation/ClientLease.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/CrashReporter.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/LRUCache.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/LifeCycleListener.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/LifeCycleThread.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/SSLOptions.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/TimeServerClient.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/TimeSync.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/VersionManagement.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/buffer/ASCIIString.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/buffer/BufferPool.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/buffer/ReusableBuffer.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumAlgorithm.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumFactory.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumProvider.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/checksums/StringChecksumAlgorithm.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/Adler32.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/CRC32.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/JavaChecksumAlgorithm.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/JavaHash.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/SDBM.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/checksums/provider/JavaChecksumProvider.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/json/JSONCharBufferString.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/json/JSONException.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/json/JSONInput.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/json/JSONParser.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/json/JSONString.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/logging/Logging.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/logging/Utils.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/monitoring/ListMonitoring.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/monitoring/Monitoring.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringEvent.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringListener.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringLog.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/monitoring/NumberMonitoring.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/Schemes.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/ChannelIO.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/SSLChannelIO.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/SSLHandshakeOnlyChannelIO.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/client/PBRPCException.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCAuthentication.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCClientConnection.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCClientRequest.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCNIOSocketClient.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponse.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponseAvailableListener.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponseListener.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PBRPC.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/Ping.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PingServiceClient.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PingServiceConstants.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/RPC.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCNIOSocketServer.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCNIOSocketServerConnection.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerConnectionInterface.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerInterface.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerRequest.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerRequestListener.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerResponse.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCUDPSocketServer.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/server/UDPMessage.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ErrorUtils.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/PBRPCDatagramPacket.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/RecordMarker.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ReusableBufferInputStream.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ReusableBufferOutputStream.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/trace/Tracer.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/util/CLIParser.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/util/CLOption.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/util/CLOptionParser.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/util/FSUtils.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/util/InvalidUsageException.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/util/OutputUtils.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/util/PBRPCServiceURL.java create mode 100644 java/foundation/src/org/xtreemfs/foundation/util/PingServer.java create mode 100644 java/foundation/test/org/xtreemfs/foundation/buffer/BufferPoolTest.java create mode 100644 java/foundation/test/org/xtreemfs/foundation/buffer/ReusableBufferTest.java create mode 100644 java/foundation/test/org/xtreemfs/test/foundation/checksums/ChecksumFactoryTest.java create mode 100644 java/foundation/test/org/xtreemfs/test/foundation/checksums/StringChecksumAlgorithmTest.java create mode 100644 java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCClientServerTest.java create mode 100644 java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCDatagramPacketTest.java create mode 100644 java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCTest.java create mode 100644 java/foundation/test/org/xtreemfs/test/foundation/pbrpc/RPCNIOSocketServerTest.java create mode 100644 java/foundation/test/org/xtreemfs/test/foundation/pbrpc/RPCUDPSocketServerTest.java create mode 100644 java/foundation/test/org/xtreemfs/test/foundation/util/OutputUtilsTest.java create mode 100644 java/foundation/test/org/xtreemfs/test/foundation/util/PBRPCServiceURLTest.java create mode 100755 java/init_eclipse_projects_linux.sh create mode 100644 java/init_eclipse_projects_windows.bat create mode 100644 java/lib/BabuDB.jar create mode 100644 java/lib/commons-codec-1.3.jar create mode 100644 java/lib/jdmkrt.jar create mode 100644 java/lib/jdmktk.jar create mode 100644 java/lib/protobuf-java-2.5.0.jar create mode 100644 java/lib/test/commons-httpclient-3.0.1-contrib.jar create mode 100644 java/lib/test/commons-httpclient-3.0.1.jar create mode 100644 java/lib/test/commons-logging-1.1.jar create mode 100644 java/lib/test/hamcrest-core-1.3.jar create mode 100644 java/lib/test/junit-4.11.jar create mode 100644 java/pbrpcgen/build.xml create mode 100644 java/pbrpcgen/eclipse-project/.classpath create mode 100644 java/pbrpcgen/eclipse-project/.project create mode 100644 java/pbrpcgen/manifest.mf create mode 100644 java/pbrpcgen/nbproject/build-impl.xml create mode 100644 java/pbrpcgen/nbproject/genfiles.properties create mode 100644 java/pbrpcgen/nbproject/private/private.properties create mode 100644 java/pbrpcgen/nbproject/private/private.xml create mode 100644 java/pbrpcgen/nbproject/project.properties create mode 100644 java/pbrpcgen/nbproject/project.xml create mode 100644 java/pbrpcgen/src/com/google/protobuf/compiler/PluginProtos.java create mode 100644 java/pbrpcgen/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PBRPC.java create mode 100644 java/pbrpcgen/src/org/xtreemfs/pbrpcgen/RPCCPPSourceGenerator.java create mode 100644 java/pbrpcgen/src/org/xtreemfs/pbrpcgen/RPCSourceGenerator.java create mode 100644 java/servers/build-1.6.5.xml create mode 100644 java/servers/build-before-profiler.xml create mode 100644 java/servers/build.xml create mode 100644 java/servers/eclipse-project/.classpath create mode 100644 java/servers/eclipse-project/.classpath_WITH_BabuDB_project_reference create mode 100644 java/servers/eclipse-project/.project create mode 100644 java/servers/nbproject/build-impl-1.6.5.xml create mode 100644 java/servers/nbproject/build-impl.xml create mode 100644 java/servers/nbproject/genfiles.properties create mode 100644 java/servers/nbproject/profiler-build-impl.xml create mode 100644 java/servers/nbproject/project.properties create mode 100644 java/servers/nbproject/project.xml create mode 100644 java/servers/src/org/xtreemfs/common/Capability.java create mode 100644 java/servers/src/org/xtreemfs/common/GlobalConstants.java create mode 100644 java/servers/src/org/xtreemfs/common/HeartbeatThread.java create mode 100644 java/servers/src/org/xtreemfs/common/KeyValuePairs.java create mode 100644 java/servers/src/org/xtreemfs/common/ReplicaUpdatePolicies.java create mode 100755 java/servers/src/org/xtreemfs/common/ServiceAvailability.java create mode 100644 java/servers/src/org/xtreemfs/common/auth/AuthenticationException.java create mode 100644 java/servers/src/org/xtreemfs/common/auth/AuthenticationProvider.java create mode 100644 java/servers/src/org/xtreemfs/common/auth/FederationIdX509AuthProvider.java create mode 100644 java/servers/src/org/xtreemfs/common/auth/NullAuthProvider.java create mode 100644 java/servers/src/org/xtreemfs/common/auth/SimpleX509AuthProvider.java create mode 100644 java/servers/src/org/xtreemfs/common/auth/UserCredentials.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/AbstractBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/BenchmarkConfig.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/BenchmarkFactory.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/BenchmarkFailedException.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/BenchmarkResult.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/BenchmarkUtils.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/ClientManager.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/Controller.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/FilebasedBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/FilebasedReadBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/FilebasedWriteBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/RandomOffsetbasedBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/RandomReadBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/RandomWriteBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/SequentialBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/SequentialReadBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/SequentialWriteBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/UnalignedSequentialWriteBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/UncaughtExceptionHandlerBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/common/benchmark/VolumeManager.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/CachedXAttr.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/Client.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/File.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/InvalidChecksumException.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/RandomAccessFile.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/Replica.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/Volume.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/internal/ObjectMapper.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/internal/OpenFileList.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/internal/RAID0ObjectMapper.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/io/ByteMapper.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/io/ByteMapperFactory.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/io/ByteMapperRAID0.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/io/ObjectStore.java create mode 100644 java/servers/src/org/xtreemfs/common/clients/io/RandomAccessFile.java create mode 100644 java/servers/src/org/xtreemfs/common/config/Config.java create mode 100644 java/servers/src/org/xtreemfs/common/config/PolicyClassLoader.java create mode 100644 java/servers/src/org/xtreemfs/common/config/PolicyContainer.java create mode 100644 java/servers/src/org/xtreemfs/common/config/RemoteConfigHelper.java create mode 100644 java/servers/src/org/xtreemfs/common/config/ServiceConfig.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/AdminClient.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/AdminFileHandle.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/AdminVolume.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/AsyncWriteBuffer.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/AsyncWriteHandler.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/Client.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/ClientFactory.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/ClientImplementation.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/FileHandle.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/FileHandleImplementation.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/FileInfo.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/Helper.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/MetadataCache.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/MetadataCacheEntry.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/Options.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/PeriodicFileSizeUpdateThread.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/PeriodicXcapRenewalThread.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/RPCCaller.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/ReadOperation.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/StripeTranslator.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/StripeTranslatorRaid0.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/Tupel.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/UUIDIterator.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/UUIDResolver.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/Volume.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/VolumeImplementation.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/WriteOperation.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/AddressToUUIDNotFoundException.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InternalServerErrorException.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InvalidChecksumException.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InvalidViewException.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/PosixErrorException.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/UUIDIteratorListIsEmpyException.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/UUIDNotInXlocSetException.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/VolumeNotFoundException.java create mode 100644 java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/XtreemFSException.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/DirImpl.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/GeneralImpl.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/MrcImpl.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/OsdImpl.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/StatusMonitor.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/XTREEMFS_MIBImpl.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Dir.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/DirMBean.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/DirMeta.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/General.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/GeneralMBean.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/GeneralMeta.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Mrc.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/MrcMBean.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/MrcMeta.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Osd.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/OsdMBean.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/OsdMeta.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/XTREEMFS_MIB.java create mode 100644 java/servers/src/org/xtreemfs/common/monitoring/generatedcode/XTREEMFS_MIBOidTable.java create mode 100644 java/servers/src/org/xtreemfs/common/statusserver/BabuDBStatusPage.java create mode 100644 java/servers/src/org/xtreemfs/common/statusserver/PrintStackTrace.java create mode 100644 java/servers/src/org/xtreemfs/common/statusserver/StatusServer.java create mode 100644 java/servers/src/org/xtreemfs/common/statusserver/StatusServerHelper.java create mode 100644 java/servers/src/org/xtreemfs/common/statusserver/StatusServerModule.java create mode 100644 java/servers/src/org/xtreemfs/common/util/NetUtils.java create mode 100644 java/servers/src/org/xtreemfs/common/uuids/Mapping.java create mode 100644 java/servers/src/org/xtreemfs/common/uuids/ServiceUUID.java create mode 100644 java/servers/src/org/xtreemfs/common/uuids/UUIDCacheEntry.java create mode 100644 java/servers/src/org/xtreemfs/common/uuids/UUIDResolver.java create mode 100644 java/servers/src/org/xtreemfs/common/uuids/UnknownUUIDException.java create mode 100644 java/servers/src/org/xtreemfs/common/xloc/InvalidXLocationsException.java create mode 100644 java/servers/src/org/xtreemfs/common/xloc/RAID0Impl.java create mode 100644 java/servers/src/org/xtreemfs/common/xloc/Replica.java create mode 100755 java/servers/src/org/xtreemfs/common/xloc/ReplicationFlags.java create mode 100644 java/servers/src/org/xtreemfs/common/xloc/ReplicationPolicyImplementation.java create mode 100644 java/servers/src/org/xtreemfs/common/xloc/StripingPolicyImpl.java create mode 100644 java/servers/src/org/xtreemfs/common/xloc/XLocations.java create mode 100644 java/servers/src/org/xtreemfs/dir/DIR.java create mode 100644 java/servers/src/org/xtreemfs/dir/DIRClient.java create mode 100644 java/servers/src/org/xtreemfs/dir/DIRConfig.java create mode 100644 java/servers/src/org/xtreemfs/dir/DIRRequest.java create mode 100644 java/servers/src/org/xtreemfs/dir/DIRRequestDispatcher.java create mode 100644 java/servers/src/org/xtreemfs/dir/DIRStatusListener.java create mode 100644 java/servers/src/org/xtreemfs/dir/MonitoringThread.java create mode 100644 java/servers/src/org/xtreemfs/dir/ReplicaStatusPage.java create mode 100644 java/servers/src/org/xtreemfs/dir/StatusPage.java create mode 100644 java/servers/src/org/xtreemfs/dir/VivaldiClientMap.java create mode 100644 java/servers/src/org/xtreemfs/dir/VivaldiStatusPage.java create mode 100644 java/servers/src/org/xtreemfs/dir/data/AddressMappingRecord.java create mode 100644 java/servers/src/org/xtreemfs/dir/data/AddressMappingRecords.java create mode 100644 java/servers/src/org/xtreemfs/dir/data/ConfigurationRecord.java create mode 100644 java/servers/src/org/xtreemfs/dir/data/ServiceRecord.java create mode 100644 java/servers/src/org/xtreemfs/dir/data/ServiceRecords.java create mode 100644 java/servers/src/org/xtreemfs/dir/discovery/DiscoveryMsgThread.java create mode 100644 java/servers/src/org/xtreemfs/dir/discovery/DiscoveryUtils.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/DIROperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/DeleteAddressMappingOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/DeregisterServiceOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/GetAddressMappingOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/GetConfigurationOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/GetGlobalTimeOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/GetServiceByNameOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/GetServiceByUuidOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/GetServicesByTypeOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/RegisterServiceOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/ServiceOfflineOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/SetAddressMappingOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/SetConfigurationOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/operations/UpdateVivaldiClientOperation.java create mode 100644 java/servers/src/org/xtreemfs/dir/templates/d3.js create mode 100644 java/servers/src/org/xtreemfs/dir/templates/d3.v3.js create mode 100644 java/servers/src/org/xtreemfs/dir/templates/replica_status.html create mode 100644 java/servers/src/org/xtreemfs/dir/templates/status.html create mode 100644 java/servers/src/org/xtreemfs/dir/templates/vivaldi.html create mode 100644 java/servers/src/org/xtreemfs/mrc/ErrorRecord.java create mode 100644 java/servers/src/org/xtreemfs/mrc/MRC.java create mode 100644 java/servers/src/org/xtreemfs/mrc/MRCConfig.java create mode 100644 java/servers/src/org/xtreemfs/mrc/MRCException.java create mode 100644 java/servers/src/org/xtreemfs/mrc/MRCPolicyContainer.java create mode 100644 java/servers/src/org/xtreemfs/mrc/MRCRequest.java create mode 100644 java/servers/src/org/xtreemfs/mrc/MRCRequestDispatcher.java create mode 100644 java/servers/src/org/xtreemfs/mrc/MRCStatusListener.java create mode 100644 java/servers/src/org/xtreemfs/mrc/MRCStatusManager.java create mode 100644 java/servers/src/org/xtreemfs/mrc/RequestDetails.java create mode 100644 java/servers/src/org/xtreemfs/mrc/StatusPage.java create mode 100644 java/servers/src/org/xtreemfs/mrc/UserException.java create mode 100644 java/servers/src/org/xtreemfs/mrc/ac/FileAccessManager.java create mode 100644 java/servers/src/org/xtreemfs/mrc/ac/FileAccessPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/ac/POSIXFileAccessPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/ac/VolumeACLFileAccessPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/ac/YesToAnyoneFileAccessPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/AtomicDBUpdate.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/DBAccessResultListener.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/DatabaseException.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/DatabaseResultSet.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/ReplicationManager.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/StorageManager.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/VolumeChangeListener.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/VolumeInfo.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/VolumeManager.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/babudb/AtomicBabuDBSnapshotUpdate.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/babudb/AtomicBabuDBUpdate.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBRequestListenerWrapper.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBSnapshotStorageManager.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBSnapshotVolumeInfo.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBStorageHelper.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBStorageManager.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBVolumeInfo.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBVolumeManager.java create mode 100644 java/servers/src/org/xtreemfs/mrc/database/babudb/TransactionalBabuDBUpdate.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/ACLEntry.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedACLEntry.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedFileMetadata.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedIndexMetadata.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedMetadata.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedRCMetadata.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedStripingPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXAttr.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXLoc.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXLocList.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/FileMetadata.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/ReplicationPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/StripingPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/XAttr.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/XLoc.java create mode 100644 java/servers/src/org/xtreemfs/mrc/metadata/XLocList.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/AccessOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/AddReplicaOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/CheckFileListOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/CheckpointOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/CreateDirOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/CreateLinkOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/CreateSymLinkOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/CreateVolumeOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/DeleteOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/DeleteVolumeOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/DumpDBOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/FSetAttrOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/GetFileCredentialsOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/GetLocalVolumesOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/GetSuitableOSDsOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/GetXAttrOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/GetXAttrsOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/GetXLocListOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/GetXLocSetOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/InternalDebugOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/MRCOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/MoveOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/OpenOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/ReadDirAndStatOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/ReadLinkOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/RemoveReplicaOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/RemoveXAttrOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/RenewOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/RestoreDBOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/RestoreFileOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/SetReadOnlyXattrOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/SetReplicaUpdatePolicyOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/SetXAttrOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/SetattrOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/ShutdownOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/StatFSOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/StatOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/TruncateOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/operations/UpdateFileSizeOperation.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/DCMapPolicyBase.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/FQDNPolicyBase.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/FilterDefaultPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/FilterFQDNPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/FilterUUIDPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/GroupDCMapPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/GroupFQDNPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/Inet4AddressMatcher.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/InetAddressMatcher.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/OSDSelectionPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/OSDStatusManager.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/PolicyHelper.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/SortDCMapPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/SortFQDNPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/SortHostRoundRobinPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/SortRandomPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/SortReversePolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/SortUUIDPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/SortVivaldiPolicy.java create mode 100644 java/servers/src/org/xtreemfs/mrc/osdselection/VolumeOSDFilter.java create mode 100644 java/servers/src/org/xtreemfs/mrc/stages/InternalCallbackInterface.java create mode 100644 java/servers/src/org/xtreemfs/mrc/stages/InternalCallbackMRCRequest.java create mode 100644 java/servers/src/org/xtreemfs/mrc/stages/MRCStage.java create mode 100644 java/servers/src/org/xtreemfs/mrc/stages/MRCStageCallbackInterface.java create mode 100644 java/servers/src/org/xtreemfs/mrc/stages/OnCloseReplicationThread.java create mode 100644 java/servers/src/org/xtreemfs/mrc/stages/ProcessingStage.java create mode 100644 java/servers/src/org/xtreemfs/mrc/stages/XLocSetCoordinator.java create mode 100644 java/servers/src/org/xtreemfs/mrc/stages/XLocSetCoordinatorCallback.java create mode 100644 java/servers/src/org/xtreemfs/mrc/stages/XLocSetLock.java create mode 100644 java/servers/src/org/xtreemfs/mrc/templates/status.html create mode 100644 java/servers/src/org/xtreemfs/mrc/utils/Converter.java create mode 100644 java/servers/src/org/xtreemfs/mrc/utils/DBAdminHelper.java create mode 100644 java/servers/src/org/xtreemfs/mrc/utils/MRCHelper.java create mode 100644 java/servers/src/org/xtreemfs/mrc/utils/Path.java create mode 100644 java/servers/src/org/xtreemfs/mrc/utils/PathResolver.java create mode 100644 java/servers/src/org/xtreemfs/osd/AdvisoryLock.java create mode 100644 java/servers/src/org/xtreemfs/osd/ErrorCodes.java create mode 100644 java/servers/src/org/xtreemfs/osd/InternalObjectData.java create mode 100644 java/servers/src/org/xtreemfs/osd/LocationsCache.java create mode 100644 java/servers/src/org/xtreemfs/osd/OSD.java create mode 100644 java/servers/src/org/xtreemfs/osd/OSDConfig.java create mode 100644 java/servers/src/org/xtreemfs/osd/OSDRequest.java create mode 100644 java/servers/src/org/xtreemfs/osd/OSDRequestDispatcher.java create mode 100644 java/servers/src/org/xtreemfs/osd/OSDStatusListener.java create mode 100644 java/servers/src/org/xtreemfs/osd/OpenFileTable.java create mode 100644 java/servers/src/org/xtreemfs/osd/ReplicatedFileStatusJSON.java create mode 100644 java/servers/src/org/xtreemfs/osd/ReplicatedFileStatusPage.java create mode 100644 java/servers/src/org/xtreemfs/osd/StatusPage.java create mode 100644 java/servers/src/org/xtreemfs/osd/drain/OSDDrain.java create mode 100644 java/servers/src/org/xtreemfs/osd/drain/OSDDrainException.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/CheckObjectOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/CleanupGetResultsOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/CleanupGetStatusOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/CleanupIsRunningOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/CleanupStartOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/CleanupStopOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/CleanupVersionsStartOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/DeleteOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/EventCloseFile.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/EventCreateFileVersion.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/EventGmax.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/EventInsertPaddingObject.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/EventPingFile.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/EventRWRStatus.java create mode 100755 java/servers/src/org/xtreemfs/osd/operations/EventWriteObject.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/FleaseMessageOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/GetFileIDListOperation.java create mode 100755 java/servers/src/org/xtreemfs/osd/operations/GetObjectSetOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/InternalGetFileSizeOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/InternalGetGmaxOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/InternalRWRAuthStateInvalidatedOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/InternalRWRAuthStateOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/InternalRWRFetchOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/InternalRWRStatusOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/InternalRWRTruncateOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/InternalRWRUpdateOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/InternalTruncateOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/InvalidateXLocSetOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/KeepFileOpenOperation.java create mode 100755 java/servers/src/org/xtreemfs/osd/operations/LocalReadOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/LockAcquireOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/LockCheckOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/LockReleaseOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/OSDOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/RWRNotifyOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/ReadOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/RepairObjectOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/RequestTimeHelper.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/ShutdownOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/TruncateOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/VivaldiPingOperation.java create mode 100644 java/servers/src/org/xtreemfs/osd/operations/WriteOperation.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/ObjectDissemination.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/ObjectSet.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/ReplicatingFile.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/selection/ObjectSetOSDSelection.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/selection/RandomOSDSelection.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/selection/RandomObjectSelection.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/selection/RarestFirstObjectSelection.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/selection/RoundRobinOSDSelection.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/selection/SequentialObjectSelection.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/transferStrategies/MasqueradingTransferStrategy.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RandomStrategy.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RandomStrategyWithoutObjectSets.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RarestFirstStrategy.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/transferStrategies/SequentialPrefetchingStrategy.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/transferStrategies/SequentialStrategy.java create mode 100755 java/servers/src/org/xtreemfs/osd/replication/transferStrategies/TransferStrategy.java create mode 100644 java/servers/src/org/xtreemfs/osd/rwre/CoordinatedReplicaUpdatePolicy.java create mode 100644 java/servers/src/org/xtreemfs/osd/rwre/FleaseMasterEpochThread.java create mode 100644 java/servers/src/org/xtreemfs/osd/rwre/ObjectFetchRecord.java create mode 100644 java/servers/src/org/xtreemfs/osd/rwre/RWReplicationStage.java create mode 100644 java/servers/src/org/xtreemfs/osd/rwre/RedirectToMasterException.java create mode 100644 java/servers/src/org/xtreemfs/osd/rwre/ReplicaUpdatePolicy.java create mode 100644 java/servers/src/org/xtreemfs/osd/rwre/ReplicatedFileState.java create mode 100644 java/servers/src/org/xtreemfs/osd/rwre/RetryException.java create mode 100644 java/servers/src/org/xtreemfs/osd/rwre/WaR1UpdatePolicy.java create mode 100644 java/servers/src/org/xtreemfs/osd/rwre/WaRaUpdatePolicy.java create mode 100644 java/servers/src/org/xtreemfs/osd/rwre/WqRqUpdatePolicy.java create mode 100644 java/servers/src/org/xtreemfs/osd/stages/DeletionStage.java create mode 100644 java/servers/src/org/xtreemfs/osd/stages/PreprocStage.java create mode 100755 java/servers/src/org/xtreemfs/osd/stages/ReplicationStage.java create mode 100644 java/servers/src/org/xtreemfs/osd/stages/Stage.java create mode 100644 java/servers/src/org/xtreemfs/osd/stages/StorageStage.java create mode 100644 java/servers/src/org/xtreemfs/osd/stages/VivaldiStage.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/CleanupThread.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/CleanupVersionsThread.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/CowPolicy.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/FileMetadata.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/HashStorageLayout.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/MetadataCache.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/ObjectInformation.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/RealSingleFileStorageLayout.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/SingleFileStorageLayout.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/StorageLayout.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/StorageThread.java create mode 100644 java/servers/src/org/xtreemfs/osd/storage/VersionTable.java create mode 100644 java/servers/src/org/xtreemfs/osd/templates/status.html create mode 100644 java/servers/src/org/xtreemfs/osd/vivaldi/VivaldiNode.java create mode 100644 java/servers/src/org/xtreemfs/osd/vivaldi/ZipfGenerator.java create mode 100644 java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/Common.java create mode 100644 java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIR.java create mode 100644 java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIRServiceClient.java create mode 100644 java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIRServiceConstants.java create mode 100644 java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/GlobalTypes.java create mode 100644 java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRC.java create mode 100644 java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRCServiceClient.java create mode 100644 java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRCServiceConstants.java create mode 100644 java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSD.java create mode 100644 java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSDServiceClient.java create mode 100644 java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSDServiceConstants.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/BenchmarkStorageLayouts.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/CleanupDemoVolume.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/DBViewer.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/DemoScrubber.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/DemoScrubberFileInfo.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/ExampleLibxtreemfsWithSSL.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/LocalX509AuthProvider.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/ThroughputTest.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/ThroughputTest.properties create mode 100644 java/servers/src/org/xtreemfs/sandbox/compile-DirectIOReader.txt create mode 100644 java/servers/src/org/xtreemfs/sandbox/dir_replication_test.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/mrc_replication_test.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/sliceTest.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/tests/CreateConfig.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/tests/FcntlLockTest.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/tests/JavaClientTest.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/tests/MRCStressTest.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/tests/OSDTestClient.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/tests/ReplicatedTortureXtreemFS.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/tests/TortureLocalFS.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/tests/TortureXtreemFS.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/tests/rwrepl_test.java create mode 100644 java/servers/src/org/xtreemfs/sandbox/writeTruncTest.java create mode 100644 java/servers/src/org/xtreemfs/utils/DefaultDirConfig.java create mode 100644 java/servers/src/org/xtreemfs/utils/discover_dir.java create mode 100644 java/servers/src/org/xtreemfs/utils/utils.java create mode 100644 java/servers/src/org/xtreemfs/utils/xtfs_benchmark/CLIOptions.java create mode 100644 java/servers/src/org/xtreemfs/utils/xtfs_benchmark/UncaughtExceptionHandlerBenchmark.java create mode 100644 java/servers/src/org/xtreemfs/utils/xtfs_benchmark/xtfs_benchmark.java create mode 100644 java/servers/src/org/xtreemfs/utils/xtfs_chstatus.java create mode 100644 java/servers/src/org/xtreemfs/utils/xtfs_cleanup_osd.java create mode 100644 java/servers/src/org/xtreemfs/utils/xtfs_mrcdbtool.java create mode 100644 java/servers/src/org/xtreemfs/utils/xtfs_remove_osd.java create mode 100644 java/servers/src/org/xtreemfs/utils/xtfs_scrub/FileScrubber.java create mode 100644 java/servers/src/org/xtreemfs/utils/xtfs_scrub/xtfs_scrub.java create mode 100644 java/servers/test/org/xtreemfs/common/clients/ClientTest.java create mode 100644 java/servers/test/org/xtreemfs/common/clients/ReplicatedClientTest.java create mode 100644 java/servers/test/org/xtreemfs/common/clients/internal/RAID0ObjectMapperTest.java create mode 100644 java/servers/test/org/xtreemfs/common/libxtreemfs/ClientTest.java create mode 100644 java/servers/test/org/xtreemfs/common/libxtreemfs/FileHandleTest.java create mode 100644 java/servers/test/org/xtreemfs/common/libxtreemfs/FileSizeUpdateThreadTest.java create mode 100644 java/servers/test/org/xtreemfs/common/libxtreemfs/MetadataCacheTest.java create mode 100644 java/servers/test/org/xtreemfs/common/libxtreemfs/RPCCallerTest.java create mode 100644 java/servers/test/org/xtreemfs/common/libxtreemfs/ReadOnlyReplicationTest.java create mode 100644 java/servers/test/org/xtreemfs/common/libxtreemfs/StripeTranslatorTest.java create mode 100644 java/servers/test/org/xtreemfs/common/libxtreemfs/UUIDIteratorTest.java create mode 100644 java/servers/test/org/xtreemfs/common/libxtreemfs/UUIDResolverTest.java create mode 100644 java/servers/test/org/xtreemfs/common/libxtreemfs/VolumeTest.java create mode 100644 java/servers/test/org/xtreemfs/common/statusserver/StatusServerTest.java create mode 100644 java/servers/test/org/xtreemfs/integrationtest/ExternalIntegrationTest.java create mode 100644 java/servers/test/org/xtreemfs/test/SetupUtils.java create mode 100644 java/servers/test/org/xtreemfs/test/TestEnvironment.java create mode 100644 java/servers/test/org/xtreemfs/test/TestHelper.java create mode 100644 java/servers/test/org/xtreemfs/test/common/CapabilityTest.java create mode 100644 java/servers/test/org/xtreemfs/test/common/benchmark/ControllerIntegrationTest.java create mode 100644 java/servers/test/org/xtreemfs/test/common/monitoring/DIRMonitoringTest.java create mode 100644 java/servers/test/org/xtreemfs/test/common/monitoring/GeneralMonitoringTest.java create mode 100644 java/servers/test/org/xtreemfs/test/common/monitoring/MRCMonitoringTest.java create mode 100644 java/servers/test/org/xtreemfs/test/common/monitoring/OSDMonitoringTest.java create mode 100644 java/servers/test/org/xtreemfs/test/common/striping/LocationsCacheTest.java create mode 100644 java/servers/test/org/xtreemfs/test/common/striping/LocationsTest.java create mode 100644 java/servers/test/org/xtreemfs/test/common/striping/RAID0Test.java create mode 100644 java/servers/test/org/xtreemfs/test/common/uuid/UUIDResolverTest.java create mode 100644 java/servers/test/org/xtreemfs/test/dir/DIRClientTest.java create mode 100644 java/servers/test/org/xtreemfs/test/dir/DIRTest.java create mode 100644 java/servers/test/org/xtreemfs/test/mrc/BabuDBStorageManagerTest.java create mode 100644 java/servers/test/org/xtreemfs/test/mrc/BufferBackedMetadataTest.java create mode 100644 java/servers/test/org/xtreemfs/test/mrc/MRCTest.java create mode 100644 java/servers/test/org/xtreemfs/test/mrc/OSDPolicyTest.java create mode 100644 java/servers/test/org/xtreemfs/test/mrc/SetReadOnlyXattrTest.java create mode 100644 java/servers/test/org/xtreemfs/test/mrc/SetReplicaUpdatePolicyTest.java create mode 100644 java/servers/test/org/xtreemfs/test/mrc/SnapshotTest.java create mode 100644 java/servers/test/org/xtreemfs/test/mrc/VersionedXLocSetTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/AdvisoryLocksTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/CleanupTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/ClientLeaseTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/CowPolicyTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/FastDeleteOpenFile.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/OSDDataIntegrityTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/OSDDrainTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/OSDRangeReads.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/OSDTruncateTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/SimpleVivaldiStageTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/StorageLayoutTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/StorageStageTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/StripingTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/StripingTestCOW.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/VersionManagementTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/VersionTableTest.java create mode 100755 java/servers/test/org/xtreemfs/test/osd/replication/ObjectSetTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/replication/ReadWriteReplicationTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/replication/ReplicationRAFTest.java create mode 100755 java/servers/test/org/xtreemfs/test/osd/replication/ReplicationTest.java create mode 100755 java/servers/test/org/xtreemfs/test/osd/replication/ServiceAvailabilityTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/replication/TransferStrategiesTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/rwre/FixWrongMasterEpochDirectoryTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/rwre/RWQuorumReplicationTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/rwre/RWReplicationFailureTest.java create mode 100644 java/servers/test/org/xtreemfs/test/osd/rwre/RWReplicationTest.java create mode 100644 java/servers/test/org/xtreemfs/utils/ScrubberTest.java create mode 100644 man/man1/lsfs.xtreemfs.1 create mode 100644 man/man1/mkfs.xtreemfs.1 create mode 100644 man/man1/mount.xtreemfs.1 create mode 100644 man/man1/rmfs.xtreemfs.1 create mode 100644 man/man1/umount.xtreemfs.1 create mode 100644 man/man1/xtfs_chstatus.1 create mode 100644 man/man1/xtfs_cleanup.1 create mode 100644 man/man1/xtfs_mrcdbtool.1 create mode 100644 man/man1/xtfs_remove_osd.1 create mode 100644 man/man1/xtfs_scrub.1 create mode 100644 man/man1/xtfsutil.1 create mode 100755 packaging/generate_uuid create mode 100644 packaging/postinstall_setup.sh create mode 100644 snmp/README.txt create mode 100644 snmp/generatedcode.sh create mode 100644 snmp/jdmk.acl create mode 100644 snmp/mib_core.txt create mode 100644 snmp/xtreemfs-mib.txt create mode 100644 tests/.project create mode 100644 tests/.pydevproject create mode 100644 tests/certs/Client.key create mode 100644 tests/certs/Client.p12 create mode 100644 tests/certs/Client.pem create mode 100644 tests/certs/Client.req create mode 100644 tests/certs/DIR.key create mode 100644 tests/certs/DIR.p12 create mode 100644 tests/certs/DIR.pem create mode 100644 tests/certs/DIR.req create mode 100644 tests/certs/MRC.key create mode 100644 tests/certs/MRC.p12 create mode 100644 tests/certs/MRC.pem create mode 100644 tests/certs/MRC.req create mode 100644 tests/certs/OSD.key create mode 100644 tests/certs/OSD.p12 create mode 100644 tests/certs/OSD.pem create mode 100644 tests/certs/OSD.req create mode 100644 tests/certs/client_ssl_test/CA_Chain.pem create mode 100644 tests/certs/client_ssl_test/CA_Intermediate.key create mode 100644 tests/certs/client_ssl_test/CA_Intermediate.pem create mode 100644 tests/certs/client_ssl_test/CA_Intermediate.req create mode 100644 tests/certs/client_ssl_test/CA_Intermediate.srl create mode 100644 tests/certs/client_ssl_test/CA_Leaf.key create mode 100644 tests/certs/client_ssl_test/CA_Leaf.pem create mode 100644 tests/certs/client_ssl_test/CA_Leaf.req create mode 100644 tests/certs/client_ssl_test/CA_Leaf.srl create mode 100644 tests/certs/client_ssl_test/CA_Root.key create mode 100644 tests/certs/client_ssl_test/CA_Root.pem create mode 100644 tests/certs/client_ssl_test/CA_Root.req create mode 100644 tests/certs/client_ssl_test/CA_Root.srl create mode 100644 tests/certs/client_ssl_test/Client_Leaf.key create mode 100644 tests/certs/client_ssl_test/Client_Leaf.p12 create mode 100644 tests/certs/client_ssl_test/Client_Leaf.pem create mode 100644 tests/certs/client_ssl_test/Client_Leaf.req create mode 100644 tests/certs/client_ssl_test/Client_Leaf_Chain.p12 create mode 100644 tests/certs/client_ssl_test/Client_Leaf_Leaf.p12 create mode 100644 tests/certs/client_ssl_test/Client_Leaf_Root.p12 create mode 100644 tests/certs/client_ssl_test/Client_Root.key create mode 100644 tests/certs/client_ssl_test/Client_Root.p12 create mode 100644 tests/certs/client_ssl_test/Client_Root.pem create mode 100644 tests/certs/client_ssl_test/Client_Root.req create mode 100644 tests/certs/client_ssl_test/Client_Root_Chain.p12 create mode 100644 tests/certs/client_ssl_test/Client_Root_Leaf.p12 create mode 100644 tests/certs/client_ssl_test/Client_Root_Root.p12 create mode 100644 tests/certs/client_ssl_test/DIR_Leaf.key create mode 100644 tests/certs/client_ssl_test/DIR_Leaf.p12 create mode 100644 tests/certs/client_ssl_test/DIR_Leaf.pem create mode 100644 tests/certs/client_ssl_test/DIR_Leaf.req create mode 100644 tests/certs/client_ssl_test/DIR_Root.key create mode 100644 tests/certs/client_ssl_test/DIR_Root.p12 create mode 100644 tests/certs/client_ssl_test/DIR_Root.pem create mode 100644 tests/certs/client_ssl_test/DIR_Root.req create mode 100644 tests/certs/client_ssl_test/MRC_Leaf.key create mode 100644 tests/certs/client_ssl_test/MRC_Leaf.p12 create mode 100644 tests/certs/client_ssl_test/MRC_Leaf.pem create mode 100644 tests/certs/client_ssl_test/MRC_Leaf.req create mode 100644 tests/certs/client_ssl_test/MRC_Root.key create mode 100644 tests/certs/client_ssl_test/MRC_Root.p12 create mode 100644 tests/certs/client_ssl_test/MRC_Root.pem create mode 100644 tests/certs/client_ssl_test/MRC_Root.req create mode 100644 tests/certs/client_ssl_test/OSD_Leaf.key create mode 100644 tests/certs/client_ssl_test/OSD_Leaf.p12 create mode 100644 tests/certs/client_ssl_test/OSD_Leaf.pem create mode 100644 tests/certs/client_ssl_test/OSD_Leaf.req create mode 100644 tests/certs/client_ssl_test/OSD_Root.key create mode 100644 tests/certs/client_ssl_test/OSD_Root.p12 create mode 100644 tests/certs/client_ssl_test/OSD_Root.pem create mode 100644 tests/certs/client_ssl_test/OSD_Root.req create mode 100644 tests/certs/client_ssl_test/README create mode 100644 tests/certs/client_ssl_test/trusted_leaf.jks create mode 100644 tests/certs/client_ssl_test/trusted_root.jks create mode 100644 tests/certs/trusted.jks create mode 100644 tests/config_parser.py create mode 100644 tests/configs/dirconfig_no_ssl.test create mode 100644 tests/configs/dirconfig_ssl_ignore_errors.test create mode 100644 tests/configs/dirconfig_ssl_long_chain.test create mode 100644 tests/configs/dirconfig_ssl_no_verification.test create mode 100644 tests/configs/dirconfig_ssl_short_chain.test create mode 100644 tests/configs/dirconfig_ssl_version.test create mode 100644 tests/configs/dirconfig_ssl_version_sslv3.test create mode 100644 tests/configs/dirconfig_ssl_version_tlsv1.test create mode 100644 tests/configs/dirconfig_ssl_version_tlsv11.test create mode 100644 tests/configs/dirconfig_ssl_version_tlsv12.test create mode 100644 tests/configs/mrcconfig_no_ssl.test create mode 100644 tests/configs/mrcconfig_ssl_ignore_errors.test create mode 100644 tests/configs/mrcconfig_ssl_long_chain.test create mode 100644 tests/configs/mrcconfig_ssl_no_verification.test create mode 100644 tests/configs/mrcconfig_ssl_short_chain.test create mode 100644 tests/configs/mrcconfig_ssl_version.test create mode 100644 tests/configs/mrcconfig_ssl_version_sslv3.test create mode 100644 tests/configs/mrcconfig_ssl_version_tlsv1.test create mode 100644 tests/configs/mrcconfig_ssl_version_tlsv11.test create mode 100644 tests/configs/mrcconfig_ssl_version_tlsv12.test create mode 100644 tests/configs/osdconfig_no_ssl.test create mode 100644 tests/configs/osdconfig_ssl_ignore_errors.test create mode 100644 tests/configs/osdconfig_ssl_long_chain.test create mode 100644 tests/configs/osdconfig_ssl_no_verification.test create mode 100644 tests/configs/osdconfig_ssl_short_chain.test create mode 100644 tests/configs/osdconfig_ssl_version.test create mode 100644 tests/configs/osdconfig_ssl_version_sslv3.test create mode 100644 tests/configs/osdconfig_ssl_version_tlsv1.test create mode 100644 tests/configs/osdconfig_ssl_version_tlsv11.test create mode 100644 tests/configs/osdconfig_ssl_version_tlsv12.test create mode 100755 tests/cronjob/run_xtreemfs_tests.sh create mode 100755 tests/kill_running_servers.sh create mode 100644 tests/test_config.py create mode 100755 tests/test_scripts/01_simple_metadata.py create mode 100755 tests/test_scripts/02_erichs_ddwrite.py create mode 100755 tests/test_scripts/03_erichs_data_integrity_test.py create mode 100755 tests/test_scripts/05_findgreptar.sh create mode 100755 tests/test_scripts/09_fsx.py create mode 100755 tests/test_scripts/10_bonnie.py create mode 100755 tests/test_scripts/11_iozone_diagnostic.py create mode 100755 tests/test_scripts/12_iozone_throughput.py create mode 100755 tests/test_scripts/13_dbench.py create mode 100755 tests/test_scripts/14_xtfs_benchmark.sh create mode 100755 tests/test_scripts/15_makextreemfs.py create mode 100755 tests/test_scripts/16_iozone_multithread.py create mode 100755 tests/test_scripts/17_bonnie_multithread.py create mode 100755 tests/test_scripts/18_view_renewal.py create mode 100755 tests/test_scripts/cpp_unit_tests.sh create mode 100755 tests/test_scripts/cpp_unit_tests_valgrind.sh create mode 100644 tests/test_scripts/dbench-client.txt.gz create mode 100755 tests/test_scripts/fsx.sh create mode 100755 tests/test_scripts/hadoop2_test.sh create mode 100755 tests/test_scripts/hadoop_ssl_test.sh create mode 100755 tests/test_scripts/hadoop_test.sh create mode 100755 tests/test_scripts/junit_tests.sh create mode 100755 tests/test_scripts/marked_block.pl create mode 100755 tests/test_scripts/marked_block_helper.pl create mode 100644 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/LICENSE create mode 100644 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/Makefile create mode 100644 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/README create mode 100644 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/README.XtreemFS create mode 100644 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/bogus.t create mode 100644 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/fstest.c create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/02.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/10.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/11.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/mkfifo/12.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/02.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/10.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/11.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/12.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chflags/13.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/02.t.length create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/10.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chmod/11.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chown/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chown/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chown/02.t.length create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chown/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chown/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chown/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chown/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chown/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chown/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chown/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/chown/10.t create mode 100644 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/conf create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/02.t.length create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/10.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/11.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/12.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/13.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/14.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/15.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/16.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/link/17.t create mode 100644 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/misc.sh create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/02.t.length create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/10.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/11.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/mkdir/12.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/02.t.length create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/10.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/11.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/12.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/13.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/14.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/15.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/16.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/17.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/18.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/19.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/20.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/21.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/22.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/open/23.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/01.t.length create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/02.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/10.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/11.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/12.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/13.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/14.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/15.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/16.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/17.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/18.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/19.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rename/20.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/02.t.length create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/10.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/11.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/12.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/13.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/14.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/rmdir/15.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/02.t.length create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/10.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/11.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/symlink/12.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/02.t.length create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/10.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/11.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/12.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/13.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/truncate/14.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/02.t.length create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/06.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/07.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/08.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/09.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/10.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/11.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/12.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/tests/unlink/13.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/xacl/00.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/xacl/01.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/xacl/02.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/xacl/03.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/xacl/04.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/xacl/05.t create mode 100755 tests/test_scripts/pjd-fstest-20090130-RC_XtreemFS/xacl/06.t create mode 100755 tests/test_scripts/posix_test_suite.sh create mode 100755 tests/test_scripts/ronly_replication_add_delete_replica.sh create mode 100755 tests/test_scripts/system_chstatus_test.sh create mode 100755 tests/test_scripts/system_cleanup_test.sh create mode 100755 tests/test_scripts/system_mkfs_lsfs_rmfs_test.sh create mode 100755 tests/test_scripts/system_mrcdbtool_test.sh create mode 100755 tests/test_scripts/system_scrub_test.sh create mode 100755 tests/test_scripts/system_snap_test.sh create mode 100755 tests/test_scripts/test_flocks.sh create mode 100755 tests/test_scripts/test_xattrs.sh create mode 100644 tests/test_server.py create mode 100644 tests/test_volume.py create mode 100644 tests/utils/ltp-fsx.c create mode 100755 tests/xstartserv create mode 100755 tests/xtestenv diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..3ad3654 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,20 @@ +Michael Berlin +Eugenio Cesario +Johannes Dillmann +Jan Fajerski +Jens V. Fischer +Juan Gonzalez +Lukas Kairies +Christoph Kleineweber +Björn Kolbeck +Nico Kruber +Felix Langner +Philippe Lieser +Christian Lorenz +Matthias Noack +Patrick Schäfer +Robert Schmidtke +Thorsten Schuett +Paul Seiferth +Dmitry Smirnov +Jan Stender diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..27486c5 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,92 @@ +12-MAR-2015: release 1.5.1 + + Changes: + * Hadoop Adapter supports Hadoop-2.x and other applications running on the YARN platform (tested with Apache Spark and Apache Flink), new OSD selection policy that imitates the HDFS placement behavior. + * Consistent adding and removing replicas for R/W replication. + * xtfs_scrup now replaces failed replicas using the R/W replication policy. + * Improvements of the SSL mode: the used SSL/TLS version is selectable, strict certificate chain checks are possible, the SSL code on client and server side was improved. + * Support for PKCS12 certificate containers is remove from the Windows client (did not work in previous release). + * mount.xtreemfs accepts all parameters to be passed in the form -o option=value. If XtreemFS is mounted via /etc/fstab, mount options are passed to the XtreemFS client. + * Dockerfiles for the XtreemFS services are available at https://github.com/xtreemfs/xtreemfs-docker. + * A Vagrantfile is available in the XtreemFS repository to ease development and testing for new contributors. + * Fixed snapshots in the case of deleted files. + * Snapshots can be deleted even after inactivating snapshots for a volume (issue 290). + * Initial version of an LD_PRELOAD based client that bypasses FUSE (experimental). + * Initial implementation of volume quotas (checked only while opening files by the MRC). + * OSDs can report their health to the DIR (e.g. based on SMART values), which aggregates this information in the web interface. A new OSD selection policy sorts out unhealthy OSDs. + * Improved automatic testing: introduced Travis-CI, migrated all JUnit tests to version 4, improved reliability of nightly integration tests. + * Added new benchmark tool xtfs_benchmark that is based on the JAVA libxtreemfs. + * Many small improvements and fixes. + +12-MAR-2014: release 1.5 (Wonderful Waffles) + + Changes: + * Improved Hadoop Adapter e.g., added support for multiple volumes and read and write buffer to speed up performance. + * Support for SSDs: Support for multiple OSD storage threads to increase parallelism. + * Status webpage as part of the DIR webinterface for replicated files to show current primary and backup replicas. + * Multi-homing support. XtreemFS can now be made available for multiple networks and clients will pick the correct address automatically. + * Support for multiple OSDs per machine (e.g. one for each disk) through the xtreemfs-osd-farm init.d script. + * Fixed major issues in Read-Only and Read/Write file replication. + * Reduced metadata cache default timeout from 120 to 10 seconds. Disable it completely with --metadata-cache-size=0. + * Upgraded to Google Protobuffers 2.5 which improves performance. + * Windows Client: Fixed several issues (e.g., 286, 299) and updated the CbFS driver to the latest version. + * XtreemFS also compiles under buildroot now. + * Fixed several issues around SSL (e.g., 263, 281). + * Fixed many small issues e.g., reported volume capacity was inaccurate (issue 296). + Other fixed issues: 267, 268, 272, 274, 276, 277, 278, 283, 287, 288, 292, 293, 294. + * Improved general stability (e.g., see issues 297, 301). + * xtfs_scrub now repairs replicas with an invalid checksum automatically. + * Disabled deferred deletion of file data on the OSDs. + * Improved test coverage of nightly tests and added missing unit tests and a Valgrind leak check for C++ unit tests. + +12-NOV-2012: release 1.4 (Salty Sticks) + + Changes: + * Improved stability: Fixed client crashes when timeouts occurred; fixed server crashes and issues with the R/W replication. + * Full support for asynchronous writes: If a client is started with "--enable-async-writes", write() requests will be immediately acknowledged by the client and executed in the background. Outstanding writes are always flushed at close() or fsync*() events. This improves the write throughput, especially in case of connections with high latency. + * Added Windows Client Beta which uses Eldos' Callback File System product instead of Dokan. + * Re-wrote HDFS interface implementation: Use XtreemFS as replacement for HDFS in your Hadoop setup. + * libxtreemfs for Java: Access XtreemFS directly from your Java application. See source files org.xtreemfs.common.libxtreemfs.{Client,Volume,FileHandle}.java for the interface. + * Re-added Vivaldi support and added/improved its functionality: + * Vivaldi is directly integrated in the client now and can be enabled with '--vivaldi-enable'. + * Added Vivaldi visualization: see '/vivaldi' subpage on DIR. Have a look at our demo server to get an impressium: http://demo.xtreemfs.org:30638/vivaldi + * Coordinates of clients can be also visualized if clients reporting was enabled with '--vivaldi-enable-dir-updates'. + * Added support for OSD Selection based on Custom Attributes. For example, assign a country code to every OSD as custom attribute and limit the placement of files on OSDs based on the attribute. + + * Rewrote xtfs_scrub tool and fixed support for read-only replicated files and checksums. R/W replicas will be supported in the next release. + * Certificate password provided on command line no longer visible in process listing output. Additionally, the password can be entered on stdin now. (Issue 251) + * Support for binary extended attributes (allows to preserve POSIX ACLs when copying data to XtreemFS; however they are not evaluated - use the XtreemFS ACLs therefore). + * Fixed several client issues (e.g., 231, 234, 237). + * Fixed clock synchronization problems which impaired the DIR/MRC replication. This also fixed issue 236. + * Client: Added DIR fail over support. Specify multiple DIR replicas when mounting as follows: mount.xtreemfs dir1,dir2,dir3/volume. However, please note that the DIR/MRC replication is still experimental and not officially supported yet. + * MacOSX Client: Fixed wrong df output (issue 247). Fixed failed installer if XtreemFS is already installed (issue 239). Fixed installer check if FUSE is installed (also works for OSXFUSE now) (issue 197). + * Volume Snapshots Tools: Functionality was moved from "xtfs_snap" tool to "xtfsutil". + * Various minor fixes. + + * MRC: To prevent confusion, global policy attributes are no longer allowed and always have to be prefixed by the policy id e.g., "1002.uuids". + * init.d scripts no longer store a lock file in /var/lock/subsys. You can remove this directory now. + +03-NOV-2011: release 1.3.1 + * Added 'xtfs_remove_osd' utility to remove OSDs from an XtreemFS installation. All files on the OSD to be removed will be relocated to different OSDs. + * Added first support for asynchronous writes in the client. Mounting with '--max-writeahead' and '--max-writeahead-requests' allows the user to specify the maximum number of bytes and requests to be sent to an OSD before receiving an acknowledgment. However, this feature currently does not work together with replication and retries. + * Added monitoring support to servers. Various characteristics are accessible now via SNMP, such as data transfer statistics, memory usage, numbers of files and directories, etc. A Ganglia plugin makes it possible to visualize them. + * improved stability of MRC/DIR replication + * improved the behavior of the read-write replication under heavy load by internally limiting the length of request queues + * made several usability changes to xtfsutil + * added '/babudb' subpage to MRC/DIR status page that shows internal database statistics + * added Gentoo overlay + * installing XtreemFS now creates symlinks '/sbin/mount.xtreemfs' and '/sbin/umount.xtreemfs' in order to support XtreemFS mounting via fstab (however, not all client options are available in the fstab yet, see issue 205) + * the replication policy "WaRa" was renamed to "WaR1" + * fixed issues 196, 198-204, 206-209, 211-218, 220, 222 + * fixed a wide range of issues w/ read-only and read-write replication of files + * fixed issues w/ several MRC calls when admin passwords were specified (a consequence of this is that an XtreemFS 1.3.0 client can no longer mount admin_password protected MRCs; upgrade the client to 1.3.1 to fix this) + * fixed various client issues, such as deadlocks and memory leaks + +10-AUG-2011: release 1.3.0 (Tasty Tartlet) + * added new features: full read-write replication of files, snapshots + * completely re-wrote the client + - it now supports metadata caching and automatic fail-over for replicated files + - a client library 'libxtreemfs' separates the client logic from platform-specific bindings (e.g. FUSE, Dokan) + * added first prototypes of metadata (MRC and DIR) replication + * merged all user tools into a new general-purpose tool 'xtfsutil' + * changed license from GPL to BSD diff --git a/KNOWN_ISSUES b/KNOWN_ISSUES new file mode 100644 index 0000000..28b1b5f --- /dev/null +++ b/KNOWN_ISSUES @@ -0,0 +1,8 @@ +From release 1.3.1 on, we document all known limitations of XtreemFS +in our issue tracker and mark each with the label "KnownLimitations". + +Please have a look at + + https://github.com/xtreemfs/xtreemfs/labels/KnownLimitations + +for the complete list of current known limitations. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c5ef559 --- /dev/null +++ b/LICENSE @@ -0,0 +1,35 @@ +Copyright (c) 2008-2012, Michael Berlin, Eugenio Cesario, +Juan Gonzalez, Björn Kolbeck, Felix Langner, Christian Lorenz, +Matthias Noack, Patrick Schäfer, Paul Seiferth, Jan Stender + + +All rights reserved. + +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 the Zuse Institute Berlin 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. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..16de650 --- /dev/null +++ b/Makefile @@ -0,0 +1,349 @@ +ifeq "$(JAVA_HOME)" "" + JAVAC_BIN = /usr/bin/javac +else + JAVAC_BIN = $(JAVA_HOME)/bin/javac +endif + +ifeq "$(ANT_HOME)" "" + ANT_BIN = /usr/bin/ant +else + ANT_BIN = $(ANT_HOME)/bin/ant +endif + +ifeq "$(CMAKE_HOME)" "" + CMAKE_BIN = cmake +else + CMAKE_BIN = $(CMAKE_HOME)/bin/cmake +endif + +SHELL := $(shell which bash) +WHICH_GPP = $(shell which g++) +WHICH_CLANGPP = $(shell which clang++) + +ifeq "$(shell uname)" "SunOS" + PROTOBUF_DISABLE_64_BIT_SOLARIS = "--disable-64bit-solaris" +endif + +# Paths used during compilation. +XTREEMFS_CLIENT_BUILD_DIR=$(shell pwd)/cpp/build +XTREEMFS_BINARIES_DIR = $(shell pwd)/bin + +# Install paths relative to DESTDIR. +XTREEMFS_JAR_DIR=$(DESTDIR)/usr/share/java +XTREEMFS_CONFIG_PARENT_DIR=$(DESTDIR)/etc/xos +XTREEMFS_CONFIG_DIR=$(XTREEMFS_CONFIG_PARENT_DIR)/xtreemfs +XTREEMFS_INIT_DIR=$(DESTDIR)/etc/init.d +XTREEMFS_SHARE_DIR=$(DESTDIR)/usr/share/xtreemfs +BIN_DIR=$(DESTDIR)/usr/bin +SBIN_DIR=$(DESTDIR)/sbin +MAN_DIR=$(DESTDIR)/usr/share/man/man1 +DOC_DIR_SERVER=$(DESTDIR)/usr/share/doc/xtreemfs-server +DOC_DIR_CLIENT=$(DESTDIR)/usr/share/doc/xtreemfs-client +DOC_DIR_TOOLS=$(DESTDIR)/usr/share/doc/xtreemfs-tools +PLUGIN_CONFIG_DIR=$(XTREEMFS_CONFIG_DIR)/server-repl-plugin + +#Configuration of cpp code thirdparty dependencies. +# If you edit the next five variables, make sure you also change them in cpp/CMakeLists.txt. +CLIENT_GOOGLE_PROTOBUF_CPP = cpp/thirdparty/protobuf-2.5.0 +CLIENT_GOOGLE_PROTOBUF_CPP_LIBRARY = $(CLIENT_GOOGLE_PROTOBUF_CPP)/src/.libs/libprotobuf.a +CLIENT_GOOGLE_TEST_CPP = cpp/thirdparty/gtest-1.7.0 +CLIENT_GOOGLE_TEST_CPP_LIBRARY = $(CLIENT_GOOGLE_TEST_CPP)/lib/.libs/libgtest.a +CLIENT_GOOGLE_TEST_CPP_MAIN = $(CLIENT_GOOGLE_TEST_CPP)/lib/.libs/libgtest_main.a +# The two required objects libgtest.a and libgtest_main.a both depend +# on the same target building the Google googletest library. +# Therefore, this target is guarded by a checkfile which will be touched once it was executed. +# This prevents the target from getting executed again as long as the checkfile does not change. +CLIENT_GOOGLE_TEST_CHECKFILE = .googletest_library_already_built + +TARGETS = client server foundation flease +.PHONY: clean distclean set_version + +all: check_server check_client check_test $(TARGETS) + +clean: check_server check_client $(patsubst %,%_clean,$(TARGETS)) + +distclean: check_server check_client $(patsubst %,%_distclean,$(TARGETS)) + +install: install-client install-server install-tools + +install-client: + + @if [ ! -f $(XTREEMFS_BINARIES_DIR)/mkfs.xtreemfs ]; then echo "PLEASE RUN 'make client' FIRST!"; exit 1; fi + + @mkdir -p $(DOC_DIR_CLIENT) + @cp LICENSE $(DOC_DIR_CLIENT) + + @mkdir -p $(BIN_DIR) + @cp -p $(XTREEMFS_BINARIES_DIR)/*.xtreemfs $(XTREEMFS_BINARIES_DIR)/xtfsutil $(BIN_DIR) + +# mount -t xtreemfs will be recognized when binaries are present in /sbin/. Only applicable if the Fuse Client was built. + @[ -f $(XTREEMFS_BINARIES_DIR)/mount.xtreemfs ] && mkdir -p $(SBIN_DIR); true + @[ -f $(XTREEMFS_BINARIES_DIR)/mount.xtreemfs ] && ln -s $(BIN_DIR)/mount.xtreemfs $(SBIN_DIR)/mount.xtreemfs; true + @[ -f $(XTREEMFS_BINARIES_DIR)/mount.xtreemfs ] && ln -s $(BIN_DIR)/umount.xtreemfs $(SBIN_DIR)/umount.xtreemfs; true + + @mkdir -p $(XTREEMFS_CONFIG_DIR) + @cp etc/xos/xtreemfs/default_dir $(XTREEMFS_CONFIG_DIR) + + @mkdir -p $(MAN_DIR) + @cp -R man/man1/*.xtreemfs* $(MAN_DIR) + @cp -R man/man1/xtfsutil.* $(MAN_DIR) + +install-server: + + @if [ ! -f java/servers/dist/XtreemFS.jar ]; then echo "PLEASE RUN 'make server' FIRST!"; exit 1; fi + + @mkdir -p $(DOC_DIR_SERVER) + @cp LICENSE $(DOC_DIR_SERVER) + + @mkdir -p $(XTREEMFS_JAR_DIR) + @cp java/servers/dist/XtreemFS.jar $(XTREEMFS_JAR_DIR) + @cp java/foundation/dist/Foundation.jar $(XTREEMFS_JAR_DIR) + @cp java/flease/dist/Flease.jar $(XTREEMFS_JAR_DIR) + @cp java/lib/*.jar $(XTREEMFS_JAR_DIR) + @cp contrib/server-repl-plugin/BabuDB_replication_plugin.jar $(XTREEMFS_JAR_DIR) + + @mkdir -p $(XTREEMFS_CONFIG_DIR) +# @cp etc/xos/xtreemfs/*config.properties $(XTREEMFS_CONFIG_DIR) +# delete UUID from config-files + @grep -v '^uuid\W*=\W*\w\+' etc/xos/xtreemfs/dirconfig.properties > $(XTREEMFS_CONFIG_DIR)/dirconfig.properties + @grep -v '^uuid\W*=\W*\w\+' etc/xos/xtreemfs/mrcconfig.properties > $(XTREEMFS_CONFIG_DIR)/mrcconfig.properties + @grep -v '^uuid\W*=\W*\w\+' etc/xos/xtreemfs/osdconfig.properties > $(XTREEMFS_CONFIG_DIR)/osdconfig.properties + + @mkdir -p $(PLUGIN_CONFIG_DIR) + @cp contrib/server-repl-plugin/config/dir.properties $(PLUGIN_CONFIG_DIR) + @cp contrib/server-repl-plugin/config/mrc.properties $(PLUGIN_CONFIG_DIR) + + @cp packaging/generate_uuid $(XTREEMFS_CONFIG_DIR) + @cp packaging/postinstall_setup.sh $(XTREEMFS_CONFIG_DIR) + @chmod a+x $(XTREEMFS_CONFIG_DIR)/postinstall_setup.sh + +# Generating init.d scripts based on template. + @etc/init.d/generate_initd_scripts.sh + @mkdir -p $(XTREEMFS_INIT_DIR) + @cp etc/init.d/xtreemfs-{dir,mrc,osd} $(XTREEMFS_INIT_DIR) + @chmod a+x $(XTREEMFS_INIT_DIR)/xtreemfs-* + + @mkdir -p $(XTREEMFS_SHARE_DIR) + @cp contrib/xtreemfs-osd-farm/xtreemfs-osd-farm $(XTREEMFS_SHARE_DIR) + + @echo "to complete the server installation, please execute $(XTREEMFS_CONFIG_DIR)/postinstall_setup.sh" + +install-tools: + + @if [ ! -f java/servers/dist/XtreemFS.jar ]; then echo "PLEASE RUN 'make server' FIRST!"; exit 1; fi + + @mkdir -p $(DOC_DIR_TOOLS) + @cp LICENSE $(DOC_DIR_TOOLS) + + @mkdir -p $(XTREEMFS_JAR_DIR) + @cp java/servers/dist/XtreemFS.jar $(XTREEMFS_JAR_DIR) + @cp java/foundation/dist/Foundation.jar $(XTREEMFS_JAR_DIR) + @cp java/flease/dist/Flease.jar $(XTREEMFS_JAR_DIR) + @cp java/lib/*.jar $(XTREEMFS_JAR_DIR) + + @mkdir -p $(BIN_DIR) + @cp -p `ls $(XTREEMFS_BINARIES_DIR)/xtfs_* | grep -v xtfs_.*mount` $(BIN_DIR) + + @mkdir -p $(MAN_DIR) + @cp -R man/man1/xtfs_* $(MAN_DIR) + +uninstall: + + @rm -rf $(DOC_DIR_SERVER) + @rm -rf $(DOC_DIR_CLIENT) + @rm -rf $(DOC_DIR_TOOLS) + + @rm -rf $(BIN_DIR)/xtfs* + @rm -rf $(BIN_DIR)/*.xtreemfs + + @rm -f $(SBIN_DIR)/mount.xtreemfs + @rm -f $(SBIN_DIR)/umount.xtreemfs + + @rm -f $(XTREEMFS_JAR_DIR)/XtreemFS.jar + @rm -f $(XTREEMFS_JAR_DIR)/Foundation.jar + @rm -f $(XTREEMFS_JAR_DIR)/Flease.jar + @rm -f $(XTREEMFS_JAR_DIR)/BabuDB.jar + @rm -f $(XTREEMFS_JAR_DIR)/commons-codec-1.3.jar + @rm -f $(XTREEMFS_JAR_DIR)/jdmkrt.jar + @rm -f $(XTREEMFS_JAR_DIR)/jdmktk.jar + @rm -f $(XTREEMFS_JAR_DIR)/protobuf-java-2.5.0.jar + @rm -f $(XTREEMFS_JAR_DIR)/BabuDB_replication_plugin.jar + + @rm -f $(XTREEMFS_INIT_DIR)/xtreemfs-* + + @rm -rf $(MAN_DIR)/xtfs* + @rm -rf $(MAN_DIR)/*.xtreemfs* + + @echo "uninstall complete" + +purge: uninstall + + @rm -rf $(XTREEMFS_CONFIG_DIR) + @echo "purge complete" + +check_server: + @if [ ! -e $(JAVAC_BIN) ]; then echo "javac not found! Make sure a JDK is installed and set JAVA_HOME."; exit 1; fi; + @if [ $(shell $(JAVAC_BIN) -version 2>&1 | head -n1 | cut -d" " -f2 | cut -d. -f2) -lt 6 ]; then echo "java version >= 1.6.0 required!"; exit 1; fi; + @echo "java ok" + + @if [ ! -e $(ANT_BIN) ]; then echo "ant not found! Make sure ant is installed and set ANT_HOME."; exit 1; fi; + @echo "ant ok" + +check_client: + @if [ ! $(WHICH_GPP) -a ! $(WHICH_CLANGPP) ]; then echo "C++ compiler not found";exit 1; fi; + @if [ ! $(CMAKE_BIN) ]; then echo "cmake not found";exit 1; fi; + @echo "C++ ok" + + +check_test: + @if [[ $(shell python -V 2>&1 | head -n1 | cut -d" " -f2 | cut -d. -f2) -lt 3 && $(shell python -V 2>&1 | head -n1 | cut -d" " -f2 | cut -d. -f1) -lt 3 ]]; then echo "python >= 2.4 required!"; exit 1; fi; + @echo "python ok" + +set_version: +# Try to set the SVN revision and branch name as part of the version. We don't care if this may fail. +ifndef SKIP_SET_SVN_VERSION + @./packaging/set_version.sh -s &>/dev/null; exit 0 +endif + +.PHONY: client client_clean client_distclean client_thirdparty_clean client_package_macosx + +# Client section. +CLIENT_THIRDPARTY_REQUIREMENTS = $(CLIENT_GOOGLE_PROTOBUF_CPP_LIBRARY) +ifdef BUILD_CLIENT_TESTS + CLIENT_THIRDPARTY_REQUIREMENTS += $(CLIENT_GOOGLE_TEST_CPP_LIBRARY) $(CLIENT_GOOGLE_TEST_CPP_MAIN) + CMAKE_BUILD_CLIENT_TESTS = -DBUILD_CLIENT_TESTS=true +endif + +# Do not use env variables to control the CMake behavior as stated in http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_get_or_set_environment_variables.3F +# Instead define them via -D, so they will be cached. +ifdef BOOST_ROOT + CMAKE_BOOST_ROOT = -DBOOST_ROOT="$(BOOST_ROOT)" -DBoost_NO_SYSTEM_PATHS=ON +endif +# Tell CMake if it should ignore a missing Fuse. +ifdef SKIP_FUSE + CMAKE_SKIP_FUSE = -DSKIP_FUSE=true +endif +# Trigger building the experimental LD_PRELOAD library +ifdef BUILD_PRELOAD + CMAKE_BUILD_PRELOAD = -DBUILD_PRELOAD=true +endif + + +client_thirdparty: $(CLIENT_THIRDPARTY_REQUIREMENTS) + +$(CLIENT_GOOGLE_PROTOBUF_CPP_LIBRARY): $(CLIENT_GOOGLE_PROTOBUF_CPP)/src/** + @echo "client_thirdparty: Configuring and building required Google protobuf library..." + @cd $(CLIENT_GOOGLE_PROTOBUF_CPP) && LIBS=-lpthread ./configure $(PROTOBUF_DISABLE_64_BIT_SOLARIS) >/dev/null + @$(MAKE) -C $(CLIENT_GOOGLE_PROTOBUF_CPP) >/dev/null + @echo "client_thirdparty: ...completed building required Google protobuf library." + @touch $(CLIENT_GOOGLE_PROTOBUF_CPP_LIBRARY) + +$(CLIENT_GOOGLE_TEST_CPP_LIBRARY): $(CLIENT_GOOGLE_TEST_CHECKFILE) + @touch $(CLIENT_GOOGLE_TEST_CPP_LIBRARY) + +$(CLIENT_GOOGLE_TEST_CPP_MAIN): $(CLIENT_GOOGLE_TEST_CHECKFILE) + @touch $(CLIENT_GOOGLE_TEST_CPP_MAIN) + +$(CLIENT_GOOGLE_TEST_CHECKFILE): $(CLIENT_GOOGLE_TEST_CPP)/include/** $(CLIENT_GOOGLE_TEST_CPP)/src/** + @echo "client_thirdparty: Configuring and building required Google googletest library..." + @cd $(CLIENT_GOOGLE_TEST_CPP) && ./configure >/dev/null + @$(MAKE) -C $(CLIENT_GOOGLE_TEST_CPP) >/dev/null + @touch $(CLIENT_GOOGLE_TEST_CPP_LIBRARY) + @echo "client_thirdparty: ...completed building required Google googletest library." + @touch $(CLIENT_GOOGLE_TEST_CHECKFILE) + +client_thirdparty_clean: + @if [ -f $(CLIENT_GOOGLE_PROTOBUF_CPP)/Makefile ]; then echo "Cleaning required Google protobuf library sources..."; $(MAKE) -C $(CLIENT_GOOGLE_PROTOBUF_CPP) clean >/dev/null; fi + @if [ -f $(shell pwd)/$(CLIENT_GOOGLE_TEST_CPP)/Makefile ]; then echo "Cleaning required Google googletest library sources..."; $(MAKE) -C $(shell pwd)/$(CLIENT_GOOGLE_TEST_CPP) clean >/dev/null; fi + @if [ -f $(CLIENT_GOOGLE_TEST_CHECKFILE) ]; then rm $(CLIENT_GOOGLE_TEST_CHECKFILE); fi + @echo "...finished cleaning thirdparty sources." + +client_thirdparty_distclean: + @echo "client_thirdparty: Dist-Cleaning required Google protobuf library sources..." + @if [ -f $(shell pwd)/$(CLIENT_GOOGLE_PROTOBUF_CPP)/Makefile ]; then $(MAKE) -C $(shell pwd)/$(CLIENT_GOOGLE_PROTOBUF_CPP) distclean >/dev/null; fi + @echo "client_thirdparty: Dist-Cleaning required Google googletest library sources..." + @if [ -f $(shell pwd)/$(CLIENT_GOOGLE_TEST_CPP)/Makefile ]; then $(MAKE) -C $(shell pwd)/$(CLIENT_GOOGLE_TEST_CPP) distclean >/dev/null; fi + @if [ -f $(CLIENT_GOOGLE_TEST_CHECKFILE) ]; then rm $(CLIENT_GOOGLE_TEST_CHECKFILE); fi + @echo "client_thirdparty: ...finished distcleaning thirdparty sources." + +client_debug: CLIENT_DEBUG = -DCMAKE_BUILD_TYPE=Debug +client_debug: client + +client: check_client client_thirdparty set_version + $(CMAKE_BIN) -Hcpp -B$(XTREEMFS_CLIENT_BUILD_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 $(CLIENT_DEBUG) $(CMAKE_BOOST_ROOT) $(CMAKE_BUILD_CLIENT_TESTS) $(CMAKE_SKIP_FUSE) ${CMAKE_BUILD_PRELOAD} + @$(MAKE) -C $(XTREEMFS_CLIENT_BUILD_DIR) + @cd $(XTREEMFS_CLIENT_BUILD_DIR); for i in *.xtreemfs xtfsutil; do [ -f $(XTREEMFS_BINARIES_DIR)/$$i ] && rm -f $(XTREEMFS_BINARIES_DIR)/$$i; done; true + @cp -p $(XTREEMFS_CLIENT_BUILD_DIR)/*.xtreemfs $(XTREEMFS_BINARIES_DIR) + @cp -p $(XTREEMFS_CLIENT_BUILD_DIR)/xtfsutil $(XTREEMFS_BINARIES_DIR) + +client_clean: check_client client_thirdparty_clean + @cd $(XTREEMFS_CLIENT_BUILD_DIR) &>/dev/null && { for i in *.xtreemfs xtfsutil; do [ -f $(XTREEMFS_BINARIES_DIR)/$$i ] && rm -f $(XTREEMFS_BINARIES_DIR)/$$i; done }; true + @rm -rf $(XTREEMFS_CLIENT_BUILD_DIR) + +client_distclean: check_client client_thirdparty_distclean + @cd $(XTREEMFS_CLIENT_BUILD_DIR) &>/dev/null && { for i in *.xtreemfs xtfsutil; do [ -f $(XTREEMFS_BINARIES_DIR)/$$i ] && rm -f $(XTREEMFS_BINARIES_DIR)/$$i; done }; true + @rm -rf $(XTREEMFS_CLIENT_BUILD_DIR) + +CLIENT_PACKAGE_MACOSX_OUTPUT_DIR = XtreemFS_Client_MacOSX.mpkg +CLIENT_PACKAGE_MACOSX_OUTPUT_FILE = XtreemFS_Client_MacOSX_installer.dmg +client_package_macosx: +ifeq ($(CMAKE_BOOST_ROOT),) + @echo No BOOST_ROOT environment variable is specified. This will probably fail. Please set it first.; exit 1 +endif + @./packaging/set_version.sh -i +# Clean everything first to ensure we package a clean client. + @$(MAKE) client_distclean +# We call $(MAKE) instead of specifying the targets as requirements as its not possible to define dependencies between these two and this breaks in case of parallel builds. + @$(MAKE) client SKIP_SET_SVN_VERSION=1 + @echo "Running the Apple Packagemaker..." + @/Developer/usr/bin/packagemaker -d packaging/macosx/XtreemFS_MacOSX_Package.pmdoc/ -o $(CLIENT_PACKAGE_MACOSX_OUTPUT_DIR) + @echo "Creating a DMG file..." + @if [ -f "$(CLIENT_PACKAGE_MACOSX_OUTPUT_FILE)" ]; then echo "Removing previous file $(CLIENT_PACKAGE_MACOSX_OUTPUT_FILE)."; rm "$(CLIENT_PACKAGE_MACOSX_OUTPUT_FILE)"; fi + @hdiutil create -fs HFS+ -srcfolder "$(CLIENT_PACKAGE_MACOSX_OUTPUT_DIR)" -volname "XtreemFS Client for MacOSX" "$(CLIENT_PACKAGE_MACOSX_OUTPUT_FILE)" + @if [ -d "$(CLIENT_PACKAGE_MACOSX_OUTPUT_DIR)" ]; then echo "Cleaning up temporary files..."; rm -r "$(CLIENT_PACKAGE_MACOSX_OUTPUT_DIR)"; fi + @echo "Package file created: $(CLIENT_PACKAGE_MACOSX_OUTPUT_FILE)" + +.PHONY: flease flease_clean flease_distclean +flease: foundation + $(ANT_BIN) -D"file.encoding=UTF-8" -f java/flease/build-1.6.5.xml jar +flease_clean: + $(ANT_BIN) -D"file.encoding=UTF-8" -f java/flease/build-1.6.5.xml clean || exit 1; +flease_distclean: + $(ANT_BIN) -D"file.encoding=UTF-8" -f java/flease/build-1.6.5.xml clean || exit 1; + +.PHONY: foundation foundation_clean foundation_distclean +foundation: set_version + $(ANT_BIN) -D"file.encoding=UTF-8" -f java/foundation/build-1.6.5.xml jar +foundation_clean: + $(ANT_BIN) -D"file.encoding=UTF-8" -f java/foundation/build-1.6.5.xml clean || exit 1; +foundation_distclean: + $(ANT_BIN) -D"file.encoding=UTF-8" -f java/foundation/build-1.6.5.xml clean || exit 1; + +.PHONY: server server_clean server_distclean +server: check_server foundation flease + $(ANT_BIN) -D"file.encoding=UTF-8" -f java/servers/build-1.6.5.xml jar +server_clean: check_server + $(ANT_BIN) -D"file.encoding=UTF-8" -f java/servers/build-1.6.5.xml clean || exit 1; +server_distclean: check_server + $(ANT_BIN) -D"file.encoding=UTF-8" -f java/servers/build-1.6.5.xml clean || exit 1; + +.PHONY: hadoop-client hadoop-client_clean hadoop-client_distclean +hadoop-client: server foundation + $(ANT_BIN) -D"file.encoding=UTF-8" -f contrib/hadoop/build.xml jar + @echo -e "\n\nHadoop Client was successfully compiled. You can find it here:\n\n\tcontrib/hadoop/dist/XtreemFSHadoopClient.jar\n\nSee the XtreemFS User Guide how to add it in Hadoop.\n" +hadoop-client_clean: + $(ANT_BIN) -D"file.encoding=UTF-8" -f contrib/hadoop/build.xml clean || exit 1 +hadoop-client_distclean: + $(ANT_BIN) -D"file.encoding=UTF-8" -f contrib/hadoop/build.xml clean || exit 1 + +test: check_test client server + python ./tests/xtestenv -c ./tests/test_config.py short + +pbrpcgen: + $(ANT_BIN) -D"file.encoding=UTF-8" -f java/pbrpcgen/build.xml + +pbrpcgen_clean: + $(ANT_BIN) -D"file.encoding=UTF-8" -f java/pbrpcgen/build.xml clean || exit 1 + +interfaces: pbrpcgen client_thirdparty + $(MAKE) -C interface diff --git a/README.md b/README.md new file mode 100644 index 0000000..1ea3039 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +XtreemFS is a distributed, replicated and fault-tolerant file system for federated IT infrastructures. It is open source software licensed under the New BSD License. + +**For more information, downloads and documentation visit our website at http://www.XtreemFS.org.** + + * Website: http://www.XtreemFS.org + * Downloads (Linux, MacOSX, Windows): http://www.XtreemFS.org/download.php + * User Documentation: http://www.XtreemFS.org/userguide.php + * Mailing List: http://groups.google.com/group/xtreemfs + * Tutorial for Replication Fail-Over Demo: https://code.google.com/p/xtreemfs/wiki/ContrailSummerSchoolHandsOn2013 + +The XtreemFS project is developed by Zuse Institute Berlin. The development of the project is funded by the European Commission since 2006 under Grant Agreements No. FP6-033576, FP7-ICT-257438, and FP7-318521, as well as the German projects MoSGrid, "First We Take Berlin", FFMK, GeoMultiSens, and BBDC. + +[![Build Status](https://travis-ci.org/xtreemfs/xtreemfs.svg?branch=master)](https://travis-ci.org/xtreemfs/xtreemfs) diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..80b9725 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,129 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + # All Vagrant configuration is done here. The most common configuration + # options are documented and commented below. For a complete reference, + # please see the online documentation at vagrantup.com. + + # Every Vagrant virtual environment requires a box to build off of. + config.vm.box = "precise64" + + # The url from where the 'config.vm.box' box will be fetched if it + # doesn't already exist on the user's system. + config.vm.box_url = "http://files.vagrantup.com/precise64.box" + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # config.vm.network :forwarded_port, guest: 80, host: 8080 + + config.vm.network :forwarded_port, guest: 30636, host: 30636 + config.vm.network :forwarded_port, guest: 32636, host: 32636 + config.vm.network :forwarded_port, guest: 30638, host: 30638 + config.vm.network :forwarded_port, guest: 32638, host: 32638 + config.vm.network :forwarded_port, guest: 30640, host: 30640 + config.vm.network :forwarded_port, guest: 32640, host: 32640 + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network :private_network, ip: "192.168.33.10" + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + # config.vm.network :public_network + + # If true, then any SSH connections made will enable agent forwarding. + # Default value: false + # config.ssh.forward_agent = true + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + + config.vm.synced_folder ".", "/vagrant", disabled: true + config.vm.synced_folder ".", "/xtreemfs_src" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + # + # config.vm.provider :virtualbox do |vb| + # # Don't boot with headless mode + # vb.gui = true + # + # # Use VBoxManage to customize the VM. For example to change memory: + # vb.customize ["modifyvm", :id, "--memory", "1024"] + # end + # + # View the documentation for the provider you're using for more + # information on available options. + + # Enable provisioning with Puppet stand alone. Puppet manifests + # are contained in a directory path relative to this Vagrantfile. + # You will need to create the manifests directory and a manifest in + # the file precise64.pp in the manifests_path directory. + # + # An example Puppet manifest to provision the message of the day: + # + # # group { "puppet": + # # ensure => "present", + # # } + # # + # # File { owner => 0, group => 0, mode => 0644 } + # # + # # file { '/etc/motd': + # # content => "Welcome to your Vagrant-built virtual machine! + # # Managed by Puppet.\n" + # # } + # + # config.vm.provision :puppet do |puppet| + # puppet.manifests_path = "manifests" + # puppet.manifest_file = "site.pp" + # end + + # Enable provisioning with chef solo, specifying a cookbooks path, roles + # path, and data_bags path (all relative to this Vagrantfile), and adding + # some recipes and/or roles. + # + # config.vm.provision :chef_solo do |chef| + # chef.cookbooks_path = "../my-recipes/cookbooks" + # chef.roles_path = "../my-recipes/roles" + # chef.data_bags_path = "../my-recipes/data_bags" + # chef.add_recipe "mysql" + # chef.add_role "web" + # + # # You may also specify custom JSON attributes: + # chef.json = { :mysql_password => "foo" } + # end + + # Enable provisioning with chef server, specifying the chef server URL, + # and the path to the validation key (relative to this Vagrantfile). + # + # The Opscode Platform uses HTTPS. Substitute your organization for + # ORGNAME in the URL and validation key. + # + # If you have your own Chef Server, use the appropriate URL, which may be + # HTTP instead of HTTPS depending on your configuration. Also change the + # validation key to validation.pem. + # + # config.vm.provision :chef_client do |chef| + # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME" + # chef.validation_key_path = "ORGNAME-validator.pem" + # end + # + # If you're using the Opscode platform, your validator client is + # ORGNAME-validator, replacing ORGNAME with your organization name. + # + # If you have your own Chef Server, the default validation client name is + # chef-validator, unless you changed the configuration. + # + # chef.validation_client_name = "ORGNAME-validator" + + config.vm.provision "shell", path: "contrib/vagrant/provision.sh" +end diff --git a/bin/cpplint.py b/bin/cpplint.py new file mode 100755 index 0000000..188f8ea --- /dev/null +++ b/bin/cpplint.py @@ -0,0 +1,2725 @@ +#!/usr/bin/python +# +# cpplint.py is Copyright (C) 2009 Google Inc. +# +# It is free software; you can redistribute it and/or modify it under the +# terms of either: +# +# a) the GNU General Public License as published by the Free Software +# Foundation; either version 1, or (at your option) any later version, or +# +# b) the "Artistic License". + +# Here are some issues that I've had people identify in my code during reviews, +# that I think are possible to flag automatically in a lint tool. If these were +# caught by lint, it would save time both for myself and that of my reviewers. +# Most likely, some of these are beyond the scope of the current lint framework, +# but I think it is valuable to retain these wish-list items even if they cannot +# be immediately implemented. +# +# Suggestions +# ----------- +# - Check for no 'explicit' for multi-arg ctor +# - Check for boolean assign RHS in parens +# - Check for ctor initializer-list colon position and spacing +# - Check that if there's a ctor, there should be a dtor +# - Check accessors that return non-pointer member variables are +# declared const +# - Check accessors that return non-const pointer member vars are +# *not* declared const +# - Check for using public includes for testing +# - Check for spaces between brackets in one-line inline method +# - Check for no assert() +# - Check for spaces surrounding operators +# - Check for 0 in pointer context (should be NULL) +# - Check for 0 in char context (should be '\0') +# - Check for camel-case method name conventions for methods +# that are not simple inline getters and setters +# - Check that base classes have virtual destructors +# put " // namespace" after } that closes a namespace, with +# namespace's name after 'namespace' if it is named. +# - Do not indent namespace contents +# - Avoid inlining non-trivial constructors in header files +# include base/basictypes.h if DISALLOW_EVIL_CONSTRUCTORS is used +# - Check for old-school (void) cast for call-sites of functions +# ignored return value +# - Check gUnit usage of anonymous namespace +# - Check for class declaration order (typedefs, consts, enums, +# ctor(s?), dtor, friend declarations, methods, member vars) +# + +"""Does google-lint on c++ files. + +The goal of this script is to identify places in the code that *may* +be in non-compliance with google style. It does not attempt to fix +up these problems -- the point is to educate. It does also not +attempt to find all problems, or to ensure that everything it does +find is legitimately a problem. + +In particular, we can get very confused by /* and // inside strings! +We do a small hack, which is to ignore //'s with "'s after them on the +same line, but it is far from perfect (in either direction). +""" + +import codecs +import getopt +import math # for log +import os +import re +import sre_compile +import string +import sys +import unicodedata + + +_USAGE = """ +Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] + [file] ... + + The style guidelines this tries to follow are those in + http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml + + Every problem is given a confidence score from 1-5, with 5 meaning we are + certain of the problem, and 1 meaning it could be a legitimate construct. + This will miss some errors, and is not a substitute for a code review. + + To prevent specific lines from being linted, add a '// NOLINT' comment to the + end of the line. + + The files passed in will be linted; at least one file must be provided. + Linted extensions are .cc, .cpp, and .h. Other file types will be ignored. + + Flags: + + output=vs7 + By default, the output is formatted to ease emacs parsing. Visual Studio + compatible output (vs7) may also be used. Other formats are unsupported. + + verbose=# + Specify a number 0-5 to restrict errors to certain verbosity levels. + + filter=-x,+y,... + Specify a comma-separated list of category-filters to apply: only + error messages whose category names pass the filters will be printed. + (Category names are printed with the message and look like + "[whitespace/indent]".) Filters are evaluated left to right. + "-FOO" and "FOO" means "do not print categories that start with FOO". + "+FOO" means "do print categories that start with FOO". + + Examples: --filter=-whitespace,+whitespace/braces + --filter=whitespace,runtime/printf,+runtime/printf_format + --filter=-,+build/include_what_you_use + + To see a list of all the categories used in cpplint, pass no arg: + --filter= +""" + +# We categorize each error message we print. Here are the categories. +# We want an explicit list so we can list them all in cpplint --filter=. +# If you add a new error message with a new category, add it to the list +# here! cpplint_unittest.py should tell you if you forget to do this. +_ERROR_CATEGORIES = """\ + build/class + build/deprecated + build/endif_comment + build/forward_decl + build/header_guard + build/include + build/include_order + build/include_what_you_use + build/namespaces + build/printf_format + build/storage_class + legal/copyright + readability/braces + readability/casting + readability/check + readability/constructors + readability/fn_size + readability/function + readability/multiline_comment + readability/multiline_string + readability/streams + readability/todo + readability/utf8 + runtime/arrays + runtime/casting + runtime/explicit + runtime/int + runtime/init + runtime/memset + runtime/printf + runtime/printf_format + runtime/references + runtime/rtti + runtime/sizeof + runtime/string + runtime/threadsafe_fn + runtime/virtual + whitespace/blank_line + whitespace/braces + whitespace/comma + whitespace/comments + whitespace/end_of_line + whitespace/ending_newline + whitespace/indent + whitespace/labels + whitespace/line_length + whitespace/newline + whitespace/operators + whitespace/parens + whitespace/semicolon + whitespace/tab + whitespace/todo +""" + +# We used to check for high-bit characters, but after much discussion we +# decided those were OK, as long as they were in UTF-8 and didn't represent +# hard-coded international strings, which belong in a seperate i18n file. + +# Headers that we consider STL headers. +_STL_HEADERS = frozenset([ + 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception', + 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set', + 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h', + 'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack', + 'stl_alloc.h', 'stl_relops.h', 'type_traits.h', + 'utility', 'vector', 'vector.h', + ]) + + +# Non-STL C++ system headers. +_CPP_HEADERS = frozenset([ + 'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype', + 'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath', + 'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef', + 'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype', + 'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream', + 'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip', + 'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream.h', + 'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h', + 'numeric', 'ostream.h', 'parsestream.h', 'pfstream.h', 'PlotFile.h', + 'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h', 'ropeimpl.h', + 'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept', + 'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string', + 'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray', + ]) + + +# Assertion macros. These are defined in base/logging.h and +# testing/base/gunit.h. Note that the _M versions need to come first +# for substring matching to work. +_CHECK_MACROS = [ + 'CHECK', + 'EXPECT_TRUE_M', 'EXPECT_TRUE', + 'ASSERT_TRUE_M', 'ASSERT_TRUE', + 'EXPECT_FALSE_M', 'EXPECT_FALSE', + 'ASSERT_FALSE_M', 'ASSERT_FALSE', + ] + +# Replacement macros for CHECK/EXPECT_TRUE/EXPECT_FALSE +_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS]) + +for op, replacement in [('==', 'EQ'), ('!=', 'NE'), + ('>=', 'GE'), ('>', 'GT'), + ('<=', 'LE'), ('<', 'LT')]: + _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement + _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement + _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement + _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement + _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement + +for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'), + ('>=', 'LT'), ('>', 'LE'), + ('<=', 'GT'), ('<', 'GE')]: + _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement + _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement + _CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement + _CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement + + +# These constants define types of headers for use with +# _IncludeState.CheckNextIncludeOrder(). +_C_SYS_HEADER = 1 +_CPP_SYS_HEADER = 2 +_LIKELY_MY_HEADER = 3 +_POSSIBLE_MY_HEADER = 4 +_OTHER_HEADER = 5 + + +_regexp_compile_cache = {} + + +def Match(pattern, s): + """Matches the string with the pattern, caching the compiled regexp.""" + # The regexp compilation caching is inlined in both Match and Search for + # performance reasons; factoring it out into a separate function turns out + # to be noticeably expensive. + if not pattern in _regexp_compile_cache: + _regexp_compile_cache[pattern] = sre_compile.compile(pattern) + return _regexp_compile_cache[pattern].match(s) + + +def Search(pattern, s): + """Searches the string for the pattern, caching the compiled regexp.""" + if not pattern in _regexp_compile_cache: + _regexp_compile_cache[pattern] = sre_compile.compile(pattern) + return _regexp_compile_cache[pattern].search(s) + + +class _IncludeState(dict): + """Tracks line numbers for includes, and the order in which includes appear. + + As a dict, an _IncludeState object serves as a mapping between include + filename and line number on which that file was included. + + Call CheckNextIncludeOrder() once for each header in the file, passing + in the type constants defined above. Calls in an illegal order will + raise an _IncludeError with an appropriate error message. + + """ + # self._section will move monotonically through this set. If it ever + # needs to move backwards, CheckNextIncludeOrder will raise an error. + _INITIAL_SECTION = 0 + _MY_H_SECTION = 1 + _C_SECTION = 2 + _CPP_SECTION = 3 + _OTHER_H_SECTION = 4 + + _TYPE_NAMES = { + _C_SYS_HEADER: 'C system header', + _CPP_SYS_HEADER: 'C++ system header', + _LIKELY_MY_HEADER: 'header this file implements', + _POSSIBLE_MY_HEADER: 'header this file may implement', + _OTHER_HEADER: 'other header', + } + _SECTION_NAMES = { + _INITIAL_SECTION: "... nothing. (This can't be an error.)", + _MY_H_SECTION: 'a header this file implements', + _C_SECTION: 'C system header', + _CPP_SECTION: 'C++ system header', + _OTHER_H_SECTION: 'other header', + } + + def __init__(self): + dict.__init__(self) + self._section = self._INITIAL_SECTION + + def CheckNextIncludeOrder(self, header_type): + """Returns a non-empty error message if the next header is out of order. + + This function also updates the internal state to be ready to check + the next include. + + Args: + header_type: One of the _XXX_HEADER constants defined above. + + Returns: + The empty string if the header is in the right order, or an + error message describing what's wrong. + + """ + error_message = ('Found %s after %s' % + (self._TYPE_NAMES[header_type], + self._SECTION_NAMES[self._section])) + + if header_type == _C_SYS_HEADER: + if self._section <= self._C_SECTION: + self._section = self._C_SECTION + else: + return error_message + elif header_type == _CPP_SYS_HEADER: + if self._section <= self._CPP_SECTION: + self._section = self._CPP_SECTION + else: + return error_message + elif header_type == _LIKELY_MY_HEADER: + if self._section <= self._MY_H_SECTION: + self._section = self._MY_H_SECTION + else: + self._section = self._OTHER_H_SECTION + elif header_type == _POSSIBLE_MY_HEADER: + if self._section <= self._MY_H_SECTION: + self._section = self._MY_H_SECTION + else: + # This will always be the fallback because we're not sure + # enough that the header is associated with this file. + self._section = self._OTHER_H_SECTION + else: + assert header_type == _OTHER_HEADER + self._section = self._OTHER_H_SECTION + + return '' + + +class _CppLintState(object): + """Maintains module-wide state..""" + + def __init__(self): + self.verbose_level = 1 # global setting. + self.error_count = 0 # global count of reported errors + self.filters = [] # filters to apply when emitting error messages + + # output format: + # "emacs" - format that emacs can parse (default) + # "vs7" - format that Microsoft Visual Studio 7 can parse + self.output_format = 'emacs' + + def SetOutputFormat(self, output_format): + """Sets the output format for errors.""" + self.output_format = output_format + + def SetVerboseLevel(self, level): + """Sets the module's verbosity, and returns the previous setting.""" + last_verbose_level = self.verbose_level + self.verbose_level = level + return last_verbose_level + + def SetFilters(self, filters): + """Sets the error-message filters. + + These filters are applied when deciding whether to emit a given + error message. + + Args: + filters: A string of comma-separated filters (eg "+whitespace/indent"). + Each filter should start with + or -; else we die. + """ + if not filters: + self.filters = [] + else: + self.filters = filters.split(',') + for filt in self.filters: + if not (filt.startswith('+') or filt.startswith('-')): + raise ValueError('Every filter in --filters must start with + or -' + ' (%s does not)' % filt) + + def ResetErrorCount(self): + """Sets the module's error statistic back to zero.""" + self.error_count = 0 + + def IncrementErrorCount(self): + """Bumps the module's error statistic.""" + self.error_count += 1 + + +_cpplint_state = _CppLintState() + + +def _OutputFormat(): + """Gets the module's output format.""" + return _cpplint_state.output_format + + +def _SetOutputFormat(output_format): + """Sets the module's output format.""" + _cpplint_state.SetOutputFormat(output_format) + + +def _VerboseLevel(): + """Returns the module's verbosity setting.""" + return _cpplint_state.verbose_level + + +def _SetVerboseLevel(level): + """Sets the module's verbosity, and returns the previous setting.""" + return _cpplint_state.SetVerboseLevel(level) + + +def _Filters(): + """Returns the module's list of output filters, as a list.""" + return _cpplint_state.filters + + +def _SetFilters(filters): + """Sets the module's error-message filters. + + These filters are applied when deciding whether to emit a given + error message. + + Args: + filters: A string of comma-separated filters (eg "whitespace/indent"). + Each filter should start with + or -; else we die. + """ + _cpplint_state.SetFilters(filters) + + +class _FunctionState(object): + """Tracks current function name and the number of lines in its body.""" + + _NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc. + _TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER. + + def __init__(self): + self.in_a_function = False + self.lines_in_function = 0 + self.current_function = '' + + def Begin(self, function_name): + """Start analyzing function body. + + Args: + function_name: The name of the function being tracked. + """ + self.in_a_function = True + self.lines_in_function = 0 + self.current_function = function_name + + def Count(self): + """Count line in current function body.""" + if self.in_a_function: + self.lines_in_function += 1 + + def Check(self, error, filename, linenum): + """Report if too many lines in function body. + + Args: + error: The function to call with any errors found. + filename: The name of the current file. + linenum: The number of the line to check. + """ + if Match(r'T(EST|est)', self.current_function): + base_trigger = self._TEST_TRIGGER + else: + base_trigger = self._NORMAL_TRIGGER + trigger = base_trigger * 2**_VerboseLevel() + + if self.lines_in_function > trigger: + error_level = int(math.log(self.lines_in_function / base_trigger, 2)) + # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ... + if error_level > 5: + error_level = 5 + error(filename, linenum, 'readability/fn_size', error_level, + 'Small and focused functions are preferred:' + ' %s has %d non-comment lines' + ' (error triggered by exceeding %d lines).' % ( + self.current_function, self.lines_in_function, trigger)) + + def End(self): + """Stop analizing function body.""" + self.in_a_function = False + + +class _IncludeError(Exception): + """Indicates a problem with the include order in a file.""" + pass + + +class FileInfo: + """Provides utility functions for filenames. + + FileInfo provides easy access to the components of a file's path + relative to the project root. + """ + + def __init__(self, filename): + self._filename = filename + + def FullName(self): + """Make Windows paths like Unix.""" + return os.path.abspath(self._filename).replace('\\', '/') + + def RepositoryName(self): + """FullName after removing the local path to the repository. + + If we have a real absolute path name here we can try to do something smart: + detecting the root of the checkout and truncating /path/to/checkout from + the name so that we get header guards that don't include things like + "C:\Documents and Settings\..." or "/home/username/..." in them and thus + people on different computers who have checked the source out to different + locations won't see bogus errors. + """ + fullname = self.FullName() + + if os.path.exists(fullname): + project_dir = os.path.dirname(fullname) + + if os.path.exists(os.path.join(project_dir, ".svn")): + # If there's a .svn file in the current directory, we recursively look + # up the directory tree for the top of the SVN checkout + root_dir = project_dir + one_up_dir = os.path.dirname(root_dir) + while os.path.exists(os.path.join(one_up_dir, ".svn")): + root_dir = os.path.dirname(root_dir) + one_up_dir = os.path.dirname(one_up_dir) + + prefix = os.path.commonprefix([root_dir, project_dir]) + return fullname[len(prefix) + 1:] + + # Not SVN? Try to find a git top level directory by searching up from the + # current path. + root_dir = os.path.dirname(fullname) + while (root_dir != os.path.dirname(root_dir) and + not os.path.exists(os.path.join(root_dir, ".git"))): + root_dir = os.path.dirname(root_dir) + if os.path.exists(os.path.join(root_dir, ".git")): + prefix = os.path.commonprefix([root_dir, project_dir]) + return fullname[len(prefix) + 1:] + + # Don't know what to do; header guard warnings may be wrong... + return fullname + + def Split(self): + """Splits the file into the directory, basename, and extension. + + For 'chrome/browser/browser.cc', Split() would + return ('chrome/browser', 'browser', '.cc') + + Returns: + A tuple of (directory, basename, extension). + """ + + googlename = self.RepositoryName() + project, rest = os.path.split(googlename) + return (project,) + os.path.splitext(rest) + + def BaseName(self): + """File base name - text after the final slash, before the final period.""" + return self.Split()[1] + + def Extension(self): + """File extension - text following the final period.""" + return self.Split()[2] + + def NoExtension(self): + """File has no source file extension.""" + return '/'.join(self.Split()[0:2]) + + def IsSource(self): + """File has a source file extension.""" + return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx') + + +def _ShouldPrintError(category, confidence): + """Returns true iff confidence >= verbose, and category passes filter.""" + # There are two ways we might decide not to print an error message: + # the verbosity level isn't high enough, or the filters filter it out. + if confidence < _cpplint_state.verbose_level: + return False + + is_filtered = False + for one_filter in _Filters(): + if one_filter.startswith('-'): + if category.startswith(one_filter[1:]): + is_filtered = True + elif one_filter.startswith('+'): + if category.startswith(one_filter[1:]): + is_filtered = False + else: + assert False # should have been checked for in SetFilter. + if is_filtered: + return False + + return True + + +def Error(filename, linenum, category, confidence, message): + """Logs the fact we've found a lint error. + + We log where the error was found, and also our confidence in the error, + that is, how certain we are this is a legitimate style regression, and + not a misidentification or a use that's sometimes justified. + + Args: + filename: The name of the file containing the error. + linenum: The number of the line containing the error. + category: A string used to describe the "category" this bug + falls under: "whitespace", say, or "runtime". Categories + may have a hierarchy separated by slashes: "whitespace/indent". + confidence: A number from 1-5 representing a confidence score for + the error, with 5 meaning that we are certain of the problem, + and 1 meaning that it could be a legitimate construct. + message: The error message. + """ + # There are two ways we might decide not to print an error message: + # the verbosity level isn't high enough, or the filters filter it out. + if _ShouldPrintError(category, confidence): + _cpplint_state.IncrementErrorCount() + if _cpplint_state.output_format == 'vs7': + sys.stderr.write('%s(%s): %s [%s] [%d]\n' % ( + filename, linenum, message, category, confidence)) + else: + sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( + filename, linenum, message, category, confidence)) + + +# Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard. +_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile( + r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)') +# Matches strings. Escape codes should already be removed by ESCAPES. +_RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"') +# Matches characters. Escape codes should already be removed by ESCAPES. +_RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'") +# Matches multi-line C++ comments. +# This RE is a little bit more complicated than one might expect, because we +# have to take care of space removals tools so we can handle comments inside +# statements better. +# The current rule is: We only clear spaces from both sides when we're at the +# end of the line. Otherwise, we try to remove spaces from the right side, +# if this doesn't work we try on left side but only if there's a non-character +# on the right. +_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile( + r"""(\s*/\*.*\*/\s*$| + /\*.*\*/\s+| + \s+/\*.*\*/(?=\W)| + /\*.*\*/)""", re.VERBOSE) + + +def IsCppString(line): + """Does line terminate so, that the next symbol is in string constant. + + This function does not consider single-line nor multi-line comments. + + Args: + line: is a partial line of code starting from the 0..n. + + Returns: + True, if next character appended to 'line' is inside a + string constant. + """ + + line = line.replace(r'\\', 'XX') # after this, \\" does not match to \" + return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1 + + +def FindNextMultiLineCommentStart(lines, lineix): + """Find the beginning marker for a multiline comment.""" + while lineix < len(lines): + if lines[lineix].strip().startswith('/*'): + # Only return this marker if the comment goes beyond this line + if lines[lineix].strip().find('*/', 2) < 0: + return lineix + lineix += 1 + return len(lines) + + +def FindNextMultiLineCommentEnd(lines, lineix): + """We are inside a comment, find the end marker.""" + while lineix < len(lines): + if lines[lineix].strip().endswith('*/'): + return lineix + lineix += 1 + return len(lines) + + +def RemoveMultiLineCommentsFromRange(lines, begin, end): + """Clears a range of lines for multi-line comments.""" + # Having // dummy comments makes the lines non-empty, so we will not get + # unnecessary blank line warnings later in the code. + for i in range(begin, end): + lines[i] = '// dummy' + + +def RemoveMultiLineComments(filename, lines, error): + """Removes multiline (c-style) comments from lines.""" + lineix = 0 + while lineix < len(lines): + lineix_begin = FindNextMultiLineCommentStart(lines, lineix) + if lineix_begin >= len(lines): + return + lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin) + if lineix_end >= len(lines): + error(filename, lineix_begin + 1, 'readability/multiline_comment', 5, + 'Could not find end of multi-line comment') + return + RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1) + lineix = lineix_end + 1 + + +def CleanseComments(line): + """Removes //-comments and single-line C-style /* */ comments. + + Args: + line: A line of C++ source. + + Returns: + The line with single-line comments removed. + """ + commentpos = line.find('//') + if commentpos != -1 and not IsCppString(line[:commentpos]): + line = line[:commentpos] + # get rid of /* ... */ + return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) + + +class CleansedLines: + """Holds 3 copies of all lines with different preprocessing applied to them. + + 1) elided member contains lines without strings and comments, + 2) lines member contains lines without comments, and + 3) raw member contains all the lines without processing. + All these three members are of , and of the same length. + """ + + def __init__(self, lines): + self.elided = [] + self.lines = [] + self.raw_lines = lines + self.num_lines = len(lines) + for linenum in range(len(lines)): + self.lines.append(CleanseComments(lines[linenum])) + elided = self._CollapseStrings(lines[linenum]) + self.elided.append(CleanseComments(elided)) + + def NumLines(self): + """Returns the number of lines represented.""" + return self.num_lines + + @staticmethod + def _CollapseStrings(elided): + """Collapses strings and chars on a line to simple "" or '' blocks. + + We nix strings first so we're not fooled by text like '"http://"' + + Args: + elided: The line being processed. + + Returns: + The line with collapsed strings. + """ + if not _RE_PATTERN_INCLUDE.match(elided): + # Remove escaped characters first to make quote/single quote collapsing + # basic. Things that look like escaped characters shouldn't occur + # outside of strings and chars. + elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided) + elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided) + elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided) + return elided + + +def CloseExpression(clean_lines, linenum, pos): + """If input points to ( or { or [, finds the position that closes it. + + If lines[linenum][pos] points to a '(' or '{' or '[', finds the the + linenum/pos that correspond to the closing of the expression. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + pos: A position on the line. + + Returns: + A tuple (line, linenum, pos) pointer *past* the closing brace, or + (line, len(lines), -1) if we never find a close. Note we ignore + strings and comments when matching; and the line we return is the + 'cleansed' line at linenum. + """ + + line = clean_lines.elided[linenum] + startchar = line[pos] + if startchar not in '({[': + return (line, clean_lines.NumLines(), -1) + if startchar == '(': endchar = ')' + if startchar == '[': endchar = ']' + if startchar == '{': endchar = '}' + + num_open = line.count(startchar) - line.count(endchar) + while linenum < clean_lines.NumLines() and num_open > 0: + linenum += 1 + line = clean_lines.elided[linenum] + num_open += line.count(startchar) - line.count(endchar) + # OK, now find the endchar that actually got us back to even + endpos = len(line) + while num_open >= 0: + endpos = line.rfind(')', 0, endpos) + num_open -= 1 # chopped off another ) + return (line, linenum, endpos + 1) + + +def CheckForCopyright(filename, lines, error): + """Logs an error if no Copyright message appears at the top of the file.""" + + # We'll say it should occur by line 10. Don't forget there's a + # dummy line at the front. + for line in xrange(1, min(len(lines), 11)): + if re.search(r'Copyright', lines[line], re.I): break + else: # means no copyright line was found + error(filename, 0, 'legal/copyright', 5, + 'No copyright message found. ' + 'You should have a line: "Copyright [year] "') + + +def GetHeaderGuardCPPVariable(filename): + """Returns the CPP variable that should be used as a header guard. + + Args: + filename: The name of a C++ header file. + + Returns: + The CPP variable that should be used as a header guard in the + named file. + + """ + + fileinfo = FileInfo(filename) + return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper() + '_' + + +def CheckForHeaderGuard(filename, lines, error): + """Checks that the file contains a header guard. + + Logs an error if no #ifndef header guard is present. For google3 + headers, checks that the full pathname is used. + + Args: + filename: The name of the C++ header file. + lines: An array of strings, each representing a line of the file. + error: The function to call with any errors found. + """ + + cppvar = GetHeaderGuardCPPVariable(filename) + + ifndef = None + ifndef_linenum = 0 + define = None + endif = None + endif_linenum = 0 + for linenum, line in enumerate(lines): + linesplit = line.split() + if len(linesplit) >= 2: + # find the first occurrence of #ifndef and #define, save arg + if not ifndef and linesplit[0] == '#ifndef': + # set ifndef to the header guard presented on the #ifndef line. + ifndef = linesplit[1] + ifndef_linenum = linenum + if not define and linesplit[0] == '#define': + define = linesplit[1] + # find the last occurrence of #endif, save entire line + if line.startswith('#endif'): + endif = line + endif_linenum = linenum + + if not ifndef or not define or ifndef != define: + error(filename, 0, 'build/header_guard', 5, + 'No #ifndef header guard found, suggested CPP variable is: %s' % + cppvar) + return + + # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ + # for backward compatibility. + if ifndef != cppvar: + error_level = 0 + if ifndef != cppvar + '_': + error_level = 5 + + error(filename, ifndef_linenum, 'build/header_guard', error_level, + '#ifndef header guard has wrong style, please use: %s' % cppvar) + + if endif != ('#endif // %s' % cppvar): + error_level = 0 + if endif != ('#endif // %s' % (cppvar + '_')): + error_level = 5 + + error(filename, endif_linenum, 'build/header_guard', error_level, + '#endif line should be "#endif // %s"' % cppvar) + + +def CheckForUnicodeReplacementCharacters(filename, lines, error): + """Logs an error for each line containing Unicode replacement characters. + + These indicate that either the file contained invalid UTF-8 (likely) + or Unicode replacement characters (which it shouldn't). Note that + it's possible for this to throw off line numbering if the invalid + UTF-8 occurred adjacent to a newline. + + Args: + filename: The name of the current file. + lines: An array of strings, each representing a line of the file. + error: The function to call with any errors found. + """ + for linenum, line in enumerate(lines): + if u'\ufffd' in line: + error(filename, linenum, 'readability/utf8', 5, + 'Line contains invalid UTF-8 (or Unicode replacement character).') + + +def CheckForNewlineAtEOF(filename, lines, error): + """Logs an error if there is no newline char at the end of the file. + + Args: + filename: The name of the current file. + lines: An array of strings, each representing a line of the file. + error: The function to call with any errors found. + """ + + # The array lines() was created by adding two newlines to the + # original file (go figure), then splitting on \n. + # To verify that the file ends in \n, we just have to make sure the + # last-but-two element of lines() exists and is empty. + if len(lines) < 3 or lines[-2]: + error(filename, len(lines) - 2, 'whitespace/ending_newline', 5, + 'Could not find a newline character at the end of the file.') + + +def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error): + """Logs an error if we see /* ... */ or "..." that extend past one line. + + /* ... */ comments are legit inside macros, for one line. + Otherwise, we prefer // comments, so it's ok to warn about the + other. Likewise, it's ok for strings to extend across multiple + lines, as long as a line continuation character (backslash) + terminates each line. Although not currently prohibited by the C++ + style guide, it's ugly and unnecessary. We don't do well with either + in this lint program, so we warn about both. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # Remove all \\ (escaped backslashes) from the line. They are OK, and the + # second (escaped) slash may trigger later \" detection erroneously. + line = line.replace('\\\\', '') + + if line.count('/*') > line.count('*/'): + error(filename, linenum, 'readability/multiline_comment', 5, + 'Complex multi-line /*...*/-style comment found. ' + 'Lint may give bogus warnings. ' + 'Consider replacing these with //-style comments, ' + 'with #if 0...#endif, ' + 'or with more clearly structured multi-line comments.') + + if (line.count('"') - line.count('\\"')) % 2: + error(filename, linenum, 'readability/multiline_string', 5, + 'Multi-line string ("...") found. This lint script doesn\'t ' + 'do well with such strings, and may give bogus warnings. They\'re ' + 'ugly and unnecessary, and you should use concatenation instead".') + + +threading_list = ( + ('asctime(', 'asctime_r('), + ('ctime(', 'ctime_r('), + ('getgrgid(', 'getgrgid_r('), + ('getgrnam(', 'getgrnam_r('), + ('getlogin(', 'getlogin_r('), + ('getpwnam(', 'getpwnam_r('), + ('getpwuid(', 'getpwuid_r('), + ('gmtime(', 'gmtime_r('), + ('localtime(', 'localtime_r('), + ('rand(', 'rand_r('), + ('readdir(', 'readdir_r('), + ('strtok(', 'strtok_r('), + ('ttyname(', 'ttyname_r('), + ) + + +def CheckPosixThreading(filename, clean_lines, linenum, error): + """Checks for calls to thread-unsafe functions. + + Much code has been originally written without consideration of + multi-threading. Also, engineers are relying on their old experience; + they have learned posix before threading extensions were added. These + tests guide the engineers to use thread-safe functions (when using + posix directly). + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + for single_thread_function, multithread_safe_function in threading_list: + ix = line.find(single_thread_function) + if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and + line[ix - 1] not in ('_', '.', '>'))): + error(filename, linenum, 'runtime/threadsafe_fn', 2, + 'Consider using ' + multithread_safe_function + + '...) instead of ' + single_thread_function + + '...) for improved thread safety.') + + +class _ClassInfo(object): + """Stores information about a class.""" + + def __init__(self, name, linenum): + self.name = name + self.linenum = linenum + self.seen_open_brace = False + self.is_derived = False + self.virtual_method_linenumber = None + self.has_virtual_destructor = False + self.brace_depth = 0 + + +class _ClassState(object): + """Holds the current state of the parse relating to class declarations. + + It maintains a stack of _ClassInfos representing the parser's guess + as to the current nesting of class declarations. The innermost class + is at the top (back) of the stack. Typically, the stack will either + be empty or have exactly one entry. + """ + + def __init__(self): + self.classinfo_stack = [] + + def CheckFinished(self, filename, error): + """Checks that all classes have been completely parsed. + + Call this when all lines in a file have been processed. + Args: + filename: The name of the current file. + error: The function to call with any errors found. + """ + if self.classinfo_stack: + # Note: This test can result in false positives if #ifdef constructs + # get in the way of brace matching. See the testBuildClass test in + # cpplint_unittest.py for an example of this. + error(filename, self.classinfo_stack[0].linenum, 'build/class', 5, + 'Failed to find complete declaration of class %s' % + self.classinfo_stack[0].name) + + +def CheckForNonStandardConstructs(filename, clean_lines, linenum, + class_state, error): + """Logs an error if we see certain non-ANSI constructs ignored by gcc-2. + + Complain about several constructs which gcc-2 accepts, but which are + not standard C++. Warning about these in lint is one way to ease the + transition to new compilers. + - put storage class first (e.g. "static const" instead of "const static"). + - "%lld" instead of %qd" in printf-type functions. + - "%1$d" is non-standard in printf-type functions. + - "\%" is an undefined character escape sequence. + - text after #endif is not allowed. + - invalid inner-style forward declaration. + - >? and ?= and )\?=?\s*(\w+|[+-]?\d+)(\.\d*)?', + line): + error(filename, linenum, 'build/deprecated', 3, + '>? and ,:]*>\s*)?(class|struct)\s+(\w+(::\w+)*)', line) + if class_decl_match: + classinfo_stack.append(_ClassInfo(class_decl_match.group(3), linenum)) + + # Everything else in this function uses the top of the stack if it's + # not empty. + if not classinfo_stack: + return + + classinfo = classinfo_stack[-1] + + # If the opening brace hasn't been seen look for it and also + # parent class declarations. + if not classinfo.seen_open_brace: + # If the line has a ';' in it, assume it's a forward declaration or + # a single-line class declaration, which we won't process. + if line.find(';') != -1: + classinfo_stack.pop() + return + classinfo.seen_open_brace = (line.find('{') != -1) + # Look for a bare ':' + if Search('(^|[^:]):($|[^:])', line): + classinfo.is_derived = True + if not classinfo.seen_open_brace: + return # Everything else in this function is for after open brace + + # The class may have been declared with namespace or classname qualifiers. + # The constructor and destructor will not have those qualifiers. + base_classname = classinfo.name.split('::')[-1] + + # Look for single-argument constructors that aren't marked explicit. + # Technically a valid construct, but against style. + args = Match(r'(? 1: + error(filename, linenum, 'whitespace/todo', 2, + 'Too many spaces before TODO') + + username = match.group(2) + if not username: + error(filename, linenum, 'readability/todo', 2, + 'Missing username in TODO; it should look like ' + '"// TODO(my_username): Stuff."') + + middle_whitespace = match.group(3) + if middle_whitespace != ' ' and middle_whitespace != '': + error(filename, linenum, 'whitespace/todo', 2, + 'TODO(my_username) should be followed by a space') + + +def CheckSpacing(filename, clean_lines, linenum, error): + """Checks for the correctness of various spacing issues in the code. + + Things we check for: spaces around operators, spaces after + if/for/while/switch, no spaces around parens in function calls, two + spaces between code and comment, don't start a block with a blank + line, don't end a function with a blank line, don't have too many + blank lines in a row. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + + raw = clean_lines.raw_lines + line = raw[linenum] + + # Before nixing comments, check if the line is blank for no good + # reason. This includes the first line after a block is opened, and + # blank lines at the end of a function (ie, right before a line like '}' + if IsBlankLine(line): + elided = clean_lines.elided + prev_line = elided[linenum - 1] + prevbrace = prev_line.rfind('{') + # TODO(unknown): Don't complain if line before blank line, and line after, + # both start with alnums and are indented the same amount. + # This ignores whitespace at the start of a namespace block + # because those are not usually indented. + if (prevbrace != -1 and prev_line[prevbrace:].find('}') == -1 + and prev_line[:prevbrace].find('namespace') == -1): + # OK, we have a blank line at the start of a code block. Before we + # complain, we check if it is an exception to the rule: The previous + # non-empty line has the paramters of a function header that are indented + # 4 spaces (because they did not fit in a 80 column line when placed on + # the same line as the function name). We also check for the case where + # the previous line is indented 6 spaces, which may happen when the + # initializers of a constructor do not fit into a 80 column line. + exception = False + if Match(r' {6}\w', prev_line): # Initializer list? + # We are looking for the opening column of initializer list, which + # should be indented 4 spaces to cause 6 space indentation afterwards. + search_position = linenum-2 + while (search_position >= 0 + and Match(r' {6}\w', elided[search_position])): + search_position -= 1 + exception = (search_position >= 0 + and elided[search_position][:5] == ' :') + else: + # Search for the function arguments or an initializer list. We use a + # simple heuristic here: If the line is indented 4 spaces; and we have a + # closing paren, without the opening paren, followed by an opening brace + # or colon (for initializer lists) we assume that it is the last line of + # a function header. If we have a colon indented 4 spaces, it is an + # initializer list. + exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)', + prev_line) + or Match(r' {4}:', prev_line)) + + if not exception: + error(filename, linenum, 'whitespace/blank_line', 2, + 'Blank line at the start of a code block. Is this needed?') + # This doesn't ignore whitespace at the end of a namespace block + # because that is too hard without pairing open/close braces; + # however, a special exception is made for namespace closing + # brackets which have a comment containing "namespace". + # + # Also, ignore blank lines at the end of a block in a long if-else + # chain, like this: + # if (condition1) { + # // Something followed by a blank line + # + # } else if (condition2) { + # // Something else + # } + if linenum + 1 < clean_lines.NumLines(): + next_line = raw[linenum + 1] + if (next_line + and Match(r'\s*}', next_line) + and next_line.find('namespace') == -1 + and next_line.find('} else ') == -1): + error(filename, linenum, 'whitespace/blank_line', 3, + 'Blank line at the end of a code block. Is this needed?') + + # Next, we complain if there's a comment too near the text + commentpos = line.find('//') + if commentpos != -1: + # Check if the // may be in quotes. If so, ignore it + if (line.count('"', 0, commentpos) - + line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes + # Allow one space for new scopes, two spaces otherwise: + if (not Match(r'^\s*{ //', line) and + ((commentpos >= 1 and + line[commentpos-1] not in string.whitespace) or + (commentpos >= 2 and + line[commentpos-2] not in string.whitespace))): + error(filename, linenum, 'whitespace/comments', 2, + 'At least two spaces is best between code and comments') + # There should always be a space between the // and the comment + commentend = commentpos + 2 + if commentend < len(line) and not line[commentend] == ' ': + # but some lines are exceptions -- e.g. if they're big + # comment delimiters like: + # //---------------------------------------------------------- + match = Search(r'[=/-]{4,}\s*$', line[commentend:]) + if not match: + error(filename, linenum, 'whitespace/comments', 4, + 'Should have a space between // and comment') + CheckComment(line[commentpos:], filename, linenum, error) + + line = clean_lines.elided[linenum] # get rid of comments and strings + + # Don't try to do spacing checks for operator methods + line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line) + + # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )". + # Otherwise not. Note we only check for non-spaces on *both* sides; + # sometimes people put non-spaces on one side when aligning ='s among + # many lines (not that this is behavior that I approve of...) + if Search(r'[\w.]=[\w.]', line) and not Search(r'\b(if|while) ', line): + error(filename, linenum, 'whitespace/operators', 4, + 'Missing spaces around =') + + # It's ok not to have spaces around binary operators like + - * /, but if + # there's too little whitespace, we get concerned. It's hard to tell, + # though, so we punt on this one for now. TODO. + + # You should always have whitespace around binary operators. + # Alas, we can't test < or > because they're legitimately used sans spaces + # (a->b, vector a). The only time we can tell is a < with no >, and + # only if it's not template params list spilling into the next line. + match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line) + if not match: + # Note that while it seems that the '<[^<]*' term in the following + # regexp could be simplified to '<.*', which would indeed match + # the same class of strings, the [^<] means that searching for the + # regexp takes linear rather than quadratic time. + if not Search(r'<[^<]*,\s*$', line): # template params spill + match = Search(r'[^<>=!\s](<)[^<>=!\s]([^>]|->)*$', line) + if match: + error(filename, linenum, 'whitespace/operators', 3, + 'Missing spaces around %s' % match.group(1)) + # We allow no-spaces around << and >> when used like this: 10<<20, but + # not otherwise (particularly, not when used as streams) + match = Search(r'[^0-9\s](<<|>>)[^0-9\s]', line) + if match: + error(filename, linenum, 'whitespace/operators', 3, + 'Missing spaces around %s' % match.group(1)) + + # There shouldn't be space around unary operators + match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line) + if match: + error(filename, linenum, 'whitespace/operators', 4, + 'Extra space for operator %s' % match.group(1)) + + # A pet peeve of mine: no spaces after an if, while, switch, or for + match = Search(r' (if\(|for\(|while\(|switch\()', line) + if match: + error(filename, linenum, 'whitespace/parens', 5, + 'Missing space before ( in %s' % match.group(1)) + + # For if/for/while/switch, the left and right parens should be + # consistent about how many spaces are inside the parens, and + # there should either be zero or one spaces inside the parens. + # We don't want: "if ( foo)" or "if ( foo )". + # Exception: "for ( ; foo; bar)" is allowed. + match = Search(r'\b(if|for|while|switch)\s*' + r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$', + line) + if match: + if len(match.group(2)) != len(match.group(4)): + if not (match.group(3) == ';' and + len(match.group(2)) == 1 + len(match.group(4))): + error(filename, linenum, 'whitespace/parens', 5, + 'Mismatching spaces inside () in %s' % match.group(1)) + if not len(match.group(2)) in [0, 1]: + error(filename, linenum, 'whitespace/parens', 5, + 'Should have zero or one spaces inside ( and ) in %s' % + match.group(1)) + + # You should always have a space after a comma (either as fn arg or operator) + if Search(r',[^\s]', line): + error(filename, linenum, 'whitespace/comma', 3, + 'Missing space after ,') + + # Next we will look for issues with function calls. + CheckSpacingForFunctionCall(filename, line, linenum, error) + + # Except after an opening paren, you should have spaces before your braces. + # And since you should never have braces at the beginning of a line, this is + # an easy test. + if Search(r'[^ (]{', line): + error(filename, linenum, 'whitespace/braces', 5, + 'Missing space before {') + + # Make sure '} else {' has spaces. + if Search(r'}else', line): + error(filename, linenum, 'whitespace/braces', 5, + 'Missing space before else') + + # You shouldn't have spaces before your brackets, except maybe after + # 'delete []' or 'new char * []'. + if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line): + error(filename, linenum, 'whitespace/braces', 5, + 'Extra space before [') + + # You shouldn't have a space before a semicolon at the end of the line. + # There's a special case for "for" since the style guide allows space before + # the semicolon there. + if Search(r':\s*;\s*$', line): + error(filename, linenum, 'whitespace/semicolon', 5, + 'Semicolon defining empty statement. Use { } instead.') + elif Search(r'^\s*;\s*$', line): + error(filename, linenum, 'whitespace/semicolon', 5, + 'Line contains only semicolon. If this should be an empty statement, ' + 'use { } instead.') + elif (Search(r'\s+;\s*$', line) and + not Search(r'\bfor\b', line)): + error(filename, linenum, 'whitespace/semicolon', 5, + 'Extra space before last semicolon. If this should be an empty ' + 'statement, use { } instead.') + + +def GetPreviousNonBlankLine(clean_lines, linenum): + """Return the most recent non-blank line and its line number. + + Args: + clean_lines: A CleansedLines instance containing the file contents. + linenum: The number of the line to check. + + Returns: + A tuple with two elements. The first element is the contents of the last + non-blank line before the current line, or the empty string if this is the + first non-blank line. The second is the line number of that line, or -1 + if this is the first non-blank line. + """ + + prevlinenum = linenum - 1 + while prevlinenum >= 0: + prevline = clean_lines.elided[prevlinenum] + if not IsBlankLine(prevline): # if not a blank line... + return (prevline, prevlinenum) + prevlinenum -= 1 + return ('', -1) + + +def CheckBraces(filename, clean_lines, linenum, error): + """Looks for misplaced braces (e.g. at the end of line). + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + + line = clean_lines.elided[linenum] # get rid of comments and strings + + if Match(r'\s*{\s*$', line): + # We allow an open brace to start a line in the case where someone + # is using braces in a block to explicitly create a new scope, + # which is commonly used to control the lifetime of + # stack-allocated variables. We don't detect this perfectly: we + # just don't complain if the last non-whitespace character on the + # previous non-blank line is ';', ':', '{', or '}'. + prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] + if not Search(r'[;:}{]\s*$', prevline): + error(filename, linenum, 'whitespace/braces', 4, + '{ should almost always be at the end of the previous line') + + # An else clause should be on the same line as the preceding closing brace. + if Match(r'\s*else\s*', line): + prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] + if Match(r'\s*}\s*$', prevline): + error(filename, linenum, 'whitespace/newline', 4, + 'An else should appear on the same line as the preceding }') + + # If braces come on one side of an else, they should be on both. + # However, we have to worry about "else if" that spans multiple lines! + if Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line): + if Search(r'}\s*else if([^{]*)$', line): # could be multi-line if + # find the ( after the if + pos = line.find('else if') + pos = line.find('(', pos) + if pos > 0: + (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos) + if endline[endpos:].find('{') == -1: # must be brace after if + error(filename, linenum, 'readability/braces', 5, + 'If an else has a brace on one side, it should have it on both') + else: # common case: else not followed by a multi-line if + error(filename, linenum, 'readability/braces', 5, + 'If an else has a brace on one side, it should have it on both') + + # Likewise, an else should never have the else clause on the same line + if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line): + error(filename, linenum, 'whitespace/newline', 4, + 'Else clause should never be on same line as else (use 2 lines)') + + # In the same way, a do/while should never be on one line + if Match(r'\s*do [^\s{]', line): + error(filename, linenum, 'whitespace/newline', 4, + 'do/while clauses should not be on a single line') + + # Braces shouldn't be followed by a ; unless they're defining a struct + # or initializing an array. + # We can't tell in general, but we can for some common cases. + prevlinenum = linenum + while True: + (prevline, prevlinenum) = GetPreviousNonBlankLine(clean_lines, prevlinenum) + if Match(r'\s+{.*}\s*;', line) and not prevline.count(';'): + line = prevline + line + else: + break + if (Search(r'{.*}\s*;', line) and + line.count('{') == line.count('}') and + not Search(r'struct|class|enum|\s*=\s*{', line)): + error(filename, linenum, 'readability/braces', 4, + "You don't need a ; after a }") + + +def ReplaceableCheck(operator, macro, line): + """Determine whether a basic CHECK can be replaced with a more specific one. + + For example suggest using CHECK_EQ instead of CHECK(a == b) and + similarly for CHECK_GE, CHECK_GT, CHECK_LE, CHECK_LT, CHECK_NE. + + Args: + operator: The C++ operator used in the CHECK. + macro: The CHECK or EXPECT macro being called. + line: The current source line. + + Returns: + True if the CHECK can be replaced with a more specific one. + """ + + # This matches decimal and hex integers, strings, and chars (in that order). + match_constant = r'([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')' + + # Expression to match two sides of the operator with something that + # looks like a literal, since CHECK(x == iterator) won't compile. + # This means we can't catch all the cases where a more specific + # CHECK is possible, but it's less annoying than dealing with + # extraneous warnings. + match_this = (r'\s*' + macro + r'\((\s*' + + match_constant + r'\s*' + operator + r'[^<>].*|' + r'.*[^<>]' + operator + r'\s*' + match_constant + + r'\s*\))') + + # Don't complain about CHECK(x == NULL) or similar because + # CHECK_EQ(x, NULL) won't compile (requires a cast). + # Also, don't complain about more complex boolean expressions + # involving && or || such as CHECK(a == b || c == d). + return Match(match_this, line) and not Search(r'NULL|&&|\|\|', line) + + +def CheckCheck(filename, clean_lines, linenum, error): + """Checks the use of CHECK and EXPECT macros. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + + # Decide the set of replacement macros that should be suggested + raw_lines = clean_lines.raw_lines + current_macro = '' + for macro in _CHECK_MACROS: + if raw_lines[linenum].find(macro) >= 0: + current_macro = macro + break + if not current_macro: + # Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT' + return + + line = clean_lines.elided[linenum] # get rid of comments and strings + + # Encourage replacing plain CHECKs with CHECK_EQ/CHECK_NE/etc. + for operator in ['==', '!=', '>=', '>', '<=', '<']: + if ReplaceableCheck(operator, current_macro, line): + error(filename, linenum, 'readability/check', 2, + 'Consider using %s instead of %s(a %s b)' % ( + _CHECK_REPLACEMENT[current_macro][operator], + current_macro, operator)) + break + + +def GetLineWidth(line): + """Determines the width of the line in column positions. + + Args: + line: A string, which may be a Unicode string. + + Returns: + The width of the line in column positions, accounting for Unicode + combining characters and wide characters. + """ + if isinstance(line, unicode): + width = 0 + for c in unicodedata.normalize('NFC', line): + if unicodedata.east_asian_width(c) in ('W', 'F'): + width += 2 + elif not unicodedata.combining(c): + width += 1 + return width + else: + return len(line) + + +def CheckStyle(filename, clean_lines, linenum, file_extension, error): + """Checks rules from the 'C++ style rules' section of cppguide.html. + + Most of these rules are hard to test (naming, comment style), but we + do what we can. In particular we check for 2-space indents, line lengths, + tab usage, spaces inside code, etc. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + file_extension: The extension (without the dot) of the filename. + error: The function to call with any errors found. + """ + + raw_lines = clean_lines.raw_lines + line = raw_lines[linenum] + + if line.find('\t') != -1: + error(filename, linenum, 'whitespace/tab', 1, + 'Tab found; better to use spaces') + + # One or three blank spaces at the beginning of the line is weird; it's + # hard to reconcile that with 2-space indents. + # NOTE: here are the conditions rob pike used for his tests. Mine aren't + # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces + # if(RLENGTH > 20) complain = 0; + # if(match($0, " +(error|private|public|protected):")) complain = 0; + # if(match(prev, "&& *$")) complain = 0; + # if(match(prev, "\\|\\| *$")) complain = 0; + # if(match(prev, "[\",=><] *$")) complain = 0; + # if(match($0, " <<")) complain = 0; + # if(match(prev, " +for \\(")) complain = 0; + # if(prevodd && match(prevprev, " +for \\(")) complain = 0; + initial_spaces = 0 + cleansed_line = clean_lines.elided[linenum] + while initial_spaces < len(line) and line[initial_spaces] == ' ': + initial_spaces += 1 + if line and line[-1].isspace(): + error(filename, linenum, 'whitespace/end_of_line', 4, + 'Line ends in whitespace. Consider deleting these extra spaces.') + # There are certain situations we allow one space, notably for labels + elif ((initial_spaces == 1 or initial_spaces == 3) and + not Match(r'\s*\w+\s*:\s*$', cleansed_line)): + error(filename, linenum, 'whitespace/indent', 3, + 'Weird number of spaces at line-start. ' + 'Are you using a 2-space indent?') + # Labels should always be indented at least one space. + elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$', + line): + error(filename, linenum, 'whitespace/labels', 4, + 'Labels should always be indented at least one space. ' + 'If this is a member-initializer list in a constructor, ' + 'the colon should be on the line after the definition header.') + + # Check if the line is a header guard. + is_header_guard = False + if file_extension == 'h': + cppvar = GetHeaderGuardCPPVariable(filename) + if (line.startswith('#ifndef %s' % cppvar) or + line.startswith('#define %s' % cppvar) or + line.startswith('#endif // %s' % cppvar)): + is_header_guard = True + # #include lines and header guards can be long, since there's no clean way to + # split them. + if not line.startswith('#include') and not is_header_guard: + line_width = GetLineWidth(line) + if line_width > 100: + error(filename, linenum, 'whitespace/line_length', 4, + 'Lines should very rarely be longer than 100 characters') + elif line_width > 80: + error(filename, linenum, 'whitespace/line_length', 2, + 'Lines should be <= 80 characters long') + + if (cleansed_line.count(';') > 1 and + # for loops are allowed two ;'s (and may run over two lines). + cleansed_line.find('for') == -1 and + (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or + GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and + # It's ok to have many commands in a switch case that fits in 1 line + not ((cleansed_line.find('case ') != -1 or + cleansed_line.find('default:') != -1) and + cleansed_line.find('break;') != -1)): + error(filename, linenum, 'whitespace/newline', 4, + 'More than one command on the same line') + + # Some more style checks + CheckBraces(filename, clean_lines, linenum, error) + CheckSpacing(filename, clean_lines, linenum, error) + CheckCheck(filename, clean_lines, linenum, error) + + +_RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"') +_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') +# Matches the first component of a filename delimited by -s and _s. That is: +# _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo' +# _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo' +# _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo' +# _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo' +_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+') + + +def _DropCommonSuffixes(filename): + """Drops common suffixes like _test.cc or -inl.h from filename. + + For example: + >>> _DropCommonSuffixes('foo/foo-inl.h') + 'foo/foo' + >>> _DropCommonSuffixes('foo/bar/foo.cc') + 'foo/bar/foo' + >>> _DropCommonSuffixes('foo/foo_internal.h') + 'foo/foo' + >>> _DropCommonSuffixes('foo/foo_unusualinternal.h') + 'foo/foo_unusualinternal' + + Args: + filename: The input filename. + + Returns: + The filename with the common suffix removed. + """ + for suffix in ('test.cc', 'regtest.cc', 'unittest.cc', + 'inl.h', 'impl.h', 'internal.h'): + if (filename.endswith(suffix) and len(filename) > len(suffix) and + filename[-len(suffix) - 1] in ('-', '_')): + return filename[:-len(suffix) - 1] + return os.path.splitext(filename)[0] + + +def _IsTestFilename(filename): + """Determines if the given filename has a suffix that identifies it as a test. + + Args: + filename: The input filename. + + Returns: + True if 'filename' looks like a test, False otherwise. + """ + if (filename.endswith('_test.cc') or + filename.endswith('_unittest.cc') or + filename.endswith('_regtest.cc')): + return True + else: + return False + + +def _ClassifyInclude(fileinfo, include, is_system): + """Figures out what kind of header 'include' is. + + Args: + fileinfo: The current file cpplint is running over. A FileInfo instance. + include: The path to a #included file. + is_system: True if the #include used <> rather than "". + + Returns: + One of the _XXX_HEADER constants. + + For example: + >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True) + _C_SYS_HEADER + >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True) + _CPP_SYS_HEADER + >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False) + _LIKELY_MY_HEADER + >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'), + ... 'bar/foo_other_ext.h', False) + _POSSIBLE_MY_HEADER + >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False) + _OTHER_HEADER + """ + # This is a list of all standard c++ header files, except + # those already checked for above. + is_stl_h = include in _STL_HEADERS + is_cpp_h = is_stl_h or include in _CPP_HEADERS + + if is_system: + if is_cpp_h: + return _CPP_SYS_HEADER + else: + return _C_SYS_HEADER + + # If the target file and the include we're checking share a + # basename when we drop common extensions, and the include + # lives in . , then it's likely to be owned by the target file. + target_dir, target_base = ( + os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName()))) + include_dir, include_base = os.path.split(_DropCommonSuffixes(include)) + if target_base == include_base and ( + include_dir == target_dir or + include_dir == os.path.normpath(target_dir + '/../public')): + return _LIKELY_MY_HEADER + + # If the target and include share some initial basename + # component, it's possible the target is implementing the + # include, so it's allowed to be first, but we'll never + # complain if it's not there. + target_first_component = _RE_FIRST_COMPONENT.match(target_base) + include_first_component = _RE_FIRST_COMPONENT.match(include_base) + if (target_first_component and include_first_component and + target_first_component.group(0) == + include_first_component.group(0)): + return _POSSIBLE_MY_HEADER + + return _OTHER_HEADER + + +def CheckLanguage(filename, clean_lines, linenum, file_extension, include_state, + error): + """Checks rules from the 'C++ language rules' section of cppguide.html. + + Some of these rules are hard to test (function overloading, using + uint32 inappropriately), but we do the best we can. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + file_extension: The extension (without the dot) of the filename. + include_state: An _IncludeState instance in which the headers are inserted. + error: The function to call with any errors found. + """ + fileinfo = FileInfo(filename) + + # get rid of comments + comment_elided_line = clean_lines.lines[linenum] + + # "include" should use the new style "foo/bar.h" instead of just "bar.h" + if _RE_PATTERN_INCLUDE_NEW_STYLE.search(comment_elided_line): + error(filename, linenum, 'build/include', 4, + 'Include the directory when naming .h files') + + # we shouldn't include a file more than once. actually, there are a + # handful of instances where doing so is okay, but in general it's + # not. + match = _RE_PATTERN_INCLUDE.search(comment_elided_line) + if match: + include = match.group(2) + is_system = (match.group(1) == '<') + if include in include_state: + error(filename, linenum, 'build/include', 4, + '"%s" already included at %s:%s' % + (include, filename, include_state[include])) + else: + include_state[include] = linenum + + # We want to ensure that headers appear in the right order: + # 1) for foo.cc, foo.h (preferred location) + # 2) c system files + # 3) cpp system files + # 4) for foo.cc, foo.h (deprecated location) + # 5) other google headers + # + # We classify each include statement as one of those 5 types + # using a number of techniques. The include_state object keeps + # track of the highest type seen, and complains if we see a + # lower type after that. + error_message = include_state.CheckNextIncludeOrder( + _ClassifyInclude(fileinfo, include, is_system)) + if error_message: + error(filename, linenum, 'build/include_order', 4, + '%s. Should be: %s.h, c system, c++ system, other.' % + (error_message, fileinfo.BaseName())) + + # If the line is empty or consists of entirely a comment, no need to + # check it. + line = clean_lines.elided[linenum] + if not line: + return + + # Create an extended_line, which is the concatenation of the current and + # next lines, for more effective checking of code that may span more than one + # line. + if linenum + 1 < clean_lines.NumLines(): + extended_line = line + clean_lines.elided[linenum + 1] + else: + extended_line = line + + # Make Windows paths like Unix. + fullname = os.path.abspath(filename).replace('\\', '/') + + # TODO(unknown): figure out if they're using default arguments in fn proto. + + # Look for any of the stream classes that are part of standard C++. + match = _RE_PATTERN_INCLUDE.match(line) + if match: + include = match.group(2) + if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include): + # Many unit tests use cout, so we exempt them. + if not _IsTestFilename(filename): + error(filename, linenum, 'readability/streams', 3, + 'Streams are highly discouraged.') + + # Check for non-const references in functions. This is tricky because & + # is also used to take the address of something. We allow <> for templates, + # (ignoring whatever is between the braces) and : for classes. + # These are complicated re's. They try to capture the following: + # paren (for fn-prototype start), typename, &, varname. For the const + # version, we're willing for const to be before typename or after + # Don't check the implemention on same line. + fnline = line.split('{', 1)[0] + if (len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) > + len(re.findall(r'\([^()]*\bconst\s+(?:typename\s+)?(?:struct\s+)?' + r'(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) + + len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+\s+const(\s?&|&\s?)[\w]+', + fnline))): + + # We allow non-const references in a few standard places, like functions + # called "swap()" or iostream operators like "<<" or ">>". + if not Search( + r'(swap|Swap|operator[<>][<>])\s*\(\s*(?:[\w:]|<.*>)+\s*&', + fnline): + error(filename, linenum, 'runtime/references', 2, + 'Is this a non-const reference? ' + 'If so, make const or use a pointer.') + + # Check to see if they're using an conversion function cast. + # I just try to capture the most common basic types, though there are more. + # Parameterless conversion functions, such as bool(), are allowed as they are + # probably a member operator declaration or default constructor. + match = Search( + r'\b(int|float|double|bool|char|int32|uint32|int64|uint64)\([^)]', line) + if match: + # gMock methods are defined using some variant of MOCK_METHODx(name, type) + # where type may be float(), int(string), etc. Without context they are + # virtually indistinguishable from int(x) casts. + if not Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line): + error(filename, linenum, 'readability/casting', 4, + 'Using deprecated casting style. ' + 'Use static_cast<%s>(...) instead' % + match.group(1)) + + CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], + 'static_cast', + r'\((int|float|double|bool|char|u?int(16|32|64))\)', + error) + # This doesn't catch all cases. Consider (const char * const)"hello". + CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], + 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error) + + # In addition, we look for people taking the address of a cast. This + # is dangerous -- casts can assign to temporaries, so the pointer doesn't + # point where you think. + if Search( + r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line): + error(filename, linenum, 'runtime/casting', 4, + ('Are you taking an address of a cast? ' + 'This is dangerous: could be a temp var. ' + 'Take the address before doing the cast, rather than after')) + + # Check for people declaring static/global STL strings at the top level. + # This is dangerous because the C++ language does not guarantee that + # globals with constructors are initialized before the first access. + match = Match( + r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)', + line) + # Make sure it's not a function. + # Function template specialization looks like: "string foo(...". + # Class template definitions look like: "string Foo::Method(...". + if match and not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)', + match.group(3)): + error(filename, linenum, 'runtime/string', 4, + 'For a static/global string constant, use a C style string instead: ' + '"%schar %s[]".' % + (match.group(1), match.group(2))) + + # Check that we're not using RTTI outside of testing code. + if Search(r'\bdynamic_cast<', line) and not _IsTestFilename(filename): + error(filename, linenum, 'runtime/rtti', 5, + 'Do not use dynamic_cast<>. If you need to cast within a class ' + "hierarchy, use static_cast<> to upcast. Google doesn't support " + 'RTTI.') + + if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line): + error(filename, linenum, 'runtime/init', 4, + 'You seem to be initializing a member variable with itself.') + + if file_extension == 'h': + # TODO(unknown): check that 1-arg constructors are explicit. + # How to tell it's a constructor? + # (handled in CheckForNonStandardConstructs for now) + # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS + # (level 1 error) + pass + + # Check if people are using the verboten C basic types. The only exception + # we regularly allow is "unsigned short port" for port. + if Search(r'\bshort port\b', line): + if not Search(r'\bunsigned short port\b', line): + error(filename, linenum, 'runtime/int', 4, + 'Use "unsigned short" for ports, not "short"') + else: + match = Search(r'\b(short|long(?! +double)|long long)\b', line) + if match: + error(filename, linenum, 'runtime/int', 4, + 'Use int16/int64/etc, rather than the C type %s' % match.group(1)) + + # When snprintf is used, the second argument shouldn't be a literal. + match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) + if match: + error(filename, linenum, 'runtime/printf', 3, + 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' + 'to snprintf.' % (match.group(1), match.group(2))) + + # Check if some verboten C functions are being used. + if Search(r'\bsprintf\b', line): + error(filename, linenum, 'runtime/printf', 5, + 'Never use sprintf. Use snprintf instead.') + match = Search(r'\b(strcpy|strcat)\b', line) + if match: + error(filename, linenum, 'runtime/printf', 4, + 'Almost always, snprintf is better than %s' % match.group(1)) + + if Search(r'\bsscanf\b', line): + error(filename, linenum, 'runtime/printf', 1, + 'sscanf can be ok, but is slow and can overflow buffers.') + + # Check for suspicious usage of "if" like + # } if (a == b) { + if Search(r'\}\s*if\s*\(', line): + error(filename, linenum, 'readability/braces', 4, + 'Did you mean "else if"? If not, start a new line for "if".') + + # Check for potential format string bugs like printf(foo). + # We constrain the pattern not to pick things like DocidForPrintf(foo). + # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str()) + match = re.search(r'\b((?:string)?printf)\s*\(([\w.\->()]+)\)', line, re.I) + if match: + error(filename, linenum, 'runtime/printf', 4, + 'Potential format string bug. Do %s("%%s", %s) instead.' + % (match.group(1), match.group(2))) + + # Check for potential memset bugs like memset(buf, sizeof(buf), 0). + match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line) + if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)): + error(filename, linenum, 'runtime/memset', 4, + 'Did you mean "memset(%s, 0, %s)"?' + % (match.group(1), match.group(2))) + + if Search(r'\busing namespace\b', line): + error(filename, linenum, 'build/namespaces', 5, + 'Do not use namespace using-directives. ' + 'Use using-declarations instead.') + + # Detect variable-length arrays. + match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line) + if (match and match.group(2) != 'return' and match.group(2) != 'delete' and + match.group(3).find(']') == -1): + # Split the size using space and arithmetic operators as delimiters. + # If any of the resulting tokens are not compile time constants then + # report the error. + tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3)) + is_const = True + skip_next = False + for tok in tokens: + if skip_next: + skip_next = False + continue + + if Search(r'sizeof\(.+\)', tok): continue + if Search(r'arraysize\(\w+\)', tok): continue + + tok = tok.lstrip('(') + tok = tok.rstrip(')') + if not tok: continue + if Match(r'\d+', tok): continue + if Match(r'0[xX][0-9a-fA-F]+', tok): continue + if Match(r'k[A-Z0-9]\w*', tok): continue + if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue + if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue + # A catch all for tricky sizeof cases, including 'sizeof expression', + # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)' + # requires skipping the next token becasue we split on ' ' and '*'. + if tok.startswith('sizeof'): + skip_next = True + continue + is_const = False + break + if not is_const: + error(filename, linenum, 'runtime/arrays', 1, + 'Do not use variable-length arrays. Use an appropriately named ' + "('k' followed by CamelCase) compile-time constant for the size.") + + # If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or + # DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing + # in the class declaration. + match = Match( + (r'\s*' + r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))' + r'\(.*\);$'), + line) + if match and linenum + 1 < clean_lines.NumLines(): + next_line = clean_lines.elided[linenum + 1] + if not Search(r'^\s*};', next_line): + error(filename, linenum, 'readability/constructors', 3, + match.group(1) + ' should be the last thing in the class') + + # Check for use of unnamed namespaces in header files. Registration + # macros are typically OK, so we allow use of "namespace {" on lines + # that end with backslashes. + if (file_extension == 'h' + and Search(r'\bnamespace\s*{', line) + and line[-1] != '\\'): + error(filename, linenum, 'build/namespaces', 4, + 'Do not use unnamed namespaces in header files. See ' + 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces' + ' for more information.') + + +def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern, + error): + """Checks for a C-style cast by looking for the pattern. + + This also handles sizeof(type) warnings, due to similarity of content. + + Args: + filename: The name of the current file. + linenum: The number of the line to check. + line: The line of code to check. + raw_line: The raw line of code to check, with comments. + cast_type: The string for the C++ cast to recommend. This is either + reinterpret_cast or static_cast, depending. + pattern: The regular expression used to find C-style casts. + error: The function to call with any errors found. + """ + match = Search(pattern, line) + if not match: + return + + # e.g., sizeof(int) + sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1]) + if sizeof_match: + error(filename, linenum, 'runtime/sizeof', 1, + 'Using sizeof(type). Use sizeof(varname) instead if possible') + return + + remainder = line[match.end(0):] + + # The close paren is for function pointers as arguments to a function. + # eg, void foo(void (*bar)(int)); + # The semicolon check is a more basic function check; also possibly a + # function pointer typedef. + # eg, void foo(int); or void foo(int) const; + # The equals check is for function pointer assignment. + # eg, void *(*foo)(int) = ... + # + # Right now, this will only catch cases where there's a single argument, and + # it's unnamed. It should probably be expanded to check for multiple + # arguments with some unnamed. + function_match = Match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)))', remainder) + if function_match: + if (not function_match.group(3) or + function_match.group(3) == ';' or + raw_line.find('/*') < 0): + error(filename, linenum, 'readability/function', 3, + 'All parameters should be named in a function') + return + + # At this point, all that should be left is actual casts. + error(filename, linenum, 'readability/casting', 4, + 'Using C-style cast. Use %s<%s>(...) instead' % + (cast_type, match.group(1))) + + +_HEADERS_CONTAINING_TEMPLATES = ( + ('', ('deque',)), + ('', ('unary_function', 'binary_function', + 'plus', 'minus', 'multiplies', 'divides', 'modulus', + 'negate', + 'equal_to', 'not_equal_to', 'greater', 'less', + 'greater_equal', 'less_equal', + 'logical_and', 'logical_or', 'logical_not', + 'unary_negate', 'not1', 'binary_negate', 'not2', + 'bind1st', 'bind2nd', + 'pointer_to_unary_function', + 'pointer_to_binary_function', + 'ptr_fun', + 'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t', + 'mem_fun_ref_t', + 'const_mem_fun_t', 'const_mem_fun1_t', + 'const_mem_fun_ref_t', 'const_mem_fun1_ref_t', + 'mem_fun_ref', + )), + ('', ('numeric_limits',)), + ('', ('list',)), + ('', ('map', 'multimap',)), + ('', ('allocator',)), + ('', ('queue', 'priority_queue',)), + ('', ('set', 'multiset',)), + ('', ('stack',)), + ('', ('char_traits', 'basic_string',)), + ('', ('pair',)), + ('', ('vector',)), + + # gcc extensions. + # Note: std::hash is their hash, ::hash is our hash + ('', ('hash_map', 'hash_multimap',)), + ('', ('hash_set', 'hash_multiset',)), + ('', ('slist',)), + ) + +_HEADERS_ACCEPTED_BUT_NOT_PROMOTED = { + # We can trust with reasonable confidence that map gives us pair<>, too. + 'pair<>': ('map', 'multimap', 'hash_map', 'hash_multimap') +} + +_RE_PATTERN_STRING = re.compile(r'\bstring\b') + +_re_pattern_algorithm_header = [] +for _template in ('copy', 'max', 'min', 'sort', 'swap'): + # Match max(..., ...), max(..., ...), but not foo->max, foo.max or + # type::max(). + _re_pattern_algorithm_header.append( + (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'), + _template, + '')) + +_re_pattern_templates = [] +for _header, _templates in _HEADERS_CONTAINING_TEMPLATES: + for _template in _templates: + _re_pattern_templates.append( + (re.compile(r'(\<|\b)' + _template + r'\s*\<'), + _template + '<>', + _header)) + + +def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error): + """Reports for missing stl includes. + + This function will output warnings to make sure you are including the headers + necessary for the stl containers and functions that you use. We only give one + reason to include a header. For example, if you use both equal_to<> and + less<> in a .h file, only one (the latter in the file) of these will be + reported as a reason to include the . + + We only check headers. We do not check inside cc-files. .cc files should be + able to depend on their respective header files for includes. However, there + is no simple way of producing this logic here. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + include_state: An _IncludeState instance. + error: The function to call with any errors found. + """ + if filename.endswith('.cc'): + return + + required = {} # A map of header name to linenumber and the template entity. + # Example of required: { '': (1219, 'less<>') } + + for linenum in xrange(clean_lines.NumLines()): + line = clean_lines.elided[linenum] + if not line or line[0] == '#': + continue + + # String is special -- it is a non-templatized type in STL. + if _RE_PATTERN_STRING.search(line): + required[''] = (linenum, 'string') + + for pattern, template, header in _re_pattern_algorithm_header: + if pattern.search(line): + required[header] = (linenum, template) + + # The following function is just a speed up, no semantics are changed. + if not '<' in line: # Reduces the cpu time usage by skipping lines. + continue + + for pattern, template, header in _re_pattern_templates: + if pattern.search(line): + required[header] = (linenum, template) + + # All the lines have been processed, report the errors found. + for required_header_unstripped in required: + template = required[required_header_unstripped][1] + if template in _HEADERS_ACCEPTED_BUT_NOT_PROMOTED: + headers = _HEADERS_ACCEPTED_BUT_NOT_PROMOTED[template] + if [True for header in headers if header in include_state]: + continue + if required_header_unstripped.strip('<>"') not in include_state: + error(filename, required[required_header_unstripped][0], + 'build/include_what_you_use', 4, + 'Add #include ' + required_header_unstripped + ' for ' + template) + + +def ProcessLine(filename, file_extension, + clean_lines, line, include_state, function_state, + class_state, error): + """Processes a single line in the file. + + Args: + filename: Filename of the file that is being processed. + file_extension: The extension (dot not included) of the file. + clean_lines: An array of strings, each representing a line of the file, + with comments stripped. + line: Number of line being processed. + include_state: An _IncludeState instance in which the headers are inserted. + function_state: A _FunctionState instance which counts function lines, etc. + class_state: A _ClassState instance which maintains information about + the current stack of nested class declarations being parsed. + error: A callable to which errors are reported, which takes 4 arguments: + filename, line number, error level, and message + + """ + raw_lines = clean_lines.raw_lines + CheckForFunctionLengths(filename, clean_lines, line, function_state, error) + if Search(r'\bNOLINT\b', raw_lines[line]): # ignore nolint lines + return + CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) + CheckStyle(filename, clean_lines, line, file_extension, error) + CheckLanguage(filename, clean_lines, line, file_extension, include_state, + error) + CheckForNonStandardConstructs(filename, clean_lines, line, + class_state, error) + CheckPosixThreading(filename, clean_lines, line, error) + + +def ProcessFileData(filename, file_extension, lines, error): + """Performs lint checks and reports any errors to the given error function. + + Args: + filename: Filename of the file that is being processed. + file_extension: The extension (dot not included) of the file. + lines: An array of strings, each representing a line of the file, with the + last element being empty if the file is termined with a newline. + error: A callable to which errors are reported, which takes 4 arguments: + """ + lines = (['// marker so line numbers and indices both start at 1'] + lines + + ['// marker so line numbers end in a known way']) + + include_state = _IncludeState() + function_state = _FunctionState() + class_state = _ClassState() + + CheckForCopyright(filename, lines, error) + + if file_extension == 'h': + CheckForHeaderGuard(filename, lines, error) + + RemoveMultiLineComments(filename, lines, error) + clean_lines = CleansedLines(lines) + for line in xrange(clean_lines.NumLines()): + ProcessLine(filename, file_extension, clean_lines, line, + include_state, function_state, class_state, error) + class_state.CheckFinished(filename, error) + + CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) + + # We check here rather than inside ProcessLine so that we see raw + # lines rather than "cleaned" lines. + CheckForUnicodeReplacementCharacters(filename, lines, error) + + CheckForNewlineAtEOF(filename, lines, error) + + +def ProcessFile(filename, vlevel): + """Does google-lint on a single file. + + Args: + filename: The name of the file to parse. + + vlevel: The level of errors to report. Every error of confidence + >= verbose_level will be reported. 0 is a good default. + """ + + _SetVerboseLevel(vlevel) + + try: + # Support the UNIX convention of using "-" for stdin. Note that + # we are not opening the file with universal newline support + # (which codecs doesn't support anyway), so the resulting lines do + # contain trailing '\r' characters if we are reading a file that + # has CRLF endings. + # If after the split a trailing '\r' is present, it is removed + # below. If it is not expected to be present (i.e. os.linesep != + # '\r\n' as in Windows), a warning is issued below if this file + # is processed. + + if filename == '-': + lines = codecs.StreamReaderWriter(sys.stdin, + codecs.getreader('utf8'), + codecs.getwriter('utf8'), + 'replace').read().split('\n') + else: + lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n') + + carriage_return_found = False + # Remove trailing '\r'. + for linenum in range(len(lines)): + if lines[linenum].endswith('\r'): + lines[linenum] = lines[linenum].rstrip('\r') + carriage_return_found = True + + except IOError: + sys.stderr.write( + "Skipping input '%s': Can't open for reading\n" % filename) + return + + # Note, if no dot is found, this will give the entire filename as the ext. + file_extension = filename[filename.rfind('.') + 1:] + + # When reading from stdin, the extension is unknown, so no cpplint tests + # should rely on the extension. + if (filename != '-' and file_extension != 'cc' and file_extension != 'h' + and file_extension != 'cpp'): + sys.stderr.write('Ignoring %s; not a .cc or .h file\n' % filename) + else: + ProcessFileData(filename, file_extension, lines, Error) + if carriage_return_found and os.linesep != '\r\n': + # Use 0 for linenum since outputing only one error for potentially + # several lines. + Error(filename, 0, 'whitespace/newline', 1, + 'One or more unexpected \\r (^M) found;' + 'better to use only a \\n') + + sys.stderr.write('Done processing %s\n' % filename) + + +def PrintUsage(message): + """Prints a brief usage string and exits, optionally with an error message. + + Args: + message: The optional error message. + """ + sys.stderr.write(_USAGE) + if message: + sys.exit('\nFATAL ERROR: ' + message) + else: + sys.exit(1) + + +def PrintCategories(): + """Prints a list of all the error-categories used by error messages. + + These are the categories used to filter messages via --filter. + """ + sys.stderr.write(_ERROR_CATEGORIES) + sys.exit(0) + + +def ParseArguments(args): + """Parses the command line arguments. + + This may set the output format and verbosity level as side-effects. + + Args: + args: The command line arguments: + + Returns: + The list of filenames to lint. + """ + try: + (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=', + 'filter=']) + except getopt.GetoptError: + PrintUsage('Invalid arguments.') + + verbosity = _VerboseLevel() + output_format = _OutputFormat() + filters = '' + + for (opt, val) in opts: + if opt == '--help': + PrintUsage(None) + elif opt == '--output': + if not val in ('emacs', 'vs7'): + PrintUsage('The only allowed output formats are emacs and vs7.') + output_format = val + elif opt == '--verbose': + verbosity = int(val) + elif opt == '--filter': + filters = val + if filters == '': + PrintCategories() + + if not filenames: + PrintUsage('No files were specified.') + + _SetOutputFormat(output_format) + _SetVerboseLevel(verbosity) + _SetFilters(filters) + + return filenames + + +def main(): + filenames = ParseArguments(sys.argv[1:]) + + # Change stderr to write with replacement characters so we don't die + # if we try to print something containing non-ASCII characters. + sys.stderr = codecs.StreamReaderWriter(sys.stderr, + codecs.getreader('utf8'), + codecs.getwriter('utf8'), + 'replace') + + _cpplint_state.ResetErrorCount() + for filename in filenames: + ProcessFile(filename, _cpplint_state.verbose_level) + sys.stderr.write('Total errors found: %d\n' % _cpplint_state.error_count) + sys.exit(_cpplint_state.error_count > 0) + + +if __name__ == '__main__': + main() diff --git a/bin/protoc-gen-pbrpc b/bin/protoc-gen-pbrpc new file mode 100755 index 0000000..75ba193 --- /dev/null +++ b/bin/protoc-gen-pbrpc @@ -0,0 +1,4 @@ +#!/bin/bash +FULLPATH=`readlink -f $0` +BASEDIR=`dirname ${FULLPATH}` +java -cp ${BASEDIR}/../java/pbrpcgen/dist/pbrpcgen.jar:${BASEDIR}/../java/lib/protobuf-java-2.5.0.jar org.xtreemfs.pbrpcgen.RPCSourceGenerator diff --git a/bin/protoc-gen-pbrpccpp b/bin/protoc-gen-pbrpccpp new file mode 100755 index 0000000..44a8aaf --- /dev/null +++ b/bin/protoc-gen-pbrpccpp @@ -0,0 +1,4 @@ +#!/bin/bash +FULLPATH=`readlink -f $0` +BASEDIR=`dirname ${FULLPATH}` +java -cp ${BASEDIR}/../java/pbrpcgen/dist/pbrpcgen.jar:${BASEDIR}/../java/lib/protobuf-java-2.5.0.jar org.xtreemfs.pbrpcgen.RPCCPPSourceGenerator diff --git a/bin/toggle_jcip_annnotations.sh b/bin/toggle_jcip_annnotations.sh new file mode 100755 index 0000000..25b4364 --- /dev/null +++ b/bin/toggle_jcip_annnotations.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin +# +# Licensed under the BSD License, see LICENSE file for details. +# +# This file is only used for developers of the Java code. +# It allows to comment and uncomment the JCIP annotations (http://www.jcip.net/). +# +# If JCIP annotations are enabled, the jcip-annotations.jar is required for +# compiling and running the XtreemFS code. However, we do not want to package +# it as part of binary packages. Therefore, this script is used to comment +# the annotations in the code. We do not delete the annotations from the code +# since we want to keep them as documentation - even if currently (Feb 2012) +# there is no tool available to evaluate them. + +function display_usage() { + cat < Comments all JCIP annotations found in .java files in path +-u Uncomments all JCIP annotations found in .java files in path +EOF +} + +if [ -z "$1" ] +then + display_usage + exit 1 +fi + +while getopts ":hc:u:" opt +do + case $opt in + c) + mode="comment" + path="$OPTARG" + ;; + u) + mode="uncomment" + path="$OPTARG" + ;; + h) + display_usage + exit 1 + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + :) + echo "Option -$OPTARG requires a path as an argument." >&2 + exit 1 + ;; + esac +done + +if [ -z "$mode" ] +then + echo "Error: Run with -c or -u ." + exit 1 +fi + +if [ ! "$path" ] +then + echo "Error: The given path \"$path\" does not exist." + exit 1 +fi + +comment_prefix="\/\/ JCIP " +if [ "$mode" = "comment" ] +then +# find "$path" -iname "*.java" -exec sed -r -i -e "s/^([^\/][^\/].*@(GuardedBy|Immutable|NotThreadSafe|ThreadSafe).*)$/$comment_prefix\1/" {} \; + find "$path" -iname "*.java" -exec sed -r -i -e "s/^([^\/][^\/].*(@|net\.jcip\.annotations\.)(GuardedBy|Immutable|NotThreadSafe|ThreadSafe).*)$/$comment_prefix\1/" {} \; +else + find "$path" -iname "*.java" -exec sed -r -i -e "s/^$comment_prefix([^\/][^\/].*(@|net\.jcip\.annotations\.)(GuardedBy|Immutable|NotThreadSafe|ThreadSafe).*)$/\1/" {} \; +fi \ No newline at end of file diff --git a/bin/umount.xtreemfs b/bin/umount.xtreemfs new file mode 100755 index 0000000..b0f8061 --- /dev/null +++ b/bin/umount.xtreemfs @@ -0,0 +1,12 @@ +#!/bin/bash +# a simple wrapper around fusermount -u, now passes all args to fusermount + +if [ "x$1" == "x" -o "$1" == "--help" -o "$1" == "-h" ] +then + echo "usage: umount.xtreemfs " + echo "" + exit 1 +fi + +fusermount -u $@ +exit $? diff --git a/bin/xtfs_benchmark b/bin/xtfs_benchmark new file mode 100755 index 0000000..de7c21e --- /dev/null +++ b/bin/xtfs_benchmark @@ -0,0 +1,54 @@ +#!/bin/bash + +check_xtreemfs() { + if [ -z "$XTREEMFS" ]; then + if [ -d java -a -d cpp -a -d etc ]; then + #echo "Looks like you are in an XtreemFS base directory..." + XTREEMFS=`pwd` + elif [ -d ../java -a -d ../cpp -a -d ../etc ]; then + #echo "XTREEMFS base could be the parent directory..." + XTREEMFS=`pwd`/.. + fi + fi + if [ ! -e "$XTREEMFS/java/servers/dist/XtreemFS.jar" -a ! -d "$XTREEMFS/java/lib" -a ! -f "/usr/share/java/XtreemFS.jar" ]; + then + echo "XtreemFS jar could not be found!" + exit 1 + fi +} + +check_java() { + if [ -z "$JAVA_HOME" -a ! -f "/usr/bin/java" ]; then + echo "\$JAVA_HOME not set, JDK/JRE 1.6 required" + exit 1 + fi + + if [ -z "$JAVA_HOME" ]; then + JAVA_HOME=/usr + fi + + JVERS=`$JAVA_HOME/bin/java -version 2>&1 | grep "java version" | \ + cut -d " " -f 3` + test "$JVERS" \> "\"1.6.0" + if [ $? -eq 1 ]; then + echo "Java version is $JVERS. You need JAVA 1.6!!!" + exit 1 + fi + + #echo "Java version $JVERS found under $JAVA_HOME" +} + + +check_xtreemfs +check_java + + + +# exec $JAVA_HOME/bin/java -Dcom.sun.sdp.conf=$XTREEMFS/sdp.conf -Dcom.sun.sdp.debug=sdp.log -Djava.net.preferIPv4Stack=true -ea -cp $XTREEMFS/java/servers/dist/XtreemFS.jar:$XTREEMFS/java/foundation/dist/Foundation.jar:$XTREEMFS/java/lib/*:/usr/share/java/XtreemFS.jar:/usr/share/java/protobuf-java-2.3.0.jar:/usr/share/java/Foundation.jar:. \ + # org.xtreemfs.utils.xtfs_benchmark.xtfs_benchmark $* + +exec $JAVA_HOME/bin/java -ea -cp $XTREEMFS/java/servers/dist/XtreemFS.jar:$XTREEMFS/java/foundation/dist/Foundation.jar:$XTREEMFS/java/lib/*:/usr/share/java/XtreemFS.jar:/usr/share/java/protobuf-java-2.3.0.jar:/usr/share/java/Foundation.jar:. \ + org.xtreemfs.utils.xtfs_benchmark.xtfs_benchmark $* + +# exec $JAVA_HOME/bin/java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=3128 -ea -cp $XTREEMFS/java/servers/dist/XtreemFS.jar:$XTREEMFS/java/foundation/dist/Foundation.jar:$XTREEMFS/java/lib/*:/usr/share/java/XtreemFS.jar:/usr/share/java/protobuf-java-2.3.0.jar:/usr/share/java/Foundation.jar:. \ + # org.xtreemfs.utils.xtfs_benchmark.xtfs_benchmark $* diff --git a/bin/xtfs_chstatus b/bin/xtfs_chstatus new file mode 100755 index 0000000..d269100 --- /dev/null +++ b/bin/xtfs_chstatus @@ -0,0 +1,46 @@ +#!/bin/bash + +check_xtreemfs() { + if [ -z "$XTREEMFS" ]; then + if [ -d java -a -d cpp -a -d etc ]; then + #echo "Looks like you are in an XtreemFS base directory..." + XTREEMFS=`pwd` + elif [ -d ../java -a -d ../cpp -a -d ../etc ]; then + #echo "XTREEMFS base could be the parent directory..." + XTREEMFS=`pwd`/.. + fi + fi + if [ ! -e "$XTREEMFS/java/servers/dist/XtreemFS.jar" -a ! -d "$XTREEMFS/java/lib" -a ! -f "/usr/share/java/XtreemFS.jar" ]; + then + echo "XtreemFS jar could not be found!" + exit 1 + fi +} + +check_java() { + if [ -z "$JAVA_HOME" -a ! -f "/usr/bin/java" ]; then + echo "\$JAVA_HOME not set, JDK/JRE 1.6 required" + exit 1 + fi + + if [ -z "$JAVA_HOME" ]; then + JAVA_HOME=/usr + fi + + JVERS=`$JAVA_HOME/bin/java -version 2>&1 | grep "java version" | \ + cut -d " " -f 3` + test "$JVERS" \> "\"1.6.0" + if [ $? -eq 1 ]; then + echo "Java version is $JVERS. You need JAVA 1.6!!!" + exit 1 + fi + + #echo "Java version $JVERS found under $JAVA_HOME" +} + + +check_xtreemfs +check_java + +exec $JAVA_HOME/bin/java -ea -cp $XTREEMFS/java/servers/dist/XtreemFS.jar:$XTREEMFS/java/foundation/dist/Foundation.jar:$XTREEMFS/java/lib/*:/usr/share/java/XtreemFS.jar:/usr/share/java/protobuf-java-2.5.0.jar:/usr/share/java/Foundation.jar:. \ + org.xtreemfs.utils.xtfs_chstatus $* diff --git a/bin/xtfs_cleanup b/bin/xtfs_cleanup new file mode 100755 index 0000000..2ca3013 --- /dev/null +++ b/bin/xtfs_cleanup @@ -0,0 +1,46 @@ +#!/bin/bash + +check_xtreemfs() { + if [ -z "$XTREEMFS" ]; then + if [ -d java -a -d cpp -a -d etc ]; then + #echo "Looks like you are in an XtreemFS base directory..." + XTREEMFS=`pwd` + elif [ -d ../java -a -d ../cpp -a -d ../etc ]; then + #echo "XTREEMFS base could be the parent directory..." + XTREEMFS=`pwd`/.. + fi + fi + if [ ! -e "$XTREEMFS/java/servers/dist/XtreemFS.jar" -a ! -d "$XTREEMFS/java/lib" -a ! -f "/usr/share/java/XtreemFS.jar" ]; + then + echo "XtreemFS jar could not be found!" + exit 1 + fi +} + +check_java() { + if [ -z "$JAVA_HOME" -a ! -f "/usr/bin/java" ]; then + echo "\$JAVA_HOME not set, JDK/JRE 1.6 required" + exit 1 + fi + + if [ -z "$JAVA_HOME" ]; then + JAVA_HOME=/usr + fi + + JVERS=`$JAVA_HOME/bin/java -version 2>&1 | grep "java version" | \ + cut -d " " -f 3` + test "$JVERS" \> "\"1.6.0" + if [ $? -eq 1 ]; then + echo "Java version is $JVERS. You need JAVA 1.6!!!" + exit 1 + fi + + #echo "Java version $JVERS found under $JAVA_HOME" +} + + +check_xtreemfs +check_java + +exec $JAVA_HOME/bin/java -ea -cp $XTREEMFS/java/servers/dist/XtreemFS.jar:$XTREEMFS/java/foundation/dist/Foundation.jar:$XTREEMFS/java/lib/*:/usr/share/java/XtreemFS.jar:/usr/share/java/protobuf-java-2.5.0.jar:/usr/share/java/Foundation.jar:. \ + org.xtreemfs.utils.xtfs_cleanup_osd $* diff --git a/bin/xtfs_mrcdbtool b/bin/xtfs_mrcdbtool new file mode 100755 index 0000000..7a5502f --- /dev/null +++ b/bin/xtfs_mrcdbtool @@ -0,0 +1,46 @@ +#!/bin/bash + +check_xtreemfs() { + if [ -z "$XTREEMFS" ]; then + if [ -d java -a -d cpp -a -d etc ]; then + #echo "Looks like you are in an XtreemFS base directory..." + XTREEMFS=`pwd` + elif [ -d ../java -a -d ../cpp -a -d ../etc ]; then + #echo "XTREEMFS base could be the parent directory..." + XTREEMFS=`pwd`/.. + fi + fi + if [ ! -e "$XTREEMFS/java/servers/dist/XtreemFS.jar" -a ! -d "$XTREEMFS/java/lib" -a ! -f "/usr/share/java/XtreemFS.jar" ]; + then + echo "XtreemFS jar could not be found!" + exit 1 + fi +} + +check_java() { + if [ -z "$JAVA_HOME" -a ! -f "/usr/bin/java" ]; then + echo "\$JAVA_HOME not set, JDK/JRE 1.6 required" + exit 1 + fi + + if [ -z "$JAVA_HOME" ]; then + JAVA_HOME=/usr + fi + + JVERS=`$JAVA_HOME/bin/java -version 2>&1 | grep "java version" | \ + cut -d " " -f 3` + test "$JVERS" \> "\"1.6.0" + if [ $? -eq 1 ]; then + echo "Java version is $JVERS. You need JAVA 1.6!!!" + exit 1 + fi + + #echo "Java version $JVERS found under $JAVA_HOME" +} + + +check_xtreemfs +check_java + +exec $JAVA_HOME/bin/java -ea -cp $XTREEMFS/java/servers/dist/XtreemFS.jar:$XTREEMFS/java/foundation/dist/Foundation.jar:$XTREEMFS/java/lib/*:/usr/share/java/XtreemFS.jar:/usr/share/java/protobuf-java-2.5.0.jar:/usr/share/java/Foundation.jar:. \ + org.xtreemfs.utils.xtfs_mrcdbtool $* diff --git a/bin/xtfs_remove_osd b/bin/xtfs_remove_osd new file mode 100755 index 0000000..e68f193 --- /dev/null +++ b/bin/xtfs_remove_osd @@ -0,0 +1,46 @@ +#!/bin/bash + +check_xtreemfs() { + if [ -z "$XTREEMFS" ]; then + if [ -d java -a -d cpp -a -d etc ]; then + #echo "Looks like you are in an XtreemFS base directory..." + XTREEMFS=`pwd` + elif [ -d ../java -a -d ../cpp -a -d ../etc ]; then + #echo "XTREEMFS base could be the parent directory..." + XTREEMFS=`pwd`/.. + fi + fi + if [ ! -e "$XTREEMFS/java/servers/dist/XtreemFS.jar" -a ! -d "$XTREEMFS/java/lib" -a ! -f "/usr/share/java/XtreemFS.jar" ]; + then + echo "XtreemFS jar could not be found!" + exit 1 + fi +} + +check_java() { + if [ -z "$JAVA_HOME" -a ! -f "/usr/bin/java" ]; then + echo "\$JAVA_HOME not set, JDK/JRE 1.6 required" + exit 1 + fi + + if [ -z "$JAVA_HOME" ]; then + JAVA_HOME=/usr + fi + + JVERS=`$JAVA_HOME/bin/java -version 2>&1 | grep "java version" | \ + cut -d " " -f 3` + test "$JVERS" \> "\"1.6.0" + if [ $? -eq 1 ]; then + echo "Java version is $JVERS. You need JAVA 1.6!!!" + exit 1 + fi + + #echo "Java version $JVERS found under $JAVA_HOME" +} + + +check_xtreemfs +check_java + +exec $JAVA_HOME/bin/java -ea -cp $XTREEMFS/java/servers/dist/XtreemFS.jar:$XTREEMFS/java/foundation/dist/Foundation.jar:$XTREEMFS/java/lib/*:/usr/share/java/XtreemFS.jar:/usr/share/java/protobuf-java-2.5.0.jar:/usr/share/java/Foundation.jar:. \ + org.xtreemfs.utils.xtfs_remove_osd $* diff --git a/bin/xtfs_scrub b/bin/xtfs_scrub new file mode 100755 index 0000000..718319c --- /dev/null +++ b/bin/xtfs_scrub @@ -0,0 +1,46 @@ +#!/bin/bash + +check_xtreemfs() { + if [ -z "$XTREEMFS" ]; then + if [ -d java -a -d cpp -a -d etc ]; then + #echo "Looks like you are in an XtreemFS base directory..." + XTREEMFS=`pwd` + elif [ -d ../java -a -d ../cpp -a -d ../etc ]; then + #echo "XTREEMFS base could be the parent directory..." + XTREEMFS=`pwd`/.. + fi + fi + if [ ! -e "$XTREEMFS/java/servers/dist/XtreemFS.jar" -a ! -d "$XTREEMFS/java/lib" -a ! -f "/usr/share/java/XtreemFS.jar" ]; + then + echo "XtreemFS jar could not be found!" + exit 1 + fi +} + +check_java() { + if [ -z "$JAVA_HOME" -a ! -f "/usr/bin/java" ]; then + echo "\$JAVA_HOME not set, JDK/JRE 1.6 required" + exit 1 + fi + + if [ -z "$JAVA_HOME" ]; then + JAVA_HOME=/usr + fi + + JVERS=`$JAVA_HOME/bin/java -version 2>&1 | grep "java version" | \ + cut -d " " -f 3` + test "$JVERS" \> "\"1.6.0" + if [ $? -eq 1 ]; then + echo "Java version is $JVERS. You need JAVA 1.6!!!" + exit 1 + fi + + #echo "Java version $JVERS found under $JAVA_HOME" +} + + +check_xtreemfs +check_java + +exec $JAVA_HOME/bin/java -ea -cp $XTREEMFS/java/servers/dist/XtreemFS.jar:$XTREEMFS/java/foundation/dist/Foundation.jar:$XTREEMFS/java/lib/*:/usr/share/java/XtreemFS.jar:/usr/share/java/protobuf-java-2.5.0.jar:/usr/share/java/Foundation.jar:. \ + org.xtreemfs.utils.xtfs_scrub.xtfs_scrub $* diff --git a/contrib/benchmark/benchmark.sh b/contrib/benchmark/benchmark.sh new file mode 100755 index 0000000..db617e4 --- /dev/null +++ b/contrib/benchmark/benchmark.sh @@ -0,0 +1,403 @@ +#!/bin/bash + +# the timeout for one execution of xtfs_benchmark +TIMEOUT=1500 + +# the timeout for one cleanup +TIMEOUT_CLEANUP=300 + +# the time to sleep after a cleanup +SLEEPTIME=600 + +# if false, the script will not sleep after a cleanup and after drop_caches +# (-v will set false) +SLEEP=true + +# the size of the basefile for random benchmarks +BASEFILE_SIZE="100g" + +# the directories for the logfiles and the results +LOG_BASE=${BENCH_LOG:-$HOME} +LOG_DIR="$LOG_BASE/log" +RESULT_DIR="$LOG_BASE/result" + +# Drops caches after each benchmark. Uncomment to activate +# cp "drop_caches" to "/usr/local/bin" and add "ALL ALL=NOPASSWD: /usr/local/bin/drop_caches" to sudoers file +DROP_CACHES=${BENCH_DROP_CACHES:-"/usr/local/bin/drop_caches"} +if [[ $DROP_CACHES != "false" ]]; then + DROP_CACHES_CALL="sudo ${DROP_CACHES}" +fi + +# IP and Port of the DIR +DIR=${BENCH_DIR:-"localhost:32638"} + +# IP and Port of the MRC +MRC=${BENCH_MRC:-"localhost:32636"} + +# space separed list of OSD_UUIDS, e.g. "osd1 osd2 ..." +OSD_UUIDS=${BENCH_OSD_UUIDS:-"test-osd0"} + +# stripe size for a volume +STRIPE_SIZE="128K" + +# request size for each I/O operation +REQUEST_SIZE=$STRIPE_SIZE + +# replication settings +REPLICATION_POLICY="" +REPLICATION_FACTOR=1 + +check_env(){ + # check XTREEMFS + if [ -z "$XTREEMFS" ]; then + if [ -d java -a -d cpp -a -d etc ]; then + #echo "Looks like you are in an XtreemFS base directory..." + XTREEMFS=`pwd` + elif [ -d ../java -a -d ../cpp -a -d ../etc ]; then + #echo "XTREEMFS base could be the parent directory..." + XTREEMFS=`pwd`/.. + fi + fi + if [ ! -e "$XTREEMFS/java/servers/dist/XtreemFS.jar" -a ! -d "$XTREEMFS/java/lib" -a ! -f "/usr/share/java/XtreemFS.jar" ]; + then + echo "XtreemFS jar could not be found!" + exit 1 + fi + + # check JAVA_HOME + if [ -z "$JAVA_HOME" -a ! -f "/usr/bin/java" ]; then + echo "\$JAVA_HOME not set, JDK/JRE 1.6 required" + exit 1 + fi + + if [ -z "$JAVA_HOME" ]; then + JAVA_HOME=/usr + fi + +} + +printUsage() { + cat << EOF + +Synopsis + $(basename $0) -t TYPE -s NUMBER [-x NUMBER] [-p POLICY -f NUMBER] [-b NUMBER -e NUMBER] [-r NUMBER] [-v] + Run a XtreemFS benchmark series, i.e. a series of benchmarks with increasing + numbers of threads. Logs are placed in \$HOME/log/, results in \$HOME/results + (can be changed at the head of the script). + + -t type + Type of benchmarks to run. Type can be either of the following: + sw sequential write + usw unaligned sequential write + sr sequential read + rw random write + rr random read + + -s size + Size of one benchmark, modifier K (for KiB), M (for MiB) or G (for GiB) is mandatory. + + -c size + Size of each read/write request, modifier K (for KiB), M (for MiB) or G (for GiB) is mandatory. + Defaults to 128K. + + -i size + Stripe size for each volume, modifier K (for KiB), M (for MiB) or G (for GiB) is mandatory. + Defaults to 128K. + + -p policy + Replication policy to use. Defaults to none. + + -f factor + Replication factor to use. Defaults to 1. + + -b number of threads to beginn the benchmark series + Minimum number of threads to be run as the benchmarks series. + The series will run benchmarks between the 'begin' and the 'end' number of threads. + + -e number of threads to end the benchmark series + Maximum number of threads to be run as the benchmarks series. + The series will run benchmarks between the 'begin' and the 'end' number of threads. + + -r repetitions + Number of times a benchmark is repeated. + + -v verbose + If set, bash debugging is enabled ('set -x') and sleeping after the benchmarks + is disabled. + +EOF +} + +init_params(){ + + check_env + + if ! [ -d $LOG_DIR ]; then + echo "$LOG_DIR doesn't existing. Creating $LOG_DIR..." + mkdir -p $LOG_DIR + fi + if ! [ -d $RESULT_DIR ]; then + echo "$RESULT_DIR doesn't existing. Creating $RESULT_DIR" + mkdir -p $RESULT_DIR + fi + + THREADS="$(seq $BEGIN $END)" + REPETITIONS="$(seq 1 $REPETITIONS)" + + # use second resolution in case multiple benchmarks are run per minute + NOW=$(date +"%y-%m-%d_%H-%M-%S") + # redirect stdout and stderr + exec 2> >(tee $LOG_DIR/$TYPE-$NOW.log) + exec > >(tee $RESULT_DIR/$TYPE-$NOW.csv) + + BASEFILE_SIZE=$(parse_size $BASEFILE_SIZE) + REQUEST_SIZE=$(parse_size $REQUEST_SIZE) + STRIPE_SIZE=$(parse_size $STRIPE_SIZE) + +} + + +parse_size(){ + local size_with_modifier=$1 + local index=$(echo `expr match $size_with_modifier '[0-9]\+'`) + local size=${size_with_modifier:0:$index} + local modifier=${size_with_modifier:$index} + + if [ $index != ${#size_with_modifier} ]; then + if [ $modifier = "K" ] || [ $modifier = "k" ]; then + size=$(echo "$size*2^10" | bc) + elif [ $modifier = "M" ] || [ $modifier = "m" ]; then + size=$(echo "$size*2^20" | bc) + elif [ $modifier = "G" ] || [ $modifier = "g" ]; then + size=$(echo "$size*2^30" | bc) + else + echo "Wrong size modifier. Only 'M' and 'G' are allowed" + exit 1 + fi + fi + + echo $size +} + + + +prepare_seq_read(){ + + local size=$1 + local threads=$2 + + # declare array of volume names + local volume_index=$(echo "$threads-1" | bc) + for i in $(seq 0 $volume_index); do VOLUMES[$i]=benchmark$i; done + + echo -e "\nPreparing sequential read benchmarks\n" >&2 + for i in $(seq 1 $threads); do + local index=$(echo "$i-1"|bc) + timeout --foreground $TIMEOUT $XTREEMFS/bin/xtfs_benchmark -sw -ssize $1 --no-cleanup --user $USER \ + ${VOLUMES[$index]} --stripe-size $STRIPE_SIZE --chunk-size $REQUEST_SIZE + done +} + +prepare_random(){ + + local threads=$1 + + # declare array of volume names + local volume_index=$(echo "$threads-1" | bc) + for i in $(seq 0 $volume_index); do VOLUMES[$i]=benchmark$i; done + + # calc basefile size and round to a number divideable through REQUEST_SIZE + local basefile_size=$(echo "(($BASEFILE_SIZE/$threads)/$REQUEST_SIZE)*$REQUEST_SIZE" | bc) + + echo -e "\nPreparing random benchmark: Creating a basefiles\n" >&2 + for i in $(seq 1 $threads); do + local index=$(echo "$i-1"|bc) + timeout --foreground $TIMEOUT $XTREEMFS/bin/xtfs_benchmark -rr -rsize $REQUEST_SIZE --no-cleanup-basefile --no-cleanup-volumes --user $USER \ + --basefile-size $basefile_size ${VOLUMES[$index]} --stripe-size $STRIPE_SIZE --chunk-size $REQUEST_SIZE + done +} + + +run_benchmark(){ + local benchType=$1 + local size=$2 + local threads=$3 + local replicationOpt="" + if [[ $REPLICATION_POLICY != "" ]]; then + replicationOpt="--replication-policy $REPLICATION_POLICY" + fi + + if [ $benchType = "sr" ]; then + XTREEMFS=$XTREEMFS timeout --foreground $TIMEOUT $XTREEMFS/bin/xtfs_benchmark -$benchType -ssize $size -n $threads --no-cleanup-volumes --user $USER \ + $replicationOpt --replication-factor $REPLICATION_FACTOR --chunk-size $REQUEST_SIZE --stripe-size $STRIPE_SIZE + elif [ $benchType = "sw" ] || [ $benchType = "usw" ]; then + XTREEMFS=$XTREEMFS timeout --foreground $TIMEOUT $XTREEMFS/bin/xtfs_benchmark -$benchType -ssize $size -n $threads --user $USER \ + $replicationOpt --replication-factor $REPLICATION_FACTOR --chunk-size $REQUEST_SIZE --stripe-size $STRIPE_SIZE + elif [ $benchType = "rw" ] || [ $benchType = "rr" ]; then + # calc basefile size and round to a number divideable through REQUEST_SIZE + local basefile_size=$(echo "(($BASEFILE_SIZE/$threads)/$REQUEST_SIZE)*$REQUEST_SIZE" | bc) + XTREEMFS=$XTREEMFS timeout --foreground $TIMEOUT $XTREEMFS/bin/xtfs_benchmark -$benchType -rsize $size --basefile-size $basefile_size -n $threads \ + --no-cleanup-basefile --no-cleanup-volumes --user $USER \ + $replicationOpt --replication-factor $REPLICATION_FACTOR --chunk-size $REQUEST_SIZE --stripe-size $STRIPE_SIZE + fi + + local bench_exit_status=$? + if [ $bench_exit_status -eq 124 ]; then + echo "The benchmark timed out (Timeout: $TIMEOUT)" >&2 + interrupted_exit + elif [ $bench_exit_status -ne 0 ]; then + echo "The benchmark did not finish with exit status 0" >&2 + interrupted_exit + fi + + # cleanup after *every* benchmark only for seq write benchmark + if [ $benchType = "sr" ]; then + cleanup_osd + fi +} + +delete_volumes(){ + local number_of_threads=$1 + local volume_index=$(echo "$number_of_threads-1" | bc) + for i in $(seq 0 $volume_index); do + rmfs.xtreemfs -f $MRC/benchmark$i >/dev/null + if [ $? -eq 0 ]; then + echo "Removed volume benchmark$i" >&2 + fi + done +} + +cleanup_osd(){ + for osd in $OSD_UUIDS; do + timeout --foreground $TIMEOUT_CLEANUP $XTREEMFS/bin/xtfs_cleanup -dir pbrpc://$DIR -wait -e -delete_volumes uuid:$osd >&2 + done + if $SLEEP; then + echo "Start Sleeping for $(echo "$SLEEPTIME/60"|bc) minutes at $(date)" >&2 + sleep $SLEEPTIME + echo "Finished Sleeping at $(date)" >&2 + fi + drop_caches +} + +interrupted_exit(){ + echo "Unexpected exit, cleaning up..." >&2 + SLEEP=false + delete_volumes $END + cleanup_osd + exit 1 +} + +drop_caches(){ + if [ -n "$DROP_CACHES_CALL" ]; then + echo "Dropping caches" >&2 + $DROP_CACHES_CALL + if $SLEEP; then + sleep 10 + fi + fi +} + +##### main ### + +trap "echo; echo 'Interrupt received '; interrupted_exit" INT + +# show usage if invoked without options/arguments +if [ $# -eq 0 ]; then + printUsage + exit 1 +fi + +# default values +BEGIN=1 +END=1 +REPETITIONS=1 + + +# parse options +while getopts ":t:s:c:i:b:e:r:p:f:v" opt; do + case $opt in + t) + if [ $OPTARG = "sw" ] || [ $OPTARG = "usw" ] || [ $OPTARG = "sr" ] || [ $OPTARG = "rw" ] || [ $OPTARG = "rr" ]; then + TYPE=$OPTARG + else + echo 'wrong argument to -t. Needs to be either "sw", "usw", "sr", "rw" or "rr"' + exit 1 + fi + ;; + s) + SIZE=$(parse_size $OPTARG) + ;; + c) + REQUEST_SIZE=$(parse_size $OPTARG) + ;; + i) + STRIPE_SIZE=$(parse_size $OPTARG) + ;; + b) + BEGIN=$OPTARG + ;; + e) + END=$OPTARG + ;; + r) + REPETITIONS=$OPTARG + ;; + p) + REPLICATION_POLICY=$OPTARG + ;; + f) + REPLICATION_FACTOR=$OPTARG + ;; + v) + SLEEP=false + set -x + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + exit 1 + ;; + esac +done + +init_params +drop_caches + +echo "Running:" $0 $@ >&2 + +for i in $THREADS; do + size="$(echo "$SIZE/$i"|bc)" + if [ $TYPE != "usw" ]; then + size="$(echo "($size/$REQUEST_SIZE)*$REQUEST_SIZE" | bc)" # round down to a size divideable through the REQUEST_SIZE + fi + + if [ $TYPE = "sr" ]; then + prepare_seq_read $size $i + cleanup_osd + elif [ $TYPE = "rw" ] || [ $TYPE = "rr" ]; then + prepare_random $i + fi + + for j in $REPETITIONS; do + echo "Start $i-Thread-Benchmark Nr. $j" >&2 + + run_benchmark $TYPE $size $i + + echo "Finished $i-Thread-Benchmark Nr. $j" >&2 + + done + + # seq write benchmarks run cleanup after every benchmark, so this would be redundant + if [ $TYPE != "sw" ] && [ $TYPE != "usw" ]; then + volume_index=$(echo "$i-1" | bc) + for i in $(seq 0 $volume_index); do + rmfs.xtreemfs -f $MRC/benchmark$i >&2 + echo "Remove volume benchmark$i" >&2 + done + cleanup_osd + fi + +done diff --git a/contrib/benchmark/drop_caches b/contrib/benchmark/drop_caches new file mode 100755 index 0000000..d83e2ce --- /dev/null +++ b/contrib/benchmark/drop_caches @@ -0,0 +1,3 @@ +#!/bin/bash + +/bin/bash -c "echo 3 > /proc/sys/vm/drop_caches" diff --git a/contrib/filter-MRC-dump-with-XSLT/filter_files.xslt b/contrib/filter-MRC-dump-with-XSLT/filter_files.xslt new file mode 100644 index 0000000..8adaab9 --- /dev/null +++ b/contrib/filter-MRC-dump-with-XSLT/filter_files.xslt @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + + + + | + + + + | + + + + | + + + + + + + \ No newline at end of file diff --git a/contrib/ganglia-plugin/.project b/contrib/ganglia-plugin/.project new file mode 100644 index 0000000..3714cb1 --- /dev/null +++ b/contrib/ganglia-plugin/.project @@ -0,0 +1,17 @@ + + + ganglia-plugin + + + + + + org.python.pydev.PyDevBuilder + + + + + + org.python.pydev.pythonNature + + diff --git a/contrib/ganglia-plugin/.pydevproject b/contrib/ganglia-plugin/.pydevproject new file mode 100644 index 0000000..f8b45b0 --- /dev/null +++ b/contrib/ganglia-plugin/.pydevproject @@ -0,0 +1,10 @@ + + + + +Default +python 2.6 + +/ganglia-plugin/src + + diff --git a/contrib/ganglia-plugin/README.txt b/contrib/ganglia-plugin/README.txt new file mode 100644 index 0000000..3219512 --- /dev/null +++ b/contrib/ganglia-plugin/README.txt @@ -0,0 +1,6 @@ +How to use this plugin? + +- Make sure your ganglia installation supports python plugins. +- Copy plugin files from src directory to /usr/lib/ganglia/python_modules/ +- Copy configuration files configuration-files directory to /etc/ganglia/conf.d +- Alter configuration files to suite your needs. diff --git a/contrib/ganglia-plugin/config-files/xtfs-dir.pyconf b/contrib/ganglia-plugin/config-files/xtfs-dir.pyconf new file mode 100644 index 0000000..6f93903 --- /dev/null +++ b/contrib/ganglia-plugin/config-files/xtfs-dir.pyconf @@ -0,0 +1,61 @@ +modules { + module { + name = "xtfs-dir-plugin" + language = "python" + # The following params are examples only + param Host { + value = localhost + } + param Port { + value = 9001 + } + param CommunityString { + value = public + } + } +} + +collection_group { + collect_every = 60 + time_threshold = 10 + metric { + name = "dir_jvm_used_mem" + title = "used memory of the jvm" + value_threshold = 1 + } + metric { + name = "dir_jvm_free_mem" + title = "free memory of the jvm" + value_threshold = 1 + } + metric { + name = "dir_client_connections" + title = "number of Clients" + value_threshold = 1 + } + metric { + name = "dir_pending_requests" + title = "number of pending requests" + value_threshold = 1 + } + metric { + name = "addr_mapping_count" + title = "number of address mappings" + value_threshold = 1 + } + metric { + name = "service_count" + title = "number of services" + value_threshold = 1 + } + metric { + name = "dir_status" + title = "Status DIR" + } + metric { + name = "dir_uuid" + title = "DIR UUID" + } +} + + diff --git a/contrib/ganglia-plugin/config-files/xtfs-mrc.pyconf b/contrib/ganglia-plugin/config-files/xtfs-mrc.pyconf new file mode 100644 index 0000000..a6bd12a --- /dev/null +++ b/contrib/ganglia-plugin/config-files/xtfs-mrc.pyconf @@ -0,0 +1,56 @@ +modules { + module { + name = "xtfs-mrc-plugin" + language = "python" + # The following params are examples only + param Host { + value = localhost + } + param Port { + value = 9002 + } + param CommunityString { + value = public + } + } +} + +collection_group { + collect_every = 60 + time_threshold = 10 + metric { + name = "mrc_jvm_used_mem" + title = "used memory of the jvm" + value_threshold = 1 + } + metric { + name = "mrc_jvm_free_mem" + title = "free memory of the jvm" + value_threshold = 1 + } + metric { + name = "mrc_client_connections" + title = "number of Clients" + value_threshold = 1 + } + metric { + name = "mrc_pending_requests" + title = "number of pending requests" + value_threshold = 1 + } + metric { + name = "volumes_count" + title = "number of volumes" + value_threshold = 1 + } + metric { + name = "mrc_status" + title = "Status MRC" + } + metric { + name = "mrc_uuid" + title = "MRC UUID" + } +} + + diff --git a/contrib/ganglia-plugin/config-files/xtfs-osd.pyconf b/contrib/ganglia-plugin/config-files/xtfs-osd.pyconf new file mode 100644 index 0000000..56128f5 --- /dev/null +++ b/contrib/ganglia-plugin/config-files/xtfs-osd.pyconf @@ -0,0 +1,107 @@ +modules { + module { + name = "xtfs-osd-plugin" + language = "python" + # The following params are examples only + param Host { + value = localhost + } + param Port { + value = 9003 + } + param CommunityString { + value = public + } + } +} + +collection_group { + collect_every = 60 + time_threshold = 10 + metric { + name = "osd_jvm_used_mem" + title = "used memory of the jvm" + value_threshold = 1 + } + metric { + name = "osd_jvm_free_mem" + title = "free memory of the jvm" + value_threshold = 1 + } + metric { + name = "osd_client_connections" + title = "number of Clients" + value_threshold = 1 + } + metric { + name = "objects_received" + title = "objects received" + value_threshold = 1 + } + metric { + name = "repl_objects_received" + title = "replicated objects received" + value_threshold = 1 + } + metric { + name = "objects_transmitted" + title = "objects transmitted" + value_threshold = 1 + } + metric { + name = "repl_bytes_received" + title = "replicated bytes received" + value_threshold = 1 + } + metric { + name = "bytes_received" + title = "bytes received" + value_threshold = 1 + } + metric { + name = "bytes_transmitted" + title = "bytes transmitted" + value_threshold = 1 + } + metric { + name = "preproc_queue_length" + title = "preprocessing stage queue length" + value_threshold = 1 + } + metric { + name = "storage_queue_length" + title = "storage stage queue length" + value_threshold = 1 + } + metric { + name = "deletion_queue_length" + title = "deletion stage queue length" + value_threshold = 1 + } + metric { + name = "open_files" + title = "open files" + value_threshold = 1 + } + metric { + name = "deleted_files" + title = "deleted files" + value_threshold = 1 + } + metric { + name = "free_space" + title = "free space" + value_threshold = 100 + } + metric { + name = "osd_status" + title = "Status OSD" + } + metric { + name = "osd_uuid" + title = "OSD UUID" + } +} + + + \ No newline at end of file diff --git a/contrib/ganglia-plugin/src/xtfs-dir-plugin.py b/contrib/ganglia-plugin/src/xtfs-dir-plugin.py new file mode 100644 index 0000000..32f40ab --- /dev/null +++ b/contrib/ganglia-plugin/src/xtfs-dir-plugin.py @@ -0,0 +1,250 @@ +''' +Created on May 25, 2011 + +@author: bzcseife + +This is a python ganglia plugin which monitors the status of an DIR service of the XtreemFS +filesystem. It is intend to run on the same host as the DIR and gathers information of the DIR per +SNMP. Therefore you have to configure your DIR to provide a SNMP Agent on this host. + +''' +#TODO: If ganglia supports 64bit values uses 64bit integers instead of converting all 64 bit integers +#reported from the SNMP Agent to 32bit integers. + + +import random +from pysnmp.entity.rfc3413.oneliner import cmdgen +from pysnmp.entity.rfc3413.oneliner.cmdgen import UdpTransportTarget + + +descriptors = list() +Random_Max = 50 +Constant_Value = 50 + + + +#Get the used memory of the JVM +def JvmUsedMem(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 1, 0)) + if (errorStatus == False and errorIndication == None): + + return int(varBinds[0][1]/1024/1024) + else: + return 0 +#Get the free memory of the JVM +def JvmFreeMem(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 2, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1] / 1024 / 1024) + else: + return 0 + +#Get the number of client connections +def ClientConnections(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 8, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + + +#Get the number of pending requests +def PendingRequests(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 9, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + +#Get the number of address mappings registered +def AddressMappingCount(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 2, 1, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + +#Get the number of services registered +def ServiceCount(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 2, 2, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + +#get the status of the DIR +#OID: 1.3.6.1.4.1.38350.1.11.0 +def Status(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 11, 0)) + + if (errorStatus == False and errorIndication == None): + return str(varBinds[0][1]) + else: + return "OFFLINE" + +#get the UUID of the DIR +#OID: 1.3.6.1.4.1.38350.1.13.0 +def Uuid(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 13, 0)) + + if (errorStatus == False and errorIndication == None): + return str(varBinds[0][1]) + else: + return "Service not available" + +def metric_init(params): + + global descriptors + global Commmunity_String + global Snmp_Port + global authData + global transportTarget + + + if 'ComummunityString' in params: + Community_String = params['CommunityString'] + else: + Community_String = 'public' + + if 'Port' in params: + Snmp_Port = int(params['Port']) + if 'Host' in params: + Snmp_Host = params['Host'] + + authData = cmdgen.CommunityData('xtreemfs-agent', 'public') + transportTarget = cmdgen.UdpTransportTarget((Snmp_Host, Snmp_Port), 1, 0) + + d0 = {'name': 'dir_jvm_used_mem', + 'call_back': JvmUsedMem, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'Megabytes', + 'slope': 'both', + 'format': '%u', + 'description': 'The amount of memory the JVM uses currently.', + 'groups': 'dir'} + + d1 = {'name': 'dir_jvm_free_mem', + 'call_back': JvmFreeMem, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'Megabytes', + 'slope': 'both', + 'format': '%u', + 'description': 'The amount of free memory the JVM can still use.', + 'groups': 'dir'} + + d2 = {'name': 'dir_client_connections', + 'call_back': ClientConnections, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'clients', + 'slope': 'both', + 'format': '%u', + 'description': 'The number of active client connection this DIR has currently to handle.', + 'groups': 'dir'} + + d3 = {'name': 'dir_pending_requests', + 'call_back': PendingRequests, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'pending requests', + 'slope': 'both', + 'format': '%u', + 'description': 'The number of pending requests this DIR has enqueued.', + 'groups': 'dir'} + + d4 = {'name': 'addr_mapping_count', + 'call_back': AddressMappingCount, + 'time_max': 90, + #value_type: string | uint | float | double + 'value_type': 'uint', + #units: unit of your metric + 'units': 'mappings', + #slope: zero | positive | negative | both + #This value maps to the data source types defined for RRDTool + #If 'positive', RRD file generated will be of COUNTER type (calculating the rate of change) + #If 'negative', ???? + #'both' will be of GAUGE type (no calculations are performed, graphing only the value reported) + #If 'zero', the metric will appear in the "Time and String Metrics" or the "Constant Metrics" depending on the value_type of the m + 'slope': 'both', + #format: format string of your metric + #Must correspond to value_type otherwise value of your metric will be unpredictable (reference: http://docs.python.org/library/stdtypes.html#string-formatting) + 'format': '%u', + #description: description of your metric + 'description': 'The number of address mapping registered at the DIR.', + #groups (optional): groups your metric belongs to + 'groups': 'dir'} + + d5 = {'name': 'service_count', + 'call_back': ServiceCount, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'services', + 'slope': 'both', + 'format': '%u', + 'description': 'The number of services registered at the DIR.', + 'groups': 'dir'} + + d6 = {'name': 'dir_status', + 'call_back': Status, + 'time_max': 90, + 'value_type': 'string', + 'units': '', + 'slope': 'zero', + 'format': '%s', + 'description': 'ONLINE if this DIR is running correctly, OFFLINE otherwise', + 'groups': 'dir'} + + d7 = {'name': 'dir_uuid', + 'call_back': Uuid, + 'time_max': 90, + 'value_type': 'string', + 'units': '', + 'slope': 'zero', + 'format': '%s', + 'description': 'UUID of the DIR running on this host', + 'groups': 'dir'} + + + descriptors = [d0, d1, d2, d3, d4, d5, d6, d7] + + return descriptors + +def metric_cleanup(): + '''Clean up the metric module.''' + pass + + +#for debugging purpose +if __name__ == '__main__': + params = {'CommunityString': 'public', 'Host': 'localhost', 'Port': 9001} + metric_init(params) + for d in descriptors: + v = d['call_back'](d['name']) + print 'value for %s is' % (d['name']) + print v + + + diff --git a/contrib/ganglia-plugin/src/xtfs-mrc-plugin.py b/contrib/ganglia-plugin/src/xtfs-mrc-plugin.py new file mode 100644 index 0000000..91bc396 --- /dev/null +++ b/contrib/ganglia-plugin/src/xtfs-mrc-plugin.py @@ -0,0 +1,221 @@ +''' +Created on May 25, 2011 + +@author: bzcseife + +This is a python ganglia plugin which monitors the status of an DIR service of the XtreemFS +filesystem. It is intend to run on the same host as the MRC and gathers information of the MRC per +SNMP. Therefore you have to configure your MRC to provide a SNMP Agent on this host. + +''' +#TODO: If ganglia supports 64bit values uses 64bit integers instead of converting all 64 bit integers +#reported from the SNMP Agent to 32bit integers. + + +import random +from pysnmp.entity.rfc3413.oneliner import cmdgen +from pysnmp.entity.rfc3413.oneliner.cmdgen import UdpTransportTarget + + +descriptors = list() +Random_Max = 50 +Constant_Value = 50 + + + +#Get the used memory of the JVM +def JvmUsedMem(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 1, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1] / 1024 / 1024) + else: + return 0 + +#Get the free memory of the JVM +def JvmFreeMem(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 2, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1] / 1024 / 1024) + else: + return 0 + + +#Get the number of client connections +def ClientConnections(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 7, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + + +#Get the number of pending requests +def PendingRequests(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 8, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + +#Get the number of volumes +def VolumeCount(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 3, 2, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + +#get the status of the MRC +def Status(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 11, 0)) + + if (errorStatus == False and errorIndication == None): + return str(varBinds[0][1]) + else: + return "OFFLINE" + + +#get the UUID of the MRC +#OID: 1.3.6.1.4.1.38350.1.13.0 +def Uuid(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 13, 0)) + + if (errorStatus == False and errorIndication == None): + return str(varBinds[0][1]) + else: + return "Service not available" + + +def metric_init(params): + + global descriptors + global Commmunity_String + global Snmp_Port + global authData + global transportTarget + + + if 'ComummunityString' in params: + Community_String = params['CommunityString'] + else: + Community_String = 'public' + + if 'Port' in params: + Snmp_Port = int(params['Port']) + if 'Host' in params: + Snmp_Host = params['Host'] + + authData = cmdgen.CommunityData('xtreemfs-agent', 'public') + transportTarget = cmdgen.UdpTransportTarget((Snmp_Host, Snmp_Port),1 ,0) + + d0 = {'name': 'mrc_jvm_used_mem', + 'call_back': JvmUsedMem, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'Megabytes', + 'slope': 'both', + 'format': '%u', + 'description': 'The amount of memory the JVM uses currently.', + 'groups': 'mrc'} + + d1 = {'name': 'mrc_jvm_free_mem', + 'call_back': JvmFreeMem, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'Megabytes', + 'slope': 'both', + 'format': '%u', + 'description': 'The amount of free memory the JVM can still use.', + 'groups': 'mrc'} + + d2 = {'name': 'mrc_client_connections', + 'call_back': ClientConnections, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'clients', + 'slope': 'both', + 'format': '%u', + 'description': 'The number of active client connection this MRC has currently to handle.', + 'groups': 'mrc'} + + d3 = {'name': 'mrc_pending_requests', + 'call_back': PendingRequests, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'pending requests', + 'slope': 'both', + 'format': '%u', + 'description': 'The number of pending requests this MRC has enqueued.', + 'groups': 'mrc'} + + d4 = {'name': 'volumes_count', + 'call_back': VolumeCount, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'volumes', + 'slope': 'both', + 'format': '%u', + 'description': 'The number of volumes on this MRC.', + 'groups': 'mrc'} + + d5 = {'name': 'mrc_status', + 'call_back': Status, + 'time_max': 90, + 'value_type': 'string', + 'units': '', + 'slope': 'zero', + 'format': '%s', + 'description': 'ONLINE if this OSD is running correctly, OFFLINE otherwise', + 'groups': 'mrc'} + + d6 = {'name': 'mrc_uuid', + 'call_back': Uuid, + 'time_max': 90, + 'value_type': 'string', + 'units': '', + 'slope': 'zero', + 'format': '%s', + 'description': 'UUID of the MRC running on this host', + 'groups': 'mrc'} + + + + descriptors = [d0, d1, d2, d3, d4, d5, d6 ] + + return descriptors + +def metric_cleanup(): + '''Clean up the metric module.''' + pass + + +#for debugging purpose +if __name__ == '__main__': + params = {'CommunityString': 'public', 'Host': 'localhost', 'Port': 9002} + metric_init(params) + for d in descriptors: + v = d['call_back'](d['name']) + print 'value for %s is ' % (d['name']) + print v + + + diff --git a/contrib/ganglia-plugin/src/xtfs-osd-plugin.py b/contrib/ganglia-plugin/src/xtfs-osd-plugin.py new file mode 100644 index 0000000..e2fc721 --- /dev/null +++ b/contrib/ganglia-plugin/src/xtfs-osd-plugin.py @@ -0,0 +1,477 @@ +''' +Created on May 25, 2011 + +@author: bzcseife + +This is a python ganglia plugin which monitors the status of an OSD service of the XtreemFS +filesystem. It is intend to run on the same host as the OSD and gathers information of the OSD per +SNMP. Therefore you have to configure your OSD to provide a SNMP Agent on this host. + +''' +#TODO: If ganglia supports 64bit values uses 64bit integers instead of converting all 64 bit integers +#reported from the SNMP Agent to 32bit integers. + + +import random +from pysnmp.entity.rfc3413.oneliner import cmdgen +from pysnmp.entity.rfc3413.oneliner.cmdgen import UdpTransportTarget + + + + +descriptors = list() +Random_Max = 50 +Constant_Value = 50 + + + +#Get the used memory of the JVM +def JvmUsedMem(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 1, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1] / 1024 / 1024) + else: + return 0 + + + +#Get the free memory of the JVM +def JvmFreeMem(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 2, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1] / 1024 / 1024) + else: + return 0 + + +#Get the number of client connections +def ClientConnections(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 7, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + + +#Get the number of pending requests +def PendingRequests(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 8, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + +#Get the number of objects received +def ObjectsReceived(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 1, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + +#Get the number of replicated objects received +def ReplObjectsReceived(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 2, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + +#Get the number of replicated objects transmitted +def ObjectsTransmitted(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 3, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + +#Get the number of replicated bytes received +def ReplBytesReceived(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 4, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1] / 1024 / 1024) + else: + return 0 + +#Get the number of bytes received +def BytesReceived(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 5, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1] / 1024 / 1024) + else: + return 0 + +#Get the number of bytes transmitted +def BytesTransmitted(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 6, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1] / 1024 / 1024) + else: + return 0 + +#Get the length of the preprocessing stage queue +def PreprocQueueLength(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 7, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1] / 1024 / 1024) + else: + return 0 + +#Get the length of the storage stage queue +def StorageQueueLength(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 8, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + +#Get the length of the deletion stage queue +def DeletionQueueLength(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 9, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + + +#Get the number of open files from the OSD per snmp +def OsdOpenFiles(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 10, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + + + +#Get the number of deleted files from the OSD per snmp +def OsdDeletedFiles(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 11, 0)) + + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1]) + else: + return 0 + + +#Get the free space from the OSD per snmp +def OsdFreeSpace(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 4, 12, 0)) + if (errorStatus == False and errorIndication == None): + return int(varBinds[0][1] / 1024 / 1024) + else: + return 0 + +#get the status of the OSD +def Status(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 11, 0)) + + if (errorStatus == False and errorIndication == None): + return str(varBinds[0][1]) + else: + return "OFFLINE" + +#get the UUID of the OSD +#OID: 1.3.6.1.4.1.38350.1.13.0 +def Uuid(name): + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(authData, + transportTarget, + (1, 3, 6, 1, 4, 1, 38350, 1, 13, 0)) + + if (errorStatus == False and errorIndication == None): + return str(varBinds[0][1]) + else: + return "Service not available" + +def metric_init(params): + + global descriptors + global Commmunity_String + global Snmp_Port + global authData + global transportTarget + + + if 'ComummunityString' in params: + Community_String = params['CommunityString'] + else: + Community_String = 'public' + + if 'Port' in params: + Snmp_Port = int(params['Port']) + if 'Host' in params: + Snmp_Host = params['Host'] + + authData = cmdgen.CommunityData('xtreemfs-agent', 'public') + transportTarget = cmdgen.UdpTransportTarget((Snmp_Host, Snmp_Port),1,0) + + d0 = {'name': 'osd_jvm_used_mem', + 'call_back': JvmUsedMem, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'Megabytes', + 'slope': 'both', + 'format': '%u', + 'description': 'The amount of memory the JVM uses currently.', + 'groups': 'osd'} + + d1 = {'name': 'osd_jvm_free_mem', + 'call_back': JvmFreeMem, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'Megabytes', + 'slope': 'both', + 'format': '%u', + 'description': 'The amount of free memory the JVM can still use.', + 'groups': 'osd'} + + d2 = {'name': 'osd_client_connections', + 'call_back': ClientConnections, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'clients', + 'slope': 'both', + 'format': '%u', + 'description': 'The number of active client connection this OSD has currently to handle.', + 'groups': 'osd'} + + d3 = {'name': 'osd_pending_requests', + 'call_back': PendingRequests, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'pending requests', + 'slope': 'both', + 'format': '%u', + 'description': 'The number of pending requests this OSD has enqueued.', + 'groups': 'osd'} + + d4 = {'name': 'objects_received', + 'call_back': ObjectsReceived, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'objects', + 'slope': 'positive', + 'format': '%u', + 'description': 'The number of objects this OSD has received.', + 'groups': 'osd'} + + d5 = {'name': 'repl_objects_received', + 'call_back': ReplObjectsReceived, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'objects', + 'slope': 'positive', + 'format': '%u', + 'description': 'The number of replicated objects this OSD has received.', + 'groups': 'osd'} + + d6 = {'name': 'objects_transmitted', + 'call_back': ObjectsTransmitted, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'objects', + 'slope': 'positive', + 'format': '%u', + 'description': 'The number of objects this OSD has transmitted.', + 'groups': 'osd'} + + d7 = {'name': 'repl_bytes_received', + 'call_back': ReplBytesReceived, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'Megabytes', + 'slope': 'positive', + 'format': '%u', + 'description': 'The number of replicated bytes this OSD has received.', + 'groups': 'osd'} + + d8 = {'name': 'bytes_received', + 'call_back': BytesReceived, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'Megabytes', + 'slope': 'positive', + 'format': '%u', + 'description': 'The number of bytes this OSD has received.', + 'groups': 'osd'} + + d9 = {'name': 'bytes_transmitted', + 'call_back': BytesTransmitted, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'Megabytes', + 'slope': 'positive', + 'format': '%u', + 'description': 'The number of bytes this OSD has transmitted.', + 'groups': 'osd'} + + d10 = {'name': 'preproc_queue_length', + 'call_back': PreprocQueueLength, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'requests', + 'slope': 'both', + 'format': '%u', + 'description': 'The length of the preprocessing stage queue of this OSD.', + 'groups': 'osd'} + + d11 = {'name': 'storage_queue_length', + 'call_back': StorageQueueLength, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'requests', + 'slope': 'positive', + 'format': '%u', + 'description': 'The length of the storage stage queue of this OSD.', + 'groups': 'osd'} + + d12 = {'name': 'deletion_queue_length', + 'call_back': DeletionQueueLength, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'requests', + 'slope': 'both', + 'format': '%u', + 'description': 'The length of the deletion stage queue of this OSD.', + 'groups': 'osd'} + + d13 = {'name': 'storage_queue_length', + 'call_back': StorageQueueLength, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'requests', + 'slope': 'both', + 'format': '%u', + 'description': 'The length of the storage stage queue of this OSD.', + 'groups': 'osd'} + + d14 = {'name': 'open_files', + 'call_back': OsdOpenFiles, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'files', + 'slope': 'both', + 'format': '%u', + 'description': 'The number of file this OSD has currently opened.', + 'groups': 'osd'} + + d15 = {'name': 'deleted_files', + 'call_back': OsdDeletedFiles, + 'time_max': 90, + 'value_type': 'uint', + 'units': 'files', + 'slope': 'positive', + 'format': '%u', + 'description': 'The number of deleted files on this OSD', + 'groups': 'osd'} + + + d16 = {'name': 'free_space', + 'call_back': OsdFreeSpace, + 'time_max': 90, + #value_type: string | uint | float | double + 'value_type': 'uint', + #units: unit of your metric + 'units': 'Megabytes', + #slope: zero | positive | negative | both + #This value maps to the data source types defined for RRDTool + #If 'positive', RRD file generated will be of COUNTER type (calculating the rate of change) + #If 'negative', ???? + #'both' will be of GAUGE type (no calculations are performed, graphing only the value reported) + #If 'zero', the metric will appear in the "Time and String Metrics" or the "Constant Metrics" depending on the value_type of the m + 'slope': 'both', + #format: format string of your metric + #Must correspond to value_type otherwise value of your metric will be unpredictable (reference: http://docs.python.org/library/stdtypes.html#string-formatting) + 'format': '%u', + #description: description of your metric + 'description': 'The free disc space on the partition this OSD stores the object files.', + #groups (optional): groups your metric belongs to + 'groups': 'osd'} + + d17 = {'name': 'osd_status', + 'call_back': Status, + 'time_max': 90, + 'value_type': 'string', + 'units': '', + 'slope': 'zero', + 'format': '%s', + 'description': 'ONLINE if this OSD is running correctly, OFFLINE otherwise', + 'groups': 'osd'} + + d18 = {'name': 'osd_uuid', + 'call_back': Uuid, + 'time_max': 90, + 'value_type': 'string', + 'units': '', + 'slope': 'zero', + 'format': '%s', + 'description': 'UUID of the OSD running on this host', + 'groups': 'osd'} + + descriptors = [d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18] + + return descriptors + +def metric_cleanup(): + '''Clean up the metric module.''' + pass + + +#for debugging purpose +if __name__ == '__main__': + params = {'CommunityString': 'public', 'Host': 'localhost', 'Port': 9003} + metric_init(params) + for d in descriptors: + v = d['call_back'](d['name']) + print 'value for %s is' % (d['name']) + print v + + diff --git a/contrib/osd-health/osd_health_check.sh b/contrib/osd-health/osd_health_check.sh new file mode 100755 index 0000000..068de1c --- /dev/null +++ b/contrib/osd-health/osd_health_check.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +OBJECT_DIR=$1 + +# get device for object_dir +IFS=' ' read -r DEVICE TMP <<< $(df $OBJECT_DIR | grep dev) + +# Determine device type +if [[ $DEVICE == *md* ]]; then + # DEVICE is a RAID configuration + DEVICES=$(IFS=' ' read -a TMP <<< $(cat /proc/mdstat | grep $DEVICE)) + DEVICES=${DEVICES[@]:4} +elif [[ $DEVICE == *sd* || $DEVICE == *hd* ]]; then + # DEVICE is a single disk + DEVICES=$DEVICE +else + # unsupported device type + echo "unsupported device type" + exit 3 +fi + +for DEVICE in $DEVICES; do + SMART_STATUS="$(sudo smartctl --health $DEVICE)" + echo $SMART_STATUS + if [[ $SMART_STATUS == *PASSED* ]] + then + continue; + elif [[ $SMART_STATUS == *FAILED* ]] + then + exit 1 + else + exit 3 + fi +done + +# If no device's health test failed, return 0 (i.e. health test PASSED). +exit 0 diff --git a/contrib/server-repl-plugin/BabuDB_replication_plugin.jar b/contrib/server-repl-plugin/BabuDB_replication_plugin.jar new file mode 100644 index 0000000000000000000000000000000000000000..9c2114e15adf29ea961acaee4846d8b0d2557915 GIT binary patch literal 757620 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�`!76<uQ#u5FEad9|N1jby7)s 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 z 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

F~*;{E?lFsI~R|fkr85$r^K7RN-E64G@6wQlsgW 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

!WG3DSyL_TgE;jxkVqx9^U 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Π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º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 literal 0 HcmV?d00001 diff --git a/contrib/server-repl-plugin/LICENSE b/contrib/server-repl-plugin/LICENSE new file mode 100644 index 0000000..2f35497 --- /dev/null +++ b/contrib/server-repl-plugin/LICENSE @@ -0,0 +1,32 @@ +Copyright (c) 2008-2011, Jan Stender, Bjoern Kolbeck, Mikael Hoegqvist, + Felix Hupfeld, Felix Langner, Zuse Institute Berlin +All rights reserved. + +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 the Zuse Institute Berlin 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. diff --git a/contrib/server-repl-plugin/README b/contrib/server-repl-plugin/README new file mode 100644 index 0000000..c364af4 --- /dev/null +++ b/contrib/server-repl-plugin/README @@ -0,0 +1,3 @@ +For further details on how to use the BabuDB replication plug-in, please refer to the BabuDB Wiki: + +http://code.google.com/p/babudb/wiki/UsageReplicationForJava \ No newline at end of file diff --git a/contrib/server-repl-plugin/config/dir.properties b/contrib/server-repl-plugin/config/dir.properties new file mode 100644 index 0000000..bf25913 --- /dev/null +++ b/contrib/server-repl-plugin/config/dir.properties @@ -0,0 +1,82 @@ +##################################################################### +# BabuDB replication plugin configuration (DIR replication) # +##################################################################### + +##################################################################### +# List of replicas and replication configuration +##################################################################### + +# participants of the replication including this replica +babudb.repl.participant.0 = first-DIR-replica +babudb.repl.participant.0.port = 35678 +babudb.repl.participant.1 = second-DIR-replica +babudb.repl.participant.1.port = 35678 +babudb.repl.participant.2 = third-DIR-replica +babudb.repl.participant.2.port = 35678 + +# number of servers that at least have to be up to date +# To have a fault-tolerant system, this value has to be set to the +# majority of nodes i.e., if you have three replicas, set this to 2 +# Please note that a setup with two nodes provides no fault-tolerance. +babudb.repl.sync.n = 2 + +##################################################################### +# Advanced Options (usually you do NOT have to edit these) +##################################################################### + +# It's possible to set the local address and port of this server explicitly. +# If not, it will be chosen from the list of participants. +#babudb.repl.localhost = localhost +#babudb.repl.localport = 35678 + +# Choose here one of the predefined policies for handling database requests: +# +# MasterOnly - Redirect any kind of request to the master. +# Provides strong consistency. +# WriteRestriction - Same as MasterOnly plus lookup operations are also permitted on the slaves. +# Consequently, clients may read stale values from a backup replica. +# NoRestriction - Allows any kind of request to be performed at the local BabuDB instance. +# May result into conflicts which are not resolved. +# +# default setting is MasterOnly. +#babudb.repl.policy = MasterOnly + +# DB backup directory - needed for the initial loading of the BabuDB from the +# master in replication context +babudb.repl.backupDir = /var/lib/xtreemfs/server-repl-dir + +##################################################################### +# SSL options (disabled by default) +##################################################################### + +# specify whether SSL is required +#babudb.ssl.enabled = false + +# server credentials for SSL handshakes +#babudb.ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12 +#babudb.ssl.service_creds.pw = xtreemfs +#babudb.ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +#babudb.ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/xosrootca.jks +#babudb.ssl.trusted_certs.pw = xtreemfs +#babudb.ssl.trusted_certs.container = jks + +#babudb.ssl.authenticationWithoutEncryption = false + +##################################################################### +# Internal options (usually do not have to be touched) +##################################################################### +plugin.jar = /usr/share/java/BabuDB_replication_plugin.jar + +# paths to libraries this plugin depends on +babudb.repl.dependency.0 = /usr/share/java/Flease.jar + +# local time renew in milliseconds +#babudb.localTimeRenew = 0 + +# chunk size, for initial load of file chunks +#babudb.repl.chunkSize = 5242880 + +# decides whether redirects should be handled by the user-application or not +#babudb.repl.redirectIsVisible = false diff --git a/contrib/server-repl-plugin/config/mrc.properties b/contrib/server-repl-plugin/config/mrc.properties new file mode 100644 index 0000000..2ec33cb --- /dev/null +++ b/contrib/server-repl-plugin/config/mrc.properties @@ -0,0 +1,82 @@ +##################################################################### +# BabuDB replication plugin configuration (MRC replication) # +##################################################################### + +##################################################################### +# List of replicas and replication configuration +##################################################################### + +# participants of the replication including this replica +babudb.repl.participant.0 = first-MRC-replica +babudb.repl.participant.0.port = 35676 +babudb.repl.participant.1 = second-MRC-replica +babudb.repl.participant.1.port = 35676 +babudb.repl.participant.2 = third-MRC-replica +babudb.repl.participant.2.port = 35676 + +# number of servers that at least have to be up to date +# To have a fault-tolerant system, this value has to be set to the +# majority of nodes i.e., if you have three replicas, set this to 2 +# Please note that a setup with two nodes provides no fault-tolerance. +babudb.repl.sync.n = 2 + +##################################################################### +# Advanced Options (usually you do NOT have to edit these) +##################################################################### + +# It's possible to set the local address and port of this server explicitly. +# If not, it will be chosen from the list of participants. +#babudb.repl.localhost = localhost +#babudb.repl.localport = 35676 + +# Choose here one of the predefined policies for handling database requests: +# +# MasterOnly - Redirect any kind of request to the master. +# Provides strong consistency. +# WriteRestriction - Same as MasterOnly plus lookup operations are also permitted on the slaves. +# Consequently, clients may read stale values from a backup replica. +# NoRestriction - Allows any kind of request to be performed at the local BabuDB instance. +# May result into conflicts which are not resolved. +# +# default setting is MasterOnly. +#babudb.repl.policy = MasterOnly + +# DB backup directory - needed for the initial loading of the BabuDB from the +# master in replication context +babudb.repl.backupDir = /var/lib/xtreemfs/server-repl-mrc + +##################################################################### +# SSL options (disabled by default) +##################################################################### + +# specify whether SSL is required +#babudb.ssl.enabled = false + +# server credentials for SSL handshakes +#babudb.ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12 +#babudb.ssl.service_creds.pw = xtreemfs +#babudb.ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +#babudb.ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/xosrootca.jks +#babudb.ssl.trusted_certs.pw = xtreemfs +#babudb.ssl.trusted_certs.container = jks + +#babudb.ssl.authenticationWithoutEncryption = false + +##################################################################### +# Internal options (usually do not have to be touched) +##################################################################### +plugin.jar = /usr/share/java/BabuDB_replication_plugin.jar + +# paths to libraries this plugin depends on +babudb.repl.dependency.0 = /usr/share/java/Flease.jar + +# local time renew in milliseconds +#babudb.localTimeRenew = 0 + +# chunk size, for initial load of file chunks +#babudb.repl.chunkSize = 5242880 + +# decides whether redirects should be handled by the user-application or not +#babudb.repl.redirectIsVisible = false diff --git a/contrib/server-repl-plugin/update_BabuDB_replication_plugin_jar.sh b/contrib/server-repl-plugin/update_BabuDB_replication_plugin_jar.sh new file mode 100755 index 0000000..11fa3ce --- /dev/null +++ b/contrib/server-repl-plugin/update_BabuDB_replication_plugin_jar.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# Copyright (c) 2012 Michael Berlin, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +set -e + +trap onexit 1 2 3 15 ERR + +function onexit() { + local exit_status=${1:-$?} + echo ERROR: Exiting $0 with $exit_status + exit $exit_status +} + +replication_dir_in_babudb_trunk="java/replication" + +cat </dev/null +ant jar -f "$babudb_replication_buildfile" >/dev/null +cp -a "$babudb_replication_jar_source" "$babudb_replication_jar_dest" + +echo "finished compiling BabuDB replication plugion (BabuDB_replication_plugin.jar)" diff --git a/contrib/travis/parse_results.py b/contrib/travis/parse_results.py new file mode 100755 index 0000000..fc32124 --- /dev/null +++ b/contrib/travis/parse_results.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +# Copyright (c) 2014 by Johannes Dillmann, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +import sys + +import argparse +import json + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("file", type=argparse.FileType('r')) + parser.add_argument("test") + args = parser.parse_args() + + results = json.load(args.file) + result = None + + if args.test in results: + result = results[args.test] + + if type(result) == bool and result: + print "true" + sys.exit(0) + + if type(result) == dict and all(result.values()): + print "true" + sys.exit(0) + + print "false" + sys.exit(1) + diff --git a/contrib/vagrant/provision.sh b/contrib/vagrant/provision.sh new file mode 100644 index 0000000..a24f674 --- /dev/null +++ b/contrib/vagrant/provision.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +echo "Installing XtreemFS build dependencies" +apt-get -y update +apt-get -y install openjdk-7-jdk ant build-essential libssl-dev libfuse-dev libattr1-dev cmake libboost-regex-dev libboost-program-options-dev libboost-thread-dev libboost-system-dev valgrind +echo "export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64" >> /etc/bash.bashrc +echo "export BUILD_CLIENT_TESTS=true" >> /etc/bash.bashrc diff --git a/contrib/xtreemfs-osd-farm/xtreemfs-osd-farm b/contrib/xtreemfs-osd-farm/xtreemfs-osd-farm new file mode 100755 index 0000000..8260843 --- /dev/null +++ b/contrib/xtreemfs-osd-farm/xtreemfs-osd-farm @@ -0,0 +1,223 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: xtreemfs-osd-farm +# Required-Start: $network $remote_fs +# Required-Stop: $network $remote_fs +# Should-Start: xtreemfs-dir +# Should-Stop: $null +# Default-Start: 3 5 +# Default-Stop: 0 1 2 6 +# Short-Description: XtreemFS OSD init.d script which can start multiple OSDs on the same machine in contrast to xtreemfs-osd +# Description: XtreemFS Object Storage Device (OSD). http://www.xtreemfs.org/ +### END INIT INFO + +# Source function library. +if [ -e /lib/lsb/init-functions ]; then + . /lib/lsb/init-functions +else + . /etc/init.d/functions +fi + +XTREEMFS_USER=xtreemfs + +# List of OSD instances which shall be started, seperated by spaces. +# For every OSD there has to be a configuration file. +OSD_INSTANCES="osd1 osd2 osd3" + +# OSD specific options. Use %OSDNAME% which will be substituted. +PID_OSD_GENERIC=/var/run/xtreemfs_%OSDNAME%.pid + +CONFIG_OSD_GENERIC=/etc/xos/xtreemfs/%OSDNAME%.config.properties + +LOG_OSD_GENERIC=/var/log/xtreemfs/%OSDNAME%.log + +if [ -z $JAVA_HOME ]; then + export JAVA_HOME=/usr +fi +JAVA_CALL="$JAVA_HOME/bin/java -ea -cp /usr/share/java/XtreemFS.jar:/usr/share/java/BabuDB.jar:/usr/share/java/Flease.jar:/usr/share/java/protobuf-java-2.5.0.jar:/usr/share/java/Foundation.jar:/usr/share/java/jdmkrt.jar:/usr/share/java/jdmktk.jar:/usr/share/java/commons-codec-1.3.jar" + +# For SELinux we need to use 'runuser' not 'su' +if [ -x "/sbin/runuser" ]; then + SU="/sbin/runuser" +else + SU="/bin/su" +fi + +pre_check() { + LOG_OSD="$1" + CONFIG_OSD="$2" + exists=`grep -c $XTREEMFS_USER /etc/passwd` + if [ $exists -eq 0 ]; then + echo "User $XTREEMFS_USER does not exist. Create it first." + exit 1 + fi + log_directory=`dirname $LOG_OSD` + if [ ! -e $log_directory ]; then + echo "Directory for logfiles $log_directory does not exist. Create it first." + exit 1 + fi + + if [ ! -f "$CONFIG_OSD" ]; then + echo -e "Config file not found: $CONFIG_OSD" + echo + exit 1 + fi +} + +get_osd_list() { + OSD_LIST="" + if [ -n "$1" ]; then + # Check if given OSD name in list of allowed OSDs. + for osd in $OSD_INSTANCES; do + [ "$osd" = "$1" ] && OSD_LIST="$1" && return 0 + done + + echo "OSD \"$1\" is not part of the list OSD_INSTANCES." + exit 1 + else + OSD_LIST=$OSD_INSTANCES + return 0 + fi +} + +substitute_osdname() { + echo "$1" | sed -e "s/%OSDNAME%/$2/g" +} + +pre_check_vars() { + for var in $LOG_OSD_GENERIC $PID_OSD_GENERIC $CONFIG_OSD_GENERIC; do + echo "$var" | grep %OSDNAME% >/dev/null || { + echo "%OSDNAME% parameter not found in variable: $var" + exit 1 + } + done +} + +start() { + get_osd_list "$1" + pre_check_vars + + for osdname in $OSD_LIST; do + LOG_OSD=$(substitute_osdname "$LOG_OSD_GENERIC" "$osdname") + PID_OSD=$(substitute_osdname "$PID_OSD_GENERIC" "$osdname") + CONFIG_OSD=$(substitute_osdname "$CONFIG_OSD_GENERIC" "$osdname") + + pre_check "$LOG_OSD" "$CONFIG_OSD" + + echo >> $LOG_OSD + date >> $LOG_OSD + echo -e "Starting XtreemFS Object Storage Device (OSD): $osdname ... \n\n" >> $LOG_OSD + + echo -n "Starting XtreemFS Object Storage Device (OSD): $osdname ... " + $SU -s /bin/bash $XTREEMFS_USER -c "$JAVA_CALL org.xtreemfs.osd.OSD $CONFIG_OSD" >> $LOG_OSD 2>&1 & + PROCPID=$! + echo $PROCPID > $PID_OSD + sleep 1s + + if [ -e /proc/$PROCPID ]; then + echo "success" + else + echo "failed" + return 1 + fi + + done + + return 0 +} + +stop() { + get_osd_list "$1" + pre_check_vars + + for osdname in $OSD_LIST; do + LOG_OSD=$(substitute_osdname "$LOG_OSD_GENERIC" "$osdname") + PID_OSD=$(substitute_osdname "$PID_OSD_GENERIC" "$osdname") + CONFIG_OSD=$(substitute_osdname "$CONFIG_OSD_GENERIC" "$osdname") + + result=0 + if [ -f $PID_OSD ]; then + echo -n "Stopping XtreemFS Object Storage Device (OSD): $osdname ... " + killproc -p $PID_OSD $SU + result=$? + if [ $result -eq 0 ]; then + rm -f $PID_OSD + echo "success" + else + echo "failed" + fi + else + echo "XtreemFS Object Storage Device (OSD) is not running" + fi + + done + return $result +} + +status() { + get_osd_list "$1" + pre_check_vars + + rc=0 + for osdname in $OSD_LIST; do + LOG_OSD=$(substitute_osdname "$LOG_OSD_GENERIC" "$osdname") + PID_OSD=$(substitute_osdname "$PID_OSD_GENERIC" "$osdname") + CONFIG_OSD=$(substitute_osdname "$CONFIG_OSD_GENERIC" "$osdname") + + if [ -f $PID_OSD ]; then + PROCPID=`cat $PID_OSD` + if [ ! -e /proc/$PROCPID ]; then + echo "XtreemFS Object Storage Device (OSD): $osdname has crashed" + rc=1 + else + echo "XtreemFS Object Storage Device (OSD): $osdname is running" + fi + else + echo "XtreemFS Object Storage Device (OSD): $osdname is not running" + rc=3 + fi + done + + return $rc +} + +# See how we were called. +case "$1" in + start) + start "$2" + result=$? + ;; + stop) + stop "$2" + result=$? + ;; + status) + status "$2" + result=$? + ;; + reload) + result=0 + ;; + restart) + stop "$2" && sleep 1 && start "$2" + result=$? + ;; + try-restart) + ## Stop the service and if this succeeds (i.e. the + ## service was running before), start it again. + $0 status "$2" >/dev/null + if [ $? -eq 0 ]; then + $0 restart "$2" + result=$? + else + result=0 + fi + ;; + *) + echo -e "Usage: $0 {start|stop|restart|reload|status|try-restart}\n" + result=1 + ;; +esac + +exit $result diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt new file mode 100644 index 0000000..db85f26 --- /dev/null +++ b/cpp/CMakeLists.txt @@ -0,0 +1,397 @@ +cmake_minimum_required(VERSION 2.6) +PROJECT(cpp CXX C) + +#SET (CMAKE_VERBOSE_MAKEFILE true) + +# used for everything, but the preload library (which struggles with implicitly +# generated symbols suffixed with 64, e.g. open64) +set(COMPILE_DEFS "_FILE_OFFSET_BITS=64") + +# Uncomment this to enable boost::asio debug output. +#add_definitions(-DBOOST_ASIO_ENABLE_HANDLER_TRACKING) + +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + +# Set variables and required libraries. +########################################## +if (CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "-Wall -Wno-unused-function -Wno-sign-compare -pthread") +endif(CMAKE_COMPILER_IS_GNUCXX) +if (MSVC) + # Windows uses Unicode internally, so we also use Unicode instead of the default multi-byte character set. + add_definitions(-DUNICODE -D_UNICODE) + # Require at least Windows XP. + add_definitions(-D_WIN32_WINNT=0x0501) + # autolink for boost::asio does wrongfully require date_time and regex libraries. + # See: http://www.boost.org/doc/libs/1_46_1/doc/html/boost_asio/using.html + add_definitions(-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB) + ADD_DEFINITIONS(/D _CRT_SECURE_NO_WARNINGS) +endif(MSVC) +if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + set (SOLARIS true) +endif(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") +if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + set (FREEBSD true) +endif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + +# Set paths for required thirdparty libraries. +set(CLIENT_GOOGLE_PROTOBUF_CPP "${CMAKE_SOURCE_DIR}/thirdparty/protobuf-2.5.0") +if (WIN32) + set(CLIENT_GOOGLE_PROTOBUF_CPP_LIBRARY "${CLIENT_GOOGLE_PROTOBUF_CPP}/vsprojects/Release/libprotobuf.lib") +else() + FIND_FILE(CLIENT_GOOGLE_PROTOBUF_CPP_LIBRARY + "libprotobuf.a" + PATHS "${CLIENT_GOOGLE_PROTOBUF_CPP}/src/.libs/") + FIND_FILE(CLIENT_GOOGLE_PROTOBUF_CPP_DYNAMIC_LIBRARY + "libprotobuf.so" + PATHS "${CLIENT_GOOGLE_PROTOBUF_CPP}/src/.libs/") +endif(WIN32) +set(CLIENT_GOOGLE_TEST_CPP "${CMAKE_SOURCE_DIR}/thirdparty/gtest-1.7.0") +if (WIN32) + set(CLIENT_GOOGLE_TEST_CPP_LIBRARY "${CLIENT_GOOGLE_TEST_CPP}/msvc/gtest-md/Debug/gtestd.lib") +else() + set(CLIENT_GOOGLE_TEST_CPP_LIBRARY "${CLIENT_GOOGLE_TEST_CPP}/lib/.libs/libgtest.a") +endif(WIN32) +if (WIN32) + set(CLIENT_GOOGLE_TEST_CPP_MAIN "${CLIENT_GOOGLE_TEST_CPP}/msvc/gtest-md/Debug/gtest_main-mdd.lib") +else() + set(CLIENT_GOOGLE_TEST_CPP_MAIN "${CLIENT_GOOGLE_TEST_CPP}/lib/.libs/libgtest_main.a") +endif(WIN32) +# Windows requires for a Debug build also debug libraries from protobuf & co. +STRING(REPLACE "Release" "Debug" CLIENT_GOOGLE_PROTOBUF_CPP_LIBRARY_DEBUG ${CLIENT_GOOGLE_PROTOBUF_CPP_LIBRARY}) +STRING(REPLACE "Release" "Debug" TEMP ${CLIENT_GOOGLE_TEST_CPP_LIBRARY}) +STRING(REPLACE ".lib" "d.lib" CLIENT_GOOGLE_TEST_CPP_LIBRARY_DEBUG ${TEMP}) +STRING(REPLACE "Release" "Debug" TEMP ${CLIENT_GOOGLE_TEST_CPP_MAIN}) +STRING(REPLACE ".lib" "d.lib" CLIENT_GOOGLE_TEST_CPP_MAIN_DEBUG ${TEMP}) + +# Set required libraries. +if (NOT WIN32) + set(LIBFUSE "fuse") + SET(LIBATTR "attr") + SET(LIBPTHREAD "pthread") +endif(NOT WIN32) + +if (SOLARIS) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthreads") + SET(LIBSOCKET_SOLARIS "socket") + SET(LIBNSL_SOLARIS "nsl") + # No libattr on Solaris. + SET(LIBATTR "") +endif(SOLARIS) + +IF (APPLE OR FREEBSD) + SET(LIBATTR "") +ENDIF(APPLE OR FREEBSD) + +IF (WIN32 OR APPLE OR SOLARIS) + # Run cmake with -DBOOST_ROOT= on Windows, Solaris and MacOSX. + # We link against the boost libraries found in BOOST_ROOT. + SET(Boost_USE_STATIC_LIBS true) +ENDIF(WIN32 OR APPLE OR SOLARIS) + +IF (APPLE) + # Update 8/12/2011: Setting macosx-version-min does break mount.xtreemfs for unknown reasons - so disabled for now. + # Tell gcc to compile 10.4 compatible files (does not work otherwise on older Macs). + #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.4") + + SET(OSXFUSE_FUSE_H_INCLUDE_DIR "/usr/local/include/osxfuse/") + if (EXISTS ${OSXFUSE_FUSE_H_INCLUDE_DIR}) + include_directories(${OSXFUSE_FUSE_H_INCLUDE_DIR}) + endif(EXISTS ${OSXFUSE_FUSE_H_INCLUDE_DIR}) +ENDIF(APPLE) +IF(WIN32) + SET(Boost_USE_STATIC_LIBS true) + LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) + + SET(CBFS_LICENSE "include/cbfs/cbfs_license.h") + IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${CBFS_LICENSE}") + ## Find CbFS + # CBFS_ROOT - Input variable: Set to + # CBFS_FOUND - Output variable: CBFS was found. + # CBFS_INCLUDE_DIR - Output variable: Directory which contains the CbFS.h file. + # CBFS_LIBRARIES - Output variable: Will be set to CbFS.lib location. + find_path(CBFS_INCLUDE_DIR CbFS.h PATHS "$ENV{ProgramFiles}/EldoS/Callback File System/CPP/VC2010/32bit/dynamic_runtime(MD)" ${CBFS_ROOT}) + find_library(CBFS_LIBRARY CbFS "$ENV{ProgramFiles}/EldoS/Callback File System/CPP/VC2010/32bit/dynamic_runtime(MD)" ${CBFS_ROOT}) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(CBFS DEFAULT_MSG CBFS_LIBRARY CBFS_INCLUDE_DIR) + + if (CBFS_FOUND) + set(CBFS_LIBRARIES ${CBFS_LIBRARY}) + include_directories(${CBFS_INCLUDE_DIR}) + else(CBFS_FOUND) + message(FATAL_ERROR "The required library 'CbFS' was not found.") + endif (CBFS_FOUND) + mark_as_advanced(CBFS_LIBRARY) + ELSE() + message(STATUS "File ${CBFS_LICENSE} was not found. Compilation of the CbFSAdapter, which allows to mount XtreemFS volumes as network drive, will be skipped.\n\nPlease note: it is not possible to build the CbFSAdapter on your own unless you have a license for the CbFS library. The XtreemFS open-source project was granted a non-commercial license and therefore we can compile the CbFSAdapter and distribute binaries of it.\n") + ENDIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${CBFS_LICENSE}") +ENDIF(WIN32) + +# Set required thirdparty libraries. + +# Boost +#set(Boost_DEBUG ON) +set(REQUIRED_BOOST_LIBRARIES "system" "thread" "program_options" "regex") +if (BOOST_ROOT) + message(STATUS "Info: BOOST_ROOT is set to: ${BOOST_ROOT}") +endif(BOOST_ROOT) +# Finding the boost libraries may fail. If existing, we point FIND_PACKAGE to /usr/lib64. +if(NOT BOOST_ROOT AND EXISTS "/usr/lib64/libboost_system.so") + set(BOOST_LIBRARYDIR "/usr/lib64") +endif(NOT BOOST_ROOT AND EXISTS "/usr/lib64/libboost_system.so") +# Initial find boost only to retrieve the version number. +FIND_PACKAGE(Boost) +# Unset the Boost_FOUND variable because the result of the second find will be checked. +set(Boost_FOUND) +if(WIN32 AND Boost_VERSION VERSION_GREATER "104900") + set(REQUIRED_BOOST_LIBRARIES ${REQUIRED_BOOST_LIBRARIES} "chrono") +endif(WIN32 AND Boost_VERSION VERSION_GREATER "104900") +# Actual find boost including all required libraries. +FIND_PACKAGE(Boost COMPONENTS ${REQUIRED_BOOST_LIBRARIES} REQUIRED) +if (NOT Boost_FOUND) + message(FATAL_ERROR "The boost library was not found on your system. If needed, you can also download and compile it on your own. After compiling boost locally, set the the environment variable BOOST_ROOT to the boost base directory before executing 'make' e.g., 'export BOOST_ROOT=/Users/xyz/boost_1_47_0'.") +endif(NOT Boost_FOUND) +include_directories(${Boost_INCLUDE_DIRS}) + +find_package(OpenSSL) +if (NOT OPENSSL_FOUND) +# OpenSSL find_package script cannot cope with /usr/lib64 directory under Cmake 2.8.3. + set(LIBCRYPTO "crypto") + set(LIBSSL "ssl") + set(OPENSSL_LIBRARIES ${LIBCRYPTO} ${LIBSSL}) +endif(NOT OPENSSL_FOUND) +include_directories(${OPENSSL_INCLUDE_DIR}) +# Comment this definition if the XtreemFS source should not depend on OpenSSL. +add_definitions(-DHAS_OPENSSL) + +find_package(Valgrind) +if (VALGRIND_FOUND) + include_directories(${VALGRIND_INCLUDE_DIR}) + add_definitions(-DHAS_VALGRIND) +else (VALGRIND_FOUND) + message(WARNING "Valgrind headers not found, running memcheck might report false positives.") +endif (VALGRIND_FOUND) + +SET(REQUIRED_STATIC_LIBRARIES ${CLIENT_GOOGLE_PROTOBUF_CPP_LIBRARY}) +if(BUILD_CLIENT_TESTS) + SET(REQUIRED_STATIC_LIBRARIES ${REQUIRED_STATIC_LIBRARIES} ${CLIENT_GOOGLE_TEST_CPP_LIBRARY} ${CLIENT_GOOGLE_TEST_CPP_MAIN}) +endif(BUILD_CLIENT_TESTS) + +foreach (STATIC_LIB_FULL_PATH ${REQUIRED_STATIC_LIBRARIES}) + if(NOT EXISTS ${STATIC_LIB_FULL_PATH}) + message(FATAL_ERROR "The file ${STATIC_LIB_FULL_PATH} was not found. Please run 'make client' or 'make' from the base directory in order to build the required static libraries.") + endif() +endforeach(STATIC_LIB_FULL_PATH) + +CMAKE_POLICY(SET CMP0003 OLD) +ADD_LIBRARY(protobuf STATIC IMPORTED) +ADD_LIBRARY(protobuf_debug STATIC IMPORTED) +SET_PROPERTY(TARGET protobuf PROPERTY IMPORTED_LOCATION ${CLIENT_GOOGLE_PROTOBUF_CPP_LIBRARY}) +SET_PROPERTY(TARGET protobuf_debug PROPERTY IMPORTED_LOCATION ${CLIENT_GOOGLE_PROTOBUF_CPP_LIBRARY_DEBUG}) +include_directories(${CLIENT_GOOGLE_PROTOBUF_CPP}/src) + +ADD_LIBRARY(gtest STATIC IMPORTED) +ADD_LIBRARY(gtest_debug STATIC IMPORTED) +ADD_LIBRARY(gtest_main STATIC IMPORTED) +ADD_LIBRARY(gtest_main_debug STATIC IMPORTED) +SET_PROPERTY(TARGET gtest PROPERTY IMPORTED_LOCATION ${CLIENT_GOOGLE_TEST_CPP_LIBRARY}) +SET_PROPERTY(TARGET gtest_debug PROPERTY IMPORTED_LOCATION ${CLIENT_GOOGLE_TEST_CPP_LIBRARY_DEBUG}) +SET_PROPERTY(TARGET gtest_main PROPERTY IMPORTED_LOCATION ${CLIENT_GOOGLE_TEST_CPP_MAIN}) +SET_PROPERTY(TARGET gtest_main_debug PROPERTY IMPORTED_LOCATION ${CLIENT_GOOGLE_TEST_CPP_MAIN_DEBUG}) +include_directories(${CLIENT_GOOGLE_TEST_CPP}/include) + +# Check if this is a 64 Bit system +if(UNIX AND NOT WIN32) + if(APPLE) + set(LIBFUSE "osxfuse") + endif(APPLE) +endif(UNIX AND NOT WIN32) + +SET(REQUIRED_LIBRARIES ${LIBATTR} ${LIBCRYPTO} ${LIBSSL} ${LIBPTHREAD}) +if (SKIP_FUSE) + MESSAGE(STATUS "INFO: Skipping the XtreemFS Fuse Adapter (mount.xtreemfs) because SKIP_FUSE was defined.") +else() + SET(REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} ${LIBFUSE}) +endif(SKIP_FUSE) + +foreach(LIB ${REQUIRED_LIBRARIES}) + #message(STATUS "checking for library: ${LIB}") + # For unknown reasons, setting "FIND_LIBRARY_USE_LIB64_PATHS" does not fix the issue that libraries in /usr/lib64/ are not found under openSuse. + # Therefore we just specify a list of possible library directories. + find_library(FOUND${LIB} ${LIB} PATHS "/lib64" "/usr/lib64") + if (NOT FOUND${LIB}) + if (${LIB} STREQUAL ${LIBFUSE}) + message(STATUS "INFO: If you want to skip the compilation of the FuseAdapter e.g., because your system does not provide Fuse (library: ${LIBFUSE}), please define SKIP_FUSE e.g., run: SKIP_FUSE=true make client") + endif (${LIB} STREQUAL ${LIBFUSE}) + message(FATAL_ERROR "The required library '${LIB}' was not found. Please install it on your system first.") + #else() + # message(STATUS "Result of find_library: ${FOUND${LIB}}") + endif(NOT FOUND${LIB}) +endforeach(LIB) + +# Define building of binaries. +########################################## +MESSAGE(STATUS "Configuring XtreemFS Client Library (libxtreemfs) and Volume Tools ({mkfs,rmfs,lsfs}.xtreemfs).") + +INCLUDE_DIRECTORIES(include generated) +file(GLOB_RECURSE SRCS_RPC src/rpc/*.cpp include/rpc/*.h) +file(GLOB_RECURSE SRCS_UTIL src/util/*.cpp include/util/*.h) +file(GLOB_RECURSE SRCS_GENERATED generated/*.cc generated/*.h) +file(GLOB_RECURSE SRCS_XTREEMFS src/libxtreemfs/*.cpp include/libxtreemfs/*.h) +add_library(xtreemfs ${SRCS_RPC} ${SRCS_UTIL} ${SRCS_GENERATED} ${SRCS_XTREEMFS}) +# WARNING: The resulting static libxtreemfs does NOT contain the required static library protobuf. +# If you want to use a static libxtreemfs, you have to use a CMake file like this which does automatically add the static libxtreemfs and libprotobuf to the executable. +# An alternative would be to change this file in such a way that the static libxtreemfs and libprotobuf are merged together into a static libxtreemfs. +# But this would require additional CMake macros as presented here: http://www.mail-archive.com/cmake@cmake.org/msg28670.html +TARGET_LINK_LIBRARIES(xtreemfs optimized protobuf debug protobuf_debug ${Boost_LIBRARIES} ${LIBPTHREAD} ${OPENSSL_LIBRARIES} ${LIBSOCKET_SOLARIS} ${LIBNSL_SOLARIS}) + +ADD_EXECUTABLE(example_libxtreemfs src/example_libxtreemfs/example_libxtreemfs.cpp) +SET_TARGET_PROPERTIES(example_libxtreemfs PROPERTIES COMPILE_DEFINITIONS ${COMPILE_DEFS}) +TARGET_LINK_LIBRARIES(example_libxtreemfs xtreemfs) + +ADD_EXECUTABLE(example_replication src/example_libxtreemfs/example_replication.cpp) +SET_TARGET_PROPERTIES(example_replication PROPERTIES COMPILE_DEFINITIONS ${COMPILE_DEFS}) +TARGET_LINK_LIBRARIES(example_replication xtreemfs) + +file(GLOB_RECURSE SRCS_MKFS src/mkfs.xtreemfs/*.cpp) +ADD_EXECUTABLE(mkfs.xtreemfs ${SRCS_MKFS}) +SET_TARGET_PROPERTIES(mkfs.xtreemfs PROPERTIES COMPILE_DEFINITIONS ${COMPILE_DEFS}) +TARGET_LINK_LIBRARIES(mkfs.xtreemfs xtreemfs) + +file(GLOB_RECURSE SRCS_RMFS src/rmfs.xtreemfs/*.cpp) +ADD_EXECUTABLE(rmfs.xtreemfs ${SRCS_RMFS}) +SET_TARGET_PROPERTIES(rmfs.xtreemfs PROPERTIES COMPILE_DEFINITIONS ${COMPILE_DEFS}) +TARGET_LINK_LIBRARIES(rmfs.xtreemfs xtreemfs) + +file(GLOB_RECURSE SRCS_LSFS src/lsfs.xtreemfs/*.cpp) +ADD_EXECUTABLE(lsfs.xtreemfs ${SRCS_LSFS}) +SET_TARGET_PROPERTIES(lsfs.xtreemfs PROPERTIES COMPILE_DEFINITIONS ${COMPILE_DEFS}) +TARGET_LINK_LIBRARIES(lsfs.xtreemfs xtreemfs) + +file(GLOB_RECURSE SRCS_XTFS_UTIL src/xtfsutil/xtfsutil_server.cpp) +file(GLOB_RECURSE SRCS_JSONCPP src/json/*.cpp) + +if (NOT WIN32) + if (FOUND${LIBFUSE}) + MESSAGE(STATUS "Configuring XtreemFS Fuse Adapter (mount.xtreemfs).") + file(GLOB_RECURSE SRCS_FUSE_ADAPTER src/fuse/fuse*.cpp) + file(GLOB_RECURSE SRCS_FUSE_ADAPTER_MAIN src/fuse/mount.xtreemfs.cpp) + ADD_EXECUTABLE(mount.xtreemfs ${SRCS_FUSE_ADAPTER} ${SRCS_FUSE_ADAPTER_MAIN} ${SRCS_XTFS_UTIL} ${SRCS_JSONCPP}) + SET_TARGET_PROPERTIES(mount.xtreemfs PROPERTIES COMPILE_DEFINITIONS ${COMPILE_DEFS}) + TARGET_LINK_LIBRARIES(mount.xtreemfs xtreemfs ${LIBFUSE}) + + set(UNITTESTS_REQUIRED_SOURCES_fuse ${SRCS_FUSE_ADAPTER} ${SRCS_XTFS_UTIL} ${SRCS_JSONCPP}) + set(UNITTESTS_REQUIRED_LIBRARIES_fuse ${LIBFUSE}) + endif(FOUND${LIBFUSE}) + + ADD_EXECUTABLE(xtfsutil src/xtfsutil/xtfsutil.cpp ${SRCS_JSONCPP}) + TARGET_LINK_LIBRARIES(xtfsutil ${Boost_LIBRARIES} ${LIBATTR}) + + set(UNITTESTS_SKIP_cbfs true) +endif(NOT WIN32) +if(WIN32 AND CBFS_FOUND) + MESSAGE(STATUS "Configuring XtreemFS CbFS Adapter (mount.xtreemfs.exe).") + file(GLOB_RECURSE SRCS_CBFS_ADAPTER src/cbfs/*.cpp) + ADD_EXECUTABLE(mount.xtreemfs ${SRCS_CBFS_ADAPTER} ${SRCS_XTFS_UTIL} ${SRCS_JSONCPP}) + TARGET_LINK_LIBRARIES(mount.xtreemfs xtreemfs ${CBFS_LIBRARIES}) + + set(UNITTESTS_SKIP_fuse true) +endif(WIN32 AND CBFS_FOUND) + +function(find_source_files RESULT) + set(RESULT "") + foreach(GLOBEXPR ${ARGV}) + file(GLOB_RECURSE FILES ${GLOBEXPR}) + foreach(TEST ${FILES}) + get_filename_component(DIRNAME ${TEST} PATH) + get_filename_component(COMPONENT ${DIRNAME} NAME) + get_filename_component(FILENAME ${TEST} NAME) + if (${FILENAME} MATCHES "_test.cpp$") + #skip + elseif (${FILENAME} MATCHES "_main.cpp$") + #skip + else() + LIST(APPEND RESULT ${TEST}) + endif() + endforeach(TEST) + endforeach(GLOBEXPR) + set(FIND_RESULT ${RESULT} PARENT_SCOPE) +endfunction(find_source_files) + +#SET(BUILD_PRELOAD TRUE) +if (BUILD_PRELOAD) + find_source_files("src/ld_preload/*.cpp" "include/ld_preload/*.h") + set(SRCS_PRELOAD ${FIND_RESULT}) + + # The LD_PRELOAD dynamic library + add_library(xtreemfs_preload SHARED ${SRCS_PRELOAD} + ${SRCS_RPC} ${SRCS_UTIL} ${SRCS_GENERATED} ${SRCS_XTREEMFS}) + + IF(NOT ${CMAKE_BUILD_TYPE} MATCHES "Debug") + SET_TARGET_PROPERTIES(xtreemfs_preload PROPERTIES COMPILE_DEFINITIONS "XTREEMFS_PRELOAD_QUIET") + ENDIF(NOT ${CMAKE_BUILD_TYPE} MATCHES "Debug") + + SET_TARGET_PROPERTIES(xtreemfs_preload PROPERTIES LINKER_LANGUAGE C) + TARGET_LINK_LIBRARIES(xtreemfs_preload + xtreemfs + -ldl + ${CLIENT_GOOGLE_PROTOBUF_CPP_DYNAMIC_LIBRARY}) + ADD_EXECUTABLE(preload_test "test/ld_preload/preload_test.cpp") +endif(BUILD_PRELOAD) + +################################################################################ +# Define building of unittests. +################################################################################ +# +# Unit tests are only compiled if the CMake variable BUILD_CLIENT_TESTS is set +# (passed by the top level Makefile if the environment variable +# BUILD_CLIENT_TESTS is set). +# +# The directory structure under test/ is identical to the one under src/ and +# include/. +# Since some components are not available on all plattforms, some variables +# are inspected for each component before the component's unit tests are +# compiled. +# A component here is given by the name of the directory below test/ i.e., +# the component for the file test/fuse/fuse_options_test.cpp is "fuse". +# +# The following variables are inspected for each component: +# UNITTESTS_SKIP_${COMPONENT} - set if component unit tests must not be compiled +# UNITTESTS_REQUIRED_SOURCES_${COMPONENT} - list of source files which have to +# be compiled for the unit test +# UNITTESTS_REQUIRED_LIBRARIES_${COMPONENT} - list of libraries which have to be +# linked to the unit test. +################################################################################ +if(BUILD_CLIENT_TESTS) + # enable_testing() will provide a target "test". + enable_testing() + include_directories("test") + + MESSAGE(STATUS "Configuring libxtreemfs unittests.") + + file(GLOB_RECURSE SRCS_TEST_COMMON test/common/*.cpp) + add_library(test_common ${SRCS_TEST_COMMON}) + set (UNITTESTS_SKIP_common true) + + file(GLOB_RECURSE SRCS_TESTS test/*.cpp) + foreach (TEST ${SRCS_TESTS}) + get_filename_component(DIRNAME ${TEST} PATH) + get_filename_component(COMPONENT ${DIRNAME} NAME) + get_filename_component(FILENAME ${TEST} NAME) + if (NOT UNITTESTS_SKIP_${COMPONENT}) + if (${FILENAME} MATCHES "_test.cpp$") + string(REGEX REPLACE "_test.cpp$" "" testname ${FILENAME}) + set(testname "test_${testname}") + MESSAGE(STATUS "\tConfiguring test: ${testname}.") + + add_executable(${testname} ${TEST} ${UNITTESTS_REQUIRED_SOURCES_${COMPONENT}}) + SET_TARGET_PROPERTIES(${testname} PROPERTIES COMPILE_DEFINITIONS ${COMPILE_DEFS}) + TARGET_LINK_LIBRARIES(${testname} gtest_main gtest test_common xtreemfs ${UNITTESTS_REQUIRED_LIBRARIES_${COMPONENT}}) + ADD_TEST(${testname} ${testname}) + else() + MESSAGE(STATUS "\tWARNING: Found file '${FILENAME}' below test/ does not end with '_test.cpp' and was therefore ignored as unit test.") + endif(${FILENAME} MATCHES "_test.cpp$") + endif(NOT UNITTESTS_SKIP_${COMPONENT}) + endforeach(TEST) +endif(BUILD_CLIENT_TESTS) diff --git a/cpp/Doxyfile b/cpp/Doxyfile new file mode 100644 index 0000000..07fd28c --- /dev/null +++ b/cpp/Doxyfile @@ -0,0 +1,1623 @@ +# Doxyfile 1.7.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = XtreemFS-Client + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src \ + include \ + test + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans.ttf + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/cpp/cmake/FindValgrind.cmake b/cpp/cmake/FindValgrind.cmake new file mode 100644 index 0000000..cc21cb6 --- /dev/null +++ b/cpp/cmake/FindValgrind.cmake @@ -0,0 +1,18 @@ +find_path(VALGRIND_INCLUDE_DIR + NAMES + valgrind/valgrind.h + HINTS + /usr + /usr/local + PATH_SUFFIXES + include +) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(VALGRIND + DEFAULT_MSG + VALGRIND_INCLUDE_DIR +) + +mark_as_advanced(VALGRIND_INCLUDE_DIR) \ No newline at end of file diff --git a/cpp/cpp_prj/.dep.inc b/cpp/cpp_prj/.dep.inc new file mode 100644 index 0000000..4560e55 --- /dev/null +++ b/cpp/cpp_prj/.dep.inc @@ -0,0 +1,5 @@ +# This code depends on make tool being used +DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES})) +ifneq (${DEPFILES},) +include ${DEPFILES} +endif diff --git a/cpp/cpp_prj/cpp_prj-Makefile.mk b/cpp/cpp_prj/cpp_prj-Makefile.mk new file mode 100644 index 0000000..ec9de69 --- /dev/null +++ b/cpp/cpp_prj/cpp_prj-Makefile.mk @@ -0,0 +1,128 @@ +# +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: +# +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target +# +# Targets beginning with '.' are not intended to be called on their own. +# +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. +# +# Available make variables: +# +# CND_BASEDIR base directory for relative paths +# CND_DISTDIR default top distribution directory (build artifacts) +# CND_BUILDDIR default top build directory (object files, ...) +# CONF name of current configuration +# CND_PLATFORM_${CONF} platform name (current configuration) +# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) +# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) +# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) +# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) +# CND_PACKAGE_NAME_${CONF} name of package (current configuration) +# CND_PACKAGE_PATH_${CONF} path to package (current configuration) +# +# NOCDDL + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin + + +# build +build: .build-post + +.build-pre: +# Add your pre 'build' code here... + +.build-post: .build-impl +# Add your post 'build' code here... + + +# clean +clean: .clean-post + +.clean-pre: +# Add your pre 'clean' code here... + +.clean-post: .clean-impl +# Add your post 'clean' code here... + + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# build tests +build-tests: .build-tests-post + +.build-tests-pre: +# Add your pre 'build-tests' code here... + +.build-tests-post: .build-tests-impl +# Add your post 'build-tests' code here... + + +# run tests +test: .test-post + +.test-pre: +# Add your pre 'test' code here... + +.test-post: .test-impl +# Add your post 'test' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk + +# include project make variables +include nbproject/Makefile-variables.mk diff --git a/cpp/cpp_prj/nbproject/Makefile-Default.mk b/cpp/cpp_prj/nbproject/Makefile-Default.mk new file mode 100644 index 0000000..f763f28 --- /dev/null +++ b/cpp/cpp_prj/nbproject/Makefile-Default.mk @@ -0,0 +1,66 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc +CCC=g++ +CXX=g++ +FC= +AS=as + +# Macros +CND_PLATFORM=GNU-Linux-x86 +CND_CONF=Default +CND_DISTDIR=dist + +# Include project Makefile +include cpp_prj-Makefile.mk + +# Object Directory +OBJECTDIR=build/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS= +CXXFLAGS= + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS= + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + cd .. && ${MAKE} -f Makefile + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + cd .. && ${MAKE} -f Makefile clean + +# Subprojects +.clean-subprojects: diff --git a/cpp/cpp_prj/nbproject/Makefile-impl.mk b/cpp/cpp_prj/nbproject/Makefile-impl.mk new file mode 100644 index 0000000..41e48c2 --- /dev/null +++ b/cpp/cpp_prj/nbproject/Makefile-impl.mk @@ -0,0 +1,133 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a pre- and a post- target defined where you can add customization code. +# +# This makefile implements macros and targets common to all configurations. +# +# NOCDDL + + +# Building and Cleaning subprojects are done by default, but can be controlled with the SUB +# macro. If SUB=no, subprojects will not be built or cleaned. The following macro +# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf +# and .clean-reqprojects-conf unless SUB has the value 'no' +SUB_no=NO +SUBPROJECTS=${SUB_${SUB}} +BUILD_SUBPROJECTS_=.build-subprojects +BUILD_SUBPROJECTS_NO= +BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}} +CLEAN_SUBPROJECTS_=.clean-subprojects +CLEAN_SUBPROJECTS_NO= +CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} + + +# Project Name +PROJECTNAME=cpp_prj + +# Active Configuration +DEFAULTCONF=Default +CONF=${DEFAULTCONF} + +# All Configurations +ALLCONFS=Default + + +# build +.build-impl: .build-pre .validate-impl .depcheck-impl + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf + + +# clean +.clean-impl: .clean-pre .validate-impl .depcheck-impl + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf + + +# clobber +.clobber-impl: .clobber-pre .depcheck-impl + @#echo "=> Running $@..." + for CONF in ${ALLCONFS}; \ + do \ + "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \ + done + +# all +.all-impl: .all-pre .depcheck-impl + @#echo "=> Running $@..." + for CONF in ${ALLCONFS}; \ + do \ + "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \ + done + +# build tests +.build-tests-impl: .build-impl .build-tests-pre + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf + +# run tests +.test-impl: .build-tests-impl .test-pre + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf + +# dependency checking support +.depcheck-impl: + @echo "# This code depends on make tool being used" >.dep.inc + @if [ -n "${MAKE_VERSION}" ]; then \ + echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \ + echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ + echo "include \$${DEPFILES}" >>.dep.inc; \ + echo "endif" >>.dep.inc; \ + else \ + echo ".KEEP_STATE:" >>.dep.inc; \ + echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ + fi + +# configuration validation +.validate-impl: + @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ + then \ + echo ""; \ + echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \ + echo "See 'make help' for details."; \ + echo "Current directory: " `pwd`; \ + echo ""; \ + fi + @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ + then \ + exit 1; \ + fi + + +# help +.help-impl: .help-pre + @echo "This makefile supports the following configurations:" + @echo " ${ALLCONFS}" + @echo "" + @echo "and the following targets:" + @echo " build (default target)" + @echo " clean" + @echo " clobber" + @echo " all" + @echo " help" + @echo "" + @echo "Makefile Usage:" + @echo " make [CONF=] [SUB=no] build" + @echo " make [CONF=] [SUB=no] clean" + @echo " make [SUB=no] clobber" + @echo " make [SUB=no] all" + @echo " make help" + @echo "" + @echo "Target 'build' will build a specific configuration and, unless 'SUB=no'," + @echo " also build subprojects." + @echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no'," + @echo " also clean subprojects." + @echo "Target 'clobber' will remove all built files from all configurations and," + @echo " unless 'SUB=no', also from subprojects." + @echo "Target 'all' will will build all configurations and, unless 'SUB=no'," + @echo " also build subprojects." + @echo "Target 'help' prints this message." + @echo "" + diff --git a/cpp/cpp_prj/nbproject/Makefile-variables.mk b/cpp/cpp_prj/nbproject/Makefile-variables.mk new file mode 100644 index 0000000..1dd487f --- /dev/null +++ b/cpp/cpp_prj/nbproject/Makefile-variables.mk @@ -0,0 +1,16 @@ +# +# Generated - do not edit! +# +# NOCDDL +# +CND_BASEDIR=`pwd` +CND_BUILDDIR=build +CND_DISTDIR=dist +# Default configuration +CND_PLATFORM_Default=GNU-Linux-x86 +CND_ARTIFACT_DIR_Default=.. +CND_ARTIFACT_NAME_Default=fusetest +CND_ARTIFACT_PATH_Default=../fusetest +CND_PACKAGE_DIR_Default=dist/Default/GNU-Linux-x86/package +CND_PACKAGE_NAME_Default=cppprj.tar +CND_PACKAGE_PATH_Default=dist/Default/GNU-Linux-x86/package/cppprj.tar diff --git a/cpp/cpp_prj/nbproject/Package-Default.bash b/cpp/cpp_prj/nbproject/Package-Default.bash new file mode 100644 index 0000000..d994f75 --- /dev/null +++ b/cpp/cpp_prj/nbproject/Package-Default.bash @@ -0,0 +1,74 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=GNU-Linux-x86 +CND_CONF=Default +CND_DISTDIR=dist +NBTMPDIR=build/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=../fusetest +OUTPUT_BASENAME=fusetest +PACKAGE_TOP_DIR=cppprj/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/cppprj/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/cppprj.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/cppprj.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/cpp/cpp_prj/nbproject/configurations.xml b/cpp/cpp_prj/nbproject/configurations.xml new file mode 100644 index 0000000..28dce16 --- /dev/null +++ b/cpp/cpp_prj/nbproject/configurations.xml @@ -0,0 +1,137 @@ + + + + + + Common.pb.cc + Common.pb.h + PBRPC.pb.cc + PBRPC.pb.h + + + Ping.pb.cc + Ping.pb.h + PingServiceClient.h + RPC.pb.cc + RPC.pb.h + + + DIR.pb.cc + DIR.pb.h + DIRServiceClient.h + GlobalTypes.pb.cc + GlobalTypes.pb.h + MRC.pb.cc + MRC.pb.h + MRCServiceClient.h + OSD.pb.cc + OSD.pb.h + OSDServiceClient.h + + + + + abstract_socket_channel.h + callback_interface.h + client.h + client_connection.h + client_request.h + client_request_callback_interface.h + grid_ssl_socket_channel.h + record_marker.h + ssl_options.h + ssl_socket_channel.h + sync_callback.h + tcp_socket_channel.h + + + logging.h + pbrpc_url.h + user_mapping.h + + + + + fuse_client.cpp + mkvol_xtreemfs.cpp + + + client.cpp + client_connection.cpp + client_request.cpp + record_marker.cpp + + + logging.cpp + pbrpc_url.cpp + user_mapping.cpp + + main.cpp + + + ../CMakeLists.txt + ../Makefile + cpp_prj-Makefile.mk + + + + ../src + ../generated + ../include + + cpp_prj-Makefile.mk + + + + localhost + GNU|GNU + 2 + + + + .. + ${MAKE} -f Makefile + ${MAKE} -f Makefile clean + ../fusetest + + + ../generated + ../include + + + + + + + + ../generated + + + + + + + ../generated + + + + + + + ../generated + + + + + + + ../include/rpc + + + + + + diff --git a/cpp/cpp_prj/nbproject/private/configurations.xml b/cpp/cpp_prj/nbproject/private/configurations.xml new file mode 100644 index 0000000..3a36d13 --- /dev/null +++ b/cpp/cpp_prj/nbproject/private/configurations.xml @@ -0,0 +1,21 @@ + + + cpp_prj-Makefile.mk + 0 + + + + + + /home/bjko/mnt + + true + 0 + 0 + 0 + + + + + + diff --git a/cpp/cpp_prj/nbproject/private/private.properties b/cpp/cpp_prj/nbproject/private/private.properties new file mode 100644 index 0000000..e69de29 diff --git a/cpp/cpp_prj/nbproject/private/private.xml b/cpp/cpp_prj/nbproject/private/private.xml new file mode 100644 index 0000000..bf91c93 --- /dev/null +++ b/cpp/cpp_prj/nbproject/private/private.xml @@ -0,0 +1,7 @@ + + + + true + + + diff --git a/cpp/cpp_prj/nbproject/project.properties b/cpp/cpp_prj/nbproject/project.properties new file mode 100644 index 0000000..e69de29 diff --git a/cpp/cpp_prj/nbproject/project.xml b/cpp/cpp_prj/nbproject/project.xml new file mode 100644 index 0000000..fa8dde0 --- /dev/null +++ b/cpp/cpp_prj/nbproject/project.xml @@ -0,0 +1,23 @@ + + + org.netbeans.modules.cnd.makeproject + + + cpp_prj + 0 + + cc,cpp + h + UTF-8 + + + ../src + ../generated + ../include + + + Default + + + + diff --git a/cpp/generated/include/Common.pb.cc b/cpp/generated/include/Common.pb.cc new file mode 100644 index 0000000..f2b1cec --- /dev/null +++ b/cpp/generated/include/Common.pb.cc @@ -0,0 +1,438 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: include/Common.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "include/Common.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +namespace { + +const ::google::protobuf::Descriptor* emptyRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + emptyRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* emptyResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + emptyResponse_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_include_2fCommon_2eproto() { + protobuf_AddDesc_include_2fCommon_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "include/Common.proto"); + GOOGLE_CHECK(file != NULL); + emptyRequest_descriptor_ = file->message_type(0); + static const int emptyRequest_offsets_[1] = { + }; + emptyRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + emptyRequest_descriptor_, + emptyRequest::default_instance_, + emptyRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(emptyRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(emptyRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(emptyRequest)); + emptyResponse_descriptor_ = file->message_type(1); + static const int emptyResponse_offsets_[1] = { + }; + emptyResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + emptyResponse_descriptor_, + emptyResponse::default_instance_, + emptyResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(emptyResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(emptyResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(emptyResponse)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_include_2fCommon_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + emptyRequest_descriptor_, &emptyRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + emptyResponse_descriptor_, &emptyResponse::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_include_2fCommon_2eproto() { + delete emptyRequest::default_instance_; + delete emptyRequest_reflection_; + delete emptyResponse::default_instance_; + delete emptyResponse_reflection_; +} + +void protobuf_AddDesc_include_2fCommon_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\024include/Common.proto\022\016xtreemfs.pbrpc\"\016" + "\n\014emptyRequest\"\017\n\remptyResponseB(\n&org.x" + "treemfs.pbrpc.generatedinterfaces", 113); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "include/Common.proto", &protobuf_RegisterTypes); + emptyRequest::default_instance_ = new emptyRequest(); + emptyResponse::default_instance_ = new emptyResponse(); + emptyRequest::default_instance_->InitAsDefaultInstance(); + emptyResponse::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_include_2fCommon_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_include_2fCommon_2eproto { + StaticDescriptorInitializer_include_2fCommon_2eproto() { + protobuf_AddDesc_include_2fCommon_2eproto(); + } +} static_descriptor_initializer_include_2fCommon_2eproto_; + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +emptyRequest::emptyRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void emptyRequest::InitAsDefaultInstance() { +} + +emptyRequest::emptyRequest(const emptyRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void emptyRequest::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +emptyRequest::~emptyRequest() { + SharedDtor(); +} + +void emptyRequest::SharedDtor() { + if (this != default_instance_) { + } +} + +void emptyRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* emptyRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return emptyRequest_descriptor_; +} + +const emptyRequest& emptyRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_include_2fCommon_2eproto(); + return *default_instance_; +} + +emptyRequest* emptyRequest::default_instance_ = NULL; + +emptyRequest* emptyRequest::New() const { + return new emptyRequest; +} + +void emptyRequest::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool emptyRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + } + return true; +#undef DO_ +} + +void emptyRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* emptyRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int emptyRequest::ByteSize() const { + int total_size = 0; + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void emptyRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const emptyRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void emptyRequest::MergeFrom(const emptyRequest& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void emptyRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void emptyRequest::CopyFrom(const emptyRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool emptyRequest::IsInitialized() const { + + return true; +} + +void emptyRequest::Swap(emptyRequest* other) { + if (other != this) { + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata emptyRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = emptyRequest_descriptor_; + metadata.reflection = emptyRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +emptyResponse::emptyResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void emptyResponse::InitAsDefaultInstance() { +} + +emptyResponse::emptyResponse(const emptyResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void emptyResponse::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +emptyResponse::~emptyResponse() { + SharedDtor(); +} + +void emptyResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void emptyResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* emptyResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return emptyResponse_descriptor_; +} + +const emptyResponse& emptyResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_include_2fCommon_2eproto(); + return *default_instance_; +} + +emptyResponse* emptyResponse::default_instance_ = NULL; + +emptyResponse* emptyResponse::New() const { + return new emptyResponse; +} + +void emptyResponse::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool emptyResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + } + return true; +#undef DO_ +} + +void emptyResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* emptyResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int emptyResponse::ByteSize() const { + int total_size = 0; + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void emptyResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const emptyResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void emptyResponse::MergeFrom(const emptyResponse& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void emptyResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void emptyResponse::CopyFrom(const emptyResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool emptyResponse::IsInitialized() const { + + return true; +} + +void emptyResponse::Swap(emptyResponse* other) { + if (other != this) { + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata emptyResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = emptyResponse_descriptor_; + metadata.reflection = emptyResponse_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/generated/include/Common.pb.h b/cpp/generated/include/Common.pb.h new file mode 100644 index 0000000..f7e9eb2 --- /dev/null +++ b/cpp/generated/include/Common.pb.h @@ -0,0 +1,212 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: include/Common.proto + +#ifndef PROTOBUF_include_2fCommon_2eproto__INCLUDED +#define PROTOBUF_include_2fCommon_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_include_2fCommon_2eproto(); +void protobuf_AssignDesc_include_2fCommon_2eproto(); +void protobuf_ShutdownFile_include_2fCommon_2eproto(); + +class emptyRequest; +class emptyResponse; + +// =================================================================== + +class emptyRequest : public ::google::protobuf::Message { + public: + emptyRequest(); + virtual ~emptyRequest(); + + emptyRequest(const emptyRequest& from); + + inline emptyRequest& operator=(const emptyRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const emptyRequest& default_instance(); + + void Swap(emptyRequest* other); + + // implements Message ---------------------------------------------- + + emptyRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const emptyRequest& from); + void MergeFrom(const emptyRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.emptyRequest) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[1]; + + friend void protobuf_AddDesc_include_2fCommon_2eproto(); + friend void protobuf_AssignDesc_include_2fCommon_2eproto(); + friend void protobuf_ShutdownFile_include_2fCommon_2eproto(); + + void InitAsDefaultInstance(); + static emptyRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class emptyResponse : public ::google::protobuf::Message { + public: + emptyResponse(); + virtual ~emptyResponse(); + + emptyResponse(const emptyResponse& from); + + inline emptyResponse& operator=(const emptyResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const emptyResponse& default_instance(); + + void Swap(emptyResponse* other); + + // implements Message ---------------------------------------------- + + emptyResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const emptyResponse& from); + void MergeFrom(const emptyResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.emptyResponse) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[1]; + + friend void protobuf_AddDesc_include_2fCommon_2eproto(); + friend void protobuf_AssignDesc_include_2fCommon_2eproto(); + friend void protobuf_ShutdownFile_include_2fCommon_2eproto(); + + void InitAsDefaultInstance(); + static emptyResponse* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// emptyRequest + +// ------------------------------------------------------------------- + +// emptyResponse + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_include_2fCommon_2eproto__INCLUDED diff --git a/cpp/generated/include/PBRPC.pb.cc b/cpp/generated/include/PBRPC.pb.cc new file mode 100644 index 0000000..c6f0748 --- /dev/null +++ b/cpp/generated/include/PBRPC.pb.cc @@ -0,0 +1,111 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: include/PBRPC.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "include/PBRPC.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +namespace { + + +} // namespace + + +void protobuf_AssignDesc_include_2fPBRPC_2eproto() { + protobuf_AddDesc_include_2fPBRPC_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "include/PBRPC.proto"); + GOOGLE_CHECK(file != NULL); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_include_2fPBRPC_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); +} + +} // namespace + +void protobuf_ShutdownFile_include_2fPBRPC_2eproto() { +} + +void protobuf_AddDesc_include_2fPBRPC_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\023include/PBRPC.proto\022\016xtreemfs.pbrpc\032 g" + "oogle/protobuf/descriptor.proto:1\n\007proc_" + "id\022\036.google.protobuf.MethodOptions\030\321\206\003 \001" + "(\007:1\n\007data_in\022\036.google.protobuf.MethodOp" + "tions\030\324\206\003 \001(\010:2\n\010data_out\022\036.google.proto" + "buf.MethodOptions\030\323\206\003 \001(\010:7\n\014interface_i" + "d\022\037.google.protobuf.ServiceOptions\030\322\206\003 \001" + "(\007B3\n1org.xtreemfs.foundation.pbrpc.gene" + "ratedinterfaces", 335); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "include/PBRPC.proto", &protobuf_RegisterTypes); + ::google::protobuf::internal::ExtensionSet::RegisterExtension( + &::google::protobuf::MethodOptions::default_instance(), + 50001, 7, false, false); + ::google::protobuf::internal::ExtensionSet::RegisterExtension( + &::google::protobuf::MethodOptions::default_instance(), + 50004, 8, false, false); + ::google::protobuf::internal::ExtensionSet::RegisterExtension( + &::google::protobuf::MethodOptions::default_instance(), + 50003, 8, false, false); + ::google::protobuf::internal::ExtensionSet::RegisterExtension( + &::google::protobuf::ServiceOptions::default_instance(), + 50002, 7, false, false); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_include_2fPBRPC_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_include_2fPBRPC_2eproto { + StaticDescriptorInitializer_include_2fPBRPC_2eproto() { + protobuf_AddDesc_include_2fPBRPC_2eproto(); + } +} static_descriptor_initializer_include_2fPBRPC_2eproto_; +::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 7, false > + proc_id(kProcIdFieldNumber, 0u); +::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< bool >, 8, false > + data_in(kDataInFieldNumber, false); +::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< bool >, 8, false > + data_out(kDataOutFieldNumber, false); +::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::ServiceOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 7, false > + interface_id(kInterfaceIdFieldNumber, 0u); + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/generated/include/PBRPC.pb.h b/cpp/generated/include/PBRPC.pb.h new file mode 100644 index 0000000..1151f71 --- /dev/null +++ b/cpp/generated/include/PBRPC.pb.h @@ -0,0 +1,78 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: include/PBRPC.proto + +#ifndef PROTOBUF_include_2fPBRPC_2eproto__INCLUDED +#define PROTOBUF_include_2fPBRPC_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include "google/protobuf/descriptor.pb.h" +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_include_2fPBRPC_2eproto(); +void protobuf_AssignDesc_include_2fPBRPC_2eproto(); +void protobuf_ShutdownFile_include_2fPBRPC_2eproto(); + + +// =================================================================== + + +// =================================================================== + +static const int kProcIdFieldNumber = 50001; +extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 7, false > + proc_id; +static const int kDataInFieldNumber = 50004; +extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< bool >, 8, false > + data_in; +static const int kDataOutFieldNumber = 50003; +extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< bool >, 8, false > + data_out; +static const int kInterfaceIdFieldNumber = 50002; +extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::ServiceOptions, + ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 7, false > + interface_id; + +// =================================================================== + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_include_2fPBRPC_2eproto__INCLUDED diff --git a/cpp/generated/pbrpc/Ping.pb.cc b/cpp/generated/pbrpc/Ping.pb.cc new file mode 100644 index 0000000..e90bd96 --- /dev/null +++ b/cpp/generated/pbrpc/Ping.pb.cc @@ -0,0 +1,1529 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: pbrpc/Ping.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "pbrpc/Ping.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +namespace { + +const ::google::protobuf::Descriptor* PingRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + PingRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* PingResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + PingResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* PingResponse_PingResult_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + PingResponse_PingResult_reflection_ = NULL; +const ::google::protobuf::Descriptor* PingResponse_PingError_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + PingResponse_PingError_reflection_ = NULL; +const ::google::protobuf::Descriptor* Ping_emptyRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Ping_emptyRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* Ping_emptyResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Ping_emptyResponse_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_pbrpc_2fPing_2eproto() { + protobuf_AddDesc_pbrpc_2fPing_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "pbrpc/Ping.proto"); + GOOGLE_CHECK(file != NULL); + PingRequest_descriptor_ = file->message_type(0); + static const int PingRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingRequest, text_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingRequest, senderror_), + }; + PingRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + PingRequest_descriptor_, + PingRequest::default_instance_, + PingRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(PingRequest)); + PingResponse_descriptor_ = file->message_type(1); + static const int PingResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingResponse, result_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingResponse, error_), + }; + PingResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + PingResponse_descriptor_, + PingResponse::default_instance_, + PingResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(PingResponse)); + PingResponse_PingResult_descriptor_ = PingResponse_descriptor_->nested_type(0); + static const int PingResponse_PingResult_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingResponse_PingResult, text_), + }; + PingResponse_PingResult_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + PingResponse_PingResult_descriptor_, + PingResponse_PingResult::default_instance_, + PingResponse_PingResult_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingResponse_PingResult, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingResponse_PingResult, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(PingResponse_PingResult)); + PingResponse_PingError_descriptor_ = PingResponse_descriptor_->nested_type(1); + static const int PingResponse_PingError_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingResponse_PingError, errormessage_), + }; + PingResponse_PingError_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + PingResponse_PingError_descriptor_, + PingResponse_PingError::default_instance_, + PingResponse_PingError_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingResponse_PingError, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PingResponse_PingError, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(PingResponse_PingError)); + Ping_emptyRequest_descriptor_ = file->message_type(2); + static const int Ping_emptyRequest_offsets_[1] = { + }; + Ping_emptyRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Ping_emptyRequest_descriptor_, + Ping_emptyRequest::default_instance_, + Ping_emptyRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Ping_emptyRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Ping_emptyRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Ping_emptyRequest)); + Ping_emptyResponse_descriptor_ = file->message_type(3); + static const int Ping_emptyResponse_offsets_[1] = { + }; + Ping_emptyResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Ping_emptyResponse_descriptor_, + Ping_emptyResponse::default_instance_, + Ping_emptyResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Ping_emptyResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Ping_emptyResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Ping_emptyResponse)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_pbrpc_2fPing_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + PingRequest_descriptor_, &PingRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + PingResponse_descriptor_, &PingResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + PingResponse_PingResult_descriptor_, &PingResponse_PingResult::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + PingResponse_PingError_descriptor_, &PingResponse_PingError::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Ping_emptyRequest_descriptor_, &Ping_emptyRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Ping_emptyResponse_descriptor_, &Ping_emptyResponse::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_pbrpc_2fPing_2eproto() { + delete PingRequest::default_instance_; + delete PingRequest_reflection_; + delete PingResponse::default_instance_; + delete PingResponse_reflection_; + delete PingResponse_PingResult::default_instance_; + delete PingResponse_PingResult_reflection_; + delete PingResponse_PingError::default_instance_; + delete PingResponse_PingError_reflection_; + delete Ping_emptyRequest::default_instance_; + delete Ping_emptyRequest_reflection_; + delete Ping_emptyResponse::default_instance_; + delete Ping_emptyResponse_reflection_; +} + +void protobuf_AddDesc_pbrpc_2fPing_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::xtreemfs::pbrpc::protobuf_AddDesc_include_2fPBRPC_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\020pbrpc/Ping.proto\022\016xtreemfs.pbrpc\032\023incl" + "ude/PBRPC.proto\".\n\013PingRequest\022\014\n\004text\030\001" + " \002(\t\022\021\n\tsendError\030\002 \002(\010\"\275\001\n\014PingResponse" + "\0227\n\006result\030\001 \001(\0132\'.xtreemfs.pbrpc.PingRe" + "sponse.PingResult\0225\n\005error\030\002 \001(\0132&.xtree" + "mfs.pbrpc.PingResponse.PingError\032\032\n\nPing" + "Result\022\014\n\004text\030\001 \002(\t\032!\n\tPingError\022\024\n\014err" + "orMessage\030\001 \002(\t\"\023\n\021Ping_emptyRequest\"\024\n\022" + "Ping_emptyResponse2\305\001\n\013PingService\022P\n\006do" + "Ping\022\033.xtreemfs.pbrpc.PingRequest\032\034.xtre" + "emfs.pbrpc.PingResponse\"\013\215\265\030\001\000\000\000\240\265\030\001\022[\n\t" + "emptyPing\022!.xtreemfs.pbrpc.Ping_emptyReq" + "uest\032\".xtreemfs.pbrpc.Ping_emptyResponse" + "\"\007\215\265\030\002\000\000\000\032\007\225\265\030\001\000\000\000B3\n1org.xtreemfs.found" + "ation.pbrpc.generatedinterfaces", 591); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "pbrpc/Ping.proto", &protobuf_RegisterTypes); + PingRequest::default_instance_ = new PingRequest(); + PingResponse::default_instance_ = new PingResponse(); + PingResponse_PingResult::default_instance_ = new PingResponse_PingResult(); + PingResponse_PingError::default_instance_ = new PingResponse_PingError(); + Ping_emptyRequest::default_instance_ = new Ping_emptyRequest(); + Ping_emptyResponse::default_instance_ = new Ping_emptyResponse(); + PingRequest::default_instance_->InitAsDefaultInstance(); + PingResponse::default_instance_->InitAsDefaultInstance(); + PingResponse_PingResult::default_instance_->InitAsDefaultInstance(); + PingResponse_PingError::default_instance_->InitAsDefaultInstance(); + Ping_emptyRequest::default_instance_->InitAsDefaultInstance(); + Ping_emptyResponse::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_pbrpc_2fPing_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_pbrpc_2fPing_2eproto { + StaticDescriptorInitializer_pbrpc_2fPing_2eproto() { + protobuf_AddDesc_pbrpc_2fPing_2eproto(); + } +} static_descriptor_initializer_pbrpc_2fPing_2eproto_; + +// =================================================================== + +#ifndef _MSC_VER +const int PingRequest::kTextFieldNumber; +const int PingRequest::kSendErrorFieldNumber; +#endif // !_MSC_VER + +PingRequest::PingRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void PingRequest::InitAsDefaultInstance() { +} + +PingRequest::PingRequest(const PingRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void PingRequest::SharedCtor() { + _cached_size_ = 0; + text_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + senderror_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +PingRequest::~PingRequest() { + SharedDtor(); +} + +void PingRequest::SharedDtor() { + if (text_ != &::google::protobuf::internal::kEmptyString) { + delete text_; + } + if (this != default_instance_) { + } +} + +void PingRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* PingRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return PingRequest_descriptor_; +} + +const PingRequest& PingRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fPing_2eproto(); + return *default_instance_; +} + +PingRequest* PingRequest::default_instance_ = NULL; + +PingRequest* PingRequest::New() const { + return new PingRequest; +} + +void PingRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_text()) { + if (text_ != &::google::protobuf::internal::kEmptyString) { + text_->clear(); + } + } + senderror_ = false; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool PingRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string text = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_text())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->text().data(), this->text().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_sendError; + break; + } + + // required bool sendError = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_sendError: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &senderror_))); + set_has_senderror(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void PingRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string text = 1; + if (has_text()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->text().data(), this->text().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->text(), output); + } + + // required bool sendError = 2; + if (has_senderror()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->senderror(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* PingRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string text = 1; + if (has_text()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->text().data(), this->text().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->text(), target); + } + + // required bool sendError = 2; + if (has_senderror()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->senderror(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int PingRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string text = 1; + if (has_text()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->text()); + } + + // required bool sendError = 2; + if (has_senderror()) { + total_size += 1 + 1; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void PingRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const PingRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void PingRequest::MergeFrom(const PingRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_text()) { + set_text(from.text()); + } + if (from.has_senderror()) { + set_senderror(from.senderror()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void PingRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void PingRequest::CopyFrom(const PingRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool PingRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void PingRequest::Swap(PingRequest* other) { + if (other != this) { + std::swap(text_, other->text_); + std::swap(senderror_, other->senderror_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata PingRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = PingRequest_descriptor_; + metadata.reflection = PingRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int PingResponse_PingResult::kTextFieldNumber; +#endif // !_MSC_VER + +PingResponse_PingResult::PingResponse_PingResult() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void PingResponse_PingResult::InitAsDefaultInstance() { +} + +PingResponse_PingResult::PingResponse_PingResult(const PingResponse_PingResult& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void PingResponse_PingResult::SharedCtor() { + _cached_size_ = 0; + text_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +PingResponse_PingResult::~PingResponse_PingResult() { + SharedDtor(); +} + +void PingResponse_PingResult::SharedDtor() { + if (text_ != &::google::protobuf::internal::kEmptyString) { + delete text_; + } + if (this != default_instance_) { + } +} + +void PingResponse_PingResult::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* PingResponse_PingResult::descriptor() { + protobuf_AssignDescriptorsOnce(); + return PingResponse_PingResult_descriptor_; +} + +const PingResponse_PingResult& PingResponse_PingResult::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fPing_2eproto(); + return *default_instance_; +} + +PingResponse_PingResult* PingResponse_PingResult::default_instance_ = NULL; + +PingResponse_PingResult* PingResponse_PingResult::New() const { + return new PingResponse_PingResult; +} + +void PingResponse_PingResult::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_text()) { + if (text_ != &::google::protobuf::internal::kEmptyString) { + text_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool PingResponse_PingResult::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string text = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_text())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->text().data(), this->text().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void PingResponse_PingResult::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string text = 1; + if (has_text()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->text().data(), this->text().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->text(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* PingResponse_PingResult::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string text = 1; + if (has_text()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->text().data(), this->text().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->text(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int PingResponse_PingResult::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string text = 1; + if (has_text()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->text()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void PingResponse_PingResult::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const PingResponse_PingResult* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void PingResponse_PingResult::MergeFrom(const PingResponse_PingResult& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_text()) { + set_text(from.text()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void PingResponse_PingResult::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void PingResponse_PingResult::CopyFrom(const PingResponse_PingResult& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool PingResponse_PingResult::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void PingResponse_PingResult::Swap(PingResponse_PingResult* other) { + if (other != this) { + std::swap(text_, other->text_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata PingResponse_PingResult::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = PingResponse_PingResult_descriptor_; + metadata.reflection = PingResponse_PingResult_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#ifndef _MSC_VER +const int PingResponse_PingError::kErrorMessageFieldNumber; +#endif // !_MSC_VER + +PingResponse_PingError::PingResponse_PingError() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void PingResponse_PingError::InitAsDefaultInstance() { +} + +PingResponse_PingError::PingResponse_PingError(const PingResponse_PingError& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void PingResponse_PingError::SharedCtor() { + _cached_size_ = 0; + errormessage_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +PingResponse_PingError::~PingResponse_PingError() { + SharedDtor(); +} + +void PingResponse_PingError::SharedDtor() { + if (errormessage_ != &::google::protobuf::internal::kEmptyString) { + delete errormessage_; + } + if (this != default_instance_) { + } +} + +void PingResponse_PingError::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* PingResponse_PingError::descriptor() { + protobuf_AssignDescriptorsOnce(); + return PingResponse_PingError_descriptor_; +} + +const PingResponse_PingError& PingResponse_PingError::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fPing_2eproto(); + return *default_instance_; +} + +PingResponse_PingError* PingResponse_PingError::default_instance_ = NULL; + +PingResponse_PingError* PingResponse_PingError::New() const { + return new PingResponse_PingError; +} + +void PingResponse_PingError::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_errormessage()) { + if (errormessage_ != &::google::protobuf::internal::kEmptyString) { + errormessage_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool PingResponse_PingError::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string errorMessage = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_errormessage())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->errormessage().data(), this->errormessage().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void PingResponse_PingError::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string errorMessage = 1; + if (has_errormessage()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->errormessage().data(), this->errormessage().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->errormessage(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* PingResponse_PingError::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string errorMessage = 1; + if (has_errormessage()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->errormessage().data(), this->errormessage().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->errormessage(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int PingResponse_PingError::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string errorMessage = 1; + if (has_errormessage()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->errormessage()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void PingResponse_PingError::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const PingResponse_PingError* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void PingResponse_PingError::MergeFrom(const PingResponse_PingError& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_errormessage()) { + set_errormessage(from.errormessage()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void PingResponse_PingError::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void PingResponse_PingError::CopyFrom(const PingResponse_PingError& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool PingResponse_PingError::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void PingResponse_PingError::Swap(PingResponse_PingError* other) { + if (other != this) { + std::swap(errormessage_, other->errormessage_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata PingResponse_PingError::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = PingResponse_PingError_descriptor_; + metadata.reflection = PingResponse_PingError_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#ifndef _MSC_VER +const int PingResponse::kResultFieldNumber; +const int PingResponse::kErrorFieldNumber; +#endif // !_MSC_VER + +PingResponse::PingResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void PingResponse::InitAsDefaultInstance() { + result_ = const_cast< ::xtreemfs::pbrpc::PingResponse_PingResult*>(&::xtreemfs::pbrpc::PingResponse_PingResult::default_instance()); + error_ = const_cast< ::xtreemfs::pbrpc::PingResponse_PingError*>(&::xtreemfs::pbrpc::PingResponse_PingError::default_instance()); +} + +PingResponse::PingResponse(const PingResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void PingResponse::SharedCtor() { + _cached_size_ = 0; + result_ = NULL; + error_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +PingResponse::~PingResponse() { + SharedDtor(); +} + +void PingResponse::SharedDtor() { + if (this != default_instance_) { + delete result_; + delete error_; + } +} + +void PingResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* PingResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return PingResponse_descriptor_; +} + +const PingResponse& PingResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fPing_2eproto(); + return *default_instance_; +} + +PingResponse* PingResponse::default_instance_ = NULL; + +PingResponse* PingResponse::New() const { + return new PingResponse; +} + +void PingResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_result()) { + if (result_ != NULL) result_->::xtreemfs::pbrpc::PingResponse_PingResult::Clear(); + } + if (has_error()) { + if (error_ != NULL) error_->::xtreemfs::pbrpc::PingResponse_PingError::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool PingResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_result())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_error; + break; + } + + // optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_error: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_error())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void PingResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + if (has_result()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->result(), output); + } + + // optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + if (has_error()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->error(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* PingResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + if (has_result()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->result(), target); + } + + // optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + if (has_error()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->error(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int PingResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + if (has_result()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->result()); + } + + // optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + if (has_error()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->error()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void PingResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const PingResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void PingResponse::MergeFrom(const PingResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_result()) { + mutable_result()->::xtreemfs::pbrpc::PingResponse_PingResult::MergeFrom(from.result()); + } + if (from.has_error()) { + mutable_error()->::xtreemfs::pbrpc::PingResponse_PingError::MergeFrom(from.error()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void PingResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void PingResponse::CopyFrom(const PingResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool PingResponse::IsInitialized() const { + + if (has_result()) { + if (!this->result().IsInitialized()) return false; + } + if (has_error()) { + if (!this->error().IsInitialized()) return false; + } + return true; +} + +void PingResponse::Swap(PingResponse* other) { + if (other != this) { + std::swap(result_, other->result_); + std::swap(error_, other->error_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata PingResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = PingResponse_descriptor_; + metadata.reflection = PingResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +Ping_emptyRequest::Ping_emptyRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Ping_emptyRequest::InitAsDefaultInstance() { +} + +Ping_emptyRequest::Ping_emptyRequest(const Ping_emptyRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Ping_emptyRequest::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Ping_emptyRequest::~Ping_emptyRequest() { + SharedDtor(); +} + +void Ping_emptyRequest::SharedDtor() { + if (this != default_instance_) { + } +} + +void Ping_emptyRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Ping_emptyRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Ping_emptyRequest_descriptor_; +} + +const Ping_emptyRequest& Ping_emptyRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fPing_2eproto(); + return *default_instance_; +} + +Ping_emptyRequest* Ping_emptyRequest::default_instance_ = NULL; + +Ping_emptyRequest* Ping_emptyRequest::New() const { + return new Ping_emptyRequest; +} + +void Ping_emptyRequest::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Ping_emptyRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + } + return true; +#undef DO_ +} + +void Ping_emptyRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Ping_emptyRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Ping_emptyRequest::ByteSize() const { + int total_size = 0; + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Ping_emptyRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Ping_emptyRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Ping_emptyRequest::MergeFrom(const Ping_emptyRequest& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Ping_emptyRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Ping_emptyRequest::CopyFrom(const Ping_emptyRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Ping_emptyRequest::IsInitialized() const { + + return true; +} + +void Ping_emptyRequest::Swap(Ping_emptyRequest* other) { + if (other != this) { + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Ping_emptyRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Ping_emptyRequest_descriptor_; + metadata.reflection = Ping_emptyRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +Ping_emptyResponse::Ping_emptyResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Ping_emptyResponse::InitAsDefaultInstance() { +} + +Ping_emptyResponse::Ping_emptyResponse(const Ping_emptyResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Ping_emptyResponse::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Ping_emptyResponse::~Ping_emptyResponse() { + SharedDtor(); +} + +void Ping_emptyResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void Ping_emptyResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Ping_emptyResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Ping_emptyResponse_descriptor_; +} + +const Ping_emptyResponse& Ping_emptyResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fPing_2eproto(); + return *default_instance_; +} + +Ping_emptyResponse* Ping_emptyResponse::default_instance_ = NULL; + +Ping_emptyResponse* Ping_emptyResponse::New() const { + return new Ping_emptyResponse; +} + +void Ping_emptyResponse::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Ping_emptyResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + } + return true; +#undef DO_ +} + +void Ping_emptyResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Ping_emptyResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Ping_emptyResponse::ByteSize() const { + int total_size = 0; + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Ping_emptyResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Ping_emptyResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Ping_emptyResponse::MergeFrom(const Ping_emptyResponse& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Ping_emptyResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Ping_emptyResponse::CopyFrom(const Ping_emptyResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Ping_emptyResponse::IsInitialized() const { + + return true; +} + +void Ping_emptyResponse::Swap(Ping_emptyResponse* other) { + if (other != this) { + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Ping_emptyResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Ping_emptyResponse_descriptor_; + metadata.reflection = Ping_emptyResponse_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/generated/pbrpc/Ping.pb.h b/cpp/generated/pbrpc/Ping.pb.h new file mode 100644 index 0000000..5e9c266 --- /dev/null +++ b/cpp/generated/pbrpc/Ping.pb.h @@ -0,0 +1,911 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: pbrpc/Ping.proto + +#ifndef PROTOBUF_pbrpc_2fPing_2eproto__INCLUDED +#define PROTOBUF_pbrpc_2fPing_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include "include/PBRPC.pb.h" +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_pbrpc_2fPing_2eproto(); +void protobuf_AssignDesc_pbrpc_2fPing_2eproto(); +void protobuf_ShutdownFile_pbrpc_2fPing_2eproto(); + +class PingRequest; +class PingResponse; +class PingResponse_PingResult; +class PingResponse_PingError; +class Ping_emptyRequest; +class Ping_emptyResponse; + +// =================================================================== + +class PingRequest : public ::google::protobuf::Message { + public: + PingRequest(); + virtual ~PingRequest(); + + PingRequest(const PingRequest& from); + + inline PingRequest& operator=(const PingRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const PingRequest& default_instance(); + + void Swap(PingRequest* other); + + // implements Message ---------------------------------------------- + + PingRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const PingRequest& from); + void MergeFrom(const PingRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string text = 1; + inline bool has_text() const; + inline void clear_text(); + static const int kTextFieldNumber = 1; + inline const ::std::string& text() const; + inline void set_text(const ::std::string& value); + inline void set_text(const char* value); + inline void set_text(const char* value, size_t size); + inline ::std::string* mutable_text(); + inline ::std::string* release_text(); + inline void set_allocated_text(::std::string* text); + + // required bool sendError = 2; + inline bool has_senderror() const; + inline void clear_senderror(); + static const int kSendErrorFieldNumber = 2; + inline bool senderror() const; + inline void set_senderror(bool value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.PingRequest) + private: + inline void set_has_text(); + inline void clear_has_text(); + inline void set_has_senderror(); + inline void clear_has_senderror(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* text_; + bool senderror_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fPing_2eproto(); + + void InitAsDefaultInstance(); + static PingRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class PingResponse_PingResult : public ::google::protobuf::Message { + public: + PingResponse_PingResult(); + virtual ~PingResponse_PingResult(); + + PingResponse_PingResult(const PingResponse_PingResult& from); + + inline PingResponse_PingResult& operator=(const PingResponse_PingResult& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const PingResponse_PingResult& default_instance(); + + void Swap(PingResponse_PingResult* other); + + // implements Message ---------------------------------------------- + + PingResponse_PingResult* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const PingResponse_PingResult& from); + void MergeFrom(const PingResponse_PingResult& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string text = 1; + inline bool has_text() const; + inline void clear_text(); + static const int kTextFieldNumber = 1; + inline const ::std::string& text() const; + inline void set_text(const ::std::string& value); + inline void set_text(const char* value); + inline void set_text(const char* value, size_t size); + inline ::std::string* mutable_text(); + inline ::std::string* release_text(); + inline void set_allocated_text(::std::string* text); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.PingResponse.PingResult) + private: + inline void set_has_text(); + inline void clear_has_text(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* text_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fPing_2eproto(); + + void InitAsDefaultInstance(); + static PingResponse_PingResult* default_instance_; +}; +// ------------------------------------------------------------------- + +class PingResponse_PingError : public ::google::protobuf::Message { + public: + PingResponse_PingError(); + virtual ~PingResponse_PingError(); + + PingResponse_PingError(const PingResponse_PingError& from); + + inline PingResponse_PingError& operator=(const PingResponse_PingError& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const PingResponse_PingError& default_instance(); + + void Swap(PingResponse_PingError* other); + + // implements Message ---------------------------------------------- + + PingResponse_PingError* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const PingResponse_PingError& from); + void MergeFrom(const PingResponse_PingError& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string errorMessage = 1; + inline bool has_errormessage() const; + inline void clear_errormessage(); + static const int kErrorMessageFieldNumber = 1; + inline const ::std::string& errormessage() const; + inline void set_errormessage(const ::std::string& value); + inline void set_errormessage(const char* value); + inline void set_errormessage(const char* value, size_t size); + inline ::std::string* mutable_errormessage(); + inline ::std::string* release_errormessage(); + inline void set_allocated_errormessage(::std::string* errormessage); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.PingResponse.PingError) + private: + inline void set_has_errormessage(); + inline void clear_has_errormessage(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* errormessage_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fPing_2eproto(); + + void InitAsDefaultInstance(); + static PingResponse_PingError* default_instance_; +}; +// ------------------------------------------------------------------- + +class PingResponse : public ::google::protobuf::Message { + public: + PingResponse(); + virtual ~PingResponse(); + + PingResponse(const PingResponse& from); + + inline PingResponse& operator=(const PingResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const PingResponse& default_instance(); + + void Swap(PingResponse* other); + + // implements Message ---------------------------------------------- + + PingResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const PingResponse& from); + void MergeFrom(const PingResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef PingResponse_PingResult PingResult; + typedef PingResponse_PingError PingError; + + // accessors ------------------------------------------------------- + + // optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + inline bool has_result() const; + inline void clear_result(); + static const int kResultFieldNumber = 1; + inline const ::xtreemfs::pbrpc::PingResponse_PingResult& result() const; + inline ::xtreemfs::pbrpc::PingResponse_PingResult* mutable_result(); + inline ::xtreemfs::pbrpc::PingResponse_PingResult* release_result(); + inline void set_allocated_result(::xtreemfs::pbrpc::PingResponse_PingResult* result); + + // optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + inline bool has_error() const; + inline void clear_error(); + static const int kErrorFieldNumber = 2; + inline const ::xtreemfs::pbrpc::PingResponse_PingError& error() const; + inline ::xtreemfs::pbrpc::PingResponse_PingError* mutable_error(); + inline ::xtreemfs::pbrpc::PingResponse_PingError* release_error(); + inline void set_allocated_error(::xtreemfs::pbrpc::PingResponse_PingError* error); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.PingResponse) + private: + inline void set_has_result(); + inline void clear_has_result(); + inline void set_has_error(); + inline void clear_has_error(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::PingResponse_PingResult* result_; + ::xtreemfs::pbrpc::PingResponse_PingError* error_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fPing_2eproto(); + + void InitAsDefaultInstance(); + static PingResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class Ping_emptyRequest : public ::google::protobuf::Message { + public: + Ping_emptyRequest(); + virtual ~Ping_emptyRequest(); + + Ping_emptyRequest(const Ping_emptyRequest& from); + + inline Ping_emptyRequest& operator=(const Ping_emptyRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Ping_emptyRequest& default_instance(); + + void Swap(Ping_emptyRequest* other); + + // implements Message ---------------------------------------------- + + Ping_emptyRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Ping_emptyRequest& from); + void MergeFrom(const Ping_emptyRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Ping_emptyRequest) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[1]; + + friend void protobuf_AddDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fPing_2eproto(); + + void InitAsDefaultInstance(); + static Ping_emptyRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class Ping_emptyResponse : public ::google::protobuf::Message { + public: + Ping_emptyResponse(); + virtual ~Ping_emptyResponse(); + + Ping_emptyResponse(const Ping_emptyResponse& from); + + inline Ping_emptyResponse& operator=(const Ping_emptyResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Ping_emptyResponse& default_instance(); + + void Swap(Ping_emptyResponse* other); + + // implements Message ---------------------------------------------- + + Ping_emptyResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Ping_emptyResponse& from); + void MergeFrom(const Ping_emptyResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Ping_emptyResponse) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[1]; + + friend void protobuf_AddDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fPing_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fPing_2eproto(); + + void InitAsDefaultInstance(); + static Ping_emptyResponse* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// PingRequest + +// required string text = 1; +inline bool PingRequest::has_text() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void PingRequest::set_has_text() { + _has_bits_[0] |= 0x00000001u; +} +inline void PingRequest::clear_has_text() { + _has_bits_[0] &= ~0x00000001u; +} +inline void PingRequest::clear_text() { + if (text_ != &::google::protobuf::internal::kEmptyString) { + text_->clear(); + } + clear_has_text(); +} +inline const ::std::string& PingRequest::text() const { + return *text_; +} +inline void PingRequest::set_text(const ::std::string& value) { + set_has_text(); + if (text_ == &::google::protobuf::internal::kEmptyString) { + text_ = new ::std::string; + } + text_->assign(value); +} +inline void PingRequest::set_text(const char* value) { + set_has_text(); + if (text_ == &::google::protobuf::internal::kEmptyString) { + text_ = new ::std::string; + } + text_->assign(value); +} +inline void PingRequest::set_text(const char* value, size_t size) { + set_has_text(); + if (text_ == &::google::protobuf::internal::kEmptyString) { + text_ = new ::std::string; + } + text_->assign(reinterpret_cast(value), size); +} +inline ::std::string* PingRequest::mutable_text() { + set_has_text(); + if (text_ == &::google::protobuf::internal::kEmptyString) { + text_ = new ::std::string; + } + return text_; +} +inline ::std::string* PingRequest::release_text() { + clear_has_text(); + if (text_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = text_; + text_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void PingRequest::set_allocated_text(::std::string* text) { + if (text_ != &::google::protobuf::internal::kEmptyString) { + delete text_; + } + if (text) { + set_has_text(); + text_ = text; + } else { + clear_has_text(); + text_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required bool sendError = 2; +inline bool PingRequest::has_senderror() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void PingRequest::set_has_senderror() { + _has_bits_[0] |= 0x00000002u; +} +inline void PingRequest::clear_has_senderror() { + _has_bits_[0] &= ~0x00000002u; +} +inline void PingRequest::clear_senderror() { + senderror_ = false; + clear_has_senderror(); +} +inline bool PingRequest::senderror() const { + return senderror_; +} +inline void PingRequest::set_senderror(bool value) { + set_has_senderror(); + senderror_ = value; +} + +// ------------------------------------------------------------------- + +// PingResponse_PingResult + +// required string text = 1; +inline bool PingResponse_PingResult::has_text() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void PingResponse_PingResult::set_has_text() { + _has_bits_[0] |= 0x00000001u; +} +inline void PingResponse_PingResult::clear_has_text() { + _has_bits_[0] &= ~0x00000001u; +} +inline void PingResponse_PingResult::clear_text() { + if (text_ != &::google::protobuf::internal::kEmptyString) { + text_->clear(); + } + clear_has_text(); +} +inline const ::std::string& PingResponse_PingResult::text() const { + return *text_; +} +inline void PingResponse_PingResult::set_text(const ::std::string& value) { + set_has_text(); + if (text_ == &::google::protobuf::internal::kEmptyString) { + text_ = new ::std::string; + } + text_->assign(value); +} +inline void PingResponse_PingResult::set_text(const char* value) { + set_has_text(); + if (text_ == &::google::protobuf::internal::kEmptyString) { + text_ = new ::std::string; + } + text_->assign(value); +} +inline void PingResponse_PingResult::set_text(const char* value, size_t size) { + set_has_text(); + if (text_ == &::google::protobuf::internal::kEmptyString) { + text_ = new ::std::string; + } + text_->assign(reinterpret_cast(value), size); +} +inline ::std::string* PingResponse_PingResult::mutable_text() { + set_has_text(); + if (text_ == &::google::protobuf::internal::kEmptyString) { + text_ = new ::std::string; + } + return text_; +} +inline ::std::string* PingResponse_PingResult::release_text() { + clear_has_text(); + if (text_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = text_; + text_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void PingResponse_PingResult::set_allocated_text(::std::string* text) { + if (text_ != &::google::protobuf::internal::kEmptyString) { + delete text_; + } + if (text) { + set_has_text(); + text_ = text; + } else { + clear_has_text(); + text_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// PingResponse_PingError + +// required string errorMessage = 1; +inline bool PingResponse_PingError::has_errormessage() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void PingResponse_PingError::set_has_errormessage() { + _has_bits_[0] |= 0x00000001u; +} +inline void PingResponse_PingError::clear_has_errormessage() { + _has_bits_[0] &= ~0x00000001u; +} +inline void PingResponse_PingError::clear_errormessage() { + if (errormessage_ != &::google::protobuf::internal::kEmptyString) { + errormessage_->clear(); + } + clear_has_errormessage(); +} +inline const ::std::string& PingResponse_PingError::errormessage() const { + return *errormessage_; +} +inline void PingResponse_PingError::set_errormessage(const ::std::string& value) { + set_has_errormessage(); + if (errormessage_ == &::google::protobuf::internal::kEmptyString) { + errormessage_ = new ::std::string; + } + errormessage_->assign(value); +} +inline void PingResponse_PingError::set_errormessage(const char* value) { + set_has_errormessage(); + if (errormessage_ == &::google::protobuf::internal::kEmptyString) { + errormessage_ = new ::std::string; + } + errormessage_->assign(value); +} +inline void PingResponse_PingError::set_errormessage(const char* value, size_t size) { + set_has_errormessage(); + if (errormessage_ == &::google::protobuf::internal::kEmptyString) { + errormessage_ = new ::std::string; + } + errormessage_->assign(reinterpret_cast(value), size); +} +inline ::std::string* PingResponse_PingError::mutable_errormessage() { + set_has_errormessage(); + if (errormessage_ == &::google::protobuf::internal::kEmptyString) { + errormessage_ = new ::std::string; + } + return errormessage_; +} +inline ::std::string* PingResponse_PingError::release_errormessage() { + clear_has_errormessage(); + if (errormessage_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = errormessage_; + errormessage_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void PingResponse_PingError::set_allocated_errormessage(::std::string* errormessage) { + if (errormessage_ != &::google::protobuf::internal::kEmptyString) { + delete errormessage_; + } + if (errormessage) { + set_has_errormessage(); + errormessage_ = errormessage; + } else { + clear_has_errormessage(); + errormessage_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// PingResponse + +// optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; +inline bool PingResponse::has_result() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void PingResponse::set_has_result() { + _has_bits_[0] |= 0x00000001u; +} +inline void PingResponse::clear_has_result() { + _has_bits_[0] &= ~0x00000001u; +} +inline void PingResponse::clear_result() { + if (result_ != NULL) result_->::xtreemfs::pbrpc::PingResponse_PingResult::Clear(); + clear_has_result(); +} +inline const ::xtreemfs::pbrpc::PingResponse_PingResult& PingResponse::result() const { + return result_ != NULL ? *result_ : *default_instance_->result_; +} +inline ::xtreemfs::pbrpc::PingResponse_PingResult* PingResponse::mutable_result() { + set_has_result(); + if (result_ == NULL) result_ = new ::xtreemfs::pbrpc::PingResponse_PingResult; + return result_; +} +inline ::xtreemfs::pbrpc::PingResponse_PingResult* PingResponse::release_result() { + clear_has_result(); + ::xtreemfs::pbrpc::PingResponse_PingResult* temp = result_; + result_ = NULL; + return temp; +} +inline void PingResponse::set_allocated_result(::xtreemfs::pbrpc::PingResponse_PingResult* result) { + delete result_; + result_ = result; + if (result) { + set_has_result(); + } else { + clear_has_result(); + } +} + +// optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; +inline bool PingResponse::has_error() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void PingResponse::set_has_error() { + _has_bits_[0] |= 0x00000002u; +} +inline void PingResponse::clear_has_error() { + _has_bits_[0] &= ~0x00000002u; +} +inline void PingResponse::clear_error() { + if (error_ != NULL) error_->::xtreemfs::pbrpc::PingResponse_PingError::Clear(); + clear_has_error(); +} +inline const ::xtreemfs::pbrpc::PingResponse_PingError& PingResponse::error() const { + return error_ != NULL ? *error_ : *default_instance_->error_; +} +inline ::xtreemfs::pbrpc::PingResponse_PingError* PingResponse::mutable_error() { + set_has_error(); + if (error_ == NULL) error_ = new ::xtreemfs::pbrpc::PingResponse_PingError; + return error_; +} +inline ::xtreemfs::pbrpc::PingResponse_PingError* PingResponse::release_error() { + clear_has_error(); + ::xtreemfs::pbrpc::PingResponse_PingError* temp = error_; + error_ = NULL; + return temp; +} +inline void PingResponse::set_allocated_error(::xtreemfs::pbrpc::PingResponse_PingError* error) { + delete error_; + error_ = error; + if (error) { + set_has_error(); + } else { + clear_has_error(); + } +} + +// ------------------------------------------------------------------- + +// Ping_emptyRequest + +// ------------------------------------------------------------------- + +// Ping_emptyResponse + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_pbrpc_2fPing_2eproto__INCLUDED diff --git a/cpp/generated/pbrpc/PingServiceClient.h b/cpp/generated/pbrpc/PingServiceClient.h new file mode 100644 index 0000000..9c101f0 --- /dev/null +++ b/cpp/generated/pbrpc/PingServiceClient.h @@ -0,0 +1,79 @@ +//automatically generated from Ping.proto at Thu Dec 11 16:09:41 CET 2014 +//(c) 2014. See LICENSE file for details. + +#ifndef PINGSERVICECLIENT_H +#define PINGSERVICECLIENT_H + +#include +#include "pbrpc/RPC.pb.h" +#include "rpc/client.h" +#include "rpc/sync_callback.h" +#include "rpc/callback_interface.h" +#include "pbrpc/Ping.pb.h" + + +namespace xtreemfs { +namespace pbrpc { + using ::xtreemfs::rpc::Client; + using ::xtreemfs::rpc::CallbackInterface; + using ::xtreemfs::rpc::SyncCallback; + + class PingServiceClient { + + public: + PingServiceClient(Client* client) : client_(client) { + } + + virtual ~PingServiceClient() { + } + + void doPing(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::PingRequest* request,const char* data, uint32_t data_length, + CallbackInterface *callback, void *context = NULL) { + client_->sendRequest(address, 1, 1, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::PingResponse(), + context, callback); + } + + SyncCallback* doPing_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::PingRequest* request, const char* data, uint32_t data_length) { + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 1, 1, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::PingResponse(), + NULL, sync_cb); + return sync_cb; + } + + void emptyPing(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::Ping_emptyRequest* request = NULL; + client_->sendRequest(address, 1, 2, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* emptyPing_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::Ping_emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 1, 2, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + private: + Client* client_; + }; + } +} +#endif //PINGSERVICECLIENT_H diff --git a/cpp/generated/pbrpc/PingServiceConstants.h b/cpp/generated/pbrpc/PingServiceConstants.h new file mode 100644 index 0000000..8892de8 --- /dev/null +++ b/cpp/generated/pbrpc/PingServiceConstants.h @@ -0,0 +1,18 @@ +//automatically generated from Ping.proto at Thu Dec 11 16:09:41 CET 2014 +//(c) 2014. See LICENSE file for details. + +#ifndef PINGSERVICECONSTANTS_H_ +#define PINGSERVICECONSTANTS_H_ +#include + +namespace xtreemfs { +namespace pbrpc { + +const uint32_t INTERFACE_ID_PING = 1; +const uint32_t PROC_ID_DOPING = 1; +const uint32_t PROC_ID_EMPTYPING = 2; + +} // namespace pbrpc +} // namespace xtreemfs + +#endif // PINGSERVICECLIENT_H_ diff --git a/cpp/generated/pbrpc/RPC.pb.cc b/cpp/generated/pbrpc/RPC.pb.cc new file mode 100644 index 0000000..5cad7fe --- /dev/null +++ b/cpp/generated/pbrpc/RPC.pb.cc @@ -0,0 +1,2293 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: pbrpc/RPC.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "pbrpc/RPC.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +namespace { + +const ::google::protobuf::Descriptor* UserCredentials_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + UserCredentials_reflection_ = NULL; +const ::google::protobuf::Descriptor* AuthPassword_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + AuthPassword_reflection_ = NULL; +const ::google::protobuf::Descriptor* Auth_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Auth_reflection_ = NULL; +const ::google::protobuf::Descriptor* RPCHeader_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RPCHeader_reflection_ = NULL; +const ::google::protobuf::Descriptor* RPCHeader_RequestHeader_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RPCHeader_RequestHeader_reflection_ = NULL; +const ::google::protobuf::Descriptor* RPCHeader_ErrorResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RPCHeader_ErrorResponse_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* MessageType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* AuthType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ErrorType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* POSIXErrno_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_pbrpc_2fRPC_2eproto() { + protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "pbrpc/RPC.proto"); + GOOGLE_CHECK(file != NULL); + UserCredentials_descriptor_ = file->message_type(0); + static const int UserCredentials_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UserCredentials, username_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UserCredentials, groups_), + }; + UserCredentials_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + UserCredentials_descriptor_, + UserCredentials::default_instance_, + UserCredentials_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UserCredentials, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UserCredentials, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(UserCredentials)); + AuthPassword_descriptor_ = file->message_type(1); + static const int AuthPassword_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AuthPassword, password_), + }; + AuthPassword_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + AuthPassword_descriptor_, + AuthPassword::default_instance_, + AuthPassword_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AuthPassword, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AuthPassword, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(AuthPassword)); + Auth_descriptor_ = file->message_type(2); + static const int Auth_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Auth, auth_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Auth, auth_passwd_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Auth, auth_data_), + }; + Auth_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Auth_descriptor_, + Auth::default_instance_, + Auth_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Auth, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Auth, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Auth)); + RPCHeader_descriptor_ = file->message_type(3); + static const int RPCHeader_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader, call_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader, message_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader, request_header_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader, error_response_), + }; + RPCHeader_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RPCHeader_descriptor_, + RPCHeader::default_instance_, + RPCHeader_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RPCHeader)); + RPCHeader_RequestHeader_descriptor_ = RPCHeader_descriptor_->nested_type(0); + static const int RPCHeader_RequestHeader_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_RequestHeader, interface_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_RequestHeader, proc_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_RequestHeader, user_creds_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_RequestHeader, auth_data_), + }; + RPCHeader_RequestHeader_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RPCHeader_RequestHeader_descriptor_, + RPCHeader_RequestHeader::default_instance_, + RPCHeader_RequestHeader_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_RequestHeader, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_RequestHeader, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RPCHeader_RequestHeader)); + RPCHeader_ErrorResponse_descriptor_ = RPCHeader_descriptor_->nested_type(1); + static const int RPCHeader_ErrorResponse_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_ErrorResponse, error_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_ErrorResponse, posix_errno_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_ErrorResponse, error_message_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_ErrorResponse, debug_info_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_ErrorResponse, redirect_to_server_uuid_), + }; + RPCHeader_ErrorResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RPCHeader_ErrorResponse_descriptor_, + RPCHeader_ErrorResponse::default_instance_, + RPCHeader_ErrorResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_ErrorResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RPCHeader_ErrorResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RPCHeader_ErrorResponse)); + MessageType_descriptor_ = file->enum_type(0); + AuthType_descriptor_ = file->enum_type(1); + ErrorType_descriptor_ = file->enum_type(2); + POSIXErrno_descriptor_ = file->enum_type(3); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_pbrpc_2fRPC_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + UserCredentials_descriptor_, &UserCredentials::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + AuthPassword_descriptor_, &AuthPassword::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Auth_descriptor_, &Auth::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RPCHeader_descriptor_, &RPCHeader::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RPCHeader_RequestHeader_descriptor_, &RPCHeader_RequestHeader::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RPCHeader_ErrorResponse_descriptor_, &RPCHeader_ErrorResponse::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_pbrpc_2fRPC_2eproto() { + delete UserCredentials::default_instance_; + delete UserCredentials_reflection_; + delete AuthPassword::default_instance_; + delete AuthPassword_reflection_; + delete Auth::default_instance_; + delete Auth_reflection_; + delete RPCHeader::default_instance_; + delete RPCHeader_reflection_; + delete RPCHeader_RequestHeader::default_instance_; + delete RPCHeader_RequestHeader_reflection_; + delete RPCHeader_ErrorResponse::default_instance_; + delete RPCHeader_ErrorResponse_reflection_; +} + +void protobuf_AddDesc_pbrpc_2fRPC_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\017pbrpc/RPC.proto\022\016xtreemfs.pbrpc\"3\n\017Use" + "rCredentials\022\020\n\010username\030\001 \002(\t\022\016\n\006groups" + "\030\002 \003(\t\" \n\014AuthPassword\022\020\n\010password\030\001 \002(\t" + "\"y\n\004Auth\022+\n\tauth_type\030\001 \002(\0162\030.xtreemfs.p" + "brpc.AuthType\0221\n\013auth_passwd\030\003 \001(\0132\034.xtr" + "eemfs.pbrpc.AuthPassword\022\021\n\tauth_data\030\002 " + "\001(\014\"\270\004\n\tRPCHeader\022\017\n\007call_id\030\001 \002(\007\0221\n\014me" + "ssage_type\030\002 \002(\0162\033.xtreemfs.pbrpc.Messag" + "eType\022\?\n\016request_header\030\003 \001(\0132\'.xtreemfs" + ".pbrpc.RPCHeader.RequestHeader\022\?\n\016error_" + "response\030\004 \001(\0132\'.xtreemfs.pbrpc.RPCHeade" + "r.ErrorResponse\032\224\001\n\rRequestHeader\022\024\n\014int" + "erface_id\030\001 \002(\007\022\017\n\007proc_id\030\002 \002(\007\0223\n\nuser" + "_creds\030\003 \002(\0132\037.xtreemfs.pbrpc.UserCreden" + "tials\022\'\n\tauth_data\030\004 \002(\0132\024.xtreemfs.pbrp" + "c.Auth\032\315\001\n\rErrorResponse\022-\n\nerror_type\030\001" + " \002(\0162\031.xtreemfs.pbrpc.ErrorType\022A\n\013posix" + "_errno\030\002 \001(\0162\032.xtreemfs.pbrpc.POSIXErrno" + ":\020POSIX_ERROR_NONE\022\025\n\rerror_message\030\003 \001(" + "\t\022\022\n\ndebug_info\030\004 \001(\t\022\037\n\027redirect_to_ser" + "ver_uuid\030\005 \001(\t*P\n\013MessageType\022\017\n\013RPC_REQ" + "UEST\020\000\022\030\n\024RPC_RESPONSE_SUCCESS\020\001\022\026\n\022RPC_" + "RESPONSE_ERROR\020\002*,\n\010AuthType\022\r\n\tAUTH_NON" + "E\020\000\022\021\n\rAUTH_PASSWORD\020\001*\261\001\n\tErrorType\022\030\n\024" + "INVALID_INTERFACE_ID\020\001\022\023\n\017INVALID_PROC_I" + "D\020\002\022\020\n\014GARBAGE_ARGS\020\003\022\017\n\013AUTH_FAILED\020\004\022\031" + "\n\025INTERNAL_SERVER_ERROR\020\005\022\t\n\005ERRNO\020\006\022\014\n\010" + "REDIRECT\020\007\022\020\n\014INVALID_VIEW\020\010\022\014\n\010IO_ERROR" + "\020d*\212\003\n\nPOSIXErrno\022\025\n\020POSIX_ERROR_NONE\020\217N" + "\022\025\n\021POSIX_ERROR_EPERM\020\001\022\026\n\022POSIX_ERROR_E" + "NOENT\020\002\022\025\n\021POSIX_ERROR_EINTR\020\004\022\023\n\017POSIX_" + "ERROR_EIO\020\005\022\026\n\022POSIX_ERROR_EAGAIN\020\013\022\026\n\022P" + "OSIX_ERROR_EACCES\020\r\022\026\n\022POSIX_ERROR_EEXIS" + "T\020\021\022\025\n\021POSIX_ERROR_EXDEV\020\022\022\026\n\022POSIX_ERRO" + "R_ENODEV\020\023\022\027\n\023POSIX_ERROR_ENOTDIR\020\024\022\026\n\022P" + "OSIX_ERROR_EISDIR\020\025\022\026\n\022POSIX_ERROR_EINVA" + "L\020\026\022\026\n\022POSIX_ERROR_ENOSPC\020\034\022\031\n\025POSIX_ERR" + "OR_ENOTEMPTY\020\'\022\027\n\023POSIX_ERROR_ENODATA\020=B" + "3\n1org.xtreemfs.foundation.pbrpc.generat" + "edinterfaces", 1572); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "pbrpc/RPC.proto", &protobuf_RegisterTypes); + UserCredentials::default_instance_ = new UserCredentials(); + AuthPassword::default_instance_ = new AuthPassword(); + Auth::default_instance_ = new Auth(); + RPCHeader::default_instance_ = new RPCHeader(); + RPCHeader_RequestHeader::default_instance_ = new RPCHeader_RequestHeader(); + RPCHeader_ErrorResponse::default_instance_ = new RPCHeader_ErrorResponse(); + UserCredentials::default_instance_->InitAsDefaultInstance(); + AuthPassword::default_instance_->InitAsDefaultInstance(); + Auth::default_instance_->InitAsDefaultInstance(); + RPCHeader::default_instance_->InitAsDefaultInstance(); + RPCHeader_RequestHeader::default_instance_->InitAsDefaultInstance(); + RPCHeader_ErrorResponse::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_pbrpc_2fRPC_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_pbrpc_2fRPC_2eproto { + StaticDescriptorInitializer_pbrpc_2fRPC_2eproto() { + protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + } +} static_descriptor_initializer_pbrpc_2fRPC_2eproto_; +const ::google::protobuf::EnumDescriptor* MessageType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return MessageType_descriptor_; +} +bool MessageType_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* AuthType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return AuthType_descriptor_; +} +bool AuthType_IsValid(int value) { + switch(value) { + case 0: + case 1: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ErrorType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ErrorType_descriptor_; +} +bool ErrorType_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 100: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* POSIXErrno_descriptor() { + protobuf_AssignDescriptorsOnce(); + return POSIXErrno_descriptor_; +} +bool POSIXErrno_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 4: + case 5: + case 11: + case 13: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 28: + case 39: + case 61: + case 9999: + return true; + default: + return false; + } +} + + +// =================================================================== + +#ifndef _MSC_VER +const int UserCredentials::kUsernameFieldNumber; +const int UserCredentials::kGroupsFieldNumber; +#endif // !_MSC_VER + +UserCredentials::UserCredentials() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void UserCredentials::InitAsDefaultInstance() { +} + +UserCredentials::UserCredentials(const UserCredentials& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void UserCredentials::SharedCtor() { + _cached_size_ = 0; + username_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +UserCredentials::~UserCredentials() { + SharedDtor(); +} + +void UserCredentials::SharedDtor() { + if (username_ != &::google::protobuf::internal::kEmptyString) { + delete username_; + } + if (this != default_instance_) { + } +} + +void UserCredentials::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* UserCredentials::descriptor() { + protobuf_AssignDescriptorsOnce(); + return UserCredentials_descriptor_; +} + +const UserCredentials& UserCredentials::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + return *default_instance_; +} + +UserCredentials* UserCredentials::default_instance_ = NULL; + +UserCredentials* UserCredentials::New() const { + return new UserCredentials; +} + +void UserCredentials::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_username()) { + if (username_ != &::google::protobuf::internal::kEmptyString) { + username_->clear(); + } + } + } + groups_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool UserCredentials::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string username = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_username())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->username().data(), this->username().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_groups; + break; + } + + // repeated string groups = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_groups: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_groups())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->groups(this->groups_size() - 1).data(), + this->groups(this->groups_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_groups; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void UserCredentials::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string username = 1; + if (has_username()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->username().data(), this->username().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->username(), output); + } + + // repeated string groups = 2; + for (int i = 0; i < this->groups_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->groups(i).data(), this->groups(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->groups(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* UserCredentials::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string username = 1; + if (has_username()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->username().data(), this->username().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->username(), target); + } + + // repeated string groups = 2; + for (int i = 0; i < this->groups_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->groups(i).data(), this->groups(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(2, this->groups(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int UserCredentials::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string username = 1; + if (has_username()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->username()); + } + + } + // repeated string groups = 2; + total_size += 1 * this->groups_size(); + for (int i = 0; i < this->groups_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->groups(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void UserCredentials::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const UserCredentials* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void UserCredentials::MergeFrom(const UserCredentials& from) { + GOOGLE_CHECK_NE(&from, this); + groups_.MergeFrom(from.groups_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_username()) { + set_username(from.username()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void UserCredentials::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void UserCredentials::CopyFrom(const UserCredentials& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool UserCredentials::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void UserCredentials::Swap(UserCredentials* other) { + if (other != this) { + std::swap(username_, other->username_); + groups_.Swap(&other->groups_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata UserCredentials::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = UserCredentials_descriptor_; + metadata.reflection = UserCredentials_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int AuthPassword::kPasswordFieldNumber; +#endif // !_MSC_VER + +AuthPassword::AuthPassword() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void AuthPassword::InitAsDefaultInstance() { +} + +AuthPassword::AuthPassword(const AuthPassword& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void AuthPassword::SharedCtor() { + _cached_size_ = 0; + password_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +AuthPassword::~AuthPassword() { + SharedDtor(); +} + +void AuthPassword::SharedDtor() { + if (password_ != &::google::protobuf::internal::kEmptyString) { + delete password_; + } + if (this != default_instance_) { + } +} + +void AuthPassword::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* AuthPassword::descriptor() { + protobuf_AssignDescriptorsOnce(); + return AuthPassword_descriptor_; +} + +const AuthPassword& AuthPassword::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + return *default_instance_; +} + +AuthPassword* AuthPassword::default_instance_ = NULL; + +AuthPassword* AuthPassword::New() const { + return new AuthPassword; +} + +void AuthPassword::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_password()) { + if (password_ != &::google::protobuf::internal::kEmptyString) { + password_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool AuthPassword::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string password = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_password())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->password().data(), this->password().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void AuthPassword::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string password = 1; + if (has_password()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->password().data(), this->password().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->password(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* AuthPassword::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string password = 1; + if (has_password()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->password().data(), this->password().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->password(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int AuthPassword::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string password = 1; + if (has_password()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->password()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void AuthPassword::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const AuthPassword* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void AuthPassword::MergeFrom(const AuthPassword& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_password()) { + set_password(from.password()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void AuthPassword::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void AuthPassword::CopyFrom(const AuthPassword& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool AuthPassword::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void AuthPassword::Swap(AuthPassword* other) { + if (other != this) { + std::swap(password_, other->password_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata AuthPassword::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = AuthPassword_descriptor_; + metadata.reflection = AuthPassword_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Auth::kAuthTypeFieldNumber; +const int Auth::kAuthPasswdFieldNumber; +const int Auth::kAuthDataFieldNumber; +#endif // !_MSC_VER + +Auth::Auth() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Auth::InitAsDefaultInstance() { + auth_passwd_ = const_cast< ::xtreemfs::pbrpc::AuthPassword*>(&::xtreemfs::pbrpc::AuthPassword::default_instance()); +} + +Auth::Auth(const Auth& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Auth::SharedCtor() { + _cached_size_ = 0; + auth_type_ = 0; + auth_passwd_ = NULL; + auth_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Auth::~Auth() { + SharedDtor(); +} + +void Auth::SharedDtor() { + if (auth_data_ != &::google::protobuf::internal::kEmptyString) { + delete auth_data_; + } + if (this != default_instance_) { + delete auth_passwd_; + } +} + +void Auth::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Auth::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Auth_descriptor_; +} + +const Auth& Auth::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + return *default_instance_; +} + +Auth* Auth::default_instance_ = NULL; + +Auth* Auth::New() const { + return new Auth; +} + +void Auth::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + auth_type_ = 0; + if (has_auth_passwd()) { + if (auth_passwd_ != NULL) auth_passwd_->::xtreemfs::pbrpc::AuthPassword::Clear(); + } + if (has_auth_data()) { + if (auth_data_ != &::google::protobuf::internal::kEmptyString) { + auth_data_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Auth::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.AuthType auth_type = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::AuthType_IsValid(value)) { + set_auth_type(static_cast< ::xtreemfs::pbrpc::AuthType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_auth_data; + break; + } + + // optional bytes auth_data = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_auth_data: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_auth_data())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_auth_passwd; + break; + } + + // optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_auth_passwd: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_auth_passwd())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Auth::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.AuthType auth_type = 1; + if (has_auth_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->auth_type(), output); + } + + // optional bytes auth_data = 2; + if (has_auth_data()) { + ::google::protobuf::internal::WireFormatLite::WriteBytes( + 2, this->auth_data(), output); + } + + // optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + if (has_auth_passwd()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->auth_passwd(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Auth::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.AuthType auth_type = 1; + if (has_auth_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->auth_type(), target); + } + + // optional bytes auth_data = 2; + if (has_auth_data()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 2, this->auth_data(), target); + } + + // optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + if (has_auth_passwd()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->auth_passwd(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Auth::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.AuthType auth_type = 1; + if (has_auth_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->auth_type()); + } + + // optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + if (has_auth_passwd()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->auth_passwd()); + } + + // optional bytes auth_data = 2; + if (has_auth_data()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->auth_data()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Auth::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Auth* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Auth::MergeFrom(const Auth& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_auth_type()) { + set_auth_type(from.auth_type()); + } + if (from.has_auth_passwd()) { + mutable_auth_passwd()->::xtreemfs::pbrpc::AuthPassword::MergeFrom(from.auth_passwd()); + } + if (from.has_auth_data()) { + set_auth_data(from.auth_data()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Auth::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Auth::CopyFrom(const Auth& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Auth::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_auth_passwd()) { + if (!this->auth_passwd().IsInitialized()) return false; + } + return true; +} + +void Auth::Swap(Auth* other) { + if (other != this) { + std::swap(auth_type_, other->auth_type_); + std::swap(auth_passwd_, other->auth_passwd_); + std::swap(auth_data_, other->auth_data_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Auth::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Auth_descriptor_; + metadata.reflection = Auth_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int RPCHeader_RequestHeader::kInterfaceIdFieldNumber; +const int RPCHeader_RequestHeader::kProcIdFieldNumber; +const int RPCHeader_RequestHeader::kUserCredsFieldNumber; +const int RPCHeader_RequestHeader::kAuthDataFieldNumber; +#endif // !_MSC_VER + +RPCHeader_RequestHeader::RPCHeader_RequestHeader() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RPCHeader_RequestHeader::InitAsDefaultInstance() { + user_creds_ = const_cast< ::xtreemfs::pbrpc::UserCredentials*>(&::xtreemfs::pbrpc::UserCredentials::default_instance()); + auth_data_ = const_cast< ::xtreemfs::pbrpc::Auth*>(&::xtreemfs::pbrpc::Auth::default_instance()); +} + +RPCHeader_RequestHeader::RPCHeader_RequestHeader(const RPCHeader_RequestHeader& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RPCHeader_RequestHeader::SharedCtor() { + _cached_size_ = 0; + interface_id_ = 0u; + proc_id_ = 0u; + user_creds_ = NULL; + auth_data_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RPCHeader_RequestHeader::~RPCHeader_RequestHeader() { + SharedDtor(); +} + +void RPCHeader_RequestHeader::SharedDtor() { + if (this != default_instance_) { + delete user_creds_; + delete auth_data_; + } +} + +void RPCHeader_RequestHeader::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RPCHeader_RequestHeader::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RPCHeader_RequestHeader_descriptor_; +} + +const RPCHeader_RequestHeader& RPCHeader_RequestHeader::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + return *default_instance_; +} + +RPCHeader_RequestHeader* RPCHeader_RequestHeader::default_instance_ = NULL; + +RPCHeader_RequestHeader* RPCHeader_RequestHeader::New() const { + return new RPCHeader_RequestHeader; +} + +void RPCHeader_RequestHeader::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + interface_id_ = 0u; + proc_id_ = 0u; + if (has_user_creds()) { + if (user_creds_ != NULL) user_creds_->::xtreemfs::pbrpc::UserCredentials::Clear(); + } + if (has_auth_data()) { + if (auth_data_ != NULL) auth_data_->::xtreemfs::pbrpc::Auth::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RPCHeader_RequestHeader::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed32 interface_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &interface_id_))); + set_has_interface_id(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(21)) goto parse_proc_id; + break; + } + + // required fixed32 proc_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_proc_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &proc_id_))); + set_has_proc_id(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_user_creds; + break; + } + + // required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_user_creds: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_user_creds())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_auth_data; + break; + } + + // required .xtreemfs.pbrpc.Auth auth_data = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_auth_data: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_auth_data())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RPCHeader_RequestHeader::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed32 interface_id = 1; + if (has_interface_id()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(1, this->interface_id(), output); + } + + // required fixed32 proc_id = 2; + if (has_proc_id()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(2, this->proc_id(), output); + } + + // required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + if (has_user_creds()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->user_creds(), output); + } + + // required .xtreemfs.pbrpc.Auth auth_data = 4; + if (has_auth_data()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, this->auth_data(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RPCHeader_RequestHeader::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed32 interface_id = 1; + if (has_interface_id()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(1, this->interface_id(), target); + } + + // required fixed32 proc_id = 2; + if (has_proc_id()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(2, this->proc_id(), target); + } + + // required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + if (has_user_creds()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->user_creds(), target); + } + + // required .xtreemfs.pbrpc.Auth auth_data = 4; + if (has_auth_data()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->auth_data(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RPCHeader_RequestHeader::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed32 interface_id = 1; + if (has_interface_id()) { + total_size += 1 + 4; + } + + // required fixed32 proc_id = 2; + if (has_proc_id()) { + total_size += 1 + 4; + } + + // required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + if (has_user_creds()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->user_creds()); + } + + // required .xtreemfs.pbrpc.Auth auth_data = 4; + if (has_auth_data()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->auth_data()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RPCHeader_RequestHeader::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RPCHeader_RequestHeader* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RPCHeader_RequestHeader::MergeFrom(const RPCHeader_RequestHeader& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_interface_id()) { + set_interface_id(from.interface_id()); + } + if (from.has_proc_id()) { + set_proc_id(from.proc_id()); + } + if (from.has_user_creds()) { + mutable_user_creds()->::xtreemfs::pbrpc::UserCredentials::MergeFrom(from.user_creds()); + } + if (from.has_auth_data()) { + mutable_auth_data()->::xtreemfs::pbrpc::Auth::MergeFrom(from.auth_data()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RPCHeader_RequestHeader::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RPCHeader_RequestHeader::CopyFrom(const RPCHeader_RequestHeader& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RPCHeader_RequestHeader::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + if (has_user_creds()) { + if (!this->user_creds().IsInitialized()) return false; + } + if (has_auth_data()) { + if (!this->auth_data().IsInitialized()) return false; + } + return true; +} + +void RPCHeader_RequestHeader::Swap(RPCHeader_RequestHeader* other) { + if (other != this) { + std::swap(interface_id_, other->interface_id_); + std::swap(proc_id_, other->proc_id_); + std::swap(user_creds_, other->user_creds_); + std::swap(auth_data_, other->auth_data_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RPCHeader_RequestHeader::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RPCHeader_RequestHeader_descriptor_; + metadata.reflection = RPCHeader_RequestHeader_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#ifndef _MSC_VER +const int RPCHeader_ErrorResponse::kErrorTypeFieldNumber; +const int RPCHeader_ErrorResponse::kPosixErrnoFieldNumber; +const int RPCHeader_ErrorResponse::kErrorMessageFieldNumber; +const int RPCHeader_ErrorResponse::kDebugInfoFieldNumber; +const int RPCHeader_ErrorResponse::kRedirectToServerUuidFieldNumber; +#endif // !_MSC_VER + +RPCHeader_ErrorResponse::RPCHeader_ErrorResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RPCHeader_ErrorResponse::InitAsDefaultInstance() { +} + +RPCHeader_ErrorResponse::RPCHeader_ErrorResponse(const RPCHeader_ErrorResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RPCHeader_ErrorResponse::SharedCtor() { + _cached_size_ = 0; + error_type_ = 1; + posix_errno_ = 9999; + error_message_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + debug_info_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + redirect_to_server_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RPCHeader_ErrorResponse::~RPCHeader_ErrorResponse() { + SharedDtor(); +} + +void RPCHeader_ErrorResponse::SharedDtor() { + if (error_message_ != &::google::protobuf::internal::kEmptyString) { + delete error_message_; + } + if (debug_info_ != &::google::protobuf::internal::kEmptyString) { + delete debug_info_; + } + if (redirect_to_server_uuid_ != &::google::protobuf::internal::kEmptyString) { + delete redirect_to_server_uuid_; + } + if (this != default_instance_) { + } +} + +void RPCHeader_ErrorResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RPCHeader_ErrorResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RPCHeader_ErrorResponse_descriptor_; +} + +const RPCHeader_ErrorResponse& RPCHeader_ErrorResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + return *default_instance_; +} + +RPCHeader_ErrorResponse* RPCHeader_ErrorResponse::default_instance_ = NULL; + +RPCHeader_ErrorResponse* RPCHeader_ErrorResponse::New() const { + return new RPCHeader_ErrorResponse; +} + +void RPCHeader_ErrorResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + error_type_ = 1; + posix_errno_ = 9999; + if (has_error_message()) { + if (error_message_ != &::google::protobuf::internal::kEmptyString) { + error_message_->clear(); + } + } + if (has_debug_info()) { + if (debug_info_ != &::google::protobuf::internal::kEmptyString) { + debug_info_->clear(); + } + } + if (has_redirect_to_server_uuid()) { + if (redirect_to_server_uuid_ != &::google::protobuf::internal::kEmptyString) { + redirect_to_server_uuid_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RPCHeader_ErrorResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.ErrorType error_type = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::ErrorType_IsValid(value)) { + set_error_type(static_cast< ::xtreemfs::pbrpc::ErrorType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_posix_errno; + break; + } + + // optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_posix_errno: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::POSIXErrno_IsValid(value)) { + set_posix_errno(static_cast< ::xtreemfs::pbrpc::POSIXErrno >(value)); + } else { + mutable_unknown_fields()->AddVarint(2, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_error_message; + break; + } + + // optional string error_message = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_error_message: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_error_message())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->error_message().data(), this->error_message().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_debug_info; + break; + } + + // optional string debug_info = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_debug_info: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_debug_info())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->debug_info().data(), this->debug_info().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_redirect_to_server_uuid; + break; + } + + // optional string redirect_to_server_uuid = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_redirect_to_server_uuid: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_redirect_to_server_uuid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->redirect_to_server_uuid().data(), this->redirect_to_server_uuid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RPCHeader_ErrorResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.ErrorType error_type = 1; + if (has_error_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->error_type(), output); + } + + // optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + if (has_posix_errno()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->posix_errno(), output); + } + + // optional string error_message = 3; + if (has_error_message()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->error_message().data(), this->error_message().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->error_message(), output); + } + + // optional string debug_info = 4; + if (has_debug_info()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->debug_info().data(), this->debug_info().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->debug_info(), output); + } + + // optional string redirect_to_server_uuid = 5; + if (has_redirect_to_server_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->redirect_to_server_uuid().data(), this->redirect_to_server_uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 5, this->redirect_to_server_uuid(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RPCHeader_ErrorResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.ErrorType error_type = 1; + if (has_error_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->error_type(), target); + } + + // optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + if (has_posix_errno()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 2, this->posix_errno(), target); + } + + // optional string error_message = 3; + if (has_error_message()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->error_message().data(), this->error_message().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->error_message(), target); + } + + // optional string debug_info = 4; + if (has_debug_info()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->debug_info().data(), this->debug_info().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->debug_info(), target); + } + + // optional string redirect_to_server_uuid = 5; + if (has_redirect_to_server_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->redirect_to_server_uuid().data(), this->redirect_to_server_uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 5, this->redirect_to_server_uuid(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RPCHeader_ErrorResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.ErrorType error_type = 1; + if (has_error_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->error_type()); + } + + // optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + if (has_posix_errno()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->posix_errno()); + } + + // optional string error_message = 3; + if (has_error_message()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->error_message()); + } + + // optional string debug_info = 4; + if (has_debug_info()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->debug_info()); + } + + // optional string redirect_to_server_uuid = 5; + if (has_redirect_to_server_uuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->redirect_to_server_uuid()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RPCHeader_ErrorResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RPCHeader_ErrorResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RPCHeader_ErrorResponse::MergeFrom(const RPCHeader_ErrorResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_error_type()) { + set_error_type(from.error_type()); + } + if (from.has_posix_errno()) { + set_posix_errno(from.posix_errno()); + } + if (from.has_error_message()) { + set_error_message(from.error_message()); + } + if (from.has_debug_info()) { + set_debug_info(from.debug_info()); + } + if (from.has_redirect_to_server_uuid()) { + set_redirect_to_server_uuid(from.redirect_to_server_uuid()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RPCHeader_ErrorResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RPCHeader_ErrorResponse::CopyFrom(const RPCHeader_ErrorResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RPCHeader_ErrorResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void RPCHeader_ErrorResponse::Swap(RPCHeader_ErrorResponse* other) { + if (other != this) { + std::swap(error_type_, other->error_type_); + std::swap(posix_errno_, other->posix_errno_); + std::swap(error_message_, other->error_message_); + std::swap(debug_info_, other->debug_info_); + std::swap(redirect_to_server_uuid_, other->redirect_to_server_uuid_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RPCHeader_ErrorResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RPCHeader_ErrorResponse_descriptor_; + metadata.reflection = RPCHeader_ErrorResponse_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#ifndef _MSC_VER +const int RPCHeader::kCallIdFieldNumber; +const int RPCHeader::kMessageTypeFieldNumber; +const int RPCHeader::kRequestHeaderFieldNumber; +const int RPCHeader::kErrorResponseFieldNumber; +#endif // !_MSC_VER + +RPCHeader::RPCHeader() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RPCHeader::InitAsDefaultInstance() { + request_header_ = const_cast< ::xtreemfs::pbrpc::RPCHeader_RequestHeader*>(&::xtreemfs::pbrpc::RPCHeader_RequestHeader::default_instance()); + error_response_ = const_cast< ::xtreemfs::pbrpc::RPCHeader_ErrorResponse*>(&::xtreemfs::pbrpc::RPCHeader_ErrorResponse::default_instance()); +} + +RPCHeader::RPCHeader(const RPCHeader& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RPCHeader::SharedCtor() { + _cached_size_ = 0; + call_id_ = 0u; + message_type_ = 0; + request_header_ = NULL; + error_response_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RPCHeader::~RPCHeader() { + SharedDtor(); +} + +void RPCHeader::SharedDtor() { + if (this != default_instance_) { + delete request_header_; + delete error_response_; + } +} + +void RPCHeader::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RPCHeader::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RPCHeader_descriptor_; +} + +const RPCHeader& RPCHeader::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + return *default_instance_; +} + +RPCHeader* RPCHeader::default_instance_ = NULL; + +RPCHeader* RPCHeader::New() const { + return new RPCHeader; +} + +void RPCHeader::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + call_id_ = 0u; + message_type_ = 0; + if (has_request_header()) { + if (request_header_ != NULL) request_header_->::xtreemfs::pbrpc::RPCHeader_RequestHeader::Clear(); + } + if (has_error_response()) { + if (error_response_ != NULL) error_response_->::xtreemfs::pbrpc::RPCHeader_ErrorResponse::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RPCHeader::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed32 call_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &call_id_))); + set_has_call_id(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_message_type; + break; + } + + // required .xtreemfs.pbrpc.MessageType message_type = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_message_type: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::MessageType_IsValid(value)) { + set_message_type(static_cast< ::xtreemfs::pbrpc::MessageType >(value)); + } else { + mutable_unknown_fields()->AddVarint(2, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_request_header; + break; + } + + // optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_request_header: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_request_header())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_error_response; + break; + } + + // optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_error_response: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_error_response())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RPCHeader::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed32 call_id = 1; + if (has_call_id()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(1, this->call_id(), output); + } + + // required .xtreemfs.pbrpc.MessageType message_type = 2; + if (has_message_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->message_type(), output); + } + + // optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + if (has_request_header()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->request_header(), output); + } + + // optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + if (has_error_response()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, this->error_response(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RPCHeader::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed32 call_id = 1; + if (has_call_id()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(1, this->call_id(), target); + } + + // required .xtreemfs.pbrpc.MessageType message_type = 2; + if (has_message_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 2, this->message_type(), target); + } + + // optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + if (has_request_header()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->request_header(), target); + } + + // optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + if (has_error_response()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->error_response(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RPCHeader::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed32 call_id = 1; + if (has_call_id()) { + total_size += 1 + 4; + } + + // required .xtreemfs.pbrpc.MessageType message_type = 2; + if (has_message_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->message_type()); + } + + // optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + if (has_request_header()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->request_header()); + } + + // optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + if (has_error_response()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->error_response()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RPCHeader::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RPCHeader* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RPCHeader::MergeFrom(const RPCHeader& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_call_id()) { + set_call_id(from.call_id()); + } + if (from.has_message_type()) { + set_message_type(from.message_type()); + } + if (from.has_request_header()) { + mutable_request_header()->::xtreemfs::pbrpc::RPCHeader_RequestHeader::MergeFrom(from.request_header()); + } + if (from.has_error_response()) { + mutable_error_response()->::xtreemfs::pbrpc::RPCHeader_ErrorResponse::MergeFrom(from.error_response()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RPCHeader::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RPCHeader::CopyFrom(const RPCHeader& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RPCHeader::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_request_header()) { + if (!this->request_header().IsInitialized()) return false; + } + if (has_error_response()) { + if (!this->error_response().IsInitialized()) return false; + } + return true; +} + +void RPCHeader::Swap(RPCHeader* other) { + if (other != this) { + std::swap(call_id_, other->call_id_); + std::swap(message_type_, other->message_type_); + std::swap(request_header_, other->request_header_); + std::swap(error_response_, other->error_response_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RPCHeader::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RPCHeader_descriptor_; + metadata.reflection = RPCHeader_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/generated/pbrpc/RPC.pb.h b/cpp/generated/pbrpc/RPC.pb.h new file mode 100644 index 0000000..6712497 --- /dev/null +++ b/cpp/generated/pbrpc/RPC.pb.h @@ -0,0 +1,1687 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: pbrpc/RPC.proto + +#ifndef PROTOBUF_pbrpc_2fRPC_2eproto__INCLUDED +#define PROTOBUF_pbrpc_2fRPC_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_pbrpc_2fRPC_2eproto(); +void protobuf_AssignDesc_pbrpc_2fRPC_2eproto(); +void protobuf_ShutdownFile_pbrpc_2fRPC_2eproto(); + +class UserCredentials; +class AuthPassword; +class Auth; +class RPCHeader; +class RPCHeader_RequestHeader; +class RPCHeader_ErrorResponse; + +enum MessageType { + RPC_REQUEST = 0, + RPC_RESPONSE_SUCCESS = 1, + RPC_RESPONSE_ERROR = 2 +}; +bool MessageType_IsValid(int value); +const MessageType MessageType_MIN = RPC_REQUEST; +const MessageType MessageType_MAX = RPC_RESPONSE_ERROR; +const int MessageType_ARRAYSIZE = MessageType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* MessageType_descriptor(); +inline const ::std::string& MessageType_Name(MessageType value) { + return ::google::protobuf::internal::NameOfEnum( + MessageType_descriptor(), value); +} +inline bool MessageType_Parse( + const ::std::string& name, MessageType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + MessageType_descriptor(), name, value); +} +enum AuthType { + AUTH_NONE = 0, + AUTH_PASSWORD = 1 +}; +bool AuthType_IsValid(int value); +const AuthType AuthType_MIN = AUTH_NONE; +const AuthType AuthType_MAX = AUTH_PASSWORD; +const int AuthType_ARRAYSIZE = AuthType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* AuthType_descriptor(); +inline const ::std::string& AuthType_Name(AuthType value) { + return ::google::protobuf::internal::NameOfEnum( + AuthType_descriptor(), value); +} +inline bool AuthType_Parse( + const ::std::string& name, AuthType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + AuthType_descriptor(), name, value); +} +enum ErrorType { + INVALID_INTERFACE_ID = 1, + INVALID_PROC_ID = 2, + GARBAGE_ARGS = 3, + AUTH_FAILED = 4, + INTERNAL_SERVER_ERROR = 5, + ERRNO = 6, + REDIRECT = 7, + INVALID_VIEW = 8, + IO_ERROR = 100 +}; +bool ErrorType_IsValid(int value); +const ErrorType ErrorType_MIN = INVALID_INTERFACE_ID; +const ErrorType ErrorType_MAX = IO_ERROR; +const int ErrorType_ARRAYSIZE = ErrorType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ErrorType_descriptor(); +inline const ::std::string& ErrorType_Name(ErrorType value) { + return ::google::protobuf::internal::NameOfEnum( + ErrorType_descriptor(), value); +} +inline bool ErrorType_Parse( + const ::std::string& name, ErrorType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ErrorType_descriptor(), name, value); +} +enum POSIXErrno { + POSIX_ERROR_NONE = 9999, + POSIX_ERROR_EPERM = 1, + POSIX_ERROR_ENOENT = 2, + POSIX_ERROR_EINTR = 4, + POSIX_ERROR_EIO = 5, + POSIX_ERROR_EAGAIN = 11, + POSIX_ERROR_EACCES = 13, + POSIX_ERROR_EEXIST = 17, + POSIX_ERROR_EXDEV = 18, + POSIX_ERROR_ENODEV = 19, + POSIX_ERROR_ENOTDIR = 20, + POSIX_ERROR_EISDIR = 21, + POSIX_ERROR_EINVAL = 22, + POSIX_ERROR_ENOSPC = 28, + POSIX_ERROR_ENOTEMPTY = 39, + POSIX_ERROR_ENODATA = 61 +}; +bool POSIXErrno_IsValid(int value); +const POSIXErrno POSIXErrno_MIN = POSIX_ERROR_EPERM; +const POSIXErrno POSIXErrno_MAX = POSIX_ERROR_NONE; +const int POSIXErrno_ARRAYSIZE = POSIXErrno_MAX + 1; + +const ::google::protobuf::EnumDescriptor* POSIXErrno_descriptor(); +inline const ::std::string& POSIXErrno_Name(POSIXErrno value) { + return ::google::protobuf::internal::NameOfEnum( + POSIXErrno_descriptor(), value); +} +inline bool POSIXErrno_Parse( + const ::std::string& name, POSIXErrno* value) { + return ::google::protobuf::internal::ParseNamedEnum( + POSIXErrno_descriptor(), name, value); +} +// =================================================================== + +class UserCredentials : public ::google::protobuf::Message { + public: + UserCredentials(); + virtual ~UserCredentials(); + + UserCredentials(const UserCredentials& from); + + inline UserCredentials& operator=(const UserCredentials& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const UserCredentials& default_instance(); + + void Swap(UserCredentials* other); + + // implements Message ---------------------------------------------- + + UserCredentials* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const UserCredentials& from); + void MergeFrom(const UserCredentials& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string username = 1; + inline bool has_username() const; + inline void clear_username(); + static const int kUsernameFieldNumber = 1; + inline const ::std::string& username() const; + inline void set_username(const ::std::string& value); + inline void set_username(const char* value); + inline void set_username(const char* value, size_t size); + inline ::std::string* mutable_username(); + inline ::std::string* release_username(); + inline void set_allocated_username(::std::string* username); + + // repeated string groups = 2; + inline int groups_size() const; + inline void clear_groups(); + static const int kGroupsFieldNumber = 2; + inline const ::std::string& groups(int index) const; + inline ::std::string* mutable_groups(int index); + inline void set_groups(int index, const ::std::string& value); + inline void set_groups(int index, const char* value); + inline void set_groups(int index, const char* value, size_t size); + inline ::std::string* add_groups(); + inline void add_groups(const ::std::string& value); + inline void add_groups(const char* value); + inline void add_groups(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& groups() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_groups(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.UserCredentials) + private: + inline void set_has_username(); + inline void clear_has_username(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* username_; + ::google::protobuf::RepeatedPtrField< ::std::string> groups_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fRPC_2eproto(); + + void InitAsDefaultInstance(); + static UserCredentials* default_instance_; +}; +// ------------------------------------------------------------------- + +class AuthPassword : public ::google::protobuf::Message { + public: + AuthPassword(); + virtual ~AuthPassword(); + + AuthPassword(const AuthPassword& from); + + inline AuthPassword& operator=(const AuthPassword& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const AuthPassword& default_instance(); + + void Swap(AuthPassword* other); + + // implements Message ---------------------------------------------- + + AuthPassword* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const AuthPassword& from); + void MergeFrom(const AuthPassword& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string password = 1; + inline bool has_password() const; + inline void clear_password(); + static const int kPasswordFieldNumber = 1; + inline const ::std::string& password() const; + inline void set_password(const ::std::string& value); + inline void set_password(const char* value); + inline void set_password(const char* value, size_t size); + inline ::std::string* mutable_password(); + inline ::std::string* release_password(); + inline void set_allocated_password(::std::string* password); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.AuthPassword) + private: + inline void set_has_password(); + inline void clear_has_password(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* password_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fRPC_2eproto(); + + void InitAsDefaultInstance(); + static AuthPassword* default_instance_; +}; +// ------------------------------------------------------------------- + +class Auth : public ::google::protobuf::Message { + public: + Auth(); + virtual ~Auth(); + + Auth(const Auth& from); + + inline Auth& operator=(const Auth& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Auth& default_instance(); + + void Swap(Auth* other); + + // implements Message ---------------------------------------------- + + Auth* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Auth& from); + void MergeFrom(const Auth& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.AuthType auth_type = 1; + inline bool has_auth_type() const; + inline void clear_auth_type(); + static const int kAuthTypeFieldNumber = 1; + inline ::xtreemfs::pbrpc::AuthType auth_type() const; + inline void set_auth_type(::xtreemfs::pbrpc::AuthType value); + + // optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + inline bool has_auth_passwd() const; + inline void clear_auth_passwd(); + static const int kAuthPasswdFieldNumber = 3; + inline const ::xtreemfs::pbrpc::AuthPassword& auth_passwd() const; + inline ::xtreemfs::pbrpc::AuthPassword* mutable_auth_passwd(); + inline ::xtreemfs::pbrpc::AuthPassword* release_auth_passwd(); + inline void set_allocated_auth_passwd(::xtreemfs::pbrpc::AuthPassword* auth_passwd); + + // optional bytes auth_data = 2; + inline bool has_auth_data() const; + inline void clear_auth_data(); + static const int kAuthDataFieldNumber = 2; + inline const ::std::string& auth_data() const; + inline void set_auth_data(const ::std::string& value); + inline void set_auth_data(const char* value); + inline void set_auth_data(const void* value, size_t size); + inline ::std::string* mutable_auth_data(); + inline ::std::string* release_auth_data(); + inline void set_allocated_auth_data(::std::string* auth_data); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Auth) + private: + inline void set_has_auth_type(); + inline void clear_has_auth_type(); + inline void set_has_auth_passwd(); + inline void clear_has_auth_passwd(); + inline void set_has_auth_data(); + inline void clear_has_auth_data(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::AuthPassword* auth_passwd_; + ::std::string* auth_data_; + int auth_type_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fRPC_2eproto(); + + void InitAsDefaultInstance(); + static Auth* default_instance_; +}; +// ------------------------------------------------------------------- + +class RPCHeader_RequestHeader : public ::google::protobuf::Message { + public: + RPCHeader_RequestHeader(); + virtual ~RPCHeader_RequestHeader(); + + RPCHeader_RequestHeader(const RPCHeader_RequestHeader& from); + + inline RPCHeader_RequestHeader& operator=(const RPCHeader_RequestHeader& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RPCHeader_RequestHeader& default_instance(); + + void Swap(RPCHeader_RequestHeader* other); + + // implements Message ---------------------------------------------- + + RPCHeader_RequestHeader* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RPCHeader_RequestHeader& from); + void MergeFrom(const RPCHeader_RequestHeader& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed32 interface_id = 1; + inline bool has_interface_id() const; + inline void clear_interface_id(); + static const int kInterfaceIdFieldNumber = 1; + inline ::google::protobuf::uint32 interface_id() const; + inline void set_interface_id(::google::protobuf::uint32 value); + + // required fixed32 proc_id = 2; + inline bool has_proc_id() const; + inline void clear_proc_id(); + static const int kProcIdFieldNumber = 2; + inline ::google::protobuf::uint32 proc_id() const; + inline void set_proc_id(::google::protobuf::uint32 value); + + // required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + inline bool has_user_creds() const; + inline void clear_user_creds(); + static const int kUserCredsFieldNumber = 3; + inline const ::xtreemfs::pbrpc::UserCredentials& user_creds() const; + inline ::xtreemfs::pbrpc::UserCredentials* mutable_user_creds(); + inline ::xtreemfs::pbrpc::UserCredentials* release_user_creds(); + inline void set_allocated_user_creds(::xtreemfs::pbrpc::UserCredentials* user_creds); + + // required .xtreemfs.pbrpc.Auth auth_data = 4; + inline bool has_auth_data() const; + inline void clear_auth_data(); + static const int kAuthDataFieldNumber = 4; + inline const ::xtreemfs::pbrpc::Auth& auth_data() const; + inline ::xtreemfs::pbrpc::Auth* mutable_auth_data(); + inline ::xtreemfs::pbrpc::Auth* release_auth_data(); + inline void set_allocated_auth_data(::xtreemfs::pbrpc::Auth* auth_data); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.RPCHeader.RequestHeader) + private: + inline void set_has_interface_id(); + inline void clear_has_interface_id(); + inline void set_has_proc_id(); + inline void clear_has_proc_id(); + inline void set_has_user_creds(); + inline void clear_has_user_creds(); + inline void set_has_auth_data(); + inline void clear_has_auth_data(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 interface_id_; + ::google::protobuf::uint32 proc_id_; + ::xtreemfs::pbrpc::UserCredentials* user_creds_; + ::xtreemfs::pbrpc::Auth* auth_data_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fRPC_2eproto(); + + void InitAsDefaultInstance(); + static RPCHeader_RequestHeader* default_instance_; +}; +// ------------------------------------------------------------------- + +class RPCHeader_ErrorResponse : public ::google::protobuf::Message { + public: + RPCHeader_ErrorResponse(); + virtual ~RPCHeader_ErrorResponse(); + + RPCHeader_ErrorResponse(const RPCHeader_ErrorResponse& from); + + inline RPCHeader_ErrorResponse& operator=(const RPCHeader_ErrorResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RPCHeader_ErrorResponse& default_instance(); + + void Swap(RPCHeader_ErrorResponse* other); + + // implements Message ---------------------------------------------- + + RPCHeader_ErrorResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RPCHeader_ErrorResponse& from); + void MergeFrom(const RPCHeader_ErrorResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.ErrorType error_type = 1; + inline bool has_error_type() const; + inline void clear_error_type(); + static const int kErrorTypeFieldNumber = 1; + inline ::xtreemfs::pbrpc::ErrorType error_type() const; + inline void set_error_type(::xtreemfs::pbrpc::ErrorType value); + + // optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + inline bool has_posix_errno() const; + inline void clear_posix_errno(); + static const int kPosixErrnoFieldNumber = 2; + inline ::xtreemfs::pbrpc::POSIXErrno posix_errno() const; + inline void set_posix_errno(::xtreemfs::pbrpc::POSIXErrno value); + + // optional string error_message = 3; + inline bool has_error_message() const; + inline void clear_error_message(); + static const int kErrorMessageFieldNumber = 3; + inline const ::std::string& error_message() const; + inline void set_error_message(const ::std::string& value); + inline void set_error_message(const char* value); + inline void set_error_message(const char* value, size_t size); + inline ::std::string* mutable_error_message(); + inline ::std::string* release_error_message(); + inline void set_allocated_error_message(::std::string* error_message); + + // optional string debug_info = 4; + inline bool has_debug_info() const; + inline void clear_debug_info(); + static const int kDebugInfoFieldNumber = 4; + inline const ::std::string& debug_info() const; + inline void set_debug_info(const ::std::string& value); + inline void set_debug_info(const char* value); + inline void set_debug_info(const char* value, size_t size); + inline ::std::string* mutable_debug_info(); + inline ::std::string* release_debug_info(); + inline void set_allocated_debug_info(::std::string* debug_info); + + // optional string redirect_to_server_uuid = 5; + inline bool has_redirect_to_server_uuid() const; + inline void clear_redirect_to_server_uuid(); + static const int kRedirectToServerUuidFieldNumber = 5; + inline const ::std::string& redirect_to_server_uuid() const; + inline void set_redirect_to_server_uuid(const ::std::string& value); + inline void set_redirect_to_server_uuid(const char* value); + inline void set_redirect_to_server_uuid(const char* value, size_t size); + inline ::std::string* mutable_redirect_to_server_uuid(); + inline ::std::string* release_redirect_to_server_uuid(); + inline void set_allocated_redirect_to_server_uuid(::std::string* redirect_to_server_uuid); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.RPCHeader.ErrorResponse) + private: + inline void set_has_error_type(); + inline void clear_has_error_type(); + inline void set_has_posix_errno(); + inline void clear_has_posix_errno(); + inline void set_has_error_message(); + inline void clear_has_error_message(); + inline void set_has_debug_info(); + inline void clear_has_debug_info(); + inline void set_has_redirect_to_server_uuid(); + inline void clear_has_redirect_to_server_uuid(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + int error_type_; + int posix_errno_; + ::std::string* error_message_; + ::std::string* debug_info_; + ::std::string* redirect_to_server_uuid_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; + + friend void protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fRPC_2eproto(); + + void InitAsDefaultInstance(); + static RPCHeader_ErrorResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class RPCHeader : public ::google::protobuf::Message { + public: + RPCHeader(); + virtual ~RPCHeader(); + + RPCHeader(const RPCHeader& from); + + inline RPCHeader& operator=(const RPCHeader& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RPCHeader& default_instance(); + + void Swap(RPCHeader* other); + + // implements Message ---------------------------------------------- + + RPCHeader* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RPCHeader& from); + void MergeFrom(const RPCHeader& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef RPCHeader_RequestHeader RequestHeader; + typedef RPCHeader_ErrorResponse ErrorResponse; + + // accessors ------------------------------------------------------- + + // required fixed32 call_id = 1; + inline bool has_call_id() const; + inline void clear_call_id(); + static const int kCallIdFieldNumber = 1; + inline ::google::protobuf::uint32 call_id() const; + inline void set_call_id(::google::protobuf::uint32 value); + + // required .xtreemfs.pbrpc.MessageType message_type = 2; + inline bool has_message_type() const; + inline void clear_message_type(); + static const int kMessageTypeFieldNumber = 2; + inline ::xtreemfs::pbrpc::MessageType message_type() const; + inline void set_message_type(::xtreemfs::pbrpc::MessageType value); + + // optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + inline bool has_request_header() const; + inline void clear_request_header(); + static const int kRequestHeaderFieldNumber = 3; + inline const ::xtreemfs::pbrpc::RPCHeader_RequestHeader& request_header() const; + inline ::xtreemfs::pbrpc::RPCHeader_RequestHeader* mutable_request_header(); + inline ::xtreemfs::pbrpc::RPCHeader_RequestHeader* release_request_header(); + inline void set_allocated_request_header(::xtreemfs::pbrpc::RPCHeader_RequestHeader* request_header); + + // optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + inline bool has_error_response() const; + inline void clear_error_response(); + static const int kErrorResponseFieldNumber = 4; + inline const ::xtreemfs::pbrpc::RPCHeader_ErrorResponse& error_response() const; + inline ::xtreemfs::pbrpc::RPCHeader_ErrorResponse* mutable_error_response(); + inline ::xtreemfs::pbrpc::RPCHeader_ErrorResponse* release_error_response(); + inline void set_allocated_error_response(::xtreemfs::pbrpc::RPCHeader_ErrorResponse* error_response); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.RPCHeader) + private: + inline void set_has_call_id(); + inline void clear_has_call_id(); + inline void set_has_message_type(); + inline void clear_has_message_type(); + inline void set_has_request_header(); + inline void clear_has_request_header(); + inline void set_has_error_response(); + inline void clear_has_error_response(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 call_id_; + int message_type_; + ::xtreemfs::pbrpc::RPCHeader_RequestHeader* request_header_; + ::xtreemfs::pbrpc::RPCHeader_ErrorResponse* error_response_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_AssignDesc_pbrpc_2fRPC_2eproto(); + friend void protobuf_ShutdownFile_pbrpc_2fRPC_2eproto(); + + void InitAsDefaultInstance(); + static RPCHeader* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// UserCredentials + +// required string username = 1; +inline bool UserCredentials::has_username() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void UserCredentials::set_has_username() { + _has_bits_[0] |= 0x00000001u; +} +inline void UserCredentials::clear_has_username() { + _has_bits_[0] &= ~0x00000001u; +} +inline void UserCredentials::clear_username() { + if (username_ != &::google::protobuf::internal::kEmptyString) { + username_->clear(); + } + clear_has_username(); +} +inline const ::std::string& UserCredentials::username() const { + return *username_; +} +inline void UserCredentials::set_username(const ::std::string& value) { + set_has_username(); + if (username_ == &::google::protobuf::internal::kEmptyString) { + username_ = new ::std::string; + } + username_->assign(value); +} +inline void UserCredentials::set_username(const char* value) { + set_has_username(); + if (username_ == &::google::protobuf::internal::kEmptyString) { + username_ = new ::std::string; + } + username_->assign(value); +} +inline void UserCredentials::set_username(const char* value, size_t size) { + set_has_username(); + if (username_ == &::google::protobuf::internal::kEmptyString) { + username_ = new ::std::string; + } + username_->assign(reinterpret_cast(value), size); +} +inline ::std::string* UserCredentials::mutable_username() { + set_has_username(); + if (username_ == &::google::protobuf::internal::kEmptyString) { + username_ = new ::std::string; + } + return username_; +} +inline ::std::string* UserCredentials::release_username() { + clear_has_username(); + if (username_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = username_; + username_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void UserCredentials::set_allocated_username(::std::string* username) { + if (username_ != &::google::protobuf::internal::kEmptyString) { + delete username_; + } + if (username) { + set_has_username(); + username_ = username; + } else { + clear_has_username(); + username_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// repeated string groups = 2; +inline int UserCredentials::groups_size() const { + return groups_.size(); +} +inline void UserCredentials::clear_groups() { + groups_.Clear(); +} +inline const ::std::string& UserCredentials::groups(int index) const { + return groups_.Get(index); +} +inline ::std::string* UserCredentials::mutable_groups(int index) { + return groups_.Mutable(index); +} +inline void UserCredentials::set_groups(int index, const ::std::string& value) { + groups_.Mutable(index)->assign(value); +} +inline void UserCredentials::set_groups(int index, const char* value) { + groups_.Mutable(index)->assign(value); +} +inline void UserCredentials::set_groups(int index, const char* value, size_t size) { + groups_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* UserCredentials::add_groups() { + return groups_.Add(); +} +inline void UserCredentials::add_groups(const ::std::string& value) { + groups_.Add()->assign(value); +} +inline void UserCredentials::add_groups(const char* value) { + groups_.Add()->assign(value); +} +inline void UserCredentials::add_groups(const char* value, size_t size) { + groups_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +UserCredentials::groups() const { + return groups_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +UserCredentials::mutable_groups() { + return &groups_; +} + +// ------------------------------------------------------------------- + +// AuthPassword + +// required string password = 1; +inline bool AuthPassword::has_password() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void AuthPassword::set_has_password() { + _has_bits_[0] |= 0x00000001u; +} +inline void AuthPassword::clear_has_password() { + _has_bits_[0] &= ~0x00000001u; +} +inline void AuthPassword::clear_password() { + if (password_ != &::google::protobuf::internal::kEmptyString) { + password_->clear(); + } + clear_has_password(); +} +inline const ::std::string& AuthPassword::password() const { + return *password_; +} +inline void AuthPassword::set_password(const ::std::string& value) { + set_has_password(); + if (password_ == &::google::protobuf::internal::kEmptyString) { + password_ = new ::std::string; + } + password_->assign(value); +} +inline void AuthPassword::set_password(const char* value) { + set_has_password(); + if (password_ == &::google::protobuf::internal::kEmptyString) { + password_ = new ::std::string; + } + password_->assign(value); +} +inline void AuthPassword::set_password(const char* value, size_t size) { + set_has_password(); + if (password_ == &::google::protobuf::internal::kEmptyString) { + password_ = new ::std::string; + } + password_->assign(reinterpret_cast(value), size); +} +inline ::std::string* AuthPassword::mutable_password() { + set_has_password(); + if (password_ == &::google::protobuf::internal::kEmptyString) { + password_ = new ::std::string; + } + return password_; +} +inline ::std::string* AuthPassword::release_password() { + clear_has_password(); + if (password_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = password_; + password_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void AuthPassword::set_allocated_password(::std::string* password) { + if (password_ != &::google::protobuf::internal::kEmptyString) { + delete password_; + } + if (password) { + set_has_password(); + password_ = password; + } else { + clear_has_password(); + password_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// Auth + +// required .xtreemfs.pbrpc.AuthType auth_type = 1; +inline bool Auth::has_auth_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Auth::set_has_auth_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void Auth::clear_has_auth_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Auth::clear_auth_type() { + auth_type_ = 0; + clear_has_auth_type(); +} +inline ::xtreemfs::pbrpc::AuthType Auth::auth_type() const { + return static_cast< ::xtreemfs::pbrpc::AuthType >(auth_type_); +} +inline void Auth::set_auth_type(::xtreemfs::pbrpc::AuthType value) { + assert(::xtreemfs::pbrpc::AuthType_IsValid(value)); + set_has_auth_type(); + auth_type_ = value; +} + +// optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; +inline bool Auth::has_auth_passwd() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Auth::set_has_auth_passwd() { + _has_bits_[0] |= 0x00000002u; +} +inline void Auth::clear_has_auth_passwd() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Auth::clear_auth_passwd() { + if (auth_passwd_ != NULL) auth_passwd_->::xtreemfs::pbrpc::AuthPassword::Clear(); + clear_has_auth_passwd(); +} +inline const ::xtreemfs::pbrpc::AuthPassword& Auth::auth_passwd() const { + return auth_passwd_ != NULL ? *auth_passwd_ : *default_instance_->auth_passwd_; +} +inline ::xtreemfs::pbrpc::AuthPassword* Auth::mutable_auth_passwd() { + set_has_auth_passwd(); + if (auth_passwd_ == NULL) auth_passwd_ = new ::xtreemfs::pbrpc::AuthPassword; + return auth_passwd_; +} +inline ::xtreemfs::pbrpc::AuthPassword* Auth::release_auth_passwd() { + clear_has_auth_passwd(); + ::xtreemfs::pbrpc::AuthPassword* temp = auth_passwd_; + auth_passwd_ = NULL; + return temp; +} +inline void Auth::set_allocated_auth_passwd(::xtreemfs::pbrpc::AuthPassword* auth_passwd) { + delete auth_passwd_; + auth_passwd_ = auth_passwd; + if (auth_passwd) { + set_has_auth_passwd(); + } else { + clear_has_auth_passwd(); + } +} + +// optional bytes auth_data = 2; +inline bool Auth::has_auth_data() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Auth::set_has_auth_data() { + _has_bits_[0] |= 0x00000004u; +} +inline void Auth::clear_has_auth_data() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Auth::clear_auth_data() { + if (auth_data_ != &::google::protobuf::internal::kEmptyString) { + auth_data_->clear(); + } + clear_has_auth_data(); +} +inline const ::std::string& Auth::auth_data() const { + return *auth_data_; +} +inline void Auth::set_auth_data(const ::std::string& value) { + set_has_auth_data(); + if (auth_data_ == &::google::protobuf::internal::kEmptyString) { + auth_data_ = new ::std::string; + } + auth_data_->assign(value); +} +inline void Auth::set_auth_data(const char* value) { + set_has_auth_data(); + if (auth_data_ == &::google::protobuf::internal::kEmptyString) { + auth_data_ = new ::std::string; + } + auth_data_->assign(value); +} +inline void Auth::set_auth_data(const void* value, size_t size) { + set_has_auth_data(); + if (auth_data_ == &::google::protobuf::internal::kEmptyString) { + auth_data_ = new ::std::string; + } + auth_data_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Auth::mutable_auth_data() { + set_has_auth_data(); + if (auth_data_ == &::google::protobuf::internal::kEmptyString) { + auth_data_ = new ::std::string; + } + return auth_data_; +} +inline ::std::string* Auth::release_auth_data() { + clear_has_auth_data(); + if (auth_data_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = auth_data_; + auth_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void Auth::set_allocated_auth_data(::std::string* auth_data) { + if (auth_data_ != &::google::protobuf::internal::kEmptyString) { + delete auth_data_; + } + if (auth_data) { + set_has_auth_data(); + auth_data_ = auth_data; + } else { + clear_has_auth_data(); + auth_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// RPCHeader_RequestHeader + +// required fixed32 interface_id = 1; +inline bool RPCHeader_RequestHeader::has_interface_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RPCHeader_RequestHeader::set_has_interface_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void RPCHeader_RequestHeader::clear_has_interface_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RPCHeader_RequestHeader::clear_interface_id() { + interface_id_ = 0u; + clear_has_interface_id(); +} +inline ::google::protobuf::uint32 RPCHeader_RequestHeader::interface_id() const { + return interface_id_; +} +inline void RPCHeader_RequestHeader::set_interface_id(::google::protobuf::uint32 value) { + set_has_interface_id(); + interface_id_ = value; +} + +// required fixed32 proc_id = 2; +inline bool RPCHeader_RequestHeader::has_proc_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void RPCHeader_RequestHeader::set_has_proc_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void RPCHeader_RequestHeader::clear_has_proc_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void RPCHeader_RequestHeader::clear_proc_id() { + proc_id_ = 0u; + clear_has_proc_id(); +} +inline ::google::protobuf::uint32 RPCHeader_RequestHeader::proc_id() const { + return proc_id_; +} +inline void RPCHeader_RequestHeader::set_proc_id(::google::protobuf::uint32 value) { + set_has_proc_id(); + proc_id_ = value; +} + +// required .xtreemfs.pbrpc.UserCredentials user_creds = 3; +inline bool RPCHeader_RequestHeader::has_user_creds() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void RPCHeader_RequestHeader::set_has_user_creds() { + _has_bits_[0] |= 0x00000004u; +} +inline void RPCHeader_RequestHeader::clear_has_user_creds() { + _has_bits_[0] &= ~0x00000004u; +} +inline void RPCHeader_RequestHeader::clear_user_creds() { + if (user_creds_ != NULL) user_creds_->::xtreemfs::pbrpc::UserCredentials::Clear(); + clear_has_user_creds(); +} +inline const ::xtreemfs::pbrpc::UserCredentials& RPCHeader_RequestHeader::user_creds() const { + return user_creds_ != NULL ? *user_creds_ : *default_instance_->user_creds_; +} +inline ::xtreemfs::pbrpc::UserCredentials* RPCHeader_RequestHeader::mutable_user_creds() { + set_has_user_creds(); + if (user_creds_ == NULL) user_creds_ = new ::xtreemfs::pbrpc::UserCredentials; + return user_creds_; +} +inline ::xtreemfs::pbrpc::UserCredentials* RPCHeader_RequestHeader::release_user_creds() { + clear_has_user_creds(); + ::xtreemfs::pbrpc::UserCredentials* temp = user_creds_; + user_creds_ = NULL; + return temp; +} +inline void RPCHeader_RequestHeader::set_allocated_user_creds(::xtreemfs::pbrpc::UserCredentials* user_creds) { + delete user_creds_; + user_creds_ = user_creds; + if (user_creds) { + set_has_user_creds(); + } else { + clear_has_user_creds(); + } +} + +// required .xtreemfs.pbrpc.Auth auth_data = 4; +inline bool RPCHeader_RequestHeader::has_auth_data() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void RPCHeader_RequestHeader::set_has_auth_data() { + _has_bits_[0] |= 0x00000008u; +} +inline void RPCHeader_RequestHeader::clear_has_auth_data() { + _has_bits_[0] &= ~0x00000008u; +} +inline void RPCHeader_RequestHeader::clear_auth_data() { + if (auth_data_ != NULL) auth_data_->::xtreemfs::pbrpc::Auth::Clear(); + clear_has_auth_data(); +} +inline const ::xtreemfs::pbrpc::Auth& RPCHeader_RequestHeader::auth_data() const { + return auth_data_ != NULL ? *auth_data_ : *default_instance_->auth_data_; +} +inline ::xtreemfs::pbrpc::Auth* RPCHeader_RequestHeader::mutable_auth_data() { + set_has_auth_data(); + if (auth_data_ == NULL) auth_data_ = new ::xtreemfs::pbrpc::Auth; + return auth_data_; +} +inline ::xtreemfs::pbrpc::Auth* RPCHeader_RequestHeader::release_auth_data() { + clear_has_auth_data(); + ::xtreemfs::pbrpc::Auth* temp = auth_data_; + auth_data_ = NULL; + return temp; +} +inline void RPCHeader_RequestHeader::set_allocated_auth_data(::xtreemfs::pbrpc::Auth* auth_data) { + delete auth_data_; + auth_data_ = auth_data; + if (auth_data) { + set_has_auth_data(); + } else { + clear_has_auth_data(); + } +} + +// ------------------------------------------------------------------- + +// RPCHeader_ErrorResponse + +// required .xtreemfs.pbrpc.ErrorType error_type = 1; +inline bool RPCHeader_ErrorResponse::has_error_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RPCHeader_ErrorResponse::set_has_error_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void RPCHeader_ErrorResponse::clear_has_error_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RPCHeader_ErrorResponse::clear_error_type() { + error_type_ = 1; + clear_has_error_type(); +} +inline ::xtreemfs::pbrpc::ErrorType RPCHeader_ErrorResponse::error_type() const { + return static_cast< ::xtreemfs::pbrpc::ErrorType >(error_type_); +} +inline void RPCHeader_ErrorResponse::set_error_type(::xtreemfs::pbrpc::ErrorType value) { + assert(::xtreemfs::pbrpc::ErrorType_IsValid(value)); + set_has_error_type(); + error_type_ = value; +} + +// optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; +inline bool RPCHeader_ErrorResponse::has_posix_errno() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void RPCHeader_ErrorResponse::set_has_posix_errno() { + _has_bits_[0] |= 0x00000002u; +} +inline void RPCHeader_ErrorResponse::clear_has_posix_errno() { + _has_bits_[0] &= ~0x00000002u; +} +inline void RPCHeader_ErrorResponse::clear_posix_errno() { + posix_errno_ = 9999; + clear_has_posix_errno(); +} +inline ::xtreemfs::pbrpc::POSIXErrno RPCHeader_ErrorResponse::posix_errno() const { + return static_cast< ::xtreemfs::pbrpc::POSIXErrno >(posix_errno_); +} +inline void RPCHeader_ErrorResponse::set_posix_errno(::xtreemfs::pbrpc::POSIXErrno value) { + assert(::xtreemfs::pbrpc::POSIXErrno_IsValid(value)); + set_has_posix_errno(); + posix_errno_ = value; +} + +// optional string error_message = 3; +inline bool RPCHeader_ErrorResponse::has_error_message() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void RPCHeader_ErrorResponse::set_has_error_message() { + _has_bits_[0] |= 0x00000004u; +} +inline void RPCHeader_ErrorResponse::clear_has_error_message() { + _has_bits_[0] &= ~0x00000004u; +} +inline void RPCHeader_ErrorResponse::clear_error_message() { + if (error_message_ != &::google::protobuf::internal::kEmptyString) { + error_message_->clear(); + } + clear_has_error_message(); +} +inline const ::std::string& RPCHeader_ErrorResponse::error_message() const { + return *error_message_; +} +inline void RPCHeader_ErrorResponse::set_error_message(const ::std::string& value) { + set_has_error_message(); + if (error_message_ == &::google::protobuf::internal::kEmptyString) { + error_message_ = new ::std::string; + } + error_message_->assign(value); +} +inline void RPCHeader_ErrorResponse::set_error_message(const char* value) { + set_has_error_message(); + if (error_message_ == &::google::protobuf::internal::kEmptyString) { + error_message_ = new ::std::string; + } + error_message_->assign(value); +} +inline void RPCHeader_ErrorResponse::set_error_message(const char* value, size_t size) { + set_has_error_message(); + if (error_message_ == &::google::protobuf::internal::kEmptyString) { + error_message_ = new ::std::string; + } + error_message_->assign(reinterpret_cast(value), size); +} +inline ::std::string* RPCHeader_ErrorResponse::mutable_error_message() { + set_has_error_message(); + if (error_message_ == &::google::protobuf::internal::kEmptyString) { + error_message_ = new ::std::string; + } + return error_message_; +} +inline ::std::string* RPCHeader_ErrorResponse::release_error_message() { + clear_has_error_message(); + if (error_message_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = error_message_; + error_message_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void RPCHeader_ErrorResponse::set_allocated_error_message(::std::string* error_message) { + if (error_message_ != &::google::protobuf::internal::kEmptyString) { + delete error_message_; + } + if (error_message) { + set_has_error_message(); + error_message_ = error_message; + } else { + clear_has_error_message(); + error_message_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string debug_info = 4; +inline bool RPCHeader_ErrorResponse::has_debug_info() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void RPCHeader_ErrorResponse::set_has_debug_info() { + _has_bits_[0] |= 0x00000008u; +} +inline void RPCHeader_ErrorResponse::clear_has_debug_info() { + _has_bits_[0] &= ~0x00000008u; +} +inline void RPCHeader_ErrorResponse::clear_debug_info() { + if (debug_info_ != &::google::protobuf::internal::kEmptyString) { + debug_info_->clear(); + } + clear_has_debug_info(); +} +inline const ::std::string& RPCHeader_ErrorResponse::debug_info() const { + return *debug_info_; +} +inline void RPCHeader_ErrorResponse::set_debug_info(const ::std::string& value) { + set_has_debug_info(); + if (debug_info_ == &::google::protobuf::internal::kEmptyString) { + debug_info_ = new ::std::string; + } + debug_info_->assign(value); +} +inline void RPCHeader_ErrorResponse::set_debug_info(const char* value) { + set_has_debug_info(); + if (debug_info_ == &::google::protobuf::internal::kEmptyString) { + debug_info_ = new ::std::string; + } + debug_info_->assign(value); +} +inline void RPCHeader_ErrorResponse::set_debug_info(const char* value, size_t size) { + set_has_debug_info(); + if (debug_info_ == &::google::protobuf::internal::kEmptyString) { + debug_info_ = new ::std::string; + } + debug_info_->assign(reinterpret_cast(value), size); +} +inline ::std::string* RPCHeader_ErrorResponse::mutable_debug_info() { + set_has_debug_info(); + if (debug_info_ == &::google::protobuf::internal::kEmptyString) { + debug_info_ = new ::std::string; + } + return debug_info_; +} +inline ::std::string* RPCHeader_ErrorResponse::release_debug_info() { + clear_has_debug_info(); + if (debug_info_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = debug_info_; + debug_info_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void RPCHeader_ErrorResponse::set_allocated_debug_info(::std::string* debug_info) { + if (debug_info_ != &::google::protobuf::internal::kEmptyString) { + delete debug_info_; + } + if (debug_info) { + set_has_debug_info(); + debug_info_ = debug_info; + } else { + clear_has_debug_info(); + debug_info_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string redirect_to_server_uuid = 5; +inline bool RPCHeader_ErrorResponse::has_redirect_to_server_uuid() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void RPCHeader_ErrorResponse::set_has_redirect_to_server_uuid() { + _has_bits_[0] |= 0x00000010u; +} +inline void RPCHeader_ErrorResponse::clear_has_redirect_to_server_uuid() { + _has_bits_[0] &= ~0x00000010u; +} +inline void RPCHeader_ErrorResponse::clear_redirect_to_server_uuid() { + if (redirect_to_server_uuid_ != &::google::protobuf::internal::kEmptyString) { + redirect_to_server_uuid_->clear(); + } + clear_has_redirect_to_server_uuid(); +} +inline const ::std::string& RPCHeader_ErrorResponse::redirect_to_server_uuid() const { + return *redirect_to_server_uuid_; +} +inline void RPCHeader_ErrorResponse::set_redirect_to_server_uuid(const ::std::string& value) { + set_has_redirect_to_server_uuid(); + if (redirect_to_server_uuid_ == &::google::protobuf::internal::kEmptyString) { + redirect_to_server_uuid_ = new ::std::string; + } + redirect_to_server_uuid_->assign(value); +} +inline void RPCHeader_ErrorResponse::set_redirect_to_server_uuid(const char* value) { + set_has_redirect_to_server_uuid(); + if (redirect_to_server_uuid_ == &::google::protobuf::internal::kEmptyString) { + redirect_to_server_uuid_ = new ::std::string; + } + redirect_to_server_uuid_->assign(value); +} +inline void RPCHeader_ErrorResponse::set_redirect_to_server_uuid(const char* value, size_t size) { + set_has_redirect_to_server_uuid(); + if (redirect_to_server_uuid_ == &::google::protobuf::internal::kEmptyString) { + redirect_to_server_uuid_ = new ::std::string; + } + redirect_to_server_uuid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* RPCHeader_ErrorResponse::mutable_redirect_to_server_uuid() { + set_has_redirect_to_server_uuid(); + if (redirect_to_server_uuid_ == &::google::protobuf::internal::kEmptyString) { + redirect_to_server_uuid_ = new ::std::string; + } + return redirect_to_server_uuid_; +} +inline ::std::string* RPCHeader_ErrorResponse::release_redirect_to_server_uuid() { + clear_has_redirect_to_server_uuid(); + if (redirect_to_server_uuid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = redirect_to_server_uuid_; + redirect_to_server_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void RPCHeader_ErrorResponse::set_allocated_redirect_to_server_uuid(::std::string* redirect_to_server_uuid) { + if (redirect_to_server_uuid_ != &::google::protobuf::internal::kEmptyString) { + delete redirect_to_server_uuid_; + } + if (redirect_to_server_uuid) { + set_has_redirect_to_server_uuid(); + redirect_to_server_uuid_ = redirect_to_server_uuid; + } else { + clear_has_redirect_to_server_uuid(); + redirect_to_server_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// RPCHeader + +// required fixed32 call_id = 1; +inline bool RPCHeader::has_call_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RPCHeader::set_has_call_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void RPCHeader::clear_has_call_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RPCHeader::clear_call_id() { + call_id_ = 0u; + clear_has_call_id(); +} +inline ::google::protobuf::uint32 RPCHeader::call_id() const { + return call_id_; +} +inline void RPCHeader::set_call_id(::google::protobuf::uint32 value) { + set_has_call_id(); + call_id_ = value; +} + +// required .xtreemfs.pbrpc.MessageType message_type = 2; +inline bool RPCHeader::has_message_type() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void RPCHeader::set_has_message_type() { + _has_bits_[0] |= 0x00000002u; +} +inline void RPCHeader::clear_has_message_type() { + _has_bits_[0] &= ~0x00000002u; +} +inline void RPCHeader::clear_message_type() { + message_type_ = 0; + clear_has_message_type(); +} +inline ::xtreemfs::pbrpc::MessageType RPCHeader::message_type() const { + return static_cast< ::xtreemfs::pbrpc::MessageType >(message_type_); +} +inline void RPCHeader::set_message_type(::xtreemfs::pbrpc::MessageType value) { + assert(::xtreemfs::pbrpc::MessageType_IsValid(value)); + set_has_message_type(); + message_type_ = value; +} + +// optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; +inline bool RPCHeader::has_request_header() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void RPCHeader::set_has_request_header() { + _has_bits_[0] |= 0x00000004u; +} +inline void RPCHeader::clear_has_request_header() { + _has_bits_[0] &= ~0x00000004u; +} +inline void RPCHeader::clear_request_header() { + if (request_header_ != NULL) request_header_->::xtreemfs::pbrpc::RPCHeader_RequestHeader::Clear(); + clear_has_request_header(); +} +inline const ::xtreemfs::pbrpc::RPCHeader_RequestHeader& RPCHeader::request_header() const { + return request_header_ != NULL ? *request_header_ : *default_instance_->request_header_; +} +inline ::xtreemfs::pbrpc::RPCHeader_RequestHeader* RPCHeader::mutable_request_header() { + set_has_request_header(); + if (request_header_ == NULL) request_header_ = new ::xtreemfs::pbrpc::RPCHeader_RequestHeader; + return request_header_; +} +inline ::xtreemfs::pbrpc::RPCHeader_RequestHeader* RPCHeader::release_request_header() { + clear_has_request_header(); + ::xtreemfs::pbrpc::RPCHeader_RequestHeader* temp = request_header_; + request_header_ = NULL; + return temp; +} +inline void RPCHeader::set_allocated_request_header(::xtreemfs::pbrpc::RPCHeader_RequestHeader* request_header) { + delete request_header_; + request_header_ = request_header; + if (request_header) { + set_has_request_header(); + } else { + clear_has_request_header(); + } +} + +// optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; +inline bool RPCHeader::has_error_response() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void RPCHeader::set_has_error_response() { + _has_bits_[0] |= 0x00000008u; +} +inline void RPCHeader::clear_has_error_response() { + _has_bits_[0] &= ~0x00000008u; +} +inline void RPCHeader::clear_error_response() { + if (error_response_ != NULL) error_response_->::xtreemfs::pbrpc::RPCHeader_ErrorResponse::Clear(); + clear_has_error_response(); +} +inline const ::xtreemfs::pbrpc::RPCHeader_ErrorResponse& RPCHeader::error_response() const { + return error_response_ != NULL ? *error_response_ : *default_instance_->error_response_; +} +inline ::xtreemfs::pbrpc::RPCHeader_ErrorResponse* RPCHeader::mutable_error_response() { + set_has_error_response(); + if (error_response_ == NULL) error_response_ = new ::xtreemfs::pbrpc::RPCHeader_ErrorResponse; + return error_response_; +} +inline ::xtreemfs::pbrpc::RPCHeader_ErrorResponse* RPCHeader::release_error_response() { + clear_has_error_response(); + ::xtreemfs::pbrpc::RPCHeader_ErrorResponse* temp = error_response_; + error_response_ = NULL; + return temp; +} +inline void RPCHeader::set_allocated_error_response(::xtreemfs::pbrpc::RPCHeader_ErrorResponse* error_response) { + delete error_response_; + error_response_ = error_response; + if (error_response) { + set_has_error_response(); + } else { + clear_has_error_response(); + } +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::MessageType>() { + return ::xtreemfs::pbrpc::MessageType_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::AuthType>() { + return ::xtreemfs::pbrpc::AuthType_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::ErrorType>() { + return ::xtreemfs::pbrpc::ErrorType_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::POSIXErrno>() { + return ::xtreemfs::pbrpc::POSIXErrno_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_pbrpc_2fRPC_2eproto__INCLUDED diff --git a/cpp/generated/xtreemfs/DIR.pb.cc b/cpp/generated/xtreemfs/DIR.pb.cc new file mode 100644 index 0000000..0fe7bb2 --- /dev/null +++ b/cpp/generated/xtreemfs/DIR.pb.cc @@ -0,0 +1,5586 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/DIR.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "xtreemfs/DIR.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +namespace { + +const ::google::protobuf::Descriptor* AddressMapping_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + AddressMapping_reflection_ = NULL; +const ::google::protobuf::Descriptor* AddressMappingSet_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + AddressMappingSet_reflection_ = NULL; +const ::google::protobuf::Descriptor* DirService_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + DirService_reflection_ = NULL; +const ::google::protobuf::Descriptor* ServiceDataMap_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ServiceDataMap_reflection_ = NULL; +const ::google::protobuf::Descriptor* Service_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Service_reflection_ = NULL; +const ::google::protobuf::Descriptor* ServiceSet_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ServiceSet_reflection_ = NULL; +const ::google::protobuf::Descriptor* Configuration_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Configuration_reflection_ = NULL; +const ::google::protobuf::Descriptor* addressMappingGetRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + addressMappingGetRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* addressMappingGetResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + addressMappingGetResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* addressMappingSetResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + addressMappingSetResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* globalTimeSGetResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + globalTimeSGetResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* serviceDeregisterRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + serviceDeregisterRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* serviceGetByNameRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + serviceGetByNameRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* serviceGetByUUIDRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + serviceGetByUUIDRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* serviceGetByTypeRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + serviceGetByTypeRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* serviceRegisterRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + serviceRegisterRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* serviceRegisterResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + serviceRegisterResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* configurationGetRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + configurationGetRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* configurationSetResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + configurationSetResponse_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* ServiceType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ServiceStatus_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto() { + protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "xtreemfs/DIR.proto"); + GOOGLE_CHECK(file != NULL); + AddressMapping_descriptor_ = file->message_type(0); + static const int AddressMapping_offsets_[8] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMapping, uuid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMapping, version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMapping, protocol_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMapping, address_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMapping, port_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMapping, match_network_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMapping, ttl_s_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMapping, uri_), + }; + AddressMapping_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + AddressMapping_descriptor_, + AddressMapping::default_instance_, + AddressMapping_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMapping, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMapping, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(AddressMapping)); + AddressMappingSet_descriptor_ = file->message_type(1); + static const int AddressMappingSet_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMappingSet, mappings_), + }; + AddressMappingSet_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + AddressMappingSet_descriptor_, + AddressMappingSet::default_instance_, + AddressMappingSet_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMappingSet, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AddressMappingSet, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(AddressMappingSet)); + DirService_descriptor_ = file->message_type(2); + static const int DirService_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirService, address_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirService, port_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirService, protocol_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirService, interface_version_), + }; + DirService_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + DirService_descriptor_, + DirService::default_instance_, + DirService_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirService, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirService, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(DirService)); + ServiceDataMap_descriptor_ = file->message_type(3); + static const int ServiceDataMap_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDataMap, data_), + }; + ServiceDataMap_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ServiceDataMap_descriptor_, + ServiceDataMap::default_instance_, + ServiceDataMap_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDataMap, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDataMap, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ServiceDataMap)); + Service_descriptor_ = file->message_type(4); + static const int Service_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Service, type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Service, uuid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Service, version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Service, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Service, last_updated_s_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Service, data_), + }; + Service_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Service_descriptor_, + Service::default_instance_, + Service_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Service, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Service, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Service)); + ServiceSet_descriptor_ = file->message_type(5); + static const int ServiceSet_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceSet, services_), + }; + ServiceSet_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ServiceSet_descriptor_, + ServiceSet::default_instance_, + ServiceSet_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceSet, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceSet, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ServiceSet)); + Configuration_descriptor_ = file->message_type(6); + static const int Configuration_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Configuration, uuid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Configuration, parameter_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Configuration, version_), + }; + Configuration_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Configuration_descriptor_, + Configuration::default_instance_, + Configuration_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Configuration, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Configuration, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Configuration)); + addressMappingGetRequest_descriptor_ = file->message_type(7); + static const int addressMappingGetRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(addressMappingGetRequest, uuid_), + }; + addressMappingGetRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + addressMappingGetRequest_descriptor_, + addressMappingGetRequest::default_instance_, + addressMappingGetRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(addressMappingGetRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(addressMappingGetRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(addressMappingGetRequest)); + addressMappingGetResponse_descriptor_ = file->message_type(8); + static const int addressMappingGetResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(addressMappingGetResponse, result_), + }; + addressMappingGetResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + addressMappingGetResponse_descriptor_, + addressMappingGetResponse::default_instance_, + addressMappingGetResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(addressMappingGetResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(addressMappingGetResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(addressMappingGetResponse)); + addressMappingSetResponse_descriptor_ = file->message_type(9); + static const int addressMappingSetResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(addressMappingSetResponse, new_version_), + }; + addressMappingSetResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + addressMappingSetResponse_descriptor_, + addressMappingSetResponse::default_instance_, + addressMappingSetResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(addressMappingSetResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(addressMappingSetResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(addressMappingSetResponse)); + globalTimeSGetResponse_descriptor_ = file->message_type(10); + static const int globalTimeSGetResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(globalTimeSGetResponse, time_in_seconds_), + }; + globalTimeSGetResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + globalTimeSGetResponse_descriptor_, + globalTimeSGetResponse::default_instance_, + globalTimeSGetResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(globalTimeSGetResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(globalTimeSGetResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(globalTimeSGetResponse)); + serviceDeregisterRequest_descriptor_ = file->message_type(11); + static const int serviceDeregisterRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceDeregisterRequest, uuid_), + }; + serviceDeregisterRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + serviceDeregisterRequest_descriptor_, + serviceDeregisterRequest::default_instance_, + serviceDeregisterRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceDeregisterRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceDeregisterRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(serviceDeregisterRequest)); + serviceGetByNameRequest_descriptor_ = file->message_type(12); + static const int serviceGetByNameRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceGetByNameRequest, name_), + }; + serviceGetByNameRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + serviceGetByNameRequest_descriptor_, + serviceGetByNameRequest::default_instance_, + serviceGetByNameRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceGetByNameRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceGetByNameRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(serviceGetByNameRequest)); + serviceGetByUUIDRequest_descriptor_ = file->message_type(13); + static const int serviceGetByUUIDRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceGetByUUIDRequest, name_), + }; + serviceGetByUUIDRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + serviceGetByUUIDRequest_descriptor_, + serviceGetByUUIDRequest::default_instance_, + serviceGetByUUIDRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceGetByUUIDRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceGetByUUIDRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(serviceGetByUUIDRequest)); + serviceGetByTypeRequest_descriptor_ = file->message_type(14); + static const int serviceGetByTypeRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceGetByTypeRequest, type_), + }; + serviceGetByTypeRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + serviceGetByTypeRequest_descriptor_, + serviceGetByTypeRequest::default_instance_, + serviceGetByTypeRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceGetByTypeRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceGetByTypeRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(serviceGetByTypeRequest)); + serviceRegisterRequest_descriptor_ = file->message_type(15); + static const int serviceRegisterRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceRegisterRequest, service_), + }; + serviceRegisterRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + serviceRegisterRequest_descriptor_, + serviceRegisterRequest::default_instance_, + serviceRegisterRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceRegisterRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceRegisterRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(serviceRegisterRequest)); + serviceRegisterResponse_descriptor_ = file->message_type(16); + static const int serviceRegisterResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceRegisterResponse, new_version_), + }; + serviceRegisterResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + serviceRegisterResponse_descriptor_, + serviceRegisterResponse::default_instance_, + serviceRegisterResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceRegisterResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(serviceRegisterResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(serviceRegisterResponse)); + configurationGetRequest_descriptor_ = file->message_type(17); + static const int configurationGetRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(configurationGetRequest, uuid_), + }; + configurationGetRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + configurationGetRequest_descriptor_, + configurationGetRequest::default_instance_, + configurationGetRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(configurationGetRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(configurationGetRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(configurationGetRequest)); + configurationSetResponse_descriptor_ = file->message_type(18); + static const int configurationSetResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(configurationSetResponse, new_version_), + }; + configurationSetResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + configurationSetResponse_descriptor_, + configurationSetResponse::default_instance_, + configurationSetResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(configurationSetResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(configurationSetResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(configurationSetResponse)); + ServiceType_descriptor_ = file->enum_type(0); + ServiceStatus_descriptor_ = file->enum_type(1); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_xtreemfs_2fDIR_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + AddressMapping_descriptor_, &AddressMapping::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + AddressMappingSet_descriptor_, &AddressMappingSet::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + DirService_descriptor_, &DirService::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ServiceDataMap_descriptor_, &ServiceDataMap::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Service_descriptor_, &Service::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ServiceSet_descriptor_, &ServiceSet::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Configuration_descriptor_, &Configuration::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + addressMappingGetRequest_descriptor_, &addressMappingGetRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + addressMappingGetResponse_descriptor_, &addressMappingGetResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + addressMappingSetResponse_descriptor_, &addressMappingSetResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + globalTimeSGetResponse_descriptor_, &globalTimeSGetResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + serviceDeregisterRequest_descriptor_, &serviceDeregisterRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + serviceGetByNameRequest_descriptor_, &serviceGetByNameRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + serviceGetByUUIDRequest_descriptor_, &serviceGetByUUIDRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + serviceGetByTypeRequest_descriptor_, &serviceGetByTypeRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + serviceRegisterRequest_descriptor_, &serviceRegisterRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + serviceRegisterResponse_descriptor_, &serviceRegisterResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + configurationGetRequest_descriptor_, &configurationGetRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + configurationSetResponse_descriptor_, &configurationSetResponse::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto() { + delete AddressMapping::default_instance_; + delete AddressMapping_reflection_; + delete AddressMappingSet::default_instance_; + delete AddressMappingSet_reflection_; + delete DirService::default_instance_; + delete DirService_reflection_; + delete ServiceDataMap::default_instance_; + delete ServiceDataMap_reflection_; + delete Service::default_instance_; + delete Service_reflection_; + delete ServiceSet::default_instance_; + delete ServiceSet_reflection_; + delete Configuration::default_instance_; + delete Configuration_reflection_; + delete addressMappingGetRequest::default_instance_; + delete addressMappingGetRequest_reflection_; + delete addressMappingGetResponse::default_instance_; + delete addressMappingGetResponse_reflection_; + delete addressMappingSetResponse::default_instance_; + delete addressMappingSetResponse_reflection_; + delete globalTimeSGetResponse::default_instance_; + delete globalTimeSGetResponse_reflection_; + delete serviceDeregisterRequest::default_instance_; + delete serviceDeregisterRequest_reflection_; + delete serviceGetByNameRequest::default_instance_; + delete serviceGetByNameRequest_reflection_; + delete serviceGetByUUIDRequest::default_instance_; + delete serviceGetByUUIDRequest_reflection_; + delete serviceGetByTypeRequest::default_instance_; + delete serviceGetByTypeRequest_reflection_; + delete serviceRegisterRequest::default_instance_; + delete serviceRegisterRequest_reflection_; + delete serviceRegisterResponse::default_instance_; + delete serviceRegisterResponse_reflection_; + delete configurationGetRequest::default_instance_; + delete configurationGetRequest_reflection_; + delete configurationSetResponse::default_instance_; + delete configurationSetResponse_reflection_; +} + +void protobuf_AddDesc_xtreemfs_2fDIR_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::xtreemfs::pbrpc::protobuf_AddDesc_include_2fPBRPC_2eproto(); + ::xtreemfs::pbrpc::protobuf_AddDesc_include_2fCommon_2eproto(); + ::xtreemfs::pbrpc::protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\022xtreemfs/DIR.proto\022\016xtreemfs.pbrpc\032\023in" + "clude/PBRPC.proto\032\024include/Common.proto\032" + "\032xtreemfs/GlobalTypes.proto\"\223\001\n\016AddressM" + "apping\022\014\n\004uuid\030\001 \002(\t\022\017\n\007version\030\002 \002(\006\022\020\n" + "\010protocol\030\003 \002(\t\022\017\n\007address\030\004 \002(\t\022\014\n\004port" + "\030\005 \002(\007\022\025\n\rmatch_network\030\006 \002(\t\022\r\n\005ttl_s\030\007" + " \002(\007\022\013\n\003uri\030\010 \002(\t\"E\n\021AddressMappingSet\0220" + "\n\010mappings\030\001 \003(\0132\036.xtreemfs.pbrpc.Addres" + "sMapping\"X\n\nDirService\022\017\n\007address\030\001 \002(\t\022" + "\014\n\004port\030\002 \002(\007\022\020\n\010protocol\030\003 \002(\t\022\031\n\021inter" + "face_version\030\004 \002(\007\"<\n\016ServiceDataMap\022*\n\004" + "data\030\001 \003(\0132\034.xtreemfs.pbrpc.KeyValuePair" + "\"\247\001\n\007Service\022)\n\004type\030\001 \002(\0162\033.xtreemfs.pb" + "rpc.ServiceType\022\014\n\004uuid\030\002 \002(\t\022\017\n\007version" + "\030\003 \002(\006\022\014\n\004name\030\004 \002(\t\022\026\n\016last_updated_s\030\005" + " \002(\006\022,\n\004data\030\006 \002(\0132\036.xtreemfs.pbrpc.Serv" + "iceDataMap\"7\n\nServiceSet\022)\n\010services\030\001 \003" + "(\0132\027.xtreemfs.pbrpc.Service\"_\n\rConfigura" + "tion\022\014\n\004uuid\030\001 \002(\t\022/\n\tparameter\030\002 \003(\0132\034." + "xtreemfs.pbrpc.KeyValuePair\022\017\n\007version\030\003" + " \002(\006\"(\n\030addressMappingGetRequest\022\014\n\004uuid" + "\030\001 \002(\t\"N\n\031addressMappingGetResponse\0221\n\006r" + "esult\030\001 \001(\0132!.xtreemfs.pbrpc.AddressMapp" + "ingSet\"0\n\031addressMappingSetResponse\022\023\n\013n" + "ew_version\030\001 \001(\006\"1\n\026globalTimeSGetRespon" + "se\022\027\n\017time_in_seconds\030\001 \002(\006\"(\n\030serviceDe" + "registerRequest\022\014\n\004uuid\030\001 \002(\t\"\'\n\027service" + "GetByNameRequest\022\014\n\004name\030\001 \002(\t\"\'\n\027servic" + "eGetByUUIDRequest\022\014\n\004name\030\001 \002(\t\"D\n\027servi" + "ceGetByTypeRequest\022)\n\004type\030\001 \002(\0162\033.xtree" + "mfs.pbrpc.ServiceType\"B\n\026serviceRegister" + "Request\022(\n\007service\030\001 \002(\0132\027.xtreemfs.pbrp" + "c.Service\".\n\027serviceRegisterResponse\022\023\n\013" + "new_version\030\001 \002(\006\"\'\n\027configurationGetReq" + "uest\022\014\n\004uuid\030\001 \002(\t\"/\n\030configurationSetRe" + "sponse\022\023\n\013new_version\030\001 \001(\006*\200\001\n\013ServiceT" + "ype\022\026\n\022SERVICE_TYPE_MIXED\020\000\022\024\n\020SERVICE_T" + "YPE_MRC\020\001\022\024\n\020SERVICE_TYPE_OSD\020\002\022\027\n\023SERVI" + "CE_TYPE_VOLUME\020\003\022\024\n\020SERVICE_TYPE_DIR\020\004*g" + "\n\rServiceStatus\022\030\n\024SERVICE_STATUS_AVAIL\020" + "\000\022 \n\034SERVICE_STATUS_TO_BE_REMOVED\020\001\022\032\n\026S" + "ERVICE_STATUS_REMOVED\020\0022\355\r\n\020DirectorySer" + "vice\022u\n\035xtreemfs_address_mappings_get\022(." + "xtreemfs.pbrpc.addressMappingGetRequest\032" + "!.xtreemfs.pbrpc.AddressMappingSet\"\007\215\265\030\001" + "\000\000\000\022t\n xtreemfs_address_mappings_remove\022" + "(.xtreemfs.pbrpc.addressMappingGetReques" + "t\032\035.xtreemfs.pbrpc.emptyResponse\"\007\215\265\030\002\000\000" + "\000\022v\n\035xtreemfs_address_mappings_set\022!.xtr" + "eemfs.pbrpc.AddressMappingSet\032).xtreemfs" + ".pbrpc.addressMappingSetResponse\"\007\215\265\030\003\000\000" + "\000\022Z\n\025xtreemfs_discover_dir\022\034.xtreemfs.pb" + "rpc.emptyRequest\032\032.xtreemfs.pbrpc.DirSer" + "vice\"\007\215\265\030\004\000\000\000\022k\n\032xtreemfs_global_time_s_" + "get\022\034.xtreemfs.pbrpc.emptyRequest\032&.xtre" + "emfs.pbrpc.globalTimeSGetResponse\"\007\215\265\030\005\000" + "\000\000\022o\n\033xtreemfs_service_deregister\022(.xtre" + "emfs.pbrpc.serviceDeregisterRequest\032\035.xt" + "reemfs.pbrpc.emptyResponse\"\007\215\265\030\006\000\000\000\022l\n\034x" + "treemfs_service_get_by_name\022\'.xtreemfs.p" + "brpc.serviceGetByNameRequest\032\032.xtreemfs." + "pbrpc.ServiceSet\"\007\215\265\030\007\000\000\000\022l\n\034xtreemfs_se" + "rvice_get_by_type\022\'.xtreemfs.pbrpc.servi" + "ceGetByTypeRequest\032\032.xtreemfs.pbrpc.Serv" + "iceSet\"\007\215\265\030\010\000\000\000\022l\n\034xtreemfs_service_get_" + "by_uuid\022\'.xtreemfs.pbrpc.serviceGetByUUI" + "DRequest\032\032.xtreemfs.pbrpc.ServiceSet\"\007\215\265" + "\030\t\000\000\000\022k\n\030xtreemfs_service_offline\022\'.xtre" + "emfs.pbrpc.serviceGetByUUIDRequest\032\035.xtr" + "eemfs.pbrpc.emptyResponse\"\007\215\265\030\n\000\000\000\022u\n\031xt" + "reemfs_service_register\022&.xtreemfs.pbrpc" + ".serviceRegisterRequest\032\'.xtreemfs.pbrpc" + ".serviceRegisterResponse\"\007\215\265\030\013\000\000\000\022[\n\023xtr" + "eemfs_checkpoint\022\034.xtreemfs.pbrpc.emptyR" + "equest\032\035.xtreemfs.pbrpc.emptyResponse\"\007\215" + "\265\030\024\000\000\000\022Y\n\021xtreemfs_shutdown\022\034.xtreemfs.p" + "brpc.emptyRequest\032\035.xtreemfs.pbrpc.empty" + "Response\"\007\215\265\030\025\000\000\000\022m\n\032xtreemfs_configurat" + "ion_get\022\'.xtreemfs.pbrpc.configurationGe" + "tRequest\032\035.xtreemfs.pbrpc.Configuration\"" + "\007\215\265\030\026\000\000\000\022n\n\032xtreemfs_configuration_set\022\035" + ".xtreemfs.pbrpc.Configuration\032(.xtreemfs" + ".pbrpc.configurationSetResponse\"\007\215\265\030\027\000\000\000" + "\022l\n\036xtreemfs_vivaldi_client_update\022\".xtr" + "eemfs.pbrpc.VivaldiCoordinates\032\035.xtreemf" + "s.pbrpc.emptyResponse\"\007\215\265\030\030\000\000\000\032\007\225\265\030\021\'\000\000B" + "(\n&org.xtreemfs.pbrpc.generatedinterface" + "s", 3481); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "xtreemfs/DIR.proto", &protobuf_RegisterTypes); + AddressMapping::default_instance_ = new AddressMapping(); + AddressMappingSet::default_instance_ = new AddressMappingSet(); + DirService::default_instance_ = new DirService(); + ServiceDataMap::default_instance_ = new ServiceDataMap(); + Service::default_instance_ = new Service(); + ServiceSet::default_instance_ = new ServiceSet(); + Configuration::default_instance_ = new Configuration(); + addressMappingGetRequest::default_instance_ = new addressMappingGetRequest(); + addressMappingGetResponse::default_instance_ = new addressMappingGetResponse(); + addressMappingSetResponse::default_instance_ = new addressMappingSetResponse(); + globalTimeSGetResponse::default_instance_ = new globalTimeSGetResponse(); + serviceDeregisterRequest::default_instance_ = new serviceDeregisterRequest(); + serviceGetByNameRequest::default_instance_ = new serviceGetByNameRequest(); + serviceGetByUUIDRequest::default_instance_ = new serviceGetByUUIDRequest(); + serviceGetByTypeRequest::default_instance_ = new serviceGetByTypeRequest(); + serviceRegisterRequest::default_instance_ = new serviceRegisterRequest(); + serviceRegisterResponse::default_instance_ = new serviceRegisterResponse(); + configurationGetRequest::default_instance_ = new configurationGetRequest(); + configurationSetResponse::default_instance_ = new configurationSetResponse(); + AddressMapping::default_instance_->InitAsDefaultInstance(); + AddressMappingSet::default_instance_->InitAsDefaultInstance(); + DirService::default_instance_->InitAsDefaultInstance(); + ServiceDataMap::default_instance_->InitAsDefaultInstance(); + Service::default_instance_->InitAsDefaultInstance(); + ServiceSet::default_instance_->InitAsDefaultInstance(); + Configuration::default_instance_->InitAsDefaultInstance(); + addressMappingGetRequest::default_instance_->InitAsDefaultInstance(); + addressMappingGetResponse::default_instance_->InitAsDefaultInstance(); + addressMappingSetResponse::default_instance_->InitAsDefaultInstance(); + globalTimeSGetResponse::default_instance_->InitAsDefaultInstance(); + serviceDeregisterRequest::default_instance_->InitAsDefaultInstance(); + serviceGetByNameRequest::default_instance_->InitAsDefaultInstance(); + serviceGetByUUIDRequest::default_instance_->InitAsDefaultInstance(); + serviceGetByTypeRequest::default_instance_->InitAsDefaultInstance(); + serviceRegisterRequest::default_instance_->InitAsDefaultInstance(); + serviceRegisterResponse::default_instance_->InitAsDefaultInstance(); + configurationGetRequest::default_instance_->InitAsDefaultInstance(); + configurationSetResponse::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_xtreemfs_2fDIR_2eproto { + StaticDescriptorInitializer_xtreemfs_2fDIR_2eproto() { + protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + } +} static_descriptor_initializer_xtreemfs_2fDIR_2eproto_; +const ::google::protobuf::EnumDescriptor* ServiceType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServiceType_descriptor_; +} +bool ServiceType_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + case 4: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ServiceStatus_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServiceStatus_descriptor_; +} +bool ServiceStatus_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + + +// =================================================================== + +#ifndef _MSC_VER +const int AddressMapping::kUuidFieldNumber; +const int AddressMapping::kVersionFieldNumber; +const int AddressMapping::kProtocolFieldNumber; +const int AddressMapping::kAddressFieldNumber; +const int AddressMapping::kPortFieldNumber; +const int AddressMapping::kMatchNetworkFieldNumber; +const int AddressMapping::kTtlSFieldNumber; +const int AddressMapping::kUriFieldNumber; +#endif // !_MSC_VER + +AddressMapping::AddressMapping() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void AddressMapping::InitAsDefaultInstance() { +} + +AddressMapping::AddressMapping(const AddressMapping& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void AddressMapping::SharedCtor() { + _cached_size_ = 0; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + version_ = GOOGLE_ULONGLONG(0); + protocol_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + address_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + port_ = 0u; + match_network_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ttl_s_ = 0u; + uri_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +AddressMapping::~AddressMapping() { + SharedDtor(); +} + +void AddressMapping::SharedDtor() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (protocol_ != &::google::protobuf::internal::kEmptyString) { + delete protocol_; + } + if (address_ != &::google::protobuf::internal::kEmptyString) { + delete address_; + } + if (match_network_ != &::google::protobuf::internal::kEmptyString) { + delete match_network_; + } + if (uri_ != &::google::protobuf::internal::kEmptyString) { + delete uri_; + } + if (this != default_instance_) { + } +} + +void AddressMapping::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* AddressMapping::descriptor() { + protobuf_AssignDescriptorsOnce(); + return AddressMapping_descriptor_; +} + +const AddressMapping& AddressMapping::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +AddressMapping* AddressMapping::default_instance_ = NULL; + +AddressMapping* AddressMapping::New() const { + return new AddressMapping; +} + +void AddressMapping::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_uuid()) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + } + version_ = GOOGLE_ULONGLONG(0); + if (has_protocol()) { + if (protocol_ != &::google::protobuf::internal::kEmptyString) { + protocol_->clear(); + } + } + if (has_address()) { + if (address_ != &::google::protobuf::internal::kEmptyString) { + address_->clear(); + } + } + port_ = 0u; + if (has_match_network()) { + if (match_network_ != &::google::protobuf::internal::kEmptyString) { + match_network_->clear(); + } + } + ttl_s_ = 0u; + if (has_uri()) { + if (uri_ != &::google::protobuf::internal::kEmptyString) { + uri_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool AddressMapping::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string uuid = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_uuid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(17)) goto parse_version; + break; + } + + // required fixed64 version = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &version_))); + set_has_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_protocol; + break; + } + + // required string protocol = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_protocol: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_protocol())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->protocol().data(), this->protocol().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_address; + break; + } + + // required string address = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_address: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_address())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->address().data(), this->address().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(45)) goto parse_port; + break; + } + + // required fixed32 port = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_port: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &port_))); + set_has_port(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(50)) goto parse_match_network; + break; + } + + // required string match_network = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_match_network: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_match_network())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->match_network().data(), this->match_network().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(61)) goto parse_ttl_s; + break; + } + + // required fixed32 ttl_s = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_ttl_s: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &ttl_s_))); + set_has_ttl_s(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(66)) goto parse_uri; + break; + } + + // required string uri = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uri: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_uri())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uri().data(), this->uri().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void AddressMapping::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string uuid = 1; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->uuid(), output); + } + + // required fixed64 version = 2; + if (has_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(2, this->version(), output); + } + + // required string protocol = 3; + if (has_protocol()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->protocol().data(), this->protocol().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->protocol(), output); + } + + // required string address = 4; + if (has_address()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->address().data(), this->address().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->address(), output); + } + + // required fixed32 port = 5; + if (has_port()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(5, this->port(), output); + } + + // required string match_network = 6; + if (has_match_network()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->match_network().data(), this->match_network().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 6, this->match_network(), output); + } + + // required fixed32 ttl_s = 7; + if (has_ttl_s()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(7, this->ttl_s(), output); + } + + // required string uri = 8; + if (has_uri()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uri().data(), this->uri().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 8, this->uri(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* AddressMapping::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string uuid = 1; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->uuid(), target); + } + + // required fixed64 version = 2; + if (has_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(2, this->version(), target); + } + + // required string protocol = 3; + if (has_protocol()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->protocol().data(), this->protocol().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->protocol(), target); + } + + // required string address = 4; + if (has_address()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->address().data(), this->address().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->address(), target); + } + + // required fixed32 port = 5; + if (has_port()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(5, this->port(), target); + } + + // required string match_network = 6; + if (has_match_network()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->match_network().data(), this->match_network().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 6, this->match_network(), target); + } + + // required fixed32 ttl_s = 7; + if (has_ttl_s()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(7, this->ttl_s(), target); + } + + // required string uri = 8; + if (has_uri()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uri().data(), this->uri().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 8, this->uri(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int AddressMapping::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string uuid = 1; + if (has_uuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->uuid()); + } + + // required fixed64 version = 2; + if (has_version()) { + total_size += 1 + 8; + } + + // required string protocol = 3; + if (has_protocol()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->protocol()); + } + + // required string address = 4; + if (has_address()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->address()); + } + + // required fixed32 port = 5; + if (has_port()) { + total_size += 1 + 4; + } + + // required string match_network = 6; + if (has_match_network()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->match_network()); + } + + // required fixed32 ttl_s = 7; + if (has_ttl_s()) { + total_size += 1 + 4; + } + + // required string uri = 8; + if (has_uri()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->uri()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void AddressMapping::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const AddressMapping* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void AddressMapping::MergeFrom(const AddressMapping& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_uuid()) { + set_uuid(from.uuid()); + } + if (from.has_version()) { + set_version(from.version()); + } + if (from.has_protocol()) { + set_protocol(from.protocol()); + } + if (from.has_address()) { + set_address(from.address()); + } + if (from.has_port()) { + set_port(from.port()); + } + if (from.has_match_network()) { + set_match_network(from.match_network()); + } + if (from.has_ttl_s()) { + set_ttl_s(from.ttl_s()); + } + if (from.has_uri()) { + set_uri(from.uri()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void AddressMapping::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void AddressMapping::CopyFrom(const AddressMapping& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool AddressMapping::IsInitialized() const { + if ((_has_bits_[0] & 0x000000ff) != 0x000000ff) return false; + + return true; +} + +void AddressMapping::Swap(AddressMapping* other) { + if (other != this) { + std::swap(uuid_, other->uuid_); + std::swap(version_, other->version_); + std::swap(protocol_, other->protocol_); + std::swap(address_, other->address_); + std::swap(port_, other->port_); + std::swap(match_network_, other->match_network_); + std::swap(ttl_s_, other->ttl_s_); + std::swap(uri_, other->uri_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata AddressMapping::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = AddressMapping_descriptor_; + metadata.reflection = AddressMapping_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int AddressMappingSet::kMappingsFieldNumber; +#endif // !_MSC_VER + +AddressMappingSet::AddressMappingSet() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void AddressMappingSet::InitAsDefaultInstance() { +} + +AddressMappingSet::AddressMappingSet(const AddressMappingSet& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void AddressMappingSet::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +AddressMappingSet::~AddressMappingSet() { + SharedDtor(); +} + +void AddressMappingSet::SharedDtor() { + if (this != default_instance_) { + } +} + +void AddressMappingSet::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* AddressMappingSet::descriptor() { + protobuf_AssignDescriptorsOnce(); + return AddressMappingSet_descriptor_; +} + +const AddressMappingSet& AddressMappingSet::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +AddressMappingSet* AddressMappingSet::default_instance_ = NULL; + +AddressMappingSet* AddressMappingSet::New() const { + return new AddressMappingSet; +} + +void AddressMappingSet::Clear() { + mappings_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool AddressMappingSet::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_mappings: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_mappings())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_mappings; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void AddressMappingSet::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + for (int i = 0; i < this->mappings_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->mappings(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* AddressMappingSet::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + for (int i = 0; i < this->mappings_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->mappings(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int AddressMappingSet::ByteSize() const { + int total_size = 0; + + // repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + total_size += 1 * this->mappings_size(); + for (int i = 0; i < this->mappings_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->mappings(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void AddressMappingSet::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const AddressMappingSet* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void AddressMappingSet::MergeFrom(const AddressMappingSet& from) { + GOOGLE_CHECK_NE(&from, this); + mappings_.MergeFrom(from.mappings_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void AddressMappingSet::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void AddressMappingSet::CopyFrom(const AddressMappingSet& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool AddressMappingSet::IsInitialized() const { + + for (int i = 0; i < mappings_size(); i++) { + if (!this->mappings(i).IsInitialized()) return false; + } + return true; +} + +void AddressMappingSet::Swap(AddressMappingSet* other) { + if (other != this) { + mappings_.Swap(&other->mappings_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata AddressMappingSet::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = AddressMappingSet_descriptor_; + metadata.reflection = AddressMappingSet_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int DirService::kAddressFieldNumber; +const int DirService::kPortFieldNumber; +const int DirService::kProtocolFieldNumber; +const int DirService::kInterfaceVersionFieldNumber; +#endif // !_MSC_VER + +DirService::DirService() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void DirService::InitAsDefaultInstance() { +} + +DirService::DirService(const DirService& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void DirService::SharedCtor() { + _cached_size_ = 0; + address_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + port_ = 0u; + protocol_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + interface_version_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +DirService::~DirService() { + SharedDtor(); +} + +void DirService::SharedDtor() { + if (address_ != &::google::protobuf::internal::kEmptyString) { + delete address_; + } + if (protocol_ != &::google::protobuf::internal::kEmptyString) { + delete protocol_; + } + if (this != default_instance_) { + } +} + +void DirService::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* DirService::descriptor() { + protobuf_AssignDescriptorsOnce(); + return DirService_descriptor_; +} + +const DirService& DirService::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +DirService* DirService::default_instance_ = NULL; + +DirService* DirService::New() const { + return new DirService; +} + +void DirService::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_address()) { + if (address_ != &::google::protobuf::internal::kEmptyString) { + address_->clear(); + } + } + port_ = 0u; + if (has_protocol()) { + if (protocol_ != &::google::protobuf::internal::kEmptyString) { + protocol_->clear(); + } + } + interface_version_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool DirService::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string address = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_address())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->address().data(), this->address().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(21)) goto parse_port; + break; + } + + // required fixed32 port = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_port: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &port_))); + set_has_port(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_protocol; + break; + } + + // required string protocol = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_protocol: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_protocol())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->protocol().data(), this->protocol().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(37)) goto parse_interface_version; + break; + } + + // required fixed32 interface_version = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_interface_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &interface_version_))); + set_has_interface_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void DirService::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string address = 1; + if (has_address()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->address().data(), this->address().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->address(), output); + } + + // required fixed32 port = 2; + if (has_port()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(2, this->port(), output); + } + + // required string protocol = 3; + if (has_protocol()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->protocol().data(), this->protocol().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->protocol(), output); + } + + // required fixed32 interface_version = 4; + if (has_interface_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(4, this->interface_version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* DirService::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string address = 1; + if (has_address()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->address().data(), this->address().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->address(), target); + } + + // required fixed32 port = 2; + if (has_port()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(2, this->port(), target); + } + + // required string protocol = 3; + if (has_protocol()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->protocol().data(), this->protocol().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->protocol(), target); + } + + // required fixed32 interface_version = 4; + if (has_interface_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(4, this->interface_version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int DirService::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string address = 1; + if (has_address()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->address()); + } + + // required fixed32 port = 2; + if (has_port()) { + total_size += 1 + 4; + } + + // required string protocol = 3; + if (has_protocol()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->protocol()); + } + + // required fixed32 interface_version = 4; + if (has_interface_version()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void DirService::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const DirService* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void DirService::MergeFrom(const DirService& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_address()) { + set_address(from.address()); + } + if (from.has_port()) { + set_port(from.port()); + } + if (from.has_protocol()) { + set_protocol(from.protocol()); + } + if (from.has_interface_version()) { + set_interface_version(from.interface_version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void DirService::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void DirService::CopyFrom(const DirService& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DirService::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void DirService::Swap(DirService* other) { + if (other != this) { + std::swap(address_, other->address_); + std::swap(port_, other->port_); + std::swap(protocol_, other->protocol_); + std::swap(interface_version_, other->interface_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata DirService::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = DirService_descriptor_; + metadata.reflection = DirService_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ServiceDataMap::kDataFieldNumber; +#endif // !_MSC_VER + +ServiceDataMap::ServiceDataMap() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ServiceDataMap::InitAsDefaultInstance() { +} + +ServiceDataMap::ServiceDataMap(const ServiceDataMap& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ServiceDataMap::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ServiceDataMap::~ServiceDataMap() { + SharedDtor(); +} + +void ServiceDataMap::SharedDtor() { + if (this != default_instance_) { + } +} + +void ServiceDataMap::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ServiceDataMap::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServiceDataMap_descriptor_; +} + +const ServiceDataMap& ServiceDataMap::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +ServiceDataMap* ServiceDataMap::default_instance_ = NULL; + +ServiceDataMap* ServiceDataMap::New() const { + return new ServiceDataMap; +} + +void ServiceDataMap::Clear() { + data_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ServiceDataMap::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_data: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_data())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_data; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ServiceDataMap::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + for (int i = 0; i < this->data_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->data(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ServiceDataMap::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + for (int i = 0; i < this->data_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->data(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ServiceDataMap::ByteSize() const { + int total_size = 0; + + // repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + total_size += 1 * this->data_size(); + for (int i = 0; i < this->data_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->data(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ServiceDataMap::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ServiceDataMap* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ServiceDataMap::MergeFrom(const ServiceDataMap& from) { + GOOGLE_CHECK_NE(&from, this); + data_.MergeFrom(from.data_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ServiceDataMap::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ServiceDataMap::CopyFrom(const ServiceDataMap& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServiceDataMap::IsInitialized() const { + + for (int i = 0; i < data_size(); i++) { + if (!this->data(i).IsInitialized()) return false; + } + return true; +} + +void ServiceDataMap::Swap(ServiceDataMap* other) { + if (other != this) { + data_.Swap(&other->data_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ServiceDataMap::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServiceDataMap_descriptor_; + metadata.reflection = ServiceDataMap_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Service::kTypeFieldNumber; +const int Service::kUuidFieldNumber; +const int Service::kVersionFieldNumber; +const int Service::kNameFieldNumber; +const int Service::kLastUpdatedSFieldNumber; +const int Service::kDataFieldNumber; +#endif // !_MSC_VER + +Service::Service() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Service::InitAsDefaultInstance() { + data_ = const_cast< ::xtreemfs::pbrpc::ServiceDataMap*>(&::xtreemfs::pbrpc::ServiceDataMap::default_instance()); +} + +Service::Service(const Service& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Service::SharedCtor() { + _cached_size_ = 0; + type_ = 0; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + version_ = GOOGLE_ULONGLONG(0); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + last_updated_s_ = GOOGLE_ULONGLONG(0); + data_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Service::~Service() { + SharedDtor(); +} + +void Service::SharedDtor() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + delete data_; + } +} + +void Service::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Service::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Service_descriptor_; +} + +const Service& Service::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +Service* Service::default_instance_ = NULL; + +Service* Service::New() const { + return new Service; +} + +void Service::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + type_ = 0; + if (has_uuid()) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + } + version_ = GOOGLE_ULONGLONG(0); + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + last_updated_s_ = GOOGLE_ULONGLONG(0); + if (has_data()) { + if (data_ != NULL) data_->::xtreemfs::pbrpc::ServiceDataMap::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Service::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.ServiceType type = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::ServiceType_IsValid(value)) { + set_type(static_cast< ::xtreemfs::pbrpc::ServiceType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_uuid; + break; + } + + // required string uuid = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uuid: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_uuid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_version; + break; + } + + // required fixed64 version = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &version_))); + set_has_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_name; + break; + } + + // required string name = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(41)) goto parse_last_updated_s; + break; + } + + // required fixed64 last_updated_s = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_last_updated_s: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &last_updated_s_))); + set_has_last_updated_s(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(50)) goto parse_data; + break; + } + + // required .xtreemfs.pbrpc.ServiceDataMap data = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_data: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_data())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Service::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.ServiceType type = 1; + if (has_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->type(), output); + } + + // required string uuid = 2; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->uuid(), output); + } + + // required fixed64 version = 3; + if (has_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->version(), output); + } + + // required string name = 4; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->name(), output); + } + + // required fixed64 last_updated_s = 5; + if (has_last_updated_s()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(5, this->last_updated_s(), output); + } + + // required .xtreemfs.pbrpc.ServiceDataMap data = 6; + if (has_data()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 6, this->data(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Service::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.ServiceType type = 1; + if (has_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->type(), target); + } + + // required string uuid = 2; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->uuid(), target); + } + + // required fixed64 version = 3; + if (has_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->version(), target); + } + + // required string name = 4; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->name(), target); + } + + // required fixed64 last_updated_s = 5; + if (has_last_updated_s()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(5, this->last_updated_s(), target); + } + + // required .xtreemfs.pbrpc.ServiceDataMap data = 6; + if (has_data()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, this->data(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Service::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.ServiceType type = 1; + if (has_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); + } + + // required string uuid = 2; + if (has_uuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->uuid()); + } + + // required fixed64 version = 3; + if (has_version()) { + total_size += 1 + 8; + } + + // required string name = 4; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // required fixed64 last_updated_s = 5; + if (has_last_updated_s()) { + total_size += 1 + 8; + } + + // required .xtreemfs.pbrpc.ServiceDataMap data = 6; + if (has_data()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->data()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Service::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Service* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Service::MergeFrom(const Service& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_type()) { + set_type(from.type()); + } + if (from.has_uuid()) { + set_uuid(from.uuid()); + } + if (from.has_version()) { + set_version(from.version()); + } + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_last_updated_s()) { + set_last_updated_s(from.last_updated_s()); + } + if (from.has_data()) { + mutable_data()->::xtreemfs::pbrpc::ServiceDataMap::MergeFrom(from.data()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Service::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Service::CopyFrom(const Service& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Service::IsInitialized() const { + if ((_has_bits_[0] & 0x0000003f) != 0x0000003f) return false; + + if (has_data()) { + if (!this->data().IsInitialized()) return false; + } + return true; +} + +void Service::Swap(Service* other) { + if (other != this) { + std::swap(type_, other->type_); + std::swap(uuid_, other->uuid_); + std::swap(version_, other->version_); + std::swap(name_, other->name_); + std::swap(last_updated_s_, other->last_updated_s_); + std::swap(data_, other->data_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Service::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Service_descriptor_; + metadata.reflection = Service_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ServiceSet::kServicesFieldNumber; +#endif // !_MSC_VER + +ServiceSet::ServiceSet() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ServiceSet::InitAsDefaultInstance() { +} + +ServiceSet::ServiceSet(const ServiceSet& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ServiceSet::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ServiceSet::~ServiceSet() { + SharedDtor(); +} + +void ServiceSet::SharedDtor() { + if (this != default_instance_) { + } +} + +void ServiceSet::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ServiceSet::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServiceSet_descriptor_; +} + +const ServiceSet& ServiceSet::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +ServiceSet* ServiceSet::default_instance_ = NULL; + +ServiceSet* ServiceSet::New() const { + return new ServiceSet; +} + +void ServiceSet::Clear() { + services_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ServiceSet::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .xtreemfs.pbrpc.Service services = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_services: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_services())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_services; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ServiceSet::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .xtreemfs.pbrpc.Service services = 1; + for (int i = 0; i < this->services_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->services(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ServiceSet::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .xtreemfs.pbrpc.Service services = 1; + for (int i = 0; i < this->services_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->services(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ServiceSet::ByteSize() const { + int total_size = 0; + + // repeated .xtreemfs.pbrpc.Service services = 1; + total_size += 1 * this->services_size(); + for (int i = 0; i < this->services_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->services(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ServiceSet::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ServiceSet* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ServiceSet::MergeFrom(const ServiceSet& from) { + GOOGLE_CHECK_NE(&from, this); + services_.MergeFrom(from.services_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ServiceSet::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ServiceSet::CopyFrom(const ServiceSet& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServiceSet::IsInitialized() const { + + for (int i = 0; i < services_size(); i++) { + if (!this->services(i).IsInitialized()) return false; + } + return true; +} + +void ServiceSet::Swap(ServiceSet* other) { + if (other != this) { + services_.Swap(&other->services_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ServiceSet::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServiceSet_descriptor_; + metadata.reflection = ServiceSet_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Configuration::kUuidFieldNumber; +const int Configuration::kParameterFieldNumber; +const int Configuration::kVersionFieldNumber; +#endif // !_MSC_VER + +Configuration::Configuration() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Configuration::InitAsDefaultInstance() { +} + +Configuration::Configuration(const Configuration& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Configuration::SharedCtor() { + _cached_size_ = 0; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Configuration::~Configuration() { + SharedDtor(); +} + +void Configuration::SharedDtor() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (this != default_instance_) { + } +} + +void Configuration::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Configuration::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Configuration_descriptor_; +} + +const Configuration& Configuration::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +Configuration* Configuration::default_instance_ = NULL; + +Configuration* Configuration::New() const { + return new Configuration; +} + +void Configuration::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_uuid()) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + } + version_ = GOOGLE_ULONGLONG(0); + } + parameter_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Configuration::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string uuid = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_uuid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_parameter; + break; + } + + // repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_parameter: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_parameter())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_parameter; + if (input->ExpectTag(25)) goto parse_version; + break; + } + + // required fixed64 version = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &version_))); + set_has_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Configuration::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string uuid = 1; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->uuid(), output); + } + + // repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + for (int i = 0; i < this->parameter_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->parameter(i), output); + } + + // required fixed64 version = 3; + if (has_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Configuration::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string uuid = 1; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->uuid(), target); + } + + // repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + for (int i = 0; i < this->parameter_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->parameter(i), target); + } + + // required fixed64 version = 3; + if (has_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Configuration::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string uuid = 1; + if (has_uuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->uuid()); + } + + // required fixed64 version = 3; + if (has_version()) { + total_size += 1 + 8; + } + + } + // repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + total_size += 1 * this->parameter_size(); + for (int i = 0; i < this->parameter_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->parameter(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Configuration::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Configuration* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Configuration::MergeFrom(const Configuration& from) { + GOOGLE_CHECK_NE(&from, this); + parameter_.MergeFrom(from.parameter_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_uuid()) { + set_uuid(from.uuid()); + } + if (from.has_version()) { + set_version(from.version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Configuration::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Configuration::CopyFrom(const Configuration& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Configuration::IsInitialized() const { + if ((_has_bits_[0] & 0x00000005) != 0x00000005) return false; + + for (int i = 0; i < parameter_size(); i++) { + if (!this->parameter(i).IsInitialized()) return false; + } + return true; +} + +void Configuration::Swap(Configuration* other) { + if (other != this) { + std::swap(uuid_, other->uuid_); + parameter_.Swap(&other->parameter_); + std::swap(version_, other->version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Configuration::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Configuration_descriptor_; + metadata.reflection = Configuration_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int addressMappingGetRequest::kUuidFieldNumber; +#endif // !_MSC_VER + +addressMappingGetRequest::addressMappingGetRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void addressMappingGetRequest::InitAsDefaultInstance() { +} + +addressMappingGetRequest::addressMappingGetRequest(const addressMappingGetRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void addressMappingGetRequest::SharedCtor() { + _cached_size_ = 0; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +addressMappingGetRequest::~addressMappingGetRequest() { + SharedDtor(); +} + +void addressMappingGetRequest::SharedDtor() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (this != default_instance_) { + } +} + +void addressMappingGetRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* addressMappingGetRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return addressMappingGetRequest_descriptor_; +} + +const addressMappingGetRequest& addressMappingGetRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +addressMappingGetRequest* addressMappingGetRequest::default_instance_ = NULL; + +addressMappingGetRequest* addressMappingGetRequest::New() const { + return new addressMappingGetRequest; +} + +void addressMappingGetRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_uuid()) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool addressMappingGetRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string uuid = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_uuid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void addressMappingGetRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string uuid = 1; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->uuid(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* addressMappingGetRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string uuid = 1; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->uuid(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int addressMappingGetRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string uuid = 1; + if (has_uuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->uuid()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void addressMappingGetRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const addressMappingGetRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void addressMappingGetRequest::MergeFrom(const addressMappingGetRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_uuid()) { + set_uuid(from.uuid()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void addressMappingGetRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void addressMappingGetRequest::CopyFrom(const addressMappingGetRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool addressMappingGetRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void addressMappingGetRequest::Swap(addressMappingGetRequest* other) { + if (other != this) { + std::swap(uuid_, other->uuid_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata addressMappingGetRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = addressMappingGetRequest_descriptor_; + metadata.reflection = addressMappingGetRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int addressMappingGetResponse::kResultFieldNumber; +#endif // !_MSC_VER + +addressMappingGetResponse::addressMappingGetResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void addressMappingGetResponse::InitAsDefaultInstance() { + result_ = const_cast< ::xtreemfs::pbrpc::AddressMappingSet*>(&::xtreemfs::pbrpc::AddressMappingSet::default_instance()); +} + +addressMappingGetResponse::addressMappingGetResponse(const addressMappingGetResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void addressMappingGetResponse::SharedCtor() { + _cached_size_ = 0; + result_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +addressMappingGetResponse::~addressMappingGetResponse() { + SharedDtor(); +} + +void addressMappingGetResponse::SharedDtor() { + if (this != default_instance_) { + delete result_; + } +} + +void addressMappingGetResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* addressMappingGetResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return addressMappingGetResponse_descriptor_; +} + +const addressMappingGetResponse& addressMappingGetResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +addressMappingGetResponse* addressMappingGetResponse::default_instance_ = NULL; + +addressMappingGetResponse* addressMappingGetResponse::New() const { + return new addressMappingGetResponse; +} + +void addressMappingGetResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_result()) { + if (result_ != NULL) result_->::xtreemfs::pbrpc::AddressMappingSet::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool addressMappingGetResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_result())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void addressMappingGetResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + if (has_result()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->result(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* addressMappingGetResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + if (has_result()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->result(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int addressMappingGetResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + if (has_result()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->result()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void addressMappingGetResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const addressMappingGetResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void addressMappingGetResponse::MergeFrom(const addressMappingGetResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_result()) { + mutable_result()->::xtreemfs::pbrpc::AddressMappingSet::MergeFrom(from.result()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void addressMappingGetResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void addressMappingGetResponse::CopyFrom(const addressMappingGetResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool addressMappingGetResponse::IsInitialized() const { + + if (has_result()) { + if (!this->result().IsInitialized()) return false; + } + return true; +} + +void addressMappingGetResponse::Swap(addressMappingGetResponse* other) { + if (other != this) { + std::swap(result_, other->result_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata addressMappingGetResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = addressMappingGetResponse_descriptor_; + metadata.reflection = addressMappingGetResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int addressMappingSetResponse::kNewVersionFieldNumber; +#endif // !_MSC_VER + +addressMappingSetResponse::addressMappingSetResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void addressMappingSetResponse::InitAsDefaultInstance() { +} + +addressMappingSetResponse::addressMappingSetResponse(const addressMappingSetResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void addressMappingSetResponse::SharedCtor() { + _cached_size_ = 0; + new_version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +addressMappingSetResponse::~addressMappingSetResponse() { + SharedDtor(); +} + +void addressMappingSetResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void addressMappingSetResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* addressMappingSetResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return addressMappingSetResponse_descriptor_; +} + +const addressMappingSetResponse& addressMappingSetResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +addressMappingSetResponse* addressMappingSetResponse::default_instance_ = NULL; + +addressMappingSetResponse* addressMappingSetResponse::New() const { + return new addressMappingSetResponse; +} + +void addressMappingSetResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + new_version_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool addressMappingSetResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional fixed64 new_version = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &new_version_))); + set_has_new_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void addressMappingSetResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional fixed64 new_version = 1; + if (has_new_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->new_version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* addressMappingSetResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional fixed64 new_version = 1; + if (has_new_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->new_version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int addressMappingSetResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional fixed64 new_version = 1; + if (has_new_version()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void addressMappingSetResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const addressMappingSetResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void addressMappingSetResponse::MergeFrom(const addressMappingSetResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_new_version()) { + set_new_version(from.new_version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void addressMappingSetResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void addressMappingSetResponse::CopyFrom(const addressMappingSetResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool addressMappingSetResponse::IsInitialized() const { + + return true; +} + +void addressMappingSetResponse::Swap(addressMappingSetResponse* other) { + if (other != this) { + std::swap(new_version_, other->new_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata addressMappingSetResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = addressMappingSetResponse_descriptor_; + metadata.reflection = addressMappingSetResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int globalTimeSGetResponse::kTimeInSecondsFieldNumber; +#endif // !_MSC_VER + +globalTimeSGetResponse::globalTimeSGetResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void globalTimeSGetResponse::InitAsDefaultInstance() { +} + +globalTimeSGetResponse::globalTimeSGetResponse(const globalTimeSGetResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void globalTimeSGetResponse::SharedCtor() { + _cached_size_ = 0; + time_in_seconds_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +globalTimeSGetResponse::~globalTimeSGetResponse() { + SharedDtor(); +} + +void globalTimeSGetResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void globalTimeSGetResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* globalTimeSGetResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return globalTimeSGetResponse_descriptor_; +} + +const globalTimeSGetResponse& globalTimeSGetResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +globalTimeSGetResponse* globalTimeSGetResponse::default_instance_ = NULL; + +globalTimeSGetResponse* globalTimeSGetResponse::New() const { + return new globalTimeSGetResponse; +} + +void globalTimeSGetResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + time_in_seconds_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool globalTimeSGetResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 time_in_seconds = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &time_in_seconds_))); + set_has_time_in_seconds(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void globalTimeSGetResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 time_in_seconds = 1; + if (has_time_in_seconds()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->time_in_seconds(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* globalTimeSGetResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 time_in_seconds = 1; + if (has_time_in_seconds()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->time_in_seconds(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int globalTimeSGetResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 time_in_seconds = 1; + if (has_time_in_seconds()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void globalTimeSGetResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const globalTimeSGetResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void globalTimeSGetResponse::MergeFrom(const globalTimeSGetResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_time_in_seconds()) { + set_time_in_seconds(from.time_in_seconds()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void globalTimeSGetResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void globalTimeSGetResponse::CopyFrom(const globalTimeSGetResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool globalTimeSGetResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void globalTimeSGetResponse::Swap(globalTimeSGetResponse* other) { + if (other != this) { + std::swap(time_in_seconds_, other->time_in_seconds_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata globalTimeSGetResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = globalTimeSGetResponse_descriptor_; + metadata.reflection = globalTimeSGetResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int serviceDeregisterRequest::kUuidFieldNumber; +#endif // !_MSC_VER + +serviceDeregisterRequest::serviceDeregisterRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void serviceDeregisterRequest::InitAsDefaultInstance() { +} + +serviceDeregisterRequest::serviceDeregisterRequest(const serviceDeregisterRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void serviceDeregisterRequest::SharedCtor() { + _cached_size_ = 0; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +serviceDeregisterRequest::~serviceDeregisterRequest() { + SharedDtor(); +} + +void serviceDeregisterRequest::SharedDtor() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (this != default_instance_) { + } +} + +void serviceDeregisterRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* serviceDeregisterRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return serviceDeregisterRequest_descriptor_; +} + +const serviceDeregisterRequest& serviceDeregisterRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +serviceDeregisterRequest* serviceDeregisterRequest::default_instance_ = NULL; + +serviceDeregisterRequest* serviceDeregisterRequest::New() const { + return new serviceDeregisterRequest; +} + +void serviceDeregisterRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_uuid()) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool serviceDeregisterRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string uuid = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_uuid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void serviceDeregisterRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string uuid = 1; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->uuid(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* serviceDeregisterRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string uuid = 1; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->uuid(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int serviceDeregisterRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string uuid = 1; + if (has_uuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->uuid()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void serviceDeregisterRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const serviceDeregisterRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void serviceDeregisterRequest::MergeFrom(const serviceDeregisterRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_uuid()) { + set_uuid(from.uuid()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void serviceDeregisterRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void serviceDeregisterRequest::CopyFrom(const serviceDeregisterRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool serviceDeregisterRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void serviceDeregisterRequest::Swap(serviceDeregisterRequest* other) { + if (other != this) { + std::swap(uuid_, other->uuid_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata serviceDeregisterRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = serviceDeregisterRequest_descriptor_; + metadata.reflection = serviceDeregisterRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int serviceGetByNameRequest::kNameFieldNumber; +#endif // !_MSC_VER + +serviceGetByNameRequest::serviceGetByNameRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void serviceGetByNameRequest::InitAsDefaultInstance() { +} + +serviceGetByNameRequest::serviceGetByNameRequest(const serviceGetByNameRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void serviceGetByNameRequest::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +serviceGetByNameRequest::~serviceGetByNameRequest() { + SharedDtor(); +} + +void serviceGetByNameRequest::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + } +} + +void serviceGetByNameRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* serviceGetByNameRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return serviceGetByNameRequest_descriptor_; +} + +const serviceGetByNameRequest& serviceGetByNameRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +serviceGetByNameRequest* serviceGetByNameRequest::default_instance_ = NULL; + +serviceGetByNameRequest* serviceGetByNameRequest::New() const { + return new serviceGetByNameRequest; +} + +void serviceGetByNameRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool serviceGetByNameRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void serviceGetByNameRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* serviceGetByNameRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int serviceGetByNameRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void serviceGetByNameRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const serviceGetByNameRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void serviceGetByNameRequest::MergeFrom(const serviceGetByNameRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void serviceGetByNameRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void serviceGetByNameRequest::CopyFrom(const serviceGetByNameRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool serviceGetByNameRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void serviceGetByNameRequest::Swap(serviceGetByNameRequest* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata serviceGetByNameRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = serviceGetByNameRequest_descriptor_; + metadata.reflection = serviceGetByNameRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int serviceGetByUUIDRequest::kNameFieldNumber; +#endif // !_MSC_VER + +serviceGetByUUIDRequest::serviceGetByUUIDRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void serviceGetByUUIDRequest::InitAsDefaultInstance() { +} + +serviceGetByUUIDRequest::serviceGetByUUIDRequest(const serviceGetByUUIDRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void serviceGetByUUIDRequest::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +serviceGetByUUIDRequest::~serviceGetByUUIDRequest() { + SharedDtor(); +} + +void serviceGetByUUIDRequest::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + } +} + +void serviceGetByUUIDRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* serviceGetByUUIDRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return serviceGetByUUIDRequest_descriptor_; +} + +const serviceGetByUUIDRequest& serviceGetByUUIDRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +serviceGetByUUIDRequest* serviceGetByUUIDRequest::default_instance_ = NULL; + +serviceGetByUUIDRequest* serviceGetByUUIDRequest::New() const { + return new serviceGetByUUIDRequest; +} + +void serviceGetByUUIDRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool serviceGetByUUIDRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void serviceGetByUUIDRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* serviceGetByUUIDRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int serviceGetByUUIDRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void serviceGetByUUIDRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const serviceGetByUUIDRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void serviceGetByUUIDRequest::MergeFrom(const serviceGetByUUIDRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void serviceGetByUUIDRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void serviceGetByUUIDRequest::CopyFrom(const serviceGetByUUIDRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool serviceGetByUUIDRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void serviceGetByUUIDRequest::Swap(serviceGetByUUIDRequest* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata serviceGetByUUIDRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = serviceGetByUUIDRequest_descriptor_; + metadata.reflection = serviceGetByUUIDRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int serviceGetByTypeRequest::kTypeFieldNumber; +#endif // !_MSC_VER + +serviceGetByTypeRequest::serviceGetByTypeRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void serviceGetByTypeRequest::InitAsDefaultInstance() { +} + +serviceGetByTypeRequest::serviceGetByTypeRequest(const serviceGetByTypeRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void serviceGetByTypeRequest::SharedCtor() { + _cached_size_ = 0; + type_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +serviceGetByTypeRequest::~serviceGetByTypeRequest() { + SharedDtor(); +} + +void serviceGetByTypeRequest::SharedDtor() { + if (this != default_instance_) { + } +} + +void serviceGetByTypeRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* serviceGetByTypeRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return serviceGetByTypeRequest_descriptor_; +} + +const serviceGetByTypeRequest& serviceGetByTypeRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +serviceGetByTypeRequest* serviceGetByTypeRequest::default_instance_ = NULL; + +serviceGetByTypeRequest* serviceGetByTypeRequest::New() const { + return new serviceGetByTypeRequest; +} + +void serviceGetByTypeRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + type_ = 0; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool serviceGetByTypeRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.ServiceType type = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::ServiceType_IsValid(value)) { + set_type(static_cast< ::xtreemfs::pbrpc::ServiceType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void serviceGetByTypeRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.ServiceType type = 1; + if (has_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->type(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* serviceGetByTypeRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.ServiceType type = 1; + if (has_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->type(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int serviceGetByTypeRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.ServiceType type = 1; + if (has_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void serviceGetByTypeRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const serviceGetByTypeRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void serviceGetByTypeRequest::MergeFrom(const serviceGetByTypeRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_type()) { + set_type(from.type()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void serviceGetByTypeRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void serviceGetByTypeRequest::CopyFrom(const serviceGetByTypeRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool serviceGetByTypeRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void serviceGetByTypeRequest::Swap(serviceGetByTypeRequest* other) { + if (other != this) { + std::swap(type_, other->type_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata serviceGetByTypeRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = serviceGetByTypeRequest_descriptor_; + metadata.reflection = serviceGetByTypeRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int serviceRegisterRequest::kServiceFieldNumber; +#endif // !_MSC_VER + +serviceRegisterRequest::serviceRegisterRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void serviceRegisterRequest::InitAsDefaultInstance() { + service_ = const_cast< ::xtreemfs::pbrpc::Service*>(&::xtreemfs::pbrpc::Service::default_instance()); +} + +serviceRegisterRequest::serviceRegisterRequest(const serviceRegisterRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void serviceRegisterRequest::SharedCtor() { + _cached_size_ = 0; + service_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +serviceRegisterRequest::~serviceRegisterRequest() { + SharedDtor(); +} + +void serviceRegisterRequest::SharedDtor() { + if (this != default_instance_) { + delete service_; + } +} + +void serviceRegisterRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* serviceRegisterRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return serviceRegisterRequest_descriptor_; +} + +const serviceRegisterRequest& serviceRegisterRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +serviceRegisterRequest* serviceRegisterRequest::default_instance_ = NULL; + +serviceRegisterRequest* serviceRegisterRequest::New() const { + return new serviceRegisterRequest; +} + +void serviceRegisterRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_service()) { + if (service_ != NULL) service_->::xtreemfs::pbrpc::Service::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool serviceRegisterRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.Service service = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_service())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void serviceRegisterRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.Service service = 1; + if (has_service()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->service(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* serviceRegisterRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.Service service = 1; + if (has_service()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->service(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int serviceRegisterRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.Service service = 1; + if (has_service()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->service()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void serviceRegisterRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const serviceRegisterRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void serviceRegisterRequest::MergeFrom(const serviceRegisterRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_service()) { + mutable_service()->::xtreemfs::pbrpc::Service::MergeFrom(from.service()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void serviceRegisterRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void serviceRegisterRequest::CopyFrom(const serviceRegisterRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool serviceRegisterRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_service()) { + if (!this->service().IsInitialized()) return false; + } + return true; +} + +void serviceRegisterRequest::Swap(serviceRegisterRequest* other) { + if (other != this) { + std::swap(service_, other->service_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata serviceRegisterRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = serviceRegisterRequest_descriptor_; + metadata.reflection = serviceRegisterRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int serviceRegisterResponse::kNewVersionFieldNumber; +#endif // !_MSC_VER + +serviceRegisterResponse::serviceRegisterResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void serviceRegisterResponse::InitAsDefaultInstance() { +} + +serviceRegisterResponse::serviceRegisterResponse(const serviceRegisterResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void serviceRegisterResponse::SharedCtor() { + _cached_size_ = 0; + new_version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +serviceRegisterResponse::~serviceRegisterResponse() { + SharedDtor(); +} + +void serviceRegisterResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void serviceRegisterResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* serviceRegisterResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return serviceRegisterResponse_descriptor_; +} + +const serviceRegisterResponse& serviceRegisterResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +serviceRegisterResponse* serviceRegisterResponse::default_instance_ = NULL; + +serviceRegisterResponse* serviceRegisterResponse::New() const { + return new serviceRegisterResponse; +} + +void serviceRegisterResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + new_version_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool serviceRegisterResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 new_version = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &new_version_))); + set_has_new_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void serviceRegisterResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 new_version = 1; + if (has_new_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->new_version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* serviceRegisterResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 new_version = 1; + if (has_new_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->new_version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int serviceRegisterResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 new_version = 1; + if (has_new_version()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void serviceRegisterResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const serviceRegisterResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void serviceRegisterResponse::MergeFrom(const serviceRegisterResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_new_version()) { + set_new_version(from.new_version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void serviceRegisterResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void serviceRegisterResponse::CopyFrom(const serviceRegisterResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool serviceRegisterResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void serviceRegisterResponse::Swap(serviceRegisterResponse* other) { + if (other != this) { + std::swap(new_version_, other->new_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata serviceRegisterResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = serviceRegisterResponse_descriptor_; + metadata.reflection = serviceRegisterResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int configurationGetRequest::kUuidFieldNumber; +#endif // !_MSC_VER + +configurationGetRequest::configurationGetRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void configurationGetRequest::InitAsDefaultInstance() { +} + +configurationGetRequest::configurationGetRequest(const configurationGetRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void configurationGetRequest::SharedCtor() { + _cached_size_ = 0; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +configurationGetRequest::~configurationGetRequest() { + SharedDtor(); +} + +void configurationGetRequest::SharedDtor() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (this != default_instance_) { + } +} + +void configurationGetRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* configurationGetRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return configurationGetRequest_descriptor_; +} + +const configurationGetRequest& configurationGetRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +configurationGetRequest* configurationGetRequest::default_instance_ = NULL; + +configurationGetRequest* configurationGetRequest::New() const { + return new configurationGetRequest; +} + +void configurationGetRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_uuid()) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool configurationGetRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string uuid = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_uuid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void configurationGetRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string uuid = 1; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->uuid(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* configurationGetRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string uuid = 1; + if (has_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->uuid().data(), this->uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->uuid(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int configurationGetRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string uuid = 1; + if (has_uuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->uuid()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void configurationGetRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const configurationGetRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void configurationGetRequest::MergeFrom(const configurationGetRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_uuid()) { + set_uuid(from.uuid()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void configurationGetRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void configurationGetRequest::CopyFrom(const configurationGetRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool configurationGetRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void configurationGetRequest::Swap(configurationGetRequest* other) { + if (other != this) { + std::swap(uuid_, other->uuid_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata configurationGetRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = configurationGetRequest_descriptor_; + metadata.reflection = configurationGetRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int configurationSetResponse::kNewVersionFieldNumber; +#endif // !_MSC_VER + +configurationSetResponse::configurationSetResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void configurationSetResponse::InitAsDefaultInstance() { +} + +configurationSetResponse::configurationSetResponse(const configurationSetResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void configurationSetResponse::SharedCtor() { + _cached_size_ = 0; + new_version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +configurationSetResponse::~configurationSetResponse() { + SharedDtor(); +} + +void configurationSetResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void configurationSetResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* configurationSetResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return configurationSetResponse_descriptor_; +} + +const configurationSetResponse& configurationSetResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + return *default_instance_; +} + +configurationSetResponse* configurationSetResponse::default_instance_ = NULL; + +configurationSetResponse* configurationSetResponse::New() const { + return new configurationSetResponse; +} + +void configurationSetResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + new_version_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool configurationSetResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional fixed64 new_version = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &new_version_))); + set_has_new_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void configurationSetResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional fixed64 new_version = 1; + if (has_new_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->new_version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* configurationSetResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional fixed64 new_version = 1; + if (has_new_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->new_version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int configurationSetResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional fixed64 new_version = 1; + if (has_new_version()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void configurationSetResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const configurationSetResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void configurationSetResponse::MergeFrom(const configurationSetResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_new_version()) { + set_new_version(from.new_version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void configurationSetResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void configurationSetResponse::CopyFrom(const configurationSetResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool configurationSetResponse::IsInitialized() const { + + return true; +} + +void configurationSetResponse::Swap(configurationSetResponse* other) { + if (other != this) { + std::swap(new_version_, other->new_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata configurationSetResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = configurationSetResponse_descriptor_; + metadata.reflection = configurationSetResponse_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/generated/xtreemfs/DIR.pb.h b/cpp/generated/xtreemfs/DIR.pb.h new file mode 100644 index 0000000..0dbba44 --- /dev/null +++ b/cpp/generated/xtreemfs/DIR.pb.h @@ -0,0 +1,3602 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/DIR.proto + +#ifndef PROTOBUF_xtreemfs_2fDIR_2eproto__INCLUDED +#define PROTOBUF_xtreemfs_2fDIR_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include "include/PBRPC.pb.h" +#include "include/Common.pb.h" +#include "xtreemfs/GlobalTypes.pb.h" +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); +void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); +void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + +class AddressMapping; +class AddressMappingSet; +class DirService; +class ServiceDataMap; +class Service; +class ServiceSet; +class Configuration; +class addressMappingGetRequest; +class addressMappingGetResponse; +class addressMappingSetResponse; +class globalTimeSGetResponse; +class serviceDeregisterRequest; +class serviceGetByNameRequest; +class serviceGetByUUIDRequest; +class serviceGetByTypeRequest; +class serviceRegisterRequest; +class serviceRegisterResponse; +class configurationGetRequest; +class configurationSetResponse; + +enum ServiceType { + SERVICE_TYPE_MIXED = 0, + SERVICE_TYPE_MRC = 1, + SERVICE_TYPE_OSD = 2, + SERVICE_TYPE_VOLUME = 3, + SERVICE_TYPE_DIR = 4 +}; +bool ServiceType_IsValid(int value); +const ServiceType ServiceType_MIN = SERVICE_TYPE_MIXED; +const ServiceType ServiceType_MAX = SERVICE_TYPE_DIR; +const int ServiceType_ARRAYSIZE = ServiceType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ServiceType_descriptor(); +inline const ::std::string& ServiceType_Name(ServiceType value) { + return ::google::protobuf::internal::NameOfEnum( + ServiceType_descriptor(), value); +} +inline bool ServiceType_Parse( + const ::std::string& name, ServiceType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ServiceType_descriptor(), name, value); +} +enum ServiceStatus { + SERVICE_STATUS_AVAIL = 0, + SERVICE_STATUS_TO_BE_REMOVED = 1, + SERVICE_STATUS_REMOVED = 2 +}; +bool ServiceStatus_IsValid(int value); +const ServiceStatus ServiceStatus_MIN = SERVICE_STATUS_AVAIL; +const ServiceStatus ServiceStatus_MAX = SERVICE_STATUS_REMOVED; +const int ServiceStatus_ARRAYSIZE = ServiceStatus_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ServiceStatus_descriptor(); +inline const ::std::string& ServiceStatus_Name(ServiceStatus value) { + return ::google::protobuf::internal::NameOfEnum( + ServiceStatus_descriptor(), value); +} +inline bool ServiceStatus_Parse( + const ::std::string& name, ServiceStatus* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ServiceStatus_descriptor(), name, value); +} +// =================================================================== + +class AddressMapping : public ::google::protobuf::Message { + public: + AddressMapping(); + virtual ~AddressMapping(); + + AddressMapping(const AddressMapping& from); + + inline AddressMapping& operator=(const AddressMapping& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const AddressMapping& default_instance(); + + void Swap(AddressMapping* other); + + // implements Message ---------------------------------------------- + + AddressMapping* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const AddressMapping& from); + void MergeFrom(const AddressMapping& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string uuid = 1; + inline bool has_uuid() const; + inline void clear_uuid(); + static const int kUuidFieldNumber = 1; + inline const ::std::string& uuid() const; + inline void set_uuid(const ::std::string& value); + inline void set_uuid(const char* value); + inline void set_uuid(const char* value, size_t size); + inline ::std::string* mutable_uuid(); + inline ::std::string* release_uuid(); + inline void set_allocated_uuid(::std::string* uuid); + + // required fixed64 version = 2; + inline bool has_version() const; + inline void clear_version(); + static const int kVersionFieldNumber = 2; + inline ::google::protobuf::uint64 version() const; + inline void set_version(::google::protobuf::uint64 value); + + // required string protocol = 3; + inline bool has_protocol() const; + inline void clear_protocol(); + static const int kProtocolFieldNumber = 3; + inline const ::std::string& protocol() const; + inline void set_protocol(const ::std::string& value); + inline void set_protocol(const char* value); + inline void set_protocol(const char* value, size_t size); + inline ::std::string* mutable_protocol(); + inline ::std::string* release_protocol(); + inline void set_allocated_protocol(::std::string* protocol); + + // required string address = 4; + inline bool has_address() const; + inline void clear_address(); + static const int kAddressFieldNumber = 4; + inline const ::std::string& address() const; + inline void set_address(const ::std::string& value); + inline void set_address(const char* value); + inline void set_address(const char* value, size_t size); + inline ::std::string* mutable_address(); + inline ::std::string* release_address(); + inline void set_allocated_address(::std::string* address); + + // required fixed32 port = 5; + inline bool has_port() const; + inline void clear_port(); + static const int kPortFieldNumber = 5; + inline ::google::protobuf::uint32 port() const; + inline void set_port(::google::protobuf::uint32 value); + + // required string match_network = 6; + inline bool has_match_network() const; + inline void clear_match_network(); + static const int kMatchNetworkFieldNumber = 6; + inline const ::std::string& match_network() const; + inline void set_match_network(const ::std::string& value); + inline void set_match_network(const char* value); + inline void set_match_network(const char* value, size_t size); + inline ::std::string* mutable_match_network(); + inline ::std::string* release_match_network(); + inline void set_allocated_match_network(::std::string* match_network); + + // required fixed32 ttl_s = 7; + inline bool has_ttl_s() const; + inline void clear_ttl_s(); + static const int kTtlSFieldNumber = 7; + inline ::google::protobuf::uint32 ttl_s() const; + inline void set_ttl_s(::google::protobuf::uint32 value); + + // required string uri = 8; + inline bool has_uri() const; + inline void clear_uri(); + static const int kUriFieldNumber = 8; + inline const ::std::string& uri() const; + inline void set_uri(const ::std::string& value); + inline void set_uri(const char* value); + inline void set_uri(const char* value, size_t size); + inline ::std::string* mutable_uri(); + inline ::std::string* release_uri(); + inline void set_allocated_uri(::std::string* uri); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.AddressMapping) + private: + inline void set_has_uuid(); + inline void clear_has_uuid(); + inline void set_has_version(); + inline void clear_has_version(); + inline void set_has_protocol(); + inline void clear_has_protocol(); + inline void set_has_address(); + inline void clear_has_address(); + inline void set_has_port(); + inline void clear_has_port(); + inline void set_has_match_network(); + inline void clear_has_match_network(); + inline void set_has_ttl_s(); + inline void clear_has_ttl_s(); + inline void set_has_uri(); + inline void clear_has_uri(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* uuid_; + ::google::protobuf::uint64 version_; + ::std::string* protocol_; + ::std::string* address_; + ::std::string* match_network_; + ::google::protobuf::uint32 port_; + ::google::protobuf::uint32 ttl_s_; + ::std::string* uri_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static AddressMapping* default_instance_; +}; +// ------------------------------------------------------------------- + +class AddressMappingSet : public ::google::protobuf::Message { + public: + AddressMappingSet(); + virtual ~AddressMappingSet(); + + AddressMappingSet(const AddressMappingSet& from); + + inline AddressMappingSet& operator=(const AddressMappingSet& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const AddressMappingSet& default_instance(); + + void Swap(AddressMappingSet* other); + + // implements Message ---------------------------------------------- + + AddressMappingSet* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const AddressMappingSet& from); + void MergeFrom(const AddressMappingSet& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + inline int mappings_size() const; + inline void clear_mappings(); + static const int kMappingsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::AddressMapping& mappings(int index) const; + inline ::xtreemfs::pbrpc::AddressMapping* mutable_mappings(int index); + inline ::xtreemfs::pbrpc::AddressMapping* add_mappings(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::AddressMapping >& + mappings() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::AddressMapping >* + mutable_mappings(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.AddressMappingSet) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::AddressMapping > mappings_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static AddressMappingSet* default_instance_; +}; +// ------------------------------------------------------------------- + +class DirService : public ::google::protobuf::Message { + public: + DirService(); + virtual ~DirService(); + + DirService(const DirService& from); + + inline DirService& operator=(const DirService& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const DirService& default_instance(); + + void Swap(DirService* other); + + // implements Message ---------------------------------------------- + + DirService* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DirService& from); + void MergeFrom(const DirService& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string address = 1; + inline bool has_address() const; + inline void clear_address(); + static const int kAddressFieldNumber = 1; + inline const ::std::string& address() const; + inline void set_address(const ::std::string& value); + inline void set_address(const char* value); + inline void set_address(const char* value, size_t size); + inline ::std::string* mutable_address(); + inline ::std::string* release_address(); + inline void set_allocated_address(::std::string* address); + + // required fixed32 port = 2; + inline bool has_port() const; + inline void clear_port(); + static const int kPortFieldNumber = 2; + inline ::google::protobuf::uint32 port() const; + inline void set_port(::google::protobuf::uint32 value); + + // required string protocol = 3; + inline bool has_protocol() const; + inline void clear_protocol(); + static const int kProtocolFieldNumber = 3; + inline const ::std::string& protocol() const; + inline void set_protocol(const ::std::string& value); + inline void set_protocol(const char* value); + inline void set_protocol(const char* value, size_t size); + inline ::std::string* mutable_protocol(); + inline ::std::string* release_protocol(); + inline void set_allocated_protocol(::std::string* protocol); + + // required fixed32 interface_version = 4; + inline bool has_interface_version() const; + inline void clear_interface_version(); + static const int kInterfaceVersionFieldNumber = 4; + inline ::google::protobuf::uint32 interface_version() const; + inline void set_interface_version(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.DirService) + private: + inline void set_has_address(); + inline void clear_has_address(); + inline void set_has_port(); + inline void clear_has_port(); + inline void set_has_protocol(); + inline void clear_has_protocol(); + inline void set_has_interface_version(); + inline void clear_has_interface_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* address_; + ::std::string* protocol_; + ::google::protobuf::uint32 port_; + ::google::protobuf::uint32 interface_version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static DirService* default_instance_; +}; +// ------------------------------------------------------------------- + +class ServiceDataMap : public ::google::protobuf::Message { + public: + ServiceDataMap(); + virtual ~ServiceDataMap(); + + ServiceDataMap(const ServiceDataMap& from); + + inline ServiceDataMap& operator=(const ServiceDataMap& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServiceDataMap& default_instance(); + + void Swap(ServiceDataMap* other); + + // implements Message ---------------------------------------------- + + ServiceDataMap* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServiceDataMap& from); + void MergeFrom(const ServiceDataMap& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + inline int data_size() const; + inline void clear_data(); + static const int kDataFieldNumber = 1; + inline const ::xtreemfs::pbrpc::KeyValuePair& data(int index) const; + inline ::xtreemfs::pbrpc::KeyValuePair* mutable_data(int index); + inline ::xtreemfs::pbrpc::KeyValuePair* add_data(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >& + data() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >* + mutable_data(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ServiceDataMap) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair > data_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static ServiceDataMap* default_instance_; +}; +// ------------------------------------------------------------------- + +class Service : public ::google::protobuf::Message { + public: + Service(); + virtual ~Service(); + + Service(const Service& from); + + inline Service& operator=(const Service& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Service& default_instance(); + + void Swap(Service* other); + + // implements Message ---------------------------------------------- + + Service* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Service& from); + void MergeFrom(const Service& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.ServiceType type = 1; + inline bool has_type() const; + inline void clear_type(); + static const int kTypeFieldNumber = 1; + inline ::xtreemfs::pbrpc::ServiceType type() const; + inline void set_type(::xtreemfs::pbrpc::ServiceType value); + + // required string uuid = 2; + inline bool has_uuid() const; + inline void clear_uuid(); + static const int kUuidFieldNumber = 2; + inline const ::std::string& uuid() const; + inline void set_uuid(const ::std::string& value); + inline void set_uuid(const char* value); + inline void set_uuid(const char* value, size_t size); + inline ::std::string* mutable_uuid(); + inline ::std::string* release_uuid(); + inline void set_allocated_uuid(::std::string* uuid); + + // required fixed64 version = 3; + inline bool has_version() const; + inline void clear_version(); + static const int kVersionFieldNumber = 3; + inline ::google::protobuf::uint64 version() const; + inline void set_version(::google::protobuf::uint64 value); + + // required string name = 4; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 4; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // required fixed64 last_updated_s = 5; + inline bool has_last_updated_s() const; + inline void clear_last_updated_s(); + static const int kLastUpdatedSFieldNumber = 5; + inline ::google::protobuf::uint64 last_updated_s() const; + inline void set_last_updated_s(::google::protobuf::uint64 value); + + // required .xtreemfs.pbrpc.ServiceDataMap data = 6; + inline bool has_data() const; + inline void clear_data(); + static const int kDataFieldNumber = 6; + inline const ::xtreemfs::pbrpc::ServiceDataMap& data() const; + inline ::xtreemfs::pbrpc::ServiceDataMap* mutable_data(); + inline ::xtreemfs::pbrpc::ServiceDataMap* release_data(); + inline void set_allocated_data(::xtreemfs::pbrpc::ServiceDataMap* data); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Service) + private: + inline void set_has_type(); + inline void clear_has_type(); + inline void set_has_uuid(); + inline void clear_has_uuid(); + inline void set_has_version(); + inline void clear_has_version(); + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_last_updated_s(); + inline void clear_has_last_updated_s(); + inline void set_has_data(); + inline void clear_has_data(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* uuid_; + ::google::protobuf::uint64 version_; + ::std::string* name_; + ::google::protobuf::uint64 last_updated_s_; + ::xtreemfs::pbrpc::ServiceDataMap* data_; + int type_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static Service* default_instance_; +}; +// ------------------------------------------------------------------- + +class ServiceSet : public ::google::protobuf::Message { + public: + ServiceSet(); + virtual ~ServiceSet(); + + ServiceSet(const ServiceSet& from); + + inline ServiceSet& operator=(const ServiceSet& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServiceSet& default_instance(); + + void Swap(ServiceSet* other); + + // implements Message ---------------------------------------------- + + ServiceSet* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServiceSet& from); + void MergeFrom(const ServiceSet& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .xtreemfs.pbrpc.Service services = 1; + inline int services_size() const; + inline void clear_services(); + static const int kServicesFieldNumber = 1; + inline const ::xtreemfs::pbrpc::Service& services(int index) const; + inline ::xtreemfs::pbrpc::Service* mutable_services(int index); + inline ::xtreemfs::pbrpc::Service* add_services(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Service >& + services() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Service >* + mutable_services(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ServiceSet) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Service > services_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static ServiceSet* default_instance_; +}; +// ------------------------------------------------------------------- + +class Configuration : public ::google::protobuf::Message { + public: + Configuration(); + virtual ~Configuration(); + + Configuration(const Configuration& from); + + inline Configuration& operator=(const Configuration& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Configuration& default_instance(); + + void Swap(Configuration* other); + + // implements Message ---------------------------------------------- + + Configuration* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Configuration& from); + void MergeFrom(const Configuration& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string uuid = 1; + inline bool has_uuid() const; + inline void clear_uuid(); + static const int kUuidFieldNumber = 1; + inline const ::std::string& uuid() const; + inline void set_uuid(const ::std::string& value); + inline void set_uuid(const char* value); + inline void set_uuid(const char* value, size_t size); + inline ::std::string* mutable_uuid(); + inline ::std::string* release_uuid(); + inline void set_allocated_uuid(::std::string* uuid); + + // repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + inline int parameter_size() const; + inline void clear_parameter(); + static const int kParameterFieldNumber = 2; + inline const ::xtreemfs::pbrpc::KeyValuePair& parameter(int index) const; + inline ::xtreemfs::pbrpc::KeyValuePair* mutable_parameter(int index); + inline ::xtreemfs::pbrpc::KeyValuePair* add_parameter(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >& + parameter() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >* + mutable_parameter(); + + // required fixed64 version = 3; + inline bool has_version() const; + inline void clear_version(); + static const int kVersionFieldNumber = 3; + inline ::google::protobuf::uint64 version() const; + inline void set_version(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Configuration) + private: + inline void set_has_uuid(); + inline void clear_has_uuid(); + inline void set_has_version(); + inline void clear_has_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* uuid_; + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair > parameter_; + ::google::protobuf::uint64 version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static Configuration* default_instance_; +}; +// ------------------------------------------------------------------- + +class addressMappingGetRequest : public ::google::protobuf::Message { + public: + addressMappingGetRequest(); + virtual ~addressMappingGetRequest(); + + addressMappingGetRequest(const addressMappingGetRequest& from); + + inline addressMappingGetRequest& operator=(const addressMappingGetRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const addressMappingGetRequest& default_instance(); + + void Swap(addressMappingGetRequest* other); + + // implements Message ---------------------------------------------- + + addressMappingGetRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const addressMappingGetRequest& from); + void MergeFrom(const addressMappingGetRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string uuid = 1; + inline bool has_uuid() const; + inline void clear_uuid(); + static const int kUuidFieldNumber = 1; + inline const ::std::string& uuid() const; + inline void set_uuid(const ::std::string& value); + inline void set_uuid(const char* value); + inline void set_uuid(const char* value, size_t size); + inline ::std::string* mutable_uuid(); + inline ::std::string* release_uuid(); + inline void set_allocated_uuid(::std::string* uuid); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.addressMappingGetRequest) + private: + inline void set_has_uuid(); + inline void clear_has_uuid(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* uuid_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static addressMappingGetRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class addressMappingGetResponse : public ::google::protobuf::Message { + public: + addressMappingGetResponse(); + virtual ~addressMappingGetResponse(); + + addressMappingGetResponse(const addressMappingGetResponse& from); + + inline addressMappingGetResponse& operator=(const addressMappingGetResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const addressMappingGetResponse& default_instance(); + + void Swap(addressMappingGetResponse* other); + + // implements Message ---------------------------------------------- + + addressMappingGetResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const addressMappingGetResponse& from); + void MergeFrom(const addressMappingGetResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + inline bool has_result() const; + inline void clear_result(); + static const int kResultFieldNumber = 1; + inline const ::xtreemfs::pbrpc::AddressMappingSet& result() const; + inline ::xtreemfs::pbrpc::AddressMappingSet* mutable_result(); + inline ::xtreemfs::pbrpc::AddressMappingSet* release_result(); + inline void set_allocated_result(::xtreemfs::pbrpc::AddressMappingSet* result); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.addressMappingGetResponse) + private: + inline void set_has_result(); + inline void clear_has_result(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::AddressMappingSet* result_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static addressMappingGetResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class addressMappingSetResponse : public ::google::protobuf::Message { + public: + addressMappingSetResponse(); + virtual ~addressMappingSetResponse(); + + addressMappingSetResponse(const addressMappingSetResponse& from); + + inline addressMappingSetResponse& operator=(const addressMappingSetResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const addressMappingSetResponse& default_instance(); + + void Swap(addressMappingSetResponse* other); + + // implements Message ---------------------------------------------- + + addressMappingSetResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const addressMappingSetResponse& from); + void MergeFrom(const addressMappingSetResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional fixed64 new_version = 1; + inline bool has_new_version() const; + inline void clear_new_version(); + static const int kNewVersionFieldNumber = 1; + inline ::google::protobuf::uint64 new_version() const; + inline void set_new_version(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.addressMappingSetResponse) + private: + inline void set_has_new_version(); + inline void clear_has_new_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 new_version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static addressMappingSetResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class globalTimeSGetResponse : public ::google::protobuf::Message { + public: + globalTimeSGetResponse(); + virtual ~globalTimeSGetResponse(); + + globalTimeSGetResponse(const globalTimeSGetResponse& from); + + inline globalTimeSGetResponse& operator=(const globalTimeSGetResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const globalTimeSGetResponse& default_instance(); + + void Swap(globalTimeSGetResponse* other); + + // implements Message ---------------------------------------------- + + globalTimeSGetResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const globalTimeSGetResponse& from); + void MergeFrom(const globalTimeSGetResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 time_in_seconds = 1; + inline bool has_time_in_seconds() const; + inline void clear_time_in_seconds(); + static const int kTimeInSecondsFieldNumber = 1; + inline ::google::protobuf::uint64 time_in_seconds() const; + inline void set_time_in_seconds(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.globalTimeSGetResponse) + private: + inline void set_has_time_in_seconds(); + inline void clear_has_time_in_seconds(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 time_in_seconds_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static globalTimeSGetResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class serviceDeregisterRequest : public ::google::protobuf::Message { + public: + serviceDeregisterRequest(); + virtual ~serviceDeregisterRequest(); + + serviceDeregisterRequest(const serviceDeregisterRequest& from); + + inline serviceDeregisterRequest& operator=(const serviceDeregisterRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const serviceDeregisterRequest& default_instance(); + + void Swap(serviceDeregisterRequest* other); + + // implements Message ---------------------------------------------- + + serviceDeregisterRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const serviceDeregisterRequest& from); + void MergeFrom(const serviceDeregisterRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string uuid = 1; + inline bool has_uuid() const; + inline void clear_uuid(); + static const int kUuidFieldNumber = 1; + inline const ::std::string& uuid() const; + inline void set_uuid(const ::std::string& value); + inline void set_uuid(const char* value); + inline void set_uuid(const char* value, size_t size); + inline ::std::string* mutable_uuid(); + inline ::std::string* release_uuid(); + inline void set_allocated_uuid(::std::string* uuid); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceDeregisterRequest) + private: + inline void set_has_uuid(); + inline void clear_has_uuid(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* uuid_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static serviceDeregisterRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class serviceGetByNameRequest : public ::google::protobuf::Message { + public: + serviceGetByNameRequest(); + virtual ~serviceGetByNameRequest(); + + serviceGetByNameRequest(const serviceGetByNameRequest& from); + + inline serviceGetByNameRequest& operator=(const serviceGetByNameRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const serviceGetByNameRequest& default_instance(); + + void Swap(serviceGetByNameRequest* other); + + // implements Message ---------------------------------------------- + + serviceGetByNameRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const serviceGetByNameRequest& from); + void MergeFrom(const serviceGetByNameRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceGetByNameRequest) + private: + inline void set_has_name(); + inline void clear_has_name(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static serviceGetByNameRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class serviceGetByUUIDRequest : public ::google::protobuf::Message { + public: + serviceGetByUUIDRequest(); + virtual ~serviceGetByUUIDRequest(); + + serviceGetByUUIDRequest(const serviceGetByUUIDRequest& from); + + inline serviceGetByUUIDRequest& operator=(const serviceGetByUUIDRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const serviceGetByUUIDRequest& default_instance(); + + void Swap(serviceGetByUUIDRequest* other); + + // implements Message ---------------------------------------------- + + serviceGetByUUIDRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const serviceGetByUUIDRequest& from); + void MergeFrom(const serviceGetByUUIDRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceGetByUUIDRequest) + private: + inline void set_has_name(); + inline void clear_has_name(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static serviceGetByUUIDRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class serviceGetByTypeRequest : public ::google::protobuf::Message { + public: + serviceGetByTypeRequest(); + virtual ~serviceGetByTypeRequest(); + + serviceGetByTypeRequest(const serviceGetByTypeRequest& from); + + inline serviceGetByTypeRequest& operator=(const serviceGetByTypeRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const serviceGetByTypeRequest& default_instance(); + + void Swap(serviceGetByTypeRequest* other); + + // implements Message ---------------------------------------------- + + serviceGetByTypeRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const serviceGetByTypeRequest& from); + void MergeFrom(const serviceGetByTypeRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.ServiceType type = 1; + inline bool has_type() const; + inline void clear_type(); + static const int kTypeFieldNumber = 1; + inline ::xtreemfs::pbrpc::ServiceType type() const; + inline void set_type(::xtreemfs::pbrpc::ServiceType value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceGetByTypeRequest) + private: + inline void set_has_type(); + inline void clear_has_type(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + int type_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static serviceGetByTypeRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class serviceRegisterRequest : public ::google::protobuf::Message { + public: + serviceRegisterRequest(); + virtual ~serviceRegisterRequest(); + + serviceRegisterRequest(const serviceRegisterRequest& from); + + inline serviceRegisterRequest& operator=(const serviceRegisterRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const serviceRegisterRequest& default_instance(); + + void Swap(serviceRegisterRequest* other); + + // implements Message ---------------------------------------------- + + serviceRegisterRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const serviceRegisterRequest& from); + void MergeFrom(const serviceRegisterRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.Service service = 1; + inline bool has_service() const; + inline void clear_service(); + static const int kServiceFieldNumber = 1; + inline const ::xtreemfs::pbrpc::Service& service() const; + inline ::xtreemfs::pbrpc::Service* mutable_service(); + inline ::xtreemfs::pbrpc::Service* release_service(); + inline void set_allocated_service(::xtreemfs::pbrpc::Service* service); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceRegisterRequest) + private: + inline void set_has_service(); + inline void clear_has_service(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::Service* service_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static serviceRegisterRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class serviceRegisterResponse : public ::google::protobuf::Message { + public: + serviceRegisterResponse(); + virtual ~serviceRegisterResponse(); + + serviceRegisterResponse(const serviceRegisterResponse& from); + + inline serviceRegisterResponse& operator=(const serviceRegisterResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const serviceRegisterResponse& default_instance(); + + void Swap(serviceRegisterResponse* other); + + // implements Message ---------------------------------------------- + + serviceRegisterResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const serviceRegisterResponse& from); + void MergeFrom(const serviceRegisterResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 new_version = 1; + inline bool has_new_version() const; + inline void clear_new_version(); + static const int kNewVersionFieldNumber = 1; + inline ::google::protobuf::uint64 new_version() const; + inline void set_new_version(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceRegisterResponse) + private: + inline void set_has_new_version(); + inline void clear_has_new_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 new_version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static serviceRegisterResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class configurationGetRequest : public ::google::protobuf::Message { + public: + configurationGetRequest(); + virtual ~configurationGetRequest(); + + configurationGetRequest(const configurationGetRequest& from); + + inline configurationGetRequest& operator=(const configurationGetRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const configurationGetRequest& default_instance(); + + void Swap(configurationGetRequest* other); + + // implements Message ---------------------------------------------- + + configurationGetRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const configurationGetRequest& from); + void MergeFrom(const configurationGetRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string uuid = 1; + inline bool has_uuid() const; + inline void clear_uuid(); + static const int kUuidFieldNumber = 1; + inline const ::std::string& uuid() const; + inline void set_uuid(const ::std::string& value); + inline void set_uuid(const char* value); + inline void set_uuid(const char* value, size_t size); + inline ::std::string* mutable_uuid(); + inline ::std::string* release_uuid(); + inline void set_allocated_uuid(::std::string* uuid); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.configurationGetRequest) + private: + inline void set_has_uuid(); + inline void clear_has_uuid(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* uuid_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static configurationGetRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class configurationSetResponse : public ::google::protobuf::Message { + public: + configurationSetResponse(); + virtual ~configurationSetResponse(); + + configurationSetResponse(const configurationSetResponse& from); + + inline configurationSetResponse& operator=(const configurationSetResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const configurationSetResponse& default_instance(); + + void Swap(configurationSetResponse* other); + + // implements Message ---------------------------------------------- + + configurationSetResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const configurationSetResponse& from); + void MergeFrom(const configurationSetResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional fixed64 new_version = 1; + inline bool has_new_version() const; + inline void clear_new_version(); + static const int kNewVersionFieldNumber = 1; + inline ::google::protobuf::uint64 new_version() const; + inline void set_new_version(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.configurationSetResponse) + private: + inline void set_has_new_version(); + inline void clear_has_new_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 new_version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fDIR_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fDIR_2eproto(); + + void InitAsDefaultInstance(); + static configurationSetResponse* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// AddressMapping + +// required string uuid = 1; +inline bool AddressMapping::has_uuid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void AddressMapping::set_has_uuid() { + _has_bits_[0] |= 0x00000001u; +} +inline void AddressMapping::clear_has_uuid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void AddressMapping::clear_uuid() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + clear_has_uuid(); +} +inline const ::std::string& AddressMapping::uuid() const { + return *uuid_; +} +inline void AddressMapping::set_uuid(const ::std::string& value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void AddressMapping::set_uuid(const char* value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void AddressMapping::set_uuid(const char* value, size_t size) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* AddressMapping::mutable_uuid() { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + return uuid_; +} +inline ::std::string* AddressMapping::release_uuid() { + clear_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = uuid_; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void AddressMapping::set_allocated_uuid(::std::string* uuid) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (uuid) { + set_has_uuid(); + uuid_ = uuid; + } else { + clear_has_uuid(); + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 version = 2; +inline bool AddressMapping::has_version() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void AddressMapping::set_has_version() { + _has_bits_[0] |= 0x00000002u; +} +inline void AddressMapping::clear_has_version() { + _has_bits_[0] &= ~0x00000002u; +} +inline void AddressMapping::clear_version() { + version_ = GOOGLE_ULONGLONG(0); + clear_has_version(); +} +inline ::google::protobuf::uint64 AddressMapping::version() const { + return version_; +} +inline void AddressMapping::set_version(::google::protobuf::uint64 value) { + set_has_version(); + version_ = value; +} + +// required string protocol = 3; +inline bool AddressMapping::has_protocol() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void AddressMapping::set_has_protocol() { + _has_bits_[0] |= 0x00000004u; +} +inline void AddressMapping::clear_has_protocol() { + _has_bits_[0] &= ~0x00000004u; +} +inline void AddressMapping::clear_protocol() { + if (protocol_ != &::google::protobuf::internal::kEmptyString) { + protocol_->clear(); + } + clear_has_protocol(); +} +inline const ::std::string& AddressMapping::protocol() const { + return *protocol_; +} +inline void AddressMapping::set_protocol(const ::std::string& value) { + set_has_protocol(); + if (protocol_ == &::google::protobuf::internal::kEmptyString) { + protocol_ = new ::std::string; + } + protocol_->assign(value); +} +inline void AddressMapping::set_protocol(const char* value) { + set_has_protocol(); + if (protocol_ == &::google::protobuf::internal::kEmptyString) { + protocol_ = new ::std::string; + } + protocol_->assign(value); +} +inline void AddressMapping::set_protocol(const char* value, size_t size) { + set_has_protocol(); + if (protocol_ == &::google::protobuf::internal::kEmptyString) { + protocol_ = new ::std::string; + } + protocol_->assign(reinterpret_cast(value), size); +} +inline ::std::string* AddressMapping::mutable_protocol() { + set_has_protocol(); + if (protocol_ == &::google::protobuf::internal::kEmptyString) { + protocol_ = new ::std::string; + } + return protocol_; +} +inline ::std::string* AddressMapping::release_protocol() { + clear_has_protocol(); + if (protocol_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = protocol_; + protocol_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void AddressMapping::set_allocated_protocol(::std::string* protocol) { + if (protocol_ != &::google::protobuf::internal::kEmptyString) { + delete protocol_; + } + if (protocol) { + set_has_protocol(); + protocol_ = protocol; + } else { + clear_has_protocol(); + protocol_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string address = 4; +inline bool AddressMapping::has_address() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void AddressMapping::set_has_address() { + _has_bits_[0] |= 0x00000008u; +} +inline void AddressMapping::clear_has_address() { + _has_bits_[0] &= ~0x00000008u; +} +inline void AddressMapping::clear_address() { + if (address_ != &::google::protobuf::internal::kEmptyString) { + address_->clear(); + } + clear_has_address(); +} +inline const ::std::string& AddressMapping::address() const { + return *address_; +} +inline void AddressMapping::set_address(const ::std::string& value) { + set_has_address(); + if (address_ == &::google::protobuf::internal::kEmptyString) { + address_ = new ::std::string; + } + address_->assign(value); +} +inline void AddressMapping::set_address(const char* value) { + set_has_address(); + if (address_ == &::google::protobuf::internal::kEmptyString) { + address_ = new ::std::string; + } + address_->assign(value); +} +inline void AddressMapping::set_address(const char* value, size_t size) { + set_has_address(); + if (address_ == &::google::protobuf::internal::kEmptyString) { + address_ = new ::std::string; + } + address_->assign(reinterpret_cast(value), size); +} +inline ::std::string* AddressMapping::mutable_address() { + set_has_address(); + if (address_ == &::google::protobuf::internal::kEmptyString) { + address_ = new ::std::string; + } + return address_; +} +inline ::std::string* AddressMapping::release_address() { + clear_has_address(); + if (address_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = address_; + address_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void AddressMapping::set_allocated_address(::std::string* address) { + if (address_ != &::google::protobuf::internal::kEmptyString) { + delete address_; + } + if (address) { + set_has_address(); + address_ = address; + } else { + clear_has_address(); + address_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 port = 5; +inline bool AddressMapping::has_port() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void AddressMapping::set_has_port() { + _has_bits_[0] |= 0x00000010u; +} +inline void AddressMapping::clear_has_port() { + _has_bits_[0] &= ~0x00000010u; +} +inline void AddressMapping::clear_port() { + port_ = 0u; + clear_has_port(); +} +inline ::google::protobuf::uint32 AddressMapping::port() const { + return port_; +} +inline void AddressMapping::set_port(::google::protobuf::uint32 value) { + set_has_port(); + port_ = value; +} + +// required string match_network = 6; +inline bool AddressMapping::has_match_network() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void AddressMapping::set_has_match_network() { + _has_bits_[0] |= 0x00000020u; +} +inline void AddressMapping::clear_has_match_network() { + _has_bits_[0] &= ~0x00000020u; +} +inline void AddressMapping::clear_match_network() { + if (match_network_ != &::google::protobuf::internal::kEmptyString) { + match_network_->clear(); + } + clear_has_match_network(); +} +inline const ::std::string& AddressMapping::match_network() const { + return *match_network_; +} +inline void AddressMapping::set_match_network(const ::std::string& value) { + set_has_match_network(); + if (match_network_ == &::google::protobuf::internal::kEmptyString) { + match_network_ = new ::std::string; + } + match_network_->assign(value); +} +inline void AddressMapping::set_match_network(const char* value) { + set_has_match_network(); + if (match_network_ == &::google::protobuf::internal::kEmptyString) { + match_network_ = new ::std::string; + } + match_network_->assign(value); +} +inline void AddressMapping::set_match_network(const char* value, size_t size) { + set_has_match_network(); + if (match_network_ == &::google::protobuf::internal::kEmptyString) { + match_network_ = new ::std::string; + } + match_network_->assign(reinterpret_cast(value), size); +} +inline ::std::string* AddressMapping::mutable_match_network() { + set_has_match_network(); + if (match_network_ == &::google::protobuf::internal::kEmptyString) { + match_network_ = new ::std::string; + } + return match_network_; +} +inline ::std::string* AddressMapping::release_match_network() { + clear_has_match_network(); + if (match_network_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = match_network_; + match_network_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void AddressMapping::set_allocated_match_network(::std::string* match_network) { + if (match_network_ != &::google::protobuf::internal::kEmptyString) { + delete match_network_; + } + if (match_network) { + set_has_match_network(); + match_network_ = match_network; + } else { + clear_has_match_network(); + match_network_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 ttl_s = 7; +inline bool AddressMapping::has_ttl_s() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void AddressMapping::set_has_ttl_s() { + _has_bits_[0] |= 0x00000040u; +} +inline void AddressMapping::clear_has_ttl_s() { + _has_bits_[0] &= ~0x00000040u; +} +inline void AddressMapping::clear_ttl_s() { + ttl_s_ = 0u; + clear_has_ttl_s(); +} +inline ::google::protobuf::uint32 AddressMapping::ttl_s() const { + return ttl_s_; +} +inline void AddressMapping::set_ttl_s(::google::protobuf::uint32 value) { + set_has_ttl_s(); + ttl_s_ = value; +} + +// required string uri = 8; +inline bool AddressMapping::has_uri() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void AddressMapping::set_has_uri() { + _has_bits_[0] |= 0x00000080u; +} +inline void AddressMapping::clear_has_uri() { + _has_bits_[0] &= ~0x00000080u; +} +inline void AddressMapping::clear_uri() { + if (uri_ != &::google::protobuf::internal::kEmptyString) { + uri_->clear(); + } + clear_has_uri(); +} +inline const ::std::string& AddressMapping::uri() const { + return *uri_; +} +inline void AddressMapping::set_uri(const ::std::string& value) { + set_has_uri(); + if (uri_ == &::google::protobuf::internal::kEmptyString) { + uri_ = new ::std::string; + } + uri_->assign(value); +} +inline void AddressMapping::set_uri(const char* value) { + set_has_uri(); + if (uri_ == &::google::protobuf::internal::kEmptyString) { + uri_ = new ::std::string; + } + uri_->assign(value); +} +inline void AddressMapping::set_uri(const char* value, size_t size) { + set_has_uri(); + if (uri_ == &::google::protobuf::internal::kEmptyString) { + uri_ = new ::std::string; + } + uri_->assign(reinterpret_cast(value), size); +} +inline ::std::string* AddressMapping::mutable_uri() { + set_has_uri(); + if (uri_ == &::google::protobuf::internal::kEmptyString) { + uri_ = new ::std::string; + } + return uri_; +} +inline ::std::string* AddressMapping::release_uri() { + clear_has_uri(); + if (uri_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = uri_; + uri_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void AddressMapping::set_allocated_uri(::std::string* uri) { + if (uri_ != &::google::protobuf::internal::kEmptyString) { + delete uri_; + } + if (uri) { + set_has_uri(); + uri_ = uri; + } else { + clear_has_uri(); + uri_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// AddressMappingSet + +// repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; +inline int AddressMappingSet::mappings_size() const { + return mappings_.size(); +} +inline void AddressMappingSet::clear_mappings() { + mappings_.Clear(); +} +inline const ::xtreemfs::pbrpc::AddressMapping& AddressMappingSet::mappings(int index) const { + return mappings_.Get(index); +} +inline ::xtreemfs::pbrpc::AddressMapping* AddressMappingSet::mutable_mappings(int index) { + return mappings_.Mutable(index); +} +inline ::xtreemfs::pbrpc::AddressMapping* AddressMappingSet::add_mappings() { + return mappings_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::AddressMapping >& +AddressMappingSet::mappings() const { + return mappings_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::AddressMapping >* +AddressMappingSet::mutable_mappings() { + return &mappings_; +} + +// ------------------------------------------------------------------- + +// DirService + +// required string address = 1; +inline bool DirService::has_address() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DirService::set_has_address() { + _has_bits_[0] |= 0x00000001u; +} +inline void DirService::clear_has_address() { + _has_bits_[0] &= ~0x00000001u; +} +inline void DirService::clear_address() { + if (address_ != &::google::protobuf::internal::kEmptyString) { + address_->clear(); + } + clear_has_address(); +} +inline const ::std::string& DirService::address() const { + return *address_; +} +inline void DirService::set_address(const ::std::string& value) { + set_has_address(); + if (address_ == &::google::protobuf::internal::kEmptyString) { + address_ = new ::std::string; + } + address_->assign(value); +} +inline void DirService::set_address(const char* value) { + set_has_address(); + if (address_ == &::google::protobuf::internal::kEmptyString) { + address_ = new ::std::string; + } + address_->assign(value); +} +inline void DirService::set_address(const char* value, size_t size) { + set_has_address(); + if (address_ == &::google::protobuf::internal::kEmptyString) { + address_ = new ::std::string; + } + address_->assign(reinterpret_cast(value), size); +} +inline ::std::string* DirService::mutable_address() { + set_has_address(); + if (address_ == &::google::protobuf::internal::kEmptyString) { + address_ = new ::std::string; + } + return address_; +} +inline ::std::string* DirService::release_address() { + clear_has_address(); + if (address_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = address_; + address_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void DirService::set_allocated_address(::std::string* address) { + if (address_ != &::google::protobuf::internal::kEmptyString) { + delete address_; + } + if (address) { + set_has_address(); + address_ = address; + } else { + clear_has_address(); + address_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 port = 2; +inline bool DirService::has_port() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void DirService::set_has_port() { + _has_bits_[0] |= 0x00000002u; +} +inline void DirService::clear_has_port() { + _has_bits_[0] &= ~0x00000002u; +} +inline void DirService::clear_port() { + port_ = 0u; + clear_has_port(); +} +inline ::google::protobuf::uint32 DirService::port() const { + return port_; +} +inline void DirService::set_port(::google::protobuf::uint32 value) { + set_has_port(); + port_ = value; +} + +// required string protocol = 3; +inline bool DirService::has_protocol() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void DirService::set_has_protocol() { + _has_bits_[0] |= 0x00000004u; +} +inline void DirService::clear_has_protocol() { + _has_bits_[0] &= ~0x00000004u; +} +inline void DirService::clear_protocol() { + if (protocol_ != &::google::protobuf::internal::kEmptyString) { + protocol_->clear(); + } + clear_has_protocol(); +} +inline const ::std::string& DirService::protocol() const { + return *protocol_; +} +inline void DirService::set_protocol(const ::std::string& value) { + set_has_protocol(); + if (protocol_ == &::google::protobuf::internal::kEmptyString) { + protocol_ = new ::std::string; + } + protocol_->assign(value); +} +inline void DirService::set_protocol(const char* value) { + set_has_protocol(); + if (protocol_ == &::google::protobuf::internal::kEmptyString) { + protocol_ = new ::std::string; + } + protocol_->assign(value); +} +inline void DirService::set_protocol(const char* value, size_t size) { + set_has_protocol(); + if (protocol_ == &::google::protobuf::internal::kEmptyString) { + protocol_ = new ::std::string; + } + protocol_->assign(reinterpret_cast(value), size); +} +inline ::std::string* DirService::mutable_protocol() { + set_has_protocol(); + if (protocol_ == &::google::protobuf::internal::kEmptyString) { + protocol_ = new ::std::string; + } + return protocol_; +} +inline ::std::string* DirService::release_protocol() { + clear_has_protocol(); + if (protocol_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = protocol_; + protocol_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void DirService::set_allocated_protocol(::std::string* protocol) { + if (protocol_ != &::google::protobuf::internal::kEmptyString) { + delete protocol_; + } + if (protocol) { + set_has_protocol(); + protocol_ = protocol; + } else { + clear_has_protocol(); + protocol_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 interface_version = 4; +inline bool DirService::has_interface_version() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void DirService::set_has_interface_version() { + _has_bits_[0] |= 0x00000008u; +} +inline void DirService::clear_has_interface_version() { + _has_bits_[0] &= ~0x00000008u; +} +inline void DirService::clear_interface_version() { + interface_version_ = 0u; + clear_has_interface_version(); +} +inline ::google::protobuf::uint32 DirService::interface_version() const { + return interface_version_; +} +inline void DirService::set_interface_version(::google::protobuf::uint32 value) { + set_has_interface_version(); + interface_version_ = value; +} + +// ------------------------------------------------------------------- + +// ServiceDataMap + +// repeated .xtreemfs.pbrpc.KeyValuePair data = 1; +inline int ServiceDataMap::data_size() const { + return data_.size(); +} +inline void ServiceDataMap::clear_data() { + data_.Clear(); +} +inline const ::xtreemfs::pbrpc::KeyValuePair& ServiceDataMap::data(int index) const { + return data_.Get(index); +} +inline ::xtreemfs::pbrpc::KeyValuePair* ServiceDataMap::mutable_data(int index) { + return data_.Mutable(index); +} +inline ::xtreemfs::pbrpc::KeyValuePair* ServiceDataMap::add_data() { + return data_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >& +ServiceDataMap::data() const { + return data_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >* +ServiceDataMap::mutable_data() { + return &data_; +} + +// ------------------------------------------------------------------- + +// Service + +// required .xtreemfs.pbrpc.ServiceType type = 1; +inline bool Service::has_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Service::set_has_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void Service::clear_has_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Service::clear_type() { + type_ = 0; + clear_has_type(); +} +inline ::xtreemfs::pbrpc::ServiceType Service::type() const { + return static_cast< ::xtreemfs::pbrpc::ServiceType >(type_); +} +inline void Service::set_type(::xtreemfs::pbrpc::ServiceType value) { + assert(::xtreemfs::pbrpc::ServiceType_IsValid(value)); + set_has_type(); + type_ = value; +} + +// required string uuid = 2; +inline bool Service::has_uuid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Service::set_has_uuid() { + _has_bits_[0] |= 0x00000002u; +} +inline void Service::clear_has_uuid() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Service::clear_uuid() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + clear_has_uuid(); +} +inline const ::std::string& Service::uuid() const { + return *uuid_; +} +inline void Service::set_uuid(const ::std::string& value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void Service::set_uuid(const char* value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void Service::set_uuid(const char* value, size_t size) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Service::mutable_uuid() { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + return uuid_; +} +inline ::std::string* Service::release_uuid() { + clear_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = uuid_; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void Service::set_allocated_uuid(::std::string* uuid) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (uuid) { + set_has_uuid(); + uuid_ = uuid; + } else { + clear_has_uuid(); + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 version = 3; +inline bool Service::has_version() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Service::set_has_version() { + _has_bits_[0] |= 0x00000004u; +} +inline void Service::clear_has_version() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Service::clear_version() { + version_ = GOOGLE_ULONGLONG(0); + clear_has_version(); +} +inline ::google::protobuf::uint64 Service::version() const { + return version_; +} +inline void Service::set_version(::google::protobuf::uint64 value) { + set_has_version(); + version_ = value; +} + +// required string name = 4; +inline bool Service::has_name() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void Service::set_has_name() { + _has_bits_[0] |= 0x00000008u; +} +inline void Service::clear_has_name() { + _has_bits_[0] &= ~0x00000008u; +} +inline void Service::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& Service::name() const { + return *name_; +} +inline void Service::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void Service::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void Service::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Service::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* Service::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void Service::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 last_updated_s = 5; +inline bool Service::has_last_updated_s() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void Service::set_has_last_updated_s() { + _has_bits_[0] |= 0x00000010u; +} +inline void Service::clear_has_last_updated_s() { + _has_bits_[0] &= ~0x00000010u; +} +inline void Service::clear_last_updated_s() { + last_updated_s_ = GOOGLE_ULONGLONG(0); + clear_has_last_updated_s(); +} +inline ::google::protobuf::uint64 Service::last_updated_s() const { + return last_updated_s_; +} +inline void Service::set_last_updated_s(::google::protobuf::uint64 value) { + set_has_last_updated_s(); + last_updated_s_ = value; +} + +// required .xtreemfs.pbrpc.ServiceDataMap data = 6; +inline bool Service::has_data() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void Service::set_has_data() { + _has_bits_[0] |= 0x00000020u; +} +inline void Service::clear_has_data() { + _has_bits_[0] &= ~0x00000020u; +} +inline void Service::clear_data() { + if (data_ != NULL) data_->::xtreemfs::pbrpc::ServiceDataMap::Clear(); + clear_has_data(); +} +inline const ::xtreemfs::pbrpc::ServiceDataMap& Service::data() const { + return data_ != NULL ? *data_ : *default_instance_->data_; +} +inline ::xtreemfs::pbrpc::ServiceDataMap* Service::mutable_data() { + set_has_data(); + if (data_ == NULL) data_ = new ::xtreemfs::pbrpc::ServiceDataMap; + return data_; +} +inline ::xtreemfs::pbrpc::ServiceDataMap* Service::release_data() { + clear_has_data(); + ::xtreemfs::pbrpc::ServiceDataMap* temp = data_; + data_ = NULL; + return temp; +} +inline void Service::set_allocated_data(::xtreemfs::pbrpc::ServiceDataMap* data) { + delete data_; + data_ = data; + if (data) { + set_has_data(); + } else { + clear_has_data(); + } +} + +// ------------------------------------------------------------------- + +// ServiceSet + +// repeated .xtreemfs.pbrpc.Service services = 1; +inline int ServiceSet::services_size() const { + return services_.size(); +} +inline void ServiceSet::clear_services() { + services_.Clear(); +} +inline const ::xtreemfs::pbrpc::Service& ServiceSet::services(int index) const { + return services_.Get(index); +} +inline ::xtreemfs::pbrpc::Service* ServiceSet::mutable_services(int index) { + return services_.Mutable(index); +} +inline ::xtreemfs::pbrpc::Service* ServiceSet::add_services() { + return services_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Service >& +ServiceSet::services() const { + return services_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Service >* +ServiceSet::mutable_services() { + return &services_; +} + +// ------------------------------------------------------------------- + +// Configuration + +// required string uuid = 1; +inline bool Configuration::has_uuid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Configuration::set_has_uuid() { + _has_bits_[0] |= 0x00000001u; +} +inline void Configuration::clear_has_uuid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Configuration::clear_uuid() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + clear_has_uuid(); +} +inline const ::std::string& Configuration::uuid() const { + return *uuid_; +} +inline void Configuration::set_uuid(const ::std::string& value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void Configuration::set_uuid(const char* value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void Configuration::set_uuid(const char* value, size_t size) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Configuration::mutable_uuid() { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + return uuid_; +} +inline ::std::string* Configuration::release_uuid() { + clear_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = uuid_; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void Configuration::set_allocated_uuid(::std::string* uuid) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (uuid) { + set_has_uuid(); + uuid_ = uuid; + } else { + clear_has_uuid(); + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; +inline int Configuration::parameter_size() const { + return parameter_.size(); +} +inline void Configuration::clear_parameter() { + parameter_.Clear(); +} +inline const ::xtreemfs::pbrpc::KeyValuePair& Configuration::parameter(int index) const { + return parameter_.Get(index); +} +inline ::xtreemfs::pbrpc::KeyValuePair* Configuration::mutable_parameter(int index) { + return parameter_.Mutable(index); +} +inline ::xtreemfs::pbrpc::KeyValuePair* Configuration::add_parameter() { + return parameter_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >& +Configuration::parameter() const { + return parameter_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >* +Configuration::mutable_parameter() { + return ¶meter_; +} + +// required fixed64 version = 3; +inline bool Configuration::has_version() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Configuration::set_has_version() { + _has_bits_[0] |= 0x00000004u; +} +inline void Configuration::clear_has_version() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Configuration::clear_version() { + version_ = GOOGLE_ULONGLONG(0); + clear_has_version(); +} +inline ::google::protobuf::uint64 Configuration::version() const { + return version_; +} +inline void Configuration::set_version(::google::protobuf::uint64 value) { + set_has_version(); + version_ = value; +} + +// ------------------------------------------------------------------- + +// addressMappingGetRequest + +// required string uuid = 1; +inline bool addressMappingGetRequest::has_uuid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void addressMappingGetRequest::set_has_uuid() { + _has_bits_[0] |= 0x00000001u; +} +inline void addressMappingGetRequest::clear_has_uuid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void addressMappingGetRequest::clear_uuid() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + clear_has_uuid(); +} +inline const ::std::string& addressMappingGetRequest::uuid() const { + return *uuid_; +} +inline void addressMappingGetRequest::set_uuid(const ::std::string& value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void addressMappingGetRequest::set_uuid(const char* value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void addressMappingGetRequest::set_uuid(const char* value, size_t size) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* addressMappingGetRequest::mutable_uuid() { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + return uuid_; +} +inline ::std::string* addressMappingGetRequest::release_uuid() { + clear_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = uuid_; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void addressMappingGetRequest::set_allocated_uuid(::std::string* uuid) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (uuid) { + set_has_uuid(); + uuid_ = uuid; + } else { + clear_has_uuid(); + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// addressMappingGetResponse + +// optional .xtreemfs.pbrpc.AddressMappingSet result = 1; +inline bool addressMappingGetResponse::has_result() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void addressMappingGetResponse::set_has_result() { + _has_bits_[0] |= 0x00000001u; +} +inline void addressMappingGetResponse::clear_has_result() { + _has_bits_[0] &= ~0x00000001u; +} +inline void addressMappingGetResponse::clear_result() { + if (result_ != NULL) result_->::xtreemfs::pbrpc::AddressMappingSet::Clear(); + clear_has_result(); +} +inline const ::xtreemfs::pbrpc::AddressMappingSet& addressMappingGetResponse::result() const { + return result_ != NULL ? *result_ : *default_instance_->result_; +} +inline ::xtreemfs::pbrpc::AddressMappingSet* addressMappingGetResponse::mutable_result() { + set_has_result(); + if (result_ == NULL) result_ = new ::xtreemfs::pbrpc::AddressMappingSet; + return result_; +} +inline ::xtreemfs::pbrpc::AddressMappingSet* addressMappingGetResponse::release_result() { + clear_has_result(); + ::xtreemfs::pbrpc::AddressMappingSet* temp = result_; + result_ = NULL; + return temp; +} +inline void addressMappingGetResponse::set_allocated_result(::xtreemfs::pbrpc::AddressMappingSet* result) { + delete result_; + result_ = result; + if (result) { + set_has_result(); + } else { + clear_has_result(); + } +} + +// ------------------------------------------------------------------- + +// addressMappingSetResponse + +// optional fixed64 new_version = 1; +inline bool addressMappingSetResponse::has_new_version() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void addressMappingSetResponse::set_has_new_version() { + _has_bits_[0] |= 0x00000001u; +} +inline void addressMappingSetResponse::clear_has_new_version() { + _has_bits_[0] &= ~0x00000001u; +} +inline void addressMappingSetResponse::clear_new_version() { + new_version_ = GOOGLE_ULONGLONG(0); + clear_has_new_version(); +} +inline ::google::protobuf::uint64 addressMappingSetResponse::new_version() const { + return new_version_; +} +inline void addressMappingSetResponse::set_new_version(::google::protobuf::uint64 value) { + set_has_new_version(); + new_version_ = value; +} + +// ------------------------------------------------------------------- + +// globalTimeSGetResponse + +// required fixed64 time_in_seconds = 1; +inline bool globalTimeSGetResponse::has_time_in_seconds() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void globalTimeSGetResponse::set_has_time_in_seconds() { + _has_bits_[0] |= 0x00000001u; +} +inline void globalTimeSGetResponse::clear_has_time_in_seconds() { + _has_bits_[0] &= ~0x00000001u; +} +inline void globalTimeSGetResponse::clear_time_in_seconds() { + time_in_seconds_ = GOOGLE_ULONGLONG(0); + clear_has_time_in_seconds(); +} +inline ::google::protobuf::uint64 globalTimeSGetResponse::time_in_seconds() const { + return time_in_seconds_; +} +inline void globalTimeSGetResponse::set_time_in_seconds(::google::protobuf::uint64 value) { + set_has_time_in_seconds(); + time_in_seconds_ = value; +} + +// ------------------------------------------------------------------- + +// serviceDeregisterRequest + +// required string uuid = 1; +inline bool serviceDeregisterRequest::has_uuid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void serviceDeregisterRequest::set_has_uuid() { + _has_bits_[0] |= 0x00000001u; +} +inline void serviceDeregisterRequest::clear_has_uuid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void serviceDeregisterRequest::clear_uuid() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + clear_has_uuid(); +} +inline const ::std::string& serviceDeregisterRequest::uuid() const { + return *uuid_; +} +inline void serviceDeregisterRequest::set_uuid(const ::std::string& value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void serviceDeregisterRequest::set_uuid(const char* value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void serviceDeregisterRequest::set_uuid(const char* value, size_t size) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* serviceDeregisterRequest::mutable_uuid() { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + return uuid_; +} +inline ::std::string* serviceDeregisterRequest::release_uuid() { + clear_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = uuid_; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void serviceDeregisterRequest::set_allocated_uuid(::std::string* uuid) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (uuid) { + set_has_uuid(); + uuid_ = uuid; + } else { + clear_has_uuid(); + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// serviceGetByNameRequest + +// required string name = 1; +inline bool serviceGetByNameRequest::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void serviceGetByNameRequest::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void serviceGetByNameRequest::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void serviceGetByNameRequest::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& serviceGetByNameRequest::name() const { + return *name_; +} +inline void serviceGetByNameRequest::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void serviceGetByNameRequest::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void serviceGetByNameRequest::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* serviceGetByNameRequest::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* serviceGetByNameRequest::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void serviceGetByNameRequest::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// serviceGetByUUIDRequest + +// required string name = 1; +inline bool serviceGetByUUIDRequest::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void serviceGetByUUIDRequest::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void serviceGetByUUIDRequest::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void serviceGetByUUIDRequest::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& serviceGetByUUIDRequest::name() const { + return *name_; +} +inline void serviceGetByUUIDRequest::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void serviceGetByUUIDRequest::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void serviceGetByUUIDRequest::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* serviceGetByUUIDRequest::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* serviceGetByUUIDRequest::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void serviceGetByUUIDRequest::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// serviceGetByTypeRequest + +// required .xtreemfs.pbrpc.ServiceType type = 1; +inline bool serviceGetByTypeRequest::has_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void serviceGetByTypeRequest::set_has_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void serviceGetByTypeRequest::clear_has_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void serviceGetByTypeRequest::clear_type() { + type_ = 0; + clear_has_type(); +} +inline ::xtreemfs::pbrpc::ServiceType serviceGetByTypeRequest::type() const { + return static_cast< ::xtreemfs::pbrpc::ServiceType >(type_); +} +inline void serviceGetByTypeRequest::set_type(::xtreemfs::pbrpc::ServiceType value) { + assert(::xtreemfs::pbrpc::ServiceType_IsValid(value)); + set_has_type(); + type_ = value; +} + +// ------------------------------------------------------------------- + +// serviceRegisterRequest + +// required .xtreemfs.pbrpc.Service service = 1; +inline bool serviceRegisterRequest::has_service() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void serviceRegisterRequest::set_has_service() { + _has_bits_[0] |= 0x00000001u; +} +inline void serviceRegisterRequest::clear_has_service() { + _has_bits_[0] &= ~0x00000001u; +} +inline void serviceRegisterRequest::clear_service() { + if (service_ != NULL) service_->::xtreemfs::pbrpc::Service::Clear(); + clear_has_service(); +} +inline const ::xtreemfs::pbrpc::Service& serviceRegisterRequest::service() const { + return service_ != NULL ? *service_ : *default_instance_->service_; +} +inline ::xtreemfs::pbrpc::Service* serviceRegisterRequest::mutable_service() { + set_has_service(); + if (service_ == NULL) service_ = new ::xtreemfs::pbrpc::Service; + return service_; +} +inline ::xtreemfs::pbrpc::Service* serviceRegisterRequest::release_service() { + clear_has_service(); + ::xtreemfs::pbrpc::Service* temp = service_; + service_ = NULL; + return temp; +} +inline void serviceRegisterRequest::set_allocated_service(::xtreemfs::pbrpc::Service* service) { + delete service_; + service_ = service; + if (service) { + set_has_service(); + } else { + clear_has_service(); + } +} + +// ------------------------------------------------------------------- + +// serviceRegisterResponse + +// required fixed64 new_version = 1; +inline bool serviceRegisterResponse::has_new_version() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void serviceRegisterResponse::set_has_new_version() { + _has_bits_[0] |= 0x00000001u; +} +inline void serviceRegisterResponse::clear_has_new_version() { + _has_bits_[0] &= ~0x00000001u; +} +inline void serviceRegisterResponse::clear_new_version() { + new_version_ = GOOGLE_ULONGLONG(0); + clear_has_new_version(); +} +inline ::google::protobuf::uint64 serviceRegisterResponse::new_version() const { + return new_version_; +} +inline void serviceRegisterResponse::set_new_version(::google::protobuf::uint64 value) { + set_has_new_version(); + new_version_ = value; +} + +// ------------------------------------------------------------------- + +// configurationGetRequest + +// required string uuid = 1; +inline bool configurationGetRequest::has_uuid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void configurationGetRequest::set_has_uuid() { + _has_bits_[0] |= 0x00000001u; +} +inline void configurationGetRequest::clear_has_uuid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void configurationGetRequest::clear_uuid() { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + uuid_->clear(); + } + clear_has_uuid(); +} +inline const ::std::string& configurationGetRequest::uuid() const { + return *uuid_; +} +inline void configurationGetRequest::set_uuid(const ::std::string& value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void configurationGetRequest::set_uuid(const char* value) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(value); +} +inline void configurationGetRequest::set_uuid(const char* value, size_t size) { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + uuid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* configurationGetRequest::mutable_uuid() { + set_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + uuid_ = new ::std::string; + } + return uuid_; +} +inline ::std::string* configurationGetRequest::release_uuid() { + clear_has_uuid(); + if (uuid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = uuid_; + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void configurationGetRequest::set_allocated_uuid(::std::string* uuid) { + if (uuid_ != &::google::protobuf::internal::kEmptyString) { + delete uuid_; + } + if (uuid) { + set_has_uuid(); + uuid_ = uuid; + } else { + clear_has_uuid(); + uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// configurationSetResponse + +// optional fixed64 new_version = 1; +inline bool configurationSetResponse::has_new_version() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void configurationSetResponse::set_has_new_version() { + _has_bits_[0] |= 0x00000001u; +} +inline void configurationSetResponse::clear_has_new_version() { + _has_bits_[0] &= ~0x00000001u; +} +inline void configurationSetResponse::clear_new_version() { + new_version_ = GOOGLE_ULONGLONG(0); + clear_has_new_version(); +} +inline ::google::protobuf::uint64 configurationSetResponse::new_version() const { + return new_version_; +} +inline void configurationSetResponse::set_new_version(::google::protobuf::uint64 value) { + set_has_new_version(); + new_version_ = value; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::ServiceType>() { + return ::xtreemfs::pbrpc::ServiceType_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::ServiceStatus>() { + return ::xtreemfs::pbrpc::ServiceStatus_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_xtreemfs_2fDIR_2eproto__INCLUDED diff --git a/cpp/generated/xtreemfs/DIRServiceClient.h b/cpp/generated/xtreemfs/DIRServiceClient.h new file mode 100644 index 0000000..25f5878 --- /dev/null +++ b/cpp/generated/xtreemfs/DIRServiceClient.h @@ -0,0 +1,405 @@ +//automatically generated from DIR.proto at Thu Dec 11 16:09:40 CET 2014 +//(c) 2014. See LICENSE file for details. + +#ifndef DIRSERVICECLIENT_H +#define DIRSERVICECLIENT_H + +#include +#include "pbrpc/RPC.pb.h" +#include "rpc/client.h" +#include "rpc/sync_callback.h" +#include "rpc/callback_interface.h" +#include "include/Common.pb.h" +#include "xtreemfs/GlobalTypes.pb.h" +#include "xtreemfs/DIR.pb.h" + + +namespace xtreemfs { +namespace pbrpc { + using ::xtreemfs::rpc::Client; + using ::xtreemfs::rpc::CallbackInterface; + using ::xtreemfs::rpc::SyncCallback; + + class DIRServiceClient { + + public: + DIRServiceClient(Client* client) : client_(client) { + } + + virtual ~DIRServiceClient() { + } + + void xtreemfs_address_mappings_get(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::addressMappingGetRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 1, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::AddressMappingSet(), + context, callback); + } + + SyncCallback* xtreemfs_address_mappings_get_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::addressMappingGetRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 1, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::AddressMappingSet(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_address_mappings_remove(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::addressMappingGetRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 2, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_address_mappings_remove_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::addressMappingGetRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 2, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_address_mappings_set(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::AddressMappingSet* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 3, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::addressMappingSetResponse(), + context, callback); + } + + SyncCallback* xtreemfs_address_mappings_set_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::AddressMappingSet* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 3, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::addressMappingSetResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_discover_dir(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 10001, 4, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::DirService(), + context, callback); + } + + SyncCallback* xtreemfs_discover_dir_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 4, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::DirService(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_global_time_s_get(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 10001, 5, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::globalTimeSGetResponse(), + context, callback); + } + + SyncCallback* xtreemfs_global_time_s_get_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 5, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::globalTimeSGetResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_service_deregister(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::serviceDeregisterRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 6, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_service_deregister_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::serviceDeregisterRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 6, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_service_get_by_name(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::serviceGetByNameRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 7, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ServiceSet(), + context, callback); + } + + SyncCallback* xtreemfs_service_get_by_name_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::serviceGetByNameRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 7, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ServiceSet(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_service_get_by_type(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::serviceGetByTypeRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 8, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ServiceSet(), + context, callback); + } + + SyncCallback* xtreemfs_service_get_by_type_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::serviceGetByTypeRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 8, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ServiceSet(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_service_get_by_uuid(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::serviceGetByUUIDRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 9, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ServiceSet(), + context, callback); + } + + SyncCallback* xtreemfs_service_get_by_uuid_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::serviceGetByUUIDRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 9, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ServiceSet(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_service_offline(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::serviceGetByUUIDRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 10, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_service_offline_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::serviceGetByUUIDRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 10, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_service_register(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::serviceRegisterRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 11, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::serviceRegisterResponse(), + context, callback); + } + + SyncCallback* xtreemfs_service_register_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::serviceRegisterRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 11, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::serviceRegisterResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_checkpoint(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 10001, 20, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_checkpoint_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 20, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_shutdown(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 10001, 21, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_shutdown_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 21, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_configuration_get(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::configurationGetRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 22, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::Configuration(), + context, callback); + } + + SyncCallback* xtreemfs_configuration_get_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::configurationGetRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 22, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::Configuration(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_configuration_set(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::Configuration* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 23, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::configurationSetResponse(), + context, callback); + } + + SyncCallback* xtreemfs_configuration_set_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::Configuration* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 23, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::configurationSetResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_vivaldi_client_update(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::VivaldiCoordinates* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 10001, 24, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_vivaldi_client_update_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::VivaldiCoordinates* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 10001, 24, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + private: + Client* client_; + }; + } +} +#endif //DIRSERVICECLIENT_H diff --git a/cpp/generated/xtreemfs/DIRServiceConstants.h b/cpp/generated/xtreemfs/DIRServiceConstants.h new file mode 100644 index 0000000..6446ed0 --- /dev/null +++ b/cpp/generated/xtreemfs/DIRServiceConstants.h @@ -0,0 +1,32 @@ +//automatically generated from DIR.proto at Thu Dec 11 16:09:40 CET 2014 +//(c) 2014. See LICENSE file for details. + +#ifndef DIRSERVICECONSTANTS_H_ +#define DIRSERVICECONSTANTS_H_ +#include + +namespace xtreemfs { +namespace pbrpc { + +const uint32_t INTERFACE_ID_DIR = 10001; +const uint32_t PROC_ID_XTREEMFS_ADDRESS_MAPPINGS_GET = 1; +const uint32_t PROC_ID_XTREEMFS_ADDRESS_MAPPINGS_REMOVE = 2; +const uint32_t PROC_ID_XTREEMFS_ADDRESS_MAPPINGS_SET = 3; +const uint32_t PROC_ID_XTREEMFS_DISCOVER_DIR = 4; +const uint32_t PROC_ID_XTREEMFS_GLOBAL_TIME_S_GET = 5; +const uint32_t PROC_ID_XTREEMFS_SERVICE_DEREGISTER = 6; +const uint32_t PROC_ID_XTREEMFS_SERVICE_GET_BY_NAME = 7; +const uint32_t PROC_ID_XTREEMFS_SERVICE_GET_BY_TYPE = 8; +const uint32_t PROC_ID_XTREEMFS_SERVICE_GET_BY_UUID = 9; +const uint32_t PROC_ID_XTREEMFS_SERVICE_OFFLINE = 10; +const uint32_t PROC_ID_XTREEMFS_SERVICE_REGISTER = 11; +const uint32_t PROC_ID_XTREEMFS_CHECKPOINT = 20; +const uint32_t PROC_ID_XTREEMFS_SHUTDOWN = 21; +const uint32_t PROC_ID_XTREEMFS_CONFIGURATION_GET = 22; +const uint32_t PROC_ID_XTREEMFS_CONFIGURATION_SET = 23; +const uint32_t PROC_ID_XTREEMFS_VIVALDI_CLIENT_UPDATE = 24; + +} // namespace pbrpc +} // namespace xtreemfs + +#endif // DIRSERVICECLIENT_H_ diff --git a/cpp/generated/xtreemfs/GlobalTypes.pb.cc b/cpp/generated/xtreemfs/GlobalTypes.pb.cc new file mode 100644 index 0000000..cc96212 --- /dev/null +++ b/cpp/generated/xtreemfs/GlobalTypes.pb.cc @@ -0,0 +1,3991 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/GlobalTypes.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "xtreemfs/GlobalTypes.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +namespace { + +const ::google::protobuf::Descriptor* NewFileSize_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + NewFileSize_reflection_ = NULL; +const ::google::protobuf::Descriptor* StripingPolicy_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + StripingPolicy_reflection_ = NULL; +const ::google::protobuf::Descriptor* Replica_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Replica_reflection_ = NULL; +const ::google::protobuf::Descriptor* Replicas_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Replicas_reflection_ = NULL; +const ::google::protobuf::Descriptor* XCap_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + XCap_reflection_ = NULL; +const ::google::protobuf::Descriptor* XLocSet_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + XLocSet_reflection_ = NULL; +const ::google::protobuf::Descriptor* FileCredentials_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FileCredentials_reflection_ = NULL; +const ::google::protobuf::Descriptor* FileCredentialsSet_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FileCredentialsSet_reflection_ = NULL; +const ::google::protobuf::Descriptor* VivaldiCoordinates_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + VivaldiCoordinates_reflection_ = NULL; +const ::google::protobuf::Descriptor* OSDWriteResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + OSDWriteResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* KeyValuePair_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + KeyValuePair_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* AccessControlPolicyType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* OSDSelectionPolicyType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ReplicaSelectionPolicyType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* SnapConfig_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* StripingPolicyType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* LeaseState_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* PORTS_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* CONSTANTS_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* SYSTEM_V_FCNTL_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* REPL_FLAG_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* SERVICES_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto() { + protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "xtreemfs/GlobalTypes.proto"); + GOOGLE_CHECK(file != NULL); + NewFileSize_descriptor_ = file->message_type(0); + static const int NewFileSize_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(NewFileSize, size_in_bytes_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(NewFileSize, truncate_epoch_), + }; + NewFileSize_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + NewFileSize_descriptor_, + NewFileSize::default_instance_, + NewFileSize_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(NewFileSize, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(NewFileSize, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(NewFileSize)); + StripingPolicy_descriptor_ = file->message_type(1); + static const int StripingPolicy_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StripingPolicy, type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StripingPolicy, stripe_size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StripingPolicy, width_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StripingPolicy, parity_width_), + }; + StripingPolicy_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + StripingPolicy_descriptor_, + StripingPolicy::default_instance_, + StripingPolicy_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StripingPolicy, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StripingPolicy, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(StripingPolicy)); + Replica_descriptor_ = file->message_type(2); + static const int Replica_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Replica, osd_uuids_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Replica, replication_flags_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Replica, striping_policy_), + }; + Replica_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Replica_descriptor_, + Replica::default_instance_, + Replica_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Replica, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Replica, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Replica)); + Replicas_descriptor_ = file->message_type(3); + static const int Replicas_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Replicas, replicas_), + }; + Replicas_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Replicas_descriptor_, + Replicas::default_instance_, + Replicas_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Replicas, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Replicas, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Replicas)); + XCap_descriptor_ = file->message_type(4); + static const int XCap_offsets_[10] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, access_mode_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, client_identity_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, expire_time_s_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, expire_timeout_s_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, replicate_on_close_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, server_signature_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, truncate_epoch_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, snap_config_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, snap_timestamp_), + }; + XCap_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + XCap_descriptor_, + XCap::default_instance_, + XCap_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XCap, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(XCap)); + XLocSet_descriptor_ = file->message_type(5); + static const int XLocSet_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XLocSet, read_only_file_size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XLocSet, replicas_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XLocSet, replica_update_policy_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XLocSet, version_), + }; + XLocSet_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + XLocSet_descriptor_, + XLocSet::default_instance_, + XLocSet_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XLocSet, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XLocSet, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(XLocSet)); + FileCredentials_descriptor_ = file->message_type(6); + static const int FileCredentials_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileCredentials, xcap_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileCredentials, xlocs_), + }; + FileCredentials_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FileCredentials_descriptor_, + FileCredentials::default_instance_, + FileCredentials_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileCredentials, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileCredentials, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FileCredentials)); + FileCredentialsSet_descriptor_ = file->message_type(7); + static const int FileCredentialsSet_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileCredentialsSet, file_credentials_), + }; + FileCredentialsSet_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FileCredentialsSet_descriptor_, + FileCredentialsSet::default_instance_, + FileCredentialsSet_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileCredentialsSet, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileCredentialsSet, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FileCredentialsSet)); + VivaldiCoordinates_descriptor_ = file->message_type(8); + static const int VivaldiCoordinates_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(VivaldiCoordinates, x_coordinate_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(VivaldiCoordinates, y_coordinate_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(VivaldiCoordinates, local_error_), + }; + VivaldiCoordinates_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + VivaldiCoordinates_descriptor_, + VivaldiCoordinates::default_instance_, + VivaldiCoordinates_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(VivaldiCoordinates, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(VivaldiCoordinates, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(VivaldiCoordinates)); + OSDWriteResponse_descriptor_ = file->message_type(9); + static const int OSDWriteResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OSDWriteResponse, size_in_bytes_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OSDWriteResponse, truncate_epoch_), + }; + OSDWriteResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + OSDWriteResponse_descriptor_, + OSDWriteResponse::default_instance_, + OSDWriteResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OSDWriteResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OSDWriteResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(OSDWriteResponse)); + KeyValuePair_descriptor_ = file->message_type(10); + static const int KeyValuePair_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KeyValuePair, key_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KeyValuePair, value_), + }; + KeyValuePair_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + KeyValuePair_descriptor_, + KeyValuePair::default_instance_, + KeyValuePair_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KeyValuePair, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KeyValuePair, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(KeyValuePair)); + AccessControlPolicyType_descriptor_ = file->enum_type(0); + OSDSelectionPolicyType_descriptor_ = file->enum_type(1); + ReplicaSelectionPolicyType_descriptor_ = file->enum_type(2); + SnapConfig_descriptor_ = file->enum_type(3); + StripingPolicyType_descriptor_ = file->enum_type(4); + LeaseState_descriptor_ = file->enum_type(5); + PORTS_descriptor_ = file->enum_type(6); + CONSTANTS_descriptor_ = file->enum_type(7); + SYSTEM_V_FCNTL_descriptor_ = file->enum_type(8); + REPL_FLAG_descriptor_ = file->enum_type(9); + SERVICES_descriptor_ = file->enum_type(10); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + NewFileSize_descriptor_, &NewFileSize::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + StripingPolicy_descriptor_, &StripingPolicy::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Replica_descriptor_, &Replica::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Replicas_descriptor_, &Replicas::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + XCap_descriptor_, &XCap::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + XLocSet_descriptor_, &XLocSet::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FileCredentials_descriptor_, &FileCredentials::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FileCredentialsSet_descriptor_, &FileCredentialsSet::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + VivaldiCoordinates_descriptor_, &VivaldiCoordinates::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + OSDWriteResponse_descriptor_, &OSDWriteResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + KeyValuePair_descriptor_, &KeyValuePair::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto() { + delete NewFileSize::default_instance_; + delete NewFileSize_reflection_; + delete StripingPolicy::default_instance_; + delete StripingPolicy_reflection_; + delete Replica::default_instance_; + delete Replica_reflection_; + delete Replicas::default_instance_; + delete Replicas_reflection_; + delete XCap::default_instance_; + delete XCap_reflection_; + delete XLocSet::default_instance_; + delete XLocSet_reflection_; + delete FileCredentials::default_instance_; + delete FileCredentials_reflection_; + delete FileCredentialsSet::default_instance_; + delete FileCredentialsSet_reflection_; + delete VivaldiCoordinates::default_instance_; + delete VivaldiCoordinates_reflection_; + delete OSDWriteResponse::default_instance_; + delete OSDWriteResponse_reflection_; + delete KeyValuePair::default_instance_; + delete KeyValuePair_reflection_; +} + +void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::xtreemfs::pbrpc::protobuf_AddDesc_include_2fPBRPC_2eproto(); + ::xtreemfs::pbrpc::protobuf_AddDesc_include_2fCommon_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\032xtreemfs/GlobalTypes.proto\022\016xtreemfs.p" + "brpc\032\023include/PBRPC.proto\032\024include/Commo" + "n.proto\"<\n\013NewFileSize\022\025\n\rsize_in_bytes\030" + "\001 \002(\006\022\026\n\016truncate_epoch\030\002 \002(\007\"|\n\016Stripin" + "gPolicy\0220\n\004type\030\001 \002(\0162\".xtreemfs.pbrpc.S" + "tripingPolicyType\022\023\n\013stripe_size\030\002 \002(\007\022\r" + "\n\005width\030\003 \002(\007\022\024\n\014parity_width\030\004 \001(\007\"p\n\007R" + "eplica\022\021\n\tosd_uuids\030\001 \003(\t\022\031\n\021replication" + "_flags\030\002 \002(\007\0227\n\017striping_policy\030\003 \002(\0132\036." + "xtreemfs.pbrpc.StripingPolicy\"5\n\010Replica" + "s\022)\n\010replicas\030\001 \003(\0132\027.xtreemfs.pbrpc.Rep" + "lica\"\215\002\n\004XCap\022\023\n\013access_mode\030\001 \002(\007\022\027\n\017cl" + "ient_identity\030\002 \002(\t\022\025\n\rexpire_time_s\030\003 \002" + "(\006\022\030\n\020expire_timeout_s\030\004 \002(\007\022\017\n\007file_id\030" + "\005 \002(\t\022\032\n\022replicate_on_close\030\006 \002(\010\022\030\n\020ser" + "ver_signature\030\007 \002(\t\022\026\n\016truncate_epoch\030\010 " + "\002(\007\022/\n\013snap_config\030\t \002(\0162\032.xtreemfs.pbrp" + "c.SnapConfig\022\026\n\016snap_timestamp\030\n \002(\006\"\201\001\n" + "\007XLocSet\022\033\n\023read_only_file_size\030\001 \002(\006\022)\n" + "\010replicas\030\002 \003(\0132\027.xtreemfs.pbrpc.Replica" + "\022\035\n\025replica_update_policy\030\003 \002(\t\022\017\n\007versi" + "on\030\004 \002(\007\"]\n\017FileCredentials\022\"\n\004xcap\030\001 \002(" + "\0132\024.xtreemfs.pbrpc.XCap\022&\n\005xlocs\030\002 \002(\0132\027" + ".xtreemfs.pbrpc.XLocSet\"O\n\022FileCredentia" + "lsSet\0229\n\020file_credentials\030\001 \001(\0132\037.xtreem" + "fs.pbrpc.FileCredentials\"U\n\022VivaldiCoord" + "inates\022\024\n\014x_coordinate\030\001 \002(\001\022\024\n\014y_coordi" + "nate\030\002 \002(\001\022\023\n\013local_error\030\003 \002(\001\"A\n\020OSDWr" + "iteResponse\022\025\n\rsize_in_bytes\030\001 \001(\006\022\026\n\016tr" + "uncate_epoch\030\002 \001(\007\"*\n\014KeyValuePair\022\013\n\003ke" + "y\030\001 \002(\t\022\r\n\005value\030\002 \002(\t*|\n\027AccessControlP" + "olicyType\022\036\n\032ACCESS_CONTROL_POLICY_NULL\020" + "\001\022\037\n\033ACCESS_CONTROL_POLICY_POSIX\020\002\022 \n\034AC" + "CESS_CONTROL_POLICY_VOLUME\020\003*\365\003\n\026OSDSele" + "ctionPolicyType\022(\n#OSD_SELECTION_POLICY_" + "FILTER_DEFAULT\020\350\007\022%\n OSD_SELECTION_POLIC" + "Y_FILTER_FQDN\020\351\007\022%\n OSD_SELECTION_POLICY" + "_FILTER_UUID\020\352\007\022%\n OSD_SELECTION_POLICY_" + "GROUP_DCMAP\020\320\017\022$\n\037OSD_SELECTION_POLICY_G" + "ROUP_FQDN\020\321\017\022$\n\037OSD_SELECTION_POLICY_SOR" + "T_DCMAP\020\270\027\022#\n\036OSD_SELECTION_POLICY_SORT_" + "FQDN\020\271\027\022%\n OSD_SELECTION_POLICY_SORT_RAN" + "DOM\020\272\027\022&\n!OSD_SELECTION_POLICY_SORT_VIVA" + "LDI\020\273\027\022/\n*OSD_SELECTION_POLICY_SORT_HOST" + "_ROUND_ROBIN\020\274\027\022#\n\036OSD_SELECTION_POLICY_" + "SORT_UUID\020\236\037\022&\n!OSD_SELECTION_POLICY_SOR" + "T_REVERSE\020\237\037*A\n\032ReplicaSelectionPolicyTy" + "pe\022#\n\037REPLICA_SELECTION_POLICY_SIMPLE\020\001*" + "i\n\nSnapConfig\022\036\n\032SNAP_CONFIG_SNAPS_DISAB" + "LED\020\000\022\036\n\032SNAP_CONFIG_ACCESS_CURRENT\020\001\022\033\n" + "\027SNAP_CONFIG_ACCESS_SNAP\020\002*P\n\022StripingPo" + "licyType\022\031\n\025STRIPING_POLICY_RAID0\020\000\022\037\n\033S" + "TRIPING_POLICY_ERASURECODE\020\001*9\n\nLeaseSta" + "te\022\010\n\004NONE\020\000\022\013\n\007PRIMARY\020\001\022\n\n\006BACKUP\020\002\022\010\n" + "\004IDLE\020\003*\270\001\n\005PORTS\022\033\n\025DIR_HTTP_PORT_DEFAU" + "LT\020\256\357\001\022\034\n\026DIR_PBRPC_PORT_DEFAULT\020\376\376\001\022\033\n\025" + "MRC_HTTP_PORT_DEFAULT\020\254\357\001\022\034\n\026MRC_PBRPC_P" + "ORT_DEFAULT\020\374\376\001\022\033\n\025OSD_HTTP_PORT_DEFAULT" + "\020\260\357\001\022\034\n\026OSD_PBRPC_PORT_DEFAULT\020\200\377\001*+\n\tCO" + "NSTANTS\022\036\n\032XCAP_RENEW_INTERVAL_IN_MIN\020\001*" + "\202\003\n\016SYSTEM_V_FCNTL\022\035\n\031SYSTEM_V_FCNTL_H_O" + "_RDONLY\020\000\022\035\n\031SYSTEM_V_FCNTL_H_O_WRONLY\020\001" + "\022\033\n\027SYSTEM_V_FCNTL_H_O_RDWR\020\002\022\035\n\031SYSTEM_" + "V_FCNTL_H_O_APPEND\020\010\022\035\n\030SYSTEM_V_FCNTL_H" + "_O_CREAT\020\200\002\022\035\n\030SYSTEM_V_FCNTL_H_O_TRUNC\020" + "\200\004\022\034\n\027SYSTEM_V_FCNTL_H_O_EXCL\020\200\010\022\033\n\027SYST" + "EM_V_FCNTL_H_O_SYNC\020\020\022\036\n\030SYSTEM_V_FCNTL_" + "H_S_IFREG\020\200\200\002\022\036\n\030SYSTEM_V_FCNTL_H_S_IFDI" + "R\020\200\200\001\022\036\n\030SYSTEM_V_FCNTL_H_S_IFLNK\020\200\300\002\022\035\n" + "\030SYSTEM_V_FCNTL_H_S_IFIFO\020\200 *\330\001\n\tREPL_FL" + "AG\022\032\n\026REPL_FLAG_FULL_REPLICA\020\001\022\031\n\025REPL_F" + "LAG_IS_COMPLETE\020\002\022\035\n\031REPL_FLAG_STRATEGY_" + "RANDOM\020\004\022#\n\037REPL_FLAG_STRATEGY_RAREST_FI" + "RST\020\010\022!\n\035REPL_FLAG_STRATEGY_SEQUENTIAL\020\020" + "\022-\n)REPL_FLAG_STRATEGY_SEQUENTIAL_PREFET" + "CHING\020 *%\n\010SERVICES\022\007\n\003DIR\020\001\022\007\n\003MRC\020\002\022\007\n" + "\003OSD\020\003B(\n&org.xtreemfs.pbrpc.generatedin" + "terfaces", 3088); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "xtreemfs/GlobalTypes.proto", &protobuf_RegisterTypes); + NewFileSize::default_instance_ = new NewFileSize(); + StripingPolicy::default_instance_ = new StripingPolicy(); + Replica::default_instance_ = new Replica(); + Replicas::default_instance_ = new Replicas(); + XCap::default_instance_ = new XCap(); + XLocSet::default_instance_ = new XLocSet(); + FileCredentials::default_instance_ = new FileCredentials(); + FileCredentialsSet::default_instance_ = new FileCredentialsSet(); + VivaldiCoordinates::default_instance_ = new VivaldiCoordinates(); + OSDWriteResponse::default_instance_ = new OSDWriteResponse(); + KeyValuePair::default_instance_ = new KeyValuePair(); + NewFileSize::default_instance_->InitAsDefaultInstance(); + StripingPolicy::default_instance_->InitAsDefaultInstance(); + Replica::default_instance_->InitAsDefaultInstance(); + Replicas::default_instance_->InitAsDefaultInstance(); + XCap::default_instance_->InitAsDefaultInstance(); + XLocSet::default_instance_->InitAsDefaultInstance(); + FileCredentials::default_instance_->InitAsDefaultInstance(); + FileCredentialsSet::default_instance_->InitAsDefaultInstance(); + VivaldiCoordinates::default_instance_->InitAsDefaultInstance(); + OSDWriteResponse::default_instance_->InitAsDefaultInstance(); + KeyValuePair::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_xtreemfs_2fGlobalTypes_2eproto { + StaticDescriptorInitializer_xtreemfs_2fGlobalTypes_2eproto() { + protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + } +} static_descriptor_initializer_xtreemfs_2fGlobalTypes_2eproto_; +const ::google::protobuf::EnumDescriptor* AccessControlPolicyType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return AccessControlPolicyType_descriptor_; +} +bool AccessControlPolicyType_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* OSDSelectionPolicyType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return OSDSelectionPolicyType_descriptor_; +} +bool OSDSelectionPolicyType_IsValid(int value) { + switch(value) { + case 1000: + case 1001: + case 1002: + case 2000: + case 2001: + case 3000: + case 3001: + case 3002: + case 3003: + case 3004: + case 3998: + case 3999: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ReplicaSelectionPolicyType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ReplicaSelectionPolicyType_descriptor_; +} +bool ReplicaSelectionPolicyType_IsValid(int value) { + switch(value) { + case 1: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* SnapConfig_descriptor() { + protobuf_AssignDescriptorsOnce(); + return SnapConfig_descriptor_; +} +bool SnapConfig_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* StripingPolicyType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return StripingPolicyType_descriptor_; +} +bool StripingPolicyType_IsValid(int value) { + switch(value) { + case 0: + case 1: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* LeaseState_descriptor() { + protobuf_AssignDescriptorsOnce(); + return LeaseState_descriptor_; +} +bool LeaseState_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* PORTS_descriptor() { + protobuf_AssignDescriptorsOnce(); + return PORTS_descriptor_; +} +bool PORTS_IsValid(int value) { + switch(value) { + case 30636: + case 30638: + case 30640: + case 32636: + case 32638: + case 32640: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* CONSTANTS_descriptor() { + protobuf_AssignDescriptorsOnce(); + return CONSTANTS_descriptor_; +} +bool CONSTANTS_IsValid(int value) { + switch(value) { + case 1: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* SYSTEM_V_FCNTL_descriptor() { + protobuf_AssignDescriptorsOnce(); + return SYSTEM_V_FCNTL_descriptor_; +} +bool SYSTEM_V_FCNTL_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 8: + case 16: + case 256: + case 512: + case 1024: + case 4096: + case 16384: + case 32768: + case 40960: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* REPL_FLAG_descriptor() { + protobuf_AssignDescriptorsOnce(); + return REPL_FLAG_descriptor_; +} +bool REPL_FLAG_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 4: + case 8: + case 16: + case 32: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* SERVICES_descriptor() { + protobuf_AssignDescriptorsOnce(); + return SERVICES_descriptor_; +} +bool SERVICES_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + + +// =================================================================== + +#ifndef _MSC_VER +const int NewFileSize::kSizeInBytesFieldNumber; +const int NewFileSize::kTruncateEpochFieldNumber; +#endif // !_MSC_VER + +NewFileSize::NewFileSize() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void NewFileSize::InitAsDefaultInstance() { +} + +NewFileSize::NewFileSize(const NewFileSize& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void NewFileSize::SharedCtor() { + _cached_size_ = 0; + size_in_bytes_ = GOOGLE_ULONGLONG(0); + truncate_epoch_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +NewFileSize::~NewFileSize() { + SharedDtor(); +} + +void NewFileSize::SharedDtor() { + if (this != default_instance_) { + } +} + +void NewFileSize::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* NewFileSize::descriptor() { + protobuf_AssignDescriptorsOnce(); + return NewFileSize_descriptor_; +} + +const NewFileSize& NewFileSize::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + return *default_instance_; +} + +NewFileSize* NewFileSize::default_instance_ = NULL; + +NewFileSize* NewFileSize::New() const { + return new NewFileSize; +} + +void NewFileSize::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + size_in_bytes_ = GOOGLE_ULONGLONG(0); + truncate_epoch_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool NewFileSize::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 size_in_bytes = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &size_in_bytes_))); + set_has_size_in_bytes(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(21)) goto parse_truncate_epoch; + break; + } + + // required fixed32 truncate_epoch = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_truncate_epoch: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &truncate_epoch_))); + set_has_truncate_epoch(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void NewFileSize::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 size_in_bytes = 1; + if (has_size_in_bytes()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->size_in_bytes(), output); + } + + // required fixed32 truncate_epoch = 2; + if (has_truncate_epoch()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(2, this->truncate_epoch(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* NewFileSize::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 size_in_bytes = 1; + if (has_size_in_bytes()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->size_in_bytes(), target); + } + + // required fixed32 truncate_epoch = 2; + if (has_truncate_epoch()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(2, this->truncate_epoch(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int NewFileSize::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 size_in_bytes = 1; + if (has_size_in_bytes()) { + total_size += 1 + 8; + } + + // required fixed32 truncate_epoch = 2; + if (has_truncate_epoch()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void NewFileSize::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const NewFileSize* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void NewFileSize::MergeFrom(const NewFileSize& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_size_in_bytes()) { + set_size_in_bytes(from.size_in_bytes()); + } + if (from.has_truncate_epoch()) { + set_truncate_epoch(from.truncate_epoch()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void NewFileSize::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void NewFileSize::CopyFrom(const NewFileSize& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool NewFileSize::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void NewFileSize::Swap(NewFileSize* other) { + if (other != this) { + std::swap(size_in_bytes_, other->size_in_bytes_); + std::swap(truncate_epoch_, other->truncate_epoch_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata NewFileSize::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = NewFileSize_descriptor_; + metadata.reflection = NewFileSize_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int StripingPolicy::kTypeFieldNumber; +const int StripingPolicy::kStripeSizeFieldNumber; +const int StripingPolicy::kWidthFieldNumber; +const int StripingPolicy::kParityWidthFieldNumber; +#endif // !_MSC_VER + +StripingPolicy::StripingPolicy() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void StripingPolicy::InitAsDefaultInstance() { +} + +StripingPolicy::StripingPolicy(const StripingPolicy& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void StripingPolicy::SharedCtor() { + _cached_size_ = 0; + type_ = 0; + stripe_size_ = 0u; + width_ = 0u; + parity_width_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +StripingPolicy::~StripingPolicy() { + SharedDtor(); +} + +void StripingPolicy::SharedDtor() { + if (this != default_instance_) { + } +} + +void StripingPolicy::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* StripingPolicy::descriptor() { + protobuf_AssignDescriptorsOnce(); + return StripingPolicy_descriptor_; +} + +const StripingPolicy& StripingPolicy::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + return *default_instance_; +} + +StripingPolicy* StripingPolicy::default_instance_ = NULL; + +StripingPolicy* StripingPolicy::New() const { + return new StripingPolicy; +} + +void StripingPolicy::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + type_ = 0; + stripe_size_ = 0u; + width_ = 0u; + parity_width_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool StripingPolicy::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.StripingPolicyType type = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::StripingPolicyType_IsValid(value)) { + set_type(static_cast< ::xtreemfs::pbrpc::StripingPolicyType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(21)) goto parse_stripe_size; + break; + } + + // required fixed32 stripe_size = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_stripe_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &stripe_size_))); + set_has_stripe_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(29)) goto parse_width; + break; + } + + // required fixed32 width = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_width: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &width_))); + set_has_width(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(37)) goto parse_parity_width; + break; + } + + // optional fixed32 parity_width = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_parity_width: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &parity_width_))); + set_has_parity_width(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void StripingPolicy::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.StripingPolicyType type = 1; + if (has_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->type(), output); + } + + // required fixed32 stripe_size = 2; + if (has_stripe_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(2, this->stripe_size(), output); + } + + // required fixed32 width = 3; + if (has_width()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(3, this->width(), output); + } + + // optional fixed32 parity_width = 4; + if (has_parity_width()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(4, this->parity_width(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* StripingPolicy::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.StripingPolicyType type = 1; + if (has_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->type(), target); + } + + // required fixed32 stripe_size = 2; + if (has_stripe_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(2, this->stripe_size(), target); + } + + // required fixed32 width = 3; + if (has_width()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(3, this->width(), target); + } + + // optional fixed32 parity_width = 4; + if (has_parity_width()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(4, this->parity_width(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int StripingPolicy::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.StripingPolicyType type = 1; + if (has_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); + } + + // required fixed32 stripe_size = 2; + if (has_stripe_size()) { + total_size += 1 + 4; + } + + // required fixed32 width = 3; + if (has_width()) { + total_size += 1 + 4; + } + + // optional fixed32 parity_width = 4; + if (has_parity_width()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void StripingPolicy::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const StripingPolicy* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void StripingPolicy::MergeFrom(const StripingPolicy& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_type()) { + set_type(from.type()); + } + if (from.has_stripe_size()) { + set_stripe_size(from.stripe_size()); + } + if (from.has_width()) { + set_width(from.width()); + } + if (from.has_parity_width()) { + set_parity_width(from.parity_width()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void StripingPolicy::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void StripingPolicy::CopyFrom(const StripingPolicy& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool StripingPolicy::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void StripingPolicy::Swap(StripingPolicy* other) { + if (other != this) { + std::swap(type_, other->type_); + std::swap(stripe_size_, other->stripe_size_); + std::swap(width_, other->width_); + std::swap(parity_width_, other->parity_width_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata StripingPolicy::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = StripingPolicy_descriptor_; + metadata.reflection = StripingPolicy_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Replica::kOsdUuidsFieldNumber; +const int Replica::kReplicationFlagsFieldNumber; +const int Replica::kStripingPolicyFieldNumber; +#endif // !_MSC_VER + +Replica::Replica() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Replica::InitAsDefaultInstance() { + striping_policy_ = const_cast< ::xtreemfs::pbrpc::StripingPolicy*>(&::xtreemfs::pbrpc::StripingPolicy::default_instance()); +} + +Replica::Replica(const Replica& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Replica::SharedCtor() { + _cached_size_ = 0; + replication_flags_ = 0u; + striping_policy_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Replica::~Replica() { + SharedDtor(); +} + +void Replica::SharedDtor() { + if (this != default_instance_) { + delete striping_policy_; + } +} + +void Replica::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Replica::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Replica_descriptor_; +} + +const Replica& Replica::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + return *default_instance_; +} + +Replica* Replica::default_instance_ = NULL; + +Replica* Replica::New() const { + return new Replica; +} + +void Replica::Clear() { + if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { + replication_flags_ = 0u; + if (has_striping_policy()) { + if (striping_policy_ != NULL) striping_policy_->::xtreemfs::pbrpc::StripingPolicy::Clear(); + } + } + osd_uuids_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Replica::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string osd_uuids = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_osd_uuids: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_osd_uuids())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuids(this->osd_uuids_size() - 1).data(), + this->osd_uuids(this->osd_uuids_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_osd_uuids; + if (input->ExpectTag(21)) goto parse_replication_flags; + break; + } + + // required fixed32 replication_flags = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_replication_flags: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &replication_flags_))); + set_has_replication_flags(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_striping_policy; + break; + } + + // required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_striping_policy: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_striping_policy())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Replica::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated string osd_uuids = 1; + for (int i = 0; i < this->osd_uuids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuids(i).data(), this->osd_uuids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->osd_uuids(i), output); + } + + // required fixed32 replication_flags = 2; + if (has_replication_flags()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(2, this->replication_flags(), output); + } + + // required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + if (has_striping_policy()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->striping_policy(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Replica::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated string osd_uuids = 1; + for (int i = 0; i < this->osd_uuids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuids(i).data(), this->osd_uuids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->osd_uuids(i), target); + } + + // required fixed32 replication_flags = 2; + if (has_replication_flags()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(2, this->replication_flags(), target); + } + + // required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + if (has_striping_policy()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->striping_policy(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Replica::ByteSize() const { + int total_size = 0; + + if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { + // required fixed32 replication_flags = 2; + if (has_replication_flags()) { + total_size += 1 + 4; + } + + // required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + if (has_striping_policy()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->striping_policy()); + } + + } + // repeated string osd_uuids = 1; + total_size += 1 * this->osd_uuids_size(); + for (int i = 0; i < this->osd_uuids_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->osd_uuids(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Replica::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Replica* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Replica::MergeFrom(const Replica& from) { + GOOGLE_CHECK_NE(&from, this); + osd_uuids_.MergeFrom(from.osd_uuids_); + if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) { + if (from.has_replication_flags()) { + set_replication_flags(from.replication_flags()); + } + if (from.has_striping_policy()) { + mutable_striping_policy()->::xtreemfs::pbrpc::StripingPolicy::MergeFrom(from.striping_policy()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Replica::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Replica::CopyFrom(const Replica& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Replica::IsInitialized() const { + if ((_has_bits_[0] & 0x00000006) != 0x00000006) return false; + + if (has_striping_policy()) { + if (!this->striping_policy().IsInitialized()) return false; + } + return true; +} + +void Replica::Swap(Replica* other) { + if (other != this) { + osd_uuids_.Swap(&other->osd_uuids_); + std::swap(replication_flags_, other->replication_flags_); + std::swap(striping_policy_, other->striping_policy_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Replica::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Replica_descriptor_; + metadata.reflection = Replica_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Replicas::kReplicasFieldNumber; +#endif // !_MSC_VER + +Replicas::Replicas() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Replicas::InitAsDefaultInstance() { +} + +Replicas::Replicas(const Replicas& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Replicas::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Replicas::~Replicas() { + SharedDtor(); +} + +void Replicas::SharedDtor() { + if (this != default_instance_) { + } +} + +void Replicas::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Replicas::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Replicas_descriptor_; +} + +const Replicas& Replicas::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + return *default_instance_; +} + +Replicas* Replicas::default_instance_ = NULL; + +Replicas* Replicas::New() const { + return new Replicas; +} + +void Replicas::Clear() { + replicas_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Replicas::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .xtreemfs.pbrpc.Replica replicas = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_replicas: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_replicas())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_replicas; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Replicas::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .xtreemfs.pbrpc.Replica replicas = 1; + for (int i = 0; i < this->replicas_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->replicas(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Replicas::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .xtreemfs.pbrpc.Replica replicas = 1; + for (int i = 0; i < this->replicas_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->replicas(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Replicas::ByteSize() const { + int total_size = 0; + + // repeated .xtreemfs.pbrpc.Replica replicas = 1; + total_size += 1 * this->replicas_size(); + for (int i = 0; i < this->replicas_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->replicas(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Replicas::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Replicas* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Replicas::MergeFrom(const Replicas& from) { + GOOGLE_CHECK_NE(&from, this); + replicas_.MergeFrom(from.replicas_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Replicas::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Replicas::CopyFrom(const Replicas& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Replicas::IsInitialized() const { + + for (int i = 0; i < replicas_size(); i++) { + if (!this->replicas(i).IsInitialized()) return false; + } + return true; +} + +void Replicas::Swap(Replicas* other) { + if (other != this) { + replicas_.Swap(&other->replicas_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Replicas::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Replicas_descriptor_; + metadata.reflection = Replicas_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int XCap::kAccessModeFieldNumber; +const int XCap::kClientIdentityFieldNumber; +const int XCap::kExpireTimeSFieldNumber; +const int XCap::kExpireTimeoutSFieldNumber; +const int XCap::kFileIdFieldNumber; +const int XCap::kReplicateOnCloseFieldNumber; +const int XCap::kServerSignatureFieldNumber; +const int XCap::kTruncateEpochFieldNumber; +const int XCap::kSnapConfigFieldNumber; +const int XCap::kSnapTimestampFieldNumber; +#endif // !_MSC_VER + +XCap::XCap() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void XCap::InitAsDefaultInstance() { +} + +XCap::XCap(const XCap& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void XCap::SharedCtor() { + _cached_size_ = 0; + access_mode_ = 0u; + client_identity_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + expire_time_s_ = GOOGLE_ULONGLONG(0); + expire_timeout_s_ = 0u; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + replicate_on_close_ = false; + server_signature_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + truncate_epoch_ = 0u; + snap_config_ = 0; + snap_timestamp_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +XCap::~XCap() { + SharedDtor(); +} + +void XCap::SharedDtor() { + if (client_identity_ != &::google::protobuf::internal::kEmptyString) { + delete client_identity_; + } + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (server_signature_ != &::google::protobuf::internal::kEmptyString) { + delete server_signature_; + } + if (this != default_instance_) { + } +} + +void XCap::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* XCap::descriptor() { + protobuf_AssignDescriptorsOnce(); + return XCap_descriptor_; +} + +const XCap& XCap::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + return *default_instance_; +} + +XCap* XCap::default_instance_ = NULL; + +XCap* XCap::New() const { + return new XCap; +} + +void XCap::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + access_mode_ = 0u; + if (has_client_identity()) { + if (client_identity_ != &::google::protobuf::internal::kEmptyString) { + client_identity_->clear(); + } + } + expire_time_s_ = GOOGLE_ULONGLONG(0); + expire_timeout_s_ = 0u; + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + replicate_on_close_ = false; + if (has_server_signature()) { + if (server_signature_ != &::google::protobuf::internal::kEmptyString) { + server_signature_->clear(); + } + } + truncate_epoch_ = 0u; + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + snap_config_ = 0; + snap_timestamp_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool XCap::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed32 access_mode = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &access_mode_))); + set_has_access_mode(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_client_identity; + break; + } + + // required string client_identity = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_client_identity: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_client_identity())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->client_identity().data(), this->client_identity().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_expire_time_s; + break; + } + + // required fixed64 expire_time_s = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_expire_time_s: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &expire_time_s_))); + set_has_expire_time_s(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(37)) goto parse_expire_timeout_s; + break; + } + + // required fixed32 expire_timeout_s = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_expire_timeout_s: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &expire_timeout_s_))); + set_has_expire_timeout_s(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_file_id; + break; + } + + // required string file_id = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(48)) goto parse_replicate_on_close; + break; + } + + // required bool replicate_on_close = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_replicate_on_close: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &replicate_on_close_))); + set_has_replicate_on_close(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(58)) goto parse_server_signature; + break; + } + + // required string server_signature = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_server_signature: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_server_signature())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->server_signature().data(), this->server_signature().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(69)) goto parse_truncate_epoch; + break; + } + + // required fixed32 truncate_epoch = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_truncate_epoch: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &truncate_epoch_))); + set_has_truncate_epoch(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(72)) goto parse_snap_config; + break; + } + + // required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + case 9: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_snap_config: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::SnapConfig_IsValid(value)) { + set_snap_config(static_cast< ::xtreemfs::pbrpc::SnapConfig >(value)); + } else { + mutable_unknown_fields()->AddVarint(9, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(81)) goto parse_snap_timestamp; + break; + } + + // required fixed64 snap_timestamp = 10; + case 10: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_snap_timestamp: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &snap_timestamp_))); + set_has_snap_timestamp(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void XCap::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed32 access_mode = 1; + if (has_access_mode()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(1, this->access_mode(), output); + } + + // required string client_identity = 2; + if (has_client_identity()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->client_identity().data(), this->client_identity().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->client_identity(), output); + } + + // required fixed64 expire_time_s = 3; + if (has_expire_time_s()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->expire_time_s(), output); + } + + // required fixed32 expire_timeout_s = 4; + if (has_expire_timeout_s()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(4, this->expire_timeout_s(), output); + } + + // required string file_id = 5; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 5, this->file_id(), output); + } + + // required bool replicate_on_close = 6; + if (has_replicate_on_close()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(6, this->replicate_on_close(), output); + } + + // required string server_signature = 7; + if (has_server_signature()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->server_signature().data(), this->server_signature().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 7, this->server_signature(), output); + } + + // required fixed32 truncate_epoch = 8; + if (has_truncate_epoch()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(8, this->truncate_epoch(), output); + } + + // required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + if (has_snap_config()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 9, this->snap_config(), output); + } + + // required fixed64 snap_timestamp = 10; + if (has_snap_timestamp()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(10, this->snap_timestamp(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* XCap::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed32 access_mode = 1; + if (has_access_mode()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(1, this->access_mode(), target); + } + + // required string client_identity = 2; + if (has_client_identity()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->client_identity().data(), this->client_identity().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->client_identity(), target); + } + + // required fixed64 expire_time_s = 3; + if (has_expire_time_s()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->expire_time_s(), target); + } + + // required fixed32 expire_timeout_s = 4; + if (has_expire_timeout_s()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(4, this->expire_timeout_s(), target); + } + + // required string file_id = 5; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 5, this->file_id(), target); + } + + // required bool replicate_on_close = 6; + if (has_replicate_on_close()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(6, this->replicate_on_close(), target); + } + + // required string server_signature = 7; + if (has_server_signature()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->server_signature().data(), this->server_signature().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 7, this->server_signature(), target); + } + + // required fixed32 truncate_epoch = 8; + if (has_truncate_epoch()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(8, this->truncate_epoch(), target); + } + + // required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + if (has_snap_config()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 9, this->snap_config(), target); + } + + // required fixed64 snap_timestamp = 10; + if (has_snap_timestamp()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(10, this->snap_timestamp(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int XCap::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed32 access_mode = 1; + if (has_access_mode()) { + total_size += 1 + 4; + } + + // required string client_identity = 2; + if (has_client_identity()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->client_identity()); + } + + // required fixed64 expire_time_s = 3; + if (has_expire_time_s()) { + total_size += 1 + 8; + } + + // required fixed32 expire_timeout_s = 4; + if (has_expire_timeout_s()) { + total_size += 1 + 4; + } + + // required string file_id = 5; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required bool replicate_on_close = 6; + if (has_replicate_on_close()) { + total_size += 1 + 1; + } + + // required string server_signature = 7; + if (has_server_signature()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->server_signature()); + } + + // required fixed32 truncate_epoch = 8; + if (has_truncate_epoch()) { + total_size += 1 + 4; + } + + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + if (has_snap_config()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->snap_config()); + } + + // required fixed64 snap_timestamp = 10; + if (has_snap_timestamp()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void XCap::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const XCap* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void XCap::MergeFrom(const XCap& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_access_mode()) { + set_access_mode(from.access_mode()); + } + if (from.has_client_identity()) { + set_client_identity(from.client_identity()); + } + if (from.has_expire_time_s()) { + set_expire_time_s(from.expire_time_s()); + } + if (from.has_expire_timeout_s()) { + set_expire_timeout_s(from.expire_timeout_s()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_replicate_on_close()) { + set_replicate_on_close(from.replicate_on_close()); + } + if (from.has_server_signature()) { + set_server_signature(from.server_signature()); + } + if (from.has_truncate_epoch()) { + set_truncate_epoch(from.truncate_epoch()); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_snap_config()) { + set_snap_config(from.snap_config()); + } + if (from.has_snap_timestamp()) { + set_snap_timestamp(from.snap_timestamp()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void XCap::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void XCap::CopyFrom(const XCap& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool XCap::IsInitialized() const { + if ((_has_bits_[0] & 0x000003ff) != 0x000003ff) return false; + + return true; +} + +void XCap::Swap(XCap* other) { + if (other != this) { + std::swap(access_mode_, other->access_mode_); + std::swap(client_identity_, other->client_identity_); + std::swap(expire_time_s_, other->expire_time_s_); + std::swap(expire_timeout_s_, other->expire_timeout_s_); + std::swap(file_id_, other->file_id_); + std::swap(replicate_on_close_, other->replicate_on_close_); + std::swap(server_signature_, other->server_signature_); + std::swap(truncate_epoch_, other->truncate_epoch_); + std::swap(snap_config_, other->snap_config_); + std::swap(snap_timestamp_, other->snap_timestamp_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata XCap::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = XCap_descriptor_; + metadata.reflection = XCap_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int XLocSet::kReadOnlyFileSizeFieldNumber; +const int XLocSet::kReplicasFieldNumber; +const int XLocSet::kReplicaUpdatePolicyFieldNumber; +const int XLocSet::kVersionFieldNumber; +#endif // !_MSC_VER + +XLocSet::XLocSet() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void XLocSet::InitAsDefaultInstance() { +} + +XLocSet::XLocSet(const XLocSet& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void XLocSet::SharedCtor() { + _cached_size_ = 0; + read_only_file_size_ = GOOGLE_ULONGLONG(0); + replica_update_policy_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + version_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +XLocSet::~XLocSet() { + SharedDtor(); +} + +void XLocSet::SharedDtor() { + if (replica_update_policy_ != &::google::protobuf::internal::kEmptyString) { + delete replica_update_policy_; + } + if (this != default_instance_) { + } +} + +void XLocSet::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* XLocSet::descriptor() { + protobuf_AssignDescriptorsOnce(); + return XLocSet_descriptor_; +} + +const XLocSet& XLocSet::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + return *default_instance_; +} + +XLocSet* XLocSet::default_instance_ = NULL; + +XLocSet* XLocSet::New() const { + return new XLocSet; +} + +void XLocSet::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + read_only_file_size_ = GOOGLE_ULONGLONG(0); + if (has_replica_update_policy()) { + if (replica_update_policy_ != &::google::protobuf::internal::kEmptyString) { + replica_update_policy_->clear(); + } + } + version_ = 0u; + } + replicas_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool XLocSet::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 read_only_file_size = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &read_only_file_size_))); + set_has_read_only_file_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_replicas; + break; + } + + // repeated .xtreemfs.pbrpc.Replica replicas = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_replicas: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_replicas())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_replicas; + if (input->ExpectTag(26)) goto parse_replica_update_policy; + break; + } + + // required string replica_update_policy = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_replica_update_policy: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_replica_update_policy())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->replica_update_policy().data(), this->replica_update_policy().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(37)) goto parse_version; + break; + } + + // required fixed32 version = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &version_))); + set_has_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void XLocSet::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 read_only_file_size = 1; + if (has_read_only_file_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->read_only_file_size(), output); + } + + // repeated .xtreemfs.pbrpc.Replica replicas = 2; + for (int i = 0; i < this->replicas_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->replicas(i), output); + } + + // required string replica_update_policy = 3; + if (has_replica_update_policy()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->replica_update_policy().data(), this->replica_update_policy().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->replica_update_policy(), output); + } + + // required fixed32 version = 4; + if (has_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(4, this->version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* XLocSet::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 read_only_file_size = 1; + if (has_read_only_file_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->read_only_file_size(), target); + } + + // repeated .xtreemfs.pbrpc.Replica replicas = 2; + for (int i = 0; i < this->replicas_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->replicas(i), target); + } + + // required string replica_update_policy = 3; + if (has_replica_update_policy()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->replica_update_policy().data(), this->replica_update_policy().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->replica_update_policy(), target); + } + + // required fixed32 version = 4; + if (has_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(4, this->version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int XLocSet::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 read_only_file_size = 1; + if (has_read_only_file_size()) { + total_size += 1 + 8; + } + + // required string replica_update_policy = 3; + if (has_replica_update_policy()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->replica_update_policy()); + } + + // required fixed32 version = 4; + if (has_version()) { + total_size += 1 + 4; + } + + } + // repeated .xtreemfs.pbrpc.Replica replicas = 2; + total_size += 1 * this->replicas_size(); + for (int i = 0; i < this->replicas_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->replicas(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void XLocSet::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const XLocSet* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void XLocSet::MergeFrom(const XLocSet& from) { + GOOGLE_CHECK_NE(&from, this); + replicas_.MergeFrom(from.replicas_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_read_only_file_size()) { + set_read_only_file_size(from.read_only_file_size()); + } + if (from.has_replica_update_policy()) { + set_replica_update_policy(from.replica_update_policy()); + } + if (from.has_version()) { + set_version(from.version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void XLocSet::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void XLocSet::CopyFrom(const XLocSet& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool XLocSet::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000d) != 0x0000000d) return false; + + for (int i = 0; i < replicas_size(); i++) { + if (!this->replicas(i).IsInitialized()) return false; + } + return true; +} + +void XLocSet::Swap(XLocSet* other) { + if (other != this) { + std::swap(read_only_file_size_, other->read_only_file_size_); + replicas_.Swap(&other->replicas_); + std::swap(replica_update_policy_, other->replica_update_policy_); + std::swap(version_, other->version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata XLocSet::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = XLocSet_descriptor_; + metadata.reflection = XLocSet_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FileCredentials::kXcapFieldNumber; +const int FileCredentials::kXlocsFieldNumber; +#endif // !_MSC_VER + +FileCredentials::FileCredentials() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void FileCredentials::InitAsDefaultInstance() { + xcap_ = const_cast< ::xtreemfs::pbrpc::XCap*>(&::xtreemfs::pbrpc::XCap::default_instance()); + xlocs_ = const_cast< ::xtreemfs::pbrpc::XLocSet*>(&::xtreemfs::pbrpc::XLocSet::default_instance()); +} + +FileCredentials::FileCredentials(const FileCredentials& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void FileCredentials::SharedCtor() { + _cached_size_ = 0; + xcap_ = NULL; + xlocs_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FileCredentials::~FileCredentials() { + SharedDtor(); +} + +void FileCredentials::SharedDtor() { + if (this != default_instance_) { + delete xcap_; + delete xlocs_; + } +} + +void FileCredentials::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FileCredentials::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FileCredentials_descriptor_; +} + +const FileCredentials& FileCredentials::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + return *default_instance_; +} + +FileCredentials* FileCredentials::default_instance_ = NULL; + +FileCredentials* FileCredentials::New() const { + return new FileCredentials; +} + +void FileCredentials::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_xcap()) { + if (xcap_ != NULL) xcap_->::xtreemfs::pbrpc::XCap::Clear(); + } + if (has_xlocs()) { + if (xlocs_ != NULL) xlocs_->::xtreemfs::pbrpc::XLocSet::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FileCredentials::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.XCap xcap = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_xcap())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_xlocs; + break; + } + + // required .xtreemfs.pbrpc.XLocSet xlocs = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_xlocs: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_xlocs())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void FileCredentials::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.XCap xcap = 1; + if (has_xcap()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->xcap(), output); + } + + // required .xtreemfs.pbrpc.XLocSet xlocs = 2; + if (has_xlocs()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->xlocs(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* FileCredentials::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.XCap xcap = 1; + if (has_xcap()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->xcap(), target); + } + + // required .xtreemfs.pbrpc.XLocSet xlocs = 2; + if (has_xlocs()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->xlocs(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int FileCredentials::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.XCap xcap = 1; + if (has_xcap()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->xcap()); + } + + // required .xtreemfs.pbrpc.XLocSet xlocs = 2; + if (has_xlocs()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->xlocs()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FileCredentials::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FileCredentials* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FileCredentials::MergeFrom(const FileCredentials& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_xcap()) { + mutable_xcap()->::xtreemfs::pbrpc::XCap::MergeFrom(from.xcap()); + } + if (from.has_xlocs()) { + mutable_xlocs()->::xtreemfs::pbrpc::XLocSet::MergeFrom(from.xlocs()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FileCredentials::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FileCredentials::CopyFrom(const FileCredentials& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FileCredentials::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_xcap()) { + if (!this->xcap().IsInitialized()) return false; + } + if (has_xlocs()) { + if (!this->xlocs().IsInitialized()) return false; + } + return true; +} + +void FileCredentials::Swap(FileCredentials* other) { + if (other != this) { + std::swap(xcap_, other->xcap_); + std::swap(xlocs_, other->xlocs_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FileCredentials::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FileCredentials_descriptor_; + metadata.reflection = FileCredentials_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FileCredentialsSet::kFileCredentialsFieldNumber; +#endif // !_MSC_VER + +FileCredentialsSet::FileCredentialsSet() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void FileCredentialsSet::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +FileCredentialsSet::FileCredentialsSet(const FileCredentialsSet& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void FileCredentialsSet::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FileCredentialsSet::~FileCredentialsSet() { + SharedDtor(); +} + +void FileCredentialsSet::SharedDtor() { + if (this != default_instance_) { + delete file_credentials_; + } +} + +void FileCredentialsSet::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FileCredentialsSet::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FileCredentialsSet_descriptor_; +} + +const FileCredentialsSet& FileCredentialsSet::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + return *default_instance_; +} + +FileCredentialsSet* FileCredentialsSet::default_instance_ = NULL; + +FileCredentialsSet* FileCredentialsSet::New() const { + return new FileCredentialsSet; +} + +void FileCredentialsSet::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FileCredentialsSet::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void FileCredentialsSet::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* FileCredentialsSet::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int FileCredentialsSet::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FileCredentialsSet::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FileCredentialsSet* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FileCredentialsSet::MergeFrom(const FileCredentialsSet& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FileCredentialsSet::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FileCredentialsSet::CopyFrom(const FileCredentialsSet& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FileCredentialsSet::IsInitialized() const { + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void FileCredentialsSet::Swap(FileCredentialsSet* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FileCredentialsSet::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FileCredentialsSet_descriptor_; + metadata.reflection = FileCredentialsSet_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int VivaldiCoordinates::kXCoordinateFieldNumber; +const int VivaldiCoordinates::kYCoordinateFieldNumber; +const int VivaldiCoordinates::kLocalErrorFieldNumber; +#endif // !_MSC_VER + +VivaldiCoordinates::VivaldiCoordinates() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void VivaldiCoordinates::InitAsDefaultInstance() { +} + +VivaldiCoordinates::VivaldiCoordinates(const VivaldiCoordinates& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void VivaldiCoordinates::SharedCtor() { + _cached_size_ = 0; + x_coordinate_ = 0; + y_coordinate_ = 0; + local_error_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +VivaldiCoordinates::~VivaldiCoordinates() { + SharedDtor(); +} + +void VivaldiCoordinates::SharedDtor() { + if (this != default_instance_) { + } +} + +void VivaldiCoordinates::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* VivaldiCoordinates::descriptor() { + protobuf_AssignDescriptorsOnce(); + return VivaldiCoordinates_descriptor_; +} + +const VivaldiCoordinates& VivaldiCoordinates::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + return *default_instance_; +} + +VivaldiCoordinates* VivaldiCoordinates::default_instance_ = NULL; + +VivaldiCoordinates* VivaldiCoordinates::New() const { + return new VivaldiCoordinates; +} + +void VivaldiCoordinates::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + x_coordinate_ = 0; + y_coordinate_ = 0; + local_error_ = 0; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool VivaldiCoordinates::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required double x_coordinate = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &x_coordinate_))); + set_has_x_coordinate(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(17)) goto parse_y_coordinate; + break; + } + + // required double y_coordinate = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_y_coordinate: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &y_coordinate_))); + set_has_y_coordinate(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_local_error; + break; + } + + // required double local_error = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_local_error: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &local_error_))); + set_has_local_error(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void VivaldiCoordinates::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required double x_coordinate = 1; + if (has_x_coordinate()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->x_coordinate(), output); + } + + // required double y_coordinate = 2; + if (has_y_coordinate()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->y_coordinate(), output); + } + + // required double local_error = 3; + if (has_local_error()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(3, this->local_error(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* VivaldiCoordinates::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required double x_coordinate = 1; + if (has_x_coordinate()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->x_coordinate(), target); + } + + // required double y_coordinate = 2; + if (has_y_coordinate()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->y_coordinate(), target); + } + + // required double local_error = 3; + if (has_local_error()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(3, this->local_error(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int VivaldiCoordinates::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required double x_coordinate = 1; + if (has_x_coordinate()) { + total_size += 1 + 8; + } + + // required double y_coordinate = 2; + if (has_y_coordinate()) { + total_size += 1 + 8; + } + + // required double local_error = 3; + if (has_local_error()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void VivaldiCoordinates::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const VivaldiCoordinates* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void VivaldiCoordinates::MergeFrom(const VivaldiCoordinates& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_x_coordinate()) { + set_x_coordinate(from.x_coordinate()); + } + if (from.has_y_coordinate()) { + set_y_coordinate(from.y_coordinate()); + } + if (from.has_local_error()) { + set_local_error(from.local_error()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void VivaldiCoordinates::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void VivaldiCoordinates::CopyFrom(const VivaldiCoordinates& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool VivaldiCoordinates::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void VivaldiCoordinates::Swap(VivaldiCoordinates* other) { + if (other != this) { + std::swap(x_coordinate_, other->x_coordinate_); + std::swap(y_coordinate_, other->y_coordinate_); + std::swap(local_error_, other->local_error_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata VivaldiCoordinates::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = VivaldiCoordinates_descriptor_; + metadata.reflection = VivaldiCoordinates_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int OSDWriteResponse::kSizeInBytesFieldNumber; +const int OSDWriteResponse::kTruncateEpochFieldNumber; +#endif // !_MSC_VER + +OSDWriteResponse::OSDWriteResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void OSDWriteResponse::InitAsDefaultInstance() { +} + +OSDWriteResponse::OSDWriteResponse(const OSDWriteResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void OSDWriteResponse::SharedCtor() { + _cached_size_ = 0; + size_in_bytes_ = GOOGLE_ULONGLONG(0); + truncate_epoch_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +OSDWriteResponse::~OSDWriteResponse() { + SharedDtor(); +} + +void OSDWriteResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void OSDWriteResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* OSDWriteResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return OSDWriteResponse_descriptor_; +} + +const OSDWriteResponse& OSDWriteResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + return *default_instance_; +} + +OSDWriteResponse* OSDWriteResponse::default_instance_ = NULL; + +OSDWriteResponse* OSDWriteResponse::New() const { + return new OSDWriteResponse; +} + +void OSDWriteResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + size_in_bytes_ = GOOGLE_ULONGLONG(0); + truncate_epoch_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool OSDWriteResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional fixed64 size_in_bytes = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &size_in_bytes_))); + set_has_size_in_bytes(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(21)) goto parse_truncate_epoch; + break; + } + + // optional fixed32 truncate_epoch = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_truncate_epoch: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &truncate_epoch_))); + set_has_truncate_epoch(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void OSDWriteResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional fixed64 size_in_bytes = 1; + if (has_size_in_bytes()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->size_in_bytes(), output); + } + + // optional fixed32 truncate_epoch = 2; + if (has_truncate_epoch()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(2, this->truncate_epoch(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* OSDWriteResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional fixed64 size_in_bytes = 1; + if (has_size_in_bytes()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->size_in_bytes(), target); + } + + // optional fixed32 truncate_epoch = 2; + if (has_truncate_epoch()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(2, this->truncate_epoch(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int OSDWriteResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional fixed64 size_in_bytes = 1; + if (has_size_in_bytes()) { + total_size += 1 + 8; + } + + // optional fixed32 truncate_epoch = 2; + if (has_truncate_epoch()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void OSDWriteResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const OSDWriteResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void OSDWriteResponse::MergeFrom(const OSDWriteResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_size_in_bytes()) { + set_size_in_bytes(from.size_in_bytes()); + } + if (from.has_truncate_epoch()) { + set_truncate_epoch(from.truncate_epoch()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void OSDWriteResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void OSDWriteResponse::CopyFrom(const OSDWriteResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool OSDWriteResponse::IsInitialized() const { + + return true; +} + +void OSDWriteResponse::Swap(OSDWriteResponse* other) { + if (other != this) { + std::swap(size_in_bytes_, other->size_in_bytes_); + std::swap(truncate_epoch_, other->truncate_epoch_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata OSDWriteResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = OSDWriteResponse_descriptor_; + metadata.reflection = OSDWriteResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int KeyValuePair::kKeyFieldNumber; +const int KeyValuePair::kValueFieldNumber; +#endif // !_MSC_VER + +KeyValuePair::KeyValuePair() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void KeyValuePair::InitAsDefaultInstance() { +} + +KeyValuePair::KeyValuePair(const KeyValuePair& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void KeyValuePair::SharedCtor() { + _cached_size_ = 0; + key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +KeyValuePair::~KeyValuePair() { + SharedDtor(); +} + +void KeyValuePair::SharedDtor() { + if (key_ != &::google::protobuf::internal::kEmptyString) { + delete key_; + } + if (value_ != &::google::protobuf::internal::kEmptyString) { + delete value_; + } + if (this != default_instance_) { + } +} + +void KeyValuePair::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* KeyValuePair::descriptor() { + protobuf_AssignDescriptorsOnce(); + return KeyValuePair_descriptor_; +} + +const KeyValuePair& KeyValuePair::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + return *default_instance_; +} + +KeyValuePair* KeyValuePair::default_instance_ = NULL; + +KeyValuePair* KeyValuePair::New() const { + return new KeyValuePair; +} + +void KeyValuePair::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_key()) { + if (key_ != &::google::protobuf::internal::kEmptyString) { + key_->clear(); + } + } + if (has_value()) { + if (value_ != &::google::protobuf::internal::kEmptyString) { + value_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool KeyValuePair::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string key = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_key())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->key().data(), this->key().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_value; + break; + } + + // required string value = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void KeyValuePair::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string key = 1; + if (has_key()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->key().data(), this->key().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->key(), output); + } + + // required string value = 2; + if (has_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->value(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* KeyValuePair::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string key = 1; + if (has_key()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->key().data(), this->key().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->key(), target); + } + + // required string value = 2; + if (has_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->value(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int KeyValuePair::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string key = 1; + if (has_key()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->key()); + } + + // required string value = 2; + if (has_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->value()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void KeyValuePair::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const KeyValuePair* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void KeyValuePair::MergeFrom(const KeyValuePair& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_key()) { + set_key(from.key()); + } + if (from.has_value()) { + set_value(from.value()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void KeyValuePair::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void KeyValuePair::CopyFrom(const KeyValuePair& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool KeyValuePair::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void KeyValuePair::Swap(KeyValuePair* other) { + if (other != this) { + std::swap(key_, other->key_); + std::swap(value_, other->value_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata KeyValuePair::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = KeyValuePair_descriptor_; + metadata.reflection = KeyValuePair_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/generated/xtreemfs/GlobalTypes.pb.h b/cpp/generated/xtreemfs/GlobalTypes.pb.h new file mode 100644 index 0000000..fdba318 --- /dev/null +++ b/cpp/generated/xtreemfs/GlobalTypes.pb.h @@ -0,0 +1,2713 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/GlobalTypes.proto + +#ifndef PROTOBUF_xtreemfs_2fGlobalTypes_2eproto__INCLUDED +#define PROTOBUF_xtreemfs_2fGlobalTypes_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include "include/PBRPC.pb.h" +#include "include/Common.pb.h" +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); +void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); +void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + +class NewFileSize; +class StripingPolicy; +class Replica; +class Replicas; +class XCap; +class XLocSet; +class FileCredentials; +class FileCredentialsSet; +class VivaldiCoordinates; +class OSDWriteResponse; +class KeyValuePair; + +enum AccessControlPolicyType { + ACCESS_CONTROL_POLICY_NULL = 1, + ACCESS_CONTROL_POLICY_POSIX = 2, + ACCESS_CONTROL_POLICY_VOLUME = 3 +}; +bool AccessControlPolicyType_IsValid(int value); +const AccessControlPolicyType AccessControlPolicyType_MIN = ACCESS_CONTROL_POLICY_NULL; +const AccessControlPolicyType AccessControlPolicyType_MAX = ACCESS_CONTROL_POLICY_VOLUME; +const int AccessControlPolicyType_ARRAYSIZE = AccessControlPolicyType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* AccessControlPolicyType_descriptor(); +inline const ::std::string& AccessControlPolicyType_Name(AccessControlPolicyType value) { + return ::google::protobuf::internal::NameOfEnum( + AccessControlPolicyType_descriptor(), value); +} +inline bool AccessControlPolicyType_Parse( + const ::std::string& name, AccessControlPolicyType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + AccessControlPolicyType_descriptor(), name, value); +} +enum OSDSelectionPolicyType { + OSD_SELECTION_POLICY_FILTER_DEFAULT = 1000, + OSD_SELECTION_POLICY_FILTER_FQDN = 1001, + OSD_SELECTION_POLICY_FILTER_UUID = 1002, + OSD_SELECTION_POLICY_GROUP_DCMAP = 2000, + OSD_SELECTION_POLICY_GROUP_FQDN = 2001, + OSD_SELECTION_POLICY_SORT_DCMAP = 3000, + OSD_SELECTION_POLICY_SORT_FQDN = 3001, + OSD_SELECTION_POLICY_SORT_RANDOM = 3002, + OSD_SELECTION_POLICY_SORT_VIVALDI = 3003, + OSD_SELECTION_POLICY_SORT_HOST_ROUND_ROBIN = 3004, + OSD_SELECTION_POLICY_SORT_UUID = 3998, + OSD_SELECTION_POLICY_SORT_REVERSE = 3999 +}; +bool OSDSelectionPolicyType_IsValid(int value); +const OSDSelectionPolicyType OSDSelectionPolicyType_MIN = OSD_SELECTION_POLICY_FILTER_DEFAULT; +const OSDSelectionPolicyType OSDSelectionPolicyType_MAX = OSD_SELECTION_POLICY_SORT_REVERSE; +const int OSDSelectionPolicyType_ARRAYSIZE = OSDSelectionPolicyType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* OSDSelectionPolicyType_descriptor(); +inline const ::std::string& OSDSelectionPolicyType_Name(OSDSelectionPolicyType value) { + return ::google::protobuf::internal::NameOfEnum( + OSDSelectionPolicyType_descriptor(), value); +} +inline bool OSDSelectionPolicyType_Parse( + const ::std::string& name, OSDSelectionPolicyType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + OSDSelectionPolicyType_descriptor(), name, value); +} +enum ReplicaSelectionPolicyType { + REPLICA_SELECTION_POLICY_SIMPLE = 1 +}; +bool ReplicaSelectionPolicyType_IsValid(int value); +const ReplicaSelectionPolicyType ReplicaSelectionPolicyType_MIN = REPLICA_SELECTION_POLICY_SIMPLE; +const ReplicaSelectionPolicyType ReplicaSelectionPolicyType_MAX = REPLICA_SELECTION_POLICY_SIMPLE; +const int ReplicaSelectionPolicyType_ARRAYSIZE = ReplicaSelectionPolicyType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ReplicaSelectionPolicyType_descriptor(); +inline const ::std::string& ReplicaSelectionPolicyType_Name(ReplicaSelectionPolicyType value) { + return ::google::protobuf::internal::NameOfEnum( + ReplicaSelectionPolicyType_descriptor(), value); +} +inline bool ReplicaSelectionPolicyType_Parse( + const ::std::string& name, ReplicaSelectionPolicyType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ReplicaSelectionPolicyType_descriptor(), name, value); +} +enum SnapConfig { + SNAP_CONFIG_SNAPS_DISABLED = 0, + SNAP_CONFIG_ACCESS_CURRENT = 1, + SNAP_CONFIG_ACCESS_SNAP = 2 +}; +bool SnapConfig_IsValid(int value); +const SnapConfig SnapConfig_MIN = SNAP_CONFIG_SNAPS_DISABLED; +const SnapConfig SnapConfig_MAX = SNAP_CONFIG_ACCESS_SNAP; +const int SnapConfig_ARRAYSIZE = SnapConfig_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SnapConfig_descriptor(); +inline const ::std::string& SnapConfig_Name(SnapConfig value) { + return ::google::protobuf::internal::NameOfEnum( + SnapConfig_descriptor(), value); +} +inline bool SnapConfig_Parse( + const ::std::string& name, SnapConfig* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SnapConfig_descriptor(), name, value); +} +enum StripingPolicyType { + STRIPING_POLICY_RAID0 = 0, + STRIPING_POLICY_ERASURECODE = 1 +}; +bool StripingPolicyType_IsValid(int value); +const StripingPolicyType StripingPolicyType_MIN = STRIPING_POLICY_RAID0; +const StripingPolicyType StripingPolicyType_MAX = STRIPING_POLICY_ERASURECODE; +const int StripingPolicyType_ARRAYSIZE = StripingPolicyType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* StripingPolicyType_descriptor(); +inline const ::std::string& StripingPolicyType_Name(StripingPolicyType value) { + return ::google::protobuf::internal::NameOfEnum( + StripingPolicyType_descriptor(), value); +} +inline bool StripingPolicyType_Parse( + const ::std::string& name, StripingPolicyType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + StripingPolicyType_descriptor(), name, value); +} +enum LeaseState { + NONE = 0, + PRIMARY = 1, + BACKUP = 2, + IDLE = 3 +}; +bool LeaseState_IsValid(int value); +const LeaseState LeaseState_MIN = NONE; +const LeaseState LeaseState_MAX = IDLE; +const int LeaseState_ARRAYSIZE = LeaseState_MAX + 1; + +const ::google::protobuf::EnumDescriptor* LeaseState_descriptor(); +inline const ::std::string& LeaseState_Name(LeaseState value) { + return ::google::protobuf::internal::NameOfEnum( + LeaseState_descriptor(), value); +} +inline bool LeaseState_Parse( + const ::std::string& name, LeaseState* value) { + return ::google::protobuf::internal::ParseNamedEnum( + LeaseState_descriptor(), name, value); +} +enum PORTS { + DIR_HTTP_PORT_DEFAULT = 30638, + DIR_PBRPC_PORT_DEFAULT = 32638, + MRC_HTTP_PORT_DEFAULT = 30636, + MRC_PBRPC_PORT_DEFAULT = 32636, + OSD_HTTP_PORT_DEFAULT = 30640, + OSD_PBRPC_PORT_DEFAULT = 32640 +}; +bool PORTS_IsValid(int value); +const PORTS PORTS_MIN = MRC_HTTP_PORT_DEFAULT; +const PORTS PORTS_MAX = OSD_PBRPC_PORT_DEFAULT; +const int PORTS_ARRAYSIZE = PORTS_MAX + 1; + +const ::google::protobuf::EnumDescriptor* PORTS_descriptor(); +inline const ::std::string& PORTS_Name(PORTS value) { + return ::google::protobuf::internal::NameOfEnum( + PORTS_descriptor(), value); +} +inline bool PORTS_Parse( + const ::std::string& name, PORTS* value) { + return ::google::protobuf::internal::ParseNamedEnum( + PORTS_descriptor(), name, value); +} +enum CONSTANTS { + XCAP_RENEW_INTERVAL_IN_MIN = 1 +}; +bool CONSTANTS_IsValid(int value); +const CONSTANTS CONSTANTS_MIN = XCAP_RENEW_INTERVAL_IN_MIN; +const CONSTANTS CONSTANTS_MAX = XCAP_RENEW_INTERVAL_IN_MIN; +const int CONSTANTS_ARRAYSIZE = CONSTANTS_MAX + 1; + +const ::google::protobuf::EnumDescriptor* CONSTANTS_descriptor(); +inline const ::std::string& CONSTANTS_Name(CONSTANTS value) { + return ::google::protobuf::internal::NameOfEnum( + CONSTANTS_descriptor(), value); +} +inline bool CONSTANTS_Parse( + const ::std::string& name, CONSTANTS* value) { + return ::google::protobuf::internal::ParseNamedEnum( + CONSTANTS_descriptor(), name, value); +} +enum SYSTEM_V_FCNTL { + SYSTEM_V_FCNTL_H_O_RDONLY = 0, + SYSTEM_V_FCNTL_H_O_WRONLY = 1, + SYSTEM_V_FCNTL_H_O_RDWR = 2, + SYSTEM_V_FCNTL_H_O_APPEND = 8, + SYSTEM_V_FCNTL_H_O_CREAT = 256, + SYSTEM_V_FCNTL_H_O_TRUNC = 512, + SYSTEM_V_FCNTL_H_O_EXCL = 1024, + SYSTEM_V_FCNTL_H_O_SYNC = 16, + SYSTEM_V_FCNTL_H_S_IFREG = 32768, + SYSTEM_V_FCNTL_H_S_IFDIR = 16384, + SYSTEM_V_FCNTL_H_S_IFLNK = 40960, + SYSTEM_V_FCNTL_H_S_IFIFO = 4096 +}; +bool SYSTEM_V_FCNTL_IsValid(int value); +const SYSTEM_V_FCNTL SYSTEM_V_FCNTL_MIN = SYSTEM_V_FCNTL_H_O_RDONLY; +const SYSTEM_V_FCNTL SYSTEM_V_FCNTL_MAX = SYSTEM_V_FCNTL_H_S_IFLNK; +const int SYSTEM_V_FCNTL_ARRAYSIZE = SYSTEM_V_FCNTL_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SYSTEM_V_FCNTL_descriptor(); +inline const ::std::string& SYSTEM_V_FCNTL_Name(SYSTEM_V_FCNTL value) { + return ::google::protobuf::internal::NameOfEnum( + SYSTEM_V_FCNTL_descriptor(), value); +} +inline bool SYSTEM_V_FCNTL_Parse( + const ::std::string& name, SYSTEM_V_FCNTL* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SYSTEM_V_FCNTL_descriptor(), name, value); +} +enum REPL_FLAG { + REPL_FLAG_FULL_REPLICA = 1, + REPL_FLAG_IS_COMPLETE = 2, + REPL_FLAG_STRATEGY_RANDOM = 4, + REPL_FLAG_STRATEGY_RAREST_FIRST = 8, + REPL_FLAG_STRATEGY_SEQUENTIAL = 16, + REPL_FLAG_STRATEGY_SEQUENTIAL_PREFETCHING = 32 +}; +bool REPL_FLAG_IsValid(int value); +const REPL_FLAG REPL_FLAG_MIN = REPL_FLAG_FULL_REPLICA; +const REPL_FLAG REPL_FLAG_MAX = REPL_FLAG_STRATEGY_SEQUENTIAL_PREFETCHING; +const int REPL_FLAG_ARRAYSIZE = REPL_FLAG_MAX + 1; + +const ::google::protobuf::EnumDescriptor* REPL_FLAG_descriptor(); +inline const ::std::string& REPL_FLAG_Name(REPL_FLAG value) { + return ::google::protobuf::internal::NameOfEnum( + REPL_FLAG_descriptor(), value); +} +inline bool REPL_FLAG_Parse( + const ::std::string& name, REPL_FLAG* value) { + return ::google::protobuf::internal::ParseNamedEnum( + REPL_FLAG_descriptor(), name, value); +} +enum SERVICES { + DIR = 1, + MRC = 2, + OSD = 3 +}; +bool SERVICES_IsValid(int value); +const SERVICES SERVICES_MIN = DIR; +const SERVICES SERVICES_MAX = OSD; +const int SERVICES_ARRAYSIZE = SERVICES_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SERVICES_descriptor(); +inline const ::std::string& SERVICES_Name(SERVICES value) { + return ::google::protobuf::internal::NameOfEnum( + SERVICES_descriptor(), value); +} +inline bool SERVICES_Parse( + const ::std::string& name, SERVICES* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SERVICES_descriptor(), name, value); +} +// =================================================================== + +class NewFileSize : public ::google::protobuf::Message { + public: + NewFileSize(); + virtual ~NewFileSize(); + + NewFileSize(const NewFileSize& from); + + inline NewFileSize& operator=(const NewFileSize& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const NewFileSize& default_instance(); + + void Swap(NewFileSize* other); + + // implements Message ---------------------------------------------- + + NewFileSize* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const NewFileSize& from); + void MergeFrom(const NewFileSize& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 size_in_bytes = 1; + inline bool has_size_in_bytes() const; + inline void clear_size_in_bytes(); + static const int kSizeInBytesFieldNumber = 1; + inline ::google::protobuf::uint64 size_in_bytes() const; + inline void set_size_in_bytes(::google::protobuf::uint64 value); + + // required fixed32 truncate_epoch = 2; + inline bool has_truncate_epoch() const; + inline void clear_truncate_epoch(); + static const int kTruncateEpochFieldNumber = 2; + inline ::google::protobuf::uint32 truncate_epoch() const; + inline void set_truncate_epoch(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.NewFileSize) + private: + inline void set_has_size_in_bytes(); + inline void clear_has_size_in_bytes(); + inline void set_has_truncate_epoch(); + inline void clear_has_truncate_epoch(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 size_in_bytes_; + ::google::protobuf::uint32 truncate_epoch_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + + void InitAsDefaultInstance(); + static NewFileSize* default_instance_; +}; +// ------------------------------------------------------------------- + +class StripingPolicy : public ::google::protobuf::Message { + public: + StripingPolicy(); + virtual ~StripingPolicy(); + + StripingPolicy(const StripingPolicy& from); + + inline StripingPolicy& operator=(const StripingPolicy& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const StripingPolicy& default_instance(); + + void Swap(StripingPolicy* other); + + // implements Message ---------------------------------------------- + + StripingPolicy* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const StripingPolicy& from); + void MergeFrom(const StripingPolicy& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.StripingPolicyType type = 1; + inline bool has_type() const; + inline void clear_type(); + static const int kTypeFieldNumber = 1; + inline ::xtreemfs::pbrpc::StripingPolicyType type() const; + inline void set_type(::xtreemfs::pbrpc::StripingPolicyType value); + + // required fixed32 stripe_size = 2; + inline bool has_stripe_size() const; + inline void clear_stripe_size(); + static const int kStripeSizeFieldNumber = 2; + inline ::google::protobuf::uint32 stripe_size() const; + inline void set_stripe_size(::google::protobuf::uint32 value); + + // required fixed32 width = 3; + inline bool has_width() const; + inline void clear_width(); + static const int kWidthFieldNumber = 3; + inline ::google::protobuf::uint32 width() const; + inline void set_width(::google::protobuf::uint32 value); + + // optional fixed32 parity_width = 4; + inline bool has_parity_width() const; + inline void clear_parity_width(); + static const int kParityWidthFieldNumber = 4; + inline ::google::protobuf::uint32 parity_width() const; + inline void set_parity_width(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.StripingPolicy) + private: + inline void set_has_type(); + inline void clear_has_type(); + inline void set_has_stripe_size(); + inline void clear_has_stripe_size(); + inline void set_has_width(); + inline void clear_has_width(); + inline void set_has_parity_width(); + inline void clear_has_parity_width(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + int type_; + ::google::protobuf::uint32 stripe_size_; + ::google::protobuf::uint32 width_; + ::google::protobuf::uint32 parity_width_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + + void InitAsDefaultInstance(); + static StripingPolicy* default_instance_; +}; +// ------------------------------------------------------------------- + +class Replica : public ::google::protobuf::Message { + public: + Replica(); + virtual ~Replica(); + + Replica(const Replica& from); + + inline Replica& operator=(const Replica& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Replica& default_instance(); + + void Swap(Replica* other); + + // implements Message ---------------------------------------------- + + Replica* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Replica& from); + void MergeFrom(const Replica& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string osd_uuids = 1; + inline int osd_uuids_size() const; + inline void clear_osd_uuids(); + static const int kOsdUuidsFieldNumber = 1; + inline const ::std::string& osd_uuids(int index) const; + inline ::std::string* mutable_osd_uuids(int index); + inline void set_osd_uuids(int index, const ::std::string& value); + inline void set_osd_uuids(int index, const char* value); + inline void set_osd_uuids(int index, const char* value, size_t size); + inline ::std::string* add_osd_uuids(); + inline void add_osd_uuids(const ::std::string& value); + inline void add_osd_uuids(const char* value); + inline void add_osd_uuids(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& osd_uuids() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_osd_uuids(); + + // required fixed32 replication_flags = 2; + inline bool has_replication_flags() const; + inline void clear_replication_flags(); + static const int kReplicationFlagsFieldNumber = 2; + inline ::google::protobuf::uint32 replication_flags() const; + inline void set_replication_flags(::google::protobuf::uint32 value); + + // required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + inline bool has_striping_policy() const; + inline void clear_striping_policy(); + static const int kStripingPolicyFieldNumber = 3; + inline const ::xtreemfs::pbrpc::StripingPolicy& striping_policy() const; + inline ::xtreemfs::pbrpc::StripingPolicy* mutable_striping_policy(); + inline ::xtreemfs::pbrpc::StripingPolicy* release_striping_policy(); + inline void set_allocated_striping_policy(::xtreemfs::pbrpc::StripingPolicy* striping_policy); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Replica) + private: + inline void set_has_replication_flags(); + inline void clear_has_replication_flags(); + inline void set_has_striping_policy(); + inline void clear_has_striping_policy(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::std::string> osd_uuids_; + ::xtreemfs::pbrpc::StripingPolicy* striping_policy_; + ::google::protobuf::uint32 replication_flags_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + + void InitAsDefaultInstance(); + static Replica* default_instance_; +}; +// ------------------------------------------------------------------- + +class Replicas : public ::google::protobuf::Message { + public: + Replicas(); + virtual ~Replicas(); + + Replicas(const Replicas& from); + + inline Replicas& operator=(const Replicas& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Replicas& default_instance(); + + void Swap(Replicas* other); + + // implements Message ---------------------------------------------- + + Replicas* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Replicas& from); + void MergeFrom(const Replicas& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .xtreemfs.pbrpc.Replica replicas = 1; + inline int replicas_size() const; + inline void clear_replicas(); + static const int kReplicasFieldNumber = 1; + inline const ::xtreemfs::pbrpc::Replica& replicas(int index) const; + inline ::xtreemfs::pbrpc::Replica* mutable_replicas(int index); + inline ::xtreemfs::pbrpc::Replica* add_replicas(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Replica >& + replicas() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Replica >* + mutable_replicas(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Replicas) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Replica > replicas_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + + void InitAsDefaultInstance(); + static Replicas* default_instance_; +}; +// ------------------------------------------------------------------- + +class XCap : public ::google::protobuf::Message { + public: + XCap(); + virtual ~XCap(); + + XCap(const XCap& from); + + inline XCap& operator=(const XCap& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const XCap& default_instance(); + + void Swap(XCap* other); + + // implements Message ---------------------------------------------- + + XCap* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const XCap& from); + void MergeFrom(const XCap& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed32 access_mode = 1; + inline bool has_access_mode() const; + inline void clear_access_mode(); + static const int kAccessModeFieldNumber = 1; + inline ::google::protobuf::uint32 access_mode() const; + inline void set_access_mode(::google::protobuf::uint32 value); + + // required string client_identity = 2; + inline bool has_client_identity() const; + inline void clear_client_identity(); + static const int kClientIdentityFieldNumber = 2; + inline const ::std::string& client_identity() const; + inline void set_client_identity(const ::std::string& value); + inline void set_client_identity(const char* value); + inline void set_client_identity(const char* value, size_t size); + inline ::std::string* mutable_client_identity(); + inline ::std::string* release_client_identity(); + inline void set_allocated_client_identity(::std::string* client_identity); + + // required fixed64 expire_time_s = 3; + inline bool has_expire_time_s() const; + inline void clear_expire_time_s(); + static const int kExpireTimeSFieldNumber = 3; + inline ::google::protobuf::uint64 expire_time_s() const; + inline void set_expire_time_s(::google::protobuf::uint64 value); + + // required fixed32 expire_timeout_s = 4; + inline bool has_expire_timeout_s() const; + inline void clear_expire_timeout_s(); + static const int kExpireTimeoutSFieldNumber = 4; + inline ::google::protobuf::uint32 expire_timeout_s() const; + inline void set_expire_timeout_s(::google::protobuf::uint32 value); + + // required string file_id = 5; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 5; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required bool replicate_on_close = 6; + inline bool has_replicate_on_close() const; + inline void clear_replicate_on_close(); + static const int kReplicateOnCloseFieldNumber = 6; + inline bool replicate_on_close() const; + inline void set_replicate_on_close(bool value); + + // required string server_signature = 7; + inline bool has_server_signature() const; + inline void clear_server_signature(); + static const int kServerSignatureFieldNumber = 7; + inline const ::std::string& server_signature() const; + inline void set_server_signature(const ::std::string& value); + inline void set_server_signature(const char* value); + inline void set_server_signature(const char* value, size_t size); + inline ::std::string* mutable_server_signature(); + inline ::std::string* release_server_signature(); + inline void set_allocated_server_signature(::std::string* server_signature); + + // required fixed32 truncate_epoch = 8; + inline bool has_truncate_epoch() const; + inline void clear_truncate_epoch(); + static const int kTruncateEpochFieldNumber = 8; + inline ::google::protobuf::uint32 truncate_epoch() const; + inline void set_truncate_epoch(::google::protobuf::uint32 value); + + // required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + inline bool has_snap_config() const; + inline void clear_snap_config(); + static const int kSnapConfigFieldNumber = 9; + inline ::xtreemfs::pbrpc::SnapConfig snap_config() const; + inline void set_snap_config(::xtreemfs::pbrpc::SnapConfig value); + + // required fixed64 snap_timestamp = 10; + inline bool has_snap_timestamp() const; + inline void clear_snap_timestamp(); + static const int kSnapTimestampFieldNumber = 10; + inline ::google::protobuf::uint64 snap_timestamp() const; + inline void set_snap_timestamp(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.XCap) + private: + inline void set_has_access_mode(); + inline void clear_has_access_mode(); + inline void set_has_client_identity(); + inline void clear_has_client_identity(); + inline void set_has_expire_time_s(); + inline void clear_has_expire_time_s(); + inline void set_has_expire_timeout_s(); + inline void clear_has_expire_timeout_s(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_replicate_on_close(); + inline void clear_has_replicate_on_close(); + inline void set_has_server_signature(); + inline void clear_has_server_signature(); + inline void set_has_truncate_epoch(); + inline void clear_has_truncate_epoch(); + inline void set_has_snap_config(); + inline void clear_has_snap_config(); + inline void set_has_snap_timestamp(); + inline void clear_has_snap_timestamp(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* client_identity_; + ::google::protobuf::uint32 access_mode_; + ::google::protobuf::uint32 expire_timeout_s_; + ::google::protobuf::uint64 expire_time_s_; + ::std::string* file_id_; + ::std::string* server_signature_; + bool replicate_on_close_; + ::google::protobuf::uint32 truncate_epoch_; + ::google::protobuf::uint64 snap_timestamp_; + int snap_config_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(10 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + + void InitAsDefaultInstance(); + static XCap* default_instance_; +}; +// ------------------------------------------------------------------- + +class XLocSet : public ::google::protobuf::Message { + public: + XLocSet(); + virtual ~XLocSet(); + + XLocSet(const XLocSet& from); + + inline XLocSet& operator=(const XLocSet& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const XLocSet& default_instance(); + + void Swap(XLocSet* other); + + // implements Message ---------------------------------------------- + + XLocSet* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const XLocSet& from); + void MergeFrom(const XLocSet& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 read_only_file_size = 1; + inline bool has_read_only_file_size() const; + inline void clear_read_only_file_size(); + static const int kReadOnlyFileSizeFieldNumber = 1; + inline ::google::protobuf::uint64 read_only_file_size() const; + inline void set_read_only_file_size(::google::protobuf::uint64 value); + + // repeated .xtreemfs.pbrpc.Replica replicas = 2; + inline int replicas_size() const; + inline void clear_replicas(); + static const int kReplicasFieldNumber = 2; + inline const ::xtreemfs::pbrpc::Replica& replicas(int index) const; + inline ::xtreemfs::pbrpc::Replica* mutable_replicas(int index); + inline ::xtreemfs::pbrpc::Replica* add_replicas(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Replica >& + replicas() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Replica >* + mutable_replicas(); + + // required string replica_update_policy = 3; + inline bool has_replica_update_policy() const; + inline void clear_replica_update_policy(); + static const int kReplicaUpdatePolicyFieldNumber = 3; + inline const ::std::string& replica_update_policy() const; + inline void set_replica_update_policy(const ::std::string& value); + inline void set_replica_update_policy(const char* value); + inline void set_replica_update_policy(const char* value, size_t size); + inline ::std::string* mutable_replica_update_policy(); + inline ::std::string* release_replica_update_policy(); + inline void set_allocated_replica_update_policy(::std::string* replica_update_policy); + + // required fixed32 version = 4; + inline bool has_version() const; + inline void clear_version(); + static const int kVersionFieldNumber = 4; + inline ::google::protobuf::uint32 version() const; + inline void set_version(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.XLocSet) + private: + inline void set_has_read_only_file_size(); + inline void clear_has_read_only_file_size(); + inline void set_has_replica_update_policy(); + inline void clear_has_replica_update_policy(); + inline void set_has_version(); + inline void clear_has_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 read_only_file_size_; + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Replica > replicas_; + ::std::string* replica_update_policy_; + ::google::protobuf::uint32 version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + + void InitAsDefaultInstance(); + static XLocSet* default_instance_; +}; +// ------------------------------------------------------------------- + +class FileCredentials : public ::google::protobuf::Message { + public: + FileCredentials(); + virtual ~FileCredentials(); + + FileCredentials(const FileCredentials& from); + + inline FileCredentials& operator=(const FileCredentials& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FileCredentials& default_instance(); + + void Swap(FileCredentials* other); + + // implements Message ---------------------------------------------- + + FileCredentials* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FileCredentials& from); + void MergeFrom(const FileCredentials& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.XCap xcap = 1; + inline bool has_xcap() const; + inline void clear_xcap(); + static const int kXcapFieldNumber = 1; + inline const ::xtreemfs::pbrpc::XCap& xcap() const; + inline ::xtreemfs::pbrpc::XCap* mutable_xcap(); + inline ::xtreemfs::pbrpc::XCap* release_xcap(); + inline void set_allocated_xcap(::xtreemfs::pbrpc::XCap* xcap); + + // required .xtreemfs.pbrpc.XLocSet xlocs = 2; + inline bool has_xlocs() const; + inline void clear_xlocs(); + static const int kXlocsFieldNumber = 2; + inline const ::xtreemfs::pbrpc::XLocSet& xlocs() const; + inline ::xtreemfs::pbrpc::XLocSet* mutable_xlocs(); + inline ::xtreemfs::pbrpc::XLocSet* release_xlocs(); + inline void set_allocated_xlocs(::xtreemfs::pbrpc::XLocSet* xlocs); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.FileCredentials) + private: + inline void set_has_xcap(); + inline void clear_has_xcap(); + inline void set_has_xlocs(); + inline void clear_has_xlocs(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::XCap* xcap_; + ::xtreemfs::pbrpc::XLocSet* xlocs_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + + void InitAsDefaultInstance(); + static FileCredentials* default_instance_; +}; +// ------------------------------------------------------------------- + +class FileCredentialsSet : public ::google::protobuf::Message { + public: + FileCredentialsSet(); + virtual ~FileCredentialsSet(); + + FileCredentialsSet(const FileCredentialsSet& from); + + inline FileCredentialsSet& operator=(const FileCredentialsSet& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FileCredentialsSet& default_instance(); + + void Swap(FileCredentialsSet* other); + + // implements Message ---------------------------------------------- + + FileCredentialsSet* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FileCredentialsSet& from); + void MergeFrom(const FileCredentialsSet& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.FileCredentialsSet) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + + void InitAsDefaultInstance(); + static FileCredentialsSet* default_instance_; +}; +// ------------------------------------------------------------------- + +class VivaldiCoordinates : public ::google::protobuf::Message { + public: + VivaldiCoordinates(); + virtual ~VivaldiCoordinates(); + + VivaldiCoordinates(const VivaldiCoordinates& from); + + inline VivaldiCoordinates& operator=(const VivaldiCoordinates& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const VivaldiCoordinates& default_instance(); + + void Swap(VivaldiCoordinates* other); + + // implements Message ---------------------------------------------- + + VivaldiCoordinates* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const VivaldiCoordinates& from); + void MergeFrom(const VivaldiCoordinates& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required double x_coordinate = 1; + inline bool has_x_coordinate() const; + inline void clear_x_coordinate(); + static const int kXCoordinateFieldNumber = 1; + inline double x_coordinate() const; + inline void set_x_coordinate(double value); + + // required double y_coordinate = 2; + inline bool has_y_coordinate() const; + inline void clear_y_coordinate(); + static const int kYCoordinateFieldNumber = 2; + inline double y_coordinate() const; + inline void set_y_coordinate(double value); + + // required double local_error = 3; + inline bool has_local_error() const; + inline void clear_local_error(); + static const int kLocalErrorFieldNumber = 3; + inline double local_error() const; + inline void set_local_error(double value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.VivaldiCoordinates) + private: + inline void set_has_x_coordinate(); + inline void clear_has_x_coordinate(); + inline void set_has_y_coordinate(); + inline void clear_has_y_coordinate(); + inline void set_has_local_error(); + inline void clear_has_local_error(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + double x_coordinate_; + double y_coordinate_; + double local_error_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + + void InitAsDefaultInstance(); + static VivaldiCoordinates* default_instance_; +}; +// ------------------------------------------------------------------- + +class OSDWriteResponse : public ::google::protobuf::Message { + public: + OSDWriteResponse(); + virtual ~OSDWriteResponse(); + + OSDWriteResponse(const OSDWriteResponse& from); + + inline OSDWriteResponse& operator=(const OSDWriteResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const OSDWriteResponse& default_instance(); + + void Swap(OSDWriteResponse* other); + + // implements Message ---------------------------------------------- + + OSDWriteResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const OSDWriteResponse& from); + void MergeFrom(const OSDWriteResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional fixed64 size_in_bytes = 1; + inline bool has_size_in_bytes() const; + inline void clear_size_in_bytes(); + static const int kSizeInBytesFieldNumber = 1; + inline ::google::protobuf::uint64 size_in_bytes() const; + inline void set_size_in_bytes(::google::protobuf::uint64 value); + + // optional fixed32 truncate_epoch = 2; + inline bool has_truncate_epoch() const; + inline void clear_truncate_epoch(); + static const int kTruncateEpochFieldNumber = 2; + inline ::google::protobuf::uint32 truncate_epoch() const; + inline void set_truncate_epoch(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.OSDWriteResponse) + private: + inline void set_has_size_in_bytes(); + inline void clear_has_size_in_bytes(); + inline void set_has_truncate_epoch(); + inline void clear_has_truncate_epoch(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 size_in_bytes_; + ::google::protobuf::uint32 truncate_epoch_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + + void InitAsDefaultInstance(); + static OSDWriteResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class KeyValuePair : public ::google::protobuf::Message { + public: + KeyValuePair(); + virtual ~KeyValuePair(); + + KeyValuePair(const KeyValuePair& from); + + inline KeyValuePair& operator=(const KeyValuePair& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const KeyValuePair& default_instance(); + + void Swap(KeyValuePair* other); + + // implements Message ---------------------------------------------- + + KeyValuePair* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const KeyValuePair& from); + void MergeFrom(const KeyValuePair& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string key = 1; + inline bool has_key() const; + inline void clear_key(); + static const int kKeyFieldNumber = 1; + inline const ::std::string& key() const; + inline void set_key(const ::std::string& value); + inline void set_key(const char* value); + inline void set_key(const char* value, size_t size); + inline ::std::string* mutable_key(); + inline ::std::string* release_key(); + inline void set_allocated_key(::std::string* key); + + // required string value = 2; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 2; + inline const ::std::string& value() const; + inline void set_value(const ::std::string& value); + inline void set_value(const char* value); + inline void set_value(const char* value, size_t size); + inline ::std::string* mutable_value(); + inline ::std::string* release_value(); + inline void set_allocated_value(::std::string* value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.KeyValuePair) + private: + inline void set_has_key(); + inline void clear_has_key(); + inline void set_has_value(); + inline void clear_has_value(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* key_; + ::std::string* value_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fGlobalTypes_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fGlobalTypes_2eproto(); + + void InitAsDefaultInstance(); + static KeyValuePair* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// NewFileSize + +// required fixed64 size_in_bytes = 1; +inline bool NewFileSize::has_size_in_bytes() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void NewFileSize::set_has_size_in_bytes() { + _has_bits_[0] |= 0x00000001u; +} +inline void NewFileSize::clear_has_size_in_bytes() { + _has_bits_[0] &= ~0x00000001u; +} +inline void NewFileSize::clear_size_in_bytes() { + size_in_bytes_ = GOOGLE_ULONGLONG(0); + clear_has_size_in_bytes(); +} +inline ::google::protobuf::uint64 NewFileSize::size_in_bytes() const { + return size_in_bytes_; +} +inline void NewFileSize::set_size_in_bytes(::google::protobuf::uint64 value) { + set_has_size_in_bytes(); + size_in_bytes_ = value; +} + +// required fixed32 truncate_epoch = 2; +inline bool NewFileSize::has_truncate_epoch() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void NewFileSize::set_has_truncate_epoch() { + _has_bits_[0] |= 0x00000002u; +} +inline void NewFileSize::clear_has_truncate_epoch() { + _has_bits_[0] &= ~0x00000002u; +} +inline void NewFileSize::clear_truncate_epoch() { + truncate_epoch_ = 0u; + clear_has_truncate_epoch(); +} +inline ::google::protobuf::uint32 NewFileSize::truncate_epoch() const { + return truncate_epoch_; +} +inline void NewFileSize::set_truncate_epoch(::google::protobuf::uint32 value) { + set_has_truncate_epoch(); + truncate_epoch_ = value; +} + +// ------------------------------------------------------------------- + +// StripingPolicy + +// required .xtreemfs.pbrpc.StripingPolicyType type = 1; +inline bool StripingPolicy::has_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void StripingPolicy::set_has_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void StripingPolicy::clear_has_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void StripingPolicy::clear_type() { + type_ = 0; + clear_has_type(); +} +inline ::xtreemfs::pbrpc::StripingPolicyType StripingPolicy::type() const { + return static_cast< ::xtreemfs::pbrpc::StripingPolicyType >(type_); +} +inline void StripingPolicy::set_type(::xtreemfs::pbrpc::StripingPolicyType value) { + assert(::xtreemfs::pbrpc::StripingPolicyType_IsValid(value)); + set_has_type(); + type_ = value; +} + +// required fixed32 stripe_size = 2; +inline bool StripingPolicy::has_stripe_size() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void StripingPolicy::set_has_stripe_size() { + _has_bits_[0] |= 0x00000002u; +} +inline void StripingPolicy::clear_has_stripe_size() { + _has_bits_[0] &= ~0x00000002u; +} +inline void StripingPolicy::clear_stripe_size() { + stripe_size_ = 0u; + clear_has_stripe_size(); +} +inline ::google::protobuf::uint32 StripingPolicy::stripe_size() const { + return stripe_size_; +} +inline void StripingPolicy::set_stripe_size(::google::protobuf::uint32 value) { + set_has_stripe_size(); + stripe_size_ = value; +} + +// required fixed32 width = 3; +inline bool StripingPolicy::has_width() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void StripingPolicy::set_has_width() { + _has_bits_[0] |= 0x00000004u; +} +inline void StripingPolicy::clear_has_width() { + _has_bits_[0] &= ~0x00000004u; +} +inline void StripingPolicy::clear_width() { + width_ = 0u; + clear_has_width(); +} +inline ::google::protobuf::uint32 StripingPolicy::width() const { + return width_; +} +inline void StripingPolicy::set_width(::google::protobuf::uint32 value) { + set_has_width(); + width_ = value; +} + +// optional fixed32 parity_width = 4; +inline bool StripingPolicy::has_parity_width() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void StripingPolicy::set_has_parity_width() { + _has_bits_[0] |= 0x00000008u; +} +inline void StripingPolicy::clear_has_parity_width() { + _has_bits_[0] &= ~0x00000008u; +} +inline void StripingPolicy::clear_parity_width() { + parity_width_ = 0u; + clear_has_parity_width(); +} +inline ::google::protobuf::uint32 StripingPolicy::parity_width() const { + return parity_width_; +} +inline void StripingPolicy::set_parity_width(::google::protobuf::uint32 value) { + set_has_parity_width(); + parity_width_ = value; +} + +// ------------------------------------------------------------------- + +// Replica + +// repeated string osd_uuids = 1; +inline int Replica::osd_uuids_size() const { + return osd_uuids_.size(); +} +inline void Replica::clear_osd_uuids() { + osd_uuids_.Clear(); +} +inline const ::std::string& Replica::osd_uuids(int index) const { + return osd_uuids_.Get(index); +} +inline ::std::string* Replica::mutable_osd_uuids(int index) { + return osd_uuids_.Mutable(index); +} +inline void Replica::set_osd_uuids(int index, const ::std::string& value) { + osd_uuids_.Mutable(index)->assign(value); +} +inline void Replica::set_osd_uuids(int index, const char* value) { + osd_uuids_.Mutable(index)->assign(value); +} +inline void Replica::set_osd_uuids(int index, const char* value, size_t size) { + osd_uuids_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* Replica::add_osd_uuids() { + return osd_uuids_.Add(); +} +inline void Replica::add_osd_uuids(const ::std::string& value) { + osd_uuids_.Add()->assign(value); +} +inline void Replica::add_osd_uuids(const char* value) { + osd_uuids_.Add()->assign(value); +} +inline void Replica::add_osd_uuids(const char* value, size_t size) { + osd_uuids_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +Replica::osd_uuids() const { + return osd_uuids_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +Replica::mutable_osd_uuids() { + return &osd_uuids_; +} + +// required fixed32 replication_flags = 2; +inline bool Replica::has_replication_flags() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Replica::set_has_replication_flags() { + _has_bits_[0] |= 0x00000002u; +} +inline void Replica::clear_has_replication_flags() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Replica::clear_replication_flags() { + replication_flags_ = 0u; + clear_has_replication_flags(); +} +inline ::google::protobuf::uint32 Replica::replication_flags() const { + return replication_flags_; +} +inline void Replica::set_replication_flags(::google::protobuf::uint32 value) { + set_has_replication_flags(); + replication_flags_ = value; +} + +// required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; +inline bool Replica::has_striping_policy() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Replica::set_has_striping_policy() { + _has_bits_[0] |= 0x00000004u; +} +inline void Replica::clear_has_striping_policy() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Replica::clear_striping_policy() { + if (striping_policy_ != NULL) striping_policy_->::xtreemfs::pbrpc::StripingPolicy::Clear(); + clear_has_striping_policy(); +} +inline const ::xtreemfs::pbrpc::StripingPolicy& Replica::striping_policy() const { + return striping_policy_ != NULL ? *striping_policy_ : *default_instance_->striping_policy_; +} +inline ::xtreemfs::pbrpc::StripingPolicy* Replica::mutable_striping_policy() { + set_has_striping_policy(); + if (striping_policy_ == NULL) striping_policy_ = new ::xtreemfs::pbrpc::StripingPolicy; + return striping_policy_; +} +inline ::xtreemfs::pbrpc::StripingPolicy* Replica::release_striping_policy() { + clear_has_striping_policy(); + ::xtreemfs::pbrpc::StripingPolicy* temp = striping_policy_; + striping_policy_ = NULL; + return temp; +} +inline void Replica::set_allocated_striping_policy(::xtreemfs::pbrpc::StripingPolicy* striping_policy) { + delete striping_policy_; + striping_policy_ = striping_policy; + if (striping_policy) { + set_has_striping_policy(); + } else { + clear_has_striping_policy(); + } +} + +// ------------------------------------------------------------------- + +// Replicas + +// repeated .xtreemfs.pbrpc.Replica replicas = 1; +inline int Replicas::replicas_size() const { + return replicas_.size(); +} +inline void Replicas::clear_replicas() { + replicas_.Clear(); +} +inline const ::xtreemfs::pbrpc::Replica& Replicas::replicas(int index) const { + return replicas_.Get(index); +} +inline ::xtreemfs::pbrpc::Replica* Replicas::mutable_replicas(int index) { + return replicas_.Mutable(index); +} +inline ::xtreemfs::pbrpc::Replica* Replicas::add_replicas() { + return replicas_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Replica >& +Replicas::replicas() const { + return replicas_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Replica >* +Replicas::mutable_replicas() { + return &replicas_; +} + +// ------------------------------------------------------------------- + +// XCap + +// required fixed32 access_mode = 1; +inline bool XCap::has_access_mode() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void XCap::set_has_access_mode() { + _has_bits_[0] |= 0x00000001u; +} +inline void XCap::clear_has_access_mode() { + _has_bits_[0] &= ~0x00000001u; +} +inline void XCap::clear_access_mode() { + access_mode_ = 0u; + clear_has_access_mode(); +} +inline ::google::protobuf::uint32 XCap::access_mode() const { + return access_mode_; +} +inline void XCap::set_access_mode(::google::protobuf::uint32 value) { + set_has_access_mode(); + access_mode_ = value; +} + +// required string client_identity = 2; +inline bool XCap::has_client_identity() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void XCap::set_has_client_identity() { + _has_bits_[0] |= 0x00000002u; +} +inline void XCap::clear_has_client_identity() { + _has_bits_[0] &= ~0x00000002u; +} +inline void XCap::clear_client_identity() { + if (client_identity_ != &::google::protobuf::internal::kEmptyString) { + client_identity_->clear(); + } + clear_has_client_identity(); +} +inline const ::std::string& XCap::client_identity() const { + return *client_identity_; +} +inline void XCap::set_client_identity(const ::std::string& value) { + set_has_client_identity(); + if (client_identity_ == &::google::protobuf::internal::kEmptyString) { + client_identity_ = new ::std::string; + } + client_identity_->assign(value); +} +inline void XCap::set_client_identity(const char* value) { + set_has_client_identity(); + if (client_identity_ == &::google::protobuf::internal::kEmptyString) { + client_identity_ = new ::std::string; + } + client_identity_->assign(value); +} +inline void XCap::set_client_identity(const char* value, size_t size) { + set_has_client_identity(); + if (client_identity_ == &::google::protobuf::internal::kEmptyString) { + client_identity_ = new ::std::string; + } + client_identity_->assign(reinterpret_cast(value), size); +} +inline ::std::string* XCap::mutable_client_identity() { + set_has_client_identity(); + if (client_identity_ == &::google::protobuf::internal::kEmptyString) { + client_identity_ = new ::std::string; + } + return client_identity_; +} +inline ::std::string* XCap::release_client_identity() { + clear_has_client_identity(); + if (client_identity_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = client_identity_; + client_identity_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void XCap::set_allocated_client_identity(::std::string* client_identity) { + if (client_identity_ != &::google::protobuf::internal::kEmptyString) { + delete client_identity_; + } + if (client_identity) { + set_has_client_identity(); + client_identity_ = client_identity; + } else { + clear_has_client_identity(); + client_identity_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 expire_time_s = 3; +inline bool XCap::has_expire_time_s() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void XCap::set_has_expire_time_s() { + _has_bits_[0] |= 0x00000004u; +} +inline void XCap::clear_has_expire_time_s() { + _has_bits_[0] &= ~0x00000004u; +} +inline void XCap::clear_expire_time_s() { + expire_time_s_ = GOOGLE_ULONGLONG(0); + clear_has_expire_time_s(); +} +inline ::google::protobuf::uint64 XCap::expire_time_s() const { + return expire_time_s_; +} +inline void XCap::set_expire_time_s(::google::protobuf::uint64 value) { + set_has_expire_time_s(); + expire_time_s_ = value; +} + +// required fixed32 expire_timeout_s = 4; +inline bool XCap::has_expire_timeout_s() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void XCap::set_has_expire_timeout_s() { + _has_bits_[0] |= 0x00000008u; +} +inline void XCap::clear_has_expire_timeout_s() { + _has_bits_[0] &= ~0x00000008u; +} +inline void XCap::clear_expire_timeout_s() { + expire_timeout_s_ = 0u; + clear_has_expire_timeout_s(); +} +inline ::google::protobuf::uint32 XCap::expire_timeout_s() const { + return expire_timeout_s_; +} +inline void XCap::set_expire_timeout_s(::google::protobuf::uint32 value) { + set_has_expire_timeout_s(); + expire_timeout_s_ = value; +} + +// required string file_id = 5; +inline bool XCap::has_file_id() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void XCap::set_has_file_id() { + _has_bits_[0] |= 0x00000010u; +} +inline void XCap::clear_has_file_id() { + _has_bits_[0] &= ~0x00000010u; +} +inline void XCap::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& XCap::file_id() const { + return *file_id_; +} +inline void XCap::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void XCap::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void XCap::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* XCap::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* XCap::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void XCap::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required bool replicate_on_close = 6; +inline bool XCap::has_replicate_on_close() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void XCap::set_has_replicate_on_close() { + _has_bits_[0] |= 0x00000020u; +} +inline void XCap::clear_has_replicate_on_close() { + _has_bits_[0] &= ~0x00000020u; +} +inline void XCap::clear_replicate_on_close() { + replicate_on_close_ = false; + clear_has_replicate_on_close(); +} +inline bool XCap::replicate_on_close() const { + return replicate_on_close_; +} +inline void XCap::set_replicate_on_close(bool value) { + set_has_replicate_on_close(); + replicate_on_close_ = value; +} + +// required string server_signature = 7; +inline bool XCap::has_server_signature() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void XCap::set_has_server_signature() { + _has_bits_[0] |= 0x00000040u; +} +inline void XCap::clear_has_server_signature() { + _has_bits_[0] &= ~0x00000040u; +} +inline void XCap::clear_server_signature() { + if (server_signature_ != &::google::protobuf::internal::kEmptyString) { + server_signature_->clear(); + } + clear_has_server_signature(); +} +inline const ::std::string& XCap::server_signature() const { + return *server_signature_; +} +inline void XCap::set_server_signature(const ::std::string& value) { + set_has_server_signature(); + if (server_signature_ == &::google::protobuf::internal::kEmptyString) { + server_signature_ = new ::std::string; + } + server_signature_->assign(value); +} +inline void XCap::set_server_signature(const char* value) { + set_has_server_signature(); + if (server_signature_ == &::google::protobuf::internal::kEmptyString) { + server_signature_ = new ::std::string; + } + server_signature_->assign(value); +} +inline void XCap::set_server_signature(const char* value, size_t size) { + set_has_server_signature(); + if (server_signature_ == &::google::protobuf::internal::kEmptyString) { + server_signature_ = new ::std::string; + } + server_signature_->assign(reinterpret_cast(value), size); +} +inline ::std::string* XCap::mutable_server_signature() { + set_has_server_signature(); + if (server_signature_ == &::google::protobuf::internal::kEmptyString) { + server_signature_ = new ::std::string; + } + return server_signature_; +} +inline ::std::string* XCap::release_server_signature() { + clear_has_server_signature(); + if (server_signature_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = server_signature_; + server_signature_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void XCap::set_allocated_server_signature(::std::string* server_signature) { + if (server_signature_ != &::google::protobuf::internal::kEmptyString) { + delete server_signature_; + } + if (server_signature) { + set_has_server_signature(); + server_signature_ = server_signature; + } else { + clear_has_server_signature(); + server_signature_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 truncate_epoch = 8; +inline bool XCap::has_truncate_epoch() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void XCap::set_has_truncate_epoch() { + _has_bits_[0] |= 0x00000080u; +} +inline void XCap::clear_has_truncate_epoch() { + _has_bits_[0] &= ~0x00000080u; +} +inline void XCap::clear_truncate_epoch() { + truncate_epoch_ = 0u; + clear_has_truncate_epoch(); +} +inline ::google::protobuf::uint32 XCap::truncate_epoch() const { + return truncate_epoch_; +} +inline void XCap::set_truncate_epoch(::google::protobuf::uint32 value) { + set_has_truncate_epoch(); + truncate_epoch_ = value; +} + +// required .xtreemfs.pbrpc.SnapConfig snap_config = 9; +inline bool XCap::has_snap_config() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void XCap::set_has_snap_config() { + _has_bits_[0] |= 0x00000100u; +} +inline void XCap::clear_has_snap_config() { + _has_bits_[0] &= ~0x00000100u; +} +inline void XCap::clear_snap_config() { + snap_config_ = 0; + clear_has_snap_config(); +} +inline ::xtreemfs::pbrpc::SnapConfig XCap::snap_config() const { + return static_cast< ::xtreemfs::pbrpc::SnapConfig >(snap_config_); +} +inline void XCap::set_snap_config(::xtreemfs::pbrpc::SnapConfig value) { + assert(::xtreemfs::pbrpc::SnapConfig_IsValid(value)); + set_has_snap_config(); + snap_config_ = value; +} + +// required fixed64 snap_timestamp = 10; +inline bool XCap::has_snap_timestamp() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void XCap::set_has_snap_timestamp() { + _has_bits_[0] |= 0x00000200u; +} +inline void XCap::clear_has_snap_timestamp() { + _has_bits_[0] &= ~0x00000200u; +} +inline void XCap::clear_snap_timestamp() { + snap_timestamp_ = GOOGLE_ULONGLONG(0); + clear_has_snap_timestamp(); +} +inline ::google::protobuf::uint64 XCap::snap_timestamp() const { + return snap_timestamp_; +} +inline void XCap::set_snap_timestamp(::google::protobuf::uint64 value) { + set_has_snap_timestamp(); + snap_timestamp_ = value; +} + +// ------------------------------------------------------------------- + +// XLocSet + +// required fixed64 read_only_file_size = 1; +inline bool XLocSet::has_read_only_file_size() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void XLocSet::set_has_read_only_file_size() { + _has_bits_[0] |= 0x00000001u; +} +inline void XLocSet::clear_has_read_only_file_size() { + _has_bits_[0] &= ~0x00000001u; +} +inline void XLocSet::clear_read_only_file_size() { + read_only_file_size_ = GOOGLE_ULONGLONG(0); + clear_has_read_only_file_size(); +} +inline ::google::protobuf::uint64 XLocSet::read_only_file_size() const { + return read_only_file_size_; +} +inline void XLocSet::set_read_only_file_size(::google::protobuf::uint64 value) { + set_has_read_only_file_size(); + read_only_file_size_ = value; +} + +// repeated .xtreemfs.pbrpc.Replica replicas = 2; +inline int XLocSet::replicas_size() const { + return replicas_.size(); +} +inline void XLocSet::clear_replicas() { + replicas_.Clear(); +} +inline const ::xtreemfs::pbrpc::Replica& XLocSet::replicas(int index) const { + return replicas_.Get(index); +} +inline ::xtreemfs::pbrpc::Replica* XLocSet::mutable_replicas(int index) { + return replicas_.Mutable(index); +} +inline ::xtreemfs::pbrpc::Replica* XLocSet::add_replicas() { + return replicas_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Replica >& +XLocSet::replicas() const { + return replicas_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Replica >* +XLocSet::mutable_replicas() { + return &replicas_; +} + +// required string replica_update_policy = 3; +inline bool XLocSet::has_replica_update_policy() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void XLocSet::set_has_replica_update_policy() { + _has_bits_[0] |= 0x00000004u; +} +inline void XLocSet::clear_has_replica_update_policy() { + _has_bits_[0] &= ~0x00000004u; +} +inline void XLocSet::clear_replica_update_policy() { + if (replica_update_policy_ != &::google::protobuf::internal::kEmptyString) { + replica_update_policy_->clear(); + } + clear_has_replica_update_policy(); +} +inline const ::std::string& XLocSet::replica_update_policy() const { + return *replica_update_policy_; +} +inline void XLocSet::set_replica_update_policy(const ::std::string& value) { + set_has_replica_update_policy(); + if (replica_update_policy_ == &::google::protobuf::internal::kEmptyString) { + replica_update_policy_ = new ::std::string; + } + replica_update_policy_->assign(value); +} +inline void XLocSet::set_replica_update_policy(const char* value) { + set_has_replica_update_policy(); + if (replica_update_policy_ == &::google::protobuf::internal::kEmptyString) { + replica_update_policy_ = new ::std::string; + } + replica_update_policy_->assign(value); +} +inline void XLocSet::set_replica_update_policy(const char* value, size_t size) { + set_has_replica_update_policy(); + if (replica_update_policy_ == &::google::protobuf::internal::kEmptyString) { + replica_update_policy_ = new ::std::string; + } + replica_update_policy_->assign(reinterpret_cast(value), size); +} +inline ::std::string* XLocSet::mutable_replica_update_policy() { + set_has_replica_update_policy(); + if (replica_update_policy_ == &::google::protobuf::internal::kEmptyString) { + replica_update_policy_ = new ::std::string; + } + return replica_update_policy_; +} +inline ::std::string* XLocSet::release_replica_update_policy() { + clear_has_replica_update_policy(); + if (replica_update_policy_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = replica_update_policy_; + replica_update_policy_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void XLocSet::set_allocated_replica_update_policy(::std::string* replica_update_policy) { + if (replica_update_policy_ != &::google::protobuf::internal::kEmptyString) { + delete replica_update_policy_; + } + if (replica_update_policy) { + set_has_replica_update_policy(); + replica_update_policy_ = replica_update_policy; + } else { + clear_has_replica_update_policy(); + replica_update_policy_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 version = 4; +inline bool XLocSet::has_version() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void XLocSet::set_has_version() { + _has_bits_[0] |= 0x00000008u; +} +inline void XLocSet::clear_has_version() { + _has_bits_[0] &= ~0x00000008u; +} +inline void XLocSet::clear_version() { + version_ = 0u; + clear_has_version(); +} +inline ::google::protobuf::uint32 XLocSet::version() const { + return version_; +} +inline void XLocSet::set_version(::google::protobuf::uint32 value) { + set_has_version(); + version_ = value; +} + +// ------------------------------------------------------------------- + +// FileCredentials + +// required .xtreemfs.pbrpc.XCap xcap = 1; +inline bool FileCredentials::has_xcap() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FileCredentials::set_has_xcap() { + _has_bits_[0] |= 0x00000001u; +} +inline void FileCredentials::clear_has_xcap() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FileCredentials::clear_xcap() { + if (xcap_ != NULL) xcap_->::xtreemfs::pbrpc::XCap::Clear(); + clear_has_xcap(); +} +inline const ::xtreemfs::pbrpc::XCap& FileCredentials::xcap() const { + return xcap_ != NULL ? *xcap_ : *default_instance_->xcap_; +} +inline ::xtreemfs::pbrpc::XCap* FileCredentials::mutable_xcap() { + set_has_xcap(); + if (xcap_ == NULL) xcap_ = new ::xtreemfs::pbrpc::XCap; + return xcap_; +} +inline ::xtreemfs::pbrpc::XCap* FileCredentials::release_xcap() { + clear_has_xcap(); + ::xtreemfs::pbrpc::XCap* temp = xcap_; + xcap_ = NULL; + return temp; +} +inline void FileCredentials::set_allocated_xcap(::xtreemfs::pbrpc::XCap* xcap) { + delete xcap_; + xcap_ = xcap; + if (xcap) { + set_has_xcap(); + } else { + clear_has_xcap(); + } +} + +// required .xtreemfs.pbrpc.XLocSet xlocs = 2; +inline bool FileCredentials::has_xlocs() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FileCredentials::set_has_xlocs() { + _has_bits_[0] |= 0x00000002u; +} +inline void FileCredentials::clear_has_xlocs() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FileCredentials::clear_xlocs() { + if (xlocs_ != NULL) xlocs_->::xtreemfs::pbrpc::XLocSet::Clear(); + clear_has_xlocs(); +} +inline const ::xtreemfs::pbrpc::XLocSet& FileCredentials::xlocs() const { + return xlocs_ != NULL ? *xlocs_ : *default_instance_->xlocs_; +} +inline ::xtreemfs::pbrpc::XLocSet* FileCredentials::mutable_xlocs() { + set_has_xlocs(); + if (xlocs_ == NULL) xlocs_ = new ::xtreemfs::pbrpc::XLocSet; + return xlocs_; +} +inline ::xtreemfs::pbrpc::XLocSet* FileCredentials::release_xlocs() { + clear_has_xlocs(); + ::xtreemfs::pbrpc::XLocSet* temp = xlocs_; + xlocs_ = NULL; + return temp; +} +inline void FileCredentials::set_allocated_xlocs(::xtreemfs::pbrpc::XLocSet* xlocs) { + delete xlocs_; + xlocs_ = xlocs; + if (xlocs) { + set_has_xlocs(); + } else { + clear_has_xlocs(); + } +} + +// ------------------------------------------------------------------- + +// FileCredentialsSet + +// optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool FileCredentialsSet::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FileCredentialsSet::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void FileCredentialsSet::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FileCredentialsSet::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& FileCredentialsSet::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* FileCredentialsSet::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* FileCredentialsSet::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void FileCredentialsSet::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// ------------------------------------------------------------------- + +// VivaldiCoordinates + +// required double x_coordinate = 1; +inline bool VivaldiCoordinates::has_x_coordinate() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void VivaldiCoordinates::set_has_x_coordinate() { + _has_bits_[0] |= 0x00000001u; +} +inline void VivaldiCoordinates::clear_has_x_coordinate() { + _has_bits_[0] &= ~0x00000001u; +} +inline void VivaldiCoordinates::clear_x_coordinate() { + x_coordinate_ = 0; + clear_has_x_coordinate(); +} +inline double VivaldiCoordinates::x_coordinate() const { + return x_coordinate_; +} +inline void VivaldiCoordinates::set_x_coordinate(double value) { + set_has_x_coordinate(); + x_coordinate_ = value; +} + +// required double y_coordinate = 2; +inline bool VivaldiCoordinates::has_y_coordinate() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void VivaldiCoordinates::set_has_y_coordinate() { + _has_bits_[0] |= 0x00000002u; +} +inline void VivaldiCoordinates::clear_has_y_coordinate() { + _has_bits_[0] &= ~0x00000002u; +} +inline void VivaldiCoordinates::clear_y_coordinate() { + y_coordinate_ = 0; + clear_has_y_coordinate(); +} +inline double VivaldiCoordinates::y_coordinate() const { + return y_coordinate_; +} +inline void VivaldiCoordinates::set_y_coordinate(double value) { + set_has_y_coordinate(); + y_coordinate_ = value; +} + +// required double local_error = 3; +inline bool VivaldiCoordinates::has_local_error() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void VivaldiCoordinates::set_has_local_error() { + _has_bits_[0] |= 0x00000004u; +} +inline void VivaldiCoordinates::clear_has_local_error() { + _has_bits_[0] &= ~0x00000004u; +} +inline void VivaldiCoordinates::clear_local_error() { + local_error_ = 0; + clear_has_local_error(); +} +inline double VivaldiCoordinates::local_error() const { + return local_error_; +} +inline void VivaldiCoordinates::set_local_error(double value) { + set_has_local_error(); + local_error_ = value; +} + +// ------------------------------------------------------------------- + +// OSDWriteResponse + +// optional fixed64 size_in_bytes = 1; +inline bool OSDWriteResponse::has_size_in_bytes() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void OSDWriteResponse::set_has_size_in_bytes() { + _has_bits_[0] |= 0x00000001u; +} +inline void OSDWriteResponse::clear_has_size_in_bytes() { + _has_bits_[0] &= ~0x00000001u; +} +inline void OSDWriteResponse::clear_size_in_bytes() { + size_in_bytes_ = GOOGLE_ULONGLONG(0); + clear_has_size_in_bytes(); +} +inline ::google::protobuf::uint64 OSDWriteResponse::size_in_bytes() const { + return size_in_bytes_; +} +inline void OSDWriteResponse::set_size_in_bytes(::google::protobuf::uint64 value) { + set_has_size_in_bytes(); + size_in_bytes_ = value; +} + +// optional fixed32 truncate_epoch = 2; +inline bool OSDWriteResponse::has_truncate_epoch() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void OSDWriteResponse::set_has_truncate_epoch() { + _has_bits_[0] |= 0x00000002u; +} +inline void OSDWriteResponse::clear_has_truncate_epoch() { + _has_bits_[0] &= ~0x00000002u; +} +inline void OSDWriteResponse::clear_truncate_epoch() { + truncate_epoch_ = 0u; + clear_has_truncate_epoch(); +} +inline ::google::protobuf::uint32 OSDWriteResponse::truncate_epoch() const { + return truncate_epoch_; +} +inline void OSDWriteResponse::set_truncate_epoch(::google::protobuf::uint32 value) { + set_has_truncate_epoch(); + truncate_epoch_ = value; +} + +// ------------------------------------------------------------------- + +// KeyValuePair + +// required string key = 1; +inline bool KeyValuePair::has_key() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void KeyValuePair::set_has_key() { + _has_bits_[0] |= 0x00000001u; +} +inline void KeyValuePair::clear_has_key() { + _has_bits_[0] &= ~0x00000001u; +} +inline void KeyValuePair::clear_key() { + if (key_ != &::google::protobuf::internal::kEmptyString) { + key_->clear(); + } + clear_has_key(); +} +inline const ::std::string& KeyValuePair::key() const { + return *key_; +} +inline void KeyValuePair::set_key(const ::std::string& value) { + set_has_key(); + if (key_ == &::google::protobuf::internal::kEmptyString) { + key_ = new ::std::string; + } + key_->assign(value); +} +inline void KeyValuePair::set_key(const char* value) { + set_has_key(); + if (key_ == &::google::protobuf::internal::kEmptyString) { + key_ = new ::std::string; + } + key_->assign(value); +} +inline void KeyValuePair::set_key(const char* value, size_t size) { + set_has_key(); + if (key_ == &::google::protobuf::internal::kEmptyString) { + key_ = new ::std::string; + } + key_->assign(reinterpret_cast(value), size); +} +inline ::std::string* KeyValuePair::mutable_key() { + set_has_key(); + if (key_ == &::google::protobuf::internal::kEmptyString) { + key_ = new ::std::string; + } + return key_; +} +inline ::std::string* KeyValuePair::release_key() { + clear_has_key(); + if (key_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = key_; + key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void KeyValuePair::set_allocated_key(::std::string* key) { + if (key_ != &::google::protobuf::internal::kEmptyString) { + delete key_; + } + if (key) { + set_has_key(); + key_ = key; + } else { + clear_has_key(); + key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string value = 2; +inline bool KeyValuePair::has_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void KeyValuePair::set_has_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void KeyValuePair::clear_has_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void KeyValuePair::clear_value() { + if (value_ != &::google::protobuf::internal::kEmptyString) { + value_->clear(); + } + clear_has_value(); +} +inline const ::std::string& KeyValuePair::value() const { + return *value_; +} +inline void KeyValuePair::set_value(const ::std::string& value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(value); +} +inline void KeyValuePair::set_value(const char* value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(value); +} +inline void KeyValuePair::set_value(const char* value, size_t size) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(reinterpret_cast(value), size); +} +inline ::std::string* KeyValuePair::mutable_value() { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + return value_; +} +inline ::std::string* KeyValuePair::release_value() { + clear_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = value_; + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void KeyValuePair::set_allocated_value(::std::string* value) { + if (value_ != &::google::protobuf::internal::kEmptyString) { + delete value_; + } + if (value) { + set_has_value(); + value_ = value; + } else { + clear_has_value(); + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::AccessControlPolicyType>() { + return ::xtreemfs::pbrpc::AccessControlPolicyType_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::OSDSelectionPolicyType>() { + return ::xtreemfs::pbrpc::OSDSelectionPolicyType_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::ReplicaSelectionPolicyType>() { + return ::xtreemfs::pbrpc::ReplicaSelectionPolicyType_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::SnapConfig>() { + return ::xtreemfs::pbrpc::SnapConfig_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::StripingPolicyType>() { + return ::xtreemfs::pbrpc::StripingPolicyType_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::LeaseState>() { + return ::xtreemfs::pbrpc::LeaseState_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::PORTS>() { + return ::xtreemfs::pbrpc::PORTS_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::CONSTANTS>() { + return ::xtreemfs::pbrpc::CONSTANTS_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::SYSTEM_V_FCNTL>() { + return ::xtreemfs::pbrpc::SYSTEM_V_FCNTL_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::REPL_FLAG>() { + return ::xtreemfs::pbrpc::REPL_FLAG_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::SERVICES>() { + return ::xtreemfs::pbrpc::SERVICES_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_xtreemfs_2fGlobalTypes_2eproto__INCLUDED diff --git a/cpp/generated/xtreemfs/MRC.pb.cc b/cpp/generated/xtreemfs/MRC.pb.cc new file mode 100644 index 0000000..6a9898f --- /dev/null +++ b/cpp/generated/xtreemfs/MRC.pb.cc @@ -0,0 +1,18740 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/MRC.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "xtreemfs/MRC.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +namespace { + +const ::google::protobuf::Descriptor* Stat_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Stat_reflection_ = NULL; +const ::google::protobuf::Descriptor* DirectoryEntry_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + DirectoryEntry_reflection_ = NULL; +const ::google::protobuf::Descriptor* DirectoryEntries_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + DirectoryEntries_reflection_ = NULL; +const ::google::protobuf::Descriptor* XAttr_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + XAttr_reflection_ = NULL; +const ::google::protobuf::Descriptor* Volume_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Volume_reflection_ = NULL; +const ::google::protobuf::Descriptor* Volumes_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Volumes_reflection_ = NULL; +const ::google::protobuf::Descriptor* StatVFS_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + StatVFS_reflection_ = NULL; +const ::google::protobuf::Descriptor* fsetattrRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + fsetattrRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* getattrRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + getattrRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* getattrResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + getattrResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* getxattrRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + getxattrRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* getxattrResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + getxattrResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* linkRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + linkRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* listxattrRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + listxattrRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* listxattrResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + listxattrResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* mkdirRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + mkdirRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* openRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + openRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* openResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + openResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* readdirRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + readdirRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* readlinkRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + readlinkRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* readlinkResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + readlinkResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* removexattrRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + removexattrRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* renameRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + renameRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* renameResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + renameResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* rmdirRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + rmdirRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* setattrRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + setattrRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* setxattrRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + setxattrRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* statvfsRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + statvfsRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* symlinkRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + symlinkRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* unlinkRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + unlinkRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* unlinkResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + unlinkResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* accessRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + accessRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_check_file_existsRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_check_file_existsRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_check_file_existsResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_check_file_existsResponse_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* xtreemfs_check_file_existsResponse_FILE_STATE_descriptor_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_dump_restore_databaseRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_dump_restore_databaseRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_get_suitable_osdsRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_get_suitable_osdsRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_get_suitable_osdsResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_get_suitable_osdsResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* timestampResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + timestampResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* stringMessage_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + stringMessage_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_listdirRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_listdirRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_listdirResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_listdirResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_replica_addRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_replica_addRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_replica_listRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_replica_listRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_get_xlocsetRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_get_xlocsetRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_replica_removeRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_replica_removeRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_restore_fileRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_restore_fileRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_rmvolRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_rmvolRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_update_file_sizeRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_update_file_sizeRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_set_replica_update_policyRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_set_replica_update_policyRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_set_replica_update_policyResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_set_replica_update_policyResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_set_read_only_xattrRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_set_read_only_xattrRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_set_read_only_xattrResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_set_read_only_xattrResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_get_file_credentialsRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_get_file_credentialsRequest_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* Setattrs_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* XATTR_FLAGS_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ACCESS_FLAGS_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto() { + protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "xtreemfs/MRC.proto"); + GOOGLE_CHECK(file != NULL); + Stat_descriptor_ = file->message_type(0); + static const int Stat_offsets_[14] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, dev_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, ino_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, mode_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, nlink_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, user_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, group_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, atime_ns_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, mtime_ns_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, ctime_ns_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, blksize_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, etag_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, truncate_epoch_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, attributes_), + }; + Stat_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Stat_descriptor_, + Stat::default_instance_, + Stat_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Stat, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Stat)); + DirectoryEntry_descriptor_ = file->message_type(1); + static const int DirectoryEntry_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirectoryEntry, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirectoryEntry, stbuf_), + }; + DirectoryEntry_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + DirectoryEntry_descriptor_, + DirectoryEntry::default_instance_, + DirectoryEntry_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirectoryEntry, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirectoryEntry, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(DirectoryEntry)); + DirectoryEntries_descriptor_ = file->message_type(2); + static const int DirectoryEntries_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirectoryEntries, entries_), + }; + DirectoryEntries_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + DirectoryEntries_descriptor_, + DirectoryEntries::default_instance_, + DirectoryEntries_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirectoryEntries, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DirectoryEntries, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(DirectoryEntries)); + XAttr_descriptor_ = file->message_type(3); + static const int XAttr_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XAttr, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XAttr, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XAttr, value_bytes_string_), + }; + XAttr_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + XAttr_descriptor_, + XAttr::default_instance_, + XAttr_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XAttr, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XAttr, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(XAttr)); + Volume_descriptor_ = file->message_type(4); + static const int Volume_offsets_[9] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volume, access_control_policy_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volume, default_striping_policy_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volume, id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volume, mode_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volume, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volume, owner_group_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volume, owner_user_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volume, attrs_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volume, quota_), + }; + Volume_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Volume_descriptor_, + Volume::default_instance_, + Volume_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volume, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volume, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Volume)); + Volumes_descriptor_ = file->message_type(5); + static const int Volumes_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volumes, volumes_), + }; + Volumes_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Volumes_descriptor_, + Volumes::default_instance_, + Volumes_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volumes, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Volumes, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Volumes)); + StatVFS_descriptor_ = file->message_type(6); + static const int StatVFS_offsets_[13] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, bsize_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, bavail_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, bfree_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, blocks_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, fsid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, namemax_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, access_control_policy_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, default_striping_policy_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, etag_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, mode_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, owner_group_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, owner_user_id_), + }; + StatVFS_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + StatVFS_descriptor_, + StatVFS::default_instance_, + StatVFS_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StatVFS, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(StatVFS)); + fsetattrRequest_descriptor_ = file->message_type(7); + static const int fsetattrRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(fsetattrRequest, stbuf_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(fsetattrRequest, to_set_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(fsetattrRequest, cap_), + }; + fsetattrRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + fsetattrRequest_descriptor_, + fsetattrRequest::default_instance_, + fsetattrRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(fsetattrRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(fsetattrRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(fsetattrRequest)); + getattrRequest_descriptor_ = file->message_type(8); + static const int getattrRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getattrRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getattrRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getattrRequest, known_etag_), + }; + getattrRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + getattrRequest_descriptor_, + getattrRequest::default_instance_, + getattrRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getattrRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getattrRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(getattrRequest)); + getattrResponse_descriptor_ = file->message_type(9); + static const int getattrResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getattrResponse, stbuf_), + }; + getattrResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + getattrResponse_descriptor_, + getattrResponse::default_instance_, + getattrResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getattrResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getattrResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(getattrResponse)); + getxattrRequest_descriptor_ = file->message_type(10); + static const int getxattrRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getxattrRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getxattrRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getxattrRequest, name_), + }; + getxattrRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + getxattrRequest_descriptor_, + getxattrRequest::default_instance_, + getxattrRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getxattrRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getxattrRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(getxattrRequest)); + getxattrResponse_descriptor_ = file->message_type(11); + static const int getxattrResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getxattrResponse, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getxattrResponse, value_bytes_string_), + }; + getxattrResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + getxattrResponse_descriptor_, + getxattrResponse::default_instance_, + getxattrResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getxattrResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(getxattrResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(getxattrResponse)); + linkRequest_descriptor_ = file->message_type(12); + static const int linkRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(linkRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(linkRequest, target_path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(linkRequest, link_path_), + }; + linkRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + linkRequest_descriptor_, + linkRequest::default_instance_, + linkRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(linkRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(linkRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(linkRequest)); + listxattrRequest_descriptor_ = file->message_type(13); + static const int listxattrRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(listxattrRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(listxattrRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(listxattrRequest, names_only_), + }; + listxattrRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + listxattrRequest_descriptor_, + listxattrRequest::default_instance_, + listxattrRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(listxattrRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(listxattrRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(listxattrRequest)); + listxattrResponse_descriptor_ = file->message_type(14); + static const int listxattrResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(listxattrResponse, xattrs_), + }; + listxattrResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + listxattrResponse_descriptor_, + listxattrResponse::default_instance_, + listxattrResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(listxattrResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(listxattrResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(listxattrResponse)); + mkdirRequest_descriptor_ = file->message_type(15); + static const int mkdirRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(mkdirRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(mkdirRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(mkdirRequest, mode_), + }; + mkdirRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + mkdirRequest_descriptor_, + mkdirRequest::default_instance_, + mkdirRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(mkdirRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(mkdirRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(mkdirRequest)); + openRequest_descriptor_ = file->message_type(16); + static const int openRequest_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openRequest, flags_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openRequest, mode_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openRequest, attributes_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openRequest, coordinates_), + }; + openRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + openRequest_descriptor_, + openRequest::default_instance_, + openRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(openRequest)); + openResponse_descriptor_ = file->message_type(17); + static const int openResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openResponse, creds_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openResponse, timestamp_s_), + }; + openResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + openResponse_descriptor_, + openResponse::default_instance_, + openResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(openResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(openResponse)); + readdirRequest_descriptor_ = file->message_type(18); + static const int readdirRequest_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readdirRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readdirRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readdirRequest, known_etag_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readdirRequest, limit_directory_entries_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readdirRequest, names_only_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readdirRequest, seen_directory_entries_count_), + }; + readdirRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + readdirRequest_descriptor_, + readdirRequest::default_instance_, + readdirRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readdirRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readdirRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(readdirRequest)); + readlinkRequest_descriptor_ = file->message_type(19); + static const int readlinkRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readlinkRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readlinkRequest, path_), + }; + readlinkRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + readlinkRequest_descriptor_, + readlinkRequest::default_instance_, + readlinkRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readlinkRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readlinkRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(readlinkRequest)); + readlinkResponse_descriptor_ = file->message_type(20); + static const int readlinkResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readlinkResponse, link_target_path_), + }; + readlinkResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + readlinkResponse_descriptor_, + readlinkResponse::default_instance_, + readlinkResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readlinkResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readlinkResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(readlinkResponse)); + removexattrRequest_descriptor_ = file->message_type(21); + static const int removexattrRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(removexattrRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(removexattrRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(removexattrRequest, name_), + }; + removexattrRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + removexattrRequest_descriptor_, + removexattrRequest::default_instance_, + removexattrRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(removexattrRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(removexattrRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(removexattrRequest)); + renameRequest_descriptor_ = file->message_type(22); + static const int renameRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(renameRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(renameRequest, source_path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(renameRequest, target_path_), + }; + renameRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + renameRequest_descriptor_, + renameRequest::default_instance_, + renameRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(renameRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(renameRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(renameRequest)); + renameResponse_descriptor_ = file->message_type(23); + static const int renameResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(renameResponse, timestamp_s_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(renameResponse, creds_), + }; + renameResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + renameResponse_descriptor_, + renameResponse::default_instance_, + renameResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(renameResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(renameResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(renameResponse)); + rmdirRequest_descriptor_ = file->message_type(24); + static const int rmdirRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(rmdirRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(rmdirRequest, path_), + }; + rmdirRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + rmdirRequest_descriptor_, + rmdirRequest::default_instance_, + rmdirRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(rmdirRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(rmdirRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(rmdirRequest)); + setattrRequest_descriptor_ = file->message_type(25); + static const int setattrRequest_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setattrRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setattrRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setattrRequest, stbuf_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setattrRequest, to_set_), + }; + setattrRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + setattrRequest_descriptor_, + setattrRequest::default_instance_, + setattrRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setattrRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setattrRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(setattrRequest)); + setxattrRequest_descriptor_ = file->message_type(26); + static const int setxattrRequest_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setxattrRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setxattrRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setxattrRequest, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setxattrRequest, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setxattrRequest, value_bytes_string_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setxattrRequest, flags_), + }; + setxattrRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + setxattrRequest_descriptor_, + setxattrRequest::default_instance_, + setxattrRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setxattrRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(setxattrRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(setxattrRequest)); + statvfsRequest_descriptor_ = file->message_type(27); + static const int statvfsRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(statvfsRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(statvfsRequest, known_etag_), + }; + statvfsRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + statvfsRequest_descriptor_, + statvfsRequest::default_instance_, + statvfsRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(statvfsRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(statvfsRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(statvfsRequest)); + symlinkRequest_descriptor_ = file->message_type(28); + static const int symlinkRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(symlinkRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(symlinkRequest, target_path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(symlinkRequest, link_path_), + }; + symlinkRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + symlinkRequest_descriptor_, + symlinkRequest::default_instance_, + symlinkRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(symlinkRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(symlinkRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(symlinkRequest)); + unlinkRequest_descriptor_ = file->message_type(29); + static const int unlinkRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlinkRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlinkRequest, path_), + }; + unlinkRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + unlinkRequest_descriptor_, + unlinkRequest::default_instance_, + unlinkRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlinkRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlinkRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(unlinkRequest)); + unlinkResponse_descriptor_ = file->message_type(30); + static const int unlinkResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlinkResponse, timestamp_s_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlinkResponse, creds_), + }; + unlinkResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + unlinkResponse_descriptor_, + unlinkResponse::default_instance_, + unlinkResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlinkResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlinkResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(unlinkResponse)); + accessRequest_descriptor_ = file->message_type(31); + static const int accessRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(accessRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(accessRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(accessRequest, flags_), + }; + accessRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + accessRequest_descriptor_, + accessRequest::default_instance_, + accessRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(accessRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(accessRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(accessRequest)); + xtreemfs_check_file_existsRequest_descriptor_ = file->message_type(32); + static const int xtreemfs_check_file_existsRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_file_existsRequest, volume_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_file_existsRequest, file_ids_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_file_existsRequest, osd_uuid_), + }; + xtreemfs_check_file_existsRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_check_file_existsRequest_descriptor_, + xtreemfs_check_file_existsRequest::default_instance_, + xtreemfs_check_file_existsRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_file_existsRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_file_existsRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_check_file_existsRequest)); + xtreemfs_check_file_existsResponse_descriptor_ = file->message_type(33); + static const int xtreemfs_check_file_existsResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_file_existsResponse, volume_exists_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_file_existsResponse, file_states_), + }; + xtreemfs_check_file_existsResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_check_file_existsResponse_descriptor_, + xtreemfs_check_file_existsResponse::default_instance_, + xtreemfs_check_file_existsResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_file_existsResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_file_existsResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_check_file_existsResponse)); + xtreemfs_check_file_existsResponse_FILE_STATE_descriptor_ = xtreemfs_check_file_existsResponse_descriptor_->enum_type(0); + xtreemfs_dump_restore_databaseRequest_descriptor_ = file->message_type(34); + static const int xtreemfs_dump_restore_databaseRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_dump_restore_databaseRequest, dump_file_), + }; + xtreemfs_dump_restore_databaseRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_dump_restore_databaseRequest_descriptor_, + xtreemfs_dump_restore_databaseRequest::default_instance_, + xtreemfs_dump_restore_databaseRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_dump_restore_databaseRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_dump_restore_databaseRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_dump_restore_databaseRequest)); + xtreemfs_get_suitable_osdsRequest_descriptor_ = file->message_type(35); + static const int xtreemfs_get_suitable_osdsRequest_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_suitable_osdsRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_suitable_osdsRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_suitable_osdsRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_suitable_osdsRequest, num_osds_), + }; + xtreemfs_get_suitable_osdsRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_get_suitable_osdsRequest_descriptor_, + xtreemfs_get_suitable_osdsRequest::default_instance_, + xtreemfs_get_suitable_osdsRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_suitable_osdsRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_suitable_osdsRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_get_suitable_osdsRequest)); + xtreemfs_get_suitable_osdsResponse_descriptor_ = file->message_type(36); + static const int xtreemfs_get_suitable_osdsResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_suitable_osdsResponse, osd_uuids_), + }; + xtreemfs_get_suitable_osdsResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_get_suitable_osdsResponse_descriptor_, + xtreemfs_get_suitable_osdsResponse::default_instance_, + xtreemfs_get_suitable_osdsResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_suitable_osdsResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_suitable_osdsResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_get_suitable_osdsResponse)); + timestampResponse_descriptor_ = file->message_type(37); + static const int timestampResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(timestampResponse, timestamp_s_), + }; + timestampResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + timestampResponse_descriptor_, + timestampResponse::default_instance_, + timestampResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(timestampResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(timestampResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(timestampResponse)); + stringMessage_descriptor_ = file->message_type(38); + static const int stringMessage_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(stringMessage, a_string_), + }; + stringMessage_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + stringMessage_descriptor_, + stringMessage::default_instance_, + stringMessage_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(stringMessage, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(stringMessage, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(stringMessage)); + xtreemfs_listdirRequest_descriptor_ = file->message_type(39); + static const int xtreemfs_listdirRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_listdirRequest, path_), + }; + xtreemfs_listdirRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_listdirRequest_descriptor_, + xtreemfs_listdirRequest::default_instance_, + xtreemfs_listdirRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_listdirRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_listdirRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_listdirRequest)); + xtreemfs_listdirResponse_descriptor_ = file->message_type(40); + static const int xtreemfs_listdirResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_listdirResponse, names_), + }; + xtreemfs_listdirResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_listdirResponse_descriptor_, + xtreemfs_listdirResponse::default_instance_, + xtreemfs_listdirResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_listdirResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_listdirResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_listdirResponse)); + xtreemfs_replica_addRequest_descriptor_ = file->message_type(41); + static const int xtreemfs_replica_addRequest_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_addRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_addRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_addRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_addRequest, new_replica_), + }; + xtreemfs_replica_addRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_replica_addRequest_descriptor_, + xtreemfs_replica_addRequest::default_instance_, + xtreemfs_replica_addRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_addRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_addRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_replica_addRequest)); + xtreemfs_replica_listRequest_descriptor_ = file->message_type(42); + static const int xtreemfs_replica_listRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_listRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_listRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_listRequest, volume_name_), + }; + xtreemfs_replica_listRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_replica_listRequest_descriptor_, + xtreemfs_replica_listRequest::default_instance_, + xtreemfs_replica_listRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_listRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_listRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_replica_listRequest)); + xtreemfs_get_xlocsetRequest_descriptor_ = file->message_type(43); + static const int xtreemfs_get_xlocsetRequest_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_xlocsetRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_xlocsetRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_xlocsetRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_xlocsetRequest, xcap_), + }; + xtreemfs_get_xlocsetRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_get_xlocsetRequest_descriptor_, + xtreemfs_get_xlocsetRequest::default_instance_, + xtreemfs_get_xlocsetRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_xlocsetRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_xlocsetRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_get_xlocsetRequest)); + xtreemfs_replica_removeRequest_descriptor_ = file->message_type(44); + static const int xtreemfs_replica_removeRequest_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_removeRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_removeRequest, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_removeRequest, volume_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_removeRequest, osd_uuid_), + }; + xtreemfs_replica_removeRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_replica_removeRequest_descriptor_, + xtreemfs_replica_removeRequest::default_instance_, + xtreemfs_replica_removeRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_removeRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_replica_removeRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_replica_removeRequest)); + xtreemfs_restore_fileRequest_descriptor_ = file->message_type(45); + static const int xtreemfs_restore_fileRequest_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_restore_fileRequest, file_path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_restore_fileRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_restore_fileRequest, file_size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_restore_fileRequest, osd_uuid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_restore_fileRequest, stripe_size_), + }; + xtreemfs_restore_fileRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_restore_fileRequest_descriptor_, + xtreemfs_restore_fileRequest::default_instance_, + xtreemfs_restore_fileRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_restore_fileRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_restore_fileRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_restore_fileRequest)); + xtreemfs_rmvolRequest_descriptor_ = file->message_type(46); + static const int xtreemfs_rmvolRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rmvolRequest, volume_name_), + }; + xtreemfs_rmvolRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_rmvolRequest_descriptor_, + xtreemfs_rmvolRequest::default_instance_, + xtreemfs_rmvolRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rmvolRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rmvolRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_rmvolRequest)); + xtreemfs_update_file_sizeRequest_descriptor_ = file->message_type(47); + static const int xtreemfs_update_file_sizeRequest_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_update_file_sizeRequest, xcap_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_update_file_sizeRequest, osd_write_response_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_update_file_sizeRequest, close_file_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_update_file_sizeRequest, coordinates_), + }; + xtreemfs_update_file_sizeRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_update_file_sizeRequest_descriptor_, + xtreemfs_update_file_sizeRequest::default_instance_, + xtreemfs_update_file_sizeRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_update_file_sizeRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_update_file_sizeRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_update_file_sizeRequest)); + xtreemfs_set_replica_update_policyRequest_descriptor_ = file->message_type(48); + static const int xtreemfs_set_replica_update_policyRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_replica_update_policyRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_replica_update_policyRequest, update_policy_), + }; + xtreemfs_set_replica_update_policyRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_set_replica_update_policyRequest_descriptor_, + xtreemfs_set_replica_update_policyRequest::default_instance_, + xtreemfs_set_replica_update_policyRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_replica_update_policyRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_replica_update_policyRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_set_replica_update_policyRequest)); + xtreemfs_set_replica_update_policyResponse_descriptor_ = file->message_type(49); + static const int xtreemfs_set_replica_update_policyResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_replica_update_policyResponse, old_update_policy_), + }; + xtreemfs_set_replica_update_policyResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_set_replica_update_policyResponse_descriptor_, + xtreemfs_set_replica_update_policyResponse::default_instance_, + xtreemfs_set_replica_update_policyResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_replica_update_policyResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_replica_update_policyResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_set_replica_update_policyResponse)); + xtreemfs_set_read_only_xattrRequest_descriptor_ = file->message_type(50); + static const int xtreemfs_set_read_only_xattrRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_read_only_xattrRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_read_only_xattrRequest, value_), + }; + xtreemfs_set_read_only_xattrRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_set_read_only_xattrRequest_descriptor_, + xtreemfs_set_read_only_xattrRequest::default_instance_, + xtreemfs_set_read_only_xattrRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_read_only_xattrRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_read_only_xattrRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_set_read_only_xattrRequest)); + xtreemfs_set_read_only_xattrResponse_descriptor_ = file->message_type(51); + static const int xtreemfs_set_read_only_xattrResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_read_only_xattrResponse, was_set_), + }; + xtreemfs_set_read_only_xattrResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_set_read_only_xattrResponse_descriptor_, + xtreemfs_set_read_only_xattrResponse::default_instance_, + xtreemfs_set_read_only_xattrResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_read_only_xattrResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_set_read_only_xattrResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_set_read_only_xattrResponse)); + xtreemfs_get_file_credentialsRequest_descriptor_ = file->message_type(52); + static const int xtreemfs_get_file_credentialsRequest_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_file_credentialsRequest, file_id_), + }; + xtreemfs_get_file_credentialsRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_get_file_credentialsRequest_descriptor_, + xtreemfs_get_file_credentialsRequest::default_instance_, + xtreemfs_get_file_credentialsRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_file_credentialsRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_get_file_credentialsRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_get_file_credentialsRequest)); + Setattrs_descriptor_ = file->enum_type(0); + XATTR_FLAGS_descriptor_ = file->enum_type(1); + ACCESS_FLAGS_descriptor_ = file->enum_type(2); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_xtreemfs_2fMRC_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Stat_descriptor_, &Stat::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + DirectoryEntry_descriptor_, &DirectoryEntry::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + DirectoryEntries_descriptor_, &DirectoryEntries::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + XAttr_descriptor_, &XAttr::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Volume_descriptor_, &Volume::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Volumes_descriptor_, &Volumes::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + StatVFS_descriptor_, &StatVFS::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + fsetattrRequest_descriptor_, &fsetattrRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + getattrRequest_descriptor_, &getattrRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + getattrResponse_descriptor_, &getattrResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + getxattrRequest_descriptor_, &getxattrRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + getxattrResponse_descriptor_, &getxattrResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + linkRequest_descriptor_, &linkRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + listxattrRequest_descriptor_, &listxattrRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + listxattrResponse_descriptor_, &listxattrResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + mkdirRequest_descriptor_, &mkdirRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + openRequest_descriptor_, &openRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + openResponse_descriptor_, &openResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + readdirRequest_descriptor_, &readdirRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + readlinkRequest_descriptor_, &readlinkRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + readlinkResponse_descriptor_, &readlinkResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + removexattrRequest_descriptor_, &removexattrRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + renameRequest_descriptor_, &renameRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + renameResponse_descriptor_, &renameResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + rmdirRequest_descriptor_, &rmdirRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + setattrRequest_descriptor_, &setattrRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + setxattrRequest_descriptor_, &setxattrRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + statvfsRequest_descriptor_, &statvfsRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + symlinkRequest_descriptor_, &symlinkRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + unlinkRequest_descriptor_, &unlinkRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + unlinkResponse_descriptor_, &unlinkResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + accessRequest_descriptor_, &accessRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_check_file_existsRequest_descriptor_, &xtreemfs_check_file_existsRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_check_file_existsResponse_descriptor_, &xtreemfs_check_file_existsResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_dump_restore_databaseRequest_descriptor_, &xtreemfs_dump_restore_databaseRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_get_suitable_osdsRequest_descriptor_, &xtreemfs_get_suitable_osdsRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_get_suitable_osdsResponse_descriptor_, &xtreemfs_get_suitable_osdsResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + timestampResponse_descriptor_, ×tampResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + stringMessage_descriptor_, &stringMessage::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_listdirRequest_descriptor_, &xtreemfs_listdirRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_listdirResponse_descriptor_, &xtreemfs_listdirResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_replica_addRequest_descriptor_, &xtreemfs_replica_addRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_replica_listRequest_descriptor_, &xtreemfs_replica_listRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_get_xlocsetRequest_descriptor_, &xtreemfs_get_xlocsetRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_replica_removeRequest_descriptor_, &xtreemfs_replica_removeRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_restore_fileRequest_descriptor_, &xtreemfs_restore_fileRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_rmvolRequest_descriptor_, &xtreemfs_rmvolRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_update_file_sizeRequest_descriptor_, &xtreemfs_update_file_sizeRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_set_replica_update_policyRequest_descriptor_, &xtreemfs_set_replica_update_policyRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_set_replica_update_policyResponse_descriptor_, &xtreemfs_set_replica_update_policyResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_set_read_only_xattrRequest_descriptor_, &xtreemfs_set_read_only_xattrRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_set_read_only_xattrResponse_descriptor_, &xtreemfs_set_read_only_xattrResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_get_file_credentialsRequest_descriptor_, &xtreemfs_get_file_credentialsRequest::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto() { + delete Stat::default_instance_; + delete Stat_reflection_; + delete DirectoryEntry::default_instance_; + delete DirectoryEntry_reflection_; + delete DirectoryEntries::default_instance_; + delete DirectoryEntries_reflection_; + delete XAttr::default_instance_; + delete XAttr_reflection_; + delete Volume::default_instance_; + delete Volume_reflection_; + delete Volumes::default_instance_; + delete Volumes_reflection_; + delete StatVFS::default_instance_; + delete StatVFS_reflection_; + delete fsetattrRequest::default_instance_; + delete fsetattrRequest_reflection_; + delete getattrRequest::default_instance_; + delete getattrRequest_reflection_; + delete getattrResponse::default_instance_; + delete getattrResponse_reflection_; + delete getxattrRequest::default_instance_; + delete getxattrRequest_reflection_; + delete getxattrResponse::default_instance_; + delete getxattrResponse_reflection_; + delete linkRequest::default_instance_; + delete linkRequest_reflection_; + delete listxattrRequest::default_instance_; + delete listxattrRequest_reflection_; + delete listxattrResponse::default_instance_; + delete listxattrResponse_reflection_; + delete mkdirRequest::default_instance_; + delete mkdirRequest_reflection_; + delete openRequest::default_instance_; + delete openRequest_reflection_; + delete openResponse::default_instance_; + delete openResponse_reflection_; + delete readdirRequest::default_instance_; + delete readdirRequest_reflection_; + delete readlinkRequest::default_instance_; + delete readlinkRequest_reflection_; + delete readlinkResponse::default_instance_; + delete readlinkResponse_reflection_; + delete removexattrRequest::default_instance_; + delete removexattrRequest_reflection_; + delete renameRequest::default_instance_; + delete renameRequest_reflection_; + delete renameResponse::default_instance_; + delete renameResponse_reflection_; + delete rmdirRequest::default_instance_; + delete rmdirRequest_reflection_; + delete setattrRequest::default_instance_; + delete setattrRequest_reflection_; + delete setxattrRequest::default_instance_; + delete setxattrRequest_reflection_; + delete statvfsRequest::default_instance_; + delete statvfsRequest_reflection_; + delete symlinkRequest::default_instance_; + delete symlinkRequest_reflection_; + delete unlinkRequest::default_instance_; + delete unlinkRequest_reflection_; + delete unlinkResponse::default_instance_; + delete unlinkResponse_reflection_; + delete accessRequest::default_instance_; + delete accessRequest_reflection_; + delete xtreemfs_check_file_existsRequest::default_instance_; + delete xtreemfs_check_file_existsRequest_reflection_; + delete xtreemfs_check_file_existsResponse::default_instance_; + delete xtreemfs_check_file_existsResponse_reflection_; + delete xtreemfs_dump_restore_databaseRequest::default_instance_; + delete xtreemfs_dump_restore_databaseRequest_reflection_; + delete xtreemfs_get_suitable_osdsRequest::default_instance_; + delete xtreemfs_get_suitable_osdsRequest_reflection_; + delete xtreemfs_get_suitable_osdsResponse::default_instance_; + delete xtreemfs_get_suitable_osdsResponse_reflection_; + delete timestampResponse::default_instance_; + delete timestampResponse_reflection_; + delete stringMessage::default_instance_; + delete stringMessage_reflection_; + delete xtreemfs_listdirRequest::default_instance_; + delete xtreemfs_listdirRequest_reflection_; + delete xtreemfs_listdirResponse::default_instance_; + delete xtreemfs_listdirResponse_reflection_; + delete xtreemfs_replica_addRequest::default_instance_; + delete xtreemfs_replica_addRequest_reflection_; + delete xtreemfs_replica_listRequest::default_instance_; + delete xtreemfs_replica_listRequest_reflection_; + delete xtreemfs_get_xlocsetRequest::default_instance_; + delete xtreemfs_get_xlocsetRequest_reflection_; + delete xtreemfs_replica_removeRequest::default_instance_; + delete xtreemfs_replica_removeRequest_reflection_; + delete xtreemfs_restore_fileRequest::default_instance_; + delete xtreemfs_restore_fileRequest_reflection_; + delete xtreemfs_rmvolRequest::default_instance_; + delete xtreemfs_rmvolRequest_reflection_; + delete xtreemfs_update_file_sizeRequest::default_instance_; + delete xtreemfs_update_file_sizeRequest_reflection_; + delete xtreemfs_set_replica_update_policyRequest::default_instance_; + delete xtreemfs_set_replica_update_policyRequest_reflection_; + delete xtreemfs_set_replica_update_policyResponse::default_instance_; + delete xtreemfs_set_replica_update_policyResponse_reflection_; + delete xtreemfs_set_read_only_xattrRequest::default_instance_; + delete xtreemfs_set_read_only_xattrRequest_reflection_; + delete xtreemfs_set_read_only_xattrResponse::default_instance_; + delete xtreemfs_set_read_only_xattrResponse_reflection_; + delete xtreemfs_get_file_credentialsRequest::default_instance_; + delete xtreemfs_get_file_credentialsRequest_reflection_; +} + +void protobuf_AddDesc_xtreemfs_2fMRC_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::xtreemfs::pbrpc::protobuf_AddDesc_include_2fPBRPC_2eproto(); + ::xtreemfs::pbrpc::protobuf_AddDesc_include_2fCommon_2eproto(); + ::xtreemfs::pbrpc::protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\022xtreemfs/MRC.proto\022\016xtreemfs.pbrpc\032\023in" + "clude/PBRPC.proto\032\024include/Common.proto\032" + "\032xtreemfs/GlobalTypes.proto\"\357\001\n\004Stat\022\013\n\003" + "dev\030\001 \002(\006\022\013\n\003ino\030\002 \002(\006\022\014\n\004mode\030\003 \002(\007\022\r\n\005" + "nlink\030\004 \002(\007\022\017\n\007user_id\030\005 \002(\t\022\020\n\010group_id" + "\030\006 \002(\t\022\014\n\004size\030\007 \002(\006\022\020\n\010atime_ns\030\010 \002(\006\022\020" + "\n\010mtime_ns\030\t \002(\006\022\020\n\010ctime_ns\030\n \002(\006\022\017\n\007bl" + "ksize\030\013 \002(\007\022\014\n\004etag\030\014 \001(\006\022\026\n\016truncate_ep" + "och\030\r \002(\007\022\022\n\nattributes\030\016 \001(\007\"C\n\016Directo" + "ryEntry\022\014\n\004name\030\001 \002(\t\022#\n\005stbuf\030\002 \001(\0132\024.x" + "treemfs.pbrpc.Stat\"C\n\020DirectoryEntries\022/" + "\n\007entries\030\001 \003(\0132\036.xtreemfs.pbrpc.Directo" + "ryEntry\"@\n\005XAttr\022\014\n\004name\030\001 \002(\t\022\r\n\005value\030" + "\002 \001(\t\022\032\n\022value_bytes_string\030\003 \001(\014\"\244\002\n\006Vo" + "lume\022F\n\025access_control_policy\030\001 \002(\0162\'.xt" + "reemfs.pbrpc.AccessControlPolicyType\022\?\n\027" + "default_striping_policy\030\002 \002(\0132\036.xtreemfs" + ".pbrpc.StripingPolicy\022\n\n\002id\030\003 \002(\t\022\014\n\004mod" + "e\030\004 \002(\007\022\014\n\004name\030\005 \002(\t\022\026\n\016owner_group_id\030" + "\006 \002(\t\022\025\n\rowner_user_id\030\007 \002(\t\022+\n\005attrs\030\010 " + "\003(\0132\034.xtreemfs.pbrpc.KeyValuePair\022\r\n\005quo" + "ta\030\t \001(\006\"2\n\007Volumes\022\'\n\007volumes\030\001 \003(\0132\026.x" + "treemfs.pbrpc.Volume\"\310\002\n\007StatVFS\022\r\n\005bsiz" + "e\030\001 \002(\007\022\016\n\006bavail\030\002 \002(\006\022\r\n\005bfree\030\r \001(\006\022\016" + "\n\006blocks\030\003 \002(\006\022\014\n\004fsid\030\004 \002(\t\022\017\n\007namemax\030" + "\005 \002(\007\022F\n\025access_control_policy\030\006 \002(\0162\'.x" + "treemfs.pbrpc.AccessControlPolicyType\022\?\n" + "\027default_striping_policy\030\007 \002(\0132\036.xtreemf" + "s.pbrpc.StripingPolicy\022\014\n\004etag\030\010 \002(\006\022\014\n\004" + "mode\030\t \002(\007\022\014\n\004name\030\n \002(\t\022\026\n\016owner_group_" + "id\030\013 \002(\t\022\025\n\rowner_user_id\030\014 \002(\t\"i\n\017fseta" + "ttrRequest\022#\n\005stbuf\030\001 \002(\0132\024.xtreemfs.pbr" + "pc.Stat\022\016\n\006to_set\030\002 \002(\007\022!\n\003cap\030\003 \002(\0132\024.x" + "treemfs.pbrpc.XCap\"G\n\016getattrRequest\022\023\n\013" + "volume_name\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\022\022\n\nknown" + "_etag\030\003 \002(\006\"6\n\017getattrResponse\022#\n\005stbuf\030" + "\001 \001(\0132\024.xtreemfs.pbrpc.Stat\"B\n\017getxattrR" + "equest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030\002 \002(" + "\t\022\014\n\004name\030\003 \002(\t\"=\n\020getxattrResponse\022\r\n\005v" + "alue\030\001 \002(\t\022\032\n\022value_bytes_string\030\002 \001(\014\"J" + "\n\013linkRequest\022\023\n\013volume_name\030\001 \002(\t\022\023\n\013ta" + "rget_path\030\002 \002(\t\022\021\n\tlink_path\030\003 \002(\t\"I\n\020li" + "stxattrRequest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004p" + "ath\030\002 \002(\t\022\022\n\nnames_only\030\003 \002(\010\":\n\021listxat" + "trResponse\022%\n\006xattrs\030\001 \003(\0132\025.xtreemfs.pb" + "rpc.XAttr\"\?\n\014mkdirRequest\022\023\n\013volume_name" + "\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\022\014\n\004mode\030\003 \002(\007\"\232\001\n\013o" + "penRequest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030" + "\002 \002(\t\022\r\n\005flags\030\003 \002(\007\022\014\n\004mode\030\004 \002(\007\022\022\n\nat" + "tributes\030\005 \002(\007\0227\n\013coordinates\030\006 \001(\0132\".xt" + "reemfs.pbrpc.VivaldiCoordinates\"S\n\014openR" + "esponse\022.\n\005creds\030\001 \002(\0132\037.xtreemfs.pbrpc." + "FileCredentials\022\023\n\013timestamp_s\030\002 \002(\007\"\250\001\n" + "\016readdirRequest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004" + "path\030\002 \002(\t\022\022\n\nknown_etag\030\003 \002(\006\022%\n\035limit_" + "directory_entries_count\030\004 \002(\007\022\022\n\nnames_o" + "nly\030\005 \002(\010\022$\n\034seen_directory_entries_coun" + "t\030\006 \002(\006\"4\n\017readlinkRequest\022\023\n\013volume_nam" + "e\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\",\n\020readlinkRespons" + "e\022\030\n\020link_target_path\030\001 \003(\t\"E\n\022removexat" + "trRequest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030\002" + " \002(\t\022\014\n\004name\030\003 \002(\t\"N\n\rrenameRequest\022\023\n\013v" + "olume_name\030\001 \002(\t\022\023\n\013source_path\030\002 \002(\t\022\023\n" + "\013target_path\030\003 \002(\t\"U\n\016renameResponse\022\023\n\013" + "timestamp_s\030\001 \002(\007\022.\n\005creds\030\002 \001(\0132\037.xtree" + "mfs.pbrpc.FileCredentials\"1\n\014rmdirReques" + "t\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\"h\n\016" + "setattrRequest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004p" + "ath\030\002 \002(\t\022#\n\005stbuf\030\003 \002(\0132\024.xtreemfs.pbrp" + "c.Stat\022\016\n\006to_set\030\004 \002(\007\"|\n\017setxattrReques" + "t\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\022\014\n\004" + "name\030\003 \002(\t\022\r\n\005value\030\004 \002(\t\022\032\n\022value_bytes" + "_string\030\006 \001(\014\022\r\n\005flags\030\005 \002(\007\"9\n\016statvfsR" + "equest\022\023\n\013volume_name\030\001 \002(\t\022\022\n\nknown_eta" + "g\030\005 \002(\006\"M\n\016symlinkRequest\022\023\n\013volume_name" + "\030\001 \002(\t\022\023\n\013target_path\030\002 \002(\t\022\021\n\tlink_path" + "\030\003 \002(\t\"2\n\runlinkRequest\022\023\n\013volume_name\030\001" + " \002(\t\022\014\n\004path\030\002 \002(\t\"U\n\016unlinkResponse\022\023\n\013" + "timestamp_s\030\001 \002(\007\022.\n\005creds\030\002 \001(\0132\037.xtree" + "mfs.pbrpc.FileCredentials\"A\n\raccessReque" + "st\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\022\r\n" + "\005flags\030\003 \002(\007\"Z\n!xtreemfs_check_file_exis" + "tsRequest\022\021\n\tvolume_id\030\001 \002(\t\022\020\n\010file_ids" + "\030\002 \003(\t\022\020\n\010osd_uuid\030\003 \002(\t\"\315\001\n\"xtreemfs_ch" + "eck_file_existsResponse\022\025\n\rvolume_exists" + "\030\001 \002(\010\022V\n\013file_states\030\002 \003(\0162=.xtreemfs.p" + "brpc.xtreemfs_check_file_existsResponse." + "FILE_STATEB\002\020\001\"8\n\nFILE_STATE\022\013\n\007DELETED\020" + "\000\022\016\n\nREGISTERED\020\001\022\r\n\tABANDONED\020\002\":\n%xtre" + "emfs_dump_restore_databaseRequest\022\021\n\tdum" + "p_file\030\001 \002(\t\"i\n!xtreemfs_get_suitable_os" + "dsRequest\022\017\n\007file_id\030\001 \001(\t\022\014\n\004path\030\003 \001(\t" + "\022\023\n\013volume_name\030\004 \001(\t\022\020\n\010num_osds\030\002 \002(\007\"" + "7\n\"xtreemfs_get_suitable_osdsResponse\022\021\n" + "\tosd_uuids\030\001 \003(\t\"(\n\021timestampResponse\022\023\n" + "\013timestamp_s\030\001 \002(\007\"!\n\rstringMessage\022\020\n\010a" + "_string\030\001 \002(\t\"\'\n\027xtreemfs_listdirRequest" + "\022\014\n\004path\030\001 \002(\t\")\n\030xtreemfs_listdirRespon" + "se\022\r\n\005names\030\001 \003(\t\"\177\n\033xtreemfs_replica_ad" + "dRequest\022\017\n\007file_id\030\001 \001(\t\022\014\n\004path\030\003 \001(\t\022" + "\023\n\013volume_name\030\004 \001(\t\022,\n\013new_replica\030\002 \002(" + "\0132\027.xtreemfs.pbrpc.Replica\"R\n\034xtreemfs_r" + "eplica_listRequest\022\017\n\007file_id\030\001 \001(\t\022\014\n\004p" + "ath\030\002 \001(\t\022\023\n\013volume_name\030\003 \001(\t\"u\n\033xtreem" + "fs_get_xlocsetRequest\022\017\n\007file_id\030\001 \001(\t\022\014" + "\n\004path\030\002 \001(\t\022\023\n\013volume_name\030\003 \001(\t\022\"\n\004xca" + "p\030\004 \001(\0132\024.xtreemfs.pbrpc.XCap\"f\n\036xtreemf" + "s_replica_removeRequest\022\017\n\007file_id\030\001 \001(\t" + "\022\014\n\004path\030\003 \001(\t\022\023\n\013volume_name\030\004 \001(\t\022\020\n\010o" + "sd_uuid\030\002 \002(\t\"|\n\034xtreemfs_restore_fileRe" + "quest\022\021\n\tfile_path\030\001 \002(\t\022\017\n\007file_id\030\002 \002(" + "\t\022\021\n\tfile_size\030\003 \002(\006\022\020\n\010osd_uuid\030\004 \002(\t\022\023" + "\n\013stripe_size\030\005 \002(\007\",\n\025xtreemfs_rmvolReq" + "uest\022\023\n\013volume_name\030\001 \002(\t\"\321\001\n xtreemfs_u" + "pdate_file_sizeRequest\022\"\n\004xcap\030\001 \002(\0132\024.x" + "treemfs.pbrpc.XCap\022<\n\022osd_write_response" + "\030\002 \002(\0132 .xtreemfs.pbrpc.OSDWriteResponse" + "\022\022\n\nclose_file\030\003 \001(\010\0227\n\013coordinates\030\004 \001(" + "\0132\".xtreemfs.pbrpc.VivaldiCoordinates\"S\n" + ")xtreemfs_set_replica_update_policyReque" + "st\022\017\n\007file_id\030\001 \002(\t\022\025\n\rupdate_policy\030\002 \002" + "(\t\"G\n*xtreemfs_set_replica_update_policy" + "Response\022\031\n\021old_update_policy\030\001 \002(\t\"E\n#x" + "treemfs_set_read_only_xattrRequest\022\017\n\007fi" + "le_id\030\001 \002(\t\022\r\n\005value\030\002 \002(\010\"7\n$xtreemfs_s" + "et_read_only_xattrResponse\022\017\n\007was_set\030\001 " + "\002(\010\"7\n$xtreemfs_get_file_credentialsRequ" + "est\022\017\n\007file_id\030\001 \002(\t*\242\001\n\010Setattrs\022\020\n\014SET" + "ATTR_MODE\020\001\022\017\n\013SETATTR_UID\020\002\022\017\n\013SETATTR_" + "GID\020\004\022\020\n\014SETATTR_SIZE\020\010\022\021\n\rSETATTR_ATIME" + "\020\020\022\021\n\rSETATTR_MTIME\020 \022\021\n\rSETATTR_CTIME\020@" + "\022\027\n\022SETATTR_ATTRIBUTES\020\200\001*>\n\013XATTR_FLAGS" + "\022\026\n\022XATTR_FLAGS_CREATE\020\001\022\027\n\023XATTR_FLAGS_" + "REPLACE\020\002*j\n\014ACCESS_FLAGS\022\025\n\021ACCESS_FLAG" + "S_F_OK\020\000\022\025\n\021ACCESS_FLAGS_X_OK\020\001\022\025\n\021ACCES" + "S_FLAGS_W_OK\020\002\022\025\n\021ACCESS_FLAGS_R_OK\020\0042\203 " + "\n\nMRCService\022S\n\010fsetattr\022\037.xtreemfs.pbrp" + "c.fsetattrRequest\032\035.xtreemfs.pbrpc.empty" + "Response\"\007\215\265\030\002\000\000\000\022@\n\tftruncate\022\024.xtreemf" + "s.pbrpc.XCap\032\024.xtreemfs.pbrpc.XCap\"\007\215\265\030\003" + "\000\000\000\022S\n\007getattr\022\036.xtreemfs.pbrpc.getattrR" + "equest\032\037.xtreemfs.pbrpc.getattrResponse\"" + "\007\215\265\030\004\000\000\000\022V\n\010getxattr\022\037.xtreemfs.pbrpc.ge" + "txattrRequest\032 .xtreemfs.pbrpc.getxattrR" + "esponse\"\007\215\265\030\005\000\000\000\022O\n\004link\022\033.xtreemfs.pbrp" + "c.linkRequest\032!.xtreemfs.pbrpc.timestamp" + "Response\"\007\215\265\030\006\000\000\000\022Y\n\tlistxattr\022 .xtreemf" + "s.pbrpc.listxattrRequest\032!.xtreemfs.pbrp" + "c.listxattrResponse\"\007\215\265\030\007\000\000\000\022Q\n\005mkdir\022\034." + "xtreemfs.pbrpc.mkdirRequest\032!.xtreemfs.p" + "brpc.timestampResponse\"\007\215\265\030\010\000\000\000\022J\n\004open\022" + "\033.xtreemfs.pbrpc.openRequest\032\034.xtreemfs." + "pbrpc.openResponse\"\007\215\265\030\t\000\000\000\022T\n\007readdir\022\036" + ".xtreemfs.pbrpc.readdirRequest\032 .xtreemf" + "s.pbrpc.DirectoryEntries\"\007\215\265\030\n\000\000\000\022V\n\010rea" + "dlink\022\037.xtreemfs.pbrpc.readlinkRequest\032 " + ".xtreemfs.pbrpc.readlinkResponse\"\007\215\265\030\013\000\000" + "\000\022]\n\013removexattr\022\".xtreemfs.pbrpc.remove" + "xattrRequest\032!.xtreemfs.pbrpc.timestampR" + "esponse\"\007\215\265\030\014\000\000\000\022P\n\006rename\022\035.xtreemfs.pb" + "rpc.renameRequest\032\036.xtreemfs.pbrpc.renam" + "eResponse\"\007\215\265\030\r\000\000\000\022Q\n\005rmdir\022\034.xtreemfs.p" + "brpc.rmdirRequest\032!.xtreemfs.pbrpc.times" + "tampResponse\"\007\215\265\030\016\000\000\000\022U\n\007setattr\022\036.xtree" + "mfs.pbrpc.setattrRequest\032!.xtreemfs.pbrp" + "c.timestampResponse\"\007\215\265\030\017\000\000\000\022W\n\010setxattr" + "\022\037.xtreemfs.pbrpc.setxattrRequest\032!.xtre" + "emfs.pbrpc.timestampResponse\"\007\215\265\030\020\000\000\000\022K\n" + "\007statvfs\022\036.xtreemfs.pbrpc.statvfsRequest" + "\032\027.xtreemfs.pbrpc.StatVFS\"\007\215\265\030\021\000\000\000\022U\n\007sy" + "mlink\022\036.xtreemfs.pbrpc.symlinkRequest\032!." + "xtreemfs.pbrpc.timestampResponse\"\007\215\265\030\022\000\000" + "\000\022P\n\006unlink\022\035.xtreemfs.pbrpc.unlinkReque" + "st\032\036.xtreemfs.pbrpc.unlinkResponse\"\007\215\265\030\023" + "\000\000\000\022O\n\006access\022\035.xtreemfs.pbrpc.accessReq" + "uest\032\035.xtreemfs.pbrpc.emptyResponse\"\007\215\265\030" + "\024\000\000\000\022[\n\023xtreemfs_checkpoint\022\034.xtreemfs.p" + "brpc.emptyRequest\032\035.xtreemfs.pbrpc.empty" + "Response\"\007\215\265\030\036\000\000\000\022\214\001\n\032xtreemfs_check_fil" + "e_exists\0221.xtreemfs.pbrpc.xtreemfs_check" + "_file_existsRequest\0322.xtreemfs.pbrpc.xtr" + "eemfs_check_file_existsResponse\"\007\215\265\030\037\000\000\000" + "\022w\n\026xtreemfs_dump_database\0225.xtreemfs.pb" + "rpc.xtreemfs_dump_restore_databaseReques" + "t\032\035.xtreemfs.pbrpc.emptyResponse\"\007\215\265\030 \000\000" + "\000\022\214\001\n\032xtreemfs_get_suitable_osds\0221.xtree" + "mfs.pbrpc.xtreemfs_get_suitable_osdsRequ" + "est\0322.xtreemfs.pbrpc.xtreemfs_get_suitab" + "le_osdsResponse\"\007\215\265\030!\000\000\000\022`\n\027xtreemfs_int" + "ernal_debug\022\035.xtreemfs.pbrpc.stringMessa" + "ge\032\035.xtreemfs.pbrpc.stringMessage\"\007\215\265\030\"\000" + "\000\000\022n\n\020xtreemfs_listdir\022\'.xtreemfs.pbrpc." + "xtreemfs_listdirRequest\032(.xtreemfs.pbrpc" + ".xtreemfs_listdirResponse\"\007\215\265\030#\000\000\000\022P\n\016xt" + "reemfs_lsvol\022\034.xtreemfs.pbrpc.emptyReque" + "st\032\027.xtreemfs.pbrpc.Volumes\"\007\215\265\030$\000\000\000\022P\n\016" + "xtreemfs_mkvol\022\026.xtreemfs.pbrpc.Volume\032\035" + ".xtreemfs.pbrpc.emptyResponse\"\007\215\265\030/\000\000\000\022P" + "\n\031xtreemfs_renew_capability\022\024.xtreemfs.p" + "brpc.XCap\032\024.xtreemfs.pbrpc.XCap\"\007\215\265\030%\000\000\000" + "\022f\n\036xtreemfs_replication_to_master\022\034.xtr" + "eemfs.pbrpc.emptyRequest\032\035.xtreemfs.pbrp" + "c.emptyResponse\"\007\215\265\030&\000\000\000\022k\n\024xtreemfs_rep" + "lica_add\022+.xtreemfs.pbrpc.xtreemfs_repli" + "ca_addRequest\032\035.xtreemfs.pbrpc.emptyResp" + "onse\"\007\215\265\030\'\000\000\000\022h\n\025xtreemfs_replica_list\022," + ".xtreemfs.pbrpc.xtreemfs_replica_listReq" + "uest\032\030.xtreemfs.pbrpc.Replicas\"\007\215\265\030(\000\000\000\022" + "s\n\027xtreemfs_replica_remove\022..xtreemfs.pb" + "rpc.xtreemfs_replica_removeRequest\032\037.xtr" + "eemfs.pbrpc.FileCredentials\"\007\215\265\030)\000\000\000\022z\n\031" + "xtreemfs_restore_database\0225.xtreemfs.pbr" + "pc.xtreemfs_dump_restore_databaseRequest" + "\032\035.xtreemfs.pbrpc.emptyResponse\"\007\215\265\030*\000\000\000" + "\022m\n\025xtreemfs_restore_file\022,.xtreemfs.pbr" + "pc.xtreemfs_restore_fileRequest\032\035.xtreem" + "fs.pbrpc.emptyResponse\"\007\215\265\030+\000\000\000\022_\n\016xtree" + "mfs_rmvol\022%.xtreemfs.pbrpc.xtreemfs_rmvo" + "lRequest\032\035.xtreemfs.pbrpc.emptyResponse\"" + "\007\215\265\030,\000\000\000\022Y\n\021xtreemfs_shutdown\022\034.xtreemfs" + ".pbrpc.emptyRequest\032\035.xtreemfs.pbrpc.emp" + "tyResponse\"\007\215\265\030-\000\000\000\022y\n\031xtreemfs_update_f" + "ile_size\0220.xtreemfs.pbrpc.xtreemfs_updat" + "e_file_sizeRequest\032!.xtreemfs.pbrpc.time" + "stampResponse\"\007\215\265\030.\000\000\000\022\244\001\n\"xtreemfs_set_" + "replica_update_policy\0229.xtreemfs.pbrpc.x" + "treemfs_set_replica_update_policyRequest" + "\032:.xtreemfs.pbrpc.xtreemfs_set_replica_u" + "pdate_policyResponse\"\007\215\265\0300\000\000\000\022\222\001\n\034xtreem" + "fs_set_read_only_xattr\0223.xtreemfs.pbrpc." + "xtreemfs_set_read_only_xattrRequest\0324.xt" + "reemfs.pbrpc.xtreemfs_set_read_only_xatt" + "rResponse\"\007\215\265\0301\000\000\000\022\177\n\035xtreemfs_get_file_" + "credentials\0224.xtreemfs.pbrpc.xtreemfs_ge" + "t_file_credentialsRequest\032\037.xtreemfs.pbr" + "pc.FileCredentials\"\007\215\265\0302\000\000\000\022e\n\024xtreemfs_" + "get_xlocset\022+.xtreemfs.pbrpc.xtreemfs_ge" + "t_xlocsetRequest\032\027.xtreemfs.pbrpc.XLocSe" + "t\"\007\215\265\0303\000\000\000\032\007\225\265\030!N\000\000B(\n&org.xtreemfs.pbrp" + "c.generatedinterfaces", 9581); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "xtreemfs/MRC.proto", &protobuf_RegisterTypes); + Stat::default_instance_ = new Stat(); + DirectoryEntry::default_instance_ = new DirectoryEntry(); + DirectoryEntries::default_instance_ = new DirectoryEntries(); + XAttr::default_instance_ = new XAttr(); + Volume::default_instance_ = new Volume(); + Volumes::default_instance_ = new Volumes(); + StatVFS::default_instance_ = new StatVFS(); + fsetattrRequest::default_instance_ = new fsetattrRequest(); + getattrRequest::default_instance_ = new getattrRequest(); + getattrResponse::default_instance_ = new getattrResponse(); + getxattrRequest::default_instance_ = new getxattrRequest(); + getxattrResponse::default_instance_ = new getxattrResponse(); + linkRequest::default_instance_ = new linkRequest(); + listxattrRequest::default_instance_ = new listxattrRequest(); + listxattrResponse::default_instance_ = new listxattrResponse(); + mkdirRequest::default_instance_ = new mkdirRequest(); + openRequest::default_instance_ = new openRequest(); + openResponse::default_instance_ = new openResponse(); + readdirRequest::default_instance_ = new readdirRequest(); + readlinkRequest::default_instance_ = new readlinkRequest(); + readlinkResponse::default_instance_ = new readlinkResponse(); + removexattrRequest::default_instance_ = new removexattrRequest(); + renameRequest::default_instance_ = new renameRequest(); + renameResponse::default_instance_ = new renameResponse(); + rmdirRequest::default_instance_ = new rmdirRequest(); + setattrRequest::default_instance_ = new setattrRequest(); + setxattrRequest::default_instance_ = new setxattrRequest(); + statvfsRequest::default_instance_ = new statvfsRequest(); + symlinkRequest::default_instance_ = new symlinkRequest(); + unlinkRequest::default_instance_ = new unlinkRequest(); + unlinkResponse::default_instance_ = new unlinkResponse(); + accessRequest::default_instance_ = new accessRequest(); + xtreemfs_check_file_existsRequest::default_instance_ = new xtreemfs_check_file_existsRequest(); + xtreemfs_check_file_existsResponse::default_instance_ = new xtreemfs_check_file_existsResponse(); + xtreemfs_dump_restore_databaseRequest::default_instance_ = new xtreemfs_dump_restore_databaseRequest(); + xtreemfs_get_suitable_osdsRequest::default_instance_ = new xtreemfs_get_suitable_osdsRequest(); + xtreemfs_get_suitable_osdsResponse::default_instance_ = new xtreemfs_get_suitable_osdsResponse(); + timestampResponse::default_instance_ = new timestampResponse(); + stringMessage::default_instance_ = new stringMessage(); + xtreemfs_listdirRequest::default_instance_ = new xtreemfs_listdirRequest(); + xtreemfs_listdirResponse::default_instance_ = new xtreemfs_listdirResponse(); + xtreemfs_replica_addRequest::default_instance_ = new xtreemfs_replica_addRequest(); + xtreemfs_replica_listRequest::default_instance_ = new xtreemfs_replica_listRequest(); + xtreemfs_get_xlocsetRequest::default_instance_ = new xtreemfs_get_xlocsetRequest(); + xtreemfs_replica_removeRequest::default_instance_ = new xtreemfs_replica_removeRequest(); + xtreemfs_restore_fileRequest::default_instance_ = new xtreemfs_restore_fileRequest(); + xtreemfs_rmvolRequest::default_instance_ = new xtreemfs_rmvolRequest(); + xtreemfs_update_file_sizeRequest::default_instance_ = new xtreemfs_update_file_sizeRequest(); + xtreemfs_set_replica_update_policyRequest::default_instance_ = new xtreemfs_set_replica_update_policyRequest(); + xtreemfs_set_replica_update_policyResponse::default_instance_ = new xtreemfs_set_replica_update_policyResponse(); + xtreemfs_set_read_only_xattrRequest::default_instance_ = new xtreemfs_set_read_only_xattrRequest(); + xtreemfs_set_read_only_xattrResponse::default_instance_ = new xtreemfs_set_read_only_xattrResponse(); + xtreemfs_get_file_credentialsRequest::default_instance_ = new xtreemfs_get_file_credentialsRequest(); + Stat::default_instance_->InitAsDefaultInstance(); + DirectoryEntry::default_instance_->InitAsDefaultInstance(); + DirectoryEntries::default_instance_->InitAsDefaultInstance(); + XAttr::default_instance_->InitAsDefaultInstance(); + Volume::default_instance_->InitAsDefaultInstance(); + Volumes::default_instance_->InitAsDefaultInstance(); + StatVFS::default_instance_->InitAsDefaultInstance(); + fsetattrRequest::default_instance_->InitAsDefaultInstance(); + getattrRequest::default_instance_->InitAsDefaultInstance(); + getattrResponse::default_instance_->InitAsDefaultInstance(); + getxattrRequest::default_instance_->InitAsDefaultInstance(); + getxattrResponse::default_instance_->InitAsDefaultInstance(); + linkRequest::default_instance_->InitAsDefaultInstance(); + listxattrRequest::default_instance_->InitAsDefaultInstance(); + listxattrResponse::default_instance_->InitAsDefaultInstance(); + mkdirRequest::default_instance_->InitAsDefaultInstance(); + openRequest::default_instance_->InitAsDefaultInstance(); + openResponse::default_instance_->InitAsDefaultInstance(); + readdirRequest::default_instance_->InitAsDefaultInstance(); + readlinkRequest::default_instance_->InitAsDefaultInstance(); + readlinkResponse::default_instance_->InitAsDefaultInstance(); + removexattrRequest::default_instance_->InitAsDefaultInstance(); + renameRequest::default_instance_->InitAsDefaultInstance(); + renameResponse::default_instance_->InitAsDefaultInstance(); + rmdirRequest::default_instance_->InitAsDefaultInstance(); + setattrRequest::default_instance_->InitAsDefaultInstance(); + setxattrRequest::default_instance_->InitAsDefaultInstance(); + statvfsRequest::default_instance_->InitAsDefaultInstance(); + symlinkRequest::default_instance_->InitAsDefaultInstance(); + unlinkRequest::default_instance_->InitAsDefaultInstance(); + unlinkResponse::default_instance_->InitAsDefaultInstance(); + accessRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_check_file_existsRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_check_file_existsResponse::default_instance_->InitAsDefaultInstance(); + xtreemfs_dump_restore_databaseRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_get_suitable_osdsRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_get_suitable_osdsResponse::default_instance_->InitAsDefaultInstance(); + timestampResponse::default_instance_->InitAsDefaultInstance(); + stringMessage::default_instance_->InitAsDefaultInstance(); + xtreemfs_listdirRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_listdirResponse::default_instance_->InitAsDefaultInstance(); + xtreemfs_replica_addRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_replica_listRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_get_xlocsetRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_replica_removeRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_restore_fileRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_rmvolRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_update_file_sizeRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_set_replica_update_policyRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_set_replica_update_policyResponse::default_instance_->InitAsDefaultInstance(); + xtreemfs_set_read_only_xattrRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_set_read_only_xattrResponse::default_instance_->InitAsDefaultInstance(); + xtreemfs_get_file_credentialsRequest::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_xtreemfs_2fMRC_2eproto { + StaticDescriptorInitializer_xtreemfs_2fMRC_2eproto() { + protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + } +} static_descriptor_initializer_xtreemfs_2fMRC_2eproto_; +const ::google::protobuf::EnumDescriptor* Setattrs_descriptor() { + protobuf_AssignDescriptorsOnce(); + return Setattrs_descriptor_; +} +bool Setattrs_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* XATTR_FLAGS_descriptor() { + protobuf_AssignDescriptorsOnce(); + return XATTR_FLAGS_descriptor_; +} +bool XATTR_FLAGS_IsValid(int value) { + switch(value) { + case 1: + case 2: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ACCESS_FLAGS_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ACCESS_FLAGS_descriptor_; +} +bool ACCESS_FLAGS_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 4: + return true; + default: + return false; + } +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Stat::kDevFieldNumber; +const int Stat::kInoFieldNumber; +const int Stat::kModeFieldNumber; +const int Stat::kNlinkFieldNumber; +const int Stat::kUserIdFieldNumber; +const int Stat::kGroupIdFieldNumber; +const int Stat::kSizeFieldNumber; +const int Stat::kAtimeNsFieldNumber; +const int Stat::kMtimeNsFieldNumber; +const int Stat::kCtimeNsFieldNumber; +const int Stat::kBlksizeFieldNumber; +const int Stat::kEtagFieldNumber; +const int Stat::kTruncateEpochFieldNumber; +const int Stat::kAttributesFieldNumber; +#endif // !_MSC_VER + +Stat::Stat() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Stat::InitAsDefaultInstance() { +} + +Stat::Stat(const Stat& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Stat::SharedCtor() { + _cached_size_ = 0; + dev_ = GOOGLE_ULONGLONG(0); + ino_ = GOOGLE_ULONGLONG(0); + mode_ = 0u; + nlink_ = 0u; + user_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + group_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + size_ = GOOGLE_ULONGLONG(0); + atime_ns_ = GOOGLE_ULONGLONG(0); + mtime_ns_ = GOOGLE_ULONGLONG(0); + ctime_ns_ = GOOGLE_ULONGLONG(0); + blksize_ = 0u; + etag_ = GOOGLE_ULONGLONG(0); + truncate_epoch_ = 0u; + attributes_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Stat::~Stat() { + SharedDtor(); +} + +void Stat::SharedDtor() { + if (user_id_ != &::google::protobuf::internal::kEmptyString) { + delete user_id_; + } + if (group_id_ != &::google::protobuf::internal::kEmptyString) { + delete group_id_; + } + if (this != default_instance_) { + } +} + +void Stat::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Stat::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Stat_descriptor_; +} + +const Stat& Stat::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +Stat* Stat::default_instance_ = NULL; + +Stat* Stat::New() const { + return new Stat; +} + +void Stat::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + dev_ = GOOGLE_ULONGLONG(0); + ino_ = GOOGLE_ULONGLONG(0); + mode_ = 0u; + nlink_ = 0u; + if (has_user_id()) { + if (user_id_ != &::google::protobuf::internal::kEmptyString) { + user_id_->clear(); + } + } + if (has_group_id()) { + if (group_id_ != &::google::protobuf::internal::kEmptyString) { + group_id_->clear(); + } + } + size_ = GOOGLE_ULONGLONG(0); + atime_ns_ = GOOGLE_ULONGLONG(0); + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + mtime_ns_ = GOOGLE_ULONGLONG(0); + ctime_ns_ = GOOGLE_ULONGLONG(0); + blksize_ = 0u; + etag_ = GOOGLE_ULONGLONG(0); + truncate_epoch_ = 0u; + attributes_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Stat::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 dev = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &dev_))); + set_has_dev(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(17)) goto parse_ino; + break; + } + + // required fixed64 ino = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_ino: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &ino_))); + set_has_ino(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(29)) goto parse_mode; + break; + } + + // required fixed32 mode = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_mode: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &mode_))); + set_has_mode(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(37)) goto parse_nlink; + break; + } + + // required fixed32 nlink = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_nlink: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &nlink_))); + set_has_nlink(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_user_id; + break; + } + + // required string user_id = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_user_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_user_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->user_id().data(), this->user_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(50)) goto parse_group_id; + break; + } + + // required string group_id = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_group_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_group_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->group_id().data(), this->group_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(57)) goto parse_size; + break; + } + + // required fixed64 size = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &size_))); + set_has_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(65)) goto parse_atime_ns; + break; + } + + // required fixed64 atime_ns = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_atime_ns: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &atime_ns_))); + set_has_atime_ns(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(73)) goto parse_mtime_ns; + break; + } + + // required fixed64 mtime_ns = 9; + case 9: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_mtime_ns: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &mtime_ns_))); + set_has_mtime_ns(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(81)) goto parse_ctime_ns; + break; + } + + // required fixed64 ctime_ns = 10; + case 10: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_ctime_ns: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &ctime_ns_))); + set_has_ctime_ns(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(93)) goto parse_blksize; + break; + } + + // required fixed32 blksize = 11; + case 11: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_blksize: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &blksize_))); + set_has_blksize(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(97)) goto parse_etag; + break; + } + + // optional fixed64 etag = 12; + case 12: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_etag: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &etag_))); + set_has_etag(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(109)) goto parse_truncate_epoch; + break; + } + + // required fixed32 truncate_epoch = 13; + case 13: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_truncate_epoch: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &truncate_epoch_))); + set_has_truncate_epoch(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(117)) goto parse_attributes; + break; + } + + // optional fixed32 attributes = 14; + case 14: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_attributes: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &attributes_))); + set_has_attributes(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Stat::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 dev = 1; + if (has_dev()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->dev(), output); + } + + // required fixed64 ino = 2; + if (has_ino()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(2, this->ino(), output); + } + + // required fixed32 mode = 3; + if (has_mode()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(3, this->mode(), output); + } + + // required fixed32 nlink = 4; + if (has_nlink()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(4, this->nlink(), output); + } + + // required string user_id = 5; + if (has_user_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->user_id().data(), this->user_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 5, this->user_id(), output); + } + + // required string group_id = 6; + if (has_group_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->group_id().data(), this->group_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 6, this->group_id(), output); + } + + // required fixed64 size = 7; + if (has_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(7, this->size(), output); + } + + // required fixed64 atime_ns = 8; + if (has_atime_ns()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(8, this->atime_ns(), output); + } + + // required fixed64 mtime_ns = 9; + if (has_mtime_ns()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(9, this->mtime_ns(), output); + } + + // required fixed64 ctime_ns = 10; + if (has_ctime_ns()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(10, this->ctime_ns(), output); + } + + // required fixed32 blksize = 11; + if (has_blksize()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(11, this->blksize(), output); + } + + // optional fixed64 etag = 12; + if (has_etag()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(12, this->etag(), output); + } + + // required fixed32 truncate_epoch = 13; + if (has_truncate_epoch()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(13, this->truncate_epoch(), output); + } + + // optional fixed32 attributes = 14; + if (has_attributes()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(14, this->attributes(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Stat::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 dev = 1; + if (has_dev()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->dev(), target); + } + + // required fixed64 ino = 2; + if (has_ino()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(2, this->ino(), target); + } + + // required fixed32 mode = 3; + if (has_mode()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(3, this->mode(), target); + } + + // required fixed32 nlink = 4; + if (has_nlink()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(4, this->nlink(), target); + } + + // required string user_id = 5; + if (has_user_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->user_id().data(), this->user_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 5, this->user_id(), target); + } + + // required string group_id = 6; + if (has_group_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->group_id().data(), this->group_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 6, this->group_id(), target); + } + + // required fixed64 size = 7; + if (has_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(7, this->size(), target); + } + + // required fixed64 atime_ns = 8; + if (has_atime_ns()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(8, this->atime_ns(), target); + } + + // required fixed64 mtime_ns = 9; + if (has_mtime_ns()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(9, this->mtime_ns(), target); + } + + // required fixed64 ctime_ns = 10; + if (has_ctime_ns()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(10, this->ctime_ns(), target); + } + + // required fixed32 blksize = 11; + if (has_blksize()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(11, this->blksize(), target); + } + + // optional fixed64 etag = 12; + if (has_etag()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(12, this->etag(), target); + } + + // required fixed32 truncate_epoch = 13; + if (has_truncate_epoch()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(13, this->truncate_epoch(), target); + } + + // optional fixed32 attributes = 14; + if (has_attributes()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(14, this->attributes(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Stat::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 dev = 1; + if (has_dev()) { + total_size += 1 + 8; + } + + // required fixed64 ino = 2; + if (has_ino()) { + total_size += 1 + 8; + } + + // required fixed32 mode = 3; + if (has_mode()) { + total_size += 1 + 4; + } + + // required fixed32 nlink = 4; + if (has_nlink()) { + total_size += 1 + 4; + } + + // required string user_id = 5; + if (has_user_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->user_id()); + } + + // required string group_id = 6; + if (has_group_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->group_id()); + } + + // required fixed64 size = 7; + if (has_size()) { + total_size += 1 + 8; + } + + // required fixed64 atime_ns = 8; + if (has_atime_ns()) { + total_size += 1 + 8; + } + + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // required fixed64 mtime_ns = 9; + if (has_mtime_ns()) { + total_size += 1 + 8; + } + + // required fixed64 ctime_ns = 10; + if (has_ctime_ns()) { + total_size += 1 + 8; + } + + // required fixed32 blksize = 11; + if (has_blksize()) { + total_size += 1 + 4; + } + + // optional fixed64 etag = 12; + if (has_etag()) { + total_size += 1 + 8; + } + + // required fixed32 truncate_epoch = 13; + if (has_truncate_epoch()) { + total_size += 1 + 4; + } + + // optional fixed32 attributes = 14; + if (has_attributes()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Stat::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Stat* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Stat::MergeFrom(const Stat& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_dev()) { + set_dev(from.dev()); + } + if (from.has_ino()) { + set_ino(from.ino()); + } + if (from.has_mode()) { + set_mode(from.mode()); + } + if (from.has_nlink()) { + set_nlink(from.nlink()); + } + if (from.has_user_id()) { + set_user_id(from.user_id()); + } + if (from.has_group_id()) { + set_group_id(from.group_id()); + } + if (from.has_size()) { + set_size(from.size()); + } + if (from.has_atime_ns()) { + set_atime_ns(from.atime_ns()); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_mtime_ns()) { + set_mtime_ns(from.mtime_ns()); + } + if (from.has_ctime_ns()) { + set_ctime_ns(from.ctime_ns()); + } + if (from.has_blksize()) { + set_blksize(from.blksize()); + } + if (from.has_etag()) { + set_etag(from.etag()); + } + if (from.has_truncate_epoch()) { + set_truncate_epoch(from.truncate_epoch()); + } + if (from.has_attributes()) { + set_attributes(from.attributes()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Stat::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Stat::CopyFrom(const Stat& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Stat::IsInitialized() const { + if ((_has_bits_[0] & 0x000017ff) != 0x000017ff) return false; + + return true; +} + +void Stat::Swap(Stat* other) { + if (other != this) { + std::swap(dev_, other->dev_); + std::swap(ino_, other->ino_); + std::swap(mode_, other->mode_); + std::swap(nlink_, other->nlink_); + std::swap(user_id_, other->user_id_); + std::swap(group_id_, other->group_id_); + std::swap(size_, other->size_); + std::swap(atime_ns_, other->atime_ns_); + std::swap(mtime_ns_, other->mtime_ns_); + std::swap(ctime_ns_, other->ctime_ns_); + std::swap(blksize_, other->blksize_); + std::swap(etag_, other->etag_); + std::swap(truncate_epoch_, other->truncate_epoch_); + std::swap(attributes_, other->attributes_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Stat::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Stat_descriptor_; + metadata.reflection = Stat_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int DirectoryEntry::kNameFieldNumber; +const int DirectoryEntry::kStbufFieldNumber; +#endif // !_MSC_VER + +DirectoryEntry::DirectoryEntry() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void DirectoryEntry::InitAsDefaultInstance() { + stbuf_ = const_cast< ::xtreemfs::pbrpc::Stat*>(&::xtreemfs::pbrpc::Stat::default_instance()); +} + +DirectoryEntry::DirectoryEntry(const DirectoryEntry& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void DirectoryEntry::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + stbuf_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +DirectoryEntry::~DirectoryEntry() { + SharedDtor(); +} + +void DirectoryEntry::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + delete stbuf_; + } +} + +void DirectoryEntry::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* DirectoryEntry::descriptor() { + protobuf_AssignDescriptorsOnce(); + return DirectoryEntry_descriptor_; +} + +const DirectoryEntry& DirectoryEntry::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +DirectoryEntry* DirectoryEntry::default_instance_ = NULL; + +DirectoryEntry* DirectoryEntry::New() const { + return new DirectoryEntry; +} + +void DirectoryEntry::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_stbuf()) { + if (stbuf_ != NULL) stbuf_->::xtreemfs::pbrpc::Stat::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool DirectoryEntry::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_stbuf; + break; + } + + // optional .xtreemfs.pbrpc.Stat stbuf = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_stbuf: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_stbuf())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void DirectoryEntry::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // optional .xtreemfs.pbrpc.Stat stbuf = 2; + if (has_stbuf()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->stbuf(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* DirectoryEntry::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional .xtreemfs.pbrpc.Stat stbuf = 2; + if (has_stbuf()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->stbuf(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int DirectoryEntry::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional .xtreemfs.pbrpc.Stat stbuf = 2; + if (has_stbuf()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->stbuf()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void DirectoryEntry::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const DirectoryEntry* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void DirectoryEntry::MergeFrom(const DirectoryEntry& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_stbuf()) { + mutable_stbuf()->::xtreemfs::pbrpc::Stat::MergeFrom(from.stbuf()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void DirectoryEntry::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void DirectoryEntry::CopyFrom(const DirectoryEntry& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DirectoryEntry::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_stbuf()) { + if (!this->stbuf().IsInitialized()) return false; + } + return true; +} + +void DirectoryEntry::Swap(DirectoryEntry* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(stbuf_, other->stbuf_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata DirectoryEntry::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = DirectoryEntry_descriptor_; + metadata.reflection = DirectoryEntry_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int DirectoryEntries::kEntriesFieldNumber; +#endif // !_MSC_VER + +DirectoryEntries::DirectoryEntries() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void DirectoryEntries::InitAsDefaultInstance() { +} + +DirectoryEntries::DirectoryEntries(const DirectoryEntries& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void DirectoryEntries::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +DirectoryEntries::~DirectoryEntries() { + SharedDtor(); +} + +void DirectoryEntries::SharedDtor() { + if (this != default_instance_) { + } +} + +void DirectoryEntries::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* DirectoryEntries::descriptor() { + protobuf_AssignDescriptorsOnce(); + return DirectoryEntries_descriptor_; +} + +const DirectoryEntries& DirectoryEntries::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +DirectoryEntries* DirectoryEntries::default_instance_ = NULL; + +DirectoryEntries* DirectoryEntries::New() const { + return new DirectoryEntries; +} + +void DirectoryEntries::Clear() { + entries_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool DirectoryEntries::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_entries: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_entries())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_entries; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void DirectoryEntries::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + for (int i = 0; i < this->entries_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->entries(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* DirectoryEntries::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + for (int i = 0; i < this->entries_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->entries(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int DirectoryEntries::ByteSize() const { + int total_size = 0; + + // repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + total_size += 1 * this->entries_size(); + for (int i = 0; i < this->entries_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->entries(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void DirectoryEntries::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const DirectoryEntries* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void DirectoryEntries::MergeFrom(const DirectoryEntries& from) { + GOOGLE_CHECK_NE(&from, this); + entries_.MergeFrom(from.entries_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void DirectoryEntries::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void DirectoryEntries::CopyFrom(const DirectoryEntries& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DirectoryEntries::IsInitialized() const { + + for (int i = 0; i < entries_size(); i++) { + if (!this->entries(i).IsInitialized()) return false; + } + return true; +} + +void DirectoryEntries::Swap(DirectoryEntries* other) { + if (other != this) { + entries_.Swap(&other->entries_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata DirectoryEntries::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = DirectoryEntries_descriptor_; + metadata.reflection = DirectoryEntries_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int XAttr::kNameFieldNumber; +const int XAttr::kValueFieldNumber; +const int XAttr::kValueBytesStringFieldNumber; +#endif // !_MSC_VER + +XAttr::XAttr() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void XAttr::InitAsDefaultInstance() { +} + +XAttr::XAttr(const XAttr& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void XAttr::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + value_bytes_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +XAttr::~XAttr() { + SharedDtor(); +} + +void XAttr::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (value_ != &::google::protobuf::internal::kEmptyString) { + delete value_; + } + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + delete value_bytes_string_; + } + if (this != default_instance_) { + } +} + +void XAttr::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* XAttr::descriptor() { + protobuf_AssignDescriptorsOnce(); + return XAttr_descriptor_; +} + +const XAttr& XAttr::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +XAttr* XAttr::default_instance_ = NULL; + +XAttr* XAttr::New() const { + return new XAttr; +} + +void XAttr::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_value()) { + if (value_ != &::google::protobuf::internal::kEmptyString) { + value_->clear(); + } + } + if (has_value_bytes_string()) { + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + value_bytes_string_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool XAttr::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_value; + break; + } + + // optional string value = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_value_bytes_string; + break; + } + + // optional bytes value_bytes_string = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_value_bytes_string: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_value_bytes_string())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void XAttr::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // optional string value = 2; + if (has_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->value(), output); + } + + // optional bytes value_bytes_string = 3; + if (has_value_bytes_string()) { + ::google::protobuf::internal::WireFormatLite::WriteBytes( + 3, this->value_bytes_string(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* XAttr::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional string value = 2; + if (has_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->value(), target); + } + + // optional bytes value_bytes_string = 3; + if (has_value_bytes_string()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 3, this->value_bytes_string(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int XAttr::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional string value = 2; + if (has_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->value()); + } + + // optional bytes value_bytes_string = 3; + if (has_value_bytes_string()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->value_bytes_string()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void XAttr::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const XAttr* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void XAttr::MergeFrom(const XAttr& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_value()) { + set_value(from.value()); + } + if (from.has_value_bytes_string()) { + set_value_bytes_string(from.value_bytes_string()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void XAttr::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void XAttr::CopyFrom(const XAttr& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool XAttr::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void XAttr::Swap(XAttr* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(value_, other->value_); + std::swap(value_bytes_string_, other->value_bytes_string_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata XAttr::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = XAttr_descriptor_; + metadata.reflection = XAttr_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Volume::kAccessControlPolicyFieldNumber; +const int Volume::kDefaultStripingPolicyFieldNumber; +const int Volume::kIdFieldNumber; +const int Volume::kModeFieldNumber; +const int Volume::kNameFieldNumber; +const int Volume::kOwnerGroupIdFieldNumber; +const int Volume::kOwnerUserIdFieldNumber; +const int Volume::kAttrsFieldNumber; +const int Volume::kQuotaFieldNumber; +#endif // !_MSC_VER + +Volume::Volume() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Volume::InitAsDefaultInstance() { + default_striping_policy_ = const_cast< ::xtreemfs::pbrpc::StripingPolicy*>(&::xtreemfs::pbrpc::StripingPolicy::default_instance()); +} + +Volume::Volume(const Volume& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Volume::SharedCtor() { + _cached_size_ = 0; + access_control_policy_ = 1; + default_striping_policy_ = NULL; + id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + mode_ = 0u; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + owner_group_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + owner_user_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + quota_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Volume::~Volume() { + SharedDtor(); +} + +void Volume::SharedDtor() { + if (id_ != &::google::protobuf::internal::kEmptyString) { + delete id_; + } + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (owner_group_id_ != &::google::protobuf::internal::kEmptyString) { + delete owner_group_id_; + } + if (owner_user_id_ != &::google::protobuf::internal::kEmptyString) { + delete owner_user_id_; + } + if (this != default_instance_) { + delete default_striping_policy_; + } +} + +void Volume::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Volume::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Volume_descriptor_; +} + +const Volume& Volume::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +Volume* Volume::default_instance_ = NULL; + +Volume* Volume::New() const { + return new Volume; +} + +void Volume::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + access_control_policy_ = 1; + if (has_default_striping_policy()) { + if (default_striping_policy_ != NULL) default_striping_policy_->::xtreemfs::pbrpc::StripingPolicy::Clear(); + } + if (has_id()) { + if (id_ != &::google::protobuf::internal::kEmptyString) { + id_->clear(); + } + } + mode_ = 0u; + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_owner_group_id()) { + if (owner_group_id_ != &::google::protobuf::internal::kEmptyString) { + owner_group_id_->clear(); + } + } + if (has_owner_user_id()) { + if (owner_user_id_ != &::google::protobuf::internal::kEmptyString) { + owner_user_id_->clear(); + } + } + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + quota_ = GOOGLE_ULONGLONG(0); + } + attrs_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Volume::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::AccessControlPolicyType_IsValid(value)) { + set_access_control_policy(static_cast< ::xtreemfs::pbrpc::AccessControlPolicyType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_default_striping_policy; + break; + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_default_striping_policy: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_default_striping_policy())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_id; + break; + } + + // required string id = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->id().data(), this->id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(37)) goto parse_mode; + break; + } + + // required fixed32 mode = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_mode: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &mode_))); + set_has_mode(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_name; + break; + } + + // required string name = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(50)) goto parse_owner_group_id; + break; + } + + // required string owner_group_id = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_owner_group_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_owner_group_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_group_id().data(), this->owner_group_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(58)) goto parse_owner_user_id; + break; + } + + // required string owner_user_id = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_owner_user_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_owner_user_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_user_id().data(), this->owner_user_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(66)) goto parse_attrs; + break; + } + + // repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_attrs: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_attrs())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(66)) goto parse_attrs; + if (input->ExpectTag(73)) goto parse_quota; + break; + } + + // optional fixed64 quota = 9; + case 9: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_quota: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, "a_))); + set_has_quota(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Volume::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + if (has_access_control_policy()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->access_control_policy(), output); + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + if (has_default_striping_policy()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->default_striping_policy(), output); + } + + // required string id = 3; + if (has_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->id().data(), this->id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->id(), output); + } + + // required fixed32 mode = 4; + if (has_mode()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(4, this->mode(), output); + } + + // required string name = 5; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 5, this->name(), output); + } + + // required string owner_group_id = 6; + if (has_owner_group_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_group_id().data(), this->owner_group_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 6, this->owner_group_id(), output); + } + + // required string owner_user_id = 7; + if (has_owner_user_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_user_id().data(), this->owner_user_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 7, this->owner_user_id(), output); + } + + // repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + for (int i = 0; i < this->attrs_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 8, this->attrs(i), output); + } + + // optional fixed64 quota = 9; + if (has_quota()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(9, this->quota(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Volume::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + if (has_access_control_policy()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->access_control_policy(), target); + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + if (has_default_striping_policy()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->default_striping_policy(), target); + } + + // required string id = 3; + if (has_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->id().data(), this->id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->id(), target); + } + + // required fixed32 mode = 4; + if (has_mode()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(4, this->mode(), target); + } + + // required string name = 5; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 5, this->name(), target); + } + + // required string owner_group_id = 6; + if (has_owner_group_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_group_id().data(), this->owner_group_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 6, this->owner_group_id(), target); + } + + // required string owner_user_id = 7; + if (has_owner_user_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_user_id().data(), this->owner_user_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 7, this->owner_user_id(), target); + } + + // repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + for (int i = 0; i < this->attrs_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 8, this->attrs(i), target); + } + + // optional fixed64 quota = 9; + if (has_quota()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(9, this->quota(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Volume::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + if (has_access_control_policy()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->access_control_policy()); + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + if (has_default_striping_policy()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->default_striping_policy()); + } + + // required string id = 3; + if (has_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->id()); + } + + // required fixed32 mode = 4; + if (has_mode()) { + total_size += 1 + 4; + } + + // required string name = 5; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // required string owner_group_id = 6; + if (has_owner_group_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->owner_group_id()); + } + + // required string owner_user_id = 7; + if (has_owner_user_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->owner_user_id()); + } + + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // optional fixed64 quota = 9; + if (has_quota()) { + total_size += 1 + 8; + } + + } + // repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + total_size += 1 * this->attrs_size(); + for (int i = 0; i < this->attrs_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->attrs(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Volume::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Volume* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Volume::MergeFrom(const Volume& from) { + GOOGLE_CHECK_NE(&from, this); + attrs_.MergeFrom(from.attrs_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_access_control_policy()) { + set_access_control_policy(from.access_control_policy()); + } + if (from.has_default_striping_policy()) { + mutable_default_striping_policy()->::xtreemfs::pbrpc::StripingPolicy::MergeFrom(from.default_striping_policy()); + } + if (from.has_id()) { + set_id(from.id()); + } + if (from.has_mode()) { + set_mode(from.mode()); + } + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_owner_group_id()) { + set_owner_group_id(from.owner_group_id()); + } + if (from.has_owner_user_id()) { + set_owner_user_id(from.owner_user_id()); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_quota()) { + set_quota(from.quota()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Volume::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Volume::CopyFrom(const Volume& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Volume::IsInitialized() const { + if ((_has_bits_[0] & 0x0000007f) != 0x0000007f) return false; + + if (has_default_striping_policy()) { + if (!this->default_striping_policy().IsInitialized()) return false; + } + for (int i = 0; i < attrs_size(); i++) { + if (!this->attrs(i).IsInitialized()) return false; + } + return true; +} + +void Volume::Swap(Volume* other) { + if (other != this) { + std::swap(access_control_policy_, other->access_control_policy_); + std::swap(default_striping_policy_, other->default_striping_policy_); + std::swap(id_, other->id_); + std::swap(mode_, other->mode_); + std::swap(name_, other->name_); + std::swap(owner_group_id_, other->owner_group_id_); + std::swap(owner_user_id_, other->owner_user_id_); + attrs_.Swap(&other->attrs_); + std::swap(quota_, other->quota_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Volume::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Volume_descriptor_; + metadata.reflection = Volume_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Volumes::kVolumesFieldNumber; +#endif // !_MSC_VER + +Volumes::Volumes() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Volumes::InitAsDefaultInstance() { +} + +Volumes::Volumes(const Volumes& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Volumes::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Volumes::~Volumes() { + SharedDtor(); +} + +void Volumes::SharedDtor() { + if (this != default_instance_) { + } +} + +void Volumes::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Volumes::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Volumes_descriptor_; +} + +const Volumes& Volumes::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +Volumes* Volumes::default_instance_ = NULL; + +Volumes* Volumes::New() const { + return new Volumes; +} + +void Volumes::Clear() { + volumes_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Volumes::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .xtreemfs.pbrpc.Volume volumes = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_volumes: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_volumes())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_volumes; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Volumes::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .xtreemfs.pbrpc.Volume volumes = 1; + for (int i = 0; i < this->volumes_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->volumes(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Volumes::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .xtreemfs.pbrpc.Volume volumes = 1; + for (int i = 0; i < this->volumes_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->volumes(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Volumes::ByteSize() const { + int total_size = 0; + + // repeated .xtreemfs.pbrpc.Volume volumes = 1; + total_size += 1 * this->volumes_size(); + for (int i = 0; i < this->volumes_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->volumes(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Volumes::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Volumes* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Volumes::MergeFrom(const Volumes& from) { + GOOGLE_CHECK_NE(&from, this); + volumes_.MergeFrom(from.volumes_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Volumes::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Volumes::CopyFrom(const Volumes& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Volumes::IsInitialized() const { + + for (int i = 0; i < volumes_size(); i++) { + if (!this->volumes(i).IsInitialized()) return false; + } + return true; +} + +void Volumes::Swap(Volumes* other) { + if (other != this) { + volumes_.Swap(&other->volumes_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Volumes::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Volumes_descriptor_; + metadata.reflection = Volumes_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int StatVFS::kBsizeFieldNumber; +const int StatVFS::kBavailFieldNumber; +const int StatVFS::kBfreeFieldNumber; +const int StatVFS::kBlocksFieldNumber; +const int StatVFS::kFsidFieldNumber; +const int StatVFS::kNamemaxFieldNumber; +const int StatVFS::kAccessControlPolicyFieldNumber; +const int StatVFS::kDefaultStripingPolicyFieldNumber; +const int StatVFS::kEtagFieldNumber; +const int StatVFS::kModeFieldNumber; +const int StatVFS::kNameFieldNumber; +const int StatVFS::kOwnerGroupIdFieldNumber; +const int StatVFS::kOwnerUserIdFieldNumber; +#endif // !_MSC_VER + +StatVFS::StatVFS() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void StatVFS::InitAsDefaultInstance() { + default_striping_policy_ = const_cast< ::xtreemfs::pbrpc::StripingPolicy*>(&::xtreemfs::pbrpc::StripingPolicy::default_instance()); +} + +StatVFS::StatVFS(const StatVFS& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void StatVFS::SharedCtor() { + _cached_size_ = 0; + bsize_ = 0u; + bavail_ = GOOGLE_ULONGLONG(0); + bfree_ = GOOGLE_ULONGLONG(0); + blocks_ = GOOGLE_ULONGLONG(0); + fsid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + namemax_ = 0u; + access_control_policy_ = 1; + default_striping_policy_ = NULL; + etag_ = GOOGLE_ULONGLONG(0); + mode_ = 0u; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + owner_group_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + owner_user_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +StatVFS::~StatVFS() { + SharedDtor(); +} + +void StatVFS::SharedDtor() { + if (fsid_ != &::google::protobuf::internal::kEmptyString) { + delete fsid_; + } + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (owner_group_id_ != &::google::protobuf::internal::kEmptyString) { + delete owner_group_id_; + } + if (owner_user_id_ != &::google::protobuf::internal::kEmptyString) { + delete owner_user_id_; + } + if (this != default_instance_) { + delete default_striping_policy_; + } +} + +void StatVFS::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* StatVFS::descriptor() { + protobuf_AssignDescriptorsOnce(); + return StatVFS_descriptor_; +} + +const StatVFS& StatVFS::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +StatVFS* StatVFS::default_instance_ = NULL; + +StatVFS* StatVFS::New() const { + return new StatVFS; +} + +void StatVFS::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + bsize_ = 0u; + bavail_ = GOOGLE_ULONGLONG(0); + bfree_ = GOOGLE_ULONGLONG(0); + blocks_ = GOOGLE_ULONGLONG(0); + if (has_fsid()) { + if (fsid_ != &::google::protobuf::internal::kEmptyString) { + fsid_->clear(); + } + } + namemax_ = 0u; + access_control_policy_ = 1; + if (has_default_striping_policy()) { + if (default_striping_policy_ != NULL) default_striping_policy_->::xtreemfs::pbrpc::StripingPolicy::Clear(); + } + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + etag_ = GOOGLE_ULONGLONG(0); + mode_ = 0u; + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_owner_group_id()) { + if (owner_group_id_ != &::google::protobuf::internal::kEmptyString) { + owner_group_id_->clear(); + } + } + if (has_owner_user_id()) { + if (owner_user_id_ != &::google::protobuf::internal::kEmptyString) { + owner_user_id_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool StatVFS::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed32 bsize = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &bsize_))); + set_has_bsize(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(17)) goto parse_bavail; + break; + } + + // required fixed64 bavail = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_bavail: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &bavail_))); + set_has_bavail(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_blocks; + break; + } + + // required fixed64 blocks = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_blocks: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &blocks_))); + set_has_blocks(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_fsid; + break; + } + + // required string fsid = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_fsid: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_fsid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->fsid().data(), this->fsid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(45)) goto parse_namemax; + break; + } + + // required fixed32 namemax = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_namemax: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &namemax_))); + set_has_namemax(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(48)) goto parse_access_control_policy; + break; + } + + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_access_control_policy: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::AccessControlPolicyType_IsValid(value)) { + set_access_control_policy(static_cast< ::xtreemfs::pbrpc::AccessControlPolicyType >(value)); + } else { + mutable_unknown_fields()->AddVarint(6, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(58)) goto parse_default_striping_policy; + break; + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_default_striping_policy: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_default_striping_policy())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(65)) goto parse_etag; + break; + } + + // required fixed64 etag = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_etag: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &etag_))); + set_has_etag(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(77)) goto parse_mode; + break; + } + + // required fixed32 mode = 9; + case 9: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_mode: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &mode_))); + set_has_mode(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(82)) goto parse_name; + break; + } + + // required string name = 10; + case 10: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(90)) goto parse_owner_group_id; + break; + } + + // required string owner_group_id = 11; + case 11: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_owner_group_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_owner_group_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_group_id().data(), this->owner_group_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(98)) goto parse_owner_user_id; + break; + } + + // required string owner_user_id = 12; + case 12: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_owner_user_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_owner_user_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_user_id().data(), this->owner_user_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(105)) goto parse_bfree; + break; + } + + // optional fixed64 bfree = 13; + case 13: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_bfree: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &bfree_))); + set_has_bfree(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void StatVFS::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed32 bsize = 1; + if (has_bsize()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(1, this->bsize(), output); + } + + // required fixed64 bavail = 2; + if (has_bavail()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(2, this->bavail(), output); + } + + // required fixed64 blocks = 3; + if (has_blocks()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->blocks(), output); + } + + // required string fsid = 4; + if (has_fsid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->fsid().data(), this->fsid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->fsid(), output); + } + + // required fixed32 namemax = 5; + if (has_namemax()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(5, this->namemax(), output); + } + + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + if (has_access_control_policy()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 6, this->access_control_policy(), output); + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + if (has_default_striping_policy()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 7, this->default_striping_policy(), output); + } + + // required fixed64 etag = 8; + if (has_etag()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(8, this->etag(), output); + } + + // required fixed32 mode = 9; + if (has_mode()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(9, this->mode(), output); + } + + // required string name = 10; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 10, this->name(), output); + } + + // required string owner_group_id = 11; + if (has_owner_group_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_group_id().data(), this->owner_group_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 11, this->owner_group_id(), output); + } + + // required string owner_user_id = 12; + if (has_owner_user_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_user_id().data(), this->owner_user_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 12, this->owner_user_id(), output); + } + + // optional fixed64 bfree = 13; + if (has_bfree()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(13, this->bfree(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* StatVFS::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed32 bsize = 1; + if (has_bsize()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(1, this->bsize(), target); + } + + // required fixed64 bavail = 2; + if (has_bavail()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(2, this->bavail(), target); + } + + // required fixed64 blocks = 3; + if (has_blocks()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->blocks(), target); + } + + // required string fsid = 4; + if (has_fsid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->fsid().data(), this->fsid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->fsid(), target); + } + + // required fixed32 namemax = 5; + if (has_namemax()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(5, this->namemax(), target); + } + + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + if (has_access_control_policy()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 6, this->access_control_policy(), target); + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + if (has_default_striping_policy()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 7, this->default_striping_policy(), target); + } + + // required fixed64 etag = 8; + if (has_etag()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(8, this->etag(), target); + } + + // required fixed32 mode = 9; + if (has_mode()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(9, this->mode(), target); + } + + // required string name = 10; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 10, this->name(), target); + } + + // required string owner_group_id = 11; + if (has_owner_group_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_group_id().data(), this->owner_group_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 11, this->owner_group_id(), target); + } + + // required string owner_user_id = 12; + if (has_owner_user_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->owner_user_id().data(), this->owner_user_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 12, this->owner_user_id(), target); + } + + // optional fixed64 bfree = 13; + if (has_bfree()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(13, this->bfree(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int StatVFS::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed32 bsize = 1; + if (has_bsize()) { + total_size += 1 + 4; + } + + // required fixed64 bavail = 2; + if (has_bavail()) { + total_size += 1 + 8; + } + + // optional fixed64 bfree = 13; + if (has_bfree()) { + total_size += 1 + 8; + } + + // required fixed64 blocks = 3; + if (has_blocks()) { + total_size += 1 + 8; + } + + // required string fsid = 4; + if (has_fsid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->fsid()); + } + + // required fixed32 namemax = 5; + if (has_namemax()) { + total_size += 1 + 4; + } + + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + if (has_access_control_policy()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->access_control_policy()); + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + if (has_default_striping_policy()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->default_striping_policy()); + } + + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // required fixed64 etag = 8; + if (has_etag()) { + total_size += 1 + 8; + } + + // required fixed32 mode = 9; + if (has_mode()) { + total_size += 1 + 4; + } + + // required string name = 10; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // required string owner_group_id = 11; + if (has_owner_group_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->owner_group_id()); + } + + // required string owner_user_id = 12; + if (has_owner_user_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->owner_user_id()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void StatVFS::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const StatVFS* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void StatVFS::MergeFrom(const StatVFS& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_bsize()) { + set_bsize(from.bsize()); + } + if (from.has_bavail()) { + set_bavail(from.bavail()); + } + if (from.has_bfree()) { + set_bfree(from.bfree()); + } + if (from.has_blocks()) { + set_blocks(from.blocks()); + } + if (from.has_fsid()) { + set_fsid(from.fsid()); + } + if (from.has_namemax()) { + set_namemax(from.namemax()); + } + if (from.has_access_control_policy()) { + set_access_control_policy(from.access_control_policy()); + } + if (from.has_default_striping_policy()) { + mutable_default_striping_policy()->::xtreemfs::pbrpc::StripingPolicy::MergeFrom(from.default_striping_policy()); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_etag()) { + set_etag(from.etag()); + } + if (from.has_mode()) { + set_mode(from.mode()); + } + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_owner_group_id()) { + set_owner_group_id(from.owner_group_id()); + } + if (from.has_owner_user_id()) { + set_owner_user_id(from.owner_user_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void StatVFS::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void StatVFS::CopyFrom(const StatVFS& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool StatVFS::IsInitialized() const { + if ((_has_bits_[0] & 0x00001ffb) != 0x00001ffb) return false; + + if (has_default_striping_policy()) { + if (!this->default_striping_policy().IsInitialized()) return false; + } + return true; +} + +void StatVFS::Swap(StatVFS* other) { + if (other != this) { + std::swap(bsize_, other->bsize_); + std::swap(bavail_, other->bavail_); + std::swap(bfree_, other->bfree_); + std::swap(blocks_, other->blocks_); + std::swap(fsid_, other->fsid_); + std::swap(namemax_, other->namemax_); + std::swap(access_control_policy_, other->access_control_policy_); + std::swap(default_striping_policy_, other->default_striping_policy_); + std::swap(etag_, other->etag_); + std::swap(mode_, other->mode_); + std::swap(name_, other->name_); + std::swap(owner_group_id_, other->owner_group_id_); + std::swap(owner_user_id_, other->owner_user_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata StatVFS::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = StatVFS_descriptor_; + metadata.reflection = StatVFS_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int fsetattrRequest::kStbufFieldNumber; +const int fsetattrRequest::kToSetFieldNumber; +const int fsetattrRequest::kCapFieldNumber; +#endif // !_MSC_VER + +fsetattrRequest::fsetattrRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void fsetattrRequest::InitAsDefaultInstance() { + stbuf_ = const_cast< ::xtreemfs::pbrpc::Stat*>(&::xtreemfs::pbrpc::Stat::default_instance()); + cap_ = const_cast< ::xtreemfs::pbrpc::XCap*>(&::xtreemfs::pbrpc::XCap::default_instance()); +} + +fsetattrRequest::fsetattrRequest(const fsetattrRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void fsetattrRequest::SharedCtor() { + _cached_size_ = 0; + stbuf_ = NULL; + to_set_ = 0u; + cap_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +fsetattrRequest::~fsetattrRequest() { + SharedDtor(); +} + +void fsetattrRequest::SharedDtor() { + if (this != default_instance_) { + delete stbuf_; + delete cap_; + } +} + +void fsetattrRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* fsetattrRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return fsetattrRequest_descriptor_; +} + +const fsetattrRequest& fsetattrRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +fsetattrRequest* fsetattrRequest::default_instance_ = NULL; + +fsetattrRequest* fsetattrRequest::New() const { + return new fsetattrRequest; +} + +void fsetattrRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_stbuf()) { + if (stbuf_ != NULL) stbuf_->::xtreemfs::pbrpc::Stat::Clear(); + } + to_set_ = 0u; + if (has_cap()) { + if (cap_ != NULL) cap_->::xtreemfs::pbrpc::XCap::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool fsetattrRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.Stat stbuf = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_stbuf())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(21)) goto parse_to_set; + break; + } + + // required fixed32 to_set = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_to_set: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &to_set_))); + set_has_to_set(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_cap; + break; + } + + // required .xtreemfs.pbrpc.XCap cap = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_cap: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_cap())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void fsetattrRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.Stat stbuf = 1; + if (has_stbuf()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->stbuf(), output); + } + + // required fixed32 to_set = 2; + if (has_to_set()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(2, this->to_set(), output); + } + + // required .xtreemfs.pbrpc.XCap cap = 3; + if (has_cap()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->cap(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* fsetattrRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.Stat stbuf = 1; + if (has_stbuf()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->stbuf(), target); + } + + // required fixed32 to_set = 2; + if (has_to_set()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(2, this->to_set(), target); + } + + // required .xtreemfs.pbrpc.XCap cap = 3; + if (has_cap()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->cap(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int fsetattrRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.Stat stbuf = 1; + if (has_stbuf()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->stbuf()); + } + + // required fixed32 to_set = 2; + if (has_to_set()) { + total_size += 1 + 4; + } + + // required .xtreemfs.pbrpc.XCap cap = 3; + if (has_cap()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->cap()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void fsetattrRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const fsetattrRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void fsetattrRequest::MergeFrom(const fsetattrRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_stbuf()) { + mutable_stbuf()->::xtreemfs::pbrpc::Stat::MergeFrom(from.stbuf()); + } + if (from.has_to_set()) { + set_to_set(from.to_set()); + } + if (from.has_cap()) { + mutable_cap()->::xtreemfs::pbrpc::XCap::MergeFrom(from.cap()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void fsetattrRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void fsetattrRequest::CopyFrom(const fsetattrRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool fsetattrRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + if (has_stbuf()) { + if (!this->stbuf().IsInitialized()) return false; + } + if (has_cap()) { + if (!this->cap().IsInitialized()) return false; + } + return true; +} + +void fsetattrRequest::Swap(fsetattrRequest* other) { + if (other != this) { + std::swap(stbuf_, other->stbuf_); + std::swap(to_set_, other->to_set_); + std::swap(cap_, other->cap_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata fsetattrRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = fsetattrRequest_descriptor_; + metadata.reflection = fsetattrRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int getattrRequest::kVolumeNameFieldNumber; +const int getattrRequest::kPathFieldNumber; +const int getattrRequest::kKnownEtagFieldNumber; +#endif // !_MSC_VER + +getattrRequest::getattrRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void getattrRequest::InitAsDefaultInstance() { +} + +getattrRequest::getattrRequest(const getattrRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void getattrRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + known_etag_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +getattrRequest::~getattrRequest() { + SharedDtor(); +} + +void getattrRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + } +} + +void getattrRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* getattrRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return getattrRequest_descriptor_; +} + +const getattrRequest& getattrRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +getattrRequest* getattrRequest::default_instance_ = NULL; + +getattrRequest* getattrRequest::New() const { + return new getattrRequest; +} + +void getattrRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + known_etag_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool getattrRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_known_etag; + break; + } + + // required fixed64 known_etag = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_known_etag: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &known_etag_))); + set_has_known_etag(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void getattrRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // required fixed64 known_etag = 3; + if (has_known_etag()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->known_etag(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* getattrRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // required fixed64 known_etag = 3; + if (has_known_etag()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->known_etag(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int getattrRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // required fixed64 known_etag = 3; + if (has_known_etag()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void getattrRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const getattrRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void getattrRequest::MergeFrom(const getattrRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_known_etag()) { + set_known_etag(from.known_etag()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void getattrRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void getattrRequest::CopyFrom(const getattrRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool getattrRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void getattrRequest::Swap(getattrRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(known_etag_, other->known_etag_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata getattrRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = getattrRequest_descriptor_; + metadata.reflection = getattrRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int getattrResponse::kStbufFieldNumber; +#endif // !_MSC_VER + +getattrResponse::getattrResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void getattrResponse::InitAsDefaultInstance() { + stbuf_ = const_cast< ::xtreemfs::pbrpc::Stat*>(&::xtreemfs::pbrpc::Stat::default_instance()); +} + +getattrResponse::getattrResponse(const getattrResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void getattrResponse::SharedCtor() { + _cached_size_ = 0; + stbuf_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +getattrResponse::~getattrResponse() { + SharedDtor(); +} + +void getattrResponse::SharedDtor() { + if (this != default_instance_) { + delete stbuf_; + } +} + +void getattrResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* getattrResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return getattrResponse_descriptor_; +} + +const getattrResponse& getattrResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +getattrResponse* getattrResponse::default_instance_ = NULL; + +getattrResponse* getattrResponse::New() const { + return new getattrResponse; +} + +void getattrResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_stbuf()) { + if (stbuf_ != NULL) stbuf_->::xtreemfs::pbrpc::Stat::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool getattrResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .xtreemfs.pbrpc.Stat stbuf = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_stbuf())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void getattrResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional .xtreemfs.pbrpc.Stat stbuf = 1; + if (has_stbuf()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->stbuf(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* getattrResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional .xtreemfs.pbrpc.Stat stbuf = 1; + if (has_stbuf()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->stbuf(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int getattrResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional .xtreemfs.pbrpc.Stat stbuf = 1; + if (has_stbuf()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->stbuf()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void getattrResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const getattrResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void getattrResponse::MergeFrom(const getattrResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_stbuf()) { + mutable_stbuf()->::xtreemfs::pbrpc::Stat::MergeFrom(from.stbuf()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void getattrResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void getattrResponse::CopyFrom(const getattrResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool getattrResponse::IsInitialized() const { + + if (has_stbuf()) { + if (!this->stbuf().IsInitialized()) return false; + } + return true; +} + +void getattrResponse::Swap(getattrResponse* other) { + if (other != this) { + std::swap(stbuf_, other->stbuf_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata getattrResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = getattrResponse_descriptor_; + metadata.reflection = getattrResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int getxattrRequest::kVolumeNameFieldNumber; +const int getxattrRequest::kPathFieldNumber; +const int getxattrRequest::kNameFieldNumber; +#endif // !_MSC_VER + +getxattrRequest::getxattrRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void getxattrRequest::InitAsDefaultInstance() { +} + +getxattrRequest::getxattrRequest(const getxattrRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void getxattrRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +getxattrRequest::~getxattrRequest() { + SharedDtor(); +} + +void getxattrRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + } +} + +void getxattrRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* getxattrRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return getxattrRequest_descriptor_; +} + +const getxattrRequest& getxattrRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +getxattrRequest* getxattrRequest::default_instance_ = NULL; + +getxattrRequest* getxattrRequest::New() const { + return new getxattrRequest; +} + +void getxattrRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool getxattrRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_name; + break; + } + + // required string name = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void getxattrRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // required string name = 3; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->name(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* getxattrRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // required string name = 3; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->name(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int getxattrRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // required string name = 3; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void getxattrRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const getxattrRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void getxattrRequest::MergeFrom(const getxattrRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_name()) { + set_name(from.name()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void getxattrRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void getxattrRequest::CopyFrom(const getxattrRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool getxattrRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void getxattrRequest::Swap(getxattrRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(name_, other->name_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata getxattrRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = getxattrRequest_descriptor_; + metadata.reflection = getxattrRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int getxattrResponse::kValueFieldNumber; +const int getxattrResponse::kValueBytesStringFieldNumber; +#endif // !_MSC_VER + +getxattrResponse::getxattrResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void getxattrResponse::InitAsDefaultInstance() { +} + +getxattrResponse::getxattrResponse(const getxattrResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void getxattrResponse::SharedCtor() { + _cached_size_ = 0; + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + value_bytes_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +getxattrResponse::~getxattrResponse() { + SharedDtor(); +} + +void getxattrResponse::SharedDtor() { + if (value_ != &::google::protobuf::internal::kEmptyString) { + delete value_; + } + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + delete value_bytes_string_; + } + if (this != default_instance_) { + } +} + +void getxattrResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* getxattrResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return getxattrResponse_descriptor_; +} + +const getxattrResponse& getxattrResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +getxattrResponse* getxattrResponse::default_instance_ = NULL; + +getxattrResponse* getxattrResponse::New() const { + return new getxattrResponse; +} + +void getxattrResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_value()) { + if (value_ != &::google::protobuf::internal::kEmptyString) { + value_->clear(); + } + } + if (has_value_bytes_string()) { + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + value_bytes_string_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool getxattrResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string value = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_value_bytes_string; + break; + } + + // optional bytes value_bytes_string = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_value_bytes_string: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_value_bytes_string())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void getxattrResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string value = 1; + if (has_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->value(), output); + } + + // optional bytes value_bytes_string = 2; + if (has_value_bytes_string()) { + ::google::protobuf::internal::WireFormatLite::WriteBytes( + 2, this->value_bytes_string(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* getxattrResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string value = 1; + if (has_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->value(), target); + } + + // optional bytes value_bytes_string = 2; + if (has_value_bytes_string()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 2, this->value_bytes_string(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int getxattrResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string value = 1; + if (has_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->value()); + } + + // optional bytes value_bytes_string = 2; + if (has_value_bytes_string()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->value_bytes_string()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void getxattrResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const getxattrResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void getxattrResponse::MergeFrom(const getxattrResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_value()) { + set_value(from.value()); + } + if (from.has_value_bytes_string()) { + set_value_bytes_string(from.value_bytes_string()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void getxattrResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void getxattrResponse::CopyFrom(const getxattrResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool getxattrResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void getxattrResponse::Swap(getxattrResponse* other) { + if (other != this) { + std::swap(value_, other->value_); + std::swap(value_bytes_string_, other->value_bytes_string_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata getxattrResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = getxattrResponse_descriptor_; + metadata.reflection = getxattrResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int linkRequest::kVolumeNameFieldNumber; +const int linkRequest::kTargetPathFieldNumber; +const int linkRequest::kLinkPathFieldNumber; +#endif // !_MSC_VER + +linkRequest::linkRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void linkRequest::InitAsDefaultInstance() { +} + +linkRequest::linkRequest(const linkRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void linkRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + target_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + link_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +linkRequest::~linkRequest() { + SharedDtor(); +} + +void linkRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + delete target_path_; + } + if (link_path_ != &::google::protobuf::internal::kEmptyString) { + delete link_path_; + } + if (this != default_instance_) { + } +} + +void linkRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* linkRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return linkRequest_descriptor_; +} + +const linkRequest& linkRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +linkRequest* linkRequest::default_instance_ = NULL; + +linkRequest* linkRequest::New() const { + return new linkRequest; +} + +void linkRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_target_path()) { + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + target_path_->clear(); + } + } + if (has_link_path()) { + if (link_path_ != &::google::protobuf::internal::kEmptyString) { + link_path_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool linkRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_target_path; + break; + } + + // required string target_path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_target_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_target_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->target_path().data(), this->target_path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_link_path; + break; + } + + // required string link_path = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_link_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_link_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->link_path().data(), this->link_path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void linkRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string target_path = 2; + if (has_target_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->target_path().data(), this->target_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->target_path(), output); + } + + // required string link_path = 3; + if (has_link_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->link_path().data(), this->link_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->link_path(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* linkRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string target_path = 2; + if (has_target_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->target_path().data(), this->target_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->target_path(), target); + } + + // required string link_path = 3; + if (has_link_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->link_path().data(), this->link_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->link_path(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int linkRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string target_path = 2; + if (has_target_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->target_path()); + } + + // required string link_path = 3; + if (has_link_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->link_path()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void linkRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const linkRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void linkRequest::MergeFrom(const linkRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_target_path()) { + set_target_path(from.target_path()); + } + if (from.has_link_path()) { + set_link_path(from.link_path()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void linkRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void linkRequest::CopyFrom(const linkRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool linkRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void linkRequest::Swap(linkRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(target_path_, other->target_path_); + std::swap(link_path_, other->link_path_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata linkRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = linkRequest_descriptor_; + metadata.reflection = linkRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int listxattrRequest::kVolumeNameFieldNumber; +const int listxattrRequest::kPathFieldNumber; +const int listxattrRequest::kNamesOnlyFieldNumber; +#endif // !_MSC_VER + +listxattrRequest::listxattrRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void listxattrRequest::InitAsDefaultInstance() { +} + +listxattrRequest::listxattrRequest(const listxattrRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void listxattrRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + names_only_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +listxattrRequest::~listxattrRequest() { + SharedDtor(); +} + +void listxattrRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + } +} + +void listxattrRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* listxattrRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return listxattrRequest_descriptor_; +} + +const listxattrRequest& listxattrRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +listxattrRequest* listxattrRequest::default_instance_ = NULL; + +listxattrRequest* listxattrRequest::New() const { + return new listxattrRequest; +} + +void listxattrRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + names_only_ = false; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool listxattrRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(24)) goto parse_names_only; + break; + } + + // required bool names_only = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_names_only: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &names_only_))); + set_has_names_only(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void listxattrRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // required bool names_only = 3; + if (has_names_only()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->names_only(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* listxattrRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // required bool names_only = 3; + if (has_names_only()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->names_only(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int listxattrRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // required bool names_only = 3; + if (has_names_only()) { + total_size += 1 + 1; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void listxattrRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const listxattrRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void listxattrRequest::MergeFrom(const listxattrRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_names_only()) { + set_names_only(from.names_only()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void listxattrRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void listxattrRequest::CopyFrom(const listxattrRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool listxattrRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void listxattrRequest::Swap(listxattrRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(names_only_, other->names_only_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata listxattrRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = listxattrRequest_descriptor_; + metadata.reflection = listxattrRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int listxattrResponse::kXattrsFieldNumber; +#endif // !_MSC_VER + +listxattrResponse::listxattrResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void listxattrResponse::InitAsDefaultInstance() { +} + +listxattrResponse::listxattrResponse(const listxattrResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void listxattrResponse::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +listxattrResponse::~listxattrResponse() { + SharedDtor(); +} + +void listxattrResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void listxattrResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* listxattrResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return listxattrResponse_descriptor_; +} + +const listxattrResponse& listxattrResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +listxattrResponse* listxattrResponse::default_instance_ = NULL; + +listxattrResponse* listxattrResponse::New() const { + return new listxattrResponse; +} + +void listxattrResponse::Clear() { + xattrs_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool listxattrResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_xattrs: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_xattrs())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_xattrs; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void listxattrResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + for (int i = 0; i < this->xattrs_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->xattrs(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* listxattrResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + for (int i = 0; i < this->xattrs_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->xattrs(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int listxattrResponse::ByteSize() const { + int total_size = 0; + + // repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + total_size += 1 * this->xattrs_size(); + for (int i = 0; i < this->xattrs_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->xattrs(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void listxattrResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const listxattrResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void listxattrResponse::MergeFrom(const listxattrResponse& from) { + GOOGLE_CHECK_NE(&from, this); + xattrs_.MergeFrom(from.xattrs_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void listxattrResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void listxattrResponse::CopyFrom(const listxattrResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool listxattrResponse::IsInitialized() const { + + for (int i = 0; i < xattrs_size(); i++) { + if (!this->xattrs(i).IsInitialized()) return false; + } + return true; +} + +void listxattrResponse::Swap(listxattrResponse* other) { + if (other != this) { + xattrs_.Swap(&other->xattrs_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata listxattrResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = listxattrResponse_descriptor_; + metadata.reflection = listxattrResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int mkdirRequest::kVolumeNameFieldNumber; +const int mkdirRequest::kPathFieldNumber; +const int mkdirRequest::kModeFieldNumber; +#endif // !_MSC_VER + +mkdirRequest::mkdirRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void mkdirRequest::InitAsDefaultInstance() { +} + +mkdirRequest::mkdirRequest(const mkdirRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void mkdirRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + mode_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +mkdirRequest::~mkdirRequest() { + SharedDtor(); +} + +void mkdirRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + } +} + +void mkdirRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* mkdirRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return mkdirRequest_descriptor_; +} + +const mkdirRequest& mkdirRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +mkdirRequest* mkdirRequest::default_instance_ = NULL; + +mkdirRequest* mkdirRequest::New() const { + return new mkdirRequest; +} + +void mkdirRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + mode_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool mkdirRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(29)) goto parse_mode; + break; + } + + // required fixed32 mode = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_mode: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &mode_))); + set_has_mode(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void mkdirRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // required fixed32 mode = 3; + if (has_mode()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(3, this->mode(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* mkdirRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // required fixed32 mode = 3; + if (has_mode()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(3, this->mode(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int mkdirRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // required fixed32 mode = 3; + if (has_mode()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void mkdirRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const mkdirRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void mkdirRequest::MergeFrom(const mkdirRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_mode()) { + set_mode(from.mode()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void mkdirRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void mkdirRequest::CopyFrom(const mkdirRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool mkdirRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void mkdirRequest::Swap(mkdirRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(mode_, other->mode_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata mkdirRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = mkdirRequest_descriptor_; + metadata.reflection = mkdirRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int openRequest::kVolumeNameFieldNumber; +const int openRequest::kPathFieldNumber; +const int openRequest::kFlagsFieldNumber; +const int openRequest::kModeFieldNumber; +const int openRequest::kAttributesFieldNumber; +const int openRequest::kCoordinatesFieldNumber; +#endif // !_MSC_VER + +openRequest::openRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void openRequest::InitAsDefaultInstance() { + coordinates_ = const_cast< ::xtreemfs::pbrpc::VivaldiCoordinates*>(&::xtreemfs::pbrpc::VivaldiCoordinates::default_instance()); +} + +openRequest::openRequest(const openRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void openRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + flags_ = 0u; + mode_ = 0u; + attributes_ = 0u; + coordinates_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +openRequest::~openRequest() { + SharedDtor(); +} + +void openRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + delete coordinates_; + } +} + +void openRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* openRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return openRequest_descriptor_; +} + +const openRequest& openRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +openRequest* openRequest::default_instance_ = NULL; + +openRequest* openRequest::New() const { + return new openRequest; +} + +void openRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + flags_ = 0u; + mode_ = 0u; + attributes_ = 0u; + if (has_coordinates()) { + if (coordinates_ != NULL) coordinates_->::xtreemfs::pbrpc::VivaldiCoordinates::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool openRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(29)) goto parse_flags; + break; + } + + // required fixed32 flags = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_flags: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &flags_))); + set_has_flags(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(37)) goto parse_mode; + break; + } + + // required fixed32 mode = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_mode: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &mode_))); + set_has_mode(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(45)) goto parse_attributes; + break; + } + + // required fixed32 attributes = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_attributes: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &attributes_))); + set_has_attributes(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(50)) goto parse_coordinates; + break; + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_coordinates: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_coordinates())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void openRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // required fixed32 flags = 3; + if (has_flags()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(3, this->flags(), output); + } + + // required fixed32 mode = 4; + if (has_mode()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(4, this->mode(), output); + } + + // required fixed32 attributes = 5; + if (has_attributes()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(5, this->attributes(), output); + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + if (has_coordinates()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 6, this->coordinates(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* openRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // required fixed32 flags = 3; + if (has_flags()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(3, this->flags(), target); + } + + // required fixed32 mode = 4; + if (has_mode()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(4, this->mode(), target); + } + + // required fixed32 attributes = 5; + if (has_attributes()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(5, this->attributes(), target); + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + if (has_coordinates()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, this->coordinates(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int openRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // required fixed32 flags = 3; + if (has_flags()) { + total_size += 1 + 4; + } + + // required fixed32 mode = 4; + if (has_mode()) { + total_size += 1 + 4; + } + + // required fixed32 attributes = 5; + if (has_attributes()) { + total_size += 1 + 4; + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + if (has_coordinates()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->coordinates()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void openRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const openRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void openRequest::MergeFrom(const openRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_flags()) { + set_flags(from.flags()); + } + if (from.has_mode()) { + set_mode(from.mode()); + } + if (from.has_attributes()) { + set_attributes(from.attributes()); + } + if (from.has_coordinates()) { + mutable_coordinates()->::xtreemfs::pbrpc::VivaldiCoordinates::MergeFrom(from.coordinates()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void openRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void openRequest::CopyFrom(const openRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool openRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false; + + if (has_coordinates()) { + if (!this->coordinates().IsInitialized()) return false; + } + return true; +} + +void openRequest::Swap(openRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(flags_, other->flags_); + std::swap(mode_, other->mode_); + std::swap(attributes_, other->attributes_); + std::swap(coordinates_, other->coordinates_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata openRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = openRequest_descriptor_; + metadata.reflection = openRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int openResponse::kCredsFieldNumber; +const int openResponse::kTimestampSFieldNumber; +#endif // !_MSC_VER + +openResponse::openResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void openResponse::InitAsDefaultInstance() { + creds_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +openResponse::openResponse(const openResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void openResponse::SharedCtor() { + _cached_size_ = 0; + creds_ = NULL; + timestamp_s_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +openResponse::~openResponse() { + SharedDtor(); +} + +void openResponse::SharedDtor() { + if (this != default_instance_) { + delete creds_; + } +} + +void openResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* openResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return openResponse_descriptor_; +} + +const openResponse& openResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +openResponse* openResponse::default_instance_ = NULL; + +openResponse* openResponse::New() const { + return new openResponse; +} + +void openResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_creds()) { + if (creds_ != NULL) creds_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + timestamp_s_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool openResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials creds = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_creds())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(21)) goto parse_timestamp_s; + break; + } + + // required fixed32 timestamp_s = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_timestamp_s: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, ×tamp_s_))); + set_has_timestamp_s(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void openResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials creds = 1; + if (has_creds()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->creds(), output); + } + + // required fixed32 timestamp_s = 2; + if (has_timestamp_s()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(2, this->timestamp_s(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* openResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials creds = 1; + if (has_creds()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->creds(), target); + } + + // required fixed32 timestamp_s = 2; + if (has_timestamp_s()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(2, this->timestamp_s(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int openResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials creds = 1; + if (has_creds()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->creds()); + } + + // required fixed32 timestamp_s = 2; + if (has_timestamp_s()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void openResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const openResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void openResponse::MergeFrom(const openResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_creds()) { + mutable_creds()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.creds()); + } + if (from.has_timestamp_s()) { + set_timestamp_s(from.timestamp_s()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void openResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void openResponse::CopyFrom(const openResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool openResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_creds()) { + if (!this->creds().IsInitialized()) return false; + } + return true; +} + +void openResponse::Swap(openResponse* other) { + if (other != this) { + std::swap(creds_, other->creds_); + std::swap(timestamp_s_, other->timestamp_s_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata openResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = openResponse_descriptor_; + metadata.reflection = openResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int readdirRequest::kVolumeNameFieldNumber; +const int readdirRequest::kPathFieldNumber; +const int readdirRequest::kKnownEtagFieldNumber; +const int readdirRequest::kLimitDirectoryEntriesCountFieldNumber; +const int readdirRequest::kNamesOnlyFieldNumber; +const int readdirRequest::kSeenDirectoryEntriesCountFieldNumber; +#endif // !_MSC_VER + +readdirRequest::readdirRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void readdirRequest::InitAsDefaultInstance() { +} + +readdirRequest::readdirRequest(const readdirRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void readdirRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + known_etag_ = GOOGLE_ULONGLONG(0); + limit_directory_entries_count_ = 0u; + names_only_ = false; + seen_directory_entries_count_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +readdirRequest::~readdirRequest() { + SharedDtor(); +} + +void readdirRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + } +} + +void readdirRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* readdirRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return readdirRequest_descriptor_; +} + +const readdirRequest& readdirRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +readdirRequest* readdirRequest::default_instance_ = NULL; + +readdirRequest* readdirRequest::New() const { + return new readdirRequest; +} + +void readdirRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + known_etag_ = GOOGLE_ULONGLONG(0); + limit_directory_entries_count_ = 0u; + names_only_ = false; + seen_directory_entries_count_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool readdirRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_known_etag; + break; + } + + // required fixed64 known_etag = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_known_etag: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &known_etag_))); + set_has_known_etag(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(37)) goto parse_limit_directory_entries_count; + break; + } + + // required fixed32 limit_directory_entries_count = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_limit_directory_entries_count: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &limit_directory_entries_count_))); + set_has_limit_directory_entries_count(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(40)) goto parse_names_only; + break; + } + + // required bool names_only = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_names_only: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &names_only_))); + set_has_names_only(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(49)) goto parse_seen_directory_entries_count; + break; + } + + // required fixed64 seen_directory_entries_count = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_seen_directory_entries_count: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &seen_directory_entries_count_))); + set_has_seen_directory_entries_count(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void readdirRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // required fixed64 known_etag = 3; + if (has_known_etag()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->known_etag(), output); + } + + // required fixed32 limit_directory_entries_count = 4; + if (has_limit_directory_entries_count()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(4, this->limit_directory_entries_count(), output); + } + + // required bool names_only = 5; + if (has_names_only()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->names_only(), output); + } + + // required fixed64 seen_directory_entries_count = 6; + if (has_seen_directory_entries_count()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(6, this->seen_directory_entries_count(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* readdirRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // required fixed64 known_etag = 3; + if (has_known_etag()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->known_etag(), target); + } + + // required fixed32 limit_directory_entries_count = 4; + if (has_limit_directory_entries_count()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(4, this->limit_directory_entries_count(), target); + } + + // required bool names_only = 5; + if (has_names_only()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->names_only(), target); + } + + // required fixed64 seen_directory_entries_count = 6; + if (has_seen_directory_entries_count()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(6, this->seen_directory_entries_count(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int readdirRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // required fixed64 known_etag = 3; + if (has_known_etag()) { + total_size += 1 + 8; + } + + // required fixed32 limit_directory_entries_count = 4; + if (has_limit_directory_entries_count()) { + total_size += 1 + 4; + } + + // required bool names_only = 5; + if (has_names_only()) { + total_size += 1 + 1; + } + + // required fixed64 seen_directory_entries_count = 6; + if (has_seen_directory_entries_count()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void readdirRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const readdirRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void readdirRequest::MergeFrom(const readdirRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_known_etag()) { + set_known_etag(from.known_etag()); + } + if (from.has_limit_directory_entries_count()) { + set_limit_directory_entries_count(from.limit_directory_entries_count()); + } + if (from.has_names_only()) { + set_names_only(from.names_only()); + } + if (from.has_seen_directory_entries_count()) { + set_seen_directory_entries_count(from.seen_directory_entries_count()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void readdirRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void readdirRequest::CopyFrom(const readdirRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool readdirRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000003f) != 0x0000003f) return false; + + return true; +} + +void readdirRequest::Swap(readdirRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(known_etag_, other->known_etag_); + std::swap(limit_directory_entries_count_, other->limit_directory_entries_count_); + std::swap(names_only_, other->names_only_); + std::swap(seen_directory_entries_count_, other->seen_directory_entries_count_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata readdirRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = readdirRequest_descriptor_; + metadata.reflection = readdirRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int readlinkRequest::kVolumeNameFieldNumber; +const int readlinkRequest::kPathFieldNumber; +#endif // !_MSC_VER + +readlinkRequest::readlinkRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void readlinkRequest::InitAsDefaultInstance() { +} + +readlinkRequest::readlinkRequest(const readlinkRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void readlinkRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +readlinkRequest::~readlinkRequest() { + SharedDtor(); +} + +void readlinkRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + } +} + +void readlinkRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* readlinkRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return readlinkRequest_descriptor_; +} + +const readlinkRequest& readlinkRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +readlinkRequest* readlinkRequest::default_instance_ = NULL; + +readlinkRequest* readlinkRequest::New() const { + return new readlinkRequest; +} + +void readlinkRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool readlinkRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void readlinkRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* readlinkRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int readlinkRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void readlinkRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const readlinkRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void readlinkRequest::MergeFrom(const readlinkRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void readlinkRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void readlinkRequest::CopyFrom(const readlinkRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool readlinkRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void readlinkRequest::Swap(readlinkRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata readlinkRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = readlinkRequest_descriptor_; + metadata.reflection = readlinkRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int readlinkResponse::kLinkTargetPathFieldNumber; +#endif // !_MSC_VER + +readlinkResponse::readlinkResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void readlinkResponse::InitAsDefaultInstance() { +} + +readlinkResponse::readlinkResponse(const readlinkResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void readlinkResponse::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +readlinkResponse::~readlinkResponse() { + SharedDtor(); +} + +void readlinkResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void readlinkResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* readlinkResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return readlinkResponse_descriptor_; +} + +const readlinkResponse& readlinkResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +readlinkResponse* readlinkResponse::default_instance_ = NULL; + +readlinkResponse* readlinkResponse::New() const { + return new readlinkResponse; +} + +void readlinkResponse::Clear() { + link_target_path_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool readlinkResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string link_target_path = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_link_target_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_link_target_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->link_target_path(this->link_target_path_size() - 1).data(), + this->link_target_path(this->link_target_path_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_link_target_path; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void readlinkResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated string link_target_path = 1; + for (int i = 0; i < this->link_target_path_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->link_target_path(i).data(), this->link_target_path(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->link_target_path(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* readlinkResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated string link_target_path = 1; + for (int i = 0; i < this->link_target_path_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->link_target_path(i).data(), this->link_target_path(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->link_target_path(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int readlinkResponse::ByteSize() const { + int total_size = 0; + + // repeated string link_target_path = 1; + total_size += 1 * this->link_target_path_size(); + for (int i = 0; i < this->link_target_path_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->link_target_path(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void readlinkResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const readlinkResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void readlinkResponse::MergeFrom(const readlinkResponse& from) { + GOOGLE_CHECK_NE(&from, this); + link_target_path_.MergeFrom(from.link_target_path_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void readlinkResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void readlinkResponse::CopyFrom(const readlinkResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool readlinkResponse::IsInitialized() const { + + return true; +} + +void readlinkResponse::Swap(readlinkResponse* other) { + if (other != this) { + link_target_path_.Swap(&other->link_target_path_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata readlinkResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = readlinkResponse_descriptor_; + metadata.reflection = readlinkResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int removexattrRequest::kVolumeNameFieldNumber; +const int removexattrRequest::kPathFieldNumber; +const int removexattrRequest::kNameFieldNumber; +#endif // !_MSC_VER + +removexattrRequest::removexattrRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void removexattrRequest::InitAsDefaultInstance() { +} + +removexattrRequest::removexattrRequest(const removexattrRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void removexattrRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +removexattrRequest::~removexattrRequest() { + SharedDtor(); +} + +void removexattrRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + } +} + +void removexattrRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* removexattrRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return removexattrRequest_descriptor_; +} + +const removexattrRequest& removexattrRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +removexattrRequest* removexattrRequest::default_instance_ = NULL; + +removexattrRequest* removexattrRequest::New() const { + return new removexattrRequest; +} + +void removexattrRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool removexattrRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_name; + break; + } + + // required string name = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void removexattrRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // required string name = 3; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->name(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* removexattrRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // required string name = 3; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->name(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int removexattrRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // required string name = 3; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void removexattrRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const removexattrRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void removexattrRequest::MergeFrom(const removexattrRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_name()) { + set_name(from.name()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void removexattrRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void removexattrRequest::CopyFrom(const removexattrRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool removexattrRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void removexattrRequest::Swap(removexattrRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(name_, other->name_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata removexattrRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = removexattrRequest_descriptor_; + metadata.reflection = removexattrRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int renameRequest::kVolumeNameFieldNumber; +const int renameRequest::kSourcePathFieldNumber; +const int renameRequest::kTargetPathFieldNumber; +#endif // !_MSC_VER + +renameRequest::renameRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void renameRequest::InitAsDefaultInstance() { +} + +renameRequest::renameRequest(const renameRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void renameRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + source_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + target_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +renameRequest::~renameRequest() { + SharedDtor(); +} + +void renameRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (source_path_ != &::google::protobuf::internal::kEmptyString) { + delete source_path_; + } + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + delete target_path_; + } + if (this != default_instance_) { + } +} + +void renameRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* renameRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return renameRequest_descriptor_; +} + +const renameRequest& renameRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +renameRequest* renameRequest::default_instance_ = NULL; + +renameRequest* renameRequest::New() const { + return new renameRequest; +} + +void renameRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_source_path()) { + if (source_path_ != &::google::protobuf::internal::kEmptyString) { + source_path_->clear(); + } + } + if (has_target_path()) { + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + target_path_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool renameRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_source_path; + break; + } + + // required string source_path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_source_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_source_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->source_path().data(), this->source_path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_target_path; + break; + } + + // required string target_path = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_target_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_target_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->target_path().data(), this->target_path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void renameRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string source_path = 2; + if (has_source_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->source_path().data(), this->source_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->source_path(), output); + } + + // required string target_path = 3; + if (has_target_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->target_path().data(), this->target_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->target_path(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* renameRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string source_path = 2; + if (has_source_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->source_path().data(), this->source_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->source_path(), target); + } + + // required string target_path = 3; + if (has_target_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->target_path().data(), this->target_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->target_path(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int renameRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string source_path = 2; + if (has_source_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->source_path()); + } + + // required string target_path = 3; + if (has_target_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->target_path()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void renameRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const renameRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void renameRequest::MergeFrom(const renameRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_source_path()) { + set_source_path(from.source_path()); + } + if (from.has_target_path()) { + set_target_path(from.target_path()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void renameRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void renameRequest::CopyFrom(const renameRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool renameRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void renameRequest::Swap(renameRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(source_path_, other->source_path_); + std::swap(target_path_, other->target_path_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata renameRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = renameRequest_descriptor_; + metadata.reflection = renameRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int renameResponse::kTimestampSFieldNumber; +const int renameResponse::kCredsFieldNumber; +#endif // !_MSC_VER + +renameResponse::renameResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void renameResponse::InitAsDefaultInstance() { + creds_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +renameResponse::renameResponse(const renameResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void renameResponse::SharedCtor() { + _cached_size_ = 0; + timestamp_s_ = 0u; + creds_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +renameResponse::~renameResponse() { + SharedDtor(); +} + +void renameResponse::SharedDtor() { + if (this != default_instance_) { + delete creds_; + } +} + +void renameResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* renameResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return renameResponse_descriptor_; +} + +const renameResponse& renameResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +renameResponse* renameResponse::default_instance_ = NULL; + +renameResponse* renameResponse::New() const { + return new renameResponse; +} + +void renameResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + timestamp_s_ = 0u; + if (has_creds()) { + if (creds_ != NULL) creds_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool renameResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed32 timestamp_s = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, ×tamp_s_))); + set_has_timestamp_s(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_creds; + break; + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_creds: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_creds())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void renameResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed32 timestamp_s = 1; + if (has_timestamp_s()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(1, this->timestamp_s(), output); + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + if (has_creds()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->creds(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* renameResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed32 timestamp_s = 1; + if (has_timestamp_s()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(1, this->timestamp_s(), target); + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + if (has_creds()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->creds(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int renameResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed32 timestamp_s = 1; + if (has_timestamp_s()) { + total_size += 1 + 4; + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + if (has_creds()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->creds()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void renameResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const renameResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void renameResponse::MergeFrom(const renameResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_timestamp_s()) { + set_timestamp_s(from.timestamp_s()); + } + if (from.has_creds()) { + mutable_creds()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.creds()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void renameResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void renameResponse::CopyFrom(const renameResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool renameResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_creds()) { + if (!this->creds().IsInitialized()) return false; + } + return true; +} + +void renameResponse::Swap(renameResponse* other) { + if (other != this) { + std::swap(timestamp_s_, other->timestamp_s_); + std::swap(creds_, other->creds_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata renameResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = renameResponse_descriptor_; + metadata.reflection = renameResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int rmdirRequest::kVolumeNameFieldNumber; +const int rmdirRequest::kPathFieldNumber; +#endif // !_MSC_VER + +rmdirRequest::rmdirRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void rmdirRequest::InitAsDefaultInstance() { +} + +rmdirRequest::rmdirRequest(const rmdirRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void rmdirRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +rmdirRequest::~rmdirRequest() { + SharedDtor(); +} + +void rmdirRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + } +} + +void rmdirRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* rmdirRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return rmdirRequest_descriptor_; +} + +const rmdirRequest& rmdirRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +rmdirRequest* rmdirRequest::default_instance_ = NULL; + +rmdirRequest* rmdirRequest::New() const { + return new rmdirRequest; +} + +void rmdirRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool rmdirRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void rmdirRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* rmdirRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int rmdirRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void rmdirRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const rmdirRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void rmdirRequest::MergeFrom(const rmdirRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void rmdirRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void rmdirRequest::CopyFrom(const rmdirRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool rmdirRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void rmdirRequest::Swap(rmdirRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata rmdirRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = rmdirRequest_descriptor_; + metadata.reflection = rmdirRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int setattrRequest::kVolumeNameFieldNumber; +const int setattrRequest::kPathFieldNumber; +const int setattrRequest::kStbufFieldNumber; +const int setattrRequest::kToSetFieldNumber; +#endif // !_MSC_VER + +setattrRequest::setattrRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void setattrRequest::InitAsDefaultInstance() { + stbuf_ = const_cast< ::xtreemfs::pbrpc::Stat*>(&::xtreemfs::pbrpc::Stat::default_instance()); +} + +setattrRequest::setattrRequest(const setattrRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void setattrRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + stbuf_ = NULL; + to_set_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +setattrRequest::~setattrRequest() { + SharedDtor(); +} + +void setattrRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + delete stbuf_; + } +} + +void setattrRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* setattrRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return setattrRequest_descriptor_; +} + +const setattrRequest& setattrRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +setattrRequest* setattrRequest::default_instance_ = NULL; + +setattrRequest* setattrRequest::New() const { + return new setattrRequest; +} + +void setattrRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + if (has_stbuf()) { + if (stbuf_ != NULL) stbuf_->::xtreemfs::pbrpc::Stat::Clear(); + } + to_set_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool setattrRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_stbuf; + break; + } + + // required .xtreemfs.pbrpc.Stat stbuf = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_stbuf: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_stbuf())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(37)) goto parse_to_set; + break; + } + + // required fixed32 to_set = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_to_set: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &to_set_))); + set_has_to_set(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void setattrRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // required .xtreemfs.pbrpc.Stat stbuf = 3; + if (has_stbuf()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->stbuf(), output); + } + + // required fixed32 to_set = 4; + if (has_to_set()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(4, this->to_set(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* setattrRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // required .xtreemfs.pbrpc.Stat stbuf = 3; + if (has_stbuf()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->stbuf(), target); + } + + // required fixed32 to_set = 4; + if (has_to_set()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(4, this->to_set(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int setattrRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // required .xtreemfs.pbrpc.Stat stbuf = 3; + if (has_stbuf()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->stbuf()); + } + + // required fixed32 to_set = 4; + if (has_to_set()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void setattrRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const setattrRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void setattrRequest::MergeFrom(const setattrRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_stbuf()) { + mutable_stbuf()->::xtreemfs::pbrpc::Stat::MergeFrom(from.stbuf()); + } + if (from.has_to_set()) { + set_to_set(from.to_set()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void setattrRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void setattrRequest::CopyFrom(const setattrRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool setattrRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + if (has_stbuf()) { + if (!this->stbuf().IsInitialized()) return false; + } + return true; +} + +void setattrRequest::Swap(setattrRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(stbuf_, other->stbuf_); + std::swap(to_set_, other->to_set_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata setattrRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = setattrRequest_descriptor_; + metadata.reflection = setattrRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int setxattrRequest::kVolumeNameFieldNumber; +const int setxattrRequest::kPathFieldNumber; +const int setxattrRequest::kNameFieldNumber; +const int setxattrRequest::kValueFieldNumber; +const int setxattrRequest::kValueBytesStringFieldNumber; +const int setxattrRequest::kFlagsFieldNumber; +#endif // !_MSC_VER + +setxattrRequest::setxattrRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void setxattrRequest::InitAsDefaultInstance() { +} + +setxattrRequest::setxattrRequest(const setxattrRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void setxattrRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + value_bytes_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + flags_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +setxattrRequest::~setxattrRequest() { + SharedDtor(); +} + +void setxattrRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (value_ != &::google::protobuf::internal::kEmptyString) { + delete value_; + } + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + delete value_bytes_string_; + } + if (this != default_instance_) { + } +} + +void setxattrRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* setxattrRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return setxattrRequest_descriptor_; +} + +const setxattrRequest& setxattrRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +setxattrRequest* setxattrRequest::default_instance_ = NULL; + +setxattrRequest* setxattrRequest::New() const { + return new setxattrRequest; +} + +void setxattrRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_value()) { + if (value_ != &::google::protobuf::internal::kEmptyString) { + value_->clear(); + } + } + if (has_value_bytes_string()) { + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + value_bytes_string_->clear(); + } + } + flags_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool setxattrRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_name; + break; + } + + // required string name = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_value; + break; + } + + // required string value = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(45)) goto parse_flags; + break; + } + + // required fixed32 flags = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_flags: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &flags_))); + set_has_flags(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(50)) goto parse_value_bytes_string; + break; + } + + // optional bytes value_bytes_string = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_value_bytes_string: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_value_bytes_string())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void setxattrRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // required string name = 3; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->name(), output); + } + + // required string value = 4; + if (has_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->value(), output); + } + + // required fixed32 flags = 5; + if (has_flags()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(5, this->flags(), output); + } + + // optional bytes value_bytes_string = 6; + if (has_value_bytes_string()) { + ::google::protobuf::internal::WireFormatLite::WriteBytes( + 6, this->value_bytes_string(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* setxattrRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // required string name = 3; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->name(), target); + } + + // required string value = 4; + if (has_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->value(), target); + } + + // required fixed32 flags = 5; + if (has_flags()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(5, this->flags(), target); + } + + // optional bytes value_bytes_string = 6; + if (has_value_bytes_string()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 6, this->value_bytes_string(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int setxattrRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // required string name = 3; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // required string value = 4; + if (has_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->value()); + } + + // optional bytes value_bytes_string = 6; + if (has_value_bytes_string()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->value_bytes_string()); + } + + // required fixed32 flags = 5; + if (has_flags()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void setxattrRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const setxattrRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void setxattrRequest::MergeFrom(const setxattrRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_value()) { + set_value(from.value()); + } + if (from.has_value_bytes_string()) { + set_value_bytes_string(from.value_bytes_string()); + } + if (from.has_flags()) { + set_flags(from.flags()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void setxattrRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void setxattrRequest::CopyFrom(const setxattrRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool setxattrRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000002f) != 0x0000002f) return false; + + return true; +} + +void setxattrRequest::Swap(setxattrRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(name_, other->name_); + std::swap(value_, other->value_); + std::swap(value_bytes_string_, other->value_bytes_string_); + std::swap(flags_, other->flags_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata setxattrRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = setxattrRequest_descriptor_; + metadata.reflection = setxattrRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int statvfsRequest::kVolumeNameFieldNumber; +const int statvfsRequest::kKnownEtagFieldNumber; +#endif // !_MSC_VER + +statvfsRequest::statvfsRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void statvfsRequest::InitAsDefaultInstance() { +} + +statvfsRequest::statvfsRequest(const statvfsRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void statvfsRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + known_etag_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +statvfsRequest::~statvfsRequest() { + SharedDtor(); +} + +void statvfsRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (this != default_instance_) { + } +} + +void statvfsRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* statvfsRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return statvfsRequest_descriptor_; +} + +const statvfsRequest& statvfsRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +statvfsRequest* statvfsRequest::default_instance_ = NULL; + +statvfsRequest* statvfsRequest::New() const { + return new statvfsRequest; +} + +void statvfsRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + known_etag_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool statvfsRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(41)) goto parse_known_etag; + break; + } + + // required fixed64 known_etag = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_known_etag: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &known_etag_))); + set_has_known_etag(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void statvfsRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required fixed64 known_etag = 5; + if (has_known_etag()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(5, this->known_etag(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* statvfsRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required fixed64 known_etag = 5; + if (has_known_etag()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(5, this->known_etag(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int statvfsRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required fixed64 known_etag = 5; + if (has_known_etag()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void statvfsRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const statvfsRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void statvfsRequest::MergeFrom(const statvfsRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_known_etag()) { + set_known_etag(from.known_etag()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void statvfsRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void statvfsRequest::CopyFrom(const statvfsRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool statvfsRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void statvfsRequest::Swap(statvfsRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(known_etag_, other->known_etag_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata statvfsRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = statvfsRequest_descriptor_; + metadata.reflection = statvfsRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int symlinkRequest::kVolumeNameFieldNumber; +const int symlinkRequest::kTargetPathFieldNumber; +const int symlinkRequest::kLinkPathFieldNumber; +#endif // !_MSC_VER + +symlinkRequest::symlinkRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void symlinkRequest::InitAsDefaultInstance() { +} + +symlinkRequest::symlinkRequest(const symlinkRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void symlinkRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + target_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + link_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +symlinkRequest::~symlinkRequest() { + SharedDtor(); +} + +void symlinkRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + delete target_path_; + } + if (link_path_ != &::google::protobuf::internal::kEmptyString) { + delete link_path_; + } + if (this != default_instance_) { + } +} + +void symlinkRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* symlinkRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return symlinkRequest_descriptor_; +} + +const symlinkRequest& symlinkRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +symlinkRequest* symlinkRequest::default_instance_ = NULL; + +symlinkRequest* symlinkRequest::New() const { + return new symlinkRequest; +} + +void symlinkRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_target_path()) { + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + target_path_->clear(); + } + } + if (has_link_path()) { + if (link_path_ != &::google::protobuf::internal::kEmptyString) { + link_path_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool symlinkRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_target_path; + break; + } + + // required string target_path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_target_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_target_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->target_path().data(), this->target_path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_link_path; + break; + } + + // required string link_path = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_link_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_link_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->link_path().data(), this->link_path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void symlinkRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string target_path = 2; + if (has_target_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->target_path().data(), this->target_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->target_path(), output); + } + + // required string link_path = 3; + if (has_link_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->link_path().data(), this->link_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->link_path(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* symlinkRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string target_path = 2; + if (has_target_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->target_path().data(), this->target_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->target_path(), target); + } + + // required string link_path = 3; + if (has_link_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->link_path().data(), this->link_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->link_path(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int symlinkRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string target_path = 2; + if (has_target_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->target_path()); + } + + // required string link_path = 3; + if (has_link_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->link_path()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void symlinkRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const symlinkRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void symlinkRequest::MergeFrom(const symlinkRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_target_path()) { + set_target_path(from.target_path()); + } + if (from.has_link_path()) { + set_link_path(from.link_path()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void symlinkRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void symlinkRequest::CopyFrom(const symlinkRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool symlinkRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void symlinkRequest::Swap(symlinkRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(target_path_, other->target_path_); + std::swap(link_path_, other->link_path_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata symlinkRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = symlinkRequest_descriptor_; + metadata.reflection = symlinkRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int unlinkRequest::kVolumeNameFieldNumber; +const int unlinkRequest::kPathFieldNumber; +#endif // !_MSC_VER + +unlinkRequest::unlinkRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void unlinkRequest::InitAsDefaultInstance() { +} + +unlinkRequest::unlinkRequest(const unlinkRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void unlinkRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +unlinkRequest::~unlinkRequest() { + SharedDtor(); +} + +void unlinkRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + } +} + +void unlinkRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* unlinkRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return unlinkRequest_descriptor_; +} + +const unlinkRequest& unlinkRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +unlinkRequest* unlinkRequest::default_instance_ = NULL; + +unlinkRequest* unlinkRequest::New() const { + return new unlinkRequest; +} + +void unlinkRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool unlinkRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void unlinkRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* unlinkRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int unlinkRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void unlinkRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const unlinkRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void unlinkRequest::MergeFrom(const unlinkRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void unlinkRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void unlinkRequest::CopyFrom(const unlinkRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool unlinkRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void unlinkRequest::Swap(unlinkRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata unlinkRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = unlinkRequest_descriptor_; + metadata.reflection = unlinkRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int unlinkResponse::kTimestampSFieldNumber; +const int unlinkResponse::kCredsFieldNumber; +#endif // !_MSC_VER + +unlinkResponse::unlinkResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void unlinkResponse::InitAsDefaultInstance() { + creds_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +unlinkResponse::unlinkResponse(const unlinkResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void unlinkResponse::SharedCtor() { + _cached_size_ = 0; + timestamp_s_ = 0u; + creds_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +unlinkResponse::~unlinkResponse() { + SharedDtor(); +} + +void unlinkResponse::SharedDtor() { + if (this != default_instance_) { + delete creds_; + } +} + +void unlinkResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* unlinkResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return unlinkResponse_descriptor_; +} + +const unlinkResponse& unlinkResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +unlinkResponse* unlinkResponse::default_instance_ = NULL; + +unlinkResponse* unlinkResponse::New() const { + return new unlinkResponse; +} + +void unlinkResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + timestamp_s_ = 0u; + if (has_creds()) { + if (creds_ != NULL) creds_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool unlinkResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed32 timestamp_s = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, ×tamp_s_))); + set_has_timestamp_s(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_creds; + break; + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_creds: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_creds())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void unlinkResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed32 timestamp_s = 1; + if (has_timestamp_s()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(1, this->timestamp_s(), output); + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + if (has_creds()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->creds(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* unlinkResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed32 timestamp_s = 1; + if (has_timestamp_s()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(1, this->timestamp_s(), target); + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + if (has_creds()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->creds(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int unlinkResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed32 timestamp_s = 1; + if (has_timestamp_s()) { + total_size += 1 + 4; + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + if (has_creds()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->creds()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void unlinkResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const unlinkResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void unlinkResponse::MergeFrom(const unlinkResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_timestamp_s()) { + set_timestamp_s(from.timestamp_s()); + } + if (from.has_creds()) { + mutable_creds()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.creds()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void unlinkResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void unlinkResponse::CopyFrom(const unlinkResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool unlinkResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_creds()) { + if (!this->creds().IsInitialized()) return false; + } + return true; +} + +void unlinkResponse::Swap(unlinkResponse* other) { + if (other != this) { + std::swap(timestamp_s_, other->timestamp_s_); + std::swap(creds_, other->creds_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata unlinkResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = unlinkResponse_descriptor_; + metadata.reflection = unlinkResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int accessRequest::kVolumeNameFieldNumber; +const int accessRequest::kPathFieldNumber; +const int accessRequest::kFlagsFieldNumber; +#endif // !_MSC_VER + +accessRequest::accessRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void accessRequest::InitAsDefaultInstance() { +} + +accessRequest::accessRequest(const accessRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void accessRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + flags_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +accessRequest::~accessRequest() { + SharedDtor(); +} + +void accessRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + } +} + +void accessRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* accessRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return accessRequest_descriptor_; +} + +const accessRequest& accessRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +accessRequest* accessRequest::default_instance_ = NULL; + +accessRequest* accessRequest::New() const { + return new accessRequest; +} + +void accessRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + flags_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool accessRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(29)) goto parse_flags; + break; + } + + // required fixed32 flags = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_flags: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &flags_))); + set_has_flags(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void accessRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // required fixed32 flags = 3; + if (has_flags()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(3, this->flags(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* accessRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // required fixed32 flags = 3; + if (has_flags()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(3, this->flags(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int accessRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // required fixed32 flags = 3; + if (has_flags()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void accessRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const accessRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void accessRequest::MergeFrom(const accessRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_flags()) { + set_flags(from.flags()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void accessRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void accessRequest::CopyFrom(const accessRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool accessRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void accessRequest::Swap(accessRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(path_, other->path_); + std::swap(flags_, other->flags_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata accessRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = accessRequest_descriptor_; + metadata.reflection = accessRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_check_file_existsRequest::kVolumeIdFieldNumber; +const int xtreemfs_check_file_existsRequest::kFileIdsFieldNumber; +const int xtreemfs_check_file_existsRequest::kOsdUuidFieldNumber; +#endif // !_MSC_VER + +xtreemfs_check_file_existsRequest::xtreemfs_check_file_existsRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_check_file_existsRequest::InitAsDefaultInstance() { +} + +xtreemfs_check_file_existsRequest::xtreemfs_check_file_existsRequest(const xtreemfs_check_file_existsRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_check_file_existsRequest::SharedCtor() { + _cached_size_ = 0; + volume_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + osd_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_check_file_existsRequest::~xtreemfs_check_file_existsRequest() { + SharedDtor(); +} + +void xtreemfs_check_file_existsRequest::SharedDtor() { + if (volume_id_ != &::google::protobuf::internal::kEmptyString) { + delete volume_id_; + } + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + delete osd_uuid_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_check_file_existsRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_check_file_existsRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_check_file_existsRequest_descriptor_; +} + +const xtreemfs_check_file_existsRequest& xtreemfs_check_file_existsRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_check_file_existsRequest* xtreemfs_check_file_existsRequest::default_instance_ = NULL; + +xtreemfs_check_file_existsRequest* xtreemfs_check_file_existsRequest::New() const { + return new xtreemfs_check_file_existsRequest; +} + +void xtreemfs_check_file_existsRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_id()) { + if (volume_id_ != &::google::protobuf::internal::kEmptyString) { + volume_id_->clear(); + } + } + if (has_osd_uuid()) { + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + osd_uuid_->clear(); + } + } + } + file_ids_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_check_file_existsRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_id().data(), this->volume_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_ids; + break; + } + + // repeated string file_ids = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_ids: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_file_ids())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_ids(this->file_ids_size() - 1).data(), + this->file_ids(this->file_ids_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_ids; + if (input->ExpectTag(26)) goto parse_osd_uuid; + break; + } + + // required string osd_uuid = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_osd_uuid: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_osd_uuid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuid().data(), this->osd_uuid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_check_file_existsRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_id = 1; + if (has_volume_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_id().data(), this->volume_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_id(), output); + } + + // repeated string file_ids = 2; + for (int i = 0; i < this->file_ids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_ids(i).data(), this->file_ids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_ids(i), output); + } + + // required string osd_uuid = 3; + if (has_osd_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuid().data(), this->osd_uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->osd_uuid(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_check_file_existsRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_id = 1; + if (has_volume_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_id().data(), this->volume_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_id(), target); + } + + // repeated string file_ids = 2; + for (int i = 0; i < this->file_ids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_ids(i).data(), this->file_ids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(2, this->file_ids(i), target); + } + + // required string osd_uuid = 3; + if (has_osd_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuid().data(), this->osd_uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->osd_uuid(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_check_file_existsRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_id = 1; + if (has_volume_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_id()); + } + + // required string osd_uuid = 3; + if (has_osd_uuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->osd_uuid()); + } + + } + // repeated string file_ids = 2; + total_size += 1 * this->file_ids_size(); + for (int i = 0; i < this->file_ids_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_ids(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_check_file_existsRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_check_file_existsRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_check_file_existsRequest::MergeFrom(const xtreemfs_check_file_existsRequest& from) { + GOOGLE_CHECK_NE(&from, this); + file_ids_.MergeFrom(from.file_ids_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_id()) { + set_volume_id(from.volume_id()); + } + if (from.has_osd_uuid()) { + set_osd_uuid(from.osd_uuid()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_check_file_existsRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_check_file_existsRequest::CopyFrom(const xtreemfs_check_file_existsRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_check_file_existsRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000005) != 0x00000005) return false; + + return true; +} + +void xtreemfs_check_file_existsRequest::Swap(xtreemfs_check_file_existsRequest* other) { + if (other != this) { + std::swap(volume_id_, other->volume_id_); + file_ids_.Swap(&other->file_ids_); + std::swap(osd_uuid_, other->osd_uuid_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_check_file_existsRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_check_file_existsRequest_descriptor_; + metadata.reflection = xtreemfs_check_file_existsRequest_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* xtreemfs_check_file_existsResponse_FILE_STATE_descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_check_file_existsResponse_FILE_STATE_descriptor_; +} +bool xtreemfs_check_file_existsResponse_FILE_STATE_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const xtreemfs_check_file_existsResponse_FILE_STATE xtreemfs_check_file_existsResponse::DELETED; +const xtreemfs_check_file_existsResponse_FILE_STATE xtreemfs_check_file_existsResponse::REGISTERED; +const xtreemfs_check_file_existsResponse_FILE_STATE xtreemfs_check_file_existsResponse::ABANDONED; +const xtreemfs_check_file_existsResponse_FILE_STATE xtreemfs_check_file_existsResponse::FILE_STATE_MIN; +const xtreemfs_check_file_existsResponse_FILE_STATE xtreemfs_check_file_existsResponse::FILE_STATE_MAX; +const int xtreemfs_check_file_existsResponse::FILE_STATE_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int xtreemfs_check_file_existsResponse::kVolumeExistsFieldNumber; +const int xtreemfs_check_file_existsResponse::kFileStatesFieldNumber; +#endif // !_MSC_VER + +xtreemfs_check_file_existsResponse::xtreemfs_check_file_existsResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_check_file_existsResponse::InitAsDefaultInstance() { +} + +xtreemfs_check_file_existsResponse::xtreemfs_check_file_existsResponse(const xtreemfs_check_file_existsResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_check_file_existsResponse::SharedCtor() { + _cached_size_ = 0; + volume_exists_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_check_file_existsResponse::~xtreemfs_check_file_existsResponse() { + SharedDtor(); +} + +void xtreemfs_check_file_existsResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void xtreemfs_check_file_existsResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_check_file_existsResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_check_file_existsResponse_descriptor_; +} + +const xtreemfs_check_file_existsResponse& xtreemfs_check_file_existsResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_check_file_existsResponse* xtreemfs_check_file_existsResponse::default_instance_ = NULL; + +xtreemfs_check_file_existsResponse* xtreemfs_check_file_existsResponse::New() const { + return new xtreemfs_check_file_existsResponse; +} + +void xtreemfs_check_file_existsResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + volume_exists_ = false; + } + file_states_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_check_file_existsResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required bool volume_exists = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &volume_exists_))); + set_has_volume_exists(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_states; + break; + } + + // repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_states: + ::google::protobuf::uint32 length; + DO_(input->ReadVarint32(&length)); + ::google::protobuf::io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE_IsValid(value)) { + add_file_states(static_cast< ::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE >(value)); + } + } + input->PopLimit(limit); + } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) + == ::google::protobuf::internal::WireFormatLite:: + WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE_IsValid(value)) { + add_file_states(static_cast< ::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE >(value)); + } else { + mutable_unknown_fields()->AddVarint(2, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_check_file_existsResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required bool volume_exists = 1; + if (has_volume_exists()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->volume_exists(), output); + } + + // repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + if (this->file_states_size() > 0) { + ::google::protobuf::internal::WireFormatLite::WriteTag( + 2, + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + output); + output->WriteVarint32(_file_states_cached_byte_size_); + } + for (int i = 0; i < this->file_states_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteEnumNoTag( + this->file_states(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_check_file_existsResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required bool volume_exists = 1; + if (has_volume_exists()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->volume_exists(), target); + } + + // repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + if (this->file_states_size() > 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray( + 2, + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + target); + target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( _file_states_cached_byte_size_, target); + } + for (int i = 0; i < this->file_states_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray( + this->file_states(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_check_file_existsResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required bool volume_exists = 1; + if (has_volume_exists()) { + total_size += 1 + 1; + } + + } + // repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + { + int data_size = 0; + for (int i = 0; i < this->file_states_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite::EnumSize( + this->file_states(i)); + } + if (data_size > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size(data_size); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _file_states_cached_byte_size_ = data_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + total_size += data_size; + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_check_file_existsResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_check_file_existsResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_check_file_existsResponse::MergeFrom(const xtreemfs_check_file_existsResponse& from) { + GOOGLE_CHECK_NE(&from, this); + file_states_.MergeFrom(from.file_states_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_exists()) { + set_volume_exists(from.volume_exists()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_check_file_existsResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_check_file_existsResponse::CopyFrom(const xtreemfs_check_file_existsResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_check_file_existsResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void xtreemfs_check_file_existsResponse::Swap(xtreemfs_check_file_existsResponse* other) { + if (other != this) { + std::swap(volume_exists_, other->volume_exists_); + file_states_.Swap(&other->file_states_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_check_file_existsResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_check_file_existsResponse_descriptor_; + metadata.reflection = xtreemfs_check_file_existsResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_dump_restore_databaseRequest::kDumpFileFieldNumber; +#endif // !_MSC_VER + +xtreemfs_dump_restore_databaseRequest::xtreemfs_dump_restore_databaseRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_dump_restore_databaseRequest::InitAsDefaultInstance() { +} + +xtreemfs_dump_restore_databaseRequest::xtreemfs_dump_restore_databaseRequest(const xtreemfs_dump_restore_databaseRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_dump_restore_databaseRequest::SharedCtor() { + _cached_size_ = 0; + dump_file_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_dump_restore_databaseRequest::~xtreemfs_dump_restore_databaseRequest() { + SharedDtor(); +} + +void xtreemfs_dump_restore_databaseRequest::SharedDtor() { + if (dump_file_ != &::google::protobuf::internal::kEmptyString) { + delete dump_file_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_dump_restore_databaseRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_dump_restore_databaseRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_dump_restore_databaseRequest_descriptor_; +} + +const xtreemfs_dump_restore_databaseRequest& xtreemfs_dump_restore_databaseRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_dump_restore_databaseRequest* xtreemfs_dump_restore_databaseRequest::default_instance_ = NULL; + +xtreemfs_dump_restore_databaseRequest* xtreemfs_dump_restore_databaseRequest::New() const { + return new xtreemfs_dump_restore_databaseRequest; +} + +void xtreemfs_dump_restore_databaseRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_dump_file()) { + if (dump_file_ != &::google::protobuf::internal::kEmptyString) { + dump_file_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_dump_restore_databaseRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string dump_file = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_dump_file())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dump_file().data(), this->dump_file().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_dump_restore_databaseRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string dump_file = 1; + if (has_dump_file()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dump_file().data(), this->dump_file().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->dump_file(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_dump_restore_databaseRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string dump_file = 1; + if (has_dump_file()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dump_file().data(), this->dump_file().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->dump_file(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_dump_restore_databaseRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string dump_file = 1; + if (has_dump_file()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->dump_file()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_dump_restore_databaseRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_dump_restore_databaseRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_dump_restore_databaseRequest::MergeFrom(const xtreemfs_dump_restore_databaseRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_dump_file()) { + set_dump_file(from.dump_file()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_dump_restore_databaseRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_dump_restore_databaseRequest::CopyFrom(const xtreemfs_dump_restore_databaseRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_dump_restore_databaseRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void xtreemfs_dump_restore_databaseRequest::Swap(xtreemfs_dump_restore_databaseRequest* other) { + if (other != this) { + std::swap(dump_file_, other->dump_file_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_dump_restore_databaseRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_dump_restore_databaseRequest_descriptor_; + metadata.reflection = xtreemfs_dump_restore_databaseRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_get_suitable_osdsRequest::kFileIdFieldNumber; +const int xtreemfs_get_suitable_osdsRequest::kPathFieldNumber; +const int xtreemfs_get_suitable_osdsRequest::kVolumeNameFieldNumber; +const int xtreemfs_get_suitable_osdsRequest::kNumOsdsFieldNumber; +#endif // !_MSC_VER + +xtreemfs_get_suitable_osdsRequest::xtreemfs_get_suitable_osdsRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_get_suitable_osdsRequest::InitAsDefaultInstance() { +} + +xtreemfs_get_suitable_osdsRequest::xtreemfs_get_suitable_osdsRequest(const xtreemfs_get_suitable_osdsRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_get_suitable_osdsRequest::SharedCtor() { + _cached_size_ = 0; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + num_osds_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_get_suitable_osdsRequest::~xtreemfs_get_suitable_osdsRequest() { + SharedDtor(); +} + +void xtreemfs_get_suitable_osdsRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_get_suitable_osdsRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_get_suitable_osdsRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_get_suitable_osdsRequest_descriptor_; +} + +const xtreemfs_get_suitable_osdsRequest& xtreemfs_get_suitable_osdsRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_get_suitable_osdsRequest* xtreemfs_get_suitable_osdsRequest::default_instance_ = NULL; + +xtreemfs_get_suitable_osdsRequest* xtreemfs_get_suitable_osdsRequest::New() const { + return new xtreemfs_get_suitable_osdsRequest; +} + +void xtreemfs_get_suitable_osdsRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + num_osds_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_get_suitable_osdsRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string file_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(21)) goto parse_num_osds; + break; + } + + // required fixed32 num_osds = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_num_osds: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &num_osds_))); + set_has_num_osds(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_path; + break; + } + + // optional string path = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_volume_name; + break; + } + + // optional string volume_name = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_volume_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_get_suitable_osdsRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_id(), output); + } + + // required fixed32 num_osds = 2; + if (has_num_osds()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(2, this->num_osds(), output); + } + + // optional string path = 3; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->path(), output); + } + + // optional string volume_name = 4; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->volume_name(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_get_suitable_osdsRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->file_id(), target); + } + + // required fixed32 num_osds = 2; + if (has_num_osds()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(2, this->num_osds(), target); + } + + // optional string path = 3; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->path(), target); + } + + // optional string volume_name = 4; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->volume_name(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_get_suitable_osdsRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string file_id = 1; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // optional string path = 3; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // optional string volume_name = 4; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required fixed32 num_osds = 2; + if (has_num_osds()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_get_suitable_osdsRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_get_suitable_osdsRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_get_suitable_osdsRequest::MergeFrom(const xtreemfs_get_suitable_osdsRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_num_osds()) { + set_num_osds(from.num_osds()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_get_suitable_osdsRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_get_suitable_osdsRequest::CopyFrom(const xtreemfs_get_suitable_osdsRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_get_suitable_osdsRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000008) != 0x00000008) return false; + + return true; +} + +void xtreemfs_get_suitable_osdsRequest::Swap(xtreemfs_get_suitable_osdsRequest* other) { + if (other != this) { + std::swap(file_id_, other->file_id_); + std::swap(path_, other->path_); + std::swap(volume_name_, other->volume_name_); + std::swap(num_osds_, other->num_osds_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_get_suitable_osdsRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_get_suitable_osdsRequest_descriptor_; + metadata.reflection = xtreemfs_get_suitable_osdsRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_get_suitable_osdsResponse::kOsdUuidsFieldNumber; +#endif // !_MSC_VER + +xtreemfs_get_suitable_osdsResponse::xtreemfs_get_suitable_osdsResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_get_suitable_osdsResponse::InitAsDefaultInstance() { +} + +xtreemfs_get_suitable_osdsResponse::xtreemfs_get_suitable_osdsResponse(const xtreemfs_get_suitable_osdsResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_get_suitable_osdsResponse::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_get_suitable_osdsResponse::~xtreemfs_get_suitable_osdsResponse() { + SharedDtor(); +} + +void xtreemfs_get_suitable_osdsResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void xtreemfs_get_suitable_osdsResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_get_suitable_osdsResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_get_suitable_osdsResponse_descriptor_; +} + +const xtreemfs_get_suitable_osdsResponse& xtreemfs_get_suitable_osdsResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_get_suitable_osdsResponse* xtreemfs_get_suitable_osdsResponse::default_instance_ = NULL; + +xtreemfs_get_suitable_osdsResponse* xtreemfs_get_suitable_osdsResponse::New() const { + return new xtreemfs_get_suitable_osdsResponse; +} + +void xtreemfs_get_suitable_osdsResponse::Clear() { + osd_uuids_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_get_suitable_osdsResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string osd_uuids = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_osd_uuids: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_osd_uuids())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuids(this->osd_uuids_size() - 1).data(), + this->osd_uuids(this->osd_uuids_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_osd_uuids; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_get_suitable_osdsResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated string osd_uuids = 1; + for (int i = 0; i < this->osd_uuids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuids(i).data(), this->osd_uuids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->osd_uuids(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_get_suitable_osdsResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated string osd_uuids = 1; + for (int i = 0; i < this->osd_uuids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuids(i).data(), this->osd_uuids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->osd_uuids(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_get_suitable_osdsResponse::ByteSize() const { + int total_size = 0; + + // repeated string osd_uuids = 1; + total_size += 1 * this->osd_uuids_size(); + for (int i = 0; i < this->osd_uuids_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->osd_uuids(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_get_suitable_osdsResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_get_suitable_osdsResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_get_suitable_osdsResponse::MergeFrom(const xtreemfs_get_suitable_osdsResponse& from) { + GOOGLE_CHECK_NE(&from, this); + osd_uuids_.MergeFrom(from.osd_uuids_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_get_suitable_osdsResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_get_suitable_osdsResponse::CopyFrom(const xtreemfs_get_suitable_osdsResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_get_suitable_osdsResponse::IsInitialized() const { + + return true; +} + +void xtreemfs_get_suitable_osdsResponse::Swap(xtreemfs_get_suitable_osdsResponse* other) { + if (other != this) { + osd_uuids_.Swap(&other->osd_uuids_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_get_suitable_osdsResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_get_suitable_osdsResponse_descriptor_; + metadata.reflection = xtreemfs_get_suitable_osdsResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int timestampResponse::kTimestampSFieldNumber; +#endif // !_MSC_VER + +timestampResponse::timestampResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void timestampResponse::InitAsDefaultInstance() { +} + +timestampResponse::timestampResponse(const timestampResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void timestampResponse::SharedCtor() { + _cached_size_ = 0; + timestamp_s_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +timestampResponse::~timestampResponse() { + SharedDtor(); +} + +void timestampResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void timestampResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* timestampResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return timestampResponse_descriptor_; +} + +const timestampResponse& timestampResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +timestampResponse* timestampResponse::default_instance_ = NULL; + +timestampResponse* timestampResponse::New() const { + return new timestampResponse; +} + +void timestampResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + timestamp_s_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool timestampResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed32 timestamp_s = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, ×tamp_s_))); + set_has_timestamp_s(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void timestampResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed32 timestamp_s = 1; + if (has_timestamp_s()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(1, this->timestamp_s(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* timestampResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed32 timestamp_s = 1; + if (has_timestamp_s()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(1, this->timestamp_s(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int timestampResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed32 timestamp_s = 1; + if (has_timestamp_s()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void timestampResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const timestampResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void timestampResponse::MergeFrom(const timestampResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_timestamp_s()) { + set_timestamp_s(from.timestamp_s()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void timestampResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void timestampResponse::CopyFrom(const timestampResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool timestampResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void timestampResponse::Swap(timestampResponse* other) { + if (other != this) { + std::swap(timestamp_s_, other->timestamp_s_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata timestampResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = timestampResponse_descriptor_; + metadata.reflection = timestampResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int stringMessage::kAStringFieldNumber; +#endif // !_MSC_VER + +stringMessage::stringMessage() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void stringMessage::InitAsDefaultInstance() { +} + +stringMessage::stringMessage(const stringMessage& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void stringMessage::SharedCtor() { + _cached_size_ = 0; + a_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +stringMessage::~stringMessage() { + SharedDtor(); +} + +void stringMessage::SharedDtor() { + if (a_string_ != &::google::protobuf::internal::kEmptyString) { + delete a_string_; + } + if (this != default_instance_) { + } +} + +void stringMessage::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* stringMessage::descriptor() { + protobuf_AssignDescriptorsOnce(); + return stringMessage_descriptor_; +} + +const stringMessage& stringMessage::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +stringMessage* stringMessage::default_instance_ = NULL; + +stringMessage* stringMessage::New() const { + return new stringMessage; +} + +void stringMessage::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_a_string()) { + if (a_string_ != &::google::protobuf::internal::kEmptyString) { + a_string_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool stringMessage::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string a_string = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_a_string())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->a_string().data(), this->a_string().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void stringMessage::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string a_string = 1; + if (has_a_string()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->a_string().data(), this->a_string().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->a_string(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* stringMessage::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string a_string = 1; + if (has_a_string()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->a_string().data(), this->a_string().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->a_string(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int stringMessage::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string a_string = 1; + if (has_a_string()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->a_string()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void stringMessage::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const stringMessage* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void stringMessage::MergeFrom(const stringMessage& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_a_string()) { + set_a_string(from.a_string()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void stringMessage::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void stringMessage::CopyFrom(const stringMessage& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool stringMessage::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void stringMessage::Swap(stringMessage* other) { + if (other != this) { + std::swap(a_string_, other->a_string_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata stringMessage::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = stringMessage_descriptor_; + metadata.reflection = stringMessage_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_listdirRequest::kPathFieldNumber; +#endif // !_MSC_VER + +xtreemfs_listdirRequest::xtreemfs_listdirRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_listdirRequest::InitAsDefaultInstance() { +} + +xtreemfs_listdirRequest::xtreemfs_listdirRequest(const xtreemfs_listdirRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_listdirRequest::SharedCtor() { + _cached_size_ = 0; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_listdirRequest::~xtreemfs_listdirRequest() { + SharedDtor(); +} + +void xtreemfs_listdirRequest::SharedDtor() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_listdirRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_listdirRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_listdirRequest_descriptor_; +} + +const xtreemfs_listdirRequest& xtreemfs_listdirRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_listdirRequest* xtreemfs_listdirRequest::default_instance_ = NULL; + +xtreemfs_listdirRequest* xtreemfs_listdirRequest::New() const { + return new xtreemfs_listdirRequest; +} + +void xtreemfs_listdirRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_listdirRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string path = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_listdirRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string path = 1; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->path(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_listdirRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string path = 1; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->path(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_listdirRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string path = 1; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_listdirRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_listdirRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_listdirRequest::MergeFrom(const xtreemfs_listdirRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_path()) { + set_path(from.path()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_listdirRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_listdirRequest::CopyFrom(const xtreemfs_listdirRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_listdirRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void xtreemfs_listdirRequest::Swap(xtreemfs_listdirRequest* other) { + if (other != this) { + std::swap(path_, other->path_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_listdirRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_listdirRequest_descriptor_; + metadata.reflection = xtreemfs_listdirRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_listdirResponse::kNamesFieldNumber; +#endif // !_MSC_VER + +xtreemfs_listdirResponse::xtreemfs_listdirResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_listdirResponse::InitAsDefaultInstance() { +} + +xtreemfs_listdirResponse::xtreemfs_listdirResponse(const xtreemfs_listdirResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_listdirResponse::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_listdirResponse::~xtreemfs_listdirResponse() { + SharedDtor(); +} + +void xtreemfs_listdirResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void xtreemfs_listdirResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_listdirResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_listdirResponse_descriptor_; +} + +const xtreemfs_listdirResponse& xtreemfs_listdirResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_listdirResponse* xtreemfs_listdirResponse::default_instance_ = NULL; + +xtreemfs_listdirResponse* xtreemfs_listdirResponse::New() const { + return new xtreemfs_listdirResponse; +} + +void xtreemfs_listdirResponse::Clear() { + names_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_listdirResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string names = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_names: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_names())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->names(this->names_size() - 1).data(), + this->names(this->names_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_names; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_listdirResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated string names = 1; + for (int i = 0; i < this->names_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->names(i).data(), this->names(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->names(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_listdirResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated string names = 1; + for (int i = 0; i < this->names_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->names(i).data(), this->names(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->names(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_listdirResponse::ByteSize() const { + int total_size = 0; + + // repeated string names = 1; + total_size += 1 * this->names_size(); + for (int i = 0; i < this->names_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->names(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_listdirResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_listdirResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_listdirResponse::MergeFrom(const xtreemfs_listdirResponse& from) { + GOOGLE_CHECK_NE(&from, this); + names_.MergeFrom(from.names_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_listdirResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_listdirResponse::CopyFrom(const xtreemfs_listdirResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_listdirResponse::IsInitialized() const { + + return true; +} + +void xtreemfs_listdirResponse::Swap(xtreemfs_listdirResponse* other) { + if (other != this) { + names_.Swap(&other->names_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_listdirResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_listdirResponse_descriptor_; + metadata.reflection = xtreemfs_listdirResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_replica_addRequest::kFileIdFieldNumber; +const int xtreemfs_replica_addRequest::kPathFieldNumber; +const int xtreemfs_replica_addRequest::kVolumeNameFieldNumber; +const int xtreemfs_replica_addRequest::kNewReplicaFieldNumber; +#endif // !_MSC_VER + +xtreemfs_replica_addRequest::xtreemfs_replica_addRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_replica_addRequest::InitAsDefaultInstance() { + new_replica_ = const_cast< ::xtreemfs::pbrpc::Replica*>(&::xtreemfs::pbrpc::Replica::default_instance()); +} + +xtreemfs_replica_addRequest::xtreemfs_replica_addRequest(const xtreemfs_replica_addRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_replica_addRequest::SharedCtor() { + _cached_size_ = 0; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + new_replica_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_replica_addRequest::~xtreemfs_replica_addRequest() { + SharedDtor(); +} + +void xtreemfs_replica_addRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (this != default_instance_) { + delete new_replica_; + } +} + +void xtreemfs_replica_addRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_replica_addRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_replica_addRequest_descriptor_; +} + +const xtreemfs_replica_addRequest& xtreemfs_replica_addRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_replica_addRequest* xtreemfs_replica_addRequest::default_instance_ = NULL; + +xtreemfs_replica_addRequest* xtreemfs_replica_addRequest::New() const { + return new xtreemfs_replica_addRequest; +} + +void xtreemfs_replica_addRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_new_replica()) { + if (new_replica_ != NULL) new_replica_->::xtreemfs::pbrpc::Replica::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_replica_addRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string file_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_new_replica; + break; + } + + // required .xtreemfs.pbrpc.Replica new_replica = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_new_replica: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_new_replica())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_path; + break; + } + + // optional string path = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_volume_name; + break; + } + + // optional string volume_name = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_volume_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_replica_addRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_id(), output); + } + + // required .xtreemfs.pbrpc.Replica new_replica = 2; + if (has_new_replica()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->new_replica(), output); + } + + // optional string path = 3; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->path(), output); + } + + // optional string volume_name = 4; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->volume_name(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_replica_addRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->file_id(), target); + } + + // required .xtreemfs.pbrpc.Replica new_replica = 2; + if (has_new_replica()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->new_replica(), target); + } + + // optional string path = 3; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->path(), target); + } + + // optional string volume_name = 4; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->volume_name(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_replica_addRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string file_id = 1; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // optional string path = 3; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // optional string volume_name = 4; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required .xtreemfs.pbrpc.Replica new_replica = 2; + if (has_new_replica()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->new_replica()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_replica_addRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_replica_addRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_replica_addRequest::MergeFrom(const xtreemfs_replica_addRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_new_replica()) { + mutable_new_replica()->::xtreemfs::pbrpc::Replica::MergeFrom(from.new_replica()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_replica_addRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_replica_addRequest::CopyFrom(const xtreemfs_replica_addRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_replica_addRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000008) != 0x00000008) return false; + + if (has_new_replica()) { + if (!this->new_replica().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_replica_addRequest::Swap(xtreemfs_replica_addRequest* other) { + if (other != this) { + std::swap(file_id_, other->file_id_); + std::swap(path_, other->path_); + std::swap(volume_name_, other->volume_name_); + std::swap(new_replica_, other->new_replica_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_replica_addRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_replica_addRequest_descriptor_; + metadata.reflection = xtreemfs_replica_addRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_replica_listRequest::kFileIdFieldNumber; +const int xtreemfs_replica_listRequest::kPathFieldNumber; +const int xtreemfs_replica_listRequest::kVolumeNameFieldNumber; +#endif // !_MSC_VER + +xtreemfs_replica_listRequest::xtreemfs_replica_listRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_replica_listRequest::InitAsDefaultInstance() { +} + +xtreemfs_replica_listRequest::xtreemfs_replica_listRequest(const xtreemfs_replica_listRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_replica_listRequest::SharedCtor() { + _cached_size_ = 0; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_replica_listRequest::~xtreemfs_replica_listRequest() { + SharedDtor(); +} + +void xtreemfs_replica_listRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_replica_listRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_replica_listRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_replica_listRequest_descriptor_; +} + +const xtreemfs_replica_listRequest& xtreemfs_replica_listRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_replica_listRequest* xtreemfs_replica_listRequest::default_instance_ = NULL; + +xtreemfs_replica_listRequest* xtreemfs_replica_listRequest::New() const { + return new xtreemfs_replica_listRequest; +} + +void xtreemfs_replica_listRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_replica_listRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string file_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // optional string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_volume_name; + break; + } + + // optional string volume_name = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_volume_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_replica_listRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_id(), output); + } + + // optional string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // optional string volume_name = 3; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->volume_name(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_replica_listRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->file_id(), target); + } + + // optional string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // optional string volume_name = 3; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->volume_name(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_replica_listRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string file_id = 1; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // optional string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // optional string volume_name = 3; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_replica_listRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_replica_listRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_replica_listRequest::MergeFrom(const xtreemfs_replica_listRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_replica_listRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_replica_listRequest::CopyFrom(const xtreemfs_replica_listRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_replica_listRequest::IsInitialized() const { + + return true; +} + +void xtreemfs_replica_listRequest::Swap(xtreemfs_replica_listRequest* other) { + if (other != this) { + std::swap(file_id_, other->file_id_); + std::swap(path_, other->path_); + std::swap(volume_name_, other->volume_name_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_replica_listRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_replica_listRequest_descriptor_; + metadata.reflection = xtreemfs_replica_listRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_get_xlocsetRequest::kFileIdFieldNumber; +const int xtreemfs_get_xlocsetRequest::kPathFieldNumber; +const int xtreemfs_get_xlocsetRequest::kVolumeNameFieldNumber; +const int xtreemfs_get_xlocsetRequest::kXcapFieldNumber; +#endif // !_MSC_VER + +xtreemfs_get_xlocsetRequest::xtreemfs_get_xlocsetRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_get_xlocsetRequest::InitAsDefaultInstance() { + xcap_ = const_cast< ::xtreemfs::pbrpc::XCap*>(&::xtreemfs::pbrpc::XCap::default_instance()); +} + +xtreemfs_get_xlocsetRequest::xtreemfs_get_xlocsetRequest(const xtreemfs_get_xlocsetRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_get_xlocsetRequest::SharedCtor() { + _cached_size_ = 0; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + xcap_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_get_xlocsetRequest::~xtreemfs_get_xlocsetRequest() { + SharedDtor(); +} + +void xtreemfs_get_xlocsetRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (this != default_instance_) { + delete xcap_; + } +} + +void xtreemfs_get_xlocsetRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_get_xlocsetRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_get_xlocsetRequest_descriptor_; +} + +const xtreemfs_get_xlocsetRequest& xtreemfs_get_xlocsetRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_get_xlocsetRequest* xtreemfs_get_xlocsetRequest::default_instance_ = NULL; + +xtreemfs_get_xlocsetRequest* xtreemfs_get_xlocsetRequest::New() const { + return new xtreemfs_get_xlocsetRequest; +} + +void xtreemfs_get_xlocsetRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_xcap()) { + if (xcap_ != NULL) xcap_->::xtreemfs::pbrpc::XCap::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_get_xlocsetRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string file_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // optional string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_volume_name; + break; + } + + // optional string volume_name = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_volume_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_xcap; + break; + } + + // optional .xtreemfs.pbrpc.XCap xcap = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_xcap: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_xcap())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_get_xlocsetRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_id(), output); + } + + // optional string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // optional string volume_name = 3; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->volume_name(), output); + } + + // optional .xtreemfs.pbrpc.XCap xcap = 4; + if (has_xcap()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, this->xcap(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_get_xlocsetRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->file_id(), target); + } + + // optional string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // optional string volume_name = 3; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->volume_name(), target); + } + + // optional .xtreemfs.pbrpc.XCap xcap = 4; + if (has_xcap()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->xcap(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_get_xlocsetRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string file_id = 1; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // optional string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // optional string volume_name = 3; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // optional .xtreemfs.pbrpc.XCap xcap = 4; + if (has_xcap()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->xcap()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_get_xlocsetRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_get_xlocsetRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_get_xlocsetRequest::MergeFrom(const xtreemfs_get_xlocsetRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_xcap()) { + mutable_xcap()->::xtreemfs::pbrpc::XCap::MergeFrom(from.xcap()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_get_xlocsetRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_get_xlocsetRequest::CopyFrom(const xtreemfs_get_xlocsetRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_get_xlocsetRequest::IsInitialized() const { + + if (has_xcap()) { + if (!this->xcap().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_get_xlocsetRequest::Swap(xtreemfs_get_xlocsetRequest* other) { + if (other != this) { + std::swap(file_id_, other->file_id_); + std::swap(path_, other->path_); + std::swap(volume_name_, other->volume_name_); + std::swap(xcap_, other->xcap_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_get_xlocsetRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_get_xlocsetRequest_descriptor_; + metadata.reflection = xtreemfs_get_xlocsetRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_replica_removeRequest::kFileIdFieldNumber; +const int xtreemfs_replica_removeRequest::kPathFieldNumber; +const int xtreemfs_replica_removeRequest::kVolumeNameFieldNumber; +const int xtreemfs_replica_removeRequest::kOsdUuidFieldNumber; +#endif // !_MSC_VER + +xtreemfs_replica_removeRequest::xtreemfs_replica_removeRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_replica_removeRequest::InitAsDefaultInstance() { +} + +xtreemfs_replica_removeRequest::xtreemfs_replica_removeRequest(const xtreemfs_replica_removeRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_replica_removeRequest::SharedCtor() { + _cached_size_ = 0; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + osd_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_replica_removeRequest::~xtreemfs_replica_removeRequest() { + SharedDtor(); +} + +void xtreemfs_replica_removeRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + delete osd_uuid_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_replica_removeRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_replica_removeRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_replica_removeRequest_descriptor_; +} + +const xtreemfs_replica_removeRequest& xtreemfs_replica_removeRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_replica_removeRequest* xtreemfs_replica_removeRequest::default_instance_ = NULL; + +xtreemfs_replica_removeRequest* xtreemfs_replica_removeRequest::New() const { + return new xtreemfs_replica_removeRequest; +} + +void xtreemfs_replica_removeRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + if (has_osd_uuid()) { + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + osd_uuid_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_replica_removeRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string file_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_osd_uuid; + break; + } + + // required string osd_uuid = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_osd_uuid: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_osd_uuid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuid().data(), this->osd_uuid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_path; + break; + } + + // optional string path = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_volume_name; + break; + } + + // optional string volume_name = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_volume_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_replica_removeRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_id(), output); + } + + // required string osd_uuid = 2; + if (has_osd_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuid().data(), this->osd_uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->osd_uuid(), output); + } + + // optional string path = 3; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->path(), output); + } + + // optional string volume_name = 4; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->volume_name(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_replica_removeRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->file_id(), target); + } + + // required string osd_uuid = 2; + if (has_osd_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuid().data(), this->osd_uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->osd_uuid(), target); + } + + // optional string path = 3; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->path(), target); + } + + // optional string volume_name = 4; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->volume_name(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_replica_removeRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string file_id = 1; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // optional string path = 3; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // optional string volume_name = 4; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + // required string osd_uuid = 2; + if (has_osd_uuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->osd_uuid()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_replica_removeRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_replica_removeRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_replica_removeRequest::MergeFrom(const xtreemfs_replica_removeRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + if (from.has_osd_uuid()) { + set_osd_uuid(from.osd_uuid()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_replica_removeRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_replica_removeRequest::CopyFrom(const xtreemfs_replica_removeRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_replica_removeRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000008) != 0x00000008) return false; + + return true; +} + +void xtreemfs_replica_removeRequest::Swap(xtreemfs_replica_removeRequest* other) { + if (other != this) { + std::swap(file_id_, other->file_id_); + std::swap(path_, other->path_); + std::swap(volume_name_, other->volume_name_); + std::swap(osd_uuid_, other->osd_uuid_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_replica_removeRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_replica_removeRequest_descriptor_; + metadata.reflection = xtreemfs_replica_removeRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_restore_fileRequest::kFilePathFieldNumber; +const int xtreemfs_restore_fileRequest::kFileIdFieldNumber; +const int xtreemfs_restore_fileRequest::kFileSizeFieldNumber; +const int xtreemfs_restore_fileRequest::kOsdUuidFieldNumber; +const int xtreemfs_restore_fileRequest::kStripeSizeFieldNumber; +#endif // !_MSC_VER + +xtreemfs_restore_fileRequest::xtreemfs_restore_fileRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_restore_fileRequest::InitAsDefaultInstance() { +} + +xtreemfs_restore_fileRequest::xtreemfs_restore_fileRequest(const xtreemfs_restore_fileRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_restore_fileRequest::SharedCtor() { + _cached_size_ = 0; + file_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + file_size_ = GOOGLE_ULONGLONG(0); + osd_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + stripe_size_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_restore_fileRequest::~xtreemfs_restore_fileRequest() { + SharedDtor(); +} + +void xtreemfs_restore_fileRequest::SharedDtor() { + if (file_path_ != &::google::protobuf::internal::kEmptyString) { + delete file_path_; + } + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + delete osd_uuid_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_restore_fileRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_restore_fileRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_restore_fileRequest_descriptor_; +} + +const xtreemfs_restore_fileRequest& xtreemfs_restore_fileRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_restore_fileRequest* xtreemfs_restore_fileRequest::default_instance_ = NULL; + +xtreemfs_restore_fileRequest* xtreemfs_restore_fileRequest::New() const { + return new xtreemfs_restore_fileRequest; +} + +void xtreemfs_restore_fileRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_path()) { + if (file_path_ != &::google::protobuf::internal::kEmptyString) { + file_path_->clear(); + } + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + file_size_ = GOOGLE_ULONGLONG(0); + if (has_osd_uuid()) { + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + osd_uuid_->clear(); + } + } + stripe_size_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_restore_fileRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string file_path = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_path().data(), this->file_path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_file_size; + break; + } + + // required fixed64 file_size = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_file_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &file_size_))); + set_has_file_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_osd_uuid; + break; + } + + // required string osd_uuid = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_osd_uuid: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_osd_uuid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuid().data(), this->osd_uuid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(45)) goto parse_stripe_size; + break; + } + + // required fixed32 stripe_size = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_stripe_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &stripe_size_))); + set_has_stripe_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_restore_fileRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string file_path = 1; + if (has_file_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_path().data(), this->file_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_path(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed64 file_size = 3; + if (has_file_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->file_size(), output); + } + + // required string osd_uuid = 4; + if (has_osd_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuid().data(), this->osd_uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->osd_uuid(), output); + } + + // required fixed32 stripe_size = 5; + if (has_stripe_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(5, this->stripe_size(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_restore_fileRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string file_path = 1; + if (has_file_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_path().data(), this->file_path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->file_path(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed64 file_size = 3; + if (has_file_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->file_size(), target); + } + + // required string osd_uuid = 4; + if (has_osd_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuid().data(), this->osd_uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->osd_uuid(), target); + } + + // required fixed32 stripe_size = 5; + if (has_stripe_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(5, this->stripe_size(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_restore_fileRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string file_path = 1; + if (has_file_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_path()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 file_size = 3; + if (has_file_size()) { + total_size += 1 + 8; + } + + // required string osd_uuid = 4; + if (has_osd_uuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->osd_uuid()); + } + + // required fixed32 stripe_size = 5; + if (has_stripe_size()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_restore_fileRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_restore_fileRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_restore_fileRequest::MergeFrom(const xtreemfs_restore_fileRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_path()) { + set_file_path(from.file_path()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_file_size()) { + set_file_size(from.file_size()); + } + if (from.has_osd_uuid()) { + set_osd_uuid(from.osd_uuid()); + } + if (from.has_stripe_size()) { + set_stripe_size(from.stripe_size()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_restore_fileRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_restore_fileRequest::CopyFrom(const xtreemfs_restore_fileRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_restore_fileRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false; + + return true; +} + +void xtreemfs_restore_fileRequest::Swap(xtreemfs_restore_fileRequest* other) { + if (other != this) { + std::swap(file_path_, other->file_path_); + std::swap(file_id_, other->file_id_); + std::swap(file_size_, other->file_size_); + std::swap(osd_uuid_, other->osd_uuid_); + std::swap(stripe_size_, other->stripe_size_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_restore_fileRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_restore_fileRequest_descriptor_; + metadata.reflection = xtreemfs_restore_fileRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_rmvolRequest::kVolumeNameFieldNumber; +#endif // !_MSC_VER + +xtreemfs_rmvolRequest::xtreemfs_rmvolRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_rmvolRequest::InitAsDefaultInstance() { +} + +xtreemfs_rmvolRequest::xtreemfs_rmvolRequest(const xtreemfs_rmvolRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_rmvolRequest::SharedCtor() { + _cached_size_ = 0; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_rmvolRequest::~xtreemfs_rmvolRequest() { + SharedDtor(); +} + +void xtreemfs_rmvolRequest::SharedDtor() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_rmvolRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_rmvolRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_rmvolRequest_descriptor_; +} + +const xtreemfs_rmvolRequest& xtreemfs_rmvolRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_rmvolRequest* xtreemfs_rmvolRequest::default_instance_ = NULL; + +xtreemfs_rmvolRequest* xtreemfs_rmvolRequest::New() const { + return new xtreemfs_rmvolRequest; +} + +void xtreemfs_rmvolRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_volume_name()) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_rmvolRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string volume_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_volume_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_rmvolRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->volume_name(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_rmvolRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string volume_name = 1; + if (has_volume_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->volume_name().data(), this->volume_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->volume_name(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_rmvolRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string volume_name = 1; + if (has_volume_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->volume_name()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_rmvolRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_rmvolRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_rmvolRequest::MergeFrom(const xtreemfs_rmvolRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_volume_name()) { + set_volume_name(from.volume_name()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_rmvolRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_rmvolRequest::CopyFrom(const xtreemfs_rmvolRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_rmvolRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void xtreemfs_rmvolRequest::Swap(xtreemfs_rmvolRequest* other) { + if (other != this) { + std::swap(volume_name_, other->volume_name_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_rmvolRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_rmvolRequest_descriptor_; + metadata.reflection = xtreemfs_rmvolRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_update_file_sizeRequest::kXcapFieldNumber; +const int xtreemfs_update_file_sizeRequest::kOsdWriteResponseFieldNumber; +const int xtreemfs_update_file_sizeRequest::kCloseFileFieldNumber; +const int xtreemfs_update_file_sizeRequest::kCoordinatesFieldNumber; +#endif // !_MSC_VER + +xtreemfs_update_file_sizeRequest::xtreemfs_update_file_sizeRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_update_file_sizeRequest::InitAsDefaultInstance() { + xcap_ = const_cast< ::xtreemfs::pbrpc::XCap*>(&::xtreemfs::pbrpc::XCap::default_instance()); + osd_write_response_ = const_cast< ::xtreemfs::pbrpc::OSDWriteResponse*>(&::xtreemfs::pbrpc::OSDWriteResponse::default_instance()); + coordinates_ = const_cast< ::xtreemfs::pbrpc::VivaldiCoordinates*>(&::xtreemfs::pbrpc::VivaldiCoordinates::default_instance()); +} + +xtreemfs_update_file_sizeRequest::xtreemfs_update_file_sizeRequest(const xtreemfs_update_file_sizeRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_update_file_sizeRequest::SharedCtor() { + _cached_size_ = 0; + xcap_ = NULL; + osd_write_response_ = NULL; + close_file_ = false; + coordinates_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_update_file_sizeRequest::~xtreemfs_update_file_sizeRequest() { + SharedDtor(); +} + +void xtreemfs_update_file_sizeRequest::SharedDtor() { + if (this != default_instance_) { + delete xcap_; + delete osd_write_response_; + delete coordinates_; + } +} + +void xtreemfs_update_file_sizeRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_update_file_sizeRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_update_file_sizeRequest_descriptor_; +} + +const xtreemfs_update_file_sizeRequest& xtreemfs_update_file_sizeRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_update_file_sizeRequest* xtreemfs_update_file_sizeRequest::default_instance_ = NULL; + +xtreemfs_update_file_sizeRequest* xtreemfs_update_file_sizeRequest::New() const { + return new xtreemfs_update_file_sizeRequest; +} + +void xtreemfs_update_file_sizeRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_xcap()) { + if (xcap_ != NULL) xcap_->::xtreemfs::pbrpc::XCap::Clear(); + } + if (has_osd_write_response()) { + if (osd_write_response_ != NULL) osd_write_response_->::xtreemfs::pbrpc::OSDWriteResponse::Clear(); + } + close_file_ = false; + if (has_coordinates()) { + if (coordinates_ != NULL) coordinates_->::xtreemfs::pbrpc::VivaldiCoordinates::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_update_file_sizeRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.XCap xcap = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_xcap())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_osd_write_response; + break; + } + + // required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_osd_write_response: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_osd_write_response())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(24)) goto parse_close_file; + break; + } + + // optional bool close_file = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_close_file: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &close_file_))); + set_has_close_file(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_coordinates; + break; + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_coordinates: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_coordinates())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_update_file_sizeRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.XCap xcap = 1; + if (has_xcap()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->xcap(), output); + } + + // required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + if (has_osd_write_response()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->osd_write_response(), output); + } + + // optional bool close_file = 3; + if (has_close_file()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->close_file(), output); + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + if (has_coordinates()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, this->coordinates(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_update_file_sizeRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.XCap xcap = 1; + if (has_xcap()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->xcap(), target); + } + + // required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + if (has_osd_write_response()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->osd_write_response(), target); + } + + // optional bool close_file = 3; + if (has_close_file()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->close_file(), target); + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + if (has_coordinates()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->coordinates(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_update_file_sizeRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.XCap xcap = 1; + if (has_xcap()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->xcap()); + } + + // required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + if (has_osd_write_response()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->osd_write_response()); + } + + // optional bool close_file = 3; + if (has_close_file()) { + total_size += 1 + 1; + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + if (has_coordinates()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->coordinates()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_update_file_sizeRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_update_file_sizeRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_update_file_sizeRequest::MergeFrom(const xtreemfs_update_file_sizeRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_xcap()) { + mutable_xcap()->::xtreemfs::pbrpc::XCap::MergeFrom(from.xcap()); + } + if (from.has_osd_write_response()) { + mutable_osd_write_response()->::xtreemfs::pbrpc::OSDWriteResponse::MergeFrom(from.osd_write_response()); + } + if (from.has_close_file()) { + set_close_file(from.close_file()); + } + if (from.has_coordinates()) { + mutable_coordinates()->::xtreemfs::pbrpc::VivaldiCoordinates::MergeFrom(from.coordinates()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_update_file_sizeRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_update_file_sizeRequest::CopyFrom(const xtreemfs_update_file_sizeRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_update_file_sizeRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_xcap()) { + if (!this->xcap().IsInitialized()) return false; + } + if (has_coordinates()) { + if (!this->coordinates().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_update_file_sizeRequest::Swap(xtreemfs_update_file_sizeRequest* other) { + if (other != this) { + std::swap(xcap_, other->xcap_); + std::swap(osd_write_response_, other->osd_write_response_); + std::swap(close_file_, other->close_file_); + std::swap(coordinates_, other->coordinates_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_update_file_sizeRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_update_file_sizeRequest_descriptor_; + metadata.reflection = xtreemfs_update_file_sizeRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_set_replica_update_policyRequest::kFileIdFieldNumber; +const int xtreemfs_set_replica_update_policyRequest::kUpdatePolicyFieldNumber; +#endif // !_MSC_VER + +xtreemfs_set_replica_update_policyRequest::xtreemfs_set_replica_update_policyRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_set_replica_update_policyRequest::InitAsDefaultInstance() { +} + +xtreemfs_set_replica_update_policyRequest::xtreemfs_set_replica_update_policyRequest(const xtreemfs_set_replica_update_policyRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_set_replica_update_policyRequest::SharedCtor() { + _cached_size_ = 0; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + update_policy_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_set_replica_update_policyRequest::~xtreemfs_set_replica_update_policyRequest() { + SharedDtor(); +} + +void xtreemfs_set_replica_update_policyRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (update_policy_ != &::google::protobuf::internal::kEmptyString) { + delete update_policy_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_set_replica_update_policyRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_set_replica_update_policyRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_set_replica_update_policyRequest_descriptor_; +} + +const xtreemfs_set_replica_update_policyRequest& xtreemfs_set_replica_update_policyRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_set_replica_update_policyRequest* xtreemfs_set_replica_update_policyRequest::default_instance_ = NULL; + +xtreemfs_set_replica_update_policyRequest* xtreemfs_set_replica_update_policyRequest::New() const { + return new xtreemfs_set_replica_update_policyRequest; +} + +void xtreemfs_set_replica_update_policyRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + if (has_update_policy()) { + if (update_policy_ != &::google::protobuf::internal::kEmptyString) { + update_policy_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_set_replica_update_policyRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string file_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_update_policy; + break; + } + + // required string update_policy = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_update_policy: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_update_policy())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->update_policy().data(), this->update_policy().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_set_replica_update_policyRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_id(), output); + } + + // required string update_policy = 2; + if (has_update_policy()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->update_policy().data(), this->update_policy().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->update_policy(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_set_replica_update_policyRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->file_id(), target); + } + + // required string update_policy = 2; + if (has_update_policy()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->update_policy().data(), this->update_policy().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->update_policy(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_set_replica_update_policyRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string file_id = 1; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required string update_policy = 2; + if (has_update_policy()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->update_policy()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_set_replica_update_policyRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_set_replica_update_policyRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_set_replica_update_policyRequest::MergeFrom(const xtreemfs_set_replica_update_policyRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_update_policy()) { + set_update_policy(from.update_policy()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_set_replica_update_policyRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_set_replica_update_policyRequest::CopyFrom(const xtreemfs_set_replica_update_policyRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_set_replica_update_policyRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void xtreemfs_set_replica_update_policyRequest::Swap(xtreemfs_set_replica_update_policyRequest* other) { + if (other != this) { + std::swap(file_id_, other->file_id_); + std::swap(update_policy_, other->update_policy_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_set_replica_update_policyRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_set_replica_update_policyRequest_descriptor_; + metadata.reflection = xtreemfs_set_replica_update_policyRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_set_replica_update_policyResponse::kOldUpdatePolicyFieldNumber; +#endif // !_MSC_VER + +xtreemfs_set_replica_update_policyResponse::xtreemfs_set_replica_update_policyResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_set_replica_update_policyResponse::InitAsDefaultInstance() { +} + +xtreemfs_set_replica_update_policyResponse::xtreemfs_set_replica_update_policyResponse(const xtreemfs_set_replica_update_policyResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_set_replica_update_policyResponse::SharedCtor() { + _cached_size_ = 0; + old_update_policy_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_set_replica_update_policyResponse::~xtreemfs_set_replica_update_policyResponse() { + SharedDtor(); +} + +void xtreemfs_set_replica_update_policyResponse::SharedDtor() { + if (old_update_policy_ != &::google::protobuf::internal::kEmptyString) { + delete old_update_policy_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_set_replica_update_policyResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_set_replica_update_policyResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_set_replica_update_policyResponse_descriptor_; +} + +const xtreemfs_set_replica_update_policyResponse& xtreemfs_set_replica_update_policyResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_set_replica_update_policyResponse* xtreemfs_set_replica_update_policyResponse::default_instance_ = NULL; + +xtreemfs_set_replica_update_policyResponse* xtreemfs_set_replica_update_policyResponse::New() const { + return new xtreemfs_set_replica_update_policyResponse; +} + +void xtreemfs_set_replica_update_policyResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_old_update_policy()) { + if (old_update_policy_ != &::google::protobuf::internal::kEmptyString) { + old_update_policy_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_set_replica_update_policyResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string old_update_policy = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_old_update_policy())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->old_update_policy().data(), this->old_update_policy().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_set_replica_update_policyResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string old_update_policy = 1; + if (has_old_update_policy()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->old_update_policy().data(), this->old_update_policy().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->old_update_policy(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_set_replica_update_policyResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string old_update_policy = 1; + if (has_old_update_policy()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->old_update_policy().data(), this->old_update_policy().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->old_update_policy(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_set_replica_update_policyResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string old_update_policy = 1; + if (has_old_update_policy()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->old_update_policy()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_set_replica_update_policyResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_set_replica_update_policyResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_set_replica_update_policyResponse::MergeFrom(const xtreemfs_set_replica_update_policyResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_old_update_policy()) { + set_old_update_policy(from.old_update_policy()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_set_replica_update_policyResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_set_replica_update_policyResponse::CopyFrom(const xtreemfs_set_replica_update_policyResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_set_replica_update_policyResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void xtreemfs_set_replica_update_policyResponse::Swap(xtreemfs_set_replica_update_policyResponse* other) { + if (other != this) { + std::swap(old_update_policy_, other->old_update_policy_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_set_replica_update_policyResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_set_replica_update_policyResponse_descriptor_; + metadata.reflection = xtreemfs_set_replica_update_policyResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_set_read_only_xattrRequest::kFileIdFieldNumber; +const int xtreemfs_set_read_only_xattrRequest::kValueFieldNumber; +#endif // !_MSC_VER + +xtreemfs_set_read_only_xattrRequest::xtreemfs_set_read_only_xattrRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_set_read_only_xattrRequest::InitAsDefaultInstance() { +} + +xtreemfs_set_read_only_xattrRequest::xtreemfs_set_read_only_xattrRequest(const xtreemfs_set_read_only_xattrRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_set_read_only_xattrRequest::SharedCtor() { + _cached_size_ = 0; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + value_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_set_read_only_xattrRequest::~xtreemfs_set_read_only_xattrRequest() { + SharedDtor(); +} + +void xtreemfs_set_read_only_xattrRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_set_read_only_xattrRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_set_read_only_xattrRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_set_read_only_xattrRequest_descriptor_; +} + +const xtreemfs_set_read_only_xattrRequest& xtreemfs_set_read_only_xattrRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_set_read_only_xattrRequest* xtreemfs_set_read_only_xattrRequest::default_instance_ = NULL; + +xtreemfs_set_read_only_xattrRequest* xtreemfs_set_read_only_xattrRequest::New() const { + return new xtreemfs_set_read_only_xattrRequest; +} + +void xtreemfs_set_read_only_xattrRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + value_ = false; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_set_read_only_xattrRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string file_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_value; + break; + } + + // required bool value = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &value_))); + set_has_value(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_set_read_only_xattrRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_id(), output); + } + + // required bool value = 2; + if (has_value()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->value(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_set_read_only_xattrRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->file_id(), target); + } + + // required bool value = 2; + if (has_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->value(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_set_read_only_xattrRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string file_id = 1; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required bool value = 2; + if (has_value()) { + total_size += 1 + 1; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_set_read_only_xattrRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_set_read_only_xattrRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_set_read_only_xattrRequest::MergeFrom(const xtreemfs_set_read_only_xattrRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_value()) { + set_value(from.value()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_set_read_only_xattrRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_set_read_only_xattrRequest::CopyFrom(const xtreemfs_set_read_only_xattrRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_set_read_only_xattrRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void xtreemfs_set_read_only_xattrRequest::Swap(xtreemfs_set_read_only_xattrRequest* other) { + if (other != this) { + std::swap(file_id_, other->file_id_); + std::swap(value_, other->value_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_set_read_only_xattrRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_set_read_only_xattrRequest_descriptor_; + metadata.reflection = xtreemfs_set_read_only_xattrRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_set_read_only_xattrResponse::kWasSetFieldNumber; +#endif // !_MSC_VER + +xtreemfs_set_read_only_xattrResponse::xtreemfs_set_read_only_xattrResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_set_read_only_xattrResponse::InitAsDefaultInstance() { +} + +xtreemfs_set_read_only_xattrResponse::xtreemfs_set_read_only_xattrResponse(const xtreemfs_set_read_only_xattrResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_set_read_only_xattrResponse::SharedCtor() { + _cached_size_ = 0; + was_set_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_set_read_only_xattrResponse::~xtreemfs_set_read_only_xattrResponse() { + SharedDtor(); +} + +void xtreemfs_set_read_only_xattrResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void xtreemfs_set_read_only_xattrResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_set_read_only_xattrResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_set_read_only_xattrResponse_descriptor_; +} + +const xtreemfs_set_read_only_xattrResponse& xtreemfs_set_read_only_xattrResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_set_read_only_xattrResponse* xtreemfs_set_read_only_xattrResponse::default_instance_ = NULL; + +xtreemfs_set_read_only_xattrResponse* xtreemfs_set_read_only_xattrResponse::New() const { + return new xtreemfs_set_read_only_xattrResponse; +} + +void xtreemfs_set_read_only_xattrResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + was_set_ = false; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_set_read_only_xattrResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required bool was_set = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &was_set_))); + set_has_was_set(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_set_read_only_xattrResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required bool was_set = 1; + if (has_was_set()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->was_set(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_set_read_only_xattrResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required bool was_set = 1; + if (has_was_set()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->was_set(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_set_read_only_xattrResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required bool was_set = 1; + if (has_was_set()) { + total_size += 1 + 1; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_set_read_only_xattrResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_set_read_only_xattrResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_set_read_only_xattrResponse::MergeFrom(const xtreemfs_set_read_only_xattrResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_was_set()) { + set_was_set(from.was_set()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_set_read_only_xattrResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_set_read_only_xattrResponse::CopyFrom(const xtreemfs_set_read_only_xattrResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_set_read_only_xattrResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void xtreemfs_set_read_only_xattrResponse::Swap(xtreemfs_set_read_only_xattrResponse* other) { + if (other != this) { + std::swap(was_set_, other->was_set_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_set_read_only_xattrResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_set_read_only_xattrResponse_descriptor_; + metadata.reflection = xtreemfs_set_read_only_xattrResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_get_file_credentialsRequest::kFileIdFieldNumber; +#endif // !_MSC_VER + +xtreemfs_get_file_credentialsRequest::xtreemfs_get_file_credentialsRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_get_file_credentialsRequest::InitAsDefaultInstance() { +} + +xtreemfs_get_file_credentialsRequest::xtreemfs_get_file_credentialsRequest(const xtreemfs_get_file_credentialsRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_get_file_credentialsRequest::SharedCtor() { + _cached_size_ = 0; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_get_file_credentialsRequest::~xtreemfs_get_file_credentialsRequest() { + SharedDtor(); +} + +void xtreemfs_get_file_credentialsRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_get_file_credentialsRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_get_file_credentialsRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_get_file_credentialsRequest_descriptor_; +} + +const xtreemfs_get_file_credentialsRequest& xtreemfs_get_file_credentialsRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + return *default_instance_; +} + +xtreemfs_get_file_credentialsRequest* xtreemfs_get_file_credentialsRequest::default_instance_ = NULL; + +xtreemfs_get_file_credentialsRequest* xtreemfs_get_file_credentialsRequest::New() const { + return new xtreemfs_get_file_credentialsRequest; +} + +void xtreemfs_get_file_credentialsRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_get_file_credentialsRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string file_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_get_file_credentialsRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_id(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_get_file_credentialsRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->file_id(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_get_file_credentialsRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string file_id = 1; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_get_file_credentialsRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_get_file_credentialsRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_get_file_credentialsRequest::MergeFrom(const xtreemfs_get_file_credentialsRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_get_file_credentialsRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_get_file_credentialsRequest::CopyFrom(const xtreemfs_get_file_credentialsRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_get_file_credentialsRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void xtreemfs_get_file_credentialsRequest::Swap(xtreemfs_get_file_credentialsRequest* other) { + if (other != this) { + std::swap(file_id_, other->file_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_get_file_credentialsRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_get_file_credentialsRequest_descriptor_; + metadata.reflection = xtreemfs_get_file_credentialsRequest_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/generated/xtreemfs/MRC.pb.h b/cpp/generated/xtreemfs/MRC.pb.h new file mode 100644 index 0000000..29caf1e --- /dev/null +++ b/cpp/generated/xtreemfs/MRC.pb.h @@ -0,0 +1,14469 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/MRC.proto + +#ifndef PROTOBUF_xtreemfs_2fMRC_2eproto__INCLUDED +#define PROTOBUF_xtreemfs_2fMRC_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include "include/PBRPC.pb.h" +#include "include/Common.pb.h" +#include "xtreemfs/GlobalTypes.pb.h" +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); +void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); +void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + +class Stat; +class DirectoryEntry; +class DirectoryEntries; +class XAttr; +class Volume; +class Volumes; +class StatVFS; +class fsetattrRequest; +class getattrRequest; +class getattrResponse; +class getxattrRequest; +class getxattrResponse; +class linkRequest; +class listxattrRequest; +class listxattrResponse; +class mkdirRequest; +class openRequest; +class openResponse; +class readdirRequest; +class readlinkRequest; +class readlinkResponse; +class removexattrRequest; +class renameRequest; +class renameResponse; +class rmdirRequest; +class setattrRequest; +class setxattrRequest; +class statvfsRequest; +class symlinkRequest; +class unlinkRequest; +class unlinkResponse; +class accessRequest; +class xtreemfs_check_file_existsRequest; +class xtreemfs_check_file_existsResponse; +class xtreemfs_dump_restore_databaseRequest; +class xtreemfs_get_suitable_osdsRequest; +class xtreemfs_get_suitable_osdsResponse; +class timestampResponse; +class stringMessage; +class xtreemfs_listdirRequest; +class xtreemfs_listdirResponse; +class xtreemfs_replica_addRequest; +class xtreemfs_replica_listRequest; +class xtreemfs_get_xlocsetRequest; +class xtreemfs_replica_removeRequest; +class xtreemfs_restore_fileRequest; +class xtreemfs_rmvolRequest; +class xtreemfs_update_file_sizeRequest; +class xtreemfs_set_replica_update_policyRequest; +class xtreemfs_set_replica_update_policyResponse; +class xtreemfs_set_read_only_xattrRequest; +class xtreemfs_set_read_only_xattrResponse; +class xtreemfs_get_file_credentialsRequest; + +enum xtreemfs_check_file_existsResponse_FILE_STATE { + xtreemfs_check_file_existsResponse_FILE_STATE_DELETED = 0, + xtreemfs_check_file_existsResponse_FILE_STATE_REGISTERED = 1, + xtreemfs_check_file_existsResponse_FILE_STATE_ABANDONED = 2 +}; +bool xtreemfs_check_file_existsResponse_FILE_STATE_IsValid(int value); +const xtreemfs_check_file_existsResponse_FILE_STATE xtreemfs_check_file_existsResponse_FILE_STATE_FILE_STATE_MIN = xtreemfs_check_file_existsResponse_FILE_STATE_DELETED; +const xtreemfs_check_file_existsResponse_FILE_STATE xtreemfs_check_file_existsResponse_FILE_STATE_FILE_STATE_MAX = xtreemfs_check_file_existsResponse_FILE_STATE_ABANDONED; +const int xtreemfs_check_file_existsResponse_FILE_STATE_FILE_STATE_ARRAYSIZE = xtreemfs_check_file_existsResponse_FILE_STATE_FILE_STATE_MAX + 1; + +const ::google::protobuf::EnumDescriptor* xtreemfs_check_file_existsResponse_FILE_STATE_descriptor(); +inline const ::std::string& xtreemfs_check_file_existsResponse_FILE_STATE_Name(xtreemfs_check_file_existsResponse_FILE_STATE value) { + return ::google::protobuf::internal::NameOfEnum( + xtreemfs_check_file_existsResponse_FILE_STATE_descriptor(), value); +} +inline bool xtreemfs_check_file_existsResponse_FILE_STATE_Parse( + const ::std::string& name, xtreemfs_check_file_existsResponse_FILE_STATE* value) { + return ::google::protobuf::internal::ParseNamedEnum( + xtreemfs_check_file_existsResponse_FILE_STATE_descriptor(), name, value); +} +enum Setattrs { + SETATTR_MODE = 1, + SETATTR_UID = 2, + SETATTR_GID = 4, + SETATTR_SIZE = 8, + SETATTR_ATIME = 16, + SETATTR_MTIME = 32, + SETATTR_CTIME = 64, + SETATTR_ATTRIBUTES = 128 +}; +bool Setattrs_IsValid(int value); +const Setattrs Setattrs_MIN = SETATTR_MODE; +const Setattrs Setattrs_MAX = SETATTR_ATTRIBUTES; +const int Setattrs_ARRAYSIZE = Setattrs_MAX + 1; + +const ::google::protobuf::EnumDescriptor* Setattrs_descriptor(); +inline const ::std::string& Setattrs_Name(Setattrs value) { + return ::google::protobuf::internal::NameOfEnum( + Setattrs_descriptor(), value); +} +inline bool Setattrs_Parse( + const ::std::string& name, Setattrs* value) { + return ::google::protobuf::internal::ParseNamedEnum( + Setattrs_descriptor(), name, value); +} +enum XATTR_FLAGS { + XATTR_FLAGS_CREATE = 1, + XATTR_FLAGS_REPLACE = 2 +}; +bool XATTR_FLAGS_IsValid(int value); +const XATTR_FLAGS XATTR_FLAGS_MIN = XATTR_FLAGS_CREATE; +const XATTR_FLAGS XATTR_FLAGS_MAX = XATTR_FLAGS_REPLACE; +const int XATTR_FLAGS_ARRAYSIZE = XATTR_FLAGS_MAX + 1; + +const ::google::protobuf::EnumDescriptor* XATTR_FLAGS_descriptor(); +inline const ::std::string& XATTR_FLAGS_Name(XATTR_FLAGS value) { + return ::google::protobuf::internal::NameOfEnum( + XATTR_FLAGS_descriptor(), value); +} +inline bool XATTR_FLAGS_Parse( + const ::std::string& name, XATTR_FLAGS* value) { + return ::google::protobuf::internal::ParseNamedEnum( + XATTR_FLAGS_descriptor(), name, value); +} +enum ACCESS_FLAGS { + ACCESS_FLAGS_F_OK = 0, + ACCESS_FLAGS_X_OK = 1, + ACCESS_FLAGS_W_OK = 2, + ACCESS_FLAGS_R_OK = 4 +}; +bool ACCESS_FLAGS_IsValid(int value); +const ACCESS_FLAGS ACCESS_FLAGS_MIN = ACCESS_FLAGS_F_OK; +const ACCESS_FLAGS ACCESS_FLAGS_MAX = ACCESS_FLAGS_R_OK; +const int ACCESS_FLAGS_ARRAYSIZE = ACCESS_FLAGS_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ACCESS_FLAGS_descriptor(); +inline const ::std::string& ACCESS_FLAGS_Name(ACCESS_FLAGS value) { + return ::google::protobuf::internal::NameOfEnum( + ACCESS_FLAGS_descriptor(), value); +} +inline bool ACCESS_FLAGS_Parse( + const ::std::string& name, ACCESS_FLAGS* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ACCESS_FLAGS_descriptor(), name, value); +} +// =================================================================== + +class Stat : public ::google::protobuf::Message { + public: + Stat(); + virtual ~Stat(); + + Stat(const Stat& from); + + inline Stat& operator=(const Stat& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Stat& default_instance(); + + void Swap(Stat* other); + + // implements Message ---------------------------------------------- + + Stat* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Stat& from); + void MergeFrom(const Stat& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 dev = 1; + inline bool has_dev() const; + inline void clear_dev(); + static const int kDevFieldNumber = 1; + inline ::google::protobuf::uint64 dev() const; + inline void set_dev(::google::protobuf::uint64 value); + + // required fixed64 ino = 2; + inline bool has_ino() const; + inline void clear_ino(); + static const int kInoFieldNumber = 2; + inline ::google::protobuf::uint64 ino() const; + inline void set_ino(::google::protobuf::uint64 value); + + // required fixed32 mode = 3; + inline bool has_mode() const; + inline void clear_mode(); + static const int kModeFieldNumber = 3; + inline ::google::protobuf::uint32 mode() const; + inline void set_mode(::google::protobuf::uint32 value); + + // required fixed32 nlink = 4; + inline bool has_nlink() const; + inline void clear_nlink(); + static const int kNlinkFieldNumber = 4; + inline ::google::protobuf::uint32 nlink() const; + inline void set_nlink(::google::protobuf::uint32 value); + + // required string user_id = 5; + inline bool has_user_id() const; + inline void clear_user_id(); + static const int kUserIdFieldNumber = 5; + inline const ::std::string& user_id() const; + inline void set_user_id(const ::std::string& value); + inline void set_user_id(const char* value); + inline void set_user_id(const char* value, size_t size); + inline ::std::string* mutable_user_id(); + inline ::std::string* release_user_id(); + inline void set_allocated_user_id(::std::string* user_id); + + // required string group_id = 6; + inline bool has_group_id() const; + inline void clear_group_id(); + static const int kGroupIdFieldNumber = 6; + inline const ::std::string& group_id() const; + inline void set_group_id(const ::std::string& value); + inline void set_group_id(const char* value); + inline void set_group_id(const char* value, size_t size); + inline ::std::string* mutable_group_id(); + inline ::std::string* release_group_id(); + inline void set_allocated_group_id(::std::string* group_id); + + // required fixed64 size = 7; + inline bool has_size() const; + inline void clear_size(); + static const int kSizeFieldNumber = 7; + inline ::google::protobuf::uint64 size() const; + inline void set_size(::google::protobuf::uint64 value); + + // required fixed64 atime_ns = 8; + inline bool has_atime_ns() const; + inline void clear_atime_ns(); + static const int kAtimeNsFieldNumber = 8; + inline ::google::protobuf::uint64 atime_ns() const; + inline void set_atime_ns(::google::protobuf::uint64 value); + + // required fixed64 mtime_ns = 9; + inline bool has_mtime_ns() const; + inline void clear_mtime_ns(); + static const int kMtimeNsFieldNumber = 9; + inline ::google::protobuf::uint64 mtime_ns() const; + inline void set_mtime_ns(::google::protobuf::uint64 value); + + // required fixed64 ctime_ns = 10; + inline bool has_ctime_ns() const; + inline void clear_ctime_ns(); + static const int kCtimeNsFieldNumber = 10; + inline ::google::protobuf::uint64 ctime_ns() const; + inline void set_ctime_ns(::google::protobuf::uint64 value); + + // required fixed32 blksize = 11; + inline bool has_blksize() const; + inline void clear_blksize(); + static const int kBlksizeFieldNumber = 11; + inline ::google::protobuf::uint32 blksize() const; + inline void set_blksize(::google::protobuf::uint32 value); + + // optional fixed64 etag = 12; + inline bool has_etag() const; + inline void clear_etag(); + static const int kEtagFieldNumber = 12; + inline ::google::protobuf::uint64 etag() const; + inline void set_etag(::google::protobuf::uint64 value); + + // required fixed32 truncate_epoch = 13; + inline bool has_truncate_epoch() const; + inline void clear_truncate_epoch(); + static const int kTruncateEpochFieldNumber = 13; + inline ::google::protobuf::uint32 truncate_epoch() const; + inline void set_truncate_epoch(::google::protobuf::uint32 value); + + // optional fixed32 attributes = 14; + inline bool has_attributes() const; + inline void clear_attributes(); + static const int kAttributesFieldNumber = 14; + inline ::google::protobuf::uint32 attributes() const; + inline void set_attributes(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Stat) + private: + inline void set_has_dev(); + inline void clear_has_dev(); + inline void set_has_ino(); + inline void clear_has_ino(); + inline void set_has_mode(); + inline void clear_has_mode(); + inline void set_has_nlink(); + inline void clear_has_nlink(); + inline void set_has_user_id(); + inline void clear_has_user_id(); + inline void set_has_group_id(); + inline void clear_has_group_id(); + inline void set_has_size(); + inline void clear_has_size(); + inline void set_has_atime_ns(); + inline void clear_has_atime_ns(); + inline void set_has_mtime_ns(); + inline void clear_has_mtime_ns(); + inline void set_has_ctime_ns(); + inline void clear_has_ctime_ns(); + inline void set_has_blksize(); + inline void clear_has_blksize(); + inline void set_has_etag(); + inline void clear_has_etag(); + inline void set_has_truncate_epoch(); + inline void clear_has_truncate_epoch(); + inline void set_has_attributes(); + inline void clear_has_attributes(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 dev_; + ::google::protobuf::uint64 ino_; + ::google::protobuf::uint32 mode_; + ::google::protobuf::uint32 nlink_; + ::std::string* user_id_; + ::std::string* group_id_; + ::google::protobuf::uint64 size_; + ::google::protobuf::uint64 atime_ns_; + ::google::protobuf::uint64 mtime_ns_; + ::google::protobuf::uint64 ctime_ns_; + ::google::protobuf::uint64 etag_; + ::google::protobuf::uint32 blksize_; + ::google::protobuf::uint32 truncate_epoch_; + ::google::protobuf::uint32 attributes_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(14 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static Stat* default_instance_; +}; +// ------------------------------------------------------------------- + +class DirectoryEntry : public ::google::protobuf::Message { + public: + DirectoryEntry(); + virtual ~DirectoryEntry(); + + DirectoryEntry(const DirectoryEntry& from); + + inline DirectoryEntry& operator=(const DirectoryEntry& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const DirectoryEntry& default_instance(); + + void Swap(DirectoryEntry* other); + + // implements Message ---------------------------------------------- + + DirectoryEntry* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DirectoryEntry& from); + void MergeFrom(const DirectoryEntry& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // optional .xtreemfs.pbrpc.Stat stbuf = 2; + inline bool has_stbuf() const; + inline void clear_stbuf(); + static const int kStbufFieldNumber = 2; + inline const ::xtreemfs::pbrpc::Stat& stbuf() const; + inline ::xtreemfs::pbrpc::Stat* mutable_stbuf(); + inline ::xtreemfs::pbrpc::Stat* release_stbuf(); + inline void set_allocated_stbuf(::xtreemfs::pbrpc::Stat* stbuf); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.DirectoryEntry) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_stbuf(); + inline void clear_has_stbuf(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::xtreemfs::pbrpc::Stat* stbuf_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static DirectoryEntry* default_instance_; +}; +// ------------------------------------------------------------------- + +class DirectoryEntries : public ::google::protobuf::Message { + public: + DirectoryEntries(); + virtual ~DirectoryEntries(); + + DirectoryEntries(const DirectoryEntries& from); + + inline DirectoryEntries& operator=(const DirectoryEntries& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const DirectoryEntries& default_instance(); + + void Swap(DirectoryEntries* other); + + // implements Message ---------------------------------------------- + + DirectoryEntries* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DirectoryEntries& from); + void MergeFrom(const DirectoryEntries& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + inline int entries_size() const; + inline void clear_entries(); + static const int kEntriesFieldNumber = 1; + inline const ::xtreemfs::pbrpc::DirectoryEntry& entries(int index) const; + inline ::xtreemfs::pbrpc::DirectoryEntry* mutable_entries(int index); + inline ::xtreemfs::pbrpc::DirectoryEntry* add_entries(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::DirectoryEntry >& + entries() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::DirectoryEntry >* + mutable_entries(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.DirectoryEntries) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::DirectoryEntry > entries_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static DirectoryEntries* default_instance_; +}; +// ------------------------------------------------------------------- + +class XAttr : public ::google::protobuf::Message { + public: + XAttr(); + virtual ~XAttr(); + + XAttr(const XAttr& from); + + inline XAttr& operator=(const XAttr& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const XAttr& default_instance(); + + void Swap(XAttr* other); + + // implements Message ---------------------------------------------- + + XAttr* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const XAttr& from); + void MergeFrom(const XAttr& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // optional string value = 2; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 2; + inline const ::std::string& value() const; + inline void set_value(const ::std::string& value); + inline void set_value(const char* value); + inline void set_value(const char* value, size_t size); + inline ::std::string* mutable_value(); + inline ::std::string* release_value(); + inline void set_allocated_value(::std::string* value); + + // optional bytes value_bytes_string = 3; + inline bool has_value_bytes_string() const; + inline void clear_value_bytes_string(); + static const int kValueBytesStringFieldNumber = 3; + inline const ::std::string& value_bytes_string() const; + inline void set_value_bytes_string(const ::std::string& value); + inline void set_value_bytes_string(const char* value); + inline void set_value_bytes_string(const void* value, size_t size); + inline ::std::string* mutable_value_bytes_string(); + inline ::std::string* release_value_bytes_string(); + inline void set_allocated_value_bytes_string(::std::string* value_bytes_string); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.XAttr) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_value(); + inline void clear_has_value(); + inline void set_has_value_bytes_string(); + inline void clear_has_value_bytes_string(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::std::string* value_; + ::std::string* value_bytes_string_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static XAttr* default_instance_; +}; +// ------------------------------------------------------------------- + +class Volume : public ::google::protobuf::Message { + public: + Volume(); + virtual ~Volume(); + + Volume(const Volume& from); + + inline Volume& operator=(const Volume& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Volume& default_instance(); + + void Swap(Volume* other); + + // implements Message ---------------------------------------------- + + Volume* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Volume& from); + void MergeFrom(const Volume& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + inline bool has_access_control_policy() const; + inline void clear_access_control_policy(); + static const int kAccessControlPolicyFieldNumber = 1; + inline ::xtreemfs::pbrpc::AccessControlPolicyType access_control_policy() const; + inline void set_access_control_policy(::xtreemfs::pbrpc::AccessControlPolicyType value); + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + inline bool has_default_striping_policy() const; + inline void clear_default_striping_policy(); + static const int kDefaultStripingPolicyFieldNumber = 2; + inline const ::xtreemfs::pbrpc::StripingPolicy& default_striping_policy() const; + inline ::xtreemfs::pbrpc::StripingPolicy* mutable_default_striping_policy(); + inline ::xtreemfs::pbrpc::StripingPolicy* release_default_striping_policy(); + inline void set_allocated_default_striping_policy(::xtreemfs::pbrpc::StripingPolicy* default_striping_policy); + + // required string id = 3; + inline bool has_id() const; + inline void clear_id(); + static const int kIdFieldNumber = 3; + inline const ::std::string& id() const; + inline void set_id(const ::std::string& value); + inline void set_id(const char* value); + inline void set_id(const char* value, size_t size); + inline ::std::string* mutable_id(); + inline ::std::string* release_id(); + inline void set_allocated_id(::std::string* id); + + // required fixed32 mode = 4; + inline bool has_mode() const; + inline void clear_mode(); + static const int kModeFieldNumber = 4; + inline ::google::protobuf::uint32 mode() const; + inline void set_mode(::google::protobuf::uint32 value); + + // required string name = 5; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 5; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // required string owner_group_id = 6; + inline bool has_owner_group_id() const; + inline void clear_owner_group_id(); + static const int kOwnerGroupIdFieldNumber = 6; + inline const ::std::string& owner_group_id() const; + inline void set_owner_group_id(const ::std::string& value); + inline void set_owner_group_id(const char* value); + inline void set_owner_group_id(const char* value, size_t size); + inline ::std::string* mutable_owner_group_id(); + inline ::std::string* release_owner_group_id(); + inline void set_allocated_owner_group_id(::std::string* owner_group_id); + + // required string owner_user_id = 7; + inline bool has_owner_user_id() const; + inline void clear_owner_user_id(); + static const int kOwnerUserIdFieldNumber = 7; + inline const ::std::string& owner_user_id() const; + inline void set_owner_user_id(const ::std::string& value); + inline void set_owner_user_id(const char* value); + inline void set_owner_user_id(const char* value, size_t size); + inline ::std::string* mutable_owner_user_id(); + inline ::std::string* release_owner_user_id(); + inline void set_allocated_owner_user_id(::std::string* owner_user_id); + + // repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + inline int attrs_size() const; + inline void clear_attrs(); + static const int kAttrsFieldNumber = 8; + inline const ::xtreemfs::pbrpc::KeyValuePair& attrs(int index) const; + inline ::xtreemfs::pbrpc::KeyValuePair* mutable_attrs(int index); + inline ::xtreemfs::pbrpc::KeyValuePair* add_attrs(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >& + attrs() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >* + mutable_attrs(); + + // optional fixed64 quota = 9; + inline bool has_quota() const; + inline void clear_quota(); + static const int kQuotaFieldNumber = 9; + inline ::google::protobuf::uint64 quota() const; + inline void set_quota(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Volume) + private: + inline void set_has_access_control_policy(); + inline void clear_has_access_control_policy(); + inline void set_has_default_striping_policy(); + inline void clear_has_default_striping_policy(); + inline void set_has_id(); + inline void clear_has_id(); + inline void set_has_mode(); + inline void clear_has_mode(); + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_owner_group_id(); + inline void clear_has_owner_group_id(); + inline void set_has_owner_user_id(); + inline void clear_has_owner_user_id(); + inline void set_has_quota(); + inline void clear_has_quota(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::StripingPolicy* default_striping_policy_; + int access_control_policy_; + ::google::protobuf::uint32 mode_; + ::std::string* id_; + ::std::string* name_; + ::std::string* owner_group_id_; + ::std::string* owner_user_id_; + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair > attrs_; + ::google::protobuf::uint64 quota_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(9 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static Volume* default_instance_; +}; +// ------------------------------------------------------------------- + +class Volumes : public ::google::protobuf::Message { + public: + Volumes(); + virtual ~Volumes(); + + Volumes(const Volumes& from); + + inline Volumes& operator=(const Volumes& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Volumes& default_instance(); + + void Swap(Volumes* other); + + // implements Message ---------------------------------------------- + + Volumes* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Volumes& from); + void MergeFrom(const Volumes& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .xtreemfs.pbrpc.Volume volumes = 1; + inline int volumes_size() const; + inline void clear_volumes(); + static const int kVolumesFieldNumber = 1; + inline const ::xtreemfs::pbrpc::Volume& volumes(int index) const; + inline ::xtreemfs::pbrpc::Volume* mutable_volumes(int index); + inline ::xtreemfs::pbrpc::Volume* add_volumes(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Volume >& + volumes() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Volume >* + mutable_volumes(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Volumes) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Volume > volumes_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static Volumes* default_instance_; +}; +// ------------------------------------------------------------------- + +class StatVFS : public ::google::protobuf::Message { + public: + StatVFS(); + virtual ~StatVFS(); + + StatVFS(const StatVFS& from); + + inline StatVFS& operator=(const StatVFS& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const StatVFS& default_instance(); + + void Swap(StatVFS* other); + + // implements Message ---------------------------------------------- + + StatVFS* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const StatVFS& from); + void MergeFrom(const StatVFS& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed32 bsize = 1; + inline bool has_bsize() const; + inline void clear_bsize(); + static const int kBsizeFieldNumber = 1; + inline ::google::protobuf::uint32 bsize() const; + inline void set_bsize(::google::protobuf::uint32 value); + + // required fixed64 bavail = 2; + inline bool has_bavail() const; + inline void clear_bavail(); + static const int kBavailFieldNumber = 2; + inline ::google::protobuf::uint64 bavail() const; + inline void set_bavail(::google::protobuf::uint64 value); + + // optional fixed64 bfree = 13; + inline bool has_bfree() const; + inline void clear_bfree(); + static const int kBfreeFieldNumber = 13; + inline ::google::protobuf::uint64 bfree() const; + inline void set_bfree(::google::protobuf::uint64 value); + + // required fixed64 blocks = 3; + inline bool has_blocks() const; + inline void clear_blocks(); + static const int kBlocksFieldNumber = 3; + inline ::google::protobuf::uint64 blocks() const; + inline void set_blocks(::google::protobuf::uint64 value); + + // required string fsid = 4; + inline bool has_fsid() const; + inline void clear_fsid(); + static const int kFsidFieldNumber = 4; + inline const ::std::string& fsid() const; + inline void set_fsid(const ::std::string& value); + inline void set_fsid(const char* value); + inline void set_fsid(const char* value, size_t size); + inline ::std::string* mutable_fsid(); + inline ::std::string* release_fsid(); + inline void set_allocated_fsid(::std::string* fsid); + + // required fixed32 namemax = 5; + inline bool has_namemax() const; + inline void clear_namemax(); + static const int kNamemaxFieldNumber = 5; + inline ::google::protobuf::uint32 namemax() const; + inline void set_namemax(::google::protobuf::uint32 value); + + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + inline bool has_access_control_policy() const; + inline void clear_access_control_policy(); + static const int kAccessControlPolicyFieldNumber = 6; + inline ::xtreemfs::pbrpc::AccessControlPolicyType access_control_policy() const; + inline void set_access_control_policy(::xtreemfs::pbrpc::AccessControlPolicyType value); + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + inline bool has_default_striping_policy() const; + inline void clear_default_striping_policy(); + static const int kDefaultStripingPolicyFieldNumber = 7; + inline const ::xtreemfs::pbrpc::StripingPolicy& default_striping_policy() const; + inline ::xtreemfs::pbrpc::StripingPolicy* mutable_default_striping_policy(); + inline ::xtreemfs::pbrpc::StripingPolicy* release_default_striping_policy(); + inline void set_allocated_default_striping_policy(::xtreemfs::pbrpc::StripingPolicy* default_striping_policy); + + // required fixed64 etag = 8; + inline bool has_etag() const; + inline void clear_etag(); + static const int kEtagFieldNumber = 8; + inline ::google::protobuf::uint64 etag() const; + inline void set_etag(::google::protobuf::uint64 value); + + // required fixed32 mode = 9; + inline bool has_mode() const; + inline void clear_mode(); + static const int kModeFieldNumber = 9; + inline ::google::protobuf::uint32 mode() const; + inline void set_mode(::google::protobuf::uint32 value); + + // required string name = 10; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 10; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // required string owner_group_id = 11; + inline bool has_owner_group_id() const; + inline void clear_owner_group_id(); + static const int kOwnerGroupIdFieldNumber = 11; + inline const ::std::string& owner_group_id() const; + inline void set_owner_group_id(const ::std::string& value); + inline void set_owner_group_id(const char* value); + inline void set_owner_group_id(const char* value, size_t size); + inline ::std::string* mutable_owner_group_id(); + inline ::std::string* release_owner_group_id(); + inline void set_allocated_owner_group_id(::std::string* owner_group_id); + + // required string owner_user_id = 12; + inline bool has_owner_user_id() const; + inline void clear_owner_user_id(); + static const int kOwnerUserIdFieldNumber = 12; + inline const ::std::string& owner_user_id() const; + inline void set_owner_user_id(const ::std::string& value); + inline void set_owner_user_id(const char* value); + inline void set_owner_user_id(const char* value, size_t size); + inline ::std::string* mutable_owner_user_id(); + inline ::std::string* release_owner_user_id(); + inline void set_allocated_owner_user_id(::std::string* owner_user_id); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.StatVFS) + private: + inline void set_has_bsize(); + inline void clear_has_bsize(); + inline void set_has_bavail(); + inline void clear_has_bavail(); + inline void set_has_bfree(); + inline void clear_has_bfree(); + inline void set_has_blocks(); + inline void clear_has_blocks(); + inline void set_has_fsid(); + inline void clear_has_fsid(); + inline void set_has_namemax(); + inline void clear_has_namemax(); + inline void set_has_access_control_policy(); + inline void clear_has_access_control_policy(); + inline void set_has_default_striping_policy(); + inline void clear_has_default_striping_policy(); + inline void set_has_etag(); + inline void clear_has_etag(); + inline void set_has_mode(); + inline void clear_has_mode(); + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_owner_group_id(); + inline void clear_has_owner_group_id(); + inline void set_has_owner_user_id(); + inline void clear_has_owner_user_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 bavail_; + ::google::protobuf::uint64 bfree_; + ::google::protobuf::uint32 bsize_; + ::google::protobuf::uint32 namemax_; + ::google::protobuf::uint64 blocks_; + ::std::string* fsid_; + ::xtreemfs::pbrpc::StripingPolicy* default_striping_policy_; + int access_control_policy_; + ::google::protobuf::uint32 mode_; + ::google::protobuf::uint64 etag_; + ::std::string* name_; + ::std::string* owner_group_id_; + ::std::string* owner_user_id_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(13 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static StatVFS* default_instance_; +}; +// ------------------------------------------------------------------- + +class fsetattrRequest : public ::google::protobuf::Message { + public: + fsetattrRequest(); + virtual ~fsetattrRequest(); + + fsetattrRequest(const fsetattrRequest& from); + + inline fsetattrRequest& operator=(const fsetattrRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const fsetattrRequest& default_instance(); + + void Swap(fsetattrRequest* other); + + // implements Message ---------------------------------------------- + + fsetattrRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const fsetattrRequest& from); + void MergeFrom(const fsetattrRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.Stat stbuf = 1; + inline bool has_stbuf() const; + inline void clear_stbuf(); + static const int kStbufFieldNumber = 1; + inline const ::xtreemfs::pbrpc::Stat& stbuf() const; + inline ::xtreemfs::pbrpc::Stat* mutable_stbuf(); + inline ::xtreemfs::pbrpc::Stat* release_stbuf(); + inline void set_allocated_stbuf(::xtreemfs::pbrpc::Stat* stbuf); + + // required fixed32 to_set = 2; + inline bool has_to_set() const; + inline void clear_to_set(); + static const int kToSetFieldNumber = 2; + inline ::google::protobuf::uint32 to_set() const; + inline void set_to_set(::google::protobuf::uint32 value); + + // required .xtreemfs.pbrpc.XCap cap = 3; + inline bool has_cap() const; + inline void clear_cap(); + static const int kCapFieldNumber = 3; + inline const ::xtreemfs::pbrpc::XCap& cap() const; + inline ::xtreemfs::pbrpc::XCap* mutable_cap(); + inline ::xtreemfs::pbrpc::XCap* release_cap(); + inline void set_allocated_cap(::xtreemfs::pbrpc::XCap* cap); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.fsetattrRequest) + private: + inline void set_has_stbuf(); + inline void clear_has_stbuf(); + inline void set_has_to_set(); + inline void clear_has_to_set(); + inline void set_has_cap(); + inline void clear_has_cap(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::Stat* stbuf_; + ::xtreemfs::pbrpc::XCap* cap_; + ::google::protobuf::uint32 to_set_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static fsetattrRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class getattrRequest : public ::google::protobuf::Message { + public: + getattrRequest(); + virtual ~getattrRequest(); + + getattrRequest(const getattrRequest& from); + + inline getattrRequest& operator=(const getattrRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const getattrRequest& default_instance(); + + void Swap(getattrRequest* other); + + // implements Message ---------------------------------------------- + + getattrRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const getattrRequest& from); + void MergeFrom(const getattrRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // required fixed64 known_etag = 3; + inline bool has_known_etag() const; + inline void clear_known_etag(); + static const int kKnownEtagFieldNumber = 3; + inline ::google::protobuf::uint64 known_etag() const; + inline void set_known_etag(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.getattrRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_known_etag(); + inline void clear_has_known_etag(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + ::google::protobuf::uint64 known_etag_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static getattrRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class getattrResponse : public ::google::protobuf::Message { + public: + getattrResponse(); + virtual ~getattrResponse(); + + getattrResponse(const getattrResponse& from); + + inline getattrResponse& operator=(const getattrResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const getattrResponse& default_instance(); + + void Swap(getattrResponse* other); + + // implements Message ---------------------------------------------- + + getattrResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const getattrResponse& from); + void MergeFrom(const getattrResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .xtreemfs.pbrpc.Stat stbuf = 1; + inline bool has_stbuf() const; + inline void clear_stbuf(); + static const int kStbufFieldNumber = 1; + inline const ::xtreemfs::pbrpc::Stat& stbuf() const; + inline ::xtreemfs::pbrpc::Stat* mutable_stbuf(); + inline ::xtreemfs::pbrpc::Stat* release_stbuf(); + inline void set_allocated_stbuf(::xtreemfs::pbrpc::Stat* stbuf); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.getattrResponse) + private: + inline void set_has_stbuf(); + inline void clear_has_stbuf(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::Stat* stbuf_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static getattrResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class getxattrRequest : public ::google::protobuf::Message { + public: + getxattrRequest(); + virtual ~getxattrRequest(); + + getxattrRequest(const getxattrRequest& from); + + inline getxattrRequest& operator=(const getxattrRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const getxattrRequest& default_instance(); + + void Swap(getxattrRequest* other); + + // implements Message ---------------------------------------------- + + getxattrRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const getxattrRequest& from); + void MergeFrom(const getxattrRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // required string name = 3; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 3; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.getxattrRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_name(); + inline void clear_has_name(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + ::std::string* name_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static getxattrRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class getxattrResponse : public ::google::protobuf::Message { + public: + getxattrResponse(); + virtual ~getxattrResponse(); + + getxattrResponse(const getxattrResponse& from); + + inline getxattrResponse& operator=(const getxattrResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const getxattrResponse& default_instance(); + + void Swap(getxattrResponse* other); + + // implements Message ---------------------------------------------- + + getxattrResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const getxattrResponse& from); + void MergeFrom(const getxattrResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string value = 1; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 1; + inline const ::std::string& value() const; + inline void set_value(const ::std::string& value); + inline void set_value(const char* value); + inline void set_value(const char* value, size_t size); + inline ::std::string* mutable_value(); + inline ::std::string* release_value(); + inline void set_allocated_value(::std::string* value); + + // optional bytes value_bytes_string = 2; + inline bool has_value_bytes_string() const; + inline void clear_value_bytes_string(); + static const int kValueBytesStringFieldNumber = 2; + inline const ::std::string& value_bytes_string() const; + inline void set_value_bytes_string(const ::std::string& value); + inline void set_value_bytes_string(const char* value); + inline void set_value_bytes_string(const void* value, size_t size); + inline ::std::string* mutable_value_bytes_string(); + inline ::std::string* release_value_bytes_string(); + inline void set_allocated_value_bytes_string(::std::string* value_bytes_string); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.getxattrResponse) + private: + inline void set_has_value(); + inline void clear_has_value(); + inline void set_has_value_bytes_string(); + inline void clear_has_value_bytes_string(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* value_; + ::std::string* value_bytes_string_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static getxattrResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class linkRequest : public ::google::protobuf::Message { + public: + linkRequest(); + virtual ~linkRequest(); + + linkRequest(const linkRequest& from); + + inline linkRequest& operator=(const linkRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const linkRequest& default_instance(); + + void Swap(linkRequest* other); + + // implements Message ---------------------------------------------- + + linkRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const linkRequest& from); + void MergeFrom(const linkRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string target_path = 2; + inline bool has_target_path() const; + inline void clear_target_path(); + static const int kTargetPathFieldNumber = 2; + inline const ::std::string& target_path() const; + inline void set_target_path(const ::std::string& value); + inline void set_target_path(const char* value); + inline void set_target_path(const char* value, size_t size); + inline ::std::string* mutable_target_path(); + inline ::std::string* release_target_path(); + inline void set_allocated_target_path(::std::string* target_path); + + // required string link_path = 3; + inline bool has_link_path() const; + inline void clear_link_path(); + static const int kLinkPathFieldNumber = 3; + inline const ::std::string& link_path() const; + inline void set_link_path(const ::std::string& value); + inline void set_link_path(const char* value); + inline void set_link_path(const char* value, size_t size); + inline ::std::string* mutable_link_path(); + inline ::std::string* release_link_path(); + inline void set_allocated_link_path(::std::string* link_path); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.linkRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_target_path(); + inline void clear_has_target_path(); + inline void set_has_link_path(); + inline void clear_has_link_path(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* target_path_; + ::std::string* link_path_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static linkRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class listxattrRequest : public ::google::protobuf::Message { + public: + listxattrRequest(); + virtual ~listxattrRequest(); + + listxattrRequest(const listxattrRequest& from); + + inline listxattrRequest& operator=(const listxattrRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const listxattrRequest& default_instance(); + + void Swap(listxattrRequest* other); + + // implements Message ---------------------------------------------- + + listxattrRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const listxattrRequest& from); + void MergeFrom(const listxattrRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // required bool names_only = 3; + inline bool has_names_only() const; + inline void clear_names_only(); + static const int kNamesOnlyFieldNumber = 3; + inline bool names_only() const; + inline void set_names_only(bool value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.listxattrRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_names_only(); + inline void clear_has_names_only(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + bool names_only_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static listxattrRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class listxattrResponse : public ::google::protobuf::Message { + public: + listxattrResponse(); + virtual ~listxattrResponse(); + + listxattrResponse(const listxattrResponse& from); + + inline listxattrResponse& operator=(const listxattrResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const listxattrResponse& default_instance(); + + void Swap(listxattrResponse* other); + + // implements Message ---------------------------------------------- + + listxattrResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const listxattrResponse& from); + void MergeFrom(const listxattrResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + inline int xattrs_size() const; + inline void clear_xattrs(); + static const int kXattrsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::XAttr& xattrs(int index) const; + inline ::xtreemfs::pbrpc::XAttr* mutable_xattrs(int index); + inline ::xtreemfs::pbrpc::XAttr* add_xattrs(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::XAttr >& + xattrs() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::XAttr >* + mutable_xattrs(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.listxattrResponse) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::XAttr > xattrs_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static listxattrResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class mkdirRequest : public ::google::protobuf::Message { + public: + mkdirRequest(); + virtual ~mkdirRequest(); + + mkdirRequest(const mkdirRequest& from); + + inline mkdirRequest& operator=(const mkdirRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const mkdirRequest& default_instance(); + + void Swap(mkdirRequest* other); + + // implements Message ---------------------------------------------- + + mkdirRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const mkdirRequest& from); + void MergeFrom(const mkdirRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // required fixed32 mode = 3; + inline bool has_mode() const; + inline void clear_mode(); + static const int kModeFieldNumber = 3; + inline ::google::protobuf::uint32 mode() const; + inline void set_mode(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.mkdirRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_mode(); + inline void clear_has_mode(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + ::google::protobuf::uint32 mode_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static mkdirRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class openRequest : public ::google::protobuf::Message { + public: + openRequest(); + virtual ~openRequest(); + + openRequest(const openRequest& from); + + inline openRequest& operator=(const openRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const openRequest& default_instance(); + + void Swap(openRequest* other); + + // implements Message ---------------------------------------------- + + openRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const openRequest& from); + void MergeFrom(const openRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // required fixed32 flags = 3; + inline bool has_flags() const; + inline void clear_flags(); + static const int kFlagsFieldNumber = 3; + inline ::google::protobuf::uint32 flags() const; + inline void set_flags(::google::protobuf::uint32 value); + + // required fixed32 mode = 4; + inline bool has_mode() const; + inline void clear_mode(); + static const int kModeFieldNumber = 4; + inline ::google::protobuf::uint32 mode() const; + inline void set_mode(::google::protobuf::uint32 value); + + // required fixed32 attributes = 5; + inline bool has_attributes() const; + inline void clear_attributes(); + static const int kAttributesFieldNumber = 5; + inline ::google::protobuf::uint32 attributes() const; + inline void set_attributes(::google::protobuf::uint32 value); + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + inline bool has_coordinates() const; + inline void clear_coordinates(); + static const int kCoordinatesFieldNumber = 6; + inline const ::xtreemfs::pbrpc::VivaldiCoordinates& coordinates() const; + inline ::xtreemfs::pbrpc::VivaldiCoordinates* mutable_coordinates(); + inline ::xtreemfs::pbrpc::VivaldiCoordinates* release_coordinates(); + inline void set_allocated_coordinates(::xtreemfs::pbrpc::VivaldiCoordinates* coordinates); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.openRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_flags(); + inline void clear_has_flags(); + inline void set_has_mode(); + inline void clear_has_mode(); + inline void set_has_attributes(); + inline void clear_has_attributes(); + inline void set_has_coordinates(); + inline void clear_has_coordinates(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + ::google::protobuf::uint32 flags_; + ::google::protobuf::uint32 mode_; + ::xtreemfs::pbrpc::VivaldiCoordinates* coordinates_; + ::google::protobuf::uint32 attributes_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static openRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class openResponse : public ::google::protobuf::Message { + public: + openResponse(); + virtual ~openResponse(); + + openResponse(const openResponse& from); + + inline openResponse& operator=(const openResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const openResponse& default_instance(); + + void Swap(openResponse* other); + + // implements Message ---------------------------------------------- + + openResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const openResponse& from); + void MergeFrom(const openResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials creds = 1; + inline bool has_creds() const; + inline void clear_creds(); + static const int kCredsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& creds() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_creds(); + inline ::xtreemfs::pbrpc::FileCredentials* release_creds(); + inline void set_allocated_creds(::xtreemfs::pbrpc::FileCredentials* creds); + + // required fixed32 timestamp_s = 2; + inline bool has_timestamp_s() const; + inline void clear_timestamp_s(); + static const int kTimestampSFieldNumber = 2; + inline ::google::protobuf::uint32 timestamp_s() const; + inline void set_timestamp_s(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.openResponse) + private: + inline void set_has_creds(); + inline void clear_has_creds(); + inline void set_has_timestamp_s(); + inline void clear_has_timestamp_s(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* creds_; + ::google::protobuf::uint32 timestamp_s_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static openResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class readdirRequest : public ::google::protobuf::Message { + public: + readdirRequest(); + virtual ~readdirRequest(); + + readdirRequest(const readdirRequest& from); + + inline readdirRequest& operator=(const readdirRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const readdirRequest& default_instance(); + + void Swap(readdirRequest* other); + + // implements Message ---------------------------------------------- + + readdirRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const readdirRequest& from); + void MergeFrom(const readdirRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // required fixed64 known_etag = 3; + inline bool has_known_etag() const; + inline void clear_known_etag(); + static const int kKnownEtagFieldNumber = 3; + inline ::google::protobuf::uint64 known_etag() const; + inline void set_known_etag(::google::protobuf::uint64 value); + + // required fixed32 limit_directory_entries_count = 4; + inline bool has_limit_directory_entries_count() const; + inline void clear_limit_directory_entries_count(); + static const int kLimitDirectoryEntriesCountFieldNumber = 4; + inline ::google::protobuf::uint32 limit_directory_entries_count() const; + inline void set_limit_directory_entries_count(::google::protobuf::uint32 value); + + // required bool names_only = 5; + inline bool has_names_only() const; + inline void clear_names_only(); + static const int kNamesOnlyFieldNumber = 5; + inline bool names_only() const; + inline void set_names_only(bool value); + + // required fixed64 seen_directory_entries_count = 6; + inline bool has_seen_directory_entries_count() const; + inline void clear_seen_directory_entries_count(); + static const int kSeenDirectoryEntriesCountFieldNumber = 6; + inline ::google::protobuf::uint64 seen_directory_entries_count() const; + inline void set_seen_directory_entries_count(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.readdirRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_known_etag(); + inline void clear_has_known_etag(); + inline void set_has_limit_directory_entries_count(); + inline void clear_has_limit_directory_entries_count(); + inline void set_has_names_only(); + inline void clear_has_names_only(); + inline void set_has_seen_directory_entries_count(); + inline void clear_has_seen_directory_entries_count(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + ::google::protobuf::uint64 known_etag_; + ::google::protobuf::uint32 limit_directory_entries_count_; + bool names_only_; + ::google::protobuf::uint64 seen_directory_entries_count_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static readdirRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class readlinkRequest : public ::google::protobuf::Message { + public: + readlinkRequest(); + virtual ~readlinkRequest(); + + readlinkRequest(const readlinkRequest& from); + + inline readlinkRequest& operator=(const readlinkRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const readlinkRequest& default_instance(); + + void Swap(readlinkRequest* other); + + // implements Message ---------------------------------------------- + + readlinkRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const readlinkRequest& from); + void MergeFrom(const readlinkRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.readlinkRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static readlinkRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class readlinkResponse : public ::google::protobuf::Message { + public: + readlinkResponse(); + virtual ~readlinkResponse(); + + readlinkResponse(const readlinkResponse& from); + + inline readlinkResponse& operator=(const readlinkResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const readlinkResponse& default_instance(); + + void Swap(readlinkResponse* other); + + // implements Message ---------------------------------------------- + + readlinkResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const readlinkResponse& from); + void MergeFrom(const readlinkResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string link_target_path = 1; + inline int link_target_path_size() const; + inline void clear_link_target_path(); + static const int kLinkTargetPathFieldNumber = 1; + inline const ::std::string& link_target_path(int index) const; + inline ::std::string* mutable_link_target_path(int index); + inline void set_link_target_path(int index, const ::std::string& value); + inline void set_link_target_path(int index, const char* value); + inline void set_link_target_path(int index, const char* value, size_t size); + inline ::std::string* add_link_target_path(); + inline void add_link_target_path(const ::std::string& value); + inline void add_link_target_path(const char* value); + inline void add_link_target_path(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& link_target_path() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_link_target_path(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.readlinkResponse) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::std::string> link_target_path_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static readlinkResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class removexattrRequest : public ::google::protobuf::Message { + public: + removexattrRequest(); + virtual ~removexattrRequest(); + + removexattrRequest(const removexattrRequest& from); + + inline removexattrRequest& operator=(const removexattrRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const removexattrRequest& default_instance(); + + void Swap(removexattrRequest* other); + + // implements Message ---------------------------------------------- + + removexattrRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const removexattrRequest& from); + void MergeFrom(const removexattrRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // required string name = 3; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 3; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.removexattrRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_name(); + inline void clear_has_name(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + ::std::string* name_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static removexattrRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class renameRequest : public ::google::protobuf::Message { + public: + renameRequest(); + virtual ~renameRequest(); + + renameRequest(const renameRequest& from); + + inline renameRequest& operator=(const renameRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const renameRequest& default_instance(); + + void Swap(renameRequest* other); + + // implements Message ---------------------------------------------- + + renameRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const renameRequest& from); + void MergeFrom(const renameRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string source_path = 2; + inline bool has_source_path() const; + inline void clear_source_path(); + static const int kSourcePathFieldNumber = 2; + inline const ::std::string& source_path() const; + inline void set_source_path(const ::std::string& value); + inline void set_source_path(const char* value); + inline void set_source_path(const char* value, size_t size); + inline ::std::string* mutable_source_path(); + inline ::std::string* release_source_path(); + inline void set_allocated_source_path(::std::string* source_path); + + // required string target_path = 3; + inline bool has_target_path() const; + inline void clear_target_path(); + static const int kTargetPathFieldNumber = 3; + inline const ::std::string& target_path() const; + inline void set_target_path(const ::std::string& value); + inline void set_target_path(const char* value); + inline void set_target_path(const char* value, size_t size); + inline ::std::string* mutable_target_path(); + inline ::std::string* release_target_path(); + inline void set_allocated_target_path(::std::string* target_path); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.renameRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_source_path(); + inline void clear_has_source_path(); + inline void set_has_target_path(); + inline void clear_has_target_path(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* source_path_; + ::std::string* target_path_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static renameRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class renameResponse : public ::google::protobuf::Message { + public: + renameResponse(); + virtual ~renameResponse(); + + renameResponse(const renameResponse& from); + + inline renameResponse& operator=(const renameResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const renameResponse& default_instance(); + + void Swap(renameResponse* other); + + // implements Message ---------------------------------------------- + + renameResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const renameResponse& from); + void MergeFrom(const renameResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed32 timestamp_s = 1; + inline bool has_timestamp_s() const; + inline void clear_timestamp_s(); + static const int kTimestampSFieldNumber = 1; + inline ::google::protobuf::uint32 timestamp_s() const; + inline void set_timestamp_s(::google::protobuf::uint32 value); + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + inline bool has_creds() const; + inline void clear_creds(); + static const int kCredsFieldNumber = 2; + inline const ::xtreemfs::pbrpc::FileCredentials& creds() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_creds(); + inline ::xtreemfs::pbrpc::FileCredentials* release_creds(); + inline void set_allocated_creds(::xtreemfs::pbrpc::FileCredentials* creds); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.renameResponse) + private: + inline void set_has_timestamp_s(); + inline void clear_has_timestamp_s(); + inline void set_has_creds(); + inline void clear_has_creds(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* creds_; + ::google::protobuf::uint32 timestamp_s_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static renameResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class rmdirRequest : public ::google::protobuf::Message { + public: + rmdirRequest(); + virtual ~rmdirRequest(); + + rmdirRequest(const rmdirRequest& from); + + inline rmdirRequest& operator=(const rmdirRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const rmdirRequest& default_instance(); + + void Swap(rmdirRequest* other); + + // implements Message ---------------------------------------------- + + rmdirRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const rmdirRequest& from); + void MergeFrom(const rmdirRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.rmdirRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static rmdirRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class setattrRequest : public ::google::protobuf::Message { + public: + setattrRequest(); + virtual ~setattrRequest(); + + setattrRequest(const setattrRequest& from); + + inline setattrRequest& operator=(const setattrRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const setattrRequest& default_instance(); + + void Swap(setattrRequest* other); + + // implements Message ---------------------------------------------- + + setattrRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const setattrRequest& from); + void MergeFrom(const setattrRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // required .xtreemfs.pbrpc.Stat stbuf = 3; + inline bool has_stbuf() const; + inline void clear_stbuf(); + static const int kStbufFieldNumber = 3; + inline const ::xtreemfs::pbrpc::Stat& stbuf() const; + inline ::xtreemfs::pbrpc::Stat* mutable_stbuf(); + inline ::xtreemfs::pbrpc::Stat* release_stbuf(); + inline void set_allocated_stbuf(::xtreemfs::pbrpc::Stat* stbuf); + + // required fixed32 to_set = 4; + inline bool has_to_set() const; + inline void clear_to_set(); + static const int kToSetFieldNumber = 4; + inline ::google::protobuf::uint32 to_set() const; + inline void set_to_set(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.setattrRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_stbuf(); + inline void clear_has_stbuf(); + inline void set_has_to_set(); + inline void clear_has_to_set(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + ::xtreemfs::pbrpc::Stat* stbuf_; + ::google::protobuf::uint32 to_set_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static setattrRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class setxattrRequest : public ::google::protobuf::Message { + public: + setxattrRequest(); + virtual ~setxattrRequest(); + + setxattrRequest(const setxattrRequest& from); + + inline setxattrRequest& operator=(const setxattrRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const setxattrRequest& default_instance(); + + void Swap(setxattrRequest* other); + + // implements Message ---------------------------------------------- + + setxattrRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const setxattrRequest& from); + void MergeFrom(const setxattrRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // required string name = 3; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 3; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // required string value = 4; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 4; + inline const ::std::string& value() const; + inline void set_value(const ::std::string& value); + inline void set_value(const char* value); + inline void set_value(const char* value, size_t size); + inline ::std::string* mutable_value(); + inline ::std::string* release_value(); + inline void set_allocated_value(::std::string* value); + + // optional bytes value_bytes_string = 6; + inline bool has_value_bytes_string() const; + inline void clear_value_bytes_string(); + static const int kValueBytesStringFieldNumber = 6; + inline const ::std::string& value_bytes_string() const; + inline void set_value_bytes_string(const ::std::string& value); + inline void set_value_bytes_string(const char* value); + inline void set_value_bytes_string(const void* value, size_t size); + inline ::std::string* mutable_value_bytes_string(); + inline ::std::string* release_value_bytes_string(); + inline void set_allocated_value_bytes_string(::std::string* value_bytes_string); + + // required fixed32 flags = 5; + inline bool has_flags() const; + inline void clear_flags(); + static const int kFlagsFieldNumber = 5; + inline ::google::protobuf::uint32 flags() const; + inline void set_flags(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.setxattrRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_value(); + inline void clear_has_value(); + inline void set_has_value_bytes_string(); + inline void clear_has_value_bytes_string(); + inline void set_has_flags(); + inline void clear_has_flags(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + ::std::string* name_; + ::std::string* value_; + ::std::string* value_bytes_string_; + ::google::protobuf::uint32 flags_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static setxattrRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class statvfsRequest : public ::google::protobuf::Message { + public: + statvfsRequest(); + virtual ~statvfsRequest(); + + statvfsRequest(const statvfsRequest& from); + + inline statvfsRequest& operator=(const statvfsRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const statvfsRequest& default_instance(); + + void Swap(statvfsRequest* other); + + // implements Message ---------------------------------------------- + + statvfsRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const statvfsRequest& from); + void MergeFrom(const statvfsRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required fixed64 known_etag = 5; + inline bool has_known_etag() const; + inline void clear_known_etag(); + static const int kKnownEtagFieldNumber = 5; + inline ::google::protobuf::uint64 known_etag() const; + inline void set_known_etag(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.statvfsRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_known_etag(); + inline void clear_has_known_etag(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::google::protobuf::uint64 known_etag_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static statvfsRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class symlinkRequest : public ::google::protobuf::Message { + public: + symlinkRequest(); + virtual ~symlinkRequest(); + + symlinkRequest(const symlinkRequest& from); + + inline symlinkRequest& operator=(const symlinkRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const symlinkRequest& default_instance(); + + void Swap(symlinkRequest* other); + + // implements Message ---------------------------------------------- + + symlinkRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const symlinkRequest& from); + void MergeFrom(const symlinkRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string target_path = 2; + inline bool has_target_path() const; + inline void clear_target_path(); + static const int kTargetPathFieldNumber = 2; + inline const ::std::string& target_path() const; + inline void set_target_path(const ::std::string& value); + inline void set_target_path(const char* value); + inline void set_target_path(const char* value, size_t size); + inline ::std::string* mutable_target_path(); + inline ::std::string* release_target_path(); + inline void set_allocated_target_path(::std::string* target_path); + + // required string link_path = 3; + inline bool has_link_path() const; + inline void clear_link_path(); + static const int kLinkPathFieldNumber = 3; + inline const ::std::string& link_path() const; + inline void set_link_path(const ::std::string& value); + inline void set_link_path(const char* value); + inline void set_link_path(const char* value, size_t size); + inline ::std::string* mutable_link_path(); + inline ::std::string* release_link_path(); + inline void set_allocated_link_path(::std::string* link_path); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.symlinkRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_target_path(); + inline void clear_has_target_path(); + inline void set_has_link_path(); + inline void clear_has_link_path(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* target_path_; + ::std::string* link_path_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static symlinkRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class unlinkRequest : public ::google::protobuf::Message { + public: + unlinkRequest(); + virtual ~unlinkRequest(); + + unlinkRequest(const unlinkRequest& from); + + inline unlinkRequest& operator=(const unlinkRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const unlinkRequest& default_instance(); + + void Swap(unlinkRequest* other); + + // implements Message ---------------------------------------------- + + unlinkRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const unlinkRequest& from); + void MergeFrom(const unlinkRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.unlinkRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static unlinkRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class unlinkResponse : public ::google::protobuf::Message { + public: + unlinkResponse(); + virtual ~unlinkResponse(); + + unlinkResponse(const unlinkResponse& from); + + inline unlinkResponse& operator=(const unlinkResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const unlinkResponse& default_instance(); + + void Swap(unlinkResponse* other); + + // implements Message ---------------------------------------------- + + unlinkResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const unlinkResponse& from); + void MergeFrom(const unlinkResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed32 timestamp_s = 1; + inline bool has_timestamp_s() const; + inline void clear_timestamp_s(); + static const int kTimestampSFieldNumber = 1; + inline ::google::protobuf::uint32 timestamp_s() const; + inline void set_timestamp_s(::google::protobuf::uint32 value); + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + inline bool has_creds() const; + inline void clear_creds(); + static const int kCredsFieldNumber = 2; + inline const ::xtreemfs::pbrpc::FileCredentials& creds() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_creds(); + inline ::xtreemfs::pbrpc::FileCredentials* release_creds(); + inline void set_allocated_creds(::xtreemfs::pbrpc::FileCredentials* creds); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.unlinkResponse) + private: + inline void set_has_timestamp_s(); + inline void clear_has_timestamp_s(); + inline void set_has_creds(); + inline void clear_has_creds(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* creds_; + ::google::protobuf::uint32 timestamp_s_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static unlinkResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class accessRequest : public ::google::protobuf::Message { + public: + accessRequest(); + virtual ~accessRequest(); + + accessRequest(const accessRequest& from); + + inline accessRequest& operator=(const accessRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const accessRequest& default_instance(); + + void Swap(accessRequest* other); + + // implements Message ---------------------------------------------- + + accessRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const accessRequest& from); + void MergeFrom(const accessRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // required fixed32 flags = 3; + inline bool has_flags() const; + inline void clear_flags(); + static const int kFlagsFieldNumber = 3; + inline ::google::protobuf::uint32 flags() const; + inline void set_flags(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.accessRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_flags(); + inline void clear_has_flags(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + ::std::string* path_; + ::google::protobuf::uint32 flags_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static accessRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_check_file_existsRequest : public ::google::protobuf::Message { + public: + xtreemfs_check_file_existsRequest(); + virtual ~xtreemfs_check_file_existsRequest(); + + xtreemfs_check_file_existsRequest(const xtreemfs_check_file_existsRequest& from); + + inline xtreemfs_check_file_existsRequest& operator=(const xtreemfs_check_file_existsRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_check_file_existsRequest& default_instance(); + + void Swap(xtreemfs_check_file_existsRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_check_file_existsRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_check_file_existsRequest& from); + void MergeFrom(const xtreemfs_check_file_existsRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_id = 1; + inline bool has_volume_id() const; + inline void clear_volume_id(); + static const int kVolumeIdFieldNumber = 1; + inline const ::std::string& volume_id() const; + inline void set_volume_id(const ::std::string& value); + inline void set_volume_id(const char* value); + inline void set_volume_id(const char* value, size_t size); + inline ::std::string* mutable_volume_id(); + inline ::std::string* release_volume_id(); + inline void set_allocated_volume_id(::std::string* volume_id); + + // repeated string file_ids = 2; + inline int file_ids_size() const; + inline void clear_file_ids(); + static const int kFileIdsFieldNumber = 2; + inline const ::std::string& file_ids(int index) const; + inline ::std::string* mutable_file_ids(int index); + inline void set_file_ids(int index, const ::std::string& value); + inline void set_file_ids(int index, const char* value); + inline void set_file_ids(int index, const char* value, size_t size); + inline ::std::string* add_file_ids(); + inline void add_file_ids(const ::std::string& value); + inline void add_file_ids(const char* value); + inline void add_file_ids(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& file_ids() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_ids(); + + // required string osd_uuid = 3; + inline bool has_osd_uuid() const; + inline void clear_osd_uuid(); + static const int kOsdUuidFieldNumber = 3; + inline const ::std::string& osd_uuid() const; + inline void set_osd_uuid(const ::std::string& value); + inline void set_osd_uuid(const char* value); + inline void set_osd_uuid(const char* value, size_t size); + inline ::std::string* mutable_osd_uuid(); + inline ::std::string* release_osd_uuid(); + inline void set_allocated_osd_uuid(::std::string* osd_uuid); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_check_file_existsRequest) + private: + inline void set_has_volume_id(); + inline void clear_has_volume_id(); + inline void set_has_osd_uuid(); + inline void clear_has_osd_uuid(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_id_; + ::google::protobuf::RepeatedPtrField< ::std::string> file_ids_; + ::std::string* osd_uuid_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_check_file_existsRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_check_file_existsResponse : public ::google::protobuf::Message { + public: + xtreemfs_check_file_existsResponse(); + virtual ~xtreemfs_check_file_existsResponse(); + + xtreemfs_check_file_existsResponse(const xtreemfs_check_file_existsResponse& from); + + inline xtreemfs_check_file_existsResponse& operator=(const xtreemfs_check_file_existsResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_check_file_existsResponse& default_instance(); + + void Swap(xtreemfs_check_file_existsResponse* other); + + // implements Message ---------------------------------------------- + + xtreemfs_check_file_existsResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_check_file_existsResponse& from); + void MergeFrom(const xtreemfs_check_file_existsResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef xtreemfs_check_file_existsResponse_FILE_STATE FILE_STATE; + static const FILE_STATE DELETED = xtreemfs_check_file_existsResponse_FILE_STATE_DELETED; + static const FILE_STATE REGISTERED = xtreemfs_check_file_existsResponse_FILE_STATE_REGISTERED; + static const FILE_STATE ABANDONED = xtreemfs_check_file_existsResponse_FILE_STATE_ABANDONED; + static inline bool FILE_STATE_IsValid(int value) { + return xtreemfs_check_file_existsResponse_FILE_STATE_IsValid(value); + } + static const FILE_STATE FILE_STATE_MIN = + xtreemfs_check_file_existsResponse_FILE_STATE_FILE_STATE_MIN; + static const FILE_STATE FILE_STATE_MAX = + xtreemfs_check_file_existsResponse_FILE_STATE_FILE_STATE_MAX; + static const int FILE_STATE_ARRAYSIZE = + xtreemfs_check_file_existsResponse_FILE_STATE_FILE_STATE_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + FILE_STATE_descriptor() { + return xtreemfs_check_file_existsResponse_FILE_STATE_descriptor(); + } + static inline const ::std::string& FILE_STATE_Name(FILE_STATE value) { + return xtreemfs_check_file_existsResponse_FILE_STATE_Name(value); + } + static inline bool FILE_STATE_Parse(const ::std::string& name, + FILE_STATE* value) { + return xtreemfs_check_file_existsResponse_FILE_STATE_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required bool volume_exists = 1; + inline bool has_volume_exists() const; + inline void clear_volume_exists(); + static const int kVolumeExistsFieldNumber = 1; + inline bool volume_exists() const; + inline void set_volume_exists(bool value); + + // repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + inline int file_states_size() const; + inline void clear_file_states(); + static const int kFileStatesFieldNumber = 2; + inline ::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE file_states(int index) const; + inline void set_file_states(int index, ::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE value); + inline void add_file_states(::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE value); + inline const ::google::protobuf::RepeatedField& file_states() const; + inline ::google::protobuf::RepeatedField* mutable_file_states(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_check_file_existsResponse) + private: + inline void set_has_volume_exists(); + inline void clear_has_volume_exists(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedField file_states_; + mutable int _file_states_cached_byte_size_; + bool volume_exists_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_check_file_existsResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_dump_restore_databaseRequest : public ::google::protobuf::Message { + public: + xtreemfs_dump_restore_databaseRequest(); + virtual ~xtreemfs_dump_restore_databaseRequest(); + + xtreemfs_dump_restore_databaseRequest(const xtreemfs_dump_restore_databaseRequest& from); + + inline xtreemfs_dump_restore_databaseRequest& operator=(const xtreemfs_dump_restore_databaseRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_dump_restore_databaseRequest& default_instance(); + + void Swap(xtreemfs_dump_restore_databaseRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_dump_restore_databaseRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_dump_restore_databaseRequest& from); + void MergeFrom(const xtreemfs_dump_restore_databaseRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string dump_file = 1; + inline bool has_dump_file() const; + inline void clear_dump_file(); + static const int kDumpFileFieldNumber = 1; + inline const ::std::string& dump_file() const; + inline void set_dump_file(const ::std::string& value); + inline void set_dump_file(const char* value); + inline void set_dump_file(const char* value, size_t size); + inline ::std::string* mutable_dump_file(); + inline ::std::string* release_dump_file(); + inline void set_allocated_dump_file(::std::string* dump_file); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_dump_restore_databaseRequest) + private: + inline void set_has_dump_file(); + inline void clear_has_dump_file(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* dump_file_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_dump_restore_databaseRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_get_suitable_osdsRequest : public ::google::protobuf::Message { + public: + xtreemfs_get_suitable_osdsRequest(); + virtual ~xtreemfs_get_suitable_osdsRequest(); + + xtreemfs_get_suitable_osdsRequest(const xtreemfs_get_suitable_osdsRequest& from); + + inline xtreemfs_get_suitable_osdsRequest& operator=(const xtreemfs_get_suitable_osdsRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_get_suitable_osdsRequest& default_instance(); + + void Swap(xtreemfs_get_suitable_osdsRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_get_suitable_osdsRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_get_suitable_osdsRequest& from); + void MergeFrom(const xtreemfs_get_suitable_osdsRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string file_id = 1; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 1; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // optional string path = 3; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 3; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // optional string volume_name = 4; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 4; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required fixed32 num_osds = 2; + inline bool has_num_osds() const; + inline void clear_num_osds(); + static const int kNumOsdsFieldNumber = 2; + inline ::google::protobuf::uint32 num_osds() const; + inline void set_num_osds(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_get_suitable_osdsRequest) + private: + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_num_osds(); + inline void clear_has_num_osds(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* file_id_; + ::std::string* path_; + ::std::string* volume_name_; + ::google::protobuf::uint32 num_osds_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_get_suitable_osdsRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_get_suitable_osdsResponse : public ::google::protobuf::Message { + public: + xtreemfs_get_suitable_osdsResponse(); + virtual ~xtreemfs_get_suitable_osdsResponse(); + + xtreemfs_get_suitable_osdsResponse(const xtreemfs_get_suitable_osdsResponse& from); + + inline xtreemfs_get_suitable_osdsResponse& operator=(const xtreemfs_get_suitable_osdsResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_get_suitable_osdsResponse& default_instance(); + + void Swap(xtreemfs_get_suitable_osdsResponse* other); + + // implements Message ---------------------------------------------- + + xtreemfs_get_suitable_osdsResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_get_suitable_osdsResponse& from); + void MergeFrom(const xtreemfs_get_suitable_osdsResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string osd_uuids = 1; + inline int osd_uuids_size() const; + inline void clear_osd_uuids(); + static const int kOsdUuidsFieldNumber = 1; + inline const ::std::string& osd_uuids(int index) const; + inline ::std::string* mutable_osd_uuids(int index); + inline void set_osd_uuids(int index, const ::std::string& value); + inline void set_osd_uuids(int index, const char* value); + inline void set_osd_uuids(int index, const char* value, size_t size); + inline ::std::string* add_osd_uuids(); + inline void add_osd_uuids(const ::std::string& value); + inline void add_osd_uuids(const char* value); + inline void add_osd_uuids(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& osd_uuids() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_osd_uuids(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_get_suitable_osdsResponse) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::std::string> osd_uuids_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_get_suitable_osdsResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class timestampResponse : public ::google::protobuf::Message { + public: + timestampResponse(); + virtual ~timestampResponse(); + + timestampResponse(const timestampResponse& from); + + inline timestampResponse& operator=(const timestampResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const timestampResponse& default_instance(); + + void Swap(timestampResponse* other); + + // implements Message ---------------------------------------------- + + timestampResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const timestampResponse& from); + void MergeFrom(const timestampResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed32 timestamp_s = 1; + inline bool has_timestamp_s() const; + inline void clear_timestamp_s(); + static const int kTimestampSFieldNumber = 1; + inline ::google::protobuf::uint32 timestamp_s() const; + inline void set_timestamp_s(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.timestampResponse) + private: + inline void set_has_timestamp_s(); + inline void clear_has_timestamp_s(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 timestamp_s_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static timestampResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class stringMessage : public ::google::protobuf::Message { + public: + stringMessage(); + virtual ~stringMessage(); + + stringMessage(const stringMessage& from); + + inline stringMessage& operator=(const stringMessage& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const stringMessage& default_instance(); + + void Swap(stringMessage* other); + + // implements Message ---------------------------------------------- + + stringMessage* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const stringMessage& from); + void MergeFrom(const stringMessage& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string a_string = 1; + inline bool has_a_string() const; + inline void clear_a_string(); + static const int kAStringFieldNumber = 1; + inline const ::std::string& a_string() const; + inline void set_a_string(const ::std::string& value); + inline void set_a_string(const char* value); + inline void set_a_string(const char* value, size_t size); + inline ::std::string* mutable_a_string(); + inline ::std::string* release_a_string(); + inline void set_allocated_a_string(::std::string* a_string); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.stringMessage) + private: + inline void set_has_a_string(); + inline void clear_has_a_string(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* a_string_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static stringMessage* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_listdirRequest : public ::google::protobuf::Message { + public: + xtreemfs_listdirRequest(); + virtual ~xtreemfs_listdirRequest(); + + xtreemfs_listdirRequest(const xtreemfs_listdirRequest& from); + + inline xtreemfs_listdirRequest& operator=(const xtreemfs_listdirRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_listdirRequest& default_instance(); + + void Swap(xtreemfs_listdirRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_listdirRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_listdirRequest& from); + void MergeFrom(const xtreemfs_listdirRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string path = 1; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 1; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_listdirRequest) + private: + inline void set_has_path(); + inline void clear_has_path(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* path_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_listdirRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_listdirResponse : public ::google::protobuf::Message { + public: + xtreemfs_listdirResponse(); + virtual ~xtreemfs_listdirResponse(); + + xtreemfs_listdirResponse(const xtreemfs_listdirResponse& from); + + inline xtreemfs_listdirResponse& operator=(const xtreemfs_listdirResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_listdirResponse& default_instance(); + + void Swap(xtreemfs_listdirResponse* other); + + // implements Message ---------------------------------------------- + + xtreemfs_listdirResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_listdirResponse& from); + void MergeFrom(const xtreemfs_listdirResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string names = 1; + inline int names_size() const; + inline void clear_names(); + static const int kNamesFieldNumber = 1; + inline const ::std::string& names(int index) const; + inline ::std::string* mutable_names(int index); + inline void set_names(int index, const ::std::string& value); + inline void set_names(int index, const char* value); + inline void set_names(int index, const char* value, size_t size); + inline ::std::string* add_names(); + inline void add_names(const ::std::string& value); + inline void add_names(const char* value); + inline void add_names(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& names() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_names(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_listdirResponse) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::std::string> names_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_listdirResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_replica_addRequest : public ::google::protobuf::Message { + public: + xtreemfs_replica_addRequest(); + virtual ~xtreemfs_replica_addRequest(); + + xtreemfs_replica_addRequest(const xtreemfs_replica_addRequest& from); + + inline xtreemfs_replica_addRequest& operator=(const xtreemfs_replica_addRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_replica_addRequest& default_instance(); + + void Swap(xtreemfs_replica_addRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_replica_addRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_replica_addRequest& from); + void MergeFrom(const xtreemfs_replica_addRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string file_id = 1; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 1; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // optional string path = 3; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 3; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // optional string volume_name = 4; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 4; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required .xtreemfs.pbrpc.Replica new_replica = 2; + inline bool has_new_replica() const; + inline void clear_new_replica(); + static const int kNewReplicaFieldNumber = 2; + inline const ::xtreemfs::pbrpc::Replica& new_replica() const; + inline ::xtreemfs::pbrpc::Replica* mutable_new_replica(); + inline ::xtreemfs::pbrpc::Replica* release_new_replica(); + inline void set_allocated_new_replica(::xtreemfs::pbrpc::Replica* new_replica); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_replica_addRequest) + private: + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_new_replica(); + inline void clear_has_new_replica(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* file_id_; + ::std::string* path_; + ::std::string* volume_name_; + ::xtreemfs::pbrpc::Replica* new_replica_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_replica_addRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_replica_listRequest : public ::google::protobuf::Message { + public: + xtreemfs_replica_listRequest(); + virtual ~xtreemfs_replica_listRequest(); + + xtreemfs_replica_listRequest(const xtreemfs_replica_listRequest& from); + + inline xtreemfs_replica_listRequest& operator=(const xtreemfs_replica_listRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_replica_listRequest& default_instance(); + + void Swap(xtreemfs_replica_listRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_replica_listRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_replica_listRequest& from); + void MergeFrom(const xtreemfs_replica_listRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string file_id = 1; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 1; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // optional string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // optional string volume_name = 3; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 3; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_replica_listRequest) + private: + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* file_id_; + ::std::string* path_; + ::std::string* volume_name_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_replica_listRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_get_xlocsetRequest : public ::google::protobuf::Message { + public: + xtreemfs_get_xlocsetRequest(); + virtual ~xtreemfs_get_xlocsetRequest(); + + xtreemfs_get_xlocsetRequest(const xtreemfs_get_xlocsetRequest& from); + + inline xtreemfs_get_xlocsetRequest& operator=(const xtreemfs_get_xlocsetRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_get_xlocsetRequest& default_instance(); + + void Swap(xtreemfs_get_xlocsetRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_get_xlocsetRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_get_xlocsetRequest& from); + void MergeFrom(const xtreemfs_get_xlocsetRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string file_id = 1; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 1; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // optional string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // optional string volume_name = 3; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 3; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // optional .xtreemfs.pbrpc.XCap xcap = 4; + inline bool has_xcap() const; + inline void clear_xcap(); + static const int kXcapFieldNumber = 4; + inline const ::xtreemfs::pbrpc::XCap& xcap() const; + inline ::xtreemfs::pbrpc::XCap* mutable_xcap(); + inline ::xtreemfs::pbrpc::XCap* release_xcap(); + inline void set_allocated_xcap(::xtreemfs::pbrpc::XCap* xcap); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_get_xlocsetRequest) + private: + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_xcap(); + inline void clear_has_xcap(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* file_id_; + ::std::string* path_; + ::std::string* volume_name_; + ::xtreemfs::pbrpc::XCap* xcap_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_get_xlocsetRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_replica_removeRequest : public ::google::protobuf::Message { + public: + xtreemfs_replica_removeRequest(); + virtual ~xtreemfs_replica_removeRequest(); + + xtreemfs_replica_removeRequest(const xtreemfs_replica_removeRequest& from); + + inline xtreemfs_replica_removeRequest& operator=(const xtreemfs_replica_removeRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_replica_removeRequest& default_instance(); + + void Swap(xtreemfs_replica_removeRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_replica_removeRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_replica_removeRequest& from); + void MergeFrom(const xtreemfs_replica_removeRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string file_id = 1; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 1; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // optional string path = 3; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 3; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + inline void set_allocated_path(::std::string* path); + + // optional string volume_name = 4; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 4; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // required string osd_uuid = 2; + inline bool has_osd_uuid() const; + inline void clear_osd_uuid(); + static const int kOsdUuidFieldNumber = 2; + inline const ::std::string& osd_uuid() const; + inline void set_osd_uuid(const ::std::string& value); + inline void set_osd_uuid(const char* value); + inline void set_osd_uuid(const char* value, size_t size); + inline ::std::string* mutable_osd_uuid(); + inline ::std::string* release_osd_uuid(); + inline void set_allocated_osd_uuid(::std::string* osd_uuid); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_replica_removeRequest) + private: + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + inline void set_has_osd_uuid(); + inline void clear_has_osd_uuid(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* file_id_; + ::std::string* path_; + ::std::string* volume_name_; + ::std::string* osd_uuid_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_replica_removeRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_restore_fileRequest : public ::google::protobuf::Message { + public: + xtreemfs_restore_fileRequest(); + virtual ~xtreemfs_restore_fileRequest(); + + xtreemfs_restore_fileRequest(const xtreemfs_restore_fileRequest& from); + + inline xtreemfs_restore_fileRequest& operator=(const xtreemfs_restore_fileRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_restore_fileRequest& default_instance(); + + void Swap(xtreemfs_restore_fileRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_restore_fileRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_restore_fileRequest& from); + void MergeFrom(const xtreemfs_restore_fileRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string file_path = 1; + inline bool has_file_path() const; + inline void clear_file_path(); + static const int kFilePathFieldNumber = 1; + inline const ::std::string& file_path() const; + inline void set_file_path(const ::std::string& value); + inline void set_file_path(const char* value); + inline void set_file_path(const char* value, size_t size); + inline ::std::string* mutable_file_path(); + inline ::std::string* release_file_path(); + inline void set_allocated_file_path(::std::string* file_path); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 file_size = 3; + inline bool has_file_size() const; + inline void clear_file_size(); + static const int kFileSizeFieldNumber = 3; + inline ::google::protobuf::uint64 file_size() const; + inline void set_file_size(::google::protobuf::uint64 value); + + // required string osd_uuid = 4; + inline bool has_osd_uuid() const; + inline void clear_osd_uuid(); + static const int kOsdUuidFieldNumber = 4; + inline const ::std::string& osd_uuid() const; + inline void set_osd_uuid(const ::std::string& value); + inline void set_osd_uuid(const char* value); + inline void set_osd_uuid(const char* value, size_t size); + inline ::std::string* mutable_osd_uuid(); + inline ::std::string* release_osd_uuid(); + inline void set_allocated_osd_uuid(::std::string* osd_uuid); + + // required fixed32 stripe_size = 5; + inline bool has_stripe_size() const; + inline void clear_stripe_size(); + static const int kStripeSizeFieldNumber = 5; + inline ::google::protobuf::uint32 stripe_size() const; + inline void set_stripe_size(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_restore_fileRequest) + private: + inline void set_has_file_path(); + inline void clear_has_file_path(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_file_size(); + inline void clear_has_file_size(); + inline void set_has_osd_uuid(); + inline void clear_has_osd_uuid(); + inline void set_has_stripe_size(); + inline void clear_has_stripe_size(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* file_path_; + ::std::string* file_id_; + ::google::protobuf::uint64 file_size_; + ::std::string* osd_uuid_; + ::google::protobuf::uint32 stripe_size_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_restore_fileRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_rmvolRequest : public ::google::protobuf::Message { + public: + xtreemfs_rmvolRequest(); + virtual ~xtreemfs_rmvolRequest(); + + xtreemfs_rmvolRequest(const xtreemfs_rmvolRequest& from); + + inline xtreemfs_rmvolRequest& operator=(const xtreemfs_rmvolRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_rmvolRequest& default_instance(); + + void Swap(xtreemfs_rmvolRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_rmvolRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_rmvolRequest& from); + void MergeFrom(const xtreemfs_rmvolRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string volume_name = 1; + inline bool has_volume_name() const; + inline void clear_volume_name(); + static const int kVolumeNameFieldNumber = 1; + inline const ::std::string& volume_name() const; + inline void set_volume_name(const ::std::string& value); + inline void set_volume_name(const char* value); + inline void set_volume_name(const char* value, size_t size); + inline ::std::string* mutable_volume_name(); + inline ::std::string* release_volume_name(); + inline void set_allocated_volume_name(::std::string* volume_name); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rmvolRequest) + private: + inline void set_has_volume_name(); + inline void clear_has_volume_name(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* volume_name_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_rmvolRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_update_file_sizeRequest : public ::google::protobuf::Message { + public: + xtreemfs_update_file_sizeRequest(); + virtual ~xtreemfs_update_file_sizeRequest(); + + xtreemfs_update_file_sizeRequest(const xtreemfs_update_file_sizeRequest& from); + + inline xtreemfs_update_file_sizeRequest& operator=(const xtreemfs_update_file_sizeRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_update_file_sizeRequest& default_instance(); + + void Swap(xtreemfs_update_file_sizeRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_update_file_sizeRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_update_file_sizeRequest& from); + void MergeFrom(const xtreemfs_update_file_sizeRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.XCap xcap = 1; + inline bool has_xcap() const; + inline void clear_xcap(); + static const int kXcapFieldNumber = 1; + inline const ::xtreemfs::pbrpc::XCap& xcap() const; + inline ::xtreemfs::pbrpc::XCap* mutable_xcap(); + inline ::xtreemfs::pbrpc::XCap* release_xcap(); + inline void set_allocated_xcap(::xtreemfs::pbrpc::XCap* xcap); + + // required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + inline bool has_osd_write_response() const; + inline void clear_osd_write_response(); + static const int kOsdWriteResponseFieldNumber = 2; + inline const ::xtreemfs::pbrpc::OSDWriteResponse& osd_write_response() const; + inline ::xtreemfs::pbrpc::OSDWriteResponse* mutable_osd_write_response(); + inline ::xtreemfs::pbrpc::OSDWriteResponse* release_osd_write_response(); + inline void set_allocated_osd_write_response(::xtreemfs::pbrpc::OSDWriteResponse* osd_write_response); + + // optional bool close_file = 3; + inline bool has_close_file() const; + inline void clear_close_file(); + static const int kCloseFileFieldNumber = 3; + inline bool close_file() const; + inline void set_close_file(bool value); + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + inline bool has_coordinates() const; + inline void clear_coordinates(); + static const int kCoordinatesFieldNumber = 4; + inline const ::xtreemfs::pbrpc::VivaldiCoordinates& coordinates() const; + inline ::xtreemfs::pbrpc::VivaldiCoordinates* mutable_coordinates(); + inline ::xtreemfs::pbrpc::VivaldiCoordinates* release_coordinates(); + inline void set_allocated_coordinates(::xtreemfs::pbrpc::VivaldiCoordinates* coordinates); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_update_file_sizeRequest) + private: + inline void set_has_xcap(); + inline void clear_has_xcap(); + inline void set_has_osd_write_response(); + inline void clear_has_osd_write_response(); + inline void set_has_close_file(); + inline void clear_has_close_file(); + inline void set_has_coordinates(); + inline void clear_has_coordinates(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::XCap* xcap_; + ::xtreemfs::pbrpc::OSDWriteResponse* osd_write_response_; + ::xtreemfs::pbrpc::VivaldiCoordinates* coordinates_; + bool close_file_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_update_file_sizeRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_set_replica_update_policyRequest : public ::google::protobuf::Message { + public: + xtreemfs_set_replica_update_policyRequest(); + virtual ~xtreemfs_set_replica_update_policyRequest(); + + xtreemfs_set_replica_update_policyRequest(const xtreemfs_set_replica_update_policyRequest& from); + + inline xtreemfs_set_replica_update_policyRequest& operator=(const xtreemfs_set_replica_update_policyRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_set_replica_update_policyRequest& default_instance(); + + void Swap(xtreemfs_set_replica_update_policyRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_set_replica_update_policyRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_set_replica_update_policyRequest& from); + void MergeFrom(const xtreemfs_set_replica_update_policyRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string file_id = 1; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 1; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required string update_policy = 2; + inline bool has_update_policy() const; + inline void clear_update_policy(); + static const int kUpdatePolicyFieldNumber = 2; + inline const ::std::string& update_policy() const; + inline void set_update_policy(const ::std::string& value); + inline void set_update_policy(const char* value); + inline void set_update_policy(const char* value, size_t size); + inline ::std::string* mutable_update_policy(); + inline ::std::string* release_update_policy(); + inline void set_allocated_update_policy(::std::string* update_policy); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_set_replica_update_policyRequest) + private: + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_update_policy(); + inline void clear_has_update_policy(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* file_id_; + ::std::string* update_policy_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_set_replica_update_policyRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_set_replica_update_policyResponse : public ::google::protobuf::Message { + public: + xtreemfs_set_replica_update_policyResponse(); + virtual ~xtreemfs_set_replica_update_policyResponse(); + + xtreemfs_set_replica_update_policyResponse(const xtreemfs_set_replica_update_policyResponse& from); + + inline xtreemfs_set_replica_update_policyResponse& operator=(const xtreemfs_set_replica_update_policyResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_set_replica_update_policyResponse& default_instance(); + + void Swap(xtreemfs_set_replica_update_policyResponse* other); + + // implements Message ---------------------------------------------- + + xtreemfs_set_replica_update_policyResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_set_replica_update_policyResponse& from); + void MergeFrom(const xtreemfs_set_replica_update_policyResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string old_update_policy = 1; + inline bool has_old_update_policy() const; + inline void clear_old_update_policy(); + static const int kOldUpdatePolicyFieldNumber = 1; + inline const ::std::string& old_update_policy() const; + inline void set_old_update_policy(const ::std::string& value); + inline void set_old_update_policy(const char* value); + inline void set_old_update_policy(const char* value, size_t size); + inline ::std::string* mutable_old_update_policy(); + inline ::std::string* release_old_update_policy(); + inline void set_allocated_old_update_policy(::std::string* old_update_policy); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_set_replica_update_policyResponse) + private: + inline void set_has_old_update_policy(); + inline void clear_has_old_update_policy(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* old_update_policy_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_set_replica_update_policyResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_set_read_only_xattrRequest : public ::google::protobuf::Message { + public: + xtreemfs_set_read_only_xattrRequest(); + virtual ~xtreemfs_set_read_only_xattrRequest(); + + xtreemfs_set_read_only_xattrRequest(const xtreemfs_set_read_only_xattrRequest& from); + + inline xtreemfs_set_read_only_xattrRequest& operator=(const xtreemfs_set_read_only_xattrRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_set_read_only_xattrRequest& default_instance(); + + void Swap(xtreemfs_set_read_only_xattrRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_set_read_only_xattrRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_set_read_only_xattrRequest& from); + void MergeFrom(const xtreemfs_set_read_only_xattrRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string file_id = 1; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 1; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required bool value = 2; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 2; + inline bool value() const; + inline void set_value(bool value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_set_read_only_xattrRequest) + private: + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_value(); + inline void clear_has_value(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* file_id_; + bool value_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_set_read_only_xattrRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_set_read_only_xattrResponse : public ::google::protobuf::Message { + public: + xtreemfs_set_read_only_xattrResponse(); + virtual ~xtreemfs_set_read_only_xattrResponse(); + + xtreemfs_set_read_only_xattrResponse(const xtreemfs_set_read_only_xattrResponse& from); + + inline xtreemfs_set_read_only_xattrResponse& operator=(const xtreemfs_set_read_only_xattrResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_set_read_only_xattrResponse& default_instance(); + + void Swap(xtreemfs_set_read_only_xattrResponse* other); + + // implements Message ---------------------------------------------- + + xtreemfs_set_read_only_xattrResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_set_read_only_xattrResponse& from); + void MergeFrom(const xtreemfs_set_read_only_xattrResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required bool was_set = 1; + inline bool has_was_set() const; + inline void clear_was_set(); + static const int kWasSetFieldNumber = 1; + inline bool was_set() const; + inline void set_was_set(bool value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_set_read_only_xattrResponse) + private: + inline void set_has_was_set(); + inline void clear_has_was_set(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + bool was_set_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_set_read_only_xattrResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_get_file_credentialsRequest : public ::google::protobuf::Message { + public: + xtreemfs_get_file_credentialsRequest(); + virtual ~xtreemfs_get_file_credentialsRequest(); + + xtreemfs_get_file_credentialsRequest(const xtreemfs_get_file_credentialsRequest& from); + + inline xtreemfs_get_file_credentialsRequest& operator=(const xtreemfs_get_file_credentialsRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_get_file_credentialsRequest& default_instance(); + + void Swap(xtreemfs_get_file_credentialsRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_get_file_credentialsRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_get_file_credentialsRequest& from); + void MergeFrom(const xtreemfs_get_file_credentialsRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string file_id = 1; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 1; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_get_file_credentialsRequest) + private: + inline void set_has_file_id(); + inline void clear_has_file_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* file_id_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fMRC_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fMRC_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_get_file_credentialsRequest* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// Stat + +// required fixed64 dev = 1; +inline bool Stat::has_dev() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Stat::set_has_dev() { + _has_bits_[0] |= 0x00000001u; +} +inline void Stat::clear_has_dev() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Stat::clear_dev() { + dev_ = GOOGLE_ULONGLONG(0); + clear_has_dev(); +} +inline ::google::protobuf::uint64 Stat::dev() const { + return dev_; +} +inline void Stat::set_dev(::google::protobuf::uint64 value) { + set_has_dev(); + dev_ = value; +} + +// required fixed64 ino = 2; +inline bool Stat::has_ino() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Stat::set_has_ino() { + _has_bits_[0] |= 0x00000002u; +} +inline void Stat::clear_has_ino() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Stat::clear_ino() { + ino_ = GOOGLE_ULONGLONG(0); + clear_has_ino(); +} +inline ::google::protobuf::uint64 Stat::ino() const { + return ino_; +} +inline void Stat::set_ino(::google::protobuf::uint64 value) { + set_has_ino(); + ino_ = value; +} + +// required fixed32 mode = 3; +inline bool Stat::has_mode() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Stat::set_has_mode() { + _has_bits_[0] |= 0x00000004u; +} +inline void Stat::clear_has_mode() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Stat::clear_mode() { + mode_ = 0u; + clear_has_mode(); +} +inline ::google::protobuf::uint32 Stat::mode() const { + return mode_; +} +inline void Stat::set_mode(::google::protobuf::uint32 value) { + set_has_mode(); + mode_ = value; +} + +// required fixed32 nlink = 4; +inline bool Stat::has_nlink() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void Stat::set_has_nlink() { + _has_bits_[0] |= 0x00000008u; +} +inline void Stat::clear_has_nlink() { + _has_bits_[0] &= ~0x00000008u; +} +inline void Stat::clear_nlink() { + nlink_ = 0u; + clear_has_nlink(); +} +inline ::google::protobuf::uint32 Stat::nlink() const { + return nlink_; +} +inline void Stat::set_nlink(::google::protobuf::uint32 value) { + set_has_nlink(); + nlink_ = value; +} + +// required string user_id = 5; +inline bool Stat::has_user_id() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void Stat::set_has_user_id() { + _has_bits_[0] |= 0x00000010u; +} +inline void Stat::clear_has_user_id() { + _has_bits_[0] &= ~0x00000010u; +} +inline void Stat::clear_user_id() { + if (user_id_ != &::google::protobuf::internal::kEmptyString) { + user_id_->clear(); + } + clear_has_user_id(); +} +inline const ::std::string& Stat::user_id() const { + return *user_id_; +} +inline void Stat::set_user_id(const ::std::string& value) { + set_has_user_id(); + if (user_id_ == &::google::protobuf::internal::kEmptyString) { + user_id_ = new ::std::string; + } + user_id_->assign(value); +} +inline void Stat::set_user_id(const char* value) { + set_has_user_id(); + if (user_id_ == &::google::protobuf::internal::kEmptyString) { + user_id_ = new ::std::string; + } + user_id_->assign(value); +} +inline void Stat::set_user_id(const char* value, size_t size) { + set_has_user_id(); + if (user_id_ == &::google::protobuf::internal::kEmptyString) { + user_id_ = new ::std::string; + } + user_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Stat::mutable_user_id() { + set_has_user_id(); + if (user_id_ == &::google::protobuf::internal::kEmptyString) { + user_id_ = new ::std::string; + } + return user_id_; +} +inline ::std::string* Stat::release_user_id() { + clear_has_user_id(); + if (user_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = user_id_; + user_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void Stat::set_allocated_user_id(::std::string* user_id) { + if (user_id_ != &::google::protobuf::internal::kEmptyString) { + delete user_id_; + } + if (user_id) { + set_has_user_id(); + user_id_ = user_id; + } else { + clear_has_user_id(); + user_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string group_id = 6; +inline bool Stat::has_group_id() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void Stat::set_has_group_id() { + _has_bits_[0] |= 0x00000020u; +} +inline void Stat::clear_has_group_id() { + _has_bits_[0] &= ~0x00000020u; +} +inline void Stat::clear_group_id() { + if (group_id_ != &::google::protobuf::internal::kEmptyString) { + group_id_->clear(); + } + clear_has_group_id(); +} +inline const ::std::string& Stat::group_id() const { + return *group_id_; +} +inline void Stat::set_group_id(const ::std::string& value) { + set_has_group_id(); + if (group_id_ == &::google::protobuf::internal::kEmptyString) { + group_id_ = new ::std::string; + } + group_id_->assign(value); +} +inline void Stat::set_group_id(const char* value) { + set_has_group_id(); + if (group_id_ == &::google::protobuf::internal::kEmptyString) { + group_id_ = new ::std::string; + } + group_id_->assign(value); +} +inline void Stat::set_group_id(const char* value, size_t size) { + set_has_group_id(); + if (group_id_ == &::google::protobuf::internal::kEmptyString) { + group_id_ = new ::std::string; + } + group_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Stat::mutable_group_id() { + set_has_group_id(); + if (group_id_ == &::google::protobuf::internal::kEmptyString) { + group_id_ = new ::std::string; + } + return group_id_; +} +inline ::std::string* Stat::release_group_id() { + clear_has_group_id(); + if (group_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = group_id_; + group_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void Stat::set_allocated_group_id(::std::string* group_id) { + if (group_id_ != &::google::protobuf::internal::kEmptyString) { + delete group_id_; + } + if (group_id) { + set_has_group_id(); + group_id_ = group_id; + } else { + clear_has_group_id(); + group_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 size = 7; +inline bool Stat::has_size() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void Stat::set_has_size() { + _has_bits_[0] |= 0x00000040u; +} +inline void Stat::clear_has_size() { + _has_bits_[0] &= ~0x00000040u; +} +inline void Stat::clear_size() { + size_ = GOOGLE_ULONGLONG(0); + clear_has_size(); +} +inline ::google::protobuf::uint64 Stat::size() const { + return size_; +} +inline void Stat::set_size(::google::protobuf::uint64 value) { + set_has_size(); + size_ = value; +} + +// required fixed64 atime_ns = 8; +inline bool Stat::has_atime_ns() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void Stat::set_has_atime_ns() { + _has_bits_[0] |= 0x00000080u; +} +inline void Stat::clear_has_atime_ns() { + _has_bits_[0] &= ~0x00000080u; +} +inline void Stat::clear_atime_ns() { + atime_ns_ = GOOGLE_ULONGLONG(0); + clear_has_atime_ns(); +} +inline ::google::protobuf::uint64 Stat::atime_ns() const { + return atime_ns_; +} +inline void Stat::set_atime_ns(::google::protobuf::uint64 value) { + set_has_atime_ns(); + atime_ns_ = value; +} + +// required fixed64 mtime_ns = 9; +inline bool Stat::has_mtime_ns() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void Stat::set_has_mtime_ns() { + _has_bits_[0] |= 0x00000100u; +} +inline void Stat::clear_has_mtime_ns() { + _has_bits_[0] &= ~0x00000100u; +} +inline void Stat::clear_mtime_ns() { + mtime_ns_ = GOOGLE_ULONGLONG(0); + clear_has_mtime_ns(); +} +inline ::google::protobuf::uint64 Stat::mtime_ns() const { + return mtime_ns_; +} +inline void Stat::set_mtime_ns(::google::protobuf::uint64 value) { + set_has_mtime_ns(); + mtime_ns_ = value; +} + +// required fixed64 ctime_ns = 10; +inline bool Stat::has_ctime_ns() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void Stat::set_has_ctime_ns() { + _has_bits_[0] |= 0x00000200u; +} +inline void Stat::clear_has_ctime_ns() { + _has_bits_[0] &= ~0x00000200u; +} +inline void Stat::clear_ctime_ns() { + ctime_ns_ = GOOGLE_ULONGLONG(0); + clear_has_ctime_ns(); +} +inline ::google::protobuf::uint64 Stat::ctime_ns() const { + return ctime_ns_; +} +inline void Stat::set_ctime_ns(::google::protobuf::uint64 value) { + set_has_ctime_ns(); + ctime_ns_ = value; +} + +// required fixed32 blksize = 11; +inline bool Stat::has_blksize() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void Stat::set_has_blksize() { + _has_bits_[0] |= 0x00000400u; +} +inline void Stat::clear_has_blksize() { + _has_bits_[0] &= ~0x00000400u; +} +inline void Stat::clear_blksize() { + blksize_ = 0u; + clear_has_blksize(); +} +inline ::google::protobuf::uint32 Stat::blksize() const { + return blksize_; +} +inline void Stat::set_blksize(::google::protobuf::uint32 value) { + set_has_blksize(); + blksize_ = value; +} + +// optional fixed64 etag = 12; +inline bool Stat::has_etag() const { + return (_has_bits_[0] & 0x00000800u) != 0; +} +inline void Stat::set_has_etag() { + _has_bits_[0] |= 0x00000800u; +} +inline void Stat::clear_has_etag() { + _has_bits_[0] &= ~0x00000800u; +} +inline void Stat::clear_etag() { + etag_ = GOOGLE_ULONGLONG(0); + clear_has_etag(); +} +inline ::google::protobuf::uint64 Stat::etag() const { + return etag_; +} +inline void Stat::set_etag(::google::protobuf::uint64 value) { + set_has_etag(); + etag_ = value; +} + +// required fixed32 truncate_epoch = 13; +inline bool Stat::has_truncate_epoch() const { + return (_has_bits_[0] & 0x00001000u) != 0; +} +inline void Stat::set_has_truncate_epoch() { + _has_bits_[0] |= 0x00001000u; +} +inline void Stat::clear_has_truncate_epoch() { + _has_bits_[0] &= ~0x00001000u; +} +inline void Stat::clear_truncate_epoch() { + truncate_epoch_ = 0u; + clear_has_truncate_epoch(); +} +inline ::google::protobuf::uint32 Stat::truncate_epoch() const { + return truncate_epoch_; +} +inline void Stat::set_truncate_epoch(::google::protobuf::uint32 value) { + set_has_truncate_epoch(); + truncate_epoch_ = value; +} + +// optional fixed32 attributes = 14; +inline bool Stat::has_attributes() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +inline void Stat::set_has_attributes() { + _has_bits_[0] |= 0x00002000u; +} +inline void Stat::clear_has_attributes() { + _has_bits_[0] &= ~0x00002000u; +} +inline void Stat::clear_attributes() { + attributes_ = 0u; + clear_has_attributes(); +} +inline ::google::protobuf::uint32 Stat::attributes() const { + return attributes_; +} +inline void Stat::set_attributes(::google::protobuf::uint32 value) { + set_has_attributes(); + attributes_ = value; +} + +// ------------------------------------------------------------------- + +// DirectoryEntry + +// required string name = 1; +inline bool DirectoryEntry::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DirectoryEntry::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void DirectoryEntry::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void DirectoryEntry::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& DirectoryEntry::name() const { + return *name_; +} +inline void DirectoryEntry::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void DirectoryEntry::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void DirectoryEntry::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* DirectoryEntry::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* DirectoryEntry::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void DirectoryEntry::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional .xtreemfs.pbrpc.Stat stbuf = 2; +inline bool DirectoryEntry::has_stbuf() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void DirectoryEntry::set_has_stbuf() { + _has_bits_[0] |= 0x00000002u; +} +inline void DirectoryEntry::clear_has_stbuf() { + _has_bits_[0] &= ~0x00000002u; +} +inline void DirectoryEntry::clear_stbuf() { + if (stbuf_ != NULL) stbuf_->::xtreemfs::pbrpc::Stat::Clear(); + clear_has_stbuf(); +} +inline const ::xtreemfs::pbrpc::Stat& DirectoryEntry::stbuf() const { + return stbuf_ != NULL ? *stbuf_ : *default_instance_->stbuf_; +} +inline ::xtreemfs::pbrpc::Stat* DirectoryEntry::mutable_stbuf() { + set_has_stbuf(); + if (stbuf_ == NULL) stbuf_ = new ::xtreemfs::pbrpc::Stat; + return stbuf_; +} +inline ::xtreemfs::pbrpc::Stat* DirectoryEntry::release_stbuf() { + clear_has_stbuf(); + ::xtreemfs::pbrpc::Stat* temp = stbuf_; + stbuf_ = NULL; + return temp; +} +inline void DirectoryEntry::set_allocated_stbuf(::xtreemfs::pbrpc::Stat* stbuf) { + delete stbuf_; + stbuf_ = stbuf; + if (stbuf) { + set_has_stbuf(); + } else { + clear_has_stbuf(); + } +} + +// ------------------------------------------------------------------- + +// DirectoryEntries + +// repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; +inline int DirectoryEntries::entries_size() const { + return entries_.size(); +} +inline void DirectoryEntries::clear_entries() { + entries_.Clear(); +} +inline const ::xtreemfs::pbrpc::DirectoryEntry& DirectoryEntries::entries(int index) const { + return entries_.Get(index); +} +inline ::xtreemfs::pbrpc::DirectoryEntry* DirectoryEntries::mutable_entries(int index) { + return entries_.Mutable(index); +} +inline ::xtreemfs::pbrpc::DirectoryEntry* DirectoryEntries::add_entries() { + return entries_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::DirectoryEntry >& +DirectoryEntries::entries() const { + return entries_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::DirectoryEntry >* +DirectoryEntries::mutable_entries() { + return &entries_; +} + +// ------------------------------------------------------------------- + +// XAttr + +// required string name = 1; +inline bool XAttr::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void XAttr::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void XAttr::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void XAttr::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& XAttr::name() const { + return *name_; +} +inline void XAttr::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void XAttr::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void XAttr::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* XAttr::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* XAttr::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void XAttr::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string value = 2; +inline bool XAttr::has_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void XAttr::set_has_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void XAttr::clear_has_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void XAttr::clear_value() { + if (value_ != &::google::protobuf::internal::kEmptyString) { + value_->clear(); + } + clear_has_value(); +} +inline const ::std::string& XAttr::value() const { + return *value_; +} +inline void XAttr::set_value(const ::std::string& value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(value); +} +inline void XAttr::set_value(const char* value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(value); +} +inline void XAttr::set_value(const char* value, size_t size) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(reinterpret_cast(value), size); +} +inline ::std::string* XAttr::mutable_value() { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + return value_; +} +inline ::std::string* XAttr::release_value() { + clear_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = value_; + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void XAttr::set_allocated_value(::std::string* value) { + if (value_ != &::google::protobuf::internal::kEmptyString) { + delete value_; + } + if (value) { + set_has_value(); + value_ = value; + } else { + clear_has_value(); + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional bytes value_bytes_string = 3; +inline bool XAttr::has_value_bytes_string() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void XAttr::set_has_value_bytes_string() { + _has_bits_[0] |= 0x00000004u; +} +inline void XAttr::clear_has_value_bytes_string() { + _has_bits_[0] &= ~0x00000004u; +} +inline void XAttr::clear_value_bytes_string() { + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + value_bytes_string_->clear(); + } + clear_has_value_bytes_string(); +} +inline const ::std::string& XAttr::value_bytes_string() const { + return *value_bytes_string_; +} +inline void XAttr::set_value_bytes_string(const ::std::string& value) { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + value_bytes_string_->assign(value); +} +inline void XAttr::set_value_bytes_string(const char* value) { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + value_bytes_string_->assign(value); +} +inline void XAttr::set_value_bytes_string(const void* value, size_t size) { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + value_bytes_string_->assign(reinterpret_cast(value), size); +} +inline ::std::string* XAttr::mutable_value_bytes_string() { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + return value_bytes_string_; +} +inline ::std::string* XAttr::release_value_bytes_string() { + clear_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = value_bytes_string_; + value_bytes_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void XAttr::set_allocated_value_bytes_string(::std::string* value_bytes_string) { + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + delete value_bytes_string_; + } + if (value_bytes_string) { + set_has_value_bytes_string(); + value_bytes_string_ = value_bytes_string; + } else { + clear_has_value_bytes_string(); + value_bytes_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// Volume + +// required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; +inline bool Volume::has_access_control_policy() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Volume::set_has_access_control_policy() { + _has_bits_[0] |= 0x00000001u; +} +inline void Volume::clear_has_access_control_policy() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Volume::clear_access_control_policy() { + access_control_policy_ = 1; + clear_has_access_control_policy(); +} +inline ::xtreemfs::pbrpc::AccessControlPolicyType Volume::access_control_policy() const { + return static_cast< ::xtreemfs::pbrpc::AccessControlPolicyType >(access_control_policy_); +} +inline void Volume::set_access_control_policy(::xtreemfs::pbrpc::AccessControlPolicyType value) { + assert(::xtreemfs::pbrpc::AccessControlPolicyType_IsValid(value)); + set_has_access_control_policy(); + access_control_policy_ = value; +} + +// required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; +inline bool Volume::has_default_striping_policy() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Volume::set_has_default_striping_policy() { + _has_bits_[0] |= 0x00000002u; +} +inline void Volume::clear_has_default_striping_policy() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Volume::clear_default_striping_policy() { + if (default_striping_policy_ != NULL) default_striping_policy_->::xtreemfs::pbrpc::StripingPolicy::Clear(); + clear_has_default_striping_policy(); +} +inline const ::xtreemfs::pbrpc::StripingPolicy& Volume::default_striping_policy() const { + return default_striping_policy_ != NULL ? *default_striping_policy_ : *default_instance_->default_striping_policy_; +} +inline ::xtreemfs::pbrpc::StripingPolicy* Volume::mutable_default_striping_policy() { + set_has_default_striping_policy(); + if (default_striping_policy_ == NULL) default_striping_policy_ = new ::xtreemfs::pbrpc::StripingPolicy; + return default_striping_policy_; +} +inline ::xtreemfs::pbrpc::StripingPolicy* Volume::release_default_striping_policy() { + clear_has_default_striping_policy(); + ::xtreemfs::pbrpc::StripingPolicy* temp = default_striping_policy_; + default_striping_policy_ = NULL; + return temp; +} +inline void Volume::set_allocated_default_striping_policy(::xtreemfs::pbrpc::StripingPolicy* default_striping_policy) { + delete default_striping_policy_; + default_striping_policy_ = default_striping_policy; + if (default_striping_policy) { + set_has_default_striping_policy(); + } else { + clear_has_default_striping_policy(); + } +} + +// required string id = 3; +inline bool Volume::has_id() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Volume::set_has_id() { + _has_bits_[0] |= 0x00000004u; +} +inline void Volume::clear_has_id() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Volume::clear_id() { + if (id_ != &::google::protobuf::internal::kEmptyString) { + id_->clear(); + } + clear_has_id(); +} +inline const ::std::string& Volume::id() const { + return *id_; +} +inline void Volume::set_id(const ::std::string& value) { + set_has_id(); + if (id_ == &::google::protobuf::internal::kEmptyString) { + id_ = new ::std::string; + } + id_->assign(value); +} +inline void Volume::set_id(const char* value) { + set_has_id(); + if (id_ == &::google::protobuf::internal::kEmptyString) { + id_ = new ::std::string; + } + id_->assign(value); +} +inline void Volume::set_id(const char* value, size_t size) { + set_has_id(); + if (id_ == &::google::protobuf::internal::kEmptyString) { + id_ = new ::std::string; + } + id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Volume::mutable_id() { + set_has_id(); + if (id_ == &::google::protobuf::internal::kEmptyString) { + id_ = new ::std::string; + } + return id_; +} +inline ::std::string* Volume::release_id() { + clear_has_id(); + if (id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = id_; + id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void Volume::set_allocated_id(::std::string* id) { + if (id_ != &::google::protobuf::internal::kEmptyString) { + delete id_; + } + if (id) { + set_has_id(); + id_ = id; + } else { + clear_has_id(); + id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 mode = 4; +inline bool Volume::has_mode() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void Volume::set_has_mode() { + _has_bits_[0] |= 0x00000008u; +} +inline void Volume::clear_has_mode() { + _has_bits_[0] &= ~0x00000008u; +} +inline void Volume::clear_mode() { + mode_ = 0u; + clear_has_mode(); +} +inline ::google::protobuf::uint32 Volume::mode() const { + return mode_; +} +inline void Volume::set_mode(::google::protobuf::uint32 value) { + set_has_mode(); + mode_ = value; +} + +// required string name = 5; +inline bool Volume::has_name() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void Volume::set_has_name() { + _has_bits_[0] |= 0x00000010u; +} +inline void Volume::clear_has_name() { + _has_bits_[0] &= ~0x00000010u; +} +inline void Volume::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& Volume::name() const { + return *name_; +} +inline void Volume::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void Volume::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void Volume::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Volume::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* Volume::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void Volume::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string owner_group_id = 6; +inline bool Volume::has_owner_group_id() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void Volume::set_has_owner_group_id() { + _has_bits_[0] |= 0x00000020u; +} +inline void Volume::clear_has_owner_group_id() { + _has_bits_[0] &= ~0x00000020u; +} +inline void Volume::clear_owner_group_id() { + if (owner_group_id_ != &::google::protobuf::internal::kEmptyString) { + owner_group_id_->clear(); + } + clear_has_owner_group_id(); +} +inline const ::std::string& Volume::owner_group_id() const { + return *owner_group_id_; +} +inline void Volume::set_owner_group_id(const ::std::string& value) { + set_has_owner_group_id(); + if (owner_group_id_ == &::google::protobuf::internal::kEmptyString) { + owner_group_id_ = new ::std::string; + } + owner_group_id_->assign(value); +} +inline void Volume::set_owner_group_id(const char* value) { + set_has_owner_group_id(); + if (owner_group_id_ == &::google::protobuf::internal::kEmptyString) { + owner_group_id_ = new ::std::string; + } + owner_group_id_->assign(value); +} +inline void Volume::set_owner_group_id(const char* value, size_t size) { + set_has_owner_group_id(); + if (owner_group_id_ == &::google::protobuf::internal::kEmptyString) { + owner_group_id_ = new ::std::string; + } + owner_group_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Volume::mutable_owner_group_id() { + set_has_owner_group_id(); + if (owner_group_id_ == &::google::protobuf::internal::kEmptyString) { + owner_group_id_ = new ::std::string; + } + return owner_group_id_; +} +inline ::std::string* Volume::release_owner_group_id() { + clear_has_owner_group_id(); + if (owner_group_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = owner_group_id_; + owner_group_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void Volume::set_allocated_owner_group_id(::std::string* owner_group_id) { + if (owner_group_id_ != &::google::protobuf::internal::kEmptyString) { + delete owner_group_id_; + } + if (owner_group_id) { + set_has_owner_group_id(); + owner_group_id_ = owner_group_id; + } else { + clear_has_owner_group_id(); + owner_group_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string owner_user_id = 7; +inline bool Volume::has_owner_user_id() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void Volume::set_has_owner_user_id() { + _has_bits_[0] |= 0x00000040u; +} +inline void Volume::clear_has_owner_user_id() { + _has_bits_[0] &= ~0x00000040u; +} +inline void Volume::clear_owner_user_id() { + if (owner_user_id_ != &::google::protobuf::internal::kEmptyString) { + owner_user_id_->clear(); + } + clear_has_owner_user_id(); +} +inline const ::std::string& Volume::owner_user_id() const { + return *owner_user_id_; +} +inline void Volume::set_owner_user_id(const ::std::string& value) { + set_has_owner_user_id(); + if (owner_user_id_ == &::google::protobuf::internal::kEmptyString) { + owner_user_id_ = new ::std::string; + } + owner_user_id_->assign(value); +} +inline void Volume::set_owner_user_id(const char* value) { + set_has_owner_user_id(); + if (owner_user_id_ == &::google::protobuf::internal::kEmptyString) { + owner_user_id_ = new ::std::string; + } + owner_user_id_->assign(value); +} +inline void Volume::set_owner_user_id(const char* value, size_t size) { + set_has_owner_user_id(); + if (owner_user_id_ == &::google::protobuf::internal::kEmptyString) { + owner_user_id_ = new ::std::string; + } + owner_user_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Volume::mutable_owner_user_id() { + set_has_owner_user_id(); + if (owner_user_id_ == &::google::protobuf::internal::kEmptyString) { + owner_user_id_ = new ::std::string; + } + return owner_user_id_; +} +inline ::std::string* Volume::release_owner_user_id() { + clear_has_owner_user_id(); + if (owner_user_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = owner_user_id_; + owner_user_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void Volume::set_allocated_owner_user_id(::std::string* owner_user_id) { + if (owner_user_id_ != &::google::protobuf::internal::kEmptyString) { + delete owner_user_id_; + } + if (owner_user_id) { + set_has_owner_user_id(); + owner_user_id_ = owner_user_id; + } else { + clear_has_owner_user_id(); + owner_user_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; +inline int Volume::attrs_size() const { + return attrs_.size(); +} +inline void Volume::clear_attrs() { + attrs_.Clear(); +} +inline const ::xtreemfs::pbrpc::KeyValuePair& Volume::attrs(int index) const { + return attrs_.Get(index); +} +inline ::xtreemfs::pbrpc::KeyValuePair* Volume::mutable_attrs(int index) { + return attrs_.Mutable(index); +} +inline ::xtreemfs::pbrpc::KeyValuePair* Volume::add_attrs() { + return attrs_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >& +Volume::attrs() const { + return attrs_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::KeyValuePair >* +Volume::mutable_attrs() { + return &attrs_; +} + +// optional fixed64 quota = 9; +inline bool Volume::has_quota() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void Volume::set_has_quota() { + _has_bits_[0] |= 0x00000100u; +} +inline void Volume::clear_has_quota() { + _has_bits_[0] &= ~0x00000100u; +} +inline void Volume::clear_quota() { + quota_ = GOOGLE_ULONGLONG(0); + clear_has_quota(); +} +inline ::google::protobuf::uint64 Volume::quota() const { + return quota_; +} +inline void Volume::set_quota(::google::protobuf::uint64 value) { + set_has_quota(); + quota_ = value; +} + +// ------------------------------------------------------------------- + +// Volumes + +// repeated .xtreemfs.pbrpc.Volume volumes = 1; +inline int Volumes::volumes_size() const { + return volumes_.size(); +} +inline void Volumes::clear_volumes() { + volumes_.Clear(); +} +inline const ::xtreemfs::pbrpc::Volume& Volumes::volumes(int index) const { + return volumes_.Get(index); +} +inline ::xtreemfs::pbrpc::Volume* Volumes::mutable_volumes(int index) { + return volumes_.Mutable(index); +} +inline ::xtreemfs::pbrpc::Volume* Volumes::add_volumes() { + return volumes_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Volume >& +Volumes::volumes() const { + return volumes_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::Volume >* +Volumes::mutable_volumes() { + return &volumes_; +} + +// ------------------------------------------------------------------- + +// StatVFS + +// required fixed32 bsize = 1; +inline bool StatVFS::has_bsize() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void StatVFS::set_has_bsize() { + _has_bits_[0] |= 0x00000001u; +} +inline void StatVFS::clear_has_bsize() { + _has_bits_[0] &= ~0x00000001u; +} +inline void StatVFS::clear_bsize() { + bsize_ = 0u; + clear_has_bsize(); +} +inline ::google::protobuf::uint32 StatVFS::bsize() const { + return bsize_; +} +inline void StatVFS::set_bsize(::google::protobuf::uint32 value) { + set_has_bsize(); + bsize_ = value; +} + +// required fixed64 bavail = 2; +inline bool StatVFS::has_bavail() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void StatVFS::set_has_bavail() { + _has_bits_[0] |= 0x00000002u; +} +inline void StatVFS::clear_has_bavail() { + _has_bits_[0] &= ~0x00000002u; +} +inline void StatVFS::clear_bavail() { + bavail_ = GOOGLE_ULONGLONG(0); + clear_has_bavail(); +} +inline ::google::protobuf::uint64 StatVFS::bavail() const { + return bavail_; +} +inline void StatVFS::set_bavail(::google::protobuf::uint64 value) { + set_has_bavail(); + bavail_ = value; +} + +// optional fixed64 bfree = 13; +inline bool StatVFS::has_bfree() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void StatVFS::set_has_bfree() { + _has_bits_[0] |= 0x00000004u; +} +inline void StatVFS::clear_has_bfree() { + _has_bits_[0] &= ~0x00000004u; +} +inline void StatVFS::clear_bfree() { + bfree_ = GOOGLE_ULONGLONG(0); + clear_has_bfree(); +} +inline ::google::protobuf::uint64 StatVFS::bfree() const { + return bfree_; +} +inline void StatVFS::set_bfree(::google::protobuf::uint64 value) { + set_has_bfree(); + bfree_ = value; +} + +// required fixed64 blocks = 3; +inline bool StatVFS::has_blocks() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void StatVFS::set_has_blocks() { + _has_bits_[0] |= 0x00000008u; +} +inline void StatVFS::clear_has_blocks() { + _has_bits_[0] &= ~0x00000008u; +} +inline void StatVFS::clear_blocks() { + blocks_ = GOOGLE_ULONGLONG(0); + clear_has_blocks(); +} +inline ::google::protobuf::uint64 StatVFS::blocks() const { + return blocks_; +} +inline void StatVFS::set_blocks(::google::protobuf::uint64 value) { + set_has_blocks(); + blocks_ = value; +} + +// required string fsid = 4; +inline bool StatVFS::has_fsid() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void StatVFS::set_has_fsid() { + _has_bits_[0] |= 0x00000010u; +} +inline void StatVFS::clear_has_fsid() { + _has_bits_[0] &= ~0x00000010u; +} +inline void StatVFS::clear_fsid() { + if (fsid_ != &::google::protobuf::internal::kEmptyString) { + fsid_->clear(); + } + clear_has_fsid(); +} +inline const ::std::string& StatVFS::fsid() const { + return *fsid_; +} +inline void StatVFS::set_fsid(const ::std::string& value) { + set_has_fsid(); + if (fsid_ == &::google::protobuf::internal::kEmptyString) { + fsid_ = new ::std::string; + } + fsid_->assign(value); +} +inline void StatVFS::set_fsid(const char* value) { + set_has_fsid(); + if (fsid_ == &::google::protobuf::internal::kEmptyString) { + fsid_ = new ::std::string; + } + fsid_->assign(value); +} +inline void StatVFS::set_fsid(const char* value, size_t size) { + set_has_fsid(); + if (fsid_ == &::google::protobuf::internal::kEmptyString) { + fsid_ = new ::std::string; + } + fsid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* StatVFS::mutable_fsid() { + set_has_fsid(); + if (fsid_ == &::google::protobuf::internal::kEmptyString) { + fsid_ = new ::std::string; + } + return fsid_; +} +inline ::std::string* StatVFS::release_fsid() { + clear_has_fsid(); + if (fsid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = fsid_; + fsid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void StatVFS::set_allocated_fsid(::std::string* fsid) { + if (fsid_ != &::google::protobuf::internal::kEmptyString) { + delete fsid_; + } + if (fsid) { + set_has_fsid(); + fsid_ = fsid; + } else { + clear_has_fsid(); + fsid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 namemax = 5; +inline bool StatVFS::has_namemax() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void StatVFS::set_has_namemax() { + _has_bits_[0] |= 0x00000020u; +} +inline void StatVFS::clear_has_namemax() { + _has_bits_[0] &= ~0x00000020u; +} +inline void StatVFS::clear_namemax() { + namemax_ = 0u; + clear_has_namemax(); +} +inline ::google::protobuf::uint32 StatVFS::namemax() const { + return namemax_; +} +inline void StatVFS::set_namemax(::google::protobuf::uint32 value) { + set_has_namemax(); + namemax_ = value; +} + +// required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; +inline bool StatVFS::has_access_control_policy() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void StatVFS::set_has_access_control_policy() { + _has_bits_[0] |= 0x00000040u; +} +inline void StatVFS::clear_has_access_control_policy() { + _has_bits_[0] &= ~0x00000040u; +} +inline void StatVFS::clear_access_control_policy() { + access_control_policy_ = 1; + clear_has_access_control_policy(); +} +inline ::xtreemfs::pbrpc::AccessControlPolicyType StatVFS::access_control_policy() const { + return static_cast< ::xtreemfs::pbrpc::AccessControlPolicyType >(access_control_policy_); +} +inline void StatVFS::set_access_control_policy(::xtreemfs::pbrpc::AccessControlPolicyType value) { + assert(::xtreemfs::pbrpc::AccessControlPolicyType_IsValid(value)); + set_has_access_control_policy(); + access_control_policy_ = value; +} + +// required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; +inline bool StatVFS::has_default_striping_policy() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void StatVFS::set_has_default_striping_policy() { + _has_bits_[0] |= 0x00000080u; +} +inline void StatVFS::clear_has_default_striping_policy() { + _has_bits_[0] &= ~0x00000080u; +} +inline void StatVFS::clear_default_striping_policy() { + if (default_striping_policy_ != NULL) default_striping_policy_->::xtreemfs::pbrpc::StripingPolicy::Clear(); + clear_has_default_striping_policy(); +} +inline const ::xtreemfs::pbrpc::StripingPolicy& StatVFS::default_striping_policy() const { + return default_striping_policy_ != NULL ? *default_striping_policy_ : *default_instance_->default_striping_policy_; +} +inline ::xtreemfs::pbrpc::StripingPolicy* StatVFS::mutable_default_striping_policy() { + set_has_default_striping_policy(); + if (default_striping_policy_ == NULL) default_striping_policy_ = new ::xtreemfs::pbrpc::StripingPolicy; + return default_striping_policy_; +} +inline ::xtreemfs::pbrpc::StripingPolicy* StatVFS::release_default_striping_policy() { + clear_has_default_striping_policy(); + ::xtreemfs::pbrpc::StripingPolicy* temp = default_striping_policy_; + default_striping_policy_ = NULL; + return temp; +} +inline void StatVFS::set_allocated_default_striping_policy(::xtreemfs::pbrpc::StripingPolicy* default_striping_policy) { + delete default_striping_policy_; + default_striping_policy_ = default_striping_policy; + if (default_striping_policy) { + set_has_default_striping_policy(); + } else { + clear_has_default_striping_policy(); + } +} + +// required fixed64 etag = 8; +inline bool StatVFS::has_etag() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void StatVFS::set_has_etag() { + _has_bits_[0] |= 0x00000100u; +} +inline void StatVFS::clear_has_etag() { + _has_bits_[0] &= ~0x00000100u; +} +inline void StatVFS::clear_etag() { + etag_ = GOOGLE_ULONGLONG(0); + clear_has_etag(); +} +inline ::google::protobuf::uint64 StatVFS::etag() const { + return etag_; +} +inline void StatVFS::set_etag(::google::protobuf::uint64 value) { + set_has_etag(); + etag_ = value; +} + +// required fixed32 mode = 9; +inline bool StatVFS::has_mode() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void StatVFS::set_has_mode() { + _has_bits_[0] |= 0x00000200u; +} +inline void StatVFS::clear_has_mode() { + _has_bits_[0] &= ~0x00000200u; +} +inline void StatVFS::clear_mode() { + mode_ = 0u; + clear_has_mode(); +} +inline ::google::protobuf::uint32 StatVFS::mode() const { + return mode_; +} +inline void StatVFS::set_mode(::google::protobuf::uint32 value) { + set_has_mode(); + mode_ = value; +} + +// required string name = 10; +inline bool StatVFS::has_name() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void StatVFS::set_has_name() { + _has_bits_[0] |= 0x00000400u; +} +inline void StatVFS::clear_has_name() { + _has_bits_[0] &= ~0x00000400u; +} +inline void StatVFS::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& StatVFS::name() const { + return *name_; +} +inline void StatVFS::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void StatVFS::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void StatVFS::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* StatVFS::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* StatVFS::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void StatVFS::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string owner_group_id = 11; +inline bool StatVFS::has_owner_group_id() const { + return (_has_bits_[0] & 0x00000800u) != 0; +} +inline void StatVFS::set_has_owner_group_id() { + _has_bits_[0] |= 0x00000800u; +} +inline void StatVFS::clear_has_owner_group_id() { + _has_bits_[0] &= ~0x00000800u; +} +inline void StatVFS::clear_owner_group_id() { + if (owner_group_id_ != &::google::protobuf::internal::kEmptyString) { + owner_group_id_->clear(); + } + clear_has_owner_group_id(); +} +inline const ::std::string& StatVFS::owner_group_id() const { + return *owner_group_id_; +} +inline void StatVFS::set_owner_group_id(const ::std::string& value) { + set_has_owner_group_id(); + if (owner_group_id_ == &::google::protobuf::internal::kEmptyString) { + owner_group_id_ = new ::std::string; + } + owner_group_id_->assign(value); +} +inline void StatVFS::set_owner_group_id(const char* value) { + set_has_owner_group_id(); + if (owner_group_id_ == &::google::protobuf::internal::kEmptyString) { + owner_group_id_ = new ::std::string; + } + owner_group_id_->assign(value); +} +inline void StatVFS::set_owner_group_id(const char* value, size_t size) { + set_has_owner_group_id(); + if (owner_group_id_ == &::google::protobuf::internal::kEmptyString) { + owner_group_id_ = new ::std::string; + } + owner_group_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* StatVFS::mutable_owner_group_id() { + set_has_owner_group_id(); + if (owner_group_id_ == &::google::protobuf::internal::kEmptyString) { + owner_group_id_ = new ::std::string; + } + return owner_group_id_; +} +inline ::std::string* StatVFS::release_owner_group_id() { + clear_has_owner_group_id(); + if (owner_group_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = owner_group_id_; + owner_group_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void StatVFS::set_allocated_owner_group_id(::std::string* owner_group_id) { + if (owner_group_id_ != &::google::protobuf::internal::kEmptyString) { + delete owner_group_id_; + } + if (owner_group_id) { + set_has_owner_group_id(); + owner_group_id_ = owner_group_id; + } else { + clear_has_owner_group_id(); + owner_group_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string owner_user_id = 12; +inline bool StatVFS::has_owner_user_id() const { + return (_has_bits_[0] & 0x00001000u) != 0; +} +inline void StatVFS::set_has_owner_user_id() { + _has_bits_[0] |= 0x00001000u; +} +inline void StatVFS::clear_has_owner_user_id() { + _has_bits_[0] &= ~0x00001000u; +} +inline void StatVFS::clear_owner_user_id() { + if (owner_user_id_ != &::google::protobuf::internal::kEmptyString) { + owner_user_id_->clear(); + } + clear_has_owner_user_id(); +} +inline const ::std::string& StatVFS::owner_user_id() const { + return *owner_user_id_; +} +inline void StatVFS::set_owner_user_id(const ::std::string& value) { + set_has_owner_user_id(); + if (owner_user_id_ == &::google::protobuf::internal::kEmptyString) { + owner_user_id_ = new ::std::string; + } + owner_user_id_->assign(value); +} +inline void StatVFS::set_owner_user_id(const char* value) { + set_has_owner_user_id(); + if (owner_user_id_ == &::google::protobuf::internal::kEmptyString) { + owner_user_id_ = new ::std::string; + } + owner_user_id_->assign(value); +} +inline void StatVFS::set_owner_user_id(const char* value, size_t size) { + set_has_owner_user_id(); + if (owner_user_id_ == &::google::protobuf::internal::kEmptyString) { + owner_user_id_ = new ::std::string; + } + owner_user_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* StatVFS::mutable_owner_user_id() { + set_has_owner_user_id(); + if (owner_user_id_ == &::google::protobuf::internal::kEmptyString) { + owner_user_id_ = new ::std::string; + } + return owner_user_id_; +} +inline ::std::string* StatVFS::release_owner_user_id() { + clear_has_owner_user_id(); + if (owner_user_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = owner_user_id_; + owner_user_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void StatVFS::set_allocated_owner_user_id(::std::string* owner_user_id) { + if (owner_user_id_ != &::google::protobuf::internal::kEmptyString) { + delete owner_user_id_; + } + if (owner_user_id) { + set_has_owner_user_id(); + owner_user_id_ = owner_user_id; + } else { + clear_has_owner_user_id(); + owner_user_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// fsetattrRequest + +// required .xtreemfs.pbrpc.Stat stbuf = 1; +inline bool fsetattrRequest::has_stbuf() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void fsetattrRequest::set_has_stbuf() { + _has_bits_[0] |= 0x00000001u; +} +inline void fsetattrRequest::clear_has_stbuf() { + _has_bits_[0] &= ~0x00000001u; +} +inline void fsetattrRequest::clear_stbuf() { + if (stbuf_ != NULL) stbuf_->::xtreemfs::pbrpc::Stat::Clear(); + clear_has_stbuf(); +} +inline const ::xtreemfs::pbrpc::Stat& fsetattrRequest::stbuf() const { + return stbuf_ != NULL ? *stbuf_ : *default_instance_->stbuf_; +} +inline ::xtreemfs::pbrpc::Stat* fsetattrRequest::mutable_stbuf() { + set_has_stbuf(); + if (stbuf_ == NULL) stbuf_ = new ::xtreemfs::pbrpc::Stat; + return stbuf_; +} +inline ::xtreemfs::pbrpc::Stat* fsetattrRequest::release_stbuf() { + clear_has_stbuf(); + ::xtreemfs::pbrpc::Stat* temp = stbuf_; + stbuf_ = NULL; + return temp; +} +inline void fsetattrRequest::set_allocated_stbuf(::xtreemfs::pbrpc::Stat* stbuf) { + delete stbuf_; + stbuf_ = stbuf; + if (stbuf) { + set_has_stbuf(); + } else { + clear_has_stbuf(); + } +} + +// required fixed32 to_set = 2; +inline bool fsetattrRequest::has_to_set() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void fsetattrRequest::set_has_to_set() { + _has_bits_[0] |= 0x00000002u; +} +inline void fsetattrRequest::clear_has_to_set() { + _has_bits_[0] &= ~0x00000002u; +} +inline void fsetattrRequest::clear_to_set() { + to_set_ = 0u; + clear_has_to_set(); +} +inline ::google::protobuf::uint32 fsetattrRequest::to_set() const { + return to_set_; +} +inline void fsetattrRequest::set_to_set(::google::protobuf::uint32 value) { + set_has_to_set(); + to_set_ = value; +} + +// required .xtreemfs.pbrpc.XCap cap = 3; +inline bool fsetattrRequest::has_cap() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void fsetattrRequest::set_has_cap() { + _has_bits_[0] |= 0x00000004u; +} +inline void fsetattrRequest::clear_has_cap() { + _has_bits_[0] &= ~0x00000004u; +} +inline void fsetattrRequest::clear_cap() { + if (cap_ != NULL) cap_->::xtreemfs::pbrpc::XCap::Clear(); + clear_has_cap(); +} +inline const ::xtreemfs::pbrpc::XCap& fsetattrRequest::cap() const { + return cap_ != NULL ? *cap_ : *default_instance_->cap_; +} +inline ::xtreemfs::pbrpc::XCap* fsetattrRequest::mutable_cap() { + set_has_cap(); + if (cap_ == NULL) cap_ = new ::xtreemfs::pbrpc::XCap; + return cap_; +} +inline ::xtreemfs::pbrpc::XCap* fsetattrRequest::release_cap() { + clear_has_cap(); + ::xtreemfs::pbrpc::XCap* temp = cap_; + cap_ = NULL; + return temp; +} +inline void fsetattrRequest::set_allocated_cap(::xtreemfs::pbrpc::XCap* cap) { + delete cap_; + cap_ = cap; + if (cap) { + set_has_cap(); + } else { + clear_has_cap(); + } +} + +// ------------------------------------------------------------------- + +// getattrRequest + +// required string volume_name = 1; +inline bool getattrRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void getattrRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void getattrRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void getattrRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& getattrRequest::volume_name() const { + return *volume_name_; +} +inline void getattrRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void getattrRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void getattrRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* getattrRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* getattrRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void getattrRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool getattrRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void getattrRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void getattrRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void getattrRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& getattrRequest::path() const { + return *path_; +} +inline void getattrRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void getattrRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void getattrRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* getattrRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* getattrRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void getattrRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 known_etag = 3; +inline bool getattrRequest::has_known_etag() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void getattrRequest::set_has_known_etag() { + _has_bits_[0] |= 0x00000004u; +} +inline void getattrRequest::clear_has_known_etag() { + _has_bits_[0] &= ~0x00000004u; +} +inline void getattrRequest::clear_known_etag() { + known_etag_ = GOOGLE_ULONGLONG(0); + clear_has_known_etag(); +} +inline ::google::protobuf::uint64 getattrRequest::known_etag() const { + return known_etag_; +} +inline void getattrRequest::set_known_etag(::google::protobuf::uint64 value) { + set_has_known_etag(); + known_etag_ = value; +} + +// ------------------------------------------------------------------- + +// getattrResponse + +// optional .xtreemfs.pbrpc.Stat stbuf = 1; +inline bool getattrResponse::has_stbuf() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void getattrResponse::set_has_stbuf() { + _has_bits_[0] |= 0x00000001u; +} +inline void getattrResponse::clear_has_stbuf() { + _has_bits_[0] &= ~0x00000001u; +} +inline void getattrResponse::clear_stbuf() { + if (stbuf_ != NULL) stbuf_->::xtreemfs::pbrpc::Stat::Clear(); + clear_has_stbuf(); +} +inline const ::xtreemfs::pbrpc::Stat& getattrResponse::stbuf() const { + return stbuf_ != NULL ? *stbuf_ : *default_instance_->stbuf_; +} +inline ::xtreemfs::pbrpc::Stat* getattrResponse::mutable_stbuf() { + set_has_stbuf(); + if (stbuf_ == NULL) stbuf_ = new ::xtreemfs::pbrpc::Stat; + return stbuf_; +} +inline ::xtreemfs::pbrpc::Stat* getattrResponse::release_stbuf() { + clear_has_stbuf(); + ::xtreemfs::pbrpc::Stat* temp = stbuf_; + stbuf_ = NULL; + return temp; +} +inline void getattrResponse::set_allocated_stbuf(::xtreemfs::pbrpc::Stat* stbuf) { + delete stbuf_; + stbuf_ = stbuf; + if (stbuf) { + set_has_stbuf(); + } else { + clear_has_stbuf(); + } +} + +// ------------------------------------------------------------------- + +// getxattrRequest + +// required string volume_name = 1; +inline bool getxattrRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void getxattrRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void getxattrRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void getxattrRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& getxattrRequest::volume_name() const { + return *volume_name_; +} +inline void getxattrRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void getxattrRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void getxattrRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* getxattrRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* getxattrRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void getxattrRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool getxattrRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void getxattrRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void getxattrRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void getxattrRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& getxattrRequest::path() const { + return *path_; +} +inline void getxattrRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void getxattrRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void getxattrRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* getxattrRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* getxattrRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void getxattrRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string name = 3; +inline bool getxattrRequest::has_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void getxattrRequest::set_has_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void getxattrRequest::clear_has_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void getxattrRequest::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& getxattrRequest::name() const { + return *name_; +} +inline void getxattrRequest::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void getxattrRequest::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void getxattrRequest::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* getxattrRequest::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* getxattrRequest::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void getxattrRequest::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// getxattrResponse + +// required string value = 1; +inline bool getxattrResponse::has_value() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void getxattrResponse::set_has_value() { + _has_bits_[0] |= 0x00000001u; +} +inline void getxattrResponse::clear_has_value() { + _has_bits_[0] &= ~0x00000001u; +} +inline void getxattrResponse::clear_value() { + if (value_ != &::google::protobuf::internal::kEmptyString) { + value_->clear(); + } + clear_has_value(); +} +inline const ::std::string& getxattrResponse::value() const { + return *value_; +} +inline void getxattrResponse::set_value(const ::std::string& value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(value); +} +inline void getxattrResponse::set_value(const char* value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(value); +} +inline void getxattrResponse::set_value(const char* value, size_t size) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(reinterpret_cast(value), size); +} +inline ::std::string* getxattrResponse::mutable_value() { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + return value_; +} +inline ::std::string* getxattrResponse::release_value() { + clear_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = value_; + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void getxattrResponse::set_allocated_value(::std::string* value) { + if (value_ != &::google::protobuf::internal::kEmptyString) { + delete value_; + } + if (value) { + set_has_value(); + value_ = value; + } else { + clear_has_value(); + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional bytes value_bytes_string = 2; +inline bool getxattrResponse::has_value_bytes_string() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void getxattrResponse::set_has_value_bytes_string() { + _has_bits_[0] |= 0x00000002u; +} +inline void getxattrResponse::clear_has_value_bytes_string() { + _has_bits_[0] &= ~0x00000002u; +} +inline void getxattrResponse::clear_value_bytes_string() { + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + value_bytes_string_->clear(); + } + clear_has_value_bytes_string(); +} +inline const ::std::string& getxattrResponse::value_bytes_string() const { + return *value_bytes_string_; +} +inline void getxattrResponse::set_value_bytes_string(const ::std::string& value) { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + value_bytes_string_->assign(value); +} +inline void getxattrResponse::set_value_bytes_string(const char* value) { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + value_bytes_string_->assign(value); +} +inline void getxattrResponse::set_value_bytes_string(const void* value, size_t size) { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + value_bytes_string_->assign(reinterpret_cast(value), size); +} +inline ::std::string* getxattrResponse::mutable_value_bytes_string() { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + return value_bytes_string_; +} +inline ::std::string* getxattrResponse::release_value_bytes_string() { + clear_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = value_bytes_string_; + value_bytes_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void getxattrResponse::set_allocated_value_bytes_string(::std::string* value_bytes_string) { + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + delete value_bytes_string_; + } + if (value_bytes_string) { + set_has_value_bytes_string(); + value_bytes_string_ = value_bytes_string; + } else { + clear_has_value_bytes_string(); + value_bytes_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// linkRequest + +// required string volume_name = 1; +inline bool linkRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void linkRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void linkRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void linkRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& linkRequest::volume_name() const { + return *volume_name_; +} +inline void linkRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void linkRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void linkRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* linkRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* linkRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void linkRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string target_path = 2; +inline bool linkRequest::has_target_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void linkRequest::set_has_target_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void linkRequest::clear_has_target_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void linkRequest::clear_target_path() { + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + target_path_->clear(); + } + clear_has_target_path(); +} +inline const ::std::string& linkRequest::target_path() const { + return *target_path_; +} +inline void linkRequest::set_target_path(const ::std::string& value) { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + target_path_->assign(value); +} +inline void linkRequest::set_target_path(const char* value) { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + target_path_->assign(value); +} +inline void linkRequest::set_target_path(const char* value, size_t size) { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + target_path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* linkRequest::mutable_target_path() { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + return target_path_; +} +inline ::std::string* linkRequest::release_target_path() { + clear_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = target_path_; + target_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void linkRequest::set_allocated_target_path(::std::string* target_path) { + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + delete target_path_; + } + if (target_path) { + set_has_target_path(); + target_path_ = target_path; + } else { + clear_has_target_path(); + target_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string link_path = 3; +inline bool linkRequest::has_link_path() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void linkRequest::set_has_link_path() { + _has_bits_[0] |= 0x00000004u; +} +inline void linkRequest::clear_has_link_path() { + _has_bits_[0] &= ~0x00000004u; +} +inline void linkRequest::clear_link_path() { + if (link_path_ != &::google::protobuf::internal::kEmptyString) { + link_path_->clear(); + } + clear_has_link_path(); +} +inline const ::std::string& linkRequest::link_path() const { + return *link_path_; +} +inline void linkRequest::set_link_path(const ::std::string& value) { + set_has_link_path(); + if (link_path_ == &::google::protobuf::internal::kEmptyString) { + link_path_ = new ::std::string; + } + link_path_->assign(value); +} +inline void linkRequest::set_link_path(const char* value) { + set_has_link_path(); + if (link_path_ == &::google::protobuf::internal::kEmptyString) { + link_path_ = new ::std::string; + } + link_path_->assign(value); +} +inline void linkRequest::set_link_path(const char* value, size_t size) { + set_has_link_path(); + if (link_path_ == &::google::protobuf::internal::kEmptyString) { + link_path_ = new ::std::string; + } + link_path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* linkRequest::mutable_link_path() { + set_has_link_path(); + if (link_path_ == &::google::protobuf::internal::kEmptyString) { + link_path_ = new ::std::string; + } + return link_path_; +} +inline ::std::string* linkRequest::release_link_path() { + clear_has_link_path(); + if (link_path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = link_path_; + link_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void linkRequest::set_allocated_link_path(::std::string* link_path) { + if (link_path_ != &::google::protobuf::internal::kEmptyString) { + delete link_path_; + } + if (link_path) { + set_has_link_path(); + link_path_ = link_path; + } else { + clear_has_link_path(); + link_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// listxattrRequest + +// required string volume_name = 1; +inline bool listxattrRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void listxattrRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void listxattrRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void listxattrRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& listxattrRequest::volume_name() const { + return *volume_name_; +} +inline void listxattrRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void listxattrRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void listxattrRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* listxattrRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* listxattrRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void listxattrRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool listxattrRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void listxattrRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void listxattrRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void listxattrRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& listxattrRequest::path() const { + return *path_; +} +inline void listxattrRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void listxattrRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void listxattrRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* listxattrRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* listxattrRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void listxattrRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required bool names_only = 3; +inline bool listxattrRequest::has_names_only() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void listxattrRequest::set_has_names_only() { + _has_bits_[0] |= 0x00000004u; +} +inline void listxattrRequest::clear_has_names_only() { + _has_bits_[0] &= ~0x00000004u; +} +inline void listxattrRequest::clear_names_only() { + names_only_ = false; + clear_has_names_only(); +} +inline bool listxattrRequest::names_only() const { + return names_only_; +} +inline void listxattrRequest::set_names_only(bool value) { + set_has_names_only(); + names_only_ = value; +} + +// ------------------------------------------------------------------- + +// listxattrResponse + +// repeated .xtreemfs.pbrpc.XAttr xattrs = 1; +inline int listxattrResponse::xattrs_size() const { + return xattrs_.size(); +} +inline void listxattrResponse::clear_xattrs() { + xattrs_.Clear(); +} +inline const ::xtreemfs::pbrpc::XAttr& listxattrResponse::xattrs(int index) const { + return xattrs_.Get(index); +} +inline ::xtreemfs::pbrpc::XAttr* listxattrResponse::mutable_xattrs(int index) { + return xattrs_.Mutable(index); +} +inline ::xtreemfs::pbrpc::XAttr* listxattrResponse::add_xattrs() { + return xattrs_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::XAttr >& +listxattrResponse::xattrs() const { + return xattrs_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::XAttr >* +listxattrResponse::mutable_xattrs() { + return &xattrs_; +} + +// ------------------------------------------------------------------- + +// mkdirRequest + +// required string volume_name = 1; +inline bool mkdirRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void mkdirRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void mkdirRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void mkdirRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& mkdirRequest::volume_name() const { + return *volume_name_; +} +inline void mkdirRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void mkdirRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void mkdirRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* mkdirRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* mkdirRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void mkdirRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool mkdirRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void mkdirRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void mkdirRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void mkdirRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& mkdirRequest::path() const { + return *path_; +} +inline void mkdirRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void mkdirRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void mkdirRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* mkdirRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* mkdirRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void mkdirRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 mode = 3; +inline bool mkdirRequest::has_mode() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void mkdirRequest::set_has_mode() { + _has_bits_[0] |= 0x00000004u; +} +inline void mkdirRequest::clear_has_mode() { + _has_bits_[0] &= ~0x00000004u; +} +inline void mkdirRequest::clear_mode() { + mode_ = 0u; + clear_has_mode(); +} +inline ::google::protobuf::uint32 mkdirRequest::mode() const { + return mode_; +} +inline void mkdirRequest::set_mode(::google::protobuf::uint32 value) { + set_has_mode(); + mode_ = value; +} + +// ------------------------------------------------------------------- + +// openRequest + +// required string volume_name = 1; +inline bool openRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void openRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void openRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void openRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& openRequest::volume_name() const { + return *volume_name_; +} +inline void openRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void openRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void openRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* openRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* openRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void openRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool openRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void openRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void openRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void openRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& openRequest::path() const { + return *path_; +} +inline void openRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void openRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void openRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* openRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* openRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void openRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 flags = 3; +inline bool openRequest::has_flags() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void openRequest::set_has_flags() { + _has_bits_[0] |= 0x00000004u; +} +inline void openRequest::clear_has_flags() { + _has_bits_[0] &= ~0x00000004u; +} +inline void openRequest::clear_flags() { + flags_ = 0u; + clear_has_flags(); +} +inline ::google::protobuf::uint32 openRequest::flags() const { + return flags_; +} +inline void openRequest::set_flags(::google::protobuf::uint32 value) { + set_has_flags(); + flags_ = value; +} + +// required fixed32 mode = 4; +inline bool openRequest::has_mode() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void openRequest::set_has_mode() { + _has_bits_[0] |= 0x00000008u; +} +inline void openRequest::clear_has_mode() { + _has_bits_[0] &= ~0x00000008u; +} +inline void openRequest::clear_mode() { + mode_ = 0u; + clear_has_mode(); +} +inline ::google::protobuf::uint32 openRequest::mode() const { + return mode_; +} +inline void openRequest::set_mode(::google::protobuf::uint32 value) { + set_has_mode(); + mode_ = value; +} + +// required fixed32 attributes = 5; +inline bool openRequest::has_attributes() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void openRequest::set_has_attributes() { + _has_bits_[0] |= 0x00000010u; +} +inline void openRequest::clear_has_attributes() { + _has_bits_[0] &= ~0x00000010u; +} +inline void openRequest::clear_attributes() { + attributes_ = 0u; + clear_has_attributes(); +} +inline ::google::protobuf::uint32 openRequest::attributes() const { + return attributes_; +} +inline void openRequest::set_attributes(::google::protobuf::uint32 value) { + set_has_attributes(); + attributes_ = value; +} + +// optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; +inline bool openRequest::has_coordinates() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void openRequest::set_has_coordinates() { + _has_bits_[0] |= 0x00000020u; +} +inline void openRequest::clear_has_coordinates() { + _has_bits_[0] &= ~0x00000020u; +} +inline void openRequest::clear_coordinates() { + if (coordinates_ != NULL) coordinates_->::xtreemfs::pbrpc::VivaldiCoordinates::Clear(); + clear_has_coordinates(); +} +inline const ::xtreemfs::pbrpc::VivaldiCoordinates& openRequest::coordinates() const { + return coordinates_ != NULL ? *coordinates_ : *default_instance_->coordinates_; +} +inline ::xtreemfs::pbrpc::VivaldiCoordinates* openRequest::mutable_coordinates() { + set_has_coordinates(); + if (coordinates_ == NULL) coordinates_ = new ::xtreemfs::pbrpc::VivaldiCoordinates; + return coordinates_; +} +inline ::xtreemfs::pbrpc::VivaldiCoordinates* openRequest::release_coordinates() { + clear_has_coordinates(); + ::xtreemfs::pbrpc::VivaldiCoordinates* temp = coordinates_; + coordinates_ = NULL; + return temp; +} +inline void openRequest::set_allocated_coordinates(::xtreemfs::pbrpc::VivaldiCoordinates* coordinates) { + delete coordinates_; + coordinates_ = coordinates; + if (coordinates) { + set_has_coordinates(); + } else { + clear_has_coordinates(); + } +} + +// ------------------------------------------------------------------- + +// openResponse + +// required .xtreemfs.pbrpc.FileCredentials creds = 1; +inline bool openResponse::has_creds() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void openResponse::set_has_creds() { + _has_bits_[0] |= 0x00000001u; +} +inline void openResponse::clear_has_creds() { + _has_bits_[0] &= ~0x00000001u; +} +inline void openResponse::clear_creds() { + if (creds_ != NULL) creds_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_creds(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& openResponse::creds() const { + return creds_ != NULL ? *creds_ : *default_instance_->creds_; +} +inline ::xtreemfs::pbrpc::FileCredentials* openResponse::mutable_creds() { + set_has_creds(); + if (creds_ == NULL) creds_ = new ::xtreemfs::pbrpc::FileCredentials; + return creds_; +} +inline ::xtreemfs::pbrpc::FileCredentials* openResponse::release_creds() { + clear_has_creds(); + ::xtreemfs::pbrpc::FileCredentials* temp = creds_; + creds_ = NULL; + return temp; +} +inline void openResponse::set_allocated_creds(::xtreemfs::pbrpc::FileCredentials* creds) { + delete creds_; + creds_ = creds; + if (creds) { + set_has_creds(); + } else { + clear_has_creds(); + } +} + +// required fixed32 timestamp_s = 2; +inline bool openResponse::has_timestamp_s() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void openResponse::set_has_timestamp_s() { + _has_bits_[0] |= 0x00000002u; +} +inline void openResponse::clear_has_timestamp_s() { + _has_bits_[0] &= ~0x00000002u; +} +inline void openResponse::clear_timestamp_s() { + timestamp_s_ = 0u; + clear_has_timestamp_s(); +} +inline ::google::protobuf::uint32 openResponse::timestamp_s() const { + return timestamp_s_; +} +inline void openResponse::set_timestamp_s(::google::protobuf::uint32 value) { + set_has_timestamp_s(); + timestamp_s_ = value; +} + +// ------------------------------------------------------------------- + +// readdirRequest + +// required string volume_name = 1; +inline bool readdirRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void readdirRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void readdirRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void readdirRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& readdirRequest::volume_name() const { + return *volume_name_; +} +inline void readdirRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void readdirRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void readdirRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* readdirRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* readdirRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void readdirRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool readdirRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void readdirRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void readdirRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void readdirRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& readdirRequest::path() const { + return *path_; +} +inline void readdirRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void readdirRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void readdirRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* readdirRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* readdirRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void readdirRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 known_etag = 3; +inline bool readdirRequest::has_known_etag() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void readdirRequest::set_has_known_etag() { + _has_bits_[0] |= 0x00000004u; +} +inline void readdirRequest::clear_has_known_etag() { + _has_bits_[0] &= ~0x00000004u; +} +inline void readdirRequest::clear_known_etag() { + known_etag_ = GOOGLE_ULONGLONG(0); + clear_has_known_etag(); +} +inline ::google::protobuf::uint64 readdirRequest::known_etag() const { + return known_etag_; +} +inline void readdirRequest::set_known_etag(::google::protobuf::uint64 value) { + set_has_known_etag(); + known_etag_ = value; +} + +// required fixed32 limit_directory_entries_count = 4; +inline bool readdirRequest::has_limit_directory_entries_count() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void readdirRequest::set_has_limit_directory_entries_count() { + _has_bits_[0] |= 0x00000008u; +} +inline void readdirRequest::clear_has_limit_directory_entries_count() { + _has_bits_[0] &= ~0x00000008u; +} +inline void readdirRequest::clear_limit_directory_entries_count() { + limit_directory_entries_count_ = 0u; + clear_has_limit_directory_entries_count(); +} +inline ::google::protobuf::uint32 readdirRequest::limit_directory_entries_count() const { + return limit_directory_entries_count_; +} +inline void readdirRequest::set_limit_directory_entries_count(::google::protobuf::uint32 value) { + set_has_limit_directory_entries_count(); + limit_directory_entries_count_ = value; +} + +// required bool names_only = 5; +inline bool readdirRequest::has_names_only() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void readdirRequest::set_has_names_only() { + _has_bits_[0] |= 0x00000010u; +} +inline void readdirRequest::clear_has_names_only() { + _has_bits_[0] &= ~0x00000010u; +} +inline void readdirRequest::clear_names_only() { + names_only_ = false; + clear_has_names_only(); +} +inline bool readdirRequest::names_only() const { + return names_only_; +} +inline void readdirRequest::set_names_only(bool value) { + set_has_names_only(); + names_only_ = value; +} + +// required fixed64 seen_directory_entries_count = 6; +inline bool readdirRequest::has_seen_directory_entries_count() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void readdirRequest::set_has_seen_directory_entries_count() { + _has_bits_[0] |= 0x00000020u; +} +inline void readdirRequest::clear_has_seen_directory_entries_count() { + _has_bits_[0] &= ~0x00000020u; +} +inline void readdirRequest::clear_seen_directory_entries_count() { + seen_directory_entries_count_ = GOOGLE_ULONGLONG(0); + clear_has_seen_directory_entries_count(); +} +inline ::google::protobuf::uint64 readdirRequest::seen_directory_entries_count() const { + return seen_directory_entries_count_; +} +inline void readdirRequest::set_seen_directory_entries_count(::google::protobuf::uint64 value) { + set_has_seen_directory_entries_count(); + seen_directory_entries_count_ = value; +} + +// ------------------------------------------------------------------- + +// readlinkRequest + +// required string volume_name = 1; +inline bool readlinkRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void readlinkRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void readlinkRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void readlinkRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& readlinkRequest::volume_name() const { + return *volume_name_; +} +inline void readlinkRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void readlinkRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void readlinkRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* readlinkRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* readlinkRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void readlinkRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool readlinkRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void readlinkRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void readlinkRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void readlinkRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& readlinkRequest::path() const { + return *path_; +} +inline void readlinkRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void readlinkRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void readlinkRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* readlinkRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* readlinkRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void readlinkRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// readlinkResponse + +// repeated string link_target_path = 1; +inline int readlinkResponse::link_target_path_size() const { + return link_target_path_.size(); +} +inline void readlinkResponse::clear_link_target_path() { + link_target_path_.Clear(); +} +inline const ::std::string& readlinkResponse::link_target_path(int index) const { + return link_target_path_.Get(index); +} +inline ::std::string* readlinkResponse::mutable_link_target_path(int index) { + return link_target_path_.Mutable(index); +} +inline void readlinkResponse::set_link_target_path(int index, const ::std::string& value) { + link_target_path_.Mutable(index)->assign(value); +} +inline void readlinkResponse::set_link_target_path(int index, const char* value) { + link_target_path_.Mutable(index)->assign(value); +} +inline void readlinkResponse::set_link_target_path(int index, const char* value, size_t size) { + link_target_path_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* readlinkResponse::add_link_target_path() { + return link_target_path_.Add(); +} +inline void readlinkResponse::add_link_target_path(const ::std::string& value) { + link_target_path_.Add()->assign(value); +} +inline void readlinkResponse::add_link_target_path(const char* value) { + link_target_path_.Add()->assign(value); +} +inline void readlinkResponse::add_link_target_path(const char* value, size_t size) { + link_target_path_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +readlinkResponse::link_target_path() const { + return link_target_path_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +readlinkResponse::mutable_link_target_path() { + return &link_target_path_; +} + +// ------------------------------------------------------------------- + +// removexattrRequest + +// required string volume_name = 1; +inline bool removexattrRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void removexattrRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void removexattrRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void removexattrRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& removexattrRequest::volume_name() const { + return *volume_name_; +} +inline void removexattrRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void removexattrRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void removexattrRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* removexattrRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* removexattrRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void removexattrRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool removexattrRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void removexattrRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void removexattrRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void removexattrRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& removexattrRequest::path() const { + return *path_; +} +inline void removexattrRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void removexattrRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void removexattrRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* removexattrRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* removexattrRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void removexattrRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string name = 3; +inline bool removexattrRequest::has_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void removexattrRequest::set_has_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void removexattrRequest::clear_has_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void removexattrRequest::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& removexattrRequest::name() const { + return *name_; +} +inline void removexattrRequest::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void removexattrRequest::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void removexattrRequest::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* removexattrRequest::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* removexattrRequest::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void removexattrRequest::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// renameRequest + +// required string volume_name = 1; +inline bool renameRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void renameRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void renameRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void renameRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& renameRequest::volume_name() const { + return *volume_name_; +} +inline void renameRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void renameRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void renameRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* renameRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* renameRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void renameRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string source_path = 2; +inline bool renameRequest::has_source_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void renameRequest::set_has_source_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void renameRequest::clear_has_source_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void renameRequest::clear_source_path() { + if (source_path_ != &::google::protobuf::internal::kEmptyString) { + source_path_->clear(); + } + clear_has_source_path(); +} +inline const ::std::string& renameRequest::source_path() const { + return *source_path_; +} +inline void renameRequest::set_source_path(const ::std::string& value) { + set_has_source_path(); + if (source_path_ == &::google::protobuf::internal::kEmptyString) { + source_path_ = new ::std::string; + } + source_path_->assign(value); +} +inline void renameRequest::set_source_path(const char* value) { + set_has_source_path(); + if (source_path_ == &::google::protobuf::internal::kEmptyString) { + source_path_ = new ::std::string; + } + source_path_->assign(value); +} +inline void renameRequest::set_source_path(const char* value, size_t size) { + set_has_source_path(); + if (source_path_ == &::google::protobuf::internal::kEmptyString) { + source_path_ = new ::std::string; + } + source_path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* renameRequest::mutable_source_path() { + set_has_source_path(); + if (source_path_ == &::google::protobuf::internal::kEmptyString) { + source_path_ = new ::std::string; + } + return source_path_; +} +inline ::std::string* renameRequest::release_source_path() { + clear_has_source_path(); + if (source_path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = source_path_; + source_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void renameRequest::set_allocated_source_path(::std::string* source_path) { + if (source_path_ != &::google::protobuf::internal::kEmptyString) { + delete source_path_; + } + if (source_path) { + set_has_source_path(); + source_path_ = source_path; + } else { + clear_has_source_path(); + source_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string target_path = 3; +inline bool renameRequest::has_target_path() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void renameRequest::set_has_target_path() { + _has_bits_[0] |= 0x00000004u; +} +inline void renameRequest::clear_has_target_path() { + _has_bits_[0] &= ~0x00000004u; +} +inline void renameRequest::clear_target_path() { + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + target_path_->clear(); + } + clear_has_target_path(); +} +inline const ::std::string& renameRequest::target_path() const { + return *target_path_; +} +inline void renameRequest::set_target_path(const ::std::string& value) { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + target_path_->assign(value); +} +inline void renameRequest::set_target_path(const char* value) { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + target_path_->assign(value); +} +inline void renameRequest::set_target_path(const char* value, size_t size) { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + target_path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* renameRequest::mutable_target_path() { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + return target_path_; +} +inline ::std::string* renameRequest::release_target_path() { + clear_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = target_path_; + target_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void renameRequest::set_allocated_target_path(::std::string* target_path) { + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + delete target_path_; + } + if (target_path) { + set_has_target_path(); + target_path_ = target_path; + } else { + clear_has_target_path(); + target_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// renameResponse + +// required fixed32 timestamp_s = 1; +inline bool renameResponse::has_timestamp_s() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void renameResponse::set_has_timestamp_s() { + _has_bits_[0] |= 0x00000001u; +} +inline void renameResponse::clear_has_timestamp_s() { + _has_bits_[0] &= ~0x00000001u; +} +inline void renameResponse::clear_timestamp_s() { + timestamp_s_ = 0u; + clear_has_timestamp_s(); +} +inline ::google::protobuf::uint32 renameResponse::timestamp_s() const { + return timestamp_s_; +} +inline void renameResponse::set_timestamp_s(::google::protobuf::uint32 value) { + set_has_timestamp_s(); + timestamp_s_ = value; +} + +// optional .xtreemfs.pbrpc.FileCredentials creds = 2; +inline bool renameResponse::has_creds() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void renameResponse::set_has_creds() { + _has_bits_[0] |= 0x00000002u; +} +inline void renameResponse::clear_has_creds() { + _has_bits_[0] &= ~0x00000002u; +} +inline void renameResponse::clear_creds() { + if (creds_ != NULL) creds_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_creds(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& renameResponse::creds() const { + return creds_ != NULL ? *creds_ : *default_instance_->creds_; +} +inline ::xtreemfs::pbrpc::FileCredentials* renameResponse::mutable_creds() { + set_has_creds(); + if (creds_ == NULL) creds_ = new ::xtreemfs::pbrpc::FileCredentials; + return creds_; +} +inline ::xtreemfs::pbrpc::FileCredentials* renameResponse::release_creds() { + clear_has_creds(); + ::xtreemfs::pbrpc::FileCredentials* temp = creds_; + creds_ = NULL; + return temp; +} +inline void renameResponse::set_allocated_creds(::xtreemfs::pbrpc::FileCredentials* creds) { + delete creds_; + creds_ = creds; + if (creds) { + set_has_creds(); + } else { + clear_has_creds(); + } +} + +// ------------------------------------------------------------------- + +// rmdirRequest + +// required string volume_name = 1; +inline bool rmdirRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void rmdirRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void rmdirRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void rmdirRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& rmdirRequest::volume_name() const { + return *volume_name_; +} +inline void rmdirRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void rmdirRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void rmdirRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* rmdirRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* rmdirRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void rmdirRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool rmdirRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void rmdirRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void rmdirRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void rmdirRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& rmdirRequest::path() const { + return *path_; +} +inline void rmdirRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void rmdirRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void rmdirRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* rmdirRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* rmdirRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void rmdirRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// setattrRequest + +// required string volume_name = 1; +inline bool setattrRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void setattrRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void setattrRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void setattrRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& setattrRequest::volume_name() const { + return *volume_name_; +} +inline void setattrRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void setattrRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void setattrRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* setattrRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* setattrRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void setattrRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool setattrRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void setattrRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void setattrRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void setattrRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& setattrRequest::path() const { + return *path_; +} +inline void setattrRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void setattrRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void setattrRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* setattrRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* setattrRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void setattrRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required .xtreemfs.pbrpc.Stat stbuf = 3; +inline bool setattrRequest::has_stbuf() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void setattrRequest::set_has_stbuf() { + _has_bits_[0] |= 0x00000004u; +} +inline void setattrRequest::clear_has_stbuf() { + _has_bits_[0] &= ~0x00000004u; +} +inline void setattrRequest::clear_stbuf() { + if (stbuf_ != NULL) stbuf_->::xtreemfs::pbrpc::Stat::Clear(); + clear_has_stbuf(); +} +inline const ::xtreemfs::pbrpc::Stat& setattrRequest::stbuf() const { + return stbuf_ != NULL ? *stbuf_ : *default_instance_->stbuf_; +} +inline ::xtreemfs::pbrpc::Stat* setattrRequest::mutable_stbuf() { + set_has_stbuf(); + if (stbuf_ == NULL) stbuf_ = new ::xtreemfs::pbrpc::Stat; + return stbuf_; +} +inline ::xtreemfs::pbrpc::Stat* setattrRequest::release_stbuf() { + clear_has_stbuf(); + ::xtreemfs::pbrpc::Stat* temp = stbuf_; + stbuf_ = NULL; + return temp; +} +inline void setattrRequest::set_allocated_stbuf(::xtreemfs::pbrpc::Stat* stbuf) { + delete stbuf_; + stbuf_ = stbuf; + if (stbuf) { + set_has_stbuf(); + } else { + clear_has_stbuf(); + } +} + +// required fixed32 to_set = 4; +inline bool setattrRequest::has_to_set() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void setattrRequest::set_has_to_set() { + _has_bits_[0] |= 0x00000008u; +} +inline void setattrRequest::clear_has_to_set() { + _has_bits_[0] &= ~0x00000008u; +} +inline void setattrRequest::clear_to_set() { + to_set_ = 0u; + clear_has_to_set(); +} +inline ::google::protobuf::uint32 setattrRequest::to_set() const { + return to_set_; +} +inline void setattrRequest::set_to_set(::google::protobuf::uint32 value) { + set_has_to_set(); + to_set_ = value; +} + +// ------------------------------------------------------------------- + +// setxattrRequest + +// required string volume_name = 1; +inline bool setxattrRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void setxattrRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void setxattrRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void setxattrRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& setxattrRequest::volume_name() const { + return *volume_name_; +} +inline void setxattrRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void setxattrRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void setxattrRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* setxattrRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* setxattrRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void setxattrRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool setxattrRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void setxattrRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void setxattrRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void setxattrRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& setxattrRequest::path() const { + return *path_; +} +inline void setxattrRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void setxattrRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void setxattrRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* setxattrRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* setxattrRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void setxattrRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string name = 3; +inline bool setxattrRequest::has_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void setxattrRequest::set_has_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void setxattrRequest::clear_has_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void setxattrRequest::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& setxattrRequest::name() const { + return *name_; +} +inline void setxattrRequest::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void setxattrRequest::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void setxattrRequest::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* setxattrRequest::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* setxattrRequest::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void setxattrRequest::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string value = 4; +inline bool setxattrRequest::has_value() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void setxattrRequest::set_has_value() { + _has_bits_[0] |= 0x00000008u; +} +inline void setxattrRequest::clear_has_value() { + _has_bits_[0] &= ~0x00000008u; +} +inline void setxattrRequest::clear_value() { + if (value_ != &::google::protobuf::internal::kEmptyString) { + value_->clear(); + } + clear_has_value(); +} +inline const ::std::string& setxattrRequest::value() const { + return *value_; +} +inline void setxattrRequest::set_value(const ::std::string& value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(value); +} +inline void setxattrRequest::set_value(const char* value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(value); +} +inline void setxattrRequest::set_value(const char* value, size_t size) { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + value_->assign(reinterpret_cast(value), size); +} +inline ::std::string* setxattrRequest::mutable_value() { + set_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + value_ = new ::std::string; + } + return value_; +} +inline ::std::string* setxattrRequest::release_value() { + clear_has_value(); + if (value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = value_; + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void setxattrRequest::set_allocated_value(::std::string* value) { + if (value_ != &::google::protobuf::internal::kEmptyString) { + delete value_; + } + if (value) { + set_has_value(); + value_ = value; + } else { + clear_has_value(); + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional bytes value_bytes_string = 6; +inline bool setxattrRequest::has_value_bytes_string() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void setxattrRequest::set_has_value_bytes_string() { + _has_bits_[0] |= 0x00000010u; +} +inline void setxattrRequest::clear_has_value_bytes_string() { + _has_bits_[0] &= ~0x00000010u; +} +inline void setxattrRequest::clear_value_bytes_string() { + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + value_bytes_string_->clear(); + } + clear_has_value_bytes_string(); +} +inline const ::std::string& setxattrRequest::value_bytes_string() const { + return *value_bytes_string_; +} +inline void setxattrRequest::set_value_bytes_string(const ::std::string& value) { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + value_bytes_string_->assign(value); +} +inline void setxattrRequest::set_value_bytes_string(const char* value) { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + value_bytes_string_->assign(value); +} +inline void setxattrRequest::set_value_bytes_string(const void* value, size_t size) { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + value_bytes_string_->assign(reinterpret_cast(value), size); +} +inline ::std::string* setxattrRequest::mutable_value_bytes_string() { + set_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + value_bytes_string_ = new ::std::string; + } + return value_bytes_string_; +} +inline ::std::string* setxattrRequest::release_value_bytes_string() { + clear_has_value_bytes_string(); + if (value_bytes_string_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = value_bytes_string_; + value_bytes_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void setxattrRequest::set_allocated_value_bytes_string(::std::string* value_bytes_string) { + if (value_bytes_string_ != &::google::protobuf::internal::kEmptyString) { + delete value_bytes_string_; + } + if (value_bytes_string) { + set_has_value_bytes_string(); + value_bytes_string_ = value_bytes_string; + } else { + clear_has_value_bytes_string(); + value_bytes_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 flags = 5; +inline bool setxattrRequest::has_flags() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void setxattrRequest::set_has_flags() { + _has_bits_[0] |= 0x00000020u; +} +inline void setxattrRequest::clear_has_flags() { + _has_bits_[0] &= ~0x00000020u; +} +inline void setxattrRequest::clear_flags() { + flags_ = 0u; + clear_has_flags(); +} +inline ::google::protobuf::uint32 setxattrRequest::flags() const { + return flags_; +} +inline void setxattrRequest::set_flags(::google::protobuf::uint32 value) { + set_has_flags(); + flags_ = value; +} + +// ------------------------------------------------------------------- + +// statvfsRequest + +// required string volume_name = 1; +inline bool statvfsRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void statvfsRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void statvfsRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void statvfsRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& statvfsRequest::volume_name() const { + return *volume_name_; +} +inline void statvfsRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void statvfsRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void statvfsRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* statvfsRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* statvfsRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void statvfsRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 known_etag = 5; +inline bool statvfsRequest::has_known_etag() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void statvfsRequest::set_has_known_etag() { + _has_bits_[0] |= 0x00000002u; +} +inline void statvfsRequest::clear_has_known_etag() { + _has_bits_[0] &= ~0x00000002u; +} +inline void statvfsRequest::clear_known_etag() { + known_etag_ = GOOGLE_ULONGLONG(0); + clear_has_known_etag(); +} +inline ::google::protobuf::uint64 statvfsRequest::known_etag() const { + return known_etag_; +} +inline void statvfsRequest::set_known_etag(::google::protobuf::uint64 value) { + set_has_known_etag(); + known_etag_ = value; +} + +// ------------------------------------------------------------------- + +// symlinkRequest + +// required string volume_name = 1; +inline bool symlinkRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void symlinkRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void symlinkRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void symlinkRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& symlinkRequest::volume_name() const { + return *volume_name_; +} +inline void symlinkRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void symlinkRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void symlinkRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* symlinkRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* symlinkRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void symlinkRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string target_path = 2; +inline bool symlinkRequest::has_target_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void symlinkRequest::set_has_target_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void symlinkRequest::clear_has_target_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void symlinkRequest::clear_target_path() { + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + target_path_->clear(); + } + clear_has_target_path(); +} +inline const ::std::string& symlinkRequest::target_path() const { + return *target_path_; +} +inline void symlinkRequest::set_target_path(const ::std::string& value) { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + target_path_->assign(value); +} +inline void symlinkRequest::set_target_path(const char* value) { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + target_path_->assign(value); +} +inline void symlinkRequest::set_target_path(const char* value, size_t size) { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + target_path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* symlinkRequest::mutable_target_path() { + set_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + target_path_ = new ::std::string; + } + return target_path_; +} +inline ::std::string* symlinkRequest::release_target_path() { + clear_has_target_path(); + if (target_path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = target_path_; + target_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void symlinkRequest::set_allocated_target_path(::std::string* target_path) { + if (target_path_ != &::google::protobuf::internal::kEmptyString) { + delete target_path_; + } + if (target_path) { + set_has_target_path(); + target_path_ = target_path; + } else { + clear_has_target_path(); + target_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string link_path = 3; +inline bool symlinkRequest::has_link_path() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void symlinkRequest::set_has_link_path() { + _has_bits_[0] |= 0x00000004u; +} +inline void symlinkRequest::clear_has_link_path() { + _has_bits_[0] &= ~0x00000004u; +} +inline void symlinkRequest::clear_link_path() { + if (link_path_ != &::google::protobuf::internal::kEmptyString) { + link_path_->clear(); + } + clear_has_link_path(); +} +inline const ::std::string& symlinkRequest::link_path() const { + return *link_path_; +} +inline void symlinkRequest::set_link_path(const ::std::string& value) { + set_has_link_path(); + if (link_path_ == &::google::protobuf::internal::kEmptyString) { + link_path_ = new ::std::string; + } + link_path_->assign(value); +} +inline void symlinkRequest::set_link_path(const char* value) { + set_has_link_path(); + if (link_path_ == &::google::protobuf::internal::kEmptyString) { + link_path_ = new ::std::string; + } + link_path_->assign(value); +} +inline void symlinkRequest::set_link_path(const char* value, size_t size) { + set_has_link_path(); + if (link_path_ == &::google::protobuf::internal::kEmptyString) { + link_path_ = new ::std::string; + } + link_path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* symlinkRequest::mutable_link_path() { + set_has_link_path(); + if (link_path_ == &::google::protobuf::internal::kEmptyString) { + link_path_ = new ::std::string; + } + return link_path_; +} +inline ::std::string* symlinkRequest::release_link_path() { + clear_has_link_path(); + if (link_path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = link_path_; + link_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void symlinkRequest::set_allocated_link_path(::std::string* link_path) { + if (link_path_ != &::google::protobuf::internal::kEmptyString) { + delete link_path_; + } + if (link_path) { + set_has_link_path(); + link_path_ = link_path; + } else { + clear_has_link_path(); + link_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// unlinkRequest + +// required string volume_name = 1; +inline bool unlinkRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void unlinkRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void unlinkRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void unlinkRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& unlinkRequest::volume_name() const { + return *volume_name_; +} +inline void unlinkRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void unlinkRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void unlinkRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* unlinkRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* unlinkRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void unlinkRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool unlinkRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void unlinkRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void unlinkRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void unlinkRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& unlinkRequest::path() const { + return *path_; +} +inline void unlinkRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void unlinkRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void unlinkRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* unlinkRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* unlinkRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void unlinkRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// unlinkResponse + +// required fixed32 timestamp_s = 1; +inline bool unlinkResponse::has_timestamp_s() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void unlinkResponse::set_has_timestamp_s() { + _has_bits_[0] |= 0x00000001u; +} +inline void unlinkResponse::clear_has_timestamp_s() { + _has_bits_[0] &= ~0x00000001u; +} +inline void unlinkResponse::clear_timestamp_s() { + timestamp_s_ = 0u; + clear_has_timestamp_s(); +} +inline ::google::protobuf::uint32 unlinkResponse::timestamp_s() const { + return timestamp_s_; +} +inline void unlinkResponse::set_timestamp_s(::google::protobuf::uint32 value) { + set_has_timestamp_s(); + timestamp_s_ = value; +} + +// optional .xtreemfs.pbrpc.FileCredentials creds = 2; +inline bool unlinkResponse::has_creds() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void unlinkResponse::set_has_creds() { + _has_bits_[0] |= 0x00000002u; +} +inline void unlinkResponse::clear_has_creds() { + _has_bits_[0] &= ~0x00000002u; +} +inline void unlinkResponse::clear_creds() { + if (creds_ != NULL) creds_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_creds(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& unlinkResponse::creds() const { + return creds_ != NULL ? *creds_ : *default_instance_->creds_; +} +inline ::xtreemfs::pbrpc::FileCredentials* unlinkResponse::mutable_creds() { + set_has_creds(); + if (creds_ == NULL) creds_ = new ::xtreemfs::pbrpc::FileCredentials; + return creds_; +} +inline ::xtreemfs::pbrpc::FileCredentials* unlinkResponse::release_creds() { + clear_has_creds(); + ::xtreemfs::pbrpc::FileCredentials* temp = creds_; + creds_ = NULL; + return temp; +} +inline void unlinkResponse::set_allocated_creds(::xtreemfs::pbrpc::FileCredentials* creds) { + delete creds_; + creds_ = creds; + if (creds) { + set_has_creds(); + } else { + clear_has_creds(); + } +} + +// ------------------------------------------------------------------- + +// accessRequest + +// required string volume_name = 1; +inline bool accessRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void accessRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void accessRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void accessRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& accessRequest::volume_name() const { + return *volume_name_; +} +inline void accessRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void accessRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void accessRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* accessRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* accessRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void accessRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string path = 2; +inline bool accessRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void accessRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void accessRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void accessRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& accessRequest::path() const { + return *path_; +} +inline void accessRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void accessRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void accessRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* accessRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* accessRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void accessRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 flags = 3; +inline bool accessRequest::has_flags() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void accessRequest::set_has_flags() { + _has_bits_[0] |= 0x00000004u; +} +inline void accessRequest::clear_has_flags() { + _has_bits_[0] &= ~0x00000004u; +} +inline void accessRequest::clear_flags() { + flags_ = 0u; + clear_has_flags(); +} +inline ::google::protobuf::uint32 accessRequest::flags() const { + return flags_; +} +inline void accessRequest::set_flags(::google::protobuf::uint32 value) { + set_has_flags(); + flags_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_check_file_existsRequest + +// required string volume_id = 1; +inline bool xtreemfs_check_file_existsRequest::has_volume_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_check_file_existsRequest::set_has_volume_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_check_file_existsRequest::clear_has_volume_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_check_file_existsRequest::clear_volume_id() { + if (volume_id_ != &::google::protobuf::internal::kEmptyString) { + volume_id_->clear(); + } + clear_has_volume_id(); +} +inline const ::std::string& xtreemfs_check_file_existsRequest::volume_id() const { + return *volume_id_; +} +inline void xtreemfs_check_file_existsRequest::set_volume_id(const ::std::string& value) { + set_has_volume_id(); + if (volume_id_ == &::google::protobuf::internal::kEmptyString) { + volume_id_ = new ::std::string; + } + volume_id_->assign(value); +} +inline void xtreemfs_check_file_existsRequest::set_volume_id(const char* value) { + set_has_volume_id(); + if (volume_id_ == &::google::protobuf::internal::kEmptyString) { + volume_id_ = new ::std::string; + } + volume_id_->assign(value); +} +inline void xtreemfs_check_file_existsRequest::set_volume_id(const char* value, size_t size) { + set_has_volume_id(); + if (volume_id_ == &::google::protobuf::internal::kEmptyString) { + volume_id_ = new ::std::string; + } + volume_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_check_file_existsRequest::mutable_volume_id() { + set_has_volume_id(); + if (volume_id_ == &::google::protobuf::internal::kEmptyString) { + volume_id_ = new ::std::string; + } + return volume_id_; +} +inline ::std::string* xtreemfs_check_file_existsRequest::release_volume_id() { + clear_has_volume_id(); + if (volume_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_id_; + volume_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_check_file_existsRequest::set_allocated_volume_id(::std::string* volume_id) { + if (volume_id_ != &::google::protobuf::internal::kEmptyString) { + delete volume_id_; + } + if (volume_id) { + set_has_volume_id(); + volume_id_ = volume_id; + } else { + clear_has_volume_id(); + volume_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// repeated string file_ids = 2; +inline int xtreemfs_check_file_existsRequest::file_ids_size() const { + return file_ids_.size(); +} +inline void xtreemfs_check_file_existsRequest::clear_file_ids() { + file_ids_.Clear(); +} +inline const ::std::string& xtreemfs_check_file_existsRequest::file_ids(int index) const { + return file_ids_.Get(index); +} +inline ::std::string* xtreemfs_check_file_existsRequest::mutable_file_ids(int index) { + return file_ids_.Mutable(index); +} +inline void xtreemfs_check_file_existsRequest::set_file_ids(int index, const ::std::string& value) { + file_ids_.Mutable(index)->assign(value); +} +inline void xtreemfs_check_file_existsRequest::set_file_ids(int index, const char* value) { + file_ids_.Mutable(index)->assign(value); +} +inline void xtreemfs_check_file_existsRequest::set_file_ids(int index, const char* value, size_t size) { + file_ids_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_check_file_existsRequest::add_file_ids() { + return file_ids_.Add(); +} +inline void xtreemfs_check_file_existsRequest::add_file_ids(const ::std::string& value) { + file_ids_.Add()->assign(value); +} +inline void xtreemfs_check_file_existsRequest::add_file_ids(const char* value) { + file_ids_.Add()->assign(value); +} +inline void xtreemfs_check_file_existsRequest::add_file_ids(const char* value, size_t size) { + file_ids_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +xtreemfs_check_file_existsRequest::file_ids() const { + return file_ids_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +xtreemfs_check_file_existsRequest::mutable_file_ids() { + return &file_ids_; +} + +// required string osd_uuid = 3; +inline bool xtreemfs_check_file_existsRequest::has_osd_uuid() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_check_file_existsRequest::set_has_osd_uuid() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_check_file_existsRequest::clear_has_osd_uuid() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_check_file_existsRequest::clear_osd_uuid() { + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + osd_uuid_->clear(); + } + clear_has_osd_uuid(); +} +inline const ::std::string& xtreemfs_check_file_existsRequest::osd_uuid() const { + return *osd_uuid_; +} +inline void xtreemfs_check_file_existsRequest::set_osd_uuid(const ::std::string& value) { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + osd_uuid_->assign(value); +} +inline void xtreemfs_check_file_existsRequest::set_osd_uuid(const char* value) { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + osd_uuid_->assign(value); +} +inline void xtreemfs_check_file_existsRequest::set_osd_uuid(const char* value, size_t size) { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + osd_uuid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_check_file_existsRequest::mutable_osd_uuid() { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + return osd_uuid_; +} +inline ::std::string* xtreemfs_check_file_existsRequest::release_osd_uuid() { + clear_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = osd_uuid_; + osd_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_check_file_existsRequest::set_allocated_osd_uuid(::std::string* osd_uuid) { + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + delete osd_uuid_; + } + if (osd_uuid) { + set_has_osd_uuid(); + osd_uuid_ = osd_uuid; + } else { + clear_has_osd_uuid(); + osd_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_check_file_existsResponse + +// required bool volume_exists = 1; +inline bool xtreemfs_check_file_existsResponse::has_volume_exists() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_check_file_existsResponse::set_has_volume_exists() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_check_file_existsResponse::clear_has_volume_exists() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_check_file_existsResponse::clear_volume_exists() { + volume_exists_ = false; + clear_has_volume_exists(); +} +inline bool xtreemfs_check_file_existsResponse::volume_exists() const { + return volume_exists_; +} +inline void xtreemfs_check_file_existsResponse::set_volume_exists(bool value) { + set_has_volume_exists(); + volume_exists_ = value; +} + +// repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; +inline int xtreemfs_check_file_existsResponse::file_states_size() const { + return file_states_.size(); +} +inline void xtreemfs_check_file_existsResponse::clear_file_states() { + file_states_.Clear(); +} +inline ::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE xtreemfs_check_file_existsResponse::file_states(int index) const { + return static_cast< ::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE >(file_states_.Get(index)); +} +inline void xtreemfs_check_file_existsResponse::set_file_states(int index, ::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE value) { + assert(::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE_IsValid(value)); + file_states_.Set(index, value); +} +inline void xtreemfs_check_file_existsResponse::add_file_states(::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE value) { + assert(::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE_IsValid(value)); + file_states_.Add(value); +} +inline const ::google::protobuf::RepeatedField& +xtreemfs_check_file_existsResponse::file_states() const { + return file_states_; +} +inline ::google::protobuf::RepeatedField* +xtreemfs_check_file_existsResponse::mutable_file_states() { + return &file_states_; +} + +// ------------------------------------------------------------------- + +// xtreemfs_dump_restore_databaseRequest + +// required string dump_file = 1; +inline bool xtreemfs_dump_restore_databaseRequest::has_dump_file() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_dump_restore_databaseRequest::set_has_dump_file() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_dump_restore_databaseRequest::clear_has_dump_file() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_dump_restore_databaseRequest::clear_dump_file() { + if (dump_file_ != &::google::protobuf::internal::kEmptyString) { + dump_file_->clear(); + } + clear_has_dump_file(); +} +inline const ::std::string& xtreemfs_dump_restore_databaseRequest::dump_file() const { + return *dump_file_; +} +inline void xtreemfs_dump_restore_databaseRequest::set_dump_file(const ::std::string& value) { + set_has_dump_file(); + if (dump_file_ == &::google::protobuf::internal::kEmptyString) { + dump_file_ = new ::std::string; + } + dump_file_->assign(value); +} +inline void xtreemfs_dump_restore_databaseRequest::set_dump_file(const char* value) { + set_has_dump_file(); + if (dump_file_ == &::google::protobuf::internal::kEmptyString) { + dump_file_ = new ::std::string; + } + dump_file_->assign(value); +} +inline void xtreemfs_dump_restore_databaseRequest::set_dump_file(const char* value, size_t size) { + set_has_dump_file(); + if (dump_file_ == &::google::protobuf::internal::kEmptyString) { + dump_file_ = new ::std::string; + } + dump_file_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_dump_restore_databaseRequest::mutable_dump_file() { + set_has_dump_file(); + if (dump_file_ == &::google::protobuf::internal::kEmptyString) { + dump_file_ = new ::std::string; + } + return dump_file_; +} +inline ::std::string* xtreemfs_dump_restore_databaseRequest::release_dump_file() { + clear_has_dump_file(); + if (dump_file_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = dump_file_; + dump_file_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_dump_restore_databaseRequest::set_allocated_dump_file(::std::string* dump_file) { + if (dump_file_ != &::google::protobuf::internal::kEmptyString) { + delete dump_file_; + } + if (dump_file) { + set_has_dump_file(); + dump_file_ = dump_file; + } else { + clear_has_dump_file(); + dump_file_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_get_suitable_osdsRequest + +// optional string file_id = 1; +inline bool xtreemfs_get_suitable_osdsRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_get_suitable_osdsRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_get_suitable_osdsRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_get_suitable_osdsRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_get_suitable_osdsRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_get_suitable_osdsRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_get_suitable_osdsRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_get_suitable_osdsRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_get_suitable_osdsRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_get_suitable_osdsRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_get_suitable_osdsRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string path = 3; +inline bool xtreemfs_get_suitable_osdsRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_get_suitable_osdsRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_get_suitable_osdsRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_get_suitable_osdsRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& xtreemfs_get_suitable_osdsRequest::path() const { + return *path_; +} +inline void xtreemfs_get_suitable_osdsRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_get_suitable_osdsRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_get_suitable_osdsRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_get_suitable_osdsRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* xtreemfs_get_suitable_osdsRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_get_suitable_osdsRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string volume_name = 4; +inline bool xtreemfs_get_suitable_osdsRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_get_suitable_osdsRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_get_suitable_osdsRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_get_suitable_osdsRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& xtreemfs_get_suitable_osdsRequest::volume_name() const { + return *volume_name_; +} +inline void xtreemfs_get_suitable_osdsRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_get_suitable_osdsRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_get_suitable_osdsRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_get_suitable_osdsRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* xtreemfs_get_suitable_osdsRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_get_suitable_osdsRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 num_osds = 2; +inline bool xtreemfs_get_suitable_osdsRequest::has_num_osds() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_get_suitable_osdsRequest::set_has_num_osds() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_get_suitable_osdsRequest::clear_has_num_osds() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_get_suitable_osdsRequest::clear_num_osds() { + num_osds_ = 0u; + clear_has_num_osds(); +} +inline ::google::protobuf::uint32 xtreemfs_get_suitable_osdsRequest::num_osds() const { + return num_osds_; +} +inline void xtreemfs_get_suitable_osdsRequest::set_num_osds(::google::protobuf::uint32 value) { + set_has_num_osds(); + num_osds_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_get_suitable_osdsResponse + +// repeated string osd_uuids = 1; +inline int xtreemfs_get_suitable_osdsResponse::osd_uuids_size() const { + return osd_uuids_.size(); +} +inline void xtreemfs_get_suitable_osdsResponse::clear_osd_uuids() { + osd_uuids_.Clear(); +} +inline const ::std::string& xtreemfs_get_suitable_osdsResponse::osd_uuids(int index) const { + return osd_uuids_.Get(index); +} +inline ::std::string* xtreemfs_get_suitable_osdsResponse::mutable_osd_uuids(int index) { + return osd_uuids_.Mutable(index); +} +inline void xtreemfs_get_suitable_osdsResponse::set_osd_uuids(int index, const ::std::string& value) { + osd_uuids_.Mutable(index)->assign(value); +} +inline void xtreemfs_get_suitable_osdsResponse::set_osd_uuids(int index, const char* value) { + osd_uuids_.Mutable(index)->assign(value); +} +inline void xtreemfs_get_suitable_osdsResponse::set_osd_uuids(int index, const char* value, size_t size) { + osd_uuids_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_get_suitable_osdsResponse::add_osd_uuids() { + return osd_uuids_.Add(); +} +inline void xtreemfs_get_suitable_osdsResponse::add_osd_uuids(const ::std::string& value) { + osd_uuids_.Add()->assign(value); +} +inline void xtreemfs_get_suitable_osdsResponse::add_osd_uuids(const char* value) { + osd_uuids_.Add()->assign(value); +} +inline void xtreemfs_get_suitable_osdsResponse::add_osd_uuids(const char* value, size_t size) { + osd_uuids_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +xtreemfs_get_suitable_osdsResponse::osd_uuids() const { + return osd_uuids_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +xtreemfs_get_suitable_osdsResponse::mutable_osd_uuids() { + return &osd_uuids_; +} + +// ------------------------------------------------------------------- + +// timestampResponse + +// required fixed32 timestamp_s = 1; +inline bool timestampResponse::has_timestamp_s() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void timestampResponse::set_has_timestamp_s() { + _has_bits_[0] |= 0x00000001u; +} +inline void timestampResponse::clear_has_timestamp_s() { + _has_bits_[0] &= ~0x00000001u; +} +inline void timestampResponse::clear_timestamp_s() { + timestamp_s_ = 0u; + clear_has_timestamp_s(); +} +inline ::google::protobuf::uint32 timestampResponse::timestamp_s() const { + return timestamp_s_; +} +inline void timestampResponse::set_timestamp_s(::google::protobuf::uint32 value) { + set_has_timestamp_s(); + timestamp_s_ = value; +} + +// ------------------------------------------------------------------- + +// stringMessage + +// required string a_string = 1; +inline bool stringMessage::has_a_string() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void stringMessage::set_has_a_string() { + _has_bits_[0] |= 0x00000001u; +} +inline void stringMessage::clear_has_a_string() { + _has_bits_[0] &= ~0x00000001u; +} +inline void stringMessage::clear_a_string() { + if (a_string_ != &::google::protobuf::internal::kEmptyString) { + a_string_->clear(); + } + clear_has_a_string(); +} +inline const ::std::string& stringMessage::a_string() const { + return *a_string_; +} +inline void stringMessage::set_a_string(const ::std::string& value) { + set_has_a_string(); + if (a_string_ == &::google::protobuf::internal::kEmptyString) { + a_string_ = new ::std::string; + } + a_string_->assign(value); +} +inline void stringMessage::set_a_string(const char* value) { + set_has_a_string(); + if (a_string_ == &::google::protobuf::internal::kEmptyString) { + a_string_ = new ::std::string; + } + a_string_->assign(value); +} +inline void stringMessage::set_a_string(const char* value, size_t size) { + set_has_a_string(); + if (a_string_ == &::google::protobuf::internal::kEmptyString) { + a_string_ = new ::std::string; + } + a_string_->assign(reinterpret_cast(value), size); +} +inline ::std::string* stringMessage::mutable_a_string() { + set_has_a_string(); + if (a_string_ == &::google::protobuf::internal::kEmptyString) { + a_string_ = new ::std::string; + } + return a_string_; +} +inline ::std::string* stringMessage::release_a_string() { + clear_has_a_string(); + if (a_string_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = a_string_; + a_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void stringMessage::set_allocated_a_string(::std::string* a_string) { + if (a_string_ != &::google::protobuf::internal::kEmptyString) { + delete a_string_; + } + if (a_string) { + set_has_a_string(); + a_string_ = a_string; + } else { + clear_has_a_string(); + a_string_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_listdirRequest + +// required string path = 1; +inline bool xtreemfs_listdirRequest::has_path() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_listdirRequest::set_has_path() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_listdirRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_listdirRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& xtreemfs_listdirRequest::path() const { + return *path_; +} +inline void xtreemfs_listdirRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_listdirRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_listdirRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_listdirRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* xtreemfs_listdirRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_listdirRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_listdirResponse + +// repeated string names = 1; +inline int xtreemfs_listdirResponse::names_size() const { + return names_.size(); +} +inline void xtreemfs_listdirResponse::clear_names() { + names_.Clear(); +} +inline const ::std::string& xtreemfs_listdirResponse::names(int index) const { + return names_.Get(index); +} +inline ::std::string* xtreemfs_listdirResponse::mutable_names(int index) { + return names_.Mutable(index); +} +inline void xtreemfs_listdirResponse::set_names(int index, const ::std::string& value) { + names_.Mutable(index)->assign(value); +} +inline void xtreemfs_listdirResponse::set_names(int index, const char* value) { + names_.Mutable(index)->assign(value); +} +inline void xtreemfs_listdirResponse::set_names(int index, const char* value, size_t size) { + names_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_listdirResponse::add_names() { + return names_.Add(); +} +inline void xtreemfs_listdirResponse::add_names(const ::std::string& value) { + names_.Add()->assign(value); +} +inline void xtreemfs_listdirResponse::add_names(const char* value) { + names_.Add()->assign(value); +} +inline void xtreemfs_listdirResponse::add_names(const char* value, size_t size) { + names_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +xtreemfs_listdirResponse::names() const { + return names_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +xtreemfs_listdirResponse::mutable_names() { + return &names_; +} + +// ------------------------------------------------------------------- + +// xtreemfs_replica_addRequest + +// optional string file_id = 1; +inline bool xtreemfs_replica_addRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_replica_addRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_replica_addRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_replica_addRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_replica_addRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_replica_addRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_replica_addRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_replica_addRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_replica_addRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_replica_addRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_replica_addRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string path = 3; +inline bool xtreemfs_replica_addRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_replica_addRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_replica_addRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_replica_addRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& xtreemfs_replica_addRequest::path() const { + return *path_; +} +inline void xtreemfs_replica_addRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_replica_addRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_replica_addRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_replica_addRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* xtreemfs_replica_addRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_replica_addRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string volume_name = 4; +inline bool xtreemfs_replica_addRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_replica_addRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_replica_addRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_replica_addRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& xtreemfs_replica_addRequest::volume_name() const { + return *volume_name_; +} +inline void xtreemfs_replica_addRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_replica_addRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_replica_addRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_replica_addRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* xtreemfs_replica_addRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_replica_addRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required .xtreemfs.pbrpc.Replica new_replica = 2; +inline bool xtreemfs_replica_addRequest::has_new_replica() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_replica_addRequest::set_has_new_replica() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_replica_addRequest::clear_has_new_replica() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_replica_addRequest::clear_new_replica() { + if (new_replica_ != NULL) new_replica_->::xtreemfs::pbrpc::Replica::Clear(); + clear_has_new_replica(); +} +inline const ::xtreemfs::pbrpc::Replica& xtreemfs_replica_addRequest::new_replica() const { + return new_replica_ != NULL ? *new_replica_ : *default_instance_->new_replica_; +} +inline ::xtreemfs::pbrpc::Replica* xtreemfs_replica_addRequest::mutable_new_replica() { + set_has_new_replica(); + if (new_replica_ == NULL) new_replica_ = new ::xtreemfs::pbrpc::Replica; + return new_replica_; +} +inline ::xtreemfs::pbrpc::Replica* xtreemfs_replica_addRequest::release_new_replica() { + clear_has_new_replica(); + ::xtreemfs::pbrpc::Replica* temp = new_replica_; + new_replica_ = NULL; + return temp; +} +inline void xtreemfs_replica_addRequest::set_allocated_new_replica(::xtreemfs::pbrpc::Replica* new_replica) { + delete new_replica_; + new_replica_ = new_replica; + if (new_replica) { + set_has_new_replica(); + } else { + clear_has_new_replica(); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_replica_listRequest + +// optional string file_id = 1; +inline bool xtreemfs_replica_listRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_replica_listRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_replica_listRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_replica_listRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_replica_listRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_replica_listRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_replica_listRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_replica_listRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_replica_listRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_replica_listRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_replica_listRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string path = 2; +inline bool xtreemfs_replica_listRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_replica_listRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_replica_listRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_replica_listRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& xtreemfs_replica_listRequest::path() const { + return *path_; +} +inline void xtreemfs_replica_listRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_replica_listRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_replica_listRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_replica_listRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* xtreemfs_replica_listRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_replica_listRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string volume_name = 3; +inline bool xtreemfs_replica_listRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_replica_listRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_replica_listRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_replica_listRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& xtreemfs_replica_listRequest::volume_name() const { + return *volume_name_; +} +inline void xtreemfs_replica_listRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_replica_listRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_replica_listRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_replica_listRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* xtreemfs_replica_listRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_replica_listRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_get_xlocsetRequest + +// optional string file_id = 1; +inline bool xtreemfs_get_xlocsetRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_get_xlocsetRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_get_xlocsetRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_get_xlocsetRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_get_xlocsetRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_get_xlocsetRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_get_xlocsetRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_get_xlocsetRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_get_xlocsetRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_get_xlocsetRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_get_xlocsetRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string path = 2; +inline bool xtreemfs_get_xlocsetRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_get_xlocsetRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_get_xlocsetRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_get_xlocsetRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& xtreemfs_get_xlocsetRequest::path() const { + return *path_; +} +inline void xtreemfs_get_xlocsetRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_get_xlocsetRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_get_xlocsetRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_get_xlocsetRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* xtreemfs_get_xlocsetRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_get_xlocsetRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string volume_name = 3; +inline bool xtreemfs_get_xlocsetRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_get_xlocsetRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_get_xlocsetRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_get_xlocsetRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& xtreemfs_get_xlocsetRequest::volume_name() const { + return *volume_name_; +} +inline void xtreemfs_get_xlocsetRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_get_xlocsetRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_get_xlocsetRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_get_xlocsetRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* xtreemfs_get_xlocsetRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_get_xlocsetRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional .xtreemfs.pbrpc.XCap xcap = 4; +inline bool xtreemfs_get_xlocsetRequest::has_xcap() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_get_xlocsetRequest::set_has_xcap() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_get_xlocsetRequest::clear_has_xcap() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_get_xlocsetRequest::clear_xcap() { + if (xcap_ != NULL) xcap_->::xtreemfs::pbrpc::XCap::Clear(); + clear_has_xcap(); +} +inline const ::xtreemfs::pbrpc::XCap& xtreemfs_get_xlocsetRequest::xcap() const { + return xcap_ != NULL ? *xcap_ : *default_instance_->xcap_; +} +inline ::xtreemfs::pbrpc::XCap* xtreemfs_get_xlocsetRequest::mutable_xcap() { + set_has_xcap(); + if (xcap_ == NULL) xcap_ = new ::xtreemfs::pbrpc::XCap; + return xcap_; +} +inline ::xtreemfs::pbrpc::XCap* xtreemfs_get_xlocsetRequest::release_xcap() { + clear_has_xcap(); + ::xtreemfs::pbrpc::XCap* temp = xcap_; + xcap_ = NULL; + return temp; +} +inline void xtreemfs_get_xlocsetRequest::set_allocated_xcap(::xtreemfs::pbrpc::XCap* xcap) { + delete xcap_; + xcap_ = xcap; + if (xcap) { + set_has_xcap(); + } else { + clear_has_xcap(); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_replica_removeRequest + +// optional string file_id = 1; +inline bool xtreemfs_replica_removeRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_replica_removeRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_replica_removeRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_replica_removeRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_replica_removeRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_replica_removeRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_replica_removeRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_replica_removeRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_replica_removeRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_replica_removeRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_replica_removeRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string path = 3; +inline bool xtreemfs_replica_removeRequest::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_replica_removeRequest::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_replica_removeRequest::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_replica_removeRequest::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& xtreemfs_replica_removeRequest::path() const { + return *path_; +} +inline void xtreemfs_replica_removeRequest::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_replica_removeRequest::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void xtreemfs_replica_removeRequest::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_replica_removeRequest::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* xtreemfs_replica_removeRequest::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_replica_removeRequest::set_allocated_path(::std::string* path) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (path) { + set_has_path(); + path_ = path; + } else { + clear_has_path(); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string volume_name = 4; +inline bool xtreemfs_replica_removeRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_replica_removeRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_replica_removeRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_replica_removeRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& xtreemfs_replica_removeRequest::volume_name() const { + return *volume_name_; +} +inline void xtreemfs_replica_removeRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_replica_removeRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_replica_removeRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_replica_removeRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* xtreemfs_replica_removeRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_replica_removeRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string osd_uuid = 2; +inline bool xtreemfs_replica_removeRequest::has_osd_uuid() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_replica_removeRequest::set_has_osd_uuid() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_replica_removeRequest::clear_has_osd_uuid() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_replica_removeRequest::clear_osd_uuid() { + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + osd_uuid_->clear(); + } + clear_has_osd_uuid(); +} +inline const ::std::string& xtreemfs_replica_removeRequest::osd_uuid() const { + return *osd_uuid_; +} +inline void xtreemfs_replica_removeRequest::set_osd_uuid(const ::std::string& value) { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + osd_uuid_->assign(value); +} +inline void xtreemfs_replica_removeRequest::set_osd_uuid(const char* value) { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + osd_uuid_->assign(value); +} +inline void xtreemfs_replica_removeRequest::set_osd_uuid(const char* value, size_t size) { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + osd_uuid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_replica_removeRequest::mutable_osd_uuid() { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + return osd_uuid_; +} +inline ::std::string* xtreemfs_replica_removeRequest::release_osd_uuid() { + clear_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = osd_uuid_; + osd_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_replica_removeRequest::set_allocated_osd_uuid(::std::string* osd_uuid) { + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + delete osd_uuid_; + } + if (osd_uuid) { + set_has_osd_uuid(); + osd_uuid_ = osd_uuid; + } else { + clear_has_osd_uuid(); + osd_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_restore_fileRequest + +// required string file_path = 1; +inline bool xtreemfs_restore_fileRequest::has_file_path() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_restore_fileRequest::set_has_file_path() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_restore_fileRequest::clear_has_file_path() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_restore_fileRequest::clear_file_path() { + if (file_path_ != &::google::protobuf::internal::kEmptyString) { + file_path_->clear(); + } + clear_has_file_path(); +} +inline const ::std::string& xtreemfs_restore_fileRequest::file_path() const { + return *file_path_; +} +inline void xtreemfs_restore_fileRequest::set_file_path(const ::std::string& value) { + set_has_file_path(); + if (file_path_ == &::google::protobuf::internal::kEmptyString) { + file_path_ = new ::std::string; + } + file_path_->assign(value); +} +inline void xtreemfs_restore_fileRequest::set_file_path(const char* value) { + set_has_file_path(); + if (file_path_ == &::google::protobuf::internal::kEmptyString) { + file_path_ = new ::std::string; + } + file_path_->assign(value); +} +inline void xtreemfs_restore_fileRequest::set_file_path(const char* value, size_t size) { + set_has_file_path(); + if (file_path_ == &::google::protobuf::internal::kEmptyString) { + file_path_ = new ::std::string; + } + file_path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_restore_fileRequest::mutable_file_path() { + set_has_file_path(); + if (file_path_ == &::google::protobuf::internal::kEmptyString) { + file_path_ = new ::std::string; + } + return file_path_; +} +inline ::std::string* xtreemfs_restore_fileRequest::release_file_path() { + clear_has_file_path(); + if (file_path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_path_; + file_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_restore_fileRequest::set_allocated_file_path(::std::string* file_path) { + if (file_path_ != &::google::protobuf::internal::kEmptyString) { + delete file_path_; + } + if (file_path) { + set_has_file_path(); + file_path_ = file_path; + } else { + clear_has_file_path(); + file_path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string file_id = 2; +inline bool xtreemfs_restore_fileRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_restore_fileRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_restore_fileRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_restore_fileRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_restore_fileRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_restore_fileRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_restore_fileRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_restore_fileRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_restore_fileRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_restore_fileRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_restore_fileRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 file_size = 3; +inline bool xtreemfs_restore_fileRequest::has_file_size() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_restore_fileRequest::set_has_file_size() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_restore_fileRequest::clear_has_file_size() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_restore_fileRequest::clear_file_size() { + file_size_ = GOOGLE_ULONGLONG(0); + clear_has_file_size(); +} +inline ::google::protobuf::uint64 xtreemfs_restore_fileRequest::file_size() const { + return file_size_; +} +inline void xtreemfs_restore_fileRequest::set_file_size(::google::protobuf::uint64 value) { + set_has_file_size(); + file_size_ = value; +} + +// required string osd_uuid = 4; +inline bool xtreemfs_restore_fileRequest::has_osd_uuid() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_restore_fileRequest::set_has_osd_uuid() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_restore_fileRequest::clear_has_osd_uuid() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_restore_fileRequest::clear_osd_uuid() { + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + osd_uuid_->clear(); + } + clear_has_osd_uuid(); +} +inline const ::std::string& xtreemfs_restore_fileRequest::osd_uuid() const { + return *osd_uuid_; +} +inline void xtreemfs_restore_fileRequest::set_osd_uuid(const ::std::string& value) { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + osd_uuid_->assign(value); +} +inline void xtreemfs_restore_fileRequest::set_osd_uuid(const char* value) { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + osd_uuid_->assign(value); +} +inline void xtreemfs_restore_fileRequest::set_osd_uuid(const char* value, size_t size) { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + osd_uuid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_restore_fileRequest::mutable_osd_uuid() { + set_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + osd_uuid_ = new ::std::string; + } + return osd_uuid_; +} +inline ::std::string* xtreemfs_restore_fileRequest::release_osd_uuid() { + clear_has_osd_uuid(); + if (osd_uuid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = osd_uuid_; + osd_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_restore_fileRequest::set_allocated_osd_uuid(::std::string* osd_uuid) { + if (osd_uuid_ != &::google::protobuf::internal::kEmptyString) { + delete osd_uuid_; + } + if (osd_uuid) { + set_has_osd_uuid(); + osd_uuid_ = osd_uuid; + } else { + clear_has_osd_uuid(); + osd_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 stripe_size = 5; +inline bool xtreemfs_restore_fileRequest::has_stripe_size() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void xtreemfs_restore_fileRequest::set_has_stripe_size() { + _has_bits_[0] |= 0x00000010u; +} +inline void xtreemfs_restore_fileRequest::clear_has_stripe_size() { + _has_bits_[0] &= ~0x00000010u; +} +inline void xtreemfs_restore_fileRequest::clear_stripe_size() { + stripe_size_ = 0u; + clear_has_stripe_size(); +} +inline ::google::protobuf::uint32 xtreemfs_restore_fileRequest::stripe_size() const { + return stripe_size_; +} +inline void xtreemfs_restore_fileRequest::set_stripe_size(::google::protobuf::uint32 value) { + set_has_stripe_size(); + stripe_size_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_rmvolRequest + +// required string volume_name = 1; +inline bool xtreemfs_rmvolRequest::has_volume_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_rmvolRequest::set_has_volume_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_rmvolRequest::clear_has_volume_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_rmvolRequest::clear_volume_name() { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + volume_name_->clear(); + } + clear_has_volume_name(); +} +inline const ::std::string& xtreemfs_rmvolRequest::volume_name() const { + return *volume_name_; +} +inline void xtreemfs_rmvolRequest::set_volume_name(const ::std::string& value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_rmvolRequest::set_volume_name(const char* value) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(value); +} +inline void xtreemfs_rmvolRequest::set_volume_name(const char* value, size_t size) { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + volume_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_rmvolRequest::mutable_volume_name() { + set_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + volume_name_ = new ::std::string; + } + return volume_name_; +} +inline ::std::string* xtreemfs_rmvolRequest::release_volume_name() { + clear_has_volume_name(); + if (volume_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = volume_name_; + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_rmvolRequest::set_allocated_volume_name(::std::string* volume_name) { + if (volume_name_ != &::google::protobuf::internal::kEmptyString) { + delete volume_name_; + } + if (volume_name) { + set_has_volume_name(); + volume_name_ = volume_name; + } else { + clear_has_volume_name(); + volume_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_update_file_sizeRequest + +// required .xtreemfs.pbrpc.XCap xcap = 1; +inline bool xtreemfs_update_file_sizeRequest::has_xcap() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_update_file_sizeRequest::set_has_xcap() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_update_file_sizeRequest::clear_has_xcap() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_update_file_sizeRequest::clear_xcap() { + if (xcap_ != NULL) xcap_->::xtreemfs::pbrpc::XCap::Clear(); + clear_has_xcap(); +} +inline const ::xtreemfs::pbrpc::XCap& xtreemfs_update_file_sizeRequest::xcap() const { + return xcap_ != NULL ? *xcap_ : *default_instance_->xcap_; +} +inline ::xtreemfs::pbrpc::XCap* xtreemfs_update_file_sizeRequest::mutable_xcap() { + set_has_xcap(); + if (xcap_ == NULL) xcap_ = new ::xtreemfs::pbrpc::XCap; + return xcap_; +} +inline ::xtreemfs::pbrpc::XCap* xtreemfs_update_file_sizeRequest::release_xcap() { + clear_has_xcap(); + ::xtreemfs::pbrpc::XCap* temp = xcap_; + xcap_ = NULL; + return temp; +} +inline void xtreemfs_update_file_sizeRequest::set_allocated_xcap(::xtreemfs::pbrpc::XCap* xcap) { + delete xcap_; + xcap_ = xcap; + if (xcap) { + set_has_xcap(); + } else { + clear_has_xcap(); + } +} + +// required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; +inline bool xtreemfs_update_file_sizeRequest::has_osd_write_response() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_update_file_sizeRequest::set_has_osd_write_response() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_update_file_sizeRequest::clear_has_osd_write_response() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_update_file_sizeRequest::clear_osd_write_response() { + if (osd_write_response_ != NULL) osd_write_response_->::xtreemfs::pbrpc::OSDWriteResponse::Clear(); + clear_has_osd_write_response(); +} +inline const ::xtreemfs::pbrpc::OSDWriteResponse& xtreemfs_update_file_sizeRequest::osd_write_response() const { + return osd_write_response_ != NULL ? *osd_write_response_ : *default_instance_->osd_write_response_; +} +inline ::xtreemfs::pbrpc::OSDWriteResponse* xtreemfs_update_file_sizeRequest::mutable_osd_write_response() { + set_has_osd_write_response(); + if (osd_write_response_ == NULL) osd_write_response_ = new ::xtreemfs::pbrpc::OSDWriteResponse; + return osd_write_response_; +} +inline ::xtreemfs::pbrpc::OSDWriteResponse* xtreemfs_update_file_sizeRequest::release_osd_write_response() { + clear_has_osd_write_response(); + ::xtreemfs::pbrpc::OSDWriteResponse* temp = osd_write_response_; + osd_write_response_ = NULL; + return temp; +} +inline void xtreemfs_update_file_sizeRequest::set_allocated_osd_write_response(::xtreemfs::pbrpc::OSDWriteResponse* osd_write_response) { + delete osd_write_response_; + osd_write_response_ = osd_write_response; + if (osd_write_response) { + set_has_osd_write_response(); + } else { + clear_has_osd_write_response(); + } +} + +// optional bool close_file = 3; +inline bool xtreemfs_update_file_sizeRequest::has_close_file() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_update_file_sizeRequest::set_has_close_file() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_update_file_sizeRequest::clear_has_close_file() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_update_file_sizeRequest::clear_close_file() { + close_file_ = false; + clear_has_close_file(); +} +inline bool xtreemfs_update_file_sizeRequest::close_file() const { + return close_file_; +} +inline void xtreemfs_update_file_sizeRequest::set_close_file(bool value) { + set_has_close_file(); + close_file_ = value; +} + +// optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; +inline bool xtreemfs_update_file_sizeRequest::has_coordinates() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_update_file_sizeRequest::set_has_coordinates() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_update_file_sizeRequest::clear_has_coordinates() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_update_file_sizeRequest::clear_coordinates() { + if (coordinates_ != NULL) coordinates_->::xtreemfs::pbrpc::VivaldiCoordinates::Clear(); + clear_has_coordinates(); +} +inline const ::xtreemfs::pbrpc::VivaldiCoordinates& xtreemfs_update_file_sizeRequest::coordinates() const { + return coordinates_ != NULL ? *coordinates_ : *default_instance_->coordinates_; +} +inline ::xtreemfs::pbrpc::VivaldiCoordinates* xtreemfs_update_file_sizeRequest::mutable_coordinates() { + set_has_coordinates(); + if (coordinates_ == NULL) coordinates_ = new ::xtreemfs::pbrpc::VivaldiCoordinates; + return coordinates_; +} +inline ::xtreemfs::pbrpc::VivaldiCoordinates* xtreemfs_update_file_sizeRequest::release_coordinates() { + clear_has_coordinates(); + ::xtreemfs::pbrpc::VivaldiCoordinates* temp = coordinates_; + coordinates_ = NULL; + return temp; +} +inline void xtreemfs_update_file_sizeRequest::set_allocated_coordinates(::xtreemfs::pbrpc::VivaldiCoordinates* coordinates) { + delete coordinates_; + coordinates_ = coordinates; + if (coordinates) { + set_has_coordinates(); + } else { + clear_has_coordinates(); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_set_replica_update_policyRequest + +// required string file_id = 1; +inline bool xtreemfs_set_replica_update_policyRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_set_replica_update_policyRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_set_replica_update_policyRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_set_replica_update_policyRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_set_replica_update_policyRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_set_replica_update_policyRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_set_replica_update_policyRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_set_replica_update_policyRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_set_replica_update_policyRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_set_replica_update_policyRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_set_replica_update_policyRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required string update_policy = 2; +inline bool xtreemfs_set_replica_update_policyRequest::has_update_policy() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_set_replica_update_policyRequest::set_has_update_policy() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_set_replica_update_policyRequest::clear_has_update_policy() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_set_replica_update_policyRequest::clear_update_policy() { + if (update_policy_ != &::google::protobuf::internal::kEmptyString) { + update_policy_->clear(); + } + clear_has_update_policy(); +} +inline const ::std::string& xtreemfs_set_replica_update_policyRequest::update_policy() const { + return *update_policy_; +} +inline void xtreemfs_set_replica_update_policyRequest::set_update_policy(const ::std::string& value) { + set_has_update_policy(); + if (update_policy_ == &::google::protobuf::internal::kEmptyString) { + update_policy_ = new ::std::string; + } + update_policy_->assign(value); +} +inline void xtreemfs_set_replica_update_policyRequest::set_update_policy(const char* value) { + set_has_update_policy(); + if (update_policy_ == &::google::protobuf::internal::kEmptyString) { + update_policy_ = new ::std::string; + } + update_policy_->assign(value); +} +inline void xtreemfs_set_replica_update_policyRequest::set_update_policy(const char* value, size_t size) { + set_has_update_policy(); + if (update_policy_ == &::google::protobuf::internal::kEmptyString) { + update_policy_ = new ::std::string; + } + update_policy_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_set_replica_update_policyRequest::mutable_update_policy() { + set_has_update_policy(); + if (update_policy_ == &::google::protobuf::internal::kEmptyString) { + update_policy_ = new ::std::string; + } + return update_policy_; +} +inline ::std::string* xtreemfs_set_replica_update_policyRequest::release_update_policy() { + clear_has_update_policy(); + if (update_policy_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = update_policy_; + update_policy_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_set_replica_update_policyRequest::set_allocated_update_policy(::std::string* update_policy) { + if (update_policy_ != &::google::protobuf::internal::kEmptyString) { + delete update_policy_; + } + if (update_policy) { + set_has_update_policy(); + update_policy_ = update_policy; + } else { + clear_has_update_policy(); + update_policy_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_set_replica_update_policyResponse + +// required string old_update_policy = 1; +inline bool xtreemfs_set_replica_update_policyResponse::has_old_update_policy() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_set_replica_update_policyResponse::set_has_old_update_policy() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_set_replica_update_policyResponse::clear_has_old_update_policy() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_set_replica_update_policyResponse::clear_old_update_policy() { + if (old_update_policy_ != &::google::protobuf::internal::kEmptyString) { + old_update_policy_->clear(); + } + clear_has_old_update_policy(); +} +inline const ::std::string& xtreemfs_set_replica_update_policyResponse::old_update_policy() const { + return *old_update_policy_; +} +inline void xtreemfs_set_replica_update_policyResponse::set_old_update_policy(const ::std::string& value) { + set_has_old_update_policy(); + if (old_update_policy_ == &::google::protobuf::internal::kEmptyString) { + old_update_policy_ = new ::std::string; + } + old_update_policy_->assign(value); +} +inline void xtreemfs_set_replica_update_policyResponse::set_old_update_policy(const char* value) { + set_has_old_update_policy(); + if (old_update_policy_ == &::google::protobuf::internal::kEmptyString) { + old_update_policy_ = new ::std::string; + } + old_update_policy_->assign(value); +} +inline void xtreemfs_set_replica_update_policyResponse::set_old_update_policy(const char* value, size_t size) { + set_has_old_update_policy(); + if (old_update_policy_ == &::google::protobuf::internal::kEmptyString) { + old_update_policy_ = new ::std::string; + } + old_update_policy_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_set_replica_update_policyResponse::mutable_old_update_policy() { + set_has_old_update_policy(); + if (old_update_policy_ == &::google::protobuf::internal::kEmptyString) { + old_update_policy_ = new ::std::string; + } + return old_update_policy_; +} +inline ::std::string* xtreemfs_set_replica_update_policyResponse::release_old_update_policy() { + clear_has_old_update_policy(); + if (old_update_policy_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = old_update_policy_; + old_update_policy_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_set_replica_update_policyResponse::set_allocated_old_update_policy(::std::string* old_update_policy) { + if (old_update_policy_ != &::google::protobuf::internal::kEmptyString) { + delete old_update_policy_; + } + if (old_update_policy) { + set_has_old_update_policy(); + old_update_policy_ = old_update_policy; + } else { + clear_has_old_update_policy(); + old_update_policy_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_set_read_only_xattrRequest + +// required string file_id = 1; +inline bool xtreemfs_set_read_only_xattrRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_set_read_only_xattrRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_set_read_only_xattrRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_set_read_only_xattrRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_set_read_only_xattrRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_set_read_only_xattrRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_set_read_only_xattrRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_set_read_only_xattrRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_set_read_only_xattrRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_set_read_only_xattrRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_set_read_only_xattrRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required bool value = 2; +inline bool xtreemfs_set_read_only_xattrRequest::has_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_set_read_only_xattrRequest::set_has_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_set_read_only_xattrRequest::clear_has_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_set_read_only_xattrRequest::clear_value() { + value_ = false; + clear_has_value(); +} +inline bool xtreemfs_set_read_only_xattrRequest::value() const { + return value_; +} +inline void xtreemfs_set_read_only_xattrRequest::set_value(bool value) { + set_has_value(); + value_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_set_read_only_xattrResponse + +// required bool was_set = 1; +inline bool xtreemfs_set_read_only_xattrResponse::has_was_set() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_set_read_only_xattrResponse::set_has_was_set() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_set_read_only_xattrResponse::clear_has_was_set() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_set_read_only_xattrResponse::clear_was_set() { + was_set_ = false; + clear_has_was_set(); +} +inline bool xtreemfs_set_read_only_xattrResponse::was_set() const { + return was_set_; +} +inline void xtreemfs_set_read_only_xattrResponse::set_was_set(bool value) { + set_has_was_set(); + was_set_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_get_file_credentialsRequest + +// required string file_id = 1; +inline bool xtreemfs_get_file_credentialsRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_get_file_credentialsRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_get_file_credentialsRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_get_file_credentialsRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_get_file_credentialsRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_get_file_credentialsRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_get_file_credentialsRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_get_file_credentialsRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_get_file_credentialsRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_get_file_credentialsRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_get_file_credentialsRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE>() { + return ::xtreemfs::pbrpc::xtreemfs_check_file_existsResponse_FILE_STATE_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::Setattrs>() { + return ::xtreemfs::pbrpc::Setattrs_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::XATTR_FLAGS>() { + return ::xtreemfs::pbrpc::XATTR_FLAGS_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::ACCESS_FLAGS>() { + return ::xtreemfs::pbrpc::ACCESS_FLAGS_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_xtreemfs_2fMRC_2eproto__INCLUDED diff --git a/cpp/generated/xtreemfs/MRCServiceClient.h b/cpp/generated/xtreemfs/MRCServiceClient.h new file mode 100644 index 0000000..70cd4b4 --- /dev/null +++ b/cpp/generated/xtreemfs/MRCServiceClient.h @@ -0,0 +1,981 @@ +//automatically generated from MRC.proto at Thu Dec 11 16:09:40 CET 2014 +//(c) 2014. See LICENSE file for details. + +#ifndef MRCSERVICECLIENT_H +#define MRCSERVICECLIENT_H + +#include +#include "pbrpc/RPC.pb.h" +#include "rpc/client.h" +#include "rpc/sync_callback.h" +#include "rpc/callback_interface.h" +#include "xtreemfs/MRC.pb.h" +#include "include/Common.pb.h" +#include "xtreemfs/GlobalTypes.pb.h" +#include "xtreemfs/DIR.pb.h" + + +namespace xtreemfs { +namespace pbrpc { + using ::xtreemfs::rpc::Client; + using ::xtreemfs::rpc::CallbackInterface; + using ::xtreemfs::rpc::SyncCallback; + + class MRCServiceClient { + + public: + MRCServiceClient(Client* client) : client_(client) { + } + + virtual ~MRCServiceClient() { + } + + void fsetattr(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::fsetattrRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 2, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* fsetattr_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::fsetattrRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 2, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void ftruncate(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::XCap* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 3, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::XCap(), + context, callback); + } + + SyncCallback* ftruncate_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::XCap* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 3, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::XCap(), + NULL, sync_cb); + return sync_cb; + } + + void getattr(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::getattrRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 4, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::getattrResponse(), + context, callback); + } + + SyncCallback* getattr_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::getattrRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 4, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::getattrResponse(), + NULL, sync_cb); + return sync_cb; + } + + void getxattr(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::getxattrRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 5, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::getxattrResponse(), + context, callback); + } + + SyncCallback* getxattr_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::getxattrRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 5, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::getxattrResponse(), + NULL, sync_cb); + return sync_cb; + } + + void link(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::linkRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 6, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + context, callback); + } + + SyncCallback* link_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::linkRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 6, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + NULL, sync_cb); + return sync_cb; + } + + void listxattr(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::listxattrRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 7, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::listxattrResponse(), + context, callback); + } + + SyncCallback* listxattr_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::listxattrRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 7, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::listxattrResponse(), + NULL, sync_cb); + return sync_cb; + } + + void mkdir(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::mkdirRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 8, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + context, callback); + } + + SyncCallback* mkdir_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::mkdirRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 8, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + NULL, sync_cb); + return sync_cb; + } + + void open(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::openRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 9, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::openResponse(), + context, callback); + } + + SyncCallback* open_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::openRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 9, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::openResponse(), + NULL, sync_cb); + return sync_cb; + } + + void readdir(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::readdirRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 10, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::DirectoryEntries(), + context, callback); + } + + SyncCallback* readdir_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::readdirRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 10, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::DirectoryEntries(), + NULL, sync_cb); + return sync_cb; + } + + void readlink(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::readlinkRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 11, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::readlinkResponse(), + context, callback); + } + + SyncCallback* readlink_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::readlinkRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 11, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::readlinkResponse(), + NULL, sync_cb); + return sync_cb; + } + + void removexattr(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::removexattrRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 12, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + context, callback); + } + + SyncCallback* removexattr_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::removexattrRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 12, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + NULL, sync_cb); + return sync_cb; + } + + void rename(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::renameRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 13, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::renameResponse(), + context, callback); + } + + SyncCallback* rename_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::renameRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 13, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::renameResponse(), + NULL, sync_cb); + return sync_cb; + } + + void rmdir(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::rmdirRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 14, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + context, callback); + } + + SyncCallback* rmdir_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::rmdirRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 14, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + NULL, sync_cb); + return sync_cb; + } + + void setattr(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::setattrRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 15, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + context, callback); + } + + SyncCallback* setattr_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::setattrRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 15, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + NULL, sync_cb); + return sync_cb; + } + + void setxattr(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::setxattrRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 16, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + context, callback); + } + + SyncCallback* setxattr_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::setxattrRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 16, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + NULL, sync_cb); + return sync_cb; + } + + void statvfs(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::statvfsRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 17, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::StatVFS(), + context, callback); + } + + SyncCallback* statvfs_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::statvfsRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 17, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::StatVFS(), + NULL, sync_cb); + return sync_cb; + } + + void symlink(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::symlinkRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 18, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + context, callback); + } + + SyncCallback* symlink_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::symlinkRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 18, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + NULL, sync_cb); + return sync_cb; + } + + void unlink(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::unlinkRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 19, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::unlinkResponse(), + context, callback); + } + + SyncCallback* unlink_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::unlinkRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 19, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::unlinkResponse(), + NULL, sync_cb); + return sync_cb; + } + + void access(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::accessRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 20, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* access_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::accessRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 20, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_checkpoint(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 20001, 30, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_checkpoint_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 30, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_check_file_exists(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_check_file_existsRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 31, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_check_file_existsResponse(), + context, callback); + } + + SyncCallback* xtreemfs_check_file_exists_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_check_file_existsRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 31, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_check_file_existsResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_dump_database(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_dump_restore_databaseRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 32, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_dump_database_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_dump_restore_databaseRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 32, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_get_suitable_osds(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_get_suitable_osdsRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 33, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_get_suitable_osdsResponse(), + context, callback); + } + + SyncCallback* xtreemfs_get_suitable_osds_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_get_suitable_osdsRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 33, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_get_suitable_osdsResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_internal_debug(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::stringMessage* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 34, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::stringMessage(), + context, callback); + } + + SyncCallback* xtreemfs_internal_debug_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::stringMessage* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 34, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::stringMessage(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_listdir(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_listdirRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 35, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_listdirResponse(), + context, callback); + } + + SyncCallback* xtreemfs_listdir_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_listdirRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 35, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_listdirResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_lsvol(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 20001, 36, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::Volumes(), + context, callback); + } + + SyncCallback* xtreemfs_lsvol_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 36, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::Volumes(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_mkvol(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::Volume* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 47, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_mkvol_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::Volume* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 47, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_renew_capability(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::XCap* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 37, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::XCap(), + context, callback); + } + + SyncCallback* xtreemfs_renew_capability_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::XCap* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 37, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::XCap(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_replication_to_master(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 20001, 38, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_replication_to_master_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 38, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_replica_add(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_replica_addRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 39, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_replica_add_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_replica_addRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 39, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_replica_list(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_replica_listRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 40, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::Replicas(), + context, callback); + } + + SyncCallback* xtreemfs_replica_list_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_replica_listRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 40, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::Replicas(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_replica_remove(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_replica_removeRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 41, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::FileCredentials(), + context, callback); + } + + SyncCallback* xtreemfs_replica_remove_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_replica_removeRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 41, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::FileCredentials(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_restore_database(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_dump_restore_databaseRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 42, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_restore_database_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_dump_restore_databaseRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 42, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_restore_file(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_restore_fileRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 43, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_restore_file_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_restore_fileRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 43, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_rmvol(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_rmvolRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 44, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_rmvol_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_rmvolRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 44, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_shutdown(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 20001, 45, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_shutdown_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 45, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_update_file_size(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_update_file_sizeRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 46, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + context, callback); + } + + SyncCallback* xtreemfs_update_file_size_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_update_file_sizeRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 46, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::timestampResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_set_replica_update_policy(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_set_replica_update_policyRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 48, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_set_replica_update_policyResponse(), + context, callback); + } + + SyncCallback* xtreemfs_set_replica_update_policy_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_set_replica_update_policyRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 48, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_set_replica_update_policyResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_set_read_only_xattr(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_set_read_only_xattrRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 49, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_set_read_only_xattrResponse(), + context, callback); + } + + SyncCallback* xtreemfs_set_read_only_xattr_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_set_read_only_xattrRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 49, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_set_read_only_xattrResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_get_file_credentials(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_get_file_credentialsRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 50, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::FileCredentials(), + context, callback); + } + + SyncCallback* xtreemfs_get_file_credentials_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_get_file_credentialsRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 50, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::FileCredentials(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_get_xlocset(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_get_xlocsetRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 20001, 51, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::XLocSet(), + context, callback); + } + + SyncCallback* xtreemfs_get_xlocset_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_get_xlocsetRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 20001, 51, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::XLocSet(), + NULL, sync_cb); + return sync_cb; + } + + private: + Client* client_; + }; + } +} +#endif //MRCSERVICECLIENT_H diff --git a/cpp/generated/xtreemfs/MRCServiceConstants.h b/cpp/generated/xtreemfs/MRCServiceConstants.h new file mode 100644 index 0000000..f2017de --- /dev/null +++ b/cpp/generated/xtreemfs/MRCServiceConstants.h @@ -0,0 +1,57 @@ +//automatically generated from MRC.proto at Thu Dec 11 16:09:40 CET 2014 +//(c) 2014. See LICENSE file for details. + +#ifndef MRCSERVICECONSTANTS_H_ +#define MRCSERVICECONSTANTS_H_ +#include + +namespace xtreemfs { +namespace pbrpc { + +const uint32_t INTERFACE_ID_MRC = 20001; +const uint32_t PROC_ID_FSETATTR = 2; +const uint32_t PROC_ID_FTRUNCATE = 3; +const uint32_t PROC_ID_GETATTR = 4; +const uint32_t PROC_ID_GETXATTR = 5; +const uint32_t PROC_ID_LINK = 6; +const uint32_t PROC_ID_LISTXATTR = 7; +const uint32_t PROC_ID_MKDIR = 8; +const uint32_t PROC_ID_OPEN = 9; +const uint32_t PROC_ID_READDIR = 10; +const uint32_t PROC_ID_READLINK = 11; +const uint32_t PROC_ID_REMOVEXATTR = 12; +const uint32_t PROC_ID_RENAME = 13; +const uint32_t PROC_ID_RMDIR = 14; +const uint32_t PROC_ID_SETATTR = 15; +const uint32_t PROC_ID_SETXATTR = 16; +const uint32_t PROC_ID_STATVFS = 17; +const uint32_t PROC_ID_SYMLINK = 18; +const uint32_t PROC_ID_UNLINK = 19; +const uint32_t PROC_ID_ACCESS = 20; +const uint32_t PROC_ID_XTREEMFS_CHECKPOINT = 30; +const uint32_t PROC_ID_XTREEMFS_CHECK_FILE_EXISTS = 31; +const uint32_t PROC_ID_XTREEMFS_DUMP_DATABASE = 32; +const uint32_t PROC_ID_XTREEMFS_GET_SUITABLE_OSDS = 33; +const uint32_t PROC_ID_XTREEMFS_INTERNAL_DEBUG = 34; +const uint32_t PROC_ID_XTREEMFS_LISTDIR = 35; +const uint32_t PROC_ID_XTREEMFS_LSVOL = 36; +const uint32_t PROC_ID_XTREEMFS_MKVOL = 47; +const uint32_t PROC_ID_XTREEMFS_RENEW_CAPABILITY = 37; +const uint32_t PROC_ID_XTREEMFS_REPLICATION_TO_MASTER = 38; +const uint32_t PROC_ID_XTREEMFS_REPLICA_ADD = 39; +const uint32_t PROC_ID_XTREEMFS_REPLICA_LIST = 40; +const uint32_t PROC_ID_XTREEMFS_REPLICA_REMOVE = 41; +const uint32_t PROC_ID_XTREEMFS_RESTORE_DATABASE = 42; +const uint32_t PROC_ID_XTREEMFS_RESTORE_FILE = 43; +const uint32_t PROC_ID_XTREEMFS_RMVOL = 44; +const uint32_t PROC_ID_XTREEMFS_SHUTDOWN = 45; +const uint32_t PROC_ID_XTREEMFS_UPDATE_FILE_SIZE = 46; +const uint32_t PROC_ID_XTREEMFS_SET_REPLICA_UPDATE_POLICY = 48; +const uint32_t PROC_ID_XTREEMFS_SET_READ_ONLY_XATTR = 49; +const uint32_t PROC_ID_XTREEMFS_GET_FILE_CREDENTIALS = 50; +const uint32_t PROC_ID_XTREEMFS_GET_XLOCSET = 51; + +} // namespace pbrpc +} // namespace xtreemfs + +#endif // MRCSERVICECLIENT_H_ diff --git a/cpp/generated/xtreemfs/OSD.pb.cc b/cpp/generated/xtreemfs/OSD.pb.cc new file mode 100644 index 0000000..7de087f --- /dev/null +++ b/cpp/generated/xtreemfs/OSD.pb.cc @@ -0,0 +1,13946 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/OSD.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "xtreemfs/OSD.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +namespace { + +const ::google::protobuf::Descriptor* InternalGmax_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + InternalGmax_reflection_ = NULL; +const ::google::protobuf::Descriptor* Lock_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Lock_reflection_ = NULL; +const ::google::protobuf::Descriptor* ObjectData_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ObjectData_reflection_ = NULL; +const ::google::protobuf::Descriptor* ObjectList_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ObjectList_reflection_ = NULL; +const ::google::protobuf::Descriptor* ObjectVersion_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ObjectVersion_reflection_ = NULL; +const ::google::protobuf::Descriptor* TruncateRecord_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + TruncateRecord_reflection_ = NULL; +const ::google::protobuf::Descriptor* TruncateLog_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + TruncateLog_reflection_ = NULL; +const ::google::protobuf::Descriptor* XLocSetVersionState_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + XLocSetVersionState_reflection_ = NULL; +const ::google::protobuf::Descriptor* ReplicaStatus_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ReplicaStatus_reflection_ = NULL; +const ::google::protobuf::Descriptor* ObjectVersionMapping_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ObjectVersionMapping_reflection_ = NULL; +const ::google::protobuf::Descriptor* AuthoritativeReplicaState_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + AuthoritativeReplicaState_reflection_ = NULL; +const ::google::protobuf::Descriptor* InternalReadLocalResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + InternalReadLocalResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* readRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + readRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* truncateRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + truncateRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* unlink_osd_Request_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + unlink_osd_Request_reflection_ = NULL; +const ::google::protobuf::Descriptor* writeRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + writeRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_broadcast_gmaxRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_broadcast_gmaxRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_check_objectRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_check_objectRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_cleanup_get_resultsResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_cleanup_get_resultsResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_cleanup_is_runningResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_cleanup_is_runningResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_cleanup_startRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_cleanup_startRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_cleanup_statusResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_cleanup_statusResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_rwr_fetchRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_rwr_fetchRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_repair_objectRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_repair_objectRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_rwr_flease_msgRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_rwr_flease_msgRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_rwr_set_primary_epochRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_rwr_set_primary_epochRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_rwr_statusRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_rwr_statusRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_rwr_truncateRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_rwr_truncateRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_rwr_updateRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_rwr_updateRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_internal_get_gmaxRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_internal_get_gmaxRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_internal_get_file_sizeRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_internal_get_file_sizeRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_internal_get_file_sizeResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_internal_get_file_sizeResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_internal_read_localRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_internal_read_localRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_internal_get_object_setRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_internal_get_object_setRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_internal_get_fileid_listResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_internal_get_fileid_listResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* lockRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + lockRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_pingMesssage_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_pingMesssage_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_rwr_auth_stateRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_rwr_auth_stateRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_rwr_reset_completeRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_rwr_reset_completeRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_xloc_set_invalidateRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_xloc_set_invalidateRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* xtreemfs_xloc_set_invalidateResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + xtreemfs_xloc_set_invalidateResponse_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* OSDHealthResult_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto() { + protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "xtreemfs/OSD.proto"); + GOOGLE_CHECK(file != NULL); + InternalGmax_descriptor_ = file->message_type(0); + static const int InternalGmax_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InternalGmax, epoch_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InternalGmax, file_size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InternalGmax, last_object_id_), + }; + InternalGmax_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + InternalGmax_descriptor_, + InternalGmax::default_instance_, + InternalGmax_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InternalGmax, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InternalGmax, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(InternalGmax)); + Lock_descriptor_ = file->message_type(1); + static const int Lock_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Lock, client_pid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Lock, client_uuid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Lock, length_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Lock, offset_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Lock, exclusive_), + }; + Lock_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Lock_descriptor_, + Lock::default_instance_, + Lock_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Lock, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Lock, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Lock)); + ObjectData_descriptor_ = file->message_type(2); + static const int ObjectData_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectData, checksum_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectData, invalid_checksum_on_osd_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectData, zero_padding_), + }; + ObjectData_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ObjectData_descriptor_, + ObjectData::default_instance_, + ObjectData_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectData, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectData, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ObjectData)); + ObjectList_descriptor_ = file->message_type(3); + static const int ObjectList_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectList, set_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectList, stripe_width_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectList, first__), + }; + ObjectList_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ObjectList_descriptor_, + ObjectList::default_instance_, + ObjectList_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectList, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectList, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ObjectList)); + ObjectVersion_descriptor_ = file->message_type(4); + static const int ObjectVersion_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectVersion, object_number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectVersion, object_version_), + }; + ObjectVersion_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ObjectVersion_descriptor_, + ObjectVersion::default_instance_, + ObjectVersion_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectVersion, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectVersion, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ObjectVersion)); + TruncateRecord_descriptor_ = file->message_type(5); + static const int TruncateRecord_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TruncateRecord, version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TruncateRecord, last_object_number_), + }; + TruncateRecord_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + TruncateRecord_descriptor_, + TruncateRecord::default_instance_, + TruncateRecord_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TruncateRecord, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TruncateRecord, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(TruncateRecord)); + TruncateLog_descriptor_ = file->message_type(6); + static const int TruncateLog_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TruncateLog, records_), + }; + TruncateLog_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + TruncateLog_descriptor_, + TruncateLog::default_instance_, + TruncateLog_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TruncateLog, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TruncateLog, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(TruncateLog)); + XLocSetVersionState_descriptor_ = file->message_type(7); + static const int XLocSetVersionState_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XLocSetVersionState, version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XLocSetVersionState, invalidated_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XLocSetVersionState, modified_time_), + }; + XLocSetVersionState_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + XLocSetVersionState_descriptor_, + XLocSetVersionState::default_instance_, + XLocSetVersionState_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XLocSetVersionState, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(XLocSetVersionState, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(XLocSetVersionState)); + ReplicaStatus_descriptor_ = file->message_type(8); + static const int ReplicaStatus_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ReplicaStatus, truncate_epoch_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ReplicaStatus, file_size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ReplicaStatus, max_obj_version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ReplicaStatus, primary_epoch_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ReplicaStatus, objectversions_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ReplicaStatus, truncate_log_), + }; + ReplicaStatus_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ReplicaStatus_descriptor_, + ReplicaStatus::default_instance_, + ReplicaStatus_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ReplicaStatus, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ReplicaStatus, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ReplicaStatus)); + ObjectVersionMapping_descriptor_ = file->message_type(9); + static const int ObjectVersionMapping_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectVersionMapping, object_number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectVersionMapping, object_version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectVersionMapping, osd_uuids_), + }; + ObjectVersionMapping_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ObjectVersionMapping_descriptor_, + ObjectVersionMapping::default_instance_, + ObjectVersionMapping_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectVersionMapping, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ObjectVersionMapping, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ObjectVersionMapping)); + AuthoritativeReplicaState_descriptor_ = file->message_type(10); + static const int AuthoritativeReplicaState_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AuthoritativeReplicaState, truncate_epoch_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AuthoritativeReplicaState, max_obj_version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AuthoritativeReplicaState, objectversions_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AuthoritativeReplicaState, truncate_log_), + }; + AuthoritativeReplicaState_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + AuthoritativeReplicaState_descriptor_, + AuthoritativeReplicaState::default_instance_, + AuthoritativeReplicaState_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AuthoritativeReplicaState, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AuthoritativeReplicaState, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(AuthoritativeReplicaState)); + InternalReadLocalResponse_descriptor_ = file->message_type(11); + static const int InternalReadLocalResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InternalReadLocalResponse, data_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InternalReadLocalResponse, object_set_), + }; + InternalReadLocalResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + InternalReadLocalResponse_descriptor_, + InternalReadLocalResponse::default_instance_, + InternalReadLocalResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InternalReadLocalResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(InternalReadLocalResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(InternalReadLocalResponse)); + readRequest_descriptor_ = file->message_type(12); + static const int readRequest_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readRequest, object_number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readRequest, object_version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readRequest, offset_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readRequest, length_), + }; + readRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + readRequest_descriptor_, + readRequest::default_instance_, + readRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(readRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(readRequest)); + truncateRequest_descriptor_ = file->message_type(13); + static const int truncateRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(truncateRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(truncateRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(truncateRequest, new_file_size_), + }; + truncateRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + truncateRequest_descriptor_, + truncateRequest::default_instance_, + truncateRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(truncateRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(truncateRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(truncateRequest)); + unlink_osd_Request_descriptor_ = file->message_type(14); + static const int unlink_osd_Request_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlink_osd_Request, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlink_osd_Request, file_id_), + }; + unlink_osd_Request_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + unlink_osd_Request_descriptor_, + unlink_osd_Request::default_instance_, + unlink_osd_Request_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlink_osd_Request, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(unlink_osd_Request, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(unlink_osd_Request)); + writeRequest_descriptor_ = file->message_type(15); + static const int writeRequest_offsets_[7] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(writeRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(writeRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(writeRequest, object_number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(writeRequest, object_version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(writeRequest, offset_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(writeRequest, lease_timeout_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(writeRequest, object_data_), + }; + writeRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + writeRequest_descriptor_, + writeRequest::default_instance_, + writeRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(writeRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(writeRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(writeRequest)); + xtreemfs_broadcast_gmaxRequest_descriptor_ = file->message_type(16); + static const int xtreemfs_broadcast_gmaxRequest_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_broadcast_gmaxRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_broadcast_gmaxRequest, truncate_epoch_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_broadcast_gmaxRequest, last_object_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_broadcast_gmaxRequest, file_size_), + }; + xtreemfs_broadcast_gmaxRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_broadcast_gmaxRequest_descriptor_, + xtreemfs_broadcast_gmaxRequest::default_instance_, + xtreemfs_broadcast_gmaxRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_broadcast_gmaxRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_broadcast_gmaxRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_broadcast_gmaxRequest)); + xtreemfs_check_objectRequest_descriptor_ = file->message_type(17); + static const int xtreemfs_check_objectRequest_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_objectRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_objectRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_objectRequest, object_number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_objectRequest, object_version_), + }; + xtreemfs_check_objectRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_check_objectRequest_descriptor_, + xtreemfs_check_objectRequest::default_instance_, + xtreemfs_check_objectRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_objectRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_check_objectRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_check_objectRequest)); + xtreemfs_cleanup_get_resultsResponse_descriptor_ = file->message_type(18); + static const int xtreemfs_cleanup_get_resultsResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_get_resultsResponse, results_), + }; + xtreemfs_cleanup_get_resultsResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_cleanup_get_resultsResponse_descriptor_, + xtreemfs_cleanup_get_resultsResponse::default_instance_, + xtreemfs_cleanup_get_resultsResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_get_resultsResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_get_resultsResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_cleanup_get_resultsResponse)); + xtreemfs_cleanup_is_runningResponse_descriptor_ = file->message_type(19); + static const int xtreemfs_cleanup_is_runningResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_is_runningResponse, is_running_), + }; + xtreemfs_cleanup_is_runningResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_cleanup_is_runningResponse_descriptor_, + xtreemfs_cleanup_is_runningResponse::default_instance_, + xtreemfs_cleanup_is_runningResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_is_runningResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_is_runningResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_cleanup_is_runningResponse)); + xtreemfs_cleanup_startRequest_descriptor_ = file->message_type(20); + static const int xtreemfs_cleanup_startRequest_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_startRequest, remove_zombies_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_startRequest, remove_unavail_volume_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_startRequest, lost_and_found_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_startRequest, delete_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_startRequest, metadata_timeout_), + }; + xtreemfs_cleanup_startRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_cleanup_startRequest_descriptor_, + xtreemfs_cleanup_startRequest::default_instance_, + xtreemfs_cleanup_startRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_startRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_startRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_cleanup_startRequest)); + xtreemfs_cleanup_statusResponse_descriptor_ = file->message_type(21); + static const int xtreemfs_cleanup_statusResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_statusResponse, status_), + }; + xtreemfs_cleanup_statusResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_cleanup_statusResponse_descriptor_, + xtreemfs_cleanup_statusResponse::default_instance_, + xtreemfs_cleanup_statusResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_statusResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_cleanup_statusResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_cleanup_statusResponse)); + xtreemfs_rwr_fetchRequest_descriptor_ = file->message_type(22); + static const int xtreemfs_rwr_fetchRequest_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_fetchRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_fetchRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_fetchRequest, object_number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_fetchRequest, object_version_), + }; + xtreemfs_rwr_fetchRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_rwr_fetchRequest_descriptor_, + xtreemfs_rwr_fetchRequest::default_instance_, + xtreemfs_rwr_fetchRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_fetchRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_fetchRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_rwr_fetchRequest)); + xtreemfs_repair_objectRequest_descriptor_ = file->message_type(23); + static const int xtreemfs_repair_objectRequest_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_repair_objectRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_repair_objectRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_repair_objectRequest, object_number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_repair_objectRequest, object_version_), + }; + xtreemfs_repair_objectRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_repair_objectRequest_descriptor_, + xtreemfs_repair_objectRequest::default_instance_, + xtreemfs_repair_objectRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_repair_objectRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_repair_objectRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_repair_objectRequest)); + xtreemfs_rwr_flease_msgRequest_descriptor_ = file->message_type(24); + static const int xtreemfs_rwr_flease_msgRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_flease_msgRequest, sender_hostname_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_flease_msgRequest, sender_port_), + }; + xtreemfs_rwr_flease_msgRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_rwr_flease_msgRequest_descriptor_, + xtreemfs_rwr_flease_msgRequest::default_instance_, + xtreemfs_rwr_flease_msgRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_flease_msgRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_flease_msgRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_rwr_flease_msgRequest)); + xtreemfs_rwr_set_primary_epochRequest_descriptor_ = file->message_type(25); + static const int xtreemfs_rwr_set_primary_epochRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_set_primary_epochRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_set_primary_epochRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_set_primary_epochRequest, primary_epoch_), + }; + xtreemfs_rwr_set_primary_epochRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_rwr_set_primary_epochRequest_descriptor_, + xtreemfs_rwr_set_primary_epochRequest::default_instance_, + xtreemfs_rwr_set_primary_epochRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_set_primary_epochRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_set_primary_epochRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_rwr_set_primary_epochRequest)); + xtreemfs_rwr_statusRequest_descriptor_ = file->message_type(26); + static const int xtreemfs_rwr_statusRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_statusRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_statusRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_statusRequest, max_local_obj_version_), + }; + xtreemfs_rwr_statusRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_rwr_statusRequest_descriptor_, + xtreemfs_rwr_statusRequest::default_instance_, + xtreemfs_rwr_statusRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_statusRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_statusRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_rwr_statusRequest)); + xtreemfs_rwr_truncateRequest_descriptor_ = file->message_type(27); + static const int xtreemfs_rwr_truncateRequest_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_truncateRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_truncateRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_truncateRequest, new_file_size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_truncateRequest, object_version_), + }; + xtreemfs_rwr_truncateRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_rwr_truncateRequest_descriptor_, + xtreemfs_rwr_truncateRequest::default_instance_, + xtreemfs_rwr_truncateRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_truncateRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_truncateRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_rwr_truncateRequest)); + xtreemfs_rwr_updateRequest_descriptor_ = file->message_type(28); + static const int xtreemfs_rwr_updateRequest_offsets_[7] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_updateRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_updateRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_updateRequest, new_file_size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_updateRequest, object_number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_updateRequest, object_version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_updateRequest, offset_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_updateRequest, obj_), + }; + xtreemfs_rwr_updateRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_rwr_updateRequest_descriptor_, + xtreemfs_rwr_updateRequest::default_instance_, + xtreemfs_rwr_updateRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_updateRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_updateRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_rwr_updateRequest)); + xtreemfs_internal_get_gmaxRequest_descriptor_ = file->message_type(29); + static const int xtreemfs_internal_get_gmaxRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_gmaxRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_gmaxRequest, file_id_), + }; + xtreemfs_internal_get_gmaxRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_internal_get_gmaxRequest_descriptor_, + xtreemfs_internal_get_gmaxRequest::default_instance_, + xtreemfs_internal_get_gmaxRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_gmaxRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_gmaxRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_internal_get_gmaxRequest)); + xtreemfs_internal_get_file_sizeRequest_descriptor_ = file->message_type(30); + static const int xtreemfs_internal_get_file_sizeRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_file_sizeRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_file_sizeRequest, file_id_), + }; + xtreemfs_internal_get_file_sizeRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_internal_get_file_sizeRequest_descriptor_, + xtreemfs_internal_get_file_sizeRequest::default_instance_, + xtreemfs_internal_get_file_sizeRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_file_sizeRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_file_sizeRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_internal_get_file_sizeRequest)); + xtreemfs_internal_get_file_sizeResponse_descriptor_ = file->message_type(31); + static const int xtreemfs_internal_get_file_sizeResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_file_sizeResponse, file_size_), + }; + xtreemfs_internal_get_file_sizeResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_internal_get_file_sizeResponse_descriptor_, + xtreemfs_internal_get_file_sizeResponse::default_instance_, + xtreemfs_internal_get_file_sizeResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_file_sizeResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_file_sizeResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_internal_get_file_sizeResponse)); + xtreemfs_internal_read_localRequest_descriptor_ = file->message_type(32); + static const int xtreemfs_internal_read_localRequest_offsets_[8] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_read_localRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_read_localRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_read_localRequest, object_number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_read_localRequest, object_version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_read_localRequest, offset_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_read_localRequest, length_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_read_localRequest, attach_object_list_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_read_localRequest, required_objects_), + }; + xtreemfs_internal_read_localRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_internal_read_localRequest_descriptor_, + xtreemfs_internal_read_localRequest::default_instance_, + xtreemfs_internal_read_localRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_read_localRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_read_localRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_internal_read_localRequest)); + xtreemfs_internal_get_object_setRequest_descriptor_ = file->message_type(33); + static const int xtreemfs_internal_get_object_setRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_object_setRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_object_setRequest, file_id_), + }; + xtreemfs_internal_get_object_setRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_internal_get_object_setRequest_descriptor_, + xtreemfs_internal_get_object_setRequest::default_instance_, + xtreemfs_internal_get_object_setRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_object_setRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_object_setRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_internal_get_object_setRequest)); + xtreemfs_internal_get_fileid_listResponse_descriptor_ = file->message_type(34); + static const int xtreemfs_internal_get_fileid_listResponse_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_fileid_listResponse, file_ids_), + }; + xtreemfs_internal_get_fileid_listResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_internal_get_fileid_listResponse_descriptor_, + xtreemfs_internal_get_fileid_listResponse::default_instance_, + xtreemfs_internal_get_fileid_listResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_fileid_listResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_internal_get_fileid_listResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_internal_get_fileid_listResponse)); + lockRequest_descriptor_ = file->message_type(35); + static const int lockRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(lockRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(lockRequest, lock_request_), + }; + lockRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + lockRequest_descriptor_, + lockRequest::default_instance_, + lockRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(lockRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(lockRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(lockRequest)); + xtreemfs_pingMesssage_descriptor_ = file->message_type(36); + static const int xtreemfs_pingMesssage_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_pingMesssage, coordinates_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_pingMesssage, request_response_), + }; + xtreemfs_pingMesssage_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_pingMesssage_descriptor_, + xtreemfs_pingMesssage::default_instance_, + xtreemfs_pingMesssage_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_pingMesssage, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_pingMesssage, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_pingMesssage)); + xtreemfs_rwr_auth_stateRequest_descriptor_ = file->message_type(37); + static const int xtreemfs_rwr_auth_stateRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_auth_stateRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_auth_stateRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_auth_stateRequest, state_), + }; + xtreemfs_rwr_auth_stateRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_rwr_auth_stateRequest_descriptor_, + xtreemfs_rwr_auth_stateRequest::default_instance_, + xtreemfs_rwr_auth_stateRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_auth_stateRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_auth_stateRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_rwr_auth_stateRequest)); + xtreemfs_rwr_reset_completeRequest_descriptor_ = file->message_type(38); + static const int xtreemfs_rwr_reset_completeRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_reset_completeRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_reset_completeRequest, file_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_reset_completeRequest, primary_epoch_), + }; + xtreemfs_rwr_reset_completeRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_rwr_reset_completeRequest_descriptor_, + xtreemfs_rwr_reset_completeRequest::default_instance_, + xtreemfs_rwr_reset_completeRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_reset_completeRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_rwr_reset_completeRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_rwr_reset_completeRequest)); + xtreemfs_xloc_set_invalidateRequest_descriptor_ = file->message_type(39); + static const int xtreemfs_xloc_set_invalidateRequest_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_xloc_set_invalidateRequest, file_credentials_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_xloc_set_invalidateRequest, file_id_), + }; + xtreemfs_xloc_set_invalidateRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_xloc_set_invalidateRequest_descriptor_, + xtreemfs_xloc_set_invalidateRequest::default_instance_, + xtreemfs_xloc_set_invalidateRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_xloc_set_invalidateRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_xloc_set_invalidateRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_xloc_set_invalidateRequest)); + xtreemfs_xloc_set_invalidateResponse_descriptor_ = file->message_type(40); + static const int xtreemfs_xloc_set_invalidateResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_xloc_set_invalidateResponse, lease_state_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_xloc_set_invalidateResponse, replica_status_), + }; + xtreemfs_xloc_set_invalidateResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + xtreemfs_xloc_set_invalidateResponse_descriptor_, + xtreemfs_xloc_set_invalidateResponse::default_instance_, + xtreemfs_xloc_set_invalidateResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_xloc_set_invalidateResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(xtreemfs_xloc_set_invalidateResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(xtreemfs_xloc_set_invalidateResponse)); + OSDHealthResult_descriptor_ = file->enum_type(0); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_xtreemfs_2fOSD_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + InternalGmax_descriptor_, &InternalGmax::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Lock_descriptor_, &Lock::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ObjectData_descriptor_, &ObjectData::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ObjectList_descriptor_, &ObjectList::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ObjectVersion_descriptor_, &ObjectVersion::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + TruncateRecord_descriptor_, &TruncateRecord::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + TruncateLog_descriptor_, &TruncateLog::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + XLocSetVersionState_descriptor_, &XLocSetVersionState::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ReplicaStatus_descriptor_, &ReplicaStatus::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ObjectVersionMapping_descriptor_, &ObjectVersionMapping::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + AuthoritativeReplicaState_descriptor_, &AuthoritativeReplicaState::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + InternalReadLocalResponse_descriptor_, &InternalReadLocalResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + readRequest_descriptor_, &readRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + truncateRequest_descriptor_, &truncateRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + unlink_osd_Request_descriptor_, &unlink_osd_Request::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + writeRequest_descriptor_, &writeRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_broadcast_gmaxRequest_descriptor_, &xtreemfs_broadcast_gmaxRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_check_objectRequest_descriptor_, &xtreemfs_check_objectRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_cleanup_get_resultsResponse_descriptor_, &xtreemfs_cleanup_get_resultsResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_cleanup_is_runningResponse_descriptor_, &xtreemfs_cleanup_is_runningResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_cleanup_startRequest_descriptor_, &xtreemfs_cleanup_startRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_cleanup_statusResponse_descriptor_, &xtreemfs_cleanup_statusResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_rwr_fetchRequest_descriptor_, &xtreemfs_rwr_fetchRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_repair_objectRequest_descriptor_, &xtreemfs_repair_objectRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_rwr_flease_msgRequest_descriptor_, &xtreemfs_rwr_flease_msgRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_rwr_set_primary_epochRequest_descriptor_, &xtreemfs_rwr_set_primary_epochRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_rwr_statusRequest_descriptor_, &xtreemfs_rwr_statusRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_rwr_truncateRequest_descriptor_, &xtreemfs_rwr_truncateRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_rwr_updateRequest_descriptor_, &xtreemfs_rwr_updateRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_internal_get_gmaxRequest_descriptor_, &xtreemfs_internal_get_gmaxRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_internal_get_file_sizeRequest_descriptor_, &xtreemfs_internal_get_file_sizeRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_internal_get_file_sizeResponse_descriptor_, &xtreemfs_internal_get_file_sizeResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_internal_read_localRequest_descriptor_, &xtreemfs_internal_read_localRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_internal_get_object_setRequest_descriptor_, &xtreemfs_internal_get_object_setRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_internal_get_fileid_listResponse_descriptor_, &xtreemfs_internal_get_fileid_listResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + lockRequest_descriptor_, &lockRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_pingMesssage_descriptor_, &xtreemfs_pingMesssage::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_rwr_auth_stateRequest_descriptor_, &xtreemfs_rwr_auth_stateRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_rwr_reset_completeRequest_descriptor_, &xtreemfs_rwr_reset_completeRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_xloc_set_invalidateRequest_descriptor_, &xtreemfs_xloc_set_invalidateRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + xtreemfs_xloc_set_invalidateResponse_descriptor_, &xtreemfs_xloc_set_invalidateResponse::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto() { + delete InternalGmax::default_instance_; + delete InternalGmax_reflection_; + delete Lock::default_instance_; + delete Lock_reflection_; + delete ObjectData::default_instance_; + delete ObjectData_reflection_; + delete ObjectList::default_instance_; + delete ObjectList_reflection_; + delete ObjectVersion::default_instance_; + delete ObjectVersion_reflection_; + delete TruncateRecord::default_instance_; + delete TruncateRecord_reflection_; + delete TruncateLog::default_instance_; + delete TruncateLog_reflection_; + delete XLocSetVersionState::default_instance_; + delete XLocSetVersionState_reflection_; + delete ReplicaStatus::default_instance_; + delete ReplicaStatus_reflection_; + delete ObjectVersionMapping::default_instance_; + delete ObjectVersionMapping_reflection_; + delete AuthoritativeReplicaState::default_instance_; + delete AuthoritativeReplicaState_reflection_; + delete InternalReadLocalResponse::default_instance_; + delete InternalReadLocalResponse_reflection_; + delete readRequest::default_instance_; + delete readRequest_reflection_; + delete truncateRequest::default_instance_; + delete truncateRequest_reflection_; + delete unlink_osd_Request::default_instance_; + delete unlink_osd_Request_reflection_; + delete writeRequest::default_instance_; + delete writeRequest_reflection_; + delete xtreemfs_broadcast_gmaxRequest::default_instance_; + delete xtreemfs_broadcast_gmaxRequest_reflection_; + delete xtreemfs_check_objectRequest::default_instance_; + delete xtreemfs_check_objectRequest_reflection_; + delete xtreemfs_cleanup_get_resultsResponse::default_instance_; + delete xtreemfs_cleanup_get_resultsResponse_reflection_; + delete xtreemfs_cleanup_is_runningResponse::default_instance_; + delete xtreemfs_cleanup_is_runningResponse_reflection_; + delete xtreemfs_cleanup_startRequest::default_instance_; + delete xtreemfs_cleanup_startRequest_reflection_; + delete xtreemfs_cleanup_statusResponse::default_instance_; + delete xtreemfs_cleanup_statusResponse_reflection_; + delete xtreemfs_rwr_fetchRequest::default_instance_; + delete xtreemfs_rwr_fetchRequest_reflection_; + delete xtreemfs_repair_objectRequest::default_instance_; + delete xtreemfs_repair_objectRequest_reflection_; + delete xtreemfs_rwr_flease_msgRequest::default_instance_; + delete xtreemfs_rwr_flease_msgRequest_reflection_; + delete xtreemfs_rwr_set_primary_epochRequest::default_instance_; + delete xtreemfs_rwr_set_primary_epochRequest_reflection_; + delete xtreemfs_rwr_statusRequest::default_instance_; + delete xtreemfs_rwr_statusRequest_reflection_; + delete xtreemfs_rwr_truncateRequest::default_instance_; + delete xtreemfs_rwr_truncateRequest_reflection_; + delete xtreemfs_rwr_updateRequest::default_instance_; + delete xtreemfs_rwr_updateRequest_reflection_; + delete xtreemfs_internal_get_gmaxRequest::default_instance_; + delete xtreemfs_internal_get_gmaxRequest_reflection_; + delete xtreemfs_internal_get_file_sizeRequest::default_instance_; + delete xtreemfs_internal_get_file_sizeRequest_reflection_; + delete xtreemfs_internal_get_file_sizeResponse::default_instance_; + delete xtreemfs_internal_get_file_sizeResponse_reflection_; + delete xtreemfs_internal_read_localRequest::default_instance_; + delete xtreemfs_internal_read_localRequest_reflection_; + delete xtreemfs_internal_get_object_setRequest::default_instance_; + delete xtreemfs_internal_get_object_setRequest_reflection_; + delete xtreemfs_internal_get_fileid_listResponse::default_instance_; + delete xtreemfs_internal_get_fileid_listResponse_reflection_; + delete lockRequest::default_instance_; + delete lockRequest_reflection_; + delete xtreemfs_pingMesssage::default_instance_; + delete xtreemfs_pingMesssage_reflection_; + delete xtreemfs_rwr_auth_stateRequest::default_instance_; + delete xtreemfs_rwr_auth_stateRequest_reflection_; + delete xtreemfs_rwr_reset_completeRequest::default_instance_; + delete xtreemfs_rwr_reset_completeRequest_reflection_; + delete xtreemfs_xloc_set_invalidateRequest::default_instance_; + delete xtreemfs_xloc_set_invalidateRequest_reflection_; + delete xtreemfs_xloc_set_invalidateResponse::default_instance_; + delete xtreemfs_xloc_set_invalidateResponse_reflection_; +} + +void protobuf_AddDesc_xtreemfs_2fOSD_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::xtreemfs::pbrpc::protobuf_AddDesc_include_2fPBRPC_2eproto(); + ::xtreemfs::pbrpc::protobuf_AddDesc_include_2fCommon_2eproto(); + ::xtreemfs::pbrpc::protobuf_AddDesc_xtreemfs_2fGlobalTypes_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\022xtreemfs/OSD.proto\022\016xtreemfs.pbrpc\032\023in" + "clude/PBRPC.proto\032\024include/Common.proto\032" + "\032xtreemfs/GlobalTypes.proto\"H\n\014InternalG" + "max\022\r\n\005epoch\030\001 \002(\006\022\021\n\tfile_size\030\002 \002(\006\022\026\n" + "\016last_object_id\030\003 \002(\006\"b\n\004Lock\022\022\n\nclient_" + "pid\030\001 \002(\007\022\023\n\013client_uuid\030\002 \002(\t\022\016\n\006length" + "\030\003 \002(\006\022\016\n\006offset\030\004 \002(\006\022\021\n\texclusive\030\005 \002(" + "\010\"U\n\nObjectData\022\020\n\010checksum\030\001 \002(\007\022\037\n\027inv" + "alid_checksum_on_osd\030\002 \002(\010\022\024\n\014zero_paddi" + "ng\030\003 \002(\007\"\?\n\nObjectList\022\013\n\003set\030\001 \002(\014\022\024\n\014s" + "tripe_width\030\002 \002(\007\022\016\n\006first_\030\003 \002(\007\">\n\rObj" + "ectVersion\022\025\n\robject_number\030\001 \002(\006\022\026\n\016obj" + "ect_version\030\002 \002(\006\"=\n\016TruncateRecord\022\017\n\007v" + "ersion\030\001 \002(\006\022\032\n\022last_object_number\030\002 \002(\006" + "\">\n\013TruncateLog\022/\n\007records\030\001 \003(\0132\036.xtree" + "mfs.pbrpc.TruncateRecord\"R\n\023XLocSetVersi" + "onState\022\017\n\007version\030\001 \002(\007\022\023\n\013invalidated\030" + "\002 \002(\010\022\025\n\rmodified_time\030\003 \001(\006\"\324\001\n\rReplica" + "Status\022\026\n\016truncate_epoch\030\001 \002(\006\022\021\n\tfile_s" + "ize\030\002 \002(\006\022\027\n\017max_obj_version\030\003 \002(\006\022\025\n\rpr" + "imary_epoch\030\004 \002(\007\0225\n\016objectVersions\030\005 \003(" + "\0132\035.xtreemfs.pbrpc.ObjectVersion\0221\n\014trun" + "cate_log\030\006 \002(\0132\033.xtreemfs.pbrpc.Truncate" + "Log\"X\n\024ObjectVersionMapping\022\025\n\robject_nu" + "mber\030\001 \002(\006\022\026\n\016object_version\030\002 \002(\006\022\021\n\tos" + "d_uuids\030\003 \003(\t\"\275\001\n\031AuthoritativeReplicaSt" + "ate\022\026\n\016truncate_epoch\030\001 \002(\006\022\027\n\017max_obj_v" + "ersion\030\004 \002(\006\022<\n\016objectVersions\030\002 \003(\0132$.x" + "treemfs.pbrpc.ObjectVersionMapping\0221\n\014tr" + "uncate_log\030\003 \002(\0132\033.xtreemfs.pbrpc.Trunca" + "teLog\"u\n\031InternalReadLocalResponse\022(\n\004da" + "ta\030\001 \002(\0132\032.xtreemfs.pbrpc.ObjectData\022.\n\n" + "object_set\030\002 \003(\0132\032.xtreemfs.pbrpc.Object" + "List\"\250\001\n\013readRequest\0229\n\020file_credentials" + "\030\001 \002(\0132\037.xtreemfs.pbrpc.FileCredentials\022" + "\017\n\007file_id\030\002 \002(\t\022\025\n\robject_number\030\003 \002(\006\022" + "\026\n\016object_version\030\004 \002(\006\022\016\n\006offset\030\005 \002(\007\022" + "\016\n\006length\030\006 \002(\007\"t\n\017truncateRequest\0229\n\020fi" + "le_credentials\030\001 \002(\0132\037.xtreemfs.pbrpc.Fi" + "leCredentials\022\017\n\007file_id\030\002 \002(\t\022\025\n\rnew_fi" + "le_size\030\003 \002(\006\"`\n\022unlink_osd_Request\0229\n\020f" + "ile_credentials\030\001 \002(\0132\037.xtreemfs.pbrpc.F" + "ileCredentials\022\017\n\007file_id\030\002 \002(\t\"\341\001\n\014writ" + "eRequest\0229\n\020file_credentials\030\001 \002(\0132\037.xtr" + "eemfs.pbrpc.FileCredentials\022\017\n\007file_id\030\002" + " \002(\t\022\025\n\robject_number\030\003 \002(\006\022\026\n\016object_ve" + "rsion\030\004 \002(\006\022\016\n\006offset\030\005 \002(\007\022\025\n\rlease_tim" + "eout\030\006 \002(\006\022/\n\013object_data\030\007 \002(\0132\032.xtreem" + "fs.pbrpc.ObjectData\"q\n\036xtreemfs_broadcas" + "t_gmaxRequest\022\017\n\007file_id\030\001 \002(\t\022\026\n\016trunca" + "te_epoch\030\002 \002(\006\022\023\n\013last_object\030\003 \002(\006\022\021\n\tf" + "ile_size\030\004 \002(\006\"\231\001\n\034xtreemfs_check_object" + "Request\0229\n\020file_credentials\030\001 \002(\0132\037.xtre" + "emfs.pbrpc.FileCredentials\022\017\n\007file_id\030\002 " + "\002(\t\022\025\n\robject_number\030\003 \002(\006\022\026\n\016object_ver" + "sion\030\004 \002(\006\"7\n$xtreemfs_cleanup_get_resul" + "tsResponse\022\017\n\007results\030\001 \003(\t\"9\n#xtreemfs_" + "cleanup_is_runningResponse\022\022\n\nis_running" + "\030\001 \002(\010\"\241\001\n\035xtreemfs_cleanup_startRequest" + "\022\026\n\016remove_zombies\030\001 \002(\010\022\035\n\025remove_unava" + "il_volume\030\002 \002(\010\022\026\n\016lost_and_found\030\003 \002(\010\022" + "\027\n\017delete_metadata\030\004 \002(\010\022\030\n\020metadata_tim" + "eout\030\005 \002(\007\"1\n\037xtreemfs_cleanup_statusRes" + "ponse\022\016\n\006status\030\001 \002(\t\"\226\001\n\031xtreemfs_rwr_f" + "etchRequest\0229\n\020file_credentials\030\001 \002(\0132\037." + "xtreemfs.pbrpc.FileCredentials\022\017\n\007file_i" + "d\030\002 \002(\t\022\025\n\robject_number\030\003 \002(\006\022\026\n\016object" + "_version\030\004 \002(\006\"\232\001\n\035xtreemfs_repair_objec" + "tRequest\0229\n\020file_credentials\030\001 \002(\0132\037.xtr" + "eemfs.pbrpc.FileCredentials\022\017\n\007file_id\030\002" + " \002(\t\022\025\n\robject_number\030\003 \002(\006\022\026\n\016object_ve" + "rsion\030\004 \002(\006\"N\n\036xtreemfs_rwr_flease_msgRe" + "quest\022\027\n\017sender_hostname\030\001 \002(\t\022\023\n\013sender" + "_port\030\002 \002(\007\"\212\001\n%xtreemfs_rwr_set_primary" + "_epochRequest\0229\n\020file_credentials\030\001 \002(\0132" + "\037.xtreemfs.pbrpc.FileCredentials\022\017\n\007file" + "_id\030\002 \002(\t\022\025\n\rprimary_epoch\030\003 \002(\007\"\207\001\n\032xtr" + "eemfs_rwr_statusRequest\0229\n\020file_credenti" + "als\030\001 \002(\0132\037.xtreemfs.pbrpc.FileCredentia" + "ls\022\017\n\007file_id\030\002 \002(\t\022\035\n\025max_local_obj_ver" + "sion\030\003 \002(\006\"\231\001\n\034xtreemfs_rwr_truncateRequ" + "est\0229\n\020file_credentials\030\001 \002(\0132\037.xtreemfs" + ".pbrpc.FileCredentials\022\017\n\007file_id\030\002 \002(\t\022" + "\025\n\rnew_file_size\030\003 \002(\006\022\026\n\016object_version" + "\030\004 \002(\006\"\347\001\n\032xtreemfs_rwr_updateRequest\0229\n" + "\020file_credentials\030\001 \002(\0132\037.xtreemfs.pbrpc" + ".FileCredentials\022\017\n\007file_id\030\002 \002(\t\022\025\n\rnew" + "_file_size\030\003 \002(\006\022\025\n\robject_number\030\007 \002(\006\022" + "\026\n\016object_version\030\004 \002(\006\022\016\n\006offset\030\005 \002(\007\022" + "\'\n\003obj\030\006 \002(\0132\032.xtreemfs.pbrpc.ObjectData" + "\"o\n!xtreemfs_internal_get_gmaxRequest\0229\n" + "\020file_credentials\030\001 \002(\0132\037.xtreemfs.pbrpc" + ".FileCredentials\022\017\n\007file_id\030\002 \002(\t\"t\n&xtr" + "eemfs_internal_get_file_sizeRequest\0229\n\020f" + "ile_credentials\030\001 \002(\0132\037.xtreemfs.pbrpc.F" + "ileCredentials\022\017\n\007file_id\030\002 \002(\t\"<\n\'xtree" + "mfs_internal_get_file_sizeResponse\022\021\n\tfi" + "le_size\030\001 \002(\006\"\222\002\n#xtreemfs_internal_read" + "_localRequest\0229\n\020file_credentials\030\001 \002(\0132" + "\037.xtreemfs.pbrpc.FileCredentials\022\017\n\007file" + "_id\030\002 \002(\t\022\025\n\robject_number\030\003 \002(\006\022\026\n\016obje" + "ct_version\030\004 \002(\006\022\016\n\006offset\030\005 \002(\007\022\016\n\006leng" + "th\030\006 \002(\007\022\032\n\022attach_object_list\030\007 \002(\010\0224\n\020" + "required_objects\030\010 \003(\0132\032.xtreemfs.pbrpc." + "ObjectList\"u\n\'xtreemfs_internal_get_obje" + "ct_setRequest\0229\n\020file_credentials\030\001 \002(\0132" + "\037.xtreemfs.pbrpc.FileCredentials\022\017\n\007file" + "_id\030\002 \002(\t\"=\n)xtreemfs_internal_get_filei" + "d_listResponse\022\020\n\010file_ids\030\001 \003(\t\"t\n\013lock" + "Request\0229\n\020file_credentials\030\001 \002(\0132\037.xtre" + "emfs.pbrpc.FileCredentials\022*\n\014lock_reque" + "st\030\002 \002(\0132\024.xtreemfs.pbrpc.Lock\"j\n\025xtreem" + "fs_pingMesssage\0227\n\013coordinates\030\001 \002(\0132\".x" + "treemfs.pbrpc.VivaldiCoordinates\022\030\n\020requ" + "est_response\030\002 \002(\010\"\246\001\n\036xtreemfs_rwr_auth" + "_stateRequest\0229\n\020file_credentials\030\001 \002(\0132" + "\037.xtreemfs.pbrpc.FileCredentials\022\017\n\007file" + "_id\030\002 \002(\t\0228\n\005state\030\003 \002(\0132).xtreemfs.pbrp" + "c.AuthoritativeReplicaState\"\207\001\n\"xtreemfs" + "_rwr_reset_completeRequest\0229\n\020file_crede" + "ntials\030\001 \002(\0132\037.xtreemfs.pbrpc.FileCreden" + "tials\022\017\n\007file_id\030\002 \002(\t\022\025\n\rprimary_epoch\030" + "\003 \002(\007\"q\n#xtreemfs_xloc_set_invalidateReq" + "uest\0229\n\020file_credentials\030\001 \002(\0132\037.xtreemf" + "s.pbrpc.FileCredentials\022\017\n\007file_id\030\002 \002(\t" + "\"\216\001\n$xtreemfs_xloc_set_invalidateRespons" + "e\022/\n\013lease_state\030\001 \002(\0162\032.xtreemfs.pbrpc." + "LeaseState\0225\n\016replica_status\030\002 \001(\0132\035.xtr" + "eemfs.pbrpc.ReplicaStatus*\215\001\n\017OSDHealthR" + "esult\022\034\n\030OSD_HEALTH_RESULT_PASSED\020\000\022\035\n\031O" + "SD_HEALTH_RESULT_WARNING\020\001\022\034\n\030OSD_HEALTH" + "_RESULT_FAILED\020\002\022\037\n\033OSD_HEALTH_RESULT_NO" + "T_AVAIL\020\0032\277\036\n\nOSDService\022L\n\004read\022\033.xtree" + "mfs.pbrpc.readRequest\032\032.xtreemfs.pbrpc.O" + "bjectData\"\013\215\265\030\n\000\000\000\230\265\030\001\022V\n\010truncate\022\037.xtr" + "eemfs.pbrpc.truncateRequest\032 .xtreemfs.p" + "brpc.OSDWriteResponse\"\007\215\265\030\013\000\000\000\022T\n\006unlink" + "\022\".xtreemfs.pbrpc.unlink_osd_Request\032\035.x" + "treemfs.pbrpc.emptyResponse\"\007\215\265\030\014\000\000\000\022T\n\005" + "write\022\034.xtreemfs.pbrpc.writeRequest\032 .xt" + "reemfs.pbrpc.OSDWriteResponse\"\013\215\265\030\r\000\000\000\240\265" + "\030\001\022q\n\027xtreemfs_broadcast_gmax\022..xtreemfs" + ".pbrpc.xtreemfs_broadcast_gmaxRequest\032\035." + "xtreemfs.pbrpc.emptyResponse\"\007\215\265\030\024\000\000\000\022j\n" + "\025xtreemfs_check_object\022,.xtreemfs.pbrpc." + "xtreemfs_check_objectRequest\032\032.xtreemfs." + "pbrpc.ObjectData\"\007\215\265\030\025\000\000\000\022{\n\034xtreemfs_cl" + "eanup_get_results\022\034.xtreemfs.pbrpc.empty" + "Request\0324.xtreemfs.pbrpc.xtreemfs_cleanu" + "p_get_resultsResponse\"\007\215\265\030\036\000\000\000\022y\n\033xtreem" + "fs_cleanup_is_running\022\034.xtreemfs.pbrpc.e" + "mptyRequest\0323.xtreemfs.pbrpc.xtreemfs_cl" + "eanup_is_runningResponse\"\007\215\265\030\037\000\000\000\022o\n\026xtr" + "eemfs_cleanup_start\022-.xtreemfs.pbrpc.xtr" + "eemfs_cleanup_startRequest\032\035.xtreemfs.pb" + "rpc.emptyResponse\"\007\215\265\030 \000\000\000\022q\n\027xtreemfs_c" + "leanup_status\022\034.xtreemfs.pbrpc.emptyRequ" + "est\032/.xtreemfs.pbrpc.xtreemfs_cleanup_st" + "atusResponse\"\007\215\265\030!\000\000\000\022]\n\025xtreemfs_cleanu" + "p_stop\022\034.xtreemfs.pbrpc.emptyRequest\032\035.x" + "treemfs.pbrpc.emptyResponse\"\007\215\265\030\"\000\000\000\022g\n\037" + "xtreemfs_cleanup_versions_start\022\034.xtreem" + "fs.pbrpc.emptyRequest\032\035.xtreemfs.pbrpc.e" + "mptyResponse\"\007\215\265\030#\000\000\000\022o\n\026xtreemfs_repair" + "_object\022-.xtreemfs.pbrpc.xtreemfs_repair" + "_objectRequest\032\035.xtreemfs.pbrpc.emptyRes" + "ponse\"\007\215\265\030$\000\000\000\022d\n\022xtreemfs_rwr_fetch\022).x" + "treemfs.pbrpc.xtreemfs_rwr_fetchRequest\032" + "\032.xtreemfs.pbrpc.ObjectData\"\007\215\265\030I\000\000\000\022u\n\027" + "xtreemfs_rwr_flease_msg\022..xtreemfs.pbrpc" + ".xtreemfs_rwr_flease_msgRequest\032\035.xtreem" + "fs.pbrpc.emptyResponse\"\013\215\265\030G\000\000\000\240\265\030\001\022^\n\023x" + "treemfs_rwr_notify\022\037.xtreemfs.pbrpc.File" + "Credentials\032\035.xtreemfs.pbrpc.emptyRespon" + "se\"\007\215\265\030K\000\000\000\022|\n\036xtreemfs_rwr_set_primary_" + "epoch\0225.xtreemfs.pbrpc.xtreemfs_rwr_set_" + "primary_epochRequest\032\032.xtreemfs.pbrpc.Ob" + "jectData\"\007\215\265\030N\000\000\000\022i\n\023xtreemfs_rwr_status" + "\022*.xtreemfs.pbrpc.xtreemfs_rwr_statusReq" + "uest\032\035.xtreemfs.pbrpc.ReplicaStatus\"\007\215\265\030" + "L\000\000\000\022m\n\025xtreemfs_rwr_truncate\022,.xtreemfs" + ".pbrpc.xtreemfs_rwr_truncateRequest\032\035.xt" + "reemfs.pbrpc.emptyResponse\"\007\215\265\030J\000\000\000\022m\n\023x" + "treemfs_rwr_update\022*.xtreemfs.pbrpc.xtre" + "emfs_rwr_updateRequest\032\035.xtreemfs.pbrpc." + "emptyResponse\"\013\215\265\030H\000\000\000\240\265\030\001\022q\n\027xtreemfs_r" + "wr_auth_state\022..xtreemfs.pbrpc.xtreemfs_" + "rwr_auth_stateRequest\032\035.xtreemfs.pbrpc.e" + "mptyResponse\"\007\215\265\030O\000\000\000\022y\n\033xtreemfs_rwr_re" + "set_complete\0222.xtreemfs.pbrpc.xtreemfs_r" + "wr_reset_completeRequest\032\035.xtreemfs.pbrp" + "c.emptyResponse\"\007\215\265\030P\000\000\000\022v\n\032xtreemfs_int" + "ernal_get_gmax\0221.xtreemfs.pbrpc.xtreemfs" + "_internal_get_gmaxRequest\032\034.xtreemfs.pbr" + "pc.InternalGmax\"\007\215\265\030(\000\000\000\022h\n\032xtreemfs_int" + "ernal_truncate\022\037.xtreemfs.pbrpc.truncate" + "Request\032 .xtreemfs.pbrpc.OSDWriteRespons" + "e\"\007\215\265\030)\000\000\000\022\233\001\n\037xtreemfs_internal_get_fil" + "e_size\0226.xtreemfs.pbrpc.xtreemfs_interna" + "l_get_file_sizeRequest\0327.xtreemfs.pbrpc." + "xtreemfs_internal_get_file_sizeResponse\"" + "\007\215\265\030*\000\000\000\022\207\001\n\034xtreemfs_internal_read_loca" + "l\0223.xtreemfs.pbrpc.xtreemfs_internal_rea" + "d_localRequest\032).xtreemfs.pbrpc.Internal" + "ReadLocalResponse\"\007\215\265\030+\000\000\000\022\200\001\n xtreemfs_" + "internal_get_object_set\0227.xtreemfs.pbrpc" + ".xtreemfs_internal_get_object_setRequest" + "\032\032.xtreemfs.pbrpc.ObjectList\"\007\215\265\030,\000\000\000\022\205\001" + "\n!xtreemfs_internal_get_fileid_list\022\034.xt" + "reemfs.pbrpc.emptyRequest\0329.xtreemfs.pbr" + "pc.xtreemfs_internal_get_fileid_listResp" + "onse\"\007\215\265\030-\000\000\000\022S\n\025xtreemfs_lock_acquire\022\033" + ".xtreemfs.pbrpc.lockRequest\032\024.xtreemfs.p" + "brpc.Lock\"\007\215\265\0302\000\000\000\022Q\n\023xtreemfs_lock_chec" + "k\022\033.xtreemfs.pbrpc.lockRequest\032\024.xtreemf" + "s.pbrpc.Lock\"\007\215\265\0303\000\000\000\022\\\n\025xtreemfs_lock_r" + "elease\022\033.xtreemfs.pbrpc.lockRequest\032\035.xt" + "reemfs.pbrpc.emptyResponse\"\007\215\265\0304\000\000\000\022f\n\rx" + "treemfs_ping\022%.xtreemfs.pbrpc.xtreemfs_p" + "ingMesssage\032%.xtreemfs.pbrpc.xtreemfs_pi" + "ngMesssage\"\007\215\265\030<\000\000\000\022Y\n\021xtreemfs_shutdown" + "\022\034.xtreemfs.pbrpc.emptyRequest\032\035.xtreemf" + "s.pbrpc.emptyResponse\"\007\215\265\030F\000\000\000\022\222\001\n\034xtree" + "mfs_xloc_set_invalidate\0223.xtreemfs.pbrpc" + ".xtreemfs_xloc_set_invalidateRequest\0324.x" + "treemfs.pbrpc.xtreemfs_xloc_set_invalida" + "teResponse\"\007\215\265\030Q\000\000\000\022}\n#xtreemfs_rwr_auth" + "_state_invalidated\022..xtreemfs.pbrpc.xtre" + "emfs_rwr_auth_stateRequest\032\035.xtreemfs.pb" + "rpc.emptyResponse\"\007\215\265\030R\000\000\000\032\007\225\265\0301u\000\000B(\n&o" + "rg.xtreemfs.pbrpc.generatedinterfaces", 9237); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "xtreemfs/OSD.proto", &protobuf_RegisterTypes); + InternalGmax::default_instance_ = new InternalGmax(); + Lock::default_instance_ = new Lock(); + ObjectData::default_instance_ = new ObjectData(); + ObjectList::default_instance_ = new ObjectList(); + ObjectVersion::default_instance_ = new ObjectVersion(); + TruncateRecord::default_instance_ = new TruncateRecord(); + TruncateLog::default_instance_ = new TruncateLog(); + XLocSetVersionState::default_instance_ = new XLocSetVersionState(); + ReplicaStatus::default_instance_ = new ReplicaStatus(); + ObjectVersionMapping::default_instance_ = new ObjectVersionMapping(); + AuthoritativeReplicaState::default_instance_ = new AuthoritativeReplicaState(); + InternalReadLocalResponse::default_instance_ = new InternalReadLocalResponse(); + readRequest::default_instance_ = new readRequest(); + truncateRequest::default_instance_ = new truncateRequest(); + unlink_osd_Request::default_instance_ = new unlink_osd_Request(); + writeRequest::default_instance_ = new writeRequest(); + xtreemfs_broadcast_gmaxRequest::default_instance_ = new xtreemfs_broadcast_gmaxRequest(); + xtreemfs_check_objectRequest::default_instance_ = new xtreemfs_check_objectRequest(); + xtreemfs_cleanup_get_resultsResponse::default_instance_ = new xtreemfs_cleanup_get_resultsResponse(); + xtreemfs_cleanup_is_runningResponse::default_instance_ = new xtreemfs_cleanup_is_runningResponse(); + xtreemfs_cleanup_startRequest::default_instance_ = new xtreemfs_cleanup_startRequest(); + xtreemfs_cleanup_statusResponse::default_instance_ = new xtreemfs_cleanup_statusResponse(); + xtreemfs_rwr_fetchRequest::default_instance_ = new xtreemfs_rwr_fetchRequest(); + xtreemfs_repair_objectRequest::default_instance_ = new xtreemfs_repair_objectRequest(); + xtreemfs_rwr_flease_msgRequest::default_instance_ = new xtreemfs_rwr_flease_msgRequest(); + xtreemfs_rwr_set_primary_epochRequest::default_instance_ = new xtreemfs_rwr_set_primary_epochRequest(); + xtreemfs_rwr_statusRequest::default_instance_ = new xtreemfs_rwr_statusRequest(); + xtreemfs_rwr_truncateRequest::default_instance_ = new xtreemfs_rwr_truncateRequest(); + xtreemfs_rwr_updateRequest::default_instance_ = new xtreemfs_rwr_updateRequest(); + xtreemfs_internal_get_gmaxRequest::default_instance_ = new xtreemfs_internal_get_gmaxRequest(); + xtreemfs_internal_get_file_sizeRequest::default_instance_ = new xtreemfs_internal_get_file_sizeRequest(); + xtreemfs_internal_get_file_sizeResponse::default_instance_ = new xtreemfs_internal_get_file_sizeResponse(); + xtreemfs_internal_read_localRequest::default_instance_ = new xtreemfs_internal_read_localRequest(); + xtreemfs_internal_get_object_setRequest::default_instance_ = new xtreemfs_internal_get_object_setRequest(); + xtreemfs_internal_get_fileid_listResponse::default_instance_ = new xtreemfs_internal_get_fileid_listResponse(); + lockRequest::default_instance_ = new lockRequest(); + xtreemfs_pingMesssage::default_instance_ = new xtreemfs_pingMesssage(); + xtreemfs_rwr_auth_stateRequest::default_instance_ = new xtreemfs_rwr_auth_stateRequest(); + xtreemfs_rwr_reset_completeRequest::default_instance_ = new xtreemfs_rwr_reset_completeRequest(); + xtreemfs_xloc_set_invalidateRequest::default_instance_ = new xtreemfs_xloc_set_invalidateRequest(); + xtreemfs_xloc_set_invalidateResponse::default_instance_ = new xtreemfs_xloc_set_invalidateResponse(); + InternalGmax::default_instance_->InitAsDefaultInstance(); + Lock::default_instance_->InitAsDefaultInstance(); + ObjectData::default_instance_->InitAsDefaultInstance(); + ObjectList::default_instance_->InitAsDefaultInstance(); + ObjectVersion::default_instance_->InitAsDefaultInstance(); + TruncateRecord::default_instance_->InitAsDefaultInstance(); + TruncateLog::default_instance_->InitAsDefaultInstance(); + XLocSetVersionState::default_instance_->InitAsDefaultInstance(); + ReplicaStatus::default_instance_->InitAsDefaultInstance(); + ObjectVersionMapping::default_instance_->InitAsDefaultInstance(); + AuthoritativeReplicaState::default_instance_->InitAsDefaultInstance(); + InternalReadLocalResponse::default_instance_->InitAsDefaultInstance(); + readRequest::default_instance_->InitAsDefaultInstance(); + truncateRequest::default_instance_->InitAsDefaultInstance(); + unlink_osd_Request::default_instance_->InitAsDefaultInstance(); + writeRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_broadcast_gmaxRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_check_objectRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_cleanup_get_resultsResponse::default_instance_->InitAsDefaultInstance(); + xtreemfs_cleanup_is_runningResponse::default_instance_->InitAsDefaultInstance(); + xtreemfs_cleanup_startRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_cleanup_statusResponse::default_instance_->InitAsDefaultInstance(); + xtreemfs_rwr_fetchRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_repair_objectRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_rwr_flease_msgRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_rwr_set_primary_epochRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_rwr_statusRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_rwr_truncateRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_rwr_updateRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_internal_get_gmaxRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_internal_get_file_sizeRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_internal_get_file_sizeResponse::default_instance_->InitAsDefaultInstance(); + xtreemfs_internal_read_localRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_internal_get_object_setRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_internal_get_fileid_listResponse::default_instance_->InitAsDefaultInstance(); + lockRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_pingMesssage::default_instance_->InitAsDefaultInstance(); + xtreemfs_rwr_auth_stateRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_rwr_reset_completeRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_xloc_set_invalidateRequest::default_instance_->InitAsDefaultInstance(); + xtreemfs_xloc_set_invalidateResponse::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_xtreemfs_2fOSD_2eproto { + StaticDescriptorInitializer_xtreemfs_2fOSD_2eproto() { + protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + } +} static_descriptor_initializer_xtreemfs_2fOSD_2eproto_; +const ::google::protobuf::EnumDescriptor* OSDHealthResult_descriptor() { + protobuf_AssignDescriptorsOnce(); + return OSDHealthResult_descriptor_; +} +bool OSDHealthResult_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + + +// =================================================================== + +#ifndef _MSC_VER +const int InternalGmax::kEpochFieldNumber; +const int InternalGmax::kFileSizeFieldNumber; +const int InternalGmax::kLastObjectIdFieldNumber; +#endif // !_MSC_VER + +InternalGmax::InternalGmax() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void InternalGmax::InitAsDefaultInstance() { +} + +InternalGmax::InternalGmax(const InternalGmax& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void InternalGmax::SharedCtor() { + _cached_size_ = 0; + epoch_ = GOOGLE_ULONGLONG(0); + file_size_ = GOOGLE_ULONGLONG(0); + last_object_id_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +InternalGmax::~InternalGmax() { + SharedDtor(); +} + +void InternalGmax::SharedDtor() { + if (this != default_instance_) { + } +} + +void InternalGmax::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* InternalGmax::descriptor() { + protobuf_AssignDescriptorsOnce(); + return InternalGmax_descriptor_; +} + +const InternalGmax& InternalGmax::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +InternalGmax* InternalGmax::default_instance_ = NULL; + +InternalGmax* InternalGmax::New() const { + return new InternalGmax; +} + +void InternalGmax::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + epoch_ = GOOGLE_ULONGLONG(0); + file_size_ = GOOGLE_ULONGLONG(0); + last_object_id_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool InternalGmax::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 epoch = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &epoch_))); + set_has_epoch(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(17)) goto parse_file_size; + break; + } + + // required fixed64 file_size = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_file_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &file_size_))); + set_has_file_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_last_object_id; + break; + } + + // required fixed64 last_object_id = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_last_object_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &last_object_id_))); + set_has_last_object_id(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void InternalGmax::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 epoch = 1; + if (has_epoch()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->epoch(), output); + } + + // required fixed64 file_size = 2; + if (has_file_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(2, this->file_size(), output); + } + + // required fixed64 last_object_id = 3; + if (has_last_object_id()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->last_object_id(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* InternalGmax::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 epoch = 1; + if (has_epoch()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->epoch(), target); + } + + // required fixed64 file_size = 2; + if (has_file_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(2, this->file_size(), target); + } + + // required fixed64 last_object_id = 3; + if (has_last_object_id()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->last_object_id(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int InternalGmax::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 epoch = 1; + if (has_epoch()) { + total_size += 1 + 8; + } + + // required fixed64 file_size = 2; + if (has_file_size()) { + total_size += 1 + 8; + } + + // required fixed64 last_object_id = 3; + if (has_last_object_id()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void InternalGmax::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const InternalGmax* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void InternalGmax::MergeFrom(const InternalGmax& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_epoch()) { + set_epoch(from.epoch()); + } + if (from.has_file_size()) { + set_file_size(from.file_size()); + } + if (from.has_last_object_id()) { + set_last_object_id(from.last_object_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void InternalGmax::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void InternalGmax::CopyFrom(const InternalGmax& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool InternalGmax::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void InternalGmax::Swap(InternalGmax* other) { + if (other != this) { + std::swap(epoch_, other->epoch_); + std::swap(file_size_, other->file_size_); + std::swap(last_object_id_, other->last_object_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata InternalGmax::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = InternalGmax_descriptor_; + metadata.reflection = InternalGmax_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Lock::kClientPidFieldNumber; +const int Lock::kClientUuidFieldNumber; +const int Lock::kLengthFieldNumber; +const int Lock::kOffsetFieldNumber; +const int Lock::kExclusiveFieldNumber; +#endif // !_MSC_VER + +Lock::Lock() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Lock::InitAsDefaultInstance() { +} + +Lock::Lock(const Lock& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Lock::SharedCtor() { + _cached_size_ = 0; + client_pid_ = 0u; + client_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + length_ = GOOGLE_ULONGLONG(0); + offset_ = GOOGLE_ULONGLONG(0); + exclusive_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Lock::~Lock() { + SharedDtor(); +} + +void Lock::SharedDtor() { + if (client_uuid_ != &::google::protobuf::internal::kEmptyString) { + delete client_uuid_; + } + if (this != default_instance_) { + } +} + +void Lock::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Lock::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Lock_descriptor_; +} + +const Lock& Lock::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +Lock* Lock::default_instance_ = NULL; + +Lock* Lock::New() const { + return new Lock; +} + +void Lock::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + client_pid_ = 0u; + if (has_client_uuid()) { + if (client_uuid_ != &::google::protobuf::internal::kEmptyString) { + client_uuid_->clear(); + } + } + length_ = GOOGLE_ULONGLONG(0); + offset_ = GOOGLE_ULONGLONG(0); + exclusive_ = false; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Lock::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed32 client_pid = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &client_pid_))); + set_has_client_pid(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_client_uuid; + break; + } + + // required string client_uuid = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_client_uuid: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_client_uuid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->client_uuid().data(), this->client_uuid().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_length; + break; + } + + // required fixed64 length = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_length: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &length_))); + set_has_length(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(33)) goto parse_offset; + break; + } + + // required fixed64 offset = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_offset: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &offset_))); + set_has_offset(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(40)) goto parse_exclusive; + break; + } + + // required bool exclusive = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_exclusive: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &exclusive_))); + set_has_exclusive(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Lock::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed32 client_pid = 1; + if (has_client_pid()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(1, this->client_pid(), output); + } + + // required string client_uuid = 2; + if (has_client_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->client_uuid().data(), this->client_uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->client_uuid(), output); + } + + // required fixed64 length = 3; + if (has_length()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->length(), output); + } + + // required fixed64 offset = 4; + if (has_offset()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->offset(), output); + } + + // required bool exclusive = 5; + if (has_exclusive()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->exclusive(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Lock::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed32 client_pid = 1; + if (has_client_pid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(1, this->client_pid(), target); + } + + // required string client_uuid = 2; + if (has_client_uuid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->client_uuid().data(), this->client_uuid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->client_uuid(), target); + } + + // required fixed64 length = 3; + if (has_length()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->length(), target); + } + + // required fixed64 offset = 4; + if (has_offset()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->offset(), target); + } + + // required bool exclusive = 5; + if (has_exclusive()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->exclusive(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Lock::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed32 client_pid = 1; + if (has_client_pid()) { + total_size += 1 + 4; + } + + // required string client_uuid = 2; + if (has_client_uuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->client_uuid()); + } + + // required fixed64 length = 3; + if (has_length()) { + total_size += 1 + 8; + } + + // required fixed64 offset = 4; + if (has_offset()) { + total_size += 1 + 8; + } + + // required bool exclusive = 5; + if (has_exclusive()) { + total_size += 1 + 1; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Lock::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Lock* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Lock::MergeFrom(const Lock& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_client_pid()) { + set_client_pid(from.client_pid()); + } + if (from.has_client_uuid()) { + set_client_uuid(from.client_uuid()); + } + if (from.has_length()) { + set_length(from.length()); + } + if (from.has_offset()) { + set_offset(from.offset()); + } + if (from.has_exclusive()) { + set_exclusive(from.exclusive()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Lock::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Lock::CopyFrom(const Lock& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Lock::IsInitialized() const { + if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false; + + return true; +} + +void Lock::Swap(Lock* other) { + if (other != this) { + std::swap(client_pid_, other->client_pid_); + std::swap(client_uuid_, other->client_uuid_); + std::swap(length_, other->length_); + std::swap(offset_, other->offset_); + std::swap(exclusive_, other->exclusive_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Lock::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Lock_descriptor_; + metadata.reflection = Lock_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ObjectData::kChecksumFieldNumber; +const int ObjectData::kInvalidChecksumOnOsdFieldNumber; +const int ObjectData::kZeroPaddingFieldNumber; +#endif // !_MSC_VER + +ObjectData::ObjectData() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ObjectData::InitAsDefaultInstance() { +} + +ObjectData::ObjectData(const ObjectData& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ObjectData::SharedCtor() { + _cached_size_ = 0; + checksum_ = 0u; + invalid_checksum_on_osd_ = false; + zero_padding_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ObjectData::~ObjectData() { + SharedDtor(); +} + +void ObjectData::SharedDtor() { + if (this != default_instance_) { + } +} + +void ObjectData::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ObjectData::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ObjectData_descriptor_; +} + +const ObjectData& ObjectData::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +ObjectData* ObjectData::default_instance_ = NULL; + +ObjectData* ObjectData::New() const { + return new ObjectData; +} + +void ObjectData::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + checksum_ = 0u; + invalid_checksum_on_osd_ = false; + zero_padding_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ObjectData::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed32 checksum = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &checksum_))); + set_has_checksum(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_invalid_checksum_on_osd; + break; + } + + // required bool invalid_checksum_on_osd = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_invalid_checksum_on_osd: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &invalid_checksum_on_osd_))); + set_has_invalid_checksum_on_osd(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(29)) goto parse_zero_padding; + break; + } + + // required fixed32 zero_padding = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_zero_padding: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &zero_padding_))); + set_has_zero_padding(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ObjectData::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed32 checksum = 1; + if (has_checksum()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(1, this->checksum(), output); + } + + // required bool invalid_checksum_on_osd = 2; + if (has_invalid_checksum_on_osd()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->invalid_checksum_on_osd(), output); + } + + // required fixed32 zero_padding = 3; + if (has_zero_padding()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(3, this->zero_padding(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ObjectData::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed32 checksum = 1; + if (has_checksum()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(1, this->checksum(), target); + } + + // required bool invalid_checksum_on_osd = 2; + if (has_invalid_checksum_on_osd()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->invalid_checksum_on_osd(), target); + } + + // required fixed32 zero_padding = 3; + if (has_zero_padding()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(3, this->zero_padding(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ObjectData::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed32 checksum = 1; + if (has_checksum()) { + total_size += 1 + 4; + } + + // required bool invalid_checksum_on_osd = 2; + if (has_invalid_checksum_on_osd()) { + total_size += 1 + 1; + } + + // required fixed32 zero_padding = 3; + if (has_zero_padding()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ObjectData::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ObjectData* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ObjectData::MergeFrom(const ObjectData& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_checksum()) { + set_checksum(from.checksum()); + } + if (from.has_invalid_checksum_on_osd()) { + set_invalid_checksum_on_osd(from.invalid_checksum_on_osd()); + } + if (from.has_zero_padding()) { + set_zero_padding(from.zero_padding()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ObjectData::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ObjectData::CopyFrom(const ObjectData& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ObjectData::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void ObjectData::Swap(ObjectData* other) { + if (other != this) { + std::swap(checksum_, other->checksum_); + std::swap(invalid_checksum_on_osd_, other->invalid_checksum_on_osd_); + std::swap(zero_padding_, other->zero_padding_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ObjectData::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ObjectData_descriptor_; + metadata.reflection = ObjectData_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ObjectList::kSetFieldNumber; +const int ObjectList::kStripeWidthFieldNumber; +const int ObjectList::kFirstFieldNumber; +#endif // !_MSC_VER + +ObjectList::ObjectList() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ObjectList::InitAsDefaultInstance() { +} + +ObjectList::ObjectList(const ObjectList& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ObjectList::SharedCtor() { + _cached_size_ = 0; + set_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + stripe_width_ = 0u; + first__ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ObjectList::~ObjectList() { + SharedDtor(); +} + +void ObjectList::SharedDtor() { + if (set_ != &::google::protobuf::internal::kEmptyString) { + delete set_; + } + if (this != default_instance_) { + } +} + +void ObjectList::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ObjectList::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ObjectList_descriptor_; +} + +const ObjectList& ObjectList::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +ObjectList* ObjectList::default_instance_ = NULL; + +ObjectList* ObjectList::New() const { + return new ObjectList; +} + +void ObjectList::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_set()) { + if (set_ != &::google::protobuf::internal::kEmptyString) { + set_->clear(); + } + } + stripe_width_ = 0u; + first__ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ObjectList::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required bytes set = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_set())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(21)) goto parse_stripe_width; + break; + } + + // required fixed32 stripe_width = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_stripe_width: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &stripe_width_))); + set_has_stripe_width(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(29)) goto parse_first_; + break; + } + + // required fixed32 first_ = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_first_: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &first__))); + set_has_first_(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ObjectList::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required bytes set = 1; + if (has_set()) { + ::google::protobuf::internal::WireFormatLite::WriteBytes( + 1, this->set(), output); + } + + // required fixed32 stripe_width = 2; + if (has_stripe_width()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(2, this->stripe_width(), output); + } + + // required fixed32 first_ = 3; + if (has_first_()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(3, this->first_(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ObjectList::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required bytes set = 1; + if (has_set()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 1, this->set(), target); + } + + // required fixed32 stripe_width = 2; + if (has_stripe_width()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(2, this->stripe_width(), target); + } + + // required fixed32 first_ = 3; + if (has_first_()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(3, this->first_(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ObjectList::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required bytes set = 1; + if (has_set()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->set()); + } + + // required fixed32 stripe_width = 2; + if (has_stripe_width()) { + total_size += 1 + 4; + } + + // required fixed32 first_ = 3; + if (has_first_()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ObjectList::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ObjectList* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ObjectList::MergeFrom(const ObjectList& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_set()) { + set_set(from.set()); + } + if (from.has_stripe_width()) { + set_stripe_width(from.stripe_width()); + } + if (from.has_first_()) { + set_first_(from.first_()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ObjectList::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ObjectList::CopyFrom(const ObjectList& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ObjectList::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void ObjectList::Swap(ObjectList* other) { + if (other != this) { + std::swap(set_, other->set_); + std::swap(stripe_width_, other->stripe_width_); + std::swap(first__, other->first__); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ObjectList::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ObjectList_descriptor_; + metadata.reflection = ObjectList_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ObjectVersion::kObjectNumberFieldNumber; +const int ObjectVersion::kObjectVersionFieldNumber; +#endif // !_MSC_VER + +ObjectVersion::ObjectVersion() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ObjectVersion::InitAsDefaultInstance() { +} + +ObjectVersion::ObjectVersion(const ObjectVersion& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ObjectVersion::SharedCtor() { + _cached_size_ = 0; + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ObjectVersion::~ObjectVersion() { + SharedDtor(); +} + +void ObjectVersion::SharedDtor() { + if (this != default_instance_) { + } +} + +void ObjectVersion::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ObjectVersion::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ObjectVersion_descriptor_; +} + +const ObjectVersion& ObjectVersion::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +ObjectVersion* ObjectVersion::default_instance_ = NULL; + +ObjectVersion* ObjectVersion::New() const { + return new ObjectVersion; +} + +void ObjectVersion::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ObjectVersion::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 object_number = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_number_))); + set_has_object_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(17)) goto parse_object_version; + break; + } + + // required fixed64 object_version = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_version_))); + set_has_object_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ObjectVersion::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 object_number = 1; + if (has_object_number()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->object_number(), output); + } + + // required fixed64 object_version = 2; + if (has_object_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(2, this->object_version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ObjectVersion::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 object_number = 1; + if (has_object_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->object_number(), target); + } + + // required fixed64 object_version = 2; + if (has_object_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(2, this->object_version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ObjectVersion::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 object_number = 1; + if (has_object_number()) { + total_size += 1 + 8; + } + + // required fixed64 object_version = 2; + if (has_object_version()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ObjectVersion::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ObjectVersion* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ObjectVersion::MergeFrom(const ObjectVersion& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_object_number()) { + set_object_number(from.object_number()); + } + if (from.has_object_version()) { + set_object_version(from.object_version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ObjectVersion::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ObjectVersion::CopyFrom(const ObjectVersion& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ObjectVersion::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void ObjectVersion::Swap(ObjectVersion* other) { + if (other != this) { + std::swap(object_number_, other->object_number_); + std::swap(object_version_, other->object_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ObjectVersion::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ObjectVersion_descriptor_; + metadata.reflection = ObjectVersion_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int TruncateRecord::kVersionFieldNumber; +const int TruncateRecord::kLastObjectNumberFieldNumber; +#endif // !_MSC_VER + +TruncateRecord::TruncateRecord() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void TruncateRecord::InitAsDefaultInstance() { +} + +TruncateRecord::TruncateRecord(const TruncateRecord& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void TruncateRecord::SharedCtor() { + _cached_size_ = 0; + version_ = GOOGLE_ULONGLONG(0); + last_object_number_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +TruncateRecord::~TruncateRecord() { + SharedDtor(); +} + +void TruncateRecord::SharedDtor() { + if (this != default_instance_) { + } +} + +void TruncateRecord::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* TruncateRecord::descriptor() { + protobuf_AssignDescriptorsOnce(); + return TruncateRecord_descriptor_; +} + +const TruncateRecord& TruncateRecord::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +TruncateRecord* TruncateRecord::default_instance_ = NULL; + +TruncateRecord* TruncateRecord::New() const { + return new TruncateRecord; +} + +void TruncateRecord::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + version_ = GOOGLE_ULONGLONG(0); + last_object_number_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool TruncateRecord::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 version = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &version_))); + set_has_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(17)) goto parse_last_object_number; + break; + } + + // required fixed64 last_object_number = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_last_object_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &last_object_number_))); + set_has_last_object_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void TruncateRecord::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 version = 1; + if (has_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->version(), output); + } + + // required fixed64 last_object_number = 2; + if (has_last_object_number()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(2, this->last_object_number(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* TruncateRecord::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 version = 1; + if (has_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->version(), target); + } + + // required fixed64 last_object_number = 2; + if (has_last_object_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(2, this->last_object_number(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int TruncateRecord::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 version = 1; + if (has_version()) { + total_size += 1 + 8; + } + + // required fixed64 last_object_number = 2; + if (has_last_object_number()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void TruncateRecord::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const TruncateRecord* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void TruncateRecord::MergeFrom(const TruncateRecord& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_version()) { + set_version(from.version()); + } + if (from.has_last_object_number()) { + set_last_object_number(from.last_object_number()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void TruncateRecord::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void TruncateRecord::CopyFrom(const TruncateRecord& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool TruncateRecord::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void TruncateRecord::Swap(TruncateRecord* other) { + if (other != this) { + std::swap(version_, other->version_); + std::swap(last_object_number_, other->last_object_number_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata TruncateRecord::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = TruncateRecord_descriptor_; + metadata.reflection = TruncateRecord_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int TruncateLog::kRecordsFieldNumber; +#endif // !_MSC_VER + +TruncateLog::TruncateLog() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void TruncateLog::InitAsDefaultInstance() { +} + +TruncateLog::TruncateLog(const TruncateLog& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void TruncateLog::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +TruncateLog::~TruncateLog() { + SharedDtor(); +} + +void TruncateLog::SharedDtor() { + if (this != default_instance_) { + } +} + +void TruncateLog::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* TruncateLog::descriptor() { + protobuf_AssignDescriptorsOnce(); + return TruncateLog_descriptor_; +} + +const TruncateLog& TruncateLog::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +TruncateLog* TruncateLog::default_instance_ = NULL; + +TruncateLog* TruncateLog::New() const { + return new TruncateLog; +} + +void TruncateLog::Clear() { + records_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool TruncateLog::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_records: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_records())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_records; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void TruncateLog::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + for (int i = 0; i < this->records_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->records(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* TruncateLog::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + for (int i = 0; i < this->records_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->records(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int TruncateLog::ByteSize() const { + int total_size = 0; + + // repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + total_size += 1 * this->records_size(); + for (int i = 0; i < this->records_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->records(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void TruncateLog::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const TruncateLog* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void TruncateLog::MergeFrom(const TruncateLog& from) { + GOOGLE_CHECK_NE(&from, this); + records_.MergeFrom(from.records_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void TruncateLog::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void TruncateLog::CopyFrom(const TruncateLog& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool TruncateLog::IsInitialized() const { + + for (int i = 0; i < records_size(); i++) { + if (!this->records(i).IsInitialized()) return false; + } + return true; +} + +void TruncateLog::Swap(TruncateLog* other) { + if (other != this) { + records_.Swap(&other->records_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata TruncateLog::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = TruncateLog_descriptor_; + metadata.reflection = TruncateLog_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int XLocSetVersionState::kVersionFieldNumber; +const int XLocSetVersionState::kInvalidatedFieldNumber; +const int XLocSetVersionState::kModifiedTimeFieldNumber; +#endif // !_MSC_VER + +XLocSetVersionState::XLocSetVersionState() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void XLocSetVersionState::InitAsDefaultInstance() { +} + +XLocSetVersionState::XLocSetVersionState(const XLocSetVersionState& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void XLocSetVersionState::SharedCtor() { + _cached_size_ = 0; + version_ = 0u; + invalidated_ = false; + modified_time_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +XLocSetVersionState::~XLocSetVersionState() { + SharedDtor(); +} + +void XLocSetVersionState::SharedDtor() { + if (this != default_instance_) { + } +} + +void XLocSetVersionState::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* XLocSetVersionState::descriptor() { + protobuf_AssignDescriptorsOnce(); + return XLocSetVersionState_descriptor_; +} + +const XLocSetVersionState& XLocSetVersionState::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +XLocSetVersionState* XLocSetVersionState::default_instance_ = NULL; + +XLocSetVersionState* XLocSetVersionState::New() const { + return new XLocSetVersionState; +} + +void XLocSetVersionState::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + version_ = 0u; + invalidated_ = false; + modified_time_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool XLocSetVersionState::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed32 version = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &version_))); + set_has_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_invalidated; + break; + } + + // required bool invalidated = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_invalidated: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &invalidated_))); + set_has_invalidated(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_modified_time; + break; + } + + // optional fixed64 modified_time = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_modified_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &modified_time_))); + set_has_modified_time(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void XLocSetVersionState::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed32 version = 1; + if (has_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(1, this->version(), output); + } + + // required bool invalidated = 2; + if (has_invalidated()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->invalidated(), output); + } + + // optional fixed64 modified_time = 3; + if (has_modified_time()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->modified_time(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* XLocSetVersionState::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed32 version = 1; + if (has_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(1, this->version(), target); + } + + // required bool invalidated = 2; + if (has_invalidated()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->invalidated(), target); + } + + // optional fixed64 modified_time = 3; + if (has_modified_time()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->modified_time(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int XLocSetVersionState::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed32 version = 1; + if (has_version()) { + total_size += 1 + 4; + } + + // required bool invalidated = 2; + if (has_invalidated()) { + total_size += 1 + 1; + } + + // optional fixed64 modified_time = 3; + if (has_modified_time()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void XLocSetVersionState::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const XLocSetVersionState* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void XLocSetVersionState::MergeFrom(const XLocSetVersionState& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_version()) { + set_version(from.version()); + } + if (from.has_invalidated()) { + set_invalidated(from.invalidated()); + } + if (from.has_modified_time()) { + set_modified_time(from.modified_time()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void XLocSetVersionState::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void XLocSetVersionState::CopyFrom(const XLocSetVersionState& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool XLocSetVersionState::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void XLocSetVersionState::Swap(XLocSetVersionState* other) { + if (other != this) { + std::swap(version_, other->version_); + std::swap(invalidated_, other->invalidated_); + std::swap(modified_time_, other->modified_time_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata XLocSetVersionState::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = XLocSetVersionState_descriptor_; + metadata.reflection = XLocSetVersionState_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ReplicaStatus::kTruncateEpochFieldNumber; +const int ReplicaStatus::kFileSizeFieldNumber; +const int ReplicaStatus::kMaxObjVersionFieldNumber; +const int ReplicaStatus::kPrimaryEpochFieldNumber; +const int ReplicaStatus::kObjectVersionsFieldNumber; +const int ReplicaStatus::kTruncateLogFieldNumber; +#endif // !_MSC_VER + +ReplicaStatus::ReplicaStatus() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ReplicaStatus::InitAsDefaultInstance() { + truncate_log_ = const_cast< ::xtreemfs::pbrpc::TruncateLog*>(&::xtreemfs::pbrpc::TruncateLog::default_instance()); +} + +ReplicaStatus::ReplicaStatus(const ReplicaStatus& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ReplicaStatus::SharedCtor() { + _cached_size_ = 0; + truncate_epoch_ = GOOGLE_ULONGLONG(0); + file_size_ = GOOGLE_ULONGLONG(0); + max_obj_version_ = GOOGLE_ULONGLONG(0); + primary_epoch_ = 0u; + truncate_log_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ReplicaStatus::~ReplicaStatus() { + SharedDtor(); +} + +void ReplicaStatus::SharedDtor() { + if (this != default_instance_) { + delete truncate_log_; + } +} + +void ReplicaStatus::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ReplicaStatus::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ReplicaStatus_descriptor_; +} + +const ReplicaStatus& ReplicaStatus::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +ReplicaStatus* ReplicaStatus::default_instance_ = NULL; + +ReplicaStatus* ReplicaStatus::New() const { + return new ReplicaStatus; +} + +void ReplicaStatus::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + truncate_epoch_ = GOOGLE_ULONGLONG(0); + file_size_ = GOOGLE_ULONGLONG(0); + max_obj_version_ = GOOGLE_ULONGLONG(0); + primary_epoch_ = 0u; + if (has_truncate_log()) { + if (truncate_log_ != NULL) truncate_log_->::xtreemfs::pbrpc::TruncateLog::Clear(); + } + } + objectversions_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ReplicaStatus::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 truncate_epoch = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &truncate_epoch_))); + set_has_truncate_epoch(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(17)) goto parse_file_size; + break; + } + + // required fixed64 file_size = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_file_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &file_size_))); + set_has_file_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_max_obj_version; + break; + } + + // required fixed64 max_obj_version = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_max_obj_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &max_obj_version_))); + set_has_max_obj_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(37)) goto parse_primary_epoch; + break; + } + + // required fixed32 primary_epoch = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_primary_epoch: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &primary_epoch_))); + set_has_primary_epoch(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_objectVersions; + break; + } + + // repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_objectVersions: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_objectversions())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_objectVersions; + if (input->ExpectTag(50)) goto parse_truncate_log; + break; + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_truncate_log: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_truncate_log())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ReplicaStatus::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 truncate_epoch = 1; + if (has_truncate_epoch()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->truncate_epoch(), output); + } + + // required fixed64 file_size = 2; + if (has_file_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(2, this->file_size(), output); + } + + // required fixed64 max_obj_version = 3; + if (has_max_obj_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->max_obj_version(), output); + } + + // required fixed32 primary_epoch = 4; + if (has_primary_epoch()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(4, this->primary_epoch(), output); + } + + // repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + for (int i = 0; i < this->objectversions_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 5, this->objectversions(i), output); + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + if (has_truncate_log()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 6, this->truncate_log(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ReplicaStatus::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 truncate_epoch = 1; + if (has_truncate_epoch()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->truncate_epoch(), target); + } + + // required fixed64 file_size = 2; + if (has_file_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(2, this->file_size(), target); + } + + // required fixed64 max_obj_version = 3; + if (has_max_obj_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->max_obj_version(), target); + } + + // required fixed32 primary_epoch = 4; + if (has_primary_epoch()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(4, this->primary_epoch(), target); + } + + // repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + for (int i = 0; i < this->objectversions_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 5, this->objectversions(i), target); + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + if (has_truncate_log()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, this->truncate_log(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ReplicaStatus::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 truncate_epoch = 1; + if (has_truncate_epoch()) { + total_size += 1 + 8; + } + + // required fixed64 file_size = 2; + if (has_file_size()) { + total_size += 1 + 8; + } + + // required fixed64 max_obj_version = 3; + if (has_max_obj_version()) { + total_size += 1 + 8; + } + + // required fixed32 primary_epoch = 4; + if (has_primary_epoch()) { + total_size += 1 + 4; + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + if (has_truncate_log()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->truncate_log()); + } + + } + // repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + total_size += 1 * this->objectversions_size(); + for (int i = 0; i < this->objectversions_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->objectversions(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ReplicaStatus::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ReplicaStatus* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ReplicaStatus::MergeFrom(const ReplicaStatus& from) { + GOOGLE_CHECK_NE(&from, this); + objectversions_.MergeFrom(from.objectversions_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_truncate_epoch()) { + set_truncate_epoch(from.truncate_epoch()); + } + if (from.has_file_size()) { + set_file_size(from.file_size()); + } + if (from.has_max_obj_version()) { + set_max_obj_version(from.max_obj_version()); + } + if (from.has_primary_epoch()) { + set_primary_epoch(from.primary_epoch()); + } + if (from.has_truncate_log()) { + mutable_truncate_log()->::xtreemfs::pbrpc::TruncateLog::MergeFrom(from.truncate_log()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ReplicaStatus::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ReplicaStatus::CopyFrom(const ReplicaStatus& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ReplicaStatus::IsInitialized() const { + if ((_has_bits_[0] & 0x0000002f) != 0x0000002f) return false; + + for (int i = 0; i < objectversions_size(); i++) { + if (!this->objectversions(i).IsInitialized()) return false; + } + if (has_truncate_log()) { + if (!this->truncate_log().IsInitialized()) return false; + } + return true; +} + +void ReplicaStatus::Swap(ReplicaStatus* other) { + if (other != this) { + std::swap(truncate_epoch_, other->truncate_epoch_); + std::swap(file_size_, other->file_size_); + std::swap(max_obj_version_, other->max_obj_version_); + std::swap(primary_epoch_, other->primary_epoch_); + objectversions_.Swap(&other->objectversions_); + std::swap(truncate_log_, other->truncate_log_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ReplicaStatus::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ReplicaStatus_descriptor_; + metadata.reflection = ReplicaStatus_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ObjectVersionMapping::kObjectNumberFieldNumber; +const int ObjectVersionMapping::kObjectVersionFieldNumber; +const int ObjectVersionMapping::kOsdUuidsFieldNumber; +#endif // !_MSC_VER + +ObjectVersionMapping::ObjectVersionMapping() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ObjectVersionMapping::InitAsDefaultInstance() { +} + +ObjectVersionMapping::ObjectVersionMapping(const ObjectVersionMapping& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ObjectVersionMapping::SharedCtor() { + _cached_size_ = 0; + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ObjectVersionMapping::~ObjectVersionMapping() { + SharedDtor(); +} + +void ObjectVersionMapping::SharedDtor() { + if (this != default_instance_) { + } +} + +void ObjectVersionMapping::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ObjectVersionMapping::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ObjectVersionMapping_descriptor_; +} + +const ObjectVersionMapping& ObjectVersionMapping::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +ObjectVersionMapping* ObjectVersionMapping::default_instance_ = NULL; + +ObjectVersionMapping* ObjectVersionMapping::New() const { + return new ObjectVersionMapping; +} + +void ObjectVersionMapping::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + } + osd_uuids_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ObjectVersionMapping::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 object_number = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_number_))); + set_has_object_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(17)) goto parse_object_version; + break; + } + + // required fixed64 object_version = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_version_))); + set_has_object_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_osd_uuids; + break; + } + + // repeated string osd_uuids = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_osd_uuids: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_osd_uuids())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuids(this->osd_uuids_size() - 1).data(), + this->osd_uuids(this->osd_uuids_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_osd_uuids; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ObjectVersionMapping::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 object_number = 1; + if (has_object_number()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->object_number(), output); + } + + // required fixed64 object_version = 2; + if (has_object_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(2, this->object_version(), output); + } + + // repeated string osd_uuids = 3; + for (int i = 0; i < this->osd_uuids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuids(i).data(), this->osd_uuids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->osd_uuids(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ObjectVersionMapping::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 object_number = 1; + if (has_object_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->object_number(), target); + } + + // required fixed64 object_version = 2; + if (has_object_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(2, this->object_version(), target); + } + + // repeated string osd_uuids = 3; + for (int i = 0; i < this->osd_uuids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->osd_uuids(i).data(), this->osd_uuids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(3, this->osd_uuids(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ObjectVersionMapping::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 object_number = 1; + if (has_object_number()) { + total_size += 1 + 8; + } + + // required fixed64 object_version = 2; + if (has_object_version()) { + total_size += 1 + 8; + } + + } + // repeated string osd_uuids = 3; + total_size += 1 * this->osd_uuids_size(); + for (int i = 0; i < this->osd_uuids_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->osd_uuids(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ObjectVersionMapping::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ObjectVersionMapping* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ObjectVersionMapping::MergeFrom(const ObjectVersionMapping& from) { + GOOGLE_CHECK_NE(&from, this); + osd_uuids_.MergeFrom(from.osd_uuids_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_object_number()) { + set_object_number(from.object_number()); + } + if (from.has_object_version()) { + set_object_version(from.object_version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ObjectVersionMapping::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ObjectVersionMapping::CopyFrom(const ObjectVersionMapping& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ObjectVersionMapping::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void ObjectVersionMapping::Swap(ObjectVersionMapping* other) { + if (other != this) { + std::swap(object_number_, other->object_number_); + std::swap(object_version_, other->object_version_); + osd_uuids_.Swap(&other->osd_uuids_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ObjectVersionMapping::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ObjectVersionMapping_descriptor_; + metadata.reflection = ObjectVersionMapping_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int AuthoritativeReplicaState::kTruncateEpochFieldNumber; +const int AuthoritativeReplicaState::kMaxObjVersionFieldNumber; +const int AuthoritativeReplicaState::kObjectVersionsFieldNumber; +const int AuthoritativeReplicaState::kTruncateLogFieldNumber; +#endif // !_MSC_VER + +AuthoritativeReplicaState::AuthoritativeReplicaState() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void AuthoritativeReplicaState::InitAsDefaultInstance() { + truncate_log_ = const_cast< ::xtreemfs::pbrpc::TruncateLog*>(&::xtreemfs::pbrpc::TruncateLog::default_instance()); +} + +AuthoritativeReplicaState::AuthoritativeReplicaState(const AuthoritativeReplicaState& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void AuthoritativeReplicaState::SharedCtor() { + _cached_size_ = 0; + truncate_epoch_ = GOOGLE_ULONGLONG(0); + max_obj_version_ = GOOGLE_ULONGLONG(0); + truncate_log_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +AuthoritativeReplicaState::~AuthoritativeReplicaState() { + SharedDtor(); +} + +void AuthoritativeReplicaState::SharedDtor() { + if (this != default_instance_) { + delete truncate_log_; + } +} + +void AuthoritativeReplicaState::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* AuthoritativeReplicaState::descriptor() { + protobuf_AssignDescriptorsOnce(); + return AuthoritativeReplicaState_descriptor_; +} + +const AuthoritativeReplicaState& AuthoritativeReplicaState::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +AuthoritativeReplicaState* AuthoritativeReplicaState::default_instance_ = NULL; + +AuthoritativeReplicaState* AuthoritativeReplicaState::New() const { + return new AuthoritativeReplicaState; +} + +void AuthoritativeReplicaState::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + truncate_epoch_ = GOOGLE_ULONGLONG(0); + max_obj_version_ = GOOGLE_ULONGLONG(0); + if (has_truncate_log()) { + if (truncate_log_ != NULL) truncate_log_->::xtreemfs::pbrpc::TruncateLog::Clear(); + } + } + objectversions_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool AuthoritativeReplicaState::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 truncate_epoch = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &truncate_epoch_))); + set_has_truncate_epoch(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_objectVersions; + break; + } + + // repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_objectVersions: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_objectversions())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_objectVersions; + if (input->ExpectTag(26)) goto parse_truncate_log; + break; + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_truncate_log: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_truncate_log())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(33)) goto parse_max_obj_version; + break; + } + + // required fixed64 max_obj_version = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_max_obj_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &max_obj_version_))); + set_has_max_obj_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void AuthoritativeReplicaState::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 truncate_epoch = 1; + if (has_truncate_epoch()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->truncate_epoch(), output); + } + + // repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + for (int i = 0; i < this->objectversions_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->objectversions(i), output); + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + if (has_truncate_log()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->truncate_log(), output); + } + + // required fixed64 max_obj_version = 4; + if (has_max_obj_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->max_obj_version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* AuthoritativeReplicaState::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 truncate_epoch = 1; + if (has_truncate_epoch()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->truncate_epoch(), target); + } + + // repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + for (int i = 0; i < this->objectversions_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->objectversions(i), target); + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + if (has_truncate_log()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->truncate_log(), target); + } + + // required fixed64 max_obj_version = 4; + if (has_max_obj_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->max_obj_version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int AuthoritativeReplicaState::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 truncate_epoch = 1; + if (has_truncate_epoch()) { + total_size += 1 + 8; + } + + // required fixed64 max_obj_version = 4; + if (has_max_obj_version()) { + total_size += 1 + 8; + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + if (has_truncate_log()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->truncate_log()); + } + + } + // repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + total_size += 1 * this->objectversions_size(); + for (int i = 0; i < this->objectversions_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->objectversions(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void AuthoritativeReplicaState::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const AuthoritativeReplicaState* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void AuthoritativeReplicaState::MergeFrom(const AuthoritativeReplicaState& from) { + GOOGLE_CHECK_NE(&from, this); + objectversions_.MergeFrom(from.objectversions_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_truncate_epoch()) { + set_truncate_epoch(from.truncate_epoch()); + } + if (from.has_max_obj_version()) { + set_max_obj_version(from.max_obj_version()); + } + if (from.has_truncate_log()) { + mutable_truncate_log()->::xtreemfs::pbrpc::TruncateLog::MergeFrom(from.truncate_log()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void AuthoritativeReplicaState::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void AuthoritativeReplicaState::CopyFrom(const AuthoritativeReplicaState& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool AuthoritativeReplicaState::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000b) != 0x0000000b) return false; + + for (int i = 0; i < objectversions_size(); i++) { + if (!this->objectversions(i).IsInitialized()) return false; + } + if (has_truncate_log()) { + if (!this->truncate_log().IsInitialized()) return false; + } + return true; +} + +void AuthoritativeReplicaState::Swap(AuthoritativeReplicaState* other) { + if (other != this) { + std::swap(truncate_epoch_, other->truncate_epoch_); + std::swap(max_obj_version_, other->max_obj_version_); + objectversions_.Swap(&other->objectversions_); + std::swap(truncate_log_, other->truncate_log_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata AuthoritativeReplicaState::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = AuthoritativeReplicaState_descriptor_; + metadata.reflection = AuthoritativeReplicaState_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int InternalReadLocalResponse::kDataFieldNumber; +const int InternalReadLocalResponse::kObjectSetFieldNumber; +#endif // !_MSC_VER + +InternalReadLocalResponse::InternalReadLocalResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void InternalReadLocalResponse::InitAsDefaultInstance() { + data_ = const_cast< ::xtreemfs::pbrpc::ObjectData*>(&::xtreemfs::pbrpc::ObjectData::default_instance()); +} + +InternalReadLocalResponse::InternalReadLocalResponse(const InternalReadLocalResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void InternalReadLocalResponse::SharedCtor() { + _cached_size_ = 0; + data_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +InternalReadLocalResponse::~InternalReadLocalResponse() { + SharedDtor(); +} + +void InternalReadLocalResponse::SharedDtor() { + if (this != default_instance_) { + delete data_; + } +} + +void InternalReadLocalResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* InternalReadLocalResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return InternalReadLocalResponse_descriptor_; +} + +const InternalReadLocalResponse& InternalReadLocalResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +InternalReadLocalResponse* InternalReadLocalResponse::default_instance_ = NULL; + +InternalReadLocalResponse* InternalReadLocalResponse::New() const { + return new InternalReadLocalResponse; +} + +void InternalReadLocalResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_data()) { + if (data_ != NULL) data_->::xtreemfs::pbrpc::ObjectData::Clear(); + } + } + object_set_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool InternalReadLocalResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.ObjectData data = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_data())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_object_set; + break; + } + + // repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_object_set: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_object_set())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_object_set; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void InternalReadLocalResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.ObjectData data = 1; + if (has_data()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->data(), output); + } + + // repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + for (int i = 0; i < this->object_set_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->object_set(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* InternalReadLocalResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.ObjectData data = 1; + if (has_data()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->data(), target); + } + + // repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + for (int i = 0; i < this->object_set_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->object_set(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int InternalReadLocalResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.ObjectData data = 1; + if (has_data()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->data()); + } + + } + // repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + total_size += 1 * this->object_set_size(); + for (int i = 0; i < this->object_set_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->object_set(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void InternalReadLocalResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const InternalReadLocalResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void InternalReadLocalResponse::MergeFrom(const InternalReadLocalResponse& from) { + GOOGLE_CHECK_NE(&from, this); + object_set_.MergeFrom(from.object_set_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_data()) { + mutable_data()->::xtreemfs::pbrpc::ObjectData::MergeFrom(from.data()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void InternalReadLocalResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void InternalReadLocalResponse::CopyFrom(const InternalReadLocalResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool InternalReadLocalResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_data()) { + if (!this->data().IsInitialized()) return false; + } + for (int i = 0; i < object_set_size(); i++) { + if (!this->object_set(i).IsInitialized()) return false; + } + return true; +} + +void InternalReadLocalResponse::Swap(InternalReadLocalResponse* other) { + if (other != this) { + std::swap(data_, other->data_); + object_set_.Swap(&other->object_set_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata InternalReadLocalResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = InternalReadLocalResponse_descriptor_; + metadata.reflection = InternalReadLocalResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int readRequest::kFileCredentialsFieldNumber; +const int readRequest::kFileIdFieldNumber; +const int readRequest::kObjectNumberFieldNumber; +const int readRequest::kObjectVersionFieldNumber; +const int readRequest::kOffsetFieldNumber; +const int readRequest::kLengthFieldNumber; +#endif // !_MSC_VER + +readRequest::readRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void readRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +readRequest::readRequest(const readRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void readRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + offset_ = 0u; + length_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +readRequest::~readRequest() { + SharedDtor(); +} + +void readRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void readRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* readRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return readRequest_descriptor_; +} + +const readRequest& readRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +readRequest* readRequest::default_instance_ = NULL; + +readRequest* readRequest::New() const { + return new readRequest; +} + +void readRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + offset_ = 0u; + length_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool readRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_object_number; + break; + } + + // required fixed64 object_number = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_number_))); + set_has_object_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(33)) goto parse_object_version; + break; + } + + // required fixed64 object_version = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_version_))); + set_has_object_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(45)) goto parse_offset; + break; + } + + // required fixed32 offset = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_offset: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &offset_))); + set_has_offset(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(53)) goto parse_length; + break; + } + + // required fixed32 length = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_length: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &length_))); + set_has_length(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void readRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->object_number(), output); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->object_version(), output); + } + + // required fixed32 offset = 5; + if (has_offset()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(5, this->offset(), output); + } + + // required fixed32 length = 6; + if (has_length()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(6, this->length(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* readRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->object_number(), target); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->object_version(), target); + } + + // required fixed32 offset = 5; + if (has_offset()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(5, this->offset(), target); + } + + // required fixed32 length = 6; + if (has_length()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(6, this->length(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int readRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + total_size += 1 + 8; + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + total_size += 1 + 8; + } + + // required fixed32 offset = 5; + if (has_offset()) { + total_size += 1 + 4; + } + + // required fixed32 length = 6; + if (has_length()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void readRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const readRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void readRequest::MergeFrom(const readRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_object_number()) { + set_object_number(from.object_number()); + } + if (from.has_object_version()) { + set_object_version(from.object_version()); + } + if (from.has_offset()) { + set_offset(from.offset()); + } + if (from.has_length()) { + set_length(from.length()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void readRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void readRequest::CopyFrom(const readRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool readRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000003f) != 0x0000003f) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void readRequest::Swap(readRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(object_number_, other->object_number_); + std::swap(object_version_, other->object_version_); + std::swap(offset_, other->offset_); + std::swap(length_, other->length_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata readRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = readRequest_descriptor_; + metadata.reflection = readRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int truncateRequest::kFileCredentialsFieldNumber; +const int truncateRequest::kFileIdFieldNumber; +const int truncateRequest::kNewFileSizeFieldNumber; +#endif // !_MSC_VER + +truncateRequest::truncateRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void truncateRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +truncateRequest::truncateRequest(const truncateRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void truncateRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + new_file_size_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +truncateRequest::~truncateRequest() { + SharedDtor(); +} + +void truncateRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void truncateRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* truncateRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return truncateRequest_descriptor_; +} + +const truncateRequest& truncateRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +truncateRequest* truncateRequest::default_instance_ = NULL; + +truncateRequest* truncateRequest::New() const { + return new truncateRequest; +} + +void truncateRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + new_file_size_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool truncateRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_new_file_size; + break; + } + + // required fixed64 new_file_size = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_new_file_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &new_file_size_))); + set_has_new_file_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void truncateRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed64 new_file_size = 3; + if (has_new_file_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->new_file_size(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* truncateRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed64 new_file_size = 3; + if (has_new_file_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->new_file_size(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int truncateRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 new_file_size = 3; + if (has_new_file_size()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void truncateRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const truncateRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void truncateRequest::MergeFrom(const truncateRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_new_file_size()) { + set_new_file_size(from.new_file_size()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void truncateRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void truncateRequest::CopyFrom(const truncateRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool truncateRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void truncateRequest::Swap(truncateRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(new_file_size_, other->new_file_size_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata truncateRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = truncateRequest_descriptor_; + metadata.reflection = truncateRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int unlink_osd_Request::kFileCredentialsFieldNumber; +const int unlink_osd_Request::kFileIdFieldNumber; +#endif // !_MSC_VER + +unlink_osd_Request::unlink_osd_Request() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void unlink_osd_Request::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +unlink_osd_Request::unlink_osd_Request(const unlink_osd_Request& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void unlink_osd_Request::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +unlink_osd_Request::~unlink_osd_Request() { + SharedDtor(); +} + +void unlink_osd_Request::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void unlink_osd_Request::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* unlink_osd_Request::descriptor() { + protobuf_AssignDescriptorsOnce(); + return unlink_osd_Request_descriptor_; +} + +const unlink_osd_Request& unlink_osd_Request::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +unlink_osd_Request* unlink_osd_Request::default_instance_ = NULL; + +unlink_osd_Request* unlink_osd_Request::New() const { + return new unlink_osd_Request; +} + +void unlink_osd_Request::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool unlink_osd_Request::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void unlink_osd_Request::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* unlink_osd_Request::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int unlink_osd_Request::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void unlink_osd_Request::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const unlink_osd_Request* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void unlink_osd_Request::MergeFrom(const unlink_osd_Request& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void unlink_osd_Request::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void unlink_osd_Request::CopyFrom(const unlink_osd_Request& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool unlink_osd_Request::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void unlink_osd_Request::Swap(unlink_osd_Request* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata unlink_osd_Request::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = unlink_osd_Request_descriptor_; + metadata.reflection = unlink_osd_Request_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int writeRequest::kFileCredentialsFieldNumber; +const int writeRequest::kFileIdFieldNumber; +const int writeRequest::kObjectNumberFieldNumber; +const int writeRequest::kObjectVersionFieldNumber; +const int writeRequest::kOffsetFieldNumber; +const int writeRequest::kLeaseTimeoutFieldNumber; +const int writeRequest::kObjectDataFieldNumber; +#endif // !_MSC_VER + +writeRequest::writeRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void writeRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); + object_data_ = const_cast< ::xtreemfs::pbrpc::ObjectData*>(&::xtreemfs::pbrpc::ObjectData::default_instance()); +} + +writeRequest::writeRequest(const writeRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void writeRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + offset_ = 0u; + lease_timeout_ = GOOGLE_ULONGLONG(0); + object_data_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +writeRequest::~writeRequest() { + SharedDtor(); +} + +void writeRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + delete object_data_; + } +} + +void writeRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* writeRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return writeRequest_descriptor_; +} + +const writeRequest& writeRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +writeRequest* writeRequest::default_instance_ = NULL; + +writeRequest* writeRequest::New() const { + return new writeRequest; +} + +void writeRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + offset_ = 0u; + lease_timeout_ = GOOGLE_ULONGLONG(0); + if (has_object_data()) { + if (object_data_ != NULL) object_data_->::xtreemfs::pbrpc::ObjectData::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool writeRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_object_number; + break; + } + + // required fixed64 object_number = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_number_))); + set_has_object_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(33)) goto parse_object_version; + break; + } + + // required fixed64 object_version = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_version_))); + set_has_object_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(45)) goto parse_offset; + break; + } + + // required fixed32 offset = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_offset: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &offset_))); + set_has_offset(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(49)) goto parse_lease_timeout; + break; + } + + // required fixed64 lease_timeout = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_lease_timeout: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &lease_timeout_))); + set_has_lease_timeout(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(58)) goto parse_object_data; + break; + } + + // required .xtreemfs.pbrpc.ObjectData object_data = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_object_data: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_object_data())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void writeRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->object_number(), output); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->object_version(), output); + } + + // required fixed32 offset = 5; + if (has_offset()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(5, this->offset(), output); + } + + // required fixed64 lease_timeout = 6; + if (has_lease_timeout()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(6, this->lease_timeout(), output); + } + + // required .xtreemfs.pbrpc.ObjectData object_data = 7; + if (has_object_data()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 7, this->object_data(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* writeRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->object_number(), target); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->object_version(), target); + } + + // required fixed32 offset = 5; + if (has_offset()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(5, this->offset(), target); + } + + // required fixed64 lease_timeout = 6; + if (has_lease_timeout()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(6, this->lease_timeout(), target); + } + + // required .xtreemfs.pbrpc.ObjectData object_data = 7; + if (has_object_data()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 7, this->object_data(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int writeRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + total_size += 1 + 8; + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + total_size += 1 + 8; + } + + // required fixed32 offset = 5; + if (has_offset()) { + total_size += 1 + 4; + } + + // required fixed64 lease_timeout = 6; + if (has_lease_timeout()) { + total_size += 1 + 8; + } + + // required .xtreemfs.pbrpc.ObjectData object_data = 7; + if (has_object_data()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->object_data()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void writeRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const writeRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void writeRequest::MergeFrom(const writeRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_object_number()) { + set_object_number(from.object_number()); + } + if (from.has_object_version()) { + set_object_version(from.object_version()); + } + if (from.has_offset()) { + set_offset(from.offset()); + } + if (from.has_lease_timeout()) { + set_lease_timeout(from.lease_timeout()); + } + if (from.has_object_data()) { + mutable_object_data()->::xtreemfs::pbrpc::ObjectData::MergeFrom(from.object_data()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void writeRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void writeRequest::CopyFrom(const writeRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool writeRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000007f) != 0x0000007f) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + if (has_object_data()) { + if (!this->object_data().IsInitialized()) return false; + } + return true; +} + +void writeRequest::Swap(writeRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(object_number_, other->object_number_); + std::swap(object_version_, other->object_version_); + std::swap(offset_, other->offset_); + std::swap(lease_timeout_, other->lease_timeout_); + std::swap(object_data_, other->object_data_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata writeRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = writeRequest_descriptor_; + metadata.reflection = writeRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_broadcast_gmaxRequest::kFileIdFieldNumber; +const int xtreemfs_broadcast_gmaxRequest::kTruncateEpochFieldNumber; +const int xtreemfs_broadcast_gmaxRequest::kLastObjectFieldNumber; +const int xtreemfs_broadcast_gmaxRequest::kFileSizeFieldNumber; +#endif // !_MSC_VER + +xtreemfs_broadcast_gmaxRequest::xtreemfs_broadcast_gmaxRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_broadcast_gmaxRequest::InitAsDefaultInstance() { +} + +xtreemfs_broadcast_gmaxRequest::xtreemfs_broadcast_gmaxRequest(const xtreemfs_broadcast_gmaxRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_broadcast_gmaxRequest::SharedCtor() { + _cached_size_ = 0; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + truncate_epoch_ = GOOGLE_ULONGLONG(0); + last_object_ = GOOGLE_ULONGLONG(0); + file_size_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_broadcast_gmaxRequest::~xtreemfs_broadcast_gmaxRequest() { + SharedDtor(); +} + +void xtreemfs_broadcast_gmaxRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_broadcast_gmaxRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_broadcast_gmaxRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_broadcast_gmaxRequest_descriptor_; +} + +const xtreemfs_broadcast_gmaxRequest& xtreemfs_broadcast_gmaxRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_broadcast_gmaxRequest* xtreemfs_broadcast_gmaxRequest::default_instance_ = NULL; + +xtreemfs_broadcast_gmaxRequest* xtreemfs_broadcast_gmaxRequest::New() const { + return new xtreemfs_broadcast_gmaxRequest; +} + +void xtreemfs_broadcast_gmaxRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + truncate_epoch_ = GOOGLE_ULONGLONG(0); + last_object_ = GOOGLE_ULONGLONG(0); + file_size_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_broadcast_gmaxRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string file_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(17)) goto parse_truncate_epoch; + break; + } + + // required fixed64 truncate_epoch = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_truncate_epoch: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &truncate_epoch_))); + set_has_truncate_epoch(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_last_object; + break; + } + + // required fixed64 last_object = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_last_object: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &last_object_))); + set_has_last_object(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(33)) goto parse_file_size; + break; + } + + // required fixed64 file_size = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_file_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &file_size_))); + set_has_file_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_broadcast_gmaxRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_id(), output); + } + + // required fixed64 truncate_epoch = 2; + if (has_truncate_epoch()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(2, this->truncate_epoch(), output); + } + + // required fixed64 last_object = 3; + if (has_last_object()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->last_object(), output); + } + + // required fixed64 file_size = 4; + if (has_file_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->file_size(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_broadcast_gmaxRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string file_id = 1; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->file_id(), target); + } + + // required fixed64 truncate_epoch = 2; + if (has_truncate_epoch()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(2, this->truncate_epoch(), target); + } + + // required fixed64 last_object = 3; + if (has_last_object()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->last_object(), target); + } + + // required fixed64 file_size = 4; + if (has_file_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->file_size(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_broadcast_gmaxRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string file_id = 1; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 truncate_epoch = 2; + if (has_truncate_epoch()) { + total_size += 1 + 8; + } + + // required fixed64 last_object = 3; + if (has_last_object()) { + total_size += 1 + 8; + } + + // required fixed64 file_size = 4; + if (has_file_size()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_broadcast_gmaxRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_broadcast_gmaxRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_broadcast_gmaxRequest::MergeFrom(const xtreemfs_broadcast_gmaxRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_truncate_epoch()) { + set_truncate_epoch(from.truncate_epoch()); + } + if (from.has_last_object()) { + set_last_object(from.last_object()); + } + if (from.has_file_size()) { + set_file_size(from.file_size()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_broadcast_gmaxRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_broadcast_gmaxRequest::CopyFrom(const xtreemfs_broadcast_gmaxRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_broadcast_gmaxRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void xtreemfs_broadcast_gmaxRequest::Swap(xtreemfs_broadcast_gmaxRequest* other) { + if (other != this) { + std::swap(file_id_, other->file_id_); + std::swap(truncate_epoch_, other->truncate_epoch_); + std::swap(last_object_, other->last_object_); + std::swap(file_size_, other->file_size_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_broadcast_gmaxRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_broadcast_gmaxRequest_descriptor_; + metadata.reflection = xtreemfs_broadcast_gmaxRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_check_objectRequest::kFileCredentialsFieldNumber; +const int xtreemfs_check_objectRequest::kFileIdFieldNumber; +const int xtreemfs_check_objectRequest::kObjectNumberFieldNumber; +const int xtreemfs_check_objectRequest::kObjectVersionFieldNumber; +#endif // !_MSC_VER + +xtreemfs_check_objectRequest::xtreemfs_check_objectRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_check_objectRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_check_objectRequest::xtreemfs_check_objectRequest(const xtreemfs_check_objectRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_check_objectRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_check_objectRequest::~xtreemfs_check_objectRequest() { + SharedDtor(); +} + +void xtreemfs_check_objectRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_check_objectRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_check_objectRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_check_objectRequest_descriptor_; +} + +const xtreemfs_check_objectRequest& xtreemfs_check_objectRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_check_objectRequest* xtreemfs_check_objectRequest::default_instance_ = NULL; + +xtreemfs_check_objectRequest* xtreemfs_check_objectRequest::New() const { + return new xtreemfs_check_objectRequest; +} + +void xtreemfs_check_objectRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_check_objectRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_object_number; + break; + } + + // required fixed64 object_number = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_number_))); + set_has_object_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(33)) goto parse_object_version; + break; + } + + // required fixed64 object_version = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_version_))); + set_has_object_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_check_objectRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->object_number(), output); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->object_version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_check_objectRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->object_number(), target); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->object_version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_check_objectRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + total_size += 1 + 8; + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_check_objectRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_check_objectRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_check_objectRequest::MergeFrom(const xtreemfs_check_objectRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_object_number()) { + set_object_number(from.object_number()); + } + if (from.has_object_version()) { + set_object_version(from.object_version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_check_objectRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_check_objectRequest::CopyFrom(const xtreemfs_check_objectRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_check_objectRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_check_objectRequest::Swap(xtreemfs_check_objectRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(object_number_, other->object_number_); + std::swap(object_version_, other->object_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_check_objectRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_check_objectRequest_descriptor_; + metadata.reflection = xtreemfs_check_objectRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_cleanup_get_resultsResponse::kResultsFieldNumber; +#endif // !_MSC_VER + +xtreemfs_cleanup_get_resultsResponse::xtreemfs_cleanup_get_resultsResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_cleanup_get_resultsResponse::InitAsDefaultInstance() { +} + +xtreemfs_cleanup_get_resultsResponse::xtreemfs_cleanup_get_resultsResponse(const xtreemfs_cleanup_get_resultsResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_cleanup_get_resultsResponse::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_cleanup_get_resultsResponse::~xtreemfs_cleanup_get_resultsResponse() { + SharedDtor(); +} + +void xtreemfs_cleanup_get_resultsResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void xtreemfs_cleanup_get_resultsResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_cleanup_get_resultsResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_cleanup_get_resultsResponse_descriptor_; +} + +const xtreemfs_cleanup_get_resultsResponse& xtreemfs_cleanup_get_resultsResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_cleanup_get_resultsResponse* xtreemfs_cleanup_get_resultsResponse::default_instance_ = NULL; + +xtreemfs_cleanup_get_resultsResponse* xtreemfs_cleanup_get_resultsResponse::New() const { + return new xtreemfs_cleanup_get_resultsResponse; +} + +void xtreemfs_cleanup_get_resultsResponse::Clear() { + results_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_cleanup_get_resultsResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string results = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_results: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_results())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->results(this->results_size() - 1).data(), + this->results(this->results_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_results; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_cleanup_get_resultsResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated string results = 1; + for (int i = 0; i < this->results_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->results(i).data(), this->results(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->results(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_cleanup_get_resultsResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated string results = 1; + for (int i = 0; i < this->results_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->results(i).data(), this->results(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->results(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_cleanup_get_resultsResponse::ByteSize() const { + int total_size = 0; + + // repeated string results = 1; + total_size += 1 * this->results_size(); + for (int i = 0; i < this->results_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->results(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_cleanup_get_resultsResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_cleanup_get_resultsResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_cleanup_get_resultsResponse::MergeFrom(const xtreemfs_cleanup_get_resultsResponse& from) { + GOOGLE_CHECK_NE(&from, this); + results_.MergeFrom(from.results_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_cleanup_get_resultsResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_cleanup_get_resultsResponse::CopyFrom(const xtreemfs_cleanup_get_resultsResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_cleanup_get_resultsResponse::IsInitialized() const { + + return true; +} + +void xtreemfs_cleanup_get_resultsResponse::Swap(xtreemfs_cleanup_get_resultsResponse* other) { + if (other != this) { + results_.Swap(&other->results_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_cleanup_get_resultsResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_cleanup_get_resultsResponse_descriptor_; + metadata.reflection = xtreemfs_cleanup_get_resultsResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_cleanup_is_runningResponse::kIsRunningFieldNumber; +#endif // !_MSC_VER + +xtreemfs_cleanup_is_runningResponse::xtreemfs_cleanup_is_runningResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_cleanup_is_runningResponse::InitAsDefaultInstance() { +} + +xtreemfs_cleanup_is_runningResponse::xtreemfs_cleanup_is_runningResponse(const xtreemfs_cleanup_is_runningResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_cleanup_is_runningResponse::SharedCtor() { + _cached_size_ = 0; + is_running_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_cleanup_is_runningResponse::~xtreemfs_cleanup_is_runningResponse() { + SharedDtor(); +} + +void xtreemfs_cleanup_is_runningResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void xtreemfs_cleanup_is_runningResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_cleanup_is_runningResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_cleanup_is_runningResponse_descriptor_; +} + +const xtreemfs_cleanup_is_runningResponse& xtreemfs_cleanup_is_runningResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_cleanup_is_runningResponse* xtreemfs_cleanup_is_runningResponse::default_instance_ = NULL; + +xtreemfs_cleanup_is_runningResponse* xtreemfs_cleanup_is_runningResponse::New() const { + return new xtreemfs_cleanup_is_runningResponse; +} + +void xtreemfs_cleanup_is_runningResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + is_running_ = false; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_cleanup_is_runningResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required bool is_running = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &is_running_))); + set_has_is_running(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_cleanup_is_runningResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required bool is_running = 1; + if (has_is_running()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->is_running(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_cleanup_is_runningResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required bool is_running = 1; + if (has_is_running()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->is_running(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_cleanup_is_runningResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required bool is_running = 1; + if (has_is_running()) { + total_size += 1 + 1; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_cleanup_is_runningResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_cleanup_is_runningResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_cleanup_is_runningResponse::MergeFrom(const xtreemfs_cleanup_is_runningResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_is_running()) { + set_is_running(from.is_running()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_cleanup_is_runningResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_cleanup_is_runningResponse::CopyFrom(const xtreemfs_cleanup_is_runningResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_cleanup_is_runningResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void xtreemfs_cleanup_is_runningResponse::Swap(xtreemfs_cleanup_is_runningResponse* other) { + if (other != this) { + std::swap(is_running_, other->is_running_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_cleanup_is_runningResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_cleanup_is_runningResponse_descriptor_; + metadata.reflection = xtreemfs_cleanup_is_runningResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_cleanup_startRequest::kRemoveZombiesFieldNumber; +const int xtreemfs_cleanup_startRequest::kRemoveUnavailVolumeFieldNumber; +const int xtreemfs_cleanup_startRequest::kLostAndFoundFieldNumber; +const int xtreemfs_cleanup_startRequest::kDeleteMetadataFieldNumber; +const int xtreemfs_cleanup_startRequest::kMetadataTimeoutFieldNumber; +#endif // !_MSC_VER + +xtreemfs_cleanup_startRequest::xtreemfs_cleanup_startRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_cleanup_startRequest::InitAsDefaultInstance() { +} + +xtreemfs_cleanup_startRequest::xtreemfs_cleanup_startRequest(const xtreemfs_cleanup_startRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_cleanup_startRequest::SharedCtor() { + _cached_size_ = 0; + remove_zombies_ = false; + remove_unavail_volume_ = false; + lost_and_found_ = false; + delete_metadata_ = false; + metadata_timeout_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_cleanup_startRequest::~xtreemfs_cleanup_startRequest() { + SharedDtor(); +} + +void xtreemfs_cleanup_startRequest::SharedDtor() { + if (this != default_instance_) { + } +} + +void xtreemfs_cleanup_startRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_cleanup_startRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_cleanup_startRequest_descriptor_; +} + +const xtreemfs_cleanup_startRequest& xtreemfs_cleanup_startRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_cleanup_startRequest* xtreemfs_cleanup_startRequest::default_instance_ = NULL; + +xtreemfs_cleanup_startRequest* xtreemfs_cleanup_startRequest::New() const { + return new xtreemfs_cleanup_startRequest; +} + +void xtreemfs_cleanup_startRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + remove_zombies_ = false; + remove_unavail_volume_ = false; + lost_and_found_ = false; + delete_metadata_ = false; + metadata_timeout_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_cleanup_startRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required bool remove_zombies = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &remove_zombies_))); + set_has_remove_zombies(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_remove_unavail_volume; + break; + } + + // required bool remove_unavail_volume = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_remove_unavail_volume: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &remove_unavail_volume_))); + set_has_remove_unavail_volume(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(24)) goto parse_lost_and_found; + break; + } + + // required bool lost_and_found = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_lost_and_found: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &lost_and_found_))); + set_has_lost_and_found(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(32)) goto parse_delete_metadata; + break; + } + + // required bool delete_metadata = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_delete_metadata: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &delete_metadata_))); + set_has_delete_metadata(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(45)) goto parse_metadata_timeout; + break; + } + + // required fixed32 metadata_timeout = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_metadata_timeout: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &metadata_timeout_))); + set_has_metadata_timeout(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_cleanup_startRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required bool remove_zombies = 1; + if (has_remove_zombies()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->remove_zombies(), output); + } + + // required bool remove_unavail_volume = 2; + if (has_remove_unavail_volume()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->remove_unavail_volume(), output); + } + + // required bool lost_and_found = 3; + if (has_lost_and_found()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->lost_and_found(), output); + } + + // required bool delete_metadata = 4; + if (has_delete_metadata()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(4, this->delete_metadata(), output); + } + + // required fixed32 metadata_timeout = 5; + if (has_metadata_timeout()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(5, this->metadata_timeout(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_cleanup_startRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required bool remove_zombies = 1; + if (has_remove_zombies()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->remove_zombies(), target); + } + + // required bool remove_unavail_volume = 2; + if (has_remove_unavail_volume()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->remove_unavail_volume(), target); + } + + // required bool lost_and_found = 3; + if (has_lost_and_found()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->lost_and_found(), target); + } + + // required bool delete_metadata = 4; + if (has_delete_metadata()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(4, this->delete_metadata(), target); + } + + // required fixed32 metadata_timeout = 5; + if (has_metadata_timeout()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(5, this->metadata_timeout(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_cleanup_startRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required bool remove_zombies = 1; + if (has_remove_zombies()) { + total_size += 1 + 1; + } + + // required bool remove_unavail_volume = 2; + if (has_remove_unavail_volume()) { + total_size += 1 + 1; + } + + // required bool lost_and_found = 3; + if (has_lost_and_found()) { + total_size += 1 + 1; + } + + // required bool delete_metadata = 4; + if (has_delete_metadata()) { + total_size += 1 + 1; + } + + // required fixed32 metadata_timeout = 5; + if (has_metadata_timeout()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_cleanup_startRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_cleanup_startRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_cleanup_startRequest::MergeFrom(const xtreemfs_cleanup_startRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_remove_zombies()) { + set_remove_zombies(from.remove_zombies()); + } + if (from.has_remove_unavail_volume()) { + set_remove_unavail_volume(from.remove_unavail_volume()); + } + if (from.has_lost_and_found()) { + set_lost_and_found(from.lost_and_found()); + } + if (from.has_delete_metadata()) { + set_delete_metadata(from.delete_metadata()); + } + if (from.has_metadata_timeout()) { + set_metadata_timeout(from.metadata_timeout()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_cleanup_startRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_cleanup_startRequest::CopyFrom(const xtreemfs_cleanup_startRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_cleanup_startRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false; + + return true; +} + +void xtreemfs_cleanup_startRequest::Swap(xtreemfs_cleanup_startRequest* other) { + if (other != this) { + std::swap(remove_zombies_, other->remove_zombies_); + std::swap(remove_unavail_volume_, other->remove_unavail_volume_); + std::swap(lost_and_found_, other->lost_and_found_); + std::swap(delete_metadata_, other->delete_metadata_); + std::swap(metadata_timeout_, other->metadata_timeout_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_cleanup_startRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_cleanup_startRequest_descriptor_; + metadata.reflection = xtreemfs_cleanup_startRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_cleanup_statusResponse::kStatusFieldNumber; +#endif // !_MSC_VER + +xtreemfs_cleanup_statusResponse::xtreemfs_cleanup_statusResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_cleanup_statusResponse::InitAsDefaultInstance() { +} + +xtreemfs_cleanup_statusResponse::xtreemfs_cleanup_statusResponse(const xtreemfs_cleanup_statusResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_cleanup_statusResponse::SharedCtor() { + _cached_size_ = 0; + status_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_cleanup_statusResponse::~xtreemfs_cleanup_statusResponse() { + SharedDtor(); +} + +void xtreemfs_cleanup_statusResponse::SharedDtor() { + if (status_ != &::google::protobuf::internal::kEmptyString) { + delete status_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_cleanup_statusResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_cleanup_statusResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_cleanup_statusResponse_descriptor_; +} + +const xtreemfs_cleanup_statusResponse& xtreemfs_cleanup_statusResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_cleanup_statusResponse* xtreemfs_cleanup_statusResponse::default_instance_ = NULL; + +xtreemfs_cleanup_statusResponse* xtreemfs_cleanup_statusResponse::New() const { + return new xtreemfs_cleanup_statusResponse; +} + +void xtreemfs_cleanup_statusResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != &::google::protobuf::internal::kEmptyString) { + status_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_cleanup_statusResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_status())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->status().data(), this->status().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_cleanup_statusResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->status().data(), this->status().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->status(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_cleanup_statusResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->status().data(), this->status().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->status(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_cleanup_statusResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->status()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_cleanup_statusResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_cleanup_statusResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_cleanup_statusResponse::MergeFrom(const xtreemfs_cleanup_statusResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + set_status(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_cleanup_statusResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_cleanup_statusResponse::CopyFrom(const xtreemfs_cleanup_statusResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_cleanup_statusResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void xtreemfs_cleanup_statusResponse::Swap(xtreemfs_cleanup_statusResponse* other) { + if (other != this) { + std::swap(status_, other->status_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_cleanup_statusResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_cleanup_statusResponse_descriptor_; + metadata.reflection = xtreemfs_cleanup_statusResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_rwr_fetchRequest::kFileCredentialsFieldNumber; +const int xtreemfs_rwr_fetchRequest::kFileIdFieldNumber; +const int xtreemfs_rwr_fetchRequest::kObjectNumberFieldNumber; +const int xtreemfs_rwr_fetchRequest::kObjectVersionFieldNumber; +#endif // !_MSC_VER + +xtreemfs_rwr_fetchRequest::xtreemfs_rwr_fetchRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_rwr_fetchRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_rwr_fetchRequest::xtreemfs_rwr_fetchRequest(const xtreemfs_rwr_fetchRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_rwr_fetchRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_rwr_fetchRequest::~xtreemfs_rwr_fetchRequest() { + SharedDtor(); +} + +void xtreemfs_rwr_fetchRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_rwr_fetchRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_rwr_fetchRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_rwr_fetchRequest_descriptor_; +} + +const xtreemfs_rwr_fetchRequest& xtreemfs_rwr_fetchRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_rwr_fetchRequest* xtreemfs_rwr_fetchRequest::default_instance_ = NULL; + +xtreemfs_rwr_fetchRequest* xtreemfs_rwr_fetchRequest::New() const { + return new xtreemfs_rwr_fetchRequest; +} + +void xtreemfs_rwr_fetchRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_rwr_fetchRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_object_number; + break; + } + + // required fixed64 object_number = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_number_))); + set_has_object_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(33)) goto parse_object_version; + break; + } + + // required fixed64 object_version = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_version_))); + set_has_object_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_rwr_fetchRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->object_number(), output); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->object_version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_rwr_fetchRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->object_number(), target); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->object_version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_rwr_fetchRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + total_size += 1 + 8; + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_rwr_fetchRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_rwr_fetchRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_rwr_fetchRequest::MergeFrom(const xtreemfs_rwr_fetchRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_object_number()) { + set_object_number(from.object_number()); + } + if (from.has_object_version()) { + set_object_version(from.object_version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_rwr_fetchRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_rwr_fetchRequest::CopyFrom(const xtreemfs_rwr_fetchRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_rwr_fetchRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_rwr_fetchRequest::Swap(xtreemfs_rwr_fetchRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(object_number_, other->object_number_); + std::swap(object_version_, other->object_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_rwr_fetchRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_rwr_fetchRequest_descriptor_; + metadata.reflection = xtreemfs_rwr_fetchRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_repair_objectRequest::kFileCredentialsFieldNumber; +const int xtreemfs_repair_objectRequest::kFileIdFieldNumber; +const int xtreemfs_repair_objectRequest::kObjectNumberFieldNumber; +const int xtreemfs_repair_objectRequest::kObjectVersionFieldNumber; +#endif // !_MSC_VER + +xtreemfs_repair_objectRequest::xtreemfs_repair_objectRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_repair_objectRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_repair_objectRequest::xtreemfs_repair_objectRequest(const xtreemfs_repair_objectRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_repair_objectRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_repair_objectRequest::~xtreemfs_repair_objectRequest() { + SharedDtor(); +} + +void xtreemfs_repair_objectRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_repair_objectRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_repair_objectRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_repair_objectRequest_descriptor_; +} + +const xtreemfs_repair_objectRequest& xtreemfs_repair_objectRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_repair_objectRequest* xtreemfs_repair_objectRequest::default_instance_ = NULL; + +xtreemfs_repair_objectRequest* xtreemfs_repair_objectRequest::New() const { + return new xtreemfs_repair_objectRequest; +} + +void xtreemfs_repair_objectRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_repair_objectRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_object_number; + break; + } + + // required fixed64 object_number = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_number_))); + set_has_object_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(33)) goto parse_object_version; + break; + } + + // required fixed64 object_version = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_version_))); + set_has_object_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_repair_objectRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->object_number(), output); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->object_version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_repair_objectRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->object_number(), target); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->object_version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_repair_objectRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + total_size += 1 + 8; + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_repair_objectRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_repair_objectRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_repair_objectRequest::MergeFrom(const xtreemfs_repair_objectRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_object_number()) { + set_object_number(from.object_number()); + } + if (from.has_object_version()) { + set_object_version(from.object_version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_repair_objectRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_repair_objectRequest::CopyFrom(const xtreemfs_repair_objectRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_repair_objectRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_repair_objectRequest::Swap(xtreemfs_repair_objectRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(object_number_, other->object_number_); + std::swap(object_version_, other->object_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_repair_objectRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_repair_objectRequest_descriptor_; + metadata.reflection = xtreemfs_repair_objectRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_rwr_flease_msgRequest::kSenderHostnameFieldNumber; +const int xtreemfs_rwr_flease_msgRequest::kSenderPortFieldNumber; +#endif // !_MSC_VER + +xtreemfs_rwr_flease_msgRequest::xtreemfs_rwr_flease_msgRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_rwr_flease_msgRequest::InitAsDefaultInstance() { +} + +xtreemfs_rwr_flease_msgRequest::xtreemfs_rwr_flease_msgRequest(const xtreemfs_rwr_flease_msgRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_rwr_flease_msgRequest::SharedCtor() { + _cached_size_ = 0; + sender_hostname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + sender_port_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_rwr_flease_msgRequest::~xtreemfs_rwr_flease_msgRequest() { + SharedDtor(); +} + +void xtreemfs_rwr_flease_msgRequest::SharedDtor() { + if (sender_hostname_ != &::google::protobuf::internal::kEmptyString) { + delete sender_hostname_; + } + if (this != default_instance_) { + } +} + +void xtreemfs_rwr_flease_msgRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_rwr_flease_msgRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_rwr_flease_msgRequest_descriptor_; +} + +const xtreemfs_rwr_flease_msgRequest& xtreemfs_rwr_flease_msgRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_rwr_flease_msgRequest* xtreemfs_rwr_flease_msgRequest::default_instance_ = NULL; + +xtreemfs_rwr_flease_msgRequest* xtreemfs_rwr_flease_msgRequest::New() const { + return new xtreemfs_rwr_flease_msgRequest; +} + +void xtreemfs_rwr_flease_msgRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_sender_hostname()) { + if (sender_hostname_ != &::google::protobuf::internal::kEmptyString) { + sender_hostname_->clear(); + } + } + sender_port_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_rwr_flease_msgRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string sender_hostname = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_sender_hostname())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->sender_hostname().data(), this->sender_hostname().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(21)) goto parse_sender_port; + break; + } + + // required fixed32 sender_port = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_sender_port: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &sender_port_))); + set_has_sender_port(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_rwr_flease_msgRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string sender_hostname = 1; + if (has_sender_hostname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->sender_hostname().data(), this->sender_hostname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->sender_hostname(), output); + } + + // required fixed32 sender_port = 2; + if (has_sender_port()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(2, this->sender_port(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_rwr_flease_msgRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string sender_hostname = 1; + if (has_sender_hostname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->sender_hostname().data(), this->sender_hostname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->sender_hostname(), target); + } + + // required fixed32 sender_port = 2; + if (has_sender_port()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(2, this->sender_port(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_rwr_flease_msgRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string sender_hostname = 1; + if (has_sender_hostname()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->sender_hostname()); + } + + // required fixed32 sender_port = 2; + if (has_sender_port()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_rwr_flease_msgRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_rwr_flease_msgRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_rwr_flease_msgRequest::MergeFrom(const xtreemfs_rwr_flease_msgRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_sender_hostname()) { + set_sender_hostname(from.sender_hostname()); + } + if (from.has_sender_port()) { + set_sender_port(from.sender_port()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_rwr_flease_msgRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_rwr_flease_msgRequest::CopyFrom(const xtreemfs_rwr_flease_msgRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_rwr_flease_msgRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void xtreemfs_rwr_flease_msgRequest::Swap(xtreemfs_rwr_flease_msgRequest* other) { + if (other != this) { + std::swap(sender_hostname_, other->sender_hostname_); + std::swap(sender_port_, other->sender_port_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_rwr_flease_msgRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_rwr_flease_msgRequest_descriptor_; + metadata.reflection = xtreemfs_rwr_flease_msgRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_rwr_set_primary_epochRequest::kFileCredentialsFieldNumber; +const int xtreemfs_rwr_set_primary_epochRequest::kFileIdFieldNumber; +const int xtreemfs_rwr_set_primary_epochRequest::kPrimaryEpochFieldNumber; +#endif // !_MSC_VER + +xtreemfs_rwr_set_primary_epochRequest::xtreemfs_rwr_set_primary_epochRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_rwr_set_primary_epochRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_rwr_set_primary_epochRequest::xtreemfs_rwr_set_primary_epochRequest(const xtreemfs_rwr_set_primary_epochRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_rwr_set_primary_epochRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + primary_epoch_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_rwr_set_primary_epochRequest::~xtreemfs_rwr_set_primary_epochRequest() { + SharedDtor(); +} + +void xtreemfs_rwr_set_primary_epochRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_rwr_set_primary_epochRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_rwr_set_primary_epochRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_rwr_set_primary_epochRequest_descriptor_; +} + +const xtreemfs_rwr_set_primary_epochRequest& xtreemfs_rwr_set_primary_epochRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_rwr_set_primary_epochRequest* xtreemfs_rwr_set_primary_epochRequest::default_instance_ = NULL; + +xtreemfs_rwr_set_primary_epochRequest* xtreemfs_rwr_set_primary_epochRequest::New() const { + return new xtreemfs_rwr_set_primary_epochRequest; +} + +void xtreemfs_rwr_set_primary_epochRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + primary_epoch_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_rwr_set_primary_epochRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(29)) goto parse_primary_epoch; + break; + } + + // required fixed32 primary_epoch = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_primary_epoch: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &primary_epoch_))); + set_has_primary_epoch(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_rwr_set_primary_epochRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed32 primary_epoch = 3; + if (has_primary_epoch()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(3, this->primary_epoch(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_rwr_set_primary_epochRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed32 primary_epoch = 3; + if (has_primary_epoch()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(3, this->primary_epoch(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_rwr_set_primary_epochRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed32 primary_epoch = 3; + if (has_primary_epoch()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_rwr_set_primary_epochRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_rwr_set_primary_epochRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_rwr_set_primary_epochRequest::MergeFrom(const xtreemfs_rwr_set_primary_epochRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_primary_epoch()) { + set_primary_epoch(from.primary_epoch()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_rwr_set_primary_epochRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_rwr_set_primary_epochRequest::CopyFrom(const xtreemfs_rwr_set_primary_epochRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_rwr_set_primary_epochRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_rwr_set_primary_epochRequest::Swap(xtreemfs_rwr_set_primary_epochRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(primary_epoch_, other->primary_epoch_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_rwr_set_primary_epochRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_rwr_set_primary_epochRequest_descriptor_; + metadata.reflection = xtreemfs_rwr_set_primary_epochRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_rwr_statusRequest::kFileCredentialsFieldNumber; +const int xtreemfs_rwr_statusRequest::kFileIdFieldNumber; +const int xtreemfs_rwr_statusRequest::kMaxLocalObjVersionFieldNumber; +#endif // !_MSC_VER + +xtreemfs_rwr_statusRequest::xtreemfs_rwr_statusRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_rwr_statusRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_rwr_statusRequest::xtreemfs_rwr_statusRequest(const xtreemfs_rwr_statusRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_rwr_statusRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + max_local_obj_version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_rwr_statusRequest::~xtreemfs_rwr_statusRequest() { + SharedDtor(); +} + +void xtreemfs_rwr_statusRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_rwr_statusRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_rwr_statusRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_rwr_statusRequest_descriptor_; +} + +const xtreemfs_rwr_statusRequest& xtreemfs_rwr_statusRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_rwr_statusRequest* xtreemfs_rwr_statusRequest::default_instance_ = NULL; + +xtreemfs_rwr_statusRequest* xtreemfs_rwr_statusRequest::New() const { + return new xtreemfs_rwr_statusRequest; +} + +void xtreemfs_rwr_statusRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + max_local_obj_version_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_rwr_statusRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_max_local_obj_version; + break; + } + + // required fixed64 max_local_obj_version = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_max_local_obj_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &max_local_obj_version_))); + set_has_max_local_obj_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_rwr_statusRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed64 max_local_obj_version = 3; + if (has_max_local_obj_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->max_local_obj_version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_rwr_statusRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed64 max_local_obj_version = 3; + if (has_max_local_obj_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->max_local_obj_version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_rwr_statusRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 max_local_obj_version = 3; + if (has_max_local_obj_version()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_rwr_statusRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_rwr_statusRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_rwr_statusRequest::MergeFrom(const xtreemfs_rwr_statusRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_max_local_obj_version()) { + set_max_local_obj_version(from.max_local_obj_version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_rwr_statusRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_rwr_statusRequest::CopyFrom(const xtreemfs_rwr_statusRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_rwr_statusRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_rwr_statusRequest::Swap(xtreemfs_rwr_statusRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(max_local_obj_version_, other->max_local_obj_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_rwr_statusRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_rwr_statusRequest_descriptor_; + metadata.reflection = xtreemfs_rwr_statusRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_rwr_truncateRequest::kFileCredentialsFieldNumber; +const int xtreemfs_rwr_truncateRequest::kFileIdFieldNumber; +const int xtreemfs_rwr_truncateRequest::kNewFileSizeFieldNumber; +const int xtreemfs_rwr_truncateRequest::kObjectVersionFieldNumber; +#endif // !_MSC_VER + +xtreemfs_rwr_truncateRequest::xtreemfs_rwr_truncateRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_rwr_truncateRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_rwr_truncateRequest::xtreemfs_rwr_truncateRequest(const xtreemfs_rwr_truncateRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_rwr_truncateRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + new_file_size_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_rwr_truncateRequest::~xtreemfs_rwr_truncateRequest() { + SharedDtor(); +} + +void xtreemfs_rwr_truncateRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_rwr_truncateRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_rwr_truncateRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_rwr_truncateRequest_descriptor_; +} + +const xtreemfs_rwr_truncateRequest& xtreemfs_rwr_truncateRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_rwr_truncateRequest* xtreemfs_rwr_truncateRequest::default_instance_ = NULL; + +xtreemfs_rwr_truncateRequest* xtreemfs_rwr_truncateRequest::New() const { + return new xtreemfs_rwr_truncateRequest; +} + +void xtreemfs_rwr_truncateRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + new_file_size_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_rwr_truncateRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_new_file_size; + break; + } + + // required fixed64 new_file_size = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_new_file_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &new_file_size_))); + set_has_new_file_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(33)) goto parse_object_version; + break; + } + + // required fixed64 object_version = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_version_))); + set_has_object_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_rwr_truncateRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed64 new_file_size = 3; + if (has_new_file_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->new_file_size(), output); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->object_version(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_rwr_truncateRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed64 new_file_size = 3; + if (has_new_file_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->new_file_size(), target); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->object_version(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_rwr_truncateRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 new_file_size = 3; + if (has_new_file_size()) { + total_size += 1 + 8; + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_rwr_truncateRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_rwr_truncateRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_rwr_truncateRequest::MergeFrom(const xtreemfs_rwr_truncateRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_new_file_size()) { + set_new_file_size(from.new_file_size()); + } + if (from.has_object_version()) { + set_object_version(from.object_version()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_rwr_truncateRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_rwr_truncateRequest::CopyFrom(const xtreemfs_rwr_truncateRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_rwr_truncateRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_rwr_truncateRequest::Swap(xtreemfs_rwr_truncateRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(new_file_size_, other->new_file_size_); + std::swap(object_version_, other->object_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_rwr_truncateRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_rwr_truncateRequest_descriptor_; + metadata.reflection = xtreemfs_rwr_truncateRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_rwr_updateRequest::kFileCredentialsFieldNumber; +const int xtreemfs_rwr_updateRequest::kFileIdFieldNumber; +const int xtreemfs_rwr_updateRequest::kNewFileSizeFieldNumber; +const int xtreemfs_rwr_updateRequest::kObjectNumberFieldNumber; +const int xtreemfs_rwr_updateRequest::kObjectVersionFieldNumber; +const int xtreemfs_rwr_updateRequest::kOffsetFieldNumber; +const int xtreemfs_rwr_updateRequest::kObjFieldNumber; +#endif // !_MSC_VER + +xtreemfs_rwr_updateRequest::xtreemfs_rwr_updateRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_rwr_updateRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); + obj_ = const_cast< ::xtreemfs::pbrpc::ObjectData*>(&::xtreemfs::pbrpc::ObjectData::default_instance()); +} + +xtreemfs_rwr_updateRequest::xtreemfs_rwr_updateRequest(const xtreemfs_rwr_updateRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_rwr_updateRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + new_file_size_ = GOOGLE_ULONGLONG(0); + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + offset_ = 0u; + obj_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_rwr_updateRequest::~xtreemfs_rwr_updateRequest() { + SharedDtor(); +} + +void xtreemfs_rwr_updateRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + delete obj_; + } +} + +void xtreemfs_rwr_updateRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_rwr_updateRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_rwr_updateRequest_descriptor_; +} + +const xtreemfs_rwr_updateRequest& xtreemfs_rwr_updateRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_rwr_updateRequest* xtreemfs_rwr_updateRequest::default_instance_ = NULL; + +xtreemfs_rwr_updateRequest* xtreemfs_rwr_updateRequest::New() const { + return new xtreemfs_rwr_updateRequest; +} + +void xtreemfs_rwr_updateRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + new_file_size_ = GOOGLE_ULONGLONG(0); + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + offset_ = 0u; + if (has_obj()) { + if (obj_ != NULL) obj_->::xtreemfs::pbrpc::ObjectData::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_rwr_updateRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_new_file_size; + break; + } + + // required fixed64 new_file_size = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_new_file_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &new_file_size_))); + set_has_new_file_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(33)) goto parse_object_version; + break; + } + + // required fixed64 object_version = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_version_))); + set_has_object_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(45)) goto parse_offset; + break; + } + + // required fixed32 offset = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_offset: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &offset_))); + set_has_offset(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(50)) goto parse_obj; + break; + } + + // required .xtreemfs.pbrpc.ObjectData obj = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_obj: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_obj())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(57)) goto parse_object_number; + break; + } + + // required fixed64 object_number = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_number_))); + set_has_object_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_rwr_updateRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed64 new_file_size = 3; + if (has_new_file_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->new_file_size(), output); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->object_version(), output); + } + + // required fixed32 offset = 5; + if (has_offset()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(5, this->offset(), output); + } + + // required .xtreemfs.pbrpc.ObjectData obj = 6; + if (has_obj()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 6, this->obj(), output); + } + + // required fixed64 object_number = 7; + if (has_object_number()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(7, this->object_number(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_rwr_updateRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed64 new_file_size = 3; + if (has_new_file_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->new_file_size(), target); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->object_version(), target); + } + + // required fixed32 offset = 5; + if (has_offset()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(5, this->offset(), target); + } + + // required .xtreemfs.pbrpc.ObjectData obj = 6; + if (has_obj()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, this->obj(), target); + } + + // required fixed64 object_number = 7; + if (has_object_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(7, this->object_number(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_rwr_updateRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 new_file_size = 3; + if (has_new_file_size()) { + total_size += 1 + 8; + } + + // required fixed64 object_number = 7; + if (has_object_number()) { + total_size += 1 + 8; + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + total_size += 1 + 8; + } + + // required fixed32 offset = 5; + if (has_offset()) { + total_size += 1 + 4; + } + + // required .xtreemfs.pbrpc.ObjectData obj = 6; + if (has_obj()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->obj()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_rwr_updateRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_rwr_updateRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_rwr_updateRequest::MergeFrom(const xtreemfs_rwr_updateRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_new_file_size()) { + set_new_file_size(from.new_file_size()); + } + if (from.has_object_number()) { + set_object_number(from.object_number()); + } + if (from.has_object_version()) { + set_object_version(from.object_version()); + } + if (from.has_offset()) { + set_offset(from.offset()); + } + if (from.has_obj()) { + mutable_obj()->::xtreemfs::pbrpc::ObjectData::MergeFrom(from.obj()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_rwr_updateRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_rwr_updateRequest::CopyFrom(const xtreemfs_rwr_updateRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_rwr_updateRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000007f) != 0x0000007f) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + if (has_obj()) { + if (!this->obj().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_rwr_updateRequest::Swap(xtreemfs_rwr_updateRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(new_file_size_, other->new_file_size_); + std::swap(object_number_, other->object_number_); + std::swap(object_version_, other->object_version_); + std::swap(offset_, other->offset_); + std::swap(obj_, other->obj_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_rwr_updateRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_rwr_updateRequest_descriptor_; + metadata.reflection = xtreemfs_rwr_updateRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_internal_get_gmaxRequest::kFileCredentialsFieldNumber; +const int xtreemfs_internal_get_gmaxRequest::kFileIdFieldNumber; +#endif // !_MSC_VER + +xtreemfs_internal_get_gmaxRequest::xtreemfs_internal_get_gmaxRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_internal_get_gmaxRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_internal_get_gmaxRequest::xtreemfs_internal_get_gmaxRequest(const xtreemfs_internal_get_gmaxRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_internal_get_gmaxRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_internal_get_gmaxRequest::~xtreemfs_internal_get_gmaxRequest() { + SharedDtor(); +} + +void xtreemfs_internal_get_gmaxRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_internal_get_gmaxRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_internal_get_gmaxRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_internal_get_gmaxRequest_descriptor_; +} + +const xtreemfs_internal_get_gmaxRequest& xtreemfs_internal_get_gmaxRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_internal_get_gmaxRequest* xtreemfs_internal_get_gmaxRequest::default_instance_ = NULL; + +xtreemfs_internal_get_gmaxRequest* xtreemfs_internal_get_gmaxRequest::New() const { + return new xtreemfs_internal_get_gmaxRequest; +} + +void xtreemfs_internal_get_gmaxRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_internal_get_gmaxRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_internal_get_gmaxRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_internal_get_gmaxRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_internal_get_gmaxRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_internal_get_gmaxRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_internal_get_gmaxRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_internal_get_gmaxRequest::MergeFrom(const xtreemfs_internal_get_gmaxRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_internal_get_gmaxRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_internal_get_gmaxRequest::CopyFrom(const xtreemfs_internal_get_gmaxRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_internal_get_gmaxRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_internal_get_gmaxRequest::Swap(xtreemfs_internal_get_gmaxRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_internal_get_gmaxRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_internal_get_gmaxRequest_descriptor_; + metadata.reflection = xtreemfs_internal_get_gmaxRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_internal_get_file_sizeRequest::kFileCredentialsFieldNumber; +const int xtreemfs_internal_get_file_sizeRequest::kFileIdFieldNumber; +#endif // !_MSC_VER + +xtreemfs_internal_get_file_sizeRequest::xtreemfs_internal_get_file_sizeRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_internal_get_file_sizeRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_internal_get_file_sizeRequest::xtreemfs_internal_get_file_sizeRequest(const xtreemfs_internal_get_file_sizeRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_internal_get_file_sizeRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_internal_get_file_sizeRequest::~xtreemfs_internal_get_file_sizeRequest() { + SharedDtor(); +} + +void xtreemfs_internal_get_file_sizeRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_internal_get_file_sizeRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_internal_get_file_sizeRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_internal_get_file_sizeRequest_descriptor_; +} + +const xtreemfs_internal_get_file_sizeRequest& xtreemfs_internal_get_file_sizeRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_internal_get_file_sizeRequest* xtreemfs_internal_get_file_sizeRequest::default_instance_ = NULL; + +xtreemfs_internal_get_file_sizeRequest* xtreemfs_internal_get_file_sizeRequest::New() const { + return new xtreemfs_internal_get_file_sizeRequest; +} + +void xtreemfs_internal_get_file_sizeRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_internal_get_file_sizeRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_internal_get_file_sizeRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_internal_get_file_sizeRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_internal_get_file_sizeRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_internal_get_file_sizeRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_internal_get_file_sizeRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_internal_get_file_sizeRequest::MergeFrom(const xtreemfs_internal_get_file_sizeRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_internal_get_file_sizeRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_internal_get_file_sizeRequest::CopyFrom(const xtreemfs_internal_get_file_sizeRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_internal_get_file_sizeRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_internal_get_file_sizeRequest::Swap(xtreemfs_internal_get_file_sizeRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_internal_get_file_sizeRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_internal_get_file_sizeRequest_descriptor_; + metadata.reflection = xtreemfs_internal_get_file_sizeRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_internal_get_file_sizeResponse::kFileSizeFieldNumber; +#endif // !_MSC_VER + +xtreemfs_internal_get_file_sizeResponse::xtreemfs_internal_get_file_sizeResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_internal_get_file_sizeResponse::InitAsDefaultInstance() { +} + +xtreemfs_internal_get_file_sizeResponse::xtreemfs_internal_get_file_sizeResponse(const xtreemfs_internal_get_file_sizeResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_internal_get_file_sizeResponse::SharedCtor() { + _cached_size_ = 0; + file_size_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_internal_get_file_sizeResponse::~xtreemfs_internal_get_file_sizeResponse() { + SharedDtor(); +} + +void xtreemfs_internal_get_file_sizeResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void xtreemfs_internal_get_file_sizeResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_internal_get_file_sizeResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_internal_get_file_sizeResponse_descriptor_; +} + +const xtreemfs_internal_get_file_sizeResponse& xtreemfs_internal_get_file_sizeResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_internal_get_file_sizeResponse* xtreemfs_internal_get_file_sizeResponse::default_instance_ = NULL; + +xtreemfs_internal_get_file_sizeResponse* xtreemfs_internal_get_file_sizeResponse::New() const { + return new xtreemfs_internal_get_file_sizeResponse; +} + +void xtreemfs_internal_get_file_sizeResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + file_size_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_internal_get_file_sizeResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required fixed64 file_size = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &file_size_))); + set_has_file_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_internal_get_file_sizeResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required fixed64 file_size = 1; + if (has_file_size()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(1, this->file_size(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_internal_get_file_sizeResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required fixed64 file_size = 1; + if (has_file_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(1, this->file_size(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_internal_get_file_sizeResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required fixed64 file_size = 1; + if (has_file_size()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_internal_get_file_sizeResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_internal_get_file_sizeResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_internal_get_file_sizeResponse::MergeFrom(const xtreemfs_internal_get_file_sizeResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_size()) { + set_file_size(from.file_size()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_internal_get_file_sizeResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_internal_get_file_sizeResponse::CopyFrom(const xtreemfs_internal_get_file_sizeResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_internal_get_file_sizeResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void xtreemfs_internal_get_file_sizeResponse::Swap(xtreemfs_internal_get_file_sizeResponse* other) { + if (other != this) { + std::swap(file_size_, other->file_size_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_internal_get_file_sizeResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_internal_get_file_sizeResponse_descriptor_; + metadata.reflection = xtreemfs_internal_get_file_sizeResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_internal_read_localRequest::kFileCredentialsFieldNumber; +const int xtreemfs_internal_read_localRequest::kFileIdFieldNumber; +const int xtreemfs_internal_read_localRequest::kObjectNumberFieldNumber; +const int xtreemfs_internal_read_localRequest::kObjectVersionFieldNumber; +const int xtreemfs_internal_read_localRequest::kOffsetFieldNumber; +const int xtreemfs_internal_read_localRequest::kLengthFieldNumber; +const int xtreemfs_internal_read_localRequest::kAttachObjectListFieldNumber; +const int xtreemfs_internal_read_localRequest::kRequiredObjectsFieldNumber; +#endif // !_MSC_VER + +xtreemfs_internal_read_localRequest::xtreemfs_internal_read_localRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_internal_read_localRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_internal_read_localRequest::xtreemfs_internal_read_localRequest(const xtreemfs_internal_read_localRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_internal_read_localRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + offset_ = 0u; + length_ = 0u; + attach_object_list_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_internal_read_localRequest::~xtreemfs_internal_read_localRequest() { + SharedDtor(); +} + +void xtreemfs_internal_read_localRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_internal_read_localRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_internal_read_localRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_internal_read_localRequest_descriptor_; +} + +const xtreemfs_internal_read_localRequest& xtreemfs_internal_read_localRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_internal_read_localRequest* xtreemfs_internal_read_localRequest::default_instance_ = NULL; + +xtreemfs_internal_read_localRequest* xtreemfs_internal_read_localRequest::New() const { + return new xtreemfs_internal_read_localRequest; +} + +void xtreemfs_internal_read_localRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + object_number_ = GOOGLE_ULONGLONG(0); + object_version_ = GOOGLE_ULONGLONG(0); + offset_ = 0u; + length_ = 0u; + attach_object_list_ = false; + } + required_objects_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_internal_read_localRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(25)) goto parse_object_number; + break; + } + + // required fixed64 object_number = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_number_))); + set_has_object_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(33)) goto parse_object_version; + break; + } + + // required fixed64 object_version = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_object_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED64>( + input, &object_version_))); + set_has_object_version(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(45)) goto parse_offset; + break; + } + + // required fixed32 offset = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_offset: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &offset_))); + set_has_offset(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(53)) goto parse_length; + break; + } + + // required fixed32 length = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_length: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &length_))); + set_has_length(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(56)) goto parse_attach_object_list; + break; + } + + // required bool attach_object_list = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_attach_object_list: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &attach_object_list_))); + set_has_attach_object_list(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(66)) goto parse_required_objects; + break; + } + + // repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_required_objects: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_required_objects())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(66)) goto parse_required_objects; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_internal_read_localRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(3, this->object_number(), output); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed64(4, this->object_version(), output); + } + + // required fixed32 offset = 5; + if (has_offset()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(5, this->offset(), output); + } + + // required fixed32 length = 6; + if (has_length()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(6, this->length(), output); + } + + // required bool attach_object_list = 7; + if (has_attach_object_list()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->attach_object_list(), output); + } + + // repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + for (int i = 0; i < this->required_objects_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 8, this->required_objects(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_internal_read_localRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(3, this->object_number(), target); + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed64ToArray(4, this->object_version(), target); + } + + // required fixed32 offset = 5; + if (has_offset()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(5, this->offset(), target); + } + + // required fixed32 length = 6; + if (has_length()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(6, this->length(), target); + } + + // required bool attach_object_list = 7; + if (has_attach_object_list()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(7, this->attach_object_list(), target); + } + + // repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + for (int i = 0; i < this->required_objects_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 8, this->required_objects(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_internal_read_localRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed64 object_number = 3; + if (has_object_number()) { + total_size += 1 + 8; + } + + // required fixed64 object_version = 4; + if (has_object_version()) { + total_size += 1 + 8; + } + + // required fixed32 offset = 5; + if (has_offset()) { + total_size += 1 + 4; + } + + // required fixed32 length = 6; + if (has_length()) { + total_size += 1 + 4; + } + + // required bool attach_object_list = 7; + if (has_attach_object_list()) { + total_size += 1 + 1; + } + + } + // repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + total_size += 1 * this->required_objects_size(); + for (int i = 0; i < this->required_objects_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->required_objects(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_internal_read_localRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_internal_read_localRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_internal_read_localRequest::MergeFrom(const xtreemfs_internal_read_localRequest& from) { + GOOGLE_CHECK_NE(&from, this); + required_objects_.MergeFrom(from.required_objects_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_object_number()) { + set_object_number(from.object_number()); + } + if (from.has_object_version()) { + set_object_version(from.object_version()); + } + if (from.has_offset()) { + set_offset(from.offset()); + } + if (from.has_length()) { + set_length(from.length()); + } + if (from.has_attach_object_list()) { + set_attach_object_list(from.attach_object_list()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_internal_read_localRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_internal_read_localRequest::CopyFrom(const xtreemfs_internal_read_localRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_internal_read_localRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x0000007f) != 0x0000007f) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + for (int i = 0; i < required_objects_size(); i++) { + if (!this->required_objects(i).IsInitialized()) return false; + } + return true; +} + +void xtreemfs_internal_read_localRequest::Swap(xtreemfs_internal_read_localRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(object_number_, other->object_number_); + std::swap(object_version_, other->object_version_); + std::swap(offset_, other->offset_); + std::swap(length_, other->length_); + std::swap(attach_object_list_, other->attach_object_list_); + required_objects_.Swap(&other->required_objects_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_internal_read_localRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_internal_read_localRequest_descriptor_; + metadata.reflection = xtreemfs_internal_read_localRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_internal_get_object_setRequest::kFileCredentialsFieldNumber; +const int xtreemfs_internal_get_object_setRequest::kFileIdFieldNumber; +#endif // !_MSC_VER + +xtreemfs_internal_get_object_setRequest::xtreemfs_internal_get_object_setRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_internal_get_object_setRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_internal_get_object_setRequest::xtreemfs_internal_get_object_setRequest(const xtreemfs_internal_get_object_setRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_internal_get_object_setRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_internal_get_object_setRequest::~xtreemfs_internal_get_object_setRequest() { + SharedDtor(); +} + +void xtreemfs_internal_get_object_setRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_internal_get_object_setRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_internal_get_object_setRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_internal_get_object_setRequest_descriptor_; +} + +const xtreemfs_internal_get_object_setRequest& xtreemfs_internal_get_object_setRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_internal_get_object_setRequest* xtreemfs_internal_get_object_setRequest::default_instance_ = NULL; + +xtreemfs_internal_get_object_setRequest* xtreemfs_internal_get_object_setRequest::New() const { + return new xtreemfs_internal_get_object_setRequest; +} + +void xtreemfs_internal_get_object_setRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_internal_get_object_setRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_internal_get_object_setRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_internal_get_object_setRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_internal_get_object_setRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_internal_get_object_setRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_internal_get_object_setRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_internal_get_object_setRequest::MergeFrom(const xtreemfs_internal_get_object_setRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_internal_get_object_setRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_internal_get_object_setRequest::CopyFrom(const xtreemfs_internal_get_object_setRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_internal_get_object_setRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_internal_get_object_setRequest::Swap(xtreemfs_internal_get_object_setRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_internal_get_object_setRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_internal_get_object_setRequest_descriptor_; + metadata.reflection = xtreemfs_internal_get_object_setRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_internal_get_fileid_listResponse::kFileIdsFieldNumber; +#endif // !_MSC_VER + +xtreemfs_internal_get_fileid_listResponse::xtreemfs_internal_get_fileid_listResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_internal_get_fileid_listResponse::InitAsDefaultInstance() { +} + +xtreemfs_internal_get_fileid_listResponse::xtreemfs_internal_get_fileid_listResponse(const xtreemfs_internal_get_fileid_listResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_internal_get_fileid_listResponse::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_internal_get_fileid_listResponse::~xtreemfs_internal_get_fileid_listResponse() { + SharedDtor(); +} + +void xtreemfs_internal_get_fileid_listResponse::SharedDtor() { + if (this != default_instance_) { + } +} + +void xtreemfs_internal_get_fileid_listResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_internal_get_fileid_listResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_internal_get_fileid_listResponse_descriptor_; +} + +const xtreemfs_internal_get_fileid_listResponse& xtreemfs_internal_get_fileid_listResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_internal_get_fileid_listResponse* xtreemfs_internal_get_fileid_listResponse::default_instance_ = NULL; + +xtreemfs_internal_get_fileid_listResponse* xtreemfs_internal_get_fileid_listResponse::New() const { + return new xtreemfs_internal_get_fileid_listResponse; +} + +void xtreemfs_internal_get_fileid_listResponse::Clear() { + file_ids_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_internal_get_fileid_listResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string file_ids = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_ids: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_file_ids())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_ids(this->file_ids_size() - 1).data(), + this->file_ids(this->file_ids_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_file_ids; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_internal_get_fileid_listResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated string file_ids = 1; + for (int i = 0; i < this->file_ids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_ids(i).data(), this->file_ids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_ids(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_internal_get_fileid_listResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated string file_ids = 1; + for (int i = 0; i < this->file_ids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_ids(i).data(), this->file_ids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->file_ids(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_internal_get_fileid_listResponse::ByteSize() const { + int total_size = 0; + + // repeated string file_ids = 1; + total_size += 1 * this->file_ids_size(); + for (int i = 0; i < this->file_ids_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_ids(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_internal_get_fileid_listResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_internal_get_fileid_listResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_internal_get_fileid_listResponse::MergeFrom(const xtreemfs_internal_get_fileid_listResponse& from) { + GOOGLE_CHECK_NE(&from, this); + file_ids_.MergeFrom(from.file_ids_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_internal_get_fileid_listResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_internal_get_fileid_listResponse::CopyFrom(const xtreemfs_internal_get_fileid_listResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_internal_get_fileid_listResponse::IsInitialized() const { + + return true; +} + +void xtreemfs_internal_get_fileid_listResponse::Swap(xtreemfs_internal_get_fileid_listResponse* other) { + if (other != this) { + file_ids_.Swap(&other->file_ids_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_internal_get_fileid_listResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_internal_get_fileid_listResponse_descriptor_; + metadata.reflection = xtreemfs_internal_get_fileid_listResponse_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int lockRequest::kFileCredentialsFieldNumber; +const int lockRequest::kLockRequestFieldNumber; +#endif // !_MSC_VER + +lockRequest::lockRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void lockRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); + lock_request_ = const_cast< ::xtreemfs::pbrpc::Lock*>(&::xtreemfs::pbrpc::Lock::default_instance()); +} + +lockRequest::lockRequest(const lockRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void lockRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + lock_request_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +lockRequest::~lockRequest() { + SharedDtor(); +} + +void lockRequest::SharedDtor() { + if (this != default_instance_) { + delete file_credentials_; + delete lock_request_; + } +} + +void lockRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* lockRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return lockRequest_descriptor_; +} + +const lockRequest& lockRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +lockRequest* lockRequest::default_instance_ = NULL; + +lockRequest* lockRequest::New() const { + return new lockRequest; +} + +void lockRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_lock_request()) { + if (lock_request_ != NULL) lock_request_->::xtreemfs::pbrpc::Lock::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool lockRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_lock_request; + break; + } + + // required .xtreemfs.pbrpc.Lock lock_request = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_lock_request: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_lock_request())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void lockRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required .xtreemfs.pbrpc.Lock lock_request = 2; + if (has_lock_request()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->lock_request(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* lockRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required .xtreemfs.pbrpc.Lock lock_request = 2; + if (has_lock_request()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->lock_request(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int lockRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required .xtreemfs.pbrpc.Lock lock_request = 2; + if (has_lock_request()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->lock_request()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void lockRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const lockRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void lockRequest::MergeFrom(const lockRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_lock_request()) { + mutable_lock_request()->::xtreemfs::pbrpc::Lock::MergeFrom(from.lock_request()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void lockRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void lockRequest::CopyFrom(const lockRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool lockRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + if (has_lock_request()) { + if (!this->lock_request().IsInitialized()) return false; + } + return true; +} + +void lockRequest::Swap(lockRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(lock_request_, other->lock_request_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata lockRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = lockRequest_descriptor_; + metadata.reflection = lockRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_pingMesssage::kCoordinatesFieldNumber; +const int xtreemfs_pingMesssage::kRequestResponseFieldNumber; +#endif // !_MSC_VER + +xtreemfs_pingMesssage::xtreemfs_pingMesssage() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_pingMesssage::InitAsDefaultInstance() { + coordinates_ = const_cast< ::xtreemfs::pbrpc::VivaldiCoordinates*>(&::xtreemfs::pbrpc::VivaldiCoordinates::default_instance()); +} + +xtreemfs_pingMesssage::xtreemfs_pingMesssage(const xtreemfs_pingMesssage& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_pingMesssage::SharedCtor() { + _cached_size_ = 0; + coordinates_ = NULL; + request_response_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_pingMesssage::~xtreemfs_pingMesssage() { + SharedDtor(); +} + +void xtreemfs_pingMesssage::SharedDtor() { + if (this != default_instance_) { + delete coordinates_; + } +} + +void xtreemfs_pingMesssage::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_pingMesssage::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_pingMesssage_descriptor_; +} + +const xtreemfs_pingMesssage& xtreemfs_pingMesssage::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_pingMesssage* xtreemfs_pingMesssage::default_instance_ = NULL; + +xtreemfs_pingMesssage* xtreemfs_pingMesssage::New() const { + return new xtreemfs_pingMesssage; +} + +void xtreemfs_pingMesssage::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_coordinates()) { + if (coordinates_ != NULL) coordinates_->::xtreemfs::pbrpc::VivaldiCoordinates::Clear(); + } + request_response_ = false; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_pingMesssage::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_coordinates())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_request_response; + break; + } + + // required bool request_response = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_request_response: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &request_response_))); + set_has_request_response(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_pingMesssage::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + if (has_coordinates()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->coordinates(), output); + } + + // required bool request_response = 2; + if (has_request_response()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->request_response(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_pingMesssage::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + if (has_coordinates()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->coordinates(), target); + } + + // required bool request_response = 2; + if (has_request_response()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->request_response(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_pingMesssage::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + if (has_coordinates()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->coordinates()); + } + + // required bool request_response = 2; + if (has_request_response()) { + total_size += 1 + 1; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_pingMesssage::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_pingMesssage* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_pingMesssage::MergeFrom(const xtreemfs_pingMesssage& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_coordinates()) { + mutable_coordinates()->::xtreemfs::pbrpc::VivaldiCoordinates::MergeFrom(from.coordinates()); + } + if (from.has_request_response()) { + set_request_response(from.request_response()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_pingMesssage::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_pingMesssage::CopyFrom(const xtreemfs_pingMesssage& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_pingMesssage::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_coordinates()) { + if (!this->coordinates().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_pingMesssage::Swap(xtreemfs_pingMesssage* other) { + if (other != this) { + std::swap(coordinates_, other->coordinates_); + std::swap(request_response_, other->request_response_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_pingMesssage::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_pingMesssage_descriptor_; + metadata.reflection = xtreemfs_pingMesssage_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_rwr_auth_stateRequest::kFileCredentialsFieldNumber; +const int xtreemfs_rwr_auth_stateRequest::kFileIdFieldNumber; +const int xtreemfs_rwr_auth_stateRequest::kStateFieldNumber; +#endif // !_MSC_VER + +xtreemfs_rwr_auth_stateRequest::xtreemfs_rwr_auth_stateRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_rwr_auth_stateRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); + state_ = const_cast< ::xtreemfs::pbrpc::AuthoritativeReplicaState*>(&::xtreemfs::pbrpc::AuthoritativeReplicaState::default_instance()); +} + +xtreemfs_rwr_auth_stateRequest::xtreemfs_rwr_auth_stateRequest(const xtreemfs_rwr_auth_stateRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_rwr_auth_stateRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + state_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_rwr_auth_stateRequest::~xtreemfs_rwr_auth_stateRequest() { + SharedDtor(); +} + +void xtreemfs_rwr_auth_stateRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + delete state_; + } +} + +void xtreemfs_rwr_auth_stateRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_rwr_auth_stateRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_rwr_auth_stateRequest_descriptor_; +} + +const xtreemfs_rwr_auth_stateRequest& xtreemfs_rwr_auth_stateRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_rwr_auth_stateRequest* xtreemfs_rwr_auth_stateRequest::default_instance_ = NULL; + +xtreemfs_rwr_auth_stateRequest* xtreemfs_rwr_auth_stateRequest::New() const { + return new xtreemfs_rwr_auth_stateRequest; +} + +void xtreemfs_rwr_auth_stateRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + if (has_state()) { + if (state_ != NULL) state_->::xtreemfs::pbrpc::AuthoritativeReplicaState::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_rwr_auth_stateRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_state; + break; + } + + // required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_state: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_state())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_rwr_auth_stateRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + if (has_state()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->state(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_rwr_auth_stateRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + if (has_state()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->state(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_rwr_auth_stateRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + if (has_state()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->state()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_rwr_auth_stateRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_rwr_auth_stateRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_rwr_auth_stateRequest::MergeFrom(const xtreemfs_rwr_auth_stateRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_state()) { + mutable_state()->::xtreemfs::pbrpc::AuthoritativeReplicaState::MergeFrom(from.state()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_rwr_auth_stateRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_rwr_auth_stateRequest::CopyFrom(const xtreemfs_rwr_auth_stateRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_rwr_auth_stateRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + if (has_state()) { + if (!this->state().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_rwr_auth_stateRequest::Swap(xtreemfs_rwr_auth_stateRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(state_, other->state_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_rwr_auth_stateRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_rwr_auth_stateRequest_descriptor_; + metadata.reflection = xtreemfs_rwr_auth_stateRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_rwr_reset_completeRequest::kFileCredentialsFieldNumber; +const int xtreemfs_rwr_reset_completeRequest::kFileIdFieldNumber; +const int xtreemfs_rwr_reset_completeRequest::kPrimaryEpochFieldNumber; +#endif // !_MSC_VER + +xtreemfs_rwr_reset_completeRequest::xtreemfs_rwr_reset_completeRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_rwr_reset_completeRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_rwr_reset_completeRequest::xtreemfs_rwr_reset_completeRequest(const xtreemfs_rwr_reset_completeRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_rwr_reset_completeRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + primary_epoch_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_rwr_reset_completeRequest::~xtreemfs_rwr_reset_completeRequest() { + SharedDtor(); +} + +void xtreemfs_rwr_reset_completeRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_rwr_reset_completeRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_rwr_reset_completeRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_rwr_reset_completeRequest_descriptor_; +} + +const xtreemfs_rwr_reset_completeRequest& xtreemfs_rwr_reset_completeRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_rwr_reset_completeRequest* xtreemfs_rwr_reset_completeRequest::default_instance_ = NULL; + +xtreemfs_rwr_reset_completeRequest* xtreemfs_rwr_reset_completeRequest::New() const { + return new xtreemfs_rwr_reset_completeRequest; +} + +void xtreemfs_rwr_reset_completeRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + primary_epoch_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_rwr_reset_completeRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(29)) goto parse_primary_epoch; + break; + } + + // required fixed32 primary_epoch = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_primary_epoch: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_FIXED32>( + input, &primary_epoch_))); + set_has_primary_epoch(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_rwr_reset_completeRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + // required fixed32 primary_epoch = 3; + if (has_primary_epoch()) { + ::google::protobuf::internal::WireFormatLite::WriteFixed32(3, this->primary_epoch(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_rwr_reset_completeRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + // required fixed32 primary_epoch = 3; + if (has_primary_epoch()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFixed32ToArray(3, this->primary_epoch(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_rwr_reset_completeRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + // required fixed32 primary_epoch = 3; + if (has_primary_epoch()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_rwr_reset_completeRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_rwr_reset_completeRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_rwr_reset_completeRequest::MergeFrom(const xtreemfs_rwr_reset_completeRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + if (from.has_primary_epoch()) { + set_primary_epoch(from.primary_epoch()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_rwr_reset_completeRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_rwr_reset_completeRequest::CopyFrom(const xtreemfs_rwr_reset_completeRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_rwr_reset_completeRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_rwr_reset_completeRequest::Swap(xtreemfs_rwr_reset_completeRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(primary_epoch_, other->primary_epoch_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_rwr_reset_completeRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_rwr_reset_completeRequest_descriptor_; + metadata.reflection = xtreemfs_rwr_reset_completeRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_xloc_set_invalidateRequest::kFileCredentialsFieldNumber; +const int xtreemfs_xloc_set_invalidateRequest::kFileIdFieldNumber; +#endif // !_MSC_VER + +xtreemfs_xloc_set_invalidateRequest::xtreemfs_xloc_set_invalidateRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_xloc_set_invalidateRequest::InitAsDefaultInstance() { + file_credentials_ = const_cast< ::xtreemfs::pbrpc::FileCredentials*>(&::xtreemfs::pbrpc::FileCredentials::default_instance()); +} + +xtreemfs_xloc_set_invalidateRequest::xtreemfs_xloc_set_invalidateRequest(const xtreemfs_xloc_set_invalidateRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_xloc_set_invalidateRequest::SharedCtor() { + _cached_size_ = 0; + file_credentials_ = NULL; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_xloc_set_invalidateRequest::~xtreemfs_xloc_set_invalidateRequest() { + SharedDtor(); +} + +void xtreemfs_xloc_set_invalidateRequest::SharedDtor() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (this != default_instance_) { + delete file_credentials_; + } +} + +void xtreemfs_xloc_set_invalidateRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_xloc_set_invalidateRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_xloc_set_invalidateRequest_descriptor_; +} + +const xtreemfs_xloc_set_invalidateRequest& xtreemfs_xloc_set_invalidateRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_xloc_set_invalidateRequest* xtreemfs_xloc_set_invalidateRequest::default_instance_ = NULL; + +xtreemfs_xloc_set_invalidateRequest* xtreemfs_xloc_set_invalidateRequest::New() const { + return new xtreemfs_xloc_set_invalidateRequest; +} + +void xtreemfs_xloc_set_invalidateRequest::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file_credentials()) { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + } + if (has_file_id()) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_xloc_set_invalidateRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file_credentials())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_file_id; + break; + } + + // required string file_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_xloc_set_invalidateRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file_credentials(), output); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->file_id(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_xloc_set_invalidateRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file_credentials(), target); + } + + // required string file_id = 2; + if (has_file_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_id().data(), this->file_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->file_id(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_xloc_set_invalidateRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + if (has_file_credentials()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file_credentials()); + } + + // required string file_id = 2; + if (has_file_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_id()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_xloc_set_invalidateRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_xloc_set_invalidateRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_xloc_set_invalidateRequest::MergeFrom(const xtreemfs_xloc_set_invalidateRequest& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file_credentials()) { + mutable_file_credentials()->::xtreemfs::pbrpc::FileCredentials::MergeFrom(from.file_credentials()); + } + if (from.has_file_id()) { + set_file_id(from.file_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_xloc_set_invalidateRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_xloc_set_invalidateRequest::CopyFrom(const xtreemfs_xloc_set_invalidateRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_xloc_set_invalidateRequest::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_file_credentials()) { + if (!this->file_credentials().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_xloc_set_invalidateRequest::Swap(xtreemfs_xloc_set_invalidateRequest* other) { + if (other != this) { + std::swap(file_credentials_, other->file_credentials_); + std::swap(file_id_, other->file_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_xloc_set_invalidateRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_xloc_set_invalidateRequest_descriptor_; + metadata.reflection = xtreemfs_xloc_set_invalidateRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int xtreemfs_xloc_set_invalidateResponse::kLeaseStateFieldNumber; +const int xtreemfs_xloc_set_invalidateResponse::kReplicaStatusFieldNumber; +#endif // !_MSC_VER + +xtreemfs_xloc_set_invalidateResponse::xtreemfs_xloc_set_invalidateResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void xtreemfs_xloc_set_invalidateResponse::InitAsDefaultInstance() { + replica_status_ = const_cast< ::xtreemfs::pbrpc::ReplicaStatus*>(&::xtreemfs::pbrpc::ReplicaStatus::default_instance()); +} + +xtreemfs_xloc_set_invalidateResponse::xtreemfs_xloc_set_invalidateResponse(const xtreemfs_xloc_set_invalidateResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void xtreemfs_xloc_set_invalidateResponse::SharedCtor() { + _cached_size_ = 0; + lease_state_ = 0; + replica_status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +xtreemfs_xloc_set_invalidateResponse::~xtreemfs_xloc_set_invalidateResponse() { + SharedDtor(); +} + +void xtreemfs_xloc_set_invalidateResponse::SharedDtor() { + if (this != default_instance_) { + delete replica_status_; + } +} + +void xtreemfs_xloc_set_invalidateResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* xtreemfs_xloc_set_invalidateResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return xtreemfs_xloc_set_invalidateResponse_descriptor_; +} + +const xtreemfs_xloc_set_invalidateResponse& xtreemfs_xloc_set_invalidateResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + return *default_instance_; +} + +xtreemfs_xloc_set_invalidateResponse* xtreemfs_xloc_set_invalidateResponse::default_instance_ = NULL; + +xtreemfs_xloc_set_invalidateResponse* xtreemfs_xloc_set_invalidateResponse::New() const { + return new xtreemfs_xloc_set_invalidateResponse; +} + +void xtreemfs_xloc_set_invalidateResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + lease_state_ = 0; + if (has_replica_status()) { + if (replica_status_ != NULL) replica_status_->::xtreemfs::pbrpc::ReplicaStatus::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool xtreemfs_xloc_set_invalidateResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .xtreemfs.pbrpc.LeaseState lease_state = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::xtreemfs::pbrpc::LeaseState_IsValid(value)) { + set_lease_state(static_cast< ::xtreemfs::pbrpc::LeaseState >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_replica_status; + break; + } + + // optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_replica_status: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_replica_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void xtreemfs_xloc_set_invalidateResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .xtreemfs.pbrpc.LeaseState lease_state = 1; + if (has_lease_state()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->lease_state(), output); + } + + // optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + if (has_replica_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->replica_status(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* xtreemfs_xloc_set_invalidateResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .xtreemfs.pbrpc.LeaseState lease_state = 1; + if (has_lease_state()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->lease_state(), target); + } + + // optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + if (has_replica_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->replica_status(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int xtreemfs_xloc_set_invalidateResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .xtreemfs.pbrpc.LeaseState lease_state = 1; + if (has_lease_state()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->lease_state()); + } + + // optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + if (has_replica_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->replica_status()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void xtreemfs_xloc_set_invalidateResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const xtreemfs_xloc_set_invalidateResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void xtreemfs_xloc_set_invalidateResponse::MergeFrom(const xtreemfs_xloc_set_invalidateResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_lease_state()) { + set_lease_state(from.lease_state()); + } + if (from.has_replica_status()) { + mutable_replica_status()->::xtreemfs::pbrpc::ReplicaStatus::MergeFrom(from.replica_status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void xtreemfs_xloc_set_invalidateResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void xtreemfs_xloc_set_invalidateResponse::CopyFrom(const xtreemfs_xloc_set_invalidateResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool xtreemfs_xloc_set_invalidateResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_replica_status()) { + if (!this->replica_status().IsInitialized()) return false; + } + return true; +} + +void xtreemfs_xloc_set_invalidateResponse::Swap(xtreemfs_xloc_set_invalidateResponse* other) { + if (other != this) { + std::swap(lease_state_, other->lease_state_); + std::swap(replica_status_, other->replica_status_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata xtreemfs_xloc_set_invalidateResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = xtreemfs_xloc_set_invalidateResponse_descriptor_; + metadata.reflection = xtreemfs_xloc_set_invalidateResponse_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/generated/xtreemfs/OSD.pb.h b/cpp/generated/xtreemfs/OSD.pb.h new file mode 100644 index 0000000..f299263 --- /dev/null +++ b/cpp/generated/xtreemfs/OSD.pb.h @@ -0,0 +1,9181 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/OSD.proto + +#ifndef PROTOBUF_xtreemfs_2fOSD_2eproto__INCLUDED +#define PROTOBUF_xtreemfs_2fOSD_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include "include/PBRPC.pb.h" +#include "include/Common.pb.h" +#include "xtreemfs/GlobalTypes.pb.h" +// @@protoc_insertion_point(includes) + +namespace xtreemfs { +namespace pbrpc { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); +void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); +void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + +class InternalGmax; +class Lock; +class ObjectData; +class ObjectList; +class ObjectVersion; +class TruncateRecord; +class TruncateLog; +class XLocSetVersionState; +class ReplicaStatus; +class ObjectVersionMapping; +class AuthoritativeReplicaState; +class InternalReadLocalResponse; +class readRequest; +class truncateRequest; +class unlink_osd_Request; +class writeRequest; +class xtreemfs_broadcast_gmaxRequest; +class xtreemfs_check_objectRequest; +class xtreemfs_cleanup_get_resultsResponse; +class xtreemfs_cleanup_is_runningResponse; +class xtreemfs_cleanup_startRequest; +class xtreemfs_cleanup_statusResponse; +class xtreemfs_rwr_fetchRequest; +class xtreemfs_repair_objectRequest; +class xtreemfs_rwr_flease_msgRequest; +class xtreemfs_rwr_set_primary_epochRequest; +class xtreemfs_rwr_statusRequest; +class xtreemfs_rwr_truncateRequest; +class xtreemfs_rwr_updateRequest; +class xtreemfs_internal_get_gmaxRequest; +class xtreemfs_internal_get_file_sizeRequest; +class xtreemfs_internal_get_file_sizeResponse; +class xtreemfs_internal_read_localRequest; +class xtreemfs_internal_get_object_setRequest; +class xtreemfs_internal_get_fileid_listResponse; +class lockRequest; +class xtreemfs_pingMesssage; +class xtreemfs_rwr_auth_stateRequest; +class xtreemfs_rwr_reset_completeRequest; +class xtreemfs_xloc_set_invalidateRequest; +class xtreemfs_xloc_set_invalidateResponse; + +enum OSDHealthResult { + OSD_HEALTH_RESULT_PASSED = 0, + OSD_HEALTH_RESULT_WARNING = 1, + OSD_HEALTH_RESULT_FAILED = 2, + OSD_HEALTH_RESULT_NOT_AVAIL = 3 +}; +bool OSDHealthResult_IsValid(int value); +const OSDHealthResult OSDHealthResult_MIN = OSD_HEALTH_RESULT_PASSED; +const OSDHealthResult OSDHealthResult_MAX = OSD_HEALTH_RESULT_NOT_AVAIL; +const int OSDHealthResult_ARRAYSIZE = OSDHealthResult_MAX + 1; + +const ::google::protobuf::EnumDescriptor* OSDHealthResult_descriptor(); +inline const ::std::string& OSDHealthResult_Name(OSDHealthResult value) { + return ::google::protobuf::internal::NameOfEnum( + OSDHealthResult_descriptor(), value); +} +inline bool OSDHealthResult_Parse( + const ::std::string& name, OSDHealthResult* value) { + return ::google::protobuf::internal::ParseNamedEnum( + OSDHealthResult_descriptor(), name, value); +} +// =================================================================== + +class InternalGmax : public ::google::protobuf::Message { + public: + InternalGmax(); + virtual ~InternalGmax(); + + InternalGmax(const InternalGmax& from); + + inline InternalGmax& operator=(const InternalGmax& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const InternalGmax& default_instance(); + + void Swap(InternalGmax* other); + + // implements Message ---------------------------------------------- + + InternalGmax* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const InternalGmax& from); + void MergeFrom(const InternalGmax& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 epoch = 1; + inline bool has_epoch() const; + inline void clear_epoch(); + static const int kEpochFieldNumber = 1; + inline ::google::protobuf::uint64 epoch() const; + inline void set_epoch(::google::protobuf::uint64 value); + + // required fixed64 file_size = 2; + inline bool has_file_size() const; + inline void clear_file_size(); + static const int kFileSizeFieldNumber = 2; + inline ::google::protobuf::uint64 file_size() const; + inline void set_file_size(::google::protobuf::uint64 value); + + // required fixed64 last_object_id = 3; + inline bool has_last_object_id() const; + inline void clear_last_object_id(); + static const int kLastObjectIdFieldNumber = 3; + inline ::google::protobuf::uint64 last_object_id() const; + inline void set_last_object_id(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.InternalGmax) + private: + inline void set_has_epoch(); + inline void clear_has_epoch(); + inline void set_has_file_size(); + inline void clear_has_file_size(); + inline void set_has_last_object_id(); + inline void clear_has_last_object_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 epoch_; + ::google::protobuf::uint64 file_size_; + ::google::protobuf::uint64 last_object_id_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static InternalGmax* default_instance_; +}; +// ------------------------------------------------------------------- + +class Lock : public ::google::protobuf::Message { + public: + Lock(); + virtual ~Lock(); + + Lock(const Lock& from); + + inline Lock& operator=(const Lock& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Lock& default_instance(); + + void Swap(Lock* other); + + // implements Message ---------------------------------------------- + + Lock* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Lock& from); + void MergeFrom(const Lock& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed32 client_pid = 1; + inline bool has_client_pid() const; + inline void clear_client_pid(); + static const int kClientPidFieldNumber = 1; + inline ::google::protobuf::uint32 client_pid() const; + inline void set_client_pid(::google::protobuf::uint32 value); + + // required string client_uuid = 2; + inline bool has_client_uuid() const; + inline void clear_client_uuid(); + static const int kClientUuidFieldNumber = 2; + inline const ::std::string& client_uuid() const; + inline void set_client_uuid(const ::std::string& value); + inline void set_client_uuid(const char* value); + inline void set_client_uuid(const char* value, size_t size); + inline ::std::string* mutable_client_uuid(); + inline ::std::string* release_client_uuid(); + inline void set_allocated_client_uuid(::std::string* client_uuid); + + // required fixed64 length = 3; + inline bool has_length() const; + inline void clear_length(); + static const int kLengthFieldNumber = 3; + inline ::google::protobuf::uint64 length() const; + inline void set_length(::google::protobuf::uint64 value); + + // required fixed64 offset = 4; + inline bool has_offset() const; + inline void clear_offset(); + static const int kOffsetFieldNumber = 4; + inline ::google::protobuf::uint64 offset() const; + inline void set_offset(::google::protobuf::uint64 value); + + // required bool exclusive = 5; + inline bool has_exclusive() const; + inline void clear_exclusive(); + static const int kExclusiveFieldNumber = 5; + inline bool exclusive() const; + inline void set_exclusive(bool value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Lock) + private: + inline void set_has_client_pid(); + inline void clear_has_client_pid(); + inline void set_has_client_uuid(); + inline void clear_has_client_uuid(); + inline void set_has_length(); + inline void clear_has_length(); + inline void set_has_offset(); + inline void clear_has_offset(); + inline void set_has_exclusive(); + inline void clear_has_exclusive(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* client_uuid_; + ::google::protobuf::uint64 length_; + ::google::protobuf::uint32 client_pid_; + bool exclusive_; + ::google::protobuf::uint64 offset_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static Lock* default_instance_; +}; +// ------------------------------------------------------------------- + +class ObjectData : public ::google::protobuf::Message { + public: + ObjectData(); + virtual ~ObjectData(); + + ObjectData(const ObjectData& from); + + inline ObjectData& operator=(const ObjectData& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ObjectData& default_instance(); + + void Swap(ObjectData* other); + + // implements Message ---------------------------------------------- + + ObjectData* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ObjectData& from); + void MergeFrom(const ObjectData& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed32 checksum = 1; + inline bool has_checksum() const; + inline void clear_checksum(); + static const int kChecksumFieldNumber = 1; + inline ::google::protobuf::uint32 checksum() const; + inline void set_checksum(::google::protobuf::uint32 value); + + // required bool invalid_checksum_on_osd = 2; + inline bool has_invalid_checksum_on_osd() const; + inline void clear_invalid_checksum_on_osd(); + static const int kInvalidChecksumOnOsdFieldNumber = 2; + inline bool invalid_checksum_on_osd() const; + inline void set_invalid_checksum_on_osd(bool value); + + // required fixed32 zero_padding = 3; + inline bool has_zero_padding() const; + inline void clear_zero_padding(); + static const int kZeroPaddingFieldNumber = 3; + inline ::google::protobuf::uint32 zero_padding() const; + inline void set_zero_padding(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ObjectData) + private: + inline void set_has_checksum(); + inline void clear_has_checksum(); + inline void set_has_invalid_checksum_on_osd(); + inline void clear_has_invalid_checksum_on_osd(); + inline void set_has_zero_padding(); + inline void clear_has_zero_padding(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 checksum_; + bool invalid_checksum_on_osd_; + ::google::protobuf::uint32 zero_padding_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static ObjectData* default_instance_; +}; +// ------------------------------------------------------------------- + +class ObjectList : public ::google::protobuf::Message { + public: + ObjectList(); + virtual ~ObjectList(); + + ObjectList(const ObjectList& from); + + inline ObjectList& operator=(const ObjectList& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ObjectList& default_instance(); + + void Swap(ObjectList* other); + + // implements Message ---------------------------------------------- + + ObjectList* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ObjectList& from); + void MergeFrom(const ObjectList& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required bytes set = 1; + inline bool has_set() const; + inline void clear_set(); + static const int kSetFieldNumber = 1; + inline const ::std::string& set() const; + inline void set_set(const ::std::string& value); + inline void set_set(const char* value); + inline void set_set(const void* value, size_t size); + inline ::std::string* mutable_set(); + inline ::std::string* release_set(); + inline void set_allocated_set(::std::string* set); + + // required fixed32 stripe_width = 2; + inline bool has_stripe_width() const; + inline void clear_stripe_width(); + static const int kStripeWidthFieldNumber = 2; + inline ::google::protobuf::uint32 stripe_width() const; + inline void set_stripe_width(::google::protobuf::uint32 value); + + // required fixed32 first_ = 3; + inline bool has_first_() const; + inline void clear_first_(); + static const int kFirstFieldNumber = 3; + inline ::google::protobuf::uint32 first_() const; + inline void set_first_(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ObjectList) + private: + inline void set_has_set(); + inline void clear_has_set(); + inline void set_has_stripe_width(); + inline void clear_has_stripe_width(); + inline void set_has_first_(); + inline void clear_has_first_(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* set_; + ::google::protobuf::uint32 stripe_width_; + ::google::protobuf::uint32 first__; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static ObjectList* default_instance_; +}; +// ------------------------------------------------------------------- + +class ObjectVersion : public ::google::protobuf::Message { + public: + ObjectVersion(); + virtual ~ObjectVersion(); + + ObjectVersion(const ObjectVersion& from); + + inline ObjectVersion& operator=(const ObjectVersion& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ObjectVersion& default_instance(); + + void Swap(ObjectVersion* other); + + // implements Message ---------------------------------------------- + + ObjectVersion* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ObjectVersion& from); + void MergeFrom(const ObjectVersion& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 object_number = 1; + inline bool has_object_number() const; + inline void clear_object_number(); + static const int kObjectNumberFieldNumber = 1; + inline ::google::protobuf::uint64 object_number() const; + inline void set_object_number(::google::protobuf::uint64 value); + + // required fixed64 object_version = 2; + inline bool has_object_version() const; + inline void clear_object_version(); + static const int kObjectVersionFieldNumber = 2; + inline ::google::protobuf::uint64 object_version() const; + inline void set_object_version(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ObjectVersion) + private: + inline void set_has_object_number(); + inline void clear_has_object_number(); + inline void set_has_object_version(); + inline void clear_has_object_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 object_number_; + ::google::protobuf::uint64 object_version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static ObjectVersion* default_instance_; +}; +// ------------------------------------------------------------------- + +class TruncateRecord : public ::google::protobuf::Message { + public: + TruncateRecord(); + virtual ~TruncateRecord(); + + TruncateRecord(const TruncateRecord& from); + + inline TruncateRecord& operator=(const TruncateRecord& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const TruncateRecord& default_instance(); + + void Swap(TruncateRecord* other); + + // implements Message ---------------------------------------------- + + TruncateRecord* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const TruncateRecord& from); + void MergeFrom(const TruncateRecord& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 version = 1; + inline bool has_version() const; + inline void clear_version(); + static const int kVersionFieldNumber = 1; + inline ::google::protobuf::uint64 version() const; + inline void set_version(::google::protobuf::uint64 value); + + // required fixed64 last_object_number = 2; + inline bool has_last_object_number() const; + inline void clear_last_object_number(); + static const int kLastObjectNumberFieldNumber = 2; + inline ::google::protobuf::uint64 last_object_number() const; + inline void set_last_object_number(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.TruncateRecord) + private: + inline void set_has_version(); + inline void clear_has_version(); + inline void set_has_last_object_number(); + inline void clear_has_last_object_number(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 version_; + ::google::protobuf::uint64 last_object_number_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static TruncateRecord* default_instance_; +}; +// ------------------------------------------------------------------- + +class TruncateLog : public ::google::protobuf::Message { + public: + TruncateLog(); + virtual ~TruncateLog(); + + TruncateLog(const TruncateLog& from); + + inline TruncateLog& operator=(const TruncateLog& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const TruncateLog& default_instance(); + + void Swap(TruncateLog* other); + + // implements Message ---------------------------------------------- + + TruncateLog* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const TruncateLog& from); + void MergeFrom(const TruncateLog& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + inline int records_size() const; + inline void clear_records(); + static const int kRecordsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::TruncateRecord& records(int index) const; + inline ::xtreemfs::pbrpc::TruncateRecord* mutable_records(int index); + inline ::xtreemfs::pbrpc::TruncateRecord* add_records(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::TruncateRecord >& + records() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::TruncateRecord >* + mutable_records(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.TruncateLog) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::TruncateRecord > records_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static TruncateLog* default_instance_; +}; +// ------------------------------------------------------------------- + +class XLocSetVersionState : public ::google::protobuf::Message { + public: + XLocSetVersionState(); + virtual ~XLocSetVersionState(); + + XLocSetVersionState(const XLocSetVersionState& from); + + inline XLocSetVersionState& operator=(const XLocSetVersionState& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const XLocSetVersionState& default_instance(); + + void Swap(XLocSetVersionState* other); + + // implements Message ---------------------------------------------- + + XLocSetVersionState* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const XLocSetVersionState& from); + void MergeFrom(const XLocSetVersionState& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed32 version = 1; + inline bool has_version() const; + inline void clear_version(); + static const int kVersionFieldNumber = 1; + inline ::google::protobuf::uint32 version() const; + inline void set_version(::google::protobuf::uint32 value); + + // required bool invalidated = 2; + inline bool has_invalidated() const; + inline void clear_invalidated(); + static const int kInvalidatedFieldNumber = 2; + inline bool invalidated() const; + inline void set_invalidated(bool value); + + // optional fixed64 modified_time = 3; + inline bool has_modified_time() const; + inline void clear_modified_time(); + static const int kModifiedTimeFieldNumber = 3; + inline ::google::protobuf::uint64 modified_time() const; + inline void set_modified_time(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.XLocSetVersionState) + private: + inline void set_has_version(); + inline void clear_has_version(); + inline void set_has_invalidated(); + inline void clear_has_invalidated(); + inline void set_has_modified_time(); + inline void clear_has_modified_time(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 version_; + bool invalidated_; + ::google::protobuf::uint64 modified_time_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static XLocSetVersionState* default_instance_; +}; +// ------------------------------------------------------------------- + +class ReplicaStatus : public ::google::protobuf::Message { + public: + ReplicaStatus(); + virtual ~ReplicaStatus(); + + ReplicaStatus(const ReplicaStatus& from); + + inline ReplicaStatus& operator=(const ReplicaStatus& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ReplicaStatus& default_instance(); + + void Swap(ReplicaStatus* other); + + // implements Message ---------------------------------------------- + + ReplicaStatus* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ReplicaStatus& from); + void MergeFrom(const ReplicaStatus& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 truncate_epoch = 1; + inline bool has_truncate_epoch() const; + inline void clear_truncate_epoch(); + static const int kTruncateEpochFieldNumber = 1; + inline ::google::protobuf::uint64 truncate_epoch() const; + inline void set_truncate_epoch(::google::protobuf::uint64 value); + + // required fixed64 file_size = 2; + inline bool has_file_size() const; + inline void clear_file_size(); + static const int kFileSizeFieldNumber = 2; + inline ::google::protobuf::uint64 file_size() const; + inline void set_file_size(::google::protobuf::uint64 value); + + // required fixed64 max_obj_version = 3; + inline bool has_max_obj_version() const; + inline void clear_max_obj_version(); + static const int kMaxObjVersionFieldNumber = 3; + inline ::google::protobuf::uint64 max_obj_version() const; + inline void set_max_obj_version(::google::protobuf::uint64 value); + + // required fixed32 primary_epoch = 4; + inline bool has_primary_epoch() const; + inline void clear_primary_epoch(); + static const int kPrimaryEpochFieldNumber = 4; + inline ::google::protobuf::uint32 primary_epoch() const; + inline void set_primary_epoch(::google::protobuf::uint32 value); + + // repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + inline int objectversions_size() const; + inline void clear_objectversions(); + static const int kObjectVersionsFieldNumber = 5; + inline const ::xtreemfs::pbrpc::ObjectVersion& objectversions(int index) const; + inline ::xtreemfs::pbrpc::ObjectVersion* mutable_objectversions(int index); + inline ::xtreemfs::pbrpc::ObjectVersion* add_objectversions(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectVersion >& + objectversions() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectVersion >* + mutable_objectversions(); + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + inline bool has_truncate_log() const; + inline void clear_truncate_log(); + static const int kTruncateLogFieldNumber = 6; + inline const ::xtreemfs::pbrpc::TruncateLog& truncate_log() const; + inline ::xtreemfs::pbrpc::TruncateLog* mutable_truncate_log(); + inline ::xtreemfs::pbrpc::TruncateLog* release_truncate_log(); + inline void set_allocated_truncate_log(::xtreemfs::pbrpc::TruncateLog* truncate_log); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ReplicaStatus) + private: + inline void set_has_truncate_epoch(); + inline void clear_has_truncate_epoch(); + inline void set_has_file_size(); + inline void clear_has_file_size(); + inline void set_has_max_obj_version(); + inline void clear_has_max_obj_version(); + inline void set_has_primary_epoch(); + inline void clear_has_primary_epoch(); + inline void set_has_truncate_log(); + inline void clear_has_truncate_log(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 truncate_epoch_; + ::google::protobuf::uint64 file_size_; + ::google::protobuf::uint64 max_obj_version_; + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectVersion > objectversions_; + ::xtreemfs::pbrpc::TruncateLog* truncate_log_; + ::google::protobuf::uint32 primary_epoch_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static ReplicaStatus* default_instance_; +}; +// ------------------------------------------------------------------- + +class ObjectVersionMapping : public ::google::protobuf::Message { + public: + ObjectVersionMapping(); + virtual ~ObjectVersionMapping(); + + ObjectVersionMapping(const ObjectVersionMapping& from); + + inline ObjectVersionMapping& operator=(const ObjectVersionMapping& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ObjectVersionMapping& default_instance(); + + void Swap(ObjectVersionMapping* other); + + // implements Message ---------------------------------------------- + + ObjectVersionMapping* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ObjectVersionMapping& from); + void MergeFrom(const ObjectVersionMapping& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 object_number = 1; + inline bool has_object_number() const; + inline void clear_object_number(); + static const int kObjectNumberFieldNumber = 1; + inline ::google::protobuf::uint64 object_number() const; + inline void set_object_number(::google::protobuf::uint64 value); + + // required fixed64 object_version = 2; + inline bool has_object_version() const; + inline void clear_object_version(); + static const int kObjectVersionFieldNumber = 2; + inline ::google::protobuf::uint64 object_version() const; + inline void set_object_version(::google::protobuf::uint64 value); + + // repeated string osd_uuids = 3; + inline int osd_uuids_size() const; + inline void clear_osd_uuids(); + static const int kOsdUuidsFieldNumber = 3; + inline const ::std::string& osd_uuids(int index) const; + inline ::std::string* mutable_osd_uuids(int index); + inline void set_osd_uuids(int index, const ::std::string& value); + inline void set_osd_uuids(int index, const char* value); + inline void set_osd_uuids(int index, const char* value, size_t size); + inline ::std::string* add_osd_uuids(); + inline void add_osd_uuids(const ::std::string& value); + inline void add_osd_uuids(const char* value); + inline void add_osd_uuids(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& osd_uuids() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_osd_uuids(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ObjectVersionMapping) + private: + inline void set_has_object_number(); + inline void clear_has_object_number(); + inline void set_has_object_version(); + inline void clear_has_object_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 object_number_; + ::google::protobuf::uint64 object_version_; + ::google::protobuf::RepeatedPtrField< ::std::string> osd_uuids_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static ObjectVersionMapping* default_instance_; +}; +// ------------------------------------------------------------------- + +class AuthoritativeReplicaState : public ::google::protobuf::Message { + public: + AuthoritativeReplicaState(); + virtual ~AuthoritativeReplicaState(); + + AuthoritativeReplicaState(const AuthoritativeReplicaState& from); + + inline AuthoritativeReplicaState& operator=(const AuthoritativeReplicaState& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const AuthoritativeReplicaState& default_instance(); + + void Swap(AuthoritativeReplicaState* other); + + // implements Message ---------------------------------------------- + + AuthoritativeReplicaState* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const AuthoritativeReplicaState& from); + void MergeFrom(const AuthoritativeReplicaState& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 truncate_epoch = 1; + inline bool has_truncate_epoch() const; + inline void clear_truncate_epoch(); + static const int kTruncateEpochFieldNumber = 1; + inline ::google::protobuf::uint64 truncate_epoch() const; + inline void set_truncate_epoch(::google::protobuf::uint64 value); + + // required fixed64 max_obj_version = 4; + inline bool has_max_obj_version() const; + inline void clear_max_obj_version(); + static const int kMaxObjVersionFieldNumber = 4; + inline ::google::protobuf::uint64 max_obj_version() const; + inline void set_max_obj_version(::google::protobuf::uint64 value); + + // repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + inline int objectversions_size() const; + inline void clear_objectversions(); + static const int kObjectVersionsFieldNumber = 2; + inline const ::xtreemfs::pbrpc::ObjectVersionMapping& objectversions(int index) const; + inline ::xtreemfs::pbrpc::ObjectVersionMapping* mutable_objectversions(int index); + inline ::xtreemfs::pbrpc::ObjectVersionMapping* add_objectversions(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectVersionMapping >& + objectversions() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectVersionMapping >* + mutable_objectversions(); + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + inline bool has_truncate_log() const; + inline void clear_truncate_log(); + static const int kTruncateLogFieldNumber = 3; + inline const ::xtreemfs::pbrpc::TruncateLog& truncate_log() const; + inline ::xtreemfs::pbrpc::TruncateLog* mutable_truncate_log(); + inline ::xtreemfs::pbrpc::TruncateLog* release_truncate_log(); + inline void set_allocated_truncate_log(::xtreemfs::pbrpc::TruncateLog* truncate_log); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.AuthoritativeReplicaState) + private: + inline void set_has_truncate_epoch(); + inline void clear_has_truncate_epoch(); + inline void set_has_max_obj_version(); + inline void clear_has_max_obj_version(); + inline void set_has_truncate_log(); + inline void clear_has_truncate_log(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 truncate_epoch_; + ::google::protobuf::uint64 max_obj_version_; + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectVersionMapping > objectversions_; + ::xtreemfs::pbrpc::TruncateLog* truncate_log_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static AuthoritativeReplicaState* default_instance_; +}; +// ------------------------------------------------------------------- + +class InternalReadLocalResponse : public ::google::protobuf::Message { + public: + InternalReadLocalResponse(); + virtual ~InternalReadLocalResponse(); + + InternalReadLocalResponse(const InternalReadLocalResponse& from); + + inline InternalReadLocalResponse& operator=(const InternalReadLocalResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const InternalReadLocalResponse& default_instance(); + + void Swap(InternalReadLocalResponse* other); + + // implements Message ---------------------------------------------- + + InternalReadLocalResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const InternalReadLocalResponse& from); + void MergeFrom(const InternalReadLocalResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.ObjectData data = 1; + inline bool has_data() const; + inline void clear_data(); + static const int kDataFieldNumber = 1; + inline const ::xtreemfs::pbrpc::ObjectData& data() const; + inline ::xtreemfs::pbrpc::ObjectData* mutable_data(); + inline ::xtreemfs::pbrpc::ObjectData* release_data(); + inline void set_allocated_data(::xtreemfs::pbrpc::ObjectData* data); + + // repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + inline int object_set_size() const; + inline void clear_object_set(); + static const int kObjectSetFieldNumber = 2; + inline const ::xtreemfs::pbrpc::ObjectList& object_set(int index) const; + inline ::xtreemfs::pbrpc::ObjectList* mutable_object_set(int index); + inline ::xtreemfs::pbrpc::ObjectList* add_object_set(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectList >& + object_set() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectList >* + mutable_object_set(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.InternalReadLocalResponse) + private: + inline void set_has_data(); + inline void clear_has_data(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::ObjectData* data_; + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectList > object_set_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static InternalReadLocalResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class readRequest : public ::google::protobuf::Message { + public: + readRequest(); + virtual ~readRequest(); + + readRequest(const readRequest& from); + + inline readRequest& operator=(const readRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const readRequest& default_instance(); + + void Swap(readRequest* other); + + // implements Message ---------------------------------------------- + + readRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const readRequest& from); + void MergeFrom(const readRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 object_number = 3; + inline bool has_object_number() const; + inline void clear_object_number(); + static const int kObjectNumberFieldNumber = 3; + inline ::google::protobuf::uint64 object_number() const; + inline void set_object_number(::google::protobuf::uint64 value); + + // required fixed64 object_version = 4; + inline bool has_object_version() const; + inline void clear_object_version(); + static const int kObjectVersionFieldNumber = 4; + inline ::google::protobuf::uint64 object_version() const; + inline void set_object_version(::google::protobuf::uint64 value); + + // required fixed32 offset = 5; + inline bool has_offset() const; + inline void clear_offset(); + static const int kOffsetFieldNumber = 5; + inline ::google::protobuf::uint32 offset() const; + inline void set_offset(::google::protobuf::uint32 value); + + // required fixed32 length = 6; + inline bool has_length() const; + inline void clear_length(); + static const int kLengthFieldNumber = 6; + inline ::google::protobuf::uint32 length() const; + inline void set_length(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.readRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_object_number(); + inline void clear_has_object_number(); + inline void set_has_object_version(); + inline void clear_has_object_version(); + inline void set_has_offset(); + inline void clear_has_offset(); + inline void set_has_length(); + inline void clear_has_length(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint64 object_number_; + ::google::protobuf::uint64 object_version_; + ::google::protobuf::uint32 offset_; + ::google::protobuf::uint32 length_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static readRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class truncateRequest : public ::google::protobuf::Message { + public: + truncateRequest(); + virtual ~truncateRequest(); + + truncateRequest(const truncateRequest& from); + + inline truncateRequest& operator=(const truncateRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const truncateRequest& default_instance(); + + void Swap(truncateRequest* other); + + // implements Message ---------------------------------------------- + + truncateRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const truncateRequest& from); + void MergeFrom(const truncateRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 new_file_size = 3; + inline bool has_new_file_size() const; + inline void clear_new_file_size(); + static const int kNewFileSizeFieldNumber = 3; + inline ::google::protobuf::uint64 new_file_size() const; + inline void set_new_file_size(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.truncateRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_new_file_size(); + inline void clear_has_new_file_size(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint64 new_file_size_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static truncateRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class unlink_osd_Request : public ::google::protobuf::Message { + public: + unlink_osd_Request(); + virtual ~unlink_osd_Request(); + + unlink_osd_Request(const unlink_osd_Request& from); + + inline unlink_osd_Request& operator=(const unlink_osd_Request& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const unlink_osd_Request& default_instance(); + + void Swap(unlink_osd_Request* other); + + // implements Message ---------------------------------------------- + + unlink_osd_Request* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const unlink_osd_Request& from); + void MergeFrom(const unlink_osd_Request& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.unlink_osd_Request) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static unlink_osd_Request* default_instance_; +}; +// ------------------------------------------------------------------- + +class writeRequest : public ::google::protobuf::Message { + public: + writeRequest(); + virtual ~writeRequest(); + + writeRequest(const writeRequest& from); + + inline writeRequest& operator=(const writeRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const writeRequest& default_instance(); + + void Swap(writeRequest* other); + + // implements Message ---------------------------------------------- + + writeRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const writeRequest& from); + void MergeFrom(const writeRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 object_number = 3; + inline bool has_object_number() const; + inline void clear_object_number(); + static const int kObjectNumberFieldNumber = 3; + inline ::google::protobuf::uint64 object_number() const; + inline void set_object_number(::google::protobuf::uint64 value); + + // required fixed64 object_version = 4; + inline bool has_object_version() const; + inline void clear_object_version(); + static const int kObjectVersionFieldNumber = 4; + inline ::google::protobuf::uint64 object_version() const; + inline void set_object_version(::google::protobuf::uint64 value); + + // required fixed32 offset = 5; + inline bool has_offset() const; + inline void clear_offset(); + static const int kOffsetFieldNumber = 5; + inline ::google::protobuf::uint32 offset() const; + inline void set_offset(::google::protobuf::uint32 value); + + // required fixed64 lease_timeout = 6; + inline bool has_lease_timeout() const; + inline void clear_lease_timeout(); + static const int kLeaseTimeoutFieldNumber = 6; + inline ::google::protobuf::uint64 lease_timeout() const; + inline void set_lease_timeout(::google::protobuf::uint64 value); + + // required .xtreemfs.pbrpc.ObjectData object_data = 7; + inline bool has_object_data() const; + inline void clear_object_data(); + static const int kObjectDataFieldNumber = 7; + inline const ::xtreemfs::pbrpc::ObjectData& object_data() const; + inline ::xtreemfs::pbrpc::ObjectData* mutable_object_data(); + inline ::xtreemfs::pbrpc::ObjectData* release_object_data(); + inline void set_allocated_object_data(::xtreemfs::pbrpc::ObjectData* object_data); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.writeRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_object_number(); + inline void clear_has_object_number(); + inline void set_has_object_version(); + inline void clear_has_object_version(); + inline void set_has_offset(); + inline void clear_has_offset(); + inline void set_has_lease_timeout(); + inline void clear_has_lease_timeout(); + inline void set_has_object_data(); + inline void clear_has_object_data(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint64 object_number_; + ::google::protobuf::uint64 object_version_; + ::google::protobuf::uint64 lease_timeout_; + ::xtreemfs::pbrpc::ObjectData* object_data_; + ::google::protobuf::uint32 offset_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static writeRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_broadcast_gmaxRequest : public ::google::protobuf::Message { + public: + xtreemfs_broadcast_gmaxRequest(); + virtual ~xtreemfs_broadcast_gmaxRequest(); + + xtreemfs_broadcast_gmaxRequest(const xtreemfs_broadcast_gmaxRequest& from); + + inline xtreemfs_broadcast_gmaxRequest& operator=(const xtreemfs_broadcast_gmaxRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_broadcast_gmaxRequest& default_instance(); + + void Swap(xtreemfs_broadcast_gmaxRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_broadcast_gmaxRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_broadcast_gmaxRequest& from); + void MergeFrom(const xtreemfs_broadcast_gmaxRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string file_id = 1; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 1; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 truncate_epoch = 2; + inline bool has_truncate_epoch() const; + inline void clear_truncate_epoch(); + static const int kTruncateEpochFieldNumber = 2; + inline ::google::protobuf::uint64 truncate_epoch() const; + inline void set_truncate_epoch(::google::protobuf::uint64 value); + + // required fixed64 last_object = 3; + inline bool has_last_object() const; + inline void clear_last_object(); + static const int kLastObjectFieldNumber = 3; + inline ::google::protobuf::uint64 last_object() const; + inline void set_last_object(::google::protobuf::uint64 value); + + // required fixed64 file_size = 4; + inline bool has_file_size() const; + inline void clear_file_size(); + static const int kFileSizeFieldNumber = 4; + inline ::google::protobuf::uint64 file_size() const; + inline void set_file_size(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_broadcast_gmaxRequest) + private: + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_truncate_epoch(); + inline void clear_has_truncate_epoch(); + inline void set_has_last_object(); + inline void clear_has_last_object(); + inline void set_has_file_size(); + inline void clear_has_file_size(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* file_id_; + ::google::protobuf::uint64 truncate_epoch_; + ::google::protobuf::uint64 last_object_; + ::google::protobuf::uint64 file_size_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_broadcast_gmaxRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_check_objectRequest : public ::google::protobuf::Message { + public: + xtreemfs_check_objectRequest(); + virtual ~xtreemfs_check_objectRequest(); + + xtreemfs_check_objectRequest(const xtreemfs_check_objectRequest& from); + + inline xtreemfs_check_objectRequest& operator=(const xtreemfs_check_objectRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_check_objectRequest& default_instance(); + + void Swap(xtreemfs_check_objectRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_check_objectRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_check_objectRequest& from); + void MergeFrom(const xtreemfs_check_objectRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 object_number = 3; + inline bool has_object_number() const; + inline void clear_object_number(); + static const int kObjectNumberFieldNumber = 3; + inline ::google::protobuf::uint64 object_number() const; + inline void set_object_number(::google::protobuf::uint64 value); + + // required fixed64 object_version = 4; + inline bool has_object_version() const; + inline void clear_object_version(); + static const int kObjectVersionFieldNumber = 4; + inline ::google::protobuf::uint64 object_version() const; + inline void set_object_version(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_check_objectRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_object_number(); + inline void clear_has_object_number(); + inline void set_has_object_version(); + inline void clear_has_object_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint64 object_number_; + ::google::protobuf::uint64 object_version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_check_objectRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_cleanup_get_resultsResponse : public ::google::protobuf::Message { + public: + xtreemfs_cleanup_get_resultsResponse(); + virtual ~xtreemfs_cleanup_get_resultsResponse(); + + xtreemfs_cleanup_get_resultsResponse(const xtreemfs_cleanup_get_resultsResponse& from); + + inline xtreemfs_cleanup_get_resultsResponse& operator=(const xtreemfs_cleanup_get_resultsResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_cleanup_get_resultsResponse& default_instance(); + + void Swap(xtreemfs_cleanup_get_resultsResponse* other); + + // implements Message ---------------------------------------------- + + xtreemfs_cleanup_get_resultsResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_cleanup_get_resultsResponse& from); + void MergeFrom(const xtreemfs_cleanup_get_resultsResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string results = 1; + inline int results_size() const; + inline void clear_results(); + static const int kResultsFieldNumber = 1; + inline const ::std::string& results(int index) const; + inline ::std::string* mutable_results(int index); + inline void set_results(int index, const ::std::string& value); + inline void set_results(int index, const char* value); + inline void set_results(int index, const char* value, size_t size); + inline ::std::string* add_results(); + inline void add_results(const ::std::string& value); + inline void add_results(const char* value); + inline void add_results(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& results() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_results(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_cleanup_get_resultsResponse) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::std::string> results_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_cleanup_get_resultsResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_cleanup_is_runningResponse : public ::google::protobuf::Message { + public: + xtreemfs_cleanup_is_runningResponse(); + virtual ~xtreemfs_cleanup_is_runningResponse(); + + xtreemfs_cleanup_is_runningResponse(const xtreemfs_cleanup_is_runningResponse& from); + + inline xtreemfs_cleanup_is_runningResponse& operator=(const xtreemfs_cleanup_is_runningResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_cleanup_is_runningResponse& default_instance(); + + void Swap(xtreemfs_cleanup_is_runningResponse* other); + + // implements Message ---------------------------------------------- + + xtreemfs_cleanup_is_runningResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_cleanup_is_runningResponse& from); + void MergeFrom(const xtreemfs_cleanup_is_runningResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required bool is_running = 1; + inline bool has_is_running() const; + inline void clear_is_running(); + static const int kIsRunningFieldNumber = 1; + inline bool is_running() const; + inline void set_is_running(bool value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_cleanup_is_runningResponse) + private: + inline void set_has_is_running(); + inline void clear_has_is_running(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + bool is_running_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_cleanup_is_runningResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_cleanup_startRequest : public ::google::protobuf::Message { + public: + xtreemfs_cleanup_startRequest(); + virtual ~xtreemfs_cleanup_startRequest(); + + xtreemfs_cleanup_startRequest(const xtreemfs_cleanup_startRequest& from); + + inline xtreemfs_cleanup_startRequest& operator=(const xtreemfs_cleanup_startRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_cleanup_startRequest& default_instance(); + + void Swap(xtreemfs_cleanup_startRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_cleanup_startRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_cleanup_startRequest& from); + void MergeFrom(const xtreemfs_cleanup_startRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required bool remove_zombies = 1; + inline bool has_remove_zombies() const; + inline void clear_remove_zombies(); + static const int kRemoveZombiesFieldNumber = 1; + inline bool remove_zombies() const; + inline void set_remove_zombies(bool value); + + // required bool remove_unavail_volume = 2; + inline bool has_remove_unavail_volume() const; + inline void clear_remove_unavail_volume(); + static const int kRemoveUnavailVolumeFieldNumber = 2; + inline bool remove_unavail_volume() const; + inline void set_remove_unavail_volume(bool value); + + // required bool lost_and_found = 3; + inline bool has_lost_and_found() const; + inline void clear_lost_and_found(); + static const int kLostAndFoundFieldNumber = 3; + inline bool lost_and_found() const; + inline void set_lost_and_found(bool value); + + // required bool delete_metadata = 4; + inline bool has_delete_metadata() const; + inline void clear_delete_metadata(); + static const int kDeleteMetadataFieldNumber = 4; + inline bool delete_metadata() const; + inline void set_delete_metadata(bool value); + + // required fixed32 metadata_timeout = 5; + inline bool has_metadata_timeout() const; + inline void clear_metadata_timeout(); + static const int kMetadataTimeoutFieldNumber = 5; + inline ::google::protobuf::uint32 metadata_timeout() const; + inline void set_metadata_timeout(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_cleanup_startRequest) + private: + inline void set_has_remove_zombies(); + inline void clear_has_remove_zombies(); + inline void set_has_remove_unavail_volume(); + inline void clear_has_remove_unavail_volume(); + inline void set_has_lost_and_found(); + inline void clear_has_lost_and_found(); + inline void set_has_delete_metadata(); + inline void clear_has_delete_metadata(); + inline void set_has_metadata_timeout(); + inline void clear_has_metadata_timeout(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + bool remove_zombies_; + bool remove_unavail_volume_; + bool lost_and_found_; + bool delete_metadata_; + ::google::protobuf::uint32 metadata_timeout_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_cleanup_startRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_cleanup_statusResponse : public ::google::protobuf::Message { + public: + xtreemfs_cleanup_statusResponse(); + virtual ~xtreemfs_cleanup_statusResponse(); + + xtreemfs_cleanup_statusResponse(const xtreemfs_cleanup_statusResponse& from); + + inline xtreemfs_cleanup_statusResponse& operator=(const xtreemfs_cleanup_statusResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_cleanup_statusResponse& default_instance(); + + void Swap(xtreemfs_cleanup_statusResponse* other); + + // implements Message ---------------------------------------------- + + xtreemfs_cleanup_statusResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_cleanup_statusResponse& from); + void MergeFrom(const xtreemfs_cleanup_statusResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::std::string& status() const; + inline void set_status(const ::std::string& value); + inline void set_status(const char* value); + inline void set_status(const char* value, size_t size); + inline ::std::string* mutable_status(); + inline ::std::string* release_status(); + inline void set_allocated_status(::std::string* status); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_cleanup_statusResponse) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* status_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_cleanup_statusResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_rwr_fetchRequest : public ::google::protobuf::Message { + public: + xtreemfs_rwr_fetchRequest(); + virtual ~xtreemfs_rwr_fetchRequest(); + + xtreemfs_rwr_fetchRequest(const xtreemfs_rwr_fetchRequest& from); + + inline xtreemfs_rwr_fetchRequest& operator=(const xtreemfs_rwr_fetchRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_rwr_fetchRequest& default_instance(); + + void Swap(xtreemfs_rwr_fetchRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_rwr_fetchRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_rwr_fetchRequest& from); + void MergeFrom(const xtreemfs_rwr_fetchRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 object_number = 3; + inline bool has_object_number() const; + inline void clear_object_number(); + static const int kObjectNumberFieldNumber = 3; + inline ::google::protobuf::uint64 object_number() const; + inline void set_object_number(::google::protobuf::uint64 value); + + // required fixed64 object_version = 4; + inline bool has_object_version() const; + inline void clear_object_version(); + static const int kObjectVersionFieldNumber = 4; + inline ::google::protobuf::uint64 object_version() const; + inline void set_object_version(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_fetchRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_object_number(); + inline void clear_has_object_number(); + inline void set_has_object_version(); + inline void clear_has_object_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint64 object_number_; + ::google::protobuf::uint64 object_version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_rwr_fetchRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_repair_objectRequest : public ::google::protobuf::Message { + public: + xtreemfs_repair_objectRequest(); + virtual ~xtreemfs_repair_objectRequest(); + + xtreemfs_repair_objectRequest(const xtreemfs_repair_objectRequest& from); + + inline xtreemfs_repair_objectRequest& operator=(const xtreemfs_repair_objectRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_repair_objectRequest& default_instance(); + + void Swap(xtreemfs_repair_objectRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_repair_objectRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_repair_objectRequest& from); + void MergeFrom(const xtreemfs_repair_objectRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 object_number = 3; + inline bool has_object_number() const; + inline void clear_object_number(); + static const int kObjectNumberFieldNumber = 3; + inline ::google::protobuf::uint64 object_number() const; + inline void set_object_number(::google::protobuf::uint64 value); + + // required fixed64 object_version = 4; + inline bool has_object_version() const; + inline void clear_object_version(); + static const int kObjectVersionFieldNumber = 4; + inline ::google::protobuf::uint64 object_version() const; + inline void set_object_version(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_repair_objectRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_object_number(); + inline void clear_has_object_number(); + inline void set_has_object_version(); + inline void clear_has_object_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint64 object_number_; + ::google::protobuf::uint64 object_version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_repair_objectRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_rwr_flease_msgRequest : public ::google::protobuf::Message { + public: + xtreemfs_rwr_flease_msgRequest(); + virtual ~xtreemfs_rwr_flease_msgRequest(); + + xtreemfs_rwr_flease_msgRequest(const xtreemfs_rwr_flease_msgRequest& from); + + inline xtreemfs_rwr_flease_msgRequest& operator=(const xtreemfs_rwr_flease_msgRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_rwr_flease_msgRequest& default_instance(); + + void Swap(xtreemfs_rwr_flease_msgRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_rwr_flease_msgRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_rwr_flease_msgRequest& from); + void MergeFrom(const xtreemfs_rwr_flease_msgRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string sender_hostname = 1; + inline bool has_sender_hostname() const; + inline void clear_sender_hostname(); + static const int kSenderHostnameFieldNumber = 1; + inline const ::std::string& sender_hostname() const; + inline void set_sender_hostname(const ::std::string& value); + inline void set_sender_hostname(const char* value); + inline void set_sender_hostname(const char* value, size_t size); + inline ::std::string* mutable_sender_hostname(); + inline ::std::string* release_sender_hostname(); + inline void set_allocated_sender_hostname(::std::string* sender_hostname); + + // required fixed32 sender_port = 2; + inline bool has_sender_port() const; + inline void clear_sender_port(); + static const int kSenderPortFieldNumber = 2; + inline ::google::protobuf::uint32 sender_port() const; + inline void set_sender_port(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_flease_msgRequest) + private: + inline void set_has_sender_hostname(); + inline void clear_has_sender_hostname(); + inline void set_has_sender_port(); + inline void clear_has_sender_port(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* sender_hostname_; + ::google::protobuf::uint32 sender_port_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_rwr_flease_msgRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_rwr_set_primary_epochRequest : public ::google::protobuf::Message { + public: + xtreemfs_rwr_set_primary_epochRequest(); + virtual ~xtreemfs_rwr_set_primary_epochRequest(); + + xtreemfs_rwr_set_primary_epochRequest(const xtreemfs_rwr_set_primary_epochRequest& from); + + inline xtreemfs_rwr_set_primary_epochRequest& operator=(const xtreemfs_rwr_set_primary_epochRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_rwr_set_primary_epochRequest& default_instance(); + + void Swap(xtreemfs_rwr_set_primary_epochRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_rwr_set_primary_epochRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_rwr_set_primary_epochRequest& from); + void MergeFrom(const xtreemfs_rwr_set_primary_epochRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed32 primary_epoch = 3; + inline bool has_primary_epoch() const; + inline void clear_primary_epoch(); + static const int kPrimaryEpochFieldNumber = 3; + inline ::google::protobuf::uint32 primary_epoch() const; + inline void set_primary_epoch(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_set_primary_epochRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_primary_epoch(); + inline void clear_has_primary_epoch(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint32 primary_epoch_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_rwr_set_primary_epochRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_rwr_statusRequest : public ::google::protobuf::Message { + public: + xtreemfs_rwr_statusRequest(); + virtual ~xtreemfs_rwr_statusRequest(); + + xtreemfs_rwr_statusRequest(const xtreemfs_rwr_statusRequest& from); + + inline xtreemfs_rwr_statusRequest& operator=(const xtreemfs_rwr_statusRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_rwr_statusRequest& default_instance(); + + void Swap(xtreemfs_rwr_statusRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_rwr_statusRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_rwr_statusRequest& from); + void MergeFrom(const xtreemfs_rwr_statusRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 max_local_obj_version = 3; + inline bool has_max_local_obj_version() const; + inline void clear_max_local_obj_version(); + static const int kMaxLocalObjVersionFieldNumber = 3; + inline ::google::protobuf::uint64 max_local_obj_version() const; + inline void set_max_local_obj_version(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_statusRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_max_local_obj_version(); + inline void clear_has_max_local_obj_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint64 max_local_obj_version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_rwr_statusRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_rwr_truncateRequest : public ::google::protobuf::Message { + public: + xtreemfs_rwr_truncateRequest(); + virtual ~xtreemfs_rwr_truncateRequest(); + + xtreemfs_rwr_truncateRequest(const xtreemfs_rwr_truncateRequest& from); + + inline xtreemfs_rwr_truncateRequest& operator=(const xtreemfs_rwr_truncateRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_rwr_truncateRequest& default_instance(); + + void Swap(xtreemfs_rwr_truncateRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_rwr_truncateRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_rwr_truncateRequest& from); + void MergeFrom(const xtreemfs_rwr_truncateRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 new_file_size = 3; + inline bool has_new_file_size() const; + inline void clear_new_file_size(); + static const int kNewFileSizeFieldNumber = 3; + inline ::google::protobuf::uint64 new_file_size() const; + inline void set_new_file_size(::google::protobuf::uint64 value); + + // required fixed64 object_version = 4; + inline bool has_object_version() const; + inline void clear_object_version(); + static const int kObjectVersionFieldNumber = 4; + inline ::google::protobuf::uint64 object_version() const; + inline void set_object_version(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_truncateRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_new_file_size(); + inline void clear_has_new_file_size(); + inline void set_has_object_version(); + inline void clear_has_object_version(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint64 new_file_size_; + ::google::protobuf::uint64 object_version_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_rwr_truncateRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_rwr_updateRequest : public ::google::protobuf::Message { + public: + xtreemfs_rwr_updateRequest(); + virtual ~xtreemfs_rwr_updateRequest(); + + xtreemfs_rwr_updateRequest(const xtreemfs_rwr_updateRequest& from); + + inline xtreemfs_rwr_updateRequest& operator=(const xtreemfs_rwr_updateRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_rwr_updateRequest& default_instance(); + + void Swap(xtreemfs_rwr_updateRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_rwr_updateRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_rwr_updateRequest& from); + void MergeFrom(const xtreemfs_rwr_updateRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 new_file_size = 3; + inline bool has_new_file_size() const; + inline void clear_new_file_size(); + static const int kNewFileSizeFieldNumber = 3; + inline ::google::protobuf::uint64 new_file_size() const; + inline void set_new_file_size(::google::protobuf::uint64 value); + + // required fixed64 object_number = 7; + inline bool has_object_number() const; + inline void clear_object_number(); + static const int kObjectNumberFieldNumber = 7; + inline ::google::protobuf::uint64 object_number() const; + inline void set_object_number(::google::protobuf::uint64 value); + + // required fixed64 object_version = 4; + inline bool has_object_version() const; + inline void clear_object_version(); + static const int kObjectVersionFieldNumber = 4; + inline ::google::protobuf::uint64 object_version() const; + inline void set_object_version(::google::protobuf::uint64 value); + + // required fixed32 offset = 5; + inline bool has_offset() const; + inline void clear_offset(); + static const int kOffsetFieldNumber = 5; + inline ::google::protobuf::uint32 offset() const; + inline void set_offset(::google::protobuf::uint32 value); + + // required .xtreemfs.pbrpc.ObjectData obj = 6; + inline bool has_obj() const; + inline void clear_obj(); + static const int kObjFieldNumber = 6; + inline const ::xtreemfs::pbrpc::ObjectData& obj() const; + inline ::xtreemfs::pbrpc::ObjectData* mutable_obj(); + inline ::xtreemfs::pbrpc::ObjectData* release_obj(); + inline void set_allocated_obj(::xtreemfs::pbrpc::ObjectData* obj); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_updateRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_new_file_size(); + inline void clear_has_new_file_size(); + inline void set_has_object_number(); + inline void clear_has_object_number(); + inline void set_has_object_version(); + inline void clear_has_object_version(); + inline void set_has_offset(); + inline void clear_has_offset(); + inline void set_has_obj(); + inline void clear_has_obj(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint64 new_file_size_; + ::google::protobuf::uint64 object_number_; + ::google::protobuf::uint64 object_version_; + ::xtreemfs::pbrpc::ObjectData* obj_; + ::google::protobuf::uint32 offset_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_rwr_updateRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_internal_get_gmaxRequest : public ::google::protobuf::Message { + public: + xtreemfs_internal_get_gmaxRequest(); + virtual ~xtreemfs_internal_get_gmaxRequest(); + + xtreemfs_internal_get_gmaxRequest(const xtreemfs_internal_get_gmaxRequest& from); + + inline xtreemfs_internal_get_gmaxRequest& operator=(const xtreemfs_internal_get_gmaxRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_internal_get_gmaxRequest& default_instance(); + + void Swap(xtreemfs_internal_get_gmaxRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_internal_get_gmaxRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_internal_get_gmaxRequest& from); + void MergeFrom(const xtreemfs_internal_get_gmaxRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_get_gmaxRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_internal_get_gmaxRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_internal_get_file_sizeRequest : public ::google::protobuf::Message { + public: + xtreemfs_internal_get_file_sizeRequest(); + virtual ~xtreemfs_internal_get_file_sizeRequest(); + + xtreemfs_internal_get_file_sizeRequest(const xtreemfs_internal_get_file_sizeRequest& from); + + inline xtreemfs_internal_get_file_sizeRequest& operator=(const xtreemfs_internal_get_file_sizeRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_internal_get_file_sizeRequest& default_instance(); + + void Swap(xtreemfs_internal_get_file_sizeRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_internal_get_file_sizeRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_internal_get_file_sizeRequest& from); + void MergeFrom(const xtreemfs_internal_get_file_sizeRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_get_file_sizeRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_internal_get_file_sizeRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_internal_get_file_sizeResponse : public ::google::protobuf::Message { + public: + xtreemfs_internal_get_file_sizeResponse(); + virtual ~xtreemfs_internal_get_file_sizeResponse(); + + xtreemfs_internal_get_file_sizeResponse(const xtreemfs_internal_get_file_sizeResponse& from); + + inline xtreemfs_internal_get_file_sizeResponse& operator=(const xtreemfs_internal_get_file_sizeResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_internal_get_file_sizeResponse& default_instance(); + + void Swap(xtreemfs_internal_get_file_sizeResponse* other); + + // implements Message ---------------------------------------------- + + xtreemfs_internal_get_file_sizeResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_internal_get_file_sizeResponse& from); + void MergeFrom(const xtreemfs_internal_get_file_sizeResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required fixed64 file_size = 1; + inline bool has_file_size() const; + inline void clear_file_size(); + static const int kFileSizeFieldNumber = 1; + inline ::google::protobuf::uint64 file_size() const; + inline void set_file_size(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_get_file_sizeResponse) + private: + inline void set_has_file_size(); + inline void clear_has_file_size(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint64 file_size_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_internal_get_file_sizeResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_internal_read_localRequest : public ::google::protobuf::Message { + public: + xtreemfs_internal_read_localRequest(); + virtual ~xtreemfs_internal_read_localRequest(); + + xtreemfs_internal_read_localRequest(const xtreemfs_internal_read_localRequest& from); + + inline xtreemfs_internal_read_localRequest& operator=(const xtreemfs_internal_read_localRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_internal_read_localRequest& default_instance(); + + void Swap(xtreemfs_internal_read_localRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_internal_read_localRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_internal_read_localRequest& from); + void MergeFrom(const xtreemfs_internal_read_localRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed64 object_number = 3; + inline bool has_object_number() const; + inline void clear_object_number(); + static const int kObjectNumberFieldNumber = 3; + inline ::google::protobuf::uint64 object_number() const; + inline void set_object_number(::google::protobuf::uint64 value); + + // required fixed64 object_version = 4; + inline bool has_object_version() const; + inline void clear_object_version(); + static const int kObjectVersionFieldNumber = 4; + inline ::google::protobuf::uint64 object_version() const; + inline void set_object_version(::google::protobuf::uint64 value); + + // required fixed32 offset = 5; + inline bool has_offset() const; + inline void clear_offset(); + static const int kOffsetFieldNumber = 5; + inline ::google::protobuf::uint32 offset() const; + inline void set_offset(::google::protobuf::uint32 value); + + // required fixed32 length = 6; + inline bool has_length() const; + inline void clear_length(); + static const int kLengthFieldNumber = 6; + inline ::google::protobuf::uint32 length() const; + inline void set_length(::google::protobuf::uint32 value); + + // required bool attach_object_list = 7; + inline bool has_attach_object_list() const; + inline void clear_attach_object_list(); + static const int kAttachObjectListFieldNumber = 7; + inline bool attach_object_list() const; + inline void set_attach_object_list(bool value); + + // repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + inline int required_objects_size() const; + inline void clear_required_objects(); + static const int kRequiredObjectsFieldNumber = 8; + inline const ::xtreemfs::pbrpc::ObjectList& required_objects(int index) const; + inline ::xtreemfs::pbrpc::ObjectList* mutable_required_objects(int index); + inline ::xtreemfs::pbrpc::ObjectList* add_required_objects(); + inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectList >& + required_objects() const; + inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectList >* + mutable_required_objects(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_read_localRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_object_number(); + inline void clear_has_object_number(); + inline void set_has_object_version(); + inline void clear_has_object_version(); + inline void set_has_offset(); + inline void clear_has_offset(); + inline void set_has_length(); + inline void clear_has_length(); + inline void set_has_attach_object_list(); + inline void clear_has_attach_object_list(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint64 object_number_; + ::google::protobuf::uint64 object_version_; + ::google::protobuf::uint32 offset_; + ::google::protobuf::uint32 length_; + ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectList > required_objects_; + bool attach_object_list_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_internal_read_localRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_internal_get_object_setRequest : public ::google::protobuf::Message { + public: + xtreemfs_internal_get_object_setRequest(); + virtual ~xtreemfs_internal_get_object_setRequest(); + + xtreemfs_internal_get_object_setRequest(const xtreemfs_internal_get_object_setRequest& from); + + inline xtreemfs_internal_get_object_setRequest& operator=(const xtreemfs_internal_get_object_setRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_internal_get_object_setRequest& default_instance(); + + void Swap(xtreemfs_internal_get_object_setRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_internal_get_object_setRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_internal_get_object_setRequest& from); + void MergeFrom(const xtreemfs_internal_get_object_setRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_get_object_setRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_internal_get_object_setRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_internal_get_fileid_listResponse : public ::google::protobuf::Message { + public: + xtreemfs_internal_get_fileid_listResponse(); + virtual ~xtreemfs_internal_get_fileid_listResponse(); + + xtreemfs_internal_get_fileid_listResponse(const xtreemfs_internal_get_fileid_listResponse& from); + + inline xtreemfs_internal_get_fileid_listResponse& operator=(const xtreemfs_internal_get_fileid_listResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_internal_get_fileid_listResponse& default_instance(); + + void Swap(xtreemfs_internal_get_fileid_listResponse* other); + + // implements Message ---------------------------------------------- + + xtreemfs_internal_get_fileid_listResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_internal_get_fileid_listResponse& from); + void MergeFrom(const xtreemfs_internal_get_fileid_listResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string file_ids = 1; + inline int file_ids_size() const; + inline void clear_file_ids(); + static const int kFileIdsFieldNumber = 1; + inline const ::std::string& file_ids(int index) const; + inline ::std::string* mutable_file_ids(int index); + inline void set_file_ids(int index, const ::std::string& value); + inline void set_file_ids(int index, const char* value); + inline void set_file_ids(int index, const char* value, size_t size); + inline ::std::string* add_file_ids(); + inline void add_file_ids(const ::std::string& value); + inline void add_file_ids(const char* value); + inline void add_file_ids(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& file_ids() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_ids(); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_get_fileid_listResponse) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::std::string> file_ids_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_internal_get_fileid_listResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class lockRequest : public ::google::protobuf::Message { + public: + lockRequest(); + virtual ~lockRequest(); + + lockRequest(const lockRequest& from); + + inline lockRequest& operator=(const lockRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const lockRequest& default_instance(); + + void Swap(lockRequest* other); + + // implements Message ---------------------------------------------- + + lockRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const lockRequest& from); + void MergeFrom(const lockRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required .xtreemfs.pbrpc.Lock lock_request = 2; + inline bool has_lock_request() const; + inline void clear_lock_request(); + static const int kLockRequestFieldNumber = 2; + inline const ::xtreemfs::pbrpc::Lock& lock_request() const; + inline ::xtreemfs::pbrpc::Lock* mutable_lock_request(); + inline ::xtreemfs::pbrpc::Lock* release_lock_request(); + inline void set_allocated_lock_request(::xtreemfs::pbrpc::Lock* lock_request); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.lockRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_lock_request(); + inline void clear_has_lock_request(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::xtreemfs::pbrpc::Lock* lock_request_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static lockRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_pingMesssage : public ::google::protobuf::Message { + public: + xtreemfs_pingMesssage(); + virtual ~xtreemfs_pingMesssage(); + + xtreemfs_pingMesssage(const xtreemfs_pingMesssage& from); + + inline xtreemfs_pingMesssage& operator=(const xtreemfs_pingMesssage& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_pingMesssage& default_instance(); + + void Swap(xtreemfs_pingMesssage* other); + + // implements Message ---------------------------------------------- + + xtreemfs_pingMesssage* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_pingMesssage& from); + void MergeFrom(const xtreemfs_pingMesssage& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + inline bool has_coordinates() const; + inline void clear_coordinates(); + static const int kCoordinatesFieldNumber = 1; + inline const ::xtreemfs::pbrpc::VivaldiCoordinates& coordinates() const; + inline ::xtreemfs::pbrpc::VivaldiCoordinates* mutable_coordinates(); + inline ::xtreemfs::pbrpc::VivaldiCoordinates* release_coordinates(); + inline void set_allocated_coordinates(::xtreemfs::pbrpc::VivaldiCoordinates* coordinates); + + // required bool request_response = 2; + inline bool has_request_response() const; + inline void clear_request_response(); + static const int kRequestResponseFieldNumber = 2; + inline bool request_response() const; + inline void set_request_response(bool value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_pingMesssage) + private: + inline void set_has_coordinates(); + inline void clear_has_coordinates(); + inline void set_has_request_response(); + inline void clear_has_request_response(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::VivaldiCoordinates* coordinates_; + bool request_response_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_pingMesssage* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_rwr_auth_stateRequest : public ::google::protobuf::Message { + public: + xtreemfs_rwr_auth_stateRequest(); + virtual ~xtreemfs_rwr_auth_stateRequest(); + + xtreemfs_rwr_auth_stateRequest(const xtreemfs_rwr_auth_stateRequest& from); + + inline xtreemfs_rwr_auth_stateRequest& operator=(const xtreemfs_rwr_auth_stateRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_rwr_auth_stateRequest& default_instance(); + + void Swap(xtreemfs_rwr_auth_stateRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_rwr_auth_stateRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_rwr_auth_stateRequest& from); + void MergeFrom(const xtreemfs_rwr_auth_stateRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + inline bool has_state() const; + inline void clear_state(); + static const int kStateFieldNumber = 3; + inline const ::xtreemfs::pbrpc::AuthoritativeReplicaState& state() const; + inline ::xtreemfs::pbrpc::AuthoritativeReplicaState* mutable_state(); + inline ::xtreemfs::pbrpc::AuthoritativeReplicaState* release_state(); + inline void set_allocated_state(::xtreemfs::pbrpc::AuthoritativeReplicaState* state); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_auth_stateRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_state(); + inline void clear_has_state(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::xtreemfs::pbrpc::AuthoritativeReplicaState* state_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_rwr_auth_stateRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_rwr_reset_completeRequest : public ::google::protobuf::Message { + public: + xtreemfs_rwr_reset_completeRequest(); + virtual ~xtreemfs_rwr_reset_completeRequest(); + + xtreemfs_rwr_reset_completeRequest(const xtreemfs_rwr_reset_completeRequest& from); + + inline xtreemfs_rwr_reset_completeRequest& operator=(const xtreemfs_rwr_reset_completeRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_rwr_reset_completeRequest& default_instance(); + + void Swap(xtreemfs_rwr_reset_completeRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_rwr_reset_completeRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_rwr_reset_completeRequest& from); + void MergeFrom(const xtreemfs_rwr_reset_completeRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // required fixed32 primary_epoch = 3; + inline bool has_primary_epoch() const; + inline void clear_primary_epoch(); + static const int kPrimaryEpochFieldNumber = 3; + inline ::google::protobuf::uint32 primary_epoch() const; + inline void set_primary_epoch(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_reset_completeRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + inline void set_has_primary_epoch(); + inline void clear_has_primary_epoch(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + ::google::protobuf::uint32 primary_epoch_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_rwr_reset_completeRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_xloc_set_invalidateRequest : public ::google::protobuf::Message { + public: + xtreemfs_xloc_set_invalidateRequest(); + virtual ~xtreemfs_xloc_set_invalidateRequest(); + + xtreemfs_xloc_set_invalidateRequest(const xtreemfs_xloc_set_invalidateRequest& from); + + inline xtreemfs_xloc_set_invalidateRequest& operator=(const xtreemfs_xloc_set_invalidateRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_xloc_set_invalidateRequest& default_instance(); + + void Swap(xtreemfs_xloc_set_invalidateRequest* other); + + // implements Message ---------------------------------------------- + + xtreemfs_xloc_set_invalidateRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_xloc_set_invalidateRequest& from); + void MergeFrom(const xtreemfs_xloc_set_invalidateRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + inline bool has_file_credentials() const; + inline void clear_file_credentials(); + static const int kFileCredentialsFieldNumber = 1; + inline const ::xtreemfs::pbrpc::FileCredentials& file_credentials() const; + inline ::xtreemfs::pbrpc::FileCredentials* mutable_file_credentials(); + inline ::xtreemfs::pbrpc::FileCredentials* release_file_credentials(); + inline void set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials); + + // required string file_id = 2; + inline bool has_file_id() const; + inline void clear_file_id(); + static const int kFileIdFieldNumber = 2; + inline const ::std::string& file_id() const; + inline void set_file_id(const ::std::string& value); + inline void set_file_id(const char* value); + inline void set_file_id(const char* value, size_t size); + inline ::std::string* mutable_file_id(); + inline ::std::string* release_file_id(); + inline void set_allocated_file_id(::std::string* file_id); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_xloc_set_invalidateRequest) + private: + inline void set_has_file_credentials(); + inline void clear_has_file_credentials(); + inline void set_has_file_id(); + inline void clear_has_file_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::FileCredentials* file_credentials_; + ::std::string* file_id_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_xloc_set_invalidateRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class xtreemfs_xloc_set_invalidateResponse : public ::google::protobuf::Message { + public: + xtreemfs_xloc_set_invalidateResponse(); + virtual ~xtreemfs_xloc_set_invalidateResponse(); + + xtreemfs_xloc_set_invalidateResponse(const xtreemfs_xloc_set_invalidateResponse& from); + + inline xtreemfs_xloc_set_invalidateResponse& operator=(const xtreemfs_xloc_set_invalidateResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const xtreemfs_xloc_set_invalidateResponse& default_instance(); + + void Swap(xtreemfs_xloc_set_invalidateResponse* other); + + // implements Message ---------------------------------------------- + + xtreemfs_xloc_set_invalidateResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const xtreemfs_xloc_set_invalidateResponse& from); + void MergeFrom(const xtreemfs_xloc_set_invalidateResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .xtreemfs.pbrpc.LeaseState lease_state = 1; + inline bool has_lease_state() const; + inline void clear_lease_state(); + static const int kLeaseStateFieldNumber = 1; + inline ::xtreemfs::pbrpc::LeaseState lease_state() const; + inline void set_lease_state(::xtreemfs::pbrpc::LeaseState value); + + // optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + inline bool has_replica_status() const; + inline void clear_replica_status(); + static const int kReplicaStatusFieldNumber = 2; + inline const ::xtreemfs::pbrpc::ReplicaStatus& replica_status() const; + inline ::xtreemfs::pbrpc::ReplicaStatus* mutable_replica_status(); + inline ::xtreemfs::pbrpc::ReplicaStatus* release_replica_status(); + inline void set_allocated_replica_status(::xtreemfs::pbrpc::ReplicaStatus* replica_status); + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_xloc_set_invalidateResponse) + private: + inline void set_has_lease_state(); + inline void clear_has_lease_state(); + inline void set_has_replica_status(); + inline void clear_has_replica_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::xtreemfs::pbrpc::ReplicaStatus* replica_status_; + int lease_state_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_AssignDesc_xtreemfs_2fOSD_2eproto(); + friend void protobuf_ShutdownFile_xtreemfs_2fOSD_2eproto(); + + void InitAsDefaultInstance(); + static xtreemfs_xloc_set_invalidateResponse* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// InternalGmax + +// required fixed64 epoch = 1; +inline bool InternalGmax::has_epoch() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void InternalGmax::set_has_epoch() { + _has_bits_[0] |= 0x00000001u; +} +inline void InternalGmax::clear_has_epoch() { + _has_bits_[0] &= ~0x00000001u; +} +inline void InternalGmax::clear_epoch() { + epoch_ = GOOGLE_ULONGLONG(0); + clear_has_epoch(); +} +inline ::google::protobuf::uint64 InternalGmax::epoch() const { + return epoch_; +} +inline void InternalGmax::set_epoch(::google::protobuf::uint64 value) { + set_has_epoch(); + epoch_ = value; +} + +// required fixed64 file_size = 2; +inline bool InternalGmax::has_file_size() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void InternalGmax::set_has_file_size() { + _has_bits_[0] |= 0x00000002u; +} +inline void InternalGmax::clear_has_file_size() { + _has_bits_[0] &= ~0x00000002u; +} +inline void InternalGmax::clear_file_size() { + file_size_ = GOOGLE_ULONGLONG(0); + clear_has_file_size(); +} +inline ::google::protobuf::uint64 InternalGmax::file_size() const { + return file_size_; +} +inline void InternalGmax::set_file_size(::google::protobuf::uint64 value) { + set_has_file_size(); + file_size_ = value; +} + +// required fixed64 last_object_id = 3; +inline bool InternalGmax::has_last_object_id() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void InternalGmax::set_has_last_object_id() { + _has_bits_[0] |= 0x00000004u; +} +inline void InternalGmax::clear_has_last_object_id() { + _has_bits_[0] &= ~0x00000004u; +} +inline void InternalGmax::clear_last_object_id() { + last_object_id_ = GOOGLE_ULONGLONG(0); + clear_has_last_object_id(); +} +inline ::google::protobuf::uint64 InternalGmax::last_object_id() const { + return last_object_id_; +} +inline void InternalGmax::set_last_object_id(::google::protobuf::uint64 value) { + set_has_last_object_id(); + last_object_id_ = value; +} + +// ------------------------------------------------------------------- + +// Lock + +// required fixed32 client_pid = 1; +inline bool Lock::has_client_pid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Lock::set_has_client_pid() { + _has_bits_[0] |= 0x00000001u; +} +inline void Lock::clear_has_client_pid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Lock::clear_client_pid() { + client_pid_ = 0u; + clear_has_client_pid(); +} +inline ::google::protobuf::uint32 Lock::client_pid() const { + return client_pid_; +} +inline void Lock::set_client_pid(::google::protobuf::uint32 value) { + set_has_client_pid(); + client_pid_ = value; +} + +// required string client_uuid = 2; +inline bool Lock::has_client_uuid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Lock::set_has_client_uuid() { + _has_bits_[0] |= 0x00000002u; +} +inline void Lock::clear_has_client_uuid() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Lock::clear_client_uuid() { + if (client_uuid_ != &::google::protobuf::internal::kEmptyString) { + client_uuid_->clear(); + } + clear_has_client_uuid(); +} +inline const ::std::string& Lock::client_uuid() const { + return *client_uuid_; +} +inline void Lock::set_client_uuid(const ::std::string& value) { + set_has_client_uuid(); + if (client_uuid_ == &::google::protobuf::internal::kEmptyString) { + client_uuid_ = new ::std::string; + } + client_uuid_->assign(value); +} +inline void Lock::set_client_uuid(const char* value) { + set_has_client_uuid(); + if (client_uuid_ == &::google::protobuf::internal::kEmptyString) { + client_uuid_ = new ::std::string; + } + client_uuid_->assign(value); +} +inline void Lock::set_client_uuid(const char* value, size_t size) { + set_has_client_uuid(); + if (client_uuid_ == &::google::protobuf::internal::kEmptyString) { + client_uuid_ = new ::std::string; + } + client_uuid_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Lock::mutable_client_uuid() { + set_has_client_uuid(); + if (client_uuid_ == &::google::protobuf::internal::kEmptyString) { + client_uuid_ = new ::std::string; + } + return client_uuid_; +} +inline ::std::string* Lock::release_client_uuid() { + clear_has_client_uuid(); + if (client_uuid_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = client_uuid_; + client_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void Lock::set_allocated_client_uuid(::std::string* client_uuid) { + if (client_uuid_ != &::google::protobuf::internal::kEmptyString) { + delete client_uuid_; + } + if (client_uuid) { + set_has_client_uuid(); + client_uuid_ = client_uuid; + } else { + clear_has_client_uuid(); + client_uuid_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 length = 3; +inline bool Lock::has_length() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Lock::set_has_length() { + _has_bits_[0] |= 0x00000004u; +} +inline void Lock::clear_has_length() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Lock::clear_length() { + length_ = GOOGLE_ULONGLONG(0); + clear_has_length(); +} +inline ::google::protobuf::uint64 Lock::length() const { + return length_; +} +inline void Lock::set_length(::google::protobuf::uint64 value) { + set_has_length(); + length_ = value; +} + +// required fixed64 offset = 4; +inline bool Lock::has_offset() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void Lock::set_has_offset() { + _has_bits_[0] |= 0x00000008u; +} +inline void Lock::clear_has_offset() { + _has_bits_[0] &= ~0x00000008u; +} +inline void Lock::clear_offset() { + offset_ = GOOGLE_ULONGLONG(0); + clear_has_offset(); +} +inline ::google::protobuf::uint64 Lock::offset() const { + return offset_; +} +inline void Lock::set_offset(::google::protobuf::uint64 value) { + set_has_offset(); + offset_ = value; +} + +// required bool exclusive = 5; +inline bool Lock::has_exclusive() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void Lock::set_has_exclusive() { + _has_bits_[0] |= 0x00000010u; +} +inline void Lock::clear_has_exclusive() { + _has_bits_[0] &= ~0x00000010u; +} +inline void Lock::clear_exclusive() { + exclusive_ = false; + clear_has_exclusive(); +} +inline bool Lock::exclusive() const { + return exclusive_; +} +inline void Lock::set_exclusive(bool value) { + set_has_exclusive(); + exclusive_ = value; +} + +// ------------------------------------------------------------------- + +// ObjectData + +// required fixed32 checksum = 1; +inline bool ObjectData::has_checksum() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ObjectData::set_has_checksum() { + _has_bits_[0] |= 0x00000001u; +} +inline void ObjectData::clear_has_checksum() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ObjectData::clear_checksum() { + checksum_ = 0u; + clear_has_checksum(); +} +inline ::google::protobuf::uint32 ObjectData::checksum() const { + return checksum_; +} +inline void ObjectData::set_checksum(::google::protobuf::uint32 value) { + set_has_checksum(); + checksum_ = value; +} + +// required bool invalid_checksum_on_osd = 2; +inline bool ObjectData::has_invalid_checksum_on_osd() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ObjectData::set_has_invalid_checksum_on_osd() { + _has_bits_[0] |= 0x00000002u; +} +inline void ObjectData::clear_has_invalid_checksum_on_osd() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ObjectData::clear_invalid_checksum_on_osd() { + invalid_checksum_on_osd_ = false; + clear_has_invalid_checksum_on_osd(); +} +inline bool ObjectData::invalid_checksum_on_osd() const { + return invalid_checksum_on_osd_; +} +inline void ObjectData::set_invalid_checksum_on_osd(bool value) { + set_has_invalid_checksum_on_osd(); + invalid_checksum_on_osd_ = value; +} + +// required fixed32 zero_padding = 3; +inline bool ObjectData::has_zero_padding() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ObjectData::set_has_zero_padding() { + _has_bits_[0] |= 0x00000004u; +} +inline void ObjectData::clear_has_zero_padding() { + _has_bits_[0] &= ~0x00000004u; +} +inline void ObjectData::clear_zero_padding() { + zero_padding_ = 0u; + clear_has_zero_padding(); +} +inline ::google::protobuf::uint32 ObjectData::zero_padding() const { + return zero_padding_; +} +inline void ObjectData::set_zero_padding(::google::protobuf::uint32 value) { + set_has_zero_padding(); + zero_padding_ = value; +} + +// ------------------------------------------------------------------- + +// ObjectList + +// required bytes set = 1; +inline bool ObjectList::has_set() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ObjectList::set_has_set() { + _has_bits_[0] |= 0x00000001u; +} +inline void ObjectList::clear_has_set() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ObjectList::clear_set() { + if (set_ != &::google::protobuf::internal::kEmptyString) { + set_->clear(); + } + clear_has_set(); +} +inline const ::std::string& ObjectList::set() const { + return *set_; +} +inline void ObjectList::set_set(const ::std::string& value) { + set_has_set(); + if (set_ == &::google::protobuf::internal::kEmptyString) { + set_ = new ::std::string; + } + set_->assign(value); +} +inline void ObjectList::set_set(const char* value) { + set_has_set(); + if (set_ == &::google::protobuf::internal::kEmptyString) { + set_ = new ::std::string; + } + set_->assign(value); +} +inline void ObjectList::set_set(const void* value, size_t size) { + set_has_set(); + if (set_ == &::google::protobuf::internal::kEmptyString) { + set_ = new ::std::string; + } + set_->assign(reinterpret_cast(value), size); +} +inline ::std::string* ObjectList::mutable_set() { + set_has_set(); + if (set_ == &::google::protobuf::internal::kEmptyString) { + set_ = new ::std::string; + } + return set_; +} +inline ::std::string* ObjectList::release_set() { + clear_has_set(); + if (set_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = set_; + set_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void ObjectList::set_allocated_set(::std::string* set) { + if (set_ != &::google::protobuf::internal::kEmptyString) { + delete set_; + } + if (set) { + set_has_set(); + set_ = set; + } else { + clear_has_set(); + set_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 stripe_width = 2; +inline bool ObjectList::has_stripe_width() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ObjectList::set_has_stripe_width() { + _has_bits_[0] |= 0x00000002u; +} +inline void ObjectList::clear_has_stripe_width() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ObjectList::clear_stripe_width() { + stripe_width_ = 0u; + clear_has_stripe_width(); +} +inline ::google::protobuf::uint32 ObjectList::stripe_width() const { + return stripe_width_; +} +inline void ObjectList::set_stripe_width(::google::protobuf::uint32 value) { + set_has_stripe_width(); + stripe_width_ = value; +} + +// required fixed32 first_ = 3; +inline bool ObjectList::has_first_() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ObjectList::set_has_first_() { + _has_bits_[0] |= 0x00000004u; +} +inline void ObjectList::clear_has_first_() { + _has_bits_[0] &= ~0x00000004u; +} +inline void ObjectList::clear_first_() { + first__ = 0u; + clear_has_first_(); +} +inline ::google::protobuf::uint32 ObjectList::first_() const { + return first__; +} +inline void ObjectList::set_first_(::google::protobuf::uint32 value) { + set_has_first_(); + first__ = value; +} + +// ------------------------------------------------------------------- + +// ObjectVersion + +// required fixed64 object_number = 1; +inline bool ObjectVersion::has_object_number() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ObjectVersion::set_has_object_number() { + _has_bits_[0] |= 0x00000001u; +} +inline void ObjectVersion::clear_has_object_number() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ObjectVersion::clear_object_number() { + object_number_ = GOOGLE_ULONGLONG(0); + clear_has_object_number(); +} +inline ::google::protobuf::uint64 ObjectVersion::object_number() const { + return object_number_; +} +inline void ObjectVersion::set_object_number(::google::protobuf::uint64 value) { + set_has_object_number(); + object_number_ = value; +} + +// required fixed64 object_version = 2; +inline bool ObjectVersion::has_object_version() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ObjectVersion::set_has_object_version() { + _has_bits_[0] |= 0x00000002u; +} +inline void ObjectVersion::clear_has_object_version() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ObjectVersion::clear_object_version() { + object_version_ = GOOGLE_ULONGLONG(0); + clear_has_object_version(); +} +inline ::google::protobuf::uint64 ObjectVersion::object_version() const { + return object_version_; +} +inline void ObjectVersion::set_object_version(::google::protobuf::uint64 value) { + set_has_object_version(); + object_version_ = value; +} + +// ------------------------------------------------------------------- + +// TruncateRecord + +// required fixed64 version = 1; +inline bool TruncateRecord::has_version() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void TruncateRecord::set_has_version() { + _has_bits_[0] |= 0x00000001u; +} +inline void TruncateRecord::clear_has_version() { + _has_bits_[0] &= ~0x00000001u; +} +inline void TruncateRecord::clear_version() { + version_ = GOOGLE_ULONGLONG(0); + clear_has_version(); +} +inline ::google::protobuf::uint64 TruncateRecord::version() const { + return version_; +} +inline void TruncateRecord::set_version(::google::protobuf::uint64 value) { + set_has_version(); + version_ = value; +} + +// required fixed64 last_object_number = 2; +inline bool TruncateRecord::has_last_object_number() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void TruncateRecord::set_has_last_object_number() { + _has_bits_[0] |= 0x00000002u; +} +inline void TruncateRecord::clear_has_last_object_number() { + _has_bits_[0] &= ~0x00000002u; +} +inline void TruncateRecord::clear_last_object_number() { + last_object_number_ = GOOGLE_ULONGLONG(0); + clear_has_last_object_number(); +} +inline ::google::protobuf::uint64 TruncateRecord::last_object_number() const { + return last_object_number_; +} +inline void TruncateRecord::set_last_object_number(::google::protobuf::uint64 value) { + set_has_last_object_number(); + last_object_number_ = value; +} + +// ------------------------------------------------------------------- + +// TruncateLog + +// repeated .xtreemfs.pbrpc.TruncateRecord records = 1; +inline int TruncateLog::records_size() const { + return records_.size(); +} +inline void TruncateLog::clear_records() { + records_.Clear(); +} +inline const ::xtreemfs::pbrpc::TruncateRecord& TruncateLog::records(int index) const { + return records_.Get(index); +} +inline ::xtreemfs::pbrpc::TruncateRecord* TruncateLog::mutable_records(int index) { + return records_.Mutable(index); +} +inline ::xtreemfs::pbrpc::TruncateRecord* TruncateLog::add_records() { + return records_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::TruncateRecord >& +TruncateLog::records() const { + return records_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::TruncateRecord >* +TruncateLog::mutable_records() { + return &records_; +} + +// ------------------------------------------------------------------- + +// XLocSetVersionState + +// required fixed32 version = 1; +inline bool XLocSetVersionState::has_version() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void XLocSetVersionState::set_has_version() { + _has_bits_[0] |= 0x00000001u; +} +inline void XLocSetVersionState::clear_has_version() { + _has_bits_[0] &= ~0x00000001u; +} +inline void XLocSetVersionState::clear_version() { + version_ = 0u; + clear_has_version(); +} +inline ::google::protobuf::uint32 XLocSetVersionState::version() const { + return version_; +} +inline void XLocSetVersionState::set_version(::google::protobuf::uint32 value) { + set_has_version(); + version_ = value; +} + +// required bool invalidated = 2; +inline bool XLocSetVersionState::has_invalidated() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void XLocSetVersionState::set_has_invalidated() { + _has_bits_[0] |= 0x00000002u; +} +inline void XLocSetVersionState::clear_has_invalidated() { + _has_bits_[0] &= ~0x00000002u; +} +inline void XLocSetVersionState::clear_invalidated() { + invalidated_ = false; + clear_has_invalidated(); +} +inline bool XLocSetVersionState::invalidated() const { + return invalidated_; +} +inline void XLocSetVersionState::set_invalidated(bool value) { + set_has_invalidated(); + invalidated_ = value; +} + +// optional fixed64 modified_time = 3; +inline bool XLocSetVersionState::has_modified_time() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void XLocSetVersionState::set_has_modified_time() { + _has_bits_[0] |= 0x00000004u; +} +inline void XLocSetVersionState::clear_has_modified_time() { + _has_bits_[0] &= ~0x00000004u; +} +inline void XLocSetVersionState::clear_modified_time() { + modified_time_ = GOOGLE_ULONGLONG(0); + clear_has_modified_time(); +} +inline ::google::protobuf::uint64 XLocSetVersionState::modified_time() const { + return modified_time_; +} +inline void XLocSetVersionState::set_modified_time(::google::protobuf::uint64 value) { + set_has_modified_time(); + modified_time_ = value; +} + +// ------------------------------------------------------------------- + +// ReplicaStatus + +// required fixed64 truncate_epoch = 1; +inline bool ReplicaStatus::has_truncate_epoch() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ReplicaStatus::set_has_truncate_epoch() { + _has_bits_[0] |= 0x00000001u; +} +inline void ReplicaStatus::clear_has_truncate_epoch() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ReplicaStatus::clear_truncate_epoch() { + truncate_epoch_ = GOOGLE_ULONGLONG(0); + clear_has_truncate_epoch(); +} +inline ::google::protobuf::uint64 ReplicaStatus::truncate_epoch() const { + return truncate_epoch_; +} +inline void ReplicaStatus::set_truncate_epoch(::google::protobuf::uint64 value) { + set_has_truncate_epoch(); + truncate_epoch_ = value; +} + +// required fixed64 file_size = 2; +inline bool ReplicaStatus::has_file_size() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ReplicaStatus::set_has_file_size() { + _has_bits_[0] |= 0x00000002u; +} +inline void ReplicaStatus::clear_has_file_size() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ReplicaStatus::clear_file_size() { + file_size_ = GOOGLE_ULONGLONG(0); + clear_has_file_size(); +} +inline ::google::protobuf::uint64 ReplicaStatus::file_size() const { + return file_size_; +} +inline void ReplicaStatus::set_file_size(::google::protobuf::uint64 value) { + set_has_file_size(); + file_size_ = value; +} + +// required fixed64 max_obj_version = 3; +inline bool ReplicaStatus::has_max_obj_version() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ReplicaStatus::set_has_max_obj_version() { + _has_bits_[0] |= 0x00000004u; +} +inline void ReplicaStatus::clear_has_max_obj_version() { + _has_bits_[0] &= ~0x00000004u; +} +inline void ReplicaStatus::clear_max_obj_version() { + max_obj_version_ = GOOGLE_ULONGLONG(0); + clear_has_max_obj_version(); +} +inline ::google::protobuf::uint64 ReplicaStatus::max_obj_version() const { + return max_obj_version_; +} +inline void ReplicaStatus::set_max_obj_version(::google::protobuf::uint64 value) { + set_has_max_obj_version(); + max_obj_version_ = value; +} + +// required fixed32 primary_epoch = 4; +inline bool ReplicaStatus::has_primary_epoch() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void ReplicaStatus::set_has_primary_epoch() { + _has_bits_[0] |= 0x00000008u; +} +inline void ReplicaStatus::clear_has_primary_epoch() { + _has_bits_[0] &= ~0x00000008u; +} +inline void ReplicaStatus::clear_primary_epoch() { + primary_epoch_ = 0u; + clear_has_primary_epoch(); +} +inline ::google::protobuf::uint32 ReplicaStatus::primary_epoch() const { + return primary_epoch_; +} +inline void ReplicaStatus::set_primary_epoch(::google::protobuf::uint32 value) { + set_has_primary_epoch(); + primary_epoch_ = value; +} + +// repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; +inline int ReplicaStatus::objectversions_size() const { + return objectversions_.size(); +} +inline void ReplicaStatus::clear_objectversions() { + objectversions_.Clear(); +} +inline const ::xtreemfs::pbrpc::ObjectVersion& ReplicaStatus::objectversions(int index) const { + return objectversions_.Get(index); +} +inline ::xtreemfs::pbrpc::ObjectVersion* ReplicaStatus::mutable_objectversions(int index) { + return objectversions_.Mutable(index); +} +inline ::xtreemfs::pbrpc::ObjectVersion* ReplicaStatus::add_objectversions() { + return objectversions_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectVersion >& +ReplicaStatus::objectversions() const { + return objectversions_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectVersion >* +ReplicaStatus::mutable_objectversions() { + return &objectversions_; +} + +// required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; +inline bool ReplicaStatus::has_truncate_log() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void ReplicaStatus::set_has_truncate_log() { + _has_bits_[0] |= 0x00000020u; +} +inline void ReplicaStatus::clear_has_truncate_log() { + _has_bits_[0] &= ~0x00000020u; +} +inline void ReplicaStatus::clear_truncate_log() { + if (truncate_log_ != NULL) truncate_log_->::xtreemfs::pbrpc::TruncateLog::Clear(); + clear_has_truncate_log(); +} +inline const ::xtreemfs::pbrpc::TruncateLog& ReplicaStatus::truncate_log() const { + return truncate_log_ != NULL ? *truncate_log_ : *default_instance_->truncate_log_; +} +inline ::xtreemfs::pbrpc::TruncateLog* ReplicaStatus::mutable_truncate_log() { + set_has_truncate_log(); + if (truncate_log_ == NULL) truncate_log_ = new ::xtreemfs::pbrpc::TruncateLog; + return truncate_log_; +} +inline ::xtreemfs::pbrpc::TruncateLog* ReplicaStatus::release_truncate_log() { + clear_has_truncate_log(); + ::xtreemfs::pbrpc::TruncateLog* temp = truncate_log_; + truncate_log_ = NULL; + return temp; +} +inline void ReplicaStatus::set_allocated_truncate_log(::xtreemfs::pbrpc::TruncateLog* truncate_log) { + delete truncate_log_; + truncate_log_ = truncate_log; + if (truncate_log) { + set_has_truncate_log(); + } else { + clear_has_truncate_log(); + } +} + +// ------------------------------------------------------------------- + +// ObjectVersionMapping + +// required fixed64 object_number = 1; +inline bool ObjectVersionMapping::has_object_number() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ObjectVersionMapping::set_has_object_number() { + _has_bits_[0] |= 0x00000001u; +} +inline void ObjectVersionMapping::clear_has_object_number() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ObjectVersionMapping::clear_object_number() { + object_number_ = GOOGLE_ULONGLONG(0); + clear_has_object_number(); +} +inline ::google::protobuf::uint64 ObjectVersionMapping::object_number() const { + return object_number_; +} +inline void ObjectVersionMapping::set_object_number(::google::protobuf::uint64 value) { + set_has_object_number(); + object_number_ = value; +} + +// required fixed64 object_version = 2; +inline bool ObjectVersionMapping::has_object_version() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ObjectVersionMapping::set_has_object_version() { + _has_bits_[0] |= 0x00000002u; +} +inline void ObjectVersionMapping::clear_has_object_version() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ObjectVersionMapping::clear_object_version() { + object_version_ = GOOGLE_ULONGLONG(0); + clear_has_object_version(); +} +inline ::google::protobuf::uint64 ObjectVersionMapping::object_version() const { + return object_version_; +} +inline void ObjectVersionMapping::set_object_version(::google::protobuf::uint64 value) { + set_has_object_version(); + object_version_ = value; +} + +// repeated string osd_uuids = 3; +inline int ObjectVersionMapping::osd_uuids_size() const { + return osd_uuids_.size(); +} +inline void ObjectVersionMapping::clear_osd_uuids() { + osd_uuids_.Clear(); +} +inline const ::std::string& ObjectVersionMapping::osd_uuids(int index) const { + return osd_uuids_.Get(index); +} +inline ::std::string* ObjectVersionMapping::mutable_osd_uuids(int index) { + return osd_uuids_.Mutable(index); +} +inline void ObjectVersionMapping::set_osd_uuids(int index, const ::std::string& value) { + osd_uuids_.Mutable(index)->assign(value); +} +inline void ObjectVersionMapping::set_osd_uuids(int index, const char* value) { + osd_uuids_.Mutable(index)->assign(value); +} +inline void ObjectVersionMapping::set_osd_uuids(int index, const char* value, size_t size) { + osd_uuids_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* ObjectVersionMapping::add_osd_uuids() { + return osd_uuids_.Add(); +} +inline void ObjectVersionMapping::add_osd_uuids(const ::std::string& value) { + osd_uuids_.Add()->assign(value); +} +inline void ObjectVersionMapping::add_osd_uuids(const char* value) { + osd_uuids_.Add()->assign(value); +} +inline void ObjectVersionMapping::add_osd_uuids(const char* value, size_t size) { + osd_uuids_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +ObjectVersionMapping::osd_uuids() const { + return osd_uuids_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +ObjectVersionMapping::mutable_osd_uuids() { + return &osd_uuids_; +} + +// ------------------------------------------------------------------- + +// AuthoritativeReplicaState + +// required fixed64 truncate_epoch = 1; +inline bool AuthoritativeReplicaState::has_truncate_epoch() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void AuthoritativeReplicaState::set_has_truncate_epoch() { + _has_bits_[0] |= 0x00000001u; +} +inline void AuthoritativeReplicaState::clear_has_truncate_epoch() { + _has_bits_[0] &= ~0x00000001u; +} +inline void AuthoritativeReplicaState::clear_truncate_epoch() { + truncate_epoch_ = GOOGLE_ULONGLONG(0); + clear_has_truncate_epoch(); +} +inline ::google::protobuf::uint64 AuthoritativeReplicaState::truncate_epoch() const { + return truncate_epoch_; +} +inline void AuthoritativeReplicaState::set_truncate_epoch(::google::protobuf::uint64 value) { + set_has_truncate_epoch(); + truncate_epoch_ = value; +} + +// required fixed64 max_obj_version = 4; +inline bool AuthoritativeReplicaState::has_max_obj_version() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void AuthoritativeReplicaState::set_has_max_obj_version() { + _has_bits_[0] |= 0x00000002u; +} +inline void AuthoritativeReplicaState::clear_has_max_obj_version() { + _has_bits_[0] &= ~0x00000002u; +} +inline void AuthoritativeReplicaState::clear_max_obj_version() { + max_obj_version_ = GOOGLE_ULONGLONG(0); + clear_has_max_obj_version(); +} +inline ::google::protobuf::uint64 AuthoritativeReplicaState::max_obj_version() const { + return max_obj_version_; +} +inline void AuthoritativeReplicaState::set_max_obj_version(::google::protobuf::uint64 value) { + set_has_max_obj_version(); + max_obj_version_ = value; +} + +// repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; +inline int AuthoritativeReplicaState::objectversions_size() const { + return objectversions_.size(); +} +inline void AuthoritativeReplicaState::clear_objectversions() { + objectversions_.Clear(); +} +inline const ::xtreemfs::pbrpc::ObjectVersionMapping& AuthoritativeReplicaState::objectversions(int index) const { + return objectversions_.Get(index); +} +inline ::xtreemfs::pbrpc::ObjectVersionMapping* AuthoritativeReplicaState::mutable_objectversions(int index) { + return objectversions_.Mutable(index); +} +inline ::xtreemfs::pbrpc::ObjectVersionMapping* AuthoritativeReplicaState::add_objectversions() { + return objectversions_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectVersionMapping >& +AuthoritativeReplicaState::objectversions() const { + return objectversions_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectVersionMapping >* +AuthoritativeReplicaState::mutable_objectversions() { + return &objectversions_; +} + +// required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; +inline bool AuthoritativeReplicaState::has_truncate_log() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void AuthoritativeReplicaState::set_has_truncate_log() { + _has_bits_[0] |= 0x00000008u; +} +inline void AuthoritativeReplicaState::clear_has_truncate_log() { + _has_bits_[0] &= ~0x00000008u; +} +inline void AuthoritativeReplicaState::clear_truncate_log() { + if (truncate_log_ != NULL) truncate_log_->::xtreemfs::pbrpc::TruncateLog::Clear(); + clear_has_truncate_log(); +} +inline const ::xtreemfs::pbrpc::TruncateLog& AuthoritativeReplicaState::truncate_log() const { + return truncate_log_ != NULL ? *truncate_log_ : *default_instance_->truncate_log_; +} +inline ::xtreemfs::pbrpc::TruncateLog* AuthoritativeReplicaState::mutable_truncate_log() { + set_has_truncate_log(); + if (truncate_log_ == NULL) truncate_log_ = new ::xtreemfs::pbrpc::TruncateLog; + return truncate_log_; +} +inline ::xtreemfs::pbrpc::TruncateLog* AuthoritativeReplicaState::release_truncate_log() { + clear_has_truncate_log(); + ::xtreemfs::pbrpc::TruncateLog* temp = truncate_log_; + truncate_log_ = NULL; + return temp; +} +inline void AuthoritativeReplicaState::set_allocated_truncate_log(::xtreemfs::pbrpc::TruncateLog* truncate_log) { + delete truncate_log_; + truncate_log_ = truncate_log; + if (truncate_log) { + set_has_truncate_log(); + } else { + clear_has_truncate_log(); + } +} + +// ------------------------------------------------------------------- + +// InternalReadLocalResponse + +// required .xtreemfs.pbrpc.ObjectData data = 1; +inline bool InternalReadLocalResponse::has_data() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void InternalReadLocalResponse::set_has_data() { + _has_bits_[0] |= 0x00000001u; +} +inline void InternalReadLocalResponse::clear_has_data() { + _has_bits_[0] &= ~0x00000001u; +} +inline void InternalReadLocalResponse::clear_data() { + if (data_ != NULL) data_->::xtreemfs::pbrpc::ObjectData::Clear(); + clear_has_data(); +} +inline const ::xtreemfs::pbrpc::ObjectData& InternalReadLocalResponse::data() const { + return data_ != NULL ? *data_ : *default_instance_->data_; +} +inline ::xtreemfs::pbrpc::ObjectData* InternalReadLocalResponse::mutable_data() { + set_has_data(); + if (data_ == NULL) data_ = new ::xtreemfs::pbrpc::ObjectData; + return data_; +} +inline ::xtreemfs::pbrpc::ObjectData* InternalReadLocalResponse::release_data() { + clear_has_data(); + ::xtreemfs::pbrpc::ObjectData* temp = data_; + data_ = NULL; + return temp; +} +inline void InternalReadLocalResponse::set_allocated_data(::xtreemfs::pbrpc::ObjectData* data) { + delete data_; + data_ = data; + if (data) { + set_has_data(); + } else { + clear_has_data(); + } +} + +// repeated .xtreemfs.pbrpc.ObjectList object_set = 2; +inline int InternalReadLocalResponse::object_set_size() const { + return object_set_.size(); +} +inline void InternalReadLocalResponse::clear_object_set() { + object_set_.Clear(); +} +inline const ::xtreemfs::pbrpc::ObjectList& InternalReadLocalResponse::object_set(int index) const { + return object_set_.Get(index); +} +inline ::xtreemfs::pbrpc::ObjectList* InternalReadLocalResponse::mutable_object_set(int index) { + return object_set_.Mutable(index); +} +inline ::xtreemfs::pbrpc::ObjectList* InternalReadLocalResponse::add_object_set() { + return object_set_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectList >& +InternalReadLocalResponse::object_set() const { + return object_set_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectList >* +InternalReadLocalResponse::mutable_object_set() { + return &object_set_; +} + +// ------------------------------------------------------------------- + +// readRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool readRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void readRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void readRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void readRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& readRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* readRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* readRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void readRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool readRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void readRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void readRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void readRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& readRequest::file_id() const { + return *file_id_; +} +inline void readRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void readRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void readRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* readRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* readRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void readRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 object_number = 3; +inline bool readRequest::has_object_number() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void readRequest::set_has_object_number() { + _has_bits_[0] |= 0x00000004u; +} +inline void readRequest::clear_has_object_number() { + _has_bits_[0] &= ~0x00000004u; +} +inline void readRequest::clear_object_number() { + object_number_ = GOOGLE_ULONGLONG(0); + clear_has_object_number(); +} +inline ::google::protobuf::uint64 readRequest::object_number() const { + return object_number_; +} +inline void readRequest::set_object_number(::google::protobuf::uint64 value) { + set_has_object_number(); + object_number_ = value; +} + +// required fixed64 object_version = 4; +inline bool readRequest::has_object_version() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void readRequest::set_has_object_version() { + _has_bits_[0] |= 0x00000008u; +} +inline void readRequest::clear_has_object_version() { + _has_bits_[0] &= ~0x00000008u; +} +inline void readRequest::clear_object_version() { + object_version_ = GOOGLE_ULONGLONG(0); + clear_has_object_version(); +} +inline ::google::protobuf::uint64 readRequest::object_version() const { + return object_version_; +} +inline void readRequest::set_object_version(::google::protobuf::uint64 value) { + set_has_object_version(); + object_version_ = value; +} + +// required fixed32 offset = 5; +inline bool readRequest::has_offset() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void readRequest::set_has_offset() { + _has_bits_[0] |= 0x00000010u; +} +inline void readRequest::clear_has_offset() { + _has_bits_[0] &= ~0x00000010u; +} +inline void readRequest::clear_offset() { + offset_ = 0u; + clear_has_offset(); +} +inline ::google::protobuf::uint32 readRequest::offset() const { + return offset_; +} +inline void readRequest::set_offset(::google::protobuf::uint32 value) { + set_has_offset(); + offset_ = value; +} + +// required fixed32 length = 6; +inline bool readRequest::has_length() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void readRequest::set_has_length() { + _has_bits_[0] |= 0x00000020u; +} +inline void readRequest::clear_has_length() { + _has_bits_[0] &= ~0x00000020u; +} +inline void readRequest::clear_length() { + length_ = 0u; + clear_has_length(); +} +inline ::google::protobuf::uint32 readRequest::length() const { + return length_; +} +inline void readRequest::set_length(::google::protobuf::uint32 value) { + set_has_length(); + length_ = value; +} + +// ------------------------------------------------------------------- + +// truncateRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool truncateRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void truncateRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void truncateRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void truncateRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& truncateRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* truncateRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* truncateRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void truncateRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool truncateRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void truncateRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void truncateRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void truncateRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& truncateRequest::file_id() const { + return *file_id_; +} +inline void truncateRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void truncateRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void truncateRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* truncateRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* truncateRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void truncateRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 new_file_size = 3; +inline bool truncateRequest::has_new_file_size() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void truncateRequest::set_has_new_file_size() { + _has_bits_[0] |= 0x00000004u; +} +inline void truncateRequest::clear_has_new_file_size() { + _has_bits_[0] &= ~0x00000004u; +} +inline void truncateRequest::clear_new_file_size() { + new_file_size_ = GOOGLE_ULONGLONG(0); + clear_has_new_file_size(); +} +inline ::google::protobuf::uint64 truncateRequest::new_file_size() const { + return new_file_size_; +} +inline void truncateRequest::set_new_file_size(::google::protobuf::uint64 value) { + set_has_new_file_size(); + new_file_size_ = value; +} + +// ------------------------------------------------------------------- + +// unlink_osd_Request + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool unlink_osd_Request::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void unlink_osd_Request::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void unlink_osd_Request::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void unlink_osd_Request::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& unlink_osd_Request::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* unlink_osd_Request::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* unlink_osd_Request::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void unlink_osd_Request::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool unlink_osd_Request::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void unlink_osd_Request::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void unlink_osd_Request::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void unlink_osd_Request::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& unlink_osd_Request::file_id() const { + return *file_id_; +} +inline void unlink_osd_Request::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void unlink_osd_Request::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void unlink_osd_Request::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* unlink_osd_Request::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* unlink_osd_Request::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void unlink_osd_Request::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// writeRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool writeRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void writeRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void writeRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void writeRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& writeRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* writeRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* writeRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void writeRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool writeRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void writeRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void writeRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void writeRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& writeRequest::file_id() const { + return *file_id_; +} +inline void writeRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void writeRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void writeRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* writeRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* writeRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void writeRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 object_number = 3; +inline bool writeRequest::has_object_number() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void writeRequest::set_has_object_number() { + _has_bits_[0] |= 0x00000004u; +} +inline void writeRequest::clear_has_object_number() { + _has_bits_[0] &= ~0x00000004u; +} +inline void writeRequest::clear_object_number() { + object_number_ = GOOGLE_ULONGLONG(0); + clear_has_object_number(); +} +inline ::google::protobuf::uint64 writeRequest::object_number() const { + return object_number_; +} +inline void writeRequest::set_object_number(::google::protobuf::uint64 value) { + set_has_object_number(); + object_number_ = value; +} + +// required fixed64 object_version = 4; +inline bool writeRequest::has_object_version() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void writeRequest::set_has_object_version() { + _has_bits_[0] |= 0x00000008u; +} +inline void writeRequest::clear_has_object_version() { + _has_bits_[0] &= ~0x00000008u; +} +inline void writeRequest::clear_object_version() { + object_version_ = GOOGLE_ULONGLONG(0); + clear_has_object_version(); +} +inline ::google::protobuf::uint64 writeRequest::object_version() const { + return object_version_; +} +inline void writeRequest::set_object_version(::google::protobuf::uint64 value) { + set_has_object_version(); + object_version_ = value; +} + +// required fixed32 offset = 5; +inline bool writeRequest::has_offset() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void writeRequest::set_has_offset() { + _has_bits_[0] |= 0x00000010u; +} +inline void writeRequest::clear_has_offset() { + _has_bits_[0] &= ~0x00000010u; +} +inline void writeRequest::clear_offset() { + offset_ = 0u; + clear_has_offset(); +} +inline ::google::protobuf::uint32 writeRequest::offset() const { + return offset_; +} +inline void writeRequest::set_offset(::google::protobuf::uint32 value) { + set_has_offset(); + offset_ = value; +} + +// required fixed64 lease_timeout = 6; +inline bool writeRequest::has_lease_timeout() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void writeRequest::set_has_lease_timeout() { + _has_bits_[0] |= 0x00000020u; +} +inline void writeRequest::clear_has_lease_timeout() { + _has_bits_[0] &= ~0x00000020u; +} +inline void writeRequest::clear_lease_timeout() { + lease_timeout_ = GOOGLE_ULONGLONG(0); + clear_has_lease_timeout(); +} +inline ::google::protobuf::uint64 writeRequest::lease_timeout() const { + return lease_timeout_; +} +inline void writeRequest::set_lease_timeout(::google::protobuf::uint64 value) { + set_has_lease_timeout(); + lease_timeout_ = value; +} + +// required .xtreemfs.pbrpc.ObjectData object_data = 7; +inline bool writeRequest::has_object_data() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void writeRequest::set_has_object_data() { + _has_bits_[0] |= 0x00000040u; +} +inline void writeRequest::clear_has_object_data() { + _has_bits_[0] &= ~0x00000040u; +} +inline void writeRequest::clear_object_data() { + if (object_data_ != NULL) object_data_->::xtreemfs::pbrpc::ObjectData::Clear(); + clear_has_object_data(); +} +inline const ::xtreemfs::pbrpc::ObjectData& writeRequest::object_data() const { + return object_data_ != NULL ? *object_data_ : *default_instance_->object_data_; +} +inline ::xtreemfs::pbrpc::ObjectData* writeRequest::mutable_object_data() { + set_has_object_data(); + if (object_data_ == NULL) object_data_ = new ::xtreemfs::pbrpc::ObjectData; + return object_data_; +} +inline ::xtreemfs::pbrpc::ObjectData* writeRequest::release_object_data() { + clear_has_object_data(); + ::xtreemfs::pbrpc::ObjectData* temp = object_data_; + object_data_ = NULL; + return temp; +} +inline void writeRequest::set_allocated_object_data(::xtreemfs::pbrpc::ObjectData* object_data) { + delete object_data_; + object_data_ = object_data; + if (object_data) { + set_has_object_data(); + } else { + clear_has_object_data(); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_broadcast_gmaxRequest + +// required string file_id = 1; +inline bool xtreemfs_broadcast_gmaxRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_broadcast_gmaxRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_broadcast_gmaxRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_broadcast_gmaxRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_broadcast_gmaxRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_broadcast_gmaxRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_broadcast_gmaxRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_broadcast_gmaxRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_broadcast_gmaxRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_broadcast_gmaxRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_broadcast_gmaxRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 truncate_epoch = 2; +inline bool xtreemfs_broadcast_gmaxRequest::has_truncate_epoch() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_broadcast_gmaxRequest::set_has_truncate_epoch() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_broadcast_gmaxRequest::clear_has_truncate_epoch() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_broadcast_gmaxRequest::clear_truncate_epoch() { + truncate_epoch_ = GOOGLE_ULONGLONG(0); + clear_has_truncate_epoch(); +} +inline ::google::protobuf::uint64 xtreemfs_broadcast_gmaxRequest::truncate_epoch() const { + return truncate_epoch_; +} +inline void xtreemfs_broadcast_gmaxRequest::set_truncate_epoch(::google::protobuf::uint64 value) { + set_has_truncate_epoch(); + truncate_epoch_ = value; +} + +// required fixed64 last_object = 3; +inline bool xtreemfs_broadcast_gmaxRequest::has_last_object() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_broadcast_gmaxRequest::set_has_last_object() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_broadcast_gmaxRequest::clear_has_last_object() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_broadcast_gmaxRequest::clear_last_object() { + last_object_ = GOOGLE_ULONGLONG(0); + clear_has_last_object(); +} +inline ::google::protobuf::uint64 xtreemfs_broadcast_gmaxRequest::last_object() const { + return last_object_; +} +inline void xtreemfs_broadcast_gmaxRequest::set_last_object(::google::protobuf::uint64 value) { + set_has_last_object(); + last_object_ = value; +} + +// required fixed64 file_size = 4; +inline bool xtreemfs_broadcast_gmaxRequest::has_file_size() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_broadcast_gmaxRequest::set_has_file_size() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_broadcast_gmaxRequest::clear_has_file_size() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_broadcast_gmaxRequest::clear_file_size() { + file_size_ = GOOGLE_ULONGLONG(0); + clear_has_file_size(); +} +inline ::google::protobuf::uint64 xtreemfs_broadcast_gmaxRequest::file_size() const { + return file_size_; +} +inline void xtreemfs_broadcast_gmaxRequest::set_file_size(::google::protobuf::uint64 value) { + set_has_file_size(); + file_size_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_check_objectRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_check_objectRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_check_objectRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_check_objectRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_check_objectRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_check_objectRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_check_objectRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_check_objectRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_check_objectRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_check_objectRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_check_objectRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_check_objectRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_check_objectRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_check_objectRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_check_objectRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_check_objectRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_check_objectRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_check_objectRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_check_objectRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_check_objectRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 object_number = 3; +inline bool xtreemfs_check_objectRequest::has_object_number() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_check_objectRequest::set_has_object_number() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_check_objectRequest::clear_has_object_number() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_check_objectRequest::clear_object_number() { + object_number_ = GOOGLE_ULONGLONG(0); + clear_has_object_number(); +} +inline ::google::protobuf::uint64 xtreemfs_check_objectRequest::object_number() const { + return object_number_; +} +inline void xtreemfs_check_objectRequest::set_object_number(::google::protobuf::uint64 value) { + set_has_object_number(); + object_number_ = value; +} + +// required fixed64 object_version = 4; +inline bool xtreemfs_check_objectRequest::has_object_version() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_check_objectRequest::set_has_object_version() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_check_objectRequest::clear_has_object_version() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_check_objectRequest::clear_object_version() { + object_version_ = GOOGLE_ULONGLONG(0); + clear_has_object_version(); +} +inline ::google::protobuf::uint64 xtreemfs_check_objectRequest::object_version() const { + return object_version_; +} +inline void xtreemfs_check_objectRequest::set_object_version(::google::protobuf::uint64 value) { + set_has_object_version(); + object_version_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_cleanup_get_resultsResponse + +// repeated string results = 1; +inline int xtreemfs_cleanup_get_resultsResponse::results_size() const { + return results_.size(); +} +inline void xtreemfs_cleanup_get_resultsResponse::clear_results() { + results_.Clear(); +} +inline const ::std::string& xtreemfs_cleanup_get_resultsResponse::results(int index) const { + return results_.Get(index); +} +inline ::std::string* xtreemfs_cleanup_get_resultsResponse::mutable_results(int index) { + return results_.Mutable(index); +} +inline void xtreemfs_cleanup_get_resultsResponse::set_results(int index, const ::std::string& value) { + results_.Mutable(index)->assign(value); +} +inline void xtreemfs_cleanup_get_resultsResponse::set_results(int index, const char* value) { + results_.Mutable(index)->assign(value); +} +inline void xtreemfs_cleanup_get_resultsResponse::set_results(int index, const char* value, size_t size) { + results_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_cleanup_get_resultsResponse::add_results() { + return results_.Add(); +} +inline void xtreemfs_cleanup_get_resultsResponse::add_results(const ::std::string& value) { + results_.Add()->assign(value); +} +inline void xtreemfs_cleanup_get_resultsResponse::add_results(const char* value) { + results_.Add()->assign(value); +} +inline void xtreemfs_cleanup_get_resultsResponse::add_results(const char* value, size_t size) { + results_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +xtreemfs_cleanup_get_resultsResponse::results() const { + return results_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +xtreemfs_cleanup_get_resultsResponse::mutable_results() { + return &results_; +} + +// ------------------------------------------------------------------- + +// xtreemfs_cleanup_is_runningResponse + +// required bool is_running = 1; +inline bool xtreemfs_cleanup_is_runningResponse::has_is_running() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_cleanup_is_runningResponse::set_has_is_running() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_cleanup_is_runningResponse::clear_has_is_running() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_cleanup_is_runningResponse::clear_is_running() { + is_running_ = false; + clear_has_is_running(); +} +inline bool xtreemfs_cleanup_is_runningResponse::is_running() const { + return is_running_; +} +inline void xtreemfs_cleanup_is_runningResponse::set_is_running(bool value) { + set_has_is_running(); + is_running_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_cleanup_startRequest + +// required bool remove_zombies = 1; +inline bool xtreemfs_cleanup_startRequest::has_remove_zombies() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_cleanup_startRequest::set_has_remove_zombies() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_cleanup_startRequest::clear_has_remove_zombies() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_cleanup_startRequest::clear_remove_zombies() { + remove_zombies_ = false; + clear_has_remove_zombies(); +} +inline bool xtreemfs_cleanup_startRequest::remove_zombies() const { + return remove_zombies_; +} +inline void xtreemfs_cleanup_startRequest::set_remove_zombies(bool value) { + set_has_remove_zombies(); + remove_zombies_ = value; +} + +// required bool remove_unavail_volume = 2; +inline bool xtreemfs_cleanup_startRequest::has_remove_unavail_volume() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_cleanup_startRequest::set_has_remove_unavail_volume() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_cleanup_startRequest::clear_has_remove_unavail_volume() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_cleanup_startRequest::clear_remove_unavail_volume() { + remove_unavail_volume_ = false; + clear_has_remove_unavail_volume(); +} +inline bool xtreemfs_cleanup_startRequest::remove_unavail_volume() const { + return remove_unavail_volume_; +} +inline void xtreemfs_cleanup_startRequest::set_remove_unavail_volume(bool value) { + set_has_remove_unavail_volume(); + remove_unavail_volume_ = value; +} + +// required bool lost_and_found = 3; +inline bool xtreemfs_cleanup_startRequest::has_lost_and_found() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_cleanup_startRequest::set_has_lost_and_found() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_cleanup_startRequest::clear_has_lost_and_found() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_cleanup_startRequest::clear_lost_and_found() { + lost_and_found_ = false; + clear_has_lost_and_found(); +} +inline bool xtreemfs_cleanup_startRequest::lost_and_found() const { + return lost_and_found_; +} +inline void xtreemfs_cleanup_startRequest::set_lost_and_found(bool value) { + set_has_lost_and_found(); + lost_and_found_ = value; +} + +// required bool delete_metadata = 4; +inline bool xtreemfs_cleanup_startRequest::has_delete_metadata() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_cleanup_startRequest::set_has_delete_metadata() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_cleanup_startRequest::clear_has_delete_metadata() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_cleanup_startRequest::clear_delete_metadata() { + delete_metadata_ = false; + clear_has_delete_metadata(); +} +inline bool xtreemfs_cleanup_startRequest::delete_metadata() const { + return delete_metadata_; +} +inline void xtreemfs_cleanup_startRequest::set_delete_metadata(bool value) { + set_has_delete_metadata(); + delete_metadata_ = value; +} + +// required fixed32 metadata_timeout = 5; +inline bool xtreemfs_cleanup_startRequest::has_metadata_timeout() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void xtreemfs_cleanup_startRequest::set_has_metadata_timeout() { + _has_bits_[0] |= 0x00000010u; +} +inline void xtreemfs_cleanup_startRequest::clear_has_metadata_timeout() { + _has_bits_[0] &= ~0x00000010u; +} +inline void xtreemfs_cleanup_startRequest::clear_metadata_timeout() { + metadata_timeout_ = 0u; + clear_has_metadata_timeout(); +} +inline ::google::protobuf::uint32 xtreemfs_cleanup_startRequest::metadata_timeout() const { + return metadata_timeout_; +} +inline void xtreemfs_cleanup_startRequest::set_metadata_timeout(::google::protobuf::uint32 value) { + set_has_metadata_timeout(); + metadata_timeout_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_cleanup_statusResponse + +// required string status = 1; +inline bool xtreemfs_cleanup_statusResponse::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_cleanup_statusResponse::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_cleanup_statusResponse::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_cleanup_statusResponse::clear_status() { + if (status_ != &::google::protobuf::internal::kEmptyString) { + status_->clear(); + } + clear_has_status(); +} +inline const ::std::string& xtreemfs_cleanup_statusResponse::status() const { + return *status_; +} +inline void xtreemfs_cleanup_statusResponse::set_status(const ::std::string& value) { + set_has_status(); + if (status_ == &::google::protobuf::internal::kEmptyString) { + status_ = new ::std::string; + } + status_->assign(value); +} +inline void xtreemfs_cleanup_statusResponse::set_status(const char* value) { + set_has_status(); + if (status_ == &::google::protobuf::internal::kEmptyString) { + status_ = new ::std::string; + } + status_->assign(value); +} +inline void xtreemfs_cleanup_statusResponse::set_status(const char* value, size_t size) { + set_has_status(); + if (status_ == &::google::protobuf::internal::kEmptyString) { + status_ = new ::std::string; + } + status_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_cleanup_statusResponse::mutable_status() { + set_has_status(); + if (status_ == &::google::protobuf::internal::kEmptyString) { + status_ = new ::std::string; + } + return status_; +} +inline ::std::string* xtreemfs_cleanup_statusResponse::release_status() { + clear_has_status(); + if (status_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = status_; + status_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_cleanup_statusResponse::set_allocated_status(::std::string* status) { + if (status_ != &::google::protobuf::internal::kEmptyString) { + delete status_; + } + if (status) { + set_has_status(); + status_ = status; + } else { + clear_has_status(); + status_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_rwr_fetchRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_rwr_fetchRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_rwr_fetchRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_rwr_fetchRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_rwr_fetchRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_rwr_fetchRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_fetchRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_fetchRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_rwr_fetchRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_rwr_fetchRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_rwr_fetchRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_rwr_fetchRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_rwr_fetchRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_rwr_fetchRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_rwr_fetchRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_fetchRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_fetchRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_rwr_fetchRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_rwr_fetchRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_rwr_fetchRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 object_number = 3; +inline bool xtreemfs_rwr_fetchRequest::has_object_number() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_rwr_fetchRequest::set_has_object_number() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_rwr_fetchRequest::clear_has_object_number() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_rwr_fetchRequest::clear_object_number() { + object_number_ = GOOGLE_ULONGLONG(0); + clear_has_object_number(); +} +inline ::google::protobuf::uint64 xtreemfs_rwr_fetchRequest::object_number() const { + return object_number_; +} +inline void xtreemfs_rwr_fetchRequest::set_object_number(::google::protobuf::uint64 value) { + set_has_object_number(); + object_number_ = value; +} + +// required fixed64 object_version = 4; +inline bool xtreemfs_rwr_fetchRequest::has_object_version() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_rwr_fetchRequest::set_has_object_version() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_rwr_fetchRequest::clear_has_object_version() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_rwr_fetchRequest::clear_object_version() { + object_version_ = GOOGLE_ULONGLONG(0); + clear_has_object_version(); +} +inline ::google::protobuf::uint64 xtreemfs_rwr_fetchRequest::object_version() const { + return object_version_; +} +inline void xtreemfs_rwr_fetchRequest::set_object_version(::google::protobuf::uint64 value) { + set_has_object_version(); + object_version_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_repair_objectRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_repair_objectRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_repair_objectRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_repair_objectRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_repair_objectRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_repair_objectRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_repair_objectRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_repair_objectRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_repair_objectRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_repair_objectRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_repair_objectRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_repair_objectRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_repair_objectRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_repair_objectRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_repair_objectRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_repair_objectRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_repair_objectRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_repair_objectRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_repair_objectRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_repair_objectRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 object_number = 3; +inline bool xtreemfs_repair_objectRequest::has_object_number() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_repair_objectRequest::set_has_object_number() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_repair_objectRequest::clear_has_object_number() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_repair_objectRequest::clear_object_number() { + object_number_ = GOOGLE_ULONGLONG(0); + clear_has_object_number(); +} +inline ::google::protobuf::uint64 xtreemfs_repair_objectRequest::object_number() const { + return object_number_; +} +inline void xtreemfs_repair_objectRequest::set_object_number(::google::protobuf::uint64 value) { + set_has_object_number(); + object_number_ = value; +} + +// required fixed64 object_version = 4; +inline bool xtreemfs_repair_objectRequest::has_object_version() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_repair_objectRequest::set_has_object_version() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_repair_objectRequest::clear_has_object_version() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_repair_objectRequest::clear_object_version() { + object_version_ = GOOGLE_ULONGLONG(0); + clear_has_object_version(); +} +inline ::google::protobuf::uint64 xtreemfs_repair_objectRequest::object_version() const { + return object_version_; +} +inline void xtreemfs_repair_objectRequest::set_object_version(::google::protobuf::uint64 value) { + set_has_object_version(); + object_version_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_rwr_flease_msgRequest + +// required string sender_hostname = 1; +inline bool xtreemfs_rwr_flease_msgRequest::has_sender_hostname() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_rwr_flease_msgRequest::set_has_sender_hostname() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_rwr_flease_msgRequest::clear_has_sender_hostname() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_rwr_flease_msgRequest::clear_sender_hostname() { + if (sender_hostname_ != &::google::protobuf::internal::kEmptyString) { + sender_hostname_->clear(); + } + clear_has_sender_hostname(); +} +inline const ::std::string& xtreemfs_rwr_flease_msgRequest::sender_hostname() const { + return *sender_hostname_; +} +inline void xtreemfs_rwr_flease_msgRequest::set_sender_hostname(const ::std::string& value) { + set_has_sender_hostname(); + if (sender_hostname_ == &::google::protobuf::internal::kEmptyString) { + sender_hostname_ = new ::std::string; + } + sender_hostname_->assign(value); +} +inline void xtreemfs_rwr_flease_msgRequest::set_sender_hostname(const char* value) { + set_has_sender_hostname(); + if (sender_hostname_ == &::google::protobuf::internal::kEmptyString) { + sender_hostname_ = new ::std::string; + } + sender_hostname_->assign(value); +} +inline void xtreemfs_rwr_flease_msgRequest::set_sender_hostname(const char* value, size_t size) { + set_has_sender_hostname(); + if (sender_hostname_ == &::google::protobuf::internal::kEmptyString) { + sender_hostname_ = new ::std::string; + } + sender_hostname_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_rwr_flease_msgRequest::mutable_sender_hostname() { + set_has_sender_hostname(); + if (sender_hostname_ == &::google::protobuf::internal::kEmptyString) { + sender_hostname_ = new ::std::string; + } + return sender_hostname_; +} +inline ::std::string* xtreemfs_rwr_flease_msgRequest::release_sender_hostname() { + clear_has_sender_hostname(); + if (sender_hostname_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = sender_hostname_; + sender_hostname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_rwr_flease_msgRequest::set_allocated_sender_hostname(::std::string* sender_hostname) { + if (sender_hostname_ != &::google::protobuf::internal::kEmptyString) { + delete sender_hostname_; + } + if (sender_hostname) { + set_has_sender_hostname(); + sender_hostname_ = sender_hostname; + } else { + clear_has_sender_hostname(); + sender_hostname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 sender_port = 2; +inline bool xtreemfs_rwr_flease_msgRequest::has_sender_port() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_rwr_flease_msgRequest::set_has_sender_port() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_rwr_flease_msgRequest::clear_has_sender_port() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_rwr_flease_msgRequest::clear_sender_port() { + sender_port_ = 0u; + clear_has_sender_port(); +} +inline ::google::protobuf::uint32 xtreemfs_rwr_flease_msgRequest::sender_port() const { + return sender_port_; +} +inline void xtreemfs_rwr_flease_msgRequest::set_sender_port(::google::protobuf::uint32 value) { + set_has_sender_port(); + sender_port_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_rwr_set_primary_epochRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_rwr_set_primary_epochRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_rwr_set_primary_epochRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_rwr_set_primary_epochRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_rwr_set_primary_epochRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_rwr_set_primary_epochRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_set_primary_epochRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_set_primary_epochRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_rwr_set_primary_epochRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_rwr_set_primary_epochRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_rwr_set_primary_epochRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_rwr_set_primary_epochRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_rwr_set_primary_epochRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_rwr_set_primary_epochRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_rwr_set_primary_epochRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_set_primary_epochRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_set_primary_epochRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_rwr_set_primary_epochRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_rwr_set_primary_epochRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_rwr_set_primary_epochRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 primary_epoch = 3; +inline bool xtreemfs_rwr_set_primary_epochRequest::has_primary_epoch() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_rwr_set_primary_epochRequest::set_has_primary_epoch() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_rwr_set_primary_epochRequest::clear_has_primary_epoch() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_rwr_set_primary_epochRequest::clear_primary_epoch() { + primary_epoch_ = 0u; + clear_has_primary_epoch(); +} +inline ::google::protobuf::uint32 xtreemfs_rwr_set_primary_epochRequest::primary_epoch() const { + return primary_epoch_; +} +inline void xtreemfs_rwr_set_primary_epochRequest::set_primary_epoch(::google::protobuf::uint32 value) { + set_has_primary_epoch(); + primary_epoch_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_rwr_statusRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_rwr_statusRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_rwr_statusRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_rwr_statusRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_rwr_statusRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_rwr_statusRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_statusRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_statusRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_rwr_statusRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_rwr_statusRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_rwr_statusRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_rwr_statusRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_rwr_statusRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_rwr_statusRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_rwr_statusRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_statusRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_statusRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_rwr_statusRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_rwr_statusRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_rwr_statusRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 max_local_obj_version = 3; +inline bool xtreemfs_rwr_statusRequest::has_max_local_obj_version() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_rwr_statusRequest::set_has_max_local_obj_version() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_rwr_statusRequest::clear_has_max_local_obj_version() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_rwr_statusRequest::clear_max_local_obj_version() { + max_local_obj_version_ = GOOGLE_ULONGLONG(0); + clear_has_max_local_obj_version(); +} +inline ::google::protobuf::uint64 xtreemfs_rwr_statusRequest::max_local_obj_version() const { + return max_local_obj_version_; +} +inline void xtreemfs_rwr_statusRequest::set_max_local_obj_version(::google::protobuf::uint64 value) { + set_has_max_local_obj_version(); + max_local_obj_version_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_rwr_truncateRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_rwr_truncateRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_rwr_truncateRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_rwr_truncateRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_rwr_truncateRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_rwr_truncateRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_truncateRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_truncateRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_rwr_truncateRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_rwr_truncateRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_rwr_truncateRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_rwr_truncateRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_rwr_truncateRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_rwr_truncateRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_rwr_truncateRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_truncateRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_truncateRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_rwr_truncateRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_rwr_truncateRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_rwr_truncateRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 new_file_size = 3; +inline bool xtreemfs_rwr_truncateRequest::has_new_file_size() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_rwr_truncateRequest::set_has_new_file_size() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_rwr_truncateRequest::clear_has_new_file_size() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_rwr_truncateRequest::clear_new_file_size() { + new_file_size_ = GOOGLE_ULONGLONG(0); + clear_has_new_file_size(); +} +inline ::google::protobuf::uint64 xtreemfs_rwr_truncateRequest::new_file_size() const { + return new_file_size_; +} +inline void xtreemfs_rwr_truncateRequest::set_new_file_size(::google::protobuf::uint64 value) { + set_has_new_file_size(); + new_file_size_ = value; +} + +// required fixed64 object_version = 4; +inline bool xtreemfs_rwr_truncateRequest::has_object_version() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_rwr_truncateRequest::set_has_object_version() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_rwr_truncateRequest::clear_has_object_version() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_rwr_truncateRequest::clear_object_version() { + object_version_ = GOOGLE_ULONGLONG(0); + clear_has_object_version(); +} +inline ::google::protobuf::uint64 xtreemfs_rwr_truncateRequest::object_version() const { + return object_version_; +} +inline void xtreemfs_rwr_truncateRequest::set_object_version(::google::protobuf::uint64 value) { + set_has_object_version(); + object_version_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_rwr_updateRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_rwr_updateRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_rwr_updateRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_rwr_updateRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_rwr_updateRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_rwr_updateRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_updateRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_updateRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_rwr_updateRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_rwr_updateRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_rwr_updateRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_rwr_updateRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_rwr_updateRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_rwr_updateRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_rwr_updateRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_updateRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_updateRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_rwr_updateRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_rwr_updateRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_rwr_updateRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 new_file_size = 3; +inline bool xtreemfs_rwr_updateRequest::has_new_file_size() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_rwr_updateRequest::set_has_new_file_size() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_rwr_updateRequest::clear_has_new_file_size() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_rwr_updateRequest::clear_new_file_size() { + new_file_size_ = GOOGLE_ULONGLONG(0); + clear_has_new_file_size(); +} +inline ::google::protobuf::uint64 xtreemfs_rwr_updateRequest::new_file_size() const { + return new_file_size_; +} +inline void xtreemfs_rwr_updateRequest::set_new_file_size(::google::protobuf::uint64 value) { + set_has_new_file_size(); + new_file_size_ = value; +} + +// required fixed64 object_number = 7; +inline bool xtreemfs_rwr_updateRequest::has_object_number() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_rwr_updateRequest::set_has_object_number() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_rwr_updateRequest::clear_has_object_number() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_rwr_updateRequest::clear_object_number() { + object_number_ = GOOGLE_ULONGLONG(0); + clear_has_object_number(); +} +inline ::google::protobuf::uint64 xtreemfs_rwr_updateRequest::object_number() const { + return object_number_; +} +inline void xtreemfs_rwr_updateRequest::set_object_number(::google::protobuf::uint64 value) { + set_has_object_number(); + object_number_ = value; +} + +// required fixed64 object_version = 4; +inline bool xtreemfs_rwr_updateRequest::has_object_version() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void xtreemfs_rwr_updateRequest::set_has_object_version() { + _has_bits_[0] |= 0x00000010u; +} +inline void xtreemfs_rwr_updateRequest::clear_has_object_version() { + _has_bits_[0] &= ~0x00000010u; +} +inline void xtreemfs_rwr_updateRequest::clear_object_version() { + object_version_ = GOOGLE_ULONGLONG(0); + clear_has_object_version(); +} +inline ::google::protobuf::uint64 xtreemfs_rwr_updateRequest::object_version() const { + return object_version_; +} +inline void xtreemfs_rwr_updateRequest::set_object_version(::google::protobuf::uint64 value) { + set_has_object_version(); + object_version_ = value; +} + +// required fixed32 offset = 5; +inline bool xtreemfs_rwr_updateRequest::has_offset() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void xtreemfs_rwr_updateRequest::set_has_offset() { + _has_bits_[0] |= 0x00000020u; +} +inline void xtreemfs_rwr_updateRequest::clear_has_offset() { + _has_bits_[0] &= ~0x00000020u; +} +inline void xtreemfs_rwr_updateRequest::clear_offset() { + offset_ = 0u; + clear_has_offset(); +} +inline ::google::protobuf::uint32 xtreemfs_rwr_updateRequest::offset() const { + return offset_; +} +inline void xtreemfs_rwr_updateRequest::set_offset(::google::protobuf::uint32 value) { + set_has_offset(); + offset_ = value; +} + +// required .xtreemfs.pbrpc.ObjectData obj = 6; +inline bool xtreemfs_rwr_updateRequest::has_obj() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void xtreemfs_rwr_updateRequest::set_has_obj() { + _has_bits_[0] |= 0x00000040u; +} +inline void xtreemfs_rwr_updateRequest::clear_has_obj() { + _has_bits_[0] &= ~0x00000040u; +} +inline void xtreemfs_rwr_updateRequest::clear_obj() { + if (obj_ != NULL) obj_->::xtreemfs::pbrpc::ObjectData::Clear(); + clear_has_obj(); +} +inline const ::xtreemfs::pbrpc::ObjectData& xtreemfs_rwr_updateRequest::obj() const { + return obj_ != NULL ? *obj_ : *default_instance_->obj_; +} +inline ::xtreemfs::pbrpc::ObjectData* xtreemfs_rwr_updateRequest::mutable_obj() { + set_has_obj(); + if (obj_ == NULL) obj_ = new ::xtreemfs::pbrpc::ObjectData; + return obj_; +} +inline ::xtreemfs::pbrpc::ObjectData* xtreemfs_rwr_updateRequest::release_obj() { + clear_has_obj(); + ::xtreemfs::pbrpc::ObjectData* temp = obj_; + obj_ = NULL; + return temp; +} +inline void xtreemfs_rwr_updateRequest::set_allocated_obj(::xtreemfs::pbrpc::ObjectData* obj) { + delete obj_; + obj_ = obj; + if (obj) { + set_has_obj(); + } else { + clear_has_obj(); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_internal_get_gmaxRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_internal_get_gmaxRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_internal_get_gmaxRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_internal_get_gmaxRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_internal_get_gmaxRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_internal_get_gmaxRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_internal_get_gmaxRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_internal_get_gmaxRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_internal_get_gmaxRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_internal_get_gmaxRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_internal_get_gmaxRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_internal_get_gmaxRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_internal_get_gmaxRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_internal_get_gmaxRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_internal_get_gmaxRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_internal_get_gmaxRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_internal_get_gmaxRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_internal_get_gmaxRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_internal_get_gmaxRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_internal_get_gmaxRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_internal_get_file_sizeRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_internal_get_file_sizeRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_internal_get_file_sizeRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_internal_get_file_sizeRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_internal_get_file_sizeRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_internal_get_file_sizeRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_internal_get_file_sizeRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_internal_get_file_sizeRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_internal_get_file_sizeRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_internal_get_file_sizeRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_internal_get_file_sizeRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_internal_get_file_sizeRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_internal_get_file_sizeRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_internal_get_file_sizeRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_internal_get_file_sizeRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_internal_get_file_sizeRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_internal_get_file_sizeRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_internal_get_file_sizeRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_internal_get_file_sizeRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_internal_get_file_sizeRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_internal_get_file_sizeResponse + +// required fixed64 file_size = 1; +inline bool xtreemfs_internal_get_file_sizeResponse::has_file_size() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_internal_get_file_sizeResponse::set_has_file_size() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_internal_get_file_sizeResponse::clear_has_file_size() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_internal_get_file_sizeResponse::clear_file_size() { + file_size_ = GOOGLE_ULONGLONG(0); + clear_has_file_size(); +} +inline ::google::protobuf::uint64 xtreemfs_internal_get_file_sizeResponse::file_size() const { + return file_size_; +} +inline void xtreemfs_internal_get_file_sizeResponse::set_file_size(::google::protobuf::uint64 value) { + set_has_file_size(); + file_size_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_internal_read_localRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_internal_read_localRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_internal_read_localRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_internal_read_localRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_internal_read_localRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_internal_read_localRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_internal_read_localRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_internal_read_localRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_internal_read_localRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_internal_read_localRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_internal_read_localRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_internal_read_localRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_internal_read_localRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_internal_read_localRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_internal_read_localRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_internal_read_localRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_internal_read_localRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_internal_read_localRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_internal_read_localRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_internal_read_localRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed64 object_number = 3; +inline bool xtreemfs_internal_read_localRequest::has_object_number() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_internal_read_localRequest::set_has_object_number() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_internal_read_localRequest::clear_has_object_number() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_internal_read_localRequest::clear_object_number() { + object_number_ = GOOGLE_ULONGLONG(0); + clear_has_object_number(); +} +inline ::google::protobuf::uint64 xtreemfs_internal_read_localRequest::object_number() const { + return object_number_; +} +inline void xtreemfs_internal_read_localRequest::set_object_number(::google::protobuf::uint64 value) { + set_has_object_number(); + object_number_ = value; +} + +// required fixed64 object_version = 4; +inline bool xtreemfs_internal_read_localRequest::has_object_version() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void xtreemfs_internal_read_localRequest::set_has_object_version() { + _has_bits_[0] |= 0x00000008u; +} +inline void xtreemfs_internal_read_localRequest::clear_has_object_version() { + _has_bits_[0] &= ~0x00000008u; +} +inline void xtreemfs_internal_read_localRequest::clear_object_version() { + object_version_ = GOOGLE_ULONGLONG(0); + clear_has_object_version(); +} +inline ::google::protobuf::uint64 xtreemfs_internal_read_localRequest::object_version() const { + return object_version_; +} +inline void xtreemfs_internal_read_localRequest::set_object_version(::google::protobuf::uint64 value) { + set_has_object_version(); + object_version_ = value; +} + +// required fixed32 offset = 5; +inline bool xtreemfs_internal_read_localRequest::has_offset() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void xtreemfs_internal_read_localRequest::set_has_offset() { + _has_bits_[0] |= 0x00000010u; +} +inline void xtreemfs_internal_read_localRequest::clear_has_offset() { + _has_bits_[0] &= ~0x00000010u; +} +inline void xtreemfs_internal_read_localRequest::clear_offset() { + offset_ = 0u; + clear_has_offset(); +} +inline ::google::protobuf::uint32 xtreemfs_internal_read_localRequest::offset() const { + return offset_; +} +inline void xtreemfs_internal_read_localRequest::set_offset(::google::protobuf::uint32 value) { + set_has_offset(); + offset_ = value; +} + +// required fixed32 length = 6; +inline bool xtreemfs_internal_read_localRequest::has_length() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void xtreemfs_internal_read_localRequest::set_has_length() { + _has_bits_[0] |= 0x00000020u; +} +inline void xtreemfs_internal_read_localRequest::clear_has_length() { + _has_bits_[0] &= ~0x00000020u; +} +inline void xtreemfs_internal_read_localRequest::clear_length() { + length_ = 0u; + clear_has_length(); +} +inline ::google::protobuf::uint32 xtreemfs_internal_read_localRequest::length() const { + return length_; +} +inline void xtreemfs_internal_read_localRequest::set_length(::google::protobuf::uint32 value) { + set_has_length(); + length_ = value; +} + +// required bool attach_object_list = 7; +inline bool xtreemfs_internal_read_localRequest::has_attach_object_list() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void xtreemfs_internal_read_localRequest::set_has_attach_object_list() { + _has_bits_[0] |= 0x00000040u; +} +inline void xtreemfs_internal_read_localRequest::clear_has_attach_object_list() { + _has_bits_[0] &= ~0x00000040u; +} +inline void xtreemfs_internal_read_localRequest::clear_attach_object_list() { + attach_object_list_ = false; + clear_has_attach_object_list(); +} +inline bool xtreemfs_internal_read_localRequest::attach_object_list() const { + return attach_object_list_; +} +inline void xtreemfs_internal_read_localRequest::set_attach_object_list(bool value) { + set_has_attach_object_list(); + attach_object_list_ = value; +} + +// repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; +inline int xtreemfs_internal_read_localRequest::required_objects_size() const { + return required_objects_.size(); +} +inline void xtreemfs_internal_read_localRequest::clear_required_objects() { + required_objects_.Clear(); +} +inline const ::xtreemfs::pbrpc::ObjectList& xtreemfs_internal_read_localRequest::required_objects(int index) const { + return required_objects_.Get(index); +} +inline ::xtreemfs::pbrpc::ObjectList* xtreemfs_internal_read_localRequest::mutable_required_objects(int index) { + return required_objects_.Mutable(index); +} +inline ::xtreemfs::pbrpc::ObjectList* xtreemfs_internal_read_localRequest::add_required_objects() { + return required_objects_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectList >& +xtreemfs_internal_read_localRequest::required_objects() const { + return required_objects_; +} +inline ::google::protobuf::RepeatedPtrField< ::xtreemfs::pbrpc::ObjectList >* +xtreemfs_internal_read_localRequest::mutable_required_objects() { + return &required_objects_; +} + +// ------------------------------------------------------------------- + +// xtreemfs_internal_get_object_setRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_internal_get_object_setRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_internal_get_object_setRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_internal_get_object_setRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_internal_get_object_setRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_internal_get_object_setRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_internal_get_object_setRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_internal_get_object_setRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_internal_get_object_setRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_internal_get_object_setRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_internal_get_object_setRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_internal_get_object_setRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_internal_get_object_setRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_internal_get_object_setRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_internal_get_object_setRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_internal_get_object_setRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_internal_get_object_setRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_internal_get_object_setRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_internal_get_object_setRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_internal_get_object_setRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_internal_get_fileid_listResponse + +// repeated string file_ids = 1; +inline int xtreemfs_internal_get_fileid_listResponse::file_ids_size() const { + return file_ids_.size(); +} +inline void xtreemfs_internal_get_fileid_listResponse::clear_file_ids() { + file_ids_.Clear(); +} +inline const ::std::string& xtreemfs_internal_get_fileid_listResponse::file_ids(int index) const { + return file_ids_.Get(index); +} +inline ::std::string* xtreemfs_internal_get_fileid_listResponse::mutable_file_ids(int index) { + return file_ids_.Mutable(index); +} +inline void xtreemfs_internal_get_fileid_listResponse::set_file_ids(int index, const ::std::string& value) { + file_ids_.Mutable(index)->assign(value); +} +inline void xtreemfs_internal_get_fileid_listResponse::set_file_ids(int index, const char* value) { + file_ids_.Mutable(index)->assign(value); +} +inline void xtreemfs_internal_get_fileid_listResponse::set_file_ids(int index, const char* value, size_t size) { + file_ids_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_internal_get_fileid_listResponse::add_file_ids() { + return file_ids_.Add(); +} +inline void xtreemfs_internal_get_fileid_listResponse::add_file_ids(const ::std::string& value) { + file_ids_.Add()->assign(value); +} +inline void xtreemfs_internal_get_fileid_listResponse::add_file_ids(const char* value) { + file_ids_.Add()->assign(value); +} +inline void xtreemfs_internal_get_fileid_listResponse::add_file_ids(const char* value, size_t size) { + file_ids_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +xtreemfs_internal_get_fileid_listResponse::file_ids() const { + return file_ids_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +xtreemfs_internal_get_fileid_listResponse::mutable_file_ids() { + return &file_ids_; +} + +// ------------------------------------------------------------------- + +// lockRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool lockRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void lockRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void lockRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void lockRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& lockRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* lockRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* lockRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void lockRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required .xtreemfs.pbrpc.Lock lock_request = 2; +inline bool lockRequest::has_lock_request() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void lockRequest::set_has_lock_request() { + _has_bits_[0] |= 0x00000002u; +} +inline void lockRequest::clear_has_lock_request() { + _has_bits_[0] &= ~0x00000002u; +} +inline void lockRequest::clear_lock_request() { + if (lock_request_ != NULL) lock_request_->::xtreemfs::pbrpc::Lock::Clear(); + clear_has_lock_request(); +} +inline const ::xtreemfs::pbrpc::Lock& lockRequest::lock_request() const { + return lock_request_ != NULL ? *lock_request_ : *default_instance_->lock_request_; +} +inline ::xtreemfs::pbrpc::Lock* lockRequest::mutable_lock_request() { + set_has_lock_request(); + if (lock_request_ == NULL) lock_request_ = new ::xtreemfs::pbrpc::Lock; + return lock_request_; +} +inline ::xtreemfs::pbrpc::Lock* lockRequest::release_lock_request() { + clear_has_lock_request(); + ::xtreemfs::pbrpc::Lock* temp = lock_request_; + lock_request_ = NULL; + return temp; +} +inline void lockRequest::set_allocated_lock_request(::xtreemfs::pbrpc::Lock* lock_request) { + delete lock_request_; + lock_request_ = lock_request; + if (lock_request) { + set_has_lock_request(); + } else { + clear_has_lock_request(); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_pingMesssage + +// required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; +inline bool xtreemfs_pingMesssage::has_coordinates() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_pingMesssage::set_has_coordinates() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_pingMesssage::clear_has_coordinates() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_pingMesssage::clear_coordinates() { + if (coordinates_ != NULL) coordinates_->::xtreemfs::pbrpc::VivaldiCoordinates::Clear(); + clear_has_coordinates(); +} +inline const ::xtreemfs::pbrpc::VivaldiCoordinates& xtreemfs_pingMesssage::coordinates() const { + return coordinates_ != NULL ? *coordinates_ : *default_instance_->coordinates_; +} +inline ::xtreemfs::pbrpc::VivaldiCoordinates* xtreemfs_pingMesssage::mutable_coordinates() { + set_has_coordinates(); + if (coordinates_ == NULL) coordinates_ = new ::xtreemfs::pbrpc::VivaldiCoordinates; + return coordinates_; +} +inline ::xtreemfs::pbrpc::VivaldiCoordinates* xtreemfs_pingMesssage::release_coordinates() { + clear_has_coordinates(); + ::xtreemfs::pbrpc::VivaldiCoordinates* temp = coordinates_; + coordinates_ = NULL; + return temp; +} +inline void xtreemfs_pingMesssage::set_allocated_coordinates(::xtreemfs::pbrpc::VivaldiCoordinates* coordinates) { + delete coordinates_; + coordinates_ = coordinates; + if (coordinates) { + set_has_coordinates(); + } else { + clear_has_coordinates(); + } +} + +// required bool request_response = 2; +inline bool xtreemfs_pingMesssage::has_request_response() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_pingMesssage::set_has_request_response() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_pingMesssage::clear_has_request_response() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_pingMesssage::clear_request_response() { + request_response_ = false; + clear_has_request_response(); +} +inline bool xtreemfs_pingMesssage::request_response() const { + return request_response_; +} +inline void xtreemfs_pingMesssage::set_request_response(bool value) { + set_has_request_response(); + request_response_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_rwr_auth_stateRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_rwr_auth_stateRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_rwr_auth_stateRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_rwr_auth_stateRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_rwr_auth_stateRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_rwr_auth_stateRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_auth_stateRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_auth_stateRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_rwr_auth_stateRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_rwr_auth_stateRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_rwr_auth_stateRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_rwr_auth_stateRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_rwr_auth_stateRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_rwr_auth_stateRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_rwr_auth_stateRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_auth_stateRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_auth_stateRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_rwr_auth_stateRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_rwr_auth_stateRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_rwr_auth_stateRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; +inline bool xtreemfs_rwr_auth_stateRequest::has_state() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_rwr_auth_stateRequest::set_has_state() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_rwr_auth_stateRequest::clear_has_state() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_rwr_auth_stateRequest::clear_state() { + if (state_ != NULL) state_->::xtreemfs::pbrpc::AuthoritativeReplicaState::Clear(); + clear_has_state(); +} +inline const ::xtreemfs::pbrpc::AuthoritativeReplicaState& xtreemfs_rwr_auth_stateRequest::state() const { + return state_ != NULL ? *state_ : *default_instance_->state_; +} +inline ::xtreemfs::pbrpc::AuthoritativeReplicaState* xtreemfs_rwr_auth_stateRequest::mutable_state() { + set_has_state(); + if (state_ == NULL) state_ = new ::xtreemfs::pbrpc::AuthoritativeReplicaState; + return state_; +} +inline ::xtreemfs::pbrpc::AuthoritativeReplicaState* xtreemfs_rwr_auth_stateRequest::release_state() { + clear_has_state(); + ::xtreemfs::pbrpc::AuthoritativeReplicaState* temp = state_; + state_ = NULL; + return temp; +} +inline void xtreemfs_rwr_auth_stateRequest::set_allocated_state(::xtreemfs::pbrpc::AuthoritativeReplicaState* state) { + delete state_; + state_ = state; + if (state) { + set_has_state(); + } else { + clear_has_state(); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_rwr_reset_completeRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_rwr_reset_completeRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_rwr_reset_completeRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_rwr_reset_completeRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_rwr_reset_completeRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_rwr_reset_completeRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_reset_completeRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_rwr_reset_completeRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_rwr_reset_completeRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_rwr_reset_completeRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_rwr_reset_completeRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_rwr_reset_completeRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_rwr_reset_completeRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_rwr_reset_completeRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_rwr_reset_completeRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_reset_completeRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_rwr_reset_completeRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_rwr_reset_completeRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_rwr_reset_completeRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_rwr_reset_completeRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required fixed32 primary_epoch = 3; +inline bool xtreemfs_rwr_reset_completeRequest::has_primary_epoch() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void xtreemfs_rwr_reset_completeRequest::set_has_primary_epoch() { + _has_bits_[0] |= 0x00000004u; +} +inline void xtreemfs_rwr_reset_completeRequest::clear_has_primary_epoch() { + _has_bits_[0] &= ~0x00000004u; +} +inline void xtreemfs_rwr_reset_completeRequest::clear_primary_epoch() { + primary_epoch_ = 0u; + clear_has_primary_epoch(); +} +inline ::google::protobuf::uint32 xtreemfs_rwr_reset_completeRequest::primary_epoch() const { + return primary_epoch_; +} +inline void xtreemfs_rwr_reset_completeRequest::set_primary_epoch(::google::protobuf::uint32 value) { + set_has_primary_epoch(); + primary_epoch_ = value; +} + +// ------------------------------------------------------------------- + +// xtreemfs_xloc_set_invalidateRequest + +// required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; +inline bool xtreemfs_xloc_set_invalidateRequest::has_file_credentials() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_xloc_set_invalidateRequest::set_has_file_credentials() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_xloc_set_invalidateRequest::clear_has_file_credentials() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_xloc_set_invalidateRequest::clear_file_credentials() { + if (file_credentials_ != NULL) file_credentials_->::xtreemfs::pbrpc::FileCredentials::Clear(); + clear_has_file_credentials(); +} +inline const ::xtreemfs::pbrpc::FileCredentials& xtreemfs_xloc_set_invalidateRequest::file_credentials() const { + return file_credentials_ != NULL ? *file_credentials_ : *default_instance_->file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_xloc_set_invalidateRequest::mutable_file_credentials() { + set_has_file_credentials(); + if (file_credentials_ == NULL) file_credentials_ = new ::xtreemfs::pbrpc::FileCredentials; + return file_credentials_; +} +inline ::xtreemfs::pbrpc::FileCredentials* xtreemfs_xloc_set_invalidateRequest::release_file_credentials() { + clear_has_file_credentials(); + ::xtreemfs::pbrpc::FileCredentials* temp = file_credentials_; + file_credentials_ = NULL; + return temp; +} +inline void xtreemfs_xloc_set_invalidateRequest::set_allocated_file_credentials(::xtreemfs::pbrpc::FileCredentials* file_credentials) { + delete file_credentials_; + file_credentials_ = file_credentials; + if (file_credentials) { + set_has_file_credentials(); + } else { + clear_has_file_credentials(); + } +} + +// required string file_id = 2; +inline bool xtreemfs_xloc_set_invalidateRequest::has_file_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_xloc_set_invalidateRequest::set_has_file_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_xloc_set_invalidateRequest::clear_has_file_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_xloc_set_invalidateRequest::clear_file_id() { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + file_id_->clear(); + } + clear_has_file_id(); +} +inline const ::std::string& xtreemfs_xloc_set_invalidateRequest::file_id() const { + return *file_id_; +} +inline void xtreemfs_xloc_set_invalidateRequest::set_file_id(const ::std::string& value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_xloc_set_invalidateRequest::set_file_id(const char* value) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(value); +} +inline void xtreemfs_xloc_set_invalidateRequest::set_file_id(const char* value, size_t size) { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + file_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* xtreemfs_xloc_set_invalidateRequest::mutable_file_id() { + set_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + file_id_ = new ::std::string; + } + return file_id_; +} +inline ::std::string* xtreemfs_xloc_set_invalidateRequest::release_file_id() { + clear_has_file_id(); + if (file_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = file_id_; + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void xtreemfs_xloc_set_invalidateRequest::set_allocated_file_id(::std::string* file_id) { + if (file_id_ != &::google::protobuf::internal::kEmptyString) { + delete file_id_; + } + if (file_id) { + set_has_file_id(); + file_id_ = file_id; + } else { + clear_has_file_id(); + file_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// xtreemfs_xloc_set_invalidateResponse + +// required .xtreemfs.pbrpc.LeaseState lease_state = 1; +inline bool xtreemfs_xloc_set_invalidateResponse::has_lease_state() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void xtreemfs_xloc_set_invalidateResponse::set_has_lease_state() { + _has_bits_[0] |= 0x00000001u; +} +inline void xtreemfs_xloc_set_invalidateResponse::clear_has_lease_state() { + _has_bits_[0] &= ~0x00000001u; +} +inline void xtreemfs_xloc_set_invalidateResponse::clear_lease_state() { + lease_state_ = 0; + clear_has_lease_state(); +} +inline ::xtreemfs::pbrpc::LeaseState xtreemfs_xloc_set_invalidateResponse::lease_state() const { + return static_cast< ::xtreemfs::pbrpc::LeaseState >(lease_state_); +} +inline void xtreemfs_xloc_set_invalidateResponse::set_lease_state(::xtreemfs::pbrpc::LeaseState value) { + assert(::xtreemfs::pbrpc::LeaseState_IsValid(value)); + set_has_lease_state(); + lease_state_ = value; +} + +// optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; +inline bool xtreemfs_xloc_set_invalidateResponse::has_replica_status() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void xtreemfs_xloc_set_invalidateResponse::set_has_replica_status() { + _has_bits_[0] |= 0x00000002u; +} +inline void xtreemfs_xloc_set_invalidateResponse::clear_has_replica_status() { + _has_bits_[0] &= ~0x00000002u; +} +inline void xtreemfs_xloc_set_invalidateResponse::clear_replica_status() { + if (replica_status_ != NULL) replica_status_->::xtreemfs::pbrpc::ReplicaStatus::Clear(); + clear_has_replica_status(); +} +inline const ::xtreemfs::pbrpc::ReplicaStatus& xtreemfs_xloc_set_invalidateResponse::replica_status() const { + return replica_status_ != NULL ? *replica_status_ : *default_instance_->replica_status_; +} +inline ::xtreemfs::pbrpc::ReplicaStatus* xtreemfs_xloc_set_invalidateResponse::mutable_replica_status() { + set_has_replica_status(); + if (replica_status_ == NULL) replica_status_ = new ::xtreemfs::pbrpc::ReplicaStatus; + return replica_status_; +} +inline ::xtreemfs::pbrpc::ReplicaStatus* xtreemfs_xloc_set_invalidateResponse::release_replica_status() { + clear_has_replica_status(); + ::xtreemfs::pbrpc::ReplicaStatus* temp = replica_status_; + replica_status_ = NULL; + return temp; +} +inline void xtreemfs_xloc_set_invalidateResponse::set_allocated_replica_status(::xtreemfs::pbrpc::ReplicaStatus* replica_status) { + delete replica_status_; + replica_status_ = replica_status; + if (replica_status) { + set_has_replica_status(); + } else { + clear_has_replica_status(); + } +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace pbrpc +} // namespace xtreemfs + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::xtreemfs::pbrpc::OSDHealthResult>() { + return ::xtreemfs::pbrpc::OSDHealthResult_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_xtreemfs_2fOSD_2eproto__INCLUDED diff --git a/cpp/generated/xtreemfs/OSDServiceClient.h b/cpp/generated/xtreemfs/OSDServiceClient.h new file mode 100644 index 0000000..4729173 --- /dev/null +++ b/cpp/generated/xtreemfs/OSDServiceClient.h @@ -0,0 +1,838 @@ +//automatically generated from OSD.proto at Thu Dec 11 16:09:41 CET 2014 +//(c) 2014. See LICENSE file for details. + +#ifndef OSDSERVICECLIENT_H +#define OSDSERVICECLIENT_H + +#include +#include "pbrpc/RPC.pb.h" +#include "rpc/client.h" +#include "rpc/sync_callback.h" +#include "rpc/callback_interface.h" +#include "xtreemfs/OSD.pb.h" +#include "xtreemfs/MRC.pb.h" +#include "include/Common.pb.h" +#include "xtreemfs/GlobalTypes.pb.h" +#include "xtreemfs/DIR.pb.h" + + +namespace xtreemfs { +namespace pbrpc { + using ::xtreemfs::rpc::Client; + using ::xtreemfs::rpc::CallbackInterface; + using ::xtreemfs::rpc::SyncCallback; + + class OSDServiceClient { + + public: + OSDServiceClient(Client* client) : client_(client) { + } + + virtual ~OSDServiceClient() { + } + + void read(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::readRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 10, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ObjectData(), + context, callback); + } + + SyncCallback* read_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::readRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 10, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ObjectData(), + NULL, sync_cb); + return sync_cb; + } + + void truncate(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::truncateRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 11, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::OSDWriteResponse(), + context, callback); + } + + SyncCallback* truncate_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::truncateRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 11, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::OSDWriteResponse(), + NULL, sync_cb); + return sync_cb; + } + + void unlink(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::unlink_osd_Request* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 12, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* unlink_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::unlink_osd_Request* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 12, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void write(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::writeRequest* request,const char* data, uint32_t data_length, + CallbackInterface *callback, void *context = NULL) { + client_->sendRequest(address, 30001, 13, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::OSDWriteResponse(), + context, callback); + } + + SyncCallback* write_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::writeRequest* request, const char* data, uint32_t data_length) { + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 13, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::OSDWriteResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_broadcast_gmax(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_broadcast_gmaxRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 20, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_broadcast_gmax_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_broadcast_gmaxRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 20, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_check_object(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_check_objectRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 21, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ObjectData(), + context, callback); + } + + SyncCallback* xtreemfs_check_object_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_check_objectRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 21, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ObjectData(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_cleanup_get_results(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 30001, 30, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_cleanup_get_resultsResponse(), + context, callback); + } + + SyncCallback* xtreemfs_cleanup_get_results_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 30, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_cleanup_get_resultsResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_cleanup_is_running(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 30001, 31, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_cleanup_is_runningResponse(), + context, callback); + } + + SyncCallback* xtreemfs_cleanup_is_running_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 31, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_cleanup_is_runningResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_cleanup_start(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_cleanup_startRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 32, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_cleanup_start_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_cleanup_startRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 32, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_cleanup_status(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 30001, 33, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_cleanup_statusResponse(), + context, callback); + } + + SyncCallback* xtreemfs_cleanup_status_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 33, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_cleanup_statusResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_cleanup_stop(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 30001, 34, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_cleanup_stop_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 34, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_cleanup_versions_start(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 30001, 35, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_cleanup_versions_start_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 35, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_repair_object(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_repair_objectRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 36, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_repair_object_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_repair_objectRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 36, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_rwr_fetch(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_rwr_fetchRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 73, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ObjectData(), + context, callback); + } + + SyncCallback* xtreemfs_rwr_fetch_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_rwr_fetchRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 73, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ObjectData(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_rwr_flease_msg(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_rwr_flease_msgRequest* request,const char* data, uint32_t data_length, + CallbackInterface *callback, void *context = NULL) { + client_->sendRequest(address, 30001, 71, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_rwr_flease_msg_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_rwr_flease_msgRequest* request, const char* data, uint32_t data_length) { + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 71, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_rwr_notify(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::FileCredentials* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 75, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_rwr_notify_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::FileCredentials* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 75, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_rwr_set_primary_epoch(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_rwr_set_primary_epochRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 78, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ObjectData(), + context, callback); + } + + SyncCallback* xtreemfs_rwr_set_primary_epoch_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_rwr_set_primary_epochRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 78, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ObjectData(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_rwr_status(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_rwr_statusRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 76, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ReplicaStatus(), + context, callback); + } + + SyncCallback* xtreemfs_rwr_status_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_rwr_statusRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 76, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ReplicaStatus(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_rwr_truncate(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_rwr_truncateRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 74, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_rwr_truncate_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_rwr_truncateRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 74, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_rwr_update(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_rwr_updateRequest* request,const char* data, uint32_t data_length, + CallbackInterface *callback, void *context = NULL) { + client_->sendRequest(address, 30001, 72, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_rwr_update_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_rwr_updateRequest* request, const char* data, uint32_t data_length) { + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 72, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_rwr_auth_state(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_rwr_auth_stateRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 79, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_rwr_auth_state_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_rwr_auth_stateRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 79, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_rwr_reset_complete(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_rwr_reset_completeRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 80, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_rwr_reset_complete_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_rwr_reset_completeRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 80, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_internal_get_gmax(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_internal_get_gmaxRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 40, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::InternalGmax(), + context, callback); + } + + SyncCallback* xtreemfs_internal_get_gmax_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_internal_get_gmaxRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 40, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::InternalGmax(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_internal_truncate(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::truncateRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 41, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::OSDWriteResponse(), + context, callback); + } + + SyncCallback* xtreemfs_internal_truncate_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::truncateRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 41, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::OSDWriteResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_internal_get_file_size(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_internal_get_file_sizeRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 42, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_internal_get_file_sizeResponse(), + context, callback); + } + + SyncCallback* xtreemfs_internal_get_file_size_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_internal_get_file_sizeRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 42, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_internal_get_file_sizeResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_internal_read_local(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_internal_read_localRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 43, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::InternalReadLocalResponse(), + context, callback); + } + + SyncCallback* xtreemfs_internal_read_local_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_internal_read_localRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 43, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::InternalReadLocalResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_internal_get_object_set(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_internal_get_object_setRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 44, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ObjectList(), + context, callback); + } + + SyncCallback* xtreemfs_internal_get_object_set_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_internal_get_object_setRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 44, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::ObjectList(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_internal_get_fileid_list(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 30001, 45, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_internal_get_fileid_listResponse(), + context, callback); + } + + SyncCallback* xtreemfs_internal_get_fileid_list_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 45, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_internal_get_fileid_listResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_lock_acquire(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::lockRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 50, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::Lock(), + context, callback); + } + + SyncCallback* xtreemfs_lock_acquire_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::lockRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 50, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::Lock(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_lock_check(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::lockRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 51, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::Lock(), + context, callback); + } + + SyncCallback* xtreemfs_lock_check_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::lockRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 51, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::Lock(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_lock_release(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::lockRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 52, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_lock_release_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::lockRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 52, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_ping(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_pingMesssage* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 60, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_pingMesssage(), + context, callback); + } + + SyncCallback* xtreemfs_ping_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_pingMesssage* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 60, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_pingMesssage(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_shutdown(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + client_->sendRequest(address, 30001, 70, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_shutdown_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds) { + const char* data = NULL; uint32_t data_length = 0; + xtreemfs::pbrpc::emptyRequest* request = NULL; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 70, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_xloc_set_invalidate(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_xloc_set_invalidateRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 81, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_xloc_set_invalidateResponse(), + context, callback); + } + + SyncCallback* xtreemfs_xloc_set_invalidate_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_xloc_set_invalidateRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 81, + creds, auth, request, data, data_length, new xtreemfs::pbrpc::xtreemfs_xloc_set_invalidateResponse(), + NULL, sync_cb); + return sync_cb; + } + + void xtreemfs_rwr_auth_state_invalidated(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds, + const xtreemfs::pbrpc::xtreemfs_rwr_auth_stateRequest* request, + CallbackInterface *callback, void *context = NULL) { + const char* data = NULL; uint32_t data_length = 0; + client_->sendRequest(address, 30001, 82, + creds, auth, request, data, data_length, NULL, + context, callback); + } + + SyncCallback* xtreemfs_rwr_auth_state_invalidated_sync(const std::string &address, + const xtreemfs::pbrpc::Auth& auth, + const xtreemfs::pbrpc::UserCredentials &creds + , const xtreemfs::pbrpc::xtreemfs_rwr_auth_stateRequest* request) { + const char* data = NULL; uint32_t data_length = 0; + SyncCallback* sync_cb = new SyncCallback(); + client_->sendRequest(address, 30001, 82, + creds, auth, request, data, data_length, NULL, + NULL, sync_cb); + return sync_cb; + } + + private: + Client* client_; + }; + } +} +#endif //OSDSERVICECLIENT_H diff --git a/cpp/generated/xtreemfs/OSDServiceConstants.h b/cpp/generated/xtreemfs/OSDServiceConstants.h new file mode 100644 index 0000000..2204d25 --- /dev/null +++ b/cpp/generated/xtreemfs/OSDServiceConstants.h @@ -0,0 +1,51 @@ +//automatically generated from OSD.proto at Thu Dec 11 16:09:41 CET 2014 +//(c) 2014. See LICENSE file for details. + +#ifndef OSDSERVICECONSTANTS_H_ +#define OSDSERVICECONSTANTS_H_ +#include + +namespace xtreemfs { +namespace pbrpc { + +const uint32_t INTERFACE_ID_OSD = 30001; +const uint32_t PROC_ID_READ = 10; +const uint32_t PROC_ID_TRUNCATE = 11; +const uint32_t PROC_ID_UNLINK = 12; +const uint32_t PROC_ID_WRITE = 13; +const uint32_t PROC_ID_XTREEMFS_BROADCAST_GMAX = 20; +const uint32_t PROC_ID_XTREEMFS_CHECK_OBJECT = 21; +const uint32_t PROC_ID_XTREEMFS_CLEANUP_GET_RESULTS = 30; +const uint32_t PROC_ID_XTREEMFS_CLEANUP_IS_RUNNING = 31; +const uint32_t PROC_ID_XTREEMFS_CLEANUP_START = 32; +const uint32_t PROC_ID_XTREEMFS_CLEANUP_STATUS = 33; +const uint32_t PROC_ID_XTREEMFS_CLEANUP_STOP = 34; +const uint32_t PROC_ID_XTREEMFS_CLEANUP_VERSIONS_START = 35; +const uint32_t PROC_ID_XTREEMFS_REPAIR_OBJECT = 36; +const uint32_t PROC_ID_XTREEMFS_RWR_FETCH = 73; +const uint32_t PROC_ID_XTREEMFS_RWR_FLEASE_MSG = 71; +const uint32_t PROC_ID_XTREEMFS_RWR_NOTIFY = 75; +const uint32_t PROC_ID_XTREEMFS_RWR_SET_PRIMARY_EPOCH = 78; +const uint32_t PROC_ID_XTREEMFS_RWR_STATUS = 76; +const uint32_t PROC_ID_XTREEMFS_RWR_TRUNCATE = 74; +const uint32_t PROC_ID_XTREEMFS_RWR_UPDATE = 72; +const uint32_t PROC_ID_XTREEMFS_RWR_AUTH_STATE = 79; +const uint32_t PROC_ID_XTREEMFS_RWR_RESET_COMPLETE = 80; +const uint32_t PROC_ID_XTREEMFS_INTERNAL_GET_GMAX = 40; +const uint32_t PROC_ID_XTREEMFS_INTERNAL_TRUNCATE = 41; +const uint32_t PROC_ID_XTREEMFS_INTERNAL_GET_FILE_SIZE = 42; +const uint32_t PROC_ID_XTREEMFS_INTERNAL_READ_LOCAL = 43; +const uint32_t PROC_ID_XTREEMFS_INTERNAL_GET_OBJECT_SET = 44; +const uint32_t PROC_ID_XTREEMFS_INTERNAL_GET_FILEID_LIST = 45; +const uint32_t PROC_ID_XTREEMFS_LOCK_ACQUIRE = 50; +const uint32_t PROC_ID_XTREEMFS_LOCK_CHECK = 51; +const uint32_t PROC_ID_XTREEMFS_LOCK_RELEASE = 52; +const uint32_t PROC_ID_XTREEMFS_PING = 60; +const uint32_t PROC_ID_XTREEMFS_SHUTDOWN = 70; +const uint32_t PROC_ID_XTREEMFS_XLOC_SET_INVALIDATE = 81; +const uint32_t PROC_ID_XTREEMFS_RWR_AUTH_STATE_INVALIDATED = 82; + +} // namespace pbrpc +} // namespace xtreemfs + +#endif // OSDSERVICECLIENT_H_ diff --git a/cpp/generated/xtreemfs/get_request_message.cc b/cpp/generated/xtreemfs/get_request_message.cc new file mode 100644 index 0000000..f8ec99a --- /dev/null +++ b/cpp/generated/xtreemfs/get_request_message.cc @@ -0,0 +1,420 @@ +//automatically generated at Thu Dec 11 16:09:40 CET 2014 +//(c) 2014. See LICENSE file for details. + +#include "xtreemfs/get_request_message.h" + +#include "xtreemfs/OSD.pb.h" +#include "xtreemfs/MRC.pb.h" +#include "include/Common.pb.h" +#include "xtreemfs/GlobalTypes.pb.h" +#include "xtreemfs/DIR.pb.h" + +namespace xtreemfs { +namespace pbrpc { + +google::protobuf::Message* GetMessageForProcID(uint32_t interface_id, + uint32_t proc_id) { + switch (interface_id) { +// Generated from DIR.proto + case 10001: { + switch (proc_id) { + case 1: { + return new xtreemfs::pbrpc::addressMappingGetRequest(); + break; + } + case 2: { + return new xtreemfs::pbrpc::addressMappingGetRequest(); + break; + } + case 3: { + return new xtreemfs::pbrpc::AddressMappingSet(); + break; + } + case 4: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 5: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 6: { + return new xtreemfs::pbrpc::serviceDeregisterRequest(); + break; + } + case 7: { + return new xtreemfs::pbrpc::serviceGetByNameRequest(); + break; + } + case 8: { + return new xtreemfs::pbrpc::serviceGetByTypeRequest(); + break; + } + case 9: { + return new xtreemfs::pbrpc::serviceGetByUUIDRequest(); + break; + } + case 10: { + return new xtreemfs::pbrpc::serviceGetByUUIDRequest(); + break; + } + case 11: { + return new xtreemfs::pbrpc::serviceRegisterRequest(); + break; + } + case 20: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 21: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 22: { + return new xtreemfs::pbrpc::configurationGetRequest(); + break; + } + case 23: { + return new xtreemfs::pbrpc::Configuration(); + break; + } + case 24: { + return new xtreemfs::pbrpc::VivaldiCoordinates(); + break; + } + default: { + return NULL; + } + } + break; + } +// Generated from MRC.proto + case 20001: { + switch (proc_id) { + case 2: { + return new xtreemfs::pbrpc::fsetattrRequest(); + break; + } + case 3: { + return new xtreemfs::pbrpc::XCap(); + break; + } + case 4: { + return new xtreemfs::pbrpc::getattrRequest(); + break; + } + case 5: { + return new xtreemfs::pbrpc::getxattrRequest(); + break; + } + case 6: { + return new xtreemfs::pbrpc::linkRequest(); + break; + } + case 7: { + return new xtreemfs::pbrpc::listxattrRequest(); + break; + } + case 8: { + return new xtreemfs::pbrpc::mkdirRequest(); + break; + } + case 9: { + return new xtreemfs::pbrpc::openRequest(); + break; + } + case 10: { + return new xtreemfs::pbrpc::readdirRequest(); + break; + } + case 11: { + return new xtreemfs::pbrpc::readlinkRequest(); + break; + } + case 12: { + return new xtreemfs::pbrpc::removexattrRequest(); + break; + } + case 13: { + return new xtreemfs::pbrpc::renameRequest(); + break; + } + case 14: { + return new xtreemfs::pbrpc::rmdirRequest(); + break; + } + case 15: { + return new xtreemfs::pbrpc::setattrRequest(); + break; + } + case 16: { + return new xtreemfs::pbrpc::setxattrRequest(); + break; + } + case 17: { + return new xtreemfs::pbrpc::statvfsRequest(); + break; + } + case 18: { + return new xtreemfs::pbrpc::symlinkRequest(); + break; + } + case 19: { + return new xtreemfs::pbrpc::unlinkRequest(); + break; + } + case 20: { + return new xtreemfs::pbrpc::accessRequest(); + break; + } + case 30: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 31: { + return new xtreemfs::pbrpc::xtreemfs_check_file_existsRequest(); + break; + } + case 32: { + return new xtreemfs::pbrpc::xtreemfs_dump_restore_databaseRequest(); + break; + } + case 33: { + return new xtreemfs::pbrpc::xtreemfs_get_suitable_osdsRequest(); + break; + } + case 34: { + return new xtreemfs::pbrpc::stringMessage(); + break; + } + case 35: { + return new xtreemfs::pbrpc::xtreemfs_listdirRequest(); + break; + } + case 36: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 47: { + return new xtreemfs::pbrpc::Volume(); + break; + } + case 37: { + return new xtreemfs::pbrpc::XCap(); + break; + } + case 38: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 39: { + return new xtreemfs::pbrpc::xtreemfs_replica_addRequest(); + break; + } + case 40: { + return new xtreemfs::pbrpc::xtreemfs_replica_listRequest(); + break; + } + case 41: { + return new xtreemfs::pbrpc::xtreemfs_replica_removeRequest(); + break; + } + case 42: { + return new xtreemfs::pbrpc::xtreemfs_dump_restore_databaseRequest(); + break; + } + case 43: { + return new xtreemfs::pbrpc::xtreemfs_restore_fileRequest(); + break; + } + case 44: { + return new xtreemfs::pbrpc::xtreemfs_rmvolRequest(); + break; + } + case 45: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 46: { + return new xtreemfs::pbrpc::xtreemfs_update_file_sizeRequest(); + break; + } + case 48: { + return new xtreemfs::pbrpc::xtreemfs_set_replica_update_policyRequest(); + break; + } + case 49: { + return new xtreemfs::pbrpc::xtreemfs_set_read_only_xattrRequest(); + break; + } + case 50: { + return new xtreemfs::pbrpc::xtreemfs_get_file_credentialsRequest(); + break; + } + case 51: { + return new xtreemfs::pbrpc::xtreemfs_get_xlocsetRequest(); + break; + } + default: { + return NULL; + } + } + break; + } +// Generated from OSD.proto + case 30001: { + switch (proc_id) { + case 10: { + return new xtreemfs::pbrpc::readRequest(); + break; + } + case 11: { + return new xtreemfs::pbrpc::truncateRequest(); + break; + } + case 12: { + return new xtreemfs::pbrpc::unlink_osd_Request(); + break; + } + case 13: { + return new xtreemfs::pbrpc::writeRequest(); + break; + } + case 20: { + return new xtreemfs::pbrpc::xtreemfs_broadcast_gmaxRequest(); + break; + } + case 21: { + return new xtreemfs::pbrpc::xtreemfs_check_objectRequest(); + break; + } + case 30: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 31: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 32: { + return new xtreemfs::pbrpc::xtreemfs_cleanup_startRequest(); + break; + } + case 33: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 34: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 35: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 36: { + return new xtreemfs::pbrpc::xtreemfs_repair_objectRequest(); + break; + } + case 73: { + return new xtreemfs::pbrpc::xtreemfs_rwr_fetchRequest(); + break; + } + case 71: { + return new xtreemfs::pbrpc::xtreemfs_rwr_flease_msgRequest(); + break; + } + case 75: { + return new xtreemfs::pbrpc::FileCredentials(); + break; + } + case 78: { + return new xtreemfs::pbrpc::xtreemfs_rwr_set_primary_epochRequest(); + break; + } + case 76: { + return new xtreemfs::pbrpc::xtreemfs_rwr_statusRequest(); + break; + } + case 74: { + return new xtreemfs::pbrpc::xtreemfs_rwr_truncateRequest(); + break; + } + case 72: { + return new xtreemfs::pbrpc::xtreemfs_rwr_updateRequest(); + break; + } + case 79: { + return new xtreemfs::pbrpc::xtreemfs_rwr_auth_stateRequest(); + break; + } + case 80: { + return new xtreemfs::pbrpc::xtreemfs_rwr_reset_completeRequest(); + break; + } + case 40: { + return new xtreemfs::pbrpc::xtreemfs_internal_get_gmaxRequest(); + break; + } + case 41: { + return new xtreemfs::pbrpc::truncateRequest(); + break; + } + case 42: { + return new xtreemfs::pbrpc::xtreemfs_internal_get_file_sizeRequest(); + break; + } + case 43: { + return new xtreemfs::pbrpc::xtreemfs_internal_read_localRequest(); + break; + } + case 44: { + return new xtreemfs::pbrpc::xtreemfs_internal_get_object_setRequest(); + break; + } + case 45: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 50: { + return new xtreemfs::pbrpc::lockRequest(); + break; + } + case 51: { + return new xtreemfs::pbrpc::lockRequest(); + break; + } + case 52: { + return new xtreemfs::pbrpc::lockRequest(); + break; + } + case 60: { + return new xtreemfs::pbrpc::xtreemfs_pingMesssage(); + break; + } + case 70: { + return new xtreemfs::pbrpc::emptyRequest(); + break; + } + case 81: { + return new xtreemfs::pbrpc::xtreemfs_xloc_set_invalidateRequest(); + break; + } + case 82: { + return new xtreemfs::pbrpc::xtreemfs_rwr_auth_stateRequest(); + break; + } + default: { + return NULL; + } + } + break; + } + default: { + return NULL; + } + } +} + +} // namespace pbrpc +} // namespace xtreemfs diff --git a/cpp/generated/xtreemfs/get_request_message.h b/cpp/generated/xtreemfs/get_request_message.h new file mode 100644 index 0000000..2ad1b02 --- /dev/null +++ b/cpp/generated/xtreemfs/get_request_message.h @@ -0,0 +1,24 @@ +//automatically generated at Thu Dec 11 16:09:40 CET 2014 +//(c) 2014. See LICENSE file for details. + +#ifndef CPP_GENERATED_XTREEMFS_GET_REQUEST_MESSAGE_H_ +#define CPP_GENERATED_XTREEMFS_GET_REQUEST_MESSAGE_H_ + +#include + +namespace google { +namespace protobuf { +class Message; +} // namespace protobuf +} // namespace google + +namespace xtreemfs { +namespace pbrpc { + +google::protobuf::Message* GetMessageForProcID(uint32_t interface_id, + uint32_t proc_id); + +} // namespace pbrpc +} // namespace xtreemfs + +#endif // CPP_GENERATED_XTREEMFS_GET_REQUEST_MESSAGE_H_ diff --git a/cpp/include/cbfs/cbfs_adapter.h b/cpp/include/cbfs/cbfs_adapter.h new file mode 100644 index 0000000..dd2a5a3 --- /dev/null +++ b/cpp/include/cbfs/cbfs_adapter.h @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +#ifndef CPP_INCLUDE_CBFS_CBFS_ADAPTER_H_ +#define CPP_INCLUDE_CBFS_CBFS_ADAPTER_H_ + +#define WIN32_LEAN_AND_MEAN +#include // required for CbFS.h + +#include +#include +#include +#include +#include + +#include "xtfsutil/xtfsutil_server.h" +#include "xtreemfs/GlobalTypes.pb.h" + +namespace xtreemfs { + +namespace pbrpc { +class Stat; +} // namespace pbrpc + +class CbFSOptions; +class Client; +class SystemUserMapping; + +class CbFSAdapter { + public: + /** Replace "\" path separator by "/" and convert UTF-16 to UTF-8. */ + static std::string WindowsPathToUTF8Unix(const wchar_t* from); + + static void DebugPrintCreateFile( + LPCWSTR OperationType, + LPCTSTR FileName, + ACCESS_MASK DesiredAccess, + DWORD FileAttributes, + DWORD ShareMode, + PVOID FileHandleContext); + + /** Creates a new instance of CbFSAdapter, but does not create any + * libxtreemfs Client yet. + * + * Use Start() to actually create the client and mount the volume given in + * options. May modify options. + */ + explicit CbFSAdapter(CbFSOptions* options); + + ~CbFSAdapter(); + + /** Create client, open volume and start needed threads. */ + void Start(); + + /** Shutdown threads, close Volume and Client and blocks until all threads + * are stopped. */ + void Stop(); + + /** Same as Stop(), but does not call cbfs_.UnmountMedia(). */ + void StopWithoutUnmount(); + + void GetVolumeSize(CallbackFileSystem* Sender, + __int64* TotalNumberOfSectors, + __int64* NumberOfFreeSectors); + + void GetVolumeLabel(CallbackFileSystem* Sender, LPTSTR VolumeLabel); + + void GetVolumeId(CallbackFileSystem* Sender, PDWORD VolumeID); + + void CreateFile(CallbackFileSystem* Sender, + LPCTSTR FileName, + ACCESS_MASK DesiredAccess, + DWORD FileAttributes, + DWORD ShareMode, + PVOID* FileHandleContext); + + void OpenFile(CallbackFileSystem* Sender, + LPCTSTR FileName, + ACCESS_MASK DesiredAccess, + DWORD ShareMode, + PVOID* FileHandleContext); + + void CloseFile(CallbackFileSystem* Sender, + CbFsFileInfo* FileInfo, + PVOID FileHandleContext); + + void GetFileInfo(CallbackFileSystem* Sender, + LPCTSTR FileName, + LPBOOL FileExists, + PFILETIME CreationTime, + PFILETIME LastAccessTime, + PFILETIME LastWriteTime, + __int64* EndOfFile, + __int64* AllocationSize, + __int64* FileId, + PDWORD FileAttributes, + LPTSTR LongFileName OPTIONAL, + PWORD LongFileNameLength OPTIONAL); + + void EnumerateDirectory(CallbackFileSystem* Sender, + CbFsFileInfo* DirectoryInfo, + PVOID* EnumerationContext, + LPCTSTR Mask, + INT Index, + BOOL Restart, + LPBOOL FileFound, + LPTSTR FileName, + PDWORD FileNameLength, + LPTSTR ShortFileName OPTIONAL, + PUCHAR ShortFileNameLength OPTIONAL, + PFILETIME CreationTime, + PFILETIME LastAccessTime, + PFILETIME LastWriteTime, + __int64* EndOfFile, + __int64* AllocationSize, + __int64* FileId, + PDWORD FileAttributes); + + void CloseEnumeration(CallbackFileSystem* Sender, + CbFsFileInfo* DirectoryInfo, + PVOID EnumerationContext); + + void SetAllocationSize(CallbackFileSystem* Sender, + CbFsFileInfo* FileInfo, + PVOID FileHandleContext, + __int64 AllocationSize); + + void SetEndOfFile(CallbackFileSystem* Sender, + CbFsFileInfo* FileInfo, + PVOID FileHandleContext, + __int64 EndOfFile); + + void SetFileAttributes(CallbackFileSystem* Sender, + CbFsFileInfo* FileInfo, + PVOID FileHandleContext, + PFILETIME CreationTime, + PFILETIME LastAccessTime, + PFILETIME LastWriteTime, + DWORD FileAttributes); + + void CanFileBeDeleted(CallbackFileSystem* Sender, + CbFsFileInfo* FileInfo, + BOOL* CanBeDeleted); + + void DeleteFile(CallbackFileSystem* Sender, CbFsFileInfo* FileInfo); + + void RenameOrMoveFile(CallbackFileSystem* Sender, + CbFsFileInfo* FileInfo, + LPCTSTR NewFileName); + + void ReadFile(CallbackFileSystem* Sender, + CbFsFileInfo* FileInfo, + PVOID FileHandleContext, + __int64 Position, + PVOID Buffer, + DWORD BytesToRead, + PDWORD BytesRead); + + void WriteFile(CallbackFileSystem* Sender, + CbFsFileInfo* FileInfo, + PVOID FileHandleContext, + __int64 Position, + PVOID Buffer, + DWORD BytesToWrite, + PDWORD BytesWritten); + + void IsDirectoryEmpty(CallbackFileSystem* Sender, + LPWSTR FileName, + LPBOOL IsEmpty); + + void StorageEjected(CallbackFileSystem* Sender); + + /** Blocks until device was ejected by user. */ + void WaitForEjection(); + + private: + static const DWORD kMaxFileNameLength = 32767; + + static const size_t kMaxVolumeLabelLength = 32; + + /** Print debug output to stdout. */ + static void DbgPrint(LPCWSTR format, ...); + + /** Output exception thrown by CBFS as string. */ + static std::string ECBFSErrorToString(ECBFSError& e); + + /** Maps XtreemFS return values to Windows specific ones. */ + static int ConvertXtreemFSErrnoToWindows( + xtreemfs::pbrpc::POSIXErrno xtreemfs_errno); + + /** Convert UNIX timestamp (in nanoseconds) to Windows time format. */ + static void XtreemFSTimeToWinTime(uint64_t utime_ns, + DWORD* lower, + DWORD* upper); + + /** Convert Windows timestamp to UNIX timestamp (in nanoseconds). */ + static boost::uint64_t ConvertWinTimeToXtreemFSTime(DWORD lower, + DWORD upper); + + /** Returns true if "stat" is a directory. */ + static bool IsDirectory(const xtreemfs::pbrpc::Stat& stat); + + /** Convert "desired_access", passed at Create and Open, to e.g., O_RDWR. */ + static xtreemfs::pbrpc::SYSTEM_V_FCNTL ConvertFlagsWindowsToXtreemFS( + const ACCESS_MASK desired_access); + + /** Provides the CBFS library the required license key. */ + void SetRegistrationKey(); + + /** Returns true if "path" is a directory. + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * @throws UnknownAddressSchemeException + */ + bool IsDirectory(const std::string& path); + + /** Same as GetFileInfo(), except that "path" is an UTF8 encoded UNIX path. */ + void ConvertXtreemFSStatToCbFS(const xtreemfs::pbrpc::Stat& stat, + PFILETIME CreationTime, + PFILETIME LastAccessTime, + PFILETIME LastWriteTime, + __int64* EndOfFile, + __int64* AllocationSize, + __int64* FileId, + PDWORD FileAttributes, + LPTSTR LongFileName OPTIONAL, + PWORD LongFileNameLength OPTIONAL); + + /** Contains all needed options to mount the requested volume. */ + CbFSOptions* options_; + + /** Volume Label generated from the given XtreemFS URL. */ + std::wstring volume_label_; + + /** The chosen UserMapping provides methods to translate between local and + * remote usernames and groups. */ + boost::scoped_ptr system_user_mapping_; + + /** Username and domain name of user executing the Dokan client. Will be used + * by all XtreemFS operations. */ + xtreemfs::pbrpc::UserCredentials user_credentials_; + + /** Created libxtreemfs Client. */ + boost::scoped_ptr client_; + + /** Opened libxtreemfs Volume. */ + Volume* volume_; + + /** Server for processing commands sent from the xtfsutil tool + via xctl files. */ + XtfsUtilServer xctl_; + + /** Callback Filesystem instance which provides a Windows user space + * file system interface. */ + CallbackFileSystem cbfs_; + + /** True if device was ejected by user. */ + bool device_ejected_; + + /** Guards device_ejected_. */ + boost::mutex device_ejected_mutex_; + + /** Used when waiting for a change of device_ejected_. */ + boost::condition device_ejected_cond_; +}; + +} // namespace xtreemfs + +#endif // CPP_INCLUDE_CBFS_CBFS_ADAPTER_H_ diff --git a/cpp/include/cbfs/cbfs_enumeration_context.h b/cpp/include/cbfs/cbfs_enumeration_context.h new file mode 100644 index 0000000..dc10302 --- /dev/null +++ b/cpp/include/cbfs/cbfs_enumeration_context.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +#ifndef CPP_INCLUDE_CBFS_CBFS_ENUMERATION_CONTEXT_H_ +#define CPP_INCLUDE_CBFS_CBFS_ENUMERATION_CONTEXT_H_ + +#include + +namespace xtreemfs { + +namespace pbrpc { + +class DirectoryEntries; + +} // namespace pbrpc + +struct CbFSEnumerationContext { + CbFSEnumerationContext(); + + ~CbFSEnumerationContext(); + + /** Index in the complete directory listing where dir_entries starts. */ + boost::uint64_t offset; + xtreemfs::pbrpc::DirectoryEntries* dir_entries; + /** Index of next entry which will be returned from dir_entries (starting from + * 0). + * + * @attention This is relative to dir_entries, not to the complete dir. + */ + int next_index; +}; + +} // namespace xtreemfs + +#endif // CPP_INCLUDE_CBFS_CBFS_ENUMERATION_CONTEXT_H_ diff --git a/cpp/include/cbfs/cbfs_options.h b/cpp/include/cbfs/cbfs_options.h new file mode 100644 index 0000000..b2d8115 --- /dev/null +++ b/cpp/include/cbfs/cbfs_options.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +#ifndef CPP_INCLUDE_CBFS_CBFS_OPTIONS_H_ +#define CPP_INCLUDE_CBFS_CBFS_OPTIONS_H_ + +#include "libxtreemfs/options.h" + +#include +#include +#include + +namespace xtreemfs { + +class CbFSOptions : public Options { + public: + /** Sets the default values. */ + CbFSOptions(); + + /** Set options parsed from command line which must contain at least the URL + * to a XtreemFS volume and a mount point. + * + * Calls Options::ParseCommandLine() to parse general options. + * + * @throws InvalidCommandLineParametersException + * @throws InvalidURLException */ + void ParseCommandLine(int argc, char** argv); + + /** Shows only the minimal help text describing the usage of mount.xtreemfs.*/ + std::string ShowCommandLineUsage(); + + /** Outputs usage of the command line parameters. */ + virtual std::string ShowCommandLineHelp(); + + // CbFS options. + + private: + /** Contains all available CbFS options and its descriptions. */ + boost::program_options::options_description cbfs_descriptions_; + + /** Brief help text if there are no command line arguments. */ + std::string helptext_usage_; +}; + +} // namespace xtreemfs + +#endif // CPP_INCLUDE_CBFS_CBFS_OPTIONS_H_ diff --git a/cpp/include/fuse/cached_directory_entries.h b/cpp/include/fuse/cached_directory_entries.h new file mode 100644 index 0000000..729246b --- /dev/null +++ b/cpp/include/fuse/cached_directory_entries.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +#ifndef CPP_INCLUDE_FUSE_CACHED_DIRECTORY_ENTRIES_H_ +#define CPP_INCLUDE_FUSE_CACHED_DIRECTORY_ENTRIES_H_ + +#include + +#include + +namespace xtreemfs { + +namespace pbrpc { + +class DirectoryEntries; + +} // namespace pbrpc + +struct CachedDirectoryEntries { + uint64_t offset; + xtreemfs::pbrpc::DirectoryEntries* dir_entries; + boost::mutex mutex; +}; + +} // namespace xtreemfs + +#endif // CPP_INCLUDE_FUSE_CACHED_DIRECTORY_ENTRIES_H_ diff --git a/cpp/include/fuse/fuse_adapter.h b/cpp/include/fuse/fuse_adapter.h new file mode 100644 index 0000000..b00de48 --- /dev/null +++ b/cpp/include/fuse/fuse_adapter.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +#ifndef CPP_INCLUDE_FUSE_FUSE_ADAPTER_H_ +#define CPP_INCLUDE_FUSE_FUSE_ADAPTER_H_ + +#include +#define FUSE_USE_VERSION 26 +#include + +#include +#include +#include + +#include "libxtreemfs/system_user_mapping_unix.h" +#include "xtfsutil/xtfsutil_server.h" +#include "xtreemfs/GlobalTypes.pb.h" + +namespace xtreemfs { +class Client; +class FuseOptions; +class UserMapping; +class Volume; + +namespace pbrpc { +class Stat; +class UserCredentials; +} // namespace pbrpc + +/** Uses fuse_interrupted() to check if an operation was cancelled by the user + * and stops retrying to execute the request then. + * + * Always returns 0, if called from a non-Fuse thread. */ +int CheckIfOperationInterrupted(); + +class FuseAdapter { + public: + /** Creates a new instance of FuseAdapter, but does not create any libxtreemfs + * Client yet. + * + * Use Start() to actually create the client and mount the volume given in + * options. May modify options. + */ + explicit FuseAdapter(FuseOptions* options); + + ~FuseAdapter(); + + /** Create client, open volume and start needed threads. + * @return Returns a list of additional "-o

overrides the installation prefix + --exec-prefix= overrides the executable installation prefix + --libdir= overrides the library installation prefix + --includedir= overrides the header file installation prefix + + Installation Queries: + --prefix installation prefix + --exec-prefix executable installation prefix + --libdir library installation directory + --includedir header file installation directory + --version the version of the Google Test installation + + Version Queries: + --min-version=VERSION return 0 if the version is at least VERSION + --exact-version=VERSION return 0 if the version is exactly VERSION + --max-version=VERSION return 0 if the version is at most VERSION + + Compilation Flag Queries: + --cppflags compile flags specific to the C-like preprocessors + --cxxflags compile flags appropriate for C++ programs + --ldflags linker flags + --libs libraries for linking + +EOF +} + +# This function bounds our version with a min and a max. It uses some clever +# POSIX-compliant variable expansion to portably do all the work in the shell +# and avoid any dependency on a particular "sed" or "awk" implementation. +# Notable is that it will only ever compare the first 3 components of versions. +# Further components will be cleanly stripped off. All versions must be +# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and +# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should +# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than +# continuing to maintain our own shell version. +check_versions() +{ + major_version=${version%%.*} + minor_version="0" + point_version="0" + if test "${version#*.}" != "${version}"; then + minor_version=${version#*.} + minor_version=${minor_version%%.*} + fi + if test "${version#*.*.}" != "${version}"; then + point_version=${version#*.*.} + point_version=${point_version%%.*} + fi + + min_version="$1" + min_major_version=${min_version%%.*} + min_minor_version="0" + min_point_version="0" + if test "${min_version#*.}" != "${min_version}"; then + min_minor_version=${min_version#*.} + min_minor_version=${min_minor_version%%.*} + fi + if test "${min_version#*.*.}" != "${min_version}"; then + min_point_version=${min_version#*.*.} + min_point_version=${min_point_version%%.*} + fi + + max_version="$2" + max_major_version=${max_version%%.*} + max_minor_version="0" + max_point_version="0" + if test "${max_version#*.}" != "${max_version}"; then + max_minor_version=${max_version#*.} + max_minor_version=${max_minor_version%%.*} + fi + if test "${max_version#*.*.}" != "${max_version}"; then + max_point_version=${max_version#*.*.} + max_point_version=${max_point_version%%.*} + fi + + test $(($major_version)) -lt $(($min_major_version)) && exit 1 + if test $(($major_version)) -eq $(($min_major_version)); then + test $(($minor_version)) -lt $(($min_minor_version)) && exit 1 + if test $(($minor_version)) -eq $(($min_minor_version)); then + test $(($point_version)) -lt $(($min_point_version)) && exit 1 + fi + fi + + test $(($major_version)) -gt $(($max_major_version)) && exit 1 + if test $(($major_version)) -eq $(($max_major_version)); then + test $(($minor_version)) -gt $(($max_minor_version)) && exit 1 + if test $(($minor_version)) -eq $(($max_minor_version)); then + test $(($point_version)) -gt $(($max_point_version)) && exit 1 + fi + fi + + exit 0 +} + +# Show the usage line when no arguments are specified. +if test $# -eq 0; then + show_usage + exit 1 +fi + +while test $# -gt 0; do + case $1 in + --usage) show_usage; exit 0;; + --help) show_help; exit 0;; + + # Installation overrides + --prefix=*) GTEST_PREFIX=${1#--prefix=};; + --exec-prefix=*) GTEST_EXEC_PREFIX=${1#--exec-prefix=};; + --libdir=*) GTEST_LIBDIR=${1#--libdir=};; + --includedir=*) GTEST_INCLUDEDIR=${1#--includedir=};; + + # Installation queries + --prefix|--exec-prefix|--libdir|--includedir|--version) + if test -n "${do_query}"; then + show_usage + exit 1 + fi + do_query=${1#--} + ;; + + # Version checking + --min-version=*) + do_check_versions=yes + min_version=${1#--min-version=} + ;; + --max-version=*) + do_check_versions=yes + max_version=${1#--max-version=} + ;; + --exact-version=*) + do_check_versions=yes + exact_version=${1#--exact-version=} + ;; + + # Compiler flag output + --cppflags) echo_cppflags=yes;; + --cxxflags) echo_cxxflags=yes;; + --ldflags) echo_ldflags=yes;; + --libs) echo_libs=yes;; + + # Everything else is an error + *) show_usage; exit 1;; + esac + shift +done + +# These have defaults filled in by the configure script but can also be +# overridden by environment variables or command line parameters. +prefix="${GTEST_PREFIX:-@prefix@}" +exec_prefix="${GTEST_EXEC_PREFIX:-@exec_prefix@}" +libdir="${GTEST_LIBDIR:-@libdir@}" +includedir="${GTEST_INCLUDEDIR:-@includedir@}" + +# We try and detect if our binary is not located at its installed location. If +# it's not, we provide variables pointing to the source and build tree rather +# than to the install tree. This allows building against a just-built gtest +# rather than an installed gtest. +bindir="@bindir@" +this_relative_bindir=`dirname $0` +this_bindir=`cd ${this_relative_bindir}; pwd -P` +if test "${this_bindir}" = "${this_bindir%${bindir}}"; then + # The path to the script doesn't end in the bindir sequence from Autoconf, + # assume that we are in a build tree. + build_dir=`dirname ${this_bindir}` + src_dir=`cd ${this_bindir}; cd @top_srcdir@; pwd -P` + + # TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we + # should work to remove it, and/or remove libtool altogether, replacing it + # with direct references to the library and a link path. + gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@" + gtest_ldflags="" + + # We provide hooks to include from either the source or build dir, where the + # build dir is always preferred. This will potentially allow us to write + # build rules for generated headers and have them automatically be preferred + # over provided versions. + gtest_cppflags="-I${build_dir}/include -I${src_dir}/include" + gtest_cxxflags="@PTHREAD_CFLAGS@" +else + # We're using an installed gtest, although it may be staged under some + # prefix. Assume (as our own libraries do) that we can resolve the prefix, + # and are present in the dynamic link paths. + gtest_ldflags="-L${libdir}" + gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@" + gtest_cppflags="-I${includedir}" + gtest_cxxflags="@PTHREAD_CFLAGS@" +fi + +# Do an installation query if requested. +if test -n "$do_query"; then + case $do_query in + prefix) echo $prefix; exit 0;; + exec-prefix) echo $exec_prefix; exit 0;; + libdir) echo $libdir; exit 0;; + includedir) echo $includedir; exit 0;; + version) echo $version; exit 0;; + *) show_usage; exit 1;; + esac +fi + +# Do a version check if requested. +if test "$do_check_versions" = "yes"; then + # Make sure we didn't receive a bad combination of parameters. + test "$echo_cppflags" = "yes" && show_usage && exit 1 + test "$echo_cxxflags" = "yes" && show_usage && exit 1 + test "$echo_ldflags" = "yes" && show_usage && exit 1 + test "$echo_libs" = "yes" && show_usage && exit 1 + + if test "$exact_version" != ""; then + check_versions $exact_version $exact_version + # unreachable + else + check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999} + # unreachable + fi +fi + +# Do the output in the correct order so that these can be used in-line of +# a compiler invocation. +output="" +test "$echo_cppflags" = "yes" && output="$output $gtest_cppflags" +test "$echo_cxxflags" = "yes" && output="$output $gtest_cxxflags" +test "$echo_ldflags" = "yes" && output="$output $gtest_ldflags" +test "$echo_libs" = "yes" && output="$output $gtest_libs" +echo $output + +exit 0 diff --git a/cpp/thirdparty/gtest-1.7.0/scripts/pump.py b/cpp/thirdparty/gtest-1.7.0/scripts/pump.py new file mode 100755 index 0000000..5efb653 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/scripts/pump.py @@ -0,0 +1,855 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""pump v0.2.0 - Pretty Useful for Meta Programming. + +A tool for preprocessor meta programming. Useful for generating +repetitive boilerplate code. Especially useful for writing C++ +classes, functions, macros, and templates that need to work with +various number of arguments. + +USAGE: + pump.py SOURCE_FILE + +EXAMPLES: + pump.py foo.cc.pump + Converts foo.cc.pump to foo.cc. + +GRAMMAR: + CODE ::= ATOMIC_CODE* + ATOMIC_CODE ::= $var ID = EXPRESSION + | $var ID = [[ CODE ]] + | $range ID EXPRESSION..EXPRESSION + | $for ID SEPARATOR [[ CODE ]] + | $($) + | $ID + | $(EXPRESSION) + | $if EXPRESSION [[ CODE ]] ELSE_BRANCH + | [[ CODE ]] + | RAW_CODE + SEPARATOR ::= RAW_CODE | EMPTY + ELSE_BRANCH ::= $else [[ CODE ]] + | $elif EXPRESSION [[ CODE ]] ELSE_BRANCH + | EMPTY + EXPRESSION has Python syntax. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sys + + +TOKEN_TABLE = [ + (re.compile(r'\$var\s+'), '$var'), + (re.compile(r'\$elif\s+'), '$elif'), + (re.compile(r'\$else\s+'), '$else'), + (re.compile(r'\$for\s+'), '$for'), + (re.compile(r'\$if\s+'), '$if'), + (re.compile(r'\$range\s+'), '$range'), + (re.compile(r'\$[_A-Za-z]\w*'), '$id'), + (re.compile(r'\$\(\$\)'), '$($)'), + (re.compile(r'\$'), '$'), + (re.compile(r'\[\[\n?'), '[['), + (re.compile(r'\]\]\n?'), ']]'), + ] + + +class Cursor: + """Represents a position (line and column) in a text file.""" + + def __init__(self, line=-1, column=-1): + self.line = line + self.column = column + + def __eq__(self, rhs): + return self.line == rhs.line and self.column == rhs.column + + def __ne__(self, rhs): + return not self == rhs + + def __lt__(self, rhs): + return self.line < rhs.line or ( + self.line == rhs.line and self.column < rhs.column) + + def __le__(self, rhs): + return self < rhs or self == rhs + + def __gt__(self, rhs): + return rhs < self + + def __ge__(self, rhs): + return rhs <= self + + def __str__(self): + if self == Eof(): + return 'EOF' + else: + return '%s(%s)' % (self.line + 1, self.column) + + def __add__(self, offset): + return Cursor(self.line, self.column + offset) + + def __sub__(self, offset): + return Cursor(self.line, self.column - offset) + + def Clone(self): + """Returns a copy of self.""" + + return Cursor(self.line, self.column) + + +# Special cursor to indicate the end-of-file. +def Eof(): + """Returns the special cursor to denote the end-of-file.""" + return Cursor(-1, -1) + + +class Token: + """Represents a token in a Pump source file.""" + + def __init__(self, start=None, end=None, value=None, token_type=None): + if start is None: + self.start = Eof() + else: + self.start = start + if end is None: + self.end = Eof() + else: + self.end = end + self.value = value + self.token_type = token_type + + def __str__(self): + return 'Token @%s: \'%s\' type=%s' % ( + self.start, self.value, self.token_type) + + def Clone(self): + """Returns a copy of self.""" + + return Token(self.start.Clone(), self.end.Clone(), self.value, + self.token_type) + + +def StartsWith(lines, pos, string): + """Returns True iff the given position in lines starts with 'string'.""" + + return lines[pos.line][pos.column:].startswith(string) + + +def FindFirstInLine(line, token_table): + best_match_start = -1 + for (regex, token_type) in token_table: + m = regex.search(line) + if m: + # We found regex in lines + if best_match_start < 0 or m.start() < best_match_start: + best_match_start = m.start() + best_match_length = m.end() - m.start() + best_match_token_type = token_type + + if best_match_start < 0: + return None + + return (best_match_start, best_match_length, best_match_token_type) + + +def FindFirst(lines, token_table, cursor): + """Finds the first occurrence of any string in strings in lines.""" + + start = cursor.Clone() + cur_line_number = cursor.line + for line in lines[start.line:]: + if cur_line_number == start.line: + line = line[start.column:] + m = FindFirstInLine(line, token_table) + if m: + # We found a regex in line. + (start_column, length, token_type) = m + if cur_line_number == start.line: + start_column += start.column + found_start = Cursor(cur_line_number, start_column) + found_end = found_start + length + return MakeToken(lines, found_start, found_end, token_type) + cur_line_number += 1 + # We failed to find str in lines + return None + + +def SubString(lines, start, end): + """Returns a substring in lines.""" + + if end == Eof(): + end = Cursor(len(lines) - 1, len(lines[-1])) + + if start >= end: + return '' + + if start.line == end.line: + return lines[start.line][start.column:end.column] + + result_lines = ([lines[start.line][start.column:]] + + lines[start.line + 1:end.line] + + [lines[end.line][:end.column]]) + return ''.join(result_lines) + + +def StripMetaComments(str): + """Strip meta comments from each line in the given string.""" + + # First, completely remove lines containing nothing but a meta + # comment, including the trailing \n. + str = re.sub(r'^\s*\$\$.*\n', '', str) + + # Then, remove meta comments from contentful lines. + return re.sub(r'\s*\$\$.*', '', str) + + +def MakeToken(lines, start, end, token_type): + """Creates a new instance of Token.""" + + return Token(start, end, SubString(lines, start, end), token_type) + + +def ParseToken(lines, pos, regex, token_type): + line = lines[pos.line][pos.column:] + m = regex.search(line) + if m and not m.start(): + return MakeToken(lines, pos, pos + m.end(), token_type) + else: + print 'ERROR: %s expected at %s.' % (token_type, pos) + sys.exit(1) + + +ID_REGEX = re.compile(r'[_A-Za-z]\w*') +EQ_REGEX = re.compile(r'=') +REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)') +OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*') +WHITE_SPACE_REGEX = re.compile(r'\s') +DOT_DOT_REGEX = re.compile(r'\.\.') + + +def Skip(lines, pos, regex): + line = lines[pos.line][pos.column:] + m = re.search(regex, line) + if m and not m.start(): + return pos + m.end() + else: + return pos + + +def SkipUntil(lines, pos, regex, token_type): + line = lines[pos.line][pos.column:] + m = re.search(regex, line) + if m: + return pos + m.start() + else: + print ('ERROR: %s expected on line %s after column %s.' % + (token_type, pos.line + 1, pos.column)) + sys.exit(1) + + +def ParseExpTokenInParens(lines, pos): + def ParseInParens(pos): + pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX) + pos = Skip(lines, pos, r'\(') + pos = Parse(pos) + pos = Skip(lines, pos, r'\)') + return pos + + def Parse(pos): + pos = SkipUntil(lines, pos, r'\(|\)', ')') + if SubString(lines, pos, pos + 1) == '(': + pos = Parse(pos + 1) + pos = Skip(lines, pos, r'\)') + return Parse(pos) + else: + return pos + + start = pos.Clone() + pos = ParseInParens(pos) + return MakeToken(lines, start, pos, 'exp') + + +def RStripNewLineFromToken(token): + if token.value.endswith('\n'): + return Token(token.start, token.end, token.value[:-1], token.token_type) + else: + return token + + +def TokenizeLines(lines, pos): + while True: + found = FindFirst(lines, TOKEN_TABLE, pos) + if not found: + yield MakeToken(lines, pos, Eof(), 'code') + return + + if found.start == pos: + prev_token = None + prev_token_rstripped = None + else: + prev_token = MakeToken(lines, pos, found.start, 'code') + prev_token_rstripped = RStripNewLineFromToken(prev_token) + + if found.token_type == '$var': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) + + eq_token = ParseToken(lines, pos, EQ_REGEX, '=') + yield eq_token + pos = Skip(lines, eq_token.end, r'\s*') + + if SubString(lines, pos, pos + 2) != '[[': + exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp') + yield exp_token + pos = Cursor(exp_token.end.line + 1, 0) + elif found.token_type == '$for': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX) + elif found.token_type == '$range': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) + + dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..') + yield MakeToken(lines, pos, dots_pos, 'exp') + yield MakeToken(lines, dots_pos, dots_pos + 2, '..') + pos = dots_pos + 2 + new_pos = Cursor(pos.line + 1, 0) + yield MakeToken(lines, pos, new_pos, 'exp') + pos = new_pos + elif found.token_type == '$': + if prev_token: + yield prev_token + yield found + exp_token = ParseExpTokenInParens(lines, found.end) + yield exp_token + pos = exp_token.end + elif (found.token_type == ']]' or found.token_type == '$if' or + found.token_type == '$elif' or found.token_type == '$else'): + if prev_token_rstripped: + yield prev_token_rstripped + yield found + pos = found.end + else: + if prev_token: + yield prev_token + yield found + pos = found.end + + +def Tokenize(s): + """A generator that yields the tokens in the given string.""" + if s != '': + lines = s.splitlines(True) + for token in TokenizeLines(lines, Cursor(0, 0)): + yield token + + +class CodeNode: + def __init__(self, atomic_code_list=None): + self.atomic_code = atomic_code_list + + +class VarNode: + def __init__(self, identifier=None, atomic_code=None): + self.identifier = identifier + self.atomic_code = atomic_code + + +class RangeNode: + def __init__(self, identifier=None, exp1=None, exp2=None): + self.identifier = identifier + self.exp1 = exp1 + self.exp2 = exp2 + + +class ForNode: + def __init__(self, identifier=None, sep=None, code=None): + self.identifier = identifier + self.sep = sep + self.code = code + + +class ElseNode: + def __init__(self, else_branch=None): + self.else_branch = else_branch + + +class IfNode: + def __init__(self, exp=None, then_branch=None, else_branch=None): + self.exp = exp + self.then_branch = then_branch + self.else_branch = else_branch + + +class RawCodeNode: + def __init__(self, token=None): + self.raw_code = token + + +class LiteralDollarNode: + def __init__(self, token): + self.token = token + + +class ExpNode: + def __init__(self, token, python_exp): + self.token = token + self.python_exp = python_exp + + +def PopFront(a_list): + head = a_list[0] + a_list[:1] = [] + return head + + +def PushFront(a_list, elem): + a_list[:0] = [elem] + + +def PopToken(a_list, token_type=None): + token = PopFront(a_list) + if token_type is not None and token.token_type != token_type: + print 'ERROR: %s expected at %s' % (token_type, token.start) + print 'ERROR: %s found instead' % (token,) + sys.exit(1) + + return token + + +def PeekToken(a_list): + if not a_list: + return None + + return a_list[0] + + +def ParseExpNode(token): + python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value) + return ExpNode(token, python_exp) + + +def ParseElseNode(tokens): + def Pop(token_type=None): + return PopToken(tokens, token_type) + + next = PeekToken(tokens) + if not next: + return None + if next.token_type == '$else': + Pop('$else') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return code_node + elif next.token_type == '$elif': + Pop('$elif') + exp = Pop('code') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + inner_else_node = ParseElseNode(tokens) + return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)]) + elif not next.value.strip(): + Pop('code') + return ParseElseNode(tokens) + else: + return None + + +def ParseAtomicCodeNode(tokens): + def Pop(token_type=None): + return PopToken(tokens, token_type) + + head = PopFront(tokens) + t = head.token_type + if t == 'code': + return RawCodeNode(head) + elif t == '$var': + id_token = Pop('id') + Pop('=') + next = PeekToken(tokens) + if next.token_type == 'exp': + exp_token = Pop() + return VarNode(id_token, ParseExpNode(exp_token)) + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return VarNode(id_token, code_node) + elif t == '$for': + id_token = Pop('id') + next_token = PeekToken(tokens) + if next_token.token_type == 'code': + sep_token = next_token + Pop('code') + else: + sep_token = None + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return ForNode(id_token, sep_token, code_node) + elif t == '$if': + exp_token = Pop('code') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + else_node = ParseElseNode(tokens) + return IfNode(ParseExpNode(exp_token), code_node, else_node) + elif t == '$range': + id_token = Pop('id') + exp1_token = Pop('exp') + Pop('..') + exp2_token = Pop('exp') + return RangeNode(id_token, ParseExpNode(exp1_token), + ParseExpNode(exp2_token)) + elif t == '$id': + return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id')) + elif t == '$($)': + return LiteralDollarNode(head) + elif t == '$': + exp_token = Pop('exp') + return ParseExpNode(exp_token) + elif t == '[[': + code_node = ParseCodeNode(tokens) + Pop(']]') + return code_node + else: + PushFront(tokens, head) + return None + + +def ParseCodeNode(tokens): + atomic_code_list = [] + while True: + if not tokens: + break + atomic_code_node = ParseAtomicCodeNode(tokens) + if atomic_code_node: + atomic_code_list.append(atomic_code_node) + else: + break + return CodeNode(atomic_code_list) + + +def ParseToAST(pump_src_text): + """Convert the given Pump source text into an AST.""" + tokens = list(Tokenize(pump_src_text)) + code_node = ParseCodeNode(tokens) + return code_node + + +class Env: + def __init__(self): + self.variables = [] + self.ranges = [] + + def Clone(self): + clone = Env() + clone.variables = self.variables[:] + clone.ranges = self.ranges[:] + return clone + + def PushVariable(self, var, value): + # If value looks like an int, store it as an int. + try: + int_value = int(value) + if ('%s' % int_value) == value: + value = int_value + except Exception: + pass + self.variables[:0] = [(var, value)] + + def PopVariable(self): + self.variables[:1] = [] + + def PushRange(self, var, lower, upper): + self.ranges[:0] = [(var, lower, upper)] + + def PopRange(self): + self.ranges[:1] = [] + + def GetValue(self, identifier): + for (var, value) in self.variables: + if identifier == var: + return value + + print 'ERROR: meta variable %s is undefined.' % (identifier,) + sys.exit(1) + + def EvalExp(self, exp): + try: + result = eval(exp.python_exp) + except Exception, e: + print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e) + print ('ERROR: failed to evaluate meta expression %s at %s' % + (exp.python_exp, exp.token.start)) + sys.exit(1) + return result + + def GetRange(self, identifier): + for (var, lower, upper) in self.ranges: + if identifier == var: + return (lower, upper) + + print 'ERROR: range %s is undefined.' % (identifier,) + sys.exit(1) + + +class Output: + def __init__(self): + self.string = '' + + def GetLastLine(self): + index = self.string.rfind('\n') + if index < 0: + return '' + + return self.string[index + 1:] + + def Append(self, s): + self.string += s + + +def RunAtomicCode(env, node, output): + if isinstance(node, VarNode): + identifier = node.identifier.value.strip() + result = Output() + RunAtomicCode(env.Clone(), node.atomic_code, result) + value = result.string + env.PushVariable(identifier, value) + elif isinstance(node, RangeNode): + identifier = node.identifier.value.strip() + lower = int(env.EvalExp(node.exp1)) + upper = int(env.EvalExp(node.exp2)) + env.PushRange(identifier, lower, upper) + elif isinstance(node, ForNode): + identifier = node.identifier.value.strip() + if node.sep is None: + sep = '' + else: + sep = node.sep.value + (lower, upper) = env.GetRange(identifier) + for i in range(lower, upper + 1): + new_env = env.Clone() + new_env.PushVariable(identifier, i) + RunCode(new_env, node.code, output) + if i != upper: + output.Append(sep) + elif isinstance(node, RawCodeNode): + output.Append(node.raw_code.value) + elif isinstance(node, IfNode): + cond = env.EvalExp(node.exp) + if cond: + RunCode(env.Clone(), node.then_branch, output) + elif node.else_branch is not None: + RunCode(env.Clone(), node.else_branch, output) + elif isinstance(node, ExpNode): + value = env.EvalExp(node) + output.Append('%s' % (value,)) + elif isinstance(node, LiteralDollarNode): + output.Append('$') + elif isinstance(node, CodeNode): + RunCode(env.Clone(), node, output) + else: + print 'BAD' + print node + sys.exit(1) + + +def RunCode(env, code_node, output): + for atomic_code in code_node.atomic_code: + RunAtomicCode(env, atomic_code, output) + + +def IsSingleLineComment(cur_line): + return '//' in cur_line + + +def IsInPreprocessorDirective(prev_lines, cur_line): + if cur_line.lstrip().startswith('#'): + return True + return prev_lines and prev_lines[-1].endswith('\\') + + +def WrapComment(line, output): + loc = line.find('//') + before_comment = line[:loc].rstrip() + if before_comment == '': + indent = loc + else: + output.append(before_comment) + indent = len(before_comment) - len(before_comment.lstrip()) + prefix = indent*' ' + '// ' + max_len = 80 - len(prefix) + comment = line[loc + 2:].strip() + segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != ''] + cur_line = '' + for seg in segs: + if len((cur_line + seg).rstrip()) < max_len: + cur_line += seg + else: + if cur_line.strip() != '': + output.append(prefix + cur_line.rstrip()) + cur_line = seg.lstrip() + if cur_line.strip() != '': + output.append(prefix + cur_line.strip()) + + +def WrapCode(line, line_concat, output): + indent = len(line) - len(line.lstrip()) + prefix = indent*' ' # Prefix of the current line + max_len = 80 - indent - len(line_concat) # Maximum length of the current line + new_prefix = prefix + 4*' ' # Prefix of a continuation line + new_max_len = max_len - 4 # Maximum length of a continuation line + # Prefers to wrap a line after a ',' or ';'. + segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != ''] + cur_line = '' # The current line without leading spaces. + for seg in segs: + # If the line is still too long, wrap at a space. + while cur_line == '' and len(seg.strip()) > max_len: + seg = seg.lstrip() + split_at = seg.rfind(' ', 0, max_len) + output.append(prefix + seg[:split_at].strip() + line_concat) + seg = seg[split_at + 1:] + prefix = new_prefix + max_len = new_max_len + + if len((cur_line + seg).rstrip()) < max_len: + cur_line = (cur_line + seg).lstrip() + else: + output.append(prefix + cur_line.rstrip() + line_concat) + prefix = new_prefix + max_len = new_max_len + cur_line = seg.lstrip() + if cur_line.strip() != '': + output.append(prefix + cur_line.strip()) + + +def WrapPreprocessorDirective(line, output): + WrapCode(line, ' \\', output) + + +def WrapPlainCode(line, output): + WrapCode(line, '', output) + + +def IsMultiLineIWYUPragma(line): + return re.search(r'/\* IWYU pragma: ', line) + + +def IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or + re.match(r'^#include\s', line) or + # Don't break IWYU pragmas, either; that causes iwyu.py problems. + re.search(r'// IWYU pragma: ', line)) + + +def WrapLongLine(line, output): + line = line.rstrip() + if len(line) <= 80: + output.append(line) + elif IsSingleLineComment(line): + if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + # The style guide made an exception to allow long header guard lines, + # includes and IWYU pragmas. + output.append(line) + else: + WrapComment(line, output) + elif IsInPreprocessorDirective(output, line): + if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + # The style guide made an exception to allow long header guard lines, + # includes and IWYU pragmas. + output.append(line) + else: + WrapPreprocessorDirective(line, output) + elif IsMultiLineIWYUPragma(line): + output.append(line) + else: + WrapPlainCode(line, output) + + +def BeautifyCode(string): + lines = string.splitlines() + output = [] + for line in lines: + WrapLongLine(line, output) + output2 = [line.rstrip() for line in output] + return '\n'.join(output2) + '\n' + + +def ConvertFromPumpSource(src_text): + """Return the text generated from the given Pump source text.""" + ast = ParseToAST(StripMetaComments(src_text)) + output = Output() + RunCode(Env(), ast, output) + return BeautifyCode(output.string) + + +def main(argv): + if len(argv) == 1: + print __doc__ + sys.exit(1) + + file_path = argv[-1] + output_str = ConvertFromPumpSource(file(file_path, 'r').read()) + if file_path.endswith('.pump'): + output_file_path = file_path[:-5] + else: + output_file_path = '-' + if output_file_path == '-': + print output_str, + else: + output_file = file(output_file_path, 'w') + output_file.write('// This file was GENERATED by command:\n') + output_file.write('// %s %s\n' % + (os.path.basename(__file__), os.path.basename(file_path))) + output_file.write('// DO NOT EDIT BY HAND!!!\n\n') + output_file.write(output_str) + output_file.close() + + +if __name__ == '__main__': + main(sys.argv) diff --git a/cpp/thirdparty/gtest-1.7.0/scripts/test/Makefile b/cpp/thirdparty/gtest-1.7.0/scripts/test/Makefile new file mode 100644 index 0000000..cdff584 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/scripts/test/Makefile @@ -0,0 +1,59 @@ +# A Makefile for fusing Google Test and building a sample test against it. +# +# SYNOPSIS: +# +# make [all] - makes everything. +# make TARGET - makes the given target. +# make check - makes everything and runs the built sample test. +# make clean - removes all files generated by make. + +# Points to the root of fused Google Test, relative to where this file is. +FUSED_GTEST_DIR = output + +# Paths to the fused gtest files. +FUSED_GTEST_H = $(FUSED_GTEST_DIR)/gtest/gtest.h +FUSED_GTEST_ALL_CC = $(FUSED_GTEST_DIR)/gtest/gtest-all.cc + +# Where to find the sample test. +SAMPLE_DIR = ../../samples + +# Where to find gtest_main.cc. +GTEST_MAIN_CC = ../../src/gtest_main.cc + +# Flags passed to the preprocessor. +# We have no idea here whether pthreads is available in the system, so +# disable its use. +CPPFLAGS += -I$(FUSED_GTEST_DIR) -DGTEST_HAS_PTHREAD=0 + +# Flags passed to the C++ compiler. +CXXFLAGS += -g + +all : sample1_unittest + +check : all + ./sample1_unittest + +clean : + rm -rf $(FUSED_GTEST_DIR) sample1_unittest *.o + +$(FUSED_GTEST_H) : + ../fuse_gtest_files.py $(FUSED_GTEST_DIR) + +$(FUSED_GTEST_ALL_CC) : + ../fuse_gtest_files.py $(FUSED_GTEST_DIR) + +gtest-all.o : $(FUSED_GTEST_H) $(FUSED_GTEST_ALL_CC) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FUSED_GTEST_DIR)/gtest/gtest-all.cc + +gtest_main.o : $(FUSED_GTEST_H) $(GTEST_MAIN_CC) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_MAIN_CC) + +sample1.o : $(SAMPLE_DIR)/sample1.cc $(SAMPLE_DIR)/sample1.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1.cc + +sample1_unittest.o : $(SAMPLE_DIR)/sample1_unittest.cc \ + $(SAMPLE_DIR)/sample1.h $(FUSED_GTEST_H) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1_unittest.cc + +sample1_unittest : sample1.o sample1_unittest.o gtest-all.o gtest_main.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@ diff --git a/cpp/thirdparty/gtest-1.7.0/src/gtest-all.cc b/cpp/thirdparty/gtest-1.7.0/src/gtest-all.cc new file mode 100644 index 0000000..0a9cee5 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/src/gtest-all.cc @@ -0,0 +1,48 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include "gtest/gtest.h" + +// The following lines pull in the real gtest *.cc files. +#include "src/gtest.cc" +#include "src/gtest-death-test.cc" +#include "src/gtest-filepath.cc" +#include "src/gtest-port.cc" +#include "src/gtest-printers.cc" +#include "src/gtest-test-part.cc" +#include "src/gtest-typed-test.cc" diff --git a/cpp/thirdparty/gtest-1.7.0/src/gtest-death-test.cc b/cpp/thirdparty/gtest-1.7.0/src/gtest-death-test.cc new file mode 100644 index 0000000..a6023fc --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/src/gtest-death-test.cc @@ -0,0 +1,1344 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) +// +// This file implements death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_MAC +# include +# endif // GTEST_OS_MAC + +# include +# include +# include + +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + +# include + +# if GTEST_OS_WINDOWS +# include +# else +# include +# include +# endif // GTEST_OS_WINDOWS + +# if GTEST_OS_QNX +# include +# endif // GTEST_OS_QNX + +#endif // GTEST_HAS_DEATH_TEST + +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-string.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +// Constants. + +// The default death test style. +static const char kDefaultDeathTestStyle[] = "fast"; + +GTEST_DEFINE_string_( + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); + +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + +namespace internal { +GTEST_DEFINE_string_( + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "the '|' characters. This flag is specified if and only if the current " + "process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); +} // namespace internal + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Valid only for fast death tests. Indicates the code is running in the +// child process of a fast style death test. +static bool g_in_fast_death_test_child = false; + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +bool InDeathTestChild() { +# if GTEST_OS_WINDOWS + + // On Windows, death tests are thread-safe regardless of the value of the + // death_test_style flag. + return !GTEST_FLAG(internal_run_death_test).empty(); + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") + return !GTEST_FLAG(internal_run_death_test).empty(); + else + return g_in_fast_death_test_child; +#endif +} + +} // namespace internal + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +# if GTEST_OS_WINDOWS + + return exit_status == exit_code_; + +# else + + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; + +# endif // GTEST_OS_WINDOWS +} + +# if !GTEST_OS_WINDOWS +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} +# endif // !GTEST_OS_WINDOWS + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static std::string ExitSummary(int exit_code) { + Message m; + +# if GTEST_OS_WINDOWS + + m << "Exited with exit status " << exit_code; + +# else + + if (WIFEXITED(exit_code)) { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } else if (WIFSIGNALED(exit_code)) { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +# ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) { + m << " (core dumped)"; + } +# endif +# endif // GTEST_OS_WINDOWS + + return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { + return !ExitedWithCode(0)(exit_status); +} + +# if !GTEST_OS_WINDOWS +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement. It is the responsibility of the +// caller not to pass a thread_count of 1. +static std::string DeathTestThreadWarning(size_t thread_count) { + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) + msg << "couldn't detect the number of threads."; + else + msg << "detected " << thread_count << " threads."; + return msg.GetString(); +} +# endif // !GTEST_OS_WINDOWS + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestThrew = 'T'; +static const char kDeathTestInternalError = 'I'; + +// An enumeration describing all of the possible ways that a death test can +// conclude. DIED means that the process died while executing the test +// code; LIVED means that process lived beyond the end of the test code; +// RETURNED means that the test statement attempted to execute a return +// statement, which is not allowed; THREW means that the test statement +// returned control by throwing an exception. IN_PROGRESS means the test +// has not yet concluded. +// TODO(vladl@google.com): Unify names and possibly values for +// AbortReason, DeathTestOutcome, and flag characters above. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the error +// message is propagated back to the parent process. Otherwise, the +// message is simply printed to stderr. In either case, the program +// then exits with status 1. +void DeathTestAbort(const std::string& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != NULL) { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } else { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + posix::Abort(); + } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +# define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + + ::testing::internal::StreamableToString(__LINE__) + ": " \ + + #expression); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again. The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR. If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + + ::testing::internal::StreamableToString(__LINE__) + ": " \ + + #expression + " != -1"); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +std::string GetLastErrnoDescription() { + return errno == 0 ? "" : posix::StrError(errno); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} + +// Death test constructor. Increments the running death test count +// for the current test. +DeathTest::DeathTest() { + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == NULL) { + DeathTestAbort("Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) { + return GetUnitTestImpl()->death_test_factory()->Create( + statement, regex, file, line, test); +} + +const char* DeathTest::LastMessage() { + return last_death_test_message_.c_str(); +} + +void DeathTest::set_last_death_test_message(const std::string& message) { + last_death_test_message_ = message; +} + +std::string DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } + + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; +}; + +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; + + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestThrew: + set_outcome(THREW); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast(flag) << ")"; + } + } else { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : + reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; + + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + // We are leaking the descriptor here because on some platforms (i.e., + // when built as Windows DLL), destructors of global objects will still + // run after calling _exit(). On such systems, write_fd_ will be + // indirectly closed from the destructor of UnitTestImpl, causing double + // close if it is also closed here. On debug configurations, double close + // may assert. As there are no in-process buffers to flush here, we are + // relying on the OS to close the descriptor after the process terminates + // when the destructors are not run. + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// Returns an indented copy of stderr output for a death test. +// This makes distinguishing death test output lines from regular log lines +// much easier. +static ::std::string FormatDeathTestOutput(const ::std::string& output) { + ::std::string ret; + for (size_t at = 0; ; ) { + const size_t line_end = output.find('\n', at); + ret += "[ DEATH ] "; + if (line_end == ::std::string::npos) { + ret += output.substr(at); + break; + } + ret += output.substr(at, line_end + 1 - at); + at = line_end + 1; + } + return ret; +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +// outcome: An enumeration describing how the death test +// concluded: DIED, LIVED, THREW, or RETURNED. The death test +// fails in the latter three cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to +// the test's captured standard error output; the death test +// fails if it does not match. +// +// Argument: +// status_ok: true if exit_status is acceptable in the context of +// this particular death test, which fails if it is false +// +// Returns true iff all of the above conditions are met. Otherwise, the +// first failing condition, in the order given above, is the one that is +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) + return false; + + const std::string error_message = GetCapturedStderr(); + + bool success = false; + Message buffer; + + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case THREW: + buffer << " Result: threw an exception.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case DIED: + if (status_ok) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { + success = true; + } else { + buffer << " Result: died but not with expected error.\n" + << " Expected: " << regex()->pattern() << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + } else { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } + + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; +} + +# if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* a_statement, + const RE* a_regex, + const char* file, + int line) + : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status_code; + GTEST_DEATH_TEST_CHECK_( + ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); + child_handle_.Reset(); + set_status(static_cast(status_code)); + return status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + + "=" + file_ + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(static_cast(::GetCurrentProcessId())) + + // size_t has the same width as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + "|" + StreamableToString(reinterpret_cast(write_handle)) + + "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + std::string command_line = + std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + + internal_flag + "\""; + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +# else // We are not on Windows. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, const RE* regex); + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } + virtual TestRole AssumeRole(); +}; + +// The AssumeRole process for a fork-and-run death test. It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); + + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + g_in_fast_death_test_child = true; + return EXECUTE_TEST; + } else { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: + ExecDeathTest(const char* a_statement, const RE* a_regex, + const char* file, int line) : + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } + virtual TestRole AssumeRole(); + private: + static ::std::vector + GetArgvsForDeathTestChildProcess() { + ::std::vector args = GetInjectableArgvs(); + return args; + } + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { + args_.push_back(NULL); + } + + ~Arguments() { + for (std::vector::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template + void AddArguments(const ::std::vector& arguments) { + for (typename ::std::vector::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + + private: + std::vector args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe +}; + +# if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +# else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +# endif // GTEST_OS_MAC + +# if !GTEST_OS_QNX +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { + ExecDeathTestArgs* const args = static_cast(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + + original_dir + " failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; +} +# endif // !GTEST_OS_QNX + +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +// +// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining +// StackLowerThanAddress into StackGrowsDown, which then doesn't give +// correct answer. +void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; +void StackLowerThanAddress(const void* ptr, bool* result) { + int dummy; + *result = (&dummy < ptr); +} + +bool StackGrowsDown() { + int dummy; + bool result; + StackLowerThanAddress(&dummy, &result); + return result; +} + +// Spawns a child process with the same executable as the current process in +// a thread-safe manner and instructs it to run the death test. The +// implementation uses fork(2) + exec. On systems where clone(2) is +// available, it is used instead, being slightly more thread-safe. On QNX, +// fork supports only single-threaded environments, so this function uses +// spawn(2) there instead. The function dies with an error message if +// anything goes wrong. +static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { + ExecDeathTestArgs args = { argv, close_fd }; + pid_t child_pid = -1; + +# if GTEST_OS_QNX + // Obtains the current directory and sets it to be closed in the child + // process. + const int cwd_fd = open(".", O_RDONLY); + GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + int fd_flags; + // Set close_fd to be closed after spawn. + GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, + fd_flags | FD_CLOEXEC)); + struct inheritance inherit = {0}; + // spawn is a system call. + child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); + // Restores the current working directory. + GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); + +# else // GTEST_OS_QNX +# if GTEST_OS_LINUX + // When a SIGPROF signal is received while fork() or clone() are executing, + // the process may hang. To avoid this, we ignore SIGPROF here and re-enable + // it after the call to fork()/clone() is complete. + struct sigaction saved_sigprof_action; + struct sigaction ignore_sigprof_action; + memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); + sigemptyset(&ignore_sigprof_action.sa_mask); + ignore_sigprof_action.sa_handler = SIG_IGN; + GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( + SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); +# endif // GTEST_OS_LINUX + +# if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + + // Maximum stack alignment in bytes: For a downward-growing stack, this + // amount is subtracted from size of the stack space to get an address + // that is within the stack space and is aligned on all systems we care + // about. As far as I know there is no ABI with stack alignment greater + // than 64. We assume stack and stack_size already have alignment of + // kMaxStackAlignment. + const size_t kMaxStackAlignment = 64; + void* const stack_top = + static_cast(stack) + + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); + GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && + reinterpret_cast(stack_top) % kMaxStackAlignment == 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +# else + const bool use_fork = true; +# endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } +# endif // GTEST_OS_QNX +# if GTEST_OS_LINUX + GTEST_DEATH_TEST_CHECK_SYSCALL_( + sigaction(SIGPROF, &saved_sigprof_action, NULL)); +# endif // GTEST_OS_LINUX + + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test. It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + + file_ + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvsForDeathTestChildProcess()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); + + const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; +} + +# endif // !GTEST_OS_WINDOWS + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address. If the test should be +// skipped, sets that pointer to NULL. Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, + const char* file, int line, + DeathTest** test) { + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); + + if (flag != NULL) { + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message( + "Death test count (" + StreamableToString(death_test_index) + + ") somehow exceeded expected maximum (" + + StreamableToString(flag->index()) + ")"); + return false; + } + + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { + *test = NULL; + return true; + } + } + +# if GTEST_OS_WINDOWS + + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") { + *test = new ExecDeathTest(statement, regex, file, line); + } else if (GTEST_FLAG(death_test_style) == "fast") { + *test = new NoExecDeathTest(statement, regex); + } + +# endif // GTEST_OS_WINDOWS + + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message( + "Unknown death test style \"" + GTEST_FLAG(death_test_style) + + "\" encountered"); + return false; + } + + return true; +} + +// Splits a given string on a given delimiter, populating a given +// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have +// ::std::string, so we can use it here. +static void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest) { + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) { + parsed.push_back(str.substr(pos)); + break; + } else { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); +} + +# if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort("Unable to open parent process " + + StreamableToString(parent_process_id)); + } + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort("Unable to duplicate the pipe handle " + + StreamableToString(write_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } + + const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort("Unable to duplicate the event handle " + + StreamableToString(event_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort("Unable to convert pipe handle " + + StreamableToString(write_handle_as_size_t) + + " to a file descriptor"); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; +} +# endif // GTEST_OS_WINDOWS + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { + if (GTEST_FLAG(internal_run_death_test) == "") return NULL; + + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +# if GTEST_OS_WINDOWS + + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +# else + + if (fields.size() != 4 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + +# endif // GTEST_OS_WINDOWS + + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); +} + +} // namespace internal + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace testing diff --git a/cpp/thirdparty/gtest-1.7.0/src/gtest-filepath.cc b/cpp/thirdparty/gtest-1.7.0/src/gtest-filepath.cc new file mode 100644 index 0000000..6be58b6 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/src/gtest-filepath.cc @@ -0,0 +1,382 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) + +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-filepath.h" +#include "gtest/internal/gtest-port.h" + +#include + +#if GTEST_OS_WINDOWS_MOBILE +# include +#elif GTEST_OS_WINDOWS +# include +# include +#elif GTEST_OS_SYMBIAN +// Symbian OpenC has PATH_MAX in sys/syslimits.h +# include +#else +# include +# include // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +# define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +# define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif // GTEST_OS_WINDOWS + +#include "gtest/internal/gtest-string.h" + +namespace testing { +namespace internal { + +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. +const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; +const char kPathSeparatorString[] = "\\"; +const char kAlternatePathSeparatorString[] = "/"; +# if GTEST_OS_WINDOWS_MOBILE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +# else +const char kCurrentDirectoryString[] = ".\\"; +# endif // GTEST_OS_WINDOWS_MOBILE +#else +const char kPathSeparator = '/'; +const char kPathSeparatorString[] = "/"; +const char kCurrentDirectoryString[] = "./"; +#endif // GTEST_OS_WINDOWS + +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#else + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { + const std::string dot_extension = std::string(".") + extension; + if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { + return FilePath(pathname_.substr( + 0, pathname_.length() - dot_extension.length())); + } + return *this; +} + +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(last_sep + 1) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { + const char* const last_sep = FindLastPathSeparator(); + std::string dir; + if (last_sep) { + dir = std::string(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension) { + std::string file; + if (number == 0) { + file = base_name.string() + "." + extension; + } else { + file = base_name.string() + "_" + StreamableToString(number) + + "." + extension; + } + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(dir.string() + kPathSeparator + relative_path.string()); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + return attributes != kInvalidFileAttributes; +#else + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { + bool result = false; +#if GTEST_OS_WINDOWS + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : + RemoveTrailingPathSeparator()); +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = true; + } +#else + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + + return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { + const char* const name = pathname_.c_str(); +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); +#else + return IsPathSeparator(name[0]); +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension) { + FilePath full_pathname; + int number = 0; + do { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { + if (!this->IsDirectory()) { + return false; + } + + if (pathname_.length() == 0 || this->DirectoryExists()) { + return true; + } + + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#if GTEST_OS_WINDOWS_MOBILE + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, NULL) ? 0 : -1; + delete [] unicode; +#elif GTEST_OS_WINDOWS + int result = _mkdir(pathname_.c_str()); +#else + int result = mkdir(pathname_.c_str(), 0777); +#endif // GTEST_OS_WINDOWS_MOBILE + + if (result == -1) { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { + return IsDirectory() + ? FilePath(pathname_.substr(0, pathname_.length() - 1)) + : *this; +} + +// Removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). +void FilePath::Normalize() { + if (pathname_.c_str() == NULL) { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); + + while (*src != '\0') { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { + src++; + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; +} + +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/gtest-1.7.0/src/gtest-internal-inl.h b/cpp/thirdparty/gtest-1.7.0/src/gtest-internal-inl.h new file mode 100644 index 0000000..35df303 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/src/gtest-internal-inl.h @@ -0,0 +1,1218 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// Utility functions and classes used by the Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This file contains purely Google Test's internal implementation. Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ +// A user is trying to include this from his code - just say no. +# error "gtest-internal-inl.h is part of Google Test's internal implementation." +# error "It must not be included except by Google Test itself." +#endif // GTEST_IMPLEMENTATION_ + +#ifndef _WIN32_WCE +# include +#endif // !_WIN32_WCE +#include +#include // For strtoll/_strtoul64/malloc/free. +#include // For memmove. + +#include +#include +#include + +#include "gtest/internal/gtest-port.h" + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +#endif + +#if GTEST_OS_WINDOWS +# include // NOLINT +#endif // GTEST_OS_WINDOWS + +#include "gtest/gtest.h" // NOLINT +#include "gtest/gtest-spi.h" + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; +const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kStreamResultToFlag[] = "stream_result_to"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Converts the given time in milliseconds to a date string in the ISO 8601 +// format, without the timezone information. N.B.: due to the use the +// non-reentrant localtime() function, this function is not thread safe. Do +// not use it in any code that can be called from multiple threads. +GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast(GetTimeInMillis()) : + static_cast(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast((raw_seed - 1U) % + static_cast(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: + // The c'tor. + GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + stream_result_to_ = GTEST_FLAG(stream_result_to); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } + + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(stream_result_to) = stream_result_to_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } + + private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + std::string color_; + std::string death_test_style_; + bool death_test_use_fork_; + std::string filter_; + std::string internal_run_death_test_; + bool list_tests_; + std::string output_; + bool print_time_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + std::string stream_result_to_; + bool throw_on_failure_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted +// to "(Invalid Unicode 0xXXXXXXXX)". +GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template +inline int CountIf(const Container& c, Predicate predicate) { + // Implemented as an explicit loop since std::count_if() in libCstd on + // Solaris has a non-standard signature. + int count = 0; + for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { + if (predicate(*it)) + ++count; + } + return count; +} + +// Applies a function/functor to each element in the container. +template +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} + +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template +inline E GetElementOr(const std::vector& v, int i, E default_value) { + return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; +} + +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector* v) { + const int size = static_cast(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); + } +} + +// Performs an in-place shuffle of the vector's elements. +template +inline void Shuffle(internal::Random* random, std::vector* v) { + ShuffleRange(random, 0, static_cast(v->size()), v); +} + +// A function for deleting an object. Handy for being used as a +// functor. +template +static void Delete(T* x) { + delete x; +} + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} + + // Returns true iff the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const { + return test_property.key() == key_; + } + + private: + std::string key_; +}; + +// Class UnitTestOptions. +// +// This class contains functions for processing options the user +// specifies when running the tests. It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag. E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter. If both +// the variable and the flag are present, the latter overrides the +// former. +class GTEST_API_ UnitTestOptions { + public: + // Functions for processing the gtest_output flag. + + // Returns the output format, or "" for normal printed output. + static std::string GetOutputFormat(); + + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static std::string GetAbsolutePathToOutputFile(); + + // Functions for processing the gtest_filter flag. + + // Returns true iff the wildcard pattern matches the string. The + // first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char *pattern, const char *str); + + // Returns true iff the user-specified filter matches the test case + // name and the test name. + static bool FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name); + +#if GTEST_OS_WINDOWS + // Function for supporting the gtest_catch_exception flag. + + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); +#endif // GTEST_OS_WINDOWS + + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const std::string& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present. Used by UnitTestOptions::GetOutputFile. +GTEST_API_ FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} + + // Returns the current OS stack trace as an std::string. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; + + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: + OsStackTraceGetter() : caller_frame_(NULL) {} + + virtual string CurrentStackTrace(int max_depth, int skip_count) + GTEST_LOCK_EXCLUDED_(mutex_); + + virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); + + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + + private: + Mutex mutex_; // protects all internal state + + // We save the stack frame below the frame that calls user code. + // We do this because the address of the frame immediately below + // the user code changes between the call to UponLeavingGTest() + // and any calls to CurrentStackTrace() from within the user code. + void* caller_frame_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { + const char* file; + int line; + std::string message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); +}; + +// The private implementation of the UnitTest class. We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class GTEST_API_ UnitTestImpl { + public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); + + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); + + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const { return start_timestamp_; } + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const { return !Failed(); } + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const { + return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; + } + + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); + + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); + + // Returns the current OS stack trace as an std::string. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; + + // Finds and returns a TestCase with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_case_name: name of the test case + // type_param: the name of the test's type parameter, or NULL if + // this is not a typed or a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase* GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + // test_info: the TestInfo object + void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + TestInfo* test_info) { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } + + GetTestCase(test_info->test_case_name(), + test_info->type_param(), + set_up_tc, + tear_down_tc)->AddTestInfo(test_info); + } + +#if GTEST_HAS_PARAM_TEST + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } +#endif // GTEST_HAS_PARAM_TEST + + // Sets the TestCase object for the test that's currently running. + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has guards + // protecting from registering the tests more then once. If + // value-parameterized tests are disabled, RegisterParameterizedTests is + // present but does nothing. + void RegisterParameterizedTests(); + + // Runs all tests in this UnitTest object, prints the result, and + // returns true if all tests are successful. If any exception is + // thrown during a test, this test is considered to be failed, but + // the rest of the tests will still be run. + bool RunAllTests(); + + // Clears the results of all tests, except the ad hoc tests. + void ClearNonAdHocTestResult() { + ForEach(test_cases_, TestCase::ClearTestCaseResult); + } + + // Clears the results of ad-hoc test assertions. + void ClearAdHocTestResult() { + ad_hoc_test_result_.Clear(); + } + + // Adds a TestProperty to the current TestResult object when invoked in a + // context of a test or a test case, or to the global property set. If the + // result already contains a property with the same key, the value will be + // updated. + void RecordProperty(const TestProperty& test_property); + + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); + + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); + + const TestCase* current_test_case() const { return current_test_case_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } + + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector& environments() { return environments_; } + + // Getters for the per-thread Google Test trace stack. + std::vector& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); + } + const std::vector& gtest_trace_stack() const { + return gtest_trace_stack_.get(); + } + +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const { + return internal_run_death_test_flag_.get(); + } + + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() { + return death_test_factory_.get(); + } + + void SuppressTestEventsIfInSubprocess(); + + friend class ReplaceDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Initializes the event listener for streaming test results to a socket. + // Must not be called before InitGoogleTest. + void ConfigureStreamingOutput(); +#endif + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + + // Returns the value of GTEST_FLAG(catch_exceptions) at the moment + // UnitTest::Run() starts. + bool catch_exceptions() const { return catch_exceptions_; } + + private: + friend class ::testing::UnitTest; + + // Used by UnitTest::Run() to capture the state of + // GTEST_FLAG(catch_exceptions) at the moment it starts. + void set_catch_exceptions(bool value) { catch_exceptions_ = value; } + + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; + + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; + + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal + per_thread_test_part_result_reporter_; + + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector environments_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector test_cases_; + + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector test_case_indices_; + +#if GTEST_HAS_PARAM_TEST + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; +#endif // GTEST_HAS_PARAM_TEST + + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; + + // This points to the TestCase for the currently running test. It + // changes as Google Test goes through one test case after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestCase* current_test_case_; + + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; + + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; + + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; + + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; + + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + + // The time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp_; + + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; + +#if GTEST_HAS_DEATH_TEST + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + internal::scoped_ptr internal_run_death_test_flag_; + internal::scoped_ptr death_test_factory_; +#endif // GTEST_HAS_DEATH_TEST + + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal > gtest_trace_stack_; + + // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() + // starts. + bool catch_exceptions_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +}; // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { + return UnitTest::GetInstance()->impl(); +} + +#if GTEST_USES_SIMPLE_RE + +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsAsciiDigit(char ch); +GTEST_API_ bool IsAsciiPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsAsciiWhiteSpace(char ch); +GTEST_API_ bool IsAsciiWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + +#endif // GTEST_USES_SIMPLE_RE + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +GTEST_API_ std::string GetLastErrnoDescription(); + +# if GTEST_OS_WINDOWS +// Provides leak-safe Windows kernel handle ownership. +class AutoHandle { + public: + AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} + explicit AutoHandle(HANDLE handle) : handle_(handle) {} + + ~AutoHandle() { Reset(); } + + HANDLE Get() const { return handle_; } + void Reset() { Reset(INVALID_HANDLE_VALUE); } + void Reset(HANDLE handle) { + if (handle != handle_) { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + handle_ = handle; + } + } + + private: + HANDLE handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; +# endif // GTEST_OS_WINDOWS + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !IsDigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. + +# if GTEST_OS_WINDOWS && !defined(__GNUC__) + + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); + +# else + + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); + +# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast(parsed); + if (parse_success && static_cast(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const std::string& xml_element, + const TestProperty& property) { + test_result->RecordProperty(xml_element, property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + +#if GTEST_CAN_STREAM_RESULTS_ + +// Streams test results to the given port on the given host machine. +class StreamingListener : public EmptyTestEventListener { + public: + // Abstract base class for writing strings to a socket. + class AbstractSocketWriter { + public: + virtual ~AbstractSocketWriter() {} + + // Sends a string to the socket. + virtual void Send(const string& message) = 0; + + // Closes the socket. + virtual void CloseConnection() {} + + // Sends a string and a newline to the socket. + void SendLn(const string& message) { + Send(message + "\n"); + } + }; + + // Concrete class for actually writing strings to a socket. + class SocketWriter : public AbstractSocketWriter { + public: + SocketWriter(const string& host, const string& port) + : sockfd_(-1), host_name_(host), port_num_(port) { + MakeConnection(); + } + + virtual ~SocketWriter() { + if (sockfd_ != -1) + CloseConnection(); + } + + // Sends a string to the socket. + virtual void Send(const string& message) { + GTEST_CHECK_(sockfd_ != -1) + << "Send() can be called only when there is a connection."; + + const int len = static_cast(message.length()); + if (write(sockfd_, message.c_str(), len) != len) { + GTEST_LOG_(WARNING) + << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; + } + } + + private: + // Creates a client socket and connects to the server. + void MakeConnection(); + + // Closes the socket. + void CloseConnection() { + GTEST_CHECK_(sockfd_ != -1) + << "CloseConnection() can be called only when there is a connection."; + + close(sockfd_); + sockfd_ = -1; + } + + int sockfd_; // socket file descriptor + const string host_name_; + const string port_num_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); + }; // class SocketWriter + + // Escapes '=', '&', '%', and '\n' characters in str as "%xx". + static string UrlEncode(const char* str); + + StreamingListener(const string& host, const string& port) + : socket_writer_(new SocketWriter(host, port)) { Start(); } + + explicit StreamingListener(AbstractSocketWriter* socket_writer) + : socket_writer_(socket_writer) { Start(); } + + void OnTestProgramStart(const UnitTest& /* unit_test */) { + SendLn("event=TestProgramStart"); + } + + void OnTestProgramEnd(const UnitTest& unit_test) { + // Note that Google Test current only report elapsed time for each + // test iteration, not for the entire test program. + SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); + + // Notify the streaming server to stop. + socket_writer_->CloseConnection(); + } + + void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { + SendLn("event=TestIterationStart&iteration=" + + StreamableToString(iteration)); + } + + void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { + SendLn("event=TestIterationEnd&passed=" + + FormatBool(unit_test.Passed()) + "&elapsed_time=" + + StreamableToString(unit_test.elapsed_time()) + "ms"); + } + + void OnTestCaseStart(const TestCase& test_case) { + SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); + } + + void OnTestCaseEnd(const TestCase& test_case) { + SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + + "ms"); + } + + void OnTestStart(const TestInfo& test_info) { + SendLn(std::string("event=TestStart&name=") + test_info.name()); + } + + void OnTestEnd(const TestInfo& test_info) { + SendLn("event=TestEnd&passed=" + + FormatBool((test_info.result())->Passed()) + + "&elapsed_time=" + + StreamableToString((test_info.result())->elapsed_time()) + "ms"); + } + + void OnTestPartResult(const TestPartResult& test_part_result) { + const char* file_name = test_part_result.file_name(); + if (file_name == NULL) + file_name = ""; + SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + + "&line=" + StreamableToString(test_part_result.line_number()) + + "&message=" + UrlEncode(test_part_result.message())); + } + + private: + // Sends the given message and a newline to the socket. + void SendLn(const string& message) { socket_writer_->SendLn(message); } + + // Called at the start of streaming to notify the receiver what + // protocol we are using. + void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } + + string FormatBool(bool value) { return value ? "1" : "0"; } + + const scoped_ptr socket_writer_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); +}; // class StreamingListener + +#endif // GTEST_CAN_STREAM_RESULTS_ + +} // namespace internal +} // namespace testing + +#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ diff --git a/cpp/thirdparty/gtest-1.7.0/src/gtest-port.cc b/cpp/thirdparty/gtest-1.7.0/src/gtest-port.cc new file mode 100644 index 0000000..0c4df5f --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/src/gtest-port.cc @@ -0,0 +1,805 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/internal/gtest-port.h" + +#include +#include +#include +#include + +#if GTEST_OS_WINDOWS_MOBILE +# include // For TerminateProcess() +#elif GTEST_OS_WINDOWS +# include +# include +#else +# include +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_MAC +# include +# include +# include +#endif // GTEST_OS_MAC + +#if GTEST_OS_QNX +# include +# include +#endif // GTEST_OS_QNX + +#include "gtest/gtest-spi.h" +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_MAC + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast(thread_list), + sizeof(thread_t) * thread_count); + return static_cast(thread_count); + } else { + return 0; + } +} + +#elif GTEST_OS_QNX + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const int fd = open("/proc/self/as", O_RDONLY); + if (fd < 0) { + return 0; + } + procfs_info process_info; + const int status = + devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); + close(fd); + if (status == EOK) { + return static_cast(process_info.num_threads); + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_MAC + +#if GTEST_USES_POSIX_RE + +// Implements RE. Currently only needed for death tests. + +RE::~RE() { + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast(pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = posix::StrDup(regex); + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; +} + +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in , these aren't affected by the +// current locale. +bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsAsciiPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsAsciiWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsAsciiDigit(ch); + case 'D': return !IsAsciiDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsAsciiWhiteSpace(ch); + case 'S': return !IsAsciiWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsAsciiWordChar(ch); + case 'W': return !IsAsciiWordChar(ch); + } + return IsAsciiPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +std::string FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast(pattern_)); + free(const_cast(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + +const char kUnknownFile[] = "unknown file"; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { + const std::string file_name(file == NULL ? kUnknownFile : file); + + if (line < 0) { + return file_name + ":"; + } +#ifdef _MSC_VER + return file_name + "(" + StreamableToString(line) + "):"; +#else + return file_name + ":" + StreamableToString(line) + ":"; +#endif // _MSC_VER +} + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +// Note that FormatCompilerIndependentFileLocation() does NOT append colon +// to the file location it produces, unlike FormatFileLocation(). +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( + const char* file, int line) { + const std::string file_name(file == NULL ? kUnknownFile : file); + + if (line < 0) + return file_name; + else + return file_name + ":" + StreamableToString(line); +} + + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : + severity == GTEST_WARNING ? "[WARNING]" : + severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4996) +#endif // _MSC_VER + +#if GTEST_HAS_STREAM_REDIRECTION + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { +# if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +# else + // There's no guarantee that a test has write access to the current + // directory, so we create the temporary file in the /tmp directory + // instead. We use /tmp on most systems, and /sdcard on Android. + // That's because Android doesn't have /tmp. +# if GTEST_OS_LINUX_ANDROID + // Note: Android applications are expected to call the framework's + // Context.getExternalStorageDirectory() method through JNI to get + // the location of the world-writable SD Card directory. However, + // this requires a Context handle, which cannot be retrieved + // globally from native code. Doing so also precludes running the + // code as part of a regular standalone executable, which doesn't + // run in a Dalvik process (e.g. when running it through 'adb shell'). + // + // The location /sdcard is directly accessible from native code + // and is the only location (unofficially) supported by the Android + // team. It's generally a symlink to the real SD Card mount point + // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or + // other OEM-customized locations. Never rely on these, and always + // use /sdcard. + char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; +# else + char name_template[] = "/tmp/captured_stream.XXXXXX"; +# endif // GTEST_OS_LINUX_ANDROID + const int captured_fd = mkstemp(name_template); + filename_ = name_template; +# endif // GTEST_OS_WINDOWS + fflush(NULL); + dup2(captured_fd, fd_); + close(captured_fd); + } + + ~CapturedStream() { + remove(filename_.c_str()); + } + + std::string GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const std::string content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + // Reads the entire content of a file as an std::string. + static std::string ReadEntireFile(FILE* file); + + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); + + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; + +// Returns the size (in bytes) of a file. +size_t CapturedStream::GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast(ftell(file)); +} + +// Reads the entire content of a file as a string. +std::string CapturedStream::ReadEntireFile(FILE* file) { + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; + + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far + + fseek(file, 0, SEEK_SET); + + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do { + bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); + + const std::string content(buffer, bytes_read); + delete[] buffer; + + return content; +} + +# ifdef _MSC_VER +# pragma warning(pop) +# endif // _MSC_VER + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +std::string GetCapturedStream(CapturedStream** captured_stream) { + const std::string content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = NULL; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +std::string GetCapturedStdout() { + return GetCapturedStream(&g_captured_stdout); +} + +// Stops capturing stderr and returns the captured string. +std::string GetCapturedStderr() { + return GetCapturedStream(&g_captured_stderr); +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +::std::vector g_argvs; + +static const ::std::vector* g_injected_test_argvs = + NULL; // Owned. + +void SetInjectableArgvs(const ::std::vector* argvs) { + if (g_injected_test_argvs != argvs) + delete g_injected_test_argvs; + g_injected_test_argvs = argvs; +} + +const ::std::vector& GetInjectableArgvs() { + if (g_injected_test_argvs != NULL) { + return *g_injected_test_argvs; + } + return g_argvs; +} +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); +} +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static std::string FlagToEnvVar(const char* flag) { + const std::string full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); + + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) { + env_var << ToUpper(full_flag.c_str()[i]); + } + + return env_var.GetString(); +} + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { + // Parses the environment variable as a decimal integer. + char* end = NULL; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + *value = result; + return true; +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == NULL) { + // The environment variable is not set. + return default_value; + } + + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } + + return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromGTestEnv(const char* flag, const char* default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const value = posix::GetEnv(env_var.c_str()); + return value == NULL ? default_value : value; +} + +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/gtest-1.7.0/src/gtest-printers.cc b/cpp/thirdparty/gtest-1.7.0/src/gtest-printers.cc new file mode 100644 index 0000000..75fa408 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/src/gtest-printers.cc @@ -0,0 +1,363 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// It uses the << operator when possible, and prints the bytes in the +// object otherwise. A user can override its behavior for a class +// type Foo by defining either operator<<(::std::ostream&, const Foo&) +// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that +// defines Foo. + +#include "gtest/gtest-printers.h" +#include +#include +#include // NOLINT +#include +#include "gtest/internal/gtest-port.h" + +namespace testing { + +namespace { + +using ::std::ostream; + +// Prints a segment of bytes in the given object. +void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, + size_t count, ostream* os) { + char text[5] = ""; + for (size_t i = 0; i != count; i++) { + const size_t j = start + i; + if (i != 0) { + // Organizes the bytes into groups of 2 for easy parsing by + // human. + if ((j % 2) == 0) + *os << ' '; + else + *os << '-'; + } + GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); + *os << text; + } +} + +// Prints the bytes in the given value to the given ostream. +void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, + ostream* os) { + // Tells the user how big the object is. + *os << count << "-byte object <"; + + const size_t kThreshold = 132; + const size_t kChunkSize = 64; + // If the object size is bigger than kThreshold, we'll have to omit + // some details by printing only the first and the last kChunkSize + // bytes. + // TODO(wan): let the user control the threshold using a flag. + if (count < kThreshold) { + PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); + } else { + PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); + *os << " ... "; + // Rounds up to 2-byte boundary. + const size_t resume_pos = (count - kChunkSize + 1)/2*2; + PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); + } + *os << ">"; +} + +} // namespace + +namespace internal2 { + +// Delegates to PrintBytesInObjectToImpl() to print the bytes in the +// given object. The delegation simplifies the implementation, which +// uses the << operator and thus is easier done outside of the +// ::testing::internal namespace, which contains a << operator that +// sometimes conflicts with the one in STL. +void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, + ostream* os) { + PrintBytesInObjectToImpl(obj_bytes, count, os); +} + +} // namespace internal2 + +namespace internal { + +// Depending on the value of a char (or wchar_t), we print it in one +// of three formats: +// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), +// - as a hexidecimal escape sequence (e.g. '\x7F'), or +// - as a special escape sequence (e.g. '\r', '\n'). +enum CharFormat { + kAsIs, + kHexEscape, + kSpecialEscape +}; + +// Returns true if c is a printable ASCII character. We test the +// value of c directly instead of calling isprint(), which is buggy on +// Windows Mobile. +inline bool IsPrintableAscii(wchar_t c) { + return 0x20 <= c && c <= 0x7E; +} + +// Prints a wide or narrow char c as a character literal without the +// quotes, escaping it when necessary; returns how c was formatted. +// The template argument UnsignedChar is the unsigned version of Char, +// which is the type of c. +template +static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { + switch (static_cast(c)) { + case L'\0': + *os << "\\0"; + break; + case L'\'': + *os << "\\'"; + break; + case L'\\': + *os << "\\\\"; + break; + case L'\a': + *os << "\\a"; + break; + case L'\b': + *os << "\\b"; + break; + case L'\f': + *os << "\\f"; + break; + case L'\n': + *os << "\\n"; + break; + case L'\r': + *os << "\\r"; + break; + case L'\t': + *os << "\\t"; + break; + case L'\v': + *os << "\\v"; + break; + default: + if (IsPrintableAscii(c)) { + *os << static_cast(c); + return kAsIs; + } else { + *os << "\\x" + String::FormatHexInt(static_cast(c)); + return kHexEscape; + } + } + return kSpecialEscape; +} + +// Prints a wchar_t c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { + switch (c) { + case L'\'': + *os << "'"; + return kAsIs; + case L'"': + *os << "\\\""; + return kSpecialEscape; + default: + return PrintAsCharLiteralTo(c, os); + } +} + +// Prints a char c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { + return PrintAsStringLiteralTo( + static_cast(static_cast(c)), os); +} + +// Prints a wide or narrow character c and its code. '\0' is printed +// as "'\\0'", other unprintable characters are also properly escaped +// using the standard C++ escape sequence. The template argument +// UnsignedChar is the unsigned version of Char, which is the type of c. +template +void PrintCharAndCodeTo(Char c, ostream* os) { + // First, print c as a literal in the most readable form we can find. + *os << ((sizeof(c) > 1) ? "L'" : "'"); + const CharFormat format = PrintAsCharLiteralTo(c, os); + *os << "'"; + + // To aid user debugging, we also print c's code in decimal, unless + // it's 0 (in which case c was printed as '\\0', making the code + // obvious). + if (c == 0) + return; + *os << " (" << static_cast(c); + + // For more convenience, we print c's code again in hexidecimal, + // unless c was already printed in the form '\x##' or the code is in + // [1, 9]. + if (format == kHexEscape || (1 <= c && c <= 9)) { + // Do nothing. + } else { + *os << ", 0x" << String::FormatHexInt(static_cast(c)); + } + *os << ")"; +} + +void PrintTo(unsigned char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} +void PrintTo(signed char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} + +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its code. L'\0' is printed as "L'\\0'". +void PrintTo(wchar_t wc, ostream* os) { + PrintCharAndCodeTo(wc, os); +} + +// Prints the given array of characters to the ostream. CharType must be either +// char or wchar_t. +// The array starts at begin, the length is len, it may include '\0' characters +// and may not be NUL-terminated. +template +static void PrintCharsAsStringTo( + const CharType* begin, size_t len, ostream* os) { + const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; + *os << kQuoteBegin; + bool is_previous_hex = false; + for (size_t index = 0; index < len; ++index) { + const CharType cur = begin[index]; + if (is_previous_hex && IsXDigit(cur)) { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" " << kQuoteBegin; + } + is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; + } + *os << "\""; +} + +// Prints a (const) char/wchar_t array of 'len' elements, starting at address +// 'begin'. CharType must be either char or wchar_t. +template +static void UniversalPrintCharArray( + const CharType* begin, size_t len, ostream* os) { + // The code + // const char kFoo[] = "foo"; + // generates an array of 4, not 3, elements, with the last one being '\0'. + // + // Therefore when printing a char array, we don't print the last element if + // it's '\0', such that the output matches the string literal as it's + // written in the source code. + if (len > 0 && begin[len - 1] == '\0') { + PrintCharsAsStringTo(begin, len - 1, os); + return; + } + + // If, however, the last element in the array is not '\0', e.g. + // const char kFoo[] = { 'f', 'o', 'o' }; + // we must print the entire array. We also print a message to indicate + // that the array is not NUL-terminated. + PrintCharsAsStringTo(begin, len, os); + *os << " (no terminating NUL)"; +} + +// Prints a (const) char array of 'len' elements, starting at address 'begin'. +void UniversalPrintArray(const char* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints a (const) wchar_t array of 'len' elements, starting at address +// 'begin'. +void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints the given C string to the ostream. +void PrintTo(const char* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, strlen(s), os); + } +} + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Prints the given wide C string to the ostream. +void PrintTo(const wchar_t* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, wcslen(s), os); + } +} +#endif // wchar_t is native + +// Prints a ::string object. +#if GTEST_HAS_GLOBAL_STRING +void PrintStringTo(const ::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +void PrintStringTo(const ::std::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} + +// Prints a ::wstring object. +#if GTEST_HAS_GLOBAL_WSTRING +void PrintWideStringTo(const ::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +void PrintWideStringTo(const ::std::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_STD_WSTRING + +} // namespace internal + +} // namespace testing diff --git a/cpp/thirdparty/gtest-1.7.0/src/gtest-test-part.cc b/cpp/thirdparty/gtest-1.7.0/src/gtest-test-part.cc new file mode 100644 index 0000000..c60eef3 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/src/gtest-test-part.cc @@ -0,0 +1,110 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + +#include "gtest/gtest-test-part.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +using internal::GetUnitTestImpl; + +// Gets the summary of the failure message by omitting the stack trace +// in it. +std::string TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? message : + std::string(message, stack_trace); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + array_.push_back(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } + + return array_[index]; +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return static_cast(array_.size()); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()-> + GetTestPartResultReporterForCurrentThread()) { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing diff --git a/cpp/thirdparty/gtest-1.7.0/src/gtest-typed-test.cc b/cpp/thirdparty/gtest-1.7.0/src/gtest-typed-test.cc new file mode 100644 index 0000000..f0079f4 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/src/gtest-typed-test.cc @@ -0,0 +1,110 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest-typed-test.h" +#include "gtest/gtest.h" + +namespace testing { +namespace internal { + +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (IsSpace(*str)) + str++; + return str; +} + +// Verifies that registered_tests match the test names in +// defined_test_names_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestCasePState::VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests) { + typedef ::std::set::const_iterator DefinedTestIter; + registered_ = true; + + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); + + Message errors; + ::std::set tests; + for (const char* names = registered_tests; names != NULL; + names = SkipComma(names)) { + const std::string name = GetPrefixUntilComma(names); + if (tests.count(name) != 0) { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } + + bool found = false; + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (name == *it) { + found = true; + break; + } + } + + if (found) { + tests.insert(name); + } else { + errors << "No test named " << name + << " can be found in this test case.\n"; + } + } + + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (tests.count(*it) == 0) { + errors << "You forgot to list test " << *it << ".\n"; + } + } + + const std::string& errors_str = errors.GetString(); + if (errors_str != "") { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } + + return registered_tests; +} + +#endif // GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/gtest-1.7.0/src/gtest.cc b/cpp/thirdparty/gtest-1.7.0/src/gtest.cc new file mode 100644 index 0000000..6de53dd --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/src/gtest.cc @@ -0,0 +1,5015 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include // NOLINT +#include +#include + +#if GTEST_OS_LINUX + +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +# include // NOLINT +# include // NOLINT +# include // NOLINT +// Declares vsnprintf(). This header is not available on Windows. +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include + +#elif GTEST_OS_SYMBIAN +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +#elif GTEST_OS_ZOS +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +# include // NOLINT + +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. + +# include // NOLINT + +#elif GTEST_OS_WINDOWS // We are on Windows proper. + +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT + +# if GTEST_OS_WINDOWS_MINGW +// MinGW has gettimeofday() but not _ftime64(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +// TODO(kenton@google.com): There are other ways to get the time on +// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW +// supports these. consider using them instead. +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT +# endif // GTEST_OS_WINDOWS_MINGW + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT + +#else + +// Assume other platforms have gettimeofday(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT +# include // NOLINT + +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +# include +#endif + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +#endif + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS +# define vsnprintf _vsnprintf +#endif // GTEST_OS_WINDOWS + +namespace testing { + +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + +// Constants. + +// A test whose test case name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test case whose name matches this filter is considered a death +// test case and will be run before test cases whose name doesn't +// match this filter. +static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output file for XML output. +static const char kDefaultOutputFile[] = "test_detail.xml"; + +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + +} // namespace internal + +static const char* GetDefaultFilter() { + return kUniversalFilter; +} + +GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( + break_on_failure, + internal::BoolFromGTestEnv("break_on_failure", false), + "True iff a failed assertion should be a debugger break-point."); + +GTEST_DEFINE_bool_( + catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", true), + "True iff " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to a terminal type that supports colors."); + +GTEST_DEFINE_string_( + filter, + internal::StringFromGTestEnv("filter", GetDefaultFilter()), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); + +GTEST_DEFINE_string_( + output, + internal::StringFromGTestEnv("output", ""), + "A format (currently must be \"xml\"), optionally followed " + "by a colon and an output file name or directory. A directory " + "is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); + +GTEST_DEFINE_bool_( + print_time, + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ + " should display elapsed time in text output."); + +GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +GTEST_DEFINE_int32_( + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); + +GTEST_DEFINE_bool_( + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_( + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); + +GTEST_DEFINE_int32_( + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_string_( + stream_result_to, + internal::StringFromGTestEnv("stream_result_to", ""), + "This flag specifies the host name and the port number on which to stream " + "test results. Example: \"localhost:555\". The flag is effective only on " + "Linux."); + +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); + +namespace internal { + +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + +// GTestIsInitialized() returns true iff the user has initialized +// Google Test. Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +// +// A user must call testing::InitGoogleTest() to initialize Google +// Test. g_init_gtest_count is set to the number of times +// InitGoogleTest() has been called. We don't protect this variable +// under a mutex as it is only accessed in the main thread. +GTEST_API_ int g_init_gtest_count = 0; +static bool GTestIsInitialized() { return g_init_gtest_count != 0; } + +// Iterates over a vector of TestCases, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestCaseList(const std::vector& case_list, + int (TestCase::*method)() const) { + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); + } + return sum; +} + +// Returns true iff the test case passed. +static bool TestCasePassed(const TestCase* test_case) { + return test_case->should_run() && test_case->Passed(); +} + +// Returns true iff the test case failed. +static bool TestCaseFailed(const TestCase* test_case) { + return test_case->should_run() && test_case->Failed(); +} + +// Returns true iff test_case contains at least one test that should +// run. +static bool ShouldRunTestCase(const TestCase* test_case) { + return test_case->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { + UnitTest::GetInstance()-> + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl() + ->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT +} + +// Mutex for linked pointers. +GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// Application pathname gotten in InitGoogleTest. +std::string g_executable_path; + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { + FilePath result; + +#if GTEST_OS_WINDOWS + result.Set(FilePath(g_executable_path).RemoveExtension("exe")); +#else + result.Set(FilePath(g_executable_path)); +#endif // GTEST_OS_WINDOWS + + return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +std::string UnitTestOptions::GetOutputFormat() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) return std::string(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == NULL) ? + std::string(gtest_output_flag) : + std::string(gtest_output_flag, colon - gtest_output_flag); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +std::string UnitTestOptions::GetAbsolutePathToOutputFile() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) + return ""; + + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == NULL) + return internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).string(); + + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + + if (!output_name.IsDirectory()) + return output_name.string(); + + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.string(); +} + +// Returns true iff the wildcard pattern matches the string. The +// first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, + const char *str) { + switch (*pattern) { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } +} + +bool UnitTestOptions::MatchesFilter( + const std::string& name, const char* filter) { + const char *cur_pattern = filter; + for (;;) { + if (PatternMatchesString(cur_pattern, name.c_str())) { + return true; + } + + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); + + // Returns if no more pattern can be found. + if (cur_pattern == NULL) { + return false; + } + + // Skips the pattern separater (the ':' character). + cur_pattern++; + } +} + +// Returns true iff the user-specified filter matches the test case +// name and the test name. +bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name) { + const std::string& full_name = test_case_name + "." + test_name.c_str(); + + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + std::string positive; + std::string negative; + if (dash == NULL) { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = ""; + } else { + positive = std::string(p, dash); // Everything up to the dash + negative = std::string(dash + 1); // Everything after the dash + if (positive.empty()) { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } + + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); +} + +#if GTEST_HAS_SEH +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { + // Google Test should handle a SEH exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception, AND + // 3. this is not a C++ exception (VC++ implements them via SEH, + // apparently). + // + // SEH exception code for C++ exceptions. + // (see http://support.microsoft.com/kb/185294 for more information). + const DWORD kCxxExceptionCode = 0xe06d7363; + + bool should_handle = true; + + if (!GTEST_FLAG(catch_exceptions)) + should_handle = false; + else if (exception_code == EXCEPTION_BREAKPOINT) + should_handle = false; + else if (exception_code == kCxxExceptionCode) + should_handle = false; + + return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} +#endif // GTEST_HAS_SEH + +} // namespace internal + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test. We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test. This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X. The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code. GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { + return GetTypeId(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +AssertionResult HasOneFailure(const char* /* results_expr */, + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const string& substr) { + const std::string expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); + Message msg; + if (results.size() != 1) { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) { + msg << "\n" << results.GetTestPartResult(i); + } + return AssertionFailure() << msg; + } + + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) { + return AssertionFailure() << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + } + + if (strstr(r.message(), substr.c_str()) == NULL) { + return AssertionFailure() << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + } + + return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker:: SingleFailureChecker( + const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr) + : results_(results), + type_(type), + substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter) { + per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test cases. +int UnitTestImpl::successful_test_case_count() const { + return CountIf(test_cases_, TestCasePassed); +} + +// Gets the number of failed test cases. +int UnitTestImpl::failed_test_case_count() const { + return CountIf(test_cases_, TestCaseFailed); +} + +// Gets the number of all test cases. +int UnitTestImpl::total_test_case_count() const { + return static_cast(test_cases_.size()); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTestImpl::test_case_to_run_count() const { + return CountIf(test_cases_, ShouldRunTestCase); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +} + +// Gets the number of disabled tests that will be reported in the XML report. +int UnitTestImpl::reportable_disabled_test_count() const { + return SumOverTestCaseList(test_cases_, + &TestCase::reportable_disabled_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +} + +// Gets the number of tests to be printed in the XML report. +int UnitTestImpl::reportable_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { + (void)skip_count; + return ""; +} + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; + + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + // TODO(kenton@google.com): Shouldn't this just use + // GetSystemTimeAsFileTime()? + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ + __timeb64 now; + +# ifdef _MSC_VER + + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + // TODO(kenton@google.com): Use GetTickCount()? Or use + // SystemTimeToFileTime() +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996. + _ftime64(&now); +# pragma warning(pop) // Restores the warning state. +# else + + _ftime64(&now); + +# endif // _MSC_VER + + return static_cast(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, NULL); + return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +# error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String. + +#if GTEST_OS_WINDOWS_MOBILE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { + if (!ansi) return NULL; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, + NULL, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { + if (!utf16_str) return NULL; + const int ansi_length = + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + NULL, 0, NULL, NULL); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + ansi, ansi_length, NULL, NULL); + ansi[ansi_length] = 0; + return ansi; +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +// Compares two C strings. Returns true iff they have the same content. +// +// Unlike strcmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + + return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, + Message* msg) { + for (size_t i = 0; i != length; ) { // NOLINT + if (wstr[i] != L'\0') { + *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } else { + *msg << '\0'; + i++; + } + } +} + +#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +} // namespace internal + +// Constructs an empty Message. +// We allocate the stringstream separately because otherwise each use of +// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's +// stack frame leading to huge stack frames in some cases; gcc does not reuse +// the stack space. +Message::Message() : ss_(new ::std::stringstream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); +} + +// These two overloads allow streaming a wide C string to a Message +// using the UTF-8 encoding. +Message& Message::operator <<(const wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); +} +Message& Message::operator <<(wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); +} + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Gets the text streamed to this object so far as an std::string. +// Each '\0' character in the buffer is replaced with "\\0". +std::string Message::GetString() const { + return internal::StringStreamToString(ss_.get()); +} + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new ::std::string(*other.message_) : + static_cast< ::std::string*>(NULL)) { +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { + return AssertionResult(true); +} + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +namespace internal { + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case) { + Message msg; + msg << "Value of: " << actual_expression; + if (actual_value != actual_expression) { + msg << "\n Actual: " << actual_value; + } + + msg << "\nExpected: " << expected_expression; + if (ignoring_case) { + msg << " (ignoring case)"; + } + if (expected_value != expected_expression) { + msg << "\nWhich is: " << expected_value; + } + + return AssertionFailure() << msg; +} + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) { + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); + + // TODO(wan): do not print the value of an expression if it's + // already a literal. + return AssertionFailure() + << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template +AssertionResult FloatingPointLE(const char* expr1, + const char* expr2, + RawType val1, + RawType val2) { + // Returns success if val1 is less than val2, + if (val1 < val2) { + return AssertionSuccess(); + } + + // or if val1 is almost equal to val2. + const FloatingPoint lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. + + ::std::stringstream val1_ss; + val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val1; + + ::std::stringstream val2_ss; + val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val2; + + return AssertionFailure() + << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StringStreamToString(&val1_ss) << " vs " + << StringStreamToString(&val2_ss); +} + +} // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + if (expected == actual) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CaseInsensitiveCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CaseInsensitiveCStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +} // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true iff needle is a +// substring of haystack. NULL is considered a substring of itself +// only. + +bool IsSubstringPred(const char* needle, const char* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return strstr(haystack, needle) != NULL; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return wcsstr(haystack, needle) != NULL; +} + +// StringType here can be either ::std::string or ::std::wstring. +template +bool IsSubstringPred(const StringType& needle, + const StringType& haystack) { + return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template +AssertionResult IsSubstringImpl( + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) { + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""; +} + +} // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +#if GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, + const char* expected, + long hr) { // NOLINT +# if GTEST_OS_WINDOWS_MOBILE + + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; + +# else + + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = { '\0' }; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + hr, // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + NULL); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing CR-LF) + for (; message_length && IsSpace(error_text[message_length - 1]); + --message_length) { + error_text[message_length - 1] = '\0'; + } + +# endif // GTEST_OS_WINDOWS_MOBILE + + const std::string error_hex("0x" + String::FormatHexInt(hr)); + return ::testing::AssertionFailure() + << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << " " << error_text << "\n"; +} + +} // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT + if (SUCCEEDED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT + if (FAILED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length Encoding +// 0 - 7 bits 0xxxxxxx +// 8 - 11 bits 110xxxxx 10xxxxxx +// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx +// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern. Returns the n +// lowest bits. As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { + const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); + *bits >>= n; + return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted +// to "(Invalid Unicode 0xXXXXXXXX)". +std::string CodePointToUtf8(UInt32 code_point) { + if (code_point > kMaxCodePoint4) { + return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")"; + } + + char str[5]; // Big enough for the largest valid code point. + if (code_point <= kMaxCodePoint1) { + str[1] = '\0'; + str[0] = static_cast(code_point); // 0xxxxxxx + } else if (code_point <= kMaxCodePoint2) { + str[2] = '\0'; + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xC0 | code_point); // 110xxxxx + } else if (code_point <= kMaxCodePoint3) { + str[3] = '\0'; + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xE0 | code_point); // 1110xxxx + } else { // code_point <= kMaxCodePoint4 + str[4] = '\0'; + str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xF0 | code_point); // 11110xxx + } + return str; +} + +// The following two functions only make sense if the the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast(first); +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +std::string WideStringToUtf8(const wchar_t* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast(wcslen(str)); + + ::std::stringstream stream; + for (int i = 0; i < num_chars; ++i) { + UInt32 unicode_code_point; + + if (str[i] == L'\0') { + break; + } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } else { + unicode_code_point = static_cast(str[i]); + } + + stream << CodePointToUtf8(unicode_code_point); + } + return StringStreamToString(&stream); +} + +// Converts a wide C string to an std::string using the UTF-8 encoding. +// NULL will be converted to "(null)". +std::string String::ShowWideCString(const wchar_t * wide_c_str) { + if (wide_c_str == NULL) return "(null)"; + + return internal::WideStringToUtf8(wide_c_str, -1); +} + +// Compares two wide C strings. Returns true iff they have the same +// content. +// +// Unlike wcscmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + + return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual) { + if (String::WideCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) { + if (!String::WideCStringEquals(s1, s2)) { + return AssertionSuccess(); + } + + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << PrintToString(s1) + << " vs " << PrintToString(s2); +} + +// Compares two C strings, ignoring case. Returns true iff they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s). A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; +} + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + +#if GTEST_OS_WINDOWS + return _wcsicmp(lhs, rhs) == 0; +#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID + return wcscasecmp(lhs, rhs) == 0; +#else + // Android, Mac OS X and Cygwin don't define wcscasecmp. + // Other unknown OSes may not define it either. + wint_t left, right; + do { + left = towlower(*lhs++); + right = towlower(*rhs++); + } while (left && left == right); + return left == right; +#endif // OS selector +} + +// Returns true iff str ends with the given suffix, ignoring case. +// Any string is considered to end with an empty suffix. +bool String::EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix) { + const size_t str_len = str.length(); + const size_t suffix_len = suffix.length(); + return (str_len >= suffix_len) && + CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, + suffix.c_str()); +} + +// Formats an int value as "%02d". +std::string String::FormatIntWidth2(int value) { + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << value; + return ss.str(); +} + +// Formats an int value as "%X". +std::string String::FormatHexInt(int value) { + std::stringstream ss; + ss << std::hex << std::uppercase << value; + return ss.str(); +} + +// Formats a byte as "%02X". +std::string String::FormatByte(unsigned char value) { + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase + << static_cast(value); + return ss.str(); +} + +// Converts the buffer in a stringstream to an std::string, converting NUL +// bytes to "\\0" along the way. +std::string StringStreamToString(::std::stringstream* ss) { + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); + + std::string result; + result.reserve(2 * (end - start)); + for (const char* ch = start; ch != end; ++ch) { + if (*ch == '\0') { + result += "\\0"; // Replaces NUL with "\\0"; + } else { + result += *ch; + } + } + + return result; +} + +// Appends the user-supplied message to the Google-Test-generated message. +std::string AppendUserMessage(const std::string& gtest_msg, + const Message& user_msg) { + // Appends the user message if it's non-empty. + const std::string user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) { + return gtest_msg; + } + + return gtest_msg + "\n" + user_msg_string; +} + +} // namespace internal + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() + : death_test_count_(0), + elapsed_time_(0) { +} + +// D'tor. +TestResult::~TestResult() { +} + +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { + test_part_results_.push_back(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const std::string& xml_element, + const TestProperty& test_property) { + if (!ValidateTestProperty(xml_element, test_property)) { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); +} + +// The list of reserved attributes used in the element of XML +// output. +static const char* const kReservedTestSuitesAttributes[] = { + "disabled", + "errors", + "failures", + "name", + "random_seed", + "tests", + "time", + "timestamp" +}; + +// The list of reserved attributes used in the element of XML +// output. +static const char* const kReservedTestSuiteAttributes[] = { + "disabled", + "errors", + "failures", + "name", + "tests", + "time" +}; + +// The list of reserved attributes used in the element of XML output. +static const char* const kReservedTestCaseAttributes[] = { + "classname", + "name", + "status", + "time", + "type_param", + "value_param" +}; + +template +std::vector ArrayAsVector(const char* const (&array)[kSize]) { + return std::vector(array, array + kSize); +} + +static std::vector GetReservedAttributesForElement( + const std::string& xml_element) { + if (xml_element == "testsuites") { + return ArrayAsVector(kReservedTestSuitesAttributes); + } else if (xml_element == "testsuite") { + return ArrayAsVector(kReservedTestSuiteAttributes); + } else if (xml_element == "testcase") { + return ArrayAsVector(kReservedTestCaseAttributes); + } else { + GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; + } + // This code is unreachable but some compilers may not realizes that. + return std::vector(); +} + +static std::string FormatWordList(const std::vector& words) { + Message word_list; + for (size_t i = 0; i < words.size(); ++i) { + if (i > 0 && words.size() > 2) { + word_list << ", "; + } + if (i == words.size() - 1) { + word_list << "and "; + } + word_list << "'" << words[i] << "'"; + } + return word_list.GetString(); +} + +bool ValidateTestPropertyName(const std::string& property_name, + const std::vector& reserved_names) { + if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != + reserved_names.end()) { + ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name + << " (" << FormatWordList(reserved_names) + << " are reserved by " << GTEST_NAME_ << ")"; + return false; + } + return true; +} + +// Adds a failure if the key is a reserved attribute of the element named +// xml_element. Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const std::string& xml_element, + const TestProperty& test_property) { + return ValidateTestPropertyName(test_property.key(), + GetReservedAttributesForElement(xml_element)); +} + +// Clears the object. +void TestResult::Clear() { + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; +} + +// Returns true iff the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; +} + +// Returns true iff the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult& result) { + return result.fatally_failed(); +} + +// Returns true iff the test fatally failed. +bool TestResult::HasFatalFailure() const { + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true iff the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true iff the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +} + +// Gets the number of all test parts. This is the sum of the number +// of successful test parts and the number of failed test parts. +int TestResult::total_part_count() const { + return static_cast(test_part_results_.size()); +} + +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast(test_properties_.size()); +} + +// class Test + +// Creates a Test object. + +// The c'tor saves the values of all Google Test flags. +Test::Test() + : gtest_flag_saver_(new internal::GTestFlagSaver) { +} + +// The d'tor restores the values of all Google Test flags. +Test::~Test() { + delete gtest_flag_saver_; +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const std::string& key, const std::string& value) { + UnitTest::GetInstance()->RecordProperty(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const std::string& key, int value) { + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); +} + +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + ""); // No stack trace, either. +} + +} // namespace internal + +// Google Test requires all tests in the same test case to use the same test +// fixture class. This function checks if the current test has the +// same fixture class as the first test in the current test case. If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestCase* const test_case = impl->current_test_case(); + + // Info about the first test in the current test case. + const TestInfo* const first_test_info = test_case->test_info_list()[0]; + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; + const char* const first_test_name = first_test_info->name(); + + // Info about the current test. + const TestInfo* const this_test_info = impl->current_test_info(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; + const char* const this_test_name = this_test_info->name(); + + if (this_fixture_id != first_fixture_id) { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + + if (first_is_TEST || this_is_TEST) { + // The user mixed TEST and TEST_F in this test case - we'll tell + // him/her how to fix it. + + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; + + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test case is\n" + << "illegal. In test case " << this_test_info->test_case_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } else { + // The user defined two fixture classes with the same name in + // two namespaces - we'll tell him/her how to fix it. + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " + << this_test_info->test_case_name() << ",\n" + << "you defined test " << first_test_name + << " and test " << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test cases."; + } + return false; + } + + return true; +} + +#if GTEST_HAS_SEH + +// Adds an "exception thrown" fatal failure to the current test. This +// function returns its result via an output parameter pointer because VC++ +// prohibits creation of objects with destructors on stack in functions +// using __try (see error C2712). +static std::string* FormatSehExceptionMessage(DWORD exception_code, + const char* location) { + Message message; + message << "SEH exception with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " thrown in " << location << "."; + + return new std::string(message.GetString()); +} + +#endif // GTEST_HAS_SEH + +namespace internal { + +#if GTEST_HAS_EXCEPTIONS + +// Adds an "exception thrown" fatal failure to the current test. +static std::string FormatCxxExceptionMessage(const char* description, + const char* location) { + Message message; + if (description != NULL) { + message << "C++ exception with description \"" << description << "\""; + } else { + message << "Unknown C++ exception"; + } + message << " thrown in " << location << "."; + + return message.GetString(); +} + +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result); + +GoogleTestFailureException::GoogleTestFailureException( + const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} + +#endif // GTEST_HAS_EXCEPTIONS + +// We put these helper functions in the internal namespace as IBM's xlC +// compiler rejects the code if they were declared static. + +// Runs the given method and handles SEH exceptions it throws, when +// SEH is supported; returns the 0-value for type Result in case of an +// SEH exception. (Microsoft compilers cannot handle SEH and C++ +// exceptions in the same function. Therefore, we provide a separate +// wrapper function for handling SEH exceptions.) +template +Result HandleSehExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { +#if GTEST_HAS_SEH + __try { + return (object->*method)(); + } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT + GetExceptionCode())) { + // We create the exception message on the heap because VC++ prohibits + // creation of objects with destructors on stack in functions using __try + // (see error C2712). + std::string* exception_message = FormatSehExceptionMessage( + GetExceptionCode(), location); + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + *exception_message); + delete exception_message; + return static_cast(0); + } +#else + (void)location; + return (object->*method)(); +#endif // GTEST_HAS_SEH +} + +// Runs the given method and catches and reports C++ and/or SEH-style +// exceptions, if they are supported; returns the 0-value for type +// Result in case of an SEH exception. +template +Result HandleExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { + // NOTE: The user code can affect the way in which Google Test handles + // exceptions by setting GTEST_FLAG(catch_exceptions), but only before + // RUN_ALL_TESTS() starts. It is technically possible to check the flag + // after the exception is caught and either report or re-throw the + // exception based on the flag's value: + // + // try { + // // Perform the test method. + // } catch (...) { + // if (GTEST_FLAG(catch_exceptions)) + // // Report the exception as failure. + // else + // throw; // Re-throws the original exception. + // } + // + // However, the purpose of this flag is to allow the program to drop into + // the debugger when the exception is thrown. On most platforms, once the + // control enters the catch block, the exception origin information is + // lost and the debugger will stop the program at the point of the + // re-throw in this function -- instead of at the point of the original + // throw statement in the code under test. For this reason, we perform + // the check early, sacrificing the ability to affect Google Test's + // exception handling in the method where the exception is thrown. + if (internal::GetUnitTestImpl()->catch_exceptions()) { +#if GTEST_HAS_EXCEPTIONS + try { + return HandleSehExceptionsInMethodIfSupported(object, method, location); + } catch (const internal::GoogleTestFailureException&) { // NOLINT + // This exception type can only be thrown by a failed Google + // Test assertion with the intention of letting another testing + // framework catch it. Therefore we just re-throw it. + throw; + } catch (const std::exception& e) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(e.what(), location)); + } catch (...) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(NULL, location)); + } + return static_cast(0); +#else + return HandleSehExceptionsInMethodIfSupported(object, method, location); +#endif // GTEST_HAS_EXCEPTIONS + } else { + return (object->*method)(); + } +} + +} // namespace internal + +// Runs the test and updates the test result. +void Test::Run() { + if (!HasSameFixtureClass()) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); + // We will run the test only if SetUp() was successful. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TestBody, "the test body"); + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TearDown, "TearDown()"); +} + +// Returns true iff the current test has a fatal failure. +bool Test::HasFatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// Returns true iff the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object. +TestInfo::TestInfo(const std::string& a_test_case_name, + const std::string& a_name, + const char* a_type_param, + const char* a_value_param, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) + : test_case_name_(a_test_case_name), + name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + value_param_(a_value_param ? new std::string(a_value_param) : NULL), + fixture_class_id_(fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory), + result_() {} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { delete factory_; } + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param: the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param: text representation of the test's value parameter, +// or NULL if this is not a value-parameterized test. +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, + const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory) { + TestInfo* const test_info = + new TestInfo(test_case_name, name, type_param, value_param, + fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; +} + +#if GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line) { + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; + + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors.GetString().c_str()); +} +#endif // GTEST_HAS_PARAM_TEST + +} // namespace internal + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestCase class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. +class TestNameIs { + public: + // Constructor. + // + // TestNameIs has NO default constructor. + explicit TestNameIs(const char* name) + : name_(name) {} + + // Returns true iff the test name of test_info matches name_. + bool operator()(const TestInfo * test_info) const { + return test_info && test_info->name() == name_; + } + + private: + std::string name_; +}; + +} // namespace + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#if GTEST_HAS_PARAM_TEST + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +#endif +} + +} // namespace internal + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfo::Run() { + if (!should_run_) return; + + // Tells UnitTest where to store test result. + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*this); + + const TimeInMillis start = internal::GetTimeInMillis(); + + impl->os_stack_trace_getter()->UponLeavingGTest(); + + // Creates the test object. + Test* const test = internal::HandleExceptionsInMethodIfSupported( + factory_, &internal::TestFactoryBase::CreateTest, + "the test fixture's constructor"); + + // Runs the test only if the test object was created and its + // constructor didn't generate a fatal failure. + if ((test != NULL) && !Test::HasFatalFailure()) { + // This doesn't throw as all user code that can throw are wrapped into + // exception handling code. + test->Run(); + } + + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + test, &Test::DeleteSelf_, "the test fixture's destructor"); + + result_.set_elapsed_time(internal::GetTimeInMillis() - start); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*this); + + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(NULL); +} + +// class TestCase + +// Gets the number of successful tests in this test case. +int TestCase::successful_test_count() const { + return CountIf(test_info_list_, TestPassed); +} + +// Gets the number of failed tests in this test case. +int TestCase::failed_test_count() const { + return CountIf(test_info_list_, TestFailed); +} + +// Gets the number of disabled tests that will be reported in the XML report. +int TestCase::reportable_disabled_test_count() const { + return CountIf(test_info_list_, TestReportableDisabled); +} + +// Gets the number of disabled tests in this test case. +int TestCase::disabled_test_count() const { + return CountIf(test_info_list_, TestDisabled); +} + +// Gets the number of tests to be printed in the XML report. +int TestCase::reportable_test_count() const { + return CountIf(test_info_list_, TestReportable); +} + +// Get the number of tests in this test case that should run. +int TestCase::test_to_run_count() const { + return CountIf(test_info_list_, ShouldRunTest); +} + +// Gets the number of all tests. +int TestCase::total_test_count() const { + return static_cast(test_info_list_.size()); +} + +// Creates a TestCase with the given name. +// +// Arguments: +// +// name: name of the test case +// a_type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase::TestCase(const char* a_name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) + : name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + elapsed_time_(0) { +} + +// Destructor of TestCase. +TestCase::~TestCase() { + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestCase::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Adds a test to this test case. Will delete the test upon +// destruction of the TestCase object. +void TestCase::AddTestInfo(TestInfo * test_info) { + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast(test_indices_.size())); +} + +// Runs every test in this TestCase. +void TestCase::Run() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_case(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + repeater->OnTestCaseStart(*this); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); + + const internal::TimeInMillis start = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start; + + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); + + repeater->OnTestCaseEnd(*this); + impl->set_current_test_case(NULL); +} + +// Clears the results of all tests in this test case. +void TestCase::ClearResult() { + ad_hoc_test_result_.Clear(); + ForEach(test_info_list_, TestInfo::ClearTestResult); +} + +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast(i); + } +} + +// Formats a countable noun. Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static std::string FormatCountableNoun(int count, + const char * singular_form, + const char * plural_form) { + return internal::StreamableToString(count) + " " + + (count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static std::string FormatTestCount(int test_count) { + return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test cases. +static std::string FormatTestCaseCount(int test_case_count) { + return FormatCountableNoun(test_case_count, "test case", "test cases"); +} + +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { + switch (type) { + case TestPartResult::kSuccess: + return "Success"; + + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: +#ifdef _MSC_VER + return "error: "; +#else + return "Failure\n"; +#endif + default: + return "Unknown result type"; + } +} + +namespace internal { + +// Prints a TestPartResult to an std::string. +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + +// Prints a TestPartResult. +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const std::string& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif +} + +// class PrettyUnitTestResultPrinter + +enum GTestColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GTestColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. +const char* GetAnsiColorCode(GTestColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + default: return NULL; + }; +} + +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns true iff Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { + const char* const gtest_color = GTEST_FLAG(color).c_str(); + + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#if GTEST_OS_WINDOWS + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "screen") || + String::CStringEquals(term, "screen-256color") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; +#endif // GTEST_OS_WINDOWS + } + + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS + const bool use_color = false; +#else + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + + if (!use_color) { + vprintf(fmt, args); + va_end(args); + return; + } + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + va_end(args); +} + +// Text printed in Google Test's text output and --gunit_list_tests +// output to label the type parameter and value parameter for a test. +static const char kTypeParamLabel[] = "TypeParam"; +static const char kValueParamLabel[] = "GetParam()"; + +void PrintFullTestCommentIfPresent(const TestInfo& test_info) { + const char* const type_param = test_info.type_param(); + const char* const value_param = test_info.value_param(); + + if (type_param != NULL || value_param != NULL) { + printf(", where "); + if (type_param != NULL) { + printf("%s = %s", kTypeParamLabel, type_param); + if (value_param != NULL) + printf(" and "); + } + if (value_param != NULL) { + printf("%s = %s", kValueParamLabel, value_param); + } + } +} + +// This class implements the TestEventListener interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public TestEventListener { + public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char * test_case, const char * test) { + printf("%s.%s", test_case, test); + } + + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} + + private: + static void PrintFailedTests(const UnitTest& unit_test); +}; + + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); + + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!String::CStringEquals(filter, kUniversalFilter)) { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %d of %s.\n", + static_cast(shard_index) + 1, + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } + + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case.name()); + if (test_case.type_param() == NULL) { + printf("\n"); + } else { + printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_info.test_case_name(), test_info.name()); + printf("\n"); + fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } else { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_info.test_case_name(), test_info.name()); + if (test_info.result()->Failed()) + PrintFullTestCommentIfPresent(test_info); + + if (GTEST_FLAG(print_time)) { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()).c_str()); + } else { + printf("\n"); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; + + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case.name(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); +} + +// Internal helper for printing the list of failed tests. +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_case.name(), test_info.name()); + PrintFullTestCommentIfPresent(test_info); + printf("\n"); + } + } +} + +void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } + + int num_disabled = unit_test.reportable_disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (!num_failures) { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class TestEventRepeater +// +// This class forwards events to other event listeners. +class TestEventRepeater : public TestEventListener { + public: + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); + + private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector listeners_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); +}; + +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete); +} + +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); +} + +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} + +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) + +#undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ + +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit XmlUnitTestResultPrinter(const char* output_file); + + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + + private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) { + return c == 0x9 || c == 0xA || c == 0xD; + } + + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) { + return IsNormalizableWhitespace(c) || c >= 0x20; + } + + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static std::string EscapeXml(const std::string& str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static std::string RemoveInvalidXmlCharacters(const std::string& str); + + // Convenience wrapper around EscapeXml when str is an attribute value. + static std::string EscapeXmlAttribute(const std::string& str) { + return EscapeXml(str, true); + } + + // Convenience wrapper around EscapeXml when str is not an attribute value. + static std::string EscapeXmlText(const char* str) { + return EscapeXml(str, false); + } + + // Verifies that the given attribute belongs to the given element and + // streams the attribute as XML. + static void OutputXmlAttribute(std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value); + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); + + // Prints an XML representation of a TestCase object + static void PrintXmlTestCase(::std::ostream* stream, + const TestCase& test_case); + + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(::std::ostream* stream, + const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the std::string is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static std::string TestPropertiesAsXmlAttributes(const TestResult& result); + + // The output file. + const std::string output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.c_str() == NULL || output_file_.empty()) { + fprintf(stderr, "XML output file may not be null\n"); + fflush(stderr); + exit(EXIT_FAILURE); + } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* xmlout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + xmlout = posix::FOpen(output_file_.c_str(), "w"); + } + if (xmlout == NULL) { + // TODO(wan): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + fprintf(stderr, + "Unable to open file \"%s\"\n", + output_file_.c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + std::stringstream stream; + PrintXmlUnitTest(&stream, unit_test); + fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); + fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str. If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +// TODO(wan): It might be nice to have a minimally invasive, human-readable +// escaping scheme for invalid characters, rather than dropping them. +std::string XmlUnitTestResultPrinter::EscapeXml( + const std::string& str, bool is_attribute) { + Message m; + + for (size_t i = 0; i < str.size(); ++i) { + const char ch = str[i]; + switch (ch) { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(ch)) { + if (is_attribute && IsNormalizableWhitespace(ch)) + m << "&#x" << String::FormatByte(static_cast(ch)) + << ";"; + else + m << ch; + } + break; + } + } + + return m.GetString(); +} + +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( + const std::string& str) { + std::string output; + output.reserve(str.size()); + for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) + if (IsValidXmlCharacter(*it)) + output.push_back(*it); + + return output; +} + +// The following routines generate an XML representation of a UnitTest +// object. +// +// This is how Google Test concepts map to the DTD: +// +// <-- corresponds to a UnitTest object +// <-- corresponds to a TestCase object +// <-- corresponds to a TestInfo object +// ... +// ... +// ... +// <-- individual assertion failures +// +// +// + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << ms/1000.0; + return ss.str(); +} + +// Converts the given epoch time in milliseconds to a date string in the ISO +// 8601 format, without the timezone information. +std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { + // Using non-reentrant version as localtime_r is not portable. + time_t seconds = static_cast(ms / 1000); +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996 + // (function or variable may be unsafe). + const struct tm* const time_struct = localtime(&seconds); // NOLINT +# pragma warning(pop) // Restores the warning state again. +#else + const struct tm* const time_struct = localtime(&seconds); // NOLINT +#endif + if (time_struct == NULL) + return ""; // Invalid ms value + + // YYYY-MM-DDThh:mm:ss + return StreamableToString(time_struct->tm_year + 1900) + "-" + + String::FormatIntWidth2(time_struct->tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct->tm_mday) + "T" + + String::FormatIntWidth2(time_struct->tm_hour) + ":" + + String::FormatIntWidth2(time_struct->tm_min) + ":" + + String::FormatIntWidth2(time_struct->tm_sec); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << ""); + if (next_segment != NULL) { + stream->write( + segment, static_cast(next_segment - segment)); + *stream << "]]>]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} + +void XmlUnitTestResultPrinter::OutputXmlAttribute( + std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value) { + const std::vector& allowed_names = + GetReservedAttributesForElement(element_name); + + GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != + allowed_names.end()) + << "Attribute " << name << " is not allowed for element <" << element_name + << ">."; + + *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; +} + +// Prints an XML representation of a TestInfo object. +// TODO(wan): There is also value in printing properties with the plain printer. +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + const std::string kTestcase = "testcase"; + + *stream << " \n"; + } + const string location = internal::FormatCompilerIndependentFileLocation( + part.file_name(), part.line_number()); + const string summary = location + "\n" + part.summary(); + *stream << " "; + const string detail = location + "\n" + part.message(); + OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); + *stream << "\n"; + } + } + + if (failures == 0) + *stream << " />\n"; + else + *stream << " \n"; +} + +// Prints an XML representation of a TestCase object +void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream, + const TestCase& test_case) { + const std::string kTestsuite = "testsuite"; + *stream << " <" << kTestsuite; + OutputXmlAttribute(stream, kTestsuite, "name", test_case.name()); + OutputXmlAttribute(stream, kTestsuite, "tests", + StreamableToString(test_case.reportable_test_count())); + OutputXmlAttribute(stream, kTestsuite, "failures", + StreamableToString(test_case.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuite, "disabled", + StreamableToString(test_case.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuite, "errors", "0"); + OutputXmlAttribute(stream, kTestsuite, "time", + FormatTimeInMillisAsSeconds(test_case.elapsed_time())); + *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result()) + << ">\n"; + + for (int i = 0; i < test_case.total_test_count(); ++i) { + if (test_case.GetTestInfo(i)->is_reportable()) + OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); + } + *stream << " \n"; +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, + const UnitTest& unit_test) { + const std::string kTestsuites = "testsuites"; + + *stream << "\n"; + *stream << "<" << kTestsuites; + + OutputXmlAttribute(stream, kTestsuites, "tests", + StreamableToString(unit_test.reportable_test_count())); + OutputXmlAttribute(stream, kTestsuites, "failures", + StreamableToString(unit_test.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuites, "disabled", + StreamableToString(unit_test.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuites, "errors", "0"); + OutputXmlAttribute( + stream, kTestsuites, "timestamp", + FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); + OutputXmlAttribute(stream, kTestsuites, "time", + FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); + + if (GTEST_FLAG(shuffle)) { + OutputXmlAttribute(stream, kTestsuites, "random_seed", + StreamableToString(unit_test.random_seed())); + } + + *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); + + OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); + *stream << ">\n"; + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + if (unit_test.GetTestCase(i)->reportable_test_count() > 0) + PrintXmlTestCase(stream, *unit_test.GetTestCase(i)); + } + *stream << "\n"; +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End XmlUnitTestResultPrinter + +#if GTEST_CAN_STREAM_RESULTS_ + +// Checks if str contains '=', '&', '%' or '\n' characters. If yes, +// replaces them by "%xx" where xx is their hexadecimal value. For +// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) +// in both time and space -- important as the input str may contain an +// arbitrarily long test failure message and stack trace. +string StreamingListener::UrlEncode(const char* str) { + string result; + result.reserve(strlen(str) + 1); + for (char ch = *str; ch != '\0'; ch = *++str) { + switch (ch) { + case '%': + case '=': + case '&': + case '\n': + result.append("%" + String::FormatByte(static_cast(ch))); + break; + default: + result.push_back(ch); + break; + } + } + return result; +} + +void StreamingListener::SocketWriter::MakeConnection() { + GTEST_CHECK_(sockfd_ == -1) + << "MakeConnection() can't be called when there is already a connection."; + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. + hints.ai_socktype = SOCK_STREAM; + addrinfo* servinfo = NULL; + + // Use the getaddrinfo() to get a linked list of IP addresses for + // the given host name. + const int error_num = getaddrinfo( + host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); + if (error_num != 0) { + GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " + << gai_strerror(error_num); + } + + // Loop through all the results and connect to the first we can. + for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; + cur_addr = cur_addr->ai_next) { + sockfd_ = socket( + cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); + if (sockfd_ != -1) { + // Connect the client socket to the server socket. + if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { + close(sockfd_); + sockfd_ = -1; + } + } + } + + freeaddrinfo(servinfo); // all done with this structure + + if (sockfd_ == -1) { + GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " + << host_name_ << ":" << port_num_; + } +} + +// End of class Streaming Listener +#endif // GTEST_CAN_STREAM_RESULTS__ + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message = message.GetString(); + + UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +ScopedTrace::~ScopedTrace() + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + UnitTest::GetInstance()->PopGTestTrace(); +} + + +// class OsStackTraceGetter + +// Returns the current OS stack trace as an std::string. Parameters: +// +// max_depth - the maximum number of stack frames to be included +// in the trace. +// skip_count - the number of top frames to be skipped; doesn't count +// against max_depth. +// +string OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, + int /* skip_count */) + GTEST_LOCK_EXCLUDED_(mutex_) { + return ""; +} + +void OsStackTraceGetter::UponLeavingGTest() + GTEST_LOCK_EXCLUDED_(mutex_) { +} + +const char* const +OsStackTraceGetter::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +// A helper class that creates the premature-exit file in its +// constructor and deletes the file in its destructor. +class ScopedPrematureExitFile { + public: + explicit ScopedPrematureExitFile(const char* premature_exit_filepath) + : premature_exit_filepath_(premature_exit_filepath) { + // If a path to the premature-exit file is specified... + if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { + // create the file with a single "0" character in it. I/O + // errors are ignored as there's nothing better we can do and we + // don't want to fail the test because of this. + FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); + fwrite("0", 1, 1, pfile); + fclose(pfile); + } + } + + ~ScopedPrematureExitFile() { + if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { + remove(premature_exit_filepath_); + } + } + + private: + const char* const premature_exit_filepath_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); +}; + +} // namespace internal + +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + +// class UnitTest + +// Gets the singleton UnitTest object. The first time this method is +// called, a UnitTest object is constructed and returned. Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest* UnitTest::GetInstance() { + // When compiled with MSVC 7.1 in optimized mode, destroying the + // UnitTest object upon exiting the program messes up the exit code, + // causing successful tests to appear failed. We have to use a + // different implementation in this case to bypass the compiler bug. + // This implementation makes the compiler happy, at the cost of + // leaking the UnitTest object. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) + static UnitTest* const instance = new UnitTest; + return instance; +#else + static UnitTest instance; + return &instance; +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) +} + +// Gets the number of successful test cases. +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_case_count(); +} + +// Gets the number of failed test cases. +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_case_count(); +} + +// Gets the number of all test cases. +int UnitTest::total_test_case_count() const { + return impl()->total_test_case_count(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTest::test_case_to_run_count() const { + return impl()->test_case_to_run_count(); +} + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests that will be reported in the XML report. +int UnitTest::reportable_disabled_test_count() const { + return impl()->reportable_disabled_test_count(); +} + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of tests to be printed in the XML report. +int UnitTest::reportable_test_count() const { + return impl()->reportable_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the time of the test program start, in ms from the start of the +// UNIX epoch. +internal::TimeInMillis UnitTest::start_timestamp() const { + return impl()->start_timestamp(); +} + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true iff the unit test passed (i.e. all test cases passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true iff the unit test failed (i.e. some test case failed +// or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} + +// Returns the TestResult containing information on test failures and +// properties logged outside of individual test cases. +const TestResult& UnitTest::ad_hoc_test_result() const { + return *impl()->ad_hoc_test_result(); +} + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + +// Registers and returns a global test environment. When a test +// program is run, all global test environments will be set-up in the +// order they were registered. After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { + if (env == NULL) { + return NULL; + } + + impl_->environments().push_back(env); + return env; +} + +// Adds a TestPartResult to the current TestResult object. All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results. The user code should use the +// assertion macros instead of calling this directly. +void UnitTest::AddTestPartResult( + TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { + Message msg; + msg << message; + + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (int i = static_cast(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } + + if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { + msg << internal::kStackTraceMarker << os_stack_trace; + } + + const TestPartResult result = + TestPartResult(result_type, file_name, line_number, + msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); + + if (result_type != TestPartResult::kSuccess) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#else + // Dereference NULL through a volatile pointer to prevent the compiler + // from removing. We use this rather than abort() or __builtin_trap() for + // portability: Symbian doesn't implement abort() well, and some debuggers + // don't correctly trap abort(). + *static_cast(NULL) = 1; +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw internal::GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } + } +} + +// Adds a TestProperty to the current TestResult object when invoked from +// inside a test, to current TestCase's ad_hoc_test_result_ when invoked +// from SetUpTestCase or TearDownTestCase, or to the global property set +// when invoked elsewhere. If the result already contains a property with +// the same key, the value will be updated. +void UnitTest::RecordProperty(const std::string& key, + const std::string& value) { + impl_->RecordProperty(TestProperty(key, value)); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Google Test implements this protocol for catching that a test + // program exits before returning control to Google Test: + // + // 1. Upon start, Google Test creates a file whose absolute path + // is specified by the environment variable + // TEST_PREMATURE_EXIT_FILE. + // 2. When Google Test has finished its work, it deletes the file. + // + // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before + // running a Google-Test-based test program and check the existence + // of the file at the end of the test execution to see if it has + // exited prematurely. + + // If we are in the child process of a death test, don't + // create/delete the premature exit file, as doing so is unnecessary + // and will confuse the parent process. Otherwise, create/delete + // the file upon entering/leaving this function. If the program + // somehow exits before this function has a chance to return, the + // premature-exit file will be left undeleted, causing a test runner + // that understands the premature-exit-file protocol to report the + // test as having failed. + const internal::ScopedPrematureExitFile premature_exit_file( + in_death_test_child_process ? + NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); + + // Captures the value of GTEST_FLAG(catch_exceptions). This value will be + // used for the duration of the program. + impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); + +#if GTEST_HAS_SEH + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected. + if (impl()->catch_exceptions() || in_death_test_child_process) { +# if !GTEST_OS_WINDOWS_MOBILE + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +# endif // !GTEST_OS_WINDOWS_MOBILE + +# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +# endif + +# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +# endif + } +#endif // GTEST_HAS_SEH + + return internal::HandleExceptionsInMethodIfSupported( + impl(), + &internal::UnitTestImpl::RunAllTests, + "auxiliary test code (environments or event listeners)") ? 0 : 1; +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { + return impl_->original_working_dir_.c_str(); +} + +// Returns the TestCase object for the test that's currently running, +// or NULL if no test is running. +const TestCase* UnitTest::current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_case(); +} + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +const TestInfo* UnitTest::current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); +} + +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +#if GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +internal::ParameterizedTestCaseRegistry& + UnitTest::parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_) { + return impl_->parameterized_test_registry(); +} +#endif // GTEST_HAS_PARAM_TEST + +// Creates an empty UnitTest. +UnitTest::UnitTest() { + impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { + delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +void UnitTest::PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) + : parent_(parent), +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4355) // Temporarily disables warning 4355 + // (using this in initializer). + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +# pragma warning(pop) // Restores the warning state again. +#else + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#endif // _MSC_VER + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), +#if GTEST_HAS_PARAM_TEST + parameterized_test_registry_(), + parameterized_tests_registered_(false), +#endif // GTEST_HAS_PARAM_TEST + last_death_test_case_(-1), + current_test_case_(NULL), + current_test_info_(NULL), + ad_hoc_test_result_(), + os_stack_trace_getter_(NULL), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. + start_timestamp_(0), + elapsed_time_(0), +#if GTEST_HAS_DEATH_TEST + death_test_factory_(new DefaultDeathTestFactory), +#endif + // Will be overridden by the flag before first use. + catch_exceptions_(false) { + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); +} + +UnitTestImpl::~UnitTestImpl() { + // Deletes every TestCase. + ForEach(test_cases_, internal::Delete); + + // Deletes every Environment. + ForEach(environments_, internal::Delete); + + delete os_stack_trace_getter_; +} + +// Adds a TestProperty to the current TestResult object when invoked in a +// context of a test, to current test case's ad_hoc_test_result when invoke +// from SetUpTestCase/TearDownTestCase, or to the global property set +// otherwise. If the result already contains a property with the same key, +// the value will be updated. +void UnitTestImpl::RecordProperty(const TestProperty& test_property) { + std::string xml_element; + TestResult* test_result; // TestResult appropriate for property recording. + + if (current_test_info_ != NULL) { + xml_element = "testcase"; + test_result = &(current_test_info_->result_); + } else if (current_test_case_ != NULL) { + xml_element = "testsuite"; + test_result = &(current_test_case_->ad_hoc_test_result_); + } else { + xml_element = "testsuites"; + test_result = &ad_hoc_test_result_; + } + test_result->RecordProperty(xml_element, test_property); +} + +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const std::string& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +#if GTEST_CAN_STREAM_RESULTS_ +// Initializes event listeners for streaming test results in string form. +// Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureStreamingOutput() { + const std::string& target = GTEST_FLAG(stream_result_to); + if (!target.empty()) { + const size_t pos = target.find(':'); + if (pos != std::string::npos) { + listeners()->Append(new StreamingListener(target.substr(0, pos), + target.substr(pos+1))); + } else { + printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", + target.c_str()); + fflush(stdout); + } + } +} +#endif // GTEST_CAN_STREAM_RESULTS_ + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Configures listeners for streaming test results to the specified server. + ConfigureStreamingOutput(); +#endif // GTEST_CAN_STREAM_RESULTS_ + } +} + +// A predicate that checks the name of a TestCase against a known +// value. +// +// This is used for implementation of the UnitTest class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestCaseNameIs is copyable. +class TestCaseNameIs { + public: + // Constructor. + explicit TestCaseNameIs(const std::string& name) + : name_(name) {} + + // Returns true iff the name of test_case matches name_. + bool operator()(const TestCase* test_case) const { + return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; + } + + private: + std::string name_; +}; + +// Finds and returns a TestCase with the given name. If one doesn't +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. +// +// Arguments: +// +// test_case_name: name of the test case +// type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) { + // Can we find a TestCase with the given name? + const std::vector::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); + + if (test_case != test_cases_.end()) + return *test_case; + + // No. Let's create one. + TestCase* const new_test_case = + new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); + + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(test_case_name, + kDeathTestCaseFilter)) { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } else { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); + } + + test_case_indices_.push_back(static_cast(test_case_indices_.size())); + return new_test_case; +} + +// Helpers for setting up / tearing down the given environment. They +// are for use in the ForEach() function. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns true if all tests are successful. If any exception is +// thrown during a test, the test is considered to be failed, but the +// rest of the tests will still be run. +// +// When parameterized tests are enabled, it expands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +bool UnitTestImpl::RunAllTests() { + // Makes sure InitGoogleTest() was called. + if (!GTestIsInitialized()) { + printf("%s", + "\nThis test program did NOT call ::testing::InitGoogleTest " + "before calling RUN_ALL_TESTS(). Please fix it.\n"); + return false; + } + + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return true; + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + + // True iff we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; + +#if GTEST_HAS_DEATH_TEST + in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +#endif // GTEST_HAS_DEATH_TEST + + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return true; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + + // True iff at least one test has failed. + bool failed = false; + + TestEventListener* repeater = listeners()->repeater(); + + start_timestamp_ = GetTimeInMillis(); + repeater->OnTestProgramStart(*parent_); + + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool forever = repeat < 0; + for (int i = 0; forever || i != repeat; i++) { + // We want to preserve failures generated by ad-hoc test + // assertions executed before RUN_ALL_TESTS(). + ClearNonAdHocTestResult(); + + const TimeInMillis start = GetTimeInMillis(); + + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + + // Runs each test case if there is at least one test to run. + if (has_tests_to_run) { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + + // Runs the tests only if there was no fatal failure during global + // set-up. + if (!Test::HasFatalFailure()) { + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); + } + } + + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } + + elapsed_time_ = GetTimeInMillis() - start; + + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); + + // Gets the result and clears it. + if (!Passed()) { + failed = true; + } + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } + + repeater->OnTestProgramEnd(*parent_); + + return !failed; +} + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. +// Returns the number of tests that should run. +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; + const std::string &test_case_name = test_case->name(); + test_case->set_should_run(false); + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; + const std::string test_name(test_info->name()); + // A test is disabled if test case name or test name matches + // kDisableTestFilter. + const bool is_disabled = + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); + test_info->is_disabled_ = is_disabled; + + const bool matches_filter = + internal::UnitTestOptions::FilterMatchesTest(test_case_name, + test_name); + test_info->matches_filter_ = matches_filter; + + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; + + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->should_run_ = is_selected; + test_case->set_should_run(test_case->should_run() || is_selected); + } + } + return num_selected_tests; +} + +// Prints the given C-string on a single line by replacing all '\n' +// characters with string "\\n". If the output takes more than +// max_length characters, only prints the first max_length characters +// and "...". +static void PrintOnOneLine(const char* str, int max_length) { + if (str != NULL) { + for (int i = 0; *str != '\0'; ++str) { + if (i >= max_length) { + printf("..."); + break; + } + if (*str == '\n') { + printf("\\n"); + i += 2; + } else { + printf("%c", *str); + ++i; + } + } + } +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + // Print at most this many characters for each type/value parameter. + const int kMaxParamLength = 250; + + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter_) { + if (!printed_test_case_name) { + printed_test_case_name = true; + printf("%s.", test_case->name()); + if (test_case->type_param() != NULL) { + printf(" # %s = ", kTypeParamLabel); + // We print the type parameter on a single line to make + // the output easy to parse by a program. + PrintOnOneLine(test_case->type_param(), kMaxParamLength); + } + printf("\n"); + } + printf(" %s", test_info->name()); + if (test_info->value_param() != NULL) { + printf(" # %s = ", kValueParamLabel); + // We print the value parameter on a single line to make the + // output easy to parse by a program. + PrintOnOneLine(test_info->value_param(), kMaxParamLength); + } + printf("\n"); + } + } + } + fflush(stdout); +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( + OsStackTraceGetterInterface* getter) { + if (os_stack_trace_getter_ != getter) { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { + if (os_stack_trace_getter_ == NULL) { + os_stack_trace_getter_ = new OsStackTraceGetter; + } + + return os_stack_trace_getter_; +} + +// Returns the TestResult for the test that's currently running, or +// the TestResult for the ad hoc test if no test is running. +TestResult* UnitTestImpl::current_test_result() { + return current_test_info_ ? + &(current_test_info_->result_) : &ad_hoc_test_result_; +} + +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast(test_cases_.size()), &test_case_indices_); + + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast(i); + } +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to +// suppress unreachable code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +const char* ParseFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; + + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, std::string* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", std::string(str, p).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +#if GTEST_CAN_STREAM_RESULTS_ +" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" +" Stream test results to the given server.\n" +#endif // GTEST_CAN_STREAM_RESULTS_ +"\n" +"Assertion Behavior:\n" +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" +" Do not report exceptions as test failures. Instead, allow them\n" +" to crash the program or throw a pop-up (on Windows).\n" +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. The type parameter CharType can be +// instantiated to either char or wchar_t. +template +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + for (int i = 1; i < *argc; i++) { + const std::string arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; + + // Do we see a Google Test flag? + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, + >EST_FLAG(throw_on_failure)) + ) { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template +void InitGoogleTestImpl(int* argc, CharType** argv) { + g_init_gtest_count++; + + // We don't want to run the initialization code twice. + if (g_init_gtest_count != 1) return; + + if (*argc <= 0) return; + + internal::g_executable_path = internal::StreamableToString(argv[0]); + +#if GTEST_HAS_DEATH_TEST + + g_argvs.clear(); + for (int i = 0; i != *argc; i++) { + g_argvs.push_back(StreamableToString(argv[i])); + } + +#endif // GTEST_HAS_DEATH_TEST + + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); +} + +} // namespace internal + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +} // namespace testing diff --git a/cpp/thirdparty/gtest-1.7.0/src/gtest_main.cc b/cpp/thirdparty/gtest-1.7.0/src/gtest_main.cc new file mode 100644 index 0000000..f302822 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/src/gtest_main.cc @@ -0,0 +1,38 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +#include + +#include "gtest/gtest.h" + +GTEST_API_ int main(int argc, char **argv) { + printf("Running main() from gtest_main.cc\n"); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-death-test_ex_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-death-test_ex_test.cc new file mode 100644 index 0000000..b50a13d --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-death-test_ex_test.cc @@ -0,0 +1,93 @@ +// Copyright 2010, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests that verify interaction of exceptions and death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_HAS_SEH +# include // For RaiseException(). +# endif + +# include "gtest/gtest-spi.h" + +# if GTEST_HAS_EXCEPTIONS + +# include // For std::exception. + +// Tests that death tests report thrown exceptions as failures and that the +// exceptions do not escape death test macros. +TEST(CxxExceptionDeathTest, ExceptionIsFailure) { + try { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw 1, ""), "threw an exception"); + } catch (...) { // NOLINT + FAIL() << "An exception escaped a death test macro invocation " + << "with catch_exceptions " + << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); + } +} + +class TestException : public std::exception { + public: + virtual const char* what() const throw() { return "exceptional message"; } +}; + +TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) { + // Verifies that the exception message is quoted in the failure text. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), + "exceptional message"); + // Verifies that the location is mentioned in the failure text. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), + "gtest-death-test_ex_test.cc"); +} +# endif // GTEST_HAS_EXCEPTIONS + +# if GTEST_HAS_SEH +// Tests that enabling interception of SEH exceptions with the +// catch_exceptions flag does not interfere with SEH exceptions being +// treated as death by death tests. +TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) { + EXPECT_DEATH(RaiseException(42, 0x0, 0, NULL), "") + << "with catch_exceptions " + << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); +} +# endif + +#endif // GTEST_HAS_DEATH_TEST + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + testing::GTEST_FLAG(catch_exceptions) = GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0; + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-death-test_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-death-test_test.cc new file mode 100644 index 0000000..c2d26df --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-death-test_test.cc @@ -0,0 +1,1367 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/gtest.h" +#include "gtest/internal/gtest-filepath.h" + +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_WINDOWS +# include // For chdir(). +# else +# include +# include // For waitpid. +# endif // GTEST_OS_WINDOWS + +# include +# include +# include + +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + +# include "gtest/gtest-spi.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +# define GTEST_IMPLEMENTATION_ 1 +# include "src/gtest-internal-inl.h" +# undef GTEST_IMPLEMENTATION_ + +namespace posix = ::testing::internal::posix; + +using testing::Message; +using testing::internal::DeathTest; +using testing::internal::DeathTestFactory; +using testing::internal::FilePath; +using testing::internal::GetLastErrnoDescription; +using testing::internal::GetUnitTestImpl; +using testing::internal::InDeathTestChild; +using testing::internal::ParseNaturalNumber; + +namespace testing { +namespace internal { + +// A helper class whose objects replace the death test factory for a +// single UnitTest object during their lifetimes. +class ReplaceDeathTestFactory { + public: + explicit ReplaceDeathTestFactory(DeathTestFactory* new_factory) + : unit_test_impl_(GetUnitTestImpl()) { + old_factory_ = unit_test_impl_->death_test_factory_.release(); + unit_test_impl_->death_test_factory_.reset(new_factory); + } + + ~ReplaceDeathTestFactory() { + unit_test_impl_->death_test_factory_.release(); + unit_test_impl_->death_test_factory_.reset(old_factory_); + } + private: + // Prevents copying ReplaceDeathTestFactory objects. + ReplaceDeathTestFactory(const ReplaceDeathTestFactory&); + void operator=(const ReplaceDeathTestFactory&); + + UnitTestImpl* unit_test_impl_; + DeathTestFactory* old_factory_; +}; + +} // namespace internal +} // namespace testing + +void DieWithMessage(const ::std::string& message) { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); // Make sure the text is printed before the process exits. + + // We call _exit() instead of exit(), as the former is a direct + // system call and thus safer in the presence of threads. exit() + // will invoke user-defined exit-hooks, which may do dangerous + // things that conflict with death tests. + // + // Some compilers can recognize that _exit() never returns and issue the + // 'unreachable code' warning for code following this function, unless + // fooled by a fake condition. + if (AlwaysTrue()) + _exit(1); +} + +void DieInside(const ::std::string& function) { + DieWithMessage("death inside " + function + "()."); +} + +// Tests that death tests work. + +class TestForDeathTest : public testing::Test { + protected: + TestForDeathTest() : original_dir_(FilePath::GetCurrentDir()) {} + + virtual ~TestForDeathTest() { + posix::ChDir(original_dir_.c_str()); + } + + // A static member function that's expected to die. + static void StaticMemberFunction() { DieInside("StaticMemberFunction"); } + + // A method of the test fixture that may die. + void MemberFunction() { + if (should_die_) + DieInside("MemberFunction"); + } + + // True iff MemberFunction() should die. + bool should_die_; + const FilePath original_dir_; +}; + +// A class with a member function that may die. +class MayDie { + public: + explicit MayDie(bool should_die) : should_die_(should_die) {} + + // A member function that may die. + void MemberFunction() const { + if (should_die_) + DieInside("MayDie::MemberFunction"); + } + + private: + // True iff MemberFunction() should die. + bool should_die_; +}; + +// A global function that's expected to die. +void GlobalFunction() { DieInside("GlobalFunction"); } + +// A non-void function that's expected to die. +int NonVoidFunction() { + DieInside("NonVoidFunction"); + return 1; +} + +// A unary function that may die. +void DieIf(bool should_die) { + if (should_die) + DieInside("DieIf"); +} + +// A binary function that may die. +bool DieIfLessThan(int x, int y) { + if (x < y) { + DieInside("DieIfLessThan"); + } + return true; +} + +// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. +void DeathTestSubroutine() { + EXPECT_DEATH(GlobalFunction(), "death.*GlobalFunction"); + ASSERT_DEATH(GlobalFunction(), "death.*GlobalFunction"); +} + +// Death in dbg, not opt. +int DieInDebugElse12(int* sideeffect) { + if (sideeffect) *sideeffect = 12; + +# ifndef NDEBUG + + DieInside("DieInDebugElse12"); + +# endif // NDEBUG + + return 12; +} + +# if GTEST_OS_WINDOWS + +// Tests the ExitedWithCode predicate. +TEST(ExitStatusPredicateTest, ExitedWithCode) { + // On Windows, the process's exit code is the same as its exit status, + // so the predicate just compares the its input with its parameter. + EXPECT_TRUE(testing::ExitedWithCode(0)(0)); + EXPECT_TRUE(testing::ExitedWithCode(1)(1)); + EXPECT_TRUE(testing::ExitedWithCode(42)(42)); + EXPECT_FALSE(testing::ExitedWithCode(0)(1)); + EXPECT_FALSE(testing::ExitedWithCode(1)(0)); +} + +# else + +// Returns the exit status of a process that calls _exit(2) with a +// given exit code. This is a helper function for the +// ExitStatusPredicateTest test suite. +static int NormalExitStatus(int exit_code) { + pid_t child_pid = fork(); + if (child_pid == 0) { + _exit(exit_code); + } + int status; + waitpid(child_pid, &status, 0); + return status; +} + +// Returns the exit status of a process that raises a given signal. +// If the signal does not cause the process to die, then it returns +// instead the exit status of a process that exits normally with exit +// code 1. This is a helper function for the ExitStatusPredicateTest +// test suite. +static int KilledExitStatus(int signum) { + pid_t child_pid = fork(); + if (child_pid == 0) { + raise(signum); + _exit(1); + } + int status; + waitpid(child_pid, &status, 0); + return status; +} + +// Tests the ExitedWithCode predicate. +TEST(ExitStatusPredicateTest, ExitedWithCode) { + const int status0 = NormalExitStatus(0); + const int status1 = NormalExitStatus(1); + const int status42 = NormalExitStatus(42); + const testing::ExitedWithCode pred0(0); + const testing::ExitedWithCode pred1(1); + const testing::ExitedWithCode pred42(42); + EXPECT_PRED1(pred0, status0); + EXPECT_PRED1(pred1, status1); + EXPECT_PRED1(pred42, status42); + EXPECT_FALSE(pred0(status1)); + EXPECT_FALSE(pred42(status0)); + EXPECT_FALSE(pred1(status42)); +} + +// Tests the KilledBySignal predicate. +TEST(ExitStatusPredicateTest, KilledBySignal) { + const int status_segv = KilledExitStatus(SIGSEGV); + const int status_kill = KilledExitStatus(SIGKILL); + const testing::KilledBySignal pred_segv(SIGSEGV); + const testing::KilledBySignal pred_kill(SIGKILL); + EXPECT_PRED1(pred_segv, status_segv); + EXPECT_PRED1(pred_kill, status_kill); + EXPECT_FALSE(pred_segv(status_kill)); + EXPECT_FALSE(pred_kill(status_segv)); +} + +# endif // GTEST_OS_WINDOWS + +// Tests that the death test macros expand to code which may or may not +// be followed by operator<<, and that in either case the complete text +// comprises only a single C++ statement. +TEST_F(TestForDeathTest, SingleStatement) { + if (AlwaysFalse()) + // This would fail if executed; this is a compilation test only + ASSERT_DEATH(return, ""); + + if (AlwaysTrue()) + EXPECT_DEATH(_exit(1), ""); + else + // This empty "else" branch is meant to ensure that EXPECT_DEATH + // doesn't expand into an "if" statement without an "else" + ; + + if (AlwaysFalse()) + ASSERT_DEATH(return, "") << "did not die"; + + if (AlwaysFalse()) + ; + else + EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3; +} + +void DieWithEmbeddedNul() { + fprintf(stderr, "Hello%cmy null world.\n", '\0'); + fflush(stderr); + _exit(1); +} + +# if GTEST_USES_PCRE +// Tests that EXPECT_DEATH and ASSERT_DEATH work when the error +// message has a NUL character in it. +TEST_F(TestForDeathTest, EmbeddedNulInMessage) { + // TODO(wan@google.com): doesn't support matching strings + // with embedded NUL characters - find a way to workaround it. + EXPECT_DEATH(DieWithEmbeddedNul(), "my null world"); + ASSERT_DEATH(DieWithEmbeddedNul(), "my null world"); +} +# endif // GTEST_USES_PCRE + +// Tests that death test macros expand to code which interacts well with switch +// statements. +TEST_F(TestForDeathTest, SwitchStatement) { +// Microsoft compiler usually complains about switch statements without +// case labels. We suppress that warning for this test. +# ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4065) +# endif // _MSC_VER + + switch (0) + default: + ASSERT_DEATH(_exit(1), "") << "exit in default switch handler"; + + switch (0) + case 0: + EXPECT_DEATH(_exit(1), "") << "exit in switch case"; + +# ifdef _MSC_VER +# pragma warning(pop) +# endif // _MSC_VER +} + +// Tests that a static member function can be used in a "fast" style +// death test. +TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); +} + +// Tests that a method of the test fixture can be used in a "fast" +// style death test. +TEST_F(TestForDeathTest, MemberFunctionFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + should_die_ = true; + EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); +} + +void ChangeToRootDir() { posix::ChDir(GTEST_PATH_SEP_); } + +// Tests that death tests work even if the current directory has been +// changed. +TEST_F(TestForDeathTest, FastDeathTestInChangedDir) { + testing::GTEST_FLAG(death_test_style) = "fast"; + + ChangeToRootDir(); + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + + ChangeToRootDir(); + ASSERT_DEATH(_exit(1), ""); +} + +# if GTEST_OS_LINUX +void SigprofAction(int, siginfo_t*, void*) { /* no op */ } + +// Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms). +void SetSigprofActionAndTimer() { + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 1; + timer.it_value = timer.it_interval; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); + struct sigaction signal_action; + memset(&signal_action, 0, sizeof(signal_action)); + sigemptyset(&signal_action.sa_mask); + signal_action.sa_sigaction = SigprofAction; + signal_action.sa_flags = SA_RESTART | SA_SIGINFO; + ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, NULL)); +} + +// Disables ITIMER_PROF timer and ignores SIGPROF signal. +void DisableSigprofActionAndTimer(struct sigaction* old_signal_action) { + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + timer.it_value = timer.it_interval; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); + struct sigaction signal_action; + memset(&signal_action, 0, sizeof(signal_action)); + sigemptyset(&signal_action.sa_mask); + signal_action.sa_handler = SIG_IGN; + ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, old_signal_action)); +} + +// Tests that death tests work when SIGPROF handler and timer are set. +TEST_F(TestForDeathTest, FastSigprofActionSet) { + testing::GTEST_FLAG(death_test_style) = "fast"; + SetSigprofActionAndTimer(); + EXPECT_DEATH(_exit(1), ""); + struct sigaction old_signal_action; + DisableSigprofActionAndTimer(&old_signal_action); + EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); +} + +TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + SetSigprofActionAndTimer(); + EXPECT_DEATH(_exit(1), ""); + struct sigaction old_signal_action; + DisableSigprofActionAndTimer(&old_signal_action); + EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); +} +# endif // GTEST_OS_LINUX + +// Repeats a representative sample of death tests in the "threadsafe" style: + +TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); +} + +TEST_F(TestForDeathTest, MemberFunctionThreadsafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + should_die_ = true; + EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); +} + +TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + + for (int i = 0; i < 3; ++i) + EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i; +} + +TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + + ChangeToRootDir(); + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + + ChangeToRootDir(); + ASSERT_DEATH(_exit(1), ""); +} + +TEST_F(TestForDeathTest, MixedStyles) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_DEATH(_exit(1), ""); + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(_exit(1), ""); +} + +# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD + +namespace { + +bool pthread_flag; + +void SetPthreadFlag() { + pthread_flag = true; +} + +} // namespace + +TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { + if (!testing::GTEST_FLAG(death_test_use_fork)) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + pthread_flag = false; + ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, NULL, NULL)); + ASSERT_DEATH(_exit(1), ""); + ASSERT_FALSE(pthread_flag); + } +} + +# endif // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD + +// Tests that a method of another class can be used in a death test. +TEST_F(TestForDeathTest, MethodOfAnotherClass) { + const MayDie x(true); + ASSERT_DEATH(x.MemberFunction(), "MayDie\\:\\:MemberFunction"); +} + +// Tests that a global function can be used in a death test. +TEST_F(TestForDeathTest, GlobalFunction) { + EXPECT_DEATH(GlobalFunction(), "GlobalFunction"); +} + +// Tests that any value convertible to an RE works as a second +// argument to EXPECT_DEATH. +TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) { + static const char regex_c_str[] = "GlobalFunction"; + EXPECT_DEATH(GlobalFunction(), regex_c_str); + + const testing::internal::RE regex(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex); + +# if GTEST_HAS_GLOBAL_STRING + + const string regex_str(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex_str); + +# endif // GTEST_HAS_GLOBAL_STRING + + const ::std::string regex_std_str(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex_std_str); +} + +// Tests that a non-void function can be used in a death test. +TEST_F(TestForDeathTest, NonVoidFunction) { + ASSERT_DEATH(NonVoidFunction(), "NonVoidFunction"); +} + +// Tests that functions that take parameter(s) can be used in a death test. +TEST_F(TestForDeathTest, FunctionWithParameter) { + EXPECT_DEATH(DieIf(true), "DieIf\\(\\)"); + EXPECT_DEATH(DieIfLessThan(2, 3), "DieIfLessThan"); +} + +// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. +TEST_F(TestForDeathTest, OutsideFixture) { + DeathTestSubroutine(); +} + +// Tests that death tests can be done inside a loop. +TEST_F(TestForDeathTest, InsideLoop) { + for (int i = 0; i < 5; i++) { + EXPECT_DEATH(DieIfLessThan(-1, i), "DieIfLessThan") << "where i == " << i; + } +} + +// Tests that a compound statement can be used in a death test. +TEST_F(TestForDeathTest, CompoundStatement) { + EXPECT_DEATH({ // NOLINT + const int x = 2; + const int y = x + 1; + DieIfLessThan(x, y); + }, + "DieIfLessThan"); +} + +// Tests that code that doesn't die causes a death test to fail. +TEST_F(TestForDeathTest, DoesNotDie) { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(DieIf(false), "DieIf"), + "failed to die"); +} + +// Tests that a death test fails when the error message isn't expected. +TEST_F(TestForDeathTest, ErrorMessageMismatch) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(DieIf(true), "DieIfLessThan") << "End of death test message."; + }, "died but not with expected error"); +} + +// On exit, *aborted will be true iff the EXPECT_DEATH() statement +// aborted the function. +void ExpectDeathTestHelper(bool* aborted) { + *aborted = true; + EXPECT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. + *aborted = false; +} + +// Tests that EXPECT_DEATH doesn't abort the test on failure. +TEST_F(TestForDeathTest, EXPECT_DEATH) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(ExpectDeathTestHelper(&aborted), + "failed to die"); + EXPECT_FALSE(aborted); +} + +// Tests that ASSERT_DEATH does abort the test on failure. +TEST_F(TestForDeathTest, ASSERT_DEATH) { + static bool aborted; + EXPECT_FATAL_FAILURE({ // NOLINT + aborted = true; + ASSERT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. + aborted = false; + }, "failed to die"); + EXPECT_TRUE(aborted); +} + +// Tests that EXPECT_DEATH evaluates the arguments exactly once. +TEST_F(TestForDeathTest, SingleEvaluation) { + int x = 3; + EXPECT_DEATH(DieIf((++x) == 4), "DieIf"); + + const char* regex = "DieIf"; + const char* regex_save = regex; + EXPECT_DEATH(DieIfLessThan(3, 4), regex++); + EXPECT_EQ(regex_save + 1, regex); +} + +// Tests that run-away death tests are reported as failures. +TEST_F(TestForDeathTest, RunawayIsFailure) { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(static_cast(0), "Foo"), + "failed to die."); +} + +// Tests that death tests report executing 'return' in the statement as +// failure. +TEST_F(TestForDeathTest, ReturnIsFailure) { + EXPECT_FATAL_FAILURE(ASSERT_DEATH(return, "Bar"), + "illegal return in test statement."); +} + +// Tests that EXPECT_DEBUG_DEATH works as expected, that is, you can stream a +// message to it, and in debug mode it: +// 1. Asserts on death. +// 2. Has no side effect. +// +// And in opt mode, it: +// 1. Has side effects but does not assert. +TEST_F(TestForDeathTest, TestExpectDebugDeath) { + int sideeffect = 0; + + EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") + << "Must accept a streamed message"; + +# ifdef NDEBUG + + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); + +# else + + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); + +# endif +} + +// Tests that ASSERT_DEBUG_DEATH works as expected, that is, you can stream a +// message to it, and in debug mode it: +// 1. Asserts on death. +// 2. Has no side effect. +// +// And in opt mode, it: +// 1. Has side effects but does not assert. +TEST_F(TestForDeathTest, TestAssertDebugDeath) { + int sideeffect = 0; + + ASSERT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") + << "Must accept a streamed message"; + +# ifdef NDEBUG + + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); + +# else + + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); + +# endif +} + +# ifndef NDEBUG + +void ExpectDebugDeathHelper(bool* aborted) { + *aborted = true; + EXPECT_DEBUG_DEATH(return, "") << "This is expected to fail."; + *aborted = false; +} + +# if GTEST_OS_WINDOWS +TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) { + printf("This test should be considered failing if it shows " + "any pop-up dialogs.\n"); + fflush(stdout); + + EXPECT_DEATH({ + testing::GTEST_FLAG(catch_exceptions) = false; + abort(); + }, ""); +} +# endif // GTEST_OS_WINDOWS + +// Tests that EXPECT_DEBUG_DEATH in debug mode does not abort +// the function. +TEST_F(TestForDeathTest, ExpectDebugDeathDoesNotAbort) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(ExpectDebugDeathHelper(&aborted), ""); + EXPECT_FALSE(aborted); +} + +void AssertDebugDeathHelper(bool* aborted) { + *aborted = true; + ASSERT_DEBUG_DEATH(return, "") << "This is expected to fail."; + *aborted = false; +} + +// Tests that ASSERT_DEBUG_DEATH in debug mode aborts the function on +// failure. +TEST_F(TestForDeathTest, AssertDebugDeathAborts) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +# endif // _NDEBUG + +// Tests the *_EXIT family of macros, using a variety of predicates. +static void TestExitMacros() { + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); + +# if GTEST_OS_WINDOWS + + // Of all signals effects on the process exit code, only those of SIGABRT + // are documented on Windows. + // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. + EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), "") << "b_ar"; + +# else + + EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; + ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") + << "This failure is expected, too."; + }, "This failure is expected, too."); + +# endif // GTEST_OS_WINDOWS + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") + << "This failure is expected."; + }, "This failure is expected."); +} + +TEST_F(TestForDeathTest, ExitMacros) { + TestExitMacros(); +} + +TEST_F(TestForDeathTest, ExitMacrosUsingFork) { + testing::GTEST_FLAG(death_test_use_fork) = true; + TestExitMacros(); +} + +TEST_F(TestForDeathTest, InvalidStyle) { + testing::GTEST_FLAG(death_test_style) = "rococo"; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(_exit(0), "") << "This failure is expected."; + }, "This failure is expected."); +} + +TEST_F(TestForDeathTest, DeathTestFailedOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("death\n"), + "expected message"), + "Actual msg:\n" + "[ DEATH ] death\n"); +} + +TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH({ + fprintf(stderr, "returning\n"); + fflush(stderr); + return; + }, ""), + " Result: illegal return in test statement.\n" + " Error msg:\n" + "[ DEATH ] returning\n"); +} + +TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"), + testing::ExitedWithCode(3), + "expected message"), + " Result: died but not with expected exit code:\n" + " Exited with exit status 1\n" + "Actual msg:\n" + "[ DEATH ] exiting with rc 1\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nxyz\nline 3\n"), + "Actual msg:\n" + "[ DEATH ] line 1\n" + "[ DEATH ] line 2\n" + "[ DEATH ] line 3\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nline 2\nline 3\n"); +} + +// A DeathTestFactory that returns MockDeathTests. +class MockDeathTestFactory : public DeathTestFactory { + public: + MockDeathTestFactory(); + virtual bool Create(const char* statement, + const ::testing::internal::RE* regex, + const char* file, int line, DeathTest** test); + + // Sets the parameters for subsequent calls to Create. + void SetParameters(bool create, DeathTest::TestRole role, + int status, bool passed); + + // Accessors. + int AssumeRoleCalls() const { return assume_role_calls_; } + int WaitCalls() const { return wait_calls_; } + int PassedCalls() const { return passed_args_.size(); } + bool PassedArgument(int n) const { return passed_args_[n]; } + int AbortCalls() const { return abort_args_.size(); } + DeathTest::AbortReason AbortArgument(int n) const { + return abort_args_[n]; + } + bool TestDeleted() const { return test_deleted_; } + + private: + friend class MockDeathTest; + // If true, Create will return a MockDeathTest; otherwise it returns + // NULL. + bool create_; + // The value a MockDeathTest will return from its AssumeRole method. + DeathTest::TestRole role_; + // The value a MockDeathTest will return from its Wait method. + int status_; + // The value a MockDeathTest will return from its Passed method. + bool passed_; + + // Number of times AssumeRole was called. + int assume_role_calls_; + // Number of times Wait was called. + int wait_calls_; + // The arguments to the calls to Passed since the last call to + // SetParameters. + std::vector passed_args_; + // The arguments to the calls to Abort since the last call to + // SetParameters. + std::vector abort_args_; + // True if the last MockDeathTest returned by Create has been + // deleted. + bool test_deleted_; +}; + + +// A DeathTest implementation useful in testing. It returns values set +// at its creation from its various inherited DeathTest methods, and +// reports calls to those methods to its parent MockDeathTestFactory +// object. +class MockDeathTest : public DeathTest { + public: + MockDeathTest(MockDeathTestFactory *parent, + TestRole role, int status, bool passed) : + parent_(parent), role_(role), status_(status), passed_(passed) { + } + virtual ~MockDeathTest() { + parent_->test_deleted_ = true; + } + virtual TestRole AssumeRole() { + ++parent_->assume_role_calls_; + return role_; + } + virtual int Wait() { + ++parent_->wait_calls_; + return status_; + } + virtual bool Passed(bool exit_status_ok) { + parent_->passed_args_.push_back(exit_status_ok); + return passed_; + } + virtual void Abort(AbortReason reason) { + parent_->abort_args_.push_back(reason); + } + + private: + MockDeathTestFactory* const parent_; + const TestRole role_; + const int status_; + const bool passed_; +}; + + +// MockDeathTestFactory constructor. +MockDeathTestFactory::MockDeathTestFactory() + : create_(true), + role_(DeathTest::OVERSEE_TEST), + status_(0), + passed_(true), + assume_role_calls_(0), + wait_calls_(0), + passed_args_(), + abort_args_() { +} + + +// Sets the parameters for subsequent calls to Create. +void MockDeathTestFactory::SetParameters(bool create, + DeathTest::TestRole role, + int status, bool passed) { + create_ = create; + role_ = role; + status_ = status; + passed_ = passed; + + assume_role_calls_ = 0; + wait_calls_ = 0; + passed_args_.clear(); + abort_args_.clear(); +} + + +// Sets test to NULL (if create_ is false) or to the address of a new +// MockDeathTest object with parameters taken from the last call +// to SetParameters (if create_ is true). Always returns true. +bool MockDeathTestFactory::Create(const char* /*statement*/, + const ::testing::internal::RE* /*regex*/, + const char* /*file*/, + int /*line*/, + DeathTest** test) { + test_deleted_ = false; + if (create_) { + *test = new MockDeathTest(this, role_, status_, passed_); + } else { + *test = NULL; + } + return true; +} + +// A test fixture for testing the logic of the GTEST_DEATH_TEST_ macro. +// It installs a MockDeathTestFactory that is used for the duration +// of the test case. +class MacroLogicDeathTest : public testing::Test { + protected: + static testing::internal::ReplaceDeathTestFactory* replacer_; + static MockDeathTestFactory* factory_; + + static void SetUpTestCase() { + factory_ = new MockDeathTestFactory; + replacer_ = new testing::internal::ReplaceDeathTestFactory(factory_); + } + + static void TearDownTestCase() { + delete replacer_; + replacer_ = NULL; + delete factory_; + factory_ = NULL; + } + + // Runs a death test that breaks the rules by returning. Such a death + // test cannot be run directly from a test routine that uses a + // MockDeathTest, or the remainder of the routine will not be executed. + static void RunReturningDeathTest(bool* flag) { + ASSERT_DEATH({ // NOLINT + *flag = true; + return; + }, ""); + } +}; + +testing::internal::ReplaceDeathTestFactory* MacroLogicDeathTest::replacer_ + = NULL; +MockDeathTestFactory* MacroLogicDeathTest::factory_ = NULL; + + +// Test that nothing happens when the factory doesn't return a DeathTest: +TEST_F(MacroLogicDeathTest, NothingHappens) { + bool flag = false; + factory_->SetParameters(false, DeathTest::OVERSEE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(0, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_FALSE(factory_->TestDeleted()); +} + +// Test that the parent process doesn't run the death test code, +// and that the Passed method returns false when the (simulated) +// child process exits with status 0: +TEST_F(MacroLogicDeathTest, ChildExitsSuccessfully) { + bool flag = false; + factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(1, factory_->WaitCalls()); + ASSERT_EQ(1, factory_->PassedCalls()); + EXPECT_FALSE(factory_->PassedArgument(0)); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the Passed method was given the argument "true" when +// the (simulated) child process exits with status 1: +TEST_F(MacroLogicDeathTest, ChildExitsUnsuccessfully) { + bool flag = false; + factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 1, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(1, factory_->WaitCalls()); + ASSERT_EQ(1, factory_->PassedCalls()); + EXPECT_TRUE(factory_->PassedArgument(0)); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the (simulated) child process executes the death test +// code, and is aborted with the correct AbortReason if it +// executes a return statement. +TEST_F(MacroLogicDeathTest, ChildPerformsReturn) { + bool flag = false; + factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); + RunReturningDeathTest(&flag); + EXPECT_TRUE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + EXPECT_EQ(1, factory_->AbortCalls()); + EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, + factory_->AbortArgument(0)); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the (simulated) child process is aborted with the +// correct AbortReason if it does not die. +TEST_F(MacroLogicDeathTest, ChildDoesNotDie) { + bool flag = false; + factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_TRUE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + // This time there are two calls to Abort: one since the test didn't + // die, and another from the ReturnSentinel when it's destroyed. The + // sentinel normally isn't destroyed if a test doesn't die, since + // _exit(2) is called in that case by ForkingDeathTest, but not by + // our MockDeathTest. + ASSERT_EQ(2, factory_->AbortCalls()); + EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE, + factory_->AbortArgument(0)); + EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, + factory_->AbortArgument(1)); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that a successful death test does not register a successful +// test part. +TEST(SuccessRegistrationDeathTest, NoSuccessPart) { + EXPECT_DEATH(_exit(1), ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +TEST(StreamingAssertionsDeathTest, DeathTest) { + EXPECT_DEATH(_exit(1), "") << "unexpected failure"; + ASSERT_DEATH(_exit(1), "") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(_exit(0), "") << "expected failure"; + }, "expected failure"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_DEATH(_exit(0), "") << "expected failure"; + }, "expected failure"); +} + +// Tests that GetLastErrnoDescription returns an empty string when the +// last error is 0 and non-empty string when it is non-zero. +TEST(GetLastErrnoDescription, GetLastErrnoDescriptionWorks) { + errno = ENOENT; + EXPECT_STRNE("", GetLastErrnoDescription().c_str()); + errno = 0; + EXPECT_STREQ("", GetLastErrnoDescription().c_str()); +} + +# if GTEST_OS_WINDOWS +TEST(AutoHandleTest, AutoHandleWorks) { + HANDLE handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + + // Tests that the AutoHandle is correctly initialized with a handle. + testing::internal::AutoHandle auto_handle(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that Reset assigns INVALID_HANDLE_VALUE. + // Note that this cannot verify whether the original handle is closed. + auto_handle.Reset(); + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle.Get()); + + // Tests that Reset assigns the new handle. + // Note that this cannot verify whether the original handle is closed. + handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + auto_handle.Reset(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that AutoHandle contains INVALID_HANDLE_VALUE by default. + testing::internal::AutoHandle auto_handle2; + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle2.Get()); +} +# endif // GTEST_OS_WINDOWS + +# if GTEST_OS_WINDOWS +typedef unsigned __int64 BiggestParsable; +typedef signed __int64 BiggestSignedParsable; +# else +typedef unsigned long long BiggestParsable; +typedef signed long long BiggestSignedParsable; +# endif // GTEST_OS_WINDOWS + +// We cannot use std::numeric_limits::max() as it clashes with the +// max() macro defined by . +const BiggestParsable kBiggestParsableMax = ULLONG_MAX; +const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX; + +TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { + BiggestParsable result = 0; + + // Rejects non-numbers. + EXPECT_FALSE(ParseNaturalNumber("non-number string", &result)); + + // Rejects numbers with whitespace prefix. + EXPECT_FALSE(ParseNaturalNumber(" 123", &result)); + + // Rejects negative numbers. + EXPECT_FALSE(ParseNaturalNumber("-123", &result)); + + // Rejects numbers starting with a plus sign. + EXPECT_FALSE(ParseNaturalNumber("+123", &result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) { + BiggestParsable result = 0; + + EXPECT_FALSE(ParseNaturalNumber("99999999999999999999999", &result)); + + signed char char_result = 0; + EXPECT_FALSE(ParseNaturalNumber("200", &char_result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, AcceptsValidNumbers) { + BiggestParsable result = 0; + + result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &result)); + EXPECT_EQ(123U, result); + + // Check 0 as an edge case. + result = 1; + ASSERT_TRUE(ParseNaturalNumber("0", &result)); + EXPECT_EQ(0U, result); + + result = 1; + ASSERT_TRUE(ParseNaturalNumber("00000", &result)); + EXPECT_EQ(0U, result); +} + +TEST(ParseNaturalNumberTest, AcceptsTypeLimits) { + Message msg; + msg << kBiggestParsableMax; + + BiggestParsable result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg.GetString(), &result)); + EXPECT_EQ(kBiggestParsableMax, result); + + Message msg2; + msg2 << kBiggestSignedParsableMax; + + BiggestSignedParsable signed_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg2.GetString(), &signed_result)); + EXPECT_EQ(kBiggestSignedParsableMax, signed_result); + + Message msg3; + msg3 << INT_MAX; + + int int_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg3.GetString(), &int_result)); + EXPECT_EQ(INT_MAX, int_result); + + Message msg4; + msg4 << UINT_MAX; + + unsigned int uint_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg4.GetString(), &uint_result)); + EXPECT_EQ(UINT_MAX, uint_result); +} + +TEST(ParseNaturalNumberTest, WorksForShorterIntegers) { + short short_result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &short_result)); + EXPECT_EQ(123, short_result); + + signed char char_result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &char_result)); + EXPECT_EQ(123, char_result); +} + +# if GTEST_OS_WINDOWS +TEST(EnvironmentTest, HandleFitsIntoSizeT) { + // TODO(vladl@google.com): Remove this test after this condition is verified + // in a static assertion in gtest-death-test.cc in the function + // GetStatusFileDescriptor. + ASSERT_TRUE(sizeof(HANDLE) <= sizeof(size_t)); +} +# endif // GTEST_OS_WINDOWS + +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger +// failures when death tests are available on the system. +TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) { + EXPECT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestExpectMacro"), + "death inside CondDeathTestExpectMacro"); + ASSERT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestAssertMacro"), + "death inside CondDeathTestAssertMacro"); + + // Empty statement will not crash, which must trigger a failure. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH_IF_SUPPORTED(;, ""), ""); + EXPECT_FATAL_FAILURE(ASSERT_DEATH_IF_SUPPORTED(;, ""), ""); +} + +#else + +using testing::internal::CaptureStderr; +using testing::internal::GetCapturedStderr; + +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still +// defined but do not trigger failures when death tests are not available on +// the system. +TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { + // Empty statement will not crash, but that should not trigger a failure + // when death tests are not supported. + CaptureStderr(); + EXPECT_DEATH_IF_SUPPORTED(;, ""); + std::string output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + // The streamed message should not be printed as there is no test failure. + CaptureStderr(); + EXPECT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, ""); // NOLINT + output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; // NOLINT + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); +} + +void FuncWithAssert(int* n) { + ASSERT_DEATH_IF_SUPPORTED(return;, ""); + (*n)++; +} + +// Tests that ASSERT_DEATH_IF_SUPPORTED does not return from the current +// function (as ASSERT_DEATH does) if death tests are not supported. +TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) { + int n = 0; + FuncWithAssert(&n); + EXPECT_EQ(1, n); +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +#endif // GTEST_HAS_DEATH_TEST + +// Tests that the death test macros expand to code which may or may not +// be followed by operator<<, and that in either case the complete text +// comprises only a single C++ statement. +// +// The syntax should work whether death tests are available or not. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) { + if (AlwaysFalse()) + // This would fail if executed; this is a compilation test only + ASSERT_DEATH_IF_SUPPORTED(return, ""); + + if (AlwaysTrue()) + EXPECT_DEATH_IF_SUPPORTED(_exit(1), ""); + else + // This empty "else" branch is meant to ensure that EXPECT_DEATH + // doesn't expand into an "if" statement without an "else" + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_DEATH_IF_SUPPORTED(return, "") << "did not die"; + + if (AlwaysFalse()) + ; // NOLINT + else + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << 1 << 2 << 3; +} + +// Tests that conditional death test macros expand to code which interacts +// well with switch statements. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { +// Microsoft compiler usually complains about switch statements without +// case labels. We suppress that warning for this test. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4065) +#endif // _MSC_VER + + switch (0) + default: + ASSERT_DEATH_IF_SUPPORTED(_exit(1), "") + << "exit in default switch handler"; + + switch (0) + case 0: + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case"; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif // _MSC_VER +} + +// Tests that a test case whose name ends with "DeathTest" works fine +// on Windows. +TEST(NotADeathTest, Test) { + SUCCEED(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-filepath_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-filepath_test.cc new file mode 100644 index 0000000..ae9f55a --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-filepath_test.cc @@ -0,0 +1,680 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This file tests classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included from gtest_unittest.cc, to avoid changing +// build or make-files for some existing Google Test clients. Do not +// #include this file anywhere else! + +#include "gtest/internal/gtest-filepath.h" +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS_MOBILE +# include // NOLINT +#elif GTEST_OS_WINDOWS +# include // NOLINT +#endif // GTEST_OS_WINDOWS_MOBILE + +namespace testing { +namespace internal { +namespace { + +#if GTEST_OS_WINDOWS_MOBILE +// TODO(wan@google.com): Move these to the POSIX adapter section in +// gtest-port.h. + +// Windows CE doesn't have the remove C function. +int remove(const char* path) { + LPCWSTR wpath = String::AnsiToUtf16(path); + int ret = DeleteFile(wpath) ? 0 : -1; + delete [] wpath; + return ret; +} +// Windows CE doesn't have the _rmdir C function. +int _rmdir(const char* path) { + FilePath filepath(path); + LPCWSTR wpath = String::AnsiToUtf16( + filepath.RemoveTrailingPathSeparator().c_str()); + int ret = RemoveDirectory(wpath) ? 0 : -1; + delete [] wpath; + return ret; +} + +#else + +TEST(GetCurrentDirTest, ReturnsCurrentDir) { + const FilePath original_dir = FilePath::GetCurrentDir(); + EXPECT_FALSE(original_dir.IsEmpty()); + + posix::ChDir(GTEST_PATH_SEP_); + const FilePath cwd = FilePath::GetCurrentDir(); + posix::ChDir(original_dir.c_str()); + +# if GTEST_OS_WINDOWS + + // Skips the ":". + const char* const cwd_without_drive = strchr(cwd.c_str(), ':'); + ASSERT_TRUE(cwd_without_drive != NULL); + EXPECT_STREQ(GTEST_PATH_SEP_, cwd_without_drive + 1); + +# else + + EXPECT_EQ(GTEST_PATH_SEP_, cwd.string()); + +# endif +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +TEST(IsEmptyTest, ReturnsTrueForEmptyPath) { + EXPECT_TRUE(FilePath("").IsEmpty()); +} + +TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) { + EXPECT_FALSE(FilePath("a").IsEmpty()); + EXPECT_FALSE(FilePath(".").IsEmpty()); + EXPECT_FALSE(FilePath("a/b").IsEmpty()); + EXPECT_FALSE(FilePath("a\\b\\").IsEmpty()); +} + +// RemoveDirectoryName "" -> "" +TEST(RemoveDirectoryNameTest, WhenEmptyName) { + EXPECT_EQ("", FilePath("").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "afile" -> "afile" +TEST(RemoveDirectoryNameTest, ButNoDirectory) { + EXPECT_EQ("afile", + FilePath("afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "/afile" -> "afile" +TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) { + EXPECT_EQ("afile", + FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/" -> "" +TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) { + EXPECT_EQ("", + FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldGiveFileName) { + EXPECT_EQ("afile", + FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/subdir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { + EXPECT_EQ("afile", + FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") + .RemoveDirectoryName().string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that RemoveDirectoryName() works with the alternate separator +// on Windows. + +// RemoveDirectoryName("/afile") -> "afile" +TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", FilePath("/afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/") -> "" +TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) { + EXPECT_EQ("", FilePath("adir/").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/afile") -> "afile" +TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", FilePath("adir/afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/subdir/afile") -> "afile" +TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", + FilePath("adir/subdir/afile").RemoveDirectoryName().string()); +} + +#endif + +// RemoveFileName "" -> "./" +TEST(RemoveFileNameTest, EmptyName) { +#if GTEST_OS_WINDOWS_MOBILE + // On Windows CE, we use the root as the current directory. + EXPECT_EQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); +#else + EXPECT_EQ("." GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); +#endif +} + +// RemoveFileName "adir/" -> "adir/" +TEST(RemoveFileNameTest, ButNoFile) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().string()); +} + +// RemoveFileName "adir/afile" -> "adir/" +TEST(RemoveFileNameTest, GivesDirName) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveFileName().string()); +} + +// RemoveFileName "adir/subdir/afile" -> "adir/subdir/" +TEST(RemoveFileNameTest, GivesDirAndSubDirName) { + EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") + .RemoveFileName().string()); +} + +// RemoveFileName "/afile" -> "/" +TEST(RemoveFileNameTest, GivesRootDir) { + EXPECT_EQ(GTEST_PATH_SEP_, + FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that RemoveFileName() works with the alternate separator on +// Windows. + +// RemoveFileName("adir/") -> "adir/" +TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir/").RemoveFileName().string()); +} + +// RemoveFileName("adir/afile") -> "adir/" +TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir/afile").RemoveFileName().string()); +} + +// RemoveFileName("adir/subdir/afile") -> "adir/subdir/" +TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + FilePath("adir/subdir/afile").RemoveFileName().string()); +} + +// RemoveFileName("/afile") -> "\" +TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) { + EXPECT_EQ(GTEST_PATH_SEP_, FilePath("/afile").RemoveFileName().string()); +} + +#endif + +TEST(MakeFileNameTest, GenerateWhenNumberIsZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), + 0, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), + 12, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar"), 0, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar"), 12, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) { + FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), + 0, "xml"); + EXPECT_EQ("bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) { + FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), + 14, "xml"); + EXPECT_EQ("bar_14.xml", actual.string()); +} + +TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), + FilePath("bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, Path1BeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath(""), + FilePath("bar.xml")); + EXPECT_EQ("bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, Path2BeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("")); + EXPECT_EQ("foo" GTEST_PATH_SEP_, actual.string()); +} + +TEST(ConcatPathsTest, BothPathBeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath(""), + FilePath("")); + EXPECT_EQ("", actual.string()); +} + +TEST(ConcatPathsTest, Path1ContainsPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"), + FilePath("foobar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml", + actual.string()); +} + +TEST(ConcatPathsTest, Path2ContainsPathSep) { + FilePath actual = FilePath::ConcatPaths( + FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar" GTEST_PATH_SEP_ "bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml", + actual.string()); +} + +TEST(ConcatPathsTest, Path2EndsWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), + FilePath("bar" GTEST_PATH_SEP_)); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.string()); +} + +// RemoveTrailingPathSeparator "" -> "" +TEST(RemoveTrailingPathSeparatorTest, EmptyString) { + EXPECT_EQ("", FilePath("").RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo" -> "foo" +TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) { + EXPECT_EQ("foo", FilePath("foo").RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo/" -> "foo" +TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) { + EXPECT_EQ("foo", + FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().string()); +#if GTEST_HAS_ALT_PATH_SEP_ + EXPECT_EQ("foo", FilePath("foo/").RemoveTrailingPathSeparator().string()); +#endif +} + +// RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/" +TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_) + .RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo/bar" -> "foo/bar" +TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar") + .RemoveTrailingPathSeparator().string()); +} + +TEST(DirectoryTest, RootDirectoryExists) { +#if GTEST_OS_WINDOWS // We are on Windows. + char current_drive[_MAX_PATH]; // NOLINT + current_drive[0] = static_cast(_getdrive() + 'A' - 1); + current_drive[1] = ':'; + current_drive[2] = '\\'; + current_drive[3] = '\0'; + EXPECT_TRUE(FilePath(current_drive).DirectoryExists()); +#else + EXPECT_TRUE(FilePath("/").DirectoryExists()); +#endif // GTEST_OS_WINDOWS +} + +#if GTEST_OS_WINDOWS +TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { + const int saved_drive_ = _getdrive(); + // Find a drive that doesn't exist. Start with 'Z' to avoid common ones. + for (char drive = 'Z'; drive >= 'A'; drive--) + if (_chdrive(drive - 'A' + 1) == -1) { + char non_drive[_MAX_PATH]; // NOLINT + non_drive[0] = drive; + non_drive[1] = ':'; + non_drive[2] = '\\'; + non_drive[3] = '\0'; + EXPECT_FALSE(FilePath(non_drive).DirectoryExists()); + break; + } + _chdrive(saved_drive_); +} +#endif // GTEST_OS_WINDOWS + +#if !GTEST_OS_WINDOWS_MOBILE +// Windows CE _does_ consider an empty directory to exist. +TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { + EXPECT_FALSE(FilePath("").DirectoryExists()); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +TEST(DirectoryTest, CurrentDirectoryExists) { +#if GTEST_OS_WINDOWS // We are on Windows. +# ifndef _WIN32_CE // Windows CE doesn't have a current directory. + + EXPECT_TRUE(FilePath(".").DirectoryExists()); + EXPECT_TRUE(FilePath(".\\").DirectoryExists()); + +# endif // _WIN32_CE +#else + EXPECT_TRUE(FilePath(".").DirectoryExists()); + EXPECT_TRUE(FilePath("./").DirectoryExists()); +#endif // GTEST_OS_WINDOWS +} + +// "foo/bar" == foo//bar" == "foo///bar" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ + GTEST_PATH_SEP_ "bar").string()); +} + +// "/bar" == //bar" == "///bar" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) { + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); +} + +// "foo/" == foo//" == "foo///" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_).string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that separators at the end of the string are normalized +// regardless of their combination (e.g. "foo\" =="foo/\" == +// "foo\\/"). +TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) { + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo/").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ "/").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo//" GTEST_PATH_SEP_).string()); +} + +#endif + +TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) { + FilePath default_path; + FilePath non_default_path("path"); + non_default_path = default_path; + EXPECT_EQ("", non_default_path.string()); + EXPECT_EQ("", default_path.string()); // RHS var is unchanged. +} + +TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) { + FilePath non_default_path("path"); + FilePath default_path; + default_path = non_default_path; + EXPECT_EQ("path", default_path.string()); + EXPECT_EQ("path", non_default_path.string()); // RHS var is unchanged. +} + +TEST(AssignmentOperatorTest, ConstAssignedToNonConst) { + const FilePath const_default_path("const_path"); + FilePath non_default_path("path"); + non_default_path = const_default_path; + EXPECT_EQ("const_path", non_default_path.string()); +} + +class DirectoryCreationTest : public Test { + protected: + virtual void SetUp() { + testdata_path_.Set(FilePath( + TempDir() + GetCurrentExecutableName().string() + + "_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_)); + testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator()); + + unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), + 0, "txt")); + unique_file1_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), + 1, "txt")); + + remove(testdata_file_.c_str()); + remove(unique_file0_.c_str()); + remove(unique_file1_.c_str()); + posix::RmDir(testdata_path_.c_str()); + } + + virtual void TearDown() { + remove(testdata_file_.c_str()); + remove(unique_file0_.c_str()); + remove(unique_file1_.c_str()); + posix::RmDir(testdata_path_.c_str()); + } + + std::string TempDir() const { +#if GTEST_OS_WINDOWS_MOBILE + return "\\temp\\"; +#elif GTEST_OS_WINDOWS + const char* temp_dir = posix::GetEnv("TEMP"); + if (temp_dir == NULL || temp_dir[0] == '\0') + return "\\temp\\"; + else if (temp_dir[strlen(temp_dir) - 1] == '\\') + return temp_dir; + else + return std::string(temp_dir) + "\\"; +#elif GTEST_OS_LINUX_ANDROID + return "/sdcard/"; +#else + return "/tmp/"; +#endif // GTEST_OS_WINDOWS_MOBILE + } + + void CreateTextFile(const char* filename) { + FILE* f = posix::FOpen(filename, "w"); + fprintf(f, "text\n"); + fclose(f); + } + + // Strings representing a directory and a file, with identical paths + // except for the trailing separator character that distinquishes + // a directory named 'test' from a file named 'test'. Example names: + FilePath testdata_path_; // "/tmp/directory_creation/test/" + FilePath testdata_file_; // "/tmp/directory_creation/test" + FilePath unique_file0_; // "/tmp/directory_creation/test/unique.txt" + FilePath unique_file1_; // "/tmp/directory_creation/test/unique_1.txt" +}; + +TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) { + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); + EXPECT_TRUE(testdata_path_.DirectoryExists()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) { + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); + // Call 'create' again... should still succeed. + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) { + FilePath file_path(FilePath::GenerateUniqueFileName(testdata_path_, + FilePath("unique"), "txt")); + EXPECT_EQ(unique_file0_.string(), file_path.string()); + EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file not there + + testdata_path_.CreateDirectoriesRecursively(); + EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file still not there + CreateTextFile(file_path.c_str()); + EXPECT_TRUE(file_path.FileOrDirectoryExists()); + + FilePath file_path2(FilePath::GenerateUniqueFileName(testdata_path_, + FilePath("unique"), "txt")); + EXPECT_EQ(unique_file1_.string(), file_path2.string()); + EXPECT_FALSE(file_path2.FileOrDirectoryExists()); // file not there + CreateTextFile(file_path2.c_str()); + EXPECT_TRUE(file_path2.FileOrDirectoryExists()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesFail) { + // force a failure by putting a file where we will try to create a directory. + CreateTextFile(testdata_file_.c_str()); + EXPECT_TRUE(testdata_file_.FileOrDirectoryExists()); + EXPECT_FALSE(testdata_file_.DirectoryExists()); + EXPECT_FALSE(testdata_file_.CreateDirectoriesRecursively()); +} + +TEST(NoDirectoryCreationTest, CreateNoDirectoriesForDefaultXmlFile) { + const FilePath test_detail_xml("test_detail.xml"); + EXPECT_FALSE(test_detail_xml.CreateDirectoriesRecursively()); +} + +TEST(FilePathTest, DefaultConstructor) { + FilePath fp; + EXPECT_EQ("", fp.string()); +} + +TEST(FilePathTest, CharAndCopyConstructors) { + const FilePath fp("spicy"); + EXPECT_EQ("spicy", fp.string()); + + const FilePath fp_copy(fp); + EXPECT_EQ("spicy", fp_copy.string()); +} + +TEST(FilePathTest, StringConstructor) { + const FilePath fp(std::string("cider")); + EXPECT_EQ("cider", fp.string()); +} + +TEST(FilePathTest, Set) { + const FilePath apple("apple"); + FilePath mac("mac"); + mac.Set(apple); // Implement Set() since overloading operator= is forbidden. + EXPECT_EQ("apple", mac.string()); + EXPECT_EQ("apple", apple.string()); +} + +TEST(FilePathTest, ToString) { + const FilePath file("drink"); + EXPECT_EQ("drink", file.string()); +} + +TEST(FilePathTest, RemoveExtension) { + EXPECT_EQ("app", FilePath("app.cc").RemoveExtension("cc").string()); + EXPECT_EQ("app", FilePath("app.exe").RemoveExtension("exe").string()); + EXPECT_EQ("APP", FilePath("APP.EXE").RemoveExtension("exe").string()); +} + +TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) { + EXPECT_EQ("app", FilePath("app").RemoveExtension("exe").string()); +} + +TEST(FilePathTest, IsDirectory) { + EXPECT_FALSE(FilePath("cola").IsDirectory()); + EXPECT_TRUE(FilePath("koala" GTEST_PATH_SEP_).IsDirectory()); +#if GTEST_HAS_ALT_PATH_SEP_ + EXPECT_TRUE(FilePath("koala/").IsDirectory()); +#endif +} + +TEST(FilePathTest, IsAbsolutePath) { + EXPECT_FALSE(FilePath("is" GTEST_PATH_SEP_ "relative").IsAbsolutePath()); + EXPECT_FALSE(FilePath("").IsAbsolutePath()); +#if GTEST_OS_WINDOWS + EXPECT_TRUE(FilePath("c:\\" GTEST_PATH_SEP_ "is_not" + GTEST_PATH_SEP_ "relative").IsAbsolutePath()); + EXPECT_FALSE(FilePath("c:foo" GTEST_PATH_SEP_ "bar").IsAbsolutePath()); + EXPECT_TRUE(FilePath("c:/" GTEST_PATH_SEP_ "is_not" + GTEST_PATH_SEP_ "relative").IsAbsolutePath()); +#else + EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative") + .IsAbsolutePath()); +#endif // GTEST_OS_WINDOWS +} + +TEST(FilePathTest, IsRootDirectory) { +#if GTEST_OS_WINDOWS + EXPECT_TRUE(FilePath("a:\\").IsRootDirectory()); + EXPECT_TRUE(FilePath("Z:/").IsRootDirectory()); + EXPECT_TRUE(FilePath("e://").IsRootDirectory()); + EXPECT_FALSE(FilePath("").IsRootDirectory()); + EXPECT_FALSE(FilePath("b:").IsRootDirectory()); + EXPECT_FALSE(FilePath("b:a").IsRootDirectory()); + EXPECT_FALSE(FilePath("8:/").IsRootDirectory()); + EXPECT_FALSE(FilePath("c|/").IsRootDirectory()); +#else + EXPECT_TRUE(FilePath("/").IsRootDirectory()); + EXPECT_TRUE(FilePath("//").IsRootDirectory()); + EXPECT_FALSE(FilePath("").IsRootDirectory()); + EXPECT_FALSE(FilePath("\\").IsRootDirectory()); + EXPECT_FALSE(FilePath("/x").IsRootDirectory()); +#endif +} + +} // namespace +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-linked_ptr_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-linked_ptr_test.cc new file mode 100644 index 0000000..6fcf512 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-linked_ptr_test.cc @@ -0,0 +1,154 @@ +// Copyright 2003, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: Dan Egnor (egnor@google.com) +// Ported to Windows: Vadim Berman (vadimb@google.com) + +#include "gtest/internal/gtest-linked_ptr.h" + +#include +#include "gtest/gtest.h" + +namespace { + +using testing::Message; +using testing::internal::linked_ptr; + +int num; +Message* history = NULL; + +// Class which tracks allocation/deallocation +class A { + public: + A(): mynum(num++) { *history << "A" << mynum << " ctor\n"; } + virtual ~A() { *history << "A" << mynum << " dtor\n"; } + virtual void Use() { *history << "A" << mynum << " use\n"; } + protected: + int mynum; +}; + +// Subclass +class B : public A { + public: + B() { *history << "B" << mynum << " ctor\n"; } + ~B() { *history << "B" << mynum << " dtor\n"; } + virtual void Use() { *history << "B" << mynum << " use\n"; } +}; + +class LinkedPtrTest : public testing::Test { + public: + LinkedPtrTest() { + num = 0; + history = new Message; + } + + virtual ~LinkedPtrTest() { + delete history; + history = NULL; + } +}; + +TEST_F(LinkedPtrTest, GeneralTest) { + { + linked_ptr a0, a1, a2; + // Use explicit function call notation here to suppress self-assign warning. + a0.operator=(a0); + a1 = a2; + ASSERT_EQ(a0.get(), static_cast(NULL)); + ASSERT_EQ(a1.get(), static_cast(NULL)); + ASSERT_EQ(a2.get(), static_cast(NULL)); + ASSERT_TRUE(a0 == NULL); + ASSERT_TRUE(a1 == NULL); + ASSERT_TRUE(a2 == NULL); + + { + linked_ptr a3(new A); + a0 = a3; + ASSERT_TRUE(a0 == a3); + ASSERT_TRUE(a0 != NULL); + ASSERT_TRUE(a0.get() == a3); + ASSERT_TRUE(a0 == a3.get()); + linked_ptr a4(a0); + a1 = a4; + linked_ptr a5(new A); + ASSERT_TRUE(a5.get() != a3); + ASSERT_TRUE(a5 != a3.get()); + a2 = a5; + linked_ptr b0(new B); + linked_ptr a6(b0); + ASSERT_TRUE(b0 == a6); + ASSERT_TRUE(a6 == b0); + ASSERT_TRUE(b0 != NULL); + a5 = b0; + a5 = b0; + a3->Use(); + a4->Use(); + a5->Use(); + a6->Use(); + b0->Use(); + (*b0).Use(); + b0.get()->Use(); + } + + a0->Use(); + a1->Use(); + a2->Use(); + + a1 = a2; + a2.reset(new A); + a0.reset(); + + linked_ptr a7; + } + + ASSERT_STREQ( + "A0 ctor\n" + "A1 ctor\n" + "A2 ctor\n" + "B2 ctor\n" + "A0 use\n" + "A0 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 dtor\n" + "A2 dtor\n" + "A0 use\n" + "A0 use\n" + "A1 use\n" + "A3 ctor\n" + "A0 dtor\n" + "A3 dtor\n" + "A1 dtor\n", + history->GetString().c_str()); +} + +} // Unnamed namespace diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-listener_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-listener_test.cc new file mode 100644 index 0000000..99662cf --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-listener_test.cc @@ -0,0 +1,310 @@ +// Copyright 2009 Google Inc. All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This file verifies Google Test event listeners receive events at the +// right times. + +#include "gtest/gtest.h" +#include + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Environment; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListener; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +// Used by tests to register their events. +std::vector* g_events = NULL; + +namespace testing { +namespace internal { + +class EventRecordingListener : public TestEventListener { + public: + explicit EventRecordingListener(const char* name) : name_(name) {} + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnTestProgramStart")); + } + + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationStart") + << "(" << iteration << ")"; + g_events->push_back(message.GetString()); + } + + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart")); + } + + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd")); + } + + virtual void OnTestCaseStart(const TestCase& /*test_case*/) { + g_events->push_back(GetFullMethodName("OnTestCaseStart")); + } + + virtual void OnTestStart(const TestInfo& /*test_info*/) { + g_events->push_back(GetFullMethodName("OnTestStart")); + } + + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) { + g_events->push_back(GetFullMethodName("OnTestPartResult")); + } + + virtual void OnTestEnd(const TestInfo& /*test_info*/) { + g_events->push_back(GetFullMethodName("OnTestEnd")); + } + + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) { + g_events->push_back(GetFullMethodName("OnTestCaseEnd")); + } + + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart")); + } + + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd")); + } + + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationEnd") + << "(" << iteration << ")"; + g_events->push_back(message.GetString()); + } + + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnTestProgramEnd")); + } + + private: + std::string GetFullMethodName(const char* name) { + return name_ + "." + name; + } + + std::string name_; +}; + +class EnvironmentInvocationCatcher : public Environment { + protected: + virtual void SetUp() { + g_events->push_back("Environment::SetUp"); + } + + virtual void TearDown() { + g_events->push_back("Environment::TearDown"); + } +}; + +class ListenerTest : public Test { + protected: + static void SetUpTestCase() { + g_events->push_back("ListenerTest::SetUpTestCase"); + } + + static void TearDownTestCase() { + g_events->push_back("ListenerTest::TearDownTestCase"); + } + + virtual void SetUp() { + g_events->push_back("ListenerTest::SetUp"); + } + + virtual void TearDown() { + g_events->push_back("ListenerTest::TearDown"); + } +}; + +TEST_F(ListenerTest, DoesFoo) { + // Test execution order within a test case is not guaranteed so we are not + // recording the test name. + g_events->push_back("ListenerTest::* Test Body"); + SUCCEED(); // Triggers OnTestPartResult. +} + +TEST_F(ListenerTest, DoesBar) { + g_events->push_back("ListenerTest::* Test Body"); + SUCCEED(); // Triggers OnTestPartResult. +} + +} // namespace internal + +} // namespace testing + +using ::testing::internal::EnvironmentInvocationCatcher; +using ::testing::internal::EventRecordingListener; + +void VerifyResults(const std::vector& data, + const char* const* expected_data, + int expected_data_size) { + const int actual_size = data.size(); + // If the following assertion fails, a new entry will be appended to + // data. Hence we save data.size() first. + EXPECT_EQ(expected_data_size, actual_size); + + // Compares the common prefix. + const int shorter_size = expected_data_size <= actual_size ? + expected_data_size : actual_size; + int i = 0; + for (; i < shorter_size; ++i) { + ASSERT_STREQ(expected_data[i], data[i].c_str()) + << "at position " << i; + } + + // Prints extra elements in the actual data. + for (; i < actual_size; ++i) { + printf(" Actual event #%d: %s\n", i, data[i].c_str()); + } +} + +int main(int argc, char **argv) { + std::vector events; + g_events = &events; + InitGoogleTest(&argc, argv); + + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("1st")); + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("2nd")); + + AddGlobalTestEnvironment(new EnvironmentInvocationCatcher); + + GTEST_CHECK_(events.size() == 0) + << "AddGlobalTestEnvironment should not generate any events itself."; + + ::testing::GTEST_FLAG(repeat) = 2; + int ret_val = RUN_ALL_TESTS(); + + const char* const expected_events[] = { + "1st.OnTestProgramStart", + "2nd.OnTestProgramStart", + "1st.OnTestIterationStart(0)", + "2nd.OnTestIterationStart(0)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestCase", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(0)", + "1st.OnTestIterationEnd(0)", + "1st.OnTestIterationStart(1)", + "2nd.OnTestIterationStart(1)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestCase", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(1)", + "1st.OnTestIterationEnd(1)", + "2nd.OnTestProgramEnd", + "1st.OnTestProgramEnd" + }; + VerifyResults(events, + expected_events, + sizeof(expected_events)/sizeof(expected_events[0])); + + // We need to check manually for ad hoc test failures that happen after + // RUN_ALL_TESTS finishes. + if (UnitTest::GetInstance()->Failed()) + ret_val = 1; + + return ret_val; +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-message_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-message_test.cc new file mode 100644 index 0000000..175238e --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-message_test.cc @@ -0,0 +1,159 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for the Message class. + +#include "gtest/gtest-message.h" + +#include "gtest/gtest.h" + +namespace { + +using ::testing::Message; + +// Tests the testing::Message class + +// Tests the default constructor. +TEST(MessageTest, DefaultConstructor) { + const Message msg; + EXPECT_EQ("", msg.GetString()); +} + +// Tests the copy constructor. +TEST(MessageTest, CopyConstructor) { + const Message msg1("Hello"); + const Message msg2(msg1); + EXPECT_EQ("Hello", msg2.GetString()); +} + +// Tests constructing a Message from a C-string. +TEST(MessageTest, ConstructsFromCString) { + Message msg("Hello"); + EXPECT_EQ("Hello", msg.GetString()); +} + +// Tests streaming a float. +TEST(MessageTest, StreamsFloat) { + const std::string s = (Message() << 1.23456F << " " << 2.34567F).GetString(); + // Both numbers should be printed with enough precision. + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s.c_str()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s.c_str()); +} + +// Tests streaming a double. +TEST(MessageTest, StreamsDouble) { + const std::string s = (Message() << 1260570880.4555497 << " " + << 1260572265.1954534).GetString(); + // Both numbers should be printed with enough precision. + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s.c_str()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s.c_str()); +} + +// Tests streaming a non-char pointer. +TEST(MessageTest, StreamsPointer) { + int n = 0; + int* p = &n; + EXPECT_NE("(null)", (Message() << p).GetString()); +} + +// Tests streaming a NULL non-char pointer. +TEST(MessageTest, StreamsNullPointer) { + int* p = NULL; + EXPECT_EQ("(null)", (Message() << p).GetString()); +} + +// Tests streaming a C string. +TEST(MessageTest, StreamsCString) { + EXPECT_EQ("Foo", (Message() << "Foo").GetString()); +} + +// Tests streaming a NULL C string. +TEST(MessageTest, StreamsNullCString) { + char* p = NULL; + EXPECT_EQ("(null)", (Message() << p).GetString()); +} + +// Tests streaming std::string. +TEST(MessageTest, StreamsString) { + const ::std::string str("Hello"); + EXPECT_EQ("Hello", (Message() << str).GetString()); +} + +// Tests that we can output strings containing embedded NULs. +TEST(MessageTest, StreamsStringWithEmbeddedNUL) { + const char char_array_with_nul[] = + "Here's a NUL\0 and some more string"; + const ::std::string string_with_nul(char_array_with_nul, + sizeof(char_array_with_nul) - 1); + EXPECT_EQ("Here's a NUL\\0 and some more string", + (Message() << string_with_nul).GetString()); +} + +// Tests streaming a NUL char. +TEST(MessageTest, StreamsNULChar) { + EXPECT_EQ("\\0", (Message() << '\0').GetString()); +} + +// Tests streaming int. +TEST(MessageTest, StreamsInt) { + EXPECT_EQ("123", (Message() << 123).GetString()); +} + +// Tests that basic IO manipulators (endl, ends, and flush) can be +// streamed to Message. +TEST(MessageTest, StreamsBasicIoManip) { + EXPECT_EQ("Line 1.\nA NUL char \\0 in line 2.", + (Message() << "Line 1." << std::endl + << "A NUL char " << std::ends << std::flush + << " in line 2.").GetString()); +} + +// Tests Message::GetString() +TEST(MessageTest, GetString) { + Message msg; + msg << 1 << " lamb"; + EXPECT_EQ("1 lamb", msg.GetString()); +} + +// Tests streaming a Message object to an ostream. +TEST(MessageTest, StreamsToOStream) { + Message msg("Hello"); + ::std::stringstream ss; + ss << msg; + EXPECT_EQ("Hello", testing::internal::StringStreamToString(&ss)); +} + +// Tests that a Message object doesn't take up too much stack space. +TEST(MessageTest, DoesNotTakeUpMuchStackSpace) { + EXPECT_LE(sizeof(Message), 16U); +} + +} // namespace diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-options_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-options_test.cc new file mode 100644 index 0000000..5586dc3 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-options_test.cc @@ -0,0 +1,215 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) +// +// Google Test UnitTestOptions tests +// +// This file tests classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included from gtest.cc, to avoid changing build or +// make-files on Windows and other platforms. Do not #include this file +// anywhere else! + +#include "gtest/gtest.h" + +#if GTEST_OS_WINDOWS_MOBILE +# include +#elif GTEST_OS_WINDOWS +# include +#endif // GTEST_OS_WINDOWS_MOBILE + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { +namespace { + +// Turns the given relative path into an absolute path. +FilePath GetAbsolutePathOf(const FilePath& relative_path) { + return FilePath::ConcatPaths(FilePath::GetCurrentDir(), relative_path); +} + +// Testing UnitTestOptions::GetOutputFormat/GetOutputFile. + +TEST(XmlOutputTest, GetOutputFormatDefault) { + GTEST_FLAG(output) = ""; + EXPECT_STREQ("", UnitTestOptions::GetOutputFormat().c_str()); +} + +TEST(XmlOutputTest, GetOutputFormat) { + GTEST_FLAG(output) = "xml:filename"; + EXPECT_STREQ("xml", UnitTestOptions::GetOutputFormat().c_str()); +} + +TEST(XmlOutputTest, GetOutputFileDefault) { + GTEST_FLAG(output) = ""; + EXPECT_EQ(GetAbsolutePathOf(FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST(XmlOutputTest, GetOutputFileSingleFile) { + GTEST_FLAG(output) = "xml:filename.abc"; + EXPECT_EQ(GetAbsolutePathOf(FilePath("filename.abc")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { + GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; + const std::string expected_output_file = + GetAbsolutePathOf( + FilePath(std::string("path") + GTEST_PATH_SEP_ + + GetCurrentExecutableName().string() + ".xml")).string(); + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +TEST(OutputFileHelpersTest, GetCurrentExecutableName) { + const std::string exe_str = GetCurrentExecutableName().string(); +#if GTEST_OS_WINDOWS + const bool success = + _strcmpi("gtest-options_test", exe_str.c_str()) == 0 || + _strcmpi("gtest-options-ex_test", exe_str.c_str()) == 0 || + _strcmpi("gtest_all_test", exe_str.c_str()) == 0 || + _strcmpi("gtest_dll_test", exe_str.c_str()) == 0; +#else + // TODO(wan@google.com): remove the hard-coded "lt-" prefix when + // Chandler Carruth's libtool replacement is ready. + const bool success = + exe_str == "gtest-options_test" || + exe_str == "gtest_all_test" || + exe_str == "lt-gtest_all_test" || + exe_str == "gtest_dll_test"; +#endif // GTEST_OS_WINDOWS + if (!success) + FAIL() << "GetCurrentExecutableName() returns " << exe_str; +} + +class XmlOutputChangeDirTest : public Test { + protected: + virtual void SetUp() { + original_working_dir_ = FilePath::GetCurrentDir(); + posix::ChDir(".."); + // This will make the test fail if run from the root directory. + EXPECT_NE(original_working_dir_.string(), + FilePath::GetCurrentDir().string()); + } + + virtual void TearDown() { + posix::ChDir(original_working_dir_.string().c_str()); + } + + FilePath original_working_dir_; +}; + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) { + GTEST_FLAG(output) = ""; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) { + GTEST_FLAG(output) = "xml"; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) { + GTEST_FLAG(output) = "xml:filename.abc"; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("filename.abc")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { + GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; + const std::string expected_output_file = + FilePath::ConcatPaths( + original_working_dir_, + FilePath(std::string("path") + GTEST_PATH_SEP_ + + GetCurrentExecutableName().string() + ".xml")).string(); + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { +#if GTEST_OS_WINDOWS + GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc"; + EXPECT_EQ(FilePath("c:\\tmp\\filename.abc").string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +#else + GTEST_FLAG(output) ="xml:/tmp/filename.abc"; + EXPECT_EQ(FilePath("/tmp/filename.abc").string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +#endif +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { +#if GTEST_OS_WINDOWS + const std::string path = "c:\\tmp\\"; +#else + const std::string path = "/tmp/"; +#endif + + GTEST_FLAG(output) = "xml:" + path; + const std::string expected_output_file = + path + GetCurrentExecutableName().string() + ".xml"; + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); + +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +} // namespace +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-param-test2_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-param-test2_test.cc new file mode 100644 index 0000000..4a782fe --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-param-test2_test.cc @@ -0,0 +1,65 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. This verifies that the basic constructs of +// Google Test work. + +#include "gtest/gtest.h" + +#include "test/gtest-param-test_test.h" + +#if GTEST_HAS_PARAM_TEST + +using ::testing::Values; +using ::testing::internal::ParamGenerator; + +// Tests that generators defined in a different translation unit +// are functional. The test using extern_gen is defined +// in gtest-param-test_test.cc. +ParamGenerator extern_gen = Values(33); + +// Tests that a parameterized test case can be defined in one translation unit +// and instantiated in another. The test is defined in gtest-param-test_test.cc +// and ExternalInstantiationTest fixture class is defined in +// gtest-param-test_test.h. +INSTANTIATE_TEST_CASE_P(MultiplesOf33, + ExternalInstantiationTest, + Values(33, 66)); + +// Tests that a parameterized test case can be instantiated +// in multiple translation units. Another instantiation is defined +// in gtest-param-test_test.cc and InstantiationInMultipleTranslaionUnitsTest +// fixture is defined in gtest-param-test_test.h +INSTANTIATE_TEST_CASE_P(Sequence2, + InstantiationInMultipleTranslaionUnitsTest, + Values(42*3, 42*4, 42*5)); + +#endif // GTEST_HAS_PARAM_TEST diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-param-test_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-param-test_test.cc new file mode 100644 index 0000000..f60cb8a --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-param-test_test.cc @@ -0,0 +1,904 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. This file verifies that the parameter +// generators objects produce correct parameter sequences and that +// Google Test runtime instantiates correct tests from those sequences. + +#include "gtest/gtest.h" + +#if GTEST_HAS_PARAM_TEST + +# include +# include +# include +# include +# include +# include + +// To include gtest-internal-inl.h. +# define GTEST_IMPLEMENTATION_ 1 +# include "src/gtest-internal-inl.h" // for UnitTestOptions +# undef GTEST_IMPLEMENTATION_ + +# include "test/gtest-param-test_test.h" + +using ::std::vector; +using ::std::sort; + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Bool; +using ::testing::Message; +using ::testing::Range; +using ::testing::TestWithParam; +using ::testing::Values; +using ::testing::ValuesIn; + +# if GTEST_HAS_COMBINE +using ::testing::Combine; +using ::std::tr1::get; +using ::std::tr1::make_tuple; +using ::std::tr1::tuple; +# endif // GTEST_HAS_COMBINE + +using ::testing::internal::ParamGenerator; +using ::testing::internal::UnitTestOptions; + +// Prints a value to a string. +// +// TODO(wan@google.com): remove PrintValue() when we move matchers and +// EXPECT_THAT() from Google Mock to Google Test. At that time, we +// can write EXPECT_THAT(x, Eq(y)) to compare two tuples x and y, as +// EXPECT_THAT() and the matchers know how to print tuples. +template +::std::string PrintValue(const T& value) { + ::std::stringstream stream; + stream << value; + return stream.str(); +} + +# if GTEST_HAS_COMBINE + +// These overloads allow printing tuples in our tests. We cannot +// define an operator<< for tuples, as that definition needs to be in +// the std namespace in order to be picked up by Google Test via +// Argument-Dependent Lookup, yet defining anything in the std +// namespace in non-STL code is undefined behavior. + +template +::std::string PrintValue(const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) << ")"; + return stream.str(); +} + +template +::std::string PrintValue(const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) + << ", "<< get<2>(value) << ")"; + return stream.str(); +} + +template +::std::string PrintValue( + const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) + << ", "<< get<2>(value) << ", " << get<3>(value) + << ", "<< get<4>(value) << ", " << get<5>(value) + << ", "<< get<6>(value) << ", " << get<7>(value) + << ", "<< get<8>(value) << ", " << get<9>(value) << ")"; + return stream.str(); +} + +# endif // GTEST_HAS_COMBINE + +// Verifies that a sequence generated by the generator and accessed +// via the iterator object matches the expected one using Google Test +// assertions. +template +void VerifyGenerator(const ParamGenerator& generator, + const T (&expected_values)[N]) { + typename ParamGenerator::iterator it = generator.begin(); + for (size_t i = 0; i < N; ++i) { + ASSERT_FALSE(it == generator.end()) + << "At element " << i << " when accessing via an iterator " + << "created with the copy constructor.\n"; + // We cannot use EXPECT_EQ() here as the values may be tuples, + // which don't support <<. + EXPECT_TRUE(expected_values[i] == *it) + << "where i is " << i + << ", expected_values[i] is " << PrintValue(expected_values[i]) + << ", *it is " << PrintValue(*it) + << ", and 'it' is an iterator created with the copy constructor.\n"; + it++; + } + EXPECT_TRUE(it == generator.end()) + << "At the presumed end of sequence when accessing via an iterator " + << "created with the copy constructor.\n"; + + // Test the iterator assignment. The following lines verify that + // the sequence accessed via an iterator initialized via the + // assignment operator (as opposed to a copy constructor) matches + // just the same. + it = generator.begin(); + for (size_t i = 0; i < N; ++i) { + ASSERT_FALSE(it == generator.end()) + << "At element " << i << " when accessing via an iterator " + << "created with the assignment operator.\n"; + EXPECT_TRUE(expected_values[i] == *it) + << "where i is " << i + << ", expected_values[i] is " << PrintValue(expected_values[i]) + << ", *it is " << PrintValue(*it) + << ", and 'it' is an iterator created with the copy constructor.\n"; + it++; + } + EXPECT_TRUE(it == generator.end()) + << "At the presumed end of sequence when accessing via an iterator " + << "created with the assignment operator.\n"; +} + +template +void VerifyGeneratorIsEmpty(const ParamGenerator& generator) { + typename ParamGenerator::iterator it = generator.begin(); + EXPECT_TRUE(it == generator.end()); + + it = generator.begin(); + EXPECT_TRUE(it == generator.end()); +} + +// Generator tests. They test that each of the provided generator functions +// generates an expected sequence of values. The general test pattern +// instantiates a generator using one of the generator functions, +// checks the sequence produced by the generator using its iterator API, +// and then resets the iterator back to the beginning of the sequence +// and checks the sequence again. + +// Tests that iterators produced by generator functions conform to the +// ForwardIterator concept. +TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) { + const ParamGenerator gen = Range(0, 10); + ParamGenerator::iterator it = gen.begin(); + + // Verifies that iterator initialization works as expected. + ParamGenerator::iterator it2 = it; + EXPECT_TRUE(*it == *it2) << "Initialized iterators must point to the " + << "element same as its source points to"; + + // Verifies that iterator assignment works as expected. + it++; + EXPECT_FALSE(*it == *it2); + it2 = it; + EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the " + << "element same as its source points to"; + + // Verifies that prefix operator++() returns *this. + EXPECT_EQ(&it, &(++it)) << "Result of the prefix operator++ must be " + << "refer to the original object"; + + // Verifies that the result of the postfix operator++ points to the value + // pointed to by the original iterator. + int original_value = *it; // Have to compute it outside of macro call to be + // unaffected by the parameter evaluation order. + EXPECT_EQ(original_value, *(it++)); + + // Verifies that prefix and postfix operator++() advance an iterator + // all the same. + it2 = it; + it++; + ++it2; + EXPECT_TRUE(*it == *it2); +} + +// Tests that Range() generates the expected sequence. +TEST(RangeTest, IntRangeWithDefaultStep) { + const ParamGenerator gen = Range(0, 3); + const int expected_values[] = {0, 1, 2}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that Range() generates the single element sequence +// as expected when provided with range limits that are equal. +TEST(RangeTest, IntRangeSingleValue) { + const ParamGenerator gen = Range(0, 1); + const int expected_values[] = {0}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that Range() with generates empty sequence when +// supplied with an empty range. +TEST(RangeTest, IntRangeEmpty) { + const ParamGenerator gen = Range(0, 0); + VerifyGeneratorIsEmpty(gen); +} + +// Tests that Range() with custom step (greater then one) generates +// the expected sequence. +TEST(RangeTest, IntRangeWithCustomStep) { + const ParamGenerator gen = Range(0, 9, 3); + const int expected_values[] = {0, 3, 6}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Range() with custom step (greater then one) generates +// the expected sequence when the last element does not fall on the +// upper range limit. Sequences generated by Range() must not have +// elements beyond the range limits. +TEST(RangeTest, IntRangeWithCustomStepOverUpperBound) { + const ParamGenerator gen = Range(0, 4, 3); + const int expected_values[] = {0, 3}; + VerifyGenerator(gen, expected_values); +} + +// Verifies that Range works with user-defined types that define +// copy constructor, operator=(), operator+(), and operator<(). +class DogAdder { + public: + explicit DogAdder(const char* a_value) : value_(a_value) {} + DogAdder(const DogAdder& other) : value_(other.value_.c_str()) {} + + DogAdder operator=(const DogAdder& other) { + if (this != &other) + value_ = other.value_; + return *this; + } + DogAdder operator+(const DogAdder& other) const { + Message msg; + msg << value_.c_str() << other.value_.c_str(); + return DogAdder(msg.GetString().c_str()); + } + bool operator<(const DogAdder& other) const { + return value_ < other.value_; + } + const std::string& value() const { return value_; } + + private: + std::string value_; +}; + +TEST(RangeTest, WorksWithACustomType) { + const ParamGenerator gen = + Range(DogAdder("cat"), DogAdder("catdogdog"), DogAdder("dog")); + ParamGenerator::iterator it = gen.begin(); + + ASSERT_FALSE(it == gen.end()); + EXPECT_STREQ("cat", it->value().c_str()); + + ASSERT_FALSE(++it == gen.end()); + EXPECT_STREQ("catdog", it->value().c_str()); + + EXPECT_TRUE(++it == gen.end()); +} + +class IntWrapper { + public: + explicit IntWrapper(int a_value) : value_(a_value) {} + IntWrapper(const IntWrapper& other) : value_(other.value_) {} + + IntWrapper operator=(const IntWrapper& other) { + value_ = other.value_; + return *this; + } + // operator+() adds a different type. + IntWrapper operator+(int other) const { return IntWrapper(value_ + other); } + bool operator<(const IntWrapper& other) const { + return value_ < other.value_; + } + int value() const { return value_; } + + private: + int value_; +}; + +TEST(RangeTest, WorksWithACustomTypeWithDifferentIncrementType) { + const ParamGenerator gen = Range(IntWrapper(0), IntWrapper(2)); + ParamGenerator::iterator it = gen.begin(); + + ASSERT_FALSE(it == gen.end()); + EXPECT_EQ(0, it->value()); + + ASSERT_FALSE(++it == gen.end()); + EXPECT_EQ(1, it->value()); + + EXPECT_TRUE(++it == gen.end()); +} + +// Tests that ValuesIn() with an array parameter generates +// the expected sequence. +TEST(ValuesInTest, ValuesInArray) { + int array[] = {3, 5, 8}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Tests that ValuesIn() with a const array parameter generates +// the expected sequence. +TEST(ValuesInTest, ValuesInConstArray) { + const int array[] = {3, 5, 8}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Edge case. Tests that ValuesIn() with an array parameter containing a +// single element generates the single element sequence. +TEST(ValuesInTest, ValuesInSingleElementArray) { + int array[] = {42}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Tests that ValuesIn() generates the expected sequence for an STL +// container (vector). +TEST(ValuesInTest, ValuesInVector) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(3); + values.push_back(5); + values.push_back(8); + const ParamGenerator gen = ValuesIn(values); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Tests that ValuesIn() generates the expected sequence. +TEST(ValuesInTest, ValuesInIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(3); + values.push_back(5); + values.push_back(8); + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that ValuesIn() provided with an iterator range specifying a +// single value generates a single-element sequence. +TEST(ValuesInTest, ValuesInSingleElementIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(42); + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + const int expected_values[] = {42}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that ValuesIn() provided with an empty iterator range +// generates an empty sequence. +TEST(ValuesInTest, ValuesInEmptyIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + VerifyGeneratorIsEmpty(gen); +} + +// Tests that the Values() generates the expected sequence. +TEST(ValuesTest, ValuesWorks) { + const ParamGenerator gen = Values(3, 5, 8); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Values() generates the expected sequences from elements of +// different types convertible to ParamGenerator's parameter type. +TEST(ValuesTest, ValuesWorksForValuesOfCompatibleTypes) { + const ParamGenerator gen = Values(3, 5.0f, 8.0); + + const double expected_values[] = {3.0, 5.0, 8.0}; + VerifyGenerator(gen, expected_values); +} + +TEST(ValuesTest, ValuesWorksForMaxLengthList) { + const ParamGenerator gen = Values( + 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, + 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, + 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, + 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, + 410, 420, 430, 440, 450, 460, 470, 480, 490, 500); + + const int expected_values[] = { + 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, + 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, + 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, + 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, + 410, 420, 430, 440, 450, 460, 470, 480, 490, 500}; + VerifyGenerator(gen, expected_values); +} + +// Edge case test. Tests that single-parameter Values() generates the sequence +// with the single value. +TEST(ValuesTest, ValuesWithSingleParameter) { + const ParamGenerator gen = Values(42); + + const int expected_values[] = {42}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Bool() generates sequence (false, true). +TEST(BoolTest, BoolWorks) { + const ParamGenerator gen = Bool(); + + const bool expected_values[] = {false, true}; + VerifyGenerator(gen, expected_values); +} + +# if GTEST_HAS_COMBINE + +// Tests that Combine() with two parameters generates the expected sequence. +TEST(CombineTest, CombineWithTwoParameters) { + const char* foo = "foo"; + const char* bar = "bar"; + const ParamGenerator > gen = + Combine(Values(foo, bar), Values(3, 4)); + + tuple expected_values[] = { + make_tuple(foo, 3), make_tuple(foo, 4), + make_tuple(bar, 3), make_tuple(bar, 4)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Combine() with three parameters generates the expected sequence. +TEST(CombineTest, CombineWithThreeParameters) { + const ParamGenerator > gen = Combine(Values(0, 1), + Values(3, 4), + Values(5, 6)); + tuple expected_values[] = { + make_tuple(0, 3, 5), make_tuple(0, 3, 6), + make_tuple(0, 4, 5), make_tuple(0, 4, 6), + make_tuple(1, 3, 5), make_tuple(1, 3, 6), + make_tuple(1, 4, 5), make_tuple(1, 4, 6)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that the Combine() with the first parameter generating a single value +// sequence generates a sequence with the number of elements equal to the +// number of elements in the sequence generated by the second parameter. +TEST(CombineTest, CombineWithFirstParameterSingleValue) { + const ParamGenerator > gen = Combine(Values(42), + Values(0, 1)); + + tuple expected_values[] = {make_tuple(42, 0), make_tuple(42, 1)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that the Combine() with the second parameter generating a single value +// sequence generates a sequence with the number of elements equal to the +// number of elements in the sequence generated by the first parameter. +TEST(CombineTest, CombineWithSecondParameterSingleValue) { + const ParamGenerator > gen = Combine(Values(0, 1), + Values(42)); + + tuple expected_values[] = {make_tuple(0, 42), make_tuple(1, 42)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that when the first parameter produces an empty sequence, +// Combine() produces an empty sequence, too. +TEST(CombineTest, CombineWithFirstParameterEmptyRange) { + const ParamGenerator > gen = Combine(Range(0, 0), + Values(0, 1)); + VerifyGeneratorIsEmpty(gen); +} + +// Tests that when the second parameter produces an empty sequence, +// Combine() produces an empty sequence, too. +TEST(CombineTest, CombineWithSecondParameterEmptyRange) { + const ParamGenerator > gen = Combine(Values(0, 1), + Range(1, 1)); + VerifyGeneratorIsEmpty(gen); +} + +// Edge case. Tests that combine works with the maximum number +// of parameters supported by Google Test (currently 10). +TEST(CombineTest, CombineWithMaxNumberOfParameters) { + const char* foo = "foo"; + const char* bar = "bar"; + const ParamGenerator > gen = Combine(Values(foo, bar), + Values(1), Values(2), + Values(3), Values(4), + Values(5), Values(6), + Values(7), Values(8), + Values(9)); + + tuple + expected_values[] = {make_tuple(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9), + make_tuple(bar, 1, 2, 3, 4, 5, 6, 7, 8, 9)}; + VerifyGenerator(gen, expected_values); +} + +# endif // GTEST_HAS_COMBINE + +// Tests that an generator produces correct sequence after being +// assigned from another generator. +TEST(ParamGeneratorTest, AssignmentWorks) { + ParamGenerator gen = Values(1, 2); + const ParamGenerator gen2 = Values(3, 4); + gen = gen2; + + const int expected_values[] = {3, 4}; + VerifyGenerator(gen, expected_values); +} + +// This test verifies that the tests are expanded and run as specified: +// one test per element from the sequence produced by the generator +// specified in INSTANTIATE_TEST_CASE_P. It also verifies that the test's +// fixture constructor, SetUp(), and TearDown() have run and have been +// supplied with the correct parameters. + +// The use of environment object allows detection of the case where no test +// case functionality is run at all. In this case TestCaseTearDown will not +// be able to detect missing tests, naturally. +template +class TestGenerationEnvironment : public ::testing::Environment { + public: + static TestGenerationEnvironment* Instance() { + static TestGenerationEnvironment* instance = new TestGenerationEnvironment; + return instance; + } + + void FixtureConstructorExecuted() { fixture_constructor_count_++; } + void SetUpExecuted() { set_up_count_++; } + void TearDownExecuted() { tear_down_count_++; } + void TestBodyExecuted() { test_body_count_++; } + + virtual void TearDown() { + // If all MultipleTestGenerationTest tests have been de-selected + // by the filter flag, the following checks make no sense. + bool perform_check = false; + + for (int i = 0; i < kExpectedCalls; ++i) { + Message msg; + msg << "TestsExpandedAndRun/" << i; + if (UnitTestOptions::FilterMatchesTest( + "TestExpansionModule/MultipleTestGenerationTest", + msg.GetString().c_str())) { + perform_check = true; + } + } + if (perform_check) { + EXPECT_EQ(kExpectedCalls, fixture_constructor_count_) + << "Fixture constructor of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, set_up_count_) + << "Fixture SetUp method of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, tear_down_count_) + << "Fixture TearDown method of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, test_body_count_) + << "Test in ParamTestGenerationTest test case " + << "has not been run as expected."; + } + } + + private: + TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0), + tear_down_count_(0), test_body_count_(0) {} + + int fixture_constructor_count_; + int set_up_count_; + int tear_down_count_; + int test_body_count_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationEnvironment); +}; + +const int test_generation_params[] = {36, 42, 72}; + +class TestGenerationTest : public TestWithParam { + public: + enum { + PARAMETER_COUNT = + sizeof(test_generation_params)/sizeof(test_generation_params[0]) + }; + + typedef TestGenerationEnvironment Environment; + + TestGenerationTest() { + Environment::Instance()->FixtureConstructorExecuted(); + current_parameter_ = GetParam(); + } + virtual void SetUp() { + Environment::Instance()->SetUpExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + } + virtual void TearDown() { + Environment::Instance()->TearDownExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + } + + static void SetUpTestCase() { + bool all_tests_in_test_case_selected = true; + + for (int i = 0; i < PARAMETER_COUNT; ++i) { + Message test_name; + test_name << "TestsExpandedAndRun/" << i; + if ( !UnitTestOptions::FilterMatchesTest( + "TestExpansionModule/MultipleTestGenerationTest", + test_name.GetString())) { + all_tests_in_test_case_selected = false; + } + } + EXPECT_TRUE(all_tests_in_test_case_selected) + << "When running the TestGenerationTest test case all of its tests\n" + << "must be selected by the filter flag for the test case to pass.\n" + << "If not all of them are enabled, we can't reliably conclude\n" + << "that the correct number of tests have been generated."; + + collected_parameters_.clear(); + } + + static void TearDownTestCase() { + vector expected_values(test_generation_params, + test_generation_params + PARAMETER_COUNT); + // Test execution order is not guaranteed by Google Test, + // so the order of values in collected_parameters_ can be + // different and we have to sort to compare. + sort(expected_values.begin(), expected_values.end()); + sort(collected_parameters_.begin(), collected_parameters_.end()); + + EXPECT_TRUE(collected_parameters_ == expected_values); + } + + protected: + int current_parameter_; + static vector collected_parameters_; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationTest); +}; +vector TestGenerationTest::collected_parameters_; + +TEST_P(TestGenerationTest, TestsExpandedAndRun) { + Environment::Instance()->TestBodyExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + collected_parameters_.push_back(GetParam()); +} +INSTANTIATE_TEST_CASE_P(TestExpansionModule, TestGenerationTest, + ValuesIn(test_generation_params)); + +// This test verifies that the element sequence (third parameter of +// INSTANTIATE_TEST_CASE_P) is evaluated in InitGoogleTest() and neither at +// the call site of INSTANTIATE_TEST_CASE_P nor in RUN_ALL_TESTS(). For +// that, we declare param_value_ to be a static member of +// GeneratorEvaluationTest and initialize it to 0. We set it to 1 in +// main(), just before invocation of InitGoogleTest(). After calling +// InitGoogleTest(), we set the value to 2. If the sequence is evaluated +// before or after InitGoogleTest, INSTANTIATE_TEST_CASE_P will create a +// test with parameter other than 1, and the test body will fail the +// assertion. +class GeneratorEvaluationTest : public TestWithParam { + public: + static int param_value() { return param_value_; } + static void set_param_value(int param_value) { param_value_ = param_value; } + + private: + static int param_value_; +}; +int GeneratorEvaluationTest::param_value_ = 0; + +TEST_P(GeneratorEvaluationTest, GeneratorsEvaluatedInMain) { + EXPECT_EQ(1, GetParam()); +} +INSTANTIATE_TEST_CASE_P(GenEvalModule, + GeneratorEvaluationTest, + Values(GeneratorEvaluationTest::param_value())); + +// Tests that generators defined in a different translation unit are +// functional. Generator extern_gen is defined in gtest-param-test_test2.cc. +extern ParamGenerator extern_gen; +class ExternalGeneratorTest : public TestWithParam {}; +TEST_P(ExternalGeneratorTest, ExternalGenerator) { + // Sequence produced by extern_gen contains only a single value + // which we verify here. + EXPECT_EQ(GetParam(), 33); +} +INSTANTIATE_TEST_CASE_P(ExternalGeneratorModule, + ExternalGeneratorTest, + extern_gen); + +// Tests that a parameterized test case can be defined in one translation +// unit and instantiated in another. This test will be instantiated in +// gtest-param-test_test2.cc. ExternalInstantiationTest fixture class is +// defined in gtest-param-test_test.h. +TEST_P(ExternalInstantiationTest, IsMultipleOf33) { + EXPECT_EQ(0, GetParam() % 33); +} + +// Tests that a parameterized test case can be instantiated with multiple +// generators. +class MultipleInstantiationTest : public TestWithParam {}; +TEST_P(MultipleInstantiationTest, AllowsMultipleInstances) { +} +INSTANTIATE_TEST_CASE_P(Sequence1, MultipleInstantiationTest, Values(1, 2)); +INSTANTIATE_TEST_CASE_P(Sequence2, MultipleInstantiationTest, Range(3, 5)); + +// Tests that a parameterized test case can be instantiated +// in multiple translation units. This test will be instantiated +// here and in gtest-param-test_test2.cc. +// InstantiationInMultipleTranslationUnitsTest fixture class +// is defined in gtest-param-test_test.h. +TEST_P(InstantiationInMultipleTranslaionUnitsTest, IsMultipleOf42) { + EXPECT_EQ(0, GetParam() % 42); +} +INSTANTIATE_TEST_CASE_P(Sequence1, + InstantiationInMultipleTranslaionUnitsTest, + Values(42, 42*2)); + +// Tests that each iteration of parameterized test runs in a separate test +// object. +class SeparateInstanceTest : public TestWithParam { + public: + SeparateInstanceTest() : count_(0) {} + + static void TearDownTestCase() { + EXPECT_GE(global_count_, 2) + << "If some (but not all) SeparateInstanceTest tests have been " + << "filtered out this test will fail. Make sure that all " + << "GeneratorEvaluationTest are selected or de-selected together " + << "by the test filter."; + } + + protected: + int count_; + static int global_count_; +}; +int SeparateInstanceTest::global_count_ = 0; + +TEST_P(SeparateInstanceTest, TestsRunInSeparateInstances) { + EXPECT_EQ(0, count_++); + global_count_++; +} +INSTANTIATE_TEST_CASE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4)); + +// Tests that all instantiations of a test have named appropriately. Test +// defined with TEST_P(TestCaseName, TestName) and instantiated with +// INSTANTIATE_TEST_CASE_P(SequenceName, TestCaseName, generator) must be named +// SequenceName/TestCaseName.TestName/i, where i is the 0-based index of the +// sequence element used to instantiate the test. +class NamingTest : public TestWithParam {}; + +TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name()); + + Message index_stream; + index_stream << "TestsReportCorrectNamesAndParameters/" << GetParam(); + EXPECT_STREQ(index_stream.GetString().c_str(), test_info->name()); + + EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); +} + +INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); + +// Class that cannot be streamed into an ostream. It needs to be copyable +// (and, in case of MSVC, also assignable) in order to be a test parameter +// type. Its default copy constructor and assignment operator do exactly +// what we need. +class Unstreamable { + public: + explicit Unstreamable(int value) : value_(value) {} + + private: + int value_; +}; + +class CommentTest : public TestWithParam {}; + +TEST_P(CommentTest, TestsCorrectlyReportUnstreamableParams) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); +} + +INSTANTIATE_TEST_CASE_P(InstantiationWithComments, + CommentTest, + Values(Unstreamable(1))); + +// Verify that we can create a hierarchy of test fixtures, where the base +// class fixture is not parameterized and the derived class is. In this case +// ParameterizedDerivedTest inherits from NonParameterizedBaseTest. We +// perform simple tests on both. +class NonParameterizedBaseTest : public ::testing::Test { + public: + NonParameterizedBaseTest() : n_(17) { } + protected: + int n_; +}; + +class ParameterizedDerivedTest : public NonParameterizedBaseTest, + public ::testing::WithParamInterface { + protected: + ParameterizedDerivedTest() : count_(0) { } + int count_; + static int global_count_; +}; + +int ParameterizedDerivedTest::global_count_ = 0; + +TEST_F(NonParameterizedBaseTest, FixtureIsInitialized) { + EXPECT_EQ(17, n_); +} + +TEST_P(ParameterizedDerivedTest, SeesSequence) { + EXPECT_EQ(17, n_); + EXPECT_EQ(0, count_++); + EXPECT_EQ(GetParam(), global_count_++); +} + +class ParameterizedDeathTest : public ::testing::TestWithParam { }; + +TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) { + EXPECT_DEATH_IF_SUPPORTED(GetParam(), + ".* value-parameterized test .*"); +} + +INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); + +#endif // GTEST_HAS_PARAM_TEST + +TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) { +#if GTEST_HAS_COMBINE && !GTEST_HAS_PARAM_TEST + FAIL() << "GTEST_HAS_COMBINE is defined while GTEST_HAS_PARAM_TEST is not\n" +#endif +} + +int main(int argc, char **argv) { +#if GTEST_HAS_PARAM_TEST + // Used in TestGenerationTest test case. + AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); + // Used in GeneratorEvaluationTest test case. Tests that the updated value + // will be picked up for instantiating tests in GeneratorEvaluationTest. + GeneratorEvaluationTest::set_param_value(1); +#endif // GTEST_HAS_PARAM_TEST + + ::testing::InitGoogleTest(&argc, argv); + +#if GTEST_HAS_PARAM_TEST + // Used in GeneratorEvaluationTest test case. Tests that value updated + // here will NOT be used for instantiating tests in + // GeneratorEvaluationTest. + GeneratorEvaluationTest::set_param_value(2); +#endif // GTEST_HAS_PARAM_TEST + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-param-test_test.h b/cpp/thirdparty/gtest-1.7.0/test/gtest-param-test_test.h new file mode 100644 index 0000000..26ea122 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-param-test_test.h @@ -0,0 +1,57 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file provides classes and functions used internally +// for testing Google Test itself. + +#ifndef GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ +#define GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ + +#include "gtest/gtest.h" + +#if GTEST_HAS_PARAM_TEST + +// Test fixture for testing definition and instantiation of a test +// in separate translation units. +class ExternalInstantiationTest : public ::testing::TestWithParam { +}; + +// Test fixture for testing instantiation of a test in multiple +// translation units. +class InstantiationInMultipleTranslaionUnitsTest + : public ::testing::TestWithParam { +}; + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-port_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-port_test.cc new file mode 100644 index 0000000..43f1f20 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-port_test.cc @@ -0,0 +1,1253 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: vladl@google.com (Vlad Losev), wan@google.com (Zhanyong Wan) +// +// This file tests the internal cross-platform support utilities. + +#include "gtest/internal/gtest-port.h" + +#include + +#if GTEST_OS_MAC +# include +#endif // GTEST_OS_MAC + +#include +#include // For std::pair and std::make_pair. +#include + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +using std::make_pair; +using std::pair; + +namespace testing { +namespace internal { + +TEST(IsXDigitTest, WorksForNarrowAscii) { + EXPECT_TRUE(IsXDigit('0')); + EXPECT_TRUE(IsXDigit('9')); + EXPECT_TRUE(IsXDigit('A')); + EXPECT_TRUE(IsXDigit('F')); + EXPECT_TRUE(IsXDigit('a')); + EXPECT_TRUE(IsXDigit('f')); + + EXPECT_FALSE(IsXDigit('-')); + EXPECT_FALSE(IsXDigit('g')); + EXPECT_FALSE(IsXDigit('G')); +} + +TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) { + EXPECT_FALSE(IsXDigit(static_cast(0x80))); + EXPECT_FALSE(IsXDigit(static_cast('0' | 0x80))); +} + +TEST(IsXDigitTest, WorksForWideAscii) { + EXPECT_TRUE(IsXDigit(L'0')); + EXPECT_TRUE(IsXDigit(L'9')); + EXPECT_TRUE(IsXDigit(L'A')); + EXPECT_TRUE(IsXDigit(L'F')); + EXPECT_TRUE(IsXDigit(L'a')); + EXPECT_TRUE(IsXDigit(L'f')); + + EXPECT_FALSE(IsXDigit(L'-')); + EXPECT_FALSE(IsXDigit(L'g')); + EXPECT_FALSE(IsXDigit(L'G')); +} + +TEST(IsXDigitTest, ReturnsFalseForWideNonAscii) { + EXPECT_FALSE(IsXDigit(static_cast(0x80))); + EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x80))); + EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x100))); +} + +class Base { + public: + // Copy constructor and assignment operator do exactly what we need, so we + // use them. + Base() : member_(0) {} + explicit Base(int n) : member_(n) {} + virtual ~Base() {} + int member() { return member_; } + + private: + int member_; +}; + +class Derived : public Base { + public: + explicit Derived(int n) : Base(n) {} +}; + +TEST(ImplicitCastTest, ConvertsPointers) { + Derived derived(0); + EXPECT_TRUE(&derived == ::testing::internal::ImplicitCast_(&derived)); +} + +TEST(ImplicitCastTest, CanUseInheritance) { + Derived derived(1); + Base base = ::testing::internal::ImplicitCast_(derived); + EXPECT_EQ(derived.member(), base.member()); +} + +class Castable { + public: + explicit Castable(bool* converted) : converted_(converted) {} + operator Base() { + *converted_ = true; + return Base(); + } + + private: + bool* converted_; +}; + +TEST(ImplicitCastTest, CanUseNonConstCastOperator) { + bool converted = false; + Castable castable(&converted); + Base base = ::testing::internal::ImplicitCast_(castable); + EXPECT_TRUE(converted); +} + +class ConstCastable { + public: + explicit ConstCastable(bool* converted) : converted_(converted) {} + operator Base() const { + *converted_ = true; + return Base(); + } + + private: + bool* converted_; +}; + +TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) { + bool converted = false; + const ConstCastable const_castable(&converted); + Base base = ::testing::internal::ImplicitCast_(const_castable); + EXPECT_TRUE(converted); +} + +class ConstAndNonConstCastable { + public: + ConstAndNonConstCastable(bool* converted, bool* const_converted) + : converted_(converted), const_converted_(const_converted) {} + operator Base() { + *converted_ = true; + return Base(); + } + operator Base() const { + *const_converted_ = true; + return Base(); + } + + private: + bool* converted_; + bool* const_converted_; +}; + +TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) { + bool converted = false; + bool const_converted = false; + ConstAndNonConstCastable castable(&converted, &const_converted); + Base base = ::testing::internal::ImplicitCast_(castable); + EXPECT_TRUE(converted); + EXPECT_FALSE(const_converted); + + converted = false; + const_converted = false; + const ConstAndNonConstCastable const_castable(&converted, &const_converted); + base = ::testing::internal::ImplicitCast_(const_castable); + EXPECT_FALSE(converted); + EXPECT_TRUE(const_converted); +} + +class To { + public: + To(bool* converted) { *converted = true; } // NOLINT +}; + +TEST(ImplicitCastTest, CanUseImplicitConstructor) { + bool converted = false; + To to = ::testing::internal::ImplicitCast_(&converted); + (void)to; + EXPECT_TRUE(converted); +} + +TEST(IteratorTraitsTest, WorksForSTLContainerIterators) { + StaticAssertTypeEq::const_iterator>::value_type>(); + StaticAssertTypeEq::iterator>::value_type>(); +} + +TEST(IteratorTraitsTest, WorksForPointerToNonConst) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); +} + +TEST(IteratorTraitsTest, WorksForPointerToConst) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); +} + +// Tests that the element_type typedef is available in scoped_ptr and refers +// to the parameter type. +TEST(ScopedPtrTest, DefinesElementType) { + StaticAssertTypeEq::element_type>(); +} + +// TODO(vladl@google.com): Implement THE REST of scoped_ptr tests. + +TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { + if (AlwaysFalse()) + GTEST_CHECK_(false) << "This should never be executed; " + "It's a compilation test only."; + + if (AlwaysTrue()) + GTEST_CHECK_(true); + else + ; // NOLINT + + if (AlwaysFalse()) + ; // NOLINT + else + GTEST_CHECK_(true) << ""; +} + +TEST(GtestCheckSyntaxTest, WorksWithSwitch) { + switch (0) { + case 1: + break; + default: + GTEST_CHECK_(true); + } + + switch (0) + case 0: + GTEST_CHECK_(true) << "Check failed in switch case"; +} + +// Verifies behavior of FormatFileLocation. +TEST(FormatFileLocationTest, FormatsFileLocation) { + EXPECT_PRED_FORMAT2(IsSubstring, "foo.cc", FormatFileLocation("foo.cc", 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation("foo.cc", 42)); +} + +TEST(FormatFileLocationTest, FormatsUnknownFile) { + EXPECT_PRED_FORMAT2( + IsSubstring, "unknown file", FormatFileLocation(NULL, 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation(NULL, 42)); +} + +TEST(FormatFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc:", FormatFileLocation("foo.cc", -1)); +} + +TEST(FormatFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file:", FormatFileLocation(NULL, -1)); +} + +// Verifies behavior of FormatCompilerIndependentFileLocation. +TEST(FormatCompilerIndependentFileLocationTest, FormatsFileLocation) { + EXPECT_EQ("foo.cc:42", FormatCompilerIndependentFileLocation("foo.cc", 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFile) { + EXPECT_EQ("unknown file:42", + FormatCompilerIndependentFileLocation(NULL, 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc", FormatCompilerIndependentFileLocation("foo.cc", -1)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1)); +} + +#if GTEST_OS_MAC || GTEST_OS_QNX +void* ThreadFunc(void* data) { + pthread_mutex_t* mutex = static_cast(data); + pthread_mutex_lock(mutex); + pthread_mutex_unlock(mutex); + return NULL; +} + +TEST(GetThreadCountTest, ReturnsCorrectValue) { + EXPECT_EQ(1U, GetThreadCount()); + pthread_mutex_t mutex; + pthread_attr_t attr; + pthread_t thread_id; + + // TODO(vladl@google.com): turn mutex into internal::Mutex for automatic + // destruction. + pthread_mutex_init(&mutex, NULL); + pthread_mutex_lock(&mutex); + ASSERT_EQ(0, pthread_attr_init(&attr)); + ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); + + const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex); + ASSERT_EQ(0, pthread_attr_destroy(&attr)); + ASSERT_EQ(0, status); + EXPECT_EQ(2U, GetThreadCount()); + pthread_mutex_unlock(&mutex); + + void* dummy; + ASSERT_EQ(0, pthread_join(thread_id, &dummy)); + +# if GTEST_OS_MAC + + // MacOS X may not immediately report the updated thread count after + // joining a thread, causing flakiness in this test. To counter that, we + // wait for up to .5 seconds for the OS to report the correct value. + for (int i = 0; i < 5; ++i) { + if (GetThreadCount() == 1) + break; + + SleepMilliseconds(100); + } + +# endif // GTEST_OS_MAC + + EXPECT_EQ(1U, GetThreadCount()); + pthread_mutex_destroy(&mutex); +} +#else +TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { + EXPECT_EQ(0U, GetThreadCount()); +} +#endif // GTEST_OS_MAC || GTEST_OS_QNX + +TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { + const bool a_false_condition = false; + const char regex[] = +#ifdef _MSC_VER + "gtest-port_test\\.cc\\(\\d+\\):" +#elif GTEST_USES_POSIX_RE + "gtest-port_test\\.cc:[0-9]+" +#else + "gtest-port_test\\.cc:\\d+" +#endif // _MSC_VER + ".*a_false_condition.*Extra info.*"; + + EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info", + regex); +} + +#if GTEST_HAS_DEATH_TEST + +TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { + EXPECT_EXIT({ + GTEST_CHECK_(true) << "Extra info"; + ::std::cerr << "Success\n"; + exit(0); }, + ::testing::ExitedWithCode(0), "Success"); +} + +#endif // GTEST_HAS_DEATH_TEST + +// Verifies that Google Test choose regular expression engine appropriate to +// the platform. The test will produce compiler errors in case of failure. +// For simplicity, we only cover the most important platforms here. +TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) { +#if GTEST_HAS_POSIX_RE + + EXPECT_TRUE(GTEST_USES_POSIX_RE); + +#else + + EXPECT_TRUE(GTEST_USES_SIMPLE_RE); + +#endif +} + +#if GTEST_USES_POSIX_RE + +# if GTEST_HAS_TYPED_TEST + +template +class RETest : public ::testing::Test {}; + +// Defines StringTypes as the list of all string types that class RE +// supports. +typedef testing::Types< + ::std::string, +# if GTEST_HAS_GLOBAL_STRING + ::string, +# endif // GTEST_HAS_GLOBAL_STRING + const char*> StringTypes; + +TYPED_TEST_CASE(RETest, StringTypes); + +// Tests RE's implicit constructors. +TYPED_TEST(RETest, ImplicitConstructorWorks) { + const RE empty(TypeParam("")); + EXPECT_STREQ("", empty.pattern()); + + const RE simple(TypeParam("hello")); + EXPECT_STREQ("hello", simple.pattern()); + + const RE normal(TypeParam(".*(\\w+)")); + EXPECT_STREQ(".*(\\w+)", normal.pattern()); +} + +// Tests that RE's constructors reject invalid regular expressions. +TYPED_TEST(RETest, RejectsInvalidRegex) { + EXPECT_NONFATAL_FAILURE({ + const RE invalid(TypeParam("?")); + }, "\"?\" is not a valid POSIX Extended regular expression."); +} + +// Tests RE::FullMatch(). +TYPED_TEST(RETest, FullMatchWorks) { + const RE empty(TypeParam("")); + EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty)); + EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty)); + + const RE re(TypeParam("a.*z")); + EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re)); + EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re)); + EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re)); + EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re)); +} + +// Tests RE::PartialMatch(). +TYPED_TEST(RETest, PartialMatchWorks) { + const RE empty(TypeParam("")); + EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty)); + + const RE re(TypeParam("a.*z")); + EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re)); + EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); +} + +# endif // GTEST_HAS_TYPED_TEST + +#elif GTEST_USES_SIMPLE_RE + +TEST(IsInSetTest, NulCharIsNotInAnySet) { + EXPECT_FALSE(IsInSet('\0', "")); + EXPECT_FALSE(IsInSet('\0', "\0")); + EXPECT_FALSE(IsInSet('\0', "a")); +} + +TEST(IsInSetTest, WorksForNonNulChars) { + EXPECT_FALSE(IsInSet('a', "Ab")); + EXPECT_FALSE(IsInSet('c', "")); + + EXPECT_TRUE(IsInSet('b', "bcd")); + EXPECT_TRUE(IsInSet('b', "ab")); +} + +TEST(IsAsciiDigitTest, IsFalseForNonDigit) { + EXPECT_FALSE(IsAsciiDigit('\0')); + EXPECT_FALSE(IsAsciiDigit(' ')); + EXPECT_FALSE(IsAsciiDigit('+')); + EXPECT_FALSE(IsAsciiDigit('-')); + EXPECT_FALSE(IsAsciiDigit('.')); + EXPECT_FALSE(IsAsciiDigit('a')); +} + +TEST(IsAsciiDigitTest, IsTrueForDigit) { + EXPECT_TRUE(IsAsciiDigit('0')); + EXPECT_TRUE(IsAsciiDigit('1')); + EXPECT_TRUE(IsAsciiDigit('5')); + EXPECT_TRUE(IsAsciiDigit('9')); +} + +TEST(IsAsciiPunctTest, IsFalseForNonPunct) { + EXPECT_FALSE(IsAsciiPunct('\0')); + EXPECT_FALSE(IsAsciiPunct(' ')); + EXPECT_FALSE(IsAsciiPunct('\n')); + EXPECT_FALSE(IsAsciiPunct('a')); + EXPECT_FALSE(IsAsciiPunct('0')); +} + +TEST(IsAsciiPunctTest, IsTrueForPunct) { + for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) { + EXPECT_PRED1(IsAsciiPunct, *p); + } +} + +TEST(IsRepeatTest, IsFalseForNonRepeatChar) { + EXPECT_FALSE(IsRepeat('\0')); + EXPECT_FALSE(IsRepeat(' ')); + EXPECT_FALSE(IsRepeat('a')); + EXPECT_FALSE(IsRepeat('1')); + EXPECT_FALSE(IsRepeat('-')); +} + +TEST(IsRepeatTest, IsTrueForRepeatChar) { + EXPECT_TRUE(IsRepeat('?')); + EXPECT_TRUE(IsRepeat('*')); + EXPECT_TRUE(IsRepeat('+')); +} + +TEST(IsAsciiWhiteSpaceTest, IsFalseForNonWhiteSpace) { + EXPECT_FALSE(IsAsciiWhiteSpace('\0')); + EXPECT_FALSE(IsAsciiWhiteSpace('a')); + EXPECT_FALSE(IsAsciiWhiteSpace('1')); + EXPECT_FALSE(IsAsciiWhiteSpace('+')); + EXPECT_FALSE(IsAsciiWhiteSpace('_')); +} + +TEST(IsAsciiWhiteSpaceTest, IsTrueForWhiteSpace) { + EXPECT_TRUE(IsAsciiWhiteSpace(' ')); + EXPECT_TRUE(IsAsciiWhiteSpace('\n')); + EXPECT_TRUE(IsAsciiWhiteSpace('\r')); + EXPECT_TRUE(IsAsciiWhiteSpace('\t')); + EXPECT_TRUE(IsAsciiWhiteSpace('\v')); + EXPECT_TRUE(IsAsciiWhiteSpace('\f')); +} + +TEST(IsAsciiWordCharTest, IsFalseForNonWordChar) { + EXPECT_FALSE(IsAsciiWordChar('\0')); + EXPECT_FALSE(IsAsciiWordChar('+')); + EXPECT_FALSE(IsAsciiWordChar('.')); + EXPECT_FALSE(IsAsciiWordChar(' ')); + EXPECT_FALSE(IsAsciiWordChar('\n')); +} + +TEST(IsAsciiWordCharTest, IsTrueForLetter) { + EXPECT_TRUE(IsAsciiWordChar('a')); + EXPECT_TRUE(IsAsciiWordChar('b')); + EXPECT_TRUE(IsAsciiWordChar('A')); + EXPECT_TRUE(IsAsciiWordChar('Z')); +} + +TEST(IsAsciiWordCharTest, IsTrueForDigit) { + EXPECT_TRUE(IsAsciiWordChar('0')); + EXPECT_TRUE(IsAsciiWordChar('1')); + EXPECT_TRUE(IsAsciiWordChar('7')); + EXPECT_TRUE(IsAsciiWordChar('9')); +} + +TEST(IsAsciiWordCharTest, IsTrueForUnderscore) { + EXPECT_TRUE(IsAsciiWordChar('_')); +} + +TEST(IsValidEscapeTest, IsFalseForNonPrintable) { + EXPECT_FALSE(IsValidEscape('\0')); + EXPECT_FALSE(IsValidEscape('\007')); +} + +TEST(IsValidEscapeTest, IsFalseForDigit) { + EXPECT_FALSE(IsValidEscape('0')); + EXPECT_FALSE(IsValidEscape('9')); +} + +TEST(IsValidEscapeTest, IsFalseForWhiteSpace) { + EXPECT_FALSE(IsValidEscape(' ')); + EXPECT_FALSE(IsValidEscape('\n')); +} + +TEST(IsValidEscapeTest, IsFalseForSomeLetter) { + EXPECT_FALSE(IsValidEscape('a')); + EXPECT_FALSE(IsValidEscape('Z')); +} + +TEST(IsValidEscapeTest, IsTrueForPunct) { + EXPECT_TRUE(IsValidEscape('.')); + EXPECT_TRUE(IsValidEscape('-')); + EXPECT_TRUE(IsValidEscape('^')); + EXPECT_TRUE(IsValidEscape('$')); + EXPECT_TRUE(IsValidEscape('(')); + EXPECT_TRUE(IsValidEscape(']')); + EXPECT_TRUE(IsValidEscape('{')); + EXPECT_TRUE(IsValidEscape('|')); +} + +TEST(IsValidEscapeTest, IsTrueForSomeLetter) { + EXPECT_TRUE(IsValidEscape('d')); + EXPECT_TRUE(IsValidEscape('D')); + EXPECT_TRUE(IsValidEscape('s')); + EXPECT_TRUE(IsValidEscape('S')); + EXPECT_TRUE(IsValidEscape('w')); + EXPECT_TRUE(IsValidEscape('W')); +} + +TEST(AtomMatchesCharTest, EscapedPunct) { + EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, '\\', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, '_', '.')); + EXPECT_FALSE(AtomMatchesChar(true, '.', 'a')); + + EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\')); + EXPECT_TRUE(AtomMatchesChar(true, '_', '_')); + EXPECT_TRUE(AtomMatchesChar(true, '+', '+')); + EXPECT_TRUE(AtomMatchesChar(true, '.', '.')); +} + +TEST(AtomMatchesCharTest, Escaped_d) { + EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 'd', '.')); + + EXPECT_TRUE(AtomMatchesChar(true, 'd', '0')); + EXPECT_TRUE(AtomMatchesChar(true, 'd', '9')); +} + +TEST(AtomMatchesCharTest, Escaped_D) { + EXPECT_FALSE(AtomMatchesChar(true, 'D', '0')); + EXPECT_FALSE(AtomMatchesChar(true, 'D', '9')); + + EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a')); + EXPECT_TRUE(AtomMatchesChar(true, 'D', '-')); +} + +TEST(AtomMatchesCharTest, Escaped_s) { + EXPECT_FALSE(AtomMatchesChar(true, 's', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 's', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 's', '.')); + EXPECT_FALSE(AtomMatchesChar(true, 's', '9')); + + EXPECT_TRUE(AtomMatchesChar(true, 's', ' ')); + EXPECT_TRUE(AtomMatchesChar(true, 's', '\n')); + EXPECT_TRUE(AtomMatchesChar(true, 's', '\t')); +} + +TEST(AtomMatchesCharTest, Escaped_S) { + EXPECT_FALSE(AtomMatchesChar(true, 'S', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r')); + + EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a')); + EXPECT_TRUE(AtomMatchesChar(true, 'S', '9')); +} + +TEST(AtomMatchesCharTest, Escaped_w) { + EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', '+')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n')); + + EXPECT_TRUE(AtomMatchesChar(true, 'w', '0')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', '_')); +} + +TEST(AtomMatchesCharTest, Escaped_W) { + EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', '9')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', '_')); + + EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'W', '*')); + EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n')); +} + +TEST(AtomMatchesCharTest, EscapedWhiteSpace) { + EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n')); + EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r')); + EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 't', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 't', 't')); + EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f')); + + EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f')); + EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n')); + EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r')); + EXPECT_TRUE(AtomMatchesChar(true, 't', '\t')); + EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v')); +} + +TEST(AtomMatchesCharTest, UnescapedDot) { + EXPECT_FALSE(AtomMatchesChar(false, '.', '\n')); + + EXPECT_TRUE(AtomMatchesChar(false, '.', '\0')); + EXPECT_TRUE(AtomMatchesChar(false, '.', '.')); + EXPECT_TRUE(AtomMatchesChar(false, '.', 'a')); + EXPECT_TRUE(AtomMatchesChar(false, '.', ' ')); +} + +TEST(AtomMatchesCharTest, UnescapedChar) { + EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0')); + EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b')); + EXPECT_FALSE(AtomMatchesChar(false, '$', 'a')); + + EXPECT_TRUE(AtomMatchesChar(false, '$', '$')); + EXPECT_TRUE(AtomMatchesChar(false, '5', '5')); + EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z')); +} + +TEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) { + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)), + "NULL is not a valid simple regular expression"); + EXPECT_NONFATAL_FAILURE( + ASSERT_FALSE(ValidateRegex("a\\")), + "Syntax error at index 1 in simple regular expression \"a\\\": "); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")), + "'\\' cannot appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")), + "'\\' cannot appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")), + "invalid escape sequence \"\\h\""); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")), + "'^' can only appear at the beginning"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")), + "'^' can only appear at the beginning"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")), + "'$' can only appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")), + "'$' can only appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")), + "'(' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")), + "')' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")), + "'[' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")), + "'{' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")), + "'?' can only follow a repeatable token"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")), + "'*' can only follow a repeatable token"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")), + "'+' can only follow a repeatable token"); +} + +TEST(ValidateRegexTest, ReturnsTrueForValid) { + EXPECT_TRUE(ValidateRegex("")); + EXPECT_TRUE(ValidateRegex("a")); + EXPECT_TRUE(ValidateRegex(".*")); + EXPECT_TRUE(ValidateRegex("^a_+")); + EXPECT_TRUE(ValidateRegex("^a\\t\\&?")); + EXPECT_TRUE(ValidateRegex("09*$")); + EXPECT_TRUE(ValidateRegex("^Z$")); + EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba")); + // Repeating more than once. + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab")); + + // Repeating zero times. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba")); + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab")); + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab")); + + // Repeating zero times. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc")); + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc")); + // Repeating more than once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab")); + // Repeating zero times. + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc")); + + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc")); + // Repeating more than once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g")); +} + +TEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) { + EXPECT_TRUE(MatchRegexAtHead("", "")); + EXPECT_TRUE(MatchRegexAtHead("", "ab")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) { + EXPECT_FALSE(MatchRegexAtHead("$", "a")); + + EXPECT_TRUE(MatchRegexAtHead("$", "")); + EXPECT_TRUE(MatchRegexAtHead("a$", "a")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) { + EXPECT_FALSE(MatchRegexAtHead("\\w", "+")); + EXPECT_FALSE(MatchRegexAtHead("\\W", "ab")); + + EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab")); + EXPECT_TRUE(MatchRegexAtHead("\\d", "1a")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) { + EXPECT_FALSE(MatchRegexAtHead(".+a", "abc")); + EXPECT_FALSE(MatchRegexAtHead("a?b", "aab")); + + EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab")); + EXPECT_TRUE(MatchRegexAtHead("a?b", "b")); + EXPECT_TRUE(MatchRegexAtHead("a?b", "ab")); +} + +TEST(MatchRegexAtHeadTest, + WorksWhenRegexStartsWithRepetionOfEscapeSequence) { + EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc")); + EXPECT_FALSE(MatchRegexAtHead("\\s?b", " b")); + + EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab")); + EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b")); + EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b")); + EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b")); +} + +TEST(MatchRegexAtHeadTest, MatchesSequentially) { + EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc")); + + EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc")); +} + +TEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) { + EXPECT_FALSE(MatchRegexAnywhere("", NULL)); +} + +TEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) { + EXPECT_FALSE(MatchRegexAnywhere("^a", "ba")); + EXPECT_FALSE(MatchRegexAnywhere("^$", "a")); + + EXPECT_TRUE(MatchRegexAnywhere("^a", "ab")); + EXPECT_TRUE(MatchRegexAnywhere("^", "ab")); + EXPECT_TRUE(MatchRegexAnywhere("^$", "")); +} + +TEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) { + EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123")); + EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888")); +} + +TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) { + EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5")); + EXPECT_TRUE(MatchRegexAnywhere(".*=", "=")); + EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc")); +} + +TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) { + EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5")); + EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "= ...=")); +} + +// Tests RE's implicit constructors. +TEST(RETest, ImplicitConstructorWorks) { + const RE empty(""); + EXPECT_STREQ("", empty.pattern()); + + const RE simple("hello"); + EXPECT_STREQ("hello", simple.pattern()); +} + +// Tests that RE's constructors reject invalid regular expressions. +TEST(RETest, RejectsInvalidRegex) { + EXPECT_NONFATAL_FAILURE({ + const RE normal(NULL); + }, "NULL is not a valid simple regular expression"); + + EXPECT_NONFATAL_FAILURE({ + const RE normal(".*(\\w+"); + }, "'(' is unsupported"); + + EXPECT_NONFATAL_FAILURE({ + const RE invalid("^?"); + }, "'?' can only follow a repeatable token"); +} + +// Tests RE::FullMatch(). +TEST(RETest, FullMatchWorks) { + const RE empty(""); + EXPECT_TRUE(RE::FullMatch("", empty)); + EXPECT_FALSE(RE::FullMatch("a", empty)); + + const RE re1("a"); + EXPECT_TRUE(RE::FullMatch("a", re1)); + + const RE re("a.*z"); + EXPECT_TRUE(RE::FullMatch("az", re)); + EXPECT_TRUE(RE::FullMatch("axyz", re)); + EXPECT_FALSE(RE::FullMatch("baz", re)); + EXPECT_FALSE(RE::FullMatch("azy", re)); +} + +// Tests RE::PartialMatch(). +TEST(RETest, PartialMatchWorks) { + const RE empty(""); + EXPECT_TRUE(RE::PartialMatch("", empty)); + EXPECT_TRUE(RE::PartialMatch("a", empty)); + + const RE re("a.*z"); + EXPECT_TRUE(RE::PartialMatch("az", re)); + EXPECT_TRUE(RE::PartialMatch("axyz", re)); + EXPECT_TRUE(RE::PartialMatch("baz", re)); + EXPECT_TRUE(RE::PartialMatch("azy", re)); + EXPECT_FALSE(RE::PartialMatch("zza", re)); +} + +#endif // GTEST_USES_POSIX_RE + +#if !GTEST_OS_WINDOWS_MOBILE + +TEST(CaptureTest, CapturesStdout) { + CaptureStdout(); + fprintf(stdout, "abc"); + EXPECT_STREQ("abc", GetCapturedStdout().c_str()); + + CaptureStdout(); + fprintf(stdout, "def%cghi", '\0'); + EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout())); +} + +TEST(CaptureTest, CapturesStderr) { + CaptureStderr(); + fprintf(stderr, "jkl"); + EXPECT_STREQ("jkl", GetCapturedStderr().c_str()); + + CaptureStderr(); + fprintf(stderr, "jkl%cmno", '\0'); + EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr())); +} + +// Tests that stdout and stderr capture don't interfere with each other. +TEST(CaptureTest, CapturesStdoutAndStderr) { + CaptureStdout(); + CaptureStderr(); + fprintf(stdout, "pqr"); + fprintf(stderr, "stu"); + EXPECT_STREQ("pqr", GetCapturedStdout().c_str()); + EXPECT_STREQ("stu", GetCapturedStderr().c_str()); +} + +TEST(CaptureDeathTest, CannotReenterStdoutCapture) { + CaptureStdout(); + EXPECT_DEATH_IF_SUPPORTED(CaptureStdout(), + "Only one stdout capturer can exist at a time"); + GetCapturedStdout(); + + // We cannot test stderr capturing using death tests as they use it + // themselves. +} + +#endif // !GTEST_OS_WINDOWS_MOBILE + +TEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) { + ThreadLocal t1; + EXPECT_EQ(0, t1.get()); + + ThreadLocal t2; + EXPECT_TRUE(t2.get() == NULL); +} + +TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) { + ThreadLocal t1(123); + EXPECT_EQ(123, t1.get()); + + int i = 0; + ThreadLocal t2(&i); + EXPECT_EQ(&i, t2.get()); +} + +class NoDefaultContructor { + public: + explicit NoDefaultContructor(const char*) {} + NoDefaultContructor(const NoDefaultContructor&) {} +}; + +TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) { + ThreadLocal bar(NoDefaultContructor("foo")); + bar.pointer(); +} + +TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { + ThreadLocal thread_local_string; + + EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); + + // Verifies the condition still holds after calling set. + thread_local_string.set("foo"); + EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); +} + +TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { + ThreadLocal thread_local_string; + const ThreadLocal& const_thread_local_string = + thread_local_string; + + EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); + + thread_local_string.set("foo"); + EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); +} + +#if GTEST_IS_THREADSAFE + +void AddTwo(int* param) { *param += 2; } + +TEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) { + int i = 40; + ThreadWithParam thread(&AddTwo, &i, NULL); + thread.Join(); + EXPECT_EQ(42, i); +} + +TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { + // AssertHeld() is flaky only in the presence of multiple threads accessing + // the lock. In this case, the test is robust. + EXPECT_DEATH_IF_SUPPORTED({ + Mutex m; + { MutexLock lock(&m); } + m.AssertHeld(); + }, + "thread .*hold"); +} + +TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) { + Mutex m; + MutexLock lock(&m); + m.AssertHeld(); +} + +class AtomicCounterWithMutex { + public: + explicit AtomicCounterWithMutex(Mutex* mutex) : + value_(0), mutex_(mutex), random_(42) {} + + void Increment() { + MutexLock lock(mutex_); + int temp = value_; + { + // Locking a mutex puts up a memory barrier, preventing reads and + // writes to value_ rearranged when observed from other threads. + // + // We cannot use Mutex and MutexLock here or rely on their memory + // barrier functionality as we are testing them here. + pthread_mutex_t memory_barrier_mutex; + GTEST_CHECK_POSIX_SUCCESS_( + pthread_mutex_init(&memory_barrier_mutex, NULL)); + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex)); + + SleepMilliseconds(random_.Generate(30)); + + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex)); + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex)); + } + value_ = temp + 1; + } + int value() const { return value_; } + + private: + volatile int value_; + Mutex* const mutex_; // Protects value_. + Random random_; +}; + +void CountingThreadFunc(pair param) { + for (int i = 0; i < param.second; ++i) + param.first->Increment(); +} + +// Tests that the mutex only lets one thread at a time to lock it. +TEST(MutexTest, OnlyOneThreadCanLockAtATime) { + Mutex mutex; + AtomicCounterWithMutex locked_counter(&mutex); + + typedef ThreadWithParam > ThreadType; + const int kCycleCount = 20; + const int kThreadCount = 7; + scoped_ptr counting_threads[kThreadCount]; + Notification threads_can_start; + // Creates and runs kThreadCount threads that increment locked_counter + // kCycleCount times each. + for (int i = 0; i < kThreadCount; ++i) { + counting_threads[i].reset(new ThreadType(&CountingThreadFunc, + make_pair(&locked_counter, + kCycleCount), + &threads_can_start)); + } + threads_can_start.Notify(); + for (int i = 0; i < kThreadCount; ++i) + counting_threads[i]->Join(); + + // If the mutex lets more than one thread to increment the counter at a + // time, they are likely to encounter a race condition and have some + // increments overwritten, resulting in the lower then expected counter + // value. + EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value()); +} + +template +void RunFromThread(void (func)(T), T param) { + ThreadWithParam thread(func, param, NULL); + thread.Join(); +} + +void RetrieveThreadLocalValue( + pair*, std::string*> param) { + *param.second = param.first->get(); +} + +TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { + ThreadLocal thread_local_string("foo"); + EXPECT_STREQ("foo", thread_local_string.get().c_str()); + + thread_local_string.set("bar"); + EXPECT_STREQ("bar", thread_local_string.get().c_str()); + + std::string result; + RunFromThread(&RetrieveThreadLocalValue, + make_pair(&thread_local_string, &result)); + EXPECT_STREQ("foo", result.c_str()); +} + +// DestructorTracker keeps track of whether its instances have been +// destroyed. +static std::vector g_destroyed; + +class DestructorTracker { + public: + DestructorTracker() : index_(GetNewIndex()) {} + DestructorTracker(const DestructorTracker& /* rhs */) + : index_(GetNewIndex()) {} + ~DestructorTracker() { + // We never access g_destroyed concurrently, so we don't need to + // protect the write operation under a mutex. + g_destroyed[index_] = true; + } + + private: + static int GetNewIndex() { + g_destroyed.push_back(false); + return g_destroyed.size() - 1; + } + const int index_; +}; + +typedef ThreadLocal* ThreadParam; + +void CallThreadLocalGet(ThreadParam thread_local_param) { + thread_local_param->get(); +} + +// Tests that when a ThreadLocal object dies in a thread, it destroys +// the managed object for that thread. +TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) { + g_destroyed.clear(); + + { + // The next line default constructs a DestructorTracker object as + // the default value of objects managed by thread_local_tracker. + ThreadLocal thread_local_tracker; + ASSERT_EQ(1U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + + // This creates another DestructorTracker object for the main thread. + thread_local_tracker.get(); + ASSERT_EQ(2U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + ASSERT_FALSE(g_destroyed[1]); + } + + // Now thread_local_tracker has died. It should have destroyed both the + // default value shared by all threads and the value for the main + // thread. + ASSERT_EQ(2U, g_destroyed.size()); + EXPECT_TRUE(g_destroyed[0]); + EXPECT_TRUE(g_destroyed[1]); + + g_destroyed.clear(); +} + +// Tests that when a thread exits, the thread-local object for that +// thread is destroyed. +TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { + g_destroyed.clear(); + + { + // The next line default constructs a DestructorTracker object as + // the default value of objects managed by thread_local_tracker. + ThreadLocal thread_local_tracker; + ASSERT_EQ(1U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + + // This creates another DestructorTracker object in the new thread. + ThreadWithParam thread( + &CallThreadLocalGet, &thread_local_tracker, NULL); + thread.Join(); + + // Now the new thread has exited. The per-thread object for it + // should have been destroyed. + ASSERT_EQ(2U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + ASSERT_TRUE(g_destroyed[1]); + } + + // Now thread_local_tracker has died. The default value should have been + // destroyed too. + ASSERT_EQ(2U, g_destroyed.size()); + EXPECT_TRUE(g_destroyed[0]); + EXPECT_TRUE(g_destroyed[1]); + + g_destroyed.clear(); +} + +TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { + ThreadLocal thread_local_string; + thread_local_string.set("Foo"); + EXPECT_STREQ("Foo", thread_local_string.get().c_str()); + + std::string result; + RunFromThread(&RetrieveThreadLocalValue, + make_pair(&thread_local_string, &result)); + EXPECT_TRUE(result.empty()); +} + +#endif // GTEST_IS_THREADSAFE + +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-printers_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-printers_test.cc new file mode 100644 index 0000000..c2beca7 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-printers_test.cc @@ -0,0 +1,1566 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file tests the universal value printer. + +#include "gtest/gtest-printers.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" + +// hash_map and hash_set are available under Visual C++. +#if _MSC_VER +# define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available. +# include // NOLINT +# define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available. +# include // NOLINT +#endif // GTEST_OS_WINDOWS + +// Some user-defined types for testing the universal value printer. + +// An anonymous enum type. +enum AnonymousEnum { + kAE1 = -1, + kAE2 = 1 +}; + +// An enum without a user-defined printer. +enum EnumWithoutPrinter { + kEWP1 = -2, + kEWP2 = 42 +}; + +// An enum with a << operator. +enum EnumWithStreaming { + kEWS1 = 10 +}; + +std::ostream& operator<<(std::ostream& os, EnumWithStreaming e) { + return os << (e == kEWS1 ? "kEWS1" : "invalid"); +} + +// An enum with a PrintTo() function. +enum EnumWithPrintTo { + kEWPT1 = 1 +}; + +void PrintTo(EnumWithPrintTo e, std::ostream* os) { + *os << (e == kEWPT1 ? "kEWPT1" : "invalid"); +} + +// A class implicitly convertible to BiggestInt. +class BiggestIntConvertible { + public: + operator ::testing::internal::BiggestInt() const { return 42; } +}; + +// A user-defined unprintable class template in the global namespace. +template +class UnprintableTemplateInGlobal { + public: + UnprintableTemplateInGlobal() : value_() {} + private: + T value_; +}; + +// A user-defined streamable type in the global namespace. +class StreamableInGlobal { + public: + virtual ~StreamableInGlobal() {} +}; + +inline void operator<<(::std::ostream& os, const StreamableInGlobal& /* x */) { + os << "StreamableInGlobal"; +} + +void operator<<(::std::ostream& os, const StreamableInGlobal* /* x */) { + os << "StreamableInGlobal*"; +} + +namespace foo { + +// A user-defined unprintable type in a user namespace. +class UnprintableInFoo { + public: + UnprintableInFoo() : z_(0) { memcpy(xy_, "\xEF\x12\x0\x0\x34\xAB\x0\x0", 8); } + private: + char xy_[8]; + double z_; +}; + +// A user-defined printable type in a user-chosen namespace. +struct PrintableViaPrintTo { + PrintableViaPrintTo() : value() {} + int value; +}; + +void PrintTo(const PrintableViaPrintTo& x, ::std::ostream* os) { + *os << "PrintableViaPrintTo: " << x.value; +} + +// A type with a user-defined << for printing its pointer. +struct PointerPrintable { +}; + +::std::ostream& operator<<(::std::ostream& os, + const PointerPrintable* /* x */) { + return os << "PointerPrintable*"; +} + +// A user-defined printable class template in a user-chosen namespace. +template +class PrintableViaPrintToTemplate { + public: + explicit PrintableViaPrintToTemplate(const T& a_value) : value_(a_value) {} + + const T& value() const { return value_; } + private: + T value_; +}; + +template +void PrintTo(const PrintableViaPrintToTemplate& x, ::std::ostream* os) { + *os << "PrintableViaPrintToTemplate: " << x.value(); +} + +// A user-defined streamable class template in a user namespace. +template +class StreamableTemplateInFoo { + public: + StreamableTemplateInFoo() : value_() {} + + const T& value() const { return value_; } + private: + T value_; +}; + +template +inline ::std::ostream& operator<<(::std::ostream& os, + const StreamableTemplateInFoo& x) { + return os << "StreamableTemplateInFoo: " << x.value(); +} + +} // namespace foo + +namespace testing { +namespace gtest_printers_test { + +using ::std::deque; +using ::std::list; +using ::std::make_pair; +using ::std::map; +using ::std::multimap; +using ::std::multiset; +using ::std::pair; +using ::std::set; +using ::std::vector; +using ::testing::PrintToString; +using ::testing::internal::FormatForComparisonFailureMessage; +using ::testing::internal::ImplicitCast_; +using ::testing::internal::NativeArray; +using ::testing::internal::RE; +using ::testing::internal::Strings; +using ::testing::internal::UniversalPrint; +using ::testing::internal::UniversalPrinter; +using ::testing::internal::UniversalTersePrint; +using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; +using ::testing::internal::kReference; +using ::testing::internal::string; + +#if GTEST_HAS_TR1_TUPLE +using ::std::tr1::make_tuple; +using ::std::tr1::tuple; +#endif + +// The hash_* classes are not part of the C++ standard. STLport +// defines them in namespace std. MSVC defines them in ::stdext. GCC +// defines them in ::. +#ifdef _STLP_HASH_MAP // We got from STLport. +using ::std::hash_map; +using ::std::hash_set; +using ::std::hash_multimap; +using ::std::hash_multiset; +#elif _MSC_VER +using ::stdext::hash_map; +using ::stdext::hash_set; +using ::stdext::hash_multimap; +using ::stdext::hash_multiset; +#endif + +// Prints a value to a string using the universal value printer. This +// is a helper for testing UniversalPrinter::Print() for various types. +template +string Print(const T& value) { + ::std::stringstream ss; + UniversalPrinter::Print(value, &ss); + return ss.str(); +} + +// Prints a value passed by reference to a string, using the universal +// value printer. This is a helper for testing +// UniversalPrinter::Print() for various types. +template +string PrintByRef(const T& value) { + ::std::stringstream ss; + UniversalPrinter::Print(value, &ss); + return ss.str(); +} + +// Tests printing various enum types. + +TEST(PrintEnumTest, AnonymousEnum) { + EXPECT_EQ("-1", Print(kAE1)); + EXPECT_EQ("1", Print(kAE2)); +} + +TEST(PrintEnumTest, EnumWithoutPrinter) { + EXPECT_EQ("-2", Print(kEWP1)); + EXPECT_EQ("42", Print(kEWP2)); +} + +TEST(PrintEnumTest, EnumWithStreaming) { + EXPECT_EQ("kEWS1", Print(kEWS1)); + EXPECT_EQ("invalid", Print(static_cast(0))); +} + +TEST(PrintEnumTest, EnumWithPrintTo) { + EXPECT_EQ("kEWPT1", Print(kEWPT1)); + EXPECT_EQ("invalid", Print(static_cast(0))); +} + +// Tests printing a class implicitly convertible to BiggestInt. + +TEST(PrintClassTest, BiggestIntConvertible) { + EXPECT_EQ("42", Print(BiggestIntConvertible())); +} + +// Tests printing various char types. + +// char. +TEST(PrintCharTest, PlainChar) { + EXPECT_EQ("'\\0'", Print('\0')); + EXPECT_EQ("'\\'' (39, 0x27)", Print('\'')); + EXPECT_EQ("'\"' (34, 0x22)", Print('"')); + EXPECT_EQ("'?' (63, 0x3F)", Print('?')); + EXPECT_EQ("'\\\\' (92, 0x5C)", Print('\\')); + EXPECT_EQ("'\\a' (7)", Print('\a')); + EXPECT_EQ("'\\b' (8)", Print('\b')); + EXPECT_EQ("'\\f' (12, 0xC)", Print('\f')); + EXPECT_EQ("'\\n' (10, 0xA)", Print('\n')); + EXPECT_EQ("'\\r' (13, 0xD)", Print('\r')); + EXPECT_EQ("'\\t' (9)", Print('\t')); + EXPECT_EQ("'\\v' (11, 0xB)", Print('\v')); + EXPECT_EQ("'\\x7F' (127)", Print('\x7F')); + EXPECT_EQ("'\\xFF' (255)", Print('\xFF')); + EXPECT_EQ("' ' (32, 0x20)", Print(' ')); + EXPECT_EQ("'a' (97, 0x61)", Print('a')); +} + +// signed char. +TEST(PrintCharTest, SignedChar) { + EXPECT_EQ("'\\0'", Print(static_cast('\0'))); + EXPECT_EQ("'\\xCE' (-50)", + Print(static_cast(-50))); +} + +// unsigned char. +TEST(PrintCharTest, UnsignedChar) { + EXPECT_EQ("'\\0'", Print(static_cast('\0'))); + EXPECT_EQ("'b' (98, 0x62)", + Print(static_cast('b'))); +} + +// Tests printing other simple, built-in types. + +// bool. +TEST(PrintBuiltInTypeTest, Bool) { + EXPECT_EQ("false", Print(false)); + EXPECT_EQ("true", Print(true)); +} + +// wchar_t. +TEST(PrintBuiltInTypeTest, Wchar_t) { + EXPECT_EQ("L'\\0'", Print(L'\0')); + EXPECT_EQ("L'\\'' (39, 0x27)", Print(L'\'')); + EXPECT_EQ("L'\"' (34, 0x22)", Print(L'"')); + EXPECT_EQ("L'?' (63, 0x3F)", Print(L'?')); + EXPECT_EQ("L'\\\\' (92, 0x5C)", Print(L'\\')); + EXPECT_EQ("L'\\a' (7)", Print(L'\a')); + EXPECT_EQ("L'\\b' (8)", Print(L'\b')); + EXPECT_EQ("L'\\f' (12, 0xC)", Print(L'\f')); + EXPECT_EQ("L'\\n' (10, 0xA)", Print(L'\n')); + EXPECT_EQ("L'\\r' (13, 0xD)", Print(L'\r')); + EXPECT_EQ("L'\\t' (9)", Print(L'\t')); + EXPECT_EQ("L'\\v' (11, 0xB)", Print(L'\v')); + EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F')); + EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); + EXPECT_EQ("L' ' (32, 0x20)", Print(L' ')); + EXPECT_EQ("L'a' (97, 0x61)", Print(L'a')); + EXPECT_EQ("L'\\x576' (1398)", Print(static_cast(0x576))); + EXPECT_EQ("L'\\xC74D' (51021)", Print(static_cast(0xC74D))); +} + +// Test that Int64 provides more storage than wchar_t. +TEST(PrintTypeSizeTest, Wchar_t) { + EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64)); +} + +// Various integer types. +TEST(PrintBuiltInTypeTest, Integer) { + EXPECT_EQ("'\\xFF' (255)", Print(static_cast(255))); // uint8 + EXPECT_EQ("'\\x80' (-128)", Print(static_cast(-128))); // int8 + EXPECT_EQ("65535", Print(USHRT_MAX)); // uint16 + EXPECT_EQ("-32768", Print(SHRT_MIN)); // int16 + EXPECT_EQ("4294967295", Print(UINT_MAX)); // uint32 + EXPECT_EQ("-2147483648", Print(INT_MIN)); // int32 + EXPECT_EQ("18446744073709551615", + Print(static_cast(-1))); // uint64 + EXPECT_EQ("-9223372036854775808", + Print(static_cast(1) << 63)); // int64 +} + +// Size types. +TEST(PrintBuiltInTypeTest, Size_t) { + EXPECT_EQ("1", Print(sizeof('a'))); // size_t. +#if !GTEST_OS_WINDOWS + // Windows has no ssize_t type. + EXPECT_EQ("-2", Print(static_cast(-2))); // ssize_t. +#endif // !GTEST_OS_WINDOWS +} + +// Floating-points. +TEST(PrintBuiltInTypeTest, FloatingPoints) { + EXPECT_EQ("1.5", Print(1.5f)); // float + EXPECT_EQ("-2.5", Print(-2.5)); // double +} + +// Since ::std::stringstream::operator<<(const void *) formats the pointer +// output differently with different compilers, we have to create the expected +// output first and use it as our expectation. +static string PrintPointer(const void *p) { + ::std::stringstream expected_result_stream; + expected_result_stream << p; + return expected_result_stream.str(); +} + +// Tests printing C strings. + +// const char*. +TEST(PrintCStringTest, Const) { + const char* p = "World"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"World\"", Print(p)); +} + +// char*. +TEST(PrintCStringTest, NonConst) { + char p[] = "Hi"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"Hi\"", + Print(static_cast(p))); +} + +// NULL C string. +TEST(PrintCStringTest, Null) { + const char* p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that C strings are escaped properly. +TEST(PrintCStringTest, EscapesProperly) { + const char* p = "'\"?\\\a\b\f\n\r\t\v\x7F\xFF a"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"?\\\\\\a\\b\\f" + "\\n\\r\\t\\v\\x7F\\xFF a\"", + Print(p)); +} + + + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) + +// const wchar_t*. +TEST(PrintWideCStringTest, Const) { + const wchar_t* p = L"World"; + EXPECT_EQ(PrintPointer(p) + " pointing to L\"World\"", Print(p)); +} + +// wchar_t*. +TEST(PrintWideCStringTest, NonConst) { + wchar_t p[] = L"Hi"; + EXPECT_EQ(PrintPointer(p) + " pointing to L\"Hi\"", + Print(static_cast(p))); +} + +// NULL wide C string. +TEST(PrintWideCStringTest, Null) { + const wchar_t* p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that wide C strings are escaped properly. +TEST(PrintWideCStringTest, EscapesProperly) { + const wchar_t s[] = {'\'', '"', '?', '\\', '\a', '\b', '\f', '\n', '\r', + '\t', '\v', 0xD3, 0x576, 0x8D3, 0xC74D, ' ', 'a', '\0'}; + EXPECT_EQ(PrintPointer(s) + " pointing to L\"'\\\"?\\\\\\a\\b\\f" + "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", + Print(static_cast(s))); +} +#endif // native wchar_t + +// Tests printing pointers to other char types. + +// signed char*. +TEST(PrintCharPointerTest, SignedChar) { + signed char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const signed char*. +TEST(PrintCharPointerTest, ConstSignedChar) { + signed char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// unsigned char*. +TEST(PrintCharPointerTest, UnsignedChar) { + unsigned char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const unsigned char*. +TEST(PrintCharPointerTest, ConstUnsignedChar) { + const unsigned char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to simple, built-in types. + +// bool*. +TEST(PrintPointerToBuiltInTypeTest, Bool) { + bool* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// void*. +TEST(PrintPointerToBuiltInTypeTest, Void) { + void* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const void*. +TEST(PrintPointerToBuiltInTypeTest, ConstVoid) { + const void* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to pointers. +TEST(PrintPointerToPointerTest, IntPointerPointer) { + int** p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing (non-member) function pointers. + +void MyFunction(int /* n */) {} + +TEST(PrintPointerTest, NonMemberFunctionPointer) { + // We cannot directly cast &MyFunction to const void* because the + // standard disallows casting between pointers to functions and + // pointers to objects, and some compilers (e.g. GCC 3.4) enforce + // this limitation. + EXPECT_EQ( + PrintPointer(reinterpret_cast( + reinterpret_cast(&MyFunction))), + Print(&MyFunction)); + int (*p)(bool) = NULL; // NOLINT + EXPECT_EQ("NULL", Print(p)); +} + +// An assertion predicate determining whether a one string is a prefix for +// another. +template +AssertionResult HasPrefix(const StringType& str, const StringType& prefix) { + if (str.find(prefix, 0) == 0) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(prefix[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << begin_string_quote << prefix << "\" is not a prefix of " + << begin_string_quote << str << "\"\n"; +} + +// Tests printing member variable pointers. Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined. Thus they will be +// printed as raw bytes. + +struct Foo { + public: + virtual ~Foo() {} + int MyMethod(char x) { return x + 1; } + virtual char MyVirtualMethod(int /* n */) { return 'a'; } + + int value; +}; + +TEST(PrintPointerTest, MemberVariablePointer) { + EXPECT_TRUE(HasPrefix(Print(&Foo::value), + Print(sizeof(&Foo::value)) + "-byte object ")); + int (Foo::*p) = NULL; // NOLINT + EXPECT_TRUE(HasPrefix(Print(p), + Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing member function pointers. Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined. Thus they will be +// printed as raw bytes. +TEST(PrintPointerTest, MemberFunctionPointer) { + EXPECT_TRUE(HasPrefix(Print(&Foo::MyMethod), + Print(sizeof(&Foo::MyMethod)) + "-byte object ")); + EXPECT_TRUE( + HasPrefix(Print(&Foo::MyVirtualMethod), + Print(sizeof((&Foo::MyVirtualMethod))) + "-byte object ")); + int (Foo::*p)(char) = NULL; // NOLINT + EXPECT_TRUE(HasPrefix(Print(p), + Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing C arrays. + +// The difference between this and Print() is that it ensures that the +// argument is a reference to an array. +template +string PrintArrayHelper(T (&a)[N]) { + return Print(a); +} + +// One-dimensional array. +TEST(PrintArrayTest, OneDimensionalArray) { + int a[5] = { 1, 2, 3, 4, 5 }; + EXPECT_EQ("{ 1, 2, 3, 4, 5 }", PrintArrayHelper(a)); +} + +// Two-dimensional array. +TEST(PrintArrayTest, TwoDimensionalArray) { + int a[2][5] = { + { 1, 2, 3, 4, 5 }, + { 6, 7, 8, 9, 0 } + }; + EXPECT_EQ("{ { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }", PrintArrayHelper(a)); +} + +// Array of const elements. +TEST(PrintArrayTest, ConstArray) { + const bool a[1] = { false }; + EXPECT_EQ("{ false }", PrintArrayHelper(a)); +} + +// char array without terminating NUL. +TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + char a[] = { 'H', '\0', 'i' }; + EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); +} + +// const char array with terminating NUL. +TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) { + const char a[] = "\0Hi"; + EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a)); +} + +// const wchar_t array without terminating NUL. +TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + const wchar_t a[] = { L'H', L'\0', L'i' }; + EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); +} + +// wchar_t array with terminating NUL. +TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) { + const wchar_t a[] = L"\0Hi"; + EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); +} + +// Array of objects. +TEST(PrintArrayTest, ObjectArray) { + string a[3] = { "Hi", "Hello", "Ni hao" }; + EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", PrintArrayHelper(a)); +} + +// Array with many elements. +TEST(PrintArrayTest, BigArray) { + int a[100] = { 1, 2, 3 }; + EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, ..., 0, 0, 0, 0, 0, 0, 0, 0 }", + PrintArrayHelper(a)); +} + +// Tests printing ::string and ::std::string. + +#if GTEST_HAS_GLOBAL_STRING +// ::string. +TEST(PrintStringTest, StringInGlobalNamespace) { + const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; + const ::string str(s, sizeof(s)); + EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", + Print(str)); +} +#endif // GTEST_HAS_GLOBAL_STRING + +// ::std::string. +TEST(PrintStringTest, StringInStdNamespace) { + const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; + const ::std::string str(s, sizeof(s)); + EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", + Print(str)); +} + +TEST(PrintStringTest, StringAmbiguousHex) { + // "\x6BANANA" is ambiguous, it can be interpreted as starting with either of: + // '\x6', '\x6B', or '\x6BA'. + + // a hex escaping sequence following by a decimal digit + EXPECT_EQ("\"0\\x12\" \"3\"", Print(::std::string("0\x12" "3"))); + // a hex escaping sequence following by a hex digit (lower-case) + EXPECT_EQ("\"mm\\x6\" \"bananas\"", Print(::std::string("mm\x6" "bananas"))); + // a hex escaping sequence following by a hex digit (upper-case) + EXPECT_EQ("\"NOM\\x6\" \"BANANA\"", Print(::std::string("NOM\x6" "BANANA"))); + // a hex escaping sequence following by a non-xdigit + EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!"))); +} + +// Tests printing ::wstring and ::std::wstring. + +#if GTEST_HAS_GLOBAL_WSTRING +// ::wstring. +TEST(PrintWideStringTest, StringInGlobalNamespace) { + const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; + const ::wstring str(s, sizeof(s)/sizeof(wchar_t)); + EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" + "\\xD3\\x576\\x8D3\\xC74D a\\0\"", + Print(str)); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +// ::std::wstring. +TEST(PrintWideStringTest, StringInStdNamespace) { + const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; + const ::std::wstring str(s, sizeof(s)/sizeof(wchar_t)); + EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" + "\\xD3\\x576\\x8D3\\xC74D a\\0\"", + Print(str)); +} + +TEST(PrintWideStringTest, StringAmbiguousHex) { + // same for wide strings. + EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12" L"3"))); + EXPECT_EQ("L\"mm\\x6\" L\"bananas\"", + Print(::std::wstring(L"mm\x6" L"bananas"))); + EXPECT_EQ("L\"NOM\\x6\" L\"BANANA\"", + Print(::std::wstring(L"NOM\x6" L"BANANA"))); + EXPECT_EQ("L\"!\\x5-!\"", Print(::std::wstring(L"!\x5-!"))); +} +#endif // GTEST_HAS_STD_WSTRING + +// Tests printing types that support generic streaming (i.e. streaming +// to std::basic_ostream for any valid Char and +// CharTraits types). + +// Tests printing a non-template type that supports generic streaming. + +class AllowsGenericStreaming {}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreaming& /* a */) { + return os << "AllowsGenericStreaming"; +} + +TEST(PrintTypeWithGenericStreamingTest, NonTemplateType) { + AllowsGenericStreaming a; + EXPECT_EQ("AllowsGenericStreaming", Print(a)); +} + +// Tests printing a template type that supports generic streaming. + +template +class AllowsGenericStreamingTemplate {}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreamingTemplate& /* a */) { + return os << "AllowsGenericStreamingTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TemplateType) { + AllowsGenericStreamingTemplate a; + EXPECT_EQ("AllowsGenericStreamingTemplate", Print(a)); +} + +// Tests printing a type that supports generic streaming and can be +// implicitly converted to another printable type. + +template +class AllowsGenericStreamingAndImplicitConversionTemplate { + public: + operator bool() const { return false; } +}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreamingAndImplicitConversionTemplate& /* a */) { + return os << "AllowsGenericStreamingAndImplicitConversionTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { + AllowsGenericStreamingAndImplicitConversionTemplate a; + EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); +} + +#if GTEST_HAS_STRING_PIECE_ + +// Tests printing StringPiece. + +TEST(PrintStringPieceTest, SimpleStringPiece) { + const StringPiece sp = "Hello"; + EXPECT_EQ("\"Hello\"", Print(sp)); +} + +TEST(PrintStringPieceTest, UnprintableCharacters) { + const char str[] = "NUL (\0) and \r\t"; + const StringPiece sp(str, sizeof(str) - 1); + EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); +} + +#endif // GTEST_HAS_STRING_PIECE_ + +// Tests printing STL containers. + +TEST(PrintStlContainerTest, EmptyDeque) { + deque empty; + EXPECT_EQ("{}", Print(empty)); +} + +TEST(PrintStlContainerTest, NonEmptyDeque) { + deque non_empty; + non_empty.push_back(1); + non_empty.push_back(3); + EXPECT_EQ("{ 1, 3 }", Print(non_empty)); +} + +#if GTEST_HAS_HASH_MAP_ + +TEST(PrintStlContainerTest, OneElementHashMap) { + hash_map map1; + map1[1] = 'a'; + EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1)); +} + +TEST(PrintStlContainerTest, HashMultiMap) { + hash_multimap map1; + map1.insert(make_pair(5, true)); + map1.insert(make_pair(5, false)); + + // Elements of hash_multimap can be printed in any order. + const string result = Print(map1); + EXPECT_TRUE(result == "{ (5, true), (5, false) }" || + result == "{ (5, false), (5, true) }") + << " where Print(map1) returns \"" << result << "\"."; +} + +#endif // GTEST_HAS_HASH_MAP_ + +#if GTEST_HAS_HASH_SET_ + +TEST(PrintStlContainerTest, HashSet) { + hash_set set1; + set1.insert("hello"); + EXPECT_EQ("{ \"hello\" }", Print(set1)); +} + +TEST(PrintStlContainerTest, HashMultiSet) { + const int kSize = 5; + int a[kSize] = { 1, 1, 2, 5, 1 }; + hash_multiset set1(a, a + kSize); + + // Elements of hash_multiset can be printed in any order. + const string result = Print(set1); + const string expected_pattern = "{ d, d, d, d, d }"; // d means a digit. + + // Verifies the result matches the expected pattern; also extracts + // the numbers in the result. + ASSERT_EQ(expected_pattern.length(), result.length()); + std::vector numbers; + for (size_t i = 0; i != result.length(); i++) { + if (expected_pattern[i] == 'd') { + ASSERT_NE(isdigit(static_cast(result[i])), 0); + numbers.push_back(result[i] - '0'); + } else { + EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " + << result; + } + } + + // Makes sure the result contains the right numbers. + std::sort(numbers.begin(), numbers.end()); + std::sort(a, a + kSize); + EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin())); +} + +#endif // GTEST_HAS_HASH_SET_ + +TEST(PrintStlContainerTest, List) { + const string a[] = { + "hello", + "world" + }; + const list strings(a, a + 2); + EXPECT_EQ("{ \"hello\", \"world\" }", Print(strings)); +} + +TEST(PrintStlContainerTest, Map) { + map map1; + map1[1] = true; + map1[5] = false; + map1[3] = true; + EXPECT_EQ("{ (1, true), (3, true), (5, false) }", Print(map1)); +} + +TEST(PrintStlContainerTest, MultiMap) { + multimap map1; + // The make_pair template function would deduce the type as + // pair here, and since the key part in a multimap has to + // be constant, without a templated ctor in the pair class (as in + // libCstd on Solaris), make_pair call would fail to compile as no + // implicit conversion is found. Thus explicit typename is used + // here instead. + map1.insert(pair(true, 0)); + map1.insert(pair(true, 1)); + map1.insert(pair(false, 2)); + EXPECT_EQ("{ (false, 2), (true, 0), (true, 1) }", Print(map1)); +} + +TEST(PrintStlContainerTest, Set) { + const unsigned int a[] = { 3, 0, 5 }; + set set1(a, a + 3); + EXPECT_EQ("{ 0, 3, 5 }", Print(set1)); +} + +TEST(PrintStlContainerTest, MultiSet) { + const int a[] = { 1, 1, 2, 5, 1 }; + multiset set1(a, a + 5); + EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1)); +} + +TEST(PrintStlContainerTest, Pair) { + pair p(true, 5); + EXPECT_EQ("(true, 5)", Print(p)); +} + +TEST(PrintStlContainerTest, Vector) { + vector v; + v.push_back(1); + v.push_back(2); + EXPECT_EQ("{ 1, 2 }", Print(v)); +} + +TEST(PrintStlContainerTest, LongSequence) { + const int a[100] = { 1, 2, 3 }; + const vector v(a, a + 100); + EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, " + "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... }", Print(v)); +} + +TEST(PrintStlContainerTest, NestedContainer) { + const int a1[] = { 1, 2 }; + const int a2[] = { 3, 4, 5 }; + const list l1(a1, a1 + 2); + const list l2(a2, a2 + 3); + + vector > v; + v.push_back(l1); + v.push_back(l2); + EXPECT_EQ("{ { 1, 2 }, { 3, 4, 5 } }", Print(v)); +} + +TEST(PrintStlContainerTest, OneDimensionalNativeArray) { + const int a[3] = { 1, 2, 3 }; + NativeArray b(a, 3, kReference); + EXPECT_EQ("{ 1, 2, 3 }", Print(b)); +} + +TEST(PrintStlContainerTest, TwoDimensionalNativeArray) { + const int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; + NativeArray b(a, 2, kReference); + EXPECT_EQ("{ { 1, 2, 3 }, { 4, 5, 6 } }", Print(b)); +} + +// Tests that a class named iterator isn't treated as a container. + +struct iterator { + char x; +}; + +TEST(PrintStlContainerTest, Iterator) { + iterator it = {}; + EXPECT_EQ("1-byte object <00>", Print(it)); +} + +// Tests that a class named const_iterator isn't treated as a container. + +struct const_iterator { + char x; +}; + +TEST(PrintStlContainerTest, ConstIterator) { + const_iterator it = {}; + EXPECT_EQ("1-byte object <00>", Print(it)); +} + +#if GTEST_HAS_TR1_TUPLE +// Tests printing tuples. + +// Tuples of various arities. +TEST(PrintTupleTest, VariousSizes) { + tuple<> t0; + EXPECT_EQ("()", Print(t0)); + + tuple t1(5); + EXPECT_EQ("(5)", Print(t1)); + + tuple t2('a', true); + EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); + + tuple t3(false, 2, 3); + EXPECT_EQ("(false, 2, 3)", Print(t3)); + + tuple t4(false, 2, 3, 4); + EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); + + tuple t5(false, 2, 3, 4, true); + EXPECT_EQ("(false, 2, 3, 4, true)", Print(t5)); + + tuple t6(false, 2, 3, 4, true, 6); + EXPECT_EQ("(false, 2, 3, 4, true, 6)", Print(t6)); + + tuple t7(false, 2, 3, 4, true, 6, 7); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7)", Print(t7)); + + tuple t8( + false, 2, 3, 4, true, 6, 7, true); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true)", Print(t8)); + + tuple t9( + false, 2, 3, 4, true, 6, 7, true, 9); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9)); + + const char* const str = "8"; + // VC++ 2010's implementation of tuple of C++0x is deficient, requiring + // an explicit type cast of NULL to be used. + tuple + t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, + ImplicitCast_(NULL), "10"); + EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + + " pointing to \"8\", NULL, \"10\")", + Print(t10)); +} + +// Nested tuples. +TEST(PrintTupleTest, NestedTuple) { + tuple, char> nested(make_tuple(5, true), 'a'); + EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested)); +} + +#endif // GTEST_HAS_TR1_TUPLE + +// Tests printing user-defined unprintable types. + +// Unprintable types in the global namespace. +TEST(PrintUnprintableTypeTest, InGlobalNamespace) { + EXPECT_EQ("1-byte object <00>", + Print(UnprintableTemplateInGlobal())); +} + +// Unprintable types in a user namespace. +TEST(PrintUnprintableTypeTest, InUserNamespace) { + EXPECT_EQ("16-byte object ", + Print(::foo::UnprintableInFoo())); +} + +// Unprintable types are that too big to be printed completely. + +struct Big { + Big() { memset(array, 0, sizeof(array)); } + char array[257]; +}; + +TEST(PrintUnpritableTypeTest, BigObject) { + EXPECT_EQ("257-byte object <00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 ... 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00>", + Print(Big())); +} + +// Tests printing user-defined streamable types. + +// Streamable types in the global namespace. +TEST(PrintStreamableTypeTest, InGlobalNamespace) { + StreamableInGlobal x; + EXPECT_EQ("StreamableInGlobal", Print(x)); + EXPECT_EQ("StreamableInGlobal*", Print(&x)); +} + +// Printable template types in a user namespace. +TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) { + EXPECT_EQ("StreamableTemplateInFoo: 0", + Print(::foo::StreamableTemplateInFoo())); +} + +// Tests printing user-defined types that have a PrintTo() function. +TEST(PrintPrintableTypeTest, InUserNamespace) { + EXPECT_EQ("PrintableViaPrintTo: 0", + Print(::foo::PrintableViaPrintTo())); +} + +// Tests printing a pointer to a user-defined type that has a << +// operator for its pointer. +TEST(PrintPrintableTypeTest, PointerInUserNamespace) { + ::foo::PointerPrintable x; + EXPECT_EQ("PointerPrintable*", Print(&x)); +} + +// Tests printing user-defined class template that have a PrintTo() function. +TEST(PrintPrintableTypeTest, TemplateInUserNamespace) { + EXPECT_EQ("PrintableViaPrintToTemplate: 5", + Print(::foo::PrintableViaPrintToTemplate(5))); +} + +#if GTEST_HAS_PROTOBUF_ + +// Tests printing a protocol message. +TEST(PrintProtocolMessageTest, PrintsShortDebugString) { + testing::internal::TestMessage msg; + msg.set_member("yes"); + EXPECT_EQ("", Print(msg)); +} + +// Tests printing a short proto2 message. +TEST(PrintProto2MessageTest, PrintsShortDebugStringWhenItIsShort) { + testing::internal::FooMessage msg; + msg.set_int_field(2); + msg.set_string_field("hello"); + EXPECT_PRED2(RE::FullMatch, Print(msg), + ""); +} + +// Tests printing a long proto2 message. +TEST(PrintProto2MessageTest, PrintsDebugStringWhenItIsLong) { + testing::internal::FooMessage msg; + msg.set_int_field(2); + msg.set_string_field("hello"); + msg.add_names("peter"); + msg.add_names("paul"); + msg.add_names("mary"); + EXPECT_PRED2(RE::FullMatch, Print(msg), + "<\n" + "int_field:\\s*2\n" + "string_field:\\s*\"hello\"\n" + "names:\\s*\"peter\"\n" + "names:\\s*\"paul\"\n" + "names:\\s*\"mary\"\n" + ">"); +} + +#endif // GTEST_HAS_PROTOBUF_ + +// Tests that the universal printer prints both the address and the +// value of a reference. +TEST(PrintReferenceTest, PrintsAddressAndValue) { + int n = 5; + EXPECT_EQ("@" + PrintPointer(&n) + " 5", PrintByRef(n)); + + int a[2][3] = { + { 0, 1, 2 }, + { 3, 4, 5 } + }; + EXPECT_EQ("@" + PrintPointer(a) + " { { 0, 1, 2 }, { 3, 4, 5 } }", + PrintByRef(a)); + + const ::foo::UnprintableInFoo x; + EXPECT_EQ("@" + PrintPointer(&x) + " 16-byte object " + "", + PrintByRef(x)); +} + +// Tests that the universal printer prints a function pointer passed by +// reference. +TEST(PrintReferenceTest, HandlesFunctionPointer) { + void (*fp)(int n) = &MyFunction; + const string fp_pointer_string = + PrintPointer(reinterpret_cast(&fp)); + // We cannot directly cast &MyFunction to const void* because the + // standard disallows casting between pointers to functions and + // pointers to objects, and some compilers (e.g. GCC 3.4) enforce + // this limitation. + const string fp_string = PrintPointer(reinterpret_cast( + reinterpret_cast(fp))); + EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, + PrintByRef(fp)); +} + +// Tests that the universal printer prints a member function pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberFunctionPointer) { + int (Foo::*p)(char ch) = &Foo::MyMethod; + EXPECT_TRUE(HasPrefix( + PrintByRef(p), + "@" + PrintPointer(reinterpret_cast(&p)) + " " + + Print(sizeof(p)) + "-byte object ")); + + char (Foo::*p2)(int n) = &Foo::MyVirtualMethod; + EXPECT_TRUE(HasPrefix( + PrintByRef(p2), + "@" + PrintPointer(reinterpret_cast(&p2)) + " " + + Print(sizeof(p2)) + "-byte object ")); +} + +// Tests that the universal printer prints a member variable pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberVariablePointer) { + int (Foo::*p) = &Foo::value; // NOLINT + EXPECT_TRUE(HasPrefix( + PrintByRef(p), + "@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object ")); +} + +// Tests that FormatForComparisonFailureMessage(), which is used to print +// an operand in a comparison assertion (e.g. ASSERT_EQ) when the assertion +// fails, formats the operand in the desired way. + +// scalar +TEST(FormatForComparisonFailureMessageTest, WorksForScalar) { + EXPECT_STREQ("123", + FormatForComparisonFailureMessage(123, 124).c_str()); +} + +// non-char pointer +TEST(FormatForComparisonFailureMessageTest, WorksForNonCharPointer) { + int n = 0; + EXPECT_EQ(PrintPointer(&n), + FormatForComparisonFailureMessage(&n, &n).c_str()); +} + +// non-char array +TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) { + // In expression 'array == x', 'array' is compared by pointer. + // Therefore we want to print an array operand as a pointer. + int n[] = { 1, 2, 3 }; + EXPECT_EQ(PrintPointer(n), + FormatForComparisonFailureMessage(n, n).c_str()); +} + +// Tests formatting a char pointer when it's compared with another pointer. +// In this case we want to print it as a raw pointer, as the comparision is by +// pointer. + +// char pointer vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsPointer) { + // In expression 'p == x', where 'p' and 'x' are (const or not) char + // pointers, the operands are compared by pointer. Therefore we + // want to print 'p' as a pointer instead of a C string (we don't + // even know if it's supposed to point to a valid C string). + + // const char* + const char* s = "hello"; + EXPECT_EQ(PrintPointer(s), + FormatForComparisonFailureMessage(s, s).c_str()); + + // char* + char ch = 'a'; + EXPECT_EQ(PrintPointer(&ch), + FormatForComparisonFailureMessage(&ch, &ch).c_str()); +} + +// wchar_t pointer vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsPointer) { + // In expression 'p == x', where 'p' and 'x' are (const or not) char + // pointers, the operands are compared by pointer. Therefore we + // want to print 'p' as a pointer instead of a wide C string (we don't + // even know if it's supposed to point to a valid wide C string). + + // const wchar_t* + const wchar_t* s = L"hello"; + EXPECT_EQ(PrintPointer(s), + FormatForComparisonFailureMessage(s, s).c_str()); + + // wchar_t* + wchar_t ch = L'a'; + EXPECT_EQ(PrintPointer(&ch), + FormatForComparisonFailureMessage(&ch, &ch).c_str()); +} + +// Tests formatting a char pointer when it's compared to a string object. +// In this case we want to print the char pointer as a C string. + +#if GTEST_HAS_GLOBAL_STRING +// char pointer vs ::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsString) { + const char* s = "hello \"world"; + EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::string()).c_str()); + + // char* + char str[] = "hi\1"; + char* p = str; + EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::string()).c_str()); +} +#endif + +// char pointer vs std::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsStdString) { + const char* s = "hello \"world"; + EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::std::string()).c_str()); + + // char* + char str[] = "hi\1"; + char* p = str; + EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::std::string()).c_str()); +} + +#if GTEST_HAS_GLOBAL_WSTRING +// wchar_t pointer vs ::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsWString) { + const wchar_t* s = L"hi \"world"; + EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::wstring()).c_str()); + + // wchar_t* + wchar_t str[] = L"hi\1"; + wchar_t* p = str; + EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::wstring()).c_str()); +} +#endif + +#if GTEST_HAS_STD_WSTRING +// wchar_t pointer vs std::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsStdWString) { + const wchar_t* s = L"hi \"world"; + EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::std::wstring()).c_str()); + + // wchar_t* + wchar_t str[] = L"hi\1"; + wchar_t* p = str; + EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::std::wstring()).c_str()); +} +#endif + +// Tests formatting a char array when it's compared with a pointer or array. +// In this case we want to print the array as a row pointer, as the comparison +// is by pointer. + +// char array vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsPointer) { + char str[] = "hi \"world\""; + char* p = NULL; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, p).c_str()); +} + +// char array vs char array +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsCharArray) { + const char str[] = "hi \"world\""; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, str).c_str()); +} + +// wchar_t array vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsPointer) { + wchar_t str[] = L"hi \"world\""; + wchar_t* p = NULL; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, p).c_str()); +} + +// wchar_t array vs wchar_t array +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWCharArray) { + const wchar_t str[] = L"hi \"world\""; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, str).c_str()); +} + +// Tests formatting a char array when it's compared with a string object. +// In this case we want to print the array as a C string. + +#if GTEST_HAS_GLOBAL_STRING +// char array vs string +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsString) { + const char str[] = "hi \"w\0rld\""; + EXPECT_STREQ("\"hi \\\"w\"", // The content should be escaped. + // Embedded NUL terminates the string. + FormatForComparisonFailureMessage(str, ::string()).c_str()); +} +#endif + +// char array vs std::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsStdString) { + const char str[] = "hi \"world\""; + EXPECT_STREQ("\"hi \\\"world\\\"\"", // The content should be escaped. + FormatForComparisonFailureMessage(str, ::std::string()).c_str()); +} + +#if GTEST_HAS_GLOBAL_WSTRING +// wchar_t array vs wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWString) { + const wchar_t str[] = L"hi \"world\""; + EXPECT_STREQ("L\"hi \\\"world\\\"\"", // The content should be escaped. + FormatForComparisonFailureMessage(str, ::wstring()).c_str()); +} +#endif + +#if GTEST_HAS_STD_WSTRING +// wchar_t array vs std::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsStdWString) { + const wchar_t str[] = L"hi \"w\0rld\""; + EXPECT_STREQ( + "L\"hi \\\"w\"", // The content should be escaped. + // Embedded NUL terminates the string. + FormatForComparisonFailureMessage(str, ::std::wstring()).c_str()); +} +#endif + +// Useful for testing PrintToString(). We cannot use EXPECT_EQ() +// there as its implementation uses PrintToString(). The caller must +// ensure that 'value' has no side effect. +#define EXPECT_PRINT_TO_STRING_(value, expected_string) \ + EXPECT_TRUE(PrintToString(value) == (expected_string)) \ + << " where " #value " prints as " << (PrintToString(value)) + +TEST(PrintToStringTest, WorksForScalar) { + EXPECT_PRINT_TO_STRING_(123, "123"); +} + +TEST(PrintToStringTest, WorksForPointerToConstChar) { + const char* p = "hello"; + EXPECT_PRINT_TO_STRING_(p, "\"hello\""); +} + +TEST(PrintToStringTest, WorksForPointerToNonConstChar) { + char s[] = "hello"; + char* p = s; + EXPECT_PRINT_TO_STRING_(p, "\"hello\""); +} + +TEST(PrintToStringTest, EscapesForPointerToConstChar) { + const char* p = "hello\n"; + EXPECT_PRINT_TO_STRING_(p, "\"hello\\n\""); +} + +TEST(PrintToStringTest, EscapesForPointerToNonConstChar) { + char s[] = "hello\1"; + char* p = s; + EXPECT_PRINT_TO_STRING_(p, "\"hello\\x1\""); +} + +TEST(PrintToStringTest, WorksForArray) { + int n[3] = { 1, 2, 3 }; + EXPECT_PRINT_TO_STRING_(n, "{ 1, 2, 3 }"); +} + +TEST(PrintToStringTest, WorksForCharArray) { + char s[] = "hello"; + EXPECT_PRINT_TO_STRING_(s, "\"hello\""); +} + +TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { + const char str_with_nul[] = "hello\0 world"; + EXPECT_PRINT_TO_STRING_(str_with_nul, "\"hello\\0 world\""); + + char mutable_str_with_nul[] = "hello\0 world"; + EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\""); +} + +#undef EXPECT_PRINT_TO_STRING_ + +TEST(UniversalTersePrintTest, WorksForNonReference) { + ::std::stringstream ss; + UniversalTersePrint(123, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalTersePrintTest, WorksForReference) { + const int& n = 123; + ::std::stringstream ss; + UniversalTersePrint(n, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalTersePrintTest, WorksForCString) { + const char* s1 = "abc"; + ::std::stringstream ss1; + UniversalTersePrint(s1, &ss1); + EXPECT_EQ("\"abc\"", ss1.str()); + + char* s2 = const_cast(s1); + ::std::stringstream ss2; + UniversalTersePrint(s2, &ss2); + EXPECT_EQ("\"abc\"", ss2.str()); + + const char* s3 = NULL; + ::std::stringstream ss3; + UniversalTersePrint(s3, &ss3); + EXPECT_EQ("NULL", ss3.str()); +} + +TEST(UniversalPrintTest, WorksForNonReference) { + ::std::stringstream ss; + UniversalPrint(123, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalPrintTest, WorksForReference) { + const int& n = 123; + ::std::stringstream ss; + UniversalPrint(n, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalPrintTest, WorksForCString) { + const char* s1 = "abc"; + ::std::stringstream ss1; + UniversalPrint(s1, &ss1); + EXPECT_EQ(PrintPointer(s1) + " pointing to \"abc\"", string(ss1.str())); + + char* s2 = const_cast(s1); + ::std::stringstream ss2; + UniversalPrint(s2, &ss2); + EXPECT_EQ(PrintPointer(s2) + " pointing to \"abc\"", string(ss2.str())); + + const char* s3 = NULL; + ::std::stringstream ss3; + UniversalPrint(s3, &ss3); + EXPECT_EQ("NULL", ss3.str()); +} + +TEST(UniversalPrintTest, WorksForCharArray) { + const char str[] = "\"Line\0 1\"\nLine 2"; + ::std::stringstream ss1; + UniversalPrint(str, &ss1); + EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss1.str()); + + const char mutable_str[] = "\"Line\0 1\"\nLine 2"; + ::std::stringstream ss2; + UniversalPrint(mutable_str, &ss2); + EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str()); +} + +#if GTEST_HAS_TR1_TUPLE + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsEmptyTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple()); + EXPECT_EQ(0u, result.size()); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsOneTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1)); + ASSERT_EQ(1u, result.size()); + EXPECT_EQ("1", result[0]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTwoTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1, 'a')); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("'a' (97, 0x61)", result[1]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTersely) { + const int n = 1; + Strings result = UniversalTersePrintTupleFieldsToStrings( + tuple(n, "a")); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("\"a\"", result[1]); +} + +#endif // GTEST_HAS_TR1_TUPLE + +} // namespace gtest_printers_test +} // namespace testing diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-test-part_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-test-part_test.cc new file mode 100644 index 0000000..ca8ba93 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-test-part_test.cc @@ -0,0 +1,208 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// + +#include "gtest/gtest-test-part.h" + +#include "gtest/gtest.h" + +using testing::Message; +using testing::Test; +using testing::TestPartResult; +using testing::TestPartResultArray; + +namespace { + +// Tests the TestPartResult class. + +// The test fixture for testing TestPartResult. +class TestPartResultTest : public Test { + protected: + TestPartResultTest() + : r1_(TestPartResult::kSuccess, "foo/bar.cc", 10, "Success!"), + r2_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure!"), + r3_(TestPartResult::kFatalFailure, NULL, -1, "Failure!") {} + + TestPartResult r1_, r2_, r3_; +}; + + +TEST_F(TestPartResultTest, ConstructorWorks) { + Message message; + message << "something is terribly wrong"; + message << static_cast(testing::internal::kStackTraceMarker); + message << "some unimportant stack trace"; + + const TestPartResult result(TestPartResult::kNonFatalFailure, + "some_file.cc", + 42, + message.GetString().c_str()); + + EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type()); + EXPECT_STREQ("some_file.cc", result.file_name()); + EXPECT_EQ(42, result.line_number()); + EXPECT_STREQ(message.GetString().c_str(), result.message()); + EXPECT_STREQ("something is terribly wrong", result.summary()); +} + +TEST_F(TestPartResultTest, ResultAccessorsWork) { + const TestPartResult success(TestPartResult::kSuccess, + "file.cc", + 42, + "message"); + EXPECT_TRUE(success.passed()); + EXPECT_FALSE(success.failed()); + EXPECT_FALSE(success.nonfatally_failed()); + EXPECT_FALSE(success.fatally_failed()); + + const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure, + "file.cc", + 42, + "message"); + EXPECT_FALSE(nonfatal_failure.passed()); + EXPECT_TRUE(nonfatal_failure.failed()); + EXPECT_TRUE(nonfatal_failure.nonfatally_failed()); + EXPECT_FALSE(nonfatal_failure.fatally_failed()); + + const TestPartResult fatal_failure(TestPartResult::kFatalFailure, + "file.cc", + 42, + "message"); + EXPECT_FALSE(fatal_failure.passed()); + EXPECT_TRUE(fatal_failure.failed()); + EXPECT_FALSE(fatal_failure.nonfatally_failed()); + EXPECT_TRUE(fatal_failure.fatally_failed()); +} + +// Tests TestPartResult::type(). +TEST_F(TestPartResultTest, type) { + EXPECT_EQ(TestPartResult::kSuccess, r1_.type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, r2_.type()); + EXPECT_EQ(TestPartResult::kFatalFailure, r3_.type()); +} + +// Tests TestPartResult::file_name(). +TEST_F(TestPartResultTest, file_name) { + EXPECT_STREQ("foo/bar.cc", r1_.file_name()); + EXPECT_STREQ(NULL, r3_.file_name()); +} + +// Tests TestPartResult::line_number(). +TEST_F(TestPartResultTest, line_number) { + EXPECT_EQ(10, r1_.line_number()); + EXPECT_EQ(-1, r2_.line_number()); +} + +// Tests TestPartResult::message(). +TEST_F(TestPartResultTest, message) { + EXPECT_STREQ("Success!", r1_.message()); +} + +// Tests TestPartResult::passed(). +TEST_F(TestPartResultTest, Passed) { + EXPECT_TRUE(r1_.passed()); + EXPECT_FALSE(r2_.passed()); + EXPECT_FALSE(r3_.passed()); +} + +// Tests TestPartResult::failed(). +TEST_F(TestPartResultTest, Failed) { + EXPECT_FALSE(r1_.failed()); + EXPECT_TRUE(r2_.failed()); + EXPECT_TRUE(r3_.failed()); +} + +// Tests TestPartResult::fatally_failed(). +TEST_F(TestPartResultTest, FatallyFailed) { + EXPECT_FALSE(r1_.fatally_failed()); + EXPECT_FALSE(r2_.fatally_failed()); + EXPECT_TRUE(r3_.fatally_failed()); +} + +// Tests TestPartResult::nonfatally_failed(). +TEST_F(TestPartResultTest, NonfatallyFailed) { + EXPECT_FALSE(r1_.nonfatally_failed()); + EXPECT_TRUE(r2_.nonfatally_failed()); + EXPECT_FALSE(r3_.nonfatally_failed()); +} + +// Tests the TestPartResultArray class. + +class TestPartResultArrayTest : public Test { + protected: + TestPartResultArrayTest() + : r1_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure 1"), + r2_(TestPartResult::kFatalFailure, "foo/bar.cc", -1, "Failure 2") {} + + const TestPartResult r1_, r2_; +}; + +// Tests that TestPartResultArray initially has size 0. +TEST_F(TestPartResultArrayTest, InitialSizeIsZero) { + TestPartResultArray results; + EXPECT_EQ(0, results.size()); +} + +// Tests that TestPartResultArray contains the given TestPartResult +// after one Append() operation. +TEST_F(TestPartResultArrayTest, ContainsGivenResultAfterAppend) { + TestPartResultArray results; + results.Append(r1_); + EXPECT_EQ(1, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); +} + +// Tests that TestPartResultArray contains the given TestPartResults +// after two Append() operations. +TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) { + TestPartResultArray results; + results.Append(r1_); + results.Append(r2_); + EXPECT_EQ(2, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); + EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message()); +} + +typedef TestPartResultArrayTest TestPartResultArrayDeathTest; + +// Tests that the program dies when GetTestPartResult() is called with +// an invalid index. +TEST_F(TestPartResultArrayDeathTest, DiesWhenIndexIsOutOfBound) { + TestPartResultArray results; + results.Append(r1_); + + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(-1), ""); + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(1), ""); +} + +// TODO(mheule@google.com): Add a test for the class HasNewFatalFailureHelper. + +} // namespace diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-tuple_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-tuple_test.cc new file mode 100644 index 0000000..bfaa3e0 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-tuple_test.cc @@ -0,0 +1,320 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/internal/gtest-tuple.h" +#include +#include "gtest/gtest.h" + +namespace { + +using ::std::tr1::get; +using ::std::tr1::make_tuple; +using ::std::tr1::tuple; +using ::std::tr1::tuple_element; +using ::std::tr1::tuple_size; +using ::testing::StaticAssertTypeEq; + +// Tests that tuple_element >::type returns TK. +TEST(tuple_element_Test, ReturnsElementType) { + StaticAssertTypeEq >::type>(); + StaticAssertTypeEq >::type>(); + StaticAssertTypeEq >::type>(); +} + +// Tests that tuple_size::value gives the number of fields in tuple +// type T. +TEST(tuple_size_Test, ReturnsNumberOfFields) { + EXPECT_EQ(0, +tuple_size >::value); + EXPECT_EQ(1, +tuple_size >::value); + EXPECT_EQ(1, +tuple_size >::value); + EXPECT_EQ(1, +(tuple_size > >::value)); + EXPECT_EQ(2, +(tuple_size >::value)); + EXPECT_EQ(3, +(tuple_size >::value)); +} + +// Tests comparing a tuple with itself. +TEST(ComparisonTest, ComparesWithSelf) { + const tuple a(5, 'a', false); + + EXPECT_TRUE(a == a); + EXPECT_FALSE(a != a); +} + +// Tests comparing two tuples with the same value. +TEST(ComparisonTest, ComparesEqualTuples) { + const tuple a(5, true), b(5, true); + + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); +} + +// Tests comparing two different tuples that have no reference fields. +TEST(ComparisonTest, ComparesUnequalTuplesWithoutReferenceFields) { + typedef tuple FooTuple; + + const FooTuple a(0, 'x'); + const FooTuple b(1, 'a'); + + EXPECT_TRUE(a != b); + EXPECT_FALSE(a == b); + + const FooTuple c(1, 'b'); + + EXPECT_TRUE(b != c); + EXPECT_FALSE(b == c); +} + +// Tests comparing two different tuples that have reference fields. +TEST(ComparisonTest, ComparesUnequalTuplesWithReferenceFields) { + typedef tuple FooTuple; + + int i = 5; + const char ch = 'a'; + const FooTuple a(i, ch); + + int j = 6; + const FooTuple b(j, ch); + + EXPECT_TRUE(a != b); + EXPECT_FALSE(a == b); + + j = 5; + const char ch2 = 'b'; + const FooTuple c(j, ch2); + + EXPECT_TRUE(b != c); + EXPECT_FALSE(b == c); +} + +// Tests that a tuple field with a reference type is an alias of the +// variable it's supposed to reference. +TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) { + int n = 0; + tuple t(true, n); + + n = 1; + EXPECT_EQ(n, get<1>(t)) + << "Changing a underlying variable should update the reference field."; + + // Makes sure that the implementation doesn't do anything funny with + // the & operator for the return type of get<>(). + EXPECT_EQ(&n, &(get<1>(t))) + << "The address of a reference field should equal the address of " + << "the underlying variable."; + + get<1>(t) = 2; + EXPECT_EQ(2, n) + << "Changing a reference field should update the underlying variable."; +} + +// Tests that tuple's default constructor default initializes each field. +// This test needs to compile without generating warnings. +TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) { + // The TR1 report requires that tuple's default constructor default + // initializes each field, even if it's a primitive type. If the + // implementation forgets to do this, this test will catch it by + // generating warnings about using uninitialized variables (assuming + // a decent compiler). + + tuple<> empty; + + tuple a1, b1; + b1 = a1; + EXPECT_EQ(0, get<0>(b1)); + + tuple a2, b2; + b2 = a2; + EXPECT_EQ(0, get<0>(b2)); + EXPECT_EQ(0.0, get<1>(b2)); + + tuple a3, b3; + b3 = a3; + EXPECT_EQ(0.0, get<0>(b3)); + EXPECT_EQ('\0', get<1>(b3)); + EXPECT_TRUE(get<2>(b3) == NULL); + + tuple a10, b10; + b10 = a10; + EXPECT_EQ(0, get<0>(b10)); + EXPECT_EQ(0, get<1>(b10)); + EXPECT_EQ(0, get<2>(b10)); + EXPECT_EQ(0, get<3>(b10)); + EXPECT_EQ(0, get<4>(b10)); + EXPECT_EQ(0, get<5>(b10)); + EXPECT_EQ(0, get<6>(b10)); + EXPECT_EQ(0, get<7>(b10)); + EXPECT_EQ(0, get<8>(b10)); + EXPECT_EQ(0, get<9>(b10)); +} + +// Tests constructing a tuple from its fields. +TEST(TupleConstructorTest, ConstructsFromFields) { + int n = 1; + // Reference field. + tuple a(n); + EXPECT_EQ(&n, &(get<0>(a))); + + // Non-reference fields. + tuple b(5, 'a'); + EXPECT_EQ(5, get<0>(b)); + EXPECT_EQ('a', get<1>(b)); + + // Const reference field. + const int m = 2; + tuple c(true, m); + EXPECT_TRUE(get<0>(c)); + EXPECT_EQ(&m, &(get<1>(c))); +} + +// Tests tuple's copy constructor. +TEST(TupleConstructorTest, CopyConstructor) { + tuple a(0.0, true); + tuple b(a); + + EXPECT_DOUBLE_EQ(0.0, get<0>(b)); + EXPECT_TRUE(get<1>(b)); +} + +// Tests constructing a tuple from another tuple that has a compatible +// but different type. +TEST(TupleConstructorTest, ConstructsFromDifferentTupleType) { + tuple a(0, 1, 'a'); + tuple b(a); + + EXPECT_DOUBLE_EQ(0.0, get<0>(b)); + EXPECT_EQ(1, get<1>(b)); + EXPECT_EQ('a', get<2>(b)); +} + +// Tests constructing a 2-tuple from an std::pair. +TEST(TupleConstructorTest, ConstructsFromPair) { + ::std::pair a(1, 'a'); + tuple b(a); + tuple c(a); +} + +// Tests assigning a tuple to another tuple with the same type. +TEST(TupleAssignmentTest, AssignsToSameTupleType) { + const tuple a(5, 7L); + tuple b; + b = a; + EXPECT_EQ(5, get<0>(b)); + EXPECT_EQ(7L, get<1>(b)); +} + +// Tests assigning a tuple to another tuple with a different but +// compatible type. +TEST(TupleAssignmentTest, AssignsToDifferentTupleType) { + const tuple a(1, 7L, true); + tuple b; + b = a; + EXPECT_EQ(1L, get<0>(b)); + EXPECT_EQ(7, get<1>(b)); + EXPECT_TRUE(get<2>(b)); +} + +// Tests assigning an std::pair to a 2-tuple. +TEST(TupleAssignmentTest, AssignsFromPair) { + const ::std::pair a(5, true); + tuple b; + b = a; + EXPECT_EQ(5, get<0>(b)); + EXPECT_TRUE(get<1>(b)); + + tuple c; + c = a; + EXPECT_EQ(5L, get<0>(c)); + EXPECT_TRUE(get<1>(c)); +} + +// A fixture for testing big tuples. +class BigTupleTest : public testing::Test { + protected: + typedef tuple BigTuple; + + BigTupleTest() : + a_(1, 0, 0, 0, 0, 0, 0, 0, 0, 2), + b_(1, 0, 0, 0, 0, 0, 0, 0, 0, 3) {} + + BigTuple a_, b_; +}; + +// Tests constructing big tuples. +TEST_F(BigTupleTest, Construction) { + BigTuple a; + BigTuple b(b_); +} + +// Tests that get(t) returns the N-th (0-based) field of tuple t. +TEST_F(BigTupleTest, get) { + EXPECT_EQ(1, get<0>(a_)); + EXPECT_EQ(2, get<9>(a_)); + + // Tests that get() works on a const tuple too. + const BigTuple a(a_); + EXPECT_EQ(1, get<0>(a)); + EXPECT_EQ(2, get<9>(a)); +} + +// Tests comparing big tuples. +TEST_F(BigTupleTest, Comparisons) { + EXPECT_TRUE(a_ == a_); + EXPECT_FALSE(a_ != a_); + + EXPECT_TRUE(a_ != b_); + EXPECT_FALSE(a_ == b_); +} + +TEST(MakeTupleTest, WorksForScalarTypes) { + tuple a; + a = make_tuple(true, 5); + EXPECT_TRUE(get<0>(a)); + EXPECT_EQ(5, get<1>(a)); + + tuple b; + b = make_tuple('a', 'b', 5); + EXPECT_EQ('a', get<0>(b)); + EXPECT_EQ('b', get<1>(b)); + EXPECT_EQ(5, get<2>(b)); +} + +TEST(MakeTupleTest, WorksForPointers) { + int a[] = { 1, 2, 3, 4 }; + const char* const str = "hi"; + int* const p = a; + + tuple t; + t = make_tuple(str, p); + EXPECT_EQ(str, get<0>(t)); + EXPECT_EQ(p, get<1>(t)); +} + +} // namespace diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test2_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test2_test.cc new file mode 100644 index 0000000..c284700 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test2_test.cc @@ -0,0 +1,45 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include + +#include "test/gtest-typed-test_test.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_TYPED_TEST_P + +// Tests that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// (ContainerTest is also instantiated in gtest-typed-test_test.cc.) +INSTANTIATE_TYPED_TEST_CASE_P(Vector, ContainerTest, + testing::Types >); + +#endif // GTEST_HAS_TYPED_TEST_P diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test_test.cc new file mode 100644 index 0000000..dd4ba43 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test_test.cc @@ -0,0 +1,360 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include +#include + +#include "test/gtest-typed-test_test.h" +#include "gtest/gtest.h" + +using testing::Test; + +// Used for testing that SetUpTestCase()/TearDownTestCase(), fixture +// ctor/dtor, and SetUp()/TearDown() work correctly in typed tests and +// type-parameterized test. +template +class CommonTest : public Test { + // For some technical reason, SetUpTestCase() and TearDownTestCase() + // must be public. + public: + static void SetUpTestCase() { + shared_ = new T(5); + } + + static void TearDownTestCase() { + delete shared_; + shared_ = NULL; + } + + // This 'protected:' is optional. There's no harm in making all + // members of this fixture class template public. + protected: + // We used to use std::list here, but switched to std::vector since + // MSVC's doesn't compile cleanly with /W4. + typedef std::vector Vector; + typedef std::set IntSet; + + CommonTest() : value_(1) {} + + virtual ~CommonTest() { EXPECT_EQ(3, value_); } + + virtual void SetUp() { + EXPECT_EQ(1, value_); + value_++; + } + + virtual void TearDown() { + EXPECT_EQ(2, value_); + value_++; + } + + T value_; + static T* shared_; +}; + +template +T* CommonTest::shared_ = NULL; + +// This #ifdef block tests typed tests. +#if GTEST_HAS_TYPED_TEST + +using testing::Types; + +// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, +// and SetUp()/TearDown() work correctly in typed tests + +typedef Types TwoTypes; +TYPED_TEST_CASE(CommonTest, TwoTypes); + +TYPED_TEST(CommonTest, ValuesAreCorrect) { + // Static members of the fixture class template can be visited via + // the TestFixture:: prefix. + EXPECT_EQ(5, *TestFixture::shared_); + + // Typedefs in the fixture class template can be visited via the + // "typename TestFixture::" prefix. + typename TestFixture::Vector empty; + EXPECT_EQ(0U, empty.size()); + + typename TestFixture::IntSet empty2; + EXPECT_EQ(0U, empty2.size()); + + // Non-static members of the fixture class must be visited via + // 'this', as required by C++ for class templates. + EXPECT_EQ(2, this->value_); +} + +// The second test makes sure shared_ is not deleted after the first +// test. +TYPED_TEST(CommonTest, ValuesAreStillCorrect) { + // Static members of the fixture class template can also be visited + // via 'this'. + ASSERT_TRUE(this->shared_ != NULL); + EXPECT_EQ(5, *this->shared_); + + // TypeParam can be used to refer to the type parameter. + EXPECT_EQ(static_cast(2), this->value_); +} + +// Tests that multiple TYPED_TEST_CASE's can be defined in the same +// translation unit. + +template +class TypedTest1 : public Test { +}; + +// Verifies that the second argument of TYPED_TEST_CASE can be a +// single type. +TYPED_TEST_CASE(TypedTest1, int); +TYPED_TEST(TypedTest1, A) {} + +template +class TypedTest2 : public Test { +}; + +// Verifies that the second argument of TYPED_TEST_CASE can be a +// Types<...> type list. +TYPED_TEST_CASE(TypedTest2, Types); + +// This also verifies that tests from different typed test cases can +// share the same name. +TYPED_TEST(TypedTest2, A) {} + +// Tests that a typed test case can be defined in a namespace. + +namespace library1 { + +template +class NumericTest : public Test { +}; + +typedef Types NumericTypes; +TYPED_TEST_CASE(NumericTest, NumericTypes); + +TYPED_TEST(NumericTest, DefaultIsZero) { + EXPECT_EQ(0, TypeParam()); +} + +} // namespace library1 + +#endif // GTEST_HAS_TYPED_TEST + +// This #ifdef block tests type-parameterized tests. +#if GTEST_HAS_TYPED_TEST_P + +using testing::Types; +using testing::internal::TypedTestCasePState; + +// Tests TypedTestCasePState. + +class TypedTestCasePStateTest : public Test { + protected: + virtual void SetUp() { + state_.AddTestName("foo.cc", 0, "FooTest", "A"); + state_.AddTestName("foo.cc", 0, "FooTest", "B"); + state_.AddTestName("foo.cc", 0, "FooTest", "C"); + } + + TypedTestCasePState state_; +}; + +TEST_F(TypedTestCasePStateTest, SucceedsForMatchingList) { + const char* tests = "A, B, C"; + EXPECT_EQ(tests, + state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); +} + +// Makes sure that the order of the tests and spaces around the names +// don't matter. +TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) { + const char* tests = "A,C, B"; + EXPECT_EQ(tests, + state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); +} + +typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest; + +TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), + "foo\\.cc.1.?: Test A is listed more than once\\."); +} + +TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), + "foo\\.cc.1.?: No test named D can be found in this test case\\."); +} + +TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), + "foo\\.cc.1.?: You forgot to list test B\\."); +} + +// Tests that defining a test for a parameterized test case generates +// a run-time error if the test case has been registered. +TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) { + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); + EXPECT_DEATH_IF_SUPPORTED( + state_.AddTestName("foo.cc", 2, "FooTest", "D"), + "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_CASE_P" + "\\(FooTest, \\.\\.\\.\\)\\."); +} + +// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, +// and SetUp()/TearDown() work correctly in type-parameterized tests. + +template +class DerivedTest : public CommonTest { +}; + +TYPED_TEST_CASE_P(DerivedTest); + +TYPED_TEST_P(DerivedTest, ValuesAreCorrect) { + // Static members of the fixture class template can be visited via + // the TestFixture:: prefix. + EXPECT_EQ(5, *TestFixture::shared_); + + // Non-static members of the fixture class must be visited via + // 'this', as required by C++ for class templates. + EXPECT_EQ(2, this->value_); +} + +// The second test makes sure shared_ is not deleted after the first +// test. +TYPED_TEST_P(DerivedTest, ValuesAreStillCorrect) { + // Static members of the fixture class template can also be visited + // via 'this'. + ASSERT_TRUE(this->shared_ != NULL); + EXPECT_EQ(5, *this->shared_); + EXPECT_EQ(2, this->value_); +} + +REGISTER_TYPED_TEST_CASE_P(DerivedTest, + ValuesAreCorrect, ValuesAreStillCorrect); + +typedef Types MyTwoTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, DerivedTest, MyTwoTypes); + +// Tests that multiple TYPED_TEST_CASE_P's can be defined in the same +// translation unit. + +template +class TypedTestP1 : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP1); + +// For testing that the code between TYPED_TEST_CASE_P() and +// TYPED_TEST_P() is not enclosed in a namespace. +typedef int IntAfterTypedTestCaseP; + +TYPED_TEST_P(TypedTestP1, A) {} +TYPED_TEST_P(TypedTestP1, B) {} + +// For testing that the code between TYPED_TEST_P() and +// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. +typedef int IntBeforeRegisterTypedTestCaseP; + +REGISTER_TYPED_TEST_CASE_P(TypedTestP1, A, B); + +template +class TypedTestP2 : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP2); + +// This also verifies that tests from different type-parameterized +// test cases can share the same name. +TYPED_TEST_P(TypedTestP2, A) {} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP2, A); + +// Verifies that the code between TYPED_TEST_CASE_P() and +// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. +IntAfterTypedTestCaseP after = 0; +IntBeforeRegisterTypedTestCaseP before = 0; + +// Verifies that the last argument of INSTANTIATE_TYPED_TEST_CASE_P() +// can be either a single type or a Types<...> type list. +INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP1, int); +INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP2, Types); + +// Tests that the same type-parameterized test case can be +// instantiated more than once in the same translation unit. +INSTANTIATE_TYPED_TEST_CASE_P(Double, TypedTestP2, Types); + +// Tests that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// (ContainerTest is also instantiated in gtest-typed-test_test.cc.) +typedef Types, std::set > MyContainers; +INSTANTIATE_TYPED_TEST_CASE_P(My, ContainerTest, MyContainers); + +// Tests that a type-parameterized test case can be defined and +// instantiated in a namespace. + +namespace library2 { + +template +class NumericTest : public Test { +}; + +TYPED_TEST_CASE_P(NumericTest); + +TYPED_TEST_P(NumericTest, DefaultIsZero) { + EXPECT_EQ(0, TypeParam()); +} + +TYPED_TEST_P(NumericTest, ZeroIsLessThanOne) { + EXPECT_LT(TypeParam(0), TypeParam(1)); +} + +REGISTER_TYPED_TEST_CASE_P(NumericTest, + DefaultIsZero, ZeroIsLessThanOne); +typedef Types NumericTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes); + +} // namespace library2 + +#endif // GTEST_HAS_TYPED_TEST_P + +#if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) + +// Google Test may not support type-parameterized tests with some +// compilers. If we use conditional compilation to compile out all +// code referring to the gtest_main library, MSVC linker will not link +// that library at all and consequently complain about missing entry +// point defined in that library (fatal error LNK1561: entry point +// must be defined). This dummy test keeps gtest_main linked in. +TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {} + +#endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test_test.h b/cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test_test.h new file mode 100644 index 0000000..41d7570 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-typed-test_test.h @@ -0,0 +1,66 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ +#define GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ + +#include "gtest/gtest.h" + +#if GTEST_HAS_TYPED_TEST_P + +using testing::Test; + +// For testing that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// ContainerTest will be instantiated in both gtest-typed-test_test.cc +// and gtest-typed-test2_test.cc. + +template +class ContainerTest : public Test { +}; + +TYPED_TEST_CASE_P(ContainerTest); + +TYPED_TEST_P(ContainerTest, CanBeDefaultConstructed) { + TypeParam container; +} + +TYPED_TEST_P(ContainerTest, InitialSizeIsZero) { + TypeParam container; + EXPECT_EQ(0U, container.size()); +} + +REGISTER_TYPED_TEST_CASE_P(ContainerTest, + CanBeDefaultConstructed, InitialSizeIsZero); + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest-unittest-api_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest-unittest-api_test.cc new file mode 100644 index 0000000..07083e5 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest-unittest-api_test.cc @@ -0,0 +1,341 @@ +// Copyright 2009 Google Inc. All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This file contains tests verifying correctness of data provided via +// UnitTest's public methods. + +#include "gtest/gtest.h" + +#include // For strcmp. +#include + +using ::testing::InitGoogleTest; + +namespace testing { +namespace internal { + +template +struct LessByName { + bool operator()(const T* a, const T* b) { + return strcmp(a->name(), b->name()) < 0; + } +}; + +class UnitTestHelper { + public: + // Returns the array of pointers to all test cases sorted by the test case + // name. The caller is responsible for deleting the array. + static TestCase const** const GetSortedTestCases() { + UnitTest& unit_test = *UnitTest::GetInstance(); + TestCase const** const test_cases = + new const TestCase*[unit_test.total_test_case_count()]; + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + test_cases[i] = unit_test.GetTestCase(i); + + std::sort(test_cases, + test_cases + unit_test.total_test_case_count(), + LessByName()); + return test_cases; + } + + // Returns the test case by its name. The caller doesn't own the returned + // pointer. + static const TestCase* FindTestCase(const char* name) { + UnitTest& unit_test = *UnitTest::GetInstance(); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase* test_case = unit_test.GetTestCase(i); + if (0 == strcmp(test_case->name(), name)) + return test_case; + } + return NULL; + } + + // Returns the array of pointers to all tests in a particular test case + // sorted by the test name. The caller is responsible for deleting the + // array. + static TestInfo const** const GetSortedTests(const TestCase* test_case) { + TestInfo const** const tests = + new const TestInfo*[test_case->total_test_count()]; + + for (int i = 0; i < test_case->total_test_count(); ++i) + tests[i] = test_case->GetTestInfo(i); + + std::sort(tests, tests + test_case->total_test_count(), + LessByName()); + return tests; + } +}; + +#if GTEST_HAS_TYPED_TEST +template class TestCaseWithCommentTest : public Test {}; +TYPED_TEST_CASE(TestCaseWithCommentTest, Types); +TYPED_TEST(TestCaseWithCommentTest, Dummy) {} + +const int kTypedTestCases = 1; +const int kTypedTests = 1; +#else +const int kTypedTestCases = 0; +const int kTypedTests = 0; +#endif // GTEST_HAS_TYPED_TEST + +// We can only test the accessors that do not change value while tests run. +// Since tests can be run in any order, the values the accessors that track +// test execution (such as failed_test_count) can not be predicted. +TEST(ApiTest, UnitTestImmutableAccessorsWork) { + UnitTest* unit_test = UnitTest::GetInstance(); + + ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); + EXPECT_EQ(1 + kTypedTestCases, unit_test->test_case_to_run_count()); + EXPECT_EQ(2, unit_test->disabled_test_count()); + EXPECT_EQ(5 + kTypedTests, unit_test->total_test_count()); + EXPECT_EQ(3 + kTypedTests, unit_test->test_to_run_count()); + + const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); + + EXPECT_STREQ("ApiTest", test_cases[0]->name()); + EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); +#if GTEST_HAS_TYPED_TEST + EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); +#endif // GTEST_HAS_TYPED_TEST + + delete[] test_cases; + + // The following lines initiate actions to verify certain methods in + // FinalSuccessChecker::TearDown. + + // Records a test property to verify TestResult::GetTestProperty(). + RecordProperty("key", "value"); +} + +AssertionResult IsNull(const char* str) { + if (str != NULL) { + return testing::AssertionFailure() << "argument is " << str; + } + return AssertionSuccess(); +} + +TEST(ApiTest, TestCaseImmutableAccessorsWork) { + const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("ApiTest", test_case->name()); + EXPECT_TRUE(IsNull(test_case->type_param())); + EXPECT_TRUE(test_case->should_run()); + EXPECT_EQ(1, test_case->disabled_test_count()); + EXPECT_EQ(3, test_case->test_to_run_count()); + ASSERT_EQ(4, test_case->total_test_count()); + + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); + + EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); + EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_TRUE(IsNull(tests[0]->type_param())); + EXPECT_FALSE(tests[0]->should_run()); + + EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); + EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); + EXPECT_TRUE(IsNull(tests[1]->value_param())); + EXPECT_TRUE(IsNull(tests[1]->type_param())); + EXPECT_TRUE(tests[1]->should_run()); + + EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); + EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); + EXPECT_TRUE(IsNull(tests[2]->value_param())); + EXPECT_TRUE(IsNull(tests[2]->type_param())); + EXPECT_TRUE(tests[2]->should_run()); + + EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); + EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); + EXPECT_TRUE(IsNull(tests[3]->value_param())); + EXPECT_TRUE(IsNull(tests[3]->type_param())); + EXPECT_TRUE(tests[3]->should_run()); + + delete[] tests; + tests = NULL; + +#if GTEST_HAS_TYPED_TEST + test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name()); + EXPECT_STREQ(GetTypeName().c_str(), test_case->type_param()); + EXPECT_TRUE(test_case->should_run()); + EXPECT_EQ(0, test_case->disabled_test_count()); + EXPECT_EQ(1, test_case->test_to_run_count()); + ASSERT_EQ(1, test_case->total_test_count()); + + tests = UnitTestHelper::GetSortedTests(test_case); + + EXPECT_STREQ("Dummy", tests[0]->name()); + EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); + EXPECT_TRUE(tests[0]->should_run()); + + delete[] tests; +#endif // GTEST_HAS_TYPED_TEST +} + +TEST(ApiTest, TestCaseDisabledAccessorsWork) { + const TestCase* test_case = UnitTestHelper::FindTestCase("DISABLED_Test"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("DISABLED_Test", test_case->name()); + EXPECT_TRUE(IsNull(test_case->type_param())); + EXPECT_FALSE(test_case->should_run()); + EXPECT_EQ(1, test_case->disabled_test_count()); + EXPECT_EQ(0, test_case->test_to_run_count()); + ASSERT_EQ(1, test_case->total_test_count()); + + const TestInfo* const test_info = test_case->GetTestInfo(0); + EXPECT_STREQ("Dummy2", test_info->name()); + EXPECT_STREQ("DISABLED_Test", test_info->test_case_name()); + EXPECT_TRUE(IsNull(test_info->value_param())); + EXPECT_TRUE(IsNull(test_info->type_param())); + EXPECT_FALSE(test_info->should_run()); +} + +// These two tests are here to provide support for testing +// test_case_to_run_count, disabled_test_count, and test_to_run_count. +TEST(ApiTest, DISABLED_Dummy1) {} +TEST(DISABLED_Test, Dummy2) {} + +class FinalSuccessChecker : public Environment { + protected: + virtual void TearDown() { + UnitTest* unit_test = UnitTest::GetInstance(); + + EXPECT_EQ(1 + kTypedTestCases, unit_test->successful_test_case_count()); + EXPECT_EQ(3 + kTypedTests, unit_test->successful_test_count()); + EXPECT_EQ(0, unit_test->failed_test_case_count()); + EXPECT_EQ(0, unit_test->failed_test_count()); + EXPECT_TRUE(unit_test->Passed()); + EXPECT_FALSE(unit_test->Failed()); + ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); + + const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); + + EXPECT_STREQ("ApiTest", test_cases[0]->name()); + EXPECT_TRUE(IsNull(test_cases[0]->type_param())); + EXPECT_TRUE(test_cases[0]->should_run()); + EXPECT_EQ(1, test_cases[0]->disabled_test_count()); + ASSERT_EQ(4, test_cases[0]->total_test_count()); + EXPECT_EQ(3, test_cases[0]->successful_test_count()); + EXPECT_EQ(0, test_cases[0]->failed_test_count()); + EXPECT_TRUE(test_cases[0]->Passed()); + EXPECT_FALSE(test_cases[0]->Failed()); + + EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); + EXPECT_TRUE(IsNull(test_cases[1]->type_param())); + EXPECT_FALSE(test_cases[1]->should_run()); + EXPECT_EQ(1, test_cases[1]->disabled_test_count()); + ASSERT_EQ(1, test_cases[1]->total_test_count()); + EXPECT_EQ(0, test_cases[1]->successful_test_count()); + EXPECT_EQ(0, test_cases[1]->failed_test_count()); + +#if GTEST_HAS_TYPED_TEST + EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); + EXPECT_STREQ(GetTypeName().c_str(), test_cases[2]->type_param()); + EXPECT_TRUE(test_cases[2]->should_run()); + EXPECT_EQ(0, test_cases[2]->disabled_test_count()); + ASSERT_EQ(1, test_cases[2]->total_test_count()); + EXPECT_EQ(1, test_cases[2]->successful_test_count()); + EXPECT_EQ(0, test_cases[2]->failed_test_count()); + EXPECT_TRUE(test_cases[2]->Passed()); + EXPECT_FALSE(test_cases[2]->Failed()); +#endif // GTEST_HAS_TYPED_TEST + + const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); + EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); + EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); + EXPECT_FALSE(tests[0]->should_run()); + + EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); + EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); + EXPECT_TRUE(IsNull(tests[1]->value_param())); + EXPECT_TRUE(IsNull(tests[1]->type_param())); + EXPECT_TRUE(tests[1]->should_run()); + EXPECT_TRUE(tests[1]->result()->Passed()); + EXPECT_EQ(0, tests[1]->result()->test_property_count()); + + EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); + EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); + EXPECT_TRUE(IsNull(tests[2]->value_param())); + EXPECT_TRUE(IsNull(tests[2]->type_param())); + EXPECT_TRUE(tests[2]->should_run()); + EXPECT_TRUE(tests[2]->result()->Passed()); + EXPECT_EQ(0, tests[2]->result()->test_property_count()); + + EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); + EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); + EXPECT_TRUE(IsNull(tests[3]->value_param())); + EXPECT_TRUE(IsNull(tests[3]->type_param())); + EXPECT_TRUE(tests[3]->should_run()); + EXPECT_TRUE(tests[3]->result()->Passed()); + EXPECT_EQ(1, tests[3]->result()->test_property_count()); + const TestProperty& property = tests[3]->result()->GetTestProperty(0); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value", property.value()); + + delete[] tests; + +#if GTEST_HAS_TYPED_TEST + test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); + tests = UnitTestHelper::GetSortedTests(test_case); + + EXPECT_STREQ("Dummy", tests[0]->name()); + EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); + EXPECT_TRUE(tests[0]->should_run()); + EXPECT_TRUE(tests[0]->result()->Passed()); + EXPECT_EQ(0, tests[0]->result()->test_property_count()); + + delete[] tests; +#endif // GTEST_HAS_TYPED_TEST + delete[] test_cases; + } +}; + +} // namespace internal +} // namespace testing + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + AddGlobalTestEnvironment(new testing::internal::FinalSuccessChecker()); + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_all_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_all_test.cc new file mode 100644 index 0000000..955aa62 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_all_test.cc @@ -0,0 +1,47 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build most of Google Test's own tests +// by compiling a single file. This file serves this purpose. +#include "test/gtest-filepath_test.cc" +#include "test/gtest-linked_ptr_test.cc" +#include "test/gtest-message_test.cc" +#include "test/gtest-options_test.cc" +#include "test/gtest-port_test.cc" +#include "test/gtest_pred_impl_unittest.cc" +#include "test/gtest_prod_test.cc" +#include "test/gtest-test-part_test.cc" +#include "test/gtest-typed-test_test.cc" +#include "test/gtest-typed-test2_test.cc" +#include "test/gtest_unittest.cc" +#include "test/production.cc" diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_break_on_failure_unittest.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_break_on_failure_unittest.py new file mode 100755 index 0000000..78f3e0f --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_break_on_failure_unittest.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test for Google Test's break-on-failure mode. + +A user can ask Google Test to seg-fault when an assertion fails, using +either the GTEST_BREAK_ON_FAILURE environment variable or the +--gtest_break_on_failure flag. This script tests such functionality +by invoking gtest_break_on_failure_unittest_ (a program written with +Google Test) with different environments and command line flags. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils +import os +import sys + + +# Constants. + +IS_WINDOWS = os.name == 'nt' + +# The environment variable for enabling/disabling the break-on-failure mode. +BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE' + +# The command line flag for enabling/disabling the break-on-failure mode. +BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure' + +# The environment variable for enabling/disabling the throw-on-failure mode. +THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE' + +# The environment variable for enabling/disabling the catch-exceptions mode. +CATCH_EXCEPTIONS_ENV_VAR = 'GTEST_CATCH_EXCEPTIONS' + +# Path to the gtest_break_on_failure_unittest_ program. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_break_on_failure_unittest_') + + +environ = gtest_test_utils.environ +SetEnvVar = gtest_test_utils.SetEnvVar + +# Tests in this file run a Google-Test-based test program and expect it +# to terminate prematurely. Therefore they are incompatible with +# the premature-exit-file protocol by design. Unset the +# premature-exit filepath to prevent Google Test from creating +# the file. +SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) + + +def Run(command): + """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise.""" + + p = gtest_test_utils.Subprocess(command, env=environ) + if p.terminated_by_signal: + return 1 + else: + return 0 + + +# The tests. + + +class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase): + """Tests using the GTEST_BREAK_ON_FAILURE environment variable or + the --gtest_break_on_failure flag to turn assertion failures into + segmentation faults. + """ + + def RunAndVerify(self, env_var_value, flag_value, expect_seg_fault): + """Runs gtest_break_on_failure_unittest_ and verifies that it does + (or does not) have a seg-fault. + + Args: + env_var_value: value of the GTEST_BREAK_ON_FAILURE environment + variable; None if the variable should be unset. + flag_value: value of the --gtest_break_on_failure flag; + None if the flag should not be present. + expect_seg_fault: 1 if the program is expected to generate a seg-fault; + 0 otherwise. + """ + + SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, env_var_value) + + if env_var_value is None: + env_var_value_msg = ' is not set' + else: + env_var_value_msg = '=' + env_var_value + + if flag_value is None: + flag = '' + elif flag_value == '0': + flag = '--%s=0' % BREAK_ON_FAILURE_FLAG + else: + flag = '--%s' % BREAK_ON_FAILURE_FLAG + + command = [EXE_PATH] + if flag: + command.append(flag) + + if expect_seg_fault: + should_or_not = 'should' + else: + should_or_not = 'should not' + + has_seg_fault = Run(command) + + SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None) + + msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' % + (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command), + should_or_not)) + self.assert_(has_seg_fault == expect_seg_fault, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(env_var_value=None, + flag_value=None, + expect_seg_fault=0) + + def testEnvVar(self): + """Tests using the GTEST_BREAK_ON_FAILURE environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value=None, + expect_seg_fault=0) + self.RunAndVerify(env_var_value='1', + flag_value=None, + expect_seg_fault=1) + + def testFlag(self): + """Tests using the --gtest_break_on_failure flag.""" + + self.RunAndVerify(env_var_value=None, + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value=None, + flag_value='1', + expect_seg_fault=1) + + def testFlagOverridesEnvVar(self): + """Tests that the flag overrides the environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value='0', + flag_value='1', + expect_seg_fault=1) + self.RunAndVerify(env_var_value='1', + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value='1', + flag_value='1', + expect_seg_fault=1) + + def testBreakOnFailureOverridesThrowOnFailure(self): + """Tests that gtest_break_on_failure overrides gtest_throw_on_failure.""" + + SetEnvVar(THROW_ON_FAILURE_ENV_VAR, '1') + try: + self.RunAndVerify(env_var_value=None, + flag_value='1', + expect_seg_fault=1) + finally: + SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None) + + if IS_WINDOWS: + def testCatchExceptionsDoesNotInterfere(self): + """Tests that gtest_catch_exceptions doesn't interfere.""" + + SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, '1') + try: + self.RunAndVerify(env_var_value='1', + flag_value='1', + expect_seg_fault=1) + finally: + SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, None) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_break_on_failure_unittest_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_break_on_failure_unittest_.cc new file mode 100644 index 0000000..dd07478 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_break_on_failure_unittest_.cc @@ -0,0 +1,88 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Unit test for Google Test's break-on-failure mode. +// +// A user can ask Google Test to seg-fault when an assertion fails, using +// either the GTEST_BREAK_ON_FAILURE environment variable or the +// --gtest_break_on_failure flag. This file is used for testing such +// functionality. +// +// This program will be invoked from a Python unit test. It is +// expected to fail. Don't run it directly. + +#include "gtest/gtest.h" + +#if GTEST_OS_WINDOWS +# include +# include +#endif + +namespace { + +// A test that's expected to fail. +TEST(Foo, Bar) { + EXPECT_EQ(2, 3); +} + +#if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE +// On Windows Mobile global exception handlers are not supported. +LONG WINAPI ExitWithExceptionCode( + struct _EXCEPTION_POINTERS* exception_pointers) { + exit(exception_pointers->ExceptionRecord->ExceptionCode); +} +#endif + +} // namespace + +int main(int argc, char **argv) { +#if GTEST_OS_WINDOWS + // Suppresses display of the Windows error dialog upon encountering + // a general protection fault (segment violation). + SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); + +# if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE + + // The default unhandled exception filter does not always exit + // with the exception code as exit code - for example it exits with + // 0 for EXCEPTION_ACCESS_VIOLATION and 1 for EXCEPTION_BREAKPOINT + // if the application is compiled in debug mode. Thus we use our own + // filter which always exits with the exception code for unhandled + // exceptions. + SetUnhandledExceptionFilter(ExitWithExceptionCode); + +# endif +#endif + + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_catch_exceptions_test.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_catch_exceptions_test.py new file mode 100755 index 0000000..e6fc22f --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_catch_exceptions_test.py @@ -0,0 +1,237 @@ +#!/usr/bin/env python +# +# Copyright 2010 Google Inc. All Rights Reserved. +# +# 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. + +"""Tests Google Test's exception catching behavior. + +This script invokes gtest_catch_exceptions_test_ and +gtest_catch_exceptions_ex_test_ (programs written with +Google Test) and verifies their output. +""" + +__author__ = 'vladl@google.com (Vlad Losev)' + +import os + +import gtest_test_utils + +# Constants. +FLAG_PREFIX = '--gtest_' +LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' +NO_CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions=0' +FILTER_FLAG = FLAG_PREFIX + 'filter' + +# Path to the gtest_catch_exceptions_ex_test_ binary, compiled with +# exceptions enabled. +EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_catch_exceptions_ex_test_') + +# Path to the gtest_catch_exceptions_test_ binary, compiled with +# exceptions disabled. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_catch_exceptions_no_ex_test_') + +environ = gtest_test_utils.environ +SetEnvVar = gtest_test_utils.SetEnvVar + +# Tests in this file run a Google-Test-based test program and expect it +# to terminate prematurely. Therefore they are incompatible with +# the premature-exit-file protocol by design. Unset the +# premature-exit filepath to prevent Google Test from creating +# the file. +SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) + +TEST_LIST = gtest_test_utils.Subprocess( + [EXE_PATH, LIST_TESTS_FLAG], env=environ).output + +SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST + +if SUPPORTS_SEH_EXCEPTIONS: + BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH], env=environ).output + +EX_BINARY_OUTPUT = gtest_test_utils.Subprocess( + [EX_EXE_PATH], env=environ).output + + +# The tests. +if SUPPORTS_SEH_EXCEPTIONS: + # pylint:disable-msg=C6302 + class CatchSehExceptionsTest(gtest_test_utils.TestCase): + """Tests exception-catching behavior.""" + + + def TestSehExceptions(self, test_output): + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s constructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s destructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUpTestCase()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDownTestCase()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUp()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDown()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in the test body' + in test_output) + + def testCatchesSehExceptionsWithCxxExceptionsEnabled(self): + self.TestSehExceptions(EX_BINARY_OUTPUT) + + def testCatchesSehExceptionsWithCxxExceptionsDisabled(self): + self.TestSehExceptions(BINARY_OUTPUT) + + +class CatchCxxExceptionsTest(gtest_test_utils.TestCase): + """Tests C++ exception-catching behavior. + + Tests in this test case verify that: + * C++ exceptions are caught and logged as C++ (not SEH) exceptions + * Exception thrown affect the remainder of the test work flow in the + expected manner. + """ + + def testCatchesCxxExceptionsInFixtureConstructor(self): + self.assert_('C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s constructor' + in EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInConstructorTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in + EX_BINARY_OUTPUT): + + def testCatchesCxxExceptionsInFixtureDestructor(self): + self.assert_('C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s destructor' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUpTestCase(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in SetUpTestCase()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInConstructorTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest constructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest::SetUp() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest test body ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTearDownTestCase(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in TearDownTestCase()' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUp(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in SetUp()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInSetUpTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + def testCatchesCxxExceptionsInTearDown(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in TearDown()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTearDownTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTearDownTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTestBody(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in the test body' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesNonStdCxxExceptions(self): + self.assert_('Unknown C++ exception thrown in the test body' + in EX_BINARY_OUTPUT) + + def testUnhandledCxxExceptionsAbortTheProgram(self): + # Filters out SEH exception tests on Windows. Unhandled SEH exceptions + # cause tests to show pop-up windows there. + FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*' + # By default, Google Test doesn't catch the exceptions. + uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( + [EX_EXE_PATH, + NO_CATCH_EXCEPTIONS_FLAG, + FITLER_OUT_SEH_TESTS_FLAG], + env=environ).output + + self.assert_('Unhandled C++ exception terminating the program' + in uncaught_exceptions_ex_binary_output) + self.assert_('unexpected' not in uncaught_exceptions_ex_binary_output) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_catch_exceptions_test_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_catch_exceptions_test_.cc new file mode 100644 index 0000000..d0fc82c --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_catch_exceptions_test_.cc @@ -0,0 +1,311 @@ +// Copyright 2010, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. Tests in this file throw C++ or SEH +// exceptions, and the output is verified by gtest_catch_exceptions_test.py. + +#include "gtest/gtest.h" + +#include // NOLINT +#include // For exit(). + +#if GTEST_HAS_SEH +# include +#endif + +#if GTEST_HAS_EXCEPTIONS +# include // For set_terminate(). +# include +#endif + +using testing::Test; + +#if GTEST_HAS_SEH + +class SehExceptionInConstructorTest : public Test { + public: + SehExceptionInConstructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInConstructorTest, ThrowsExceptionInConstructor) {} + +class SehExceptionInDestructorTest : public Test { + public: + ~SehExceptionInDestructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInDestructorTest, ThrowsExceptionInDestructor) {} + +class SehExceptionInSetUpTestCaseTest : public Test { + public: + static void SetUpTestCase() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) {} + +class SehExceptionInTearDownTestCaseTest : public Test { + public: + static void TearDownTestCase() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} + +class SehExceptionInSetUpTest : public Test { + protected: + virtual void SetUp() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTest, ThrowsExceptionInSetUp) {} + +class SehExceptionInTearDownTest : public Test { + protected: + virtual void TearDown() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +TEST(SehExceptionTest, ThrowsSehException) { + RaiseException(42, 0, 0, NULL); +} + +#endif // GTEST_HAS_SEH + +#if GTEST_HAS_EXCEPTIONS + +class CxxExceptionInConstructorTest : public Test { + public: + CxxExceptionInConstructorTest() { + // Without this macro VC++ complains about unreachable code at the end of + // the constructor. + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + throw std::runtime_error("Standard C++ exception")); + } + + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInConstructorTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInConstructorTest() { + ADD_FAILURE() << "CxxExceptionInConstructorTest destructor " + << "called unexpectedly."; + } + + virtual void SetUp() { + ADD_FAILURE() << "CxxExceptionInConstructorTest::SetUp() " + << "called unexpectedly."; + } + + virtual void TearDown() { + ADD_FAILURE() << "CxxExceptionInConstructorTest::TearDown() " + << "called unexpectedly."; + } +}; + +TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) { + ADD_FAILURE() << "CxxExceptionInConstructorTest test body " + << "called unexpectedly."; +} + +// Exceptions in destructors are not supported in C++11. +#if !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L +class CxxExceptionInDestructorTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInDestructorTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInDestructorTest() { + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + throw std::runtime_error("Standard C++ exception")); + } +}; + +TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {} +#endif // C++11 mode + +class CxxExceptionInSetUpTestCaseTest : public Test { + public: + CxxExceptionInSetUpTestCaseTest() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest constructor " + "called as expected.\n"); + } + + static void SetUpTestCase() { + throw std::runtime_error("Standard C++ exception"); + } + + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTestCaseTest() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest destructor " + "called as expected.\n"); + } + + virtual void SetUp() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::SetUp() " + "called as expected.\n"); + } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) { + printf("%s", + "CxxExceptionInSetUpTestCaseTest test body " + "called as expected.\n"); +} + +class CxxExceptionInTearDownTestCaseTest : public Test { + public: + static void TearDownTestCase() { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} + +class CxxExceptionInSetUpTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInSetUpTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTest() { + printf("%s", + "CxxExceptionInSetUpTest destructor " + "called as expected.\n"); + } + + virtual void SetUp() { throw std::runtime_error("Standard C++ exception"); } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInSetUpTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTest, ThrowsExceptionInSetUp) { + ADD_FAILURE() << "CxxExceptionInSetUpTest test body " + << "called unexpectedly."; +} + +class CxxExceptionInTearDownTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInTearDownTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTearDownTest() { + printf("%s", + "CxxExceptionInTearDownTest destructor " + "called as expected.\n"); + } + + virtual void TearDown() { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +class CxxExceptionInTestBodyTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInTestBodyTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTestBodyTest() { + printf("%s", + "CxxExceptionInTestBodyTest destructor " + "called as expected.\n"); + } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInTestBodyTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInTestBodyTest, ThrowsStdCxxException) { + throw std::runtime_error("Standard C++ exception"); +} + +TEST(CxxExceptionTest, ThrowsNonStdCxxException) { + throw "C-string"; +} + +// This terminate handler aborts the program using exit() rather than abort(). +// This avoids showing pop-ups on Windows systems and core dumps on Unix-like +// ones. +void TerminateHandler() { + fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); + fflush(NULL); + exit(3); +} + +#endif // GTEST_HAS_EXCEPTIONS + +int main(int argc, char** argv) { +#if GTEST_HAS_EXCEPTIONS + std::set_terminate(&TerminateHandler); +#endif + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_color_test.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_color_test.py new file mode 100755 index 0000000..d02a53e --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_color_test.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""Verifies that Google Test correctly determines whether to use colors.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + + +IS_WINDOWS = os.name = 'nt' + +COLOR_ENV_VAR = 'GTEST_COLOR' +COLOR_FLAG = 'gtest_color' +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_color_test_') + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def UsesColor(term, color_env_var, color_flag): + """Runs gtest_color_test_ and returns its exit code.""" + + SetEnvVar('TERM', term) + SetEnvVar(COLOR_ENV_VAR, color_env_var) + + if color_flag is None: + args = [] + else: + args = ['--%s=%s' % (COLOR_FLAG, color_flag)] + p = gtest_test_utils.Subprocess([COMMAND] + args) + return not p.exited or p.exit_code + + +class GTestColorTest(gtest_test_utils.TestCase): + def testNoEnvVarNoFlag(self): + """Tests the case when there's neither GTEST_COLOR nor --gtest_color.""" + + if not IS_WINDOWS: + self.assert_(not UsesColor('dumb', None, None)) + self.assert_(not UsesColor('emacs', None, None)) + self.assert_(not UsesColor('xterm-mono', None, None)) + self.assert_(not UsesColor('unknown', None, None)) + self.assert_(not UsesColor(None, None, None)) + self.assert_(UsesColor('linux', None, None)) + self.assert_(UsesColor('cygwin', None, None)) + self.assert_(UsesColor('xterm', None, None)) + self.assert_(UsesColor('xterm-color', None, None)) + self.assert_(UsesColor('xterm-256color', None, None)) + + def testFlagOnly(self): + """Tests the case when there's --gtest_color but not GTEST_COLOR.""" + + self.assert_(not UsesColor('dumb', None, 'no')) + self.assert_(not UsesColor('xterm-color', None, 'no')) + if not IS_WINDOWS: + self.assert_(not UsesColor('emacs', None, 'auto')) + self.assert_(UsesColor('xterm', None, 'auto')) + self.assert_(UsesColor('dumb', None, 'yes')) + self.assert_(UsesColor('xterm', None, 'yes')) + + def testEnvVarOnly(self): + """Tests the case when there's GTEST_COLOR but not --gtest_color.""" + + self.assert_(not UsesColor('dumb', 'no', None)) + self.assert_(not UsesColor('xterm-color', 'no', None)) + if not IS_WINDOWS: + self.assert_(not UsesColor('dumb', 'auto', None)) + self.assert_(UsesColor('xterm-color', 'auto', None)) + self.assert_(UsesColor('dumb', 'yes', None)) + self.assert_(UsesColor('xterm-color', 'yes', None)) + + def testEnvVarAndFlag(self): + """Tests the case when there are both GTEST_COLOR and --gtest_color.""" + + self.assert_(not UsesColor('xterm-color', 'no', 'no')) + self.assert_(UsesColor('dumb', 'no', 'yes')) + self.assert_(UsesColor('xterm-color', 'no', 'auto')) + + def testAliasesOfYesAndNo(self): + """Tests using aliases in specifying --gtest_color.""" + + self.assert_(UsesColor('dumb', None, 'true')) + self.assert_(UsesColor('dumb', None, 'YES')) + self.assert_(UsesColor('dumb', None, 'T')) + self.assert_(UsesColor('dumb', None, '1')) + + self.assert_(not UsesColor('xterm', None, 'f')) + self.assert_(not UsesColor('xterm', None, 'false')) + self.assert_(not UsesColor('xterm', None, '0')) + self.assert_(not UsesColor('xterm', None, 'unknown')) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_color_test_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_color_test_.cc new file mode 100644 index 0000000..f61ebb8 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_color_test_.cc @@ -0,0 +1,71 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// A helper program for testing how Google Test determines whether to use +// colors in the output. It prints "YES" and returns 1 if Google Test +// decides to use colors, and prints "NO" and returns 0 otherwise. + +#include + +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +using testing::internal::ShouldUseColor; + +// The purpose of this is to ensure that the UnitTest singleton is +// created before main() is entered, and thus that ShouldUseColor() +// works the same way as in a real Google-Test-based test. We don't actual +// run the TEST itself. +TEST(GTestColorTest, Dummy) { +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + if (ShouldUseColor(true)) { + // Google Test decides to use colors in the output (assuming it + // goes to a TTY). + printf("YES\n"); + return 1; + } else { + // Google Test decides not to use colors in the output. + printf("NO\n"); + return 0; + } +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_env_var_test.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_env_var_test.py new file mode 100755 index 0000000..ac24337 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_env_var_test.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""Verifies that Google Test correctly parses environment variables.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + + +IS_WINDOWS = os.name == 'nt' +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' + +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_') + +environ = os.environ.copy() + + +def AssertEq(expected, actual): + if expected != actual: + print 'Expected: %s' % (expected,) + print ' Actual: %s' % (actual,) + raise AssertionError + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +def GetFlag(flag): + """Runs gtest_env_var_test_ and returns its output.""" + + args = [COMMAND] + if flag is not None: + args += [flag] + return gtest_test_utils.Subprocess(args, env=environ).output + + +def TestFlag(flag, test_val, default_val): + """Verifies that the given flag is affected by the corresponding env var.""" + + env_var = 'GTEST_' + flag.upper() + SetEnvVar(env_var, test_val) + AssertEq(test_val, GetFlag(flag)) + SetEnvVar(env_var, None) + AssertEq(default_val, GetFlag(flag)) + + +class GTestEnvVarTest(gtest_test_utils.TestCase): + def testEnvVarAffectsFlag(self): + """Tests that environment variable should affect the corresponding flag.""" + + TestFlag('break_on_failure', '1', '0') + TestFlag('color', 'yes', 'auto') + TestFlag('filter', 'FooTest.Bar', '*') + TestFlag('output', 'xml:tmp/foo.xml', '') + TestFlag('print_time', '0', '1') + TestFlag('repeat', '999', '1') + TestFlag('throw_on_failure', '1', '0') + TestFlag('death_test_style', 'threadsafe', 'fast') + TestFlag('catch_exceptions', '0', '1') + + if IS_LINUX: + TestFlag('death_test_use_fork', '1', '0') + TestFlag('stack_trace_depth', '0', '100') + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_env_var_test_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_env_var_test_.cc new file mode 100644 index 0000000..539afc9 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_env_var_test_.cc @@ -0,0 +1,126 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// A helper program for testing that Google Test parses the environment +// variables correctly. + +#include "gtest/gtest.h" + +#include + +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +using ::std::cout; + +namespace testing { + +// The purpose of this is to make the test more realistic by ensuring +// that the UnitTest singleton is created before main() is entered. +// We don't actual run the TEST itself. +TEST(GTestEnvVarTest, Dummy) { +} + +void PrintFlag(const char* flag) { + if (strcmp(flag, "break_on_failure") == 0) { + cout << GTEST_FLAG(break_on_failure); + return; + } + + if (strcmp(flag, "catch_exceptions") == 0) { + cout << GTEST_FLAG(catch_exceptions); + return; + } + + if (strcmp(flag, "color") == 0) { + cout << GTEST_FLAG(color); + return; + } + + if (strcmp(flag, "death_test_style") == 0) { + cout << GTEST_FLAG(death_test_style); + return; + } + + if (strcmp(flag, "death_test_use_fork") == 0) { + cout << GTEST_FLAG(death_test_use_fork); + return; + } + + if (strcmp(flag, "filter") == 0) { + cout << GTEST_FLAG(filter); + return; + } + + if (strcmp(flag, "output") == 0) { + cout << GTEST_FLAG(output); + return; + } + + if (strcmp(flag, "print_time") == 0) { + cout << GTEST_FLAG(print_time); + return; + } + + if (strcmp(flag, "repeat") == 0) { + cout << GTEST_FLAG(repeat); + return; + } + + if (strcmp(flag, "stack_trace_depth") == 0) { + cout << GTEST_FLAG(stack_trace_depth); + return; + } + + if (strcmp(flag, "throw_on_failure") == 0) { + cout << GTEST_FLAG(throw_on_failure); + return; + } + + cout << "Invalid flag name " << flag + << ". Valid names are break_on_failure, color, filter, etc.\n"; + exit(1); +} + +} // namespace testing + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + if (argc != 2) { + cout << "Usage: gtest_env_var_test_ NAME_OF_FLAG\n"; + return 1; + } + + testing::PrintFlag(argv[1]); + return 0; +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_environment_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_environment_test.cc new file mode 100644 index 0000000..3cff19e --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_environment_test.cc @@ -0,0 +1,192 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests using global test environments. + +#include +#include +#include "gtest/gtest.h" + +#define GTEST_IMPLEMENTATION_ 1 // Required for the next #include. +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +GTEST_DECLARE_string_(filter); +} + +namespace { + +enum FailureType { + NO_FAILURE, NON_FATAL_FAILURE, FATAL_FAILURE +}; + +// For testing using global test environments. +class MyEnvironment : public testing::Environment { + public: + MyEnvironment() { Reset(); } + + // Depending on the value of failure_in_set_up_, SetUp() will + // generate a non-fatal failure, generate a fatal failure, or + // succeed. + virtual void SetUp() { + set_up_was_run_ = true; + + switch (failure_in_set_up_) { + case NON_FATAL_FAILURE: + ADD_FAILURE() << "Expected non-fatal failure in global set-up."; + break; + case FATAL_FAILURE: + FAIL() << "Expected fatal failure in global set-up."; + break; + default: + break; + } + } + + // Generates a non-fatal failure. + virtual void TearDown() { + tear_down_was_run_ = true; + ADD_FAILURE() << "Expected non-fatal failure in global tear-down."; + } + + // Resets the state of the environment s.t. it can be reused. + void Reset() { + failure_in_set_up_ = NO_FAILURE; + set_up_was_run_ = false; + tear_down_was_run_ = false; + } + + // We call this function to set the type of failure SetUp() should + // generate. + void set_failure_in_set_up(FailureType type) { + failure_in_set_up_ = type; + } + + // Was SetUp() run? + bool set_up_was_run() const { return set_up_was_run_; } + + // Was TearDown() run? + bool tear_down_was_run() const { return tear_down_was_run_; } + + private: + FailureType failure_in_set_up_; + bool set_up_was_run_; + bool tear_down_was_run_; +}; + +// Was the TEST run? +bool test_was_run; + +// The sole purpose of this TEST is to enable us to check whether it +// was run. +TEST(FooTest, Bar) { + test_was_run = true; +} + +// Prints the message and aborts the program if condition is false. +void Check(bool condition, const char* msg) { + if (!condition) { + printf("FAILED: %s\n", msg); + testing::internal::posix::Abort(); + } +} + +// Runs the tests. Return true iff successful. +// +// The 'failure' parameter specifies the type of failure that should +// be generated by the global set-up. +int RunAllTests(MyEnvironment* env, FailureType failure) { + env->Reset(); + env->set_failure_in_set_up(failure); + test_was_run = false; + testing::internal::GetUnitTestImpl()->ClearAdHocTestResult(); + return RUN_ALL_TESTS(); +} + +} // namespace + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + // Registers a global test environment, and verifies that the + // registration function returns its argument. + MyEnvironment* const env = new MyEnvironment; + Check(testing::AddGlobalTestEnvironment(env) == env, + "AddGlobalTestEnvironment() should return its argument."); + + // Verifies that RUN_ALL_TESTS() runs the tests when the global + // set-up is successful. + Check(RunAllTests(env, NO_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as the global tear-down " + "should generate a failure."); + Check(test_was_run, + "The tests should run, as the global set-up should generate no " + "failure"); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() runs the tests when the global + // set-up generates no fatal failure. + Check(RunAllTests(env, NON_FATAL_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as both the global set-up " + "and the global tear-down should generate a non-fatal failure."); + Check(test_was_run, + "The tests should run, as the global set-up should generate no " + "fatal failure."); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() runs no test when the global set-up + // generates a fatal failure. + Check(RunAllTests(env, FATAL_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as the global set-up " + "should generate a fatal failure."); + Check(!test_was_run, + "The tests should not run, as the global set-up should generate " + "a fatal failure."); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() doesn't do global set-up or + // tear-down when there is no test to run. + testing::GTEST_FLAG(filter) = "-*"; + Check(RunAllTests(env, NO_FAILURE) == 0, + "RUN_ALL_TESTS() should return zero, as there is no test to run."); + Check(!env->set_up_was_run(), + "The global set-up should not run, as there is no test to run."); + Check(!env->tear_down_was_run(), + "The global tear-down should not run, " + "as the global set-up was not run."); + + printf("PASS\n"); + return 0; +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_filter_unittest.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_filter_unittest.py new file mode 100755 index 0000000..0d1a770 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_filter_unittest.py @@ -0,0 +1,633 @@ +#!/usr/bin/env python +# +# Copyright 2005 Google Inc. All Rights Reserved. +# +# 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. + +"""Unit test for Google Test test filters. + +A user can specify which test(s) in a Google Test program to run via either +the GTEST_FILTER environment variable or the --gtest_filter flag. +This script tests such functionality by invoking +gtest_filter_unittest_ (a program written with Google Test) with different +environments and command line flags. + +Note that test sharding may also influence which tests are filtered. Therefore, +we test that here also. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sets +import sys + +import gtest_test_utils + +# Constants. + +# Checks if this platform can pass empty environment variables to child +# processes. We set an env variable to an empty string and invoke a python +# script in a subprocess to print whether the variable is STILL in +# os.environ. We then use 'eval' to parse the child's output so that an +# exception is thrown if the input is anything other than 'True' nor 'False'. +os.environ['EMPTY_VAR'] = '' +child = gtest_test_utils.Subprocess( + [sys.executable, '-c', 'import os; print \'EMPTY_VAR\' in os.environ']) +CAN_PASS_EMPTY_ENV = eval(child.output) + + +# Check if this platform can unset environment variables in child processes. +# We set an env variable to a non-empty string, unset it, and invoke +# a python script in a subprocess to print whether the variable +# is NO LONGER in os.environ. +# We use 'eval' to parse the child's output so that an exception +# is thrown if the input is neither 'True' nor 'False'. +os.environ['UNSET_VAR'] = 'X' +del os.environ['UNSET_VAR'] +child = gtest_test_utils.Subprocess( + [sys.executable, '-c', 'import os; print \'UNSET_VAR\' not in os.environ']) +CAN_UNSET_ENV = eval(child.output) + + +# Checks if we should test with an empty filter. This doesn't +# make sense on platforms that cannot pass empty env variables (Win32) +# and on platforms that cannot unset variables (since we cannot tell +# the difference between "" and NULL -- Borland and Solaris < 5.10) +CAN_TEST_EMPTY_FILTER = (CAN_PASS_EMPTY_ENV and CAN_UNSET_ENV) + + +# The environment variable for specifying the test filters. +FILTER_ENV_VAR = 'GTEST_FILTER' + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' +SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE' + +# The command line flag for specifying the test filters. +FILTER_FLAG = 'gtest_filter' + +# The command line flag for including disabled tests. +ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests' + +# Command to run the gtest_filter_unittest_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_') + +# Regex for determining whether parameterized tests are enabled in the binary. +PARAM_TEST_REGEX = re.compile(r'/ParamTest') + +# Regex for parsing test case names from Google Test's output. +TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)') + +# Regex for parsing test names from Google Test's output. +TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)') + +# The command line flag to tell Google Test to output the list of tests it +# will run. +LIST_TESTS_FLAG = '--gtest_list_tests' + +# Indicates whether Google Test supports death tests. +SUPPORTS_DEATH_TESTS = 'HasDeathTest' in gtest_test_utils.Subprocess( + [COMMAND, LIST_TESTS_FLAG]).output + +# Full names of all tests in gtest_filter_unittests_. +PARAM_TESTS = [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + 'SeqQ/ParamTest.TestX/0', + 'SeqQ/ParamTest.TestX/1', + 'SeqQ/ParamTest.TestY/0', + 'SeqQ/ParamTest.TestY/1', + ] + +DISABLED_TESTS = [ + 'BarTest.DISABLED_TestFour', + 'BarTest.DISABLED_TestFive', + 'BazTest.DISABLED_TestC', + 'DISABLED_FoobarTest.Test1', + 'DISABLED_FoobarTest.DISABLED_Test2', + 'DISABLED_FoobarbazTest.TestA', + ] + +if SUPPORTS_DEATH_TESTS: + DEATH_TESTS = [ + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', + ] +else: + DEATH_TESTS = [] + +# All the non-disabled tests. +ACTIVE_TESTS = [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', + ] + DEATH_TESTS + PARAM_TESTS + +param_tests_present = None + +# Utilities. + +environ = os.environ.copy() + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +def RunAndReturnOutput(args = None): + """Runs the test program and returns its output.""" + + return gtest_test_utils.Subprocess([COMMAND] + (args or []), + env=environ).output + + +def RunAndExtractTestList(args = None): + """Runs the test program and returns its exit code and a list of tests run.""" + + p = gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ) + tests_run = [] + test_case = '' + test = '' + for line in p.output.split('\n'): + match = TEST_CASE_REGEX.match(line) + if match is not None: + test_case = match.group(1) + else: + match = TEST_REGEX.match(line) + if match is not None: + test = match.group(1) + tests_run.append(test_case + '.' + test) + return (tests_run, p.exit_code) + + +def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs): + """Runs the given function and arguments in a modified environment.""" + try: + original_env = environ.copy() + environ.update(extra_env) + return function(*args, **kwargs) + finally: + environ.clear() + environ.update(original_env) + + +def RunWithSharding(total_shards, shard_index, command): + """Runs a test program shard and returns exit code and a list of tests run.""" + + extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index), + TOTAL_SHARDS_ENV_VAR: str(total_shards)} + return InvokeWithModifiedEnv(extra_env, RunAndExtractTestList, command) + +# The unit test. + + +class GTestFilterUnitTest(gtest_test_utils.TestCase): + """Tests the env variable or the command line flag to filter tests.""" + + # Utilities. + + def AssertSetEqual(self, lhs, rhs): + """Asserts that two sets are equal.""" + + for elem in lhs: + self.assert_(elem in rhs, '%s in %s' % (elem, rhs)) + + for elem in rhs: + self.assert_(elem in lhs, '%s in %s' % (elem, lhs)) + + def AssertPartitionIsValid(self, set_var, list_of_sets): + """Asserts that list_of_sets is a valid partition of set_var.""" + + full_partition = [] + for slice_var in list_of_sets: + full_partition.extend(slice_var) + self.assertEqual(len(set_var), len(full_partition)) + self.assertEqual(sets.Set(set_var), sets.Set(full_partition)) + + def AdjustForParameterizedTests(self, tests_to_run): + """Adjust tests_to_run in case value parameterized tests are disabled.""" + + global param_tests_present + if not param_tests_present: + return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS)) + else: + return tests_to_run + + def RunAndVerify(self, gtest_filter, tests_to_run): + """Checks that the binary runs correct set of tests for a given filter.""" + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # First, tests using the environment variable. + + # Windows removes empty variables from the environment when passing it + # to a new process. This means it is impossible to pass an empty filter + # into a process using the environment variable. However, we can still + # test the case when the variable is not supplied (i.e., gtest_filter is + # None). + # pylint: disable-msg=C6403 + if CAN_TEST_EMPTY_FILTER or gtest_filter != '': + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + tests_run = RunAndExtractTestList()[0] + SetEnvVar(FILTER_ENV_VAR, None) + self.AssertSetEqual(tests_run, tests_to_run) + # pylint: enable-msg=C6403 + + # Next, tests using the command line flag. + + if gtest_filter is None: + args = [] + else: + args = ['--%s=%s' % (FILTER_FLAG, gtest_filter)] + + tests_run = RunAndExtractTestList(args)[0] + self.AssertSetEqual(tests_run, tests_to_run) + + def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run, + args=None, check_exit_0=False): + """Checks that binary runs correct tests for the given filter and shard. + + Runs all shards of gtest_filter_unittest_ with the given filter, and + verifies that the right set of tests were run. The union of tests run + on each shard should be identical to tests_to_run, without duplicates. + + Args: + gtest_filter: A filter to apply to the tests. + total_shards: A total number of shards to split test run into. + tests_to_run: A set of tests expected to run. + args : Arguments to pass to the to the test binary. + check_exit_0: When set to a true value, make sure that all shards + return 0. + """ + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # Windows removes empty variables from the environment when passing it + # to a new process. This means it is impossible to pass an empty filter + # into a process using the environment variable. However, we can still + # test the case when the variable is not supplied (i.e., gtest_filter is + # None). + # pylint: disable-msg=C6403 + if CAN_TEST_EMPTY_FILTER or gtest_filter != '': + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + partition = [] + for i in range(0, total_shards): + (tests_run, exit_code) = RunWithSharding(total_shards, i, args) + if check_exit_0: + self.assertEqual(0, exit_code) + partition.append(tests_run) + + self.AssertPartitionIsValid(tests_to_run, partition) + SetEnvVar(FILTER_ENV_VAR, None) + # pylint: enable-msg=C6403 + + def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run): + """Checks that the binary runs correct set of tests for the given filter. + + Runs gtest_filter_unittest_ with the given filter, and enables + disabled tests. Verifies that the right set of tests were run. + + Args: + gtest_filter: A filter to apply to the tests. + tests_to_run: A set of tests expected to run. + """ + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # Construct the command line. + args = ['--%s' % ALSO_RUN_DISABED_TESTS_FLAG] + if gtest_filter is not None: + args.append('--%s=%s' % (FILTER_FLAG, gtest_filter)) + + tests_run = RunAndExtractTestList(args)[0] + self.AssertSetEqual(tests_run, tests_to_run) + + def setUp(self): + """Sets up test case. + + Determines whether value-parameterized tests are enabled in the binary and + sets the flags accordingly. + """ + + global param_tests_present + if param_tests_present is None: + param_tests_present = PARAM_TEST_REGEX.search( + RunAndReturnOutput()) is not None + + def testDefaultBehavior(self): + """Tests the behavior of not specifying the filter.""" + + self.RunAndVerify(None, ACTIVE_TESTS) + + def testDefaultBehaviorWithShards(self): + """Tests the behavior without the filter, with sharding enabled.""" + + self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS), ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) + 1, ACTIVE_TESTS) + + def testEmptyFilter(self): + """Tests an empty filter.""" + + self.RunAndVerify('', []) + self.RunAndVerifyWithSharding('', 1, []) + self.RunAndVerifyWithSharding('', 2, []) + + def testBadFilter(self): + """Tests a filter that matches nothing.""" + + self.RunAndVerify('BadFilter', []) + self.RunAndVerifyAllowingDisabled('BadFilter', []) + + def testFullName(self): + """Tests filtering by full name.""" + + self.RunAndVerify('FooTest.Xyz', ['FooTest.Xyz']) + self.RunAndVerifyAllowingDisabled('FooTest.Xyz', ['FooTest.Xyz']) + self.RunAndVerifyWithSharding('FooTest.Xyz', 5, ['FooTest.Xyz']) + + def testUniversalFilters(self): + """Tests filters that match everything.""" + + self.RunAndVerify('*', ACTIVE_TESTS) + self.RunAndVerify('*.*', ACTIVE_TESTS) + self.RunAndVerifyWithSharding('*.*', len(ACTIVE_TESTS) - 3, ACTIVE_TESTS) + self.RunAndVerifyAllowingDisabled('*', ACTIVE_TESTS + DISABLED_TESTS) + self.RunAndVerifyAllowingDisabled('*.*', ACTIVE_TESTS + DISABLED_TESTS) + + def testFilterByTestCase(self): + """Tests filtering by test case name.""" + + self.RunAndVerify('FooTest.*', ['FooTest.Abc', 'FooTest.Xyz']) + + BAZ_TESTS = ['BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB'] + self.RunAndVerify('BazTest.*', BAZ_TESTS) + self.RunAndVerifyAllowingDisabled('BazTest.*', + BAZ_TESTS + ['BazTest.DISABLED_TestC']) + + def testFilterByTest(self): + """Tests filtering by test name.""" + + self.RunAndVerify('*.TestOne', ['BarTest.TestOne', 'BazTest.TestOne']) + + def testFilterDisabledTests(self): + """Select only the disabled tests to run.""" + + self.RunAndVerify('DISABLED_FoobarTest.Test1', []) + self.RunAndVerifyAllowingDisabled('DISABLED_FoobarTest.Test1', + ['DISABLED_FoobarTest.Test1']) + + self.RunAndVerify('*DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('*DISABLED_*', DISABLED_TESTS) + + self.RunAndVerify('*.DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('*.DISABLED_*', [ + 'BarTest.DISABLED_TestFour', + 'BarTest.DISABLED_TestFive', + 'BazTest.DISABLED_TestC', + 'DISABLED_FoobarTest.DISABLED_Test2', + ]) + + self.RunAndVerify('DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('DISABLED_*', [ + 'DISABLED_FoobarTest.Test1', + 'DISABLED_FoobarTest.DISABLED_Test2', + 'DISABLED_FoobarbazTest.TestA', + ]) + + def testWildcardInTestCaseName(self): + """Tests using wildcard in the test case name.""" + + self.RunAndVerify('*a*.*', [ + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS) + + def testWildcardInTestName(self): + """Tests using wildcard in the test name.""" + + self.RunAndVerify('*.*A*', ['FooTest.Abc', 'BazTest.TestA']) + + def testFilterWithoutDot(self): + """Tests a filter that has no '.' in it.""" + + self.RunAndVerify('*z*', [ + 'FooTest.Xyz', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', + ]) + + def testTwoPatterns(self): + """Tests filters that consist of two patterns.""" + + self.RunAndVerify('Foo*.*:*A*', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BazTest.TestA', + ]) + + # An empty pattern + a non-empty one + self.RunAndVerify(':*A*', ['FooTest.Abc', 'BazTest.TestA']) + + def testThreePatterns(self): + """Tests filters that consist of three patterns.""" + + self.RunAndVerify('*oo*:*A*:*One', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + + 'BazTest.TestOne', + 'BazTest.TestA', + ]) + + # The 2nd pattern is empty. + self.RunAndVerify('*oo*::*One', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + + 'BazTest.TestOne', + ]) + + # The last 2 patterns are empty. + self.RunAndVerify('*oo*::', [ + 'FooTest.Abc', + 'FooTest.Xyz', + ]) + + def testNegativeFilters(self): + self.RunAndVerify('*-BazTest.TestOne', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestA', + 'BazTest.TestB', + ] + DEATH_TESTS + PARAM_TESTS) + + self.RunAndVerify('*-FooTest.Abc:BazTest.*', [ + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + ] + DEATH_TESTS + PARAM_TESTS) + + self.RunAndVerify('BarTest.*-BarTest.TestOne', [ + 'BarTest.TestTwo', + 'BarTest.TestThree', + ]) + + # Tests without leading '*'. + self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:BazTest.*', [ + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + ] + DEATH_TESTS + PARAM_TESTS) + + # Value parameterized tests. + self.RunAndVerify('*/*', PARAM_TESTS) + + # Value parameterized tests filtering by the sequence name. + self.RunAndVerify('SeqP/*', [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + ]) + + # Value parameterized tests filtering by the test name. + self.RunAndVerify('*/0', [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestY/0', + 'SeqQ/ParamTest.TestX/0', + 'SeqQ/ParamTest.TestY/0', + ]) + + def testFlagOverridesEnvVar(self): + """Tests that the filter flag overrides the filtering env. variable.""" + + SetEnvVar(FILTER_ENV_VAR, 'Foo*') + args = ['--%s=%s' % (FILTER_FLAG, '*One')] + tests_run = RunAndExtractTestList(args)[0] + SetEnvVar(FILTER_ENV_VAR, None) + + self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne']) + + def testShardStatusFileIsCreated(self): + """Tests that the shard file is created if specified in the environment.""" + + shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), + 'shard_status_file') + self.assert_(not os.path.exists(shard_status_file)) + + extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} + try: + InvokeWithModifiedEnv(extra_env, RunAndReturnOutput) + finally: + self.assert_(os.path.exists(shard_status_file)) + os.remove(shard_status_file) + + def testShardStatusFileIsCreatedWithListTests(self): + """Tests that the shard file is created with the "list_tests" flag.""" + + shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), + 'shard_status_file2') + self.assert_(not os.path.exists(shard_status_file)) + + extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} + try: + output = InvokeWithModifiedEnv(extra_env, + RunAndReturnOutput, + [LIST_TESTS_FLAG]) + finally: + # This assertion ensures that Google Test enumerated the tests as + # opposed to running them. + self.assert_('[==========]' not in output, + 'Unexpected output during test enumeration.\n' + 'Please ensure that LIST_TESTS_FLAG is assigned the\n' + 'correct flag value for listing Google Test tests.') + + self.assert_(os.path.exists(shard_status_file)) + os.remove(shard_status_file) + + if SUPPORTS_DEATH_TESTS: + def testShardingWorksWithDeathTests(self): + """Tests integration with death tests and sharding.""" + + gtest_filter = 'HasDeathTest.*:SeqP/*' + expected_tests = [ + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', + + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + ] + + for flag in ['--gtest_death_test_style=threadsafe', + '--gtest_death_test_style=fast']: + self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests, + check_exit_0=True, args=[flag]) + self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests, + check_exit_0=True, args=[flag]) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_filter_unittest_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_filter_unittest_.cc new file mode 100644 index 0000000..77deffc --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_filter_unittest_.cc @@ -0,0 +1,140 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Unit test for Google Test test filters. +// +// A user can specify which test(s) in a Google Test program to run via +// either the GTEST_FILTER environment variable or the --gtest_filter +// flag. This is used for testing such functionality. +// +// The program will be invoked from a Python unit test. Don't run it +// directly. + +#include "gtest/gtest.h" + +namespace { + +// Test case FooTest. + +class FooTest : public testing::Test { +}; + +TEST_F(FooTest, Abc) { +} + +TEST_F(FooTest, Xyz) { + FAIL() << "Expected failure."; +} + +// Test case BarTest. + +TEST(BarTest, TestOne) { +} + +TEST(BarTest, TestTwo) { +} + +TEST(BarTest, TestThree) { +} + +TEST(BarTest, DISABLED_TestFour) { + FAIL() << "Expected failure."; +} + +TEST(BarTest, DISABLED_TestFive) { + FAIL() << "Expected failure."; +} + +// Test case BazTest. + +TEST(BazTest, TestOne) { + FAIL() << "Expected failure."; +} + +TEST(BazTest, TestA) { +} + +TEST(BazTest, TestB) { +} + +TEST(BazTest, DISABLED_TestC) { + FAIL() << "Expected failure."; +} + +// Test case HasDeathTest + +TEST(HasDeathTest, Test1) { + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); +} + +// We need at least two death tests to make sure that the all death tests +// aren't on the first shard. +TEST(HasDeathTest, Test2) { + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); +} + +// Test case FoobarTest + +TEST(DISABLED_FoobarTest, Test1) { + FAIL() << "Expected failure."; +} + +TEST(DISABLED_FoobarTest, DISABLED_Test2) { + FAIL() << "Expected failure."; +} + +// Test case FoobarbazTest + +TEST(DISABLED_FoobarbazTest, TestA) { + FAIL() << "Expected failure."; +} + +#if GTEST_HAS_PARAM_TEST +class ParamTest : public testing::TestWithParam { +}; + +TEST_P(ParamTest, TestX) { +} + +TEST_P(ParamTest, TestY) { +} + +INSTANTIATE_TEST_CASE_P(SeqP, ParamTest, testing::Values(1, 2)); +INSTANTIATE_TEST_CASE_P(SeqQ, ParamTest, testing::Values(5, 6)); +#endif // GTEST_HAS_PARAM_TEST + +} // namespace + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_help_test.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_help_test.py new file mode 100755 index 0000000..093c838 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_help_test.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# 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. + +"""Tests the --help flag of Google C++ Testing Framework. + +SYNOPSIS + gtest_help_test.py --build_dir=BUILD/DIR + # where BUILD/DIR contains the built gtest_help_test_ file. + gtest_help_test.py +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import gtest_test_utils + + +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' +IS_WINDOWS = os.name == 'nt' + +PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_') +FLAG_PREFIX = '--gtest_' +DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style' +STREAM_RESULT_TO_FLAG = FLAG_PREFIX + 'stream_result_to' +UNKNOWN_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing' +LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' +INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', LIST_TESTS_FLAG), + re.sub('^--', '/', LIST_TESTS_FLAG), + re.sub('_', '-', LIST_TESTS_FLAG)] +INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing' + +SUPPORTS_DEATH_TESTS = "DeathTest" in gtest_test_utils.Subprocess( + [PROGRAM_PATH, LIST_TESTS_FLAG]).output + +# The help message must match this regex. +HELP_REGEX = re.compile( + FLAG_PREFIX + r'list_tests.*' + + FLAG_PREFIX + r'filter=.*' + + FLAG_PREFIX + r'also_run_disabled_tests.*' + + FLAG_PREFIX + r'repeat=.*' + + FLAG_PREFIX + r'shuffle.*' + + FLAG_PREFIX + r'random_seed=.*' + + FLAG_PREFIX + r'color=.*' + + FLAG_PREFIX + r'print_time.*' + + FLAG_PREFIX + r'output=.*' + + FLAG_PREFIX + r'break_on_failure.*' + + FLAG_PREFIX + r'throw_on_failure.*' + + FLAG_PREFIX + r'catch_exceptions=0.*', + re.DOTALL) + + +def RunWithFlag(flag): + """Runs gtest_help_test_ with the given flag. + + Returns: + the exit code and the text output as a tuple. + Args: + flag: the command-line flag to pass to gtest_help_test_, or None. + """ + + if flag is None: + command = [PROGRAM_PATH] + else: + command = [PROGRAM_PATH, flag] + child = gtest_test_utils.Subprocess(command) + return child.exit_code, child.output + + +class GTestHelpTest(gtest_test_utils.TestCase): + """Tests the --help flag and its equivalent forms.""" + + def TestHelpFlag(self, flag): + """Verifies correct behavior when help flag is specified. + + The right message must be printed and the tests must + skipped when the given flag is specified. + + Args: + flag: A flag to pass to the binary or None. + """ + + exit_code, output = RunWithFlag(flag) + self.assertEquals(0, exit_code) + self.assert_(HELP_REGEX.search(output), output) + + if IS_LINUX: + self.assert_(STREAM_RESULT_TO_FLAG in output, output) + else: + self.assert_(STREAM_RESULT_TO_FLAG not in output, output) + + if SUPPORTS_DEATH_TESTS and not IS_WINDOWS: + self.assert_(DEATH_TEST_STYLE_FLAG in output, output) + else: + self.assert_(DEATH_TEST_STYLE_FLAG not in output, output) + + def TestNonHelpFlag(self, flag): + """Verifies correct behavior when no help flag is specified. + + Verifies that when no help flag is specified, the tests are run + and the help message is not printed. + + Args: + flag: A flag to pass to the binary or None. + """ + + exit_code, output = RunWithFlag(flag) + self.assert_(exit_code != 0) + self.assert_(not HELP_REGEX.search(output), output) + + def testPrintsHelpWithFullFlag(self): + self.TestHelpFlag('--help') + + def testPrintsHelpWithShortFlag(self): + self.TestHelpFlag('-h') + + def testPrintsHelpWithQuestionFlag(self): + self.TestHelpFlag('-?') + + def testPrintsHelpWithWindowsStyleQuestionFlag(self): + self.TestHelpFlag('/?') + + def testPrintsHelpWithUnrecognizedGoogleTestFlag(self): + self.TestHelpFlag(UNKNOWN_FLAG) + + def testPrintsHelpWithIncorrectFlagStyle(self): + for incorrect_flag in INCORRECT_FLAG_VARIANTS: + self.TestHelpFlag(incorrect_flag) + + def testRunsTestsWithoutHelpFlag(self): + """Verifies that when no help flag is specified, the tests are run + and the help message is not printed.""" + + self.TestNonHelpFlag(None) + + def testRunsTestsWithGtestInternalFlag(self): + """Verifies that the tests are run and no help message is printed when + a flag starting with Google Test prefix and 'internal_' is supplied.""" + + self.TestNonHelpFlag(INTERNAL_FLAG_FOR_TESTING) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_help_test_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_help_test_.cc new file mode 100644 index 0000000..31f78c2 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_help_test_.cc @@ -0,0 +1,46 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// This program is meant to be run by gtest_help_test.py. Do not run +// it directly. + +#include "gtest/gtest.h" + +// When a help flag is specified, this program should skip the tests +// and exit with 0; otherwise the following test will be executed, +// causing this program to exit with a non-zero code. +TEST(HelpFlagTest, ShouldNotBeRun) { + ASSERT_TRUE(false) << "Tests shouldn't be run when --help is specified."; +} + +#if GTEST_HAS_DEATH_TEST +TEST(DeathTest, UsedByPythonScriptToDetectSupportForDeathTestsInThisBinary) {} +#endif diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_list_tests_unittest.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_list_tests_unittest.py new file mode 100755 index 0000000..925b09d --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_list_tests_unittest.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test for Google Test's --gtest_list_tests flag. + +A user can ask Google Test to list all tests by specifying the +--gtest_list_tests flag. This script tests such functionality +by invoking gtest_list_tests_unittest_ (a program written with +Google Test) the command line flags. +""" + +__author__ = 'phanna@google.com (Patrick Hanna)' + +import gtest_test_utils +import re + + +# Constants. + +# The command line flag for enabling/disabling listing all tests. +LIST_TESTS_FLAG = 'gtest_list_tests' + +# Path to the gtest_list_tests_unittest_ program. +EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_') + +# The expected output when running gtest_list_tests_unittest_ with +# --gtest_list_tests +EXPECTED_OUTPUT_NO_FILTER_RE = re.compile(r"""FooDeathTest\. + Test1 +Foo\. + Bar1 + Bar2 + DISABLED_Bar3 +Abc\. + Xyz + Def +FooBar\. + Baz +FooTest\. + Test1 + DISABLED_Test2 + Test3 +TypedTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\. + TestA + TestB +TypedTest/1\. # TypeParam = int\s*\* + TestA + TestB +TypedTest/2\. # TypeParam = .*MyArray + TestA + TestB +My/TypeParamTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\. + TestA + TestB +My/TypeParamTest/1\. # TypeParam = int\s*\* + TestA + TestB +My/TypeParamTest/2\. # TypeParam = .*MyArray + TestA + TestB +MyInstantiation/ValueParamTest\. + TestA/0 # GetParam\(\) = one line + TestA/1 # GetParam\(\) = two\\nlines + TestA/2 # GetParam\(\) = a very\\nlo{241}\.\.\. + TestB/0 # GetParam\(\) = one line + TestB/1 # GetParam\(\) = two\\nlines + TestB/2 # GetParam\(\) = a very\\nlo{241}\.\.\. +""") + +# The expected output when running gtest_list_tests_unittest_ with +# --gtest_list_tests and --gtest_filter=Foo*. +EXPECTED_OUTPUT_FILTER_FOO_RE = re.compile(r"""FooDeathTest\. + Test1 +Foo\. + Bar1 + Bar2 + DISABLED_Bar3 +FooBar\. + Baz +FooTest\. + Test1 + DISABLED_Test2 + Test3 +""") + +# Utilities. + + +def Run(args): + """Runs gtest_list_tests_unittest_ and returns the list of tests printed.""" + + return gtest_test_utils.Subprocess([EXE_PATH] + args, + capture_stderr=False).output + + +# The unit test. + +class GTestListTestsUnitTest(gtest_test_utils.TestCase): + """Tests using the --gtest_list_tests flag to list all tests.""" + + def RunAndVerify(self, flag_value, expected_output_re, other_flag): + """Runs gtest_list_tests_unittest_ and verifies that it prints + the correct tests. + + Args: + flag_value: value of the --gtest_list_tests flag; + None if the flag should not be present. + expected_output_re: regular expression that matches the expected + output after running command; + other_flag: a different flag to be passed to command + along with gtest_list_tests; + None if the flag should not be present. + """ + + if flag_value is None: + flag = '' + flag_expression = 'not set' + elif flag_value == '0': + flag = '--%s=0' % LIST_TESTS_FLAG + flag_expression = '0' + else: + flag = '--%s' % LIST_TESTS_FLAG + flag_expression = '1' + + args = [flag] + + if other_flag is not None: + args += [other_flag] + + output = Run(args) + + if expected_output_re: + self.assert_( + expected_output_re.match(output), + ('when %s is %s, the output of "%s" is "%s",\n' + 'which does not match regex "%s"' % + (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output, + expected_output_re.pattern))) + else: + self.assert_( + not EXPECTED_OUTPUT_NO_FILTER_RE.match(output), + ('when %s is %s, the output of "%s" is "%s"'% + (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output))) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(flag_value=None, + expected_output_re=None, + other_flag=None) + + def testFlag(self): + """Tests using the --gtest_list_tests flag.""" + + self.RunAndVerify(flag_value='0', + expected_output_re=None, + other_flag=None) + self.RunAndVerify(flag_value='1', + expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE, + other_flag=None) + + def testOverrideNonFilterFlags(self): + """Tests that --gtest_list_tests overrides the non-filter flags.""" + + self.RunAndVerify(flag_value='1', + expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE, + other_flag='--gtest_break_on_failure') + + def testWithFilterFlags(self): + """Tests that --gtest_list_tests takes into account the + --gtest_filter flag.""" + + self.RunAndVerify(flag_value='1', + expected_output_re=EXPECTED_OUTPUT_FILTER_FOO_RE, + other_flag='--gtest_filter=Foo*') + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_list_tests_unittest_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_list_tests_unittest_.cc new file mode 100644 index 0000000..907c176 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_list_tests_unittest_.cc @@ -0,0 +1,157 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: phanna@google.com (Patrick Hanna) + +// Unit test for Google Test's --gtest_list_tests flag. +// +// A user can ask Google Test to list all tests that will run +// so that when using a filter, a user will know what +// tests to look for. The tests will not be run after listing. +// +// This program will be invoked from a Python unit test. +// Don't run it directly. + +#include "gtest/gtest.h" + +// Several different test cases and tests that will be listed. +TEST(Foo, Bar1) { +} + +TEST(Foo, Bar2) { +} + +TEST(Foo, DISABLED_Bar3) { +} + +TEST(Abc, Xyz) { +} + +TEST(Abc, Def) { +} + +TEST(FooBar, Baz) { +} + +class FooTest : public testing::Test { +}; + +TEST_F(FooTest, Test1) { +} + +TEST_F(FooTest, DISABLED_Test2) { +} + +TEST_F(FooTest, Test3) { +} + +TEST(FooDeathTest, Test1) { +} + +// A group of value-parameterized tests. + +class MyType { + public: + explicit MyType(const std::string& a_value) : value_(a_value) {} + + const std::string& value() const { return value_; } + + private: + std::string value_; +}; + +// Teaches Google Test how to print a MyType. +void PrintTo(const MyType& x, std::ostream* os) { + *os << x.value(); +} + +class ValueParamTest : public testing::TestWithParam { +}; + +TEST_P(ValueParamTest, TestA) { +} + +TEST_P(ValueParamTest, TestB) { +} + +INSTANTIATE_TEST_CASE_P( + MyInstantiation, ValueParamTest, + testing::Values(MyType("one line"), + MyType("two\nlines"), + MyType("a very\nloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line"))); // NOLINT + +// A group of typed tests. + +// A deliberately long type name for testing the line-truncating +// behavior when printing a type parameter. +class VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName { // NOLINT +}; + +template +class TypedTest : public testing::Test { +}; + +template +class MyArray { +}; + +typedef testing::Types > MyTypes; + +TYPED_TEST_CASE(TypedTest, MyTypes); + +TYPED_TEST(TypedTest, TestA) { +} + +TYPED_TEST(TypedTest, TestB) { +} + +// A group of type-parameterized tests. + +template +class TypeParamTest : public testing::Test { +}; + +TYPED_TEST_CASE_P(TypeParamTest); + +TYPED_TEST_P(TypeParamTest, TestA) { +} + +TYPED_TEST_P(TypeParamTest, TestB) { +} + +REGISTER_TYPED_TEST_CASE_P(TypeParamTest, TestA, TestB); + +INSTANTIATE_TYPED_TEST_CASE_P(My, TypeParamTest, MyTypes); + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_main_unittest.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_main_unittest.cc new file mode 100644 index 0000000..ecd9bb8 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_main_unittest.cc @@ -0,0 +1,45 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest.h" + +// Tests that we don't have to define main() when we link to +// gtest_main instead of gtest. + +namespace { + +TEST(GTestMainTest, ShouldSucceed) { +} + +} // namespace + +// We are using the main() function defined in src/gtest_main.cc, so +// we don't define it here. diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_no_test_unittest.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_no_test_unittest.cc new file mode 100644 index 0000000..292599a --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_no_test_unittest.cc @@ -0,0 +1,56 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +// Tests that a Google Test program that has no test defined can run +// successfully. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest.h" + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + // An ad-hoc assertion outside of all tests. + // + // This serves three purposes: + // + // 1. It verifies that an ad-hoc assertion can be executed even if + // no test is defined. + // 2. It verifies that a failed ad-hoc assertion causes the test + // program to fail. + // 3. We had a bug where the XML output won't be generated if an + // assertion is executed before RUN_ALL_TESTS() is called, even + // though --gtest_output=xml is specified. This makes sure the + // bug is fixed and doesn't regress. + EXPECT_EQ(1, 2); + + // The above EXPECT_EQ() should cause RUN_ALL_TESTS() to return non-zero. + return RUN_ALL_TESTS() ? 0 : 1; +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_output_test.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_output_test.py new file mode 100755 index 0000000..f409e2a --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_output_test.py @@ -0,0 +1,335 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""Tests the text output of Google C++ Testing Framework. + +SYNOPSIS + gtest_output_test.py --build_dir=BUILD/DIR --gengolden + # where BUILD/DIR contains the built gtest_output_test_ file. + gtest_output_test.py --gengolden + gtest_output_test.py +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sys +import gtest_test_utils + + +# The flag for generating the golden file +GENGOLDEN_FLAG = '--gengolden' +CATCH_EXCEPTIONS_ENV_VAR_NAME = 'GTEST_CATCH_EXCEPTIONS' + +IS_WINDOWS = os.name == 'nt' + +# TODO(vladl@google.com): remove the _lin suffix. +GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' + +PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_') + +# At least one command we exercise must not have the +# --gtest_internal_skip_environment_and_ad_hoc_tests flag. +COMMAND_LIST_TESTS = ({}, [PROGRAM_PATH, '--gtest_list_tests']) +COMMAND_WITH_COLOR = ({}, [PROGRAM_PATH, '--gtest_color=yes']) +COMMAND_WITH_TIME = ({}, [PROGRAM_PATH, + '--gtest_print_time', + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=FatalFailureTest.*:LoggingTest.*']) +COMMAND_WITH_DISABLED = ( + {}, [PROGRAM_PATH, + '--gtest_also_run_disabled_tests', + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=*DISABLED_*']) +COMMAND_WITH_SHARDING = ( + {'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'}, + [PROGRAM_PATH, + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=PassingTest.*']) + +GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) + + +def ToUnixLineEnding(s): + """Changes all Windows/Mac line endings in s to UNIX line endings.""" + + return s.replace('\r\n', '\n').replace('\r', '\n') + + +def RemoveLocations(test_output): + """Removes all file location info from a Google Test program's output. + + Args: + test_output: the output of a Google Test program. + + Returns: + output with all file location info (in the form of + 'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or + 'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by + 'FILE_NAME:#: '. + """ + + return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', test_output) + + +def RemoveStackTraceDetails(output): + """Removes all stack traces from a Google Test program's output.""" + + # *? means "find the shortest string that matches". + return re.sub(r'Stack trace:(.|\n)*?\n\n', + 'Stack trace: (omitted)\n\n', output) + + +def RemoveStackTraces(output): + """Removes all traces of stack traces from a Google Test program's output.""" + + # *? means "find the shortest string that matches". + return re.sub(r'Stack trace:(.|\n)*?\n\n', '', output) + + +def RemoveTime(output): + """Removes all time information from a Google Test program's output.""" + + return re.sub(r'\(\d+ ms', '(? ms', output) + + +def RemoveTypeInfoDetails(test_output): + """Removes compiler-specific type info from Google Test program's output. + + Args: + test_output: the output of a Google Test program. + + Returns: + output with type information normalized to canonical form. + """ + + # some compilers output the name of type 'unsigned int' as 'unsigned' + return re.sub(r'unsigned int', 'unsigned', test_output) + + +def NormalizeToCurrentPlatform(test_output): + """Normalizes platform specific output details for easier comparison.""" + + if IS_WINDOWS: + # Removes the color information that is not present on Windows. + test_output = re.sub('\x1b\\[(0;3\d)?m', '', test_output) + # Changes failure message headers into the Windows format. + test_output = re.sub(r': Failure\n', r': error: ', test_output) + # Changes file(line_number) to file:line_number. + test_output = re.sub(r'((\w|\.)+)\((\d+)\):', r'\1:\3:', test_output) + + return test_output + + +def RemoveTestCounts(output): + """Removes test counts from a Google Test program's output.""" + + output = re.sub(r'\d+ tests?, listed below', + '? tests, listed below', output) + output = re.sub(r'\d+ FAILED TESTS', + '? FAILED TESTS', output) + output = re.sub(r'\d+ tests? from \d+ test cases?', + '? tests from ? test cases', output) + output = re.sub(r'\d+ tests? from ([a-zA-Z_])', + r'? tests from \1', output) + return re.sub(r'\d+ tests?\.', '? tests.', output) + + +def RemoveMatchingTests(test_output, pattern): + """Removes output of specified tests from a Google Test program's output. + + This function strips not only the beginning and the end of a test but also + all output in between. + + Args: + test_output: A string containing the test output. + pattern: A regex string that matches names of test cases or + tests to remove. + + Returns: + Contents of test_output with tests whose names match pattern removed. + """ + + test_output = re.sub( + r'.*\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % ( + pattern, pattern), + '', + test_output) + return re.sub(r'.*%s.*\n' % pattern, '', test_output) + + +def NormalizeOutput(output): + """Normalizes output (the output of gtest_output_test_.exe).""" + + output = ToUnixLineEnding(output) + output = RemoveLocations(output) + output = RemoveStackTraceDetails(output) + output = RemoveTime(output) + return output + + +def GetShellCommandOutput(env_cmd): + """Runs a command in a sub-process, and returns its output in a string. + + Args: + env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra + environment variables to set, and element 1 is a string with + the command and any flags. + + Returns: + A string with the command's combined standard and diagnostic output. + """ + + # Spawns cmd in a sub-process, and gets its standard I/O file objects. + # Set and save the environment properly. + environ = os.environ.copy() + environ.update(env_cmd[0]) + p = gtest_test_utils.Subprocess(env_cmd[1], env=environ) + + return p.output + + +def GetCommandOutput(env_cmd): + """Runs a command and returns its output with all file location + info stripped off. + + Args: + env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra + environment variables to set, and element 1 is a string with + the command and any flags. + """ + + # Disables exception pop-ups on Windows. + environ, cmdline = env_cmd + environ = dict(environ) # Ensures we are modifying a copy. + environ[CATCH_EXCEPTIONS_ENV_VAR_NAME] = '1' + return NormalizeOutput(GetShellCommandOutput((environ, cmdline))) + + +def GetOutputOfAllCommands(): + """Returns concatenated output from several representative commands.""" + + return (GetCommandOutput(COMMAND_WITH_COLOR) + + GetCommandOutput(COMMAND_WITH_TIME) + + GetCommandOutput(COMMAND_WITH_DISABLED) + + GetCommandOutput(COMMAND_WITH_SHARDING)) + + +test_list = GetShellCommandOutput(COMMAND_LIST_TESTS) +SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list +SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list +SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list +SUPPORTS_STACK_TRACES = False + +CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and + SUPPORTS_TYPED_TESTS and + SUPPORTS_THREADS) + + +class GTestOutputTest(gtest_test_utils.TestCase): + def RemoveUnsupportedTests(self, test_output): + if not SUPPORTS_DEATH_TESTS: + test_output = RemoveMatchingTests(test_output, 'DeathTest') + if not SUPPORTS_TYPED_TESTS: + test_output = RemoveMatchingTests(test_output, 'TypedTest') + test_output = RemoveMatchingTests(test_output, 'TypedDeathTest') + test_output = RemoveMatchingTests(test_output, 'TypeParamDeathTest') + if not SUPPORTS_THREADS: + test_output = RemoveMatchingTests(test_output, + 'ExpectFailureWithThreadsTest') + test_output = RemoveMatchingTests(test_output, + 'ScopedFakeTestPartResultReporterTest') + test_output = RemoveMatchingTests(test_output, + 'WorksConcurrently') + if not SUPPORTS_STACK_TRACES: + test_output = RemoveStackTraces(test_output) + + return test_output + + def testOutput(self): + output = GetOutputOfAllCommands() + + golden_file = open(GOLDEN_PATH, 'rb') + # A mis-configured source control system can cause \r appear in EOL + # sequences when we read the golden file irrespective of an operating + # system used. Therefore, we need to strip those \r's from newlines + # unconditionally. + golden = ToUnixLineEnding(golden_file.read()) + golden_file.close() + + # We want the test to pass regardless of certain features being + # supported or not. + + # We still have to remove type name specifics in all cases. + normalized_actual = RemoveTypeInfoDetails(output) + normalized_golden = RemoveTypeInfoDetails(golden) + + if CAN_GENERATE_GOLDEN_FILE: + self.assertEqual(normalized_golden, normalized_actual) + else: + normalized_actual = NormalizeToCurrentPlatform( + RemoveTestCounts(normalized_actual)) + normalized_golden = NormalizeToCurrentPlatform( + RemoveTestCounts(self.RemoveUnsupportedTests(normalized_golden))) + + # This code is very handy when debugging golden file differences: + if os.getenv('DEBUG_GTEST_OUTPUT_TEST'): + open(os.path.join( + gtest_test_utils.GetSourceDir(), + '_gtest_output_test_normalized_actual.txt'), 'wb').write( + normalized_actual) + open(os.path.join( + gtest_test_utils.GetSourceDir(), + '_gtest_output_test_normalized_golden.txt'), 'wb').write( + normalized_golden) + + self.assertEqual(normalized_golden, normalized_actual) + + +if __name__ == '__main__': + if sys.argv[1:] == [GENGOLDEN_FLAG]: + if CAN_GENERATE_GOLDEN_FILE: + output = GetOutputOfAllCommands() + golden_file = open(GOLDEN_PATH, 'wb') + golden_file.write(output) + golden_file.close() + else: + message = ( + """Unable to write a golden file when compiled in an environment +that does not support all the required features (death tests, typed tests, +and multiple threads). Please generate the golden file using a binary built +with those features enabled.""") + + sys.stderr.write(message) + sys.exit(1) + else: + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_output_test_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_output_test_.cc new file mode 100644 index 0000000..07ab633 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_output_test_.cc @@ -0,0 +1,1034 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// The purpose of this file is to generate Google Test output under +// various conditions. The output will then be verified by +// gtest_output_test.py to ensure that Google Test generates the +// desired messages. Therefore, most tests in this file are MEANT TO +// FAIL. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#include + +#if GTEST_IS_THREADSAFE +using testing::ScopedFakeTestPartResultReporter; +using testing::TestPartResultArray; + +using testing::internal::Notification; +using testing::internal::ThreadWithParam; +#endif + +namespace posix = ::testing::internal::posix; +using testing::internal::scoped_ptr; + +// Tests catching fatal failures. + +// A subroutine used by the following test. +void TestEq1(int x) { + ASSERT_EQ(1, x); +} + +// This function calls a test subroutine, catches the fatal failure it +// generates, and then returns early. +void TryTestSubroutine() { + // Calls a subrountine that yields a fatal failure. + TestEq1(2); + + // Catches the fatal failure and aborts the test. + // + // The testing::Test:: prefix is necessary when calling + // HasFatalFailure() outside of a TEST, TEST_F, or test fixture. + if (testing::Test::HasFatalFailure()) return; + + // If we get here, something is wrong. + FAIL() << "This should never be reached."; +} + +TEST(PassingTest, PassingTest1) { +} + +TEST(PassingTest, PassingTest2) { +} + +// Tests that parameters of failing parameterized tests are printed in the +// failing test summary. +class FailingParamTest : public testing::TestWithParam {}; + +TEST_P(FailingParamTest, Fails) { + EXPECT_EQ(1, GetParam()); +} + +// This generates a test which will fail. Google Test is expected to print +// its parameter when it outputs the list of all failed tests. +INSTANTIATE_TEST_CASE_P(PrintingFailingParams, + FailingParamTest, + testing::Values(2)); + +static const char kGoldenString[] = "\"Line\0 1\"\nLine 2"; + +TEST(NonfatalFailureTest, EscapesStringOperands) { + std::string actual = "actual \"string\""; + EXPECT_EQ(kGoldenString, actual); + + const char* golden = kGoldenString; + EXPECT_EQ(golden, actual); +} + +// Tests catching a fatal failure in a subroutine. +TEST(FatalFailureTest, FatalFailureInSubroutine) { + printf("(expecting a failure that x should be 1)\n"); + + TryTestSubroutine(); +} + +// Tests catching a fatal failure in a nested subroutine. +TEST(FatalFailureTest, FatalFailureInNestedSubroutine) { + printf("(expecting a failure that x should be 1)\n"); + + // Calls a subrountine that yields a fatal failure. + TryTestSubroutine(); + + // Catches the fatal failure and aborts the test. + // + // When calling HasFatalFailure() inside a TEST, TEST_F, or test + // fixture, the testing::Test:: prefix is not needed. + if (HasFatalFailure()) return; + + // If we get here, something is wrong. + FAIL() << "This should never be reached."; +} + +// Tests HasFatalFailure() after a failed EXPECT check. +TEST(FatalFailureTest, NonfatalFailureInSubroutine) { + printf("(expecting a failure on false)\n"); + EXPECT_TRUE(false); // Generates a nonfatal failure + ASSERT_FALSE(HasFatalFailure()); // This should succeed. +} + +// Tests interleaving user logging and Google Test assertions. +TEST(LoggingTest, InterleavingLoggingAndAssertions) { + static const int a[4] = { + 3, 9, 2, 6 + }; + + printf("(expecting 2 failures on (3) >= (a[i]))\n"); + for (int i = 0; i < static_cast(sizeof(a)/sizeof(*a)); i++) { + printf("i == %d\n", i); + EXPECT_GE(3, a[i]); + } +} + +// Tests the SCOPED_TRACE macro. + +// A helper function for testing SCOPED_TRACE. +void SubWithoutTrace(int n) { + EXPECT_EQ(1, n); + ASSERT_EQ(2, n); +} + +// Another helper function for testing SCOPED_TRACE. +void SubWithTrace(int n) { + SCOPED_TRACE(testing::Message() << "n = " << n); + + SubWithoutTrace(n); +} + +// Tests that SCOPED_TRACE() obeys lexical scopes. +TEST(SCOPED_TRACETest, ObeysScopes) { + printf("(expected to fail)\n"); + + // There should be no trace before SCOPED_TRACE() is invoked. + ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; + + { + SCOPED_TRACE("Expected trace"); + // After SCOPED_TRACE(), a failure in the current scope should contain + // the trace. + ADD_FAILURE() << "This failure is expected, and should have a trace."; + } + + // Once the control leaves the scope of the SCOPED_TRACE(), there + // should be no trace again. + ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; +} + +// Tests that SCOPED_TRACE works inside a loop. +TEST(SCOPED_TRACETest, WorksInLoop) { + printf("(expected to fail)\n"); + + for (int i = 1; i <= 2; i++) { + SCOPED_TRACE(testing::Message() << "i = " << i); + + SubWithoutTrace(i); + } +} + +// Tests that SCOPED_TRACE works in a subroutine. +TEST(SCOPED_TRACETest, WorksInSubroutine) { + printf("(expected to fail)\n"); + + SubWithTrace(1); + SubWithTrace(2); +} + +// Tests that SCOPED_TRACE can be nested. +TEST(SCOPED_TRACETest, CanBeNested) { + printf("(expected to fail)\n"); + + SCOPED_TRACE(""); // A trace without a message. + + SubWithTrace(2); +} + +// Tests that multiple SCOPED_TRACEs can be used in the same scope. +TEST(SCOPED_TRACETest, CanBeRepeated) { + printf("(expected to fail)\n"); + + SCOPED_TRACE("A"); + ADD_FAILURE() + << "This failure is expected, and should contain trace point A."; + + SCOPED_TRACE("B"); + ADD_FAILURE() + << "This failure is expected, and should contain trace point A and B."; + + { + SCOPED_TRACE("C"); + ADD_FAILURE() << "This failure is expected, and should " + << "contain trace point A, B, and C."; + } + + SCOPED_TRACE("D"); + ADD_FAILURE() << "This failure is expected, and should " + << "contain trace point A, B, and D."; +} + +#if GTEST_IS_THREADSAFE +// Tests that SCOPED_TRACE()s can be used concurrently from multiple +// threads. Namely, an assertion should be affected by +// SCOPED_TRACE()s in its own thread only. + +// Here's the sequence of actions that happen in the test: +// +// Thread A (main) | Thread B (spawned) +// ===============================|================================ +// spawns thread B | +// -------------------------------+-------------------------------- +// waits for n1 | SCOPED_TRACE("Trace B"); +// | generates failure #1 +// | notifies n1 +// -------------------------------+-------------------------------- +// SCOPED_TRACE("Trace A"); | waits for n2 +// generates failure #2 | +// notifies n2 | +// -------------------------------|-------------------------------- +// waits for n3 | generates failure #3 +// | trace B dies +// | generates failure #4 +// | notifies n3 +// -------------------------------|-------------------------------- +// generates failure #5 | finishes +// trace A dies | +// generates failure #6 | +// -------------------------------|-------------------------------- +// waits for thread B to finish | + +struct CheckPoints { + Notification n1; + Notification n2; + Notification n3; +}; + +static void ThreadWithScopedTrace(CheckPoints* check_points) { + { + SCOPED_TRACE("Trace B"); + ADD_FAILURE() + << "Expected failure #1 (in thread B, only trace B alive)."; + check_points->n1.Notify(); + check_points->n2.WaitForNotification(); + + ADD_FAILURE() + << "Expected failure #3 (in thread B, trace A & B both alive)."; + } // Trace B dies here. + ADD_FAILURE() + << "Expected failure #4 (in thread B, only trace A alive)."; + check_points->n3.Notify(); +} + +TEST(SCOPED_TRACETest, WorksConcurrently) { + printf("(expecting 6 failures)\n"); + + CheckPoints check_points; + ThreadWithParam thread(&ThreadWithScopedTrace, + &check_points, + NULL); + check_points.n1.WaitForNotification(); + + { + SCOPED_TRACE("Trace A"); + ADD_FAILURE() + << "Expected failure #2 (in thread A, trace A & B both alive)."; + check_points.n2.Notify(); + check_points.n3.WaitForNotification(); + + ADD_FAILURE() + << "Expected failure #5 (in thread A, only trace A alive)."; + } // Trace A dies here. + ADD_FAILURE() + << "Expected failure #6 (in thread A, no trace alive)."; + thread.Join(); +} +#endif // GTEST_IS_THREADSAFE + +TEST(DisabledTestsWarningTest, + DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning) { + // This test body is intentionally empty. Its sole purpose is for + // verifying that the --gtest_also_run_disabled_tests flag + // suppresses the "YOU HAVE 12 DISABLED TESTS" warning at the end of + // the test output. +} + +// Tests using assertions outside of TEST and TEST_F. +// +// This function creates two failures intentionally. +void AdHocTest() { + printf("The non-test part of the code is expected to have 2 failures.\n\n"); + EXPECT_TRUE(false); + EXPECT_EQ(2, 3); +} + +// Runs all TESTs, all TEST_Fs, and the ad hoc test. +int RunAllTests() { + AdHocTest(); + return RUN_ALL_TESTS(); +} + +// Tests non-fatal failures in the fixture constructor. +class NonFatalFailureInFixtureConstructorTest : public testing::Test { + protected: + NonFatalFailureInFixtureConstructorTest() { + printf("(expecting 5 failures)\n"); + ADD_FAILURE() << "Expected failure #1, in the test fixture c'tor."; + } + + ~NonFatalFailureInFixtureConstructorTest() { + ADD_FAILURE() << "Expected failure #5, in the test fixture d'tor."; + } + + virtual void SetUp() { + ADD_FAILURE() << "Expected failure #2, in SetUp()."; + } + + virtual void TearDown() { + ADD_FAILURE() << "Expected failure #4, in TearDown."; + } +}; + +TEST_F(NonFatalFailureInFixtureConstructorTest, FailureInConstructor) { + ADD_FAILURE() << "Expected failure #3, in the test body."; +} + +// Tests fatal failures in the fixture constructor. +class FatalFailureInFixtureConstructorTest : public testing::Test { + protected: + FatalFailureInFixtureConstructorTest() { + printf("(expecting 2 failures)\n"); + Init(); + } + + ~FatalFailureInFixtureConstructorTest() { + ADD_FAILURE() << "Expected failure #2, in the test fixture d'tor."; + } + + virtual void SetUp() { + ADD_FAILURE() << "UNEXPECTED failure in SetUp(). " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; + } + + virtual void TearDown() { + ADD_FAILURE() << "UNEXPECTED failure in TearDown(). " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; + } + + private: + void Init() { + FAIL() << "Expected failure #1, in the test fixture c'tor."; + } +}; + +TEST_F(FatalFailureInFixtureConstructorTest, FailureInConstructor) { + ADD_FAILURE() << "UNEXPECTED failure in the test body. " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; +} + +// Tests non-fatal failures in SetUp(). +class NonFatalFailureInSetUpTest : public testing::Test { + protected: + virtual ~NonFatalFailureInSetUpTest() { + Deinit(); + } + + virtual void SetUp() { + printf("(expecting 4 failures)\n"); + ADD_FAILURE() << "Expected failure #1, in SetUp()."; + } + + virtual void TearDown() { + FAIL() << "Expected failure #3, in TearDown()."; + } + private: + void Deinit() { + FAIL() << "Expected failure #4, in the test fixture d'tor."; + } +}; + +TEST_F(NonFatalFailureInSetUpTest, FailureInSetUp) { + FAIL() << "Expected failure #2, in the test function."; +} + +// Tests fatal failures in SetUp(). +class FatalFailureInSetUpTest : public testing::Test { + protected: + virtual ~FatalFailureInSetUpTest() { + Deinit(); + } + + virtual void SetUp() { + printf("(expecting 3 failures)\n"); + FAIL() << "Expected failure #1, in SetUp()."; + } + + virtual void TearDown() { + FAIL() << "Expected failure #2, in TearDown()."; + } + private: + void Deinit() { + FAIL() << "Expected failure #3, in the test fixture d'tor."; + } +}; + +TEST_F(FatalFailureInSetUpTest, FailureInSetUp) { + FAIL() << "UNEXPECTED failure in the test function. " + << "We should never get here, as SetUp() failed."; +} + +TEST(AddFailureAtTest, MessageContainsSpecifiedFileAndLineNumber) { + ADD_FAILURE_AT("foo.cc", 42) << "Expected failure in foo.cc"; +} + +#if GTEST_IS_THREADSAFE + +// A unary function that may die. +void DieIf(bool should_die) { + GTEST_CHECK_(!should_die) << " - death inside DieIf()."; +} + +// Tests running death tests in a multi-threaded context. + +// Used for coordination between the main and the spawn thread. +struct SpawnThreadNotifications { + SpawnThreadNotifications() {} + + Notification spawn_thread_started; + Notification spawn_thread_ok_to_terminate; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications); +}; + +// The function to be executed in the thread spawn by the +// MultipleThreads test (below). +static void ThreadRoutine(SpawnThreadNotifications* notifications) { + // Signals the main thread that this thread has started. + notifications->spawn_thread_started.Notify(); + + // Waits for permission to finish from the main thread. + notifications->spawn_thread_ok_to_terminate.WaitForNotification(); +} + +// This is a death-test test, but it's not named with a DeathTest +// suffix. It starts threads which might interfere with later +// death tests, so it must run after all other death tests. +class DeathTestAndMultiThreadsTest : public testing::Test { + protected: + // Starts a thread and waits for it to begin. + virtual void SetUp() { + thread_.reset(new ThreadWithParam( + &ThreadRoutine, ¬ifications_, NULL)); + notifications_.spawn_thread_started.WaitForNotification(); + } + // Tells the thread to finish, and reaps it. + // Depending on the version of the thread library in use, + // a manager thread might still be left running that will interfere + // with later death tests. This is unfortunate, but this class + // cleans up after itself as best it can. + virtual void TearDown() { + notifications_.spawn_thread_ok_to_terminate.Notify(); + } + + private: + SpawnThreadNotifications notifications_; + scoped_ptr > thread_; +}; + +#endif // GTEST_IS_THREADSAFE + +// The MixedUpTestCaseTest test case verifies that Google Test will fail a +// test if it uses a different fixture class than what other tests in +// the same test case use. It deliberately contains two fixture +// classes with the same name but defined in different namespaces. + +// The MixedUpTestCaseWithSameTestNameTest test case verifies that +// when the user defines two tests with the same test case name AND +// same test name (but in different namespaces), the second test will +// fail. + +namespace foo { + +class MixedUpTestCaseTest : public testing::Test { +}; + +TEST_F(MixedUpTestCaseTest, FirstTestFromNamespaceFoo) {} +TEST_F(MixedUpTestCaseTest, SecondTestFromNamespaceFoo) {} + +class MixedUpTestCaseWithSameTestNameTest : public testing::Test { +}; + +TEST_F(MixedUpTestCaseWithSameTestNameTest, + TheSecondTestWithThisNameShouldFail) {} + +} // namespace foo + +namespace bar { + +class MixedUpTestCaseTest : public testing::Test { +}; + +// The following two tests are expected to fail. We rely on the +// golden file to check that Google Test generates the right error message. +TEST_F(MixedUpTestCaseTest, ThisShouldFail) {} +TEST_F(MixedUpTestCaseTest, ThisShouldFailToo) {} + +class MixedUpTestCaseWithSameTestNameTest : public testing::Test { +}; + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST_F(MixedUpTestCaseWithSameTestNameTest, + TheSecondTestWithThisNameShouldFail) {} + +} // namespace bar + +// The following two test cases verify that Google Test catches the user +// error of mixing TEST and TEST_F in the same test case. The first +// test case checks the scenario where TEST_F appears before TEST, and +// the second one checks where TEST appears before TEST_F. + +class TEST_F_before_TEST_in_same_test_case : public testing::Test { +}; + +TEST_F(TEST_F_before_TEST_in_same_test_case, DefinedUsingTEST_F) {} + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST(TEST_F_before_TEST_in_same_test_case, DefinedUsingTESTAndShouldFail) {} + +class TEST_before_TEST_F_in_same_test_case : public testing::Test { +}; + +TEST(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST) {} + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST_F(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST_FAndShouldFail) { +} + +// Used for testing EXPECT_NONFATAL_FAILURE() and EXPECT_FATAL_FAILURE(). +int global_integer = 0; + +// Tests that EXPECT_NONFATAL_FAILURE() can reference global variables. +TEST(ExpectNonfatalFailureTest, CanReferenceGlobalVariables) { + global_integer = 0; + EXPECT_NONFATAL_FAILURE({ + EXPECT_EQ(1, global_integer) << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() can reference local variables +// (static or not). +TEST(ExpectNonfatalFailureTest, CanReferenceLocalVariables) { + int m = 0; + static int n; + n = 1; + EXPECT_NONFATAL_FAILURE({ + EXPECT_EQ(m, n) << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() succeeds when there is exactly +// one non-fatal failure and no fatal failure. +TEST(ExpectNonfatalFailureTest, SucceedsWhenThereIsOneNonfatalFailure) { + EXPECT_NONFATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there is no +// non-fatal failure. +TEST(ExpectNonfatalFailureTest, FailsWhenThereIsNoNonfatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there are two +// non-fatal failures. +TEST(ExpectNonfatalFailureTest, FailsWhenThereAreTwoNonfatalFailures) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure 1."; + ADD_FAILURE() << "Expected non-fatal failure 2."; + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there is one fatal +// failure. +TEST(ExpectNonfatalFailureTest, FailsWhenThereIsOneFatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + FAIL() << "Expected fatal failure."; + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being +// tested returns. +TEST(ExpectNonfatalFailureTest, FailsWhenStatementReturns) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + return; + }, ""); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being +// tested throws. +TEST(ExpectNonfatalFailureTest, FailsWhenStatementThrows) { + printf("(expecting a failure)\n"); + try { + EXPECT_NONFATAL_FAILURE({ + throw 0; + }, ""); + } catch(int) { // NOLINT + } +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_FATAL_FAILURE() can reference global variables. +TEST(ExpectFatalFailureTest, CanReferenceGlobalVariables) { + global_integer = 0; + EXPECT_FATAL_FAILURE({ + ASSERT_EQ(1, global_integer) << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() can reference local static +// variables. +TEST(ExpectFatalFailureTest, CanReferenceLocalStaticVariables) { + static int n; + n = 1; + EXPECT_FATAL_FAILURE({ + ASSERT_EQ(0, n) << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() succeeds when there is exactly +// one fatal failure and no non-fatal failure. +TEST(ExpectFatalFailureTest, SucceedsWhenThereIsOneFatalFailure) { + EXPECT_FATAL_FAILURE({ + FAIL() << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there is no fatal +// failure. +TEST(ExpectFatalFailureTest, FailsWhenThereIsNoFatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + }, ""); +} + +// A helper for generating a fatal failure. +void FatalFailure() { + FAIL() << "Expected fatal failure."; +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there are two +// fatal failures. +TEST(ExpectFatalFailureTest, FailsWhenThereAreTwoFatalFailures) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + FatalFailure(); + FatalFailure(); + }, ""); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there is one non-fatal +// failure. +TEST(ExpectFatalFailureTest, FailsWhenThereIsOneNonfatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure."; + }, ""); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when the statement being +// tested returns. +TEST(ExpectFatalFailureTest, FailsWhenStatementReturns) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + return; + }, ""); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_FATAL_FAILURE() fails when the statement being +// tested throws. +TEST(ExpectFatalFailureTest, FailsWhenStatementThrows) { + printf("(expecting a failure)\n"); + try { + EXPECT_FATAL_FAILURE({ + throw 0; + }, ""); + } catch(int) { // NOLINT + } +} + +#endif // GTEST_HAS_EXCEPTIONS + +// This #ifdef block tests the output of typed tests. +#if GTEST_HAS_TYPED_TEST + +template +class TypedTest : public testing::Test { +}; + +TYPED_TEST_CASE(TypedTest, testing::Types); + +TYPED_TEST(TypedTest, Success) { + EXPECT_EQ(0, TypeParam()); +} + +TYPED_TEST(TypedTest, Failure) { + EXPECT_EQ(1, TypeParam()) << "Expected failure"; +} + +#endif // GTEST_HAS_TYPED_TEST + +// This #ifdef block tests the output of type-parameterized tests. +#if GTEST_HAS_TYPED_TEST_P + +template +class TypedTestP : public testing::Test { +}; + +TYPED_TEST_CASE_P(TypedTestP); + +TYPED_TEST_P(TypedTestP, Success) { + EXPECT_EQ(0U, TypeParam()); +} + +TYPED_TEST_P(TypedTestP, Failure) { + EXPECT_EQ(1U, TypeParam()) << "Expected failure"; +} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP, Success, Failure); + +typedef testing::Types UnsignedTypes; +INSTANTIATE_TYPED_TEST_CASE_P(Unsigned, TypedTestP, UnsignedTypes); + +#endif // GTEST_HAS_TYPED_TEST_P + +#if GTEST_HAS_DEATH_TEST + +// We rely on the golden file to verify that tests whose test case +// name ends with DeathTest are run first. + +TEST(ADeathTest, ShouldRunFirst) { +} + +# if GTEST_HAS_TYPED_TEST + +// We rely on the golden file to verify that typed tests whose test +// case name ends with DeathTest are run first. + +template +class ATypedDeathTest : public testing::Test { +}; + +typedef testing::Types NumericTypes; +TYPED_TEST_CASE(ATypedDeathTest, NumericTypes); + +TYPED_TEST(ATypedDeathTest, ShouldRunFirst) { +} + +# endif // GTEST_HAS_TYPED_TEST + +# if GTEST_HAS_TYPED_TEST_P + + +// We rely on the golden file to verify that type-parameterized tests +// whose test case name ends with DeathTest are run first. + +template +class ATypeParamDeathTest : public testing::Test { +}; + +TYPED_TEST_CASE_P(ATypeParamDeathTest); + +TYPED_TEST_P(ATypeParamDeathTest, ShouldRunFirst) { +} + +REGISTER_TYPED_TEST_CASE_P(ATypeParamDeathTest, ShouldRunFirst); + +INSTANTIATE_TYPED_TEST_CASE_P(My, ATypeParamDeathTest, NumericTypes); + +# endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_HAS_DEATH_TEST + +// Tests various failure conditions of +// EXPECT_{,NON}FATAL_FAILURE{,_ON_ALL_THREADS}. +class ExpectFailureTest : public testing::Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + enum FailureMode { + FATAL_FAILURE, + NONFATAL_FAILURE + }; + static void AddFailure(FailureMode failure) { + if (failure == FATAL_FAILURE) { + FAIL() << "Expected fatal failure."; + } else { + ADD_FAILURE() << "Expected non-fatal failure."; + } + } +}; + +TEST_F(ExpectFailureTest, ExpectFatalFailure) { + // Expected fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(SUCCEED(), "Expected fatal failure."); + // Expected fatal failure, but got a non-fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Expected non-fatal " + "failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Some other fatal failure " + "expected."); +} + +TEST_F(ExpectFailureTest, ExpectNonFatalFailure) { + // Expected non-fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(SUCCEED(), "Expected non-fatal failure."); + // Expected non-fatal failure, but got a fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Some other non-fatal " + "failure."); +} + +#if GTEST_IS_THREADSAFE + +class ExpectFailureWithThreadsTest : public ExpectFailureTest { + protected: + static void AddFailureInOtherThread(FailureMode failure) { + ThreadWithParam thread(&AddFailure, failure, NULL); + thread.Join(); + } +}; + +TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailure) { + // We only intercept the current thread. + printf("(expecting 2 failures)\n"); + EXPECT_FATAL_FAILURE(AddFailureInOtherThread(FATAL_FAILURE), + "Expected fatal failure."); +} + +TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailure) { + // We only intercept the current thread. + printf("(expecting 2 failures)\n"); + EXPECT_NONFATAL_FAILURE(AddFailureInOtherThread(NONFATAL_FAILURE), + "Expected non-fatal failure."); +} + +typedef ExpectFailureWithThreadsTest ScopedFakeTestPartResultReporterTest; + +// Tests that the ScopedFakeTestPartResultReporter only catches failures from +// the current thread if it is instantiated with INTERCEPT_ONLY_CURRENT_THREAD. +TEST_F(ScopedFakeTestPartResultReporterTest, InterceptOnlyCurrentThread) { + printf("(expecting 2 failures)\n"); + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, + &results); + AddFailureInOtherThread(FATAL_FAILURE); + AddFailureInOtherThread(NONFATAL_FAILURE); + } + // The two failures should not have been intercepted. + EXPECT_EQ(0, results.size()) << "This shouldn't fail."; +} + +#endif // GTEST_IS_THREADSAFE + +TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) { + // Expected fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected fatal failure."); + // Expected fatal failure, but got a non-fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Expected non-fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + "Some other fatal failure expected."); +} + +TEST_F(ExpectFailureTest, ExpectNonFatalFailureOnAllThreads) { + // Expected non-fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected non-fatal " + "failure."); + // Expected non-fatal failure, but got a fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + "Expected fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Some other non-fatal failure."); +} + + +// Two test environments for testing testing::AddGlobalTestEnvironment(). + +class FooEnvironment : public testing::Environment { + public: + virtual void SetUp() { + printf("%s", "FooEnvironment::SetUp() called.\n"); + } + + virtual void TearDown() { + printf("%s", "FooEnvironment::TearDown() called.\n"); + FAIL() << "Expected fatal failure."; + } +}; + +class BarEnvironment : public testing::Environment { + public: + virtual void SetUp() { + printf("%s", "BarEnvironment::SetUp() called.\n"); + } + + virtual void TearDown() { + printf("%s", "BarEnvironment::TearDown() called.\n"); + ADD_FAILURE() << "Expected non-fatal failure."; + } +}; + +bool GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = false; + +// The main function. +// +// The idea is to use Google Test to run all the tests we have defined (some +// of them are intended to fail), and then compare the test results +// with the "golden" file. +int main(int argc, char **argv) { + testing::GTEST_FLAG(print_time) = false; + + // We just run the tests, knowing some of them are intended to fail. + // We will use a separate Python script to compare the output of + // this program with the golden file. + + // It's hard to test InitGoogleTest() directly, as it has many + // global side effects. The following line serves as a sanity test + // for it. + testing::InitGoogleTest(&argc, argv); + if (argc >= 2 && + (std::string(argv[1]) == + "--gtest_internal_skip_environment_and_ad_hoc_tests")) + GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true; + +#if GTEST_HAS_DEATH_TEST + if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { + // Skip the usual output capturing if we're running as the child + // process of an threadsafe-style death test. +# if GTEST_OS_WINDOWS + posix::FReopen("nul:", "w", stdout); +# else + posix::FReopen("/dev/null", "w", stdout); +# endif // GTEST_OS_WINDOWS + return RUN_ALL_TESTS(); + } +#endif // GTEST_HAS_DEATH_TEST + + if (GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests)) + return RUN_ALL_TESTS(); + + // Registers two global test environments. + // The golden file verifies that they are set up in the order they + // are registered, and torn down in the reverse order. + testing::AddGlobalTestEnvironment(new FooEnvironment); + testing::AddGlobalTestEnvironment(new BarEnvironment); + + return RunAllTests(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_output_test_golden_lin.txt b/cpp/thirdparty/gtest-1.7.0/test/gtest_output_test_golden_lin.txt new file mode 100644 index 0000000..960eedc --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_output_test_golden_lin.txt @@ -0,0 +1,720 @@ +The non-test part of the code is expected to have 2 failures. + +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +gtest_output_test_.cc:#: Failure +Value of: 3 +Expected: 2 +[==========] Running 63 tests from 28 test cases. +[----------] Global test environment set-up. +FooEnvironment::SetUp() called. +BarEnvironment::SetUp() called. +[----------] 1 test from ADeathTest +[ RUN ] ADeathTest.ShouldRunFirst +[ OK ] ADeathTest.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/0, where TypeParam = int +[ RUN ] ATypedDeathTest/0.ShouldRunFirst +[ OK ] ATypedDeathTest/0.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/1, where TypeParam = double +[ RUN ] ATypedDeathTest/1.ShouldRunFirst +[ OK ] ATypedDeathTest/1.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int +[ RUN ] My/ATypeParamDeathTest/0.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/0.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double +[ RUN ] My/ATypeParamDeathTest/1.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/1.ShouldRunFirst +[----------] 2 tests from PassingTest +[ RUN ] PassingTest.PassingTest1 +[ OK ] PassingTest.PassingTest1 +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 +[----------] 1 test from NonfatalFailureTest +[ RUN ] NonfatalFailureTest.EscapesStringOperands +gtest_output_test_.cc:#: Failure +Value of: actual + Actual: "actual \"string\"" +Expected: kGoldenString +Which is: "\"Line" +gtest_output_test_.cc:#: Failure +Value of: actual + Actual: "actual \"string\"" +Expected: golden +Which is: "\"Line" +[ FAILED ] NonfatalFailureTest.EscapesStringOperands +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 9 +i == 2 +i == 3 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 6 +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[----------] 6 tests from SCOPED_TRACETest +[ RUN ] SCOPED_TRACETest.ObeysScopes +(expected to fail) +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should have a trace. +Google Test trace: +gtest_output_test_.cc:#: Expected trace +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ RUN ] SCOPED_TRACETest.WorksInLoop +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 1 +Expected: 2 +Google Test trace: +gtest_output_test_.cc:#: i = 1 +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: i = 2 +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ RUN ] SCOPED_TRACETest.WorksInSubroutine +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 1 +Expected: 2 +Google Test trace: +gtest_output_test_.cc:#: n = 1 +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: n = 2 +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ RUN ] SCOPED_TRACETest.CanBeNested +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: n = 2 +gtest_output_test_.cc:#: +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ RUN ] SCOPED_TRACETest.CanBeRepeated +(expected to fail) +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A. +Google Test trace: +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A and B. +Google Test trace: +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and C. +Google Test trace: +gtest_output_test_.cc:#: C +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and D. +Google Test trace: +gtest_output_test_.cc:#: D +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ RUN ] SCOPED_TRACETest.WorksConcurrently +(expecting 6 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1 (in thread B, only trace B alive). +Google Test trace: +gtest_output_test_.cc:#: Trace B +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2 (in thread A, trace A & B both alive). +Google Test trace: +gtest_output_test_.cc:#: Trace A +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3 (in thread B, trace A & B both alive). +Google Test trace: +gtest_output_test_.cc:#: Trace B +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4 (in thread B, only trace A alive). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #5 (in thread A, only trace A alive). +Google Test trace: +gtest_output_test_.cc:#: Trace A +gtest_output_test_.cc:#: Failure +Failed +Expected failure #6 (in thread A, no trace alive). +[ FAILED ] SCOPED_TRACETest.WorksConcurrently +[----------] 1 test from NonFatalFailureInFixtureConstructorTest +[ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 5 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test body. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4, in TearDown. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #5, in the test fixture d'tor. +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from FatalFailureInFixtureConstructorTest +[ RUN ] FatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in the test fixture d'tor. +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from NonFatalFailureInSetUpTest +[ RUN ] NonFatalFailureInSetUpTest.FailureInSetUp +(expecting 4 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in the test function. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4, in the test fixture d'tor. +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from FatalFailureInSetUpTest +[ RUN ] FatalFailureInSetUpTest.FailureInSetUp +(expecting 3 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test fixture d'tor. +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from AddFailureAtTest +[ RUN ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +foo.cc:42: Failure +Failed +Expected failure in foo.cc +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +[----------] 4 tests from MixedUpTestCaseTest +[ RUN ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo +[ OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo +[ RUN ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo +[ OK ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo +[ RUN ] MixedUpTestCaseTest.ThisShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseTest.ThisShouldFail +[ RUN ] MixedUpTestCaseTest.ThisShouldFailToo +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFailToo +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo +[----------] 2 tests from MixedUpTestCaseWithSameTestNameTest +[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ OK ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseWithSameTestNameTest, +you defined test TheSecondTestWithThisNameShouldFail and test TheSecondTestWithThisNameShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[----------] 2 tests from TEST_F_before_TEST_in_same_test_case +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ OK ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class, so mixing TEST_F and TEST in the same test case is +illegal. In test case TEST_F_before_TEST_in_same_test_case, +test DefinedUsingTEST_F is defined using TEST_F but +test DefinedUsingTESTAndShouldFail is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[----------] 2 tests from TEST_before_TEST_F_in_same_test_case +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ OK ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class, so mixing TEST_F and TEST in the same test case is +illegal. In test case TEST_before_TEST_F_in_same_test_case, +test DefinedUsingTEST_FAndShouldFail is defined using TEST_F but +test DefinedUsingTEST is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[----------] 8 tests from ExpectNonfatalFailureTest +[ RUN ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ RUN ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ OK ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 2 failures +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 1. + +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 2. + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +[----------] 8 tests from ExpectFatalFailureTest +[ RUN ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ OK ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ RUN ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ OK ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 2 failures +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows +[----------] 2 tests from TypedTest/0, where TypeParam = int +[ RUN ] TypedTest/0.Success +[ OK ] TypedTest/0.Success +[ RUN ] TypedTest/0.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: 0 +Expected: 1 +Expected failure +[ FAILED ] TypedTest/0.Failure, where TypeParam = int +[----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char +[ RUN ] Unsigned/TypedTestP/0.Success +[ OK ] Unsigned/TypedTestP/0.Success +[ RUN ] Unsigned/TypedTestP/0.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: '\0' +Expected: 1U +Which is: 1 +Expected failure +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char +[----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int +[ RUN ] Unsigned/TypedTestP/1.Success +[ OK ] Unsigned/TypedTestP/1.Success +[ RUN ] Unsigned/TypedTestP/1.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: 0 +Expected: 1U +Which is: 1 +Expected failure +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int +[----------] 4 tests from ExpectFailureTest +[ RUN ] ExpectFailureTest.ExpectFatalFailure +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ RUN ] ExpectFailureTest.ExpectNonFatalFailure +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ RUN ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ RUN ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[----------] 2 tests from ExpectFailureWithThreadsTest +[ RUN ] ExpectFailureWithThreadsTest.ExpectFatalFailure +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure +[ RUN ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +[----------] 1 test from ScopedFakeTestPartResultReporterTest +[ RUN ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +[----------] 1 test from PrintingFailingParams/FailingParamTest +[ RUN ] PrintingFailingParams/FailingParamTest.Fails/0 +gtest_output_test_.cc:#: Failure +Value of: GetParam() + Actual: 2 +Expected: 1 +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 +[----------] Global test environment tear-down +BarEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +FooEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +[==========] 63 tests from 28 test cases ran. +[ PASSED ] 21 tests. +[ FAILED ] 42 tests, listed below: +[ FAILED ] NonfatalFailureTest.EscapesStringOperands +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ FAILED ] SCOPED_TRACETest.WorksConcurrently +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +[ FAILED ] MixedUpTestCaseTest.ThisShouldFail +[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo +[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows +[ FAILED ] TypedTest/0.Failure, where TypeParam = int +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure +[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 + +42 FAILED TESTS + YOU HAVE 1 DISABLED TEST + +Note: Google Test filter = FatalFailureTest.*:LoggingTest.* +[==========] Running 4 tests from 2 test cases. +[----------] Global test environment set-up. +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine (? ms) +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine (? ms) +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine (? ms) +[----------] 3 tests from FatalFailureTest (? ms total) + +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 9 +i == 2 +i == 3 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 6 +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions (? ms) +[----------] 1 test from LoggingTest (? ms total) + +[----------] Global test environment tear-down +[==========] 4 tests from 2 test cases ran. (? ms total) +[ PASSED ] 0 tests. +[ FAILED ] 4 tests, listed below: +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions + + 4 FAILED TESTS +Note: Google Test filter = *DISABLED_* +[==========] Running 1 test from 1 test case. +[----------] Global test environment set-up. +[----------] 1 test from DisabledTestsWarningTest +[ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[----------] Global test environment tear-down +[==========] 1 test from 1 test case ran. +[ PASSED ] 1 test. +Note: Google Test filter = PassingTest.* +Note: This is test shard 2 of 2. +[==========] Running 1 test from 1 test case. +[----------] Global test environment set-up. +[----------] 1 test from PassingTest +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 +[----------] Global test environment tear-down +[==========] 1 test from 1 test case ran. +[ PASSED ] 1 test. diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_pred_impl_unittest.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_pred_impl_unittest.cc new file mode 100644 index 0000000..a84eff8 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_pred_impl_unittest.cc @@ -0,0 +1,2427 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! + +// Regression test for gtest_pred_impl.h +// +// This file is generated by a script and quite long. If you intend to +// learn how Google Test works by reading its unit tests, read +// gtest_unittest.cc instead. +// +// This is intended as a regression test for the Google Test predicate +// assertions. We compile it as part of the gtest_unittest target +// only to keep the implementation tidy and compact, as it is quite +// involved to set up the stage for testing Google Test using Google +// Test itself. +// +// Currently, gtest_unittest takes ~11 seconds to run in the testing +// daemon. In the future, if it grows too large and needs much more +// time to finish, we should consider separating this file into a +// stand-alone regression test. + +#include + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +// A user-defined data type. +struct Bool { + explicit Bool(int val) : value(val != 0) {} + + bool operator>(int n) const { return value > Bool(n).value; } + + Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); } + + bool operator==(const Bool& rhs) const { return value == rhs.value; } + + bool value; +}; + +// Enables Bool to be used in assertions. +std::ostream& operator<<(std::ostream& os, const Bool& x) { + return os << (x.value ? "true" : "false"); +} + +// Sample functions/functors for testing unary predicate assertions. + +// A unary predicate function. +template +bool PredFunction1(T1 v1) { + return v1 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction1Int(int v1) { + return v1 > 0; +} +bool PredFunction1Bool(Bool v1) { + return v1 > 0; +} + +// A unary predicate functor. +struct PredFunctor1 { + template + bool operator()(const T1& v1) { + return v1 > 0; + } +}; + +// A unary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction1(const char* e1, + const T1& v1) { + if (PredFunction1(v1)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 + << " is expected to be positive, but evaluates to " + << v1 << "."; +} + +// A unary predicate-formatter functor. +struct PredFormatFunctor1 { + template + testing::AssertionResult operator()(const char* e1, + const T1& v1) const { + return PredFormatFunction1(e1, v1); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT1. + +class Predicate1Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; +}; + +bool Predicate1Test::expected_to_finish_; +bool Predicate1Test::finished_; +int Predicate1Test::n1_; + +typedef Predicate1Test EXPECT_PRED_FORMAT1Test; +typedef Predicate1Test ASSERT_PRED_FORMAT1Test; +typedef Predicate1Test EXPECT_PRED1Test; +typedef Predicate1Test ASSERT_PRED1Test; + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED1(PredFunction1Int, + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED1(PredFunction1Bool, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED1(PredFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED1(PredFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunction1Int, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunction1Bool, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED1(PredFunction1Int, + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED1(PredFunction1Bool, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED1(PredFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED1(PredFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunction1Int, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunction1Bool, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunction1, + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunction1, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunction1, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunction1, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunction1, + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunction1, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunction1, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunction1, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing binary predicate assertions. + +// A binary predicate function. +template +bool PredFunction2(T1 v1, T2 v2) { + return v1 + v2 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction2Int(int v1, int v2) { + return v1 + v2 > 0; +} +bool PredFunction2Bool(Bool v1, Bool v2) { + return v1 + v2 > 0; +} + +// A binary predicate functor. +struct PredFunctor2 { + template + bool operator()(const T1& v1, + const T2& v2) { + return v1 + v2 > 0; + } +}; + +// A binary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction2(const char* e1, + const char* e2, + const T1& v1, + const T2& v2) { + if (PredFunction2(v1, v2)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 + << " is expected to be positive, but evaluates to " + << v1 + v2 << "."; +} + +// A binary predicate-formatter functor. +struct PredFormatFunctor2 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const T1& v1, + const T2& v2) const { + return PredFormatFunction2(e1, e2, v1, v2); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT2. + +class Predicate2Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; +}; + +bool Predicate2Test::expected_to_finish_; +bool Predicate2Test::finished_; +int Predicate2Test::n1_; +int Predicate2Test::n2_; + +typedef Predicate2Test EXPECT_PRED_FORMAT2Test; +typedef Predicate2Test ASSERT_PRED_FORMAT2Test; +typedef Predicate2Test EXPECT_PRED2Test; +typedef Predicate2Test ASSERT_PRED2Test; + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED2(PredFunction2Int, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED2(PredFunction2Bool, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED2(PredFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED2(PredFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunction2Int, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunction2Bool, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED2(PredFunction2Int, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED2(PredFunction2Bool, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED2(PredFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED2(PredFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunction2Int, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunction2Bool, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunction2, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunction2, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunction2, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunction2, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunction2, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunction2, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunction2, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunction2, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing ternary predicate assertions. + +// A ternary predicate function. +template +bool PredFunction3(T1 v1, T2 v2, T3 v3) { + return v1 + v2 + v3 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction3Int(int v1, int v2, int v3) { + return v1 + v2 + v3 > 0; +} +bool PredFunction3Bool(Bool v1, Bool v2, Bool v3) { + return v1 + v2 + v3 > 0; +} + +// A ternary predicate functor. +struct PredFunctor3 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3) { + return v1 + v2 + v3 > 0; + } +}; + +// A ternary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction3(const char* e1, + const char* e2, + const char* e3, + const T1& v1, + const T2& v2, + const T3& v3) { + if (PredFunction3(v1, v2, v3)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 << "."; +} + +// A ternary predicate-formatter functor. +struct PredFormatFunctor3 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const T1& v1, + const T2& v2, + const T3& v3) const { + return PredFormatFunction3(e1, e2, e3, v1, v2, v3); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT3. + +class Predicate3Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; +}; + +bool Predicate3Test::expected_to_finish_; +bool Predicate3Test::finished_; +int Predicate3Test::n1_; +int Predicate3Test::n2_; +int Predicate3Test::n3_; + +typedef Predicate3Test EXPECT_PRED_FORMAT3Test; +typedef Predicate3Test ASSERT_PRED_FORMAT3Test; +typedef Predicate3Test EXPECT_PRED3Test; +typedef Predicate3Test ASSERT_PRED3Test; + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED3(PredFunction3Int, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED3(PredFunction3Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED3(PredFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED3(PredFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunction3Int, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunction3Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED3(PredFunction3Int, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED3(PredFunction3Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED3(PredFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED3(PredFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunction3Int, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunction3Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunction3, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunction3, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunction3, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunction3, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunction3, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunction3, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunction3, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunction3, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing 4-ary predicate assertions. + +// A 4-ary predicate function. +template +bool PredFunction4(T1 v1, T2 v2, T3 v3, T4 v4) { + return v1 + v2 + v3 + v4 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction4Int(int v1, int v2, int v3, int v4) { + return v1 + v2 + v3 + v4 > 0; +} +bool PredFunction4Bool(Bool v1, Bool v2, Bool v3, Bool v4) { + return v1 + v2 + v3 + v4 > 0; +} + +// A 4-ary predicate functor. +struct PredFunctor4 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + return v1 + v2 + v3 + v4 > 0; + } +}; + +// A 4-ary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction4(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (PredFunction4(v1, v2, v3, v4)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 << " + " << e4 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 + v4 << "."; +} + +// A 4-ary predicate-formatter functor. +struct PredFormatFunctor4 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) const { + return PredFormatFunction4(e1, e2, e3, e4, v1, v2, v3, v4); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT4. + +class Predicate4Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = n4_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + EXPECT_EQ(1, n4_) << + "The predicate assertion didn't evaluate argument 5 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; + static int n4_; +}; + +bool Predicate4Test::expected_to_finish_; +bool Predicate4Test::finished_; +int Predicate4Test::n1_; +int Predicate4Test::n2_; +int Predicate4Test::n3_; +int Predicate4Test::n4_; + +typedef Predicate4Test EXPECT_PRED_FORMAT4Test; +typedef Predicate4Test ASSERT_PRED_FORMAT4Test; +typedef Predicate4Test EXPECT_PRED4Test; +typedef Predicate4Test ASSERT_PRED4Test; + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED4(PredFunction4Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED4(PredFunction4Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED4(PredFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED4(PredFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunction4Int, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunction4Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED4(PredFunction4Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED4(PredFunction4Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED4(PredFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED4(PredFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunction4Int, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunction4Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunction4, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunction4, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunction4, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunction4, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunction4, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunction4, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunction4, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunction4, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing 5-ary predicate assertions. + +// A 5-ary predicate function. +template +bool PredFunction5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction5Int(int v1, int v2, int v3, int v4, int v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} +bool PredFunction5Bool(Bool v1, Bool v2, Bool v3, Bool v4, Bool v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} + +// A 5-ary predicate functor. +struct PredFunctor5 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + return v1 + v2 + v3 + v4 + v5 > 0; + } +}; + +// A 5-ary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction5(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (PredFunction5(v1, v2, v3, v4, v5)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 + v4 + v5 << "."; +} + +// A 5-ary predicate-formatter functor. +struct PredFormatFunctor5 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) const { + return PredFormatFunction5(e1, e2, e3, e4, e5, v1, v2, v3, v4, v5); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT5. + +class Predicate5Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = n4_ = n5_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + EXPECT_EQ(1, n4_) << + "The predicate assertion didn't evaluate argument 5 " + "exactly once."; + EXPECT_EQ(1, n5_) << + "The predicate assertion didn't evaluate argument 6 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; + static int n4_; + static int n5_; +}; + +bool Predicate5Test::expected_to_finish_; +bool Predicate5Test::finished_; +int Predicate5Test::n1_; +int Predicate5Test::n2_; +int Predicate5Test::n3_; +int Predicate5Test::n4_; +int Predicate5Test::n5_; + +typedef Predicate5Test EXPECT_PRED_FORMAT5Test; +typedef Predicate5Test ASSERT_PRED_FORMAT5Test; +typedef Predicate5Test EXPECT_PRED5Test; +typedef Predicate5Test ASSERT_PRED5Test; + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED5(PredFunction5Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED5(PredFunction5Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED5(PredFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED5(PredFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunction5Int, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunction5Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED5(PredFunction5Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED5(PredFunction5Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED5(PredFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED5(PredFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunction5Int, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunction5Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunction5, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunction5, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunction5, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunction5, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunction5, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunction5, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunction5, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunction5, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_premature_exit_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_premature_exit_test.cc new file mode 100644 index 0000000..f6b6be9 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_premature_exit_test.cc @@ -0,0 +1,141 @@ +// Copyright 2013, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests that Google Test manipulates the premature-exit-detection +// file correctly. + +#include + +#include "gtest/gtest.h" + +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::internal::posix::GetEnv; +using ::testing::internal::posix::Stat; +using ::testing::internal::posix::StatStruct; + +namespace { + +// Is the TEST_PREMATURE_EXIT_FILE environment variable expected to be +// set? +const bool kTestPrematureExitFileEnvVarShouldBeSet = false; + +class PrematureExitTest : public Test { + public: + // Returns true iff the given file exists. + static bool FileExists(const char* filepath) { + StatStruct stat; + return Stat(filepath, &stat) == 0; + } + + protected: + PrematureExitTest() { + premature_exit_file_path_ = GetEnv("TEST_PREMATURE_EXIT_FILE"); + + // Normalize NULL to "" for ease of handling. + if (premature_exit_file_path_ == NULL) { + premature_exit_file_path_ = ""; + } + } + + // Returns true iff the premature-exit file exists. + bool PrematureExitFileExists() const { + return FileExists(premature_exit_file_path_); + } + + const char* premature_exit_file_path_; +}; + +typedef PrematureExitTest PrematureExitDeathTest; + +// Tests that: +// - the premature-exit file exists during the execution of a +// death test (EXPECT_DEATH*), and +// - a death test doesn't interfere with the main test process's +// handling of the premature-exit file. +TEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) { + if (*premature_exit_file_path_ == '\0') { + return; + } + + EXPECT_DEATH_IF_SUPPORTED({ + // If the file exists, crash the process such that the main test + // process will catch the (expected) crash and report a success; + // otherwise don't crash, which will cause the main test process + // to report that the death test has failed. + if (PrematureExitFileExists()) { + exit(1); + } + }, ""); +} + +// Tests that TEST_PREMATURE_EXIT_FILE is set where it's expected to +// be set. +TEST_F(PrematureExitTest, TestPrematureExitFileEnvVarIsSet) { + if (kTestPrematureExitFileEnvVarShouldBeSet) { + const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); + ASSERT_TRUE(filepath != NULL); + ASSERT_NE(*filepath, '\0'); + } +} + +// Tests that the premature-exit file exists during the execution of a +// normal (non-death) test. +TEST_F(PrematureExitTest, PrematureExitFileExistsDuringTestExecution) { + if (*premature_exit_file_path_ == '\0') { + return; + } + + EXPECT_TRUE(PrematureExitFileExists()) + << " file " << premature_exit_file_path_ + << " should exist during test execution, but doesn't."; +} + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + const int exit_code = RUN_ALL_TESTS(); + + // Test that the premature-exit file is deleted upon return from + // RUN_ALL_TESTS(). + const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); + if (filepath != NULL && *filepath != '\0') { + if (PrematureExitTest::FileExists(filepath)) { + printf( + "File %s shouldn't exist after the test program finishes, but does.", + filepath); + return 1; + } + } + + return exit_code; +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_prod_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_prod_test.cc new file mode 100644 index 0000000..060abce --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_prod_test.cc @@ -0,0 +1,57 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Unit test for include/gtest/gtest_prod.h. + +#include "gtest/gtest.h" +#include "test/production.h" + +// Tests that private members can be accessed from a TEST declared as +// a friend of the class. +TEST(PrivateCodeTest, CanAccessPrivateMembers) { + PrivateCode a; + EXPECT_EQ(0, a.x_); + + a.set_x(1); + EXPECT_EQ(1, a.x_); +} + +typedef testing::Test PrivateCodeFixtureTest; + +// Tests that private members can be accessed from a TEST_F declared +// as a friend of the class. +TEST_F(PrivateCodeFixtureTest, CanAccessPrivateMembers) { + PrivateCode a; + EXPECT_EQ(0, a.x_); + + a.set_x(2); + EXPECT_EQ(2, a.x_); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_repeat_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_repeat_test.cc new file mode 100644 index 0000000..481012a --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_repeat_test.cc @@ -0,0 +1,253 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests the --gtest_repeat=number flag. + +#include +#include +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +GTEST_DECLARE_string_(death_test_style); +GTEST_DECLARE_string_(filter); +GTEST_DECLARE_int32_(repeat); + +} // namespace testing + +using testing::GTEST_FLAG(death_test_style); +using testing::GTEST_FLAG(filter); +using testing::GTEST_FLAG(repeat); + +namespace { + +// We need this when we are testing Google Test itself and therefore +// cannot use Google Test assertions. +#define GTEST_CHECK_INT_EQ_(expected, actual) \ + do {\ + const int expected_val = (expected);\ + const int actual_val = (actual);\ + if (::testing::internal::IsTrue(expected_val != actual_val)) {\ + ::std::cout << "Value of: " #actual "\n"\ + << " Actual: " << actual_val << "\n"\ + << "Expected: " #expected "\n"\ + << "Which is: " << expected_val << "\n";\ + ::testing::internal::posix::Abort();\ + }\ + } while (::testing::internal::AlwaysFalse()) + + +// Used for verifying that global environment set-up and tear-down are +// inside the gtest_repeat loop. + +int g_environment_set_up_count = 0; +int g_environment_tear_down_count = 0; + +class MyEnvironment : public testing::Environment { + public: + MyEnvironment() {} + virtual void SetUp() { g_environment_set_up_count++; } + virtual void TearDown() { g_environment_tear_down_count++; } +}; + +// A test that should fail. + +int g_should_fail_count = 0; + +TEST(FooTest, ShouldFail) { + g_should_fail_count++; + EXPECT_EQ(0, 1) << "Expected failure."; +} + +// A test that should pass. + +int g_should_pass_count = 0; + +TEST(FooTest, ShouldPass) { + g_should_pass_count++; +} + +// A test that contains a thread-safe death test and a fast death +// test. It should pass. + +int g_death_test_count = 0; + +TEST(BarDeathTest, ThreadSafeAndFast) { + g_death_test_count++; + + GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); + + GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); +} + +#if GTEST_HAS_PARAM_TEST +int g_param_test_count = 0; + +const int kNumberOfParamTests = 10; + +class MyParamTest : public testing::TestWithParam {}; + +TEST_P(MyParamTest, ShouldPass) { + // TODO(vladl@google.com): Make parameter value checking robust + // WRT order of tests. + GTEST_CHECK_INT_EQ_(g_param_test_count % kNumberOfParamTests, GetParam()); + g_param_test_count++; +} +INSTANTIATE_TEST_CASE_P(MyParamSequence, + MyParamTest, + testing::Range(0, kNumberOfParamTests)); +#endif // GTEST_HAS_PARAM_TEST + +// Resets the count for each test. +void ResetCounts() { + g_environment_set_up_count = 0; + g_environment_tear_down_count = 0; + g_should_fail_count = 0; + g_should_pass_count = 0; + g_death_test_count = 0; +#if GTEST_HAS_PARAM_TEST + g_param_test_count = 0; +#endif // GTEST_HAS_PARAM_TEST +} + +// Checks that the count for each test is expected. +void CheckCounts(int expected) { + GTEST_CHECK_INT_EQ_(expected, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(expected, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(expected, g_should_fail_count); + GTEST_CHECK_INT_EQ_(expected, g_should_pass_count); + GTEST_CHECK_INT_EQ_(expected, g_death_test_count); +#if GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(expected * kNumberOfParamTests, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST +} + +// Tests the behavior of Google Test when --gtest_repeat is not specified. +void TestRepeatUnspecified() { + ResetCounts(); + GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); + CheckCounts(1); +} + +// Tests the behavior of Google Test when --gtest_repeat has the given value. +void TestRepeat(int repeat) { + GTEST_FLAG(repeat) = repeat; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(repeat > 0 ? 1 : 0, RUN_ALL_TESTS()); + CheckCounts(repeat); +} + +// Tests using --gtest_repeat when --gtest_filter specifies an empty +// set of tests. +void TestRepeatWithEmptyFilter(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "None"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); + CheckCounts(0); +} + +// Tests using --gtest_repeat when --gtest_filter specifies a set of +// successful tests. +void TestRepeatWithFilterForSuccessfulTests(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "*-*ShouldFail"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); + GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(0, g_should_fail_count); + GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count); + GTEST_CHECK_INT_EQ_(repeat, g_death_test_count); +#if GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(repeat * kNumberOfParamTests, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST +} + +// Tests using --gtest_repeat when --gtest_filter specifies a set of +// failed tests. +void TestRepeatWithFilterForFailedTests(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "*ShouldFail"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); + GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count); + GTEST_CHECK_INT_EQ_(0, g_should_pass_count); + GTEST_CHECK_INT_EQ_(0, g_death_test_count); +#if GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(0, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST +} + +} // namespace + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + testing::AddGlobalTestEnvironment(new MyEnvironment); + + TestRepeatUnspecified(); + TestRepeat(0); + TestRepeat(1); + TestRepeat(5); + + TestRepeatWithEmptyFilter(2); + TestRepeatWithEmptyFilter(3); + + TestRepeatWithFilterForSuccessfulTests(3); + + TestRepeatWithFilterForFailedTests(4); + + // It would be nice to verify that the tests indeed loop forever + // when GTEST_FLAG(repeat) is negative, but this test will be quite + // complicated to write. Since this flag is for interactive + // debugging only and doesn't affect the normal test result, such a + // test would be an overkill. + + printf("PASS\n"); + return 0; +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_shuffle_test.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_shuffle_test.py new file mode 100755 index 0000000..30d0303 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_shuffle_test.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python +# +# Copyright 2009 Google Inc. All Rights Reserved. +# +# 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. + +"""Verifies that test shuffling works.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + +# Command to run the gtest_shuffle_test_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_shuffle_test_') + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' + +TEST_FILTER = 'A*.A:A*.B:C*' + +ALL_TESTS = [] +ACTIVE_TESTS = [] +FILTERED_TESTS = [] +SHARDED_TESTS = [] + +SHUFFLED_ALL_TESTS = [] +SHUFFLED_ACTIVE_TESTS = [] +SHUFFLED_FILTERED_TESTS = [] +SHUFFLED_SHARDED_TESTS = [] + + +def AlsoRunDisabledTestsFlag(): + return '--gtest_also_run_disabled_tests' + + +def FilterFlag(test_filter): + return '--gtest_filter=%s' % (test_filter,) + + +def RepeatFlag(n): + return '--gtest_repeat=%s' % (n,) + + +def ShuffleFlag(): + return '--gtest_shuffle' + + +def RandomSeedFlag(n): + return '--gtest_random_seed=%s' % (n,) + + +def RunAndReturnOutput(extra_env, args): + """Runs the test program and returns its output.""" + + environ_copy = os.environ.copy() + environ_copy.update(extra_env) + + return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output + + +def GetTestsForAllIterations(extra_env, args): + """Runs the test program and returns a list of test lists. + + Args: + extra_env: a map from environment variables to their values + args: command line flags to pass to gtest_shuffle_test_ + + Returns: + A list where the i-th element is the list of tests run in the i-th + test iteration. + """ + + test_iterations = [] + for line in RunAndReturnOutput(extra_env, args).split('\n'): + if line.startswith('----'): + tests = [] + test_iterations.append(tests) + elif line.strip(): + tests.append(line.strip()) # 'TestCaseName.TestName' + + return test_iterations + + +def GetTestCases(tests): + """Returns a list of test cases in the given full test names. + + Args: + tests: a list of full test names + + Returns: + A list of test cases from 'tests', in their original order. + Consecutive duplicates are removed. + """ + + test_cases = [] + for test in tests: + test_case = test.split('.')[0] + if not test_case in test_cases: + test_cases.append(test_case) + + return test_cases + + +def CalculateTestLists(): + """Calculates the list of tests run under different flags.""" + + if not ALL_TESTS: + ALL_TESTS.extend( + GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0]) + + if not ACTIVE_TESTS: + ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0]) + + if not FILTERED_TESTS: + FILTERED_TESTS.extend( + GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0]) + + if not SHARDED_TESTS: + SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [])[0]) + + if not SHUFFLED_ALL_TESTS: + SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations( + {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_ACTIVE_TESTS: + SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_FILTERED_TESTS: + SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0]) + + if not SHUFFLED_SHARDED_TESTS: + SHUFFLED_SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + +class GTestShuffleUnitTest(gtest_test_utils.TestCase): + """Tests test shuffling.""" + + def setUp(self): + CalculateTestLists() + + def testShufflePreservesNumberOfTests(self): + self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS)) + self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS)) + self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS)) + self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS)) + + def testShuffleChangesTestOrder(self): + self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS) + self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS) + self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS, + SHUFFLED_FILTERED_TESTS) + self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS, + SHUFFLED_SHARDED_TESTS) + + def testShuffleChangesTestCaseOrder(self): + self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS), + GetTestCases(SHUFFLED_ALL_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS), + GetTestCases(SHUFFLED_ACTIVE_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS), + GetTestCases(SHUFFLED_FILTERED_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS), + GetTestCases(SHUFFLED_SHARDED_TESTS)) + + def testShuffleDoesNotRepeatTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test), + '%s appears more than once' % (test,)) + + def testShuffleDoesNotCreateNewTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,)) + + def testShuffleIncludesAllTests(self): + for test in ALL_TESTS: + self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,)) + for test in ACTIVE_TESTS: + self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,)) + for test in FILTERED_TESTS: + self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,)) + for test in SHARDED_TESTS: + self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,)) + + def testShuffleLeavesDeathTestsAtFront(self): + non_death_test_found = False + for test in SHUFFLED_ACTIVE_TESTS: + if 'DeathTest.' in test: + self.assert_(not non_death_test_found, + '%s appears after a non-death test' % (test,)) + else: + non_death_test_found = True + + def _VerifyTestCasesDoNotInterleave(self, tests): + test_cases = [] + for test in tests: + [test_case, _] = test.split('.') + if test_cases and test_cases[-1] != test_case: + test_cases.append(test_case) + self.assertEqual(1, test_cases.count(test_case), + 'Test case %s is not grouped together in %s' % + (test_case, tests)) + + def testShuffleDoesNotInterleaveTestCases(self): + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS) + + def testShuffleRestoresOrderAfterEachIteration(self): + # Get the test lists in all 3 iterations, using random seed 1, 2, + # and 3 respectively. Google Test picks a different seed in each + # iteration, and this test depends on the current implementation + # picking successive numbers. This dependency is not ideal, but + # makes the test much easier to write. + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + # Make sure running the tests with random seed 1 gets the same + # order as in iteration 1 above. + [tests_with_seed1] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)]) + self.assertEqual(tests_in_iteration1, tests_with_seed1) + + # Make sure running the tests with random seed 2 gets the same + # order as in iteration 2 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 2. + [tests_with_seed2] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(2)]) + self.assertEqual(tests_in_iteration2, tests_with_seed2) + + # Make sure running the tests with random seed 3 gets the same + # order as in iteration 3 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 3. + [tests_with_seed3] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(3)]) + self.assertEqual(tests_in_iteration3, tests_with_seed3) + + def testShuffleGeneratesNewOrderInEachIteration(self): + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + self.assert_(tests_in_iteration1 != tests_in_iteration2, + tests_in_iteration1) + self.assert_(tests_in_iteration1 != tests_in_iteration3, + tests_in_iteration1) + self.assert_(tests_in_iteration2 != tests_in_iteration3, + tests_in_iteration2) + + def testShuffleShardedTestsPreservesPartition(self): + # If we run M tests on N shards, the same M tests should be run in + # total, regardless of the random seeds used by the shards. + [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '0'}, + [ShuffleFlag(), RandomSeedFlag(1)]) + [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(20)]) + [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '2'}, + [ShuffleFlag(), RandomSeedFlag(25)]) + sorted_sharded_tests = tests1 + tests2 + tests3 + sorted_sharded_tests.sort() + sorted_active_tests = [] + sorted_active_tests.extend(ACTIVE_TESTS) + sorted_active_tests.sort() + self.assertEqual(sorted_active_tests, sorted_sharded_tests) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_shuffle_test_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_shuffle_test_.cc new file mode 100644 index 0000000..6fb441b --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_shuffle_test_.cc @@ -0,0 +1,103 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Verifies that test shuffling works. + +#include "gtest/gtest.h" + +namespace { + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Message; +using ::testing::Test; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::UnitTest; +using ::testing::internal::scoped_ptr; + +// The test methods are empty, as the sole purpose of this program is +// to print the test names before/after shuffling. + +class A : public Test {}; +TEST_F(A, A) {} +TEST_F(A, B) {} + +TEST(ADeathTest, A) {} +TEST(ADeathTest, B) {} +TEST(ADeathTest, C) {} + +TEST(B, A) {} +TEST(B, B) {} +TEST(B, C) {} +TEST(B, DISABLED_D) {} +TEST(B, DISABLED_E) {} + +TEST(BDeathTest, A) {} +TEST(BDeathTest, B) {} + +TEST(C, A) {} +TEST(C, B) {} +TEST(C, C) {} +TEST(C, DISABLED_D) {} + +TEST(CDeathTest, A) {} + +TEST(DISABLED_D, A) {} +TEST(DISABLED_D, DISABLED_B) {} + +// This printer prints the full test names only, starting each test +// iteration with a "----" marker. +class TestNamePrinter : public EmptyTestEventListener { + public: + virtual void OnTestIterationStart(const UnitTest& /* unit_test */, + int /* iteration */) { + printf("----\n"); + } + + virtual void OnTestStart(const TestInfo& test_info) { + printf("%s.%s\n", test_info.test_case_name(), test_info.name()); + } +}; + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + // Replaces the default printer with TestNamePrinter, which prints + // the test name only. + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_result_printer()); + listeners.Append(new TestNamePrinter); + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_sole_header_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_sole_header_test.cc new file mode 100644 index 0000000..ccd091a --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_sole_header_test.cc @@ -0,0 +1,57 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// +// This test verifies that it's possible to use Google Test by including +// the gtest.h header file alone. + +#include "gtest/gtest.h" + +namespace { + +void Subroutine() { + EXPECT_EQ(42, 42); +} + +TEST(NoFatalFailureTest, ExpectNoFatalFailure) { + EXPECT_NO_FATAL_FAILURE(;); + EXPECT_NO_FATAL_FAILURE(SUCCEED()); + EXPECT_NO_FATAL_FAILURE(Subroutine()); + EXPECT_NO_FATAL_FAILURE({ SUCCEED(); }); +} + +TEST(NoFatalFailureTest, AssertNoFatalFailure) { + ASSERT_NO_FATAL_FAILURE(;); + ASSERT_NO_FATAL_FAILURE(SUCCEED()); + ASSERT_NO_FATAL_FAILURE(Subroutine()); + ASSERT_NO_FATAL_FAILURE({ SUCCEED(); }); +} + +} // namespace diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_stress_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_stress_test.cc new file mode 100644 index 0000000..e7daa43 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_stress_test.cc @@ -0,0 +1,256 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests that SCOPED_TRACE() and various Google Test assertions can be +// used in a large number of threads concurrently. + +#include "gtest/gtest.h" + +#include +#include + +// We must define this macro in order to #include +// gtest-internal-inl.h. This is how Google Test prevents a user from +// accidentally depending on its internal implementation. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_IS_THREADSAFE + +namespace testing { +namespace { + +using internal::Notification; +using internal::TestPropertyKeyIs; +using internal::ThreadWithParam; +using internal::scoped_ptr; + +// In order to run tests in this file, for platforms where Google Test is +// thread safe, implement ThreadWithParam. See the description of its API +// in gtest-port.h, where it is defined for already supported platforms. + +// How many threads to create? +const int kThreadCount = 50; + +std::string IdToKey(int id, const char* suffix) { + Message key; + key << "key_" << id << "_" << suffix; + return key.GetString(); +} + +std::string IdToString(int id) { + Message id_message; + id_message << id; + return id_message.GetString(); +} + +void ExpectKeyAndValueWereRecordedForId( + const std::vector& properties, + int id, const char* suffix) { + TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str()); + const std::vector::const_iterator property = + std::find_if(properties.begin(), properties.end(), matches_key); + ASSERT_TRUE(property != properties.end()) + << "expecting " << suffix << " value for id " << id; + EXPECT_STREQ(IdToString(id).c_str(), property->value()); +} + +// Calls a large number of Google Test assertions, where exactly one of them +// will fail. +void ManyAsserts(int id) { + GTEST_LOG_(INFO) << "Thread #" << id << " running..."; + + SCOPED_TRACE(Message() << "Thread #" << id); + + for (int i = 0; i < kThreadCount; i++) { + SCOPED_TRACE(Message() << "Iteration #" << i); + + // A bunch of assertions that should succeed. + EXPECT_TRUE(true); + ASSERT_FALSE(false) << "This shouldn't fail."; + EXPECT_STREQ("a", "a"); + ASSERT_LE(5, 6); + EXPECT_EQ(i, i) << "This shouldn't fail."; + + // RecordProperty() should interact safely with other threads as well. + // The shared_key forces property updates. + Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str()); + Test::RecordProperty(IdToKey(id, "int").c_str(), id); + Test::RecordProperty("shared_key", IdToString(id).c_str()); + + // This assertion should fail kThreadCount times per thread. It + // is for testing whether Google Test can handle failed assertions in a + // multi-threaded context. + EXPECT_LT(i, 0) << "This should always fail."; + } +} + +void CheckTestFailureCount(int expected_failures) { + const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); + const TestResult* const result = info->result(); + GTEST_CHECK_(expected_failures == result->total_part_count()) + << "Logged " << result->total_part_count() << " failures " + << " vs. " << expected_failures << " expected"; +} + +// Tests using SCOPED_TRACE() and Google Test assertions in many threads +// concurrently. +TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { + { + scoped_ptr > threads[kThreadCount]; + Notification threads_can_start; + for (int i = 0; i != kThreadCount; i++) + threads[i].reset(new ThreadWithParam(&ManyAsserts, + i, + &threads_can_start)); + + threads_can_start.Notify(); + + // Blocks until all the threads are done. + for (int i = 0; i != kThreadCount; i++) + threads[i]->Join(); + } + + // Ensures that kThreadCount*kThreadCount failures have been reported. + const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); + const TestResult* const result = info->result(); + + std::vector properties; + // We have no access to the TestResult's list of properties but we can + // copy them one by one. + for (int i = 0; i < result->test_property_count(); ++i) + properties.push_back(result->GetTestProperty(i)); + + EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count()) + << "String and int values recorded on each thread, " + << "as well as one shared_key"; + for (int i = 0; i < kThreadCount; ++i) { + ExpectKeyAndValueWereRecordedForId(properties, i, "string"); + ExpectKeyAndValueWereRecordedForId(properties, i, "int"); + } + CheckTestFailureCount(kThreadCount*kThreadCount); +} + +void FailingThread(bool is_fatal) { + if (is_fatal) + FAIL() << "Fatal failure in some other thread. " + << "(This failure is expected.)"; + else + ADD_FAILURE() << "Non-fatal failure in some other thread. " + << "(This failure is expected.)"; +} + +void GenerateFatalFailureInAnotherThread(bool is_fatal) { + ThreadWithParam thread(&FailingThread, is_fatal, NULL); + thread.Join(); +} + +TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) { + EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); + // We should only have one failure (the one from + // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE + // should succeed. + CheckTestFailureCount(1); +} + +void AssertNoFatalFailureIgnoresFailuresInOtherThreads() { + ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); +} +TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) { + // Using a subroutine, to make sure, that the test continues. + AssertNoFatalFailureIgnoresFailuresInOtherThreads(); + // We should only have one failure (the one from + // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE + // should succeed. + CheckTestFailureCount(1); +} + +TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) { + // This statement should fail, since the current thread doesn't generate a + // fatal failure, only another one does. + EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected"); + CheckTestFailureCount(2); +} + +TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) { + // This statement should succeed, because failures in all threads are + // considered. + EXPECT_FATAL_FAILURE_ON_ALL_THREADS( + GenerateFatalFailureInAnotherThread(true), "expected"); + CheckTestFailureCount(0); + // We need to add a failure, because main() checks that there are failures. + // But when only this test is run, we shouldn't have any failures. + ADD_FAILURE() << "This is an expected non-fatal failure."; +} + +TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) { + // This statement should fail, since the current thread doesn't generate a + // fatal failure, only another one does. + EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false), + "expected"); + CheckTestFailureCount(2); +} + +TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) { + // This statement should succeed, because failures in all threads are + // considered. + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( + GenerateFatalFailureInAnotherThread(false), "expected"); + CheckTestFailureCount(0); + // We need to add a failure, because main() checks that there are failures, + // But when only this test is run, we shouldn't have any failures. + ADD_FAILURE() << "This is an expected non-fatal failure."; +} + +} // namespace +} // namespace testing + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + const int result = RUN_ALL_TESTS(); // Expected to fail. + GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected"; + + printf("\nPASS\n"); + return 0; +} + +#else +TEST(StressTest, + DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) { +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif // GTEST_IS_THREADSAFE diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_test_utils.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_test_utils.py new file mode 100755 index 0000000..28884bd --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_test_utils.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test utilities for Google C++ Testing Framework.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import atexit +import os +import shutil +import sys +import tempfile +import unittest +_test_module = unittest + +# Suppresses the 'Import not at the top of the file' lint complaint. +# pylint: disable-msg=C6204 +try: + import subprocess + _SUBPROCESS_MODULE_AVAILABLE = True +except: + import popen2 + _SUBPROCESS_MODULE_AVAILABLE = False +# pylint: enable-msg=C6204 + +GTEST_OUTPUT_VAR_NAME = 'GTEST_OUTPUT' + +IS_WINDOWS = os.name == 'nt' +IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] + +# The environment variable for specifying the path to the premature-exit file. +PREMATURE_EXIT_FILE_ENV_VAR = 'TEST_PREMATURE_EXIT_FILE' + +environ = os.environ.copy() + + +def SetEnvVar(env_var, value): + """Sets/unsets an environment variable to a given value.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +# Here we expose a class from a particular module, depending on the +# environment. The comment suppresses the 'Invalid variable name' lint +# complaint. +TestCase = _test_module.TestCase # pylint: disable-msg=C6409 + +# Initially maps a flag to its default value. After +# _ParseAndStripGTestFlags() is called, maps a flag to its actual value. +_flag_map = {'source_dir': os.path.dirname(sys.argv[0]), + 'build_dir': os.path.dirname(sys.argv[0])} +_gtest_flags_are_parsed = False + + +def _ParseAndStripGTestFlags(argv): + """Parses and strips Google Test flags from argv. This is idempotent.""" + + # Suppresses the lint complaint about a global variable since we need it + # here to maintain module-wide state. + global _gtest_flags_are_parsed # pylint: disable-msg=W0603 + if _gtest_flags_are_parsed: + return + + _gtest_flags_are_parsed = True + for flag in _flag_map: + # The environment variable overrides the default value. + if flag.upper() in os.environ: + _flag_map[flag] = os.environ[flag.upper()] + + # The command line flag overrides the environment variable. + i = 1 # Skips the program name. + while i < len(argv): + prefix = '--' + flag + '=' + if argv[i].startswith(prefix): + _flag_map[flag] = argv[i][len(prefix):] + del argv[i] + break + else: + # We don't increment i in case we just found a --gtest_* flag + # and removed it from argv. + i += 1 + + +def GetFlag(flag): + """Returns the value of the given flag.""" + + # In case GetFlag() is called before Main(), we always call + # _ParseAndStripGTestFlags() here to make sure the --gtest_* flags + # are parsed. + _ParseAndStripGTestFlags(sys.argv) + + return _flag_map[flag] + + +def GetSourceDir(): + """Returns the absolute path of the directory where the .py files are.""" + + return os.path.abspath(GetFlag('source_dir')) + + +def GetBuildDir(): + """Returns the absolute path of the directory where the test binaries are.""" + + return os.path.abspath(GetFlag('build_dir')) + + +_temp_dir = None + +def _RemoveTempDir(): + if _temp_dir: + shutil.rmtree(_temp_dir, ignore_errors=True) + +atexit.register(_RemoveTempDir) + + +def GetTempDir(): + """Returns a directory for temporary files.""" + + global _temp_dir + if not _temp_dir: + _temp_dir = tempfile.mkdtemp() + return _temp_dir + + +def GetTestExecutablePath(executable_name, build_dir=None): + """Returns the absolute path of the test binary given its name. + + The function will print a message and abort the program if the resulting file + doesn't exist. + + Args: + executable_name: name of the test binary that the test script runs. + build_dir: directory where to look for executables, by default + the result of GetBuildDir(). + + Returns: + The absolute path of the test binary. + """ + + path = os.path.abspath(os.path.join(build_dir or GetBuildDir(), + executable_name)) + if (IS_WINDOWS or IS_CYGWIN) and not path.endswith('.exe'): + path += '.exe' + + if not os.path.exists(path): + message = ( + 'Unable to find the test binary. Please make sure to provide path\n' + 'to the binary via the --build_dir flag or the BUILD_DIR\n' + 'environment variable.') + print >> sys.stderr, message + sys.exit(1) + + return path + + +def GetExitStatus(exit_code): + """Returns the argument to exit(), or -1 if exit() wasn't called. + + Args: + exit_code: the result value of os.system(command). + """ + + if os.name == 'nt': + # On Windows, os.WEXITSTATUS() doesn't work and os.system() returns + # the argument to exit() directly. + return exit_code + else: + # On Unix, os.WEXITSTATUS() must be used to extract the exit status + # from the result of os.system(). + if os.WIFEXITED(exit_code): + return os.WEXITSTATUS(exit_code) + else: + return -1 + + +class Subprocess: + def __init__(self, command, working_dir=None, capture_stderr=True, env=None): + """Changes into a specified directory, if provided, and executes a command. + + Restores the old directory afterwards. + + Args: + command: The command to run, in the form of sys.argv. + working_dir: The directory to change into. + capture_stderr: Determines whether to capture stderr in the output member + or to discard it. + env: Dictionary with environment to pass to the subprocess. + + Returns: + An object that represents outcome of the executed process. It has the + following attributes: + terminated_by_signal True iff the child process has been terminated + by a signal. + signal Sygnal that terminated the child process. + exited True iff the child process exited normally. + exit_code The code with which the child process exited. + output Child process's stdout and stderr output + combined in a string. + """ + + # The subprocess module is the preferrable way of running programs + # since it is available and behaves consistently on all platforms, + # including Windows. But it is only available starting in python 2.4. + # In earlier python versions, we revert to the popen2 module, which is + # available in python 2.0 and later but doesn't provide required + # functionality (Popen4) under Windows. This allows us to support Mac + # OS X 10.4 Tiger, which has python 2.3 installed. + if _SUBPROCESS_MODULE_AVAILABLE: + if capture_stderr: + stderr = subprocess.STDOUT + else: + stderr = subprocess.PIPE + + p = subprocess.Popen(command, + stdout=subprocess.PIPE, stderr=stderr, + cwd=working_dir, universal_newlines=True, env=env) + # communicate returns a tuple with the file obect for the child's + # output. + self.output = p.communicate()[0] + self._return_code = p.returncode + else: + old_dir = os.getcwd() + + def _ReplaceEnvDict(dest, src): + # Changes made by os.environ.clear are not inheritable by child + # processes until Python 2.6. To produce inheritable changes we have + # to delete environment items with the del statement. + for key in dest.keys(): + del dest[key] + dest.update(src) + + # When 'env' is not None, backup the environment variables and replace + # them with the passed 'env'. When 'env' is None, we simply use the + # current 'os.environ' for compatibility with the subprocess.Popen + # semantics used above. + if env is not None: + old_environ = os.environ.copy() + _ReplaceEnvDict(os.environ, env) + + try: + if working_dir is not None: + os.chdir(working_dir) + if capture_stderr: + p = popen2.Popen4(command) + else: + p = popen2.Popen3(command) + p.tochild.close() + self.output = p.fromchild.read() + ret_code = p.wait() + finally: + os.chdir(old_dir) + + # Restore the old environment variables + # if they were replaced. + if env is not None: + _ReplaceEnvDict(os.environ, old_environ) + + # Converts ret_code to match the semantics of + # subprocess.Popen.returncode. + if os.WIFSIGNALED(ret_code): + self._return_code = -os.WTERMSIG(ret_code) + else: # os.WIFEXITED(ret_code) should return True here. + self._return_code = os.WEXITSTATUS(ret_code) + + if self._return_code < 0: + self.terminated_by_signal = True + self.exited = False + self.signal = -self._return_code + else: + self.terminated_by_signal = False + self.exited = True + self.exit_code = self._return_code + + +def Main(): + """Runs the unit test.""" + + # We must call _ParseAndStripGTestFlags() before calling + # unittest.main(). Otherwise the latter will be confused by the + # --gtest_* flags. + _ParseAndStripGTestFlags(sys.argv) + # The tested binaries should not be writing XML output files unless the + # script explicitly instructs them to. + # TODO(vladl@google.com): Move this into Subprocess when we implement + # passing environment into it as a parameter. + if GTEST_OUTPUT_VAR_NAME in os.environ: + del os.environ[GTEST_OUTPUT_VAR_NAME] + + _test_module.main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_ex_test.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_ex_test.cc new file mode 100644 index 0000000..8d46c76 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_ex_test.cc @@ -0,0 +1,92 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests Google Test's throw-on-failure mode with exceptions enabled. + +#include "gtest/gtest.h" + +#include +#include +#include +#include + +// Prints the given failure message and exits the program with +// non-zero. We use this instead of a Google Test assertion to +// indicate a failure, as the latter is been tested and cannot be +// relied on. +void Fail(const char* msg) { + printf("FAILURE: %s\n", msg); + fflush(stdout); + exit(1); +} + +// Tests that an assertion failure throws a subclass of +// std::runtime_error. +void TestFailureThrowsRuntimeError() { + testing::GTEST_FLAG(throw_on_failure) = true; + + // A successful assertion shouldn't throw. + try { + EXPECT_EQ(3, 3); + } catch(...) { + Fail("A successful assertion wrongfully threw."); + } + + // A failed assertion should throw a subclass of std::runtime_error. + try { + EXPECT_EQ(2, 3) << "Expected failure"; + } catch(const std::runtime_error& e) { + if (strstr(e.what(), "Expected failure") != NULL) + return; + + printf("%s", + "A failed assertion did throw an exception of the right type, " + "but the message is incorrect. Instead of containing \"Expected " + "failure\", it is:\n"); + Fail(e.what()); + } catch(...) { + Fail("A failed assertion threw the wrong type of exception."); + } + Fail("A failed assertion should've thrown but didn't."); +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + // We want to ensure that people can use Google Test assertions in + // other testing frameworks, as long as they initialize Google Test + // properly and set the thrown-on-failure mode. Therefore, we don't + // use Google Test's constructs for defining and running tests + // (e.g. TEST and RUN_ALL_TESTS) here. + + TestFailureThrowsRuntimeError(); + return 0; +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_test.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_test.py new file mode 100755 index 0000000..5678ffe --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_test.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# 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. + +"""Tests Google Test's throw-on-failure mode with exceptions disabled. + +This script invokes gtest_throw_on_failure_test_ (a program written with +Google Test) with different environments and command line flags. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + + +# Constants. + +# The command line flag for enabling/disabling the throw-on-failure mode. +THROW_ON_FAILURE = 'gtest_throw_on_failure' + +# Path to the gtest_throw_on_failure_test_ program, compiled with +# exceptions disabled. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_throw_on_failure_test_') + + +# Utilities. + + +def SetEnvVar(env_var, value): + """Sets an environment variable to a given value; unsets it when the + given value is None. + """ + + env_var = env_var.upper() + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def Run(command): + """Runs a command; returns True/False if its exit code is/isn't 0.""" + + print 'Running "%s". . .' % ' '.join(command) + p = gtest_test_utils.Subprocess(command) + return p.exited and p.exit_code == 0 + + +# The tests. TODO(wan@google.com): refactor the class to share common +# logic with code in gtest_break_on_failure_unittest.py. +class ThrowOnFailureTest(gtest_test_utils.TestCase): + """Tests the throw-on-failure mode.""" + + def RunAndVerify(self, env_var_value, flag_value, should_fail): + """Runs gtest_throw_on_failure_test_ and verifies that it does + (or does not) exit with a non-zero code. + + Args: + env_var_value: value of the GTEST_BREAK_ON_FAILURE environment + variable; None if the variable should be unset. + flag_value: value of the --gtest_break_on_failure flag; + None if the flag should not be present. + should_fail: True iff the program is expected to fail. + """ + + SetEnvVar(THROW_ON_FAILURE, env_var_value) + + if env_var_value is None: + env_var_value_msg = ' is not set' + else: + env_var_value_msg = '=' + env_var_value + + if flag_value is None: + flag = '' + elif flag_value == '0': + flag = '--%s=0' % THROW_ON_FAILURE + else: + flag = '--%s' % THROW_ON_FAILURE + + command = [EXE_PATH] + if flag: + command.append(flag) + + if should_fail: + should_or_not = 'should' + else: + should_or_not = 'should not' + + failed = not Run(command) + + SetEnvVar(THROW_ON_FAILURE, None) + + msg = ('when %s%s, an assertion failure in "%s" %s cause a non-zero ' + 'exit code.' % + (THROW_ON_FAILURE, env_var_value_msg, ' '.join(command), + should_or_not)) + self.assert_(failed == should_fail, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(env_var_value=None, flag_value=None, should_fail=False) + + def testThrowOnFailureEnvVar(self): + """Tests using the GTEST_THROW_ON_FAILURE environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value=None, + should_fail=False) + self.RunAndVerify(env_var_value='1', + flag_value=None, + should_fail=True) + + def testThrowOnFailureFlag(self): + """Tests using the --gtest_throw_on_failure flag.""" + + self.RunAndVerify(env_var_value=None, + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value=None, + flag_value='1', + should_fail=True) + + def testThrowOnFailureFlagOverridesEnvVar(self): + """Tests that --gtest_throw_on_failure overrides GTEST_THROW_ON_FAILURE.""" + + self.RunAndVerify(env_var_value='0', + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value='0', + flag_value='1', + should_fail=True) + self.RunAndVerify(env_var_value='1', + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value='1', + flag_value='1', + should_fail=True) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_test_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_test_.cc new file mode 100644 index 0000000..2b88fe3 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_throw_on_failure_test_.cc @@ -0,0 +1,72 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests Google Test's throw-on-failure mode with exceptions disabled. +// +// This program must be compiled with exceptions disabled. It will be +// invoked by gtest_throw_on_failure_test.py, and is expected to exit +// with non-zero in the throw-on-failure mode or 0 otherwise. + +#include "gtest/gtest.h" + +#include // for fflush, fprintf, NULL, etc. +#include // for exit +#include // for set_terminate + +// This terminate handler aborts the program using exit() rather than abort(). +// This avoids showing pop-ups on Windows systems and core dumps on Unix-like +// ones. +void TerminateHandler() { + fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); + fflush(NULL); + exit(1); +} + +int main(int argc, char** argv) { +#if GTEST_HAS_EXCEPTIONS + std::set_terminate(&TerminateHandler); +#endif + testing::InitGoogleTest(&argc, argv); + + // We want to ensure that people can use Google Test assertions in + // other testing frameworks, as long as they initialize Google Test + // properly and set the throw-on-failure mode. Therefore, we don't + // use Google Test's constructs for defining and running tests + // (e.g. TEST and RUN_ALL_TESTS) here. + + // In the throw-on-failure mode with exceptions disabled, this + // assertion will cause the program to exit with a non-zero code. + EXPECT_EQ(2, 3); + + // When not in the throw-on-failure mode, the control will reach + // here. + return 0; +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_uninitialized_test.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_uninitialized_test.py new file mode 100755 index 0000000..6ae57ee --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_uninitialized_test.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""Verifies that Google Test warns the user when not initialized properly.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils + + +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_') + + +def Assert(condition): + if not condition: + raise AssertionError + + +def AssertEq(expected, actual): + if expected != actual: + print 'Expected: %s' % (expected,) + print ' Actual: %s' % (actual,) + raise AssertionError + + +def TestExitCodeAndOutput(command): + """Runs the given command and verifies its exit code and output.""" + + # Verifies that 'command' exits with code 1. + p = gtest_test_utils.Subprocess(command) + Assert(p.exited) + AssertEq(1, p.exit_code) + Assert('InitGoogleTest' in p.output) + + +class GTestUninitializedTest(gtest_test_utils.TestCase): + def testExitCodeAndOutput(self): + TestExitCodeAndOutput(COMMAND) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_uninitialized_test_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_uninitialized_test_.cc new file mode 100644 index 0000000..4431698 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_uninitialized_test_.cc @@ -0,0 +1,43 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest.h" + +TEST(DummyTest, Dummy) { + // This test doesn't verify anything. We just need it to create a + // realistic stage for testing the behavior of Google Test when + // RUN_ALL_TESTS() is called without testing::InitGoogleTest() being + // called first. +} + +int main() { + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_unittest.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_unittest.cc new file mode 100644 index 0000000..0cab07d --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_unittest.cc @@ -0,0 +1,7415 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for Google Test itself. This verifies that the basic constructs of +// Google Test work. + +#include "gtest/gtest.h" + +// Verifies that the command line flag variables can be accessed +// in code once has been #included. +// Do not move it after other #includes. +TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { + bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) + || testing::GTEST_FLAG(break_on_failure) + || testing::GTEST_FLAG(catch_exceptions) + || testing::GTEST_FLAG(color) != "unknown" + || testing::GTEST_FLAG(filter) != "unknown" + || testing::GTEST_FLAG(list_tests) + || testing::GTEST_FLAG(output) != "unknown" + || testing::GTEST_FLAG(print_time) + || testing::GTEST_FLAG(random_seed) + || testing::GTEST_FLAG(repeat) > 0 + || testing::GTEST_FLAG(show_internal_stack_frames) + || testing::GTEST_FLAG(shuffle) + || testing::GTEST_FLAG(stack_trace_depth) > 0 + || testing::GTEST_FLAG(stream_result_to) != "unknown" + || testing::GTEST_FLAG(throw_on_failure); + EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. +} + +#include // For INT_MAX. +#include +#include +#include + +#include +#include +#include + +#include "gtest/gtest-spi.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if GTEST_CAN_STREAM_RESULTS_ + +class StreamingListenerTest : public Test { + public: + class FakeSocketWriter : public StreamingListener::AbstractSocketWriter { + public: + // Sends a string to the socket. + virtual void Send(const string& message) { output_ += message; } + + string output_; + }; + + StreamingListenerTest() + : fake_sock_writer_(new FakeSocketWriter), + streamer_(fake_sock_writer_), + test_info_obj_("FooTest", "Bar", NULL, NULL, 0, NULL) {} + + protected: + string* output() { return &(fake_sock_writer_->output_); } + + FakeSocketWriter* const fake_sock_writer_; + StreamingListener streamer_; + UnitTest unit_test_; + TestInfo test_info_obj_; // The name test_info_ was taken by testing::Test. +}; + +TEST_F(StreamingListenerTest, OnTestProgramEnd) { + *output() = ""; + streamer_.OnTestProgramEnd(unit_test_); + EXPECT_EQ("event=TestProgramEnd&passed=1\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestIterationEnd) { + *output() = ""; + streamer_.OnTestIterationEnd(unit_test_, 42); + EXPECT_EQ("event=TestIterationEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestCaseStart) { + *output() = ""; + streamer_.OnTestCaseStart(TestCase("FooTest", "Bar", NULL, NULL)); + EXPECT_EQ("event=TestCaseStart&name=FooTest\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestCaseEnd) { + *output() = ""; + streamer_.OnTestCaseEnd(TestCase("FooTest", "Bar", NULL, NULL)); + EXPECT_EQ("event=TestCaseEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestStart) { + *output() = ""; + streamer_.OnTestStart(test_info_obj_); + EXPECT_EQ("event=TestStart&name=Bar\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestEnd) { + *output() = ""; + streamer_.OnTestEnd(test_info_obj_); + EXPECT_EQ("event=TestEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestPartResult) { + *output() = ""; + streamer_.OnTestPartResult(TestPartResult( + TestPartResult::kFatalFailure, "foo.cc", 42, "failed=\n&%")); + + // Meta characters in the failure message should be properly escaped. + EXPECT_EQ( + "event=TestPartResult&file=foo.cc&line=42&message=failed%3D%0A%26%25\n", + *output()); +} + +#endif // GTEST_CAN_STREAM_RESULTS_ + +// Provides access to otherwise private parts of the TestEventListeners class +// that are needed to test it. +class TestEventListenersAccessor { + public: + static TestEventListener* GetRepeater(TestEventListeners* listeners) { + return listeners->repeater(); + } + + static void SetDefaultResultPrinter(TestEventListeners* listeners, + TestEventListener* listener) { + listeners->SetDefaultResultPrinter(listener); + } + static void SetDefaultXmlGenerator(TestEventListeners* listeners, + TestEventListener* listener) { + listeners->SetDefaultXmlGenerator(listener); + } + + static bool EventForwardingEnabled(const TestEventListeners& listeners) { + return listeners.EventForwardingEnabled(); + } + + static void SuppressEventForwarding(TestEventListeners* listeners) { + listeners->SuppressEventForwarding(); + } +}; + +class UnitTestRecordPropertyTestHelper : public Test { + protected: + UnitTestRecordPropertyTestHelper() {} + + // Forwards to UnitTest::RecordProperty() to bypass access controls. + void UnitTestRecordProperty(const char* key, const std::string& value) { + unit_test_.RecordProperty(key, value); + } + + UnitTest unit_test_; +}; + +} // namespace internal +} // namespace testing + +using testing::AssertionFailure; +using testing::AssertionResult; +using testing::AssertionSuccess; +using testing::DoubleLE; +using testing::EmptyTestEventListener; +using testing::Environment; +using testing::FloatLE; +using testing::GTEST_FLAG(also_run_disabled_tests); +using testing::GTEST_FLAG(break_on_failure); +using testing::GTEST_FLAG(catch_exceptions); +using testing::GTEST_FLAG(color); +using testing::GTEST_FLAG(death_test_use_fork); +using testing::GTEST_FLAG(filter); +using testing::GTEST_FLAG(list_tests); +using testing::GTEST_FLAG(output); +using testing::GTEST_FLAG(print_time); +using testing::GTEST_FLAG(random_seed); +using testing::GTEST_FLAG(repeat); +using testing::GTEST_FLAG(show_internal_stack_frames); +using testing::GTEST_FLAG(shuffle); +using testing::GTEST_FLAG(stack_trace_depth); +using testing::GTEST_FLAG(stream_result_to); +using testing::GTEST_FLAG(throw_on_failure); +using testing::IsNotSubstring; +using testing::IsSubstring; +using testing::Message; +using testing::ScopedFakeTestPartResultReporter; +using testing::StaticAssertTypeEq; +using testing::Test; +using testing::TestCase; +using testing::TestEventListeners; +using testing::TestInfo; +using testing::TestPartResult; +using testing::TestPartResultArray; +using testing::TestProperty; +using testing::TestResult; +using testing::TimeInMillis; +using testing::UnitTest; +using testing::kMaxStackTraceDepth; +using testing::internal::AddReference; +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; +using testing::internal::AppendUserMessage; +using testing::internal::ArrayAwareFind; +using testing::internal::ArrayEq; +using testing::internal::CodePointToUtf8; +using testing::internal::CompileAssertTypesEqual; +using testing::internal::CopyArray; +using testing::internal::CountIf; +using testing::internal::EqFailure; +using testing::internal::FloatingPoint; +using testing::internal::ForEach; +using testing::internal::FormatEpochTimeInMillisAsIso8601; +using testing::internal::FormatTimeInMillisAsSeconds; +using testing::internal::GTestFlagSaver; +using testing::internal::GetCurrentOsStackTraceExceptTop; +using testing::internal::GetElementOr; +using testing::internal::GetNextRandomSeed; +using testing::internal::GetRandomSeedFromFlag; +using testing::internal::GetTestTypeId; +using testing::internal::GetTimeInMillis; +using testing::internal::GetTypeId; +using testing::internal::GetUnitTestImpl; +using testing::internal::ImplicitlyConvertible; +using testing::internal::Int32; +using testing::internal::Int32FromEnvOrDie; +using testing::internal::IsAProtocolMessage; +using testing::internal::IsContainer; +using testing::internal::IsContainerTest; +using testing::internal::IsNotContainer; +using testing::internal::NativeArray; +using testing::internal::ParseInt32Flag; +using testing::internal::RemoveConst; +using testing::internal::RemoveReference; +using testing::internal::ShouldRunTestOnShard; +using testing::internal::ShouldShard; +using testing::internal::ShouldUseColor; +using testing::internal::Shuffle; +using testing::internal::ShuffleRange; +using testing::internal::SkipPrefix; +using testing::internal::StreamableToString; +using testing::internal::String; +using testing::internal::TestEventListenersAccessor; +using testing::internal::TestResultAccessor; +using testing::internal::UInt32; +using testing::internal::WideStringToUtf8; +using testing::internal::kCopy; +using testing::internal::kMaxRandomSeed; +using testing::internal::kReference; +using testing::internal::kTestTypeIdInGoogleTest; +using testing::internal::scoped_ptr; + +#if GTEST_HAS_STREAM_REDIRECTION +using testing::internal::CaptureStdout; +using testing::internal::GetCapturedStdout; +#endif + +#if GTEST_IS_THREADSAFE +using testing::internal::ThreadWithParam; +#endif + +class TestingVector : public std::vector { +}; + +::std::ostream& operator<<(::std::ostream& os, + const TestingVector& vector) { + os << "{ "; + for (size_t i = 0; i < vector.size(); i++) { + os << vector[i] << " "; + } + os << "}"; + return os; +} + +// This line tests that we can define tests in an unnamed namespace. +namespace { + +TEST(GetRandomSeedFromFlagTest, HandlesZero) { + const int seed = GetRandomSeedFromFlag(0); + EXPECT_LE(1, seed); + EXPECT_LE(seed, static_cast(kMaxRandomSeed)); +} + +TEST(GetRandomSeedFromFlagTest, PreservesValidSeed) { + EXPECT_EQ(1, GetRandomSeedFromFlag(1)); + EXPECT_EQ(2, GetRandomSeedFromFlag(2)); + EXPECT_EQ(kMaxRandomSeed - 1, GetRandomSeedFromFlag(kMaxRandomSeed - 1)); + EXPECT_EQ(static_cast(kMaxRandomSeed), + GetRandomSeedFromFlag(kMaxRandomSeed)); +} + +TEST(GetRandomSeedFromFlagTest, NormalizesInvalidSeed) { + const int seed1 = GetRandomSeedFromFlag(-1); + EXPECT_LE(1, seed1); + EXPECT_LE(seed1, static_cast(kMaxRandomSeed)); + + const int seed2 = GetRandomSeedFromFlag(kMaxRandomSeed + 1); + EXPECT_LE(1, seed2); + EXPECT_LE(seed2, static_cast(kMaxRandomSeed)); +} + +TEST(GetNextRandomSeedTest, WorksForValidInput) { + EXPECT_EQ(2, GetNextRandomSeed(1)); + EXPECT_EQ(3, GetNextRandomSeed(2)); + EXPECT_EQ(static_cast(kMaxRandomSeed), + GetNextRandomSeed(kMaxRandomSeed - 1)); + EXPECT_EQ(1, GetNextRandomSeed(kMaxRandomSeed)); + + // We deliberately don't test GetNextRandomSeed() with invalid + // inputs, as that requires death tests, which are expensive. This + // is fine as GetNextRandomSeed() is internal and has a + // straightforward definition. +} + +static void ClearCurrentTestPartResults() { + TestResultAccessor::ClearTestPartResults( + GetUnitTestImpl()->current_test_result()); +} + +// Tests GetTypeId. + +TEST(GetTypeIdTest, ReturnsSameValueForSameType) { + EXPECT_EQ(GetTypeId(), GetTypeId()); + EXPECT_EQ(GetTypeId(), GetTypeId()); +} + +class SubClassOfTest : public Test {}; +class AnotherSubClassOfTest : public Test {}; + +TEST(GetTypeIdTest, ReturnsDifferentValuesForDifferentTypes) { + EXPECT_NE(GetTypeId(), GetTypeId()); + EXPECT_NE(GetTypeId(), GetTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTypeId()); +} + +// Verifies that GetTestTypeId() returns the same value, no matter it +// is called from inside Google Test or outside of it. +TEST(GetTestTypeIdTest, ReturnsTheSameValueInsideOrOutsideOfGoogleTest) { + EXPECT_EQ(kTestTypeIdInGoogleTest, GetTestTypeId()); +} + +// Tests FormatTimeInMillisAsSeconds(). + +TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) { + EXPECT_EQ("0", FormatTimeInMillisAsSeconds(0)); +} + +TEST(FormatTimeInMillisAsSecondsTest, FormatsPositiveNumber) { + EXPECT_EQ("0.003", FormatTimeInMillisAsSeconds(3)); + EXPECT_EQ("0.01", FormatTimeInMillisAsSeconds(10)); + EXPECT_EQ("0.2", FormatTimeInMillisAsSeconds(200)); + EXPECT_EQ("1.2", FormatTimeInMillisAsSeconds(1200)); + EXPECT_EQ("3", FormatTimeInMillisAsSeconds(3000)); +} + +TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { + EXPECT_EQ("-0.003", FormatTimeInMillisAsSeconds(-3)); + EXPECT_EQ("-0.01", FormatTimeInMillisAsSeconds(-10)); + EXPECT_EQ("-0.2", FormatTimeInMillisAsSeconds(-200)); + EXPECT_EQ("-1.2", FormatTimeInMillisAsSeconds(-1200)); + EXPECT_EQ("-3", FormatTimeInMillisAsSeconds(-3000)); +} + +// Tests FormatEpochTimeInMillisAsIso8601(). The correctness of conversion +// for particular dates below was verified in Python using +// datetime.datetime.fromutctimestamp(/1000). + +// FormatEpochTimeInMillisAsIso8601 depends on the current timezone, so we +// have to set up a particular timezone to obtain predictable results. +class FormatEpochTimeInMillisAsIso8601Test : public Test { + public: + // On Cygwin, GCC doesn't allow unqualified integer literals to exceed + // 32 bits, even when 64-bit integer types are available. We have to + // force the constants to have a 64-bit type here. + static const TimeInMillis kMillisPerSec = 1000; + + private: + virtual void SetUp() { + saved_tz_ = NULL; +#if _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996 + // (function or variable may be unsafe + // for getenv, function is deprecated for + // strdup). + if (getenv("TZ")) + saved_tz_ = strdup(getenv("TZ")); +# pragma warning(pop) // Restores the warning state again. +#else + if (getenv("TZ")) + saved_tz_ = strdup(getenv("TZ")); +#endif + + // Set up the time zone for FormatEpochTimeInMillisAsIso8601 to use. We + // cannot use the local time zone because the function's output depends + // on the time zone. + SetTimeZone("UTC+00"); + } + + virtual void TearDown() { + SetTimeZone(saved_tz_); + free(const_cast(saved_tz_)); + saved_tz_ = NULL; + } + + static void SetTimeZone(const char* time_zone) { + // tzset() distinguishes between the TZ variable being present and empty + // and not being present, so we have to consider the case of time_zone + // being NULL. +#if _MSC_VER + // ...Unless it's MSVC, whose standard library's _putenv doesn't + // distinguish between an empty and a missing variable. + const std::string env_var = + std::string("TZ=") + (time_zone ? time_zone : ""); + _putenv(env_var.c_str()); +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996 + // (function is deprecated). + tzset(); +# pragma warning(pop) // Restores the warning state again. +#else + if (time_zone) { + setenv(("TZ"), time_zone, 1); + } else { + unsetenv("TZ"); + } + tzset(); +#endif + } + + const char* saved_tz_; +}; + +const TimeInMillis FormatEpochTimeInMillisAsIso8601Test::kMillisPerSec; + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsTwoDigitSegments) { + EXPECT_EQ("2011-10-31T18:52:42", + FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, MillisecondsDoNotAffectResult) { + EXPECT_EQ( + "2011-10-31T18:52:42", + FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec + 234)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsLeadingZeroes) { + EXPECT_EQ("2011-09-03T05:07:02", + FormatEpochTimeInMillisAsIso8601(1315026422 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, Prints24HourTime) { + EXPECT_EQ("2011-09-28T17:08:22", + FormatEpochTimeInMillisAsIso8601(1317229702 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsEpochStart) { + EXPECT_EQ("1970-01-01T00:00:00", FormatEpochTimeInMillisAsIso8601(0)); +} + +#if GTEST_CAN_COMPARE_NULL + +# ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +# endif + +// Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null +// pointer literal. +TEST(NullLiteralTest, IsTrueForNullLiterals) { + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(NULL)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L)); +} + +// Tests that GTEST_IS_NULL_LITERAL_(x) is false when x is not a null +// pointer literal. +TEST(NullLiteralTest, IsFalseForNonNullLiterals) { + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(1)); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(0.0)); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_('a')); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast(NULL))); +} + +# ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" suppressed them. +# pragma option pop +# endif + +#endif // GTEST_CAN_COMPARE_NULL +// +// Tests CodePointToUtf8(). + +// Tests that the NUL character L'\0' is encoded correctly. +TEST(CodePointToUtf8Test, CanEncodeNul) { + EXPECT_EQ("", CodePointToUtf8(L'\0')); +} + +// Tests that ASCII characters are encoded correctly. +TEST(CodePointToUtf8Test, CanEncodeAscii) { + EXPECT_EQ("a", CodePointToUtf8(L'a')); + EXPECT_EQ("Z", CodePointToUtf8(L'Z')); + EXPECT_EQ("&", CodePointToUtf8(L'&')); + EXPECT_EQ("\x7F", CodePointToUtf8(L'\x7F')); +} + +// Tests that Unicode code-points that have 8 to 11 bits are encoded +// as 110xxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode8To11Bits) { + // 000 1101 0011 => 110-00011 10-010011 + EXPECT_EQ("\xC3\x93", CodePointToUtf8(L'\xD3')); + + // 101 0111 0110 => 110-10101 10-110110 + // Some compilers (e.g., GCC on MinGW) cannot handle non-ASCII codepoints + // in wide strings and wide chars. In order to accomodate them, we have to + // introduce such character constants as integers. + EXPECT_EQ("\xD5\xB6", + CodePointToUtf8(static_cast(0x576))); +} + +// Tests that Unicode code-points that have 12 to 16 bits are encoded +// as 1110xxxx 10xxxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode12To16Bits) { + // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 + EXPECT_EQ("\xE0\xA3\x93", + CodePointToUtf8(static_cast(0x8D3))); + + // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 + EXPECT_EQ("\xEC\x9D\x8D", + CodePointToUtf8(static_cast(0xC74D))); +} + +#if !GTEST_WIDE_STRING_USES_UTF16_ +// Tests in this group require a wchar_t to hold > 16 bits, and thus +// are skipped on Windows, Cygwin, and Symbian, where a wchar_t is +// 16-bit wide. This code may not compile on those systems. + +// Tests that Unicode code-points that have 17 to 21 bits are encoded +// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode17To21Bits) { + // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 + EXPECT_EQ("\xF0\x90\xA3\x93", CodePointToUtf8(L'\x108D3')); + + // 0 0001 0000 0100 0000 0000 => 11110-000 10-010000 10-010000 10-000000 + EXPECT_EQ("\xF0\x90\x90\x80", CodePointToUtf8(L'\x10400')); + + // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 + EXPECT_EQ("\xF4\x88\x98\xB4", CodePointToUtf8(L'\x108634')); +} + +// Tests that encoding an invalid code-point generates the expected result. +TEST(CodePointToUtf8Test, CanEncodeInvalidCodePoint) { + EXPECT_EQ("(Invalid Unicode 0x1234ABCD)", CodePointToUtf8(L'\x1234ABCD')); +} + +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests WideStringToUtf8(). + +// Tests that the NUL character L'\0' is encoded correctly. +TEST(WideStringToUtf8Test, CanEncodeNul) { + EXPECT_STREQ("", WideStringToUtf8(L"", 0).c_str()); + EXPECT_STREQ("", WideStringToUtf8(L"", -1).c_str()); +} + +// Tests that ASCII strings are encoded correctly. +TEST(WideStringToUtf8Test, CanEncodeAscii) { + EXPECT_STREQ("a", WideStringToUtf8(L"a", 1).c_str()); + EXPECT_STREQ("ab", WideStringToUtf8(L"ab", 2).c_str()); + EXPECT_STREQ("a", WideStringToUtf8(L"a", -1).c_str()); + EXPECT_STREQ("ab", WideStringToUtf8(L"ab", -1).c_str()); +} + +// Tests that Unicode code-points that have 8 to 11 bits are encoded +// as 110xxxxx 10xxxxxx. +TEST(WideStringToUtf8Test, CanEncode8To11Bits) { + // 000 1101 0011 => 110-00011 10-010011 + EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", 1).c_str()); + EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", -1).c_str()); + + // 101 0111 0110 => 110-10101 10-110110 + const wchar_t s[] = { 0x576, '\0' }; + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, 1).c_str()); + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, -1).c_str()); +} + +// Tests that Unicode code-points that have 12 to 16 bits are encoded +// as 1110xxxx 10xxxxxx 10xxxxxx. +TEST(WideStringToUtf8Test, CanEncode12To16Bits) { + // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 + const wchar_t s1[] = { 0x8D3, '\0' }; + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, 1).c_str()); + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, -1).c_str()); + + // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 + const wchar_t s2[] = { 0xC74D, '\0' }; + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, 1).c_str()); + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, -1).c_str()); +} + +// Tests that the conversion stops when the function encounters \0 character. +TEST(WideStringToUtf8Test, StopsOnNulCharacter) { + EXPECT_STREQ("ABC", WideStringToUtf8(L"ABC\0XYZ", 100).c_str()); +} + +// Tests that the conversion stops when the function reaches the limit +// specified by the 'length' parameter. +TEST(WideStringToUtf8Test, StopsWhenLengthLimitReached) { + EXPECT_STREQ("ABC", WideStringToUtf8(L"ABCDEF", 3).c_str()); +} + +#if !GTEST_WIDE_STRING_USES_UTF16_ +// Tests that Unicode code-points that have 17 to 21 bits are encoded +// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. This code may not compile +// on the systems using UTF-16 encoding. +TEST(WideStringToUtf8Test, CanEncode17To21Bits) { + // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 + EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", 1).c_str()); + EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", -1).c_str()); + + // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 + EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", 1).c_str()); + EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", -1).c_str()); +} + +// Tests that encoding an invalid code-point generates the expected result. +TEST(WideStringToUtf8Test, CanEncodeInvalidCodePoint) { + EXPECT_STREQ("(Invalid Unicode 0xABCDFF)", + WideStringToUtf8(L"\xABCDFF", -1).c_str()); +} +#else // !GTEST_WIDE_STRING_USES_UTF16_ +// Tests that surrogate pairs are encoded correctly on the systems using +// UTF-16 encoding in the wide strings. +TEST(WideStringToUtf8Test, CanEncodeValidUtf16SUrrogatePairs) { + const wchar_t s[] = { 0xD801, 0xDC00, '\0' }; + EXPECT_STREQ("\xF0\x90\x90\x80", WideStringToUtf8(s, -1).c_str()); +} + +// Tests that encoding an invalid UTF-16 surrogate pair +// generates the expected result. +TEST(WideStringToUtf8Test, CanEncodeInvalidUtf16SurrogatePair) { + // Leading surrogate is at the end of the string. + const wchar_t s1[] = { 0xD800, '\0' }; + EXPECT_STREQ("\xED\xA0\x80", WideStringToUtf8(s1, -1).c_str()); + // Leading surrogate is not followed by the trailing surrogate. + const wchar_t s2[] = { 0xD800, 'M', '\0' }; + EXPECT_STREQ("\xED\xA0\x80M", WideStringToUtf8(s2, -1).c_str()); + // Trailing surrogate appearas without a leading surrogate. + const wchar_t s3[] = { 0xDC00, 'P', 'Q', 'R', '\0' }; + EXPECT_STREQ("\xED\xB0\x80PQR", WideStringToUtf8(s3, -1).c_str()); +} +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests that codepoint concatenation works correctly. +#if !GTEST_WIDE_STRING_USES_UTF16_ +TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + const wchar_t s[] = { 0x108634, 0xC74D, '\n', 0x576, 0x8D3, 0x108634, '\0'}; + EXPECT_STREQ( + "\xF4\x88\x98\xB4" + "\xEC\x9D\x8D" + "\n" + "\xD5\xB6" + "\xE0\xA3\x93" + "\xF4\x88\x98\xB4", + WideStringToUtf8(s, -1).c_str()); +} +#else +TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + const wchar_t s[] = { 0xC74D, '\n', 0x576, 0x8D3, '\0'}; + EXPECT_STREQ( + "\xEC\x9D\x8D" "\n" "\xD5\xB6" "\xE0\xA3\x93", + WideStringToUtf8(s, -1).c_str()); +} +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests the Random class. + +TEST(RandomDeathTest, GeneratesCrashesOnInvalidRange) { + testing::internal::Random random(42); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(0), + "Cannot generate a number in the range \\[0, 0\\)"); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(testing::internal::Random::kMaxRange + 1), + "Generation of a number in \\[0, 2147483649\\) was requested, " + "but this can only generate numbers in \\[0, 2147483648\\)"); +} + +TEST(RandomTest, GeneratesNumbersWithinRange) { + const UInt32 kRange = 10000; + testing::internal::Random random(12345); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random.Generate(kRange), kRange) << " for iteration " << i; + } + + testing::internal::Random random2(testing::internal::Random::kMaxRange); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random2.Generate(kRange), kRange) << " for iteration " << i; + } +} + +TEST(RandomTest, RepeatsWhenReseeded) { + const int kSeed = 123; + const int kArraySize = 10; + const UInt32 kRange = 10000; + UInt32 values[kArraySize]; + + testing::internal::Random random(kSeed); + for (int i = 0; i < kArraySize; i++) { + values[i] = random.Generate(kRange); + } + + random.Reseed(kSeed); + for (int i = 0; i < kArraySize; i++) { + EXPECT_EQ(values[i], random.Generate(kRange)) << " for iteration " << i; + } +} + +// Tests STL container utilities. + +// Tests CountIf(). + +static bool IsPositive(int n) { return n > 0; } + +TEST(ContainerUtilityTest, CountIf) { + std::vector v; + EXPECT_EQ(0, CountIf(v, IsPositive)); // Works for an empty container. + + v.push_back(-1); + v.push_back(0); + EXPECT_EQ(0, CountIf(v, IsPositive)); // Works when no value satisfies. + + v.push_back(2); + v.push_back(-10); + v.push_back(10); + EXPECT_EQ(2, CountIf(v, IsPositive)); +} + +// Tests ForEach(). + +static int g_sum = 0; +static void Accumulate(int n) { g_sum += n; } + +TEST(ContainerUtilityTest, ForEach) { + std::vector v; + g_sum = 0; + ForEach(v, Accumulate); + EXPECT_EQ(0, g_sum); // Works for an empty container; + + g_sum = 0; + v.push_back(1); + ForEach(v, Accumulate); + EXPECT_EQ(1, g_sum); // Works for a container with one element. + + g_sum = 0; + v.push_back(20); + v.push_back(300); + ForEach(v, Accumulate); + EXPECT_EQ(321, g_sum); +} + +// Tests GetElementOr(). +TEST(ContainerUtilityTest, GetElementOr) { + std::vector a; + EXPECT_EQ('x', GetElementOr(a, 0, 'x')); + + a.push_back('a'); + a.push_back('b'); + EXPECT_EQ('a', GetElementOr(a, 0, 'x')); + EXPECT_EQ('b', GetElementOr(a, 1, 'x')); + EXPECT_EQ('x', GetElementOr(a, -2, 'x')); + EXPECT_EQ('x', GetElementOr(a, 2, 'x')); +} + +TEST(ContainerUtilityDeathTest, ShuffleRange) { + std::vector a; + a.push_back(0); + a.push_back(1); + a.push_back(2); + testing::internal::Random random(1); + + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, -1, 1, &a), + "Invalid shuffle range start -1: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 4, 4, &a), + "Invalid shuffle range start 4: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 3, 2, &a), + "Invalid shuffle range finish 2: must be in range \\[3, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 3, 4, &a), + "Invalid shuffle range finish 4: must be in range \\[3, 3\\]"); +} + +class VectorShuffleTest : public Test { + protected: + static const int kVectorSize = 20; + + VectorShuffleTest() : random_(1) { + for (int i = 0; i < kVectorSize; i++) { + vector_.push_back(i); + } + } + + static bool VectorIsCorrupt(const TestingVector& vector) { + if (kVectorSize != static_cast(vector.size())) { + return true; + } + + bool found_in_vector[kVectorSize] = { false }; + for (size_t i = 0; i < vector.size(); i++) { + const int e = vector[i]; + if (e < 0 || e >= kVectorSize || found_in_vector[e]) { + return true; + } + found_in_vector[e] = true; + } + + // Vector size is correct, elements' range is correct, no + // duplicate elements. Therefore no corruption has occurred. + return false; + } + + static bool VectorIsNotCorrupt(const TestingVector& vector) { + return !VectorIsCorrupt(vector); + } + + static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) { + for (int i = begin; i < end; i++) { + if (i != vector[i]) { + return true; + } + } + return false; + } + + static bool RangeIsUnshuffled( + const TestingVector& vector, int begin, int end) { + return !RangeIsShuffled(vector, begin, end); + } + + static bool VectorIsShuffled(const TestingVector& vector) { + return RangeIsShuffled(vector, 0, static_cast(vector.size())); + } + + static bool VectorIsUnshuffled(const TestingVector& vector) { + return !VectorIsShuffled(vector); + } + + testing::internal::Random random_; + TestingVector vector_; +}; // class VectorShuffleTest + +const int VectorShuffleTest::kVectorSize; + +TEST_F(VectorShuffleTest, HandlesEmptyRange) { + // Tests an empty range at the beginning... + ShuffleRange(&random_, 0, 0, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + ShuffleRange(&random_, kVectorSize/2, kVectorSize/2, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...at the end... + ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and past the end. + ShuffleRange(&random_, kVectorSize, kVectorSize, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) { + // Tests a size one range at the beginning... + ShuffleRange(&random_, 0, 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and at the end. + ShuffleRange(&random_, kVectorSize - 1, kVectorSize, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +// Because we use our own random number generator and a fixed seed, +// we can guarantee that the following "random" tests will succeed. + +TEST_F(VectorShuffleTest, ShufflesEntireVector) { + Shuffle(&random_, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_; + + // Tests the first and last elements in particular to ensure that + // there are no off-by-one problems in our shuffle algorithm. + EXPECT_NE(0, vector_[0]); + EXPECT_NE(kVectorSize - 1, vector_[kVectorSize - 1]); +} + +TEST_F(VectorShuffleTest, ShufflesStartOfVector) { + const int kRangeSize = kVectorSize/2; + + ShuffleRange(&random_, 0, kRangeSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesEndOfVector) { + const int kRangeSize = kVectorSize / 2; + ShuffleRange(&random_, kRangeSize, kVectorSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) { + int kRangeSize = kVectorSize/3; + ShuffleRange(&random_, kRangeSize, 2*kRangeSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, 2*kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 2*kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesRepeatably) { + TestingVector vector2; + for (int i = 0; i < kVectorSize; i++) { + vector2.push_back(i); + } + + random_.Reseed(1234); + Shuffle(&random_, &vector_); + random_.Reseed(1234); + Shuffle(&random_, &vector2); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector2); + + for (int i = 0; i < kVectorSize; i++) { + EXPECT_EQ(vector_[i], vector2[i]) << " where i is " << i; + } +} + +// Tests the size of the AssertHelper class. + +TEST(AssertHelperTest, AssertHelperIsSmall) { + // To avoid breaking clients that use lots of assertions in one + // function, we cannot grow the size of AssertHelper. + EXPECT_LE(sizeof(testing::internal::AssertHelper), sizeof(void*)); +} + +// Tests String::EndsWithCaseInsensitive(). +TEST(StringTest, EndsWithCaseInsensitive) { + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "BAR")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobaR", "bar")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("", "")); + + EXPECT_FALSE(String::EndsWithCaseInsensitive("Foobar", "foo")); + EXPECT_FALSE(String::EndsWithCaseInsensitive("foobar", "Foo")); + EXPECT_FALSE(String::EndsWithCaseInsensitive("", "foo")); +} + +// C++Builder's preprocessor is buggy; it fails to expand macros that +// appear in macro parameters after wide char literals. Provide an alias +// for NULL as a workaround. +static const wchar_t* const kNull = NULL; + +// Tests String::CaseInsensitiveWideCStringEquals +TEST(StringTest, CaseInsensitiveWideCStringEquals) { + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(NULL, NULL)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", kNull)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"foobar")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", kNull)); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"foobar")); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"FOOBAR")); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar")); +} + +#if GTEST_OS_WINDOWS + +// Tests String::ShowWideCString(). +TEST(StringTest, ShowWideCString) { + EXPECT_STREQ("(null)", + String::ShowWideCString(NULL).c_str()); + EXPECT_STREQ("", String::ShowWideCString(L"").c_str()); + EXPECT_STREQ("foo", String::ShowWideCString(L"foo").c_str()); +} + +# if GTEST_OS_WINDOWS_MOBILE +TEST(StringTest, AnsiAndUtf16Null) { + EXPECT_EQ(NULL, String::AnsiToUtf16(NULL)); + EXPECT_EQ(NULL, String::Utf16ToAnsi(NULL)); +} + +TEST(StringTest, AnsiAndUtf16ConvertBasic) { + const char* ansi = String::Utf16ToAnsi(L"str"); + EXPECT_STREQ("str", ansi); + delete [] ansi; + const WCHAR* utf16 = String::AnsiToUtf16("str"); + EXPECT_EQ(0, wcsncmp(L"str", utf16, 3)); + delete [] utf16; +} + +TEST(StringTest, AnsiAndUtf16ConvertPathChars) { + const char* ansi = String::Utf16ToAnsi(L".:\\ \"*?"); + EXPECT_STREQ(".:\\ \"*?", ansi); + delete [] ansi; + const WCHAR* utf16 = String::AnsiToUtf16(".:\\ \"*?"); + EXPECT_EQ(0, wcsncmp(L".:\\ \"*?", utf16, 3)); + delete [] utf16; +} +# endif // GTEST_OS_WINDOWS_MOBILE + +#endif // GTEST_OS_WINDOWS + +// Tests TestProperty construction. +TEST(TestPropertyTest, StringValue) { + TestProperty property("key", "1"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("1", property.value()); +} + +// Tests TestProperty replacing a value. +TEST(TestPropertyTest, ReplaceStringValue) { + TestProperty property("key", "1"); + EXPECT_STREQ("1", property.value()); + property.SetValue("2"); + EXPECT_STREQ("2", property.value()); +} + +// AddFatalFailure() and AddNonfatalFailure() must be stand-alone +// functions (i.e. their definitions cannot be inlined at the call +// sites), or C++Builder won't compile the code. +static void AddFatalFailure() { + FAIL() << "Expected fatal failure."; +} + +static void AddNonfatalFailure() { + ADD_FAILURE() << "Expected non-fatal failure."; +} + +class ScopedFakeTestPartResultReporterTest : public Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + enum FailureMode { + FATAL_FAILURE, + NONFATAL_FAILURE + }; + static void AddFailure(FailureMode failure) { + if (failure == FATAL_FAILURE) { + AddFatalFailure(); + } else { + AddNonfatalFailure(); + } + } +}; + +// Tests that ScopedFakeTestPartResultReporter intercepts test +// failures. +TEST_F(ScopedFakeTestPartResultReporterTest, InterceptsTestFailures) { + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, + &results); + AddFailure(NONFATAL_FAILURE); + AddFailure(FATAL_FAILURE); + } + + EXPECT_EQ(2, results.size()); + EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); +} + +TEST_F(ScopedFakeTestPartResultReporterTest, DeprecatedConstructor) { + TestPartResultArray results; + { + // Tests, that the deprecated constructor still works. + ScopedFakeTestPartResultReporter reporter(&results); + AddFailure(NONFATAL_FAILURE); + } + EXPECT_EQ(1, results.size()); +} + +#if GTEST_IS_THREADSAFE + +class ScopedFakeTestPartResultReporterWithThreadsTest + : public ScopedFakeTestPartResultReporterTest { + protected: + static void AddFailureInOtherThread(FailureMode failure) { + ThreadWithParam thread(&AddFailure, failure, NULL); + thread.Join(); + } +}; + +TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest, + InterceptsTestFailuresInAllThreads) { + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, &results); + AddFailure(NONFATAL_FAILURE); + AddFailure(FATAL_FAILURE); + AddFailureInOtherThread(NONFATAL_FAILURE); + AddFailureInOtherThread(FATAL_FAILURE); + } + + EXPECT_EQ(4, results.size()); + EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(2).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(3).fatally_failed()); +} + +#endif // GTEST_IS_THREADSAFE + +// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. Makes sure that they +// work even if the failure is generated in a called function rather than +// the current context. + +typedef ScopedFakeTestPartResultReporterTest ExpectFatalFailureTest; + +TEST_F(ExpectFatalFailureTest, CatchesFatalFaliure) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), "Expected fatal failure."); +} + +#if GTEST_HAS_GLOBAL_STRING +TEST_F(ExpectFatalFailureTest, AcceptsStringObject) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), ::string("Expected fatal failure.")); +} +#endif + +TEST_F(ExpectFatalFailureTest, AcceptsStdStringObject) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), + ::std::string("Expected fatal failure.")); +} + +TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches fatal + // failures generated on another thread. + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFatalFailure(), + "Expected fatal failure."); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true" +# pragma option push -w-ccc +#endif + +// Tests that EXPECT_FATAL_FAILURE() can be used in a non-void +// function even when the statement in it contains ASSERT_*. + +int NonVoidFunction() { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + return 0; +} + +TEST_F(ExpectFatalFailureTest, CanBeUsedInNonVoidFunction) { + NonVoidFunction(); +} + +// Tests that EXPECT_FATAL_FAILURE(statement, ...) doesn't abort the +// current function even though 'statement' generates a fatal failure. + +void DoesNotAbortHelper(bool* aborted) { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + + *aborted = false; +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" suppressed them. +# pragma option pop +#endif + +TEST_F(ExpectFatalFailureTest, DoesNotAbort) { + bool aborted = true; + DoesNotAbortHelper(&aborted); + EXPECT_FALSE(aborted); +} + +// Tests that the EXPECT_FATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. + +static int global_var = 0; +#define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ + +TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFatalFailure(); + }, ""); +#endif + + EXPECT_FATAL_FAILURE_ON_ALL_THREADS({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFatalFailure(); + }, ""); +} + +// Tests EXPECT_NONFATAL_FAILURE{,ON_ALL_THREADS}. + +typedef ScopedFakeTestPartResultReporterTest ExpectNonfatalFailureTest; + +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailure) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + "Expected non-fatal failure."); +} + +#if GTEST_HAS_GLOBAL_STRING +TEST_F(ExpectNonfatalFailureTest, AcceptsStringObject) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + ::string("Expected non-fatal failure.")); +} +#endif + +TEST_F(ExpectNonfatalFailureTest, AcceptsStdStringObject) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + ::std::string("Expected non-fatal failure.")); +} + +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches + // non-fatal failures generated on another thread. + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddNonfatalFailure(), + "Expected non-fatal failure."); +} + +// Tests that the EXPECT_NONFATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. +TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { + EXPECT_NONFATAL_FAILURE({ + GTEST_USE_UNPROTECTED_COMMA_; + AddNonfatalFailure(); + }, ""); + + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS({ + GTEST_USE_UNPROTECTED_COMMA_; + AddNonfatalFailure(); + }, ""); +} + +#if GTEST_IS_THREADSAFE + +typedef ScopedFakeTestPartResultReporterWithThreadsTest + ExpectFailureWithThreadsTest; + +TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailureOnAllThreads) { + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailureInOtherThread(FATAL_FAILURE), + "Expected fatal failure."); +} + +TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) { + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( + AddFailureInOtherThread(NONFATAL_FAILURE), "Expected non-fatal failure."); +} + +#endif // GTEST_IS_THREADSAFE + +// Tests the TestProperty class. + +TEST(TestPropertyTest, ConstructorWorks) { + const TestProperty property("key", "value"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value", property.value()); +} + +TEST(TestPropertyTest, SetValue) { + TestProperty property("key", "value_1"); + EXPECT_STREQ("key", property.key()); + property.SetValue("value_2"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value_2", property.value()); +} + +// Tests the TestResult class + +// The test fixture for testing TestResult. +class TestResultTest : public Test { + protected: + typedef std::vector TPRVector; + + // We make use of 2 TestPartResult objects, + TestPartResult * pr1, * pr2; + + // ... and 3 TestResult objects. + TestResult * r0, * r1, * r2; + + virtual void SetUp() { + // pr1 is for success. + pr1 = new TestPartResult(TestPartResult::kSuccess, + "foo/bar.cc", + 10, + "Success!"); + + // pr2 is for fatal failure. + pr2 = new TestPartResult(TestPartResult::kFatalFailure, + "foo/bar.cc", + -1, // This line number means "unknown" + "Failure!"); + + // Creates the TestResult objects. + r0 = new TestResult(); + r1 = new TestResult(); + r2 = new TestResult(); + + // In order to test TestResult, we need to modify its internal + // state, in particular the TestPartResult vector it holds. + // test_part_results() returns a const reference to this vector. + // We cast it to a non-const object s.t. it can be modified (yes, + // this is a hack). + TPRVector* results1 = const_cast( + &TestResultAccessor::test_part_results(*r1)); + TPRVector* results2 = const_cast( + &TestResultAccessor::test_part_results(*r2)); + + // r0 is an empty TestResult. + + // r1 contains a single SUCCESS TestPartResult. + results1->push_back(*pr1); + + // r2 contains a SUCCESS, and a FAILURE. + results2->push_back(*pr1); + results2->push_back(*pr2); + } + + virtual void TearDown() { + delete pr1; + delete pr2; + + delete r0; + delete r1; + delete r2; + } + + // Helper that compares two two TestPartResults. + static void CompareTestPartResult(const TestPartResult& expected, + const TestPartResult& actual) { + EXPECT_EQ(expected.type(), actual.type()); + EXPECT_STREQ(expected.file_name(), actual.file_name()); + EXPECT_EQ(expected.line_number(), actual.line_number()); + EXPECT_STREQ(expected.summary(), actual.summary()); + EXPECT_STREQ(expected.message(), actual.message()); + EXPECT_EQ(expected.passed(), actual.passed()); + EXPECT_EQ(expected.failed(), actual.failed()); + EXPECT_EQ(expected.nonfatally_failed(), actual.nonfatally_failed()); + EXPECT_EQ(expected.fatally_failed(), actual.fatally_failed()); + } +}; + +// Tests TestResult::total_part_count(). +TEST_F(TestResultTest, total_part_count) { + ASSERT_EQ(0, r0->total_part_count()); + ASSERT_EQ(1, r1->total_part_count()); + ASSERT_EQ(2, r2->total_part_count()); +} + +// Tests TestResult::Passed(). +TEST_F(TestResultTest, Passed) { + ASSERT_TRUE(r0->Passed()); + ASSERT_TRUE(r1->Passed()); + ASSERT_FALSE(r2->Passed()); +} + +// Tests TestResult::Failed(). +TEST_F(TestResultTest, Failed) { + ASSERT_FALSE(r0->Failed()); + ASSERT_FALSE(r1->Failed()); + ASSERT_TRUE(r2->Failed()); +} + +// Tests TestResult::GetTestPartResult(). + +typedef TestResultTest TestResultDeathTest; + +TEST_F(TestResultDeathTest, GetTestPartResult) { + CompareTestPartResult(*pr1, r2->GetTestPartResult(0)); + CompareTestPartResult(*pr2, r2->GetTestPartResult(1)); + EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(2), ""); + EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(-1), ""); +} + +// Tests TestResult has no properties when none are added. +TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) { + TestResult test_result; + ASSERT_EQ(0, test_result.test_property_count()); +} + +// Tests TestResult has the expected property when added. +TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) { + TestResult test_result; + TestProperty property("key_1", "1"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property); + ASSERT_EQ(1, test_result.test_property_count()); + const TestProperty& actual_property = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property.key()); + EXPECT_STREQ("1", actual_property.value()); +} + +// Tests TestResult has multiple properties when added. +TEST(TestResultPropertyTest, MultiplePropertiesFoundWhenAdded) { + TestResult test_result; + TestProperty property_1("key_1", "1"); + TestProperty property_2("key_2", "2"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2); + ASSERT_EQ(2, test_result.test_property_count()); + const TestProperty& actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("1", actual_property_1.value()); + + const TestProperty& actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("2", actual_property_2.value()); +} + +// Tests TestResult::RecordProperty() overrides values for duplicate keys. +TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { + TestResult test_result; + TestProperty property_1_1("key_1", "1"); + TestProperty property_2_1("key_2", "2"); + TestProperty property_1_2("key_1", "12"); + TestProperty property_2_2("key_2", "22"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_2); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_2); + + ASSERT_EQ(2, test_result.test_property_count()); + const TestProperty& actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("12", actual_property_1.value()); + + const TestProperty& actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("22", actual_property_2.value()); +} + +// Tests TestResult::GetTestProperty(). +TEST(TestResultPropertyTest, GetTestProperty) { + TestResult test_result; + TestProperty property_1("key_1", "1"); + TestProperty property_2("key_2", "2"); + TestProperty property_3("key_3", "3"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_3); + + const TestProperty& fetched_property_1 = test_result.GetTestProperty(0); + const TestProperty& fetched_property_2 = test_result.GetTestProperty(1); + const TestProperty& fetched_property_3 = test_result.GetTestProperty(2); + + EXPECT_STREQ("key_1", fetched_property_1.key()); + EXPECT_STREQ("1", fetched_property_1.value()); + + EXPECT_STREQ("key_2", fetched_property_2.key()); + EXPECT_STREQ("2", fetched_property_2.value()); + + EXPECT_STREQ("key_3", fetched_property_3.key()); + EXPECT_STREQ("3", fetched_property_3.value()); + + EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(3), ""); + EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), ""); +} + +// Tests that GTestFlagSaver works on Windows and Mac. + +class GTestFlagSaverTest : public Test { + protected: + // Saves the Google Test flags such that we can restore them later, and + // then sets them to their default values. This will be called + // before the first test in this test case is run. + static void SetUpTestCase() { + saver_ = new GTestFlagSaver; + + GTEST_FLAG(also_run_disabled_tests) = false; + GTEST_FLAG(break_on_failure) = false; + GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(death_test_use_fork) = false; + GTEST_FLAG(color) = "auto"; + GTEST_FLAG(filter) = ""; + GTEST_FLAG(list_tests) = false; + GTEST_FLAG(output) = ""; + GTEST_FLAG(print_time) = true; + GTEST_FLAG(random_seed) = 0; + GTEST_FLAG(repeat) = 1; + GTEST_FLAG(shuffle) = false; + GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; + GTEST_FLAG(stream_result_to) = ""; + GTEST_FLAG(throw_on_failure) = false; + } + + // Restores the Google Test flags that the tests have modified. This will + // be called after the last test in this test case is run. + static void TearDownTestCase() { + delete saver_; + saver_ = NULL; + } + + // Verifies that the Google Test flags have their default values, and then + // modifies each of them. + void VerifyAndModifyFlags() { + EXPECT_FALSE(GTEST_FLAG(also_run_disabled_tests)); + EXPECT_FALSE(GTEST_FLAG(break_on_failure)); + EXPECT_FALSE(GTEST_FLAG(catch_exceptions)); + EXPECT_STREQ("auto", GTEST_FLAG(color).c_str()); + EXPECT_FALSE(GTEST_FLAG(death_test_use_fork)); + EXPECT_STREQ("", GTEST_FLAG(filter).c_str()); + EXPECT_FALSE(GTEST_FLAG(list_tests)); + EXPECT_STREQ("", GTEST_FLAG(output).c_str()); + EXPECT_TRUE(GTEST_FLAG(print_time)); + EXPECT_EQ(0, GTEST_FLAG(random_seed)); + EXPECT_EQ(1, GTEST_FLAG(repeat)); + EXPECT_FALSE(GTEST_FLAG(shuffle)); + EXPECT_EQ(kMaxStackTraceDepth, GTEST_FLAG(stack_trace_depth)); + EXPECT_STREQ("", GTEST_FLAG(stream_result_to).c_str()); + EXPECT_FALSE(GTEST_FLAG(throw_on_failure)); + + GTEST_FLAG(also_run_disabled_tests) = true; + GTEST_FLAG(break_on_failure) = true; + GTEST_FLAG(catch_exceptions) = true; + GTEST_FLAG(color) = "no"; + GTEST_FLAG(death_test_use_fork) = true; + GTEST_FLAG(filter) = "abc"; + GTEST_FLAG(list_tests) = true; + GTEST_FLAG(output) = "xml:foo.xml"; + GTEST_FLAG(print_time) = false; + GTEST_FLAG(random_seed) = 1; + GTEST_FLAG(repeat) = 100; + GTEST_FLAG(shuffle) = true; + GTEST_FLAG(stack_trace_depth) = 1; + GTEST_FLAG(stream_result_to) = "localhost:1234"; + GTEST_FLAG(throw_on_failure) = true; + } + + private: + // For saving Google Test flags during this test case. + static GTestFlagSaver* saver_; +}; + +GTestFlagSaver* GTestFlagSaverTest::saver_ = NULL; + +// Google Test doesn't guarantee the order of tests. The following two +// tests are designed to work regardless of their order. + +// Modifies the Google Test flags in the test body. +TEST_F(GTestFlagSaverTest, ModifyGTestFlags) { + VerifyAndModifyFlags(); +} + +// Verifies that the Google Test flags in the body of the previous test were +// restored to their original values. +TEST_F(GTestFlagSaverTest, VerifyGTestFlags) { + VerifyAndModifyFlags(); +} + +// Sets an environment variable with the given name to the given +// value. If the value argument is "", unsets the environment +// variable. The caller must ensure that both arguments are not NULL. +static void SetEnv(const char* name, const char* value) { +#if GTEST_OS_WINDOWS_MOBILE + // Environment variables are not supported on Windows CE. + return; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // C++Builder's putenv only stores a pointer to its parameter; we have to + // ensure that the string remains valid as long as it might be needed. + // We use an std::map to do so. + static std::map added_env; + + // Because putenv stores a pointer to the string buffer, we can't delete the + // previous string (if present) until after it's replaced. + std::string *prev_env = NULL; + if (added_env.find(name) != added_env.end()) { + prev_env = added_env[name]; + } + added_env[name] = new std::string( + (Message() << name << "=" << value).GetString()); + + // The standard signature of putenv accepts a 'char*' argument. Other + // implementations, like C++Builder's, accept a 'const char*'. + // We cast away the 'const' since that would work for both variants. + putenv(const_cast(added_env[name]->c_str())); + delete prev_env; +#elif GTEST_OS_WINDOWS // If we are on Windows proper. + _putenv((Message() << name << "=" << value).GetString().c_str()); +#else + if (*value == '\0') { + unsetenv(name); + } else { + setenv(name, value, 1); + } +#endif // GTEST_OS_WINDOWS_MOBILE +} + +#if !GTEST_OS_WINDOWS_MOBILE +// Environment variables are not supported on Windows CE. + +using testing::internal::Int32FromGTestEnv; + +// Tests Int32FromGTestEnv(). + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable is not set. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenVariableIsNotSet) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", ""); + EXPECT_EQ(10, Int32FromGTestEnv("temp", 10)); +} + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable overflows as an Int32. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueOverflows) { + printf("(expecting 2 warnings)\n"); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12345678987654321"); + EXPECT_EQ(20, Int32FromGTestEnv("temp", 20)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-12345678987654321"); + EXPECT_EQ(30, Int32FromGTestEnv("temp", 30)); +} + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable does not represent a valid decimal integer. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueIsInvalid) { + printf("(expecting 2 warnings)\n"); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "A1"); + EXPECT_EQ(40, Int32FromGTestEnv("temp", 40)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12X"); + EXPECT_EQ(50, Int32FromGTestEnv("temp", 50)); +} + +// Tests that Int32FromGTestEnv() parses and returns the value of the +// environment variable when it represents a valid decimal integer in +// the range of an Int32. +TEST(Int32FromGTestEnvTest, ParsesAndReturnsValidValue) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "123"); + EXPECT_EQ(123, Int32FromGTestEnv("temp", 0)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-321"); + EXPECT_EQ(-321, Int32FromGTestEnv("temp", 0)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests ParseInt32Flag(). + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag has wrong format +TEST(ParseInt32FlagTest, ReturnsFalseForInvalidFlag) { + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--a=100", "b", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("a=100", "a", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag overflows as an Int32. +TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueOverflows) { + printf("(expecting 2 warnings)\n"); + + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--abc=12345678987654321", "abc", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("--abc=-12345678987654321", "abc", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag does not represent a valid decimal +// integer. +TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueIsInvalid) { + printf("(expecting 2 warnings)\n"); + + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--abc=A1", "abc", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("--abc=12X", "abc", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() parses the value of the flag and +// returns true when the flag represents a valid decimal integer in +// the range of an Int32. +TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { + Int32 value = 123; + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=456", "abc", &value)); + EXPECT_EQ(456, value); + + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=-789", + "abc", &value)); + EXPECT_EQ(-789, value); +} + +// Tests that Int32FromEnvOrDie() parses the value of the var or +// returns the correct default. +// Environment variables are not supported on Windows CE. +#if !GTEST_OS_WINDOWS_MOBILE +TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { + EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "123"); + EXPECT_EQ(123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123"); + EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests that Int32FromEnvOrDie() aborts with an error message +// if the variable is not an Int32. +TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx"); + EXPECT_DEATH_IF_SUPPORTED( + Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), + ".*"); +} + +// Tests that Int32FromEnvOrDie() aborts with an error message +// if the variable cannot be represnted by an Int32. +TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); + EXPECT_DEATH_IF_SUPPORTED( + Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), + ".*"); +} + +// Tests that ShouldRunTestOnShard() selects all tests +// where there is 1 shard. +TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereIsOneShard) { + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 0)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 1)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 2)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 3)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 4)); +} + +class ShouldShardTest : public testing::Test { + protected: + virtual void SetUp() { + index_var_ = GTEST_FLAG_PREFIX_UPPER_ "INDEX"; + total_var_ = GTEST_FLAG_PREFIX_UPPER_ "TOTAL"; + } + + virtual void TearDown() { + SetEnv(index_var_, ""); + SetEnv(total_var_, ""); + } + + const char* index_var_; + const char* total_var_; +}; + +// Tests that sharding is disabled if neither of the environment variables +// are set. +TEST_F(ShouldShardTest, ReturnsFalseWhenNeitherEnvVarIsSet) { + SetEnv(index_var_, ""); + SetEnv(total_var_, ""); + + EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} + +// Tests that sharding is not enabled if total_shards == 1. +TEST_F(ShouldShardTest, ReturnsFalseWhenTotalShardIsOne) { + SetEnv(index_var_, "0"); + SetEnv(total_var_, "1"); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} + +// Tests that sharding is enabled if total_shards > 1 and +// we are not in a death test subprocess. +// Environment variables are not supported on Windows CE. +#if !GTEST_OS_WINDOWS_MOBILE +TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { + SetEnv(index_var_, "4"); + SetEnv(total_var_, "22"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); + + SetEnv(index_var_, "8"); + SetEnv(total_var_, "9"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); + + SetEnv(index_var_, "0"); + SetEnv(total_var_, "9"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests that we exit in error if the sharding values are not valid. + +typedef ShouldShardTest ShouldShardDeathTest; + +TEST_F(ShouldShardDeathTest, AbortsWhenShardingEnvVarsAreInvalid) { + SetEnv(index_var_, "4"); + SetEnv(total_var_, "4"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, "4"); + SetEnv(total_var_, "-2"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, "5"); + SetEnv(total_var_, ""); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, ""); + SetEnv(total_var_, "5"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); +} + +// Tests that ShouldRunTestOnShard is a partition when 5 +// shards are used. +TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereAreFiveShards) { + // Choose an arbitrary number of tests and shards. + const int num_tests = 17; + const int num_shards = 5; + + // Check partitioning: each test should be on exactly 1 shard. + for (int test_id = 0; test_id < num_tests; test_id++) { + int prev_selected_shard_index = -1; + for (int shard_index = 0; shard_index < num_shards; shard_index++) { + if (ShouldRunTestOnShard(num_shards, shard_index, test_id)) { + if (prev_selected_shard_index < 0) { + prev_selected_shard_index = shard_index; + } else { + ADD_FAILURE() << "Shard " << prev_selected_shard_index << " and " + << shard_index << " are both selected to run test " << test_id; + } + } + } + } + + // Check balance: This is not required by the sharding protocol, but is a + // desirable property for performance. + for (int shard_index = 0; shard_index < num_shards; shard_index++) { + int num_tests_on_shard = 0; + for (int test_id = 0; test_id < num_tests; test_id++) { + num_tests_on_shard += + ShouldRunTestOnShard(num_shards, shard_index, test_id); + } + EXPECT_GE(num_tests_on_shard, num_tests / num_shards); + } +} + +// For the same reason we are not explicitly testing everything in the +// Test class, there are no separate tests for the following classes +// (except for some trivial cases): +// +// TestCase, UnitTest, UnitTestResultPrinter. +// +// Similarly, there are no separate tests for the following macros: +// +// TEST, TEST_F, RUN_ALL_TESTS + +TEST(UnitTestTest, CanGetOriginalWorkingDir) { + ASSERT_TRUE(UnitTest::GetInstance()->original_working_dir() != NULL); + EXPECT_STRNE(UnitTest::GetInstance()->original_working_dir(), ""); +} + +TEST(UnitTestTest, ReturnsPlausibleTimestamp) { + EXPECT_LT(0, UnitTest::GetInstance()->start_timestamp()); + EXPECT_LE(UnitTest::GetInstance()->start_timestamp(), GetTimeInMillis()); +} + +// When a property using a reserved key is supplied to this function, it +// tests that a non-fatal failure is added, a fatal failure is not added, +// and that the property is not recorded. +void ExpectNonFatalFailureRecordingPropertyWithReservedKey( + const TestResult& test_result, const char* key) { + EXPECT_NONFATAL_FAILURE(Test::RecordProperty(key, "1"), "Reserved key"); + ASSERT_EQ(0, test_result.test_property_count()) << "Property for key '" << key + << "' recorded unexpectedly."; +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + const char* key) { + const TestInfo* test_info = UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(test_info != NULL); + ExpectNonFatalFailureRecordingPropertyWithReservedKey(*test_info->result(), + key); +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + const char* key) { + const TestCase* test_case = UnitTest::GetInstance()->current_test_case(); + ASSERT_TRUE(test_case != NULL); + ExpectNonFatalFailureRecordingPropertyWithReservedKey( + test_case->ad_hoc_test_result(), key); +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + const char* key) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey( + UnitTest::GetInstance()->ad_hoc_test_result(), key); +} + +// Tests that property recording functions in UnitTest outside of tests +// functions correcly. Creating a separate instance of UnitTest ensures it +// is in a state similar to the UnitTest's singleton's between tests. +class UnitTestRecordPropertyTest : + public testing::internal::UnitTestRecordPropertyTestHelper { + public: + static void SetUpTestCase() { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "disabled"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "errors"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "failures"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "tests"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "time"); + + Test::RecordProperty("test_case_key_1", "1"); + const TestCase* test_case = UnitTest::GetInstance()->current_test_case(); + ASSERT_TRUE(test_case != NULL); + + ASSERT_EQ(1, test_case->ad_hoc_test_result().test_property_count()); + EXPECT_STREQ("test_case_key_1", + test_case->ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", + test_case->ad_hoc_test_result().GetTestProperty(0).value()); + } +}; + +// Tests TestResult has the expected property when added. +TEST_F(UnitTestRecordPropertyTest, OnePropertyFoundWhenAdded) { + UnitTestRecordProperty("key_1", "1"); + + ASSERT_EQ(1, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); +} + +// Tests TestResult has multiple properties when added. +TEST_F(UnitTestRecordPropertyTest, MultiplePropertiesFoundWhenAdded) { + UnitTestRecordProperty("key_1", "1"); + UnitTestRecordProperty("key_2", "2"); + + ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); + + EXPECT_STREQ("key_2", + unit_test_.ad_hoc_test_result().GetTestProperty(1).key()); + EXPECT_STREQ("2", unit_test_.ad_hoc_test_result().GetTestProperty(1).value()); +} + +// Tests TestResult::RecordProperty() overrides values for duplicate keys. +TEST_F(UnitTestRecordPropertyTest, OverridesValuesForDuplicateKeys) { + UnitTestRecordProperty("key_1", "1"); + UnitTestRecordProperty("key_2", "2"); + UnitTestRecordProperty("key_1", "12"); + UnitTestRecordProperty("key_2", "22"); + + ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("12", + unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); + + EXPECT_STREQ("key_2", + unit_test_.ad_hoc_test_result().GetTestProperty(1).key()); + EXPECT_STREQ("22", + unit_test_.ad_hoc_test_result().GetTestProperty(1).value()); +} + +TEST_F(UnitTestRecordPropertyTest, + AddFailureInsideTestsWhenUsingTestCaseReservedKeys) { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "value_param"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "type_param"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "status"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "time"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "classname"); +} + +TEST_F(UnitTestRecordPropertyTest, + AddRecordWithReservedKeysGeneratesCorrectPropertyList) { + EXPECT_NONFATAL_FAILURE( + Test::RecordProperty("name", "1"), + "'classname', 'name', 'status', 'time', 'type_param', and 'value_param'" + " are reserved"); +} + +class UnitTestRecordPropertyTestEnvironment : public Environment { + public: + virtual void TearDown() { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "tests"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "failures"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "disabled"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "errors"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "timestamp"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "time"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "random_seed"); + } +}; + +// This will test property recording outside of any test or test case. +static Environment* record_property_env = + AddGlobalTestEnvironment(new UnitTestRecordPropertyTestEnvironment); + +// This group of tests is for predicate assertions (ASSERT_PRED*, etc) +// of various arities. They do not attempt to be exhaustive. Rather, +// view them as smoke tests that can be easily reviewed and verified. +// A more complete set of tests for predicate assertions can be found +// in gtest_pred_impl_unittest.cc. + +// First, some predicates and predicate-formatters needed by the tests. + +// Returns true iff the argument is an even number. +bool IsEven(int n) { + return (n % 2) == 0; +} + +// A functor that returns true iff the argument is an even number. +struct IsEvenFunctor { + bool operator()(int n) { return IsEven(n); } +}; + +// A predicate-formatter function that asserts the argument is an even +// number. +AssertionResult AssertIsEven(const char* expr, int n) { + if (IsEven(n)) { + return AssertionSuccess(); + } + + Message msg; + msg << expr << " evaluates to " << n << ", which is not even."; + return AssertionFailure(msg); +} + +// A predicate function that returns AssertionResult for use in +// EXPECT/ASSERT_TRUE/FALSE. +AssertionResult ResultIsEven(int n) { + if (IsEven(n)) + return AssertionSuccess() << n << " is even"; + else + return AssertionFailure() << n << " is odd"; +} + +// A predicate function that returns AssertionResult but gives no +// explanation why it succeeds. Needed for testing that +// EXPECT/ASSERT_FALSE handles such functions correctly. +AssertionResult ResultIsEvenNoExplanation(int n) { + if (IsEven(n)) + return AssertionSuccess(); + else + return AssertionFailure() << n << " is odd"; +} + +// A predicate-formatter functor that asserts the argument is an even +// number. +struct AssertIsEvenFunctor { + AssertionResult operator()(const char* expr, int n) { + return AssertIsEven(expr, n); + } +}; + +// Returns true iff the sum of the arguments is an even number. +bool SumIsEven2(int n1, int n2) { + return IsEven(n1 + n2); +} + +// A functor that returns true iff the sum of the arguments is an even +// number. +struct SumIsEven3Functor { + bool operator()(int n1, int n2, int n3) { + return IsEven(n1 + n2 + n3); + } +}; + +// A predicate-formatter function that asserts the sum of the +// arguments is an even number. +AssertionResult AssertSumIsEven4( + const char* e1, const char* e2, const char* e3, const char* e4, + int n1, int n2, int n3, int n4) { + const int sum = n1 + n2 + n3 + n4; + if (IsEven(sum)) { + return AssertionSuccess(); + } + + Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 + << " (" << n1 << " + " << n2 << " + " << n3 << " + " << n4 + << ") evaluates to " << sum << ", which is not even."; + return AssertionFailure(msg); +} + +// A predicate-formatter functor that asserts the sum of the arguments +// is an even number. +struct AssertSumIsEven5Functor { + AssertionResult operator()( + const char* e1, const char* e2, const char* e3, const char* e4, + const char* e5, int n1, int n2, int n3, int n4, int n5) { + const int sum = n1 + n2 + n3 + n4 + n5; + if (IsEven(sum)) { + return AssertionSuccess(); + } + + Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 + << " (" + << n1 << " + " << n2 << " + " << n3 << " + " << n4 << " + " << n5 + << ") evaluates to " << sum << ", which is not even."; + return AssertionFailure(msg); + } +}; + + +// Tests unary predicate assertions. + +// Tests unary predicate assertions that don't use a custom formatter. +TEST(Pred1Test, WithoutFormat) { + // Success cases. + EXPECT_PRED1(IsEvenFunctor(), 2) << "This failure is UNEXPECTED!"; + ASSERT_PRED1(IsEven, 4); + + // Failure cases. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(IsEven, 5) << "This failure is expected."; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE(ASSERT_PRED1(IsEvenFunctor(), 5), + "evaluates to false"); +} + +// Tests unary predicate assertions that use a custom formatter. +TEST(Pred1Test, WithFormat) { + // Success cases. + EXPECT_PRED_FORMAT1(AssertIsEven, 2); + ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), 4) + << "This failure is UNEXPECTED!"; + + // Failure cases. + const int n = 5; + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT1(AssertIsEvenFunctor(), n), + "n evaluates to 5, which is not even."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(AssertIsEven, 5) << "This failure is expected."; + }, "This failure is expected."); +} + +// Tests that unary predicate assertions evaluates their arguments +// exactly once. +TEST(Pred1Test, SingleEvaluationOnFailure) { + // A success case. + static int n = 0; + EXPECT_PRED1(IsEven, n++); + EXPECT_EQ(1, n) << "The argument is not evaluated exactly once."; + + // A failure case. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), n++) + << "This failure is expected."; + }, "This failure is expected."); + EXPECT_EQ(2, n) << "The argument is not evaluated exactly once."; +} + + +// Tests predicate assertions whose arity is >= 2. + +// Tests predicate assertions that don't use a custom formatter. +TEST(PredTest, WithoutFormat) { + // Success cases. + ASSERT_PRED2(SumIsEven2, 2, 4) << "This failure is UNEXPECTED!"; + EXPECT_PRED3(SumIsEven3Functor(), 4, 6, 8); + + // Failure cases. + const int n1 = 1; + const int n2 = 2; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(SumIsEven2, n1, n2) << "This failure is expected."; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(SumIsEven3Functor(), 1, 2, 4); + }, "evaluates to false"); +} + +// Tests predicate assertions that use a custom formatter. +TEST(PredTest, WithFormat) { + // Success cases. + ASSERT_PRED_FORMAT4(AssertSumIsEven4, 4, 6, 8, 10) << + "This failure is UNEXPECTED!"; + EXPECT_PRED_FORMAT5(AssertSumIsEven5Functor(), 2, 4, 6, 8, 10); + + // Failure cases. + const int n1 = 1; + const int n2 = 2; + const int n3 = 4; + const int n4 = 6; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(AssertSumIsEven4, n1, n2, n3, n4); + }, "evaluates to 13, which is not even."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), 1, 2, 4, 6, 8) + << "This failure is expected."; + }, "This failure is expected."); +} + +// Tests that predicate assertions evaluates their arguments +// exactly once. +TEST(PredTest, SingleEvaluationOnFailure) { + // A success case. + int n1 = 0; + int n2 = 0; + EXPECT_PRED2(SumIsEven2, n1++, n2++); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + + // Another success case. + n1 = n2 = 0; + int n3 = 0; + int n4 = 0; + int n5 = 0; + ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), + n1++, n2++, n3++, n4++, n5++) + << "This failure is UNEXPECTED!"; + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; + EXPECT_EQ(1, n5) << "Argument 5 is not evaluated exactly once."; + + // A failure case. + n1 = n2 = n3 = 0; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(SumIsEven3Functor(), ++n1, n2++, n3++) + << "This failure is expected."; + }, "This failure is expected."); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + + // Another failure case. + n1 = n2 = n3 = n4 = 0; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(AssertSumIsEven4, ++n1, n2++, n3++, n4++); + }, "evaluates to 1, which is not even."); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; +} + + +// Some helper functions for testing using overloaded/template +// functions with ASSERT_PREDn and EXPECT_PREDn. + +bool IsPositive(double x) { + return x > 0; +} + +template +bool IsNegative(T x) { + return x < 0; +} + +template +bool GreaterThan(T1 x1, T2 x2) { + return x1 > x2; +} + +// Tests that overloaded functions can be used in *_PRED* as long as +// their types are explicitly specified. +TEST(PredicateAssertionTest, AcceptsOverloadedFunction) { + // C++Builder requires C-style casts rather than static_cast. + EXPECT_PRED1((bool (*)(int))(IsPositive), 5); // NOLINT + ASSERT_PRED1((bool (*)(double))(IsPositive), 6.0); // NOLINT +} + +// Tests that template functions can be used in *_PRED* as long as +// their types are explicitly specified. +TEST(PredicateAssertionTest, AcceptsTemplateFunction) { + EXPECT_PRED1(IsNegative, -5); + // Makes sure that we can handle templates with more than one + // parameter. + ASSERT_PRED2((GreaterThan), 5, 0); +} + + +// Some helper functions for testing using overloaded/template +// functions with ASSERT_PRED_FORMATn and EXPECT_PRED_FORMATn. + +AssertionResult IsPositiveFormat(const char* /* expr */, int n) { + return n > 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +AssertionResult IsPositiveFormat(const char* /* expr */, double x) { + return x > 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +template +AssertionResult IsNegativeFormat(const char* /* expr */, T x) { + return x < 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +template +AssertionResult EqualsFormat(const char* /* expr1 */, const char* /* expr2 */, + const T1& x1, const T2& x2) { + return x1 == x2 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +// Tests that overloaded functions can be used in *_PRED_FORMAT* +// without explicitly specifying their types. +TEST(PredicateFormatAssertionTest, AcceptsOverloadedFunction) { + EXPECT_PRED_FORMAT1(IsPositiveFormat, 5); + ASSERT_PRED_FORMAT1(IsPositiveFormat, 6.0); +} + +// Tests that template functions can be used in *_PRED_FORMAT* without +// explicitly specifying their types. +TEST(PredicateFormatAssertionTest, AcceptsTemplateFunction) { + EXPECT_PRED_FORMAT1(IsNegativeFormat, -5); + ASSERT_PRED_FORMAT2(EqualsFormat, 3, 3); +} + + +// Tests string assertions. + +// Tests ASSERT_STREQ with non-NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ) { + const char * const p1 = "good"; + ASSERT_STREQ(p1, p1); + + // Let p2 have the same content as p1, but be at a different address. + const char p2[] = "good"; + ASSERT_STREQ(p1, p2); + + EXPECT_FATAL_FAILURE(ASSERT_STREQ("bad", "good"), + "Expected: \"bad\""); +} + +// Tests ASSERT_STREQ with NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ_Null) { + ASSERT_STREQ(static_cast(NULL), NULL); + EXPECT_FATAL_FAILURE(ASSERT_STREQ(NULL, "non-null"), + "non-null"); +} + +// Tests ASSERT_STREQ with NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ_Null2) { + EXPECT_FATAL_FAILURE(ASSERT_STREQ("non-null", NULL), + "non-null"); +} + +// Tests ASSERT_STRNE. +TEST(StringAssertionTest, ASSERT_STRNE) { + ASSERT_STRNE("hi", "Hi"); + ASSERT_STRNE("Hi", NULL); + ASSERT_STRNE(NULL, "Hi"); + ASSERT_STRNE("", NULL); + ASSERT_STRNE(NULL, ""); + ASSERT_STRNE("", "Hi"); + ASSERT_STRNE("Hi", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRNE("Hi", "Hi"), + "\"Hi\" vs \"Hi\""); +} + +// Tests ASSERT_STRCASEEQ. +TEST(StringAssertionTest, ASSERT_STRCASEEQ) { + ASSERT_STRCASEEQ("hi", "Hi"); + ASSERT_STRCASEEQ(static_cast(NULL), NULL); + + ASSERT_STRCASEEQ("", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("Hi", "hi2"), + "(ignoring case)"); +} + +// Tests ASSERT_STRCASENE. +TEST(StringAssertionTest, ASSERT_STRCASENE) { + ASSERT_STRCASENE("hi1", "Hi2"); + ASSERT_STRCASENE("Hi", NULL); + ASSERT_STRCASENE(NULL, "Hi"); + ASSERT_STRCASENE("", NULL); + ASSERT_STRCASENE(NULL, ""); + ASSERT_STRCASENE("", "Hi"); + ASSERT_STRCASENE("Hi", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("Hi", "hi"), + "(ignoring case)"); +} + +// Tests *_STREQ on wide strings. +TEST(StringAssertionTest, STREQ_Wide) { + // NULL strings. + ASSERT_STREQ(static_cast(NULL), NULL); + + // Empty strings. + ASSERT_STREQ(L"", L""); + + // Non-null vs NULL. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"non-null", NULL), + "non-null"); + + // Equal strings. + EXPECT_STREQ(L"Hi", L"Hi"); + + // Unequal strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc", L"Abc"), + "Abc"); + + // Strings containing wide characters. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc\x8119", L"abc\x8120"), + "abc"); + + // The streaming variation. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_STREQ(L"abc\x8119", L"abc\x8121") << "Expected failure"; + }, "Expected failure"); +} + +// Tests *_STRNE on wide strings. +TEST(StringAssertionTest, STRNE_Wide) { + // NULL strings. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_STRNE(static_cast(NULL), NULL); + }, ""); + + // Empty strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"", L""), + "L\"\""); + + // Non-null vs NULL. + ASSERT_STRNE(L"non-null", NULL); + + // Equal strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"Hi", L"Hi"), + "L\"Hi\""); + + // Unequal strings. + EXPECT_STRNE(L"abc", L"Abc"); + + // Strings containing wide characters. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"abc\x8119", L"abc\x8119"), + "abc"); + + // The streaming variation. + ASSERT_STRNE(L"abc\x8119", L"abc\x8120") << "This shouldn't happen"; +} + +// Tests for ::testing::IsSubstring(). + +// Tests that IsSubstring() returns the correct result when the input +// argument type is const char*. +TEST(IsSubstringTest, ReturnsCorrectResultForCString) { + EXPECT_FALSE(IsSubstring("", "", NULL, "a")); + EXPECT_FALSE(IsSubstring("", "", "b", NULL)); + EXPECT_FALSE(IsSubstring("", "", "needle", "haystack")); + + EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); + EXPECT_TRUE(IsSubstring("", "", "needle", "two needles")); +} + +// Tests that IsSubstring() returns the correct result when the input +// argument type is const wchar_t*. +TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) { + EXPECT_FALSE(IsSubstring("", "", kNull, L"a")); + EXPECT_FALSE(IsSubstring("", "", L"b", kNull)); + EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack")); + + EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); + EXPECT_TRUE(IsSubstring("", "", L"needle", L"two needles")); +} + +// Tests that IsSubstring() generates the correct message when the input +// argument type is const char*. +TEST(IsSubstringTest, GeneratesCorrectMessageForCString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: \"needle\"\n" + "Expected: a substring of haystack_expr\n" + "Which is: \"haystack\"", + IsSubstring("needle_expr", "haystack_expr", + "needle", "haystack").failure_message()); +} + +// Tests that IsSubstring returns the correct result when the input +// argument type is ::std::string. +TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) { + EXPECT_TRUE(IsSubstring("", "", std::string("hello"), "ahellob")); + EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world"))); +} + +#if GTEST_HAS_STD_WSTRING +// Tests that IsSubstring returns the correct result when the input +// argument type is ::std::wstring. +TEST(IsSubstringTest, ReturnsCorrectResultForStdWstring) { + EXPECT_TRUE(IsSubstring("", "", ::std::wstring(L"needle"), L"two needles")); + EXPECT_FALSE(IsSubstring("", "", L"needle", ::std::wstring(L"haystack"))); +} + +// Tests that IsSubstring() generates the correct message when the input +// argument type is ::std::wstring. +TEST(IsSubstringTest, GeneratesCorrectMessageForWstring) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: L\"needle\"\n" + "Expected: a substring of haystack_expr\n" + "Which is: L\"haystack\"", + IsSubstring( + "needle_expr", "haystack_expr", + ::std::wstring(L"needle"), L"haystack").failure_message()); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Tests for ::testing::IsNotSubstring(). + +// Tests that IsNotSubstring() returns the correct result when the input +// argument type is const char*. +TEST(IsNotSubstringTest, ReturnsCorrectResultForCString) { + EXPECT_TRUE(IsNotSubstring("", "", "needle", "haystack")); + EXPECT_FALSE(IsNotSubstring("", "", "needle", "two needles")); +} + +// Tests that IsNotSubstring() returns the correct result when the input +// argument type is const wchar_t*. +TEST(IsNotSubstringTest, ReturnsCorrectResultForWideCString) { + EXPECT_TRUE(IsNotSubstring("", "", L"needle", L"haystack")); + EXPECT_FALSE(IsNotSubstring("", "", L"needle", L"two needles")); +} + +// Tests that IsNotSubstring() generates the correct message when the input +// argument type is const wchar_t*. +TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: L\"needle\"\n" + "Expected: not a substring of haystack_expr\n" + "Which is: L\"two needles\"", + IsNotSubstring( + "needle_expr", "haystack_expr", + L"needle", L"two needles").failure_message()); +} + +// Tests that IsNotSubstring returns the correct result when the input +// argument type is ::std::string. +TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) { + EXPECT_FALSE(IsNotSubstring("", "", std::string("hello"), "ahellob")); + EXPECT_TRUE(IsNotSubstring("", "", "hello", std::string("world"))); +} + +// Tests that IsNotSubstring() generates the correct message when the input +// argument type is ::std::string. +TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: \"needle\"\n" + "Expected: not a substring of haystack_expr\n" + "Which is: \"two needles\"", + IsNotSubstring( + "needle_expr", "haystack_expr", + ::std::string("needle"), "two needles").failure_message()); +} + +#if GTEST_HAS_STD_WSTRING + +// Tests that IsNotSubstring returns the correct result when the input +// argument type is ::std::wstring. +TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { + EXPECT_FALSE( + IsNotSubstring("", "", ::std::wstring(L"needle"), L"two needles")); + EXPECT_TRUE(IsNotSubstring("", "", L"needle", ::std::wstring(L"haystack"))); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Tests floating-point assertions. + +template +class FloatingPointTest : public Test { + protected: + // Pre-calculated numbers to be used by the tests. + struct TestValues { + RawType close_to_positive_zero; + RawType close_to_negative_zero; + RawType further_from_negative_zero; + + RawType close_to_one; + RawType further_from_one; + + RawType infinity; + RawType close_to_infinity; + RawType further_from_infinity; + + RawType nan1; + RawType nan2; + }; + + typedef typename testing::internal::FloatingPoint Floating; + typedef typename Floating::Bits Bits; + + virtual void SetUp() { + const size_t max_ulps = Floating::kMaxUlps; + + // The bits that represent 0.0. + const Bits zero_bits = Floating(0).bits(); + + // Makes some numbers close to 0.0. + values_.close_to_positive_zero = Floating::ReinterpretBits( + zero_bits + max_ulps/2); + values_.close_to_negative_zero = -Floating::ReinterpretBits( + zero_bits + max_ulps - max_ulps/2); + values_.further_from_negative_zero = -Floating::ReinterpretBits( + zero_bits + max_ulps + 1 - max_ulps/2); + + // The bits that represent 1.0. + const Bits one_bits = Floating(1).bits(); + + // Makes some numbers close to 1.0. + values_.close_to_one = Floating::ReinterpretBits(one_bits + max_ulps); + values_.further_from_one = Floating::ReinterpretBits( + one_bits + max_ulps + 1); + + // +infinity. + values_.infinity = Floating::Infinity(); + + // The bits that represent +infinity. + const Bits infinity_bits = Floating(values_.infinity).bits(); + + // Makes some numbers close to infinity. + values_.close_to_infinity = Floating::ReinterpretBits( + infinity_bits - max_ulps); + values_.further_from_infinity = Floating::ReinterpretBits( + infinity_bits - max_ulps - 1); + + // Makes some NAN's. Sets the most significant bit of the fraction so that + // our NaN's are quiet; trying to process a signaling NaN would raise an + // exception if our environment enables floating point exceptions. + values_.nan1 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 1); + values_.nan2 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 200); + } + + void TestSize() { + EXPECT_EQ(sizeof(RawType), sizeof(Bits)); + } + + static TestValues values_; +}; + +template +typename FloatingPointTest::TestValues + FloatingPointTest::values_; + +// Instantiates FloatingPointTest for testing *_FLOAT_EQ. +typedef FloatingPointTest FloatTest; + +// Tests that the size of Float::Bits matches the size of float. +TEST_F(FloatTest, Size) { + TestSize(); +} + +// Tests comparing with +0 and -0. +TEST_F(FloatTest, Zeros) { + EXPECT_FLOAT_EQ(0.0, -0.0); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(-0.0, 1.0), + "1.0"); + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.5), + "1.5"); +} + +// Tests comparing numbers close to 0. +// +// This ensures that *_FLOAT_EQ handles the sign correctly and no +// overflow occurs when comparing numbers whose absolute value is very +// small. +TEST_F(FloatTest, AlmostZeros) { + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const FloatTest::TestValues& v = this->values_; + + EXPECT_FLOAT_EQ(0.0, v.close_to_positive_zero); + EXPECT_FLOAT_EQ(-0.0, v.close_to_negative_zero); + EXPECT_FLOAT_EQ(v.close_to_positive_zero, v.close_to_negative_zero); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_FLOAT_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); +} + +// Tests comparing numbers close to each other. +TEST_F(FloatTest, SmallDiff) { + EXPECT_FLOAT_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); +} + +// Tests comparing numbers far apart. +TEST_F(FloatTest, LargeDiff) { + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(2.5, 3.0), + "3.0"); +} + +// Tests comparing with infinity. +// +// This ensures that no overflow occurs when comparing numbers whose +// absolute value is very large. +TEST_F(FloatTest, Infinity) { + EXPECT_FLOAT_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_FLOAT_EQ(-values_.infinity, -values_.close_to_infinity); +#if !GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); + + // This is interesting as the representations of infinity and nan1 + // are only 1 DLP apart. + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, values_.nan1), + "values_.nan1"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that comparing with NAN always returns false. +TEST_F(FloatTest, NaN) { +#if !GTEST_OS_SYMBIAN +// Nokia's STLport crashes if we try to output infinity or NaN. + + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const FloatTest::TestValues& v = this->values_; + + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan2), + "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, v.nan1), + "v.nan1"); + + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(v.nan1, v.infinity), + "v.infinity"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that *_FLOAT_EQ are reflexive. +TEST_F(FloatTest, Reflexive) { + EXPECT_FLOAT_EQ(0.0, 0.0); + EXPECT_FLOAT_EQ(1.0, 1.0); + ASSERT_FLOAT_EQ(values_.infinity, values_.infinity); +} + +// Tests that *_FLOAT_EQ are commutative. +TEST_F(FloatTest, Commutative) { + // We already tested EXPECT_FLOAT_EQ(1.0, values_.close_to_one). + EXPECT_FLOAT_EQ(values_.close_to_one, 1.0); + + // We already tested EXPECT_FLOAT_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.further_from_one, 1.0), + "1.0"); +} + +// Tests EXPECT_NEAR. +TEST_F(FloatTest, EXPECT_NEAR) { + EXPECT_NEAR(-1.0f, -1.1f, 0.2f); + EXPECT_NEAR(2.0f, 3.0f, 1.0f); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + "The difference between 1.0f and 1.5f is 0.5, " + "which exceeds 0.25f"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous line. +} + +// Tests ASSERT_NEAR. +TEST_F(FloatTest, ASSERT_NEAR) { + ASSERT_NEAR(-1.0f, -1.1f, 0.2f); + ASSERT_NEAR(2.0f, 3.0f, 1.0f); + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + "The difference between 1.0f and 1.5f is 0.5, " + "which exceeds 0.25f"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous line. +} + +// Tests the cases where FloatLE() should succeed. +TEST_F(FloatTest, FloatLESucceeds) { + EXPECT_PRED_FORMAT2(FloatLE, 1.0f, 2.0f); // When val1 < val2, + ASSERT_PRED_FORMAT2(FloatLE, 1.0f, 1.0f); // val1 == val2, + + // or when val1 is greater than, but almost equals to, val2. + EXPECT_PRED_FORMAT2(FloatLE, values_.close_to_positive_zero, 0.0f); +} + +// Tests the cases where FloatLE() should fail. +TEST_F(FloatTest, FloatLEFails) { + // When val1 is greater than val2 by a large margin, + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(FloatLE, 2.0f, 1.0f), + "(2.0f) <= (1.0f)"); + + // or by a small yet non-negligible margin, + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, values_.further_from_one, 1.0f); + }, "(values_.further_from_one) <= (1.0f)"); + +#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) + // Nokia's STLport crashes if we try to output infinity or NaN. + // C++Builder gives bad results for ordered comparisons involving NaNs + // due to compiler bugs. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, -values_.infinity, values_.nan1); + }, "(-values_.infinity) <= (values_.nan1)"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(FloatLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +#endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) +} + +// Instantiates FloatingPointTest for testing *_DOUBLE_EQ. +typedef FloatingPointTest DoubleTest; + +// Tests that the size of Double::Bits matches the size of double. +TEST_F(DoubleTest, Size) { + TestSize(); +} + +// Tests comparing with +0 and -0. +TEST_F(DoubleTest, Zeros) { + EXPECT_DOUBLE_EQ(0.0, -0.0); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(-0.0, 1.0), + "1.0"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(0.0, 1.0), + "1.0"); +} + +// Tests comparing numbers close to 0. +// +// This ensures that *_DOUBLE_EQ handles the sign correctly and no +// overflow occurs when comparing numbers whose absolute value is very +// small. +TEST_F(DoubleTest, AlmostZeros) { + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const DoubleTest::TestValues& v = this->values_; + + EXPECT_DOUBLE_EQ(0.0, v.close_to_positive_zero); + EXPECT_DOUBLE_EQ(-0.0, v.close_to_negative_zero); + EXPECT_DOUBLE_EQ(v.close_to_positive_zero, v.close_to_negative_zero); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_DOUBLE_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); +} + +// Tests comparing numbers close to each other. +TEST_F(DoubleTest, SmallDiff) { + EXPECT_DOUBLE_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); +} + +// Tests comparing numbers far apart. +TEST_F(DoubleTest, LargeDiff) { + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(2.0, 3.0), + "3.0"); +} + +// Tests comparing with infinity. +// +// This ensures that no overflow occurs when comparing numbers whose +// absolute value is very large. +TEST_F(DoubleTest, Infinity) { + EXPECT_DOUBLE_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_DOUBLE_EQ(-values_.infinity, -values_.close_to_infinity); +#if !GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); + + // This is interesting as the representations of infinity_ and nan1_ + // are only 1 DLP apart. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, values_.nan1), + "values_.nan1"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that comparing with NAN always returns false. +TEST_F(DoubleTest, NaN) { +#if !GTEST_OS_SYMBIAN + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const DoubleTest::TestValues& v = this->values_; + + // Nokia's STLport crashes if we try to output infinity or NaN. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan2), "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, v.nan1), "v.nan1"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(v.nan1, v.infinity), + "v.infinity"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that *_DOUBLE_EQ are reflexive. +TEST_F(DoubleTest, Reflexive) { + EXPECT_DOUBLE_EQ(0.0, 0.0); + EXPECT_DOUBLE_EQ(1.0, 1.0); +#if !GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. + ASSERT_DOUBLE_EQ(values_.infinity, values_.infinity); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that *_DOUBLE_EQ are commutative. +TEST_F(DoubleTest, Commutative) { + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.close_to_one). + EXPECT_DOUBLE_EQ(values_.close_to_one, 1.0); + + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.further_from_one, 1.0), + "1.0"); +} + +// Tests EXPECT_NEAR. +TEST_F(DoubleTest, EXPECT_NEAR) { + EXPECT_NEAR(-1.0, -1.1, 0.2); + EXPECT_NEAR(2.0, 3.0, 1.0); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.5, 0.25), // NOLINT + "The difference between 1.0 and 1.5 is 0.5, " + "which exceeds 0.25"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests ASSERT_NEAR. +TEST_F(DoubleTest, ASSERT_NEAR) { + ASSERT_NEAR(-1.0, -1.1, 0.2); + ASSERT_NEAR(2.0, 3.0, 1.0); + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.5, 0.25), // NOLINT + "The difference between 1.0 and 1.5 is 0.5, " + "which exceeds 0.25"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests the cases where DoubleLE() should succeed. +TEST_F(DoubleTest, DoubleLESucceeds) { + EXPECT_PRED_FORMAT2(DoubleLE, 1.0, 2.0); // When val1 < val2, + ASSERT_PRED_FORMAT2(DoubleLE, 1.0, 1.0); // val1 == val2, + + // or when val1 is greater than, but almost equals to, val2. + EXPECT_PRED_FORMAT2(DoubleLE, values_.close_to_positive_zero, 0.0); +} + +// Tests the cases where DoubleLE() should fail. +TEST_F(DoubleTest, DoubleLEFails) { + // When val1 is greater than val2 by a large margin, + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(DoubleLE, 2.0, 1.0), + "(2.0) <= (1.0)"); + + // or by a small yet non-negligible margin, + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, values_.further_from_one, 1.0); + }, "(values_.further_from_one) <= (1.0)"); + +#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) + // Nokia's STLport crashes if we try to output infinity or NaN. + // C++Builder gives bad results for ordered comparisons involving NaNs + // due to compiler bugs. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, -values_.infinity, values_.nan1); + }, " (-values_.infinity) <= (values_.nan1)"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +#endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) +} + + +// Verifies that a test or test case whose name starts with DISABLED_ is +// not run. + +// A test whose name starts with DISABLED_. +// Should not run. +TEST(DisabledTest, DISABLED_TestShouldNotRun) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +// A test whose name does not start with DISABLED_. +// Should run. +TEST(DisabledTest, NotDISABLED_TestShouldRun) { + EXPECT_EQ(1, 1); +} + +// A test case whose name starts with DISABLED_. +// Should not run. +TEST(DISABLED_TestCase, TestShouldNotRun) { + FAIL() << "Unexpected failure: Test in disabled test case should not be run."; +} + +// A test case and test whose names start with DISABLED_. +// Should not run. +TEST(DISABLED_TestCase, DISABLED_TestShouldNotRun) { + FAIL() << "Unexpected failure: Test in disabled test case should not be run."; +} + +// Check that when all tests in a test case are disabled, SetupTestCase() and +// TearDownTestCase() are not called. +class DisabledTestsTest : public Test { + protected: + static void SetUpTestCase() { + FAIL() << "Unexpected failure: All tests disabled in test case. " + "SetupTestCase() should not be called."; + } + + static void TearDownTestCase() { + FAIL() << "Unexpected failure: All tests disabled in test case. " + "TearDownTestCase() should not be called."; + } +}; + +TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_1) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_2) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +// Tests that disabled typed tests aren't run. + +#if GTEST_HAS_TYPED_TEST + +template +class TypedTest : public Test { +}; + +typedef testing::Types NumericTypes; +TYPED_TEST_CASE(TypedTest, NumericTypes); + +TYPED_TEST(TypedTest, DISABLED_ShouldNotRun) { + FAIL() << "Unexpected failure: Disabled typed test should not run."; +} + +template +class DISABLED_TypedTest : public Test { +}; + +TYPED_TEST_CASE(DISABLED_TypedTest, NumericTypes); + +TYPED_TEST(DISABLED_TypedTest, ShouldNotRun) { + FAIL() << "Unexpected failure: Disabled typed test should not run."; +} + +#endif // GTEST_HAS_TYPED_TEST + +// Tests that disabled type-parameterized tests aren't run. + +#if GTEST_HAS_TYPED_TEST_P + +template +class TypedTestP : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP); + +TYPED_TEST_P(TypedTestP, DISABLED_ShouldNotRun) { + FAIL() << "Unexpected failure: " + << "Disabled type-parameterized test should not run."; +} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP, DISABLED_ShouldNotRun); + +INSTANTIATE_TYPED_TEST_CASE_P(My, TypedTestP, NumericTypes); + +template +class DISABLED_TypedTestP : public Test { +}; + +TYPED_TEST_CASE_P(DISABLED_TypedTestP); + +TYPED_TEST_P(DISABLED_TypedTestP, ShouldNotRun) { + FAIL() << "Unexpected failure: " + << "Disabled type-parameterized test should not run."; +} + +REGISTER_TYPED_TEST_CASE_P(DISABLED_TypedTestP, ShouldNotRun); + +INSTANTIATE_TYPED_TEST_CASE_P(My, DISABLED_TypedTestP, NumericTypes); + +#endif // GTEST_HAS_TYPED_TEST_P + +// Tests that assertion macros evaluate their arguments exactly once. + +class SingleEvaluationTest : public Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + // This helper function is needed by the FailedASSERT_STREQ test + // below. It's public to work around C++Builder's bug with scoping local + // classes. + static void CompareAndIncrementCharPtrs() { + ASSERT_STREQ(p1_++, p2_++); + } + + // This helper function is needed by the FailedASSERT_NE test below. It's + // public to work around C++Builder's bug with scoping local classes. + static void CompareAndIncrementInts() { + ASSERT_NE(a_++, b_++); + } + + protected: + SingleEvaluationTest() { + p1_ = s1_; + p2_ = s2_; + a_ = 0; + b_ = 0; + } + + static const char* const s1_; + static const char* const s2_; + static const char* p1_; + static const char* p2_; + + static int a_; + static int b_; +}; + +const char* const SingleEvaluationTest::s1_ = "01234"; +const char* const SingleEvaluationTest::s2_ = "abcde"; +const char* SingleEvaluationTest::p1_; +const char* SingleEvaluationTest::p2_; +int SingleEvaluationTest::a_; +int SingleEvaluationTest::b_; + +// Tests that when ASSERT_STREQ fails, it evaluates its arguments +// exactly once. +TEST_F(SingleEvaluationTest, FailedASSERT_STREQ) { + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementCharPtrs(), + "p2_++"); + EXPECT_EQ(s1_ + 1, p1_); + EXPECT_EQ(s2_ + 1, p2_); +} + +// Tests that string assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, ASSERT_STR) { + // successful EXPECT_STRNE + EXPECT_STRNE(p1_++, p2_++); + EXPECT_EQ(s1_ + 1, p1_); + EXPECT_EQ(s2_ + 1, p2_); + + // failed EXPECT_STRCASEEQ + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ(p1_++, p2_++), + "ignoring case"); + EXPECT_EQ(s1_ + 2, p1_); + EXPECT_EQ(s2_ + 2, p2_); +} + +// Tests that when ASSERT_NE fails, it evaluates its arguments exactly +// once. +TEST_F(SingleEvaluationTest, FailedASSERT_NE) { + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementInts(), + "(a_++) != (b_++)"); + EXPECT_EQ(1, a_); + EXPECT_EQ(1, b_); +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, OtherCases) { + // successful EXPECT_TRUE + EXPECT_TRUE(0 == a_++); // NOLINT + EXPECT_EQ(1, a_); + + // failed EXPECT_TRUE + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(-1 == a_++), "-1 == a_++"); + EXPECT_EQ(2, a_); + + // successful EXPECT_GT + EXPECT_GT(a_++, b_++); + EXPECT_EQ(3, a_); + EXPECT_EQ(1, b_); + + // failed EXPECT_LT + EXPECT_NONFATAL_FAILURE(EXPECT_LT(a_++, b_++), "(a_++) < (b_++)"); + EXPECT_EQ(4, a_); + EXPECT_EQ(2, b_); + + // successful ASSERT_TRUE + ASSERT_TRUE(0 < a_++); // NOLINT + EXPECT_EQ(5, a_); + + // successful ASSERT_GT + ASSERT_GT(a_++, b_++); + EXPECT_EQ(6, a_); + EXPECT_EQ(3, b_); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowAnInteger() { + throw 1; +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, ExceptionTests) { + // successful EXPECT_THROW + EXPECT_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }, int); + EXPECT_EQ(1, a_); + + // failed EXPECT_THROW, throws different + EXPECT_NONFATAL_FAILURE(EXPECT_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }, bool), "throws a different type"); + EXPECT_EQ(2, a_); + + // failed EXPECT_THROW, throws nothing + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(a_++, bool), "throws nothing"); + EXPECT_EQ(3, a_); + + // successful EXPECT_NO_THROW + EXPECT_NO_THROW(a_++); + EXPECT_EQ(4, a_); + + // failed EXPECT_NO_THROW + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }), "it throws"); + EXPECT_EQ(5, a_); + + // successful EXPECT_ANY_THROW + EXPECT_ANY_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }); + EXPECT_EQ(6, a_); + + // failed EXPECT_ANY_THROW + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(a_++), "it doesn't"); + EXPECT_EQ(7, a_); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests {ASSERT|EXPECT}_NO_FATAL_FAILURE. +class NoFatalFailureTest : public Test { + protected: + void Succeeds() {} + void FailsNonFatal() { + ADD_FAILURE() << "some non-fatal failure"; + } + void Fails() { + FAIL() << "some fatal failure"; + } + + void DoAssertNoFatalFailureOnFails() { + ASSERT_NO_FATAL_FAILURE(Fails()); + ADD_FAILURE() << "shold not reach here."; + } + + void DoExpectNoFatalFailureOnFails() { + EXPECT_NO_FATAL_FAILURE(Fails()); + ADD_FAILURE() << "other failure"; + } +}; + +TEST_F(NoFatalFailureTest, NoFailure) { + EXPECT_NO_FATAL_FAILURE(Succeeds()); + ASSERT_NO_FATAL_FAILURE(Succeeds()); +} + +TEST_F(NoFatalFailureTest, NonFatalIsNoFailure) { + EXPECT_NONFATAL_FAILURE( + EXPECT_NO_FATAL_FAILURE(FailsNonFatal()), + "some non-fatal failure"); + EXPECT_NONFATAL_FAILURE( + ASSERT_NO_FATAL_FAILURE(FailsNonFatal()), + "some non-fatal failure"); +} + +TEST_F(NoFatalFailureTest, AssertNoFatalFailureOnFatalFailure) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + DoAssertNoFatalFailureOnFails(); + } + ASSERT_EQ(2, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", + gtest_failures.GetTestPartResult(1).message()); +} + +TEST_F(NoFatalFailureTest, ExpectNoFatalFailureOnFatalFailure) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + DoExpectNoFatalFailureOnFails(); + } + ASSERT_EQ(3, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(2).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", + gtest_failures.GetTestPartResult(1).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "other failure", + gtest_failures.GetTestPartResult(2).message()); +} + +TEST_F(NoFatalFailureTest, MessageIsStreamable) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + EXPECT_NO_FATAL_FAILURE(FAIL() << "foo") << "my message"; + } + ASSERT_EQ(2, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "foo", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "my message", + gtest_failures.GetTestPartResult(1).message()); +} + +// Tests non-string assertions. + +// Tests EqFailure(), used for implementing *EQ* assertions. +TEST(AssertionTest, EqFailure) { + const std::string foo_val("5"), bar_val("6"); + const std::string msg1( + EqFailure("foo", "bar", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: 6\n" + "Expected: foo\n" + "Which is: 5", + msg1.c_str()); + + const std::string msg2( + EqFailure("foo", "6", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: 6\n" + "Expected: foo\n" + "Which is: 5", + msg2.c_str()); + + const std::string msg3( + EqFailure("5", "bar", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: 6\n" + "Expected: 5", + msg3.c_str()); + + const std::string msg4( + EqFailure("5", "6", foo_val, bar_val, false).failure_message()); + EXPECT_STREQ( + "Value of: 6\n" + "Expected: 5", + msg4.c_str()); + + const std::string msg5( + EqFailure("foo", "bar", + std::string("\"x\""), std::string("\"y\""), + true).failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: \"y\"\n" + "Expected: foo (ignoring case)\n" + "Which is: \"x\"", + msg5.c_str()); +} + +// Tests AppendUserMessage(), used for implementing the *EQ* macros. +TEST(AssertionTest, AppendUserMessage) { + const std::string foo("foo"); + + Message msg; + EXPECT_STREQ("foo", + AppendUserMessage(foo, msg).c_str()); + + msg << "bar"; + EXPECT_STREQ("foo\nbar", + AppendUserMessage(foo, msg).c_str()); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +// Tests ASSERT_TRUE. +TEST(AssertionTest, ASSERT_TRUE) { + ASSERT_TRUE(2 > 1); // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_TRUE(2 < 1), + "2 < 1"); +} + +// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult. +TEST(AssertionTest, AssertTrueWithAssertionResult) { + ASSERT_TRUE(ResultIsEven(2)); +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)), + "Value of: ResultIsEven(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +#endif + ASSERT_TRUE(ResultIsEvenNoExplanation(2)); + EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)), + "Value of: ResultIsEvenNoExplanation(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +} + +// Tests ASSERT_FALSE. +TEST(AssertionTest, ASSERT_FALSE) { + ASSERT_FALSE(2 < 1); // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_FALSE(2 > 1), + "Value of: 2 > 1\n" + " Actual: true\n" + "Expected: false"); +} + +// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult. +TEST(AssertionTest, AssertFalseWithAssertionResult) { + ASSERT_FALSE(ResultIsEven(3)); +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)), + "Value of: ResultIsEven(2)\n" + " Actual: true (2 is even)\n" + "Expected: false"); +#endif + ASSERT_FALSE(ResultIsEvenNoExplanation(3)); + EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)), + "Value of: ResultIsEvenNoExplanation(2)\n" + " Actual: true\n" + "Expected: false"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +# pragma option pop +#endif + +// Tests using ASSERT_EQ on double values. The purpose is to make +// sure that the specialization we did for integer and anonymous enums +// isn't used for double arguments. +TEST(ExpectTest, ASSERT_EQ_Double) { + // A success. + ASSERT_EQ(5.6, 5.6); + + // A failure. + EXPECT_FATAL_FAILURE(ASSERT_EQ(5.1, 5.2), + "5.1"); +} + +// Tests ASSERT_EQ. +TEST(AssertionTest, ASSERT_EQ) { + ASSERT_EQ(5, 2 + 3); + EXPECT_FATAL_FAILURE(ASSERT_EQ(5, 2*3), + "Value of: 2*3\n" + " Actual: 6\n" + "Expected: 5"); +} + +// Tests ASSERT_EQ(NULL, pointer). +#if GTEST_CAN_COMPARE_NULL +TEST(AssertionTest, ASSERT_EQ_NULL) { + // A success. + const char* p = NULL; + // Some older GCC versions may issue a spurious waring in this or the next + // assertion statement. This warning should not be suppressed with + // static_cast since the test verifies the ability to use bare NULL as the + // expected parameter to the macro. + ASSERT_EQ(NULL, p); + + // A failure. + static int n = 0; + EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n), + "Value of: &n\n"); +} +#endif // GTEST_CAN_COMPARE_NULL + +// Tests ASSERT_EQ(0, non_pointer). Since the literal 0 can be +// treated as a null pointer by the compiler, we need to make sure +// that ASSERT_EQ(0, non_pointer) isn't interpreted by Google Test as +// ASSERT_EQ(static_cast(NULL), non_pointer). +TEST(ExpectTest, ASSERT_EQ_0) { + int n = 0; + + // A success. + ASSERT_EQ(0, n); + + // A failure. + EXPECT_FATAL_FAILURE(ASSERT_EQ(0, 5.6), + "Expected: 0"); +} + +// Tests ASSERT_NE. +TEST(AssertionTest, ASSERT_NE) { + ASSERT_NE(6, 7); + EXPECT_FATAL_FAILURE(ASSERT_NE('a', 'a'), + "Expected: ('a') != ('a'), " + "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); +} + +// Tests ASSERT_LE. +TEST(AssertionTest, ASSERT_LE) { + ASSERT_LE(2, 3); + ASSERT_LE(2, 2); + EXPECT_FATAL_FAILURE(ASSERT_LE(2, 0), + "Expected: (2) <= (0), actual: 2 vs 0"); +} + +// Tests ASSERT_LT. +TEST(AssertionTest, ASSERT_LT) { + ASSERT_LT(2, 3); + EXPECT_FATAL_FAILURE(ASSERT_LT(2, 2), + "Expected: (2) < (2), actual: 2 vs 2"); +} + +// Tests ASSERT_GE. +TEST(AssertionTest, ASSERT_GE) { + ASSERT_GE(2, 1); + ASSERT_GE(2, 2); + EXPECT_FATAL_FAILURE(ASSERT_GE(2, 3), + "Expected: (2) >= (3), actual: 2 vs 3"); +} + +// Tests ASSERT_GT. +TEST(AssertionTest, ASSERT_GT) { + ASSERT_GT(2, 1); + EXPECT_FATAL_FAILURE(ASSERT_GT(2, 2), + "Expected: (2) > (2), actual: 2 vs 2"); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowNothing() {} + +// Tests ASSERT_THROW. +TEST(AssertionTest, ASSERT_THROW) { + ASSERT_THROW(ThrowAnInteger(), int); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE( + ASSERT_THROW(ThrowAnInteger(), bool), + "Expected: ThrowAnInteger() throws an exception of type bool.\n" + " Actual: it throws a different type."); +# endif + + EXPECT_FATAL_FAILURE( + ASSERT_THROW(ThrowNothing(), bool), + "Expected: ThrowNothing() throws an exception of type bool.\n" + " Actual: it throws nothing."); +} + +// Tests ASSERT_NO_THROW. +TEST(AssertionTest, ASSERT_NO_THROW) { + ASSERT_NO_THROW(ThrowNothing()); + EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()), + "Expected: ThrowAnInteger() doesn't throw an exception." + "\n Actual: it throws."); +} + +// Tests ASSERT_ANY_THROW. +TEST(AssertionTest, ASSERT_ANY_THROW) { + ASSERT_ANY_THROW(ThrowAnInteger()); + EXPECT_FATAL_FAILURE( + ASSERT_ANY_THROW(ThrowNothing()), + "Expected: ThrowNothing() throws an exception.\n" + " Actual: it doesn't."); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Makes sure we deal with the precedence of <<. This test should +// compile. +TEST(AssertionTest, AssertPrecedence) { + ASSERT_EQ(1 < 2, true); + bool false_value = false; + ASSERT_EQ(true && false_value, false); +} + +// A subroutine used by the following test. +void TestEq1(int x) { + ASSERT_EQ(1, x); +} + +// Tests calling a test subroutine that's not part of a fixture. +TEST(AssertionTest, NonFixtureSubroutine) { + EXPECT_FATAL_FAILURE(TestEq1(2), + "Value of: x"); +} + +// An uncopyable class. +class Uncopyable { + public: + explicit Uncopyable(int a_value) : value_(a_value) {} + + int value() const { return value_; } + bool operator==(const Uncopyable& rhs) const { + return value() == rhs.value(); + } + private: + // This constructor deliberately has no implementation, as we don't + // want this class to be copyable. + Uncopyable(const Uncopyable&); // NOLINT + + int value_; +}; + +::std::ostream& operator<<(::std::ostream& os, const Uncopyable& value) { + return os << value.value(); +} + + +bool IsPositiveUncopyable(const Uncopyable& x) { + return x.value() > 0; +} + +// A subroutine used by the following test. +void TestAssertNonPositive() { + Uncopyable y(-1); + ASSERT_PRED1(IsPositiveUncopyable, y); +} +// A subroutine used by the following test. +void TestAssertEqualsUncopyable() { + Uncopyable x(5); + Uncopyable y(-1); + ASSERT_EQ(x, y); +} + +// Tests that uncopyable objects can be used in assertions. +TEST(AssertionTest, AssertWorksWithUncopyableObject) { + Uncopyable x(5); + ASSERT_PRED1(IsPositiveUncopyable, x); + ASSERT_EQ(x, x); + EXPECT_FATAL_FAILURE(TestAssertNonPositive(), + "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); + EXPECT_FATAL_FAILURE(TestAssertEqualsUncopyable(), + "Value of: y\n Actual: -1\nExpected: x\nWhich is: 5"); +} + +// Tests that uncopyable objects can be used in expects. +TEST(AssertionTest, ExpectWorksWithUncopyableObject) { + Uncopyable x(5); + EXPECT_PRED1(IsPositiveUncopyable, x); + Uncopyable y(-1); + EXPECT_NONFATAL_FAILURE(EXPECT_PRED1(IsPositiveUncopyable, y), + "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); + EXPECT_EQ(x, x); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), + "Value of: y\n Actual: -1\nExpected: x\nWhich is: 5"); +} + +enum NamedEnum { + kE1 = 0, + kE2 = 1 +}; + +TEST(AssertionTest, NamedEnum) { + EXPECT_EQ(kE1, kE1); + EXPECT_LT(kE1, kE2); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Which is: 0"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Actual: 1"); +} + +// The version of gcc used in XCode 2.2 has a bug and doesn't allow +// anonymous enums in assertions. Therefore the following test is not +// done on Mac. +// Sun Studio and HP aCC also reject this code. +#if !GTEST_OS_MAC && !defined(__SUNPRO_CC) && !defined(__HP_aCC) + +// Tests using assertions with anonymous enums. +enum { + kCaseA = -1, + +# if GTEST_OS_LINUX + + // We want to test the case where the size of the anonymous enum is + // larger than sizeof(int), to make sure our implementation of the + // assertions doesn't truncate the enums. However, MSVC + // (incorrectly) doesn't allow an enum value to exceed the range of + // an int, so this has to be conditionally compiled. + // + // On Linux, kCaseB and kCaseA have the same value when truncated to + // int size. We want to test whether this will confuse the + // assertions. + kCaseB = testing::internal::kMaxBiggestInt, + +# else + + kCaseB = INT_MAX, + +# endif // GTEST_OS_LINUX + + kCaseC = 42 +}; + +TEST(AssertionTest, AnonymousEnum) { +# if GTEST_OS_LINUX + + EXPECT_EQ(static_cast(kCaseA), static_cast(kCaseB)); + +# endif // GTEST_OS_LINUX + + EXPECT_EQ(kCaseA, kCaseA); + EXPECT_NE(kCaseA, kCaseB); + EXPECT_LT(kCaseA, kCaseB); + EXPECT_LE(kCaseA, kCaseB); + EXPECT_GT(kCaseB, kCaseA); + EXPECT_GE(kCaseA, kCaseA); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseB), + "(kCaseA) >= (kCaseB)"); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseC), + "-1 vs 42"); + + ASSERT_EQ(kCaseA, kCaseA); + ASSERT_NE(kCaseA, kCaseB); + ASSERT_LT(kCaseA, kCaseB); + ASSERT_LE(kCaseA, kCaseB); + ASSERT_GT(kCaseB, kCaseA); + ASSERT_GE(kCaseA, kCaseA); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), + "Value of: kCaseB"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), + "Actual: 42"); +# endif + + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), + "Which is: -1"); +} + +#endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC) + +#if GTEST_OS_WINDOWS + +static HRESULT UnexpectedHRESULTFailure() { + return E_UNEXPECTED; +} + +static HRESULT OkHRESULTSuccess() { + return S_OK; +} + +static HRESULT FalseHRESULTSuccess() { + return S_FALSE; +} + +// HRESULT assertion tests test both zero and non-zero +// success codes as well as failure message for each. +// +// Windows CE doesn't support message texts. +TEST(HRESULTAssertionTest, EXPECT_HRESULT_SUCCEEDED) { + EXPECT_HRESULT_SUCCEEDED(S_OK); + EXPECT_HRESULT_SUCCEEDED(S_FALSE); + + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"); +} + +TEST(HRESULTAssertionTest, ASSERT_HRESULT_SUCCEEDED) { + ASSERT_HRESULT_SUCCEEDED(S_OK); + ASSERT_HRESULT_SUCCEEDED(S_FALSE); + + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"); +} + +TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) { + EXPECT_HRESULT_FAILED(E_UNEXPECTED); + + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(OkHRESULTSuccess()), + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x0"); + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(FalseHRESULTSuccess()), + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x1"); +} + +TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { + ASSERT_HRESULT_FAILED(E_UNEXPECTED); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x0"); +# endif + + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x1"); +} + +// Tests that streaming to the HRESULT macros works. +TEST(HRESULTAssertionTest, Streaming) { + EXPECT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; + ASSERT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; + EXPECT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; + ASSERT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; + + EXPECT_NONFATAL_FAILURE( + EXPECT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", + "expected failure"); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE( + ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", + "expected failure"); +# endif + + EXPECT_NONFATAL_FAILURE( + EXPECT_HRESULT_FAILED(S_OK) << "expected failure", + "expected failure"); + + EXPECT_FATAL_FAILURE( + ASSERT_HRESULT_FAILED(S_OK) << "expected failure", + "expected failure"); +} + +#endif // GTEST_OS_WINDOWS + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +// Tests that the assertion macros behave like single statements. +TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + ASSERT_TRUE(false) << "This should never be executed; " + "It's a compilation test only."; + + if (AlwaysTrue()) + EXPECT_FALSE(false); + else + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_LT(1, 3); + + if (AlwaysFalse()) + ; // NOLINT + else + EXPECT_GT(3, 2) << ""; +} + +#if GTEST_HAS_EXCEPTIONS +// Tests that the compiler will not complain about unreachable code in the +// EXPECT_THROW/EXPECT_ANY_THROW/EXPECT_NO_THROW macros. +TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { + int n = 0; + + EXPECT_THROW(throw 1, int); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(n++, int), ""); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(throw 1, const char*), ""); + EXPECT_NO_THROW(n++); + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(throw 1), ""); + EXPECT_ANY_THROW(throw 1); + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(n++), ""); +} + +TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + EXPECT_THROW(ThrowNothing(), bool); + + if (AlwaysTrue()) + EXPECT_THROW(ThrowAnInteger(), int); + else + ; // NOLINT + + if (AlwaysFalse()) + EXPECT_NO_THROW(ThrowAnInteger()); + + if (AlwaysTrue()) + EXPECT_NO_THROW(ThrowNothing()); + else + ; // NOLINT + + if (AlwaysFalse()) + EXPECT_ANY_THROW(ThrowNothing()); + + if (AlwaysTrue()) + EXPECT_ANY_THROW(ThrowAnInteger()); + else + ; // NOLINT +} +#endif // GTEST_HAS_EXCEPTIONS + +TEST(AssertionSyntaxTest, NoFatalFailureAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + EXPECT_NO_FATAL_FAILURE(FAIL()) << "This should never be executed. " + << "It's a compilation test only."; + else + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_NO_FATAL_FAILURE(FAIL()) << ""; + else + ; // NOLINT + + if (AlwaysTrue()) + EXPECT_NO_FATAL_FAILURE(SUCCEED()); + else + ; // NOLINT + + if (AlwaysFalse()) + ; // NOLINT + else + ASSERT_NO_FATAL_FAILURE(SUCCEED()); +} + +// Tests that the assertion macros work well with switch statements. +TEST(AssertionSyntaxTest, WorksWithSwitch) { + switch (0) { + case 1: + break; + default: + ASSERT_TRUE(true); + } + + switch (0) + case 0: + EXPECT_FALSE(false) << "EXPECT_FALSE failed in switch case"; + + // Binary assertions are implemented using a different code path + // than the Boolean assertions. Hence we test them separately. + switch (0) { + case 1: + default: + ASSERT_EQ(1, 1) << "ASSERT_EQ failed in default switch handler"; + } + + switch (0) + case 0: + EXPECT_NE(1, 2); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowAString() { + throw "std::string"; +} + +// Test that the exception assertion macros compile and work with const +// type qualifier. +TEST(AssertionSyntaxTest, WorksWithConst) { + ASSERT_THROW(ThrowAString(), const char*); + + EXPECT_THROW(ThrowAString(), const char*); +} + +#endif // GTEST_HAS_EXCEPTIONS + +} // namespace + +namespace testing { + +// Tests that Google Test tracks SUCCEED*. +TEST(SuccessfulAssertionTest, SUCCEED) { + SUCCEED(); + SUCCEED() << "OK"; + EXPECT_EQ(2, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful EXPECT_*. +TEST(SuccessfulAssertionTest, EXPECT) { + EXPECT_TRUE(true); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful EXPECT_STR*. +TEST(SuccessfulAssertionTest, EXPECT_STR) { + EXPECT_STREQ("", ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful ASSERT_*. +TEST(SuccessfulAssertionTest, ASSERT) { + ASSERT_TRUE(true); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful ASSERT_STR*. +TEST(SuccessfulAssertionTest, ASSERT_STR) { + ASSERT_STREQ("", ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +} // namespace testing + +namespace { + +// Tests the message streaming variation of assertions. + +TEST(AssertionWithMessageTest, EXPECT) { + EXPECT_EQ(1, 1) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_NE(1, 1) << "Expected failure #1.", + "Expected failure #1"); + EXPECT_LE(1, 2) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_LT(1, 0) << "Expected failure #2.", + "Expected failure #2."); + EXPECT_GE(1, 0) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_GT(1, 2) << "Expected failure #3.", + "Expected failure #3."); + + EXPECT_STREQ("1", "1") << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("1", "1") << "Expected failure #4.", + "Expected failure #4."); + EXPECT_STRCASEEQ("a", "A") << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("a", "A") << "Expected failure #5.", + "Expected failure #5."); + + EXPECT_FLOAT_EQ(1, 1) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1, 1.2) << "Expected failure #6.", + "Expected failure #6."); + EXPECT_NEAR(1, 1.1, 0.2) << "This should succeed."; +} + +TEST(AssertionWithMessageTest, ASSERT) { + ASSERT_EQ(1, 1) << "This should succeed."; + ASSERT_NE(1, 2) << "This should succeed."; + ASSERT_LE(1, 2) << "This should succeed."; + ASSERT_LT(1, 2) << "This should succeed."; + ASSERT_GE(1, 0) << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_GT(1, 2) << "Expected failure.", + "Expected failure."); +} + +TEST(AssertionWithMessageTest, ASSERT_STR) { + ASSERT_STREQ("1", "1") << "This should succeed."; + ASSERT_STRNE("1", "2") << "This should succeed."; + ASSERT_STRCASEEQ("a", "A") << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("a", "A") << "Expected failure.", + "Expected failure."); +} + +TEST(AssertionWithMessageTest, ASSERT_FLOATING) { + ASSERT_FLOAT_EQ(1, 1) << "This should succeed."; + ASSERT_DOUBLE_EQ(1, 1) << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1,1.2, 0.1) << "Expect failure.", // NOLINT + "Expect failure."); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests using ASSERT_FALSE with a streamed message. +TEST(AssertionWithMessageTest, ASSERT_FALSE) { + ASSERT_FALSE(false) << "This shouldn't fail."; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_FALSE(true) << "Expected failure: " << 2 << " > " << 1 + << " evaluates to " << true; + }, "Expected failure"); +} + +// Tests using FAIL with a streamed message. +TEST(AssertionWithMessageTest, FAIL) { + EXPECT_FATAL_FAILURE(FAIL() << 0, + "0"); +} + +// Tests using SUCCEED with a streamed message. +TEST(AssertionWithMessageTest, SUCCEED) { + SUCCEED() << "Success == " << 1; +} + +// Tests using ASSERT_TRUE with a streamed message. +TEST(AssertionWithMessageTest, ASSERT_TRUE) { + ASSERT_TRUE(true) << "This should succeed."; + ASSERT_TRUE(true) << true; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_TRUE(false) << static_cast(NULL) + << static_cast(NULL); + }, "(null)(null)"); +} + +#if GTEST_OS_WINDOWS +// Tests using wide strings in assertion messages. +TEST(AssertionWithMessageTest, WideStringMessage) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_TRUE(false) << L"This failure is expected.\x8119"; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(1, 2) << "This failure is " + << L"expected too.\x8120"; + }, "This failure is expected too."); +} +#endif // GTEST_OS_WINDOWS + +// Tests EXPECT_TRUE. +TEST(ExpectTest, EXPECT_TRUE) { + EXPECT_TRUE(true) << "Intentional success"; + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #1.", + "Intentional failure #1."); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #2.", + "Intentional failure #2."); + EXPECT_TRUE(2 > 1); // NOLINT + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 < 1), + "Value of: 2 < 1\n" + " Actual: false\n" + "Expected: true"); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 > 3), + "2 > 3"); +} + +// Tests EXPECT_TRUE(predicate) for predicates returning AssertionResult. +TEST(ExpectTest, ExpectTrueWithAssertionResult) { + EXPECT_TRUE(ResultIsEven(2)); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEven(3)), + "Value of: ResultIsEven(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); + EXPECT_TRUE(ResultIsEvenNoExplanation(2)); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEvenNoExplanation(3)), + "Value of: ResultIsEvenNoExplanation(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +} + +// Tests EXPECT_FALSE with a streamed message. +TEST(ExpectTest, EXPECT_FALSE) { + EXPECT_FALSE(2 < 1); // NOLINT + EXPECT_FALSE(false) << "Intentional success"; + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #1.", + "Intentional failure #1."); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #2.", + "Intentional failure #2."); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 > 1), + "Value of: 2 > 1\n" + " Actual: true\n" + "Expected: false"); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 < 3), + "2 < 3"); +} + +// Tests EXPECT_FALSE(predicate) for predicates returning AssertionResult. +TEST(ExpectTest, ExpectFalseWithAssertionResult) { + EXPECT_FALSE(ResultIsEven(3)); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEven(2)), + "Value of: ResultIsEven(2)\n" + " Actual: true (2 is even)\n" + "Expected: false"); + EXPECT_FALSE(ResultIsEvenNoExplanation(3)); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEvenNoExplanation(2)), + "Value of: ResultIsEvenNoExplanation(2)\n" + " Actual: true\n" + "Expected: false"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +# pragma option pop +#endif + +// Tests EXPECT_EQ. +TEST(ExpectTest, EXPECT_EQ) { + EXPECT_EQ(5, 2 + 3); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2*3), + "Value of: 2*3\n" + " Actual: 6\n" + "Expected: 5"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2 - 3), + "2 - 3"); +} + +// Tests using EXPECT_EQ on double values. The purpose is to make +// sure that the specialization we did for integer and anonymous enums +// isn't used for double arguments. +TEST(ExpectTest, EXPECT_EQ_Double) { + // A success. + EXPECT_EQ(5.6, 5.6); + + // A failure. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5.1, 5.2), + "5.1"); +} + +#if GTEST_CAN_COMPARE_NULL +// Tests EXPECT_EQ(NULL, pointer). +TEST(ExpectTest, EXPECT_EQ_NULL) { + // A success. + const char* p = NULL; + // Some older GCC versions may issue a spurious warning in this or the next + // assertion statement. This warning should not be suppressed with + // static_cast since the test verifies the ability to use bare NULL as the + // expected parameter to the macro. + EXPECT_EQ(NULL, p); + + // A failure. + int n = 0; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n), + "Value of: &n\n"); +} +#endif // GTEST_CAN_COMPARE_NULL + +// Tests EXPECT_EQ(0, non_pointer). Since the literal 0 can be +// treated as a null pointer by the compiler, we need to make sure +// that EXPECT_EQ(0, non_pointer) isn't interpreted by Google Test as +// EXPECT_EQ(static_cast(NULL), non_pointer). +TEST(ExpectTest, EXPECT_EQ_0) { + int n = 0; + + // A success. + EXPECT_EQ(0, n); + + // A failure. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(0, 5.6), + "Expected: 0"); +} + +// Tests EXPECT_NE. +TEST(ExpectTest, EXPECT_NE) { + EXPECT_NE(6, 7); + + EXPECT_NONFATAL_FAILURE(EXPECT_NE('a', 'a'), + "Expected: ('a') != ('a'), " + "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); + EXPECT_NONFATAL_FAILURE(EXPECT_NE(2, 2), + "2"); + char* const p0 = NULL; + EXPECT_NONFATAL_FAILURE(EXPECT_NE(p0, p0), + "p0"); + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + char* const p1 = reinterpret_cast(pv1); + EXPECT_NONFATAL_FAILURE(EXPECT_NE(p1, p1), + "p1"); +} + +// Tests EXPECT_LE. +TEST(ExpectTest, EXPECT_LE) { + EXPECT_LE(2, 3); + EXPECT_LE(2, 2); + EXPECT_NONFATAL_FAILURE(EXPECT_LE(2, 0), + "Expected: (2) <= (0), actual: 2 vs 0"); + EXPECT_NONFATAL_FAILURE(EXPECT_LE(1.1, 0.9), + "(1.1) <= (0.9)"); +} + +// Tests EXPECT_LT. +TEST(ExpectTest, EXPECT_LT) { + EXPECT_LT(2, 3); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 2), + "Expected: (2) < (2), actual: 2 vs 2"); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1), + "(2) < (1)"); +} + +// Tests EXPECT_GE. +TEST(ExpectTest, EXPECT_GE) { + EXPECT_GE(2, 1); + EXPECT_GE(2, 2); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(2, 3), + "Expected: (2) >= (3), actual: 2 vs 3"); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(0.9, 1.1), + "(0.9) >= (1.1)"); +} + +// Tests EXPECT_GT. +TEST(ExpectTest, EXPECT_GT) { + EXPECT_GT(2, 1); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 2), + "Expected: (2) > (2), actual: 2 vs 2"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 3), + "(2) > (3)"); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests EXPECT_THROW. +TEST(ExpectTest, EXPECT_THROW) { + EXPECT_THROW(ThrowAnInteger(), int); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool), + "Expected: ThrowAnInteger() throws an exception of " + "type bool.\n Actual: it throws a different type."); + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW(ThrowNothing(), bool), + "Expected: ThrowNothing() throws an exception of type bool.\n" + " Actual: it throws nothing."); +} + +// Tests EXPECT_NO_THROW. +TEST(ExpectTest, EXPECT_NO_THROW) { + EXPECT_NO_THROW(ThrowNothing()); + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()), + "Expected: ThrowAnInteger() doesn't throw an " + "exception.\n Actual: it throws."); +} + +// Tests EXPECT_ANY_THROW. +TEST(ExpectTest, EXPECT_ANY_THROW) { + EXPECT_ANY_THROW(ThrowAnInteger()); + EXPECT_NONFATAL_FAILURE( + EXPECT_ANY_THROW(ThrowNothing()), + "Expected: ThrowNothing() throws an exception.\n" + " Actual: it doesn't."); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Make sure we deal with the precedence of <<. +TEST(ExpectTest, ExpectPrecedence) { + EXPECT_EQ(1 < 2, true); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(true, true && false), + "Value of: true && false"); +} + + +// Tests the StreamableToString() function. + +// Tests using StreamableToString() on a scalar. +TEST(StreamableToStringTest, Scalar) { + EXPECT_STREQ("5", StreamableToString(5).c_str()); +} + +// Tests using StreamableToString() on a non-char pointer. +TEST(StreamableToStringTest, Pointer) { + int n = 0; + int* p = &n; + EXPECT_STRNE("(null)", StreamableToString(p).c_str()); +} + +// Tests using StreamableToString() on a NULL non-char pointer. +TEST(StreamableToStringTest, NullPointer) { + int* p = NULL; + EXPECT_STREQ("(null)", StreamableToString(p).c_str()); +} + +// Tests using StreamableToString() on a C string. +TEST(StreamableToStringTest, CString) { + EXPECT_STREQ("Foo", StreamableToString("Foo").c_str()); +} + +// Tests using StreamableToString() on a NULL C string. +TEST(StreamableToStringTest, NullCString) { + char* p = NULL; + EXPECT_STREQ("(null)", StreamableToString(p).c_str()); +} + +// Tests using streamable values as assertion messages. + +// Tests using std::string as an assertion message. +TEST(StreamableTest, string) { + static const std::string str( + "This failure message is a std::string, and is expected."); + EXPECT_FATAL_FAILURE(FAIL() << str, + str.c_str()); +} + +// Tests that we can output strings containing embedded NULs. +// Limited to Linux because we can only do this with std::string's. +TEST(StreamableTest, stringWithEmbeddedNUL) { + static const char char_array_with_nul[] = + "Here's a NUL\0 and some more string"; + static const std::string string_with_nul(char_array_with_nul, + sizeof(char_array_with_nul) + - 1); // drops the trailing NUL + EXPECT_FATAL_FAILURE(FAIL() << string_with_nul, + "Here's a NUL\\0 and some more string"); +} + +// Tests that we can output a NUL char. +TEST(StreamableTest, NULChar) { + EXPECT_FATAL_FAILURE({ // NOLINT + FAIL() << "A NUL" << '\0' << " and some more string"; + }, "A NUL\\0 and some more string"); +} + +// Tests using int as an assertion message. +TEST(StreamableTest, int) { + EXPECT_FATAL_FAILURE(FAIL() << 900913, + "900913"); +} + +// Tests using NULL char pointer as an assertion message. +// +// In MSVC, streaming a NULL char * causes access violation. Google Test +// implemented a workaround (substituting "(null)" for NULL). This +// tests whether the workaround works. +TEST(StreamableTest, NullCharPtr) { + EXPECT_FATAL_FAILURE(FAIL() << static_cast(NULL), + "(null)"); +} + +// Tests that basic IO manipulators (endl, ends, and flush) can be +// streamed to testing::Message. +TEST(StreamableTest, BasicIoManip) { + EXPECT_FATAL_FAILURE({ // NOLINT + FAIL() << "Line 1." << std::endl + << "A NUL char " << std::ends << std::flush << " in line 2."; + }, "Line 1.\nA NUL char \\0 in line 2."); +} + +// Tests the macros that haven't been covered so far. + +void AddFailureHelper(bool* aborted) { + *aborted = true; + ADD_FAILURE() << "Intentional failure."; + *aborted = false; +} + +// Tests ADD_FAILURE. +TEST(MacroTest, ADD_FAILURE) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(AddFailureHelper(&aborted), + "Intentional failure."); + EXPECT_FALSE(aborted); +} + +// Tests ADD_FAILURE_AT. +TEST(MacroTest, ADD_FAILURE_AT) { + // Verifies that ADD_FAILURE_AT does generate a nonfatal failure and + // the failure message contains the user-streamed part. + EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42) << "Wrong!", "Wrong!"); + + // Verifies that the user-streamed part is optional. + EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42), "Failed"); + + // Unfortunately, we cannot verify that the failure message contains + // the right file path and line number the same way, as + // EXPECT_NONFATAL_FAILURE() doesn't get to see the file path and + // line number. Instead, we do that in gtest_output_test_.cc. +} + +// Tests FAIL. +TEST(MacroTest, FAIL) { + EXPECT_FATAL_FAILURE(FAIL(), + "Failed"); + EXPECT_FATAL_FAILURE(FAIL() << "Intentional failure.", + "Intentional failure."); +} + +// Tests SUCCEED +TEST(MacroTest, SUCCEED) { + SUCCEED(); + SUCCEED() << "Explicit success."; +} + +// Tests for EXPECT_EQ() and ASSERT_EQ(). +// +// These tests fail *intentionally*, s.t. the failure messages can be +// generated and tested. +// +// We have different tests for different argument types. + +// Tests using bool values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Bool) { + EXPECT_EQ(true, true); + EXPECT_FATAL_FAILURE({ + bool false_value = false; + ASSERT_EQ(false_value, true); + }, "Value of: true"); +} + +// Tests using int values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Int) { + ASSERT_EQ(32, 32); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(32, 33), + "33"); +} + +// Tests using time_t values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Time_T) { + EXPECT_EQ(static_cast(0), + static_cast(0)); + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0), + static_cast(1234)), + "1234"); +} + +// Tests using char values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Char) { + ASSERT_EQ('z', 'z'); + const char ch = 'b'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ('\0', ch), + "ch"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ('a', ch), + "ch"); +} + +// Tests using wchar_t values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, WideChar) { + EXPECT_EQ(L'b', L'b'); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'\0', L'x'), + "Value of: L'x'\n" + " Actual: L'x' (120, 0x78)\n" + "Expected: L'\0'\n" + "Which is: L'\0' (0, 0x0)"); + + static wchar_t wchar; + wchar = L'b'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'a', wchar), + "wchar"); + wchar = 0x8119; + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0x8120), wchar), + "Value of: wchar"); +} + +// Tests using ::std::string values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, StdString) { + // Compares a const char* to an std::string that has identical + // content. + ASSERT_EQ("Test", ::std::string("Test")); + + // Compares two identical std::strings. + static const ::std::string str1("A * in the middle"); + static const ::std::string str2(str1); + EXPECT_EQ(str1, str2); + + // Compares a const char* to an std::string that has different + // content + EXPECT_NONFATAL_FAILURE(EXPECT_EQ("Test", ::std::string("test")), + "\"test\""); + + // Compares an std::string to a char* that has different content. + char* const p1 = const_cast("foo"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::std::string("bar"), p1), + "p1"); + + // Compares two std::strings that have different contents, one of + // which having a NUL character in the middle. This should fail. + static ::std::string str3(str1); + str3.at(2) = '\0'; + EXPECT_FATAL_FAILURE(ASSERT_EQ(str1, str3), + "Value of: str3\n" + " Actual: \"A \\0 in the middle\""); +} + +#if GTEST_HAS_STD_WSTRING + +// Tests using ::std::wstring values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, StdWideString) { + // Compares two identical std::wstrings. + const ::std::wstring wstr1(L"A * in the middle"); + const ::std::wstring wstr2(wstr1); + ASSERT_EQ(wstr1, wstr2); + + // Compares an std::wstring to a const wchar_t* that has identical + // content. + const wchar_t kTestX8119[] = { 'T', 'e', 's', 't', 0x8119, '\0' }; + EXPECT_EQ(::std::wstring(kTestX8119), kTestX8119); + + // Compares an std::wstring to a const wchar_t* that has different + // content. + const wchar_t kTestX8120[] = { 'T', 'e', 's', 't', 0x8120, '\0' }; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EQ(::std::wstring(kTestX8119), kTestX8120); + }, "kTestX8120"); + + // Compares two std::wstrings that have different contents, one of + // which having a NUL character in the middle. + ::std::wstring wstr3(wstr1); + wstr3.at(2) = L'\0'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(wstr1, wstr3), + "wstr3"); + + // Compares a wchar_t* to an std::wstring that has different + // content. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(const_cast(L"foo"), ::std::wstring(L"bar")); + }, ""); +} + +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_STRING +// Tests using ::string values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, GlobalString) { + // Compares a const char* to a ::string that has identical content. + EXPECT_EQ("Test", ::string("Test")); + + // Compares two identical ::strings. + const ::string str1("A * in the middle"); + const ::string str2(str1); + ASSERT_EQ(str1, str2); + + // Compares a ::string to a const char* that has different content. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::string("Test"), "test"), + "test"); + + // Compares two ::strings that have different contents, one of which + // having a NUL character in the middle. + ::string str3(str1); + str3.at(2) = '\0'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(str1, str3), + "str3"); + + // Compares a ::string to a char* that has different content. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(::string("bar"), const_cast("foo")); + }, ""); +} + +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING + +// Tests using ::wstring values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, GlobalWideString) { + // Compares two identical ::wstrings. + static const ::wstring wstr1(L"A * in the middle"); + static const ::wstring wstr2(wstr1); + EXPECT_EQ(wstr1, wstr2); + + // Compares a const wchar_t* to a ::wstring that has identical content. + const wchar_t kTestX8119[] = { 'T', 'e', 's', 't', 0x8119, '\0' }; + ASSERT_EQ(kTestX8119, ::wstring(kTestX8119)); + + // Compares a const wchar_t* to a ::wstring that has different + // content. + const wchar_t kTestX8120[] = { 'T', 'e', 's', 't', 0x8120, '\0' }; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EQ(kTestX8120, ::wstring(kTestX8119)); + }, "Test\\x8119"); + + // Compares a wchar_t* to a ::wstring that has different content. + wchar_t* const p1 = const_cast(L"foo"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, ::wstring(L"bar")), + "bar"); + + // Compares two ::wstrings that have different contents, one of which + // having a NUL character in the middle. + static ::wstring wstr3; + wstr3 = wstr1; + wstr3.at(2) = L'\0'; + EXPECT_FATAL_FAILURE(ASSERT_EQ(wstr1, wstr3), + "wstr3"); +} + +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Tests using char pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, CharPointer) { + char* const p0 = NULL; + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + void* pv2 = (void*)0xABC0; // NOLINT + char* const p1 = reinterpret_cast(pv1); + char* const p2 = reinterpret_cast(pv2); + ASSERT_EQ(p1, p1); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), + "Value of: p2"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), + "p2"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(reinterpret_cast(0x1234), + reinterpret_cast(0xABC0)), + "ABC0"); +} + +// Tests using wchar_t pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, WideCharPointer) { + wchar_t* const p0 = NULL; + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + void* pv2 = (void*)0xABC0; // NOLINT + wchar_t* const p1 = reinterpret_cast(pv1); + wchar_t* const p2 = reinterpret_cast(pv2); + EXPECT_EQ(p0, p0); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), + "Value of: p2"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), + "p2"); + void* pv3 = (void*)0x1234; // NOLINT + void* pv4 = (void*)0xABC0; // NOLINT + const wchar_t* p3 = reinterpret_cast(pv3); + const wchar_t* p4 = reinterpret_cast(pv4); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p3, p4), + "p4"); +} + +// Tests using other types of pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, OtherPointer) { + ASSERT_EQ(static_cast(NULL), + static_cast(NULL)); + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(NULL), + reinterpret_cast(0x1234)), + "0x1234"); +} + +// A class that supports binary comparison operators but not streaming. +class UnprintableChar { + public: + explicit UnprintableChar(char ch) : char_(ch) {} + + bool operator==(const UnprintableChar& rhs) const { + return char_ == rhs.char_; + } + bool operator!=(const UnprintableChar& rhs) const { + return char_ != rhs.char_; + } + bool operator<(const UnprintableChar& rhs) const { + return char_ < rhs.char_; + } + bool operator<=(const UnprintableChar& rhs) const { + return char_ <= rhs.char_; + } + bool operator>(const UnprintableChar& rhs) const { + return char_ > rhs.char_; + } + bool operator>=(const UnprintableChar& rhs) const { + return char_ >= rhs.char_; + } + + private: + char char_; +}; + +// Tests that ASSERT_EQ() and friends don't require the arguments to +// be printable. +TEST(ComparisonAssertionTest, AcceptsUnprintableArgs) { + const UnprintableChar x('x'), y('y'); + ASSERT_EQ(x, x); + EXPECT_NE(x, y); + ASSERT_LT(x, y); + EXPECT_LE(x, y); + ASSERT_GT(y, x); + EXPECT_GE(x, x); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <78>"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <79>"); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(y, y), "1-byte object <79>"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <78>"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <79>"); + + // Code tested by EXPECT_FATAL_FAILURE cannot reference local + // variables, so we have to write UnprintableChar('x') instead of x. +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')), + "1-byte object <78>"); + EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), + "1-byte object <78>"); +#endif + EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), + "1-byte object <79>"); + EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), + "1-byte object <78>"); + EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), + "1-byte object <79>"); +} + +// Tests the FRIEND_TEST macro. + +// This class has a private member we want to test. We will test it +// both in a TEST and in a TEST_F. +class Foo { + public: + Foo() {} + + private: + int Bar() const { return 1; } + + // Declares the friend tests that can access the private member + // Bar(). + FRIEND_TEST(FRIEND_TEST_Test, TEST); + FRIEND_TEST(FRIEND_TEST_Test2, TEST_F); +}; + +// Tests that the FRIEND_TEST declaration allows a TEST to access a +// class's private members. This should compile. +TEST(FRIEND_TEST_Test, TEST) { + ASSERT_EQ(1, Foo().Bar()); +} + +// The fixture needed to test using FRIEND_TEST with TEST_F. +class FRIEND_TEST_Test2 : public Test { + protected: + Foo foo; +}; + +// Tests that the FRIEND_TEST declaration allows a TEST_F to access a +// class's private members. This should compile. +TEST_F(FRIEND_TEST_Test2, TEST_F) { + ASSERT_EQ(1, foo.Bar()); +} + +// Tests the life cycle of Test objects. + +// The test fixture for testing the life cycle of Test objects. +// +// This class counts the number of live test objects that uses this +// fixture. +class TestLifeCycleTest : public Test { + protected: + // Constructor. Increments the number of test objects that uses + // this fixture. + TestLifeCycleTest() { count_++; } + + // Destructor. Decrements the number of test objects that uses this + // fixture. + ~TestLifeCycleTest() { count_--; } + + // Returns the number of live test objects that uses this fixture. + int count() const { return count_; } + + private: + static int count_; +}; + +int TestLifeCycleTest::count_ = 0; + +// Tests the life cycle of test objects. +TEST_F(TestLifeCycleTest, Test1) { + // There should be only one test object in this test case that's + // currently alive. + ASSERT_EQ(1, count()); +} + +// Tests the life cycle of test objects. +TEST_F(TestLifeCycleTest, Test2) { + // After Test1 is done and Test2 is started, there should still be + // only one live test object, as the object for Test1 should've been + // deleted. + ASSERT_EQ(1, count()); +} + +} // namespace + +// Tests that the copy constructor works when it is NOT optimized away by +// the compiler. +TEST(AssertionResultTest, CopyConstructorWorksWhenNotOptimied) { + // Checks that the copy constructor doesn't try to dereference NULL pointers + // in the source object. + AssertionResult r1 = AssertionSuccess(); + AssertionResult r2 = r1; + // The following line is added to prevent the compiler from optimizing + // away the constructor call. + r1 << "abc"; + + AssertionResult r3 = r1; + EXPECT_EQ(static_cast(r3), static_cast(r1)); + EXPECT_STREQ("abc", r1.message()); +} + +// Tests that AssertionSuccess and AssertionFailure construct +// AssertionResult objects as expected. +TEST(AssertionResultTest, ConstructionWorks) { + AssertionResult r1 = AssertionSuccess(); + EXPECT_TRUE(r1); + EXPECT_STREQ("", r1.message()); + + AssertionResult r2 = AssertionSuccess() << "abc"; + EXPECT_TRUE(r2); + EXPECT_STREQ("abc", r2.message()); + + AssertionResult r3 = AssertionFailure(); + EXPECT_FALSE(r3); + EXPECT_STREQ("", r3.message()); + + AssertionResult r4 = AssertionFailure() << "def"; + EXPECT_FALSE(r4); + EXPECT_STREQ("def", r4.message()); + + AssertionResult r5 = AssertionFailure(Message() << "ghi"); + EXPECT_FALSE(r5); + EXPECT_STREQ("ghi", r5.message()); +} + +// Tests that the negation flips the predicate result but keeps the message. +TEST(AssertionResultTest, NegationWorks) { + AssertionResult r1 = AssertionSuccess() << "abc"; + EXPECT_FALSE(!r1); + EXPECT_STREQ("abc", (!r1).message()); + + AssertionResult r2 = AssertionFailure() << "def"; + EXPECT_TRUE(!r2); + EXPECT_STREQ("def", (!r2).message()); +} + +TEST(AssertionResultTest, StreamingWorks) { + AssertionResult r = AssertionSuccess(); + r << "abc" << 'd' << 0 << true; + EXPECT_STREQ("abcd0true", r.message()); +} + +TEST(AssertionResultTest, CanStreamOstreamManipulators) { + AssertionResult r = AssertionSuccess(); + r << "Data" << std::endl << std::flush << std::ends << "Will be visible"; + EXPECT_STREQ("Data\n\\0Will be visible", r.message()); +} + +// Tests streaming a user type whose definition and operator << are +// both in the global namespace. +class Base { + public: + explicit Base(int an_x) : x_(an_x) {} + int x() const { return x_; } + private: + int x_; +}; +std::ostream& operator<<(std::ostream& os, + const Base& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const Base* pointer) { + return os << "(" << pointer->x() << ")"; +} + +TEST(MessageTest, CanStreamUserTypeInGlobalNameSpace) { + Message msg; + Base a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition and operator<< are +// both in an unnamed namespace. +namespace { +class MyTypeInUnnamedNameSpace : public Base { + public: + explicit MyTypeInUnnamedNameSpace(int an_x): Base(an_x) {} +}; +std::ostream& operator<<(std::ostream& os, + const MyTypeInUnnamedNameSpace& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const MyTypeInUnnamedNameSpace* pointer) { + return os << "(" << pointer->x() << ")"; +} +} // namespace + +TEST(MessageTest, CanStreamUserTypeInUnnamedNameSpace) { + Message msg; + MyTypeInUnnamedNameSpace a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition and operator<< are +// both in a user namespace. +namespace namespace1 { +class MyTypeInNameSpace1 : public Base { + public: + explicit MyTypeInNameSpace1(int an_x): Base(an_x) {} +}; +std::ostream& operator<<(std::ostream& os, + const MyTypeInNameSpace1& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const MyTypeInNameSpace1* pointer) { + return os << "(" << pointer->x() << ")"; +} +} // namespace namespace1 + +TEST(MessageTest, CanStreamUserTypeInUserNameSpace) { + Message msg; + namespace1::MyTypeInNameSpace1 a(1); + + msg << a << &a; // Uses namespace1::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition is in a user namespace +// but whose operator<< is in the global namespace. +namespace namespace2 { +class MyTypeInNameSpace2 : public ::Base { + public: + explicit MyTypeInNameSpace2(int an_x): Base(an_x) {} +}; +} // namespace namespace2 +std::ostream& operator<<(std::ostream& os, + const namespace2::MyTypeInNameSpace2& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const namespace2::MyTypeInNameSpace2* pointer) { + return os << "(" << pointer->x() << ")"; +} + +TEST(MessageTest, CanStreamUserTypeInUserNameSpaceWithStreamOperatorInGlobal) { + Message msg; + namespace2::MyTypeInNameSpace2 a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming NULL pointers to testing::Message. +TEST(MessageTest, NullPointers) { + Message msg; + char* const p1 = NULL; + unsigned char* const p2 = NULL; + int* p3 = NULL; + double* p4 = NULL; + bool* p5 = NULL; + Message* p6 = NULL; + + msg << p1 << p2 << p3 << p4 << p5 << p6; + ASSERT_STREQ("(null)(null)(null)(null)(null)(null)", + msg.GetString().c_str()); +} + +// Tests streaming wide strings to testing::Message. +TEST(MessageTest, WideStrings) { + // Streams a NULL of type const wchar_t*. + const wchar_t* const_wstr = NULL; + EXPECT_STREQ("(null)", + (Message() << const_wstr).GetString().c_str()); + + // Streams a NULL of type wchar_t*. + wchar_t* wstr = NULL; + EXPECT_STREQ("(null)", + (Message() << wstr).GetString().c_str()); + + // Streams a non-NULL of type const wchar_t*. + const_wstr = L"abc\x8119"; + EXPECT_STREQ("abc\xe8\x84\x99", + (Message() << const_wstr).GetString().c_str()); + + // Streams a non-NULL of type wchar_t*. + wstr = const_cast(const_wstr); + EXPECT_STREQ("abc\xe8\x84\x99", + (Message() << wstr).GetString().c_str()); +} + + +// This line tests that we can define tests in the testing namespace. +namespace testing { + +// Tests the TestInfo class. + +class TestInfoTest : public Test { + protected: + static const TestInfo* GetTestInfo(const char* test_name) { + const TestCase* const test_case = GetUnitTestImpl()-> + GetTestCase("TestInfoTest", "", NULL, NULL); + + for (int i = 0; i < test_case->total_test_count(); ++i) { + const TestInfo* const test_info = test_case->GetTestInfo(i); + if (strcmp(test_name, test_info->name()) == 0) + return test_info; + } + return NULL; + } + + static const TestResult* GetTestResult( + const TestInfo* test_info) { + return test_info->result(); + } +}; + +// Tests TestInfo::test_case_name() and TestInfo::name(). +TEST_F(TestInfoTest, Names) { + const TestInfo* const test_info = GetTestInfo("Names"); + + ASSERT_STREQ("TestInfoTest", test_info->test_case_name()); + ASSERT_STREQ("Names", test_info->name()); +} + +// Tests TestInfo::result(). +TEST_F(TestInfoTest, result) { + const TestInfo* const test_info = GetTestInfo("result"); + + // Initially, there is no TestPartResult for this test. + ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); + + // After the previous assertion, there is still none. + ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); +} + +// Tests setting up and tearing down a test case. + +class SetUpTestCaseTest : public Test { + protected: + // This will be called once before the first test in this test case + // is run. + static void SetUpTestCase() { + printf("Setting up the test case . . .\n"); + + // Initializes some shared resource. In this simple example, we + // just create a C string. More complex stuff can be done if + // desired. + shared_resource_ = "123"; + + // Increments the number of test cases that have been set up. + counter_++; + + // SetUpTestCase() should be called only once. + EXPECT_EQ(1, counter_); + } + + // This will be called once after the last test in this test case is + // run. + static void TearDownTestCase() { + printf("Tearing down the test case . . .\n"); + + // Decrements the number of test cases that have been set up. + counter_--; + + // TearDownTestCase() should be called only once. + EXPECT_EQ(0, counter_); + + // Cleans up the shared resource. + shared_resource_ = NULL; + } + + // This will be called before each test in this test case. + virtual void SetUp() { + // SetUpTestCase() should be called only once, so counter_ should + // always be 1. + EXPECT_EQ(1, counter_); + } + + // Number of test cases that have been set up. + static int counter_; + + // Some resource to be shared by all tests in this test case. + static const char* shared_resource_; +}; + +int SetUpTestCaseTest::counter_ = 0; +const char* SetUpTestCaseTest::shared_resource_ = NULL; + +// A test that uses the shared resource. +TEST_F(SetUpTestCaseTest, Test1) { + EXPECT_STRNE(NULL, shared_resource_); +} + +// Another test that uses the shared resource. +TEST_F(SetUpTestCaseTest, Test2) { + EXPECT_STREQ("123", shared_resource_); +} + +// The InitGoogleTestTest test case tests testing::InitGoogleTest(). + +// The Flags struct stores a copy of all Google Test flags. +struct Flags { + // Constructs a Flags struct where each flag has its default value. + Flags() : also_run_disabled_tests(false), + break_on_failure(false), + catch_exceptions(false), + death_test_use_fork(false), + filter(""), + list_tests(false), + output(""), + print_time(true), + random_seed(0), + repeat(1), + shuffle(false), + stack_trace_depth(kMaxStackTraceDepth), + stream_result_to(""), + throw_on_failure(false) {} + + // Factory methods. + + // Creates a Flags struct where the gtest_also_run_disabled_tests flag has + // the given value. + static Flags AlsoRunDisabledTests(bool also_run_disabled_tests) { + Flags flags; + flags.also_run_disabled_tests = also_run_disabled_tests; + return flags; + } + + // Creates a Flags struct where the gtest_break_on_failure flag has + // the given value. + static Flags BreakOnFailure(bool break_on_failure) { + Flags flags; + flags.break_on_failure = break_on_failure; + return flags; + } + + // Creates a Flags struct where the gtest_catch_exceptions flag has + // the given value. + static Flags CatchExceptions(bool catch_exceptions) { + Flags flags; + flags.catch_exceptions = catch_exceptions; + return flags; + } + + // Creates a Flags struct where the gtest_death_test_use_fork flag has + // the given value. + static Flags DeathTestUseFork(bool death_test_use_fork) { + Flags flags; + flags.death_test_use_fork = death_test_use_fork; + return flags; + } + + // Creates a Flags struct where the gtest_filter flag has the given + // value. + static Flags Filter(const char* filter) { + Flags flags; + flags.filter = filter; + return flags; + } + + // Creates a Flags struct where the gtest_list_tests flag has the + // given value. + static Flags ListTests(bool list_tests) { + Flags flags; + flags.list_tests = list_tests; + return flags; + } + + // Creates a Flags struct where the gtest_output flag has the given + // value. + static Flags Output(const char* output) { + Flags flags; + flags.output = output; + return flags; + } + + // Creates a Flags struct where the gtest_print_time flag has the given + // value. + static Flags PrintTime(bool print_time) { + Flags flags; + flags.print_time = print_time; + return flags; + } + + // Creates a Flags struct where the gtest_random_seed flag has + // the given value. + static Flags RandomSeed(Int32 random_seed) { + Flags flags; + flags.random_seed = random_seed; + return flags; + } + + // Creates a Flags struct where the gtest_repeat flag has the given + // value. + static Flags Repeat(Int32 repeat) { + Flags flags; + flags.repeat = repeat; + return flags; + } + + // Creates a Flags struct where the gtest_shuffle flag has + // the given value. + static Flags Shuffle(bool shuffle) { + Flags flags; + flags.shuffle = shuffle; + return flags; + } + + // Creates a Flags struct where the GTEST_FLAG(stack_trace_depth) flag has + // the given value. + static Flags StackTraceDepth(Int32 stack_trace_depth) { + Flags flags; + flags.stack_trace_depth = stack_trace_depth; + return flags; + } + + // Creates a Flags struct where the GTEST_FLAG(stream_result_to) flag has + // the given value. + static Flags StreamResultTo(const char* stream_result_to) { + Flags flags; + flags.stream_result_to = stream_result_to; + return flags; + } + + // Creates a Flags struct where the gtest_throw_on_failure flag has + // the given value. + static Flags ThrowOnFailure(bool throw_on_failure) { + Flags flags; + flags.throw_on_failure = throw_on_failure; + return flags; + } + + // These fields store the flag values. + bool also_run_disabled_tests; + bool break_on_failure; + bool catch_exceptions; + bool death_test_use_fork; + const char* filter; + bool list_tests; + const char* output; + bool print_time; + Int32 random_seed; + Int32 repeat; + bool shuffle; + Int32 stack_trace_depth; + const char* stream_result_to; + bool throw_on_failure; +}; + +// Fixture for testing InitGoogleTest(). +class InitGoogleTestTest : public Test { + protected: + // Clears the flags before each test. + virtual void SetUp() { + GTEST_FLAG(also_run_disabled_tests) = false; + GTEST_FLAG(break_on_failure) = false; + GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(death_test_use_fork) = false; + GTEST_FLAG(filter) = ""; + GTEST_FLAG(list_tests) = false; + GTEST_FLAG(output) = ""; + GTEST_FLAG(print_time) = true; + GTEST_FLAG(random_seed) = 0; + GTEST_FLAG(repeat) = 1; + GTEST_FLAG(shuffle) = false; + GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; + GTEST_FLAG(stream_result_to) = ""; + GTEST_FLAG(throw_on_failure) = false; + } + + // Asserts that two narrow or wide string arrays are equal. + template + static void AssertStringArrayEq(size_t size1, CharType** array1, + size_t size2, CharType** array2) { + ASSERT_EQ(size1, size2) << " Array sizes different."; + + for (size_t i = 0; i != size1; i++) { + ASSERT_STREQ(array1[i], array2[i]) << " where i == " << i; + } + } + + // Verifies that the flag values match the expected values. + static void CheckFlags(const Flags& expected) { + EXPECT_EQ(expected.also_run_disabled_tests, + GTEST_FLAG(also_run_disabled_tests)); + EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure)); + EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions)); + EXPECT_EQ(expected.death_test_use_fork, GTEST_FLAG(death_test_use_fork)); + EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str()); + EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); + EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); + EXPECT_EQ(expected.print_time, GTEST_FLAG(print_time)); + EXPECT_EQ(expected.random_seed, GTEST_FLAG(random_seed)); + EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat)); + EXPECT_EQ(expected.shuffle, GTEST_FLAG(shuffle)); + EXPECT_EQ(expected.stack_trace_depth, GTEST_FLAG(stack_trace_depth)); + EXPECT_STREQ(expected.stream_result_to, + GTEST_FLAG(stream_result_to).c_str()); + EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure)); + } + + // Parses a command line (specified by argc1 and argv1), then + // verifies that the flag values are expected and that the + // recognized flags are removed from the command line. + template + static void TestParsingFlags(int argc1, const CharType** argv1, + int argc2, const CharType** argv2, + const Flags& expected, bool should_print_help) { + const bool saved_help_flag = ::testing::internal::g_help_flag; + ::testing::internal::g_help_flag = false; + +#if GTEST_HAS_STREAM_REDIRECTION + CaptureStdout(); +#endif + + // Parses the command line. + internal::ParseGoogleTestFlagsOnly(&argc1, const_cast(argv1)); + +#if GTEST_HAS_STREAM_REDIRECTION + const std::string captured_stdout = GetCapturedStdout(); +#endif + + // Verifies the flag values. + CheckFlags(expected); + + // Verifies that the recognized flags are removed from the command + // line. + AssertStringArrayEq(argc1 + 1, argv1, argc2 + 1, argv2); + + // ParseGoogleTestFlagsOnly should neither set g_help_flag nor print the + // help message for the flags it recognizes. + EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag); + +#if GTEST_HAS_STREAM_REDIRECTION + const char* const expected_help_fragment = + "This program contains tests written using"; + if (should_print_help) { + EXPECT_PRED_FORMAT2(IsSubstring, expected_help_fragment, captured_stdout); + } else { + EXPECT_PRED_FORMAT2(IsNotSubstring, + expected_help_fragment, captured_stdout); + } +#endif // GTEST_HAS_STREAM_REDIRECTION + + ::testing::internal::g_help_flag = saved_help_flag; + } + + // This macro wraps TestParsingFlags s.t. the user doesn't need + // to specify the array sizes. + +#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \ + TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \ + sizeof(argv2)/sizeof(*argv2) - 1, argv2, \ + expected, should_print_help) +}; + +// Tests parsing an empty command line. +TEST_F(InitGoogleTestTest, Empty) { + const char* argv[] = { + NULL + }; + + const char* argv2[] = { + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); +} + +// Tests parsing a command line that has no flag. +TEST_F(InitGoogleTestTest, NoFlag) { + const char* argv[] = { + "foo.exe", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); +} + +// Tests parsing a bad --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterBad) { + const char* argv[] = { + "foo.exe", + "--gtest_filter", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "--gtest_filter", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), true); +} + +// Tests parsing an empty --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), false); +} + +// Tests parsing a non-empty --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterNonEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=abc", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"), false); +} + +// Tests parsing --gtest_break_on_failure. +TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); +} + +// Tests parsing --gtest_break_on_failure=0. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing --gtest_break_on_failure=f. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing --gtest_break_on_failure=F. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing a --gtest_break_on_failure flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, BreakOnFailureTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); +} + +// Tests parsing --gtest_catch_exceptions. +TEST_F(InitGoogleTestTest, CatchExceptions) { + const char* argv[] = { + "foo.exe", + "--gtest_catch_exceptions", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::CatchExceptions(true), false); +} + +// Tests parsing --gtest_death_test_use_fork. +TEST_F(InitGoogleTestTest, DeathTestUseFork) { + const char* argv[] = { + "foo.exe", + "--gtest_death_test_use_fork", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::DeathTestUseFork(true), false); +} + +// Tests having the same flag twice with different values. The +// expected behavior is that the one coming last takes precedence. +TEST_F(InitGoogleTestTest, DuplicatedFlags) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=a", + "--gtest_filter=b", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("b"), false); +} + +// Tests having an unrecognized flag on the command line. +TEST_F(InitGoogleTestTest, UnrecognizedFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure", + "bar", // Unrecognized by Google Test. + "--gtest_filter=b", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "bar", + NULL + }; + + Flags flags; + flags.break_on_failure = true; + flags.filter = "b"; + GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags, false); +} + +// Tests having a --gtest_list_tests flag +TEST_F(InitGoogleTestTest, ListTestsFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); +} + +// Tests having a --gtest_list_tests flag with a "true" value +TEST_F(InitGoogleTestTest, ListTestsTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); +} + +// Tests having a --gtest_list_tests flag with a "false" value +TEST_F(InitGoogleTestTest, ListTestsFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_list_tests=f. +TEST_F(InitGoogleTestTest, ListTestsFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_list_tests=F. +TEST_F(InitGoogleTestTest, ListTestsFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_output (invalid). +TEST_F(InitGoogleTestTest, OutputEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_output", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "--gtest_output", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), true); +} + +// Tests parsing --gtest_output=xml +TEST_F(InitGoogleTestTest, OutputXml) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml"), false); +} + +// Tests parsing --gtest_output=xml:file +TEST_F(InitGoogleTestTest, OutputXmlFile) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml:file", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:file"), false); +} + +// Tests parsing --gtest_output=xml:directory/path/ +TEST_F(InitGoogleTestTest, OutputXmlDirectory) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml:directory/path/", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::Output("xml:directory/path/"), false); +} + +// Tests having a --gtest_print_time flag +TEST_F(InitGoogleTestTest, PrintTimeFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); +} + +// Tests having a --gtest_print_time flag with a "true" value +TEST_F(InitGoogleTestTest, PrintTimeTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); +} + +// Tests having a --gtest_print_time flag with a "false" value +TEST_F(InitGoogleTestTest, PrintTimeFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_print_time=f. +TEST_F(InitGoogleTestTest, PrintTimeFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_print_time=F. +TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_random_seed=number +TEST_F(InitGoogleTestTest, RandomSeed) { + const char* argv[] = { + "foo.exe", + "--gtest_random_seed=1000", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::RandomSeed(1000), false); +} + +// Tests parsing --gtest_repeat=number +TEST_F(InitGoogleTestTest, Repeat) { + const char* argv[] = { + "foo.exe", + "--gtest_repeat=1000", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Repeat(1000), false); +} + +// Tests having a --gtest_also_run_disabled_tests flag +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(true), false); +} + +// Tests having a --gtest_also_run_disabled_tests flag with a "true" value +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(true), false); +} + +// Tests having a --gtest_also_run_disabled_tests flag with a "false" value +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(false), false); +} + +// Tests parsing --gtest_shuffle. +TEST_F(InitGoogleTestTest, ShuffleWithoutValue) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); +} + +// Tests parsing --gtest_shuffle=0. +TEST_F(InitGoogleTestTest, ShuffleFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false); +} + +// Tests parsing a --gtest_shuffle flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, ShuffleTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); +} + +// Tests parsing --gtest_stack_trace_depth=number. +TEST_F(InitGoogleTestTest, StackTraceDepth) { + const char* argv[] = { + "foo.exe", + "--gtest_stack_trace_depth=5", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false); +} + +TEST_F(InitGoogleTestTest, StreamResultTo) { + const char* argv[] = { + "foo.exe", + "--gtest_stream_result_to=localhost:1234", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_( + argv, argv2, Flags::StreamResultTo("localhost:1234"), false); +} + +// Tests parsing --gtest_throw_on_failure. +TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); +} + +// Tests parsing --gtest_throw_on_failure=0. +TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false), false); +} + +// Tests parsing a --gtest_throw_on_failure flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); +} + +#if GTEST_OS_WINDOWS +// Tests parsing wide strings. +TEST_F(InitGoogleTestTest, WideStrings) { + const wchar_t* argv[] = { + L"foo.exe", + L"--gtest_filter=Foo*", + L"--gtest_list_tests=1", + L"--gtest_break_on_failure", + L"--non_gtest_flag", + NULL + }; + + const wchar_t* argv2[] = { + L"foo.exe", + L"--non_gtest_flag", + NULL + }; + + Flags expected_flags; + expected_flags.break_on_failure = true; + expected_flags.filter = "Foo*"; + expected_flags.list_tests = true; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false); +} +#endif // GTEST_OS_WINDOWS + +// Tests current_test_info() in UnitTest. +class CurrentTestInfoTest : public Test { + protected: + // Tests that current_test_info() returns NULL before the first test in + // the test case is run. + static void SetUpTestCase() { + // There should be no tests running at this point. + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + EXPECT_TRUE(test_info == NULL) + << "There should be no tests running at this point."; + } + + // Tests that current_test_info() returns NULL after the last test in + // the test case has run. + static void TearDownTestCase() { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + EXPECT_TRUE(test_info == NULL) + << "There should be no tests running at this point."; + } +}; + +// Tests that current_test_info() returns TestInfo for currently running +// test by checking the expected test name against the actual one. +TEST_F(CurrentTestInfoTest, WorksForFirstTestInATestCase) { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(NULL != test_info) + << "There is a test running so we should have a valid TestInfo."; + EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) + << "Expected the name of the currently running test case."; + EXPECT_STREQ("WorksForFirstTestInATestCase", test_info->name()) + << "Expected the name of the currently running test."; +} + +// Tests that current_test_info() returns TestInfo for currently running +// test by checking the expected test name against the actual one. We +// use this test to see that the TestInfo object actually changed from +// the previous invocation. +TEST_F(CurrentTestInfoTest, WorksForSecondTestInATestCase) { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(NULL != test_info) + << "There is a test running so we should have a valid TestInfo."; + EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) + << "Expected the name of the currently running test case."; + EXPECT_STREQ("WorksForSecondTestInATestCase", test_info->name()) + << "Expected the name of the currently running test."; +} + +} // namespace testing + +// These two lines test that we can define tests in a namespace that +// has the name "testing" and is nested in another namespace. +namespace my_namespace { +namespace testing { + +// Makes sure that TEST knows to use ::testing::Test instead of +// ::my_namespace::testing::Test. +class Test {}; + +// Makes sure that an assertion knows to use ::testing::Message instead of +// ::my_namespace::testing::Message. +class Message {}; + +// Makes sure that an assertion knows to use +// ::testing::AssertionResult instead of +// ::my_namespace::testing::AssertionResult. +class AssertionResult {}; + +// Tests that an assertion that should succeed works as expected. +TEST(NestedTestingNamespaceTest, Success) { + EXPECT_EQ(1, 1) << "This shouldn't fail."; +} + +// Tests that an assertion that should fail works as expected. +TEST(NestedTestingNamespaceTest, Failure) { + EXPECT_FATAL_FAILURE(FAIL() << "This failure is expected.", + "This failure is expected."); +} + +} // namespace testing +} // namespace my_namespace + +// Tests that one can call superclass SetUp and TearDown methods-- +// that is, that they are not private. +// No tests are based on this fixture; the test "passes" if it compiles +// successfully. +class ProtectedFixtureMethodsTest : public Test { + protected: + virtual void SetUp() { + Test::SetUp(); + } + virtual void TearDown() { + Test::TearDown(); + } +}; + +// StreamingAssertionsTest tests the streaming versions of a representative +// sample of assertions. +TEST(StreamingAssertionsTest, Unconditional) { + SUCCEED() << "expected success"; + EXPECT_NONFATAL_FAILURE(ADD_FAILURE() << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(FAIL() << "expected failure", + "expected failure"); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +TEST(StreamingAssertionsTest, Truth) { + EXPECT_TRUE(true) << "unexpected failure"; + ASSERT_TRUE(true) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, Truth2) { + EXPECT_FALSE(false) << "unexpected failure"; + ASSERT_FALSE(false) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_FALSE(true) << "expected failure", + "expected failure"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +# pragma option pop +#endif + +TEST(StreamingAssertionsTest, IntegerEquals) { + EXPECT_EQ(1, 1) << "unexpected failure"; + ASSERT_EQ(1, 1) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(1, 2) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(1, 2) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, IntegerLessThan) { + EXPECT_LT(1, 2) << "unexpected failure"; + ASSERT_LT(1, 2) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_LT(2, 1) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsEqual) { + EXPECT_STREQ("foo", "foo") << "unexpected failure"; + ASSERT_STREQ("foo", "foo") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ("foo", "bar") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STREQ("foo", "bar") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsNotEqual) { + EXPECT_STRNE("foo", "bar") << "unexpected failure"; + ASSERT_STRNE("foo", "bar") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("foo", "foo") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRNE("foo", "foo") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsEqualIgnoringCase) { + EXPECT_STRCASEEQ("foo", "FOO") << "unexpected failure"; + ASSERT_STRCASEEQ("foo", "FOO") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ("foo", "bar") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("foo", "bar") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringNotEqualIgnoringCase) { + EXPECT_STRCASENE("foo", "bar") << "unexpected failure"; + ASSERT_STRCASENE("foo", "bar") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("foo", "FOO") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("bar", "BAR") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, FloatingPointEquals) { + EXPECT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; + ASSERT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(0.0, 1.0) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.0) << "expected failure", + "expected failure"); +} + +#if GTEST_HAS_EXCEPTIONS + +TEST(StreamingAssertionsTest, Throw) { + EXPECT_THROW(ThrowAnInteger(), int) << "unexpected failure"; + ASSERT_THROW(ThrowAnInteger(), int) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_THROW(ThrowAnInteger(), bool) << + "expected failure", "expected failure"); +} + +TEST(StreamingAssertionsTest, NoThrow) { + EXPECT_NO_THROW(ThrowNothing()) << "unexpected failure"; + ASSERT_NO_THROW(ThrowNothing()) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()) << + "expected failure", "expected failure"); +} + +TEST(StreamingAssertionsTest, AnyThrow) { + EXPECT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; + ASSERT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(ThrowNothing()) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(ThrowNothing()) << + "expected failure", "expected failure"); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests that Google Test correctly decides whether to use colors in the output. + +TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsYes) { + GTEST_FLAG(color) = "yes"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsAliasOfYes) { + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + + GTEST_FLAG(color) = "True"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + GTEST_FLAG(color) = "t"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + GTEST_FLAG(color) = "1"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsNo) { + GTEST_FLAG(color) = "no"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsInvalid) { + SetEnv("TERM", "xterm"); // TERM supports colors. + + GTEST_FLAG(color) = "F"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + GTEST_FLAG(color) = "0"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + GTEST_FLAG(color) = "unknown"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenStdoutIsTty) { + GTEST_FLAG(color) = "auto"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { + GTEST_FLAG(color) = "auto"; + +#if GTEST_OS_WINDOWS + // On Windows, we ignore the TERM variable as it's usually not set. + + SetEnv("TERM", "dumb"); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", ""); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm"); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +#else + // On non-Windows platforms, we rely on TERM to determine if the + // terminal supports colors. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "emacs"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "vt100"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-mono"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "screen"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "screen-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "linux"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "cygwin"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +#endif // GTEST_OS_WINDOWS +} + +// Verifies that StaticAssertTypeEq works in a namespace scope. + +static bool dummy1 GTEST_ATTRIBUTE_UNUSED_ = StaticAssertTypeEq(); +static bool dummy2 GTEST_ATTRIBUTE_UNUSED_ = + StaticAssertTypeEq(); + +// Verifies that StaticAssertTypeEq works in a class. + +template +class StaticAssertTypeEqTestHelper { + public: + StaticAssertTypeEqTestHelper() { StaticAssertTypeEq(); } +}; + +TEST(StaticAssertTypeEqTest, WorksInClass) { + StaticAssertTypeEqTestHelper(); +} + +// Verifies that StaticAssertTypeEq works inside a function. + +typedef int IntAlias; + +TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) { + StaticAssertTypeEq(); + StaticAssertTypeEq(); +} + +TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) { + testing::UnitTest* const unit_test = testing::UnitTest::GetInstance(); + + // We don't have a stack walker in Google Test yet. + EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str()); + EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str()); +} + +TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) { + EXPECT_FALSE(HasNonfatalFailure()); +} + +static void FailFatally() { FAIL(); } + +TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsOnlyFatalFailure) { + FailFatally(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_FALSE(has_nonfatal_failure); +} + +TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { + FailFatally(); + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +// A wrapper for calling HasNonfatalFailure outside of a test body. +static bool HasNonfatalFailureHelper() { + return testing::Test::HasNonfatalFailure(); +} + +TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody) { + EXPECT_FALSE(HasNonfatalFailureHelper()); +} + +TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody2) { + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailureHelper(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +TEST(HasFailureTest, ReturnsFalseWhenThereIsNoFailure) { + EXPECT_FALSE(HasFailure()); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereIsFatalFailure) { + FailFatally(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { + ADD_FAILURE(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { + FailFatally(); + ADD_FAILURE(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +// A wrapper for calling HasFailure outside of a test body. +static bool HasFailureHelper() { return testing::Test::HasFailure(); } + +TEST(HasFailureTest, WorksOutsideOfTestBody) { + EXPECT_FALSE(HasFailureHelper()); +} + +TEST(HasFailureTest, WorksOutsideOfTestBody2) { + ADD_FAILURE(); + const bool has_failure = HasFailureHelper(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +class TestListener : public EmptyTestEventListener { + public: + TestListener() : on_start_counter_(NULL), is_destroyed_(NULL) {} + TestListener(int* on_start_counter, bool* is_destroyed) + : on_start_counter_(on_start_counter), + is_destroyed_(is_destroyed) {} + + virtual ~TestListener() { + if (is_destroyed_) + *is_destroyed_ = true; + } + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + if (on_start_counter_ != NULL) + (*on_start_counter_)++; + } + + private: + int* on_start_counter_; + bool* is_destroyed_; +}; + +// Tests the constructor. +TEST(TestEventListenersTest, ConstructionWorks) { + TestEventListeners listeners; + + EXPECT_TRUE(TestEventListenersAccessor::GetRepeater(&listeners) != NULL); + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_TRUE(listeners.default_xml_generator() == NULL); +} + +// Tests that the TestEventListeners destructor deletes all the listeners it +// owns. +TEST(TestEventListenersTest, DestructionWorks) { + bool default_result_printer_is_destroyed = false; + bool default_xml_printer_is_destroyed = false; + bool extra_listener_is_destroyed = false; + TestListener* default_result_printer = new TestListener( + NULL, &default_result_printer_is_destroyed); + TestListener* default_xml_printer = new TestListener( + NULL, &default_xml_printer_is_destroyed); + TestListener* extra_listener = new TestListener( + NULL, &extra_listener_is_destroyed); + + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, + default_result_printer); + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, + default_xml_printer); + listeners.Append(extra_listener); + } + EXPECT_TRUE(default_result_printer_is_destroyed); + EXPECT_TRUE(default_xml_printer_is_destroyed); + EXPECT_TRUE(extra_listener_is_destroyed); +} + +// Tests that a listener Append'ed to a TestEventListeners list starts +// receiving events. +TEST(TestEventListenersTest, Append) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + listeners.Append(listener); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); + } + EXPECT_TRUE(is_destroyed); +} + +// Tests that listeners receive events in the order they were appended to +// the list, except for *End requests, which must be received in the reverse +// order. +class SequenceTestingListener : public EmptyTestEventListener { + public: + SequenceTestingListener(std::vector* vector, const char* id) + : vector_(vector), id_(id) {} + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + vector_->push_back(GetEventDescription("OnTestProgramStart")); + } + + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { + vector_->push_back(GetEventDescription("OnTestProgramEnd")); + } + + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) { + vector_->push_back(GetEventDescription("OnTestIterationStart")); + } + + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) { + vector_->push_back(GetEventDescription("OnTestIterationEnd")); + } + + private: + std::string GetEventDescription(const char* method) { + Message message; + message << id_ << "." << method; + return message.GetString(); + } + + std::vector* vector_; + const char* const id_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener); +}; + +TEST(EventListenerTest, AppendKeepsOrder) { + std::vector vec; + TestEventListeners listeners; + listeners.Append(new SequenceTestingListener(&vec, "1st")); + listeners.Append(new SequenceTestingListener(&vec, "2nd")); + listeners.Append(new SequenceTestingListener(&vec, "3rd")); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("1st.OnTestProgramStart", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestProgramStart", vec[1].c_str()); + EXPECT_STREQ("3rd.OnTestProgramStart", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd( + *UnitTest::GetInstance()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("3rd.OnTestProgramEnd", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestProgramEnd", vec[1].c_str()); + EXPECT_STREQ("1st.OnTestProgramEnd", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("1st.OnTestIterationStart", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestIterationStart", vec[1].c_str()); + EXPECT_STREQ("3rd.OnTestIterationStart", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("3rd.OnTestIterationEnd", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestIterationEnd", vec[1].c_str()); + EXPECT_STREQ("1st.OnTestIterationEnd", vec[2].c_str()); +} + +// Tests that a listener removed from a TestEventListeners list stops receiving +// events and is not deleted when the list is destroyed. +TEST(TestEventListenersTest, Release) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + listeners.Append(listener); + EXPECT_EQ(listener, listeners.Release(listener)); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_TRUE(listeners.Release(listener) == NULL); + } + EXPECT_EQ(0, on_start_counter); + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that no events are forwarded when event forwarding is disabled. +TEST(EventListenerTest, SuppressEventForwarding) { + int on_start_counter = 0; + TestListener* listener = new TestListener(&on_start_counter, NULL); + + TestEventListeners listeners; + listeners.Append(listener); + ASSERT_TRUE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::SuppressEventForwarding(&listeners); + ASSERT_FALSE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); +} + +// Tests that events generated by Google Test are not forwarded in +// death test subprocesses. +TEST(EventListenerDeathTest, EventsNotForwardedInDeathTestSubprecesses) { + EXPECT_DEATH_IF_SUPPORTED({ + GTEST_CHECK_(TestEventListenersAccessor::EventForwardingEnabled( + *GetUnitTestImpl()->listeners())) << "expected failure";}, + "expected failure"); +} + +// Tests that a listener installed via SetDefaultResultPrinter() starts +// receiving events and is returned via default_result_printer() and that +// the previous default_result_printer is removed from the list and deleted. +TEST(EventListenerTest, default_result_printer) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_result_printer()); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_result_printer with something else should remove it + // from the list and destroy it. + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, NULL); + + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_result_printer listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultResultPrinterWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_result_printer. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that a listener installed via SetDefaultXmlGenerator() starts +// receiving events and is returned via default_xml_generator() and that +// the previous default_xml_generator is removed from the list and deleted. +TEST(EventListenerTest, default_xml_generator) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_xml_generator()); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_xml_generator with something else should remove it + // from the list and destroy it. + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, NULL); + + EXPECT_TRUE(listeners.default_xml_generator() == NULL); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_xml_generator listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_xml_generator() == NULL); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_xml_generator. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Sanity tests to ensure that the alternative, verbose spellings of +// some of the macros work. We don't test them thoroughly as that +// would be quite involved. Since their implementations are +// straightforward, and they are rarely used, we'll just rely on the +// users to tell us when they are broken. +GTEST_TEST(AlternativeNameTest, Works) { // GTEST_TEST is the same as TEST. + GTEST_SUCCEED() << "OK"; // GTEST_SUCCEED is the same as SUCCEED. + + // GTEST_FAIL is the same as FAIL. + EXPECT_FATAL_FAILURE(GTEST_FAIL() << "An expected failure", + "An expected failure"); + + // GTEST_ASSERT_XY is the same as ASSERT_XY. + + GTEST_ASSERT_EQ(0, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(0, 1) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_NE(0, 1); + GTEST_ASSERT_NE(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_NE(0, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_LE(0, 0); + GTEST_ASSERT_LE(0, 1); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LE(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_LT(0, 1); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(0, 0) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_GE(0, 0); + GTEST_ASSERT_GE(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GE(0, 1) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_GT(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(0, 1) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(1, 1) << "An expected failure", + "An expected failure"); +} + +// Tests for internal utilities necessary for implementation of the universal +// printing. +// TODO(vladl@google.com): Find a better home for them. + +class ConversionHelperBase {}; +class ConversionHelperDerived : public ConversionHelperBase {}; + +// Tests that IsAProtocolMessage::value is a compile-time constant. +TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { + GTEST_COMPILE_ASSERT_(IsAProtocolMessage::value, + const_true); + GTEST_COMPILE_ASSERT_(!IsAProtocolMessage::value, const_false); +} + +// Tests that IsAProtocolMessage::value is true when T is +// proto2::Message or a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) { + EXPECT_TRUE(IsAProtocolMessage< ::proto2::Message>::value); + EXPECT_TRUE(IsAProtocolMessage::value); +} + +// Tests that IsAProtocolMessage::value is false when T is neither +// ProtocolMessage nor a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) { + EXPECT_FALSE(IsAProtocolMessage::value); + EXPECT_FALSE(IsAProtocolMessage::value); +} + +// Tests that CompileAssertTypesEqual compiles when the type arguments are +// equal. +TEST(CompileAssertTypesEqual, CompilesWhenTypesAreEqual) { + CompileAssertTypesEqual(); + CompileAssertTypesEqual(); +} + +// Tests that RemoveReference does not affect non-reference types. +TEST(RemoveReferenceTest, DoesNotAffectNonReferenceType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that RemoveReference removes reference from reference types. +TEST(RemoveReferenceTest, RemovesReference) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_REMOVE_REFERENCE_. + +template +void TestGTestRemoveReference() { + CompileAssertTypesEqual(); +} + +TEST(RemoveReferenceTest, MacroVersion) { + TestGTestRemoveReference(); + TestGTestRemoveReference(); +} + + +// Tests that RemoveConst does not affect non-const types. +TEST(RemoveConstTest, DoesNotAffectNonConstType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that RemoveConst removes const from const types. +TEST(RemoveConstTest, RemovesConst) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_REMOVE_CONST_. + +template +void TestGTestRemoveConst() { + CompileAssertTypesEqual(); +} + +TEST(RemoveConstTest, MacroVersion) { + TestGTestRemoveConst(); + TestGTestRemoveConst(); + TestGTestRemoveConst(); +} + +// Tests GTEST_REMOVE_REFERENCE_AND_CONST_. + +template +void TestGTestRemoveReferenceAndConst() { + CompileAssertTypesEqual(); +} + +TEST(RemoveReferenceToConstTest, Works) { + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); +} + +// Tests that AddReference does not affect reference types. +TEST(AddReferenceTest, DoesNotAffectReferenceType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that AddReference adds reference to non-reference types. +TEST(AddReferenceTest, AddsReference) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_ADD_REFERENCE_. + +template +void TestGTestAddReference() { + CompileAssertTypesEqual(); +} + +TEST(AddReferenceTest, MacroVersion) { + TestGTestAddReference(); + TestGTestAddReference(); +} + +// Tests GTEST_REFERENCE_TO_CONST_. + +template +void TestGTestReferenceToConst() { + CompileAssertTypesEqual(); +} + +TEST(GTestReferenceToConstTest, Works) { + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); +} + +// Tests that ImplicitlyConvertible::value is a compile-time constant. +TEST(ImplicitlyConvertibleTest, ValueIsCompileTimeConstant) { + GTEST_COMPILE_ASSERT_((ImplicitlyConvertible::value), const_true); + GTEST_COMPILE_ASSERT_((!ImplicitlyConvertible::value), + const_false); +} + +// Tests that ImplicitlyConvertible::value is true when T1 can +// be implicitly converted to T2. +TEST(ImplicitlyConvertibleTest, ValueIsTrueWhenConvertible) { + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); +} + +// Tests that ImplicitlyConvertible::value is false when T1 +// cannot be implicitly converted to T2. +TEST(ImplicitlyConvertibleTest, ValueIsFalseWhenNotConvertible) { + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); +} + +// Tests IsContainerTest. + +class NonContainer {}; + +TEST(IsContainerTestTest, WorksForNonContainer) { + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); +} + +TEST(IsContainerTestTest, WorksForContainer) { + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest >(0))); + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest >(0))); +} + +// Tests ArrayEq(). + +TEST(ArrayEqTest, WorksForDegeneratedArrays) { + EXPECT_TRUE(ArrayEq(5, 5L)); + EXPECT_FALSE(ArrayEq('a', 0)); +} + +TEST(ArrayEqTest, WorksForOneDimensionalArrays) { + // Note that a and b are distinct but compatible types. + const int a[] = { 0, 1 }; + long b[] = { 0, 1 }; + EXPECT_TRUE(ArrayEq(a, b)); + EXPECT_TRUE(ArrayEq(a, 2, b)); + + b[0] = 2; + EXPECT_FALSE(ArrayEq(a, b)); + EXPECT_FALSE(ArrayEq(a, 1, b)); +} + +TEST(ArrayEqTest, WorksForTwoDimensionalArrays) { + const char a[][3] = { "hi", "lo" }; + const char b[][3] = { "hi", "lo" }; + const char c[][3] = { "hi", "li" }; + + EXPECT_TRUE(ArrayEq(a, b)); + EXPECT_TRUE(ArrayEq(a, 2, b)); + + EXPECT_FALSE(ArrayEq(a, c)); + EXPECT_FALSE(ArrayEq(a, 2, c)); +} + +// Tests ArrayAwareFind(). + +TEST(ArrayAwareFindTest, WorksForOneDimensionalArray) { + const char a[] = "hello"; + EXPECT_EQ(a + 4, ArrayAwareFind(a, a + 5, 'o')); + EXPECT_EQ(a + 5, ArrayAwareFind(a, a + 5, 'x')); +} + +TEST(ArrayAwareFindTest, WorksForTwoDimensionalArray) { + int a[][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } }; + const int b[2] = { 2, 3 }; + EXPECT_EQ(a + 1, ArrayAwareFind(a, a + 3, b)); + + const int c[2] = { 6, 7 }; + EXPECT_EQ(a + 3, ArrayAwareFind(a, a + 3, c)); +} + +// Tests CopyArray(). + +TEST(CopyArrayTest, WorksForDegeneratedArrays) { + int n = 0; + CopyArray('a', &n); + EXPECT_EQ('a', n); +} + +TEST(CopyArrayTest, WorksForOneDimensionalArrays) { + const char a[3] = "hi"; + int b[3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. + CopyArray(a, &b); + EXPECT_TRUE(ArrayEq(a, b)); +#endif + + int c[3]; + CopyArray(a, 3, c); + EXPECT_TRUE(ArrayEq(a, c)); +} + +TEST(CopyArrayTest, WorksForTwoDimensionalArrays) { + const int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; + int b[2][3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. + CopyArray(a, &b); + EXPECT_TRUE(ArrayEq(a, b)); +#endif + + int c[2][3]; + CopyArray(a, 2, c); + EXPECT_TRUE(ArrayEq(a, c)); +} + +// Tests NativeArray. + +TEST(NativeArrayTest, ConstructorFromArrayWorks) { + const int a[3] = { 0, 1, 2 }; + NativeArray na(a, 3, kReference); + EXPECT_EQ(3U, na.size()); + EXPECT_EQ(a, na.begin()); +} + +TEST(NativeArrayTest, CreatesAndDeletesCopyOfArrayWhenAskedTo) { + typedef int Array[2]; + Array* a = new Array[1]; + (*a)[0] = 0; + (*a)[1] = 1; + NativeArray na(*a, 2, kCopy); + EXPECT_NE(*a, na.begin()); + delete[] a; + EXPECT_EQ(0, na.begin()[0]); + EXPECT_EQ(1, na.begin()[1]); + + // We rely on the heap checker to verify that na deletes the copy of + // array. +} + +TEST(NativeArrayTest, TypeMembersAreCorrect) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); + + StaticAssertTypeEq::const_iterator>(); + StaticAssertTypeEq::const_iterator>(); +} + +TEST(NativeArrayTest, MethodsWork) { + const int a[3] = { 0, 1, 2 }; + NativeArray na(a, 3, kCopy); + ASSERT_EQ(3U, na.size()); + EXPECT_EQ(3, na.end() - na.begin()); + + NativeArray::const_iterator it = na.begin(); + EXPECT_EQ(0, *it); + ++it; + EXPECT_EQ(1, *it); + it++; + EXPECT_EQ(2, *it); + ++it; + EXPECT_EQ(na.end(), it); + + EXPECT_TRUE(na == na); + + NativeArray na2(a, 3, kReference); + EXPECT_TRUE(na == na2); + + const int b1[3] = { 0, 1, 1 }; + const int b2[4] = { 0, 1, 2, 3 }; + EXPECT_FALSE(na == NativeArray(b1, 3, kReference)); + EXPECT_FALSE(na == NativeArray(b2, 4, kCopy)); +} + +TEST(NativeArrayTest, WorksForTwoDimensionalArray) { + const char a[2][3] = { "hi", "lo" }; + NativeArray na(a, 2, kReference); + ASSERT_EQ(2U, na.size()); + EXPECT_EQ(a, na.begin()); +} + +// Tests SkipPrefix(). + +TEST(SkipPrefixTest, SkipsWhenPrefixMatches) { + const char* const str = "hello"; + + const char* p = str; + EXPECT_TRUE(SkipPrefix("", &p)); + EXPECT_EQ(str, p); + + p = str; + EXPECT_TRUE(SkipPrefix("hell", &p)); + EXPECT_EQ(str + 4, p); +} + +TEST(SkipPrefixTest, DoesNotSkipWhenPrefixDoesNotMatch) { + const char* const str = "world"; + + const char* p = str; + EXPECT_FALSE(SkipPrefix("W", &p)); + EXPECT_EQ(str, p); + + p = str; + EXPECT_FALSE(SkipPrefix("world!", &p)); + EXPECT_EQ(str, p); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfile1_test_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfile1_test_.cc new file mode 100644 index 0000000..531ced4 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfile1_test_.cc @@ -0,0 +1,49 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// gtest_xml_outfile1_test_ writes some xml via TestProperty used by +// gtest_xml_outfiles_test.py + +#include "gtest/gtest.h" + +class PropertyOne : public testing::Test { + protected: + virtual void SetUp() { + RecordProperty("SetUpProp", 1); + } + virtual void TearDown() { + RecordProperty("TearDownProp", 1); + } +}; + +TEST_F(PropertyOne, TestSomeProperties) { + RecordProperty("TestSomeProperty", 1); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfile2_test_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfile2_test_.cc new file mode 100644 index 0000000..7b400b2 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfile2_test_.cc @@ -0,0 +1,49 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// gtest_xml_outfile2_test_ writes some xml via TestProperty used by +// gtest_xml_outfiles_test.py + +#include "gtest/gtest.h" + +class PropertyTwo : public testing::Test { + protected: + virtual void SetUp() { + RecordProperty("SetUpProp", 2); + } + virtual void TearDown() { + RecordProperty("TearDownProp", 2); + } +}; + +TEST_F(PropertyTwo, TestSomeProperties) { + RecordProperty("TestSomeProperty", 2); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfiles_test.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfiles_test.py new file mode 100755 index 0000000..524e437 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_outfiles_test.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test for the gtest_xml_output module.""" + +__author__ = "keith.ray@gmail.com (Keith Ray)" + +import os +from xml.dom import minidom, Node + +import gtest_test_utils +import gtest_xml_test_utils + + +GTEST_OUTPUT_SUBDIR = "xml_outfiles" +GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_" +GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" + +EXPECTED_XML_1 = """ + + + + + +""" + +EXPECTED_XML_2 = """ + + + + + +""" + + +class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): + """Unit test for Google Test's XML output functionality.""" + + def setUp(self): + # We want the trailing '/' that the last "" provides in os.path.join, for + # telling Google Test to create an output directory instead of a single file + # for xml output. + self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_OUTPUT_SUBDIR, "") + self.DeleteFilesAndDir() + + def tearDown(self): + self.DeleteFilesAndDir() + + def DeleteFilesAndDir(self): + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + ".xml")) + except os.error: + pass + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + ".xml")) + except os.error: + pass + try: + os.rmdir(self.output_dir_) + except os.error: + pass + + def testOutfile1(self): + self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_XML_1) + + def testOutfile2(self): + self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_XML_2) + + def _TestOutFile(self, test_name, expected_xml): + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name) + command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_] + p = gtest_test_utils.Subprocess(command, + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + + # TODO(wan@google.com): libtool causes the built test binary to be + # named lt-gtest_xml_outfiles_test_ instead of + # gtest_xml_outfiles_test_. To account for this possibillity, we + # allow both names in the following code. We should remove this + # hack when Chandler Carruth's libtool replacement tool is ready. + output_file_name1 = test_name + ".xml" + output_file1 = os.path.join(self.output_dir_, output_file_name1) + output_file_name2 = 'lt-' + output_file_name1 + output_file2 = os.path.join(self.output_dir_, output_file_name2) + self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2), + output_file1) + + expected = minidom.parseString(expected_xml) + if os.path.isfile(output_file1): + actual = minidom.parse(output_file1) + else: + actual = minidom.parse(output_file2) + self.NormalizeXml(actual.documentElement) + self.AssertEquivalentNodes(expected.documentElement, + actual.documentElement) + expected.unlink() + actual.unlink() + + +if __name__ == "__main__": + os.environ["GTEST_STACK_TRACE_DEPTH"] = "0" + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_output_unittest.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_output_unittest.py new file mode 100755 index 0000000..f605d4e --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_output_unittest.py @@ -0,0 +1,307 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test for the gtest_xml_output module""" + +__author__ = 'eefacm@gmail.com (Sean Mcafee)' + +import datetime +import errno +import os +import re +import sys +from xml.dom import minidom, Node + +import gtest_test_utils +import gtest_xml_test_utils + + +GTEST_FILTER_FLAG = '--gtest_filter' +GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' +GTEST_OUTPUT_FLAG = "--gtest_output" +GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" +GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_" + +SUPPORTS_STACK_TRACES = False + +if SUPPORTS_STACK_TRACES: + STACK_TRACE_TEMPLATE = '\nStack trace:\n*' +else: + STACK_TRACE_TEMPLATE = '' + +EXPECTED_NON_EMPTY_XML = """ + + + + + + + + + + + + + + + + + + + + ]]>%(stack)s]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" % {'stack': STACK_TRACE_TEMPLATE} + +EXPECTED_FILTERED_TEST_XML = """ + + + + +""" + +EXPECTED_EMPTY_XML = """ + +""" + +GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) + +SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess( + [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output + + +class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): + """ + Unit test for Google Test's XML output functionality. + """ + + # This test currently breaks on platforms that do not support typed and + # type-parameterized tests, so we don't run it under them. + if SUPPORTS_TYPED_TESTS: + def testNonEmptyXmlOutput(self): + """ + Runs a test program that generates a non-empty XML output, and + tests that the XML output is expected. + """ + self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) + + def testEmptyXmlOutput(self): + """Verifies XML output for a Google Test binary without actual tests. + + Runs a test program that generates an empty XML output, and + tests that the XML output is expected. + """ + + self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0) + + def testTimestampValue(self): + """Checks whether the timestamp attribute in the XML output is valid. + + Runs a test program that generates an empty XML output, and checks if + the timestamp attribute in the testsuites tag is valid. + """ + actual = self._GetXmlOutput('gtest_no_test_unittest', [], 0) + date_time_str = actual.documentElement.getAttributeNode('timestamp').value + # datetime.strptime() is only available in Python 2.5+ so we have to + # parse the expected datetime manually. + match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str) + self.assertTrue( + re.match, + 'XML datettime string %s has incorrect format' % date_time_str) + date_time_from_xml = datetime.datetime( + year=int(match.group(1)), month=int(match.group(2)), + day=int(match.group(3)), hour=int(match.group(4)), + minute=int(match.group(5)), second=int(match.group(6))) + + time_delta = abs(datetime.datetime.now() - date_time_from_xml) + # timestamp value should be near the current local time + self.assertTrue(time_delta < datetime.timedelta(seconds=600), + 'time_delta is %s' % time_delta) + actual.unlink() + + def testDefaultOutputFile(self): + """ + Confirms that Google Test produces an XML output file with the expected + default name if no name is explicitly specified. + """ + output_file = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_DEFAULT_OUTPUT_FILE) + gtest_prog_path = gtest_test_utils.GetTestExecutablePath( + 'gtest_no_test_unittest') + try: + os.remove(output_file) + except OSError, e: + if e.errno != errno.ENOENT: + raise + + p = gtest_test_utils.Subprocess( + [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG], + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + self.assert_(os.path.isfile(output_file)) + + def testSuppressedXmlOutput(self): + """ + Tests that no XML file is generated if the default XML listener is + shut down before RUN_ALL_TESTS is invoked. + """ + + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_PROGRAM_NAME + 'out.xml') + if os.path.isfile(xml_path): + os.remove(xml_path) + + command = [GTEST_PROGRAM_PATH, + '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path), + '--shut_down_xml'] + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + # p.signal is avalable only if p.terminated_by_signal is True. + self.assertFalse( + p.terminated_by_signal, + '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(1, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, 1)) + + self.assert_(not os.path.isfile(xml_path)) + + def testFilteredTestXmlOutput(self): + """Verifies XML output when a filter is applied. + + Runs a test program that executes only some tests and verifies that + non-selected tests do not show up in the XML output. + """ + + self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED_TEST_XML, 0, + extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG]) + + def _GetXmlOutput(self, gtest_prog_name, extra_args, expected_exit_code): + """ + Returns the xml output generated by running the program gtest_prog_name. + Furthermore, the program's exit code must be expected_exit_code. + """ + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + gtest_prog_name + 'out.xml') + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) + + command = ([gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] + + extra_args) + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + self.assert_(False, + '%s was killed by signal %d' % (gtest_prog_name, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(expected_exit_code, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, expected_exit_code)) + actual = minidom.parse(xml_path) + return actual + + def _TestXmlOutput(self, gtest_prog_name, expected_xml, + expected_exit_code, extra_args=None): + """ + Asserts that the XML document generated by running the program + gtest_prog_name matches expected_xml, a string containing another + XML document. Furthermore, the program's exit code must be + expected_exit_code. + """ + + actual = self._GetXmlOutput(gtest_prog_name, extra_args or [], + expected_exit_code) + expected = minidom.parseString(expected_xml) + self.NormalizeXml(actual.documentElement) + self.AssertEquivalentNodes(expected.documentElement, + actual.documentElement) + expected.unlink() + actual.unlink() + + +if __name__ == '__main__': + os.environ['GTEST_STACK_TRACE_DEPTH'] = '1' + gtest_test_utils.Main() diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_output_unittest_.cc b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_output_unittest_.cc new file mode 100644 index 0000000..48b8771 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_output_unittest_.cc @@ -0,0 +1,181 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +// Author: eefacm@gmail.com (Sean Mcafee) + +// Unit test for Google Test XML output. +// +// A user can specify XML output in a Google Test program to run via +// either the GTEST_OUTPUT environment variable or the --gtest_output +// flag. This is used for testing such functionality. +// +// This program will be invoked from a Python unit test. Don't run it +// directly. + +#include "gtest/gtest.h" + +using ::testing::InitGoogleTest; +using ::testing::TestEventListeners; +using ::testing::TestWithParam; +using ::testing::UnitTest; +using ::testing::Test; +using ::testing::Values; + +class SuccessfulTest : public Test { +}; + +TEST_F(SuccessfulTest, Succeeds) { + SUCCEED() << "This is a success."; + ASSERT_EQ(1, 1); +} + +class FailedTest : public Test { +}; + +TEST_F(FailedTest, Fails) { + ASSERT_EQ(1, 2); +} + +class DisabledTest : public Test { +}; + +TEST_F(DisabledTest, DISABLED_test_not_run) { + FAIL() << "Unexpected failure: Disabled test should not be run"; +} + +TEST(MixedResultTest, Succeeds) { + EXPECT_EQ(1, 1); + ASSERT_EQ(1, 1); +} + +TEST(MixedResultTest, Fails) { + EXPECT_EQ(1, 2); + ASSERT_EQ(2, 3); +} + +TEST(MixedResultTest, DISABLED_test) { + FAIL() << "Unexpected failure: Disabled test should not be run"; +} + +TEST(XmlQuotingTest, OutputsCData) { + FAIL() << "XML output: " + ""; +} + +// Helps to test that invalid characters produced by test code do not make +// it into the XML file. +TEST(InvalidCharactersTest, InvalidCharactersInMessage) { + FAIL() << "Invalid characters in brackets [\x1\x2]"; +} + +class PropertyRecordingTest : public Test { + public: + static void SetUpTestCase() { RecordProperty("SetUpTestCase", "yes"); } + static void TearDownTestCase() { RecordProperty("TearDownTestCase", "aye"); } +}; + +TEST_F(PropertyRecordingTest, OneProperty) { + RecordProperty("key_1", "1"); +} + +TEST_F(PropertyRecordingTest, IntValuedProperty) { + RecordProperty("key_int", 1); +} + +TEST_F(PropertyRecordingTest, ThreeProperties) { + RecordProperty("key_1", "1"); + RecordProperty("key_2", "2"); + RecordProperty("key_3", "3"); +} + +TEST_F(PropertyRecordingTest, TwoValuesForOneKeyUsesLastValue) { + RecordProperty("key_1", "1"); + RecordProperty("key_1", "2"); +} + +TEST(NoFixtureTest, RecordProperty) { + RecordProperty("key", "1"); +} + +void ExternalUtilityThatCallsRecordProperty(const std::string& key, int value) { + testing::Test::RecordProperty(key, value); +} + +void ExternalUtilityThatCallsRecordProperty(const std::string& key, + const std::string& value) { + testing::Test::RecordProperty(key, value); +} + +TEST(NoFixtureTest, ExternalUtilityThatCallsRecordIntValuedProperty) { + ExternalUtilityThatCallsRecordProperty("key_for_utility_int", 1); +} + +TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) { + ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1"); +} + +// Verifies that the test parameter value is output in the 'value_param' +// XML attribute for value-parameterized tests. +class ValueParamTest : public TestWithParam {}; +TEST_P(ValueParamTest, HasValueParamAttribute) {} +TEST_P(ValueParamTest, AnotherTestThatHasValueParamAttribute) {} +INSTANTIATE_TEST_CASE_P(Single, ValueParamTest, Values(33, 42)); + +#if GTEST_HAS_TYPED_TEST +// Verifies that the type parameter name is output in the 'type_param' +// XML attribute for typed tests. +template class TypedTest : public Test {}; +typedef testing::Types TypedTestTypes; +TYPED_TEST_CASE(TypedTest, TypedTestTypes); +TYPED_TEST(TypedTest, HasTypeParamAttribute) {} +#endif + +#if GTEST_HAS_TYPED_TEST_P +// Verifies that the type parameter name is output in the 'type_param' +// XML attribute for type-parameterized tests. +template class TypeParameterizedTestCase : public Test {}; +TYPED_TEST_CASE_P(TypeParameterizedTestCase); +TYPED_TEST_P(TypeParameterizedTestCase, HasTypeParamAttribute) {} +REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTestCase, HasTypeParamAttribute); +typedef testing::Types TypeParameterizedTestCaseTypes; +INSTANTIATE_TYPED_TEST_CASE_P(Single, + TypeParameterizedTestCase, + TypeParameterizedTestCaseTypes); +#endif + +int main(int argc, char** argv) { + InitGoogleTest(&argc, argv); + + if (argc > 1 && strcmp(argv[1], "--shut_down_xml") == 0) { + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_xml_generator()); + } + testing::Test::RecordProperty("ad_hoc_property", "42"); + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_test_utils.py b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_test_utils.py new file mode 100755 index 0000000..3d0c3b2 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/gtest_xml_test_utils.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test utilities for gtest_xml_output""" + +__author__ = 'eefacm@gmail.com (Sean Mcafee)' + +import re +from xml.dom import minidom, Node + +import gtest_test_utils + + +GTEST_OUTPUT_FLAG = '--gtest_output' +GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' + +class GTestXMLTestCase(gtest_test_utils.TestCase): + """ + Base class for tests of Google Test's XML output functionality. + """ + + + def AssertEquivalentNodes(self, expected_node, actual_node): + """ + Asserts that actual_node (a DOM node object) is equivalent to + expected_node (another DOM node object), in that either both of + them are CDATA nodes and have the same value, or both are DOM + elements and actual_node meets all of the following conditions: + + * It has the same tag name as expected_node. + * It has the same set of attributes as expected_node, each with + the same value as the corresponding attribute of expected_node. + Exceptions are any attribute named "time", which needs only be + convertible to a floating-point number and any attribute named + "type_param" which only has to be non-empty. + * It has an equivalent set of child nodes (including elements and + CDATA sections) as expected_node. Note that we ignore the + order of the children as they are not guaranteed to be in any + particular order. + """ + + if expected_node.nodeType == Node.CDATA_SECTION_NODE: + self.assertEquals(Node.CDATA_SECTION_NODE, actual_node.nodeType) + self.assertEquals(expected_node.nodeValue, actual_node.nodeValue) + return + + self.assertEquals(Node.ELEMENT_NODE, actual_node.nodeType) + self.assertEquals(Node.ELEMENT_NODE, expected_node.nodeType) + self.assertEquals(expected_node.tagName, actual_node.tagName) + + expected_attributes = expected_node.attributes + actual_attributes = actual_node .attributes + self.assertEquals( + expected_attributes.length, actual_attributes.length, + 'attribute numbers differ in element %s:\nExpected: %r\nActual: %r' % ( + actual_node.tagName, expected_attributes.keys(), + actual_attributes.keys())) + for i in range(expected_attributes.length): + expected_attr = expected_attributes.item(i) + actual_attr = actual_attributes.get(expected_attr.name) + self.assert_( + actual_attr is not None, + 'expected attribute %s not found in element %s' % + (expected_attr.name, actual_node.tagName)) + self.assertEquals( + expected_attr.value, actual_attr.value, + ' values of attribute %s in element %s differ: %s vs %s' % + (expected_attr.name, actual_node.tagName, + expected_attr.value, actual_attr.value)) + + expected_children = self._GetChildren(expected_node) + actual_children = self._GetChildren(actual_node) + self.assertEquals( + len(expected_children), len(actual_children), + 'number of child elements differ in element ' + actual_node.tagName) + for child_id, child in expected_children.iteritems(): + self.assert_(child_id in actual_children, + '<%s> is not in <%s> (in element %s)' % + (child_id, actual_children, actual_node.tagName)) + self.AssertEquivalentNodes(child, actual_children[child_id]) + + identifying_attribute = { + 'testsuites': 'name', + 'testsuite': 'name', + 'testcase': 'name', + 'failure': 'message', + } + + def _GetChildren(self, element): + """ + Fetches all of the child nodes of element, a DOM Element object. + Returns them as the values of a dictionary keyed by the IDs of the + children. For , and elements, the ID + is the value of their "name" attribute; for elements, it is + the value of the "message" attribute; CDATA sections and non-whitespace + text nodes are concatenated into a single CDATA section with ID + "detail". An exception is raised if any element other than the above + four is encountered, if two child elements with the same identifying + attributes are encountered, or if any other type of node is encountered. + """ + + children = {} + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self.assert_(child.tagName in self.identifying_attribute, + 'Encountered unknown element <%s>' % child.tagName) + childID = child.getAttribute(self.identifying_attribute[child.tagName]) + self.assert_(childID not in children) + children[childID] = child + elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: + if 'detail' not in children: + if (child.nodeType == Node.CDATA_SECTION_NODE or + not child.nodeValue.isspace()): + children['detail'] = child.ownerDocument.createCDATASection( + child.nodeValue) + else: + children['detail'].nodeValue += child.nodeValue + else: + self.fail('Encountered unexpected node type %d' % child.nodeType) + return children + + def NormalizeXml(self, element): + """ + Normalizes Google Test's XML output to eliminate references to transient + information that may change from run to run. + + * The "time" attribute of , and + elements is replaced with a single asterisk, if it contains + only digit characters. + * The "timestamp" attribute of elements is replaced with a + single asterisk, if it contains a valid ISO8601 datetime value. + * The "type_param" attribute of elements is replaced with a + single asterisk (if it sn non-empty) as it is the type name returned + by the compiler and is platform dependent. + * The line info reported in the first line of the "message" + attribute and CDATA section of elements is replaced with the + file's basename and a single asterisk for the line number. + * The directory names in file paths are removed. + * The stack traces are removed. + """ + + if element.tagName == 'testsuites': + timestamp = element.getAttributeNode('timestamp') + timestamp.value = re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$', + '*', timestamp.value) + if element.tagName in ('testsuites', 'testsuite', 'testcase'): + time = element.getAttributeNode('time') + time.value = re.sub(r'^\d+(\.\d+)?$', '*', time.value) + type_param = element.getAttributeNode('type_param') + if type_param and type_param.value: + type_param.value = '*' + elif element.tagName == 'failure': + source_line_pat = r'^.*[/\\](.*:)\d+\n' + # Replaces the source line information with a normalized form. + message = element.getAttributeNode('message') + message.value = re.sub(source_line_pat, '\\1*\n', message.value) + for child in element.childNodes: + if child.nodeType == Node.CDATA_SECTION_NODE: + # Replaces the source line information with a normalized form. + cdata = re.sub(source_line_pat, '\\1*\n', child.nodeValue) + # Removes the actual stack trace. + child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*', + '', cdata) + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self.NormalizeXml(child) diff --git a/cpp/thirdparty/gtest-1.7.0/test/production.cc b/cpp/thirdparty/gtest-1.7.0/test/production.cc new file mode 100644 index 0000000..8b8a40b --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/production.cc @@ -0,0 +1,36 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This is part of the unit test for include/gtest/gtest_prod.h. + +#include "production.h" + +PrivateCode::PrivateCode() : x_(0) {} diff --git a/cpp/thirdparty/gtest-1.7.0/test/production.h b/cpp/thirdparty/gtest-1.7.0/test/production.h new file mode 100644 index 0000000..98fd5e4 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/test/production.h @@ -0,0 +1,55 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This is part of the unit test for include/gtest/gtest_prod.h. + +#ifndef GTEST_TEST_PRODUCTION_H_ +#define GTEST_TEST_PRODUCTION_H_ + +#include "gtest/gtest_prod.h" + +class PrivateCode { + public: + // Declares a friend test that does not use a fixture. + FRIEND_TEST(PrivateCodeTest, CanAccessPrivateMembers); + + // Declares a friend test that uses a fixture. + FRIEND_TEST(PrivateCodeFixtureTest, CanAccessPrivateMembers); + + PrivateCode(); + + int x() const { return x_; } + private: + void set_x(int an_x) { x_ = an_x; } + int x_; +}; + +#endif // GTEST_TEST_PRODUCTION_H_ diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Config/DebugProject.xcconfig b/cpp/thirdparty/gtest-1.7.0/xcode/Config/DebugProject.xcconfig new file mode 100644 index 0000000..3d68157 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Config/DebugProject.xcconfig @@ -0,0 +1,30 @@ +// +// DebugProject.xcconfig +// +// These are Debug Configuration project settings for the gtest framework and +// examples. It is set in the "Based On:" dropdown in the "Project" info +// dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +#include "General.xcconfig" + +// No optimization +GCC_OPTIMIZATION_LEVEL = 0 + +// Deployment postprocessing is what triggers Xcode to strip, turn it off +DEPLOYMENT_POSTPROCESSING = NO + +// Dead code stripping off +DEAD_CODE_STRIPPING = NO + +// Debug symbols should be on obviously +GCC_GENERATE_DEBUGGING_SYMBOLS = YES + +// Define the DEBUG macro in all debug builds +OTHER_CFLAGS = $(OTHER_CFLAGS) -DDEBUG=1 + +// These are turned off to avoid STL incompatibilities with client code +// // Turns on special C++ STL checks to "encourage" good STL use +// GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS) _GLIBCXX_DEBUG_PEDANTIC _GLIBCXX_DEBUG _GLIBCPP_CONCEPT_CHECKS diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Config/FrameworkTarget.xcconfig b/cpp/thirdparty/gtest-1.7.0/xcode/Config/FrameworkTarget.xcconfig new file mode 100644 index 0000000..357b1c8 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Config/FrameworkTarget.xcconfig @@ -0,0 +1,17 @@ +// +// FrameworkTarget.xcconfig +// +// These are Framework target settings for the gtest framework and examples. It +// is set in the "Based On:" dropdown in the "Target" info dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +// Dynamic libs need to be position independent +GCC_DYNAMIC_NO_PIC = NO + +// Dynamic libs should not have their external symbols stripped. +STRIP_STYLE = non-global + +// Let the user install by specifying the $DSTROOT with xcodebuild +SKIP_INSTALL = NO diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Config/General.xcconfig b/cpp/thirdparty/gtest-1.7.0/xcode/Config/General.xcconfig new file mode 100644 index 0000000..f23e322 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Config/General.xcconfig @@ -0,0 +1,41 @@ +// +// General.xcconfig +// +// These are General configuration settings for the gtest framework and +// examples. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +// Build for PPC and Intel, 32- and 64-bit +ARCHS = i386 x86_64 ppc ppc64 + +// Zerolink prevents link warnings so turn it off +ZERO_LINK = NO + +// Prebinding considered unhelpful in 10.3 and later +PREBINDING = NO + +// Strictest warning policy +WARNING_CFLAGS = -Wall -Werror -Wendif-labels -Wnewline-eof -Wno-sign-compare -Wshadow + +// Work around Xcode bugs by using external strip. See: +// http://lists.apple.com/archives/Xcode-users/2006/Feb/msg00050.html +SEPARATE_STRIP = YES + +// Force C99 dialect +GCC_C_LANGUAGE_STANDARD = c99 + +// not sure why apple defaults this on, but it's pretty risky +ALWAYS_SEARCH_USER_PATHS = NO + +// Turn on position dependent code for most cases (overridden where appropriate) +GCC_DYNAMIC_NO_PIC = YES + +// Default SDK and minimum OS version is 10.4 +SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk +MACOSX_DEPLOYMENT_TARGET = 10.4 +GCC_VERSION = 4.0 + +// VERSIONING BUILD SETTINGS (used in Info.plist) +GTEST_VERSIONINFO_ABOUT = © 2008 Google Inc. diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Config/ReleaseProject.xcconfig b/cpp/thirdparty/gtest-1.7.0/xcode/Config/ReleaseProject.xcconfig new file mode 100644 index 0000000..5349f0a --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Config/ReleaseProject.xcconfig @@ -0,0 +1,32 @@ +// +// ReleaseProject.xcconfig +// +// These are Release Configuration project settings for the gtest framework +// and examples. It is set in the "Based On:" dropdown in the "Project" info +// dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +#include "General.xcconfig" + +// subconfig/Release.xcconfig + +// Optimize for space and size (Apple recommendation) +GCC_OPTIMIZATION_LEVEL = s + +// Deploment postprocessing is what triggers Xcode to strip +DEPLOYMENT_POSTPROCESSING = YES + +// No symbols +GCC_GENERATE_DEBUGGING_SYMBOLS = NO + +// Dead code strip does not affect ObjC code but can help for C +DEAD_CODE_STRIPPING = YES + +// NDEBUG is used by things like assert.h, so define it for general compat. +// ASSERT going away in release tends to create unused vars. +OTHER_CFLAGS = $(OTHER_CFLAGS) -DNDEBUG=1 -Wno-unused-variable + +// When we strip we want to strip all symbols in release, but save externals. +STRIP_STYLE = all diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Config/StaticLibraryTarget.xcconfig b/cpp/thirdparty/gtest-1.7.0/xcode/Config/StaticLibraryTarget.xcconfig new file mode 100644 index 0000000..3922fa5 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Config/StaticLibraryTarget.xcconfig @@ -0,0 +1,18 @@ +// +// StaticLibraryTarget.xcconfig +// +// These are static library target settings for libgtest.a. It +// is set in the "Based On:" dropdown in the "Target" info dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +// Static libs can be included in bundles so make them position independent +GCC_DYNAMIC_NO_PIC = NO + +// Static libs should not have their internal globals or external symbols +// stripped. +STRIP_STYLE = debugging + +// Let the user install by specifying the $DSTROOT with xcodebuild +SKIP_INSTALL = NO diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Config/TestTarget.xcconfig b/cpp/thirdparty/gtest-1.7.0/xcode/Config/TestTarget.xcconfig new file mode 100644 index 0000000..e6652ba --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Config/TestTarget.xcconfig @@ -0,0 +1,8 @@ +// +// TestTarget.xcconfig +// +// These are Test target settings for the gtest framework and examples. It +// is set in the "Based On:" dropdown in the "Target" info dialog. + +PRODUCT_NAME = $(TARGET_NAME) +HEADER_SEARCH_PATHS = ../include diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Resources/Info.plist b/cpp/thirdparty/gtest-1.7.0/xcode/Resources/Info.plist new file mode 100644 index 0000000..9dd28ea --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Resources/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.google.${PRODUCT_NAME} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + GTEST_VERSIONINFO_LONG + CFBundleShortVersionString + GTEST_VERSIONINFO_SHORT + CFBundleGetInfoString + ${PRODUCT_NAME} GTEST_VERSIONINFO_LONG, ${GTEST_VERSIONINFO_ABOUT} + NSHumanReadableCopyright + ${GTEST_VERSIONINFO_ABOUT} + CSResourcesFileMapped + + + diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/Info.plist b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/Info.plist new file mode 100644 index 0000000..f3852ed --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.google.gtest.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CSResourcesFileMapped + + + diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj new file mode 100644 index 0000000..497617e --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj @@ -0,0 +1,457 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXAggregateTarget section */ + 4024D162113D7D2400C7059E /* Test */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */; + buildPhases = ( + 4024D161113D7D2400C7059E /* ShellScript */, + ); + dependencies = ( + 4024D166113D7D3100C7059E /* PBXTargetDependency */, + ); + name = Test; + productName = TestAndBuild; + }; + 4024D1E9113D83FF00C7059E /* TestAndBuild */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */; + buildPhases = ( + ); + dependencies = ( + 4024D1ED113D840900C7059E /* PBXTargetDependency */, + 4024D1EF113D840D00C7059E /* PBXTargetDependency */, + ); + name = TestAndBuild; + productName = TestAndBuild; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1230E5AEE3500C7F239 /* widget.cc */; }; + 3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B7EB1240E5AEE3500C7F239 /* widget.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */; }; + 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; }; + 4024D188113D7D7800C7059E /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D185113D7D5500C7059E /* libgtest.a */; }; + 4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D183113D7D5500C7059E /* libgtest_main.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = gTestExample; + }; + 4024D165113D7D3100C7059E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3B07BDE90E3F3F9E00647869; + remoteInfo = WidgetFrameworkTest; + }; + 4024D1EC113D840900C7059E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = WidgetFramework; + }; + 4024D1EE113D840D00C7059E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4024D162113D7D2400C7059E; + remoteInfo = Test; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = WidgetFrameworkTest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B7EB1230E5AEE3500C7F239 /* widget.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget.cc; sourceTree = ""; }; + 3B7EB1240E5AEE3500C7F239 /* widget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = widget.h; sourceTree = ""; }; + 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget_test.cc; sourceTree = ""; }; + 4024D183113D7D5500C7059E /* libgtest_main.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest_main.a; path = /usr/local/lib/libgtest_main.a; sourceTree = ""; }; + 4024D185113D7D5500C7059E /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest.a; path = /usr/local/lib/libgtest.a; sourceTree = ""; }; + 4024D1E2113D838200C7059E /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = ""; }; + 8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 8D07F2C80486CC7A007CD1D0 /* Widget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Widget.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3B07BDE80E3F3F9E00647869 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */, + 4024D188113D7D7800C7059E /* libgtest.a in Frameworks */, + 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C30486CC7A007CD1D0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 8D07F2C80486CC7A007CD1D0 /* Widget.framework */, + 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */, + ); + name = Products; + sourceTree = ""; + }; + 0867D691FE84028FC02AAC07 /* gTestExample */ = { + isa = PBXGroup; + children = ( + 4024D1E1113D836C00C7059E /* Scripts */, + 08FB77ACFE841707C02AAC07 /* Source */, + 089C1665FE841158C02AAC07 /* Resources */, + 3B07BE350E4094E400647869 /* Test */, + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, + 034768DDFF38A45A11DB9C8B /* Products */, + ); + name = gTestExample; + sourceTree = ""; + }; + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 4024D183113D7D5500C7059E /* libgtest_main.a */, + 4024D185113D7D5500C7059E /* libgtest.a */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 089C1665FE841158C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D07F2C70486CC7A007CD1D0 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77ACFE841707C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 3B7EB1230E5AEE3500C7F239 /* widget.cc */, + 3B7EB1240E5AEE3500C7F239 /* widget.h */, + ); + name = Source; + sourceTree = ""; + }; + 3B07BE350E4094E400647869 /* Test */ = { + isa = PBXGroup; + children = ( + 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */, + ); + name = Test; + sourceTree = ""; + }; + 4024D1E1113D836C00C7059E /* Scripts */ = { + isa = PBXGroup; + children = ( + 4024D1E2113D838200C7059E /* runtests.sh */, + ); + name = Scripts; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */; + buildPhases = ( + 3B07BDE70E3F3F9E00647869 /* Sources */, + 3B07BDE80E3F3F9E00647869 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */, + ); + name = WidgetFrameworkTest; + productName = gTestExampleTest; + productReference = 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */; + productType = "com.apple.product-type.tool"; + }; + 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */; + buildPhases = ( + 8D07F2C10486CC7A007CD1D0 /* Sources */, + 8D07F2C30486CC7A007CD1D0 /* Frameworks */, + 8D07F2BD0486CC7A007CD1D0 /* Headers */, + 8D07F2BF0486CC7A007CD1D0 /* Resources */, + 8D07F2C50486CC7A007CD1D0 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = WidgetFramework; + productInstallPath = "$(HOME)/Library/Frameworks"; + productName = gTestExample; + productReference = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + mainGroup = 0867D691FE84028FC02AAC07 /* gTestExample */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */, + 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */, + 4024D162113D7D2400C7059E /* Test */, + 4024D1E9113D83FF00C7059E /* TestAndBuild */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 8D07F2C50486CC7A007CD1D0 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 4024D161113D7D2400C7059E /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/bash $SRCROOT/runtests.sh $BUILT_PRODUCTS_DIR/WidgetFrameworkTest\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3B07BDE70E3F3F9E00647869 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C10486CC7A007CD1D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */; + targetProxy = 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */; + }; + 4024D166113D7D3100C7059E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */; + targetProxy = 4024D165113D7D3100C7059E /* PBXContainerItemProxy */; + }; + 4024D1ED113D840900C7059E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */; + targetProxy = 4024D1EC113D840900C7059E /* PBXContainerItemProxy */; + }; + 4024D1EF113D840D00C7059E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4024D162113D7D2400C7059E /* Test */; + targetProxy = 4024D1EE113D840D00C7059E /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 3B07BDEC0E3F3F9F00647869 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = WidgetFrameworkTest; + }; + name = Debug; + }; + 3B07BDED0E3F3F9F00647869 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = WidgetFrameworkTest; + }; + name = Release; + }; + 4024D163113D7D2400C7059E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Debug; + }; + 4024D164113D7D2400C7059E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Release; + }; + 4024D1EA113D83FF00C7059E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Debug; + }; + 4024D1EB113D83FF00C7059E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Release; + }; + 4FADC24308B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "@loader_path/../Frameworks"; + PRODUCT_NAME = Widget; + }; + name = Debug; + }; + 4FADC24408B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "@loader_path/../Frameworks"; + PRODUCT_NAME = Widget; + }; + name = Release; + }; + 4FADC24708B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = 4.0; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + 4FADC24808B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = 4.0; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3B07BDEC0E3F3F9F00647869 /* Debug */, + 3B07BDED0E3F3F9F00647869 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4024D163113D7D2400C7059E /* Debug */, + 4024D164113D7D2400C7059E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4024D1EA113D83FF00C7059E /* Debug */, + 4024D1EB113D83FF00C7059E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24308B4156D00ABE55E /* Debug */, + 4FADC24408B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24708B4156D00ABE55E /* Debug */, + 4FADC24808B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/runtests.sh b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/runtests.sh new file mode 100644 index 0000000..4a0d413 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/runtests.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +# Executes the samples and tests for the Google Test Framework. + +# Help the dynamic linker find the path to the libraries. +export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR +export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR + +# Create some executables. +test_executables=$@ + +# Now execute each one in turn keeping track of how many succeeded and failed. +succeeded=0 +failed=0 +failed_list=() +for test in ${test_executables[*]}; do + "$test" + result=$? + if [ $result -eq 0 ]; then + succeeded=$(( $succeeded + 1 )) + else + failed=$(( failed + 1 )) + failed_list="$failed_list $test" + fi +done + +# Report the successes and failures to the console. +echo "Tests complete with $succeeded successes and $failed failures." +if [ $failed -ne 0 ]; then + echo "The following tests failed:" + echo $failed_list +fi +exit $failed diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget.cc b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget.cc new file mode 100644 index 0000000..bfc4e7f --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget.cc @@ -0,0 +1,63 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: preston.a.jackson@gmail.com (Preston Jackson) +// +// Google Test - FrameworkSample +// widget.cc +// + +// Widget is a very simple class used for demonstrating the use of gtest + +#include "widget.h" + +Widget::Widget(int number, const std::string& name) + : number_(number), + name_(name) {} + +Widget::~Widget() {} + +float Widget::GetFloatValue() const { + return number_; +} + +int Widget::GetIntValue() const { + return static_cast(number_); +} + +std::string Widget::GetStringValue() const { + return name_; +} + +void Widget::GetCharPtrValue(char* buffer, size_t max_size) const { + // Copy the char* representation of name_ into buffer, up to max_size. + strncpy(buffer, name_.c_str(), max_size-1); + buffer[max_size-1] = '\0'; + return; +} diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget.h b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget.h new file mode 100644 index 0000000..0c55cdc --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget.h @@ -0,0 +1,59 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: preston.a.jackson@gmail.com (Preston Jackson) +// +// Google Test - FrameworkSample +// widget.h +// + +// Widget is a very simple class used for demonstrating the use of gtest. It +// simply stores two values a string and an integer, which are returned via +// public accessors in multiple forms. + +#import + +class Widget { + public: + Widget(int number, const std::string& name); + ~Widget(); + + // Public accessors to number data + float GetFloatValue() const; + int GetIntValue() const; + + // Public accessors to the string data + std::string GetStringValue() const; + void GetCharPtrValue(char* buffer, size_t max_size) const; + + private: + // Data members + float number_; + std::string name_; +}; diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget_test.cc b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget_test.cc new file mode 100644 index 0000000..8725994 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Samples/FrameworkSample/widget_test.cc @@ -0,0 +1,68 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: preston.a.jackson@gmail.com (Preston Jackson) +// +// Google Test - FrameworkSample +// widget_test.cc +// + +// This is a simple test file for the Widget class in the Widget.framework + +#include +#include "gtest/gtest.h" + +#include + +// This test verifies that the constructor sets the internal state of the +// Widget class correctly. +TEST(WidgetInitializerTest, TestConstructor) { + Widget widget(1.0f, "name"); + EXPECT_FLOAT_EQ(1.0f, widget.GetFloatValue()); + EXPECT_EQ(std::string("name"), widget.GetStringValue()); +} + +// This test verifies the conversion of the float and string values to int and +// char*, respectively. +TEST(WidgetInitializerTest, TestConversion) { + Widget widget(1.0f, "name"); + EXPECT_EQ(1, widget.GetIntValue()); + + size_t max_size = 128; + char buffer[max_size]; + widget.GetCharPtrValue(buffer, max_size); + EXPECT_STREQ("name", buffer); +} + +// Use the Google Test main that is linked into the framework. It does something +// like this: +// int main(int argc, char** argv) { +// testing::InitGoogleTest(&argc, argv); +// return RUN_ALL_TESTS(); +// } diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Scripts/runtests.sh b/cpp/thirdparty/gtest-1.7.0/xcode/Scripts/runtests.sh new file mode 100644 index 0000000..3fc229f --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Scripts/runtests.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +# Executes the samples and tests for the Google Test Framework. + +# Help the dynamic linker find the path to the libraries. +export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR +export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR + +# Create some executables. +test_executables=("$BUILT_PRODUCTS_DIR/gtest_unittest-framework" + "$BUILT_PRODUCTS_DIR/gtest_unittest" + "$BUILT_PRODUCTS_DIR/sample1_unittest-framework" + "$BUILT_PRODUCTS_DIR/sample1_unittest-static") + +# Now execute each one in turn keeping track of how many succeeded and failed. +succeeded=0 +failed=0 +failed_list=() +for test in ${test_executables[*]}; do + "$test" + result=$? + if [ $result -eq 0 ]; then + succeeded=$(( $succeeded + 1 )) + else + failed=$(( failed + 1 )) + failed_list="$failed_list $test" + fi +done + +# Report the successes and failures to the console. +echo "Tests complete with $succeeded successes and $failed failures." +if [ $failed -ne 0 ]; then + echo "The following tests failed:" + echo $failed_list +fi +exit $failed diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/Scripts/versiongenerate.py b/cpp/thirdparty/gtest-1.7.0/xcode/Scripts/versiongenerate.py new file mode 100755 index 0000000..81de8c9 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/Scripts/versiongenerate.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""A script to prepare version informtion for use the gtest Info.plist file. + + This script extracts the version information from the configure.ac file and + uses it to generate a header file containing the same information. The + #defines in this header file will be included in during the generation of + the Info.plist of the framework, giving the correct value to the version + shown in the Finder. + + This script makes the following assumptions (these are faults of the script, + not problems with the Autoconf): + 1. The AC_INIT macro will be contained within the first 1024 characters + of configure.ac + 2. The version string will be 3 integers separated by periods and will be + surrounded by squre brackets, "[" and "]" (e.g. [1.0.1]). The first + segment represents the major version, the second represents the minor + version and the third represents the fix version. + 3. No ")" character exists between the opening "(" and closing ")" of + AC_INIT, including in comments and character strings. +""" + +import sys +import re + +# Read the command line argument (the output directory for Version.h) +if (len(sys.argv) < 3): + print "Usage: versiongenerate.py input_dir output_dir" + sys.exit(1) +else: + input_dir = sys.argv[1] + output_dir = sys.argv[2] + +# Read the first 1024 characters of the configure.ac file +config_file = open("%s/configure.ac" % input_dir, 'r') +buffer_size = 1024 +opening_string = config_file.read(buffer_size) +config_file.close() + +# Extract the version string from the AC_INIT macro +# The following init_expression means: +# Extract three integers separated by periods and surrounded by squre +# brackets(e.g. "[1.0.1]") between "AC_INIT(" and ")". Do not be greedy +# (*? is the non-greedy flag) since that would pull in everything between +# the first "(" and the last ")" in the file. +version_expression = re.compile(r"AC_INIT\(.*?\[(\d+)\.(\d+)\.(\d+)\].*?\)", + re.DOTALL) +version_values = version_expression.search(opening_string) +major_version = version_values.group(1) +minor_version = version_values.group(2) +fix_version = version_values.group(3) + +# Write the version information to a header file to be included in the +# Info.plist file. +file_data = """// +// DO NOT MODIFY THIS FILE (but you can delete it) +// +// This file is autogenerated by the versiongenerate.py script. This script +// is executed in a "Run Script" build phase when creating gtest.framework. This +// header file is not used during compilation of C-source. Rather, it simply +// defines some version strings for substitution in the Info.plist. Because of +// this, we are not not restricted to C-syntax nor are we using include guards. +// + +#define GTEST_VERSIONINFO_SHORT %s.%s +#define GTEST_VERSIONINFO_LONG %s.%s.%s + +""" % (major_version, minor_version, major_version, minor_version, fix_version) +version_file = open("%s/Version.h" % output_dir, 'w') +version_file.write(file_data) +version_file.close() diff --git a/cpp/thirdparty/gtest-1.7.0/xcode/gtest.xcodeproj/project.pbxproj b/cpp/thirdparty/gtest-1.7.0/xcode/gtest.xcodeproj/project.pbxproj new file mode 100644 index 0000000..0452a63 --- /dev/null +++ b/cpp/thirdparty/gtest-1.7.0/xcode/gtest.xcodeproj/project.pbxproj @@ -0,0 +1,1135 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXAggregateTarget section */ + 3B238F5F0E828B5400846E11 /* Check */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */; + buildPhases = ( + 3B238F5E0E828B5400846E11 /* ShellScript */, + ); + dependencies = ( + 40899F9D0FFA740F000B29AE /* PBXTargetDependency */, + 40C849F7101A43440083642A /* PBXTargetDependency */, + 4089A0980FFAD34A000B29AE /* PBXTargetDependency */, + 40C849F9101A43490083642A /* PBXTargetDependency */, + ); + name = Check; + productName = Check; + }; + 40C44ADC0E3798F4008FCC51 /* Version Info */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */; + buildPhases = ( + 40C44ADB0E3798F4008FCC51 /* Generate Version.h */, + ); + comments = "The generation of Version.h must be performed in its own target. Since the Info.plist is preprocessed before any of the other build phases in gtest, the Version.h file would not be ready if included as a build phase of that target."; + dependencies = ( + ); + name = "Version Info"; + productName = Version.h; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */ = {isa = PBXBuildFile; fileRef = 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */; }; + 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DB0E2F799B00CF7658 /* gtest-death-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884390E2F799B00CF7658 /* gtest-message.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DC0E2F799B00CF7658 /* gtest-message.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DD0E2F799B00CF7658 /* gtest-spi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843B0E2F799B00CF7658 /* gtest.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DE0E2F799B00CF7658 /* gtest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883E00E2F799B00CF7658 /* gtest_prod.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884500E2F799B00CF7658 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 404883F60E2F799B00CF7658 /* README */; }; + 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */; }; + 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E30E2F799B00CF7658 /* gtest-filepath.h */; }; + 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E40E2F799B00CF7658 /* gtest-internal.h */; }; + 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E50E2F799B00CF7658 /* gtest-port.h */; }; + 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E60E2F799B00CF7658 /* gtest-string.h */; }; + 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */ = {isa = PBXBuildFile; fileRef = 404884A90E2F7CD900CF7658 /* CHANGES */; }; + 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */ = {isa = PBXBuildFile; fileRef = 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */; }; + 404884AE0E2F7CD900CF7658 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 404884AB0E2F7CD900CF7658 /* LICENSE */; }; + 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; + 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 40899F4D0FFA7271000B29AE /* gtest-tuple.h */; }; + 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; + 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; + 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; + 40C848FF101A21150083642A /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; + 40C84915101A21DF0083642A /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4048840D0E2F799B00CF7658 /* gtest_main.cc */; }; + 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84978101A36540083642A /* libgtest_main.a in Resources */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84980101A36850083642A /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; + 40C84982101A36850083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; + 40C84983101A36850083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C8498F101A36A60083642A /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; + 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; + 40C84992101A36A60083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; + 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C849A2101A37050083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; + 40C849A4101A37150083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; + 4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 4539C9330EC280AE00A70F4C /* gtest-param-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */; }; + 4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */; }; + 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9370EC280E200A70F4C /* gtest-param-util.h */; }; + 4567C8181264FF71007740BE /* gtest-printers.h in Headers */ = {isa = PBXBuildFile; fileRef = 4567C8171264FF71007740BE /* gtest-printers.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40899F420FFA7184000B29AE; + remoteInfo = gtest_unittest; + }; + 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4089A0120FFACEFC000B29AE; + remoteInfo = sample1_unittest; + }; + 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C44ADC0E3798F4008FCC51; + remoteInfo = Version.h; + }; + 40C8497C101A36850083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C8497E101A36850083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8498B101A36A60083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C8498D101A36A60083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8499B101A36DC0083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8499D101A36E50083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = "gtest-framework"; + }; + 40C8499F101A36F10083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = "gtest-framework"; + }; + 40C849F6101A43440083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8497A101A36850083642A; + remoteInfo = "gtest_unittest-static"; + }; + 40C849F8101A43490083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C84989101A36A60083642A; + remoteInfo = "sample1_unittest-static"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 404884A50E2F7C0400CF7658 /* Copy Headers Internal */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = Headers/internal; + dstSubfolderSpec = 6; + files = ( + 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */, + 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */, + 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */, + 4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */, + 4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */, + 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */, + 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */, + 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */, + 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */, + 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */, + ); + name = "Copy Headers Internal"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 224A12A10E9EADA700BD17FD /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-all.cc"; sourceTree = ""; }; + 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "gtest-test-part.h"; sourceTree = ""; }; + 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_unittest.cc; sourceTree = ""; }; + 3B87D2100E96B92E000D1852 /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = ""; }; + 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-type-util.h"; sourceTree = ""; }; + 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-typed-test.h"; sourceTree = ""; }; + 403EE37C0E377822004BD1E2 /* versiongenerate.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = versiongenerate.py; sourceTree = ""; }; + 404883DB0E2F799B00CF7658 /* gtest-death-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test.h"; sourceTree = ""; }; + 404883DC0E2F799B00CF7658 /* gtest-message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-message.h"; sourceTree = ""; }; + 404883DD0E2F799B00CF7658 /* gtest-spi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-spi.h"; sourceTree = ""; }; + 404883DE0E2F799B00CF7658 /* gtest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest.h; sourceTree = ""; }; + 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_pred_impl.h; sourceTree = ""; }; + 404883E00E2F799B00CF7658 /* gtest_prod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_prod.h; sourceTree = ""; }; + 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test-internal.h"; sourceTree = ""; }; + 404883E30E2F799B00CF7658 /* gtest-filepath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-filepath.h"; sourceTree = ""; }; + 404883E40E2F799B00CF7658 /* gtest-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-internal.h"; sourceTree = ""; }; + 404883E50E2F799B00CF7658 /* gtest-port.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-port.h"; sourceTree = ""; }; + 404883E60E2F799B00CF7658 /* gtest-string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-string.h"; sourceTree = ""; }; + 404883F60E2F799B00CF7658 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README; path = ../README; sourceTree = SOURCE_ROOT; }; + 4048840D0E2F799B00CF7658 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main.cc; sourceTree = ""; }; + 404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; }; + 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; }; + 404884AB0E2F7CD900CF7658 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = SOURCE_ROOT; }; + 40899F430FFA7184000B29AE /* gtest_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 40899F4D0FFA7271000B29AE /* gtest-tuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-tuple.h"; sourceTree = ""; }; + 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = StaticLibraryTarget.xcconfig; sourceTree = ""; }; + 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4089A02C0FFACF7F000B29AE /* sample1.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1.cc; sourceTree = ""; }; + 4089A02D0FFACF7F000B29AE /* sample1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample1.h; sourceTree = ""; }; + 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1_unittest.cc; sourceTree = ""; }; + 40C848FA101A209C0083642A /* libgtest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C8490B101A217E0083642A /* libgtest_main.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest_main.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C84987101A36850083642A /* gtest_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C84997101A36A60083642A /* sample1_unittest-static */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-static"; sourceTree = BUILT_PRODUCTS_DIR; }; + 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugProject.xcconfig; sourceTree = ""; }; + 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FrameworkTarget.xcconfig; sourceTree = ""; }; + 40D4CDF30E30E07400294801 /* General.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = ""; }; + 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseProject.xcconfig; sourceTree = ""; }; + 40D4CF510E30F5E200294801 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4539C8FF0EC27F6400A70F4C /* gtest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = gtest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4539C9330EC280AE00A70F4C /* gtest-param-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-test.h"; sourceTree = ""; }; + 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-linked_ptr.h"; sourceTree = ""; }; + 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util-generated.h"; sourceTree = ""; }; + 4539C9370EC280E200A70F4C /* gtest-param-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util.h"; sourceTree = ""; }; + 4567C8171264FF71007740BE /* gtest-printers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-printers.h"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 40899F410FFA7184000B29AE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C849A4101A37150083642A /* gtest.framework in Frameworks */, + 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4089A0110FFACEFC000B29AE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C849A2101A37050083642A /* gtest.framework in Frameworks */, + 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84981101A36850083642A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84982101A36850083642A /* libgtest.a in Frameworks */, + 40C84983101A36850083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84991101A36A60083642A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84992101A36A60083642A /* libgtest.a in Frameworks */, + 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 4539C8FF0EC27F6400A70F4C /* gtest.framework */, + 40C848FA101A209C0083642A /* libgtest.a */, + 40C8490B101A217E0083642A /* libgtest_main.a */, + 40899F430FFA7184000B29AE /* gtest_unittest-framework */, + 40C84987101A36850083642A /* gtest_unittest */, + 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */, + 40C84997101A36A60083642A /* sample1_unittest-static */, + ); + name = Products; + sourceTree = ""; + }; + 0867D691FE84028FC02AAC07 /* gtest */ = { + isa = PBXGroup; + children = ( + 40D4CDF00E30E07400294801 /* Config */, + 08FB77ACFE841707C02AAC07 /* Source */, + 40D4CF4E0E30F5E200294801 /* Resources */, + 403EE37B0E377822004BD1E2 /* Scripts */, + 034768DDFF38A45A11DB9C8B /* Products */, + ); + name = gtest; + sourceTree = ""; + }; + 08FB77ACFE841707C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 404884A90E2F7CD900CF7658 /* CHANGES */, + 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */, + 404884AB0E2F7CD900CF7658 /* LICENSE */, + 404883F60E2F799B00CF7658 /* README */, + 404883D90E2F799B00CF7658 /* include */, + 4089A02F0FFACF84000B29AE /* samples */, + 404884070E2F799B00CF7658 /* src */, + 3B238BF00E7FE13B00846E11 /* test */, + ); + name = Source; + sourceTree = ""; + }; + 3B238BF00E7FE13B00846E11 /* test */ = { + isa = PBXGroup; + children = ( + 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */, + ); + name = test; + path = ../test; + sourceTree = SOURCE_ROOT; + }; + 403EE37B0E377822004BD1E2 /* Scripts */ = { + isa = PBXGroup; + children = ( + 403EE37C0E377822004BD1E2 /* versiongenerate.py */, + 3B87D2100E96B92E000D1852 /* runtests.sh */, + ); + path = Scripts; + sourceTree = ""; + }; + 404883D90E2F799B00CF7658 /* include */ = { + isa = PBXGroup; + children = ( + 404883DA0E2F799B00CF7658 /* gtest */, + ); + name = include; + path = ../include; + sourceTree = SOURCE_ROOT; + }; + 404883DA0E2F799B00CF7658 /* gtest */ = { + isa = PBXGroup; + children = ( + 404883E10E2F799B00CF7658 /* internal */, + 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */, + 404883DB0E2F799B00CF7658 /* gtest-death-test.h */, + 404883DC0E2F799B00CF7658 /* gtest-message.h */, + 4539C9330EC280AE00A70F4C /* gtest-param-test.h */, + 4567C8171264FF71007740BE /* gtest-printers.h */, + 404883DD0E2F799B00CF7658 /* gtest-spi.h */, + 404883DE0E2F799B00CF7658 /* gtest.h */, + 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */, + 404883E00E2F799B00CF7658 /* gtest_prod.h */, + 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */, + ); + path = gtest; + sourceTree = ""; + }; + 404883E10E2F799B00CF7658 /* internal */ = { + isa = PBXGroup; + children = ( + 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */, + 404883E30E2F799B00CF7658 /* gtest-filepath.h */, + 404883E40E2F799B00CF7658 /* gtest-internal.h */, + 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */, + 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */, + 4539C9370EC280E200A70F4C /* gtest-param-util.h */, + 404883E50E2F799B00CF7658 /* gtest-port.h */, + 404883E60E2F799B00CF7658 /* gtest-string.h */, + 40899F4D0FFA7271000B29AE /* gtest-tuple.h */, + 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */, + ); + path = internal; + sourceTree = ""; + }; + 404884070E2F799B00CF7658 /* src */ = { + isa = PBXGroup; + children = ( + 224A12A10E9EADA700BD17FD /* gtest-all.cc */, + 4048840D0E2F799B00CF7658 /* gtest_main.cc */, + ); + name = src; + path = ../src; + sourceTree = SOURCE_ROOT; + }; + 4089A02F0FFACF84000B29AE /* samples */ = { + isa = PBXGroup; + children = ( + 4089A02C0FFACF7F000B29AE /* sample1.cc */, + 4089A02D0FFACF7F000B29AE /* sample1.h */, + 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */, + ); + name = samples; + path = ../samples; + sourceTree = SOURCE_ROOT; + }; + 40D4CDF00E30E07400294801 /* Config */ = { + isa = PBXGroup; + children = ( + 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */, + 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */, + 40D4CDF30E30E07400294801 /* General.xcconfig */, + 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */, + 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */, + ); + path = Config; + sourceTree = ""; + }; + 40D4CF4E0E30F5E200294801 /* Resources */ = { + isa = PBXGroup; + children = ( + 40D4CF510E30F5E200294801 /* Info.plist */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */, + 404884390E2F799B00CF7658 /* gtest-message.h in Headers */, + 4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */, + 4567C8181264FF71007740BE /* gtest-printers.h in Headers */, + 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */, + 4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */, + 4048843B0E2F799B00CF7658 /* gtest.h in Headers */, + 4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */, + 4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */, + 224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 40899F420FFA7184000B29AE /* gtest_unittest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */; + buildPhases = ( + 40899F400FFA7184000B29AE /* Sources */, + 40899F410FFA7184000B29AE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C849A0101A36F10083642A /* PBXTargetDependency */, + ); + name = "gtest_unittest-framework"; + productName = gtest_unittest; + productReference = 40899F430FFA7184000B29AE /* gtest_unittest-framework */; + productType = "com.apple.product-type.tool"; + }; + 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */; + buildPhases = ( + 4089A0100FFACEFC000B29AE /* Sources */, + 4089A0110FFACEFC000B29AE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8499E101A36E50083642A /* PBXTargetDependency */, + ); + name = "sample1_unittest-framework"; + productName = sample1_unittest; + productReference = 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */; + productType = "com.apple.product-type.tool"; + }; + 40C848F9101A209C0083642A /* gtest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */; + buildPhases = ( + 40C848F7101A209C0083642A /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "gtest-static"; + productName = "gtest-static"; + productReference = 40C848FA101A209C0083642A /* libgtest.a */; + productType = "com.apple.product-type.library.static"; + }; + 40C8490A101A217E0083642A /* gtest_main-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */; + buildPhases = ( + 40C84908101A217E0083642A /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "gtest_main-static"; + productName = "gtest_main-static"; + productReference = 40C8490B101A217E0083642A /* libgtest_main.a */; + productType = "com.apple.product-type.library.static"; + }; + 40C8497A101A36850083642A /* gtest_unittest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */; + buildPhases = ( + 40C8497F101A36850083642A /* Sources */, + 40C84981101A36850083642A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8497B101A36850083642A /* PBXTargetDependency */, + 40C8497D101A36850083642A /* PBXTargetDependency */, + ); + name = "gtest_unittest-static"; + productName = gtest_unittest; + productReference = 40C84987101A36850083642A /* gtest_unittest */; + productType = "com.apple.product-type.tool"; + }; + 40C84989101A36A60083642A /* sample1_unittest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */; + buildPhases = ( + 40C8498E101A36A60083642A /* Sources */, + 40C84991101A36A60083642A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8498A101A36A60083642A /* PBXTargetDependency */, + 40C8498C101A36A60083642A /* PBXTargetDependency */, + ); + name = "sample1_unittest-static"; + productName = sample1_unittest; + productReference = 40C84997101A36A60083642A /* sample1_unittest-static */; + productType = "com.apple.product-type.tool"; + }; + 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */; + buildPhases = ( + 8D07F2C10486CC7A007CD1D0 /* Sources */, + 8D07F2BD0486CC7A007CD1D0 /* Headers */, + 404884A50E2F7C0400CF7658 /* Copy Headers Internal */, + 8D07F2BF0486CC7A007CD1D0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 40C44AE60E379922008FCC51 /* PBXTargetDependency */, + 408BEC101046CFE900DEF522 /* PBXTargetDependency */, + 40C8499C101A36DC0083642A /* PBXTargetDependency */, + ); + name = "gtest-framework"; + productInstallPath = "$(HOME)/Library/Frameworks"; + productName = gtest; + productReference = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0460; + }; + buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 0867D691FE84028FC02AAC07 /* gtest */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */, + 40C848F9101A209C0083642A /* gtest-static */, + 40C8490A101A217E0083642A /* gtest_main-static */, + 40899F420FFA7184000B29AE /* gtest_unittest-framework */, + 40C8497A101A36850083642A /* gtest_unittest-static */, + 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */, + 40C84989101A36A60083642A /* sample1_unittest-static */, + 3B238F5F0E828B5400846E11 /* Check */, + 40C44ADC0E3798F4008FCC51 /* Version Info */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 404884500E2F799B00CF7658 /* README in Resources */, + 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */, + 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */, + 404884AE0E2F7CD900CF7658 /* LICENSE in Resources */, + 40C84978101A36540083642A /* libgtest_main.a in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B238F5E0E828B5400846E11 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/bin/bash Scripts/runtests.sh"; + }; + 40C44ADB0E3798F4008FCC51 /* Generate Version.h */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/Scripts/versiongenerate.py", + "$(SRCROOT)/../configure.ac", + ); + name = "Generate Version.h"; + outputPaths = ( + "$(PROJECT_TEMP_DIR)/Version.h", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/usr/bin/python Scripts/versiongenerate.py ../ $PROJECT_TEMP_DIR"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 40899F400FFA7184000B29AE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4089A0100FFACEFC000B29AE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */, + 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C848F7101A209C0083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C848FF101A21150083642A /* gtest-all.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84908101A217E0083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84915101A21DF0083642A /* gtest_main.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C8497F101A36850083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84980101A36850083642A /* gtest_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C8498E101A36A60083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C8498F101A36A60083642A /* sample1.cc in Sources */, + 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C10486CC7A007CD1D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 40899F9D0FFA740F000B29AE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40899F420FFA7184000B29AE /* gtest_unittest-framework */; + targetProxy = 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */; + }; + 4089A0980FFAD34A000B29AE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */; + targetProxy = 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */; + }; + 408BEC101046CFE900DEF522 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */; + }; + 40C44AE60E379922008FCC51 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C44ADC0E3798F4008FCC51 /* Version Info */; + targetProxy = 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */; + }; + 40C8497B101A36850083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 40C8497C101A36850083642A /* PBXContainerItemProxy */; + }; + 40C8497D101A36850083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8497E101A36850083642A /* PBXContainerItemProxy */; + }; + 40C8498A101A36A60083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 40C8498B101A36A60083642A /* PBXContainerItemProxy */; + }; + 40C8498C101A36A60083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8498D101A36A60083642A /* PBXContainerItemProxy */; + }; + 40C8499C101A36DC0083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8499B101A36DC0083642A /* PBXContainerItemProxy */; + }; + 40C8499E101A36E50083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; + targetProxy = 40C8499D101A36E50083642A /* PBXContainerItemProxy */; + }; + 40C849A0101A36F10083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; + targetProxy = 40C8499F101A36F10083642A /* PBXContainerItemProxy */; + }; + 40C849F7101A43440083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8497A101A36850083642A /* gtest_unittest-static */; + targetProxy = 40C849F6101A43440083642A /* PBXContainerItemProxy */; + }; + 40C849F9101A43490083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C84989101A36A60083642A /* sample1_unittest-static */; + targetProxy = 40C849F8101A43490083642A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 3B238F600E828B5400846E11 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = Check; + SDKROOT = macosx; + }; + name = Debug; + }; + 3B238F610E828B5400846E11 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = Check; + SDKROOT = macosx; + ZERO_LINK = NO; + }; + name = Release; + }; + 40899F450FFA7185000B29AE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = "gtest_unittest-framework"; + SDKROOT = macosx; + }; + name = Debug; + }; + 40899F460FFA7185000B29AE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = "gtest_unittest-framework"; + SDKROOT = macosx; + }; + name = Release; + }; + 4089A0150FFACEFD000B29AE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = "sample1_unittest-framework"; + SDKROOT = macosx; + }; + name = Debug; + }; + 4089A0160FFACEFD000B29AE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = "sample1_unittest-framework"; + SDKROOT = macosx; + }; + name = Release; + }; + 40C44ADF0E3798F4008FCC51 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + MACOSX_DEPLOYMENT_TARGET = 10.7; + PRODUCT_NAME = gtest; + SDKROOT = macosx; + TARGET_NAME = gtest; + }; + name = Debug; + }; + 40C44AE00E3798F4008FCC51 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + MACOSX_DEPLOYMENT_TARGET = 10.7; + PRODUCT_NAME = gtest; + SDKROOT = macosx; + TARGET_NAME = gtest; + }; + name = Release; + }; + 40C848FB101A209D0083642A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest; + SDKROOT = macosx; + }; + name = Debug; + }; + 40C848FC101A209D0083642A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest; + SDKROOT = macosx; + }; + name = Release; + }; + 40C8490E101A217F0083642A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest_main; + SDKROOT = macosx; + }; + name = Debug; + }; + 40C8490F101A217F0083642A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest_main; + SDKROOT = macosx; + }; + name = Release; + }; + 40C84985101A36850083642A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = gtest_unittest; + SDKROOT = macosx; + }; + name = Debug; + }; + 40C84986101A36850083642A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = gtest_unittest; + SDKROOT = macosx; + }; + name = Release; + }; + 40C84995101A36A60083642A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = "sample1_unittest-static"; + SDKROOT = macosx; + }; + name = Debug; + }; + 40C84996101A36A60083642A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = "sample1_unittest-static"; + SDKROOT = macosx; + }; + name = Release; + }; + 4FADC24308B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + INFOPLIST_FILE = Resources/Info.plist; + INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; + INFOPLIST_PREPROCESS = YES; + PRODUCT_NAME = gtest; + SDKROOT = macosx; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 4FADC24408B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + INFOPLIST_FILE = Resources/Info.plist; + INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; + INFOPLIST_PREPROCESS = YES; + PRODUCT_NAME = gtest; + SDKROOT = macosx; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + 4FADC24708B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 4FADC24808B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */; + buildSettings = { + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3B238F600E828B5400846E11 /* Debug */, + 3B238F610E828B5400846E11 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40899F450FFA7185000B29AE /* Debug */, + 40899F460FFA7185000B29AE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4089A0150FFACEFD000B29AE /* Debug */, + 4089A0160FFACEFD000B29AE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C44ADF0E3798F4008FCC51 /* Debug */, + 40C44AE00E3798F4008FCC51 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C848FB101A209D0083642A /* Debug */, + 40C848FC101A209D0083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C8490E101A217F0083642A /* Debug */, + 40C8490F101A217F0083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C84985101A36850083642A /* Debug */, + 40C84986101A36850083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C84995101A36A60083642A /* Debug */, + 40C84996101A36A60083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24308B4156D00ABE55E /* Debug */, + 4FADC24408B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24708B4156D00ABE55E /* Debug */, + 4FADC24808B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/CHANGES.txt b/cpp/thirdparty/protobuf-2.5.0/CHANGES.txt new file mode 100644 index 0000000..6ffb8c7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/CHANGES.txt @@ -0,0 +1,528 @@ +2013-02-27 version 2.5.0: + + General + * New notion "import public" that allows a proto file to forward the content + it imports to its importers. For example, + // foo.proto + import public "bar.proto"; + import "baz.proto"; + + // qux.proto + import "foo.proto"; + // Stuff defined in bar.proto may be used in this file, but stuff from + // baz.proto may NOT be used without importing it explicitly. + This is useful for moving proto files. To move a proto file, just leave + a single "import public" in the old proto file. + * New enum option "allow_alias" that specifies whether different symbols can + be assigned the same numeric value. Default value is "true". Setting it to + false causes the compiler to reject enum definitions where multiple symbols + have the same numeric value. + + C++ + * New generated method set_allocated_foo(Type* foo) for message and string + fields. This method allows you to set the field to a pre-allocated object + and the containing message takes the ownership of that object. + * Added SetAllocatedExtension() and ReleaseExtension() to extensions API. + * Custom options are now formatted correctly when descriptors are printed in + text format. + * Various speed optimizations. + + Java + * Comments in proto files are now collected and put into generated code as + comments for corresponding classes and data members. + * Added Parser to parse directly into messages without a Builder. For + example, + Foo foo = Foo.getParser().ParseFrom(input); + Using Parser is ~25% faster than using Builder to parse messages. + * Added getters/setters to access the underlying ByteString of a string field + directly. + * ByteString now supports more operations: substring(), prepend(), and + append(). The implementation of ByteString uses a binary tree structure + to support these operations efficiently. + * New method findInitializationErrors() that lists all missing required + fields. + * Various code size and speed optimizations. + + Python + * Added support for dynamic message creation. DescriptorDatabase, + DescriptorPool, and MessageFactory work like their C++ couterparts to + simplify Descriptor construction from *DescriptorProtos, and MessageFactory + provides a message instance from a Descriptor. + * Added pickle support for protobuf messages. + * Unknown fields are now preserved after parsing. + * Fixed bug where custom options were not correctly populated. Custom + options can be accessed now. + * Added EnumTypeWrapper that provides better accessibility to enum types. + * Added ParseMessage(descriptor, bytes) to generate a new Message instance + from a descriptor and a byte string. + +2011-05-01 version 2.4.1: + + C++ + * Fixed the frendship problem for old compilers to make the library now gcc 3 + compatible again. + * Fixed vcprojects/extract_includes.bat to extract compiler/plugin.h. + + Java + * Removed usages of JDK 1.6 only features to make the library now JDK 1.5 + compatible again. + * Fixed a bug about negative enum values. + * serialVersionUID is now defined in generated messages for java serializing. + * Fixed protoc to use java.lang.Object, which makes "Object" now a valid + message name again. + + Python + * Experimental C++ implementation now requires C++ protobuf library installed. + See the README.txt in the python directory for details. + +2011-02-02 version 2.4.0: + + General + * The RPC (cc|java|py)_generic_services default value is now false instead of + true. + * Custom options can have aggregate types. For example, + message MyOption { + optional string comment = 1; + optional string author = 2; + } + extend google.protobuf.FieldOptions { + optional MyOption myoption = 12345; + } + This option can now be set as follows: + message SomeType { + optional int32 field = 1 [(myoption) = { comment:'x' author:'y' }]; + } + + C++ + * Various speed and code size optimizations. + * Added a release_foo() method on string and message fields. + * Fixed gzip_output_stream sub-stream handling. + + Java + * Builders now maintain sub-builders for sub-messages. Use getFooBuilder() to + get the builder for the sub-message "foo". This allows you to repeatedly + modify deeply-nested sub-messages without rebuilding them. + * Builder.build() no longer invalidates the Builder for generated messages + (You may continue to modify it and then build another message). + * Code generator will generate efficient equals() and hashCode() + implementations if new option java_generate_equals_and_hash is enabled. + (Otherwise, reflection-based implementations are used.) + * Generated messages now implement Serializable. + * Fields with [deprecated=true] will be marked with @Deprecated in Java. + * Added lazy conversion of UTF-8 encoded strings to String objects to improve + performance. + * Various optimizations. + * Enum value can be accessed directly, instead of calling getNumber() on the + enum member. + * For each enum value, an integer constant is also generated with the suffix + _VALUE. + + Python + * Added an experimental C++ implementation for Python messages via a Python + extension. Implementation type is controlled by an environment variable + PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION (valid values: "cpp" and "python") + The default value is currently "python" but will be changed to "cpp" in + future release. + * Improved performance on message instantiation significantly. + Most of the work on message instantiation is done just once per message + class, instead of once per message instance. + * Improved performance on text message parsing. + * Allow add() to forward keyword arguments to the concrete class. + E.g. instead of + item = repeated_field.add() + item.foo = bar + item.baz = quux + You can do: + repeated_field.add(foo=bar, baz=quux) + * Added a sort() interface to the BaseContainer. + * Added an extend() method to repeated composite fields. + * Added UTF8 debug string support. + +2010-01-08 version 2.3.0: + + General + * Parsers for repeated numeric fields now always accept both packed and + unpacked input. The [packed=true] option only affects serializers. + Therefore, it is possible to switch a field to packed format without + breaking backwards-compatibility -- as long as all parties are using + protobuf 2.3.0 or above, at least. + * The generic RPC service code generated by the C++, Java, and Python + generators can be disabled via file options: + option cc_generic_services = false; + option java_generic_services = false; + option py_generic_services = false; + This allows plugins to generate alternative code, possibly specific to some + particular RPC implementation. + + protoc + * Now supports a plugin system for code generators. Plugins can generate + code for new languages or inject additional code into the output of other + code generators. Plugins are just binaries which accept a protocol buffer + on stdin and write a protocol buffer to stdout, so they may be written in + any language. See src/google/protobuf/compiler/plugin.proto. + **WARNING**: Plugins are experimental. The interface may change in a + future version. + * If the output location ends in .zip or .jar, protoc will write its output + to a zip/jar archive instead of a directory. For example: + protoc --java_out=myproto_srcs.jar --python_out=myproto.zip myproto.proto + Currently the archive contents are not compressed, though this could change + in the future. + * inf, -inf, and nan can now be used as default values for float and double + fields. + + C++ + * Various speed and code size optimizations. + * DynamicMessageFactory is now fully thread-safe. + * Message::Utf8DebugString() method is like DebugString() but avoids escaping + UTF-8 bytes. + * Compiled-in message types can now contain dynamic extensions, through use + of CodedInputStream::SetExtensionRegistry(). + * Now compiles shared libraries (DLLs) by default on Cygwin and MinGW, to + match other platforms. Use --disable-shared to avoid this. + + Java + * parseDelimitedFrom() and mergeDelimitedFrom() now detect EOF and return + false/null instead of throwing an exception. + * Fixed some initialization ordering bugs. + * Fixes for OpenJDK 7. + + Python + * 10-25 times faster than 2.2.0, still pure-Python. + * Calling a mutating method on a sub-message always instantiates the message + in its parent even if the mutating method doesn't actually mutate anything + (e.g. parsing from an empty string). + * Expanded descriptors a bit. + +2009-08-11 version 2.2.0: + + C++ + * Lite mode: The "optimize_for = LITE_RUNTIME" option causes the compiler + to generate code which only depends libprotobuf-lite, which is much smaller + than libprotobuf but lacks descriptors, reflection, and some other features. + * Fixed bug where Message.Swap(Message) was only implemented for + optimize_for_speed. Swap now properly implemented in both modes + (Issue 91). + * Added RemoveLast and SwapElements(index1, index2) to Reflection + interface for repeated elements. + * Added Swap(Message) to Reflection interface. + * Floating-point literals in generated code that are intended to be + single-precision now explicitly have 'f' suffix to avoid pedantic warnings + produced by some compilers. + * The [deprecated=true] option now causes the C++ code generator to generate + a GCC-style deprecation annotation (no-op on other compilers). + * google::protobuf::GetEnumDescriptor() returns the + EnumDescriptor for that type -- useful for templates which cannot call + SomeGeneratedEnumType_descriptor(). + * Various optimizations and obscure bug fixes. + + Java + * Lite mode: The "optimize_for = LITE_RUNTIME" option causes the compiler + to generate code which only depends libprotobuf-lite, which is much smaller + than libprotobuf but lacks descriptors, reflection, and some other features. + * Lots of style cleanups. + + Python + * Fixed endianness bug with floats and doubles. + * Text format parsing support. + * Fix bug with parsing packed repeated fields in embedded messages. + * Ability to initialize fields by passing keyword args to constructor. + * Support iterators in extend and __setslice__ for containers. + +2009-05-13 version 2.1.0: + + General + * Repeated fields of primitive types (types other that string, group, and + nested messages) may now use the option [packed = true] to get a more + efficient encoding. In the new encoding, the entire list is written + as a single byte blob using the "length-delimited" wire type. Within + this blob, the individual values are encoded the same way they would + be normally except without a tag before each value (thus, they are + tightly "packed"). + * For each field, the generated code contains an integer constant assigned + to the field number. For example, the .proto file: + message Foo { optional int bar_baz = 123; } + would generate the following constants, all with the integer value 123: + C++: Foo::kBarBazFieldNumber + Java: Foo.BAR_BAZ_FIELD_NUMBER + Python: Foo.BAR_BAZ_FIELD_NUMBER + Constants are also generated for extensions, with the same naming scheme. + These constants may be used as switch cases. + * Updated bundled Google Test to version 1.3.0. Google Test is now bundled + in its verbatim form as a nested autoconf package, so you can drop in any + other version of Google Test if needed. + * optimize_for = SPEED is now the default, by popular demand. Use + optimize_for = CODE_SIZE if code size is more important in your app. + * It is now an error to define a default value for a repeated field. + Previously, this was silently ignored (it had no effect on the generated + code). + * Fields can now be marked deprecated like: + optional int32 foo = 1 [deprecated = true]; + Currently this does not have any actual effect, but in the future the code + generators may generate deprecation annotations in each language. + * Cross-compiling should now be possible using the --with-protoc option to + configure. See README.txt for more info. + + protoc + * --error_format=msvs option causes errors to be printed in Visual Studio + format, which should allow them to be clicked on in the build log to go + directly to the error location. + * The type name resolver will no longer resolve type names to fields. For + example, this now works: + message Foo {} + message Bar { + optional int32 Foo = 1; + optional Foo baz = 2; + } + Previously, the type of "baz" would resolve to "Bar.Foo", and you'd get + an error because Bar.Foo is a field, not a type. Now the type of "baz" + resolves to the message type Foo. This change is unlikely to make a + difference to anyone who follows the Protocol Buffers style guide. + + C++ + * Several optimizations, including but not limited to: + - Serialization, especially to flat arrays, is 10%-50% faster, possibly + more for small objects. + - Several descriptor operations which previously required locking no longer + do. + - Descriptors are now constructed lazily on first use, rather than at + process startup time. This should save memory in programs which do not + use descriptors or reflection. + - UnknownFieldSet completely redesigned to be more efficient (especially in + terms of memory usage). + - Various optimizations to reduce code size (though the serialization speed + optimizations increased code size). + * Message interface has method ParseFromBoundedZeroCopyStream() which parses + a limited number of bytes from an input stream rather than parsing until + EOF. + * GzipInputStream and GzipOutputStream support reading/writing gzip- or + zlib-compressed streams if zlib is available. + (google/protobuf/io/gzip_stream.h) + * DescriptorPool::FindAllExtensions() and corresponding + DescriptorDatabase::FindAllExtensions() can be used to enumerate all + extensions of a given type. + * For each enum type Foo, protoc will generate functions: + const string& Foo_Name(Foo value); + bool Foo_Parse(const string& name, Foo* result); + The former returns the name of the enum constant corresponding to the given + value while the latter finds the value corresponding to a name. + * RepeatedField and RepeatedPtrField now have back-insertion iterators. + * String fields now have setters that take a char* and a size, in addition + to the existing ones that took char* or const string&. + * DescriptorPool::AllowUnknownDependencies() may be used to tell + DescriptorPool to create placeholder descriptors for unknown entities + referenced in a FileDescriptorProto. This can allow you to parse a .proto + file without having access to other .proto files that it imports, for + example. + * Updated gtest to latest version. The gtest package is now included as a + nested autoconf package, so it should be able to drop new versions into the + "gtest" subdirectory without modification. + + Java + * Fixed bug where Message.mergeFrom(Message) failed to merge extensions. + * Message interface has new method toBuilder() which is equivalent to + newBuilderForType().mergeFrom(this). + * All enums now implement the ProtocolMessageEnum interface. + * Setting a field to null now throws NullPointerException. + * Fixed tendency for TextFormat's parsing to overflow the stack when + parsing large string values. The underlying problem is with Java's + regex implementation (which unfortunately uses recursive backtracking + rather than building an NFA). Worked around by making use of possesive + quantifiers. + * Generated service classes now also generate pure interfaces. For a service + Foo, Foo.Interface is a pure interface containing all of the service's + defined methods. Foo.newReflectiveService() can be called to wrap an + instance of this interface in a class that implements the generic + RpcService interface, which provides reflection support that is usually + needed by RPC server implementations. + * RPC interfaces now support blocking operation in addition to non-blocking. + The protocol compiler generates separate blocking and non-blocking stubs + which operate against separate blocking and non-blocking RPC interfaces. + RPC implementations will have to implement the new interfaces in order to + support blocking mode. + * New I/O methods parseDelimitedFrom(), mergeDelimitedFrom(), and + writeDelimitedTo() read and write "delemited" messages from/to a stream, + meaning that the message size precedes the data. This way, you can write + multiple messages to a stream without having to worry about delimiting + them yourself. + * Throw a more descriptive exception when build() is double-called. + * Add a method to query whether CodedInputStream is at the end of the input + stream. + * Add a method to reset a CodedInputStream's size counter; useful when + reading many messages with the same stream. + * equals() and hashCode() now account for unknown fields. + + Python + * Added slicing support for repeated scalar fields. Added slice retrieval and + removal of repeated composite fields. + * Updated RPC interfaces to allow for blocking operation. A client may + now pass None for a callback when making an RPC, in which case the + call will block until the response is received, and the response + object will be returned directly to the caller. This interface change + cannot be used in practice until RPC implementations are updated to + implement it. + * Changes to input_stream.py should make protobuf compatible with appengine. + +2008-11-25 version 2.0.3: + + protoc + * Enum values may now have custom options, using syntax similar to field + options. + * Fixed bug where .proto files which use custom options but don't actually + define them (i.e. they import another .proto file defining the options) + had to explicitly import descriptor.proto. + * Adjacent string literals in .proto files will now be concatenated, like in + C. + * If an input file is a Windows absolute path (e.g. "C:\foo\bar.proto") and + the import path only contains "." (or contains "." but does not contain + the file), protoc incorrectly thought that the file was under ".", because + it thought that the path was relative (since it didn't start with a slash). + This has been fixed. + + C++ + * Generated message classes now have a Swap() method which efficiently swaps + the contents of two objects. + * All message classes now have a SpaceUsed() method which returns an estimate + of the number of bytes of allocated memory currently owned by the object. + This is particularly useful when you are reusing a single message object + to improve performance but want to make sure it doesn't bloat up too large. + * New method Message::SerializeAsString() returns a string containing the + serialized data. May be more convenient than calling + SerializeToString(string*). + * In debug mode, log error messages when string-type fields are found to + contain bytes that are not valid UTF-8. + * Fixed bug where a message with multiple extension ranges couldn't parse + extensions. + * Fixed bug where MergeFrom(const Message&) didn't do anything if invoked on + a message that contained no fields (but possibly contained extensions). + * Fixed ShortDebugString() to not be O(n^2). Durr. + * Fixed crash in TextFormat parsing if the first token in the input caused a + tokenization error. + * Fixed obscure bugs in zero_copy_stream_impl.cc. + * Added support for HP C++ on Tru64. + * Only build tests on "make check", not "make". + * Fixed alignment issue that caused crashes when using DynamicMessage on + 64-bit Sparc machines. + * Simplify template usage to work with MSVC 2003. + * Work around GCC 4.3.x x86_64 compiler bug that caused crashes on startup. + (This affected Fedora 9 in particular.) + * Now works on "Solaris 10 using recent Sun Studio". + + Java + * New overload of mergeFrom() which parses a slice of a byte array instead + of the whole thing. + * New method ByteString.asReadOnlyByteBuffer() does what it sounds like. + * Improved performance of isInitialized() when optimizing for code size. + + Python + * Corrected ListFields() signature in Message base class to match what + subclasses actually implement. + * Some minor refactoring. + * Don't pass self as first argument to superclass constructor (no longer + allowed in Python 2.6). + +2008-09-29 version 2.0.2: + + General + * License changed from Apache 2.0 to New BSD. + * It is now possible to define custom "options", which are basically + annotations which may be placed on definitions in a .proto file. + For example, you might define a field option called "foo" like so: + import "google/protobuf/descriptor.proto" + extend google.protobuf.FieldOptions { + optional string foo = 12345; + } + Then you annotate a field using the "foo" option: + message MyMessage { + optional int32 some_field = 1 [(foo) = "bar"] + } + The value of this option is then visible via the message's + Descriptor: + const FieldDescriptor* field = + MyMessage::descriptor()->FindFieldByName("some_field"); + assert(field->options().GetExtension(foo) == "bar"); + This feature has been implemented and tested in C++ and Java. + Other languages may or may not need to do extra work to support + custom options, depending on how they construct descriptors. + + C++ + * Fixed some GCC warnings that only occur when using -pedantic. + * Improved static initialization code, making ordering more + predictable among other things. + * TextFormat will no longer accept messages which contain multiple + instances of a singular field. Previously, the latter instance + would overwrite the former. + * Now works on systems that don't have hash_map. + + Java + * Print @Override annotation in generated code where appropriate. + + Python + * Strings now use the "unicode" type rather than the "str" type. + String fields may still be assigned ASCII "str" values; they will + automatically be converted. + * Adding a property to an object representing a repeated field now + raises an exception. For example: + # No longer works (and never should have). + message.some_repeated_field.foo = 1 + + Windows + * We now build static libraries rather than DLLs by default on MSVC. + See vsprojects/readme.txt for more information. + +2008-08-15 version 2.0.1: + + protoc + * New flags --encode and --decode can be used to convert between protobuf text + format and binary format from the command-line. + * New flag --descriptor_set_out can be used to write FileDescriptorProtos for + all parsed files directly into a single output file. This is particularly + useful if you wish to parse .proto files from programs written in languages + other than C++: just run protoc as a background process and have it output + a FileDescriptorList, then parse that natively. + * Improved error message when an enum value's name conflicts with another + symbol defined in the enum type's scope, e.g. if two enum types declared + in the same scope have values with the same name. This is disallowed for + compatibility with C++, but this wasn't clear from the error. + * Fixed absolute output paths on Windows. + * Allow trailing slashes in --proto_path mappings. + + C++ + * Reflection objects are now per-class rather than per-instance. To make this + possible, the Reflection interface had to be changed such that all methods + take the Message instance as a parameter. This change improves performance + significantly in memory-bandwidth-limited use cases, since it makes the + message objects smaller. Note that source-incompatible interface changes + like this will not be made again after the library leaves beta. + * Heuristically detect sub-messages when printing unknown fields. + * Fix static initialization ordering bug that caused crashes at startup when + compiling on Mac with static linking. + * Fixed TokenizerTest when compiling with -DNDEBUG on Linux. + * Fixed incorrect definition of kint32min. + * Fix bytes type setter to work with byte sequences with embedded NULLs. + * Other irrelevant tweaks. + + Java + * Fixed UnknownFieldSet's parsing of varints larger than 32 bits. + * Fixed TextFormat's parsing of "inf" and "nan". + * Fixed TextFormat's parsing of comments. + * Added info to Java POM that will be required when we upload the + package to a Maven repo. + + Python + * MergeFrom(message) and CopyFrom(message) are now implemented. + * SerializeToString() raises an exception if the message is missing required + fields. + * Code organization improvements. + * Fixed doc comments for RpcController and RpcChannel, which had somehow been + swapped. + * Fixed text_format_test on Windows where floating-point exponents sometimes + contain extra zeros. + * Fix Python service CallMethod() implementation. + + Other + * Improved readmes. + * VIM syntax highlighting improvements. + +2008-07-07 version 2.0.0: + + * First public release. diff --git a/cpp/thirdparty/protobuf-2.5.0/CONTRIBUTORS.txt b/cpp/thirdparty/protobuf-2.5.0/CONTRIBUTORS.txt new file mode 100644 index 0000000..b39ec30 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/CONTRIBUTORS.txt @@ -0,0 +1,90 @@ +This file contains a list of people who have made large contributions +to the public version of Protocol Buffers. + +Original Protocol Buffers design and implementation: + Sanjay Ghemawat + Jeff Dean + Daniel Dulitz + Craig Silverstein + Paul Haahr + Corey Anderson + (and many others) + +Proto2 C++ and Java primary author: + Kenton Varda + +Proto2 Python primary authors: + Will Robinson + Petar Petrov + +Large code contributions: + Jason Hsueh + Joseph Schorr + Wenbo Zhu + +Large quantity of code reviews: + Scott Bruce + Frank Yellin + Neal Norwitz + Jeffrey Yasskin + Ambrose Feinstein + +Documentation: + Lisa Carey + +Maven packaging: + Gregory Kick + +Patch contributors: + Kevin Ko + * Small patch to handle trailing slashes in --proto_path flag. + Johan Euphrosine + * Small patch to fix Python CallMethod(). + Ulrich Kunitz + * Small optimizations to Python serialization. + Leandro Lucarella + * VI syntax highlighting tweaks. + * Fix compiler to not make output executable. + Dilip Joseph + * Heuristic detection of sub-messages when printing unknown fields in + text format. + Brian Atkinson + * Added @Override annotation to generated Java code where appropriate. + Vincent Choinière + * Tru64 support. + Monty Taylor + * Solaris 10 + Sun Studio fixes. + Alek Storm + * Slicing support for repeated scalar fields for the Python API. + Oleg Smolsky + * MS Visual Studio error format option. + * Detect unordered_map in stl_hash.m4. + Brian Olson + * gzip/zlib I/O support. + Michael Poole + * Fixed warnings about generated constructors not explicitly initializing + all fields (only present with certain compiler settings). + * Added generation of field number constants. + Wink Saville + * Fixed initialization ordering problem in logging code. + Will Pierce + * Small patch improving performance of in Python serialization. + Alexandre Vassalotti + * Emacs mode for Protocol Buffers (editors/protobuf-mode.el). + Scott Stafford + * Added Swap(), SwapElements(), and RemoveLast() to Reflection interface. + Alexander Melnikov + * HPUX support. + Oliver Jowett + * Detect whether zlib is new enough in configure script. + * Fixes for Solaris 10 32/64-bit confusion. + Evan Jones + * Optimize Java serialization code when writing a small message to a stream. + * Optimize Java serialization of strings so that UTF-8 encoding happens only + once per string per serialization call. + * Clean up some Java warnings. + * Fix bug with permanent callbacks that delete themselves when run. + Michael Kucharski + * Added CodedInputStream.getTotalBytesRead(). + Kacper Kowalik + * Fixed m4/acx_pthread.m4 problem for some Linux distributions. diff --git a/cpp/thirdparty/protobuf-2.5.0/COPYING.txt b/cpp/thirdparty/protobuf-2.5.0/COPYING.txt new file mode 100644 index 0000000..705db57 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/COPYING.txt @@ -0,0 +1,33 @@ +Copyright 2008, Google Inc. +All rights reserved. + +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. + +Code generated by the Protocol Buffer compiler is owned by the owner +of the input file used when generating it. This code is not +standalone and requires a support library to be linked with it. This +support library is itself covered by the above license. diff --git a/cpp/thirdparty/protobuf-2.5.0/INSTALL.txt b/cpp/thirdparty/protobuf-2.5.0/INSTALL.txt new file mode 100644 index 0000000..ce3b094 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/INSTALL.txt @@ -0,0 +1,237 @@ +This file contains detailed but generic information on building and +installing the C++ part of this project. For shorter instructions, +as well as instructions for compiling and installing the Java or +Python parts, see README. + +====================================================================== + +Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + + +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/cpp/thirdparty/protobuf-2.5.0/Makefile.am b/cpp/thirdparty/protobuf-2.5.0/Makefile.am new file mode 100644 index 0000000..c928613 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/Makefile.am @@ -0,0 +1,225 @@ +## Process this file with automake to produce Makefile.in + +ACLOCAL_AMFLAGS = -I m4 + +AUTOMAKE_OPTIONS = foreign + +# Build . before src so that our all-local and clean-local hooks kicks in at +# the right time. +SUBDIRS = . src + +# Always include gtest in distributions. +DIST_SUBDIRS = $(subdirs) src + +# Build gtest before we build protobuf tests. We don't add gtest to SUBDIRS +# because then "make check" would also build and run all of gtest's own tests, +# which takes a lot of time and is generally not useful to us. Also, we don't +# want "make install" to recurse into gtest since we don't want to overwrite +# the installed version of gtest if there is one. +check-local: + @echo "Making lib/libgtest.a lib/libgtest_main.a in gtest" + @cd gtest && $(MAKE) $(AM_MAKEFLAGS) lib/libgtest.la lib/libgtest_main.la + +# We would like to clean gtest when "make clean" is invoked. But we have to +# be careful because clean-local is also invoked during "make distclean", but +# "make distclean" already recurses into gtest because it's listed among the +# DIST_SUBDIRS. distclean will delete gtest/Makefile, so if we then try to +# cd to the directory again and "make clean" it will fail. So, check that the +# Makefile exists before recursing. +clean-local: + @if test -e gtest/Makefile; then \ + echo "Making clean in gtest"; \ + cd gtest && $(MAKE) $(AM_MAKEFLAGS) clean; \ + fi + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = protobuf.pc protobuf-lite.pc + +EXTRA_DIST = \ + autogen.sh \ + generate_descriptor_proto.sh \ + README.txt \ + INSTALL.txt \ + COPYING.txt \ + CONTRIBUTORS.txt \ + CHANGES.txt \ + editors/README.txt \ + editors/proto.vim \ + editors/protobuf-mode.el \ + vsprojects/config.h \ + vsprojects/extract_includes.bat \ + vsprojects/libprotobuf.vcproj \ + vsprojects/libprotobuf-lite.vcproj \ + vsprojects/libprotoc.vcproj \ + vsprojects/protobuf.sln \ + vsprojects/protoc.vcproj \ + vsprojects/readme.txt \ + vsprojects/test_plugin.vcproj \ + vsprojects/tests.vcproj \ + vsprojects/lite-test.vcproj \ + vsprojects/convert2008to2005.sh \ + examples/README.txt \ + examples/Makefile \ + examples/addressbook.proto \ + examples/add_person.cc \ + examples/list_people.cc \ + examples/AddPerson.java \ + examples/ListPeople.java \ + examples/add_person.py \ + examples/list_people.py \ + java/src/main/java/com/google/protobuf/AbstractMessage.java \ + java/src/main/java/com/google/protobuf/AbstractMessageLite.java \ + java/src/main/java/com/google/protobuf/AbstractParser.java \ + java/src/main/java/com/google/protobuf/BlockingRpcChannel.java \ + java/src/main/java/com/google/protobuf/BlockingService.java \ + java/src/main/java/com/google/protobuf/BoundedByteString.java \ + java/src/main/java/com/google/protobuf/ByteString.java \ + java/src/main/java/com/google/protobuf/CodedInputStream.java \ + java/src/main/java/com/google/protobuf/CodedOutputStream.java \ + java/src/main/java/com/google/protobuf/Descriptors.java \ + java/src/main/java/com/google/protobuf/DynamicMessage.java \ + java/src/main/java/com/google/protobuf/ExtensionRegistry.java \ + java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java \ + java/src/main/java/com/google/protobuf/FieldSet.java \ + java/src/main/java/com/google/protobuf/GeneratedMessage.java \ + java/src/main/java/com/google/protobuf/GeneratedMessageLite.java \ + java/src/main/java/com/google/protobuf/Internal.java \ + java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \ + java/src/main/java/com/google/protobuf/LazyField.java \ + java/src/main/java/com/google/protobuf/LazyStringArrayList.java \ + java/src/main/java/com/google/protobuf/LazyStringList.java \ + java/src/main/java/com/google/protobuf/LiteralByteString.java \ + java/src/main/java/com/google/protobuf/Message.java \ + java/src/main/java/com/google/protobuf/MessageLite.java \ + java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java \ + java/src/main/java/com/google/protobuf/MessageOrBuilder.java \ + java/src/main/java/com/google/protobuf/Parser.java \ + java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java \ + java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java \ + java/src/main/java/com/google/protobuf/RopeByteString.java \ + java/src/main/java/com/google/protobuf/RpcCallback.java \ + java/src/main/java/com/google/protobuf/RpcChannel.java \ + java/src/main/java/com/google/protobuf/RpcController.java \ + java/src/main/java/com/google/protobuf/RpcUtil.java \ + java/src/main/java/com/google/protobuf/ServiceException.java \ + java/src/main/java/com/google/protobuf/Service.java \ + java/src/main/java/com/google/protobuf/SingleFieldBuilder.java \ + java/src/main/java/com/google/protobuf/SmallSortedMap.java \ + java/src/main/java/com/google/protobuf/TextFormat.java \ + java/src/main/java/com/google/protobuf/UninitializedMessageException.java \ + java/src/main/java/com/google/protobuf/UnknownFieldSet.java \ + java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java \ + java/src/main/java/com/google/protobuf/Utf8.java \ + java/src/main/java/com/google/protobuf/WireFormat.java \ + java/src/test/java/com/google/protobuf/AbstractMessageTest.java \ + java/src/test/java/com/google/protobuf/BoundedByteStringTest.java \ + java/src/test/java/com/google/protobuf/ByteStringTest.java \ + java/src/test/java/com/google/protobuf/CodedInputStreamTest.java \ + java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java \ + java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java \ + java/src/test/java/com/google/protobuf/DescriptorsTest.java \ + java/src/test/java/com/google/protobuf/DynamicMessageTest.java \ + java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java \ + java/src/test/java/com/google/protobuf/GeneratedMessageTest.java \ + java/src/test/java/com/google/protobuf/IsValidUtf8Test.java \ + java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java \ + java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java \ + java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java \ + java/src/test/java/com/google/protobuf/LiteralByteStringTest.java \ + java/src/test/java/com/google/protobuf/LiteTest.java \ + java/src/test/java/com/google/protobuf/MessageTest.java \ + java/src/test/java/com/google/protobuf/NestedBuildersTest.java \ + java/src/test/java/com/google/protobuf/ParserTest.java \ + java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java \ + java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java \ + java/src/test/java/com/google/protobuf/RopeByteStringTest.java \ + java/src/test/java/com/google/protobuf/ServiceTest.java \ + java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java \ + java/src/test/java/com/google/protobuf/SmallSortedMapTest.java \ + java/src/test/java/com/google/protobuf/TestBadIdentifiers.java \ + java/src/test/java/com/google/protobuf/TestUtil.java \ + java/src/test/java/com/google/protobuf/TextFormatTest.java \ + java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java \ + java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \ + java/src/test/java/com/google/protobuf/WireFormatTest.java \ + java/src/test/java/com/google/protobuf/multiple_files_test.proto \ + java/src/test/java/com/google/protobuf/nested_builders_test.proto \ + java/src/test/java/com/google/protobuf/nested_extension_lite.proto \ + java/src/test/java/com/google/protobuf/nested_extension.proto \ + java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto \ + java/src/test/java/com/google/protobuf/non_nested_extension.proto \ + java/src/test/java/com/google/protobuf/test_bad_identifiers.proto \ + java/pom.xml \ + java/README.txt \ + python/google/protobuf/internal/generator_test.py \ + python/google/protobuf/internal/containers.py \ + python/google/protobuf/internal/decoder.py \ + python/google/protobuf/internal/descriptor_database_test.py \ + python/google/protobuf/internal/descriptor_pool_test.py \ + python/google/protobuf/internal/descriptor_test.py \ + python/google/protobuf/internal/encoder.py \ + python/google/protobuf/internal/enum_type_wrapper.py \ + python/google/protobuf/internal/factory_test1.proto \ + python/google/protobuf/internal/factory_test2.proto \ + python/google/protobuf/internal/message_cpp_test.py \ + python/google/protobuf/internal/message_factory_test.py \ + python/google/protobuf/internal/message_listener.py \ + python/google/protobuf/internal/message_test.py \ + python/google/protobuf/internal/more_extensions.proto \ + python/google/protobuf/internal/more_extensions_dynamic.proto \ + python/google/protobuf/internal/more_messages.proto \ + python/google/protobuf/internal/python_message.py \ + python/google/protobuf/internal/cpp_message.py \ + python/google/protobuf/internal/api_implementation.py \ + python/google/protobuf/internal/reflection_test.py \ + python/google/protobuf/internal/reflection_cpp_generated_test.py \ + python/google/protobuf/internal/service_reflection_test.py \ + python/google/protobuf/internal/test_bad_identifiers.proto \ + python/google/protobuf/internal/test_util.py \ + python/google/protobuf/internal/text_format_test.py \ + python/google/protobuf/internal/type_checkers.py \ + python/google/protobuf/internal/unknown_fields_test.py \ + python/google/protobuf/internal/wire_format.py \ + python/google/protobuf/internal/wire_format_test.py \ + python/google/protobuf/internal/__init__.py \ + python/google/protobuf/pyext/python-proto2.cc \ + python/google/protobuf/pyext/python_descriptor.cc \ + python/google/protobuf/pyext/python_descriptor.h \ + python/google/protobuf/pyext/python_protobuf.cc \ + python/google/protobuf/pyext/python_protobuf.h \ + python/google/protobuf/descriptor.py \ + python/google/protobuf/descriptor_database.py \ + python/google/protobuf/descriptor_pool.py \ + python/google/protobuf/message.py \ + python/google/protobuf/message_factory.py \ + python/google/protobuf/reflection.py \ + python/google/protobuf/service.py \ + python/google/protobuf/service_reflection.py \ + python/google/protobuf/text_format.py \ + python/google/protobuf/__init__.py \ + python/google/__init__.py \ + python/ez_setup.py \ + python/setup.py \ + python/mox.py \ + python/stubout.py \ + python/README.txt + +# Deletes all the files generated by autogen.sh. +MAINTAINERCLEANFILES = \ + aclocal.m4 \ + config.guess \ + config.sub \ + configure \ + depcomp \ + install-sh \ + ltmain.sh \ + Makefile.in \ + missing \ + mkinstalldirs \ + config.h.in \ + stamp.h.in \ + m4/ltsugar.m4 \ + m4/libtool.m4 \ + m4/ltversion.m4 \ + m4/lt~obsolete.m4 \ + m4/ltoptions.m4 diff --git a/cpp/thirdparty/protobuf-2.5.0/Makefile.in b/cpp/thirdparty/protobuf-2.5.0/Makefile.in new file mode 100644 index 0000000..12ae823 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/Makefile.in @@ -0,0 +1,1041 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = . +DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(srcdir)/protobuf-lite.pc.in $(srcdir)/protobuf.pc.in \ + $(top_srcdir)/configure config.guess config.sub depcomp \ + install-sh ltmain.sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_system_extensions.m4 \ + $(top_srcdir)/m4/acx_check_suncc.m4 \ + $(top_srcdir)/m4/acx_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/stl_hash.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = protobuf.pc protobuf-lite.pc +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" +DATA = $(pkgconfig_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +ISAINFO = @ISAINFO@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POW_LIB = @POW_LIB@ +PROTOBUF_OPT_FLAG = @PROTOBUF_OPT_FLAG@ +PROTOC = @PROTOC@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = foreign + +# Build . before src so that our all-local and clean-local hooks kicks in at +# the right time. +SUBDIRS = . src + +# Always include gtest in distributions. +DIST_SUBDIRS = $(subdirs) src +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = protobuf.pc protobuf-lite.pc +EXTRA_DIST = \ + autogen.sh \ + generate_descriptor_proto.sh \ + README.txt \ + INSTALL.txt \ + COPYING.txt \ + CONTRIBUTORS.txt \ + CHANGES.txt \ + editors/README.txt \ + editors/proto.vim \ + editors/protobuf-mode.el \ + vsprojects/config.h \ + vsprojects/extract_includes.bat \ + vsprojects/libprotobuf.vcproj \ + vsprojects/libprotobuf-lite.vcproj \ + vsprojects/libprotoc.vcproj \ + vsprojects/protobuf.sln \ + vsprojects/protoc.vcproj \ + vsprojects/readme.txt \ + vsprojects/test_plugin.vcproj \ + vsprojects/tests.vcproj \ + vsprojects/lite-test.vcproj \ + vsprojects/convert2008to2005.sh \ + examples/README.txt \ + examples/Makefile \ + examples/addressbook.proto \ + examples/add_person.cc \ + examples/list_people.cc \ + examples/AddPerson.java \ + examples/ListPeople.java \ + examples/add_person.py \ + examples/list_people.py \ + java/src/main/java/com/google/protobuf/AbstractMessage.java \ + java/src/main/java/com/google/protobuf/AbstractMessageLite.java \ + java/src/main/java/com/google/protobuf/AbstractParser.java \ + java/src/main/java/com/google/protobuf/BlockingRpcChannel.java \ + java/src/main/java/com/google/protobuf/BlockingService.java \ + java/src/main/java/com/google/protobuf/BoundedByteString.java \ + java/src/main/java/com/google/protobuf/ByteString.java \ + java/src/main/java/com/google/protobuf/CodedInputStream.java \ + java/src/main/java/com/google/protobuf/CodedOutputStream.java \ + java/src/main/java/com/google/protobuf/Descriptors.java \ + java/src/main/java/com/google/protobuf/DynamicMessage.java \ + java/src/main/java/com/google/protobuf/ExtensionRegistry.java \ + java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java \ + java/src/main/java/com/google/protobuf/FieldSet.java \ + java/src/main/java/com/google/protobuf/GeneratedMessage.java \ + java/src/main/java/com/google/protobuf/GeneratedMessageLite.java \ + java/src/main/java/com/google/protobuf/Internal.java \ + java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \ + java/src/main/java/com/google/protobuf/LazyField.java \ + java/src/main/java/com/google/protobuf/LazyStringArrayList.java \ + java/src/main/java/com/google/protobuf/LazyStringList.java \ + java/src/main/java/com/google/protobuf/LiteralByteString.java \ + java/src/main/java/com/google/protobuf/Message.java \ + java/src/main/java/com/google/protobuf/MessageLite.java \ + java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java \ + java/src/main/java/com/google/protobuf/MessageOrBuilder.java \ + java/src/main/java/com/google/protobuf/Parser.java \ + java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java \ + java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java \ + java/src/main/java/com/google/protobuf/RopeByteString.java \ + java/src/main/java/com/google/protobuf/RpcCallback.java \ + java/src/main/java/com/google/protobuf/RpcChannel.java \ + java/src/main/java/com/google/protobuf/RpcController.java \ + java/src/main/java/com/google/protobuf/RpcUtil.java \ + java/src/main/java/com/google/protobuf/ServiceException.java \ + java/src/main/java/com/google/protobuf/Service.java \ + java/src/main/java/com/google/protobuf/SingleFieldBuilder.java \ + java/src/main/java/com/google/protobuf/SmallSortedMap.java \ + java/src/main/java/com/google/protobuf/TextFormat.java \ + java/src/main/java/com/google/protobuf/UninitializedMessageException.java \ + java/src/main/java/com/google/protobuf/UnknownFieldSet.java \ + java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java \ + java/src/main/java/com/google/protobuf/Utf8.java \ + java/src/main/java/com/google/protobuf/WireFormat.java \ + java/src/test/java/com/google/protobuf/AbstractMessageTest.java \ + java/src/test/java/com/google/protobuf/BoundedByteStringTest.java \ + java/src/test/java/com/google/protobuf/ByteStringTest.java \ + java/src/test/java/com/google/protobuf/CodedInputStreamTest.java \ + java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java \ + java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java \ + java/src/test/java/com/google/protobuf/DescriptorsTest.java \ + java/src/test/java/com/google/protobuf/DynamicMessageTest.java \ + java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java \ + java/src/test/java/com/google/protobuf/GeneratedMessageTest.java \ + java/src/test/java/com/google/protobuf/IsValidUtf8Test.java \ + java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java \ + java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java \ + java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java \ + java/src/test/java/com/google/protobuf/LiteralByteStringTest.java \ + java/src/test/java/com/google/protobuf/LiteTest.java \ + java/src/test/java/com/google/protobuf/MessageTest.java \ + java/src/test/java/com/google/protobuf/NestedBuildersTest.java \ + java/src/test/java/com/google/protobuf/ParserTest.java \ + java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java \ + java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java \ + java/src/test/java/com/google/protobuf/RopeByteStringTest.java \ + java/src/test/java/com/google/protobuf/ServiceTest.java \ + java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java \ + java/src/test/java/com/google/protobuf/SmallSortedMapTest.java \ + java/src/test/java/com/google/protobuf/TestBadIdentifiers.java \ + java/src/test/java/com/google/protobuf/TestUtil.java \ + java/src/test/java/com/google/protobuf/TextFormatTest.java \ + java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java \ + java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \ + java/src/test/java/com/google/protobuf/WireFormatTest.java \ + java/src/test/java/com/google/protobuf/multiple_files_test.proto \ + java/src/test/java/com/google/protobuf/nested_builders_test.proto \ + java/src/test/java/com/google/protobuf/nested_extension_lite.proto \ + java/src/test/java/com/google/protobuf/nested_extension.proto \ + java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto \ + java/src/test/java/com/google/protobuf/non_nested_extension.proto \ + java/src/test/java/com/google/protobuf/test_bad_identifiers.proto \ + java/pom.xml \ + java/README.txt \ + python/google/protobuf/internal/generator_test.py \ + python/google/protobuf/internal/containers.py \ + python/google/protobuf/internal/decoder.py \ + python/google/protobuf/internal/descriptor_database_test.py \ + python/google/protobuf/internal/descriptor_pool_test.py \ + python/google/protobuf/internal/descriptor_test.py \ + python/google/protobuf/internal/encoder.py \ + python/google/protobuf/internal/enum_type_wrapper.py \ + python/google/protobuf/internal/factory_test1.proto \ + python/google/protobuf/internal/factory_test2.proto \ + python/google/protobuf/internal/message_cpp_test.py \ + python/google/protobuf/internal/message_factory_test.py \ + python/google/protobuf/internal/message_listener.py \ + python/google/protobuf/internal/message_test.py \ + python/google/protobuf/internal/more_extensions.proto \ + python/google/protobuf/internal/more_extensions_dynamic.proto \ + python/google/protobuf/internal/more_messages.proto \ + python/google/protobuf/internal/python_message.py \ + python/google/protobuf/internal/cpp_message.py \ + python/google/protobuf/internal/api_implementation.py \ + python/google/protobuf/internal/reflection_test.py \ + python/google/protobuf/internal/reflection_cpp_generated_test.py \ + python/google/protobuf/internal/service_reflection_test.py \ + python/google/protobuf/internal/test_bad_identifiers.proto \ + python/google/protobuf/internal/test_util.py \ + python/google/protobuf/internal/text_format_test.py \ + python/google/protobuf/internal/type_checkers.py \ + python/google/protobuf/internal/unknown_fields_test.py \ + python/google/protobuf/internal/wire_format.py \ + python/google/protobuf/internal/wire_format_test.py \ + python/google/protobuf/internal/__init__.py \ + python/google/protobuf/pyext/python-proto2.cc \ + python/google/protobuf/pyext/python_descriptor.cc \ + python/google/protobuf/pyext/python_descriptor.h \ + python/google/protobuf/pyext/python_protobuf.cc \ + python/google/protobuf/pyext/python_protobuf.h \ + python/google/protobuf/descriptor.py \ + python/google/protobuf/descriptor_database.py \ + python/google/protobuf/descriptor_pool.py \ + python/google/protobuf/message.py \ + python/google/protobuf/message_factory.py \ + python/google/protobuf/reflection.py \ + python/google/protobuf/service.py \ + python/google/protobuf/service_reflection.py \ + python/google/protobuf/text_format.py \ + python/google/protobuf/__init__.py \ + python/google/__init__.py \ + python/ez_setup.py \ + python/setup.py \ + python/mox.py \ + python/stubout.py \ + python/README.txt + + +# Deletes all the files generated by autogen.sh. +MAINTAINERCLEANFILES = \ + aclocal.m4 \ + config.guess \ + config.sub \ + configure \ + depcomp \ + install-sh \ + ltmain.sh \ + Makefile.in \ + missing \ + mkinstalldirs \ + config.h.in \ + stamp.h.in \ + m4/ltsugar.m4 \ + m4/libtool.m4 \ + m4/ltversion.m4 \ + m4/lt~obsolete.m4 \ + m4/ltoptions.m4 + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +protobuf.pc: $(top_builddir)/config.status $(srcdir)/protobuf.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +protobuf-lite.pc: $(top_builddir)/config.status $(srcdir)/protobuf-lite.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-recursive +all-am: Makefile $(DATA) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-local mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkgconfigDATA + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check-am \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am check-local clean \ + clean-generic clean-libtool clean-local ctags ctags-recursive \ + dist dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma \ + dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-recursive uninstall uninstall-am \ + uninstall-pkgconfigDATA + + +# Build gtest before we build protobuf tests. We don't add gtest to SUBDIRS +# because then "make check" would also build and run all of gtest's own tests, +# which takes a lot of time and is generally not useful to us. Also, we don't +# want "make install" to recurse into gtest since we don't want to overwrite +# the installed version of gtest if there is one. +check-local: + @echo "Making lib/libgtest.a lib/libgtest_main.a in gtest" + @cd gtest && $(MAKE) $(AM_MAKEFLAGS) lib/libgtest.la lib/libgtest_main.la + +# We would like to clean gtest when "make clean" is invoked. But we have to +# be careful because clean-local is also invoked during "make distclean", but +# "make distclean" already recurses into gtest because it's listed among the +# DIST_SUBDIRS. distclean will delete gtest/Makefile, so if we then try to +# cd to the directory again and "make clean" it will fail. So, check that the +# Makefile exists before recursing. +clean-local: + @if test -e gtest/Makefile; then \ + echo "Making clean in gtest"; \ + cd gtest && $(MAKE) $(AM_MAKEFLAGS) clean; \ + fi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/cpp/thirdparty/protobuf-2.5.0/README.txt b/cpp/thirdparty/protobuf-2.5.0/README.txt new file mode 100644 index 0000000..17551a5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/README.txt @@ -0,0 +1,152 @@ +Protocol Buffers - Google's data interchange format +Copyright 2008 Google Inc. +http://code.google.com/apis/protocolbuffers/ + +C++ Installation - Unix +======================= + +To build and install the C++ Protocol Buffer runtime and the Protocol +Buffer compiler (protoc) execute the following: + + $ ./configure + $ make + $ make check + $ make install + +If "make check" fails, you can still install, but it is likely that +some features of this library will not work correctly on your system. +Proceed at your own risk. + +"make install" may require superuser privileges. + +For advanced usage information on configure and make, see INSTALL.txt. + +** Hint on install location ** + + By default, the package will be installed to /usr/local. However, + on many platforms, /usr/local/lib is not part of LD_LIBRARY_PATH. + You can add it, but it may be easier to just install to /usr + instead. To do this, invoke configure as follows: + + ./configure --prefix=/usr + + If you already built the package with a different prefix, make sure + to run "make clean" before building again. + +** Compiling dependent packages ** + + To compile a package that uses Protocol Buffers, you need to pass + various flags to your compiler and linker. As of version 2.2.0, + Protocol Buffers integrates with pkg-config to manage this. If you + have pkg-config installed, then you can invoke it to get a list of + flags like so: + + pkg-config --cflags protobuf # print compiler flags + pkg-config --libs protobuf # print linker flags + pkg-config --cflags --libs protobuf # print both + + For example: + + c++ my_program.cc my_proto.pb.cc `pkg-config --cflags --libs protobuf` + + Note that packages written prior to the 2.2.0 release of Protocol + Buffers may not yet integrate with pkg-config to get flags, and may + not pass the correct set of flags to correctly link against + libprotobuf. If the package in question uses autoconf, you can + often fix the problem by invoking its configure script like: + + configure CXXFLAGS="$(pkg-config --cflags protobuf)" \ + LIBS="$(pkg-config --libs protobuf)" + + This will force it to use the correct flags. + + If you are writing an autoconf-based package that uses Protocol + Buffers, you should probably use the PKG_CHECK_MODULES macro in your + configure script like: + + PKG_CHECK_MODULES([protobuf], [protobuf]) + + See the pkg-config man page for more info. + + If you only want protobuf-lite, substitute "protobuf-lite" in place + of "protobuf" in these examples. + +** Note for cross-compiling ** + + The makefiles normally invoke the protoc executable that they just + built in order to build tests. When cross-compiling, the protoc + executable may not be executable on the host machine. In this case, + you must build a copy of protoc for the host machine first, then use + the --with-protoc option to tell configure to use it instead. For + example: + + ./configure --with-protoc=protoc + + This will use the installed protoc (found in your $PATH) instead of + trying to execute the one built during the build process. You can + also use an executable that hasn't been installed. For example, if + you built the protobuf package for your host machine in ../host, + you might do: + + ./configure --with-protoc=../host/src/protoc + + Either way, you must make sure that the protoc executable you use + has the same version as the protobuf source code you are trying to + use it with. + +** Note for Solaris users ** + + Solaris 10 x86 has a bug that will make linking fail, complaining + about libstdc++.la being invalid. We have included a work-around + in this package. To use the work-around, run configure as follows: + + ./configure LDFLAGS=-L$PWD/src/solaris + + See src/solaris/libstdc++.la for more info on this bug. + +** Note for HP C++ Tru64 users ** + + To compile invoke configure as follows: + + ./configure CXXFLAGS="-O -std ansi -ieee -D__USE_STD_IOSTREAM" + + Also, you will need to use gmake instead of make. + +C++ Installation - Windows +========================== + +If you are using Microsoft Visual C++, see vsprojects/readme.txt. + +If you are using Cygwin or MinGW, follow the Unix installation +instructions, above. + +Binary Compatibility Warning +============================ + +Due to the nature of C++, it is unlikely that any two versions of the +Protocol Buffers C++ runtime libraries will have compatible ABIs. +That is, if you linked an executable against an older version of +libprotobuf, it is unlikely to work with a newer version without +re-compiling. This problem, when it occurs, will normally be detected +immediately on startup of your app. Still, you may want to consider +using static linkage. You can configure this package to install +static libraries only using: + + ./configure --disable-shared + +Java and Python Installation +============================ + +The Java and Python runtime libraries for Protocol Buffers are located +in the java and python directories. See the README file in each +directory for more information on how to compile and install them. +Note that both of them require you to first install the Protocol +Buffer compiler (protoc), which is part of the C++ package. + +Usage +===== + +The complete documentation for Protocol Buffers is available via the +web at: + + http://code.google.com/apis/protocolbuffers/ diff --git a/cpp/thirdparty/protobuf-2.5.0/aclocal.m4 b/cpp/thirdparty/protobuf-2.5.0/aclocal.m4 new file mode 100644 index 0000000..5081ad9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/aclocal.m4 @@ -0,0 +1,1020 @@ +# generated automatically by aclocal 1.11.3 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.3], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.3])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008, +# 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless `enable' is passed literally. +# For symmetry, `disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], +[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/ac_system_extensions.m4]) +m4_include([m4/acx_check_suncc.m4]) +m4_include([m4/acx_pthread.m4]) +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) +m4_include([m4/stl_hash.m4]) diff --git a/cpp/thirdparty/protobuf-2.5.0/autogen.sh b/cpp/thirdparty/protobuf-2.5.0/autogen.sh new file mode 100755 index 0000000..c3e026d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/autogen.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +# Run this script to generate the configure script and other files that will +# be included in the distribution. These files are not checked in because they +# are automatically generated. + +set -e + +# Check that we're being run from the right directory. +if test ! -f src/google/protobuf/stubs/common.h; then + cat >&2 << __EOF__ +Could not find source code. Make sure you are running this script from the +root of the distribution tree. +__EOF__ + exit 1 +fi + +# Check that gtest is present. Usually it is already there since the +# directory is set up as an SVN external. +if test ! -e gtest; then + echo "Google Test not present. Fetching gtest-1.5.0 from the web..." + curl http://googletest.googlecode.com/files/gtest-1.5.0.tar.bz2 | tar jx + mv gtest-1.5.0 gtest +fi + +set -ex + +# Temporary hack: Must change C runtime library to "multi-threaded DLL", +# otherwise it will be set to "multi-threaded static" when MSVC upgrades +# the project file to MSVC 2005/2008. vladl of Google Test says gtest will +# probably change their default to match, then this will be unnecessary. +# One of these mappings converts the debug configuration and the other +# converts the release configuration. I don't know which is which. +sed -i -e 's/RuntimeLibrary="5"/RuntimeLibrary="3"/g; + s/RuntimeLibrary="4"/RuntimeLibrary="2"/g;' gtest/msvc/*.vcproj + +# TODO(kenton): Remove the ",no-obsolete" part and fix the resulting warnings. +autoreconf -f -i -Wall,no-obsolete + +rm -rf autom4te.cache config.h.in~ +exit 0 diff --git a/cpp/thirdparty/protobuf-2.5.0/config.guess b/cpp/thirdparty/protobuf-2.5.0/config.guess new file mode 100755 index 0000000..d622a44 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/config.guess @@ -0,0 +1,1530 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/cpp/thirdparty/protobuf-2.5.0/config.h.in b/cpp/thirdparty/protobuf-2.5.0/config.h.in new file mode 100644 index 0000000..6580e95 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/config.h.in @@ -0,0 +1,149 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* the name of */ +#undef HASH_MAP_CLASS + +/* the location of or */ +#undef HASH_MAP_H + +/* the namespace of hash_map/hash_set */ +#undef HASH_NAMESPACE + +/* the name of */ +#undef HASH_SET_CLASS + +/* the location of or */ +#undef HASH_SET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `ftruncate' function. */ +#undef HAVE_FTRUNCATE + +/* define if the compiler has hash_map */ +#undef HAVE_HASH_MAP + +/* define if the compiler has hash_set */ +#undef HAVE_HASH_SET + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the `mkdir' function. */ +#undef HAVE_MKDIR + +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Enable classes using zlib compression. */ +#undef HAVE_ZLIB + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Version number of package */ +#undef VERSION + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE diff --git a/cpp/thirdparty/protobuf-2.5.0/config.sub b/cpp/thirdparty/protobuf-2.5.0/config.sub new file mode 100755 index 0000000..c894da4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/config.sub @@ -0,0 +1,1773 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/cpp/thirdparty/protobuf-2.5.0/configure b/cpp/thirdparty/protobuf-2.5.0/configure new file mode 100755 index 0000000..9092afd --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/configure @@ -0,0 +1,19494 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for Protocol Buffers 2.5.0. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: protobuf@googlegroups.com about your system, including +$0: any error possibly output before this message. Then +$0: install a modern shell, or manually run the script +$0: under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='Protocol Buffers' +PACKAGE_TARNAME='protobuf' +PACKAGE_VERSION='2.5.0' +PACKAGE_STRING='Protocol Buffers 2.5.0' +PACKAGE_BUGREPORT='protobuf@googlegroups.com' +PACKAGE_URL='' + +ac_unique_file="src/google/protobuf/message.cc" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +enable_option_checking=no +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +subdirs +PTHREAD_CFLAGS +PTHREAD_LIBS +PTHREAD_CC +acx_pthread_config +USE_EXTERNAL_PROTOC_FALSE +USE_EXTERNAL_PROTOC_TRUE +PROTOC +HAVE_ZLIB_FALSE +HAVE_ZLIB_TRUE +POW_LIB +LIBOBJS +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +LIBTOOL +ISAINFO +PROTOBUF_OPT_FLAG +GCC_FALSE +GCC_TRUE +EGREP +GREP +CXXCPP +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_maintainer_mode +with_zlib +with_protoc +enable_dependency_tracking +enable_64bit_solaris +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CXXCPP' +ac_subdirs_all='gtest' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures Protocol Buffers 2.5.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/protobuf] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of Protocol Buffers 2.5.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-maintainer-mode disable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --disable-64bit-solaris Build 64 bit binary on Solaris [default=on] + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-zlib include classes for streaming compressed data in and + out [default=check] + --with-protoc=COMMAND use the given protoc command instead of building a + new one when building tests (useful for + cross-compiling) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +Protocol Buffers configure 2.5.0 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_cxx_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ---------------------------------------- ## +## Report this to protobuf@googlegroups.com ## +## ---------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_mongrel + +# ac_fn_cxx_try_run LINENO +# ------------------------ +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_cxx_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_run + +# ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_cxx_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_compile + +# ac_fn_cxx_check_decl LINENO SYMBOL VAR INCLUDES +# ----------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_cxx_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_decl + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_cxx_check_func LINENO FUNC VAR +# ------------------------------------ +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_cxx_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by Protocol Buffers $as_me 2.5.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + + +ac_config_headers="$ac_config_headers config.h" + + + +# autoconf's default CXXFLAGS are usually "-g -O2". These aren't necessarily +# the best choice for libprotobuf. +if test "x${ac_cv_env_CFLAGS_set}" = "x"; then : + CFLAGS="" +fi +if test "x${ac_cv_env_CXXFLAGS_set}" = "x"; then : + CXXFLAGS="" +fi + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if ${ac_cv_target+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='protobuf' + VERSION='2.5.0' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + + +# Check whether --with-zlib was given. +if test "${with_zlib+set}" = set; then : + withval=$with_zlib; +else + with_zlib=check +fi + + + +# Check whether --with-protoc was given. +if test "${with_protoc+set}" = set; then : + withval=$with_protoc; +else + with_protoc=no +fi + + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_cxx_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_cxx_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + + + + + + + if test "$GCC" = yes; then + GCC_TRUE= + GCC_FALSE='#' +else + GCC_TRUE='#' + GCC_FALSE= +fi + # let the Makefile know if we're gcc + +# test_util.cc takes forever to compile with GCC and optimization turned on. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking C++ compiler flags..." >&5 +$as_echo_n "checking C++ compiler flags...... " >&6; } +if test "x${ac_cv_env_CXXFLAGS_set}" = "x"; then : + + if test "$GCC" = "yes"; then : + + PROTOBUF_OPT_FLAG="-O2" + CXXFLAGS="${CXXFLAGS} -g" + +fi + + # Protocol Buffers contains several checks that are intended to be used only + # for debugging and which might hurt performance. Most users are probably + # end users who don't want these checks, so add -DNDEBUG by default. + CXXFLAGS="$CXXFLAGS -DNDEBUG" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: use default: $PROTOBUF_OPT_FLAG $CXXFLAGS" >&5 +$as_echo "use default: $PROTOBUF_OPT_FLAG $CXXFLAGS" >&6; } + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: use user-supplied: $CXXFLAGS" >&5 +$as_echo "use user-supplied: $CXXFLAGS" >&6; } + +fi + + + + + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + ac_fn_cxx_check_decl "$LINENO" "__SUNPRO_CC" "ac_cv_have_decl___SUNPRO_CC" "$ac_includes_default" +if test "x$ac_cv_have_decl___SUNPRO_CC" = xyes; then : + SUNCC="yes" +else + SUNCC="no" +fi + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + # Check whether --enable-64bit-solaris was given. +if test "${enable_64bit_solaris+set}" = set; then : + enableval=$enable_64bit_solaris; ac_enable_64bit="$enableval" +else + ac_enable_64bit="yes" +fi + + + if test "$SUNCC" = "yes" -a "x${ac_cv_env_CXXFLAGS_set}" = "x"; then : + + CXXFLAGS="-g0 -xO3 -xlibmil -xdepend -xbuiltin -mt -compat=5 -library=stlport4 -library=Crun -template=no%extdef ${CXXFLAGS}" + +fi + + case $host_os in + *solaris*) + for ac_prog in isainfo +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ISAINFO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ISAINFO"; then + ac_cv_prog_ISAINFO="$ISAINFO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ISAINFO="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ISAINFO=$ac_cv_prog_ISAINFO +if test -n "$ISAINFO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ISAINFO" >&5 +$as_echo "$ISAINFO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ISAINFO" && break +done +test -n "$ISAINFO" || ISAINFO="no" + + if test "x$ISAINFO" != "xno"; then : + isainfo_b=`${ISAINFO} -b` +else + isainfo_b="x" +fi + + if test "$isainfo_b" != "x"; then : + + + isainfo_k=`${ISAINFO} -k` + + if test "x$ac_enable_64bit" = "xyes"; then : + + + if test "x$libdir" = "x\${exec_prefix}/lib"; then : + + libdir="${libdir}/${isainfo_k}" + +fi + + if test "x${ac_cv_env_CXXFLAGS_set}" = "x"; then : + + CXXFLAGS="${CXXFLAGS} -m64" + ac_cv_env_CXXFLAGS_set=set + ac_cv_env_CXXFLAGS_value='-m64' + +fi + + if test "x${ac_cv_env_CFLAGS_set}" = "x"; then : + + CFLAGS="${CFLAGS} -m64" + ac_cv_env_CFLAGS_set=set + ac_cv_env_CFLAGS_value='-m64' + +fi + + if test "$target_cpu" = "sparc" -a "x$SUNCC" = "xyes" ; then : + + CXXFLAGS="-xmemalign=8s ${CXXFLAGS}" + +fi + +fi + +fi + ;; + esac + + + +# Have to do libtool after SUNCC, other wise it "helpfully" adds Crun Cstd +# to the link +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.2' +macro_revision='1.3337' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +CC="$lt_save_CC" + + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +# Checks for header files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_cxx_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +for ac_header in fcntl.h inttypes.h limits.h stdlib.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for library functions. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 +$as_echo_n "checking for working memcmp... " >&6; } +if ${ac_cv_func_memcmp_working+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_memcmp_working=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Some versions of memcmp are not 8-bit clean. */ + char c0 = '\100', c1 = '\200', c2 = '\201'; + if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) + return 1; + + /* The Next x86 OpenStep bug shows up only when comparing 16 bytes + or more and with at least one buffer not starting on a 4-byte boundary. + William Lewis provided this test program. */ + { + char foo[21]; + char bar[21]; + int i; + for (i = 0; i < 4; i++) + { + char *a = foo + i; + char *b = bar + i; + strcpy (a, "--------01111111"); + strcpy (b, "--------10000000"); + if (memcmp (a, b, 16) >= 0) + return 1; + } + return 0; + } + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_run "$LINENO"; then : + ac_cv_func_memcmp_working=yes +else + ac_cv_func_memcmp_working=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 +$as_echo "$ac_cv_func_memcmp_working" >&6; } +test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in + *" memcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" + ;; +esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strtod" >&5 +$as_echo_n "checking for working strtod... " >&6; } +if ${ac_cv_func_strtod+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_strtod=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +#ifndef strtod +double strtod (); +#endif +int +main() +{ + { + /* Some versions of Linux strtod mis-parse strings with leading '+'. */ + char *string = " +69"; + char *term; + double value; + value = strtod (string, &term); + if (value != 69 || term != (string + 4)) + return 1; + } + + { + /* Under Solaris 2.4, strtod returns the wrong value for the + terminating character under some conditions. */ + char *string = "NaN"; + char *term; + strtod (string, &term); + if (term != string && *(term - 1) == 0) + return 1; + } + return 0; +} + +_ACEOF +if ac_fn_cxx_try_run "$LINENO"; then : + ac_cv_func_strtod=yes +else + ac_cv_func_strtod=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strtod" >&5 +$as_echo "$ac_cv_func_strtod" >&6; } +if test $ac_cv_func_strtod = no; then + case " $LIBOBJS " in + *" strtod.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtod.$ac_objext" + ;; +esac + +ac_fn_cxx_check_func "$LINENO" "pow" "ac_cv_func_pow" +if test "x$ac_cv_func_pow" = xyes; then : + +fi + +if test $ac_cv_func_pow = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 +$as_echo_n "checking for pow in -lm... " >&6; } +if ${ac_cv_lib_m_pow+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pow (); +int +main () +{ +return pow (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_m_pow=yes +else + ac_cv_lib_m_pow=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 +$as_echo "$ac_cv_lib_m_pow" >&6; } +if test "x$ac_cv_lib_m_pow" = xyes; then : + POW_LIB=-lm +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find library containing definition of pow" >&5 +$as_echo "$as_me: WARNING: cannot find library containing definition of pow" >&2;} +fi + +fi + +fi + +for ac_func in ftruncate memset mkdir strchr strerror strtol +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# Check for zlib. +HAVE_ZLIB=0 +if test "$with_zlib" != no; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking zlib version" >&5 +$as_echo_n "checking zlib version... " >&6; } + + # First check the zlib header version. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1204) + # error zlib version too old + #endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok (1.2.0.4 or later)" >&5 +$as_echo "ok (1.2.0.4 or later)" >&6; } + + # Also need to add -lz to the linker flags and make sure this succeeds. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing zlibVersion" >&5 +$as_echo_n "checking for library containing zlibVersion... " >&6; } +if ${ac_cv_search_zlibVersion+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char zlibVersion (); +int +main () +{ +return zlibVersion (); + ; + return 0; +} +_ACEOF +for ac_lib in '' z; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_search_zlibVersion=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_zlibVersion+:} false; then : + break +fi +done +if ${ac_cv_search_zlibVersion+:} false; then : + +else + ac_cv_search_zlibVersion=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_zlibVersion" >&5 +$as_echo "$ac_cv_search_zlibVersion" >&6; } +ac_res=$ac_cv_search_zlibVersion +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + + +$as_echo "#define HAVE_ZLIB 1" >>confdefs.h + + HAVE_ZLIB=1 + +else + + if test "$with_zlib" != check; then : + + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "--with-zlib was given, but no working zlib library was found +See \`config.log' for more details" "$LINENO" 5; } + +fi + +fi + + +else + + if test "$with_zlib" = check; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: headers missing or too old (requires 1.2.0.4)" >&5 +$as_echo "headers missing or too old (requires 1.2.0.4)" >&6; } + +else + + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "--with-zlib was given, but zlib headers were not present or were too old (requires 1.2.0.4) +See \`config.log' for more details" "$LINENO" 5; } + +fi + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi + if test $HAVE_ZLIB = 1; then + HAVE_ZLIB_TRUE= + HAVE_ZLIB_FALSE='#' +else + HAVE_ZLIB_TRUE='#' + HAVE_ZLIB_FALSE= +fi + + +if test "$with_protoc" != "no"; then : + + PROTOC=$with_protoc + if test "$with_protoc" = "yes"; then : + + # No argument given. Use system protoc. + PROTOC=protoc + +fi + if echo "$PROTOC" | grep -q '^[^/].*/'; then : + + # Does not start with a slash, but contains a slash. So, it's a relative + # path (as opposed to an absolute path or an executable in $PATH). + # Since it will actually be executed from the src directory, prefix with + # the current directory. We also insert $ac_top_build_prefix in case this + # is a nested package and --with-protoc was actually given on the outer + # package's configure script. + PROTOC=`pwd`/${ac_top_build_prefix}$PROTOC + +fi + + +fi + if test "$with_protoc" != "no"; then + USE_EXTERNAL_PROTOC_TRUE= + USE_EXTERNAL_PROTOC_FALSE='#' +else + USE_EXTERNAL_PROTOC_TRUE='#' + USE_EXTERNAL_PROTOC_FALSE= +fi + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 +$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_join (); +int +main () +{ +return pthread_join (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + acx_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 +$as_echo "$acx_pthread_ok" >&6; } + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 +$as_echo_n "checking whether pthreads work without any flags... " >&6; } + ;; + + -*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 +$as_echo_n "checking whether pthreads work with $flag... " >&6; } + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + # Extract the first word of "pthread-config", so it can be a program name with args. +set dummy pthread-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_acx_pthread_config+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$acx_pthread_config"; then + ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_acx_pthread_config="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no" +fi +fi +acx_pthread_config=$ac_cv_prog_acx_pthread_config +if test -n "$acx_pthread_config"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5 +$as_echo "$acx_pthread_config" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 +$as_echo_n "checking for the pthreads library -l$flag... " >&6; } + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + acx_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 +$as_echo "$acx_pthread_ok" >&6; } + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 +$as_echo_n "checking for joinable pthread attribute... " >&6; } + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +int attr=$attr; return attr; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + attr_name=$attr; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 +$as_echo "$attr_name" >&6; } + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + +cat >>confdefs.h <<_ACEOF +#define PTHREAD_CREATE_JOINABLE $attr_name +_ACEOF + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 +$as_echo_n "checking if more special flags are required for pthreads... " >&6; } + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 +$as_echo "${flag}" >&6; } + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + for ac_prog in xlc_r cc_r +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_PTHREAD_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PTHREAD_CC"; then + ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_PTHREAD_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PTHREAD_CC=$ac_cv_prog_PTHREAD_CC +if test -n "$PTHREAD_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 +$as_echo "$PTHREAD_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PTHREAD_CC" && break +done +test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" + + else + PTHREAD_CC=$CC + fi + + # The next part tries to detect GCC inconsistency with -shared on some + # architectures and systems. The problem is that in certain + # configurations, when -shared is specified, GCC "forgets" to + # internally use various flags which are still necessary. + + # + # Prepare the flags + # + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_CC="$CC" + + # Try with the flags determined by the earlier checks. + # + # -Wl,-z,defs forces link-time symbol resolution, so that the + # linking checks with -shared actually have any value + # + # FIXME: -fPIC is required for -shared on many architectures, + # so we specify it here, but the right way would probably be to + # properly detect whether it is actually required. + CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CC="$PTHREAD_CC" + + # In order not to create several levels of indentation, we test + # the value of "$done" until we find the cure or run out of ideas. + done="no" + + # First, make sure the CFLAGS we added are actually accepted by our + # compiler. If not (and OS X's ld, for instance, does not accept -z), + # then we can't do this test. + if test x"$done" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to check for GCC pthread/shared inconsistencies" >&5 +$as_echo_n "checking whether to check for GCC pthread/shared inconsistencies... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +else + done=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + if test "x$done" = xyes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + fi + fi + + if test x"$done" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -pthread is sufficient with -shared" >&5 +$as_echo_n "checking whether -pthread is sufficient with -shared... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + done=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + if test "x$done" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + + # + # Linux gcc on some architectures such as mips/mipsel forgets + # about -lpthread + # + if test x"$done" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lpthread fixes that" >&5 +$as_echo_n "checking whether -lpthread fixes that... " >&6; } + LIBS="-lpthread $PTHREAD_LIBS $save_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + done=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + if test "x$done" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PTHREAD_LIBS="-lpthread $PTHREAD_LIBS" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + # + # FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc + # + if test x"$done" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc_r fixes that" >&5 +$as_echo_n "checking whether -lc_r fixes that... " >&6; } + LIBS="-lc_r $PTHREAD_LIBS $save_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + done=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + if test "x$done" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PTHREAD_LIBS="-lc_r $PTHREAD_LIBS" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + if test x"$done" = xno; then + # OK, we have run out of ideas + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Impossible to determine how to use pthreads with shared libraries" >&5 +$as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries" >&2;} + + # so it's not safe to assume that we may use pthreads + acx_pthread_ok=no + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether what we have so far is sufficient with -nostdlib" >&5 +$as_echo_n "checking whether what we have so far is sufficient with -nostdlib... " >&6; } + CFLAGS="-nostdlib $CFLAGS" + # we need c with nostdlib + LIBS="$LIBS -lc" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + done=yes +else + done=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + if test "x$done" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + + if test x"$done" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lpthread saves the day" >&5 +$as_echo_n "checking whether -lpthread saves the day... " >&6; } + LIBS="-lpthread $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + done=yes +else + done=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + if test "x$done" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PTHREAD_LIBS="$PTHREAD_LIBS -lpthread" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib" >&5 +$as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib" >&2;} + fi + fi + + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + CC="$save_CC" +else + PTHREAD_CC="$CC" +fi + + + + + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + +$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h + + : +else + acx_pthread_ok=no + +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking the location of hash_map" >&5 +$as_echo_n "checking the location of hash_map... " >&6; } + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + ac_cv_cxx_hash_map="" + # First try unordered_map, but not on gcc's before 4.2 -- I've + # seen unexplainable unordered_map bugs with -O2 on older gcc's. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)) + # error GCC too old for unordered_map + #endif + +int +main () +{ +/* no program body necessary */ + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + stl_hash_old_gcc=no +else + stl_hash_old_gcc=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + for location in unordered_map tr1/unordered_map; do + for namespace in std std::tr1; do + if test -z "$ac_cv_cxx_hash_map" -a "$stl_hash_old_gcc" != yes; then + # Some older gcc's have a buggy tr1, so test a bit of code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$location> +int +main () +{ +const ${namespace}::unordered_map t; + return t.find(5) == t.end(); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_cxx_hash_map="<$location>"; + ac_cv_cxx_hash_namespace="$namespace"; + ac_cv_cxx_hash_map_class="unordered_map"; +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + done + done + # Now try hash_map + for location in ext/hash_map hash_map; do + for namespace in __gnu_cxx "" std stdext; do + if test -z "$ac_cv_cxx_hash_map"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$location> +int +main () +{ +${namespace}::hash_map t + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_cxx_hash_map="<$location>"; + ac_cv_cxx_hash_namespace="$namespace"; + ac_cv_cxx_hash_map_class="hash_map"; +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + done + done + ac_cv_cxx_hash_set=`echo "$ac_cv_cxx_hash_map" | sed s/map/set/`; + ac_cv_cxx_hash_set_class=`echo "$ac_cv_cxx_hash_map_class" | sed s/map/set/`; + if test -n "$ac_cv_cxx_hash_map"; then + +$as_echo "#define HAVE_HASH_MAP 1" >>confdefs.h + + +$as_echo "#define HAVE_HASH_SET 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define HASH_MAP_H $ac_cv_cxx_hash_map +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define HASH_SET_H $ac_cv_cxx_hash_set +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define HASH_NAMESPACE $ac_cv_cxx_hash_namespace +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define HASH_MAP_CLASS $ac_cv_cxx_hash_map_class +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define HASH_SET_CLASS $ac_cv_cxx_hash_set_class +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_hash_map" >&5 +$as_echo "$ac_cv_cxx_hash_map" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 +$as_echo "" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find an STL hash_map" >&5 +$as_echo "$as_me: WARNING: could not find an STL hash_map" >&2;} + fi + + +# HACK: Make gtest's configure script pick up our copy of CFLAGS and CXXFLAGS, +# since the flags added by ACX_CHECK_SUNCC must be used when compiling gtest +# too. +export CFLAGS +export CXXFLAGS + + +subdirs="$subdirs gtest" + + +ac_config_files="$ac_config_files Makefile src/Makefile protobuf.pc protobuf-lite.pc" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GCC_TRUE}" && test -z "${GCC_FALSE}"; then + as_fn_error $? "conditional \"GCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_ZLIB_TRUE}" && test -z "${HAVE_ZLIB_FALSE}"; then + as_fn_error $? "conditional \"HAVE_ZLIB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_EXTERNAL_PROTOC_TRUE}" && test -z "${USE_EXTERNAL_PROTOC_FALSE}"; then + as_fn_error $? "conditional \"USE_EXTERNAL_PROTOC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by Protocol Buffers $as_me 2.5.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +Protocol Buffers config.status 2.5.0 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "protobuf.pc") CONFIG_FILES="$CONFIG_FILES protobuf.pc" ;; + "protobuf-lite.pc") CONFIG_FILES="$CONFIG_FILES protobuf-lite.pc" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi + +# +# CONFIG_SUBDIRS section. +# +if test "$no_recursion" != yes; then + + # Remove --cache-file, --srcdir, and --disable-option-checking arguments + # so they do not pile up. + ac_sub_configure_args= + ac_prev= + eval "set x $ac_configure_args" + shift + for ac_arg + do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case $ac_arg in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ + | --c=*) + ;; + --config-cache | -C) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + ;; + --disable-option-checking) + ;; + *) + case $ac_arg in + *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_sub_configure_args " '$ac_arg'" ;; + esac + done + + # Always prepend --prefix to ensure using the same prefix + # in subdir configurations. + ac_arg="--prefix=$prefix" + case $ac_arg in + *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" + + # Pass --silent + if test "$silent" = yes; then + ac_sub_configure_args="--silent $ac_sub_configure_args" + fi + + # Always prepend --disable-option-checking to silence warnings, since + # different subdirs can have different --enable and --with options. + ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args" + + ac_popdir=`pwd` + for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + test -d "$srcdir/$ac_dir" || continue + + ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" + $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5 + $as_echo "$ac_msg" >&6 + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + cd "$ac_dir" + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f "$ac_srcdir/configure.gnu"; then + ac_sub_configure=$ac_srcdir/configure.gnu + elif test -f "$ac_srcdir/configure"; then + ac_sub_configure=$ac_srcdir/configure + elif test -f "$ac_srcdir/configure.in"; then + # This should be Cygnus configure. + ac_sub_configure=$ac_aux_dir/configure + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5 +$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + # Make the cache file name correct relative to the subdirectory. + case $cache_file in + [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; + *) # Relative name. + ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 +$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} + # The eval makes quoting arguments work. + eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ + --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || + as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5 + fi + + cd "$ac_popdir" + done +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/cpp/thirdparty/protobuf-2.5.0/configure.ac b/cpp/thirdparty/protobuf-2.5.0/configure.ac new file mode 100644 index 0000000..b232529 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/configure.ac @@ -0,0 +1,150 @@ +## Process this file with autoconf to produce configure. +## In general, the safest way to proceed is to run ./autogen.sh + +AC_PREREQ(2.59) + +# Note: If you change the version, you must also update it in: +# * java/pom.xml +# * python/setup.py +# * src/google/protobuf/stubs/common.h +# * src/Makefile.am (Update -version-info for LDFLAGS if needed) +# +# 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],[2.5.0],[protobuf@googlegroups.com],[protobuf]) + +AM_MAINTAINER_MODE([enable]) + +AC_CONFIG_SRCDIR(src/google/protobuf/message.cc) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +# autoconf's default CXXFLAGS are usually "-g -O2". These aren't necessarily +# the best choice for libprotobuf. +AS_IF([test "x${ac_cv_env_CFLAGS_set}" = "x"], + [CFLAGS=""]) +AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"], + [CXXFLAGS=""]) + +AC_CANONICAL_TARGET + +AM_INIT_AUTOMAKE + +AC_ARG_WITH([zlib], + [AS_HELP_STRING([--with-zlib], + [include classes for streaming compressed data in and out @<:@default=check@:>@])], + [],[with_zlib=check]) + +AC_ARG_WITH([protoc], + [AS_HELP_STRING([--with-protoc=COMMAND], + [use the given protoc command instead of building a new one when building tests (useful for cross-compiling)])], + [],[with_protoc=no]) + +# Checks for programs. +AC_PROG_CC +AC_PROG_CXX +AC_LANG([C++]) +ACX_USE_SYSTEM_EXTENSIONS +AM_CONDITIONAL(GCC, test "$GCC" = yes) # let the Makefile know if we're gcc + +# test_util.cc takes forever to compile with GCC and optimization turned on. +AC_MSG_CHECKING([C++ compiler flags...]) +AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],[ + AS_IF([test "$GCC" = "yes"],[ + PROTOBUF_OPT_FLAG="-O2" + CXXFLAGS="${CXXFLAGS} -g" + ]) + + # Protocol Buffers contains several checks that are intended to be used only + # for debugging and which might hurt performance. Most users are probably + # end users who don't want these checks, so add -DNDEBUG by default. + CXXFLAGS="$CXXFLAGS -DNDEBUG" + + AC_MSG_RESULT([use default: $PROTOBUF_OPT_FLAG $CXXFLAGS]) +],[ + AC_MSG_RESULT([use user-supplied: $CXXFLAGS]) +]) + +AC_SUBST(PROTOBUF_OPT_FLAG) + +ACX_CHECK_SUNCC + +# Have to do libtool after SUNCC, other wise it "helpfully" adds Crun Cstd +# to the link +AC_PROG_LIBTOOL + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h stdlib.h unistd.h]) + +# Checks for library functions. +AC_FUNC_MEMCMP +AC_FUNC_STRTOD +AC_CHECK_FUNCS([ftruncate memset mkdir strchr strerror strtol]) + +# Check for zlib. +HAVE_ZLIB=0 +AS_IF([test "$with_zlib" != no], [ + AC_MSG_CHECKING([zlib version]) + + # First check the zlib header version. + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1204) + # error zlib version too old + #endif + ]], [])], [ + AC_MSG_RESULT([ok (1.2.0.4 or later)]) + + # Also need to add -lz to the linker flags and make sure this succeeds. + AC_SEARCH_LIBS([zlibVersion], [z], [ + AC_DEFINE([HAVE_ZLIB], [1], [Enable classes using zlib compression.]) + HAVE_ZLIB=1 + ], [ + AS_IF([test "$with_zlib" != check], [ + AC_MSG_FAILURE([--with-zlib was given, but no working zlib library was found]) + ]) + ]) + ], [ + AS_IF([test "$with_zlib" = check], [ + AC_MSG_RESULT([headers missing or too old (requires 1.2.0.4)]) + ], [ + AC_MSG_FAILURE([--with-zlib was given, but zlib headers were not present or were too old (requires 1.2.0.4)]) + ]) + ]) +]) +AM_CONDITIONAL([HAVE_ZLIB], [test $HAVE_ZLIB = 1]) + +AS_IF([test "$with_protoc" != "no"], [ + PROTOC=$with_protoc + AS_IF([test "$with_protoc" = "yes"], [ + # No argument given. Use system protoc. + PROTOC=protoc + ]) + AS_IF([echo "$PROTOC" | grep -q '^@<:@^/@:>@.*/'], [ + # Does not start with a slash, but contains a slash. So, it's a relative + # path (as opposed to an absolute path or an executable in $PATH). + # Since it will actually be executed from the src directory, prefix with + # the current directory. We also insert $ac_top_build_prefix in case this + # is a nested package and --with-protoc was actually given on the outer + # package's configure script. + PROTOC=`pwd`/${ac_top_build_prefix}$PROTOC + ]) + AC_SUBST([PROTOC]) +]) +AM_CONDITIONAL([USE_EXTERNAL_PROTOC], [test "$with_protoc" != "no"]) + +ACX_PTHREAD +AC_CXX_STL_HASH + +# HACK: Make gtest's configure script pick up our copy of CFLAGS and CXXFLAGS, +# since the flags added by ACX_CHECK_SUNCC must be used when compiling gtest +# too. +export CFLAGS +export CXXFLAGS +AC_CONFIG_SUBDIRS([gtest]) + +AC_CONFIG_FILES([Makefile src/Makefile protobuf.pc protobuf-lite.pc]) +AC_OUTPUT diff --git a/cpp/thirdparty/protobuf-2.5.0/depcomp b/cpp/thirdparty/protobuf-2.5.0/depcomp new file mode 100755 index 0000000..bd0ac08 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/depcomp @@ -0,0 +1,688 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2011-12-04.11; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/ \1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/ / + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/cpp/thirdparty/protobuf-2.5.0/editors/README.txt b/cpp/thirdparty/protobuf-2.5.0/editors/README.txt new file mode 100644 index 0000000..3e9fc79 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/editors/README.txt @@ -0,0 +1,5 @@ +This directory contains syntax highlighting and configuration files for editors +to properly display Protocol Buffer files. + +See each file's header comment for directions on how to use it with the +appropriate editor. diff --git a/cpp/thirdparty/protobuf-2.5.0/editors/proto.vim b/cpp/thirdparty/protobuf-2.5.0/editors/proto.vim new file mode 100644 index 0000000..2a25fa6 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/editors/proto.vim @@ -0,0 +1,105 @@ +" Protocol Buffers - Google's data interchange format +" Copyright 2008 Google Inc. All rights reserved. +" http://code.google.com/p/protobuf/ +" +" Redistribution and use in source and binary forms, with or without +" modification, are permitted provided that the following conditions are +" met: +" +" * Redistributions of source code must retain the above copyright +" notice, this list of conditions and the following disclaimer. +" * Redistributions in binary form must reproduce the above +" copyright notice, this list of conditions and the following disclaimer +" in the documentation and/or other materials provided with the +" distribution. +" * Neither the name of Google Inc. nor the names of its +" contributors may be used to endorse or promote products derived from +" this software without specific prior written permission. +" +" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +" This is the Vim syntax file for Google Protocol Buffers. +" +" Usage: +" +" 1. cp proto.vim ~/.vim/syntax/ +" 2. Add the following to ~/.vimrc: +" +" augroup filetype +" au! BufRead,BufNewFile *.proto setfiletype proto +" augroup end +" +" Or just create a new file called ~/.vim/ftdetect/proto.vim with the +" previous lines on it. + +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +syn case match + +syn keyword pbTodo contained TODO FIXME XXX +syn cluster pbCommentGrp contains=pbTodo + +syn keyword pbSyntax syntax import option +syn keyword pbStructure package message group +syn keyword pbRepeat optional required repeated +syn keyword pbDefault default +syn keyword pbExtend extend extensions to max +syn keyword pbRPC service rpc returns + +syn keyword pbType int32 int64 uint32 uint64 sint32 sint64 +syn keyword pbType fixed32 fixed64 sfixed32 sfixed64 +syn keyword pbType float double bool string bytes +syn keyword pbTypedef enum +syn keyword pbBool true false + +syn match pbInt /-\?\<\d\+\>/ +syn match pbInt /\<0[xX]\x+\>/ +syn match pbFloat /\<-\?\d*\(\.\d*\)\?/ +syn region pbComment start="\/\*" end="\*\/" contains=@pbCommentGrp +syn region pbComment start="//" skip="\\$" end="$" keepend contains=@pbCommentGrp +syn region pbString start=/"/ skip=/\\./ end=/"/ +syn region pbString start=/'/ skip=/\\./ end=/'/ + +if version >= 508 || !exists("did_proto_syn_inits") + if version < 508 + let did_proto_syn_inits = 1 + command -nargs=+ HiLink hi link + else + command -nargs=+ HiLink hi def link + endif + + HiLink pbTodo Todo + + HiLink pbSyntax Include + HiLink pbStructure Structure + HiLink pbRepeat Repeat + HiLink pbDefault Keyword + HiLink pbExtend Keyword + HiLink pbRPC Keyword + HiLink pbType Type + HiLink pbTypedef Typedef + HiLink pbBool Boolean + + HiLink pbInt Number + HiLink pbFloat Float + HiLink pbComment Comment + HiLink pbString String + + delcommand HiLink +endif + +let b:current_syntax = "proto" diff --git a/cpp/thirdparty/protobuf-2.5.0/editors/protobuf-mode.el b/cpp/thirdparty/protobuf-2.5.0/editors/protobuf-mode.el new file mode 100644 index 0000000..09aecc9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/editors/protobuf-mode.el @@ -0,0 +1,220 @@ +;;; protobuf-mode.el --- major mode for editing protocol buffers. + +;; Author: Alexandre Vassalotti +;; Created: 23-Apr-2009 +;; Version: 0.3 +;; Keywords: google protobuf languages + +;; 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. + +;;; Commentary: + +;; Installation: +;; - Put `protobuf-mode.el' in your Emacs load-path. +;; - Add this line to your .emacs file: +;; (require 'protobuf-mode) +;; +;; You can customize this mode just like any mode derived from CC Mode. If +;; you want to add customizations specific to protobuf-mode, you can use the +;; `protobuf-mode-hook'. For example, the following would make protocol-mode +;; use 2-space indentation: +;; +;; (defconst my-protobuf-style +;; '((c-basic-offset . 2) +;; (indent-tabs-mode . nil))) +;; +;; (add-hook 'protobuf-mode-hook +;; (lambda () (c-add-style "my-style" my-protobuf-style t))) +;; +;; Refer to the documentation of CC Mode for more information about +;; customization details and how to use this mode. +;; +;; TODO: +;; - Make highlighting for enum values work properly. +;; - Fix the parser to recognize extensions as identifiers and not +;; as casts. +;; - Improve the parsing of option assignment lists. For example: +;; optional int32 foo = 1 [(my_field_option) = 4.5]; +;; - Add support for fully-qualified identifiers (e.g., with a leading "."). + +;;; Code: + +(require 'cc-mode) + +(eval-when-compile + (require 'cc-langs) + (require 'cc-fonts)) + +;; This mode does not inherit properties from other modes. So, we do not use +;; the usual `c-add-language' function. +(eval-and-compile + (put 'protobuf-mode 'c-mode-prefix "protobuf-")) + +;; The following code uses of the `c-lang-defconst' macro define syntactic +;; features of protocol buffer language. Refer to the documentation in the +;; cc-langs.el file for information about the meaning of the -kwds variables. + +(c-lang-defconst c-primitive-type-kwds + protobuf '("double" "float" "int32" "int64" "uint32" "uint64" "sint32" + "sint64" "fixed32" "fixed64" "sfixed32" "sfixed64" "bool" + "string" "bytes" "group")) + +(c-lang-defconst c-modifier-kwds + protobuf '("required" "optional" "repeated")) + +(c-lang-defconst c-class-decl-kwds + protobuf '("message" "enum" "service")) + +(c-lang-defconst c-constant-kwds + protobuf '("true" "false")) + +(c-lang-defconst c-other-decl-kwds + protobuf '("package" "import")) + +(c-lang-defconst c-other-kwds + protobuf '("default" "max")) + +(c-lang-defconst c-identifier-ops + ;; Handle extended identifiers like google.protobuf.MessageOptions + protobuf '((left-assoc "."))) + +;; The following keywords do not fit well in keyword classes defined by +;; cc-mode. So, we approximate as best we can. + +(c-lang-defconst c-type-list-kwds + protobuf '("extensions" "to")) + +(c-lang-defconst c-typeless-decl-kwds + protobuf '("extend" "rpc" "option" "returns")) + + +;; Here we remove default syntax for loops, if-statements and other C +;; syntactic features that are not supported by the protocol buffer language. + +(c-lang-defconst c-brace-list-decl-kwds + ;; Remove syntax for C-style enumerations. + protobuf nil) + +(c-lang-defconst c-block-stmt-1-kwds + ;; Remove syntax for "do" and "else" keywords. + protobuf nil) + +(c-lang-defconst c-block-stmt-2-kwds + ;; Remove syntax for "for", "if", "switch" and "while" keywords. + protobuf nil) + +(c-lang-defconst c-simple-stmt-kwds + ;; Remove syntax for "break", "continue", "goto" and "return" keywords. + protobuf nil) + +(c-lang-defconst c-paren-stmt-kwds + ;; Remove special case for the "(;;)" in for-loops. + protobuf nil) + +(c-lang-defconst c-label-kwds + ;; Remove case label syntax for the "case" and "default" keywords. + protobuf nil) + +(c-lang-defconst c-before-label-kwds + ;; Remove special case for the label in a goto statement. + protobuf nil) + +(c-lang-defconst c-cpp-matchers + ;; Disable all the C preprocessor syntax. + protobuf nil) + +(c-lang-defconst c-decl-prefix-re + ;; Same as for C, except it does not match "(". This is needed for disabling + ;; the syntax for casts. + protobuf "\\([\{\};,]+\\)") + + +;; Add support for variable levels of syntax highlighting. + +(defconst protobuf-font-lock-keywords-1 (c-lang-const c-matchers-1 protobuf) + "Minimal highlighting for protobuf-mode.") + +(defconst protobuf-font-lock-keywords-2 (c-lang-const c-matchers-2 protobuf) + "Fast normal highlighting for protobuf-mode.") + +(defconst protobuf-font-lock-keywords-3 (c-lang-const c-matchers-3 protobuf) + "Accurate normal highlighting for protobuf-mode.") + +(defvar protobuf-font-lock-keywords protobuf-font-lock-keywords-3 + "Default expressions to highlight in protobuf-mode.") + +;; Our syntax table is auto-generated from the keyword classes we defined +;; previously with the `c-lang-const' macro. +(defvar protobuf-mode-syntax-table nil + "Syntax table used in protobuf-mode buffers.") +(or protobuf-mode-syntax-table + (setq protobuf-mode-syntax-table + (funcall (c-lang-const c-make-mode-syntax-table protobuf)))) + +(defvar protobuf-mode-abbrev-table nil + "Abbreviation table used in protobuf-mode buffers.") + +(defvar protobuf-mode-map nil + "Keymap used in protobuf-mode buffers.") +(or protobuf-mode-map + (setq protobuf-mode-map (c-make-inherited-keymap))) + +(easy-menu-define protobuf-menu protobuf-mode-map + "Protocol Buffers Mode Commands" + (cons "Protocol Buffers" (c-lang-const c-mode-menu protobuf))) + +;;;###autoload (add-to-list 'auto-mode-alist '("\\.proto\\'" . protobuf-mode)) + +;;;###autoload +(defun protobuf-mode () + "Major mode for editing Protocol Buffers description language. + +The hook `c-mode-common-hook' is run with no argument at mode +initialization, then `protobuf-mode-hook'. + +Key bindings: +\\{protobuf-mode-map}" + (interactive) + (kill-all-local-variables) + (set-syntax-table protobuf-mode-syntax-table) + (setq major-mode 'protobuf-mode + mode-name "Protocol-Buffers" + local-abbrev-table protobuf-mode-abbrev-table + abbrev-mode t) + (use-local-map protobuf-mode-map) + (c-initialize-cc-mode t) + (if (fboundp 'c-make-emacs-variables-local) + (c-make-emacs-variables-local)) + (c-init-language-vars protobuf-mode) + (c-common-init 'protobuf-mode) + (easy-menu-add protobuf-menu) + (c-run-mode-hooks 'c-mode-common-hook 'protobuf-mode-hook) + (c-update-modeline)) + +(provide 'protobuf-mode) + +;;; protobuf-mode.el ends here diff --git a/cpp/thirdparty/protobuf-2.5.0/examples/AddPerson.java b/cpp/thirdparty/protobuf-2.5.0/examples/AddPerson.java new file mode 100644 index 0000000..ca5ac27 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/examples/AddPerson.java @@ -0,0 +1,95 @@ +// See README.txt for information and build instructions. + +import com.example.tutorial.AddressBookProtos.AddressBook; +import com.example.tutorial.AddressBookProtos.Person; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.PrintStream; + +class AddPerson { + // This function fills in a Person message based on user input. + static Person PromptForAddress(BufferedReader stdin, + PrintStream stdout) throws IOException { + Person.Builder person = Person.newBuilder(); + + stdout.print("Enter person ID: "); + person.setId(Integer.valueOf(stdin.readLine())); + + stdout.print("Enter name: "); + person.setName(stdin.readLine()); + + stdout.print("Enter email address (blank for none): "); + String email = stdin.readLine(); + if (email.length() > 0) { + person.setEmail(email); + } + + while (true) { + stdout.print("Enter a phone number (or leave blank to finish): "); + String number = stdin.readLine(); + if (number.length() == 0) { + break; + } + + Person.PhoneNumber.Builder phoneNumber = + Person.PhoneNumber.newBuilder().setNumber(number); + + stdout.print("Is this a mobile, home, or work phone? "); + String type = stdin.readLine(); + if (type.equals("mobile")) { + phoneNumber.setType(Person.PhoneType.MOBILE); + } else if (type.equals("home")) { + phoneNumber.setType(Person.PhoneType.HOME); + } else if (type.equals("work")) { + phoneNumber.setType(Person.PhoneType.WORK); + } else { + stdout.println("Unknown phone type. Using default."); + } + + person.addPhone(phoneNumber); + } + + return person.build(); + } + + // Main function: Reads the entire address book from a file, + // adds one person based on user input, then writes it back out to the same + // file. + public static void main(String[] args) throws Exception { + if (args.length != 1) { + System.err.println("Usage: AddPerson ADDRESS_BOOK_FILE"); + System.exit(-1); + } + + AddressBook.Builder addressBook = AddressBook.newBuilder(); + + // Read the existing address book. + try { + FileInputStream input = new FileInputStream(args[0]); + try { + addressBook.mergeFrom(input); + } finally { + try { input.close(); } catch (Throwable ignore) {} + } + } catch (FileNotFoundException e) { + System.out.println(args[0] + ": File not found. Creating a new file."); + } + + // Add an address. + addressBook.addPerson( + PromptForAddress(new BufferedReader(new InputStreamReader(System.in)), + System.out)); + + // Write the new address book back to disk. + FileOutputStream output = new FileOutputStream(args[0]); + try { + addressBook.build().writeTo(output); + } finally { + output.close(); + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/examples/ListPeople.java b/cpp/thirdparty/protobuf-2.5.0/examples/ListPeople.java new file mode 100644 index 0000000..b2f153a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/examples/ListPeople.java @@ -0,0 +1,50 @@ +// See README.txt for information and build instructions. + +import com.example.tutorial.AddressBookProtos.AddressBook; +import com.example.tutorial.AddressBookProtos.Person; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.PrintStream; + +class ListPeople { + // Iterates though all people in the AddressBook and prints info about them. + static void Print(AddressBook addressBook) { + for (Person person: addressBook.getPersonList()) { + System.out.println("Person ID: " + person.getId()); + System.out.println(" Name: " + person.getName()); + if (person.hasEmail()) { + System.out.println(" E-mail address: " + person.getEmail()); + } + + for (Person.PhoneNumber phoneNumber : person.getPhoneList()) { + switch (phoneNumber.getType()) { + case MOBILE: + System.out.print(" Mobile phone #: "); + break; + case HOME: + System.out.print(" Home phone #: "); + break; + case WORK: + System.out.print(" Work phone #: "); + break; + } + System.out.println(phoneNumber.getNumber()); + } + } + } + + // Main function: Reads the entire address book from a file and prints all + // the information inside. + public static void main(String[] args) throws Exception { + if (args.length != 1) { + System.err.println("Usage: ListPeople ADDRESS_BOOK_FILE"); + System.exit(-1); + } + + // Read the existing address book. + AddressBook addressBook = + AddressBook.parseFrom(new FileInputStream(args[0])); + + Print(addressBook); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/examples/Makefile b/cpp/thirdparty/protobuf-2.5.0/examples/Makefile new file mode 100644 index 0000000..8dc9083 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/examples/Makefile @@ -0,0 +1,58 @@ +# See README.txt. + +.PHONY: all cpp java python clean + +all: cpp java python + +cpp: add_person_cpp list_people_cpp +java: add_person_java list_people_java +python: add_person_python list_people_python + +clean: + rm -f add_person_cpp list_people_cpp add_person_java list_people_java add_person_python list_people_python + rm -f javac_middleman AddPerson*.class ListPeople*.class com/example/tutorial/*.class + rm -f protoc_middleman addressbook.pb.cc addressbook.pb.h addressbook_pb2.py com/example/tutorial/AddressBookProtos.java + rm -f *.pyc + rmdir com/example/tutorial 2>/dev/null || true + rmdir com/example 2>/dev/null || true + rmdir com 2>/dev/null || true + +protoc_middleman: addressbook.proto + protoc --cpp_out=. --java_out=. --python_out=. addressbook.proto + @touch protoc_middleman + +add_person_cpp: add_person.cc protoc_middleman + pkg-config --cflags protobuf # fails if protobuf is not installed + c++ add_person.cc addressbook.pb.cc -o add_person_cpp `pkg-config --cflags --libs protobuf` + +list_people_cpp: list_people.cc protoc_middleman + pkg-config --cflags protobuf # fails if protobuf is not installed + c++ list_people.cc addressbook.pb.cc -o list_people_cpp `pkg-config --cflags --libs protobuf` + +javac_middleman: AddPerson.java ListPeople.java protoc_middleman + javac AddPerson.java ListPeople.java com/example/tutorial/AddressBookProtos.java + @touch javac_middleman + +add_person_java: javac_middleman + @echo "Writing shortcut script add_person_java..." + @echo '#! /bin/sh' > add_person_java + @echo 'java -classpath .:$$CLASSPATH AddPerson "$$@"' >> add_person_java + @chmod +x add_person_java + +list_people_java: javac_middleman + @echo "Writing shortcut script list_people_java..." + @echo '#! /bin/sh' > list_people_java + @echo 'java -classpath .:$$CLASSPATH ListPeople "$$@"' >> list_people_java + @chmod +x list_people_java + +add_person_python: add_person.py protoc_middleman + @echo "Writing shortcut script add_person_python..." + @echo '#! /bin/sh' > add_person_python + @echo './add_person.py "$$@"' >> add_person_python + @chmod +x add_person_python + +list_people_python: list_people.py protoc_middleman + @echo "Writing shortcut script list_people_python..." + @echo '#! /bin/sh' > list_people_python + @echo './list_people.py "$$@"' >> list_people_python + @chmod +x list_people_python diff --git a/cpp/thirdparty/protobuf-2.5.0/examples/README.txt b/cpp/thirdparty/protobuf-2.5.0/examples/README.txt new file mode 100644 index 0000000..d22bf06 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/examples/README.txt @@ -0,0 +1,29 @@ +This directory contains example code that uses Protocol Buffers to manage an +address book. Two programs are provided, each with three different +implementations, one written in each of C++, Java, and Python. The add_person +example adds a new person to an address book, prompting the user to input +the person's information. The list_people example lists people already in the +address book. The examples use the exact same format in all three languages, +so you can, for example, use add_person_java to create an address book and then +use list_people_python to read it. + +You must install the protobuf package before you can build these. + +To build all the examples (on a unix-like system), simply run "make". This +creates the following executable files in the current directory: + add_person_cpp list_people_cpp + add_person_java list_people_java + add_person_python list_people_python + +If you only want to compile examples in one language, use "make cpp"*, +"make java", or "make python". + +All of these programs simply take an address book file as their parameter. +The add_person programs will create the file if it doesn't already exist. + +These examples are part of the Protocol Buffers tutorial, located at: + http://code.google.com/apis/protocolbuffers/docs/tutorials.html + +* Note that on some platforms you may have to edit the Makefile and remove +"-lpthread" from the linker commands (perhaps replacing it with something else). +We didn't do this automatically because we wanted to keep the example simple. diff --git a/cpp/thirdparty/protobuf-2.5.0/examples/add_person.cc b/cpp/thirdparty/protobuf-2.5.0/examples/add_person.cc new file mode 100644 index 0000000..b9ca44f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/examples/add_person.cc @@ -0,0 +1,95 @@ +// See README.txt for information and build instructions. + +#include +#include +#include +#include "addressbook.pb.h" +using namespace std; + +// This function fills in a Person message based on user input. +void PromptForAddress(tutorial::Person* person) { + cout << "Enter person ID number: "; + int id; + cin >> id; + person->set_id(id); + cin.ignore(256, '\n'); + + cout << "Enter name: "; + getline(cin, *person->mutable_name()); + + cout << "Enter email address (blank for none): "; + string email; + getline(cin, email); + if (!email.empty()) { + person->set_email(email); + } + + while (true) { + cout << "Enter a phone number (or leave blank to finish): "; + string number; + getline(cin, number); + if (number.empty()) { + break; + } + + tutorial::Person::PhoneNumber* phone_number = person->add_phone(); + phone_number->set_number(number); + + cout << "Is this a mobile, home, or work phone? "; + string type; + getline(cin, type); + if (type == "mobile") { + phone_number->set_type(tutorial::Person::MOBILE); + } else if (type == "home") { + phone_number->set_type(tutorial::Person::HOME); + } else if (type == "work") { + phone_number->set_type(tutorial::Person::WORK); + } else { + cout << "Unknown phone type. Using default." << endl; + } + } +} + +// Main function: Reads the entire address book from a file, +// adds one person based on user input, then writes it back out to the same +// file. +int main(int argc, char* argv[]) { + // Verify that the version of the library that we linked against is + // compatible with the version of the headers we compiled against. + GOOGLE_PROTOBUF_VERIFY_VERSION; + + if (argc != 2) { + cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl; + return -1; + } + + tutorial::AddressBook address_book; + + { + // Read the existing address book. + fstream input(argv[1], ios::in | ios::binary); + if (!input) { + cout << argv[1] << ": File not found. Creating a new file." << endl; + } else if (!address_book.ParseFromIstream(&input)) { + cerr << "Failed to parse address book." << endl; + return -1; + } + } + + // Add an address. + PromptForAddress(address_book.add_person()); + + { + // Write the new address book back to disk. + fstream output(argv[1], ios::out | ios::trunc | ios::binary); + if (!address_book.SerializeToOstream(&output)) { + cerr << "Failed to write address book." << endl; + return -1; + } + } + + // Optional: Delete all global objects allocated by libprotobuf. + google::protobuf::ShutdownProtobufLibrary(); + + return 0; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/examples/add_person.py b/cpp/thirdparty/protobuf-2.5.0/examples/add_person.py new file mode 100755 index 0000000..78e5696 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/examples/add_person.py @@ -0,0 +1,58 @@ +#! /usr/bin/python + +# See README.txt for information and build instructions. + +import addressbook_pb2 +import sys + +# This function fills in a Person message based on user input. +def PromptForAddress(person): + person.id = int(raw_input("Enter person ID number: ")) + person.name = raw_input("Enter name: ") + + email = raw_input("Enter email address (blank for none): ") + if email != "": + person.email = email + + while True: + number = raw_input("Enter a phone number (or leave blank to finish): ") + if number == "": + break + + phone_number = person.phone.add() + phone_number.number = number + + type = raw_input("Is this a mobile, home, or work phone? ") + if type == "mobile": + phone_number.type = addressbook_pb2.Person.MOBILE + elif type == "home": + phone_number.type = addressbook_pb2.Person.HOME + elif type == "work": + phone_number.type = addressbook_pb2.Person.WORK + else: + print "Unknown phone type; leaving as default value." + +# Main procedure: Reads the entire address book from a file, +# adds one person based on user input, then writes it back out to the same +# file. +if len(sys.argv) != 2: + print "Usage:", sys.argv[0], "ADDRESS_BOOK_FILE" + sys.exit(-1) + +address_book = addressbook_pb2.AddressBook() + +# Read the existing address book. +try: + f = open(sys.argv[1], "rb") + address_book.ParseFromString(f.read()) + f.close() +except IOError: + print sys.argv[1] + ": File not found. Creating a new file." + +# Add an address. +PromptForAddress(address_book.person.add()) + +# Write the new address book back to disk. +f = open(sys.argv[1], "wb") +f.write(address_book.SerializeToString()) +f.close() diff --git a/cpp/thirdparty/protobuf-2.5.0/examples/addressbook.proto b/cpp/thirdparty/protobuf-2.5.0/examples/addressbook.proto new file mode 100644 index 0000000..b14829e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/examples/addressbook.proto @@ -0,0 +1,30 @@ +// See README.txt for information and build instructions. + +package tutorial; + +option java_package = "com.example.tutorial"; +option java_outer_classname = "AddressBookProtos"; + +message Person { + required string name = 1; + required int32 id = 2; // Unique ID number for this person. + optional string email = 3; + + enum PhoneType { + MOBILE = 0; + HOME = 1; + WORK = 2; + } + + message PhoneNumber { + required string number = 1; + optional PhoneType type = 2 [default = HOME]; + } + + repeated PhoneNumber phone = 4; +} + +// Our address book file is just one of these. +message AddressBook { + repeated Person person = 1; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/examples/list_people.cc b/cpp/thirdparty/protobuf-2.5.0/examples/list_people.cc new file mode 100644 index 0000000..5363152 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/examples/list_people.cc @@ -0,0 +1,68 @@ +// See README.txt for information and build instructions. + +#include +#include +#include +#include "addressbook.pb.h" +using namespace std; + +// Iterates though all people in the AddressBook and prints info about them. +void ListPeople(const tutorial::AddressBook& address_book) { + for (int i = 0; i < address_book.person_size(); i++) { + const tutorial::Person& person = address_book.person(i); + + cout << "Person ID: " << person.id() << endl; + cout << " Name: " << person.name() << endl; + if (person.has_email()) { + cout << " E-mail address: " << person.email() << endl; + } + + for (int j = 0; j < person.phone_size(); j++) { + const tutorial::Person::PhoneNumber& phone_number = person.phone(j); + + switch (phone_number.type()) { + case tutorial::Person::MOBILE: + cout << " Mobile phone #: "; + break; + case tutorial::Person::HOME: + cout << " Home phone #: "; + break; + case tutorial::Person::WORK: + cout << " Work phone #: "; + break; + } + cout << phone_number.number() << endl; + } + } +} + +// Main function: Reads the entire address book from a file and prints all +// the information inside. +int main(int argc, char* argv[]) { + // Verify that the version of the library that we linked against is + // compatible with the version of the headers we compiled against. + GOOGLE_PROTOBUF_VERIFY_VERSION; + + if (argc != 2) { + cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl; + return -1; + } + + tutorial::AddressBook address_book; + + { + // Read the existing address book. + fstream input(argv[1], ios::in | ios::binary); + if (!address_book.ParseFromIstream(&input)) { + cerr << "Failed to parse address book." << endl; + return -1; + } + } + + ListPeople(address_book); + + // Optional: Delete all global objects allocated by libprotobuf. + google::protobuf::ShutdownProtobufLibrary(); + + return 0; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/examples/list_people.py b/cpp/thirdparty/protobuf-2.5.0/examples/list_people.py new file mode 100755 index 0000000..f9f36b9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/examples/list_people.py @@ -0,0 +1,38 @@ +#! /usr/bin/python + +# See README.txt for information and build instructions. + +import addressbook_pb2 +import sys + +# Iterates though all people in the AddressBook and prints info about them. +def ListPeople(address_book): + for person in address_book.person: + print "Person ID:", person.id + print " Name:", person.name + if person.HasField('email'): + print " E-mail address:", person.email + + for phone_number in person.phone: + if phone_number.type == addressbook_pb2.Person.MOBILE: + print " Mobile phone #:", + elif phone_number.type == addressbook_pb2.Person.HOME: + print " Home phone #:", + elif phone_number.type == addressbook_pb2.Person.WORK: + print " Work phone #:", + print phone_number.number + +# Main procedure: Reads the entire address book from a file and prints all +# the information inside. +if len(sys.argv) != 2: + print "Usage:", sys.argv[0], "ADDRESS_BOOK_FILE" + sys.exit(-1) + +address_book = addressbook_pb2.AddressBook() + +# Read the existing address book. +f = open(sys.argv[1], "rb") +address_book.ParseFromString(f.read()) +f.close() + +ListPeople(address_book) diff --git a/cpp/thirdparty/protobuf-2.5.0/generate_descriptor_proto.sh b/cpp/thirdparty/protobuf-2.5.0/generate_descriptor_proto.sh new file mode 100755 index 0000000..07219dc --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/generate_descriptor_proto.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +# Run this script to regenerate descriptor.pb.{h,cc} after the protocol +# compiler changes. Since these files are compiled into the protocol compiler +# itself, they cannot be generated automatically by a make rule. "make check" +# will fail if these files do not match what the protocol compiler would +# generate. +# +# HINT: Flags passed to generate_descriptor_proto.sh will be passed directly +# to make when building protoc. This is particularly useful for passing +# -j4 to run 4 jobs simultaneously. + +if test ! -e src/google/protobuf/stubs/common.h; then + cat >&2 << __EOF__ +Could not find source code. Make sure you are running this script from the +root of the distribution tree. +__EOF__ + exit 1 +fi + +if test ! -e src/Makefile; then + cat >&2 << __EOF__ +Could not find src/Makefile. You must run ./configure (and perhaps +./autogen.sh) first. +__EOF__ + exit 1 +fi + +cd src +make $@ protoc && + ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:. google/protobuf/descriptor.proto && \ + ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:. google/protobuf/compiler/plugin.proto +cd .. diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/CHANGES b/cpp/thirdparty/protobuf-2.5.0/gtest/CHANGES new file mode 100644 index 0000000..5919245 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/CHANGES @@ -0,0 +1,130 @@ +Changes for 1.6.0: + +* New feature: ADD_FAILURE_AT() for reporting a test failure at the + given source location -- useful for writing testing utilities. +* New feature: the universal value printer is moved from Google Mock + to Google Test. +* New feature: type parameters and value parameters are reported in + the XML report now. +* A gtest_disable_pthreads CMake option. +* Colored output works in GNU Screen sessions now. +* Parameters of value-parameterized tests are now printed in the + textual output. +* Failures from ad hoc test assertions run before RUN_ALL_TESTS() are + now correctly reported. +* Arguments of ASSERT_XY and EXPECT_XY no longer need to support << to + ostream. +* More complete handling of exceptions. +* GTEST_ASSERT_XY can be used instead of ASSERT_XY in case the latter + name is already used by another library. +* --gtest_catch_exceptions is now true by default, allowing a test + program to continue after an exception is thrown. +* Value-parameterized test fixtures can now derive from Test and + WithParamInterface separately, easing conversion of legacy tests. +* Death test messages are clearly marked to make them more + distinguishable from other messages. +* Compatibility fixes for Android, Google Native Client, MinGW, HP UX, + PowerPC, Lucid autotools, libCStd, Sun C++, Borland C++ Builder (Code Gear), + IBM XL C++ (Visual Age C++), and C++0x. +* Bug fixes and implementation clean-ups. +* Potentially incompatible changes: disables the harmful 'make install' + command in autotools. + +Changes for 1.5.0: + + * New feature: assertions can be safely called in multiple threads + where the pthreads library is available. + * New feature: predicates used inside EXPECT_TRUE() and friends + can now generate custom failure messages. + * New feature: Google Test can now be compiled as a DLL. + * New feature: fused source files are included. + * New feature: prints help when encountering unrecognized Google Test flags. + * Experimental feature: CMake build script (requires CMake 2.6.4+). + * Experimental feature: the Pump script for meta programming. + * double values streamed to an assertion are printed with enough precision + to differentiate any two different values. + * Google Test now works on Solaris and AIX. + * Build and test script improvements. + * Bug fixes and implementation clean-ups. + + Potentially breaking changes: + + * Stopped supporting VC++ 7.1 with exceptions disabled. + * Dropped support for 'make install'. + +Changes for 1.4.0: + + * New feature: the event listener API + * New feature: test shuffling + * New feature: the XML report format is closer to junitreport and can + be parsed by Hudson now. + * New feature: when a test runs under Visual Studio, its failures are + integrated in the IDE. + * New feature: /MD(d) versions of VC++ projects. + * New feature: elapsed time for the tests is printed by default. + * New feature: comes with a TR1 tuple implementation such that Boost + is no longer needed for Combine(). + * New feature: EXPECT_DEATH_IF_SUPPORTED macro and friends. + * New feature: the Xcode project can now produce static gtest + libraries in addition to a framework. + * Compatibility fixes for Solaris, Cygwin, minGW, Windows Mobile, + Symbian, gcc, and C++Builder. + * Bug fixes and implementation clean-ups. + +Changes for 1.3.0: + + * New feature: death tests on Windows, Cygwin, and Mac. + * New feature: ability to use Google Test assertions in other testing + frameworks. + * New feature: ability to run disabled test via + --gtest_also_run_disabled_tests. + * New feature: the --help flag for printing the usage. + * New feature: access to Google Test flag values in user code. + * New feature: a script that packs Google Test into one .h and one + .cc file for easy deployment. + * New feature: support for distributing test functions to multiple + machines (requires support from the test runner). + * Bug fixes and implementation clean-ups. + +Changes for 1.2.1: + + * Compatibility fixes for Linux IA-64 and IBM z/OS. + * Added support for using Boost and other TR1 implementations. + * Changes to the build scripts to support upcoming release of Google C++ + Mocking Framework. + * Added Makefile to the distribution package. + * Improved build instructions in README. + +Changes for 1.2.0: + + * New feature: value-parameterized tests. + * New feature: the ASSERT/EXPECT_(NON)FATAL_FAILURE(_ON_ALL_THREADS) + macros. + * Changed the XML report format to match JUnit/Ant's. + * Added tests to the Xcode project. + * Added scons/SConscript for building with SCons. + * Added src/gtest-all.cc for building Google Test from a single file. + * Fixed compatibility with Solaris and z/OS. + * Enabled running Python tests on systems with python 2.3 installed, + e.g. Mac OS X 10.4. + * Bug fixes. + +Changes for 1.1.0: + + * New feature: type-parameterized tests. + * New feature: exception assertions. + * New feature: printing elapsed time of tests. + * Improved the robustness of death tests. + * Added an Xcode project and samples. + * Adjusted the output format on Windows to be understandable by Visual Studio. + * Minor bug fixes. + +Changes for 1.0.1: + + * Added project files for Visual Studio 7.1. + * Fixed issues with compiling on Mac OS X. + * Fixed issues with compiling on Cygwin. + +Changes for 1.0.0: + + * Initial Open Source release of Google Test diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/CMakeLists.txt b/cpp/thirdparty/protobuf-2.5.0/gtest/CMakeLists.txt new file mode 100644 index 0000000..64527f7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/CMakeLists.txt @@ -0,0 +1,250 @@ +######################################################################## +# CMake build script for Google Test. +# +# To run the tests for Google Test itself on Linux, use 'make test' or +# ctest. You can select which tests to run using 'ctest -R regex'. +# For more options, run 'ctest --help'. + +# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to +# make it prominent in the GUI. +option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) + +# When other libraries are using a shared version of runtime libraries, +# Google Test also has to use one. +option( + gtest_force_shared_crt + "Use shared (DLL) run-time lib even when Google Test is built as static lib." + OFF) + +option(gtest_build_tests "Build all of gtest's own tests." OFF) + +option(gtest_build_samples "Build gtest's sample programs." OFF) + +option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF) + +# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build(). +include(cmake/hermetic_build.cmake OPTIONAL) + +if (COMMAND pre_project_set_up_hermetic_build) + pre_project_set_up_hermetic_build() +endif() + +######################################################################## +# +# Project-wide settings + +# Name of the project. +# +# CMake files in this project can refer to the root source directory +# as ${gtest_SOURCE_DIR} and to the root binary directory as +# ${gtest_BINARY_DIR}. +# Language "C" is required for find_package(Threads). +project(gtest CXX C) +cmake_minimum_required(VERSION 2.6.2) + +if (COMMAND set_up_hermetic_build) + set_up_hermetic_build() +endif() + +# Define helper functions and macros used by Google Test. +include(cmake/internal_utils.cmake) + +config_compiler_and_linker() # Defined in internal_utils.cmake. + +# Where Google Test's .h files can be found. +include_directories( + ${gtest_SOURCE_DIR}/include + ${gtest_SOURCE_DIR}) + +# Where Google Test's libraries can be found. +link_directories(${gtest_BINARY_DIR}/src) + +######################################################################## +# +# Defines the gtest & gtest_main libraries. User tests should link +# with one of them. + +# Google Test libraries. We build them using more strict warnings than what +# are used for other targets, to ensure that gtest can be compiled by a user +# aggressive about warnings. +cxx_library(gtest "${cxx_strict}" src/gtest-all.cc) +cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc) +target_link_libraries(gtest_main gtest) + +######################################################################## +# +# Samples on how to link user tests with gtest or gtest_main. +# +# They are not built by default. To build them, set the +# gtest_build_samples option to ON. You can do it by running ccmake +# or specifying the -Dbuild_gtest_samples=ON flag when running cmake. + +if (gtest_build_samples) + cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc) + cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc) + cxx_executable(sample3_unittest samples gtest_main) + cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc) + cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc) + cxx_executable(sample6_unittest samples gtest_main) + cxx_executable(sample7_unittest samples gtest_main) + cxx_executable(sample8_unittest samples gtest_main) + cxx_executable(sample9_unittest samples gtest) + cxx_executable(sample10_unittest samples gtest) +endif() + +######################################################################## +# +# Google Test's own tests. +# +# You can skip this section if you aren't interested in testing +# Google Test itself. +# +# The tests are not built by default. To build them, set the +# gtest_build_tests option to ON. You can do it by running ccmake +# or specifying the -Dgtest_build_tests=ON flag when running cmake. + +if (gtest_build_tests) + # This must be set in the root directory for the tests to be run by + # 'make test' or ctest. + enable_testing() + + ############################################################ + # C++ tests built with standard compiler flags. + + cxx_test(gtest-death-test_test gtest_main) + cxx_test(gtest_environment_test gtest) + cxx_test(gtest-filepath_test gtest_main) + cxx_test(gtest-linked_ptr_test gtest_main) + cxx_test(gtest-listener_test gtest_main) + cxx_test(gtest_main_unittest gtest_main) + cxx_test(gtest-message_test gtest_main) + cxx_test(gtest_no_test_unittest gtest) + cxx_test(gtest-options_test gtest_main) + cxx_test(gtest-param-test_test gtest + test/gtest-param-test2_test.cc) + cxx_test(gtest-port_test gtest_main) + cxx_test(gtest_pred_impl_unittest gtest_main) + cxx_test(gtest-printers_test gtest_main) + cxx_test(gtest_prod_test gtest_main + test/production.cc) + cxx_test(gtest_repeat_test gtest) + cxx_test(gtest_sole_header_test gtest_main) + cxx_test(gtest_stress_test gtest) + cxx_test(gtest-test-part_test gtest_main) + cxx_test(gtest_throw_on_failure_ex_test gtest) + cxx_test(gtest-typed-test_test gtest_main + test/gtest-typed-test2_test.cc) + cxx_test(gtest_unittest gtest_main) + cxx_test(gtest-unittest-api_test gtest) + + ############################################################ + # C++ tests built with non-standard compiler flags. + + # MSVC 7.1 does not support STL with exceptions disabled. + if (NOT MSVC OR MSVC_VERSION GREATER 1310) + cxx_library(gtest_no_exception "${cxx_no_exception}" + src/gtest-all.cc) + cxx_library(gtest_main_no_exception "${cxx_no_exception}" + src/gtest-all.cc src/gtest_main.cc) + endif() + cxx_library(gtest_main_no_rtti "${cxx_no_rtti}" + src/gtest-all.cc src/gtest_main.cc) + + cxx_test_with_flags(gtest-death-test_ex_nocatch_test + "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0" + gtest test/gtest-death-test_ex_test.cc) + cxx_test_with_flags(gtest-death-test_ex_catch_test + "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1" + gtest test/gtest-death-test_ex_test.cc) + + cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}" + gtest_main_no_rtti test/gtest_unittest.cc) + + cxx_shared_library(gtest_dll "${cxx_default}" + src/gtest-all.cc src/gtest_main.cc) + + cxx_executable_with_flags(gtest_dll_test_ "${cxx_default}" + gtest_dll test/gtest_all_test.cc) + set_target_properties(gtest_dll_test_ + PROPERTIES + COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") + + if (NOT MSVC OR NOT MSVC_VERSION EQUAL 1600) + # The C++ Standard specifies tuple_element. + # Yet MSVC 10's declares tuple_element. + # That declaration conflicts with our own standard-conforming + # tuple implementation. Therefore using our own tuple with + # MSVC 10 doesn't compile. + cxx_library(gtest_main_use_own_tuple "${cxx_use_own_tuple}" + src/gtest-all.cc src/gtest_main.cc) + + cxx_test_with_flags(gtest-tuple_test "${cxx_use_own_tuple}" + gtest_main_use_own_tuple test/gtest-tuple_test.cc) + + cxx_test_with_flags(gtest_use_own_tuple_test "${cxx_use_own_tuple}" + gtest_main_use_own_tuple + test/gtest-param-test_test.cc test/gtest-param-test2_test.cc) + endif() + + ############################################################ + # Python tests. + + cxx_executable(gtest_break_on_failure_unittest_ test gtest) + py_test(gtest_break_on_failure_unittest) + + # MSVC 7.1 does not support STL with exceptions disabled. + if (NOT MSVC OR MSVC_VERSION GREATER 1310) + cxx_executable_with_flags( + gtest_catch_exceptions_no_ex_test_ + "${cxx_no_exception}" + gtest_main_no_exception + test/gtest_catch_exceptions_test_.cc) + endif() + + cxx_executable_with_flags( + gtest_catch_exceptions_ex_test_ + "${cxx_exception}" + gtest_main + test/gtest_catch_exceptions_test_.cc) + py_test(gtest_catch_exceptions_test) + + cxx_executable(gtest_color_test_ test gtest) + py_test(gtest_color_test) + + cxx_executable(gtest_env_var_test_ test gtest) + py_test(gtest_env_var_test) + + cxx_executable(gtest_filter_unittest_ test gtest) + py_test(gtest_filter_unittest) + + cxx_executable(gtest_help_test_ test gtest_main) + py_test(gtest_help_test) + + cxx_executable(gtest_list_tests_unittest_ test gtest) + py_test(gtest_list_tests_unittest) + + cxx_executable(gtest_output_test_ test gtest) + py_test(gtest_output_test) + + cxx_executable(gtest_shuffle_test_ test gtest) + py_test(gtest_shuffle_test) + + # MSVC 7.1 does not support STL with exceptions disabled. + if (NOT MSVC OR MSVC_VERSION GREATER 1310) + cxx_executable(gtest_throw_on_failure_test_ test gtest_no_exception) + set_target_properties(gtest_throw_on_failure_test_ + PROPERTIES + COMPILE_FLAGS "${cxx_no_exception}") + py_test(gtest_throw_on_failure_test) + endif() + + cxx_executable(gtest_uninitialized_test_ test gtest) + py_test(gtest_uninitialized_test) + + cxx_executable(gtest_xml_outfile1_test_ test gtest_main) + cxx_executable(gtest_xml_outfile2_test_ test gtest_main) + py_test(gtest_xml_outfiles_test) + + cxx_executable(gtest_xml_output_unittest_ test gtest) + py_test(gtest_xml_output_unittest) +endif() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/CONTRIBUTORS b/cpp/thirdparty/protobuf-2.5.0/gtest/CONTRIBUTORS new file mode 100644 index 0000000..feae2fc --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/CONTRIBUTORS @@ -0,0 +1,37 @@ +# This file contains a list of people who've made non-trivial +# contribution to the Google C++ Testing Framework project. People +# who commit code to the project are encouraged to add their names +# here. Please keep the list sorted by first names. + +Ajay Joshi +Balázs Dán +Bharat Mediratta +Chandler Carruth +Chris Prince +Chris Taylor +Dan Egnor +Eric Roman +Hady Zalek +Jeffrey Yasskin +Jói Sigurðsson +Keir Mierle +Keith Ray +Kenton Varda +Manuel Klimek +Markus Heule +Mika Raento +Miklós Fazekas +Pasi Valminen +Patrick Hanna +Patrick Riley +Peter Kaminski +Preston Jackson +Rainer Klaffenboeck +Russ Cox +Russ Rufer +Sean Mcafee +Sigurður Ãsgeirsson +Tracy Bialik +Vadim Berman +Vlad Losev +Zhanyong Wan diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/LICENSE b/cpp/thirdparty/protobuf-2.5.0/gtest/LICENSE new file mode 100644 index 0000000..1941a11 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/LICENSE @@ -0,0 +1,28 @@ +Copyright 2008, Google Inc. +All rights reserved. + +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. diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/Makefile.am b/cpp/thirdparty/protobuf-2.5.0/gtest/Makefile.am new file mode 100644 index 0000000..788c475 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/Makefile.am @@ -0,0 +1,305 @@ +# Automake file + +ACLOCAL_AMFLAGS = -I m4 + +# Nonstandard package files for distribution +EXTRA_DIST = \ + CHANGES \ + CONTRIBUTORS \ + LICENSE \ + include/gtest/gtest-param-test.h.pump \ + include/gtest/internal/gtest-param-util-generated.h.pump \ + include/gtest/internal/gtest-tuple.h.pump \ + include/gtest/internal/gtest-type-util.h.pump \ + make/Makefile \ + scripts/fuse_gtest_files.py \ + scripts/gen_gtest_pred_impl.py \ + scripts/pump.py \ + scripts/test/Makefile + +# gtest source files that we don't compile directly. They are +# #included by gtest-all.cc. +GTEST_SRC = \ + src/gtest-death-test.cc \ + src/gtest-filepath.cc \ + src/gtest-internal-inl.h \ + src/gtest-port.cc \ + src/gtest-printers.cc \ + src/gtest-test-part.cc \ + src/gtest-typed-test.cc \ + src/gtest.cc + +EXTRA_DIST += $(GTEST_SRC) + +# Sample files that we don't compile. +EXTRA_DIST += \ + samples/prime_tables.h \ + samples/sample2_unittest.cc \ + samples/sample3_unittest.cc \ + samples/sample4_unittest.cc \ + samples/sample5_unittest.cc \ + samples/sample6_unittest.cc \ + samples/sample7_unittest.cc \ + samples/sample8_unittest.cc \ + samples/sample9_unittest.cc + +# C++ test files that we don't compile directly. +EXTRA_DIST += \ + test/gtest-death-test_ex_test.cc \ + test/gtest-death-test_test.cc \ + test/gtest-filepath_test.cc \ + test/gtest-linked_ptr_test.cc \ + test/gtest-listener_test.cc \ + test/gtest-message_test.cc \ + test/gtest-options_test.cc \ + test/gtest-param-test2_test.cc \ + test/gtest-param-test2_test.cc \ + test/gtest-param-test_test.cc \ + test/gtest-param-test_test.cc \ + test/gtest-param-test_test.h \ + test/gtest-port_test.cc \ + test/gtest-printers_test.cc \ + test/gtest-test-part_test.cc \ + test/gtest-tuple_test.cc \ + test/gtest-typed-test2_test.cc \ + test/gtest-typed-test_test.cc \ + test/gtest-typed-test_test.h \ + test/gtest-unittest-api_test.cc \ + test/gtest_break_on_failure_unittest_.cc \ + test/gtest_catch_exceptions_test_.cc \ + test/gtest_color_test_.cc \ + test/gtest_env_var_test_.cc \ + test/gtest_environment_test.cc \ + test/gtest_filter_unittest_.cc \ + test/gtest_help_test_.cc \ + test/gtest_list_tests_unittest_.cc \ + test/gtest_main_unittest.cc \ + test/gtest_no_test_unittest.cc \ + test/gtest_output_test_.cc \ + test/gtest_pred_impl_unittest.cc \ + test/gtest_prod_test.cc \ + test/gtest_repeat_test.cc \ + test/gtest_shuffle_test_.cc \ + test/gtest_sole_header_test.cc \ + test/gtest_stress_test.cc \ + test/gtest_throw_on_failure_ex_test.cc \ + test/gtest_throw_on_failure_test_.cc \ + test/gtest_uninitialized_test_.cc \ + test/gtest_unittest.cc \ + test/gtest_unittest.cc \ + test/gtest_xml_outfile1_test_.cc \ + test/gtest_xml_outfile2_test_.cc \ + test/gtest_xml_output_unittest_.cc \ + test/production.cc \ + test/production.h + +# Python tests that we don't run. +EXTRA_DIST += \ + test/gtest_break_on_failure_unittest.py \ + test/gtest_catch_exceptions_test.py \ + test/gtest_color_test.py \ + test/gtest_env_var_test.py \ + test/gtest_filter_unittest.py \ + test/gtest_help_test.py \ + test/gtest_list_tests_unittest.py \ + test/gtest_output_test.py \ + test/gtest_output_test_golden_lin.txt \ + test/gtest_shuffle_test.py \ + test/gtest_test_utils.py \ + test/gtest_throw_on_failure_test.py \ + test/gtest_uninitialized_test.py \ + test/gtest_xml_outfiles_test.py \ + test/gtest_xml_output_unittest.py \ + test/gtest_xml_test_utils.py + +# CMake script +EXTRA_DIST += \ + CMakeLists.txt \ + cmake/internal_utils.cmake + +# MSVC project files +EXTRA_DIST += \ + msvc/gtest-md.sln \ + msvc/gtest-md.vcproj \ + msvc/gtest.sln \ + msvc/gtest.vcproj \ + msvc/gtest_main-md.vcproj \ + msvc/gtest_main.vcproj \ + msvc/gtest_prod_test-md.vcproj \ + msvc/gtest_prod_test.vcproj \ + msvc/gtest_unittest-md.vcproj \ + msvc/gtest_unittest.vcproj + +# xcode project files +EXTRA_DIST += \ + xcode/Config/DebugProject.xcconfig \ + xcode/Config/FrameworkTarget.xcconfig \ + xcode/Config/General.xcconfig \ + xcode/Config/ReleaseProject.xcconfig \ + xcode/Config/StaticLibraryTarget.xcconfig \ + xcode/Config/TestTarget.xcconfig \ + xcode/Resources/Info.plist \ + xcode/Scripts/runtests.sh \ + xcode/Scripts/versiongenerate.py \ + xcode/gtest.xcodeproj/project.pbxproj + +# xcode sample files +EXTRA_DIST += \ + xcode/Samples/FrameworkSample/Info.plist \ + xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj \ + xcode/Samples/FrameworkSample/runtests.sh \ + xcode/Samples/FrameworkSample/widget.cc \ + xcode/Samples/FrameworkSample/widget.h \ + xcode/Samples/FrameworkSample/widget_test.cc + +# C++Builder project files +EXTRA_DIST += \ + codegear/gtest.cbproj \ + codegear/gtest.groupproj \ + codegear/gtest_all.cc \ + codegear/gtest_link.cc \ + codegear/gtest_main.cbproj \ + codegear/gtest_unittest.cbproj + +# Distribute and install M4 macro +m4datadir = $(datadir)/aclocal +m4data_DATA = m4/gtest.m4 +EXTRA_DIST += $(m4data_DATA) + +# We define the global AM_CPPFLAGS as everything we compile includes from these +# directories. +AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include + +# Modifies compiler and linker flags for pthreads compatibility. +if HAVE_PTHREADS + AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1 + AM_LIBS = @PTHREAD_LIBS@ +else + AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0 +endif + +# Build rules for libraries. +lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la + +lib_libgtest_la_SOURCES = src/gtest-all.cc + +pkginclude_HEADERS = \ + include/gtest/gtest-death-test.h \ + include/gtest/gtest-message.h \ + include/gtest/gtest-param-test.h \ + include/gtest/gtest-printers.h \ + include/gtest/gtest-spi.h \ + include/gtest/gtest-test-part.h \ + include/gtest/gtest-typed-test.h \ + include/gtest/gtest.h \ + include/gtest/gtest_pred_impl.h \ + include/gtest/gtest_prod.h + +pkginclude_internaldir = $(pkgincludedir)/internal +pkginclude_internal_HEADERS = \ + include/gtest/internal/gtest-death-test-internal.h \ + include/gtest/internal/gtest-filepath.h \ + include/gtest/internal/gtest-internal.h \ + include/gtest/internal/gtest-linked_ptr.h \ + include/gtest/internal/gtest-param-util-generated.h \ + include/gtest/internal/gtest-param-util.h \ + include/gtest/internal/gtest-port.h \ + include/gtest/internal/gtest-string.h \ + include/gtest/internal/gtest-tuple.h \ + include/gtest/internal/gtest-type-util.h + +lib_libgtest_main_la_SOURCES = src/gtest_main.cc +lib_libgtest_main_la_LIBADD = lib/libgtest.la + +# Bulid rules for samples and tests. Automake's naming for some of +# these variables isn't terribly obvious, so this is a brief +# reference: +# +# TESTS -- Programs run automatically by "make check" +# check_PROGRAMS -- Programs built by "make check" but not necessarily run + +noinst_LTLIBRARIES = samples/libsamples.la + +samples_libsamples_la_SOURCES = \ + samples/sample1.cc \ + samples/sample1.h \ + samples/sample2.cc \ + samples/sample2.h \ + samples/sample3-inl.h \ + samples/sample4.cc \ + samples/sample4.h + +TESTS= +TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \ + GTEST_BUILD_DIR="$(top_builddir)/test" +check_PROGRAMS= + +# A simple sample on using gtest. +TESTS += samples/sample1_unittest +check_PROGRAMS += samples/sample1_unittest +samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc +samples_sample1_unittest_LDADD = lib/libgtest_main.la \ + lib/libgtest.la \ + samples/libsamples.la + +# Another sample. It also verifies that libgtest works. +TESTS += samples/sample10_unittest +check_PROGRAMS += samples/sample10_unittest +samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc +samples_sample10_unittest_LDADD = lib/libgtest.la + +# This tests most constructs of gtest and verifies that libgtest_main +# and libgtest work. +TESTS += test/gtest_all_test +check_PROGRAMS += test/gtest_all_test +test_gtest_all_test_SOURCES = test/gtest_all_test.cc +test_gtest_all_test_LDADD = lib/libgtest_main.la \ + lib/libgtest.la + +# Tests that fused gtest files compile and work. +FUSED_GTEST_SRC = \ + fused-src/gtest/gtest-all.cc \ + fused-src/gtest/gtest.h \ + fused-src/gtest/gtest_main.cc + +if HAVE_PYTHON +TESTS += test/fused_gtest_test +check_PROGRAMS += test/fused_gtest_test +test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \ + samples/sample1.cc samples/sample1_unittest.cc +test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src" + +# Build rules for putting fused Google Test files into the distribution +# package. The user can also create those files by manually running +# scripts/fuse_gtest_files.py. +$(test_fused_gtest_test_SOURCES): fused-gtest + +fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \ + $(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \ + scripts/fuse_gtest_files.py + mkdir -p "$(srcdir)/fused-src" + chmod -R u+w "$(srcdir)/fused-src" + rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc" + rm -f "$(srcdir)/fused-src/gtest/gtest.h" + "$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src" + cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/" + +maintainer-clean-local: + rm -rf "$(srcdir)/fused-src" +endif + +# Death tests may produce core dumps in the build directory. In case +# this happens, clean them to keep distcleancheck happy. +CLEANFILES = core + +# Disables 'make install' as installing a compiled version of Google +# Test can lead to undefined behavior due to violation of the +# One-Definition Rule. + +install-exec-local: + echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." + false + +install-data-local: + echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." + false diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/Makefile.in b/cpp/thirdparty/protobuf-2.5.0/gtest/Makefile.in new file mode 100644 index 0000000..9409343 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/Makefile.in @@ -0,0 +1,1360 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Automake file + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +TESTS = samples/sample1_unittest$(EXEEXT) \ + samples/sample10_unittest$(EXEEXT) \ + test/gtest_all_test$(EXEEXT) $(am__EXEEXT_1) +check_PROGRAMS = samples/sample1_unittest$(EXEEXT) \ + samples/sample10_unittest$(EXEEXT) \ + test/gtest_all_test$(EXEEXT) $(am__EXEEXT_1) +@HAVE_PYTHON_TRUE@am__append_1 = test/fused_gtest_test +@HAVE_PYTHON_TRUE@am__append_2 = test/fused_gtest_test +subdir = . +DIST_COMMON = README $(am__configure_deps) $(pkginclude_HEADERS) \ + $(pkginclude_internal_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/build-aux/config.h.in \ + $(top_srcdir)/configure $(top_srcdir)/scripts/gtest-config.in \ + build-aux/config.guess build-aux/config.sub build-aux/depcomp \ + build-aux/install-sh build-aux/ltmain.sh build-aux/missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/acx_pthread.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/build-aux/config.h +CONFIG_CLEAN_FILES = scripts/gtest-config +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(m4datadir)" \ + "$(DESTDIR)$(pkgincludedir)" \ + "$(DESTDIR)$(pkginclude_internaldir)" +LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) +lib_libgtest_la_LIBADD = +am__dirstamp = $(am__leading_dot)dirstamp +am_lib_libgtest_la_OBJECTS = src/gtest-all.lo +lib_libgtest_la_OBJECTS = $(am_lib_libgtest_la_OBJECTS) +lib_libgtest_main_la_DEPENDENCIES = lib/libgtest.la +am_lib_libgtest_main_la_OBJECTS = src/gtest_main.lo +lib_libgtest_main_la_OBJECTS = $(am_lib_libgtest_main_la_OBJECTS) +samples_libsamples_la_LIBADD = +am_samples_libsamples_la_OBJECTS = samples/sample1.lo \ + samples/sample2.lo samples/sample4.lo +samples_libsamples_la_OBJECTS = $(am_samples_libsamples_la_OBJECTS) +@HAVE_PYTHON_TRUE@am__EXEEXT_1 = test/fused_gtest_test$(EXEEXT) +am_samples_sample10_unittest_OBJECTS = \ + samples/sample10_unittest.$(OBJEXT) +samples_sample10_unittest_OBJECTS = \ + $(am_samples_sample10_unittest_OBJECTS) +samples_sample10_unittest_DEPENDENCIES = lib/libgtest.la +am_samples_sample1_unittest_OBJECTS = \ + samples/sample1_unittest.$(OBJEXT) +samples_sample1_unittest_OBJECTS = \ + $(am_samples_sample1_unittest_OBJECTS) +samples_sample1_unittest_DEPENDENCIES = lib/libgtest_main.la \ + lib/libgtest.la samples/libsamples.la +am__test_fused_gtest_test_SOURCES_DIST = fused-src/gtest/gtest-all.cc \ + fused-src/gtest/gtest.h fused-src/gtest/gtest_main.cc \ + samples/sample1.cc samples/sample1_unittest.cc +am__objects_1 = \ + fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT) \ + fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT) +@HAVE_PYTHON_TRUE@am_test_fused_gtest_test_OBJECTS = $(am__objects_1) \ +@HAVE_PYTHON_TRUE@ samples/test_fused_gtest_test-sample1.$(OBJEXT) \ +@HAVE_PYTHON_TRUE@ samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT) +test_fused_gtest_test_OBJECTS = $(am_test_fused_gtest_test_OBJECTS) +test_fused_gtest_test_LDADD = $(LDADD) +am_test_gtest_all_test_OBJECTS = test/gtest_all_test.$(OBJEXT) +test_gtest_all_test_OBJECTS = $(am_test_gtest_all_test_OBJECTS) +test_gtest_all_test_DEPENDENCIES = lib/libgtest_main.la \ + lib/libgtest.la +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/build-aux +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(lib_libgtest_la_SOURCES) $(lib_libgtest_main_la_SOURCES) \ + $(samples_libsamples_la_SOURCES) \ + $(samples_sample10_unittest_SOURCES) \ + $(samples_sample1_unittest_SOURCES) \ + $(test_fused_gtest_test_SOURCES) \ + $(test_gtest_all_test_SOURCES) +DIST_SOURCES = $(lib_libgtest_la_SOURCES) \ + $(lib_libgtest_main_la_SOURCES) \ + $(samples_libsamples_la_SOURCES) \ + $(samples_sample10_unittest_SOURCES) \ + $(samples_sample1_unittest_SOURCES) \ + $(am__test_fused_gtest_test_SOURCES_DIST) \ + $(test_gtest_all_test_SOURCES) +DATA = $(m4data_DATA) +HEADERS = $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +PYTHON = @PYTHON@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I m4 + +# Nonstandard package files for distribution + +# Sample files that we don't compile. + +# C++ test files that we don't compile directly. + +# Python tests that we don't run. + +# CMake script + +# MSVC project files + +# xcode project files + +# xcode sample files + +# C++Builder project files +EXTRA_DIST = CHANGES CONTRIBUTORS LICENSE \ + include/gtest/gtest-param-test.h.pump \ + include/gtest/internal/gtest-param-util-generated.h.pump \ + include/gtest/internal/gtest-tuple.h.pump \ + include/gtest/internal/gtest-type-util.h.pump make/Makefile \ + scripts/fuse_gtest_files.py scripts/gen_gtest_pred_impl.py \ + scripts/pump.py scripts/test/Makefile $(GTEST_SRC) \ + samples/prime_tables.h samples/sample2_unittest.cc \ + samples/sample3_unittest.cc samples/sample4_unittest.cc \ + samples/sample5_unittest.cc samples/sample6_unittest.cc \ + samples/sample7_unittest.cc samples/sample8_unittest.cc \ + samples/sample9_unittest.cc test/gtest-death-test_ex_test.cc \ + test/gtest-death-test_test.cc test/gtest-filepath_test.cc \ + test/gtest-linked_ptr_test.cc test/gtest-listener_test.cc \ + test/gtest-message_test.cc test/gtest-options_test.cc \ + test/gtest-param-test2_test.cc test/gtest-param-test2_test.cc \ + test/gtest-param-test_test.cc test/gtest-param-test_test.cc \ + test/gtest-param-test_test.h test/gtest-port_test.cc \ + test/gtest-printers_test.cc test/gtest-test-part_test.cc \ + test/gtest-tuple_test.cc test/gtest-typed-test2_test.cc \ + test/gtest-typed-test_test.cc test/gtest-typed-test_test.h \ + test/gtest-unittest-api_test.cc \ + test/gtest_break_on_failure_unittest_.cc \ + test/gtest_catch_exceptions_test_.cc test/gtest_color_test_.cc \ + test/gtest_env_var_test_.cc test/gtest_environment_test.cc \ + test/gtest_filter_unittest_.cc test/gtest_help_test_.cc \ + test/gtest_list_tests_unittest_.cc test/gtest_main_unittest.cc \ + test/gtest_no_test_unittest.cc test/gtest_output_test_.cc \ + test/gtest_pred_impl_unittest.cc test/gtest_prod_test.cc \ + test/gtest_repeat_test.cc test/gtest_shuffle_test_.cc \ + test/gtest_sole_header_test.cc test/gtest_stress_test.cc \ + test/gtest_throw_on_failure_ex_test.cc \ + test/gtest_throw_on_failure_test_.cc \ + test/gtest_uninitialized_test_.cc test/gtest_unittest.cc \ + test/gtest_unittest.cc test/gtest_xml_outfile1_test_.cc \ + test/gtest_xml_outfile2_test_.cc \ + test/gtest_xml_output_unittest_.cc test/production.cc \ + test/production.h test/gtest_break_on_failure_unittest.py \ + test/gtest_catch_exceptions_test.py test/gtest_color_test.py \ + test/gtest_env_var_test.py test/gtest_filter_unittest.py \ + test/gtest_help_test.py test/gtest_list_tests_unittest.py \ + test/gtest_output_test.py \ + test/gtest_output_test_golden_lin.txt \ + test/gtest_shuffle_test.py test/gtest_test_utils.py \ + test/gtest_throw_on_failure_test.py \ + test/gtest_uninitialized_test.py \ + test/gtest_xml_outfiles_test.py \ + test/gtest_xml_output_unittest.py test/gtest_xml_test_utils.py \ + CMakeLists.txt cmake/internal_utils.cmake msvc/gtest-md.sln \ + msvc/gtest-md.vcproj msvc/gtest.sln msvc/gtest.vcproj \ + msvc/gtest_main-md.vcproj msvc/gtest_main.vcproj \ + msvc/gtest_prod_test-md.vcproj msvc/gtest_prod_test.vcproj \ + msvc/gtest_unittest-md.vcproj msvc/gtest_unittest.vcproj \ + xcode/Config/DebugProject.xcconfig \ + xcode/Config/FrameworkTarget.xcconfig \ + xcode/Config/General.xcconfig \ + xcode/Config/ReleaseProject.xcconfig \ + xcode/Config/StaticLibraryTarget.xcconfig \ + xcode/Config/TestTarget.xcconfig xcode/Resources/Info.plist \ + xcode/Scripts/runtests.sh xcode/Scripts/versiongenerate.py \ + xcode/gtest.xcodeproj/project.pbxproj \ + xcode/Samples/FrameworkSample/Info.plist \ + xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj \ + xcode/Samples/FrameworkSample/runtests.sh \ + xcode/Samples/FrameworkSample/widget.cc \ + xcode/Samples/FrameworkSample/widget.h \ + xcode/Samples/FrameworkSample/widget_test.cc \ + codegear/gtest.cbproj codegear/gtest.groupproj \ + codegear/gtest_all.cc codegear/gtest_link.cc \ + codegear/gtest_main.cbproj codegear/gtest_unittest.cbproj \ + $(m4data_DATA) + +# gtest source files that we don't compile directly. They are +# #included by gtest-all.cc. +GTEST_SRC = \ + src/gtest-death-test.cc \ + src/gtest-filepath.cc \ + src/gtest-internal-inl.h \ + src/gtest-port.cc \ + src/gtest-printers.cc \ + src/gtest-test-part.cc \ + src/gtest-typed-test.cc \ + src/gtest.cc + + +# Distribute and install M4 macro +m4datadir = $(datadir)/aclocal +m4data_DATA = m4/gtest.m4 + +# We define the global AM_CPPFLAGS as everything we compile includes from these +# directories. +AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include +@HAVE_PTHREADS_FALSE@AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0 + +# Modifies compiler and linker flags for pthreads compatibility. +@HAVE_PTHREADS_TRUE@AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1 +@HAVE_PTHREADS_TRUE@AM_LIBS = @PTHREAD_LIBS@ + +# Build rules for libraries. +lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la +lib_libgtest_la_SOURCES = src/gtest-all.cc +pkginclude_HEADERS = \ + include/gtest/gtest-death-test.h \ + include/gtest/gtest-message.h \ + include/gtest/gtest-param-test.h \ + include/gtest/gtest-printers.h \ + include/gtest/gtest-spi.h \ + include/gtest/gtest-test-part.h \ + include/gtest/gtest-typed-test.h \ + include/gtest/gtest.h \ + include/gtest/gtest_pred_impl.h \ + include/gtest/gtest_prod.h + +pkginclude_internaldir = $(pkgincludedir)/internal +pkginclude_internal_HEADERS = \ + include/gtest/internal/gtest-death-test-internal.h \ + include/gtest/internal/gtest-filepath.h \ + include/gtest/internal/gtest-internal.h \ + include/gtest/internal/gtest-linked_ptr.h \ + include/gtest/internal/gtest-param-util-generated.h \ + include/gtest/internal/gtest-param-util.h \ + include/gtest/internal/gtest-port.h \ + include/gtest/internal/gtest-string.h \ + include/gtest/internal/gtest-tuple.h \ + include/gtest/internal/gtest-type-util.h + +lib_libgtest_main_la_SOURCES = src/gtest_main.cc +lib_libgtest_main_la_LIBADD = lib/libgtest.la + +# Bulid rules for samples and tests. Automake's naming for some of +# these variables isn't terribly obvious, so this is a brief +# reference: +# +# TESTS -- Programs run automatically by "make check" +# check_PROGRAMS -- Programs built by "make check" but not necessarily run +noinst_LTLIBRARIES = samples/libsamples.la +samples_libsamples_la_SOURCES = \ + samples/sample1.cc \ + samples/sample1.h \ + samples/sample2.cc \ + samples/sample2.h \ + samples/sample3-inl.h \ + samples/sample4.cc \ + samples/sample4.h + +TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \ + GTEST_BUILD_DIR="$(top_builddir)/test" + +samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc +samples_sample1_unittest_LDADD = lib/libgtest_main.la \ + lib/libgtest.la \ + samples/libsamples.la + +samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc +samples_sample10_unittest_LDADD = lib/libgtest.la +test_gtest_all_test_SOURCES = test/gtest_all_test.cc +test_gtest_all_test_LDADD = lib/libgtest_main.la \ + lib/libgtest.la + + +# Tests that fused gtest files compile and work. +FUSED_GTEST_SRC = \ + fused-src/gtest/gtest-all.cc \ + fused-src/gtest/gtest.h \ + fused-src/gtest/gtest_main.cc + +@HAVE_PYTHON_TRUE@test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \ +@HAVE_PYTHON_TRUE@ samples/sample1.cc samples/sample1_unittest.cc + +@HAVE_PYTHON_TRUE@test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src" + +# Death tests may produce core dumps in the build directory. In case +# this happens, clean them to keep distcleancheck happy. +CLEANFILES = core +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .lo .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +build-aux/config.h: build-aux/stamp-h1 + @if test ! -f $@; then rm -f build-aux/stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) build-aux/stamp-h1; else :; fi + +build-aux/stamp-h1: $(top_srcdir)/build-aux/config.h.in $(top_builddir)/config.status + @rm -f build-aux/stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status build-aux/config.h +$(top_srcdir)/build-aux/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f build-aux/stamp-h1 + touch $@ + +distclean-hdr: + -rm -f build-aux/config.h build-aux/stamp-h1 +scripts/gtest-config: $(top_builddir)/config.status $(top_srcdir)/scripts/gtest-config.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +src/$(am__dirstamp): + @$(MKDIR_P) src + @: > src/$(am__dirstamp) +src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/$(DEPDIR) + @: > src/$(DEPDIR)/$(am__dirstamp) +src/gtest-all.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +lib/$(am__dirstamp): + @$(MKDIR_P) lib + @: > lib/$(am__dirstamp) +lib/libgtest.la: $(lib_libgtest_la_OBJECTS) $(lib_libgtest_la_DEPENDENCIES) $(EXTRA_lib_libgtest_la_DEPENDENCIES) lib/$(am__dirstamp) + $(CXXLINK) -rpath $(libdir) $(lib_libgtest_la_OBJECTS) $(lib_libgtest_la_LIBADD) $(LIBS) +src/gtest_main.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +lib/libgtest_main.la: $(lib_libgtest_main_la_OBJECTS) $(lib_libgtest_main_la_DEPENDENCIES) $(EXTRA_lib_libgtest_main_la_DEPENDENCIES) lib/$(am__dirstamp) + $(CXXLINK) -rpath $(libdir) $(lib_libgtest_main_la_OBJECTS) $(lib_libgtest_main_la_LIBADD) $(LIBS) +samples/$(am__dirstamp): + @$(MKDIR_P) samples + @: > samples/$(am__dirstamp) +samples/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) samples/$(DEPDIR) + @: > samples/$(DEPDIR)/$(am__dirstamp) +samples/sample1.lo: samples/$(am__dirstamp) \ + samples/$(DEPDIR)/$(am__dirstamp) +samples/sample2.lo: samples/$(am__dirstamp) \ + samples/$(DEPDIR)/$(am__dirstamp) +samples/sample4.lo: samples/$(am__dirstamp) \ + samples/$(DEPDIR)/$(am__dirstamp) +samples/libsamples.la: $(samples_libsamples_la_OBJECTS) $(samples_libsamples_la_DEPENDENCIES) $(EXTRA_samples_libsamples_la_DEPENDENCIES) samples/$(am__dirstamp) + $(CXXLINK) $(samples_libsamples_la_OBJECTS) $(samples_libsamples_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +samples/sample10_unittest.$(OBJEXT): samples/$(am__dirstamp) \ + samples/$(DEPDIR)/$(am__dirstamp) +samples/sample10_unittest$(EXEEXT): $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_DEPENDENCIES) $(EXTRA_samples_sample10_unittest_DEPENDENCIES) samples/$(am__dirstamp) + @rm -f samples/sample10_unittest$(EXEEXT) + $(CXXLINK) $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_LDADD) $(LIBS) +samples/sample1_unittest.$(OBJEXT): samples/$(am__dirstamp) \ + samples/$(DEPDIR)/$(am__dirstamp) +samples/sample1_unittest$(EXEEXT): $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_DEPENDENCIES) $(EXTRA_samples_sample1_unittest_DEPENDENCIES) samples/$(am__dirstamp) + @rm -f samples/sample1_unittest$(EXEEXT) + $(CXXLINK) $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_LDADD) $(LIBS) +fused-src/gtest/$(am__dirstamp): + @$(MKDIR_P) fused-src/gtest + @: > fused-src/gtest/$(am__dirstamp) +fused-src/gtest/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) fused-src/gtest/$(DEPDIR) + @: > fused-src/gtest/$(DEPDIR)/$(am__dirstamp) +fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT): \ + fused-src/gtest/$(am__dirstamp) \ + fused-src/gtest/$(DEPDIR)/$(am__dirstamp) +fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT): \ + fused-src/gtest/$(am__dirstamp) \ + fused-src/gtest/$(DEPDIR)/$(am__dirstamp) +samples/test_fused_gtest_test-sample1.$(OBJEXT): \ + samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp) +samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT): \ + samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp) +test/$(am__dirstamp): + @$(MKDIR_P) test + @: > test/$(am__dirstamp) +test/fused_gtest_test$(EXEEXT): $(test_fused_gtest_test_OBJECTS) $(test_fused_gtest_test_DEPENDENCIES) $(EXTRA_test_fused_gtest_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/fused_gtest_test$(EXEEXT) + $(CXXLINK) $(test_fused_gtest_test_OBJECTS) $(test_fused_gtest_test_LDADD) $(LIBS) +test/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) test/$(DEPDIR) + @: > test/$(DEPDIR)/$(am__dirstamp) +test/gtest_all_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/gtest_all_test$(EXEEXT): $(test_gtest_all_test_OBJECTS) $(test_gtest_all_test_DEPENDENCIES) $(EXTRA_test_gtest_all_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/gtest_all_test$(EXEEXT) + $(CXXLINK) $(test_gtest_all_test_OBJECTS) $(test_gtest_all_test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT) + -rm -f fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT) + -rm -f samples/sample1.$(OBJEXT) + -rm -f samples/sample1.lo + -rm -f samples/sample10_unittest.$(OBJEXT) + -rm -f samples/sample1_unittest.$(OBJEXT) + -rm -f samples/sample2.$(OBJEXT) + -rm -f samples/sample2.lo + -rm -f samples/sample4.$(OBJEXT) + -rm -f samples/sample4.lo + -rm -f samples/test_fused_gtest_test-sample1.$(OBJEXT) + -rm -f samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT) + -rm -f src/gtest-all.$(OBJEXT) + -rm -f src/gtest-all.lo + -rm -f src/gtest_main.$(OBJEXT) + -rm -f src/gtest_main.lo + -rm -f test/gtest_all_test.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample10_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample1_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample4.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-all.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest_main.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_all_test.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +fused-src/gtest/test_fused_gtest_test-gtest-all.o: fused-src/gtest/gtest-all.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest-all.o -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.o `test -f 'fused-src/gtest/gtest-all.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest-all.cc +@am__fastdepCXX_TRUE@ $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='fused-src/gtest/gtest-all.cc' object='fused-src/gtest/test_fused_gtest_test-gtest-all.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.o `test -f 'fused-src/gtest/gtest-all.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest-all.cc + +fused-src/gtest/test_fused_gtest_test-gtest-all.obj: fused-src/gtest/gtest-all.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest-all.obj -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.obj `if test -f 'fused-src/gtest/gtest-all.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest-all.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='fused-src/gtest/gtest-all.cc' object='fused-src/gtest/test_fused_gtest_test-gtest-all.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.obj `if test -f 'fused-src/gtest/gtest-all.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest-all.cc'; fi` + +fused-src/gtest/test_fused_gtest_test-gtest_main.o: fused-src/gtest/gtest_main.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest_main.o -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.o `test -f 'fused-src/gtest/gtest_main.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest_main.cc +@am__fastdepCXX_TRUE@ $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='fused-src/gtest/gtest_main.cc' object='fused-src/gtest/test_fused_gtest_test-gtest_main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.o `test -f 'fused-src/gtest/gtest_main.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest_main.cc + +fused-src/gtest/test_fused_gtest_test-gtest_main.obj: fused-src/gtest/gtest_main.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest_main.obj -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.obj `if test -f 'fused-src/gtest/gtest_main.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest_main.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='fused-src/gtest/gtest_main.cc' object='fused-src/gtest/test_fused_gtest_test-gtest_main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.obj `if test -f 'fused-src/gtest/gtest_main.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest_main.cc'; fi` + +samples/test_fused_gtest_test-sample1.o: samples/sample1.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1.o -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo -c -o samples/test_fused_gtest_test-sample1.o `test -f 'samples/sample1.cc' || echo '$(srcdir)/'`samples/sample1.cc +@am__fastdepCXX_TRUE@ $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='samples/sample1.cc' object='samples/test_fused_gtest_test-sample1.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1.o `test -f 'samples/sample1.cc' || echo '$(srcdir)/'`samples/sample1.cc + +samples/test_fused_gtest_test-sample1.obj: samples/sample1.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1.obj -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo -c -o samples/test_fused_gtest_test-sample1.obj `if test -f 'samples/sample1.cc'; then $(CYGPATH_W) 'samples/sample1.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='samples/sample1.cc' object='samples/test_fused_gtest_test-sample1.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1.obj `if test -f 'samples/sample1.cc'; then $(CYGPATH_W) 'samples/sample1.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1.cc'; fi` + +samples/test_fused_gtest_test-sample1_unittest.o: samples/sample1_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1_unittest.o -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo -c -o samples/test_fused_gtest_test-sample1_unittest.o `test -f 'samples/sample1_unittest.cc' || echo '$(srcdir)/'`samples/sample1_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='samples/sample1_unittest.cc' object='samples/test_fused_gtest_test-sample1_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1_unittest.o `test -f 'samples/sample1_unittest.cc' || echo '$(srcdir)/'`samples/sample1_unittest.cc + +samples/test_fused_gtest_test-sample1_unittest.obj: samples/sample1_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1_unittest.obj -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo -c -o samples/test_fused_gtest_test-sample1_unittest.obj `if test -f 'samples/sample1_unittest.cc'; then $(CYGPATH_W) 'samples/sample1_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='samples/sample1_unittest.cc' object='samples/test_fused_gtest_test-sample1_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1_unittest.obj `if test -f 'samples/sample1_unittest.cc'; then $(CYGPATH_W) 'samples/sample1_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1_unittest.cc'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf lib/.libs lib/_libs + -rm -rf samples/.libs samples/_libs + -rm -rf src/.libs src/_libs + -rm -rf test/.libs test/_libs + +distclean-libtool: + -rm -f libtool config.lt +install-m4dataDATA: $(m4data_DATA) + @$(NORMAL_INSTALL) + test -z "$(m4datadir)" || $(MKDIR_P) "$(DESTDIR)$(m4datadir)" + @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(m4datadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(m4datadir)" || exit $$?; \ + done + +uninstall-m4dataDATA: + @$(NORMAL_UNINSTALL) + @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir) +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) +install-pkginclude_internalHEADERS: $(pkginclude_internal_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(pkginclude_internaldir)" || $(MKDIR_P) "$(DESTDIR)$(pkginclude_internaldir)" + @list='$(pkginclude_internal_HEADERS)'; test -n "$(pkginclude_internaldir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkginclude_internaldir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginclude_internaldir)" || exit $$?; \ + done + +uninstall-pkginclude_internalHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_internal_HEADERS)'; test -n "$(pkginclude_internaldir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkginclude_internaldir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkginclude_internaldir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f fused-src/gtest/$(DEPDIR)/$(am__dirstamp) + -rm -f fused-src/gtest/$(am__dirstamp) + -rm -f lib/$(am__dirstamp) + -rm -f samples/$(DEPDIR)/$(am__dirstamp) + -rm -f samples/$(am__dirstamp) + -rm -f src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/$(am__dirstamp) + -rm -f test/$(DEPDIR)/$(am__dirstamp) + -rm -f test/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +@HAVE_PYTHON_FALSE@maintainer-clean-local: +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf fused-src/gtest/$(DEPDIR) samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-data-local install-m4dataDATA \ + install-pkgincludeHEADERS install-pkginclude_internalHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-exec-local install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf fused-src/gtest/$(DEPDIR) samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic \ + maintainer-clean-local + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES uninstall-m4dataDATA \ + uninstall-pkgincludeHEADERS \ + uninstall-pkginclude_internalHEADERS + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \ + clean clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool clean-noinstLTLIBRARIES ctags dist dist-all \ + dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-data-local install-dvi \ + install-dvi-am install-exec install-exec-am install-exec-local \ + install-html install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-m4dataDATA install-man \ + install-pdf install-pdf-am install-pkgincludeHEADERS \ + install-pkginclude_internalHEADERS install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-local mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-libLTLIBRARIES \ + uninstall-m4dataDATA uninstall-pkgincludeHEADERS \ + uninstall-pkginclude_internalHEADERS + + +# Build rules for putting fused Google Test files into the distribution +# package. The user can also create those files by manually running +# scripts/fuse_gtest_files.py. +@HAVE_PYTHON_TRUE@$(test_fused_gtest_test_SOURCES): fused-gtest + +@HAVE_PYTHON_TRUE@fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \ +@HAVE_PYTHON_TRUE@ $(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \ +@HAVE_PYTHON_TRUE@ scripts/fuse_gtest_files.py +@HAVE_PYTHON_TRUE@ mkdir -p "$(srcdir)/fused-src" +@HAVE_PYTHON_TRUE@ chmod -R u+w "$(srcdir)/fused-src" +@HAVE_PYTHON_TRUE@ rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc" +@HAVE_PYTHON_TRUE@ rm -f "$(srcdir)/fused-src/gtest/gtest.h" +@HAVE_PYTHON_TRUE@ "$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src" +@HAVE_PYTHON_TRUE@ cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/" + +@HAVE_PYTHON_TRUE@maintainer-clean-local: +@HAVE_PYTHON_TRUE@ rm -rf "$(srcdir)/fused-src" + +# Disables 'make install' as installing a compiled version of Google +# Test can lead to undefined behavior due to violation of the +# One-Definition Rule. + +install-exec-local: + echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." + false + +install-data-local: + echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." + false + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/README b/cpp/thirdparty/protobuf-2.5.0/gtest/README new file mode 100644 index 0000000..17bf72f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/README @@ -0,0 +1,434 @@ +Google C++ Testing Framework +============================ + +http://code.google.com/p/googletest/ + +Overview +-------- + +Google's framework for writing C++ tests on a variety of platforms +(Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the +xUnit architecture. Supports automatic test discovery, a rich set of +assertions, user-defined assertions, death tests, fatal and non-fatal +failures, various options for running the tests, and XML test report +generation. + +Please see the project page above for more information as well as the +mailing list for questions, discussions, and development. There is +also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please +join us! + +Requirements for End Users +-------------------------- + +Google Test is designed to have fairly minimal requirements to build +and use with your projects, but there are some. Currently, we support +Linux, Windows, Mac OS X, and Cygwin. We will also make our best +effort to support other platforms (e.g. Solaris, AIX, and z/OS). +However, since core members of the Google Test project have no access +to these platforms, Google Test may have outstanding issues there. If +you notice any problems on your platform, please notify +googletestframework@googlegroups.com. Patches for fixing them are +even more welcome! + +### Linux Requirements ### + +These are the base requirements to build and use Google Test from a source +package (as described below): + * GNU-compatible Make or gmake + * POSIX-standard shell + * POSIX(-2) Regular Expressions (regex.h) + * A C++98-standard-compliant compiler + +### Windows Requirements ### + + * Microsoft Visual C++ 7.1 or newer + +### Cygwin Requirements ### + + * Cygwin 1.5.25-14 or newer + +### Mac OS X Requirements ### + + * Mac OS X 10.4 Tiger or newer + * Developer Tools Installed + +Also, you'll need CMake 2.6.4 or higher if you want to build the +samples using the provided CMake script, regardless of the platform. + +Requirements for Contributors +----------------------------- + +We welcome patches. If you plan to contribute a patch, you need to +build Google Test and its own tests from an SVN checkout (described +below), which has further requirements: + + * Python version 2.3 or newer (for running some of the tests and + re-generating certain source files from templates) + * CMake 2.6.4 or newer + +Getting the Source +------------------ + +There are two primary ways of getting Google Test's source code: you +can download a stable source release in your preferred archive format, +or directly check out the source from our Subversion (SVN) repositary. +The SVN checkout requires a few extra steps and some extra software +packages on your system, but lets you track the latest development and +make patches much more easily, so we highly encourage it. + +### Source Package ### + +Google Test is released in versioned source packages which can be +downloaded from the download page [1]. Several different archive +formats are provided, but the only difference is the tools used to +manipulate them, and the size of the resulting file. Download +whichever you are most comfortable with. + + [1] http://code.google.com/p/googletest/downloads/list + +Once the package is downloaded, expand it using whichever tools you +prefer for that type. This will result in a new directory with the +name "gtest-X.Y.Z" which contains all of the source code. Here are +some examples on Linux: + + tar -xvzf gtest-X.Y.Z.tar.gz + tar -xvjf gtest-X.Y.Z.tar.bz2 + unzip gtest-X.Y.Z.zip + +### SVN Checkout ### + +To check out the main branch (also known as the "trunk") of Google +Test, run the following Subversion command: + + svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn + +Setting up the Build +-------------------- + +To build Google Test and your tests that use it, you need to tell your +build system where to find its headers and source files. The exact +way to do it depends on which build system you use, and is usually +straightforward. + +### Generic Build Instructions ### + +Suppose you put Google Test in directory ${GTEST_DIR}. To build it, +create a library build target (or a project as called by Visual Studio +and Xcode) to compile + + ${GTEST_DIR}/src/gtest-all.cc + +with + + ${GTEST_DIR}/include and ${GTEST_DIR} + +in the header search path. Assuming a Linux-like system and gcc, +something like the following will do: + + g++ -I${GTEST_DIR}/include -I${GTEST_DIR} -c ${GTEST_DIR}/src/gtest-all.cc + ar -rv libgtest.a gtest-all.o + +Next, you should compile your test source file with +${GTEST_DIR}/include in the header search path, and link it with gtest +and any other necessary libraries: + + g++ -I${GTEST_DIR}/include path/to/your_test.cc libgtest.a -o your_test + +As an example, the make/ directory contains a Makefile that you can +use to build Google Test on systems where GNU make is available +(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google +Test's own tests. Instead, it just builds the Google Test library and +a sample test. You can use it as a starting point for your own build +script. + +If the default settings are correct for your environment, the +following commands should succeed: + + cd ${GTEST_DIR}/make + make + ./sample1_unittest + +If you see errors, try to tweak the contents of make/Makefile to make +them go away. There are instructions in make/Makefile on how to do +it. + +### Using CMake ### + +Google Test comes with a CMake build script (CMakeLists.txt) that can +be used on a wide range of platforms ("C" stands for cross-platofrm.). +If you don't have CMake installed already, you can download it for +free from http://www.cmake.org/. + +CMake works by generating native makefiles or build projects that can +be used in the compiler environment of your choice. The typical +workflow starts with: + + mkdir mybuild # Create a directory to hold the build output. + cd mybuild + cmake ${GTEST_DIR} # Generate native build scripts. + +If you want to build Google Test's samples, you should replace the +last command with + + cmake -Dgtest_build_samples=ON ${GTEST_DIR} + +If you are on a *nix system, you should now see a Makefile in the +current directory. Just type 'make' to build gtest. + +If you use Windows and have Vistual Studio installed, a gtest.sln file +and several .vcproj files will be created. You can then build them +using Visual Studio. + +On Mac OS X with Xcode installed, a .xcodeproj file will be generated. + +### Legacy Build Scripts ### + +Before settling on CMake, we have been providing hand-maintained build +projects/scripts for Visual Studio, Xcode, and Autotools. While we +continue to provide them for convenience, they are not actively +maintained any more. We highly recommend that you follow the +instructions in the previous two sections to integrate Google Test +with your existing build system. + +If you still need to use the legacy build scripts, here's how: + +The msvc\ folder contains two solutions with Visual C++ projects. +Open the gtest.sln or gtest-md.sln file using Visual Studio, and you +are ready to build Google Test the same way you build any Visual +Studio project. Files that have names ending with -md use DLL +versions of Microsoft runtime libraries (the /MD or the /MDd compiler +option). Files without that suffix use static versions of the runtime +libraries (the /MT or the /MTd option). Please note that one must use +the same option to compile both gtest and the test code. If you use +Visual Studio 2005 or above, we recommend the -md version as /MD is +the default for new projects in these versions of Visual Studio. + +On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using +Xcode. Build the "gtest" target. The universal binary framework will +end up in your selected build directory (selected in the Xcode +"Preferences..." -> "Building" pane and defaults to xcode/build). +Alternatively, at the command line, enter: + + xcodebuild + +This will build the "Release" configuration of gtest.framework in your +default build location. See the "xcodebuild" man page for more +information about building different configurations and building in +different locations. + +If you wish to use the Google Test Xcode project with Xcode 4.x and +above, you need to either: + * update the SDK configuration options in xcode/Config/General.xconfig. + Comment options SDKROOT, MACOS_DEPLOYMENT_TARGET, and GCC_VERSION. If + you choose this route you lose the ability to target earlier versions + of MacOS X. + * Install an SDK for an earlier version. This doesn't appear to be + supported by Apple, but has been reported to work + (http://stackoverflow.com/questions/5378518). + +Tweaking Google Test +-------------------- + +Google Test can be used in diverse environments. The default +configuration may not work (or may not work well) out of the box in +some environments. However, you can easily tweak Google Test by +defining control macros on the compiler command line. Generally, +these macros are named like GTEST_XYZ and you define them to either 1 +or 0 to enable or disable a certain feature. + +We list the most frequently used macros below. For a complete list, +see file include/gtest/internal/gtest-port.h. + +### Choosing a TR1 Tuple Library ### + +Some Google Test features require the C++ Technical Report 1 (TR1) +tuple library, which is not yet available with all compilers. The +good news is that Google Test implements a subset of TR1 tuple that's +enough for its own need, and will automatically use this when the +compiler doesn't provide TR1 tuple. + +Usually you don't need to care about which tuple library Google Test +uses. However, if your project already uses TR1 tuple, you need to +tell Google Test to use the same TR1 tuple library the rest of your +project uses, or the two tuple implementations will clash. To do +that, add + + -DGTEST_USE_OWN_TR1_TUPLE=0 + +to the compiler flags while compiling Google Test and your tests. If +you want to force Google Test to use its own tuple library, just add + + -DGTEST_USE_OWN_TR1_TUPLE=1 + +to the compiler flags instead. + +If you don't want Google Test to use tuple at all, add + + -DGTEST_HAS_TR1_TUPLE=0 + +and all features using tuple will be disabled. + +### Multi-threaded Tests ### + +Google Test is thread-safe where the pthread library is available. +After #include "gtest/gtest.h", you can check the GTEST_IS_THREADSAFE +macro to see whether this is the case (yes if the macro is #defined to +1, no if it's undefined.). + +If Google Test doesn't correctly detect whether pthread is available +in your environment, you can force it with + + -DGTEST_HAS_PTHREAD=1 + +or + + -DGTEST_HAS_PTHREAD=0 + +When Google Test uses pthread, you may need to add flags to your +compiler and/or linker to select the pthread library, or you'll get +link errors. If you use the CMake script or the deprecated Autotools +script, this is taken care of for you. If you use your own build +script, you'll need to read your compiler and linker's manual to +figure out what flags to add. + +### As a Shared Library (DLL) ### + +Google Test is compact, so most users can build and link it as a +static library for the simplicity. You can choose to use Google Test +as a shared library (known as a DLL on Windows) if you prefer. + +To compile *gtest* as a shared library, add + + -DGTEST_CREATE_SHARED_LIBRARY=1 + +to the compiler flags. You'll also need to tell the linker to produce +a shared library instead - consult your linker's manual for how to do +it. + +To compile your *tests* that use the gtest shared library, add + + -DGTEST_LINKED_AS_SHARED_LIBRARY=1 + +to the compiler flags. + +Note: while the above steps aren't technically necessary today when +using some compilers (e.g. GCC), they may become necessary in the +future, if we decide to improve the speed of loading the library (see +http://gcc.gnu.org/wiki/Visibility for details). Therefore you are +recommended to always add the above flags when using Google Test as a +shared library. Otherwise a future release of Google Test may break +your build script. + +### Avoiding Macro Name Clashes ### + +In C++, macros don't obey namespaces. Therefore two libraries that +both define a macro of the same name will clash if you #include both +definitions. In case a Google Test macro clashes with another +library, you can force Google Test to rename its macro to avoid the +conflict. + +Specifically, if both Google Test and some other code define macro +FOO, you can add + + -DGTEST_DONT_DEFINE_FOO=1 + +to the compiler flags to tell Google Test to change the macro's name +from FOO to GTEST_FOO. Currently FOO can be FAIL, SUCCEED, or TEST. +For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write + + GTEST_TEST(SomeTest, DoesThis) { ... } + +instead of + + TEST(SomeTest, DoesThis) { ... } + +in order to define a test. + +Upgrating from an Earlier Version +--------------------------------- + +We strive to keep Google Test releases backward compatible. +Sometimes, though, we have to make some breaking changes for the +users' long-term benefits. This section describes what you'll need to +do if you are upgrading from an earlier version of Google Test. + +### Upgrading from 1.3.0 or Earlier ### + +You may need to explicitly enable or disable Google Test's own TR1 +tuple library. See the instructions in section "Choosing a TR1 Tuple +Library". + +### Upgrading from 1.4.0 or Earlier ### + +The Autotools build script (configure + make) is no longer officially +supportted. You are encouraged to migrate to your own build system or +use CMake. If you still need to use Autotools, you can find +instructions in the README file from Google Test 1.4.0. + +On platforms where the pthread library is available, Google Test uses +it in order to be thread-safe. See the "Multi-threaded Tests" section +for what this means to your build script. + +If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google +Test will no longer compile. This should affect very few people, as a +large portion of STL (including ) doesn't compile in this mode +anyway. We decided to stop supporting it in order to greatly simplify +Google Test's implementation. + +Developing Google Test +---------------------- + +This section discusses how to make your own changes to Google Test. + +### Testing Google Test Itself ### + +To make sure your changes work as intended and don't break existing +functionality, you'll want to compile and run Google Test's own tests. +For that you can use CMake: + + mkdir mybuild + cd mybuild + cmake -Dgtest_build_tests=ON ${GTEST_DIR} + +Make sure you have Python installed, as some of Google Test's tests +are written in Python. If the cmake command complains about not being +able to find Python ("Could NOT find PythonInterp (missing: +PYTHON_EXECUTABLE)"), try telling it explicitly where your Python +executable can be found: + + cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR} + +Next, you can build Google Test and all of its own tests. On *nix, +this is usually done by 'make'. To run the tests, do + + make test + +All tests should pass. + +### Regenerating Source Files ### + +Some of Google Test's source files are generated from templates (not +in the C++ sense) using a script. A template file is named FOO.pump, +where FOO is the name of the file it will generate. For example, the +file include/gtest/internal/gtest-type-util.h.pump is used to generate +gtest-type-util.h in the same directory. + +Normally you don't need to worry about regenerating the source files, +unless you need to modify them. In that case, you should modify the +corresponding .pump files instead and run the pump.py Python script to +regenerate them. You can find pump.py in the scripts/ directory. +Read the Pump manual [2] for how to use it. + + [2] http://code.google.com/p/googletest/wiki/PumpManual + +### Contributing a Patch ### + +We welcome patches. Please read the Google Test developer's guide [3] +for how you can contribute. In particular, make sure you have signed +the Contributor License Agreement, or we won't be able to accept the +patch. + + [3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide + +Happy testing! diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/aclocal.m4 b/cpp/thirdparty/protobuf-2.5.0/gtest/aclocal.m4 new file mode 100644 index 0000000..e7df9fe --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/aclocal.m4 @@ -0,0 +1,1198 @@ +# generated automatically by aclocal 1.11.3 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.3], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.3])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, +# 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# --------------------------------------------------------------------------- +# Adds support for distributing Python modules and packages. To +# install modules, copy them to $(pythondir), using the python_PYTHON +# automake variable. To install a package with the same name as the +# automake package, install to $(pkgpythondir), or use the +# pkgpython_PYTHON automake variable. +# +# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as +# locations to install python extension modules (shared libraries). +# Another macro is required to find the appropriate flags to compile +# extension modules. +# +# If your package is configured with a different prefix to python, +# users will have to add the install directory to the PYTHONPATH +# environment variable, or create a .pth file (see the python +# documentation for details). +# +# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will +# cause an error if the version of python installed on the system +# doesn't meet the requirement. MINIMUM-VERSION should consist of +# numbers and dots only. +AC_DEFUN([AM_PATH_PYTHON], + [ + dnl Find a Python interpreter. Python versions prior to 2.0 are not + dnl supported. (2.0 was released on October 16, 2000). + m4_define_default([_AM_PYTHON_INTERPRETER_LIST], +[python python2 python3 python3.2 python3.1 python3.0 python2.7 dnl + python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0]) + + AC_ARG_VAR([PYTHON], [the Python interpreter]) + + m4_if([$1],[],[ + dnl No version check is needed. + # Find any Python interpreter. + if test -z "$PYTHON"; then + AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) + fi + am_display_PYTHON=python + ], [ + dnl A version check is needed. + if test -n "$PYTHON"; then + # If the user set $PYTHON, use it and don't search something else. + AC_MSG_CHECKING([whether $PYTHON version >= $1]) + AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], + [AC_MSG_RESULT(yes)], + [AC_MSG_ERROR(too old)]) + am_display_PYTHON=$PYTHON + else + # Otherwise, try each interpreter until we find one that satisfies + # VERSION. + AC_CACHE_CHECK([for a Python interpreter with version >= $1], + [am_cv_pathless_PYTHON],[ + for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do + test "$am_cv_pathless_PYTHON" = none && break + AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) + done]) + # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. + if test "$am_cv_pathless_PYTHON" = none; then + PYTHON=: + else + AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) + fi + am_display_PYTHON=$am_cv_pathless_PYTHON + fi + ]) + + if test "$PYTHON" = :; then + dnl Run any user-specified action, or abort. + m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) + else + + dnl Query Python for its version number. Getting [:3] seems to be + dnl the best way to do this; it's what "site.py" does in the standard + dnl library. + + AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], + [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`]) + AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) + + dnl Use the values of $prefix and $exec_prefix for the corresponding + dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made + dnl distinct variables so they can be overridden if need be. However, + dnl general consensus is that you shouldn't need this ability. + + AC_SUBST([PYTHON_PREFIX], ['${prefix}']) + AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}']) + + dnl At times (like when building shared libraries) you may want + dnl to know which OS platform Python thinks this is. + + AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], + [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`]) + AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) + + + dnl Set up 4 directories: + + dnl pythondir -- where to install python scripts. This is the + dnl site-packages directory, not the python standard library + dnl directory like in previous automake betas. This behavior + dnl is more consistent with lispdir.m4 for example. + dnl Query distutils for this directory. + AC_CACHE_CHECK([for $am_display_PYTHON script directory], + [am_cv_python_pythondir], + [if test "x$prefix" = xNONE + then + am_py_prefix=$ac_default_prefix + else + am_py_prefix=$prefix + fi + am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null` + case $am_cv_python_pythondir in + $am_py_prefix*) + am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` + am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` + ;; + *) + case $am_py_prefix in + /usr|/System*) ;; + *) + am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + ]) + AC_SUBST([pythondir], [$am_cv_python_pythondir]) + + dnl pkgpythondir -- $PACKAGE directory under pythondir. Was + dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is + dnl more consistent with the rest of automake. + + AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) + + dnl pyexecdir -- directory for installing python extension modules + dnl (shared libraries) + dnl Query distutils for this directory. + AC_CACHE_CHECK([for $am_display_PYTHON extension module directory], + [am_cv_python_pyexecdir], + [if test "x$exec_prefix" = xNONE + then + am_py_exec_prefix=$am_py_prefix + else + am_py_exec_prefix=$exec_prefix + fi + am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null` + case $am_cv_python_pyexecdir in + $am_py_exec_prefix*) + am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` + am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` + ;; + *) + case $am_py_exec_prefix in + /usr|/System*) ;; + *) + am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + ]) + AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) + + dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) + + AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) + + dnl Run any user-specified action. + $2 + fi + +]) + + +# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# --------------------------------------------------------------------------- +# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. +# Run ACTION-IF-FALSE otherwise. +# This test uses sys.hexversion instead of the string equivalent (first +# word of sys.version), in order to cope with versions such as 2.2c1. +# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000). +AC_DEFUN([AM_PYTHON_CHECK_VERSION], + [prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]] +sys.exit(sys.hexversion < minverhex)" + AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.guess b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.guess new file mode 100755 index 0000000..d622a44 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.guess @@ -0,0 +1,1530 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.h.in b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.h.in new file mode 100644 index 0000000..843b5b1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.h.in @@ -0,0 +1,69 @@ +/* build-aux/config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.sub b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.sub new file mode 100755 index 0000000..c894da4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/config.sub @@ -0,0 +1,1773 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/depcomp b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/depcomp new file mode 100755 index 0000000..bd0ac08 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/depcomp @@ -0,0 +1,688 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2011-12-04.11; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/ \1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/ / + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/install-sh b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/install-sh new file mode 100755 index 0000000..a9244eb --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-01-19.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for `test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/ltmain.sh b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/ltmain.sh new file mode 100644 index 0000000..c2852d8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/ltmain.sh @@ -0,0 +1,9661 @@ + +# libtool (GNU libtool) 2.4.2 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --no-warn don't display warning messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . +# GNU libtool home page: . +# General help using GNU software: . + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.2 Debian-2.4.2-1ubuntu1" +TIMESTAMP="" +package_revision=1.3337 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_warning=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-warning|--no-warn) + opt_warning=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$absdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type \`$version_type'" + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Remove ${wl} instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + func_resolve_sysroot "$deplib" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/missing b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/missing new file mode 100755 index 0000000..86a8fc3 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/build-aux/missing @@ -0,0 +1,331 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2012-01-06.13; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/cmake/internal_utils.cmake b/cpp/thirdparty/protobuf-2.5.0/gtest/cmake/internal_utils.cmake new file mode 100644 index 0000000..8cb2189 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/cmake/internal_utils.cmake @@ -0,0 +1,227 @@ +# Defines functions and macros useful for building Google Test and +# Google Mock. +# +# Note: +# +# - This file will be run twice when building Google Mock (once via +# Google Test's CMakeLists.txt, and once via Google Mock's). +# Therefore it shouldn't have any side effects other than defining +# the functions and macros. +# +# - The functions/macros defined in this file may depend on Google +# Test and Google Mock's option() definitions, and thus must be +# called *after* the options have been defined. + +# Tweaks CMake's default compiler/linker settings to suit Google Test's needs. +# +# This must be a macro(), as inside a function string() can only +# update variables in the function scope. +macro(fix_default_compiler_settings_) + if (MSVC) + # For MSVC, CMake sets certain flags to defaults we want to override. + # This replacement code is taken from sample in the CMake Wiki at + # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace. + foreach (flag_var + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt) + # When Google Test is built as a shared library, it should also use + # shared runtime libraries. Otherwise, it may end up with multiple + # copies of runtime library data in different modules, resulting in + # hard-to-find crashes. When it is built as a static library, it is + # preferable to use CRT as static libraries, as we don't have to rely + # on CRT DLLs being available. CMake always defaults to using shared + # CRT libraries, so we override that default here. + string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}") + endif() + + # We prefer more strict warning checking for building Google Test. + # Replaces /W3 with /W4 in defaults. + string(REPLACE "/W3" "-W4" ${flag_var} "${${flag_var}}") + endforeach() + endif() +endmacro() + +# Defines the compiler/linker flags used to build Google Test and +# Google Mock. You can tweak these definitions to suit your need. A +# variable's value is empty before it's explicitly assigned to. +macro(config_compiler_and_linker) + if (NOT gtest_disable_pthreads) + # Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT. + find_package(Threads) + endif() + + fix_default_compiler_settings_() + if (MSVC) + # Newlines inside flags variables break CMake's NMake generator. + # TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds. + set(cxx_base_flags "-GS -W4 -WX -wd4127 -wd4251 -wd4275 -nologo -J -Zi") + if (MSVC_VERSION LESS 1400) + # Suppress spurious warnings MSVC 7.1 sometimes issues. + # Forcing value to bool. + set(cxx_base_flags "${cxx_base_flags} -wd4800") + # Copy constructor and assignment operator could not be generated. + set(cxx_base_flags "${cxx_base_flags} -wd4511 -wd4512") + # Compatibility warnings not applicable to Google Test. + # Resolved overload was found by argument-dependent lookup. + set(cxx_base_flags "${cxx_base_flags} -wd4675") + endif() + set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32") + set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN") + set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1") + set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0") + set(cxx_no_rtti_flags "-GR-") + elseif (CMAKE_COMPILER_IS_GNUCXX) + set(cxx_base_flags "-Wall -Wshadow") + set(cxx_exception_flags "-fexceptions") + set(cxx_no_exception_flags "-fno-exceptions") + # Until version 4.3.2, GCC doesn't define a macro to indicate + # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI + # explicitly. + set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0") + set(cxx_strict_flags + "-Wextra -Wno-unused-parameter -Wno-missing-field-initializers") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") + set(cxx_exception_flags "-features=except") + # Sun Pro doesn't provide macros to indicate whether exceptions and + # RTTI are enabled, so we define GTEST_HAS_* explicitly. + set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0") + set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR + CMAKE_CXX_COMPILER_ID STREQUAL "XL") + # CMake 2.8 changes Visual Age's compiler ID to "XL". + set(cxx_exception_flags "-qeh") + set(cxx_no_exception_flags "-qnoeh") + # Until version 9.0, Visual Age doesn't define a macro to indicate + # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI + # explicitly. + set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "HP") + set(cxx_base_flags "-AA -mt") + set(cxx_exception_flags "-DGTEST_HAS_EXCEPTIONS=1") + set(cxx_no_exception_flags "+noeh -DGTEST_HAS_EXCEPTIONS=0") + # RTTI can not be disabled in HP aCC compiler. + set(cxx_no_rtti_flags "") + endif() + + if (CMAKE_USE_PTHREADS_INIT) # The pthreads library is available and allowed. + set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=1") + else() + set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=0") + endif() + + # For building gtest's own tests and samples. + set(cxx_exception "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_exception_flags}") + set(cxx_no_exception + "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}") + set(cxx_default "${cxx_exception}") + set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}") + set(cxx_use_own_tuple "${cxx_default} -DGTEST_USE_OWN_TR1_TUPLE=1") + + # For building the gtest libraries. + set(cxx_strict "${cxx_default} ${cxx_strict_flags}") +endmacro() + +# Defines the gtest & gtest_main libraries. User tests should link +# with one of them. +function(cxx_library_with_type name type cxx_flags) + # type can be either STATIC or SHARED to denote a static or shared library. + # ARGN refers to additional arguments after 'cxx_flags'. + add_library(${name} ${type} ${ARGN}) + set_target_properties(${name} + PROPERTIES + COMPILE_FLAGS "${cxx_flags}") + if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED") + set_target_properties(${name} + PROPERTIES + COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1") + endif() + if (CMAKE_USE_PTHREADS_INIT) + target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT}) + endif() +endfunction() + +######################################################################## +# +# Helper functions for creating build targets. + +function(cxx_shared_library name cxx_flags) + cxx_library_with_type(${name} SHARED "${cxx_flags}" ${ARGN}) +endfunction() + +function(cxx_library name cxx_flags) + cxx_library_with_type(${name} "" "${cxx_flags}" ${ARGN}) +endfunction() + +# cxx_executable_with_flags(name cxx_flags libs srcs...) +# +# creates a named C++ executable that depends on the given libraries and +# is built from the given source files with the given compiler flags. +function(cxx_executable_with_flags name cxx_flags libs) + add_executable(${name} ${ARGN}) + if (cxx_flags) + set_target_properties(${name} + PROPERTIES + COMPILE_FLAGS "${cxx_flags}") + endif() + if (BUILD_SHARED_LIBS) + set_target_properties(${name} + PROPERTIES + COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") + endif() + # To support mixing linking in static and dynamic libraries, link each + # library in with an extra call to target_link_libraries. + foreach (lib "${libs}") + target_link_libraries(${name} ${lib}) + endforeach() +endfunction() + +# cxx_executable(name dir lib srcs...) +# +# creates a named target that depends on the given libs and is built +# from the given source files. dir/name.cc is implicitly included in +# the source file list. +function(cxx_executable name dir libs) + cxx_executable_with_flags( + ${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN}) +endfunction() + +# Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE. +find_package(PythonInterp) + +# cxx_test_with_flags(name cxx_flags libs srcs...) +# +# creates a named C++ test that depends on the given libs and is built +# from the given source files with the given compiler flags. +function(cxx_test_with_flags name cxx_flags libs) + cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN}) + add_test(${name} ${name}) +endfunction() + +# cxx_test(name libs srcs...) +# +# creates a named test target that depends on the given libs and is +# built from the given source files. Unlike cxx_test_with_flags, +# test/name.cc is already implicitly included in the source file list. +function(cxx_test name libs) + cxx_test_with_flags("${name}" "${cxx_default}" "${libs}" + "test/${name}.cc" ${ARGN}) +endfunction() + +# py_test(name) +# +# creates a Python test with the given name whose main module is in +# test/name.py. It does nothing if Python is not installed. +function(py_test name) + # We are not supporting Python tests on Linux yet as they consider + # all Linux environments to be google3 and try to use google3 features. + if (PYTHONINTERP_FOUND) + # ${CMAKE_BINARY_DIR} is known at configuration time, so we can + # directly bind it from cmake. ${CTEST_CONFIGURATION_TYPE} is known + # only at ctest runtime (by calling ctest -c ), so + # we have to escape $ to delay variable substitution here. + add_test(${name} + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py + --build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE}) + endif() +endfunction() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest.cbproj b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest.cbproj new file mode 100644 index 0000000..95c3054 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest.cbproj @@ -0,0 +1,138 @@ + + + + {bca37a72-5b07-46cf-b44e-89f8e06451a2} + Release + + + true + + + true + true + Base + + + true + true + Base + + + true + lib + JPHNE + NO_STRICT + true + true + CppStaticLibrary + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. + rtl.lib;vcl.lib + 32 + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk + + + false + false + true + _DEBUG;$(Defines) + true + false + true + None + DEBUG + true + Debug + true + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppStaticLibrary + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + + + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 + + + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + 0 + + + 1 + + + 2 + + + 9 + + + 10 + + + 11 + + + 12 + + + 14 + + + 13 + + + 15 + + + 16 + + + 17 + + + 18 + + + Cfg_1 + + + Cfg_2 + + + \ No newline at end of file diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest.groupproj b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest.groupproj new file mode 100644 index 0000000..faf31ca --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest.groupproj @@ -0,0 +1,54 @@ + + + {c1d923e0-6cba-4332-9b6f-3420acbf5091} + + + + + + + + + Default.Personality + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_all.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_all.cc new file mode 100644 index 0000000..121b2d8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_all.cc @@ -0,0 +1,38 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: Josh Kelley (joshkel@gmail.com) +// +// Google C++ Testing Framework (Google Test) +// +// C++Builder's IDE cannot build a static library from files with hyphens +// in their name. See http://qc.codegear.com/wc/qcmain.aspx?d=70977 . +// This file serves as a workaround. + +#include "src/gtest-all.cc" diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_link.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_link.cc new file mode 100644 index 0000000..918eccd --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_link.cc @@ -0,0 +1,40 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: Josh Kelley (joshkel@gmail.com) +// +// Google C++ Testing Framework (Google Test) +// +// Links gtest.lib and gtest_main.lib into the current project in C++Builder. +// This means that these libraries can't be renamed, but it's the only way to +// ensure that Debug versus Release test builds are linked against the +// appropriate Debug or Release build of the libraries. + +#pragma link "gtest.lib" +#pragma link "gtest_main.lib" diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_main.cbproj b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_main.cbproj new file mode 100644 index 0000000..d76ce13 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_main.cbproj @@ -0,0 +1,82 @@ + + + + {bca37a72-5b07-46cf-b44e-89f8e06451a2} + Release + + + true + + + true + true + Base + + + true + true + Base + + + true + lib + JPHNE + NO_STRICT + true + true + CppStaticLibrary + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. + rtl.lib;vcl.lib + 32 + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk + + + false + false + true + _DEBUG;$(Defines) + true + false + true + None + DEBUG + true + Debug + true + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppStaticLibrary + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 + + + + + 0 + + + Cfg_1 + + + Cfg_2 + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_unittest.cbproj b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_unittest.cbproj new file mode 100644 index 0000000..dc5db8e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/codegear/gtest_unittest.cbproj @@ -0,0 +1,88 @@ + + + + {eea63393-5ac5-4b9c-8909-d75fef2daa41} + Release + + + true + + + true + true + Base + + + true + true + Base + + + exe + true + NO_STRICT + JPHNE + true + ..\test + true + CppConsoleApplication + true + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;.. + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test + true + + + false + false + true + _DEBUG;$(Defines) + true + false + true + None + DEBUG + true + Debug + true + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppConsoleApplication + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + + + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;$(OUTPUTDIR);..\test2NO_STRICTSTRICT + + + + + 0 + + + 1 + + + Cfg_1 + + + Cfg_2 + + + \ No newline at end of file diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/configure b/cpp/thirdparty/protobuf-2.5.0/gtest/configure new file mode 100755 index 0000000..9bfac5f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/configure @@ -0,0 +1,18222 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for Google C++ Testing Framework 1.6.0. +# +# Report bugs to . +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: googletestframework@googlegroups.com about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='Google C++ Testing Framework' +PACKAGE_TARNAME='gtest' +PACKAGE_VERSION='1.6.0' +PACKAGE_STRING='Google C++ Testing Framework 1.6.0' +PACKAGE_BUGREPORT='googletestframework@googlegroups.com' +PACKAGE_URL='' + +ac_unique_file="./LICENSE" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +HAVE_PTHREADS_FALSE +HAVE_PTHREADS_TRUE +PTHREAD_CFLAGS +PTHREAD_LIBS +PTHREAD_CC +acx_pthread_config +HAVE_PYTHON_FALSE +HAVE_PYTHON_TRUE +PYTHON +CXXCPP +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +with_pthreads +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures Google C++ Testing Framework 1.6.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/gtest] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of Google C++ Testing Framework 1.6.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + --with-pthreads use pthreads (default is yes) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +Google C++ Testing Framework configure 1.6.0 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by Google C++ Testing Framework $as_me 1.6.0, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Provide various options to initialize the Autoconf and configure processes. + + + +ac_aux_dir= +for ac_dir in build-aux "$srcdir"/build-aux; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +ac_config_headers="$ac_config_headers build-aux/config.h" + +ac_config_files="$ac_config_files Makefile" + +ac_config_files="$ac_config_files scripts/gtest-config" + + +# Initialize Automake with various options. We require at least v1.9, prevent +# pedantic complaints about package files, and enable various distribution +# targets. +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='gtest' + VERSION='1.6.0' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# Check for programs used in building Google Test. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.2' +macro_revision='1.3337' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +CC="$lt_save_CC" + + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +# TODO(chandlerc@google.com): Currently we aren't running the Python tests +# against the interpreter detected by AM_PATH_PYTHON, and so we condition +# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's +# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env" +# hashbang. +PYTHON= # We *do not* allow the user to specify a python interpreter +# Extract the first word of "python", so it can be a program name with args. +set dummy python; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PYTHON+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PYTHON in + [\\/]* | ?:[\\/]*) + ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_PYTHON" && ac_cv_path_PYTHON=":" + ;; +esac +fi +PYTHON=$ac_cv_path_PYTHON +if test -n "$PYTHON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 +$as_echo "$PYTHON" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "$PYTHON" != ":"; then : + prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '2.3'.split('.'))) + [0, 0, 0] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] +sys.exit(sys.hexversion < minverhex)" + if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 + ($PYTHON -c "$prog") >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then : + : +else + PYTHON=":" +fi +fi + if test "$PYTHON" != ":"; then + HAVE_PYTHON_TRUE= + HAVE_PYTHON_FALSE='#' +else + HAVE_PYTHON_TRUE='#' + HAVE_PYTHON_FALSE= +fi + + +# Configure pthreads. + +# Check whether --with-pthreads was given. +if test "${with_pthreads+set}" = set; then : + withval=$with_pthreads; with_pthreads=$withval +else + with_pthreads=check +fi + + +have_pthreads=no +if test "x$with_pthreads" != "xno"; then : + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 +$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_join (); +int +main () +{ +return pthread_join (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + acx_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 +$as_echo "$acx_pthread_ok" >&6; } + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 +$as_echo_n "checking whether pthreads work without any flags... " >&6; } + ;; + + -*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 +$as_echo_n "checking whether pthreads work with $flag... " >&6; } + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + # Extract the first word of "pthread-config", so it can be a program name with args. +set dummy pthread-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_acx_pthread_config+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$acx_pthread_config"; then + ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_acx_pthread_config="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no" +fi +fi +acx_pthread_config=$ac_cv_prog_acx_pthread_config +if test -n "$acx_pthread_config"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5 +$as_echo "$acx_pthread_config" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 +$as_echo_n "checking for the pthreads library -l$flag... " >&6; } + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + acx_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 +$as_echo "$acx_pthread_ok" >&6; } + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 +$as_echo_n "checking for joinable pthread attribute... " >&6; } + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +int attr=$attr; return attr; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + attr_name=$attr; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 +$as_echo "$attr_name" >&6; } + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + +cat >>confdefs.h <<_ACEOF +#define PTHREAD_CREATE_JOINABLE $attr_name +_ACEOF + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 +$as_echo_n "checking if more special flags are required for pthreads... " >&6; } + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 +$as_echo "${flag}" >&6; } + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + for ac_prog in xlc_r cc_r +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_PTHREAD_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PTHREAD_CC"; then + ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_PTHREAD_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PTHREAD_CC=$ac_cv_prog_PTHREAD_CC +if test -n "$PTHREAD_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 +$as_echo "$PTHREAD_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PTHREAD_CC" && break +done +test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" + + else + PTHREAD_CC=$CC + fi + + # The next part tries to detect GCC inconsistency with -shared on some + # architectures and systems. The problem is that in certain + # configurations, when -shared is specified, GCC "forgets" to + # internally use various flags which are still necessary. + + # + # Prepare the flags + # + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_CC="$CC" + + # Try with the flags determined by the earlier checks. + # + # -Wl,-z,defs forces link-time symbol resolution, so that the + # linking checks with -shared actually have any value + # + # FIXME: -fPIC is required for -shared on many architectures, + # so we specify it here, but the right way would probably be to + # properly detect whether it is actually required. + CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CC="$PTHREAD_CC" + + # In order not to create several levels of indentation, we test + # the value of "$done" until we find the cure or run out of ideas. + done="no" + + # First, make sure the CFLAGS we added are actually accepted by our + # compiler. If not (and OS X's ld, for instance, does not accept -z), + # then we can't do this test. + if test x"$done" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to check for GCC pthread/shared inconsistencies" >&5 +$as_echo_n "checking whether to check for GCC pthread/shared inconsistencies... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +else + done=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + if test "x$done" = xyes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + fi + fi + + if test x"$done" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -pthread is sufficient with -shared" >&5 +$as_echo_n "checking whether -pthread is sufficient with -shared... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + done=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + if test "x$done" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + + # + # Linux gcc on some architectures such as mips/mipsel forgets + # about -lpthread + # + if test x"$done" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lpthread fixes that" >&5 +$as_echo_n "checking whether -lpthread fixes that... " >&6; } + LIBS="-lpthread $PTHREAD_LIBS $save_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + done=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + if test "x$done" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PTHREAD_LIBS="-lpthread $PTHREAD_LIBS" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + # + # FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc + # + if test x"$done" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc_r fixes that" >&5 +$as_echo_n "checking whether -lc_r fixes that... " >&6; } + LIBS="-lc_r $PTHREAD_LIBS $save_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + done=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + if test "x$done" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PTHREAD_LIBS="-lc_r $PTHREAD_LIBS" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + if test x"$done" = xno; then + # OK, we have run out of ideas + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Impossible to determine how to use pthreads with shared libraries" >&5 +$as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries" >&2;} + + # so it's not safe to assume that we may use pthreads + acx_pthread_ok=no + fi + + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + CC="$save_CC" +else + PTHREAD_CC="$CC" +fi + + + + + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + +$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h + + : +else + acx_pthread_ok=no + if test "x$with_pthreads" != "xcheck"; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "--with-pthreads was specified, but unable to be used +See \`config.log' for more details" "$LINENO" 5; } +fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + have_pthreads="$acx_pthread_ok" +fi + if test "x$have_pthreads" == "xyes"; then + HAVE_PTHREADS_TRUE= + HAVE_PTHREADS_FALSE='#' +else + HAVE_PTHREADS_TRUE='#' + HAVE_PTHREADS_FALSE= +fi + + + + +# TODO(chandlerc@google.com) Check for the necessary system headers. + +# TODO(chandlerc@google.com) Check the types, structures, and other compiler +# and architecture characteristics. + +# Output the generated files. No further autoconf macros may be used. +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_PYTHON_TRUE}" && test -z "${HAVE_PYTHON_FALSE}"; then + as_fn_error $? "conditional \"HAVE_PYTHON\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_PTHREADS_TRUE}" && test -z "${HAVE_PTHREADS_FALSE}"; then + as_fn_error $? "conditional \"HAVE_PTHREADS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by Google C++ Testing Framework $as_me 1.6.0, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +Google C++ Testing Framework config.status 1.6.0 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "build-aux/config.h") CONFIG_HEADERS="$CONFIG_HEADERS build-aux/config.h" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "scripts/gtest-config") CONFIG_FILES="$CONFIG_FILES scripts/gtest-config" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "scripts/gtest-config":F) chmod +x scripts/gtest-config ;; + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/configure.ac b/cpp/thirdparty/protobuf-2.5.0/gtest/configure.ac new file mode 100644 index 0000000..37b298e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/configure.ac @@ -0,0 +1,68 @@ +m4_include(m4/acx_pthread.m4) + +# At this point, the Xcode project assumes the version string will be three +# integers separated by periods and surrounded by square brackets (e.g. +# "[1.0.1]"). It also asumes that there won't be any closing parenthesis +# between "AC_INIT(" and the closing ")" including comments and strings. +AC_INIT([Google C++ Testing Framework], + [1.6.0], + [googletestframework@googlegroups.com], + [gtest]) + +# Provide various options to initialize the Autoconf and configure processes. +AC_PREREQ([2.59]) +AC_CONFIG_SRCDIR([./LICENSE]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_HEADERS([build-aux/config.h]) +AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([scripts/gtest-config], [chmod +x scripts/gtest-config]) + +# Initialize Automake with various options. We require at least v1.9, prevent +# pedantic complaints about package files, and enable various distribution +# targets. +AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects]) + +# Check for programs used in building Google Test. +AC_PROG_CC +AC_PROG_CXX +AC_LANG([C++]) +AC_PROG_LIBTOOL + +# TODO(chandlerc@google.com): Currently we aren't running the Python tests +# against the interpreter detected by AM_PATH_PYTHON, and so we condition +# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's +# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env" +# hashbang. +PYTHON= # We *do not* allow the user to specify a python interpreter +AC_PATH_PROG([PYTHON],[python],[:]) +AS_IF([test "$PYTHON" != ":"], + [AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])]) +AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"]) + +# Configure pthreads. +AC_ARG_WITH([pthreads], + [AS_HELP_STRING([--with-pthreads], + [use pthreads (default is yes)])], + [with_pthreads=$withval], + [with_pthreads=check]) + +have_pthreads=no +AS_IF([test "x$with_pthreads" != "xno"], + [ACX_PTHREAD( + [], + [AS_IF([test "x$with_pthreads" != "xcheck"], + [AC_MSG_FAILURE( + [--with-pthreads was specified, but unable to be used])])]) + have_pthreads="$acx_pthread_ok"]) +AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" == "xyes"]) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_LIBS) + +# TODO(chandlerc@google.com) Check for the necessary system headers. + +# TODO(chandlerc@google.com) Check the types, structures, and other compiler +# and architecture characteristics. + +# Output the generated files. No further autoconf macros may be used. +AC_OUTPUT diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest-all.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest-all.cc new file mode 100644 index 0000000..7688ca4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest-all.cc @@ -0,0 +1,9251 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include "gtest/gtest.h" + +// The following lines pull in the real gtest *.cc files. +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) + +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Utilities for testing Google Test itself and code that uses Google Test +// (e.g. frameworks built on top of Google Test). + +#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ +#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + + +namespace testing { + +// This helper class can be used to mock out Google Test failure reporting +// so that we can test Google Test or code that builds on Google Test. +// +// An object of this class appends a TestPartResult object to the +// TestPartResultArray object given in the constructor whenever a Google Test +// failure is reported. It can either intercept only failures that are +// generated in the same thread that created this object or it can intercept +// all generated failures. The scope of this mock object can be controlled with +// the second argument to the two arguments constructor. +class GTEST_API_ ScopedFakeTestPartResultReporter + : public TestPartResultReporterInterface { + public: + // The two possible mocking modes of this object. + enum InterceptMode { + INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. + INTERCEPT_ALL_THREADS // Intercepts all failures. + }; + + // The c'tor sets this object as the test part result reporter used + // by Google Test. The 'result' parameter specifies where to report the + // results. This reporter will only catch failures generated in the current + // thread. DEPRECATED + explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + + // Same as above, but you can choose the interception scope of this object. + ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, + TestPartResultArray* result); + + // The d'tor restores the previous test part result reporter. + virtual ~ScopedFakeTestPartResultReporter(); + + // Appends the TestPartResult object to the TestPartResultArray + // received in the constructor. + // + // This method is from the TestPartResultReporterInterface + // interface. + virtual void ReportTestPartResult(const TestPartResult& result); + private: + void Init(); + + const InterceptMode intercept_mode_; + TestPartResultReporterInterface* old_reporter_; + TestPartResultArray* const result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); +}; + +namespace internal { + +// A helper class for implementing EXPECT_FATAL_FAILURE() and +// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +class GTEST_API_ SingleFailureChecker { + public: + // The constructor remembers the arguments. + SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr); + ~SingleFailureChecker(); + private: + const TestPartResultArray* const results_; + const TestPartResult::Type type_; + const string substr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +}; + +} // namespace internal + +} // namespace testing + +// A set of macros for testing Google Test assertions or code that's expected +// to generate Google Test fatal failures. It verifies that the given +// statement will cause exactly one fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_FATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - 'statement' cannot reference local non-static variables or +// non-static members of the current object. +// - 'statement' cannot return a value. +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ALL_THREADS, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +// A macro for testing Google Test assertions or code that's expected to +// generate Google Test non-fatal failures. It asserts that the given +// statement will cause exactly one non-fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// 'statement' is allowed to reference local variables and members of +// the current object. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ + >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // NOLINT +#include +#include + +#if GTEST_OS_LINUX + +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +# include // NOLINT +# include // NOLINT +# include // NOLINT +// Declares vsnprintf(). This header is not available on Windows. +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include + +#elif GTEST_OS_SYMBIAN +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +#elif GTEST_OS_ZOS +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +# include // NOLINT + +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. + +# include // NOLINT + +#elif GTEST_OS_WINDOWS // We are on Windows proper. + +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT + +# if GTEST_OS_WINDOWS_MINGW +// MinGW has gettimeofday() but not _ftime64(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +// TODO(kenton@google.com): There are other ways to get the time on +// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW +// supports these. consider using them instead. +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT +# endif // GTEST_OS_WINDOWS_MINGW + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT + +#else + +// Assume other platforms have gettimeofday(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT +# include // NOLINT + +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +# include +#endif + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +#endif + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// Utility functions and classes used by the Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This file contains purely Google Test's internal implementation. Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ +// A user is trying to include this from his code - just say no. +# error "gtest-internal-inl.h is part of Google Test's internal implementation." +# error "It must not be included except by Google Test itself." +#endif // GTEST_IMPLEMENTATION_ + +#ifndef _WIN32_WCE +# include +#endif // !_WIN32_WCE +#include +#include // For strtoll/_strtoul64/malloc/free. +#include // For memmove. + +#include +#include +#include + + +#if GTEST_OS_WINDOWS +# include // NOLINT +#endif // GTEST_OS_WINDOWS + + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; +const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kStreamResultToFlag[] = "stream_result_to"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Converts the given time in milliseconds to a date string in the ISO 8601 +// format, without the timezone information. N.B.: due to the use the +// non-reentrant localtime() function, this function is not thread safe. Do +// not use it in any code that can be called from multiple threads. +GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast(GetTimeInMillis()) : + static_cast(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast((raw_seed - 1U) % + static_cast(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: + // The c'tor. + GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + stream_result_to_ = GTEST_FLAG(stream_result_to); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } + + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(stream_result_to) = stream_result_to_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } + + private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + std::string color_; + std::string death_test_style_; + bool death_test_use_fork_; + std::string filter_; + std::string internal_run_death_test_; + bool list_tests_; + std::string output_; + bool print_time_; + bool pretty_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + std::string stream_result_to_; + bool throw_on_failure_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template +inline int CountIf(const Container& c, Predicate predicate) { + // Implemented as an explicit loop since std::count_if() in libCstd on + // Solaris has a non-standard signature. + int count = 0; + for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { + if (predicate(*it)) + ++count; + } + return count; +} + +// Applies a function/functor to each element in the container. +template +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} + +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template +inline E GetElementOr(const std::vector& v, int i, E default_value) { + return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; +} + +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector* v) { + const int size = static_cast(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); + } +} + +// Performs an in-place shuffle of the vector's elements. +template +inline void Shuffle(internal::Random* random, std::vector* v) { + ShuffleRange(random, 0, static_cast(v->size()), v); +} + +// A function for deleting an object. Handy for being used as a +// functor. +template +static void Delete(T* x) { + delete x; +} + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const char* key) + : key_(key) {} + + // Returns true iff the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const { + return test_property.key() == key_; + } + + private: + std::string key_; +}; + +// Class UnitTestOptions. +// +// This class contains functions for processing options the user +// specifies when running the tests. It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag. E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter. If both +// the variable and the flag are present, the latter overrides the +// former. +class GTEST_API_ UnitTestOptions { + public: + // Functions for processing the gtest_output flag. + + // Returns the output format, or "" for normal printed output. + static std::string GetOutputFormat(); + + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static std::string GetAbsolutePathToOutputFile(); + + // Functions for processing the gtest_filter flag. + + // Returns true iff the wildcard pattern matches the string. The + // first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char *pattern, const char *str); + + // Returns true iff the user-specified filter matches the test case + // name and the test name. + static bool FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name); + +#if GTEST_OS_WINDOWS + // Function for supporting the gtest_catch_exception flag. + + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); +#endif // GTEST_OS_WINDOWS + + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const std::string& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present. Used by UnitTestOptions::GetOutputFile. +GTEST_API_ FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} + + // Returns the current OS stack trace as an std::string. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; + + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: + OsStackTraceGetter() : caller_frame_(NULL) {} + + virtual string CurrentStackTrace(int max_depth, int skip_count) + GTEST_LOCK_EXCLUDED_(mutex_); + + virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); + + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + + private: + Mutex mutex_; // protects all internal state + + // We save the stack frame below the frame that calls user code. + // We do this because the address of the frame immediately below + // the user code changes between the call to UponLeavingGTest() + // and any calls to CurrentStackTrace() from within the user code. + void* caller_frame_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { + const char* file; + int line; + std::string message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); +}; + +// The private implementation of the UnitTest class. We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class GTEST_API_ UnitTestImpl { + public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); + + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); + + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const { return start_timestamp_; } + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const { return !Failed(); } + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const { + return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; + } + + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); + + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); + + // Returns the current OS stack trace as an std::string. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; + + // Finds and returns a TestCase with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_case_name: name of the test case + // type_param: the name of the test's type parameter, or NULL if + // this is not a typed or a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase* GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + // test_info: the TestInfo object + void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + TestInfo* test_info) { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } + + GetTestCase(test_info->test_case_name(), + test_info->type_param(), + set_up_tc, + tear_down_tc)->AddTestInfo(test_info); + } + +#if GTEST_HAS_PARAM_TEST + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } +#endif // GTEST_HAS_PARAM_TEST + + // Sets the TestCase object for the test that's currently running. + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has guards + // protecting from registering the tests more then once. If + // value-parameterized tests are disabled, RegisterParameterizedTests is + // present but does nothing. + void RegisterParameterizedTests(); + + // Runs all tests in this UnitTest object, prints the result, and + // returns true if all tests are successful. If any exception is + // thrown during a test, this test is considered to be failed, but + // the rest of the tests will still be run. + bool RunAllTests(); + + // Clears the results of all tests, except the ad hoc tests. + void ClearNonAdHocTestResult() { + ForEach(test_cases_, TestCase::ClearTestCaseResult); + } + + // Clears the results of ad-hoc test assertions. + void ClearAdHocTestResult() { + ad_hoc_test_result_.Clear(); + } + + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); + + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); + + const TestCase* current_test_case() const { return current_test_case_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } + + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector& environments() { return environments_; } + + // Getters for the per-thread Google Test trace stack. + std::vector& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); + } + const std::vector& gtest_trace_stack() const { + return gtest_trace_stack_.get(); + } + +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const { + return internal_run_death_test_flag_.get(); + } + + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() { + return death_test_factory_.get(); + } + + void SuppressTestEventsIfInSubprocess(); + + friend class ReplaceDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Initializes the event listener for streaming test results to a socket. + // Must not be called before InitGoogleTest. + void ConfigureStreamingOutput(); +#endif + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + + // Returns the value of GTEST_FLAG(catch_exceptions) at the moment + // UnitTest::Run() starts. + bool catch_exceptions() const { return catch_exceptions_; } + + private: + friend class ::testing::UnitTest; + + // Used by UnitTest::Run() to capture the state of + // GTEST_FLAG(catch_exceptions) at the moment it starts. + void set_catch_exceptions(bool value) { catch_exceptions_ = value; } + + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; + + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; + + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal + per_thread_test_part_result_reporter_; + + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector environments_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector test_cases_; + + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector test_case_indices_; + +#if GTEST_HAS_PARAM_TEST + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; +#endif // GTEST_HAS_PARAM_TEST + + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; + + // This points to the TestCase for the currently running test. It + // changes as Google Test goes through one test case after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestCase* current_test_case_; + + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; + + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; + + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; + + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; + + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + + // The time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp_; + + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; + +#if GTEST_HAS_DEATH_TEST + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + internal::scoped_ptr internal_run_death_test_flag_; + internal::scoped_ptr death_test_factory_; +#endif // GTEST_HAS_DEATH_TEST + + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal > gtest_trace_stack_; + + // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() + // starts. + bool catch_exceptions_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +}; // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { + return UnitTest::GetInstance()->impl(); +} + +#if GTEST_USES_SIMPLE_RE + +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsAsciiDigit(char ch); +GTEST_API_ bool IsAsciiPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsAsciiWhiteSpace(char ch); +GTEST_API_ bool IsAsciiWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + +#endif // GTEST_USES_SIMPLE_RE + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +GTEST_API_ std::string GetLastErrnoDescription(); + +# if GTEST_OS_WINDOWS +// Provides leak-safe Windows kernel handle ownership. +class AutoHandle { + public: + AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} + explicit AutoHandle(HANDLE handle) : handle_(handle) {} + + ~AutoHandle() { Reset(); } + + HANDLE Get() const { return handle_; } + void Reset() { Reset(INVALID_HANDLE_VALUE); } + void Reset(HANDLE handle) { + if (handle != handle_) { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + handle_ = handle; + } + } + + private: + HANDLE handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; +# endif // GTEST_OS_WINDOWS + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !IsDigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. + +# if GTEST_OS_WINDOWS && !defined(__GNUC__) + + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); + +# else + + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); + +# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast(parsed); + if (parse_success && static_cast(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const TestProperty& property) { + test_result->RecordProperty(property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS +# define vsnprintf _vsnprintf +#endif // GTEST_OS_WINDOWS + +namespace testing { + +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + +// Constants. + +// A test whose test case name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test case whose name matches this filter is considered a death +// test case and will be run before test cases whose name doesn't +// match this filter. +static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output file for XML output. +static const char kDefaultOutputFile[] = "test_detail.xml"; + +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + +} // namespace internal + +GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( + break_on_failure, + internal::BoolFromGTestEnv("break_on_failure", false), + "True iff a failed assertion should be a debugger break-point."); + +GTEST_DEFINE_bool_( + catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", true), + "True iff " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to xterm, xterm-color, xterm-256color, linux or cygwin."); + +GTEST_DEFINE_string_( + filter, + internal::StringFromGTestEnv("filter", kUniversalFilter), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); + +GTEST_DEFINE_string_( + output, + internal::StringFromGTestEnv("output", ""), + "A format (currently must be \"xml\"), optionally followed " + "by a colon and an output file name or directory. A directory " + "is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); + +GTEST_DEFINE_bool_( + print_time, + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ + " should display elapsed time in text output."); + +GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +GTEST_DEFINE_int32_( + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); + +GTEST_DEFINE_bool_( + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_( + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); + +GTEST_DEFINE_int32_( + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_string_( + stream_result_to, + internal::StringFromGTestEnv("stream_result_to", ""), + "This flag specifies the host name and the port number on which to stream " + "test results. Example: \"localhost:555\". The flag is effective only on " + "Linux."); + +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); + +namespace internal { + +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + +// GTestIsInitialized() returns true iff the user has initialized +// Google Test. Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +// +// A user must call testing::InitGoogleTest() to initialize Google +// Test. g_init_gtest_count is set to the number of times +// InitGoogleTest() has been called. We don't protect this variable +// under a mutex as it is only accessed in the main thread. +GTEST_API_ int g_init_gtest_count = 0; +static bool GTestIsInitialized() { return g_init_gtest_count != 0; } + +// Iterates over a vector of TestCases, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestCaseList(const std::vector& case_list, + int (TestCase::*method)() const) { + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); + } + return sum; +} + +// Returns true iff the test case passed. +static bool TestCasePassed(const TestCase* test_case) { + return test_case->should_run() && test_case->Passed(); +} + +// Returns true iff the test case failed. +static bool TestCaseFailed(const TestCase* test_case) { + return test_case->should_run() && test_case->Failed(); +} + +// Returns true iff test_case contains at least one test that should +// run. +static bool ShouldRunTestCase(const TestCase* test_case) { + return test_case->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { + UnitTest::GetInstance()-> + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl() + ->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT +} + +// Mutex for linked pointers. +GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// Application pathname gotten in InitGoogleTest. +std::string g_executable_path; + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { + FilePath result; + +#if GTEST_OS_WINDOWS + result.Set(FilePath(g_executable_path).RemoveExtension("exe")); +#else + result.Set(FilePath(g_executable_path)); +#endif // GTEST_OS_WINDOWS + + return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +std::string UnitTestOptions::GetOutputFormat() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) return std::string(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == NULL) ? + std::string(gtest_output_flag) : + std::string(gtest_output_flag, colon - gtest_output_flag); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +std::string UnitTestOptions::GetAbsolutePathToOutputFile() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) + return ""; + + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == NULL) + return internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).string(); + + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + + if (!output_name.IsDirectory()) + return output_name.string(); + + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.string(); +} + +// Returns true iff the wildcard pattern matches the string. The +// first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, + const char *str) { + switch (*pattern) { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } +} + +bool UnitTestOptions::MatchesFilter( + const std::string& name, const char* filter) { + const char *cur_pattern = filter; + for (;;) { + if (PatternMatchesString(cur_pattern, name.c_str())) { + return true; + } + + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); + + // Returns if no more pattern can be found. + if (cur_pattern == NULL) { + return false; + } + + // Skips the pattern separater (the ':' character). + cur_pattern++; + } +} + +// Returns true iff the user-specified filter matches the test case +// name and the test name. +bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name) { + const std::string& full_name = test_case_name + "." + test_name.c_str(); + + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + std::string positive; + std::string negative; + if (dash == NULL) { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = ""; + } else { + positive = std::string(p, dash); // Everything up to the dash + negative = std::string(dash + 1); // Everything after the dash + if (positive.empty()) { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } + + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); +} + +#if GTEST_HAS_SEH +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { + // Google Test should handle a SEH exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception, AND + // 3. this is not a C++ exception (VC++ implements them via SEH, + // apparently). + // + // SEH exception code for C++ exceptions. + // (see http://support.microsoft.com/kb/185294 for more information). + const DWORD kCxxExceptionCode = 0xe06d7363; + + bool should_handle = true; + + if (!GTEST_FLAG(catch_exceptions)) + should_handle = false; + else if (exception_code == EXCEPTION_BREAKPOINT) + should_handle = false; + else if (exception_code == kCxxExceptionCode) + should_handle = false; + + return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} +#endif // GTEST_HAS_SEH + +} // namespace internal + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test. We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test. This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X. The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code. GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { + return GetTypeId(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +AssertionResult HasOneFailure(const char* /* results_expr */, + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const string& substr) { + const std::string expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); + Message msg; + if (results.size() != 1) { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) { + msg << "\n" << results.GetTestPartResult(i); + } + return AssertionFailure() << msg; + } + + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) { + return AssertionFailure() << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + } + + if (strstr(r.message(), substr.c_str()) == NULL) { + return AssertionFailure() << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + } + + return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker:: SingleFailureChecker( + const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr) + : results_(results), + type_(type), + substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter) { + per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test cases. +int UnitTestImpl::successful_test_case_count() const { + return CountIf(test_cases_, TestCasePassed); +} + +// Gets the number of failed test cases. +int UnitTestImpl::failed_test_case_count() const { + return CountIf(test_cases_, TestCaseFailed); +} + +// Gets the number of all test cases. +int UnitTestImpl::total_test_case_count() const { + return static_cast(test_cases_.size()); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTestImpl::test_case_to_run_count() const { + return CountIf(test_cases_, ShouldRunTestCase); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { + (void)skip_count; + return ""; +} + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; + + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + // TODO(kenton@google.com): Shouldn't this just use + // GetSystemTimeAsFileTime()? + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ + __timeb64 now; + +# ifdef _MSC_VER + + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + // TODO(kenton@google.com): Use GetTickCount()? Or use + // SystemTimeToFileTime() +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996. + _ftime64(&now); +# pragma warning(pop) // Restores the warning state. +# else + + _ftime64(&now); + +# endif // _MSC_VER + + return static_cast(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, NULL); + return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +# error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String. + +#if GTEST_OS_WINDOWS_MOBILE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { + if (!ansi) return NULL; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, + NULL, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { + if (!utf16_str) return NULL; + const int ansi_length = + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + NULL, 0, NULL, NULL); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + ansi, ansi_length, NULL, NULL); + ansi[ansi_length] = 0; + return ansi; +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +// Compares two C strings. Returns true iff they have the same content. +// +// Unlike strcmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + + return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, + Message* msg) { + for (size_t i = 0; i != length; ) { // NOLINT + if (wstr[i] != L'\0') { + *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } else { + *msg << '\0'; + i++; + } + } +} + +#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +} // namespace internal + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new ::std::string(*other.message_) : + static_cast< ::std::string*>(NULL)) { +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { + return AssertionResult(true); +} + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +namespace internal { + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case) { + Message msg; + msg << "Value of: " << actual_expression; + if (actual_value != actual_expression) { + msg << "\n Actual: " << actual_value; + } + + msg << "\nExpected: " << expected_expression; + if (ignoring_case) { + msg << " (ignoring case)"; + } + if (expected_value != expected_expression) { + msg << "\nWhich is: " << expected_value; + } + + return AssertionFailure() << msg; +} + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) { + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); + + // TODO(wan): do not print the value of an expression if it's + // already a literal. + return AssertionFailure() + << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template +AssertionResult FloatingPointLE(const char* expr1, + const char* expr2, + RawType val1, + RawType val2) { + // Returns success if val1 is less than val2, + if (val1 < val2) { + return AssertionSuccess(); + } + + // or if val1 is almost equal to val2. + const FloatingPoint lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. + + ::std::stringstream val1_ss; + val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val1; + + ::std::stringstream val2_ss; + val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val2; + + return AssertionFailure() + << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StringStreamToString(&val1_ss) << " vs " + << StringStreamToString(&val2_ss); +} + +} // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + if (expected == actual) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CaseInsensitiveCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CaseInsensitiveCStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +} // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true iff needle is a +// substring of haystack. NULL is considered a substring of itself +// only. + +bool IsSubstringPred(const char* needle, const char* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return strstr(haystack, needle) != NULL; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return wcsstr(haystack, needle) != NULL; +} + +// StringType here can be either ::std::string or ::std::wstring. +template +bool IsSubstringPred(const StringType& needle, + const StringType& haystack) { + return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template +AssertionResult IsSubstringImpl( + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) { + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""; +} + +} // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +#if GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, + const char* expected, + long hr) { // NOLINT +# if GTEST_OS_WINDOWS_MOBILE + + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; + +# else + + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; // String::Format can't exceed this length. + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = { '\0' }; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + hr, // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + NULL); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing cr-lf) + for (; message_length && IsSpace(error_text[message_length - 1]); + --message_length) { + error_text[message_length - 1] = '\0'; + } + +# endif // GTEST_OS_WINDOWS_MOBILE + + const std::string error_hex(String::Format("0x%08X ", hr)); + return ::testing::AssertionFailure() + << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << error_text << "\n"; +} + +} // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT + if (SUCCEEDED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT + if (FAILED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length Encoding +// 0 - 7 bits 0xxxxxxx +// 8 - 11 bits 110xxxxx 10xxxxxx +// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx +// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern. Returns the n +// lowest bits. As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { + const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); + *bits >>= n; + return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +char* CodePointToUtf8(UInt32 code_point, char* str) { + if (code_point <= kMaxCodePoint1) { + str[1] = '\0'; + str[0] = static_cast(code_point); // 0xxxxxxx + } else if (code_point <= kMaxCodePoint2) { + str[2] = '\0'; + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xC0 | code_point); // 110xxxxx + } else if (code_point <= kMaxCodePoint3) { + str[3] = '\0'; + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xE0 | code_point); // 1110xxxx + } else if (code_point <= kMaxCodePoint4) { + str[4] = '\0'; + str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xF0 | code_point); // 11110xxx + } else { + // The longest string String::Format can produce when invoked + // with these parameters is 28 character long (not including + // the terminating nul character). We are asking for 32 character + // buffer just in case. This is also enough for strncpy to + // null-terminate the destination string. + posix::StrNCpy( + str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32); + str[31] = '\0'; // Makes sure no change in the format to strncpy leaves + // the result unterminated. + } + return str; +} + +// The following two functions only make sense if the the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast(first); +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +std::string WideStringToUtf8(const wchar_t* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast(wcslen(str)); + + ::std::stringstream stream; + for (int i = 0; i < num_chars; ++i) { + UInt32 unicode_code_point; + + if (str[i] == L'\0') { + break; + } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } else { + unicode_code_point = static_cast(str[i]); + } + + char buffer[32]; // CodePointToUtf8 requires a buffer this big. + stream << CodePointToUtf8(unicode_code_point, buffer); + } + return StringStreamToString(&stream); +} + +// Converts a wide C string to an std::string using the UTF-8 encoding. +// NULL will be converted to "(null)". +std::string String::ShowWideCString(const wchar_t * wide_c_str) { + if (wide_c_str == NULL) return "(null)"; + + return internal::WideStringToUtf8(wide_c_str, -1); +} + +// Compares two wide C strings. Returns true iff they have the same +// content. +// +// Unlike wcscmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + + return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual) { + if (String::WideCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) { + if (!String::WideCStringEquals(s1, s2)) { + return AssertionSuccess(); + } + + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << PrintToString(s1) + << " vs " << PrintToString(s2); +} + +// Compares two C strings, ignoring case. Returns true iff they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s). A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; +} + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + +#if GTEST_OS_WINDOWS + return _wcsicmp(lhs, rhs) == 0; +#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID + return wcscasecmp(lhs, rhs) == 0; +#else + // Android, Mac OS X and Cygwin don't define wcscasecmp. + // Other unknown OSes may not define it either. + wint_t left, right; + do { + left = towlower(*lhs++); + right = towlower(*rhs++); + } while (left && left == right); + return left == right; +#endif // OS selector +} + +// Returns true iff str ends with the given suffix, ignoring case. +// Any string is considered to end with an empty suffix. +bool String::EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix) { + const size_t str_len = str.length(); + const size_t suffix_len = suffix.length(); + return (str_len >= suffix_len) && + CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, + suffix.c_str()); +} + +// Formats a list of arguments to an std::string, using the same format +// spec string as for printf. +// +// We do not use the StringPrintf class as it is not universally +// available. +// +// The result is limited to 4096 characters (including the tailing 0). +// If 4096 characters are not enough to format the input, or if +// there's an error, "" is +// returned. +std::string String::Format(const char * format, ...) { + va_list args; + va_start(args, format); + + char buffer[4096]; + const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]); + + // MSVC 8 deprecates vsnprintf(), so we want to suppress warning + // 4996 (deprecated function) there. +#ifdef _MSC_VER // We are using MSVC. +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996. + + const int size = vsnprintf(buffer, kBufferSize, format, args); + +# pragma warning(pop) // Restores the warning state. +#else // We are not using MSVC. + const int size = vsnprintf(buffer, kBufferSize, format, args); +#endif // _MSC_VER + va_end(args); + + // vsnprintf()'s behavior is not portable. When the buffer is not + // big enough, it returns a negative value in MSVC, and returns the + // needed buffer size on Linux. When there is an output error, it + // always returns a negative value. For simplicity, we lump the two + // error cases together. + if (size < 0 || size >= kBufferSize) { + return ""; + } else { + return std::string(buffer, size); + } +} + +// Converts the buffer in a stringstream to an std::string, converting NUL +// bytes to "\\0" along the way. +std::string StringStreamToString(::std::stringstream* ss) { + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); + + std::string result; + result.reserve(2 * (end - start)); + for (const char* ch = start; ch != end; ++ch) { + if (*ch == '\0') { + result += "\\0"; // Replaces NUL with "\\0"; + } else { + result += *ch; + } + } + + return result; +} + +// Appends the user-supplied message to the Google-Test-generated message. +std::string AppendUserMessage(const std::string& gtest_msg, + const Message& user_msg) { + // Appends the user message if it's non-empty. + const std::string user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) { + return gtest_msg; + } + + return gtest_msg + "\n" + user_msg_string; +} + +} // namespace internal + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() + : death_test_count_(0), + elapsed_time_(0) { +} + +// D'tor. +TestResult::~TestResult() { +} + +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { + test_part_results_.push_back(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const TestProperty& test_property) { + if (!ValidateTestProperty(test_property)) { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); +} + +// Adds a failure if the key is a reserved attribute of Google Test +// testcase tags. Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const TestProperty& test_property) { + const std::string& key = test_property.key(); + if (key == "name" || key == "status" || key == "time" || key == "classname") { + ADD_FAILURE() + << "Reserved key used in RecordProperty(): " + << key + << " ('name', 'status', 'time', and 'classname' are reserved by " + << GTEST_NAME_ << ")"; + return false; + } + return true; +} + +// Clears the object. +void TestResult::Clear() { + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; +} + +// Returns true iff the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; +} + +// Returns true iff the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult& result) { + return result.fatally_failed(); +} + +// Returns true iff the test fatally failed. +bool TestResult::HasFatalFailure() const { + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true iff the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true iff the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +} + +// Gets the number of all test parts. This is the sum of the number +// of successful test parts and the number of failed test parts. +int TestResult::total_part_count() const { + return static_cast(test_part_results_.size()); +} + +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast(test_properties_.size()); +} + +// class Test + +// Creates a Test object. + +// The c'tor saves the values of all Google Test flags. +Test::Test() + : gtest_flag_saver_(new internal::GTestFlagSaver) { +} + +// The d'tor restores the values of all Google Test flags. +Test::~Test() { + delete gtest_flag_saver_; +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, const char* value) { + UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, int value) { + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); +} + +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + ""); // No stack trace, either. +} + +} // namespace internal + +// Google Test requires all tests in the same test case to use the same test +// fixture class. This function checks if the current test has the +// same fixture class as the first test in the current test case. If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestCase* const test_case = impl->current_test_case(); + + // Info about the first test in the current test case. + const TestInfo* const first_test_info = test_case->test_info_list()[0]; + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; + const char* const first_test_name = first_test_info->name(); + + // Info about the current test. + const TestInfo* const this_test_info = impl->current_test_info(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; + const char* const this_test_name = this_test_info->name(); + + if (this_fixture_id != first_fixture_id) { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + + if (first_is_TEST || this_is_TEST) { + // The user mixed TEST and TEST_F in this test case - we'll tell + // him/her how to fix it. + + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; + + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test case is\n" + << "illegal. In test case " << this_test_info->test_case_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } else { + // The user defined two fixture classes with the same name in + // two namespaces - we'll tell him/her how to fix it. + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " + << this_test_info->test_case_name() << ",\n" + << "you defined test " << first_test_name + << " and test " << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test cases."; + } + return false; + } + + return true; +} + +#if GTEST_HAS_SEH + +// Adds an "exception thrown" fatal failure to the current test. This +// function returns its result via an output parameter pointer because VC++ +// prohibits creation of objects with destructors on stack in functions +// using __try (see error C2712). +static std::string* FormatSehExceptionMessage(DWORD exception_code, + const char* location) { + Message message; + message << "SEH exception with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " thrown in " << location << "."; + + return new std::string(message.GetString()); +} + +#endif // GTEST_HAS_SEH + +#if GTEST_HAS_EXCEPTIONS + +// Adds an "exception thrown" fatal failure to the current test. +static std::string FormatCxxExceptionMessage(const char* description, + const char* location) { + Message message; + if (description != NULL) { + message << "C++ exception with description \"" << description << "\""; + } else { + message << "Unknown C++ exception"; + } + message << " thrown in " << location << "."; + + return message.GetString(); +} + +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result); + +// A failed Google Test assertion will throw an exception of this type when +// GTEST_FLAG(throw_on_failure) is true (if exceptions are enabled). We +// derive it from std::runtime_error, which is for errors presumably +// detectable only at run time. Since std::runtime_error inherits from +// std::exception, many testing frameworks know how to extract and print the +// message inside it. +class GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} +}; +#endif // GTEST_HAS_EXCEPTIONS + +namespace internal { +// We put these helper functions in the internal namespace as IBM's xlC +// compiler rejects the code if they were declared static. + +// Runs the given method and handles SEH exceptions it throws, when +// SEH is supported; returns the 0-value for type Result in case of an +// SEH exception. (Microsoft compilers cannot handle SEH and C++ +// exceptions in the same function. Therefore, we provide a separate +// wrapper function for handling SEH exceptions.) +template +Result HandleSehExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { +#if GTEST_HAS_SEH + __try { + return (object->*method)(); + } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT + GetExceptionCode())) { + // We create the exception message on the heap because VC++ prohibits + // creation of objects with destructors on stack in functions using __try + // (see error C2712). + std::string* exception_message = FormatSehExceptionMessage( + GetExceptionCode(), location); + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + *exception_message); + delete exception_message; + return static_cast(0); + } +#else + (void)location; + return (object->*method)(); +#endif // GTEST_HAS_SEH +} + +// Runs the given method and catches and reports C++ and/or SEH-style +// exceptions, if they are supported; returns the 0-value for type +// Result in case of an SEH exception. +template +Result HandleExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { + // NOTE: The user code can affect the way in which Google Test handles + // exceptions by setting GTEST_FLAG(catch_exceptions), but only before + // RUN_ALL_TESTS() starts. It is technically possible to check the flag + // after the exception is caught and either report or re-throw the + // exception based on the flag's value: + // + // try { + // // Perform the test method. + // } catch (...) { + // if (GTEST_FLAG(catch_exceptions)) + // // Report the exception as failure. + // else + // throw; // Re-throws the original exception. + // } + // + // However, the purpose of this flag is to allow the program to drop into + // the debugger when the exception is thrown. On most platforms, once the + // control enters the catch block, the exception origin information is + // lost and the debugger will stop the program at the point of the + // re-throw in this function -- instead of at the point of the original + // throw statement in the code under test. For this reason, we perform + // the check early, sacrificing the ability to affect Google Test's + // exception handling in the method where the exception is thrown. + if (internal::GetUnitTestImpl()->catch_exceptions()) { +#if GTEST_HAS_EXCEPTIONS + try { + return HandleSehExceptionsInMethodIfSupported(object, method, location); + } catch (const GoogleTestFailureException&) { // NOLINT + // This exception doesn't originate in code under test. It makes no + // sense to report it as a test failure. + throw; + } catch (const std::exception& e) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(e.what(), location)); + } catch (...) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(NULL, location)); + } + return static_cast(0); +#else + return HandleSehExceptionsInMethodIfSupported(object, method, location); +#endif // GTEST_HAS_EXCEPTIONS + } else { + return (object->*method)(); + } +} + +} // namespace internal + +// Runs the test and updates the test result. +void Test::Run() { + if (!HasSameFixtureClass()) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); + // We will run the test only if SetUp() was successful. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TestBody, "the test body"); + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TearDown, "TearDown()"); +} + +// Returns true iff the current test has a fatal failure. +bool Test::HasFatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// Returns true iff the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object. +// TODO(vladl@google.com): Make a_test_case_name and a_name const string&'s +// to signify they cannot be NULLs. +TestInfo::TestInfo(const char* a_test_case_name, + const char* a_name, + const char* a_type_param, + const char* a_value_param, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) + : test_case_name_(a_test_case_name), + name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + value_param_(a_value_param ? new std::string(a_value_param) : NULL), + fixture_class_id_(fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory), + result_() {} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { delete factory_; } + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param: the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param: text representation of the test's value parameter, +// or NULL if this is not a value-parameterized test. +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory) { + TestInfo* const test_info = + new TestInfo(test_case_name, name, type_param, value_param, + fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; +} + +#if GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line) { + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; + + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors.GetString().c_str()); +} +#endif // GTEST_HAS_PARAM_TEST + +} // namespace internal + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestCase class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. +class TestNameIs { + public: + // Constructor. + // + // TestNameIs has NO default constructor. + explicit TestNameIs(const char* name) + : name_(name) {} + + // Returns true iff the test name of test_info matches name_. + bool operator()(const TestInfo * test_info) const { + return test_info && test_info->name() == name_; + } + + private: + std::string name_; +}; + +} // namespace + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#if GTEST_HAS_PARAM_TEST + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +#endif +} + +} // namespace internal + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfo::Run() { + if (!should_run_) return; + + // Tells UnitTest where to store test result. + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*this); + + const TimeInMillis start = internal::GetTimeInMillis(); + + impl->os_stack_trace_getter()->UponLeavingGTest(); + + // Creates the test object. + Test* const test = internal::HandleExceptionsInMethodIfSupported( + factory_, &internal::TestFactoryBase::CreateTest, + "the test fixture's constructor"); + + // Runs the test only if the test object was created and its + // constructor didn't generate a fatal failure. + if ((test != NULL) && !Test::HasFatalFailure()) { + // This doesn't throw as all user code that can throw are wrapped into + // exception handling code. + test->Run(); + } + + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + test, &Test::DeleteSelf_, "the test fixture's destructor"); + + result_.set_elapsed_time(internal::GetTimeInMillis() - start); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*this); + + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(NULL); +} + +// class TestCase + +// Gets the number of successful tests in this test case. +int TestCase::successful_test_count() const { + return CountIf(test_info_list_, TestPassed); +} + +// Gets the number of failed tests in this test case. +int TestCase::failed_test_count() const { + return CountIf(test_info_list_, TestFailed); +} + +int TestCase::disabled_test_count() const { + return CountIf(test_info_list_, TestDisabled); +} + +// Get the number of tests in this test case that should run. +int TestCase::test_to_run_count() const { + return CountIf(test_info_list_, ShouldRunTest); +} + +// Gets the number of all tests. +int TestCase::total_test_count() const { + return static_cast(test_info_list_.size()); +} + +// Creates a TestCase with the given name. +// +// Arguments: +// +// name: name of the test case +// a_type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase::TestCase(const char* a_name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) + : name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + elapsed_time_(0) { +} + +// Destructor of TestCase. +TestCase::~TestCase() { + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestCase::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Adds a test to this test case. Will delete the test upon +// destruction of the TestCase object. +void TestCase::AddTestInfo(TestInfo * test_info) { + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast(test_indices_.size())); +} + +// Runs every test in this TestCase. +void TestCase::Run() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_case(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + repeater->OnTestCaseStart(*this); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); + + const internal::TimeInMillis start = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start; + + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); + + repeater->OnTestCaseEnd(*this); + impl->set_current_test_case(NULL); +} + +// Clears the results of all tests in this test case. +void TestCase::ClearResult() { + ForEach(test_info_list_, TestInfo::ClearTestResult); +} + +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast(i); + } +} + +// Formats a countable noun. Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static std::string FormatCountableNoun(int count, + const char * singular_form, + const char * plural_form) { + return internal::String::Format("%d %s", count, + count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static std::string FormatTestCount(int test_count) { + return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test cases. +static std::string FormatTestCaseCount(int test_case_count) { + return FormatCountableNoun(test_case_count, "test case", "test cases"); +} + +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { + switch (type) { + case TestPartResult::kSuccess: + return "Success"; + + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: +#ifdef _MSC_VER + return "error: "; +#else + return "Failure\n"; +#endif + default: + return "Unknown result type"; + } +} + +// Prints a TestPartResult to an std::string. +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + +// Prints a TestPartResult. +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const std::string& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif +} + +// class PrettyUnitTestResultPrinter + +namespace internal { + +enum GTestColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GTestColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. +const char* GetAnsiColorCode(GTestColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + default: return NULL; + }; +} + +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns true iff Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { + const char* const gtest_color = GTEST_FLAG(color).c_str(); + + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#if GTEST_OS_WINDOWS + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "screen") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; +#endif // GTEST_OS_WINDOWS + } + + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS + const bool use_color = false; +#else + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + + if (!use_color) { + vprintf(fmt, args); + va_end(args); + return; + } + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + va_end(args); +} + +void PrintFullTestCommentIfPresent(const TestInfo& test_info) { + const char* const type_param = test_info.type_param(); + const char* const value_param = test_info.value_param(); + + if (type_param != NULL || value_param != NULL) { + printf(", where "); + if (type_param != NULL) { + printf("TypeParam = %s", type_param); + if (value_param != NULL) + printf(" and "); + } + if (value_param != NULL) { + printf("GetParam() = %s", value_param); + } + } +} + +// This class implements the TestEventListener interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public TestEventListener { + public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char * test_case, const char * test) { + printf("%s.%s", test_case, test); + } + + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} + + private: + static void PrintFailedTests(const UnitTest& unit_test); +}; + + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); + + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!String::CStringEquals(filter, kUniversalFilter)) { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %d of %s.\n", + static_cast(shard_index) + 1, + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } + + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case.name()); + if (test_case.type_param() == NULL) { + printf("\n"); + } else { + printf(", where TypeParam = %s\n", test_case.type_param()); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_info.test_case_name(), test_info.name()); + printf("\n"); + fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } else { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_info.test_case_name(), test_info.name()); + if (test_info.result()->Failed()) + PrintFullTestCommentIfPresent(test_info); + + if (GTEST_FLAG(print_time)) { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()).c_str()); + } else { + printf("\n"); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; + + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case.name(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); +} + +// Internal helper for printing the list of failed tests. +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_case.name(), test_info.name()); + PrintFullTestCommentIfPresent(test_info); + printf("\n"); + } + } +} + +void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } + + int num_disabled = unit_test.disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (!num_failures) { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class TestEventRepeater +// +// This class forwards events to other event listeners. +class TestEventRepeater : public TestEventListener { + public: + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); + + private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector listeners_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); +}; + +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete); +} + +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); +} + +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} + +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) + +#undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ + +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit XmlUnitTestResultPrinter(const char* output_file); + + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + + private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) { + return c == 0x9 || c == 0xA || c == 0xD; + } + + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) { + return IsNormalizableWhitespace(c) || c >= 0x20; + } + + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static std::string EscapeXml(const char* str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static string RemoveInvalidXmlCharacters(const string& str); + + // Convenience wrapper around EscapeXml when str is an attribute value. + static std::string EscapeXmlAttribute(const char* str) { + return EscapeXml(str, true); + } + + // Convenience wrapper around EscapeXml when str is not an attribute value. + static std::string EscapeXmlText(const char* str) { + return EscapeXml(str, false); + } + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); + + // Prints an XML representation of a TestCase object + static void PrintXmlTestCase(FILE* out, const TestCase& test_case); + + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the std::string is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static std::string TestPropertiesAsXmlAttributes(const TestResult& result); + + // The output file. + const std::string output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.c_str() == NULL || output_file_.empty()) { + fprintf(stderr, "XML output file may not be null\n"); + fflush(stderr); + exit(EXIT_FAILURE); + } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* xmlout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + xmlout = posix::FOpen(output_file_.c_str(), "w"); + } + if (xmlout == NULL) { + // TODO(wan): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + fprintf(stderr, + "Unable to open file \"%s\"\n", + output_file_.c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + PrintXmlUnitTest(xmlout, unit_test); + fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str. If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +// TODO(wan): It might be nice to have a minimally invasive, human-readable +// escaping scheme for invalid characters, rather than dropping them. +std::string XmlUnitTestResultPrinter::EscapeXml( + const char* str, bool is_attribute) { + Message m; + + if (str != NULL) { + for (const char* src = str; *src; ++src) { + switch (*src) { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(*src)) { + if (is_attribute && IsNormalizableWhitespace(*src)) + m << String::Format("&#x%02X;", unsigned(*src)); + else + m << *src; + } + break; + } + } + } + + return m.GetString(); +} + +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const string& str) { + string output; + output.reserve(str.size()); + for (string::const_iterator it = str.begin(); it != str.end(); ++it) + if (IsValidXmlCharacter(*it)) + output.push_back(*it); + + return output; +} + +// The following routines generate an XML representation of a UnitTest +// object. +// +// This is how Google Test concepts map to the DTD: +// +// <-- corresponds to a UnitTest object +// <-- corresponds to a TestCase object +// <-- corresponds to a TestInfo object +// ... +// ... +// ... +// <-- individual assertion failures +// +// +// + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << ms/1000.0; + return ss.str(); +} + +// Converts the given epoch time in milliseconds to a date string in the ISO +// 8601 format, without the timezone information. +std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { + // Using non-reentrant version as localtime_r is not portable. + time_t seconds = static_cast(ms / 1000); +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996 + // (function or variable may be unsafe). + const struct tm* const time_struct = localtime(&seconds); // NOLINT +# pragma warning(pop) // Restores the warning state again. +#else + const struct tm* const time_struct = localtime(&seconds); // NOLINT +#endif + if (time_struct == NULL) + return ""; // Invalid ms value + + return String::Format("%d-%02d-%02dT%02d:%02d:%02d", // YYYY-MM-DDThh:mm:ss + time_struct->tm_year + 1900, + time_struct->tm_mon + 1, + time_struct->tm_mday, + time_struct->tm_hour, + time_struct->tm_min, + time_struct->tm_sec); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << ""); + if (next_segment != NULL) { + stream->write( + segment, static_cast(next_segment - segment)); + *stream << "]]>]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} + +// Prints an XML representation of a TestInfo object. +// TODO(wan): There is also value in printing properties with the plain printer. +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + *stream << " \n"; + } + const string location = internal::FormatCompilerIndependentFileLocation( + part.file_name(), part.line_number()); + const string summary = location + "\n" + part.summary(); + *stream << " "; + const string detail = location + "\n" + part.message(); + OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); + *stream << "\n"; + } + } + + if (failures == 0) + *stream << " />\n"; + else + *stream << " \n"; +} + +// Prints an XML representation of a TestCase object +void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, + const TestCase& test_case) { + fprintf(out, + " \n", + FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str()); + for (int i = 0; i < test_case.total_test_count(); ++i) { + ::std::stringstream stream; + OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i)); + fprintf(out, "%s", StringStreamToString(&stream).c_str()); + } + fprintf(out, " \n"); +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, + const UnitTest& unit_test) { + fprintf(out, "\n"); + fprintf(out, + "\n"); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + PrintXmlTestCase(out, *unit_test.GetTestCase(i)); + fprintf(out, "\n"); +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End XmlUnitTestResultPrinter + +#if GTEST_CAN_STREAM_RESULTS_ + +// Streams test results to the given port on the given host machine. +class StreamingListener : public EmptyTestEventListener { + public: + // Escapes '=', '&', '%', and '\n' characters in str as "%xx". + static string UrlEncode(const char* str); + + StreamingListener(const string& host, const string& port) + : sockfd_(-1), host_name_(host), port_num_(port) { + MakeConnection(); + Send("gtest_streaming_protocol_version=1.0\n"); + } + + virtual ~StreamingListener() { + if (sockfd_ != -1) + CloseConnection(); + } + + void OnTestProgramStart(const UnitTest& /* unit_test */) { + Send("event=TestProgramStart\n"); + } + + void OnTestProgramEnd(const UnitTest& unit_test) { + // Note that Google Test current only report elapsed time for each + // test iteration, not for the entire test program. + Send(String::Format("event=TestProgramEnd&passed=%d\n", + unit_test.Passed())); + + // Notify the streaming server to stop. + CloseConnection(); + } + + void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { + Send(String::Format("event=TestIterationStart&iteration=%d\n", + iteration)); + } + + void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { + Send(String::Format("event=TestIterationEnd&passed=%d&elapsed_time=%sms\n", + unit_test.Passed(), + StreamableToString(unit_test.elapsed_time()).c_str())); + } + + void OnTestCaseStart(const TestCase& test_case) { + Send(String::Format("event=TestCaseStart&name=%s\n", test_case.name())); + } + + void OnTestCaseEnd(const TestCase& test_case) { + Send(String::Format("event=TestCaseEnd&passed=%d&elapsed_time=%sms\n", + test_case.Passed(), + StreamableToString(test_case.elapsed_time()).c_str())); + } + + void OnTestStart(const TestInfo& test_info) { + Send(String::Format("event=TestStart&name=%s\n", test_info.name())); + } + + void OnTestEnd(const TestInfo& test_info) { + Send(String::Format( + "event=TestEnd&passed=%d&elapsed_time=%sms\n", + (test_info.result())->Passed(), + StreamableToString((test_info.result())->elapsed_time()).c_str())); + } + + void OnTestPartResult(const TestPartResult& test_part_result) { + const char* file_name = test_part_result.file_name(); + if (file_name == NULL) + file_name = ""; + Send(String::Format("event=TestPartResult&file=%s&line=%d&message=", + UrlEncode(file_name).c_str(), + test_part_result.line_number())); + Send(UrlEncode(test_part_result.message()) + "\n"); + } + + private: + // Creates a client socket and connects to the server. + void MakeConnection(); + + // Closes the socket. + void CloseConnection() { + GTEST_CHECK_(sockfd_ != -1) + << "CloseConnection() can be called only when there is a connection."; + + close(sockfd_); + sockfd_ = -1; + } + + // Sends a string to the socket. + void Send(const string& message) { + GTEST_CHECK_(sockfd_ != -1) + << "Send() can be called only when there is a connection."; + + const int len = static_cast(message.length()); + if (write(sockfd_, message.c_str(), len) != len) { + GTEST_LOG_(WARNING) + << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; + } + } + + int sockfd_; // socket file descriptor + const string host_name_; + const string port_num_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); +}; // class StreamingListener + +// Checks if str contains '=', '&', '%' or '\n' characters. If yes, +// replaces them by "%xx" where xx is their hexadecimal value. For +// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) +// in both time and space -- important as the input str may contain an +// arbitrarily long test failure message and stack trace. +string StreamingListener::UrlEncode(const char* str) { + string result; + result.reserve(strlen(str) + 1); + for (char ch = *str; ch != '\0'; ch = *++str) { + switch (ch) { + case '%': + case '=': + case '&': + case '\n': + result.append(String::Format("%%%02x", static_cast(ch))); + break; + default: + result.push_back(ch); + break; + } + } + return result; +} + +void StreamingListener::MakeConnection() { + GTEST_CHECK_(sockfd_ == -1) + << "MakeConnection() can't be called when there is already a connection."; + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. + hints.ai_socktype = SOCK_STREAM; + addrinfo* servinfo = NULL; + + // Use the getaddrinfo() to get a linked list of IP addresses for + // the given host name. + const int error_num = getaddrinfo( + host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); + if (error_num != 0) { + GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " + << gai_strerror(error_num); + } + + // Loop through all the results and connect to the first we can. + for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; + cur_addr = cur_addr->ai_next) { + sockfd_ = socket( + cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); + if (sockfd_ != -1) { + // Connect the client socket to the server socket. + if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { + close(sockfd_); + sockfd_ = -1; + } + } + } + + freeaddrinfo(servinfo); // all done with this structure + + if (sockfd_ == -1) { + GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " + << host_name_ << ":" << port_num_; + } +} + +// End of class Streaming Listener +#endif // GTEST_CAN_STREAM_RESULTS__ + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message = message.GetString(); + + UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +ScopedTrace::~ScopedTrace() + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + UnitTest::GetInstance()->PopGTestTrace(); +} + + +// class OsStackTraceGetter + +// Returns the current OS stack trace as an std::string. Parameters: +// +// max_depth - the maximum number of stack frames to be included +// in the trace. +// skip_count - the number of top frames to be skipped; doesn't count +// against max_depth. +// +string OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, + int /* skip_count */) + GTEST_LOCK_EXCLUDED_(mutex_) { + return ""; +} + +void OsStackTraceGetter::UponLeavingGTest() + GTEST_LOCK_EXCLUDED_(mutex_) { +} + +const char* const +OsStackTraceGetter::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +} // namespace internal + +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + +// class UnitTest + +// Gets the singleton UnitTest object. The first time this method is +// called, a UnitTest object is constructed and returned. Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest * UnitTest::GetInstance() { + // When compiled with MSVC 7.1 in optimized mode, destroying the + // UnitTest object upon exiting the program messes up the exit code, + // causing successful tests to appear failed. We have to use a + // different implementation in this case to bypass the compiler bug. + // This implementation makes the compiler happy, at the cost of + // leaking the UnitTest object. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) + static UnitTest* const instance = new UnitTest; + return instance; +#else + static UnitTest instance; + return &instance; +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) +} + +// Gets the number of successful test cases. +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_case_count(); +} + +// Gets the number of failed test cases. +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_case_count(); +} + +// Gets the number of all test cases. +int UnitTest::total_test_case_count() const { + return impl()->total_test_case_count(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTest::test_case_to_run_count() const { + return impl()->test_case_to_run_count(); +} + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the time of the test program start, in ms from the start of the +// UNIX epoch. +internal::TimeInMillis UnitTest::start_timestamp() const { + return impl()->start_timestamp(); +} + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true iff the unit test passed (i.e. all test cases passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true iff the unit test failed (i.e. some test case failed +// or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + +// Registers and returns a global test environment. When a test +// program is run, all global test environments will be set-up in the +// order they were registered. After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { + if (env == NULL) { + return NULL; + } + + impl_->environments().push_back(env); + return env; +} + +// Adds a TestPartResult to the current TestResult object. All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results. The user code should use the +// assertion macros instead of calling this directly. +void UnitTest::AddTestPartResult( + TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) + GTEST_LOCK_EXCLUDED_(mutex_) { + Message msg; + msg << message; + + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (int i = static_cast(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } + + if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { + msg << internal::kStackTraceMarker << os_stack_trace; + } + + const TestPartResult result = + TestPartResult(result_type, file_name, line_number, + msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); + + if (result_type != TestPartResult::kSuccess) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#else + // Dereference NULL through a volatile pointer to prevent the compiler + // from removing. We use this rather than abort() or __builtin_trap() for + // portability: Symbian doesn't implement abort() well, and some debuggers + // don't correctly trap abort(). + *static_cast(NULL) = 1; +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } + } +} + +// Creates and adds a property to the current TestResult. If a property matching +// the supplied value already exists, updates its value instead. +void UnitTest::RecordPropertyForCurrentTest(const char* key, + const char* value) { + const TestProperty test_property(key, value); + impl_->current_test_result()->RecordProperty(test_property); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { + // Captures the value of GTEST_FLAG(catch_exceptions). This value will be + // used for the duration of the program. + impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); + +#if GTEST_HAS_SEH + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected. + if (impl()->catch_exceptions() || in_death_test_child_process) { +# if !GTEST_OS_WINDOWS_MOBILE + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +# endif // !GTEST_OS_WINDOWS_MOBILE + +# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +# endif + +# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +# endif + } +#endif // GTEST_HAS_SEH + + return internal::HandleExceptionsInMethodIfSupported( + impl(), + &internal::UnitTestImpl::RunAllTests, + "auxiliary test code (environments or event listeners)") ? 0 : 1; +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { + return impl_->original_working_dir_.c_str(); +} + +// Returns the TestCase object for the test that's currently running, +// or NULL if no test is running. +const TestCase* UnitTest::current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_case(); +} + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +const TestInfo* UnitTest::current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); +} + +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +#if GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +internal::ParameterizedTestCaseRegistry& + UnitTest::parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_) { + return impl_->parameterized_test_registry(); +} +#endif // GTEST_HAS_PARAM_TEST + +// Creates an empty UnitTest. +UnitTest::UnitTest() { + impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { + delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +void UnitTest::PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) + : parent_(parent), +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4355) // Temporarily disables warning 4355 + // (using this in initializer). + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +# pragma warning(pop) // Restores the warning state again. +#else + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#endif // _MSC_VER + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), +#if GTEST_HAS_PARAM_TEST + parameterized_test_registry_(), + parameterized_tests_registered_(false), +#endif // GTEST_HAS_PARAM_TEST + last_death_test_case_(-1), + current_test_case_(NULL), + current_test_info_(NULL), + ad_hoc_test_result_(), + os_stack_trace_getter_(NULL), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. + start_timestamp_(0), + elapsed_time_(0), +#if GTEST_HAS_DEATH_TEST + internal_run_death_test_flag_(NULL), + death_test_factory_(new DefaultDeathTestFactory), +#endif + // Will be overridden by the flag before first use. + catch_exceptions_(false) { + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); +} + +UnitTestImpl::~UnitTestImpl() { + // Deletes every TestCase. + ForEach(test_cases_, internal::Delete); + + // Deletes every Environment. + ForEach(environments_, internal::Delete); + + delete os_stack_trace_getter_; +} + +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const std::string& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +#if GTEST_CAN_STREAM_RESULTS_ +// Initializes event listeners for streaming test results in string form. +// Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureStreamingOutput() { + const std::string& target = GTEST_FLAG(stream_result_to); + if (!target.empty()) { + const size_t pos = target.find(':'); + if (pos != std::string::npos) { + listeners()->Append(new StreamingListener(target.substr(0, pos), + target.substr(pos+1))); + } else { + printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", + target.c_str()); + fflush(stdout); + } + } +} +#endif // GTEST_CAN_STREAM_RESULTS_ + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Configures listeners for streaming test results to the specified server. + ConfigureStreamingOutput(); +#endif // GTEST_CAN_STREAM_RESULTS_ + } +} + +// A predicate that checks the name of a TestCase against a known +// value. +// +// This is used for implementation of the UnitTest class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestCaseNameIs is copyable. +class TestCaseNameIs { + public: + // Constructor. + explicit TestCaseNameIs(const std::string& name) + : name_(name) {} + + // Returns true iff the name of test_case matches name_. + bool operator()(const TestCase* test_case) const { + return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; + } + + private: + std::string name_; +}; + +// Finds and returns a TestCase with the given name. If one doesn't +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. +// +// Arguments: +// +// test_case_name: name of the test case +// type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) { + // Can we find a TestCase with the given name? + const std::vector::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); + + if (test_case != test_cases_.end()) + return *test_case; + + // No. Let's create one. + TestCase* const new_test_case = + new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); + + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(test_case_name, + kDeathTestCaseFilter)) { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } else { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); + } + + test_case_indices_.push_back(static_cast(test_case_indices_.size())); + return new_test_case; +} + +// Helpers for setting up / tearing down the given environment. They +// are for use in the ForEach() function. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns true if all tests are successful. If any exception is +// thrown during a test, the test is considered to be failed, but the +// rest of the tests will still be run. +// +// When parameterized tests are enabled, it expands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +bool UnitTestImpl::RunAllTests() { + // Makes sure InitGoogleTest() was called. + if (!GTestIsInitialized()) { + printf("%s", + "\nThis test program did NOT call ::testing::InitGoogleTest " + "before calling RUN_ALL_TESTS(). Please fix it.\n"); + return false; + } + + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return true; + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + + // True iff we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; + +#if GTEST_HAS_DEATH_TEST + in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +#endif // GTEST_HAS_DEATH_TEST + + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return true; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + + // True iff at least one test has failed. + bool failed = false; + + TestEventListener* repeater = listeners()->repeater(); + + start_timestamp_ = GetTimeInMillis(); + repeater->OnTestProgramStart(*parent_); + + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool forever = repeat < 0; + for (int i = 0; forever || i != repeat; i++) { + // We want to preserve failures generated by ad-hoc test + // assertions executed before RUN_ALL_TESTS(). + ClearNonAdHocTestResult(); + + const TimeInMillis start = GetTimeInMillis(); + + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + + // Runs each test case if there is at least one test to run. + if (has_tests_to_run) { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + + // Runs the tests only if there was no fatal failure during global + // set-up. + if (!Test::HasFatalFailure()) { + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); + } + } + + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } + + elapsed_time_ = GetTimeInMillis() - start; + + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); + + // Gets the result and clears it. + if (!Passed()) { + failed = true; + } + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } + + repeater->OnTestProgramEnd(*parent_); + + return !failed; +} + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. +// Returns the number of tests that should run. +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; + const std::string &test_case_name = test_case->name(); + test_case->set_should_run(false); + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; + const std::string test_name(test_info->name()); + // A test is disabled if test case name or test name matches + // kDisableTestFilter. + const bool is_disabled = + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); + test_info->is_disabled_ = is_disabled; + + const bool matches_filter = + internal::UnitTestOptions::FilterMatchesTest(test_case_name, + test_name); + test_info->matches_filter_ = matches_filter; + + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; + + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->should_run_ = is_selected; + test_case->set_should_run(test_case->should_run() || is_selected); + } + } + return num_selected_tests; +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter_) { + if (!printed_test_case_name) { + printed_test_case_name = true; + printf("%s.\n", test_case->name()); + } + printf(" %s\n", test_info->name()); + } + } + } + fflush(stdout); +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( + OsStackTraceGetterInterface* getter) { + if (os_stack_trace_getter_ != getter) { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { + if (os_stack_trace_getter_ == NULL) { + os_stack_trace_getter_ = new OsStackTraceGetter; + } + + return os_stack_trace_getter_; +} + +// Returns the TestResult for the test that's currently running, or +// the TestResult for the ad hoc test if no test is running. +TestResult* UnitTestImpl::current_test_result() { + return current_test_info_ ? + &(current_test_info_->result_) : &ad_hoc_test_result_; +} + +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast(test_cases_.size()), &test_case_indices_); + + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast(i); + } +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to +// suppress unreachable code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +const char* ParseFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; + + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, std::string* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", std::string(str, p).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +#if GTEST_CAN_STREAM_RESULTS_ +" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" +" Stream test results to the given server.\n" +#endif // GTEST_CAN_STREAM_RESULTS_ +"\n" +"Assertion Behavior:\n" +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" +" Do not report exceptions as test failures. Instead, allow them\n" +" to crash the program or throw a pop-up (on Windows).\n" +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. The type parameter CharType can be +// instantiated to either char or wchar_t. +template +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + for (int i = 1; i < *argc; i++) { + const std::string arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; + + // Do we see a Google Test flag? + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, + >EST_FLAG(throw_on_failure)) + ) { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template +void InitGoogleTestImpl(int* argc, CharType** argv) { + g_init_gtest_count++; + + // We don't want to run the initialization code twice. + if (g_init_gtest_count != 1) return; + + if (*argc <= 0) return; + + internal::g_executable_path = internal::StreamableToString(argv[0]); + +#if GTEST_HAS_DEATH_TEST + + g_argvs.clear(); + for (int i = 0; i != *argc; i++) { + g_argvs.push_back(StreamableToString(argv[i])); + } + +#endif // GTEST_HAS_DEATH_TEST + + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); +} + +} // namespace internal + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +} // namespace testing +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) +// +// This file implements death tests. + + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_MAC +# include +# endif // GTEST_OS_MAC + +# include +# include +# include + +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + +# include + +# if GTEST_OS_WINDOWS +# include +# else +# include +# include +# endif // GTEST_OS_WINDOWS + +# if GTEST_OS_QNX +# include +# endif // GTEST_OS_QNX + +#endif // GTEST_HAS_DEATH_TEST + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +// Constants. + +// The default death test style. +static const char kDefaultDeathTestStyle[] = "fast"; + +GTEST_DEFINE_string_( + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); + +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + +namespace internal { +GTEST_DEFINE_string_( + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "the '|' characters. This flag is specified if and only if the current " + "process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); +} // namespace internal + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Valid only for fast death tests. Indicates the code is running in the +// child process of a fast style death test. +static bool g_in_fast_death_test_child = false; + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +bool InDeathTestChild() { +# if GTEST_OS_WINDOWS + + // On Windows, death tests are thread-safe regardless of the value of the + // death_test_style flag. + return !GTEST_FLAG(internal_run_death_test).empty(); + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") + return !GTEST_FLAG(internal_run_death_test).empty(); + else + return g_in_fast_death_test_child; +#endif +} + +} // namespace internal + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +# if GTEST_OS_WINDOWS + + return exit_status == exit_code_; + +# else + + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; + +# endif // GTEST_OS_WINDOWS +} + +# if !GTEST_OS_WINDOWS +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} +# endif // !GTEST_OS_WINDOWS + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static std::string ExitSummary(int exit_code) { + Message m; + +# if GTEST_OS_WINDOWS + + m << "Exited with exit status " << exit_code; + +# else + + if (WIFEXITED(exit_code)) { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } else if (WIFSIGNALED(exit_code)) { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +# ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) { + m << " (core dumped)"; + } +# endif +# endif // GTEST_OS_WINDOWS + + return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { + return !ExitedWithCode(0)(exit_status); +} + +# if !GTEST_OS_WINDOWS +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement. It is the responsibility of the +// caller not to pass a thread_count of 1. +static std::string DeathTestThreadWarning(size_t thread_count) { + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) + msg << "couldn't detect the number of threads."; + else + msg << "detected " << thread_count << " threads."; + return msg.GetString(); +} +# endif // !GTEST_OS_WINDOWS + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestThrew = 'T'; +static const char kDeathTestInternalError = 'I'; + +// An enumeration describing all of the possible ways that a death test can +// conclude. DIED means that the process died while executing the test +// code; LIVED means that process lived beyond the end of the test code; +// RETURNED means that the test statement attempted to execute a return +// statement, which is not allowed; THREW means that the test statement +// returned control by throwing an exception. IN_PROGRESS means the test +// has not yet concluded. +// TODO(vladl@google.com): Unify names and possibly values for +// AbortReason, DeathTestOutcome, and flag characters above. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the error +// message is propagated back to the parent process. Otherwise, the +// message is simply printed to stderr. In either case, the program +// then exits with status 1. +void DeathTestAbort(const std::string& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != NULL) { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } else { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + posix::Abort(); + } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +# define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again. The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR. If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s != -1", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +std::string GetLastErrnoDescription() { + return errno == 0 ? "" : posix::StrError(errno); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} + +// Death test constructor. Increments the running death test count +// for the current test. +DeathTest::DeathTest() { + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == NULL) { + DeathTestAbort("Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) { + return GetUnitTestImpl()->death_test_factory()->Create( + statement, regex, file, line, test); +} + +const char* DeathTest::LastMessage() { + return last_death_test_message_.c_str(); +} + +void DeathTest::set_last_death_test_message(const std::string& message) { + last_death_test_message_ = message; +} + +std::string DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } + + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; +}; + +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; + + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestThrew: + set_outcome(THREW); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast(flag) << ")"; + } + } else { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : + reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; + + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + // We are leaking the descriptor here because on some platforms (i.e., + // when built as Windows DLL), destructors of global objects will still + // run after calling _exit(). On such systems, write_fd_ will be + // indirectly closed from the destructor of UnitTestImpl, causing double + // close if it is also closed here. On debug configurations, double close + // may assert. As there are no in-process buffers to flush here, we are + // relying on the OS to close the descriptor after the process terminates + // when the destructors are not run. + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// Returns an indented copy of stderr output for a death test. +// This makes distinguishing death test output lines from regular log lines +// much easier. +static ::std::string FormatDeathTestOutput(const ::std::string& output) { + ::std::string ret; + for (size_t at = 0; ; ) { + const size_t line_end = output.find('\n', at); + ret += "[ DEATH ] "; + if (line_end == ::std::string::npos) { + ret += output.substr(at); + break; + } + ret += output.substr(at, line_end + 1 - at); + at = line_end + 1; + } + return ret; +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +// outcome: An enumeration describing how the death test +// concluded: DIED, LIVED, THREW, or RETURNED. The death test +// fails in the latter three cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to +// the test's captured standard error output; the death test +// fails if it does not match. +// +// Argument: +// status_ok: true if exit_status is acceptable in the context of +// this particular death test, which fails if it is false +// +// Returns true iff all of the above conditions are met. Otherwise, the +// first failing condition, in the order given above, is the one that is +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) + return false; + + const std::string error_message = GetCapturedStderr(); + + bool success = false; + Message buffer; + + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case THREW: + buffer << " Result: threw an exception.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case DIED: + if (status_ok) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { + success = true; + } else { + buffer << " Result: died but not with expected error.\n" + << " Expected: " << regex()->pattern() << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + } else { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } + + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; +} + +# if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* a_statement, + const RE* a_regex, + const char* file, + int line) + : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status_code; + GTEST_DEATH_TEST_CHECK_( + ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); + child_handle_.Reset(); + set_status(static_cast(status_code)); + return status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + + "=" + file_ + "|" + String::Format("%d|%d|%u|%Iu|%Iu", line_, + death_test_index, + static_cast(::GetCurrentProcessId()), + // size_t has the same with as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + reinterpret_cast(write_handle), + reinterpret_cast(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + std::string command_line = + std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + + internal_flag + "\""; + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +# else // We are not on Windows. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, const RE* regex); + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } + virtual TestRole AssumeRole(); +}; + +// The AssumeRole process for a fork-and-run death test. It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); + + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + g_in_fast_death_test_child = true; + return EXECUTE_TEST; + } else { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: + ExecDeathTest(const char* a_statement, const RE* a_regex, + const char* file, int line) : + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } + virtual TestRole AssumeRole(); + private: + static ::std::vector + GetArgvsForDeathTestChildProcess() { + ::std::vector args = GetInjectableArgvs(); + return args; + } + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { + args_.push_back(NULL); + } + + ~Arguments() { + for (std::vector::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template + void AddArguments(const ::std::vector& arguments) { + for (typename ::std::vector::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + + private: + std::vector args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe +}; + +# if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +# else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +# endif // GTEST_OS_MAC + +# if !GTEST_OS_QNX +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { + ExecDeathTestArgs* const args = static_cast(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + + original_dir + " failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; +} +# endif // !GTEST_OS_QNX + +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +// +// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining +// StackLowerThanAddress into StackGrowsDown, which then doesn't give +// correct answer. +void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; +void StackLowerThanAddress(const void* ptr, bool* result) { + int dummy; + *result = (&dummy < ptr); +} + +bool StackGrowsDown() { + int dummy; + bool result; + StackLowerThanAddress(&dummy, &result); + return result; +} + +// Spawns a child process with the same executable as the current process in +// a thread-safe manner and instructs it to run the death test. The +// implementation uses fork(2) + exec. On systems where clone(2) is +// available, it is used instead, being slightly more thread-safe. On QNX, +// fork supports only single-threaded environments, so this function uses +// spawn(2) there instead. The function dies with an error message if +// anything goes wrong. +static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { + ExecDeathTestArgs args = { argv, close_fd }; + pid_t child_pid = -1; + +# if GTEST_OS_QNX + // Obtains the current directory and sets it to be closed in the child + // process. + const int cwd_fd = open(".", O_RDONLY); + GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + int fd_flags; + // Set close_fd to be closed after spawn. + GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, + fd_flags | FD_CLOEXEC)); + struct inheritance inherit = {0}; + // spawn is a system call. + child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); + // Restores the current working directory. + GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); + +# else // GTEST_OS_QNX +# if GTEST_OS_LINUX + // When a SIGPROF signal is received while fork() or clone() are executing, + // the process may hang. To avoid this, we ignore SIGPROF here and re-enable + // it after the call to fork()/clone() is complete. + struct sigaction saved_sigprof_action; + struct sigaction ignore_sigprof_action; + memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); + sigemptyset(&ignore_sigprof_action.sa_mask); + ignore_sigprof_action.sa_handler = SIG_IGN; + GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( + SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); +# endif // GTEST_OS_LINUX + +# if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + + // Maximum stack alignment in bytes: For a downward-growing stack, this + // amount is subtracted from size of the stack space to get an address + // that is within the stack space and is aligned on all systems we care + // about. As far as I know there is no ABI with stack alignment greater + // than 64. We assume stack and stack_size already have alignment of + // kMaxStackAlignment. + const size_t kMaxStackAlignment = 64; + void* const stack_top = + static_cast(stack) + + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); + GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && + reinterpret_cast(stack_top) % kMaxStackAlignment == 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +# else + const bool use_fork = true; +# endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } +# endif // GTEST_OS_QNX +# if GTEST_OS_LINUX + GTEST_DEATH_TEST_CHECK_SYSCALL_( + sigaction(SIGPROF, &saved_sigprof_action, NULL)); +# endif // GTEST_OS_LINUX + + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test. It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + + const std::string filter_flag = + String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), info->name()); + const std::string internal_flag = + String::Format("--%s%s=%s|%d|%d|%d", + GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag, + file_, line_, death_test_index, pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvsForDeathTestChildProcess()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); + + const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; +} + +# endif // !GTEST_OS_WINDOWS + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address. If the test should be +// skipped, sets that pointer to NULL. Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, + const char* file, int line, + DeathTest** test) { + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); + + if (flag != NULL) { + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message(String::Format( + "Death test count (%d) somehow exceeded expected maximum (%d)", + death_test_index, flag->index())); + return false; + } + + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { + *test = NULL; + return true; + } + } + +# if GTEST_OS_WINDOWS + + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") { + *test = new ExecDeathTest(statement, regex, file, line); + } else if (GTEST_FLAG(death_test_style) == "fast") { + *test = new NoExecDeathTest(statement, regex); + } + +# endif // GTEST_OS_WINDOWS + + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message(String::Format( + "Unknown death test style \"%s\" encountered", + GTEST_FLAG(death_test_style).c_str())); + return false; + } + + return true; +} + +// Splits a given string on a given delimiter, populating a given +// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have +// ::std::string, so we can use it here. +static void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest) { + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) { + parsed.push_back(str.substr(pos)); + break; + } else { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); +} + +# if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort(String::Format("Unable to open parent process %u", + parent_process_id)); + } + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the pipe handle %Iu from the parent process %u", + write_handle_as_size_t, parent_process_id)); + } + + const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the event handle %Iu from the parent process %u", + event_handle_as_size_t, parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort(String::Format( + "Unable to convert pipe handle %Iu to a file descriptor", + write_handle_as_size_t)); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; +} +# endif // GTEST_OS_WINDOWS + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { + if (GTEST_FLAG(internal_run_death_test) == "") return NULL; + + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +# if GTEST_OS_WINDOWS + + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +# else + + if (fields.size() != 4 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } + +# endif // GTEST_OS_WINDOWS + + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); +} + +} // namespace internal + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) + + +#include + +#if GTEST_OS_WINDOWS_MOBILE +# include +#elif GTEST_OS_WINDOWS +# include +# include +#elif GTEST_OS_SYMBIAN +// Symbian OpenC has PATH_MAX in sys/syslimits.h +# include +#else +# include +# include // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +# define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +# define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif // GTEST_OS_WINDOWS + + +namespace testing { +namespace internal { + +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. +const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; +const char kPathSeparatorString[] = "\\"; +const char kAlternatePathSeparatorString[] = "/"; +# if GTEST_OS_WINDOWS_MOBILE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +# else +const char kCurrentDirectoryString[] = ".\\"; +# endif // GTEST_OS_WINDOWS_MOBILE +#else +const char kPathSeparator = '/'; +const char kPathSeparatorString[] = "/"; +const char kCurrentDirectoryString[] = "./"; +#endif // GTEST_OS_WINDOWS + +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#else + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { + const std::string dot_extension = std::string(".") + extension; + if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { + return FilePath(pathname_.substr( + 0, pathname_.length() - dot_extension.length())); + } + return *this; +} + +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(last_sep + 1) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { + const char* const last_sep = FindLastPathSeparator(); + std::string dir; + if (last_sep) { + dir = std::string(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension) { + std::string file; + if (number == 0) { + file = base_name.string() + "." + extension; + } else { + file = base_name.string() + "_" + String::Format("%d", number).c_str() + + "." + extension; + } + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(dir.string() + kPathSeparator + relative_path.string()); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + return attributes != kInvalidFileAttributes; +#else + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { + bool result = false; +#if GTEST_OS_WINDOWS + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : + RemoveTrailingPathSeparator()); +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = true; + } +#else + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + + return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { + const char* const name = pathname_.c_str(); +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); +#else + return IsPathSeparator(name[0]); +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension) { + FilePath full_pathname; + int number = 0; + do { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { + if (!this->IsDirectory()) { + return false; + } + + if (pathname_.length() == 0 || this->DirectoryExists()) { + return true; + } + + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#if GTEST_OS_WINDOWS_MOBILE + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, NULL) ? 0 : -1; + delete [] unicode; +#elif GTEST_OS_WINDOWS + int result = _mkdir(pathname_.c_str()); +#else + int result = mkdir(pathname_.c_str(), 0777); +#endif // GTEST_OS_WINDOWS_MOBILE + + if (result == -1) { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { + return IsDirectory() + ? FilePath(pathname_.substr(0, pathname_.length() - 1)) + : *this; +} + +// Removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). +void FilePath::Normalize() { + if (pathname_.c_str() == NULL) { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); + + while (*src != '\0') { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { + src++; + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; +} + +} // namespace internal +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + + +#include +#include +#include +#include + +#if GTEST_OS_WINDOWS_MOBILE +# include // For TerminateProcess() +#elif GTEST_OS_WINDOWS +# include +# include +#else +# include +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_MAC +# include +# include +# include +#endif // GTEST_OS_MAC + +#if GTEST_OS_QNX +# include +# include +#endif // GTEST_OS_QNX + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_MAC + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast(thread_list), + sizeof(thread_t) * thread_count); + return static_cast(thread_count); + } else { + return 0; + } +} + +#elif GTEST_OS_QNX + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const int fd = open("/proc/self/as", O_RDONLY); + if (fd < 0) { + return 0; + } + procfs_info process_info; + const int status = + devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); + close(fd); + if (status == EOK) { + return static_cast(process_info.num_threads); + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_MAC + +#if GTEST_USES_POSIX_RE + +// Implements RE. Currently only needed for death tests. + +RE::~RE() { + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast(pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = posix::StrDup(regex); + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; +} + +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in , these aren't affected by the +// current locale. +bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsAsciiPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsAsciiWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsAsciiDigit(ch); + case 'D': return !IsAsciiDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsAsciiWhiteSpace(ch); + case 'S': return !IsAsciiWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsAsciiWordChar(ch); + case 'W': return !IsAsciiWordChar(ch); + } + return IsAsciiPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +std::string FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast(pattern_)); + free(const_cast(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + +const char kUnknownFile[] = "unknown file"; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { + const char* const file_name = file == NULL ? kUnknownFile : file; + + if (line < 0) { + return String::Format("%s:", file_name).c_str(); + } +#ifdef _MSC_VER + return String::Format("%s(%d):", file_name, line).c_str(); +#else + return String::Format("%s:%d:", file_name, line).c_str(); +#endif // _MSC_VER +} + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +// Note that FormatCompilerIndependentFileLocation() does NOT append colon +// to the file location it produces, unlike FormatFileLocation(). +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( + const char* file, int line) { + const char* const file_name = file == NULL ? kUnknownFile : file; + + if (line < 0) + return file_name; + else + return String::Format("%s:%d", file_name, line).c_str(); +} + + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : + severity == GTEST_WARNING ? "[WARNING]" : + severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4996) +#endif // _MSC_VER + +#if GTEST_HAS_STREAM_REDIRECTION + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { +# if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +# else + // There's no guarantee that a test has write access to the current + // directory, so we create the temporary file in the /tmp directory + // instead. We use /tmp on most systems, and /sdcard on Android. + // That's because Android doesn't have /tmp. +# if GTEST_OS_LINUX_ANDROID + // Note: Android applications are expected to call the framework's + // Context.getExternalStorageDirectory() method through JNI to get + // the location of the world-writable SD Card directory. However, + // this requires a Context handle, which cannot be retrieved + // globally from native code. Doing so also precludes running the + // code as part of a regular standalone executable, which doesn't + // run in a Dalvik process (e.g. when running it through 'adb shell'). + // + // The location /sdcard is directly accessible from native code + // and is the only location (unofficially) supported by the Android + // team. It's generally a symlink to the real SD Card mount point + // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or + // other OEM-customized locations. Never rely on these, and always + // use /sdcard. + char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; +# else + char name_template[] = "/tmp/captured_stream.XXXXXX"; +# endif // GTEST_OS_LINUX_ANDROID + const int captured_fd = mkstemp(name_template); + filename_ = name_template; +# endif // GTEST_OS_WINDOWS + fflush(NULL); + dup2(captured_fd, fd_); + close(captured_fd); + } + + ~CapturedStream() { + remove(filename_.c_str()); + } + + std::string GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const std::string content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + // Reads the entire content of a file as an std::string. + static std::string ReadEntireFile(FILE* file); + + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); + + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; + +// Returns the size (in bytes) of a file. +size_t CapturedStream::GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast(ftell(file)); +} + +// Reads the entire content of a file as a string. +std::string CapturedStream::ReadEntireFile(FILE* file) { + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; + + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far + + fseek(file, 0, SEEK_SET); + + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do { + bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); + + const std::string content(buffer, bytes_read); + delete[] buffer; + + return content; +} + +# ifdef _MSC_VER +# pragma warning(pop) +# endif // _MSC_VER + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +std::string GetCapturedStream(CapturedStream** captured_stream) { + const std::string content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = NULL; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +std::string GetCapturedStdout() { + return GetCapturedStream(&g_captured_stdout); +} + +// Stops capturing stderr and returns the captured string. +std::string GetCapturedStderr() { + return GetCapturedStream(&g_captured_stderr); +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +::std::vector g_argvs; + +static const ::std::vector* g_injected_test_argvs = + NULL; // Owned. + +void SetInjectableArgvs(const ::std::vector* argvs) { + if (g_injected_test_argvs != argvs) + delete g_injected_test_argvs; + g_injected_test_argvs = argvs; +} + +const ::std::vector& GetInjectableArgvs() { + if (g_injected_test_argvs != NULL) { + return *g_injected_test_argvs; + } + return g_argvs; +} +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); +} +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static std::string FlagToEnvVar(const char* flag) { + const std::string full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); + + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) { + env_var << ToUpper(full_flag.c_str()[i]); + } + + return env_var.GetString(); +} + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { + // Parses the environment variable as a decimal integer. + char* end = NULL; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + *value = result; + return true; +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == NULL) { + // The environment variable is not set. + return default_value; + } + + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } + + return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromGTestEnv(const char* flag, const char* default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const value = posix::GetEnv(env_var.c_str()); + return value == NULL ? default_value : value; +} + +} // namespace internal +} // namespace testing +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// It uses the << operator when possible, and prints the bytes in the +// object otherwise. A user can override its behavior for a class +// type Foo by defining either operator<<(::std::ostream&, const Foo&) +// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that +// defines Foo. + +#include +#include +#include // NOLINT +#include + +namespace testing { + +namespace { + +using ::std::ostream; + +// Prints a segment of bytes in the given object. +void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, + size_t count, ostream* os) { + char text[5] = ""; + for (size_t i = 0; i != count; i++) { + const size_t j = start + i; + if (i != 0) { + // Organizes the bytes into groups of 2 for easy parsing by + // human. + if ((j % 2) == 0) + *os << ' '; + else + *os << '-'; + } + GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); + *os << text; + } +} + +// Prints the bytes in the given value to the given ostream. +void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, + ostream* os) { + // Tells the user how big the object is. + *os << count << "-byte object <"; + + const size_t kThreshold = 132; + const size_t kChunkSize = 64; + // If the object size is bigger than kThreshold, we'll have to omit + // some details by printing only the first and the last kChunkSize + // bytes. + // TODO(wan): let the user control the threshold using a flag. + if (count < kThreshold) { + PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); + } else { + PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); + *os << " ... "; + // Rounds up to 2-byte boundary. + const size_t resume_pos = (count - kChunkSize + 1)/2*2; + PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); + } + *os << ">"; +} + +} // namespace + +namespace internal2 { + +// Delegates to PrintBytesInObjectToImpl() to print the bytes in the +// given object. The delegation simplifies the implementation, which +// uses the << operator and thus is easier done outside of the +// ::testing::internal namespace, which contains a << operator that +// sometimes conflicts with the one in STL. +void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, + ostream* os) { + PrintBytesInObjectToImpl(obj_bytes, count, os); +} + +} // namespace internal2 + +namespace internal { + +// Depending on the value of a char (or wchar_t), we print it in one +// of three formats: +// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), +// - as a hexidecimal escape sequence (e.g. '\x7F'), or +// - as a special escape sequence (e.g. '\r', '\n'). +enum CharFormat { + kAsIs, + kHexEscape, + kSpecialEscape +}; + +// Returns true if c is a printable ASCII character. We test the +// value of c directly instead of calling isprint(), which is buggy on +// Windows Mobile. +inline bool IsPrintableAscii(wchar_t c) { + return 0x20 <= c && c <= 0x7E; +} + +// Prints a wide or narrow char c as a character literal without the +// quotes, escaping it when necessary; returns how c was formatted. +// The template argument UnsignedChar is the unsigned version of Char, +// which is the type of c. +template +static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { + switch (static_cast(c)) { + case L'\0': + *os << "\\0"; + break; + case L'\'': + *os << "\\'"; + break; + case L'\\': + *os << "\\\\"; + break; + case L'\a': + *os << "\\a"; + break; + case L'\b': + *os << "\\b"; + break; + case L'\f': + *os << "\\f"; + break; + case L'\n': + *os << "\\n"; + break; + case L'\r': + *os << "\\r"; + break; + case L'\t': + *os << "\\t"; + break; + case L'\v': + *os << "\\v"; + break; + default: + if (IsPrintableAscii(c)) { + *os << static_cast(c); + return kAsIs; + } else { + *os << String::Format("\\x%X", static_cast(c)); + return kHexEscape; + } + } + return kSpecialEscape; +} + +// Prints a wchar_t c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { + switch (c) { + case L'\'': + *os << "'"; + return kAsIs; + case L'"': + *os << "\\\""; + return kSpecialEscape; + default: + return PrintAsCharLiteralTo(c, os); + } +} + +// Prints a char c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { + return PrintAsStringLiteralTo( + static_cast(static_cast(c)), os); +} + +// Prints a wide or narrow character c and its code. '\0' is printed +// as "'\\0'", other unprintable characters are also properly escaped +// using the standard C++ escape sequence. The template argument +// UnsignedChar is the unsigned version of Char, which is the type of c. +template +void PrintCharAndCodeTo(Char c, ostream* os) { + // First, print c as a literal in the most readable form we can find. + *os << ((sizeof(c) > 1) ? "L'" : "'"); + const CharFormat format = PrintAsCharLiteralTo(c, os); + *os << "'"; + + // To aid user debugging, we also print c's code in decimal, unless + // it's 0 (in which case c was printed as '\\0', making the code + // obvious). + if (c == 0) + return; + *os << " (" << String::Format("%d", c).c_str(); + + // For more convenience, we print c's code again in hexidecimal, + // unless c was already printed in the form '\x##' or the code is in + // [1, 9]. + if (format == kHexEscape || (1 <= c && c <= 9)) { + // Do nothing. + } else { + *os << String::Format(", 0x%X", + static_cast(c)).c_str(); + } + *os << ")"; +} + +void PrintTo(unsigned char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} +void PrintTo(signed char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} + +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its code. L'\0' is printed as "L'\\0'". +void PrintTo(wchar_t wc, ostream* os) { + PrintCharAndCodeTo(wc, os); +} + +// Prints the given array of characters to the ostream. CharType must be either +// char or wchar_t. +// The array starts at begin, the length is len, it may include '\0' characters +// and may not be NUL-terminated. +template +static void PrintCharsAsStringTo( + const CharType* begin, size_t len, ostream* os) { + const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; + *os << kQuoteBegin; + bool is_previous_hex = false; + for (size_t index = 0; index < len; ++index) { + const CharType cur = begin[index]; + if (is_previous_hex && IsXDigit(cur)) { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" " << kQuoteBegin; + } + is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; + } + *os << "\""; +} + +// Prints a (const) char/wchar_t array of 'len' elements, starting at address +// 'begin'. CharType must be either char or wchar_t. +template +static void UniversalPrintCharArray( + const CharType* begin, size_t len, ostream* os) { + // The code + // const char kFoo[] = "foo"; + // generates an array of 4, not 3, elements, with the last one being '\0'. + // + // Therefore when printing a char array, we don't print the last element if + // it's '\0', such that the output matches the string literal as it's + // written in the source code. + if (len > 0 && begin[len - 1] == '\0') { + PrintCharsAsStringTo(begin, len - 1, os); + return; + } + + // If, however, the last element in the array is not '\0', e.g. + // const char kFoo[] = { 'f', 'o', 'o' }; + // we must print the entire array. We also print a message to indicate + // that the array is not NUL-terminated. + PrintCharsAsStringTo(begin, len, os); + *os << " (no terminating NUL)"; +} + +// Prints a (const) char array of 'len' elements, starting at address 'begin'. +void UniversalPrintArray(const char* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints a (const) wchar_t array of 'len' elements, starting at address +// 'begin'. +void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints the given C string to the ostream. +void PrintTo(const char* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, strlen(s), os); + } +} + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Prints the given wide C string to the ostream. +void PrintTo(const wchar_t* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, wcslen(s), os); + } +} +#endif // wchar_t is native + +// Prints a ::string object. +#if GTEST_HAS_GLOBAL_STRING +void PrintStringTo(const ::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +void PrintStringTo(const ::std::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} + +// Prints a ::wstring object. +#if GTEST_HAS_GLOBAL_WSTRING +void PrintWideStringTo(const ::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +void PrintWideStringTo(const ::std::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_STD_WSTRING + +} // namespace internal + +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +using internal::GetUnitTestImpl; + +// Gets the summary of the failure message by omitting the stack trace +// in it. +std::string TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? message : + std::string(message, stack_trace); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + array_.push_back(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } + + return array_[index]; +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return static_cast(array_.size()); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()-> + GetTestPartResultReporterForCurrentThread()) { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + + +namespace testing { +namespace internal { + +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (IsSpace(*str)) + str++; + return str; +} + +// Verifies that registered_tests match the test names in +// defined_test_names_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestCasePState::VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests) { + typedef ::std::set::const_iterator DefinedTestIter; + registered_ = true; + + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); + + Message errors; + ::std::set tests; + for (const char* names = registered_tests; names != NULL; + names = SkipComma(names)) { + const std::string name = GetPrefixUntilComma(names); + if (tests.count(name) != 0) { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } + + bool found = false; + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (name == *it) { + found = true; + break; + } + } + + if (found) { + tests.insert(name); + } else { + errors << "No test named " << name + << " can be found in this test case.\n"; + } + } + + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (tests.count(*it) == 0) { + errors << "You forgot to list test " << *it << ".\n"; + } + } + + const std::string& errors_str = errors.GetString(); + if (errors_str != "") { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } + + return registered_tests; +} + +#endif // GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest.h b/cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest.h new file mode 100644 index 0000000..1ad7935 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest.h @@ -0,0 +1,20012 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for Google Test. It should be +// included by any test program that uses Google Test. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! +// +// Acknowledgment: Google Test borrowed the idea of automatic test +// registration from Barthelemy Dagenais' (barthelemy@prologique.com) +// easyUnit framework. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_H_ + +#include +#include +#include + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares functions and macros used internally by +// Google Test. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: wan@google.com (Zhanyong Wan) +// +// Low-level types and utilities for porting Google Test to various +// platforms. They are subject to change without notice. DO NOT USE +// THEM IN USER CODE. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +// The user can define the following macros in the build script to +// control Google Test's behavior. If the user doesn't define a macro +// in this list, Google Test will define it. +// +// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) +// is/isn't available. +// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions +// are enabled. +// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::string, which is different to std::string). +// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::wstring, which is different to std::wstring). +// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular +// expressions are/aren't available. +// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that +// is/isn't available. +// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't +// enabled. +// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that +// std::wstring does/doesn't work (Google Test can +// be used where std::wstring is unavailable). +// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple +// is/isn't available. +// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the +// compiler supports Microsoft's "Structured +// Exception Handling". +// GTEST_HAS_STREAM_REDIRECTION +// - Define it to 1/0 to indicate whether the +// platform supports I/O stream redirection using +// dup() and dup2(). +// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google +// Test's own tr1 tuple implementation should be +// used. Unused when the user sets +// GTEST_HAS_TR1_TUPLE to 0. +// GTEST_LANG_CXX11 - Define it to 1/0 to indicate that Google Test +// is building in C++11/C++98 mode. +// GTEST_LINKED_AS_SHARED_LIBRARY +// - Define to 1 when compiling tests that use +// Google Test as a shared library (known as +// DLL on Windows). +// GTEST_CREATE_SHARED_LIBRARY +// - Define to 1 when compiling Google Test itself +// as a shared library. + +// This header defines the following utilities: +// +// Macros indicating the current platform (defined to 1 if compiled on +// the given platform; otherwise undefined): +// GTEST_OS_AIX - IBM AIX +// GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_HPUX - HP-UX +// GTEST_OS_LINUX - Linux +// GTEST_OS_LINUX_ANDROID - Google Android +// GTEST_OS_MAC - Mac OS X +// GTEST_OS_IOS - iOS +// GTEST_OS_IOS_SIMULATOR - iOS simulator +// GTEST_OS_NACL - Google Native Client (NaCl) +// GTEST_OS_OPENBSD - OpenBSD +// GTEST_OS_QNX - QNX +// GTEST_OS_SOLARIS - Sun Solaris +// GTEST_OS_SYMBIAN - Symbian +// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) +// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop +// GTEST_OS_WINDOWS_MINGW - MinGW +// GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_ZOS - z/OS +// +// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the +// most stable support. Since core members of the Google Test project +// don't have access to other platforms, support for them may be less +// stable. If you notice any problems on your platform, please notify +// googletestframework@googlegroups.com (patches for fixing them are +// even more welcome!). +// +// Note that it is possible that none of the GTEST_OS_* macros are defined. +// +// Macros indicating available Google Test features (defined to 1 if +// the corresponding feature is supported; otherwise undefined): +// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized +// tests) +// GTEST_HAS_DEATH_TEST - death tests +// GTEST_HAS_PARAM_TEST - value-parameterized tests +// GTEST_HAS_TYPED_TEST - typed tests +// GTEST_HAS_TYPED_TEST_P - type-parameterized tests +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with +// GTEST_HAS_POSIX_RE (see above) which users can +// define themselves. +// GTEST_USES_SIMPLE_RE - our own simple regex is used; +// the above two are mutually exclusive. +// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). +// +// Macros for basic C++ coding: +// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. +// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a +// variable don't have to be used. +// GTEST_DISALLOW_ASSIGN_ - disables operator=. +// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. +// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. +// +// Synchronization: +// Mutex, MutexLock, ThreadLocal, GetThreadCount() +// - synchronization primitives. +// GTEST_IS_THREADSAFE - defined to 1 to indicate that the above +// synchronization primitives have real implementations +// and Google Test is thread-safe; or 0 otherwise. +// +// Template meta programming: +// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. +// IteratorTraits - partial implementation of std::iterator_traits, which +// is not available in libCstd when compiled with Sun C++. +// +// Smart pointers: +// scoped_ptr - as in TR2. +// +// Regular expressions: +// RE - a simple regular expression class using the POSIX +// Extended Regular Expression syntax on UNIX-like +// platforms, or a reduced regular exception syntax on +// other platforms, including Windows. +// +// Logging: +// GTEST_LOG_() - logs messages at the specified severity level. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. +// +// Stdout and stderr capturing: +// CaptureStdout() - starts capturing stdout. +// GetCapturedStdout() - stops capturing stdout and returns the captured +// string. +// CaptureStderr() - starts capturing stderr. +// GetCapturedStderr() - stops capturing stderr and returns the captured +// string. +// +// Integer types: +// TypeWithSize - maps an integer to a int type. +// Int32, UInt32, Int64, UInt64, TimeInMillis +// - integers of known sizes. +// BiggestInt - the biggest signed integer type. +// +// Command-line utilities: +// GTEST_FLAG() - references a flag. +// GTEST_DECLARE_*() - declares a flag. +// GTEST_DEFINE_*() - defines a flag. +// GetInjectableArgvs() - returns the command line as a vector of strings. +// +// Environment variable utilities: +// GetEnv() - gets the value of an environment variable. +// BoolFromGTestEnv() - parses a bool environment variable. +// Int32FromGTestEnv() - parses an Int32 environment variable. +// StringFromGTestEnv() - parses a string environment variable. + +#include // for isspace, etc +#include // for ptrdiff_t +#include +#include +#include +#ifndef _WIN32_WCE +# include +# include +#endif // !_WIN32_WCE + +#if defined __APPLE__ +# include +# include +#endif + +#include // NOLINT +#include // NOLINT +#include // NOLINT + +#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +#define GTEST_FLAG_PREFIX_ "gtest_" +#define GTEST_FLAG_PREFIX_DASH_ "gtest-" +#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +#define GTEST_NAME_ "Google Test" +#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" + +// Determines the version of gcc that is used to compile this. +#ifdef __GNUC__ +// 40302 means version 4.3.2. +# define GTEST_GCC_VER_ \ + (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + +// Determines the platform on which Google Test is compiled. +#ifdef __CYGWIN__ +# define GTEST_OS_CYGWIN 1 +#elif defined __SYMBIAN32__ +# define GTEST_OS_SYMBIAN 1 +#elif defined _WIN32 +# define GTEST_OS_WINDOWS 1 +# ifdef _WIN32_WCE +# define GTEST_OS_WINDOWS_MOBILE 1 +# elif defined(__MINGW__) || defined(__MINGW32__) +# define GTEST_OS_WINDOWS_MINGW 1 +# else +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif // _WIN32_WCE +#elif defined __APPLE__ +# define GTEST_OS_MAC 1 +# if TARGET_OS_IPHONE +# define GTEST_OS_IOS 1 +# if TARGET_IPHONE_SIMULATOR +# define GTEST_OS_IOS_SIMULATOR 1 +# endif +# endif +#elif defined __linux__ +# define GTEST_OS_LINUX 1 +# if defined __ANDROID__ +# define GTEST_OS_LINUX_ANDROID 1 +# endif +#elif defined __MVS__ +# define GTEST_OS_ZOS 1 +#elif defined(__sun) && defined(__SVR4) +# define GTEST_OS_SOLARIS 1 +#elif defined(_AIX) +# define GTEST_OS_AIX 1 +#elif defined(__hpux) +# define GTEST_OS_HPUX 1 +#elif defined __native_client__ +# define GTEST_OS_NACL 1 +#elif defined __OpenBSD__ +# define GTEST_OS_OPENBSD 1 +#elif defined __QNX__ +# define GTEST_OS_QNX 1 +#endif // __CYGWIN__ + +#ifndef GTEST_LANG_CXX11 +// gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when +// -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a +// value for __cplusplus, and recent versions of clang, gcc, and +// probably other compilers set that too in C++11 mode. +# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L +// Compiling in at least C++11 mode. +# define GTEST_LANG_CXX11 1 +# else +# define GTEST_LANG_CXX11 0 +# endif +#endif + +// Brings in definitions for functions used in the testing::internal::posix +// namespace (read, write, close, chdir, isatty, stat). We do not currently +// use them on Windows Mobile. +#if !GTEST_OS_WINDOWS +// This assumes that non-Windows OSes provide unistd.h. For OSes where this +// is not the case, we need to include headers that provide the functions +// mentioned above. +# include +# include +#elif !GTEST_OS_WINDOWS_MOBILE +# include +# include +#endif + +#if GTEST_OS_LINUX_ANDROID +// Used to define __ANDROID_API__ matching the target NDK API level. +# include // NOLINT +#endif + +// Defines this to true iff Google Test can use POSIX regular expressions. +#ifndef GTEST_HAS_POSIX_RE +# if GTEST_OS_LINUX_ANDROID +// On Android, is only available starting with Gingerbread. +# define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) +# else +# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) +# endif +#endif + +#if GTEST_HAS_POSIX_RE + +// On some platforms, needs someone to define size_t, and +// won't compile otherwise. We can #include it here as we already +// included , which is guaranteed to define size_t through +// . +# include // NOLINT + +# define GTEST_USES_POSIX_RE 1 + +#elif GTEST_OS_WINDOWS + +// is not available on Windows. Use our own simple regex +// implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#else + +// may not be available on this platform. Use our own +// simple regex implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#endif // GTEST_HAS_POSIX_RE + +#ifndef GTEST_HAS_EXCEPTIONS +// The user didn't tell us whether exceptions are enabled, so we need +// to figure it out. +# if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS +// macro to enable exceptions, so we'll do the same. +// Assumes that exceptions are enabled by default. +# ifndef _HAS_EXCEPTIONS +# define _HAS_EXCEPTIONS 1 +# endif // _HAS_EXCEPTIONS +# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +# elif defined(__GNUC__) && __EXCEPTIONS +// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__SUNPRO_CC) +// Sun Pro CC supports exceptions. However, there is no compile-time way of +// detecting whether they are enabled or not. Therefore, we assume that +// they are enabled unless the user tells us otherwise. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__IBMCPP__) && __EXCEPTIONS +// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__HP_aCC) +// Exception handling is in effect by default in HP aCC compiler. It has to +// be turned of by +noeh compiler option if desired. +# define GTEST_HAS_EXCEPTIONS 1 +# else +// For other compilers, we assume exceptions are disabled to be +// conservative. +# define GTEST_HAS_EXCEPTIONS 0 +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +#endif // GTEST_HAS_EXCEPTIONS + +#if !defined(GTEST_HAS_STD_STRING) +// Even though we don't use this macro any longer, we keep it in case +// some clients still depend on it. +# define GTEST_HAS_STD_STRING 1 +#elif !GTEST_HAS_STD_STRING +// The user told us that ::std::string isn't available. +# error "Google Test cannot be used where ::std::string isn't available." +#endif // !defined(GTEST_HAS_STD_STRING) + +#ifndef GTEST_HAS_GLOBAL_STRING +// The user didn't tell us whether ::string is available, so we need +// to figure it out. + +# define GTEST_HAS_GLOBAL_STRING 0 + +#endif // GTEST_HAS_GLOBAL_STRING + +#ifndef GTEST_HAS_STD_WSTRING +// The user didn't tell us whether ::std::wstring is available, so we need +// to figure it out. +// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring +// is available. + +// Cygwin 1.7 and below doesn't support ::std::wstring. +// Solaris' libc++ doesn't support it either. Android has +// no support for it at least as recent as Froyo (2.2). +# define GTEST_HAS_STD_WSTRING \ + (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) + +#endif // GTEST_HAS_STD_WSTRING + +#ifndef GTEST_HAS_GLOBAL_WSTRING +// The user didn't tell us whether ::wstring is available, so we need +// to figure it out. +# define GTEST_HAS_GLOBAL_WSTRING \ + (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Determines whether RTTI is available. +#ifndef GTEST_HAS_RTTI +// The user didn't tell us whether RTTI is enabled, so we need to +// figure it out. + +# ifdef _MSC_VER + +# ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) + +# ifdef __GXX_RTTI +// When building against STLport with the Android NDK and with +// -frtti -fno-exceptions, the build fails at link time with undefined +// references to __cxa_bad_typeid. Note sure if STL or toolchain bug, +// so disable RTTI when detected. +# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ + !defined(__EXCEPTIONS) +# define GTEST_HAS_RTTI 0 +# else +# define GTEST_HAS_RTTI 1 +# endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS +# else +# define GTEST_HAS_RTTI 0 +# endif // __GXX_RTTI + +// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends +// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the +// first version with C++ support. +# elif defined(__clang__) + +# define GTEST_HAS_RTTI __has_feature(cxx_rtti) + +// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if +// both the typeid and dynamic_cast features are present. +# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) + +# ifdef __RTTI_ALL__ +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +# else + +// For all other compilers, we assume RTTI is enabled. +# define GTEST_HAS_RTTI 1 + +# endif // _MSC_VER + +#endif // GTEST_HAS_RTTI + +// It's this header's responsibility to #include when RTTI +// is enabled. +#if GTEST_HAS_RTTI +# include +#endif + +// Determines whether Google Test can use the pthreads library. +#ifndef GTEST_HAS_PTHREAD +// The user didn't tell us explicitly, so we assume pthreads support is +// available on Linux and Mac. +// +// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 +// to your compiler flags. +# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \ + || GTEST_OS_QNX) +#endif // GTEST_HAS_PTHREAD + +#ifdef GTEST_OS_WINDOWS_MINGW +// Disable pthread support for MinGW for now. To enable it, we need to: +// 1) Implement ThreadLocal object under MinGW. The internal pthread calls are +// not available on MinGW. +// 2) Replace the nanosleep() with usleep() for MinGW. +#undef GTEST_HAS_PTHREAD +#define GTEST_HAS_PTHREAD 0 +#endif + +#if GTEST_HAS_PTHREAD +// gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is +// true. +# include // NOLINT + +// For timespec and nanosleep, used below. +# include // NOLINT +#endif + +// Determines whether Google Test can use tr1/tuple. You can define +// this macro to 0 to prevent Google Test from using tuple (any +// feature depending on tuple with be disabled in this mode). +#ifndef GTEST_HAS_TR1_TUPLE +# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) +// STLport, provided with the Android NDK, has neither or . +# define GTEST_HAS_TR1_TUPLE 0 +# else +// The user didn't tell us not to do it, so we assume it's OK. +# define GTEST_HAS_TR1_TUPLE 1 +# endif +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether Google Test's own tr1 tuple implementation +// should be used. +#ifndef GTEST_USE_OWN_TR1_TUPLE +// The user didn't tell us, so we need to figure it out. + +// We use our own TR1 tuple if we aren't sure the user has an +// implementation of it already. At this time, libstdc++ 4.0.0+ and +// MSVC 2010 are the only mainstream standard libraries that come +// with a TR1 tuple implementation. NVIDIA's CUDA NVCC compiler +// pretends to be GCC by defining __GNUC__ and friends, but cannot +// compile GCC's tuple implementation. MSVC 2008 (9.0) provides TR1 +// tuple in a 323 MB Feature Pack download, which we cannot assume the +// user has. QNX's QCC compiler is a modified GCC but it doesn't +// support TR1 tuple. libc++ only provides std::tuple, in C++11 mode, +// and it can be used with some compilers that define __GNUC__. +# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \ + && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 +# define GTEST_ENV_HAS_TR1_TUPLE_ 1 +# endif + +// C++11 specifies that provides std::tuple. Use that if gtest is used +// in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6 +// can build with clang but need to use gcc4.2's libstdc++). +# if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) +# define GTEST_ENV_HAS_STD_TUPLE_ 1 +# endif + +# if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_ +# define GTEST_USE_OWN_TR1_TUPLE 0 +# else +# define GTEST_USE_OWN_TR1_TUPLE 1 +# endif + +#endif // GTEST_USE_OWN_TR1_TUPLE + +// To avoid conditional compilation everywhere, we make it +// gtest-port.h's responsibility to #include the header implementing +// tr1/tuple. +#if GTEST_HAS_TR1_TUPLE + +# if GTEST_USE_OWN_TR1_TUPLE +// This file was GENERATED by command: +// pump.py gtest-tuple.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2009 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template friend class tuple; \ + private: +#endif + +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> +#define GTEST_1_TUPLE_(T) tuple +#define GTEST_2_TUPLE_(T) tuple +#define GTEST_3_TUPLE_(T) tuple +#define GTEST_4_TUPLE_(T) tuple +#define GTEST_5_TUPLE_(T) tuple +#define GTEST_6_TUPLE_(T) tuple +#define GTEST_7_TUPLE_(T) tuple +#define GTEST_8_TUPLE_(T) tuple +#define GTEST_9_TUPLE_(T) tuple +#define GTEST_10_TUPLE_(T) tuple + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. +#define GTEST_0_TYPENAMES_(T) +#define GTEST_1_TYPENAMES_(T) typename T##0 +#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 +#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 +#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3 +#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4 +#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5 +#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6 +#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 +#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8 +#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8, typename T##9 + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef::type is T if T is a reference; otherwise it's const T&. +template +struct ByRef { typedef const T& type; }; // NOLINT +template +struct ByRef { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type + +// AddRef::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference::type. +template +struct AddRef { typedef T& type; }; // NOLINT +template +struct AddRef { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type + +// A helper for implementing get(). +template class Get; + +// A helper for implementing tuple_element. kIndexValid is true +// iff k < the number of fields in tuple type T. +template +struct TupleElement; + +template +struct TupleElement { + typedef T0 type; +}; + +template +struct TupleElement { + typedef T1 type; +}; + +template +struct TupleElement { + typedef T2 type; +}; + +template +struct TupleElement { + typedef T3 type; +}; + +template +struct TupleElement { + typedef T4 type; +}; + +template +struct TupleElement { + typedef T5 type; +}; + +template +struct TupleElement { + typedef T6 type; +}; + +template +struct TupleElement { + typedef T7 type; +}; + +template +struct TupleElement { + typedef T8 type; +}; + +template +struct TupleElement { + typedef T9 type; +}; + +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + +template +class GTEST_1_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} + + tuple(const tuple& t) : f0_(t.f0_) {} + + template + tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_1_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { + f0_ = t.f0_; + return *this; + } + + T0 f0_; +}; + +template +class GTEST_2_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), + f1_(f1) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} + + template + tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} + template + tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_2_TUPLE_(U)& t) { + return CopyFrom(t); + } + template + tuple& operator=(const ::std::pair& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + return *this; + } + + T0 f0_; + T1 f1_; +}; + +template +class GTEST_3_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + template + tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_3_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; +}; + +template +class GTEST_4_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} + + template + tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_4_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; +}; + +template +class GTEST_5_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, + GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_) {} + + template + tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_5_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; +}; + +template +class GTEST_6_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_) {} + + template + tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_6_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; +}; + +template +class GTEST_7_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + template + tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_7_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; +}; + +template +class GTEST_8_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, + GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + template + tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_8_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; +}; + +template +class GTEST_9_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + template + tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_9_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; +}; + +template +class tuple { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), + f9_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} + + template + tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), + f9_(t.f9_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_10_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + f9_ = t.f9_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; + T9 f9_; +}; + +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +template +inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { + return GTEST_1_TUPLE_(T)(f0); +} + +template +inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { + return GTEST_2_TUPLE_(T)(f0, f1); +} + +template +inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { + return GTEST_3_TUPLE_(T)(f0, f1, f2); +} + +template +inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3) { + return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); +} + +template +inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4) { + return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); +} + +template +inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5) { + return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); +} + +template +inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6) { + return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); +} + +template +inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { + return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); +} + +template +inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8) { + return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); +} + +template +inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8, const T9& f9) { + return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); +} + +// 6.1.3.3 Tuple helper classes. + +template struct tuple_size; + +template +struct tuple_size { + static const int value = 0; +}; + +template +struct tuple_size { + static const int value = 1; +}; + +template +struct tuple_size { + static const int value = 2; +}; + +template +struct tuple_size { + static const int value = 3; +}; + +template +struct tuple_size { + static const int value = 4; +}; + +template +struct tuple_size { + static const int value = 5; +}; + +template +struct tuple_size { + static const int value = 6; +}; + +template +struct tuple_size { + static const int value = 7; +}; + +template +struct tuple_size { + static const int value = 8; +}; + +template +struct tuple_size { + static const int value = 9; +}; + +template +struct tuple_size { + static const int value = 10; +}; + +template +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + +template <> +class Get<0> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + Field(Tuple& t) { return t.f0_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + ConstField(const Tuple& t) { return t.f0_; } +}; + +template <> +class Get<1> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + Field(Tuple& t) { return t.f1_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + ConstField(const Tuple& t) { return t.f1_; } +}; + +template <> +class Get<2> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + Field(Tuple& t) { return t.f2_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + ConstField(const Tuple& t) { return t.f2_; } +}; + +template <> +class Get<3> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + Field(Tuple& t) { return t.f3_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + ConstField(const Tuple& t) { return t.f3_; } +}; + +template <> +class Get<4> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + Field(Tuple& t) { return t.f4_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + ConstField(const Tuple& t) { return t.f4_; } +}; + +template <> +class Get<5> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + Field(Tuple& t) { return t.f5_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + ConstField(const Tuple& t) { return t.f5_; } +}; + +template <> +class Get<6> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + Field(Tuple& t) { return t.f6_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + ConstField(const Tuple& t) { return t.f6_; } +}; + +template <> +class Get<7> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + Field(Tuple& t) { return t.f7_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + ConstField(const Tuple& t) { return t.f7_; } +}; + +template <> +class Get<8> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + Field(Tuple& t) { return t.f8_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + ConstField(const Tuple& t) { return t.f8_; } +}; + +template <> +class Get<9> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + Field(Tuple& t) { return t.f9_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + ConstField(const Tuple& t) { return t.f9_; } +}; + +} // namespace gtest_internal + +template +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::Field(t); +} + +template +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(const GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template +struct SameSizeTuplePrefixComparator { + template + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator::Eq(t1, t2) && + ::std::tr1::get(t1) == ::std::tr1::get(t2); + } +}; + +} // namespace gtest_internal + +template +inline bool operator==(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size::value, + tuple_size::value>::Eq(t, u); +} + +template +inline bool operator!=(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + +#undef GTEST_0_TUPLE_ +#undef GTEST_1_TUPLE_ +#undef GTEST_2_TUPLE_ +#undef GTEST_3_TUPLE_ +#undef GTEST_4_TUPLE_ +#undef GTEST_5_TUPLE_ +#undef GTEST_6_TUPLE_ +#undef GTEST_7_TUPLE_ +#undef GTEST_8_TUPLE_ +#undef GTEST_9_TUPLE_ +#undef GTEST_10_TUPLE_ + +#undef GTEST_0_TYPENAMES_ +#undef GTEST_1_TYPENAMES_ +#undef GTEST_2_TYPENAMES_ +#undef GTEST_3_TYPENAMES_ +#undef GTEST_4_TYPENAMES_ +#undef GTEST_5_TYPENAMES_ +#undef GTEST_6_TYPENAMES_ +#undef GTEST_7_TYPENAMES_ +#undef GTEST_8_TYPENAMES_ +#undef GTEST_9_TYPENAMES_ +#undef GTEST_10_TYPENAMES_ + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +# elif GTEST_ENV_HAS_STD_TUPLE_ +# include +// C++11 puts its tuple into the ::std namespace rather than +// ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there. +// This causes undefined behavior, but supported compilers react in +// the way we intend. +namespace std { +namespace tr1 { +using ::std::get; +using ::std::make_tuple; +using ::std::tuple; +using ::std::tuple_element; +using ::std::tuple_size; +} +} + +# elif GTEST_OS_SYMBIAN + +// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to +// use STLport's tuple implementation, which unfortunately doesn't +// work as the copy of STLport distributed with Symbian is incomplete. +// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to +// use its own tuple implementation. +# ifdef BOOST_HAS_TR1_TUPLE +# undef BOOST_HAS_TR1_TUPLE +# endif // BOOST_HAS_TR1_TUPLE + +// This prevents , which defines +// BOOST_HAS_TR1_TUPLE, from being #included by Boost's . +# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED +# include + +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +// GCC 4.0+ implements tr1/tuple in the header. This does +// not conform to the TR1 spec, which requires the header to be . + +# if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +// Until version 4.3.2, gcc has a bug that causes , +// which is #included by , to not compile when RTTI is +// disabled. _TR1_FUNCTIONAL is the header guard for +// . Hence the following #define is a hack to prevent +// from being included. +# define _TR1_FUNCTIONAL 1 +# include +# undef _TR1_FUNCTIONAL // Allows the user to #include + // if he chooses to. +# else +# include // NOLINT +# endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 + +# else +// If the compiler is not GCC 4.0+, we assume the user is using a +// spec-conforming TR1 implementation. +# include // NOLINT +# endif // GTEST_USE_OWN_TR1_TUPLE + +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether clone(2) is supported. +// Usually it will only be available on Linux, excluding +// Linux on the Itanium architecture. +// Also see http://linux.die.net/man/2/clone. +#ifndef GTEST_HAS_CLONE +// The user didn't tell us, so we need to figure it out. + +# if GTEST_OS_LINUX && !defined(__ia64__) +# if GTEST_OS_LINUX_ANDROID +// On Android, clone() is only available on ARM starting with Gingerbread. +# if defined(__arm__) && __ANDROID_API__ >= 9 +# define GTEST_HAS_CLONE 1 +# else +# define GTEST_HAS_CLONE 0 +# endif +# else +# define GTEST_HAS_CLONE 1 +# endif +# else +# define GTEST_HAS_CLONE 0 +# endif // GTEST_OS_LINUX && !defined(__ia64__) + +#endif // GTEST_HAS_CLONE + +// Determines whether to support stream redirection. This is used to test +// output correctness and to implement death tests. +#ifndef GTEST_HAS_STREAM_REDIRECTION +// By default, we assume that stream redirection is supported on all +// platforms except known mobile ones. +# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN +# define GTEST_HAS_STREAM_REDIRECTION 0 +# else +# define GTEST_HAS_STREAM_REDIRECTION 1 +# endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#endif // GTEST_HAS_STREAM_REDIRECTION + +// Determines whether to support death tests. +// Google Test does not support death tests for VC 7.1 and earlier as +// abort() in a VC 7.1 application compiled as GUI in debug config +// pops up a dialog window that cannot be suppressed programmatically. +#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ + GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ + GTEST_OS_OPENBSD || GTEST_OS_QNX) +# define GTEST_HAS_DEATH_TEST 1 +# include // NOLINT +#endif + +// We don't support MSVC 7.1 with exceptions disabled now. Therefore +// all the compilers we care about are adequate for supporting +// value-parameterized tests. +#define GTEST_HAS_PARAM_TEST 1 + +// Determines whether to support type-driven tests. + +// Typed tests need and variadic macros, which GCC, VC++ 8.0, +// Sun Pro CC, IBM Visual Age, and HP aCC support. +#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ + defined(__IBMCPP__) || defined(__HP_aCC) +# define GTEST_HAS_TYPED_TEST 1 +# define GTEST_HAS_TYPED_TEST_P 1 +#endif + +// Determines whether to support Combine(). This only makes sense when +// value-parameterized tests are enabled. The implementation doesn't +// work on Sun Studio since it doesn't understand templated conversion +// operators. +#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) +# define GTEST_HAS_COMBINE 1 +#endif + +// Determines whether the system compiler uses UTF-16 for encoding wide strings. +#define GTEST_WIDE_STRING_USES_UTF16_ \ + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) + +// Determines whether test results can be streamed to a socket. +#if GTEST_OS_LINUX +# define GTEST_CAN_STREAM_RESULTS_ 1 +#endif + +// Defines some utility macros. + +// The GNU compiler emits a warning if nested "if" statements are followed by +// an "else" statement and braces are not used to explicitly disambiguate the +// "else" binding. This leads to problems with code like: +// +// if (gate) +// ASSERT_*(condition) << "Some message"; +// +// The "switch (0) case 0:" idiom is used to suppress this. +#ifdef __INTEL_COMPILER +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#else +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT +#endif + +// Use this annotation at the end of a struct/class definition to +// prevent the compiler from optimizing away instances that are never +// used. This is useful when all interesting logic happens inside the +// c'tor and / or d'tor. Example: +// +// struct Foo { +// Foo() { ... } +// } GTEST_ATTRIBUTE_UNUSED_; +// +// Also use it after a variable or parameter declaration to tell the +// compiler the variable/parameter does not have to be used. +#if defined(__GNUC__) && !defined(COMPILER_ICC) +# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#else +# define GTEST_ATTRIBUTE_UNUSED_ +#endif + +// A macro to disallow operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_ASSIGN_(type)\ + void operator=(type const &) + +// A macro to disallow copy constructor and operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ + type(type const &);\ + GTEST_DISALLOW_ASSIGN_(type) + +// Tell the compiler to warn about unused return values for functions declared +// with this macro. The macro should be used on function declarations +// following the argument list: +// +// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; +#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) +# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#else +# define GTEST_MUST_USE_RESULT_ +#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC + +// Determine whether the compiler supports Microsoft's Structured Exception +// Handling. This is supported by several Windows compilers but generally +// does not exist on any other system. +#ifndef GTEST_HAS_SEH +// The user didn't tell us, so we need to figure it out. + +# if defined(_MSC_VER) || defined(__BORLANDC__) +// These two compilers are known to support SEH. +# define GTEST_HAS_SEH 1 +# else +// Assume no SEH. +# define GTEST_HAS_SEH 0 +# endif + +#endif // GTEST_HAS_SEH + +#ifdef _MSC_VER + +# if GTEST_LINKED_AS_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllimport) +# elif GTEST_CREATE_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllexport) +# endif + +#endif // _MSC_VER + +#ifndef GTEST_API_ +# define GTEST_API_ +#endif + +#ifdef __GNUC__ +// Ask the compiler to never inline a given function. +# define GTEST_NO_INLINE_ __attribute__((noinline)) +#else +# define GTEST_NO_INLINE_ +#endif + +// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. +#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) +# define GTEST_HAS_CXXABI_H_ 1 +#else +# define GTEST_HAS_CXXABI_H_ 0 +#endif + +namespace testing { + +class Message; + +namespace internal { + +// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time +// expression is true. For example, you could use it to verify the +// size of a static array: +// +// GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, +// content_type_names_incorrect_size); +// +// or to make sure a struct is smaller than a certain size: +// +// GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large); +// +// The second argument to the macro is the name of the variable. If +// the expression is false, most compilers will issue a warning/error +// containing the name of the variable. + +template +struct CompileAssert { +}; + +#define GTEST_COMPILE_ASSERT_(expr, msg) \ + typedef ::testing::internal::CompileAssert<(bool(expr))> \ + msg[bool(expr) ? 1 : -1] + +// Implementation details of GTEST_COMPILE_ASSERT_: +// +// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 +// elements (and thus is invalid) when the expression is false. +// +// - The simpler definition +// +// #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1] +// +// does not work, as gcc supports variable-length arrays whose sizes +// are determined at run-time (this is gcc's extension and not part +// of the C++ standard). As a result, gcc fails to reject the +// following code with the simple definition: +// +// int foo; +// GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is +// // not a compile-time constant. +// +// - By using the type CompileAssert<(bool(expr))>, we ensures that +// expr is a compile-time constant. (Template arguments must be +// determined at compile-time.) +// +// - The outter parentheses in CompileAssert<(bool(expr))> are necessary +// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written +// +// CompileAssert +// +// instead, these compilers will refuse to compile +// +// GTEST_COMPILE_ASSERT_(5 > 0, some_message); +// +// (They seem to think the ">" in "5 > 0" marks the end of the +// template argument list.) +// +// - The array size is (bool(expr) ? 1 : -1), instead of simply +// +// ((expr) ? 1 : -1). +// +// This is to avoid running into a bug in MS VC 7.1, which +// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. + +// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h. +// +// This template is declared, but intentionally undefined. +template +struct StaticAssertTypeEqHelper; + +template +struct StaticAssertTypeEqHelper {}; + +#if GTEST_HAS_GLOBAL_STRING +typedef ::string string; +#else +typedef ::std::string string; +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING +typedef ::wstring wstring; +#elif GTEST_HAS_STD_WSTRING +typedef ::std::wstring wstring; +#endif // GTEST_HAS_GLOBAL_WSTRING + +// A helper for suppressing warnings on constant condition. It just +// returns 'condition'. +GTEST_API_ bool IsTrue(bool condition); + +// Defines scoped_ptr. + +// This implementation of scoped_ptr is PARTIAL - it only contains +// enough stuff to satisfy Google Test's need. +template +class scoped_ptr { + public: + typedef T element_type; + + explicit scoped_ptr(T* p = NULL) : ptr_(p) {} + ~scoped_ptr() { reset(); } + + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const { return ptr_; } + + T* release() { + T* const ptr = ptr_; + ptr_ = NULL; + return ptr; + } + + void reset(T* p = NULL) { + if (p != ptr_) { + if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. + delete ptr_; + } + ptr_ = p; + } + } + + private: + T* ptr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); +}; + +// Defines RE. + +// A simple C++ wrapper for . It uses the POSIX Extended +// Regular Expression syntax. +class GTEST_API_ RE { + public: + // A copy constructor is required by the Standard to initialize object + // references from r-values. + RE(const RE& other) { Init(other.pattern()); } + + // Constructs an RE from a string. + RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + + RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT + +#endif // GTEST_HAS_GLOBAL_STRING + + RE(const char* regex) { Init(regex); } // NOLINT + ~RE(); + + // Returns the string representation of the regex. + const char* pattern() const { return pattern_; } + + // FullMatch(str, re) returns true iff regular expression re matches + // the entire str. + // PartialMatch(str, re) returns true iff regular expression re + // matches a substring of str (including str itself). + // + // TODO(wan@google.com): make FullMatch() and PartialMatch() work + // when str contains NUL characters. + static bool FullMatch(const ::std::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::std::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#if GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const ::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#endif // GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const char* str, const RE& re); + static bool PartialMatch(const char* str, const RE& re); + + private: + void Init(const char* regex); + + // We use a const char* instead of an std::string, as Google Test used to be + // used where std::string is not available. TODO(wan@google.com): change to + // std::string. + const char* pattern_; + bool is_valid_; + +#if GTEST_USES_POSIX_RE + + regex_t full_regex_; // For FullMatch(). + regex_t partial_regex_; // For PartialMatch(). + +#else // GTEST_USES_SIMPLE_RE + + const char* full_pattern_; // For FullMatch(); + +#endif + + GTEST_DISALLOW_ASSIGN_(RE); +}; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, + int line); + +// Defines logging utilities: +// GTEST_LOG_(severity) - logs messages at the specified severity level. The +// message itself is streamed into the macro. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. + +enum GTestLogSeverity { + GTEST_INFO, + GTEST_WARNING, + GTEST_ERROR, + GTEST_FATAL +}; + +// Formats log entry severity, provides a stream object for streaming the +// log message, and terminates the message with a newline when going out of +// scope. +class GTEST_API_ GTestLog { + public: + GTestLog(GTestLogSeverity severity, const char* file, int line); + + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); + + ::std::ostream& GetStream() { return ::std::cerr; } + + private: + const GTestLogSeverity severity_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); +}; + +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__).GetStream() + +inline void LogToStderr() {} +inline void FlushInfoLog() { fflush(NULL); } + +// INTERNAL IMPLEMENTATION - DO NOT USE. +// +// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition +// is not satisfied. +// Synopsys: +// GTEST_CHECK_(boolean_condition); +// or +// GTEST_CHECK_(boolean_condition) << "Additional message"; +// +// This checks the condition and if the condition is not satisfied +// it prints message about the condition violation, including the +// condition itself, plus additional message streamed into it, if any, +// and then it aborts the program. It aborts the program irrespective of +// whether it is built in the debug mode or not. +#define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " + +// An all-mode assert to verify that the given POSIX-style function +// call returns 0 (indicating success). Known limitation: this +// doesn't expand to a balanced 'if' statement, so enclose the macro +// in {} if you need to use it as the only statement in an 'if' +// branch. +#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ + << gtest_error + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Use ImplicitCast_ as a safe version of static_cast for upcasting in +// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a +// const Foo*). When you use ImplicitCast_, the compiler checks that +// the cast is safe. Such explicit ImplicitCast_s are necessary in +// surprisingly many situations where C++ demands an exact type match +// instead of an argument type convertable to a target type. +// +// The syntax for using ImplicitCast_ is the same as for static_cast: +// +// ImplicitCast_(expr) +// +// ImplicitCast_ would have been part of the C++ standard library, +// but the proposal was submitted too late. It will probably make +// its way into the language in the future. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., implicit_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template +inline To ImplicitCast_(To x) { return x; } + +// When you upcast (that is, cast a pointer from type Foo to type +// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts +// always succeed. When you downcast (that is, cast a pointer from +// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because +// how do you know the pointer is really of type SubclassOfFoo? It +// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, +// when you downcast, you should use this macro. In debug mode, we +// use dynamic_cast<> to double-check the downcast is legal (we die +// if it's not). In normal mode, we do the efficient static_cast<> +// instead. Thus, it's important to test in debug mode to make sure +// the cast is legal! +// This is the only place in the code we should use dynamic_cast<>. +// In particular, you SHOULDN'T be using dynamic_cast<> in order to +// do RTTI (eg code like this: +// if (dynamic_cast(foo)) HandleASubclass1Object(foo); +// if (dynamic_cast(foo)) HandleASubclass2Object(foo); +// You should design the code some other way not to need this. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., down_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template // use like this: DownCast_(foo); +inline To DownCast_(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) { + const To to = NULL; + ::testing::internal::ImplicitCast_(to); + } + +#if GTEST_HAS_RTTI + // RTTI: debug mode only! + GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); +#endif + return static_cast(f); +} + +// Downcasts the pointer of type Base to Derived. +// Derived must be a subclass of Base. The parameter MUST +// point to a class of type Derived, not any subclass of it. +// When RTTI is available, the function performs a runtime +// check to enforce this. +template +Derived* CheckedDowncastToActualType(Base* base) { +#if GTEST_HAS_RTTI + GTEST_CHECK_(typeid(*base) == typeid(Derived)); + return dynamic_cast(base); // NOLINT +#else + return static_cast(base); // Poor man's downcast. +#endif +} + +#if GTEST_HAS_STREAM_REDIRECTION + +// Defines the stderr capturer: +// CaptureStdout - starts capturing stdout. +// GetCapturedStdout - stops capturing stdout and returns the captured string. +// CaptureStderr - starts capturing stderr. +// GetCapturedStderr - stops capturing stderr and returns the captured string. +// +GTEST_API_ void CaptureStdout(); +GTEST_API_ std::string GetCapturedStdout(); +GTEST_API_ void CaptureStderr(); +GTEST_API_ std::string GetCapturedStderr(); + +#endif // GTEST_HAS_STREAM_REDIRECTION + + +#if GTEST_HAS_DEATH_TEST + +const ::std::vector& GetInjectableArgvs(); +void SetInjectableArgvs(const ::std::vector* + new_argvs); + +// A copy of all command line arguments. Set by InitGoogleTest(). +extern ::std::vector g_argvs; + +#endif // GTEST_HAS_DEATH_TEST + +// Defines synchronization primitives. + +#if GTEST_HAS_PTHREAD + +// Sleeps for (roughly) n milli-seconds. This function is only for +// testing Google Test's own constructs. Don't use it in user tests, +// either directly or indirectly. +inline void SleepMilliseconds(int n) { + const timespec time = { + 0, // 0 seconds. + n * 1000L * 1000L, // And n ms. + }; + nanosleep(&time, NULL); +} + +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class Notification { + public: + Notification() : notified_(false) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + } + ~Notification() { + pthread_mutex_destroy(&mutex_); + } + + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { + pthread_mutex_lock(&mutex_); + notified_ = true; + pthread_mutex_unlock(&mutex_); + } + + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + for (;;) { + pthread_mutex_lock(&mutex_); + const bool notified = notified_; + pthread_mutex_unlock(&mutex_); + if (notified) + break; + SleepMilliseconds(10); + } + } + + private: + pthread_mutex_t mutex_; + bool notified_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; + +// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. +// Consequently, it cannot select a correct instantiation of ThreadWithParam +// in order to call its Run(). Introducing ThreadWithParamBase as a +// non-templated base class for ThreadWithParam allows us to bypass this +// problem. +class ThreadWithParamBase { + public: + virtual ~ThreadWithParamBase() {} + virtual void Run() = 0; +}; + +// pthread_create() accepts a pointer to a function type with the C linkage. +// According to the Standard (7.5/1), function types with different linkages +// are different even if they are otherwise identical. Some compilers (for +// example, SunStudio) treat them as different types. Since class methods +// cannot be defined with C-linkage we need to define a free C-function to +// pass into pthread_create(). +extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { + static_cast(thread)->Run(); + return NULL; +} + +// Helper class for testing Google Test's multi-threading constructs. +// To use it, write: +// +// void ThreadFunc(int param) { /* Do things with param */ } +// Notification thread_can_start; +// ... +// // The thread_can_start parameter is optional; you can supply NULL. +// ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); +// thread_can_start.Notify(); +// +// These classes are only for testing Google Test's own constructs. Do +// not use them in user tests, either directly or indirectly. +template +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void (*UserThreadFunc)(T); + + ThreadWithParam( + UserThreadFunc func, T param, Notification* thread_can_start) + : func_(func), + param_(param), + thread_can_start_(thread_can_start), + finished_(false) { + ThreadWithParamBase* const base = this; + // The thread can be created only after all fields except thread_ + // have been initialized. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); + } + ~ThreadWithParam() { Join(); } + + void Join() { + if (!finished_) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); + finished_ = true; + } + } + + virtual void Run() { + if (thread_can_start_ != NULL) + thread_can_start_->WaitForNotification(); + func_(param_); + } + + private: + const UserThreadFunc func_; // User-supplied thread function. + const T param_; // User-supplied parameter to the thread function. + // When non-NULL, used to block execution until the controller thread + // notifies. + Notification* const thread_can_start_; + bool finished_; // true iff we know that the thread function has finished. + pthread_t thread_; // The native thread object. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// MutexBase and Mutex implement mutex on pthreads-based platforms. They +// are used in conjunction with class MutexLock: +// +// Mutex mutex; +// ... +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end +// // of the current scope. +// +// MutexBase implements behavior for both statically and dynamically +// allocated mutexes. Do not use MutexBase directly. Instead, write +// the following to define a static mutex: +// +// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); +// +// You can forward declare a static mutex like this: +// +// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); +// +// To create a dynamic mutex, just define an object of type Mutex. +class MutexBase { + public: + // Acquires this mutex. + void Lock() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); + owner_ = pthread_self(); + has_owner_ = true; + } + + // Releases this mutex. + void Unlock() { + // Since the lock is being released the owner_ field should no longer be + // considered valid. We don't protect writing to has_owner_ here, as it's + // the caller's responsibility to ensure that the current thread holds the + // mutex when this is called. + has_owner_ = false; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); + } + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld() const { + GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) + << "The current thread is not holding the mutex @" << this; + } + + // A static mutex may be used before main() is entered. It may even + // be used before the dynamic initialization stage. Therefore we + // must be able to initialize a static mutex object at link time. + // This means MutexBase has to be a POD and its member variables + // have to be public. + public: + pthread_mutex_t mutex_; // The underlying pthread mutex. + // has_owner_ indicates whether the owner_ field below contains a valid thread + // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All + // accesses to the owner_ field should be protected by a check of this field. + // An alternative might be to memset() owner_ to all zeros, but there's no + // guarantee that a zero'd pthread_t is necessarily invalid or even different + // from pthread_self(). + bool has_owner_; + pthread_t owner_; // The thread holding the mutex. +}; + +// Forward-declares a static mutex. +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex + +// Defines and statically (i.e. at link time) initializes a static mutex. +// The initialization list here does not explicitly initialize each field, +// instead relying on default initialization for the unspecified fields. In +// particular, the owner_ field (a pthread_t) is not explicitly initialized. +// This allows initialization to work whether pthread_t is a scalar or struct. +// The flag -Wmissing-field-initializers must not be specified for this to work. +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } + +// The Mutex class can only be used for mutexes created at runtime. It +// shares its API with MutexBase otherwise. +class Mutex : public MutexBase { + public: + Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + has_owner_ = false; + } + ~Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +// We cannot name this class MutexLock as the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(MutexBase* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + MutexBase* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Helpers for ThreadLocal. + +// pthread_key_create() requires DeleteThreadLocalValue() to have +// C-linkage. Therefore it cannot be templatized to access +// ThreadLocal. Hence the need for class +// ThreadLocalValueHolderBase. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Called by pthread to delete thread-local data stored by +// pthread_setspecific(). +extern "C" inline void DeleteThreadLocalValue(void* value_holder) { + delete static_cast(value_holder); +} + +// Implements thread-local storage on pthreads-based systems. +// +// // Thread 1 +// ThreadLocal tl(100); // 100 is the default value for each thread. +// +// // Thread 2 +// tl.set(150); // Changes the value for thread 2 only. +// EXPECT_EQ(150, tl.get()); +// +// // Thread 1 +// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. +// tl.set(200); +// EXPECT_EQ(200, tl.get()); +// +// The template type argument T must have a public copy constructor. +// In addition, the default ThreadLocal constructor requires T to have +// a public default constructor. +// +// An object managed for a thread by a ThreadLocal instance is deleted +// when the thread exits. Or, if the ThreadLocal instance dies in +// that thread, when the ThreadLocal dies. It's the user's +// responsibility to ensure that all other threads using a ThreadLocal +// have exited when it dies, or the per-thread objects for those +// threads will not be deleted. +// +// Google Test only uses global ThreadLocal objects. That means they +// will die after main() has returned. Therefore, no per-thread +// object managed by Google Test will be leaked as long as all threads +// using Google Test have exited when main() returns. +template +class ThreadLocal { + public: + ThreadLocal() : key_(CreateKey()), + default_() {} + explicit ThreadLocal(const T& value) : key_(CreateKey()), + default_(value) {} + + ~ThreadLocal() { + // Destroys the managed object for the current thread, if any. + DeleteThreadLocalValue(pthread_getspecific(key_)); + + // Releases resources associated with the key. This will *not* + // delete managed objects for other threads. + GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); + } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + static pthread_key_t CreateKey() { + pthread_key_t key; + // When a thread exits, DeleteThreadLocalValue() will be called on + // the object managed for that thread. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); + return key; + } + + T* GetOrCreateValue() const { + ThreadLocalValueHolderBase* const holder = + static_cast(pthread_getspecific(key_)); + if (holder != NULL) { + return CheckedDowncastToActualType(holder)->pointer(); + } + + ValueHolder* const new_holder = new ValueHolder(default_); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); + } + + // A key pthreads uses for looking up per-thread values. + const pthread_key_t key_; + const T default_; // The default value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +# define GTEST_IS_THREADSAFE 1 + +#else // GTEST_HAS_PTHREAD + +// A dummy implementation of synchronization primitives (mutex, lock, +// and thread-local variable). Necessary for compiling Google Test where +// mutex is not supported - using Google Test in multiple threads is not +// supported on such platforms. + +class Mutex { + public: + Mutex() {} + void Lock() {} + void Unlock() {} + void AssertHeld() const {} +}; + +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex + +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex*) {} // NOLINT +}; + +typedef GTestMutexLock MutexLock; + +template +class ThreadLocal { + public: + ThreadLocal() : value_() {} + explicit ThreadLocal(const T& value) : value_(value) {} + T* pointer() { return &value_; } + const T* pointer() const { return &value_; } + const T& get() const { return value_; } + void set(const T& value) { value_ = value; } + private: + T value_; +}; + +// The above synchronization primitives have dummy implementations. +// Therefore Google Test is not thread-safe. +# define GTEST_IS_THREADSAFE 0 + +#endif // GTEST_HAS_PTHREAD + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +GTEST_API_ size_t GetThreadCount(); + +// Passing non-POD classes through ellipsis (...) crashes the ARM +// compiler and generates a warning in Sun Studio. The Nokia Symbian +// and the IBM XL C/C++ compiler try to instantiate a copy constructor +// for objects passed through ellipsis (...), failing for uncopyable +// objects. We define this to ensure that only POD is passed through +// ellipsis on these systems. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +# define GTEST_ELLIPSIS_NEEDS_POD_ 1 +#else +# define GTEST_CAN_COMPARE_NULL 1 +#endif + +// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between +// const T& and const T* in a function template. These compilers +// _can_ decide between class template specializations for T and T*, +// so a tr1::type_traits-like is_pointer works. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) +# define GTEST_NEEDS_IS_POINTER_ 1 +#endif + +template +struct bool_constant { + typedef bool_constant type; + static const bool value = bool_value; +}; +template const bool bool_constant::value; + +typedef bool_constant false_type; +typedef bool_constant true_type; + +template +struct is_pointer : public false_type {}; + +template +struct is_pointer : public true_type {}; + +template +struct IteratorTraits { + typedef typename Iterator::value_type value_type; +}; + +template +struct IteratorTraits { + typedef T value_type; +}; + +template +struct IteratorTraits { + typedef T value_type; +}; + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_SEP_ "\\" +# define GTEST_HAS_ALT_PATH_SEP_ 1 +// The biggest signed integer type the compiler supports. +typedef __int64 BiggestInt; +#else +# define GTEST_PATH_SEP_ "/" +# define GTEST_HAS_ALT_PATH_SEP_ 0 +typedef long long BiggestInt; // NOLINT +#endif // GTEST_OS_WINDOWS + +// Utilities for char. + +// isspace(int ch) and friends accept an unsigned char or EOF. char +// may be signed, depending on the compiler (or compiler flags). +// Therefore we need to cast a char to unsigned char before calling +// isspace(), etc. + +inline bool IsAlpha(char ch) { + return isalpha(static_cast(ch)) != 0; +} +inline bool IsAlNum(char ch) { + return isalnum(static_cast(ch)) != 0; +} +inline bool IsDigit(char ch) { + return isdigit(static_cast(ch)) != 0; +} +inline bool IsLower(char ch) { + return islower(static_cast(ch)) != 0; +} +inline bool IsSpace(char ch) { + return isspace(static_cast(ch)) != 0; +} +inline bool IsUpper(char ch) { + return isupper(static_cast(ch)) != 0; +} +inline bool IsXDigit(char ch) { + return isxdigit(static_cast(ch)) != 0; +} +inline bool IsXDigit(wchar_t ch) { + const unsigned char low_byte = static_cast(ch); + return ch == low_byte && isxdigit(low_byte) != 0; +} + +inline char ToLower(char ch) { + return static_cast(tolower(static_cast(ch))); +} +inline char ToUpper(char ch) { + return static_cast(toupper(static_cast(ch))); +} + +// The testing::internal::posix namespace holds wrappers for common +// POSIX functions. These wrappers hide the differences between +// Windows/MSVC and POSIX systems. Since some compilers define these +// standard functions as macros, the wrapper cannot have the same name +// as the wrapped function. + +namespace posix { + +// Functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + +typedef struct _stat StatStruct; + +# ifdef __BORLANDC__ +inline int IsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +# else // !__BORLANDC__ +# if GTEST_OS_WINDOWS_MOBILE +inline int IsATTY(int /* fd */) { return 0; } +# else +inline int IsATTY(int fd) { return _isatty(fd); } +# endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return _strdup(src); } +# endif // __BORLANDC__ + +# if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } +// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this +// time and thus not defined there. +# else +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } +inline int RmDir(const char* dir) { return _rmdir(dir); } +inline bool IsDir(const StatStruct& st) { + return (_S_IFDIR & st.st_mode) != 0; +} +# endif // GTEST_OS_WINDOWS_MOBILE + +#else + +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int IsATTY(int fd) { return isatty(fd); } +inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +inline int RmDir(const char* dir) { return rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#endif // GTEST_OS_WINDOWS + +// Functions deprecated by MSVC 8.0. + +#ifdef _MSC_VER +// Temporarily disable warning 4996 (deprecated function). +# pragma warning(push) +# pragma warning(disable:4996) +#endif + +inline const char* StrNCpy(char* dest, const char* src, size_t n) { + return strncpy(dest, src, n); +} + +// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and +// StrError() aren't needed on Windows CE at this time and thus not +// defined there. + +#if !GTEST_OS_WINDOWS_MOBILE +inline int ChDir(const char* dir) { return chdir(dir); } +#endif +inline FILE* FOpen(const char* path, const char* mode) { + return fopen(path, mode); +} +#if !GTEST_OS_WINDOWS_MOBILE +inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { + return freopen(path, mode, stream); +} +inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } +#endif +inline int FClose(FILE* fp) { return fclose(fp); } +#if !GTEST_OS_WINDOWS_MOBILE +inline int Read(int fd, void* buf, unsigned int count) { + return static_cast(read(fd, buf, count)); +} +inline int Write(int fd, const void* buf, unsigned int count) { + return static_cast(write(fd, buf, count)); +} +inline int Close(int fd) { return close(fd); } +inline const char* StrError(int errnum) { return strerror(errnum); } +#endif +inline const char* GetEnv(const char* name) { +#if GTEST_OS_WINDOWS_MOBILE + // We are on Windows CE, which has no environment variables. + return NULL; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != NULL && env[0] != '\0') ? env : NULL; +#else + return getenv(name); +#endif +} + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif + +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE has no C library. The abort() function is used in +// several places in Google Test. This implementation provides a reasonable +// imitation of standard behaviour. +void Abort(); +#else +inline void Abort() { abort(); } +#endif // GTEST_OS_WINDOWS_MOBILE + +} // namespace posix + +// MSVC "deprecates" snprintf and issues warnings wherever it is used. In +// order to avoid these warnings, we need to use _snprintf or _snprintf_s on +// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate +// function in order to achieve that. We use macro definition here because +// snprintf is a variadic function. +#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE +// MSVC 2005 and above support variadic macros. +# define GTEST_SNPRINTF_(buffer, size, format, ...) \ + _snprintf_s(buffer, size, size, format, __VA_ARGS__) +#elif defined(_MSC_VER) +// Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't +// complain about _snprintf. +# define GTEST_SNPRINTF_ _snprintf +#else +# define GTEST_SNPRINTF_ snprintf +#endif + +// The maximum number a BiggestInt can represent. This definition +// works no matter BiggestInt is represented in one's complement or +// two's complement. +// +// We cannot rely on numeric_limits in STL, as __int64 and long long +// are not part of standard C++ and numeric_limits doesn't need to be +// defined for them. +const BiggestInt kMaxBiggestInt = + ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); + +// This template class serves as a compile-time function from size to +// type. It maps a size in bytes to a primitive type with that +// size. e.g. +// +// TypeWithSize<4>::UInt +// +// is typedef-ed to be unsigned int (unsigned integer made up of 4 +// bytes). +// +// Such functionality should belong to STL, but I cannot find it +// there. +// +// Google Test uses this class in the implementation of floating-point +// comparison. +// +// For now it only handles UInt (unsigned int) as that's all Google Test +// needs. Other types can be easily added in the future if need +// arises. +template +class TypeWithSize { + public: + // This prevents the user from using TypeWithSize with incorrect + // values of N. + typedef void UInt; +}; + +// The specialization for size 4. +template <> +class TypeWithSize<4> { + public: + // unsigned int has size 4 in both gcc and MSVC. + // + // As base/basictypes.h doesn't compile on Windows, we cannot use + // uint32, uint64, and etc here. + typedef int Int; + typedef unsigned int UInt; +}; + +// The specialization for size 8. +template <> +class TypeWithSize<8> { + public: +#if GTEST_OS_WINDOWS + typedef __int64 Int; + typedef unsigned __int64 UInt; +#else + typedef long long Int; // NOLINT + typedef unsigned long long UInt; // NOLINT +#endif // GTEST_OS_WINDOWS +}; + +// Integer types of known sizes. +typedef TypeWithSize<4>::Int Int32; +typedef TypeWithSize<4>::UInt UInt32; +typedef TypeWithSize<8>::Int Int64; +typedef TypeWithSize<8>::UInt UInt64; +typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. + +// Utilities for command line flags and environment variables. + +// Macro for referencing flags. +#define GTEST_FLAG(name) FLAGS_gtest_##name + +// Macros for declaring flags. +#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) +#define GTEST_DECLARE_int32_(name) \ + GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) +#define GTEST_DECLARE_string_(name) \ + GTEST_API_ extern ::std::string GTEST_FLAG(name) + +// Macros for defining flags. +#define GTEST_DEFINE_bool_(name, default_val, doc) \ + GTEST_API_ bool GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_int32_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_string_(name, default_val, doc) \ + GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) + +// Thread annotations +#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) +#define GTEST_LOCK_EXCLUDED_(locks) + +// Parses 'str' for a 32-bit signed integer. If successful, writes the result +// to *value and returns true; otherwise leaves *value unchanged and returns +// false. +// TODO(chandlerc): Find a better way to refactor flag and environment parsing +// out of both gtest-port.cc and gtest.cc to avoid exporting this utility +// function. +bool ParseInt32(const Message& src_text, const char* str, Int32* value); + +// Parses a bool/Int32/string from the environment variable +// corresponding to the given Google Test flag. +bool BoolFromGTestEnv(const char* flag, bool default_val); +GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +const char* StringFromGTestEnv(const char* flag, const char* default_val); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +#if GTEST_OS_LINUX +# include +# include +# include +# include +#endif // GTEST_OS_LINUX + +#include +#include +#include +#include +#include + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares the String class and functions used internally by +// Google Test. They are subject to change without notice. They should not used +// by code external to Google Test. +// +// This header file is #included by . +// It should not be #included by other files. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ + +#ifdef __BORLANDC__ +// string.h is not guaranteed to provide strcpy on C++ Builder. +# include +#endif + +#include +#include + + +namespace testing { +namespace internal { + +// String - an abstract class holding static string utilities. +class GTEST_API_ String { + public: + // Static utility methods + + // Clones a 0-terminated C string, allocating memory using new. The + // caller is responsible for deleting the return value using + // delete[]. Returns the cloned string, or NULL if the input is + // NULL. + // + // This is different from strdup() in string.h, which allocates + // memory using malloc(). + static const char* CloneCString(const char* c_str); + +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be + // able to pass strings to Win32 APIs on CE we need to convert them + // to 'Unicode', UTF-16. + + // Creates a UTF-16 wide string from the given ANSI string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the wide string, or NULL if the + // input is NULL. + // + // The wide string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static LPCWSTR AnsiToUtf16(const char* c_str); + + // Creates an ANSI string from the given wide string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the ANSI string, or NULL if the + // input is NULL. + // + // The returned string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static const char* Utf16ToAnsi(LPCWSTR utf16_str); +#endif + + // Compares two C strings. Returns true iff they have the same content. + // + // Unlike strcmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CStringEquals(const char* lhs, const char* rhs); + + // Converts a wide C string to a String using the UTF-8 encoding. + // NULL will be converted to "(null)". If an error occurred during + // the conversion, "(failed to convert from wide string)" is + // returned. + static std::string ShowWideCString(const wchar_t* wide_c_str); + + // Compares two wide C strings. Returns true iff they have the same + // content. + // + // Unlike wcscmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); + + // Compares two C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike strcasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CaseInsensitiveCStringEquals(const char* lhs, + const char* rhs); + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. + static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs); + + // Returns true iff the given string ends with the given suffix, ignoring + // case. Any string is considered to end with an empty suffix. + static bool EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix); + + // Formats a list of arguments to an std::string, using the same format + // spec string as for printf. + // + // We do not use the StringPrintf class as it is not universally + // available. + // + // The result is limited to 4096 characters (including the tailing + // 0). If 4096 characters are not enough to format the input, + // "" is returned. + static std::string Format(const char* format, ...); + + private: + String(); // Not meant to be instantiated. +}; // class String + +// Gets the content of the stringstream's buffer as an std::string. Each '\0' +// character in the buffer is replaced with "\\0". +GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); + +// Converts a streamable value to an std::string. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". + +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +std::string StreamableToString(const T& streamable); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This header file declares classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included in . +// Do not include this header file separately! + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ + + +namespace testing { +namespace internal { + +// FilePath - a class for file and directory pathname manipulation which +// handles platform-specific conventions (like the pathname separator). +// Used for helper functions for naming files in a directory for xml output. +// Except for Set methods, all methods are const or static, which provides an +// "immutable value object" -- useful for peace of mind. +// A FilePath with a value ending in a path separator ("like/this/") represents +// a directory, otherwise it is assumed to represent a file. In either case, +// it may or may not represent an actual file or directory in the file system. +// Names are NOT checked for syntax correctness -- no checking for illegal +// characters, malformed paths, etc. + +class GTEST_API_ FilePath { + public: + FilePath() : pathname_("") { } + FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } + + explicit FilePath(const std::string& pathname) : pathname_(pathname) { + Normalize(); + } + + FilePath& operator=(const FilePath& rhs) { + Set(rhs); + return *this; + } + + void Set(const FilePath& rhs) { + pathname_ = rhs.pathname_; + } + + const std::string& string() const { return pathname_; } + const char* c_str() const { return pathname_.c_str(); } + + // Returns the current working directory, or "" if unsuccessful. + static FilePath GetCurrentDir(); + + // Given directory = "dir", base_name = "test", number = 0, + // extension = "xml", returns "dir/test.xml". If number is greater + // than zero (e.g., 12), returns "dir/test_12.xml". + // On Windows platform, uses \ as the separator rather than /. + static FilePath MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension); + + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); + + // Returns a pathname for a file that does not currently exist. The pathname + // will be directory/base_name.extension or + // directory/base_name_.extension if directory/base_name.extension + // already exists. The number will be incremented until a pathname is found + // that does not already exist. + // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. + // There could be a race condition if two or more processes are calling this + // function at the same time -- they could both pick the same filename. + static FilePath GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension); + + // Returns true iff the path is "". + bool IsEmpty() const { return pathname_.empty(); } + + // If input name has a trailing separator character, removes it and returns + // the name, otherwise return the name string unmodified. + // On Windows platform, uses \ as the separator, other platforms use /. + FilePath RemoveTrailingPathSeparator() const; + + // Returns a copy of the FilePath with the directory part removed. + // Example: FilePath("path/to/file").RemoveDirectoryName() returns + // FilePath("file"). If there is no directory part ("just_a_file"), it returns + // the FilePath unmodified. If there is no file part ("just_a_dir/") it + // returns an empty FilePath (""). + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveDirectoryName() const; + + // RemoveFileName returns the directory path with the filename removed. + // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". + // If the FilePath is "a_file" or "/a_file", RemoveFileName returns + // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does + // not have a file, like "just/a/dir/", it returns the FilePath unmodified. + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveFileName() const; + + // Returns a copy of the FilePath with the case-insensitive extension removed. + // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns + // FilePath("dir/file"). If a case-insensitive extension is not + // found, returns a copy of the original FilePath. + FilePath RemoveExtension(const char* extension) const; + + // Creates directories so that path exists. Returns true if successful or if + // the directories already exist; returns false if unable to create + // directories for any reason. Will also return false if the FilePath does + // not represent a directory (that is, it doesn't end with a path separator). + bool CreateDirectoriesRecursively() const; + + // Create the directory so that path exists. Returns true if successful or + // if the directory already exists; returns false if unable to create the + // directory for any reason, including if the parent directory does not + // exist. Not named "CreateDirectory" because that's a macro on Windows. + bool CreateFolder() const; + + // Returns true if FilePath describes something in the file-system, + // either a file, directory, or whatever, and that something exists. + bool FileOrDirectoryExists() const; + + // Returns true if pathname describes a directory in the file-system + // that exists. + bool DirectoryExists() const; + + // Returns true if FilePath ends with a path separator, which indicates that + // it is intended to represent a directory. Returns false otherwise. + // This does NOT check that a directory (or file) actually exists. + bool IsDirectory() const; + + // Returns true if pathname describes a root directory. (Windows has one + // root directory per disk drive.) + bool IsRootDirectory() const; + + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; + + private: + // Replaces multiple consecutive separators with a single separator. + // For example, "bar///foo" becomes "bar/foo". Does not eliminate other + // redundancies that might be in a pathname involving "." or "..". + // + // A pathname with multiple consecutive separators may occur either through + // user error or as a result of some scripts or APIs that generate a pathname + // with a trailing separator. On other platforms the same API or script + // may NOT generate a pathname with a trailing "/". Then elsewhere that + // pathname may have another "/" and pathname components added to it, + // without checking for the separator already being there. + // The script language and operating system may allow paths like "foo//bar" + // but some of the functions in FilePath will not handle that correctly. In + // particular, RemoveTrailingPathSeparator() only removes one separator, and + // it is called in CreateDirectoriesRecursively() assuming that it will change + // a pathname from directory syntax (trailing separator) to filename syntax. + // + // On Windows this method also replaces the alternate path separator '/' with + // the primary path separator '\\', so that for example "bar\\/\\foo" becomes + // "bar\\foo". + + void Normalize(); + + // Returns a pointer to the last occurence of a valid path separator in + // the FilePath. On Windows, for example, both '/' and '\' are valid path + // separators. Returns NULL if no path separator was found. + const char* FindLastPathSeparator() const; + + std::string pathname_; +}; // class FilePath + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +// This file was GENERATED by command: +// pump.py gtest-type-util.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most 50 types in a list, and at most 50 +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +# if GTEST_HAS_CXXABI_H_ +# include +# elif defined(__HP_aCC) +# include +# endif // GTEST_HASH_CXXABI_H_ + +namespace testing { +namespace internal { + +// GetTypeName() returns a human-readable name of type T. +// NB: This function is also used in Google Mock, so don't move it inside of +// the typed-test-only section below. +template +std::string GetTypeName() { +# if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +# if GTEST_HAS_CXXABI_H_ + using abi::__cxa_demangle; +# endif // GTEST_HAS_CXXABI_H_ + char* const readable_name = __cxa_demangle(name, 0, 0, &status); + const std::string name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +# else + return name; +# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC + +# else + + return ""; + +# endif // GTEST_HAS_RTTI +} + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// AssertyTypeEq::type is defined iff T1 and T2 are the same +// type. This can be used as a compile-time assertion to ensure that +// two types are equal. + +template +struct AssertTypeEq; + +template +struct AssertTypeEq { + typedef bool type; +}; + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types, Type, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; +template +struct Types2 { + typedef T1 Head; + typedef Types1 Tail; +}; + +template +struct Types3 { + typedef T1 Head; + typedef Types2 Tail; +}; + +template +struct Types4 { + typedef T1 Head; + typedef Types3 Tail; +}; + +template +struct Types5 { + typedef T1 Head; + typedef Types4 Tail; +}; + +template +struct Types6 { + typedef T1 Head; + typedef Types5 Tail; +}; + +template +struct Types7 { + typedef T1 Head; + typedef Types6 Tail; +}; + +template +struct Types8 { + typedef T1 Head; + typedef Types7 Tail; +}; + +template +struct Types9 { + typedef T1 Head; + typedef Types8 Tail; +}; + +template +struct Types10 { + typedef T1 Head; + typedef Types9 Tail; +}; + +template +struct Types11 { + typedef T1 Head; + typedef Types10 Tail; +}; + +template +struct Types12 { + typedef T1 Head; + typedef Types11 Tail; +}; + +template +struct Types13 { + typedef T1 Head; + typedef Types12 Tail; +}; + +template +struct Types14 { + typedef T1 Head; + typedef Types13 Tail; +}; + +template +struct Types15 { + typedef T1 Head; + typedef Types14 Tail; +}; + +template +struct Types16 { + typedef T1 Head; + typedef Types15 Tail; +}; + +template +struct Types17 { + typedef T1 Head; + typedef Types16 Tail; +}; + +template +struct Types18 { + typedef T1 Head; + typedef Types17 Tail; +}; + +template +struct Types19 { + typedef T1 Head; + typedef Types18 Tail; +}; + +template +struct Types20 { + typedef T1 Head; + typedef Types19 Tail; +}; + +template +struct Types21 { + typedef T1 Head; + typedef Types20 Tail; +}; + +template +struct Types22 { + typedef T1 Head; + typedef Types21 Tail; +}; + +template +struct Types23 { + typedef T1 Head; + typedef Types22 Tail; +}; + +template +struct Types24 { + typedef T1 Head; + typedef Types23 Tail; +}; + +template +struct Types25 { + typedef T1 Head; + typedef Types24 Tail; +}; + +template +struct Types26 { + typedef T1 Head; + typedef Types25 Tail; +}; + +template +struct Types27 { + typedef T1 Head; + typedef Types26 Tail; +}; + +template +struct Types28 { + typedef T1 Head; + typedef Types27 Tail; +}; + +template +struct Types29 { + typedef T1 Head; + typedef Types28 Tail; +}; + +template +struct Types30 { + typedef T1 Head; + typedef Types29 Tail; +}; + +template +struct Types31 { + typedef T1 Head; + typedef Types30 Tail; +}; + +template +struct Types32 { + typedef T1 Head; + typedef Types31 Tail; +}; + +template +struct Types33 { + typedef T1 Head; + typedef Types32 Tail; +}; + +template +struct Types34 { + typedef T1 Head; + typedef Types33 Tail; +}; + +template +struct Types35 { + typedef T1 Head; + typedef Types34 Tail; +}; + +template +struct Types36 { + typedef T1 Head; + typedef Types35 Tail; +}; + +template +struct Types37 { + typedef T1 Head; + typedef Types36 Tail; +}; + +template +struct Types38 { + typedef T1 Head; + typedef Types37 Tail; +}; + +template +struct Types39 { + typedef T1 Head; + typedef Types38 Tail; +}; + +template +struct Types40 { + typedef T1 Head; + typedef Types39 Tail; +}; + +template +struct Types41 { + typedef T1 Head; + typedef Types40 Tail; +}; + +template +struct Types42 { + typedef T1 Head; + typedef Types41 Tail; +}; + +template +struct Types43 { + typedef T1 Head; + typedef Types42 Tail; +}; + +template +struct Types44 { + typedef T1 Head; + typedef Types43 Tail; +}; + +template +struct Types45 { + typedef T1 Head; + typedef Types44 Tail; +}; + +template +struct Types46 { + typedef T1 Head; + typedef Types45 Tail; +}; + +template +struct Types47 { + typedef T1 Head; + typedef Types46 Tail; +}; + +template +struct Types48 { + typedef T1 Head; + typedef Types47 Tail; +}; + +template +struct Types49 { + typedef T1 Head; + typedef Types48 Tail; +}; + +template +struct Types50 { + typedef T1 Head; + typedef Types49 Tail; +}; + + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types +// will appear as Types in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types, and Google Test will translate +// that to TypesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. +template +struct Types { + typedef internal::Types50 type; +}; + +template <> +struct Types { + typedef internal::Types0 type; +}; +template +struct Types { + typedef internal::Types1 type; +}; +template +struct Types { + typedef internal::Types2 type; +}; +template +struct Types { + typedef internal::Types3 type; +}; +template +struct Types { + typedef internal::Types4 type; +}; +template +struct Types { + typedef internal::Types5 type; +}; +template +struct Types { + typedef internal::Types6 type; +}; +template +struct Types { + typedef internal::Types7 type; +}; +template +struct Types { + typedef internal::Types8 type; +}; +template +struct Types { + typedef internal::Types9 type; +}; +template +struct Types { + typedef internal::Types10 type; +}; +template +struct Types { + typedef internal::Types11 type; +}; +template +struct Types { + typedef internal::Types12 type; +}; +template +struct Types { + typedef internal::Types13 type; +}; +template +struct Types { + typedef internal::Types14 type; +}; +template +struct Types { + typedef internal::Types15 type; +}; +template +struct Types { + typedef internal::Types16 type; +}; +template +struct Types { + typedef internal::Types17 type; +}; +template +struct Types { + typedef internal::Types18 type; +}; +template +struct Types { + typedef internal::Types19 type; +}; +template +struct Types { + typedef internal::Types20 type; +}; +template +struct Types { + typedef internal::Types21 type; +}; +template +struct Types { + typedef internal::Types22 type; +}; +template +struct Types { + typedef internal::Types23 type; +}; +template +struct Types { + typedef internal::Types24 type; +}; +template +struct Types { + typedef internal::Types25 type; +}; +template +struct Types { + typedef internal::Types26 type; +}; +template +struct Types { + typedef internal::Types27 type; +}; +template +struct Types { + typedef internal::Types28 type; +}; +template +struct Types { + typedef internal::Types29 type; +}; +template +struct Types { + typedef internal::Types30 type; +}; +template +struct Types { + typedef internal::Types31 type; +}; +template +struct Types { + typedef internal::Types32 type; +}; +template +struct Types { + typedef internal::Types33 type; +}; +template +struct Types { + typedef internal::Types34 type; +}; +template +struct Types { + typedef internal::Types35 type; +}; +template +struct Types { + typedef internal::Types36 type; +}; +template +struct Types { + typedef internal::Types37 type; +}; +template +struct Types { + typedef internal::Types38 type; +}; +template +struct Types { + typedef internal::Types39 type; +}; +template +struct Types { + typedef internal::Types40 type; +}; +template +struct Types { + typedef internal::Types41 type; +}; +template +struct Types { + typedef internal::Types42 type; +}; +template +struct Types { + typedef internal::Types43 type; +}; +template +struct Types { + typedef internal::Types44 type; +}; +template +struct Types { + typedef internal::Types45 type; +}; +template +struct Types { + typedef internal::Types46 type; +}; +template +struct Types { + typedef internal::Types47 type; +}; +template +struct Types { + typedef internal::Types48 type; +}; +template +struct Types { + typedef internal::Types49 type; +}; + +namespace internal { + +# define GTEST_TEMPLATE_ template class + +// The template "selector" struct TemplateSel is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel::Bind::type is defined +// as the type Tmpl. This allows us to actually instantiate the +// template "selected" by TemplateSel. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template +struct TemplateSel { + template + struct Bind { + typedef Tmpl type; + }; +}; + +# define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates, Templates, +// and etc), which C++ doesn't support directly. +template +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template +struct Templates1 { + typedef TemplateSel Head; + typedef Templates0 Tail; +}; +template +struct Templates2 { + typedef TemplateSel Head; + typedef Templates1 Tail; +}; + +template +struct Templates3 { + typedef TemplateSel Head; + typedef Templates2 Tail; +}; + +template +struct Templates4 { + typedef TemplateSel Head; + typedef Templates3 Tail; +}; + +template +struct Templates5 { + typedef TemplateSel Head; + typedef Templates4 Tail; +}; + +template +struct Templates6 { + typedef TemplateSel Head; + typedef Templates5 Tail; +}; + +template +struct Templates7 { + typedef TemplateSel Head; + typedef Templates6 Tail; +}; + +template +struct Templates8 { + typedef TemplateSel Head; + typedef Templates7 Tail; +}; + +template +struct Templates9 { + typedef TemplateSel Head; + typedef Templates8 Tail; +}; + +template +struct Templates10 { + typedef TemplateSel Head; + typedef Templates9 Tail; +}; + +template +struct Templates11 { + typedef TemplateSel Head; + typedef Templates10 Tail; +}; + +template +struct Templates12 { + typedef TemplateSel Head; + typedef Templates11 Tail; +}; + +template +struct Templates13 { + typedef TemplateSel Head; + typedef Templates12 Tail; +}; + +template +struct Templates14 { + typedef TemplateSel Head; + typedef Templates13 Tail; +}; + +template +struct Templates15 { + typedef TemplateSel Head; + typedef Templates14 Tail; +}; + +template +struct Templates16 { + typedef TemplateSel Head; + typedef Templates15 Tail; +}; + +template +struct Templates17 { + typedef TemplateSel Head; + typedef Templates16 Tail; +}; + +template +struct Templates18 { + typedef TemplateSel Head; + typedef Templates17 Tail; +}; + +template +struct Templates19 { + typedef TemplateSel Head; + typedef Templates18 Tail; +}; + +template +struct Templates20 { + typedef TemplateSel Head; + typedef Templates19 Tail; +}; + +template +struct Templates21 { + typedef TemplateSel Head; + typedef Templates20 Tail; +}; + +template +struct Templates22 { + typedef TemplateSel Head; + typedef Templates21 Tail; +}; + +template +struct Templates23 { + typedef TemplateSel Head; + typedef Templates22 Tail; +}; + +template +struct Templates24 { + typedef TemplateSel Head; + typedef Templates23 Tail; +}; + +template +struct Templates25 { + typedef TemplateSel Head; + typedef Templates24 Tail; +}; + +template +struct Templates26 { + typedef TemplateSel Head; + typedef Templates25 Tail; +}; + +template +struct Templates27 { + typedef TemplateSel Head; + typedef Templates26 Tail; +}; + +template +struct Templates28 { + typedef TemplateSel Head; + typedef Templates27 Tail; +}; + +template +struct Templates29 { + typedef TemplateSel Head; + typedef Templates28 Tail; +}; + +template +struct Templates30 { + typedef TemplateSel Head; + typedef Templates29 Tail; +}; + +template +struct Templates31 { + typedef TemplateSel Head; + typedef Templates30 Tail; +}; + +template +struct Templates32 { + typedef TemplateSel Head; + typedef Templates31 Tail; +}; + +template +struct Templates33 { + typedef TemplateSel Head; + typedef Templates32 Tail; +}; + +template +struct Templates34 { + typedef TemplateSel Head; + typedef Templates33 Tail; +}; + +template +struct Templates35 { + typedef TemplateSel Head; + typedef Templates34 Tail; +}; + +template +struct Templates36 { + typedef TemplateSel Head; + typedef Templates35 Tail; +}; + +template +struct Templates37 { + typedef TemplateSel Head; + typedef Templates36 Tail; +}; + +template +struct Templates38 { + typedef TemplateSel Head; + typedef Templates37 Tail; +}; + +template +struct Templates39 { + typedef TemplateSel Head; + typedef Templates38 Tail; +}; + +template +struct Templates40 { + typedef TemplateSel Head; + typedef Templates39 Tail; +}; + +template +struct Templates41 { + typedef TemplateSel Head; + typedef Templates40 Tail; +}; + +template +struct Templates42 { + typedef TemplateSel Head; + typedef Templates41 Tail; +}; + +template +struct Templates43 { + typedef TemplateSel Head; + typedef Templates42 Tail; +}; + +template +struct Templates44 { + typedef TemplateSel Head; + typedef Templates43 Tail; +}; + +template +struct Templates45 { + typedef TemplateSel Head; + typedef Templates44 Tail; +}; + +template +struct Templates46 { + typedef TemplateSel Head; + typedef Templates45 Tail; +}; + +template +struct Templates47 { + typedef TemplateSel Head; + typedef Templates46 Tail; +}; + +template +struct Templates48 { + typedef TemplateSel Head; + typedef Templates47 Tail; +}; + +template +struct Templates49 { + typedef TemplateSel Head; + typedef Templates48 Tail; +}; + +template +struct Templates50 { + typedef TemplateSel Head; + typedef Templates49 Tail; +}; + + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates +// will appear as Templates in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates, and Google Test will translate +// that to TemplatesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. +template +struct Templates { + typedef Templates50 type; +}; + +template <> +struct Templates { + typedef Templates0 type; +}; +template +struct Templates { + typedef Templates1 type; +}; +template +struct Templates { + typedef Templates2 type; +}; +template +struct Templates { + typedef Templates3 type; +}; +template +struct Templates { + typedef Templates4 type; +}; +template +struct Templates { + typedef Templates5 type; +}; +template +struct Templates { + typedef Templates6 type; +}; +template +struct Templates { + typedef Templates7 type; +}; +template +struct Templates { + typedef Templates8 type; +}; +template +struct Templates { + typedef Templates9 type; +}; +template +struct Templates { + typedef Templates10 type; +}; +template +struct Templates { + typedef Templates11 type; +}; +template +struct Templates { + typedef Templates12 type; +}; +template +struct Templates { + typedef Templates13 type; +}; +template +struct Templates { + typedef Templates14 type; +}; +template +struct Templates { + typedef Templates15 type; +}; +template +struct Templates { + typedef Templates16 type; +}; +template +struct Templates { + typedef Templates17 type; +}; +template +struct Templates { + typedef Templates18 type; +}; +template +struct Templates { + typedef Templates19 type; +}; +template +struct Templates { + typedef Templates20 type; +}; +template +struct Templates { + typedef Templates21 type; +}; +template +struct Templates { + typedef Templates22 type; +}; +template +struct Templates { + typedef Templates23 type; +}; +template +struct Templates { + typedef Templates24 type; +}; +template +struct Templates { + typedef Templates25 type; +}; +template +struct Templates { + typedef Templates26 type; +}; +template +struct Templates { + typedef Templates27 type; +}; +template +struct Templates { + typedef Templates28 type; +}; +template +struct Templates { + typedef Templates29 type; +}; +template +struct Templates { + typedef Templates30 type; +}; +template +struct Templates { + typedef Templates31 type; +}; +template +struct Templates { + typedef Templates32 type; +}; +template +struct Templates { + typedef Templates33 type; +}; +template +struct Templates { + typedef Templates34 type; +}; +template +struct Templates { + typedef Templates35 type; +}; +template +struct Templates { + typedef Templates36 type; +}; +template +struct Templates { + typedef Templates37 type; +}; +template +struct Templates { + typedef Templates38 type; +}; +template +struct Templates { + typedef Templates39 type; +}; +template +struct Templates { + typedef Templates40 type; +}; +template +struct Templates { + typedef Templates41 type; +}; +template +struct Templates { + typedef Templates42 type; +}; +template +struct Templates { + typedef Templates43 type; +}; +template +struct Templates { + typedef Templates44 type; +}; +template +struct Templates { + typedef Templates45 type; +}; +template +struct Templates { + typedef Templates46 type; +}; +template +struct Templates { + typedef Templates47 type; +}; +template +struct Templates { + typedef Templates48 type; +}; +template +struct Templates { + typedef Templates49 type; +}; + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template +struct TypeList { + typedef Types1 type; +}; + +template +struct TypeList > { + typedef typename Types::type type; +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__. Writing +// +// foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number. For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar + +// Google Test defines the testing::Message class to allow construction of +// test messages via the << operator. The idea is that anything +// streamable to std::ostream can be streamed to a testing::Message. +// This allows a user to use his own types in Google Test assertions by +// overloading the << operator. +// +// util/gtl/stl_logging.h overloads << for STL containers. These +// overloads cannot be defined in the std namespace, as that will be +// undefined behavior. Therefore, they are defined in the global +// namespace instead. +// +// C++'s symbol lookup rule (i.e. Koenig lookup) says that these +// overloads are visible in either the std namespace or the global +// namespace, but not other namespaces, including the testing +// namespace which Google Test's Message class is in. +// +// To allow STL containers (and other types that has a << operator +// defined in the global namespace) to be used in Google Test assertions, +// testing::Message must access the custom << operator from the global +// namespace. Hence this helper function. +// +// Note: Jeffrey Yasskin suggested an alternative fix by "using +// ::operator<<;" in the definition of Message's operator<<. That fix +// doesn't require a helper function, but unfortunately doesn't +// compile with MSVC. +template +inline void GTestStreamToHelper(std::ostream* os, const T& val) { + *os << val; +} + +class ProtocolMessage; +namespace proto2 { class Message; } + +namespace testing { + +// Forward declarations. + +class AssertionResult; // Result of an assertion. +class Message; // Represents a failure message. +class Test; // Represents a test. +class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. +class UnitTest; // A collection of test cases. + +template +::std::string PrintToString(const T& value); + +namespace internal { + +struct TraceInfo; // Information about a trace point. +class ScopedTrace; // Implements scoped trace. +class TestInfoImpl; // Opaque implementation of TestInfo +class UnitTestImpl; // Opaque implementation of UnitTest + +// How many times InitGoogleTest() has been called. +GTEST_API_ extern int g_init_gtest_count; + +// The text used in failure messages to indicate the start of the +// stack trace. +GTEST_API_ extern const char kStackTraceMarker[]; + +// A secret type that Google Test users don't know about. It has no +// definition on purpose. Therefore it's impossible to create a +// Secret object, which is what we want. +class Secret; + +// Two overloaded helpers for checking at compile time whether an +// expression is a null pointer literal (i.e. NULL or any 0-valued +// compile-time integral constant). Their return values have +// different sizes, so we can use sizeof() to test which version is +// picked by the compiler. These helpers have no implementations, as +// we only need their signatures. +// +// Given IsNullLiteralHelper(x), the compiler will pick the first +// version if x can be implicitly converted to Secret*, and pick the +// second version otherwise. Since Secret is a secret and incomplete +// type, the only expression a user can write that has type Secret* is +// a null pointer literal. Therefore, we know that x is a null +// pointer literal if and only if the first version is picked by the +// compiler. +char IsNullLiteralHelper(Secret* p); +char (&IsNullLiteralHelper(...))[2]; // NOLINT + +// A compile-time bool constant that is true if and only if x is a +// null pointer literal (i.e. NULL or any 0-valued compile-time +// integral constant). +#ifdef GTEST_ELLIPSIS_NEEDS_POD_ +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +# define GTEST_IS_NULL_LITERAL_(x) false +#else +# define GTEST_IS_NULL_LITERAL_(x) \ + (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) +#endif // GTEST_ELLIPSIS_NEEDS_POD_ + +// Appends the user-supplied message to the Google-Test-generated message. +GTEST_API_ std::string AppendUserMessage( + const std::string& gtest_msg, const Message& user_msg); + +// A helper class for creating scoped traces in user programs. +class GTEST_API_ ScopedTrace { + public: + // The c'tor pushes the given source file location and message onto + // a trace stack maintained by Google Test. + ScopedTrace(const char* file, int line, const Message& message); + + // The d'tor pops the info pushed by the c'tor. + // + // Note that the d'tor is not virtual in order to be efficient. + // Don't inherit from ScopedTrace! + ~ScopedTrace(); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); +} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its + // c'tor and d'tor. Therefore it doesn't + // need to be used otherwise. + +// Converts a streamable value to an std::string. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +std::string StreamableToString(const T& streamable); + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +GTEST_API_ AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case); + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +GTEST_API_ std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value); + +// This template class represents an IEEE floating-point number +// (either single-precision or double-precision, depending on the +// template parameters). +// +// The purpose of this class is to do more sophisticated number +// comparison. (Due to round-off error, etc, it's very unlikely that +// two floating-points will be equal exactly. Hence a naive +// comparison by the == operation often doesn't work.) +// +// Format of IEEE floating-point: +// +// The most-significant bit being the leftmost, an IEEE +// floating-point looks like +// +// sign_bit exponent_bits fraction_bits +// +// Here, sign_bit is a single bit that designates the sign of the +// number. +// +// For float, there are 8 exponent bits and 23 fraction bits. +// +// For double, there are 11 exponent bits and 52 fraction bits. +// +// More details can be found at +// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +template +class FloatingPoint { + public: + // Defines the unsigned integer type that has the same size as the + // floating point number. + typedef typename TypeWithSize::UInt Bits; + + // Constants. + + // # of bits in a number. + static const size_t kBitCount = 8*sizeof(RawType); + + // # of fraction bits in a number. + static const size_t kFractionBitCount = + std::numeric_limits::digits - 1; + + // # of exponent bits in a number. + static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; + + // The mask for the sign bit. + static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); + + // The mask for the fraction bits. + static const Bits kFractionBitMask = + ~static_cast(0) >> (kExponentBitCount + 1); + + // The mask for the exponent bits. + static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); + + // How many ULP's (Units in the Last Place) we want to tolerate when + // comparing two numbers. The larger the value, the more error we + // allow. A 0 value means that two numbers must be exactly the same + // to be considered equal. + // + // The maximum error of a single floating-point operation is 0.5 + // units in the last place. On Intel CPU's, all floating-point + // calculations are done with 80-bit precision, while double has 64 + // bits. Therefore, 4 should be enough for ordinary use. + // + // See the following article for more details on ULP: + // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm. + static const size_t kMaxUlps = 4; + + // Constructs a FloatingPoint from a raw floating-point number. + // + // On an Intel CPU, passing a non-normalized NAN (Not a Number) + // around may change its bits, although the new value is guaranteed + // to be also a NAN. Therefore, don't expect this constructor to + // preserve the bits in x when x is a NAN. + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } + + // Static methods + + // Reinterprets a bit pattern as a floating-point number. + // + // This function is needed to test the AlmostEquals() method. + static RawType ReinterpretBits(const Bits bits) { + FloatingPoint fp(0); + fp.u_.bits_ = bits; + return fp.u_.value_; + } + + // Returns the floating-point number that represent positive infinity. + static RawType Infinity() { + return ReinterpretBits(kExponentBitMask); + } + + // Non-static methods + + // Returns the bits that represents this number. + const Bits &bits() const { return u_.bits_; } + + // Returns the exponent bits of this number. + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } + + // Returns the fraction bits of this number. + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } + + // Returns the sign bit of this number. + Bits sign_bit() const { return kSignBitMask & u_.bits_; } + + // Returns true iff this is NAN (not a number). + bool is_nan() const { + // It's a NAN if the exponent bits are all ones and the fraction + // bits are not entirely zeros. + return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); + } + + // Returns true iff this number is at most kMaxUlps ULP's away from + // rhs. In particular, this function: + // + // - returns false if either number is (or both are) NAN. + // - treats really large numbers as almost equal to infinity. + // - thinks +0.0 and -0.0 are 0 DLP's apart. + bool AlmostEquals(const FloatingPoint& rhs) const { + // The IEEE standard says that any comparison operation involving + // a NAN must return false. + if (is_nan() || rhs.is_nan()) return false; + + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) + <= kMaxUlps; + } + + private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; + + // Converts an integer from the sign-and-magnitude representation to + // the biased representation. More precisely, let N be 2 to the + // power of (kBitCount - 1), an integer x is represented by the + // unsigned number x + N. + // + // For instance, + // + // -N + 1 (the most negative number representable using + // sign-and-magnitude) is represented by 1; + // 0 is represented by N; and + // N - 1 (the biggest number representable using + // sign-and-magnitude) is represented by 2N - 1. + // + // Read http://en.wikipedia.org/wiki/Signed_number_representations + // for more details on signed number representations. + static Bits SignAndMagnitudeToBiased(const Bits &sam) { + if (kSignBitMask & sam) { + // sam represents a negative number. + return ~sam + 1; + } else { + // sam represents a positive number. + return kSignBitMask | sam; + } + } + + // Given two numbers in the sign-and-magnitude representation, + // returns the distance between them as an unsigned number. + static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, + const Bits &sam2) { + const Bits biased1 = SignAndMagnitudeToBiased(sam1); + const Bits biased2 = SignAndMagnitudeToBiased(sam2); + return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); + } + + FloatingPointUnion u_; +}; + +// Typedefs the instances of the FloatingPoint template class that we +// care to use. +typedef FloatingPoint Float; +typedef FloatingPoint Double; + +// In order to catch the mistake of putting tests that use different +// test fixture classes in the same test case, we need to assign +// unique IDs to fixture classes and compare them. The TypeId type is +// used to hold such IDs. The user should treat TypeId as an opaque +// type: the only operation allowed on TypeId values is to compare +// them for equality using the == operator. +typedef const void* TypeId; + +template +class TypeIdHelper { + public: + // dummy_ must not have a const type. Otherwise an overly eager + // compiler (e.g. MSVC 7.1 & 8.0) may try to merge + // TypeIdHelper::dummy_ for different Ts as an "optimization". + static bool dummy_; +}; + +template +bool TypeIdHelper::dummy_ = false; + +// GetTypeId() returns the ID of type T. Different values will be +// returned for different types. Calling the function twice with the +// same type argument is guaranteed to return the same ID. +template +TypeId GetTypeId() { + // The compiler is required to allocate a different + // TypeIdHelper::dummy_ variable for each T used to instantiate + // the template. Therefore, the address of dummy_ is guaranteed to + // be unique. + return &(TypeIdHelper::dummy_); +} + +// Returns the type ID of ::testing::Test. Always call this instead +// of GetTypeId< ::testing::Test>() to get the type ID of +// ::testing::Test, as the latter may give the wrong result due to a +// suspected linker bug when compiling Google Test as a Mac OS X +// framework. +GTEST_API_ TypeId GetTestTypeId(); + +// Defines the abstract factory interface that creates instances +// of a Test object. +class TestFactoryBase { + public: + virtual ~TestFactoryBase() {} + + // Creates a test instance to run. The instance is both created and destroyed + // within TestInfoImpl::Run() + virtual Test* CreateTest() = 0; + + protected: + TestFactoryBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); +}; + +// This class provides implementation of TeastFactoryBase interface. +// It is used in TEST and TEST_F macros. +template +class TestFactoryImpl : public TestFactoryBase { + public: + virtual Test* CreateTest() { return new TestClass; } +}; + +#if GTEST_OS_WINDOWS + +// Predicate-formatters for implementing the HRESULT checking macros +// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} +// We pass a long instead of HRESULT to avoid causing an +// include dependency for the HRESULT type. +GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, + long hr); // NOLINT +GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, + long hr); // NOLINT + +#endif // GTEST_OS_WINDOWS + +// Types of SetUpTestCase() and TearDownTestCase() functions. +typedef void (*SetUpTestCaseFunc)(); +typedef void (*TearDownTestCaseFunc)(); + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param text representation of the test's value parameter, +// or NULL if this is not a type-parameterized test. +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +GTEST_API_ TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory); + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// State of the definition of a type-parameterized test case. +class GTEST_API_ TypedTestCasePState { + public: + TypedTestCasePState() : registered_(false) {} + + // Adds the given test name to defined_test_names_ and return true + // if the test case hasn't been registered; otherwise aborts the + // program. + bool AddTestName(const char* file, int line, const char* case_name, + const char* test_name) { + if (registered_) { + fprintf(stderr, "%s Test %s must be defined before " + "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", + FormatFileLocation(file, line).c_str(), test_name, case_name); + fflush(stderr); + posix::Abort(); + } + defined_test_names_.insert(test_name); + return true; + } + + // Verifies that registered_tests match the test names in + // defined_test_names_; returns registered_tests if successful, or + // aborts the program otherwise. + const char* VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests); + + private: + bool registered_; + ::std::set defined_test_names_; +}; + +// Skips to the first non-space char after the first comma in 'str'; +// returns NULL if no comma is found in 'str'. +inline const char* SkipComma(const char* str) { + const char* comma = strchr(str, ','); + if (comma == NULL) { + return NULL; + } + while (IsSpace(*(++comma))) {} + return comma; +} + +// Returns the prefix of 'str' before the first comma in it; returns +// the entire string if it contains no comma. +inline std::string GetPrefixUntilComma(const char* str) { + const char* comma = strchr(str, ','); + return comma == NULL ? str : std::string(str, comma); +} + +// TypeParameterizedTest::Register() +// registers a list of type-parameterized tests with Google Test. The +// return value is insignificant - we just need to return something +// such that we can call this function in a namespace scope. +// +// Implementation note: The GTEST_TEMPLATE_ macro declares a template +// template parameter. It's defined in gtest-type-util.h. +template +class TypeParameterizedTest { + public: + // 'index' is the index of the test in the type list 'Types' + // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, + // Types). Valid values for 'index' are [0, N - 1] where N is the + // length of Types. + static bool Register(const char* prefix, const char* case_name, + const char* test_names, int index) { + typedef typename Types::Head Type; + typedef Fixture FixtureClass; + typedef typename GTEST_BIND_(TestSel, Type) TestClass; + + // First, registers the first type-parameterized test in the type + // list. + MakeAndRegisterTestInfo( + String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/", + case_name, index).c_str(), + GetPrefixUntilComma(test_names).c_str(), + GetTypeName().c_str(), + NULL, // No value parameter. + GetTypeId(), + TestClass::SetUpTestCase, + TestClass::TearDownTestCase, + new TestFactoryImpl); + + // Next, recurses (at compile time) with the tail of the type list. + return TypeParameterizedTest + ::Register(prefix, case_name, test_names, index + 1); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTest { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/, int /*index*/) { + return true; + } +}; + +// TypeParameterizedTestCase::Register() +// registers *all combinations* of 'Tests' and 'Types' with Google +// Test. The return value is insignificant - we just need to return +// something such that we can call this function in a namespace scope. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* prefix, const char* case_name, + const char* test_names) { + typedef typename Tests::Head Head; + + // First, register the first test in 'Test' for each type in 'Types'. + TypeParameterizedTest::Register( + prefix, case_name, test_names, 0); + + // Next, recurses (at compile time) with the tail of the test list. + return TypeParameterizedTestCase + ::Register(prefix, case_name, SkipComma(test_names)); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/) { + return true; + } +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( + UnitTest* unit_test, int skip_count); + +// Helpers for suppressing warnings on unreachable code or constant +// condition. + +// Always returns true. +GTEST_API_ bool AlwaysTrue(); + +// Always returns false. +inline bool AlwaysFalse() { return !AlwaysTrue(); } + +// Helper for suppressing false warning from Clang on a const char* +// variable declared in a conditional expression always being NULL in +// the else branch. +struct GTEST_API_ ConstCharPtr { + ConstCharPtr(const char* str) : value(str) {} + operator bool() const { return true; } + const char* value; +}; + +// A simple Linear Congruential Generator for generating random +// numbers with a uniform distribution. Unlike rand() and srand(), it +// doesn't use global state (and therefore can't interfere with user +// code). Unlike rand_r(), it's portable. An LCG isn't very random, +// but it's good enough for our purposes. +class GTEST_API_ Random { + public: + static const UInt32 kMaxRange = 1u << 31; + + explicit Random(UInt32 seed) : state_(seed) {} + + void Reseed(UInt32 seed) { state_ = seed; } + + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); + + private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +}; + +// Defining a variable of type CompileAssertTypesEqual will cause a +// compiler error iff T1 and T2 are different types. +template +struct CompileAssertTypesEqual; + +template +struct CompileAssertTypesEqual { +}; + +// Removes the reference from a type if it is a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::remove_reference, which is not widely available yet. +template +struct RemoveReference { typedef T type; }; // NOLINT +template +struct RemoveReference { typedef T type; }; // NOLINT + +// A handy wrapper around RemoveReference that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_REFERENCE_(T) \ + typename ::testing::internal::RemoveReference::type + +// Removes const from a type if it is a const type, otherwise leaves +// it unchanged. This is the same as tr1::remove_const, which is not +// widely available yet. +template +struct RemoveConst { typedef T type; }; // NOLINT +template +struct RemoveConst { typedef T type; }; // NOLINT + +// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above +// definition to fail to remove the const in 'const int[3]' and 'const +// char[3][4]'. The following specialization works around the bug. +template +struct RemoveConst { + typedef typename RemoveConst::type type[N]; +}; + +#if defined(_MSC_VER) && _MSC_VER < 1400 +// This is the only specialization that allows VC++ 7.1 to remove const in +// 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC +// and thus needs to be conditionally compiled. +template +struct RemoveConst { + typedef typename RemoveConst::type type[N]; +}; +#endif + +// A handy wrapper around RemoveConst that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_CONST_(T) \ + typename ::testing::internal::RemoveConst::type + +// Turns const U&, U&, const U, and U all into U. +#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ + GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) + +// Adds reference to a type if it is not a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::add_reference, which is not widely available yet. +template +struct AddReference { typedef T& type; }; // NOLINT +template +struct AddReference { typedef T& type; }; // NOLINT + +// A handy wrapper around AddReference that works when the argument T +// depends on template parameters. +#define GTEST_ADD_REFERENCE_(T) \ + typename ::testing::internal::AddReference::type + +// Adds a reference to const on top of T as necessary. For example, +// it transforms +// +// char ==> const char& +// const char ==> const char& +// char& ==> const char& +// const char& ==> const char& +// +// The argument T must depend on some template parameters. +#define GTEST_REFERENCE_TO_CONST_(T) \ + GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) + +// ImplicitlyConvertible::value is a compile-time bool +// constant that's true iff type From can be implicitly converted to +// type To. +template +class ImplicitlyConvertible { + private: + // We need the following helper functions only for their types. + // They have no implementations. + + // MakeFrom() is an expression whose type is From. We cannot simply + // use From(), as the type From may not have a public default + // constructor. + static From MakeFrom(); + + // These two functions are overloaded. Given an expression + // Helper(x), the compiler will pick the first version if x can be + // implicitly converted to type To; otherwise it will pick the + // second version. + // + // The first version returns a value of size 1, and the second + // version returns a value of size 2. Therefore, by checking the + // size of Helper(x), which can be done at compile time, we can tell + // which version of Helper() is used, and hence whether x can be + // implicitly converted to type To. + static char Helper(To); + static char (&Helper(...))[2]; // NOLINT + + // We have to put the 'public' section after the 'private' section, + // or MSVC refuses to compile the code. + public: + // MSVC warns about implicitly converting from double to int for + // possible loss of data, so we need to temporarily disable the + // warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4244) // Temporarily disables warning 4244. + + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; +# pragma warning(pop) // Restores the warning state. +#elif defined(__BORLANDC__) + // C++Builder cannot use member overload resolution during template + // instantiation. The simplest workaround is to use its C++0x type traits + // functions (C++Builder 2009 and above only). + static const bool value = __is_convertible(From, To); +#else + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; +#endif // _MSV_VER +}; +template +const bool ImplicitlyConvertible::value; + +// IsAProtocolMessage::value is a compile-time bool constant that's +// true iff T is type ProtocolMessage, proto2::Message, or a subclass +// of those. +template +struct IsAProtocolMessage + : public bool_constant< + ImplicitlyConvertible::value || + ImplicitlyConvertible::value> { +}; + +// When the compiler sees expression IsContainerTest(0), if C is an +// STL-style container class, the first overload of IsContainerTest +// will be viable (since both C::iterator* and C::const_iterator* are +// valid types and NULL can be implicitly converted to them). It will +// be picked over the second overload as 'int' is a perfect match for +// the type of argument 0. If C::iterator or C::const_iterator is not +// a valid type, the first overload is not viable, and the second +// overload will be picked. Therefore, we can determine whether C is +// a container class by checking the type of IsContainerTest(0). +// The value of the expression is insignificant. +// +// Note that we look for both C::iterator and C::const_iterator. The +// reason is that C++ injects the name of a class as a member of the +// class itself (e.g. you can refer to class iterator as either +// 'iterator' or 'iterator::iterator'). If we look for C::iterator +// only, for example, we would mistakenly think that a class named +// iterator is an STL container. +// +// Also note that the simpler approach of overloading +// IsContainerTest(typename C::const_iterator*) and +// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. +typedef int IsContainer; +template +IsContainer IsContainerTest(int /* dummy */, + typename C::iterator* /* it */ = NULL, + typename C::const_iterator* /* const_it */ = NULL) { + return 0; +} + +typedef char IsNotContainer; +template +IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } + +// EnableIf::type is void when 'Cond' is true, and +// undefined when 'Cond' is false. To use SFINAE to make a function +// overload only apply when a particular expression is true, add +// "typename EnableIf::type* = 0" as the last parameter. +template struct EnableIf; +template<> struct EnableIf { typedef void type; }; // NOLINT + +// Utilities for native arrays. + +// ArrayEq() compares two k-dimensional native arrays using the +// elements' operator==, where k can be any integer >= 0. When k is +// 0, ArrayEq() degenerates into comparing a single pair of values. + +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs); + +// This generic version is used when k is 0. +template +inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } + +// This overload is used when k >= 1. +template +inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { + return internal::ArrayEq(lhs, N, rhs); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous ArrayEq() function, arrays with different sizes would +// lead to different copies of the template code. +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs) { + for (size_t i = 0; i != size; i++) { + if (!internal::ArrayEq(lhs[i], rhs[i])) + return false; + } + return true; +} + +// Finds the first element in the iterator range [begin, end) that +// equals elem. Element may be a native array type itself. +template +Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { + for (Iter it = begin; it != end; ++it) { + if (internal::ArrayEq(*it, elem)) + return it; + } + return end; +} + +// CopyArray() copies a k-dimensional native array using the elements' +// operator=, where k can be any integer >= 0. When k is 0, +// CopyArray() degenerates into copying a single value. + +template +void CopyArray(const T* from, size_t size, U* to); + +// This generic version is used when k is 0. +template +inline void CopyArray(const T& from, U* to) { *to = from; } + +// This overload is used when k >= 1. +template +inline void CopyArray(const T(&from)[N], U(*to)[N]) { + internal::CopyArray(from, N, *to); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous CopyArray() function, arrays with different sizes +// would lead to different copies of the template code. +template +void CopyArray(const T* from, size_t size, U* to) { + for (size_t i = 0; i != size; i++) { + internal::CopyArray(from[i], to + i); + } +} + +// The relation between an NativeArray object (see below) and the +// native array it represents. +enum RelationToSource { + kReference, // The NativeArray references the native array. + kCopy // The NativeArray makes a copy of the native array and + // owns the copy. +}; + +// Adapts a native array to a read-only STL-style container. Instead +// of the complete STL container concept, this adaptor only implements +// members useful for Google Mock's container matchers. New members +// should be added as needed. To simplify the implementation, we only +// support Element being a raw type (i.e. having no top-level const or +// reference modifier). It's the client's responsibility to satisfy +// this requirement. Element can be an array type itself (hence +// multi-dimensional arrays are supported). +template +class NativeArray { + public: + // STL-style container typedefs. + typedef Element value_type; + typedef Element* iterator; + typedef const Element* const_iterator; + + // Constructs from a native array. + NativeArray(const Element* array, size_t count, RelationToSource relation) { + Init(array, count, relation); + } + + // Copy constructor. + NativeArray(const NativeArray& rhs) { + Init(rhs.array_, rhs.size_, rhs.relation_to_source_); + } + + ~NativeArray() { + // Ensures that the user doesn't instantiate NativeArray with a + // const or reference type. + static_cast(StaticAssertTypeEqHelper()); + if (relation_to_source_ == kCopy) + delete[] array_; + } + + // STL-style container methods. + size_t size() const { return size_; } + const_iterator begin() const { return array_; } + const_iterator end() const { return array_ + size_; } + bool operator==(const NativeArray& rhs) const { + return size() == rhs.size() && + ArrayEq(begin(), size(), rhs.begin()); + } + + private: + // Initializes this object; makes a copy of the input array if + // 'relation' is kCopy. + void Init(const Element* array, size_t a_size, RelationToSource relation) { + if (relation == kReference) { + array_ = array; + } else { + Element* const copy = new Element[a_size]; + CopyArray(array, a_size, copy); + array_ = copy; + } + size_ = a_size; + relation_to_source_ = relation; + } + + const Element* array_; + size_t size_; + RelationToSource relation_to_source_; + + GTEST_DISALLOW_ASSIGN_(NativeArray); +}; + +} // namespace internal +} // namespace testing + +#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ + ::testing::internal::AssertHelper(result_type, file, line, message) \ + = ::testing::Message() + +#define GTEST_MESSAGE_(message, result_type) \ + GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) + +#define GTEST_FATAL_FAILURE_(message) \ + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) + +#define GTEST_NONFATAL_FAILURE_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) + +#define GTEST_SUCCESS_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) + +// Suppresses MSVC warnings 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } + +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::ConstCharPtr gtest_msg = "") { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const&) { \ + gtest_caught_expected = true; \ + } \ + catch (...) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws a different type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ + fail(gtest_msg.value) + +#define GTEST_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ + fail("Expected: " #statement " doesn't throw an exception.\n" \ + " Actual: it throws.") + +#define GTEST_TEST_ANY_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + bool gtest_caught_any = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_caught_any = true; \ + } \ + if (!gtest_caught_any) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ + fail("Expected: " #statement " throws an exception.\n" \ + " Actual: it doesn't.") + + +// Implements Boolean test assertions such as EXPECT_TRUE. expression can be +// either a boolean expression or an AssertionResult. text is a textual +// represenation of expression as it was passed into the EXPECT_TRUE. +#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ + ; \ + else \ + fail(::testing::internal::GetBoolAssertionFailureMessage(\ + gtest_ar_, text, #actual, #expected).c_str()) + +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ + fail("Expected: " #statement " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does.") + +// Expands to the name of the class that implements the given test. +#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + test_case_name##_##test_name##_Test + +// Helper macro for defining tests. +#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ +class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ + public:\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ + private:\ + virtual void TestBody();\ + static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ +};\ +\ +::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ + ::test_info_ =\ + ::testing::internal::MakeAndRegisterTestInfo(\ + #test_case_name, #test_name, NULL, NULL, \ + (parent_id), \ + parent_class::SetUpTestCase, \ + parent_class::TearDownTestCase, \ + new ::testing::internal::TestFactoryImpl<\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ +void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for death tests. It is +// #included by gtest.h so a user doesn't need to include this +// directly. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines internal utilities needed for implementing +// death tests. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + + +#include + +namespace testing { +namespace internal { + +GTEST_DECLARE_string_(internal_run_death_test); + +// Names of the flags (needed for parsing Google Test flags). +const char kDeathTestStyleFlag[] = "death_test_style"; +const char kDeathTestUseFork[] = "death_test_use_fork"; +const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; + +#if GTEST_HAS_DEATH_TEST + +// DeathTest is a class that hides much of the complexity of the +// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method +// returns a concrete class that depends on the prevailing death test +// style, as defined by the --gtest_death_test_style and/or +// --gtest_internal_run_death_test flags. + +// In describing the results of death tests, these terms are used with +// the corresponding definitions: +// +// exit status: The integer exit information in the format specified +// by wait(2) +// exit code: The integer code passed to exit(3), _exit(2), or +// returned from main() +class GTEST_API_ DeathTest { + public: + // Create returns false if there was an error determining the + // appropriate action to take for the current death test; for example, + // if the gtest_death_test_style flag is set to an invalid value. + // The LastMessage method will return a more detailed message in that + // case. Otherwise, the DeathTest pointer pointed to by the "test" + // argument is set. If the death test should be skipped, the pointer + // is set to NULL; otherwise, it is set to the address of a new concrete + // DeathTest object that controls the execution of the current test. + static bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); + DeathTest(); + virtual ~DeathTest() { } + + // A helper class that aborts a death test when it's deleted. + class ReturnSentinel { + public: + explicit ReturnSentinel(DeathTest* test) : test_(test) { } + ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } + private: + DeathTest* const test_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); + } GTEST_ATTRIBUTE_UNUSED_; + + // An enumeration of possible roles that may be taken when a death + // test is encountered. EXECUTE means that the death test logic should + // be executed immediately. OVERSEE means that the program should prepare + // the appropriate environment for a child process to execute the death + // test, then wait for it to complete. + enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; + + // An enumeration of the three reasons that a test might be aborted. + enum AbortReason { + TEST_ENCOUNTERED_RETURN_STATEMENT, + TEST_THREW_EXCEPTION, + TEST_DID_NOT_DIE + }; + + // Assumes one of the above roles. + virtual TestRole AssumeRole() = 0; + + // Waits for the death test to finish and returns its status. + virtual int Wait() = 0; + + // Returns true if the death test passed; that is, the test process + // exited during the test, its exit status matches a user-supplied + // predicate, and its stderr output matches a user-supplied regular + // expression. + // The user-supplied predicate may be a macro expression rather + // than a function pointer or functor, or else Wait and Passed could + // be combined. + virtual bool Passed(bool exit_status_ok) = 0; + + // Signals that the death test did not die as expected. + virtual void Abort(AbortReason reason) = 0; + + // Returns a human-readable outcome message regarding the outcome of + // the last death test. + static const char* LastMessage(); + + static void set_last_death_test_message(const std::string& message); + + private: + // A string containing a description of the outcome of the last death test. + static std::string last_death_test_message_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); +}; + +// Factory interface for death tests. May be mocked out for testing. +class DeathTestFactory { + public: + virtual ~DeathTestFactory() { } + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) = 0; +}; + +// A concrete DeathTestFactory implementation for normal use. +class DefaultDeathTestFactory : public DeathTestFactory { + public: + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); +}; + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +GTEST_API_ bool ExitedUnsuccessfully(int exit_status); + +// Traps C++ exceptions escaping statement and reports them as test +// failures. Note that trapping SEH exceptions is not implemented here. +# if GTEST_HAS_EXCEPTIONS +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (const ::std::exception& gtest_exception) { \ + fprintf(\ + stderr, \ + "\n%s: Caught std::exception-derived exception escaping the " \ + "death test statement. Exception message: %s\n", \ + ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ + gtest_exception.what()); \ + fflush(stderr); \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } catch (...) { \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } + +# else +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) + +# endif + +// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, +// ASSERT_EXIT*, and EXPECT_EXIT*. +# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + const ::testing::internal::RE& gtest_regex = (regex); \ + ::testing::internal::DeathTest* gtest_dt; \ + if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ + __FILE__, __LINE__, >est_dt)) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + if (gtest_dt != NULL) { \ + ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ + gtest_dt_ptr(gtest_dt); \ + switch (gtest_dt->AssumeRole()) { \ + case ::testing::internal::DeathTest::OVERSEE_TEST: \ + if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + break; \ + case ::testing::internal::DeathTest::EXECUTE_TEST: { \ + ::testing::internal::DeathTest::ReturnSentinel \ + gtest_sentinel(gtest_dt); \ + GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ + gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ + break; \ + } \ + default: \ + break; \ + } \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ + fail(::testing::internal::DeathTest::LastMessage()) +// The symbol "fail" here expands to something into which a message +// can be streamed. + +// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in +// NDEBUG mode. In this case we need the statements to be executed, the regex is +// ignored, and the macro must accept a streamed message even though the message +// is never printed. +# define GTEST_EXECUTE_STATEMENT_(statement, regex) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } else \ + ::testing::Message() + +// A class representing the parsed contents of the +// --gtest_internal_run_death_test flag, as it existed when +// RUN_ALL_TESTS was called. +class InternalRunDeathTestFlag { + public: + InternalRunDeathTestFlag(const std::string& a_file, + int a_line, + int an_index, + int a_write_fd) + : file_(a_file), line_(a_line), index_(an_index), + write_fd_(a_write_fd) {} + + ~InternalRunDeathTestFlag() { + if (write_fd_ >= 0) + posix::Close(write_fd_); + } + + const std::string& file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int write_fd() const { return write_fd_; } + + private: + std::string file_; + int line_; + int index_; + int write_fd_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); +}; + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); + +#else // GTEST_HAS_DEATH_TEST + +// This macro is used for implementing macros such as +// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where +// death tests are not supported. Those macros must compile on such systems +// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on +// systems that support death tests. This allows one to write such a macro +// on a system that does not support death tests and be sure that it will +// compile on a death-test supporting system. +// +// Parameters: +// statement - A statement that a macro such as EXPECT_DEATH would test +// for program termination. This macro has to make sure this +// statement is compiled but not executed, to ensure that +// EXPECT_DEATH_IF_SUPPORTED compiles with a certain +// parameter iff EXPECT_DEATH compiles with it. +// regex - A regex that a macro such as EXPECT_DEATH would use to test +// the output of statement. This parameter has to be +// compiled but not evaluated by this macro, to ensure that +// this macro only accepts expressions that a macro such as +// EXPECT_DEATH would accept. +// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED +// and a return statement for ASSERT_DEATH_IF_SUPPORTED. +// This ensures that ASSERT_DEATH_IF_SUPPORTED will not +// compile inside functions where ASSERT_DEATH doesn't +// compile. +// +// The branch that has an always false condition is used to ensure that +// statement and regex are compiled (and thus syntactically correct) but +// never executed. The unreachable code macro protects the terminator +// statement from generating an 'unreachable code' warning in case +// statement unconditionally returns or throws. The Message constructor at +// the end allows the syntax of streaming additional messages into the +// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. +# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + +namespace testing { + +// This flag controls the style of death tests. Valid values are "threadsafe", +// meaning that the death test child process will re-execute the test binary +// from the start, running only a single death test, or "fast", +// meaning that the child process will execute the test logic immediately +// after forking. +GTEST_DECLARE_string_(death_test_style); + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +GTEST_API_ bool InDeathTestChild(); + +} // namespace internal + +// The following macros are useful for writing death tests. + +// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is +// executed: +// +// 1. It generates a warning if there is more than one active +// thread. This is because it's safe to fork() or clone() only +// when there is a single thread. +// +// 2. The parent process clone()s a sub-process and runs the death +// test in it; the sub-process exits with code 0 at the end of the +// death test, if it hasn't exited already. +// +// 3. The parent process waits for the sub-process to terminate. +// +// 4. The parent process checks the exit code and error message of +// the sub-process. +// +// Examples: +// +// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); +// for (int i = 0; i < 5; i++) { +// EXPECT_DEATH(server.ProcessRequest(i), +// "Invalid request .* in ProcessRequest()") +// << "Failed to die on request " << i; +// } +// +// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); +// +// bool KilledBySIGHUP(int exit_code) { +// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; +// } +// +// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); +// +// On the regular expressions used in death tests: +// +// On POSIX-compliant systems (*nix), we use the library, +// which uses the POSIX extended regex syntax. +// +// On other platforms (e.g. Windows), we only support a simple regex +// syntax implemented as part of Google Test. This limited +// implementation should be enough most of the time when writing +// death tests; though it lacks many features you can find in PCRE +// or POSIX extended regex syntax. For example, we don't support +// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and +// repetition count ("x{5,7}"), among others. +// +// Below is the syntax that we do support. We chose it to be a +// subset of both PCRE and POSIX extended regex, so it's easy to +// learn wherever you come from. In the following: 'A' denotes a +// literal character, period (.), or a single \\ escape sequence; +// 'x' and 'y' denote regular expressions; 'm' and 'n' are for +// natural numbers. +// +// c matches any literal character c +// \\d matches any decimal digit +// \\D matches any character that's not a decimal digit +// \\f matches \f +// \\n matches \n +// \\r matches \r +// \\s matches any ASCII whitespace, including \n +// \\S matches any character that's not a whitespace +// \\t matches \t +// \\v matches \v +// \\w matches any letter, _, or decimal digit +// \\W matches any character that \\w doesn't match +// \\c matches any literal character c, which must be a punctuation +// . matches any single character except \n +// A? matches 0 or 1 occurrences of A +// A* matches 0 or many occurrences of A +// A+ matches 1 or many occurrences of A +// ^ matches the beginning of a string (not that of each line) +// $ matches the end of a string (not that of each line) +// xy matches x followed by y +// +// If you accidentally use PCRE or POSIX extended regex features +// not implemented by us, you will get a run-time failure. In that +// case, please try to rewrite your regular expression within the +// above syntax. +// +// This implementation is *not* meant to be as highly tuned or robust +// as a compiled regex library, but should perform well enough for a +// death test, which already incurs significant overhead by launching +// a child process. +// +// Known caveats: +// +// A "threadsafe" style death test obtains the path to the test +// program from argv[0] and re-executes it in the sub-process. For +// simplicity, the current implementation doesn't search the PATH +// when launching the sub-process. This means that the user must +// invoke the test program via a path that contains at least one +// path separator (e.g. path/to/foo_test and +// /absolute/path/to/bar_test are fine, but foo_test is not). This +// is rarely a problem as people usually don't put the test binary +// directory in PATH. +// +// TODO(wan@google.com): make thread-safe death tests search the PATH. + +// Asserts that a given statement causes the program to exit, with an +// integer exit status that satisfies predicate, and emitting error output +// that matches regex. +# define ASSERT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) + +// Like ASSERT_EXIT, but continues on to successive tests in the +// test case, if any: +# define EXPECT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) + +// Asserts that a given statement causes the program to exit, either by +// explicitly exiting with a nonzero exit code or being killed by a +// signal, and emitting error output that matches regex. +# define ASSERT_DEATH(statement, regex) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Like ASSERT_DEATH, but continues on to successive tests in the +// test case, if any: +# define EXPECT_DEATH(statement, regex) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: + +// Tests that an exit code describes a normal exit with a given exit code. +class GTEST_API_ ExitedWithCode { + public: + explicit ExitedWithCode(int exit_code); + bool operator()(int exit_status) const; + private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + + const int exit_code_; +}; + +# if !GTEST_OS_WINDOWS +// Tests that an exit code describes an exit due to termination by a +// given signal. +class GTEST_API_ KilledBySignal { + public: + explicit KilledBySignal(int signum); + bool operator()(int exit_status) const; + private: + const int signum_; +}; +# endif // !GTEST_OS_WINDOWS + +// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. +// The death testing framework causes this to have interesting semantics, +// since the sideeffects of the call are only visible in opt mode, and not +// in debug mode. +// +// In practice, this can be used to test functions that utilize the +// LOG(DFATAL) macro using the following style: +// +// int DieInDebugOr12(int* sideeffect) { +// if (sideeffect) { +// *sideeffect = 12; +// } +// LOG(DFATAL) << "death"; +// return 12; +// } +// +// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { +// int sideeffect = 0; +// // Only asserts in dbg. +// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); +// +// #ifdef NDEBUG +// // opt-mode has sideeffect visible. +// EXPECT_EQ(12, sideeffect); +// #else +// // dbg-mode no visible sideeffect. +// EXPECT_EQ(0, sideeffect); +// #endif +// } +// +// This will assert that DieInDebugReturn12InOpt() crashes in debug +// mode, usually due to a DCHECK or LOG(DFATAL), but returns the +// appropriate fallback value (12 in this case) in opt mode. If you +// need to test that a function has appropriate side-effects in opt +// mode, include assertions against the side-effects. A general +// pattern for this is: +// +// EXPECT_DEBUG_DEATH({ +// // Side-effects here will have an effect after this statement in +// // opt mode, but none in debug mode. +// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); +// }, "death"); +// +# ifdef NDEBUG + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) + +# else + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + EXPECT_DEATH(statement, regex) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + ASSERT_DEATH(statement, regex) + +# endif // NDEBUG for EXPECT_DEBUG_DEATH +#endif // GTEST_HAS_DEATH_TEST + +// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and +// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if +// death tests are supported; otherwise they just issue a warning. This is +// useful when you are combining death test assertions with normal test +// assertions in one test. +#if GTEST_HAS_DEATH_TEST +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) +#else +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) +#endif + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the Message class. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! + +#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ + +#include + + +namespace testing { + +// The Message class works like an ostream repeater. +// +// Typical usage: +// +// 1. You stream a bunch of values to a Message object. +// It will remember the text in a stringstream. +// 2. Then you stream the Message object to an ostream. +// This causes the text in the Message to be streamed +// to the ostream. +// +// For example; +// +// testing::Message foo; +// foo << 1 << " != " << 2; +// std::cout << foo; +// +// will print "1 != 2". +// +// Message is not intended to be inherited from. In particular, its +// destructor is not virtual. +// +// Note that stringstream behaves differently in gcc and in MSVC. You +// can stream a NULL char pointer to it in the former, but not in the +// latter (it causes an access violation if you do). The Message +// class hides this difference by treating a NULL char pointer as +// "(null)". +class GTEST_API_ Message { + private: + // The type of basic IO manipulators (endl, ends, and flush) for + // narrow streams. + typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); + + public: + // Constructs an empty Message. + // We allocate the stringstream separately because otherwise each use of + // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's + // stack frame leading to huge stack frames in some cases; gcc does not reuse + // the stack space. + Message() : ss_(new ::std::stringstream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); + } + + // Copy constructor. + Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT + *ss_ << msg.GetString(); + } + + // Constructs a Message from a C-string. + explicit Message(const char* str) : ss_(new ::std::stringstream) { + *ss_ << str; + } + +#if GTEST_OS_SYMBIAN + // Streams a value (either a pointer or not) to this object. + template + inline Message& operator <<(const T& value) { + StreamHelper(typename internal::is_pointer::type(), value); + return *this; + } +#else + // Streams a non-pointer value to this object. + template + inline Message& operator <<(const T& val) { + ::GTestStreamToHelper(ss_.get(), val); + return *this; + } + + // Streams a pointer value to this object. + // + // This function is an overload of the previous one. When you + // stream a pointer to a Message, this definition will be used as it + // is more specialized. (The C++ Standard, section + // [temp.func.order].) If you stream a non-pointer, then the + // previous definition will be used. + // + // The reason for this overload is that streaming a NULL pointer to + // ostream is undefined behavior. Depending on the compiler, you + // may get "0", "(nil)", "(null)", or an access violation. To + // ensure consistent result across compilers, we always treat NULL + // as "(null)". + template + inline Message& operator <<(T* const& pointer) { // NOLINT + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_.get(), pointer); + } + return *this; + } +#endif // GTEST_OS_SYMBIAN + + // Since the basic IO manipulators are overloaded for both narrow + // and wide streams, we have to provide this specialized definition + // of operator <<, even though its body is the same as the + // templatized version above. Without this definition, streaming + // endl or other basic IO manipulators to Message will confuse the + // compiler. + Message& operator <<(BasicNarrowIoManip val) { + *ss_ << val; + return *this; + } + + // Instead of 1/0, we want to see true/false for bool values. + Message& operator <<(bool b) { + return *this << (b ? "true" : "false"); + } + + // These two overloads allow streaming a wide C string to a Message + // using the UTF-8 encoding. + Message& operator <<(const wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + Message& operator <<(wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + +#if GTEST_HAS_STD_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::std::wstring& wstr); +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::wstring& wstr); +#endif // GTEST_HAS_GLOBAL_WSTRING + + // Gets the text streamed to this object so far as an std::string. + // Each '\0' character in the buffer is replaced with "\\0". + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + std::string GetString() const { + return internal::StringStreamToString(ss_.get()); + } + + private: + +#if GTEST_OS_SYMBIAN + // These are needed as the Nokia Symbian Compiler cannot decide between + // const T& and const T* in a function template. The Nokia compiler _can_ + // decide between class template specializations for T and T*, so a + // tr1::type_traits-like is_pointer works, and we can overload on that. + template + inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) { + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_.get(), pointer); + } + } + template + inline void StreamHelper(internal::false_type /*dummy*/, const T& value) { + ::GTestStreamToHelper(ss_.get(), value); + } +#endif // GTEST_OS_SYMBIAN + + // We'll hold the text streamed to this object here. + const internal::scoped_ptr< ::std::stringstream> ss_; + + // We declare (but don't implement) this to prevent the compiler + // from implementing the assignment operator. + void operator=(const Message&); +}; + +// Streams a Message to an ostream. +inline std::ostream& operator <<(std::ostream& os, const Message& sb) { + return os << sb.GetString(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +// This file was GENERATED by command: +// pump.py gtest-param-test.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It is usually derived from testing::TestWithParam (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface, where T is the type of the parameter +// values. Inheriting from TestWithParam satisfies that requirement because +// TestWithParam inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} + +#endif // 0 + + +#if !GTEST_OS_SYMBIAN +# include +#endif + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ + +#include +#include +#include + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +// Copyright 2003 Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: Dan Egnor (egnor@google.com) +// +// A "smart" pointer type with reference tracking. Every pointer to a +// particular object is kept on a circular linked list. When the last pointer +// to an object is destroyed or reassigned, the object is deleted. +// +// Used properly, this deletes the object when the last reference goes away. +// There are several caveats: +// - Like all reference counting schemes, cycles lead to leaks. +// - Each smart pointer is actually two pointers (8 bytes instead of 4). +// - Every time a pointer is assigned, the entire list of pointers to that +// object is traversed. This class is therefore NOT SUITABLE when there +// will often be more than two or three pointers to a particular object. +// - References are only tracked as long as linked_ptr<> objects are copied. +// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS +// will happen (double deletion). +// +// A good use of this class is storing object references in STL containers. +// You can safely put linked_ptr<> in a vector<>. +// Other uses may not be as good. +// +// Note: If you use an incomplete type with linked_ptr<>, the class +// *containing* linked_ptr<> must have a constructor and destructor (even +// if they do nothing!). +// +// Bill Gibbons suggested we use something like this. +// +// Thread Safety: +// Unlike other linked_ptr implementations, in this implementation +// a linked_ptr object is thread-safe in the sense that: +// - it's safe to copy linked_ptr objects concurrently, +// - it's safe to copy *from* a linked_ptr and read its underlying +// raw pointer (e.g. via get()) concurrently, and +// - it's safe to write to two linked_ptrs that point to the same +// shared object concurrently. +// TODO(wan@google.com): rename this to safe_linked_ptr to avoid +// confusion with normal linked_ptr. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#include +#include + + +namespace testing { +namespace internal { + +// Protects copying of all linked_ptr objects. +GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// This is used internally by all instances of linked_ptr<>. It needs to be +// a non-template class because different types of linked_ptr<> can refer to +// the same object (linked_ptr(obj) vs linked_ptr(obj)). +// So, it needs to be possible for different types of linked_ptr to participate +// in the same circular linked list, so we need a single class type here. +// +// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. +class linked_ptr_internal { + public: + // Create a new circle that includes only this instance. + void join_new() { + next_ = this; + } + + // Many linked_ptr operations may change p.link_ for some linked_ptr + // variable p in the same circle as this object. Therefore we need + // to prevent two such operations from occurring concurrently. + // + // Note that different types of linked_ptr objects can coexist in a + // circle (e.g. linked_ptr, linked_ptr, and + // linked_ptr). Therefore we must use a single mutex to + // protect all linked_ptr objects. This can create serious + // contention in production code, but is acceptable in a testing + // framework. + + // Join an existing circle. + void join(linked_ptr_internal const* ptr) + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { + MutexLock lock(&g_linked_ptr_mutex); + + linked_ptr_internal const* p = ptr; + while (p->next_ != ptr) p = p->next_; + p->next_ = this; + next_ = ptr; + } + + // Leave whatever circle we're part of. Returns true if we were the + // last member of the circle. Once this is done, you can join() another. + bool depart() + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { + MutexLock lock(&g_linked_ptr_mutex); + + if (next_ == this) return true; + linked_ptr_internal const* p = next_; + while (p->next_ != this) p = p->next_; + p->next_ = next_; + return false; + } + + private: + mutable linked_ptr_internal const* next_; +}; + +template +class linked_ptr { + public: + typedef T element_type; + + // Take over ownership of a raw pointer. This should happen as soon as + // possible after the object is created. + explicit linked_ptr(T* ptr = NULL) { capture(ptr); } + ~linked_ptr() { depart(); } + + // Copy an existing linked_ptr<>, adding ourselves to the list of references. + template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } + linked_ptr(linked_ptr const& ptr) { // NOLINT + assert(&ptr != this); + copy(&ptr); + } + + // Assignment releases the old value and acquires the new. + template linked_ptr& operator=(linked_ptr const& ptr) { + depart(); + copy(&ptr); + return *this; + } + + linked_ptr& operator=(linked_ptr const& ptr) { + if (&ptr != this) { + depart(); + copy(&ptr); + } + return *this; + } + + // Smart pointer members. + void reset(T* ptr = NULL) { + depart(); + capture(ptr); + } + T* get() const { return value_; } + T* operator->() const { return value_; } + T& operator*() const { return *value_; } + + bool operator==(T* p) const { return value_ == p; } + bool operator!=(T* p) const { return value_ != p; } + template + bool operator==(linked_ptr const& ptr) const { + return value_ == ptr.get(); + } + template + bool operator!=(linked_ptr const& ptr) const { + return value_ != ptr.get(); + } + + private: + template + friend class linked_ptr; + + T* value_; + linked_ptr_internal link_; + + void depart() { + if (link_.depart()) delete value_; + } + + void capture(T* ptr) { + value_ = ptr; + link_.join_new(); + } + + template void copy(linked_ptr const* ptr) { + value_ = ptr->get(); + if (value_) + link_.join(&ptr->link_); + else + link_.join_new(); + } +}; + +template inline +bool operator==(T* ptr, const linked_ptr& x) { + return ptr == x.get(); +} + +template inline +bool operator!=(T* ptr, const linked_ptr& x) { + return ptr != x.get(); +} + +// A function to convert T* into linked_ptr +// Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation +// for linked_ptr >(new FooBarBaz(arg)) +template +linked_ptr make_linked_ptr(T* ptr) { + return linked_ptr(ptr); +} + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// A user can teach this function how to print a class type T by +// defining either operator<<() or PrintTo() in the namespace that +// defines T. More specifically, the FIRST defined function in the +// following list will be used (assuming T is defined in namespace +// foo): +// +// 1. foo::PrintTo(const T&, ostream*) +// 2. operator<<(ostream&, const T&) defined in either foo or the +// global namespace. +// +// If none of the above is defined, it will print the debug string of +// the value if it is a protocol buffer, or print the raw bytes in the +// value otherwise. +// +// To aid debugging: when T is a reference type, the address of the +// value is also printed; when T is a (const) char pointer, both the +// pointer value and the NUL-terminated string it points to are +// printed. +// +// We also provide some convenient wrappers: +// +// // Prints a value to a string. For a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// std::string ::testing::PrintToString(const T& value); +// +// // Prints a value tersely: for a reference type, the referenced +// // value (but not the address) is printed; for a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// void ::testing::internal::UniversalTersePrint(const T& value, ostream*); +// +// // Prints value using the type inferred by the compiler. The difference +// // from UniversalTersePrint() is that this function prints both the +// // pointer and the NUL-terminated string for a (const or not) char pointer. +// void ::testing::internal::UniversalPrint(const T& value, ostream*); +// +// // Prints the fields of a tuple tersely to a string vector, one +// // element for each field. Tuple support must be enabled in +// // gtest-port.h. +// std::vector UniversalTersePrintTupleFieldsToStrings( +// const Tuple& value); +// +// Known limitation: +// +// The print primitives print the elements of an STL-style container +// using the compiler-inferred type of *iter where iter is a +// const_iterator of the container. When const_iterator is an input +// iterator but not a forward iterator, this inferred type may not +// match value_type, and the print output may be incorrect. In +// practice, this is rarely a problem as for most containers +// const_iterator is a forward iterator. We'll fix this if there's an +// actual need for it. Note that this fix cannot rely on value_type +// being defined as many user-defined container types don't have +// value_type. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ + +#include // NOLINT +#include +#include +#include +#include + +namespace testing { + +// Definitions in the 'internal' and 'internal2' name spaces are +// subject to change without notice. DO NOT USE THEM IN USER CODE! +namespace internal2 { + +// Prints the given number of bytes in the given object to the given +// ostream. +GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, + size_t count, + ::std::ostream* os); + +// For selecting which printer to use when a given type has neither << +// nor PrintTo(). +enum TypeKind { + kProtobuf, // a protobuf type + kConvertibleToInteger, // a type implicitly convertible to BiggestInt + // (e.g. a named or unnamed enum type) + kOtherType // anything else +}; + +// TypeWithoutFormatter::PrintValue(value, os) is called +// by the universal printer to print a value of type T when neither +// operator<< nor PrintTo() is defined for T, where kTypeKind is the +// "kind" of T as defined by enum TypeKind. +template +class TypeWithoutFormatter { + public: + // This default version is called when kTypeKind is kOtherType. + static void PrintValue(const T& value, ::std::ostream* os) { + PrintBytesInObjectTo(reinterpret_cast(&value), + sizeof(value), os); + } +}; + +// We print a protobuf using its ShortDebugString() when the string +// doesn't exceed this many characters; otherwise we print it using +// DebugString() for better readability. +const size_t kProtobufOneLinerMaxLength = 50; + +template +class TypeWithoutFormatter { + public: + static void PrintValue(const T& value, ::std::ostream* os) { + const ::testing::internal::string short_str = value.ShortDebugString(); + const ::testing::internal::string pretty_str = + short_str.length() <= kProtobufOneLinerMaxLength ? + short_str : ("\n" + value.DebugString()); + *os << ("<" + pretty_str + ">"); + } +}; + +template +class TypeWithoutFormatter { + public: + // Since T has no << operator or PrintTo() but can be implicitly + // converted to BiggestInt, we print it as a BiggestInt. + // + // Most likely T is an enum type (either named or unnamed), in which + // case printing it as an integer is the desired behavior. In case + // T is not an enum, printing it as an integer is the best we can do + // given that it has no user-defined printer. + static void PrintValue(const T& value, ::std::ostream* os) { + const internal::BiggestInt kBigInt = value; + *os << kBigInt; + } +}; + +// Prints the given value to the given ostream. If the value is a +// protocol message, its debug string is printed; if it's an enum or +// of a type implicitly convertible to BiggestInt, it's printed as an +// integer; otherwise the bytes in the value are printed. This is +// what UniversalPrinter::Print() does when it knows nothing about +// type T and T has neither << operator nor PrintTo(). +// +// A user can override this behavior for a class type Foo by defining +// a << operator in the namespace where Foo is defined. +// +// We put this operator in namespace 'internal2' instead of 'internal' +// to simplify the implementation, as much code in 'internal' needs to +// use << in STL, which would conflict with our own << were it defined +// in 'internal'. +// +// Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If +// we define it to take an std::ostream instead, we'll get an +// "ambiguous overloads" compiler error when trying to print a type +// Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether +// operator<<(std::ostream&, const T&) or +// operator<<(std::basic_stream, const Foo&) is more +// specific. +template +::std::basic_ostream& operator<<( + ::std::basic_ostream& os, const T& x) { + TypeWithoutFormatter::value ? kProtobuf : + internal::ImplicitlyConvertible::value ? + kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); + return os; +} + +} // namespace internal2 +} // namespace testing + +// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up +// magic needed for implementing UniversalPrinter won't work. +namespace testing_internal { + +// Used to print a value that is not an STL-style container when the +// user doesn't define PrintTo() for it. +template +void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { + // With the following statement, during unqualified name lookup, + // testing::internal2::operator<< appears as if it was declared in + // the nearest enclosing namespace that contains both + // ::testing_internal and ::testing::internal2, i.e. the global + // namespace. For more details, refer to the C++ Standard section + // 7.3.4-1 [namespace.udir]. This allows us to fall back onto + // testing::internal2::operator<< in case T doesn't come with a << + // operator. + // + // We cannot write 'using ::testing::internal2::operator<<;', which + // gcc 3.3 fails to compile due to a compiler bug. + using namespace ::testing::internal2; // NOLINT + + // Assuming T is defined in namespace foo, in the next statement, + // the compiler will consider all of: + // + // 1. foo::operator<< (thanks to Koenig look-up), + // 2. ::operator<< (as the current namespace is enclosed in ::), + // 3. testing::internal2::operator<< (thanks to the using statement above). + // + // The operator<< whose type matches T best will be picked. + // + // We deliberately allow #2 to be a candidate, as sometimes it's + // impossible to define #1 (e.g. when foo is ::std, defining + // anything in it is undefined behavior unless you are a compiler + // vendor.). + *os << value; +} + +} // namespace testing_internal + +namespace testing { +namespace internal { + +// UniversalPrinter::Print(value, ostream_ptr) prints the given +// value to the given ostream. The caller must ensure that +// 'ostream_ptr' is not NULL, or the behavior is undefined. +// +// We define UniversalPrinter as a class template (as opposed to a +// function template), as we need to partially specialize it for +// reference types, which cannot be done with function templates. +template +class UniversalPrinter; + +template +void UniversalPrint(const T& value, ::std::ostream* os); + +// Used to print an STL-style container when the user doesn't define +// a PrintTo() for it. +template +void DefaultPrintTo(IsContainer /* dummy */, + false_type /* is not a pointer */, + const C& container, ::std::ostream* os) { + const size_t kMaxCount = 32; // The maximum number of elements to print. + *os << '{'; + size_t count = 0; + for (typename C::const_iterator it = container.begin(); + it != container.end(); ++it, ++count) { + if (count > 0) { + *os << ','; + if (count == kMaxCount) { // Enough has been printed. + *os << " ..."; + break; + } + } + *os << ' '; + // We cannot call PrintTo(*it, os) here as PrintTo() doesn't + // handle *it being a native array. + internal::UniversalPrint(*it, os); + } + + if (count > 0) { + *os << ' '; + } + *os << '}'; +} + +// Used to print a pointer that is neither a char pointer nor a member +// pointer, when the user doesn't define PrintTo() for it. (A member +// variable pointer or member function pointer doesn't really point to +// a location in the address space. Their representation is +// implementation-defined. Therefore they will be printed as raw +// bytes.) +template +void DefaultPrintTo(IsNotContainer /* dummy */, + true_type /* is a pointer */, + T* p, ::std::ostream* os) { + if (p == NULL) { + *os << "NULL"; + } else { + // C++ doesn't allow casting from a function pointer to any object + // pointer. + // + // IsTrue() silences warnings: "Condition is always true", + // "unreachable code". + if (IsTrue(ImplicitlyConvertible::value)) { + // T is not a function type. We just call << to print p, + // relying on ADL to pick up user-defined << for their pointer + // types, if any. + *os << p; + } else { + // T is a function type, so '*os << p' doesn't do what we want + // (it just prints p as bool). We want to print p as a const + // void*. However, we cannot cast it to const void* directly, + // even using reinterpret_cast, as earlier versions of gcc + // (e.g. 3.4.5) cannot compile the cast when p is a function + // pointer. Casting to UInt64 first solves the problem. + *os << reinterpret_cast( + reinterpret_cast(p)); + } + } +} + +// Used to print a non-container, non-pointer value when the user +// doesn't define PrintTo() for it. +template +void DefaultPrintTo(IsNotContainer /* dummy */, + false_type /* is not a pointer */, + const T& value, ::std::ostream* os) { + ::testing_internal::DefaultPrintNonContainerTo(value, os); +} + +// Prints the given value using the << operator if it has one; +// otherwise prints the bytes in it. This is what +// UniversalPrinter::Print() does when PrintTo() is not specialized +// or overloaded for type T. +// +// A user can override this behavior for a class type Foo by defining +// an overload of PrintTo() in the namespace where Foo is defined. We +// give the user this option as sometimes defining a << operator for +// Foo is not desirable (e.g. the coding style may prevent doing it, +// or there is already a << operator but it doesn't do what the user +// wants). +template +void PrintTo(const T& value, ::std::ostream* os) { + // DefaultPrintTo() is overloaded. The type of its first two + // arguments determine which version will be picked. If T is an + // STL-style container, the version for container will be called; if + // T is a pointer, the pointer version will be called; otherwise the + // generic version will be called. + // + // Note that we check for container types here, prior to we check + // for protocol message types in our operator<<. The rationale is: + // + // For protocol messages, we want to give people a chance to + // override Google Mock's format by defining a PrintTo() or + // operator<<. For STL containers, other formats can be + // incompatible with Google Mock's format for the container + // elements; therefore we check for container types here to ensure + // that our format is used. + // + // The second argument of DefaultPrintTo() is needed to bypass a bug + // in Symbian's C++ compiler that prevents it from picking the right + // overload between: + // + // PrintTo(const T& x, ...); + // PrintTo(T* x, ...); + DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); +} + +// The following list of PrintTo() overloads tells +// UniversalPrinter::Print() how to print standard types (built-in +// types, strings, plain arrays, and pointers). + +// Overloads for various char types. +GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); +GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); +inline void PrintTo(char c, ::std::ostream* os) { + // When printing a plain char, we always treat it as unsigned. This + // way, the output won't be affected by whether the compiler thinks + // char is signed or not. + PrintTo(static_cast(c), os); +} + +// Overloads for other simple built-in types. +inline void PrintTo(bool x, ::std::ostream* os) { + *os << (x ? "true" : "false"); +} + +// Overload for wchar_t type. +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its decimal code (except for L'\0'). +// The L'\0' char is printed as "L'\\0'". The decimal code is printed +// as signed integer when wchar_t is implemented by the compiler +// as a signed type and is printed as an unsigned integer when wchar_t +// is implemented as an unsigned type. +GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); + +// Overloads for C strings. +GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); +inline void PrintTo(char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// signed/unsigned char is often used for representing binary data, so +// we print pointers to it as void* to be safe. +inline void PrintTo(const signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(const unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// MSVC can be configured to define wchar_t as a typedef of unsigned +// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native +// type. When wchar_t is a typedef, defining an overload for const +// wchar_t* would cause unsigned short* be printed as a wide string, +// possibly causing invalid memory accesses. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Overloads for wide C strings +GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); +inline void PrintTo(wchar_t* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +#endif + +// Overload for C arrays. Multi-dimensional arrays are printed +// properly. + +// Prints the given number of elements in an array, without printing +// the curly braces. +template +void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { + UniversalPrint(a[0], os); + for (size_t i = 1; i != count; i++) { + *os << ", "; + UniversalPrint(a[i], os); + } +} + +// Overloads for ::string and ::std::string. +#if GTEST_HAS_GLOBAL_STRING +GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); +inline void PrintTo(const ::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); +inline void PrintTo(const ::std::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} + +// Overloads for ::wstring and ::std::wstring. +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_TR1_TUPLE +// Overload for ::std::tr1::tuple. Needed for printing function arguments, +// which are packed as tuples. + +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template +void PrintTupleTo(const T& t, ::std::ostream* os); + +// Overloaded PrintTo() for tuples of various arities. We support +// tuples of up-to 10 fields. The following implementation works +// regardless of whether tr1::tuple is implemented using the +// non-standard variadic template feature or not. + +inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo( + const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} +#endif // GTEST_HAS_TR1_TUPLE + +// Overload for std::pair. +template +void PrintTo(const ::std::pair& value, ::std::ostream* os) { + *os << '('; + // We cannot use UniversalPrint(value.first, os) here, as T1 may be + // a reference type. The same for printing value.second. + UniversalPrinter::Print(value.first, os); + *os << ", "; + UniversalPrinter::Print(value.second, os); + *os << ')'; +} + +// Implements printing a non-reference type T by letting the compiler +// pick the right overload of PrintTo() for T. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4180) // Temporarily disables warning 4180. +#endif // _MSC_VER + + // Note: we deliberately don't call this PrintTo(), as that name + // conflicts with ::testing::internal::PrintTo in the body of the + // function. + static void Print(const T& value, ::std::ostream* os) { + // By default, ::testing::internal::PrintTo() is used for printing + // the value. + // + // Thanks to Koenig look-up, if T is a class and has its own + // PrintTo() function defined in its namespace, that function will + // be visible here. Since it is more specific than the generic ones + // in ::testing::internal, it will be picked by the compiler in the + // following statement - exactly what we want. + PrintTo(value, os); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER +}; + +// UniversalPrintArray(begin, len, os) prints an array of 'len' +// elements, starting at address 'begin'. +template +void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { + if (len == 0) { + *os << "{}"; + } else { + *os << "{ "; + const size_t kThreshold = 18; + const size_t kChunkSize = 8; + // If the array has more than kThreshold elements, we'll have to + // omit some details by printing only the first and the last + // kChunkSize elements. + // TODO(wan@google.com): let the user control the threshold using a flag. + if (len <= kThreshold) { + PrintRawArrayTo(begin, len, os); + } else { + PrintRawArrayTo(begin, kChunkSize, os); + *os << ", ..., "; + PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); + } + *os << " }"; + } +} +// This overload prints a (const) char array compactly. +GTEST_API_ void UniversalPrintArray( + const char* begin, size_t len, ::std::ostream* os); + +// This overload prints a (const) wchar_t array compactly. +GTEST_API_ void UniversalPrintArray( + const wchar_t* begin, size_t len, ::std::ostream* os); + +// Implements printing an array type T[N]. +template +class UniversalPrinter { + public: + // Prints the given array, omitting some elements when there are too + // many. + static void Print(const T (&a)[N], ::std::ostream* os) { + UniversalPrintArray(a, N, os); + } +}; + +// Implements printing a reference type T&. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4180) // Temporarily disables warning 4180. +#endif // _MSC_VER + + static void Print(const T& value, ::std::ostream* os) { + // Prints the address of the value. We use reinterpret_cast here + // as static_cast doesn't compile when T is a function type. + *os << "@" << reinterpret_cast(&value) << " "; + + // Then prints the value itself. + UniversalPrint(value, os); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER +}; + +// Prints a value tersely: for a reference type, the referenced value +// (but not the address) is printed; for a (const) char pointer, the +// NUL-terminated string (but not the pointer) is printed. + +template +class UniversalTersePrinter { + public: + static void Print(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); + } +}; +template +class UniversalTersePrinter { + public: + static void Print(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); + } +}; +template +class UniversalTersePrinter { + public: + static void Print(const T (&value)[N], ::std::ostream* os) { + UniversalPrinter::Print(value, os); + } +}; +template <> +class UniversalTersePrinter { + public: + static void Print(const char* str, ::std::ostream* os) { + if (str == NULL) { + *os << "NULL"; + } else { + UniversalPrint(string(str), os); + } + } +}; +template <> +class UniversalTersePrinter { + public: + static void Print(char* str, ::std::ostream* os) { + UniversalTersePrinter::Print(str, os); + } +}; + +#if GTEST_HAS_STD_WSTRING +template <> +class UniversalTersePrinter { + public: + static void Print(const wchar_t* str, ::std::ostream* os) { + if (str == NULL) { + *os << "NULL"; + } else { + UniversalPrint(::std::wstring(str), os); + } + } +}; +#endif + +template <> +class UniversalTersePrinter { + public: + static void Print(wchar_t* str, ::std::ostream* os) { + UniversalTersePrinter::Print(str, os); + } +}; + +template +void UniversalTersePrint(const T& value, ::std::ostream* os) { + UniversalTersePrinter::Print(value, os); +} + +// Prints a value using the type inferred by the compiler. The +// difference between this and UniversalTersePrint() is that for a +// (const) char pointer, this prints both the pointer and the +// NUL-terminated string. +template +void UniversalPrint(const T& value, ::std::ostream* os) { + // A workarond for the bug in VC++ 7.1 that prevents us from instantiating + // UniversalPrinter with T directly. + typedef T T1; + UniversalPrinter::Print(value, os); +} + +#if GTEST_HAS_TR1_TUPLE +typedef ::std::vector Strings; + +// This helper template allows PrintTo() for tuples and +// UniversalTersePrintTupleFieldsToStrings() to be defined by +// induction on the number of tuple fields. The idea is that +// TuplePrefixPrinter::PrintPrefixTo(t, os) prints the first N +// fields in tuple t, and can be defined in terms of +// TuplePrefixPrinter. + +// The inductive case. +template +struct TuplePrefixPrinter { + // Prints the first N fields of a tuple. + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + TuplePrefixPrinter::PrintPrefixTo(t, os); + *os << ", "; + UniversalPrinter::type> + ::Print(::std::tr1::get(t), os); + } + + // Tersely prints the first N fields of a tuple to a string vector, + // one element for each field. + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get(t), &ss); + strings->push_back(ss.str()); + } +}; + +// Base cases. +template <> +struct TuplePrefixPrinter<0> { + template + static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} + + template + static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} +}; +// We have to specialize the entire TuplePrefixPrinter<> class +// template here, even though the definition of +// TersePrintPrefixToStrings() is the same as the generic version, as +// Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't +// support specializing a method template of a class template. +template <> +struct TuplePrefixPrinter<1> { + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + UniversalPrinter::type>:: + Print(::std::tr1::get<0>(t), os); + } + + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get<0>(t), &ss); + strings->push_back(ss.str()); + } +}; + +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template +void PrintTupleTo(const T& t, ::std::ostream* os) { + *os << "("; + TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: + PrintPrefixTo(t, os); + *os << ")"; +} + +// Prints the fields of a tuple tersely to a string vector, one +// element for each field. See the comment before +// UniversalTersePrint() for how we define "tersely". +template +Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { + Strings result; + TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: + TersePrintPrefixToStrings(value, &result); + return result; +} +#endif // GTEST_HAS_TR1_TUPLE + +} // namespace internal + +template +::std::string PrintToString(const T& value) { + ::std::stringstream ss; + internal::UniversalTersePrinter::Print(value, &ss); + return ss.str(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ + +#if GTEST_HAS_PARAM_TEST + +namespace testing { +namespace internal { + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Outputs a message explaining invalid registration of different +// fixture class for the same test case. This may happen when +// TEST_P macro is used to define two tests with the same name +// but in different namespaces. +GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line); + +template class ParamGeneratorInterface; +template class ParamGenerator; + +// Interface for iterating over elements provided by an implementation +// of ParamGeneratorInterface. +template +class ParamIteratorInterface { + public: + virtual ~ParamIteratorInterface() {} + // A pointer to the base generator instance. + // Used only for the purposes of iterator comparison + // to make sure that two iterators belong to the same generator. + virtual const ParamGeneratorInterface* BaseGenerator() const = 0; + // Advances iterator to point to the next element + // provided by the generator. The caller is responsible + // for not calling Advance() on an iterator equal to + // BaseGenerator()->End(). + virtual void Advance() = 0; + // Clones the iterator object. Used for implementing copy semantics + // of ParamIterator. + virtual ParamIteratorInterface* Clone() const = 0; + // Dereferences the current iterator and provides (read-only) access + // to the pointed value. It is the caller's responsibility not to call + // Current() on an iterator equal to BaseGenerator()->End(). + // Used for implementing ParamGenerator::operator*(). + virtual const T* Current() const = 0; + // Determines whether the given iterator and other point to the same + // element in the sequence generated by the generator. + // Used for implementing ParamGenerator::operator==(). + virtual bool Equals(const ParamIteratorInterface& other) const = 0; +}; + +// Class iterating over elements provided by an implementation of +// ParamGeneratorInterface. It wraps ParamIteratorInterface +// and implements the const forward iterator concept. +template +class ParamIterator { + public: + typedef T value_type; + typedef const T& reference; + typedef ptrdiff_t difference_type; + + // ParamIterator assumes ownership of the impl_ pointer. + ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} + ParamIterator& operator=(const ParamIterator& other) { + if (this != &other) + impl_.reset(other.impl_->Clone()); + return *this; + } + + const T& operator*() const { return *impl_->Current(); } + const T* operator->() const { return impl_->Current(); } + // Prefix version of operator++. + ParamIterator& operator++() { + impl_->Advance(); + return *this; + } + // Postfix version of operator++. + ParamIterator operator++(int /*unused*/) { + ParamIteratorInterface* clone = impl_->Clone(); + impl_->Advance(); + return ParamIterator(clone); + } + bool operator==(const ParamIterator& other) const { + return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); + } + bool operator!=(const ParamIterator& other) const { + return !(*this == other); + } + + private: + friend class ParamGenerator; + explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} + scoped_ptr > impl_; +}; + +// ParamGeneratorInterface is the binary interface to access generators +// defined in other translation units. +template +class ParamGeneratorInterface { + public: + typedef T ParamType; + + virtual ~ParamGeneratorInterface() {} + + // Generator interface definition + virtual ParamIteratorInterface* Begin() const = 0; + virtual ParamIteratorInterface* End() const = 0; +}; + +// Wraps ParamGeneratorInterface and provides general generator syntax +// compatible with the STL Container concept. +// This class implements copy initialization semantics and the contained +// ParamGeneratorInterface instance is shared among all copies +// of the original object. This is possible because that instance is immutable. +template +class ParamGenerator { + public: + typedef ParamIterator iterator; + + explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} + ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} + + ParamGenerator& operator=(const ParamGenerator& other) { + impl_ = other.impl_; + return *this; + } + + iterator begin() const { return iterator(impl_->Begin()); } + iterator end() const { return iterator(impl_->End()); } + + private: + linked_ptr > impl_; +}; + +// Generates values from a range of two comparable values. Can be used to +// generate sequences of user-defined types that implement operator+() and +// operator<(). +// This class is used in the Range() function. +template +class RangeGenerator : public ParamGeneratorInterface { + public: + RangeGenerator(T begin, T end, IncrementT step) + : begin_(begin), end_(end), + step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} + virtual ~RangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, begin_, 0, step_); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, end_, end_index_, step_); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, T value, int index, + IncrementT step) + : base_(base), value_(value), index_(index), step_(step) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + value_ = value_ + step_; + index_++; + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const T* Current() const { return &value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const int other_index = + CheckedDowncastToActualType(&other)->index_; + return index_ == other_index; + } + + private: + Iterator(const Iterator& other) + : ParamIteratorInterface(), + base_(other.base_), value_(other.value_), index_(other.index_), + step_(other.step_) {} + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + T value_; + int index_; + const IncrementT step_; + }; // class RangeGenerator::Iterator + + static int CalculateEndIndex(const T& begin, + const T& end, + const IncrementT& step) { + int end_index = 0; + for (T i = begin; i < end; i = i + step) + end_index++; + return end_index; + } + + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); + + const T begin_; + const T end_; + const IncrementT step_; + // The index for the end() iterator. All the elements in the generated + // sequence are indexed (0-based) to aid iterator comparison. + const int end_index_; +}; // class RangeGenerator + + +// Generates values from a pair of STL-style iterators. Used in the +// ValuesIn() function. The elements are copied from the source range +// since the source can be located on the stack, and the generator +// is likely to persist beyond that stack frame. +template +class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { + public: + template + ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) + : container_(begin, end) {} + virtual ~ValuesInIteratorRangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, container_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, container_.end()); + } + + private: + typedef typename ::std::vector ContainerType; + + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + typename ContainerType::const_iterator iterator) + : base_(base), iterator_(iterator) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + ++iterator_; + value_.reset(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + // We need to use cached value referenced by iterator_ because *iterator_ + // can return a temporary object (and of type other then T), so just + // having "return &*iterator_;" doesn't work. + // value_ is updated here and not in Advance() because Advance() + // can advance iterator_ beyond the end of the range, and we cannot + // detect that fact. The client code, on the other hand, is + // responsible for not calling Current() on an out-of-range iterator. + virtual const T* Current() const { + if (value_.get() == NULL) + value_.reset(new T(*iterator_)); + return value_.get(); + } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + return iterator_ == + CheckedDowncastToActualType(&other)->iterator_; + } + + private: + Iterator(const Iterator& other) + // The explicit constructor call suppresses a false warning + // emitted by gcc when supplied with the -Wextra option. + : ParamIteratorInterface(), + base_(other.base_), + iterator_(other.iterator_) {} + + const ParamGeneratorInterface* const base_; + typename ContainerType::const_iterator iterator_; + // A cached value of *iterator_. We keep it here to allow access by + // pointer in the wrapping iterator's operator->(). + // value_ needs to be mutable to be accessed in Current(). + // Use of scoped_ptr helps manage cached value's lifetime, + // which is bound by the lifespan of the iterator itself. + mutable scoped_ptr value_; + }; // class ValuesInIteratorRangeGenerator::Iterator + + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); + + const ContainerType container_; +}; // class ValuesInIteratorRangeGenerator + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Stores a parameter value and later creates tests parameterized with that +// value. +template +class ParameterizedTestFactory : public TestFactoryBase { + public: + typedef typename TestClass::ParamType ParamType; + explicit ParameterizedTestFactory(ParamType parameter) : + parameter_(parameter) {} + virtual Test* CreateTest() { + TestClass::SetParam(¶meter_); + return new TestClass(); + } + + private: + const ParamType parameter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactoryBase is a base class for meta-factories that create +// test factories for passing into MakeAndRegisterTestInfo function. +template +class TestMetaFactoryBase { + public: + virtual ~TestMetaFactoryBase() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactory creates test factories for passing into +// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives +// ownership of test factory pointer, same factory object cannot be passed +// into that method twice. But ParameterizedTestCaseInfo is going to call +// it for each Test/Parameter value combination. Thus it needs meta factory +// creator class. +template +class TestMetaFactory + : public TestMetaFactoryBase { + public: + typedef typename TestCase::ParamType ParamType; + + TestMetaFactory() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { + return new ParameterizedTestFactory(parameter); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfoBase is a generic interface +// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase +// accumulates test information provided by TEST_P macro invocations +// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations +// and uses that information to register all resulting test instances +// in RegisterTests method. The ParameterizeTestCaseRegistry class holds +// a collection of pointers to the ParameterizedTestCaseInfo objects +// and calls RegisterTests() on each of them when asked. +class ParameterizedTestCaseInfoBase { + public: + virtual ~ParameterizedTestCaseInfoBase() {} + + // Base part of test case name for display purposes. + virtual const string& GetTestCaseName() const = 0; + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const = 0; + // UnitTest class invokes this method to register tests in this + // test case right before running them in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + virtual void RegisterTests() = 0; + + protected: + ParameterizedTestCaseInfoBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P +// macro invocations for a particular test case and generators +// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that +// test case. It registers tests with all values generated by all +// generators when asked. +template +class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { + public: + // ParamType and GeneratorCreationFunc are private types but are required + // for declarations of public methods AddTestPattern() and + // AddTestCaseInstantiation(). + typedef typename TestCase::ParamType ParamType; + // A function that returns an instance of appropriate generator type. + typedef ParamGenerator(GeneratorCreationFunc)(); + + explicit ParameterizedTestCaseInfo(const char* name) + : test_case_name_(name) {} + + // Test case base name for display purposes. + virtual const string& GetTestCaseName() const { return test_case_name_; } + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } + // TEST_P macro uses AddTestPattern() to record information + // about a single test in a LocalTestInfo structure. + // test_case_name is the base name of the test case (without invocation + // prefix). test_base_name is the name of an individual test without + // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is + // test case base name and DoBar is test base name. + void AddTestPattern(const char* test_case_name, + const char* test_base_name, + TestMetaFactoryBase* meta_factory) { + tests_.push_back(linked_ptr(new TestInfo(test_case_name, + test_base_name, + meta_factory))); + } + // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information + // about a generator. + int AddTestCaseInstantiation(const string& instantiation_name, + GeneratorCreationFunc* func, + const char* /* file */, + int /* line */) { + instantiations_.push_back(::std::make_pair(instantiation_name, func)); + return 0; // Return value used only to run this method in namespace scope. + } + // UnitTest class invokes this method to register tests in this test case + // test cases right before running tests in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + // UnitTest has a guard to prevent from calling this method more then once. + virtual void RegisterTests() { + for (typename TestInfoContainer::iterator test_it = tests_.begin(); + test_it != tests_.end(); ++test_it) { + linked_ptr test_info = *test_it; + for (typename InstantiationContainer::iterator gen_it = + instantiations_.begin(); gen_it != instantiations_.end(); + ++gen_it) { + const string& instantiation_name = gen_it->first; + ParamGenerator generator((*gen_it->second)()); + + Message test_case_name_stream; + if ( !instantiation_name.empty() ) + test_case_name_stream << instantiation_name << "/"; + test_case_name_stream << test_info->test_case_base_name; + + int i = 0; + for (typename ParamGenerator::iterator param_it = + generator.begin(); + param_it != generator.end(); ++param_it, ++i) { + Message test_name_stream; + test_name_stream << test_info->test_base_name << "/" << i; + MakeAndRegisterTestInfo( + test_case_name_stream.GetString().c_str(), + test_name_stream.GetString().c_str(), + NULL, // No type parameter. + PrintToString(*param_it).c_str(), + GetTestCaseTypeId(), + TestCase::SetUpTestCase, + TestCase::TearDownTestCase, + test_info->test_meta_factory->CreateTestFactory(*param_it)); + } // for param_it + } // for gen_it + } // for test_it + } // RegisterTests + + private: + // LocalTestInfo structure keeps information about a single test registered + // with TEST_P macro. + struct TestInfo { + TestInfo(const char* a_test_case_base_name, + const char* a_test_base_name, + TestMetaFactoryBase* a_test_meta_factory) : + test_case_base_name(a_test_case_base_name), + test_base_name(a_test_base_name), + test_meta_factory(a_test_meta_factory) {} + + const string test_case_base_name; + const string test_base_name; + const scoped_ptr > test_meta_factory; + }; + typedef ::std::vector > TestInfoContainer; + // Keeps pairs of + // received from INSTANTIATE_TEST_CASE_P macros. + typedef ::std::vector > + InstantiationContainer; + + const string test_case_name_; + TestInfoContainer tests_; + InstantiationContainer instantiations_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); +}; // class ParameterizedTestCaseInfo + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase +// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P +// macros use it to locate their corresponding ParameterizedTestCaseInfo +// descriptors. +class ParameterizedTestCaseRegistry { + public: + ParameterizedTestCaseRegistry() {} + ~ParameterizedTestCaseRegistry() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + delete *it; + } + } + + // Looks up or creates and returns a structure containing information about + // tests and instantiations of a particular test case. + template + ParameterizedTestCaseInfo* GetTestCasePatternHolder( + const char* test_case_name, + const char* file, + int line) { + ParameterizedTestCaseInfo* typed_test_info = NULL; + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + if ((*it)->GetTestCaseName() == test_case_name) { + if ((*it)->GetTestCaseTypeId() != GetTypeId()) { + // Complain about incorrect usage of Google Test facilities + // and terminate the program since we cannot guaranty correct + // test case setup and tear-down in this case. + ReportInvalidTestCaseType(test_case_name, file, line); + posix::Abort(); + } else { + // At this point we are sure that the object we found is of the same + // type we are looking for, so we downcast it to that type + // without further checks. + typed_test_info = CheckedDowncastToActualType< + ParameterizedTestCaseInfo >(*it); + } + break; + } + } + if (typed_test_info == NULL) { + typed_test_info = new ParameterizedTestCaseInfo(test_case_name); + test_case_infos_.push_back(typed_test_info); + } + return typed_test_info; + } + void RegisterTests() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + (*it)->RegisterTests(); + } + } + + private: + typedef ::std::vector TestCaseInfoContainer; + + TestCaseInfoContainer test_case_infos_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +// This file was GENERATED by command: +// pump.py gtest-param-util-generated.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most 50 arguments in Values, +// and at most 10 arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tr1::tuple which is +// currently set at 10. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end); + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]); + +template +internal::ParamGenerator ValuesIn( + const Container& container); + +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template +class ValueArray1 { + public: + explicit ValueArray1(T1 v1) : v1_(v1) {} + + template + operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + + const T1 v1_; +}; + +template +class ValueArray2 { + public: + ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray2& other); + + const T1 v1_; + const T2 v2_; +}; + +template +class ValueArray3 { + public: + ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray3& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; +}; + +template +class ValueArray4 { + public: + ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray4& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; +}; + +template +class ValueArray5 { + public: + ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray5& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; +}; + +template +class ValueArray6 { + public: + ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray6& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; +}; + +template +class ValueArray7 { + public: + ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray7& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; +}; + +template +class ValueArray8 { + public: + ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray8& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; +}; + +template +class ValueArray9 { + public: + ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray9& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; +}; + +template +class ValueArray10 { + public: + ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray10& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; +}; + +template +class ValueArray11 { + public: + ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray11& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; +}; + +template +class ValueArray12 { + public: + ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray12& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; +}; + +template +class ValueArray13 { + public: + ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray13& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; +}; + +template +class ValueArray14 { + public: + ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray14& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; +}; + +template +class ValueArray15 { + public: + ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray15& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; +}; + +template +class ValueArray16 { + public: + ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray16& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; +}; + +template +class ValueArray17 { + public: + ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray17& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; +}; + +template +class ValueArray18 { + public: + ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray18& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; +}; + +template +class ValueArray19 { + public: + ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray19& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; +}; + +template +class ValueArray20 { + public: + ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray20& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; +}; + +template +class ValueArray21 { + public: + ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray21& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; +}; + +template +class ValueArray22 { + public: + ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray22& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; +}; + +template +class ValueArray23 { + public: + ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray23& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; +}; + +template +class ValueArray24 { + public: + ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray24& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; +}; + +template +class ValueArray25 { + public: + ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray25& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; +}; + +template +class ValueArray26 { + public: + ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray26& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; +}; + +template +class ValueArray27 { + public: + ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray27& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; +}; + +template +class ValueArray28 { + public: + ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray28& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; +}; + +template +class ValueArray29 { + public: + ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray29& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; +}; + +template +class ValueArray30 { + public: + ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray30& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; +}; + +template +class ValueArray31 { + public: + ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray31& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; +}; + +template +class ValueArray32 { + public: + ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray32& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; +}; + +template +class ValueArray33 { + public: + ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray33& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; +}; + +template +class ValueArray34 { + public: + ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray34& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; +}; + +template +class ValueArray35 { + public: + ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray35& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; +}; + +template +class ValueArray36 { + public: + ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray36& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; +}; + +template +class ValueArray37 { + public: + ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray37& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; +}; + +template +class ValueArray38 { + public: + ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray38& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; +}; + +template +class ValueArray39 { + public: + ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray39& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; +}; + +template +class ValueArray40 { + public: + ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray40& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; +}; + +template +class ValueArray41 { + public: + ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray41& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; +}; + +template +class ValueArray42 { + public: + ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray42& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; +}; + +template +class ValueArray43 { + public: + ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), + v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray43& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; +}; + +template +class ValueArray44 { + public: + ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), + v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), + v43_(v43), v44_(v44) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray44& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; +}; + +template +class ValueArray45 { + public: + ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), + v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray45& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; +}; + +template +class ValueArray46 { + public: + ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray46& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; +}; + +template +class ValueArray47 { + public: + ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), + v47_(v47) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray47& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; +}; + +template +class ValueArray48 { + public: + ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), + v46_(v46), v47_(v47), v48_(v48) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray48& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; +}; + +template +class ValueArray49 { + public: + ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, + T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_), static_cast(v49_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray49& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; +}; + +template +class ValueArray50 { + public: + ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, + T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_), static_cast(v49_), static_cast(v50_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray50& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; + const T50 v50_; +}; + +# if GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +template +class CartesianProductGenerator2 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator2(const ParamGenerator& g1, + const ParamGenerator& g2) + : g1_(g1), g2_(g2) {} + virtual ~CartesianProductGenerator2() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current2_; + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + ParamType current_value_; + }; // class CartesianProductGenerator2::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator2& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; +}; // class CartesianProductGenerator2 + + +template +class CartesianProductGenerator3 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator3(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + virtual ~CartesianProductGenerator3() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current3_; + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + ParamType current_value_; + }; // class CartesianProductGenerator3::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator3& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; +}; // class CartesianProductGenerator3 + + +template +class CartesianProductGenerator4 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator4(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + virtual ~CartesianProductGenerator4() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current4_; + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + ParamType current_value_; + }; // class CartesianProductGenerator4::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator4& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; +}; // class CartesianProductGenerator4 + + +template +class CartesianProductGenerator5 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator5(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + virtual ~CartesianProductGenerator5() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current5_; + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + ParamType current_value_; + }; // class CartesianProductGenerator5::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator5& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; +}; // class CartesianProductGenerator5 + + +template +class CartesianProductGenerator6 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator6(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + virtual ~CartesianProductGenerator6() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current6_; + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + ParamType current_value_; + }; // class CartesianProductGenerator6::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator6& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; +}; // class CartesianProductGenerator6 + + +template +class CartesianProductGenerator7 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator7(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + virtual ~CartesianProductGenerator7() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current7_; + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + ParamType current_value_; + }; // class CartesianProductGenerator7::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator7& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; +}; // class CartesianProductGenerator7 + + +template +class CartesianProductGenerator8 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator8(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + virtual ~CartesianProductGenerator8() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current8_; + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + ParamType current_value_; + }; // class CartesianProductGenerator8::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator8& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; +}; // class CartesianProductGenerator8 + + +template +class CartesianProductGenerator9 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator9(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + virtual ~CartesianProductGenerator9() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current9_; + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + ParamType current_value_; + }; // class CartesianProductGenerator9::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator9& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; +}; // class CartesianProductGenerator9 + + +template +class CartesianProductGenerator10 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator10(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9, + const ParamGenerator& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + virtual ~CartesianProductGenerator10() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end(), g10_, g10_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9, + const ParamGenerator& g10, + const typename ParamGenerator::iterator& current10) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9), + begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current10_; + if (current10_ == end10_) { + current10_ = begin10_; + ++current9_; + } + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_ && + current10_ == typed_other->current10_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_), + begin10_(other.begin10_), + end10_(other.end10_), + current10_(other.current10_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_, *current10_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_ || + current10_ == end10_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + const typename ParamGenerator::iterator begin10_; + const typename ParamGenerator::iterator end10_; + typename ParamGenerator::iterator current10_; + ParamType current_value_; + }; // class CartesianProductGenerator10::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator10& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; + const ParamGenerator g10_; +}; // class CartesianProductGenerator10 + + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN to ParamGenerator if T is +// convertible to U. +// +template +class CartesianProductHolder2 { + public: +CartesianProductHolder2(const Generator1& g1, const Generator2& g2) + : g1_(g1), g2_(g2) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator2( + static_cast >(g1_), + static_cast >(g2_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder2& other); + + const Generator1 g1_; + const Generator2 g2_; +}; // class CartesianProductHolder2 + +template +class CartesianProductHolder3 { + public: +CartesianProductHolder3(const Generator1& g1, const Generator2& g2, + const Generator3& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator3( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder3& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; +}; // class CartesianProductHolder3 + +template +class CartesianProductHolder4 { + public: +CartesianProductHolder4(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator4( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder4& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; +}; // class CartesianProductHolder4 + +template +class CartesianProductHolder5 { + public: +CartesianProductHolder5(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator5( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder5& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; +}; // class CartesianProductHolder5 + +template +class CartesianProductHolder6 { + public: +CartesianProductHolder6(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator6( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder6& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; +}; // class CartesianProductHolder6 + +template +class CartesianProductHolder7 { + public: +CartesianProductHolder7(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator7( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder7& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; +}; // class CartesianProductHolder7 + +template +class CartesianProductHolder8 { + public: +CartesianProductHolder8(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator8( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder8& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; +}; // class CartesianProductHolder8 + +template +class CartesianProductHolder9 { + public: +CartesianProductHolder9(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator9( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder9& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; +}; // class CartesianProductHolder9 + +template +class CartesianProductHolder10 { + public: +CartesianProductHolder10(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9, const Generator10& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator10( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_), + static_cast >(g10_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder10& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; + const Generator10 g10_; +}; // class CartesianProductHolder10 + +# endif // GTEST_HAS_COMBINE + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template +internal::ParamGenerator Range(T start, T end, IncrementT step) { + return internal::ParamGenerator( + new internal::RangeGenerator(start, end, step)); +} + +template +internal::ParamGenerator Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list GetParameterChars() { +// ::std::list list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end) { + typedef typename ::testing::internal::IteratorTraits + ::value_type ParamType; + return internal::ParamGenerator( + new internal::ValuesInIteratorRangeGenerator(begin, end)); +} + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template +internal::ParamGenerator ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to 50 parameters. +// +template +internal::ValueArray1 Values(T1 v1) { + return internal::ValueArray1(v1); +} + +template +internal::ValueArray2 Values(T1 v1, T2 v2) { + return internal::ValueArray2(v1, v2); +} + +template +internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { + return internal::ValueArray3(v1, v2, v3); +} + +template +internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { + return internal::ValueArray4(v1, v2, v3, v4); +} + +template +internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5) { + return internal::ValueArray5(v1, v2, v3, v4, v5); +} + +template +internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6) { + return internal::ValueArray6(v1, v2, v3, v4, v5, v6); +} + +template +internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7) { + return internal::ValueArray7(v1, v2, v3, v4, v5, + v6, v7); +} + +template +internal::ValueArray8 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { + return internal::ValueArray8(v1, v2, v3, v4, + v5, v6, v7, v8); +} + +template +internal::ValueArray9 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { + return internal::ValueArray9(v1, v2, v3, + v4, v5, v6, v7, v8, v9); +} + +template +internal::ValueArray10 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { + return internal::ValueArray10(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10); +} + +template +internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) { + return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); +} + +template +internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) { + return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); +} + +template +internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) { + return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); +} + +template +internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { + return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14); +} + +template +internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { + return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); +} + +template +internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16) { + return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16); +} + +template +internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17) { + return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17); +} + +template +internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18) { + return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18); +} + +template +internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { + return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); +} + +template +internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { + return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); +} + +template +internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { + return internal::ValueArray21(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); +} + +template +internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22) { + return internal::ValueArray22(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22); +} + +template +internal::ValueArray23 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23) { + return internal::ValueArray23(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23); +} + +template +internal::ValueArray24 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24) { + return internal::ValueArray24(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24); +} + +template +internal::ValueArray25 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { + return internal::ValueArray25(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25); +} + +template +internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) { + return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); +} + +template +internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) { + return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); +} + +template +internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) { + return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28); +} + +template +internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) { + return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29); +} + +template +internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { + return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30); +} + +template +internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { + return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31); +} + +template +internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32) { + return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32); +} + +template +internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33) { + return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); +} + +template +internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34) { + return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); +} + +template +internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { + return internal::ValueArray35(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); +} + +template +internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { + return internal::ValueArray36(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36); +} + +template +internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37) { + return internal::ValueArray37(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37); +} + +template +internal::ValueArray38 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38) { + return internal::ValueArray38(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, + v33, v34, v35, v36, v37, v38); +} + +template +internal::ValueArray39 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38, T39 v39) { + return internal::ValueArray39(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, + v32, v33, v34, v35, v36, v37, v38, v39); +} + +template +internal::ValueArray40 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, + T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, + T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { + return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, + v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); +} + +template +internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { + return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, + v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); +} + +template +internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) { + return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, + v42); +} + +template +internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) { + return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, + v41, v42, v43); +} + +template +internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) { + return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, + v40, v41, v42, v43, v44); +} + +template +internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { + return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, + v39, v40, v41, v42, v43, v44, v45); +} + +template +internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { + return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46); +} + +template +internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { + return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); +} + +template +internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, + T48 v48) { + return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, + v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); +} + +template +internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, + T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, + T47 v47, T48 v48, T49 v49) { + return internal::ValueArray49(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, + v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); +} + +template +internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, + T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, + T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { + return internal::ValueArray50(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, + v48, v49, v50); +} + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator Bool() { + return Values(false, true); +} + +# if GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// tuple where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to 10 arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +template +internal::CartesianProductHolder2 Combine( + const Generator1& g1, const Generator2& g2) { + return internal::CartesianProductHolder2( + g1, g2); +} + +template +internal::CartesianProductHolder3 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3) { + return internal::CartesianProductHolder3( + g1, g2, g3); +} + +template +internal::CartesianProductHolder4 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4) { + return internal::CartesianProductHolder4( + g1, g2, g3, g4); +} + +template +internal::CartesianProductHolder5 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5) { + return internal::CartesianProductHolder5( + g1, g2, g3, g4, g5); +} + +template +internal::CartesianProductHolder6 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6) { + return internal::CartesianProductHolder6( + g1, g2, g3, g4, g5, g6); +} + +template +internal::CartesianProductHolder7 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7) { + return internal::CartesianProductHolder7( + g1, g2, g3, g4, g5, g6, g7); +} + +template +internal::CartesianProductHolder8 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8) { + return internal::CartesianProductHolder8( + g1, g2, g3, g4, g5, g6, g7, g8); +} + +template +internal::CartesianProductHolder9 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9) { + return internal::CartesianProductHolder9( + g1, g2, g3, g4, g5, g6, g7, g8, g9); +} + +template +internal::CartesianProductHolder10 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9, + const Generator10& g10) { + return internal::CartesianProductHolder10( + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); +} +# endif // GTEST_HAS_COMBINE + + + +# define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + virtual void TestBody(); \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) + +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Google C++ Testing Framework definitions useful in production code. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ + +// When you need to test the private or protected members of a class, +// use the FRIEND_TEST macro to declare your tests as friends of the +// class. For example: +// +// class MyClass { +// private: +// void MyMethod(); +// FRIEND_TEST(MyClassTest, MyMethod); +// }; +// +// class MyClassTest : public testing::Test { +// // ... +// }; +// +// TEST_F(MyClassTest, MyMethod) { +// // Can call MyClass::MyMethod() here. +// } + +#define FRIEND_TEST(test_case_name, test_name)\ +friend class test_case_name##_##test_name##_Test + +#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ + +#include +#include + +namespace testing { + +// A copyable object representing the result of a test part (i.e. an +// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). +// +// Don't inherit from TestPartResult as its destructor is not virtual. +class GTEST_API_ TestPartResult { + public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure // Failed and the test should be terminated. + }; + + // C'tor. TestPartResult does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestPartResult object. + TestPartResult(Type a_type, + const char* a_file_name, + int a_line_number, + const char* a_message) + : type_(a_type), + file_name_(a_file_name == NULL ? "" : a_file_name), + line_number_(a_line_number), + summary_(ExtractSummary(a_message)), + message_(a_message) { + } + + // Gets the outcome of the test part. + Type type() const { return type_; } + + // Gets the name of the source file where the test part took place, or + // NULL if it's unknown. + const char* file_name() const { + return file_name_.empty() ? NULL : file_name_.c_str(); + } + + // Gets the line in the source file where the test part took place, + // or -1 if it's unknown. + int line_number() const { return line_number_; } + + // Gets the summary of the failure message. + const char* summary() const { return summary_.c_str(); } + + // Gets the message associated with the test part. + const char* message() const { return message_.c_str(); } + + // Returns true iff the test part passed. + bool passed() const { return type_ == kSuccess; } + + // Returns true iff the test part failed. + bool failed() const { return type_ != kSuccess; } + + // Returns true iff the test part non-fatally failed. + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } + + // Returns true iff the test part fatally failed. + bool fatally_failed() const { return type_ == kFatalFailure; } + + private: + Type type_; + + // Gets the summary of the failure message by omitting the stack + // trace in it. + static std::string ExtractSummary(const char* message); + + // The name of the source file where the test part took place, or + // "" if the source file is unknown. + std::string file_name_; + // The line in the source file where the test part took place, or -1 + // if the line number is unknown. + int line_number_; + std::string summary_; // The test failure summary. + std::string message_; // The test failure message. +}; + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result); + +// An array of TestPartResult objects. +// +// Don't inherit from TestPartResultArray as its destructor is not +// virtual. +class GTEST_API_ TestPartResultArray { + public: + TestPartResultArray() {} + + // Appends the given TestPartResult to the array. + void Append(const TestPartResult& result); + + // Returns the TestPartResult at the given index (0-based). + const TestPartResult& GetTestPartResult(int index) const; + + // Returns the number of TestPartResult objects in the array. + int size() const; + + private: + std::vector array_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); +}; + +// This interface knows how to report a test part result. +class TestPartResultReporterInterface { + public: + virtual ~TestPartResultReporterInterface() {} + + virtual void ReportTestPartResult(const TestPartResult& result) = 0; +}; + +namespace internal { + +// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a +// statement generates new fatal failures. To do so it registers itself as the +// current test part result reporter. Besides checking if fatal failures were +// reported, it only delegates the reporting to the former result reporter. +// The original result reporter is restored in the destructor. +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +class GTEST_API_ HasNewFatalFailureHelper + : public TestPartResultReporterInterface { + public: + HasNewFatalFailureHelper(); + virtual ~HasNewFatalFailureHelper(); + virtual void ReportTestPartResult(const TestPartResult& result); + bool has_new_fatal_failure() const { return has_new_fatal_failure_; } + private: + bool has_new_fatal_failure_; + TestPartResultReporterInterface* original_reporter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); +}; + +} // namespace internal + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// This header implements typed tests and type-parameterized tests. + +// Typed (aka type-driven) tests repeat the same test for types in a +// list. You must know which types you want to test with when writing +// typed tests. Here's how you do it: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + public: + ... + typedef std::list List; + static T shared_; + T value_; +}; + +// Next, associate a list of types with the test case, which will be +// repeated for each type in the list. The typedef is necessary for +// the macro to parse correctly. +typedef testing::Types MyTypes; +TYPED_TEST_CASE(FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// TYPED_TEST_CASE(FooTest, int); + +// Then, use TYPED_TEST() instead of TEST_F() to define as many typed +// tests for this test case as you want. +TYPED_TEST(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + // Since we are inside a derived class template, C++ requires use to + // visit the members of FooTest via 'this'. + TypeParam n = this->value_; + + // To visit static members of the fixture, add the TestFixture:: + // prefix. + n += TestFixture::shared_; + + // To refer to typedefs in the fixture, add the "typename + // TestFixture::" prefix. + typename TestFixture::List values; + values.push_back(n); + ... +} + +TYPED_TEST(FooTest, HasPropertyA) { ... } + +#endif // 0 + +// Type-parameterized tests are abstract test patterns parameterized +// by a type. Compared with typed tests, type-parameterized tests +// allow you to define the test pattern without knowing what the type +// parameters are. The defined pattern can be instantiated with +// different types any number of times, in any number of translation +// units. +// +// If you are designing an interface or concept, you can define a +// suite of type-parameterized tests to verify properties that any +// valid implementation of the interface/concept should have. Then, +// each implementation can easily instantiate the test suite to verify +// that it conforms to the requirements, without having to write +// similar tests repeatedly. Here's an example: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + ... +}; + +// Next, declare that you will define a type-parameterized test case +// (the _P suffix is for "parameterized" or "pattern", whichever you +// prefer): +TYPED_TEST_CASE_P(FooTest); + +// Then, use TYPED_TEST_P() to define as many type-parameterized tests +// for this type-parameterized test case as you want. +TYPED_TEST_P(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + TypeParam n = 0; + ... +} + +TYPED_TEST_P(FooTest, HasPropertyA) { ... } + +// Now the tricky part: you need to register all test patterns before +// you can instantiate them. The first argument of the macro is the +// test case name; the rest are the names of the tests in this test +// case. +REGISTER_TYPED_TEST_CASE_P(FooTest, + DoesBlah, HasPropertyA); + +// Finally, you are free to instantiate the pattern with the types you +// want. If you put the above code in a header file, you can #include +// it in multiple C++ source files and instantiate it multiple times. +// +// To distinguish different instances of the pattern, the first +// argument to the INSTANTIATE_* macro is a prefix that will be added +// to the actual test case name. Remember to pick unique prefixes for +// different instances. +typedef testing::Types MyTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); + +#endif // 0 + + +// Implements typed tests. + +#if GTEST_HAS_TYPED_TEST + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the typedef for the type parameters of the +// given test case. +# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +# define TYPED_TEST_CASE(CaseName, Types) \ + typedef ::testing::internal::TypeList< Types >::type \ + GTEST_TYPE_PARAMS_(CaseName) + +# define TYPED_TEST(CaseName, TestName) \ + template \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel< \ + GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ + GTEST_TYPE_PARAMS_(CaseName)>::Register(\ + "", #CaseName, #TestName, 0); \ + template \ + void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() + +#endif // GTEST_HAS_TYPED_TEST + +// Implements type-parameterized tests. + +#if GTEST_HAS_TYPED_TEST_P + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the namespace name that the type-parameterized tests for +// the given type-parameterized test case are defined in. The exact +// name of the namespace is subject to change without notice. +# define GTEST_CASE_NAMESPACE_(TestCaseName) \ + gtest_case_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the variable used to remember the names of +// the defined tests in the given test case. +# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ + gtest_typed_test_case_p_state_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. +// +// Expands to the name of the variable used to remember the names of +// the registered tests in the given test case. +# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ + gtest_registered_test_names_##TestCaseName##_ + +// The variables defined in the type-parameterized test macros are +// static as typically these macros are used in a .h file that can be +// #included in multiple translation units linked together. +# define TYPED_TEST_CASE_P(CaseName) \ + static ::testing::internal::TypedTestCasePState \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) + +# define TYPED_TEST_P(CaseName, TestName) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + template \ + class TestName : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ + __FILE__, __LINE__, #CaseName, #TestName); \ + } \ + template \ + void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() + +# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ + } \ + static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ + __FILE__, __LINE__, #__VA_ARGS__) + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ + bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTestCase::type>::Register(\ + #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// Depending on the platform, different string classes are available. +// On Linux, in addition to ::std::string, Google also makes use of +// class ::string, which has the same interface as ::std::string, but +// has a different implementation. +// +// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that +// ::string is available AND is a distinct type to ::std::string, or +// define it to 0 to indicate otherwise. +// +// If the user's ::std::string and ::string are the same class due to +// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. +// +// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined +// heuristically. + +namespace testing { + +// Declares the flags. + +// This flag temporary enables the disabled tests. +GTEST_DECLARE_bool_(also_run_disabled_tests); + +// This flag brings the debugger on an assertion failure. +GTEST_DECLARE_bool_(break_on_failure); + +// This flag controls whether Google Test catches all test-thrown exceptions +// and logs them as failures. +GTEST_DECLARE_bool_(catch_exceptions); + +// This flag enables using colors in terminal output. Available values are +// "yes" to enable colors, "no" (disable colors), or "auto" (the default) +// to let Google Test decide. +GTEST_DECLARE_string_(color); + +// This flag sets up the filter to select by name using a glob pattern +// the tests to run. If the filter is not given all tests are executed. +GTEST_DECLARE_string_(filter); + +// This flag causes the Google Test to list tests. None of the tests listed +// are actually run if the flag is provided. +GTEST_DECLARE_bool_(list_tests); + +// This flag controls whether Google Test emits a detailed XML report to a file +// in addition to its normal textual output. +GTEST_DECLARE_string_(output); + +// This flags control whether Google Test prints the elapsed time for each +// test. +GTEST_DECLARE_bool_(print_time); + +// This flag specifies the random number seed. +GTEST_DECLARE_int32_(random_seed); + +// This flag sets how many times the tests are repeated. The default value +// is 1. If the value is -1 the tests are repeating forever. +GTEST_DECLARE_int32_(repeat); + +// This flag controls whether Google Test includes Google Test internal +// stack frames in failure stack traces. +GTEST_DECLARE_bool_(show_internal_stack_frames); + +// When this flag is specified, tests' order is randomized on every iteration. +GTEST_DECLARE_bool_(shuffle); + +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// When this flag is specified, a failed assertion will throw an +// exception if exceptions are enabled, or exit the program with a +// non-zero code otherwise. +GTEST_DECLARE_bool_(throw_on_failure); + +// When this flag is set with a "host:port" string, on supported +// platforms test results are streamed to the specified port on +// the specified host machine. +GTEST_DECLARE_string_(stream_result_to); + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + +namespace internal { + +class AssertHelper; +class DefaultGlobalTestPartResultReporter; +class ExecDeathTest; +class NoExecDeathTest; +class FinalSuccessChecker; +class GTestFlagSaver; +class TestResultAccessor; +class TestEventListenersAccessor; +class TestEventRepeater; +class WindowsDeathTest; +class UnitTestImpl* GetUnitTestImpl(); +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message); + +// Converts a streamable value to an std::string. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared in gtest-internal.h but defined here, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +std::string StreamableToString(const T& streamable) { + return (Message() << streamable).GetString(); +} + +} // namespace internal + +// The friend relationship of some of these classes is cyclic. +// If we don't forward declare them the compiler might confuse the classes +// in friendship clauses with same named classes on the scope. +class Test; +class TestCase; +class TestInfo; +class UnitTest; + +// A class for indicating whether an assertion was successful. When +// the assertion wasn't successful, the AssertionResult object +// remembers a non-empty message that describes how it failed. +// +// To create an instance of this class, use one of the factory functions +// (AssertionSuccess() and AssertionFailure()). +// +// This class is useful for two purposes: +// 1. Defining predicate functions to be used with Boolean test assertions +// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts +// 2. Defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// For example, if you define IsEven predicate: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) +// will print the message +// +// Value of: IsEven(Fib(5)) +// Actual: false (5 is odd) +// Expected: true +// +// instead of a more opaque +// +// Value of: IsEven(Fib(5)) +// Actual: false +// Expected: true +// +// in case IsEven is a simple Boolean predicate. +// +// If you expect your predicate to be reused and want to support informative +// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up +// about half as often as positive ones in our tests), supply messages for +// both success and failure cases: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess() << n << " is even"; +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print +// +// Value of: IsEven(Fib(6)) +// Actual: true (8 is even) +// Expected: false +// +// NB: Predicates that support negative Boolean assertions have reduced +// performance in positive ones so be careful not to use them in tests +// that have lots (tens of thousands) of positive Boolean assertions. +// +// To use this class with EXPECT_PRED_FORMAT assertions such as: +// +// // Verifies that Foo() returns an even number. +// EXPECT_PRED_FORMAT1(IsEven, Foo()); +// +// you need to define: +// +// testing::AssertionResult IsEven(const char* expr, int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() +// << "Expected: " << expr << " is even\n Actual: it's " << n; +// } +// +// If Foo() returns 5, you will see the following message: +// +// Expected: Foo() is even +// Actual: it's 5 +// +class GTEST_API_ AssertionResult { + public: + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + // Used in the EXPECT_TRUE/FALSE(bool_expression). + explicit AssertionResult(bool success) : success_(success) {} + + // Returns true iff the assertion succeeded. + operator bool() const { return success_; } // NOLINT + + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; + + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const { + return message_.get() != NULL ? message_->c_str() : ""; + } + // TODO(vladl@google.com): Remove this after making sure no clients use it. + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } + + // Streams a custom failure message into this object. + template AssertionResult& operator<<(const T& value) { + AppendMessage(Message() << value); + return *this; + } + + // Allows streaming basic output manipulators such as endl or flush into + // this object. + AssertionResult& operator<<( + ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { + AppendMessage(Message() << basic_manipulator); + return *this; + } + + private: + // Appends the contents of message to message_. + void AppendMessage(const Message& a_message) { + if (message_.get() == NULL) + message_.reset(new ::std::string); + message_->append(a_message.GetString().c_str()); + } + + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + internal::scoped_ptr< ::std::string> message_; + + GTEST_DISALLOW_ASSIGN_(AssertionResult); +}; + +// Makes a successful assertion result. +GTEST_API_ AssertionResult AssertionSuccess(); + +// Makes a failed assertion result. +GTEST_API_ AssertionResult AssertionFailure(); + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << msg. +GTEST_API_ AssertionResult AssertionFailure(const Message& msg); + +// The abstract class that all tests inherit from. +// +// In Google Test, a unit test program contains one or many TestCases, and +// each TestCase contains one or many Tests. +// +// When you define a test using the TEST macro, you don't need to +// explicitly derive from Test - the TEST macro automatically does +// this for you. +// +// The only time you derive from Test is when defining a test fixture +// to be used a TEST_F. For example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { ... } +// virtual void TearDown() { ... } +// ... +// }; +// +// TEST_F(FooTest, Bar) { ... } +// TEST_F(FooTest, Baz) { ... } +// +// Test is not copyable. +class GTEST_API_ Test { + public: + friend class TestInfo; + + // Defines types for pointers to functions that set up and tear down + // a test case. + typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; + typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; + + // The d'tor is virtual as we intend to inherit from Test. + virtual ~Test(); + + // Sets up the stuff shared by all tests in this test case. + // + // Google Test will call Foo::SetUpTestCase() before running the first + // test in test case Foo. Hence a sub-class can define its own + // SetUpTestCase() method to shadow the one defined in the super + // class. + static void SetUpTestCase() {} + + // Tears down the stuff shared by all tests in this test case. + // + // Google Test will call Foo::TearDownTestCase() after running the last + // test in test case Foo. Hence a sub-class can define its own + // TearDownTestCase() method to shadow the one defined in the super + // class. + static void TearDownTestCase() {} + + // Returns true iff the current test has a fatal failure. + static bool HasFatalFailure(); + + // Returns true iff the current test has a non-fatal failure. + static bool HasNonfatalFailure(); + + // Returns true iff the current test has a (either fatal or + // non-fatal) failure. + static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } + + // Logs a property for the current test. Only the last value for a given + // key is remembered. + // These are public static so they can be called from utility functions + // that are not members of the test fixture. + // The arguments are const char* instead strings, as Google Test is used + // on platforms where string doesn't compile. + // + // Note that a driving consideration for these RecordProperty methods + // was to produce xml output suited to the Greenspan charting utility, + // which at present will only chart values that fit in a 32-bit int. It + // is the user's responsibility to restrict their values to 32-bit ints + // if they intend them to be used with Greenspan. + static void RecordProperty(const char* key, const char* value); + static void RecordProperty(const char* key, int value); + + protected: + // Creates a Test object. + Test(); + + // Sets up the test fixture. + virtual void SetUp(); + + // Tears down the test fixture. + virtual void TearDown(); + + private: + // Returns true iff the current test has the same fixture class as + // the first test in the current test case. + static bool HasSameFixtureClass(); + + // Runs the test after the test fixture has been set up. + // + // A sub-class must implement this to define the test logic. + // + // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. + // Instead, use the TEST or TEST_F macro. + virtual void TestBody() = 0; + + // Sets up, executes, and tears down the test. + void Run(); + + // Deletes self. We deliberately pick an unusual name for this + // internal method to avoid clashing with names used in user TESTs. + void DeleteSelf_() { delete this; } + + // Uses a GTestFlagSaver to save and restore all Google Test flags. + const internal::GTestFlagSaver* const gtest_flag_saver_; + + // Often a user mis-spells SetUp() as Setup() and spends a long time + // wondering why it is never called by Google Test. The declaration of + // the following method is solely for catching such an error at + // compile time: + // + // - The return type is deliberately chosen to be not void, so it + // will be a conflict if a user declares void Setup() in his test + // fixture. + // + // - This method is private, so it will be another compiler error + // if a user calls it from his test fixture. + // + // DO NOT OVERRIDE THIS FUNCTION. + // + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } + + // We disallow copying Tests. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); +}; + +typedef internal::TimeInMillis TimeInMillis; + +// A copyable object representing a user specified test property which can be +// output as a key/value string pair. +// +// Don't inherit from TestProperty as its destructor is not virtual. +class TestProperty { + public: + // C'tor. TestProperty does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestProperty object. + TestProperty(const char* a_key, const char* a_value) : + key_(a_key), value_(a_value) { + } + + // Gets the user supplied key. + const char* key() const { + return key_.c_str(); + } + + // Gets the user supplied value. + const char* value() const { + return value_.c_str(); + } + + // Sets a new value, overriding the one supplied in the constructor. + void SetValue(const char* new_value) { + value_ = new_value; + } + + private: + // The key supplied by the user. + std::string key_; + // The value supplied by the user. + std::string value_; +}; + +// The result of a single Test. This includes a list of +// TestPartResults, a list of TestProperties, a count of how many +// death tests there are in the Test, and how much time it took to run +// the Test. +// +// TestResult is not copyable. +class GTEST_API_ TestResult { + public: + // Creates an empty TestResult. + TestResult(); + + // D'tor. Do not inherit from TestResult. + ~TestResult(); + + // Gets the number of all test parts. This is the sum of the number + // of successful test parts and the number of failed test parts. + int total_part_count() const; + + // Returns the number of the test properties. + int test_property_count() const; + + // Returns true iff the test passed (i.e. no test part failed). + bool Passed() const { return !Failed(); } + + // Returns true iff the test failed. + bool Failed() const; + + // Returns true iff the test fatally failed. + bool HasFatalFailure() const; + + // Returns true iff the test has a non-fatal failure. + bool HasNonfatalFailure() const; + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test part result among all the results. i can range + // from 0 to test_property_count() - 1. If i is not in that range, aborts + // the program. + const TestPartResult& GetTestPartResult(int i) const; + + // Returns the i-th test property. i can range from 0 to + // test_property_count() - 1. If i is not in that range, aborts the + // program. + const TestProperty& GetTestProperty(int i) const; + + private: + friend class TestInfo; + friend class UnitTest; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::ExecDeathTest; + friend class internal::TestResultAccessor; + friend class internal::UnitTestImpl; + friend class internal::WindowsDeathTest; + + // Gets the vector of TestPartResults. + const std::vector& test_part_results() const { + return test_part_results_; + } + + // Gets the vector of TestProperties. + const std::vector& test_properties() const { + return test_properties_; + } + + // Sets the elapsed time. + void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } + + // Adds a test property to the list. The property is validated and may add + // a non-fatal failure if invalid (e.g., if it conflicts with reserved + // key names). If a property is already recorded for the same key, the + // value will be updated, rather than storing multiple values for the same + // key. + void RecordProperty(const TestProperty& test_property); + + // Adds a failure if the key is a reserved attribute of Google Test + // testcase tags. Returns true if the property is valid. + // TODO(russr): Validate attribute names are legal and human readable. + static bool ValidateTestProperty(const TestProperty& test_property); + + // Adds a test part result to the list. + void AddTestPartResult(const TestPartResult& test_part_result); + + // Returns the death test count. + int death_test_count() const { return death_test_count_; } + + // Increments the death test count, returning the new count. + int increment_death_test_count() { return ++death_test_count_; } + + // Clears the test part results. + void ClearTestPartResults(); + + // Clears the object. + void Clear(); + + // Protects mutable state of the property vector and of owned + // properties, whose values may be updated. + internal::Mutex test_properites_mutex_; + + // The vector of TestPartResults + std::vector test_part_results_; + // The vector of TestProperties + std::vector test_properties_; + // Running count of death tests. + int death_test_count_; + // The elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestResult. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); +}; // class TestResult + +// A TestInfo object stores the following information about a test: +// +// Test case name +// Test name +// Whether the test should be run +// A function pointer that creates the test object when invoked +// Test result +// +// The constructor of TestInfo registers itself with the UnitTest +// singleton such that the RUN_ALL_TESTS() macro knows which tests to +// run. +class GTEST_API_ TestInfo { + public: + // Destructs a TestInfo object. This function is not virtual, so + // don't inherit from TestInfo. + ~TestInfo(); + + // Returns the test case name. + const char* test_case_name() const { return test_case_name_.c_str(); } + + // Returns the test name. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a typed + // or a type-parameterized test. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } + + // Returns the text representation of the value parameter, or NULL if this + // is not a value-parameterized test. + const char* value_param() const { + if (value_param_.get() != NULL) + return value_param_->c_str(); + return NULL; + } + + // Returns true if this test should run, that is if the test is not disabled + // (or it is disabled but the also_run_disabled_tests flag has been specified) + // and its full name matches the user-specified filter. + // + // Google Test allows the user to filter the tests by their full names. + // The full name of a test Bar in test case Foo is defined as + // "Foo.Bar". Only the tests that match the filter will run. + // + // A filter is a colon-separated list of glob (not regex) patterns, + // optionally followed by a '-' and a colon-separated list of + // negative patterns (tests to exclude). A test is run if it + // matches one of the positive patterns and does not match any of + // the negative patterns. + // + // For example, *A*:Foo.* is a filter that matches any string that + // contains the character 'A' or starts with "Foo.". + bool should_run() const { return should_run_; } + + // Returns the result of the test. + const TestResult* result() const { return &result_; } + + private: +#if GTEST_HAS_DEATH_TEST + friend class internal::DefaultDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + friend class Test; + friend class TestCase; + friend class internal::UnitTestImpl; + friend TestInfo* internal::MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* type_param, + const char* value_param, + internal::TypeId fixture_class_id, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + internal::TestFactoryBase* factory); + + // Constructs a TestInfo object. The newly constructed instance assumes + // ownership of the factory object. + TestInfo(const char* test_case_name, const char* name, + const char* a_type_param, + const char* a_value_param, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory); + + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count() { + return result_.increment_death_test_count(); + } + + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); + + static void ClearTestResult(TestInfo* test_info) { + test_info->result_.Clear(); + } + + // These fields are immutable properties of the test. + const std::string test_case_name_; // Test case name + const std::string name_; // Test name + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; + // Text representation of the value parameter, or NULL if this is not a + // value-parameterized test. + const internal::scoped_ptr value_param_; + const internal::TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True iff this test should run + bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object + + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); +}; + +// A test case, which consists of a vector of TestInfos. +// +// TestCase is not copyable. +class GTEST_API_ TestCase { + public: + // Creates a TestCase with the given name. + // + // TestCase does NOT have a default constructor. Always use this + // constructor to create a TestCase object. + // + // Arguments: + // + // name: name of the test case + // a_type_param: the name of the test's type parameter, or NULL if + // this is not a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase(const char* name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Destructor of TestCase. + virtual ~TestCase(); + + // Gets the name of the TestCase. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a + // type-parameterized test case. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } + + // Returns true if any test in this test case should run. + bool should_run() const { return should_run_; } + + // Gets the number of successful tests in this test case. + int successful_test_count() const; + + // Gets the number of failed tests in this test case. + int failed_test_count() const; + + // Gets the number of disabled tests in this test case. + int disabled_test_count() const; + + // Get the number of tests in this test case that should run. + int test_to_run_count() const; + + // Gets the number of all tests in this test case. + int total_test_count() const; + + // Returns true iff the test case passed. + bool Passed() const { return !Failed(); } + + // Returns true iff the test case failed. + bool Failed() const { return failed_test_count() > 0; } + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + const TestInfo* GetTestInfo(int i) const; + + private: + friend class Test; + friend class internal::UnitTestImpl; + + // Gets the (mutable) vector of TestInfos in this TestCase. + std::vector& test_info_list() { return test_info_list_; } + + // Gets the (immutable) vector of TestInfos in this TestCase. + const std::vector& test_info_list() const { + return test_info_list_; + } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Adds a TestInfo to this test case. Will delete the TestInfo upon + // destruction of the TestCase object. + void AddTestInfo(TestInfo * test_info); + + // Clears the results of all tests in this test case. + void ClearResult(); + + // Clears the results of all tests in the given test case. + static void ClearTestCaseResult(TestCase* test_case) { + test_case->ClearResult(); + } + + // Runs every test in this TestCase. + void Run(); + + // Runs SetUpTestCase() for this TestCase. This wrapper is needed + // for catching exceptions thrown from SetUpTestCase(). + void RunSetUpTestCase() { (*set_up_tc_)(); } + + // Runs TearDownTestCase() for this TestCase. This wrapper is + // needed for catching exceptions thrown from TearDownTestCase(). + void RunTearDownTestCase() { (*tear_down_tc_)(); } + + // Returns true iff test passed. + static bool TestPassed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Passed(); + } + + // Returns true iff test failed. + static bool TestFailed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Failed(); + } + + // Returns true iff test is disabled. + static bool TestDisabled(const TestInfo* test_info) { + return test_info->is_disabled_; + } + + // Returns true if the given test should run. + static bool ShouldRunTest(const TestInfo* test_info) { + return test_info->should_run(); + } + + // Shuffles the tests in this test case. + void ShuffleTests(internal::Random* random); + + // Restores the test order to before the first shuffle. + void UnshuffleTests(); + + // Name of the test case. + std::string name_; + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + std::vector test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + std::vector test_indices_; + // Pointer to the function that sets up the test case. + Test::SetUpTestCaseFunc set_up_tc_; + // Pointer to the function that tears down the test case. + Test::TearDownTestCaseFunc tear_down_tc_; + // True iff any test in this test case should run. + bool should_run_; + // Elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestCases. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); +}; + +// An Environment object is capable of setting up and tearing down an +// environment. The user should subclass this to define his own +// environment(s). +// +// An Environment object does the set-up and tear-down in virtual +// methods SetUp() and TearDown() instead of the constructor and the +// destructor, as: +// +// 1. You cannot safely throw from a destructor. This is a problem +// as in some cases Google Test is used where exceptions are enabled, and +// we may want to implement ASSERT_* using exceptions where they are +// available. +// 2. You cannot use ASSERT_* directly in a constructor or +// destructor. +class Environment { + public: + // The d'tor is virtual as we need to subclass Environment. + virtual ~Environment() {} + + // Override this to define how to set up the environment. + virtual void SetUp() {} + + // Override this to define how to tear down the environment. + virtual void TearDown() {} + private: + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } +}; + +// The interface for tracing execution of tests. The methods are organized in +// the order the corresponding events are fired. +class TestEventListener { + public: + virtual ~TestEventListener() {} + + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; + + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + + // Fired before the test case starts. + virtual void OnTestCaseStart(const TestCase& test_case) = 0; + + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; + + // Fired after a failed assertion or a SUCCEED() invocation. + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; + + // Fired after the test case ends. + virtual void OnTestCaseEnd(const TestCase& test_case) = 0; + + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; + + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; +}; + +// The convenience class for users who need to override just one or two +// methods and are not concerned that a possible change to a signature of +// the methods they override will not be caught during the build. For +// comments about each method please see the definition of TestEventListener +// above. +class EmptyTestEventListener : public TestEventListener { + public: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +}; + +// TestEventListeners lets users add listeners to track events in Google Test. +class GTEST_API_ TestEventListeners { + public: + TestEventListeners(); + ~TestEventListeners(); + + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); + + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); + + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const { + return default_result_printer_; + } + + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const { + return default_xml_generator_; + } + + private: + friend class TestCase; + friend class TestInfo; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::UnitTestImpl; + + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); + + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); + + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); + + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); + + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; + + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); +}; + +// A UnitTest consists of a vector of TestCases. +// +// This is a singleton class. The only instance of UnitTest is +// created when UnitTest::GetInstance() is first called. This +// instance is never deleted. +// +// UnitTest is not copyable. +// +// This class is thread-safe as long as the methods are called +// according to their specification. +class GTEST_API_ UnitTest { + public: + // Gets the singleton UnitTest object. The first time this method + // is called, a UnitTest object is constructed and returned. + // Consecutive calls will return the same object. + static UnitTest* GetInstance(); + + // Runs all tests in this UnitTest object and prints the result. + // Returns 0 if successful, or 1 otherwise. + // + // This method can only be called from the main thread. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + int Run() GTEST_MUST_USE_RESULT_; + + // Returns the working directory when the first TEST() or TEST_F() + // was executed. The UnitTest object owns the string. + const char* original_working_dir() const; + + // Returns the TestCase object for the test that's currently running, + // or NULL if no test is running. + const TestCase* current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_); + + // Returns the TestInfo object for the test that's currently running, + // or NULL if no test is running. + const TestInfo* current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_); + + // Returns the random seed used at the start of the current test run. + int random_seed() const; + +#if GTEST_HAS_PARAM_TEST + // Returns the ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_); +#endif // GTEST_HAS_PARAM_TEST + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const; + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const; + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const; + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const; + + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); + + private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); + + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) + GTEST_LOCK_EXCLUDED_(mutex_); + + // Adds a TestProperty to the current TestResult object. If the result already + // contains a property with the same key, the value will be updated. + void RecordPropertyForCurrentTest(const char* key, const char* value); + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i); + + // Accessors for the implementation object. + internal::UnitTestImpl* impl() { return impl_; } + const internal::UnitTestImpl* impl() const { return impl_; } + + // These classes and funcions are friends as they need to access private + // members of UnitTest. + friend class Test; + friend class internal::AssertHelper; + friend class internal::ScopedTrace; + friend Environment* AddGlobalTestEnvironment(Environment* env); + friend internal::UnitTestImpl* internal::GetUnitTestImpl(); + friend void internal::ReportFailureInUnknownLocation( + TestPartResult::Type result_type, + const std::string& message); + + // Creates an empty UnitTest. + UnitTest(); + + // D'tor + virtual ~UnitTest(); + + // Pushes a trace defined by SCOPED_TRACE() on to the per-thread + // Google Test trace stack. + void PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_); + + // Pops a trace from the per-thread Google Test trace stack. + void PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_); + + // Protects mutable state in *impl_. This is mutable as some const + // methods need to lock it too. + mutable internal::Mutex mutex_; + + // Opaque implementation object. This field is never changed once + // the object is constructed. We don't mark it as const here, as + // doing so will cause a warning in the constructor of UnitTest. + // Mutable state in *impl_ is protected by mutex_. + internal::UnitTestImpl* impl_; + + // We disallow copying UnitTest. + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); +}; + +// A convenient wrapper for adding an environment for the test +// program. +// +// You should call this before RUN_ALL_TESTS() is called, probably in +// main(). If you use gtest_main, you need to call this before main() +// starts for it to take effect. For example, you can define a global +// variable like this: +// +// testing::Environment* const foo_env = +// testing::AddGlobalTestEnvironment(new FooEnvironment); +// +// However, we strongly recommend you to write your own main() and +// call AddGlobalTestEnvironment() there, as relying on initialization +// of global variables makes the code harder to read and may cause +// problems when you register multiple environments from different +// translation units and the environments have dependencies among them +// (remember that the compiler doesn't guarantee the order in which +// global variables from different translation units are initialized). +inline Environment* AddGlobalTestEnvironment(Environment* env) { + return UnitTest::GetInstance()->AddEnvironment(env); +} + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +GTEST_API_ void InitGoogleTest(int* argc, char** argv); + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); + +namespace internal { + +// FormatForComparison::Format(value) formats a +// value of type ToPrint that is an operand of a comparison assertion +// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in +// the comparison, and is used to help determine the best way to +// format the value. In particular, when the value is a C string +// (char pointer) and the other operand is an STL string object, we +// want to format the C string as a string, since we know it is +// compared by value with the string object. If the value is a char +// pointer but the other operand is not an STL string object, we don't +// know whether the pointer is supposed to point to a NUL-terminated +// string, and thus want to print it as a pointer to be safe. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// The default case. +template +class FormatForComparison { + public: + static ::std::string Format(const ToPrint& value) { + return ::testing::PrintToString(value); + } +}; + +// Array. +template +class FormatForComparison { + public: + static ::std::string Format(const ToPrint* value) { + return FormatForComparison::Format(value); + } +}; + +// By default, print C string as pointers to be safe, as we don't know +// whether they actually point to a NUL-terminated string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ + template \ + class FormatForComparison { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(static_cast(value)); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ + +// If a C string is compared with an STL string object, we know it's meant +// to point to a NUL-terminated string, and thus can print it as a string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ + template <> \ + class FormatForComparison { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(value); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); + +#if GTEST_HAS_GLOBAL_STRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); +#endif + +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); +#endif + +#if GTEST_HAS_STD_WSTRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); +#endif + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ + +// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) +// operand to be used in a failure message. The type (but not value) +// of the other operand may affect the format. This allows us to +// print a char* as a raw pointer when it is compared against another +// char* or void*, and print it as a C string when it is compared +// against an std::string object, for example. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +std::string FormatForComparisonFailureMessage( + const T1& value, const T2& /* other_operand */) { + return FormatForComparison::Format(value); +} + +// The helper function for {ASSERT|EXPECT}_EQ. +template +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4389) // Temporarily disables warning on + // signed/unsigned mismatch. +#endif + + if (expected == actual) { + return AssertionSuccess(); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// With this overloaded version, we allow anonymous enums to be used +// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums +// can be implicitly cast to BiggestInt. +GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual); + +// The helper class for {ASSERT|EXPECT}_EQ. The template argument +// lhs_is_null_literal is true iff the first argument to ASSERT_EQ() +// is a null pointer literal. The following default implementation is +// for lhs_is_null_literal being false. +template +class EqHelper { + public: + // This templatized version is for the general case. + template + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // With this overloaded version, we allow anonymous enums to be used + // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous + // enums can be implicitly cast to BiggestInt. + // + // Even though its body looks the same as the above version, we + // cannot merge the two, as it will make anonymous enums unhappy. + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } +}; + +// This specialization is used when the first argument to ASSERT_EQ() +// is a null pointer literal, like NULL, false, or 0. +template <> +class EqHelper { + public: + // We define two overloaded versions of Compare(). The first + // version will be picked when the second argument to ASSERT_EQ() is + // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or + // EXPECT_EQ(false, a_bool). + template + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual, + // The following line prevents this overload from being considered if T2 + // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) + // expands to Compare("", "", NULL, my_ptr), which requires a conversion + // to match the Secret* in the other overload, which would otherwise make + // this template match better. + typename EnableIf::value>::type* = 0) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // This version will be picked when the second argument to ASSERT_EQ() is a + // pointer, e.g. ASSERT_EQ(NULL, a_pointer). + template + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + // We used to have a second template parameter instead of Secret*. That + // template parameter would deduce to 'long', making this a better match + // than the first overload even without the first overload's EnableIf. + // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to + // non-pointer argument" (even a deduced integral argument), so the old + // implementation caused warnings in user code. + Secret* /* expected (NULL) */, + T* actual) { + // We already know that 'expected' is a null pointer. + return CmpHelperEQ(expected_expression, actual_expression, + static_cast(NULL), actual); + } +}; + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste +// of similar code. +// +// For each templatized helper function, we also define an overloaded +// version for BiggestInt in order to reduce code bloat and allow +// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled +// with gcc 4. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +template \ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + const T1& val1, const T2& val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +}\ +GTEST_API_ AssertionResult CmpHelper##op_name(\ + const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) + +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// Implements the helper function for {ASSERT|EXPECT}_NE +GTEST_IMPL_CMP_HELPER_(NE, !=); +// Implements the helper function for {ASSERT|EXPECT}_LE +GTEST_IMPL_CMP_HELPER_(LE, <=); +// Implements the helper function for {ASSERT|EXPECT}_LT +GTEST_IMPL_CMP_HELPER_(LT, <); +// Implements the helper function for {ASSERT|EXPECT}_GE +GTEST_IMPL_CMP_HELPER_(GE, >=); +// Implements the helper function for {ASSERT|EXPECT}_GT +GTEST_IMPL_CMP_HELPER_(GT, >); + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRNE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + + +// Helper function for *_STREQ on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual); + +// Helper function for *_STRNE on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); + +} // namespace internal + +// IsSubstring() and IsNotSubstring() are intended to be used as the +// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by +// themselves. They check whether needle is a substring of haystack +// (NULL is considered a substring of itself only), and return an +// appropriate error message when they fail. +// +// The {needle,haystack}_expr arguments are the stringified +// expressions that generated the two real arguments. +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +// Helper template function for comparing floating-points. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, + const char* actual_expression, + RawType expected, + RawType actual) { + const FloatingPoint lhs(expected), rhs(actual); + + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + ::std::stringstream expected_ss; + expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << expected; + + ::std::stringstream actual_ss; + actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << actual; + + return EqFailure(expected_expression, + actual_expression, + StringStreamToString(&expected_ss), + StringStreamToString(&actual_ss), + false); +} + +// Helper function for implementing ASSERT_NEAR. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// A class that enables one to stream messages to assertion macros +class GTEST_API_ AssertHelper { + public: + // Constructor. + AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message); + ~AssertHelper(); + + // Message assignment is a semantic trick to enable assertion + // streaming; see the GTEST_MESSAGE_ macro below. + void operator=(const Message& message) const; + + private: + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) { } + + TestPartResult::Type const type; + const char* const file; + int const line; + std::string const message; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; + + AssertHelperData* const data_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); +}; + +} // namespace internal + +#if GTEST_HAS_PARAM_TEST +// The pure interface class that all value-parameterized tests inherit from. +// A value-parameterized class must inherit from both ::testing::Test and +// ::testing::WithParamInterface. In most cases that just means inheriting +// from ::testing::TestWithParam, but more complicated test hierarchies +// may need to inherit from Test and WithParamInterface at different levels. +// +// This interface has support for accessing the test parameter value via +// the GetParam() method. +// +// Use it with one of the parameter generator defining functions, like Range(), +// Values(), ValuesIn(), Bool(), and Combine(). +// +// class FooTest : public ::testing::TestWithParam { +// protected: +// FooTest() { +// // Can use GetParam() here. +// } +// virtual ~FooTest() { +// // Can use GetParam() here. +// } +// virtual void SetUp() { +// // Can use GetParam() here. +// } +// virtual void TearDown { +// // Can use GetParam() here. +// } +// }; +// TEST_P(FooTest, DoesBar) { +// // Can use GetParam() method here. +// Foo foo; +// ASSERT_TRUE(foo.DoesBar(GetParam())); +// } +// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); + +template +class WithParamInterface { + public: + typedef T ParamType; + virtual ~WithParamInterface() {} + + // The current parameter value. Is also available in the test fixture's + // constructor. This member function is non-static, even though it only + // references static data, to reduce the opportunity for incorrect uses + // like writing 'WithParamInterface::GetParam()' for a test that + // uses a fixture whose parameter type is int. + const ParamType& GetParam() const { return *parameter_; } + + private: + // Sets parameter value. The caller is responsible for making sure the value + // remains alive and unchanged throughout the current test. + static void SetParam(const ParamType* parameter) { + parameter_ = parameter; + } + + // Static value used for accessing parameter during a test lifetime. + static const ParamType* parameter_; + + // TestClass must be a subclass of WithParamInterface and Test. + template friend class internal::ParameterizedTestFactory; +}; + +template +const T* WithParamInterface::parameter_ = NULL; + +// Most value-parameterized classes can ignore the existence of +// WithParamInterface, and can just inherit from ::testing::TestWithParam. + +template +class TestWithParam : public Test, public WithParamInterface { +}; + +#endif // GTEST_HAS_PARAM_TEST + +// Macros for indicating success/failure in test code. + +// ADD_FAILURE unconditionally adds a failure to the current test. +// SUCCEED generates a success - it doesn't automatically make the +// current test successful, as a test is only successful when it has +// no failure. +// +// EXPECT_* verifies that a certain condition is satisfied. If not, +// it behaves like ADD_FAILURE. In particular: +// +// EXPECT_TRUE verifies that a Boolean condition is true. +// EXPECT_FALSE verifies that a Boolean condition is false. +// +// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except +// that they will also abort the current function on failure. People +// usually want the fail-fast behavior of FAIL and ASSERT_*, but those +// writing data-driven tests often find themselves using ADD_FAILURE +// and EXPECT_* more. + +// Generates a nonfatal failure with a generic message. +#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") + +// Generates a nonfatal failure at the given source file location with +// a generic message. +#define ADD_FAILURE_AT(file, line) \ + GTEST_MESSAGE_AT_(file, line, "Failed", \ + ::testing::TestPartResult::kNonFatalFailure) + +// Generates a fatal failure with a generic message. +#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") + +// Define this macro to 1 to omit the definition of FAIL(), which is a +// generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_FAIL +# define FAIL() GTEST_FAIL() +#endif + +// Generates a success with a generic message. +#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") + +// Define this macro to 1 to omit the definition of SUCCEED(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_SUCCEED +# define SUCCEED() GTEST_SUCCEED() +#endif + +// Macros for testing exceptions. +// +// * {ASSERT|EXPECT}_THROW(statement, expected_exception): +// Tests that the statement throws the expected exception. +// * {ASSERT|EXPECT}_NO_THROW(statement): +// Tests that the statement doesn't throw any exception. +// * {ASSERT|EXPECT}_ANY_THROW(statement): +// Tests that the statement throws an exception. + +#define EXPECT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) +#define EXPECT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define EXPECT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define ASSERT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) +#define ASSERT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) +#define ASSERT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) + +// Boolean assertions. Condition can be either a Boolean expression or an +// AssertionResult. For more information on how to use AssertionResult with +// these macros see comments on that class. +#define EXPECT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_NONFATAL_FAILURE_) +#define EXPECT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_NONFATAL_FAILURE_) +#define ASSERT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_FATAL_FAILURE_) +#define ASSERT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_FATAL_FAILURE_) + +// Includes the auto-generated header that implements a family of +// generic predicate assertion macros. +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Makes sure this header is not included before gtest.h. +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most 5. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar = (expression)) \ + ; \ + else \ + on_failure(gtest_ar.failure_message()) + + +// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +template +AssertionResult AssertPred1Helper(const char* pred_text, + const char* e1, + Pred pred, + const T1& v1) { + if (pred(v1)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. +// Don't use this in your code. +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, v1), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +#define GTEST_PRED1_(pred, v1, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ + #v1, \ + pred, \ + v1), on_failure) + +// Unary predicate assertion macros. +#define EXPECT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +template +AssertionResult AssertPred2Helper(const char* pred_text, + const char* e1, + const char* e2, + Pred pred, + const T1& v1, + const T2& v2) { + if (pred(v1, v2)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. +// Don't use this in your code. +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +#define GTEST_PRED2_(pred, v1, v2, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ + #v1, \ + #v2, \ + pred, \ + v1, \ + v2), on_failure) + +// Binary predicate assertion macros. +#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +template +AssertionResult AssertPred3Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3) { + if (pred(v1, v2, v3)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. +// Don't use this in your code. +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + pred, \ + v1, \ + v2, \ + v3), on_failure) + +// Ternary predicate assertion macros. +#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +template +AssertionResult AssertPred4Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (pred(v1, v2, v3, v4)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. +// Don't use this in your code. +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4), on_failure) + +// 4-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +template +AssertionResult AssertPred5Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ", " + << e5 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4 + << "\n" << e5 << " evaluates to " << v5; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. +// Don't use this in your code. +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + #v5, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4, \ + v5), on_failure) + +// 5-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) + + + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Macros for testing equalities and inequalities. +// +// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual +// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 +// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 +// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 +// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 +// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 +// +// When they are not, Google Test prints both the tested expressions and +// their actual values. The values must be compatible built-in types, +// or you will get a compiler error. By "compatible" we mean that the +// values can be compared by the respective operator. +// +// Note: +// +// 1. It is possible to make a user-defined type work with +// {ASSERT|EXPECT}_??(), but that requires overloading the +// comparison operators and is thus discouraged by the Google C++ +// Usage Guide. Therefore, you are advised to use the +// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are +// equal. +// +// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on +// pointers (in particular, C strings). Therefore, if you use it +// with two C strings, you are testing how their locations in memory +// are related, not how their content is related. To compare two C +// strings by content, use {ASSERT|EXPECT}_STR*(). +// +// 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to +// {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you +// what the actual value is when it fails, and similarly for the +// other comparisons. +// +// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() +// evaluate their arguments, which is undefined. +// +// 5. These macros evaluate their arguments exactly once. +// +// Examples: +// +// EXPECT_NE(5, Foo()); +// EXPECT_EQ(NULL, a_pointer); +// ASSERT_LT(i, array_size); +// ASSERT_GT(records.size(), 0) << "There is no record left."; + +#define EXPECT_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define EXPECT_NE(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) +#define EXPECT_LE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define EXPECT_LT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define EXPECT_GE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define EXPECT_GT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +#define GTEST_ASSERT_EQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define GTEST_ASSERT_NE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) +#define GTEST_ASSERT_LE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define GTEST_ASSERT_LT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define GTEST_ASSERT_GE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define GTEST_ASSERT_GT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of +// ASSERT_XY(), which clashes with some users' own code. + +#if !GTEST_DONT_DEFINE_ASSERT_EQ +# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_NE +# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LE +# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LT +# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GE +# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GT +# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) +#endif + +// C-string Comparisons. All tests treat NULL and any non-NULL string +// as different. Two NULLs are equal. +// +// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 +// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 +// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case +// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case +// +// For wide or narrow string objects, you can use the +// {ASSERT|EXPECT}_??() macros. +// +// Don't depend on the order in which the arguments are evaluated, +// which is undefined. +// +// These macros evaluate their arguments exactly once. + +#define EXPECT_STREQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define EXPECT_STRNE(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define EXPECT_STRCASEEQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define EXPECT_STRCASENE(s1, s2)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +#define ASSERT_STREQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define ASSERT_STRNE(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define ASSERT_STRCASEEQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define ASSERT_STRCASENE(s1, s2)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +// Macros for comparing floating-point numbers. +// +// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): +// Tests that two float values are almost equal. +// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): +// Tests that two double values are almost equal. +// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): +// Tests that v1 and v2 are within the given distance to each other. +// +// Google Test uses ULP-based comparison to automatically pick a default +// error bound that is appropriate for the operands. See the +// FloatingPoint template class in gtest-internal.h if you are +// interested in the implementation details. + +#define EXPECT_FLOAT_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_DOUBLE_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_FLOAT_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_DOUBLE_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_NEAR(val1, val2, abs_error)\ + EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +#define ASSERT_NEAR(val1, val2, abs_error)\ + ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +// These predicate format functions work on floating-point values, and +// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. +// +// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2); +GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2); + + +#if GTEST_OS_WINDOWS + +// Macros that test for HRESULT failure and success, these are only useful +// on Windows, and rely on Windows SDK macros and APIs to compile. +// +// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) +// +// When expr unexpectedly fails or succeeds, Google Test prints the +// expected result and the actual result with both a human-readable +// string representation of the error, if available, as well as the +// hex result code. +# define EXPECT_HRESULT_SUCCEEDED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define ASSERT_HRESULT_SUCCEEDED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define EXPECT_HRESULT_FAILED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +# define ASSERT_HRESULT_FAILED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#endif // GTEST_OS_WINDOWS + +// Macros that execute statement and check that it doesn't generate new fatal +// failures in the current thread. +// +// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); +// +// Examples: +// +// EXPECT_NO_FATAL_FAILURE(Process()); +// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; +// +#define ASSERT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) +#define EXPECT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + +// Causes a trace (including the source file path, the current line +// number, and the given message) to be included in every test failure +// message generated by code in the current scope. The effect is +// undone when the control leaves the current scope. +// +// The message argument can be anything streamable to std::ostream. +// +// In the implementation, we include the current line number as part +// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s +// to appear in the same block - as long as they are on different +// lines. +#define SCOPED_TRACE(message) \ + ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ + __FILE__, __LINE__, ::testing::Message() << (message)) + +// Compile-time assertion for type equality. +// StaticAssertTypeEq() compiles iff type1 and type2 are +// the same type. The value it returns is not interesting. +// +// Instead of making StaticAssertTypeEq a class template, we make it a +// function template that invokes a helper class template. This +// prevents a user from misusing StaticAssertTypeEq by +// defining objects of that type. +// +// CAVEAT: +// +// When used inside a method of a class template, +// StaticAssertTypeEq() is effective ONLY IF the method is +// instantiated. For example, given: +// +// template class Foo { +// public: +// void Bar() { testing::StaticAssertTypeEq(); } +// }; +// +// the code: +// +// void Test1() { Foo foo; } +// +// will NOT generate a compiler error, as Foo::Bar() is never +// actually instantiated. Instead, you need: +// +// void Test2() { Foo foo; foo.Bar(); } +// +// to cause a compiler error. +template +bool StaticAssertTypeEq() { + (void)internal::StaticAssertTypeEqHelper(); + return true; +} + +// Defines a test. +// +// The first parameter is the name of the test case, and the second +// parameter is the name of the test within the test case. +// +// The convention is to end the test case name with "Test". For +// example, a test case for the Foo class can be named FooTest. +// +// The user should put his test code between braces after using this +// macro. Example: +// +// TEST(FooTest, InitializesCorrectly) { +// Foo foo; +// EXPECT_TRUE(foo.StatusIsOK()); +// } + +// Note that we call GetTestTypeId() instead of GetTypeId< +// ::testing::Test>() here to get the type ID of testing::Test. This +// is to work around a suspected linker bug when using Google Test as +// a framework on Mac OS X. The bug causes GetTypeId< +// ::testing::Test>() to return different values depending on whether +// the call is from the Google Test framework itself or from user test +// code. GetTestTypeId() is guaranteed to always return the same +// value, as it always calls GetTypeId<>() from the Google Test +// framework. +#define GTEST_TEST(test_case_name, test_name)\ + GTEST_TEST_(test_case_name, test_name, \ + ::testing::Test, ::testing::internal::GetTestTypeId()) + +// Define this macro to 1 to omit the definition of TEST(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_TEST +# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) +#endif + +// Defines a test that uses a test fixture. +// +// The first parameter is the name of the test fixture class, which +// also doubles as the test case name. The second parameter is the +// name of the test within the test case. +// +// A test fixture class must be declared earlier. The user should put +// his test code between braces after using this macro. Example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { b_.AddElement(3); } +// +// Foo a_; +// Foo b_; +// }; +// +// TEST_F(FooTest, InitializesCorrectly) { +// EXPECT_TRUE(a_.StatusIsOK()); +// } +// +// TEST_F(FooTest, ReturnsElementCountCorrectly) { +// EXPECT_EQ(0, a_.size()); +// EXPECT_EQ(1, b_.size()); +// } + +#define TEST_F(test_fixture, test_name)\ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ + ::testing::internal::GetTypeId()) + +// Use this macro in main() to run all tests. It returns 0 if all +// tests are successful, or 1 otherwise. +// +// RUN_ALL_TESTS() should be invoked after the command line has been +// parsed by InitGoogleTest(). + +#define RUN_ALL_TESTS()\ + (::testing::UnitTest::GetInstance()->Run()) + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest_main.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest_main.cc new file mode 100644 index 0000000..f302822 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/fused-src/gtest/gtest_main.cc @@ -0,0 +1,38 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +#include + +#include "gtest/gtest.h" + +GTEST_API_ int main(int argc, char **argv) { + printf("Running main() from gtest_main.cc\n"); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-death-test.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-death-test.h new file mode 100644 index 0000000..957a69c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-death-test.h @@ -0,0 +1,294 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for death tests. It is +// #included by gtest.h so a user doesn't need to include this +// directly. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ + +#include "gtest/internal/gtest-death-test-internal.h" + +namespace testing { + +// This flag controls the style of death tests. Valid values are "threadsafe", +// meaning that the death test child process will re-execute the test binary +// from the start, running only a single death test, or "fast", +// meaning that the child process will execute the test logic immediately +// after forking. +GTEST_DECLARE_string_(death_test_style); + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +GTEST_API_ bool InDeathTestChild(); + +} // namespace internal + +// The following macros are useful for writing death tests. + +// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is +// executed: +// +// 1. It generates a warning if there is more than one active +// thread. This is because it's safe to fork() or clone() only +// when there is a single thread. +// +// 2. The parent process clone()s a sub-process and runs the death +// test in it; the sub-process exits with code 0 at the end of the +// death test, if it hasn't exited already. +// +// 3. The parent process waits for the sub-process to terminate. +// +// 4. The parent process checks the exit code and error message of +// the sub-process. +// +// Examples: +// +// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); +// for (int i = 0; i < 5; i++) { +// EXPECT_DEATH(server.ProcessRequest(i), +// "Invalid request .* in ProcessRequest()") +// << "Failed to die on request " << i; +// } +// +// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); +// +// bool KilledBySIGHUP(int exit_code) { +// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; +// } +// +// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); +// +// On the regular expressions used in death tests: +// +// On POSIX-compliant systems (*nix), we use the library, +// which uses the POSIX extended regex syntax. +// +// On other platforms (e.g. Windows), we only support a simple regex +// syntax implemented as part of Google Test. This limited +// implementation should be enough most of the time when writing +// death tests; though it lacks many features you can find in PCRE +// or POSIX extended regex syntax. For example, we don't support +// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and +// repetition count ("x{5,7}"), among others. +// +// Below is the syntax that we do support. We chose it to be a +// subset of both PCRE and POSIX extended regex, so it's easy to +// learn wherever you come from. In the following: 'A' denotes a +// literal character, period (.), or a single \\ escape sequence; +// 'x' and 'y' denote regular expressions; 'm' and 'n' are for +// natural numbers. +// +// c matches any literal character c +// \\d matches any decimal digit +// \\D matches any character that's not a decimal digit +// \\f matches \f +// \\n matches \n +// \\r matches \r +// \\s matches any ASCII whitespace, including \n +// \\S matches any character that's not a whitespace +// \\t matches \t +// \\v matches \v +// \\w matches any letter, _, or decimal digit +// \\W matches any character that \\w doesn't match +// \\c matches any literal character c, which must be a punctuation +// . matches any single character except \n +// A? matches 0 or 1 occurrences of A +// A* matches 0 or many occurrences of A +// A+ matches 1 or many occurrences of A +// ^ matches the beginning of a string (not that of each line) +// $ matches the end of a string (not that of each line) +// xy matches x followed by y +// +// If you accidentally use PCRE or POSIX extended regex features +// not implemented by us, you will get a run-time failure. In that +// case, please try to rewrite your regular expression within the +// above syntax. +// +// This implementation is *not* meant to be as highly tuned or robust +// as a compiled regex library, but should perform well enough for a +// death test, which already incurs significant overhead by launching +// a child process. +// +// Known caveats: +// +// A "threadsafe" style death test obtains the path to the test +// program from argv[0] and re-executes it in the sub-process. For +// simplicity, the current implementation doesn't search the PATH +// when launching the sub-process. This means that the user must +// invoke the test program via a path that contains at least one +// path separator (e.g. path/to/foo_test and +// /absolute/path/to/bar_test are fine, but foo_test is not). This +// is rarely a problem as people usually don't put the test binary +// directory in PATH. +// +// TODO(wan@google.com): make thread-safe death tests search the PATH. + +// Asserts that a given statement causes the program to exit, with an +// integer exit status that satisfies predicate, and emitting error output +// that matches regex. +# define ASSERT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) + +// Like ASSERT_EXIT, but continues on to successive tests in the +// test case, if any: +# define EXPECT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) + +// Asserts that a given statement causes the program to exit, either by +// explicitly exiting with a nonzero exit code or being killed by a +// signal, and emitting error output that matches regex. +# define ASSERT_DEATH(statement, regex) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Like ASSERT_DEATH, but continues on to successive tests in the +// test case, if any: +# define EXPECT_DEATH(statement, regex) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: + +// Tests that an exit code describes a normal exit with a given exit code. +class GTEST_API_ ExitedWithCode { + public: + explicit ExitedWithCode(int exit_code); + bool operator()(int exit_status) const; + private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + + const int exit_code_; +}; + +# if !GTEST_OS_WINDOWS +// Tests that an exit code describes an exit due to termination by a +// given signal. +class GTEST_API_ KilledBySignal { + public: + explicit KilledBySignal(int signum); + bool operator()(int exit_status) const; + private: + const int signum_; +}; +# endif // !GTEST_OS_WINDOWS + +// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. +// The death testing framework causes this to have interesting semantics, +// since the sideeffects of the call are only visible in opt mode, and not +// in debug mode. +// +// In practice, this can be used to test functions that utilize the +// LOG(DFATAL) macro using the following style: +// +// int DieInDebugOr12(int* sideeffect) { +// if (sideeffect) { +// *sideeffect = 12; +// } +// LOG(DFATAL) << "death"; +// return 12; +// } +// +// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { +// int sideeffect = 0; +// // Only asserts in dbg. +// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); +// +// #ifdef NDEBUG +// // opt-mode has sideeffect visible. +// EXPECT_EQ(12, sideeffect); +// #else +// // dbg-mode no visible sideeffect. +// EXPECT_EQ(0, sideeffect); +// #endif +// } +// +// This will assert that DieInDebugReturn12InOpt() crashes in debug +// mode, usually due to a DCHECK or LOG(DFATAL), but returns the +// appropriate fallback value (12 in this case) in opt mode. If you +// need to test that a function has appropriate side-effects in opt +// mode, include assertions against the side-effects. A general +// pattern for this is: +// +// EXPECT_DEBUG_DEATH({ +// // Side-effects here will have an effect after this statement in +// // opt mode, but none in debug mode. +// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); +// }, "death"); +// +# ifdef NDEBUG + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) + +# else + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + EXPECT_DEATH(statement, regex) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + ASSERT_DEATH(statement, regex) + +# endif // NDEBUG for EXPECT_DEBUG_DEATH +#endif // GTEST_HAS_DEATH_TEST + +// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and +// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if +// death tests are supported; otherwise they just issue a warning. This is +// useful when you are combining death test assertions with normal test +// assertions in one test. +#if GTEST_HAS_DEATH_TEST +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) +#else +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) +#endif + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-message.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-message.h new file mode 100644 index 0000000..6336b4a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-message.h @@ -0,0 +1,230 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the Message class. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! + +#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ + +#include + +#include "gtest/internal/gtest-string.h" +#include "gtest/internal/gtest-internal.h" + +namespace testing { + +// The Message class works like an ostream repeater. +// +// Typical usage: +// +// 1. You stream a bunch of values to a Message object. +// It will remember the text in a stringstream. +// 2. Then you stream the Message object to an ostream. +// This causes the text in the Message to be streamed +// to the ostream. +// +// For example; +// +// testing::Message foo; +// foo << 1 << " != " << 2; +// std::cout << foo; +// +// will print "1 != 2". +// +// Message is not intended to be inherited from. In particular, its +// destructor is not virtual. +// +// Note that stringstream behaves differently in gcc and in MSVC. You +// can stream a NULL char pointer to it in the former, but not in the +// latter (it causes an access violation if you do). The Message +// class hides this difference by treating a NULL char pointer as +// "(null)". +class GTEST_API_ Message { + private: + // The type of basic IO manipulators (endl, ends, and flush) for + // narrow streams. + typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); + + public: + // Constructs an empty Message. + // We allocate the stringstream separately because otherwise each use of + // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's + // stack frame leading to huge stack frames in some cases; gcc does not reuse + // the stack space. + Message() : ss_(new ::std::stringstream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); + } + + // Copy constructor. + Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT + *ss_ << msg.GetString(); + } + + // Constructs a Message from a C-string. + explicit Message(const char* str) : ss_(new ::std::stringstream) { + *ss_ << str; + } + +#if GTEST_OS_SYMBIAN + // Streams a value (either a pointer or not) to this object. + template + inline Message& operator <<(const T& value) { + StreamHelper(typename internal::is_pointer::type(), value); + return *this; + } +#else + // Streams a non-pointer value to this object. + template + inline Message& operator <<(const T& val) { + ::GTestStreamToHelper(ss_.get(), val); + return *this; + } + + // Streams a pointer value to this object. + // + // This function is an overload of the previous one. When you + // stream a pointer to a Message, this definition will be used as it + // is more specialized. (The C++ Standard, section + // [temp.func.order].) If you stream a non-pointer, then the + // previous definition will be used. + // + // The reason for this overload is that streaming a NULL pointer to + // ostream is undefined behavior. Depending on the compiler, you + // may get "0", "(nil)", "(null)", or an access violation. To + // ensure consistent result across compilers, we always treat NULL + // as "(null)". + template + inline Message& operator <<(T* const& pointer) { // NOLINT + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_.get(), pointer); + } + return *this; + } +#endif // GTEST_OS_SYMBIAN + + // Since the basic IO manipulators are overloaded for both narrow + // and wide streams, we have to provide this specialized definition + // of operator <<, even though its body is the same as the + // templatized version above. Without this definition, streaming + // endl or other basic IO manipulators to Message will confuse the + // compiler. + Message& operator <<(BasicNarrowIoManip val) { + *ss_ << val; + return *this; + } + + // Instead of 1/0, we want to see true/false for bool values. + Message& operator <<(bool b) { + return *this << (b ? "true" : "false"); + } + + // These two overloads allow streaming a wide C string to a Message + // using the UTF-8 encoding. + Message& operator <<(const wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + Message& operator <<(wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + +#if GTEST_HAS_STD_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::std::wstring& wstr); +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::wstring& wstr); +#endif // GTEST_HAS_GLOBAL_WSTRING + + // Gets the text streamed to this object so far as an std::string. + // Each '\0' character in the buffer is replaced with "\\0". + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + std::string GetString() const { + return internal::StringStreamToString(ss_.get()); + } + + private: + +#if GTEST_OS_SYMBIAN + // These are needed as the Nokia Symbian Compiler cannot decide between + // const T& and const T* in a function template. The Nokia compiler _can_ + // decide between class template specializations for T and T*, so a + // tr1::type_traits-like is_pointer works, and we can overload on that. + template + inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) { + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_.get(), pointer); + } + } + template + inline void StreamHelper(internal::false_type /*dummy*/, const T& value) { + ::GTestStreamToHelper(ss_.get(), value); + } +#endif // GTEST_OS_SYMBIAN + + // We'll hold the text streamed to this object here. + const internal::scoped_ptr< ::std::stringstream> ss_; + + // We declare (but don't implement) this to prevent the compiler + // from implementing the assignment operator. + void operator=(const Message&); +}; + +// Streams a Message to an ostream. +inline std::ostream& operator <<(std::ostream& os, const Message& sb) { + return os << sb.GetString(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-param-test.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-param-test.h new file mode 100644 index 0000000..d6702c8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-param-test.h @@ -0,0 +1,1421 @@ +// This file was GENERATED by command: +// pump.py gtest-param-test.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It is usually derived from testing::TestWithParam (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface, where T is the type of the parameter +// values. Inheriting from TestWithParam satisfies that requirement because +// TestWithParam inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} + +#endif // 0 + +#include "gtest/internal/gtest-port.h" + +#if !GTEST_OS_SYMBIAN +# include +#endif + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-param-util-generated.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template +internal::ParamGenerator Range(T start, T end, IncrementT step) { + return internal::ParamGenerator( + new internal::RangeGenerator(start, end, step)); +} + +template +internal::ParamGenerator Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list GetParameterChars() { +// ::std::list list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end) { + typedef typename ::testing::internal::IteratorTraits + ::value_type ParamType; + return internal::ParamGenerator( + new internal::ValuesInIteratorRangeGenerator(begin, end)); +} + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template +internal::ParamGenerator ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to 50 parameters. +// +template +internal::ValueArray1 Values(T1 v1) { + return internal::ValueArray1(v1); +} + +template +internal::ValueArray2 Values(T1 v1, T2 v2) { + return internal::ValueArray2(v1, v2); +} + +template +internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { + return internal::ValueArray3(v1, v2, v3); +} + +template +internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { + return internal::ValueArray4(v1, v2, v3, v4); +} + +template +internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5) { + return internal::ValueArray5(v1, v2, v3, v4, v5); +} + +template +internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6) { + return internal::ValueArray6(v1, v2, v3, v4, v5, v6); +} + +template +internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7) { + return internal::ValueArray7(v1, v2, v3, v4, v5, + v6, v7); +} + +template +internal::ValueArray8 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { + return internal::ValueArray8(v1, v2, v3, v4, + v5, v6, v7, v8); +} + +template +internal::ValueArray9 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { + return internal::ValueArray9(v1, v2, v3, + v4, v5, v6, v7, v8, v9); +} + +template +internal::ValueArray10 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { + return internal::ValueArray10(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10); +} + +template +internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) { + return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); +} + +template +internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) { + return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); +} + +template +internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) { + return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); +} + +template +internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { + return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14); +} + +template +internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { + return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); +} + +template +internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16) { + return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16); +} + +template +internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17) { + return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17); +} + +template +internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18) { + return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18); +} + +template +internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { + return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); +} + +template +internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { + return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); +} + +template +internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { + return internal::ValueArray21(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); +} + +template +internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22) { + return internal::ValueArray22(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22); +} + +template +internal::ValueArray23 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23) { + return internal::ValueArray23(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23); +} + +template +internal::ValueArray24 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24) { + return internal::ValueArray24(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24); +} + +template +internal::ValueArray25 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { + return internal::ValueArray25(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25); +} + +template +internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) { + return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); +} + +template +internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) { + return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); +} + +template +internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) { + return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28); +} + +template +internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) { + return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29); +} + +template +internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { + return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30); +} + +template +internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { + return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31); +} + +template +internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32) { + return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32); +} + +template +internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33) { + return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); +} + +template +internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34) { + return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); +} + +template +internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { + return internal::ValueArray35(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); +} + +template +internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { + return internal::ValueArray36(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36); +} + +template +internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37) { + return internal::ValueArray37(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37); +} + +template +internal::ValueArray38 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38) { + return internal::ValueArray38(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, + v33, v34, v35, v36, v37, v38); +} + +template +internal::ValueArray39 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38, T39 v39) { + return internal::ValueArray39(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, + v32, v33, v34, v35, v36, v37, v38, v39); +} + +template +internal::ValueArray40 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, + T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, + T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { + return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, + v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); +} + +template +internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { + return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, + v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); +} + +template +internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) { + return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, + v42); +} + +template +internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) { + return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, + v41, v42, v43); +} + +template +internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) { + return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, + v40, v41, v42, v43, v44); +} + +template +internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { + return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, + v39, v40, v41, v42, v43, v44, v45); +} + +template +internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { + return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46); +} + +template +internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { + return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); +} + +template +internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, + T48 v48) { + return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, + v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); +} + +template +internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, + T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, + T47 v47, T48 v48, T49 v49) { + return internal::ValueArray49(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, + v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); +} + +template +internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, + T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, + T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { + return internal::ValueArray50(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, + v48, v49, v50); +} + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator Bool() { + return Values(false, true); +} + +# if GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// tuple where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to 10 arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +template +internal::CartesianProductHolder2 Combine( + const Generator1& g1, const Generator2& g2) { + return internal::CartesianProductHolder2( + g1, g2); +} + +template +internal::CartesianProductHolder3 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3) { + return internal::CartesianProductHolder3( + g1, g2, g3); +} + +template +internal::CartesianProductHolder4 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4) { + return internal::CartesianProductHolder4( + g1, g2, g3, g4); +} + +template +internal::CartesianProductHolder5 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5) { + return internal::CartesianProductHolder5( + g1, g2, g3, g4, g5); +} + +template +internal::CartesianProductHolder6 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6) { + return internal::CartesianProductHolder6( + g1, g2, g3, g4, g5, g6); +} + +template +internal::CartesianProductHolder7 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7) { + return internal::CartesianProductHolder7( + g1, g2, g3, g4, g5, g6, g7); +} + +template +internal::CartesianProductHolder8 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8) { + return internal::CartesianProductHolder8( + g1, g2, g3, g4, g5, g6, g7, g8); +} + +template +internal::CartesianProductHolder9 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9) { + return internal::CartesianProductHolder9( + g1, g2, g3, g4, g5, g6, g7, g8, g9); +} + +template +internal::CartesianProductHolder10 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9, + const Generator10& g10) { + return internal::CartesianProductHolder10( + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); +} +# endif // GTEST_HAS_COMBINE + + + +# define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + virtual void TestBody(); \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) + +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-param-test.h.pump b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-param-test.h.pump new file mode 100644 index 0000000..2dc9303 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-param-test.h.pump @@ -0,0 +1,487 @@ +$$ -*- mode: c++; -*- +$var n = 50 $$ Maximum length of Values arguments we want to support. +$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It is usually derived from testing::TestWithParam (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface, where T is the type of the parameter +// values. Inheriting from TestWithParam satisfies that requirement because +// TestWithParam inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} + +#endif // 0 + +#include "gtest/internal/gtest-port.h" + +#if !GTEST_OS_SYMBIAN +# include +#endif + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-param-util-generated.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template +internal::ParamGenerator Range(T start, T end, IncrementT step) { + return internal::ParamGenerator( + new internal::RangeGenerator(start, end, step)); +} + +template +internal::ParamGenerator Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list GetParameterChars() { +// ::std::list list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end) { + typedef typename ::testing::internal::IteratorTraits + ::value_type ParamType; + return internal::ParamGenerator( + new internal::ValuesInIteratorRangeGenerator(begin, end)); +} + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template +internal::ParamGenerator ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to $n parameters. +// +$range i 1..n +$for i [[ +$range j 1..i + +template <$for j, [[typename T$j]]> +internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) { + return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]); +} + +]] + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator Bool() { + return Values(false, true); +} + +# if GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// tuple where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to $maxtuple arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +$range i 2..maxtuple +$for i [[ +$range j 1..i + +template <$for j, [[typename Generator$j]]> +internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine( + $for j, [[const Generator$j& g$j]]) { + return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>( + $for j, [[g$j]]); +} + +]] +# endif // GTEST_HAS_COMBINE + + + +# define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + virtual void TestBody(); \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) + +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-printers.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-printers.h new file mode 100644 index 0000000..0639d9f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-printers.h @@ -0,0 +1,855 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// A user can teach this function how to print a class type T by +// defining either operator<<() or PrintTo() in the namespace that +// defines T. More specifically, the FIRST defined function in the +// following list will be used (assuming T is defined in namespace +// foo): +// +// 1. foo::PrintTo(const T&, ostream*) +// 2. operator<<(ostream&, const T&) defined in either foo or the +// global namespace. +// +// If none of the above is defined, it will print the debug string of +// the value if it is a protocol buffer, or print the raw bytes in the +// value otherwise. +// +// To aid debugging: when T is a reference type, the address of the +// value is also printed; when T is a (const) char pointer, both the +// pointer value and the NUL-terminated string it points to are +// printed. +// +// We also provide some convenient wrappers: +// +// // Prints a value to a string. For a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// std::string ::testing::PrintToString(const T& value); +// +// // Prints a value tersely: for a reference type, the referenced +// // value (but not the address) is printed; for a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// void ::testing::internal::UniversalTersePrint(const T& value, ostream*); +// +// // Prints value using the type inferred by the compiler. The difference +// // from UniversalTersePrint() is that this function prints both the +// // pointer and the NUL-terminated string for a (const or not) char pointer. +// void ::testing::internal::UniversalPrint(const T& value, ostream*); +// +// // Prints the fields of a tuple tersely to a string vector, one +// // element for each field. Tuple support must be enabled in +// // gtest-port.h. +// std::vector UniversalTersePrintTupleFieldsToStrings( +// const Tuple& value); +// +// Known limitation: +// +// The print primitives print the elements of an STL-style container +// using the compiler-inferred type of *iter where iter is a +// const_iterator of the container. When const_iterator is an input +// iterator but not a forward iterator, this inferred type may not +// match value_type, and the print output may be incorrect. In +// practice, this is rarely a problem as for most containers +// const_iterator is a forward iterator. We'll fix this if there's an +// actual need for it. Note that this fix cannot rely on value_type +// being defined as many user-defined container types don't have +// value_type. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ + +#include // NOLINT +#include +#include +#include +#include +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-internal.h" + +namespace testing { + +// Definitions in the 'internal' and 'internal2' name spaces are +// subject to change without notice. DO NOT USE THEM IN USER CODE! +namespace internal2 { + +// Prints the given number of bytes in the given object to the given +// ostream. +GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, + size_t count, + ::std::ostream* os); + +// For selecting which printer to use when a given type has neither << +// nor PrintTo(). +enum TypeKind { + kProtobuf, // a protobuf type + kConvertibleToInteger, // a type implicitly convertible to BiggestInt + // (e.g. a named or unnamed enum type) + kOtherType // anything else +}; + +// TypeWithoutFormatter::PrintValue(value, os) is called +// by the universal printer to print a value of type T when neither +// operator<< nor PrintTo() is defined for T, where kTypeKind is the +// "kind" of T as defined by enum TypeKind. +template +class TypeWithoutFormatter { + public: + // This default version is called when kTypeKind is kOtherType. + static void PrintValue(const T& value, ::std::ostream* os) { + PrintBytesInObjectTo(reinterpret_cast(&value), + sizeof(value), os); + } +}; + +// We print a protobuf using its ShortDebugString() when the string +// doesn't exceed this many characters; otherwise we print it using +// DebugString() for better readability. +const size_t kProtobufOneLinerMaxLength = 50; + +template +class TypeWithoutFormatter { + public: + static void PrintValue(const T& value, ::std::ostream* os) { + const ::testing::internal::string short_str = value.ShortDebugString(); + const ::testing::internal::string pretty_str = + short_str.length() <= kProtobufOneLinerMaxLength ? + short_str : ("\n" + value.DebugString()); + *os << ("<" + pretty_str + ">"); + } +}; + +template +class TypeWithoutFormatter { + public: + // Since T has no << operator or PrintTo() but can be implicitly + // converted to BiggestInt, we print it as a BiggestInt. + // + // Most likely T is an enum type (either named or unnamed), in which + // case printing it as an integer is the desired behavior. In case + // T is not an enum, printing it as an integer is the best we can do + // given that it has no user-defined printer. + static void PrintValue(const T& value, ::std::ostream* os) { + const internal::BiggestInt kBigInt = value; + *os << kBigInt; + } +}; + +// Prints the given value to the given ostream. If the value is a +// protocol message, its debug string is printed; if it's an enum or +// of a type implicitly convertible to BiggestInt, it's printed as an +// integer; otherwise the bytes in the value are printed. This is +// what UniversalPrinter::Print() does when it knows nothing about +// type T and T has neither << operator nor PrintTo(). +// +// A user can override this behavior for a class type Foo by defining +// a << operator in the namespace where Foo is defined. +// +// We put this operator in namespace 'internal2' instead of 'internal' +// to simplify the implementation, as much code in 'internal' needs to +// use << in STL, which would conflict with our own << were it defined +// in 'internal'. +// +// Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If +// we define it to take an std::ostream instead, we'll get an +// "ambiguous overloads" compiler error when trying to print a type +// Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether +// operator<<(std::ostream&, const T&) or +// operator<<(std::basic_stream, const Foo&) is more +// specific. +template +::std::basic_ostream& operator<<( + ::std::basic_ostream& os, const T& x) { + TypeWithoutFormatter::value ? kProtobuf : + internal::ImplicitlyConvertible::value ? + kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); + return os; +} + +} // namespace internal2 +} // namespace testing + +// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up +// magic needed for implementing UniversalPrinter won't work. +namespace testing_internal { + +// Used to print a value that is not an STL-style container when the +// user doesn't define PrintTo() for it. +template +void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { + // With the following statement, during unqualified name lookup, + // testing::internal2::operator<< appears as if it was declared in + // the nearest enclosing namespace that contains both + // ::testing_internal and ::testing::internal2, i.e. the global + // namespace. For more details, refer to the C++ Standard section + // 7.3.4-1 [namespace.udir]. This allows us to fall back onto + // testing::internal2::operator<< in case T doesn't come with a << + // operator. + // + // We cannot write 'using ::testing::internal2::operator<<;', which + // gcc 3.3 fails to compile due to a compiler bug. + using namespace ::testing::internal2; // NOLINT + + // Assuming T is defined in namespace foo, in the next statement, + // the compiler will consider all of: + // + // 1. foo::operator<< (thanks to Koenig look-up), + // 2. ::operator<< (as the current namespace is enclosed in ::), + // 3. testing::internal2::operator<< (thanks to the using statement above). + // + // The operator<< whose type matches T best will be picked. + // + // We deliberately allow #2 to be a candidate, as sometimes it's + // impossible to define #1 (e.g. when foo is ::std, defining + // anything in it is undefined behavior unless you are a compiler + // vendor.). + *os << value; +} + +} // namespace testing_internal + +namespace testing { +namespace internal { + +// UniversalPrinter::Print(value, ostream_ptr) prints the given +// value to the given ostream. The caller must ensure that +// 'ostream_ptr' is not NULL, or the behavior is undefined. +// +// We define UniversalPrinter as a class template (as opposed to a +// function template), as we need to partially specialize it for +// reference types, which cannot be done with function templates. +template +class UniversalPrinter; + +template +void UniversalPrint(const T& value, ::std::ostream* os); + +// Used to print an STL-style container when the user doesn't define +// a PrintTo() for it. +template +void DefaultPrintTo(IsContainer /* dummy */, + false_type /* is not a pointer */, + const C& container, ::std::ostream* os) { + const size_t kMaxCount = 32; // The maximum number of elements to print. + *os << '{'; + size_t count = 0; + for (typename C::const_iterator it = container.begin(); + it != container.end(); ++it, ++count) { + if (count > 0) { + *os << ','; + if (count == kMaxCount) { // Enough has been printed. + *os << " ..."; + break; + } + } + *os << ' '; + // We cannot call PrintTo(*it, os) here as PrintTo() doesn't + // handle *it being a native array. + internal::UniversalPrint(*it, os); + } + + if (count > 0) { + *os << ' '; + } + *os << '}'; +} + +// Used to print a pointer that is neither a char pointer nor a member +// pointer, when the user doesn't define PrintTo() for it. (A member +// variable pointer or member function pointer doesn't really point to +// a location in the address space. Their representation is +// implementation-defined. Therefore they will be printed as raw +// bytes.) +template +void DefaultPrintTo(IsNotContainer /* dummy */, + true_type /* is a pointer */, + T* p, ::std::ostream* os) { + if (p == NULL) { + *os << "NULL"; + } else { + // C++ doesn't allow casting from a function pointer to any object + // pointer. + // + // IsTrue() silences warnings: "Condition is always true", + // "unreachable code". + if (IsTrue(ImplicitlyConvertible::value)) { + // T is not a function type. We just call << to print p, + // relying on ADL to pick up user-defined << for their pointer + // types, if any. + *os << p; + } else { + // T is a function type, so '*os << p' doesn't do what we want + // (it just prints p as bool). We want to print p as a const + // void*. However, we cannot cast it to const void* directly, + // even using reinterpret_cast, as earlier versions of gcc + // (e.g. 3.4.5) cannot compile the cast when p is a function + // pointer. Casting to UInt64 first solves the problem. + *os << reinterpret_cast( + reinterpret_cast(p)); + } + } +} + +// Used to print a non-container, non-pointer value when the user +// doesn't define PrintTo() for it. +template +void DefaultPrintTo(IsNotContainer /* dummy */, + false_type /* is not a pointer */, + const T& value, ::std::ostream* os) { + ::testing_internal::DefaultPrintNonContainerTo(value, os); +} + +// Prints the given value using the << operator if it has one; +// otherwise prints the bytes in it. This is what +// UniversalPrinter::Print() does when PrintTo() is not specialized +// or overloaded for type T. +// +// A user can override this behavior for a class type Foo by defining +// an overload of PrintTo() in the namespace where Foo is defined. We +// give the user this option as sometimes defining a << operator for +// Foo is not desirable (e.g. the coding style may prevent doing it, +// or there is already a << operator but it doesn't do what the user +// wants). +template +void PrintTo(const T& value, ::std::ostream* os) { + // DefaultPrintTo() is overloaded. The type of its first two + // arguments determine which version will be picked. If T is an + // STL-style container, the version for container will be called; if + // T is a pointer, the pointer version will be called; otherwise the + // generic version will be called. + // + // Note that we check for container types here, prior to we check + // for protocol message types in our operator<<. The rationale is: + // + // For protocol messages, we want to give people a chance to + // override Google Mock's format by defining a PrintTo() or + // operator<<. For STL containers, other formats can be + // incompatible with Google Mock's format for the container + // elements; therefore we check for container types here to ensure + // that our format is used. + // + // The second argument of DefaultPrintTo() is needed to bypass a bug + // in Symbian's C++ compiler that prevents it from picking the right + // overload between: + // + // PrintTo(const T& x, ...); + // PrintTo(T* x, ...); + DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); +} + +// The following list of PrintTo() overloads tells +// UniversalPrinter::Print() how to print standard types (built-in +// types, strings, plain arrays, and pointers). + +// Overloads for various char types. +GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); +GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); +inline void PrintTo(char c, ::std::ostream* os) { + // When printing a plain char, we always treat it as unsigned. This + // way, the output won't be affected by whether the compiler thinks + // char is signed or not. + PrintTo(static_cast(c), os); +} + +// Overloads for other simple built-in types. +inline void PrintTo(bool x, ::std::ostream* os) { + *os << (x ? "true" : "false"); +} + +// Overload for wchar_t type. +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its decimal code (except for L'\0'). +// The L'\0' char is printed as "L'\\0'". The decimal code is printed +// as signed integer when wchar_t is implemented by the compiler +// as a signed type and is printed as an unsigned integer when wchar_t +// is implemented as an unsigned type. +GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); + +// Overloads for C strings. +GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); +inline void PrintTo(char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// signed/unsigned char is often used for representing binary data, so +// we print pointers to it as void* to be safe. +inline void PrintTo(const signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(const unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// MSVC can be configured to define wchar_t as a typedef of unsigned +// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native +// type. When wchar_t is a typedef, defining an overload for const +// wchar_t* would cause unsigned short* be printed as a wide string, +// possibly causing invalid memory accesses. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Overloads for wide C strings +GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); +inline void PrintTo(wchar_t* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +#endif + +// Overload for C arrays. Multi-dimensional arrays are printed +// properly. + +// Prints the given number of elements in an array, without printing +// the curly braces. +template +void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { + UniversalPrint(a[0], os); + for (size_t i = 1; i != count; i++) { + *os << ", "; + UniversalPrint(a[i], os); + } +} + +// Overloads for ::string and ::std::string. +#if GTEST_HAS_GLOBAL_STRING +GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); +inline void PrintTo(const ::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); +inline void PrintTo(const ::std::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} + +// Overloads for ::wstring and ::std::wstring. +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_TR1_TUPLE +// Overload for ::std::tr1::tuple. Needed for printing function arguments, +// which are packed as tuples. + +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template +void PrintTupleTo(const T& t, ::std::ostream* os); + +// Overloaded PrintTo() for tuples of various arities. We support +// tuples of up-to 10 fields. The following implementation works +// regardless of whether tr1::tuple is implemented using the +// non-standard variadic template feature or not. + +inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo( + const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} +#endif // GTEST_HAS_TR1_TUPLE + +// Overload for std::pair. +template +void PrintTo(const ::std::pair& value, ::std::ostream* os) { + *os << '('; + // We cannot use UniversalPrint(value.first, os) here, as T1 may be + // a reference type. The same for printing value.second. + UniversalPrinter::Print(value.first, os); + *os << ", "; + UniversalPrinter::Print(value.second, os); + *os << ')'; +} + +// Implements printing a non-reference type T by letting the compiler +// pick the right overload of PrintTo() for T. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4180) // Temporarily disables warning 4180. +#endif // _MSC_VER + + // Note: we deliberately don't call this PrintTo(), as that name + // conflicts with ::testing::internal::PrintTo in the body of the + // function. + static void Print(const T& value, ::std::ostream* os) { + // By default, ::testing::internal::PrintTo() is used for printing + // the value. + // + // Thanks to Koenig look-up, if T is a class and has its own + // PrintTo() function defined in its namespace, that function will + // be visible here. Since it is more specific than the generic ones + // in ::testing::internal, it will be picked by the compiler in the + // following statement - exactly what we want. + PrintTo(value, os); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER +}; + +// UniversalPrintArray(begin, len, os) prints an array of 'len' +// elements, starting at address 'begin'. +template +void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { + if (len == 0) { + *os << "{}"; + } else { + *os << "{ "; + const size_t kThreshold = 18; + const size_t kChunkSize = 8; + // If the array has more than kThreshold elements, we'll have to + // omit some details by printing only the first and the last + // kChunkSize elements. + // TODO(wan@google.com): let the user control the threshold using a flag. + if (len <= kThreshold) { + PrintRawArrayTo(begin, len, os); + } else { + PrintRawArrayTo(begin, kChunkSize, os); + *os << ", ..., "; + PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); + } + *os << " }"; + } +} +// This overload prints a (const) char array compactly. +GTEST_API_ void UniversalPrintArray( + const char* begin, size_t len, ::std::ostream* os); + +// This overload prints a (const) wchar_t array compactly. +GTEST_API_ void UniversalPrintArray( + const wchar_t* begin, size_t len, ::std::ostream* os); + +// Implements printing an array type T[N]. +template +class UniversalPrinter { + public: + // Prints the given array, omitting some elements when there are too + // many. + static void Print(const T (&a)[N], ::std::ostream* os) { + UniversalPrintArray(a, N, os); + } +}; + +// Implements printing a reference type T&. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4180) // Temporarily disables warning 4180. +#endif // _MSC_VER + + static void Print(const T& value, ::std::ostream* os) { + // Prints the address of the value. We use reinterpret_cast here + // as static_cast doesn't compile when T is a function type. + *os << "@" << reinterpret_cast(&value) << " "; + + // Then prints the value itself. + UniversalPrint(value, os); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER +}; + +// Prints a value tersely: for a reference type, the referenced value +// (but not the address) is printed; for a (const) char pointer, the +// NUL-terminated string (but not the pointer) is printed. + +template +class UniversalTersePrinter { + public: + static void Print(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); + } +}; +template +class UniversalTersePrinter { + public: + static void Print(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); + } +}; +template +class UniversalTersePrinter { + public: + static void Print(const T (&value)[N], ::std::ostream* os) { + UniversalPrinter::Print(value, os); + } +}; +template <> +class UniversalTersePrinter { + public: + static void Print(const char* str, ::std::ostream* os) { + if (str == NULL) { + *os << "NULL"; + } else { + UniversalPrint(string(str), os); + } + } +}; +template <> +class UniversalTersePrinter { + public: + static void Print(char* str, ::std::ostream* os) { + UniversalTersePrinter::Print(str, os); + } +}; + +#if GTEST_HAS_STD_WSTRING +template <> +class UniversalTersePrinter { + public: + static void Print(const wchar_t* str, ::std::ostream* os) { + if (str == NULL) { + *os << "NULL"; + } else { + UniversalPrint(::std::wstring(str), os); + } + } +}; +#endif + +template <> +class UniversalTersePrinter { + public: + static void Print(wchar_t* str, ::std::ostream* os) { + UniversalTersePrinter::Print(str, os); + } +}; + +template +void UniversalTersePrint(const T& value, ::std::ostream* os) { + UniversalTersePrinter::Print(value, os); +} + +// Prints a value using the type inferred by the compiler. The +// difference between this and UniversalTersePrint() is that for a +// (const) char pointer, this prints both the pointer and the +// NUL-terminated string. +template +void UniversalPrint(const T& value, ::std::ostream* os) { + // A workarond for the bug in VC++ 7.1 that prevents us from instantiating + // UniversalPrinter with T directly. + typedef T T1; + UniversalPrinter::Print(value, os); +} + +#if GTEST_HAS_TR1_TUPLE +typedef ::std::vector Strings; + +// This helper template allows PrintTo() for tuples and +// UniversalTersePrintTupleFieldsToStrings() to be defined by +// induction on the number of tuple fields. The idea is that +// TuplePrefixPrinter::PrintPrefixTo(t, os) prints the first N +// fields in tuple t, and can be defined in terms of +// TuplePrefixPrinter. + +// The inductive case. +template +struct TuplePrefixPrinter { + // Prints the first N fields of a tuple. + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + TuplePrefixPrinter::PrintPrefixTo(t, os); + *os << ", "; + UniversalPrinter::type> + ::Print(::std::tr1::get(t), os); + } + + // Tersely prints the first N fields of a tuple to a string vector, + // one element for each field. + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get(t), &ss); + strings->push_back(ss.str()); + } +}; + +// Base cases. +template <> +struct TuplePrefixPrinter<0> { + template + static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} + + template + static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} +}; +// We have to specialize the entire TuplePrefixPrinter<> class +// template here, even though the definition of +// TersePrintPrefixToStrings() is the same as the generic version, as +// Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't +// support specializing a method template of a class template. +template <> +struct TuplePrefixPrinter<1> { + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + UniversalPrinter::type>:: + Print(::std::tr1::get<0>(t), os); + } + + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get<0>(t), &ss); + strings->push_back(ss.str()); + } +}; + +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template +void PrintTupleTo(const T& t, ::std::ostream* os) { + *os << "("; + TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: + PrintPrefixTo(t, os); + *os << ")"; +} + +// Prints the fields of a tuple tersely to a string vector, one +// element for each field. See the comment before +// UniversalTersePrint() for how we define "tersely". +template +Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { + Strings result; + TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: + TersePrintPrefixToStrings(value, &result); + return result; +} +#endif // GTEST_HAS_TR1_TUPLE + +} // namespace internal + +template +::std::string PrintToString(const T& value) { + ::std::stringstream ss; + internal::UniversalTersePrinter::Print(value, &ss); + return ss.str(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-spi.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-spi.h new file mode 100644 index 0000000..f63fa9a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-spi.h @@ -0,0 +1,232 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Utilities for testing Google Test itself and code that uses Google Test +// (e.g. frameworks built on top of Google Test). + +#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ +#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + +#include "gtest/gtest.h" + +namespace testing { + +// This helper class can be used to mock out Google Test failure reporting +// so that we can test Google Test or code that builds on Google Test. +// +// An object of this class appends a TestPartResult object to the +// TestPartResultArray object given in the constructor whenever a Google Test +// failure is reported. It can either intercept only failures that are +// generated in the same thread that created this object or it can intercept +// all generated failures. The scope of this mock object can be controlled with +// the second argument to the two arguments constructor. +class GTEST_API_ ScopedFakeTestPartResultReporter + : public TestPartResultReporterInterface { + public: + // The two possible mocking modes of this object. + enum InterceptMode { + INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. + INTERCEPT_ALL_THREADS // Intercepts all failures. + }; + + // The c'tor sets this object as the test part result reporter used + // by Google Test. The 'result' parameter specifies where to report the + // results. This reporter will only catch failures generated in the current + // thread. DEPRECATED + explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + + // Same as above, but you can choose the interception scope of this object. + ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, + TestPartResultArray* result); + + // The d'tor restores the previous test part result reporter. + virtual ~ScopedFakeTestPartResultReporter(); + + // Appends the TestPartResult object to the TestPartResultArray + // received in the constructor. + // + // This method is from the TestPartResultReporterInterface + // interface. + virtual void ReportTestPartResult(const TestPartResult& result); + private: + void Init(); + + const InterceptMode intercept_mode_; + TestPartResultReporterInterface* old_reporter_; + TestPartResultArray* const result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); +}; + +namespace internal { + +// A helper class for implementing EXPECT_FATAL_FAILURE() and +// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +class GTEST_API_ SingleFailureChecker { + public: + // The constructor remembers the arguments. + SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr); + ~SingleFailureChecker(); + private: + const TestPartResultArray* const results_; + const TestPartResult::Type type_; + const string substr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +}; + +} // namespace internal + +} // namespace testing + +// A set of macros for testing Google Test assertions or code that's expected +// to generate Google Test fatal failures. It verifies that the given +// statement will cause exactly one fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_FATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - 'statement' cannot reference local non-static variables or +// non-static members of the current object. +// - 'statement' cannot return a value. +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ALL_THREADS, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +// A macro for testing Google Test assertions or code that's expected to +// generate Google Test non-fatal failures. It asserts that the given +// statement will cause exactly one non-fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// 'statement' is allowed to reference local variables and members of +// the current object. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ + >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-test-part.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-test-part.h new file mode 100644 index 0000000..77eb844 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-test-part.h @@ -0,0 +1,179 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ + +#include +#include +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" + +namespace testing { + +// A copyable object representing the result of a test part (i.e. an +// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). +// +// Don't inherit from TestPartResult as its destructor is not virtual. +class GTEST_API_ TestPartResult { + public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure // Failed and the test should be terminated. + }; + + // C'tor. TestPartResult does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestPartResult object. + TestPartResult(Type a_type, + const char* a_file_name, + int a_line_number, + const char* a_message) + : type_(a_type), + file_name_(a_file_name == NULL ? "" : a_file_name), + line_number_(a_line_number), + summary_(ExtractSummary(a_message)), + message_(a_message) { + } + + // Gets the outcome of the test part. + Type type() const { return type_; } + + // Gets the name of the source file where the test part took place, or + // NULL if it's unknown. + const char* file_name() const { + return file_name_.empty() ? NULL : file_name_.c_str(); + } + + // Gets the line in the source file where the test part took place, + // or -1 if it's unknown. + int line_number() const { return line_number_; } + + // Gets the summary of the failure message. + const char* summary() const { return summary_.c_str(); } + + // Gets the message associated with the test part. + const char* message() const { return message_.c_str(); } + + // Returns true iff the test part passed. + bool passed() const { return type_ == kSuccess; } + + // Returns true iff the test part failed. + bool failed() const { return type_ != kSuccess; } + + // Returns true iff the test part non-fatally failed. + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } + + // Returns true iff the test part fatally failed. + bool fatally_failed() const { return type_ == kFatalFailure; } + + private: + Type type_; + + // Gets the summary of the failure message by omitting the stack + // trace in it. + static std::string ExtractSummary(const char* message); + + // The name of the source file where the test part took place, or + // "" if the source file is unknown. + std::string file_name_; + // The line in the source file where the test part took place, or -1 + // if the line number is unknown. + int line_number_; + std::string summary_; // The test failure summary. + std::string message_; // The test failure message. +}; + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result); + +// An array of TestPartResult objects. +// +// Don't inherit from TestPartResultArray as its destructor is not +// virtual. +class GTEST_API_ TestPartResultArray { + public: + TestPartResultArray() {} + + // Appends the given TestPartResult to the array. + void Append(const TestPartResult& result); + + // Returns the TestPartResult at the given index (0-based). + const TestPartResult& GetTestPartResult(int index) const; + + // Returns the number of TestPartResult objects in the array. + int size() const; + + private: + std::vector array_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); +}; + +// This interface knows how to report a test part result. +class TestPartResultReporterInterface { + public: + virtual ~TestPartResultReporterInterface() {} + + virtual void ReportTestPartResult(const TestPartResult& result) = 0; +}; + +namespace internal { + +// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a +// statement generates new fatal failures. To do so it registers itself as the +// current test part result reporter. Besides checking if fatal failures were +// reported, it only delegates the reporting to the former result reporter. +// The original result reporter is restored in the destructor. +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +class GTEST_API_ HasNewFatalFailureHelper + : public TestPartResultReporterInterface { + public: + HasNewFatalFailureHelper(); + virtual ~HasNewFatalFailureHelper(); + virtual void ReportTestPartResult(const TestPartResult& result); + bool has_new_fatal_failure() const { return has_new_fatal_failure_; } + private: + bool has_new_fatal_failure_; + TestPartResultReporterInterface* original_reporter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); +}; + +} // namespace internal + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-typed-test.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-typed-test.h new file mode 100644 index 0000000..fe1e83b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest-typed-test.h @@ -0,0 +1,259 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// This header implements typed tests and type-parameterized tests. + +// Typed (aka type-driven) tests repeat the same test for types in a +// list. You must know which types you want to test with when writing +// typed tests. Here's how you do it: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + public: + ... + typedef std::list List; + static T shared_; + T value_; +}; + +// Next, associate a list of types with the test case, which will be +// repeated for each type in the list. The typedef is necessary for +// the macro to parse correctly. +typedef testing::Types MyTypes; +TYPED_TEST_CASE(FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// TYPED_TEST_CASE(FooTest, int); + +// Then, use TYPED_TEST() instead of TEST_F() to define as many typed +// tests for this test case as you want. +TYPED_TEST(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + // Since we are inside a derived class template, C++ requires use to + // visit the members of FooTest via 'this'. + TypeParam n = this->value_; + + // To visit static members of the fixture, add the TestFixture:: + // prefix. + n += TestFixture::shared_; + + // To refer to typedefs in the fixture, add the "typename + // TestFixture::" prefix. + typename TestFixture::List values; + values.push_back(n); + ... +} + +TYPED_TEST(FooTest, HasPropertyA) { ... } + +#endif // 0 + +// Type-parameterized tests are abstract test patterns parameterized +// by a type. Compared with typed tests, type-parameterized tests +// allow you to define the test pattern without knowing what the type +// parameters are. The defined pattern can be instantiated with +// different types any number of times, in any number of translation +// units. +// +// If you are designing an interface or concept, you can define a +// suite of type-parameterized tests to verify properties that any +// valid implementation of the interface/concept should have. Then, +// each implementation can easily instantiate the test suite to verify +// that it conforms to the requirements, without having to write +// similar tests repeatedly. Here's an example: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + ... +}; + +// Next, declare that you will define a type-parameterized test case +// (the _P suffix is for "parameterized" or "pattern", whichever you +// prefer): +TYPED_TEST_CASE_P(FooTest); + +// Then, use TYPED_TEST_P() to define as many type-parameterized tests +// for this type-parameterized test case as you want. +TYPED_TEST_P(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + TypeParam n = 0; + ... +} + +TYPED_TEST_P(FooTest, HasPropertyA) { ... } + +// Now the tricky part: you need to register all test patterns before +// you can instantiate them. The first argument of the macro is the +// test case name; the rest are the names of the tests in this test +// case. +REGISTER_TYPED_TEST_CASE_P(FooTest, + DoesBlah, HasPropertyA); + +// Finally, you are free to instantiate the pattern with the types you +// want. If you put the above code in a header file, you can #include +// it in multiple C++ source files and instantiate it multiple times. +// +// To distinguish different instances of the pattern, the first +// argument to the INSTANTIATE_* macro is a prefix that will be added +// to the actual test case name. Remember to pick unique prefixes for +// different instances. +typedef testing::Types MyTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); + +#endif // 0 + +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-type-util.h" + +// Implements typed tests. + +#if GTEST_HAS_TYPED_TEST + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the typedef for the type parameters of the +// given test case. +# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +# define TYPED_TEST_CASE(CaseName, Types) \ + typedef ::testing::internal::TypeList< Types >::type \ + GTEST_TYPE_PARAMS_(CaseName) + +# define TYPED_TEST(CaseName, TestName) \ + template \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel< \ + GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ + GTEST_TYPE_PARAMS_(CaseName)>::Register(\ + "", #CaseName, #TestName, 0); \ + template \ + void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() + +#endif // GTEST_HAS_TYPED_TEST + +// Implements type-parameterized tests. + +#if GTEST_HAS_TYPED_TEST_P + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the namespace name that the type-parameterized tests for +// the given type-parameterized test case are defined in. The exact +// name of the namespace is subject to change without notice. +# define GTEST_CASE_NAMESPACE_(TestCaseName) \ + gtest_case_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the variable used to remember the names of +// the defined tests in the given test case. +# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ + gtest_typed_test_case_p_state_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. +// +// Expands to the name of the variable used to remember the names of +// the registered tests in the given test case. +# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ + gtest_registered_test_names_##TestCaseName##_ + +// The variables defined in the type-parameterized test macros are +// static as typically these macros are used in a .h file that can be +// #included in multiple translation units linked together. +# define TYPED_TEST_CASE_P(CaseName) \ + static ::testing::internal::TypedTestCasePState \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) + +# define TYPED_TEST_P(CaseName, TestName) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + template \ + class TestName : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ + __FILE__, __LINE__, #CaseName, #TestName); \ + } \ + template \ + void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() + +# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ + } \ + static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ + __FILE__, __LINE__, #__VA_ARGS__) + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ + bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTestCase::type>::Register(\ + #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest.h new file mode 100644 index 0000000..9ecb145 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest.h @@ -0,0 +1,2236 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for Google Test. It should be +// included by any test program that uses Google Test. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! +// +// Acknowledgment: Google Test borrowed the idea of automatic test +// registration from Barthelemy Dagenais' (barthelemy@prologique.com) +// easyUnit framework. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_H_ + +#include +#include +#include + +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" +#include "gtest/gtest-death-test.h" +#include "gtest/gtest-message.h" +#include "gtest/gtest-param-test.h" +#include "gtest/gtest-printers.h" +#include "gtest/gtest_prod.h" +#include "gtest/gtest-test-part.h" +#include "gtest/gtest-typed-test.h" + +// Depending on the platform, different string classes are available. +// On Linux, in addition to ::std::string, Google also makes use of +// class ::string, which has the same interface as ::std::string, but +// has a different implementation. +// +// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that +// ::string is available AND is a distinct type to ::std::string, or +// define it to 0 to indicate otherwise. +// +// If the user's ::std::string and ::string are the same class due to +// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. +// +// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined +// heuristically. + +namespace testing { + +// Declares the flags. + +// This flag temporary enables the disabled tests. +GTEST_DECLARE_bool_(also_run_disabled_tests); + +// This flag brings the debugger on an assertion failure. +GTEST_DECLARE_bool_(break_on_failure); + +// This flag controls whether Google Test catches all test-thrown exceptions +// and logs them as failures. +GTEST_DECLARE_bool_(catch_exceptions); + +// This flag enables using colors in terminal output. Available values are +// "yes" to enable colors, "no" (disable colors), or "auto" (the default) +// to let Google Test decide. +GTEST_DECLARE_string_(color); + +// This flag sets up the filter to select by name using a glob pattern +// the tests to run. If the filter is not given all tests are executed. +GTEST_DECLARE_string_(filter); + +// This flag causes the Google Test to list tests. None of the tests listed +// are actually run if the flag is provided. +GTEST_DECLARE_bool_(list_tests); + +// This flag controls whether Google Test emits a detailed XML report to a file +// in addition to its normal textual output. +GTEST_DECLARE_string_(output); + +// This flags control whether Google Test prints the elapsed time for each +// test. +GTEST_DECLARE_bool_(print_time); + +// This flag specifies the random number seed. +GTEST_DECLARE_int32_(random_seed); + +// This flag sets how many times the tests are repeated. The default value +// is 1. If the value is -1 the tests are repeating forever. +GTEST_DECLARE_int32_(repeat); + +// This flag controls whether Google Test includes Google Test internal +// stack frames in failure stack traces. +GTEST_DECLARE_bool_(show_internal_stack_frames); + +// When this flag is specified, tests' order is randomized on every iteration. +GTEST_DECLARE_bool_(shuffle); + +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// When this flag is specified, a failed assertion will throw an +// exception if exceptions are enabled, or exit the program with a +// non-zero code otherwise. +GTEST_DECLARE_bool_(throw_on_failure); + +// When this flag is set with a "host:port" string, on supported +// platforms test results are streamed to the specified port on +// the specified host machine. +GTEST_DECLARE_string_(stream_result_to); + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + +namespace internal { + +class AssertHelper; +class DefaultGlobalTestPartResultReporter; +class ExecDeathTest; +class NoExecDeathTest; +class FinalSuccessChecker; +class GTestFlagSaver; +class TestResultAccessor; +class TestEventListenersAccessor; +class TestEventRepeater; +class WindowsDeathTest; +class UnitTestImpl* GetUnitTestImpl(); +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message); + +// Converts a streamable value to an std::string. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared in gtest-internal.h but defined here, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +std::string StreamableToString(const T& streamable) { + return (Message() << streamable).GetString(); +} + +} // namespace internal + +// The friend relationship of some of these classes is cyclic. +// If we don't forward declare them the compiler might confuse the classes +// in friendship clauses with same named classes on the scope. +class Test; +class TestCase; +class TestInfo; +class UnitTest; + +// A class for indicating whether an assertion was successful. When +// the assertion wasn't successful, the AssertionResult object +// remembers a non-empty message that describes how it failed. +// +// To create an instance of this class, use one of the factory functions +// (AssertionSuccess() and AssertionFailure()). +// +// This class is useful for two purposes: +// 1. Defining predicate functions to be used with Boolean test assertions +// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts +// 2. Defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// For example, if you define IsEven predicate: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) +// will print the message +// +// Value of: IsEven(Fib(5)) +// Actual: false (5 is odd) +// Expected: true +// +// instead of a more opaque +// +// Value of: IsEven(Fib(5)) +// Actual: false +// Expected: true +// +// in case IsEven is a simple Boolean predicate. +// +// If you expect your predicate to be reused and want to support informative +// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up +// about half as often as positive ones in our tests), supply messages for +// both success and failure cases: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess() << n << " is even"; +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print +// +// Value of: IsEven(Fib(6)) +// Actual: true (8 is even) +// Expected: false +// +// NB: Predicates that support negative Boolean assertions have reduced +// performance in positive ones so be careful not to use them in tests +// that have lots (tens of thousands) of positive Boolean assertions. +// +// To use this class with EXPECT_PRED_FORMAT assertions such as: +// +// // Verifies that Foo() returns an even number. +// EXPECT_PRED_FORMAT1(IsEven, Foo()); +// +// you need to define: +// +// testing::AssertionResult IsEven(const char* expr, int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() +// << "Expected: " << expr << " is even\n Actual: it's " << n; +// } +// +// If Foo() returns 5, you will see the following message: +// +// Expected: Foo() is even +// Actual: it's 5 +// +class GTEST_API_ AssertionResult { + public: + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + // Used in the EXPECT_TRUE/FALSE(bool_expression). + explicit AssertionResult(bool success) : success_(success) {} + + // Returns true iff the assertion succeeded. + operator bool() const { return success_; } // NOLINT + + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; + + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const { + return message_.get() != NULL ? message_->c_str() : ""; + } + // TODO(vladl@google.com): Remove this after making sure no clients use it. + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } + + // Streams a custom failure message into this object. + template AssertionResult& operator<<(const T& value) { + AppendMessage(Message() << value); + return *this; + } + + // Allows streaming basic output manipulators such as endl or flush into + // this object. + AssertionResult& operator<<( + ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { + AppendMessage(Message() << basic_manipulator); + return *this; + } + + private: + // Appends the contents of message to message_. + void AppendMessage(const Message& a_message) { + if (message_.get() == NULL) + message_.reset(new ::std::string); + message_->append(a_message.GetString().c_str()); + } + + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + internal::scoped_ptr< ::std::string> message_; + + GTEST_DISALLOW_ASSIGN_(AssertionResult); +}; + +// Makes a successful assertion result. +GTEST_API_ AssertionResult AssertionSuccess(); + +// Makes a failed assertion result. +GTEST_API_ AssertionResult AssertionFailure(); + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << msg. +GTEST_API_ AssertionResult AssertionFailure(const Message& msg); + +// The abstract class that all tests inherit from. +// +// In Google Test, a unit test program contains one or many TestCases, and +// each TestCase contains one or many Tests. +// +// When you define a test using the TEST macro, you don't need to +// explicitly derive from Test - the TEST macro automatically does +// this for you. +// +// The only time you derive from Test is when defining a test fixture +// to be used a TEST_F. For example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { ... } +// virtual void TearDown() { ... } +// ... +// }; +// +// TEST_F(FooTest, Bar) { ... } +// TEST_F(FooTest, Baz) { ... } +// +// Test is not copyable. +class GTEST_API_ Test { + public: + friend class TestInfo; + + // Defines types for pointers to functions that set up and tear down + // a test case. + typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; + typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; + + // The d'tor is virtual as we intend to inherit from Test. + virtual ~Test(); + + // Sets up the stuff shared by all tests in this test case. + // + // Google Test will call Foo::SetUpTestCase() before running the first + // test in test case Foo. Hence a sub-class can define its own + // SetUpTestCase() method to shadow the one defined in the super + // class. + static void SetUpTestCase() {} + + // Tears down the stuff shared by all tests in this test case. + // + // Google Test will call Foo::TearDownTestCase() after running the last + // test in test case Foo. Hence a sub-class can define its own + // TearDownTestCase() method to shadow the one defined in the super + // class. + static void TearDownTestCase() {} + + // Returns true iff the current test has a fatal failure. + static bool HasFatalFailure(); + + // Returns true iff the current test has a non-fatal failure. + static bool HasNonfatalFailure(); + + // Returns true iff the current test has a (either fatal or + // non-fatal) failure. + static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } + + // Logs a property for the current test. Only the last value for a given + // key is remembered. + // These are public static so they can be called from utility functions + // that are not members of the test fixture. + // The arguments are const char* instead strings, as Google Test is used + // on platforms where string doesn't compile. + // + // Note that a driving consideration for these RecordProperty methods + // was to produce xml output suited to the Greenspan charting utility, + // which at present will only chart values that fit in a 32-bit int. It + // is the user's responsibility to restrict their values to 32-bit ints + // if they intend them to be used with Greenspan. + static void RecordProperty(const char* key, const char* value); + static void RecordProperty(const char* key, int value); + + protected: + // Creates a Test object. + Test(); + + // Sets up the test fixture. + virtual void SetUp(); + + // Tears down the test fixture. + virtual void TearDown(); + + private: + // Returns true iff the current test has the same fixture class as + // the first test in the current test case. + static bool HasSameFixtureClass(); + + // Runs the test after the test fixture has been set up. + // + // A sub-class must implement this to define the test logic. + // + // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. + // Instead, use the TEST or TEST_F macro. + virtual void TestBody() = 0; + + // Sets up, executes, and tears down the test. + void Run(); + + // Deletes self. We deliberately pick an unusual name for this + // internal method to avoid clashing with names used in user TESTs. + void DeleteSelf_() { delete this; } + + // Uses a GTestFlagSaver to save and restore all Google Test flags. + const internal::GTestFlagSaver* const gtest_flag_saver_; + + // Often a user mis-spells SetUp() as Setup() and spends a long time + // wondering why it is never called by Google Test. The declaration of + // the following method is solely for catching such an error at + // compile time: + // + // - The return type is deliberately chosen to be not void, so it + // will be a conflict if a user declares void Setup() in his test + // fixture. + // + // - This method is private, so it will be another compiler error + // if a user calls it from his test fixture. + // + // DO NOT OVERRIDE THIS FUNCTION. + // + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } + + // We disallow copying Tests. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); +}; + +typedef internal::TimeInMillis TimeInMillis; + +// A copyable object representing a user specified test property which can be +// output as a key/value string pair. +// +// Don't inherit from TestProperty as its destructor is not virtual. +class TestProperty { + public: + // C'tor. TestProperty does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestProperty object. + TestProperty(const char* a_key, const char* a_value) : + key_(a_key), value_(a_value) { + } + + // Gets the user supplied key. + const char* key() const { + return key_.c_str(); + } + + // Gets the user supplied value. + const char* value() const { + return value_.c_str(); + } + + // Sets a new value, overriding the one supplied in the constructor. + void SetValue(const char* new_value) { + value_ = new_value; + } + + private: + // The key supplied by the user. + std::string key_; + // The value supplied by the user. + std::string value_; +}; + +// The result of a single Test. This includes a list of +// TestPartResults, a list of TestProperties, a count of how many +// death tests there are in the Test, and how much time it took to run +// the Test. +// +// TestResult is not copyable. +class GTEST_API_ TestResult { + public: + // Creates an empty TestResult. + TestResult(); + + // D'tor. Do not inherit from TestResult. + ~TestResult(); + + // Gets the number of all test parts. This is the sum of the number + // of successful test parts and the number of failed test parts. + int total_part_count() const; + + // Returns the number of the test properties. + int test_property_count() const; + + // Returns true iff the test passed (i.e. no test part failed). + bool Passed() const { return !Failed(); } + + // Returns true iff the test failed. + bool Failed() const; + + // Returns true iff the test fatally failed. + bool HasFatalFailure() const; + + // Returns true iff the test has a non-fatal failure. + bool HasNonfatalFailure() const; + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test part result among all the results. i can range + // from 0 to test_property_count() - 1. If i is not in that range, aborts + // the program. + const TestPartResult& GetTestPartResult(int i) const; + + // Returns the i-th test property. i can range from 0 to + // test_property_count() - 1. If i is not in that range, aborts the + // program. + const TestProperty& GetTestProperty(int i) const; + + private: + friend class TestInfo; + friend class UnitTest; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::ExecDeathTest; + friend class internal::TestResultAccessor; + friend class internal::UnitTestImpl; + friend class internal::WindowsDeathTest; + + // Gets the vector of TestPartResults. + const std::vector& test_part_results() const { + return test_part_results_; + } + + // Gets the vector of TestProperties. + const std::vector& test_properties() const { + return test_properties_; + } + + // Sets the elapsed time. + void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } + + // Adds a test property to the list. The property is validated and may add + // a non-fatal failure if invalid (e.g., if it conflicts with reserved + // key names). If a property is already recorded for the same key, the + // value will be updated, rather than storing multiple values for the same + // key. + void RecordProperty(const TestProperty& test_property); + + // Adds a failure if the key is a reserved attribute of Google Test + // testcase tags. Returns true if the property is valid. + // TODO(russr): Validate attribute names are legal and human readable. + static bool ValidateTestProperty(const TestProperty& test_property); + + // Adds a test part result to the list. + void AddTestPartResult(const TestPartResult& test_part_result); + + // Returns the death test count. + int death_test_count() const { return death_test_count_; } + + // Increments the death test count, returning the new count. + int increment_death_test_count() { return ++death_test_count_; } + + // Clears the test part results. + void ClearTestPartResults(); + + // Clears the object. + void Clear(); + + // Protects mutable state of the property vector and of owned + // properties, whose values may be updated. + internal::Mutex test_properites_mutex_; + + // The vector of TestPartResults + std::vector test_part_results_; + // The vector of TestProperties + std::vector test_properties_; + // Running count of death tests. + int death_test_count_; + // The elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestResult. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); +}; // class TestResult + +// A TestInfo object stores the following information about a test: +// +// Test case name +// Test name +// Whether the test should be run +// A function pointer that creates the test object when invoked +// Test result +// +// The constructor of TestInfo registers itself with the UnitTest +// singleton such that the RUN_ALL_TESTS() macro knows which tests to +// run. +class GTEST_API_ TestInfo { + public: + // Destructs a TestInfo object. This function is not virtual, so + // don't inherit from TestInfo. + ~TestInfo(); + + // Returns the test case name. + const char* test_case_name() const { return test_case_name_.c_str(); } + + // Returns the test name. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a typed + // or a type-parameterized test. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } + + // Returns the text representation of the value parameter, or NULL if this + // is not a value-parameterized test. + const char* value_param() const { + if (value_param_.get() != NULL) + return value_param_->c_str(); + return NULL; + } + + // Returns true if this test should run, that is if the test is not disabled + // (or it is disabled but the also_run_disabled_tests flag has been specified) + // and its full name matches the user-specified filter. + // + // Google Test allows the user to filter the tests by their full names. + // The full name of a test Bar in test case Foo is defined as + // "Foo.Bar". Only the tests that match the filter will run. + // + // A filter is a colon-separated list of glob (not regex) patterns, + // optionally followed by a '-' and a colon-separated list of + // negative patterns (tests to exclude). A test is run if it + // matches one of the positive patterns and does not match any of + // the negative patterns. + // + // For example, *A*:Foo.* is a filter that matches any string that + // contains the character 'A' or starts with "Foo.". + bool should_run() const { return should_run_; } + + // Returns the result of the test. + const TestResult* result() const { return &result_; } + + private: +#if GTEST_HAS_DEATH_TEST + friend class internal::DefaultDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + friend class Test; + friend class TestCase; + friend class internal::UnitTestImpl; + friend TestInfo* internal::MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* type_param, + const char* value_param, + internal::TypeId fixture_class_id, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + internal::TestFactoryBase* factory); + + // Constructs a TestInfo object. The newly constructed instance assumes + // ownership of the factory object. + TestInfo(const char* test_case_name, const char* name, + const char* a_type_param, + const char* a_value_param, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory); + + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count() { + return result_.increment_death_test_count(); + } + + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); + + static void ClearTestResult(TestInfo* test_info) { + test_info->result_.Clear(); + } + + // These fields are immutable properties of the test. + const std::string test_case_name_; // Test case name + const std::string name_; // Test name + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; + // Text representation of the value parameter, or NULL if this is not a + // value-parameterized test. + const internal::scoped_ptr value_param_; + const internal::TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True iff this test should run + bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object + + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); +}; + +// A test case, which consists of a vector of TestInfos. +// +// TestCase is not copyable. +class GTEST_API_ TestCase { + public: + // Creates a TestCase with the given name. + // + // TestCase does NOT have a default constructor. Always use this + // constructor to create a TestCase object. + // + // Arguments: + // + // name: name of the test case + // a_type_param: the name of the test's type parameter, or NULL if + // this is not a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase(const char* name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Destructor of TestCase. + virtual ~TestCase(); + + // Gets the name of the TestCase. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a + // type-parameterized test case. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } + + // Returns true if any test in this test case should run. + bool should_run() const { return should_run_; } + + // Gets the number of successful tests in this test case. + int successful_test_count() const; + + // Gets the number of failed tests in this test case. + int failed_test_count() const; + + // Gets the number of disabled tests in this test case. + int disabled_test_count() const; + + // Get the number of tests in this test case that should run. + int test_to_run_count() const; + + // Gets the number of all tests in this test case. + int total_test_count() const; + + // Returns true iff the test case passed. + bool Passed() const { return !Failed(); } + + // Returns true iff the test case failed. + bool Failed() const { return failed_test_count() > 0; } + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + const TestInfo* GetTestInfo(int i) const; + + private: + friend class Test; + friend class internal::UnitTestImpl; + + // Gets the (mutable) vector of TestInfos in this TestCase. + std::vector& test_info_list() { return test_info_list_; } + + // Gets the (immutable) vector of TestInfos in this TestCase. + const std::vector& test_info_list() const { + return test_info_list_; + } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Adds a TestInfo to this test case. Will delete the TestInfo upon + // destruction of the TestCase object. + void AddTestInfo(TestInfo * test_info); + + // Clears the results of all tests in this test case. + void ClearResult(); + + // Clears the results of all tests in the given test case. + static void ClearTestCaseResult(TestCase* test_case) { + test_case->ClearResult(); + } + + // Runs every test in this TestCase. + void Run(); + + // Runs SetUpTestCase() for this TestCase. This wrapper is needed + // for catching exceptions thrown from SetUpTestCase(). + void RunSetUpTestCase() { (*set_up_tc_)(); } + + // Runs TearDownTestCase() for this TestCase. This wrapper is + // needed for catching exceptions thrown from TearDownTestCase(). + void RunTearDownTestCase() { (*tear_down_tc_)(); } + + // Returns true iff test passed. + static bool TestPassed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Passed(); + } + + // Returns true iff test failed. + static bool TestFailed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Failed(); + } + + // Returns true iff test is disabled. + static bool TestDisabled(const TestInfo* test_info) { + return test_info->is_disabled_; + } + + // Returns true if the given test should run. + static bool ShouldRunTest(const TestInfo* test_info) { + return test_info->should_run(); + } + + // Shuffles the tests in this test case. + void ShuffleTests(internal::Random* random); + + // Restores the test order to before the first shuffle. + void UnshuffleTests(); + + // Name of the test case. + std::string name_; + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + std::vector test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + std::vector test_indices_; + // Pointer to the function that sets up the test case. + Test::SetUpTestCaseFunc set_up_tc_; + // Pointer to the function that tears down the test case. + Test::TearDownTestCaseFunc tear_down_tc_; + // True iff any test in this test case should run. + bool should_run_; + // Elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestCases. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); +}; + +// An Environment object is capable of setting up and tearing down an +// environment. The user should subclass this to define his own +// environment(s). +// +// An Environment object does the set-up and tear-down in virtual +// methods SetUp() and TearDown() instead of the constructor and the +// destructor, as: +// +// 1. You cannot safely throw from a destructor. This is a problem +// as in some cases Google Test is used where exceptions are enabled, and +// we may want to implement ASSERT_* using exceptions where they are +// available. +// 2. You cannot use ASSERT_* directly in a constructor or +// destructor. +class Environment { + public: + // The d'tor is virtual as we need to subclass Environment. + virtual ~Environment() {} + + // Override this to define how to set up the environment. + virtual void SetUp() {} + + // Override this to define how to tear down the environment. + virtual void TearDown() {} + private: + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } +}; + +// The interface for tracing execution of tests. The methods are organized in +// the order the corresponding events are fired. +class TestEventListener { + public: + virtual ~TestEventListener() {} + + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; + + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + + // Fired before the test case starts. + virtual void OnTestCaseStart(const TestCase& test_case) = 0; + + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; + + // Fired after a failed assertion or a SUCCEED() invocation. + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; + + // Fired after the test case ends. + virtual void OnTestCaseEnd(const TestCase& test_case) = 0; + + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; + + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; +}; + +// The convenience class for users who need to override just one or two +// methods and are not concerned that a possible change to a signature of +// the methods they override will not be caught during the build. For +// comments about each method please see the definition of TestEventListener +// above. +class EmptyTestEventListener : public TestEventListener { + public: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +}; + +// TestEventListeners lets users add listeners to track events in Google Test. +class GTEST_API_ TestEventListeners { + public: + TestEventListeners(); + ~TestEventListeners(); + + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); + + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); + + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const { + return default_result_printer_; + } + + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const { + return default_xml_generator_; + } + + private: + friend class TestCase; + friend class TestInfo; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::UnitTestImpl; + + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); + + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); + + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); + + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); + + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; + + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); +}; + +// A UnitTest consists of a vector of TestCases. +// +// This is a singleton class. The only instance of UnitTest is +// created when UnitTest::GetInstance() is first called. This +// instance is never deleted. +// +// UnitTest is not copyable. +// +// This class is thread-safe as long as the methods are called +// according to their specification. +class GTEST_API_ UnitTest { + public: + // Gets the singleton UnitTest object. The first time this method + // is called, a UnitTest object is constructed and returned. + // Consecutive calls will return the same object. + static UnitTest* GetInstance(); + + // Runs all tests in this UnitTest object and prints the result. + // Returns 0 if successful, or 1 otherwise. + // + // This method can only be called from the main thread. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + int Run() GTEST_MUST_USE_RESULT_; + + // Returns the working directory when the first TEST() or TEST_F() + // was executed. The UnitTest object owns the string. + const char* original_working_dir() const; + + // Returns the TestCase object for the test that's currently running, + // or NULL if no test is running. + const TestCase* current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_); + + // Returns the TestInfo object for the test that's currently running, + // or NULL if no test is running. + const TestInfo* current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_); + + // Returns the random seed used at the start of the current test run. + int random_seed() const; + +#if GTEST_HAS_PARAM_TEST + // Returns the ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_); +#endif // GTEST_HAS_PARAM_TEST + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const; + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const; + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const; + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const; + + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); + + private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); + + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) + GTEST_LOCK_EXCLUDED_(mutex_); + + // Adds a TestProperty to the current TestResult object. If the result already + // contains a property with the same key, the value will be updated. + void RecordPropertyForCurrentTest(const char* key, const char* value); + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i); + + // Accessors for the implementation object. + internal::UnitTestImpl* impl() { return impl_; } + const internal::UnitTestImpl* impl() const { return impl_; } + + // These classes and funcions are friends as they need to access private + // members of UnitTest. + friend class Test; + friend class internal::AssertHelper; + friend class internal::ScopedTrace; + friend Environment* AddGlobalTestEnvironment(Environment* env); + friend internal::UnitTestImpl* internal::GetUnitTestImpl(); + friend void internal::ReportFailureInUnknownLocation( + TestPartResult::Type result_type, + const std::string& message); + + // Creates an empty UnitTest. + UnitTest(); + + // D'tor + virtual ~UnitTest(); + + // Pushes a trace defined by SCOPED_TRACE() on to the per-thread + // Google Test trace stack. + void PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_); + + // Pops a trace from the per-thread Google Test trace stack. + void PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_); + + // Protects mutable state in *impl_. This is mutable as some const + // methods need to lock it too. + mutable internal::Mutex mutex_; + + // Opaque implementation object. This field is never changed once + // the object is constructed. We don't mark it as const here, as + // doing so will cause a warning in the constructor of UnitTest. + // Mutable state in *impl_ is protected by mutex_. + internal::UnitTestImpl* impl_; + + // We disallow copying UnitTest. + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); +}; + +// A convenient wrapper for adding an environment for the test +// program. +// +// You should call this before RUN_ALL_TESTS() is called, probably in +// main(). If you use gtest_main, you need to call this before main() +// starts for it to take effect. For example, you can define a global +// variable like this: +// +// testing::Environment* const foo_env = +// testing::AddGlobalTestEnvironment(new FooEnvironment); +// +// However, we strongly recommend you to write your own main() and +// call AddGlobalTestEnvironment() there, as relying on initialization +// of global variables makes the code harder to read and may cause +// problems when you register multiple environments from different +// translation units and the environments have dependencies among them +// (remember that the compiler doesn't guarantee the order in which +// global variables from different translation units are initialized). +inline Environment* AddGlobalTestEnvironment(Environment* env) { + return UnitTest::GetInstance()->AddEnvironment(env); +} + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +GTEST_API_ void InitGoogleTest(int* argc, char** argv); + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); + +namespace internal { + +// FormatForComparison::Format(value) formats a +// value of type ToPrint that is an operand of a comparison assertion +// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in +// the comparison, and is used to help determine the best way to +// format the value. In particular, when the value is a C string +// (char pointer) and the other operand is an STL string object, we +// want to format the C string as a string, since we know it is +// compared by value with the string object. If the value is a char +// pointer but the other operand is not an STL string object, we don't +// know whether the pointer is supposed to point to a NUL-terminated +// string, and thus want to print it as a pointer to be safe. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// The default case. +template +class FormatForComparison { + public: + static ::std::string Format(const ToPrint& value) { + return ::testing::PrintToString(value); + } +}; + +// Array. +template +class FormatForComparison { + public: + static ::std::string Format(const ToPrint* value) { + return FormatForComparison::Format(value); + } +}; + +// By default, print C string as pointers to be safe, as we don't know +// whether they actually point to a NUL-terminated string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ + template \ + class FormatForComparison { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(static_cast(value)); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ + +// If a C string is compared with an STL string object, we know it's meant +// to point to a NUL-terminated string, and thus can print it as a string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ + template <> \ + class FormatForComparison { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(value); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); + +#if GTEST_HAS_GLOBAL_STRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); +#endif + +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); +#endif + +#if GTEST_HAS_STD_WSTRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); +#endif + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ + +// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) +// operand to be used in a failure message. The type (but not value) +// of the other operand may affect the format. This allows us to +// print a char* as a raw pointer when it is compared against another +// char* or void*, and print it as a C string when it is compared +// against an std::string object, for example. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +std::string FormatForComparisonFailureMessage( + const T1& value, const T2& /* other_operand */) { + return FormatForComparison::Format(value); +} + +// The helper function for {ASSERT|EXPECT}_EQ. +template +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4389) // Temporarily disables warning on + // signed/unsigned mismatch. +#endif + + if (expected == actual) { + return AssertionSuccess(); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// With this overloaded version, we allow anonymous enums to be used +// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums +// can be implicitly cast to BiggestInt. +GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual); + +// The helper class for {ASSERT|EXPECT}_EQ. The template argument +// lhs_is_null_literal is true iff the first argument to ASSERT_EQ() +// is a null pointer literal. The following default implementation is +// for lhs_is_null_literal being false. +template +class EqHelper { + public: + // This templatized version is for the general case. + template + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // With this overloaded version, we allow anonymous enums to be used + // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous + // enums can be implicitly cast to BiggestInt. + // + // Even though its body looks the same as the above version, we + // cannot merge the two, as it will make anonymous enums unhappy. + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } +}; + +// This specialization is used when the first argument to ASSERT_EQ() +// is a null pointer literal, like NULL, false, or 0. +template <> +class EqHelper { + public: + // We define two overloaded versions of Compare(). The first + // version will be picked when the second argument to ASSERT_EQ() is + // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or + // EXPECT_EQ(false, a_bool). + template + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual, + // The following line prevents this overload from being considered if T2 + // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) + // expands to Compare("", "", NULL, my_ptr), which requires a conversion + // to match the Secret* in the other overload, which would otherwise make + // this template match better. + typename EnableIf::value>::type* = 0) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // This version will be picked when the second argument to ASSERT_EQ() is a + // pointer, e.g. ASSERT_EQ(NULL, a_pointer). + template + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + // We used to have a second template parameter instead of Secret*. That + // template parameter would deduce to 'long', making this a better match + // than the first overload even without the first overload's EnableIf. + // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to + // non-pointer argument" (even a deduced integral argument), so the old + // implementation caused warnings in user code. + Secret* /* expected (NULL) */, + T* actual) { + // We already know that 'expected' is a null pointer. + return CmpHelperEQ(expected_expression, actual_expression, + static_cast(NULL), actual); + } +}; + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste +// of similar code. +// +// For each templatized helper function, we also define an overloaded +// version for BiggestInt in order to reduce code bloat and allow +// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled +// with gcc 4. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +template \ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + const T1& val1, const T2& val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +}\ +GTEST_API_ AssertionResult CmpHelper##op_name(\ + const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) + +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// Implements the helper function for {ASSERT|EXPECT}_NE +GTEST_IMPL_CMP_HELPER_(NE, !=); +// Implements the helper function for {ASSERT|EXPECT}_LE +GTEST_IMPL_CMP_HELPER_(LE, <=); +// Implements the helper function for {ASSERT|EXPECT}_LT +GTEST_IMPL_CMP_HELPER_(LT, <); +// Implements the helper function for {ASSERT|EXPECT}_GE +GTEST_IMPL_CMP_HELPER_(GE, >=); +// Implements the helper function for {ASSERT|EXPECT}_GT +GTEST_IMPL_CMP_HELPER_(GT, >); + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRNE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + + +// Helper function for *_STREQ on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual); + +// Helper function for *_STRNE on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); + +} // namespace internal + +// IsSubstring() and IsNotSubstring() are intended to be used as the +// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by +// themselves. They check whether needle is a substring of haystack +// (NULL is considered a substring of itself only), and return an +// appropriate error message when they fail. +// +// The {needle,haystack}_expr arguments are the stringified +// expressions that generated the two real arguments. +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +// Helper template function for comparing floating-points. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, + const char* actual_expression, + RawType expected, + RawType actual) { + const FloatingPoint lhs(expected), rhs(actual); + + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + ::std::stringstream expected_ss; + expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << expected; + + ::std::stringstream actual_ss; + actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << actual; + + return EqFailure(expected_expression, + actual_expression, + StringStreamToString(&expected_ss), + StringStreamToString(&actual_ss), + false); +} + +// Helper function for implementing ASSERT_NEAR. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// A class that enables one to stream messages to assertion macros +class GTEST_API_ AssertHelper { + public: + // Constructor. + AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message); + ~AssertHelper(); + + // Message assignment is a semantic trick to enable assertion + // streaming; see the GTEST_MESSAGE_ macro below. + void operator=(const Message& message) const; + + private: + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) { } + + TestPartResult::Type const type; + const char* const file; + int const line; + std::string const message; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; + + AssertHelperData* const data_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); +}; + +} // namespace internal + +#if GTEST_HAS_PARAM_TEST +// The pure interface class that all value-parameterized tests inherit from. +// A value-parameterized class must inherit from both ::testing::Test and +// ::testing::WithParamInterface. In most cases that just means inheriting +// from ::testing::TestWithParam, but more complicated test hierarchies +// may need to inherit from Test and WithParamInterface at different levels. +// +// This interface has support for accessing the test parameter value via +// the GetParam() method. +// +// Use it with one of the parameter generator defining functions, like Range(), +// Values(), ValuesIn(), Bool(), and Combine(). +// +// class FooTest : public ::testing::TestWithParam { +// protected: +// FooTest() { +// // Can use GetParam() here. +// } +// virtual ~FooTest() { +// // Can use GetParam() here. +// } +// virtual void SetUp() { +// // Can use GetParam() here. +// } +// virtual void TearDown { +// // Can use GetParam() here. +// } +// }; +// TEST_P(FooTest, DoesBar) { +// // Can use GetParam() method here. +// Foo foo; +// ASSERT_TRUE(foo.DoesBar(GetParam())); +// } +// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); + +template +class WithParamInterface { + public: + typedef T ParamType; + virtual ~WithParamInterface() {} + + // The current parameter value. Is also available in the test fixture's + // constructor. This member function is non-static, even though it only + // references static data, to reduce the opportunity for incorrect uses + // like writing 'WithParamInterface::GetParam()' for a test that + // uses a fixture whose parameter type is int. + const ParamType& GetParam() const { return *parameter_; } + + private: + // Sets parameter value. The caller is responsible for making sure the value + // remains alive and unchanged throughout the current test. + static void SetParam(const ParamType* parameter) { + parameter_ = parameter; + } + + // Static value used for accessing parameter during a test lifetime. + static const ParamType* parameter_; + + // TestClass must be a subclass of WithParamInterface and Test. + template friend class internal::ParameterizedTestFactory; +}; + +template +const T* WithParamInterface::parameter_ = NULL; + +// Most value-parameterized classes can ignore the existence of +// WithParamInterface, and can just inherit from ::testing::TestWithParam. + +template +class TestWithParam : public Test, public WithParamInterface { +}; + +#endif // GTEST_HAS_PARAM_TEST + +// Macros for indicating success/failure in test code. + +// ADD_FAILURE unconditionally adds a failure to the current test. +// SUCCEED generates a success - it doesn't automatically make the +// current test successful, as a test is only successful when it has +// no failure. +// +// EXPECT_* verifies that a certain condition is satisfied. If not, +// it behaves like ADD_FAILURE. In particular: +// +// EXPECT_TRUE verifies that a Boolean condition is true. +// EXPECT_FALSE verifies that a Boolean condition is false. +// +// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except +// that they will also abort the current function on failure. People +// usually want the fail-fast behavior of FAIL and ASSERT_*, but those +// writing data-driven tests often find themselves using ADD_FAILURE +// and EXPECT_* more. + +// Generates a nonfatal failure with a generic message. +#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") + +// Generates a nonfatal failure at the given source file location with +// a generic message. +#define ADD_FAILURE_AT(file, line) \ + GTEST_MESSAGE_AT_(file, line, "Failed", \ + ::testing::TestPartResult::kNonFatalFailure) + +// Generates a fatal failure with a generic message. +#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") + +// Define this macro to 1 to omit the definition of FAIL(), which is a +// generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_FAIL +# define FAIL() GTEST_FAIL() +#endif + +// Generates a success with a generic message. +#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") + +// Define this macro to 1 to omit the definition of SUCCEED(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_SUCCEED +# define SUCCEED() GTEST_SUCCEED() +#endif + +// Macros for testing exceptions. +// +// * {ASSERT|EXPECT}_THROW(statement, expected_exception): +// Tests that the statement throws the expected exception. +// * {ASSERT|EXPECT}_NO_THROW(statement): +// Tests that the statement doesn't throw any exception. +// * {ASSERT|EXPECT}_ANY_THROW(statement): +// Tests that the statement throws an exception. + +#define EXPECT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) +#define EXPECT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define EXPECT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define ASSERT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) +#define ASSERT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) +#define ASSERT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) + +// Boolean assertions. Condition can be either a Boolean expression or an +// AssertionResult. For more information on how to use AssertionResult with +// these macros see comments on that class. +#define EXPECT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_NONFATAL_FAILURE_) +#define EXPECT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_NONFATAL_FAILURE_) +#define ASSERT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_FATAL_FAILURE_) +#define ASSERT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_FATAL_FAILURE_) + +// Includes the auto-generated header that implements a family of +// generic predicate assertion macros. +#include "gtest/gtest_pred_impl.h" + +// Macros for testing equalities and inequalities. +// +// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual +// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 +// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 +// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 +// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 +// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 +// +// When they are not, Google Test prints both the tested expressions and +// their actual values. The values must be compatible built-in types, +// or you will get a compiler error. By "compatible" we mean that the +// values can be compared by the respective operator. +// +// Note: +// +// 1. It is possible to make a user-defined type work with +// {ASSERT|EXPECT}_??(), but that requires overloading the +// comparison operators and is thus discouraged by the Google C++ +// Usage Guide. Therefore, you are advised to use the +// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are +// equal. +// +// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on +// pointers (in particular, C strings). Therefore, if you use it +// with two C strings, you are testing how their locations in memory +// are related, not how their content is related. To compare two C +// strings by content, use {ASSERT|EXPECT}_STR*(). +// +// 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to +// {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you +// what the actual value is when it fails, and similarly for the +// other comparisons. +// +// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() +// evaluate their arguments, which is undefined. +// +// 5. These macros evaluate their arguments exactly once. +// +// Examples: +// +// EXPECT_NE(5, Foo()); +// EXPECT_EQ(NULL, a_pointer); +// ASSERT_LT(i, array_size); +// ASSERT_GT(records.size(), 0) << "There is no record left."; + +#define EXPECT_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define EXPECT_NE(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) +#define EXPECT_LE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define EXPECT_LT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define EXPECT_GE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define EXPECT_GT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +#define GTEST_ASSERT_EQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define GTEST_ASSERT_NE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) +#define GTEST_ASSERT_LE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define GTEST_ASSERT_LT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define GTEST_ASSERT_GE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define GTEST_ASSERT_GT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of +// ASSERT_XY(), which clashes with some users' own code. + +#if !GTEST_DONT_DEFINE_ASSERT_EQ +# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_NE +# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LE +# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LT +# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GE +# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GT +# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) +#endif + +// C-string Comparisons. All tests treat NULL and any non-NULL string +// as different. Two NULLs are equal. +// +// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 +// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 +// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case +// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case +// +// For wide or narrow string objects, you can use the +// {ASSERT|EXPECT}_??() macros. +// +// Don't depend on the order in which the arguments are evaluated, +// which is undefined. +// +// These macros evaluate their arguments exactly once. + +#define EXPECT_STREQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define EXPECT_STRNE(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define EXPECT_STRCASEEQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define EXPECT_STRCASENE(s1, s2)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +#define ASSERT_STREQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define ASSERT_STRNE(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define ASSERT_STRCASEEQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define ASSERT_STRCASENE(s1, s2)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +// Macros for comparing floating-point numbers. +// +// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): +// Tests that two float values are almost equal. +// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): +// Tests that two double values are almost equal. +// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): +// Tests that v1 and v2 are within the given distance to each other. +// +// Google Test uses ULP-based comparison to automatically pick a default +// error bound that is appropriate for the operands. See the +// FloatingPoint template class in gtest-internal.h if you are +// interested in the implementation details. + +#define EXPECT_FLOAT_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_DOUBLE_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_FLOAT_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_DOUBLE_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_NEAR(val1, val2, abs_error)\ + EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +#define ASSERT_NEAR(val1, val2, abs_error)\ + ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +// These predicate format functions work on floating-point values, and +// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. +// +// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2); +GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2); + + +#if GTEST_OS_WINDOWS + +// Macros that test for HRESULT failure and success, these are only useful +// on Windows, and rely on Windows SDK macros and APIs to compile. +// +// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) +// +// When expr unexpectedly fails or succeeds, Google Test prints the +// expected result and the actual result with both a human-readable +// string representation of the error, if available, as well as the +// hex result code. +# define EXPECT_HRESULT_SUCCEEDED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define ASSERT_HRESULT_SUCCEEDED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define EXPECT_HRESULT_FAILED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +# define ASSERT_HRESULT_FAILED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#endif // GTEST_OS_WINDOWS + +// Macros that execute statement and check that it doesn't generate new fatal +// failures in the current thread. +// +// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); +// +// Examples: +// +// EXPECT_NO_FATAL_FAILURE(Process()); +// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; +// +#define ASSERT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) +#define EXPECT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + +// Causes a trace (including the source file path, the current line +// number, and the given message) to be included in every test failure +// message generated by code in the current scope. The effect is +// undone when the control leaves the current scope. +// +// The message argument can be anything streamable to std::ostream. +// +// In the implementation, we include the current line number as part +// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s +// to appear in the same block - as long as they are on different +// lines. +#define SCOPED_TRACE(message) \ + ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ + __FILE__, __LINE__, ::testing::Message() << (message)) + +// Compile-time assertion for type equality. +// StaticAssertTypeEq() compiles iff type1 and type2 are +// the same type. The value it returns is not interesting. +// +// Instead of making StaticAssertTypeEq a class template, we make it a +// function template that invokes a helper class template. This +// prevents a user from misusing StaticAssertTypeEq by +// defining objects of that type. +// +// CAVEAT: +// +// When used inside a method of a class template, +// StaticAssertTypeEq() is effective ONLY IF the method is +// instantiated. For example, given: +// +// template class Foo { +// public: +// void Bar() { testing::StaticAssertTypeEq(); } +// }; +// +// the code: +// +// void Test1() { Foo foo; } +// +// will NOT generate a compiler error, as Foo::Bar() is never +// actually instantiated. Instead, you need: +// +// void Test2() { Foo foo; foo.Bar(); } +// +// to cause a compiler error. +template +bool StaticAssertTypeEq() { + (void)internal::StaticAssertTypeEqHelper(); + return true; +} + +// Defines a test. +// +// The first parameter is the name of the test case, and the second +// parameter is the name of the test within the test case. +// +// The convention is to end the test case name with "Test". For +// example, a test case for the Foo class can be named FooTest. +// +// The user should put his test code between braces after using this +// macro. Example: +// +// TEST(FooTest, InitializesCorrectly) { +// Foo foo; +// EXPECT_TRUE(foo.StatusIsOK()); +// } + +// Note that we call GetTestTypeId() instead of GetTypeId< +// ::testing::Test>() here to get the type ID of testing::Test. This +// is to work around a suspected linker bug when using Google Test as +// a framework on Mac OS X. The bug causes GetTypeId< +// ::testing::Test>() to return different values depending on whether +// the call is from the Google Test framework itself or from user test +// code. GetTestTypeId() is guaranteed to always return the same +// value, as it always calls GetTypeId<>() from the Google Test +// framework. +#define GTEST_TEST(test_case_name, test_name)\ + GTEST_TEST_(test_case_name, test_name, \ + ::testing::Test, ::testing::internal::GetTestTypeId()) + +// Define this macro to 1 to omit the definition of TEST(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_TEST +# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) +#endif + +// Defines a test that uses a test fixture. +// +// The first parameter is the name of the test fixture class, which +// also doubles as the test case name. The second parameter is the +// name of the test within the test case. +// +// A test fixture class must be declared earlier. The user should put +// his test code between braces after using this macro. Example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { b_.AddElement(3); } +// +// Foo a_; +// Foo b_; +// }; +// +// TEST_F(FooTest, InitializesCorrectly) { +// EXPECT_TRUE(a_.StatusIsOK()); +// } +// +// TEST_F(FooTest, ReturnsElementCountCorrectly) { +// EXPECT_EQ(0, a_.size()); +// EXPECT_EQ(1, b_.size()); +// } + +#define TEST_F(test_fixture, test_name)\ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ + ::testing::internal::GetTypeId()) + +// Use this macro in main() to run all tests. It returns 0 if all +// tests are successful, or 1 otherwise. +// +// RUN_ALL_TESTS() should be invoked after the command line has been +// parsed by InitGoogleTest(). + +#define RUN_ALL_TESTS()\ + (::testing::UnitTest::GetInstance()->Run()) + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest_pred_impl.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest_pred_impl.h new file mode 100644 index 0000000..30ae712 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest_pred_impl.h @@ -0,0 +1,358 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Makes sure this header is not included before gtest.h. +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most 5. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar = (expression)) \ + ; \ + else \ + on_failure(gtest_ar.failure_message()) + + +// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +template +AssertionResult AssertPred1Helper(const char* pred_text, + const char* e1, + Pred pred, + const T1& v1) { + if (pred(v1)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. +// Don't use this in your code. +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, v1), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +#define GTEST_PRED1_(pred, v1, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ + #v1, \ + pred, \ + v1), on_failure) + +// Unary predicate assertion macros. +#define EXPECT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +template +AssertionResult AssertPred2Helper(const char* pred_text, + const char* e1, + const char* e2, + Pred pred, + const T1& v1, + const T2& v2) { + if (pred(v1, v2)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. +// Don't use this in your code. +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +#define GTEST_PRED2_(pred, v1, v2, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ + #v1, \ + #v2, \ + pred, \ + v1, \ + v2), on_failure) + +// Binary predicate assertion macros. +#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +template +AssertionResult AssertPred3Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3) { + if (pred(v1, v2, v3)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. +// Don't use this in your code. +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + pred, \ + v1, \ + v2, \ + v3), on_failure) + +// Ternary predicate assertion macros. +#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +template +AssertionResult AssertPred4Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (pred(v1, v2, v3, v4)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. +// Don't use this in your code. +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4), on_failure) + +// 4-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +template +AssertionResult AssertPred5Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ", " + << e5 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4 + << "\n" << e5 << " evaluates to " << v5; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. +// Don't use this in your code. +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + #v5, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4, \ + v5), on_failure) + +// 5-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) + + + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest_prod.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest_prod.h new file mode 100644 index 0000000..da80ddc --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/gtest_prod.h @@ -0,0 +1,58 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Google C++ Testing Framework definitions useful in production code. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ + +// When you need to test the private or protected members of a class, +// use the FRIEND_TEST macro to declare your tests as friends of the +// class. For example: +// +// class MyClass { +// private: +// void MyMethod(); +// FRIEND_TEST(MyClassTest, MyMethod); +// }; +// +// class MyClassTest : public testing::Test { +// // ... +// }; +// +// TEST_F(MyClassTest, MyMethod) { +// // Can call MyClass::MyMethod() here. +// } + +#define FRIEND_TEST(test_case_name, test_name)\ +friend class test_case_name##_##test_name##_Test + +#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-death-test-internal.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-death-test-internal.h new file mode 100644 index 0000000..2b3a78f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-death-test-internal.h @@ -0,0 +1,319 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines internal utilities needed for implementing +// death tests. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + +#include "gtest/internal/gtest-internal.h" + +#include + +namespace testing { +namespace internal { + +GTEST_DECLARE_string_(internal_run_death_test); + +// Names of the flags (needed for parsing Google Test flags). +const char kDeathTestStyleFlag[] = "death_test_style"; +const char kDeathTestUseFork[] = "death_test_use_fork"; +const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; + +#if GTEST_HAS_DEATH_TEST + +// DeathTest is a class that hides much of the complexity of the +// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method +// returns a concrete class that depends on the prevailing death test +// style, as defined by the --gtest_death_test_style and/or +// --gtest_internal_run_death_test flags. + +// In describing the results of death tests, these terms are used with +// the corresponding definitions: +// +// exit status: The integer exit information in the format specified +// by wait(2) +// exit code: The integer code passed to exit(3), _exit(2), or +// returned from main() +class GTEST_API_ DeathTest { + public: + // Create returns false if there was an error determining the + // appropriate action to take for the current death test; for example, + // if the gtest_death_test_style flag is set to an invalid value. + // The LastMessage method will return a more detailed message in that + // case. Otherwise, the DeathTest pointer pointed to by the "test" + // argument is set. If the death test should be skipped, the pointer + // is set to NULL; otherwise, it is set to the address of a new concrete + // DeathTest object that controls the execution of the current test. + static bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); + DeathTest(); + virtual ~DeathTest() { } + + // A helper class that aborts a death test when it's deleted. + class ReturnSentinel { + public: + explicit ReturnSentinel(DeathTest* test) : test_(test) { } + ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } + private: + DeathTest* const test_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); + } GTEST_ATTRIBUTE_UNUSED_; + + // An enumeration of possible roles that may be taken when a death + // test is encountered. EXECUTE means that the death test logic should + // be executed immediately. OVERSEE means that the program should prepare + // the appropriate environment for a child process to execute the death + // test, then wait for it to complete. + enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; + + // An enumeration of the three reasons that a test might be aborted. + enum AbortReason { + TEST_ENCOUNTERED_RETURN_STATEMENT, + TEST_THREW_EXCEPTION, + TEST_DID_NOT_DIE + }; + + // Assumes one of the above roles. + virtual TestRole AssumeRole() = 0; + + // Waits for the death test to finish and returns its status. + virtual int Wait() = 0; + + // Returns true if the death test passed; that is, the test process + // exited during the test, its exit status matches a user-supplied + // predicate, and its stderr output matches a user-supplied regular + // expression. + // The user-supplied predicate may be a macro expression rather + // than a function pointer or functor, or else Wait and Passed could + // be combined. + virtual bool Passed(bool exit_status_ok) = 0; + + // Signals that the death test did not die as expected. + virtual void Abort(AbortReason reason) = 0; + + // Returns a human-readable outcome message regarding the outcome of + // the last death test. + static const char* LastMessage(); + + static void set_last_death_test_message(const std::string& message); + + private: + // A string containing a description of the outcome of the last death test. + static std::string last_death_test_message_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); +}; + +// Factory interface for death tests. May be mocked out for testing. +class DeathTestFactory { + public: + virtual ~DeathTestFactory() { } + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) = 0; +}; + +// A concrete DeathTestFactory implementation for normal use. +class DefaultDeathTestFactory : public DeathTestFactory { + public: + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); +}; + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +GTEST_API_ bool ExitedUnsuccessfully(int exit_status); + +// Traps C++ exceptions escaping statement and reports them as test +// failures. Note that trapping SEH exceptions is not implemented here. +# if GTEST_HAS_EXCEPTIONS +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (const ::std::exception& gtest_exception) { \ + fprintf(\ + stderr, \ + "\n%s: Caught std::exception-derived exception escaping the " \ + "death test statement. Exception message: %s\n", \ + ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ + gtest_exception.what()); \ + fflush(stderr); \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } catch (...) { \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } + +# else +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) + +# endif + +// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, +// ASSERT_EXIT*, and EXPECT_EXIT*. +# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + const ::testing::internal::RE& gtest_regex = (regex); \ + ::testing::internal::DeathTest* gtest_dt; \ + if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ + __FILE__, __LINE__, >est_dt)) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + if (gtest_dt != NULL) { \ + ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ + gtest_dt_ptr(gtest_dt); \ + switch (gtest_dt->AssumeRole()) { \ + case ::testing::internal::DeathTest::OVERSEE_TEST: \ + if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + break; \ + case ::testing::internal::DeathTest::EXECUTE_TEST: { \ + ::testing::internal::DeathTest::ReturnSentinel \ + gtest_sentinel(gtest_dt); \ + GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ + gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ + break; \ + } \ + default: \ + break; \ + } \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ + fail(::testing::internal::DeathTest::LastMessage()) +// The symbol "fail" here expands to something into which a message +// can be streamed. + +// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in +// NDEBUG mode. In this case we need the statements to be executed, the regex is +// ignored, and the macro must accept a streamed message even though the message +// is never printed. +# define GTEST_EXECUTE_STATEMENT_(statement, regex) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } else \ + ::testing::Message() + +// A class representing the parsed contents of the +// --gtest_internal_run_death_test flag, as it existed when +// RUN_ALL_TESTS was called. +class InternalRunDeathTestFlag { + public: + InternalRunDeathTestFlag(const std::string& a_file, + int a_line, + int an_index, + int a_write_fd) + : file_(a_file), line_(a_line), index_(an_index), + write_fd_(a_write_fd) {} + + ~InternalRunDeathTestFlag() { + if (write_fd_ >= 0) + posix::Close(write_fd_); + } + + const std::string& file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int write_fd() const { return write_fd_; } + + private: + std::string file_; + int line_; + int index_; + int write_fd_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); +}; + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); + +#else // GTEST_HAS_DEATH_TEST + +// This macro is used for implementing macros such as +// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where +// death tests are not supported. Those macros must compile on such systems +// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on +// systems that support death tests. This allows one to write such a macro +// on a system that does not support death tests and be sure that it will +// compile on a death-test supporting system. +// +// Parameters: +// statement - A statement that a macro such as EXPECT_DEATH would test +// for program termination. This macro has to make sure this +// statement is compiled but not executed, to ensure that +// EXPECT_DEATH_IF_SUPPORTED compiles with a certain +// parameter iff EXPECT_DEATH compiles with it. +// regex - A regex that a macro such as EXPECT_DEATH would use to test +// the output of statement. This parameter has to be +// compiled but not evaluated by this macro, to ensure that +// this macro only accepts expressions that a macro such as +// EXPECT_DEATH would accept. +// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED +// and a return statement for ASSERT_DEATH_IF_SUPPORTED. +// This ensures that ASSERT_DEATH_IF_SUPPORTED will not +// compile inside functions where ASSERT_DEATH doesn't +// compile. +// +// The branch that has an always false condition is used to ensure that +// statement and regex are compiled (and thus syntactically correct) but +// never executed. The unreachable code macro protects the terminator +// statement from generating an 'unreachable code' warning in case +// statement unconditionally returns or throws. The Message constructor at +// the end allows the syntax of streaming additional messages into the +// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. +# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-filepath.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-filepath.h new file mode 100644 index 0000000..7a13b4b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-filepath.h @@ -0,0 +1,206 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This header file declares classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included in . +// Do not include this header file separately! + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ + +#include "gtest/internal/gtest-string.h" + +namespace testing { +namespace internal { + +// FilePath - a class for file and directory pathname manipulation which +// handles platform-specific conventions (like the pathname separator). +// Used for helper functions for naming files in a directory for xml output. +// Except for Set methods, all methods are const or static, which provides an +// "immutable value object" -- useful for peace of mind. +// A FilePath with a value ending in a path separator ("like/this/") represents +// a directory, otherwise it is assumed to represent a file. In either case, +// it may or may not represent an actual file or directory in the file system. +// Names are NOT checked for syntax correctness -- no checking for illegal +// characters, malformed paths, etc. + +class GTEST_API_ FilePath { + public: + FilePath() : pathname_("") { } + FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } + + explicit FilePath(const std::string& pathname) : pathname_(pathname) { + Normalize(); + } + + FilePath& operator=(const FilePath& rhs) { + Set(rhs); + return *this; + } + + void Set(const FilePath& rhs) { + pathname_ = rhs.pathname_; + } + + const std::string& string() const { return pathname_; } + const char* c_str() const { return pathname_.c_str(); } + + // Returns the current working directory, or "" if unsuccessful. + static FilePath GetCurrentDir(); + + // Given directory = "dir", base_name = "test", number = 0, + // extension = "xml", returns "dir/test.xml". If number is greater + // than zero (e.g., 12), returns "dir/test_12.xml". + // On Windows platform, uses \ as the separator rather than /. + static FilePath MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension); + + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); + + // Returns a pathname for a file that does not currently exist. The pathname + // will be directory/base_name.extension or + // directory/base_name_.extension if directory/base_name.extension + // already exists. The number will be incremented until a pathname is found + // that does not already exist. + // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. + // There could be a race condition if two or more processes are calling this + // function at the same time -- they could both pick the same filename. + static FilePath GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension); + + // Returns true iff the path is "". + bool IsEmpty() const { return pathname_.empty(); } + + // If input name has a trailing separator character, removes it and returns + // the name, otherwise return the name string unmodified. + // On Windows platform, uses \ as the separator, other platforms use /. + FilePath RemoveTrailingPathSeparator() const; + + // Returns a copy of the FilePath with the directory part removed. + // Example: FilePath("path/to/file").RemoveDirectoryName() returns + // FilePath("file"). If there is no directory part ("just_a_file"), it returns + // the FilePath unmodified. If there is no file part ("just_a_dir/") it + // returns an empty FilePath (""). + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveDirectoryName() const; + + // RemoveFileName returns the directory path with the filename removed. + // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". + // If the FilePath is "a_file" or "/a_file", RemoveFileName returns + // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does + // not have a file, like "just/a/dir/", it returns the FilePath unmodified. + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveFileName() const; + + // Returns a copy of the FilePath with the case-insensitive extension removed. + // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns + // FilePath("dir/file"). If a case-insensitive extension is not + // found, returns a copy of the original FilePath. + FilePath RemoveExtension(const char* extension) const; + + // Creates directories so that path exists. Returns true if successful or if + // the directories already exist; returns false if unable to create + // directories for any reason. Will also return false if the FilePath does + // not represent a directory (that is, it doesn't end with a path separator). + bool CreateDirectoriesRecursively() const; + + // Create the directory so that path exists. Returns true if successful or + // if the directory already exists; returns false if unable to create the + // directory for any reason, including if the parent directory does not + // exist. Not named "CreateDirectory" because that's a macro on Windows. + bool CreateFolder() const; + + // Returns true if FilePath describes something in the file-system, + // either a file, directory, or whatever, and that something exists. + bool FileOrDirectoryExists() const; + + // Returns true if pathname describes a directory in the file-system + // that exists. + bool DirectoryExists() const; + + // Returns true if FilePath ends with a path separator, which indicates that + // it is intended to represent a directory. Returns false otherwise. + // This does NOT check that a directory (or file) actually exists. + bool IsDirectory() const; + + // Returns true if pathname describes a root directory. (Windows has one + // root directory per disk drive.) + bool IsRootDirectory() const; + + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; + + private: + // Replaces multiple consecutive separators with a single separator. + // For example, "bar///foo" becomes "bar/foo". Does not eliminate other + // redundancies that might be in a pathname involving "." or "..". + // + // A pathname with multiple consecutive separators may occur either through + // user error or as a result of some scripts or APIs that generate a pathname + // with a trailing separator. On other platforms the same API or script + // may NOT generate a pathname with a trailing "/". Then elsewhere that + // pathname may have another "/" and pathname components added to it, + // without checking for the separator already being there. + // The script language and operating system may allow paths like "foo//bar" + // but some of the functions in FilePath will not handle that correctly. In + // particular, RemoveTrailingPathSeparator() only removes one separator, and + // it is called in CreateDirectoriesRecursively() assuming that it will change + // a pathname from directory syntax (trailing separator) to filename syntax. + // + // On Windows this method also replaces the alternate path separator '/' with + // the primary path separator '\\', so that for example "bar\\/\\foo" becomes + // "bar\\foo". + + void Normalize(); + + // Returns a pointer to the last occurence of a valid path separator in + // the FilePath. On Windows, for example, both '/' and '\' are valid path + // separators. Returns NULL if no path separator was found. + const char* FindLastPathSeparator() const; + + std::string pathname_; +}; // class FilePath + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-internal.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-internal.h new file mode 100644 index 0000000..6e3dd66 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-internal.h @@ -0,0 +1,1171 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares functions and macros used internally by +// Google Test. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + +#include "gtest/internal/gtest-port.h" + +#if GTEST_OS_LINUX +# include +# include +# include +# include +#endif // GTEST_OS_LINUX + +#include +#include +#include +#include +#include + +#include "gtest/internal/gtest-string.h" +#include "gtest/internal/gtest-filepath.h" +#include "gtest/internal/gtest-type-util.h" + +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__. Writing +// +// foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number. For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar + +// Google Test defines the testing::Message class to allow construction of +// test messages via the << operator. The idea is that anything +// streamable to std::ostream can be streamed to a testing::Message. +// This allows a user to use his own types in Google Test assertions by +// overloading the << operator. +// +// util/gtl/stl_logging.h overloads << for STL containers. These +// overloads cannot be defined in the std namespace, as that will be +// undefined behavior. Therefore, they are defined in the global +// namespace instead. +// +// C++'s symbol lookup rule (i.e. Koenig lookup) says that these +// overloads are visible in either the std namespace or the global +// namespace, but not other namespaces, including the testing +// namespace which Google Test's Message class is in. +// +// To allow STL containers (and other types that has a << operator +// defined in the global namespace) to be used in Google Test assertions, +// testing::Message must access the custom << operator from the global +// namespace. Hence this helper function. +// +// Note: Jeffrey Yasskin suggested an alternative fix by "using +// ::operator<<;" in the definition of Message's operator<<. That fix +// doesn't require a helper function, but unfortunately doesn't +// compile with MSVC. +template +inline void GTestStreamToHelper(std::ostream* os, const T& val) { + *os << val; +} + +class ProtocolMessage; +namespace proto2 { class Message; } + +namespace testing { + +// Forward declarations. + +class AssertionResult; // Result of an assertion. +class Message; // Represents a failure message. +class Test; // Represents a test. +class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. +class UnitTest; // A collection of test cases. + +template +::std::string PrintToString(const T& value); + +namespace internal { + +struct TraceInfo; // Information about a trace point. +class ScopedTrace; // Implements scoped trace. +class TestInfoImpl; // Opaque implementation of TestInfo +class UnitTestImpl; // Opaque implementation of UnitTest + +// How many times InitGoogleTest() has been called. +GTEST_API_ extern int g_init_gtest_count; + +// The text used in failure messages to indicate the start of the +// stack trace. +GTEST_API_ extern const char kStackTraceMarker[]; + +// A secret type that Google Test users don't know about. It has no +// definition on purpose. Therefore it's impossible to create a +// Secret object, which is what we want. +class Secret; + +// Two overloaded helpers for checking at compile time whether an +// expression is a null pointer literal (i.e. NULL or any 0-valued +// compile-time integral constant). Their return values have +// different sizes, so we can use sizeof() to test which version is +// picked by the compiler. These helpers have no implementations, as +// we only need their signatures. +// +// Given IsNullLiteralHelper(x), the compiler will pick the first +// version if x can be implicitly converted to Secret*, and pick the +// second version otherwise. Since Secret is a secret and incomplete +// type, the only expression a user can write that has type Secret* is +// a null pointer literal. Therefore, we know that x is a null +// pointer literal if and only if the first version is picked by the +// compiler. +char IsNullLiteralHelper(Secret* p); +char (&IsNullLiteralHelper(...))[2]; // NOLINT + +// A compile-time bool constant that is true if and only if x is a +// null pointer literal (i.e. NULL or any 0-valued compile-time +// integral constant). +#ifdef GTEST_ELLIPSIS_NEEDS_POD_ +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +# define GTEST_IS_NULL_LITERAL_(x) false +#else +# define GTEST_IS_NULL_LITERAL_(x) \ + (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) +#endif // GTEST_ELLIPSIS_NEEDS_POD_ + +// Appends the user-supplied message to the Google-Test-generated message. +GTEST_API_ std::string AppendUserMessage( + const std::string& gtest_msg, const Message& user_msg); + +// A helper class for creating scoped traces in user programs. +class GTEST_API_ ScopedTrace { + public: + // The c'tor pushes the given source file location and message onto + // a trace stack maintained by Google Test. + ScopedTrace(const char* file, int line, const Message& message); + + // The d'tor pops the info pushed by the c'tor. + // + // Note that the d'tor is not virtual in order to be efficient. + // Don't inherit from ScopedTrace! + ~ScopedTrace(); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); +} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its + // c'tor and d'tor. Therefore it doesn't + // need to be used otherwise. + +// Converts a streamable value to an std::string. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +std::string StreamableToString(const T& streamable); + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +GTEST_API_ AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case); + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +GTEST_API_ std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value); + +// This template class represents an IEEE floating-point number +// (either single-precision or double-precision, depending on the +// template parameters). +// +// The purpose of this class is to do more sophisticated number +// comparison. (Due to round-off error, etc, it's very unlikely that +// two floating-points will be equal exactly. Hence a naive +// comparison by the == operation often doesn't work.) +// +// Format of IEEE floating-point: +// +// The most-significant bit being the leftmost, an IEEE +// floating-point looks like +// +// sign_bit exponent_bits fraction_bits +// +// Here, sign_bit is a single bit that designates the sign of the +// number. +// +// For float, there are 8 exponent bits and 23 fraction bits. +// +// For double, there are 11 exponent bits and 52 fraction bits. +// +// More details can be found at +// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +template +class FloatingPoint { + public: + // Defines the unsigned integer type that has the same size as the + // floating point number. + typedef typename TypeWithSize::UInt Bits; + + // Constants. + + // # of bits in a number. + static const size_t kBitCount = 8*sizeof(RawType); + + // # of fraction bits in a number. + static const size_t kFractionBitCount = + std::numeric_limits::digits - 1; + + // # of exponent bits in a number. + static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; + + // The mask for the sign bit. + static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); + + // The mask for the fraction bits. + static const Bits kFractionBitMask = + ~static_cast(0) >> (kExponentBitCount + 1); + + // The mask for the exponent bits. + static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); + + // How many ULP's (Units in the Last Place) we want to tolerate when + // comparing two numbers. The larger the value, the more error we + // allow. A 0 value means that two numbers must be exactly the same + // to be considered equal. + // + // The maximum error of a single floating-point operation is 0.5 + // units in the last place. On Intel CPU's, all floating-point + // calculations are done with 80-bit precision, while double has 64 + // bits. Therefore, 4 should be enough for ordinary use. + // + // See the following article for more details on ULP: + // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm. + static const size_t kMaxUlps = 4; + + // Constructs a FloatingPoint from a raw floating-point number. + // + // On an Intel CPU, passing a non-normalized NAN (Not a Number) + // around may change its bits, although the new value is guaranteed + // to be also a NAN. Therefore, don't expect this constructor to + // preserve the bits in x when x is a NAN. + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } + + // Static methods + + // Reinterprets a bit pattern as a floating-point number. + // + // This function is needed to test the AlmostEquals() method. + static RawType ReinterpretBits(const Bits bits) { + FloatingPoint fp(0); + fp.u_.bits_ = bits; + return fp.u_.value_; + } + + // Returns the floating-point number that represent positive infinity. + static RawType Infinity() { + return ReinterpretBits(kExponentBitMask); + } + + // Non-static methods + + // Returns the bits that represents this number. + const Bits &bits() const { return u_.bits_; } + + // Returns the exponent bits of this number. + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } + + // Returns the fraction bits of this number. + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } + + // Returns the sign bit of this number. + Bits sign_bit() const { return kSignBitMask & u_.bits_; } + + // Returns true iff this is NAN (not a number). + bool is_nan() const { + // It's a NAN if the exponent bits are all ones and the fraction + // bits are not entirely zeros. + return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); + } + + // Returns true iff this number is at most kMaxUlps ULP's away from + // rhs. In particular, this function: + // + // - returns false if either number is (or both are) NAN. + // - treats really large numbers as almost equal to infinity. + // - thinks +0.0 and -0.0 are 0 DLP's apart. + bool AlmostEquals(const FloatingPoint& rhs) const { + // The IEEE standard says that any comparison operation involving + // a NAN must return false. + if (is_nan() || rhs.is_nan()) return false; + + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) + <= kMaxUlps; + } + + private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; + + // Converts an integer from the sign-and-magnitude representation to + // the biased representation. More precisely, let N be 2 to the + // power of (kBitCount - 1), an integer x is represented by the + // unsigned number x + N. + // + // For instance, + // + // -N + 1 (the most negative number representable using + // sign-and-magnitude) is represented by 1; + // 0 is represented by N; and + // N - 1 (the biggest number representable using + // sign-and-magnitude) is represented by 2N - 1. + // + // Read http://en.wikipedia.org/wiki/Signed_number_representations + // for more details on signed number representations. + static Bits SignAndMagnitudeToBiased(const Bits &sam) { + if (kSignBitMask & sam) { + // sam represents a negative number. + return ~sam + 1; + } else { + // sam represents a positive number. + return kSignBitMask | sam; + } + } + + // Given two numbers in the sign-and-magnitude representation, + // returns the distance between them as an unsigned number. + static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, + const Bits &sam2) { + const Bits biased1 = SignAndMagnitudeToBiased(sam1); + const Bits biased2 = SignAndMagnitudeToBiased(sam2); + return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); + } + + FloatingPointUnion u_; +}; + +// Typedefs the instances of the FloatingPoint template class that we +// care to use. +typedef FloatingPoint Float; +typedef FloatingPoint Double; + +// In order to catch the mistake of putting tests that use different +// test fixture classes in the same test case, we need to assign +// unique IDs to fixture classes and compare them. The TypeId type is +// used to hold such IDs. The user should treat TypeId as an opaque +// type: the only operation allowed on TypeId values is to compare +// them for equality using the == operator. +typedef const void* TypeId; + +template +class TypeIdHelper { + public: + // dummy_ must not have a const type. Otherwise an overly eager + // compiler (e.g. MSVC 7.1 & 8.0) may try to merge + // TypeIdHelper::dummy_ for different Ts as an "optimization". + static bool dummy_; +}; + +template +bool TypeIdHelper::dummy_ = false; + +// GetTypeId() returns the ID of type T. Different values will be +// returned for different types. Calling the function twice with the +// same type argument is guaranteed to return the same ID. +template +TypeId GetTypeId() { + // The compiler is required to allocate a different + // TypeIdHelper::dummy_ variable for each T used to instantiate + // the template. Therefore, the address of dummy_ is guaranteed to + // be unique. + return &(TypeIdHelper::dummy_); +} + +// Returns the type ID of ::testing::Test. Always call this instead +// of GetTypeId< ::testing::Test>() to get the type ID of +// ::testing::Test, as the latter may give the wrong result due to a +// suspected linker bug when compiling Google Test as a Mac OS X +// framework. +GTEST_API_ TypeId GetTestTypeId(); + +// Defines the abstract factory interface that creates instances +// of a Test object. +class TestFactoryBase { + public: + virtual ~TestFactoryBase() {} + + // Creates a test instance to run. The instance is both created and destroyed + // within TestInfoImpl::Run() + virtual Test* CreateTest() = 0; + + protected: + TestFactoryBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); +}; + +// This class provides implementation of TeastFactoryBase interface. +// It is used in TEST and TEST_F macros. +template +class TestFactoryImpl : public TestFactoryBase { + public: + virtual Test* CreateTest() { return new TestClass; } +}; + +#if GTEST_OS_WINDOWS + +// Predicate-formatters for implementing the HRESULT checking macros +// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} +// We pass a long instead of HRESULT to avoid causing an +// include dependency for the HRESULT type. +GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, + long hr); // NOLINT +GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, + long hr); // NOLINT + +#endif // GTEST_OS_WINDOWS + +// Types of SetUpTestCase() and TearDownTestCase() functions. +typedef void (*SetUpTestCaseFunc)(); +typedef void (*TearDownTestCaseFunc)(); + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param text representation of the test's value parameter, +// or NULL if this is not a type-parameterized test. +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +GTEST_API_ TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory); + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// State of the definition of a type-parameterized test case. +class GTEST_API_ TypedTestCasePState { + public: + TypedTestCasePState() : registered_(false) {} + + // Adds the given test name to defined_test_names_ and return true + // if the test case hasn't been registered; otherwise aborts the + // program. + bool AddTestName(const char* file, int line, const char* case_name, + const char* test_name) { + if (registered_) { + fprintf(stderr, "%s Test %s must be defined before " + "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", + FormatFileLocation(file, line).c_str(), test_name, case_name); + fflush(stderr); + posix::Abort(); + } + defined_test_names_.insert(test_name); + return true; + } + + // Verifies that registered_tests match the test names in + // defined_test_names_; returns registered_tests if successful, or + // aborts the program otherwise. + const char* VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests); + + private: + bool registered_; + ::std::set defined_test_names_; +}; + +// Skips to the first non-space char after the first comma in 'str'; +// returns NULL if no comma is found in 'str'. +inline const char* SkipComma(const char* str) { + const char* comma = strchr(str, ','); + if (comma == NULL) { + return NULL; + } + while (IsSpace(*(++comma))) {} + return comma; +} + +// Returns the prefix of 'str' before the first comma in it; returns +// the entire string if it contains no comma. +inline std::string GetPrefixUntilComma(const char* str) { + const char* comma = strchr(str, ','); + return comma == NULL ? str : std::string(str, comma); +} + +// TypeParameterizedTest::Register() +// registers a list of type-parameterized tests with Google Test. The +// return value is insignificant - we just need to return something +// such that we can call this function in a namespace scope. +// +// Implementation note: The GTEST_TEMPLATE_ macro declares a template +// template parameter. It's defined in gtest-type-util.h. +template +class TypeParameterizedTest { + public: + // 'index' is the index of the test in the type list 'Types' + // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, + // Types). Valid values for 'index' are [0, N - 1] where N is the + // length of Types. + static bool Register(const char* prefix, const char* case_name, + const char* test_names, int index) { + typedef typename Types::Head Type; + typedef Fixture FixtureClass; + typedef typename GTEST_BIND_(TestSel, Type) TestClass; + + // First, registers the first type-parameterized test in the type + // list. + MakeAndRegisterTestInfo( + String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/", + case_name, index).c_str(), + GetPrefixUntilComma(test_names).c_str(), + GetTypeName().c_str(), + NULL, // No value parameter. + GetTypeId(), + TestClass::SetUpTestCase, + TestClass::TearDownTestCase, + new TestFactoryImpl); + + // Next, recurses (at compile time) with the tail of the type list. + return TypeParameterizedTest + ::Register(prefix, case_name, test_names, index + 1); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTest { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/, int /*index*/) { + return true; + } +}; + +// TypeParameterizedTestCase::Register() +// registers *all combinations* of 'Tests' and 'Types' with Google +// Test. The return value is insignificant - we just need to return +// something such that we can call this function in a namespace scope. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* prefix, const char* case_name, + const char* test_names) { + typedef typename Tests::Head Head; + + // First, register the first test in 'Test' for each type in 'Types'. + TypeParameterizedTest::Register( + prefix, case_name, test_names, 0); + + // Next, recurses (at compile time) with the tail of the test list. + return TypeParameterizedTestCase + ::Register(prefix, case_name, SkipComma(test_names)); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/) { + return true; + } +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( + UnitTest* unit_test, int skip_count); + +// Helpers for suppressing warnings on unreachable code or constant +// condition. + +// Always returns true. +GTEST_API_ bool AlwaysTrue(); + +// Always returns false. +inline bool AlwaysFalse() { return !AlwaysTrue(); } + +// Helper for suppressing false warning from Clang on a const char* +// variable declared in a conditional expression always being NULL in +// the else branch. +struct GTEST_API_ ConstCharPtr { + ConstCharPtr(const char* str) : value(str) {} + operator bool() const { return true; } + const char* value; +}; + +// A simple Linear Congruential Generator for generating random +// numbers with a uniform distribution. Unlike rand() and srand(), it +// doesn't use global state (and therefore can't interfere with user +// code). Unlike rand_r(), it's portable. An LCG isn't very random, +// but it's good enough for our purposes. +class GTEST_API_ Random { + public: + static const UInt32 kMaxRange = 1u << 31; + + explicit Random(UInt32 seed) : state_(seed) {} + + void Reseed(UInt32 seed) { state_ = seed; } + + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); + + private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +}; + +// Defining a variable of type CompileAssertTypesEqual will cause a +// compiler error iff T1 and T2 are different types. +template +struct CompileAssertTypesEqual; + +template +struct CompileAssertTypesEqual { +}; + +// Removes the reference from a type if it is a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::remove_reference, which is not widely available yet. +template +struct RemoveReference { typedef T type; }; // NOLINT +template +struct RemoveReference { typedef T type; }; // NOLINT + +// A handy wrapper around RemoveReference that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_REFERENCE_(T) \ + typename ::testing::internal::RemoveReference::type + +// Removes const from a type if it is a const type, otherwise leaves +// it unchanged. This is the same as tr1::remove_const, which is not +// widely available yet. +template +struct RemoveConst { typedef T type; }; // NOLINT +template +struct RemoveConst { typedef T type; }; // NOLINT + +// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above +// definition to fail to remove the const in 'const int[3]' and 'const +// char[3][4]'. The following specialization works around the bug. +template +struct RemoveConst { + typedef typename RemoveConst::type type[N]; +}; + +#if defined(_MSC_VER) && _MSC_VER < 1400 +// This is the only specialization that allows VC++ 7.1 to remove const in +// 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC +// and thus needs to be conditionally compiled. +template +struct RemoveConst { + typedef typename RemoveConst::type type[N]; +}; +#endif + +// A handy wrapper around RemoveConst that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_CONST_(T) \ + typename ::testing::internal::RemoveConst::type + +// Turns const U&, U&, const U, and U all into U. +#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ + GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) + +// Adds reference to a type if it is not a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::add_reference, which is not widely available yet. +template +struct AddReference { typedef T& type; }; // NOLINT +template +struct AddReference { typedef T& type; }; // NOLINT + +// A handy wrapper around AddReference that works when the argument T +// depends on template parameters. +#define GTEST_ADD_REFERENCE_(T) \ + typename ::testing::internal::AddReference::type + +// Adds a reference to const on top of T as necessary. For example, +// it transforms +// +// char ==> const char& +// const char ==> const char& +// char& ==> const char& +// const char& ==> const char& +// +// The argument T must depend on some template parameters. +#define GTEST_REFERENCE_TO_CONST_(T) \ + GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) + +// ImplicitlyConvertible::value is a compile-time bool +// constant that's true iff type From can be implicitly converted to +// type To. +template +class ImplicitlyConvertible { + private: + // We need the following helper functions only for their types. + // They have no implementations. + + // MakeFrom() is an expression whose type is From. We cannot simply + // use From(), as the type From may not have a public default + // constructor. + static From MakeFrom(); + + // These two functions are overloaded. Given an expression + // Helper(x), the compiler will pick the first version if x can be + // implicitly converted to type To; otherwise it will pick the + // second version. + // + // The first version returns a value of size 1, and the second + // version returns a value of size 2. Therefore, by checking the + // size of Helper(x), which can be done at compile time, we can tell + // which version of Helper() is used, and hence whether x can be + // implicitly converted to type To. + static char Helper(To); + static char (&Helper(...))[2]; // NOLINT + + // We have to put the 'public' section after the 'private' section, + // or MSVC refuses to compile the code. + public: + // MSVC warns about implicitly converting from double to int for + // possible loss of data, so we need to temporarily disable the + // warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4244) // Temporarily disables warning 4244. + + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; +# pragma warning(pop) // Restores the warning state. +#elif defined(__BORLANDC__) + // C++Builder cannot use member overload resolution during template + // instantiation. The simplest workaround is to use its C++0x type traits + // functions (C++Builder 2009 and above only). + static const bool value = __is_convertible(From, To); +#else + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; +#endif // _MSV_VER +}; +template +const bool ImplicitlyConvertible::value; + +// IsAProtocolMessage::value is a compile-time bool constant that's +// true iff T is type ProtocolMessage, proto2::Message, or a subclass +// of those. +template +struct IsAProtocolMessage + : public bool_constant< + ImplicitlyConvertible::value || + ImplicitlyConvertible::value> { +}; + +// When the compiler sees expression IsContainerTest(0), if C is an +// STL-style container class, the first overload of IsContainerTest +// will be viable (since both C::iterator* and C::const_iterator* are +// valid types and NULL can be implicitly converted to them). It will +// be picked over the second overload as 'int' is a perfect match for +// the type of argument 0. If C::iterator or C::const_iterator is not +// a valid type, the first overload is not viable, and the second +// overload will be picked. Therefore, we can determine whether C is +// a container class by checking the type of IsContainerTest(0). +// The value of the expression is insignificant. +// +// Note that we look for both C::iterator and C::const_iterator. The +// reason is that C++ injects the name of a class as a member of the +// class itself (e.g. you can refer to class iterator as either +// 'iterator' or 'iterator::iterator'). If we look for C::iterator +// only, for example, we would mistakenly think that a class named +// iterator is an STL container. +// +// Also note that the simpler approach of overloading +// IsContainerTest(typename C::const_iterator*) and +// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. +typedef int IsContainer; +template +IsContainer IsContainerTest(int /* dummy */, + typename C::iterator* /* it */ = NULL, + typename C::const_iterator* /* const_it */ = NULL) { + return 0; +} + +typedef char IsNotContainer; +template +IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } + +// EnableIf::type is void when 'Cond' is true, and +// undefined when 'Cond' is false. To use SFINAE to make a function +// overload only apply when a particular expression is true, add +// "typename EnableIf::type* = 0" as the last parameter. +template struct EnableIf; +template<> struct EnableIf { typedef void type; }; // NOLINT + +// Utilities for native arrays. + +// ArrayEq() compares two k-dimensional native arrays using the +// elements' operator==, where k can be any integer >= 0. When k is +// 0, ArrayEq() degenerates into comparing a single pair of values. + +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs); + +// This generic version is used when k is 0. +template +inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } + +// This overload is used when k >= 1. +template +inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { + return internal::ArrayEq(lhs, N, rhs); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous ArrayEq() function, arrays with different sizes would +// lead to different copies of the template code. +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs) { + for (size_t i = 0; i != size; i++) { + if (!internal::ArrayEq(lhs[i], rhs[i])) + return false; + } + return true; +} + +// Finds the first element in the iterator range [begin, end) that +// equals elem. Element may be a native array type itself. +template +Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { + for (Iter it = begin; it != end; ++it) { + if (internal::ArrayEq(*it, elem)) + return it; + } + return end; +} + +// CopyArray() copies a k-dimensional native array using the elements' +// operator=, where k can be any integer >= 0. When k is 0, +// CopyArray() degenerates into copying a single value. + +template +void CopyArray(const T* from, size_t size, U* to); + +// This generic version is used when k is 0. +template +inline void CopyArray(const T& from, U* to) { *to = from; } + +// This overload is used when k >= 1. +template +inline void CopyArray(const T(&from)[N], U(*to)[N]) { + internal::CopyArray(from, N, *to); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous CopyArray() function, arrays with different sizes +// would lead to different copies of the template code. +template +void CopyArray(const T* from, size_t size, U* to) { + for (size_t i = 0; i != size; i++) { + internal::CopyArray(from[i], to + i); + } +} + +// The relation between an NativeArray object (see below) and the +// native array it represents. +enum RelationToSource { + kReference, // The NativeArray references the native array. + kCopy // The NativeArray makes a copy of the native array and + // owns the copy. +}; + +// Adapts a native array to a read-only STL-style container. Instead +// of the complete STL container concept, this adaptor only implements +// members useful for Google Mock's container matchers. New members +// should be added as needed. To simplify the implementation, we only +// support Element being a raw type (i.e. having no top-level const or +// reference modifier). It's the client's responsibility to satisfy +// this requirement. Element can be an array type itself (hence +// multi-dimensional arrays are supported). +template +class NativeArray { + public: + // STL-style container typedefs. + typedef Element value_type; + typedef Element* iterator; + typedef const Element* const_iterator; + + // Constructs from a native array. + NativeArray(const Element* array, size_t count, RelationToSource relation) { + Init(array, count, relation); + } + + // Copy constructor. + NativeArray(const NativeArray& rhs) { + Init(rhs.array_, rhs.size_, rhs.relation_to_source_); + } + + ~NativeArray() { + // Ensures that the user doesn't instantiate NativeArray with a + // const or reference type. + static_cast(StaticAssertTypeEqHelper()); + if (relation_to_source_ == kCopy) + delete[] array_; + } + + // STL-style container methods. + size_t size() const { return size_; } + const_iterator begin() const { return array_; } + const_iterator end() const { return array_ + size_; } + bool operator==(const NativeArray& rhs) const { + return size() == rhs.size() && + ArrayEq(begin(), size(), rhs.begin()); + } + + private: + // Initializes this object; makes a copy of the input array if + // 'relation' is kCopy. + void Init(const Element* array, size_t a_size, RelationToSource relation) { + if (relation == kReference) { + array_ = array; + } else { + Element* const copy = new Element[a_size]; + CopyArray(array, a_size, copy); + array_ = copy; + } + size_ = a_size; + relation_to_source_ = relation; + } + + const Element* array_; + size_t size_; + RelationToSource relation_to_source_; + + GTEST_DISALLOW_ASSIGN_(NativeArray); +}; + +} // namespace internal +} // namespace testing + +#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ + ::testing::internal::AssertHelper(result_type, file, line, message) \ + = ::testing::Message() + +#define GTEST_MESSAGE_(message, result_type) \ + GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) + +#define GTEST_FATAL_FAILURE_(message) \ + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) + +#define GTEST_NONFATAL_FAILURE_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) + +#define GTEST_SUCCESS_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) + +// Suppresses MSVC warnings 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } + +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::ConstCharPtr gtest_msg = "") { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const&) { \ + gtest_caught_expected = true; \ + } \ + catch (...) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws a different type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ + fail(gtest_msg.value) + +#define GTEST_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ + fail("Expected: " #statement " doesn't throw an exception.\n" \ + " Actual: it throws.") + +#define GTEST_TEST_ANY_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + bool gtest_caught_any = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_caught_any = true; \ + } \ + if (!gtest_caught_any) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ + fail("Expected: " #statement " throws an exception.\n" \ + " Actual: it doesn't.") + + +// Implements Boolean test assertions such as EXPECT_TRUE. expression can be +// either a boolean expression or an AssertionResult. text is a textual +// represenation of expression as it was passed into the EXPECT_TRUE. +#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ + ; \ + else \ + fail(::testing::internal::GetBoolAssertionFailureMessage(\ + gtest_ar_, text, #actual, #expected).c_str()) + +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ + fail("Expected: " #statement " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does.") + +// Expands to the name of the class that implements the given test. +#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + test_case_name##_##test_name##_Test + +// Helper macro for defining tests. +#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ +class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ + public:\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ + private:\ + virtual void TestBody();\ + static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ +};\ +\ +::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ + ::test_info_ =\ + ::testing::internal::MakeAndRegisterTestInfo(\ + #test_case_name, #test_name, NULL, NULL, \ + (parent_id), \ + parent_class::SetUpTestCase, \ + parent_class::TearDownTestCase, \ + new ::testing::internal::TestFactoryImpl<\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ +void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-linked_ptr.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-linked_ptr.h new file mode 100644 index 0000000..b1362cd --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-linked_ptr.h @@ -0,0 +1,233 @@ +// Copyright 2003 Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: Dan Egnor (egnor@google.com) +// +// A "smart" pointer type with reference tracking. Every pointer to a +// particular object is kept on a circular linked list. When the last pointer +// to an object is destroyed or reassigned, the object is deleted. +// +// Used properly, this deletes the object when the last reference goes away. +// There are several caveats: +// - Like all reference counting schemes, cycles lead to leaks. +// - Each smart pointer is actually two pointers (8 bytes instead of 4). +// - Every time a pointer is assigned, the entire list of pointers to that +// object is traversed. This class is therefore NOT SUITABLE when there +// will often be more than two or three pointers to a particular object. +// - References are only tracked as long as linked_ptr<> objects are copied. +// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS +// will happen (double deletion). +// +// A good use of this class is storing object references in STL containers. +// You can safely put linked_ptr<> in a vector<>. +// Other uses may not be as good. +// +// Note: If you use an incomplete type with linked_ptr<>, the class +// *containing* linked_ptr<> must have a constructor and destructor (even +// if they do nothing!). +// +// Bill Gibbons suggested we use something like this. +// +// Thread Safety: +// Unlike other linked_ptr implementations, in this implementation +// a linked_ptr object is thread-safe in the sense that: +// - it's safe to copy linked_ptr objects concurrently, +// - it's safe to copy *from* a linked_ptr and read its underlying +// raw pointer (e.g. via get()) concurrently, and +// - it's safe to write to two linked_ptrs that point to the same +// shared object concurrently. +// TODO(wan@google.com): rename this to safe_linked_ptr to avoid +// confusion with normal linked_ptr. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#include +#include + +#include "gtest/internal/gtest-port.h" + +namespace testing { +namespace internal { + +// Protects copying of all linked_ptr objects. +GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// This is used internally by all instances of linked_ptr<>. It needs to be +// a non-template class because different types of linked_ptr<> can refer to +// the same object (linked_ptr(obj) vs linked_ptr(obj)). +// So, it needs to be possible for different types of linked_ptr to participate +// in the same circular linked list, so we need a single class type here. +// +// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. +class linked_ptr_internal { + public: + // Create a new circle that includes only this instance. + void join_new() { + next_ = this; + } + + // Many linked_ptr operations may change p.link_ for some linked_ptr + // variable p in the same circle as this object. Therefore we need + // to prevent two such operations from occurring concurrently. + // + // Note that different types of linked_ptr objects can coexist in a + // circle (e.g. linked_ptr, linked_ptr, and + // linked_ptr). Therefore we must use a single mutex to + // protect all linked_ptr objects. This can create serious + // contention in production code, but is acceptable in a testing + // framework. + + // Join an existing circle. + void join(linked_ptr_internal const* ptr) + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { + MutexLock lock(&g_linked_ptr_mutex); + + linked_ptr_internal const* p = ptr; + while (p->next_ != ptr) p = p->next_; + p->next_ = this; + next_ = ptr; + } + + // Leave whatever circle we're part of. Returns true if we were the + // last member of the circle. Once this is done, you can join() another. + bool depart() + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { + MutexLock lock(&g_linked_ptr_mutex); + + if (next_ == this) return true; + linked_ptr_internal const* p = next_; + while (p->next_ != this) p = p->next_; + p->next_ = next_; + return false; + } + + private: + mutable linked_ptr_internal const* next_; +}; + +template +class linked_ptr { + public: + typedef T element_type; + + // Take over ownership of a raw pointer. This should happen as soon as + // possible after the object is created. + explicit linked_ptr(T* ptr = NULL) { capture(ptr); } + ~linked_ptr() { depart(); } + + // Copy an existing linked_ptr<>, adding ourselves to the list of references. + template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } + linked_ptr(linked_ptr const& ptr) { // NOLINT + assert(&ptr != this); + copy(&ptr); + } + + // Assignment releases the old value and acquires the new. + template linked_ptr& operator=(linked_ptr const& ptr) { + depart(); + copy(&ptr); + return *this; + } + + linked_ptr& operator=(linked_ptr const& ptr) { + if (&ptr != this) { + depart(); + copy(&ptr); + } + return *this; + } + + // Smart pointer members. + void reset(T* ptr = NULL) { + depart(); + capture(ptr); + } + T* get() const { return value_; } + T* operator->() const { return value_; } + T& operator*() const { return *value_; } + + bool operator==(T* p) const { return value_ == p; } + bool operator!=(T* p) const { return value_ != p; } + template + bool operator==(linked_ptr const& ptr) const { + return value_ == ptr.get(); + } + template + bool operator!=(linked_ptr const& ptr) const { + return value_ != ptr.get(); + } + + private: + template + friend class linked_ptr; + + T* value_; + linked_ptr_internal link_; + + void depart() { + if (link_.depart()) delete value_; + } + + void capture(T* ptr) { + value_ = ptr; + link_.join_new(); + } + + template void copy(linked_ptr const* ptr) { + value_ = ptr->get(); + if (value_) + link_.join(&ptr->link_); + else + link_.join_new(); + } +}; + +template inline +bool operator==(T* ptr, const linked_ptr& x) { + return ptr == x.get(); +} + +template inline +bool operator!=(T* ptr, const linked_ptr& x) { + return ptr != x.get(); +} + +// A function to convert T* into linked_ptr +// Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation +// for linked_ptr >(new FooBarBaz(arg)) +template +linked_ptr make_linked_ptr(T* ptr) { + return linked_ptr(ptr); +} + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util-generated.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util-generated.h new file mode 100644 index 0000000..e805485 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util-generated.h @@ -0,0 +1,5143 @@ +// This file was GENERATED by command: +// pump.py gtest-param-util-generated.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most 50 arguments in Values, +// and at most 10 arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tr1::tuple which is +// currently set at 10. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end); + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]); + +template +internal::ParamGenerator ValuesIn( + const Container& container); + +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template +class ValueArray1 { + public: + explicit ValueArray1(T1 v1) : v1_(v1) {} + + template + operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + + const T1 v1_; +}; + +template +class ValueArray2 { + public: + ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray2& other); + + const T1 v1_; + const T2 v2_; +}; + +template +class ValueArray3 { + public: + ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray3& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; +}; + +template +class ValueArray4 { + public: + ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray4& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; +}; + +template +class ValueArray5 { + public: + ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray5& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; +}; + +template +class ValueArray6 { + public: + ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray6& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; +}; + +template +class ValueArray7 { + public: + ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray7& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; +}; + +template +class ValueArray8 { + public: + ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray8& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; +}; + +template +class ValueArray9 { + public: + ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray9& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; +}; + +template +class ValueArray10 { + public: + ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray10& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; +}; + +template +class ValueArray11 { + public: + ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray11& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; +}; + +template +class ValueArray12 { + public: + ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray12& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; +}; + +template +class ValueArray13 { + public: + ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray13& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; +}; + +template +class ValueArray14 { + public: + ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray14& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; +}; + +template +class ValueArray15 { + public: + ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray15& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; +}; + +template +class ValueArray16 { + public: + ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray16& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; +}; + +template +class ValueArray17 { + public: + ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray17& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; +}; + +template +class ValueArray18 { + public: + ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray18& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; +}; + +template +class ValueArray19 { + public: + ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray19& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; +}; + +template +class ValueArray20 { + public: + ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray20& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; +}; + +template +class ValueArray21 { + public: + ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray21& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; +}; + +template +class ValueArray22 { + public: + ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray22& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; +}; + +template +class ValueArray23 { + public: + ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray23& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; +}; + +template +class ValueArray24 { + public: + ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray24& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; +}; + +template +class ValueArray25 { + public: + ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray25& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; +}; + +template +class ValueArray26 { + public: + ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray26& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; +}; + +template +class ValueArray27 { + public: + ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray27& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; +}; + +template +class ValueArray28 { + public: + ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray28& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; +}; + +template +class ValueArray29 { + public: + ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray29& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; +}; + +template +class ValueArray30 { + public: + ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray30& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; +}; + +template +class ValueArray31 { + public: + ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray31& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; +}; + +template +class ValueArray32 { + public: + ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray32& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; +}; + +template +class ValueArray33 { + public: + ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray33& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; +}; + +template +class ValueArray34 { + public: + ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray34& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; +}; + +template +class ValueArray35 { + public: + ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray35& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; +}; + +template +class ValueArray36 { + public: + ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray36& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; +}; + +template +class ValueArray37 { + public: + ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray37& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; +}; + +template +class ValueArray38 { + public: + ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray38& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; +}; + +template +class ValueArray39 { + public: + ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray39& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; +}; + +template +class ValueArray40 { + public: + ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray40& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; +}; + +template +class ValueArray41 { + public: + ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray41& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; +}; + +template +class ValueArray42 { + public: + ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray42& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; +}; + +template +class ValueArray43 { + public: + ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), + v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray43& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; +}; + +template +class ValueArray44 { + public: + ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), + v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), + v43_(v43), v44_(v44) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray44& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; +}; + +template +class ValueArray45 { + public: + ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), + v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray45& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; +}; + +template +class ValueArray46 { + public: + ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray46& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; +}; + +template +class ValueArray47 { + public: + ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), + v47_(v47) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray47& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; +}; + +template +class ValueArray48 { + public: + ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), + v46_(v46), v47_(v47), v48_(v48) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray48& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; +}; + +template +class ValueArray49 { + public: + ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, + T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_), static_cast(v49_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray49& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; +}; + +template +class ValueArray50 { + public: + ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, + T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_), static_cast(v49_), static_cast(v50_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray50& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; + const T50 v50_; +}; + +# if GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +template +class CartesianProductGenerator2 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator2(const ParamGenerator& g1, + const ParamGenerator& g2) + : g1_(g1), g2_(g2) {} + virtual ~CartesianProductGenerator2() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current2_; + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + ParamType current_value_; + }; // class CartesianProductGenerator2::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator2& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; +}; // class CartesianProductGenerator2 + + +template +class CartesianProductGenerator3 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator3(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + virtual ~CartesianProductGenerator3() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current3_; + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + ParamType current_value_; + }; // class CartesianProductGenerator3::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator3& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; +}; // class CartesianProductGenerator3 + + +template +class CartesianProductGenerator4 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator4(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + virtual ~CartesianProductGenerator4() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current4_; + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + ParamType current_value_; + }; // class CartesianProductGenerator4::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator4& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; +}; // class CartesianProductGenerator4 + + +template +class CartesianProductGenerator5 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator5(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + virtual ~CartesianProductGenerator5() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current5_; + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + ParamType current_value_; + }; // class CartesianProductGenerator5::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator5& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; +}; // class CartesianProductGenerator5 + + +template +class CartesianProductGenerator6 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator6(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + virtual ~CartesianProductGenerator6() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current6_; + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + ParamType current_value_; + }; // class CartesianProductGenerator6::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator6& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; +}; // class CartesianProductGenerator6 + + +template +class CartesianProductGenerator7 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator7(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + virtual ~CartesianProductGenerator7() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current7_; + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + ParamType current_value_; + }; // class CartesianProductGenerator7::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator7& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; +}; // class CartesianProductGenerator7 + + +template +class CartesianProductGenerator8 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator8(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + virtual ~CartesianProductGenerator8() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current8_; + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + ParamType current_value_; + }; // class CartesianProductGenerator8::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator8& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; +}; // class CartesianProductGenerator8 + + +template +class CartesianProductGenerator9 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator9(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + virtual ~CartesianProductGenerator9() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current9_; + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + ParamType current_value_; + }; // class CartesianProductGenerator9::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator9& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; +}; // class CartesianProductGenerator9 + + +template +class CartesianProductGenerator10 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator10(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9, + const ParamGenerator& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + virtual ~CartesianProductGenerator10() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end(), g10_, g10_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9, + const ParamGenerator& g10, + const typename ParamGenerator::iterator& current10) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9), + begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current10_; + if (current10_ == end10_) { + current10_ = begin10_; + ++current9_; + } + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_ && + current10_ == typed_other->current10_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_), + begin10_(other.begin10_), + end10_(other.end10_), + current10_(other.current10_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_, *current10_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_ || + current10_ == end10_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + const typename ParamGenerator::iterator begin10_; + const typename ParamGenerator::iterator end10_; + typename ParamGenerator::iterator current10_; + ParamType current_value_; + }; // class CartesianProductGenerator10::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator10& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; + const ParamGenerator g10_; +}; // class CartesianProductGenerator10 + + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN to ParamGenerator if T is +// convertible to U. +// +template +class CartesianProductHolder2 { + public: +CartesianProductHolder2(const Generator1& g1, const Generator2& g2) + : g1_(g1), g2_(g2) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator2( + static_cast >(g1_), + static_cast >(g2_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder2& other); + + const Generator1 g1_; + const Generator2 g2_; +}; // class CartesianProductHolder2 + +template +class CartesianProductHolder3 { + public: +CartesianProductHolder3(const Generator1& g1, const Generator2& g2, + const Generator3& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator3( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder3& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; +}; // class CartesianProductHolder3 + +template +class CartesianProductHolder4 { + public: +CartesianProductHolder4(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator4( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder4& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; +}; // class CartesianProductHolder4 + +template +class CartesianProductHolder5 { + public: +CartesianProductHolder5(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator5( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder5& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; +}; // class CartesianProductHolder5 + +template +class CartesianProductHolder6 { + public: +CartesianProductHolder6(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator6( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder6& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; +}; // class CartesianProductHolder6 + +template +class CartesianProductHolder7 { + public: +CartesianProductHolder7(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator7( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder7& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; +}; // class CartesianProductHolder7 + +template +class CartesianProductHolder8 { + public: +CartesianProductHolder8(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator8( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder8& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; +}; // class CartesianProductHolder8 + +template +class CartesianProductHolder9 { + public: +CartesianProductHolder9(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator9( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder9& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; +}; // class CartesianProductHolder9 + +template +class CartesianProductHolder10 { + public: +CartesianProductHolder10(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9, const Generator10& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator10( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_), + static_cast >(g10_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder10& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; + const Generator10 g10_; +}; // class CartesianProductHolder10 + +# endif // GTEST_HAS_COMBINE + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util-generated.h.pump b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util-generated.h.pump new file mode 100644 index 0000000..009206f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util-generated.h.pump @@ -0,0 +1,301 @@ +$$ -*- mode: c++; -*- +$var n = 50 $$ Maximum length of Values arguments we want to support. +$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most $n arguments in Values, +// and at most $maxtuple arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tr1::tuple which is +// currently set at $maxtuple. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end); + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]); + +template +internal::ParamGenerator ValuesIn( + const Container& container); + +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template +class ValueArray1 { + public: + explicit ValueArray1(T1 v1) : v1_(v1) {} + + template + operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + + const T1 v1_; +}; + +$range i 2..n +$for i [[ +$range j 1..i + +template <$for j, [[typename T$j]]> +class ValueArray$i { + public: + ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {} + + template + operator ParamGenerator() const { + const T array[] = {$for j, [[static_cast(v$(j)_)]]}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray$i& other); + +$for j [[ + + const T$j v$(j)_; +]] + +}; + +]] + +# if GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +$range i 2..maxtuple +$for i [[ +$range j 1..i +$range k 2..i + +template <$for j, [[typename T$j]]> +class CartesianProductGenerator$i + : public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > { + public: + typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType; + + CartesianProductGenerator$i($for j, [[const ParamGenerator& g$j]]) + : $for j, [[g$(j)_(g$j)]] {} + virtual ~CartesianProductGenerator$i() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, $for j, [[ + + const ParamGenerator& g$j, + const typename ParamGenerator::iterator& current$(j)]]) + : base_(base), +$for j, [[ + + begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j) +]] { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current$(i)_; + +$for k [[ + if (current$(i+2-k)_ == end$(i+2-k)_) { + current$(i+2-k)_ = begin$(i+2-k)_; + ++current$(i+2-k-1)_; + } + +]] + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ($for j && [[ + + current$(j)_ == typed_other->current$(j)_ +]]); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), $for j, [[ + + begin$(j)_(other.begin$(j)_), + end$(j)_(other.end$(j)_), + current$(j)_(other.current$(j)_) +]] { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType($for j, [[*current$(j)_]]); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return +$for j || [[ + + current$(j)_ == end$(j)_ +]]; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. +$for j [[ + + const typename ParamGenerator::iterator begin$(j)_; + const typename ParamGenerator::iterator end$(j)_; + typename ParamGenerator::iterator current$(j)_; +]] + + ParamType current_value_; + }; // class CartesianProductGenerator$i::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator$i& other); + + +$for j [[ + const ParamGenerator g$(j)_; + +]] +}; // class CartesianProductGenerator$i + + +]] + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN to ParamGenerator if T is +// convertible to U. +// +$range i 2..maxtuple +$for i [[ +$range j 1..i + +template <$for j, [[class Generator$j]]> +class CartesianProductHolder$i { + public: +CartesianProductHolder$i($for j, [[const Generator$j& g$j]]) + : $for j, [[g$(j)_(g$j)]] {} + template <$for j, [[typename T$j]]> + operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const { + return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >( + new CartesianProductGenerator$i<$for j, [[T$j]]>( +$for j,[[ + + static_cast >(g$(j)_) +]])); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder$i& other); + + +$for j [[ + const Generator$j g$(j)_; + +]] +}; // class CartesianProductHolder$i + +]] + +# endif // GTEST_HAS_COMBINE + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util.h new file mode 100644 index 0000000..0ef9718 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-param-util.h @@ -0,0 +1,619 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ + +#include +#include +#include + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-linked_ptr.h" +#include "gtest/internal/gtest-port.h" +#include "gtest/gtest-printers.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { +namespace internal { + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Outputs a message explaining invalid registration of different +// fixture class for the same test case. This may happen when +// TEST_P macro is used to define two tests with the same name +// but in different namespaces. +GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line); + +template class ParamGeneratorInterface; +template class ParamGenerator; + +// Interface for iterating over elements provided by an implementation +// of ParamGeneratorInterface. +template +class ParamIteratorInterface { + public: + virtual ~ParamIteratorInterface() {} + // A pointer to the base generator instance. + // Used only for the purposes of iterator comparison + // to make sure that two iterators belong to the same generator. + virtual const ParamGeneratorInterface* BaseGenerator() const = 0; + // Advances iterator to point to the next element + // provided by the generator. The caller is responsible + // for not calling Advance() on an iterator equal to + // BaseGenerator()->End(). + virtual void Advance() = 0; + // Clones the iterator object. Used for implementing copy semantics + // of ParamIterator. + virtual ParamIteratorInterface* Clone() const = 0; + // Dereferences the current iterator and provides (read-only) access + // to the pointed value. It is the caller's responsibility not to call + // Current() on an iterator equal to BaseGenerator()->End(). + // Used for implementing ParamGenerator::operator*(). + virtual const T* Current() const = 0; + // Determines whether the given iterator and other point to the same + // element in the sequence generated by the generator. + // Used for implementing ParamGenerator::operator==(). + virtual bool Equals(const ParamIteratorInterface& other) const = 0; +}; + +// Class iterating over elements provided by an implementation of +// ParamGeneratorInterface. It wraps ParamIteratorInterface +// and implements the const forward iterator concept. +template +class ParamIterator { + public: + typedef T value_type; + typedef const T& reference; + typedef ptrdiff_t difference_type; + + // ParamIterator assumes ownership of the impl_ pointer. + ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} + ParamIterator& operator=(const ParamIterator& other) { + if (this != &other) + impl_.reset(other.impl_->Clone()); + return *this; + } + + const T& operator*() const { return *impl_->Current(); } + const T* operator->() const { return impl_->Current(); } + // Prefix version of operator++. + ParamIterator& operator++() { + impl_->Advance(); + return *this; + } + // Postfix version of operator++. + ParamIterator operator++(int /*unused*/) { + ParamIteratorInterface* clone = impl_->Clone(); + impl_->Advance(); + return ParamIterator(clone); + } + bool operator==(const ParamIterator& other) const { + return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); + } + bool operator!=(const ParamIterator& other) const { + return !(*this == other); + } + + private: + friend class ParamGenerator; + explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} + scoped_ptr > impl_; +}; + +// ParamGeneratorInterface is the binary interface to access generators +// defined in other translation units. +template +class ParamGeneratorInterface { + public: + typedef T ParamType; + + virtual ~ParamGeneratorInterface() {} + + // Generator interface definition + virtual ParamIteratorInterface* Begin() const = 0; + virtual ParamIteratorInterface* End() const = 0; +}; + +// Wraps ParamGeneratorInterface and provides general generator syntax +// compatible with the STL Container concept. +// This class implements copy initialization semantics and the contained +// ParamGeneratorInterface instance is shared among all copies +// of the original object. This is possible because that instance is immutable. +template +class ParamGenerator { + public: + typedef ParamIterator iterator; + + explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} + ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} + + ParamGenerator& operator=(const ParamGenerator& other) { + impl_ = other.impl_; + return *this; + } + + iterator begin() const { return iterator(impl_->Begin()); } + iterator end() const { return iterator(impl_->End()); } + + private: + linked_ptr > impl_; +}; + +// Generates values from a range of two comparable values. Can be used to +// generate sequences of user-defined types that implement operator+() and +// operator<(). +// This class is used in the Range() function. +template +class RangeGenerator : public ParamGeneratorInterface { + public: + RangeGenerator(T begin, T end, IncrementT step) + : begin_(begin), end_(end), + step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} + virtual ~RangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, begin_, 0, step_); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, end_, end_index_, step_); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, T value, int index, + IncrementT step) + : base_(base), value_(value), index_(index), step_(step) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + value_ = value_ + step_; + index_++; + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const T* Current() const { return &value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const int other_index = + CheckedDowncastToActualType(&other)->index_; + return index_ == other_index; + } + + private: + Iterator(const Iterator& other) + : ParamIteratorInterface(), + base_(other.base_), value_(other.value_), index_(other.index_), + step_(other.step_) {} + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + T value_; + int index_; + const IncrementT step_; + }; // class RangeGenerator::Iterator + + static int CalculateEndIndex(const T& begin, + const T& end, + const IncrementT& step) { + int end_index = 0; + for (T i = begin; i < end; i = i + step) + end_index++; + return end_index; + } + + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); + + const T begin_; + const T end_; + const IncrementT step_; + // The index for the end() iterator. All the elements in the generated + // sequence are indexed (0-based) to aid iterator comparison. + const int end_index_; +}; // class RangeGenerator + + +// Generates values from a pair of STL-style iterators. Used in the +// ValuesIn() function. The elements are copied from the source range +// since the source can be located on the stack, and the generator +// is likely to persist beyond that stack frame. +template +class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { + public: + template + ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) + : container_(begin, end) {} + virtual ~ValuesInIteratorRangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, container_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, container_.end()); + } + + private: + typedef typename ::std::vector ContainerType; + + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + typename ContainerType::const_iterator iterator) + : base_(base), iterator_(iterator) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + ++iterator_; + value_.reset(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + // We need to use cached value referenced by iterator_ because *iterator_ + // can return a temporary object (and of type other then T), so just + // having "return &*iterator_;" doesn't work. + // value_ is updated here and not in Advance() because Advance() + // can advance iterator_ beyond the end of the range, and we cannot + // detect that fact. The client code, on the other hand, is + // responsible for not calling Current() on an out-of-range iterator. + virtual const T* Current() const { + if (value_.get() == NULL) + value_.reset(new T(*iterator_)); + return value_.get(); + } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + return iterator_ == + CheckedDowncastToActualType(&other)->iterator_; + } + + private: + Iterator(const Iterator& other) + // The explicit constructor call suppresses a false warning + // emitted by gcc when supplied with the -Wextra option. + : ParamIteratorInterface(), + base_(other.base_), + iterator_(other.iterator_) {} + + const ParamGeneratorInterface* const base_; + typename ContainerType::const_iterator iterator_; + // A cached value of *iterator_. We keep it here to allow access by + // pointer in the wrapping iterator's operator->(). + // value_ needs to be mutable to be accessed in Current(). + // Use of scoped_ptr helps manage cached value's lifetime, + // which is bound by the lifespan of the iterator itself. + mutable scoped_ptr value_; + }; // class ValuesInIteratorRangeGenerator::Iterator + + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); + + const ContainerType container_; +}; // class ValuesInIteratorRangeGenerator + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Stores a parameter value and later creates tests parameterized with that +// value. +template +class ParameterizedTestFactory : public TestFactoryBase { + public: + typedef typename TestClass::ParamType ParamType; + explicit ParameterizedTestFactory(ParamType parameter) : + parameter_(parameter) {} + virtual Test* CreateTest() { + TestClass::SetParam(¶meter_); + return new TestClass(); + } + + private: + const ParamType parameter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactoryBase is a base class for meta-factories that create +// test factories for passing into MakeAndRegisterTestInfo function. +template +class TestMetaFactoryBase { + public: + virtual ~TestMetaFactoryBase() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactory creates test factories for passing into +// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives +// ownership of test factory pointer, same factory object cannot be passed +// into that method twice. But ParameterizedTestCaseInfo is going to call +// it for each Test/Parameter value combination. Thus it needs meta factory +// creator class. +template +class TestMetaFactory + : public TestMetaFactoryBase { + public: + typedef typename TestCase::ParamType ParamType; + + TestMetaFactory() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { + return new ParameterizedTestFactory(parameter); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfoBase is a generic interface +// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase +// accumulates test information provided by TEST_P macro invocations +// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations +// and uses that information to register all resulting test instances +// in RegisterTests method. The ParameterizeTestCaseRegistry class holds +// a collection of pointers to the ParameterizedTestCaseInfo objects +// and calls RegisterTests() on each of them when asked. +class ParameterizedTestCaseInfoBase { + public: + virtual ~ParameterizedTestCaseInfoBase() {} + + // Base part of test case name for display purposes. + virtual const string& GetTestCaseName() const = 0; + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const = 0; + // UnitTest class invokes this method to register tests in this + // test case right before running them in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + virtual void RegisterTests() = 0; + + protected: + ParameterizedTestCaseInfoBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P +// macro invocations for a particular test case and generators +// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that +// test case. It registers tests with all values generated by all +// generators when asked. +template +class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { + public: + // ParamType and GeneratorCreationFunc are private types but are required + // for declarations of public methods AddTestPattern() and + // AddTestCaseInstantiation(). + typedef typename TestCase::ParamType ParamType; + // A function that returns an instance of appropriate generator type. + typedef ParamGenerator(GeneratorCreationFunc)(); + + explicit ParameterizedTestCaseInfo(const char* name) + : test_case_name_(name) {} + + // Test case base name for display purposes. + virtual const string& GetTestCaseName() const { return test_case_name_; } + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } + // TEST_P macro uses AddTestPattern() to record information + // about a single test in a LocalTestInfo structure. + // test_case_name is the base name of the test case (without invocation + // prefix). test_base_name is the name of an individual test without + // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is + // test case base name and DoBar is test base name. + void AddTestPattern(const char* test_case_name, + const char* test_base_name, + TestMetaFactoryBase* meta_factory) { + tests_.push_back(linked_ptr(new TestInfo(test_case_name, + test_base_name, + meta_factory))); + } + // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information + // about a generator. + int AddTestCaseInstantiation(const string& instantiation_name, + GeneratorCreationFunc* func, + const char* /* file */, + int /* line */) { + instantiations_.push_back(::std::make_pair(instantiation_name, func)); + return 0; // Return value used only to run this method in namespace scope. + } + // UnitTest class invokes this method to register tests in this test case + // test cases right before running tests in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + // UnitTest has a guard to prevent from calling this method more then once. + virtual void RegisterTests() { + for (typename TestInfoContainer::iterator test_it = tests_.begin(); + test_it != tests_.end(); ++test_it) { + linked_ptr test_info = *test_it; + for (typename InstantiationContainer::iterator gen_it = + instantiations_.begin(); gen_it != instantiations_.end(); + ++gen_it) { + const string& instantiation_name = gen_it->first; + ParamGenerator generator((*gen_it->second)()); + + Message test_case_name_stream; + if ( !instantiation_name.empty() ) + test_case_name_stream << instantiation_name << "/"; + test_case_name_stream << test_info->test_case_base_name; + + int i = 0; + for (typename ParamGenerator::iterator param_it = + generator.begin(); + param_it != generator.end(); ++param_it, ++i) { + Message test_name_stream; + test_name_stream << test_info->test_base_name << "/" << i; + MakeAndRegisterTestInfo( + test_case_name_stream.GetString().c_str(), + test_name_stream.GetString().c_str(), + NULL, // No type parameter. + PrintToString(*param_it).c_str(), + GetTestCaseTypeId(), + TestCase::SetUpTestCase, + TestCase::TearDownTestCase, + test_info->test_meta_factory->CreateTestFactory(*param_it)); + } // for param_it + } // for gen_it + } // for test_it + } // RegisterTests + + private: + // LocalTestInfo structure keeps information about a single test registered + // with TEST_P macro. + struct TestInfo { + TestInfo(const char* a_test_case_base_name, + const char* a_test_base_name, + TestMetaFactoryBase* a_test_meta_factory) : + test_case_base_name(a_test_case_base_name), + test_base_name(a_test_base_name), + test_meta_factory(a_test_meta_factory) {} + + const string test_case_base_name; + const string test_base_name; + const scoped_ptr > test_meta_factory; + }; + typedef ::std::vector > TestInfoContainer; + // Keeps pairs of + // received from INSTANTIATE_TEST_CASE_P macros. + typedef ::std::vector > + InstantiationContainer; + + const string test_case_name_; + TestInfoContainer tests_; + InstantiationContainer instantiations_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); +}; // class ParameterizedTestCaseInfo + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase +// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P +// macros use it to locate their corresponding ParameterizedTestCaseInfo +// descriptors. +class ParameterizedTestCaseRegistry { + public: + ParameterizedTestCaseRegistry() {} + ~ParameterizedTestCaseRegistry() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + delete *it; + } + } + + // Looks up or creates and returns a structure containing information about + // tests and instantiations of a particular test case. + template + ParameterizedTestCaseInfo* GetTestCasePatternHolder( + const char* test_case_name, + const char* file, + int line) { + ParameterizedTestCaseInfo* typed_test_info = NULL; + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + if ((*it)->GetTestCaseName() == test_case_name) { + if ((*it)->GetTestCaseTypeId() != GetTypeId()) { + // Complain about incorrect usage of Google Test facilities + // and terminate the program since we cannot guaranty correct + // test case setup and tear-down in this case. + ReportInvalidTestCaseType(test_case_name, file, line); + posix::Abort(); + } else { + // At this point we are sure that the object we found is of the same + // type we are looking for, so we downcast it to that type + // without further checks. + typed_test_info = CheckedDowncastToActualType< + ParameterizedTestCaseInfo >(*it); + } + break; + } + } + if (typed_test_info == NULL) { + typed_test_info = new ParameterizedTestCaseInfo(test_case_name); + test_case_infos_.push_back(typed_test_info); + } + return typed_test_info; + } + void RegisterTests() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + (*it)->RegisterTests(); + } + } + + private: + typedef ::std::vector TestCaseInfoContainer; + + TestCaseInfoContainer test_case_infos_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-port.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-port.h new file mode 100644 index 0000000..e9050ce --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-port.h @@ -0,0 +1,1947 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: wan@google.com (Zhanyong Wan) +// +// Low-level types and utilities for porting Google Test to various +// platforms. They are subject to change without notice. DO NOT USE +// THEM IN USER CODE. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +// The user can define the following macros in the build script to +// control Google Test's behavior. If the user doesn't define a macro +// in this list, Google Test will define it. +// +// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) +// is/isn't available. +// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions +// are enabled. +// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::string, which is different to std::string). +// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::wstring, which is different to std::wstring). +// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular +// expressions are/aren't available. +// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that +// is/isn't available. +// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't +// enabled. +// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that +// std::wstring does/doesn't work (Google Test can +// be used where std::wstring is unavailable). +// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple +// is/isn't available. +// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the +// compiler supports Microsoft's "Structured +// Exception Handling". +// GTEST_HAS_STREAM_REDIRECTION +// - Define it to 1/0 to indicate whether the +// platform supports I/O stream redirection using +// dup() and dup2(). +// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google +// Test's own tr1 tuple implementation should be +// used. Unused when the user sets +// GTEST_HAS_TR1_TUPLE to 0. +// GTEST_LANG_CXX11 - Define it to 1/0 to indicate that Google Test +// is building in C++11/C++98 mode. +// GTEST_LINKED_AS_SHARED_LIBRARY +// - Define to 1 when compiling tests that use +// Google Test as a shared library (known as +// DLL on Windows). +// GTEST_CREATE_SHARED_LIBRARY +// - Define to 1 when compiling Google Test itself +// as a shared library. + +// This header defines the following utilities: +// +// Macros indicating the current platform (defined to 1 if compiled on +// the given platform; otherwise undefined): +// GTEST_OS_AIX - IBM AIX +// GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_HPUX - HP-UX +// GTEST_OS_LINUX - Linux +// GTEST_OS_LINUX_ANDROID - Google Android +// GTEST_OS_MAC - Mac OS X +// GTEST_OS_IOS - iOS +// GTEST_OS_IOS_SIMULATOR - iOS simulator +// GTEST_OS_NACL - Google Native Client (NaCl) +// GTEST_OS_OPENBSD - OpenBSD +// GTEST_OS_QNX - QNX +// GTEST_OS_SOLARIS - Sun Solaris +// GTEST_OS_SYMBIAN - Symbian +// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) +// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop +// GTEST_OS_WINDOWS_MINGW - MinGW +// GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_ZOS - z/OS +// +// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the +// most stable support. Since core members of the Google Test project +// don't have access to other platforms, support for them may be less +// stable. If you notice any problems on your platform, please notify +// googletestframework@googlegroups.com (patches for fixing them are +// even more welcome!). +// +// Note that it is possible that none of the GTEST_OS_* macros are defined. +// +// Macros indicating available Google Test features (defined to 1 if +// the corresponding feature is supported; otherwise undefined): +// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized +// tests) +// GTEST_HAS_DEATH_TEST - death tests +// GTEST_HAS_PARAM_TEST - value-parameterized tests +// GTEST_HAS_TYPED_TEST - typed tests +// GTEST_HAS_TYPED_TEST_P - type-parameterized tests +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with +// GTEST_HAS_POSIX_RE (see above) which users can +// define themselves. +// GTEST_USES_SIMPLE_RE - our own simple regex is used; +// the above two are mutually exclusive. +// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). +// +// Macros for basic C++ coding: +// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. +// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a +// variable don't have to be used. +// GTEST_DISALLOW_ASSIGN_ - disables operator=. +// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. +// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. +// +// Synchronization: +// Mutex, MutexLock, ThreadLocal, GetThreadCount() +// - synchronization primitives. +// GTEST_IS_THREADSAFE - defined to 1 to indicate that the above +// synchronization primitives have real implementations +// and Google Test is thread-safe; or 0 otherwise. +// +// Template meta programming: +// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. +// IteratorTraits - partial implementation of std::iterator_traits, which +// is not available in libCstd when compiled with Sun C++. +// +// Smart pointers: +// scoped_ptr - as in TR2. +// +// Regular expressions: +// RE - a simple regular expression class using the POSIX +// Extended Regular Expression syntax on UNIX-like +// platforms, or a reduced regular exception syntax on +// other platforms, including Windows. +// +// Logging: +// GTEST_LOG_() - logs messages at the specified severity level. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. +// +// Stdout and stderr capturing: +// CaptureStdout() - starts capturing stdout. +// GetCapturedStdout() - stops capturing stdout and returns the captured +// string. +// CaptureStderr() - starts capturing stderr. +// GetCapturedStderr() - stops capturing stderr and returns the captured +// string. +// +// Integer types: +// TypeWithSize - maps an integer to a int type. +// Int32, UInt32, Int64, UInt64, TimeInMillis +// - integers of known sizes. +// BiggestInt - the biggest signed integer type. +// +// Command-line utilities: +// GTEST_FLAG() - references a flag. +// GTEST_DECLARE_*() - declares a flag. +// GTEST_DEFINE_*() - defines a flag. +// GetInjectableArgvs() - returns the command line as a vector of strings. +// +// Environment variable utilities: +// GetEnv() - gets the value of an environment variable. +// BoolFromGTestEnv() - parses a bool environment variable. +// Int32FromGTestEnv() - parses an Int32 environment variable. +// StringFromGTestEnv() - parses a string environment variable. + +#include // for isspace, etc +#include // for ptrdiff_t +#include +#include +#include +#ifndef _WIN32_WCE +# include +# include +#endif // !_WIN32_WCE + +#if defined __APPLE__ +# include +# include +#endif + +#include // NOLINT +#include // NOLINT +#include // NOLINT + +#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +#define GTEST_FLAG_PREFIX_ "gtest_" +#define GTEST_FLAG_PREFIX_DASH_ "gtest-" +#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +#define GTEST_NAME_ "Google Test" +#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" + +// Determines the version of gcc that is used to compile this. +#ifdef __GNUC__ +// 40302 means version 4.3.2. +# define GTEST_GCC_VER_ \ + (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + +// Determines the platform on which Google Test is compiled. +#ifdef __CYGWIN__ +# define GTEST_OS_CYGWIN 1 +#elif defined __SYMBIAN32__ +# define GTEST_OS_SYMBIAN 1 +#elif defined _WIN32 +# define GTEST_OS_WINDOWS 1 +# ifdef _WIN32_WCE +# define GTEST_OS_WINDOWS_MOBILE 1 +# elif defined(__MINGW__) || defined(__MINGW32__) +# define GTEST_OS_WINDOWS_MINGW 1 +# else +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif // _WIN32_WCE +#elif defined __APPLE__ +# define GTEST_OS_MAC 1 +# if TARGET_OS_IPHONE +# define GTEST_OS_IOS 1 +# if TARGET_IPHONE_SIMULATOR +# define GTEST_OS_IOS_SIMULATOR 1 +# endif +# endif +#elif defined __linux__ +# define GTEST_OS_LINUX 1 +# if defined __ANDROID__ +# define GTEST_OS_LINUX_ANDROID 1 +# endif +#elif defined __MVS__ +# define GTEST_OS_ZOS 1 +#elif defined(__sun) && defined(__SVR4) +# define GTEST_OS_SOLARIS 1 +#elif defined(_AIX) +# define GTEST_OS_AIX 1 +#elif defined(__hpux) +# define GTEST_OS_HPUX 1 +#elif defined __native_client__ +# define GTEST_OS_NACL 1 +#elif defined __OpenBSD__ +# define GTEST_OS_OPENBSD 1 +#elif defined __QNX__ +# define GTEST_OS_QNX 1 +#endif // __CYGWIN__ + +#ifndef GTEST_LANG_CXX11 +// gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when +// -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a +// value for __cplusplus, and recent versions of clang, gcc, and +// probably other compilers set that too in C++11 mode. +# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L +// Compiling in at least C++11 mode. +# define GTEST_LANG_CXX11 1 +# else +# define GTEST_LANG_CXX11 0 +# endif +#endif + +// Brings in definitions for functions used in the testing::internal::posix +// namespace (read, write, close, chdir, isatty, stat). We do not currently +// use them on Windows Mobile. +#if !GTEST_OS_WINDOWS +// This assumes that non-Windows OSes provide unistd.h. For OSes where this +// is not the case, we need to include headers that provide the functions +// mentioned above. +# include +# include +#elif !GTEST_OS_WINDOWS_MOBILE +# include +# include +#endif + +#if GTEST_OS_LINUX_ANDROID +// Used to define __ANDROID_API__ matching the target NDK API level. +# include // NOLINT +#endif + +// Defines this to true iff Google Test can use POSIX regular expressions. +#ifndef GTEST_HAS_POSIX_RE +# if GTEST_OS_LINUX_ANDROID +// On Android, is only available starting with Gingerbread. +# define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) +# else +# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) +# endif +#endif + +#if GTEST_HAS_POSIX_RE + +// On some platforms, needs someone to define size_t, and +// won't compile otherwise. We can #include it here as we already +// included , which is guaranteed to define size_t through +// . +# include // NOLINT + +# define GTEST_USES_POSIX_RE 1 + +#elif GTEST_OS_WINDOWS + +// is not available on Windows. Use our own simple regex +// implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#else + +// may not be available on this platform. Use our own +// simple regex implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#endif // GTEST_HAS_POSIX_RE + +#ifndef GTEST_HAS_EXCEPTIONS +// The user didn't tell us whether exceptions are enabled, so we need +// to figure it out. +# if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS +// macro to enable exceptions, so we'll do the same. +// Assumes that exceptions are enabled by default. +# ifndef _HAS_EXCEPTIONS +# define _HAS_EXCEPTIONS 1 +# endif // _HAS_EXCEPTIONS +# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +# elif defined(__GNUC__) && __EXCEPTIONS +// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__SUNPRO_CC) +// Sun Pro CC supports exceptions. However, there is no compile-time way of +// detecting whether they are enabled or not. Therefore, we assume that +// they are enabled unless the user tells us otherwise. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__IBMCPP__) && __EXCEPTIONS +// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__HP_aCC) +// Exception handling is in effect by default in HP aCC compiler. It has to +// be turned of by +noeh compiler option if desired. +# define GTEST_HAS_EXCEPTIONS 1 +# else +// For other compilers, we assume exceptions are disabled to be +// conservative. +# define GTEST_HAS_EXCEPTIONS 0 +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +#endif // GTEST_HAS_EXCEPTIONS + +#if !defined(GTEST_HAS_STD_STRING) +// Even though we don't use this macro any longer, we keep it in case +// some clients still depend on it. +# define GTEST_HAS_STD_STRING 1 +#elif !GTEST_HAS_STD_STRING +// The user told us that ::std::string isn't available. +# error "Google Test cannot be used where ::std::string isn't available." +#endif // !defined(GTEST_HAS_STD_STRING) + +#ifndef GTEST_HAS_GLOBAL_STRING +// The user didn't tell us whether ::string is available, so we need +// to figure it out. + +# define GTEST_HAS_GLOBAL_STRING 0 + +#endif // GTEST_HAS_GLOBAL_STRING + +#ifndef GTEST_HAS_STD_WSTRING +// The user didn't tell us whether ::std::wstring is available, so we need +// to figure it out. +// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring +// is available. + +// Cygwin 1.7 and below doesn't support ::std::wstring. +// Solaris' libc++ doesn't support it either. Android has +// no support for it at least as recent as Froyo (2.2). +# define GTEST_HAS_STD_WSTRING \ + (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) + +#endif // GTEST_HAS_STD_WSTRING + +#ifndef GTEST_HAS_GLOBAL_WSTRING +// The user didn't tell us whether ::wstring is available, so we need +// to figure it out. +# define GTEST_HAS_GLOBAL_WSTRING \ + (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Determines whether RTTI is available. +#ifndef GTEST_HAS_RTTI +// The user didn't tell us whether RTTI is enabled, so we need to +// figure it out. + +# ifdef _MSC_VER + +# ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) + +# ifdef __GXX_RTTI +// When building against STLport with the Android NDK and with +// -frtti -fno-exceptions, the build fails at link time with undefined +// references to __cxa_bad_typeid. Note sure if STL or toolchain bug, +// so disable RTTI when detected. +# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ + !defined(__EXCEPTIONS) +# define GTEST_HAS_RTTI 0 +# else +# define GTEST_HAS_RTTI 1 +# endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS +# else +# define GTEST_HAS_RTTI 0 +# endif // __GXX_RTTI + +// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends +// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the +// first version with C++ support. +# elif defined(__clang__) + +# define GTEST_HAS_RTTI __has_feature(cxx_rtti) + +// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if +// both the typeid and dynamic_cast features are present. +# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) + +# ifdef __RTTI_ALL__ +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +# else + +// For all other compilers, we assume RTTI is enabled. +# define GTEST_HAS_RTTI 1 + +# endif // _MSC_VER + +#endif // GTEST_HAS_RTTI + +// It's this header's responsibility to #include when RTTI +// is enabled. +#if GTEST_HAS_RTTI +# include +#endif + +// Determines whether Google Test can use the pthreads library. +#ifndef GTEST_HAS_PTHREAD +// The user didn't tell us explicitly, so we assume pthreads support is +// available on Linux and Mac. +// +// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 +// to your compiler flags. +# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \ + || GTEST_OS_QNX) +#endif // GTEST_HAS_PTHREAD + +#ifdef GTEST_OS_WINDOWS_MINGW +// Disable pthread support for MinGW for now. To enable it, we need to: +// 1) Implement ThreadLocal object under MinGW. The internal pthread calls are +// not available on MinGW. +// 2) Replace the nanosleep() with usleep() for MinGW. +#undef GTEST_HAS_PTHREAD +#define GTEST_HAS_PTHREAD 0 +#endif + +#if GTEST_HAS_PTHREAD +// gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is +// true. +# include // NOLINT + +// For timespec and nanosleep, used below. +# include // NOLINT +#endif + +// Determines whether Google Test can use tr1/tuple. You can define +// this macro to 0 to prevent Google Test from using tuple (any +// feature depending on tuple with be disabled in this mode). +#ifndef GTEST_HAS_TR1_TUPLE +# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) +// STLport, provided with the Android NDK, has neither or . +# define GTEST_HAS_TR1_TUPLE 0 +# else +// The user didn't tell us not to do it, so we assume it's OK. +# define GTEST_HAS_TR1_TUPLE 1 +# endif +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether Google Test's own tr1 tuple implementation +// should be used. +#ifndef GTEST_USE_OWN_TR1_TUPLE +// The user didn't tell us, so we need to figure it out. + +// We use our own TR1 tuple if we aren't sure the user has an +// implementation of it already. At this time, libstdc++ 4.0.0+ and +// MSVC 2010 are the only mainstream standard libraries that come +// with a TR1 tuple implementation. NVIDIA's CUDA NVCC compiler +// pretends to be GCC by defining __GNUC__ and friends, but cannot +// compile GCC's tuple implementation. MSVC 2008 (9.0) provides TR1 +// tuple in a 323 MB Feature Pack download, which we cannot assume the +// user has. QNX's QCC compiler is a modified GCC but it doesn't +// support TR1 tuple. libc++ only provides std::tuple, in C++11 mode, +// and it can be used with some compilers that define __GNUC__. +# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \ + && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 +# define GTEST_ENV_HAS_TR1_TUPLE_ 1 +# endif + +// C++11 specifies that provides std::tuple. Use that if gtest is used +// in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6 +// can build with clang but need to use gcc4.2's libstdc++). +# if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) +# define GTEST_ENV_HAS_STD_TUPLE_ 1 +# endif + +# if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_ +# define GTEST_USE_OWN_TR1_TUPLE 0 +# else +# define GTEST_USE_OWN_TR1_TUPLE 1 +# endif + +#endif // GTEST_USE_OWN_TR1_TUPLE + +// To avoid conditional compilation everywhere, we make it +// gtest-port.h's responsibility to #include the header implementing +// tr1/tuple. +#if GTEST_HAS_TR1_TUPLE + +# if GTEST_USE_OWN_TR1_TUPLE +# include "gtest/internal/gtest-tuple.h" +# elif GTEST_ENV_HAS_STD_TUPLE_ +# include +// C++11 puts its tuple into the ::std namespace rather than +// ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there. +// This causes undefined behavior, but supported compilers react in +// the way we intend. +namespace std { +namespace tr1 { +using ::std::get; +using ::std::make_tuple; +using ::std::tuple; +using ::std::tuple_element; +using ::std::tuple_size; +} +} + +# elif GTEST_OS_SYMBIAN + +// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to +// use STLport's tuple implementation, which unfortunately doesn't +// work as the copy of STLport distributed with Symbian is incomplete. +// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to +// use its own tuple implementation. +# ifdef BOOST_HAS_TR1_TUPLE +# undef BOOST_HAS_TR1_TUPLE +# endif // BOOST_HAS_TR1_TUPLE + +// This prevents , which defines +// BOOST_HAS_TR1_TUPLE, from being #included by Boost's . +# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED +# include + +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +// GCC 4.0+ implements tr1/tuple in the header. This does +// not conform to the TR1 spec, which requires the header to be . + +# if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +// Until version 4.3.2, gcc has a bug that causes , +// which is #included by , to not compile when RTTI is +// disabled. _TR1_FUNCTIONAL is the header guard for +// . Hence the following #define is a hack to prevent +// from being included. +# define _TR1_FUNCTIONAL 1 +# include +# undef _TR1_FUNCTIONAL // Allows the user to #include + // if he chooses to. +# else +# include // NOLINT +# endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 + +# else +// If the compiler is not GCC 4.0+, we assume the user is using a +// spec-conforming TR1 implementation. +# include // NOLINT +# endif // GTEST_USE_OWN_TR1_TUPLE + +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether clone(2) is supported. +// Usually it will only be available on Linux, excluding +// Linux on the Itanium architecture. +// Also see http://linux.die.net/man/2/clone. +#ifndef GTEST_HAS_CLONE +// The user didn't tell us, so we need to figure it out. + +# if GTEST_OS_LINUX && !defined(__ia64__) +# if GTEST_OS_LINUX_ANDROID +// On Android, clone() is only available on ARM starting with Gingerbread. +# if defined(__arm__) && __ANDROID_API__ >= 9 +# define GTEST_HAS_CLONE 1 +# else +# define GTEST_HAS_CLONE 0 +# endif +# else +# define GTEST_HAS_CLONE 1 +# endif +# else +# define GTEST_HAS_CLONE 0 +# endif // GTEST_OS_LINUX && !defined(__ia64__) + +#endif // GTEST_HAS_CLONE + +// Determines whether to support stream redirection. This is used to test +// output correctness and to implement death tests. +#ifndef GTEST_HAS_STREAM_REDIRECTION +// By default, we assume that stream redirection is supported on all +// platforms except known mobile ones. +# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN +# define GTEST_HAS_STREAM_REDIRECTION 0 +# else +# define GTEST_HAS_STREAM_REDIRECTION 1 +# endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#endif // GTEST_HAS_STREAM_REDIRECTION + +// Determines whether to support death tests. +// Google Test does not support death tests for VC 7.1 and earlier as +// abort() in a VC 7.1 application compiled as GUI in debug config +// pops up a dialog window that cannot be suppressed programmatically. +#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ + GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ + GTEST_OS_OPENBSD || GTEST_OS_QNX) +# define GTEST_HAS_DEATH_TEST 1 +# include // NOLINT +#endif + +// We don't support MSVC 7.1 with exceptions disabled now. Therefore +// all the compilers we care about are adequate for supporting +// value-parameterized tests. +#define GTEST_HAS_PARAM_TEST 1 + +// Determines whether to support type-driven tests. + +// Typed tests need and variadic macros, which GCC, VC++ 8.0, +// Sun Pro CC, IBM Visual Age, and HP aCC support. +#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ + defined(__IBMCPP__) || defined(__HP_aCC) +# define GTEST_HAS_TYPED_TEST 1 +# define GTEST_HAS_TYPED_TEST_P 1 +#endif + +// Determines whether to support Combine(). This only makes sense when +// value-parameterized tests are enabled. The implementation doesn't +// work on Sun Studio since it doesn't understand templated conversion +// operators. +#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) +# define GTEST_HAS_COMBINE 1 +#endif + +// Determines whether the system compiler uses UTF-16 for encoding wide strings. +#define GTEST_WIDE_STRING_USES_UTF16_ \ + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) + +// Determines whether test results can be streamed to a socket. +#if GTEST_OS_LINUX +# define GTEST_CAN_STREAM_RESULTS_ 1 +#endif + +// Defines some utility macros. + +// The GNU compiler emits a warning if nested "if" statements are followed by +// an "else" statement and braces are not used to explicitly disambiguate the +// "else" binding. This leads to problems with code like: +// +// if (gate) +// ASSERT_*(condition) << "Some message"; +// +// The "switch (0) case 0:" idiom is used to suppress this. +#ifdef __INTEL_COMPILER +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#else +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT +#endif + +// Use this annotation at the end of a struct/class definition to +// prevent the compiler from optimizing away instances that are never +// used. This is useful when all interesting logic happens inside the +// c'tor and / or d'tor. Example: +// +// struct Foo { +// Foo() { ... } +// } GTEST_ATTRIBUTE_UNUSED_; +// +// Also use it after a variable or parameter declaration to tell the +// compiler the variable/parameter does not have to be used. +#if defined(__GNUC__) && !defined(COMPILER_ICC) +# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#else +# define GTEST_ATTRIBUTE_UNUSED_ +#endif + +// A macro to disallow operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_ASSIGN_(type)\ + void operator=(type const &) + +// A macro to disallow copy constructor and operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ + type(type const &);\ + GTEST_DISALLOW_ASSIGN_(type) + +// Tell the compiler to warn about unused return values for functions declared +// with this macro. The macro should be used on function declarations +// following the argument list: +// +// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; +#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) +# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#else +# define GTEST_MUST_USE_RESULT_ +#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC + +// Determine whether the compiler supports Microsoft's Structured Exception +// Handling. This is supported by several Windows compilers but generally +// does not exist on any other system. +#ifndef GTEST_HAS_SEH +// The user didn't tell us, so we need to figure it out. + +# if defined(_MSC_VER) || defined(__BORLANDC__) +// These two compilers are known to support SEH. +# define GTEST_HAS_SEH 1 +# else +// Assume no SEH. +# define GTEST_HAS_SEH 0 +# endif + +#endif // GTEST_HAS_SEH + +#ifdef _MSC_VER + +# if GTEST_LINKED_AS_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllimport) +# elif GTEST_CREATE_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllexport) +# endif + +#endif // _MSC_VER + +#ifndef GTEST_API_ +# define GTEST_API_ +#endif + +#ifdef __GNUC__ +// Ask the compiler to never inline a given function. +# define GTEST_NO_INLINE_ __attribute__((noinline)) +#else +# define GTEST_NO_INLINE_ +#endif + +// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. +#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) +# define GTEST_HAS_CXXABI_H_ 1 +#else +# define GTEST_HAS_CXXABI_H_ 0 +#endif + +namespace testing { + +class Message; + +namespace internal { + +// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time +// expression is true. For example, you could use it to verify the +// size of a static array: +// +// GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, +// content_type_names_incorrect_size); +// +// or to make sure a struct is smaller than a certain size: +// +// GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large); +// +// The second argument to the macro is the name of the variable. If +// the expression is false, most compilers will issue a warning/error +// containing the name of the variable. + +template +struct CompileAssert { +}; + +#define GTEST_COMPILE_ASSERT_(expr, msg) \ + typedef ::testing::internal::CompileAssert<(bool(expr))> \ + msg[bool(expr) ? 1 : -1] + +// Implementation details of GTEST_COMPILE_ASSERT_: +// +// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 +// elements (and thus is invalid) when the expression is false. +// +// - The simpler definition +// +// #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1] +// +// does not work, as gcc supports variable-length arrays whose sizes +// are determined at run-time (this is gcc's extension and not part +// of the C++ standard). As a result, gcc fails to reject the +// following code with the simple definition: +// +// int foo; +// GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is +// // not a compile-time constant. +// +// - By using the type CompileAssert<(bool(expr))>, we ensures that +// expr is a compile-time constant. (Template arguments must be +// determined at compile-time.) +// +// - The outter parentheses in CompileAssert<(bool(expr))> are necessary +// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written +// +// CompileAssert +// +// instead, these compilers will refuse to compile +// +// GTEST_COMPILE_ASSERT_(5 > 0, some_message); +// +// (They seem to think the ">" in "5 > 0" marks the end of the +// template argument list.) +// +// - The array size is (bool(expr) ? 1 : -1), instead of simply +// +// ((expr) ? 1 : -1). +// +// This is to avoid running into a bug in MS VC 7.1, which +// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. + +// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h. +// +// This template is declared, but intentionally undefined. +template +struct StaticAssertTypeEqHelper; + +template +struct StaticAssertTypeEqHelper {}; + +#if GTEST_HAS_GLOBAL_STRING +typedef ::string string; +#else +typedef ::std::string string; +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING +typedef ::wstring wstring; +#elif GTEST_HAS_STD_WSTRING +typedef ::std::wstring wstring; +#endif // GTEST_HAS_GLOBAL_WSTRING + +// A helper for suppressing warnings on constant condition. It just +// returns 'condition'. +GTEST_API_ bool IsTrue(bool condition); + +// Defines scoped_ptr. + +// This implementation of scoped_ptr is PARTIAL - it only contains +// enough stuff to satisfy Google Test's need. +template +class scoped_ptr { + public: + typedef T element_type; + + explicit scoped_ptr(T* p = NULL) : ptr_(p) {} + ~scoped_ptr() { reset(); } + + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const { return ptr_; } + + T* release() { + T* const ptr = ptr_; + ptr_ = NULL; + return ptr; + } + + void reset(T* p = NULL) { + if (p != ptr_) { + if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. + delete ptr_; + } + ptr_ = p; + } + } + + private: + T* ptr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); +}; + +// Defines RE. + +// A simple C++ wrapper for . It uses the POSIX Extended +// Regular Expression syntax. +class GTEST_API_ RE { + public: + // A copy constructor is required by the Standard to initialize object + // references from r-values. + RE(const RE& other) { Init(other.pattern()); } + + // Constructs an RE from a string. + RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + + RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT + +#endif // GTEST_HAS_GLOBAL_STRING + + RE(const char* regex) { Init(regex); } // NOLINT + ~RE(); + + // Returns the string representation of the regex. + const char* pattern() const { return pattern_; } + + // FullMatch(str, re) returns true iff regular expression re matches + // the entire str. + // PartialMatch(str, re) returns true iff regular expression re + // matches a substring of str (including str itself). + // + // TODO(wan@google.com): make FullMatch() and PartialMatch() work + // when str contains NUL characters. + static bool FullMatch(const ::std::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::std::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#if GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const ::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#endif // GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const char* str, const RE& re); + static bool PartialMatch(const char* str, const RE& re); + + private: + void Init(const char* regex); + + // We use a const char* instead of an std::string, as Google Test used to be + // used where std::string is not available. TODO(wan@google.com): change to + // std::string. + const char* pattern_; + bool is_valid_; + +#if GTEST_USES_POSIX_RE + + regex_t full_regex_; // For FullMatch(). + regex_t partial_regex_; // For PartialMatch(). + +#else // GTEST_USES_SIMPLE_RE + + const char* full_pattern_; // For FullMatch(); + +#endif + + GTEST_DISALLOW_ASSIGN_(RE); +}; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, + int line); + +// Defines logging utilities: +// GTEST_LOG_(severity) - logs messages at the specified severity level. The +// message itself is streamed into the macro. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. + +enum GTestLogSeverity { + GTEST_INFO, + GTEST_WARNING, + GTEST_ERROR, + GTEST_FATAL +}; + +// Formats log entry severity, provides a stream object for streaming the +// log message, and terminates the message with a newline when going out of +// scope. +class GTEST_API_ GTestLog { + public: + GTestLog(GTestLogSeverity severity, const char* file, int line); + + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); + + ::std::ostream& GetStream() { return ::std::cerr; } + + private: + const GTestLogSeverity severity_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); +}; + +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__).GetStream() + +inline void LogToStderr() {} +inline void FlushInfoLog() { fflush(NULL); } + +// INTERNAL IMPLEMENTATION - DO NOT USE. +// +// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition +// is not satisfied. +// Synopsys: +// GTEST_CHECK_(boolean_condition); +// or +// GTEST_CHECK_(boolean_condition) << "Additional message"; +// +// This checks the condition and if the condition is not satisfied +// it prints message about the condition violation, including the +// condition itself, plus additional message streamed into it, if any, +// and then it aborts the program. It aborts the program irrespective of +// whether it is built in the debug mode or not. +#define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " + +// An all-mode assert to verify that the given POSIX-style function +// call returns 0 (indicating success). Known limitation: this +// doesn't expand to a balanced 'if' statement, so enclose the macro +// in {} if you need to use it as the only statement in an 'if' +// branch. +#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ + << gtest_error + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Use ImplicitCast_ as a safe version of static_cast for upcasting in +// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a +// const Foo*). When you use ImplicitCast_, the compiler checks that +// the cast is safe. Such explicit ImplicitCast_s are necessary in +// surprisingly many situations where C++ demands an exact type match +// instead of an argument type convertable to a target type. +// +// The syntax for using ImplicitCast_ is the same as for static_cast: +// +// ImplicitCast_(expr) +// +// ImplicitCast_ would have been part of the C++ standard library, +// but the proposal was submitted too late. It will probably make +// its way into the language in the future. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., implicit_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template +inline To ImplicitCast_(To x) { return x; } + +// When you upcast (that is, cast a pointer from type Foo to type +// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts +// always succeed. When you downcast (that is, cast a pointer from +// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because +// how do you know the pointer is really of type SubclassOfFoo? It +// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, +// when you downcast, you should use this macro. In debug mode, we +// use dynamic_cast<> to double-check the downcast is legal (we die +// if it's not). In normal mode, we do the efficient static_cast<> +// instead. Thus, it's important to test in debug mode to make sure +// the cast is legal! +// This is the only place in the code we should use dynamic_cast<>. +// In particular, you SHOULDN'T be using dynamic_cast<> in order to +// do RTTI (eg code like this: +// if (dynamic_cast(foo)) HandleASubclass1Object(foo); +// if (dynamic_cast(foo)) HandleASubclass2Object(foo); +// You should design the code some other way not to need this. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., down_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template // use like this: DownCast_(foo); +inline To DownCast_(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) { + const To to = NULL; + ::testing::internal::ImplicitCast_(to); + } + +#if GTEST_HAS_RTTI + // RTTI: debug mode only! + GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); +#endif + return static_cast(f); +} + +// Downcasts the pointer of type Base to Derived. +// Derived must be a subclass of Base. The parameter MUST +// point to a class of type Derived, not any subclass of it. +// When RTTI is available, the function performs a runtime +// check to enforce this. +template +Derived* CheckedDowncastToActualType(Base* base) { +#if GTEST_HAS_RTTI + GTEST_CHECK_(typeid(*base) == typeid(Derived)); + return dynamic_cast(base); // NOLINT +#else + return static_cast(base); // Poor man's downcast. +#endif +} + +#if GTEST_HAS_STREAM_REDIRECTION + +// Defines the stderr capturer: +// CaptureStdout - starts capturing stdout. +// GetCapturedStdout - stops capturing stdout and returns the captured string. +// CaptureStderr - starts capturing stderr. +// GetCapturedStderr - stops capturing stderr and returns the captured string. +// +GTEST_API_ void CaptureStdout(); +GTEST_API_ std::string GetCapturedStdout(); +GTEST_API_ void CaptureStderr(); +GTEST_API_ std::string GetCapturedStderr(); + +#endif // GTEST_HAS_STREAM_REDIRECTION + + +#if GTEST_HAS_DEATH_TEST + +const ::std::vector& GetInjectableArgvs(); +void SetInjectableArgvs(const ::std::vector* + new_argvs); + +// A copy of all command line arguments. Set by InitGoogleTest(). +extern ::std::vector g_argvs; + +#endif // GTEST_HAS_DEATH_TEST + +// Defines synchronization primitives. + +#if GTEST_HAS_PTHREAD + +// Sleeps for (roughly) n milli-seconds. This function is only for +// testing Google Test's own constructs. Don't use it in user tests, +// either directly or indirectly. +inline void SleepMilliseconds(int n) { + const timespec time = { + 0, // 0 seconds. + n * 1000L * 1000L, // And n ms. + }; + nanosleep(&time, NULL); +} + +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class Notification { + public: + Notification() : notified_(false) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + } + ~Notification() { + pthread_mutex_destroy(&mutex_); + } + + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { + pthread_mutex_lock(&mutex_); + notified_ = true; + pthread_mutex_unlock(&mutex_); + } + + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + for (;;) { + pthread_mutex_lock(&mutex_); + const bool notified = notified_; + pthread_mutex_unlock(&mutex_); + if (notified) + break; + SleepMilliseconds(10); + } + } + + private: + pthread_mutex_t mutex_; + bool notified_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; + +// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. +// Consequently, it cannot select a correct instantiation of ThreadWithParam +// in order to call its Run(). Introducing ThreadWithParamBase as a +// non-templated base class for ThreadWithParam allows us to bypass this +// problem. +class ThreadWithParamBase { + public: + virtual ~ThreadWithParamBase() {} + virtual void Run() = 0; +}; + +// pthread_create() accepts a pointer to a function type with the C linkage. +// According to the Standard (7.5/1), function types with different linkages +// are different even if they are otherwise identical. Some compilers (for +// example, SunStudio) treat them as different types. Since class methods +// cannot be defined with C-linkage we need to define a free C-function to +// pass into pthread_create(). +extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { + static_cast(thread)->Run(); + return NULL; +} + +// Helper class for testing Google Test's multi-threading constructs. +// To use it, write: +// +// void ThreadFunc(int param) { /* Do things with param */ } +// Notification thread_can_start; +// ... +// // The thread_can_start parameter is optional; you can supply NULL. +// ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); +// thread_can_start.Notify(); +// +// These classes are only for testing Google Test's own constructs. Do +// not use them in user tests, either directly or indirectly. +template +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void (*UserThreadFunc)(T); + + ThreadWithParam( + UserThreadFunc func, T param, Notification* thread_can_start) + : func_(func), + param_(param), + thread_can_start_(thread_can_start), + finished_(false) { + ThreadWithParamBase* const base = this; + // The thread can be created only after all fields except thread_ + // have been initialized. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); + } + ~ThreadWithParam() { Join(); } + + void Join() { + if (!finished_) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); + finished_ = true; + } + } + + virtual void Run() { + if (thread_can_start_ != NULL) + thread_can_start_->WaitForNotification(); + func_(param_); + } + + private: + const UserThreadFunc func_; // User-supplied thread function. + const T param_; // User-supplied parameter to the thread function. + // When non-NULL, used to block execution until the controller thread + // notifies. + Notification* const thread_can_start_; + bool finished_; // true iff we know that the thread function has finished. + pthread_t thread_; // The native thread object. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// MutexBase and Mutex implement mutex on pthreads-based platforms. They +// are used in conjunction with class MutexLock: +// +// Mutex mutex; +// ... +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end +// // of the current scope. +// +// MutexBase implements behavior for both statically and dynamically +// allocated mutexes. Do not use MutexBase directly. Instead, write +// the following to define a static mutex: +// +// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); +// +// You can forward declare a static mutex like this: +// +// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); +// +// To create a dynamic mutex, just define an object of type Mutex. +class MutexBase { + public: + // Acquires this mutex. + void Lock() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); + owner_ = pthread_self(); + has_owner_ = true; + } + + // Releases this mutex. + void Unlock() { + // Since the lock is being released the owner_ field should no longer be + // considered valid. We don't protect writing to has_owner_ here, as it's + // the caller's responsibility to ensure that the current thread holds the + // mutex when this is called. + has_owner_ = false; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); + } + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld() const { + GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) + << "The current thread is not holding the mutex @" << this; + } + + // A static mutex may be used before main() is entered. It may even + // be used before the dynamic initialization stage. Therefore we + // must be able to initialize a static mutex object at link time. + // This means MutexBase has to be a POD and its member variables + // have to be public. + public: + pthread_mutex_t mutex_; // The underlying pthread mutex. + // has_owner_ indicates whether the owner_ field below contains a valid thread + // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All + // accesses to the owner_ field should be protected by a check of this field. + // An alternative might be to memset() owner_ to all zeros, but there's no + // guarantee that a zero'd pthread_t is necessarily invalid or even different + // from pthread_self(). + bool has_owner_; + pthread_t owner_; // The thread holding the mutex. +}; + +// Forward-declares a static mutex. +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex + +// Defines and statically (i.e. at link time) initializes a static mutex. +// The initialization list here does not explicitly initialize each field, +// instead relying on default initialization for the unspecified fields. In +// particular, the owner_ field (a pthread_t) is not explicitly initialized. +// This allows initialization to work whether pthread_t is a scalar or struct. +// The flag -Wmissing-field-initializers must not be specified for this to work. +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } + +// The Mutex class can only be used for mutexes created at runtime. It +// shares its API with MutexBase otherwise. +class Mutex : public MutexBase { + public: + Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + has_owner_ = false; + } + ~Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +// We cannot name this class MutexLock as the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(MutexBase* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + MutexBase* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Helpers for ThreadLocal. + +// pthread_key_create() requires DeleteThreadLocalValue() to have +// C-linkage. Therefore it cannot be templatized to access +// ThreadLocal. Hence the need for class +// ThreadLocalValueHolderBase. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Called by pthread to delete thread-local data stored by +// pthread_setspecific(). +extern "C" inline void DeleteThreadLocalValue(void* value_holder) { + delete static_cast(value_holder); +} + +// Implements thread-local storage on pthreads-based systems. +// +// // Thread 1 +// ThreadLocal tl(100); // 100 is the default value for each thread. +// +// // Thread 2 +// tl.set(150); // Changes the value for thread 2 only. +// EXPECT_EQ(150, tl.get()); +// +// // Thread 1 +// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. +// tl.set(200); +// EXPECT_EQ(200, tl.get()); +// +// The template type argument T must have a public copy constructor. +// In addition, the default ThreadLocal constructor requires T to have +// a public default constructor. +// +// An object managed for a thread by a ThreadLocal instance is deleted +// when the thread exits. Or, if the ThreadLocal instance dies in +// that thread, when the ThreadLocal dies. It's the user's +// responsibility to ensure that all other threads using a ThreadLocal +// have exited when it dies, or the per-thread objects for those +// threads will not be deleted. +// +// Google Test only uses global ThreadLocal objects. That means they +// will die after main() has returned. Therefore, no per-thread +// object managed by Google Test will be leaked as long as all threads +// using Google Test have exited when main() returns. +template +class ThreadLocal { + public: + ThreadLocal() : key_(CreateKey()), + default_() {} + explicit ThreadLocal(const T& value) : key_(CreateKey()), + default_(value) {} + + ~ThreadLocal() { + // Destroys the managed object for the current thread, if any. + DeleteThreadLocalValue(pthread_getspecific(key_)); + + // Releases resources associated with the key. This will *not* + // delete managed objects for other threads. + GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); + } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + static pthread_key_t CreateKey() { + pthread_key_t key; + // When a thread exits, DeleteThreadLocalValue() will be called on + // the object managed for that thread. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); + return key; + } + + T* GetOrCreateValue() const { + ThreadLocalValueHolderBase* const holder = + static_cast(pthread_getspecific(key_)); + if (holder != NULL) { + return CheckedDowncastToActualType(holder)->pointer(); + } + + ValueHolder* const new_holder = new ValueHolder(default_); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); + } + + // A key pthreads uses for looking up per-thread values. + const pthread_key_t key_; + const T default_; // The default value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +# define GTEST_IS_THREADSAFE 1 + +#else // GTEST_HAS_PTHREAD + +// A dummy implementation of synchronization primitives (mutex, lock, +// and thread-local variable). Necessary for compiling Google Test where +// mutex is not supported - using Google Test in multiple threads is not +// supported on such platforms. + +class Mutex { + public: + Mutex() {} + void Lock() {} + void Unlock() {} + void AssertHeld() const {} +}; + +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex + +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex*) {} // NOLINT +}; + +typedef GTestMutexLock MutexLock; + +template +class ThreadLocal { + public: + ThreadLocal() : value_() {} + explicit ThreadLocal(const T& value) : value_(value) {} + T* pointer() { return &value_; } + const T* pointer() const { return &value_; } + const T& get() const { return value_; } + void set(const T& value) { value_ = value; } + private: + T value_; +}; + +// The above synchronization primitives have dummy implementations. +// Therefore Google Test is not thread-safe. +# define GTEST_IS_THREADSAFE 0 + +#endif // GTEST_HAS_PTHREAD + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +GTEST_API_ size_t GetThreadCount(); + +// Passing non-POD classes through ellipsis (...) crashes the ARM +// compiler and generates a warning in Sun Studio. The Nokia Symbian +// and the IBM XL C/C++ compiler try to instantiate a copy constructor +// for objects passed through ellipsis (...), failing for uncopyable +// objects. We define this to ensure that only POD is passed through +// ellipsis on these systems. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +# define GTEST_ELLIPSIS_NEEDS_POD_ 1 +#else +# define GTEST_CAN_COMPARE_NULL 1 +#endif + +// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between +// const T& and const T* in a function template. These compilers +// _can_ decide between class template specializations for T and T*, +// so a tr1::type_traits-like is_pointer works. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) +# define GTEST_NEEDS_IS_POINTER_ 1 +#endif + +template +struct bool_constant { + typedef bool_constant type; + static const bool value = bool_value; +}; +template const bool bool_constant::value; + +typedef bool_constant false_type; +typedef bool_constant true_type; + +template +struct is_pointer : public false_type {}; + +template +struct is_pointer : public true_type {}; + +template +struct IteratorTraits { + typedef typename Iterator::value_type value_type; +}; + +template +struct IteratorTraits { + typedef T value_type; +}; + +template +struct IteratorTraits { + typedef T value_type; +}; + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_SEP_ "\\" +# define GTEST_HAS_ALT_PATH_SEP_ 1 +// The biggest signed integer type the compiler supports. +typedef __int64 BiggestInt; +#else +# define GTEST_PATH_SEP_ "/" +# define GTEST_HAS_ALT_PATH_SEP_ 0 +typedef long long BiggestInt; // NOLINT +#endif // GTEST_OS_WINDOWS + +// Utilities for char. + +// isspace(int ch) and friends accept an unsigned char or EOF. char +// may be signed, depending on the compiler (or compiler flags). +// Therefore we need to cast a char to unsigned char before calling +// isspace(), etc. + +inline bool IsAlpha(char ch) { + return isalpha(static_cast(ch)) != 0; +} +inline bool IsAlNum(char ch) { + return isalnum(static_cast(ch)) != 0; +} +inline bool IsDigit(char ch) { + return isdigit(static_cast(ch)) != 0; +} +inline bool IsLower(char ch) { + return islower(static_cast(ch)) != 0; +} +inline bool IsSpace(char ch) { + return isspace(static_cast(ch)) != 0; +} +inline bool IsUpper(char ch) { + return isupper(static_cast(ch)) != 0; +} +inline bool IsXDigit(char ch) { + return isxdigit(static_cast(ch)) != 0; +} +inline bool IsXDigit(wchar_t ch) { + const unsigned char low_byte = static_cast(ch); + return ch == low_byte && isxdigit(low_byte) != 0; +} + +inline char ToLower(char ch) { + return static_cast(tolower(static_cast(ch))); +} +inline char ToUpper(char ch) { + return static_cast(toupper(static_cast(ch))); +} + +// The testing::internal::posix namespace holds wrappers for common +// POSIX functions. These wrappers hide the differences between +// Windows/MSVC and POSIX systems. Since some compilers define these +// standard functions as macros, the wrapper cannot have the same name +// as the wrapped function. + +namespace posix { + +// Functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + +typedef struct _stat StatStruct; + +# ifdef __BORLANDC__ +inline int IsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +# else // !__BORLANDC__ +# if GTEST_OS_WINDOWS_MOBILE +inline int IsATTY(int /* fd */) { return 0; } +# else +inline int IsATTY(int fd) { return _isatty(fd); } +# endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return _strdup(src); } +# endif // __BORLANDC__ + +# if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } +// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this +// time and thus not defined there. +# else +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } +inline int RmDir(const char* dir) { return _rmdir(dir); } +inline bool IsDir(const StatStruct& st) { + return (_S_IFDIR & st.st_mode) != 0; +} +# endif // GTEST_OS_WINDOWS_MOBILE + +#else + +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int IsATTY(int fd) { return isatty(fd); } +inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +inline int RmDir(const char* dir) { return rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#endif // GTEST_OS_WINDOWS + +// Functions deprecated by MSVC 8.0. + +#ifdef _MSC_VER +// Temporarily disable warning 4996 (deprecated function). +# pragma warning(push) +# pragma warning(disable:4996) +#endif + +inline const char* StrNCpy(char* dest, const char* src, size_t n) { + return strncpy(dest, src, n); +} + +// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and +// StrError() aren't needed on Windows CE at this time and thus not +// defined there. + +#if !GTEST_OS_WINDOWS_MOBILE +inline int ChDir(const char* dir) { return chdir(dir); } +#endif +inline FILE* FOpen(const char* path, const char* mode) { + return fopen(path, mode); +} +#if !GTEST_OS_WINDOWS_MOBILE +inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { + return freopen(path, mode, stream); +} +inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } +#endif +inline int FClose(FILE* fp) { return fclose(fp); } +#if !GTEST_OS_WINDOWS_MOBILE +inline int Read(int fd, void* buf, unsigned int count) { + return static_cast(read(fd, buf, count)); +} +inline int Write(int fd, const void* buf, unsigned int count) { + return static_cast(write(fd, buf, count)); +} +inline int Close(int fd) { return close(fd); } +inline const char* StrError(int errnum) { return strerror(errnum); } +#endif +inline const char* GetEnv(const char* name) { +#if GTEST_OS_WINDOWS_MOBILE + // We are on Windows CE, which has no environment variables. + return NULL; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != NULL && env[0] != '\0') ? env : NULL; +#else + return getenv(name); +#endif +} + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif + +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE has no C library. The abort() function is used in +// several places in Google Test. This implementation provides a reasonable +// imitation of standard behaviour. +void Abort(); +#else +inline void Abort() { abort(); } +#endif // GTEST_OS_WINDOWS_MOBILE + +} // namespace posix + +// MSVC "deprecates" snprintf and issues warnings wherever it is used. In +// order to avoid these warnings, we need to use _snprintf or _snprintf_s on +// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate +// function in order to achieve that. We use macro definition here because +// snprintf is a variadic function. +#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE +// MSVC 2005 and above support variadic macros. +# define GTEST_SNPRINTF_(buffer, size, format, ...) \ + _snprintf_s(buffer, size, size, format, __VA_ARGS__) +#elif defined(_MSC_VER) +// Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't +// complain about _snprintf. +# define GTEST_SNPRINTF_ _snprintf +#else +# define GTEST_SNPRINTF_ snprintf +#endif + +// The maximum number a BiggestInt can represent. This definition +// works no matter BiggestInt is represented in one's complement or +// two's complement. +// +// We cannot rely on numeric_limits in STL, as __int64 and long long +// are not part of standard C++ and numeric_limits doesn't need to be +// defined for them. +const BiggestInt kMaxBiggestInt = + ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); + +// This template class serves as a compile-time function from size to +// type. It maps a size in bytes to a primitive type with that +// size. e.g. +// +// TypeWithSize<4>::UInt +// +// is typedef-ed to be unsigned int (unsigned integer made up of 4 +// bytes). +// +// Such functionality should belong to STL, but I cannot find it +// there. +// +// Google Test uses this class in the implementation of floating-point +// comparison. +// +// For now it only handles UInt (unsigned int) as that's all Google Test +// needs. Other types can be easily added in the future if need +// arises. +template +class TypeWithSize { + public: + // This prevents the user from using TypeWithSize with incorrect + // values of N. + typedef void UInt; +}; + +// The specialization for size 4. +template <> +class TypeWithSize<4> { + public: + // unsigned int has size 4 in both gcc and MSVC. + // + // As base/basictypes.h doesn't compile on Windows, we cannot use + // uint32, uint64, and etc here. + typedef int Int; + typedef unsigned int UInt; +}; + +// The specialization for size 8. +template <> +class TypeWithSize<8> { + public: +#if GTEST_OS_WINDOWS + typedef __int64 Int; + typedef unsigned __int64 UInt; +#else + typedef long long Int; // NOLINT + typedef unsigned long long UInt; // NOLINT +#endif // GTEST_OS_WINDOWS +}; + +// Integer types of known sizes. +typedef TypeWithSize<4>::Int Int32; +typedef TypeWithSize<4>::UInt UInt32; +typedef TypeWithSize<8>::Int Int64; +typedef TypeWithSize<8>::UInt UInt64; +typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. + +// Utilities for command line flags and environment variables. + +// Macro for referencing flags. +#define GTEST_FLAG(name) FLAGS_gtest_##name + +// Macros for declaring flags. +#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) +#define GTEST_DECLARE_int32_(name) \ + GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) +#define GTEST_DECLARE_string_(name) \ + GTEST_API_ extern ::std::string GTEST_FLAG(name) + +// Macros for defining flags. +#define GTEST_DEFINE_bool_(name, default_val, doc) \ + GTEST_API_ bool GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_int32_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_string_(name, default_val, doc) \ + GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) + +// Thread annotations +#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) +#define GTEST_LOCK_EXCLUDED_(locks) + +// Parses 'str' for a 32-bit signed integer. If successful, writes the result +// to *value and returns true; otherwise leaves *value unchanged and returns +// false. +// TODO(chandlerc): Find a better way to refactor flag and environment parsing +// out of both gtest-port.cc and gtest.cc to avoid exporting this utility +// function. +bool ParseInt32(const Message& src_text, const char* str, Int32* value); + +// Parses a bool/Int32/string from the environment variable +// corresponding to the given Google Test flag. +bool BoolFromGTestEnv(const char* flag, bool default_val); +GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +const char* StringFromGTestEnv(const char* flag, const char* default_val); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-string.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-string.h new file mode 100644 index 0000000..472dd05 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-string.h @@ -0,0 +1,180 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares the String class and functions used internally by +// Google Test. They are subject to change without notice. They should not used +// by code external to Google Test. +// +// This header file is #included by . +// It should not be #included by other files. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ + +#ifdef __BORLANDC__ +// string.h is not guaranteed to provide strcpy on C++ Builder. +# include +#endif + +#include +#include + +#include "gtest/internal/gtest-port.h" + +namespace testing { +namespace internal { + +// String - an abstract class holding static string utilities. +class GTEST_API_ String { + public: + // Static utility methods + + // Clones a 0-terminated C string, allocating memory using new. The + // caller is responsible for deleting the return value using + // delete[]. Returns the cloned string, or NULL if the input is + // NULL. + // + // This is different from strdup() in string.h, which allocates + // memory using malloc(). + static const char* CloneCString(const char* c_str); + +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be + // able to pass strings to Win32 APIs on CE we need to convert them + // to 'Unicode', UTF-16. + + // Creates a UTF-16 wide string from the given ANSI string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the wide string, or NULL if the + // input is NULL. + // + // The wide string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static LPCWSTR AnsiToUtf16(const char* c_str); + + // Creates an ANSI string from the given wide string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the ANSI string, or NULL if the + // input is NULL. + // + // The returned string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static const char* Utf16ToAnsi(LPCWSTR utf16_str); +#endif + + // Compares two C strings. Returns true iff they have the same content. + // + // Unlike strcmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CStringEquals(const char* lhs, const char* rhs); + + // Converts a wide C string to a String using the UTF-8 encoding. + // NULL will be converted to "(null)". If an error occurred during + // the conversion, "(failed to convert from wide string)" is + // returned. + static std::string ShowWideCString(const wchar_t* wide_c_str); + + // Compares two wide C strings. Returns true iff they have the same + // content. + // + // Unlike wcscmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); + + // Compares two C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike strcasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CaseInsensitiveCStringEquals(const char* lhs, + const char* rhs); + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. + static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs); + + // Returns true iff the given string ends with the given suffix, ignoring + // case. Any string is considered to end with an empty suffix. + static bool EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix); + + // Formats a list of arguments to an std::string, using the same format + // spec string as for printf. + // + // We do not use the StringPrintf class as it is not universally + // available. + // + // The result is limited to 4096 characters (including the tailing + // 0). If 4096 characters are not enough to format the input, + // "" is returned. + static std::string Format(const char* format, ...); + + private: + String(); // Not meant to be instantiated. +}; // class String + +// Gets the content of the stringstream's buffer as an std::string. Each '\0' +// character in the buffer is replaced with "\\0". +GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); + +// Converts a streamable value to an std::string. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". + +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +std::string StreamableToString(const T& streamable); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-tuple.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-tuple.h new file mode 100644 index 0000000..7b3dfc3 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-tuple.h @@ -0,0 +1,1012 @@ +// This file was GENERATED by command: +// pump.py gtest-tuple.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2009 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template friend class tuple; \ + private: +#endif + +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> +#define GTEST_1_TUPLE_(T) tuple +#define GTEST_2_TUPLE_(T) tuple +#define GTEST_3_TUPLE_(T) tuple +#define GTEST_4_TUPLE_(T) tuple +#define GTEST_5_TUPLE_(T) tuple +#define GTEST_6_TUPLE_(T) tuple +#define GTEST_7_TUPLE_(T) tuple +#define GTEST_8_TUPLE_(T) tuple +#define GTEST_9_TUPLE_(T) tuple +#define GTEST_10_TUPLE_(T) tuple + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. +#define GTEST_0_TYPENAMES_(T) +#define GTEST_1_TYPENAMES_(T) typename T##0 +#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 +#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 +#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3 +#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4 +#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5 +#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6 +#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 +#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8 +#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8, typename T##9 + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef::type is T if T is a reference; otherwise it's const T&. +template +struct ByRef { typedef const T& type; }; // NOLINT +template +struct ByRef { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type + +// AddRef::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference::type. +template +struct AddRef { typedef T& type; }; // NOLINT +template +struct AddRef { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type + +// A helper for implementing get(). +template class Get; + +// A helper for implementing tuple_element. kIndexValid is true +// iff k < the number of fields in tuple type T. +template +struct TupleElement; + +template +struct TupleElement { + typedef T0 type; +}; + +template +struct TupleElement { + typedef T1 type; +}; + +template +struct TupleElement { + typedef T2 type; +}; + +template +struct TupleElement { + typedef T3 type; +}; + +template +struct TupleElement { + typedef T4 type; +}; + +template +struct TupleElement { + typedef T5 type; +}; + +template +struct TupleElement { + typedef T6 type; +}; + +template +struct TupleElement { + typedef T7 type; +}; + +template +struct TupleElement { + typedef T8 type; +}; + +template +struct TupleElement { + typedef T9 type; +}; + +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + +template +class GTEST_1_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} + + tuple(const tuple& t) : f0_(t.f0_) {} + + template + tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_1_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { + f0_ = t.f0_; + return *this; + } + + T0 f0_; +}; + +template +class GTEST_2_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), + f1_(f1) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} + + template + tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} + template + tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_2_TUPLE_(U)& t) { + return CopyFrom(t); + } + template + tuple& operator=(const ::std::pair& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + return *this; + } + + T0 f0_; + T1 f1_; +}; + +template +class GTEST_3_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + template + tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_3_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; +}; + +template +class GTEST_4_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} + + template + tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_4_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; +}; + +template +class GTEST_5_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, + GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_) {} + + template + tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_5_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; +}; + +template +class GTEST_6_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_) {} + + template + tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_6_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; +}; + +template +class GTEST_7_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + template + tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_7_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; +}; + +template +class GTEST_8_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, + GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + template + tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_8_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; +}; + +template +class GTEST_9_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + template + tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_9_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; +}; + +template +class tuple { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), + f9_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} + + template + tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), + f9_(t.f9_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_10_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + f9_ = t.f9_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; + T9 f9_; +}; + +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +template +inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { + return GTEST_1_TUPLE_(T)(f0); +} + +template +inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { + return GTEST_2_TUPLE_(T)(f0, f1); +} + +template +inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { + return GTEST_3_TUPLE_(T)(f0, f1, f2); +} + +template +inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3) { + return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); +} + +template +inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4) { + return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); +} + +template +inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5) { + return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); +} + +template +inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6) { + return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); +} + +template +inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { + return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); +} + +template +inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8) { + return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); +} + +template +inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8, const T9& f9) { + return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); +} + +// 6.1.3.3 Tuple helper classes. + +template struct tuple_size; + +template +struct tuple_size { + static const int value = 0; +}; + +template +struct tuple_size { + static const int value = 1; +}; + +template +struct tuple_size { + static const int value = 2; +}; + +template +struct tuple_size { + static const int value = 3; +}; + +template +struct tuple_size { + static const int value = 4; +}; + +template +struct tuple_size { + static const int value = 5; +}; + +template +struct tuple_size { + static const int value = 6; +}; + +template +struct tuple_size { + static const int value = 7; +}; + +template +struct tuple_size { + static const int value = 8; +}; + +template +struct tuple_size { + static const int value = 9; +}; + +template +struct tuple_size { + static const int value = 10; +}; + +template +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + +template <> +class Get<0> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + Field(Tuple& t) { return t.f0_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + ConstField(const Tuple& t) { return t.f0_; } +}; + +template <> +class Get<1> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + Field(Tuple& t) { return t.f1_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + ConstField(const Tuple& t) { return t.f1_; } +}; + +template <> +class Get<2> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + Field(Tuple& t) { return t.f2_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + ConstField(const Tuple& t) { return t.f2_; } +}; + +template <> +class Get<3> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + Field(Tuple& t) { return t.f3_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + ConstField(const Tuple& t) { return t.f3_; } +}; + +template <> +class Get<4> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + Field(Tuple& t) { return t.f4_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + ConstField(const Tuple& t) { return t.f4_; } +}; + +template <> +class Get<5> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + Field(Tuple& t) { return t.f5_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + ConstField(const Tuple& t) { return t.f5_; } +}; + +template <> +class Get<6> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + Field(Tuple& t) { return t.f6_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + ConstField(const Tuple& t) { return t.f6_; } +}; + +template <> +class Get<7> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + Field(Tuple& t) { return t.f7_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + ConstField(const Tuple& t) { return t.f7_; } +}; + +template <> +class Get<8> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + Field(Tuple& t) { return t.f8_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + ConstField(const Tuple& t) { return t.f8_; } +}; + +template <> +class Get<9> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + Field(Tuple& t) { return t.f9_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + ConstField(const Tuple& t) { return t.f9_; } +}; + +} // namespace gtest_internal + +template +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::Field(t); +} + +template +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(const GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template +struct SameSizeTuplePrefixComparator { + template + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator::Eq(t1, t2) && + ::std::tr1::get(t1) == ::std::tr1::get(t2); + } +}; + +} // namespace gtest_internal + +template +inline bool operator==(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size::value, + tuple_size::value>::Eq(t, u); +} + +template +inline bool operator!=(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + +#undef GTEST_0_TUPLE_ +#undef GTEST_1_TUPLE_ +#undef GTEST_2_TUPLE_ +#undef GTEST_3_TUPLE_ +#undef GTEST_4_TUPLE_ +#undef GTEST_5_TUPLE_ +#undef GTEST_6_TUPLE_ +#undef GTEST_7_TUPLE_ +#undef GTEST_8_TUPLE_ +#undef GTEST_9_TUPLE_ +#undef GTEST_10_TUPLE_ + +#undef GTEST_0_TYPENAMES_ +#undef GTEST_1_TYPENAMES_ +#undef GTEST_2_TYPENAMES_ +#undef GTEST_3_TYPENAMES_ +#undef GTEST_4_TYPENAMES_ +#undef GTEST_5_TYPENAMES_ +#undef GTEST_6_TYPENAMES_ +#undef GTEST_7_TYPENAMES_ +#undef GTEST_8_TYPENAMES_ +#undef GTEST_9_TYPENAMES_ +#undef GTEST_10_TYPENAMES_ + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-tuple.h.pump b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-tuple.h.pump new file mode 100644 index 0000000..c7d9e03 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-tuple.h.pump @@ -0,0 +1,339 @@ +$$ -*- mode: c++; -*- +$var n = 10 $$ Maximum number of tuple fields we want to support. +$$ This meta comment fixes auto-indentation in Emacs. }} +// Copyright 2009 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template friend class tuple; \ + private: +#endif + + +$range i 0..n-1 +$range j 0..n +$range k 1..n +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> + +$for k [[ +$range m 0..k-1 +$range m2 k..n-1 +#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]> + +]] + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. + +$for j [[ +$range m 0..j-1 +#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]] + + +]] + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template <$for i, [[typename T$i = void]]> +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef::type is T if T is a reference; otherwise it's const T&. +template +struct ByRef { typedef const T& type; }; // NOLINT +template +struct ByRef { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type + +// AddRef::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference::type. +template +struct AddRef { typedef T& type; }; // NOLINT +template +struct AddRef { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type + +// A helper for implementing get(). +template class Get; + +// A helper for implementing tuple_element. kIndexValid is true +// iff k < the number of fields in tuple type T. +template +struct TupleElement; + + +$for i [[ +template +struct TupleElement { + typedef T$i type; +}; + + +]] +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + + +$for k [[ +$range m 0..k-1 +template +class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { + public: + template friend class gtest_internal::Get; + + tuple() : $for m, [[f$(m)_()]] {} + + explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]] +$for m, [[f$(m)_(f$m)]] {} + + tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} + + template + tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} + +$if k == 2 [[ + template + tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} + +]] + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) { + return CopyFrom(t); + } + +$if k == 2 [[ + template + tuple& operator=(const ::std::pair& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + +]] + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) { + +$for m [[ + f$(m)_ = t.f$(m)_; + +]] + return *this; + } + + +$for m [[ + T$m f$(m)_; + +]] +}; + + +]] +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +$for k [[ +$range m 0..k-1 + +template +inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) { + return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]); +} + +]] + +// 6.1.3.3 Tuple helper classes. + +template struct tuple_size; + + +$for j [[ +template +struct tuple_size { + static const int value = $j; +}; + + +]] +template +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + + +$for i [[ +template <> +class Get<$i> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) + Field(Tuple& t) { return t.f$(i)_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) + ConstField(const Tuple& t) { return t.f$(i)_; } +}; + + +]] +} // namespace gtest_internal + +template +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) +get(GTEST_$(n)_TUPLE_(T)& t) { + return gtest_internal::Get::Field(t); +} + +template +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) +get(const GTEST_$(n)_TUPLE_(T)& t) { + return gtest_internal::Get::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template +struct SameSizeTuplePrefixComparator { + template + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator::Eq(t1, t2) && + ::std::tr1::get(t1) == ::std::tr1::get(t2); + } +}; + +} // namespace gtest_internal + +template +inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t, + const GTEST_$(n)_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size::value, + tuple_size::value>::Eq(t, u); +} + +template +inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t, + const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + + +$for j [[ +#undef GTEST_$(j)_TUPLE_ + +]] + + +$for j [[ +#undef GTEST_$(j)_TYPENAMES_ + +]] + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-type-util.h b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-type-util.h new file mode 100644 index 0000000..4a7d946 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-type-util.h @@ -0,0 +1,3332 @@ +// This file was GENERATED by command: +// pump.py gtest-type-util.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most 50 types in a list, and at most 50 +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-string.h" + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +# if GTEST_HAS_CXXABI_H_ +# include +# elif defined(__HP_aCC) +# include +# endif // GTEST_HASH_CXXABI_H_ + +namespace testing { +namespace internal { + +// GetTypeName() returns a human-readable name of type T. +// NB: This function is also used in Google Mock, so don't move it inside of +// the typed-test-only section below. +template +std::string GetTypeName() { +# if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +# if GTEST_HAS_CXXABI_H_ + using abi::__cxa_demangle; +# endif // GTEST_HAS_CXXABI_H_ + char* const readable_name = __cxa_demangle(name, 0, 0, &status); + const std::string name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +# else + return name; +# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC + +# else + + return ""; + +# endif // GTEST_HAS_RTTI +} + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// AssertyTypeEq::type is defined iff T1 and T2 are the same +// type. This can be used as a compile-time assertion to ensure that +// two types are equal. + +template +struct AssertTypeEq; + +template +struct AssertTypeEq { + typedef bool type; +}; + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types, Type, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; +template +struct Types2 { + typedef T1 Head; + typedef Types1 Tail; +}; + +template +struct Types3 { + typedef T1 Head; + typedef Types2 Tail; +}; + +template +struct Types4 { + typedef T1 Head; + typedef Types3 Tail; +}; + +template +struct Types5 { + typedef T1 Head; + typedef Types4 Tail; +}; + +template +struct Types6 { + typedef T1 Head; + typedef Types5 Tail; +}; + +template +struct Types7 { + typedef T1 Head; + typedef Types6 Tail; +}; + +template +struct Types8 { + typedef T1 Head; + typedef Types7 Tail; +}; + +template +struct Types9 { + typedef T1 Head; + typedef Types8 Tail; +}; + +template +struct Types10 { + typedef T1 Head; + typedef Types9 Tail; +}; + +template +struct Types11 { + typedef T1 Head; + typedef Types10 Tail; +}; + +template +struct Types12 { + typedef T1 Head; + typedef Types11 Tail; +}; + +template +struct Types13 { + typedef T1 Head; + typedef Types12 Tail; +}; + +template +struct Types14 { + typedef T1 Head; + typedef Types13 Tail; +}; + +template +struct Types15 { + typedef T1 Head; + typedef Types14 Tail; +}; + +template +struct Types16 { + typedef T1 Head; + typedef Types15 Tail; +}; + +template +struct Types17 { + typedef T1 Head; + typedef Types16 Tail; +}; + +template +struct Types18 { + typedef T1 Head; + typedef Types17 Tail; +}; + +template +struct Types19 { + typedef T1 Head; + typedef Types18 Tail; +}; + +template +struct Types20 { + typedef T1 Head; + typedef Types19 Tail; +}; + +template +struct Types21 { + typedef T1 Head; + typedef Types20 Tail; +}; + +template +struct Types22 { + typedef T1 Head; + typedef Types21 Tail; +}; + +template +struct Types23 { + typedef T1 Head; + typedef Types22 Tail; +}; + +template +struct Types24 { + typedef T1 Head; + typedef Types23 Tail; +}; + +template +struct Types25 { + typedef T1 Head; + typedef Types24 Tail; +}; + +template +struct Types26 { + typedef T1 Head; + typedef Types25 Tail; +}; + +template +struct Types27 { + typedef T1 Head; + typedef Types26 Tail; +}; + +template +struct Types28 { + typedef T1 Head; + typedef Types27 Tail; +}; + +template +struct Types29 { + typedef T1 Head; + typedef Types28 Tail; +}; + +template +struct Types30 { + typedef T1 Head; + typedef Types29 Tail; +}; + +template +struct Types31 { + typedef T1 Head; + typedef Types30 Tail; +}; + +template +struct Types32 { + typedef T1 Head; + typedef Types31 Tail; +}; + +template +struct Types33 { + typedef T1 Head; + typedef Types32 Tail; +}; + +template +struct Types34 { + typedef T1 Head; + typedef Types33 Tail; +}; + +template +struct Types35 { + typedef T1 Head; + typedef Types34 Tail; +}; + +template +struct Types36 { + typedef T1 Head; + typedef Types35 Tail; +}; + +template +struct Types37 { + typedef T1 Head; + typedef Types36 Tail; +}; + +template +struct Types38 { + typedef T1 Head; + typedef Types37 Tail; +}; + +template +struct Types39 { + typedef T1 Head; + typedef Types38 Tail; +}; + +template +struct Types40 { + typedef T1 Head; + typedef Types39 Tail; +}; + +template +struct Types41 { + typedef T1 Head; + typedef Types40 Tail; +}; + +template +struct Types42 { + typedef T1 Head; + typedef Types41 Tail; +}; + +template +struct Types43 { + typedef T1 Head; + typedef Types42 Tail; +}; + +template +struct Types44 { + typedef T1 Head; + typedef Types43 Tail; +}; + +template +struct Types45 { + typedef T1 Head; + typedef Types44 Tail; +}; + +template +struct Types46 { + typedef T1 Head; + typedef Types45 Tail; +}; + +template +struct Types47 { + typedef T1 Head; + typedef Types46 Tail; +}; + +template +struct Types48 { + typedef T1 Head; + typedef Types47 Tail; +}; + +template +struct Types49 { + typedef T1 Head; + typedef Types48 Tail; +}; + +template +struct Types50 { + typedef T1 Head; + typedef Types49 Tail; +}; + + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types +// will appear as Types in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types, and Google Test will translate +// that to TypesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. +template +struct Types { + typedef internal::Types50 type; +}; + +template <> +struct Types { + typedef internal::Types0 type; +}; +template +struct Types { + typedef internal::Types1 type; +}; +template +struct Types { + typedef internal::Types2 type; +}; +template +struct Types { + typedef internal::Types3 type; +}; +template +struct Types { + typedef internal::Types4 type; +}; +template +struct Types { + typedef internal::Types5 type; +}; +template +struct Types { + typedef internal::Types6 type; +}; +template +struct Types { + typedef internal::Types7 type; +}; +template +struct Types { + typedef internal::Types8 type; +}; +template +struct Types { + typedef internal::Types9 type; +}; +template +struct Types { + typedef internal::Types10 type; +}; +template +struct Types { + typedef internal::Types11 type; +}; +template +struct Types { + typedef internal::Types12 type; +}; +template +struct Types { + typedef internal::Types13 type; +}; +template +struct Types { + typedef internal::Types14 type; +}; +template +struct Types { + typedef internal::Types15 type; +}; +template +struct Types { + typedef internal::Types16 type; +}; +template +struct Types { + typedef internal::Types17 type; +}; +template +struct Types { + typedef internal::Types18 type; +}; +template +struct Types { + typedef internal::Types19 type; +}; +template +struct Types { + typedef internal::Types20 type; +}; +template +struct Types { + typedef internal::Types21 type; +}; +template +struct Types { + typedef internal::Types22 type; +}; +template +struct Types { + typedef internal::Types23 type; +}; +template +struct Types { + typedef internal::Types24 type; +}; +template +struct Types { + typedef internal::Types25 type; +}; +template +struct Types { + typedef internal::Types26 type; +}; +template +struct Types { + typedef internal::Types27 type; +}; +template +struct Types { + typedef internal::Types28 type; +}; +template +struct Types { + typedef internal::Types29 type; +}; +template +struct Types { + typedef internal::Types30 type; +}; +template +struct Types { + typedef internal::Types31 type; +}; +template +struct Types { + typedef internal::Types32 type; +}; +template +struct Types { + typedef internal::Types33 type; +}; +template +struct Types { + typedef internal::Types34 type; +}; +template +struct Types { + typedef internal::Types35 type; +}; +template +struct Types { + typedef internal::Types36 type; +}; +template +struct Types { + typedef internal::Types37 type; +}; +template +struct Types { + typedef internal::Types38 type; +}; +template +struct Types { + typedef internal::Types39 type; +}; +template +struct Types { + typedef internal::Types40 type; +}; +template +struct Types { + typedef internal::Types41 type; +}; +template +struct Types { + typedef internal::Types42 type; +}; +template +struct Types { + typedef internal::Types43 type; +}; +template +struct Types { + typedef internal::Types44 type; +}; +template +struct Types { + typedef internal::Types45 type; +}; +template +struct Types { + typedef internal::Types46 type; +}; +template +struct Types { + typedef internal::Types47 type; +}; +template +struct Types { + typedef internal::Types48 type; +}; +template +struct Types { + typedef internal::Types49 type; +}; + +namespace internal { + +# define GTEST_TEMPLATE_ template class + +// The template "selector" struct TemplateSel is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel::Bind::type is defined +// as the type Tmpl. This allows us to actually instantiate the +// template "selected" by TemplateSel. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template +struct TemplateSel { + template + struct Bind { + typedef Tmpl type; + }; +}; + +# define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates, Templates, +// and etc), which C++ doesn't support directly. +template +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template +struct Templates1 { + typedef TemplateSel Head; + typedef Templates0 Tail; +}; +template +struct Templates2 { + typedef TemplateSel Head; + typedef Templates1 Tail; +}; + +template +struct Templates3 { + typedef TemplateSel Head; + typedef Templates2 Tail; +}; + +template +struct Templates4 { + typedef TemplateSel Head; + typedef Templates3 Tail; +}; + +template +struct Templates5 { + typedef TemplateSel Head; + typedef Templates4 Tail; +}; + +template +struct Templates6 { + typedef TemplateSel Head; + typedef Templates5 Tail; +}; + +template +struct Templates7 { + typedef TemplateSel Head; + typedef Templates6 Tail; +}; + +template +struct Templates8 { + typedef TemplateSel Head; + typedef Templates7 Tail; +}; + +template +struct Templates9 { + typedef TemplateSel Head; + typedef Templates8 Tail; +}; + +template +struct Templates10 { + typedef TemplateSel Head; + typedef Templates9 Tail; +}; + +template +struct Templates11 { + typedef TemplateSel Head; + typedef Templates10 Tail; +}; + +template +struct Templates12 { + typedef TemplateSel Head; + typedef Templates11 Tail; +}; + +template +struct Templates13 { + typedef TemplateSel Head; + typedef Templates12 Tail; +}; + +template +struct Templates14 { + typedef TemplateSel Head; + typedef Templates13 Tail; +}; + +template +struct Templates15 { + typedef TemplateSel Head; + typedef Templates14 Tail; +}; + +template +struct Templates16 { + typedef TemplateSel Head; + typedef Templates15 Tail; +}; + +template +struct Templates17 { + typedef TemplateSel Head; + typedef Templates16 Tail; +}; + +template +struct Templates18 { + typedef TemplateSel Head; + typedef Templates17 Tail; +}; + +template +struct Templates19 { + typedef TemplateSel Head; + typedef Templates18 Tail; +}; + +template +struct Templates20 { + typedef TemplateSel Head; + typedef Templates19 Tail; +}; + +template +struct Templates21 { + typedef TemplateSel Head; + typedef Templates20 Tail; +}; + +template +struct Templates22 { + typedef TemplateSel Head; + typedef Templates21 Tail; +}; + +template +struct Templates23 { + typedef TemplateSel Head; + typedef Templates22 Tail; +}; + +template +struct Templates24 { + typedef TemplateSel Head; + typedef Templates23 Tail; +}; + +template +struct Templates25 { + typedef TemplateSel Head; + typedef Templates24 Tail; +}; + +template +struct Templates26 { + typedef TemplateSel Head; + typedef Templates25 Tail; +}; + +template +struct Templates27 { + typedef TemplateSel Head; + typedef Templates26 Tail; +}; + +template +struct Templates28 { + typedef TemplateSel Head; + typedef Templates27 Tail; +}; + +template +struct Templates29 { + typedef TemplateSel Head; + typedef Templates28 Tail; +}; + +template +struct Templates30 { + typedef TemplateSel Head; + typedef Templates29 Tail; +}; + +template +struct Templates31 { + typedef TemplateSel Head; + typedef Templates30 Tail; +}; + +template +struct Templates32 { + typedef TemplateSel Head; + typedef Templates31 Tail; +}; + +template +struct Templates33 { + typedef TemplateSel Head; + typedef Templates32 Tail; +}; + +template +struct Templates34 { + typedef TemplateSel Head; + typedef Templates33 Tail; +}; + +template +struct Templates35 { + typedef TemplateSel Head; + typedef Templates34 Tail; +}; + +template +struct Templates36 { + typedef TemplateSel Head; + typedef Templates35 Tail; +}; + +template +struct Templates37 { + typedef TemplateSel Head; + typedef Templates36 Tail; +}; + +template +struct Templates38 { + typedef TemplateSel Head; + typedef Templates37 Tail; +}; + +template +struct Templates39 { + typedef TemplateSel Head; + typedef Templates38 Tail; +}; + +template +struct Templates40 { + typedef TemplateSel Head; + typedef Templates39 Tail; +}; + +template +struct Templates41 { + typedef TemplateSel Head; + typedef Templates40 Tail; +}; + +template +struct Templates42 { + typedef TemplateSel Head; + typedef Templates41 Tail; +}; + +template +struct Templates43 { + typedef TemplateSel Head; + typedef Templates42 Tail; +}; + +template +struct Templates44 { + typedef TemplateSel Head; + typedef Templates43 Tail; +}; + +template +struct Templates45 { + typedef TemplateSel Head; + typedef Templates44 Tail; +}; + +template +struct Templates46 { + typedef TemplateSel Head; + typedef Templates45 Tail; +}; + +template +struct Templates47 { + typedef TemplateSel Head; + typedef Templates46 Tail; +}; + +template +struct Templates48 { + typedef TemplateSel Head; + typedef Templates47 Tail; +}; + +template +struct Templates49 { + typedef TemplateSel Head; + typedef Templates48 Tail; +}; + +template +struct Templates50 { + typedef TemplateSel Head; + typedef Templates49 Tail; +}; + + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates +// will appear as Templates in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates, and Google Test will translate +// that to TemplatesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. +template +struct Templates { + typedef Templates50 type; +}; + +template <> +struct Templates { + typedef Templates0 type; +}; +template +struct Templates { + typedef Templates1 type; +}; +template +struct Templates { + typedef Templates2 type; +}; +template +struct Templates { + typedef Templates3 type; +}; +template +struct Templates { + typedef Templates4 type; +}; +template +struct Templates { + typedef Templates5 type; +}; +template +struct Templates { + typedef Templates6 type; +}; +template +struct Templates { + typedef Templates7 type; +}; +template +struct Templates { + typedef Templates8 type; +}; +template +struct Templates { + typedef Templates9 type; +}; +template +struct Templates { + typedef Templates10 type; +}; +template +struct Templates { + typedef Templates11 type; +}; +template +struct Templates { + typedef Templates12 type; +}; +template +struct Templates { + typedef Templates13 type; +}; +template +struct Templates { + typedef Templates14 type; +}; +template +struct Templates { + typedef Templates15 type; +}; +template +struct Templates { + typedef Templates16 type; +}; +template +struct Templates { + typedef Templates17 type; +}; +template +struct Templates { + typedef Templates18 type; +}; +template +struct Templates { + typedef Templates19 type; +}; +template +struct Templates { + typedef Templates20 type; +}; +template +struct Templates { + typedef Templates21 type; +}; +template +struct Templates { + typedef Templates22 type; +}; +template +struct Templates { + typedef Templates23 type; +}; +template +struct Templates { + typedef Templates24 type; +}; +template +struct Templates { + typedef Templates25 type; +}; +template +struct Templates { + typedef Templates26 type; +}; +template +struct Templates { + typedef Templates27 type; +}; +template +struct Templates { + typedef Templates28 type; +}; +template +struct Templates { + typedef Templates29 type; +}; +template +struct Templates { + typedef Templates30 type; +}; +template +struct Templates { + typedef Templates31 type; +}; +template +struct Templates { + typedef Templates32 type; +}; +template +struct Templates { + typedef Templates33 type; +}; +template +struct Templates { + typedef Templates34 type; +}; +template +struct Templates { + typedef Templates35 type; +}; +template +struct Templates { + typedef Templates36 type; +}; +template +struct Templates { + typedef Templates37 type; +}; +template +struct Templates { + typedef Templates38 type; +}; +template +struct Templates { + typedef Templates39 type; +}; +template +struct Templates { + typedef Templates40 type; +}; +template +struct Templates { + typedef Templates41 type; +}; +template +struct Templates { + typedef Templates42 type; +}; +template +struct Templates { + typedef Templates43 type; +}; +template +struct Templates { + typedef Templates44 type; +}; +template +struct Templates { + typedef Templates45 type; +}; +template +struct Templates { + typedef Templates46 type; +}; +template +struct Templates { + typedef Templates47 type; +}; +template +struct Templates { + typedef Templates48 type; +}; +template +struct Templates { + typedef Templates49 type; +}; + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template +struct TypeList { + typedef Types1 type; +}; + +template +struct TypeList > { + typedef typename Types::type type; +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-type-util.h.pump b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-type-util.h.pump new file mode 100644 index 0000000..3638d51 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/include/gtest/internal/gtest-type-util.h.pump @@ -0,0 +1,298 @@ +$$ -*- mode: c++; -*- +$var n = 50 $$ Maximum length of type lists we want to support. +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most $n types in a list, and at most $n +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-string.h" + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +# if GTEST_HAS_CXXABI_H_ +# include +# elif defined(__HP_aCC) +# include +# endif // GTEST_HASH_CXXABI_H_ + +namespace testing { +namespace internal { + +// GetTypeName() returns a human-readable name of type T. +// NB: This function is also used in Google Mock, so don't move it inside of +// the typed-test-only section below. +template +std::string GetTypeName() { +# if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +# if GTEST_HAS_CXXABI_H_ + using abi::__cxa_demangle; +# endif // GTEST_HAS_CXXABI_H_ + char* const readable_name = __cxa_demangle(name, 0, 0, &status); + const std::string name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +# else + return name; +# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC + +# else + + return ""; + +# endif // GTEST_HAS_RTTI +} + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// AssertyTypeEq::type is defined iff T1 and T2 are the same +// type. This can be used as a compile-time assertion to ensure that +// two types are equal. + +template +struct AssertTypeEq; + +template +struct AssertTypeEq { + typedef bool type; +}; + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types, Type, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; + +$range i 2..n + +$for i [[ +$range j 1..i +$range k 2..i +template <$for j, [[typename T$j]]> +struct Types$i { + typedef T1 Head; + typedef Types$(i-1)<$for k, [[T$k]]> Tail; +}; + + +]] + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types +// will appear as Types in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types, and Google Test will translate +// that to TypesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. + +$range i 1..n +template <$for i, [[typename T$i = internal::None]]> +struct Types { + typedef internal::Types$n<$for i, [[T$i]]> type; +}; + +template <> +struct Types<$for i, [[internal::None]]> { + typedef internal::Types0 type; +}; + +$range i 1..n-1 +$for i [[ +$range j 1..i +$range k i+1..n +template <$for j, [[typename T$j]]> +struct Types<$for j, [[T$j]]$for k[[, internal::None]]> { + typedef internal::Types$i<$for j, [[T$j]]> type; +}; + +]] + +namespace internal { + +# define GTEST_TEMPLATE_ template class + +// The template "selector" struct TemplateSel is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel::Bind::type is defined +// as the type Tmpl. This allows us to actually instantiate the +// template "selected" by TemplateSel. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template +struct TemplateSel { + template + struct Bind { + typedef Tmpl type; + }; +}; + +# define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates, Templates, +// and etc), which C++ doesn't support directly. +template +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template +struct Templates1 { + typedef TemplateSel Head; + typedef Templates0 Tail; +}; + +$range i 2..n + +$for i [[ +$range j 1..i +$range k 2..i +template <$for j, [[GTEST_TEMPLATE_ T$j]]> +struct Templates$i { + typedef TemplateSel Head; + typedef Templates$(i-1)<$for k, [[T$k]]> Tail; +}; + + +]] + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates +// will appear as Templates in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates, and Google Test will translate +// that to TemplatesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. + +$range i 1..n +template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]> +struct Templates { + typedef Templates$n<$for i, [[T$i]]> type; +}; + +template <> +struct Templates<$for i, [[NoneT]]> { + typedef Templates0 type; +}; + +$range i 1..n-1 +$for i [[ +$range j 1..i +$range k i+1..n +template <$for j, [[GTEST_TEMPLATE_ T$j]]> +struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> { + typedef Templates$i<$for j, [[T$j]]> type; +}; + +]] + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template +struct TypeList { + typedef Types1 type; +}; + + +$range i 1..n +template <$for i, [[typename T$i]]> +struct TypeList > { + typedef typename Types<$for i, [[T$i]]>::type type; +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/m4/acx_pthread.m4 b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/acx_pthread.m4 new file mode 100644 index 0000000..2cf20de --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/acx_pthread.m4 @@ -0,0 +1,363 @@ +# This was retrieved from +# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi +# See also (perhaps for new versions?) +# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi +# +# We've rewritten the inconsistency check code (from avahi), to work +# more broadly. In particular, it no longer assumes ld accepts -zdefs. +# This caused a restructing of the code, but the functionality has only +# changed a little. + +dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +dnl +dnl @summary figure out how to build C programs using POSIX threads +dnl +dnl This macro figures out how to build C programs using POSIX threads. +dnl It sets the PTHREAD_LIBS output variable to the threads library and +dnl linker flags, and the PTHREAD_CFLAGS output variable to any special +dnl C compiler flags that are needed. (The user can also force certain +dnl compiler flags/libs to be tested by setting these environment +dnl variables.) +dnl +dnl Also sets PTHREAD_CC to any special C compiler that is needed for +dnl multi-threaded programs (defaults to the value of CC otherwise). +dnl (This is necessary on AIX to use the special cc_r compiler alias.) +dnl +dnl NOTE: You are assumed to not only compile your program with these +dnl flags, but also link it with them as well. e.g. you should link +dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS +dnl $LIBS +dnl +dnl If you are only building threads programs, you may wish to use +dnl these variables in your default LIBS, CFLAGS, and CC: +dnl +dnl LIBS="$PTHREAD_LIBS $LIBS" +dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +dnl CC="$PTHREAD_CC" +dnl +dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute +dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to +dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +dnl +dnl ACTION-IF-FOUND is a list of shell commands to run if a threads +dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to +dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the +dnl default action will define HAVE_PTHREAD. +dnl +dnl Please let the authors know if this macro fails on any platform, or +dnl if you have any other suggestions or comments. This macro was based +dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with +dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros +dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. +dnl We are also grateful for the helpful feedback of numerous users. +dnl +dnl @category InstalledPackages +dnl @author Steven G. Johnson +dnl @version 2006-05-29 +dnl @license GPLWithACException +dnl +dnl Checks for GCC shared/pthread inconsistency based on work by +dnl Marcin Owsiany + + +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_TRY_LINK([#include ], [int attr=$attr; return attr;], + [attr_name=$attr; break]) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi + + # The next part tries to detect GCC inconsistency with -shared on some + # architectures and systems. The problem is that in certain + # configurations, when -shared is specified, GCC "forgets" to + # internally use various flags which are still necessary. + + # + # Prepare the flags + # + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_CC="$CC" + + # Try with the flags determined by the earlier checks. + # + # -Wl,-z,defs forces link-time symbol resolution, so that the + # linking checks with -shared actually have any value + # + # FIXME: -fPIC is required for -shared on many architectures, + # so we specify it here, but the right way would probably be to + # properly detect whether it is actually required. + CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CC="$PTHREAD_CC" + + # In order not to create several levels of indentation, we test + # the value of "$done" until we find the cure or run out of ideas. + done="no" + + # First, make sure the CFLAGS we added are actually accepted by our + # compiler. If not (and OS X's ld, for instance, does not accept -z), + # then we can't do this test. + if test x"$done" = xno; then + AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies]) + AC_TRY_LINK(,, , [done=yes]) + + if test "x$done" = xyes ; then + AC_MSG_RESULT([no]) + else + AC_MSG_RESULT([yes]) + fi + fi + + if test x"$done" = xno; then + AC_MSG_CHECKING([whether -pthread is sufficient with -shared]) + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [done=yes]) + + if test "x$done" = xyes; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + fi + + # + # Linux gcc on some architectures such as mips/mipsel forgets + # about -lpthread + # + if test x"$done" = xno; then + AC_MSG_CHECKING([whether -lpthread fixes that]) + LIBS="-lpthread $PTHREAD_LIBS $save_LIBS" + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [done=yes]) + + if test "x$done" = xyes; then + AC_MSG_RESULT([yes]) + PTHREAD_LIBS="-lpthread $PTHREAD_LIBS" + else + AC_MSG_RESULT([no]) + fi + fi + # + # FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc + # + if test x"$done" = xno; then + AC_MSG_CHECKING([whether -lc_r fixes that]) + LIBS="-lc_r $PTHREAD_LIBS $save_LIBS" + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [done=yes]) + + if test "x$done" = xyes; then + AC_MSG_RESULT([yes]) + PTHREAD_LIBS="-lc_r $PTHREAD_LIBS" + else + AC_MSG_RESULT([no]) + fi + fi + if test x"$done" = xno; then + # OK, we have run out of ideas + AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries]) + + # so it's not safe to assume that we may use pthreads + acx_pthread_ok=no + fi + + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + CC="$save_CC" +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/m4/gtest.m4 b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/gtest.m4 new file mode 100644 index 0000000..6598ba7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/gtest.m4 @@ -0,0 +1,74 @@ +dnl GTEST_LIB_CHECK([minimum version [, +dnl action if found [,action if not found]]]) +dnl +dnl Check for the presence of the Google Test library, optionally at a minimum +dnl version, and indicate a viable version with the HAVE_GTEST flag. It defines +dnl standard variables for substitution including GTEST_CPPFLAGS, +dnl GTEST_CXXFLAGS, GTEST_LDFLAGS, and GTEST_LIBS. It also defines +dnl GTEST_VERSION as the version of Google Test found. Finally, it provides +dnl optional custom action slots in the event GTEST is found or not. +AC_DEFUN([GTEST_LIB_CHECK], +[ +dnl Provide a flag to enable or disable Google Test usage. +AC_ARG_ENABLE([gtest], + [AS_HELP_STRING([--enable-gtest], + [Enable tests using the Google C++ Testing Framework. + (Default is enabled.)])], + [], + [enable_gtest=]) +AC_ARG_VAR([GTEST_CONFIG], + [The exact path of Google Test's 'gtest-config' script.]) +AC_ARG_VAR([GTEST_CPPFLAGS], + [C-like preprocessor flags for Google Test.]) +AC_ARG_VAR([GTEST_CXXFLAGS], + [C++ compile flags for Google Test.]) +AC_ARG_VAR([GTEST_LDFLAGS], + [Linker path and option flags for Google Test.]) +AC_ARG_VAR([GTEST_LIBS], + [Library linking flags for Google Test.]) +AC_ARG_VAR([GTEST_VERSION], + [The version of Google Test available.]) +HAVE_GTEST="no" +AS_IF([test "x${enable_gtest}" != "xno"], + [AC_MSG_CHECKING([for 'gtest-config']) + AS_IF([test "x${enable_gtest}" != "xyes"], + [AS_IF([test -x "${enable_gtest}/scripts/gtest-config"], + [GTEST_CONFIG="${enable_gtest}/scripts/gtest-config"], + [GTEST_CONFIG="${enable_gtest}/bin/gtest-config"]) + AS_IF([test -x "${GTEST_CONFIG}"], [], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([dnl +Unable to locate either a built or installed Google Test. +The specific location '${enable_gtest}' was provided for a built or installed +Google Test, but no 'gtest-config' script could be found at this location.]) + ])], + [AC_PATH_PROG([GTEST_CONFIG], [gtest-config])]) + AS_IF([test -x "${GTEST_CONFIG}"], + [AC_MSG_RESULT([${GTEST_CONFIG}]) + m4_ifval([$1], + [_gtest_min_version="--min-version=$1" + AC_MSG_CHECKING([for Google Test at least version >= $1])], + [_gtest_min_version="--min-version=0" + AC_MSG_CHECKING([for Google Test])]) + AS_IF([${GTEST_CONFIG} ${_gtest_min_version}], + [AC_MSG_RESULT([yes]) + HAVE_GTEST='yes'], + [AC_MSG_RESULT([no])])], + [AC_MSG_RESULT([no])]) + AS_IF([test "x${HAVE_GTEST}" = "xyes"], + [GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags` + GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags` + GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags` + GTEST_LIBS=`${GTEST_CONFIG} --libs` + GTEST_VERSION=`${GTEST_CONFIG} --version` + AC_DEFINE([HAVE_GTEST],[1],[Defined when Google Test is available.])], + [AS_IF([test "x${enable_gtest}" = "xyes"], + [AC_MSG_ERROR([dnl +Google Test was enabled, but no viable version could be found.]) + ])])]) +AC_SUBST([HAVE_GTEST]) +AM_CONDITIONAL([HAVE_GTEST],[test "x$HAVE_GTEST" = "xyes"]) +AS_IF([test "x$HAVE_GTEST" = "xyes"], + [m4_ifval([$2], [$2])], + [m4_ifval([$3], [$3])]) +]) diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/m4/libtool.m4 b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/libtool.m4 new file mode 100644 index 0000000..828104c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/libtool.m4 @@ -0,0 +1,8001 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltoptions.m4 b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltoptions.m4 new file mode 100644 index 0000000..5d9acd8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltoptions.m4 @@ -0,0 +1,384 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltsugar.m4 b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltsugar.m4 new file mode 100644 index 0000000..9000a05 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltversion.m4 b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltversion.m4 new file mode 100644 index 0000000..07a8602 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/m4/lt~obsolete.m4 b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/lt~obsolete.m4 new file mode 100644 index 0000000..c573da9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/make/Makefile b/cpp/thirdparty/protobuf-2.5.0/gtest/make/Makefile new file mode 100644 index 0000000..5b27b6a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/make/Makefile @@ -0,0 +1,80 @@ +# A sample Makefile for building Google Test and using it in user +# tests. Please tweak it to suit your environment and project. You +# may want to move it to your project's root directory. +# +# SYNOPSIS: +# +# make [all] - makes everything. +# make TARGET - makes the given target. +# make clean - removes all files generated by make. + +# Please tweak the following variable definitions as needed by your +# project, except GTEST_HEADERS, which you can use in your own targets +# but shouldn't modify. + +# Points to the root of Google Test, relative to where this file is. +# Remember to tweak this if you move this file. +GTEST_DIR = .. + +# Where to find user code. +USER_DIR = ../samples + +# Flags passed to the preprocessor. +CPPFLAGS += -I$(GTEST_DIR)/include + +# Flags passed to the C++ compiler. +CXXFLAGS += -g -Wall -Wextra + +# All tests produced by this Makefile. Remember to add new tests you +# created to the list. +TESTS = sample1_unittest + +# All Google Test headers. Usually you shouldn't change this +# definition. +GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \ + $(GTEST_DIR)/include/gtest/internal/*.h + +# House-keeping build targets. + +all : $(TESTS) + +clean : + rm -f $(TESTS) gtest.a gtest_main.a *.o + +# Builds gtest.a and gtest_main.a. + +# Usually you shouldn't tweak such internal variables, indicated by a +# trailing _. +GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS) + +# For simplicity and to avoid depending on Google Test's +# implementation details, the dependencies specified below are +# conservative and not optimized. This is fine as Google Test +# compiles fast and for ordinary users its source rarely changes. +gtest-all.o : $(GTEST_SRCS_) + $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ + $(GTEST_DIR)/src/gtest-all.cc + +gtest_main.o : $(GTEST_SRCS_) + $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ + $(GTEST_DIR)/src/gtest_main.cc + +gtest.a : gtest-all.o + $(AR) $(ARFLAGS) $@ $^ + +gtest_main.a : gtest-all.o gtest_main.o + $(AR) $(ARFLAGS) $@ $^ + +# Builds a sample test. A test should link with either gtest.a or +# gtest_main.a, depending on whether it defines its own main() +# function. + +sample1.o : $(USER_DIR)/sample1.cc $(USER_DIR)/sample1.h $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1.cc + +sample1_unittest.o : $(USER_DIR)/sample1_unittest.cc \ + $(USER_DIR)/sample1.h $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1_unittest.cc + +sample1_unittest : sample1.o sample1_unittest.o gtest_main.a + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest-md.sln b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest-md.sln new file mode 100644 index 0000000..f7908da --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest-md.sln @@ -0,0 +1,45 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-md", "gtest-md.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main-md", "gtest_main-md.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862033}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test-md", "gtest_prod_test-md.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest-md", "gtest_unittest-md.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.Build.0 = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.ActiveCfg = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.Build.0 = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.ActiveCfg = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.Build.0 = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.ActiveCfg = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.Build.0 = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.ActiveCfg = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.Build.0 = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.ActiveCfg = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.Build.0 = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.ActiveCfg = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.Build.0 = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.ActiveCfg = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest-md.vcproj b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest-md.vcproj new file mode 100644 index 0000000..464d36e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest-md.vcproj @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest.sln b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest.sln new file mode 100644 index 0000000..ef4b057 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest.sln @@ -0,0 +1,45 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "gtest.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "gtest_main.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest", "gtest_unittest.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test", "gtest_prod_test.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.Build.0 = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.ActiveCfg = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.Build.0 = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.ActiveCfg = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.Build.0 = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.ActiveCfg = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.Build.0 = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.ActiveCfg = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.Build.0 = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.ActiveCfg = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.Build.0 = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.ActiveCfg = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.Build.0 = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.ActiveCfg = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest.vcproj b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest.vcproj new file mode 100644 index 0000000..04ad10a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest.vcproj @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_main-md.vcproj b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_main-md.vcproj new file mode 100644 index 0000000..5142f68 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_main-md.vcproj @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_main.vcproj b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_main.vcproj new file mode 100644 index 0000000..bdc49dd --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_main.vcproj @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_prod_test-md.vcproj b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_prod_test-md.vcproj new file mode 100644 index 0000000..f4080b4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_prod_test-md.vcproj @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_prod_test.vcproj b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_prod_test.vcproj new file mode 100644 index 0000000..43bdb35 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_prod_test.vcproj @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_unittest-md.vcproj b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_unittest-md.vcproj new file mode 100644 index 0000000..1bc9e4f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_unittest-md.vcproj @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_unittest.vcproj b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_unittest.vcproj new file mode 100644 index 0000000..9a2fad2 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/msvc/gtest_unittest.vcproj @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/prime_tables.h b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/prime_tables.h new file mode 100644 index 0000000..92ce16a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/prime_tables.h @@ -0,0 +1,123 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// Author: vladl@google.com (Vlad Losev) + +// This provides interface PrimeTable that determines whether a number is a +// prime and determines a next prime number. This interface is used +// in Google Test samples demonstrating use of parameterized tests. + +#ifndef GTEST_SAMPLES_PRIME_TABLES_H_ +#define GTEST_SAMPLES_PRIME_TABLES_H_ + +#include + +// The prime table interface. +class PrimeTable { + public: + virtual ~PrimeTable() {} + + // Returns true iff n is a prime number. + virtual bool IsPrime(int n) const = 0; + + // Returns the smallest prime number greater than p; or returns -1 + // if the next prime is beyond the capacity of the table. + virtual int GetNextPrime(int p) const = 0; +}; + +// Implementation #1 calculates the primes on-the-fly. +class OnTheFlyPrimeTable : public PrimeTable { + public: + virtual bool IsPrime(int n) const { + if (n <= 1) return false; + + for (int i = 2; i*i <= n; i++) { + // n is divisible by an integer other than 1 and itself. + if ((n % i) == 0) return false; + } + + return true; + } + + virtual int GetNextPrime(int p) const { + for (int n = p + 1; n > 0; n++) { + if (IsPrime(n)) return n; + } + + return -1; + } +}; + +// Implementation #2 pre-calculates the primes and stores the result +// in an array. +class PreCalculatedPrimeTable : public PrimeTable { + public: + // 'max' specifies the maximum number the prime table holds. + explicit PreCalculatedPrimeTable(int max) + : is_prime_size_(max + 1), is_prime_(new bool[max + 1]) { + CalculatePrimesUpTo(max); + } + virtual ~PreCalculatedPrimeTable() { delete[] is_prime_; } + + virtual bool IsPrime(int n) const { + return 0 <= n && n < is_prime_size_ && is_prime_[n]; + } + + virtual int GetNextPrime(int p) const { + for (int n = p + 1; n < is_prime_size_; n++) { + if (is_prime_[n]) return n; + } + + return -1; + } + + private: + void CalculatePrimesUpTo(int max) { + ::std::fill(is_prime_, is_prime_ + is_prime_size_, true); + is_prime_[0] = is_prime_[1] = false; + + for (int i = 2; i <= max; i++) { + if (!is_prime_[i]) continue; + + // Marks all multiples of i (except i itself) as non-prime. + for (int j = 2*i; j <= max; j += i) { + is_prime_[j] = false; + } + } + } + + const int is_prime_size_; + bool* const is_prime_; + + // Disables compiler warning "assignment operator could not be generated." + void operator=(const PreCalculatedPrimeTable& rhs); +}; + +#endif // GTEST_SAMPLES_PRIME_TABLES_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1.cc new file mode 100644 index 0000000..f171e26 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1.cc @@ -0,0 +1,68 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "sample1.h" + +// Returns n! (the factorial of n). For negative n, n! is defined to be 1. +int Factorial(int n) { + int result = 1; + for (int i = 1; i <= n; i++) { + result *= i; + } + + return result; +} + +// Returns true iff n is a prime number. +bool IsPrime(int n) { + // Trivial case 1: small numbers + if (n <= 1) return false; + + // Trivial case 2: even numbers + if (n % 2 == 0) return n == 2; + + // Now, we have that n is odd and n >= 3. + + // Try to divide n by every odd number i, starting from 3 + for (int i = 3; ; i += 2) { + // We only have to try i up to the squre root of n + if (i > n/i) break; + + // Now, we have i <= n/i < n. + // If n is divisible by i, n is not prime. + if (n % i == 0) return false; + } + + // n has no integer factor in the range (1, n), and thus is prime. + return true; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1.h b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1.h new file mode 100644 index 0000000..3dfeb98 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1.h @@ -0,0 +1,43 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_SAMPLES_SAMPLE1_H_ +#define GTEST_SAMPLES_SAMPLE1_H_ + +// Returns n! (the factorial of n). For negative n, n! is defined to be 1. +int Factorial(int n); + +// Returns true iff n is a prime number. +bool IsPrime(int n); + +#endif // GTEST_SAMPLES_SAMPLE1_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample10_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample10_unittest.cc new file mode 100644 index 0000000..0051cd5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample10_unittest.cc @@ -0,0 +1,144 @@ +// Copyright 2009 Google Inc. All Rights Reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) + +// This sample shows how to use Google Test listener API to implement +// a primitive leak checker. + +#include +#include + +#include "gtest/gtest.h" + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +namespace { + +// We will track memory used by this class. +class Water { + public: + // Normal Water declarations go here. + + // operator new and operator delete help us control water allocation. + void* operator new(size_t allocation_size) { + allocated_++; + return malloc(allocation_size); + } + + void operator delete(void* block, size_t /* allocation_size */) { + allocated_--; + free(block); + } + + static int allocated() { return allocated_; } + + private: + static int allocated_; +}; + +int Water::allocated_ = 0; + +// This event listener monitors how many Water objects are created and +// destroyed by each test, and reports a failure if a test leaks some Water +// objects. It does this by comparing the number of live Water objects at +// the beginning of a test and at the end of a test. +class LeakChecker : public EmptyTestEventListener { + private: + // Called before a test starts. + virtual void OnTestStart(const TestInfo& /* test_info */) { + initially_allocated_ = Water::allocated(); + } + + // Called after a test ends. + virtual void OnTestEnd(const TestInfo& /* test_info */) { + int difference = Water::allocated() - initially_allocated_; + + // You can generate a failure in any event handler except + // OnTestPartResult. Just use an appropriate Google Test assertion to do + // it. + EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!"; + } + + int initially_allocated_; +}; + +TEST(ListenersTest, DoesNotLeak) { + Water* water = new Water; + delete water; +} + +// This should fail when the --check_for_leaks command line flag is +// specified. +TEST(ListenersTest, LeaksWater) { + Water* water = new Water; + EXPECT_TRUE(water != NULL); +} + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + bool check_for_leaks = false; + if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 ) + check_for_leaks = true; + else + printf("%s\n", "Run this program with --check_for_leaks to enable " + "custom leak checking in the tests."); + + // If we are given the --check_for_leaks command line flag, installs the + // leak checker. + if (check_for_leaks) { + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + + // Adds the leak checker to the end of the test event listener list, + // after the default text output printer and the default XML report + // generator. + // + // The order is important - it ensures that failures generated in the + // leak checker's OnTestEnd() method are processed by the text and XML + // printers *before* their OnTestEnd() methods are called, such that + // they are attributed to the right test. Remember that a listener + // receives an OnXyzStart event *after* listeners preceding it in the + // list received that event, and receives an OnXyzEnd event *before* + // listeners preceding it. + // + // We don't need to worry about deleting the new listener later, as + // Google Test will do it. + listeners.Append(new LeakChecker); + } + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1_unittest.cc new file mode 100644 index 0000000..aefc4f1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample1_unittest.cc @@ -0,0 +1,153 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + + +// This sample shows how to write a simple unit test for a function, +// using Google C++ testing framework. +// +// Writing a unit test using Google C++ testing framework is easy as 1-2-3: + + +// Step 1. Include necessary header files such that the stuff your +// test logic needs is declared. +// +// Don't forget gtest.h, which declares the testing framework. + +#include +#include "sample1.h" +#include "gtest/gtest.h" + + +// Step 2. Use the TEST macro to define your tests. +// +// TEST has two parameters: the test case name and the test name. +// After using the macro, you should define your test logic between a +// pair of braces. You can use a bunch of macros to indicate the +// success or failure of a test. EXPECT_TRUE and EXPECT_EQ are +// examples of such macros. For a complete list, see gtest.h. +// +// +// +// In Google Test, tests are grouped into test cases. This is how we +// keep test code organized. You should put logically related tests +// into the same test case. +// +// The test case name and the test name should both be valid C++ +// identifiers. And you should not use underscore (_) in the names. +// +// Google Test guarantees that each test you define is run exactly +// once, but it makes no guarantee on the order the tests are +// executed. Therefore, you should write your tests in such a way +// that their results don't depend on their order. +// +// + + +// Tests Factorial(). + +// Tests factorial of negative numbers. +TEST(FactorialTest, Negative) { + // This test is named "Negative", and belongs to the "FactorialTest" + // test case. + EXPECT_EQ(1, Factorial(-5)); + EXPECT_EQ(1, Factorial(-1)); + EXPECT_GT(Factorial(-10), 0); + + // + // + // EXPECT_EQ(expected, actual) is the same as + // + // EXPECT_TRUE((expected) == (actual)) + // + // except that it will print both the expected value and the actual + // value when the assertion fails. This is very helpful for + // debugging. Therefore in this case EXPECT_EQ is preferred. + // + // On the other hand, EXPECT_TRUE accepts any Boolean expression, + // and is thus more general. + // + // +} + +// Tests factorial of 0. +TEST(FactorialTest, Zero) { + EXPECT_EQ(1, Factorial(0)); +} + +// Tests factorial of positive numbers. +TEST(FactorialTest, Positive) { + EXPECT_EQ(1, Factorial(1)); + EXPECT_EQ(2, Factorial(2)); + EXPECT_EQ(6, Factorial(3)); + EXPECT_EQ(40320, Factorial(8)); +} + + +// Tests IsPrime() + +// Tests negative input. +TEST(IsPrimeTest, Negative) { + // This test belongs to the IsPrimeTest test case. + + EXPECT_FALSE(IsPrime(-1)); + EXPECT_FALSE(IsPrime(-2)); + EXPECT_FALSE(IsPrime(INT_MIN)); +} + +// Tests some trivial cases. +TEST(IsPrimeTest, Trivial) { + EXPECT_FALSE(IsPrime(0)); + EXPECT_FALSE(IsPrime(1)); + EXPECT_TRUE(IsPrime(2)); + EXPECT_TRUE(IsPrime(3)); +} + +// Tests positive input. +TEST(IsPrimeTest, Positive) { + EXPECT_FALSE(IsPrime(4)); + EXPECT_TRUE(IsPrime(5)); + EXPECT_FALSE(IsPrime(6)); + EXPECT_TRUE(IsPrime(23)); +} + +// Step 3. Call RUN_ALL_TESTS() in main(). +// +// We do this by linking in src/gtest_main.cc file, which consists of +// a main() function which calls RUN_ALL_TESTS() for us. +// +// This runs all the tests you've defined, prints the result, and +// returns 0 if successful, or 1 otherwise. +// +// Did you notice that we didn't register the tests? The +// RUN_ALL_TESTS() macro magically knows about all the tests we +// defined. Isn't this convenient? diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2.cc new file mode 100644 index 0000000..5f763b9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2.cc @@ -0,0 +1,56 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "sample2.h" + +#include + +// Clones a 0-terminated C string, allocating memory using new. +const char* MyString::CloneCString(const char* a_c_string) { + if (a_c_string == NULL) return NULL; + + const size_t len = strlen(a_c_string); + char* const clone = new char[ len + 1 ]; + memcpy(clone, a_c_string, len + 1); + + return clone; +} + +// Sets the 0-terminated C string this MyString object +// represents. +void MyString::Set(const char* a_c_string) { + // Makes sure this works when c_string == c_string_ + const char* const temp = MyString::CloneCString(a_c_string); + delete[] c_string_; + c_string_ = temp; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2.h b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2.h new file mode 100644 index 0000000..cb485c7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2.h @@ -0,0 +1,85 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_SAMPLES_SAMPLE2_H_ +#define GTEST_SAMPLES_SAMPLE2_H_ + +#include + + +// A simple string class. +class MyString { + private: + const char* c_string_; + const MyString& operator=(const MyString& rhs); + + public: + // Clones a 0-terminated C string, allocating memory using new. + static const char* CloneCString(const char* a_c_string); + + //////////////////////////////////////////////////////////// + // + // C'tors + + // The default c'tor constructs a NULL string. + MyString() : c_string_(NULL) {} + + // Constructs a MyString by cloning a 0-terminated C string. + explicit MyString(const char* a_c_string) : c_string_(NULL) { + Set(a_c_string); + } + + // Copy c'tor + MyString(const MyString& string) : c_string_(NULL) { + Set(string.c_string_); + } + + //////////////////////////////////////////////////////////// + // + // D'tor. MyString is intended to be a final class, so the d'tor + // doesn't need to be virtual. + ~MyString() { delete[] c_string_; } + + // Gets the 0-terminated C string this MyString object represents. + const char* c_string() const { return c_string_; } + + size_t Length() const { + return c_string_ == NULL ? 0 : strlen(c_string_); + } + + // Sets the 0-terminated C string this MyString object represents. + void Set(const char* c_string); +}; + + +#endif // GTEST_SAMPLES_SAMPLE2_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2_unittest.cc new file mode 100644 index 0000000..4fa19b7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample2_unittest.cc @@ -0,0 +1,109 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + + +// This sample shows how to write a more complex unit test for a class +// that has multiple member functions. +// +// Usually, it's a good idea to have one test for each method in your +// class. You don't have to do that exactly, but it helps to keep +// your tests organized. You may also throw in additional tests as +// needed. + +#include "sample2.h" +#include "gtest/gtest.h" + +// In this example, we test the MyString class (a simple string). + +// Tests the default c'tor. +TEST(MyString, DefaultConstructor) { + const MyString s; + + // Asserts that s.c_string() returns NULL. + // + // + // + // If we write NULL instead of + // + // static_cast(NULL) + // + // in this assertion, it will generate a warning on gcc 3.4. The + // reason is that EXPECT_EQ needs to know the types of its + // arguments in order to print them when it fails. Since NULL is + // #defined as 0, the compiler will use the formatter function for + // int to print it. However, gcc thinks that NULL should be used as + // a pointer, not an int, and therefore complains. + // + // The root of the problem is C++'s lack of distinction between the + // integer number 0 and the null pointer constant. Unfortunately, + // we have to live with this fact. + // + // + EXPECT_STREQ(NULL, s.c_string()); + + EXPECT_EQ(0u, s.Length()); +} + +const char kHelloString[] = "Hello, world!"; + +// Tests the c'tor that accepts a C string. +TEST(MyString, ConstructorFromCString) { + const MyString s(kHelloString); + EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); + EXPECT_EQ(sizeof(kHelloString)/sizeof(kHelloString[0]) - 1, + s.Length()); +} + +// Tests the copy c'tor. +TEST(MyString, CopyConstructor) { + const MyString s1(kHelloString); + const MyString s2 = s1; + EXPECT_EQ(0, strcmp(s2.c_string(), kHelloString)); +} + +// Tests the Set method. +TEST(MyString, Set) { + MyString s; + + s.Set(kHelloString); + EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); + + // Set should work when the input pointer is the same as the one + // already in the MyString object. + s.Set(s.c_string()); + EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); + + // Can we set the MyString to NULL? + s.Set(NULL); + EXPECT_STREQ(NULL, s.c_string()); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample3-inl.h b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample3-inl.h new file mode 100644 index 0000000..7e3084d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample3-inl.h @@ -0,0 +1,172 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_SAMPLES_SAMPLE3_INL_H_ +#define GTEST_SAMPLES_SAMPLE3_INL_H_ + +#include + + +// Queue is a simple queue implemented as a singled-linked list. +// +// The element type must support copy constructor. +template // E is the element type +class Queue; + +// QueueNode is a node in a Queue, which consists of an element of +// type E and a pointer to the next node. +template // E is the element type +class QueueNode { + friend class Queue; + + public: + // Gets the element in this node. + const E& element() const { return element_; } + + // Gets the next node in the queue. + QueueNode* next() { return next_; } + const QueueNode* next() const { return next_; } + + private: + // Creates a node with a given element value. The next pointer is + // set to NULL. + explicit QueueNode(const E& an_element) : element_(an_element), next_(NULL) {} + + // We disable the default assignment operator and copy c'tor. + const QueueNode& operator = (const QueueNode&); + QueueNode(const QueueNode&); + + E element_; + QueueNode* next_; +}; + +template // E is the element type. +class Queue { + public: + // Creates an empty queue. + Queue() : head_(NULL), last_(NULL), size_(0) {} + + // D'tor. Clears the queue. + ~Queue() { Clear(); } + + // Clears the queue. + void Clear() { + if (size_ > 0) { + // 1. Deletes every node. + QueueNode* node = head_; + QueueNode* next = node->next(); + for (; ;) { + delete node; + node = next; + if (node == NULL) break; + next = node->next(); + } + + // 2. Resets the member variables. + head_ = last_ = NULL; + size_ = 0; + } + } + + // Gets the number of elements. + size_t Size() const { return size_; } + + // Gets the first element of the queue, or NULL if the queue is empty. + QueueNode* Head() { return head_; } + const QueueNode* Head() const { return head_; } + + // Gets the last element of the queue, or NULL if the queue is empty. + QueueNode* Last() { return last_; } + const QueueNode* Last() const { return last_; } + + // Adds an element to the end of the queue. A copy of the element is + // created using the copy constructor, and then stored in the queue. + // Changes made to the element in the queue doesn't affect the source + // object, and vice versa. + void Enqueue(const E& element) { + QueueNode* new_node = new QueueNode(element); + + if (size_ == 0) { + head_ = last_ = new_node; + size_ = 1; + } else { + last_->next_ = new_node; + last_ = new_node; + size_++; + } + } + + // Removes the head of the queue and returns it. Returns NULL if + // the queue is empty. + E* Dequeue() { + if (size_ == 0) { + return NULL; + } + + const QueueNode* const old_head = head_; + head_ = head_->next_; + size_--; + if (size_ == 0) { + last_ = NULL; + } + + E* element = new E(old_head->element()); + delete old_head; + + return element; + } + + // Applies a function/functor on each element of the queue, and + // returns the result in a new queue. The original queue is not + // affected. + template + Queue* Map(F function) const { + Queue* new_queue = new Queue(); + for (const QueueNode* node = head_; node != NULL; node = node->next_) { + new_queue->Enqueue(function(node->element())); + } + + return new_queue; + } + + private: + QueueNode* head_; // The first node of the queue. + QueueNode* last_; // The last node of the queue. + size_t size_; // The number of elements in the queue. + + // We disallow copying a queue. + Queue(const Queue&); + const Queue& operator = (const Queue&); +}; + +#endif // GTEST_SAMPLES_SAMPLE3_INL_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample3_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample3_unittest.cc new file mode 100644 index 0000000..bf3877d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample3_unittest.cc @@ -0,0 +1,151 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + + +// In this example, we use a more advanced feature of Google Test called +// test fixture. +// +// A test fixture is a place to hold objects and functions shared by +// all tests in a test case. Using a test fixture avoids duplicating +// the test code necessary to initialize and cleanup those common +// objects for each test. It is also useful for defining sub-routines +// that your tests need to invoke a lot. +// +// +// +// The tests share the test fixture in the sense of code sharing, not +// data sharing. Each test is given its own fresh copy of the +// fixture. You cannot expect the data modified by one test to be +// passed on to another test, which is a bad idea. +// +// The reason for this design is that tests should be independent and +// repeatable. In particular, a test should not fail as the result of +// another test's failure. If one test depends on info produced by +// another test, then the two tests should really be one big test. +// +// The macros for indicating the success/failure of a test +// (EXPECT_TRUE, FAIL, etc) need to know what the current test is +// (when Google Test prints the test result, it tells you which test +// each failure belongs to). Technically, these macros invoke a +// member function of the Test class. Therefore, you cannot use them +// in a global function. That's why you should put test sub-routines +// in a test fixture. +// +// + +#include "sample3-inl.h" +#include "gtest/gtest.h" + +// To use a test fixture, derive a class from testing::Test. +class QueueTest : public testing::Test { + protected: // You should make the members protected s.t. they can be + // accessed from sub-classes. + + // virtual void SetUp() will be called before each test is run. You + // should define it if you need to initialize the varaibles. + // Otherwise, this can be skipped. + virtual void SetUp() { + q1_.Enqueue(1); + q2_.Enqueue(2); + q2_.Enqueue(3); + } + + // virtual void TearDown() will be called after each test is run. + // You should define it if there is cleanup work to do. Otherwise, + // you don't have to provide it. + // + // virtual void TearDown() { + // } + + // A helper function that some test uses. + static int Double(int n) { + return 2*n; + } + + // A helper function for testing Queue::Map(). + void MapTester(const Queue * q) { + // Creates a new queue, where each element is twice as big as the + // corresponding one in q. + const Queue * const new_q = q->Map(Double); + + // Verifies that the new queue has the same size as q. + ASSERT_EQ(q->Size(), new_q->Size()); + + // Verifies the relationship between the elements of the two queues. + for ( const QueueNode * n1 = q->Head(), * n2 = new_q->Head(); + n1 != NULL; n1 = n1->next(), n2 = n2->next() ) { + EXPECT_EQ(2 * n1->element(), n2->element()); + } + + delete new_q; + } + + // Declares the variables your tests want to use. + Queue q0_; + Queue q1_; + Queue q2_; +}; + +// When you have a test fixture, you define a test using TEST_F +// instead of TEST. + +// Tests the default c'tor. +TEST_F(QueueTest, DefaultConstructor) { + // You can access data in the test fixture here. + EXPECT_EQ(0u, q0_.Size()); +} + +// Tests Dequeue(). +TEST_F(QueueTest, Dequeue) { + int * n = q0_.Dequeue(); + EXPECT_TRUE(n == NULL); + + n = q1_.Dequeue(); + ASSERT_TRUE(n != NULL); + EXPECT_EQ(1, *n); + EXPECT_EQ(0u, q1_.Size()); + delete n; + + n = q2_.Dequeue(); + ASSERT_TRUE(n != NULL); + EXPECT_EQ(2, *n); + EXPECT_EQ(1u, q2_.Size()); + delete n; +} + +// Tests the Queue::Map() function. +TEST_F(QueueTest, Map) { + MapTester(&q0_); + MapTester(&q1_); + MapTester(&q2_); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4.cc new file mode 100644 index 0000000..ae44bda --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4.cc @@ -0,0 +1,46 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#include + +#include "sample4.h" + +// Returns the current counter value, and increments it. +int Counter::Increment() { + return counter_++; +} + +// Prints the current counter value to STDOUT. +void Counter::Print() const { + printf("%d", counter_); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4.h b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4.h new file mode 100644 index 0000000..cd60f0d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4.h @@ -0,0 +1,53 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_SAMPLES_SAMPLE4_H_ +#define GTEST_SAMPLES_SAMPLE4_H_ + +// A simple monotonic counter. +class Counter { + private: + int counter_; + + public: + // Creates a counter that starts at 0. + Counter() : counter_(0) {} + + // Returns the current counter value, and increments it. + int Increment(); + + // Prints the current counter value to STDOUT. + void Print() const; +}; + +#endif // GTEST_SAMPLES_SAMPLE4_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4_unittest.cc new file mode 100644 index 0000000..fa5afc7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample4_unittest.cc @@ -0,0 +1,45 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest.h" +#include "sample4.h" + +// Tests the Increment() method. +TEST(Counter, Increment) { + Counter c; + + // EXPECT_EQ() evaluates its arguments exactly once, so they + // can have side effects. + + EXPECT_EQ(0, c.Increment()); + EXPECT_EQ(1, c.Increment()); + EXPECT_EQ(2, c.Increment()); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample5_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample5_unittest.cc new file mode 100644 index 0000000..43d8e57 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample5_unittest.cc @@ -0,0 +1,199 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// This sample teaches how to reuse a test fixture in multiple test +// cases by deriving sub-fixtures from it. +// +// When you define a test fixture, you specify the name of the test +// case that will use this fixture. Therefore, a test fixture can +// be used by only one test case. +// +// Sometimes, more than one test cases may want to use the same or +// slightly different test fixtures. For example, you may want to +// make sure that all tests for a GUI library don't leak important +// system resources like fonts and brushes. In Google Test, you do +// this by putting the shared logic in a super (as in "super class") +// test fixture, and then have each test case use a fixture derived +// from this super fixture. + +#include +#include +#include "sample3-inl.h" +#include "gtest/gtest.h" +#include "sample1.h" + +// In this sample, we want to ensure that every test finishes within +// ~5 seconds. If a test takes longer to run, we consider it a +// failure. +// +// We put the code for timing a test in a test fixture called +// "QuickTest". QuickTest is intended to be the super fixture that +// other fixtures derive from, therefore there is no test case with +// the name "QuickTest". This is OK. +// +// Later, we will derive multiple test fixtures from QuickTest. +class QuickTest : public testing::Test { + protected: + // Remember that SetUp() is run immediately before a test starts. + // This is a good place to record the start time. + virtual void SetUp() { + start_time_ = time(NULL); + } + + // TearDown() is invoked immediately after a test finishes. Here we + // check if the test was too slow. + virtual void TearDown() { + // Gets the time when the test finishes + const time_t end_time = time(NULL); + + // Asserts that the test took no more than ~5 seconds. Did you + // know that you can use assertions in SetUp() and TearDown() as + // well? + EXPECT_TRUE(end_time - start_time_ <= 5) << "The test took too long."; + } + + // The UTC time (in seconds) when the test starts + time_t start_time_; +}; + + +// We derive a fixture named IntegerFunctionTest from the QuickTest +// fixture. All tests using this fixture will be automatically +// required to be quick. +class IntegerFunctionTest : public QuickTest { + // We don't need any more logic than already in the QuickTest fixture. + // Therefore the body is empty. +}; + + +// Now we can write tests in the IntegerFunctionTest test case. + +// Tests Factorial() +TEST_F(IntegerFunctionTest, Factorial) { + // Tests factorial of negative numbers. + EXPECT_EQ(1, Factorial(-5)); + EXPECT_EQ(1, Factorial(-1)); + EXPECT_GT(Factorial(-10), 0); + + // Tests factorial of 0. + EXPECT_EQ(1, Factorial(0)); + + // Tests factorial of positive numbers. + EXPECT_EQ(1, Factorial(1)); + EXPECT_EQ(2, Factorial(2)); + EXPECT_EQ(6, Factorial(3)); + EXPECT_EQ(40320, Factorial(8)); +} + + +// Tests IsPrime() +TEST_F(IntegerFunctionTest, IsPrime) { + // Tests negative input. + EXPECT_FALSE(IsPrime(-1)); + EXPECT_FALSE(IsPrime(-2)); + EXPECT_FALSE(IsPrime(INT_MIN)); + + // Tests some trivial cases. + EXPECT_FALSE(IsPrime(0)); + EXPECT_FALSE(IsPrime(1)); + EXPECT_TRUE(IsPrime(2)); + EXPECT_TRUE(IsPrime(3)); + + // Tests positive input. + EXPECT_FALSE(IsPrime(4)); + EXPECT_TRUE(IsPrime(5)); + EXPECT_FALSE(IsPrime(6)); + EXPECT_TRUE(IsPrime(23)); +} + + +// The next test case (named "QueueTest") also needs to be quick, so +// we derive another fixture from QuickTest. +// +// The QueueTest test fixture has some logic and shared objects in +// addition to what's in QuickTest already. We define the additional +// stuff inside the body of the test fixture, as usual. +class QueueTest : public QuickTest { + protected: + virtual void SetUp() { + // First, we need to set up the super fixture (QuickTest). + QuickTest::SetUp(); + + // Second, some additional setup for this fixture. + q1_.Enqueue(1); + q2_.Enqueue(2); + q2_.Enqueue(3); + } + + // By default, TearDown() inherits the behavior of + // QuickTest::TearDown(). As we have no additional cleaning work + // for QueueTest, we omit it here. + // + // virtual void TearDown() { + // QuickTest::TearDown(); + // } + + Queue q0_; + Queue q1_; + Queue q2_; +}; + + +// Now, let's write tests using the QueueTest fixture. + +// Tests the default constructor. +TEST_F(QueueTest, DefaultConstructor) { + EXPECT_EQ(0u, q0_.Size()); +} + +// Tests Dequeue(). +TEST_F(QueueTest, Dequeue) { + int* n = q0_.Dequeue(); + EXPECT_TRUE(n == NULL); + + n = q1_.Dequeue(); + EXPECT_TRUE(n != NULL); + EXPECT_EQ(1, *n); + EXPECT_EQ(0u, q1_.Size()); + delete n; + + n = q2_.Dequeue(); + EXPECT_TRUE(n != NULL); + EXPECT_EQ(2, *n); + EXPECT_EQ(1u, q2_.Size()); + delete n; +} + +// If necessary, you can derive further test fixtures from a derived +// fixture itself. For example, you can derive another fixture from +// QueueTest. Google Test imposes no limit on how deep the hierarchy +// can be. In practice, however, you probably don't want it to be too +// deep as to be confusing. diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample6_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample6_unittest.cc new file mode 100644 index 0000000..8f2036a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample6_unittest.cc @@ -0,0 +1,224 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// This sample shows how to test common properties of multiple +// implementations of the same interface (aka interface tests). + +// The interface and its implementations are in this header. +#include "prime_tables.h" + +#include "gtest/gtest.h" + +// First, we define some factory functions for creating instances of +// the implementations. You may be able to skip this step if all your +// implementations can be constructed the same way. + +template +PrimeTable* CreatePrimeTable(); + +template <> +PrimeTable* CreatePrimeTable() { + return new OnTheFlyPrimeTable; +} + +template <> +PrimeTable* CreatePrimeTable() { + return new PreCalculatedPrimeTable(10000); +} + +// Then we define a test fixture class template. +template +class PrimeTableTest : public testing::Test { + protected: + // The ctor calls the factory function to create a prime table + // implemented by T. + PrimeTableTest() : table_(CreatePrimeTable()) {} + + virtual ~PrimeTableTest() { delete table_; } + + // Note that we test an implementation via the base interface + // instead of the actual implementation class. This is important + // for keeping the tests close to the real world scenario, where the + // implementation is invoked via the base interface. It avoids + // got-yas where the implementation class has a method that shadows + // a method with the same name (but slightly different argument + // types) in the base interface, for example. + PrimeTable* const table_; +}; + +#if GTEST_HAS_TYPED_TEST + +using testing::Types; + +// Google Test offers two ways for reusing tests for different types. +// The first is called "typed tests". You should use it if you +// already know *all* the types you are gonna exercise when you write +// the tests. + +// To write a typed test case, first use +// +// TYPED_TEST_CASE(TestCaseName, TypeList); +// +// to declare it and specify the type parameters. As with TEST_F, +// TestCaseName must match the test fixture name. + +// The list of types we want to test. +typedef Types Implementations; + +TYPED_TEST_CASE(PrimeTableTest, Implementations); + +// Then use TYPED_TEST(TestCaseName, TestName) to define a typed test, +// similar to TEST_F. +TYPED_TEST(PrimeTableTest, ReturnsFalseForNonPrimes) { + // Inside the test body, you can refer to the type parameter by + // TypeParam, and refer to the fixture class by TestFixture. We + // don't need them in this example. + + // Since we are in the template world, C++ requires explicitly + // writing 'this->' when referring to members of the fixture class. + // This is something you have to learn to live with. + EXPECT_FALSE(this->table_->IsPrime(-5)); + EXPECT_FALSE(this->table_->IsPrime(0)); + EXPECT_FALSE(this->table_->IsPrime(1)); + EXPECT_FALSE(this->table_->IsPrime(4)); + EXPECT_FALSE(this->table_->IsPrime(6)); + EXPECT_FALSE(this->table_->IsPrime(100)); +} + +TYPED_TEST(PrimeTableTest, ReturnsTrueForPrimes) { + EXPECT_TRUE(this->table_->IsPrime(2)); + EXPECT_TRUE(this->table_->IsPrime(3)); + EXPECT_TRUE(this->table_->IsPrime(5)); + EXPECT_TRUE(this->table_->IsPrime(7)); + EXPECT_TRUE(this->table_->IsPrime(11)); + EXPECT_TRUE(this->table_->IsPrime(131)); +} + +TYPED_TEST(PrimeTableTest, CanGetNextPrime) { + EXPECT_EQ(2, this->table_->GetNextPrime(0)); + EXPECT_EQ(3, this->table_->GetNextPrime(2)); + EXPECT_EQ(5, this->table_->GetNextPrime(3)); + EXPECT_EQ(7, this->table_->GetNextPrime(5)); + EXPECT_EQ(11, this->table_->GetNextPrime(7)); + EXPECT_EQ(131, this->table_->GetNextPrime(128)); +} + +// That's it! Google Test will repeat each TYPED_TEST for each type +// in the type list specified in TYPED_TEST_CASE. Sit back and be +// happy that you don't have to define them multiple times. + +#endif // GTEST_HAS_TYPED_TEST + +#if GTEST_HAS_TYPED_TEST_P + +using testing::Types; + +// Sometimes, however, you don't yet know all the types that you want +// to test when you write the tests. For example, if you are the +// author of an interface and expect other people to implement it, you +// might want to write a set of tests to make sure each implementation +// conforms to some basic requirements, but you don't know what +// implementations will be written in the future. +// +// How can you write the tests without committing to the type +// parameters? That's what "type-parameterized tests" can do for you. +// It is a bit more involved than typed tests, but in return you get a +// test pattern that can be reused in many contexts, which is a big +// win. Here's how you do it: + +// First, define a test fixture class template. Here we just reuse +// the PrimeTableTest fixture defined earlier: + +template +class PrimeTableTest2 : public PrimeTableTest { +}; + +// Then, declare the test case. The argument is the name of the test +// fixture, and also the name of the test case (as usual). The _P +// suffix is for "parameterized" or "pattern". +TYPED_TEST_CASE_P(PrimeTableTest2); + +// Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test, +// similar to what you do with TEST_F. +TYPED_TEST_P(PrimeTableTest2, ReturnsFalseForNonPrimes) { + EXPECT_FALSE(this->table_->IsPrime(-5)); + EXPECT_FALSE(this->table_->IsPrime(0)); + EXPECT_FALSE(this->table_->IsPrime(1)); + EXPECT_FALSE(this->table_->IsPrime(4)); + EXPECT_FALSE(this->table_->IsPrime(6)); + EXPECT_FALSE(this->table_->IsPrime(100)); +} + +TYPED_TEST_P(PrimeTableTest2, ReturnsTrueForPrimes) { + EXPECT_TRUE(this->table_->IsPrime(2)); + EXPECT_TRUE(this->table_->IsPrime(3)); + EXPECT_TRUE(this->table_->IsPrime(5)); + EXPECT_TRUE(this->table_->IsPrime(7)); + EXPECT_TRUE(this->table_->IsPrime(11)); + EXPECT_TRUE(this->table_->IsPrime(131)); +} + +TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) { + EXPECT_EQ(2, this->table_->GetNextPrime(0)); + EXPECT_EQ(3, this->table_->GetNextPrime(2)); + EXPECT_EQ(5, this->table_->GetNextPrime(3)); + EXPECT_EQ(7, this->table_->GetNextPrime(5)); + EXPECT_EQ(11, this->table_->GetNextPrime(7)); + EXPECT_EQ(131, this->table_->GetNextPrime(128)); +} + +// Type-parameterized tests involve one extra step: you have to +// enumerate the tests you defined: +REGISTER_TYPED_TEST_CASE_P( + PrimeTableTest2, // The first argument is the test case name. + // The rest of the arguments are the test names. + ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime); + +// At this point the test pattern is done. However, you don't have +// any real test yet as you haven't said which types you want to run +// the tests with. + +// To turn the abstract test pattern into real tests, you instantiate +// it with a list of types. Usually the test pattern will be defined +// in a .h file, and anyone can #include and instantiate it. You can +// even instantiate it more than once in the same program. To tell +// different instances apart, you give each of them a name, which will +// become part of the test case name and can be used in test filters. + +// The list of types we want to test. Note that it doesn't have to be +// defined at the time we write the TYPED_TEST_P()s. +typedef Types + PrimeTableImplementations; +INSTANTIATE_TYPED_TEST_CASE_P(OnTheFlyAndPreCalculated, // Instance name + PrimeTableTest2, // Test case name + PrimeTableImplementations); // Type list + +#endif // GTEST_HAS_TYPED_TEST_P diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample7_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample7_unittest.cc new file mode 100644 index 0000000..1b651a2 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample7_unittest.cc @@ -0,0 +1,130 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) + +// This sample shows how to test common properties of multiple +// implementations of an interface (aka interface tests) using +// value-parameterized tests. Each test in the test case has +// a parameter that is an interface pointer to an implementation +// tested. + +// The interface and its implementations are in this header. +#include "prime_tables.h" + +#include "gtest/gtest.h" + +#if GTEST_HAS_PARAM_TEST + +using ::testing::TestWithParam; +using ::testing::Values; + +// As a general rule, to prevent a test from affecting the tests that come +// after it, you should create and destroy the tested objects for each test +// instead of reusing them. In this sample we will define a simple factory +// function for PrimeTable objects. We will instantiate objects in test's +// SetUp() method and delete them in TearDown() method. +typedef PrimeTable* CreatePrimeTableFunc(); + +PrimeTable* CreateOnTheFlyPrimeTable() { + return new OnTheFlyPrimeTable(); +} + +template +PrimeTable* CreatePreCalculatedPrimeTable() { + return new PreCalculatedPrimeTable(max_precalculated); +} + +// Inside the test body, fixture constructor, SetUp(), and TearDown() you +// can refer to the test parameter by GetParam(). In this case, the test +// parameter is a factory function which we call in fixture's SetUp() to +// create and store an instance of PrimeTable. +class PrimeTableTest : public TestWithParam { + public: + virtual ~PrimeTableTest() { delete table_; } + virtual void SetUp() { table_ = (*GetParam())(); } + virtual void TearDown() { + delete table_; + table_ = NULL; + } + + protected: + PrimeTable* table_; +}; + +TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) { + EXPECT_FALSE(table_->IsPrime(-5)); + EXPECT_FALSE(table_->IsPrime(0)); + EXPECT_FALSE(table_->IsPrime(1)); + EXPECT_FALSE(table_->IsPrime(4)); + EXPECT_FALSE(table_->IsPrime(6)); + EXPECT_FALSE(table_->IsPrime(100)); +} + +TEST_P(PrimeTableTest, ReturnsTrueForPrimes) { + EXPECT_TRUE(table_->IsPrime(2)); + EXPECT_TRUE(table_->IsPrime(3)); + EXPECT_TRUE(table_->IsPrime(5)); + EXPECT_TRUE(table_->IsPrime(7)); + EXPECT_TRUE(table_->IsPrime(11)); + EXPECT_TRUE(table_->IsPrime(131)); +} + +TEST_P(PrimeTableTest, CanGetNextPrime) { + EXPECT_EQ(2, table_->GetNextPrime(0)); + EXPECT_EQ(3, table_->GetNextPrime(2)); + EXPECT_EQ(5, table_->GetNextPrime(3)); + EXPECT_EQ(7, table_->GetNextPrime(5)); + EXPECT_EQ(11, table_->GetNextPrime(7)); + EXPECT_EQ(131, table_->GetNextPrime(128)); +} + +// In order to run value-parameterized tests, you need to instantiate them, +// or bind them to a list of values which will be used as test parameters. +// You can instantiate them in a different translation module, or even +// instantiate them several times. +// +// Here, we instantiate our tests with a list of two PrimeTable object +// factory functions: +INSTANTIATE_TEST_CASE_P( + OnTheFlyAndPreCalculated, + PrimeTableTest, + Values(&CreateOnTheFlyPrimeTable, &CreatePreCalculatedPrimeTable<1000>)); + +#else + +// Google Test may not support value-parameterized tests with some +// compilers. If we use conditional compilation to compile out all +// code referring to the gtest_main library, MSVC linker will not link +// that library at all and consequently complain about missing entry +// point defined in that library (fatal error LNK1561: entry point +// must be defined). This dummy test keeps gtest_main linked in. +TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {} + +#endif // GTEST_HAS_PARAM_TEST diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample8_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample8_unittest.cc new file mode 100644 index 0000000..5ad2e2c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample8_unittest.cc @@ -0,0 +1,173 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) + +// This sample shows how to test code relying on some global flag variables. +// Combine() helps with generating all possible combinations of such flags, +// and each test is given one combination as a parameter. + +// Use class definitions to test from this header. +#include "prime_tables.h" + +#include "gtest/gtest.h" + +#if GTEST_HAS_COMBINE + +// Suppose we want to introduce a new, improved implementation of PrimeTable +// which combines speed of PrecalcPrimeTable and versatility of +// OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both +// PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more +// appropriate under the circumstances. But in low memory conditions, it can be +// told to instantiate without PrecalcPrimeTable instance at all and use only +// OnTheFlyPrimeTable. +class HybridPrimeTable : public PrimeTable { + public: + HybridPrimeTable(bool force_on_the_fly, int max_precalculated) + : on_the_fly_impl_(new OnTheFlyPrimeTable), + precalc_impl_(force_on_the_fly ? NULL : + new PreCalculatedPrimeTable(max_precalculated)), + max_precalculated_(max_precalculated) {} + virtual ~HybridPrimeTable() { + delete on_the_fly_impl_; + delete precalc_impl_; + } + + virtual bool IsPrime(int n) const { + if (precalc_impl_ != NULL && n < max_precalculated_) + return precalc_impl_->IsPrime(n); + else + return on_the_fly_impl_->IsPrime(n); + } + + virtual int GetNextPrime(int p) const { + int next_prime = -1; + if (precalc_impl_ != NULL && p < max_precalculated_) + next_prime = precalc_impl_->GetNextPrime(p); + + return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p); + } + + private: + OnTheFlyPrimeTable* on_the_fly_impl_; + PreCalculatedPrimeTable* precalc_impl_; + int max_precalculated_; +}; + +using ::testing::TestWithParam; +using ::testing::Bool; +using ::testing::Values; +using ::testing::Combine; + +// To test all code paths for HybridPrimeTable we must test it with numbers +// both within and outside PreCalculatedPrimeTable's capacity and also with +// PreCalculatedPrimeTable disabled. We do this by defining fixture which will +// accept different combinations of parameters for instantiating a +// HybridPrimeTable instance. +class PrimeTableTest : public TestWithParam< ::std::tr1::tuple > { + protected: + virtual void SetUp() { + // This can be written as + // + // bool force_on_the_fly; + // int max_precalculated; + // tie(force_on_the_fly, max_precalculated) = GetParam(); + // + // once the Google C++ Style Guide allows use of ::std::tr1::tie. + // + bool force_on_the_fly = ::std::tr1::get<0>(GetParam()); + int max_precalculated = ::std::tr1::get<1>(GetParam()); + table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated); + } + virtual void TearDown() { + delete table_; + table_ = NULL; + } + HybridPrimeTable* table_; +}; + +TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) { + // Inside the test body, you can refer to the test parameter by GetParam(). + // In this case, the test parameter is a PrimeTable interface pointer which + // we can use directly. + // Please note that you can also save it in the fixture's SetUp() method + // or constructor and use saved copy in the tests. + + EXPECT_FALSE(table_->IsPrime(-5)); + EXPECT_FALSE(table_->IsPrime(0)); + EXPECT_FALSE(table_->IsPrime(1)); + EXPECT_FALSE(table_->IsPrime(4)); + EXPECT_FALSE(table_->IsPrime(6)); + EXPECT_FALSE(table_->IsPrime(100)); +} + +TEST_P(PrimeTableTest, ReturnsTrueForPrimes) { + EXPECT_TRUE(table_->IsPrime(2)); + EXPECT_TRUE(table_->IsPrime(3)); + EXPECT_TRUE(table_->IsPrime(5)); + EXPECT_TRUE(table_->IsPrime(7)); + EXPECT_TRUE(table_->IsPrime(11)); + EXPECT_TRUE(table_->IsPrime(131)); +} + +TEST_P(PrimeTableTest, CanGetNextPrime) { + EXPECT_EQ(2, table_->GetNextPrime(0)); + EXPECT_EQ(3, table_->GetNextPrime(2)); + EXPECT_EQ(5, table_->GetNextPrime(3)); + EXPECT_EQ(7, table_->GetNextPrime(5)); + EXPECT_EQ(11, table_->GetNextPrime(7)); + EXPECT_EQ(131, table_->GetNextPrime(128)); +} + +// In order to run value-parameterized tests, you need to instantiate them, +// or bind them to a list of values which will be used as test parameters. +// You can instantiate them in a different translation module, or even +// instantiate them several times. +// +// Here, we instantiate our tests with a list of parameters. We must combine +// all variations of the boolean flag suppressing PrecalcPrimeTable and some +// meaningful values for tests. We choose a small value (1), and a value that +// will put some of the tested numbers beyond the capability of the +// PrecalcPrimeTable instance and some inside it (10). Combine will produce all +// possible combinations. +INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters, + PrimeTableTest, + Combine(Bool(), Values(1, 10))); + +#else + +// Google Test may not support Combine() with some compilers. If we +// use conditional compilation to compile out all code referring to +// the gtest_main library, MSVC linker will not link that library at +// all and consequently complain about missing entry point defined in +// that library (fatal error LNK1561: entry point must be +// defined). This dummy test keeps gtest_main linked in. +TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {} + +#endif // GTEST_HAS_COMBINE diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample9_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample9_unittest.cc new file mode 100644 index 0000000..b2e2079 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/samples/sample9_unittest.cc @@ -0,0 +1,160 @@ +// Copyright 2009 Google Inc. All Rights Reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) + +// This sample shows how to use Google Test listener API to implement +// an alternative console output and how to use the UnitTest reflection API +// to enumerate test cases and tests and to inspect their results. + +#include + +#include "gtest/gtest.h" + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +namespace { + +// Provides alternative output mode which produces minimal amount of +// information about tests. +class TersePrinter : public EmptyTestEventListener { + private: + // Called before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& /* unit_test */) {} + + // Called after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) { + fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED"); + fflush(stdout); + } + + // Called before a test starts. + virtual void OnTestStart(const TestInfo& test_info) { + fprintf(stdout, + "*** Test %s.%s starting.\n", + test_info.test_case_name(), + test_info.name()); + fflush(stdout); + } + + // Called after a failed assertion or a SUCCEED() invocation. + virtual void OnTestPartResult(const TestPartResult& test_part_result) { + fprintf(stdout, + "%s in %s:%d\n%s\n", + test_part_result.failed() ? "*** Failure" : "Success", + test_part_result.file_name(), + test_part_result.line_number(), + test_part_result.summary()); + fflush(stdout); + } + + // Called after a test ends. + virtual void OnTestEnd(const TestInfo& test_info) { + fprintf(stdout, + "*** Test %s.%s ending.\n", + test_info.test_case_name(), + test_info.name()); + fflush(stdout); + } +}; // class TersePrinter + +TEST(CustomOutputTest, PrintsMessage) { + printf("Printing something from the test body...\n"); +} + +TEST(CustomOutputTest, Succeeds) { + SUCCEED() << "SUCCEED() has been invoked from here"; +} + +TEST(CustomOutputTest, Fails) { + EXPECT_EQ(1, 2) + << "This test fails in order to demonstrate alternative failure messages"; +} + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + bool terse_output = false; + if (argc > 1 && strcmp(argv[1], "--terse_output") == 0 ) + terse_output = true; + else + printf("%s\n", "Run this program with --terse_output to change the way " + "it prints its output."); + + UnitTest& unit_test = *UnitTest::GetInstance(); + + // If we are given the --terse_output command line flag, suppresses the + // standard output and attaches own result printer. + if (terse_output) { + TestEventListeners& listeners = unit_test.listeners(); + + // Removes the default console output listener from the list so it will + // not receive events from Google Test and won't print any output. Since + // this operation transfers ownership of the listener to the caller we + // have to delete it as well. + delete listeners.Release(listeners.default_result_printer()); + + // Adds the custom output listener to the list. It will now receive + // events from Google Test and print the alternative output. We don't + // have to worry about deleting it since Google Test assumes ownership + // over it after adding it to the list. + listeners.Append(new TersePrinter); + } + int ret_val = RUN_ALL_TESTS(); + + // This is an example of using the UnitTest reflection API to inspect test + // results. Here we discount failures from the tests we expected to fail. + int unexpectedly_failed_tests = 0; + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + // Counts failed tests that were not meant to fail (those without + // 'Fails' in the name). + if (test_info.result()->Failed() && + strcmp(test_info.name(), "Fails") != 0) { + unexpectedly_failed_tests++; + } + } + } + + // Test that were meant to fail should not affect the test program outcome. + if (unexpectedly_failed_tests == 0) + ret_val = 0; + + return ret_val; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/fuse_gtest_files.py b/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/fuse_gtest_files.py new file mode 100755 index 0000000..57ef72f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/fuse_gtest_files.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# 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. + +"""fuse_gtest_files.py v0.2.0 +Fuses Google Test source code into a .h file and a .cc file. + +SYNOPSIS + fuse_gtest_files.py [GTEST_ROOT_DIR] OUTPUT_DIR + + Scans GTEST_ROOT_DIR for Google Test source code, and generates + two files: OUTPUT_DIR/gtest/gtest.h and OUTPUT_DIR/gtest/gtest-all.cc. + Then you can build your tests by adding OUTPUT_DIR to the include + search path and linking with OUTPUT_DIR/gtest/gtest-all.cc. These + two files contain everything you need to use Google Test. Hence + you can "install" Google Test by copying them to wherever you want. + + GTEST_ROOT_DIR can be omitted and defaults to the parent + directory of the directory holding this script. + +EXAMPLES + ./fuse_gtest_files.py fused_gtest + ./fuse_gtest_files.py path/to/unpacked/gtest fused_gtest + +This tool is experimental. In particular, it assumes that there is no +conditional inclusion of Google Test headers. Please report any +problems to googletestframework@googlegroups.com. You can read +http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide for +more information. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sets +import sys + +# We assume that this file is in the scripts/ directory in the Google +# Test root directory. +DEFAULT_GTEST_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..') + +# Regex for matching '#include "gtest/..."'. +INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gtest/.+)"') + +# Regex for matching '#include "src/..."'. +INCLUDE_SRC_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(src/.+)"') + +# Where to find the source seed files. +GTEST_H_SEED = 'include/gtest/gtest.h' +GTEST_SPI_H_SEED = 'include/gtest/gtest-spi.h' +GTEST_ALL_CC_SEED = 'src/gtest-all.cc' + +# Where to put the generated files. +GTEST_H_OUTPUT = 'gtest/gtest.h' +GTEST_ALL_CC_OUTPUT = 'gtest/gtest-all.cc' + + +def VerifyFileExists(directory, relative_path): + """Verifies that the given file exists; aborts on failure. + + relative_path is the file path relative to the given directory. + """ + + if not os.path.isfile(os.path.join(directory, relative_path)): + print 'ERROR: Cannot find %s in directory %s.' % (relative_path, + directory) + print ('Please either specify a valid project root directory ' + 'or omit it on the command line.') + sys.exit(1) + + +def ValidateGTestRootDir(gtest_root): + """Makes sure gtest_root points to a valid gtest root directory. + + The function aborts the program on failure. + """ + + VerifyFileExists(gtest_root, GTEST_H_SEED) + VerifyFileExists(gtest_root, GTEST_ALL_CC_SEED) + + +def VerifyOutputFile(output_dir, relative_path): + """Verifies that the given output file path is valid. + + relative_path is relative to the output_dir directory. + """ + + # Makes sure the output file either doesn't exist or can be overwritten. + output_file = os.path.join(output_dir, relative_path) + if os.path.exists(output_file): + # TODO(wan@google.com): The following user-interaction doesn't + # work with automated processes. We should provide a way for the + # Makefile to force overwriting the files. + print ('%s already exists in directory %s - overwrite it? (y/N) ' % + (relative_path, output_dir)) + answer = sys.stdin.readline().strip() + if answer not in ['y', 'Y']: + print 'ABORTED.' + sys.exit(1) + + # Makes sure the directory holding the output file exists; creates + # it and all its ancestors if necessary. + parent_directory = os.path.dirname(output_file) + if not os.path.isdir(parent_directory): + os.makedirs(parent_directory) + + +def ValidateOutputDir(output_dir): + """Makes sure output_dir points to a valid output directory. + + The function aborts the program on failure. + """ + + VerifyOutputFile(output_dir, GTEST_H_OUTPUT) + VerifyOutputFile(output_dir, GTEST_ALL_CC_OUTPUT) + + +def FuseGTestH(gtest_root, output_dir): + """Scans folder gtest_root to generate gtest/gtest.h in output_dir.""" + + output_file = file(os.path.join(output_dir, GTEST_H_OUTPUT), 'w') + processed_files = sets.Set() # Holds all gtest headers we've processed. + + def ProcessFile(gtest_header_path): + """Processes the given gtest header file.""" + + # We don't process the same header twice. + if gtest_header_path in processed_files: + return + + processed_files.add(gtest_header_path) + + # Reads each line in the given gtest header. + for line in file(os.path.join(gtest_root, gtest_header_path), 'r'): + m = INCLUDE_GTEST_FILE_REGEX.match(line) + if m: + # It's '#include "gtest/..."' - let's process it recursively. + ProcessFile('include/' + m.group(1)) + else: + # Otherwise we copy the line unchanged to the output file. + output_file.write(line) + + ProcessFile(GTEST_H_SEED) + output_file.close() + + +def FuseGTestAllCcToFile(gtest_root, output_file): + """Scans folder gtest_root to generate gtest/gtest-all.cc in output_file.""" + + processed_files = sets.Set() + + def ProcessFile(gtest_source_file): + """Processes the given gtest source file.""" + + # We don't process the same #included file twice. + if gtest_source_file in processed_files: + return + + processed_files.add(gtest_source_file) + + # Reads each line in the given gtest source file. + for line in file(os.path.join(gtest_root, gtest_source_file), 'r'): + m = INCLUDE_GTEST_FILE_REGEX.match(line) + if m: + if 'include/' + m.group(1) == GTEST_SPI_H_SEED: + # It's '#include "gtest/gtest-spi.h"'. This file is not + # #included by "gtest/gtest.h", so we need to process it. + ProcessFile(GTEST_SPI_H_SEED) + else: + # It's '#include "gtest/foo.h"' where foo is not gtest-spi. + # We treat it as '#include "gtest/gtest.h"', as all other + # gtest headers are being fused into gtest.h and cannot be + # #included directly. + + # There is no need to #include "gtest/gtest.h" more than once. + if not GTEST_H_SEED in processed_files: + processed_files.add(GTEST_H_SEED) + output_file.write('#include "%s"\n' % (GTEST_H_OUTPUT,)) + else: + m = INCLUDE_SRC_FILE_REGEX.match(line) + if m: + # It's '#include "src/foo"' - let's process it recursively. + ProcessFile(m.group(1)) + else: + output_file.write(line) + + ProcessFile(GTEST_ALL_CC_SEED) + + +def FuseGTestAllCc(gtest_root, output_dir): + """Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir.""" + + output_file = file(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w') + FuseGTestAllCcToFile(gtest_root, output_file) + output_file.close() + + +def FuseGTest(gtest_root, output_dir): + """Fuses gtest.h and gtest-all.cc.""" + + ValidateGTestRootDir(gtest_root) + ValidateOutputDir(output_dir) + + FuseGTestH(gtest_root, output_dir) + FuseGTestAllCc(gtest_root, output_dir) + + +def main(): + argc = len(sys.argv) + if argc == 2: + # fuse_gtest_files.py OUTPUT_DIR + FuseGTest(DEFAULT_GTEST_ROOT_DIR, sys.argv[1]) + elif argc == 3: + # fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR + FuseGTest(sys.argv[1], sys.argv[2]) + else: + print __doc__ + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/gen_gtest_pred_impl.py b/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/gen_gtest_pred_impl.py new file mode 100755 index 0000000..3e7ab04 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/gen_gtest_pred_impl.py @@ -0,0 +1,730 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# 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. + +"""gen_gtest_pred_impl.py v0.1 + +Generates the implementation of Google Test predicate assertions and +accompanying tests. + +Usage: + + gen_gtest_pred_impl.py MAX_ARITY + +where MAX_ARITY is a positive integer. + +The command generates the implementation of up-to MAX_ARITY-ary +predicate assertions, and writes it to file gtest_pred_impl.h in the +directory where the script is. It also generates the accompanying +unit test in file gtest_pred_impl_unittest.cc. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import sys +import time + +# Where this script is. +SCRIPT_DIR = os.path.dirname(sys.argv[0]) + +# Where to store the generated header. +HEADER = os.path.join(SCRIPT_DIR, '../include/gtest/gtest_pred_impl.h') + +# Where to store the generated unit test. +UNIT_TEST = os.path.join(SCRIPT_DIR, '../test/gtest_pred_impl_unittest.cc') + + +def HeaderPreamble(n): + """Returns the preamble for the header file. + + Args: + n: the maximum arity of the predicate macros to be generated. + """ + + # A map that defines the values used in the preamble template. + DEFS = { + 'today' : time.strftime('%m/%d/%Y'), + 'year' : time.strftime('%Y'), + 'command' : '%s %s' % (os.path.basename(sys.argv[0]), n), + 'n' : n + } + + return ( +"""// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +// This file is AUTOMATICALLY GENERATED on %(today)s by command +// '%(command)s'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Makes sure this header is not included before gtest.h. +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most %(n)s. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \\ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\ + if (const ::testing::AssertionResult gtest_ar = (expression)) \\ + ; \\ + else \\ + on_failure(gtest_ar.failure_message()) +""" % DEFS) + + +def Arity(n): + """Returns the English name of the given arity.""" + + if n < 0: + return None + elif n <= 3: + return ['nullary', 'unary', 'binary', 'ternary'][n] + else: + return '%s-ary' % n + + +def Title(word): + """Returns the given word in title case. The difference between + this and string's title() method is that Title('4-ary') is '4-ary' + while '4-ary'.title() is '4-Ary'.""" + + return word[0].upper() + word[1:] + + +def OneTo(n): + """Returns the list [1, 2, 3, ..., n].""" + + return range(1, n + 1) + + +def Iter(n, format, sep=''): + """Given a positive integer n, a format string that contains 0 or + more '%s' format specs, and optionally a separator string, returns + the join of n strings, each formatted with the format string on an + iterator ranged from 1 to n. + + Example: + + Iter(3, 'v%s', sep=', ') returns 'v1, v2, v3'. + """ + + # How many '%s' specs are in format? + spec_count = len(format.split('%s')) - 1 + return sep.join([format % (spec_count * (i,)) for i in OneTo(n)]) + + +def ImplementationForArity(n): + """Returns the implementation of n-ary predicate assertions.""" + + # A map the defines the values used in the implementation template. + DEFS = { + 'n' : str(n), + 'vs' : Iter(n, 'v%s', sep=', '), + 'vts' : Iter(n, '#v%s', sep=', '), + 'arity' : Arity(n), + 'Arity' : Title(Arity(n)) + } + + impl = """ + +// Helper function for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use +// this in your code. +template +AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS + + impl += Iter(n, """, + const char* e%s""") + + impl += """, + Pred pred""" + + impl += Iter(n, """, + const T%s& v%s""") + + impl += """) { + if (pred(%(vs)s)) return AssertionSuccess(); + +""" % DEFS + + impl += ' return AssertionFailure() << pred_text << "("' + + impl += Iter(n, """ + << e%s""", sep=' << ", "') + + impl += ' << ") evaluates to false, where"' + + impl += Iter(n, """ + << "\\n" << e%s << " evaluates to " << v%s""") + + impl += """; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT%(n)s. +// Don't use this in your code. +#define GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, on_failure)\\ + GTEST_ASSERT_(pred_format(%(vts)s, %(vs)s), \\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use +// this in your code. +#define GTEST_PRED%(n)s_(pred, %(vs)s, on_failure)\\ + GTEST_ASSERT_(::testing::AssertPred%(n)sHelper(#pred""" % DEFS + + impl += Iter(n, """, \\ + #v%s""") + + impl += """, \\ + pred""" + + impl += Iter(n, """, \\ + v%s""") + + impl += """), on_failure) + +// %(Arity)s predicate assertion macros. +#define EXPECT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\ + GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED%(n)s(pred, %(vs)s) \\ + GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\ + GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED%(n)s(pred, %(vs)s) \\ + GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_FATAL_FAILURE_) + +""" % DEFS + + return impl + + +def HeaderPostamble(): + """Returns the postamble for the header file.""" + + return """ + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +""" + + +def GenerateFile(path, content): + """Given a file path and a content string, overwrites it with the + given content.""" + + print 'Updating file %s . . .' % path + + f = file(path, 'w+') + print >>f, content, + f.close() + + print 'File %s has been updated.' % path + + +def GenerateHeader(n): + """Given the maximum arity n, updates the header file that implements + the predicate assertions.""" + + GenerateFile(HEADER, + HeaderPreamble(n) + + ''.join([ImplementationForArity(i) for i in OneTo(n)]) + + HeaderPostamble()) + + +def UnitTestPreamble(): + """Returns the preamble for the unit test file.""" + + # A map that defines the values used in the preamble template. + DEFS = { + 'today' : time.strftime('%m/%d/%Y'), + 'year' : time.strftime('%Y'), + 'command' : '%s %s' % (os.path.basename(sys.argv[0]), sys.argv[1]), + } + + return ( +"""// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +// This file is AUTOMATICALLY GENERATED on %(today)s by command +// '%(command)s'. DO NOT EDIT BY HAND! + +// Regression test for gtest_pred_impl.h +// +// This file is generated by a script and quite long. If you intend to +// learn how Google Test works by reading its unit tests, read +// gtest_unittest.cc instead. +// +// This is intended as a regression test for the Google Test predicate +// assertions. We compile it as part of the gtest_unittest target +// only to keep the implementation tidy and compact, as it is quite +// involved to set up the stage for testing Google Test using Google +// Test itself. +// +// Currently, gtest_unittest takes ~11 seconds to run in the testing +// daemon. In the future, if it grows too large and needs much more +// time to finish, we should consider separating this file into a +// stand-alone regression test. + +#include + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +// A user-defined data type. +struct Bool { + explicit Bool(int val) : value(val != 0) {} + + bool operator>(int n) const { return value > Bool(n).value; } + + Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); } + + bool operator==(const Bool& rhs) const { return value == rhs.value; } + + bool value; +}; + +// Enables Bool to be used in assertions. +std::ostream& operator<<(std::ostream& os, const Bool& x) { + return os << (x.value ? "true" : "false"); +} + +""" % DEFS) + + +def TestsForArity(n): + """Returns the tests for n-ary predicate assertions.""" + + # A map that defines the values used in the template for the tests. + DEFS = { + 'n' : n, + 'es' : Iter(n, 'e%s', sep=', '), + 'vs' : Iter(n, 'v%s', sep=', '), + 'vts' : Iter(n, '#v%s', sep=', '), + 'tvs' : Iter(n, 'T%s v%s', sep=', '), + 'int_vs' : Iter(n, 'int v%s', sep=', '), + 'Bool_vs' : Iter(n, 'Bool v%s', sep=', '), + 'types' : Iter(n, 'typename T%s', sep=', '), + 'v_sum' : Iter(n, 'v%s', sep=' + '), + 'arity' : Arity(n), + 'Arity' : Title(Arity(n)), + } + + tests = ( +"""// Sample functions/functors for testing %(arity)s predicate assertions. + +// A %(arity)s predicate function. +template <%(types)s> +bool PredFunction%(n)s(%(tvs)s) { + return %(v_sum)s > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction%(n)sInt(%(int_vs)s) { + return %(v_sum)s > 0; +} +bool PredFunction%(n)sBool(%(Bool_vs)s) { + return %(v_sum)s > 0; +} +""" % DEFS) + + tests += """ +// A %(arity)s predicate functor. +struct PredFunctor%(n)s { + template <%(types)s> + bool operator()(""" % DEFS + + tests += Iter(n, 'const T%s& v%s', sep=""", + """) + + tests += """) { + return %(v_sum)s > 0; + } +}; +""" % DEFS + + tests += """ +// A %(arity)s predicate-formatter function. +template <%(types)s> +testing::AssertionResult PredFormatFunction%(n)s(""" % DEFS + + tests += Iter(n, 'const char* e%s', sep=""", + """) + + tests += Iter(n, """, + const T%s& v%s""") + + tests += """) { + if (PredFunction%(n)s(%(vs)s)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << """ % DEFS + + tests += Iter(n, 'e%s', sep=' << " + " << ') + + tests += """ + << " is expected to be positive, but evaluates to " + << %(v_sum)s << "."; +} +""" % DEFS + + tests += """ +// A %(arity)s predicate-formatter functor. +struct PredFormatFunctor%(n)s { + template <%(types)s> + testing::AssertionResult operator()(""" % DEFS + + tests += Iter(n, 'const char* e%s', sep=""", + """) + + tests += Iter(n, """, + const T%s& v%s""") + + tests += """) const { + return PredFormatFunction%(n)s(%(es)s, %(vs)s); + } +}; +""" % DEFS + + tests += """ +// Tests for {EXPECT|ASSERT}_PRED_FORMAT%(n)s. + +class Predicate%(n)sTest : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false;""" % DEFS + + tests += """ + """ + Iter(n, 'n%s_ = ') + """0; + } +""" + + tests += """ + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once.""" + + tests += ''.join([""" + EXPECT_EQ(1, n%s_) << + "The predicate assertion didn't evaluate argument %s " + "exactly once.";""" % (i, i + 1) for i in OneTo(n)]) + + tests += """ + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; +""" % DEFS + + tests += Iter(n, """ + static int n%s_;""") + + tests += """ +}; + +bool Predicate%(n)sTest::expected_to_finish_; +bool Predicate%(n)sTest::finished_; +""" % DEFS + + tests += Iter(n, """int Predicate%%(n)sTest::n%s_; +""") % DEFS + + tests += """ +typedef Predicate%(n)sTest EXPECT_PRED_FORMAT%(n)sTest; +typedef Predicate%(n)sTest ASSERT_PRED_FORMAT%(n)sTest; +typedef Predicate%(n)sTest EXPECT_PRED%(n)sTest; +typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest; +""" % DEFS + + def GenTest(use_format, use_assert, expect_failure, + use_functor, use_user_type): + """Returns the test for a predicate assertion macro. + + Args: + use_format: true iff the assertion is a *_PRED_FORMAT*. + use_assert: true iff the assertion is a ASSERT_*. + expect_failure: true iff the assertion is expected to fail. + use_functor: true iff the first argument of the assertion is + a functor (as opposed to a function) + use_user_type: true iff the predicate functor/function takes + argument(s) of a user-defined type. + + Example: + + GenTest(1, 0, 0, 1, 0) returns a test that tests the behavior + of a successful EXPECT_PRED_FORMATn() that takes a functor + whose arguments have built-in types.""" + + if use_assert: + assrt = 'ASSERT' # 'assert' is reserved, so we cannot use + # that identifier here. + else: + assrt = 'EXPECT' + + assertion = assrt + '_PRED' + + if use_format: + pred_format = 'PredFormat' + assertion += '_FORMAT' + else: + pred_format = 'Pred' + + assertion += '%(n)s' % DEFS + + if use_functor: + pred_format_type = 'functor' + pred_format += 'Functor%(n)s()' + else: + pred_format_type = 'function' + pred_format += 'Function%(n)s' + if not use_format: + if use_user_type: + pred_format += 'Bool' + else: + pred_format += 'Int' + + test_name = pred_format_type.title() + + if use_user_type: + arg_type = 'user-defined type (Bool)' + test_name += 'OnUserType' + if expect_failure: + arg = 'Bool(n%s_++)' + else: + arg = 'Bool(++n%s_)' + else: + arg_type = 'built-in type (int)' + test_name += 'OnBuiltInType' + if expect_failure: + arg = 'n%s_++' + else: + arg = '++n%s_' + + if expect_failure: + successful_or_failed = 'failed' + expected_or_not = 'expected.' + test_name += 'Failure' + else: + successful_or_failed = 'successful' + expected_or_not = 'UNEXPECTED!' + test_name += 'Success' + + # A map that defines the values used in the test template. + defs = DEFS.copy() + defs.update({ + 'assert' : assrt, + 'assertion' : assertion, + 'test_name' : test_name, + 'pf_type' : pred_format_type, + 'pf' : pred_format, + 'arg_type' : arg_type, + 'arg' : arg, + 'successful' : successful_or_failed, + 'expected' : expected_or_not, + }) + + test = """ +// Tests a %(successful)s %(assertion)s where the +// predicate-formatter is a %(pf_type)s on a %(arg_type)s. +TEST_F(%(assertion)sTest, %(test_name)s) {""" % defs + + indent = (len(assertion) + 3)*' ' + extra_indent = '' + + if expect_failure: + extra_indent = ' ' + if use_assert: + test += """ + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT""" + else: + test += """ + EXPECT_NONFATAL_FAILURE({ // NOLINT""" + + test += '\n' + extra_indent + """ %(assertion)s(%(pf)s""" % defs + + test = test % defs + test += Iter(n, ',\n' + indent + extra_indent + '%(arg)s' % defs) + test += ');\n' + extra_indent + ' finished_ = true;\n' + + if expect_failure: + test += ' }, "");\n' + + test += '}\n' + return test + + # Generates tests for all 2**6 = 64 combinations. + tests += ''.join([GenTest(use_format, use_assert, expect_failure, + use_functor, use_user_type) + for use_format in [0, 1] + for use_assert in [0, 1] + for expect_failure in [0, 1] + for use_functor in [0, 1] + for use_user_type in [0, 1] + ]) + + return tests + + +def UnitTestPostamble(): + """Returns the postamble for the tests.""" + + return '' + + +def GenerateUnitTest(n): + """Returns the tests for up-to n-ary predicate assertions.""" + + GenerateFile(UNIT_TEST, + UnitTestPreamble() + + ''.join([TestsForArity(i) for i in OneTo(n)]) + + UnitTestPostamble()) + + +def _Main(): + """The entry point of the script. Generates the header file and its + unit test.""" + + if len(sys.argv) != 2: + print __doc__ + print 'Author: ' + __author__ + sys.exit(1) + + n = int(sys.argv[1]) + GenerateHeader(n) + GenerateUnitTest(n) + + +if __name__ == '__main__': + _Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/gtest-config.in b/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/gtest-config.in new file mode 100755 index 0000000..9c72638 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/gtest-config.in @@ -0,0 +1,274 @@ +#!/bin/sh + +# These variables are automatically filled in by the configure script. +name="@PACKAGE_TARNAME@" +version="@PACKAGE_VERSION@" + +show_usage() +{ + echo "Usage: gtest-config [OPTIONS...]" +} + +show_help() +{ + show_usage + cat <<\EOF + +The `gtest-config' script provides access to the necessary compile and linking +flags to connect with Google C++ Testing Framework, both in a build prior to +installation, and on the system proper after installation. The installation +overrides may be issued in combination with any other queries, but will only +affect installation queries if called on a built but not installed gtest. The +installation queries may not be issued with any other types of queries, and +only one installation query may be made at a time. The version queries and +compiler flag queries may be combined as desired but not mixed. Different +version queries are always combined with logical "and" semantics, and only the +last of any particular query is used while all previous ones ignored. All +versions must be specified as a sequence of numbers separated by periods. +Compiler flag queries output the union of the sets of flags when combined. + + Examples: + gtest-config --min-version=1.0 || echo "Insufficient Google Test version." + + g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp + g++ $(gtest-config --ldflags --libs) -o foo foo.o + + # When using a built but not installed Google Test: + g++ $(../../my_gtest_build/scripts/gtest-config ...) ... + + # When using an installed Google Test, but with installation overrides: + export GTEST_PREFIX="/opt" + g++ $(gtest-config --libdir="/opt/lib64" ...) ... + + Help: + --usage brief usage information + --help display this help message + + Installation Overrides: + --prefix= overrides the installation prefix + --exec-prefix= overrides the executable installation prefix + --libdir= overrides the library installation prefix + --includedir= overrides the header file installation prefix + + Installation Queries: + --prefix installation prefix + --exec-prefix executable installation prefix + --libdir library installation directory + --includedir header file installation directory + --version the version of the Google Test installation + + Version Queries: + --min-version=VERSION return 0 if the version is at least VERSION + --exact-version=VERSION return 0 if the version is exactly VERSION + --max-version=VERSION return 0 if the version is at most VERSION + + Compilation Flag Queries: + --cppflags compile flags specific to the C-like preprocessors + --cxxflags compile flags appropriate for C++ programs + --ldflags linker flags + --libs libraries for linking + +EOF +} + +# This function bounds our version with a min and a max. It uses some clever +# POSIX-compliant variable expansion to portably do all the work in the shell +# and avoid any dependency on a particular "sed" or "awk" implementation. +# Notable is that it will only ever compare the first 3 components of versions. +# Further components will be cleanly stripped off. All versions must be +# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and +# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should +# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than +# continuing to maintain our own shell version. +check_versions() +{ + major_version=${version%%.*} + minor_version="0" + point_version="0" + if test "${version#*.}" != "${version}"; then + minor_version=${version#*.} + minor_version=${minor_version%%.*} + fi + if test "${version#*.*.}" != "${version}"; then + point_version=${version#*.*.} + point_version=${point_version%%.*} + fi + + min_version="$1" + min_major_version=${min_version%%.*} + min_minor_version="0" + min_point_version="0" + if test "${min_version#*.}" != "${min_version}"; then + min_minor_version=${min_version#*.} + min_minor_version=${min_minor_version%%.*} + fi + if test "${min_version#*.*.}" != "${min_version}"; then + min_point_version=${min_version#*.*.} + min_point_version=${min_point_version%%.*} + fi + + max_version="$2" + max_major_version=${max_version%%.*} + max_minor_version="0" + max_point_version="0" + if test "${max_version#*.}" != "${max_version}"; then + max_minor_version=${max_version#*.} + max_minor_version=${max_minor_version%%.*} + fi + if test "${max_version#*.*.}" != "${max_version}"; then + max_point_version=${max_version#*.*.} + max_point_version=${max_point_version%%.*} + fi + + test $(($major_version)) -lt $(($min_major_version)) && exit 1 + if test $(($major_version)) -eq $(($min_major_version)); then + test $(($minor_version)) -lt $(($min_minor_version)) && exit 1 + if test $(($minor_version)) -eq $(($min_minor_version)); then + test $(($point_version)) -lt $(($min_point_version)) && exit 1 + fi + fi + + test $(($major_version)) -gt $(($max_major_version)) && exit 1 + if test $(($major_version)) -eq $(($max_major_version)); then + test $(($minor_version)) -gt $(($max_minor_version)) && exit 1 + if test $(($minor_version)) -eq $(($max_minor_version)); then + test $(($point_version)) -gt $(($max_point_version)) && exit 1 + fi + fi + + exit 0 +} + +# Show the usage line when no arguments are specified. +if test $# -eq 0; then + show_usage + exit 1 +fi + +while test $# -gt 0; do + case $1 in + --usage) show_usage; exit 0;; + --help) show_help; exit 0;; + + # Installation overrides + --prefix=*) GTEST_PREFIX=${1#--prefix=};; + --exec-prefix=*) GTEST_EXEC_PREFIX=${1#--exec-prefix=};; + --libdir=*) GTEST_LIBDIR=${1#--libdir=};; + --includedir=*) GTEST_INCLUDEDIR=${1#--includedir=};; + + # Installation queries + --prefix|--exec-prefix|--libdir|--includedir|--version) + if test -n "${do_query}"; then + show_usage + exit 1 + fi + do_query=${1#--} + ;; + + # Version checking + --min-version=*) + do_check_versions=yes + min_version=${1#--min-version=} + ;; + --max-version=*) + do_check_versions=yes + max_version=${1#--max-version=} + ;; + --exact-version=*) + do_check_versions=yes + exact_version=${1#--exact-version=} + ;; + + # Compiler flag output + --cppflags) echo_cppflags=yes;; + --cxxflags) echo_cxxflags=yes;; + --ldflags) echo_ldflags=yes;; + --libs) echo_libs=yes;; + + # Everything else is an error + *) show_usage; exit 1;; + esac + shift +done + +# These have defaults filled in by the configure script but can also be +# overridden by environment variables or command line parameters. +prefix="${GTEST_PREFIX:-@prefix@}" +exec_prefix="${GTEST_EXEC_PREFIX:-@exec_prefix@}" +libdir="${GTEST_LIBDIR:-@libdir@}" +includedir="${GTEST_INCLUDEDIR:-@includedir@}" + +# We try and detect if our binary is not located at its installed location. If +# it's not, we provide variables pointing to the source and build tree rather +# than to the install tree. This allows building against a just-built gtest +# rather than an installed gtest. +bindir="@bindir@" +this_relative_bindir=`dirname $0` +this_bindir=`cd ${this_relative_bindir}; pwd -P` +if test "${this_bindir}" = "${this_bindir%${bindir}}"; then + # The path to the script doesn't end in the bindir sequence from Autoconf, + # assume that we are in a build tree. + build_dir=`dirname ${this_bindir}` + src_dir=`cd ${this_bindir}/@top_srcdir@; pwd -P` + + # TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we + # should work to remove it, and/or remove libtool altogether, replacing it + # with direct references to the library and a link path. + gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@" + gtest_ldflags="" + + # We provide hooks to include from either the source or build dir, where the + # build dir is always preferred. This will potentially allow us to write + # build rules for generated headers and have them automatically be preferred + # over provided versions. + gtest_cppflags="-I${build_dir}/include -I${src_dir}/include" + gtest_cxxflags="@PTHREAD_CFLAGS@" +else + # We're using an installed gtest, although it may be staged under some + # prefix. Assume (as our own libraries do) that we can resolve the prefix, + # and are present in the dynamic link paths. + gtest_ldflags="-L${libdir}" + gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@" + gtest_cppflags="-I${includedir}" + gtest_cxxflags="@PTHREAD_CFLAGS@" +fi + +# Do an installation query if requested. +if test -n "$do_query"; then + case $do_query in + prefix) echo $prefix; exit 0;; + exec-prefix) echo $exec_prefix; exit 0;; + libdir) echo $libdir; exit 0;; + includedir) echo $includedir; exit 0;; + version) echo $version; exit 0;; + *) show_usage; exit 1;; + esac +fi + +# Do a version check if requested. +if test "$do_check_versions" = "yes"; then + # Make sure we didn't receive a bad combination of parameters. + test "$echo_cppflags" = "yes" && show_usage && exit 1 + test "$echo_cxxflags" = "yes" && show_usage && exit 1 + test "$echo_ldflags" = "yes" && show_usage && exit 1 + test "$echo_libs" = "yes" && show_usage && exit 1 + + if test "$exact_version" != ""; then + check_versions $exact_version $exact_version + # unreachable + else + check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999} + # unreachable + fi +fi + +# Do the output in the correct order so that these can be used in-line of +# a compiler invocation. +output="" +test "$echo_cppflags" = "yes" && output="$output $gtest_cppflags" +test "$echo_cxxflags" = "yes" && output="$output $gtest_cxxflags" +test "$echo_ldflags" = "yes" && output="$output $gtest_ldflags" +test "$echo_libs" = "yes" && output="$output $gtest_libs" +echo $output + +exit 0 diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/pump.py b/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/pump.py new file mode 100755 index 0000000..5efb653 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/pump.py @@ -0,0 +1,855 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""pump v0.2.0 - Pretty Useful for Meta Programming. + +A tool for preprocessor meta programming. Useful for generating +repetitive boilerplate code. Especially useful for writing C++ +classes, functions, macros, and templates that need to work with +various number of arguments. + +USAGE: + pump.py SOURCE_FILE + +EXAMPLES: + pump.py foo.cc.pump + Converts foo.cc.pump to foo.cc. + +GRAMMAR: + CODE ::= ATOMIC_CODE* + ATOMIC_CODE ::= $var ID = EXPRESSION + | $var ID = [[ CODE ]] + | $range ID EXPRESSION..EXPRESSION + | $for ID SEPARATOR [[ CODE ]] + | $($) + | $ID + | $(EXPRESSION) + | $if EXPRESSION [[ CODE ]] ELSE_BRANCH + | [[ CODE ]] + | RAW_CODE + SEPARATOR ::= RAW_CODE | EMPTY + ELSE_BRANCH ::= $else [[ CODE ]] + | $elif EXPRESSION [[ CODE ]] ELSE_BRANCH + | EMPTY + EXPRESSION has Python syntax. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sys + + +TOKEN_TABLE = [ + (re.compile(r'\$var\s+'), '$var'), + (re.compile(r'\$elif\s+'), '$elif'), + (re.compile(r'\$else\s+'), '$else'), + (re.compile(r'\$for\s+'), '$for'), + (re.compile(r'\$if\s+'), '$if'), + (re.compile(r'\$range\s+'), '$range'), + (re.compile(r'\$[_A-Za-z]\w*'), '$id'), + (re.compile(r'\$\(\$\)'), '$($)'), + (re.compile(r'\$'), '$'), + (re.compile(r'\[\[\n?'), '[['), + (re.compile(r'\]\]\n?'), ']]'), + ] + + +class Cursor: + """Represents a position (line and column) in a text file.""" + + def __init__(self, line=-1, column=-1): + self.line = line + self.column = column + + def __eq__(self, rhs): + return self.line == rhs.line and self.column == rhs.column + + def __ne__(self, rhs): + return not self == rhs + + def __lt__(self, rhs): + return self.line < rhs.line or ( + self.line == rhs.line and self.column < rhs.column) + + def __le__(self, rhs): + return self < rhs or self == rhs + + def __gt__(self, rhs): + return rhs < self + + def __ge__(self, rhs): + return rhs <= self + + def __str__(self): + if self == Eof(): + return 'EOF' + else: + return '%s(%s)' % (self.line + 1, self.column) + + def __add__(self, offset): + return Cursor(self.line, self.column + offset) + + def __sub__(self, offset): + return Cursor(self.line, self.column - offset) + + def Clone(self): + """Returns a copy of self.""" + + return Cursor(self.line, self.column) + + +# Special cursor to indicate the end-of-file. +def Eof(): + """Returns the special cursor to denote the end-of-file.""" + return Cursor(-1, -1) + + +class Token: + """Represents a token in a Pump source file.""" + + def __init__(self, start=None, end=None, value=None, token_type=None): + if start is None: + self.start = Eof() + else: + self.start = start + if end is None: + self.end = Eof() + else: + self.end = end + self.value = value + self.token_type = token_type + + def __str__(self): + return 'Token @%s: \'%s\' type=%s' % ( + self.start, self.value, self.token_type) + + def Clone(self): + """Returns a copy of self.""" + + return Token(self.start.Clone(), self.end.Clone(), self.value, + self.token_type) + + +def StartsWith(lines, pos, string): + """Returns True iff the given position in lines starts with 'string'.""" + + return lines[pos.line][pos.column:].startswith(string) + + +def FindFirstInLine(line, token_table): + best_match_start = -1 + for (regex, token_type) in token_table: + m = regex.search(line) + if m: + # We found regex in lines + if best_match_start < 0 or m.start() < best_match_start: + best_match_start = m.start() + best_match_length = m.end() - m.start() + best_match_token_type = token_type + + if best_match_start < 0: + return None + + return (best_match_start, best_match_length, best_match_token_type) + + +def FindFirst(lines, token_table, cursor): + """Finds the first occurrence of any string in strings in lines.""" + + start = cursor.Clone() + cur_line_number = cursor.line + for line in lines[start.line:]: + if cur_line_number == start.line: + line = line[start.column:] + m = FindFirstInLine(line, token_table) + if m: + # We found a regex in line. + (start_column, length, token_type) = m + if cur_line_number == start.line: + start_column += start.column + found_start = Cursor(cur_line_number, start_column) + found_end = found_start + length + return MakeToken(lines, found_start, found_end, token_type) + cur_line_number += 1 + # We failed to find str in lines + return None + + +def SubString(lines, start, end): + """Returns a substring in lines.""" + + if end == Eof(): + end = Cursor(len(lines) - 1, len(lines[-1])) + + if start >= end: + return '' + + if start.line == end.line: + return lines[start.line][start.column:end.column] + + result_lines = ([lines[start.line][start.column:]] + + lines[start.line + 1:end.line] + + [lines[end.line][:end.column]]) + return ''.join(result_lines) + + +def StripMetaComments(str): + """Strip meta comments from each line in the given string.""" + + # First, completely remove lines containing nothing but a meta + # comment, including the trailing \n. + str = re.sub(r'^\s*\$\$.*\n', '', str) + + # Then, remove meta comments from contentful lines. + return re.sub(r'\s*\$\$.*', '', str) + + +def MakeToken(lines, start, end, token_type): + """Creates a new instance of Token.""" + + return Token(start, end, SubString(lines, start, end), token_type) + + +def ParseToken(lines, pos, regex, token_type): + line = lines[pos.line][pos.column:] + m = regex.search(line) + if m and not m.start(): + return MakeToken(lines, pos, pos + m.end(), token_type) + else: + print 'ERROR: %s expected at %s.' % (token_type, pos) + sys.exit(1) + + +ID_REGEX = re.compile(r'[_A-Za-z]\w*') +EQ_REGEX = re.compile(r'=') +REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)') +OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*') +WHITE_SPACE_REGEX = re.compile(r'\s') +DOT_DOT_REGEX = re.compile(r'\.\.') + + +def Skip(lines, pos, regex): + line = lines[pos.line][pos.column:] + m = re.search(regex, line) + if m and not m.start(): + return pos + m.end() + else: + return pos + + +def SkipUntil(lines, pos, regex, token_type): + line = lines[pos.line][pos.column:] + m = re.search(regex, line) + if m: + return pos + m.start() + else: + print ('ERROR: %s expected on line %s after column %s.' % + (token_type, pos.line + 1, pos.column)) + sys.exit(1) + + +def ParseExpTokenInParens(lines, pos): + def ParseInParens(pos): + pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX) + pos = Skip(lines, pos, r'\(') + pos = Parse(pos) + pos = Skip(lines, pos, r'\)') + return pos + + def Parse(pos): + pos = SkipUntil(lines, pos, r'\(|\)', ')') + if SubString(lines, pos, pos + 1) == '(': + pos = Parse(pos + 1) + pos = Skip(lines, pos, r'\)') + return Parse(pos) + else: + return pos + + start = pos.Clone() + pos = ParseInParens(pos) + return MakeToken(lines, start, pos, 'exp') + + +def RStripNewLineFromToken(token): + if token.value.endswith('\n'): + return Token(token.start, token.end, token.value[:-1], token.token_type) + else: + return token + + +def TokenizeLines(lines, pos): + while True: + found = FindFirst(lines, TOKEN_TABLE, pos) + if not found: + yield MakeToken(lines, pos, Eof(), 'code') + return + + if found.start == pos: + prev_token = None + prev_token_rstripped = None + else: + prev_token = MakeToken(lines, pos, found.start, 'code') + prev_token_rstripped = RStripNewLineFromToken(prev_token) + + if found.token_type == '$var': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) + + eq_token = ParseToken(lines, pos, EQ_REGEX, '=') + yield eq_token + pos = Skip(lines, eq_token.end, r'\s*') + + if SubString(lines, pos, pos + 2) != '[[': + exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp') + yield exp_token + pos = Cursor(exp_token.end.line + 1, 0) + elif found.token_type == '$for': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX) + elif found.token_type == '$range': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) + + dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..') + yield MakeToken(lines, pos, dots_pos, 'exp') + yield MakeToken(lines, dots_pos, dots_pos + 2, '..') + pos = dots_pos + 2 + new_pos = Cursor(pos.line + 1, 0) + yield MakeToken(lines, pos, new_pos, 'exp') + pos = new_pos + elif found.token_type == '$': + if prev_token: + yield prev_token + yield found + exp_token = ParseExpTokenInParens(lines, found.end) + yield exp_token + pos = exp_token.end + elif (found.token_type == ']]' or found.token_type == '$if' or + found.token_type == '$elif' or found.token_type == '$else'): + if prev_token_rstripped: + yield prev_token_rstripped + yield found + pos = found.end + else: + if prev_token: + yield prev_token + yield found + pos = found.end + + +def Tokenize(s): + """A generator that yields the tokens in the given string.""" + if s != '': + lines = s.splitlines(True) + for token in TokenizeLines(lines, Cursor(0, 0)): + yield token + + +class CodeNode: + def __init__(self, atomic_code_list=None): + self.atomic_code = atomic_code_list + + +class VarNode: + def __init__(self, identifier=None, atomic_code=None): + self.identifier = identifier + self.atomic_code = atomic_code + + +class RangeNode: + def __init__(self, identifier=None, exp1=None, exp2=None): + self.identifier = identifier + self.exp1 = exp1 + self.exp2 = exp2 + + +class ForNode: + def __init__(self, identifier=None, sep=None, code=None): + self.identifier = identifier + self.sep = sep + self.code = code + + +class ElseNode: + def __init__(self, else_branch=None): + self.else_branch = else_branch + + +class IfNode: + def __init__(self, exp=None, then_branch=None, else_branch=None): + self.exp = exp + self.then_branch = then_branch + self.else_branch = else_branch + + +class RawCodeNode: + def __init__(self, token=None): + self.raw_code = token + + +class LiteralDollarNode: + def __init__(self, token): + self.token = token + + +class ExpNode: + def __init__(self, token, python_exp): + self.token = token + self.python_exp = python_exp + + +def PopFront(a_list): + head = a_list[0] + a_list[:1] = [] + return head + + +def PushFront(a_list, elem): + a_list[:0] = [elem] + + +def PopToken(a_list, token_type=None): + token = PopFront(a_list) + if token_type is not None and token.token_type != token_type: + print 'ERROR: %s expected at %s' % (token_type, token.start) + print 'ERROR: %s found instead' % (token,) + sys.exit(1) + + return token + + +def PeekToken(a_list): + if not a_list: + return None + + return a_list[0] + + +def ParseExpNode(token): + python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value) + return ExpNode(token, python_exp) + + +def ParseElseNode(tokens): + def Pop(token_type=None): + return PopToken(tokens, token_type) + + next = PeekToken(tokens) + if not next: + return None + if next.token_type == '$else': + Pop('$else') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return code_node + elif next.token_type == '$elif': + Pop('$elif') + exp = Pop('code') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + inner_else_node = ParseElseNode(tokens) + return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)]) + elif not next.value.strip(): + Pop('code') + return ParseElseNode(tokens) + else: + return None + + +def ParseAtomicCodeNode(tokens): + def Pop(token_type=None): + return PopToken(tokens, token_type) + + head = PopFront(tokens) + t = head.token_type + if t == 'code': + return RawCodeNode(head) + elif t == '$var': + id_token = Pop('id') + Pop('=') + next = PeekToken(tokens) + if next.token_type == 'exp': + exp_token = Pop() + return VarNode(id_token, ParseExpNode(exp_token)) + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return VarNode(id_token, code_node) + elif t == '$for': + id_token = Pop('id') + next_token = PeekToken(tokens) + if next_token.token_type == 'code': + sep_token = next_token + Pop('code') + else: + sep_token = None + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return ForNode(id_token, sep_token, code_node) + elif t == '$if': + exp_token = Pop('code') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + else_node = ParseElseNode(tokens) + return IfNode(ParseExpNode(exp_token), code_node, else_node) + elif t == '$range': + id_token = Pop('id') + exp1_token = Pop('exp') + Pop('..') + exp2_token = Pop('exp') + return RangeNode(id_token, ParseExpNode(exp1_token), + ParseExpNode(exp2_token)) + elif t == '$id': + return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id')) + elif t == '$($)': + return LiteralDollarNode(head) + elif t == '$': + exp_token = Pop('exp') + return ParseExpNode(exp_token) + elif t == '[[': + code_node = ParseCodeNode(tokens) + Pop(']]') + return code_node + else: + PushFront(tokens, head) + return None + + +def ParseCodeNode(tokens): + atomic_code_list = [] + while True: + if not tokens: + break + atomic_code_node = ParseAtomicCodeNode(tokens) + if atomic_code_node: + atomic_code_list.append(atomic_code_node) + else: + break + return CodeNode(atomic_code_list) + + +def ParseToAST(pump_src_text): + """Convert the given Pump source text into an AST.""" + tokens = list(Tokenize(pump_src_text)) + code_node = ParseCodeNode(tokens) + return code_node + + +class Env: + def __init__(self): + self.variables = [] + self.ranges = [] + + def Clone(self): + clone = Env() + clone.variables = self.variables[:] + clone.ranges = self.ranges[:] + return clone + + def PushVariable(self, var, value): + # If value looks like an int, store it as an int. + try: + int_value = int(value) + if ('%s' % int_value) == value: + value = int_value + except Exception: + pass + self.variables[:0] = [(var, value)] + + def PopVariable(self): + self.variables[:1] = [] + + def PushRange(self, var, lower, upper): + self.ranges[:0] = [(var, lower, upper)] + + def PopRange(self): + self.ranges[:1] = [] + + def GetValue(self, identifier): + for (var, value) in self.variables: + if identifier == var: + return value + + print 'ERROR: meta variable %s is undefined.' % (identifier,) + sys.exit(1) + + def EvalExp(self, exp): + try: + result = eval(exp.python_exp) + except Exception, e: + print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e) + print ('ERROR: failed to evaluate meta expression %s at %s' % + (exp.python_exp, exp.token.start)) + sys.exit(1) + return result + + def GetRange(self, identifier): + for (var, lower, upper) in self.ranges: + if identifier == var: + return (lower, upper) + + print 'ERROR: range %s is undefined.' % (identifier,) + sys.exit(1) + + +class Output: + def __init__(self): + self.string = '' + + def GetLastLine(self): + index = self.string.rfind('\n') + if index < 0: + return '' + + return self.string[index + 1:] + + def Append(self, s): + self.string += s + + +def RunAtomicCode(env, node, output): + if isinstance(node, VarNode): + identifier = node.identifier.value.strip() + result = Output() + RunAtomicCode(env.Clone(), node.atomic_code, result) + value = result.string + env.PushVariable(identifier, value) + elif isinstance(node, RangeNode): + identifier = node.identifier.value.strip() + lower = int(env.EvalExp(node.exp1)) + upper = int(env.EvalExp(node.exp2)) + env.PushRange(identifier, lower, upper) + elif isinstance(node, ForNode): + identifier = node.identifier.value.strip() + if node.sep is None: + sep = '' + else: + sep = node.sep.value + (lower, upper) = env.GetRange(identifier) + for i in range(lower, upper + 1): + new_env = env.Clone() + new_env.PushVariable(identifier, i) + RunCode(new_env, node.code, output) + if i != upper: + output.Append(sep) + elif isinstance(node, RawCodeNode): + output.Append(node.raw_code.value) + elif isinstance(node, IfNode): + cond = env.EvalExp(node.exp) + if cond: + RunCode(env.Clone(), node.then_branch, output) + elif node.else_branch is not None: + RunCode(env.Clone(), node.else_branch, output) + elif isinstance(node, ExpNode): + value = env.EvalExp(node) + output.Append('%s' % (value,)) + elif isinstance(node, LiteralDollarNode): + output.Append('$') + elif isinstance(node, CodeNode): + RunCode(env.Clone(), node, output) + else: + print 'BAD' + print node + sys.exit(1) + + +def RunCode(env, code_node, output): + for atomic_code in code_node.atomic_code: + RunAtomicCode(env, atomic_code, output) + + +def IsSingleLineComment(cur_line): + return '//' in cur_line + + +def IsInPreprocessorDirective(prev_lines, cur_line): + if cur_line.lstrip().startswith('#'): + return True + return prev_lines and prev_lines[-1].endswith('\\') + + +def WrapComment(line, output): + loc = line.find('//') + before_comment = line[:loc].rstrip() + if before_comment == '': + indent = loc + else: + output.append(before_comment) + indent = len(before_comment) - len(before_comment.lstrip()) + prefix = indent*' ' + '// ' + max_len = 80 - len(prefix) + comment = line[loc + 2:].strip() + segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != ''] + cur_line = '' + for seg in segs: + if len((cur_line + seg).rstrip()) < max_len: + cur_line += seg + else: + if cur_line.strip() != '': + output.append(prefix + cur_line.rstrip()) + cur_line = seg.lstrip() + if cur_line.strip() != '': + output.append(prefix + cur_line.strip()) + + +def WrapCode(line, line_concat, output): + indent = len(line) - len(line.lstrip()) + prefix = indent*' ' # Prefix of the current line + max_len = 80 - indent - len(line_concat) # Maximum length of the current line + new_prefix = prefix + 4*' ' # Prefix of a continuation line + new_max_len = max_len - 4 # Maximum length of a continuation line + # Prefers to wrap a line after a ',' or ';'. + segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != ''] + cur_line = '' # The current line without leading spaces. + for seg in segs: + # If the line is still too long, wrap at a space. + while cur_line == '' and len(seg.strip()) > max_len: + seg = seg.lstrip() + split_at = seg.rfind(' ', 0, max_len) + output.append(prefix + seg[:split_at].strip() + line_concat) + seg = seg[split_at + 1:] + prefix = new_prefix + max_len = new_max_len + + if len((cur_line + seg).rstrip()) < max_len: + cur_line = (cur_line + seg).lstrip() + else: + output.append(prefix + cur_line.rstrip() + line_concat) + prefix = new_prefix + max_len = new_max_len + cur_line = seg.lstrip() + if cur_line.strip() != '': + output.append(prefix + cur_line.strip()) + + +def WrapPreprocessorDirective(line, output): + WrapCode(line, ' \\', output) + + +def WrapPlainCode(line, output): + WrapCode(line, '', output) + + +def IsMultiLineIWYUPragma(line): + return re.search(r'/\* IWYU pragma: ', line) + + +def IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or + re.match(r'^#include\s', line) or + # Don't break IWYU pragmas, either; that causes iwyu.py problems. + re.search(r'// IWYU pragma: ', line)) + + +def WrapLongLine(line, output): + line = line.rstrip() + if len(line) <= 80: + output.append(line) + elif IsSingleLineComment(line): + if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + # The style guide made an exception to allow long header guard lines, + # includes and IWYU pragmas. + output.append(line) + else: + WrapComment(line, output) + elif IsInPreprocessorDirective(output, line): + if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + # The style guide made an exception to allow long header guard lines, + # includes and IWYU pragmas. + output.append(line) + else: + WrapPreprocessorDirective(line, output) + elif IsMultiLineIWYUPragma(line): + output.append(line) + else: + WrapPlainCode(line, output) + + +def BeautifyCode(string): + lines = string.splitlines() + output = [] + for line in lines: + WrapLongLine(line, output) + output2 = [line.rstrip() for line in output] + return '\n'.join(output2) + '\n' + + +def ConvertFromPumpSource(src_text): + """Return the text generated from the given Pump source text.""" + ast = ParseToAST(StripMetaComments(src_text)) + output = Output() + RunCode(Env(), ast, output) + return BeautifyCode(output.string) + + +def main(argv): + if len(argv) == 1: + print __doc__ + sys.exit(1) + + file_path = argv[-1] + output_str = ConvertFromPumpSource(file(file_path, 'r').read()) + if file_path.endswith('.pump'): + output_file_path = file_path[:-5] + else: + output_file_path = '-' + if output_file_path == '-': + print output_str, + else: + output_file = file(output_file_path, 'w') + output_file.write('// This file was GENERATED by command:\n') + output_file.write('// %s %s\n' % + (os.path.basename(__file__), os.path.basename(file_path))) + output_file.write('// DO NOT EDIT BY HAND!!!\n\n') + output_file.write(output_str) + output_file.close() + + +if __name__ == '__main__': + main(sys.argv) diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/test/Makefile b/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/test/Makefile new file mode 100644 index 0000000..cdff584 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/scripts/test/Makefile @@ -0,0 +1,59 @@ +# A Makefile for fusing Google Test and building a sample test against it. +# +# SYNOPSIS: +# +# make [all] - makes everything. +# make TARGET - makes the given target. +# make check - makes everything and runs the built sample test. +# make clean - removes all files generated by make. + +# Points to the root of fused Google Test, relative to where this file is. +FUSED_GTEST_DIR = output + +# Paths to the fused gtest files. +FUSED_GTEST_H = $(FUSED_GTEST_DIR)/gtest/gtest.h +FUSED_GTEST_ALL_CC = $(FUSED_GTEST_DIR)/gtest/gtest-all.cc + +# Where to find the sample test. +SAMPLE_DIR = ../../samples + +# Where to find gtest_main.cc. +GTEST_MAIN_CC = ../../src/gtest_main.cc + +# Flags passed to the preprocessor. +# We have no idea here whether pthreads is available in the system, so +# disable its use. +CPPFLAGS += -I$(FUSED_GTEST_DIR) -DGTEST_HAS_PTHREAD=0 + +# Flags passed to the C++ compiler. +CXXFLAGS += -g + +all : sample1_unittest + +check : all + ./sample1_unittest + +clean : + rm -rf $(FUSED_GTEST_DIR) sample1_unittest *.o + +$(FUSED_GTEST_H) : + ../fuse_gtest_files.py $(FUSED_GTEST_DIR) + +$(FUSED_GTEST_ALL_CC) : + ../fuse_gtest_files.py $(FUSED_GTEST_DIR) + +gtest-all.o : $(FUSED_GTEST_H) $(FUSED_GTEST_ALL_CC) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FUSED_GTEST_DIR)/gtest/gtest-all.cc + +gtest_main.o : $(FUSED_GTEST_H) $(GTEST_MAIN_CC) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_MAIN_CC) + +sample1.o : $(SAMPLE_DIR)/sample1.cc $(SAMPLE_DIR)/sample1.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1.cc + +sample1_unittest.o : $(SAMPLE_DIR)/sample1_unittest.cc \ + $(SAMPLE_DIR)/sample1.h $(FUSED_GTEST_H) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1_unittest.cc + +sample1_unittest : sample1.o sample1_unittest.o gtest-all.o gtest_main.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-all.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-all.cc new file mode 100644 index 0000000..0a9cee5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-all.cc @@ -0,0 +1,48 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include "gtest/gtest.h" + +// The following lines pull in the real gtest *.cc files. +#include "src/gtest.cc" +#include "src/gtest-death-test.cc" +#include "src/gtest-filepath.cc" +#include "src/gtest-port.cc" +#include "src/gtest-printers.cc" +#include "src/gtest-test-part.cc" +#include "src/gtest-typed-test.cc" diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-death-test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-death-test.cc new file mode 100644 index 0000000..8b52431 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-death-test.cc @@ -0,0 +1,1341 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) +// +// This file implements death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_MAC +# include +# endif // GTEST_OS_MAC + +# include +# include +# include + +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + +# include + +# if GTEST_OS_WINDOWS +# include +# else +# include +# include +# endif // GTEST_OS_WINDOWS + +# if GTEST_OS_QNX +# include +# endif // GTEST_OS_QNX + +#endif // GTEST_HAS_DEATH_TEST + +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-string.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +// Constants. + +// The default death test style. +static const char kDefaultDeathTestStyle[] = "fast"; + +GTEST_DEFINE_string_( + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); + +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + +namespace internal { +GTEST_DEFINE_string_( + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "the '|' characters. This flag is specified if and only if the current " + "process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); +} // namespace internal + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Valid only for fast death tests. Indicates the code is running in the +// child process of a fast style death test. +static bool g_in_fast_death_test_child = false; + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +bool InDeathTestChild() { +# if GTEST_OS_WINDOWS + + // On Windows, death tests are thread-safe regardless of the value of the + // death_test_style flag. + return !GTEST_FLAG(internal_run_death_test).empty(); + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") + return !GTEST_FLAG(internal_run_death_test).empty(); + else + return g_in_fast_death_test_child; +#endif +} + +} // namespace internal + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +# if GTEST_OS_WINDOWS + + return exit_status == exit_code_; + +# else + + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; + +# endif // GTEST_OS_WINDOWS +} + +# if !GTEST_OS_WINDOWS +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} +# endif // !GTEST_OS_WINDOWS + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static std::string ExitSummary(int exit_code) { + Message m; + +# if GTEST_OS_WINDOWS + + m << "Exited with exit status " << exit_code; + +# else + + if (WIFEXITED(exit_code)) { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } else if (WIFSIGNALED(exit_code)) { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +# ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) { + m << " (core dumped)"; + } +# endif +# endif // GTEST_OS_WINDOWS + + return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { + return !ExitedWithCode(0)(exit_status); +} + +# if !GTEST_OS_WINDOWS +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement. It is the responsibility of the +// caller not to pass a thread_count of 1. +static std::string DeathTestThreadWarning(size_t thread_count) { + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) + msg << "couldn't detect the number of threads."; + else + msg << "detected " << thread_count << " threads."; + return msg.GetString(); +} +# endif // !GTEST_OS_WINDOWS + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestThrew = 'T'; +static const char kDeathTestInternalError = 'I'; + +// An enumeration describing all of the possible ways that a death test can +// conclude. DIED means that the process died while executing the test +// code; LIVED means that process lived beyond the end of the test code; +// RETURNED means that the test statement attempted to execute a return +// statement, which is not allowed; THREW means that the test statement +// returned control by throwing an exception. IN_PROGRESS means the test +// has not yet concluded. +// TODO(vladl@google.com): Unify names and possibly values for +// AbortReason, DeathTestOutcome, and flag characters above. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the error +// message is propagated back to the parent process. Otherwise, the +// message is simply printed to stderr. In either case, the program +// then exits with status 1. +void DeathTestAbort(const std::string& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != NULL) { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } else { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + posix::Abort(); + } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +# define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again. The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR. If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s != -1", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +std::string GetLastErrnoDescription() { + return errno == 0 ? "" : posix::StrError(errno); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} + +// Death test constructor. Increments the running death test count +// for the current test. +DeathTest::DeathTest() { + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == NULL) { + DeathTestAbort("Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) { + return GetUnitTestImpl()->death_test_factory()->Create( + statement, regex, file, line, test); +} + +const char* DeathTest::LastMessage() { + return last_death_test_message_.c_str(); +} + +void DeathTest::set_last_death_test_message(const std::string& message) { + last_death_test_message_ = message; +} + +std::string DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } + + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; +}; + +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; + + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestThrew: + set_outcome(THREW); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast(flag) << ")"; + } + } else { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : + reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; + + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + // We are leaking the descriptor here because on some platforms (i.e., + // when built as Windows DLL), destructors of global objects will still + // run after calling _exit(). On such systems, write_fd_ will be + // indirectly closed from the destructor of UnitTestImpl, causing double + // close if it is also closed here. On debug configurations, double close + // may assert. As there are no in-process buffers to flush here, we are + // relying on the OS to close the descriptor after the process terminates + // when the destructors are not run. + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// Returns an indented copy of stderr output for a death test. +// This makes distinguishing death test output lines from regular log lines +// much easier. +static ::std::string FormatDeathTestOutput(const ::std::string& output) { + ::std::string ret; + for (size_t at = 0; ; ) { + const size_t line_end = output.find('\n', at); + ret += "[ DEATH ] "; + if (line_end == ::std::string::npos) { + ret += output.substr(at); + break; + } + ret += output.substr(at, line_end + 1 - at); + at = line_end + 1; + } + return ret; +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +// outcome: An enumeration describing how the death test +// concluded: DIED, LIVED, THREW, or RETURNED. The death test +// fails in the latter three cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to +// the test's captured standard error output; the death test +// fails if it does not match. +// +// Argument: +// status_ok: true if exit_status is acceptable in the context of +// this particular death test, which fails if it is false +// +// Returns true iff all of the above conditions are met. Otherwise, the +// first failing condition, in the order given above, is the one that is +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) + return false; + + const std::string error_message = GetCapturedStderr(); + + bool success = false; + Message buffer; + + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case THREW: + buffer << " Result: threw an exception.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case DIED: + if (status_ok) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { + success = true; + } else { + buffer << " Result: died but not with expected error.\n" + << " Expected: " << regex()->pattern() << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + } else { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } + + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; +} + +# if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* a_statement, + const RE* a_regex, + const char* file, + int line) + : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status_code; + GTEST_DEATH_TEST_CHECK_( + ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); + child_handle_.Reset(); + set_status(static_cast(status_code)); + return status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + + "=" + file_ + "|" + String::Format("%d|%d|%u|%Iu|%Iu", line_, + death_test_index, + static_cast(::GetCurrentProcessId()), + // size_t has the same with as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + reinterpret_cast(write_handle), + reinterpret_cast(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + std::string command_line = + std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + + internal_flag + "\""; + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +# else // We are not on Windows. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, const RE* regex); + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } + virtual TestRole AssumeRole(); +}; + +// The AssumeRole process for a fork-and-run death test. It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); + + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + g_in_fast_death_test_child = true; + return EXECUTE_TEST; + } else { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: + ExecDeathTest(const char* a_statement, const RE* a_regex, + const char* file, int line) : + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } + virtual TestRole AssumeRole(); + private: + static ::std::vector + GetArgvsForDeathTestChildProcess() { + ::std::vector args = GetInjectableArgvs(); + return args; + } + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { + args_.push_back(NULL); + } + + ~Arguments() { + for (std::vector::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template + void AddArguments(const ::std::vector& arguments) { + for (typename ::std::vector::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + + private: + std::vector args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe +}; + +# if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +# else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +# endif // GTEST_OS_MAC + +# if !GTEST_OS_QNX +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { + ExecDeathTestArgs* const args = static_cast(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + + original_dir + " failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; +} +# endif // !GTEST_OS_QNX + +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +// +// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining +// StackLowerThanAddress into StackGrowsDown, which then doesn't give +// correct answer. +void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; +void StackLowerThanAddress(const void* ptr, bool* result) { + int dummy; + *result = (&dummy < ptr); +} + +bool StackGrowsDown() { + int dummy; + bool result; + StackLowerThanAddress(&dummy, &result); + return result; +} + +// Spawns a child process with the same executable as the current process in +// a thread-safe manner and instructs it to run the death test. The +// implementation uses fork(2) + exec. On systems where clone(2) is +// available, it is used instead, being slightly more thread-safe. On QNX, +// fork supports only single-threaded environments, so this function uses +// spawn(2) there instead. The function dies with an error message if +// anything goes wrong. +static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { + ExecDeathTestArgs args = { argv, close_fd }; + pid_t child_pid = -1; + +# if GTEST_OS_QNX + // Obtains the current directory and sets it to be closed in the child + // process. + const int cwd_fd = open(".", O_RDONLY); + GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + int fd_flags; + // Set close_fd to be closed after spawn. + GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, + fd_flags | FD_CLOEXEC)); + struct inheritance inherit = {0}; + // spawn is a system call. + child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); + // Restores the current working directory. + GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); + +# else // GTEST_OS_QNX +# if GTEST_OS_LINUX + // When a SIGPROF signal is received while fork() or clone() are executing, + // the process may hang. To avoid this, we ignore SIGPROF here and re-enable + // it after the call to fork()/clone() is complete. + struct sigaction saved_sigprof_action; + struct sigaction ignore_sigprof_action; + memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); + sigemptyset(&ignore_sigprof_action.sa_mask); + ignore_sigprof_action.sa_handler = SIG_IGN; + GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( + SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); +# endif // GTEST_OS_LINUX + +# if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + + // Maximum stack alignment in bytes: For a downward-growing stack, this + // amount is subtracted from size of the stack space to get an address + // that is within the stack space and is aligned on all systems we care + // about. As far as I know there is no ABI with stack alignment greater + // than 64. We assume stack and stack_size already have alignment of + // kMaxStackAlignment. + const size_t kMaxStackAlignment = 64; + void* const stack_top = + static_cast(stack) + + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); + GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && + reinterpret_cast(stack_top) % kMaxStackAlignment == 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +# else + const bool use_fork = true; +# endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } +# endif // GTEST_OS_QNX +# if GTEST_OS_LINUX + GTEST_DEATH_TEST_CHECK_SYSCALL_( + sigaction(SIGPROF, &saved_sigprof_action, NULL)); +# endif // GTEST_OS_LINUX + + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test. It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + + const std::string filter_flag = + String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), info->name()); + const std::string internal_flag = + String::Format("--%s%s=%s|%d|%d|%d", + GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag, + file_, line_, death_test_index, pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvsForDeathTestChildProcess()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); + + const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; +} + +# endif // !GTEST_OS_WINDOWS + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address. If the test should be +// skipped, sets that pointer to NULL. Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, + const char* file, int line, + DeathTest** test) { + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); + + if (flag != NULL) { + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message(String::Format( + "Death test count (%d) somehow exceeded expected maximum (%d)", + death_test_index, flag->index())); + return false; + } + + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { + *test = NULL; + return true; + } + } + +# if GTEST_OS_WINDOWS + + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") { + *test = new ExecDeathTest(statement, regex, file, line); + } else if (GTEST_FLAG(death_test_style) == "fast") { + *test = new NoExecDeathTest(statement, regex); + } + +# endif // GTEST_OS_WINDOWS + + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message(String::Format( + "Unknown death test style \"%s\" encountered", + GTEST_FLAG(death_test_style).c_str())); + return false; + } + + return true; +} + +// Splits a given string on a given delimiter, populating a given +// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have +// ::std::string, so we can use it here. +static void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest) { + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) { + parsed.push_back(str.substr(pos)); + break; + } else { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); +} + +# if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort(String::Format("Unable to open parent process %u", + parent_process_id)); + } + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the pipe handle %Iu from the parent process %u", + write_handle_as_size_t, parent_process_id)); + } + + const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the event handle %Iu from the parent process %u", + event_handle_as_size_t, parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort(String::Format( + "Unable to convert pipe handle %Iu to a file descriptor", + write_handle_as_size_t)); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; +} +# endif // GTEST_OS_WINDOWS + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { + if (GTEST_FLAG(internal_run_death_test) == "") return NULL; + + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +# if GTEST_OS_WINDOWS + + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +# else + + if (fields.size() != 4 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } + +# endif // GTEST_OS_WINDOWS + + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); +} + +} // namespace internal + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-filepath.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-filepath.cc new file mode 100644 index 0000000..4d40cb9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-filepath.cc @@ -0,0 +1,381 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) + +#include "gtest/internal/gtest-filepath.h" +#include "gtest/internal/gtest-port.h" + +#include + +#if GTEST_OS_WINDOWS_MOBILE +# include +#elif GTEST_OS_WINDOWS +# include +# include +#elif GTEST_OS_SYMBIAN +// Symbian OpenC has PATH_MAX in sys/syslimits.h +# include +#else +# include +# include // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +# define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +# define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif // GTEST_OS_WINDOWS + +#include "gtest/internal/gtest-string.h" + +namespace testing { +namespace internal { + +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. +const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; +const char kPathSeparatorString[] = "\\"; +const char kAlternatePathSeparatorString[] = "/"; +# if GTEST_OS_WINDOWS_MOBILE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +# else +const char kCurrentDirectoryString[] = ".\\"; +# endif // GTEST_OS_WINDOWS_MOBILE +#else +const char kPathSeparator = '/'; +const char kPathSeparatorString[] = "/"; +const char kCurrentDirectoryString[] = "./"; +#endif // GTEST_OS_WINDOWS + +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#else + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { + const std::string dot_extension = std::string(".") + extension; + if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { + return FilePath(pathname_.substr( + 0, pathname_.length() - dot_extension.length())); + } + return *this; +} + +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(last_sep + 1) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { + const char* const last_sep = FindLastPathSeparator(); + std::string dir; + if (last_sep) { + dir = std::string(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension) { + std::string file; + if (number == 0) { + file = base_name.string() + "." + extension; + } else { + file = base_name.string() + "_" + String::Format("%d", number).c_str() + + "." + extension; + } + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(dir.string() + kPathSeparator + relative_path.string()); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + return attributes != kInvalidFileAttributes; +#else + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { + bool result = false; +#if GTEST_OS_WINDOWS + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : + RemoveTrailingPathSeparator()); +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = true; + } +#else + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + + return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { + const char* const name = pathname_.c_str(); +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); +#else + return IsPathSeparator(name[0]); +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension) { + FilePath full_pathname; + int number = 0; + do { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { + if (!this->IsDirectory()) { + return false; + } + + if (pathname_.length() == 0 || this->DirectoryExists()) { + return true; + } + + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#if GTEST_OS_WINDOWS_MOBILE + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, NULL) ? 0 : -1; + delete [] unicode; +#elif GTEST_OS_WINDOWS + int result = _mkdir(pathname_.c_str()); +#else + int result = mkdir(pathname_.c_str(), 0777); +#endif // GTEST_OS_WINDOWS_MOBILE + + if (result == -1) { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { + return IsDirectory() + ? FilePath(pathname_.substr(0, pathname_.length() - 1)) + : *this; +} + +// Removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). +void FilePath::Normalize() { + if (pathname_.c_str() == NULL) { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); + + while (*src != '\0') { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { + src++; + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; +} + +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-internal-inl.h b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-internal-inl.h new file mode 100644 index 0000000..54717c9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-internal-inl.h @@ -0,0 +1,1056 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. + +// Utility functions and classes used by the Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This file contains purely Google Test's internal implementation. Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ +// A user is trying to include this from his code - just say no. +# error "gtest-internal-inl.h is part of Google Test's internal implementation." +# error "It must not be included except by Google Test itself." +#endif // GTEST_IMPLEMENTATION_ + +#ifndef _WIN32_WCE +# include +#endif // !_WIN32_WCE +#include +#include // For strtoll/_strtoul64/malloc/free. +#include // For memmove. + +#include +#include +#include + +#include "gtest/internal/gtest-port.h" + +#if GTEST_OS_WINDOWS +# include // NOLINT +#endif // GTEST_OS_WINDOWS + +#include "gtest/gtest.h" // NOLINT +#include "gtest/gtest-spi.h" + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; +const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kStreamResultToFlag[] = "stream_result_to"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Converts the given time in milliseconds to a date string in the ISO 8601 +// format, without the timezone information. N.B.: due to the use the +// non-reentrant localtime() function, this function is not thread safe. Do +// not use it in any code that can be called from multiple threads. +GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast(GetTimeInMillis()) : + static_cast(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast((raw_seed - 1U) % + static_cast(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: + // The c'tor. + GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + stream_result_to_ = GTEST_FLAG(stream_result_to); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } + + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(stream_result_to) = stream_result_to_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } + + private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + std::string color_; + std::string death_test_style_; + bool death_test_use_fork_; + std::string filter_; + std::string internal_run_death_test_; + bool list_tests_; + std::string output_; + bool print_time_; + bool pretty_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + std::string stream_result_to_; + bool throw_on_failure_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template +inline int CountIf(const Container& c, Predicate predicate) { + // Implemented as an explicit loop since std::count_if() in libCstd on + // Solaris has a non-standard signature. + int count = 0; + for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { + if (predicate(*it)) + ++count; + } + return count; +} + +// Applies a function/functor to each element in the container. +template +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} + +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template +inline E GetElementOr(const std::vector& v, int i, E default_value) { + return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; +} + +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector* v) { + const int size = static_cast(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); + } +} + +// Performs an in-place shuffle of the vector's elements. +template +inline void Shuffle(internal::Random* random, std::vector* v) { + ShuffleRange(random, 0, static_cast(v->size()), v); +} + +// A function for deleting an object. Handy for being used as a +// functor. +template +static void Delete(T* x) { + delete x; +} + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const char* key) + : key_(key) {} + + // Returns true iff the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const { + return test_property.key() == key_; + } + + private: + std::string key_; +}; + +// Class UnitTestOptions. +// +// This class contains functions for processing options the user +// specifies when running the tests. It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag. E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter. If both +// the variable and the flag are present, the latter overrides the +// former. +class GTEST_API_ UnitTestOptions { + public: + // Functions for processing the gtest_output flag. + + // Returns the output format, or "" for normal printed output. + static std::string GetOutputFormat(); + + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static std::string GetAbsolutePathToOutputFile(); + + // Functions for processing the gtest_filter flag. + + // Returns true iff the wildcard pattern matches the string. The + // first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char *pattern, const char *str); + + // Returns true iff the user-specified filter matches the test case + // name and the test name. + static bool FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name); + +#if GTEST_OS_WINDOWS + // Function for supporting the gtest_catch_exception flag. + + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); +#endif // GTEST_OS_WINDOWS + + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const std::string& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present. Used by UnitTestOptions::GetOutputFile. +GTEST_API_ FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} + + // Returns the current OS stack trace as an std::string. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; + + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: + OsStackTraceGetter() : caller_frame_(NULL) {} + + virtual string CurrentStackTrace(int max_depth, int skip_count) + GTEST_LOCK_EXCLUDED_(mutex_); + + virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); + + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + + private: + Mutex mutex_; // protects all internal state + + // We save the stack frame below the frame that calls user code. + // We do this because the address of the frame immediately below + // the user code changes between the call to UponLeavingGTest() + // and any calls to CurrentStackTrace() from within the user code. + void* caller_frame_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { + const char* file; + int line; + std::string message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); +}; + +// The private implementation of the UnitTest class. We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class GTEST_API_ UnitTestImpl { + public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); + + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); + + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const { return start_timestamp_; } + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const { return !Failed(); } + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const { + return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; + } + + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); + + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); + + // Returns the current OS stack trace as an std::string. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; + + // Finds and returns a TestCase with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_case_name: name of the test case + // type_param: the name of the test's type parameter, or NULL if + // this is not a typed or a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase* GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + // test_info: the TestInfo object + void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + TestInfo* test_info) { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } + + GetTestCase(test_info->test_case_name(), + test_info->type_param(), + set_up_tc, + tear_down_tc)->AddTestInfo(test_info); + } + +#if GTEST_HAS_PARAM_TEST + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } +#endif // GTEST_HAS_PARAM_TEST + + // Sets the TestCase object for the test that's currently running. + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has guards + // protecting from registering the tests more then once. If + // value-parameterized tests are disabled, RegisterParameterizedTests is + // present but does nothing. + void RegisterParameterizedTests(); + + // Runs all tests in this UnitTest object, prints the result, and + // returns true if all tests are successful. If any exception is + // thrown during a test, this test is considered to be failed, but + // the rest of the tests will still be run. + bool RunAllTests(); + + // Clears the results of all tests, except the ad hoc tests. + void ClearNonAdHocTestResult() { + ForEach(test_cases_, TestCase::ClearTestCaseResult); + } + + // Clears the results of ad-hoc test assertions. + void ClearAdHocTestResult() { + ad_hoc_test_result_.Clear(); + } + + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); + + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); + + const TestCase* current_test_case() const { return current_test_case_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } + + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector& environments() { return environments_; } + + // Getters for the per-thread Google Test trace stack. + std::vector& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); + } + const std::vector& gtest_trace_stack() const { + return gtest_trace_stack_.get(); + } + +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const { + return internal_run_death_test_flag_.get(); + } + + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() { + return death_test_factory_.get(); + } + + void SuppressTestEventsIfInSubprocess(); + + friend class ReplaceDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Initializes the event listener for streaming test results to a socket. + // Must not be called before InitGoogleTest. + void ConfigureStreamingOutput(); +#endif + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + + // Returns the value of GTEST_FLAG(catch_exceptions) at the moment + // UnitTest::Run() starts. + bool catch_exceptions() const { return catch_exceptions_; } + + private: + friend class ::testing::UnitTest; + + // Used by UnitTest::Run() to capture the state of + // GTEST_FLAG(catch_exceptions) at the moment it starts. + void set_catch_exceptions(bool value) { catch_exceptions_ = value; } + + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; + + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; + + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal + per_thread_test_part_result_reporter_; + + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector environments_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector test_cases_; + + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector test_case_indices_; + +#if GTEST_HAS_PARAM_TEST + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; +#endif // GTEST_HAS_PARAM_TEST + + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; + + // This points to the TestCase for the currently running test. It + // changes as Google Test goes through one test case after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestCase* current_test_case_; + + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; + + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; + + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; + + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; + + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + + // The time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp_; + + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; + +#if GTEST_HAS_DEATH_TEST + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + internal::scoped_ptr internal_run_death_test_flag_; + internal::scoped_ptr death_test_factory_; +#endif // GTEST_HAS_DEATH_TEST + + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal > gtest_trace_stack_; + + // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() + // starts. + bool catch_exceptions_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +}; // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { + return UnitTest::GetInstance()->impl(); +} + +#if GTEST_USES_SIMPLE_RE + +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsAsciiDigit(char ch); +GTEST_API_ bool IsAsciiPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsAsciiWhiteSpace(char ch); +GTEST_API_ bool IsAsciiWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + +#endif // GTEST_USES_SIMPLE_RE + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +GTEST_API_ std::string GetLastErrnoDescription(); + +# if GTEST_OS_WINDOWS +// Provides leak-safe Windows kernel handle ownership. +class AutoHandle { + public: + AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} + explicit AutoHandle(HANDLE handle) : handle_(handle) {} + + ~AutoHandle() { Reset(); } + + HANDLE Get() const { return handle_; } + void Reset() { Reset(INVALID_HANDLE_VALUE); } + void Reset(HANDLE handle) { + if (handle != handle_) { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + handle_ = handle; + } + } + + private: + HANDLE handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; +# endif // GTEST_OS_WINDOWS + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !IsDigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. + +# if GTEST_OS_WINDOWS && !defined(__GNUC__) + + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); + +# else + + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); + +# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast(parsed); + if (parse_success && static_cast(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const TestProperty& property) { + test_result->RecordProperty(property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-port.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-port.cc new file mode 100644 index 0000000..fa8f29c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-port.cc @@ -0,0 +1,805 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/internal/gtest-port.h" + +#include +#include +#include +#include + +#if GTEST_OS_WINDOWS_MOBILE +# include // For TerminateProcess() +#elif GTEST_OS_WINDOWS +# include +# include +#else +# include +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_MAC +# include +# include +# include +#endif // GTEST_OS_MAC + +#if GTEST_OS_QNX +# include +# include +#endif // GTEST_OS_QNX + +#include "gtest/gtest-spi.h" +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_MAC + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast(thread_list), + sizeof(thread_t) * thread_count); + return static_cast(thread_count); + } else { + return 0; + } +} + +#elif GTEST_OS_QNX + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const int fd = open("/proc/self/as", O_RDONLY); + if (fd < 0) { + return 0; + } + procfs_info process_info; + const int status = + devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); + close(fd); + if (status == EOK) { + return static_cast(process_info.num_threads); + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_MAC + +#if GTEST_USES_POSIX_RE + +// Implements RE. Currently only needed for death tests. + +RE::~RE() { + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast(pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = posix::StrDup(regex); + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; +} + +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in , these aren't affected by the +// current locale. +bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsAsciiPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsAsciiWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsAsciiDigit(ch); + case 'D': return !IsAsciiDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsAsciiWhiteSpace(ch); + case 'S': return !IsAsciiWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsAsciiWordChar(ch); + case 'W': return !IsAsciiWordChar(ch); + } + return IsAsciiPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +std::string FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast(pattern_)); + free(const_cast(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + +const char kUnknownFile[] = "unknown file"; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { + const char* const file_name = file == NULL ? kUnknownFile : file; + + if (line < 0) { + return String::Format("%s:", file_name).c_str(); + } +#ifdef _MSC_VER + return String::Format("%s(%d):", file_name, line).c_str(); +#else + return String::Format("%s:%d:", file_name, line).c_str(); +#endif // _MSC_VER +} + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +// Note that FormatCompilerIndependentFileLocation() does NOT append colon +// to the file location it produces, unlike FormatFileLocation(). +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( + const char* file, int line) { + const char* const file_name = file == NULL ? kUnknownFile : file; + + if (line < 0) + return file_name; + else + return String::Format("%s:%d", file_name, line).c_str(); +} + + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : + severity == GTEST_WARNING ? "[WARNING]" : + severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4996) +#endif // _MSC_VER + +#if GTEST_HAS_STREAM_REDIRECTION + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { +# if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +# else + // There's no guarantee that a test has write access to the current + // directory, so we create the temporary file in the /tmp directory + // instead. We use /tmp on most systems, and /sdcard on Android. + // That's because Android doesn't have /tmp. +# if GTEST_OS_LINUX_ANDROID + // Note: Android applications are expected to call the framework's + // Context.getExternalStorageDirectory() method through JNI to get + // the location of the world-writable SD Card directory. However, + // this requires a Context handle, which cannot be retrieved + // globally from native code. Doing so also precludes running the + // code as part of a regular standalone executable, which doesn't + // run in a Dalvik process (e.g. when running it through 'adb shell'). + // + // The location /sdcard is directly accessible from native code + // and is the only location (unofficially) supported by the Android + // team. It's generally a symlink to the real SD Card mount point + // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or + // other OEM-customized locations. Never rely on these, and always + // use /sdcard. + char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; +# else + char name_template[] = "/tmp/captured_stream.XXXXXX"; +# endif // GTEST_OS_LINUX_ANDROID + const int captured_fd = mkstemp(name_template); + filename_ = name_template; +# endif // GTEST_OS_WINDOWS + fflush(NULL); + dup2(captured_fd, fd_); + close(captured_fd); + } + + ~CapturedStream() { + remove(filename_.c_str()); + } + + std::string GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const std::string content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + // Reads the entire content of a file as an std::string. + static std::string ReadEntireFile(FILE* file); + + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); + + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; + +// Returns the size (in bytes) of a file. +size_t CapturedStream::GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast(ftell(file)); +} + +// Reads the entire content of a file as a string. +std::string CapturedStream::ReadEntireFile(FILE* file) { + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; + + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far + + fseek(file, 0, SEEK_SET); + + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do { + bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); + + const std::string content(buffer, bytes_read); + delete[] buffer; + + return content; +} + +# ifdef _MSC_VER +# pragma warning(pop) +# endif // _MSC_VER + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +std::string GetCapturedStream(CapturedStream** captured_stream) { + const std::string content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = NULL; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +std::string GetCapturedStdout() { + return GetCapturedStream(&g_captured_stdout); +} + +// Stops capturing stderr and returns the captured string. +std::string GetCapturedStderr() { + return GetCapturedStream(&g_captured_stderr); +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +::std::vector g_argvs; + +static const ::std::vector* g_injected_test_argvs = + NULL; // Owned. + +void SetInjectableArgvs(const ::std::vector* argvs) { + if (g_injected_test_argvs != argvs) + delete g_injected_test_argvs; + g_injected_test_argvs = argvs; +} + +const ::std::vector& GetInjectableArgvs() { + if (g_injected_test_argvs != NULL) { + return *g_injected_test_argvs; + } + return g_argvs; +} +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); +} +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static std::string FlagToEnvVar(const char* flag) { + const std::string full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); + + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) { + env_var << ToUpper(full_flag.c_str()[i]); + } + + return env_var.GetString(); +} + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { + // Parses the environment variable as a decimal integer. + char* end = NULL; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + *value = result; + return true; +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == NULL) { + // The environment variable is not set. + return default_value; + } + + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } + + return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromGTestEnv(const char* flag, const char* default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const value = posix::GetEnv(env_var.c_str()); + return value == NULL ? default_value : value; +} + +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-printers.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-printers.cc new file mode 100644 index 0000000..898d61d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-printers.cc @@ -0,0 +1,364 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// It uses the << operator when possible, and prints the bytes in the +// object otherwise. A user can override its behavior for a class +// type Foo by defining either operator<<(::std::ostream&, const Foo&) +// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that +// defines Foo. + +#include "gtest/gtest-printers.h" +#include +#include +#include // NOLINT +#include +#include "gtest/internal/gtest-port.h" + +namespace testing { + +namespace { + +using ::std::ostream; + +// Prints a segment of bytes in the given object. +void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, + size_t count, ostream* os) { + char text[5] = ""; + for (size_t i = 0; i != count; i++) { + const size_t j = start + i; + if (i != 0) { + // Organizes the bytes into groups of 2 for easy parsing by + // human. + if ((j % 2) == 0) + *os << ' '; + else + *os << '-'; + } + GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); + *os << text; + } +} + +// Prints the bytes in the given value to the given ostream. +void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, + ostream* os) { + // Tells the user how big the object is. + *os << count << "-byte object <"; + + const size_t kThreshold = 132; + const size_t kChunkSize = 64; + // If the object size is bigger than kThreshold, we'll have to omit + // some details by printing only the first and the last kChunkSize + // bytes. + // TODO(wan): let the user control the threshold using a flag. + if (count < kThreshold) { + PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); + } else { + PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); + *os << " ... "; + // Rounds up to 2-byte boundary. + const size_t resume_pos = (count - kChunkSize + 1)/2*2; + PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); + } + *os << ">"; +} + +} // namespace + +namespace internal2 { + +// Delegates to PrintBytesInObjectToImpl() to print the bytes in the +// given object. The delegation simplifies the implementation, which +// uses the << operator and thus is easier done outside of the +// ::testing::internal namespace, which contains a << operator that +// sometimes conflicts with the one in STL. +void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, + ostream* os) { + PrintBytesInObjectToImpl(obj_bytes, count, os); +} + +} // namespace internal2 + +namespace internal { + +// Depending on the value of a char (or wchar_t), we print it in one +// of three formats: +// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), +// - as a hexidecimal escape sequence (e.g. '\x7F'), or +// - as a special escape sequence (e.g. '\r', '\n'). +enum CharFormat { + kAsIs, + kHexEscape, + kSpecialEscape +}; + +// Returns true if c is a printable ASCII character. We test the +// value of c directly instead of calling isprint(), which is buggy on +// Windows Mobile. +inline bool IsPrintableAscii(wchar_t c) { + return 0x20 <= c && c <= 0x7E; +} + +// Prints a wide or narrow char c as a character literal without the +// quotes, escaping it when necessary; returns how c was formatted. +// The template argument UnsignedChar is the unsigned version of Char, +// which is the type of c. +template +static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { + switch (static_cast(c)) { + case L'\0': + *os << "\\0"; + break; + case L'\'': + *os << "\\'"; + break; + case L'\\': + *os << "\\\\"; + break; + case L'\a': + *os << "\\a"; + break; + case L'\b': + *os << "\\b"; + break; + case L'\f': + *os << "\\f"; + break; + case L'\n': + *os << "\\n"; + break; + case L'\r': + *os << "\\r"; + break; + case L'\t': + *os << "\\t"; + break; + case L'\v': + *os << "\\v"; + break; + default: + if (IsPrintableAscii(c)) { + *os << static_cast(c); + return kAsIs; + } else { + *os << String::Format("\\x%X", static_cast(c)); + return kHexEscape; + } + } + return kSpecialEscape; +} + +// Prints a wchar_t c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { + switch (c) { + case L'\'': + *os << "'"; + return kAsIs; + case L'"': + *os << "\\\""; + return kSpecialEscape; + default: + return PrintAsCharLiteralTo(c, os); + } +} + +// Prints a char c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { + return PrintAsStringLiteralTo( + static_cast(static_cast(c)), os); +} + +// Prints a wide or narrow character c and its code. '\0' is printed +// as "'\\0'", other unprintable characters are also properly escaped +// using the standard C++ escape sequence. The template argument +// UnsignedChar is the unsigned version of Char, which is the type of c. +template +void PrintCharAndCodeTo(Char c, ostream* os) { + // First, print c as a literal in the most readable form we can find. + *os << ((sizeof(c) > 1) ? "L'" : "'"); + const CharFormat format = PrintAsCharLiteralTo(c, os); + *os << "'"; + + // To aid user debugging, we also print c's code in decimal, unless + // it's 0 (in which case c was printed as '\\0', making the code + // obvious). + if (c == 0) + return; + *os << " (" << String::Format("%d", c).c_str(); + + // For more convenience, we print c's code again in hexidecimal, + // unless c was already printed in the form '\x##' or the code is in + // [1, 9]. + if (format == kHexEscape || (1 <= c && c <= 9)) { + // Do nothing. + } else { + *os << String::Format(", 0x%X", + static_cast(c)).c_str(); + } + *os << ")"; +} + +void PrintTo(unsigned char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} +void PrintTo(signed char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} + +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its code. L'\0' is printed as "L'\\0'". +void PrintTo(wchar_t wc, ostream* os) { + PrintCharAndCodeTo(wc, os); +} + +// Prints the given array of characters to the ostream. CharType must be either +// char or wchar_t. +// The array starts at begin, the length is len, it may include '\0' characters +// and may not be NUL-terminated. +template +static void PrintCharsAsStringTo( + const CharType* begin, size_t len, ostream* os) { + const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; + *os << kQuoteBegin; + bool is_previous_hex = false; + for (size_t index = 0; index < len; ++index) { + const CharType cur = begin[index]; + if (is_previous_hex && IsXDigit(cur)) { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" " << kQuoteBegin; + } + is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; + } + *os << "\""; +} + +// Prints a (const) char/wchar_t array of 'len' elements, starting at address +// 'begin'. CharType must be either char or wchar_t. +template +static void UniversalPrintCharArray( + const CharType* begin, size_t len, ostream* os) { + // The code + // const char kFoo[] = "foo"; + // generates an array of 4, not 3, elements, with the last one being '\0'. + // + // Therefore when printing a char array, we don't print the last element if + // it's '\0', such that the output matches the string literal as it's + // written in the source code. + if (len > 0 && begin[len - 1] == '\0') { + PrintCharsAsStringTo(begin, len - 1, os); + return; + } + + // If, however, the last element in the array is not '\0', e.g. + // const char kFoo[] = { 'f', 'o', 'o' }; + // we must print the entire array. We also print a message to indicate + // that the array is not NUL-terminated. + PrintCharsAsStringTo(begin, len, os); + *os << " (no terminating NUL)"; +} + +// Prints a (const) char array of 'len' elements, starting at address 'begin'. +void UniversalPrintArray(const char* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints a (const) wchar_t array of 'len' elements, starting at address +// 'begin'. +void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints the given C string to the ostream. +void PrintTo(const char* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, strlen(s), os); + } +} + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Prints the given wide C string to the ostream. +void PrintTo(const wchar_t* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, wcslen(s), os); + } +} +#endif // wchar_t is native + +// Prints a ::string object. +#if GTEST_HAS_GLOBAL_STRING +void PrintStringTo(const ::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +void PrintStringTo(const ::std::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} + +// Prints a ::wstring object. +#if GTEST_HAS_GLOBAL_WSTRING +void PrintWideStringTo(const ::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +void PrintWideStringTo(const ::std::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_STD_WSTRING + +} // namespace internal + +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-test-part.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-test-part.cc new file mode 100644 index 0000000..c60eef3 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-test-part.cc @@ -0,0 +1,110 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + +#include "gtest/gtest-test-part.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +using internal::GetUnitTestImpl; + +// Gets the summary of the failure message by omitting the stack trace +// in it. +std::string TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? message : + std::string(message, stack_trace); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + array_.push_back(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } + + return array_[index]; +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return static_cast(array_.size()); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()-> + GetTestPartResultReporterForCurrentThread()) { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-typed-test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-typed-test.cc new file mode 100644 index 0000000..f0079f4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest-typed-test.cc @@ -0,0 +1,110 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest-typed-test.h" +#include "gtest/gtest.h" + +namespace testing { +namespace internal { + +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (IsSpace(*str)) + str++; + return str; +} + +// Verifies that registered_tests match the test names in +// defined_test_names_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestCasePState::VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests) { + typedef ::std::set::const_iterator DefinedTestIter; + registered_ = true; + + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); + + Message errors; + ::std::set tests; + for (const char* names = registered_tests; names != NULL; + names = SkipComma(names)) { + const std::string name = GetPrefixUntilComma(names); + if (tests.count(name) != 0) { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } + + bool found = false; + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (name == *it) { + found = true; + break; + } + } + + if (found) { + tests.insert(name); + } else { + errors << "No test named " << name + << " can be found in this test case.\n"; + } + } + + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (tests.count(*it) == 0) { + errors << "You forgot to list test " << *it << ".\n"; + } + } + + const std::string& errors_str = errors.GetString(); + if (errors_str != "") { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } + + return registered_tests; +} + +#endif // GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest.cc new file mode 100644 index 0000000..0567e83 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest.cc @@ -0,0 +1,4838 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // NOLINT +#include +#include + +#if GTEST_OS_LINUX + +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +# include // NOLINT +# include // NOLINT +# include // NOLINT +// Declares vsnprintf(). This header is not available on Windows. +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include + +#elif GTEST_OS_SYMBIAN +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +#elif GTEST_OS_ZOS +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +# include // NOLINT + +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. + +# include // NOLINT + +#elif GTEST_OS_WINDOWS // We are on Windows proper. + +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT + +# if GTEST_OS_WINDOWS_MINGW +// MinGW has gettimeofday() but not _ftime64(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +// TODO(kenton@google.com): There are other ways to get the time on +// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW +// supports these. consider using them instead. +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT +# endif // GTEST_OS_WINDOWS_MINGW + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT + +#else + +// Assume other platforms have gettimeofday(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT +# include // NOLINT + +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +# include +#endif + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +#endif + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS +# define vsnprintf _vsnprintf +#endif // GTEST_OS_WINDOWS + +namespace testing { + +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + +// Constants. + +// A test whose test case name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test case whose name matches this filter is considered a death +// test case and will be run before test cases whose name doesn't +// match this filter. +static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output file for XML output. +static const char kDefaultOutputFile[] = "test_detail.xml"; + +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + +} // namespace internal + +GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( + break_on_failure, + internal::BoolFromGTestEnv("break_on_failure", false), + "True iff a failed assertion should be a debugger break-point."); + +GTEST_DEFINE_bool_( + catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", true), + "True iff " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to xterm, xterm-color, xterm-256color, linux or cygwin."); + +GTEST_DEFINE_string_( + filter, + internal::StringFromGTestEnv("filter", kUniversalFilter), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); + +GTEST_DEFINE_string_( + output, + internal::StringFromGTestEnv("output", ""), + "A format (currently must be \"xml\"), optionally followed " + "by a colon and an output file name or directory. A directory " + "is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); + +GTEST_DEFINE_bool_( + print_time, + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ + " should display elapsed time in text output."); + +GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +GTEST_DEFINE_int32_( + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); + +GTEST_DEFINE_bool_( + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_( + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); + +GTEST_DEFINE_int32_( + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_string_( + stream_result_to, + internal::StringFromGTestEnv("stream_result_to", ""), + "This flag specifies the host name and the port number on which to stream " + "test results. Example: \"localhost:555\". The flag is effective only on " + "Linux."); + +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); + +namespace internal { + +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + +// GTestIsInitialized() returns true iff the user has initialized +// Google Test. Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +// +// A user must call testing::InitGoogleTest() to initialize Google +// Test. g_init_gtest_count is set to the number of times +// InitGoogleTest() has been called. We don't protect this variable +// under a mutex as it is only accessed in the main thread. +GTEST_API_ int g_init_gtest_count = 0; +static bool GTestIsInitialized() { return g_init_gtest_count != 0; } + +// Iterates over a vector of TestCases, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestCaseList(const std::vector& case_list, + int (TestCase::*method)() const) { + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); + } + return sum; +} + +// Returns true iff the test case passed. +static bool TestCasePassed(const TestCase* test_case) { + return test_case->should_run() && test_case->Passed(); +} + +// Returns true iff the test case failed. +static bool TestCaseFailed(const TestCase* test_case) { + return test_case->should_run() && test_case->Failed(); +} + +// Returns true iff test_case contains at least one test that should +// run. +static bool ShouldRunTestCase(const TestCase* test_case) { + return test_case->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { + UnitTest::GetInstance()-> + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl() + ->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT +} + +// Mutex for linked pointers. +GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// Application pathname gotten in InitGoogleTest. +std::string g_executable_path; + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { + FilePath result; + +#if GTEST_OS_WINDOWS + result.Set(FilePath(g_executable_path).RemoveExtension("exe")); +#else + result.Set(FilePath(g_executable_path)); +#endif // GTEST_OS_WINDOWS + + return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +std::string UnitTestOptions::GetOutputFormat() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) return std::string(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == NULL) ? + std::string(gtest_output_flag) : + std::string(gtest_output_flag, colon - gtest_output_flag); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +std::string UnitTestOptions::GetAbsolutePathToOutputFile() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) + return ""; + + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == NULL) + return internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).string(); + + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + + if (!output_name.IsDirectory()) + return output_name.string(); + + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.string(); +} + +// Returns true iff the wildcard pattern matches the string. The +// first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, + const char *str) { + switch (*pattern) { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } +} + +bool UnitTestOptions::MatchesFilter( + const std::string& name, const char* filter) { + const char *cur_pattern = filter; + for (;;) { + if (PatternMatchesString(cur_pattern, name.c_str())) { + return true; + } + + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); + + // Returns if no more pattern can be found. + if (cur_pattern == NULL) { + return false; + } + + // Skips the pattern separater (the ':' character). + cur_pattern++; + } +} + +// Returns true iff the user-specified filter matches the test case +// name and the test name. +bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name) { + const std::string& full_name = test_case_name + "." + test_name.c_str(); + + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + std::string positive; + std::string negative; + if (dash == NULL) { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = ""; + } else { + positive = std::string(p, dash); // Everything up to the dash + negative = std::string(dash + 1); // Everything after the dash + if (positive.empty()) { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } + + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); +} + +#if GTEST_HAS_SEH +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { + // Google Test should handle a SEH exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception, AND + // 3. this is not a C++ exception (VC++ implements them via SEH, + // apparently). + // + // SEH exception code for C++ exceptions. + // (see http://support.microsoft.com/kb/185294 for more information). + const DWORD kCxxExceptionCode = 0xe06d7363; + + bool should_handle = true; + + if (!GTEST_FLAG(catch_exceptions)) + should_handle = false; + else if (exception_code == EXCEPTION_BREAKPOINT) + should_handle = false; + else if (exception_code == kCxxExceptionCode) + should_handle = false; + + return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} +#endif // GTEST_HAS_SEH + +} // namespace internal + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test. We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test. This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X. The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code. GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { + return GetTypeId(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +AssertionResult HasOneFailure(const char* /* results_expr */, + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const string& substr) { + const std::string expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); + Message msg; + if (results.size() != 1) { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) { + msg << "\n" << results.GetTestPartResult(i); + } + return AssertionFailure() << msg; + } + + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) { + return AssertionFailure() << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + } + + if (strstr(r.message(), substr.c_str()) == NULL) { + return AssertionFailure() << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + } + + return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker:: SingleFailureChecker( + const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr) + : results_(results), + type_(type), + substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter) { + per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test cases. +int UnitTestImpl::successful_test_case_count() const { + return CountIf(test_cases_, TestCasePassed); +} + +// Gets the number of failed test cases. +int UnitTestImpl::failed_test_case_count() const { + return CountIf(test_cases_, TestCaseFailed); +} + +// Gets the number of all test cases. +int UnitTestImpl::total_test_case_count() const { + return static_cast(test_cases_.size()); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTestImpl::test_case_to_run_count() const { + return CountIf(test_cases_, ShouldRunTestCase); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { + (void)skip_count; + return ""; +} + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; + + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + // TODO(kenton@google.com): Shouldn't this just use + // GetSystemTimeAsFileTime()? + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ + __timeb64 now; + +# ifdef _MSC_VER + + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + // TODO(kenton@google.com): Use GetTickCount()? Or use + // SystemTimeToFileTime() +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996. + _ftime64(&now); +# pragma warning(pop) // Restores the warning state. +# else + + _ftime64(&now); + +# endif // _MSC_VER + + return static_cast(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, NULL); + return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +# error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String. + +#if GTEST_OS_WINDOWS_MOBILE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { + if (!ansi) return NULL; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, + NULL, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { + if (!utf16_str) return NULL; + const int ansi_length = + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + NULL, 0, NULL, NULL); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + ansi, ansi_length, NULL, NULL); + ansi[ansi_length] = 0; + return ansi; +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +// Compares two C strings. Returns true iff they have the same content. +// +// Unlike strcmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + + return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, + Message* msg) { + for (size_t i = 0; i != length; ) { // NOLINT + if (wstr[i] != L'\0') { + *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } else { + *msg << '\0'; + i++; + } + } +} + +#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +} // namespace internal + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new ::std::string(*other.message_) : + static_cast< ::std::string*>(NULL)) { +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { + return AssertionResult(true); +} + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +namespace internal { + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case) { + Message msg; + msg << "Value of: " << actual_expression; + if (actual_value != actual_expression) { + msg << "\n Actual: " << actual_value; + } + + msg << "\nExpected: " << expected_expression; + if (ignoring_case) { + msg << " (ignoring case)"; + } + if (expected_value != expected_expression) { + msg << "\nWhich is: " << expected_value; + } + + return AssertionFailure() << msg; +} + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) { + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); + + // TODO(wan): do not print the value of an expression if it's + // already a literal. + return AssertionFailure() + << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template +AssertionResult FloatingPointLE(const char* expr1, + const char* expr2, + RawType val1, + RawType val2) { + // Returns success if val1 is less than val2, + if (val1 < val2) { + return AssertionSuccess(); + } + + // or if val1 is almost equal to val2. + const FloatingPoint lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. + + ::std::stringstream val1_ss; + val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val1; + + ::std::stringstream val2_ss; + val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val2; + + return AssertionFailure() + << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StringStreamToString(&val1_ss) << " vs " + << StringStreamToString(&val2_ss); +} + +} // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + if (expected == actual) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CaseInsensitiveCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CaseInsensitiveCStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +} // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true iff needle is a +// substring of haystack. NULL is considered a substring of itself +// only. + +bool IsSubstringPred(const char* needle, const char* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return strstr(haystack, needle) != NULL; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return wcsstr(haystack, needle) != NULL; +} + +// StringType here can be either ::std::string or ::std::wstring. +template +bool IsSubstringPred(const StringType& needle, + const StringType& haystack) { + return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template +AssertionResult IsSubstringImpl( + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) { + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""; +} + +} // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +#if GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, + const char* expected, + long hr) { // NOLINT +# if GTEST_OS_WINDOWS_MOBILE + + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; + +# else + + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; // String::Format can't exceed this length. + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = { '\0' }; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + hr, // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + NULL); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing cr-lf) + for (; message_length && IsSpace(error_text[message_length - 1]); + --message_length) { + error_text[message_length - 1] = '\0'; + } + +# endif // GTEST_OS_WINDOWS_MOBILE + + const std::string error_hex(String::Format("0x%08X ", hr)); + return ::testing::AssertionFailure() + << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << error_text << "\n"; +} + +} // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT + if (SUCCEEDED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT + if (FAILED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length Encoding +// 0 - 7 bits 0xxxxxxx +// 8 - 11 bits 110xxxxx 10xxxxxx +// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx +// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern. Returns the n +// lowest bits. As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { + const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); + *bits >>= n; + return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +char* CodePointToUtf8(UInt32 code_point, char* str) { + if (code_point <= kMaxCodePoint1) { + str[1] = '\0'; + str[0] = static_cast(code_point); // 0xxxxxxx + } else if (code_point <= kMaxCodePoint2) { + str[2] = '\0'; + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xC0 | code_point); // 110xxxxx + } else if (code_point <= kMaxCodePoint3) { + str[3] = '\0'; + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xE0 | code_point); // 1110xxxx + } else if (code_point <= kMaxCodePoint4) { + str[4] = '\0'; + str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xF0 | code_point); // 11110xxx + } else { + // The longest string String::Format can produce when invoked + // with these parameters is 28 character long (not including + // the terminating nul character). We are asking for 32 character + // buffer just in case. This is also enough for strncpy to + // null-terminate the destination string. + posix::StrNCpy( + str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32); + str[31] = '\0'; // Makes sure no change in the format to strncpy leaves + // the result unterminated. + } + return str; +} + +// The following two functions only make sense if the the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast(first); +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +std::string WideStringToUtf8(const wchar_t* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast(wcslen(str)); + + ::std::stringstream stream; + for (int i = 0; i < num_chars; ++i) { + UInt32 unicode_code_point; + + if (str[i] == L'\0') { + break; + } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } else { + unicode_code_point = static_cast(str[i]); + } + + char buffer[32]; // CodePointToUtf8 requires a buffer this big. + stream << CodePointToUtf8(unicode_code_point, buffer); + } + return StringStreamToString(&stream); +} + +// Converts a wide C string to an std::string using the UTF-8 encoding. +// NULL will be converted to "(null)". +std::string String::ShowWideCString(const wchar_t * wide_c_str) { + if (wide_c_str == NULL) return "(null)"; + + return internal::WideStringToUtf8(wide_c_str, -1); +} + +// Compares two wide C strings. Returns true iff they have the same +// content. +// +// Unlike wcscmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + + return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual) { + if (String::WideCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) { + if (!String::WideCStringEquals(s1, s2)) { + return AssertionSuccess(); + } + + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << PrintToString(s1) + << " vs " << PrintToString(s2); +} + +// Compares two C strings, ignoring case. Returns true iff they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s). A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; +} + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + +#if GTEST_OS_WINDOWS + return _wcsicmp(lhs, rhs) == 0; +#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID + return wcscasecmp(lhs, rhs) == 0; +#else + // Android, Mac OS X and Cygwin don't define wcscasecmp. + // Other unknown OSes may not define it either. + wint_t left, right; + do { + left = towlower(*lhs++); + right = towlower(*rhs++); + } while (left && left == right); + return left == right; +#endif // OS selector +} + +// Returns true iff str ends with the given suffix, ignoring case. +// Any string is considered to end with an empty suffix. +bool String::EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix) { + const size_t str_len = str.length(); + const size_t suffix_len = suffix.length(); + return (str_len >= suffix_len) && + CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, + suffix.c_str()); +} + +// Formats a list of arguments to an std::string, using the same format +// spec string as for printf. +// +// We do not use the StringPrintf class as it is not universally +// available. +// +// The result is limited to 4096 characters (including the tailing 0). +// If 4096 characters are not enough to format the input, or if +// there's an error, "" is +// returned. +std::string String::Format(const char * format, ...) { + va_list args; + va_start(args, format); + + char buffer[4096]; + const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]); + + // MSVC 8 deprecates vsnprintf(), so we want to suppress warning + // 4996 (deprecated function) there. +#ifdef _MSC_VER // We are using MSVC. +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996. + + const int size = vsnprintf(buffer, kBufferSize, format, args); + +# pragma warning(pop) // Restores the warning state. +#else // We are not using MSVC. + const int size = vsnprintf(buffer, kBufferSize, format, args); +#endif // _MSC_VER + va_end(args); + + // vsnprintf()'s behavior is not portable. When the buffer is not + // big enough, it returns a negative value in MSVC, and returns the + // needed buffer size on Linux. When there is an output error, it + // always returns a negative value. For simplicity, we lump the two + // error cases together. + if (size < 0 || size >= kBufferSize) { + return ""; + } else { + return std::string(buffer, size); + } +} + +// Converts the buffer in a stringstream to an std::string, converting NUL +// bytes to "\\0" along the way. +std::string StringStreamToString(::std::stringstream* ss) { + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); + + std::string result; + result.reserve(2 * (end - start)); + for (const char* ch = start; ch != end; ++ch) { + if (*ch == '\0') { + result += "\\0"; // Replaces NUL with "\\0"; + } else { + result += *ch; + } + } + + return result; +} + +// Appends the user-supplied message to the Google-Test-generated message. +std::string AppendUserMessage(const std::string& gtest_msg, + const Message& user_msg) { + // Appends the user message if it's non-empty. + const std::string user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) { + return gtest_msg; + } + + return gtest_msg + "\n" + user_msg_string; +} + +} // namespace internal + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() + : death_test_count_(0), + elapsed_time_(0) { +} + +// D'tor. +TestResult::~TestResult() { +} + +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { + test_part_results_.push_back(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const TestProperty& test_property) { + if (!ValidateTestProperty(test_property)) { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); +} + +// Adds a failure if the key is a reserved attribute of Google Test +// testcase tags. Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const TestProperty& test_property) { + const std::string& key = test_property.key(); + if (key == "name" || key == "status" || key == "time" || key == "classname") { + ADD_FAILURE() + << "Reserved key used in RecordProperty(): " + << key + << " ('name', 'status', 'time', and 'classname' are reserved by " + << GTEST_NAME_ << ")"; + return false; + } + return true; +} + +// Clears the object. +void TestResult::Clear() { + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; +} + +// Returns true iff the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; +} + +// Returns true iff the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult& result) { + return result.fatally_failed(); +} + +// Returns true iff the test fatally failed. +bool TestResult::HasFatalFailure() const { + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true iff the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true iff the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +} + +// Gets the number of all test parts. This is the sum of the number +// of successful test parts and the number of failed test parts. +int TestResult::total_part_count() const { + return static_cast(test_part_results_.size()); +} + +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast(test_properties_.size()); +} + +// class Test + +// Creates a Test object. + +// The c'tor saves the values of all Google Test flags. +Test::Test() + : gtest_flag_saver_(new internal::GTestFlagSaver) { +} + +// The d'tor restores the values of all Google Test flags. +Test::~Test() { + delete gtest_flag_saver_; +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, const char* value) { + UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, int value) { + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); +} + +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + ""); // No stack trace, either. +} + +} // namespace internal + +// Google Test requires all tests in the same test case to use the same test +// fixture class. This function checks if the current test has the +// same fixture class as the first test in the current test case. If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestCase* const test_case = impl->current_test_case(); + + // Info about the first test in the current test case. + const TestInfo* const first_test_info = test_case->test_info_list()[0]; + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; + const char* const first_test_name = first_test_info->name(); + + // Info about the current test. + const TestInfo* const this_test_info = impl->current_test_info(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; + const char* const this_test_name = this_test_info->name(); + + if (this_fixture_id != first_fixture_id) { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + + if (first_is_TEST || this_is_TEST) { + // The user mixed TEST and TEST_F in this test case - we'll tell + // him/her how to fix it. + + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; + + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test case is\n" + << "illegal. In test case " << this_test_info->test_case_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } else { + // The user defined two fixture classes with the same name in + // two namespaces - we'll tell him/her how to fix it. + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " + << this_test_info->test_case_name() << ",\n" + << "you defined test " << first_test_name + << " and test " << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test cases."; + } + return false; + } + + return true; +} + +#if GTEST_HAS_SEH + +// Adds an "exception thrown" fatal failure to the current test. This +// function returns its result via an output parameter pointer because VC++ +// prohibits creation of objects with destructors on stack in functions +// using __try (see error C2712). +static std::string* FormatSehExceptionMessage(DWORD exception_code, + const char* location) { + Message message; + message << "SEH exception with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " thrown in " << location << "."; + + return new std::string(message.GetString()); +} + +#endif // GTEST_HAS_SEH + +#if GTEST_HAS_EXCEPTIONS + +// Adds an "exception thrown" fatal failure to the current test. +static std::string FormatCxxExceptionMessage(const char* description, + const char* location) { + Message message; + if (description != NULL) { + message << "C++ exception with description \"" << description << "\""; + } else { + message << "Unknown C++ exception"; + } + message << " thrown in " << location << "."; + + return message.GetString(); +} + +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result); + +// A failed Google Test assertion will throw an exception of this type when +// GTEST_FLAG(throw_on_failure) is true (if exceptions are enabled). We +// derive it from std::runtime_error, which is for errors presumably +// detectable only at run time. Since std::runtime_error inherits from +// std::exception, many testing frameworks know how to extract and print the +// message inside it. +class GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} +}; +#endif // GTEST_HAS_EXCEPTIONS + +namespace internal { +// We put these helper functions in the internal namespace as IBM's xlC +// compiler rejects the code if they were declared static. + +// Runs the given method and handles SEH exceptions it throws, when +// SEH is supported; returns the 0-value for type Result in case of an +// SEH exception. (Microsoft compilers cannot handle SEH and C++ +// exceptions in the same function. Therefore, we provide a separate +// wrapper function for handling SEH exceptions.) +template +Result HandleSehExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { +#if GTEST_HAS_SEH + __try { + return (object->*method)(); + } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT + GetExceptionCode())) { + // We create the exception message on the heap because VC++ prohibits + // creation of objects with destructors on stack in functions using __try + // (see error C2712). + std::string* exception_message = FormatSehExceptionMessage( + GetExceptionCode(), location); + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + *exception_message); + delete exception_message; + return static_cast(0); + } +#else + (void)location; + return (object->*method)(); +#endif // GTEST_HAS_SEH +} + +// Runs the given method and catches and reports C++ and/or SEH-style +// exceptions, if they are supported; returns the 0-value for type +// Result in case of an SEH exception. +template +Result HandleExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { + // NOTE: The user code can affect the way in which Google Test handles + // exceptions by setting GTEST_FLAG(catch_exceptions), but only before + // RUN_ALL_TESTS() starts. It is technically possible to check the flag + // after the exception is caught and either report or re-throw the + // exception based on the flag's value: + // + // try { + // // Perform the test method. + // } catch (...) { + // if (GTEST_FLAG(catch_exceptions)) + // // Report the exception as failure. + // else + // throw; // Re-throws the original exception. + // } + // + // However, the purpose of this flag is to allow the program to drop into + // the debugger when the exception is thrown. On most platforms, once the + // control enters the catch block, the exception origin information is + // lost and the debugger will stop the program at the point of the + // re-throw in this function -- instead of at the point of the original + // throw statement in the code under test. For this reason, we perform + // the check early, sacrificing the ability to affect Google Test's + // exception handling in the method where the exception is thrown. + if (internal::GetUnitTestImpl()->catch_exceptions()) { +#if GTEST_HAS_EXCEPTIONS + try { + return HandleSehExceptionsInMethodIfSupported(object, method, location); + } catch (const GoogleTestFailureException&) { // NOLINT + // This exception doesn't originate in code under test. It makes no + // sense to report it as a test failure. + throw; + } catch (const std::exception& e) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(e.what(), location)); + } catch (...) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(NULL, location)); + } + return static_cast(0); +#else + return HandleSehExceptionsInMethodIfSupported(object, method, location); +#endif // GTEST_HAS_EXCEPTIONS + } else { + return (object->*method)(); + } +} + +} // namespace internal + +// Runs the test and updates the test result. +void Test::Run() { + if (!HasSameFixtureClass()) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); + // We will run the test only if SetUp() was successful. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TestBody, "the test body"); + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TearDown, "TearDown()"); +} + +// Returns true iff the current test has a fatal failure. +bool Test::HasFatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// Returns true iff the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object. +// TODO(vladl@google.com): Make a_test_case_name and a_name const string&'s +// to signify they cannot be NULLs. +TestInfo::TestInfo(const char* a_test_case_name, + const char* a_name, + const char* a_type_param, + const char* a_value_param, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) + : test_case_name_(a_test_case_name), + name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + value_param_(a_value_param ? new std::string(a_value_param) : NULL), + fixture_class_id_(fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory), + result_() {} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { delete factory_; } + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param: the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param: text representation of the test's value parameter, +// or NULL if this is not a value-parameterized test. +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory) { + TestInfo* const test_info = + new TestInfo(test_case_name, name, type_param, value_param, + fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; +} + +#if GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line) { + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; + + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors.GetString().c_str()); +} +#endif // GTEST_HAS_PARAM_TEST + +} // namespace internal + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestCase class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. +class TestNameIs { + public: + // Constructor. + // + // TestNameIs has NO default constructor. + explicit TestNameIs(const char* name) + : name_(name) {} + + // Returns true iff the test name of test_info matches name_. + bool operator()(const TestInfo * test_info) const { + return test_info && test_info->name() == name_; + } + + private: + std::string name_; +}; + +} // namespace + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#if GTEST_HAS_PARAM_TEST + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +#endif +} + +} // namespace internal + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfo::Run() { + if (!should_run_) return; + + // Tells UnitTest where to store test result. + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*this); + + const TimeInMillis start = internal::GetTimeInMillis(); + + impl->os_stack_trace_getter()->UponLeavingGTest(); + + // Creates the test object. + Test* const test = internal::HandleExceptionsInMethodIfSupported( + factory_, &internal::TestFactoryBase::CreateTest, + "the test fixture's constructor"); + + // Runs the test only if the test object was created and its + // constructor didn't generate a fatal failure. + if ((test != NULL) && !Test::HasFatalFailure()) { + // This doesn't throw as all user code that can throw are wrapped into + // exception handling code. + test->Run(); + } + + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + test, &Test::DeleteSelf_, "the test fixture's destructor"); + + result_.set_elapsed_time(internal::GetTimeInMillis() - start); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*this); + + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(NULL); +} + +// class TestCase + +// Gets the number of successful tests in this test case. +int TestCase::successful_test_count() const { + return CountIf(test_info_list_, TestPassed); +} + +// Gets the number of failed tests in this test case. +int TestCase::failed_test_count() const { + return CountIf(test_info_list_, TestFailed); +} + +int TestCase::disabled_test_count() const { + return CountIf(test_info_list_, TestDisabled); +} + +// Get the number of tests in this test case that should run. +int TestCase::test_to_run_count() const { + return CountIf(test_info_list_, ShouldRunTest); +} + +// Gets the number of all tests. +int TestCase::total_test_count() const { + return static_cast(test_info_list_.size()); +} + +// Creates a TestCase with the given name. +// +// Arguments: +// +// name: name of the test case +// a_type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase::TestCase(const char* a_name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) + : name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + elapsed_time_(0) { +} + +// Destructor of TestCase. +TestCase::~TestCase() { + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestCase::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Adds a test to this test case. Will delete the test upon +// destruction of the TestCase object. +void TestCase::AddTestInfo(TestInfo * test_info) { + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast(test_indices_.size())); +} + +// Runs every test in this TestCase. +void TestCase::Run() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_case(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + repeater->OnTestCaseStart(*this); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); + + const internal::TimeInMillis start = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start; + + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); + + repeater->OnTestCaseEnd(*this); + impl->set_current_test_case(NULL); +} + +// Clears the results of all tests in this test case. +void TestCase::ClearResult() { + ForEach(test_info_list_, TestInfo::ClearTestResult); +} + +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast(i); + } +} + +// Formats a countable noun. Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static std::string FormatCountableNoun(int count, + const char * singular_form, + const char * plural_form) { + return internal::String::Format("%d %s", count, + count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static std::string FormatTestCount(int test_count) { + return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test cases. +static std::string FormatTestCaseCount(int test_case_count) { + return FormatCountableNoun(test_case_count, "test case", "test cases"); +} + +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { + switch (type) { + case TestPartResult::kSuccess: + return "Success"; + + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: +#ifdef _MSC_VER + return "error: "; +#else + return "Failure\n"; +#endif + default: + return "Unknown result type"; + } +} + +// Prints a TestPartResult to an std::string. +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + +// Prints a TestPartResult. +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const std::string& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif +} + +// class PrettyUnitTestResultPrinter + +namespace internal { + +enum GTestColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GTestColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. +const char* GetAnsiColorCode(GTestColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + default: return NULL; + }; +} + +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns true iff Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { + const char* const gtest_color = GTEST_FLAG(color).c_str(); + + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#if GTEST_OS_WINDOWS + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "screen") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; +#endif // GTEST_OS_WINDOWS + } + + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS + const bool use_color = false; +#else + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + + if (!use_color) { + vprintf(fmt, args); + va_end(args); + return; + } + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + va_end(args); +} + +void PrintFullTestCommentIfPresent(const TestInfo& test_info) { + const char* const type_param = test_info.type_param(); + const char* const value_param = test_info.value_param(); + + if (type_param != NULL || value_param != NULL) { + printf(", where "); + if (type_param != NULL) { + printf("TypeParam = %s", type_param); + if (value_param != NULL) + printf(" and "); + } + if (value_param != NULL) { + printf("GetParam() = %s", value_param); + } + } +} + +// This class implements the TestEventListener interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public TestEventListener { + public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char * test_case, const char * test) { + printf("%s.%s", test_case, test); + } + + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} + + private: + static void PrintFailedTests(const UnitTest& unit_test); +}; + + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); + + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!String::CStringEquals(filter, kUniversalFilter)) { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %d of %s.\n", + static_cast(shard_index) + 1, + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } + + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case.name()); + if (test_case.type_param() == NULL) { + printf("\n"); + } else { + printf(", where TypeParam = %s\n", test_case.type_param()); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_info.test_case_name(), test_info.name()); + printf("\n"); + fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } else { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_info.test_case_name(), test_info.name()); + if (test_info.result()->Failed()) + PrintFullTestCommentIfPresent(test_info); + + if (GTEST_FLAG(print_time)) { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()).c_str()); + } else { + printf("\n"); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; + + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case.name(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); +} + +// Internal helper for printing the list of failed tests. +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_case.name(), test_info.name()); + PrintFullTestCommentIfPresent(test_info); + printf("\n"); + } + } +} + +void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } + + int num_disabled = unit_test.disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (!num_failures) { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class TestEventRepeater +// +// This class forwards events to other event listeners. +class TestEventRepeater : public TestEventListener { + public: + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); + + private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector listeners_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); +}; + +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete); +} + +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); +} + +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} + +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) + +#undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ + +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit XmlUnitTestResultPrinter(const char* output_file); + + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + + private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) { + return c == 0x9 || c == 0xA || c == 0xD; + } + + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) { + return IsNormalizableWhitespace(c) || c >= 0x20; + } + + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static std::string EscapeXml(const char* str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static string RemoveInvalidXmlCharacters(const string& str); + + // Convenience wrapper around EscapeXml when str is an attribute value. + static std::string EscapeXmlAttribute(const char* str) { + return EscapeXml(str, true); + } + + // Convenience wrapper around EscapeXml when str is not an attribute value. + static std::string EscapeXmlText(const char* str) { + return EscapeXml(str, false); + } + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); + + // Prints an XML representation of a TestCase object + static void PrintXmlTestCase(FILE* out, const TestCase& test_case); + + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the std::string is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static std::string TestPropertiesAsXmlAttributes(const TestResult& result); + + // The output file. + const std::string output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.c_str() == NULL || output_file_.empty()) { + fprintf(stderr, "XML output file may not be null\n"); + fflush(stderr); + exit(EXIT_FAILURE); + } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* xmlout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + xmlout = posix::FOpen(output_file_.c_str(), "w"); + } + if (xmlout == NULL) { + // TODO(wan): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + fprintf(stderr, + "Unable to open file \"%s\"\n", + output_file_.c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + PrintXmlUnitTest(xmlout, unit_test); + fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str. If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +// TODO(wan): It might be nice to have a minimally invasive, human-readable +// escaping scheme for invalid characters, rather than dropping them. +std::string XmlUnitTestResultPrinter::EscapeXml( + const char* str, bool is_attribute) { + Message m; + + if (str != NULL) { + for (const char* src = str; *src; ++src) { + switch (*src) { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(*src)) { + if (is_attribute && IsNormalizableWhitespace(*src)) + m << String::Format("&#x%02X;", unsigned(*src)); + else + m << *src; + } + break; + } + } + } + + return m.GetString(); +} + +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const string& str) { + string output; + output.reserve(str.size()); + for (string::const_iterator it = str.begin(); it != str.end(); ++it) + if (IsValidXmlCharacter(*it)) + output.push_back(*it); + + return output; +} + +// The following routines generate an XML representation of a UnitTest +// object. +// +// This is how Google Test concepts map to the DTD: +// +// <-- corresponds to a UnitTest object +// <-- corresponds to a TestCase object +// <-- corresponds to a TestInfo object +// ... +// ... +// ... +// <-- individual assertion failures +// +// +// + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << ms/1000.0; + return ss.str(); +} + +// Converts the given epoch time in milliseconds to a date string in the ISO +// 8601 format, without the timezone information. +std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { + // Using non-reentrant version as localtime_r is not portable. + time_t seconds = static_cast(ms / 1000); +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996 + // (function or variable may be unsafe). + const struct tm* const time_struct = localtime(&seconds); // NOLINT +# pragma warning(pop) // Restores the warning state again. +#else + const struct tm* const time_struct = localtime(&seconds); // NOLINT +#endif + if (time_struct == NULL) + return ""; // Invalid ms value + + return String::Format("%d-%02d-%02dT%02d:%02d:%02d", // YYYY-MM-DDThh:mm:ss + time_struct->tm_year + 1900, + time_struct->tm_mon + 1, + time_struct->tm_mday, + time_struct->tm_hour, + time_struct->tm_min, + time_struct->tm_sec); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << ""); + if (next_segment != NULL) { + stream->write( + segment, static_cast(next_segment - segment)); + *stream << "]]>]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} + +// Prints an XML representation of a TestInfo object. +// TODO(wan): There is also value in printing properties with the plain printer. +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + *stream << " \n"; + } + const string location = internal::FormatCompilerIndependentFileLocation( + part.file_name(), part.line_number()); + const string summary = location + "\n" + part.summary(); + *stream << " "; + const string detail = location + "\n" + part.message(); + OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); + *stream << "\n"; + } + } + + if (failures == 0) + *stream << " />\n"; + else + *stream << " \n"; +} + +// Prints an XML representation of a TestCase object +void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, + const TestCase& test_case) { + fprintf(out, + " \n", + FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str()); + for (int i = 0; i < test_case.total_test_count(); ++i) { + ::std::stringstream stream; + OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i)); + fprintf(out, "%s", StringStreamToString(&stream).c_str()); + } + fprintf(out, " \n"); +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, + const UnitTest& unit_test) { + fprintf(out, "\n"); + fprintf(out, + "\n"); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + PrintXmlTestCase(out, *unit_test.GetTestCase(i)); + fprintf(out, "\n"); +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End XmlUnitTestResultPrinter + +#if GTEST_CAN_STREAM_RESULTS_ + +// Streams test results to the given port on the given host machine. +class StreamingListener : public EmptyTestEventListener { + public: + // Escapes '=', '&', '%', and '\n' characters in str as "%xx". + static string UrlEncode(const char* str); + + StreamingListener(const string& host, const string& port) + : sockfd_(-1), host_name_(host), port_num_(port) { + MakeConnection(); + Send("gtest_streaming_protocol_version=1.0\n"); + } + + virtual ~StreamingListener() { + if (sockfd_ != -1) + CloseConnection(); + } + + void OnTestProgramStart(const UnitTest& /* unit_test */) { + Send("event=TestProgramStart\n"); + } + + void OnTestProgramEnd(const UnitTest& unit_test) { + // Note that Google Test current only report elapsed time for each + // test iteration, not for the entire test program. + Send(String::Format("event=TestProgramEnd&passed=%d\n", + unit_test.Passed())); + + // Notify the streaming server to stop. + CloseConnection(); + } + + void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { + Send(String::Format("event=TestIterationStart&iteration=%d\n", + iteration)); + } + + void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { + Send(String::Format("event=TestIterationEnd&passed=%d&elapsed_time=%sms\n", + unit_test.Passed(), + StreamableToString(unit_test.elapsed_time()).c_str())); + } + + void OnTestCaseStart(const TestCase& test_case) { + Send(String::Format("event=TestCaseStart&name=%s\n", test_case.name())); + } + + void OnTestCaseEnd(const TestCase& test_case) { + Send(String::Format("event=TestCaseEnd&passed=%d&elapsed_time=%sms\n", + test_case.Passed(), + StreamableToString(test_case.elapsed_time()).c_str())); + } + + void OnTestStart(const TestInfo& test_info) { + Send(String::Format("event=TestStart&name=%s\n", test_info.name())); + } + + void OnTestEnd(const TestInfo& test_info) { + Send(String::Format( + "event=TestEnd&passed=%d&elapsed_time=%sms\n", + (test_info.result())->Passed(), + StreamableToString((test_info.result())->elapsed_time()).c_str())); + } + + void OnTestPartResult(const TestPartResult& test_part_result) { + const char* file_name = test_part_result.file_name(); + if (file_name == NULL) + file_name = ""; + Send(String::Format("event=TestPartResult&file=%s&line=%d&message=", + UrlEncode(file_name).c_str(), + test_part_result.line_number())); + Send(UrlEncode(test_part_result.message()) + "\n"); + } + + private: + // Creates a client socket and connects to the server. + void MakeConnection(); + + // Closes the socket. + void CloseConnection() { + GTEST_CHECK_(sockfd_ != -1) + << "CloseConnection() can be called only when there is a connection."; + + close(sockfd_); + sockfd_ = -1; + } + + // Sends a string to the socket. + void Send(const string& message) { + GTEST_CHECK_(sockfd_ != -1) + << "Send() can be called only when there is a connection."; + + const int len = static_cast(message.length()); + if (write(sockfd_, message.c_str(), len) != len) { + GTEST_LOG_(WARNING) + << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; + } + } + + int sockfd_; // socket file descriptor + const string host_name_; + const string port_num_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); +}; // class StreamingListener + +// Checks if str contains '=', '&', '%' or '\n' characters. If yes, +// replaces them by "%xx" where xx is their hexadecimal value. For +// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) +// in both time and space -- important as the input str may contain an +// arbitrarily long test failure message and stack trace. +string StreamingListener::UrlEncode(const char* str) { + string result; + result.reserve(strlen(str) + 1); + for (char ch = *str; ch != '\0'; ch = *++str) { + switch (ch) { + case '%': + case '=': + case '&': + case '\n': + result.append(String::Format("%%%02x", static_cast(ch))); + break; + default: + result.push_back(ch); + break; + } + } + return result; +} + +void StreamingListener::MakeConnection() { + GTEST_CHECK_(sockfd_ == -1) + << "MakeConnection() can't be called when there is already a connection."; + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. + hints.ai_socktype = SOCK_STREAM; + addrinfo* servinfo = NULL; + + // Use the getaddrinfo() to get a linked list of IP addresses for + // the given host name. + const int error_num = getaddrinfo( + host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); + if (error_num != 0) { + GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " + << gai_strerror(error_num); + } + + // Loop through all the results and connect to the first we can. + for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; + cur_addr = cur_addr->ai_next) { + sockfd_ = socket( + cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); + if (sockfd_ != -1) { + // Connect the client socket to the server socket. + if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { + close(sockfd_); + sockfd_ = -1; + } + } + } + + freeaddrinfo(servinfo); // all done with this structure + + if (sockfd_ == -1) { + GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " + << host_name_ << ":" << port_num_; + } +} + +// End of class Streaming Listener +#endif // GTEST_CAN_STREAM_RESULTS__ + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message = message.GetString(); + + UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +ScopedTrace::~ScopedTrace() + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + UnitTest::GetInstance()->PopGTestTrace(); +} + + +// class OsStackTraceGetter + +// Returns the current OS stack trace as an std::string. Parameters: +// +// max_depth - the maximum number of stack frames to be included +// in the trace. +// skip_count - the number of top frames to be skipped; doesn't count +// against max_depth. +// +string OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, + int /* skip_count */) + GTEST_LOCK_EXCLUDED_(mutex_) { + return ""; +} + +void OsStackTraceGetter::UponLeavingGTest() + GTEST_LOCK_EXCLUDED_(mutex_) { +} + +const char* const +OsStackTraceGetter::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +} // namespace internal + +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + +// class UnitTest + +// Gets the singleton UnitTest object. The first time this method is +// called, a UnitTest object is constructed and returned. Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest * UnitTest::GetInstance() { + // When compiled with MSVC 7.1 in optimized mode, destroying the + // UnitTest object upon exiting the program messes up the exit code, + // causing successful tests to appear failed. We have to use a + // different implementation in this case to bypass the compiler bug. + // This implementation makes the compiler happy, at the cost of + // leaking the UnitTest object. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) + static UnitTest* const instance = new UnitTest; + return instance; +#else + static UnitTest instance; + return &instance; +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) +} + +// Gets the number of successful test cases. +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_case_count(); +} + +// Gets the number of failed test cases. +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_case_count(); +} + +// Gets the number of all test cases. +int UnitTest::total_test_case_count() const { + return impl()->total_test_case_count(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTest::test_case_to_run_count() const { + return impl()->test_case_to_run_count(); +} + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the time of the test program start, in ms from the start of the +// UNIX epoch. +internal::TimeInMillis UnitTest::start_timestamp() const { + return impl()->start_timestamp(); +} + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true iff the unit test passed (i.e. all test cases passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true iff the unit test failed (i.e. some test case failed +// or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + +// Registers and returns a global test environment. When a test +// program is run, all global test environments will be set-up in the +// order they were registered. After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { + if (env == NULL) { + return NULL; + } + + impl_->environments().push_back(env); + return env; +} + +// Adds a TestPartResult to the current TestResult object. All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results. The user code should use the +// assertion macros instead of calling this directly. +void UnitTest::AddTestPartResult( + TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) + GTEST_LOCK_EXCLUDED_(mutex_) { + Message msg; + msg << message; + + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (int i = static_cast(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } + + if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { + msg << internal::kStackTraceMarker << os_stack_trace; + } + + const TestPartResult result = + TestPartResult(result_type, file_name, line_number, + msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); + + if (result_type != TestPartResult::kSuccess) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#else + // Dereference NULL through a volatile pointer to prevent the compiler + // from removing. We use this rather than abort() or __builtin_trap() for + // portability: Symbian doesn't implement abort() well, and some debuggers + // don't correctly trap abort(). + *static_cast(NULL) = 1; +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } + } +} + +// Creates and adds a property to the current TestResult. If a property matching +// the supplied value already exists, updates its value instead. +void UnitTest::RecordPropertyForCurrentTest(const char* key, + const char* value) { + const TestProperty test_property(key, value); + impl_->current_test_result()->RecordProperty(test_property); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { + // Captures the value of GTEST_FLAG(catch_exceptions). This value will be + // used for the duration of the program. + impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); + +#if GTEST_HAS_SEH + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected. + if (impl()->catch_exceptions() || in_death_test_child_process) { +# if !GTEST_OS_WINDOWS_MOBILE + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +# endif // !GTEST_OS_WINDOWS_MOBILE + +# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +# endif + +# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +# endif + } +#endif // GTEST_HAS_SEH + + return internal::HandleExceptionsInMethodIfSupported( + impl(), + &internal::UnitTestImpl::RunAllTests, + "auxiliary test code (environments or event listeners)") ? 0 : 1; +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { + return impl_->original_working_dir_.c_str(); +} + +// Returns the TestCase object for the test that's currently running, +// or NULL if no test is running. +const TestCase* UnitTest::current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_case(); +} + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +const TestInfo* UnitTest::current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); +} + +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +#if GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +internal::ParameterizedTestCaseRegistry& + UnitTest::parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_) { + return impl_->parameterized_test_registry(); +} +#endif // GTEST_HAS_PARAM_TEST + +// Creates an empty UnitTest. +UnitTest::UnitTest() { + impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { + delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +void UnitTest::PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) + : parent_(parent), +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4355) // Temporarily disables warning 4355 + // (using this in initializer). + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +# pragma warning(pop) // Restores the warning state again. +#else + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#endif // _MSC_VER + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), +#if GTEST_HAS_PARAM_TEST + parameterized_test_registry_(), + parameterized_tests_registered_(false), +#endif // GTEST_HAS_PARAM_TEST + last_death_test_case_(-1), + current_test_case_(NULL), + current_test_info_(NULL), + ad_hoc_test_result_(), + os_stack_trace_getter_(NULL), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. + start_timestamp_(0), + elapsed_time_(0), +#if GTEST_HAS_DEATH_TEST + internal_run_death_test_flag_(NULL), + death_test_factory_(new DefaultDeathTestFactory), +#endif + // Will be overridden by the flag before first use. + catch_exceptions_(false) { + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); +} + +UnitTestImpl::~UnitTestImpl() { + // Deletes every TestCase. + ForEach(test_cases_, internal::Delete); + + // Deletes every Environment. + ForEach(environments_, internal::Delete); + + delete os_stack_trace_getter_; +} + +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const std::string& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +#if GTEST_CAN_STREAM_RESULTS_ +// Initializes event listeners for streaming test results in string form. +// Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureStreamingOutput() { + const std::string& target = GTEST_FLAG(stream_result_to); + if (!target.empty()) { + const size_t pos = target.find(':'); + if (pos != std::string::npos) { + listeners()->Append(new StreamingListener(target.substr(0, pos), + target.substr(pos+1))); + } else { + printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", + target.c_str()); + fflush(stdout); + } + } +} +#endif // GTEST_CAN_STREAM_RESULTS_ + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Configures listeners for streaming test results to the specified server. + ConfigureStreamingOutput(); +#endif // GTEST_CAN_STREAM_RESULTS_ + } +} + +// A predicate that checks the name of a TestCase against a known +// value. +// +// This is used for implementation of the UnitTest class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestCaseNameIs is copyable. +class TestCaseNameIs { + public: + // Constructor. + explicit TestCaseNameIs(const std::string& name) + : name_(name) {} + + // Returns true iff the name of test_case matches name_. + bool operator()(const TestCase* test_case) const { + return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; + } + + private: + std::string name_; +}; + +// Finds and returns a TestCase with the given name. If one doesn't +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. +// +// Arguments: +// +// test_case_name: name of the test case +// type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) { + // Can we find a TestCase with the given name? + const std::vector::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); + + if (test_case != test_cases_.end()) + return *test_case; + + // No. Let's create one. + TestCase* const new_test_case = + new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); + + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(test_case_name, + kDeathTestCaseFilter)) { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } else { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); + } + + test_case_indices_.push_back(static_cast(test_case_indices_.size())); + return new_test_case; +} + +// Helpers for setting up / tearing down the given environment. They +// are for use in the ForEach() function. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns true if all tests are successful. If any exception is +// thrown during a test, the test is considered to be failed, but the +// rest of the tests will still be run. +// +// When parameterized tests are enabled, it expands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +bool UnitTestImpl::RunAllTests() { + // Makes sure InitGoogleTest() was called. + if (!GTestIsInitialized()) { + printf("%s", + "\nThis test program did NOT call ::testing::InitGoogleTest " + "before calling RUN_ALL_TESTS(). Please fix it.\n"); + return false; + } + + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return true; + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + + // True iff we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; + +#if GTEST_HAS_DEATH_TEST + in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +#endif // GTEST_HAS_DEATH_TEST + + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return true; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + + // True iff at least one test has failed. + bool failed = false; + + TestEventListener* repeater = listeners()->repeater(); + + start_timestamp_ = GetTimeInMillis(); + repeater->OnTestProgramStart(*parent_); + + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool forever = repeat < 0; + for (int i = 0; forever || i != repeat; i++) { + // We want to preserve failures generated by ad-hoc test + // assertions executed before RUN_ALL_TESTS(). + ClearNonAdHocTestResult(); + + const TimeInMillis start = GetTimeInMillis(); + + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + + // Runs each test case if there is at least one test to run. + if (has_tests_to_run) { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + + // Runs the tests only if there was no fatal failure during global + // set-up. + if (!Test::HasFatalFailure()) { + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); + } + } + + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } + + elapsed_time_ = GetTimeInMillis() - start; + + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); + + // Gets the result and clears it. + if (!Passed()) { + failed = true; + } + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } + + repeater->OnTestProgramEnd(*parent_); + + return !failed; +} + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. +// Returns the number of tests that should run. +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; + const std::string &test_case_name = test_case->name(); + test_case->set_should_run(false); + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; + const std::string test_name(test_info->name()); + // A test is disabled if test case name or test name matches + // kDisableTestFilter. + const bool is_disabled = + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); + test_info->is_disabled_ = is_disabled; + + const bool matches_filter = + internal::UnitTestOptions::FilterMatchesTest(test_case_name, + test_name); + test_info->matches_filter_ = matches_filter; + + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; + + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->should_run_ = is_selected; + test_case->set_should_run(test_case->should_run() || is_selected); + } + } + return num_selected_tests; +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter_) { + if (!printed_test_case_name) { + printed_test_case_name = true; + printf("%s.\n", test_case->name()); + } + printf(" %s\n", test_info->name()); + } + } + } + fflush(stdout); +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( + OsStackTraceGetterInterface* getter) { + if (os_stack_trace_getter_ != getter) { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { + if (os_stack_trace_getter_ == NULL) { + os_stack_trace_getter_ = new OsStackTraceGetter; + } + + return os_stack_trace_getter_; +} + +// Returns the TestResult for the test that's currently running, or +// the TestResult for the ad hoc test if no test is running. +TestResult* UnitTestImpl::current_test_result() { + return current_test_info_ ? + &(current_test_info_->result_) : &ad_hoc_test_result_; +} + +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast(test_cases_.size()), &test_case_indices_); + + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast(i); + } +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to +// suppress unreachable code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +const char* ParseFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; + + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, std::string* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", std::string(str, p).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +#if GTEST_CAN_STREAM_RESULTS_ +" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" +" Stream test results to the given server.\n" +#endif // GTEST_CAN_STREAM_RESULTS_ +"\n" +"Assertion Behavior:\n" +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" +" Do not report exceptions as test failures. Instead, allow them\n" +" to crash the program or throw a pop-up (on Windows).\n" +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. The type parameter CharType can be +// instantiated to either char or wchar_t. +template +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + for (int i = 1; i < *argc; i++) { + const std::string arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; + + // Do we see a Google Test flag? + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, + >EST_FLAG(throw_on_failure)) + ) { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template +void InitGoogleTestImpl(int* argc, CharType** argv) { + g_init_gtest_count++; + + // We don't want to run the initialization code twice. + if (g_init_gtest_count != 1) return; + + if (*argc <= 0) return; + + internal::g_executable_path = internal::StreamableToString(argv[0]); + +#if GTEST_HAS_DEATH_TEST + + g_argvs.clear(); + for (int i = 0; i != *argc; i++) { + g_argvs.push_back(StreamableToString(argv[i])); + } + +#endif // GTEST_HAS_DEATH_TEST + + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); +} + +} // namespace internal + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest_main.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest_main.cc new file mode 100644 index 0000000..f302822 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/src/gtest_main.cc @@ -0,0 +1,38 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +#include + +#include "gtest/gtest.h" + +GTEST_API_ int main(int argc, char **argv) { + printf("Running main() from gtest_main.cc\n"); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-death-test_ex_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-death-test_ex_test.cc new file mode 100644 index 0000000..b50a13d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-death-test_ex_test.cc @@ -0,0 +1,93 @@ +// Copyright 2010, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests that verify interaction of exceptions and death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_HAS_SEH +# include // For RaiseException(). +# endif + +# include "gtest/gtest-spi.h" + +# if GTEST_HAS_EXCEPTIONS + +# include // For std::exception. + +// Tests that death tests report thrown exceptions as failures and that the +// exceptions do not escape death test macros. +TEST(CxxExceptionDeathTest, ExceptionIsFailure) { + try { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw 1, ""), "threw an exception"); + } catch (...) { // NOLINT + FAIL() << "An exception escaped a death test macro invocation " + << "with catch_exceptions " + << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); + } +} + +class TestException : public std::exception { + public: + virtual const char* what() const throw() { return "exceptional message"; } +}; + +TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) { + // Verifies that the exception message is quoted in the failure text. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), + "exceptional message"); + // Verifies that the location is mentioned in the failure text. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), + "gtest-death-test_ex_test.cc"); +} +# endif // GTEST_HAS_EXCEPTIONS + +# if GTEST_HAS_SEH +// Tests that enabling interception of SEH exceptions with the +// catch_exceptions flag does not interfere with SEH exceptions being +// treated as death by death tests. +TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) { + EXPECT_DEATH(RaiseException(42, 0x0, 0, NULL), "") + << "with catch_exceptions " + << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); +} +# endif + +#endif // GTEST_HAS_DEATH_TEST + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + testing::GTEST_FLAG(catch_exceptions) = GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0; + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-death-test_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-death-test_test.cc new file mode 100644 index 0000000..e42c013 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-death-test_test.cc @@ -0,0 +1,1368 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/gtest.h" +#include "gtest/internal/gtest-filepath.h" + +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_WINDOWS +# include // For chdir(). +# else +# include +# include // For waitpid. +# include // For std::numeric_limits. +# endif // GTEST_OS_WINDOWS + +# include +# include +# include + +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + +# include "gtest/gtest-spi.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +# define GTEST_IMPLEMENTATION_ 1 +# include "src/gtest-internal-inl.h" +# undef GTEST_IMPLEMENTATION_ + +namespace posix = ::testing::internal::posix; + +using testing::Message; +using testing::internal::DeathTest; +using testing::internal::DeathTestFactory; +using testing::internal::FilePath; +using testing::internal::GetLastErrnoDescription; +using testing::internal::GetUnitTestImpl; +using testing::internal::InDeathTestChild; +using testing::internal::ParseNaturalNumber; + +namespace testing { +namespace internal { + +// A helper class whose objects replace the death test factory for a +// single UnitTest object during their lifetimes. +class ReplaceDeathTestFactory { + public: + explicit ReplaceDeathTestFactory(DeathTestFactory* new_factory) + : unit_test_impl_(GetUnitTestImpl()) { + old_factory_ = unit_test_impl_->death_test_factory_.release(); + unit_test_impl_->death_test_factory_.reset(new_factory); + } + + ~ReplaceDeathTestFactory() { + unit_test_impl_->death_test_factory_.release(); + unit_test_impl_->death_test_factory_.reset(old_factory_); + } + private: + // Prevents copying ReplaceDeathTestFactory objects. + ReplaceDeathTestFactory(const ReplaceDeathTestFactory&); + void operator=(const ReplaceDeathTestFactory&); + + UnitTestImpl* unit_test_impl_; + DeathTestFactory* old_factory_; +}; + +} // namespace internal +} // namespace testing + +void DieWithMessage(const ::std::string& message) { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); // Make sure the text is printed before the process exits. + + // We call _exit() instead of exit(), as the former is a direct + // system call and thus safer in the presence of threads. exit() + // will invoke user-defined exit-hooks, which may do dangerous + // things that conflict with death tests. + // + // Some compilers can recognize that _exit() never returns and issue the + // 'unreachable code' warning for code following this function, unless + // fooled by a fake condition. + if (AlwaysTrue()) + _exit(1); +} + +void DieInside(const ::std::string& function) { + DieWithMessage("death inside " + function + "()."); +} + +// Tests that death tests work. + +class TestForDeathTest : public testing::Test { + protected: + TestForDeathTest() : original_dir_(FilePath::GetCurrentDir()) {} + + virtual ~TestForDeathTest() { + posix::ChDir(original_dir_.c_str()); + } + + // A static member function that's expected to die. + static void StaticMemberFunction() { DieInside("StaticMemberFunction"); } + + // A method of the test fixture that may die. + void MemberFunction() { + if (should_die_) + DieInside("MemberFunction"); + } + + // True iff MemberFunction() should die. + bool should_die_; + const FilePath original_dir_; +}; + +// A class with a member function that may die. +class MayDie { + public: + explicit MayDie(bool should_die) : should_die_(should_die) {} + + // A member function that may die. + void MemberFunction() const { + if (should_die_) + DieInside("MayDie::MemberFunction"); + } + + private: + // True iff MemberFunction() should die. + bool should_die_; +}; + +// A global function that's expected to die. +void GlobalFunction() { DieInside("GlobalFunction"); } + +// A non-void function that's expected to die. +int NonVoidFunction() { + DieInside("NonVoidFunction"); + return 1; +} + +// A unary function that may die. +void DieIf(bool should_die) { + if (should_die) + DieInside("DieIf"); +} + +// A binary function that may die. +bool DieIfLessThan(int x, int y) { + if (x < y) { + DieInside("DieIfLessThan"); + } + return true; +} + +// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. +void DeathTestSubroutine() { + EXPECT_DEATH(GlobalFunction(), "death.*GlobalFunction"); + ASSERT_DEATH(GlobalFunction(), "death.*GlobalFunction"); +} + +// Death in dbg, not opt. +int DieInDebugElse12(int* sideeffect) { + if (sideeffect) *sideeffect = 12; + +# ifndef NDEBUG + + DieInside("DieInDebugElse12"); + +# endif // NDEBUG + + return 12; +} + +# if GTEST_OS_WINDOWS + +// Tests the ExitedWithCode predicate. +TEST(ExitStatusPredicateTest, ExitedWithCode) { + // On Windows, the process's exit code is the same as its exit status, + // so the predicate just compares the its input with its parameter. + EXPECT_TRUE(testing::ExitedWithCode(0)(0)); + EXPECT_TRUE(testing::ExitedWithCode(1)(1)); + EXPECT_TRUE(testing::ExitedWithCode(42)(42)); + EXPECT_FALSE(testing::ExitedWithCode(0)(1)); + EXPECT_FALSE(testing::ExitedWithCode(1)(0)); +} + +# else + +// Returns the exit status of a process that calls _exit(2) with a +// given exit code. This is a helper function for the +// ExitStatusPredicateTest test suite. +static int NormalExitStatus(int exit_code) { + pid_t child_pid = fork(); + if (child_pid == 0) { + _exit(exit_code); + } + int status; + waitpid(child_pid, &status, 0); + return status; +} + +// Returns the exit status of a process that raises a given signal. +// If the signal does not cause the process to die, then it returns +// instead the exit status of a process that exits normally with exit +// code 1. This is a helper function for the ExitStatusPredicateTest +// test suite. +static int KilledExitStatus(int signum) { + pid_t child_pid = fork(); + if (child_pid == 0) { + raise(signum); + _exit(1); + } + int status; + waitpid(child_pid, &status, 0); + return status; +} + +// Tests the ExitedWithCode predicate. +TEST(ExitStatusPredicateTest, ExitedWithCode) { + const int status0 = NormalExitStatus(0); + const int status1 = NormalExitStatus(1); + const int status42 = NormalExitStatus(42); + const testing::ExitedWithCode pred0(0); + const testing::ExitedWithCode pred1(1); + const testing::ExitedWithCode pred42(42); + EXPECT_PRED1(pred0, status0); + EXPECT_PRED1(pred1, status1); + EXPECT_PRED1(pred42, status42); + EXPECT_FALSE(pred0(status1)); + EXPECT_FALSE(pred42(status0)); + EXPECT_FALSE(pred1(status42)); +} + +// Tests the KilledBySignal predicate. +TEST(ExitStatusPredicateTest, KilledBySignal) { + const int status_segv = KilledExitStatus(SIGSEGV); + const int status_kill = KilledExitStatus(SIGKILL); + const testing::KilledBySignal pred_segv(SIGSEGV); + const testing::KilledBySignal pred_kill(SIGKILL); + EXPECT_PRED1(pred_segv, status_segv); + EXPECT_PRED1(pred_kill, status_kill); + EXPECT_FALSE(pred_segv(status_kill)); + EXPECT_FALSE(pred_kill(status_segv)); +} + +# endif // GTEST_OS_WINDOWS + +// Tests that the death test macros expand to code which may or may not +// be followed by operator<<, and that in either case the complete text +// comprises only a single C++ statement. +TEST_F(TestForDeathTest, SingleStatement) { + if (AlwaysFalse()) + // This would fail if executed; this is a compilation test only + ASSERT_DEATH(return, ""); + + if (AlwaysTrue()) + EXPECT_DEATH(_exit(1), ""); + else + // This empty "else" branch is meant to ensure that EXPECT_DEATH + // doesn't expand into an "if" statement without an "else" + ; + + if (AlwaysFalse()) + ASSERT_DEATH(return, "") << "did not die"; + + if (AlwaysFalse()) + ; + else + EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3; +} + +void DieWithEmbeddedNul() { + fprintf(stderr, "Hello%cmy null world.\n", '\0'); + fflush(stderr); + _exit(1); +} + +# if GTEST_USES_PCRE +// Tests that EXPECT_DEATH and ASSERT_DEATH work when the error +// message has a NUL character in it. +TEST_F(TestForDeathTest, EmbeddedNulInMessage) { + // TODO(wan@google.com): doesn't support matching strings + // with embedded NUL characters - find a way to workaround it. + EXPECT_DEATH(DieWithEmbeddedNul(), "my null world"); + ASSERT_DEATH(DieWithEmbeddedNul(), "my null world"); +} +# endif // GTEST_USES_PCRE + +// Tests that death test macros expand to code which interacts well with switch +// statements. +TEST_F(TestForDeathTest, SwitchStatement) { +// Microsoft compiler usually complains about switch statements without +// case labels. We suppress that warning for this test. +# ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4065) +# endif // _MSC_VER + + switch (0) + default: + ASSERT_DEATH(_exit(1), "") << "exit in default switch handler"; + + switch (0) + case 0: + EXPECT_DEATH(_exit(1), "") << "exit in switch case"; + +# ifdef _MSC_VER +# pragma warning(pop) +# endif // _MSC_VER +} + +// Tests that a static member function can be used in a "fast" style +// death test. +TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); +} + +// Tests that a method of the test fixture can be used in a "fast" +// style death test. +TEST_F(TestForDeathTest, MemberFunctionFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + should_die_ = true; + EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); +} + +void ChangeToRootDir() { posix::ChDir(GTEST_PATH_SEP_); } + +// Tests that death tests work even if the current directory has been +// changed. +TEST_F(TestForDeathTest, FastDeathTestInChangedDir) { + testing::GTEST_FLAG(death_test_style) = "fast"; + + ChangeToRootDir(); + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + + ChangeToRootDir(); + ASSERT_DEATH(_exit(1), ""); +} + +# if GTEST_OS_LINUX +void SigprofAction(int, siginfo_t*, void*) { /* no op */ } + +// Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms). +void SetSigprofActionAndTimer() { + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 1; + timer.it_value = timer.it_interval; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); + struct sigaction signal_action; + memset(&signal_action, 0, sizeof(signal_action)); + sigemptyset(&signal_action.sa_mask); + signal_action.sa_sigaction = SigprofAction; + signal_action.sa_flags = SA_RESTART | SA_SIGINFO; + ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, NULL)); +} + +// Disables ITIMER_PROF timer and ignores SIGPROF signal. +void DisableSigprofActionAndTimer(struct sigaction* old_signal_action) { + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + timer.it_value = timer.it_interval; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); + struct sigaction signal_action; + memset(&signal_action, 0, sizeof(signal_action)); + sigemptyset(&signal_action.sa_mask); + signal_action.sa_handler = SIG_IGN; + ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, old_signal_action)); +} + +// Tests that death tests work when SIGPROF handler and timer are set. +TEST_F(TestForDeathTest, FastSigprofActionSet) { + testing::GTEST_FLAG(death_test_style) = "fast"; + SetSigprofActionAndTimer(); + EXPECT_DEATH(_exit(1), ""); + struct sigaction old_signal_action; + DisableSigprofActionAndTimer(&old_signal_action); + EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); +} + +TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + SetSigprofActionAndTimer(); + EXPECT_DEATH(_exit(1), ""); + struct sigaction old_signal_action; + DisableSigprofActionAndTimer(&old_signal_action); + EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); +} +# endif // GTEST_OS_LINUX + +// Repeats a representative sample of death tests in the "threadsafe" style: + +TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); +} + +TEST_F(TestForDeathTest, MemberFunctionThreadsafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + should_die_ = true; + EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); +} + +TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + + for (int i = 0; i < 3; ++i) + EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i; +} + +TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + + ChangeToRootDir(); + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + + ChangeToRootDir(); + ASSERT_DEATH(_exit(1), ""); +} + +TEST_F(TestForDeathTest, MixedStyles) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_DEATH(_exit(1), ""); + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(_exit(1), ""); +} + +namespace { + +bool pthread_flag; + +void SetPthreadFlag() { + pthread_flag = true; +} + +} // namespace + +# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD + +TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { + if (!testing::GTEST_FLAG(death_test_use_fork)) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + pthread_flag = false; + ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, NULL, NULL)); + ASSERT_DEATH(_exit(1), ""); + ASSERT_FALSE(pthread_flag); + } +} + +# endif // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD + +// Tests that a method of another class can be used in a death test. +TEST_F(TestForDeathTest, MethodOfAnotherClass) { + const MayDie x(true); + ASSERT_DEATH(x.MemberFunction(), "MayDie\\:\\:MemberFunction"); +} + +// Tests that a global function can be used in a death test. +TEST_F(TestForDeathTest, GlobalFunction) { + EXPECT_DEATH(GlobalFunction(), "GlobalFunction"); +} + +// Tests that any value convertible to an RE works as a second +// argument to EXPECT_DEATH. +TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) { + static const char regex_c_str[] = "GlobalFunction"; + EXPECT_DEATH(GlobalFunction(), regex_c_str); + + const testing::internal::RE regex(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex); + +# if GTEST_HAS_GLOBAL_STRING + + const string regex_str(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex_str); + +# endif // GTEST_HAS_GLOBAL_STRING + + const ::std::string regex_std_str(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex_std_str); +} + +// Tests that a non-void function can be used in a death test. +TEST_F(TestForDeathTest, NonVoidFunction) { + ASSERT_DEATH(NonVoidFunction(), "NonVoidFunction"); +} + +// Tests that functions that take parameter(s) can be used in a death test. +TEST_F(TestForDeathTest, FunctionWithParameter) { + EXPECT_DEATH(DieIf(true), "DieIf\\(\\)"); + EXPECT_DEATH(DieIfLessThan(2, 3), "DieIfLessThan"); +} + +// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. +TEST_F(TestForDeathTest, OutsideFixture) { + DeathTestSubroutine(); +} + +// Tests that death tests can be done inside a loop. +TEST_F(TestForDeathTest, InsideLoop) { + for (int i = 0; i < 5; i++) { + EXPECT_DEATH(DieIfLessThan(-1, i), "DieIfLessThan") << "where i == " << i; + } +} + +// Tests that a compound statement can be used in a death test. +TEST_F(TestForDeathTest, CompoundStatement) { + EXPECT_DEATH({ // NOLINT + const int x = 2; + const int y = x + 1; + DieIfLessThan(x, y); + }, + "DieIfLessThan"); +} + +// Tests that code that doesn't die causes a death test to fail. +TEST_F(TestForDeathTest, DoesNotDie) { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(DieIf(false), "DieIf"), + "failed to die"); +} + +// Tests that a death test fails when the error message isn't expected. +TEST_F(TestForDeathTest, ErrorMessageMismatch) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(DieIf(true), "DieIfLessThan") << "End of death test message."; + }, "died but not with expected error"); +} + +// On exit, *aborted will be true iff the EXPECT_DEATH() statement +// aborted the function. +void ExpectDeathTestHelper(bool* aborted) { + *aborted = true; + EXPECT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. + *aborted = false; +} + +// Tests that EXPECT_DEATH doesn't abort the test on failure. +TEST_F(TestForDeathTest, EXPECT_DEATH) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(ExpectDeathTestHelper(&aborted), + "failed to die"); + EXPECT_FALSE(aborted); +} + +// Tests that ASSERT_DEATH does abort the test on failure. +TEST_F(TestForDeathTest, ASSERT_DEATH) { + static bool aborted; + EXPECT_FATAL_FAILURE({ // NOLINT + aborted = true; + ASSERT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. + aborted = false; + }, "failed to die"); + EXPECT_TRUE(aborted); +} + +// Tests that EXPECT_DEATH evaluates the arguments exactly once. +TEST_F(TestForDeathTest, SingleEvaluation) { + int x = 3; + EXPECT_DEATH(DieIf((++x) == 4), "DieIf"); + + const char* regex = "DieIf"; + const char* regex_save = regex; + EXPECT_DEATH(DieIfLessThan(3, 4), regex++); + EXPECT_EQ(regex_save + 1, regex); +} + +// Tests that run-away death tests are reported as failures. +TEST_F(TestForDeathTest, RunawayIsFailure) { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(static_cast(0), "Foo"), + "failed to die."); +} + +// Tests that death tests report executing 'return' in the statement as +// failure. +TEST_F(TestForDeathTest, ReturnIsFailure) { + EXPECT_FATAL_FAILURE(ASSERT_DEATH(return, "Bar"), + "illegal return in test statement."); +} + +// Tests that EXPECT_DEBUG_DEATH works as expected, that is, you can stream a +// message to it, and in debug mode it: +// 1. Asserts on death. +// 2. Has no side effect. +// +// And in opt mode, it: +// 1. Has side effects but does not assert. +TEST_F(TestForDeathTest, TestExpectDebugDeath) { + int sideeffect = 0; + + EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") + << "Must accept a streamed message"; + +# ifdef NDEBUG + + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); + +# else + + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); + +# endif +} + +// Tests that ASSERT_DEBUG_DEATH works as expected, that is, you can stream a +// message to it, and in debug mode it: +// 1. Asserts on death. +// 2. Has no side effect. +// +// And in opt mode, it: +// 1. Has side effects but does not assert. +TEST_F(TestForDeathTest, TestAssertDebugDeath) { + int sideeffect = 0; + + ASSERT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") + << "Must accept a streamed message"; + +# ifdef NDEBUG + + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); + +# else + + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); + +# endif +} + +# ifndef NDEBUG + +void ExpectDebugDeathHelper(bool* aborted) { + *aborted = true; + EXPECT_DEBUG_DEATH(return, "") << "This is expected to fail."; + *aborted = false; +} + +# if GTEST_OS_WINDOWS +TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) { + printf("This test should be considered failing if it shows " + "any pop-up dialogs.\n"); + fflush(stdout); + + EXPECT_DEATH({ + testing::GTEST_FLAG(catch_exceptions) = false; + abort(); + }, ""); +} +# endif // GTEST_OS_WINDOWS + +// Tests that EXPECT_DEBUG_DEATH in debug mode does not abort +// the function. +TEST_F(TestForDeathTest, ExpectDebugDeathDoesNotAbort) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(ExpectDebugDeathHelper(&aborted), ""); + EXPECT_FALSE(aborted); +} + +void AssertDebugDeathHelper(bool* aborted) { + *aborted = true; + ASSERT_DEBUG_DEATH(return, "") << "This is expected to fail."; + *aborted = false; +} + +// Tests that ASSERT_DEBUG_DEATH in debug mode aborts the function on +// failure. +TEST_F(TestForDeathTest, AssertDebugDeathAborts) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +# endif // _NDEBUG + +// Tests the *_EXIT family of macros, using a variety of predicates. +static void TestExitMacros() { + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); + +# if GTEST_OS_WINDOWS + + // Of all signals effects on the process exit code, only those of SIGABRT + // are documented on Windows. + // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. + EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), "") << "b_ar"; + +# else + + EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; + ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") + << "This failure is expected, too."; + }, "This failure is expected, too."); + +# endif // GTEST_OS_WINDOWS + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") + << "This failure is expected."; + }, "This failure is expected."); +} + +TEST_F(TestForDeathTest, ExitMacros) { + TestExitMacros(); +} + +TEST_F(TestForDeathTest, ExitMacrosUsingFork) { + testing::GTEST_FLAG(death_test_use_fork) = true; + TestExitMacros(); +} + +TEST_F(TestForDeathTest, InvalidStyle) { + testing::GTEST_FLAG(death_test_style) = "rococo"; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(_exit(0), "") << "This failure is expected."; + }, "This failure is expected."); +} + +TEST_F(TestForDeathTest, DeathTestFailedOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("death\n"), + "expected message"), + "Actual msg:\n" + "[ DEATH ] death\n"); +} + +TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH({ + fprintf(stderr, "returning\n"); + fflush(stderr); + return; + }, ""), + " Result: illegal return in test statement.\n" + " Error msg:\n" + "[ DEATH ] returning\n"); +} + +TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"), + testing::ExitedWithCode(3), + "expected message"), + " Result: died but not with expected exit code:\n" + " Exited with exit status 1\n" + "Actual msg:\n" + "[ DEATH ] exiting with rc 1\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nxyz\nline 3\n"), + "Actual msg:\n" + "[ DEATH ] line 1\n" + "[ DEATH ] line 2\n" + "[ DEATH ] line 3\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nline 2\nline 3\n"); +} + +// A DeathTestFactory that returns MockDeathTests. +class MockDeathTestFactory : public DeathTestFactory { + public: + MockDeathTestFactory(); + virtual bool Create(const char* statement, + const ::testing::internal::RE* regex, + const char* file, int line, DeathTest** test); + + // Sets the parameters for subsequent calls to Create. + void SetParameters(bool create, DeathTest::TestRole role, + int status, bool passed); + + // Accessors. + int AssumeRoleCalls() const { return assume_role_calls_; } + int WaitCalls() const { return wait_calls_; } + int PassedCalls() const { return passed_args_.size(); } + bool PassedArgument(int n) const { return passed_args_[n]; } + int AbortCalls() const { return abort_args_.size(); } + DeathTest::AbortReason AbortArgument(int n) const { + return abort_args_[n]; + } + bool TestDeleted() const { return test_deleted_; } + + private: + friend class MockDeathTest; + // If true, Create will return a MockDeathTest; otherwise it returns + // NULL. + bool create_; + // The value a MockDeathTest will return from its AssumeRole method. + DeathTest::TestRole role_; + // The value a MockDeathTest will return from its Wait method. + int status_; + // The value a MockDeathTest will return from its Passed method. + bool passed_; + + // Number of times AssumeRole was called. + int assume_role_calls_; + // Number of times Wait was called. + int wait_calls_; + // The arguments to the calls to Passed since the last call to + // SetParameters. + std::vector passed_args_; + // The arguments to the calls to Abort since the last call to + // SetParameters. + std::vector abort_args_; + // True if the last MockDeathTest returned by Create has been + // deleted. + bool test_deleted_; +}; + + +// A DeathTest implementation useful in testing. It returns values set +// at its creation from its various inherited DeathTest methods, and +// reports calls to those methods to its parent MockDeathTestFactory +// object. +class MockDeathTest : public DeathTest { + public: + MockDeathTest(MockDeathTestFactory *parent, + TestRole role, int status, bool passed) : + parent_(parent), role_(role), status_(status), passed_(passed) { + } + virtual ~MockDeathTest() { + parent_->test_deleted_ = true; + } + virtual TestRole AssumeRole() { + ++parent_->assume_role_calls_; + return role_; + } + virtual int Wait() { + ++parent_->wait_calls_; + return status_; + } + virtual bool Passed(bool exit_status_ok) { + parent_->passed_args_.push_back(exit_status_ok); + return passed_; + } + virtual void Abort(AbortReason reason) { + parent_->abort_args_.push_back(reason); + } + + private: + MockDeathTestFactory* const parent_; + const TestRole role_; + const int status_; + const bool passed_; +}; + + +// MockDeathTestFactory constructor. +MockDeathTestFactory::MockDeathTestFactory() + : create_(true), + role_(DeathTest::OVERSEE_TEST), + status_(0), + passed_(true), + assume_role_calls_(0), + wait_calls_(0), + passed_args_(), + abort_args_() { +} + + +// Sets the parameters for subsequent calls to Create. +void MockDeathTestFactory::SetParameters(bool create, + DeathTest::TestRole role, + int status, bool passed) { + create_ = create; + role_ = role; + status_ = status; + passed_ = passed; + + assume_role_calls_ = 0; + wait_calls_ = 0; + passed_args_.clear(); + abort_args_.clear(); +} + + +// Sets test to NULL (if create_ is false) or to the address of a new +// MockDeathTest object with parameters taken from the last call +// to SetParameters (if create_ is true). Always returns true. +bool MockDeathTestFactory::Create(const char* /*statement*/, + const ::testing::internal::RE* /*regex*/, + const char* /*file*/, + int /*line*/, + DeathTest** test) { + test_deleted_ = false; + if (create_) { + *test = new MockDeathTest(this, role_, status_, passed_); + } else { + *test = NULL; + } + return true; +} + +// A test fixture for testing the logic of the GTEST_DEATH_TEST_ macro. +// It installs a MockDeathTestFactory that is used for the duration +// of the test case. +class MacroLogicDeathTest : public testing::Test { + protected: + static testing::internal::ReplaceDeathTestFactory* replacer_; + static MockDeathTestFactory* factory_; + + static void SetUpTestCase() { + factory_ = new MockDeathTestFactory; + replacer_ = new testing::internal::ReplaceDeathTestFactory(factory_); + } + + static void TearDownTestCase() { + delete replacer_; + replacer_ = NULL; + delete factory_; + factory_ = NULL; + } + + // Runs a death test that breaks the rules by returning. Such a death + // test cannot be run directly from a test routine that uses a + // MockDeathTest, or the remainder of the routine will not be executed. + static void RunReturningDeathTest(bool* flag) { + ASSERT_DEATH({ // NOLINT + *flag = true; + return; + }, ""); + } +}; + +testing::internal::ReplaceDeathTestFactory* MacroLogicDeathTest::replacer_ + = NULL; +MockDeathTestFactory* MacroLogicDeathTest::factory_ = NULL; + + +// Test that nothing happens when the factory doesn't return a DeathTest: +TEST_F(MacroLogicDeathTest, NothingHappens) { + bool flag = false; + factory_->SetParameters(false, DeathTest::OVERSEE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(0, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_FALSE(factory_->TestDeleted()); +} + +// Test that the parent process doesn't run the death test code, +// and that the Passed method returns false when the (simulated) +// child process exits with status 0: +TEST_F(MacroLogicDeathTest, ChildExitsSuccessfully) { + bool flag = false; + factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(1, factory_->WaitCalls()); + ASSERT_EQ(1, factory_->PassedCalls()); + EXPECT_FALSE(factory_->PassedArgument(0)); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the Passed method was given the argument "true" when +// the (simulated) child process exits with status 1: +TEST_F(MacroLogicDeathTest, ChildExitsUnsuccessfully) { + bool flag = false; + factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 1, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(1, factory_->WaitCalls()); + ASSERT_EQ(1, factory_->PassedCalls()); + EXPECT_TRUE(factory_->PassedArgument(0)); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the (simulated) child process executes the death test +// code, and is aborted with the correct AbortReason if it +// executes a return statement. +TEST_F(MacroLogicDeathTest, ChildPerformsReturn) { + bool flag = false; + factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); + RunReturningDeathTest(&flag); + EXPECT_TRUE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + EXPECT_EQ(1, factory_->AbortCalls()); + EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, + factory_->AbortArgument(0)); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the (simulated) child process is aborted with the +// correct AbortReason if it does not die. +TEST_F(MacroLogicDeathTest, ChildDoesNotDie) { + bool flag = false; + factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_TRUE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + // This time there are two calls to Abort: one since the test didn't + // die, and another from the ReturnSentinel when it's destroyed. The + // sentinel normally isn't destroyed if a test doesn't die, since + // _exit(2) is called in that case by ForkingDeathTest, but not by + // our MockDeathTest. + ASSERT_EQ(2, factory_->AbortCalls()); + EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE, + factory_->AbortArgument(0)); + EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, + factory_->AbortArgument(1)); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that a successful death test does not register a successful +// test part. +TEST(SuccessRegistrationDeathTest, NoSuccessPart) { + EXPECT_DEATH(_exit(1), ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +TEST(StreamingAssertionsDeathTest, DeathTest) { + EXPECT_DEATH(_exit(1), "") << "unexpected failure"; + ASSERT_DEATH(_exit(1), "") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(_exit(0), "") << "expected failure"; + }, "expected failure"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_DEATH(_exit(0), "") << "expected failure"; + }, "expected failure"); +} + +// Tests that GetLastErrnoDescription returns an empty string when the +// last error is 0 and non-empty string when it is non-zero. +TEST(GetLastErrnoDescription, GetLastErrnoDescriptionWorks) { + errno = ENOENT; + EXPECT_STRNE("", GetLastErrnoDescription().c_str()); + errno = 0; + EXPECT_STREQ("", GetLastErrnoDescription().c_str()); +} + +# if GTEST_OS_WINDOWS +TEST(AutoHandleTest, AutoHandleWorks) { + HANDLE handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + + // Tests that the AutoHandle is correctly initialized with a handle. + testing::internal::AutoHandle auto_handle(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that Reset assigns INVALID_HANDLE_VALUE. + // Note that this cannot verify whether the original handle is closed. + auto_handle.Reset(); + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle.Get()); + + // Tests that Reset assigns the new handle. + // Note that this cannot verify whether the original handle is closed. + handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + auto_handle.Reset(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that AutoHandle contains INVALID_HANDLE_VALUE by default. + testing::internal::AutoHandle auto_handle2; + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle2.Get()); +} +# endif // GTEST_OS_WINDOWS + +# if GTEST_OS_WINDOWS +typedef unsigned __int64 BiggestParsable; +typedef signed __int64 BiggestSignedParsable; +const BiggestParsable kBiggestParsableMax = ULLONG_MAX; +const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX; +# else +typedef unsigned long long BiggestParsable; +typedef signed long long BiggestSignedParsable; +const BiggestParsable kBiggestParsableMax = + ::std::numeric_limits::max(); +const BiggestSignedParsable kBiggestSignedParsableMax = + ::std::numeric_limits::max(); +# endif // GTEST_OS_WINDOWS + +TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { + BiggestParsable result = 0; + + // Rejects non-numbers. + EXPECT_FALSE(ParseNaturalNumber("non-number string", &result)); + + // Rejects numbers with whitespace prefix. + EXPECT_FALSE(ParseNaturalNumber(" 123", &result)); + + // Rejects negative numbers. + EXPECT_FALSE(ParseNaturalNumber("-123", &result)); + + // Rejects numbers starting with a plus sign. + EXPECT_FALSE(ParseNaturalNumber("+123", &result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) { + BiggestParsable result = 0; + + EXPECT_FALSE(ParseNaturalNumber("99999999999999999999999", &result)); + + signed char char_result = 0; + EXPECT_FALSE(ParseNaturalNumber("200", &char_result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, AcceptsValidNumbers) { + BiggestParsable result = 0; + + result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &result)); + EXPECT_EQ(123U, result); + + // Check 0 as an edge case. + result = 1; + ASSERT_TRUE(ParseNaturalNumber("0", &result)); + EXPECT_EQ(0U, result); + + result = 1; + ASSERT_TRUE(ParseNaturalNumber("00000", &result)); + EXPECT_EQ(0U, result); +} + +TEST(ParseNaturalNumberTest, AcceptsTypeLimits) { + Message msg; + msg << kBiggestParsableMax; + + BiggestParsable result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg.GetString(), &result)); + EXPECT_EQ(kBiggestParsableMax, result); + + Message msg2; + msg2 << kBiggestSignedParsableMax; + + BiggestSignedParsable signed_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg2.GetString(), &signed_result)); + EXPECT_EQ(kBiggestSignedParsableMax, signed_result); + + Message msg3; + msg3 << INT_MAX; + + int int_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg3.GetString(), &int_result)); + EXPECT_EQ(INT_MAX, int_result); + + Message msg4; + msg4 << UINT_MAX; + + unsigned int uint_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg4.GetString(), &uint_result)); + EXPECT_EQ(UINT_MAX, uint_result); +} + +TEST(ParseNaturalNumberTest, WorksForShorterIntegers) { + short short_result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &short_result)); + EXPECT_EQ(123, short_result); + + signed char char_result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &char_result)); + EXPECT_EQ(123, char_result); +} + +# if GTEST_OS_WINDOWS +TEST(EnvironmentTest, HandleFitsIntoSizeT) { + // TODO(vladl@google.com): Remove this test after this condition is verified + // in a static assertion in gtest-death-test.cc in the function + // GetStatusFileDescriptor. + ASSERT_TRUE(sizeof(HANDLE) <= sizeof(size_t)); +} +# endif // GTEST_OS_WINDOWS + +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger +// failures when death tests are available on the system. +TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) { + EXPECT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestExpectMacro"), + "death inside CondDeathTestExpectMacro"); + ASSERT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestAssertMacro"), + "death inside CondDeathTestAssertMacro"); + + // Empty statement will not crash, which must trigger a failure. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH_IF_SUPPORTED(;, ""), ""); + EXPECT_FATAL_FAILURE(ASSERT_DEATH_IF_SUPPORTED(;, ""), ""); +} + +#else + +using testing::internal::CaptureStderr; +using testing::internal::GetCapturedStderr; + +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still +// defined but do not trigger failures when death tests are not available on +// the system. +TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { + // Empty statement will not crash, but that should not trigger a failure + // when death tests are not supported. + CaptureStderr(); + EXPECT_DEATH_IF_SUPPORTED(;, ""); + std::string output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + // The streamed message should not be printed as there is no test failure. + CaptureStderr(); + EXPECT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, ""); // NOLINT + output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; // NOLINT + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); +} + +void FuncWithAssert(int* n) { + ASSERT_DEATH_IF_SUPPORTED(return;, ""); + (*n)++; +} + +// Tests that ASSERT_DEATH_IF_SUPPORTED does not return from the current +// function (as ASSERT_DEATH does) if death tests are not supported. +TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) { + int n = 0; + FuncWithAssert(&n); + EXPECT_EQ(1, n); +} +#endif // GTEST_HAS_DEATH_TEST + +// Tests that the death test macros expand to code which may or may not +// be followed by operator<<, and that in either case the complete text +// comprises only a single C++ statement. +// +// The syntax should work whether death tests are available or not. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) { + if (AlwaysFalse()) + // This would fail if executed; this is a compilation test only + ASSERT_DEATH_IF_SUPPORTED(return, ""); + + if (AlwaysTrue()) + EXPECT_DEATH_IF_SUPPORTED(_exit(1), ""); + else + // This empty "else" branch is meant to ensure that EXPECT_DEATH + // doesn't expand into an "if" statement without an "else" + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_DEATH_IF_SUPPORTED(return, "") << "did not die"; + + if (AlwaysFalse()) + ; // NOLINT + else + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << 1 << 2 << 3; +} + +// Tests that conditional death test macros expand to code which interacts +// well with switch statements. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { +// Microsoft compiler usually complains about switch statements without +// case labels. We suppress that warning for this test. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4065) +#endif // _MSC_VER + + switch (0) + default: + ASSERT_DEATH_IF_SUPPORTED(_exit(1), "") + << "exit in default switch handler"; + + switch (0) + case 0: + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case"; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif // _MSC_VER +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +// Tests that a test case whose name ends with "DeathTest" works fine +// on Windows. +TEST(NotADeathTest, Test) { + SUCCEED(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-filepath_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-filepath_test.cc new file mode 100644 index 0000000..ae9f55a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-filepath_test.cc @@ -0,0 +1,680 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This file tests classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included from gtest_unittest.cc, to avoid changing +// build or make-files for some existing Google Test clients. Do not +// #include this file anywhere else! + +#include "gtest/internal/gtest-filepath.h" +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS_MOBILE +# include // NOLINT +#elif GTEST_OS_WINDOWS +# include // NOLINT +#endif // GTEST_OS_WINDOWS_MOBILE + +namespace testing { +namespace internal { +namespace { + +#if GTEST_OS_WINDOWS_MOBILE +// TODO(wan@google.com): Move these to the POSIX adapter section in +// gtest-port.h. + +// Windows CE doesn't have the remove C function. +int remove(const char* path) { + LPCWSTR wpath = String::AnsiToUtf16(path); + int ret = DeleteFile(wpath) ? 0 : -1; + delete [] wpath; + return ret; +} +// Windows CE doesn't have the _rmdir C function. +int _rmdir(const char* path) { + FilePath filepath(path); + LPCWSTR wpath = String::AnsiToUtf16( + filepath.RemoveTrailingPathSeparator().c_str()); + int ret = RemoveDirectory(wpath) ? 0 : -1; + delete [] wpath; + return ret; +} + +#else + +TEST(GetCurrentDirTest, ReturnsCurrentDir) { + const FilePath original_dir = FilePath::GetCurrentDir(); + EXPECT_FALSE(original_dir.IsEmpty()); + + posix::ChDir(GTEST_PATH_SEP_); + const FilePath cwd = FilePath::GetCurrentDir(); + posix::ChDir(original_dir.c_str()); + +# if GTEST_OS_WINDOWS + + // Skips the ":". + const char* const cwd_without_drive = strchr(cwd.c_str(), ':'); + ASSERT_TRUE(cwd_without_drive != NULL); + EXPECT_STREQ(GTEST_PATH_SEP_, cwd_without_drive + 1); + +# else + + EXPECT_EQ(GTEST_PATH_SEP_, cwd.string()); + +# endif +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +TEST(IsEmptyTest, ReturnsTrueForEmptyPath) { + EXPECT_TRUE(FilePath("").IsEmpty()); +} + +TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) { + EXPECT_FALSE(FilePath("a").IsEmpty()); + EXPECT_FALSE(FilePath(".").IsEmpty()); + EXPECT_FALSE(FilePath("a/b").IsEmpty()); + EXPECT_FALSE(FilePath("a\\b\\").IsEmpty()); +} + +// RemoveDirectoryName "" -> "" +TEST(RemoveDirectoryNameTest, WhenEmptyName) { + EXPECT_EQ("", FilePath("").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "afile" -> "afile" +TEST(RemoveDirectoryNameTest, ButNoDirectory) { + EXPECT_EQ("afile", + FilePath("afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "/afile" -> "afile" +TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) { + EXPECT_EQ("afile", + FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/" -> "" +TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) { + EXPECT_EQ("", + FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldGiveFileName) { + EXPECT_EQ("afile", + FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/subdir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { + EXPECT_EQ("afile", + FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") + .RemoveDirectoryName().string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that RemoveDirectoryName() works with the alternate separator +// on Windows. + +// RemoveDirectoryName("/afile") -> "afile" +TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", FilePath("/afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/") -> "" +TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) { + EXPECT_EQ("", FilePath("adir/").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/afile") -> "afile" +TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", FilePath("adir/afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/subdir/afile") -> "afile" +TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", + FilePath("adir/subdir/afile").RemoveDirectoryName().string()); +} + +#endif + +// RemoveFileName "" -> "./" +TEST(RemoveFileNameTest, EmptyName) { +#if GTEST_OS_WINDOWS_MOBILE + // On Windows CE, we use the root as the current directory. + EXPECT_EQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); +#else + EXPECT_EQ("." GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); +#endif +} + +// RemoveFileName "adir/" -> "adir/" +TEST(RemoveFileNameTest, ButNoFile) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().string()); +} + +// RemoveFileName "adir/afile" -> "adir/" +TEST(RemoveFileNameTest, GivesDirName) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveFileName().string()); +} + +// RemoveFileName "adir/subdir/afile" -> "adir/subdir/" +TEST(RemoveFileNameTest, GivesDirAndSubDirName) { + EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") + .RemoveFileName().string()); +} + +// RemoveFileName "/afile" -> "/" +TEST(RemoveFileNameTest, GivesRootDir) { + EXPECT_EQ(GTEST_PATH_SEP_, + FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that RemoveFileName() works with the alternate separator on +// Windows. + +// RemoveFileName("adir/") -> "adir/" +TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir/").RemoveFileName().string()); +} + +// RemoveFileName("adir/afile") -> "adir/" +TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir/afile").RemoveFileName().string()); +} + +// RemoveFileName("adir/subdir/afile") -> "adir/subdir/" +TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + FilePath("adir/subdir/afile").RemoveFileName().string()); +} + +// RemoveFileName("/afile") -> "\" +TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) { + EXPECT_EQ(GTEST_PATH_SEP_, FilePath("/afile").RemoveFileName().string()); +} + +#endif + +TEST(MakeFileNameTest, GenerateWhenNumberIsZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), + 0, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), + 12, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar"), 0, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar"), 12, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) { + FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), + 0, "xml"); + EXPECT_EQ("bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) { + FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), + 14, "xml"); + EXPECT_EQ("bar_14.xml", actual.string()); +} + +TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), + FilePath("bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, Path1BeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath(""), + FilePath("bar.xml")); + EXPECT_EQ("bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, Path2BeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("")); + EXPECT_EQ("foo" GTEST_PATH_SEP_, actual.string()); +} + +TEST(ConcatPathsTest, BothPathBeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath(""), + FilePath("")); + EXPECT_EQ("", actual.string()); +} + +TEST(ConcatPathsTest, Path1ContainsPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"), + FilePath("foobar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml", + actual.string()); +} + +TEST(ConcatPathsTest, Path2ContainsPathSep) { + FilePath actual = FilePath::ConcatPaths( + FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar" GTEST_PATH_SEP_ "bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml", + actual.string()); +} + +TEST(ConcatPathsTest, Path2EndsWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), + FilePath("bar" GTEST_PATH_SEP_)); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.string()); +} + +// RemoveTrailingPathSeparator "" -> "" +TEST(RemoveTrailingPathSeparatorTest, EmptyString) { + EXPECT_EQ("", FilePath("").RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo" -> "foo" +TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) { + EXPECT_EQ("foo", FilePath("foo").RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo/" -> "foo" +TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) { + EXPECT_EQ("foo", + FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().string()); +#if GTEST_HAS_ALT_PATH_SEP_ + EXPECT_EQ("foo", FilePath("foo/").RemoveTrailingPathSeparator().string()); +#endif +} + +// RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/" +TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_) + .RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo/bar" -> "foo/bar" +TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar") + .RemoveTrailingPathSeparator().string()); +} + +TEST(DirectoryTest, RootDirectoryExists) { +#if GTEST_OS_WINDOWS // We are on Windows. + char current_drive[_MAX_PATH]; // NOLINT + current_drive[0] = static_cast(_getdrive() + 'A' - 1); + current_drive[1] = ':'; + current_drive[2] = '\\'; + current_drive[3] = '\0'; + EXPECT_TRUE(FilePath(current_drive).DirectoryExists()); +#else + EXPECT_TRUE(FilePath("/").DirectoryExists()); +#endif // GTEST_OS_WINDOWS +} + +#if GTEST_OS_WINDOWS +TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { + const int saved_drive_ = _getdrive(); + // Find a drive that doesn't exist. Start with 'Z' to avoid common ones. + for (char drive = 'Z'; drive >= 'A'; drive--) + if (_chdrive(drive - 'A' + 1) == -1) { + char non_drive[_MAX_PATH]; // NOLINT + non_drive[0] = drive; + non_drive[1] = ':'; + non_drive[2] = '\\'; + non_drive[3] = '\0'; + EXPECT_FALSE(FilePath(non_drive).DirectoryExists()); + break; + } + _chdrive(saved_drive_); +} +#endif // GTEST_OS_WINDOWS + +#if !GTEST_OS_WINDOWS_MOBILE +// Windows CE _does_ consider an empty directory to exist. +TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { + EXPECT_FALSE(FilePath("").DirectoryExists()); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +TEST(DirectoryTest, CurrentDirectoryExists) { +#if GTEST_OS_WINDOWS // We are on Windows. +# ifndef _WIN32_CE // Windows CE doesn't have a current directory. + + EXPECT_TRUE(FilePath(".").DirectoryExists()); + EXPECT_TRUE(FilePath(".\\").DirectoryExists()); + +# endif // _WIN32_CE +#else + EXPECT_TRUE(FilePath(".").DirectoryExists()); + EXPECT_TRUE(FilePath("./").DirectoryExists()); +#endif // GTEST_OS_WINDOWS +} + +// "foo/bar" == foo//bar" == "foo///bar" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ + GTEST_PATH_SEP_ "bar").string()); +} + +// "/bar" == //bar" == "///bar" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) { + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); +} + +// "foo/" == foo//" == "foo///" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_).string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that separators at the end of the string are normalized +// regardless of their combination (e.g. "foo\" =="foo/\" == +// "foo\\/"). +TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) { + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo/").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ "/").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo//" GTEST_PATH_SEP_).string()); +} + +#endif + +TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) { + FilePath default_path; + FilePath non_default_path("path"); + non_default_path = default_path; + EXPECT_EQ("", non_default_path.string()); + EXPECT_EQ("", default_path.string()); // RHS var is unchanged. +} + +TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) { + FilePath non_default_path("path"); + FilePath default_path; + default_path = non_default_path; + EXPECT_EQ("path", default_path.string()); + EXPECT_EQ("path", non_default_path.string()); // RHS var is unchanged. +} + +TEST(AssignmentOperatorTest, ConstAssignedToNonConst) { + const FilePath const_default_path("const_path"); + FilePath non_default_path("path"); + non_default_path = const_default_path; + EXPECT_EQ("const_path", non_default_path.string()); +} + +class DirectoryCreationTest : public Test { + protected: + virtual void SetUp() { + testdata_path_.Set(FilePath( + TempDir() + GetCurrentExecutableName().string() + + "_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_)); + testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator()); + + unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), + 0, "txt")); + unique_file1_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), + 1, "txt")); + + remove(testdata_file_.c_str()); + remove(unique_file0_.c_str()); + remove(unique_file1_.c_str()); + posix::RmDir(testdata_path_.c_str()); + } + + virtual void TearDown() { + remove(testdata_file_.c_str()); + remove(unique_file0_.c_str()); + remove(unique_file1_.c_str()); + posix::RmDir(testdata_path_.c_str()); + } + + std::string TempDir() const { +#if GTEST_OS_WINDOWS_MOBILE + return "\\temp\\"; +#elif GTEST_OS_WINDOWS + const char* temp_dir = posix::GetEnv("TEMP"); + if (temp_dir == NULL || temp_dir[0] == '\0') + return "\\temp\\"; + else if (temp_dir[strlen(temp_dir) - 1] == '\\') + return temp_dir; + else + return std::string(temp_dir) + "\\"; +#elif GTEST_OS_LINUX_ANDROID + return "/sdcard/"; +#else + return "/tmp/"; +#endif // GTEST_OS_WINDOWS_MOBILE + } + + void CreateTextFile(const char* filename) { + FILE* f = posix::FOpen(filename, "w"); + fprintf(f, "text\n"); + fclose(f); + } + + // Strings representing a directory and a file, with identical paths + // except for the trailing separator character that distinquishes + // a directory named 'test' from a file named 'test'. Example names: + FilePath testdata_path_; // "/tmp/directory_creation/test/" + FilePath testdata_file_; // "/tmp/directory_creation/test" + FilePath unique_file0_; // "/tmp/directory_creation/test/unique.txt" + FilePath unique_file1_; // "/tmp/directory_creation/test/unique_1.txt" +}; + +TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) { + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); + EXPECT_TRUE(testdata_path_.DirectoryExists()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) { + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); + // Call 'create' again... should still succeed. + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) { + FilePath file_path(FilePath::GenerateUniqueFileName(testdata_path_, + FilePath("unique"), "txt")); + EXPECT_EQ(unique_file0_.string(), file_path.string()); + EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file not there + + testdata_path_.CreateDirectoriesRecursively(); + EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file still not there + CreateTextFile(file_path.c_str()); + EXPECT_TRUE(file_path.FileOrDirectoryExists()); + + FilePath file_path2(FilePath::GenerateUniqueFileName(testdata_path_, + FilePath("unique"), "txt")); + EXPECT_EQ(unique_file1_.string(), file_path2.string()); + EXPECT_FALSE(file_path2.FileOrDirectoryExists()); // file not there + CreateTextFile(file_path2.c_str()); + EXPECT_TRUE(file_path2.FileOrDirectoryExists()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesFail) { + // force a failure by putting a file where we will try to create a directory. + CreateTextFile(testdata_file_.c_str()); + EXPECT_TRUE(testdata_file_.FileOrDirectoryExists()); + EXPECT_FALSE(testdata_file_.DirectoryExists()); + EXPECT_FALSE(testdata_file_.CreateDirectoriesRecursively()); +} + +TEST(NoDirectoryCreationTest, CreateNoDirectoriesForDefaultXmlFile) { + const FilePath test_detail_xml("test_detail.xml"); + EXPECT_FALSE(test_detail_xml.CreateDirectoriesRecursively()); +} + +TEST(FilePathTest, DefaultConstructor) { + FilePath fp; + EXPECT_EQ("", fp.string()); +} + +TEST(FilePathTest, CharAndCopyConstructors) { + const FilePath fp("spicy"); + EXPECT_EQ("spicy", fp.string()); + + const FilePath fp_copy(fp); + EXPECT_EQ("spicy", fp_copy.string()); +} + +TEST(FilePathTest, StringConstructor) { + const FilePath fp(std::string("cider")); + EXPECT_EQ("cider", fp.string()); +} + +TEST(FilePathTest, Set) { + const FilePath apple("apple"); + FilePath mac("mac"); + mac.Set(apple); // Implement Set() since overloading operator= is forbidden. + EXPECT_EQ("apple", mac.string()); + EXPECT_EQ("apple", apple.string()); +} + +TEST(FilePathTest, ToString) { + const FilePath file("drink"); + EXPECT_EQ("drink", file.string()); +} + +TEST(FilePathTest, RemoveExtension) { + EXPECT_EQ("app", FilePath("app.cc").RemoveExtension("cc").string()); + EXPECT_EQ("app", FilePath("app.exe").RemoveExtension("exe").string()); + EXPECT_EQ("APP", FilePath("APP.EXE").RemoveExtension("exe").string()); +} + +TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) { + EXPECT_EQ("app", FilePath("app").RemoveExtension("exe").string()); +} + +TEST(FilePathTest, IsDirectory) { + EXPECT_FALSE(FilePath("cola").IsDirectory()); + EXPECT_TRUE(FilePath("koala" GTEST_PATH_SEP_).IsDirectory()); +#if GTEST_HAS_ALT_PATH_SEP_ + EXPECT_TRUE(FilePath("koala/").IsDirectory()); +#endif +} + +TEST(FilePathTest, IsAbsolutePath) { + EXPECT_FALSE(FilePath("is" GTEST_PATH_SEP_ "relative").IsAbsolutePath()); + EXPECT_FALSE(FilePath("").IsAbsolutePath()); +#if GTEST_OS_WINDOWS + EXPECT_TRUE(FilePath("c:\\" GTEST_PATH_SEP_ "is_not" + GTEST_PATH_SEP_ "relative").IsAbsolutePath()); + EXPECT_FALSE(FilePath("c:foo" GTEST_PATH_SEP_ "bar").IsAbsolutePath()); + EXPECT_TRUE(FilePath("c:/" GTEST_PATH_SEP_ "is_not" + GTEST_PATH_SEP_ "relative").IsAbsolutePath()); +#else + EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative") + .IsAbsolutePath()); +#endif // GTEST_OS_WINDOWS +} + +TEST(FilePathTest, IsRootDirectory) { +#if GTEST_OS_WINDOWS + EXPECT_TRUE(FilePath("a:\\").IsRootDirectory()); + EXPECT_TRUE(FilePath("Z:/").IsRootDirectory()); + EXPECT_TRUE(FilePath("e://").IsRootDirectory()); + EXPECT_FALSE(FilePath("").IsRootDirectory()); + EXPECT_FALSE(FilePath("b:").IsRootDirectory()); + EXPECT_FALSE(FilePath("b:a").IsRootDirectory()); + EXPECT_FALSE(FilePath("8:/").IsRootDirectory()); + EXPECT_FALSE(FilePath("c|/").IsRootDirectory()); +#else + EXPECT_TRUE(FilePath("/").IsRootDirectory()); + EXPECT_TRUE(FilePath("//").IsRootDirectory()); + EXPECT_FALSE(FilePath("").IsRootDirectory()); + EXPECT_FALSE(FilePath("\\").IsRootDirectory()); + EXPECT_FALSE(FilePath("/x").IsRootDirectory()); +#endif +} + +} // namespace +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-linked_ptr_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-linked_ptr_test.cc new file mode 100644 index 0000000..6fcf512 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-linked_ptr_test.cc @@ -0,0 +1,154 @@ +// Copyright 2003, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: Dan Egnor (egnor@google.com) +// Ported to Windows: Vadim Berman (vadimb@google.com) + +#include "gtest/internal/gtest-linked_ptr.h" + +#include +#include "gtest/gtest.h" + +namespace { + +using testing::Message; +using testing::internal::linked_ptr; + +int num; +Message* history = NULL; + +// Class which tracks allocation/deallocation +class A { + public: + A(): mynum(num++) { *history << "A" << mynum << " ctor\n"; } + virtual ~A() { *history << "A" << mynum << " dtor\n"; } + virtual void Use() { *history << "A" << mynum << " use\n"; } + protected: + int mynum; +}; + +// Subclass +class B : public A { + public: + B() { *history << "B" << mynum << " ctor\n"; } + ~B() { *history << "B" << mynum << " dtor\n"; } + virtual void Use() { *history << "B" << mynum << " use\n"; } +}; + +class LinkedPtrTest : public testing::Test { + public: + LinkedPtrTest() { + num = 0; + history = new Message; + } + + virtual ~LinkedPtrTest() { + delete history; + history = NULL; + } +}; + +TEST_F(LinkedPtrTest, GeneralTest) { + { + linked_ptr a0, a1, a2; + // Use explicit function call notation here to suppress self-assign warning. + a0.operator=(a0); + a1 = a2; + ASSERT_EQ(a0.get(), static_cast(NULL)); + ASSERT_EQ(a1.get(), static_cast(NULL)); + ASSERT_EQ(a2.get(), static_cast(NULL)); + ASSERT_TRUE(a0 == NULL); + ASSERT_TRUE(a1 == NULL); + ASSERT_TRUE(a2 == NULL); + + { + linked_ptr a3(new A); + a0 = a3; + ASSERT_TRUE(a0 == a3); + ASSERT_TRUE(a0 != NULL); + ASSERT_TRUE(a0.get() == a3); + ASSERT_TRUE(a0 == a3.get()); + linked_ptr a4(a0); + a1 = a4; + linked_ptr a5(new A); + ASSERT_TRUE(a5.get() != a3); + ASSERT_TRUE(a5 != a3.get()); + a2 = a5; + linked_ptr b0(new B); + linked_ptr a6(b0); + ASSERT_TRUE(b0 == a6); + ASSERT_TRUE(a6 == b0); + ASSERT_TRUE(b0 != NULL); + a5 = b0; + a5 = b0; + a3->Use(); + a4->Use(); + a5->Use(); + a6->Use(); + b0->Use(); + (*b0).Use(); + b0.get()->Use(); + } + + a0->Use(); + a1->Use(); + a2->Use(); + + a1 = a2; + a2.reset(new A); + a0.reset(); + + linked_ptr a7; + } + + ASSERT_STREQ( + "A0 ctor\n" + "A1 ctor\n" + "A2 ctor\n" + "B2 ctor\n" + "A0 use\n" + "A0 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 dtor\n" + "A2 dtor\n" + "A0 use\n" + "A0 use\n" + "A1 use\n" + "A3 ctor\n" + "A0 dtor\n" + "A3 dtor\n" + "A1 dtor\n", + history->GetString().c_str()); +} + +} // Unnamed namespace diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-listener_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-listener_test.cc new file mode 100644 index 0000000..99662cf --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-listener_test.cc @@ -0,0 +1,310 @@ +// Copyright 2009 Google Inc. All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This file verifies Google Test event listeners receive events at the +// right times. + +#include "gtest/gtest.h" +#include + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Environment; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListener; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +// Used by tests to register their events. +std::vector* g_events = NULL; + +namespace testing { +namespace internal { + +class EventRecordingListener : public TestEventListener { + public: + explicit EventRecordingListener(const char* name) : name_(name) {} + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnTestProgramStart")); + } + + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationStart") + << "(" << iteration << ")"; + g_events->push_back(message.GetString()); + } + + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart")); + } + + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd")); + } + + virtual void OnTestCaseStart(const TestCase& /*test_case*/) { + g_events->push_back(GetFullMethodName("OnTestCaseStart")); + } + + virtual void OnTestStart(const TestInfo& /*test_info*/) { + g_events->push_back(GetFullMethodName("OnTestStart")); + } + + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) { + g_events->push_back(GetFullMethodName("OnTestPartResult")); + } + + virtual void OnTestEnd(const TestInfo& /*test_info*/) { + g_events->push_back(GetFullMethodName("OnTestEnd")); + } + + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) { + g_events->push_back(GetFullMethodName("OnTestCaseEnd")); + } + + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart")); + } + + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd")); + } + + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationEnd") + << "(" << iteration << ")"; + g_events->push_back(message.GetString()); + } + + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnTestProgramEnd")); + } + + private: + std::string GetFullMethodName(const char* name) { + return name_ + "." + name; + } + + std::string name_; +}; + +class EnvironmentInvocationCatcher : public Environment { + protected: + virtual void SetUp() { + g_events->push_back("Environment::SetUp"); + } + + virtual void TearDown() { + g_events->push_back("Environment::TearDown"); + } +}; + +class ListenerTest : public Test { + protected: + static void SetUpTestCase() { + g_events->push_back("ListenerTest::SetUpTestCase"); + } + + static void TearDownTestCase() { + g_events->push_back("ListenerTest::TearDownTestCase"); + } + + virtual void SetUp() { + g_events->push_back("ListenerTest::SetUp"); + } + + virtual void TearDown() { + g_events->push_back("ListenerTest::TearDown"); + } +}; + +TEST_F(ListenerTest, DoesFoo) { + // Test execution order within a test case is not guaranteed so we are not + // recording the test name. + g_events->push_back("ListenerTest::* Test Body"); + SUCCEED(); // Triggers OnTestPartResult. +} + +TEST_F(ListenerTest, DoesBar) { + g_events->push_back("ListenerTest::* Test Body"); + SUCCEED(); // Triggers OnTestPartResult. +} + +} // namespace internal + +} // namespace testing + +using ::testing::internal::EnvironmentInvocationCatcher; +using ::testing::internal::EventRecordingListener; + +void VerifyResults(const std::vector& data, + const char* const* expected_data, + int expected_data_size) { + const int actual_size = data.size(); + // If the following assertion fails, a new entry will be appended to + // data. Hence we save data.size() first. + EXPECT_EQ(expected_data_size, actual_size); + + // Compares the common prefix. + const int shorter_size = expected_data_size <= actual_size ? + expected_data_size : actual_size; + int i = 0; + for (; i < shorter_size; ++i) { + ASSERT_STREQ(expected_data[i], data[i].c_str()) + << "at position " << i; + } + + // Prints extra elements in the actual data. + for (; i < actual_size; ++i) { + printf(" Actual event #%d: %s\n", i, data[i].c_str()); + } +} + +int main(int argc, char **argv) { + std::vector events; + g_events = &events; + InitGoogleTest(&argc, argv); + + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("1st")); + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("2nd")); + + AddGlobalTestEnvironment(new EnvironmentInvocationCatcher); + + GTEST_CHECK_(events.size() == 0) + << "AddGlobalTestEnvironment should not generate any events itself."; + + ::testing::GTEST_FLAG(repeat) = 2; + int ret_val = RUN_ALL_TESTS(); + + const char* const expected_events[] = { + "1st.OnTestProgramStart", + "2nd.OnTestProgramStart", + "1st.OnTestIterationStart(0)", + "2nd.OnTestIterationStart(0)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestCase", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(0)", + "1st.OnTestIterationEnd(0)", + "1st.OnTestIterationStart(1)", + "2nd.OnTestIterationStart(1)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestCase", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(1)", + "1st.OnTestIterationEnd(1)", + "2nd.OnTestProgramEnd", + "1st.OnTestProgramEnd" + }; + VerifyResults(events, + expected_events, + sizeof(expected_events)/sizeof(expected_events[0])); + + // We need to check manually for ad hoc test failures that happen after + // RUN_ALL_TESTS finishes. + if (UnitTest::GetInstance()->Failed()) + ret_val = 1; + + return ret_val; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-message_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-message_test.cc new file mode 100644 index 0000000..175238e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-message_test.cc @@ -0,0 +1,159 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for the Message class. + +#include "gtest/gtest-message.h" + +#include "gtest/gtest.h" + +namespace { + +using ::testing::Message; + +// Tests the testing::Message class + +// Tests the default constructor. +TEST(MessageTest, DefaultConstructor) { + const Message msg; + EXPECT_EQ("", msg.GetString()); +} + +// Tests the copy constructor. +TEST(MessageTest, CopyConstructor) { + const Message msg1("Hello"); + const Message msg2(msg1); + EXPECT_EQ("Hello", msg2.GetString()); +} + +// Tests constructing a Message from a C-string. +TEST(MessageTest, ConstructsFromCString) { + Message msg("Hello"); + EXPECT_EQ("Hello", msg.GetString()); +} + +// Tests streaming a float. +TEST(MessageTest, StreamsFloat) { + const std::string s = (Message() << 1.23456F << " " << 2.34567F).GetString(); + // Both numbers should be printed with enough precision. + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s.c_str()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s.c_str()); +} + +// Tests streaming a double. +TEST(MessageTest, StreamsDouble) { + const std::string s = (Message() << 1260570880.4555497 << " " + << 1260572265.1954534).GetString(); + // Both numbers should be printed with enough precision. + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s.c_str()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s.c_str()); +} + +// Tests streaming a non-char pointer. +TEST(MessageTest, StreamsPointer) { + int n = 0; + int* p = &n; + EXPECT_NE("(null)", (Message() << p).GetString()); +} + +// Tests streaming a NULL non-char pointer. +TEST(MessageTest, StreamsNullPointer) { + int* p = NULL; + EXPECT_EQ("(null)", (Message() << p).GetString()); +} + +// Tests streaming a C string. +TEST(MessageTest, StreamsCString) { + EXPECT_EQ("Foo", (Message() << "Foo").GetString()); +} + +// Tests streaming a NULL C string. +TEST(MessageTest, StreamsNullCString) { + char* p = NULL; + EXPECT_EQ("(null)", (Message() << p).GetString()); +} + +// Tests streaming std::string. +TEST(MessageTest, StreamsString) { + const ::std::string str("Hello"); + EXPECT_EQ("Hello", (Message() << str).GetString()); +} + +// Tests that we can output strings containing embedded NULs. +TEST(MessageTest, StreamsStringWithEmbeddedNUL) { + const char char_array_with_nul[] = + "Here's a NUL\0 and some more string"; + const ::std::string string_with_nul(char_array_with_nul, + sizeof(char_array_with_nul) - 1); + EXPECT_EQ("Here's a NUL\\0 and some more string", + (Message() << string_with_nul).GetString()); +} + +// Tests streaming a NUL char. +TEST(MessageTest, StreamsNULChar) { + EXPECT_EQ("\\0", (Message() << '\0').GetString()); +} + +// Tests streaming int. +TEST(MessageTest, StreamsInt) { + EXPECT_EQ("123", (Message() << 123).GetString()); +} + +// Tests that basic IO manipulators (endl, ends, and flush) can be +// streamed to Message. +TEST(MessageTest, StreamsBasicIoManip) { + EXPECT_EQ("Line 1.\nA NUL char \\0 in line 2.", + (Message() << "Line 1." << std::endl + << "A NUL char " << std::ends << std::flush + << " in line 2.").GetString()); +} + +// Tests Message::GetString() +TEST(MessageTest, GetString) { + Message msg; + msg << 1 << " lamb"; + EXPECT_EQ("1 lamb", msg.GetString()); +} + +// Tests streaming a Message object to an ostream. +TEST(MessageTest, StreamsToOStream) { + Message msg("Hello"); + ::std::stringstream ss; + ss << msg; + EXPECT_EQ("Hello", testing::internal::StringStreamToString(&ss)); +} + +// Tests that a Message object doesn't take up too much stack space. +TEST(MessageTest, DoesNotTakeUpMuchStackSpace) { + EXPECT_LE(sizeof(Message), 16U); +} + +} // namespace diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-options_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-options_test.cc new file mode 100644 index 0000000..5586dc3 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-options_test.cc @@ -0,0 +1,215 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) +// +// Google Test UnitTestOptions tests +// +// This file tests classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included from gtest.cc, to avoid changing build or +// make-files on Windows and other platforms. Do not #include this file +// anywhere else! + +#include "gtest/gtest.h" + +#if GTEST_OS_WINDOWS_MOBILE +# include +#elif GTEST_OS_WINDOWS +# include +#endif // GTEST_OS_WINDOWS_MOBILE + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { +namespace { + +// Turns the given relative path into an absolute path. +FilePath GetAbsolutePathOf(const FilePath& relative_path) { + return FilePath::ConcatPaths(FilePath::GetCurrentDir(), relative_path); +} + +// Testing UnitTestOptions::GetOutputFormat/GetOutputFile. + +TEST(XmlOutputTest, GetOutputFormatDefault) { + GTEST_FLAG(output) = ""; + EXPECT_STREQ("", UnitTestOptions::GetOutputFormat().c_str()); +} + +TEST(XmlOutputTest, GetOutputFormat) { + GTEST_FLAG(output) = "xml:filename"; + EXPECT_STREQ("xml", UnitTestOptions::GetOutputFormat().c_str()); +} + +TEST(XmlOutputTest, GetOutputFileDefault) { + GTEST_FLAG(output) = ""; + EXPECT_EQ(GetAbsolutePathOf(FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST(XmlOutputTest, GetOutputFileSingleFile) { + GTEST_FLAG(output) = "xml:filename.abc"; + EXPECT_EQ(GetAbsolutePathOf(FilePath("filename.abc")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { + GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; + const std::string expected_output_file = + GetAbsolutePathOf( + FilePath(std::string("path") + GTEST_PATH_SEP_ + + GetCurrentExecutableName().string() + ".xml")).string(); + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +TEST(OutputFileHelpersTest, GetCurrentExecutableName) { + const std::string exe_str = GetCurrentExecutableName().string(); +#if GTEST_OS_WINDOWS + const bool success = + _strcmpi("gtest-options_test", exe_str.c_str()) == 0 || + _strcmpi("gtest-options-ex_test", exe_str.c_str()) == 0 || + _strcmpi("gtest_all_test", exe_str.c_str()) == 0 || + _strcmpi("gtest_dll_test", exe_str.c_str()) == 0; +#else + // TODO(wan@google.com): remove the hard-coded "lt-" prefix when + // Chandler Carruth's libtool replacement is ready. + const bool success = + exe_str == "gtest-options_test" || + exe_str == "gtest_all_test" || + exe_str == "lt-gtest_all_test" || + exe_str == "gtest_dll_test"; +#endif // GTEST_OS_WINDOWS + if (!success) + FAIL() << "GetCurrentExecutableName() returns " << exe_str; +} + +class XmlOutputChangeDirTest : public Test { + protected: + virtual void SetUp() { + original_working_dir_ = FilePath::GetCurrentDir(); + posix::ChDir(".."); + // This will make the test fail if run from the root directory. + EXPECT_NE(original_working_dir_.string(), + FilePath::GetCurrentDir().string()); + } + + virtual void TearDown() { + posix::ChDir(original_working_dir_.string().c_str()); + } + + FilePath original_working_dir_; +}; + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) { + GTEST_FLAG(output) = ""; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) { + GTEST_FLAG(output) = "xml"; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) { + GTEST_FLAG(output) = "xml:filename.abc"; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("filename.abc")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { + GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; + const std::string expected_output_file = + FilePath::ConcatPaths( + original_working_dir_, + FilePath(std::string("path") + GTEST_PATH_SEP_ + + GetCurrentExecutableName().string() + ".xml")).string(); + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { +#if GTEST_OS_WINDOWS + GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc"; + EXPECT_EQ(FilePath("c:\\tmp\\filename.abc").string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +#else + GTEST_FLAG(output) ="xml:/tmp/filename.abc"; + EXPECT_EQ(FilePath("/tmp/filename.abc").string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +#endif +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { +#if GTEST_OS_WINDOWS + const std::string path = "c:\\tmp\\"; +#else + const std::string path = "/tmp/"; +#endif + + GTEST_FLAG(output) = "xml:" + path; + const std::string expected_output_file = + path + GetCurrentExecutableName().string() + ".xml"; + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); + +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +} // namespace +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test2_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test2_test.cc new file mode 100644 index 0000000..4a782fe --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test2_test.cc @@ -0,0 +1,65 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. This verifies that the basic constructs of +// Google Test work. + +#include "gtest/gtest.h" + +#include "test/gtest-param-test_test.h" + +#if GTEST_HAS_PARAM_TEST + +using ::testing::Values; +using ::testing::internal::ParamGenerator; + +// Tests that generators defined in a different translation unit +// are functional. The test using extern_gen is defined +// in gtest-param-test_test.cc. +ParamGenerator extern_gen = Values(33); + +// Tests that a parameterized test case can be defined in one translation unit +// and instantiated in another. The test is defined in gtest-param-test_test.cc +// and ExternalInstantiationTest fixture class is defined in +// gtest-param-test_test.h. +INSTANTIATE_TEST_CASE_P(MultiplesOf33, + ExternalInstantiationTest, + Values(33, 66)); + +// Tests that a parameterized test case can be instantiated +// in multiple translation units. Another instantiation is defined +// in gtest-param-test_test.cc and InstantiationInMultipleTranslaionUnitsTest +// fixture is defined in gtest-param-test_test.h +INSTANTIATE_TEST_CASE_P(Sequence2, + InstantiationInMultipleTranslaionUnitsTest, + Values(42*3, 42*4, 42*5)); + +#endif // GTEST_HAS_PARAM_TEST diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test_test.cc new file mode 100644 index 0000000..7b6f7e2 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test_test.cc @@ -0,0 +1,897 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. This file verifies that the parameter +// generators objects produce correct parameter sequences and that +// Google Test runtime instantiates correct tests from those sequences. + +#include "gtest/gtest.h" + +#if GTEST_HAS_PARAM_TEST + +# include +# include +# include +# include +# include +# include + +// To include gtest-internal-inl.h. +# define GTEST_IMPLEMENTATION_ 1 +# include "src/gtest-internal-inl.h" // for UnitTestOptions +# undef GTEST_IMPLEMENTATION_ + +# include "test/gtest-param-test_test.h" + +using ::std::vector; +using ::std::sort; + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Bool; +using ::testing::Message; +using ::testing::Range; +using ::testing::TestWithParam; +using ::testing::Values; +using ::testing::ValuesIn; + +# if GTEST_HAS_COMBINE +using ::testing::Combine; +using ::std::tr1::get; +using ::std::tr1::make_tuple; +using ::std::tr1::tuple; +# endif // GTEST_HAS_COMBINE + +using ::testing::internal::ParamGenerator; +using ::testing::internal::UnitTestOptions; + +// Prints a value to a string. +// +// TODO(wan@google.com): remove PrintValue() when we move matchers and +// EXPECT_THAT() from Google Mock to Google Test. At that time, we +// can write EXPECT_THAT(x, Eq(y)) to compare two tuples x and y, as +// EXPECT_THAT() and the matchers know how to print tuples. +template +::std::string PrintValue(const T& value) { + ::std::stringstream stream; + stream << value; + return stream.str(); +} + +# if GTEST_HAS_COMBINE + +// These overloads allow printing tuples in our tests. We cannot +// define an operator<< for tuples, as that definition needs to be in +// the std namespace in order to be picked up by Google Test via +// Argument-Dependent Lookup, yet defining anything in the std +// namespace in non-STL code is undefined behavior. + +template +::std::string PrintValue(const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) << ")"; + return stream.str(); +} + +template +::std::string PrintValue(const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) + << ", "<< get<2>(value) << ")"; + return stream.str(); +} + +template +::std::string PrintValue( + const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) + << ", "<< get<2>(value) << ", " << get<3>(value) + << ", "<< get<4>(value) << ", " << get<5>(value) + << ", "<< get<6>(value) << ", " << get<7>(value) + << ", "<< get<8>(value) << ", " << get<9>(value) << ")"; + return stream.str(); +} + +# endif // GTEST_HAS_COMBINE + +// Verifies that a sequence generated by the generator and accessed +// via the iterator object matches the expected one using Google Test +// assertions. +template +void VerifyGenerator(const ParamGenerator& generator, + const T (&expected_values)[N]) { + typename ParamGenerator::iterator it = generator.begin(); + for (size_t i = 0; i < N; ++i) { + ASSERT_FALSE(it == generator.end()) + << "At element " << i << " when accessing via an iterator " + << "created with the copy constructor.\n"; + // We cannot use EXPECT_EQ() here as the values may be tuples, + // which don't support <<. + EXPECT_TRUE(expected_values[i] == *it) + << "where i is " << i + << ", expected_values[i] is " << PrintValue(expected_values[i]) + << ", *it is " << PrintValue(*it) + << ", and 'it' is an iterator created with the copy constructor.\n"; + it++; + } + EXPECT_TRUE(it == generator.end()) + << "At the presumed end of sequence when accessing via an iterator " + << "created with the copy constructor.\n"; + + // Test the iterator assignment. The following lines verify that + // the sequence accessed via an iterator initialized via the + // assignment operator (as opposed to a copy constructor) matches + // just the same. + it = generator.begin(); + for (size_t i = 0; i < N; ++i) { + ASSERT_FALSE(it == generator.end()) + << "At element " << i << " when accessing via an iterator " + << "created with the assignment operator.\n"; + EXPECT_TRUE(expected_values[i] == *it) + << "where i is " << i + << ", expected_values[i] is " << PrintValue(expected_values[i]) + << ", *it is " << PrintValue(*it) + << ", and 'it' is an iterator created with the copy constructor.\n"; + it++; + } + EXPECT_TRUE(it == generator.end()) + << "At the presumed end of sequence when accessing via an iterator " + << "created with the assignment operator.\n"; +} + +template +void VerifyGeneratorIsEmpty(const ParamGenerator& generator) { + typename ParamGenerator::iterator it = generator.begin(); + EXPECT_TRUE(it == generator.end()); + + it = generator.begin(); + EXPECT_TRUE(it == generator.end()); +} + +// Generator tests. They test that each of the provided generator functions +// generates an expected sequence of values. The general test pattern +// instantiates a generator using one of the generator functions, +// checks the sequence produced by the generator using its iterator API, +// and then resets the iterator back to the beginning of the sequence +// and checks the sequence again. + +// Tests that iterators produced by generator functions conform to the +// ForwardIterator concept. +TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) { + const ParamGenerator gen = Range(0, 10); + ParamGenerator::iterator it = gen.begin(); + + // Verifies that iterator initialization works as expected. + ParamGenerator::iterator it2 = it; + EXPECT_TRUE(*it == *it2) << "Initialized iterators must point to the " + << "element same as its source points to"; + + // Verifies that iterator assignment works as expected. + it++; + EXPECT_FALSE(*it == *it2); + it2 = it; + EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the " + << "element same as its source points to"; + + // Verifies that prefix operator++() returns *this. + EXPECT_EQ(&it, &(++it)) << "Result of the prefix operator++ must be " + << "refer to the original object"; + + // Verifies that the result of the postfix operator++ points to the value + // pointed to by the original iterator. + int original_value = *it; // Have to compute it outside of macro call to be + // unaffected by the parameter evaluation order. + EXPECT_EQ(original_value, *(it++)); + + // Verifies that prefix and postfix operator++() advance an iterator + // all the same. + it2 = it; + it++; + ++it2; + EXPECT_TRUE(*it == *it2); +} + +// Tests that Range() generates the expected sequence. +TEST(RangeTest, IntRangeWithDefaultStep) { + const ParamGenerator gen = Range(0, 3); + const int expected_values[] = {0, 1, 2}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that Range() generates the single element sequence +// as expected when provided with range limits that are equal. +TEST(RangeTest, IntRangeSingleValue) { + const ParamGenerator gen = Range(0, 1); + const int expected_values[] = {0}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that Range() with generates empty sequence when +// supplied with an empty range. +TEST(RangeTest, IntRangeEmpty) { + const ParamGenerator gen = Range(0, 0); + VerifyGeneratorIsEmpty(gen); +} + +// Tests that Range() with custom step (greater then one) generates +// the expected sequence. +TEST(RangeTest, IntRangeWithCustomStep) { + const ParamGenerator gen = Range(0, 9, 3); + const int expected_values[] = {0, 3, 6}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Range() with custom step (greater then one) generates +// the expected sequence when the last element does not fall on the +// upper range limit. Sequences generated by Range() must not have +// elements beyond the range limits. +TEST(RangeTest, IntRangeWithCustomStepOverUpperBound) { + const ParamGenerator gen = Range(0, 4, 3); + const int expected_values[] = {0, 3}; + VerifyGenerator(gen, expected_values); +} + +// Verifies that Range works with user-defined types that define +// copy constructor, operator=(), operator+(), and operator<(). +class DogAdder { + public: + explicit DogAdder(const char* a_value) : value_(a_value) {} + DogAdder(const DogAdder& other) : value_(other.value_.c_str()) {} + + DogAdder operator=(const DogAdder& other) { + if (this != &other) + value_ = other.value_; + return *this; + } + DogAdder operator+(const DogAdder& other) const { + Message msg; + msg << value_.c_str() << other.value_.c_str(); + return DogAdder(msg.GetString().c_str()); + } + bool operator<(const DogAdder& other) const { + return value_ < other.value_; + } + const std::string& value() const { return value_; } + + private: + std::string value_; +}; + +TEST(RangeTest, WorksWithACustomType) { + const ParamGenerator gen = + Range(DogAdder("cat"), DogAdder("catdogdog"), DogAdder("dog")); + ParamGenerator::iterator it = gen.begin(); + + ASSERT_FALSE(it == gen.end()); + EXPECT_STREQ("cat", it->value().c_str()); + + ASSERT_FALSE(++it == gen.end()); + EXPECT_STREQ("catdog", it->value().c_str()); + + EXPECT_TRUE(++it == gen.end()); +} + +class IntWrapper { + public: + explicit IntWrapper(int a_value) : value_(a_value) {} + IntWrapper(const IntWrapper& other) : value_(other.value_) {} + + IntWrapper operator=(const IntWrapper& other) { + value_ = other.value_; + return *this; + } + // operator+() adds a different type. + IntWrapper operator+(int other) const { return IntWrapper(value_ + other); } + bool operator<(const IntWrapper& other) const { + return value_ < other.value_; + } + int value() const { return value_; } + + private: + int value_; +}; + +TEST(RangeTest, WorksWithACustomTypeWithDifferentIncrementType) { + const ParamGenerator gen = Range(IntWrapper(0), IntWrapper(2)); + ParamGenerator::iterator it = gen.begin(); + + ASSERT_FALSE(it == gen.end()); + EXPECT_EQ(0, it->value()); + + ASSERT_FALSE(++it == gen.end()); + EXPECT_EQ(1, it->value()); + + EXPECT_TRUE(++it == gen.end()); +} + +// Tests that ValuesIn() with an array parameter generates +// the expected sequence. +TEST(ValuesInTest, ValuesInArray) { + int array[] = {3, 5, 8}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Tests that ValuesIn() with a const array parameter generates +// the expected sequence. +TEST(ValuesInTest, ValuesInConstArray) { + const int array[] = {3, 5, 8}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Edge case. Tests that ValuesIn() with an array parameter containing a +// single element generates the single element sequence. +TEST(ValuesInTest, ValuesInSingleElementArray) { + int array[] = {42}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Tests that ValuesIn() generates the expected sequence for an STL +// container (vector). +TEST(ValuesInTest, ValuesInVector) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(3); + values.push_back(5); + values.push_back(8); + const ParamGenerator gen = ValuesIn(values); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Tests that ValuesIn() generates the expected sequence. +TEST(ValuesInTest, ValuesInIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(3); + values.push_back(5); + values.push_back(8); + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that ValuesIn() provided with an iterator range specifying a +// single value generates a single-element sequence. +TEST(ValuesInTest, ValuesInSingleElementIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(42); + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + const int expected_values[] = {42}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that ValuesIn() provided with an empty iterator range +// generates an empty sequence. +TEST(ValuesInTest, ValuesInEmptyIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + VerifyGeneratorIsEmpty(gen); +} + +// Tests that the Values() generates the expected sequence. +TEST(ValuesTest, ValuesWorks) { + const ParamGenerator gen = Values(3, 5, 8); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Values() generates the expected sequences from elements of +// different types convertible to ParamGenerator's parameter type. +TEST(ValuesTest, ValuesWorksForValuesOfCompatibleTypes) { + const ParamGenerator gen = Values(3, 5.0f, 8.0); + + const double expected_values[] = {3.0, 5.0, 8.0}; + VerifyGenerator(gen, expected_values); +} + +TEST(ValuesTest, ValuesWorksForMaxLengthList) { + const ParamGenerator gen = Values( + 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, + 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, + 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, + 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, + 410, 420, 430, 440, 450, 460, 470, 480, 490, 500); + + const int expected_values[] = { + 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, + 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, + 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, + 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, + 410, 420, 430, 440, 450, 460, 470, 480, 490, 500}; + VerifyGenerator(gen, expected_values); +} + +// Edge case test. Tests that single-parameter Values() generates the sequence +// with the single value. +TEST(ValuesTest, ValuesWithSingleParameter) { + const ParamGenerator gen = Values(42); + + const int expected_values[] = {42}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Bool() generates sequence (false, true). +TEST(BoolTest, BoolWorks) { + const ParamGenerator gen = Bool(); + + const bool expected_values[] = {false, true}; + VerifyGenerator(gen, expected_values); +} + +# if GTEST_HAS_COMBINE + +// Tests that Combine() with two parameters generates the expected sequence. +TEST(CombineTest, CombineWithTwoParameters) { + const char* foo = "foo"; + const char* bar = "bar"; + const ParamGenerator > gen = + Combine(Values(foo, bar), Values(3, 4)); + + tuple expected_values[] = { + make_tuple(foo, 3), make_tuple(foo, 4), + make_tuple(bar, 3), make_tuple(bar, 4)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Combine() with three parameters generates the expected sequence. +TEST(CombineTest, CombineWithThreeParameters) { + const ParamGenerator > gen = Combine(Values(0, 1), + Values(3, 4), + Values(5, 6)); + tuple expected_values[] = { + make_tuple(0, 3, 5), make_tuple(0, 3, 6), + make_tuple(0, 4, 5), make_tuple(0, 4, 6), + make_tuple(1, 3, 5), make_tuple(1, 3, 6), + make_tuple(1, 4, 5), make_tuple(1, 4, 6)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that the Combine() with the first parameter generating a single value +// sequence generates a sequence with the number of elements equal to the +// number of elements in the sequence generated by the second parameter. +TEST(CombineTest, CombineWithFirstParameterSingleValue) { + const ParamGenerator > gen = Combine(Values(42), + Values(0, 1)); + + tuple expected_values[] = {make_tuple(42, 0), make_tuple(42, 1)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that the Combine() with the second parameter generating a single value +// sequence generates a sequence with the number of elements equal to the +// number of elements in the sequence generated by the first parameter. +TEST(CombineTest, CombineWithSecondParameterSingleValue) { + const ParamGenerator > gen = Combine(Values(0, 1), + Values(42)); + + tuple expected_values[] = {make_tuple(0, 42), make_tuple(1, 42)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that when the first parameter produces an empty sequence, +// Combine() produces an empty sequence, too. +TEST(CombineTest, CombineWithFirstParameterEmptyRange) { + const ParamGenerator > gen = Combine(Range(0, 0), + Values(0, 1)); + VerifyGeneratorIsEmpty(gen); +} + +// Tests that when the second parameter produces an empty sequence, +// Combine() produces an empty sequence, too. +TEST(CombineTest, CombineWithSecondParameterEmptyRange) { + const ParamGenerator > gen = Combine(Values(0, 1), + Range(1, 1)); + VerifyGeneratorIsEmpty(gen); +} + +// Edge case. Tests that combine works with the maximum number +// of parameters supported by Google Test (currently 10). +TEST(CombineTest, CombineWithMaxNumberOfParameters) { + const char* foo = "foo"; + const char* bar = "bar"; + const ParamGenerator > gen = Combine(Values(foo, bar), + Values(1), Values(2), + Values(3), Values(4), + Values(5), Values(6), + Values(7), Values(8), + Values(9)); + + tuple + expected_values[] = {make_tuple(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9), + make_tuple(bar, 1, 2, 3, 4, 5, 6, 7, 8, 9)}; + VerifyGenerator(gen, expected_values); +} + +# endif // GTEST_HAS_COMBINE + +// Tests that an generator produces correct sequence after being +// assigned from another generator. +TEST(ParamGeneratorTest, AssignmentWorks) { + ParamGenerator gen = Values(1, 2); + const ParamGenerator gen2 = Values(3, 4); + gen = gen2; + + const int expected_values[] = {3, 4}; + VerifyGenerator(gen, expected_values); +} + +// This test verifies that the tests are expanded and run as specified: +// one test per element from the sequence produced by the generator +// specified in INSTANTIATE_TEST_CASE_P. It also verifies that the test's +// fixture constructor, SetUp(), and TearDown() have run and have been +// supplied with the correct parameters. + +// The use of environment object allows detection of the case where no test +// case functionality is run at all. In this case TestCaseTearDown will not +// be able to detect missing tests, naturally. +template +class TestGenerationEnvironment : public ::testing::Environment { + public: + static TestGenerationEnvironment* Instance() { + static TestGenerationEnvironment* instance = new TestGenerationEnvironment; + return instance; + } + + void FixtureConstructorExecuted() { fixture_constructor_count_++; } + void SetUpExecuted() { set_up_count_++; } + void TearDownExecuted() { tear_down_count_++; } + void TestBodyExecuted() { test_body_count_++; } + + virtual void TearDown() { + // If all MultipleTestGenerationTest tests have been de-selected + // by the filter flag, the following checks make no sense. + bool perform_check = false; + + for (int i = 0; i < kExpectedCalls; ++i) { + Message msg; + msg << "TestsExpandedAndRun/" << i; + if (UnitTestOptions::FilterMatchesTest( + "TestExpansionModule/MultipleTestGenerationTest", + msg.GetString().c_str())) { + perform_check = true; + } + } + if (perform_check) { + EXPECT_EQ(kExpectedCalls, fixture_constructor_count_) + << "Fixture constructor of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, set_up_count_) + << "Fixture SetUp method of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, tear_down_count_) + << "Fixture TearDown method of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, test_body_count_) + << "Test in ParamTestGenerationTest test case " + << "has not been run as expected."; + } + } + + private: + TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0), + tear_down_count_(0), test_body_count_(0) {} + + int fixture_constructor_count_; + int set_up_count_; + int tear_down_count_; + int test_body_count_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationEnvironment); +}; + +const int test_generation_params[] = {36, 42, 72}; + +class TestGenerationTest : public TestWithParam { + public: + enum { + PARAMETER_COUNT = + sizeof(test_generation_params)/sizeof(test_generation_params[0]) + }; + + typedef TestGenerationEnvironment Environment; + + TestGenerationTest() { + Environment::Instance()->FixtureConstructorExecuted(); + current_parameter_ = GetParam(); + } + virtual void SetUp() { + Environment::Instance()->SetUpExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + } + virtual void TearDown() { + Environment::Instance()->TearDownExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + } + + static void SetUpTestCase() { + bool all_tests_in_test_case_selected = true; + + for (int i = 0; i < PARAMETER_COUNT; ++i) { + Message test_name; + test_name << "TestsExpandedAndRun/" << i; + if ( !UnitTestOptions::FilterMatchesTest( + "TestExpansionModule/MultipleTestGenerationTest", + test_name.GetString())) { + all_tests_in_test_case_selected = false; + } + } + EXPECT_TRUE(all_tests_in_test_case_selected) + << "When running the TestGenerationTest test case all of its tests\n" + << "must be selected by the filter flag for the test case to pass.\n" + << "If not all of them are enabled, we can't reliably conclude\n" + << "that the correct number of tests have been generated."; + + collected_parameters_.clear(); + } + + static void TearDownTestCase() { + vector expected_values(test_generation_params, + test_generation_params + PARAMETER_COUNT); + // Test execution order is not guaranteed by Google Test, + // so the order of values in collected_parameters_ can be + // different and we have to sort to compare. + sort(expected_values.begin(), expected_values.end()); + sort(collected_parameters_.begin(), collected_parameters_.end()); + + EXPECT_TRUE(collected_parameters_ == expected_values); + } + + protected: + int current_parameter_; + static vector collected_parameters_; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationTest); +}; +vector TestGenerationTest::collected_parameters_; + +TEST_P(TestGenerationTest, TestsExpandedAndRun) { + Environment::Instance()->TestBodyExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + collected_parameters_.push_back(GetParam()); +} +INSTANTIATE_TEST_CASE_P(TestExpansionModule, TestGenerationTest, + ValuesIn(test_generation_params)); + +// This test verifies that the element sequence (third parameter of +// INSTANTIATE_TEST_CASE_P) is evaluated in InitGoogleTest() and neither at +// the call site of INSTANTIATE_TEST_CASE_P nor in RUN_ALL_TESTS(). For +// that, we declare param_value_ to be a static member of +// GeneratorEvaluationTest and initialize it to 0. We set it to 1 in +// main(), just before invocation of InitGoogleTest(). After calling +// InitGoogleTest(), we set the value to 2. If the sequence is evaluated +// before or after InitGoogleTest, INSTANTIATE_TEST_CASE_P will create a +// test with parameter other than 1, and the test body will fail the +// assertion. +class GeneratorEvaluationTest : public TestWithParam { + public: + static int param_value() { return param_value_; } + static void set_param_value(int param_value) { param_value_ = param_value; } + + private: + static int param_value_; +}; +int GeneratorEvaluationTest::param_value_ = 0; + +TEST_P(GeneratorEvaluationTest, GeneratorsEvaluatedInMain) { + EXPECT_EQ(1, GetParam()); +} +INSTANTIATE_TEST_CASE_P(GenEvalModule, + GeneratorEvaluationTest, + Values(GeneratorEvaluationTest::param_value())); + +// Tests that generators defined in a different translation unit are +// functional. Generator extern_gen is defined in gtest-param-test_test2.cc. +extern ParamGenerator extern_gen; +class ExternalGeneratorTest : public TestWithParam {}; +TEST_P(ExternalGeneratorTest, ExternalGenerator) { + // Sequence produced by extern_gen contains only a single value + // which we verify here. + EXPECT_EQ(GetParam(), 33); +} +INSTANTIATE_TEST_CASE_P(ExternalGeneratorModule, + ExternalGeneratorTest, + extern_gen); + +// Tests that a parameterized test case can be defined in one translation +// unit and instantiated in another. This test will be instantiated in +// gtest-param-test_test2.cc. ExternalInstantiationTest fixture class is +// defined in gtest-param-test_test.h. +TEST_P(ExternalInstantiationTest, IsMultipleOf33) { + EXPECT_EQ(0, GetParam() % 33); +} + +// Tests that a parameterized test case can be instantiated with multiple +// generators. +class MultipleInstantiationTest : public TestWithParam {}; +TEST_P(MultipleInstantiationTest, AllowsMultipleInstances) { +} +INSTANTIATE_TEST_CASE_P(Sequence1, MultipleInstantiationTest, Values(1, 2)); +INSTANTIATE_TEST_CASE_P(Sequence2, MultipleInstantiationTest, Range(3, 5)); + +// Tests that a parameterized test case can be instantiated +// in multiple translation units. This test will be instantiated +// here and in gtest-param-test_test2.cc. +// InstantiationInMultipleTranslationUnitsTest fixture class +// is defined in gtest-param-test_test.h. +TEST_P(InstantiationInMultipleTranslaionUnitsTest, IsMultipleOf42) { + EXPECT_EQ(0, GetParam() % 42); +} +INSTANTIATE_TEST_CASE_P(Sequence1, + InstantiationInMultipleTranslaionUnitsTest, + Values(42, 42*2)); + +// Tests that each iteration of parameterized test runs in a separate test +// object. +class SeparateInstanceTest : public TestWithParam { + public: + SeparateInstanceTest() : count_(0) {} + + static void TearDownTestCase() { + EXPECT_GE(global_count_, 2) + << "If some (but not all) SeparateInstanceTest tests have been " + << "filtered out this test will fail. Make sure that all " + << "GeneratorEvaluationTest are selected or de-selected together " + << "by the test filter."; + } + + protected: + int count_; + static int global_count_; +}; +int SeparateInstanceTest::global_count_ = 0; + +TEST_P(SeparateInstanceTest, TestsRunInSeparateInstances) { + EXPECT_EQ(0, count_++); + global_count_++; +} +INSTANTIATE_TEST_CASE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4)); + +// Tests that all instantiations of a test have named appropriately. Test +// defined with TEST_P(TestCaseName, TestName) and instantiated with +// INSTANTIATE_TEST_CASE_P(SequenceName, TestCaseName, generator) must be named +// SequenceName/TestCaseName.TestName/i, where i is the 0-based index of the +// sequence element used to instantiate the test. +class NamingTest : public TestWithParam {}; + +TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name()); + + Message index_stream; + index_stream << "TestsReportCorrectNamesAndParameters/" << GetParam(); + EXPECT_STREQ(index_stream.GetString().c_str(), test_info->name()); + + EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); +} + +INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); + +// Class that cannot be streamed into an ostream. It needs to be copyable +// (and, in case of MSVC, also assignable) in order to be a test parameter +// type. Its default copy constructor and assignment operator do exactly +// what we need. +class Unstreamable { + public: + explicit Unstreamable(int value) : value_(value) {} + + private: + int value_; +}; + +class CommentTest : public TestWithParam {}; + +TEST_P(CommentTest, TestsCorrectlyReportUnstreamableParams) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); +} + +INSTANTIATE_TEST_CASE_P(InstantiationWithComments, + CommentTest, + Values(Unstreamable(1))); + +// Verify that we can create a hierarchy of test fixtures, where the base +// class fixture is not parameterized and the derived class is. In this case +// ParameterizedDerivedTest inherits from NonParameterizedBaseTest. We +// perform simple tests on both. +class NonParameterizedBaseTest : public ::testing::Test { + public: + NonParameterizedBaseTest() : n_(17) { } + protected: + int n_; +}; + +class ParameterizedDerivedTest : public NonParameterizedBaseTest, + public ::testing::WithParamInterface { + protected: + ParameterizedDerivedTest() : count_(0) { } + int count_; + static int global_count_; +}; + +int ParameterizedDerivedTest::global_count_ = 0; + +TEST_F(NonParameterizedBaseTest, FixtureIsInitialized) { + EXPECT_EQ(17, n_); +} + +TEST_P(ParameterizedDerivedTest, SeesSequence) { + EXPECT_EQ(17, n_); + EXPECT_EQ(0, count_++); + EXPECT_EQ(GetParam(), global_count_++); +} + +INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); + +#endif // GTEST_HAS_PARAM_TEST + +TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) { +#if GTEST_HAS_COMBINE && !GTEST_HAS_PARAM_TEST + FAIL() << "GTEST_HAS_COMBINE is defined while GTEST_HAS_PARAM_TEST is not\n" +#endif +} + +int main(int argc, char **argv) { +#if GTEST_HAS_PARAM_TEST + // Used in TestGenerationTest test case. + AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); + // Used in GeneratorEvaluationTest test case. Tests that the updated value + // will be picked up for instantiating tests in GeneratorEvaluationTest. + GeneratorEvaluationTest::set_param_value(1); +#endif // GTEST_HAS_PARAM_TEST + + ::testing::InitGoogleTest(&argc, argv); + +#if GTEST_HAS_PARAM_TEST + // Used in GeneratorEvaluationTest test case. Tests that value updated + // here will NOT be used for instantiating tests in + // GeneratorEvaluationTest. + GeneratorEvaluationTest::set_param_value(2); +#endif // GTEST_HAS_PARAM_TEST + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test_test.h b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test_test.h new file mode 100644 index 0000000..26ea122 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-param-test_test.h @@ -0,0 +1,57 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file provides classes and functions used internally +// for testing Google Test itself. + +#ifndef GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ +#define GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ + +#include "gtest/gtest.h" + +#if GTEST_HAS_PARAM_TEST + +// Test fixture for testing definition and instantiation of a test +// in separate translation units. +class ExternalInstantiationTest : public ::testing::TestWithParam { +}; + +// Test fixture for testing instantiation of a test in multiple +// translation units. +class InstantiationInMultipleTranslaionUnitsTest + : public ::testing::TestWithParam { +}; + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-port_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-port_test.cc new file mode 100644 index 0000000..43f1f20 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-port_test.cc @@ -0,0 +1,1253 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Authors: vladl@google.com (Vlad Losev), wan@google.com (Zhanyong Wan) +// +// This file tests the internal cross-platform support utilities. + +#include "gtest/internal/gtest-port.h" + +#include + +#if GTEST_OS_MAC +# include +#endif // GTEST_OS_MAC + +#include +#include // For std::pair and std::make_pair. +#include + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +using std::make_pair; +using std::pair; + +namespace testing { +namespace internal { + +TEST(IsXDigitTest, WorksForNarrowAscii) { + EXPECT_TRUE(IsXDigit('0')); + EXPECT_TRUE(IsXDigit('9')); + EXPECT_TRUE(IsXDigit('A')); + EXPECT_TRUE(IsXDigit('F')); + EXPECT_TRUE(IsXDigit('a')); + EXPECT_TRUE(IsXDigit('f')); + + EXPECT_FALSE(IsXDigit('-')); + EXPECT_FALSE(IsXDigit('g')); + EXPECT_FALSE(IsXDigit('G')); +} + +TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) { + EXPECT_FALSE(IsXDigit(static_cast(0x80))); + EXPECT_FALSE(IsXDigit(static_cast('0' | 0x80))); +} + +TEST(IsXDigitTest, WorksForWideAscii) { + EXPECT_TRUE(IsXDigit(L'0')); + EXPECT_TRUE(IsXDigit(L'9')); + EXPECT_TRUE(IsXDigit(L'A')); + EXPECT_TRUE(IsXDigit(L'F')); + EXPECT_TRUE(IsXDigit(L'a')); + EXPECT_TRUE(IsXDigit(L'f')); + + EXPECT_FALSE(IsXDigit(L'-')); + EXPECT_FALSE(IsXDigit(L'g')); + EXPECT_FALSE(IsXDigit(L'G')); +} + +TEST(IsXDigitTest, ReturnsFalseForWideNonAscii) { + EXPECT_FALSE(IsXDigit(static_cast(0x80))); + EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x80))); + EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x100))); +} + +class Base { + public: + // Copy constructor and assignment operator do exactly what we need, so we + // use them. + Base() : member_(0) {} + explicit Base(int n) : member_(n) {} + virtual ~Base() {} + int member() { return member_; } + + private: + int member_; +}; + +class Derived : public Base { + public: + explicit Derived(int n) : Base(n) {} +}; + +TEST(ImplicitCastTest, ConvertsPointers) { + Derived derived(0); + EXPECT_TRUE(&derived == ::testing::internal::ImplicitCast_(&derived)); +} + +TEST(ImplicitCastTest, CanUseInheritance) { + Derived derived(1); + Base base = ::testing::internal::ImplicitCast_(derived); + EXPECT_EQ(derived.member(), base.member()); +} + +class Castable { + public: + explicit Castable(bool* converted) : converted_(converted) {} + operator Base() { + *converted_ = true; + return Base(); + } + + private: + bool* converted_; +}; + +TEST(ImplicitCastTest, CanUseNonConstCastOperator) { + bool converted = false; + Castable castable(&converted); + Base base = ::testing::internal::ImplicitCast_(castable); + EXPECT_TRUE(converted); +} + +class ConstCastable { + public: + explicit ConstCastable(bool* converted) : converted_(converted) {} + operator Base() const { + *converted_ = true; + return Base(); + } + + private: + bool* converted_; +}; + +TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) { + bool converted = false; + const ConstCastable const_castable(&converted); + Base base = ::testing::internal::ImplicitCast_(const_castable); + EXPECT_TRUE(converted); +} + +class ConstAndNonConstCastable { + public: + ConstAndNonConstCastable(bool* converted, bool* const_converted) + : converted_(converted), const_converted_(const_converted) {} + operator Base() { + *converted_ = true; + return Base(); + } + operator Base() const { + *const_converted_ = true; + return Base(); + } + + private: + bool* converted_; + bool* const_converted_; +}; + +TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) { + bool converted = false; + bool const_converted = false; + ConstAndNonConstCastable castable(&converted, &const_converted); + Base base = ::testing::internal::ImplicitCast_(castable); + EXPECT_TRUE(converted); + EXPECT_FALSE(const_converted); + + converted = false; + const_converted = false; + const ConstAndNonConstCastable const_castable(&converted, &const_converted); + base = ::testing::internal::ImplicitCast_(const_castable); + EXPECT_FALSE(converted); + EXPECT_TRUE(const_converted); +} + +class To { + public: + To(bool* converted) { *converted = true; } // NOLINT +}; + +TEST(ImplicitCastTest, CanUseImplicitConstructor) { + bool converted = false; + To to = ::testing::internal::ImplicitCast_(&converted); + (void)to; + EXPECT_TRUE(converted); +} + +TEST(IteratorTraitsTest, WorksForSTLContainerIterators) { + StaticAssertTypeEq::const_iterator>::value_type>(); + StaticAssertTypeEq::iterator>::value_type>(); +} + +TEST(IteratorTraitsTest, WorksForPointerToNonConst) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); +} + +TEST(IteratorTraitsTest, WorksForPointerToConst) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); +} + +// Tests that the element_type typedef is available in scoped_ptr and refers +// to the parameter type. +TEST(ScopedPtrTest, DefinesElementType) { + StaticAssertTypeEq::element_type>(); +} + +// TODO(vladl@google.com): Implement THE REST of scoped_ptr tests. + +TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { + if (AlwaysFalse()) + GTEST_CHECK_(false) << "This should never be executed; " + "It's a compilation test only."; + + if (AlwaysTrue()) + GTEST_CHECK_(true); + else + ; // NOLINT + + if (AlwaysFalse()) + ; // NOLINT + else + GTEST_CHECK_(true) << ""; +} + +TEST(GtestCheckSyntaxTest, WorksWithSwitch) { + switch (0) { + case 1: + break; + default: + GTEST_CHECK_(true); + } + + switch (0) + case 0: + GTEST_CHECK_(true) << "Check failed in switch case"; +} + +// Verifies behavior of FormatFileLocation. +TEST(FormatFileLocationTest, FormatsFileLocation) { + EXPECT_PRED_FORMAT2(IsSubstring, "foo.cc", FormatFileLocation("foo.cc", 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation("foo.cc", 42)); +} + +TEST(FormatFileLocationTest, FormatsUnknownFile) { + EXPECT_PRED_FORMAT2( + IsSubstring, "unknown file", FormatFileLocation(NULL, 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation(NULL, 42)); +} + +TEST(FormatFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc:", FormatFileLocation("foo.cc", -1)); +} + +TEST(FormatFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file:", FormatFileLocation(NULL, -1)); +} + +// Verifies behavior of FormatCompilerIndependentFileLocation. +TEST(FormatCompilerIndependentFileLocationTest, FormatsFileLocation) { + EXPECT_EQ("foo.cc:42", FormatCompilerIndependentFileLocation("foo.cc", 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFile) { + EXPECT_EQ("unknown file:42", + FormatCompilerIndependentFileLocation(NULL, 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc", FormatCompilerIndependentFileLocation("foo.cc", -1)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1)); +} + +#if GTEST_OS_MAC || GTEST_OS_QNX +void* ThreadFunc(void* data) { + pthread_mutex_t* mutex = static_cast(data); + pthread_mutex_lock(mutex); + pthread_mutex_unlock(mutex); + return NULL; +} + +TEST(GetThreadCountTest, ReturnsCorrectValue) { + EXPECT_EQ(1U, GetThreadCount()); + pthread_mutex_t mutex; + pthread_attr_t attr; + pthread_t thread_id; + + // TODO(vladl@google.com): turn mutex into internal::Mutex for automatic + // destruction. + pthread_mutex_init(&mutex, NULL); + pthread_mutex_lock(&mutex); + ASSERT_EQ(0, pthread_attr_init(&attr)); + ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); + + const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex); + ASSERT_EQ(0, pthread_attr_destroy(&attr)); + ASSERT_EQ(0, status); + EXPECT_EQ(2U, GetThreadCount()); + pthread_mutex_unlock(&mutex); + + void* dummy; + ASSERT_EQ(0, pthread_join(thread_id, &dummy)); + +# if GTEST_OS_MAC + + // MacOS X may not immediately report the updated thread count after + // joining a thread, causing flakiness in this test. To counter that, we + // wait for up to .5 seconds for the OS to report the correct value. + for (int i = 0; i < 5; ++i) { + if (GetThreadCount() == 1) + break; + + SleepMilliseconds(100); + } + +# endif // GTEST_OS_MAC + + EXPECT_EQ(1U, GetThreadCount()); + pthread_mutex_destroy(&mutex); +} +#else +TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { + EXPECT_EQ(0U, GetThreadCount()); +} +#endif // GTEST_OS_MAC || GTEST_OS_QNX + +TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { + const bool a_false_condition = false; + const char regex[] = +#ifdef _MSC_VER + "gtest-port_test\\.cc\\(\\d+\\):" +#elif GTEST_USES_POSIX_RE + "gtest-port_test\\.cc:[0-9]+" +#else + "gtest-port_test\\.cc:\\d+" +#endif // _MSC_VER + ".*a_false_condition.*Extra info.*"; + + EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info", + regex); +} + +#if GTEST_HAS_DEATH_TEST + +TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { + EXPECT_EXIT({ + GTEST_CHECK_(true) << "Extra info"; + ::std::cerr << "Success\n"; + exit(0); }, + ::testing::ExitedWithCode(0), "Success"); +} + +#endif // GTEST_HAS_DEATH_TEST + +// Verifies that Google Test choose regular expression engine appropriate to +// the platform. The test will produce compiler errors in case of failure. +// For simplicity, we only cover the most important platforms here. +TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) { +#if GTEST_HAS_POSIX_RE + + EXPECT_TRUE(GTEST_USES_POSIX_RE); + +#else + + EXPECT_TRUE(GTEST_USES_SIMPLE_RE); + +#endif +} + +#if GTEST_USES_POSIX_RE + +# if GTEST_HAS_TYPED_TEST + +template +class RETest : public ::testing::Test {}; + +// Defines StringTypes as the list of all string types that class RE +// supports. +typedef testing::Types< + ::std::string, +# if GTEST_HAS_GLOBAL_STRING + ::string, +# endif // GTEST_HAS_GLOBAL_STRING + const char*> StringTypes; + +TYPED_TEST_CASE(RETest, StringTypes); + +// Tests RE's implicit constructors. +TYPED_TEST(RETest, ImplicitConstructorWorks) { + const RE empty(TypeParam("")); + EXPECT_STREQ("", empty.pattern()); + + const RE simple(TypeParam("hello")); + EXPECT_STREQ("hello", simple.pattern()); + + const RE normal(TypeParam(".*(\\w+)")); + EXPECT_STREQ(".*(\\w+)", normal.pattern()); +} + +// Tests that RE's constructors reject invalid regular expressions. +TYPED_TEST(RETest, RejectsInvalidRegex) { + EXPECT_NONFATAL_FAILURE({ + const RE invalid(TypeParam("?")); + }, "\"?\" is not a valid POSIX Extended regular expression."); +} + +// Tests RE::FullMatch(). +TYPED_TEST(RETest, FullMatchWorks) { + const RE empty(TypeParam("")); + EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty)); + EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty)); + + const RE re(TypeParam("a.*z")); + EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re)); + EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re)); + EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re)); + EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re)); +} + +// Tests RE::PartialMatch(). +TYPED_TEST(RETest, PartialMatchWorks) { + const RE empty(TypeParam("")); + EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty)); + + const RE re(TypeParam("a.*z")); + EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re)); + EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); +} + +# endif // GTEST_HAS_TYPED_TEST + +#elif GTEST_USES_SIMPLE_RE + +TEST(IsInSetTest, NulCharIsNotInAnySet) { + EXPECT_FALSE(IsInSet('\0', "")); + EXPECT_FALSE(IsInSet('\0', "\0")); + EXPECT_FALSE(IsInSet('\0', "a")); +} + +TEST(IsInSetTest, WorksForNonNulChars) { + EXPECT_FALSE(IsInSet('a', "Ab")); + EXPECT_FALSE(IsInSet('c', "")); + + EXPECT_TRUE(IsInSet('b', "bcd")); + EXPECT_TRUE(IsInSet('b', "ab")); +} + +TEST(IsAsciiDigitTest, IsFalseForNonDigit) { + EXPECT_FALSE(IsAsciiDigit('\0')); + EXPECT_FALSE(IsAsciiDigit(' ')); + EXPECT_FALSE(IsAsciiDigit('+')); + EXPECT_FALSE(IsAsciiDigit('-')); + EXPECT_FALSE(IsAsciiDigit('.')); + EXPECT_FALSE(IsAsciiDigit('a')); +} + +TEST(IsAsciiDigitTest, IsTrueForDigit) { + EXPECT_TRUE(IsAsciiDigit('0')); + EXPECT_TRUE(IsAsciiDigit('1')); + EXPECT_TRUE(IsAsciiDigit('5')); + EXPECT_TRUE(IsAsciiDigit('9')); +} + +TEST(IsAsciiPunctTest, IsFalseForNonPunct) { + EXPECT_FALSE(IsAsciiPunct('\0')); + EXPECT_FALSE(IsAsciiPunct(' ')); + EXPECT_FALSE(IsAsciiPunct('\n')); + EXPECT_FALSE(IsAsciiPunct('a')); + EXPECT_FALSE(IsAsciiPunct('0')); +} + +TEST(IsAsciiPunctTest, IsTrueForPunct) { + for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) { + EXPECT_PRED1(IsAsciiPunct, *p); + } +} + +TEST(IsRepeatTest, IsFalseForNonRepeatChar) { + EXPECT_FALSE(IsRepeat('\0')); + EXPECT_FALSE(IsRepeat(' ')); + EXPECT_FALSE(IsRepeat('a')); + EXPECT_FALSE(IsRepeat('1')); + EXPECT_FALSE(IsRepeat('-')); +} + +TEST(IsRepeatTest, IsTrueForRepeatChar) { + EXPECT_TRUE(IsRepeat('?')); + EXPECT_TRUE(IsRepeat('*')); + EXPECT_TRUE(IsRepeat('+')); +} + +TEST(IsAsciiWhiteSpaceTest, IsFalseForNonWhiteSpace) { + EXPECT_FALSE(IsAsciiWhiteSpace('\0')); + EXPECT_FALSE(IsAsciiWhiteSpace('a')); + EXPECT_FALSE(IsAsciiWhiteSpace('1')); + EXPECT_FALSE(IsAsciiWhiteSpace('+')); + EXPECT_FALSE(IsAsciiWhiteSpace('_')); +} + +TEST(IsAsciiWhiteSpaceTest, IsTrueForWhiteSpace) { + EXPECT_TRUE(IsAsciiWhiteSpace(' ')); + EXPECT_TRUE(IsAsciiWhiteSpace('\n')); + EXPECT_TRUE(IsAsciiWhiteSpace('\r')); + EXPECT_TRUE(IsAsciiWhiteSpace('\t')); + EXPECT_TRUE(IsAsciiWhiteSpace('\v')); + EXPECT_TRUE(IsAsciiWhiteSpace('\f')); +} + +TEST(IsAsciiWordCharTest, IsFalseForNonWordChar) { + EXPECT_FALSE(IsAsciiWordChar('\0')); + EXPECT_FALSE(IsAsciiWordChar('+')); + EXPECT_FALSE(IsAsciiWordChar('.')); + EXPECT_FALSE(IsAsciiWordChar(' ')); + EXPECT_FALSE(IsAsciiWordChar('\n')); +} + +TEST(IsAsciiWordCharTest, IsTrueForLetter) { + EXPECT_TRUE(IsAsciiWordChar('a')); + EXPECT_TRUE(IsAsciiWordChar('b')); + EXPECT_TRUE(IsAsciiWordChar('A')); + EXPECT_TRUE(IsAsciiWordChar('Z')); +} + +TEST(IsAsciiWordCharTest, IsTrueForDigit) { + EXPECT_TRUE(IsAsciiWordChar('0')); + EXPECT_TRUE(IsAsciiWordChar('1')); + EXPECT_TRUE(IsAsciiWordChar('7')); + EXPECT_TRUE(IsAsciiWordChar('9')); +} + +TEST(IsAsciiWordCharTest, IsTrueForUnderscore) { + EXPECT_TRUE(IsAsciiWordChar('_')); +} + +TEST(IsValidEscapeTest, IsFalseForNonPrintable) { + EXPECT_FALSE(IsValidEscape('\0')); + EXPECT_FALSE(IsValidEscape('\007')); +} + +TEST(IsValidEscapeTest, IsFalseForDigit) { + EXPECT_FALSE(IsValidEscape('0')); + EXPECT_FALSE(IsValidEscape('9')); +} + +TEST(IsValidEscapeTest, IsFalseForWhiteSpace) { + EXPECT_FALSE(IsValidEscape(' ')); + EXPECT_FALSE(IsValidEscape('\n')); +} + +TEST(IsValidEscapeTest, IsFalseForSomeLetter) { + EXPECT_FALSE(IsValidEscape('a')); + EXPECT_FALSE(IsValidEscape('Z')); +} + +TEST(IsValidEscapeTest, IsTrueForPunct) { + EXPECT_TRUE(IsValidEscape('.')); + EXPECT_TRUE(IsValidEscape('-')); + EXPECT_TRUE(IsValidEscape('^')); + EXPECT_TRUE(IsValidEscape('$')); + EXPECT_TRUE(IsValidEscape('(')); + EXPECT_TRUE(IsValidEscape(']')); + EXPECT_TRUE(IsValidEscape('{')); + EXPECT_TRUE(IsValidEscape('|')); +} + +TEST(IsValidEscapeTest, IsTrueForSomeLetter) { + EXPECT_TRUE(IsValidEscape('d')); + EXPECT_TRUE(IsValidEscape('D')); + EXPECT_TRUE(IsValidEscape('s')); + EXPECT_TRUE(IsValidEscape('S')); + EXPECT_TRUE(IsValidEscape('w')); + EXPECT_TRUE(IsValidEscape('W')); +} + +TEST(AtomMatchesCharTest, EscapedPunct) { + EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, '\\', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, '_', '.')); + EXPECT_FALSE(AtomMatchesChar(true, '.', 'a')); + + EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\')); + EXPECT_TRUE(AtomMatchesChar(true, '_', '_')); + EXPECT_TRUE(AtomMatchesChar(true, '+', '+')); + EXPECT_TRUE(AtomMatchesChar(true, '.', '.')); +} + +TEST(AtomMatchesCharTest, Escaped_d) { + EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 'd', '.')); + + EXPECT_TRUE(AtomMatchesChar(true, 'd', '0')); + EXPECT_TRUE(AtomMatchesChar(true, 'd', '9')); +} + +TEST(AtomMatchesCharTest, Escaped_D) { + EXPECT_FALSE(AtomMatchesChar(true, 'D', '0')); + EXPECT_FALSE(AtomMatchesChar(true, 'D', '9')); + + EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a')); + EXPECT_TRUE(AtomMatchesChar(true, 'D', '-')); +} + +TEST(AtomMatchesCharTest, Escaped_s) { + EXPECT_FALSE(AtomMatchesChar(true, 's', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 's', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 's', '.')); + EXPECT_FALSE(AtomMatchesChar(true, 's', '9')); + + EXPECT_TRUE(AtomMatchesChar(true, 's', ' ')); + EXPECT_TRUE(AtomMatchesChar(true, 's', '\n')); + EXPECT_TRUE(AtomMatchesChar(true, 's', '\t')); +} + +TEST(AtomMatchesCharTest, Escaped_S) { + EXPECT_FALSE(AtomMatchesChar(true, 'S', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r')); + + EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a')); + EXPECT_TRUE(AtomMatchesChar(true, 'S', '9')); +} + +TEST(AtomMatchesCharTest, Escaped_w) { + EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', '+')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n')); + + EXPECT_TRUE(AtomMatchesChar(true, 'w', '0')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', '_')); +} + +TEST(AtomMatchesCharTest, Escaped_W) { + EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', '9')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', '_')); + + EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'W', '*')); + EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n')); +} + +TEST(AtomMatchesCharTest, EscapedWhiteSpace) { + EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n')); + EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r')); + EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 't', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 't', 't')); + EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f')); + + EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f')); + EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n')); + EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r')); + EXPECT_TRUE(AtomMatchesChar(true, 't', '\t')); + EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v')); +} + +TEST(AtomMatchesCharTest, UnescapedDot) { + EXPECT_FALSE(AtomMatchesChar(false, '.', '\n')); + + EXPECT_TRUE(AtomMatchesChar(false, '.', '\0')); + EXPECT_TRUE(AtomMatchesChar(false, '.', '.')); + EXPECT_TRUE(AtomMatchesChar(false, '.', 'a')); + EXPECT_TRUE(AtomMatchesChar(false, '.', ' ')); +} + +TEST(AtomMatchesCharTest, UnescapedChar) { + EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0')); + EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b')); + EXPECT_FALSE(AtomMatchesChar(false, '$', 'a')); + + EXPECT_TRUE(AtomMatchesChar(false, '$', '$')); + EXPECT_TRUE(AtomMatchesChar(false, '5', '5')); + EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z')); +} + +TEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) { + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)), + "NULL is not a valid simple regular expression"); + EXPECT_NONFATAL_FAILURE( + ASSERT_FALSE(ValidateRegex("a\\")), + "Syntax error at index 1 in simple regular expression \"a\\\": "); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")), + "'\\' cannot appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")), + "'\\' cannot appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")), + "invalid escape sequence \"\\h\""); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")), + "'^' can only appear at the beginning"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")), + "'^' can only appear at the beginning"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")), + "'$' can only appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")), + "'$' can only appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")), + "'(' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")), + "')' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")), + "'[' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")), + "'{' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")), + "'?' can only follow a repeatable token"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")), + "'*' can only follow a repeatable token"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")), + "'+' can only follow a repeatable token"); +} + +TEST(ValidateRegexTest, ReturnsTrueForValid) { + EXPECT_TRUE(ValidateRegex("")); + EXPECT_TRUE(ValidateRegex("a")); + EXPECT_TRUE(ValidateRegex(".*")); + EXPECT_TRUE(ValidateRegex("^a_+")); + EXPECT_TRUE(ValidateRegex("^a\\t\\&?")); + EXPECT_TRUE(ValidateRegex("09*$")); + EXPECT_TRUE(ValidateRegex("^Z$")); + EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba")); + // Repeating more than once. + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab")); + + // Repeating zero times. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba")); + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab")); + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab")); + + // Repeating zero times. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc")); + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc")); + // Repeating more than once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab")); + // Repeating zero times. + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc")); + + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc")); + // Repeating more than once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g")); +} + +TEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) { + EXPECT_TRUE(MatchRegexAtHead("", "")); + EXPECT_TRUE(MatchRegexAtHead("", "ab")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) { + EXPECT_FALSE(MatchRegexAtHead("$", "a")); + + EXPECT_TRUE(MatchRegexAtHead("$", "")); + EXPECT_TRUE(MatchRegexAtHead("a$", "a")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) { + EXPECT_FALSE(MatchRegexAtHead("\\w", "+")); + EXPECT_FALSE(MatchRegexAtHead("\\W", "ab")); + + EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab")); + EXPECT_TRUE(MatchRegexAtHead("\\d", "1a")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) { + EXPECT_FALSE(MatchRegexAtHead(".+a", "abc")); + EXPECT_FALSE(MatchRegexAtHead("a?b", "aab")); + + EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab")); + EXPECT_TRUE(MatchRegexAtHead("a?b", "b")); + EXPECT_TRUE(MatchRegexAtHead("a?b", "ab")); +} + +TEST(MatchRegexAtHeadTest, + WorksWhenRegexStartsWithRepetionOfEscapeSequence) { + EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc")); + EXPECT_FALSE(MatchRegexAtHead("\\s?b", " b")); + + EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab")); + EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b")); + EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b")); + EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b")); +} + +TEST(MatchRegexAtHeadTest, MatchesSequentially) { + EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc")); + + EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc")); +} + +TEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) { + EXPECT_FALSE(MatchRegexAnywhere("", NULL)); +} + +TEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) { + EXPECT_FALSE(MatchRegexAnywhere("^a", "ba")); + EXPECT_FALSE(MatchRegexAnywhere("^$", "a")); + + EXPECT_TRUE(MatchRegexAnywhere("^a", "ab")); + EXPECT_TRUE(MatchRegexAnywhere("^", "ab")); + EXPECT_TRUE(MatchRegexAnywhere("^$", "")); +} + +TEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) { + EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123")); + EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888")); +} + +TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) { + EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5")); + EXPECT_TRUE(MatchRegexAnywhere(".*=", "=")); + EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc")); +} + +TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) { + EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5")); + EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "= ...=")); +} + +// Tests RE's implicit constructors. +TEST(RETest, ImplicitConstructorWorks) { + const RE empty(""); + EXPECT_STREQ("", empty.pattern()); + + const RE simple("hello"); + EXPECT_STREQ("hello", simple.pattern()); +} + +// Tests that RE's constructors reject invalid regular expressions. +TEST(RETest, RejectsInvalidRegex) { + EXPECT_NONFATAL_FAILURE({ + const RE normal(NULL); + }, "NULL is not a valid simple regular expression"); + + EXPECT_NONFATAL_FAILURE({ + const RE normal(".*(\\w+"); + }, "'(' is unsupported"); + + EXPECT_NONFATAL_FAILURE({ + const RE invalid("^?"); + }, "'?' can only follow a repeatable token"); +} + +// Tests RE::FullMatch(). +TEST(RETest, FullMatchWorks) { + const RE empty(""); + EXPECT_TRUE(RE::FullMatch("", empty)); + EXPECT_FALSE(RE::FullMatch("a", empty)); + + const RE re1("a"); + EXPECT_TRUE(RE::FullMatch("a", re1)); + + const RE re("a.*z"); + EXPECT_TRUE(RE::FullMatch("az", re)); + EXPECT_TRUE(RE::FullMatch("axyz", re)); + EXPECT_FALSE(RE::FullMatch("baz", re)); + EXPECT_FALSE(RE::FullMatch("azy", re)); +} + +// Tests RE::PartialMatch(). +TEST(RETest, PartialMatchWorks) { + const RE empty(""); + EXPECT_TRUE(RE::PartialMatch("", empty)); + EXPECT_TRUE(RE::PartialMatch("a", empty)); + + const RE re("a.*z"); + EXPECT_TRUE(RE::PartialMatch("az", re)); + EXPECT_TRUE(RE::PartialMatch("axyz", re)); + EXPECT_TRUE(RE::PartialMatch("baz", re)); + EXPECT_TRUE(RE::PartialMatch("azy", re)); + EXPECT_FALSE(RE::PartialMatch("zza", re)); +} + +#endif // GTEST_USES_POSIX_RE + +#if !GTEST_OS_WINDOWS_MOBILE + +TEST(CaptureTest, CapturesStdout) { + CaptureStdout(); + fprintf(stdout, "abc"); + EXPECT_STREQ("abc", GetCapturedStdout().c_str()); + + CaptureStdout(); + fprintf(stdout, "def%cghi", '\0'); + EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout())); +} + +TEST(CaptureTest, CapturesStderr) { + CaptureStderr(); + fprintf(stderr, "jkl"); + EXPECT_STREQ("jkl", GetCapturedStderr().c_str()); + + CaptureStderr(); + fprintf(stderr, "jkl%cmno", '\0'); + EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr())); +} + +// Tests that stdout and stderr capture don't interfere with each other. +TEST(CaptureTest, CapturesStdoutAndStderr) { + CaptureStdout(); + CaptureStderr(); + fprintf(stdout, "pqr"); + fprintf(stderr, "stu"); + EXPECT_STREQ("pqr", GetCapturedStdout().c_str()); + EXPECT_STREQ("stu", GetCapturedStderr().c_str()); +} + +TEST(CaptureDeathTest, CannotReenterStdoutCapture) { + CaptureStdout(); + EXPECT_DEATH_IF_SUPPORTED(CaptureStdout(), + "Only one stdout capturer can exist at a time"); + GetCapturedStdout(); + + // We cannot test stderr capturing using death tests as they use it + // themselves. +} + +#endif // !GTEST_OS_WINDOWS_MOBILE + +TEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) { + ThreadLocal t1; + EXPECT_EQ(0, t1.get()); + + ThreadLocal t2; + EXPECT_TRUE(t2.get() == NULL); +} + +TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) { + ThreadLocal t1(123); + EXPECT_EQ(123, t1.get()); + + int i = 0; + ThreadLocal t2(&i); + EXPECT_EQ(&i, t2.get()); +} + +class NoDefaultContructor { + public: + explicit NoDefaultContructor(const char*) {} + NoDefaultContructor(const NoDefaultContructor&) {} +}; + +TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) { + ThreadLocal bar(NoDefaultContructor("foo")); + bar.pointer(); +} + +TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { + ThreadLocal thread_local_string; + + EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); + + // Verifies the condition still holds after calling set. + thread_local_string.set("foo"); + EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); +} + +TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { + ThreadLocal thread_local_string; + const ThreadLocal& const_thread_local_string = + thread_local_string; + + EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); + + thread_local_string.set("foo"); + EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); +} + +#if GTEST_IS_THREADSAFE + +void AddTwo(int* param) { *param += 2; } + +TEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) { + int i = 40; + ThreadWithParam thread(&AddTwo, &i, NULL); + thread.Join(); + EXPECT_EQ(42, i); +} + +TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { + // AssertHeld() is flaky only in the presence of multiple threads accessing + // the lock. In this case, the test is robust. + EXPECT_DEATH_IF_SUPPORTED({ + Mutex m; + { MutexLock lock(&m); } + m.AssertHeld(); + }, + "thread .*hold"); +} + +TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) { + Mutex m; + MutexLock lock(&m); + m.AssertHeld(); +} + +class AtomicCounterWithMutex { + public: + explicit AtomicCounterWithMutex(Mutex* mutex) : + value_(0), mutex_(mutex), random_(42) {} + + void Increment() { + MutexLock lock(mutex_); + int temp = value_; + { + // Locking a mutex puts up a memory barrier, preventing reads and + // writes to value_ rearranged when observed from other threads. + // + // We cannot use Mutex and MutexLock here or rely on their memory + // barrier functionality as we are testing them here. + pthread_mutex_t memory_barrier_mutex; + GTEST_CHECK_POSIX_SUCCESS_( + pthread_mutex_init(&memory_barrier_mutex, NULL)); + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex)); + + SleepMilliseconds(random_.Generate(30)); + + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex)); + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex)); + } + value_ = temp + 1; + } + int value() const { return value_; } + + private: + volatile int value_; + Mutex* const mutex_; // Protects value_. + Random random_; +}; + +void CountingThreadFunc(pair param) { + for (int i = 0; i < param.second; ++i) + param.first->Increment(); +} + +// Tests that the mutex only lets one thread at a time to lock it. +TEST(MutexTest, OnlyOneThreadCanLockAtATime) { + Mutex mutex; + AtomicCounterWithMutex locked_counter(&mutex); + + typedef ThreadWithParam > ThreadType; + const int kCycleCount = 20; + const int kThreadCount = 7; + scoped_ptr counting_threads[kThreadCount]; + Notification threads_can_start; + // Creates and runs kThreadCount threads that increment locked_counter + // kCycleCount times each. + for (int i = 0; i < kThreadCount; ++i) { + counting_threads[i].reset(new ThreadType(&CountingThreadFunc, + make_pair(&locked_counter, + kCycleCount), + &threads_can_start)); + } + threads_can_start.Notify(); + for (int i = 0; i < kThreadCount; ++i) + counting_threads[i]->Join(); + + // If the mutex lets more than one thread to increment the counter at a + // time, they are likely to encounter a race condition and have some + // increments overwritten, resulting in the lower then expected counter + // value. + EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value()); +} + +template +void RunFromThread(void (func)(T), T param) { + ThreadWithParam thread(func, param, NULL); + thread.Join(); +} + +void RetrieveThreadLocalValue( + pair*, std::string*> param) { + *param.second = param.first->get(); +} + +TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { + ThreadLocal thread_local_string("foo"); + EXPECT_STREQ("foo", thread_local_string.get().c_str()); + + thread_local_string.set("bar"); + EXPECT_STREQ("bar", thread_local_string.get().c_str()); + + std::string result; + RunFromThread(&RetrieveThreadLocalValue, + make_pair(&thread_local_string, &result)); + EXPECT_STREQ("foo", result.c_str()); +} + +// DestructorTracker keeps track of whether its instances have been +// destroyed. +static std::vector g_destroyed; + +class DestructorTracker { + public: + DestructorTracker() : index_(GetNewIndex()) {} + DestructorTracker(const DestructorTracker& /* rhs */) + : index_(GetNewIndex()) {} + ~DestructorTracker() { + // We never access g_destroyed concurrently, so we don't need to + // protect the write operation under a mutex. + g_destroyed[index_] = true; + } + + private: + static int GetNewIndex() { + g_destroyed.push_back(false); + return g_destroyed.size() - 1; + } + const int index_; +}; + +typedef ThreadLocal* ThreadParam; + +void CallThreadLocalGet(ThreadParam thread_local_param) { + thread_local_param->get(); +} + +// Tests that when a ThreadLocal object dies in a thread, it destroys +// the managed object for that thread. +TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) { + g_destroyed.clear(); + + { + // The next line default constructs a DestructorTracker object as + // the default value of objects managed by thread_local_tracker. + ThreadLocal thread_local_tracker; + ASSERT_EQ(1U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + + // This creates another DestructorTracker object for the main thread. + thread_local_tracker.get(); + ASSERT_EQ(2U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + ASSERT_FALSE(g_destroyed[1]); + } + + // Now thread_local_tracker has died. It should have destroyed both the + // default value shared by all threads and the value for the main + // thread. + ASSERT_EQ(2U, g_destroyed.size()); + EXPECT_TRUE(g_destroyed[0]); + EXPECT_TRUE(g_destroyed[1]); + + g_destroyed.clear(); +} + +// Tests that when a thread exits, the thread-local object for that +// thread is destroyed. +TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { + g_destroyed.clear(); + + { + // The next line default constructs a DestructorTracker object as + // the default value of objects managed by thread_local_tracker. + ThreadLocal thread_local_tracker; + ASSERT_EQ(1U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + + // This creates another DestructorTracker object in the new thread. + ThreadWithParam thread( + &CallThreadLocalGet, &thread_local_tracker, NULL); + thread.Join(); + + // Now the new thread has exited. The per-thread object for it + // should have been destroyed. + ASSERT_EQ(2U, g_destroyed.size()); + ASSERT_FALSE(g_destroyed[0]); + ASSERT_TRUE(g_destroyed[1]); + } + + // Now thread_local_tracker has died. The default value should have been + // destroyed too. + ASSERT_EQ(2U, g_destroyed.size()); + EXPECT_TRUE(g_destroyed[0]); + EXPECT_TRUE(g_destroyed[1]); + + g_destroyed.clear(); +} + +TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { + ThreadLocal thread_local_string; + thread_local_string.set("Foo"); + EXPECT_STREQ("Foo", thread_local_string.get().c_str()); + + std::string result; + RunFromThread(&RetrieveThreadLocalValue, + make_pair(&thread_local_string, &result)); + EXPECT_TRUE(result.empty()); +} + +#endif // GTEST_IS_THREADSAFE + +} // namespace internal +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-printers_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-printers_test.cc new file mode 100644 index 0000000..45610f8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-printers_test.cc @@ -0,0 +1,1561 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file tests the universal value printer. + +#include "gtest/gtest-printers.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" + +// hash_map and hash_set are available under Visual C++. +#if _MSC_VER +# define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available. +# include // NOLINT +# define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available. +# include // NOLINT +#endif // GTEST_OS_WINDOWS + +// Some user-defined types for testing the universal value printer. + +// An anonymous enum type. +enum AnonymousEnum { + kAE1 = -1, + kAE2 = 1 +}; + +// An enum without a user-defined printer. +enum EnumWithoutPrinter { + kEWP1 = -2, + kEWP2 = 42 +}; + +// An enum with a << operator. +enum EnumWithStreaming { + kEWS1 = 10 +}; + +std::ostream& operator<<(std::ostream& os, EnumWithStreaming e) { + return os << (e == kEWS1 ? "kEWS1" : "invalid"); +} + +// An enum with a PrintTo() function. +enum EnumWithPrintTo { + kEWPT1 = 1 +}; + +void PrintTo(EnumWithPrintTo e, std::ostream* os) { + *os << (e == kEWPT1 ? "kEWPT1" : "invalid"); +} + +// A class implicitly convertible to BiggestInt. +class BiggestIntConvertible { + public: + operator ::testing::internal::BiggestInt() const { return 42; } +}; + +// A user-defined unprintable class template in the global namespace. +template +class UnprintableTemplateInGlobal { + public: + UnprintableTemplateInGlobal() : value_() {} + private: + T value_; +}; + +// A user-defined streamable type in the global namespace. +class StreamableInGlobal { + public: + virtual ~StreamableInGlobal() {} +}; + +inline void operator<<(::std::ostream& os, const StreamableInGlobal& /* x */) { + os << "StreamableInGlobal"; +} + +void operator<<(::std::ostream& os, const StreamableInGlobal* /* x */) { + os << "StreamableInGlobal*"; +} + +namespace foo { + +// A user-defined unprintable type in a user namespace. +class UnprintableInFoo { + public: + UnprintableInFoo() : z_(0) { memcpy(xy_, "\xEF\x12\x0\x0\x34\xAB\x0\x0", 8); } + private: + char xy_[8]; + double z_; +}; + +// A user-defined printable type in a user-chosen namespace. +struct PrintableViaPrintTo { + PrintableViaPrintTo() : value() {} + int value; +}; + +void PrintTo(const PrintableViaPrintTo& x, ::std::ostream* os) { + *os << "PrintableViaPrintTo: " << x.value; +} + +// A type with a user-defined << for printing its pointer. +struct PointerPrintable { +}; + +::std::ostream& operator<<(::std::ostream& os, + const PointerPrintable* /* x */) { + return os << "PointerPrintable*"; +} + +// A user-defined printable class template in a user-chosen namespace. +template +class PrintableViaPrintToTemplate { + public: + explicit PrintableViaPrintToTemplate(const T& a_value) : value_(a_value) {} + + const T& value() const { return value_; } + private: + T value_; +}; + +template +void PrintTo(const PrintableViaPrintToTemplate& x, ::std::ostream* os) { + *os << "PrintableViaPrintToTemplate: " << x.value(); +} + +// A user-defined streamable class template in a user namespace. +template +class StreamableTemplateInFoo { + public: + StreamableTemplateInFoo() : value_() {} + + const T& value() const { return value_; } + private: + T value_; +}; + +template +inline ::std::ostream& operator<<(::std::ostream& os, + const StreamableTemplateInFoo& x) { + return os << "StreamableTemplateInFoo: " << x.value(); +} + +} // namespace foo + +namespace testing { +namespace gtest_printers_test { + +using ::std::deque; +using ::std::list; +using ::std::make_pair; +using ::std::map; +using ::std::multimap; +using ::std::multiset; +using ::std::pair; +using ::std::set; +using ::std::vector; +using ::testing::PrintToString; +using ::testing::internal::FormatForComparisonFailureMessage; +using ::testing::internal::ImplicitCast_; +using ::testing::internal::NativeArray; +using ::testing::internal::RE; +using ::testing::internal::Strings; +using ::testing::internal::UniversalPrint; +using ::testing::internal::UniversalPrinter; +using ::testing::internal::UniversalTersePrint; +using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; +using ::testing::internal::kReference; +using ::testing::internal::string; + +#if GTEST_HAS_TR1_TUPLE +using ::std::tr1::make_tuple; +using ::std::tr1::tuple; +#endif + +#if _MSC_VER +// MSVC defines the following classes in the ::stdext namespace while +// gcc defines them in the :: namespace. Note that they are not part +// of the C++ standard. +using ::stdext::hash_map; +using ::stdext::hash_set; +using ::stdext::hash_multimap; +using ::stdext::hash_multiset; +#endif + +// Prints a value to a string using the universal value printer. This +// is a helper for testing UniversalPrinter::Print() for various types. +template +string Print(const T& value) { + ::std::stringstream ss; + UniversalPrinter::Print(value, &ss); + return ss.str(); +} + +// Prints a value passed by reference to a string, using the universal +// value printer. This is a helper for testing +// UniversalPrinter::Print() for various types. +template +string PrintByRef(const T& value) { + ::std::stringstream ss; + UniversalPrinter::Print(value, &ss); + return ss.str(); +} + +// Tests printing various enum types. + +TEST(PrintEnumTest, AnonymousEnum) { + EXPECT_EQ("-1", Print(kAE1)); + EXPECT_EQ("1", Print(kAE2)); +} + +TEST(PrintEnumTest, EnumWithoutPrinter) { + EXPECT_EQ("-2", Print(kEWP1)); + EXPECT_EQ("42", Print(kEWP2)); +} + +TEST(PrintEnumTest, EnumWithStreaming) { + EXPECT_EQ("kEWS1", Print(kEWS1)); + EXPECT_EQ("invalid", Print(static_cast(0))); +} + +TEST(PrintEnumTest, EnumWithPrintTo) { + EXPECT_EQ("kEWPT1", Print(kEWPT1)); + EXPECT_EQ("invalid", Print(static_cast(0))); +} + +// Tests printing a class implicitly convertible to BiggestInt. + +TEST(PrintClassTest, BiggestIntConvertible) { + EXPECT_EQ("42", Print(BiggestIntConvertible())); +} + +// Tests printing various char types. + +// char. +TEST(PrintCharTest, PlainChar) { + EXPECT_EQ("'\\0'", Print('\0')); + EXPECT_EQ("'\\'' (39, 0x27)", Print('\'')); + EXPECT_EQ("'\"' (34, 0x22)", Print('"')); + EXPECT_EQ("'?' (63, 0x3F)", Print('?')); + EXPECT_EQ("'\\\\' (92, 0x5C)", Print('\\')); + EXPECT_EQ("'\\a' (7)", Print('\a')); + EXPECT_EQ("'\\b' (8)", Print('\b')); + EXPECT_EQ("'\\f' (12, 0xC)", Print('\f')); + EXPECT_EQ("'\\n' (10, 0xA)", Print('\n')); + EXPECT_EQ("'\\r' (13, 0xD)", Print('\r')); + EXPECT_EQ("'\\t' (9)", Print('\t')); + EXPECT_EQ("'\\v' (11, 0xB)", Print('\v')); + EXPECT_EQ("'\\x7F' (127)", Print('\x7F')); + EXPECT_EQ("'\\xFF' (255)", Print('\xFF')); + EXPECT_EQ("' ' (32, 0x20)", Print(' ')); + EXPECT_EQ("'a' (97, 0x61)", Print('a')); +} + +// signed char. +TEST(PrintCharTest, SignedChar) { + EXPECT_EQ("'\\0'", Print(static_cast('\0'))); + EXPECT_EQ("'\\xCE' (-50)", + Print(static_cast(-50))); +} + +// unsigned char. +TEST(PrintCharTest, UnsignedChar) { + EXPECT_EQ("'\\0'", Print(static_cast('\0'))); + EXPECT_EQ("'b' (98, 0x62)", + Print(static_cast('b'))); +} + +// Tests printing other simple, built-in types. + +// bool. +TEST(PrintBuiltInTypeTest, Bool) { + EXPECT_EQ("false", Print(false)); + EXPECT_EQ("true", Print(true)); +} + +// wchar_t. +TEST(PrintBuiltInTypeTest, Wchar_t) { + EXPECT_EQ("L'\\0'", Print(L'\0')); + EXPECT_EQ("L'\\'' (39, 0x27)", Print(L'\'')); + EXPECT_EQ("L'\"' (34, 0x22)", Print(L'"')); + EXPECT_EQ("L'?' (63, 0x3F)", Print(L'?')); + EXPECT_EQ("L'\\\\' (92, 0x5C)", Print(L'\\')); + EXPECT_EQ("L'\\a' (7)", Print(L'\a')); + EXPECT_EQ("L'\\b' (8)", Print(L'\b')); + EXPECT_EQ("L'\\f' (12, 0xC)", Print(L'\f')); + EXPECT_EQ("L'\\n' (10, 0xA)", Print(L'\n')); + EXPECT_EQ("L'\\r' (13, 0xD)", Print(L'\r')); + EXPECT_EQ("L'\\t' (9)", Print(L'\t')); + EXPECT_EQ("L'\\v' (11, 0xB)", Print(L'\v')); + EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F')); + EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); + EXPECT_EQ("L' ' (32, 0x20)", Print(L' ')); + EXPECT_EQ("L'a' (97, 0x61)", Print(L'a')); + EXPECT_EQ("L'\\x576' (1398)", Print(static_cast(0x576))); + EXPECT_EQ("L'\\xC74D' (51021)", Print(static_cast(0xC74D))); +} + +// Test that Int64 provides more storage than wchar_t. +TEST(PrintTypeSizeTest, Wchar_t) { + EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64)); +} + +// Various integer types. +TEST(PrintBuiltInTypeTest, Integer) { + EXPECT_EQ("'\\xFF' (255)", Print(static_cast(255))); // uint8 + EXPECT_EQ("'\\x80' (-128)", Print(static_cast(-128))); // int8 + EXPECT_EQ("65535", Print(USHRT_MAX)); // uint16 + EXPECT_EQ("-32768", Print(SHRT_MIN)); // int16 + EXPECT_EQ("4294967295", Print(UINT_MAX)); // uint32 + EXPECT_EQ("-2147483648", Print(INT_MIN)); // int32 + EXPECT_EQ("18446744073709551615", + Print(static_cast(-1))); // uint64 + EXPECT_EQ("-9223372036854775808", + Print(static_cast(1) << 63)); // int64 +} + +// Size types. +TEST(PrintBuiltInTypeTest, Size_t) { + EXPECT_EQ("1", Print(sizeof('a'))); // size_t. +#if !GTEST_OS_WINDOWS + // Windows has no ssize_t type. + EXPECT_EQ("-2", Print(static_cast(-2))); // ssize_t. +#endif // !GTEST_OS_WINDOWS +} + +// Floating-points. +TEST(PrintBuiltInTypeTest, FloatingPoints) { + EXPECT_EQ("1.5", Print(1.5f)); // float + EXPECT_EQ("-2.5", Print(-2.5)); // double +} + +// Since ::std::stringstream::operator<<(const void *) formats the pointer +// output differently with different compilers, we have to create the expected +// output first and use it as our expectation. +static string PrintPointer(const void *p) { + ::std::stringstream expected_result_stream; + expected_result_stream << p; + return expected_result_stream.str(); +} + +// Tests printing C strings. + +// const char*. +TEST(PrintCStringTest, Const) { + const char* p = "World"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"World\"", Print(p)); +} + +// char*. +TEST(PrintCStringTest, NonConst) { + char p[] = "Hi"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"Hi\"", + Print(static_cast(p))); +} + +// NULL C string. +TEST(PrintCStringTest, Null) { + const char* p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that C strings are escaped properly. +TEST(PrintCStringTest, EscapesProperly) { + const char* p = "'\"?\\\a\b\f\n\r\t\v\x7F\xFF a"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"?\\\\\\a\\b\\f" + "\\n\\r\\t\\v\\x7F\\xFF a\"", + Print(p)); +} + + + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) + +// const wchar_t*. +TEST(PrintWideCStringTest, Const) { + const wchar_t* p = L"World"; + EXPECT_EQ(PrintPointer(p) + " pointing to L\"World\"", Print(p)); +} + +// wchar_t*. +TEST(PrintWideCStringTest, NonConst) { + wchar_t p[] = L"Hi"; + EXPECT_EQ(PrintPointer(p) + " pointing to L\"Hi\"", + Print(static_cast(p))); +} + +// NULL wide C string. +TEST(PrintWideCStringTest, Null) { + const wchar_t* p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that wide C strings are escaped properly. +TEST(PrintWideCStringTest, EscapesProperly) { + const wchar_t s[] = {'\'', '"', '?', '\\', '\a', '\b', '\f', '\n', '\r', + '\t', '\v', 0xD3, 0x576, 0x8D3, 0xC74D, ' ', 'a', '\0'}; + EXPECT_EQ(PrintPointer(s) + " pointing to L\"'\\\"?\\\\\\a\\b\\f" + "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", + Print(static_cast(s))); +} +#endif // native wchar_t + +// Tests printing pointers to other char types. + +// signed char*. +TEST(PrintCharPointerTest, SignedChar) { + signed char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const signed char*. +TEST(PrintCharPointerTest, ConstSignedChar) { + signed char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// unsigned char*. +TEST(PrintCharPointerTest, UnsignedChar) { + unsigned char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const unsigned char*. +TEST(PrintCharPointerTest, ConstUnsignedChar) { + const unsigned char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to simple, built-in types. + +// bool*. +TEST(PrintPointerToBuiltInTypeTest, Bool) { + bool* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// void*. +TEST(PrintPointerToBuiltInTypeTest, Void) { + void* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const void*. +TEST(PrintPointerToBuiltInTypeTest, ConstVoid) { + const void* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to pointers. +TEST(PrintPointerToPointerTest, IntPointerPointer) { + int** p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing (non-member) function pointers. + +void MyFunction(int /* n */) {} + +TEST(PrintPointerTest, NonMemberFunctionPointer) { + // We cannot directly cast &MyFunction to const void* because the + // standard disallows casting between pointers to functions and + // pointers to objects, and some compilers (e.g. GCC 3.4) enforce + // this limitation. + EXPECT_EQ( + PrintPointer(reinterpret_cast( + reinterpret_cast(&MyFunction))), + Print(&MyFunction)); + int (*p)(bool) = NULL; // NOLINT + EXPECT_EQ("NULL", Print(p)); +} + +// An assertion predicate determining whether a one string is a prefix for +// another. +template +AssertionResult HasPrefix(const StringType& str, const StringType& prefix) { + if (str.find(prefix, 0) == 0) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(prefix[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << begin_string_quote << prefix << "\" is not a prefix of " + << begin_string_quote << str << "\"\n"; +} + +// Tests printing member variable pointers. Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined. Thus they will be +// printed as raw bytes. + +struct Foo { + public: + virtual ~Foo() {} + int MyMethod(char x) { return x + 1; } + virtual char MyVirtualMethod(int /* n */) { return 'a'; } + + int value; +}; + +TEST(PrintPointerTest, MemberVariablePointer) { + EXPECT_TRUE(HasPrefix(Print(&Foo::value), + Print(sizeof(&Foo::value)) + "-byte object ")); + int (Foo::*p) = NULL; // NOLINT + EXPECT_TRUE(HasPrefix(Print(p), + Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing member function pointers. Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined. Thus they will be +// printed as raw bytes. +TEST(PrintPointerTest, MemberFunctionPointer) { + EXPECT_TRUE(HasPrefix(Print(&Foo::MyMethod), + Print(sizeof(&Foo::MyMethod)) + "-byte object ")); + EXPECT_TRUE( + HasPrefix(Print(&Foo::MyVirtualMethod), + Print(sizeof((&Foo::MyVirtualMethod))) + "-byte object ")); + int (Foo::*p)(char) = NULL; // NOLINT + EXPECT_TRUE(HasPrefix(Print(p), + Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing C arrays. + +// The difference between this and Print() is that it ensures that the +// argument is a reference to an array. +template +string PrintArrayHelper(T (&a)[N]) { + return Print(a); +} + +// One-dimensional array. +TEST(PrintArrayTest, OneDimensionalArray) { + int a[5] = { 1, 2, 3, 4, 5 }; + EXPECT_EQ("{ 1, 2, 3, 4, 5 }", PrintArrayHelper(a)); +} + +// Two-dimensional array. +TEST(PrintArrayTest, TwoDimensionalArray) { + int a[2][5] = { + { 1, 2, 3, 4, 5 }, + { 6, 7, 8, 9, 0 } + }; + EXPECT_EQ("{ { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }", PrintArrayHelper(a)); +} + +// Array of const elements. +TEST(PrintArrayTest, ConstArray) { + const bool a[1] = { false }; + EXPECT_EQ("{ false }", PrintArrayHelper(a)); +} + +// char array without terminating NUL. +TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + char a[] = { 'H', '\0', 'i' }; + EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); +} + +// const char array with terminating NUL. +TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) { + const char a[] = "\0Hi"; + EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a)); +} + +// const wchar_t array without terminating NUL. +TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + const wchar_t a[] = { L'H', L'\0', L'i' }; + EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); +} + +// wchar_t array with terminating NUL. +TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) { + const wchar_t a[] = L"\0Hi"; + EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); +} + +// Array of objects. +TEST(PrintArrayTest, ObjectArray) { + string a[3] = { "Hi", "Hello", "Ni hao" }; + EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", PrintArrayHelper(a)); +} + +// Array with many elements. +TEST(PrintArrayTest, BigArray) { + int a[100] = { 1, 2, 3 }; + EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, ..., 0, 0, 0, 0, 0, 0, 0, 0 }", + PrintArrayHelper(a)); +} + +// Tests printing ::string and ::std::string. + +#if GTEST_HAS_GLOBAL_STRING +// ::string. +TEST(PrintStringTest, StringInGlobalNamespace) { + const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; + const ::string str(s, sizeof(s)); + EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", + Print(str)); +} +#endif // GTEST_HAS_GLOBAL_STRING + +// ::std::string. +TEST(PrintStringTest, StringInStdNamespace) { + const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; + const ::std::string str(s, sizeof(s)); + EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", + Print(str)); +} + +TEST(PrintStringTest, StringAmbiguousHex) { + // "\x6BANANA" is ambiguous, it can be interpreted as starting with either of: + // '\x6', '\x6B', or '\x6BA'. + + // a hex escaping sequence following by a decimal digit + EXPECT_EQ("\"0\\x12\" \"3\"", Print(::std::string("0\x12" "3"))); + // a hex escaping sequence following by a hex digit (lower-case) + EXPECT_EQ("\"mm\\x6\" \"bananas\"", Print(::std::string("mm\x6" "bananas"))); + // a hex escaping sequence following by a hex digit (upper-case) + EXPECT_EQ("\"NOM\\x6\" \"BANANA\"", Print(::std::string("NOM\x6" "BANANA"))); + // a hex escaping sequence following by a non-xdigit + EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!"))); +} + +// Tests printing ::wstring and ::std::wstring. + +#if GTEST_HAS_GLOBAL_WSTRING +// ::wstring. +TEST(PrintWideStringTest, StringInGlobalNamespace) { + const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; + const ::wstring str(s, sizeof(s)/sizeof(wchar_t)); + EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" + "\\xD3\\x576\\x8D3\\xC74D a\\0\"", + Print(str)); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +// ::std::wstring. +TEST(PrintWideStringTest, StringInStdNamespace) { + const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; + const ::std::wstring str(s, sizeof(s)/sizeof(wchar_t)); + EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" + "\\xD3\\x576\\x8D3\\xC74D a\\0\"", + Print(str)); +} + +TEST(PrintWideStringTest, StringAmbiguousHex) { + // same for wide strings. + EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12" L"3"))); + EXPECT_EQ("L\"mm\\x6\" L\"bananas\"", + Print(::std::wstring(L"mm\x6" L"bananas"))); + EXPECT_EQ("L\"NOM\\x6\" L\"BANANA\"", + Print(::std::wstring(L"NOM\x6" L"BANANA"))); + EXPECT_EQ("L\"!\\x5-!\"", Print(::std::wstring(L"!\x5-!"))); +} +#endif // GTEST_HAS_STD_WSTRING + +// Tests printing types that support generic streaming (i.e. streaming +// to std::basic_ostream for any valid Char and +// CharTraits types). + +// Tests printing a non-template type that supports generic streaming. + +class AllowsGenericStreaming {}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreaming& /* a */) { + return os << "AllowsGenericStreaming"; +} + +TEST(PrintTypeWithGenericStreamingTest, NonTemplateType) { + AllowsGenericStreaming a; + EXPECT_EQ("AllowsGenericStreaming", Print(a)); +} + +// Tests printing a template type that supports generic streaming. + +template +class AllowsGenericStreamingTemplate {}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreamingTemplate& /* a */) { + return os << "AllowsGenericStreamingTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TemplateType) { + AllowsGenericStreamingTemplate a; + EXPECT_EQ("AllowsGenericStreamingTemplate", Print(a)); +} + +// Tests printing a type that supports generic streaming and can be +// implicitly converted to another printable type. + +template +class AllowsGenericStreamingAndImplicitConversionTemplate { + public: + operator bool() const { return false; } +}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreamingAndImplicitConversionTemplate& /* a */) { + return os << "AllowsGenericStreamingAndImplicitConversionTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { + AllowsGenericStreamingAndImplicitConversionTemplate a; + EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); +} + +#if GTEST_HAS_STRING_PIECE_ + +// Tests printing StringPiece. + +TEST(PrintStringPieceTest, SimpleStringPiece) { + const StringPiece sp = "Hello"; + EXPECT_EQ("\"Hello\"", Print(sp)); +} + +TEST(PrintStringPieceTest, UnprintableCharacters) { + const char str[] = "NUL (\0) and \r\t"; + const StringPiece sp(str, sizeof(str) - 1); + EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); +} + +#endif // GTEST_HAS_STRING_PIECE_ + +// Tests printing STL containers. + +TEST(PrintStlContainerTest, EmptyDeque) { + deque empty; + EXPECT_EQ("{}", Print(empty)); +} + +TEST(PrintStlContainerTest, NonEmptyDeque) { + deque non_empty; + non_empty.push_back(1); + non_empty.push_back(3); + EXPECT_EQ("{ 1, 3 }", Print(non_empty)); +} + +#if GTEST_HAS_HASH_MAP_ + +TEST(PrintStlContainerTest, OneElementHashMap) { + hash_map map1; + map1[1] = 'a'; + EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1)); +} + +TEST(PrintStlContainerTest, HashMultiMap) { + hash_multimap map1; + map1.insert(make_pair(5, true)); + map1.insert(make_pair(5, false)); + + // Elements of hash_multimap can be printed in any order. + const string result = Print(map1); + EXPECT_TRUE(result == "{ (5, true), (5, false) }" || + result == "{ (5, false), (5, true) }") + << " where Print(map1) returns \"" << result << "\"."; +} + +#endif // GTEST_HAS_HASH_MAP_ + +#if GTEST_HAS_HASH_SET_ + +TEST(PrintStlContainerTest, HashSet) { + hash_set set1; + set1.insert("hello"); + EXPECT_EQ("{ \"hello\" }", Print(set1)); +} + +TEST(PrintStlContainerTest, HashMultiSet) { + const int kSize = 5; + int a[kSize] = { 1, 1, 2, 5, 1 }; + hash_multiset set1(a, a + kSize); + + // Elements of hash_multiset can be printed in any order. + const string result = Print(set1); + const string expected_pattern = "{ d, d, d, d, d }"; // d means a digit. + + // Verifies the result matches the expected pattern; also extracts + // the numbers in the result. + ASSERT_EQ(expected_pattern.length(), result.length()); + std::vector numbers; + for (size_t i = 0; i != result.length(); i++) { + if (expected_pattern[i] == 'd') { + ASSERT_NE(isdigit(static_cast(result[i])), 0); + numbers.push_back(result[i] - '0'); + } else { + EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " + << result; + } + } + + // Makes sure the result contains the right numbers. + std::sort(numbers.begin(), numbers.end()); + std::sort(a, a + kSize); + EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin())); +} + +#endif // GTEST_HAS_HASH_SET_ + +TEST(PrintStlContainerTest, List) { + const string a[] = { + "hello", + "world" + }; + const list strings(a, a + 2); + EXPECT_EQ("{ \"hello\", \"world\" }", Print(strings)); +} + +TEST(PrintStlContainerTest, Map) { + map map1; + map1[1] = true; + map1[5] = false; + map1[3] = true; + EXPECT_EQ("{ (1, true), (3, true), (5, false) }", Print(map1)); +} + +TEST(PrintStlContainerTest, MultiMap) { + multimap map1; + // The make_pair template function would deduce the type as + // pair here, and since the key part in a multimap has to + // be constant, without a templated ctor in the pair class (as in + // libCstd on Solaris), make_pair call would fail to compile as no + // implicit conversion is found. Thus explicit typename is used + // here instead. + map1.insert(pair(true, 0)); + map1.insert(pair(true, 1)); + map1.insert(pair(false, 2)); + EXPECT_EQ("{ (false, 2), (true, 0), (true, 1) }", Print(map1)); +} + +TEST(PrintStlContainerTest, Set) { + const unsigned int a[] = { 3, 0, 5 }; + set set1(a, a + 3); + EXPECT_EQ("{ 0, 3, 5 }", Print(set1)); +} + +TEST(PrintStlContainerTest, MultiSet) { + const int a[] = { 1, 1, 2, 5, 1 }; + multiset set1(a, a + 5); + EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1)); +} + +TEST(PrintStlContainerTest, Pair) { + pair p(true, 5); + EXPECT_EQ("(true, 5)", Print(p)); +} + +TEST(PrintStlContainerTest, Vector) { + vector v; + v.push_back(1); + v.push_back(2); + EXPECT_EQ("{ 1, 2 }", Print(v)); +} + +TEST(PrintStlContainerTest, LongSequence) { + const int a[100] = { 1, 2, 3 }; + const vector v(a, a + 100); + EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, " + "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... }", Print(v)); +} + +TEST(PrintStlContainerTest, NestedContainer) { + const int a1[] = { 1, 2 }; + const int a2[] = { 3, 4, 5 }; + const list l1(a1, a1 + 2); + const list l2(a2, a2 + 3); + + vector > v; + v.push_back(l1); + v.push_back(l2); + EXPECT_EQ("{ { 1, 2 }, { 3, 4, 5 } }", Print(v)); +} + +TEST(PrintStlContainerTest, OneDimensionalNativeArray) { + const int a[3] = { 1, 2, 3 }; + NativeArray b(a, 3, kReference); + EXPECT_EQ("{ 1, 2, 3 }", Print(b)); +} + +TEST(PrintStlContainerTest, TwoDimensionalNativeArray) { + const int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; + NativeArray b(a, 2, kReference); + EXPECT_EQ("{ { 1, 2, 3 }, { 4, 5, 6 } }", Print(b)); +} + +// Tests that a class named iterator isn't treated as a container. + +struct iterator { + char x; +}; + +TEST(PrintStlContainerTest, Iterator) { + iterator it = {}; + EXPECT_EQ("1-byte object <00>", Print(it)); +} + +// Tests that a class named const_iterator isn't treated as a container. + +struct const_iterator { + char x; +}; + +TEST(PrintStlContainerTest, ConstIterator) { + const_iterator it = {}; + EXPECT_EQ("1-byte object <00>", Print(it)); +} + +#if GTEST_HAS_TR1_TUPLE +// Tests printing tuples. + +// Tuples of various arities. +TEST(PrintTupleTest, VariousSizes) { + tuple<> t0; + EXPECT_EQ("()", Print(t0)); + + tuple t1(5); + EXPECT_EQ("(5)", Print(t1)); + + tuple t2('a', true); + EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); + + tuple t3(false, 2, 3); + EXPECT_EQ("(false, 2, 3)", Print(t3)); + + tuple t4(false, 2, 3, 4); + EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); + + tuple t5(false, 2, 3, 4, true); + EXPECT_EQ("(false, 2, 3, 4, true)", Print(t5)); + + tuple t6(false, 2, 3, 4, true, 6); + EXPECT_EQ("(false, 2, 3, 4, true, 6)", Print(t6)); + + tuple t7(false, 2, 3, 4, true, 6, 7); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7)", Print(t7)); + + tuple t8( + false, 2, 3, 4, true, 6, 7, true); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true)", Print(t8)); + + tuple t9( + false, 2, 3, 4, true, 6, 7, true, 9); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9)); + + const char* const str = "8"; + // VC++ 2010's implementation of tuple of C++0x is deficient, requiring + // an explicit type cast of NULL to be used. + tuple + t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, + ImplicitCast_(NULL), "10"); + EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + + " pointing to \"8\", NULL, \"10\")", + Print(t10)); +} + +// Nested tuples. +TEST(PrintTupleTest, NestedTuple) { + tuple, char> nested(make_tuple(5, true), 'a'); + EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested)); +} + +#endif // GTEST_HAS_TR1_TUPLE + +// Tests printing user-defined unprintable types. + +// Unprintable types in the global namespace. +TEST(PrintUnprintableTypeTest, InGlobalNamespace) { + EXPECT_EQ("1-byte object <00>", + Print(UnprintableTemplateInGlobal())); +} + +// Unprintable types in a user namespace. +TEST(PrintUnprintableTypeTest, InUserNamespace) { + EXPECT_EQ("16-byte object ", + Print(::foo::UnprintableInFoo())); +} + +// Unprintable types are that too big to be printed completely. + +struct Big { + Big() { memset(array, 0, sizeof(array)); } + char array[257]; +}; + +TEST(PrintUnpritableTypeTest, BigObject) { + EXPECT_EQ("257-byte object <00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 ... 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00>", + Print(Big())); +} + +// Tests printing user-defined streamable types. + +// Streamable types in the global namespace. +TEST(PrintStreamableTypeTest, InGlobalNamespace) { + StreamableInGlobal x; + EXPECT_EQ("StreamableInGlobal", Print(x)); + EXPECT_EQ("StreamableInGlobal*", Print(&x)); +} + +// Printable template types in a user namespace. +TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) { + EXPECT_EQ("StreamableTemplateInFoo: 0", + Print(::foo::StreamableTemplateInFoo())); +} + +// Tests printing user-defined types that have a PrintTo() function. +TEST(PrintPrintableTypeTest, InUserNamespace) { + EXPECT_EQ("PrintableViaPrintTo: 0", + Print(::foo::PrintableViaPrintTo())); +} + +// Tests printing a pointer to a user-defined type that has a << +// operator for its pointer. +TEST(PrintPrintableTypeTest, PointerInUserNamespace) { + ::foo::PointerPrintable x; + EXPECT_EQ("PointerPrintable*", Print(&x)); +} + +// Tests printing user-defined class template that have a PrintTo() function. +TEST(PrintPrintableTypeTest, TemplateInUserNamespace) { + EXPECT_EQ("PrintableViaPrintToTemplate: 5", + Print(::foo::PrintableViaPrintToTemplate(5))); +} + +#if GTEST_HAS_PROTOBUF_ + +// Tests printing a protocol message. +TEST(PrintProtocolMessageTest, PrintsShortDebugString) { + testing::internal::TestMessage msg; + msg.set_member("yes"); + EXPECT_EQ("", Print(msg)); +} + +// Tests printing a short proto2 message. +TEST(PrintProto2MessageTest, PrintsShortDebugStringWhenItIsShort) { + testing::internal::FooMessage msg; + msg.set_int_field(2); + msg.set_string_field("hello"); + EXPECT_PRED2(RE::FullMatch, Print(msg), + ""); +} + +// Tests printing a long proto2 message. +TEST(PrintProto2MessageTest, PrintsDebugStringWhenItIsLong) { + testing::internal::FooMessage msg; + msg.set_int_field(2); + msg.set_string_field("hello"); + msg.add_names("peter"); + msg.add_names("paul"); + msg.add_names("mary"); + EXPECT_PRED2(RE::FullMatch, Print(msg), + "<\n" + "int_field:\\s*2\n" + "string_field:\\s*\"hello\"\n" + "names:\\s*\"peter\"\n" + "names:\\s*\"paul\"\n" + "names:\\s*\"mary\"\n" + ">"); +} + +#endif // GTEST_HAS_PROTOBUF_ + +// Tests that the universal printer prints both the address and the +// value of a reference. +TEST(PrintReferenceTest, PrintsAddressAndValue) { + int n = 5; + EXPECT_EQ("@" + PrintPointer(&n) + " 5", PrintByRef(n)); + + int a[2][3] = { + { 0, 1, 2 }, + { 3, 4, 5 } + }; + EXPECT_EQ("@" + PrintPointer(a) + " { { 0, 1, 2 }, { 3, 4, 5 } }", + PrintByRef(a)); + + const ::foo::UnprintableInFoo x; + EXPECT_EQ("@" + PrintPointer(&x) + " 16-byte object " + "", + PrintByRef(x)); +} + +// Tests that the universal printer prints a function pointer passed by +// reference. +TEST(PrintReferenceTest, HandlesFunctionPointer) { + void (*fp)(int n) = &MyFunction; + const string fp_pointer_string = + PrintPointer(reinterpret_cast(&fp)); + // We cannot directly cast &MyFunction to const void* because the + // standard disallows casting between pointers to functions and + // pointers to objects, and some compilers (e.g. GCC 3.4) enforce + // this limitation. + const string fp_string = PrintPointer(reinterpret_cast( + reinterpret_cast(fp))); + EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, + PrintByRef(fp)); +} + +// Tests that the universal printer prints a member function pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberFunctionPointer) { + int (Foo::*p)(char ch) = &Foo::MyMethod; + EXPECT_TRUE(HasPrefix( + PrintByRef(p), + "@" + PrintPointer(reinterpret_cast(&p)) + " " + + Print(sizeof(p)) + "-byte object ")); + + char (Foo::*p2)(int n) = &Foo::MyVirtualMethod; + EXPECT_TRUE(HasPrefix( + PrintByRef(p2), + "@" + PrintPointer(reinterpret_cast(&p2)) + " " + + Print(sizeof(p2)) + "-byte object ")); +} + +// Tests that the universal printer prints a member variable pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberVariablePointer) { + int (Foo::*p) = &Foo::value; // NOLINT + EXPECT_TRUE(HasPrefix( + PrintByRef(p), + "@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object ")); +} + +// Tests that FormatForComparisonFailureMessage(), which is used to print +// an operand in a comparison assertion (e.g. ASSERT_EQ) when the assertion +// fails, formats the operand in the desired way. + +// scalar +TEST(FormatForComparisonFailureMessageTest, WorksForScalar) { + EXPECT_STREQ("123", + FormatForComparisonFailureMessage(123, 124).c_str()); +} + +// non-char pointer +TEST(FormatForComparisonFailureMessageTest, WorksForNonCharPointer) { + int n = 0; + EXPECT_EQ(PrintPointer(&n), + FormatForComparisonFailureMessage(&n, &n).c_str()); +} + +// non-char array +TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) { + // In expression 'array == x', 'array' is compared by pointer. + // Therefore we want to print an array operand as a pointer. + int n[] = { 1, 2, 3 }; + EXPECT_EQ(PrintPointer(n), + FormatForComparisonFailureMessage(n, n).c_str()); +} + +// Tests formatting a char pointer when it's compared with another pointer. +// In this case we want to print it as a raw pointer, as the comparision is by +// pointer. + +// char pointer vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsPointer) { + // In expression 'p == x', where 'p' and 'x' are (const or not) char + // pointers, the operands are compared by pointer. Therefore we + // want to print 'p' as a pointer instead of a C string (we don't + // even know if it's supposed to point to a valid C string). + + // const char* + const char* s = "hello"; + EXPECT_EQ(PrintPointer(s), + FormatForComparisonFailureMessage(s, s).c_str()); + + // char* + char ch = 'a'; + EXPECT_EQ(PrintPointer(&ch), + FormatForComparisonFailureMessage(&ch, &ch).c_str()); +} + +// wchar_t pointer vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsPointer) { + // In expression 'p == x', where 'p' and 'x' are (const or not) char + // pointers, the operands are compared by pointer. Therefore we + // want to print 'p' as a pointer instead of a wide C string (we don't + // even know if it's supposed to point to a valid wide C string). + + // const wchar_t* + const wchar_t* s = L"hello"; + EXPECT_EQ(PrintPointer(s), + FormatForComparisonFailureMessage(s, s).c_str()); + + // wchar_t* + wchar_t ch = L'a'; + EXPECT_EQ(PrintPointer(&ch), + FormatForComparisonFailureMessage(&ch, &ch).c_str()); +} + +// Tests formatting a char pointer when it's compared to a string object. +// In this case we want to print the char pointer as a C string. + +#if GTEST_HAS_GLOBAL_STRING +// char pointer vs ::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsString) { + const char* s = "hello \"world"; + EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::string()).c_str()); + + // char* + char str[] = "hi\1"; + char* p = str; + EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::string()).c_str()); +} +#endif + +// char pointer vs std::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsStdString) { + const char* s = "hello \"world"; + EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::std::string()).c_str()); + + // char* + char str[] = "hi\1"; + char* p = str; + EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::std::string()).c_str()); +} + +#if GTEST_HAS_GLOBAL_WSTRING +// wchar_t pointer vs ::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsWString) { + const wchar_t* s = L"hi \"world"; + EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::wstring()).c_str()); + + // wchar_t* + wchar_t str[] = L"hi\1"; + wchar_t* p = str; + EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::wstring()).c_str()); +} +#endif + +#if GTEST_HAS_STD_WSTRING +// wchar_t pointer vs std::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsStdWString) { + const wchar_t* s = L"hi \"world"; + EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::std::wstring()).c_str()); + + // wchar_t* + wchar_t str[] = L"hi\1"; + wchar_t* p = str; + EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::std::wstring()).c_str()); +} +#endif + +// Tests formatting a char array when it's compared with a pointer or array. +// In this case we want to print the array as a row pointer, as the comparison +// is by pointer. + +// char array vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsPointer) { + char str[] = "hi \"world\""; + char* p = NULL; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, p).c_str()); +} + +// char array vs char array +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsCharArray) { + const char str[] = "hi \"world\""; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, str).c_str()); +} + +// wchar_t array vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsPointer) { + wchar_t str[] = L"hi \"world\""; + wchar_t* p = NULL; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, p).c_str()); +} + +// wchar_t array vs wchar_t array +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWCharArray) { + const wchar_t str[] = L"hi \"world\""; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, str).c_str()); +} + +// Tests formatting a char array when it's compared with a string object. +// In this case we want to print the array as a C string. + +#if GTEST_HAS_GLOBAL_STRING +// char array vs string +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsString) { + const char str[] = "hi \"w\0rld\""; + EXPECT_STREQ("\"hi \\\"w\"", // The content should be escaped. + // Embedded NUL terminates the string. + FormatForComparisonFailureMessage(str, ::string()).c_str()); +} +#endif + +// char array vs std::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsStdString) { + const char str[] = "hi \"world\""; + EXPECT_STREQ("\"hi \\\"world\\\"\"", // The content should be escaped. + FormatForComparisonFailureMessage(str, ::std::string()).c_str()); +} + +#if GTEST_HAS_GLOBAL_WSTRING +// wchar_t array vs wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWString) { + const wchar_t str[] = L"hi \"world\""; + EXPECT_STREQ("L\"hi \\\"world\\\"\"", // The content should be escaped. + FormatForComparisonFailureMessage(str, ::wstring()).c_str()); +} +#endif + +#if GTEST_HAS_STD_WSTRING +// wchar_t array vs std::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsStdWString) { + const wchar_t str[] = L"hi \"w\0rld\""; + EXPECT_STREQ( + "L\"hi \\\"w\"", // The content should be escaped. + // Embedded NUL terminates the string. + FormatForComparisonFailureMessage(str, ::std::wstring()).c_str()); +} +#endif + +// Useful for testing PrintToString(). We cannot use EXPECT_EQ() +// there as its implementation uses PrintToString(). The caller must +// ensure that 'value' has no side effect. +#define EXPECT_PRINT_TO_STRING_(value, expected_string) \ + EXPECT_TRUE(PrintToString(value) == (expected_string)) \ + << " where " #value " prints as " << (PrintToString(value)) + +TEST(PrintToStringTest, WorksForScalar) { + EXPECT_PRINT_TO_STRING_(123, "123"); +} + +TEST(PrintToStringTest, WorksForPointerToConstChar) { + const char* p = "hello"; + EXPECT_PRINT_TO_STRING_(p, "\"hello\""); +} + +TEST(PrintToStringTest, WorksForPointerToNonConstChar) { + char s[] = "hello"; + char* p = s; + EXPECT_PRINT_TO_STRING_(p, "\"hello\""); +} + +TEST(PrintToStringTest, EscapesForPointerToConstChar) { + const char* p = "hello\n"; + EXPECT_PRINT_TO_STRING_(p, "\"hello\\n\""); +} + +TEST(PrintToStringTest, EscapesForPointerToNonConstChar) { + char s[] = "hello\1"; + char* p = s; + EXPECT_PRINT_TO_STRING_(p, "\"hello\\x1\""); +} + +TEST(PrintToStringTest, WorksForArray) { + int n[3] = { 1, 2, 3 }; + EXPECT_PRINT_TO_STRING_(n, "{ 1, 2, 3 }"); +} + +TEST(PrintToStringTest, WorksForCharArray) { + char s[] = "hello"; + EXPECT_PRINT_TO_STRING_(s, "\"hello\""); +} + +TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { + const char str_with_nul[] = "hello\0 world"; + EXPECT_PRINT_TO_STRING_(str_with_nul, "\"hello\\0 world\""); + + char mutable_str_with_nul[] = "hello\0 world"; + EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\""); +} + +#undef EXPECT_PRINT_TO_STRING_ + +TEST(UniversalTersePrintTest, WorksForNonReference) { + ::std::stringstream ss; + UniversalTersePrint(123, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalTersePrintTest, WorksForReference) { + const int& n = 123; + ::std::stringstream ss; + UniversalTersePrint(n, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalTersePrintTest, WorksForCString) { + const char* s1 = "abc"; + ::std::stringstream ss1; + UniversalTersePrint(s1, &ss1); + EXPECT_EQ("\"abc\"", ss1.str()); + + char* s2 = const_cast(s1); + ::std::stringstream ss2; + UniversalTersePrint(s2, &ss2); + EXPECT_EQ("\"abc\"", ss2.str()); + + const char* s3 = NULL; + ::std::stringstream ss3; + UniversalTersePrint(s3, &ss3); + EXPECT_EQ("NULL", ss3.str()); +} + +TEST(UniversalPrintTest, WorksForNonReference) { + ::std::stringstream ss; + UniversalPrint(123, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalPrintTest, WorksForReference) { + const int& n = 123; + ::std::stringstream ss; + UniversalPrint(n, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalPrintTest, WorksForCString) { + const char* s1 = "abc"; + ::std::stringstream ss1; + UniversalPrint(s1, &ss1); + EXPECT_EQ(PrintPointer(s1) + " pointing to \"abc\"", string(ss1.str())); + + char* s2 = const_cast(s1); + ::std::stringstream ss2; + UniversalPrint(s2, &ss2); + EXPECT_EQ(PrintPointer(s2) + " pointing to \"abc\"", string(ss2.str())); + + const char* s3 = NULL; + ::std::stringstream ss3; + UniversalPrint(s3, &ss3); + EXPECT_EQ("NULL", ss3.str()); +} + +TEST(UniversalPrintTest, WorksForCharArray) { + const char str[] = "\"Line\0 1\"\nLine 2"; + ::std::stringstream ss1; + UniversalPrint(str, &ss1); + EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss1.str()); + + const char mutable_str[] = "\"Line\0 1\"\nLine 2"; + ::std::stringstream ss2; + UniversalPrint(mutable_str, &ss2); + EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str()); +} + +#if GTEST_HAS_TR1_TUPLE + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsEmptyTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple()); + EXPECT_EQ(0u, result.size()); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsOneTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1)); + ASSERT_EQ(1u, result.size()); + EXPECT_EQ("1", result[0]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTwoTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1, 'a')); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("'a' (97, 0x61)", result[1]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTersely) { + const int n = 1; + Strings result = UniversalTersePrintTupleFieldsToStrings( + tuple(n, "a")); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("\"a\"", result[1]); +} + +#endif // GTEST_HAS_TR1_TUPLE + +} // namespace gtest_printers_test +} // namespace testing diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-test-part_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-test-part_test.cc new file mode 100644 index 0000000..ca8ba93 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-test-part_test.cc @@ -0,0 +1,208 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// + +#include "gtest/gtest-test-part.h" + +#include "gtest/gtest.h" + +using testing::Message; +using testing::Test; +using testing::TestPartResult; +using testing::TestPartResultArray; + +namespace { + +// Tests the TestPartResult class. + +// The test fixture for testing TestPartResult. +class TestPartResultTest : public Test { + protected: + TestPartResultTest() + : r1_(TestPartResult::kSuccess, "foo/bar.cc", 10, "Success!"), + r2_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure!"), + r3_(TestPartResult::kFatalFailure, NULL, -1, "Failure!") {} + + TestPartResult r1_, r2_, r3_; +}; + + +TEST_F(TestPartResultTest, ConstructorWorks) { + Message message; + message << "something is terribly wrong"; + message << static_cast(testing::internal::kStackTraceMarker); + message << "some unimportant stack trace"; + + const TestPartResult result(TestPartResult::kNonFatalFailure, + "some_file.cc", + 42, + message.GetString().c_str()); + + EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type()); + EXPECT_STREQ("some_file.cc", result.file_name()); + EXPECT_EQ(42, result.line_number()); + EXPECT_STREQ(message.GetString().c_str(), result.message()); + EXPECT_STREQ("something is terribly wrong", result.summary()); +} + +TEST_F(TestPartResultTest, ResultAccessorsWork) { + const TestPartResult success(TestPartResult::kSuccess, + "file.cc", + 42, + "message"); + EXPECT_TRUE(success.passed()); + EXPECT_FALSE(success.failed()); + EXPECT_FALSE(success.nonfatally_failed()); + EXPECT_FALSE(success.fatally_failed()); + + const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure, + "file.cc", + 42, + "message"); + EXPECT_FALSE(nonfatal_failure.passed()); + EXPECT_TRUE(nonfatal_failure.failed()); + EXPECT_TRUE(nonfatal_failure.nonfatally_failed()); + EXPECT_FALSE(nonfatal_failure.fatally_failed()); + + const TestPartResult fatal_failure(TestPartResult::kFatalFailure, + "file.cc", + 42, + "message"); + EXPECT_FALSE(fatal_failure.passed()); + EXPECT_TRUE(fatal_failure.failed()); + EXPECT_FALSE(fatal_failure.nonfatally_failed()); + EXPECT_TRUE(fatal_failure.fatally_failed()); +} + +// Tests TestPartResult::type(). +TEST_F(TestPartResultTest, type) { + EXPECT_EQ(TestPartResult::kSuccess, r1_.type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, r2_.type()); + EXPECT_EQ(TestPartResult::kFatalFailure, r3_.type()); +} + +// Tests TestPartResult::file_name(). +TEST_F(TestPartResultTest, file_name) { + EXPECT_STREQ("foo/bar.cc", r1_.file_name()); + EXPECT_STREQ(NULL, r3_.file_name()); +} + +// Tests TestPartResult::line_number(). +TEST_F(TestPartResultTest, line_number) { + EXPECT_EQ(10, r1_.line_number()); + EXPECT_EQ(-1, r2_.line_number()); +} + +// Tests TestPartResult::message(). +TEST_F(TestPartResultTest, message) { + EXPECT_STREQ("Success!", r1_.message()); +} + +// Tests TestPartResult::passed(). +TEST_F(TestPartResultTest, Passed) { + EXPECT_TRUE(r1_.passed()); + EXPECT_FALSE(r2_.passed()); + EXPECT_FALSE(r3_.passed()); +} + +// Tests TestPartResult::failed(). +TEST_F(TestPartResultTest, Failed) { + EXPECT_FALSE(r1_.failed()); + EXPECT_TRUE(r2_.failed()); + EXPECT_TRUE(r3_.failed()); +} + +// Tests TestPartResult::fatally_failed(). +TEST_F(TestPartResultTest, FatallyFailed) { + EXPECT_FALSE(r1_.fatally_failed()); + EXPECT_FALSE(r2_.fatally_failed()); + EXPECT_TRUE(r3_.fatally_failed()); +} + +// Tests TestPartResult::nonfatally_failed(). +TEST_F(TestPartResultTest, NonfatallyFailed) { + EXPECT_FALSE(r1_.nonfatally_failed()); + EXPECT_TRUE(r2_.nonfatally_failed()); + EXPECT_FALSE(r3_.nonfatally_failed()); +} + +// Tests the TestPartResultArray class. + +class TestPartResultArrayTest : public Test { + protected: + TestPartResultArrayTest() + : r1_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure 1"), + r2_(TestPartResult::kFatalFailure, "foo/bar.cc", -1, "Failure 2") {} + + const TestPartResult r1_, r2_; +}; + +// Tests that TestPartResultArray initially has size 0. +TEST_F(TestPartResultArrayTest, InitialSizeIsZero) { + TestPartResultArray results; + EXPECT_EQ(0, results.size()); +} + +// Tests that TestPartResultArray contains the given TestPartResult +// after one Append() operation. +TEST_F(TestPartResultArrayTest, ContainsGivenResultAfterAppend) { + TestPartResultArray results; + results.Append(r1_); + EXPECT_EQ(1, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); +} + +// Tests that TestPartResultArray contains the given TestPartResults +// after two Append() operations. +TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) { + TestPartResultArray results; + results.Append(r1_); + results.Append(r2_); + EXPECT_EQ(2, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); + EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message()); +} + +typedef TestPartResultArrayTest TestPartResultArrayDeathTest; + +// Tests that the program dies when GetTestPartResult() is called with +// an invalid index. +TEST_F(TestPartResultArrayDeathTest, DiesWhenIndexIsOutOfBound) { + TestPartResultArray results; + results.Append(r1_); + + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(-1), ""); + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(1), ""); +} + +// TODO(mheule@google.com): Add a test for the class HasNewFatalFailureHelper. + +} // namespace diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-tuple_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-tuple_test.cc new file mode 100644 index 0000000..bfaa3e0 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-tuple_test.cc @@ -0,0 +1,320 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/internal/gtest-tuple.h" +#include +#include "gtest/gtest.h" + +namespace { + +using ::std::tr1::get; +using ::std::tr1::make_tuple; +using ::std::tr1::tuple; +using ::std::tr1::tuple_element; +using ::std::tr1::tuple_size; +using ::testing::StaticAssertTypeEq; + +// Tests that tuple_element >::type returns TK. +TEST(tuple_element_Test, ReturnsElementType) { + StaticAssertTypeEq >::type>(); + StaticAssertTypeEq >::type>(); + StaticAssertTypeEq >::type>(); +} + +// Tests that tuple_size::value gives the number of fields in tuple +// type T. +TEST(tuple_size_Test, ReturnsNumberOfFields) { + EXPECT_EQ(0, +tuple_size >::value); + EXPECT_EQ(1, +tuple_size >::value); + EXPECT_EQ(1, +tuple_size >::value); + EXPECT_EQ(1, +(tuple_size > >::value)); + EXPECT_EQ(2, +(tuple_size >::value)); + EXPECT_EQ(3, +(tuple_size >::value)); +} + +// Tests comparing a tuple with itself. +TEST(ComparisonTest, ComparesWithSelf) { + const tuple a(5, 'a', false); + + EXPECT_TRUE(a == a); + EXPECT_FALSE(a != a); +} + +// Tests comparing two tuples with the same value. +TEST(ComparisonTest, ComparesEqualTuples) { + const tuple a(5, true), b(5, true); + + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); +} + +// Tests comparing two different tuples that have no reference fields. +TEST(ComparisonTest, ComparesUnequalTuplesWithoutReferenceFields) { + typedef tuple FooTuple; + + const FooTuple a(0, 'x'); + const FooTuple b(1, 'a'); + + EXPECT_TRUE(a != b); + EXPECT_FALSE(a == b); + + const FooTuple c(1, 'b'); + + EXPECT_TRUE(b != c); + EXPECT_FALSE(b == c); +} + +// Tests comparing two different tuples that have reference fields. +TEST(ComparisonTest, ComparesUnequalTuplesWithReferenceFields) { + typedef tuple FooTuple; + + int i = 5; + const char ch = 'a'; + const FooTuple a(i, ch); + + int j = 6; + const FooTuple b(j, ch); + + EXPECT_TRUE(a != b); + EXPECT_FALSE(a == b); + + j = 5; + const char ch2 = 'b'; + const FooTuple c(j, ch2); + + EXPECT_TRUE(b != c); + EXPECT_FALSE(b == c); +} + +// Tests that a tuple field with a reference type is an alias of the +// variable it's supposed to reference. +TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) { + int n = 0; + tuple t(true, n); + + n = 1; + EXPECT_EQ(n, get<1>(t)) + << "Changing a underlying variable should update the reference field."; + + // Makes sure that the implementation doesn't do anything funny with + // the & operator for the return type of get<>(). + EXPECT_EQ(&n, &(get<1>(t))) + << "The address of a reference field should equal the address of " + << "the underlying variable."; + + get<1>(t) = 2; + EXPECT_EQ(2, n) + << "Changing a reference field should update the underlying variable."; +} + +// Tests that tuple's default constructor default initializes each field. +// This test needs to compile without generating warnings. +TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) { + // The TR1 report requires that tuple's default constructor default + // initializes each field, even if it's a primitive type. If the + // implementation forgets to do this, this test will catch it by + // generating warnings about using uninitialized variables (assuming + // a decent compiler). + + tuple<> empty; + + tuple a1, b1; + b1 = a1; + EXPECT_EQ(0, get<0>(b1)); + + tuple a2, b2; + b2 = a2; + EXPECT_EQ(0, get<0>(b2)); + EXPECT_EQ(0.0, get<1>(b2)); + + tuple a3, b3; + b3 = a3; + EXPECT_EQ(0.0, get<0>(b3)); + EXPECT_EQ('\0', get<1>(b3)); + EXPECT_TRUE(get<2>(b3) == NULL); + + tuple a10, b10; + b10 = a10; + EXPECT_EQ(0, get<0>(b10)); + EXPECT_EQ(0, get<1>(b10)); + EXPECT_EQ(0, get<2>(b10)); + EXPECT_EQ(0, get<3>(b10)); + EXPECT_EQ(0, get<4>(b10)); + EXPECT_EQ(0, get<5>(b10)); + EXPECT_EQ(0, get<6>(b10)); + EXPECT_EQ(0, get<7>(b10)); + EXPECT_EQ(0, get<8>(b10)); + EXPECT_EQ(0, get<9>(b10)); +} + +// Tests constructing a tuple from its fields. +TEST(TupleConstructorTest, ConstructsFromFields) { + int n = 1; + // Reference field. + tuple a(n); + EXPECT_EQ(&n, &(get<0>(a))); + + // Non-reference fields. + tuple b(5, 'a'); + EXPECT_EQ(5, get<0>(b)); + EXPECT_EQ('a', get<1>(b)); + + // Const reference field. + const int m = 2; + tuple c(true, m); + EXPECT_TRUE(get<0>(c)); + EXPECT_EQ(&m, &(get<1>(c))); +} + +// Tests tuple's copy constructor. +TEST(TupleConstructorTest, CopyConstructor) { + tuple a(0.0, true); + tuple b(a); + + EXPECT_DOUBLE_EQ(0.0, get<0>(b)); + EXPECT_TRUE(get<1>(b)); +} + +// Tests constructing a tuple from another tuple that has a compatible +// but different type. +TEST(TupleConstructorTest, ConstructsFromDifferentTupleType) { + tuple a(0, 1, 'a'); + tuple b(a); + + EXPECT_DOUBLE_EQ(0.0, get<0>(b)); + EXPECT_EQ(1, get<1>(b)); + EXPECT_EQ('a', get<2>(b)); +} + +// Tests constructing a 2-tuple from an std::pair. +TEST(TupleConstructorTest, ConstructsFromPair) { + ::std::pair a(1, 'a'); + tuple b(a); + tuple c(a); +} + +// Tests assigning a tuple to another tuple with the same type. +TEST(TupleAssignmentTest, AssignsToSameTupleType) { + const tuple a(5, 7L); + tuple b; + b = a; + EXPECT_EQ(5, get<0>(b)); + EXPECT_EQ(7L, get<1>(b)); +} + +// Tests assigning a tuple to another tuple with a different but +// compatible type. +TEST(TupleAssignmentTest, AssignsToDifferentTupleType) { + const tuple a(1, 7L, true); + tuple b; + b = a; + EXPECT_EQ(1L, get<0>(b)); + EXPECT_EQ(7, get<1>(b)); + EXPECT_TRUE(get<2>(b)); +} + +// Tests assigning an std::pair to a 2-tuple. +TEST(TupleAssignmentTest, AssignsFromPair) { + const ::std::pair a(5, true); + tuple b; + b = a; + EXPECT_EQ(5, get<0>(b)); + EXPECT_TRUE(get<1>(b)); + + tuple c; + c = a; + EXPECT_EQ(5L, get<0>(c)); + EXPECT_TRUE(get<1>(c)); +} + +// A fixture for testing big tuples. +class BigTupleTest : public testing::Test { + protected: + typedef tuple BigTuple; + + BigTupleTest() : + a_(1, 0, 0, 0, 0, 0, 0, 0, 0, 2), + b_(1, 0, 0, 0, 0, 0, 0, 0, 0, 3) {} + + BigTuple a_, b_; +}; + +// Tests constructing big tuples. +TEST_F(BigTupleTest, Construction) { + BigTuple a; + BigTuple b(b_); +} + +// Tests that get(t) returns the N-th (0-based) field of tuple t. +TEST_F(BigTupleTest, get) { + EXPECT_EQ(1, get<0>(a_)); + EXPECT_EQ(2, get<9>(a_)); + + // Tests that get() works on a const tuple too. + const BigTuple a(a_); + EXPECT_EQ(1, get<0>(a)); + EXPECT_EQ(2, get<9>(a)); +} + +// Tests comparing big tuples. +TEST_F(BigTupleTest, Comparisons) { + EXPECT_TRUE(a_ == a_); + EXPECT_FALSE(a_ != a_); + + EXPECT_TRUE(a_ != b_); + EXPECT_FALSE(a_ == b_); +} + +TEST(MakeTupleTest, WorksForScalarTypes) { + tuple a; + a = make_tuple(true, 5); + EXPECT_TRUE(get<0>(a)); + EXPECT_EQ(5, get<1>(a)); + + tuple b; + b = make_tuple('a', 'b', 5); + EXPECT_EQ('a', get<0>(b)); + EXPECT_EQ('b', get<1>(b)); + EXPECT_EQ(5, get<2>(b)); +} + +TEST(MakeTupleTest, WorksForPointers) { + int a[] = { 1, 2, 3, 4 }; + const char* const str = "hi"; + int* const p = a; + + tuple t; + t = make_tuple(str, p); + EXPECT_EQ(str, get<0>(t)); + EXPECT_EQ(p, get<1>(t)); +} + +} // namespace diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test2_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test2_test.cc new file mode 100644 index 0000000..c284700 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test2_test.cc @@ -0,0 +1,45 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include + +#include "test/gtest-typed-test_test.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_TYPED_TEST_P + +// Tests that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// (ContainerTest is also instantiated in gtest-typed-test_test.cc.) +INSTANTIATE_TYPED_TEST_CASE_P(Vector, ContainerTest, + testing::Types >); + +#endif // GTEST_HAS_TYPED_TEST_P diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test_test.cc new file mode 100644 index 0000000..dd4ba43 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test_test.cc @@ -0,0 +1,360 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include +#include + +#include "test/gtest-typed-test_test.h" +#include "gtest/gtest.h" + +using testing::Test; + +// Used for testing that SetUpTestCase()/TearDownTestCase(), fixture +// ctor/dtor, and SetUp()/TearDown() work correctly in typed tests and +// type-parameterized test. +template +class CommonTest : public Test { + // For some technical reason, SetUpTestCase() and TearDownTestCase() + // must be public. + public: + static void SetUpTestCase() { + shared_ = new T(5); + } + + static void TearDownTestCase() { + delete shared_; + shared_ = NULL; + } + + // This 'protected:' is optional. There's no harm in making all + // members of this fixture class template public. + protected: + // We used to use std::list here, but switched to std::vector since + // MSVC's doesn't compile cleanly with /W4. + typedef std::vector Vector; + typedef std::set IntSet; + + CommonTest() : value_(1) {} + + virtual ~CommonTest() { EXPECT_EQ(3, value_); } + + virtual void SetUp() { + EXPECT_EQ(1, value_); + value_++; + } + + virtual void TearDown() { + EXPECT_EQ(2, value_); + value_++; + } + + T value_; + static T* shared_; +}; + +template +T* CommonTest::shared_ = NULL; + +// This #ifdef block tests typed tests. +#if GTEST_HAS_TYPED_TEST + +using testing::Types; + +// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, +// and SetUp()/TearDown() work correctly in typed tests + +typedef Types TwoTypes; +TYPED_TEST_CASE(CommonTest, TwoTypes); + +TYPED_TEST(CommonTest, ValuesAreCorrect) { + // Static members of the fixture class template can be visited via + // the TestFixture:: prefix. + EXPECT_EQ(5, *TestFixture::shared_); + + // Typedefs in the fixture class template can be visited via the + // "typename TestFixture::" prefix. + typename TestFixture::Vector empty; + EXPECT_EQ(0U, empty.size()); + + typename TestFixture::IntSet empty2; + EXPECT_EQ(0U, empty2.size()); + + // Non-static members of the fixture class must be visited via + // 'this', as required by C++ for class templates. + EXPECT_EQ(2, this->value_); +} + +// The second test makes sure shared_ is not deleted after the first +// test. +TYPED_TEST(CommonTest, ValuesAreStillCorrect) { + // Static members of the fixture class template can also be visited + // via 'this'. + ASSERT_TRUE(this->shared_ != NULL); + EXPECT_EQ(5, *this->shared_); + + // TypeParam can be used to refer to the type parameter. + EXPECT_EQ(static_cast(2), this->value_); +} + +// Tests that multiple TYPED_TEST_CASE's can be defined in the same +// translation unit. + +template +class TypedTest1 : public Test { +}; + +// Verifies that the second argument of TYPED_TEST_CASE can be a +// single type. +TYPED_TEST_CASE(TypedTest1, int); +TYPED_TEST(TypedTest1, A) {} + +template +class TypedTest2 : public Test { +}; + +// Verifies that the second argument of TYPED_TEST_CASE can be a +// Types<...> type list. +TYPED_TEST_CASE(TypedTest2, Types); + +// This also verifies that tests from different typed test cases can +// share the same name. +TYPED_TEST(TypedTest2, A) {} + +// Tests that a typed test case can be defined in a namespace. + +namespace library1 { + +template +class NumericTest : public Test { +}; + +typedef Types NumericTypes; +TYPED_TEST_CASE(NumericTest, NumericTypes); + +TYPED_TEST(NumericTest, DefaultIsZero) { + EXPECT_EQ(0, TypeParam()); +} + +} // namespace library1 + +#endif // GTEST_HAS_TYPED_TEST + +// This #ifdef block tests type-parameterized tests. +#if GTEST_HAS_TYPED_TEST_P + +using testing::Types; +using testing::internal::TypedTestCasePState; + +// Tests TypedTestCasePState. + +class TypedTestCasePStateTest : public Test { + protected: + virtual void SetUp() { + state_.AddTestName("foo.cc", 0, "FooTest", "A"); + state_.AddTestName("foo.cc", 0, "FooTest", "B"); + state_.AddTestName("foo.cc", 0, "FooTest", "C"); + } + + TypedTestCasePState state_; +}; + +TEST_F(TypedTestCasePStateTest, SucceedsForMatchingList) { + const char* tests = "A, B, C"; + EXPECT_EQ(tests, + state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); +} + +// Makes sure that the order of the tests and spaces around the names +// don't matter. +TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) { + const char* tests = "A,C, B"; + EXPECT_EQ(tests, + state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); +} + +typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest; + +TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), + "foo\\.cc.1.?: Test A is listed more than once\\."); +} + +TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), + "foo\\.cc.1.?: No test named D can be found in this test case\\."); +} + +TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), + "foo\\.cc.1.?: You forgot to list test B\\."); +} + +// Tests that defining a test for a parameterized test case generates +// a run-time error if the test case has been registered. +TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) { + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); + EXPECT_DEATH_IF_SUPPORTED( + state_.AddTestName("foo.cc", 2, "FooTest", "D"), + "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_CASE_P" + "\\(FooTest, \\.\\.\\.\\)\\."); +} + +// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, +// and SetUp()/TearDown() work correctly in type-parameterized tests. + +template +class DerivedTest : public CommonTest { +}; + +TYPED_TEST_CASE_P(DerivedTest); + +TYPED_TEST_P(DerivedTest, ValuesAreCorrect) { + // Static members of the fixture class template can be visited via + // the TestFixture:: prefix. + EXPECT_EQ(5, *TestFixture::shared_); + + // Non-static members of the fixture class must be visited via + // 'this', as required by C++ for class templates. + EXPECT_EQ(2, this->value_); +} + +// The second test makes sure shared_ is not deleted after the first +// test. +TYPED_TEST_P(DerivedTest, ValuesAreStillCorrect) { + // Static members of the fixture class template can also be visited + // via 'this'. + ASSERT_TRUE(this->shared_ != NULL); + EXPECT_EQ(5, *this->shared_); + EXPECT_EQ(2, this->value_); +} + +REGISTER_TYPED_TEST_CASE_P(DerivedTest, + ValuesAreCorrect, ValuesAreStillCorrect); + +typedef Types MyTwoTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, DerivedTest, MyTwoTypes); + +// Tests that multiple TYPED_TEST_CASE_P's can be defined in the same +// translation unit. + +template +class TypedTestP1 : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP1); + +// For testing that the code between TYPED_TEST_CASE_P() and +// TYPED_TEST_P() is not enclosed in a namespace. +typedef int IntAfterTypedTestCaseP; + +TYPED_TEST_P(TypedTestP1, A) {} +TYPED_TEST_P(TypedTestP1, B) {} + +// For testing that the code between TYPED_TEST_P() and +// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. +typedef int IntBeforeRegisterTypedTestCaseP; + +REGISTER_TYPED_TEST_CASE_P(TypedTestP1, A, B); + +template +class TypedTestP2 : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP2); + +// This also verifies that tests from different type-parameterized +// test cases can share the same name. +TYPED_TEST_P(TypedTestP2, A) {} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP2, A); + +// Verifies that the code between TYPED_TEST_CASE_P() and +// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. +IntAfterTypedTestCaseP after = 0; +IntBeforeRegisterTypedTestCaseP before = 0; + +// Verifies that the last argument of INSTANTIATE_TYPED_TEST_CASE_P() +// can be either a single type or a Types<...> type list. +INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP1, int); +INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP2, Types); + +// Tests that the same type-parameterized test case can be +// instantiated more than once in the same translation unit. +INSTANTIATE_TYPED_TEST_CASE_P(Double, TypedTestP2, Types); + +// Tests that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// (ContainerTest is also instantiated in gtest-typed-test_test.cc.) +typedef Types, std::set > MyContainers; +INSTANTIATE_TYPED_TEST_CASE_P(My, ContainerTest, MyContainers); + +// Tests that a type-parameterized test case can be defined and +// instantiated in a namespace. + +namespace library2 { + +template +class NumericTest : public Test { +}; + +TYPED_TEST_CASE_P(NumericTest); + +TYPED_TEST_P(NumericTest, DefaultIsZero) { + EXPECT_EQ(0, TypeParam()); +} + +TYPED_TEST_P(NumericTest, ZeroIsLessThanOne) { + EXPECT_LT(TypeParam(0), TypeParam(1)); +} + +REGISTER_TYPED_TEST_CASE_P(NumericTest, + DefaultIsZero, ZeroIsLessThanOne); +typedef Types NumericTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes); + +} // namespace library2 + +#endif // GTEST_HAS_TYPED_TEST_P + +#if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) + +// Google Test may not support type-parameterized tests with some +// compilers. If we use conditional compilation to compile out all +// code referring to the gtest_main library, MSVC linker will not link +// that library at all and consequently complain about missing entry +// point defined in that library (fatal error LNK1561: entry point +// must be defined). This dummy test keeps gtest_main linked in. +TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {} + +#endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test_test.h b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test_test.h new file mode 100644 index 0000000..41d7570 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-typed-test_test.h @@ -0,0 +1,66 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ +#define GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ + +#include "gtest/gtest.h" + +#if GTEST_HAS_TYPED_TEST_P + +using testing::Test; + +// For testing that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// ContainerTest will be instantiated in both gtest-typed-test_test.cc +// and gtest-typed-test2_test.cc. + +template +class ContainerTest : public Test { +}; + +TYPED_TEST_CASE_P(ContainerTest); + +TYPED_TEST_P(ContainerTest, CanBeDefaultConstructed) { + TypeParam container; +} + +TYPED_TEST_P(ContainerTest, InitialSizeIsZero) { + TypeParam container; + EXPECT_EQ(0U, container.size()); +} + +REGISTER_TYPED_TEST_CASE_P(ContainerTest, + CanBeDefaultConstructed, InitialSizeIsZero); + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-unittest-api_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-unittest-api_test.cc new file mode 100644 index 0000000..07083e5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest-unittest-api_test.cc @@ -0,0 +1,341 @@ +// Copyright 2009 Google Inc. All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This file contains tests verifying correctness of data provided via +// UnitTest's public methods. + +#include "gtest/gtest.h" + +#include // For strcmp. +#include + +using ::testing::InitGoogleTest; + +namespace testing { +namespace internal { + +template +struct LessByName { + bool operator()(const T* a, const T* b) { + return strcmp(a->name(), b->name()) < 0; + } +}; + +class UnitTestHelper { + public: + // Returns the array of pointers to all test cases sorted by the test case + // name. The caller is responsible for deleting the array. + static TestCase const** const GetSortedTestCases() { + UnitTest& unit_test = *UnitTest::GetInstance(); + TestCase const** const test_cases = + new const TestCase*[unit_test.total_test_case_count()]; + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + test_cases[i] = unit_test.GetTestCase(i); + + std::sort(test_cases, + test_cases + unit_test.total_test_case_count(), + LessByName()); + return test_cases; + } + + // Returns the test case by its name. The caller doesn't own the returned + // pointer. + static const TestCase* FindTestCase(const char* name) { + UnitTest& unit_test = *UnitTest::GetInstance(); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase* test_case = unit_test.GetTestCase(i); + if (0 == strcmp(test_case->name(), name)) + return test_case; + } + return NULL; + } + + // Returns the array of pointers to all tests in a particular test case + // sorted by the test name. The caller is responsible for deleting the + // array. + static TestInfo const** const GetSortedTests(const TestCase* test_case) { + TestInfo const** const tests = + new const TestInfo*[test_case->total_test_count()]; + + for (int i = 0; i < test_case->total_test_count(); ++i) + tests[i] = test_case->GetTestInfo(i); + + std::sort(tests, tests + test_case->total_test_count(), + LessByName()); + return tests; + } +}; + +#if GTEST_HAS_TYPED_TEST +template class TestCaseWithCommentTest : public Test {}; +TYPED_TEST_CASE(TestCaseWithCommentTest, Types); +TYPED_TEST(TestCaseWithCommentTest, Dummy) {} + +const int kTypedTestCases = 1; +const int kTypedTests = 1; +#else +const int kTypedTestCases = 0; +const int kTypedTests = 0; +#endif // GTEST_HAS_TYPED_TEST + +// We can only test the accessors that do not change value while tests run. +// Since tests can be run in any order, the values the accessors that track +// test execution (such as failed_test_count) can not be predicted. +TEST(ApiTest, UnitTestImmutableAccessorsWork) { + UnitTest* unit_test = UnitTest::GetInstance(); + + ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); + EXPECT_EQ(1 + kTypedTestCases, unit_test->test_case_to_run_count()); + EXPECT_EQ(2, unit_test->disabled_test_count()); + EXPECT_EQ(5 + kTypedTests, unit_test->total_test_count()); + EXPECT_EQ(3 + kTypedTests, unit_test->test_to_run_count()); + + const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); + + EXPECT_STREQ("ApiTest", test_cases[0]->name()); + EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); +#if GTEST_HAS_TYPED_TEST + EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); +#endif // GTEST_HAS_TYPED_TEST + + delete[] test_cases; + + // The following lines initiate actions to verify certain methods in + // FinalSuccessChecker::TearDown. + + // Records a test property to verify TestResult::GetTestProperty(). + RecordProperty("key", "value"); +} + +AssertionResult IsNull(const char* str) { + if (str != NULL) { + return testing::AssertionFailure() << "argument is " << str; + } + return AssertionSuccess(); +} + +TEST(ApiTest, TestCaseImmutableAccessorsWork) { + const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("ApiTest", test_case->name()); + EXPECT_TRUE(IsNull(test_case->type_param())); + EXPECT_TRUE(test_case->should_run()); + EXPECT_EQ(1, test_case->disabled_test_count()); + EXPECT_EQ(3, test_case->test_to_run_count()); + ASSERT_EQ(4, test_case->total_test_count()); + + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); + + EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); + EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_TRUE(IsNull(tests[0]->type_param())); + EXPECT_FALSE(tests[0]->should_run()); + + EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); + EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); + EXPECT_TRUE(IsNull(tests[1]->value_param())); + EXPECT_TRUE(IsNull(tests[1]->type_param())); + EXPECT_TRUE(tests[1]->should_run()); + + EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); + EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); + EXPECT_TRUE(IsNull(tests[2]->value_param())); + EXPECT_TRUE(IsNull(tests[2]->type_param())); + EXPECT_TRUE(tests[2]->should_run()); + + EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); + EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); + EXPECT_TRUE(IsNull(tests[3]->value_param())); + EXPECT_TRUE(IsNull(tests[3]->type_param())); + EXPECT_TRUE(tests[3]->should_run()); + + delete[] tests; + tests = NULL; + +#if GTEST_HAS_TYPED_TEST + test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name()); + EXPECT_STREQ(GetTypeName().c_str(), test_case->type_param()); + EXPECT_TRUE(test_case->should_run()); + EXPECT_EQ(0, test_case->disabled_test_count()); + EXPECT_EQ(1, test_case->test_to_run_count()); + ASSERT_EQ(1, test_case->total_test_count()); + + tests = UnitTestHelper::GetSortedTests(test_case); + + EXPECT_STREQ("Dummy", tests[0]->name()); + EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); + EXPECT_TRUE(tests[0]->should_run()); + + delete[] tests; +#endif // GTEST_HAS_TYPED_TEST +} + +TEST(ApiTest, TestCaseDisabledAccessorsWork) { + const TestCase* test_case = UnitTestHelper::FindTestCase("DISABLED_Test"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("DISABLED_Test", test_case->name()); + EXPECT_TRUE(IsNull(test_case->type_param())); + EXPECT_FALSE(test_case->should_run()); + EXPECT_EQ(1, test_case->disabled_test_count()); + EXPECT_EQ(0, test_case->test_to_run_count()); + ASSERT_EQ(1, test_case->total_test_count()); + + const TestInfo* const test_info = test_case->GetTestInfo(0); + EXPECT_STREQ("Dummy2", test_info->name()); + EXPECT_STREQ("DISABLED_Test", test_info->test_case_name()); + EXPECT_TRUE(IsNull(test_info->value_param())); + EXPECT_TRUE(IsNull(test_info->type_param())); + EXPECT_FALSE(test_info->should_run()); +} + +// These two tests are here to provide support for testing +// test_case_to_run_count, disabled_test_count, and test_to_run_count. +TEST(ApiTest, DISABLED_Dummy1) {} +TEST(DISABLED_Test, Dummy2) {} + +class FinalSuccessChecker : public Environment { + protected: + virtual void TearDown() { + UnitTest* unit_test = UnitTest::GetInstance(); + + EXPECT_EQ(1 + kTypedTestCases, unit_test->successful_test_case_count()); + EXPECT_EQ(3 + kTypedTests, unit_test->successful_test_count()); + EXPECT_EQ(0, unit_test->failed_test_case_count()); + EXPECT_EQ(0, unit_test->failed_test_count()); + EXPECT_TRUE(unit_test->Passed()); + EXPECT_FALSE(unit_test->Failed()); + ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); + + const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); + + EXPECT_STREQ("ApiTest", test_cases[0]->name()); + EXPECT_TRUE(IsNull(test_cases[0]->type_param())); + EXPECT_TRUE(test_cases[0]->should_run()); + EXPECT_EQ(1, test_cases[0]->disabled_test_count()); + ASSERT_EQ(4, test_cases[0]->total_test_count()); + EXPECT_EQ(3, test_cases[0]->successful_test_count()); + EXPECT_EQ(0, test_cases[0]->failed_test_count()); + EXPECT_TRUE(test_cases[0]->Passed()); + EXPECT_FALSE(test_cases[0]->Failed()); + + EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); + EXPECT_TRUE(IsNull(test_cases[1]->type_param())); + EXPECT_FALSE(test_cases[1]->should_run()); + EXPECT_EQ(1, test_cases[1]->disabled_test_count()); + ASSERT_EQ(1, test_cases[1]->total_test_count()); + EXPECT_EQ(0, test_cases[1]->successful_test_count()); + EXPECT_EQ(0, test_cases[1]->failed_test_count()); + +#if GTEST_HAS_TYPED_TEST + EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); + EXPECT_STREQ(GetTypeName().c_str(), test_cases[2]->type_param()); + EXPECT_TRUE(test_cases[2]->should_run()); + EXPECT_EQ(0, test_cases[2]->disabled_test_count()); + ASSERT_EQ(1, test_cases[2]->total_test_count()); + EXPECT_EQ(1, test_cases[2]->successful_test_count()); + EXPECT_EQ(0, test_cases[2]->failed_test_count()); + EXPECT_TRUE(test_cases[2]->Passed()); + EXPECT_FALSE(test_cases[2]->Failed()); +#endif // GTEST_HAS_TYPED_TEST + + const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); + EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); + EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); + EXPECT_FALSE(tests[0]->should_run()); + + EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); + EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); + EXPECT_TRUE(IsNull(tests[1]->value_param())); + EXPECT_TRUE(IsNull(tests[1]->type_param())); + EXPECT_TRUE(tests[1]->should_run()); + EXPECT_TRUE(tests[1]->result()->Passed()); + EXPECT_EQ(0, tests[1]->result()->test_property_count()); + + EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); + EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); + EXPECT_TRUE(IsNull(tests[2]->value_param())); + EXPECT_TRUE(IsNull(tests[2]->type_param())); + EXPECT_TRUE(tests[2]->should_run()); + EXPECT_TRUE(tests[2]->result()->Passed()); + EXPECT_EQ(0, tests[2]->result()->test_property_count()); + + EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); + EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); + EXPECT_TRUE(IsNull(tests[3]->value_param())); + EXPECT_TRUE(IsNull(tests[3]->type_param())); + EXPECT_TRUE(tests[3]->should_run()); + EXPECT_TRUE(tests[3]->result()->Passed()); + EXPECT_EQ(1, tests[3]->result()->test_property_count()); + const TestProperty& property = tests[3]->result()->GetTestProperty(0); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value", property.value()); + + delete[] tests; + +#if GTEST_HAS_TYPED_TEST + test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); + tests = UnitTestHelper::GetSortedTests(test_case); + + EXPECT_STREQ("Dummy", tests[0]->name()); + EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); + EXPECT_TRUE(tests[0]->should_run()); + EXPECT_TRUE(tests[0]->result()->Passed()); + EXPECT_EQ(0, tests[0]->result()->test_property_count()); + + delete[] tests; +#endif // GTEST_HAS_TYPED_TEST + delete[] test_cases; + } +}; + +} // namespace internal +} // namespace testing + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + AddGlobalTestEnvironment(new testing::internal::FinalSuccessChecker()); + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_all_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_all_test.cc new file mode 100644 index 0000000..955aa62 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_all_test.cc @@ -0,0 +1,47 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build most of Google Test's own tests +// by compiling a single file. This file serves this purpose. +#include "test/gtest-filepath_test.cc" +#include "test/gtest-linked_ptr_test.cc" +#include "test/gtest-message_test.cc" +#include "test/gtest-options_test.cc" +#include "test/gtest-port_test.cc" +#include "test/gtest_pred_impl_unittest.cc" +#include "test/gtest_prod_test.cc" +#include "test/gtest-test-part_test.cc" +#include "test/gtest-typed-test_test.cc" +#include "test/gtest-typed-test2_test.cc" +#include "test/gtest_unittest.cc" +#include "test/production.cc" diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_break_on_failure_unittest.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_break_on_failure_unittest.py new file mode 100755 index 0000000..c819183 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_break_on_failure_unittest.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test for Google Test's break-on-failure mode. + +A user can ask Google Test to seg-fault when an assertion fails, using +either the GTEST_BREAK_ON_FAILURE environment variable or the +--gtest_break_on_failure flag. This script tests such functionality +by invoking gtest_break_on_failure_unittest_ (a program written with +Google Test) with different environments and command line flags. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils +import os +import sys + + +# Constants. + +IS_WINDOWS = os.name == 'nt' + +# The environment variable for enabling/disabling the break-on-failure mode. +BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE' + +# The command line flag for enabling/disabling the break-on-failure mode. +BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure' + +# The environment variable for enabling/disabling the throw-on-failure mode. +THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE' + +# The environment variable for enabling/disabling the catch-exceptions mode. +CATCH_EXCEPTIONS_ENV_VAR = 'GTEST_CATCH_EXCEPTIONS' + +# Path to the gtest_break_on_failure_unittest_ program. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_break_on_failure_unittest_') + + +# Utilities. + + +environ = os.environ.copy() + + +def SetEnvVar(env_var, value): + """Sets an environment variable to a given value; unsets it when the + given value is None. + """ + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +def Run(command): + """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise.""" + + p = gtest_test_utils.Subprocess(command, env=environ) + if p.terminated_by_signal: + return 1 + else: + return 0 + + +# The tests. + + +class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase): + """Tests using the GTEST_BREAK_ON_FAILURE environment variable or + the --gtest_break_on_failure flag to turn assertion failures into + segmentation faults. + """ + + def RunAndVerify(self, env_var_value, flag_value, expect_seg_fault): + """Runs gtest_break_on_failure_unittest_ and verifies that it does + (or does not) have a seg-fault. + + Args: + env_var_value: value of the GTEST_BREAK_ON_FAILURE environment + variable; None if the variable should be unset. + flag_value: value of the --gtest_break_on_failure flag; + None if the flag should not be present. + expect_seg_fault: 1 if the program is expected to generate a seg-fault; + 0 otherwise. + """ + + SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, env_var_value) + + if env_var_value is None: + env_var_value_msg = ' is not set' + else: + env_var_value_msg = '=' + env_var_value + + if flag_value is None: + flag = '' + elif flag_value == '0': + flag = '--%s=0' % BREAK_ON_FAILURE_FLAG + else: + flag = '--%s' % BREAK_ON_FAILURE_FLAG + + command = [EXE_PATH] + if flag: + command.append(flag) + + if expect_seg_fault: + should_or_not = 'should' + else: + should_or_not = 'should not' + + has_seg_fault = Run(command) + + SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None) + + msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' % + (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command), + should_or_not)) + self.assert_(has_seg_fault == expect_seg_fault, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(env_var_value=None, + flag_value=None, + expect_seg_fault=0) + + def testEnvVar(self): + """Tests using the GTEST_BREAK_ON_FAILURE environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value=None, + expect_seg_fault=0) + self.RunAndVerify(env_var_value='1', + flag_value=None, + expect_seg_fault=1) + + def testFlag(self): + """Tests using the --gtest_break_on_failure flag.""" + + self.RunAndVerify(env_var_value=None, + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value=None, + flag_value='1', + expect_seg_fault=1) + + def testFlagOverridesEnvVar(self): + """Tests that the flag overrides the environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value='0', + flag_value='1', + expect_seg_fault=1) + self.RunAndVerify(env_var_value='1', + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value='1', + flag_value='1', + expect_seg_fault=1) + + def testBreakOnFailureOverridesThrowOnFailure(self): + """Tests that gtest_break_on_failure overrides gtest_throw_on_failure.""" + + SetEnvVar(THROW_ON_FAILURE_ENV_VAR, '1') + try: + self.RunAndVerify(env_var_value=None, + flag_value='1', + expect_seg_fault=1) + finally: + SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None) + + if IS_WINDOWS: + def testCatchExceptionsDoesNotInterfere(self): + """Tests that gtest_catch_exceptions doesn't interfere.""" + + SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, '1') + try: + self.RunAndVerify(env_var_value='1', + flag_value='1', + expect_seg_fault=1) + finally: + SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, None) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_break_on_failure_unittest_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_break_on_failure_unittest_.cc new file mode 100644 index 0000000..dd07478 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_break_on_failure_unittest_.cc @@ -0,0 +1,88 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Unit test for Google Test's break-on-failure mode. +// +// A user can ask Google Test to seg-fault when an assertion fails, using +// either the GTEST_BREAK_ON_FAILURE environment variable or the +// --gtest_break_on_failure flag. This file is used for testing such +// functionality. +// +// This program will be invoked from a Python unit test. It is +// expected to fail. Don't run it directly. + +#include "gtest/gtest.h" + +#if GTEST_OS_WINDOWS +# include +# include +#endif + +namespace { + +// A test that's expected to fail. +TEST(Foo, Bar) { + EXPECT_EQ(2, 3); +} + +#if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE +// On Windows Mobile global exception handlers are not supported. +LONG WINAPI ExitWithExceptionCode( + struct _EXCEPTION_POINTERS* exception_pointers) { + exit(exception_pointers->ExceptionRecord->ExceptionCode); +} +#endif + +} // namespace + +int main(int argc, char **argv) { +#if GTEST_OS_WINDOWS + // Suppresses display of the Windows error dialog upon encountering + // a general protection fault (segment violation). + SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); + +# if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE + + // The default unhandled exception filter does not always exit + // with the exception code as exit code - for example it exits with + // 0 for EXCEPTION_ACCESS_VIOLATION and 1 for EXCEPTION_BREAKPOINT + // if the application is compiled in debug mode. Thus we use our own + // filter which always exits with the exception code for unhandled + // exceptions. + SetUnhandledExceptionFilter(ExitWithExceptionCode); + +# endif +#endif + + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_catch_exceptions_test.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_catch_exceptions_test.py new file mode 100755 index 0000000..d7ef10e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_catch_exceptions_test.py @@ -0,0 +1,223 @@ +#!/usr/bin/env python +# +# Copyright 2010 Google Inc. All Rights Reserved. +# +# 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. + +"""Tests Google Test's exception catching behavior. + +This script invokes gtest_catch_exceptions_test_ and +gtest_catch_exceptions_ex_test_ (programs written with +Google Test) and verifies their output. +""" + +__author__ = 'vladl@google.com (Vlad Losev)' + +import os + +import gtest_test_utils + +# Constants. +FLAG_PREFIX = '--gtest_' +LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' +NO_CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions=0' +FILTER_FLAG = FLAG_PREFIX + 'filter' + +# Path to the gtest_catch_exceptions_ex_test_ binary, compiled with +# exceptions enabled. +EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_catch_exceptions_ex_test_') + +# Path to the gtest_catch_exceptions_test_ binary, compiled with +# exceptions disabled. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_catch_exceptions_no_ex_test_') + +TEST_LIST = gtest_test_utils.Subprocess([EXE_PATH, LIST_TESTS_FLAG]).output + +SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST + +if SUPPORTS_SEH_EXCEPTIONS: + BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH]).output + +EX_BINARY_OUTPUT = gtest_test_utils.Subprocess([EX_EXE_PATH]).output + +# The tests. +if SUPPORTS_SEH_EXCEPTIONS: + # pylint:disable-msg=C6302 + class CatchSehExceptionsTest(gtest_test_utils.TestCase): + """Tests exception-catching behavior.""" + + + def TestSehExceptions(self, test_output): + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s constructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s destructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUpTestCase()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDownTestCase()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUp()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDown()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in the test body' + in test_output) + + def testCatchesSehExceptionsWithCxxExceptionsEnabled(self): + self.TestSehExceptions(EX_BINARY_OUTPUT) + + def testCatchesSehExceptionsWithCxxExceptionsDisabled(self): + self.TestSehExceptions(BINARY_OUTPUT) + + +class CatchCxxExceptionsTest(gtest_test_utils.TestCase): + """Tests C++ exception-catching behavior. + + Tests in this test case verify that: + * C++ exceptions are caught and logged as C++ (not SEH) exceptions + * Exception thrown affect the remainder of the test work flow in the + expected manner. + """ + + def testCatchesCxxExceptionsInFixtureConstructor(self): + self.assert_('C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s constructor' + in EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInConstructorTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in + EX_BINARY_OUTPUT): + + def testCatchesCxxExceptionsInFixtureDestructor(self): + self.assert_('C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s destructor' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUpTestCase(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in SetUpTestCase()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInConstructorTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest constructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest::SetUp() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest test body ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTearDownTestCase(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in TearDownTestCase()' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUp(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in SetUp()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInSetUpTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + def testCatchesCxxExceptionsInTearDown(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in TearDown()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTearDownTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTearDownTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTestBody(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in the test body' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesNonStdCxxExceptions(self): + self.assert_('Unknown C++ exception thrown in the test body' + in EX_BINARY_OUTPUT) + + def testUnhandledCxxExceptionsAbortTheProgram(self): + # Filters out SEH exception tests on Windows. Unhandled SEH exceptions + # cause tests to show pop-up windows there. + FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*' + # By default, Google Test doesn't catch the exceptions. + uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( + [EX_EXE_PATH, + NO_CATCH_EXCEPTIONS_FLAG, + FITLER_OUT_SEH_TESTS_FLAG]).output + + self.assert_('Unhandled C++ exception terminating the program' + in uncaught_exceptions_ex_binary_output) + self.assert_('unexpected' not in uncaught_exceptions_ex_binary_output) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_catch_exceptions_test_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_catch_exceptions_test_.cc new file mode 100644 index 0000000..d0fc82c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_catch_exceptions_test_.cc @@ -0,0 +1,311 @@ +// Copyright 2010, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. Tests in this file throw C++ or SEH +// exceptions, and the output is verified by gtest_catch_exceptions_test.py. + +#include "gtest/gtest.h" + +#include // NOLINT +#include // For exit(). + +#if GTEST_HAS_SEH +# include +#endif + +#if GTEST_HAS_EXCEPTIONS +# include // For set_terminate(). +# include +#endif + +using testing::Test; + +#if GTEST_HAS_SEH + +class SehExceptionInConstructorTest : public Test { + public: + SehExceptionInConstructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInConstructorTest, ThrowsExceptionInConstructor) {} + +class SehExceptionInDestructorTest : public Test { + public: + ~SehExceptionInDestructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInDestructorTest, ThrowsExceptionInDestructor) {} + +class SehExceptionInSetUpTestCaseTest : public Test { + public: + static void SetUpTestCase() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) {} + +class SehExceptionInTearDownTestCaseTest : public Test { + public: + static void TearDownTestCase() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} + +class SehExceptionInSetUpTest : public Test { + protected: + virtual void SetUp() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTest, ThrowsExceptionInSetUp) {} + +class SehExceptionInTearDownTest : public Test { + protected: + virtual void TearDown() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +TEST(SehExceptionTest, ThrowsSehException) { + RaiseException(42, 0, 0, NULL); +} + +#endif // GTEST_HAS_SEH + +#if GTEST_HAS_EXCEPTIONS + +class CxxExceptionInConstructorTest : public Test { + public: + CxxExceptionInConstructorTest() { + // Without this macro VC++ complains about unreachable code at the end of + // the constructor. + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + throw std::runtime_error("Standard C++ exception")); + } + + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInConstructorTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInConstructorTest() { + ADD_FAILURE() << "CxxExceptionInConstructorTest destructor " + << "called unexpectedly."; + } + + virtual void SetUp() { + ADD_FAILURE() << "CxxExceptionInConstructorTest::SetUp() " + << "called unexpectedly."; + } + + virtual void TearDown() { + ADD_FAILURE() << "CxxExceptionInConstructorTest::TearDown() " + << "called unexpectedly."; + } +}; + +TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) { + ADD_FAILURE() << "CxxExceptionInConstructorTest test body " + << "called unexpectedly."; +} + +// Exceptions in destructors are not supported in C++11. +#if !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L +class CxxExceptionInDestructorTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInDestructorTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInDestructorTest() { + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + throw std::runtime_error("Standard C++ exception")); + } +}; + +TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {} +#endif // C++11 mode + +class CxxExceptionInSetUpTestCaseTest : public Test { + public: + CxxExceptionInSetUpTestCaseTest() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest constructor " + "called as expected.\n"); + } + + static void SetUpTestCase() { + throw std::runtime_error("Standard C++ exception"); + } + + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTestCaseTest() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest destructor " + "called as expected.\n"); + } + + virtual void SetUp() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::SetUp() " + "called as expected.\n"); + } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) { + printf("%s", + "CxxExceptionInSetUpTestCaseTest test body " + "called as expected.\n"); +} + +class CxxExceptionInTearDownTestCaseTest : public Test { + public: + static void TearDownTestCase() { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} + +class CxxExceptionInSetUpTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInSetUpTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTest() { + printf("%s", + "CxxExceptionInSetUpTest destructor " + "called as expected.\n"); + } + + virtual void SetUp() { throw std::runtime_error("Standard C++ exception"); } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInSetUpTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTest, ThrowsExceptionInSetUp) { + ADD_FAILURE() << "CxxExceptionInSetUpTest test body " + << "called unexpectedly."; +} + +class CxxExceptionInTearDownTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInTearDownTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTearDownTest() { + printf("%s", + "CxxExceptionInTearDownTest destructor " + "called as expected.\n"); + } + + virtual void TearDown() { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +class CxxExceptionInTestBodyTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInTestBodyTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTestBodyTest() { + printf("%s", + "CxxExceptionInTestBodyTest destructor " + "called as expected.\n"); + } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInTestBodyTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInTestBodyTest, ThrowsStdCxxException) { + throw std::runtime_error("Standard C++ exception"); +} + +TEST(CxxExceptionTest, ThrowsNonStdCxxException) { + throw "C-string"; +} + +// This terminate handler aborts the program using exit() rather than abort(). +// This avoids showing pop-ups on Windows systems and core dumps on Unix-like +// ones. +void TerminateHandler() { + fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); + fflush(NULL); + exit(3); +} + +#endif // GTEST_HAS_EXCEPTIONS + +int main(int argc, char** argv) { +#if GTEST_HAS_EXCEPTIONS + std::set_terminate(&TerminateHandler); +#endif + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_color_test.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_color_test.py new file mode 100755 index 0000000..d02a53e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_color_test.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""Verifies that Google Test correctly determines whether to use colors.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + + +IS_WINDOWS = os.name = 'nt' + +COLOR_ENV_VAR = 'GTEST_COLOR' +COLOR_FLAG = 'gtest_color' +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_color_test_') + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def UsesColor(term, color_env_var, color_flag): + """Runs gtest_color_test_ and returns its exit code.""" + + SetEnvVar('TERM', term) + SetEnvVar(COLOR_ENV_VAR, color_env_var) + + if color_flag is None: + args = [] + else: + args = ['--%s=%s' % (COLOR_FLAG, color_flag)] + p = gtest_test_utils.Subprocess([COMMAND] + args) + return not p.exited or p.exit_code + + +class GTestColorTest(gtest_test_utils.TestCase): + def testNoEnvVarNoFlag(self): + """Tests the case when there's neither GTEST_COLOR nor --gtest_color.""" + + if not IS_WINDOWS: + self.assert_(not UsesColor('dumb', None, None)) + self.assert_(not UsesColor('emacs', None, None)) + self.assert_(not UsesColor('xterm-mono', None, None)) + self.assert_(not UsesColor('unknown', None, None)) + self.assert_(not UsesColor(None, None, None)) + self.assert_(UsesColor('linux', None, None)) + self.assert_(UsesColor('cygwin', None, None)) + self.assert_(UsesColor('xterm', None, None)) + self.assert_(UsesColor('xterm-color', None, None)) + self.assert_(UsesColor('xterm-256color', None, None)) + + def testFlagOnly(self): + """Tests the case when there's --gtest_color but not GTEST_COLOR.""" + + self.assert_(not UsesColor('dumb', None, 'no')) + self.assert_(not UsesColor('xterm-color', None, 'no')) + if not IS_WINDOWS: + self.assert_(not UsesColor('emacs', None, 'auto')) + self.assert_(UsesColor('xterm', None, 'auto')) + self.assert_(UsesColor('dumb', None, 'yes')) + self.assert_(UsesColor('xterm', None, 'yes')) + + def testEnvVarOnly(self): + """Tests the case when there's GTEST_COLOR but not --gtest_color.""" + + self.assert_(not UsesColor('dumb', 'no', None)) + self.assert_(not UsesColor('xterm-color', 'no', None)) + if not IS_WINDOWS: + self.assert_(not UsesColor('dumb', 'auto', None)) + self.assert_(UsesColor('xterm-color', 'auto', None)) + self.assert_(UsesColor('dumb', 'yes', None)) + self.assert_(UsesColor('xterm-color', 'yes', None)) + + def testEnvVarAndFlag(self): + """Tests the case when there are both GTEST_COLOR and --gtest_color.""" + + self.assert_(not UsesColor('xterm-color', 'no', 'no')) + self.assert_(UsesColor('dumb', 'no', 'yes')) + self.assert_(UsesColor('xterm-color', 'no', 'auto')) + + def testAliasesOfYesAndNo(self): + """Tests using aliases in specifying --gtest_color.""" + + self.assert_(UsesColor('dumb', None, 'true')) + self.assert_(UsesColor('dumb', None, 'YES')) + self.assert_(UsesColor('dumb', None, 'T')) + self.assert_(UsesColor('dumb', None, '1')) + + self.assert_(not UsesColor('xterm', None, 'f')) + self.assert_(not UsesColor('xterm', None, 'false')) + self.assert_(not UsesColor('xterm', None, '0')) + self.assert_(not UsesColor('xterm', None, 'unknown')) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_color_test_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_color_test_.cc new file mode 100644 index 0000000..f61ebb8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_color_test_.cc @@ -0,0 +1,71 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// A helper program for testing how Google Test determines whether to use +// colors in the output. It prints "YES" and returns 1 if Google Test +// decides to use colors, and prints "NO" and returns 0 otherwise. + +#include + +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +using testing::internal::ShouldUseColor; + +// The purpose of this is to ensure that the UnitTest singleton is +// created before main() is entered, and thus that ShouldUseColor() +// works the same way as in a real Google-Test-based test. We don't actual +// run the TEST itself. +TEST(GTestColorTest, Dummy) { +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + if (ShouldUseColor(true)) { + // Google Test decides to use colors in the output (assuming it + // goes to a TTY). + printf("YES\n"); + return 1; + } else { + // Google Test decides not to use colors in the output. + printf("NO\n"); + return 0; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_env_var_test.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_env_var_test.py new file mode 100755 index 0000000..ac24337 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_env_var_test.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""Verifies that Google Test correctly parses environment variables.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + + +IS_WINDOWS = os.name == 'nt' +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' + +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_') + +environ = os.environ.copy() + + +def AssertEq(expected, actual): + if expected != actual: + print 'Expected: %s' % (expected,) + print ' Actual: %s' % (actual,) + raise AssertionError + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +def GetFlag(flag): + """Runs gtest_env_var_test_ and returns its output.""" + + args = [COMMAND] + if flag is not None: + args += [flag] + return gtest_test_utils.Subprocess(args, env=environ).output + + +def TestFlag(flag, test_val, default_val): + """Verifies that the given flag is affected by the corresponding env var.""" + + env_var = 'GTEST_' + flag.upper() + SetEnvVar(env_var, test_val) + AssertEq(test_val, GetFlag(flag)) + SetEnvVar(env_var, None) + AssertEq(default_val, GetFlag(flag)) + + +class GTestEnvVarTest(gtest_test_utils.TestCase): + def testEnvVarAffectsFlag(self): + """Tests that environment variable should affect the corresponding flag.""" + + TestFlag('break_on_failure', '1', '0') + TestFlag('color', 'yes', 'auto') + TestFlag('filter', 'FooTest.Bar', '*') + TestFlag('output', 'xml:tmp/foo.xml', '') + TestFlag('print_time', '0', '1') + TestFlag('repeat', '999', '1') + TestFlag('throw_on_failure', '1', '0') + TestFlag('death_test_style', 'threadsafe', 'fast') + TestFlag('catch_exceptions', '0', '1') + + if IS_LINUX: + TestFlag('death_test_use_fork', '1', '0') + TestFlag('stack_trace_depth', '0', '100') + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_env_var_test_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_env_var_test_.cc new file mode 100644 index 0000000..539afc9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_env_var_test_.cc @@ -0,0 +1,126 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// A helper program for testing that Google Test parses the environment +// variables correctly. + +#include "gtest/gtest.h" + +#include + +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +using ::std::cout; + +namespace testing { + +// The purpose of this is to make the test more realistic by ensuring +// that the UnitTest singleton is created before main() is entered. +// We don't actual run the TEST itself. +TEST(GTestEnvVarTest, Dummy) { +} + +void PrintFlag(const char* flag) { + if (strcmp(flag, "break_on_failure") == 0) { + cout << GTEST_FLAG(break_on_failure); + return; + } + + if (strcmp(flag, "catch_exceptions") == 0) { + cout << GTEST_FLAG(catch_exceptions); + return; + } + + if (strcmp(flag, "color") == 0) { + cout << GTEST_FLAG(color); + return; + } + + if (strcmp(flag, "death_test_style") == 0) { + cout << GTEST_FLAG(death_test_style); + return; + } + + if (strcmp(flag, "death_test_use_fork") == 0) { + cout << GTEST_FLAG(death_test_use_fork); + return; + } + + if (strcmp(flag, "filter") == 0) { + cout << GTEST_FLAG(filter); + return; + } + + if (strcmp(flag, "output") == 0) { + cout << GTEST_FLAG(output); + return; + } + + if (strcmp(flag, "print_time") == 0) { + cout << GTEST_FLAG(print_time); + return; + } + + if (strcmp(flag, "repeat") == 0) { + cout << GTEST_FLAG(repeat); + return; + } + + if (strcmp(flag, "stack_trace_depth") == 0) { + cout << GTEST_FLAG(stack_trace_depth); + return; + } + + if (strcmp(flag, "throw_on_failure") == 0) { + cout << GTEST_FLAG(throw_on_failure); + return; + } + + cout << "Invalid flag name " << flag + << ". Valid names are break_on_failure, color, filter, etc.\n"; + exit(1); +} + +} // namespace testing + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + if (argc != 2) { + cout << "Usage: gtest_env_var_test_ NAME_OF_FLAG\n"; + return 1; + } + + testing::PrintFlag(argv[1]); + return 0; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_environment_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_environment_test.cc new file mode 100644 index 0000000..3cff19e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_environment_test.cc @@ -0,0 +1,192 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests using global test environments. + +#include +#include +#include "gtest/gtest.h" + +#define GTEST_IMPLEMENTATION_ 1 // Required for the next #include. +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +GTEST_DECLARE_string_(filter); +} + +namespace { + +enum FailureType { + NO_FAILURE, NON_FATAL_FAILURE, FATAL_FAILURE +}; + +// For testing using global test environments. +class MyEnvironment : public testing::Environment { + public: + MyEnvironment() { Reset(); } + + // Depending on the value of failure_in_set_up_, SetUp() will + // generate a non-fatal failure, generate a fatal failure, or + // succeed. + virtual void SetUp() { + set_up_was_run_ = true; + + switch (failure_in_set_up_) { + case NON_FATAL_FAILURE: + ADD_FAILURE() << "Expected non-fatal failure in global set-up."; + break; + case FATAL_FAILURE: + FAIL() << "Expected fatal failure in global set-up."; + break; + default: + break; + } + } + + // Generates a non-fatal failure. + virtual void TearDown() { + tear_down_was_run_ = true; + ADD_FAILURE() << "Expected non-fatal failure in global tear-down."; + } + + // Resets the state of the environment s.t. it can be reused. + void Reset() { + failure_in_set_up_ = NO_FAILURE; + set_up_was_run_ = false; + tear_down_was_run_ = false; + } + + // We call this function to set the type of failure SetUp() should + // generate. + void set_failure_in_set_up(FailureType type) { + failure_in_set_up_ = type; + } + + // Was SetUp() run? + bool set_up_was_run() const { return set_up_was_run_; } + + // Was TearDown() run? + bool tear_down_was_run() const { return tear_down_was_run_; } + + private: + FailureType failure_in_set_up_; + bool set_up_was_run_; + bool tear_down_was_run_; +}; + +// Was the TEST run? +bool test_was_run; + +// The sole purpose of this TEST is to enable us to check whether it +// was run. +TEST(FooTest, Bar) { + test_was_run = true; +} + +// Prints the message and aborts the program if condition is false. +void Check(bool condition, const char* msg) { + if (!condition) { + printf("FAILED: %s\n", msg); + testing::internal::posix::Abort(); + } +} + +// Runs the tests. Return true iff successful. +// +// The 'failure' parameter specifies the type of failure that should +// be generated by the global set-up. +int RunAllTests(MyEnvironment* env, FailureType failure) { + env->Reset(); + env->set_failure_in_set_up(failure); + test_was_run = false; + testing::internal::GetUnitTestImpl()->ClearAdHocTestResult(); + return RUN_ALL_TESTS(); +} + +} // namespace + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + // Registers a global test environment, and verifies that the + // registration function returns its argument. + MyEnvironment* const env = new MyEnvironment; + Check(testing::AddGlobalTestEnvironment(env) == env, + "AddGlobalTestEnvironment() should return its argument."); + + // Verifies that RUN_ALL_TESTS() runs the tests when the global + // set-up is successful. + Check(RunAllTests(env, NO_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as the global tear-down " + "should generate a failure."); + Check(test_was_run, + "The tests should run, as the global set-up should generate no " + "failure"); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() runs the tests when the global + // set-up generates no fatal failure. + Check(RunAllTests(env, NON_FATAL_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as both the global set-up " + "and the global tear-down should generate a non-fatal failure."); + Check(test_was_run, + "The tests should run, as the global set-up should generate no " + "fatal failure."); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() runs no test when the global set-up + // generates a fatal failure. + Check(RunAllTests(env, FATAL_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as the global set-up " + "should generate a fatal failure."); + Check(!test_was_run, + "The tests should not run, as the global set-up should generate " + "a fatal failure."); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() doesn't do global set-up or + // tear-down when there is no test to run. + testing::GTEST_FLAG(filter) = "-*"; + Check(RunAllTests(env, NO_FAILURE) == 0, + "RUN_ALL_TESTS() should return zero, as there is no test to run."); + Check(!env->set_up_was_run(), + "The global set-up should not run, as there is no test to run."); + Check(!env->tear_down_was_run(), + "The global tear-down should not run, " + "as the global set-up was not run."); + + printf("PASS\n"); + return 0; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_filter_unittest.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_filter_unittest.py new file mode 100755 index 0000000..0d1a770 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_filter_unittest.py @@ -0,0 +1,633 @@ +#!/usr/bin/env python +# +# Copyright 2005 Google Inc. All Rights Reserved. +# +# 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. + +"""Unit test for Google Test test filters. + +A user can specify which test(s) in a Google Test program to run via either +the GTEST_FILTER environment variable or the --gtest_filter flag. +This script tests such functionality by invoking +gtest_filter_unittest_ (a program written with Google Test) with different +environments and command line flags. + +Note that test sharding may also influence which tests are filtered. Therefore, +we test that here also. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sets +import sys + +import gtest_test_utils + +# Constants. + +# Checks if this platform can pass empty environment variables to child +# processes. We set an env variable to an empty string and invoke a python +# script in a subprocess to print whether the variable is STILL in +# os.environ. We then use 'eval' to parse the child's output so that an +# exception is thrown if the input is anything other than 'True' nor 'False'. +os.environ['EMPTY_VAR'] = '' +child = gtest_test_utils.Subprocess( + [sys.executable, '-c', 'import os; print \'EMPTY_VAR\' in os.environ']) +CAN_PASS_EMPTY_ENV = eval(child.output) + + +# Check if this platform can unset environment variables in child processes. +# We set an env variable to a non-empty string, unset it, and invoke +# a python script in a subprocess to print whether the variable +# is NO LONGER in os.environ. +# We use 'eval' to parse the child's output so that an exception +# is thrown if the input is neither 'True' nor 'False'. +os.environ['UNSET_VAR'] = 'X' +del os.environ['UNSET_VAR'] +child = gtest_test_utils.Subprocess( + [sys.executable, '-c', 'import os; print \'UNSET_VAR\' not in os.environ']) +CAN_UNSET_ENV = eval(child.output) + + +# Checks if we should test with an empty filter. This doesn't +# make sense on platforms that cannot pass empty env variables (Win32) +# and on platforms that cannot unset variables (since we cannot tell +# the difference between "" and NULL -- Borland and Solaris < 5.10) +CAN_TEST_EMPTY_FILTER = (CAN_PASS_EMPTY_ENV and CAN_UNSET_ENV) + + +# The environment variable for specifying the test filters. +FILTER_ENV_VAR = 'GTEST_FILTER' + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' +SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE' + +# The command line flag for specifying the test filters. +FILTER_FLAG = 'gtest_filter' + +# The command line flag for including disabled tests. +ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests' + +# Command to run the gtest_filter_unittest_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_') + +# Regex for determining whether parameterized tests are enabled in the binary. +PARAM_TEST_REGEX = re.compile(r'/ParamTest') + +# Regex for parsing test case names from Google Test's output. +TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)') + +# Regex for parsing test names from Google Test's output. +TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)') + +# The command line flag to tell Google Test to output the list of tests it +# will run. +LIST_TESTS_FLAG = '--gtest_list_tests' + +# Indicates whether Google Test supports death tests. +SUPPORTS_DEATH_TESTS = 'HasDeathTest' in gtest_test_utils.Subprocess( + [COMMAND, LIST_TESTS_FLAG]).output + +# Full names of all tests in gtest_filter_unittests_. +PARAM_TESTS = [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + 'SeqQ/ParamTest.TestX/0', + 'SeqQ/ParamTest.TestX/1', + 'SeqQ/ParamTest.TestY/0', + 'SeqQ/ParamTest.TestY/1', + ] + +DISABLED_TESTS = [ + 'BarTest.DISABLED_TestFour', + 'BarTest.DISABLED_TestFive', + 'BazTest.DISABLED_TestC', + 'DISABLED_FoobarTest.Test1', + 'DISABLED_FoobarTest.DISABLED_Test2', + 'DISABLED_FoobarbazTest.TestA', + ] + +if SUPPORTS_DEATH_TESTS: + DEATH_TESTS = [ + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', + ] +else: + DEATH_TESTS = [] + +# All the non-disabled tests. +ACTIVE_TESTS = [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', + ] + DEATH_TESTS + PARAM_TESTS + +param_tests_present = None + +# Utilities. + +environ = os.environ.copy() + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +def RunAndReturnOutput(args = None): + """Runs the test program and returns its output.""" + + return gtest_test_utils.Subprocess([COMMAND] + (args or []), + env=environ).output + + +def RunAndExtractTestList(args = None): + """Runs the test program and returns its exit code and a list of tests run.""" + + p = gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ) + tests_run = [] + test_case = '' + test = '' + for line in p.output.split('\n'): + match = TEST_CASE_REGEX.match(line) + if match is not None: + test_case = match.group(1) + else: + match = TEST_REGEX.match(line) + if match is not None: + test = match.group(1) + tests_run.append(test_case + '.' + test) + return (tests_run, p.exit_code) + + +def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs): + """Runs the given function and arguments in a modified environment.""" + try: + original_env = environ.copy() + environ.update(extra_env) + return function(*args, **kwargs) + finally: + environ.clear() + environ.update(original_env) + + +def RunWithSharding(total_shards, shard_index, command): + """Runs a test program shard and returns exit code and a list of tests run.""" + + extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index), + TOTAL_SHARDS_ENV_VAR: str(total_shards)} + return InvokeWithModifiedEnv(extra_env, RunAndExtractTestList, command) + +# The unit test. + + +class GTestFilterUnitTest(gtest_test_utils.TestCase): + """Tests the env variable or the command line flag to filter tests.""" + + # Utilities. + + def AssertSetEqual(self, lhs, rhs): + """Asserts that two sets are equal.""" + + for elem in lhs: + self.assert_(elem in rhs, '%s in %s' % (elem, rhs)) + + for elem in rhs: + self.assert_(elem in lhs, '%s in %s' % (elem, lhs)) + + def AssertPartitionIsValid(self, set_var, list_of_sets): + """Asserts that list_of_sets is a valid partition of set_var.""" + + full_partition = [] + for slice_var in list_of_sets: + full_partition.extend(slice_var) + self.assertEqual(len(set_var), len(full_partition)) + self.assertEqual(sets.Set(set_var), sets.Set(full_partition)) + + def AdjustForParameterizedTests(self, tests_to_run): + """Adjust tests_to_run in case value parameterized tests are disabled.""" + + global param_tests_present + if not param_tests_present: + return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS)) + else: + return tests_to_run + + def RunAndVerify(self, gtest_filter, tests_to_run): + """Checks that the binary runs correct set of tests for a given filter.""" + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # First, tests using the environment variable. + + # Windows removes empty variables from the environment when passing it + # to a new process. This means it is impossible to pass an empty filter + # into a process using the environment variable. However, we can still + # test the case when the variable is not supplied (i.e., gtest_filter is + # None). + # pylint: disable-msg=C6403 + if CAN_TEST_EMPTY_FILTER or gtest_filter != '': + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + tests_run = RunAndExtractTestList()[0] + SetEnvVar(FILTER_ENV_VAR, None) + self.AssertSetEqual(tests_run, tests_to_run) + # pylint: enable-msg=C6403 + + # Next, tests using the command line flag. + + if gtest_filter is None: + args = [] + else: + args = ['--%s=%s' % (FILTER_FLAG, gtest_filter)] + + tests_run = RunAndExtractTestList(args)[0] + self.AssertSetEqual(tests_run, tests_to_run) + + def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run, + args=None, check_exit_0=False): + """Checks that binary runs correct tests for the given filter and shard. + + Runs all shards of gtest_filter_unittest_ with the given filter, and + verifies that the right set of tests were run. The union of tests run + on each shard should be identical to tests_to_run, without duplicates. + + Args: + gtest_filter: A filter to apply to the tests. + total_shards: A total number of shards to split test run into. + tests_to_run: A set of tests expected to run. + args : Arguments to pass to the to the test binary. + check_exit_0: When set to a true value, make sure that all shards + return 0. + """ + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # Windows removes empty variables from the environment when passing it + # to a new process. This means it is impossible to pass an empty filter + # into a process using the environment variable. However, we can still + # test the case when the variable is not supplied (i.e., gtest_filter is + # None). + # pylint: disable-msg=C6403 + if CAN_TEST_EMPTY_FILTER or gtest_filter != '': + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + partition = [] + for i in range(0, total_shards): + (tests_run, exit_code) = RunWithSharding(total_shards, i, args) + if check_exit_0: + self.assertEqual(0, exit_code) + partition.append(tests_run) + + self.AssertPartitionIsValid(tests_to_run, partition) + SetEnvVar(FILTER_ENV_VAR, None) + # pylint: enable-msg=C6403 + + def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run): + """Checks that the binary runs correct set of tests for the given filter. + + Runs gtest_filter_unittest_ with the given filter, and enables + disabled tests. Verifies that the right set of tests were run. + + Args: + gtest_filter: A filter to apply to the tests. + tests_to_run: A set of tests expected to run. + """ + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # Construct the command line. + args = ['--%s' % ALSO_RUN_DISABED_TESTS_FLAG] + if gtest_filter is not None: + args.append('--%s=%s' % (FILTER_FLAG, gtest_filter)) + + tests_run = RunAndExtractTestList(args)[0] + self.AssertSetEqual(tests_run, tests_to_run) + + def setUp(self): + """Sets up test case. + + Determines whether value-parameterized tests are enabled in the binary and + sets the flags accordingly. + """ + + global param_tests_present + if param_tests_present is None: + param_tests_present = PARAM_TEST_REGEX.search( + RunAndReturnOutput()) is not None + + def testDefaultBehavior(self): + """Tests the behavior of not specifying the filter.""" + + self.RunAndVerify(None, ACTIVE_TESTS) + + def testDefaultBehaviorWithShards(self): + """Tests the behavior without the filter, with sharding enabled.""" + + self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS), ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) + 1, ACTIVE_TESTS) + + def testEmptyFilter(self): + """Tests an empty filter.""" + + self.RunAndVerify('', []) + self.RunAndVerifyWithSharding('', 1, []) + self.RunAndVerifyWithSharding('', 2, []) + + def testBadFilter(self): + """Tests a filter that matches nothing.""" + + self.RunAndVerify('BadFilter', []) + self.RunAndVerifyAllowingDisabled('BadFilter', []) + + def testFullName(self): + """Tests filtering by full name.""" + + self.RunAndVerify('FooTest.Xyz', ['FooTest.Xyz']) + self.RunAndVerifyAllowingDisabled('FooTest.Xyz', ['FooTest.Xyz']) + self.RunAndVerifyWithSharding('FooTest.Xyz', 5, ['FooTest.Xyz']) + + def testUniversalFilters(self): + """Tests filters that match everything.""" + + self.RunAndVerify('*', ACTIVE_TESTS) + self.RunAndVerify('*.*', ACTIVE_TESTS) + self.RunAndVerifyWithSharding('*.*', len(ACTIVE_TESTS) - 3, ACTIVE_TESTS) + self.RunAndVerifyAllowingDisabled('*', ACTIVE_TESTS + DISABLED_TESTS) + self.RunAndVerifyAllowingDisabled('*.*', ACTIVE_TESTS + DISABLED_TESTS) + + def testFilterByTestCase(self): + """Tests filtering by test case name.""" + + self.RunAndVerify('FooTest.*', ['FooTest.Abc', 'FooTest.Xyz']) + + BAZ_TESTS = ['BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB'] + self.RunAndVerify('BazTest.*', BAZ_TESTS) + self.RunAndVerifyAllowingDisabled('BazTest.*', + BAZ_TESTS + ['BazTest.DISABLED_TestC']) + + def testFilterByTest(self): + """Tests filtering by test name.""" + + self.RunAndVerify('*.TestOne', ['BarTest.TestOne', 'BazTest.TestOne']) + + def testFilterDisabledTests(self): + """Select only the disabled tests to run.""" + + self.RunAndVerify('DISABLED_FoobarTest.Test1', []) + self.RunAndVerifyAllowingDisabled('DISABLED_FoobarTest.Test1', + ['DISABLED_FoobarTest.Test1']) + + self.RunAndVerify('*DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('*DISABLED_*', DISABLED_TESTS) + + self.RunAndVerify('*.DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('*.DISABLED_*', [ + 'BarTest.DISABLED_TestFour', + 'BarTest.DISABLED_TestFive', + 'BazTest.DISABLED_TestC', + 'DISABLED_FoobarTest.DISABLED_Test2', + ]) + + self.RunAndVerify('DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('DISABLED_*', [ + 'DISABLED_FoobarTest.Test1', + 'DISABLED_FoobarTest.DISABLED_Test2', + 'DISABLED_FoobarbazTest.TestA', + ]) + + def testWildcardInTestCaseName(self): + """Tests using wildcard in the test case name.""" + + self.RunAndVerify('*a*.*', [ + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS) + + def testWildcardInTestName(self): + """Tests using wildcard in the test name.""" + + self.RunAndVerify('*.*A*', ['FooTest.Abc', 'BazTest.TestA']) + + def testFilterWithoutDot(self): + """Tests a filter that has no '.' in it.""" + + self.RunAndVerify('*z*', [ + 'FooTest.Xyz', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', + ]) + + def testTwoPatterns(self): + """Tests filters that consist of two patterns.""" + + self.RunAndVerify('Foo*.*:*A*', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BazTest.TestA', + ]) + + # An empty pattern + a non-empty one + self.RunAndVerify(':*A*', ['FooTest.Abc', 'BazTest.TestA']) + + def testThreePatterns(self): + """Tests filters that consist of three patterns.""" + + self.RunAndVerify('*oo*:*A*:*One', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + + 'BazTest.TestOne', + 'BazTest.TestA', + ]) + + # The 2nd pattern is empty. + self.RunAndVerify('*oo*::*One', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + + 'BazTest.TestOne', + ]) + + # The last 2 patterns are empty. + self.RunAndVerify('*oo*::', [ + 'FooTest.Abc', + 'FooTest.Xyz', + ]) + + def testNegativeFilters(self): + self.RunAndVerify('*-BazTest.TestOne', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestA', + 'BazTest.TestB', + ] + DEATH_TESTS + PARAM_TESTS) + + self.RunAndVerify('*-FooTest.Abc:BazTest.*', [ + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + ] + DEATH_TESTS + PARAM_TESTS) + + self.RunAndVerify('BarTest.*-BarTest.TestOne', [ + 'BarTest.TestTwo', + 'BarTest.TestThree', + ]) + + # Tests without leading '*'. + self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:BazTest.*', [ + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + ] + DEATH_TESTS + PARAM_TESTS) + + # Value parameterized tests. + self.RunAndVerify('*/*', PARAM_TESTS) + + # Value parameterized tests filtering by the sequence name. + self.RunAndVerify('SeqP/*', [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + ]) + + # Value parameterized tests filtering by the test name. + self.RunAndVerify('*/0', [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestY/0', + 'SeqQ/ParamTest.TestX/0', + 'SeqQ/ParamTest.TestY/0', + ]) + + def testFlagOverridesEnvVar(self): + """Tests that the filter flag overrides the filtering env. variable.""" + + SetEnvVar(FILTER_ENV_VAR, 'Foo*') + args = ['--%s=%s' % (FILTER_FLAG, '*One')] + tests_run = RunAndExtractTestList(args)[0] + SetEnvVar(FILTER_ENV_VAR, None) + + self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne']) + + def testShardStatusFileIsCreated(self): + """Tests that the shard file is created if specified in the environment.""" + + shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), + 'shard_status_file') + self.assert_(not os.path.exists(shard_status_file)) + + extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} + try: + InvokeWithModifiedEnv(extra_env, RunAndReturnOutput) + finally: + self.assert_(os.path.exists(shard_status_file)) + os.remove(shard_status_file) + + def testShardStatusFileIsCreatedWithListTests(self): + """Tests that the shard file is created with the "list_tests" flag.""" + + shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), + 'shard_status_file2') + self.assert_(not os.path.exists(shard_status_file)) + + extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} + try: + output = InvokeWithModifiedEnv(extra_env, + RunAndReturnOutput, + [LIST_TESTS_FLAG]) + finally: + # This assertion ensures that Google Test enumerated the tests as + # opposed to running them. + self.assert_('[==========]' not in output, + 'Unexpected output during test enumeration.\n' + 'Please ensure that LIST_TESTS_FLAG is assigned the\n' + 'correct flag value for listing Google Test tests.') + + self.assert_(os.path.exists(shard_status_file)) + os.remove(shard_status_file) + + if SUPPORTS_DEATH_TESTS: + def testShardingWorksWithDeathTests(self): + """Tests integration with death tests and sharding.""" + + gtest_filter = 'HasDeathTest.*:SeqP/*' + expected_tests = [ + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', + + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + ] + + for flag in ['--gtest_death_test_style=threadsafe', + '--gtest_death_test_style=fast']: + self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests, + check_exit_0=True, args=[flag]) + self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests, + check_exit_0=True, args=[flag]) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_filter_unittest_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_filter_unittest_.cc new file mode 100644 index 0000000..77deffc --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_filter_unittest_.cc @@ -0,0 +1,140 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Unit test for Google Test test filters. +// +// A user can specify which test(s) in a Google Test program to run via +// either the GTEST_FILTER environment variable or the --gtest_filter +// flag. This is used for testing such functionality. +// +// The program will be invoked from a Python unit test. Don't run it +// directly. + +#include "gtest/gtest.h" + +namespace { + +// Test case FooTest. + +class FooTest : public testing::Test { +}; + +TEST_F(FooTest, Abc) { +} + +TEST_F(FooTest, Xyz) { + FAIL() << "Expected failure."; +} + +// Test case BarTest. + +TEST(BarTest, TestOne) { +} + +TEST(BarTest, TestTwo) { +} + +TEST(BarTest, TestThree) { +} + +TEST(BarTest, DISABLED_TestFour) { + FAIL() << "Expected failure."; +} + +TEST(BarTest, DISABLED_TestFive) { + FAIL() << "Expected failure."; +} + +// Test case BazTest. + +TEST(BazTest, TestOne) { + FAIL() << "Expected failure."; +} + +TEST(BazTest, TestA) { +} + +TEST(BazTest, TestB) { +} + +TEST(BazTest, DISABLED_TestC) { + FAIL() << "Expected failure."; +} + +// Test case HasDeathTest + +TEST(HasDeathTest, Test1) { + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); +} + +// We need at least two death tests to make sure that the all death tests +// aren't on the first shard. +TEST(HasDeathTest, Test2) { + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); +} + +// Test case FoobarTest + +TEST(DISABLED_FoobarTest, Test1) { + FAIL() << "Expected failure."; +} + +TEST(DISABLED_FoobarTest, DISABLED_Test2) { + FAIL() << "Expected failure."; +} + +// Test case FoobarbazTest + +TEST(DISABLED_FoobarbazTest, TestA) { + FAIL() << "Expected failure."; +} + +#if GTEST_HAS_PARAM_TEST +class ParamTest : public testing::TestWithParam { +}; + +TEST_P(ParamTest, TestX) { +} + +TEST_P(ParamTest, TestY) { +} + +INSTANTIATE_TEST_CASE_P(SeqP, ParamTest, testing::Values(1, 2)); +INSTANTIATE_TEST_CASE_P(SeqQ, ParamTest, testing::Values(5, 6)); +#endif // GTEST_HAS_PARAM_TEST + +} // namespace + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_help_test.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_help_test.py new file mode 100755 index 0000000..093c838 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_help_test.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# 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. + +"""Tests the --help flag of Google C++ Testing Framework. + +SYNOPSIS + gtest_help_test.py --build_dir=BUILD/DIR + # where BUILD/DIR contains the built gtest_help_test_ file. + gtest_help_test.py +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import gtest_test_utils + + +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' +IS_WINDOWS = os.name == 'nt' + +PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_') +FLAG_PREFIX = '--gtest_' +DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style' +STREAM_RESULT_TO_FLAG = FLAG_PREFIX + 'stream_result_to' +UNKNOWN_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing' +LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' +INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', LIST_TESTS_FLAG), + re.sub('^--', '/', LIST_TESTS_FLAG), + re.sub('_', '-', LIST_TESTS_FLAG)] +INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing' + +SUPPORTS_DEATH_TESTS = "DeathTest" in gtest_test_utils.Subprocess( + [PROGRAM_PATH, LIST_TESTS_FLAG]).output + +# The help message must match this regex. +HELP_REGEX = re.compile( + FLAG_PREFIX + r'list_tests.*' + + FLAG_PREFIX + r'filter=.*' + + FLAG_PREFIX + r'also_run_disabled_tests.*' + + FLAG_PREFIX + r'repeat=.*' + + FLAG_PREFIX + r'shuffle.*' + + FLAG_PREFIX + r'random_seed=.*' + + FLAG_PREFIX + r'color=.*' + + FLAG_PREFIX + r'print_time.*' + + FLAG_PREFIX + r'output=.*' + + FLAG_PREFIX + r'break_on_failure.*' + + FLAG_PREFIX + r'throw_on_failure.*' + + FLAG_PREFIX + r'catch_exceptions=0.*', + re.DOTALL) + + +def RunWithFlag(flag): + """Runs gtest_help_test_ with the given flag. + + Returns: + the exit code and the text output as a tuple. + Args: + flag: the command-line flag to pass to gtest_help_test_, or None. + """ + + if flag is None: + command = [PROGRAM_PATH] + else: + command = [PROGRAM_PATH, flag] + child = gtest_test_utils.Subprocess(command) + return child.exit_code, child.output + + +class GTestHelpTest(gtest_test_utils.TestCase): + """Tests the --help flag and its equivalent forms.""" + + def TestHelpFlag(self, flag): + """Verifies correct behavior when help flag is specified. + + The right message must be printed and the tests must + skipped when the given flag is specified. + + Args: + flag: A flag to pass to the binary or None. + """ + + exit_code, output = RunWithFlag(flag) + self.assertEquals(0, exit_code) + self.assert_(HELP_REGEX.search(output), output) + + if IS_LINUX: + self.assert_(STREAM_RESULT_TO_FLAG in output, output) + else: + self.assert_(STREAM_RESULT_TO_FLAG not in output, output) + + if SUPPORTS_DEATH_TESTS and not IS_WINDOWS: + self.assert_(DEATH_TEST_STYLE_FLAG in output, output) + else: + self.assert_(DEATH_TEST_STYLE_FLAG not in output, output) + + def TestNonHelpFlag(self, flag): + """Verifies correct behavior when no help flag is specified. + + Verifies that when no help flag is specified, the tests are run + and the help message is not printed. + + Args: + flag: A flag to pass to the binary or None. + """ + + exit_code, output = RunWithFlag(flag) + self.assert_(exit_code != 0) + self.assert_(not HELP_REGEX.search(output), output) + + def testPrintsHelpWithFullFlag(self): + self.TestHelpFlag('--help') + + def testPrintsHelpWithShortFlag(self): + self.TestHelpFlag('-h') + + def testPrintsHelpWithQuestionFlag(self): + self.TestHelpFlag('-?') + + def testPrintsHelpWithWindowsStyleQuestionFlag(self): + self.TestHelpFlag('/?') + + def testPrintsHelpWithUnrecognizedGoogleTestFlag(self): + self.TestHelpFlag(UNKNOWN_FLAG) + + def testPrintsHelpWithIncorrectFlagStyle(self): + for incorrect_flag in INCORRECT_FLAG_VARIANTS: + self.TestHelpFlag(incorrect_flag) + + def testRunsTestsWithoutHelpFlag(self): + """Verifies that when no help flag is specified, the tests are run + and the help message is not printed.""" + + self.TestNonHelpFlag(None) + + def testRunsTestsWithGtestInternalFlag(self): + """Verifies that the tests are run and no help message is printed when + a flag starting with Google Test prefix and 'internal_' is supplied.""" + + self.TestNonHelpFlag(INTERNAL_FLAG_FOR_TESTING) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_help_test_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_help_test_.cc new file mode 100644 index 0000000..31f78c2 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_help_test_.cc @@ -0,0 +1,46 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// This program is meant to be run by gtest_help_test.py. Do not run +// it directly. + +#include "gtest/gtest.h" + +// When a help flag is specified, this program should skip the tests +// and exit with 0; otherwise the following test will be executed, +// causing this program to exit with a non-zero code. +TEST(HelpFlagTest, ShouldNotBeRun) { + ASSERT_TRUE(false) << "Tests shouldn't be run when --help is specified."; +} + +#if GTEST_HAS_DEATH_TEST +TEST(DeathTest, UsedByPythonScriptToDetectSupportForDeathTestsInThisBinary) {} +#endif diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_list_tests_unittest.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_list_tests_unittest.py new file mode 100755 index 0000000..ce8c3ef --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_list_tests_unittest.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test for Google Test's --gtest_list_tests flag. + +A user can ask Google Test to list all tests by specifying the +--gtest_list_tests flag. This script tests such functionality +by invoking gtest_list_tests_unittest_ (a program written with +Google Test) the command line flags. +""" + +__author__ = 'phanna@google.com (Patrick Hanna)' + +import gtest_test_utils + + +# Constants. + +# The command line flag for enabling/disabling listing all tests. +LIST_TESTS_FLAG = 'gtest_list_tests' + +# Path to the gtest_list_tests_unittest_ program. +EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_') + +# The expected output when running gtest_list_tests_unittest_ with +# --gtest_list_tests +EXPECTED_OUTPUT_NO_FILTER = """FooDeathTest. + Test1 +Foo. + Bar1 + Bar2 + DISABLED_Bar3 +Abc. + Xyz + Def +FooBar. + Baz +FooTest. + Test1 + DISABLED_Test2 + Test3 +""" + +# The expected output when running gtest_list_tests_unittest_ with +# --gtest_list_tests and --gtest_filter=Foo*. +EXPECTED_OUTPUT_FILTER_FOO = """FooDeathTest. + Test1 +Foo. + Bar1 + Bar2 + DISABLED_Bar3 +FooBar. + Baz +FooTest. + Test1 + DISABLED_Test2 + Test3 +""" + +# Utilities. + + +def Run(args): + """Runs gtest_list_tests_unittest_ and returns the list of tests printed.""" + + return gtest_test_utils.Subprocess([EXE_PATH] + args, + capture_stderr=False).output + + +# The unit test. + +class GTestListTestsUnitTest(gtest_test_utils.TestCase): + """Tests using the --gtest_list_tests flag to list all tests.""" + + def RunAndVerify(self, flag_value, expected_output, other_flag): + """Runs gtest_list_tests_unittest_ and verifies that it prints + the correct tests. + + Args: + flag_value: value of the --gtest_list_tests flag; + None if the flag should not be present. + + expected_output: the expected output after running command; + + other_flag: a different flag to be passed to command + along with gtest_list_tests; + None if the flag should not be present. + """ + + if flag_value is None: + flag = '' + flag_expression = 'not set' + elif flag_value == '0': + flag = '--%s=0' % LIST_TESTS_FLAG + flag_expression = '0' + else: + flag = '--%s' % LIST_TESTS_FLAG + flag_expression = '1' + + args = [flag] + + if other_flag is not None: + args += [other_flag] + + output = Run(args) + + msg = ('when %s is %s, the output of "%s" is "%s".' % + (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output)) + + if expected_output is not None: + self.assert_(output == expected_output, msg) + else: + self.assert_(output != EXPECTED_OUTPUT_NO_FILTER, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(flag_value=None, + expected_output=None, + other_flag=None) + + def testFlag(self): + """Tests using the --gtest_list_tests flag.""" + + self.RunAndVerify(flag_value='0', + expected_output=None, + other_flag=None) + self.RunAndVerify(flag_value='1', + expected_output=EXPECTED_OUTPUT_NO_FILTER, + other_flag=None) + + def testOverrideNonFilterFlags(self): + """Tests that --gtest_list_tests overrides the non-filter flags.""" + + self.RunAndVerify(flag_value='1', + expected_output=EXPECTED_OUTPUT_NO_FILTER, + other_flag='--gtest_break_on_failure') + + def testWithFilterFlags(self): + """Tests that --gtest_list_tests takes into account the + --gtest_filter flag.""" + + self.RunAndVerify(flag_value='1', + expected_output=EXPECTED_OUTPUT_FILTER_FOO, + other_flag='--gtest_filter=Foo*') + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_list_tests_unittest_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_list_tests_unittest_.cc new file mode 100644 index 0000000..2b1d078 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_list_tests_unittest_.cc @@ -0,0 +1,85 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: phanna@google.com (Patrick Hanna) + +// Unit test for Google Test's --gtest_list_tests flag. +// +// A user can ask Google Test to list all tests that will run +// so that when using a filter, a user will know what +// tests to look for. The tests will not be run after listing. +// +// This program will be invoked from a Python unit test. +// Don't run it directly. + +#include "gtest/gtest.h" + +namespace { + +// Several different test cases and tests that will be listed. +TEST(Foo, Bar1) { +} + +TEST(Foo, Bar2) { +} + +TEST(Foo, DISABLED_Bar3) { +} + +TEST(Abc, Xyz) { +} + +TEST(Abc, Def) { +} + +TEST(FooBar, Baz) { +} + +class FooTest : public testing::Test { +}; + +TEST_F(FooTest, Test1) { +} + +TEST_F(FooTest, DISABLED_Test2) { +} + +TEST_F(FooTest, Test3) { +} + +TEST(FooDeathTest, Test1) { +} + +} // namespace + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_main_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_main_unittest.cc new file mode 100644 index 0000000..ecd9bb8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_main_unittest.cc @@ -0,0 +1,45 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest.h" + +// Tests that we don't have to define main() when we link to +// gtest_main instead of gtest. + +namespace { + +TEST(GTestMainTest, ShouldSucceed) { +} + +} // namespace + +// We are using the main() function defined in src/gtest_main.cc, so +// we don't define it here. diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_no_test_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_no_test_unittest.cc new file mode 100644 index 0000000..292599a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_no_test_unittest.cc @@ -0,0 +1,56 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +// Tests that a Google Test program that has no test defined can run +// successfully. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest.h" + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + // An ad-hoc assertion outside of all tests. + // + // This serves three purposes: + // + // 1. It verifies that an ad-hoc assertion can be executed even if + // no test is defined. + // 2. It verifies that a failed ad-hoc assertion causes the test + // program to fail. + // 3. We had a bug where the XML output won't be generated if an + // assertion is executed before RUN_ALL_TESTS() is called, even + // though --gtest_output=xml is specified. This makes sure the + // bug is fixed and doesn't regress. + EXPECT_EQ(1, 2); + + // The above EXPECT_EQ() should cause RUN_ALL_TESTS() to return non-zero. + return RUN_ALL_TESTS() ? 0 : 1; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test.py new file mode 100755 index 0000000..f409e2a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test.py @@ -0,0 +1,335 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""Tests the text output of Google C++ Testing Framework. + +SYNOPSIS + gtest_output_test.py --build_dir=BUILD/DIR --gengolden + # where BUILD/DIR contains the built gtest_output_test_ file. + gtest_output_test.py --gengolden + gtest_output_test.py +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sys +import gtest_test_utils + + +# The flag for generating the golden file +GENGOLDEN_FLAG = '--gengolden' +CATCH_EXCEPTIONS_ENV_VAR_NAME = 'GTEST_CATCH_EXCEPTIONS' + +IS_WINDOWS = os.name == 'nt' + +# TODO(vladl@google.com): remove the _lin suffix. +GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' + +PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_') + +# At least one command we exercise must not have the +# --gtest_internal_skip_environment_and_ad_hoc_tests flag. +COMMAND_LIST_TESTS = ({}, [PROGRAM_PATH, '--gtest_list_tests']) +COMMAND_WITH_COLOR = ({}, [PROGRAM_PATH, '--gtest_color=yes']) +COMMAND_WITH_TIME = ({}, [PROGRAM_PATH, + '--gtest_print_time', + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=FatalFailureTest.*:LoggingTest.*']) +COMMAND_WITH_DISABLED = ( + {}, [PROGRAM_PATH, + '--gtest_also_run_disabled_tests', + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=*DISABLED_*']) +COMMAND_WITH_SHARDING = ( + {'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'}, + [PROGRAM_PATH, + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=PassingTest.*']) + +GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) + + +def ToUnixLineEnding(s): + """Changes all Windows/Mac line endings in s to UNIX line endings.""" + + return s.replace('\r\n', '\n').replace('\r', '\n') + + +def RemoveLocations(test_output): + """Removes all file location info from a Google Test program's output. + + Args: + test_output: the output of a Google Test program. + + Returns: + output with all file location info (in the form of + 'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or + 'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by + 'FILE_NAME:#: '. + """ + + return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', test_output) + + +def RemoveStackTraceDetails(output): + """Removes all stack traces from a Google Test program's output.""" + + # *? means "find the shortest string that matches". + return re.sub(r'Stack trace:(.|\n)*?\n\n', + 'Stack trace: (omitted)\n\n', output) + + +def RemoveStackTraces(output): + """Removes all traces of stack traces from a Google Test program's output.""" + + # *? means "find the shortest string that matches". + return re.sub(r'Stack trace:(.|\n)*?\n\n', '', output) + + +def RemoveTime(output): + """Removes all time information from a Google Test program's output.""" + + return re.sub(r'\(\d+ ms', '(? ms', output) + + +def RemoveTypeInfoDetails(test_output): + """Removes compiler-specific type info from Google Test program's output. + + Args: + test_output: the output of a Google Test program. + + Returns: + output with type information normalized to canonical form. + """ + + # some compilers output the name of type 'unsigned int' as 'unsigned' + return re.sub(r'unsigned int', 'unsigned', test_output) + + +def NormalizeToCurrentPlatform(test_output): + """Normalizes platform specific output details for easier comparison.""" + + if IS_WINDOWS: + # Removes the color information that is not present on Windows. + test_output = re.sub('\x1b\\[(0;3\d)?m', '', test_output) + # Changes failure message headers into the Windows format. + test_output = re.sub(r': Failure\n', r': error: ', test_output) + # Changes file(line_number) to file:line_number. + test_output = re.sub(r'((\w|\.)+)\((\d+)\):', r'\1:\3:', test_output) + + return test_output + + +def RemoveTestCounts(output): + """Removes test counts from a Google Test program's output.""" + + output = re.sub(r'\d+ tests?, listed below', + '? tests, listed below', output) + output = re.sub(r'\d+ FAILED TESTS', + '? FAILED TESTS', output) + output = re.sub(r'\d+ tests? from \d+ test cases?', + '? tests from ? test cases', output) + output = re.sub(r'\d+ tests? from ([a-zA-Z_])', + r'? tests from \1', output) + return re.sub(r'\d+ tests?\.', '? tests.', output) + + +def RemoveMatchingTests(test_output, pattern): + """Removes output of specified tests from a Google Test program's output. + + This function strips not only the beginning and the end of a test but also + all output in between. + + Args: + test_output: A string containing the test output. + pattern: A regex string that matches names of test cases or + tests to remove. + + Returns: + Contents of test_output with tests whose names match pattern removed. + """ + + test_output = re.sub( + r'.*\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % ( + pattern, pattern), + '', + test_output) + return re.sub(r'.*%s.*\n' % pattern, '', test_output) + + +def NormalizeOutput(output): + """Normalizes output (the output of gtest_output_test_.exe).""" + + output = ToUnixLineEnding(output) + output = RemoveLocations(output) + output = RemoveStackTraceDetails(output) + output = RemoveTime(output) + return output + + +def GetShellCommandOutput(env_cmd): + """Runs a command in a sub-process, and returns its output in a string. + + Args: + env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra + environment variables to set, and element 1 is a string with + the command and any flags. + + Returns: + A string with the command's combined standard and diagnostic output. + """ + + # Spawns cmd in a sub-process, and gets its standard I/O file objects. + # Set and save the environment properly. + environ = os.environ.copy() + environ.update(env_cmd[0]) + p = gtest_test_utils.Subprocess(env_cmd[1], env=environ) + + return p.output + + +def GetCommandOutput(env_cmd): + """Runs a command and returns its output with all file location + info stripped off. + + Args: + env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra + environment variables to set, and element 1 is a string with + the command and any flags. + """ + + # Disables exception pop-ups on Windows. + environ, cmdline = env_cmd + environ = dict(environ) # Ensures we are modifying a copy. + environ[CATCH_EXCEPTIONS_ENV_VAR_NAME] = '1' + return NormalizeOutput(GetShellCommandOutput((environ, cmdline))) + + +def GetOutputOfAllCommands(): + """Returns concatenated output from several representative commands.""" + + return (GetCommandOutput(COMMAND_WITH_COLOR) + + GetCommandOutput(COMMAND_WITH_TIME) + + GetCommandOutput(COMMAND_WITH_DISABLED) + + GetCommandOutput(COMMAND_WITH_SHARDING)) + + +test_list = GetShellCommandOutput(COMMAND_LIST_TESTS) +SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list +SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list +SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list +SUPPORTS_STACK_TRACES = False + +CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and + SUPPORTS_TYPED_TESTS and + SUPPORTS_THREADS) + + +class GTestOutputTest(gtest_test_utils.TestCase): + def RemoveUnsupportedTests(self, test_output): + if not SUPPORTS_DEATH_TESTS: + test_output = RemoveMatchingTests(test_output, 'DeathTest') + if not SUPPORTS_TYPED_TESTS: + test_output = RemoveMatchingTests(test_output, 'TypedTest') + test_output = RemoveMatchingTests(test_output, 'TypedDeathTest') + test_output = RemoveMatchingTests(test_output, 'TypeParamDeathTest') + if not SUPPORTS_THREADS: + test_output = RemoveMatchingTests(test_output, + 'ExpectFailureWithThreadsTest') + test_output = RemoveMatchingTests(test_output, + 'ScopedFakeTestPartResultReporterTest') + test_output = RemoveMatchingTests(test_output, + 'WorksConcurrently') + if not SUPPORTS_STACK_TRACES: + test_output = RemoveStackTraces(test_output) + + return test_output + + def testOutput(self): + output = GetOutputOfAllCommands() + + golden_file = open(GOLDEN_PATH, 'rb') + # A mis-configured source control system can cause \r appear in EOL + # sequences when we read the golden file irrespective of an operating + # system used. Therefore, we need to strip those \r's from newlines + # unconditionally. + golden = ToUnixLineEnding(golden_file.read()) + golden_file.close() + + # We want the test to pass regardless of certain features being + # supported or not. + + # We still have to remove type name specifics in all cases. + normalized_actual = RemoveTypeInfoDetails(output) + normalized_golden = RemoveTypeInfoDetails(golden) + + if CAN_GENERATE_GOLDEN_FILE: + self.assertEqual(normalized_golden, normalized_actual) + else: + normalized_actual = NormalizeToCurrentPlatform( + RemoveTestCounts(normalized_actual)) + normalized_golden = NormalizeToCurrentPlatform( + RemoveTestCounts(self.RemoveUnsupportedTests(normalized_golden))) + + # This code is very handy when debugging golden file differences: + if os.getenv('DEBUG_GTEST_OUTPUT_TEST'): + open(os.path.join( + gtest_test_utils.GetSourceDir(), + '_gtest_output_test_normalized_actual.txt'), 'wb').write( + normalized_actual) + open(os.path.join( + gtest_test_utils.GetSourceDir(), + '_gtest_output_test_normalized_golden.txt'), 'wb').write( + normalized_golden) + + self.assertEqual(normalized_golden, normalized_actual) + + +if __name__ == '__main__': + if sys.argv[1:] == [GENGOLDEN_FLAG]: + if CAN_GENERATE_GOLDEN_FILE: + output = GetOutputOfAllCommands() + golden_file = open(GOLDEN_PATH, 'wb') + golden_file.write(output) + golden_file.close() + else: + message = ( + """Unable to write a golden file when compiled in an environment +that does not support all the required features (death tests, typed tests, +and multiple threads). Please generate the golden file using a binary built +with those features enabled.""") + + sys.stderr.write(message) + sys.exit(1) + else: + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test_.cc new file mode 100644 index 0000000..07ab633 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test_.cc @@ -0,0 +1,1034 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// The purpose of this file is to generate Google Test output under +// various conditions. The output will then be verified by +// gtest_output_test.py to ensure that Google Test generates the +// desired messages. Therefore, most tests in this file are MEANT TO +// FAIL. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#include + +#if GTEST_IS_THREADSAFE +using testing::ScopedFakeTestPartResultReporter; +using testing::TestPartResultArray; + +using testing::internal::Notification; +using testing::internal::ThreadWithParam; +#endif + +namespace posix = ::testing::internal::posix; +using testing::internal::scoped_ptr; + +// Tests catching fatal failures. + +// A subroutine used by the following test. +void TestEq1(int x) { + ASSERT_EQ(1, x); +} + +// This function calls a test subroutine, catches the fatal failure it +// generates, and then returns early. +void TryTestSubroutine() { + // Calls a subrountine that yields a fatal failure. + TestEq1(2); + + // Catches the fatal failure and aborts the test. + // + // The testing::Test:: prefix is necessary when calling + // HasFatalFailure() outside of a TEST, TEST_F, or test fixture. + if (testing::Test::HasFatalFailure()) return; + + // If we get here, something is wrong. + FAIL() << "This should never be reached."; +} + +TEST(PassingTest, PassingTest1) { +} + +TEST(PassingTest, PassingTest2) { +} + +// Tests that parameters of failing parameterized tests are printed in the +// failing test summary. +class FailingParamTest : public testing::TestWithParam {}; + +TEST_P(FailingParamTest, Fails) { + EXPECT_EQ(1, GetParam()); +} + +// This generates a test which will fail. Google Test is expected to print +// its parameter when it outputs the list of all failed tests. +INSTANTIATE_TEST_CASE_P(PrintingFailingParams, + FailingParamTest, + testing::Values(2)); + +static const char kGoldenString[] = "\"Line\0 1\"\nLine 2"; + +TEST(NonfatalFailureTest, EscapesStringOperands) { + std::string actual = "actual \"string\""; + EXPECT_EQ(kGoldenString, actual); + + const char* golden = kGoldenString; + EXPECT_EQ(golden, actual); +} + +// Tests catching a fatal failure in a subroutine. +TEST(FatalFailureTest, FatalFailureInSubroutine) { + printf("(expecting a failure that x should be 1)\n"); + + TryTestSubroutine(); +} + +// Tests catching a fatal failure in a nested subroutine. +TEST(FatalFailureTest, FatalFailureInNestedSubroutine) { + printf("(expecting a failure that x should be 1)\n"); + + // Calls a subrountine that yields a fatal failure. + TryTestSubroutine(); + + // Catches the fatal failure and aborts the test. + // + // When calling HasFatalFailure() inside a TEST, TEST_F, or test + // fixture, the testing::Test:: prefix is not needed. + if (HasFatalFailure()) return; + + // If we get here, something is wrong. + FAIL() << "This should never be reached."; +} + +// Tests HasFatalFailure() after a failed EXPECT check. +TEST(FatalFailureTest, NonfatalFailureInSubroutine) { + printf("(expecting a failure on false)\n"); + EXPECT_TRUE(false); // Generates a nonfatal failure + ASSERT_FALSE(HasFatalFailure()); // This should succeed. +} + +// Tests interleaving user logging and Google Test assertions. +TEST(LoggingTest, InterleavingLoggingAndAssertions) { + static const int a[4] = { + 3, 9, 2, 6 + }; + + printf("(expecting 2 failures on (3) >= (a[i]))\n"); + for (int i = 0; i < static_cast(sizeof(a)/sizeof(*a)); i++) { + printf("i == %d\n", i); + EXPECT_GE(3, a[i]); + } +} + +// Tests the SCOPED_TRACE macro. + +// A helper function for testing SCOPED_TRACE. +void SubWithoutTrace(int n) { + EXPECT_EQ(1, n); + ASSERT_EQ(2, n); +} + +// Another helper function for testing SCOPED_TRACE. +void SubWithTrace(int n) { + SCOPED_TRACE(testing::Message() << "n = " << n); + + SubWithoutTrace(n); +} + +// Tests that SCOPED_TRACE() obeys lexical scopes. +TEST(SCOPED_TRACETest, ObeysScopes) { + printf("(expected to fail)\n"); + + // There should be no trace before SCOPED_TRACE() is invoked. + ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; + + { + SCOPED_TRACE("Expected trace"); + // After SCOPED_TRACE(), a failure in the current scope should contain + // the trace. + ADD_FAILURE() << "This failure is expected, and should have a trace."; + } + + // Once the control leaves the scope of the SCOPED_TRACE(), there + // should be no trace again. + ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; +} + +// Tests that SCOPED_TRACE works inside a loop. +TEST(SCOPED_TRACETest, WorksInLoop) { + printf("(expected to fail)\n"); + + for (int i = 1; i <= 2; i++) { + SCOPED_TRACE(testing::Message() << "i = " << i); + + SubWithoutTrace(i); + } +} + +// Tests that SCOPED_TRACE works in a subroutine. +TEST(SCOPED_TRACETest, WorksInSubroutine) { + printf("(expected to fail)\n"); + + SubWithTrace(1); + SubWithTrace(2); +} + +// Tests that SCOPED_TRACE can be nested. +TEST(SCOPED_TRACETest, CanBeNested) { + printf("(expected to fail)\n"); + + SCOPED_TRACE(""); // A trace without a message. + + SubWithTrace(2); +} + +// Tests that multiple SCOPED_TRACEs can be used in the same scope. +TEST(SCOPED_TRACETest, CanBeRepeated) { + printf("(expected to fail)\n"); + + SCOPED_TRACE("A"); + ADD_FAILURE() + << "This failure is expected, and should contain trace point A."; + + SCOPED_TRACE("B"); + ADD_FAILURE() + << "This failure is expected, and should contain trace point A and B."; + + { + SCOPED_TRACE("C"); + ADD_FAILURE() << "This failure is expected, and should " + << "contain trace point A, B, and C."; + } + + SCOPED_TRACE("D"); + ADD_FAILURE() << "This failure is expected, and should " + << "contain trace point A, B, and D."; +} + +#if GTEST_IS_THREADSAFE +// Tests that SCOPED_TRACE()s can be used concurrently from multiple +// threads. Namely, an assertion should be affected by +// SCOPED_TRACE()s in its own thread only. + +// Here's the sequence of actions that happen in the test: +// +// Thread A (main) | Thread B (spawned) +// ===============================|================================ +// spawns thread B | +// -------------------------------+-------------------------------- +// waits for n1 | SCOPED_TRACE("Trace B"); +// | generates failure #1 +// | notifies n1 +// -------------------------------+-------------------------------- +// SCOPED_TRACE("Trace A"); | waits for n2 +// generates failure #2 | +// notifies n2 | +// -------------------------------|-------------------------------- +// waits for n3 | generates failure #3 +// | trace B dies +// | generates failure #4 +// | notifies n3 +// -------------------------------|-------------------------------- +// generates failure #5 | finishes +// trace A dies | +// generates failure #6 | +// -------------------------------|-------------------------------- +// waits for thread B to finish | + +struct CheckPoints { + Notification n1; + Notification n2; + Notification n3; +}; + +static void ThreadWithScopedTrace(CheckPoints* check_points) { + { + SCOPED_TRACE("Trace B"); + ADD_FAILURE() + << "Expected failure #1 (in thread B, only trace B alive)."; + check_points->n1.Notify(); + check_points->n2.WaitForNotification(); + + ADD_FAILURE() + << "Expected failure #3 (in thread B, trace A & B both alive)."; + } // Trace B dies here. + ADD_FAILURE() + << "Expected failure #4 (in thread B, only trace A alive)."; + check_points->n3.Notify(); +} + +TEST(SCOPED_TRACETest, WorksConcurrently) { + printf("(expecting 6 failures)\n"); + + CheckPoints check_points; + ThreadWithParam thread(&ThreadWithScopedTrace, + &check_points, + NULL); + check_points.n1.WaitForNotification(); + + { + SCOPED_TRACE("Trace A"); + ADD_FAILURE() + << "Expected failure #2 (in thread A, trace A & B both alive)."; + check_points.n2.Notify(); + check_points.n3.WaitForNotification(); + + ADD_FAILURE() + << "Expected failure #5 (in thread A, only trace A alive)."; + } // Trace A dies here. + ADD_FAILURE() + << "Expected failure #6 (in thread A, no trace alive)."; + thread.Join(); +} +#endif // GTEST_IS_THREADSAFE + +TEST(DisabledTestsWarningTest, + DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning) { + // This test body is intentionally empty. Its sole purpose is for + // verifying that the --gtest_also_run_disabled_tests flag + // suppresses the "YOU HAVE 12 DISABLED TESTS" warning at the end of + // the test output. +} + +// Tests using assertions outside of TEST and TEST_F. +// +// This function creates two failures intentionally. +void AdHocTest() { + printf("The non-test part of the code is expected to have 2 failures.\n\n"); + EXPECT_TRUE(false); + EXPECT_EQ(2, 3); +} + +// Runs all TESTs, all TEST_Fs, and the ad hoc test. +int RunAllTests() { + AdHocTest(); + return RUN_ALL_TESTS(); +} + +// Tests non-fatal failures in the fixture constructor. +class NonFatalFailureInFixtureConstructorTest : public testing::Test { + protected: + NonFatalFailureInFixtureConstructorTest() { + printf("(expecting 5 failures)\n"); + ADD_FAILURE() << "Expected failure #1, in the test fixture c'tor."; + } + + ~NonFatalFailureInFixtureConstructorTest() { + ADD_FAILURE() << "Expected failure #5, in the test fixture d'tor."; + } + + virtual void SetUp() { + ADD_FAILURE() << "Expected failure #2, in SetUp()."; + } + + virtual void TearDown() { + ADD_FAILURE() << "Expected failure #4, in TearDown."; + } +}; + +TEST_F(NonFatalFailureInFixtureConstructorTest, FailureInConstructor) { + ADD_FAILURE() << "Expected failure #3, in the test body."; +} + +// Tests fatal failures in the fixture constructor. +class FatalFailureInFixtureConstructorTest : public testing::Test { + protected: + FatalFailureInFixtureConstructorTest() { + printf("(expecting 2 failures)\n"); + Init(); + } + + ~FatalFailureInFixtureConstructorTest() { + ADD_FAILURE() << "Expected failure #2, in the test fixture d'tor."; + } + + virtual void SetUp() { + ADD_FAILURE() << "UNEXPECTED failure in SetUp(). " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; + } + + virtual void TearDown() { + ADD_FAILURE() << "UNEXPECTED failure in TearDown(). " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; + } + + private: + void Init() { + FAIL() << "Expected failure #1, in the test fixture c'tor."; + } +}; + +TEST_F(FatalFailureInFixtureConstructorTest, FailureInConstructor) { + ADD_FAILURE() << "UNEXPECTED failure in the test body. " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; +} + +// Tests non-fatal failures in SetUp(). +class NonFatalFailureInSetUpTest : public testing::Test { + protected: + virtual ~NonFatalFailureInSetUpTest() { + Deinit(); + } + + virtual void SetUp() { + printf("(expecting 4 failures)\n"); + ADD_FAILURE() << "Expected failure #1, in SetUp()."; + } + + virtual void TearDown() { + FAIL() << "Expected failure #3, in TearDown()."; + } + private: + void Deinit() { + FAIL() << "Expected failure #4, in the test fixture d'tor."; + } +}; + +TEST_F(NonFatalFailureInSetUpTest, FailureInSetUp) { + FAIL() << "Expected failure #2, in the test function."; +} + +// Tests fatal failures in SetUp(). +class FatalFailureInSetUpTest : public testing::Test { + protected: + virtual ~FatalFailureInSetUpTest() { + Deinit(); + } + + virtual void SetUp() { + printf("(expecting 3 failures)\n"); + FAIL() << "Expected failure #1, in SetUp()."; + } + + virtual void TearDown() { + FAIL() << "Expected failure #2, in TearDown()."; + } + private: + void Deinit() { + FAIL() << "Expected failure #3, in the test fixture d'tor."; + } +}; + +TEST_F(FatalFailureInSetUpTest, FailureInSetUp) { + FAIL() << "UNEXPECTED failure in the test function. " + << "We should never get here, as SetUp() failed."; +} + +TEST(AddFailureAtTest, MessageContainsSpecifiedFileAndLineNumber) { + ADD_FAILURE_AT("foo.cc", 42) << "Expected failure in foo.cc"; +} + +#if GTEST_IS_THREADSAFE + +// A unary function that may die. +void DieIf(bool should_die) { + GTEST_CHECK_(!should_die) << " - death inside DieIf()."; +} + +// Tests running death tests in a multi-threaded context. + +// Used for coordination between the main and the spawn thread. +struct SpawnThreadNotifications { + SpawnThreadNotifications() {} + + Notification spawn_thread_started; + Notification spawn_thread_ok_to_terminate; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications); +}; + +// The function to be executed in the thread spawn by the +// MultipleThreads test (below). +static void ThreadRoutine(SpawnThreadNotifications* notifications) { + // Signals the main thread that this thread has started. + notifications->spawn_thread_started.Notify(); + + // Waits for permission to finish from the main thread. + notifications->spawn_thread_ok_to_terminate.WaitForNotification(); +} + +// This is a death-test test, but it's not named with a DeathTest +// suffix. It starts threads which might interfere with later +// death tests, so it must run after all other death tests. +class DeathTestAndMultiThreadsTest : public testing::Test { + protected: + // Starts a thread and waits for it to begin. + virtual void SetUp() { + thread_.reset(new ThreadWithParam( + &ThreadRoutine, ¬ifications_, NULL)); + notifications_.spawn_thread_started.WaitForNotification(); + } + // Tells the thread to finish, and reaps it. + // Depending on the version of the thread library in use, + // a manager thread might still be left running that will interfere + // with later death tests. This is unfortunate, but this class + // cleans up after itself as best it can. + virtual void TearDown() { + notifications_.spawn_thread_ok_to_terminate.Notify(); + } + + private: + SpawnThreadNotifications notifications_; + scoped_ptr > thread_; +}; + +#endif // GTEST_IS_THREADSAFE + +// The MixedUpTestCaseTest test case verifies that Google Test will fail a +// test if it uses a different fixture class than what other tests in +// the same test case use. It deliberately contains two fixture +// classes with the same name but defined in different namespaces. + +// The MixedUpTestCaseWithSameTestNameTest test case verifies that +// when the user defines two tests with the same test case name AND +// same test name (but in different namespaces), the second test will +// fail. + +namespace foo { + +class MixedUpTestCaseTest : public testing::Test { +}; + +TEST_F(MixedUpTestCaseTest, FirstTestFromNamespaceFoo) {} +TEST_F(MixedUpTestCaseTest, SecondTestFromNamespaceFoo) {} + +class MixedUpTestCaseWithSameTestNameTest : public testing::Test { +}; + +TEST_F(MixedUpTestCaseWithSameTestNameTest, + TheSecondTestWithThisNameShouldFail) {} + +} // namespace foo + +namespace bar { + +class MixedUpTestCaseTest : public testing::Test { +}; + +// The following two tests are expected to fail. We rely on the +// golden file to check that Google Test generates the right error message. +TEST_F(MixedUpTestCaseTest, ThisShouldFail) {} +TEST_F(MixedUpTestCaseTest, ThisShouldFailToo) {} + +class MixedUpTestCaseWithSameTestNameTest : public testing::Test { +}; + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST_F(MixedUpTestCaseWithSameTestNameTest, + TheSecondTestWithThisNameShouldFail) {} + +} // namespace bar + +// The following two test cases verify that Google Test catches the user +// error of mixing TEST and TEST_F in the same test case. The first +// test case checks the scenario where TEST_F appears before TEST, and +// the second one checks where TEST appears before TEST_F. + +class TEST_F_before_TEST_in_same_test_case : public testing::Test { +}; + +TEST_F(TEST_F_before_TEST_in_same_test_case, DefinedUsingTEST_F) {} + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST(TEST_F_before_TEST_in_same_test_case, DefinedUsingTESTAndShouldFail) {} + +class TEST_before_TEST_F_in_same_test_case : public testing::Test { +}; + +TEST(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST) {} + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST_F(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST_FAndShouldFail) { +} + +// Used for testing EXPECT_NONFATAL_FAILURE() and EXPECT_FATAL_FAILURE(). +int global_integer = 0; + +// Tests that EXPECT_NONFATAL_FAILURE() can reference global variables. +TEST(ExpectNonfatalFailureTest, CanReferenceGlobalVariables) { + global_integer = 0; + EXPECT_NONFATAL_FAILURE({ + EXPECT_EQ(1, global_integer) << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() can reference local variables +// (static or not). +TEST(ExpectNonfatalFailureTest, CanReferenceLocalVariables) { + int m = 0; + static int n; + n = 1; + EXPECT_NONFATAL_FAILURE({ + EXPECT_EQ(m, n) << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() succeeds when there is exactly +// one non-fatal failure and no fatal failure. +TEST(ExpectNonfatalFailureTest, SucceedsWhenThereIsOneNonfatalFailure) { + EXPECT_NONFATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there is no +// non-fatal failure. +TEST(ExpectNonfatalFailureTest, FailsWhenThereIsNoNonfatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there are two +// non-fatal failures. +TEST(ExpectNonfatalFailureTest, FailsWhenThereAreTwoNonfatalFailures) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure 1."; + ADD_FAILURE() << "Expected non-fatal failure 2."; + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there is one fatal +// failure. +TEST(ExpectNonfatalFailureTest, FailsWhenThereIsOneFatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + FAIL() << "Expected fatal failure."; + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being +// tested returns. +TEST(ExpectNonfatalFailureTest, FailsWhenStatementReturns) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + return; + }, ""); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being +// tested throws. +TEST(ExpectNonfatalFailureTest, FailsWhenStatementThrows) { + printf("(expecting a failure)\n"); + try { + EXPECT_NONFATAL_FAILURE({ + throw 0; + }, ""); + } catch(int) { // NOLINT + } +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_FATAL_FAILURE() can reference global variables. +TEST(ExpectFatalFailureTest, CanReferenceGlobalVariables) { + global_integer = 0; + EXPECT_FATAL_FAILURE({ + ASSERT_EQ(1, global_integer) << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() can reference local static +// variables. +TEST(ExpectFatalFailureTest, CanReferenceLocalStaticVariables) { + static int n; + n = 1; + EXPECT_FATAL_FAILURE({ + ASSERT_EQ(0, n) << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() succeeds when there is exactly +// one fatal failure and no non-fatal failure. +TEST(ExpectFatalFailureTest, SucceedsWhenThereIsOneFatalFailure) { + EXPECT_FATAL_FAILURE({ + FAIL() << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there is no fatal +// failure. +TEST(ExpectFatalFailureTest, FailsWhenThereIsNoFatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + }, ""); +} + +// A helper for generating a fatal failure. +void FatalFailure() { + FAIL() << "Expected fatal failure."; +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there are two +// fatal failures. +TEST(ExpectFatalFailureTest, FailsWhenThereAreTwoFatalFailures) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + FatalFailure(); + FatalFailure(); + }, ""); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there is one non-fatal +// failure. +TEST(ExpectFatalFailureTest, FailsWhenThereIsOneNonfatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure."; + }, ""); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when the statement being +// tested returns. +TEST(ExpectFatalFailureTest, FailsWhenStatementReturns) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + return; + }, ""); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_FATAL_FAILURE() fails when the statement being +// tested throws. +TEST(ExpectFatalFailureTest, FailsWhenStatementThrows) { + printf("(expecting a failure)\n"); + try { + EXPECT_FATAL_FAILURE({ + throw 0; + }, ""); + } catch(int) { // NOLINT + } +} + +#endif // GTEST_HAS_EXCEPTIONS + +// This #ifdef block tests the output of typed tests. +#if GTEST_HAS_TYPED_TEST + +template +class TypedTest : public testing::Test { +}; + +TYPED_TEST_CASE(TypedTest, testing::Types); + +TYPED_TEST(TypedTest, Success) { + EXPECT_EQ(0, TypeParam()); +} + +TYPED_TEST(TypedTest, Failure) { + EXPECT_EQ(1, TypeParam()) << "Expected failure"; +} + +#endif // GTEST_HAS_TYPED_TEST + +// This #ifdef block tests the output of type-parameterized tests. +#if GTEST_HAS_TYPED_TEST_P + +template +class TypedTestP : public testing::Test { +}; + +TYPED_TEST_CASE_P(TypedTestP); + +TYPED_TEST_P(TypedTestP, Success) { + EXPECT_EQ(0U, TypeParam()); +} + +TYPED_TEST_P(TypedTestP, Failure) { + EXPECT_EQ(1U, TypeParam()) << "Expected failure"; +} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP, Success, Failure); + +typedef testing::Types UnsignedTypes; +INSTANTIATE_TYPED_TEST_CASE_P(Unsigned, TypedTestP, UnsignedTypes); + +#endif // GTEST_HAS_TYPED_TEST_P + +#if GTEST_HAS_DEATH_TEST + +// We rely on the golden file to verify that tests whose test case +// name ends with DeathTest are run first. + +TEST(ADeathTest, ShouldRunFirst) { +} + +# if GTEST_HAS_TYPED_TEST + +// We rely on the golden file to verify that typed tests whose test +// case name ends with DeathTest are run first. + +template +class ATypedDeathTest : public testing::Test { +}; + +typedef testing::Types NumericTypes; +TYPED_TEST_CASE(ATypedDeathTest, NumericTypes); + +TYPED_TEST(ATypedDeathTest, ShouldRunFirst) { +} + +# endif // GTEST_HAS_TYPED_TEST + +# if GTEST_HAS_TYPED_TEST_P + + +// We rely on the golden file to verify that type-parameterized tests +// whose test case name ends with DeathTest are run first. + +template +class ATypeParamDeathTest : public testing::Test { +}; + +TYPED_TEST_CASE_P(ATypeParamDeathTest); + +TYPED_TEST_P(ATypeParamDeathTest, ShouldRunFirst) { +} + +REGISTER_TYPED_TEST_CASE_P(ATypeParamDeathTest, ShouldRunFirst); + +INSTANTIATE_TYPED_TEST_CASE_P(My, ATypeParamDeathTest, NumericTypes); + +# endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_HAS_DEATH_TEST + +// Tests various failure conditions of +// EXPECT_{,NON}FATAL_FAILURE{,_ON_ALL_THREADS}. +class ExpectFailureTest : public testing::Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + enum FailureMode { + FATAL_FAILURE, + NONFATAL_FAILURE + }; + static void AddFailure(FailureMode failure) { + if (failure == FATAL_FAILURE) { + FAIL() << "Expected fatal failure."; + } else { + ADD_FAILURE() << "Expected non-fatal failure."; + } + } +}; + +TEST_F(ExpectFailureTest, ExpectFatalFailure) { + // Expected fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(SUCCEED(), "Expected fatal failure."); + // Expected fatal failure, but got a non-fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Expected non-fatal " + "failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Some other fatal failure " + "expected."); +} + +TEST_F(ExpectFailureTest, ExpectNonFatalFailure) { + // Expected non-fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(SUCCEED(), "Expected non-fatal failure."); + // Expected non-fatal failure, but got a fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Some other non-fatal " + "failure."); +} + +#if GTEST_IS_THREADSAFE + +class ExpectFailureWithThreadsTest : public ExpectFailureTest { + protected: + static void AddFailureInOtherThread(FailureMode failure) { + ThreadWithParam thread(&AddFailure, failure, NULL); + thread.Join(); + } +}; + +TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailure) { + // We only intercept the current thread. + printf("(expecting 2 failures)\n"); + EXPECT_FATAL_FAILURE(AddFailureInOtherThread(FATAL_FAILURE), + "Expected fatal failure."); +} + +TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailure) { + // We only intercept the current thread. + printf("(expecting 2 failures)\n"); + EXPECT_NONFATAL_FAILURE(AddFailureInOtherThread(NONFATAL_FAILURE), + "Expected non-fatal failure."); +} + +typedef ExpectFailureWithThreadsTest ScopedFakeTestPartResultReporterTest; + +// Tests that the ScopedFakeTestPartResultReporter only catches failures from +// the current thread if it is instantiated with INTERCEPT_ONLY_CURRENT_THREAD. +TEST_F(ScopedFakeTestPartResultReporterTest, InterceptOnlyCurrentThread) { + printf("(expecting 2 failures)\n"); + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, + &results); + AddFailureInOtherThread(FATAL_FAILURE); + AddFailureInOtherThread(NONFATAL_FAILURE); + } + // The two failures should not have been intercepted. + EXPECT_EQ(0, results.size()) << "This shouldn't fail."; +} + +#endif // GTEST_IS_THREADSAFE + +TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) { + // Expected fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected fatal failure."); + // Expected fatal failure, but got a non-fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Expected non-fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + "Some other fatal failure expected."); +} + +TEST_F(ExpectFailureTest, ExpectNonFatalFailureOnAllThreads) { + // Expected non-fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected non-fatal " + "failure."); + // Expected non-fatal failure, but got a fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + "Expected fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Some other non-fatal failure."); +} + + +// Two test environments for testing testing::AddGlobalTestEnvironment(). + +class FooEnvironment : public testing::Environment { + public: + virtual void SetUp() { + printf("%s", "FooEnvironment::SetUp() called.\n"); + } + + virtual void TearDown() { + printf("%s", "FooEnvironment::TearDown() called.\n"); + FAIL() << "Expected fatal failure."; + } +}; + +class BarEnvironment : public testing::Environment { + public: + virtual void SetUp() { + printf("%s", "BarEnvironment::SetUp() called.\n"); + } + + virtual void TearDown() { + printf("%s", "BarEnvironment::TearDown() called.\n"); + ADD_FAILURE() << "Expected non-fatal failure."; + } +}; + +bool GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = false; + +// The main function. +// +// The idea is to use Google Test to run all the tests we have defined (some +// of them are intended to fail), and then compare the test results +// with the "golden" file. +int main(int argc, char **argv) { + testing::GTEST_FLAG(print_time) = false; + + // We just run the tests, knowing some of them are intended to fail. + // We will use a separate Python script to compare the output of + // this program with the golden file. + + // It's hard to test InitGoogleTest() directly, as it has many + // global side effects. The following line serves as a sanity test + // for it. + testing::InitGoogleTest(&argc, argv); + if (argc >= 2 && + (std::string(argv[1]) == + "--gtest_internal_skip_environment_and_ad_hoc_tests")) + GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true; + +#if GTEST_HAS_DEATH_TEST + if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { + // Skip the usual output capturing if we're running as the child + // process of an threadsafe-style death test. +# if GTEST_OS_WINDOWS + posix::FReopen("nul:", "w", stdout); +# else + posix::FReopen("/dev/null", "w", stdout); +# endif // GTEST_OS_WINDOWS + return RUN_ALL_TESTS(); + } +#endif // GTEST_HAS_DEATH_TEST + + if (GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests)) + return RUN_ALL_TESTS(); + + // Registers two global test environments. + // The golden file verifies that they are set up in the order they + // are registered, and torn down in the reverse order. + testing::AddGlobalTestEnvironment(new FooEnvironment); + testing::AddGlobalTestEnvironment(new BarEnvironment); + + return RunAllTests(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test_golden_lin.txt b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test_golden_lin.txt new file mode 100644 index 0000000..0e26d63 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_output_test_golden_lin.txt @@ -0,0 +1,725 @@ +The non-test part of the code is expected to have 2 failures. + +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +gtest_output_test_.cc:#: Failure +Value of: 3 +Expected: 2 +[==========] Running 63 tests from 28 test cases. +[----------] Global test environment set-up. +FooEnvironment::SetUp() called. +BarEnvironment::SetUp() called. +[----------] 1 test from ADeathTest +[ RUN ] ADeathTest.ShouldRunFirst +[ OK ] ADeathTest.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/0, where TypeParam = int +[ RUN ] ATypedDeathTest/0.ShouldRunFirst +[ OK ] ATypedDeathTest/0.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/1, where TypeParam = double +[ RUN ] ATypedDeathTest/1.ShouldRunFirst +[ OK ] ATypedDeathTest/1.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int +[ RUN ] My/ATypeParamDeathTest/0.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/0.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double +[ RUN ] My/ATypeParamDeathTest/1.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/1.ShouldRunFirst +[----------] 2 tests from PassingTest +[ RUN ] PassingTest.PassingTest1 +[ OK ] PassingTest.PassingTest1 +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 +[----------] 1 test from NonfatalFailureTest +[ RUN ] NonfatalFailureTest.EscapesStringOperands +gtest_output_test_.cc:#: Failure +Value of: actual + Actual: "actual \"string\"" +Expected: kGoldenString +Which is: "\"Line" +gtest_output_test_.cc:#: Failure +Value of: actual + Actual: "actual \"string\"" +Expected: golden +Which is: "\"Line" +[ FAILED ] NonfatalFailureTest.EscapesStringOperands +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 9 +i == 2 +i == 3 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 6 +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[----------] 6 tests from SCOPED_TRACETest +[ RUN ] SCOPED_TRACETest.ObeysScopes +(expected to fail) +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should have a trace. +Google Test trace: +gtest_output_test_.cc:#: Expected trace +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ RUN ] SCOPED_TRACETest.WorksInLoop +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 1 +Expected: 2 +Google Test trace: +gtest_output_test_.cc:#: i = 1 +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: i = 2 +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ RUN ] SCOPED_TRACETest.WorksInSubroutine +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 1 +Expected: 2 +Google Test trace: +gtest_output_test_.cc:#: n = 1 +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: n = 2 +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ RUN ] SCOPED_TRACETest.CanBeNested +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: n = 2 +gtest_output_test_.cc:#: +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ RUN ] SCOPED_TRACETest.CanBeRepeated +(expected to fail) +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A. +Google Test trace: +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A and B. +Google Test trace: +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and C. +Google Test trace: +gtest_output_test_.cc:#: C +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and D. +Google Test trace: +gtest_output_test_.cc:#: D +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ RUN ] SCOPED_TRACETest.WorksConcurrently +(expecting 6 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1 (in thread B, only trace B alive). +Google Test trace: +gtest_output_test_.cc:#: Trace B +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2 (in thread A, trace A & B both alive). +Google Test trace: +gtest_output_test_.cc:#: Trace A +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3 (in thread B, trace A & B both alive). +Google Test trace: +gtest_output_test_.cc:#: Trace B +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4 (in thread B, only trace A alive). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #5 (in thread A, only trace A alive). +Google Test trace: +gtest_output_test_.cc:#: Trace A +gtest_output_test_.cc:#: Failure +Failed +Expected failure #6 (in thread A, no trace alive). +[ FAILED ] SCOPED_TRACETest.WorksConcurrently +[----------] 1 test from NonFatalFailureInFixtureConstructorTest +[ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 5 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test body. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4, in TearDown. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #5, in the test fixture d'tor. +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from FatalFailureInFixtureConstructorTest +[ RUN ] FatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in the test fixture d'tor. +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from NonFatalFailureInSetUpTest +[ RUN ] NonFatalFailureInSetUpTest.FailureInSetUp +(expecting 4 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in the test function. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4, in the test fixture d'tor. +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from FatalFailureInSetUpTest +[ RUN ] FatalFailureInSetUpTest.FailureInSetUp +(expecting 3 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test fixture d'tor. +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from AddFailureAtTest +[ RUN ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +foo.cc:42: Failure +Failed +Expected failure in foo.cc +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +[----------] 4 tests from MixedUpTestCaseTest +[ RUN ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo +[ OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo +[ RUN ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo +[ OK ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo +[ RUN ] MixedUpTestCaseTest.ThisShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseTest.ThisShouldFail +[ RUN ] MixedUpTestCaseTest.ThisShouldFailToo +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFailToo +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo +[----------] 2 tests from MixedUpTestCaseWithSameTestNameTest +[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ OK ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseWithSameTestNameTest, +you defined test TheSecondTestWithThisNameShouldFail and test TheSecondTestWithThisNameShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[----------] 2 tests from TEST_F_before_TEST_in_same_test_case +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ OK ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class, so mixing TEST_F and TEST in the same test case is +illegal. In test case TEST_F_before_TEST_in_same_test_case, +test DefinedUsingTEST_F is defined using TEST_F but +test DefinedUsingTESTAndShouldFail is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[----------] 2 tests from TEST_before_TEST_F_in_same_test_case +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ OK ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class, so mixing TEST_F and TEST in the same test case is +illegal. In test case TEST_before_TEST_F_in_same_test_case, +test DefinedUsingTEST_FAndShouldFail is defined using TEST_F but +test DefinedUsingTEST is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[----------] 8 tests from ExpectNonfatalFailureTest +[ RUN ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ RUN ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ OK ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 2 failures +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 1. + +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 2. + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +[----------] 8 tests from ExpectFatalFailureTest +[ RUN ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ OK ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ RUN ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ OK ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 2 failures +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows +[----------] 2 tests from TypedTest/0, where TypeParam = int +[ RUN ] TypedTest/0.Success +[ OK ] TypedTest/0.Success +[ RUN ] TypedTest/0.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: 0 +Expected: 1 +Expected failure +[ FAILED ] TypedTest/0.Failure, where TypeParam = int +[----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char +[ RUN ] Unsigned/TypedTestP/0.Success +[ OK ] Unsigned/TypedTestP/0.Success +[ RUN ] Unsigned/TypedTestP/0.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: '\0' +Expected: 1U +Which is: 1 +Expected failure +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char +[----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int +[ RUN ] Unsigned/TypedTestP/1.Success +[ OK ] Unsigned/TypedTestP/1.Success +[ RUN ] Unsigned/TypedTestP/1.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: 0 +Expected: 1U +Which is: 1 +Expected failure +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int +[----------] 4 tests from ExpectFailureTest +[ RUN ] ExpectFailureTest.ExpectFatalFailure +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ RUN ] ExpectFailureTest.ExpectNonFatalFailure +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ RUN ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ RUN ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[----------] 2 tests from ExpectFailureWithThreadsTest +[ RUN ] ExpectFailureWithThreadsTest.ExpectFatalFailure +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure +[ RUN ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +[----------] 1 test from ScopedFakeTestPartResultReporterTest +[ RUN ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +[----------] 1 test from PrintingFailingParams/FailingParamTest +[ RUN ] PrintingFailingParams/FailingParamTest.Fails/0 +gtest_output_test_.cc:#: Failure +Value of: GetParam() + Actual: 2 +Expected: 1 +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 +[----------] Global test environment tear-down +BarEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +FooEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +[==========] 63 tests from 28 test cases ran. +[ PASSED ] 21 tests. +[ FAILED ] 42 tests, listed below: +[ FAILED ] NonfatalFailureTest.EscapesStringOperands +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ FAILED ] SCOPED_TRACETest.WorksConcurrently +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +[ FAILED ] MixedUpTestCaseTest.ThisShouldFail +[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo +[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows +[ FAILED ] TypedTest/0.Failure, where TypeParam = int +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure +[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 + +42 FAILED TESTS + YOU HAVE 1 DISABLED TEST + +Note: Google Test filter = FatalFailureTest.*:LoggingTest.* +[==========] Running 4 tests from 2 test cases. +[----------] Global test environment set-up. +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine (? ms) +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine (? ms) +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine (? ms) +[----------] 3 tests from FatalFailureTest (? ms total) + +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 9 +i == 2 +i == 3 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 6 +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions (? ms) +[----------] 1 test from LoggingTest (? ms total) + +[----------] Global test environment tear-down +[==========] 4 tests from 2 test cases ran. (? ms total) +[ PASSED ] 0 tests. +[ FAILED ] 4 tests, listed below: +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions + + 4 FAILED TESTS + YOU HAVE 1 DISABLED TEST + +Note: Google Test filter = *DISABLED_* +[==========] Running 1 test from 1 test case. +[----------] Global test environment set-up. +[----------] 1 test from DisabledTestsWarningTest +[ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[----------] Global test environment tear-down +[==========] 1 test from 1 test case ran. +[ PASSED ] 1 test. +Note: Google Test filter = PassingTest.* +Note: This is test shard 2 of 2. +[==========] Running 1 test from 1 test case. +[----------] Global test environment set-up. +[----------] 1 test from PassingTest +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 +[----------] Global test environment tear-down +[==========] 1 test from 1 test case ran. +[ PASSED ] 1 test. + + YOU HAVE 1 DISABLED TEST + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_pred_impl_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_pred_impl_unittest.cc new file mode 100644 index 0000000..a84eff8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_pred_impl_unittest.cc @@ -0,0 +1,2427 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! + +// Regression test for gtest_pred_impl.h +// +// This file is generated by a script and quite long. If you intend to +// learn how Google Test works by reading its unit tests, read +// gtest_unittest.cc instead. +// +// This is intended as a regression test for the Google Test predicate +// assertions. We compile it as part of the gtest_unittest target +// only to keep the implementation tidy and compact, as it is quite +// involved to set up the stage for testing Google Test using Google +// Test itself. +// +// Currently, gtest_unittest takes ~11 seconds to run in the testing +// daemon. In the future, if it grows too large and needs much more +// time to finish, we should consider separating this file into a +// stand-alone regression test. + +#include + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +// A user-defined data type. +struct Bool { + explicit Bool(int val) : value(val != 0) {} + + bool operator>(int n) const { return value > Bool(n).value; } + + Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); } + + bool operator==(const Bool& rhs) const { return value == rhs.value; } + + bool value; +}; + +// Enables Bool to be used in assertions. +std::ostream& operator<<(std::ostream& os, const Bool& x) { + return os << (x.value ? "true" : "false"); +} + +// Sample functions/functors for testing unary predicate assertions. + +// A unary predicate function. +template +bool PredFunction1(T1 v1) { + return v1 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction1Int(int v1) { + return v1 > 0; +} +bool PredFunction1Bool(Bool v1) { + return v1 > 0; +} + +// A unary predicate functor. +struct PredFunctor1 { + template + bool operator()(const T1& v1) { + return v1 > 0; + } +}; + +// A unary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction1(const char* e1, + const T1& v1) { + if (PredFunction1(v1)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 + << " is expected to be positive, but evaluates to " + << v1 << "."; +} + +// A unary predicate-formatter functor. +struct PredFormatFunctor1 { + template + testing::AssertionResult operator()(const char* e1, + const T1& v1) const { + return PredFormatFunction1(e1, v1); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT1. + +class Predicate1Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; +}; + +bool Predicate1Test::expected_to_finish_; +bool Predicate1Test::finished_; +int Predicate1Test::n1_; + +typedef Predicate1Test EXPECT_PRED_FORMAT1Test; +typedef Predicate1Test ASSERT_PRED_FORMAT1Test; +typedef Predicate1Test EXPECT_PRED1Test; +typedef Predicate1Test ASSERT_PRED1Test; + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED1(PredFunction1Int, + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED1(PredFunction1Bool, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED1(PredFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED1(PredFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunction1Int, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunction1Bool, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED1(PredFunction1Int, + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED1(PredFunction1Bool, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED1(PredFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED1(PredFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunction1Int, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunction1Bool, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunction1, + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunction1, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunction1, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunction1, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunction1, + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunction1, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunction1, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunction1, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing binary predicate assertions. + +// A binary predicate function. +template +bool PredFunction2(T1 v1, T2 v2) { + return v1 + v2 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction2Int(int v1, int v2) { + return v1 + v2 > 0; +} +bool PredFunction2Bool(Bool v1, Bool v2) { + return v1 + v2 > 0; +} + +// A binary predicate functor. +struct PredFunctor2 { + template + bool operator()(const T1& v1, + const T2& v2) { + return v1 + v2 > 0; + } +}; + +// A binary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction2(const char* e1, + const char* e2, + const T1& v1, + const T2& v2) { + if (PredFunction2(v1, v2)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 + << " is expected to be positive, but evaluates to " + << v1 + v2 << "."; +} + +// A binary predicate-formatter functor. +struct PredFormatFunctor2 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const T1& v1, + const T2& v2) const { + return PredFormatFunction2(e1, e2, v1, v2); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT2. + +class Predicate2Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; +}; + +bool Predicate2Test::expected_to_finish_; +bool Predicate2Test::finished_; +int Predicate2Test::n1_; +int Predicate2Test::n2_; + +typedef Predicate2Test EXPECT_PRED_FORMAT2Test; +typedef Predicate2Test ASSERT_PRED_FORMAT2Test; +typedef Predicate2Test EXPECT_PRED2Test; +typedef Predicate2Test ASSERT_PRED2Test; + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED2(PredFunction2Int, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED2(PredFunction2Bool, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED2(PredFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED2(PredFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunction2Int, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunction2Bool, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED2(PredFunction2Int, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED2(PredFunction2Bool, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED2(PredFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED2(PredFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunction2Int, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunction2Bool, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunction2, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunction2, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunction2, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunction2, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunction2, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunction2, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunction2, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunction2, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing ternary predicate assertions. + +// A ternary predicate function. +template +bool PredFunction3(T1 v1, T2 v2, T3 v3) { + return v1 + v2 + v3 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction3Int(int v1, int v2, int v3) { + return v1 + v2 + v3 > 0; +} +bool PredFunction3Bool(Bool v1, Bool v2, Bool v3) { + return v1 + v2 + v3 > 0; +} + +// A ternary predicate functor. +struct PredFunctor3 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3) { + return v1 + v2 + v3 > 0; + } +}; + +// A ternary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction3(const char* e1, + const char* e2, + const char* e3, + const T1& v1, + const T2& v2, + const T3& v3) { + if (PredFunction3(v1, v2, v3)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 << "."; +} + +// A ternary predicate-formatter functor. +struct PredFormatFunctor3 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const T1& v1, + const T2& v2, + const T3& v3) const { + return PredFormatFunction3(e1, e2, e3, v1, v2, v3); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT3. + +class Predicate3Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; +}; + +bool Predicate3Test::expected_to_finish_; +bool Predicate3Test::finished_; +int Predicate3Test::n1_; +int Predicate3Test::n2_; +int Predicate3Test::n3_; + +typedef Predicate3Test EXPECT_PRED_FORMAT3Test; +typedef Predicate3Test ASSERT_PRED_FORMAT3Test; +typedef Predicate3Test EXPECT_PRED3Test; +typedef Predicate3Test ASSERT_PRED3Test; + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED3(PredFunction3Int, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED3(PredFunction3Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED3(PredFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED3(PredFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunction3Int, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunction3Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED3(PredFunction3Int, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED3(PredFunction3Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED3(PredFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED3(PredFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunction3Int, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunction3Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunction3, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunction3, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunction3, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunction3, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunction3, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunction3, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunction3, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunction3, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing 4-ary predicate assertions. + +// A 4-ary predicate function. +template +bool PredFunction4(T1 v1, T2 v2, T3 v3, T4 v4) { + return v1 + v2 + v3 + v4 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction4Int(int v1, int v2, int v3, int v4) { + return v1 + v2 + v3 + v4 > 0; +} +bool PredFunction4Bool(Bool v1, Bool v2, Bool v3, Bool v4) { + return v1 + v2 + v3 + v4 > 0; +} + +// A 4-ary predicate functor. +struct PredFunctor4 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + return v1 + v2 + v3 + v4 > 0; + } +}; + +// A 4-ary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction4(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (PredFunction4(v1, v2, v3, v4)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 << " + " << e4 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 + v4 << "."; +} + +// A 4-ary predicate-formatter functor. +struct PredFormatFunctor4 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) const { + return PredFormatFunction4(e1, e2, e3, e4, v1, v2, v3, v4); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT4. + +class Predicate4Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = n4_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + EXPECT_EQ(1, n4_) << + "The predicate assertion didn't evaluate argument 5 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; + static int n4_; +}; + +bool Predicate4Test::expected_to_finish_; +bool Predicate4Test::finished_; +int Predicate4Test::n1_; +int Predicate4Test::n2_; +int Predicate4Test::n3_; +int Predicate4Test::n4_; + +typedef Predicate4Test EXPECT_PRED_FORMAT4Test; +typedef Predicate4Test ASSERT_PRED_FORMAT4Test; +typedef Predicate4Test EXPECT_PRED4Test; +typedef Predicate4Test ASSERT_PRED4Test; + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED4(PredFunction4Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED4(PredFunction4Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED4(PredFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED4(PredFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunction4Int, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunction4Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED4(PredFunction4Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED4(PredFunction4Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED4(PredFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED4(PredFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunction4Int, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunction4Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunction4, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunction4, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunction4, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunction4, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunction4, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunction4, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunction4, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunction4, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing 5-ary predicate assertions. + +// A 5-ary predicate function. +template +bool PredFunction5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction5Int(int v1, int v2, int v3, int v4, int v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} +bool PredFunction5Bool(Bool v1, Bool v2, Bool v3, Bool v4, Bool v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} + +// A 5-ary predicate functor. +struct PredFunctor5 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + return v1 + v2 + v3 + v4 + v5 > 0; + } +}; + +// A 5-ary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction5(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (PredFunction5(v1, v2, v3, v4, v5)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 + v4 + v5 << "."; +} + +// A 5-ary predicate-formatter functor. +struct PredFormatFunctor5 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) const { + return PredFormatFunction5(e1, e2, e3, e4, e5, v1, v2, v3, v4, v5); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT5. + +class Predicate5Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = n4_ = n5_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + EXPECT_EQ(1, n4_) << + "The predicate assertion didn't evaluate argument 5 " + "exactly once."; + EXPECT_EQ(1, n5_) << + "The predicate assertion didn't evaluate argument 6 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; + static int n4_; + static int n5_; +}; + +bool Predicate5Test::expected_to_finish_; +bool Predicate5Test::finished_; +int Predicate5Test::n1_; +int Predicate5Test::n2_; +int Predicate5Test::n3_; +int Predicate5Test::n4_; +int Predicate5Test::n5_; + +typedef Predicate5Test EXPECT_PRED_FORMAT5Test; +typedef Predicate5Test ASSERT_PRED_FORMAT5Test; +typedef Predicate5Test EXPECT_PRED5Test; +typedef Predicate5Test ASSERT_PRED5Test; + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED5(PredFunction5Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED5(PredFunction5Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED5(PredFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED5(PredFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunction5Int, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunction5Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED5(PredFunction5Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED5(PredFunction5Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED5(PredFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED5(PredFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunction5Int, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunction5Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunction5, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunction5, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunction5, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunction5, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunction5, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunction5, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunction5, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunction5, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_prod_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_prod_test.cc new file mode 100644 index 0000000..060abce --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_prod_test.cc @@ -0,0 +1,57 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Unit test for include/gtest/gtest_prod.h. + +#include "gtest/gtest.h" +#include "test/production.h" + +// Tests that private members can be accessed from a TEST declared as +// a friend of the class. +TEST(PrivateCodeTest, CanAccessPrivateMembers) { + PrivateCode a; + EXPECT_EQ(0, a.x_); + + a.set_x(1); + EXPECT_EQ(1, a.x_); +} + +typedef testing::Test PrivateCodeFixtureTest; + +// Tests that private members can be accessed from a TEST_F declared +// as a friend of the class. +TEST_F(PrivateCodeFixtureTest, CanAccessPrivateMembers) { + PrivateCode a; + EXPECT_EQ(0, a.x_); + + a.set_x(2); + EXPECT_EQ(2, a.x_); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_repeat_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_repeat_test.cc new file mode 100644 index 0000000..481012a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_repeat_test.cc @@ -0,0 +1,253 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests the --gtest_repeat=number flag. + +#include +#include +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +GTEST_DECLARE_string_(death_test_style); +GTEST_DECLARE_string_(filter); +GTEST_DECLARE_int32_(repeat); + +} // namespace testing + +using testing::GTEST_FLAG(death_test_style); +using testing::GTEST_FLAG(filter); +using testing::GTEST_FLAG(repeat); + +namespace { + +// We need this when we are testing Google Test itself and therefore +// cannot use Google Test assertions. +#define GTEST_CHECK_INT_EQ_(expected, actual) \ + do {\ + const int expected_val = (expected);\ + const int actual_val = (actual);\ + if (::testing::internal::IsTrue(expected_val != actual_val)) {\ + ::std::cout << "Value of: " #actual "\n"\ + << " Actual: " << actual_val << "\n"\ + << "Expected: " #expected "\n"\ + << "Which is: " << expected_val << "\n";\ + ::testing::internal::posix::Abort();\ + }\ + } while (::testing::internal::AlwaysFalse()) + + +// Used for verifying that global environment set-up and tear-down are +// inside the gtest_repeat loop. + +int g_environment_set_up_count = 0; +int g_environment_tear_down_count = 0; + +class MyEnvironment : public testing::Environment { + public: + MyEnvironment() {} + virtual void SetUp() { g_environment_set_up_count++; } + virtual void TearDown() { g_environment_tear_down_count++; } +}; + +// A test that should fail. + +int g_should_fail_count = 0; + +TEST(FooTest, ShouldFail) { + g_should_fail_count++; + EXPECT_EQ(0, 1) << "Expected failure."; +} + +// A test that should pass. + +int g_should_pass_count = 0; + +TEST(FooTest, ShouldPass) { + g_should_pass_count++; +} + +// A test that contains a thread-safe death test and a fast death +// test. It should pass. + +int g_death_test_count = 0; + +TEST(BarDeathTest, ThreadSafeAndFast) { + g_death_test_count++; + + GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); + + GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); +} + +#if GTEST_HAS_PARAM_TEST +int g_param_test_count = 0; + +const int kNumberOfParamTests = 10; + +class MyParamTest : public testing::TestWithParam {}; + +TEST_P(MyParamTest, ShouldPass) { + // TODO(vladl@google.com): Make parameter value checking robust + // WRT order of tests. + GTEST_CHECK_INT_EQ_(g_param_test_count % kNumberOfParamTests, GetParam()); + g_param_test_count++; +} +INSTANTIATE_TEST_CASE_P(MyParamSequence, + MyParamTest, + testing::Range(0, kNumberOfParamTests)); +#endif // GTEST_HAS_PARAM_TEST + +// Resets the count for each test. +void ResetCounts() { + g_environment_set_up_count = 0; + g_environment_tear_down_count = 0; + g_should_fail_count = 0; + g_should_pass_count = 0; + g_death_test_count = 0; +#if GTEST_HAS_PARAM_TEST + g_param_test_count = 0; +#endif // GTEST_HAS_PARAM_TEST +} + +// Checks that the count for each test is expected. +void CheckCounts(int expected) { + GTEST_CHECK_INT_EQ_(expected, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(expected, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(expected, g_should_fail_count); + GTEST_CHECK_INT_EQ_(expected, g_should_pass_count); + GTEST_CHECK_INT_EQ_(expected, g_death_test_count); +#if GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(expected * kNumberOfParamTests, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST +} + +// Tests the behavior of Google Test when --gtest_repeat is not specified. +void TestRepeatUnspecified() { + ResetCounts(); + GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); + CheckCounts(1); +} + +// Tests the behavior of Google Test when --gtest_repeat has the given value. +void TestRepeat(int repeat) { + GTEST_FLAG(repeat) = repeat; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(repeat > 0 ? 1 : 0, RUN_ALL_TESTS()); + CheckCounts(repeat); +} + +// Tests using --gtest_repeat when --gtest_filter specifies an empty +// set of tests. +void TestRepeatWithEmptyFilter(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "None"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); + CheckCounts(0); +} + +// Tests using --gtest_repeat when --gtest_filter specifies a set of +// successful tests. +void TestRepeatWithFilterForSuccessfulTests(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "*-*ShouldFail"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); + GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(0, g_should_fail_count); + GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count); + GTEST_CHECK_INT_EQ_(repeat, g_death_test_count); +#if GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(repeat * kNumberOfParamTests, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST +} + +// Tests using --gtest_repeat when --gtest_filter specifies a set of +// failed tests. +void TestRepeatWithFilterForFailedTests(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "*ShouldFail"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); + GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count); + GTEST_CHECK_INT_EQ_(0, g_should_pass_count); + GTEST_CHECK_INT_EQ_(0, g_death_test_count); +#if GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(0, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST +} + +} // namespace + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + testing::AddGlobalTestEnvironment(new MyEnvironment); + + TestRepeatUnspecified(); + TestRepeat(0); + TestRepeat(1); + TestRepeat(5); + + TestRepeatWithEmptyFilter(2); + TestRepeatWithEmptyFilter(3); + + TestRepeatWithFilterForSuccessfulTests(3); + + TestRepeatWithFilterForFailedTests(4); + + // It would be nice to verify that the tests indeed loop forever + // when GTEST_FLAG(repeat) is negative, but this test will be quite + // complicated to write. Since this flag is for interactive + // debugging only and doesn't affect the normal test result, such a + // test would be an overkill. + + printf("PASS\n"); + return 0; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_shuffle_test.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_shuffle_test.py new file mode 100755 index 0000000..30d0303 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_shuffle_test.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python +# +# Copyright 2009 Google Inc. All Rights Reserved. +# +# 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. + +"""Verifies that test shuffling works.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + +# Command to run the gtest_shuffle_test_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_shuffle_test_') + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' + +TEST_FILTER = 'A*.A:A*.B:C*' + +ALL_TESTS = [] +ACTIVE_TESTS = [] +FILTERED_TESTS = [] +SHARDED_TESTS = [] + +SHUFFLED_ALL_TESTS = [] +SHUFFLED_ACTIVE_TESTS = [] +SHUFFLED_FILTERED_TESTS = [] +SHUFFLED_SHARDED_TESTS = [] + + +def AlsoRunDisabledTestsFlag(): + return '--gtest_also_run_disabled_tests' + + +def FilterFlag(test_filter): + return '--gtest_filter=%s' % (test_filter,) + + +def RepeatFlag(n): + return '--gtest_repeat=%s' % (n,) + + +def ShuffleFlag(): + return '--gtest_shuffle' + + +def RandomSeedFlag(n): + return '--gtest_random_seed=%s' % (n,) + + +def RunAndReturnOutput(extra_env, args): + """Runs the test program and returns its output.""" + + environ_copy = os.environ.copy() + environ_copy.update(extra_env) + + return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output + + +def GetTestsForAllIterations(extra_env, args): + """Runs the test program and returns a list of test lists. + + Args: + extra_env: a map from environment variables to their values + args: command line flags to pass to gtest_shuffle_test_ + + Returns: + A list where the i-th element is the list of tests run in the i-th + test iteration. + """ + + test_iterations = [] + for line in RunAndReturnOutput(extra_env, args).split('\n'): + if line.startswith('----'): + tests = [] + test_iterations.append(tests) + elif line.strip(): + tests.append(line.strip()) # 'TestCaseName.TestName' + + return test_iterations + + +def GetTestCases(tests): + """Returns a list of test cases in the given full test names. + + Args: + tests: a list of full test names + + Returns: + A list of test cases from 'tests', in their original order. + Consecutive duplicates are removed. + """ + + test_cases = [] + for test in tests: + test_case = test.split('.')[0] + if not test_case in test_cases: + test_cases.append(test_case) + + return test_cases + + +def CalculateTestLists(): + """Calculates the list of tests run under different flags.""" + + if not ALL_TESTS: + ALL_TESTS.extend( + GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0]) + + if not ACTIVE_TESTS: + ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0]) + + if not FILTERED_TESTS: + FILTERED_TESTS.extend( + GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0]) + + if not SHARDED_TESTS: + SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [])[0]) + + if not SHUFFLED_ALL_TESTS: + SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations( + {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_ACTIVE_TESTS: + SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_FILTERED_TESTS: + SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0]) + + if not SHUFFLED_SHARDED_TESTS: + SHUFFLED_SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + +class GTestShuffleUnitTest(gtest_test_utils.TestCase): + """Tests test shuffling.""" + + def setUp(self): + CalculateTestLists() + + def testShufflePreservesNumberOfTests(self): + self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS)) + self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS)) + self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS)) + self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS)) + + def testShuffleChangesTestOrder(self): + self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS) + self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS) + self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS, + SHUFFLED_FILTERED_TESTS) + self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS, + SHUFFLED_SHARDED_TESTS) + + def testShuffleChangesTestCaseOrder(self): + self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS), + GetTestCases(SHUFFLED_ALL_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS), + GetTestCases(SHUFFLED_ACTIVE_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS), + GetTestCases(SHUFFLED_FILTERED_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS), + GetTestCases(SHUFFLED_SHARDED_TESTS)) + + def testShuffleDoesNotRepeatTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test), + '%s appears more than once' % (test,)) + + def testShuffleDoesNotCreateNewTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,)) + + def testShuffleIncludesAllTests(self): + for test in ALL_TESTS: + self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,)) + for test in ACTIVE_TESTS: + self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,)) + for test in FILTERED_TESTS: + self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,)) + for test in SHARDED_TESTS: + self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,)) + + def testShuffleLeavesDeathTestsAtFront(self): + non_death_test_found = False + for test in SHUFFLED_ACTIVE_TESTS: + if 'DeathTest.' in test: + self.assert_(not non_death_test_found, + '%s appears after a non-death test' % (test,)) + else: + non_death_test_found = True + + def _VerifyTestCasesDoNotInterleave(self, tests): + test_cases = [] + for test in tests: + [test_case, _] = test.split('.') + if test_cases and test_cases[-1] != test_case: + test_cases.append(test_case) + self.assertEqual(1, test_cases.count(test_case), + 'Test case %s is not grouped together in %s' % + (test_case, tests)) + + def testShuffleDoesNotInterleaveTestCases(self): + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS) + + def testShuffleRestoresOrderAfterEachIteration(self): + # Get the test lists in all 3 iterations, using random seed 1, 2, + # and 3 respectively. Google Test picks a different seed in each + # iteration, and this test depends on the current implementation + # picking successive numbers. This dependency is not ideal, but + # makes the test much easier to write. + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + # Make sure running the tests with random seed 1 gets the same + # order as in iteration 1 above. + [tests_with_seed1] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)]) + self.assertEqual(tests_in_iteration1, tests_with_seed1) + + # Make sure running the tests with random seed 2 gets the same + # order as in iteration 2 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 2. + [tests_with_seed2] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(2)]) + self.assertEqual(tests_in_iteration2, tests_with_seed2) + + # Make sure running the tests with random seed 3 gets the same + # order as in iteration 3 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 3. + [tests_with_seed3] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(3)]) + self.assertEqual(tests_in_iteration3, tests_with_seed3) + + def testShuffleGeneratesNewOrderInEachIteration(self): + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + self.assert_(tests_in_iteration1 != tests_in_iteration2, + tests_in_iteration1) + self.assert_(tests_in_iteration1 != tests_in_iteration3, + tests_in_iteration1) + self.assert_(tests_in_iteration2 != tests_in_iteration3, + tests_in_iteration2) + + def testShuffleShardedTestsPreservesPartition(self): + # If we run M tests on N shards, the same M tests should be run in + # total, regardless of the random seeds used by the shards. + [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '0'}, + [ShuffleFlag(), RandomSeedFlag(1)]) + [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(20)]) + [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '2'}, + [ShuffleFlag(), RandomSeedFlag(25)]) + sorted_sharded_tests = tests1 + tests2 + tests3 + sorted_sharded_tests.sort() + sorted_active_tests = [] + sorted_active_tests.extend(ACTIVE_TESTS) + sorted_active_tests.sort() + self.assertEqual(sorted_active_tests, sorted_sharded_tests) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_shuffle_test_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_shuffle_test_.cc new file mode 100644 index 0000000..6fb441b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_shuffle_test_.cc @@ -0,0 +1,103 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Verifies that test shuffling works. + +#include "gtest/gtest.h" + +namespace { + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Message; +using ::testing::Test; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::UnitTest; +using ::testing::internal::scoped_ptr; + +// The test methods are empty, as the sole purpose of this program is +// to print the test names before/after shuffling. + +class A : public Test {}; +TEST_F(A, A) {} +TEST_F(A, B) {} + +TEST(ADeathTest, A) {} +TEST(ADeathTest, B) {} +TEST(ADeathTest, C) {} + +TEST(B, A) {} +TEST(B, B) {} +TEST(B, C) {} +TEST(B, DISABLED_D) {} +TEST(B, DISABLED_E) {} + +TEST(BDeathTest, A) {} +TEST(BDeathTest, B) {} + +TEST(C, A) {} +TEST(C, B) {} +TEST(C, C) {} +TEST(C, DISABLED_D) {} + +TEST(CDeathTest, A) {} + +TEST(DISABLED_D, A) {} +TEST(DISABLED_D, DISABLED_B) {} + +// This printer prints the full test names only, starting each test +// iteration with a "----" marker. +class TestNamePrinter : public EmptyTestEventListener { + public: + virtual void OnTestIterationStart(const UnitTest& /* unit_test */, + int /* iteration */) { + printf("----\n"); + } + + virtual void OnTestStart(const TestInfo& test_info) { + printf("%s.%s\n", test_info.test_case_name(), test_info.name()); + } +}; + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + // Replaces the default printer with TestNamePrinter, which prints + // the test name only. + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_result_printer()); + listeners.Append(new TestNamePrinter); + + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_sole_header_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_sole_header_test.cc new file mode 100644 index 0000000..ccd091a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_sole_header_test.cc @@ -0,0 +1,57 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: mheule@google.com (Markus Heule) +// +// This test verifies that it's possible to use Google Test by including +// the gtest.h header file alone. + +#include "gtest/gtest.h" + +namespace { + +void Subroutine() { + EXPECT_EQ(42, 42); +} + +TEST(NoFatalFailureTest, ExpectNoFatalFailure) { + EXPECT_NO_FATAL_FAILURE(;); + EXPECT_NO_FATAL_FAILURE(SUCCEED()); + EXPECT_NO_FATAL_FAILURE(Subroutine()); + EXPECT_NO_FATAL_FAILURE({ SUCCEED(); }); +} + +TEST(NoFatalFailureTest, AssertNoFatalFailure) { + ASSERT_NO_FATAL_FAILURE(;); + ASSERT_NO_FATAL_FAILURE(SUCCEED()); + ASSERT_NO_FATAL_FAILURE(Subroutine()); + ASSERT_NO_FATAL_FAILURE({ SUCCEED(); }); +} + +} // namespace diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_stress_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_stress_test.cc new file mode 100644 index 0000000..e7daa43 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_stress_test.cc @@ -0,0 +1,256 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests that SCOPED_TRACE() and various Google Test assertions can be +// used in a large number of threads concurrently. + +#include "gtest/gtest.h" + +#include +#include + +// We must define this macro in order to #include +// gtest-internal-inl.h. This is how Google Test prevents a user from +// accidentally depending on its internal implementation. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_IS_THREADSAFE + +namespace testing { +namespace { + +using internal::Notification; +using internal::TestPropertyKeyIs; +using internal::ThreadWithParam; +using internal::scoped_ptr; + +// In order to run tests in this file, for platforms where Google Test is +// thread safe, implement ThreadWithParam. See the description of its API +// in gtest-port.h, where it is defined for already supported platforms. + +// How many threads to create? +const int kThreadCount = 50; + +std::string IdToKey(int id, const char* suffix) { + Message key; + key << "key_" << id << "_" << suffix; + return key.GetString(); +} + +std::string IdToString(int id) { + Message id_message; + id_message << id; + return id_message.GetString(); +} + +void ExpectKeyAndValueWereRecordedForId( + const std::vector& properties, + int id, const char* suffix) { + TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str()); + const std::vector::const_iterator property = + std::find_if(properties.begin(), properties.end(), matches_key); + ASSERT_TRUE(property != properties.end()) + << "expecting " << suffix << " value for id " << id; + EXPECT_STREQ(IdToString(id).c_str(), property->value()); +} + +// Calls a large number of Google Test assertions, where exactly one of them +// will fail. +void ManyAsserts(int id) { + GTEST_LOG_(INFO) << "Thread #" << id << " running..."; + + SCOPED_TRACE(Message() << "Thread #" << id); + + for (int i = 0; i < kThreadCount; i++) { + SCOPED_TRACE(Message() << "Iteration #" << i); + + // A bunch of assertions that should succeed. + EXPECT_TRUE(true); + ASSERT_FALSE(false) << "This shouldn't fail."; + EXPECT_STREQ("a", "a"); + ASSERT_LE(5, 6); + EXPECT_EQ(i, i) << "This shouldn't fail."; + + // RecordProperty() should interact safely with other threads as well. + // The shared_key forces property updates. + Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str()); + Test::RecordProperty(IdToKey(id, "int").c_str(), id); + Test::RecordProperty("shared_key", IdToString(id).c_str()); + + // This assertion should fail kThreadCount times per thread. It + // is for testing whether Google Test can handle failed assertions in a + // multi-threaded context. + EXPECT_LT(i, 0) << "This should always fail."; + } +} + +void CheckTestFailureCount(int expected_failures) { + const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); + const TestResult* const result = info->result(); + GTEST_CHECK_(expected_failures == result->total_part_count()) + << "Logged " << result->total_part_count() << " failures " + << " vs. " << expected_failures << " expected"; +} + +// Tests using SCOPED_TRACE() and Google Test assertions in many threads +// concurrently. +TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { + { + scoped_ptr > threads[kThreadCount]; + Notification threads_can_start; + for (int i = 0; i != kThreadCount; i++) + threads[i].reset(new ThreadWithParam(&ManyAsserts, + i, + &threads_can_start)); + + threads_can_start.Notify(); + + // Blocks until all the threads are done. + for (int i = 0; i != kThreadCount; i++) + threads[i]->Join(); + } + + // Ensures that kThreadCount*kThreadCount failures have been reported. + const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); + const TestResult* const result = info->result(); + + std::vector properties; + // We have no access to the TestResult's list of properties but we can + // copy them one by one. + for (int i = 0; i < result->test_property_count(); ++i) + properties.push_back(result->GetTestProperty(i)); + + EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count()) + << "String and int values recorded on each thread, " + << "as well as one shared_key"; + for (int i = 0; i < kThreadCount; ++i) { + ExpectKeyAndValueWereRecordedForId(properties, i, "string"); + ExpectKeyAndValueWereRecordedForId(properties, i, "int"); + } + CheckTestFailureCount(kThreadCount*kThreadCount); +} + +void FailingThread(bool is_fatal) { + if (is_fatal) + FAIL() << "Fatal failure in some other thread. " + << "(This failure is expected.)"; + else + ADD_FAILURE() << "Non-fatal failure in some other thread. " + << "(This failure is expected.)"; +} + +void GenerateFatalFailureInAnotherThread(bool is_fatal) { + ThreadWithParam thread(&FailingThread, is_fatal, NULL); + thread.Join(); +} + +TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) { + EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); + // We should only have one failure (the one from + // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE + // should succeed. + CheckTestFailureCount(1); +} + +void AssertNoFatalFailureIgnoresFailuresInOtherThreads() { + ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); +} +TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) { + // Using a subroutine, to make sure, that the test continues. + AssertNoFatalFailureIgnoresFailuresInOtherThreads(); + // We should only have one failure (the one from + // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE + // should succeed. + CheckTestFailureCount(1); +} + +TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) { + // This statement should fail, since the current thread doesn't generate a + // fatal failure, only another one does. + EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected"); + CheckTestFailureCount(2); +} + +TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) { + // This statement should succeed, because failures in all threads are + // considered. + EXPECT_FATAL_FAILURE_ON_ALL_THREADS( + GenerateFatalFailureInAnotherThread(true), "expected"); + CheckTestFailureCount(0); + // We need to add a failure, because main() checks that there are failures. + // But when only this test is run, we shouldn't have any failures. + ADD_FAILURE() << "This is an expected non-fatal failure."; +} + +TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) { + // This statement should fail, since the current thread doesn't generate a + // fatal failure, only another one does. + EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false), + "expected"); + CheckTestFailureCount(2); +} + +TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) { + // This statement should succeed, because failures in all threads are + // considered. + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( + GenerateFatalFailureInAnotherThread(false), "expected"); + CheckTestFailureCount(0); + // We need to add a failure, because main() checks that there are failures, + // But when only this test is run, we shouldn't have any failures. + ADD_FAILURE() << "This is an expected non-fatal failure."; +} + +} // namespace +} // namespace testing + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + const int result = RUN_ALL_TESTS(); // Expected to fail. + GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected"; + + printf("\nPASS\n"); + return 0; +} + +#else +TEST(StressTest, + DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) { +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif // GTEST_IS_THREADSAFE diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_test_utils.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_test_utils.py new file mode 100755 index 0000000..6dd8db4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_test_utils.py @@ -0,0 +1,305 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test utilities for Google C++ Testing Framework.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import atexit +import os +import shutil +import sys +import tempfile +import unittest +_test_module = unittest + +# Suppresses the 'Import not at the top of the file' lint complaint. +# pylint: disable-msg=C6204 +try: + import subprocess + _SUBPROCESS_MODULE_AVAILABLE = True +except: + import popen2 + _SUBPROCESS_MODULE_AVAILABLE = False +# pylint: enable-msg=C6204 + +GTEST_OUTPUT_VAR_NAME = 'GTEST_OUTPUT' + +IS_WINDOWS = os.name == 'nt' +IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] + +# Here we expose a class from a particular module, depending on the +# environment. The comment suppresses the 'Invalid variable name' lint +# complaint. +TestCase = _test_module.TestCase # pylint: disable-msg=C6409 + +# Initially maps a flag to its default value. After +# _ParseAndStripGTestFlags() is called, maps a flag to its actual value. +_flag_map = {'source_dir': os.path.dirname(sys.argv[0]), + 'build_dir': os.path.dirname(sys.argv[0])} +_gtest_flags_are_parsed = False + + +def _ParseAndStripGTestFlags(argv): + """Parses and strips Google Test flags from argv. This is idempotent.""" + + # Suppresses the lint complaint about a global variable since we need it + # here to maintain module-wide state. + global _gtest_flags_are_parsed # pylint: disable-msg=W0603 + if _gtest_flags_are_parsed: + return + + _gtest_flags_are_parsed = True + for flag in _flag_map: + # The environment variable overrides the default value. + if flag.upper() in os.environ: + _flag_map[flag] = os.environ[flag.upper()] + + # The command line flag overrides the environment variable. + i = 1 # Skips the program name. + while i < len(argv): + prefix = '--' + flag + '=' + if argv[i].startswith(prefix): + _flag_map[flag] = argv[i][len(prefix):] + del argv[i] + break + else: + # We don't increment i in case we just found a --gtest_* flag + # and removed it from argv. + i += 1 + + +def GetFlag(flag): + """Returns the value of the given flag.""" + + # In case GetFlag() is called before Main(), we always call + # _ParseAndStripGTestFlags() here to make sure the --gtest_* flags + # are parsed. + _ParseAndStripGTestFlags(sys.argv) + + return _flag_map[flag] + + +def GetSourceDir(): + """Returns the absolute path of the directory where the .py files are.""" + + return os.path.abspath(GetFlag('source_dir')) + + +def GetBuildDir(): + """Returns the absolute path of the directory where the test binaries are.""" + + return os.path.abspath(GetFlag('build_dir')) + + +_temp_dir = None + +def _RemoveTempDir(): + if _temp_dir: + shutil.rmtree(_temp_dir, ignore_errors=True) + +atexit.register(_RemoveTempDir) + + +def GetTempDir(): + """Returns a directory for temporary files.""" + + global _temp_dir + if not _temp_dir: + _temp_dir = tempfile.mkdtemp() + return _temp_dir + + +def GetTestExecutablePath(executable_name, build_dir=None): + """Returns the absolute path of the test binary given its name. + + The function will print a message and abort the program if the resulting file + doesn't exist. + + Args: + executable_name: name of the test binary that the test script runs. + build_dir: directory where to look for executables, by default + the result of GetBuildDir(). + + Returns: + The absolute path of the test binary. + """ + + path = os.path.abspath(os.path.join(build_dir or GetBuildDir(), + executable_name)) + if (IS_WINDOWS or IS_CYGWIN) and not path.endswith('.exe'): + path += '.exe' + + if not os.path.exists(path): + message = ( + 'Unable to find the test binary. Please make sure to provide path\n' + 'to the binary via the --build_dir flag or the BUILD_DIR\n' + 'environment variable.') + print >> sys.stderr, message + sys.exit(1) + + return path + + +def GetExitStatus(exit_code): + """Returns the argument to exit(), or -1 if exit() wasn't called. + + Args: + exit_code: the result value of os.system(command). + """ + + if os.name == 'nt': + # On Windows, os.WEXITSTATUS() doesn't work and os.system() returns + # the argument to exit() directly. + return exit_code + else: + # On Unix, os.WEXITSTATUS() must be used to extract the exit status + # from the result of os.system(). + if os.WIFEXITED(exit_code): + return os.WEXITSTATUS(exit_code) + else: + return -1 + + +class Subprocess: + def __init__(self, command, working_dir=None, capture_stderr=True, env=None): + """Changes into a specified directory, if provided, and executes a command. + + Restores the old directory afterwards. + + Args: + command: The command to run, in the form of sys.argv. + working_dir: The directory to change into. + capture_stderr: Determines whether to capture stderr in the output member + or to discard it. + env: Dictionary with environment to pass to the subprocess. + + Returns: + An object that represents outcome of the executed process. It has the + following attributes: + terminated_by_signal True iff the child process has been terminated + by a signal. + signal Sygnal that terminated the child process. + exited True iff the child process exited normally. + exit_code The code with which the child process exited. + output Child process's stdout and stderr output + combined in a string. + """ + + # The subprocess module is the preferrable way of running programs + # since it is available and behaves consistently on all platforms, + # including Windows. But it is only available starting in python 2.4. + # In earlier python versions, we revert to the popen2 module, which is + # available in python 2.0 and later but doesn't provide required + # functionality (Popen4) under Windows. This allows us to support Mac + # OS X 10.4 Tiger, which has python 2.3 installed. + if _SUBPROCESS_MODULE_AVAILABLE: + if capture_stderr: + stderr = subprocess.STDOUT + else: + stderr = subprocess.PIPE + + p = subprocess.Popen(command, + stdout=subprocess.PIPE, stderr=stderr, + cwd=working_dir, universal_newlines=True, env=env) + # communicate returns a tuple with the file obect for the child's + # output. + self.output = p.communicate()[0] + self._return_code = p.returncode + else: + old_dir = os.getcwd() + + def _ReplaceEnvDict(dest, src): + # Changes made by os.environ.clear are not inheritable by child + # processes until Python 2.6. To produce inheritable changes we have + # to delete environment items with the del statement. + for key in dest.keys(): + del dest[key] + dest.update(src) + + # When 'env' is not None, backup the environment variables and replace + # them with the passed 'env'. When 'env' is None, we simply use the + # current 'os.environ' for compatibility with the subprocess.Popen + # semantics used above. + if env is not None: + old_environ = os.environ.copy() + _ReplaceEnvDict(os.environ, env) + + try: + if working_dir is not None: + os.chdir(working_dir) + if capture_stderr: + p = popen2.Popen4(command) + else: + p = popen2.Popen3(command) + p.tochild.close() + self.output = p.fromchild.read() + ret_code = p.wait() + finally: + os.chdir(old_dir) + + # Restore the old environment variables + # if they were replaced. + if env is not None: + _ReplaceEnvDict(os.environ, old_environ) + + # Converts ret_code to match the semantics of + # subprocess.Popen.returncode. + if os.WIFSIGNALED(ret_code): + self._return_code = -os.WTERMSIG(ret_code) + else: # os.WIFEXITED(ret_code) should return True here. + self._return_code = os.WEXITSTATUS(ret_code) + + if self._return_code < 0: + self.terminated_by_signal = True + self.exited = False + self.signal = -self._return_code + else: + self.terminated_by_signal = False + self.exited = True + self.exit_code = self._return_code + + +def Main(): + """Runs the unit test.""" + + # We must call _ParseAndStripGTestFlags() before calling + # unittest.main(). Otherwise the latter will be confused by the + # --gtest_* flags. + _ParseAndStripGTestFlags(sys.argv) + # The tested binaries should not be writing XML output files unless the + # script explicitly instructs them to. + # TODO(vladl@google.com): Move this into Subprocess when we implement + # passing environment into it as a parameter. + if GTEST_OUTPUT_VAR_NAME in os.environ: + del os.environ[GTEST_OUTPUT_VAR_NAME] + + _test_module.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_ex_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_ex_test.cc new file mode 100644 index 0000000..8d46c76 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_ex_test.cc @@ -0,0 +1,92 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests Google Test's throw-on-failure mode with exceptions enabled. + +#include "gtest/gtest.h" + +#include +#include +#include +#include + +// Prints the given failure message and exits the program with +// non-zero. We use this instead of a Google Test assertion to +// indicate a failure, as the latter is been tested and cannot be +// relied on. +void Fail(const char* msg) { + printf("FAILURE: %s\n", msg); + fflush(stdout); + exit(1); +} + +// Tests that an assertion failure throws a subclass of +// std::runtime_error. +void TestFailureThrowsRuntimeError() { + testing::GTEST_FLAG(throw_on_failure) = true; + + // A successful assertion shouldn't throw. + try { + EXPECT_EQ(3, 3); + } catch(...) { + Fail("A successful assertion wrongfully threw."); + } + + // A failed assertion should throw a subclass of std::runtime_error. + try { + EXPECT_EQ(2, 3) << "Expected failure"; + } catch(const std::runtime_error& e) { + if (strstr(e.what(), "Expected failure") != NULL) + return; + + printf("%s", + "A failed assertion did throw an exception of the right type, " + "but the message is incorrect. Instead of containing \"Expected " + "failure\", it is:\n"); + Fail(e.what()); + } catch(...) { + Fail("A failed assertion threw the wrong type of exception."); + } + Fail("A failed assertion should've thrown but didn't."); +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + // We want to ensure that people can use Google Test assertions in + // other testing frameworks, as long as they initialize Google Test + // properly and set the thrown-on-failure mode. Therefore, we don't + // use Google Test's constructs for defining and running tests + // (e.g. TEST and RUN_ALL_TESTS) here. + + TestFailureThrowsRuntimeError(); + return 0; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_test.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_test.py new file mode 100755 index 0000000..5678ffe --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_test.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# 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. + +"""Tests Google Test's throw-on-failure mode with exceptions disabled. + +This script invokes gtest_throw_on_failure_test_ (a program written with +Google Test) with different environments and command line flags. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + + +# Constants. + +# The command line flag for enabling/disabling the throw-on-failure mode. +THROW_ON_FAILURE = 'gtest_throw_on_failure' + +# Path to the gtest_throw_on_failure_test_ program, compiled with +# exceptions disabled. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_throw_on_failure_test_') + + +# Utilities. + + +def SetEnvVar(env_var, value): + """Sets an environment variable to a given value; unsets it when the + given value is None. + """ + + env_var = env_var.upper() + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def Run(command): + """Runs a command; returns True/False if its exit code is/isn't 0.""" + + print 'Running "%s". . .' % ' '.join(command) + p = gtest_test_utils.Subprocess(command) + return p.exited and p.exit_code == 0 + + +# The tests. TODO(wan@google.com): refactor the class to share common +# logic with code in gtest_break_on_failure_unittest.py. +class ThrowOnFailureTest(gtest_test_utils.TestCase): + """Tests the throw-on-failure mode.""" + + def RunAndVerify(self, env_var_value, flag_value, should_fail): + """Runs gtest_throw_on_failure_test_ and verifies that it does + (or does not) exit with a non-zero code. + + Args: + env_var_value: value of the GTEST_BREAK_ON_FAILURE environment + variable; None if the variable should be unset. + flag_value: value of the --gtest_break_on_failure flag; + None if the flag should not be present. + should_fail: True iff the program is expected to fail. + """ + + SetEnvVar(THROW_ON_FAILURE, env_var_value) + + if env_var_value is None: + env_var_value_msg = ' is not set' + else: + env_var_value_msg = '=' + env_var_value + + if flag_value is None: + flag = '' + elif flag_value == '0': + flag = '--%s=0' % THROW_ON_FAILURE + else: + flag = '--%s' % THROW_ON_FAILURE + + command = [EXE_PATH] + if flag: + command.append(flag) + + if should_fail: + should_or_not = 'should' + else: + should_or_not = 'should not' + + failed = not Run(command) + + SetEnvVar(THROW_ON_FAILURE, None) + + msg = ('when %s%s, an assertion failure in "%s" %s cause a non-zero ' + 'exit code.' % + (THROW_ON_FAILURE, env_var_value_msg, ' '.join(command), + should_or_not)) + self.assert_(failed == should_fail, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(env_var_value=None, flag_value=None, should_fail=False) + + def testThrowOnFailureEnvVar(self): + """Tests using the GTEST_THROW_ON_FAILURE environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value=None, + should_fail=False) + self.RunAndVerify(env_var_value='1', + flag_value=None, + should_fail=True) + + def testThrowOnFailureFlag(self): + """Tests using the --gtest_throw_on_failure flag.""" + + self.RunAndVerify(env_var_value=None, + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value=None, + flag_value='1', + should_fail=True) + + def testThrowOnFailureFlagOverridesEnvVar(self): + """Tests that --gtest_throw_on_failure overrides GTEST_THROW_ON_FAILURE.""" + + self.RunAndVerify(env_var_value='0', + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value='0', + flag_value='1', + should_fail=True) + self.RunAndVerify(env_var_value='1', + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value='1', + flag_value='1', + should_fail=True) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_test_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_test_.cc new file mode 100644 index 0000000..2b88fe3 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_throw_on_failure_test_.cc @@ -0,0 +1,72 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests Google Test's throw-on-failure mode with exceptions disabled. +// +// This program must be compiled with exceptions disabled. It will be +// invoked by gtest_throw_on_failure_test.py, and is expected to exit +// with non-zero in the throw-on-failure mode or 0 otherwise. + +#include "gtest/gtest.h" + +#include // for fflush, fprintf, NULL, etc. +#include // for exit +#include // for set_terminate + +// This terminate handler aborts the program using exit() rather than abort(). +// This avoids showing pop-ups on Windows systems and core dumps on Unix-like +// ones. +void TerminateHandler() { + fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); + fflush(NULL); + exit(1); +} + +int main(int argc, char** argv) { +#if GTEST_HAS_EXCEPTIONS + std::set_terminate(&TerminateHandler); +#endif + testing::InitGoogleTest(&argc, argv); + + // We want to ensure that people can use Google Test assertions in + // other testing frameworks, as long as they initialize Google Test + // properly and set the throw-on-failure mode. Therefore, we don't + // use Google Test's constructs for defining and running tests + // (e.g. TEST and RUN_ALL_TESTS) here. + + // In the throw-on-failure mode with exceptions disabled, this + // assertion will cause the program to exit with a non-zero code. + EXPECT_EQ(2, 3); + + // When not in the throw-on-failure mode, the control will reach + // here. + return 0; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_uninitialized_test.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_uninitialized_test.py new file mode 100755 index 0000000..6ae57ee --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_uninitialized_test.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""Verifies that Google Test warns the user when not initialized properly.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils + + +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_') + + +def Assert(condition): + if not condition: + raise AssertionError + + +def AssertEq(expected, actual): + if expected != actual: + print 'Expected: %s' % (expected,) + print ' Actual: %s' % (actual,) + raise AssertionError + + +def TestExitCodeAndOutput(command): + """Runs the given command and verifies its exit code and output.""" + + # Verifies that 'command' exits with code 1. + p = gtest_test_utils.Subprocess(command) + Assert(p.exited) + AssertEq(1, p.exit_code) + Assert('InitGoogleTest' in p.output) + + +class GTestUninitializedTest(gtest_test_utils.TestCase): + def testExitCodeAndOutput(self): + TestExitCodeAndOutput(COMMAND) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_uninitialized_test_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_uninitialized_test_.cc new file mode 100644 index 0000000..4431698 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_uninitialized_test_.cc @@ -0,0 +1,43 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest.h" + +TEST(DummyTest, Dummy) { + // This test doesn't verify anything. We just need it to create a + // realistic stage for testing the behavior of Google Test when + // RUN_ALL_TESTS() is called without testing::InitGoogleTest() being + // called first. +} + +int main() { + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_unittest.cc new file mode 100644 index 0000000..f4f3043 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_unittest.cc @@ -0,0 +1,7240 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for Google Test itself. This verifies that the basic constructs of +// Google Test work. + +#include "gtest/gtest.h" + +// Verifies that the command line flag variables can be accessed +// in code once has been #included. +// Do not move it after other #includes. +TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { + bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) + || testing::GTEST_FLAG(break_on_failure) + || testing::GTEST_FLAG(catch_exceptions) + || testing::GTEST_FLAG(color) != "unknown" + || testing::GTEST_FLAG(filter) != "unknown" + || testing::GTEST_FLAG(list_tests) + || testing::GTEST_FLAG(output) != "unknown" + || testing::GTEST_FLAG(print_time) + || testing::GTEST_FLAG(random_seed) + || testing::GTEST_FLAG(repeat) > 0 + || testing::GTEST_FLAG(show_internal_stack_frames) + || testing::GTEST_FLAG(shuffle) + || testing::GTEST_FLAG(stack_trace_depth) > 0 + || testing::GTEST_FLAG(stream_result_to) != "unknown" + || testing::GTEST_FLAG(throw_on_failure); + EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. +} + +#include // For INT_MAX. +#include +#include +#include + +#include +#include +#include + +#include "gtest/gtest-spi.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +// Provides access to otherwise private parts of the TestEventListeners class +// that are needed to test it. +class TestEventListenersAccessor { + public: + static TestEventListener* GetRepeater(TestEventListeners* listeners) { + return listeners->repeater(); + } + + static void SetDefaultResultPrinter(TestEventListeners* listeners, + TestEventListener* listener) { + listeners->SetDefaultResultPrinter(listener); + } + static void SetDefaultXmlGenerator(TestEventListeners* listeners, + TestEventListener* listener) { + listeners->SetDefaultXmlGenerator(listener); + } + + static bool EventForwardingEnabled(const TestEventListeners& listeners) { + return listeners.EventForwardingEnabled(); + } + + static void SuppressEventForwarding(TestEventListeners* listeners) { + listeners->SuppressEventForwarding(); + } +}; + +} // namespace internal +} // namespace testing + +using testing::AssertionFailure; +using testing::AssertionResult; +using testing::AssertionSuccess; +using testing::DoubleLE; +using testing::EmptyTestEventListener; +using testing::FloatLE; +using testing::GTEST_FLAG(also_run_disabled_tests); +using testing::GTEST_FLAG(break_on_failure); +using testing::GTEST_FLAG(catch_exceptions); +using testing::GTEST_FLAG(color); +using testing::GTEST_FLAG(death_test_use_fork); +using testing::GTEST_FLAG(filter); +using testing::GTEST_FLAG(list_tests); +using testing::GTEST_FLAG(output); +using testing::GTEST_FLAG(print_time); +using testing::GTEST_FLAG(random_seed); +using testing::GTEST_FLAG(repeat); +using testing::GTEST_FLAG(show_internal_stack_frames); +using testing::GTEST_FLAG(shuffle); +using testing::GTEST_FLAG(stack_trace_depth); +using testing::GTEST_FLAG(stream_result_to); +using testing::GTEST_FLAG(throw_on_failure); +using testing::IsNotSubstring; +using testing::IsSubstring; +using testing::Message; +using testing::ScopedFakeTestPartResultReporter; +using testing::StaticAssertTypeEq; +using testing::Test; +using testing::TestCase; +using testing::TestEventListeners; +using testing::TestPartResult; +using testing::TestPartResultArray; +using testing::TestProperty; +using testing::TestResult; +using testing::TimeInMillis; +using testing::UnitTest; +using testing::kMaxStackTraceDepth; +using testing::internal::AddReference; +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; +using testing::internal::AppendUserMessage; +using testing::internal::ArrayAwareFind; +using testing::internal::ArrayEq; +using testing::internal::CodePointToUtf8; +using testing::internal::CompileAssertTypesEqual; +using testing::internal::CopyArray; +using testing::internal::CountIf; +using testing::internal::EqFailure; +using testing::internal::FloatingPoint; +using testing::internal::ForEach; +using testing::internal::FormatEpochTimeInMillisAsIso8601; +using testing::internal::FormatTimeInMillisAsSeconds; +using testing::internal::GTestFlagSaver; +using testing::internal::GetCurrentOsStackTraceExceptTop; +using testing::internal::GetElementOr; +using testing::internal::GetNextRandomSeed; +using testing::internal::GetRandomSeedFromFlag; +using testing::internal::GetTestTypeId; +using testing::internal::GetTimeInMillis; +using testing::internal::GetTypeId; +using testing::internal::GetUnitTestImpl; +using testing::internal::ImplicitlyConvertible; +using testing::internal::Int32; +using testing::internal::Int32FromEnvOrDie; +using testing::internal::IsAProtocolMessage; +using testing::internal::IsContainer; +using testing::internal::IsContainerTest; +using testing::internal::IsNotContainer; +using testing::internal::NativeArray; +using testing::internal::ParseInt32Flag; +using testing::internal::RemoveConst; +using testing::internal::RemoveReference; +using testing::internal::ShouldRunTestOnShard; +using testing::internal::ShouldShard; +using testing::internal::ShouldUseColor; +using testing::internal::Shuffle; +using testing::internal::ShuffleRange; +using testing::internal::SkipPrefix; +using testing::internal::StreamableToString; +using testing::internal::String; +using testing::internal::TestEventListenersAccessor; +using testing::internal::TestResultAccessor; +using testing::internal::UInt32; +using testing::internal::WideStringToUtf8; +using testing::internal::kCopy; +using testing::internal::kMaxRandomSeed; +using testing::internal::kReference; +using testing::internal::kTestTypeIdInGoogleTest; +using testing::internal::scoped_ptr; + +#if GTEST_HAS_STREAM_REDIRECTION +using testing::internal::CaptureStdout; +using testing::internal::GetCapturedStdout; +#endif + +#if GTEST_IS_THREADSAFE +using testing::internal::ThreadWithParam; +#endif + +class TestingVector : public std::vector { +}; + +::std::ostream& operator<<(::std::ostream& os, + const TestingVector& vector) { + os << "{ "; + for (size_t i = 0; i < vector.size(); i++) { + os << vector[i] << " "; + } + os << "}"; + return os; +} + +// This line tests that we can define tests in an unnamed namespace. +namespace { + +TEST(GetRandomSeedFromFlagTest, HandlesZero) { + const int seed = GetRandomSeedFromFlag(0); + EXPECT_LE(1, seed); + EXPECT_LE(seed, static_cast(kMaxRandomSeed)); +} + +TEST(GetRandomSeedFromFlagTest, PreservesValidSeed) { + EXPECT_EQ(1, GetRandomSeedFromFlag(1)); + EXPECT_EQ(2, GetRandomSeedFromFlag(2)); + EXPECT_EQ(kMaxRandomSeed - 1, GetRandomSeedFromFlag(kMaxRandomSeed - 1)); + EXPECT_EQ(static_cast(kMaxRandomSeed), + GetRandomSeedFromFlag(kMaxRandomSeed)); +} + +TEST(GetRandomSeedFromFlagTest, NormalizesInvalidSeed) { + const int seed1 = GetRandomSeedFromFlag(-1); + EXPECT_LE(1, seed1); + EXPECT_LE(seed1, static_cast(kMaxRandomSeed)); + + const int seed2 = GetRandomSeedFromFlag(kMaxRandomSeed + 1); + EXPECT_LE(1, seed2); + EXPECT_LE(seed2, static_cast(kMaxRandomSeed)); +} + +TEST(GetNextRandomSeedTest, WorksForValidInput) { + EXPECT_EQ(2, GetNextRandomSeed(1)); + EXPECT_EQ(3, GetNextRandomSeed(2)); + EXPECT_EQ(static_cast(kMaxRandomSeed), + GetNextRandomSeed(kMaxRandomSeed - 1)); + EXPECT_EQ(1, GetNextRandomSeed(kMaxRandomSeed)); + + // We deliberately don't test GetNextRandomSeed() with invalid + // inputs, as that requires death tests, which are expensive. This + // is fine as GetNextRandomSeed() is internal and has a + // straightforward definition. +} + +static void ClearCurrentTestPartResults() { + TestResultAccessor::ClearTestPartResults( + GetUnitTestImpl()->current_test_result()); +} + +// Tests GetTypeId. + +TEST(GetTypeIdTest, ReturnsSameValueForSameType) { + EXPECT_EQ(GetTypeId(), GetTypeId()); + EXPECT_EQ(GetTypeId(), GetTypeId()); +} + +class SubClassOfTest : public Test {}; +class AnotherSubClassOfTest : public Test {}; + +TEST(GetTypeIdTest, ReturnsDifferentValuesForDifferentTypes) { + EXPECT_NE(GetTypeId(), GetTypeId()); + EXPECT_NE(GetTypeId(), GetTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTypeId()); +} + +// Verifies that GetTestTypeId() returns the same value, no matter it +// is called from inside Google Test or outside of it. +TEST(GetTestTypeIdTest, ReturnsTheSameValueInsideOrOutsideOfGoogleTest) { + EXPECT_EQ(kTestTypeIdInGoogleTest, GetTestTypeId()); +} + +// Tests FormatTimeInMillisAsSeconds(). + +TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) { + EXPECT_EQ("0", FormatTimeInMillisAsSeconds(0)); +} + +TEST(FormatTimeInMillisAsSecondsTest, FormatsPositiveNumber) { + EXPECT_EQ("0.003", FormatTimeInMillisAsSeconds(3)); + EXPECT_EQ("0.01", FormatTimeInMillisAsSeconds(10)); + EXPECT_EQ("0.2", FormatTimeInMillisAsSeconds(200)); + EXPECT_EQ("1.2", FormatTimeInMillisAsSeconds(1200)); + EXPECT_EQ("3", FormatTimeInMillisAsSeconds(3000)); +} + +TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { + EXPECT_EQ("-0.003", FormatTimeInMillisAsSeconds(-3)); + EXPECT_EQ("-0.01", FormatTimeInMillisAsSeconds(-10)); + EXPECT_EQ("-0.2", FormatTimeInMillisAsSeconds(-200)); + EXPECT_EQ("-1.2", FormatTimeInMillisAsSeconds(-1200)); + EXPECT_EQ("-3", FormatTimeInMillisAsSeconds(-3000)); +} + +// Tests FormatEpochTimeInMillisAsIso8601(). The correctness of conversion +// for particular dates below was verified in Python using +// datetime.datetime.fromutctimestamp(/1000). + +// FormatEpochTimeInMillisAsIso8601 depends on the current timezone, so we +// have to set up a particular timezone to obtain predictable results. +class FormatEpochTimeInMillisAsIso8601Test : public Test { + public: + // On Cygwin, GCC doesn't allow unqualified integer literals to exceed + // 32 bits, even when 64-bit integer types are available. We have to + // force the constants to have a 64-bit type here. + static const TimeInMillis kMillisPerSec = 1000; + + private: + virtual void SetUp() { + saved_tz_ = NULL; +#if _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996 + // (function or variable may be unsafe + // for getenv, function is deprecated for + // strdup). + if (getenv("TZ")) + saved_tz_ = strdup(getenv("TZ")); +# pragma warning(pop) // Restores the warning state again. +#else + if (getenv("TZ")) + saved_tz_ = strdup(getenv("TZ")); +#endif + + // Set up the time zone for FormatEpochTimeInMillisAsIso8601 to use. We + // cannot use the local time zone because the function's output depends + // on the time zone. + SetTimeZone("UTC+00"); + } + + virtual void TearDown() { + SetTimeZone(saved_tz_); + free(const_cast(saved_tz_)); + saved_tz_ = NULL; + } + + static void SetTimeZone(const char* time_zone) { + // tzset() distinguishes between the TZ variable being present and empty + // and not being present, so we have to consider the case of time_zone + // being NULL. +#if _MSC_VER + // ...Unless it's MSVC, whose standard library's _putenv doesn't + // distinguish between an empty and a missing variable. + const std::string env_var = + std::string("TZ=") + (time_zone ? time_zone : ""); + _putenv(env_var.c_str()); +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996 + // (function is deprecated). + tzset(); +# pragma warning(pop) // Restores the warning state again. +#else + if (time_zone) { + setenv(("TZ"), time_zone, 1); + } else { + unsetenv("TZ"); + } + tzset(); +#endif + } + + const char* saved_tz_; +}; + +const TimeInMillis FormatEpochTimeInMillisAsIso8601Test::kMillisPerSec; + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsTwoDigitSegments) { + EXPECT_EQ("2011-10-31T18:52:42", + FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, MillisecondsDoNotAffectResult) { + EXPECT_EQ( + "2011-10-31T18:52:42", + FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec + 234)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsLeadingZeroes) { + EXPECT_EQ("2011-09-03T05:07:02", + FormatEpochTimeInMillisAsIso8601(1315026422 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, Prints24HourTime) { + EXPECT_EQ("2011-09-28T17:08:22", + FormatEpochTimeInMillisAsIso8601(1317229702 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsEpochStart) { + EXPECT_EQ("1970-01-01T00:00:00", FormatEpochTimeInMillisAsIso8601(0)); +} + +#if GTEST_CAN_COMPARE_NULL + +# ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +# endif + +// Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null +// pointer literal. +TEST(NullLiteralTest, IsTrueForNullLiterals) { + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(NULL)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L)); + +# ifndef __BORLANDC__ + + // Some compilers may fail to detect some null pointer literals; + // as long as users of the framework don't use such literals, this + // is harmless. + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1)); + +# endif +} + +// Tests that GTEST_IS_NULL_LITERAL_(x) is false when x is not a null +// pointer literal. +TEST(NullLiteralTest, IsFalseForNonNullLiterals) { + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(1)); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(0.0)); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_('a')); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast(NULL))); +} + +# ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" suppressed them. +# pragma option pop +# endif + +#endif // GTEST_CAN_COMPARE_NULL +// +// Tests CodePointToUtf8(). + +// Tests that the NUL character L'\0' is encoded correctly. +TEST(CodePointToUtf8Test, CanEncodeNul) { + char buffer[32]; + EXPECT_STREQ("", CodePointToUtf8(L'\0', buffer)); +} + +// Tests that ASCII characters are encoded correctly. +TEST(CodePointToUtf8Test, CanEncodeAscii) { + char buffer[32]; + EXPECT_STREQ("a", CodePointToUtf8(L'a', buffer)); + EXPECT_STREQ("Z", CodePointToUtf8(L'Z', buffer)); + EXPECT_STREQ("&", CodePointToUtf8(L'&', buffer)); + EXPECT_STREQ("\x7F", CodePointToUtf8(L'\x7F', buffer)); +} + +// Tests that Unicode code-points that have 8 to 11 bits are encoded +// as 110xxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode8To11Bits) { + char buffer[32]; + // 000 1101 0011 => 110-00011 10-010011 + EXPECT_STREQ("\xC3\x93", CodePointToUtf8(L'\xD3', buffer)); + + // 101 0111 0110 => 110-10101 10-110110 + // Some compilers (e.g., GCC on MinGW) cannot handle non-ASCII codepoints + // in wide strings and wide chars. In order to accomodate them, we have to + // introduce such character constants as integers. + EXPECT_STREQ("\xD5\xB6", + CodePointToUtf8(static_cast(0x576), buffer)); +} + +// Tests that Unicode code-points that have 12 to 16 bits are encoded +// as 1110xxxx 10xxxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode12To16Bits) { + char buffer[32]; + // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 + EXPECT_STREQ("\xE0\xA3\x93", + CodePointToUtf8(static_cast(0x8D3), buffer)); + + // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 + EXPECT_STREQ("\xEC\x9D\x8D", + CodePointToUtf8(static_cast(0xC74D), buffer)); +} + +#if !GTEST_WIDE_STRING_USES_UTF16_ +// Tests in this group require a wchar_t to hold > 16 bits, and thus +// are skipped on Windows, Cygwin, and Symbian, where a wchar_t is +// 16-bit wide. This code may not compile on those systems. + +// Tests that Unicode code-points that have 17 to 21 bits are encoded +// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode17To21Bits) { + char buffer[32]; + // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 + EXPECT_STREQ("\xF0\x90\xA3\x93", CodePointToUtf8(L'\x108D3', buffer)); + + // 0 0001 0000 0100 0000 0000 => 11110-000 10-010000 10-010000 10-000000 + EXPECT_STREQ("\xF0\x90\x90\x80", CodePointToUtf8(L'\x10400', buffer)); + + // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 + EXPECT_STREQ("\xF4\x88\x98\xB4", CodePointToUtf8(L'\x108634', buffer)); +} + +// Tests that encoding an invalid code-point generates the expected result. +TEST(CodePointToUtf8Test, CanEncodeInvalidCodePoint) { + char buffer[32]; + EXPECT_STREQ("(Invalid Unicode 0x1234ABCD)", + CodePointToUtf8(L'\x1234ABCD', buffer)); +} + +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests WideStringToUtf8(). + +// Tests that the NUL character L'\0' is encoded correctly. +TEST(WideStringToUtf8Test, CanEncodeNul) { + EXPECT_STREQ("", WideStringToUtf8(L"", 0).c_str()); + EXPECT_STREQ("", WideStringToUtf8(L"", -1).c_str()); +} + +// Tests that ASCII strings are encoded correctly. +TEST(WideStringToUtf8Test, CanEncodeAscii) { + EXPECT_STREQ("a", WideStringToUtf8(L"a", 1).c_str()); + EXPECT_STREQ("ab", WideStringToUtf8(L"ab", 2).c_str()); + EXPECT_STREQ("a", WideStringToUtf8(L"a", -1).c_str()); + EXPECT_STREQ("ab", WideStringToUtf8(L"ab", -1).c_str()); +} + +// Tests that Unicode code-points that have 8 to 11 bits are encoded +// as 110xxxxx 10xxxxxx. +TEST(WideStringToUtf8Test, CanEncode8To11Bits) { + // 000 1101 0011 => 110-00011 10-010011 + EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", 1).c_str()); + EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", -1).c_str()); + + // 101 0111 0110 => 110-10101 10-110110 + const wchar_t s[] = { 0x576, '\0' }; + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, 1).c_str()); + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, -1).c_str()); +} + +// Tests that Unicode code-points that have 12 to 16 bits are encoded +// as 1110xxxx 10xxxxxx 10xxxxxx. +TEST(WideStringToUtf8Test, CanEncode12To16Bits) { + // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 + const wchar_t s1[] = { 0x8D3, '\0' }; + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, 1).c_str()); + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, -1).c_str()); + + // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 + const wchar_t s2[] = { 0xC74D, '\0' }; + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, 1).c_str()); + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, -1).c_str()); +} + +// Tests that the conversion stops when the function encounters \0 character. +TEST(WideStringToUtf8Test, StopsOnNulCharacter) { + EXPECT_STREQ("ABC", WideStringToUtf8(L"ABC\0XYZ", 100).c_str()); +} + +// Tests that the conversion stops when the function reaches the limit +// specified by the 'length' parameter. +TEST(WideStringToUtf8Test, StopsWhenLengthLimitReached) { + EXPECT_STREQ("ABC", WideStringToUtf8(L"ABCDEF", 3).c_str()); +} + +#if !GTEST_WIDE_STRING_USES_UTF16_ +// Tests that Unicode code-points that have 17 to 21 bits are encoded +// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. This code may not compile +// on the systems using UTF-16 encoding. +TEST(WideStringToUtf8Test, CanEncode17To21Bits) { + // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 + EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", 1).c_str()); + EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", -1).c_str()); + + // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 + EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", 1).c_str()); + EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", -1).c_str()); +} + +// Tests that encoding an invalid code-point generates the expected result. +TEST(WideStringToUtf8Test, CanEncodeInvalidCodePoint) { + EXPECT_STREQ("(Invalid Unicode 0xABCDFF)", + WideStringToUtf8(L"\xABCDFF", -1).c_str()); +} +#else // !GTEST_WIDE_STRING_USES_UTF16_ +// Tests that surrogate pairs are encoded correctly on the systems using +// UTF-16 encoding in the wide strings. +TEST(WideStringToUtf8Test, CanEncodeValidUtf16SUrrogatePairs) { + const wchar_t s[] = { 0xD801, 0xDC00, '\0' }; + EXPECT_STREQ("\xF0\x90\x90\x80", WideStringToUtf8(s, -1).c_str()); +} + +// Tests that encoding an invalid UTF-16 surrogate pair +// generates the expected result. +TEST(WideStringToUtf8Test, CanEncodeInvalidUtf16SurrogatePair) { + // Leading surrogate is at the end of the string. + const wchar_t s1[] = { 0xD800, '\0' }; + EXPECT_STREQ("\xED\xA0\x80", WideStringToUtf8(s1, -1).c_str()); + // Leading surrogate is not followed by the trailing surrogate. + const wchar_t s2[] = { 0xD800, 'M', '\0' }; + EXPECT_STREQ("\xED\xA0\x80M", WideStringToUtf8(s2, -1).c_str()); + // Trailing surrogate appearas without a leading surrogate. + const wchar_t s3[] = { 0xDC00, 'P', 'Q', 'R', '\0' }; + EXPECT_STREQ("\xED\xB0\x80PQR", WideStringToUtf8(s3, -1).c_str()); +} +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests that codepoint concatenation works correctly. +#if !GTEST_WIDE_STRING_USES_UTF16_ +TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + const wchar_t s[] = { 0x108634, 0xC74D, '\n', 0x576, 0x8D3, 0x108634, '\0'}; + EXPECT_STREQ( + "\xF4\x88\x98\xB4" + "\xEC\x9D\x8D" + "\n" + "\xD5\xB6" + "\xE0\xA3\x93" + "\xF4\x88\x98\xB4", + WideStringToUtf8(s, -1).c_str()); +} +#else +TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + const wchar_t s[] = { 0xC74D, '\n', 0x576, 0x8D3, '\0'}; + EXPECT_STREQ( + "\xEC\x9D\x8D" "\n" "\xD5\xB6" "\xE0\xA3\x93", + WideStringToUtf8(s, -1).c_str()); +} +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests the Random class. + +TEST(RandomDeathTest, GeneratesCrashesOnInvalidRange) { + testing::internal::Random random(42); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(0), + "Cannot generate a number in the range \\[0, 0\\)"); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(testing::internal::Random::kMaxRange + 1), + "Generation of a number in \\[0, 2147483649\\) was requested, " + "but this can only generate numbers in \\[0, 2147483648\\)"); +} + +TEST(RandomTest, GeneratesNumbersWithinRange) { + const UInt32 kRange = 10000; + testing::internal::Random random(12345); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random.Generate(kRange), kRange) << " for iteration " << i; + } + + testing::internal::Random random2(testing::internal::Random::kMaxRange); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random2.Generate(kRange), kRange) << " for iteration " << i; + } +} + +TEST(RandomTest, RepeatsWhenReseeded) { + const int kSeed = 123; + const int kArraySize = 10; + const UInt32 kRange = 10000; + UInt32 values[kArraySize]; + + testing::internal::Random random(kSeed); + for (int i = 0; i < kArraySize; i++) { + values[i] = random.Generate(kRange); + } + + random.Reseed(kSeed); + for (int i = 0; i < kArraySize; i++) { + EXPECT_EQ(values[i], random.Generate(kRange)) << " for iteration " << i; + } +} + +// Tests STL container utilities. + +// Tests CountIf(). + +static bool IsPositive(int n) { return n > 0; } + +TEST(ContainerUtilityTest, CountIf) { + std::vector v; + EXPECT_EQ(0, CountIf(v, IsPositive)); // Works for an empty container. + + v.push_back(-1); + v.push_back(0); + EXPECT_EQ(0, CountIf(v, IsPositive)); // Works when no value satisfies. + + v.push_back(2); + v.push_back(-10); + v.push_back(10); + EXPECT_EQ(2, CountIf(v, IsPositive)); +} + +// Tests ForEach(). + +static int g_sum = 0; +static void Accumulate(int n) { g_sum += n; } + +TEST(ContainerUtilityTest, ForEach) { + std::vector v; + g_sum = 0; + ForEach(v, Accumulate); + EXPECT_EQ(0, g_sum); // Works for an empty container; + + g_sum = 0; + v.push_back(1); + ForEach(v, Accumulate); + EXPECT_EQ(1, g_sum); // Works for a container with one element. + + g_sum = 0; + v.push_back(20); + v.push_back(300); + ForEach(v, Accumulate); + EXPECT_EQ(321, g_sum); +} + +// Tests GetElementOr(). +TEST(ContainerUtilityTest, GetElementOr) { + std::vector a; + EXPECT_EQ('x', GetElementOr(a, 0, 'x')); + + a.push_back('a'); + a.push_back('b'); + EXPECT_EQ('a', GetElementOr(a, 0, 'x')); + EXPECT_EQ('b', GetElementOr(a, 1, 'x')); + EXPECT_EQ('x', GetElementOr(a, -2, 'x')); + EXPECT_EQ('x', GetElementOr(a, 2, 'x')); +} + +TEST(ContainerUtilityDeathTest, ShuffleRange) { + std::vector a; + a.push_back(0); + a.push_back(1); + a.push_back(2); + testing::internal::Random random(1); + + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, -1, 1, &a), + "Invalid shuffle range start -1: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 4, 4, &a), + "Invalid shuffle range start 4: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 3, 2, &a), + "Invalid shuffle range finish 2: must be in range \\[3, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 3, 4, &a), + "Invalid shuffle range finish 4: must be in range \\[3, 3\\]"); +} + +class VectorShuffleTest : public Test { + protected: + static const int kVectorSize = 20; + + VectorShuffleTest() : random_(1) { + for (int i = 0; i < kVectorSize; i++) { + vector_.push_back(i); + } + } + + static bool VectorIsCorrupt(const TestingVector& vector) { + if (kVectorSize != static_cast(vector.size())) { + return true; + } + + bool found_in_vector[kVectorSize] = { false }; + for (size_t i = 0; i < vector.size(); i++) { + const int e = vector[i]; + if (e < 0 || e >= kVectorSize || found_in_vector[e]) { + return true; + } + found_in_vector[e] = true; + } + + // Vector size is correct, elements' range is correct, no + // duplicate elements. Therefore no corruption has occurred. + return false; + } + + static bool VectorIsNotCorrupt(const TestingVector& vector) { + return !VectorIsCorrupt(vector); + } + + static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) { + for (int i = begin; i < end; i++) { + if (i != vector[i]) { + return true; + } + } + return false; + } + + static bool RangeIsUnshuffled( + const TestingVector& vector, int begin, int end) { + return !RangeIsShuffled(vector, begin, end); + } + + static bool VectorIsShuffled(const TestingVector& vector) { + return RangeIsShuffled(vector, 0, static_cast(vector.size())); + } + + static bool VectorIsUnshuffled(const TestingVector& vector) { + return !VectorIsShuffled(vector); + } + + testing::internal::Random random_; + TestingVector vector_; +}; // class VectorShuffleTest + +const int VectorShuffleTest::kVectorSize; + +TEST_F(VectorShuffleTest, HandlesEmptyRange) { + // Tests an empty range at the beginning... + ShuffleRange(&random_, 0, 0, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + ShuffleRange(&random_, kVectorSize/2, kVectorSize/2, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...at the end... + ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and past the end. + ShuffleRange(&random_, kVectorSize, kVectorSize, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) { + // Tests a size one range at the beginning... + ShuffleRange(&random_, 0, 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and at the end. + ShuffleRange(&random_, kVectorSize - 1, kVectorSize, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +// Because we use our own random number generator and a fixed seed, +// we can guarantee that the following "random" tests will succeed. + +TEST_F(VectorShuffleTest, ShufflesEntireVector) { + Shuffle(&random_, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_; + + // Tests the first and last elements in particular to ensure that + // there are no off-by-one problems in our shuffle algorithm. + EXPECT_NE(0, vector_[0]); + EXPECT_NE(kVectorSize - 1, vector_[kVectorSize - 1]); +} + +TEST_F(VectorShuffleTest, ShufflesStartOfVector) { + const int kRangeSize = kVectorSize/2; + + ShuffleRange(&random_, 0, kRangeSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesEndOfVector) { + const int kRangeSize = kVectorSize / 2; + ShuffleRange(&random_, kRangeSize, kVectorSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) { + int kRangeSize = kVectorSize/3; + ShuffleRange(&random_, kRangeSize, 2*kRangeSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, 2*kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 2*kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesRepeatably) { + TestingVector vector2; + for (int i = 0; i < kVectorSize; i++) { + vector2.push_back(i); + } + + random_.Reseed(1234); + Shuffle(&random_, &vector_); + random_.Reseed(1234); + Shuffle(&random_, &vector2); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector2); + + for (int i = 0; i < kVectorSize; i++) { + EXPECT_EQ(vector_[i], vector2[i]) << " where i is " << i; + } +} + +// Tests the size of the AssertHelper class. + +TEST(AssertHelperTest, AssertHelperIsSmall) { + // To avoid breaking clients that use lots of assertions in one + // function, we cannot grow the size of AssertHelper. + EXPECT_LE(sizeof(testing::internal::AssertHelper), sizeof(void*)); +} + +// Tests String::EndsWithCaseInsensitive(). +TEST(StringTest, EndsWithCaseInsensitive) { + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "BAR")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobaR", "bar")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("", "")); + + EXPECT_FALSE(String::EndsWithCaseInsensitive("Foobar", "foo")); + EXPECT_FALSE(String::EndsWithCaseInsensitive("foobar", "Foo")); + EXPECT_FALSE(String::EndsWithCaseInsensitive("", "foo")); +} + +// C++Builder's preprocessor is buggy; it fails to expand macros that +// appear in macro parameters after wide char literals. Provide an alias +// for NULL as a workaround. +static const wchar_t* const kNull = NULL; + +// Tests String::CaseInsensitiveWideCStringEquals +TEST(StringTest, CaseInsensitiveWideCStringEquals) { + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(NULL, NULL)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", kNull)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"foobar")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", kNull)); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"foobar")); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"FOOBAR")); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar")); +} + +// Tests that String::Format() works. +TEST(StringTest, FormatWorks) { + // Normal case: the format spec is valid, the arguments match the + // spec, and the result is < 4095 characters. + EXPECT_STREQ("Hello, 42", String::Format("%s, %d", "Hello", 42).c_str()); + + // Edge case: the result is 4095 characters. + char buffer[4096]; + const size_t kSize = sizeof(buffer); + memset(buffer, 'a', kSize - 1); + buffer[kSize - 1] = '\0'; + EXPECT_EQ(buffer, String::Format("%s", buffer)); + + // The result needs to be 4096 characters, exceeding Format()'s limit. + EXPECT_EQ("", + String::Format("x%s", buffer)); + +#if GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID + // On Linux, invalid format spec should lead to an error message. + // In other environment (e.g. MSVC on Windows), String::Format() may + // simply ignore a bad format spec, so this assertion is run on + // Linux only. + EXPECT_EQ("", + String::Format("%")); +#endif +} + +#if GTEST_OS_WINDOWS + +// Tests String::ShowWideCString(). +TEST(StringTest, ShowWideCString) { + EXPECT_STREQ("(null)", + String::ShowWideCString(NULL).c_str()); + EXPECT_STREQ("", String::ShowWideCString(L"").c_str()); + EXPECT_STREQ("foo", String::ShowWideCString(L"foo").c_str()); +} + +# if GTEST_OS_WINDOWS_MOBILE +TEST(StringTest, AnsiAndUtf16Null) { + EXPECT_EQ(NULL, String::AnsiToUtf16(NULL)); + EXPECT_EQ(NULL, String::Utf16ToAnsi(NULL)); +} + +TEST(StringTest, AnsiAndUtf16ConvertBasic) { + const char* ansi = String::Utf16ToAnsi(L"str"); + EXPECT_STREQ("str", ansi); + delete [] ansi; + const WCHAR* utf16 = String::AnsiToUtf16("str"); + EXPECT_EQ(0, wcsncmp(L"str", utf16, 3)); + delete [] utf16; +} + +TEST(StringTest, AnsiAndUtf16ConvertPathChars) { + const char* ansi = String::Utf16ToAnsi(L".:\\ \"*?"); + EXPECT_STREQ(".:\\ \"*?", ansi); + delete [] ansi; + const WCHAR* utf16 = String::AnsiToUtf16(".:\\ \"*?"); + EXPECT_EQ(0, wcsncmp(L".:\\ \"*?", utf16, 3)); + delete [] utf16; +} +# endif // GTEST_OS_WINDOWS_MOBILE + +#endif // GTEST_OS_WINDOWS + +// Tests TestProperty construction. +TEST(TestPropertyTest, StringValue) { + TestProperty property("key", "1"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("1", property.value()); +} + +// Tests TestProperty replacing a value. +TEST(TestPropertyTest, ReplaceStringValue) { + TestProperty property("key", "1"); + EXPECT_STREQ("1", property.value()); + property.SetValue("2"); + EXPECT_STREQ("2", property.value()); +} + +// AddFatalFailure() and AddNonfatalFailure() must be stand-alone +// functions (i.e. their definitions cannot be inlined at the call +// sites), or C++Builder won't compile the code. +static void AddFatalFailure() { + FAIL() << "Expected fatal failure."; +} + +static void AddNonfatalFailure() { + ADD_FAILURE() << "Expected non-fatal failure."; +} + +class ScopedFakeTestPartResultReporterTest : public Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + enum FailureMode { + FATAL_FAILURE, + NONFATAL_FAILURE + }; + static void AddFailure(FailureMode failure) { + if (failure == FATAL_FAILURE) { + AddFatalFailure(); + } else { + AddNonfatalFailure(); + } + } +}; + +// Tests that ScopedFakeTestPartResultReporter intercepts test +// failures. +TEST_F(ScopedFakeTestPartResultReporterTest, InterceptsTestFailures) { + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, + &results); + AddFailure(NONFATAL_FAILURE); + AddFailure(FATAL_FAILURE); + } + + EXPECT_EQ(2, results.size()); + EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); +} + +TEST_F(ScopedFakeTestPartResultReporterTest, DeprecatedConstructor) { + TestPartResultArray results; + { + // Tests, that the deprecated constructor still works. + ScopedFakeTestPartResultReporter reporter(&results); + AddFailure(NONFATAL_FAILURE); + } + EXPECT_EQ(1, results.size()); +} + +#if GTEST_IS_THREADSAFE + +class ScopedFakeTestPartResultReporterWithThreadsTest + : public ScopedFakeTestPartResultReporterTest { + protected: + static void AddFailureInOtherThread(FailureMode failure) { + ThreadWithParam thread(&AddFailure, failure, NULL); + thread.Join(); + } +}; + +TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest, + InterceptsTestFailuresInAllThreads) { + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, &results); + AddFailure(NONFATAL_FAILURE); + AddFailure(FATAL_FAILURE); + AddFailureInOtherThread(NONFATAL_FAILURE); + AddFailureInOtherThread(FATAL_FAILURE); + } + + EXPECT_EQ(4, results.size()); + EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(2).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(3).fatally_failed()); +} + +#endif // GTEST_IS_THREADSAFE + +// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. Makes sure that they +// work even if the failure is generated in a called function rather than +// the current context. + +typedef ScopedFakeTestPartResultReporterTest ExpectFatalFailureTest; + +TEST_F(ExpectFatalFailureTest, CatchesFatalFaliure) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), "Expected fatal failure."); +} + +#if GTEST_HAS_GLOBAL_STRING +TEST_F(ExpectFatalFailureTest, AcceptsStringObject) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), ::string("Expected fatal failure.")); +} +#endif + +TEST_F(ExpectFatalFailureTest, AcceptsStdStringObject) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), + ::std::string("Expected fatal failure.")); +} + +TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches fatal + // failures generated on another thread. + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFatalFailure(), + "Expected fatal failure."); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true" +# pragma option push -w-ccc +#endif + +// Tests that EXPECT_FATAL_FAILURE() can be used in a non-void +// function even when the statement in it contains ASSERT_*. + +int NonVoidFunction() { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + return 0; +} + +TEST_F(ExpectFatalFailureTest, CanBeUsedInNonVoidFunction) { + NonVoidFunction(); +} + +// Tests that EXPECT_FATAL_FAILURE(statement, ...) doesn't abort the +// current function even though 'statement' generates a fatal failure. + +void DoesNotAbortHelper(bool* aborted) { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + + *aborted = false; +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" suppressed them. +# pragma option pop +#endif + +TEST_F(ExpectFatalFailureTest, DoesNotAbort) { + bool aborted = true; + DoesNotAbortHelper(&aborted); + EXPECT_FALSE(aborted); +} + +// Tests that the EXPECT_FATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. + +static int global_var = 0; +#define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ + +TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFatalFailure(); + }, ""); +#endif + + EXPECT_FATAL_FAILURE_ON_ALL_THREADS({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFatalFailure(); + }, ""); +} + +// Tests EXPECT_NONFATAL_FAILURE{,ON_ALL_THREADS}. + +typedef ScopedFakeTestPartResultReporterTest ExpectNonfatalFailureTest; + +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailure) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + "Expected non-fatal failure."); +} + +#if GTEST_HAS_GLOBAL_STRING +TEST_F(ExpectNonfatalFailureTest, AcceptsStringObject) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + ::string("Expected non-fatal failure.")); +} +#endif + +TEST_F(ExpectNonfatalFailureTest, AcceptsStdStringObject) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + ::std::string("Expected non-fatal failure.")); +} + +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches + // non-fatal failures generated on another thread. + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddNonfatalFailure(), + "Expected non-fatal failure."); +} + +// Tests that the EXPECT_NONFATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. +TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { + EXPECT_NONFATAL_FAILURE({ + GTEST_USE_UNPROTECTED_COMMA_; + AddNonfatalFailure(); + }, ""); + + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS({ + GTEST_USE_UNPROTECTED_COMMA_; + AddNonfatalFailure(); + }, ""); +} + +#if GTEST_IS_THREADSAFE + +typedef ScopedFakeTestPartResultReporterWithThreadsTest + ExpectFailureWithThreadsTest; + +TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailureOnAllThreads) { + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailureInOtherThread(FATAL_FAILURE), + "Expected fatal failure."); +} + +TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) { + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( + AddFailureInOtherThread(NONFATAL_FAILURE), "Expected non-fatal failure."); +} + +#endif // GTEST_IS_THREADSAFE + +// Tests the TestProperty class. + +TEST(TestPropertyTest, ConstructorWorks) { + const TestProperty property("key", "value"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value", property.value()); +} + +TEST(TestPropertyTest, SetValue) { + TestProperty property("key", "value_1"); + EXPECT_STREQ("key", property.key()); + property.SetValue("value_2"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value_2", property.value()); +} + +// Tests the TestResult class + +// The test fixture for testing TestResult. +class TestResultTest : public Test { + protected: + typedef std::vector TPRVector; + + // We make use of 2 TestPartResult objects, + TestPartResult * pr1, * pr2; + + // ... and 3 TestResult objects. + TestResult * r0, * r1, * r2; + + virtual void SetUp() { + // pr1 is for success. + pr1 = new TestPartResult(TestPartResult::kSuccess, + "foo/bar.cc", + 10, + "Success!"); + + // pr2 is for fatal failure. + pr2 = new TestPartResult(TestPartResult::kFatalFailure, + "foo/bar.cc", + -1, // This line number means "unknown" + "Failure!"); + + // Creates the TestResult objects. + r0 = new TestResult(); + r1 = new TestResult(); + r2 = new TestResult(); + + // In order to test TestResult, we need to modify its internal + // state, in particular the TestPartResult vector it holds. + // test_part_results() returns a const reference to this vector. + // We cast it to a non-const object s.t. it can be modified (yes, + // this is a hack). + TPRVector* results1 = const_cast( + &TestResultAccessor::test_part_results(*r1)); + TPRVector* results2 = const_cast( + &TestResultAccessor::test_part_results(*r2)); + + // r0 is an empty TestResult. + + // r1 contains a single SUCCESS TestPartResult. + results1->push_back(*pr1); + + // r2 contains a SUCCESS, and a FAILURE. + results2->push_back(*pr1); + results2->push_back(*pr2); + } + + virtual void TearDown() { + delete pr1; + delete pr2; + + delete r0; + delete r1; + delete r2; + } + + // Helper that compares two two TestPartResults. + static void CompareTestPartResult(const TestPartResult& expected, + const TestPartResult& actual) { + EXPECT_EQ(expected.type(), actual.type()); + EXPECT_STREQ(expected.file_name(), actual.file_name()); + EXPECT_EQ(expected.line_number(), actual.line_number()); + EXPECT_STREQ(expected.summary(), actual.summary()); + EXPECT_STREQ(expected.message(), actual.message()); + EXPECT_EQ(expected.passed(), actual.passed()); + EXPECT_EQ(expected.failed(), actual.failed()); + EXPECT_EQ(expected.nonfatally_failed(), actual.nonfatally_failed()); + EXPECT_EQ(expected.fatally_failed(), actual.fatally_failed()); + } +}; + +// Tests TestResult::total_part_count(). +TEST_F(TestResultTest, total_part_count) { + ASSERT_EQ(0, r0->total_part_count()); + ASSERT_EQ(1, r1->total_part_count()); + ASSERT_EQ(2, r2->total_part_count()); +} + +// Tests TestResult::Passed(). +TEST_F(TestResultTest, Passed) { + ASSERT_TRUE(r0->Passed()); + ASSERT_TRUE(r1->Passed()); + ASSERT_FALSE(r2->Passed()); +} + +// Tests TestResult::Failed(). +TEST_F(TestResultTest, Failed) { + ASSERT_FALSE(r0->Failed()); + ASSERT_FALSE(r1->Failed()); + ASSERT_TRUE(r2->Failed()); +} + +// Tests TestResult::GetTestPartResult(). + +typedef TestResultTest TestResultDeathTest; + +TEST_F(TestResultDeathTest, GetTestPartResult) { + CompareTestPartResult(*pr1, r2->GetTestPartResult(0)); + CompareTestPartResult(*pr2, r2->GetTestPartResult(1)); + EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(2), ""); + EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(-1), ""); +} + +// Tests TestResult has no properties when none are added. +TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) { + TestResult test_result; + ASSERT_EQ(0, test_result.test_property_count()); +} + +// Tests TestResult has the expected property when added. +TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) { + TestResult test_result; + TestProperty property("key_1", "1"); + TestResultAccessor::RecordProperty(&test_result, property); + ASSERT_EQ(1, test_result.test_property_count()); + const TestProperty& actual_property = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property.key()); + EXPECT_STREQ("1", actual_property.value()); +} + +// Tests TestResult has multiple properties when added. +TEST(TestResultPropertyTest, MultiplePropertiesFoundWhenAdded) { + TestResult test_result; + TestProperty property_1("key_1", "1"); + TestProperty property_2("key_2", "2"); + TestResultAccessor::RecordProperty(&test_result, property_1); + TestResultAccessor::RecordProperty(&test_result, property_2); + ASSERT_EQ(2, test_result.test_property_count()); + const TestProperty& actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("1", actual_property_1.value()); + + const TestProperty& actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("2", actual_property_2.value()); +} + +// Tests TestResult::RecordProperty() overrides values for duplicate keys. +TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { + TestResult test_result; + TestProperty property_1_1("key_1", "1"); + TestProperty property_2_1("key_2", "2"); + TestProperty property_1_2("key_1", "12"); + TestProperty property_2_2("key_2", "22"); + TestResultAccessor::RecordProperty(&test_result, property_1_1); + TestResultAccessor::RecordProperty(&test_result, property_2_1); + TestResultAccessor::RecordProperty(&test_result, property_1_2); + TestResultAccessor::RecordProperty(&test_result, property_2_2); + + ASSERT_EQ(2, test_result.test_property_count()); + const TestProperty& actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("12", actual_property_1.value()); + + const TestProperty& actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("22", actual_property_2.value()); +} + +// Tests TestResult::GetTestProperty(). +TEST(TestResultPropertyDeathTest, GetTestProperty) { + TestResult test_result; + TestProperty property_1("key_1", "1"); + TestProperty property_2("key_2", "2"); + TestProperty property_3("key_3", "3"); + TestResultAccessor::RecordProperty(&test_result, property_1); + TestResultAccessor::RecordProperty(&test_result, property_2); + TestResultAccessor::RecordProperty(&test_result, property_3); + + const TestProperty& fetched_property_1 = test_result.GetTestProperty(0); + const TestProperty& fetched_property_2 = test_result.GetTestProperty(1); + const TestProperty& fetched_property_3 = test_result.GetTestProperty(2); + + EXPECT_STREQ("key_1", fetched_property_1.key()); + EXPECT_STREQ("1", fetched_property_1.value()); + + EXPECT_STREQ("key_2", fetched_property_2.key()); + EXPECT_STREQ("2", fetched_property_2.value()); + + EXPECT_STREQ("key_3", fetched_property_3.key()); + EXPECT_STREQ("3", fetched_property_3.value()); + + EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(3), ""); + EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), ""); +} + +// When a property using a reserved key is supplied to this function, it tests +// that a non-fatal failure is added, a fatal failure is not added, and that the +// property is not recorded. +void ExpectNonFatalFailureRecordingPropertyWithReservedKey(const char* key) { + TestResult test_result; + TestProperty property(key, "1"); + EXPECT_NONFATAL_FAILURE( + TestResultAccessor::RecordProperty(&test_result, property), + "Reserved key"); + ASSERT_EQ(0, test_result.test_property_count()) << "Not recorded"; +} + +// Attempting to recording a property with the Reserved literal "name" +// should add a non-fatal failure and the property should not be recorded. +TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledName) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey("name"); +} + +// Attempting to recording a property with the Reserved literal "status" +// should add a non-fatal failure and the property should not be recorded. +TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledStatus) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey("status"); +} + +// Attempting to recording a property with the Reserved literal "time" +// should add a non-fatal failure and the property should not be recorded. +TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledTime) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey("time"); +} + +// Attempting to recording a property with the Reserved literal "classname" +// should add a non-fatal failure and the property should not be recorded. +TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledClassname) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey("classname"); +} + +// Tests that GTestFlagSaver works on Windows and Mac. + +class GTestFlagSaverTest : public Test { + protected: + // Saves the Google Test flags such that we can restore them later, and + // then sets them to their default values. This will be called + // before the first test in this test case is run. + static void SetUpTestCase() { + saver_ = new GTestFlagSaver; + + GTEST_FLAG(also_run_disabled_tests) = false; + GTEST_FLAG(break_on_failure) = false; + GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(death_test_use_fork) = false; + GTEST_FLAG(color) = "auto"; + GTEST_FLAG(filter) = ""; + GTEST_FLAG(list_tests) = false; + GTEST_FLAG(output) = ""; + GTEST_FLAG(print_time) = true; + GTEST_FLAG(random_seed) = 0; + GTEST_FLAG(repeat) = 1; + GTEST_FLAG(shuffle) = false; + GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; + GTEST_FLAG(stream_result_to) = ""; + GTEST_FLAG(throw_on_failure) = false; + } + + // Restores the Google Test flags that the tests have modified. This will + // be called after the last test in this test case is run. + static void TearDownTestCase() { + delete saver_; + saver_ = NULL; + } + + // Verifies that the Google Test flags have their default values, and then + // modifies each of them. + void VerifyAndModifyFlags() { + EXPECT_FALSE(GTEST_FLAG(also_run_disabled_tests)); + EXPECT_FALSE(GTEST_FLAG(break_on_failure)); + EXPECT_FALSE(GTEST_FLAG(catch_exceptions)); + EXPECT_STREQ("auto", GTEST_FLAG(color).c_str()); + EXPECT_FALSE(GTEST_FLAG(death_test_use_fork)); + EXPECT_STREQ("", GTEST_FLAG(filter).c_str()); + EXPECT_FALSE(GTEST_FLAG(list_tests)); + EXPECT_STREQ("", GTEST_FLAG(output).c_str()); + EXPECT_TRUE(GTEST_FLAG(print_time)); + EXPECT_EQ(0, GTEST_FLAG(random_seed)); + EXPECT_EQ(1, GTEST_FLAG(repeat)); + EXPECT_FALSE(GTEST_FLAG(shuffle)); + EXPECT_EQ(kMaxStackTraceDepth, GTEST_FLAG(stack_trace_depth)); + EXPECT_STREQ("", GTEST_FLAG(stream_result_to).c_str()); + EXPECT_FALSE(GTEST_FLAG(throw_on_failure)); + + GTEST_FLAG(also_run_disabled_tests) = true; + GTEST_FLAG(break_on_failure) = true; + GTEST_FLAG(catch_exceptions) = true; + GTEST_FLAG(color) = "no"; + GTEST_FLAG(death_test_use_fork) = true; + GTEST_FLAG(filter) = "abc"; + GTEST_FLAG(list_tests) = true; + GTEST_FLAG(output) = "xml:foo.xml"; + GTEST_FLAG(print_time) = false; + GTEST_FLAG(random_seed) = 1; + GTEST_FLAG(repeat) = 100; + GTEST_FLAG(shuffle) = true; + GTEST_FLAG(stack_trace_depth) = 1; + GTEST_FLAG(stream_result_to) = "localhost:1234"; + GTEST_FLAG(throw_on_failure) = true; + } + + private: + // For saving Google Test flags during this test case. + static GTestFlagSaver* saver_; +}; + +GTestFlagSaver* GTestFlagSaverTest::saver_ = NULL; + +// Google Test doesn't guarantee the order of tests. The following two +// tests are designed to work regardless of their order. + +// Modifies the Google Test flags in the test body. +TEST_F(GTestFlagSaverTest, ModifyGTestFlags) { + VerifyAndModifyFlags(); +} + +// Verifies that the Google Test flags in the body of the previous test were +// restored to their original values. +TEST_F(GTestFlagSaverTest, VerifyGTestFlags) { + VerifyAndModifyFlags(); +} + +// Sets an environment variable with the given name to the given +// value. If the value argument is "", unsets the environment +// variable. The caller must ensure that both arguments are not NULL. +static void SetEnv(const char* name, const char* value) { +#if GTEST_OS_WINDOWS_MOBILE + // Environment variables are not supported on Windows CE. + return; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // C++Builder's putenv only stores a pointer to its parameter; we have to + // ensure that the string remains valid as long as it might be needed. + // We use an std::map to do so. + static std::map added_env; + + // Because putenv stores a pointer to the string buffer, we can't delete the + // previous string (if present) until after it's replaced. + std::string *prev_env = NULL; + if (added_env.find(name) != added_env.end()) { + prev_env = added_env[name]; + } + added_env[name] = new std::string( + (Message() << name << "=" << value).GetString()); + + // The standard signature of putenv accepts a 'char*' argument. Other + // implementations, like C++Builder's, accept a 'const char*'. + // We cast away the 'const' since that would work for both variants. + putenv(const_cast(added_env[name]->c_str())); + delete prev_env; +#elif GTEST_OS_WINDOWS // If we are on Windows proper. + _putenv((Message() << name << "=" << value).GetString().c_str()); +#else + if (*value == '\0') { + unsetenv(name); + } else { + setenv(name, value, 1); + } +#endif // GTEST_OS_WINDOWS_MOBILE +} + +#if !GTEST_OS_WINDOWS_MOBILE +// Environment variables are not supported on Windows CE. + +using testing::internal::Int32FromGTestEnv; + +// Tests Int32FromGTestEnv(). + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable is not set. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenVariableIsNotSet) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", ""); + EXPECT_EQ(10, Int32FromGTestEnv("temp", 10)); +} + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable overflows as an Int32. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueOverflows) { + printf("(expecting 2 warnings)\n"); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12345678987654321"); + EXPECT_EQ(20, Int32FromGTestEnv("temp", 20)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-12345678987654321"); + EXPECT_EQ(30, Int32FromGTestEnv("temp", 30)); +} + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable does not represent a valid decimal integer. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueIsInvalid) { + printf("(expecting 2 warnings)\n"); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "A1"); + EXPECT_EQ(40, Int32FromGTestEnv("temp", 40)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12X"); + EXPECT_EQ(50, Int32FromGTestEnv("temp", 50)); +} + +// Tests that Int32FromGTestEnv() parses and returns the value of the +// environment variable when it represents a valid decimal integer in +// the range of an Int32. +TEST(Int32FromGTestEnvTest, ParsesAndReturnsValidValue) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "123"); + EXPECT_EQ(123, Int32FromGTestEnv("temp", 0)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-321"); + EXPECT_EQ(-321, Int32FromGTestEnv("temp", 0)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests ParseInt32Flag(). + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag has wrong format +TEST(ParseInt32FlagTest, ReturnsFalseForInvalidFlag) { + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--a=100", "b", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("a=100", "a", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag overflows as an Int32. +TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueOverflows) { + printf("(expecting 2 warnings)\n"); + + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--abc=12345678987654321", "abc", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("--abc=-12345678987654321", "abc", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag does not represent a valid decimal +// integer. +TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueIsInvalid) { + printf("(expecting 2 warnings)\n"); + + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--abc=A1", "abc", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("--abc=12X", "abc", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() parses the value of the flag and +// returns true when the flag represents a valid decimal integer in +// the range of an Int32. +TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { + Int32 value = 123; + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=456", "abc", &value)); + EXPECT_EQ(456, value); + + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=-789", + "abc", &value)); + EXPECT_EQ(-789, value); +} + +// Tests that Int32FromEnvOrDie() parses the value of the var or +// returns the correct default. +// Environment variables are not supported on Windows CE. +#if !GTEST_OS_WINDOWS_MOBILE +TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { + EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "123"); + EXPECT_EQ(123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123"); + EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests that Int32FromEnvOrDie() aborts with an error message +// if the variable is not an Int32. +TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx"); + EXPECT_DEATH_IF_SUPPORTED( + Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), + ".*"); +} + +// Tests that Int32FromEnvOrDie() aborts with an error message +// if the variable cannot be represnted by an Int32. +TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); + EXPECT_DEATH_IF_SUPPORTED( + Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), + ".*"); +} + +// Tests that ShouldRunTestOnShard() selects all tests +// where there is 1 shard. +TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereIsOneShard) { + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 0)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 1)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 2)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 3)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 4)); +} + +class ShouldShardTest : public testing::Test { + protected: + virtual void SetUp() { + index_var_ = GTEST_FLAG_PREFIX_UPPER_ "INDEX"; + total_var_ = GTEST_FLAG_PREFIX_UPPER_ "TOTAL"; + } + + virtual void TearDown() { + SetEnv(index_var_, ""); + SetEnv(total_var_, ""); + } + + const char* index_var_; + const char* total_var_; +}; + +// Tests that sharding is disabled if neither of the environment variables +// are set. +TEST_F(ShouldShardTest, ReturnsFalseWhenNeitherEnvVarIsSet) { + SetEnv(index_var_, ""); + SetEnv(total_var_, ""); + + EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} + +// Tests that sharding is not enabled if total_shards == 1. +TEST_F(ShouldShardTest, ReturnsFalseWhenTotalShardIsOne) { + SetEnv(index_var_, "0"); + SetEnv(total_var_, "1"); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} + +// Tests that sharding is enabled if total_shards > 1 and +// we are not in a death test subprocess. +// Environment variables are not supported on Windows CE. +#if !GTEST_OS_WINDOWS_MOBILE +TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { + SetEnv(index_var_, "4"); + SetEnv(total_var_, "22"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); + + SetEnv(index_var_, "8"); + SetEnv(total_var_, "9"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); + + SetEnv(index_var_, "0"); + SetEnv(total_var_, "9"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests that we exit in error if the sharding values are not valid. + +typedef ShouldShardTest ShouldShardDeathTest; + +TEST_F(ShouldShardDeathTest, AbortsWhenShardingEnvVarsAreInvalid) { + SetEnv(index_var_, "4"); + SetEnv(total_var_, "4"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, "4"); + SetEnv(total_var_, "-2"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, "5"); + SetEnv(total_var_, ""); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, ""); + SetEnv(total_var_, "5"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); +} + +// Tests that ShouldRunTestOnShard is a partition when 5 +// shards are used. +TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereAreFiveShards) { + // Choose an arbitrary number of tests and shards. + const int num_tests = 17; + const int num_shards = 5; + + // Check partitioning: each test should be on exactly 1 shard. + for (int test_id = 0; test_id < num_tests; test_id++) { + int prev_selected_shard_index = -1; + for (int shard_index = 0; shard_index < num_shards; shard_index++) { + if (ShouldRunTestOnShard(num_shards, shard_index, test_id)) { + if (prev_selected_shard_index < 0) { + prev_selected_shard_index = shard_index; + } else { + ADD_FAILURE() << "Shard " << prev_selected_shard_index << " and " + << shard_index << " are both selected to run test " << test_id; + } + } + } + } + + // Check balance: This is not required by the sharding protocol, but is a + // desirable property for performance. + for (int shard_index = 0; shard_index < num_shards; shard_index++) { + int num_tests_on_shard = 0; + for (int test_id = 0; test_id < num_tests; test_id++) { + num_tests_on_shard += + ShouldRunTestOnShard(num_shards, shard_index, test_id); + } + EXPECT_GE(num_tests_on_shard, num_tests / num_shards); + } +} + +// For the same reason we are not explicitly testing everything in the +// Test class, there are no separate tests for the following classes +// (except for some trivial cases): +// +// TestCase, UnitTest, UnitTestResultPrinter. +// +// Similarly, there are no separate tests for the following macros: +// +// TEST, TEST_F, RUN_ALL_TESTS + +TEST(UnitTestTest, CanGetOriginalWorkingDir) { + ASSERT_TRUE(UnitTest::GetInstance()->original_working_dir() != NULL); + EXPECT_STRNE(UnitTest::GetInstance()->original_working_dir(), ""); +} + +TEST(UnitTestTest, ReturnsPlausibleTimestamp) { + EXPECT_LT(0, UnitTest::GetInstance()->start_timestamp()); + EXPECT_LE(UnitTest::GetInstance()->start_timestamp(), GetTimeInMillis()); +} + +// This group of tests is for predicate assertions (ASSERT_PRED*, etc) +// of various arities. They do not attempt to be exhaustive. Rather, +// view them as smoke tests that can be easily reviewed and verified. +// A more complete set of tests for predicate assertions can be found +// in gtest_pred_impl_unittest.cc. + +// First, some predicates and predicate-formatters needed by the tests. + +// Returns true iff the argument is an even number. +bool IsEven(int n) { + return (n % 2) == 0; +} + +// A functor that returns true iff the argument is an even number. +struct IsEvenFunctor { + bool operator()(int n) { return IsEven(n); } +}; + +// A predicate-formatter function that asserts the argument is an even +// number. +AssertionResult AssertIsEven(const char* expr, int n) { + if (IsEven(n)) { + return AssertionSuccess(); + } + + Message msg; + msg << expr << " evaluates to " << n << ", which is not even."; + return AssertionFailure(msg); +} + +// A predicate function that returns AssertionResult for use in +// EXPECT/ASSERT_TRUE/FALSE. +AssertionResult ResultIsEven(int n) { + if (IsEven(n)) + return AssertionSuccess() << n << " is even"; + else + return AssertionFailure() << n << " is odd"; +} + +// A predicate function that returns AssertionResult but gives no +// explanation why it succeeds. Needed for testing that +// EXPECT/ASSERT_FALSE handles such functions correctly. +AssertionResult ResultIsEvenNoExplanation(int n) { + if (IsEven(n)) + return AssertionSuccess(); + else + return AssertionFailure() << n << " is odd"; +} + +// A predicate-formatter functor that asserts the argument is an even +// number. +struct AssertIsEvenFunctor { + AssertionResult operator()(const char* expr, int n) { + return AssertIsEven(expr, n); + } +}; + +// Returns true iff the sum of the arguments is an even number. +bool SumIsEven2(int n1, int n2) { + return IsEven(n1 + n2); +} + +// A functor that returns true iff the sum of the arguments is an even +// number. +struct SumIsEven3Functor { + bool operator()(int n1, int n2, int n3) { + return IsEven(n1 + n2 + n3); + } +}; + +// A predicate-formatter function that asserts the sum of the +// arguments is an even number. +AssertionResult AssertSumIsEven4( + const char* e1, const char* e2, const char* e3, const char* e4, + int n1, int n2, int n3, int n4) { + const int sum = n1 + n2 + n3 + n4; + if (IsEven(sum)) { + return AssertionSuccess(); + } + + Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 + << " (" << n1 << " + " << n2 << " + " << n3 << " + " << n4 + << ") evaluates to " << sum << ", which is not even."; + return AssertionFailure(msg); +} + +// A predicate-formatter functor that asserts the sum of the arguments +// is an even number. +struct AssertSumIsEven5Functor { + AssertionResult operator()( + const char* e1, const char* e2, const char* e3, const char* e4, + const char* e5, int n1, int n2, int n3, int n4, int n5) { + const int sum = n1 + n2 + n3 + n4 + n5; + if (IsEven(sum)) { + return AssertionSuccess(); + } + + Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 + << " (" + << n1 << " + " << n2 << " + " << n3 << " + " << n4 << " + " << n5 + << ") evaluates to " << sum << ", which is not even."; + return AssertionFailure(msg); + } +}; + + +// Tests unary predicate assertions. + +// Tests unary predicate assertions that don't use a custom formatter. +TEST(Pred1Test, WithoutFormat) { + // Success cases. + EXPECT_PRED1(IsEvenFunctor(), 2) << "This failure is UNEXPECTED!"; + ASSERT_PRED1(IsEven, 4); + + // Failure cases. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(IsEven, 5) << "This failure is expected."; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE(ASSERT_PRED1(IsEvenFunctor(), 5), + "evaluates to false"); +} + +// Tests unary predicate assertions that use a custom formatter. +TEST(Pred1Test, WithFormat) { + // Success cases. + EXPECT_PRED_FORMAT1(AssertIsEven, 2); + ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), 4) + << "This failure is UNEXPECTED!"; + + // Failure cases. + const int n = 5; + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT1(AssertIsEvenFunctor(), n), + "n evaluates to 5, which is not even."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(AssertIsEven, 5) << "This failure is expected."; + }, "This failure is expected."); +} + +// Tests that unary predicate assertions evaluates their arguments +// exactly once. +TEST(Pred1Test, SingleEvaluationOnFailure) { + // A success case. + static int n = 0; + EXPECT_PRED1(IsEven, n++); + EXPECT_EQ(1, n) << "The argument is not evaluated exactly once."; + + // A failure case. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), n++) + << "This failure is expected."; + }, "This failure is expected."); + EXPECT_EQ(2, n) << "The argument is not evaluated exactly once."; +} + + +// Tests predicate assertions whose arity is >= 2. + +// Tests predicate assertions that don't use a custom formatter. +TEST(PredTest, WithoutFormat) { + // Success cases. + ASSERT_PRED2(SumIsEven2, 2, 4) << "This failure is UNEXPECTED!"; + EXPECT_PRED3(SumIsEven3Functor(), 4, 6, 8); + + // Failure cases. + const int n1 = 1; + const int n2 = 2; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(SumIsEven2, n1, n2) << "This failure is expected."; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(SumIsEven3Functor(), 1, 2, 4); + }, "evaluates to false"); +} + +// Tests predicate assertions that use a custom formatter. +TEST(PredTest, WithFormat) { + // Success cases. + ASSERT_PRED_FORMAT4(AssertSumIsEven4, 4, 6, 8, 10) << + "This failure is UNEXPECTED!"; + EXPECT_PRED_FORMAT5(AssertSumIsEven5Functor(), 2, 4, 6, 8, 10); + + // Failure cases. + const int n1 = 1; + const int n2 = 2; + const int n3 = 4; + const int n4 = 6; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(AssertSumIsEven4, n1, n2, n3, n4); + }, "evaluates to 13, which is not even."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), 1, 2, 4, 6, 8) + << "This failure is expected."; + }, "This failure is expected."); +} + +// Tests that predicate assertions evaluates their arguments +// exactly once. +TEST(PredTest, SingleEvaluationOnFailure) { + // A success case. + int n1 = 0; + int n2 = 0; + EXPECT_PRED2(SumIsEven2, n1++, n2++); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + + // Another success case. + n1 = n2 = 0; + int n3 = 0; + int n4 = 0; + int n5 = 0; + ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), + n1++, n2++, n3++, n4++, n5++) + << "This failure is UNEXPECTED!"; + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; + EXPECT_EQ(1, n5) << "Argument 5 is not evaluated exactly once."; + + // A failure case. + n1 = n2 = n3 = 0; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(SumIsEven3Functor(), ++n1, n2++, n3++) + << "This failure is expected."; + }, "This failure is expected."); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + + // Another failure case. + n1 = n2 = n3 = n4 = 0; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(AssertSumIsEven4, ++n1, n2++, n3++, n4++); + }, "evaluates to 1, which is not even."); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; +} + + +// Some helper functions for testing using overloaded/template +// functions with ASSERT_PREDn and EXPECT_PREDn. + +bool IsPositive(double x) { + return x > 0; +} + +template +bool IsNegative(T x) { + return x < 0; +} + +template +bool GreaterThan(T1 x1, T2 x2) { + return x1 > x2; +} + +// Tests that overloaded functions can be used in *_PRED* as long as +// their types are explicitly specified. +TEST(PredicateAssertionTest, AcceptsOverloadedFunction) { + // C++Builder requires C-style casts rather than static_cast. + EXPECT_PRED1((bool (*)(int))(IsPositive), 5); // NOLINT + ASSERT_PRED1((bool (*)(double))(IsPositive), 6.0); // NOLINT +} + +// Tests that template functions can be used in *_PRED* as long as +// their types are explicitly specified. +TEST(PredicateAssertionTest, AcceptsTemplateFunction) { + EXPECT_PRED1(IsNegative, -5); + // Makes sure that we can handle templates with more than one + // parameter. + ASSERT_PRED2((GreaterThan), 5, 0); +} + + +// Some helper functions for testing using overloaded/template +// functions with ASSERT_PRED_FORMATn and EXPECT_PRED_FORMATn. + +AssertionResult IsPositiveFormat(const char* /* expr */, int n) { + return n > 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +AssertionResult IsPositiveFormat(const char* /* expr */, double x) { + return x > 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +template +AssertionResult IsNegativeFormat(const char* /* expr */, T x) { + return x < 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +template +AssertionResult EqualsFormat(const char* /* expr1 */, const char* /* expr2 */, + const T1& x1, const T2& x2) { + return x1 == x2 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +// Tests that overloaded functions can be used in *_PRED_FORMAT* +// without explicitly specifying their types. +TEST(PredicateFormatAssertionTest, AcceptsOverloadedFunction) { + EXPECT_PRED_FORMAT1(IsPositiveFormat, 5); + ASSERT_PRED_FORMAT1(IsPositiveFormat, 6.0); +} + +// Tests that template functions can be used in *_PRED_FORMAT* without +// explicitly specifying their types. +TEST(PredicateFormatAssertionTest, AcceptsTemplateFunction) { + EXPECT_PRED_FORMAT1(IsNegativeFormat, -5); + ASSERT_PRED_FORMAT2(EqualsFormat, 3, 3); +} + + +// Tests string assertions. + +// Tests ASSERT_STREQ with non-NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ) { + const char * const p1 = "good"; + ASSERT_STREQ(p1, p1); + + // Let p2 have the same content as p1, but be at a different address. + const char p2[] = "good"; + ASSERT_STREQ(p1, p2); + + EXPECT_FATAL_FAILURE(ASSERT_STREQ("bad", "good"), + "Expected: \"bad\""); +} + +// Tests ASSERT_STREQ with NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ_Null) { + ASSERT_STREQ(static_cast(NULL), NULL); + EXPECT_FATAL_FAILURE(ASSERT_STREQ(NULL, "non-null"), + "non-null"); +} + +// Tests ASSERT_STREQ with NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ_Null2) { + EXPECT_FATAL_FAILURE(ASSERT_STREQ("non-null", NULL), + "non-null"); +} + +// Tests ASSERT_STRNE. +TEST(StringAssertionTest, ASSERT_STRNE) { + ASSERT_STRNE("hi", "Hi"); + ASSERT_STRNE("Hi", NULL); + ASSERT_STRNE(NULL, "Hi"); + ASSERT_STRNE("", NULL); + ASSERT_STRNE(NULL, ""); + ASSERT_STRNE("", "Hi"); + ASSERT_STRNE("Hi", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRNE("Hi", "Hi"), + "\"Hi\" vs \"Hi\""); +} + +// Tests ASSERT_STRCASEEQ. +TEST(StringAssertionTest, ASSERT_STRCASEEQ) { + ASSERT_STRCASEEQ("hi", "Hi"); + ASSERT_STRCASEEQ(static_cast(NULL), NULL); + + ASSERT_STRCASEEQ("", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("Hi", "hi2"), + "(ignoring case)"); +} + +// Tests ASSERT_STRCASENE. +TEST(StringAssertionTest, ASSERT_STRCASENE) { + ASSERT_STRCASENE("hi1", "Hi2"); + ASSERT_STRCASENE("Hi", NULL); + ASSERT_STRCASENE(NULL, "Hi"); + ASSERT_STRCASENE("", NULL); + ASSERT_STRCASENE(NULL, ""); + ASSERT_STRCASENE("", "Hi"); + ASSERT_STRCASENE("Hi", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("Hi", "hi"), + "(ignoring case)"); +} + +// Tests *_STREQ on wide strings. +TEST(StringAssertionTest, STREQ_Wide) { + // NULL strings. + ASSERT_STREQ(static_cast(NULL), NULL); + + // Empty strings. + ASSERT_STREQ(L"", L""); + + // Non-null vs NULL. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"non-null", NULL), + "non-null"); + + // Equal strings. + EXPECT_STREQ(L"Hi", L"Hi"); + + // Unequal strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc", L"Abc"), + "Abc"); + + // Strings containing wide characters. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc\x8119", L"abc\x8120"), + "abc"); + + // The streaming variation. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_STREQ(L"abc\x8119", L"abc\x8121") << "Expected failure"; + }, "Expected failure"); +} + +// Tests *_STRNE on wide strings. +TEST(StringAssertionTest, STRNE_Wide) { + // NULL strings. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_STRNE(static_cast(NULL), NULL); + }, ""); + + // Empty strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"", L""), + "L\"\""); + + // Non-null vs NULL. + ASSERT_STRNE(L"non-null", NULL); + + // Equal strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"Hi", L"Hi"), + "L\"Hi\""); + + // Unequal strings. + EXPECT_STRNE(L"abc", L"Abc"); + + // Strings containing wide characters. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"abc\x8119", L"abc\x8119"), + "abc"); + + // The streaming variation. + ASSERT_STRNE(L"abc\x8119", L"abc\x8120") << "This shouldn't happen"; +} + +// Tests for ::testing::IsSubstring(). + +// Tests that IsSubstring() returns the correct result when the input +// argument type is const char*. +TEST(IsSubstringTest, ReturnsCorrectResultForCString) { + EXPECT_FALSE(IsSubstring("", "", NULL, "a")); + EXPECT_FALSE(IsSubstring("", "", "b", NULL)); + EXPECT_FALSE(IsSubstring("", "", "needle", "haystack")); + + EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); + EXPECT_TRUE(IsSubstring("", "", "needle", "two needles")); +} + +// Tests that IsSubstring() returns the correct result when the input +// argument type is const wchar_t*. +TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) { + EXPECT_FALSE(IsSubstring("", "", kNull, L"a")); + EXPECT_FALSE(IsSubstring("", "", L"b", kNull)); + EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack")); + + EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); + EXPECT_TRUE(IsSubstring("", "", L"needle", L"two needles")); +} + +// Tests that IsSubstring() generates the correct message when the input +// argument type is const char*. +TEST(IsSubstringTest, GeneratesCorrectMessageForCString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: \"needle\"\n" + "Expected: a substring of haystack_expr\n" + "Which is: \"haystack\"", + IsSubstring("needle_expr", "haystack_expr", + "needle", "haystack").failure_message()); +} + +// Tests that IsSubstring returns the correct result when the input +// argument type is ::std::string. +TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) { + EXPECT_TRUE(IsSubstring("", "", std::string("hello"), "ahellob")); + EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world"))); +} + +#if GTEST_HAS_STD_WSTRING +// Tests that IsSubstring returns the correct result when the input +// argument type is ::std::wstring. +TEST(IsSubstringTest, ReturnsCorrectResultForStdWstring) { + EXPECT_TRUE(IsSubstring("", "", ::std::wstring(L"needle"), L"two needles")); + EXPECT_FALSE(IsSubstring("", "", L"needle", ::std::wstring(L"haystack"))); +} + +// Tests that IsSubstring() generates the correct message when the input +// argument type is ::std::wstring. +TEST(IsSubstringTest, GeneratesCorrectMessageForWstring) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: L\"needle\"\n" + "Expected: a substring of haystack_expr\n" + "Which is: L\"haystack\"", + IsSubstring( + "needle_expr", "haystack_expr", + ::std::wstring(L"needle"), L"haystack").failure_message()); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Tests for ::testing::IsNotSubstring(). + +// Tests that IsNotSubstring() returns the correct result when the input +// argument type is const char*. +TEST(IsNotSubstringTest, ReturnsCorrectResultForCString) { + EXPECT_TRUE(IsNotSubstring("", "", "needle", "haystack")); + EXPECT_FALSE(IsNotSubstring("", "", "needle", "two needles")); +} + +// Tests that IsNotSubstring() returns the correct result when the input +// argument type is const wchar_t*. +TEST(IsNotSubstringTest, ReturnsCorrectResultForWideCString) { + EXPECT_TRUE(IsNotSubstring("", "", L"needle", L"haystack")); + EXPECT_FALSE(IsNotSubstring("", "", L"needle", L"two needles")); +} + +// Tests that IsNotSubstring() generates the correct message when the input +// argument type is const wchar_t*. +TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: L\"needle\"\n" + "Expected: not a substring of haystack_expr\n" + "Which is: L\"two needles\"", + IsNotSubstring( + "needle_expr", "haystack_expr", + L"needle", L"two needles").failure_message()); +} + +// Tests that IsNotSubstring returns the correct result when the input +// argument type is ::std::string. +TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) { + EXPECT_FALSE(IsNotSubstring("", "", std::string("hello"), "ahellob")); + EXPECT_TRUE(IsNotSubstring("", "", "hello", std::string("world"))); +} + +// Tests that IsNotSubstring() generates the correct message when the input +// argument type is ::std::string. +TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: \"needle\"\n" + "Expected: not a substring of haystack_expr\n" + "Which is: \"two needles\"", + IsNotSubstring( + "needle_expr", "haystack_expr", + ::std::string("needle"), "two needles").failure_message()); +} + +#if GTEST_HAS_STD_WSTRING + +// Tests that IsNotSubstring returns the correct result when the input +// argument type is ::std::wstring. +TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { + EXPECT_FALSE( + IsNotSubstring("", "", ::std::wstring(L"needle"), L"two needles")); + EXPECT_TRUE(IsNotSubstring("", "", L"needle", ::std::wstring(L"haystack"))); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Tests floating-point assertions. + +template +class FloatingPointTest : public Test { + protected: + // Pre-calculated numbers to be used by the tests. + struct TestValues { + RawType close_to_positive_zero; + RawType close_to_negative_zero; + RawType further_from_negative_zero; + + RawType close_to_one; + RawType further_from_one; + + RawType infinity; + RawType close_to_infinity; + RawType further_from_infinity; + + RawType nan1; + RawType nan2; + }; + + typedef typename testing::internal::FloatingPoint Floating; + typedef typename Floating::Bits Bits; + + virtual void SetUp() { + const size_t max_ulps = Floating::kMaxUlps; + + // The bits that represent 0.0. + const Bits zero_bits = Floating(0).bits(); + + // Makes some numbers close to 0.0. + values_.close_to_positive_zero = Floating::ReinterpretBits( + zero_bits + max_ulps/2); + values_.close_to_negative_zero = -Floating::ReinterpretBits( + zero_bits + max_ulps - max_ulps/2); + values_.further_from_negative_zero = -Floating::ReinterpretBits( + zero_bits + max_ulps + 1 - max_ulps/2); + + // The bits that represent 1.0. + const Bits one_bits = Floating(1).bits(); + + // Makes some numbers close to 1.0. + values_.close_to_one = Floating::ReinterpretBits(one_bits + max_ulps); + values_.further_from_one = Floating::ReinterpretBits( + one_bits + max_ulps + 1); + + // +infinity. + values_.infinity = Floating::Infinity(); + + // The bits that represent +infinity. + const Bits infinity_bits = Floating(values_.infinity).bits(); + + // Makes some numbers close to infinity. + values_.close_to_infinity = Floating::ReinterpretBits( + infinity_bits - max_ulps); + values_.further_from_infinity = Floating::ReinterpretBits( + infinity_bits - max_ulps - 1); + + // Makes some NAN's. Sets the most significant bit of the fraction so that + // our NaN's are quiet; trying to process a signaling NaN would raise an + // exception if our environment enables floating point exceptions. + values_.nan1 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 1); + values_.nan2 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 200); + } + + void TestSize() { + EXPECT_EQ(sizeof(RawType), sizeof(Bits)); + } + + static TestValues values_; +}; + +template +typename FloatingPointTest::TestValues + FloatingPointTest::values_; + +// Instantiates FloatingPointTest for testing *_FLOAT_EQ. +typedef FloatingPointTest FloatTest; + +// Tests that the size of Float::Bits matches the size of float. +TEST_F(FloatTest, Size) { + TestSize(); +} + +// Tests comparing with +0 and -0. +TEST_F(FloatTest, Zeros) { + EXPECT_FLOAT_EQ(0.0, -0.0); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(-0.0, 1.0), + "1.0"); + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.5), + "1.5"); +} + +// Tests comparing numbers close to 0. +// +// This ensures that *_FLOAT_EQ handles the sign correctly and no +// overflow occurs when comparing numbers whose absolute value is very +// small. +TEST_F(FloatTest, AlmostZeros) { + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const FloatTest::TestValues& v = this->values_; + + EXPECT_FLOAT_EQ(0.0, v.close_to_positive_zero); + EXPECT_FLOAT_EQ(-0.0, v.close_to_negative_zero); + EXPECT_FLOAT_EQ(v.close_to_positive_zero, v.close_to_negative_zero); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_FLOAT_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); +} + +// Tests comparing numbers close to each other. +TEST_F(FloatTest, SmallDiff) { + EXPECT_FLOAT_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); +} + +// Tests comparing numbers far apart. +TEST_F(FloatTest, LargeDiff) { + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(2.5, 3.0), + "3.0"); +} + +// Tests comparing with infinity. +// +// This ensures that no overflow occurs when comparing numbers whose +// absolute value is very large. +TEST_F(FloatTest, Infinity) { + EXPECT_FLOAT_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_FLOAT_EQ(-values_.infinity, -values_.close_to_infinity); +#if !GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); + + // This is interesting as the representations of infinity and nan1 + // are only 1 DLP apart. + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, values_.nan1), + "values_.nan1"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that comparing with NAN always returns false. +TEST_F(FloatTest, NaN) { +#if !GTEST_OS_SYMBIAN +// Nokia's STLport crashes if we try to output infinity or NaN. + + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const FloatTest::TestValues& v = this->values_; + + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan2), + "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, v.nan1), + "v.nan1"); + + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(v.nan1, v.infinity), + "v.infinity"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that *_FLOAT_EQ are reflexive. +TEST_F(FloatTest, Reflexive) { + EXPECT_FLOAT_EQ(0.0, 0.0); + EXPECT_FLOAT_EQ(1.0, 1.0); + ASSERT_FLOAT_EQ(values_.infinity, values_.infinity); +} + +// Tests that *_FLOAT_EQ are commutative. +TEST_F(FloatTest, Commutative) { + // We already tested EXPECT_FLOAT_EQ(1.0, values_.close_to_one). + EXPECT_FLOAT_EQ(values_.close_to_one, 1.0); + + // We already tested EXPECT_FLOAT_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.further_from_one, 1.0), + "1.0"); +} + +// Tests EXPECT_NEAR. +TEST_F(FloatTest, EXPECT_NEAR) { + EXPECT_NEAR(-1.0f, -1.1f, 0.2f); + EXPECT_NEAR(2.0f, 3.0f, 1.0f); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + "The difference between 1.0f and 1.5f is 0.5, " + "which exceeds 0.25f"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous line. +} + +// Tests ASSERT_NEAR. +TEST_F(FloatTest, ASSERT_NEAR) { + ASSERT_NEAR(-1.0f, -1.1f, 0.2f); + ASSERT_NEAR(2.0f, 3.0f, 1.0f); + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + "The difference between 1.0f and 1.5f is 0.5, " + "which exceeds 0.25f"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous line. +} + +// Tests the cases where FloatLE() should succeed. +TEST_F(FloatTest, FloatLESucceeds) { + EXPECT_PRED_FORMAT2(FloatLE, 1.0f, 2.0f); // When val1 < val2, + ASSERT_PRED_FORMAT2(FloatLE, 1.0f, 1.0f); // val1 == val2, + + // or when val1 is greater than, but almost equals to, val2. + EXPECT_PRED_FORMAT2(FloatLE, values_.close_to_positive_zero, 0.0f); +} + +// Tests the cases where FloatLE() should fail. +TEST_F(FloatTest, FloatLEFails) { + // When val1 is greater than val2 by a large margin, + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(FloatLE, 2.0f, 1.0f), + "(2.0f) <= (1.0f)"); + + // or by a small yet non-negligible margin, + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, values_.further_from_one, 1.0f); + }, "(values_.further_from_one) <= (1.0f)"); + +#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) + // Nokia's STLport crashes if we try to output infinity or NaN. + // C++Builder gives bad results for ordered comparisons involving NaNs + // due to compiler bugs. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, -values_.infinity, values_.nan1); + }, "(-values_.infinity) <= (values_.nan1)"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(FloatLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +#endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) +} + +// Instantiates FloatingPointTest for testing *_DOUBLE_EQ. +typedef FloatingPointTest DoubleTest; + +// Tests that the size of Double::Bits matches the size of double. +TEST_F(DoubleTest, Size) { + TestSize(); +} + +// Tests comparing with +0 and -0. +TEST_F(DoubleTest, Zeros) { + EXPECT_DOUBLE_EQ(0.0, -0.0); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(-0.0, 1.0), + "1.0"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(0.0, 1.0), + "1.0"); +} + +// Tests comparing numbers close to 0. +// +// This ensures that *_DOUBLE_EQ handles the sign correctly and no +// overflow occurs when comparing numbers whose absolute value is very +// small. +TEST_F(DoubleTest, AlmostZeros) { + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const DoubleTest::TestValues& v = this->values_; + + EXPECT_DOUBLE_EQ(0.0, v.close_to_positive_zero); + EXPECT_DOUBLE_EQ(-0.0, v.close_to_negative_zero); + EXPECT_DOUBLE_EQ(v.close_to_positive_zero, v.close_to_negative_zero); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_DOUBLE_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); +} + +// Tests comparing numbers close to each other. +TEST_F(DoubleTest, SmallDiff) { + EXPECT_DOUBLE_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); +} + +// Tests comparing numbers far apart. +TEST_F(DoubleTest, LargeDiff) { + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(2.0, 3.0), + "3.0"); +} + +// Tests comparing with infinity. +// +// This ensures that no overflow occurs when comparing numbers whose +// absolute value is very large. +TEST_F(DoubleTest, Infinity) { + EXPECT_DOUBLE_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_DOUBLE_EQ(-values_.infinity, -values_.close_to_infinity); +#if !GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); + + // This is interesting as the representations of infinity_ and nan1_ + // are only 1 DLP apart. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, values_.nan1), + "values_.nan1"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that comparing with NAN always returns false. +TEST_F(DoubleTest, NaN) { +#if !GTEST_OS_SYMBIAN + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const DoubleTest::TestValues& v = this->values_; + + // Nokia's STLport crashes if we try to output infinity or NaN. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan2), "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, v.nan1), "v.nan1"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(v.nan1, v.infinity), + "v.infinity"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that *_DOUBLE_EQ are reflexive. +TEST_F(DoubleTest, Reflexive) { + EXPECT_DOUBLE_EQ(0.0, 0.0); + EXPECT_DOUBLE_EQ(1.0, 1.0); +#if !GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. + ASSERT_DOUBLE_EQ(values_.infinity, values_.infinity); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that *_DOUBLE_EQ are commutative. +TEST_F(DoubleTest, Commutative) { + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.close_to_one). + EXPECT_DOUBLE_EQ(values_.close_to_one, 1.0); + + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.further_from_one, 1.0), + "1.0"); +} + +// Tests EXPECT_NEAR. +TEST_F(DoubleTest, EXPECT_NEAR) { + EXPECT_NEAR(-1.0, -1.1, 0.2); + EXPECT_NEAR(2.0, 3.0, 1.0); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.5, 0.25), // NOLINT + "The difference between 1.0 and 1.5 is 0.5, " + "which exceeds 0.25"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests ASSERT_NEAR. +TEST_F(DoubleTest, ASSERT_NEAR) { + ASSERT_NEAR(-1.0, -1.1, 0.2); + ASSERT_NEAR(2.0, 3.0, 1.0); + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.5, 0.25), // NOLINT + "The difference between 1.0 and 1.5 is 0.5, " + "which exceeds 0.25"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests the cases where DoubleLE() should succeed. +TEST_F(DoubleTest, DoubleLESucceeds) { + EXPECT_PRED_FORMAT2(DoubleLE, 1.0, 2.0); // When val1 < val2, + ASSERT_PRED_FORMAT2(DoubleLE, 1.0, 1.0); // val1 == val2, + + // or when val1 is greater than, but almost equals to, val2. + EXPECT_PRED_FORMAT2(DoubleLE, values_.close_to_positive_zero, 0.0); +} + +// Tests the cases where DoubleLE() should fail. +TEST_F(DoubleTest, DoubleLEFails) { + // When val1 is greater than val2 by a large margin, + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(DoubleLE, 2.0, 1.0), + "(2.0) <= (1.0)"); + + // or by a small yet non-negligible margin, + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, values_.further_from_one, 1.0); + }, "(values_.further_from_one) <= (1.0)"); + +#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) + // Nokia's STLport crashes if we try to output infinity or NaN. + // C++Builder gives bad results for ordered comparisons involving NaNs + // due to compiler bugs. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, -values_.infinity, values_.nan1); + }, " (-values_.infinity) <= (values_.nan1)"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +#endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) +} + + +// Verifies that a test or test case whose name starts with DISABLED_ is +// not run. + +// A test whose name starts with DISABLED_. +// Should not run. +TEST(DisabledTest, DISABLED_TestShouldNotRun) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +// A test whose name does not start with DISABLED_. +// Should run. +TEST(DisabledTest, NotDISABLED_TestShouldRun) { + EXPECT_EQ(1, 1); +} + +// A test case whose name starts with DISABLED_. +// Should not run. +TEST(DISABLED_TestCase, TestShouldNotRun) { + FAIL() << "Unexpected failure: Test in disabled test case should not be run."; +} + +// A test case and test whose names start with DISABLED_. +// Should not run. +TEST(DISABLED_TestCase, DISABLED_TestShouldNotRun) { + FAIL() << "Unexpected failure: Test in disabled test case should not be run."; +} + +// Check that when all tests in a test case are disabled, SetupTestCase() and +// TearDownTestCase() are not called. +class DisabledTestsTest : public Test { + protected: + static void SetUpTestCase() { + FAIL() << "Unexpected failure: All tests disabled in test case. " + "SetupTestCase() should not be called."; + } + + static void TearDownTestCase() { + FAIL() << "Unexpected failure: All tests disabled in test case. " + "TearDownTestCase() should not be called."; + } +}; + +TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_1) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_2) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +// Tests that disabled typed tests aren't run. + +#if GTEST_HAS_TYPED_TEST + +template +class TypedTest : public Test { +}; + +typedef testing::Types NumericTypes; +TYPED_TEST_CASE(TypedTest, NumericTypes); + +TYPED_TEST(TypedTest, DISABLED_ShouldNotRun) { + FAIL() << "Unexpected failure: Disabled typed test should not run."; +} + +template +class DISABLED_TypedTest : public Test { +}; + +TYPED_TEST_CASE(DISABLED_TypedTest, NumericTypes); + +TYPED_TEST(DISABLED_TypedTest, ShouldNotRun) { + FAIL() << "Unexpected failure: Disabled typed test should not run."; +} + +#endif // GTEST_HAS_TYPED_TEST + +// Tests that disabled type-parameterized tests aren't run. + +#if GTEST_HAS_TYPED_TEST_P + +template +class TypedTestP : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP); + +TYPED_TEST_P(TypedTestP, DISABLED_ShouldNotRun) { + FAIL() << "Unexpected failure: " + << "Disabled type-parameterized test should not run."; +} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP, DISABLED_ShouldNotRun); + +INSTANTIATE_TYPED_TEST_CASE_P(My, TypedTestP, NumericTypes); + +template +class DISABLED_TypedTestP : public Test { +}; + +TYPED_TEST_CASE_P(DISABLED_TypedTestP); + +TYPED_TEST_P(DISABLED_TypedTestP, ShouldNotRun) { + FAIL() << "Unexpected failure: " + << "Disabled type-parameterized test should not run."; +} + +REGISTER_TYPED_TEST_CASE_P(DISABLED_TypedTestP, ShouldNotRun); + +INSTANTIATE_TYPED_TEST_CASE_P(My, DISABLED_TypedTestP, NumericTypes); + +#endif // GTEST_HAS_TYPED_TEST_P + +// Tests that assertion macros evaluate their arguments exactly once. + +class SingleEvaluationTest : public Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + // This helper function is needed by the FailedASSERT_STREQ test + // below. It's public to work around C++Builder's bug with scoping local + // classes. + static void CompareAndIncrementCharPtrs() { + ASSERT_STREQ(p1_++, p2_++); + } + + // This helper function is needed by the FailedASSERT_NE test below. It's + // public to work around C++Builder's bug with scoping local classes. + static void CompareAndIncrementInts() { + ASSERT_NE(a_++, b_++); + } + + protected: + SingleEvaluationTest() { + p1_ = s1_; + p2_ = s2_; + a_ = 0; + b_ = 0; + } + + static const char* const s1_; + static const char* const s2_; + static const char* p1_; + static const char* p2_; + + static int a_; + static int b_; +}; + +const char* const SingleEvaluationTest::s1_ = "01234"; +const char* const SingleEvaluationTest::s2_ = "abcde"; +const char* SingleEvaluationTest::p1_; +const char* SingleEvaluationTest::p2_; +int SingleEvaluationTest::a_; +int SingleEvaluationTest::b_; + +// Tests that when ASSERT_STREQ fails, it evaluates its arguments +// exactly once. +TEST_F(SingleEvaluationTest, FailedASSERT_STREQ) { + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementCharPtrs(), + "p2_++"); + EXPECT_EQ(s1_ + 1, p1_); + EXPECT_EQ(s2_ + 1, p2_); +} + +// Tests that string assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, ASSERT_STR) { + // successful EXPECT_STRNE + EXPECT_STRNE(p1_++, p2_++); + EXPECT_EQ(s1_ + 1, p1_); + EXPECT_EQ(s2_ + 1, p2_); + + // failed EXPECT_STRCASEEQ + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ(p1_++, p2_++), + "ignoring case"); + EXPECT_EQ(s1_ + 2, p1_); + EXPECT_EQ(s2_ + 2, p2_); +} + +// Tests that when ASSERT_NE fails, it evaluates its arguments exactly +// once. +TEST_F(SingleEvaluationTest, FailedASSERT_NE) { + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementInts(), + "(a_++) != (b_++)"); + EXPECT_EQ(1, a_); + EXPECT_EQ(1, b_); +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, OtherCases) { + // successful EXPECT_TRUE + EXPECT_TRUE(0 == a_++); // NOLINT + EXPECT_EQ(1, a_); + + // failed EXPECT_TRUE + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(-1 == a_++), "-1 == a_++"); + EXPECT_EQ(2, a_); + + // successful EXPECT_GT + EXPECT_GT(a_++, b_++); + EXPECT_EQ(3, a_); + EXPECT_EQ(1, b_); + + // failed EXPECT_LT + EXPECT_NONFATAL_FAILURE(EXPECT_LT(a_++, b_++), "(a_++) < (b_++)"); + EXPECT_EQ(4, a_); + EXPECT_EQ(2, b_); + + // successful ASSERT_TRUE + ASSERT_TRUE(0 < a_++); // NOLINT + EXPECT_EQ(5, a_); + + // successful ASSERT_GT + ASSERT_GT(a_++, b_++); + EXPECT_EQ(6, a_); + EXPECT_EQ(3, b_); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowAnInteger() { + throw 1; +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, ExceptionTests) { + // successful EXPECT_THROW + EXPECT_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }, int); + EXPECT_EQ(1, a_); + + // failed EXPECT_THROW, throws different + EXPECT_NONFATAL_FAILURE(EXPECT_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }, bool), "throws a different type"); + EXPECT_EQ(2, a_); + + // failed EXPECT_THROW, throws nothing + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(a_++, bool), "throws nothing"); + EXPECT_EQ(3, a_); + + // successful EXPECT_NO_THROW + EXPECT_NO_THROW(a_++); + EXPECT_EQ(4, a_); + + // failed EXPECT_NO_THROW + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }), "it throws"); + EXPECT_EQ(5, a_); + + // successful EXPECT_ANY_THROW + EXPECT_ANY_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }); + EXPECT_EQ(6, a_); + + // failed EXPECT_ANY_THROW + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(a_++), "it doesn't"); + EXPECT_EQ(7, a_); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests {ASSERT|EXPECT}_NO_FATAL_FAILURE. +class NoFatalFailureTest : public Test { + protected: + void Succeeds() {} + void FailsNonFatal() { + ADD_FAILURE() << "some non-fatal failure"; + } + void Fails() { + FAIL() << "some fatal failure"; + } + + void DoAssertNoFatalFailureOnFails() { + ASSERT_NO_FATAL_FAILURE(Fails()); + ADD_FAILURE() << "shold not reach here."; + } + + void DoExpectNoFatalFailureOnFails() { + EXPECT_NO_FATAL_FAILURE(Fails()); + ADD_FAILURE() << "other failure"; + } +}; + +TEST_F(NoFatalFailureTest, NoFailure) { + EXPECT_NO_FATAL_FAILURE(Succeeds()); + ASSERT_NO_FATAL_FAILURE(Succeeds()); +} + +TEST_F(NoFatalFailureTest, NonFatalIsNoFailure) { + EXPECT_NONFATAL_FAILURE( + EXPECT_NO_FATAL_FAILURE(FailsNonFatal()), + "some non-fatal failure"); + EXPECT_NONFATAL_FAILURE( + ASSERT_NO_FATAL_FAILURE(FailsNonFatal()), + "some non-fatal failure"); +} + +TEST_F(NoFatalFailureTest, AssertNoFatalFailureOnFatalFailure) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + DoAssertNoFatalFailureOnFails(); + } + ASSERT_EQ(2, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", + gtest_failures.GetTestPartResult(1).message()); +} + +TEST_F(NoFatalFailureTest, ExpectNoFatalFailureOnFatalFailure) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + DoExpectNoFatalFailureOnFails(); + } + ASSERT_EQ(3, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(2).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", + gtest_failures.GetTestPartResult(1).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "other failure", + gtest_failures.GetTestPartResult(2).message()); +} + +TEST_F(NoFatalFailureTest, MessageIsStreamable) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + EXPECT_NO_FATAL_FAILURE(FAIL() << "foo") << "my message"; + } + ASSERT_EQ(2, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "foo", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "my message", + gtest_failures.GetTestPartResult(1).message()); +} + +// Tests non-string assertions. + +// Tests EqFailure(), used for implementing *EQ* assertions. +TEST(AssertionTest, EqFailure) { + const std::string foo_val("5"), bar_val("6"); + const std::string msg1( + EqFailure("foo", "bar", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: 6\n" + "Expected: foo\n" + "Which is: 5", + msg1.c_str()); + + const std::string msg2( + EqFailure("foo", "6", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: 6\n" + "Expected: foo\n" + "Which is: 5", + msg2.c_str()); + + const std::string msg3( + EqFailure("5", "bar", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: 6\n" + "Expected: 5", + msg3.c_str()); + + const std::string msg4( + EqFailure("5", "6", foo_val, bar_val, false).failure_message()); + EXPECT_STREQ( + "Value of: 6\n" + "Expected: 5", + msg4.c_str()); + + const std::string msg5( + EqFailure("foo", "bar", + std::string("\"x\""), std::string("\"y\""), + true).failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: \"y\"\n" + "Expected: foo (ignoring case)\n" + "Which is: \"x\"", + msg5.c_str()); +} + +// Tests AppendUserMessage(), used for implementing the *EQ* macros. +TEST(AssertionTest, AppendUserMessage) { + const std::string foo("foo"); + + Message msg; + EXPECT_STREQ("foo", + AppendUserMessage(foo, msg).c_str()); + + msg << "bar"; + EXPECT_STREQ("foo\nbar", + AppendUserMessage(foo, msg).c_str()); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +// Tests ASSERT_TRUE. +TEST(AssertionTest, ASSERT_TRUE) { + ASSERT_TRUE(2 > 1); // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_TRUE(2 < 1), + "2 < 1"); +} + +// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult. +TEST(AssertionTest, AssertTrueWithAssertionResult) { + ASSERT_TRUE(ResultIsEven(2)); +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)), + "Value of: ResultIsEven(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +#endif + ASSERT_TRUE(ResultIsEvenNoExplanation(2)); + EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)), + "Value of: ResultIsEvenNoExplanation(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +} + +// Tests ASSERT_FALSE. +TEST(AssertionTest, ASSERT_FALSE) { + ASSERT_FALSE(2 < 1); // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_FALSE(2 > 1), + "Value of: 2 > 1\n" + " Actual: true\n" + "Expected: false"); +} + +// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult. +TEST(AssertionTest, AssertFalseWithAssertionResult) { + ASSERT_FALSE(ResultIsEven(3)); +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)), + "Value of: ResultIsEven(2)\n" + " Actual: true (2 is even)\n" + "Expected: false"); +#endif + ASSERT_FALSE(ResultIsEvenNoExplanation(3)); + EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)), + "Value of: ResultIsEvenNoExplanation(2)\n" + " Actual: true\n" + "Expected: false"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +# pragma option pop +#endif + +// Tests using ASSERT_EQ on double values. The purpose is to make +// sure that the specialization we did for integer and anonymous enums +// isn't used for double arguments. +TEST(ExpectTest, ASSERT_EQ_Double) { + // A success. + ASSERT_EQ(5.6, 5.6); + + // A failure. + EXPECT_FATAL_FAILURE(ASSERT_EQ(5.1, 5.2), + "5.1"); +} + +// Tests ASSERT_EQ. +TEST(AssertionTest, ASSERT_EQ) { + ASSERT_EQ(5, 2 + 3); + EXPECT_FATAL_FAILURE(ASSERT_EQ(5, 2*3), + "Value of: 2*3\n" + " Actual: 6\n" + "Expected: 5"); +} + +// Tests ASSERT_EQ(NULL, pointer). +#if GTEST_CAN_COMPARE_NULL +TEST(AssertionTest, ASSERT_EQ_NULL) { + // A success. + const char* p = NULL; + // Some older GCC versions may issue a spurious waring in this or the next + // assertion statement. This warning should not be suppressed with + // static_cast since the test verifies the ability to use bare NULL as the + // expected parameter to the macro. + ASSERT_EQ(NULL, p); + + // A failure. + static int n = 0; + EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n), + "Value of: &n\n"); +} +#endif // GTEST_CAN_COMPARE_NULL + +// Tests ASSERT_EQ(0, non_pointer). Since the literal 0 can be +// treated as a null pointer by the compiler, we need to make sure +// that ASSERT_EQ(0, non_pointer) isn't interpreted by Google Test as +// ASSERT_EQ(static_cast(NULL), non_pointer). +TEST(ExpectTest, ASSERT_EQ_0) { + int n = 0; + + // A success. + ASSERT_EQ(0, n); + + // A failure. + EXPECT_FATAL_FAILURE(ASSERT_EQ(0, 5.6), + "Expected: 0"); +} + +// Tests ASSERT_NE. +TEST(AssertionTest, ASSERT_NE) { + ASSERT_NE(6, 7); + EXPECT_FATAL_FAILURE(ASSERT_NE('a', 'a'), + "Expected: ('a') != ('a'), " + "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); +} + +// Tests ASSERT_LE. +TEST(AssertionTest, ASSERT_LE) { + ASSERT_LE(2, 3); + ASSERT_LE(2, 2); + EXPECT_FATAL_FAILURE(ASSERT_LE(2, 0), + "Expected: (2) <= (0), actual: 2 vs 0"); +} + +// Tests ASSERT_LT. +TEST(AssertionTest, ASSERT_LT) { + ASSERT_LT(2, 3); + EXPECT_FATAL_FAILURE(ASSERT_LT(2, 2), + "Expected: (2) < (2), actual: 2 vs 2"); +} + +// Tests ASSERT_GE. +TEST(AssertionTest, ASSERT_GE) { + ASSERT_GE(2, 1); + ASSERT_GE(2, 2); + EXPECT_FATAL_FAILURE(ASSERT_GE(2, 3), + "Expected: (2) >= (3), actual: 2 vs 3"); +} + +// Tests ASSERT_GT. +TEST(AssertionTest, ASSERT_GT) { + ASSERT_GT(2, 1); + EXPECT_FATAL_FAILURE(ASSERT_GT(2, 2), + "Expected: (2) > (2), actual: 2 vs 2"); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowNothing() {} + +// Tests ASSERT_THROW. +TEST(AssertionTest, ASSERT_THROW) { + ASSERT_THROW(ThrowAnInteger(), int); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE( + ASSERT_THROW(ThrowAnInteger(), bool), + "Expected: ThrowAnInteger() throws an exception of type bool.\n" + " Actual: it throws a different type."); +# endif + + EXPECT_FATAL_FAILURE( + ASSERT_THROW(ThrowNothing(), bool), + "Expected: ThrowNothing() throws an exception of type bool.\n" + " Actual: it throws nothing."); +} + +// Tests ASSERT_NO_THROW. +TEST(AssertionTest, ASSERT_NO_THROW) { + ASSERT_NO_THROW(ThrowNothing()); + EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()), + "Expected: ThrowAnInteger() doesn't throw an exception." + "\n Actual: it throws."); +} + +// Tests ASSERT_ANY_THROW. +TEST(AssertionTest, ASSERT_ANY_THROW) { + ASSERT_ANY_THROW(ThrowAnInteger()); + EXPECT_FATAL_FAILURE( + ASSERT_ANY_THROW(ThrowNothing()), + "Expected: ThrowNothing() throws an exception.\n" + " Actual: it doesn't."); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Makes sure we deal with the precedence of <<. This test should +// compile. +TEST(AssertionTest, AssertPrecedence) { + ASSERT_EQ(1 < 2, true); + bool false_value = false; + ASSERT_EQ(true && false_value, false); +} + +// A subroutine used by the following test. +void TestEq1(int x) { + ASSERT_EQ(1, x); +} + +// Tests calling a test subroutine that's not part of a fixture. +TEST(AssertionTest, NonFixtureSubroutine) { + EXPECT_FATAL_FAILURE(TestEq1(2), + "Value of: x"); +} + +// An uncopyable class. +class Uncopyable { + public: + explicit Uncopyable(int a_value) : value_(a_value) {} + + int value() const { return value_; } + bool operator==(const Uncopyable& rhs) const { + return value() == rhs.value(); + } + private: + // This constructor deliberately has no implementation, as we don't + // want this class to be copyable. + Uncopyable(const Uncopyable&); // NOLINT + + int value_; +}; + +::std::ostream& operator<<(::std::ostream& os, const Uncopyable& value) { + return os << value.value(); +} + + +bool IsPositiveUncopyable(const Uncopyable& x) { + return x.value() > 0; +} + +// A subroutine used by the following test. +void TestAssertNonPositive() { + Uncopyable y(-1); + ASSERT_PRED1(IsPositiveUncopyable, y); +} +// A subroutine used by the following test. +void TestAssertEqualsUncopyable() { + Uncopyable x(5); + Uncopyable y(-1); + ASSERT_EQ(x, y); +} + +// Tests that uncopyable objects can be used in assertions. +TEST(AssertionTest, AssertWorksWithUncopyableObject) { + Uncopyable x(5); + ASSERT_PRED1(IsPositiveUncopyable, x); + ASSERT_EQ(x, x); + EXPECT_FATAL_FAILURE(TestAssertNonPositive(), + "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); + EXPECT_FATAL_FAILURE(TestAssertEqualsUncopyable(), + "Value of: y\n Actual: -1\nExpected: x\nWhich is: 5"); +} + +// Tests that uncopyable objects can be used in expects. +TEST(AssertionTest, ExpectWorksWithUncopyableObject) { + Uncopyable x(5); + EXPECT_PRED1(IsPositiveUncopyable, x); + Uncopyable y(-1); + EXPECT_NONFATAL_FAILURE(EXPECT_PRED1(IsPositiveUncopyable, y), + "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); + EXPECT_EQ(x, x); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), + "Value of: y\n Actual: -1\nExpected: x\nWhich is: 5"); +} + +enum NamedEnum { + kE1 = 0, + kE2 = 1 +}; + +TEST(AssertionTest, NamedEnum) { + EXPECT_EQ(kE1, kE1); + EXPECT_LT(kE1, kE2); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Which is: 0"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Actual: 1"); +} + +// The version of gcc used in XCode 2.2 has a bug and doesn't allow +// anonymous enums in assertions. Therefore the following test is not +// done on Mac. +// Sun Studio and HP aCC also reject this code. +#if !GTEST_OS_MAC && !defined(__SUNPRO_CC) && !defined(__HP_aCC) + +// Tests using assertions with anonymous enums. +enum { + kCaseA = -1, + +# if GTEST_OS_LINUX + + // We want to test the case where the size of the anonymous enum is + // larger than sizeof(int), to make sure our implementation of the + // assertions doesn't truncate the enums. However, MSVC + // (incorrectly) doesn't allow an enum value to exceed the range of + // an int, so this has to be conditionally compiled. + // + // On Linux, kCaseB and kCaseA have the same value when truncated to + // int size. We want to test whether this will confuse the + // assertions. + kCaseB = testing::internal::kMaxBiggestInt, + +# else + + kCaseB = INT_MAX, + +# endif // GTEST_OS_LINUX + + kCaseC = 42 +}; + +TEST(AssertionTest, AnonymousEnum) { +# if GTEST_OS_LINUX + + EXPECT_EQ(static_cast(kCaseA), static_cast(kCaseB)); + +# endif // GTEST_OS_LINUX + + EXPECT_EQ(kCaseA, kCaseA); + EXPECT_NE(kCaseA, kCaseB); + EXPECT_LT(kCaseA, kCaseB); + EXPECT_LE(kCaseA, kCaseB); + EXPECT_GT(kCaseB, kCaseA); + EXPECT_GE(kCaseA, kCaseA); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseB), + "(kCaseA) >= (kCaseB)"); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseC), + "-1 vs 42"); + + ASSERT_EQ(kCaseA, kCaseA); + ASSERT_NE(kCaseA, kCaseB); + ASSERT_LT(kCaseA, kCaseB); + ASSERT_LE(kCaseA, kCaseB); + ASSERT_GT(kCaseB, kCaseA); + ASSERT_GE(kCaseA, kCaseA); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), + "Value of: kCaseB"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), + "Actual: 42"); +# endif + + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), + "Which is: -1"); +} + +#endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC) + +#if GTEST_OS_WINDOWS + +static HRESULT UnexpectedHRESULTFailure() { + return E_UNEXPECTED; +} + +static HRESULT OkHRESULTSuccess() { + return S_OK; +} + +static HRESULT FalseHRESULTSuccess() { + return S_FALSE; +} + +// HRESULT assertion tests test both zero and non-zero +// success codes as well as failure message for each. +// +// Windows CE doesn't support message texts. +TEST(HRESULTAssertionTest, EXPECT_HRESULT_SUCCEEDED) { + EXPECT_HRESULT_SUCCEEDED(S_OK); + EXPECT_HRESULT_SUCCEEDED(S_FALSE); + + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"); +} + +TEST(HRESULTAssertionTest, ASSERT_HRESULT_SUCCEEDED) { + ASSERT_HRESULT_SUCCEEDED(S_OK); + ASSERT_HRESULT_SUCCEEDED(S_FALSE); + + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"); +} + +TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) { + EXPECT_HRESULT_FAILED(E_UNEXPECTED); + + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(OkHRESULTSuccess()), + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x00000000"); + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(FalseHRESULTSuccess()), + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x00000001"); +} + +TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { + ASSERT_HRESULT_FAILED(E_UNEXPECTED); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x00000000"); +# endif + + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x00000001"); +} + +// Tests that streaming to the HRESULT macros works. +TEST(HRESULTAssertionTest, Streaming) { + EXPECT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; + ASSERT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; + EXPECT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; + ASSERT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; + + EXPECT_NONFATAL_FAILURE( + EXPECT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", + "expected failure"); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE( + ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", + "expected failure"); +# endif + + EXPECT_NONFATAL_FAILURE( + EXPECT_HRESULT_FAILED(S_OK) << "expected failure", + "expected failure"); + + EXPECT_FATAL_FAILURE( + ASSERT_HRESULT_FAILED(S_OK) << "expected failure", + "expected failure"); +} + +#endif // GTEST_OS_WINDOWS + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +// Tests that the assertion macros behave like single statements. +TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + ASSERT_TRUE(false) << "This should never be executed; " + "It's a compilation test only."; + + if (AlwaysTrue()) + EXPECT_FALSE(false); + else + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_LT(1, 3); + + if (AlwaysFalse()) + ; // NOLINT + else + EXPECT_GT(3, 2) << ""; +} + +#if GTEST_HAS_EXCEPTIONS +// Tests that the compiler will not complain about unreachable code in the +// EXPECT_THROW/EXPECT_ANY_THROW/EXPECT_NO_THROW macros. +TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { + int n = 0; + + EXPECT_THROW(throw 1, int); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(n++, int), ""); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(throw 1, const char*), ""); + EXPECT_NO_THROW(n++); + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(throw 1), ""); + EXPECT_ANY_THROW(throw 1); + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(n++), ""); +} + +TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + EXPECT_THROW(ThrowNothing(), bool); + + if (AlwaysTrue()) + EXPECT_THROW(ThrowAnInteger(), int); + else + ; // NOLINT + + if (AlwaysFalse()) + EXPECT_NO_THROW(ThrowAnInteger()); + + if (AlwaysTrue()) + EXPECT_NO_THROW(ThrowNothing()); + else + ; // NOLINT + + if (AlwaysFalse()) + EXPECT_ANY_THROW(ThrowNothing()); + + if (AlwaysTrue()) + EXPECT_ANY_THROW(ThrowAnInteger()); + else + ; // NOLINT +} +#endif // GTEST_HAS_EXCEPTIONS + +TEST(AssertionSyntaxTest, NoFatalFailureAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + EXPECT_NO_FATAL_FAILURE(FAIL()) << "This should never be executed. " + << "It's a compilation test only."; + else + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_NO_FATAL_FAILURE(FAIL()) << ""; + else + ; // NOLINT + + if (AlwaysTrue()) + EXPECT_NO_FATAL_FAILURE(SUCCEED()); + else + ; // NOLINT + + if (AlwaysFalse()) + ; // NOLINT + else + ASSERT_NO_FATAL_FAILURE(SUCCEED()); +} + +// Tests that the assertion macros work well with switch statements. +TEST(AssertionSyntaxTest, WorksWithSwitch) { + switch (0) { + case 1: + break; + default: + ASSERT_TRUE(true); + } + + switch (0) + case 0: + EXPECT_FALSE(false) << "EXPECT_FALSE failed in switch case"; + + // Binary assertions are implemented using a different code path + // than the Boolean assertions. Hence we test them separately. + switch (0) { + case 1: + default: + ASSERT_EQ(1, 1) << "ASSERT_EQ failed in default switch handler"; + } + + switch (0) + case 0: + EXPECT_NE(1, 2); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowAString() { + throw "std::string"; +} + +// Test that the exception assertion macros compile and work with const +// type qualifier. +TEST(AssertionSyntaxTest, WorksWithConst) { + ASSERT_THROW(ThrowAString(), const char*); + + EXPECT_THROW(ThrowAString(), const char*); +} + +#endif // GTEST_HAS_EXCEPTIONS + +} // namespace + +namespace testing { + +// Tests that Google Test tracks SUCCEED*. +TEST(SuccessfulAssertionTest, SUCCEED) { + SUCCEED(); + SUCCEED() << "OK"; + EXPECT_EQ(2, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful EXPECT_*. +TEST(SuccessfulAssertionTest, EXPECT) { + EXPECT_TRUE(true); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful EXPECT_STR*. +TEST(SuccessfulAssertionTest, EXPECT_STR) { + EXPECT_STREQ("", ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful ASSERT_*. +TEST(SuccessfulAssertionTest, ASSERT) { + ASSERT_TRUE(true); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful ASSERT_STR*. +TEST(SuccessfulAssertionTest, ASSERT_STR) { + ASSERT_STREQ("", ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +} // namespace testing + +namespace { + +// Tests the message streaming variation of assertions. + +TEST(AssertionWithMessageTest, EXPECT) { + EXPECT_EQ(1, 1) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_NE(1, 1) << "Expected failure #1.", + "Expected failure #1"); + EXPECT_LE(1, 2) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_LT(1, 0) << "Expected failure #2.", + "Expected failure #2."); + EXPECT_GE(1, 0) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_GT(1, 2) << "Expected failure #3.", + "Expected failure #3."); + + EXPECT_STREQ("1", "1") << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("1", "1") << "Expected failure #4.", + "Expected failure #4."); + EXPECT_STRCASEEQ("a", "A") << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("a", "A") << "Expected failure #5.", + "Expected failure #5."); + + EXPECT_FLOAT_EQ(1, 1) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1, 1.2) << "Expected failure #6.", + "Expected failure #6."); + EXPECT_NEAR(1, 1.1, 0.2) << "This should succeed."; +} + +TEST(AssertionWithMessageTest, ASSERT) { + ASSERT_EQ(1, 1) << "This should succeed."; + ASSERT_NE(1, 2) << "This should succeed."; + ASSERT_LE(1, 2) << "This should succeed."; + ASSERT_LT(1, 2) << "This should succeed."; + ASSERT_GE(1, 0) << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_GT(1, 2) << "Expected failure.", + "Expected failure."); +} + +TEST(AssertionWithMessageTest, ASSERT_STR) { + ASSERT_STREQ("1", "1") << "This should succeed."; + ASSERT_STRNE("1", "2") << "This should succeed."; + ASSERT_STRCASEEQ("a", "A") << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("a", "A") << "Expected failure.", + "Expected failure."); +} + +TEST(AssertionWithMessageTest, ASSERT_FLOATING) { + ASSERT_FLOAT_EQ(1, 1) << "This should succeed."; + ASSERT_DOUBLE_EQ(1, 1) << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1,1.2, 0.1) << "Expect failure.", // NOLINT + "Expect failure."); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests using ASSERT_FALSE with a streamed message. +TEST(AssertionWithMessageTest, ASSERT_FALSE) { + ASSERT_FALSE(false) << "This shouldn't fail."; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_FALSE(true) << "Expected failure: " << 2 << " > " << 1 + << " evaluates to " << true; + }, "Expected failure"); +} + +// Tests using FAIL with a streamed message. +TEST(AssertionWithMessageTest, FAIL) { + EXPECT_FATAL_FAILURE(FAIL() << 0, + "0"); +} + +// Tests using SUCCEED with a streamed message. +TEST(AssertionWithMessageTest, SUCCEED) { + SUCCEED() << "Success == " << 1; +} + +// Tests using ASSERT_TRUE with a streamed message. +TEST(AssertionWithMessageTest, ASSERT_TRUE) { + ASSERT_TRUE(true) << "This should succeed."; + ASSERT_TRUE(true) << true; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_TRUE(false) << static_cast(NULL) + << static_cast(NULL); + }, "(null)(null)"); +} + +#if GTEST_OS_WINDOWS +// Tests using wide strings in assertion messages. +TEST(AssertionWithMessageTest, WideStringMessage) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_TRUE(false) << L"This failure is expected.\x8119"; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(1, 2) << "This failure is " + << L"expected too.\x8120"; + }, "This failure is expected too."); +} +#endif // GTEST_OS_WINDOWS + +// Tests EXPECT_TRUE. +TEST(ExpectTest, EXPECT_TRUE) { + EXPECT_TRUE(true) << "Intentional success"; + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #1.", + "Intentional failure #1."); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #2.", + "Intentional failure #2."); + EXPECT_TRUE(2 > 1); // NOLINT + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 < 1), + "Value of: 2 < 1\n" + " Actual: false\n" + "Expected: true"); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 > 3), + "2 > 3"); +} + +// Tests EXPECT_TRUE(predicate) for predicates returning AssertionResult. +TEST(ExpectTest, ExpectTrueWithAssertionResult) { + EXPECT_TRUE(ResultIsEven(2)); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEven(3)), + "Value of: ResultIsEven(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); + EXPECT_TRUE(ResultIsEvenNoExplanation(2)); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEvenNoExplanation(3)), + "Value of: ResultIsEvenNoExplanation(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +} + +// Tests EXPECT_FALSE with a streamed message. +TEST(ExpectTest, EXPECT_FALSE) { + EXPECT_FALSE(2 < 1); // NOLINT + EXPECT_FALSE(false) << "Intentional success"; + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #1.", + "Intentional failure #1."); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #2.", + "Intentional failure #2."); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 > 1), + "Value of: 2 > 1\n" + " Actual: true\n" + "Expected: false"); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 < 3), + "2 < 3"); +} + +// Tests EXPECT_FALSE(predicate) for predicates returning AssertionResult. +TEST(ExpectTest, ExpectFalseWithAssertionResult) { + EXPECT_FALSE(ResultIsEven(3)); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEven(2)), + "Value of: ResultIsEven(2)\n" + " Actual: true (2 is even)\n" + "Expected: false"); + EXPECT_FALSE(ResultIsEvenNoExplanation(3)); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEvenNoExplanation(2)), + "Value of: ResultIsEvenNoExplanation(2)\n" + " Actual: true\n" + "Expected: false"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +# pragma option pop +#endif + +// Tests EXPECT_EQ. +TEST(ExpectTest, EXPECT_EQ) { + EXPECT_EQ(5, 2 + 3); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2*3), + "Value of: 2*3\n" + " Actual: 6\n" + "Expected: 5"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2 - 3), + "2 - 3"); +} + +// Tests using EXPECT_EQ on double values. The purpose is to make +// sure that the specialization we did for integer and anonymous enums +// isn't used for double arguments. +TEST(ExpectTest, EXPECT_EQ_Double) { + // A success. + EXPECT_EQ(5.6, 5.6); + + // A failure. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5.1, 5.2), + "5.1"); +} + +#if GTEST_CAN_COMPARE_NULL +// Tests EXPECT_EQ(NULL, pointer). +TEST(ExpectTest, EXPECT_EQ_NULL) { + // A success. + const char* p = NULL; + // Some older GCC versions may issue a spurious warning in this or the next + // assertion statement. This warning should not be suppressed with + // static_cast since the test verifies the ability to use bare NULL as the + // expected parameter to the macro. + EXPECT_EQ(NULL, p); + + // A failure. + int n = 0; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n), + "Value of: &n\n"); +} +#endif // GTEST_CAN_COMPARE_NULL + +// Tests EXPECT_EQ(0, non_pointer). Since the literal 0 can be +// treated as a null pointer by the compiler, we need to make sure +// that EXPECT_EQ(0, non_pointer) isn't interpreted by Google Test as +// EXPECT_EQ(static_cast(NULL), non_pointer). +TEST(ExpectTest, EXPECT_EQ_0) { + int n = 0; + + // A success. + EXPECT_EQ(0, n); + + // A failure. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(0, 5.6), + "Expected: 0"); +} + +// Tests EXPECT_NE. +TEST(ExpectTest, EXPECT_NE) { + EXPECT_NE(6, 7); + + EXPECT_NONFATAL_FAILURE(EXPECT_NE('a', 'a'), + "Expected: ('a') != ('a'), " + "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); + EXPECT_NONFATAL_FAILURE(EXPECT_NE(2, 2), + "2"); + char* const p0 = NULL; + EXPECT_NONFATAL_FAILURE(EXPECT_NE(p0, p0), + "p0"); + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + char* const p1 = reinterpret_cast(pv1); + EXPECT_NONFATAL_FAILURE(EXPECT_NE(p1, p1), + "p1"); +} + +// Tests EXPECT_LE. +TEST(ExpectTest, EXPECT_LE) { + EXPECT_LE(2, 3); + EXPECT_LE(2, 2); + EXPECT_NONFATAL_FAILURE(EXPECT_LE(2, 0), + "Expected: (2) <= (0), actual: 2 vs 0"); + EXPECT_NONFATAL_FAILURE(EXPECT_LE(1.1, 0.9), + "(1.1) <= (0.9)"); +} + +// Tests EXPECT_LT. +TEST(ExpectTest, EXPECT_LT) { + EXPECT_LT(2, 3); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 2), + "Expected: (2) < (2), actual: 2 vs 2"); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1), + "(2) < (1)"); +} + +// Tests EXPECT_GE. +TEST(ExpectTest, EXPECT_GE) { + EXPECT_GE(2, 1); + EXPECT_GE(2, 2); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(2, 3), + "Expected: (2) >= (3), actual: 2 vs 3"); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(0.9, 1.1), + "(0.9) >= (1.1)"); +} + +// Tests EXPECT_GT. +TEST(ExpectTest, EXPECT_GT) { + EXPECT_GT(2, 1); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 2), + "Expected: (2) > (2), actual: 2 vs 2"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 3), + "(2) > (3)"); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests EXPECT_THROW. +TEST(ExpectTest, EXPECT_THROW) { + EXPECT_THROW(ThrowAnInteger(), int); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool), + "Expected: ThrowAnInteger() throws an exception of " + "type bool.\n Actual: it throws a different type."); + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW(ThrowNothing(), bool), + "Expected: ThrowNothing() throws an exception of type bool.\n" + " Actual: it throws nothing."); +} + +// Tests EXPECT_NO_THROW. +TEST(ExpectTest, EXPECT_NO_THROW) { + EXPECT_NO_THROW(ThrowNothing()); + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()), + "Expected: ThrowAnInteger() doesn't throw an " + "exception.\n Actual: it throws."); +} + +// Tests EXPECT_ANY_THROW. +TEST(ExpectTest, EXPECT_ANY_THROW) { + EXPECT_ANY_THROW(ThrowAnInteger()); + EXPECT_NONFATAL_FAILURE( + EXPECT_ANY_THROW(ThrowNothing()), + "Expected: ThrowNothing() throws an exception.\n" + " Actual: it doesn't."); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Make sure we deal with the precedence of <<. +TEST(ExpectTest, ExpectPrecedence) { + EXPECT_EQ(1 < 2, true); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(true, true && false), + "Value of: true && false"); +} + + +// Tests the StreamableToString() function. + +// Tests using StreamableToString() on a scalar. +TEST(StreamableToStringTest, Scalar) { + EXPECT_STREQ("5", StreamableToString(5).c_str()); +} + +// Tests using StreamableToString() on a non-char pointer. +TEST(StreamableToStringTest, Pointer) { + int n = 0; + int* p = &n; + EXPECT_STRNE("(null)", StreamableToString(p).c_str()); +} + +// Tests using StreamableToString() on a NULL non-char pointer. +TEST(StreamableToStringTest, NullPointer) { + int* p = NULL; + EXPECT_STREQ("(null)", StreamableToString(p).c_str()); +} + +// Tests using StreamableToString() on a C string. +TEST(StreamableToStringTest, CString) { + EXPECT_STREQ("Foo", StreamableToString("Foo").c_str()); +} + +// Tests using StreamableToString() on a NULL C string. +TEST(StreamableToStringTest, NullCString) { + char* p = NULL; + EXPECT_STREQ("(null)", StreamableToString(p).c_str()); +} + +// Tests using streamable values as assertion messages. + +// Tests using std::string as an assertion message. +TEST(StreamableTest, string) { + static const std::string str( + "This failure message is a std::string, and is expected."); + EXPECT_FATAL_FAILURE(FAIL() << str, + str.c_str()); +} + +// Tests that we can output strings containing embedded NULs. +// Limited to Linux because we can only do this with std::string's. +TEST(StreamableTest, stringWithEmbeddedNUL) { + static const char char_array_with_nul[] = + "Here's a NUL\0 and some more string"; + static const std::string string_with_nul(char_array_with_nul, + sizeof(char_array_with_nul) + - 1); // drops the trailing NUL + EXPECT_FATAL_FAILURE(FAIL() << string_with_nul, + "Here's a NUL\\0 and some more string"); +} + +// Tests that we can output a NUL char. +TEST(StreamableTest, NULChar) { + EXPECT_FATAL_FAILURE({ // NOLINT + FAIL() << "A NUL" << '\0' << " and some more string"; + }, "A NUL\\0 and some more string"); +} + +// Tests using int as an assertion message. +TEST(StreamableTest, int) { + EXPECT_FATAL_FAILURE(FAIL() << 900913, + "900913"); +} + +// Tests using NULL char pointer as an assertion message. +// +// In MSVC, streaming a NULL char * causes access violation. Google Test +// implemented a workaround (substituting "(null)" for NULL). This +// tests whether the workaround works. +TEST(StreamableTest, NullCharPtr) { + EXPECT_FATAL_FAILURE(FAIL() << static_cast(NULL), + "(null)"); +} + +// Tests that basic IO manipulators (endl, ends, and flush) can be +// streamed to testing::Message. +TEST(StreamableTest, BasicIoManip) { + EXPECT_FATAL_FAILURE({ // NOLINT + FAIL() << "Line 1." << std::endl + << "A NUL char " << std::ends << std::flush << " in line 2."; + }, "Line 1.\nA NUL char \\0 in line 2."); +} + +// Tests the macros that haven't been covered so far. + +void AddFailureHelper(bool* aborted) { + *aborted = true; + ADD_FAILURE() << "Intentional failure."; + *aborted = false; +} + +// Tests ADD_FAILURE. +TEST(MacroTest, ADD_FAILURE) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(AddFailureHelper(&aborted), + "Intentional failure."); + EXPECT_FALSE(aborted); +} + +// Tests ADD_FAILURE_AT. +TEST(MacroTest, ADD_FAILURE_AT) { + // Verifies that ADD_FAILURE_AT does generate a nonfatal failure and + // the failure message contains the user-streamed part. + EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42) << "Wrong!", "Wrong!"); + + // Verifies that the user-streamed part is optional. + EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42), "Failed"); + + // Unfortunately, we cannot verify that the failure message contains + // the right file path and line number the same way, as + // EXPECT_NONFATAL_FAILURE() doesn't get to see the file path and + // line number. Instead, we do that in gtest_output_test_.cc. +} + +// Tests FAIL. +TEST(MacroTest, FAIL) { + EXPECT_FATAL_FAILURE(FAIL(), + "Failed"); + EXPECT_FATAL_FAILURE(FAIL() << "Intentional failure.", + "Intentional failure."); +} + +// Tests SUCCEED +TEST(MacroTest, SUCCEED) { + SUCCEED(); + SUCCEED() << "Explicit success."; +} + +// Tests for EXPECT_EQ() and ASSERT_EQ(). +// +// These tests fail *intentionally*, s.t. the failure messages can be +// generated and tested. +// +// We have different tests for different argument types. + +// Tests using bool values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Bool) { + EXPECT_EQ(true, true); + EXPECT_FATAL_FAILURE({ + bool false_value = false; + ASSERT_EQ(false_value, true); + }, "Value of: true"); +} + +// Tests using int values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Int) { + ASSERT_EQ(32, 32); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(32, 33), + "33"); +} + +// Tests using time_t values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Time_T) { + EXPECT_EQ(static_cast(0), + static_cast(0)); + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0), + static_cast(1234)), + "1234"); +} + +// Tests using char values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Char) { + ASSERT_EQ('z', 'z'); + const char ch = 'b'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ('\0', ch), + "ch"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ('a', ch), + "ch"); +} + +// Tests using wchar_t values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, WideChar) { + EXPECT_EQ(L'b', L'b'); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'\0', L'x'), + "Value of: L'x'\n" + " Actual: L'x' (120, 0x78)\n" + "Expected: L'\0'\n" + "Which is: L'\0' (0, 0x0)"); + + static wchar_t wchar; + wchar = L'b'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'a', wchar), + "wchar"); + wchar = 0x8119; + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0x8120), wchar), + "Value of: wchar"); +} + +// Tests using ::std::string values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, StdString) { + // Compares a const char* to an std::string that has identical + // content. + ASSERT_EQ("Test", ::std::string("Test")); + + // Compares two identical std::strings. + static const ::std::string str1("A * in the middle"); + static const ::std::string str2(str1); + EXPECT_EQ(str1, str2); + + // Compares a const char* to an std::string that has different + // content + EXPECT_NONFATAL_FAILURE(EXPECT_EQ("Test", ::std::string("test")), + "::std::string(\"test\")"); + + // Compares an std::string to a char* that has different content. + char* const p1 = const_cast("foo"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::std::string("bar"), p1), + "p1"); + + // Compares two std::strings that have different contents, one of + // which having a NUL character in the middle. This should fail. + static ::std::string str3(str1); + str3.at(2) = '\0'; + EXPECT_FATAL_FAILURE(ASSERT_EQ(str1, str3), + "Value of: str3\n" + " Actual: \"A \\0 in the middle\""); +} + +#if GTEST_HAS_STD_WSTRING + +// Tests using ::std::wstring values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, StdWideString) { + // Compares two identical std::wstrings. + const ::std::wstring wstr1(L"A * in the middle"); + const ::std::wstring wstr2(wstr1); + ASSERT_EQ(wstr1, wstr2); + + // Compares an std::wstring to a const wchar_t* that has identical + // content. + const wchar_t kTestX8119[] = { 'T', 'e', 's', 't', 0x8119, '\0' }; + EXPECT_EQ(::std::wstring(kTestX8119), kTestX8119); + + // Compares an std::wstring to a const wchar_t* that has different + // content. + const wchar_t kTestX8120[] = { 'T', 'e', 's', 't', 0x8120, '\0' }; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EQ(::std::wstring(kTestX8119), kTestX8120); + }, "kTestX8120"); + + // Compares two std::wstrings that have different contents, one of + // which having a NUL character in the middle. + ::std::wstring wstr3(wstr1); + wstr3.at(2) = L'\0'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(wstr1, wstr3), + "wstr3"); + + // Compares a wchar_t* to an std::wstring that has different + // content. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(const_cast(L"foo"), ::std::wstring(L"bar")); + }, ""); +} + +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_STRING +// Tests using ::string values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, GlobalString) { + // Compares a const char* to a ::string that has identical content. + EXPECT_EQ("Test", ::string("Test")); + + // Compares two identical ::strings. + const ::string str1("A * in the middle"); + const ::string str2(str1); + ASSERT_EQ(str1, str2); + + // Compares a ::string to a const char* that has different content. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::string("Test"), "test"), + "test"); + + // Compares two ::strings that have different contents, one of which + // having a NUL character in the middle. + ::string str3(str1); + str3.at(2) = '\0'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(str1, str3), + "str3"); + + // Compares a ::string to a char* that has different content. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(::string("bar"), const_cast("foo")); + }, ""); +} + +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING + +// Tests using ::wstring values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, GlobalWideString) { + // Compares two identical ::wstrings. + static const ::wstring wstr1(L"A * in the middle"); + static const ::wstring wstr2(wstr1); + EXPECT_EQ(wstr1, wstr2); + + // Compares a const wchar_t* to a ::wstring that has identical content. + const wchar_t kTestX8119[] = { 'T', 'e', 's', 't', 0x8119, '\0' }; + ASSERT_EQ(kTestX8119, ::wstring(kTestX8119)); + + // Compares a const wchar_t* to a ::wstring that has different + // content. + const wchar_t kTestX8120[] = { 'T', 'e', 's', 't', 0x8120, '\0' }; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EQ(kTestX8120, ::wstring(kTestX8119)); + }, "Test\\x8119"); + + // Compares a wchar_t* to a ::wstring that has different content. + wchar_t* const p1 = const_cast(L"foo"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, ::wstring(L"bar")), + "bar"); + + // Compares two ::wstrings that have different contents, one of which + // having a NUL character in the middle. + static ::wstring wstr3; + wstr3 = wstr1; + wstr3.at(2) = L'\0'; + EXPECT_FATAL_FAILURE(ASSERT_EQ(wstr1, wstr3), + "wstr3"); +} + +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Tests using char pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, CharPointer) { + char* const p0 = NULL; + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + void* pv2 = (void*)0xABC0; // NOLINT + char* const p1 = reinterpret_cast(pv1); + char* const p2 = reinterpret_cast(pv2); + ASSERT_EQ(p1, p1); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), + "Value of: p2"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), + "p2"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(reinterpret_cast(0x1234), + reinterpret_cast(0xABC0)), + "ABC0"); +} + +// Tests using wchar_t pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, WideCharPointer) { + wchar_t* const p0 = NULL; + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + void* pv2 = (void*)0xABC0; // NOLINT + wchar_t* const p1 = reinterpret_cast(pv1); + wchar_t* const p2 = reinterpret_cast(pv2); + EXPECT_EQ(p0, p0); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), + "Value of: p2"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), + "p2"); + void* pv3 = (void*)0x1234; // NOLINT + void* pv4 = (void*)0xABC0; // NOLINT + const wchar_t* p3 = reinterpret_cast(pv3); + const wchar_t* p4 = reinterpret_cast(pv4); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p3, p4), + "p4"); +} + +// Tests using other types of pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, OtherPointer) { + ASSERT_EQ(static_cast(NULL), + static_cast(NULL)); + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(NULL), + reinterpret_cast(0x1234)), + "0x1234"); +} + +// A class that supports binary comparison operators but not streaming. +class UnprintableChar { + public: + explicit UnprintableChar(char ch) : char_(ch) {} + + bool operator==(const UnprintableChar& rhs) const { + return char_ == rhs.char_; + } + bool operator!=(const UnprintableChar& rhs) const { + return char_ != rhs.char_; + } + bool operator<(const UnprintableChar& rhs) const { + return char_ < rhs.char_; + } + bool operator<=(const UnprintableChar& rhs) const { + return char_ <= rhs.char_; + } + bool operator>(const UnprintableChar& rhs) const { + return char_ > rhs.char_; + } + bool operator>=(const UnprintableChar& rhs) const { + return char_ >= rhs.char_; + } + + private: + char char_; +}; + +// Tests that ASSERT_EQ() and friends don't require the arguments to +// be printable. +TEST(ComparisonAssertionTest, AcceptsUnprintableArgs) { + const UnprintableChar x('x'), y('y'); + ASSERT_EQ(x, x); + EXPECT_NE(x, y); + ASSERT_LT(x, y); + EXPECT_LE(x, y); + ASSERT_GT(y, x); + EXPECT_GE(x, x); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <78>"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <79>"); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(y, y), "1-byte object <79>"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <78>"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <79>"); + + // Code tested by EXPECT_FATAL_FAILURE cannot reference local + // variables, so we have to write UnprintableChar('x') instead of x. +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')), + "1-byte object <78>"); + EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), + "1-byte object <78>"); +#endif + EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), + "1-byte object <79>"); + EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), + "1-byte object <78>"); + EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), + "1-byte object <79>"); +} + +// Tests the FRIEND_TEST macro. + +// This class has a private member we want to test. We will test it +// both in a TEST and in a TEST_F. +class Foo { + public: + Foo() {} + + private: + int Bar() const { return 1; } + + // Declares the friend tests that can access the private member + // Bar(). + FRIEND_TEST(FRIEND_TEST_Test, TEST); + FRIEND_TEST(FRIEND_TEST_Test2, TEST_F); +}; + +// Tests that the FRIEND_TEST declaration allows a TEST to access a +// class's private members. This should compile. +TEST(FRIEND_TEST_Test, TEST) { + ASSERT_EQ(1, Foo().Bar()); +} + +// The fixture needed to test using FRIEND_TEST with TEST_F. +class FRIEND_TEST_Test2 : public Test { + protected: + Foo foo; +}; + +// Tests that the FRIEND_TEST declaration allows a TEST_F to access a +// class's private members. This should compile. +TEST_F(FRIEND_TEST_Test2, TEST_F) { + ASSERT_EQ(1, foo.Bar()); +} + +// Tests the life cycle of Test objects. + +// The test fixture for testing the life cycle of Test objects. +// +// This class counts the number of live test objects that uses this +// fixture. +class TestLifeCycleTest : public Test { + protected: + // Constructor. Increments the number of test objects that uses + // this fixture. + TestLifeCycleTest() { count_++; } + + // Destructor. Decrements the number of test objects that uses this + // fixture. + ~TestLifeCycleTest() { count_--; } + + // Returns the number of live test objects that uses this fixture. + int count() const { return count_; } + + private: + static int count_; +}; + +int TestLifeCycleTest::count_ = 0; + +// Tests the life cycle of test objects. +TEST_F(TestLifeCycleTest, Test1) { + // There should be only one test object in this test case that's + // currently alive. + ASSERT_EQ(1, count()); +} + +// Tests the life cycle of test objects. +TEST_F(TestLifeCycleTest, Test2) { + // After Test1 is done and Test2 is started, there should still be + // only one live test object, as the object for Test1 should've been + // deleted. + ASSERT_EQ(1, count()); +} + +} // namespace + +// Tests that the copy constructor works when it is NOT optimized away by +// the compiler. +TEST(AssertionResultTest, CopyConstructorWorksWhenNotOptimied) { + // Checks that the copy constructor doesn't try to dereference NULL pointers + // in the source object. + AssertionResult r1 = AssertionSuccess(); + AssertionResult r2 = r1; + // The following line is added to prevent the compiler from optimizing + // away the constructor call. + r1 << "abc"; + + AssertionResult r3 = r1; + EXPECT_EQ(static_cast(r3), static_cast(r1)); + EXPECT_STREQ("abc", r1.message()); +} + +// Tests that AssertionSuccess and AssertionFailure construct +// AssertionResult objects as expected. +TEST(AssertionResultTest, ConstructionWorks) { + AssertionResult r1 = AssertionSuccess(); + EXPECT_TRUE(r1); + EXPECT_STREQ("", r1.message()); + + AssertionResult r2 = AssertionSuccess() << "abc"; + EXPECT_TRUE(r2); + EXPECT_STREQ("abc", r2.message()); + + AssertionResult r3 = AssertionFailure(); + EXPECT_FALSE(r3); + EXPECT_STREQ("", r3.message()); + + AssertionResult r4 = AssertionFailure() << "def"; + EXPECT_FALSE(r4); + EXPECT_STREQ("def", r4.message()); + + AssertionResult r5 = AssertionFailure(Message() << "ghi"); + EXPECT_FALSE(r5); + EXPECT_STREQ("ghi", r5.message()); +} + +// Tests that the negation flips the predicate result but keeps the message. +TEST(AssertionResultTest, NegationWorks) { + AssertionResult r1 = AssertionSuccess() << "abc"; + EXPECT_FALSE(!r1); + EXPECT_STREQ("abc", (!r1).message()); + + AssertionResult r2 = AssertionFailure() << "def"; + EXPECT_TRUE(!r2); + EXPECT_STREQ("def", (!r2).message()); +} + +TEST(AssertionResultTest, StreamingWorks) { + AssertionResult r = AssertionSuccess(); + r << "abc" << 'd' << 0 << true; + EXPECT_STREQ("abcd0true", r.message()); +} + +TEST(AssertionResultTest, CanStreamOstreamManipulators) { + AssertionResult r = AssertionSuccess(); + r << "Data" << std::endl << std::flush << std::ends << "Will be visible"; + EXPECT_STREQ("Data\n\\0Will be visible", r.message()); +} + +// Tests streaming a user type whose definition and operator << are +// both in the global namespace. +class Base { + public: + explicit Base(int an_x) : x_(an_x) {} + int x() const { return x_; } + private: + int x_; +}; +std::ostream& operator<<(std::ostream& os, + const Base& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const Base* pointer) { + return os << "(" << pointer->x() << ")"; +} + +TEST(MessageTest, CanStreamUserTypeInGlobalNameSpace) { + Message msg; + Base a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition and operator<< are +// both in an unnamed namespace. +namespace { +class MyTypeInUnnamedNameSpace : public Base { + public: + explicit MyTypeInUnnamedNameSpace(int an_x): Base(an_x) {} +}; +std::ostream& operator<<(std::ostream& os, + const MyTypeInUnnamedNameSpace& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const MyTypeInUnnamedNameSpace* pointer) { + return os << "(" << pointer->x() << ")"; +} +} // namespace + +TEST(MessageTest, CanStreamUserTypeInUnnamedNameSpace) { + Message msg; + MyTypeInUnnamedNameSpace a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition and operator<< are +// both in a user namespace. +namespace namespace1 { +class MyTypeInNameSpace1 : public Base { + public: + explicit MyTypeInNameSpace1(int an_x): Base(an_x) {} +}; +std::ostream& operator<<(std::ostream& os, + const MyTypeInNameSpace1& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const MyTypeInNameSpace1* pointer) { + return os << "(" << pointer->x() << ")"; +} +} // namespace namespace1 + +TEST(MessageTest, CanStreamUserTypeInUserNameSpace) { + Message msg; + namespace1::MyTypeInNameSpace1 a(1); + + msg << a << &a; // Uses namespace1::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition is in a user namespace +// but whose operator<< is in the global namespace. +namespace namespace2 { +class MyTypeInNameSpace2 : public ::Base { + public: + explicit MyTypeInNameSpace2(int an_x): Base(an_x) {} +}; +} // namespace namespace2 +std::ostream& operator<<(std::ostream& os, + const namespace2::MyTypeInNameSpace2& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const namespace2::MyTypeInNameSpace2* pointer) { + return os << "(" << pointer->x() << ")"; +} + +TEST(MessageTest, CanStreamUserTypeInUserNameSpaceWithStreamOperatorInGlobal) { + Message msg; + namespace2::MyTypeInNameSpace2 a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming NULL pointers to testing::Message. +TEST(MessageTest, NullPointers) { + Message msg; + char* const p1 = NULL; + unsigned char* const p2 = NULL; + int* p3 = NULL; + double* p4 = NULL; + bool* p5 = NULL; + Message* p6 = NULL; + + msg << p1 << p2 << p3 << p4 << p5 << p6; + ASSERT_STREQ("(null)(null)(null)(null)(null)(null)", + msg.GetString().c_str()); +} + +// Tests streaming wide strings to testing::Message. +TEST(MessageTest, WideStrings) { + // Streams a NULL of type const wchar_t*. + const wchar_t* const_wstr = NULL; + EXPECT_STREQ("(null)", + (Message() << const_wstr).GetString().c_str()); + + // Streams a NULL of type wchar_t*. + wchar_t* wstr = NULL; + EXPECT_STREQ("(null)", + (Message() << wstr).GetString().c_str()); + + // Streams a non-NULL of type const wchar_t*. + const_wstr = L"abc\x8119"; + EXPECT_STREQ("abc\xe8\x84\x99", + (Message() << const_wstr).GetString().c_str()); + + // Streams a non-NULL of type wchar_t*. + wstr = const_cast(const_wstr); + EXPECT_STREQ("abc\xe8\x84\x99", + (Message() << wstr).GetString().c_str()); +} + + +// This line tests that we can define tests in the testing namespace. +namespace testing { + +// Tests the TestInfo class. + +class TestInfoTest : public Test { + protected: + static const TestInfo* GetTestInfo(const char* test_name) { + const TestCase* const test_case = GetUnitTestImpl()-> + GetTestCase("TestInfoTest", "", NULL, NULL); + + for (int i = 0; i < test_case->total_test_count(); ++i) { + const TestInfo* const test_info = test_case->GetTestInfo(i); + if (strcmp(test_name, test_info->name()) == 0) + return test_info; + } + return NULL; + } + + static const TestResult* GetTestResult( + const TestInfo* test_info) { + return test_info->result(); + } +}; + +// Tests TestInfo::test_case_name() and TestInfo::name(). +TEST_F(TestInfoTest, Names) { + const TestInfo* const test_info = GetTestInfo("Names"); + + ASSERT_STREQ("TestInfoTest", test_info->test_case_name()); + ASSERT_STREQ("Names", test_info->name()); +} + +// Tests TestInfo::result(). +TEST_F(TestInfoTest, result) { + const TestInfo* const test_info = GetTestInfo("result"); + + // Initially, there is no TestPartResult for this test. + ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); + + // After the previous assertion, there is still none. + ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); +} + +// Tests setting up and tearing down a test case. + +class SetUpTestCaseTest : public Test { + protected: + // This will be called once before the first test in this test case + // is run. + static void SetUpTestCase() { + printf("Setting up the test case . . .\n"); + + // Initializes some shared resource. In this simple example, we + // just create a C string. More complex stuff can be done if + // desired. + shared_resource_ = "123"; + + // Increments the number of test cases that have been set up. + counter_++; + + // SetUpTestCase() should be called only once. + EXPECT_EQ(1, counter_); + } + + // This will be called once after the last test in this test case is + // run. + static void TearDownTestCase() { + printf("Tearing down the test case . . .\n"); + + // Decrements the number of test cases that have been set up. + counter_--; + + // TearDownTestCase() should be called only once. + EXPECT_EQ(0, counter_); + + // Cleans up the shared resource. + shared_resource_ = NULL; + } + + // This will be called before each test in this test case. + virtual void SetUp() { + // SetUpTestCase() should be called only once, so counter_ should + // always be 1. + EXPECT_EQ(1, counter_); + } + + // Number of test cases that have been set up. + static int counter_; + + // Some resource to be shared by all tests in this test case. + static const char* shared_resource_; +}; + +int SetUpTestCaseTest::counter_ = 0; +const char* SetUpTestCaseTest::shared_resource_ = NULL; + +// A test that uses the shared resource. +TEST_F(SetUpTestCaseTest, Test1) { + EXPECT_STRNE(NULL, shared_resource_); +} + +// Another test that uses the shared resource. +TEST_F(SetUpTestCaseTest, Test2) { + EXPECT_STREQ("123", shared_resource_); +} + +// The InitGoogleTestTest test case tests testing::InitGoogleTest(). + +// The Flags struct stores a copy of all Google Test flags. +struct Flags { + // Constructs a Flags struct where each flag has its default value. + Flags() : also_run_disabled_tests(false), + break_on_failure(false), + catch_exceptions(false), + death_test_use_fork(false), + filter(""), + list_tests(false), + output(""), + print_time(true), + random_seed(0), + repeat(1), + shuffle(false), + stack_trace_depth(kMaxStackTraceDepth), + stream_result_to(""), + throw_on_failure(false) {} + + // Factory methods. + + // Creates a Flags struct where the gtest_also_run_disabled_tests flag has + // the given value. + static Flags AlsoRunDisabledTests(bool also_run_disabled_tests) { + Flags flags; + flags.also_run_disabled_tests = also_run_disabled_tests; + return flags; + } + + // Creates a Flags struct where the gtest_break_on_failure flag has + // the given value. + static Flags BreakOnFailure(bool break_on_failure) { + Flags flags; + flags.break_on_failure = break_on_failure; + return flags; + } + + // Creates a Flags struct where the gtest_catch_exceptions flag has + // the given value. + static Flags CatchExceptions(bool catch_exceptions) { + Flags flags; + flags.catch_exceptions = catch_exceptions; + return flags; + } + + // Creates a Flags struct where the gtest_death_test_use_fork flag has + // the given value. + static Flags DeathTestUseFork(bool death_test_use_fork) { + Flags flags; + flags.death_test_use_fork = death_test_use_fork; + return flags; + } + + // Creates a Flags struct where the gtest_filter flag has the given + // value. + static Flags Filter(const char* filter) { + Flags flags; + flags.filter = filter; + return flags; + } + + // Creates a Flags struct where the gtest_list_tests flag has the + // given value. + static Flags ListTests(bool list_tests) { + Flags flags; + flags.list_tests = list_tests; + return flags; + } + + // Creates a Flags struct where the gtest_output flag has the given + // value. + static Flags Output(const char* output) { + Flags flags; + flags.output = output; + return flags; + } + + // Creates a Flags struct where the gtest_print_time flag has the given + // value. + static Flags PrintTime(bool print_time) { + Flags flags; + flags.print_time = print_time; + return flags; + } + + // Creates a Flags struct where the gtest_random_seed flag has + // the given value. + static Flags RandomSeed(Int32 random_seed) { + Flags flags; + flags.random_seed = random_seed; + return flags; + } + + // Creates a Flags struct where the gtest_repeat flag has the given + // value. + static Flags Repeat(Int32 repeat) { + Flags flags; + flags.repeat = repeat; + return flags; + } + + // Creates a Flags struct where the gtest_shuffle flag has + // the given value. + static Flags Shuffle(bool shuffle) { + Flags flags; + flags.shuffle = shuffle; + return flags; + } + + // Creates a Flags struct where the GTEST_FLAG(stack_trace_depth) flag has + // the given value. + static Flags StackTraceDepth(Int32 stack_trace_depth) { + Flags flags; + flags.stack_trace_depth = stack_trace_depth; + return flags; + } + + // Creates a Flags struct where the GTEST_FLAG(stream_result_to) flag has + // the given value. + static Flags StreamResultTo(const char* stream_result_to) { + Flags flags; + flags.stream_result_to = stream_result_to; + return flags; + } + + // Creates a Flags struct where the gtest_throw_on_failure flag has + // the given value. + static Flags ThrowOnFailure(bool throw_on_failure) { + Flags flags; + flags.throw_on_failure = throw_on_failure; + return flags; + } + + // These fields store the flag values. + bool also_run_disabled_tests; + bool break_on_failure; + bool catch_exceptions; + bool death_test_use_fork; + const char* filter; + bool list_tests; + const char* output; + bool print_time; + Int32 random_seed; + Int32 repeat; + bool shuffle; + Int32 stack_trace_depth; + const char* stream_result_to; + bool throw_on_failure; +}; + +// Fixture for testing InitGoogleTest(). +class InitGoogleTestTest : public Test { + protected: + // Clears the flags before each test. + virtual void SetUp() { + GTEST_FLAG(also_run_disabled_tests) = false; + GTEST_FLAG(break_on_failure) = false; + GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(death_test_use_fork) = false; + GTEST_FLAG(filter) = ""; + GTEST_FLAG(list_tests) = false; + GTEST_FLAG(output) = ""; + GTEST_FLAG(print_time) = true; + GTEST_FLAG(random_seed) = 0; + GTEST_FLAG(repeat) = 1; + GTEST_FLAG(shuffle) = false; + GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; + GTEST_FLAG(stream_result_to) = ""; + GTEST_FLAG(throw_on_failure) = false; + } + + // Asserts that two narrow or wide string arrays are equal. + template + static void AssertStringArrayEq(size_t size1, CharType** array1, + size_t size2, CharType** array2) { + ASSERT_EQ(size1, size2) << " Array sizes different."; + + for (size_t i = 0; i != size1; i++) { + ASSERT_STREQ(array1[i], array2[i]) << " where i == " << i; + } + } + + // Verifies that the flag values match the expected values. + static void CheckFlags(const Flags& expected) { + EXPECT_EQ(expected.also_run_disabled_tests, + GTEST_FLAG(also_run_disabled_tests)); + EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure)); + EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions)); + EXPECT_EQ(expected.death_test_use_fork, GTEST_FLAG(death_test_use_fork)); + EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str()); + EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); + EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); + EXPECT_EQ(expected.print_time, GTEST_FLAG(print_time)); + EXPECT_EQ(expected.random_seed, GTEST_FLAG(random_seed)); + EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat)); + EXPECT_EQ(expected.shuffle, GTEST_FLAG(shuffle)); + EXPECT_EQ(expected.stack_trace_depth, GTEST_FLAG(stack_trace_depth)); + EXPECT_STREQ(expected.stream_result_to, + GTEST_FLAG(stream_result_to).c_str()); + EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure)); + } + + // Parses a command line (specified by argc1 and argv1), then + // verifies that the flag values are expected and that the + // recognized flags are removed from the command line. + template + static void TestParsingFlags(int argc1, const CharType** argv1, + int argc2, const CharType** argv2, + const Flags& expected, bool should_print_help) { + const bool saved_help_flag = ::testing::internal::g_help_flag; + ::testing::internal::g_help_flag = false; + +#if GTEST_HAS_STREAM_REDIRECTION + CaptureStdout(); +#endif + + // Parses the command line. + internal::ParseGoogleTestFlagsOnly(&argc1, const_cast(argv1)); + +#if GTEST_HAS_STREAM_REDIRECTION + const std::string captured_stdout = GetCapturedStdout(); +#endif + + // Verifies the flag values. + CheckFlags(expected); + + // Verifies that the recognized flags are removed from the command + // line. + AssertStringArrayEq(argc1 + 1, argv1, argc2 + 1, argv2); + + // ParseGoogleTestFlagsOnly should neither set g_help_flag nor print the + // help message for the flags it recognizes. + EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag); + +#if GTEST_HAS_STREAM_REDIRECTION + const char* const expected_help_fragment = + "This program contains tests written using"; + if (should_print_help) { + EXPECT_PRED_FORMAT2(IsSubstring, expected_help_fragment, captured_stdout); + } else { + EXPECT_PRED_FORMAT2(IsNotSubstring, + expected_help_fragment, captured_stdout); + } +#endif // GTEST_HAS_STREAM_REDIRECTION + + ::testing::internal::g_help_flag = saved_help_flag; + } + + // This macro wraps TestParsingFlags s.t. the user doesn't need + // to specify the array sizes. + +#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \ + TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \ + sizeof(argv2)/sizeof(*argv2) - 1, argv2, \ + expected, should_print_help) +}; + +// Tests parsing an empty command line. +TEST_F(InitGoogleTestTest, Empty) { + const char* argv[] = { + NULL + }; + + const char* argv2[] = { + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); +} + +// Tests parsing a command line that has no flag. +TEST_F(InitGoogleTestTest, NoFlag) { + const char* argv[] = { + "foo.exe", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); +} + +// Tests parsing a bad --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterBad) { + const char* argv[] = { + "foo.exe", + "--gtest_filter", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "--gtest_filter", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), true); +} + +// Tests parsing an empty --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), false); +} + +// Tests parsing a non-empty --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterNonEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=abc", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"), false); +} + +// Tests parsing --gtest_break_on_failure. +TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); +} + +// Tests parsing --gtest_break_on_failure=0. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing --gtest_break_on_failure=f. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing --gtest_break_on_failure=F. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing a --gtest_break_on_failure flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, BreakOnFailureTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); +} + +// Tests parsing --gtest_catch_exceptions. +TEST_F(InitGoogleTestTest, CatchExceptions) { + const char* argv[] = { + "foo.exe", + "--gtest_catch_exceptions", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::CatchExceptions(true), false); +} + +// Tests parsing --gtest_death_test_use_fork. +TEST_F(InitGoogleTestTest, DeathTestUseFork) { + const char* argv[] = { + "foo.exe", + "--gtest_death_test_use_fork", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::DeathTestUseFork(true), false); +} + +// Tests having the same flag twice with different values. The +// expected behavior is that the one coming last takes precedence. +TEST_F(InitGoogleTestTest, DuplicatedFlags) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=a", + "--gtest_filter=b", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("b"), false); +} + +// Tests having an unrecognized flag on the command line. +TEST_F(InitGoogleTestTest, UnrecognizedFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure", + "bar", // Unrecognized by Google Test. + "--gtest_filter=b", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "bar", + NULL + }; + + Flags flags; + flags.break_on_failure = true; + flags.filter = "b"; + GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags, false); +} + +// Tests having a --gtest_list_tests flag +TEST_F(InitGoogleTestTest, ListTestsFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); +} + +// Tests having a --gtest_list_tests flag with a "true" value +TEST_F(InitGoogleTestTest, ListTestsTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); +} + +// Tests having a --gtest_list_tests flag with a "false" value +TEST_F(InitGoogleTestTest, ListTestsFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_list_tests=f. +TEST_F(InitGoogleTestTest, ListTestsFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_list_tests=F. +TEST_F(InitGoogleTestTest, ListTestsFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_output (invalid). +TEST_F(InitGoogleTestTest, OutputEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_output", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "--gtest_output", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), true); +} + +// Tests parsing --gtest_output=xml +TEST_F(InitGoogleTestTest, OutputXml) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml"), false); +} + +// Tests parsing --gtest_output=xml:file +TEST_F(InitGoogleTestTest, OutputXmlFile) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml:file", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:file"), false); +} + +// Tests parsing --gtest_output=xml:directory/path/ +TEST_F(InitGoogleTestTest, OutputXmlDirectory) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml:directory/path/", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::Output("xml:directory/path/"), false); +} + +// Tests having a --gtest_print_time flag +TEST_F(InitGoogleTestTest, PrintTimeFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); +} + +// Tests having a --gtest_print_time flag with a "true" value +TEST_F(InitGoogleTestTest, PrintTimeTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); +} + +// Tests having a --gtest_print_time flag with a "false" value +TEST_F(InitGoogleTestTest, PrintTimeFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_print_time=f. +TEST_F(InitGoogleTestTest, PrintTimeFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_print_time=F. +TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_random_seed=number +TEST_F(InitGoogleTestTest, RandomSeed) { + const char* argv[] = { + "foo.exe", + "--gtest_random_seed=1000", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::RandomSeed(1000), false); +} + +// Tests parsing --gtest_repeat=number +TEST_F(InitGoogleTestTest, Repeat) { + const char* argv[] = { + "foo.exe", + "--gtest_repeat=1000", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Repeat(1000), false); +} + +// Tests having a --gtest_also_run_disabled_tests flag +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(true), false); +} + +// Tests having a --gtest_also_run_disabled_tests flag with a "true" value +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(true), false); +} + +// Tests having a --gtest_also_run_disabled_tests flag with a "false" value +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(false), false); +} + +// Tests parsing --gtest_shuffle. +TEST_F(InitGoogleTestTest, ShuffleWithoutValue) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); +} + +// Tests parsing --gtest_shuffle=0. +TEST_F(InitGoogleTestTest, ShuffleFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false); +} + +// Tests parsing a --gtest_shuffle flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, ShuffleTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); +} + +// Tests parsing --gtest_stack_trace_depth=number. +TEST_F(InitGoogleTestTest, StackTraceDepth) { + const char* argv[] = { + "foo.exe", + "--gtest_stack_trace_depth=5", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false); +} + +TEST_F(InitGoogleTestTest, StreamResultTo) { + const char* argv[] = { + "foo.exe", + "--gtest_stream_result_to=localhost:1234", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_( + argv, argv2, Flags::StreamResultTo("localhost:1234"), false); +} + +// Tests parsing --gtest_throw_on_failure. +TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); +} + +// Tests parsing --gtest_throw_on_failure=0. +TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false), false); +} + +// Tests parsing a --gtest_throw_on_failure flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); +} + +#if GTEST_OS_WINDOWS +// Tests parsing wide strings. +TEST_F(InitGoogleTestTest, WideStrings) { + const wchar_t* argv[] = { + L"foo.exe", + L"--gtest_filter=Foo*", + L"--gtest_list_tests=1", + L"--gtest_break_on_failure", + L"--non_gtest_flag", + NULL + }; + + const wchar_t* argv2[] = { + L"foo.exe", + L"--non_gtest_flag", + NULL + }; + + Flags expected_flags; + expected_flags.break_on_failure = true; + expected_flags.filter = "Foo*"; + expected_flags.list_tests = true; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false); +} +#endif // GTEST_OS_WINDOWS + +// Tests current_test_info() in UnitTest. +class CurrentTestInfoTest : public Test { + protected: + // Tests that current_test_info() returns NULL before the first test in + // the test case is run. + static void SetUpTestCase() { + // There should be no tests running at this point. + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + EXPECT_TRUE(test_info == NULL) + << "There should be no tests running at this point."; + } + + // Tests that current_test_info() returns NULL after the last test in + // the test case has run. + static void TearDownTestCase() { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + EXPECT_TRUE(test_info == NULL) + << "There should be no tests running at this point."; + } +}; + +// Tests that current_test_info() returns TestInfo for currently running +// test by checking the expected test name against the actual one. +TEST_F(CurrentTestInfoTest, WorksForFirstTestInATestCase) { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(NULL != test_info) + << "There is a test running so we should have a valid TestInfo."; + EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) + << "Expected the name of the currently running test case."; + EXPECT_STREQ("WorksForFirstTestInATestCase", test_info->name()) + << "Expected the name of the currently running test."; +} + +// Tests that current_test_info() returns TestInfo for currently running +// test by checking the expected test name against the actual one. We +// use this test to see that the TestInfo object actually changed from +// the previous invocation. +TEST_F(CurrentTestInfoTest, WorksForSecondTestInATestCase) { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(NULL != test_info) + << "There is a test running so we should have a valid TestInfo."; + EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) + << "Expected the name of the currently running test case."; + EXPECT_STREQ("WorksForSecondTestInATestCase", test_info->name()) + << "Expected the name of the currently running test."; +} + +} // namespace testing + +// These two lines test that we can define tests in a namespace that +// has the name "testing" and is nested in another namespace. +namespace my_namespace { +namespace testing { + +// Makes sure that TEST knows to use ::testing::Test instead of +// ::my_namespace::testing::Test. +class Test {}; + +// Makes sure that an assertion knows to use ::testing::Message instead of +// ::my_namespace::testing::Message. +class Message {}; + +// Makes sure that an assertion knows to use +// ::testing::AssertionResult instead of +// ::my_namespace::testing::AssertionResult. +class AssertionResult {}; + +// Tests that an assertion that should succeed works as expected. +TEST(NestedTestingNamespaceTest, Success) { + EXPECT_EQ(1, 1) << "This shouldn't fail."; +} + +// Tests that an assertion that should fail works as expected. +TEST(NestedTestingNamespaceTest, Failure) { + EXPECT_FATAL_FAILURE(FAIL() << "This failure is expected.", + "This failure is expected."); +} + +} // namespace testing +} // namespace my_namespace + +// Tests that one can call superclass SetUp and TearDown methods-- +// that is, that they are not private. +// No tests are based on this fixture; the test "passes" if it compiles +// successfully. +class ProtectedFixtureMethodsTest : public Test { + protected: + virtual void SetUp() { + Test::SetUp(); + } + virtual void TearDown() { + Test::TearDown(); + } +}; + +// StreamingAssertionsTest tests the streaming versions of a representative +// sample of assertions. +TEST(StreamingAssertionsTest, Unconditional) { + SUCCEED() << "expected success"; + EXPECT_NONFATAL_FAILURE(ADD_FAILURE() << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(FAIL() << "expected failure", + "expected failure"); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +TEST(StreamingAssertionsTest, Truth) { + EXPECT_TRUE(true) << "unexpected failure"; + ASSERT_TRUE(true) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, Truth2) { + EXPECT_FALSE(false) << "unexpected failure"; + ASSERT_FALSE(false) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_FALSE(true) << "expected failure", + "expected failure"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +# pragma option pop +#endif + +TEST(StreamingAssertionsTest, IntegerEquals) { + EXPECT_EQ(1, 1) << "unexpected failure"; + ASSERT_EQ(1, 1) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(1, 2) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(1, 2) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, IntegerLessThan) { + EXPECT_LT(1, 2) << "unexpected failure"; + ASSERT_LT(1, 2) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_LT(2, 1) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsEqual) { + EXPECT_STREQ("foo", "foo") << "unexpected failure"; + ASSERT_STREQ("foo", "foo") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ("foo", "bar") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STREQ("foo", "bar") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsNotEqual) { + EXPECT_STRNE("foo", "bar") << "unexpected failure"; + ASSERT_STRNE("foo", "bar") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("foo", "foo") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRNE("foo", "foo") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsEqualIgnoringCase) { + EXPECT_STRCASEEQ("foo", "FOO") << "unexpected failure"; + ASSERT_STRCASEEQ("foo", "FOO") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ("foo", "bar") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("foo", "bar") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringNotEqualIgnoringCase) { + EXPECT_STRCASENE("foo", "bar") << "unexpected failure"; + ASSERT_STRCASENE("foo", "bar") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("foo", "FOO") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("bar", "BAR") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, FloatingPointEquals) { + EXPECT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; + ASSERT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(0.0, 1.0) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.0) << "expected failure", + "expected failure"); +} + +#if GTEST_HAS_EXCEPTIONS + +TEST(StreamingAssertionsTest, Throw) { + EXPECT_THROW(ThrowAnInteger(), int) << "unexpected failure"; + ASSERT_THROW(ThrowAnInteger(), int) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_THROW(ThrowAnInteger(), bool) << + "expected failure", "expected failure"); +} + +TEST(StreamingAssertionsTest, NoThrow) { + EXPECT_NO_THROW(ThrowNothing()) << "unexpected failure"; + ASSERT_NO_THROW(ThrowNothing()) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()) << + "expected failure", "expected failure"); +} + +TEST(StreamingAssertionsTest, AnyThrow) { + EXPECT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; + ASSERT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(ThrowNothing()) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(ThrowNothing()) << + "expected failure", "expected failure"); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests that Google Test correctly decides whether to use colors in the output. + +TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsYes) { + GTEST_FLAG(color) = "yes"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsAliasOfYes) { + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + + GTEST_FLAG(color) = "True"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + GTEST_FLAG(color) = "t"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + GTEST_FLAG(color) = "1"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsNo) { + GTEST_FLAG(color) = "no"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsInvalid) { + SetEnv("TERM", "xterm"); // TERM supports colors. + + GTEST_FLAG(color) = "F"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + GTEST_FLAG(color) = "0"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + GTEST_FLAG(color) = "unknown"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenStdoutIsTty) { + GTEST_FLAG(color) = "auto"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { + GTEST_FLAG(color) = "auto"; + +#if GTEST_OS_WINDOWS + // On Windows, we ignore the TERM variable as it's usually not set. + + SetEnv("TERM", "dumb"); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", ""); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm"); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +#else + // On non-Windows platforms, we rely on TERM to determine if the + // terminal supports colors. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "emacs"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "vt100"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-mono"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "screen"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "linux"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "cygwin"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +#endif // GTEST_OS_WINDOWS +} + +// Verifies that StaticAssertTypeEq works in a namespace scope. + +static bool dummy1 GTEST_ATTRIBUTE_UNUSED_ = StaticAssertTypeEq(); +static bool dummy2 GTEST_ATTRIBUTE_UNUSED_ = + StaticAssertTypeEq(); + +// Verifies that StaticAssertTypeEq works in a class. + +template +class StaticAssertTypeEqTestHelper { + public: + StaticAssertTypeEqTestHelper() { StaticAssertTypeEq(); } +}; + +TEST(StaticAssertTypeEqTest, WorksInClass) { + StaticAssertTypeEqTestHelper(); +} + +// Verifies that StaticAssertTypeEq works inside a function. + +typedef int IntAlias; + +TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) { + StaticAssertTypeEq(); + StaticAssertTypeEq(); +} + +TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) { + testing::UnitTest* const unit_test = testing::UnitTest::GetInstance(); + + // We don't have a stack walker in Google Test yet. + EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str()); + EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str()); +} + +TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) { + EXPECT_FALSE(HasNonfatalFailure()); +} + +static void FailFatally() { FAIL(); } + +TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsOnlyFatalFailure) { + FailFatally(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_FALSE(has_nonfatal_failure); +} + +TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { + FailFatally(); + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +// A wrapper for calling HasNonfatalFailure outside of a test body. +static bool HasNonfatalFailureHelper() { + return testing::Test::HasNonfatalFailure(); +} + +TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody) { + EXPECT_FALSE(HasNonfatalFailureHelper()); +} + +TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody2) { + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailureHelper(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +TEST(HasFailureTest, ReturnsFalseWhenThereIsNoFailure) { + EXPECT_FALSE(HasFailure()); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereIsFatalFailure) { + FailFatally(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { + ADD_FAILURE(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { + FailFatally(); + ADD_FAILURE(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +// A wrapper for calling HasFailure outside of a test body. +static bool HasFailureHelper() { return testing::Test::HasFailure(); } + +TEST(HasFailureTest, WorksOutsideOfTestBody) { + EXPECT_FALSE(HasFailureHelper()); +} + +TEST(HasFailureTest, WorksOutsideOfTestBody2) { + ADD_FAILURE(); + const bool has_failure = HasFailureHelper(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +class TestListener : public EmptyTestEventListener { + public: + TestListener() : on_start_counter_(NULL), is_destroyed_(NULL) {} + TestListener(int* on_start_counter, bool* is_destroyed) + : on_start_counter_(on_start_counter), + is_destroyed_(is_destroyed) {} + + virtual ~TestListener() { + if (is_destroyed_) + *is_destroyed_ = true; + } + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + if (on_start_counter_ != NULL) + (*on_start_counter_)++; + } + + private: + int* on_start_counter_; + bool* is_destroyed_; +}; + +// Tests the constructor. +TEST(TestEventListenersTest, ConstructionWorks) { + TestEventListeners listeners; + + EXPECT_TRUE(TestEventListenersAccessor::GetRepeater(&listeners) != NULL); + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_TRUE(listeners.default_xml_generator() == NULL); +} + +// Tests that the TestEventListeners destructor deletes all the listeners it +// owns. +TEST(TestEventListenersTest, DestructionWorks) { + bool default_result_printer_is_destroyed = false; + bool default_xml_printer_is_destroyed = false; + bool extra_listener_is_destroyed = false; + TestListener* default_result_printer = new TestListener( + NULL, &default_result_printer_is_destroyed); + TestListener* default_xml_printer = new TestListener( + NULL, &default_xml_printer_is_destroyed); + TestListener* extra_listener = new TestListener( + NULL, &extra_listener_is_destroyed); + + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, + default_result_printer); + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, + default_xml_printer); + listeners.Append(extra_listener); + } + EXPECT_TRUE(default_result_printer_is_destroyed); + EXPECT_TRUE(default_xml_printer_is_destroyed); + EXPECT_TRUE(extra_listener_is_destroyed); +} + +// Tests that a listener Append'ed to a TestEventListeners list starts +// receiving events. +TEST(TestEventListenersTest, Append) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + listeners.Append(listener); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); + } + EXPECT_TRUE(is_destroyed); +} + +// Tests that listeners receive events in the order they were appended to +// the list, except for *End requests, which must be received in the reverse +// order. +class SequenceTestingListener : public EmptyTestEventListener { + public: + SequenceTestingListener(std::vector* vector, const char* id) + : vector_(vector), id_(id) {} + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + vector_->push_back(GetEventDescription("OnTestProgramStart")); + } + + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { + vector_->push_back(GetEventDescription("OnTestProgramEnd")); + } + + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) { + vector_->push_back(GetEventDescription("OnTestIterationStart")); + } + + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) { + vector_->push_back(GetEventDescription("OnTestIterationEnd")); + } + + private: + std::string GetEventDescription(const char* method) { + Message message; + message << id_ << "." << method; + return message.GetString(); + } + + std::vector* vector_; + const char* const id_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener); +}; + +TEST(EventListenerTest, AppendKeepsOrder) { + std::vector vec; + TestEventListeners listeners; + listeners.Append(new SequenceTestingListener(&vec, "1st")); + listeners.Append(new SequenceTestingListener(&vec, "2nd")); + listeners.Append(new SequenceTestingListener(&vec, "3rd")); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("1st.OnTestProgramStart", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestProgramStart", vec[1].c_str()); + EXPECT_STREQ("3rd.OnTestProgramStart", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd( + *UnitTest::GetInstance()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("3rd.OnTestProgramEnd", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestProgramEnd", vec[1].c_str()); + EXPECT_STREQ("1st.OnTestProgramEnd", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("1st.OnTestIterationStart", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestIterationStart", vec[1].c_str()); + EXPECT_STREQ("3rd.OnTestIterationStart", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("3rd.OnTestIterationEnd", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestIterationEnd", vec[1].c_str()); + EXPECT_STREQ("1st.OnTestIterationEnd", vec[2].c_str()); +} + +// Tests that a listener removed from a TestEventListeners list stops receiving +// events and is not deleted when the list is destroyed. +TEST(TestEventListenersTest, Release) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + listeners.Append(listener); + EXPECT_EQ(listener, listeners.Release(listener)); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_TRUE(listeners.Release(listener) == NULL); + } + EXPECT_EQ(0, on_start_counter); + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that no events are forwarded when event forwarding is disabled. +TEST(EventListenerTest, SuppressEventForwarding) { + int on_start_counter = 0; + TestListener* listener = new TestListener(&on_start_counter, NULL); + + TestEventListeners listeners; + listeners.Append(listener); + ASSERT_TRUE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::SuppressEventForwarding(&listeners); + ASSERT_FALSE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); +} + +// Tests that events generated by Google Test are not forwarded in +// death test subprocesses. +TEST(EventListenerDeathTest, EventsNotForwardedInDeathTestSubprecesses) { + EXPECT_DEATH_IF_SUPPORTED({ + GTEST_CHECK_(TestEventListenersAccessor::EventForwardingEnabled( + *GetUnitTestImpl()->listeners())) << "expected failure";}, + "expected failure"); +} + +// Tests that a listener installed via SetDefaultResultPrinter() starts +// receiving events and is returned via default_result_printer() and that +// the previous default_result_printer is removed from the list and deleted. +TEST(EventListenerTest, default_result_printer) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_result_printer()); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_result_printer with something else should remove it + // from the list and destroy it. + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, NULL); + + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_result_printer listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultResultPrinterWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_result_printer. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that a listener installed via SetDefaultXmlGenerator() starts +// receiving events and is returned via default_xml_generator() and that +// the previous default_xml_generator is removed from the list and deleted. +TEST(EventListenerTest, default_xml_generator) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_xml_generator()); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_xml_generator with something else should remove it + // from the list and destroy it. + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, NULL); + + EXPECT_TRUE(listeners.default_xml_generator() == NULL); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_xml_generator listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_xml_generator() == NULL); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_xml_generator. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Sanity tests to ensure that the alternative, verbose spellings of +// some of the macros work. We don't test them thoroughly as that +// would be quite involved. Since their implementations are +// straightforward, and they are rarely used, we'll just rely on the +// users to tell us when they are broken. +GTEST_TEST(AlternativeNameTest, Works) { // GTEST_TEST is the same as TEST. + GTEST_SUCCEED() << "OK"; // GTEST_SUCCEED is the same as SUCCEED. + + // GTEST_FAIL is the same as FAIL. + EXPECT_FATAL_FAILURE(GTEST_FAIL() << "An expected failure", + "An expected failure"); + + // GTEST_ASSERT_XY is the same as ASSERT_XY. + + GTEST_ASSERT_EQ(0, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(0, 1) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_NE(0, 1); + GTEST_ASSERT_NE(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_NE(0, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_LE(0, 0); + GTEST_ASSERT_LE(0, 1); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LE(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_LT(0, 1); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(0, 0) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_GE(0, 0); + GTEST_ASSERT_GE(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GE(0, 1) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_GT(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(0, 1) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(1, 1) << "An expected failure", + "An expected failure"); +} + +// Tests for internal utilities necessary for implementation of the universal +// printing. +// TODO(vladl@google.com): Find a better home for them. + +class ConversionHelperBase {}; +class ConversionHelperDerived : public ConversionHelperBase {}; + +// Tests that IsAProtocolMessage::value is a compile-time constant. +TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { + GTEST_COMPILE_ASSERT_(IsAProtocolMessage::value, + const_true); + GTEST_COMPILE_ASSERT_(!IsAProtocolMessage::value, const_false); +} + +// Tests that IsAProtocolMessage::value is true when T is +// proto2::Message or a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) { + EXPECT_TRUE(IsAProtocolMessage< ::proto2::Message>::value); + EXPECT_TRUE(IsAProtocolMessage::value); +} + +// Tests that IsAProtocolMessage::value is false when T is neither +// ProtocolMessage nor a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) { + EXPECT_FALSE(IsAProtocolMessage::value); + EXPECT_FALSE(IsAProtocolMessage::value); +} + +// Tests that CompileAssertTypesEqual compiles when the type arguments are +// equal. +TEST(CompileAssertTypesEqual, CompilesWhenTypesAreEqual) { + CompileAssertTypesEqual(); + CompileAssertTypesEqual(); +} + +// Tests that RemoveReference does not affect non-reference types. +TEST(RemoveReferenceTest, DoesNotAffectNonReferenceType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that RemoveReference removes reference from reference types. +TEST(RemoveReferenceTest, RemovesReference) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_REMOVE_REFERENCE_. + +template +void TestGTestRemoveReference() { + CompileAssertTypesEqual(); +} + +TEST(RemoveReferenceTest, MacroVersion) { + TestGTestRemoveReference(); + TestGTestRemoveReference(); +} + + +// Tests that RemoveConst does not affect non-const types. +TEST(RemoveConstTest, DoesNotAffectNonConstType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that RemoveConst removes const from const types. +TEST(RemoveConstTest, RemovesConst) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_REMOVE_CONST_. + +template +void TestGTestRemoveConst() { + CompileAssertTypesEqual(); +} + +TEST(RemoveConstTest, MacroVersion) { + TestGTestRemoveConst(); + TestGTestRemoveConst(); + TestGTestRemoveConst(); +} + +// Tests GTEST_REMOVE_REFERENCE_AND_CONST_. + +template +void TestGTestRemoveReferenceAndConst() { + CompileAssertTypesEqual(); +} + +TEST(RemoveReferenceToConstTest, Works) { + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); +} + +// Tests that AddReference does not affect reference types. +TEST(AddReferenceTest, DoesNotAffectReferenceType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that AddReference adds reference to non-reference types. +TEST(AddReferenceTest, AddsReference) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_ADD_REFERENCE_. + +template +void TestGTestAddReference() { + CompileAssertTypesEqual(); +} + +TEST(AddReferenceTest, MacroVersion) { + TestGTestAddReference(); + TestGTestAddReference(); +} + +// Tests GTEST_REFERENCE_TO_CONST_. + +template +void TestGTestReferenceToConst() { + CompileAssertTypesEqual(); +} + +TEST(GTestReferenceToConstTest, Works) { + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); +} + +// Tests that ImplicitlyConvertible::value is a compile-time constant. +TEST(ImplicitlyConvertibleTest, ValueIsCompileTimeConstant) { + GTEST_COMPILE_ASSERT_((ImplicitlyConvertible::value), const_true); + GTEST_COMPILE_ASSERT_((!ImplicitlyConvertible::value), + const_false); +} + +// Tests that ImplicitlyConvertible::value is true when T1 can +// be implicitly converted to T2. +TEST(ImplicitlyConvertibleTest, ValueIsTrueWhenConvertible) { + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); +} + +// Tests that ImplicitlyConvertible::value is false when T1 +// cannot be implicitly converted to T2. +TEST(ImplicitlyConvertibleTest, ValueIsFalseWhenNotConvertible) { + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); +} + +// Tests IsContainerTest. + +class NonContainer {}; + +TEST(IsContainerTestTest, WorksForNonContainer) { + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); +} + +TEST(IsContainerTestTest, WorksForContainer) { + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest >(0))); + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest >(0))); +} + +// Tests ArrayEq(). + +TEST(ArrayEqTest, WorksForDegeneratedArrays) { + EXPECT_TRUE(ArrayEq(5, 5L)); + EXPECT_FALSE(ArrayEq('a', 0)); +} + +TEST(ArrayEqTest, WorksForOneDimensionalArrays) { + // Note that a and b are distinct but compatible types. + const int a[] = { 0, 1 }; + long b[] = { 0, 1 }; + EXPECT_TRUE(ArrayEq(a, b)); + EXPECT_TRUE(ArrayEq(a, 2, b)); + + b[0] = 2; + EXPECT_FALSE(ArrayEq(a, b)); + EXPECT_FALSE(ArrayEq(a, 1, b)); +} + +TEST(ArrayEqTest, WorksForTwoDimensionalArrays) { + const char a[][3] = { "hi", "lo" }; + const char b[][3] = { "hi", "lo" }; + const char c[][3] = { "hi", "li" }; + + EXPECT_TRUE(ArrayEq(a, b)); + EXPECT_TRUE(ArrayEq(a, 2, b)); + + EXPECT_FALSE(ArrayEq(a, c)); + EXPECT_FALSE(ArrayEq(a, 2, c)); +} + +// Tests ArrayAwareFind(). + +TEST(ArrayAwareFindTest, WorksForOneDimensionalArray) { + const char a[] = "hello"; + EXPECT_EQ(a + 4, ArrayAwareFind(a, a + 5, 'o')); + EXPECT_EQ(a + 5, ArrayAwareFind(a, a + 5, 'x')); +} + +TEST(ArrayAwareFindTest, WorksForTwoDimensionalArray) { + int a[][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } }; + const int b[2] = { 2, 3 }; + EXPECT_EQ(a + 1, ArrayAwareFind(a, a + 3, b)); + + const int c[2] = { 6, 7 }; + EXPECT_EQ(a + 3, ArrayAwareFind(a, a + 3, c)); +} + +// Tests CopyArray(). + +TEST(CopyArrayTest, WorksForDegeneratedArrays) { + int n = 0; + CopyArray('a', &n); + EXPECT_EQ('a', n); +} + +TEST(CopyArrayTest, WorksForOneDimensionalArrays) { + const char a[3] = "hi"; + int b[3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. + CopyArray(a, &b); + EXPECT_TRUE(ArrayEq(a, b)); +#endif + + int c[3]; + CopyArray(a, 3, c); + EXPECT_TRUE(ArrayEq(a, c)); +} + +TEST(CopyArrayTest, WorksForTwoDimensionalArrays) { + const int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; + int b[2][3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. + CopyArray(a, &b); + EXPECT_TRUE(ArrayEq(a, b)); +#endif + + int c[2][3]; + CopyArray(a, 2, c); + EXPECT_TRUE(ArrayEq(a, c)); +} + +// Tests NativeArray. + +TEST(NativeArrayTest, ConstructorFromArrayWorks) { + const int a[3] = { 0, 1, 2 }; + NativeArray na(a, 3, kReference); + EXPECT_EQ(3U, na.size()); + EXPECT_EQ(a, na.begin()); +} + +TEST(NativeArrayTest, CreatesAndDeletesCopyOfArrayWhenAskedTo) { + typedef int Array[2]; + Array* a = new Array[1]; + (*a)[0] = 0; + (*a)[1] = 1; + NativeArray na(*a, 2, kCopy); + EXPECT_NE(*a, na.begin()); + delete[] a; + EXPECT_EQ(0, na.begin()[0]); + EXPECT_EQ(1, na.begin()[1]); + + // We rely on the heap checker to verify that na deletes the copy of + // array. +} + +TEST(NativeArrayTest, TypeMembersAreCorrect) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); + + StaticAssertTypeEq::const_iterator>(); + StaticAssertTypeEq::const_iterator>(); +} + +TEST(NativeArrayTest, MethodsWork) { + const int a[3] = { 0, 1, 2 }; + NativeArray na(a, 3, kCopy); + ASSERT_EQ(3U, na.size()); + EXPECT_EQ(3, na.end() - na.begin()); + + NativeArray::const_iterator it = na.begin(); + EXPECT_EQ(0, *it); + ++it; + EXPECT_EQ(1, *it); + it++; + EXPECT_EQ(2, *it); + ++it; + EXPECT_EQ(na.end(), it); + + EXPECT_TRUE(na == na); + + NativeArray na2(a, 3, kReference); + EXPECT_TRUE(na == na2); + + const int b1[3] = { 0, 1, 1 }; + const int b2[4] = { 0, 1, 2, 3 }; + EXPECT_FALSE(na == NativeArray(b1, 3, kReference)); + EXPECT_FALSE(na == NativeArray(b2, 4, kCopy)); +} + +TEST(NativeArrayTest, WorksForTwoDimensionalArray) { + const char a[2][3] = { "hi", "lo" }; + NativeArray na(a, 2, kReference); + ASSERT_EQ(2U, na.size()); + EXPECT_EQ(a, na.begin()); +} + +// Tests SkipPrefix(). + +TEST(SkipPrefixTest, SkipsWhenPrefixMatches) { + const char* const str = "hello"; + + const char* p = str; + EXPECT_TRUE(SkipPrefix("", &p)); + EXPECT_EQ(str, p); + + p = str; + EXPECT_TRUE(SkipPrefix("hell", &p)); + EXPECT_EQ(str + 4, p); +} + +TEST(SkipPrefixTest, DoesNotSkipWhenPrefixDoesNotMatch) { + const char* const str = "world"; + + const char* p = str; + EXPECT_FALSE(SkipPrefix("W", &p)); + EXPECT_EQ(str, p); + + p = str; + EXPECT_FALSE(SkipPrefix("world!", &p)); + EXPECT_EQ(str, p); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfile1_test_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfile1_test_.cc new file mode 100644 index 0000000..531ced4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfile1_test_.cc @@ -0,0 +1,49 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// gtest_xml_outfile1_test_ writes some xml via TestProperty used by +// gtest_xml_outfiles_test.py + +#include "gtest/gtest.h" + +class PropertyOne : public testing::Test { + protected: + virtual void SetUp() { + RecordProperty("SetUpProp", 1); + } + virtual void TearDown() { + RecordProperty("TearDownProp", 1); + } +}; + +TEST_F(PropertyOne, TestSomeProperties) { + RecordProperty("TestSomeProperty", 1); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfile2_test_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfile2_test_.cc new file mode 100644 index 0000000..7b400b2 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfile2_test_.cc @@ -0,0 +1,49 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// gtest_xml_outfile2_test_ writes some xml via TestProperty used by +// gtest_xml_outfiles_test.py + +#include "gtest/gtest.h" + +class PropertyTwo : public testing::Test { + protected: + virtual void SetUp() { + RecordProperty("SetUpProp", 2); + } + virtual void TearDown() { + RecordProperty("TearDownProp", 2); + } +}; + +TEST_F(PropertyTwo, TestSomeProperties) { + RecordProperty("TestSomeProperty", 2); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfiles_test.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfiles_test.py new file mode 100755 index 0000000..524e437 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_outfiles_test.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test for the gtest_xml_output module.""" + +__author__ = "keith.ray@gmail.com (Keith Ray)" + +import os +from xml.dom import minidom, Node + +import gtest_test_utils +import gtest_xml_test_utils + + +GTEST_OUTPUT_SUBDIR = "xml_outfiles" +GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_" +GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" + +EXPECTED_XML_1 = """ + + + + + +""" + +EXPECTED_XML_2 = """ + + + + + +""" + + +class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): + """Unit test for Google Test's XML output functionality.""" + + def setUp(self): + # We want the trailing '/' that the last "" provides in os.path.join, for + # telling Google Test to create an output directory instead of a single file + # for xml output. + self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_OUTPUT_SUBDIR, "") + self.DeleteFilesAndDir() + + def tearDown(self): + self.DeleteFilesAndDir() + + def DeleteFilesAndDir(self): + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + ".xml")) + except os.error: + pass + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + ".xml")) + except os.error: + pass + try: + os.rmdir(self.output_dir_) + except os.error: + pass + + def testOutfile1(self): + self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_XML_1) + + def testOutfile2(self): + self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_XML_2) + + def _TestOutFile(self, test_name, expected_xml): + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name) + command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_] + p = gtest_test_utils.Subprocess(command, + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + + # TODO(wan@google.com): libtool causes the built test binary to be + # named lt-gtest_xml_outfiles_test_ instead of + # gtest_xml_outfiles_test_. To account for this possibillity, we + # allow both names in the following code. We should remove this + # hack when Chandler Carruth's libtool replacement tool is ready. + output_file_name1 = test_name + ".xml" + output_file1 = os.path.join(self.output_dir_, output_file_name1) + output_file_name2 = 'lt-' + output_file_name1 + output_file2 = os.path.join(self.output_dir_, output_file_name2) + self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2), + output_file1) + + expected = minidom.parseString(expected_xml) + if os.path.isfile(output_file1): + actual = minidom.parse(output_file1) + else: + actual = minidom.parse(output_file2) + self.NormalizeXml(actual.documentElement) + self.AssertEquivalentNodes(expected.documentElement, + actual.documentElement) + expected.unlink() + actual.unlink() + + +if __name__ == "__main__": + os.environ["GTEST_STACK_TRACE_DEPTH"] = "0" + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_output_unittest.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_output_unittest.py new file mode 100755 index 0000000..1bcd418 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_output_unittest.py @@ -0,0 +1,284 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test for the gtest_xml_output module""" + +__author__ = 'eefacm@gmail.com (Sean Mcafee)' + +import datetime +import errno +import os +import re +import sys +from xml.dom import minidom, Node + +import gtest_test_utils +import gtest_xml_test_utils + + +GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' +GTEST_OUTPUT_FLAG = "--gtest_output" +GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" +GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_" + +SUPPORTS_STACK_TRACES = False + +if SUPPORTS_STACK_TRACES: + STACK_TRACE_TEMPLATE = '\nStack trace:\n*' +else: + STACK_TRACE_TEMPLATE = '' + +EXPECTED_NON_EMPTY_XML = """ + + + + + + + + + + + + + + + + + + + + ]]>%(stack)s]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" % {'stack': STACK_TRACE_TEMPLATE} + + +EXPECTED_EMPTY_XML = """ + +""" + +GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) + +SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess( + [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output + + +class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): + """ + Unit test for Google Test's XML output functionality. + """ + + # This test currently breaks on platforms that do not support typed and + # type-parameterized tests, so we don't run it under them. + if SUPPORTS_TYPED_TESTS: + def testNonEmptyXmlOutput(self): + """ + Runs a test program that generates a non-empty XML output, and + tests that the XML output is expected. + """ + self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) + + def testEmptyXmlOutput(self): + """Verifies XML output for a Google Test binary without actual tests. + + Runs a test program that generates an empty XML output, and + tests that the XML output is expected. + """ + + self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0) + + def testTimestampValue(self): + """Checks whether the timestamp attribute in the XML output is valid. + + Runs a test program that generates an empty XML output, and checks if + the timestamp attribute in the testsuites tag is valid. + """ + actual = self._GetXmlOutput('gtest_no_test_unittest', 0) + date_time_str = actual.documentElement.getAttributeNode('timestamp').value + # datetime.strptime() is only available in Python 2.5+ so we have to + # parse the expected datetime manually. + match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str) + self.assertTrue( + re.match, + 'XML datettime string %s has incorrect format' % date_time_str) + date_time_from_xml = datetime.datetime( + year=int(match.group(1)), month=int(match.group(2)), + day=int(match.group(3)), hour=int(match.group(4)), + minute=int(match.group(5)), second=int(match.group(6))) + + time_delta = abs(datetime.datetime.now() - date_time_from_xml) + # timestamp value should be near the current local time + self.assertTrue(time_delta < datetime.timedelta(seconds=600), + 'time_delta is %s' % time_delta) + actual.unlink() + + def testDefaultOutputFile(self): + """ + Confirms that Google Test produces an XML output file with the expected + default name if no name is explicitly specified. + """ + output_file = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_DEFAULT_OUTPUT_FILE) + gtest_prog_path = gtest_test_utils.GetTestExecutablePath( + 'gtest_no_test_unittest') + try: + os.remove(output_file) + except OSError, e: + if e.errno != errno.ENOENT: + raise + + p = gtest_test_utils.Subprocess( + [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG], + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + self.assert_(os.path.isfile(output_file)) + + def testSuppressedXmlOutput(self): + """ + Tests that no XML file is generated if the default XML listener is + shut down before RUN_ALL_TESTS is invoked. + """ + + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_PROGRAM_NAME + 'out.xml') + if os.path.isfile(xml_path): + os.remove(xml_path) + + command = [GTEST_PROGRAM_PATH, + '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path), + '--shut_down_xml'] + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + # p.signal is avalable only if p.terminated_by_signal is True. + self.assertFalse( + p.terminated_by_signal, + '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(1, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, 1)) + + self.assert_(not os.path.isfile(xml_path)) + + def _GetXmlOutput(self, gtest_prog_name, expected_exit_code): + """ + Returns the xml output generated by running the program gtest_prog_name. + Furthermore, the program's exit code must be expected_exit_code. + """ + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + gtest_prog_name + 'out.xml') + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) + + command = [gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + self.assert_(False, + '%s was killed by signal %d' % (gtest_prog_name, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(expected_exit_code, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, expected_exit_code)) + actual = minidom.parse(xml_path) + return actual + + def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code): + """ + Asserts that the XML document generated by running the program + gtest_prog_name matches expected_xml, a string containing another + XML document. Furthermore, the program's exit code must be + expected_exit_code. + """ + + actual = self._GetXmlOutput(gtest_prog_name, expected_exit_code) + expected = minidom.parseString(expected_xml) + self.NormalizeXml(actual.documentElement) + self.AssertEquivalentNodes(expected.documentElement, + actual.documentElement) + expected.unlink() + actual.unlink() + + +if __name__ == '__main__': + os.environ['GTEST_STACK_TRACE_DEPTH'] = '1' + gtest_test_utils.Main() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_output_unittest_.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_output_unittest_.cc new file mode 100644 index 0000000..bf0c871 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_output_unittest_.cc @@ -0,0 +1,177 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. + +// Author: eefacm@gmail.com (Sean Mcafee) + +// Unit test for Google Test XML output. +// +// A user can specify XML output in a Google Test program to run via +// either the GTEST_OUTPUT environment variable or the --gtest_output +// flag. This is used for testing such functionality. +// +// This program will be invoked from a Python unit test. Don't run it +// directly. + +#include "gtest/gtest.h" + +using ::testing::InitGoogleTest; +using ::testing::TestEventListeners; +using ::testing::TestWithParam; +using ::testing::UnitTest; +using ::testing::Test; +using ::testing::Values; + +class SuccessfulTest : public Test { +}; + +TEST_F(SuccessfulTest, Succeeds) { + SUCCEED() << "This is a success."; + ASSERT_EQ(1, 1); +} + +class FailedTest : public Test { +}; + +TEST_F(FailedTest, Fails) { + ASSERT_EQ(1, 2); +} + +class DisabledTest : public Test { +}; + +TEST_F(DisabledTest, DISABLED_test_not_run) { + FAIL() << "Unexpected failure: Disabled test should not be run"; +} + +TEST(MixedResultTest, Succeeds) { + EXPECT_EQ(1, 1); + ASSERT_EQ(1, 1); +} + +TEST(MixedResultTest, Fails) { + EXPECT_EQ(1, 2); + ASSERT_EQ(2, 3); +} + +TEST(MixedResultTest, DISABLED_test) { + FAIL() << "Unexpected failure: Disabled test should not be run"; +} + +TEST(XmlQuotingTest, OutputsCData) { + FAIL() << "XML output: " + ""; +} + +// Helps to test that invalid characters produced by test code do not make +// it into the XML file. +TEST(InvalidCharactersTest, InvalidCharactersInMessage) { + FAIL() << "Invalid characters in brackets [\x1\x2]"; +} + +class PropertyRecordingTest : public Test { +}; + +TEST_F(PropertyRecordingTest, OneProperty) { + RecordProperty("key_1", "1"); +} + +TEST_F(PropertyRecordingTest, IntValuedProperty) { + RecordProperty("key_int", 1); +} + +TEST_F(PropertyRecordingTest, ThreeProperties) { + RecordProperty("key_1", "1"); + RecordProperty("key_2", "2"); + RecordProperty("key_3", "3"); +} + +TEST_F(PropertyRecordingTest, TwoValuesForOneKeyUsesLastValue) { + RecordProperty("key_1", "1"); + RecordProperty("key_1", "2"); +} + +TEST(NoFixtureTest, RecordProperty) { + RecordProperty("key", "1"); +} + +void ExternalUtilityThatCallsRecordProperty(const char* key, int value) { + testing::Test::RecordProperty(key, value); +} + +void ExternalUtilityThatCallsRecordProperty(const char* key, + const char* value) { + testing::Test::RecordProperty(key, value); +} + +TEST(NoFixtureTest, ExternalUtilityThatCallsRecordIntValuedProperty) { + ExternalUtilityThatCallsRecordProperty("key_for_utility_int", 1); +} + +TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) { + ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1"); +} + +// Verifies that the test parameter value is output in the 'value_param' +// XML attribute for value-parameterized tests. +class ValueParamTest : public TestWithParam {}; +TEST_P(ValueParamTest, HasValueParamAttribute) {} +TEST_P(ValueParamTest, AnotherTestThatHasValueParamAttribute) {} +INSTANTIATE_TEST_CASE_P(Single, ValueParamTest, Values(33, 42)); + +#if GTEST_HAS_TYPED_TEST +// Verifies that the type parameter name is output in the 'type_param' +// XML attribute for typed tests. +template class TypedTest : public Test {}; +typedef testing::Types TypedTestTypes; +TYPED_TEST_CASE(TypedTest, TypedTestTypes); +TYPED_TEST(TypedTest, HasTypeParamAttribute) {} +#endif + +#if GTEST_HAS_TYPED_TEST_P +// Verifies that the type parameter name is output in the 'type_param' +// XML attribute for type-parameterized tests. +template class TypeParameterizedTestCase : public Test {}; +TYPED_TEST_CASE_P(TypeParameterizedTestCase); +TYPED_TEST_P(TypeParameterizedTestCase, HasTypeParamAttribute) {} +REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTestCase, HasTypeParamAttribute); +typedef testing::Types TypeParameterizedTestCaseTypes; +INSTANTIATE_TYPED_TEST_CASE_P(Single, + TypeParameterizedTestCase, + TypeParameterizedTestCaseTypes); +#endif + +int main(int argc, char** argv) { + InitGoogleTest(&argc, argv); + + if (argc > 1 && strcmp(argv[1], "--shut_down_xml") == 0) { + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_xml_generator()); + } + return RUN_ALL_TESTS(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_test_utils.py b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_test_utils.py new file mode 100755 index 0000000..0e5a108 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/gtest_xml_test_utils.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# 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. + +"""Unit test utilities for gtest_xml_output""" + +__author__ = 'eefacm@gmail.com (Sean Mcafee)' + +import re +from xml.dom import minidom, Node + +import gtest_test_utils + + +GTEST_OUTPUT_FLAG = '--gtest_output' +GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' + +class GTestXMLTestCase(gtest_test_utils.TestCase): + """ + Base class for tests of Google Test's XML output functionality. + """ + + + def AssertEquivalentNodes(self, expected_node, actual_node): + """ + Asserts that actual_node (a DOM node object) is equivalent to + expected_node (another DOM node object), in that either both of + them are CDATA nodes and have the same value, or both are DOM + elements and actual_node meets all of the following conditions: + + * It has the same tag name as expected_node. + * It has the same set of attributes as expected_node, each with + the same value as the corresponding attribute of expected_node. + Exceptions are any attribute named "time", which needs only be + convertible to a floating-point number and any attribute named + "type_param" which only has to be non-empty. + * It has an equivalent set of child nodes (including elements and + CDATA sections) as expected_node. Note that we ignore the + order of the children as they are not guaranteed to be in any + particular order. + """ + + if expected_node.nodeType == Node.CDATA_SECTION_NODE: + self.assertEquals(Node.CDATA_SECTION_NODE, actual_node.nodeType) + self.assertEquals(expected_node.nodeValue, actual_node.nodeValue) + return + + self.assertEquals(Node.ELEMENT_NODE, actual_node.nodeType) + self.assertEquals(Node.ELEMENT_NODE, expected_node.nodeType) + self.assertEquals(expected_node.tagName, actual_node.tagName) + + expected_attributes = expected_node.attributes + actual_attributes = actual_node .attributes + self.assertEquals( + expected_attributes.length, actual_attributes.length, + 'attribute numbers differ in element ' + actual_node.tagName) + for i in range(expected_attributes.length): + expected_attr = expected_attributes.item(i) + actual_attr = actual_attributes.get(expected_attr.name) + self.assert_( + actual_attr is not None, + 'expected attribute %s not found in element %s' % + (expected_attr.name, actual_node.tagName)) + self.assertEquals(expected_attr.value, actual_attr.value, + ' values of attribute %s in element %s differ' % + (expected_attr.name, actual_node.tagName)) + + expected_children = self._GetChildren(expected_node) + actual_children = self._GetChildren(actual_node) + self.assertEquals( + len(expected_children), len(actual_children), + 'number of child elements differ in element ' + actual_node.tagName) + for child_id, child in expected_children.iteritems(): + self.assert_(child_id in actual_children, + '<%s> is not in <%s> (in element %s)' % + (child_id, actual_children, actual_node.tagName)) + self.AssertEquivalentNodes(child, actual_children[child_id]) + + identifying_attribute = { + 'testsuites': 'name', + 'testsuite': 'name', + 'testcase': 'name', + 'failure': 'message', + } + + def _GetChildren(self, element): + """ + Fetches all of the child nodes of element, a DOM Element object. + Returns them as the values of a dictionary keyed by the IDs of the + children. For , and elements, the ID + is the value of their "name" attribute; for elements, it is + the value of the "message" attribute; CDATA sections and non-whitespace + text nodes are concatenated into a single CDATA section with ID + "detail". An exception is raised if any element other than the above + four is encountered, if two child elements with the same identifying + attributes are encountered, or if any other type of node is encountered. + """ + + children = {} + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self.assert_(child.tagName in self.identifying_attribute, + 'Encountered unknown element <%s>' % child.tagName) + childID = child.getAttribute(self.identifying_attribute[child.tagName]) + self.assert_(childID not in children) + children[childID] = child + elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: + if 'detail' not in children: + if (child.nodeType == Node.CDATA_SECTION_NODE or + not child.nodeValue.isspace()): + children['detail'] = child.ownerDocument.createCDATASection( + child.nodeValue) + else: + children['detail'].nodeValue += child.nodeValue + else: + self.fail('Encountered unexpected node type %d' % child.nodeType) + return children + + def NormalizeXml(self, element): + """ + Normalizes Google Test's XML output to eliminate references to transient + information that may change from run to run. + + * The "time" attribute of , and + elements is replaced with a single asterisk, if it contains + only digit characters. + * The "timestamp" attribute of elements is replaced with a + single asterisk, if it contains a valid ISO8601 datetime value. + * The "type_param" attribute of elements is replaced with a + single asterisk (if it sn non-empty) as it is the type name returned + by the compiler and is platform dependent. + * The line info reported in the first line of the "message" + attribute and CDATA section of elements is replaced with the + file's basename and a single asterisk for the line number. + * The directory names in file paths are removed. + * The stack traces are removed. + """ + + if element.tagName == 'testsuites': + timestamp = element.getAttributeNode('timestamp') + timestamp.value = re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$', + '*', timestamp.value) + if element.tagName in ('testsuites', 'testsuite', 'testcase'): + time = element.getAttributeNode('time') + time.value = re.sub(r'^\d+(\.\d+)?$', '*', time.value) + type_param = element.getAttributeNode('type_param') + if type_param and type_param.value: + type_param.value = '*' + elif element.tagName == 'failure': + source_line_pat = r'^.*[/\\](.*:)\d+\n' + # Replaces the source line information with a normalized form. + message = element.getAttributeNode('message') + message.value = re.sub(source_line_pat, '\\1*\n', message.value) + for child in element.childNodes: + if child.nodeType == Node.CDATA_SECTION_NODE: + # Replaces the source line information with a normalized form. + cdata = re.sub(source_line_pat, '\\1*\n', child.nodeValue) + # Removes the actual stack trace. + child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*', + '', cdata) + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self.NormalizeXml(child) diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/production.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/test/production.cc new file mode 100644 index 0000000..8b8a40b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/production.cc @@ -0,0 +1,36 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This is part of the unit test for include/gtest/gtest_prod.h. + +#include "production.h" + +PrivateCode::PrivateCode() : x_(0) {} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/test/production.h b/cpp/thirdparty/protobuf-2.5.0/gtest/test/production.h new file mode 100644 index 0000000..98fd5e4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/test/production.h @@ -0,0 +1,55 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This is part of the unit test for include/gtest/gtest_prod.h. + +#ifndef GTEST_TEST_PRODUCTION_H_ +#define GTEST_TEST_PRODUCTION_H_ + +#include "gtest/gtest_prod.h" + +class PrivateCode { + public: + // Declares a friend test that does not use a fixture. + FRIEND_TEST(PrivateCodeTest, CanAccessPrivateMembers); + + // Declares a friend test that uses a fixture. + FRIEND_TEST(PrivateCodeFixtureTest, CanAccessPrivateMembers); + + PrivateCode(); + + int x() const { return x_; } + private: + void set_x(int an_x) { x_ = an_x; } + int x_; +}; + +#endif // GTEST_TEST_PRODUCTION_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/DebugProject.xcconfig b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/DebugProject.xcconfig new file mode 100644 index 0000000..3d68157 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/DebugProject.xcconfig @@ -0,0 +1,30 @@ +// +// DebugProject.xcconfig +// +// These are Debug Configuration project settings for the gtest framework and +// examples. It is set in the "Based On:" dropdown in the "Project" info +// dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +#include "General.xcconfig" + +// No optimization +GCC_OPTIMIZATION_LEVEL = 0 + +// Deployment postprocessing is what triggers Xcode to strip, turn it off +DEPLOYMENT_POSTPROCESSING = NO + +// Dead code stripping off +DEAD_CODE_STRIPPING = NO + +// Debug symbols should be on obviously +GCC_GENERATE_DEBUGGING_SYMBOLS = YES + +// Define the DEBUG macro in all debug builds +OTHER_CFLAGS = $(OTHER_CFLAGS) -DDEBUG=1 + +// These are turned off to avoid STL incompatibilities with client code +// // Turns on special C++ STL checks to "encourage" good STL use +// GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS) _GLIBCXX_DEBUG_PEDANTIC _GLIBCXX_DEBUG _GLIBCPP_CONCEPT_CHECKS diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/FrameworkTarget.xcconfig b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/FrameworkTarget.xcconfig new file mode 100644 index 0000000..357b1c8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/FrameworkTarget.xcconfig @@ -0,0 +1,17 @@ +// +// FrameworkTarget.xcconfig +// +// These are Framework target settings for the gtest framework and examples. It +// is set in the "Based On:" dropdown in the "Target" info dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +// Dynamic libs need to be position independent +GCC_DYNAMIC_NO_PIC = NO + +// Dynamic libs should not have their external symbols stripped. +STRIP_STYLE = non-global + +// Let the user install by specifying the $DSTROOT with xcodebuild +SKIP_INSTALL = NO diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/General.xcconfig b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/General.xcconfig new file mode 100644 index 0000000..f23e322 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/General.xcconfig @@ -0,0 +1,41 @@ +// +// General.xcconfig +// +// These are General configuration settings for the gtest framework and +// examples. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +// Build for PPC and Intel, 32- and 64-bit +ARCHS = i386 x86_64 ppc ppc64 + +// Zerolink prevents link warnings so turn it off +ZERO_LINK = NO + +// Prebinding considered unhelpful in 10.3 and later +PREBINDING = NO + +// Strictest warning policy +WARNING_CFLAGS = -Wall -Werror -Wendif-labels -Wnewline-eof -Wno-sign-compare -Wshadow + +// Work around Xcode bugs by using external strip. See: +// http://lists.apple.com/archives/Xcode-users/2006/Feb/msg00050.html +SEPARATE_STRIP = YES + +// Force C99 dialect +GCC_C_LANGUAGE_STANDARD = c99 + +// not sure why apple defaults this on, but it's pretty risky +ALWAYS_SEARCH_USER_PATHS = NO + +// Turn on position dependent code for most cases (overridden where appropriate) +GCC_DYNAMIC_NO_PIC = YES + +// Default SDK and minimum OS version is 10.4 +SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk +MACOSX_DEPLOYMENT_TARGET = 10.4 +GCC_VERSION = 4.0 + +// VERSIONING BUILD SETTINGS (used in Info.plist) +GTEST_VERSIONINFO_ABOUT = © 2008 Google Inc. diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/ReleaseProject.xcconfig b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/ReleaseProject.xcconfig new file mode 100644 index 0000000..5349f0a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/ReleaseProject.xcconfig @@ -0,0 +1,32 @@ +// +// ReleaseProject.xcconfig +// +// These are Release Configuration project settings for the gtest framework +// and examples. It is set in the "Based On:" dropdown in the "Project" info +// dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +#include "General.xcconfig" + +// subconfig/Release.xcconfig + +// Optimize for space and size (Apple recommendation) +GCC_OPTIMIZATION_LEVEL = s + +// Deploment postprocessing is what triggers Xcode to strip +DEPLOYMENT_POSTPROCESSING = YES + +// No symbols +GCC_GENERATE_DEBUGGING_SYMBOLS = NO + +// Dead code strip does not affect ObjC code but can help for C +DEAD_CODE_STRIPPING = YES + +// NDEBUG is used by things like assert.h, so define it for general compat. +// ASSERT going away in release tends to create unused vars. +OTHER_CFLAGS = $(OTHER_CFLAGS) -DNDEBUG=1 -Wno-unused-variable + +// When we strip we want to strip all symbols in release, but save externals. +STRIP_STYLE = all diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/StaticLibraryTarget.xcconfig b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/StaticLibraryTarget.xcconfig new file mode 100644 index 0000000..3922fa5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/StaticLibraryTarget.xcconfig @@ -0,0 +1,18 @@ +// +// StaticLibraryTarget.xcconfig +// +// These are static library target settings for libgtest.a. It +// is set in the "Based On:" dropdown in the "Target" info dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +// Static libs can be included in bundles so make them position independent +GCC_DYNAMIC_NO_PIC = NO + +// Static libs should not have their internal globals or external symbols +// stripped. +STRIP_STYLE = debugging + +// Let the user install by specifying the $DSTROOT with xcodebuild +SKIP_INSTALL = NO diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/TestTarget.xcconfig b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/TestTarget.xcconfig new file mode 100644 index 0000000..e6652ba --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Config/TestTarget.xcconfig @@ -0,0 +1,8 @@ +// +// TestTarget.xcconfig +// +// These are Test target settings for the gtest framework and examples. It +// is set in the "Based On:" dropdown in the "Target" info dialog. + +PRODUCT_NAME = $(TARGET_NAME) +HEADER_SEARCH_PATHS = ../include diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Resources/Info.plist b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Resources/Info.plist new file mode 100644 index 0000000..9dd28ea --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Resources/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.google.${PRODUCT_NAME} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + GTEST_VERSIONINFO_LONG + CFBundleShortVersionString + GTEST_VERSIONINFO_SHORT + CFBundleGetInfoString + ${PRODUCT_NAME} GTEST_VERSIONINFO_LONG, ${GTEST_VERSIONINFO_ABOUT} + NSHumanReadableCopyright + ${GTEST_VERSIONINFO_ABOUT} + CSResourcesFileMapped + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/Info.plist b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/Info.plist new file mode 100644 index 0000000..f3852ed --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.google.gtest.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CSResourcesFileMapped + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj new file mode 100644 index 0000000..497617e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj @@ -0,0 +1,457 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXAggregateTarget section */ + 4024D162113D7D2400C7059E /* Test */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */; + buildPhases = ( + 4024D161113D7D2400C7059E /* ShellScript */, + ); + dependencies = ( + 4024D166113D7D3100C7059E /* PBXTargetDependency */, + ); + name = Test; + productName = TestAndBuild; + }; + 4024D1E9113D83FF00C7059E /* TestAndBuild */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */; + buildPhases = ( + ); + dependencies = ( + 4024D1ED113D840900C7059E /* PBXTargetDependency */, + 4024D1EF113D840D00C7059E /* PBXTargetDependency */, + ); + name = TestAndBuild; + productName = TestAndBuild; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1230E5AEE3500C7F239 /* widget.cc */; }; + 3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B7EB1240E5AEE3500C7F239 /* widget.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */; }; + 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; }; + 4024D188113D7D7800C7059E /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D185113D7D5500C7059E /* libgtest.a */; }; + 4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D183113D7D5500C7059E /* libgtest_main.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = gTestExample; + }; + 4024D165113D7D3100C7059E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3B07BDE90E3F3F9E00647869; + remoteInfo = WidgetFrameworkTest; + }; + 4024D1EC113D840900C7059E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = WidgetFramework; + }; + 4024D1EE113D840D00C7059E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4024D162113D7D2400C7059E; + remoteInfo = Test; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = WidgetFrameworkTest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B7EB1230E5AEE3500C7F239 /* widget.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget.cc; sourceTree = ""; }; + 3B7EB1240E5AEE3500C7F239 /* widget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = widget.h; sourceTree = ""; }; + 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget_test.cc; sourceTree = ""; }; + 4024D183113D7D5500C7059E /* libgtest_main.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest_main.a; path = /usr/local/lib/libgtest_main.a; sourceTree = ""; }; + 4024D185113D7D5500C7059E /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest.a; path = /usr/local/lib/libgtest.a; sourceTree = ""; }; + 4024D1E2113D838200C7059E /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = ""; }; + 8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 8D07F2C80486CC7A007CD1D0 /* Widget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Widget.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3B07BDE80E3F3F9E00647869 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */, + 4024D188113D7D7800C7059E /* libgtest.a in Frameworks */, + 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C30486CC7A007CD1D0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 8D07F2C80486CC7A007CD1D0 /* Widget.framework */, + 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */, + ); + name = Products; + sourceTree = ""; + }; + 0867D691FE84028FC02AAC07 /* gTestExample */ = { + isa = PBXGroup; + children = ( + 4024D1E1113D836C00C7059E /* Scripts */, + 08FB77ACFE841707C02AAC07 /* Source */, + 089C1665FE841158C02AAC07 /* Resources */, + 3B07BE350E4094E400647869 /* Test */, + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, + 034768DDFF38A45A11DB9C8B /* Products */, + ); + name = gTestExample; + sourceTree = ""; + }; + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 4024D183113D7D5500C7059E /* libgtest_main.a */, + 4024D185113D7D5500C7059E /* libgtest.a */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 089C1665FE841158C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D07F2C70486CC7A007CD1D0 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77ACFE841707C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 3B7EB1230E5AEE3500C7F239 /* widget.cc */, + 3B7EB1240E5AEE3500C7F239 /* widget.h */, + ); + name = Source; + sourceTree = ""; + }; + 3B07BE350E4094E400647869 /* Test */ = { + isa = PBXGroup; + children = ( + 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */, + ); + name = Test; + sourceTree = ""; + }; + 4024D1E1113D836C00C7059E /* Scripts */ = { + isa = PBXGroup; + children = ( + 4024D1E2113D838200C7059E /* runtests.sh */, + ); + name = Scripts; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */; + buildPhases = ( + 3B07BDE70E3F3F9E00647869 /* Sources */, + 3B07BDE80E3F3F9E00647869 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */, + ); + name = WidgetFrameworkTest; + productName = gTestExampleTest; + productReference = 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */; + productType = "com.apple.product-type.tool"; + }; + 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */; + buildPhases = ( + 8D07F2C10486CC7A007CD1D0 /* Sources */, + 8D07F2C30486CC7A007CD1D0 /* Frameworks */, + 8D07F2BD0486CC7A007CD1D0 /* Headers */, + 8D07F2BF0486CC7A007CD1D0 /* Resources */, + 8D07F2C50486CC7A007CD1D0 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = WidgetFramework; + productInstallPath = "$(HOME)/Library/Frameworks"; + productName = gTestExample; + productReference = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + mainGroup = 0867D691FE84028FC02AAC07 /* gTestExample */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */, + 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */, + 4024D162113D7D2400C7059E /* Test */, + 4024D1E9113D83FF00C7059E /* TestAndBuild */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 8D07F2C50486CC7A007CD1D0 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 4024D161113D7D2400C7059E /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/bash $SRCROOT/runtests.sh $BUILT_PRODUCTS_DIR/WidgetFrameworkTest\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3B07BDE70E3F3F9E00647869 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C10486CC7A007CD1D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */; + targetProxy = 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */; + }; + 4024D166113D7D3100C7059E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */; + targetProxy = 4024D165113D7D3100C7059E /* PBXContainerItemProxy */; + }; + 4024D1ED113D840900C7059E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */; + targetProxy = 4024D1EC113D840900C7059E /* PBXContainerItemProxy */; + }; + 4024D1EF113D840D00C7059E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4024D162113D7D2400C7059E /* Test */; + targetProxy = 4024D1EE113D840D00C7059E /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 3B07BDEC0E3F3F9F00647869 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = WidgetFrameworkTest; + }; + name = Debug; + }; + 3B07BDED0E3F3F9F00647869 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = WidgetFrameworkTest; + }; + name = Release; + }; + 4024D163113D7D2400C7059E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Debug; + }; + 4024D164113D7D2400C7059E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Release; + }; + 4024D1EA113D83FF00C7059E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Debug; + }; + 4024D1EB113D83FF00C7059E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Release; + }; + 4FADC24308B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "@loader_path/../Frameworks"; + PRODUCT_NAME = Widget; + }; + name = Debug; + }; + 4FADC24408B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "@loader_path/../Frameworks"; + PRODUCT_NAME = Widget; + }; + name = Release; + }; + 4FADC24708B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = 4.0; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + 4FADC24808B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = 4.0; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3B07BDEC0E3F3F9F00647869 /* Debug */, + 3B07BDED0E3F3F9F00647869 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4024D163113D7D2400C7059E /* Debug */, + 4024D164113D7D2400C7059E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4024D1EA113D83FF00C7059E /* Debug */, + 4024D1EB113D83FF00C7059E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24308B4156D00ABE55E /* Debug */, + 4FADC24408B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24708B4156D00ABE55E /* Debug */, + 4FADC24808B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/runtests.sh b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/runtests.sh new file mode 100644 index 0000000..4a0d413 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/runtests.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +# Executes the samples and tests for the Google Test Framework. + +# Help the dynamic linker find the path to the libraries. +export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR +export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR + +# Create some executables. +test_executables=$@ + +# Now execute each one in turn keeping track of how many succeeded and failed. +succeeded=0 +failed=0 +failed_list=() +for test in ${test_executables[*]}; do + "$test" + result=$? + if [ $result -eq 0 ]; then + succeeded=$(( $succeeded + 1 )) + else + failed=$(( failed + 1 )) + failed_list="$failed_list $test" + fi +done + +# Report the successes and failures to the console. +echo "Tests complete with $succeeded successes and $failed failures." +if [ $failed -ne 0 ]; then + echo "The following tests failed:" + echo $failed_list +fi +exit $failed diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget.cc new file mode 100644 index 0000000..bfc4e7f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget.cc @@ -0,0 +1,63 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: preston.a.jackson@gmail.com (Preston Jackson) +// +// Google Test - FrameworkSample +// widget.cc +// + +// Widget is a very simple class used for demonstrating the use of gtest + +#include "widget.h" + +Widget::Widget(int number, const std::string& name) + : number_(number), + name_(name) {} + +Widget::~Widget() {} + +float Widget::GetFloatValue() const { + return number_; +} + +int Widget::GetIntValue() const { + return static_cast(number_); +} + +std::string Widget::GetStringValue() const { + return name_; +} + +void Widget::GetCharPtrValue(char* buffer, size_t max_size) const { + // Copy the char* representation of name_ into buffer, up to max_size. + strncpy(buffer, name_.c_str(), max_size-1); + buffer[max_size-1] = '\0'; + return; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget.h b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget.h new file mode 100644 index 0000000..0c55cdc --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget.h @@ -0,0 +1,59 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: preston.a.jackson@gmail.com (Preston Jackson) +// +// Google Test - FrameworkSample +// widget.h +// + +// Widget is a very simple class used for demonstrating the use of gtest. It +// simply stores two values a string and an integer, which are returned via +// public accessors in multiple forms. + +#import + +class Widget { + public: + Widget(int number, const std::string& name); + ~Widget(); + + // Public accessors to number data + float GetFloatValue() const; + int GetIntValue() const; + + // Public accessors to the string data + std::string GetStringValue() const; + void GetCharPtrValue(char* buffer, size_t max_size) const; + + private: + // Data members + float number_; + std::string name_; +}; diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget_test.cc b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget_test.cc new file mode 100644 index 0000000..8725994 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Samples/FrameworkSample/widget_test.cc @@ -0,0 +1,68 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// 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. +// +// Author: preston.a.jackson@gmail.com (Preston Jackson) +// +// Google Test - FrameworkSample +// widget_test.cc +// + +// This is a simple test file for the Widget class in the Widget.framework + +#include +#include "gtest/gtest.h" + +#include + +// This test verifies that the constructor sets the internal state of the +// Widget class correctly. +TEST(WidgetInitializerTest, TestConstructor) { + Widget widget(1.0f, "name"); + EXPECT_FLOAT_EQ(1.0f, widget.GetFloatValue()); + EXPECT_EQ(std::string("name"), widget.GetStringValue()); +} + +// This test verifies the conversion of the float and string values to int and +// char*, respectively. +TEST(WidgetInitializerTest, TestConversion) { + Widget widget(1.0f, "name"); + EXPECT_EQ(1, widget.GetIntValue()); + + size_t max_size = 128; + char buffer[max_size]; + widget.GetCharPtrValue(buffer, max_size); + EXPECT_STREQ("name", buffer); +} + +// Use the Google Test main that is linked into the framework. It does something +// like this: +// int main(int argc, char** argv) { +// testing::InitGoogleTest(&argc, argv); +// return RUN_ALL_TESTS(); +// } diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Scripts/runtests.sh b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Scripts/runtests.sh new file mode 100644 index 0000000..3fc229f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Scripts/runtests.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +# Executes the samples and tests for the Google Test Framework. + +# Help the dynamic linker find the path to the libraries. +export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR +export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR + +# Create some executables. +test_executables=("$BUILT_PRODUCTS_DIR/gtest_unittest-framework" + "$BUILT_PRODUCTS_DIR/gtest_unittest" + "$BUILT_PRODUCTS_DIR/sample1_unittest-framework" + "$BUILT_PRODUCTS_DIR/sample1_unittest-static") + +# Now execute each one in turn keeping track of how many succeeded and failed. +succeeded=0 +failed=0 +failed_list=() +for test in ${test_executables[*]}; do + "$test" + result=$? + if [ $result -eq 0 ]; then + succeeded=$(( $succeeded + 1 )) + else + failed=$(( failed + 1 )) + failed_list="$failed_list $test" + fi +done + +# Report the successes and failures to the console. +echo "Tests complete with $succeeded successes and $failed failures." +if [ $failed -ne 0 ]; then + echo "The following tests failed:" + echo $failed_list +fi +exit $failed diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Scripts/versiongenerate.py b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Scripts/versiongenerate.py new file mode 100644 index 0000000..81de8c9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/Scripts/versiongenerate.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# 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. + +"""A script to prepare version informtion for use the gtest Info.plist file. + + This script extracts the version information from the configure.ac file and + uses it to generate a header file containing the same information. The + #defines in this header file will be included in during the generation of + the Info.plist of the framework, giving the correct value to the version + shown in the Finder. + + This script makes the following assumptions (these are faults of the script, + not problems with the Autoconf): + 1. The AC_INIT macro will be contained within the first 1024 characters + of configure.ac + 2. The version string will be 3 integers separated by periods and will be + surrounded by squre brackets, "[" and "]" (e.g. [1.0.1]). The first + segment represents the major version, the second represents the minor + version and the third represents the fix version. + 3. No ")" character exists between the opening "(" and closing ")" of + AC_INIT, including in comments and character strings. +""" + +import sys +import re + +# Read the command line argument (the output directory for Version.h) +if (len(sys.argv) < 3): + print "Usage: versiongenerate.py input_dir output_dir" + sys.exit(1) +else: + input_dir = sys.argv[1] + output_dir = sys.argv[2] + +# Read the first 1024 characters of the configure.ac file +config_file = open("%s/configure.ac" % input_dir, 'r') +buffer_size = 1024 +opening_string = config_file.read(buffer_size) +config_file.close() + +# Extract the version string from the AC_INIT macro +# The following init_expression means: +# Extract three integers separated by periods and surrounded by squre +# brackets(e.g. "[1.0.1]") between "AC_INIT(" and ")". Do not be greedy +# (*? is the non-greedy flag) since that would pull in everything between +# the first "(" and the last ")" in the file. +version_expression = re.compile(r"AC_INIT\(.*?\[(\d+)\.(\d+)\.(\d+)\].*?\)", + re.DOTALL) +version_values = version_expression.search(opening_string) +major_version = version_values.group(1) +minor_version = version_values.group(2) +fix_version = version_values.group(3) + +# Write the version information to a header file to be included in the +# Info.plist file. +file_data = """// +// DO NOT MODIFY THIS FILE (but you can delete it) +// +// This file is autogenerated by the versiongenerate.py script. This script +// is executed in a "Run Script" build phase when creating gtest.framework. This +// header file is not used during compilation of C-source. Rather, it simply +// defines some version strings for substitution in the Info.plist. Because of +// this, we are not not restricted to C-syntax nor are we using include guards. +// + +#define GTEST_VERSIONINFO_SHORT %s.%s +#define GTEST_VERSIONINFO_LONG %s.%s.%s + +""" % (major_version, minor_version, major_version, minor_version, fix_version) +version_file = open("%s/Version.h" % output_dir, 'w') +version_file.write(file_data) +version_file.close() diff --git a/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/gtest.xcodeproj/project.pbxproj b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/gtest.xcodeproj/project.pbxproj new file mode 100644 index 0000000..da6455b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/gtest/xcode/gtest.xcodeproj/project.pbxproj @@ -0,0 +1,1084 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXAggregateTarget section */ + 3B238F5F0E828B5400846E11 /* Check */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */; + buildPhases = ( + 3B238F5E0E828B5400846E11 /* ShellScript */, + ); + dependencies = ( + 40899F9D0FFA740F000B29AE /* PBXTargetDependency */, + 40C849F7101A43440083642A /* PBXTargetDependency */, + 4089A0980FFAD34A000B29AE /* PBXTargetDependency */, + 40C849F9101A43490083642A /* PBXTargetDependency */, + ); + name = Check; + productName = Check; + }; + 40C44ADC0E3798F4008FCC51 /* Version Info */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */; + buildPhases = ( + 40C44ADB0E3798F4008FCC51 /* Generate Version.h */, + ); + comments = "The generation of Version.h must be performed in its own target. Since the Info.plist is preprocessed before any of the other build phases in gtest, the Version.h file would not be ready if included as a build phase of that target."; + dependencies = ( + ); + name = "Version Info"; + productName = Version.h; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */ = {isa = PBXBuildFile; fileRef = 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */; }; + 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DB0E2F799B00CF7658 /* gtest-death-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884390E2F799B00CF7658 /* gtest-message.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DC0E2F799B00CF7658 /* gtest-message.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DD0E2F799B00CF7658 /* gtest-spi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843B0E2F799B00CF7658 /* gtest.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DE0E2F799B00CF7658 /* gtest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883E00E2F799B00CF7658 /* gtest_prod.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884500E2F799B00CF7658 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 404883F60E2F799B00CF7658 /* README */; }; + 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */; }; + 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E30E2F799B00CF7658 /* gtest-filepath.h */; }; + 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E40E2F799B00CF7658 /* gtest-internal.h */; }; + 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E50E2F799B00CF7658 /* gtest-port.h */; }; + 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E60E2F799B00CF7658 /* gtest-string.h */; }; + 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */ = {isa = PBXBuildFile; fileRef = 404884A90E2F7CD900CF7658 /* CHANGES */; }; + 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */ = {isa = PBXBuildFile; fileRef = 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */; }; + 404884AE0E2F7CD900CF7658 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 404884AB0E2F7CD900CF7658 /* LICENSE */; }; + 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; + 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 40899F4D0FFA7271000B29AE /* gtest-tuple.h */; }; + 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; + 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; + 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; + 40C848FF101A21150083642A /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; + 40C84915101A21DF0083642A /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4048840D0E2F799B00CF7658 /* gtest_main.cc */; }; + 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84978101A36540083642A /* libgtest_main.a in Resources */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84980101A36850083642A /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; + 40C84982101A36850083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; + 40C84983101A36850083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C8498F101A36A60083642A /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; + 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; + 40C84992101A36A60083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; + 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C849A2101A37050083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; + 40C849A4101A37150083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; + 4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 4539C9330EC280AE00A70F4C /* gtest-param-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */; }; + 4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */; }; + 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9370EC280E200A70F4C /* gtest-param-util.h */; }; + 4567C8181264FF71007740BE /* gtest-printers.h in Headers */ = {isa = PBXBuildFile; fileRef = 4567C8171264FF71007740BE /* gtest-printers.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40899F420FFA7184000B29AE; + remoteInfo = gtest_unittest; + }; + 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4089A0120FFACEFC000B29AE; + remoteInfo = sample1_unittest; + }; + 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C44ADC0E3798F4008FCC51; + remoteInfo = Version.h; + }; + 40C8497C101A36850083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C8497E101A36850083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8498B101A36A60083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C8498D101A36A60083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8499B101A36DC0083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8499D101A36E50083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = "gtest-framework"; + }; + 40C8499F101A36F10083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = "gtest-framework"; + }; + 40C849F6101A43440083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8497A101A36850083642A; + remoteInfo = "gtest_unittest-static"; + }; + 40C849F8101A43490083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C84989101A36A60083642A; + remoteInfo = "sample1_unittest-static"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 404884A50E2F7C0400CF7658 /* Copy Headers Internal */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = Headers/internal; + dstSubfolderSpec = 6; + files = ( + 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */, + 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */, + 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */, + 4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */, + 4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */, + 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */, + 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */, + 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */, + 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */, + 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */, + ); + name = "Copy Headers Internal"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 224A12A10E9EADA700BD17FD /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-all.cc"; sourceTree = ""; }; + 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "gtest-test-part.h"; sourceTree = ""; }; + 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_unittest.cc; sourceTree = ""; }; + 3B87D2100E96B92E000D1852 /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = ""; }; + 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-type-util.h"; sourceTree = ""; }; + 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-typed-test.h"; sourceTree = ""; }; + 403EE37C0E377822004BD1E2 /* versiongenerate.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = versiongenerate.py; sourceTree = ""; }; + 404883DB0E2F799B00CF7658 /* gtest-death-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test.h"; sourceTree = ""; }; + 404883DC0E2F799B00CF7658 /* gtest-message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-message.h"; sourceTree = ""; }; + 404883DD0E2F799B00CF7658 /* gtest-spi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-spi.h"; sourceTree = ""; }; + 404883DE0E2F799B00CF7658 /* gtest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest.h; sourceTree = ""; }; + 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_pred_impl.h; sourceTree = ""; }; + 404883E00E2F799B00CF7658 /* gtest_prod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_prod.h; sourceTree = ""; }; + 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test-internal.h"; sourceTree = ""; }; + 404883E30E2F799B00CF7658 /* gtest-filepath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-filepath.h"; sourceTree = ""; }; + 404883E40E2F799B00CF7658 /* gtest-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-internal.h"; sourceTree = ""; }; + 404883E50E2F799B00CF7658 /* gtest-port.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-port.h"; sourceTree = ""; }; + 404883E60E2F799B00CF7658 /* gtest-string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-string.h"; sourceTree = ""; }; + 404883F60E2F799B00CF7658 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README; path = ../README; sourceTree = SOURCE_ROOT; }; + 4048840D0E2F799B00CF7658 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main.cc; sourceTree = ""; }; + 404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; }; + 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; }; + 404884AB0E2F7CD900CF7658 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = SOURCE_ROOT; }; + 40899F430FFA7184000B29AE /* gtest_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 40899F4D0FFA7271000B29AE /* gtest-tuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-tuple.h"; sourceTree = ""; }; + 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = StaticLibraryTarget.xcconfig; sourceTree = ""; }; + 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4089A02C0FFACF7F000B29AE /* sample1.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1.cc; sourceTree = ""; }; + 4089A02D0FFACF7F000B29AE /* sample1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample1.h; sourceTree = ""; }; + 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1_unittest.cc; sourceTree = ""; }; + 40C848FA101A209C0083642A /* libgtest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C8490B101A217E0083642A /* libgtest_main.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest_main.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C84987101A36850083642A /* gtest_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C84997101A36A60083642A /* sample1_unittest-static */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-static"; sourceTree = BUILT_PRODUCTS_DIR; }; + 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugProject.xcconfig; sourceTree = ""; }; + 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FrameworkTarget.xcconfig; sourceTree = ""; }; + 40D4CDF30E30E07400294801 /* General.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = ""; }; + 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseProject.xcconfig; sourceTree = ""; }; + 40D4CF510E30F5E200294801 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4539C8FF0EC27F6400A70F4C /* gtest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = gtest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4539C9330EC280AE00A70F4C /* gtest-param-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-test.h"; sourceTree = ""; }; + 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-linked_ptr.h"; sourceTree = ""; }; + 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util-generated.h"; sourceTree = ""; }; + 4539C9370EC280E200A70F4C /* gtest-param-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util.h"; sourceTree = ""; }; + 4567C8171264FF71007740BE /* gtest-printers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-printers.h"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 40899F410FFA7184000B29AE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C849A4101A37150083642A /* gtest.framework in Frameworks */, + 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4089A0110FFACEFC000B29AE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C849A2101A37050083642A /* gtest.framework in Frameworks */, + 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84981101A36850083642A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84982101A36850083642A /* libgtest.a in Frameworks */, + 40C84983101A36850083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84991101A36A60083642A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84992101A36A60083642A /* libgtest.a in Frameworks */, + 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 4539C8FF0EC27F6400A70F4C /* gtest.framework */, + 40C848FA101A209C0083642A /* libgtest.a */, + 40C8490B101A217E0083642A /* libgtest_main.a */, + 40899F430FFA7184000B29AE /* gtest_unittest-framework */, + 40C84987101A36850083642A /* gtest_unittest */, + 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */, + 40C84997101A36A60083642A /* sample1_unittest-static */, + ); + name = Products; + sourceTree = ""; + }; + 0867D691FE84028FC02AAC07 /* gtest */ = { + isa = PBXGroup; + children = ( + 40D4CDF00E30E07400294801 /* Config */, + 08FB77ACFE841707C02AAC07 /* Source */, + 40D4CF4E0E30F5E200294801 /* Resources */, + 403EE37B0E377822004BD1E2 /* Scripts */, + 034768DDFF38A45A11DB9C8B /* Products */, + ); + name = gtest; + sourceTree = ""; + }; + 08FB77ACFE841707C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 404884A90E2F7CD900CF7658 /* CHANGES */, + 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */, + 404884AB0E2F7CD900CF7658 /* LICENSE */, + 404883F60E2F799B00CF7658 /* README */, + 404883D90E2F799B00CF7658 /* include */, + 4089A02F0FFACF84000B29AE /* samples */, + 404884070E2F799B00CF7658 /* src */, + 3B238BF00E7FE13B00846E11 /* test */, + ); + name = Source; + sourceTree = ""; + }; + 3B238BF00E7FE13B00846E11 /* test */ = { + isa = PBXGroup; + children = ( + 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */, + ); + name = test; + path = ../test; + sourceTree = SOURCE_ROOT; + }; + 403EE37B0E377822004BD1E2 /* Scripts */ = { + isa = PBXGroup; + children = ( + 403EE37C0E377822004BD1E2 /* versiongenerate.py */, + 3B87D2100E96B92E000D1852 /* runtests.sh */, + ); + path = Scripts; + sourceTree = ""; + }; + 404883D90E2F799B00CF7658 /* include */ = { + isa = PBXGroup; + children = ( + 404883DA0E2F799B00CF7658 /* gtest */, + ); + name = include; + path = ../include; + sourceTree = SOURCE_ROOT; + }; + 404883DA0E2F799B00CF7658 /* gtest */ = { + isa = PBXGroup; + children = ( + 404883E10E2F799B00CF7658 /* internal */, + 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */, + 404883DB0E2F799B00CF7658 /* gtest-death-test.h */, + 404883DC0E2F799B00CF7658 /* gtest-message.h */, + 4539C9330EC280AE00A70F4C /* gtest-param-test.h */, + 4567C8171264FF71007740BE /* gtest-printers.h */, + 404883DD0E2F799B00CF7658 /* gtest-spi.h */, + 404883DE0E2F799B00CF7658 /* gtest.h */, + 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */, + 404883E00E2F799B00CF7658 /* gtest_prod.h */, + 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */, + ); + path = gtest; + sourceTree = ""; + }; + 404883E10E2F799B00CF7658 /* internal */ = { + isa = PBXGroup; + children = ( + 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */, + 404883E30E2F799B00CF7658 /* gtest-filepath.h */, + 404883E40E2F799B00CF7658 /* gtest-internal.h */, + 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */, + 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */, + 4539C9370EC280E200A70F4C /* gtest-param-util.h */, + 404883E50E2F799B00CF7658 /* gtest-port.h */, + 404883E60E2F799B00CF7658 /* gtest-string.h */, + 40899F4D0FFA7271000B29AE /* gtest-tuple.h */, + 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */, + ); + path = internal; + sourceTree = ""; + }; + 404884070E2F799B00CF7658 /* src */ = { + isa = PBXGroup; + children = ( + 224A12A10E9EADA700BD17FD /* gtest-all.cc */, + 4048840D0E2F799B00CF7658 /* gtest_main.cc */, + ); + name = src; + path = ../src; + sourceTree = SOURCE_ROOT; + }; + 4089A02F0FFACF84000B29AE /* samples */ = { + isa = PBXGroup; + children = ( + 4089A02C0FFACF7F000B29AE /* sample1.cc */, + 4089A02D0FFACF7F000B29AE /* sample1.h */, + 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */, + ); + name = samples; + path = ../samples; + sourceTree = SOURCE_ROOT; + }; + 40D4CDF00E30E07400294801 /* Config */ = { + isa = PBXGroup; + children = ( + 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */, + 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */, + 40D4CDF30E30E07400294801 /* General.xcconfig */, + 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */, + 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */, + ); + path = Config; + sourceTree = ""; + }; + 40D4CF4E0E30F5E200294801 /* Resources */ = { + isa = PBXGroup; + children = ( + 40D4CF510E30F5E200294801 /* Info.plist */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */, + 404884390E2F799B00CF7658 /* gtest-message.h in Headers */, + 4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */, + 4567C8181264FF71007740BE /* gtest-printers.h in Headers */, + 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */, + 4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */, + 4048843B0E2F799B00CF7658 /* gtest.h in Headers */, + 4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */, + 4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */, + 224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 40899F420FFA7184000B29AE /* gtest_unittest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */; + buildPhases = ( + 40899F400FFA7184000B29AE /* Sources */, + 40899F410FFA7184000B29AE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C849A0101A36F10083642A /* PBXTargetDependency */, + ); + name = "gtest_unittest-framework"; + productName = gtest_unittest; + productReference = 40899F430FFA7184000B29AE /* gtest_unittest-framework */; + productType = "com.apple.product-type.tool"; + }; + 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */; + buildPhases = ( + 4089A0100FFACEFC000B29AE /* Sources */, + 4089A0110FFACEFC000B29AE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8499E101A36E50083642A /* PBXTargetDependency */, + ); + name = "sample1_unittest-framework"; + productName = sample1_unittest; + productReference = 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */; + productType = "com.apple.product-type.tool"; + }; + 40C848F9101A209C0083642A /* gtest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */; + buildPhases = ( + 40C848F7101A209C0083642A /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "gtest-static"; + productName = "gtest-static"; + productReference = 40C848FA101A209C0083642A /* libgtest.a */; + productType = "com.apple.product-type.library.static"; + }; + 40C8490A101A217E0083642A /* gtest_main-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */; + buildPhases = ( + 40C84908101A217E0083642A /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "gtest_main-static"; + productName = "gtest_main-static"; + productReference = 40C8490B101A217E0083642A /* libgtest_main.a */; + productType = "com.apple.product-type.library.static"; + }; + 40C8497A101A36850083642A /* gtest_unittest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */; + buildPhases = ( + 40C8497F101A36850083642A /* Sources */, + 40C84981101A36850083642A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8497B101A36850083642A /* PBXTargetDependency */, + 40C8497D101A36850083642A /* PBXTargetDependency */, + ); + name = "gtest_unittest-static"; + productName = gtest_unittest; + productReference = 40C84987101A36850083642A /* gtest_unittest */; + productType = "com.apple.product-type.tool"; + }; + 40C84989101A36A60083642A /* sample1_unittest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */; + buildPhases = ( + 40C8498E101A36A60083642A /* Sources */, + 40C84991101A36A60083642A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8498A101A36A60083642A /* PBXTargetDependency */, + 40C8498C101A36A60083642A /* PBXTargetDependency */, + ); + name = "sample1_unittest-static"; + productName = sample1_unittest; + productReference = 40C84997101A36A60083642A /* sample1_unittest-static */; + productType = "com.apple.product-type.tool"; + }; + 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */; + buildPhases = ( + 8D07F2C10486CC7A007CD1D0 /* Sources */, + 8D07F2BD0486CC7A007CD1D0 /* Headers */, + 404884A50E2F7C0400CF7658 /* Copy Headers Internal */, + 8D07F2BF0486CC7A007CD1D0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 40C44AE60E379922008FCC51 /* PBXTargetDependency */, + 408BEC101046CFE900DEF522 /* PBXTargetDependency */, + 40C8499C101A36DC0083642A /* PBXTargetDependency */, + ); + name = "gtest-framework"; + productInstallPath = "$(HOME)/Library/Frameworks"; + productName = gtest; + productReference = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 0867D691FE84028FC02AAC07 /* gtest */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */, + 40C848F9101A209C0083642A /* gtest-static */, + 40C8490A101A217E0083642A /* gtest_main-static */, + 40899F420FFA7184000B29AE /* gtest_unittest-framework */, + 40C8497A101A36850083642A /* gtest_unittest-static */, + 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */, + 40C84989101A36A60083642A /* sample1_unittest-static */, + 3B238F5F0E828B5400846E11 /* Check */, + 40C44ADC0E3798F4008FCC51 /* Version Info */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 404884500E2F799B00CF7658 /* README in Resources */, + 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */, + 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */, + 404884AE0E2F7CD900CF7658 /* LICENSE in Resources */, + 40C84978101A36540083642A /* libgtest_main.a in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B238F5E0E828B5400846E11 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/bin/bash Scripts/runtests.sh"; + }; + 40C44ADB0E3798F4008FCC51 /* Generate Version.h */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/Scripts/versiongenerate.py", + "$(SRCROOT)/../configure.ac", + ); + name = "Generate Version.h"; + outputPaths = ( + "$(PROJECT_TEMP_DIR)/Version.h", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/usr/bin/python Scripts/versiongenerate.py ../ $PROJECT_TEMP_DIR"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 40899F400FFA7184000B29AE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4089A0100FFACEFC000B29AE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */, + 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C848F7101A209C0083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C848FF101A21150083642A /* gtest-all.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84908101A217E0083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84915101A21DF0083642A /* gtest_main.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C8497F101A36850083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84980101A36850083642A /* gtest_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C8498E101A36A60083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C8498F101A36A60083642A /* sample1.cc in Sources */, + 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C10486CC7A007CD1D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 40899F9D0FFA740F000B29AE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40899F420FFA7184000B29AE /* gtest_unittest-framework */; + targetProxy = 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */; + }; + 4089A0980FFAD34A000B29AE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */; + targetProxy = 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */; + }; + 408BEC101046CFE900DEF522 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */; + }; + 40C44AE60E379922008FCC51 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C44ADC0E3798F4008FCC51 /* Version Info */; + targetProxy = 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */; + }; + 40C8497B101A36850083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 40C8497C101A36850083642A /* PBXContainerItemProxy */; + }; + 40C8497D101A36850083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8497E101A36850083642A /* PBXContainerItemProxy */; + }; + 40C8498A101A36A60083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 40C8498B101A36A60083642A /* PBXContainerItemProxy */; + }; + 40C8498C101A36A60083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8498D101A36A60083642A /* PBXContainerItemProxy */; + }; + 40C8499C101A36DC0083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8499B101A36DC0083642A /* PBXContainerItemProxy */; + }; + 40C8499E101A36E50083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; + targetProxy = 40C8499D101A36E50083642A /* PBXContainerItemProxy */; + }; + 40C849A0101A36F10083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; + targetProxy = 40C8499F101A36F10083642A /* PBXContainerItemProxy */; + }; + 40C849F7101A43440083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8497A101A36850083642A /* gtest_unittest-static */; + targetProxy = 40C849F6101A43440083642A /* PBXContainerItemProxy */; + }; + 40C849F9101A43490083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C84989101A36A60083642A /* sample1_unittest-static */; + targetProxy = 40C849F8101A43490083642A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 3B238F600E828B5400846E11 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + PRODUCT_NAME = Check; + }; + name = Debug; + }; + 3B238F610E828B5400846E11 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PRODUCT_NAME = Check; + ZERO_LINK = NO; + }; + name = Release; + }; + 40899F450FFA7185000B29AE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = "gtest_unittest-framework"; + }; + name = Debug; + }; + 40899F460FFA7185000B29AE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = "gtest_unittest-framework"; + }; + name = Release; + }; + 4089A0150FFACEFD000B29AE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "sample1_unittest-framework"; + }; + name = Debug; + }; + 4089A0160FFACEFD000B29AE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "sample1_unittest-framework"; + }; + name = Release; + }; + 40C44ADF0E3798F4008FCC51 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = gtest; + TARGET_NAME = gtest; + }; + name = Debug; + }; + 40C44AE00E3798F4008FCC51 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = gtest; + TARGET_NAME = gtest; + }; + name = Release; + }; + 40C848FB101A209D0083642A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest; + }; + name = Debug; + }; + 40C848FC101A209D0083642A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest; + }; + name = Release; + }; + 40C8490E101A217F0083642A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest_main; + }; + name = Debug; + }; + 40C8490F101A217F0083642A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest_main; + }; + name = Release; + }; + 40C84985101A36850083642A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = gtest_unittest; + }; + name = Debug; + }; + 40C84986101A36850083642A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = gtest_unittest; + }; + name = Release; + }; + 40C84995101A36A60083642A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "sample1_unittest-static"; + }; + name = Debug; + }; + 40C84996101A36A60083642A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "sample1_unittest-static"; + }; + name = Release; + }; + 4FADC24308B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + INFOPLIST_FILE = Resources/Info.plist; + INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; + INFOPLIST_PREPROCESS = YES; + PRODUCT_NAME = gtest; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 4FADC24408B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + INFOPLIST_FILE = Resources/Info.plist; + INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; + INFOPLIST_PREPROCESS = YES; + PRODUCT_NAME = gtest; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + 4FADC24708B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 4FADC24808B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */; + buildSettings = { + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3B238F600E828B5400846E11 /* Debug */, + 3B238F610E828B5400846E11 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40899F450FFA7185000B29AE /* Debug */, + 40899F460FFA7185000B29AE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4089A0150FFACEFD000B29AE /* Debug */, + 4089A0160FFACEFD000B29AE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C44ADF0E3798F4008FCC51 /* Debug */, + 40C44AE00E3798F4008FCC51 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C848FB101A209D0083642A /* Debug */, + 40C848FC101A209D0083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C8490E101A217F0083642A /* Debug */, + 40C8490F101A217F0083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C84985101A36850083642A /* Debug */, + 40C84986101A36850083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C84995101A36A60083642A /* Debug */, + 40C84996101A36A60083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24308B4156D00ABE55E /* Debug */, + 4FADC24408B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24708B4156D00ABE55E /* Debug */, + 4FADC24808B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/install-sh b/cpp/thirdparty/protobuf-2.5.0/install-sh new file mode 100755 index 0000000..a9244eb --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-01-19.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for `test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/cpp/thirdparty/protobuf-2.5.0/java/README.txt b/cpp/thirdparty/protobuf-2.5.0/java/README.txt new file mode 100644 index 0000000..3ed06a1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/README.txt @@ -0,0 +1,96 @@ +Protocol Buffers - Google's data interchange format +Copyright 2008 Google Inc. + +This directory contains the Java Protocol Buffers runtime library. + +Installation - With Maven +========================= + +The Protocol Buffers build is managed using Maven. If you would +rather build without Maven, see below. + +1) Install Apache Maven if you don't have it: + + http://maven.apache.org/ + +2) Build the C++ code, or obtain a binary distribution of protoc. If + you install a binary distribution, make sure that it is the same + version as this package. If in doubt, run: + + $ protoc --version + + You will need to place the protoc executable in ../src. (If you + built it yourself, it should already be there.) + +3) Run the tests: + + $ mvn test + + If some tests fail, this library may not work correctly on your + system. Continue at your own risk. + +4) Install the library into your Maven repository: + + $ mvn install + +5) If you do not use Maven to manage your own build, you can build a + .jar file to use: + + $ mvn package + + The .jar will be placed in the "target" directory. + +Installation - 'Lite' Version - With Maven +========================================== + +Building the 'lite' version of the Java Protocol Buffers library is +the same as building the full version, except that all commands are +run using the 'lite' profile. (see +http://maven.apache.org/guides/introduction/introduction-to-profiles.html) + +E.g. to install the lite version of the jar, you would run: + + $ mvn install -P lite + +The resulting artifact has the 'lite' classifier. To reference it +for dependency resolution, you would specify it as: + + + com.google.protobuf + protobuf-java + ${version} + lite + + +Installation - Without Maven +============================ + +If you would rather not install Maven to build the library, you may +follow these instructions instead. Note that these instructions skip +running unit tests. + +1) Build the C++ code, or obtain a binary distribution of protoc. If + you install a binary distribution, make sure that it is the same + version as this package. If in doubt, run: + + $ protoc --version + + If you built the C++ code without installing, the compiler binary + should be located in ../src. + +2) Invoke protoc to build DescriptorProtos.java: + + $ protoc --java_out=src/main/java -I../src \ + ../src/google/protobuf/descriptor.proto + +3) Compile the code in src/main/java using whatever means you prefer. + +4) Install the classes wherever you prefer. + +Usage +===== + +The complete documentation for Protocol Buffers is available via the +web at: + + http://code.google.com/apis/protocolbuffers/ diff --git a/cpp/thirdparty/protobuf-2.5.0/java/pom.xml b/cpp/thirdparty/protobuf-2.5.0/java/pom.xml new file mode 100644 index 0000000..a3746fa --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/pom.xml @@ -0,0 +1,205 @@ + + + 4.0.0 + + com.google + google + 1 + + com.google.protobuf + protobuf-java + 2.5.0 + bundle + Protocol Buffer Java API + + Protocol Buffers are a way of encoding structured data in an efficient yet + extensible format. + + 2008 + http://code.google.com/p/protobuf + + + New BSD license + http://www.opensource.org/licenses/bsd-license.php + repo + + + + http://code.google.com/p/protobuf/source/browse + + scm:svn:http://protobuf.googlecode.com/svn/trunk/ + + + + + junit + junit + 4.4 + test + + + org.easymock + easymock + 2.2 + test + + + org.easymock + easymockclassextension + 2.2.1 + test + + + + + + maven-compiler-plugin + + 1.5 + 1.5 + + + + maven-surefire-plugin + + + **/*Test.java + + + + + maven-antrun-plugin + + + generate-sources + generate-sources + + + + + + + + + + target/generated-sources + + + run + + + + generate-test-sources + generate-test-sources + + + + + + + + + + + + + + + + + + + + + + + + + + + + + target/generated-test-sources + + + run + + + + + + org.apache.felix + maven-bundle-plugin + true + + + * + + + + + + + + lite + + + + maven-compiler-plugin + + + **/AbstractMessageLite.java + **/ByteString.java + **/CodedInputStream.java + **/CodedOutputStream.java + **/ExtensionRegistryLite.java + **/FieldSet.java + **/GeneratedMessageLite.java + **/Internal.java + **/InvalidProtocolBufferException.java + **/LazyStringArrayList.java + **/LazyStringList.java + **/MessageLite.java + **/MessageLiteOrBuilder.java + **/SmallSortedMap.java + **/UninitializedMessageException.java + **/UnmodifiableLazyStringList.java + **/WireFormat.java + **/Parser.java + **/AbstractParser.java + **/BoundedByteString.java + **/LiteralByteString.java + **/RopeByteString.java + **/Utf8.java + **/LazyField.java + + + **/LiteTest.java + **/*Lite.java + + + + + maven-surefire-plugin + + + **/LiteTest.java + + + + + maven-jar-plugin + + lite + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractMessage.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractMessage.java new file mode 100644 index 0000000..f4d115d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractMessage.java @@ -0,0 +1,930 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.GeneratedMessage.ExtendableBuilder; +import com.google.protobuf.Internal.EnumLite; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * A partial implementation of the {@link Message} interface which implements + * as many methods of that interface as possible in terms of other methods. + * + * @author kenton@google.com Kenton Varda + */ +public abstract class AbstractMessage extends AbstractMessageLite + implements Message { + @SuppressWarnings("unchecked") + public boolean isInitialized() { + // Check that all required fields are present. + for (final FieldDescriptor field : getDescriptorForType().getFields()) { + if (field.isRequired()) { + if (!hasField(field)) { + return false; + } + } + } + + // Check that embedded messages are initialized. + for (final Map.Entry entry : + getAllFields().entrySet()) { + final FieldDescriptor field = entry.getKey(); + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (field.isRepeated()) { + for (final Message element : (List) entry.getValue()) { + if (!element.isInitialized()) { + return false; + } + } + } else { + if (!((Message) entry.getValue()).isInitialized()) { + return false; + } + } + } + } + + return true; + } + + public List findInitializationErrors() { + return Builder.findMissingFields(this); + } + + public String getInitializationErrorString() { + return delimitWithCommas(findInitializationErrors()); + } + + private static String delimitWithCommas(List parts) { + StringBuilder result = new StringBuilder(); + for (String part : parts) { + if (result.length() > 0) { + result.append(", "); + } + result.append(part); + } + return result.toString(); + } + + @Override + public final String toString() { + return TextFormat.printToString(this); + } + + public void writeTo(final CodedOutputStream output) throws IOException { + final boolean isMessageSet = + getDescriptorForType().getOptions().getMessageSetWireFormat(); + + for (final Map.Entry entry : + getAllFields().entrySet()) { + final FieldDescriptor field = entry.getKey(); + final Object value = entry.getValue(); + if (isMessageSet && field.isExtension() && + field.getType() == FieldDescriptor.Type.MESSAGE && + !field.isRepeated()) { + output.writeMessageSetExtension(field.getNumber(), (Message) value); + } else { + FieldSet.writeField(field, value, output); + } + } + + final UnknownFieldSet unknownFields = getUnknownFields(); + if (isMessageSet) { + unknownFields.writeAsMessageSetTo(output); + } else { + unknownFields.writeTo(output); + } + } + + private int memoizedSize = -1; + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) { + return size; + } + + size = 0; + final boolean isMessageSet = + getDescriptorForType().getOptions().getMessageSetWireFormat(); + + for (final Map.Entry entry : + getAllFields().entrySet()) { + final FieldDescriptor field = entry.getKey(); + final Object value = entry.getValue(); + if (isMessageSet && field.isExtension() && + field.getType() == FieldDescriptor.Type.MESSAGE && + !field.isRepeated()) { + size += CodedOutputStream.computeMessageSetExtensionSize( + field.getNumber(), (Message) value); + } else { + size += FieldSet.computeFieldSize(field, value); + } + } + + final UnknownFieldSet unknownFields = getUnknownFields(); + if (isMessageSet) { + size += unknownFields.getSerializedSizeAsMessageSet(); + } else { + size += unknownFields.getSerializedSize(); + } + + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object other) { + if (other == this) { + return true; + } + if (!(other instanceof Message)) { + return false; + } + final Message otherMessage = (Message) other; + if (getDescriptorForType() != otherMessage.getDescriptorForType()) { + return false; + } + return getAllFields().equals(otherMessage.getAllFields()) && + getUnknownFields().equals(otherMessage.getUnknownFields()); + } + + @Override + public int hashCode() { + int hash = 41; + hash = (19 * hash) + getDescriptorForType().hashCode(); + hash = hashFields(hash, getAllFields()); + hash = (29 * hash) + getUnknownFields().hashCode(); + return hash; + } + + /** Get a hash code for given fields and values, using the given seed. */ + @SuppressWarnings("unchecked") + protected int hashFields(int hash, Map map) { + for (Map.Entry entry : map.entrySet()) { + FieldDescriptor field = entry.getKey(); + Object value = entry.getValue(); + hash = (37 * hash) + field.getNumber(); + if (field.getType() != FieldDescriptor.Type.ENUM){ + hash = (53 * hash) + value.hashCode(); + } else if (field.isRepeated()) { + List list = (List) value; + hash = (53 * hash) + hashEnumList(list); + } else { + hash = (53 * hash) + hashEnum((EnumLite) value); + } + } + return hash; + } + + /** + * Helper method for implementing {@link Message#hashCode()}. + * @see Boolean#hashCode() + */ + protected static int hashLong(long n) { + return (int) (n ^ (n >>> 32)); + } + + /** + * Helper method for implementing {@link Message#hashCode()}. + * @see Boolean#hashCode() + */ + protected static int hashBoolean(boolean b) { + return b ? 1231 : 1237; + } + + /** + * Package private helper method for AbstractParser to create + * UninitializedMessageException with missing field information. + */ + @Override + UninitializedMessageException newUninitializedMessageException() { + return Builder.newUninitializedMessageException(this); + } + + /** + * Helper method for implementing {@link Message#hashCode()}. + *

+ * This is needed because {@link java.lang.Enum#hashCode()} is final, but we + * need to use the field number as the hash code to ensure compatibility + * between statically and dynamically generated enum objects. + */ + protected static int hashEnum(EnumLite e) { + return e.getNumber(); + } + + /** Helper method for implementing {@link Message#hashCode()}. */ + protected static int hashEnumList(List list) { + int hash = 1; + for (EnumLite e : list) { + hash = 31 * hash + hashEnum(e); + } + return hash; + } + + // ================================================================= + + /** + * A partial implementation of the {@link Message.Builder} interface which + * implements as many methods of that interface as possible in terms of + * other methods. + */ + @SuppressWarnings("unchecked") + public static abstract class Builder + extends AbstractMessageLite.Builder + implements Message.Builder { + // The compiler produces an error if this is not declared explicitly. + @Override + public abstract BuilderType clone(); + + public BuilderType clear() { + for (final Map.Entry entry : + getAllFields().entrySet()) { + clearField(entry.getKey()); + } + return (BuilderType) this; + } + + public List findInitializationErrors() { + return findMissingFields(this); + } + + public String getInitializationErrorString() { + return delimitWithCommas(findInitializationErrors()); + } + + public BuilderType mergeFrom(final Message other) { + if (other.getDescriptorForType() != getDescriptorForType()) { + throw new IllegalArgumentException( + "mergeFrom(Message) can only merge messages of the same type."); + } + + // Note: We don't attempt to verify that other's fields have valid + // types. Doing so would be a losing battle. We'd have to verify + // all sub-messages as well, and we'd have to make copies of all of + // them to insure that they don't change after verification (since + // the Message interface itself cannot enforce immutability of + // implementations). + // TODO(kenton): Provide a function somewhere called makeDeepCopy() + // which allows people to make secure deep copies of messages. + + for (final Map.Entry entry : + other.getAllFields().entrySet()) { + final FieldDescriptor field = entry.getKey(); + if (field.isRepeated()) { + for (final Object element : (List)entry.getValue()) { + addRepeatedField(field, element); + } + } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + final Message existingValue = (Message)getField(field); + if (existingValue == existingValue.getDefaultInstanceForType()) { + setField(field, entry.getValue()); + } else { + setField(field, + existingValue.newBuilderForType() + .mergeFrom(existingValue) + .mergeFrom((Message)entry.getValue()) + .build()); + } + } else { + setField(field, entry.getValue()); + } + } + + mergeUnknownFields(other.getUnknownFields()); + + return (BuilderType) this; + } + + @Override + public BuilderType mergeFrom(final CodedInputStream input) + throws IOException { + return mergeFrom(input, ExtensionRegistry.getEmptyRegistry()); + } + + @Override + public BuilderType mergeFrom( + final CodedInputStream input, + final ExtensionRegistryLite extensionRegistry) + throws IOException { + final UnknownFieldSet.Builder unknownFields = + UnknownFieldSet.newBuilder(getUnknownFields()); + while (true) { + final int tag = input.readTag(); + if (tag == 0) { + break; + } + + if (!mergeFieldFrom(input, unknownFields, extensionRegistry, + getDescriptorForType(), this, null, tag)) { + // end group tag + break; + } + } + setUnknownFields(unknownFields.build()); + return (BuilderType) this; + } + + /** helper method to handle {@code builder} and {@code extensions}. */ + private static void addRepeatedField( + Message.Builder builder, + FieldSet extensions, + FieldDescriptor field, + Object value) { + if (builder != null) { + builder.addRepeatedField(field, value); + } else { + extensions.addRepeatedField(field, value); + } + } + + /** helper method to handle {@code builder} and {@code extensions}. */ + private static void setField( + Message.Builder builder, + FieldSet extensions, + FieldDescriptor field, + Object value) { + if (builder != null) { + builder.setField(field, value); + } else { + extensions.setField(field, value); + } + } + + /** helper method to handle {@code builder} and {@code extensions}. */ + private static boolean hasOriginalMessage( + Message.Builder builder, + FieldSet extensions, + FieldDescriptor field) { + if (builder != null) { + return builder.hasField(field); + } else { + return extensions.hasField(field); + } + } + + /** helper method to handle {@code builder} and {@code extensions}. */ + private static Message getOriginalMessage( + Message.Builder builder, + FieldSet extensions, + FieldDescriptor field) { + if (builder != null) { + return (Message) builder.getField(field); + } else { + return (Message) extensions.getField(field); + } + } + + /** helper method to handle {@code builder} and {@code extensions}. */ + private static void mergeOriginalMessage( + Message.Builder builder, + FieldSet extensions, + FieldDescriptor field, + Message.Builder subBuilder) { + Message originalMessage = getOriginalMessage(builder, extensions, field); + if (originalMessage != null) { + subBuilder.mergeFrom(originalMessage); + } + } + + /** + * Like {@link #mergeFrom(CodedInputStream, ExtensionRegistryLite)}, but + * parses a single field. + * + * When {@code builder} is not null, the method will parse and merge the + * field into {@code builder}. Otherwise, it will try to parse the field + * into {@code extensions}, when it's called by the parsing constructor in + * generated classes. + * + * Package-private because it is used by GeneratedMessage.ExtendableMessage. + * @param tag The tag, which should have already been read. + * @return {@code true} unless the tag is an end-group tag. + */ + static boolean mergeFieldFrom( + CodedInputStream input, + UnknownFieldSet.Builder unknownFields, + ExtensionRegistryLite extensionRegistry, + Descriptor type, + Message.Builder builder, + FieldSet extensions, + int tag) throws IOException { + if (type.getOptions().getMessageSetWireFormat() && + tag == WireFormat.MESSAGE_SET_ITEM_TAG) { + mergeMessageSetExtensionFromCodedStream( + input, unknownFields, extensionRegistry, type, builder, extensions); + return true; + } + + final int wireType = WireFormat.getTagWireType(tag); + final int fieldNumber = WireFormat.getTagFieldNumber(tag); + + final FieldDescriptor field; + Message defaultInstance = null; + + if (type.isExtensionNumber(fieldNumber)) { + // extensionRegistry may be either ExtensionRegistry or + // ExtensionRegistryLite. Since the type we are parsing is a full + // message, only a full ExtensionRegistry could possibly contain + // extensions of it. Otherwise we will treat the registry as if it + // were empty. + if (extensionRegistry instanceof ExtensionRegistry) { + final ExtensionRegistry.ExtensionInfo extension = + ((ExtensionRegistry) extensionRegistry) + .findExtensionByNumber(type, fieldNumber); + if (extension == null) { + field = null; + } else { + field = extension.descriptor; + defaultInstance = extension.defaultInstance; + if (defaultInstance == null && + field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + throw new IllegalStateException( + "Message-typed extension lacked default instance: " + + field.getFullName()); + } + } + } else { + field = null; + } + } else if (builder != null) { + field = type.findFieldByNumber(fieldNumber); + } else { + field = null; + } + + boolean unknown = false; + boolean packed = false; + if (field == null) { + unknown = true; // Unknown field. + } else if (wireType == FieldSet.getWireFormatForFieldType( + field.getLiteType(), + false /* isPacked */)) { + packed = false; + } else if (field.isPackable() && + wireType == FieldSet.getWireFormatForFieldType( + field.getLiteType(), + true /* isPacked */)) { + packed = true; + } else { + unknown = true; // Unknown wire type. + } + + if (unknown) { // Unknown field or wrong wire type. Skip. + return unknownFields.mergeFieldFrom(tag, input); + } + + if (packed) { + final int length = input.readRawVarint32(); + final int limit = input.pushLimit(length); + if (field.getLiteType() == WireFormat.FieldType.ENUM) { + while (input.getBytesUntilLimit() > 0) { + final int rawValue = input.readEnum(); + final Object value = field.getEnumType().findValueByNumber(rawValue); + if (value == null) { + // If the number isn't recognized as a valid value for this + // enum, drop it (don't even add it to unknownFields). + return true; + } + addRepeatedField(builder, extensions, field, value); + } + } else { + while (input.getBytesUntilLimit() > 0) { + final Object value = + FieldSet.readPrimitiveField(input, field.getLiteType()); + addRepeatedField(builder, extensions, field, value); + } + } + input.popLimit(limit); + } else { + final Object value; + switch (field.getType()) { + case GROUP: { + final Message.Builder subBuilder; + if (defaultInstance != null) { + subBuilder = defaultInstance.newBuilderForType(); + } else { + subBuilder = builder.newBuilderForField(field); + } + if (!field.isRepeated()) { + mergeOriginalMessage(builder, extensions, field, subBuilder); + } + input.readGroup(field.getNumber(), subBuilder, extensionRegistry); + value = subBuilder.buildPartial(); + break; + } + case MESSAGE: { + final Message.Builder subBuilder; + if (defaultInstance != null) { + subBuilder = defaultInstance.newBuilderForType(); + } else { + subBuilder = builder.newBuilderForField(field); + } + if (!field.isRepeated()) { + mergeOriginalMessage(builder, extensions, field, subBuilder); + } + input.readMessage(subBuilder, extensionRegistry); + value = subBuilder.buildPartial(); + break; + } + case ENUM: + final int rawValue = input.readEnum(); + value = field.getEnumType().findValueByNumber(rawValue); + // If the number isn't recognized as a valid value for this enum, + // drop it. + if (value == null) { + unknownFields.mergeVarintField(fieldNumber, rawValue); + return true; + } + break; + default: + value = FieldSet.readPrimitiveField(input, field.getLiteType()); + break; + } + + if (field.isRepeated()) { + addRepeatedField(builder, extensions, field, value); + } else { + setField(builder, extensions, field, value); + } + } + + return true; + } + + /** + * Called by {@code #mergeFieldFrom()} to parse a MessageSet extension. + * If {@code builder} is not null, this method will merge MessageSet into + * the builder. Otherwise, it will merge the MessageSet into {@code + * extensions}. + */ + private static void mergeMessageSetExtensionFromCodedStream( + CodedInputStream input, + UnknownFieldSet.Builder unknownFields, + ExtensionRegistryLite extensionRegistry, + Descriptor type, + Message.Builder builder, + FieldSet extensions) throws IOException { + + // The wire format for MessageSet is: + // message MessageSet { + // repeated group Item = 1 { + // required int32 typeId = 2; + // required bytes message = 3; + // } + // } + // "typeId" is the extension's field number. The extension can only be + // a message type, where "message" contains the encoded bytes of that + // message. + // + // In practice, we will probably never see a MessageSet item in which + // the message appears before the type ID, or where either field does not + // appear exactly once. However, in theory such cases are valid, so we + // should be prepared to accept them. + + int typeId = 0; + ByteString rawBytes = null; // If we encounter "message" before "typeId" + ExtensionRegistry.ExtensionInfo extension = null; + + // Read bytes from input, if we get it's type first then parse it eagerly, + // otherwise we store the raw bytes in a local variable. + while (true) { + final int tag = input.readTag(); + if (tag == 0) { + break; + } + + if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) { + typeId = input.readUInt32(); + if (typeId != 0) { + // extensionRegistry may be either ExtensionRegistry or + // ExtensionRegistryLite. Since the type we are parsing is a full + // message, only a full ExtensionRegistry could possibly contain + // extensions of it. Otherwise we will treat the registry as if it + // were empty. + if (extensionRegistry instanceof ExtensionRegistry) { + extension = ((ExtensionRegistry) extensionRegistry) + .findExtensionByNumber(type, typeId); + } + } + + } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) { + if (typeId != 0) { + if (extension != null && ExtensionRegistryLite.isEagerlyParseMessageSets()) { + // We already know the type, so we can parse directly from the + // input with no copying. Hooray! + eagerlyMergeMessageSetExtension( + input, extension, extensionRegistry, builder, extensions); + rawBytes = null; + continue; + } + } + // We haven't seen a type ID yet or we want parse message lazily. + rawBytes = input.readBytes(); + + } else { // Unknown tag. Skip it. + if (!input.skipField(tag)) { + break; // End of group + } + } + } + input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG); + + // Process the raw bytes. + if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID. + if (extension != null) { // We known the type + mergeMessageSetExtensionFromBytes( + rawBytes, extension, extensionRegistry, builder, extensions); + } else { // We don't know how to parse this. Ignore it. + if (rawBytes != null) { + unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder() + .addLengthDelimited(rawBytes).build()); + } + } + } + } + + private static void eagerlyMergeMessageSetExtension( + CodedInputStream input, + ExtensionRegistry.ExtensionInfo extension, + ExtensionRegistryLite extensionRegistry, + Message.Builder builder, + FieldSet extensions) throws IOException { + + FieldDescriptor field = extension.descriptor; + Message value = null; + if (hasOriginalMessage(builder, extensions, field)) { + Message originalMessage = + getOriginalMessage(builder, extensions, field); + Message.Builder subBuilder = originalMessage.toBuilder(); + input.readMessage(subBuilder, extensionRegistry); + value = subBuilder.buildPartial(); + } else { + value = input.readMessage(extension.defaultInstance.getParserForType(), + extensionRegistry); + } + + if (builder != null) { + builder.setField(field, value); + } else { + extensions.setField(field, value); + } + } + + private static void mergeMessageSetExtensionFromBytes( + ByteString rawBytes, + ExtensionRegistry.ExtensionInfo extension, + ExtensionRegistryLite extensionRegistry, + Message.Builder builder, + FieldSet extensions) throws IOException { + + FieldDescriptor field = extension.descriptor; + boolean hasOriginalValue = hasOriginalMessage(builder, extensions, field); + + if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) { + // If the field already exists, we just parse the field. + Message value = null; + if (hasOriginalValue) { + Message originalMessage = + getOriginalMessage(builder, extensions, field); + Message.Builder subBuilder= originalMessage.toBuilder(); + subBuilder.mergeFrom(rawBytes, extensionRegistry); + value = subBuilder.buildPartial(); + } else { + value = extension.defaultInstance.getParserForType() + .parsePartialFrom(rawBytes, extensionRegistry); + } + setField(builder, extensions, field, value); + } else { + // Use LazyField to load MessageSet lazily. + LazyField lazyField = new LazyField( + extension.defaultInstance, extensionRegistry, rawBytes); + if (builder != null) { + // TODO(xiangl): it looks like this method can only be invoked by + // ExtendableBuilder, but I'm not sure. So I double check the type of + // builder here. It may be useless and need more investigation. + if (builder instanceof ExtendableBuilder) { + builder.setField(field, lazyField); + } else { + builder.setField(field, lazyField.getValue()); + } + } else { + extensions.setField(field, lazyField); + } + } + } + + public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) { + setUnknownFields( + UnknownFieldSet.newBuilder(getUnknownFields()) + .mergeFrom(unknownFields) + .build()); + return (BuilderType) this; + } + + public Message.Builder getFieldBuilder(final FieldDescriptor field) { + throw new UnsupportedOperationException( + "getFieldBuilder() called on an unsupported message type."); + } + + /** + * Construct an UninitializedMessageException reporting missing fields in + * the given message. + */ + protected static UninitializedMessageException + newUninitializedMessageException(Message message) { + return new UninitializedMessageException(findMissingFields(message)); + } + + /** + * Populates {@code this.missingFields} with the full "path" of each + * missing required field in the given message. + */ + private static List findMissingFields( + final MessageOrBuilder message) { + final List results = new ArrayList(); + findMissingFields(message, "", results); + return results; + } + + /** Recursive helper implementing {@link #findMissingFields(Message)}. */ + private static void findMissingFields(final MessageOrBuilder message, + final String prefix, + final List results) { + for (final FieldDescriptor field : + message.getDescriptorForType().getFields()) { + if (field.isRequired() && !message.hasField(field)) { + results.add(prefix + field.getName()); + } + } + + for (final Map.Entry entry : + message.getAllFields().entrySet()) { + final FieldDescriptor field = entry.getKey(); + final Object value = entry.getValue(); + + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (field.isRepeated()) { + int i = 0; + for (final Object element : (List) value) { + findMissingFields((MessageOrBuilder) element, + subMessagePrefix(prefix, field, i++), + results); + } + } else { + if (message.hasField(field)) { + findMissingFields((MessageOrBuilder) value, + subMessagePrefix(prefix, field, -1), + results); + } + } + } + } + } + + private static String subMessagePrefix(final String prefix, + final FieldDescriptor field, + final int index) { + final StringBuilder result = new StringBuilder(prefix); + if (field.isExtension()) { + result.append('(') + .append(field.getFullName()) + .append(')'); + } else { + result.append(field.getName()); + } + if (index != -1) { + result.append('[') + .append(index) + .append(']'); + } + result.append('.'); + return result.toString(); + } + + // =============================================================== + // The following definitions seem to be required in order to make javac + // not produce weird errors like: + // + // java/com/google/protobuf/DynamicMessage.java:203: types + // com.google.protobuf.AbstractMessage.Builder< + // com.google.protobuf.DynamicMessage.Builder> and + // com.google.protobuf.AbstractMessage.Builder< + // com.google.protobuf.DynamicMessage.Builder> are incompatible; both + // define mergeFrom(com.google.protobuf.ByteString), but with unrelated + // return types. + // + // Strangely, these lines are only needed if javac is invoked separately + // on AbstractMessage.java and AbstractMessageLite.java. If javac is + // invoked on both simultaneously, it works. (Or maybe the important + // point is whether or not DynamicMessage.java is compiled together with + // AbstractMessageLite.java -- not sure.) I suspect this is a compiler + // bug. + + @Override + public BuilderType mergeFrom(final ByteString data) + throws InvalidProtocolBufferException { + return super.mergeFrom(data); + } + + @Override + public BuilderType mergeFrom( + final ByteString data, + final ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return super.mergeFrom(data, extensionRegistry); + } + + @Override + public BuilderType mergeFrom(final byte[] data) + throws InvalidProtocolBufferException { + return super.mergeFrom(data); + } + + @Override + public BuilderType mergeFrom( + final byte[] data, final int off, final int len) + throws InvalidProtocolBufferException { + return super.mergeFrom(data, off, len); + } + + @Override + public BuilderType mergeFrom( + final byte[] data, + final ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return super.mergeFrom(data, extensionRegistry); + } + + @Override + public BuilderType mergeFrom( + final byte[] data, final int off, final int len, + final ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return super.mergeFrom(data, off, len, extensionRegistry); + } + + @Override + public BuilderType mergeFrom(final InputStream input) + throws IOException { + return super.mergeFrom(input); + } + + @Override + public BuilderType mergeFrom( + final InputStream input, + final ExtensionRegistryLite extensionRegistry) + throws IOException { + return super.mergeFrom(input, extensionRegistry); + } + + @Override + public boolean mergeDelimitedFrom(final InputStream input) + throws IOException { + return super.mergeDelimitedFrom(input); + } + + @Override + public boolean mergeDelimitedFrom( + final InputStream input, + final ExtensionRegistryLite extensionRegistry) + throws IOException { + return super.mergeDelimitedFrom(input, extensionRegistry); + } + + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractMessageLite.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractMessageLite.java new file mode 100644 index 0000000..9926f3d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractMessageLite.java @@ -0,0 +1,343 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.FilterInputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collection; + +/** + * A partial implementation of the {@link MessageLite} interface which + * implements as many methods of that interface as possible in terms of other + * methods. + * + * @author kenton@google.com Kenton Varda + */ +public abstract class AbstractMessageLite implements MessageLite { + public ByteString toByteString() { + try { + final ByteString.CodedBuilder out = + ByteString.newCodedBuilder(getSerializedSize()); + writeTo(out.getCodedOutput()); + return out.build(); + } catch (IOException e) { + throw new RuntimeException( + "Serializing to a ByteString threw an IOException (should " + + "never happen).", e); + } + } + + public byte[] toByteArray() { + try { + final byte[] result = new byte[getSerializedSize()]; + final CodedOutputStream output = CodedOutputStream.newInstance(result); + writeTo(output); + output.checkNoSpaceLeft(); + return result; + } catch (IOException e) { + throw new RuntimeException( + "Serializing to a byte array threw an IOException " + + "(should never happen).", e); + } + } + + public void writeTo(final OutputStream output) throws IOException { + final int bufferSize = + CodedOutputStream.computePreferredBufferSize(getSerializedSize()); + final CodedOutputStream codedOutput = + CodedOutputStream.newInstance(output, bufferSize); + writeTo(codedOutput); + codedOutput.flush(); + } + + public void writeDelimitedTo(final OutputStream output) throws IOException { + final int serialized = getSerializedSize(); + final int bufferSize = CodedOutputStream.computePreferredBufferSize( + CodedOutputStream.computeRawVarint32Size(serialized) + serialized); + final CodedOutputStream codedOutput = + CodedOutputStream.newInstance(output, bufferSize); + codedOutput.writeRawVarint32(serialized); + writeTo(codedOutput); + codedOutput.flush(); + } + + /** + * Package private helper method for AbstractParser to create + * UninitializedMessageException. + */ + UninitializedMessageException newUninitializedMessageException() { + return new UninitializedMessageException(this); + } + + /** + * A partial implementation of the {@link Message.Builder} interface which + * implements as many methods of that interface as possible in terms of + * other methods. + */ + @SuppressWarnings("unchecked") + public static abstract class Builder + implements MessageLite.Builder { + // The compiler produces an error if this is not declared explicitly. + @Override + public abstract BuilderType clone(); + + public BuilderType mergeFrom(final CodedInputStream input) + throws IOException { + return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry()); + } + + // Re-defined here for return type covariance. + public abstract BuilderType mergeFrom( + final CodedInputStream input, + final ExtensionRegistryLite extensionRegistry) + throws IOException; + + public BuilderType mergeFrom(final ByteString data) + throws InvalidProtocolBufferException { + try { + final CodedInputStream input = data.newCodedInput(); + mergeFrom(input); + input.checkLastTagWas(0); + return (BuilderType) this; + } catch (InvalidProtocolBufferException e) { + throw e; + } catch (IOException e) { + throw new RuntimeException( + "Reading from a ByteString threw an IOException (should " + + "never happen).", e); + } + } + + public BuilderType mergeFrom( + final ByteString data, + final ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + try { + final CodedInputStream input = data.newCodedInput(); + mergeFrom(input, extensionRegistry); + input.checkLastTagWas(0); + return (BuilderType) this; + } catch (InvalidProtocolBufferException e) { + throw e; + } catch (IOException e) { + throw new RuntimeException( + "Reading from a ByteString threw an IOException (should " + + "never happen).", e); + } + } + + public BuilderType mergeFrom(final byte[] data) + throws InvalidProtocolBufferException { + return mergeFrom(data, 0, data.length); + } + + public BuilderType mergeFrom(final byte[] data, final int off, + final int len) + throws InvalidProtocolBufferException { + try { + final CodedInputStream input = + CodedInputStream.newInstance(data, off, len); + mergeFrom(input); + input.checkLastTagWas(0); + return (BuilderType) this; + } catch (InvalidProtocolBufferException e) { + throw e; + } catch (IOException e) { + throw new RuntimeException( + "Reading from a byte array threw an IOException (should " + + "never happen).", e); + } + } + + public BuilderType mergeFrom( + final byte[] data, + final ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return mergeFrom(data, 0, data.length, extensionRegistry); + } + + public BuilderType mergeFrom( + final byte[] data, final int off, final int len, + final ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + try { + final CodedInputStream input = + CodedInputStream.newInstance(data, off, len); + mergeFrom(input, extensionRegistry); + input.checkLastTagWas(0); + return (BuilderType) this; + } catch (InvalidProtocolBufferException e) { + throw e; + } catch (IOException e) { + throw new RuntimeException( + "Reading from a byte array threw an IOException (should " + + "never happen).", e); + } + } + + public BuilderType mergeFrom(final InputStream input) throws IOException { + final CodedInputStream codedInput = CodedInputStream.newInstance(input); + mergeFrom(codedInput); + codedInput.checkLastTagWas(0); + return (BuilderType) this; + } + + public BuilderType mergeFrom( + final InputStream input, + final ExtensionRegistryLite extensionRegistry) + throws IOException { + final CodedInputStream codedInput = CodedInputStream.newInstance(input); + mergeFrom(codedInput, extensionRegistry); + codedInput.checkLastTagWas(0); + return (BuilderType) this; + } + + /** + * An InputStream implementations which reads from some other InputStream + * but is limited to a particular number of bytes. Used by + * mergeDelimitedFrom(). This is intentionally package-private so that + * UnknownFieldSet can share it. + */ + static final class LimitedInputStream extends FilterInputStream { + private int limit; + + LimitedInputStream(InputStream in, int limit) { + super(in); + this.limit = limit; + } + + @Override + public int available() throws IOException { + return Math.min(super.available(), limit); + } + + @Override + public int read() throws IOException { + if (limit <= 0) { + return -1; + } + final int result = super.read(); + if (result >= 0) { + --limit; + } + return result; + } + + @Override + public int read(final byte[] b, final int off, int len) + throws IOException { + if (limit <= 0) { + return -1; + } + len = Math.min(len, limit); + final int result = super.read(b, off, len); + if (result >= 0) { + limit -= result; + } + return result; + } + + @Override + public long skip(final long n) throws IOException { + final long result = super.skip(Math.min(n, limit)); + if (result >= 0) { + limit -= result; + } + return result; + } + } + + public boolean mergeDelimitedFrom( + final InputStream input, + final ExtensionRegistryLite extensionRegistry) + throws IOException { + final int firstByte = input.read(); + if (firstByte == -1) { + return false; + } + final int size = CodedInputStream.readRawVarint32(firstByte, input); + final InputStream limitedInput = new LimitedInputStream(input, size); + mergeFrom(limitedInput, extensionRegistry); + return true; + } + + public boolean mergeDelimitedFrom(final InputStream input) + throws IOException { + return mergeDelimitedFrom(input, + ExtensionRegistryLite.getEmptyRegistry()); + } + + /** + * Construct an UninitializedMessageException reporting missing fields in + * the given message. + */ + protected static UninitializedMessageException + newUninitializedMessageException(MessageLite message) { + return new UninitializedMessageException(message); + } + + /** + * Adds the {@code values} to the {@code list}. This is a helper method + * used by generated code. Users should ignore it. + * + * @throws NullPointerException if any of the elements of {@code values} is + * null. + */ + protected static void addAll(final Iterable values, + final Collection list) { + if (values instanceof LazyStringList) { + // For StringOrByteStringLists, check the underlying elements to avoid + // forcing conversions of ByteStrings to Strings. + checkForNullValues(((LazyStringList) values).getUnderlyingElements()); + } else { + checkForNullValues(values); + } + if (values instanceof Collection) { + final Collection collection = (Collection) values; + list.addAll(collection); + } else { + for (final T value : values) { + list.add(value); + } + } + } + + private static void checkForNullValues(final Iterable values) { + for (final Object value : values) { + if (value == null) { + throw new NullPointerException(); + } + } + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractParser.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractParser.java new file mode 100644 index 0000000..9bd9d39 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/AbstractParser.java @@ -0,0 +1,261 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream; + +import java.io.IOException; +import java.io.InputStream; + +/** + * A partial implementation of the {@link Parser} interface which implements + * as many methods of that interface as possible in terms of other methods. + * + * Note: This class implements all the convenience methods in the + * {@link Parser} interface. See {@link Parser} for related javadocs. + * Subclasses need to implement + * {@link Parser#parsePartialFrom(CodedInputStream, ExtensionRegistryLite)} + * + * @author liujisi@google.com (Pherl Liu) + */ +public abstract class AbstractParser + implements Parser { + /** + * Creates an UninitializedMessageException for MessageType. + */ + private UninitializedMessageException + newUninitializedMessageException(MessageType message) { + if (message instanceof AbstractMessageLite) { + return ((AbstractMessageLite) message).newUninitializedMessageException(); + } + return new UninitializedMessageException(message); + } + + /** + * Helper method to check if message is initialized. + * + * @throws InvalidProtocolBufferException if it is not initialized. + * @return The message to check. + */ + private MessageType checkMessageInitialized(MessageType message) + throws InvalidProtocolBufferException { + if (message != null && !message.isInitialized()) { + throw newUninitializedMessageException(message) + .asInvalidProtocolBufferException() + .setUnfinishedMessage(message); + } + return message; + } + + private static final ExtensionRegistryLite EMPTY_REGISTRY + = ExtensionRegistryLite.getEmptyRegistry(); + + public MessageType parsePartialFrom(CodedInputStream input) + throws InvalidProtocolBufferException { + return parsePartialFrom(input, EMPTY_REGISTRY); + } + + public MessageType parseFrom(CodedInputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return checkMessageInitialized( + parsePartialFrom(input, extensionRegistry)); + } + + public MessageType parseFrom(CodedInputStream input) + throws InvalidProtocolBufferException { + return parseFrom(input, EMPTY_REGISTRY); + } + + public MessageType parsePartialFrom(ByteString data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + MessageType message; + try { + CodedInputStream input = data.newCodedInput(); + message = parsePartialFrom(input, extensionRegistry); + try { + input.checkLastTagWas(0); + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(message); + } + return message; + } catch (InvalidProtocolBufferException e) { + throw e; + } catch (IOException e) { + throw new RuntimeException( + "Reading from a ByteString threw an IOException (should " + + "never happen).", e); + } + } + + public MessageType parsePartialFrom(ByteString data) + throws InvalidProtocolBufferException { + return parsePartialFrom(data, EMPTY_REGISTRY); + } + + public MessageType parseFrom(ByteString data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return checkMessageInitialized(parsePartialFrom(data, extensionRegistry)); + } + + public MessageType parseFrom(ByteString data) + throws InvalidProtocolBufferException { + return parseFrom(data, EMPTY_REGISTRY); + } + + public MessageType parsePartialFrom(byte[] data, int off, int len, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + try { + CodedInputStream input = CodedInputStream.newInstance(data, off, len); + MessageType message = parsePartialFrom(input, extensionRegistry); + try { + input.checkLastTagWas(0); + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(message); + } + return message; + } catch (InvalidProtocolBufferException e) { + throw e; + } catch (IOException e) { + throw new RuntimeException( + "Reading from a byte array threw an IOException (should " + + "never happen).", e); + } + } + + public MessageType parsePartialFrom(byte[] data, int off, int len) + throws InvalidProtocolBufferException { + return parsePartialFrom(data, off, len, EMPTY_REGISTRY); + } + + public MessageType parsePartialFrom(byte[] data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return parsePartialFrom(data, 0, data.length, extensionRegistry); + } + + public MessageType parsePartialFrom(byte[] data) + throws InvalidProtocolBufferException { + return parsePartialFrom(data, 0, data.length, EMPTY_REGISTRY); + } + + public MessageType parseFrom(byte[] data, int off, int len, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return checkMessageInitialized( + parsePartialFrom(data, off, len, extensionRegistry)); + } + + public MessageType parseFrom(byte[] data, int off, int len) + throws InvalidProtocolBufferException { + return parseFrom(data, off, len, EMPTY_REGISTRY); + } + + public MessageType parseFrom(byte[] data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return parseFrom(data, 0, data.length, extensionRegistry); + } + + public MessageType parseFrom(byte[] data) + throws InvalidProtocolBufferException { + return parseFrom(data, EMPTY_REGISTRY); + } + + public MessageType parsePartialFrom(InputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + CodedInputStream codedInput = CodedInputStream.newInstance(input); + MessageType message = parsePartialFrom(codedInput, extensionRegistry); + try { + codedInput.checkLastTagWas(0); + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(message); + } + return message; + } + + public MessageType parsePartialFrom(InputStream input) + throws InvalidProtocolBufferException { + return parsePartialFrom(input, EMPTY_REGISTRY); + } + + public MessageType parseFrom(InputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return checkMessageInitialized( + parsePartialFrom(input, extensionRegistry)); + } + + public MessageType parseFrom(InputStream input) + throws InvalidProtocolBufferException { + return parseFrom(input, EMPTY_REGISTRY); + } + + public MessageType parsePartialDelimitedFrom( + InputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + int size; + try { + int firstByte = input.read(); + if (firstByte == -1) { + return null; + } + size = CodedInputStream.readRawVarint32(firstByte, input); + } catch (IOException e) { + throw new InvalidProtocolBufferException(e.getMessage()); + } + InputStream limitedInput = new LimitedInputStream(input, size); + return parsePartialFrom(limitedInput, extensionRegistry); + } + + public MessageType parsePartialDelimitedFrom(InputStream input) + throws InvalidProtocolBufferException { + return parsePartialDelimitedFrom(input, EMPTY_REGISTRY); + } + + public MessageType parseDelimitedFrom( + InputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return checkMessageInitialized( + parsePartialDelimitedFrom(input, extensionRegistry)); + } + + public MessageType parseDelimitedFrom(InputStream input) + throws InvalidProtocolBufferException { + return parseDelimitedFrom(input, EMPTY_REGISTRY); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java new file mode 100644 index 0000000..1e81143 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java @@ -0,0 +1,51 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + *

Abstract interface for a blocking RPC channel. {@code BlockingRpcChannel} + * is the blocking equivalent to {@link RpcChannel}. + * + * @author kenton@google.com Kenton Varda + * @author cpovirk@google.com Chris Povirk + */ +public interface BlockingRpcChannel { + /** + * Call the given method of the remote service and blocks until it returns. + * {@code callBlockingMethod()} is the blocking equivalent to + * {@link RpcChannel#callMethod}. + */ + Message callBlockingMethod( + Descriptors.MethodDescriptor method, + RpcController controller, + Message request, + Message responsePrototype) throws ServiceException; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BlockingService.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BlockingService.java new file mode 100644 index 0000000..ecc8009 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BlockingService.java @@ -0,0 +1,64 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + * Blocking equivalent to {@link Service}. + * + * @author kenton@google.com Kenton Varda + * @author cpovirk@google.com Chris Povirk + */ +public interface BlockingService { + /** + * Equivalent to {@link Service#getDescriptorForType}. + */ + Descriptors.ServiceDescriptor getDescriptorForType(); + + /** + * Equivalent to {@link Service#callMethod}, except that + * {@code callBlockingMethod()} returns the result of the RPC or throws a + * {@link ServiceException} if there is a failure, rather than passing the + * information to a callback. + */ + Message callBlockingMethod(Descriptors.MethodDescriptor method, + RpcController controller, + Message request) throws ServiceException; + + /** + * Equivalent to {@link Service#getRequestPrototype}. + */ + Message getRequestPrototype(Descriptors.MethodDescriptor method); + + /** + * Equivalent to {@link Service#getResponsePrototype}. + */ + Message getResponsePrototype(Descriptors.MethodDescriptor method); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BoundedByteString.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BoundedByteString.java new file mode 100644 index 0000000..cd4982c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/BoundedByteString.java @@ -0,0 +1,163 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.util.NoSuchElementException; + +/** + * This class is used to represent the substring of a {@link ByteString} over a + * single byte array. In terms of the public API of {@link ByteString}, you end + * up here by calling {@link ByteString#copyFrom(byte[])} followed by {@link + * ByteString#substring(int, int)}. + * + *

This class contains most of the overhead involved in creating a substring + * from a {@link LiteralByteString}. The overhead involves some range-checking + * and two extra fields. + * + * @author carlanton@google.com (Carl Haverl) + */ +class BoundedByteString extends LiteralByteString { + + private final int bytesOffset; + private final int bytesLength; + + /** + * Creates a {@code BoundedByteString} backed by the sub-range of given array, + * without copying. + * + * @param bytes array to wrap + * @param offset index to first byte to use in bytes + * @param length number of bytes to use from bytes + * @throws IllegalArgumentException if {@code offset < 0}, {@code length < 0}, + * or if {@code offset + length > + * bytes.length}. + */ + BoundedByteString(byte[] bytes, int offset, int length) { + super(bytes); + if (offset < 0) { + throw new IllegalArgumentException("Offset too small: " + offset); + } + if (length < 0) { + throw new IllegalArgumentException("Length too small: " + offset); + } + if ((long) offset + length > bytes.length) { + throw new IllegalArgumentException( + "Offset+Length too large: " + offset + "+" + length); + } + + this.bytesOffset = offset; + this.bytesLength = length; + } + + /** + * Gets the byte at the given index. + * Throws {@link ArrayIndexOutOfBoundsException} + * for backwards-compatibility reasons although it would more properly be + * {@link IndexOutOfBoundsException}. + * + * @param index index of byte + * @return the value + * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size + */ + @Override + public byte byteAt(int index) { + // We must check the index ourselves as we cannot rely on Java array index + // checking for substrings. + if (index < 0) { + throw new ArrayIndexOutOfBoundsException("Index too small: " + index); + } + if (index >= size()) { + throw new ArrayIndexOutOfBoundsException( + "Index too large: " + index + ", " + size()); + } + + return bytes[bytesOffset + index]; + } + + @Override + public int size() { + return bytesLength; + } + + @Override + protected int getOffsetIntoBytes() { + return bytesOffset; + } + + // ================================================================= + // ByteString -> byte[] + + @Override + protected void copyToInternal(byte[] target, int sourceOffset, + int targetOffset, int numberToCopy) { + System.arraycopy(bytes, getOffsetIntoBytes() + sourceOffset, target, + targetOffset, numberToCopy); + } + + // ================================================================= + // ByteIterator + + @Override + public ByteIterator iterator() { + return new BoundedByteIterator(); + } + + private class BoundedByteIterator implements ByteIterator { + + private int position; + private final int limit; + + private BoundedByteIterator() { + position = getOffsetIntoBytes(); + limit = position + size(); + } + + public boolean hasNext() { + return (position < limit); + } + + public Byte next() { + // Boxing calls Byte.valueOf(byte), which does not instantiate. + return nextByte(); + } + + public byte nextByte() { + if (position >= limit) { + throw new NoSuchElementException(); + } + return bytes[position++]; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ByteString.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ByteString.java new file mode 100644 index 0000000..73d831f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ByteString.java @@ -0,0 +1,970 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +/** + * Immutable sequence of bytes. Substring is supported by sharing the reference + * to the immutable underlying bytes, as with {@link String}. Concatenation is + * likewise supported without copying (long strings) by building a tree of + * pieces in {@link RopeByteString}. + *

+ * Like {@link String}, the contents of a {@link ByteString} can never be + * observed to change, not even in the presence of a data race or incorrect + * API usage in the client code. + * + * @author crazybob@google.com Bob Lee + * @author kenton@google.com Kenton Varda + * @author carlanton@google.com Carl Haverl + * @author martinrb@google.com Martin Buchholz + */ +public abstract class ByteString implements Iterable { + + /** + * When two strings to be concatenated have a combined length shorter than + * this, we just copy their bytes on {@link #concat(ByteString)}. + * The trade-off is copy size versus the overhead of creating tree nodes + * in {@link RopeByteString}. + */ + static final int CONCATENATE_BY_COPY_SIZE = 128; + + /** + * When copying an InputStream into a ByteString with .readFrom(), + * the chunks in the underlying rope start at 256 bytes, but double + * each iteration up to 8192 bytes. + */ + static final int MIN_READ_FROM_CHUNK_SIZE = 0x100; // 256b + static final int MAX_READ_FROM_CHUNK_SIZE = 0x2000; // 8k + + /** + * Empty {@code ByteString}. + */ + public static final ByteString EMPTY = new LiteralByteString(new byte[0]); + + // This constructor is here to prevent subclassing outside of this package, + ByteString() {} + + /** + * Gets the byte at the given index. This method should be used only for + * random access to individual bytes. To access bytes sequentially, use the + * {@link ByteIterator} returned by {@link #iterator()}, and call {@link + * #substring(int, int)} first if necessary. + * + * @param index index of byte + * @return the value + * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size + */ + public abstract byte byteAt(int index); + + /** + * Return a {@link ByteString.ByteIterator} over the bytes in the ByteString. + * To avoid auto-boxing, you may get the iterator manually and call + * {@link ByteIterator#nextByte()}. + * + * @return the iterator + */ + public abstract ByteIterator iterator(); + + /** + * This interface extends {@code Iterator}, so that we can return an + * unboxed {@code byte}. + */ + public interface ByteIterator extends Iterator { + /** + * An alternative to {@link Iterator#next()} that returns an + * unboxed primitive {@code byte}. + * + * @return the next {@code byte} in the iteration + * @throws NoSuchElementException if the iteration has no more elements + */ + byte nextByte(); + } + + /** + * Gets the number of bytes. + * + * @return size in bytes + */ + public abstract int size(); + + /** + * Returns {@code true} if the size is {@code 0}, {@code false} otherwise. + * + * @return true if this is zero bytes long + */ + public boolean isEmpty() { + return size() == 0; + } + + // ================================================================= + // ByteString -> substring + + /** + * Return the substring from {@code beginIndex}, inclusive, to the end of the + * string. + * + * @param beginIndex start at this index + * @return substring sharing underlying data + * @throws IndexOutOfBoundsException if {@code beginIndex < 0} or + * {@code beginIndex > size()}. + */ + public ByteString substring(int beginIndex) { + return substring(beginIndex, size()); + } + + /** + * Return the substring from {@code beginIndex}, inclusive, to {@code + * endIndex}, exclusive. + * + * @param beginIndex start at this index + * @param endIndex the last character is the one before this index + * @return substring sharing underlying data + * @throws IndexOutOfBoundsException if {@code beginIndex < 0}, + * {@code endIndex > size()}, or {@code beginIndex > endIndex}. + */ + public abstract ByteString substring(int beginIndex, int endIndex); + + /** + * Tests if this bytestring starts with the specified prefix. + * Similar to {@link String#startsWith(String)} + * + * @param prefix the prefix. + * @return true if the byte sequence represented by the + * argument is a prefix of the byte sequence represented by + * this string; false otherwise. + */ + public boolean startsWith(ByteString prefix) { + return size() >= prefix.size() && + substring(0, prefix.size()).equals(prefix); + } + + // ================================================================= + // byte[] -> ByteString + + /** + * Copies the given bytes into a {@code ByteString}. + * + * @param bytes source array + * @param offset offset in source array + * @param size number of bytes to copy + * @return new {@code ByteString} + */ + public static ByteString copyFrom(byte[] bytes, int offset, int size) { + byte[] copy = new byte[size]; + System.arraycopy(bytes, offset, copy, 0, size); + return new LiteralByteString(copy); + } + + /** + * Copies the given bytes into a {@code ByteString}. + * + * @param bytes to copy + * @return new {@code ByteString} + */ + public static ByteString copyFrom(byte[] bytes) { + return copyFrom(bytes, 0, bytes.length); + } + + /** + * Copies the next {@code size} bytes from a {@code java.nio.ByteBuffer} into + * a {@code ByteString}. + * + * @param bytes source buffer + * @param size number of bytes to copy + * @return new {@code ByteString} + */ + public static ByteString copyFrom(ByteBuffer bytes, int size) { + byte[] copy = new byte[size]; + bytes.get(copy); + return new LiteralByteString(copy); + } + + /** + * Copies the remaining bytes from a {@code java.nio.ByteBuffer} into + * a {@code ByteString}. + * + * @param bytes sourceBuffer + * @return new {@code ByteString} + */ + public static ByteString copyFrom(ByteBuffer bytes) { + return copyFrom(bytes, bytes.remaining()); + } + + /** + * Encodes {@code text} into a sequence of bytes using the named charset + * and returns the result as a {@code ByteString}. + * + * @param text source string + * @param charsetName encoding to use + * @return new {@code ByteString} + * @throws UnsupportedEncodingException if the encoding isn't found + */ + public static ByteString copyFrom(String text, String charsetName) + throws UnsupportedEncodingException { + return new LiteralByteString(text.getBytes(charsetName)); + } + + /** + * Encodes {@code text} into a sequence of UTF-8 bytes and returns the + * result as a {@code ByteString}. + * + * @param text source string + * @return new {@code ByteString} + */ + public static ByteString copyFromUtf8(String text) { + try { + return new LiteralByteString(text.getBytes("UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("UTF-8 not supported?", e); + } + } + + // ================================================================= + // InputStream -> ByteString + + /** + * Completely reads the given stream's bytes into a + * {@code ByteString}, blocking if necessary until all bytes are + * read through to the end of the stream. + * + * Performance notes: The returned {@code ByteString} is an + * immutable tree of byte arrays ("chunks") of the stream data. The + * first chunk is small, with subsequent chunks each being double + * the size, up to 8K. If the caller knows the precise length of + * the stream and wishes to avoid all unnecessary copies and + * allocations, consider using the two-argument version of this + * method, below. + * + * @param streamToDrain The source stream, which is read completely + * but not closed. + * @return A new {@code ByteString} which is made up of chunks of + * various sizes, depending on the behavior of the underlying + * stream. + * @throws IOException IOException is thrown if there is a problem + * reading the underlying stream. + */ + public static ByteString readFrom(InputStream streamToDrain) + throws IOException { + return readFrom( + streamToDrain, MIN_READ_FROM_CHUNK_SIZE, MAX_READ_FROM_CHUNK_SIZE); + } + + /** + * Completely reads the given stream's bytes into a + * {@code ByteString}, blocking if necessary until all bytes are + * read through to the end of the stream. + * + * Performance notes: The returned {@code ByteString} is an + * immutable tree of byte arrays ("chunks") of the stream data. The + * chunkSize parameter sets the size of these byte arrays. In + * particular, if the chunkSize is precisely the same as the length + * of the stream, unnecessary allocations and copies will be + * avoided. Otherwise, the chunks will be of the given size, except + * for the last chunk, which will be resized (via a reallocation and + * copy) to contain the remainder of the stream. + * + * @param streamToDrain The source stream, which is read completely + * but not closed. + * @param chunkSize The size of the chunks in which to read the + * stream. + * @return A new {@code ByteString} which is made up of chunks of + * the given size. + * @throws IOException IOException is thrown if there is a problem + * reading the underlying stream. + */ + public static ByteString readFrom(InputStream streamToDrain, int chunkSize) + throws IOException { + return readFrom(streamToDrain, chunkSize, chunkSize); + } + + // Helper method that takes the chunk size range as a parameter. + public static ByteString readFrom(InputStream streamToDrain, int minChunkSize, + int maxChunkSize) throws IOException { + Collection results = new ArrayList(); + + // copy the inbound bytes into a list of chunks; the chunk size + // grows exponentially to support both short and long streams. + int chunkSize = minChunkSize; + while (true) { + ByteString chunk = readChunk(streamToDrain, chunkSize); + if (chunk == null) { + break; + } + results.add(chunk); + chunkSize = Math.min(chunkSize * 2, maxChunkSize); + } + + return ByteString.copyFrom(results); + } + + /** + * Blocks until a chunk of the given size can be made from the + * stream, or EOF is reached. Calls read() repeatedly in case the + * given stream implementation doesn't completely fill the given + * buffer in one read() call. + * + * @return A chunk of the desired size, or else a chunk as large as + * was available when end of stream was reached. Returns null if the + * given stream had no more data in it. + */ + private static ByteString readChunk(InputStream in, final int chunkSize) + throws IOException { + final byte[] buf = new byte[chunkSize]; + int bytesRead = 0; + while (bytesRead < chunkSize) { + final int count = in.read(buf, bytesRead, chunkSize - bytesRead); + if (count == -1) { + break; + } + bytesRead += count; + } + + if (bytesRead == 0) { + return null; + } else { + return ByteString.copyFrom(buf, 0, bytesRead); + } + } + + // ================================================================= + // Multiple ByteStrings -> One ByteString + + /** + * Concatenate the given {@code ByteString} to this one. Short concatenations, + * of total size smaller than {@link ByteString#CONCATENATE_BY_COPY_SIZE}, are + * produced by copying the underlying bytes (as per Rope.java, + * BAP95 . In general, the concatenate involves no copying. + * + * @param other string to concatenate + * @return a new {@code ByteString} instance + */ + public ByteString concat(ByteString other) { + int thisSize = size(); + int otherSize = other.size(); + if ((long) thisSize + otherSize >= Integer.MAX_VALUE) { + throw new IllegalArgumentException("ByteString would be too long: " + + thisSize + "+" + otherSize); + } + + return RopeByteString.concatenate(this, other); + } + + /** + * Concatenates all byte strings in the iterable and returns the result. + * This is designed to run in O(list size), not O(total bytes). + * + *

The returned {@code ByteString} is not necessarily a unique object. + * If the list is empty, the returned object is the singleton empty + * {@code ByteString}. If the list has only one element, that + * {@code ByteString} will be returned without copying. + * + * @param byteStrings strings to be concatenated + * @return new {@code ByteString} + */ + public static ByteString copyFrom(Iterable byteStrings) { + Collection collection; + if (!(byteStrings instanceof Collection)) { + collection = new ArrayList(); + for (ByteString byteString : byteStrings) { + collection.add(byteString); + } + } else { + collection = (Collection) byteStrings; + } + ByteString result; + if (collection.isEmpty()) { + result = EMPTY; + } else { + result = balancedConcat(collection.iterator(), collection.size()); + } + return result; + } + + // Internal function used by copyFrom(Iterable). + // Create a balanced concatenation of the next "length" elements from the + // iterable. + private static ByteString balancedConcat(Iterator iterator, + int length) { + assert length >= 1; + ByteString result; + if (length == 1) { + result = iterator.next(); + } else { + int halfLength = length >>> 1; + ByteString left = balancedConcat(iterator, halfLength); + ByteString right = balancedConcat(iterator, length - halfLength); + result = left.concat(right); + } + return result; + } + + // ================================================================= + // ByteString -> byte[] + + /** + * Copies bytes into a buffer at the given offset. + * + * @param target buffer to copy into + * @param offset in the target buffer + * @throws IndexOutOfBoundsException if the offset is negative or too large + */ + public void copyTo(byte[] target, int offset) { + copyTo(target, 0, offset, size()); + } + + /** + * Copies bytes into a buffer. + * + * @param target buffer to copy into + * @param sourceOffset offset within these bytes + * @param targetOffset offset within the target buffer + * @param numberToCopy number of bytes to copy + * @throws IndexOutOfBoundsException if an offset or size is negative or too + * large + */ + public void copyTo(byte[] target, int sourceOffset, int targetOffset, + int numberToCopy) { + if (sourceOffset < 0) { + throw new IndexOutOfBoundsException("Source offset < 0: " + sourceOffset); + } + if (targetOffset < 0) { + throw new IndexOutOfBoundsException("Target offset < 0: " + targetOffset); + } + if (numberToCopy < 0) { + throw new IndexOutOfBoundsException("Length < 0: " + numberToCopy); + } + if (sourceOffset + numberToCopy > size()) { + throw new IndexOutOfBoundsException( + "Source end offset < 0: " + (sourceOffset + numberToCopy)); + } + if (targetOffset + numberToCopy > target.length) { + throw new IndexOutOfBoundsException( + "Target end offset < 0: " + (targetOffset + numberToCopy)); + } + if (numberToCopy > 0) { + copyToInternal(target, sourceOffset, targetOffset, numberToCopy); + } + } + + /** + * Internal (package private) implementation of + * @link{#copyTo(byte[],int,int,int}. + * It assumes that all error checking has already been performed and that + * @code{numberToCopy > 0}. + */ + protected abstract void copyToInternal(byte[] target, int sourceOffset, + int targetOffset, int numberToCopy); + + /** + * Copies bytes into a ByteBuffer. + * + * @param target ByteBuffer to copy into. + * @throws java.nio.ReadOnlyBufferException if the {@code target} is read-only + * @throws java.nio.BufferOverflowException if the {@code target}'s + * remaining() space is not large enough to hold the data. + */ + public abstract void copyTo(ByteBuffer target); + + /** + * Copies bytes to a {@code byte[]}. + * + * @return copied bytes + */ + public byte[] toByteArray() { + int size = size(); + byte[] result = new byte[size]; + copyToInternal(result, 0, 0, size); + return result; + } + + /** + * Writes the complete contents of this byte string to + * the specified output stream argument. + * + * @param out the output stream to which to write the data. + * @throws IOException if an I/O error occurs. + */ + public abstract void writeTo(OutputStream out) throws IOException; + + /** + * Constructs a read-only {@code java.nio.ByteBuffer} whose content + * is equal to the contents of this byte string. + * The result uses the same backing array as the byte string, if possible. + * + * @return wrapped bytes + */ + public abstract ByteBuffer asReadOnlyByteBuffer(); + + /** + * Constructs a list of read-only {@code java.nio.ByteBuffer} objects + * such that the concatenation of their contents is equal to the contents + * of this byte string. The result uses the same backing arrays as the + * byte string. + *

+ * By returning a list, implementations of this method may be able to avoid + * copying even when there are multiple backing arrays. + * + * @return a list of wrapped bytes + */ + public abstract List asReadOnlyByteBufferList(); + + /** + * Constructs a new {@code String} by decoding the bytes using the + * specified charset. + * + * @param charsetName encode using this charset + * @return new string + * @throws UnsupportedEncodingException if charset isn't recognized + */ + public abstract String toString(String charsetName) + throws UnsupportedEncodingException; + + // ================================================================= + // UTF-8 decoding + + /** + * Constructs a new {@code String} by decoding the bytes as UTF-8. + * + * @return new string using UTF-8 encoding + */ + public String toStringUtf8() { + try { + return toString("UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("UTF-8 not supported?", e); + } + } + + /** + * Tells whether this {@code ByteString} represents a well-formed UTF-8 + * byte sequence, such that the original bytes can be converted to a + * String object and then round tripped back to bytes without loss. + * + *

More precisely, returns {@code true} whenever:

 {@code
+   * Arrays.equals(byteString.toByteArray(),
+   *     new String(byteString.toByteArray(), "UTF-8").getBytes("UTF-8"))
+   * }
+ * + *

This method returns {@code false} for "overlong" byte sequences, + * as well as for 3-byte sequences that would map to a surrogate + * character, in accordance with the restricted definition of UTF-8 + * introduced in Unicode 3.1. Note that the UTF-8 decoder included in + * Oracle's JDK has been modified to also reject "overlong" byte + * sequences, but (as of 2011) still accepts 3-byte surrogate + * character byte sequences. + * + *

See the Unicode Standard,
+ * Table 3-6. UTF-8 Bit Distribution,
+ * Table 3-7. Well Formed UTF-8 Byte Sequences. + * + * @return whether the bytes in this {@code ByteString} are a + * well-formed UTF-8 byte sequence + */ + public abstract boolean isValidUtf8(); + + /** + * Tells whether the given byte sequence is a well-formed, malformed, or + * incomplete UTF-8 byte sequence. This method accepts and returns a partial + * state result, allowing the bytes for a complete UTF-8 byte sequence to be + * composed from multiple {@code ByteString} segments. + * + * @param state either {@code 0} (if this is the initial decoding operation) + * or the value returned from a call to a partial decoding method for the + * previous bytes + * @param offset offset of the first byte to check + * @param length number of bytes to check + * + * @return {@code -1} if the partial byte sequence is definitely malformed, + * {@code 0} if it is well-formed (no additional input needed), or, if the + * byte sequence is "incomplete", i.e. apparently terminated in the middle of + * a character, an opaque integer "state" value containing enough information + * to decode the character when passed to a subsequent invocation of a + * partial decoding method. + */ + protected abstract int partialIsValidUtf8(int state, int offset, int length); + + // ================================================================= + // equals() and hashCode() + + @Override + public abstract boolean equals(Object o); + + /** + * Return a non-zero hashCode depending only on the sequence of bytes + * in this ByteString. + * + * @return hashCode value for this object + */ + @Override + public abstract int hashCode(); + + // ================================================================= + // Input stream + + /** + * Creates an {@code InputStream} which can be used to read the bytes. + *

+ * The {@link InputStream} returned by this method is guaranteed to be + * completely non-blocking. The method {@link InputStream#available()} + * returns the number of bytes remaining in the stream. The methods + * {@link InputStream#read(byte[]), {@link InputStream#read(byte[],int,int)} + * and {@link InputStream#skip(long)} will read/skip as many bytes as are + * available. + *

+ * The methods in the returned {@link InputStream} might not be + * thread safe. + * + * @return an input stream that returns the bytes of this byte string. + */ + public abstract InputStream newInput(); + + /** + * Creates a {@link CodedInputStream} which can be used to read the bytes. + * Using this is often more efficient than creating a {@link CodedInputStream} + * that wraps the result of {@link #newInput()}. + * + * @return stream based on wrapped data + */ + public abstract CodedInputStream newCodedInput(); + + // ================================================================= + // Output stream + + /** + * Creates a new {@link Output} with the given initial capacity. Call {@link + * Output#toByteString()} to create the {@code ByteString} instance. + *

+ * A {@link ByteString.Output} offers the same functionality as a + * {@link ByteArrayOutputStream}, except that it returns a {@link ByteString} + * rather than a {@code byte} array. + * + * @param initialCapacity estimate of number of bytes to be written + * @return {@code OutputStream} for building a {@code ByteString} + */ + public static Output newOutput(int initialCapacity) { + return new Output(initialCapacity); + } + + /** + * Creates a new {@link Output}. Call {@link Output#toByteString()} to create + * the {@code ByteString} instance. + *

+ * A {@link ByteString.Output} offers the same functionality as a + * {@link ByteArrayOutputStream}, except that it returns a {@link ByteString} + * rather than a {@code byte array}. + * + * @return {@code OutputStream} for building a {@code ByteString} + */ + public static Output newOutput() { + return new Output(CONCATENATE_BY_COPY_SIZE); + } + + /** + * Outputs to a {@code ByteString} instance. Call {@link #toByteString()} to + * create the {@code ByteString} instance. + */ + public static final class Output extends OutputStream { + // Implementation note. + // The public methods of this class must be synchronized. ByteStrings + // are guaranteed to be immutable. Without some sort of locking, it could + // be possible for one thread to call toByteSring(), while another thread + // is still modifying the underlying byte array. + + private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + // argument passed by user, indicating initial capacity. + private final int initialCapacity; + // ByteStrings to be concatenated to create the result + private final ArrayList flushedBuffers; + // Total number of bytes in the ByteStrings of flushedBuffers + private int flushedBuffersTotalBytes; + // Current buffer to which we are writing + private byte[] buffer; + // Location in buffer[] to which we write the next byte. + private int bufferPos; + + /** + * Creates a new ByteString output stream with the specified + * initial capacity. + * + * @param initialCapacity the initial capacity of the output stream. + */ + Output(int initialCapacity) { + if (initialCapacity < 0) { + throw new IllegalArgumentException("Buffer size < 0"); + } + this.initialCapacity = initialCapacity; + this.flushedBuffers = new ArrayList(); + this.buffer = new byte[initialCapacity]; + } + + @Override + public synchronized void write(int b) { + if (bufferPos == buffer.length) { + flushFullBuffer(1); + } + buffer[bufferPos++] = (byte)b; + } + + @Override + public synchronized void write(byte[] b, int offset, int length) { + if (length <= buffer.length - bufferPos) { + // The bytes can fit into the current buffer. + System.arraycopy(b, offset, buffer, bufferPos, length); + bufferPos += length; + } else { + // Use up the current buffer + int copySize = buffer.length - bufferPos; + System.arraycopy(b, offset, buffer, bufferPos, copySize); + offset += copySize; + length -= copySize; + // Flush the buffer, and get a new buffer at least big enough to cover + // what we still need to output + flushFullBuffer(length); + System.arraycopy(b, offset, buffer, 0 /* count */, length); + bufferPos = length; + } + } + + /** + * Creates a byte string. Its size is the current size of this output + * stream and its output has been copied to it. + * + * @return the current contents of this output stream, as a byte string. + */ + public synchronized ByteString toByteString() { + flushLastBuffer(); + return ByteString.copyFrom(flushedBuffers); + } + + /** + * Implement java.util.Arrays.copyOf() for jdk 1.5. + */ + private byte[] copyArray(byte[] buffer, int length) { + byte[] result = new byte[length]; + System.arraycopy(buffer, 0, result, 0, Math.min(buffer.length, length)); + return result; + } + + /** + * Writes the complete contents of this byte array output stream to + * the specified output stream argument. + * + * @param out the output stream to which to write the data. + * @throws IOException if an I/O error occurs. + */ + public void writeTo(OutputStream out) throws IOException { + ByteString[] cachedFlushBuffers; + byte[] cachedBuffer; + int cachedBufferPos; + synchronized (this) { + // Copy the information we need into local variables so as to hold + // the lock for as short a time as possible. + cachedFlushBuffers = + flushedBuffers.toArray(new ByteString[flushedBuffers.size()]); + cachedBuffer = buffer; + cachedBufferPos = bufferPos; + } + for (ByteString byteString : cachedFlushBuffers) { + byteString.writeTo(out); + } + + out.write(copyArray(cachedBuffer, cachedBufferPos)); + } + + /** + * Returns the current size of the output stream. + * + * @return the current size of the output stream + */ + public synchronized int size() { + return flushedBuffersTotalBytes + bufferPos; + } + + /** + * Resets this stream, so that all currently accumulated output in the + * output stream is discarded. The output stream can be used again, + * reusing the already allocated buffer space. + */ + public synchronized void reset() { + flushedBuffers.clear(); + flushedBuffersTotalBytes = 0; + bufferPos = 0; + } + + @Override + public String toString() { + return String.format("", + Integer.toHexString(System.identityHashCode(this)), size()); + } + + /** + * Internal function used by writers. The current buffer is full, and the + * writer needs a new buffer whose size is at least the specified minimum + * size. + */ + private void flushFullBuffer(int minSize) { + flushedBuffers.add(new LiteralByteString(buffer)); + flushedBuffersTotalBytes += buffer.length; + // We want to increase our total capacity by 50%, but as a minimum, + // the new buffer should also at least be >= minSize and + // >= initial Capacity. + int newSize = Math.max(initialCapacity, + Math.max(minSize, flushedBuffersTotalBytes >>> 1)); + buffer = new byte[newSize]; + bufferPos = 0; + } + + /** + * Internal function used by {@link #toByteString()}. The current buffer may + * or may not be full, but it needs to be flushed. + */ + private void flushLastBuffer() { + if (bufferPos < buffer.length) { + if (bufferPos > 0) { + byte[] bufferCopy = copyArray(buffer, bufferPos); + flushedBuffers.add(new LiteralByteString(bufferCopy)); + } + // We reuse this buffer for further writes. + } else { + // Buffer is completely full. Huzzah. + flushedBuffers.add(new LiteralByteString(buffer)); + // 99% of the time, we're not going to use this OutputStream again. + // We set buffer to an empty byte stream so that we're handling this + // case without wasting space. In the rare case that more writes + // *do* occur, this empty buffer will be flushed and an appropriately + // sized new buffer will be created. + buffer = EMPTY_BYTE_ARRAY; + } + flushedBuffersTotalBytes += bufferPos; + bufferPos = 0; + } + } + + /** + * Constructs a new {@code ByteString} builder, which allows you to + * efficiently construct a {@code ByteString} by writing to a {@link + * CodedOutputStream}. Using this is much more efficient than calling {@code + * newOutput()} and wrapping that in a {@code CodedOutputStream}. + * + *

This is package-private because it's a somewhat confusing interface. + * Users can call {@link Message#toByteString()} instead of calling this + * directly. + * + * @param size The target byte size of the {@code ByteString}. You must write + * exactly this many bytes before building the result. + * @return the builder + */ + static CodedBuilder newCodedBuilder(int size) { + return new CodedBuilder(size); + } + + /** See {@link ByteString#newCodedBuilder(int)}. */ + static final class CodedBuilder { + private final CodedOutputStream output; + private final byte[] buffer; + + private CodedBuilder(int size) { + buffer = new byte[size]; + output = CodedOutputStream.newInstance(buffer); + } + + public ByteString build() { + output.checkNoSpaceLeft(); + + // We can be confident that the CodedOutputStream will not modify the + // underlying bytes anymore because it already wrote all of them. So, + // no need to make a copy. + return new LiteralByteString(buffer); + } + + public CodedOutputStream getCodedOutput() { + return output; + } + } + + // ================================================================= + // Methods {@link RopeByteString} needs on instances, which aren't part of the + // public API. + + /** + * Return the depth of the tree representing this {@code ByteString}, if any, + * whose root is this node. If this is a leaf node, return 0. + * + * @return tree depth or zero + */ + protected abstract int getTreeDepth(); + + /** + * Return {@code true} if this ByteString is literal (a leaf node) or a + * flat-enough tree in the sense of {@link RopeByteString}. + * + * @return true if the tree is flat enough + */ + protected abstract boolean isBalanced(); + + /** + * Return the cached hash code if available. + * + * @return value of cached hash code or 0 if not computed yet + */ + protected abstract int peekCachedHashCode(); + + /** + * Compute the hash across the value bytes starting with the given hash, and + * return the result. This is used to compute the hash across strings + * represented as a set of pieces by allowing the hash computation to be + * continued from piece to piece. + * + * @param h starting hash value + * @param offset offset into this value to start looking at data values + * @param length number of data values to include in the hash computation + * @return ending hash value + */ + protected abstract int partialHash(int h, int offset, int length); + + @Override + public String toString() { + return String.format("", + Integer.toHexString(System.identityHashCode(this)), size()); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/CodedInputStream.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/CodedInputStream.java new file mode 100644 index 0000000..33417a7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/CodedInputStream.java @@ -0,0 +1,920 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * Reads and decodes protocol message fields. + * + * This class contains two kinds of methods: methods that read specific + * protocol message constructs and field types (e.g. {@link #readTag()} and + * {@link #readInt32()}) and methods that read low-level values (e.g. + * {@link #readRawVarint32()} and {@link #readRawBytes}). If you are reading + * encoded protocol messages, you should use the former methods, but if you are + * reading some other format of your own design, use the latter. + * + * @author kenton@google.com Kenton Varda + */ +public final class CodedInputStream { + /** + * Create a new CodedInputStream wrapping the given InputStream. + */ + public static CodedInputStream newInstance(final InputStream input) { + return new CodedInputStream(input); + } + + /** + * Create a new CodedInputStream wrapping the given byte array. + */ + public static CodedInputStream newInstance(final byte[] buf) { + return newInstance(buf, 0, buf.length); + } + + /** + * Create a new CodedInputStream wrapping the given byte array slice. + */ + public static CodedInputStream newInstance(final byte[] buf, final int off, + final int len) { + CodedInputStream result = new CodedInputStream(buf, off, len); + try { + // Some uses of CodedInputStream can be more efficient if they know + // exactly how many bytes are available. By pushing the end point of the + // buffer as a limit, we allow them to get this information via + // getBytesUntilLimit(). Pushing a limit that we know is at the end of + // the stream can never hurt, since we can never past that point anyway. + result.pushLimit(len); + } catch (InvalidProtocolBufferException ex) { + // The only reason pushLimit() might throw an exception here is if len + // is negative. Normally pushLimit()'s parameter comes directly off the + // wire, so it's important to catch exceptions in case of corrupt or + // malicious data. However, in this case, we expect that len is not a + // user-supplied value, so we can assume that it being negative indicates + // a programming error. Therefore, throwing an unchecked exception is + // appropriate. + throw new IllegalArgumentException(ex); + } + return result; + } + + // ----------------------------------------------------------------- + + /** + * Attempt to read a field tag, returning zero if we have reached EOF. + * Protocol message parsers use this to read tags, since a protocol message + * may legally end wherever a tag occurs, and zero is not a valid tag number. + */ + public int readTag() throws IOException { + if (isAtEnd()) { + lastTag = 0; + return 0; + } + + lastTag = readRawVarint32(); + if (WireFormat.getTagFieldNumber(lastTag) == 0) { + // If we actually read zero (or any tag number corresponding to field + // number zero), that's not a valid tag. + throw InvalidProtocolBufferException.invalidTag(); + } + return lastTag; + } + + /** + * Verifies that the last call to readTag() returned the given tag value. + * This is used to verify that a nested group ended with the correct + * end tag. + * + * @throws InvalidProtocolBufferException {@code value} does not match the + * last tag. + */ + public void checkLastTagWas(final int value) + throws InvalidProtocolBufferException { + if (lastTag != value) { + throw InvalidProtocolBufferException.invalidEndTag(); + } + } + + /** + * Reads and discards a single field, given its tag value. + * + * @return {@code false} if the tag is an endgroup tag, in which case + * nothing is skipped. Otherwise, returns {@code true}. + */ + public boolean skipField(final int tag) throws IOException { + switch (WireFormat.getTagWireType(tag)) { + case WireFormat.WIRETYPE_VARINT: + readInt32(); + return true; + case WireFormat.WIRETYPE_FIXED64: + readRawLittleEndian64(); + return true; + case WireFormat.WIRETYPE_LENGTH_DELIMITED: + skipRawBytes(readRawVarint32()); + return true; + case WireFormat.WIRETYPE_START_GROUP: + skipMessage(); + checkLastTagWas( + WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), + WireFormat.WIRETYPE_END_GROUP)); + return true; + case WireFormat.WIRETYPE_END_GROUP: + return false; + case WireFormat.WIRETYPE_FIXED32: + readRawLittleEndian32(); + return true; + default: + throw InvalidProtocolBufferException.invalidWireType(); + } + } + + /** + * Reads and discards an entire message. This will read either until EOF + * or until an endgroup tag, whichever comes first. + */ + public void skipMessage() throws IOException { + while (true) { + final int tag = readTag(); + if (tag == 0 || !skipField(tag)) { + return; + } + } + } + + // ----------------------------------------------------------------- + + /** Read a {@code double} field value from the stream. */ + public double readDouble() throws IOException { + return Double.longBitsToDouble(readRawLittleEndian64()); + } + + /** Read a {@code float} field value from the stream. */ + public float readFloat() throws IOException { + return Float.intBitsToFloat(readRawLittleEndian32()); + } + + /** Read a {@code uint64} field value from the stream. */ + public long readUInt64() throws IOException { + return readRawVarint64(); + } + + /** Read an {@code int64} field value from the stream. */ + public long readInt64() throws IOException { + return readRawVarint64(); + } + + /** Read an {@code int32} field value from the stream. */ + public int readInt32() throws IOException { + return readRawVarint32(); + } + + /** Read a {@code fixed64} field value from the stream. */ + public long readFixed64() throws IOException { + return readRawLittleEndian64(); + } + + /** Read a {@code fixed32} field value from the stream. */ + public int readFixed32() throws IOException { + return readRawLittleEndian32(); + } + + /** Read a {@code bool} field value from the stream. */ + public boolean readBool() throws IOException { + return readRawVarint32() != 0; + } + + /** Read a {@code string} field value from the stream. */ + public String readString() throws IOException { + final int size = readRawVarint32(); + if (size <= (bufferSize - bufferPos) && size > 0) { + // Fast path: We already have the bytes in a contiguous buffer, so + // just copy directly from it. + final String result = new String(buffer, bufferPos, size, "UTF-8"); + bufferPos += size; + return result; + } else { + // Slow path: Build a byte array first then copy it. + return new String(readRawBytes(size), "UTF-8"); + } + } + + /** Read a {@code group} field value from the stream. */ + public void readGroup(final int fieldNumber, + final MessageLite.Builder builder, + final ExtensionRegistryLite extensionRegistry) + throws IOException { + if (recursionDepth >= recursionLimit) { + throw InvalidProtocolBufferException.recursionLimitExceeded(); + } + ++recursionDepth; + builder.mergeFrom(this, extensionRegistry); + checkLastTagWas( + WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); + --recursionDepth; + } + + /** Read a {@code group} field value from the stream. */ + public T readGroup( + final int fieldNumber, + final Parser parser, + final ExtensionRegistryLite extensionRegistry) + throws IOException { + if (recursionDepth >= recursionLimit) { + throw InvalidProtocolBufferException.recursionLimitExceeded(); + } + ++recursionDepth; + T result = parser.parsePartialFrom(this, extensionRegistry); + checkLastTagWas( + WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); + --recursionDepth; + return result; + } + + /** + * Reads a {@code group} field value from the stream and merges it into the + * given {@link UnknownFieldSet}. + * + * @deprecated UnknownFieldSet.Builder now implements MessageLite.Builder, so + * you can just call {@link #readGroup}. + */ + @Deprecated + public void readUnknownGroup(final int fieldNumber, + final MessageLite.Builder builder) + throws IOException { + // We know that UnknownFieldSet will ignore any ExtensionRegistry so it + // is safe to pass null here. (We can't call + // ExtensionRegistry.getEmptyRegistry() because that would make this + // class depend on ExtensionRegistry, which is not part of the lite + // library.) + readGroup(fieldNumber, builder, null); + } + + /** Read an embedded message field value from the stream. */ + public void readMessage(final MessageLite.Builder builder, + final ExtensionRegistryLite extensionRegistry) + throws IOException { + final int length = readRawVarint32(); + if (recursionDepth >= recursionLimit) { + throw InvalidProtocolBufferException.recursionLimitExceeded(); + } + final int oldLimit = pushLimit(length); + ++recursionDepth; + builder.mergeFrom(this, extensionRegistry); + checkLastTagWas(0); + --recursionDepth; + popLimit(oldLimit); + } + + /** Read an embedded message field value from the stream. */ + public T readMessage( + final Parser parser, + final ExtensionRegistryLite extensionRegistry) + throws IOException { + int length = readRawVarint32(); + if (recursionDepth >= recursionLimit) { + throw InvalidProtocolBufferException.recursionLimitExceeded(); + } + final int oldLimit = pushLimit(length); + ++recursionDepth; + T result = parser.parsePartialFrom(this, extensionRegistry); + checkLastTagWas(0); + --recursionDepth; + popLimit(oldLimit); + return result; + } + + /** Read a {@code bytes} field value from the stream. */ + public ByteString readBytes() throws IOException { + final int size = readRawVarint32(); + if (size == 0) { + return ByteString.EMPTY; + } else if (size <= (bufferSize - bufferPos) && size > 0) { + // Fast path: We already have the bytes in a contiguous buffer, so + // just copy directly from it. + final ByteString result = ByteString.copyFrom(buffer, bufferPos, size); + bufferPos += size; + return result; + } else { + // Slow path: Build a byte array first then copy it. + return ByteString.copyFrom(readRawBytes(size)); + } + } + + /** Read a {@code uint32} field value from the stream. */ + public int readUInt32() throws IOException { + return readRawVarint32(); + } + + /** + * Read an enum field value from the stream. Caller is responsible + * for converting the numeric value to an actual enum. + */ + public int readEnum() throws IOException { + return readRawVarint32(); + } + + /** Read an {@code sfixed32} field value from the stream. */ + public int readSFixed32() throws IOException { + return readRawLittleEndian32(); + } + + /** Read an {@code sfixed64} field value from the stream. */ + public long readSFixed64() throws IOException { + return readRawLittleEndian64(); + } + + /** Read an {@code sint32} field value from the stream. */ + public int readSInt32() throws IOException { + return decodeZigZag32(readRawVarint32()); + } + + /** Read an {@code sint64} field value from the stream. */ + public long readSInt64() throws IOException { + return decodeZigZag64(readRawVarint64()); + } + + // ================================================================= + + /** + * Read a raw Varint from the stream. If larger than 32 bits, discard the + * upper bits. + */ + public int readRawVarint32() throws IOException { + byte tmp = readRawByte(); + if (tmp >= 0) { + return tmp; + } + int result = tmp & 0x7f; + if ((tmp = readRawByte()) >= 0) { + result |= tmp << 7; + } else { + result |= (tmp & 0x7f) << 7; + if ((tmp = readRawByte()) >= 0) { + result |= tmp << 14; + } else { + result |= (tmp & 0x7f) << 14; + if ((tmp = readRawByte()) >= 0) { + result |= tmp << 21; + } else { + result |= (tmp & 0x7f) << 21; + result |= (tmp = readRawByte()) << 28; + if (tmp < 0) { + // Discard upper 32 bits. + for (int i = 0; i < 5; i++) { + if (readRawByte() >= 0) { + return result; + } + } + throw InvalidProtocolBufferException.malformedVarint(); + } + } + } + } + return result; + } + + /** + * Reads a varint from the input one byte at a time, so that it does not + * read any bytes after the end of the varint. If you simply wrapped the + * stream in a CodedInputStream and used {@link #readRawVarint32(InputStream)} + * then you would probably end up reading past the end of the varint since + * CodedInputStream buffers its input. + */ + static int readRawVarint32(final InputStream input) throws IOException { + final int firstByte = input.read(); + if (firstByte == -1) { + throw InvalidProtocolBufferException.truncatedMessage(); + } + return readRawVarint32(firstByte, input); + } + + /** + * Like {@link #readRawVarint32(InputStream)}, but expects that the caller + * has already read one byte. This allows the caller to determine if EOF + * has been reached before attempting to read. + */ + public static int readRawVarint32( + final int firstByte, final InputStream input) throws IOException { + if ((firstByte & 0x80) == 0) { + return firstByte; + } + + int result = firstByte & 0x7f; + int offset = 7; + for (; offset < 32; offset += 7) { + final int b = input.read(); + if (b == -1) { + throw InvalidProtocolBufferException.truncatedMessage(); + } + result |= (b & 0x7f) << offset; + if ((b & 0x80) == 0) { + return result; + } + } + // Keep reading up to 64 bits. + for (; offset < 64; offset += 7) { + final int b = input.read(); + if (b == -1) { + throw InvalidProtocolBufferException.truncatedMessage(); + } + if ((b & 0x80) == 0) { + return result; + } + } + throw InvalidProtocolBufferException.malformedVarint(); + } + + /** Read a raw Varint from the stream. */ + public long readRawVarint64() throws IOException { + int shift = 0; + long result = 0; + while (shift < 64) { + final byte b = readRawByte(); + result |= (long)(b & 0x7F) << shift; + if ((b & 0x80) == 0) { + return result; + } + shift += 7; + } + throw InvalidProtocolBufferException.malformedVarint(); + } + + /** Read a 32-bit little-endian integer from the stream. */ + public int readRawLittleEndian32() throws IOException { + final byte b1 = readRawByte(); + final byte b2 = readRawByte(); + final byte b3 = readRawByte(); + final byte b4 = readRawByte(); + return (((int)b1 & 0xff) ) | + (((int)b2 & 0xff) << 8) | + (((int)b3 & 0xff) << 16) | + (((int)b4 & 0xff) << 24); + } + + /** Read a 64-bit little-endian integer from the stream. */ + public long readRawLittleEndian64() throws IOException { + final byte b1 = readRawByte(); + final byte b2 = readRawByte(); + final byte b3 = readRawByte(); + final byte b4 = readRawByte(); + final byte b5 = readRawByte(); + final byte b6 = readRawByte(); + final byte b7 = readRawByte(); + final byte b8 = readRawByte(); + return (((long)b1 & 0xff) ) | + (((long)b2 & 0xff) << 8) | + (((long)b3 & 0xff) << 16) | + (((long)b4 & 0xff) << 24) | + (((long)b5 & 0xff) << 32) | + (((long)b6 & 0xff) << 40) | + (((long)b7 & 0xff) << 48) | + (((long)b8 & 0xff) << 56); + } + + /** + * Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers + * into values that can be efficiently encoded with varint. (Otherwise, + * negative values must be sign-extended to 64 bits to be varint encoded, + * thus always taking 10 bytes on the wire.) + * + * @param n An unsigned 32-bit integer, stored in a signed int because + * Java has no explicit unsigned support. + * @return A signed 32-bit integer. + */ + public static int decodeZigZag32(final int n) { + return (n >>> 1) ^ -(n & 1); + } + + /** + * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers + * into values that can be efficiently encoded with varint. (Otherwise, + * negative values must be sign-extended to 64 bits to be varint encoded, + * thus always taking 10 bytes on the wire.) + * + * @param n An unsigned 64-bit integer, stored in a signed int because + * Java has no explicit unsigned support. + * @return A signed 64-bit integer. + */ + public static long decodeZigZag64(final long n) { + return (n >>> 1) ^ -(n & 1); + } + + // ----------------------------------------------------------------- + + private final byte[] buffer; + private int bufferSize; + private int bufferSizeAfterLimit; + private int bufferPos; + private final InputStream input; + private int lastTag; + + /** + * The total number of bytes read before the current buffer. The total + * bytes read up to the current position can be computed as + * {@code totalBytesRetired + bufferPos}. This value may be negative if + * reading started in the middle of the current buffer (e.g. if the + * constructor that takes a byte array and an offset was used). + */ + private int totalBytesRetired; + + /** The absolute position of the end of the current message. */ + private int currentLimit = Integer.MAX_VALUE; + + /** See setRecursionLimit() */ + private int recursionDepth; + private int recursionLimit = DEFAULT_RECURSION_LIMIT; + + /** See setSizeLimit() */ + private int sizeLimit = DEFAULT_SIZE_LIMIT; + + private static final int DEFAULT_RECURSION_LIMIT = 64; + private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB + private static final int BUFFER_SIZE = 4096; + + private CodedInputStream(final byte[] buffer, final int off, final int len) { + this.buffer = buffer; + bufferSize = off + len; + bufferPos = off; + totalBytesRetired = -off; + input = null; + } + + private CodedInputStream(final InputStream input) { + buffer = new byte[BUFFER_SIZE]; + bufferSize = 0; + bufferPos = 0; + totalBytesRetired = 0; + this.input = input; + } + + /** + * Set the maximum message recursion depth. In order to prevent malicious + * messages from causing stack overflows, {@code CodedInputStream} limits + * how deeply messages may be nested. The default limit is 64. + * + * @return the old limit. + */ + public int setRecursionLimit(final int limit) { + if (limit < 0) { + throw new IllegalArgumentException( + "Recursion limit cannot be negative: " + limit); + } + final int oldLimit = recursionLimit; + recursionLimit = limit; + return oldLimit; + } + + /** + * Set the maximum message size. In order to prevent malicious + * messages from exhausting memory or causing integer overflows, + * {@code CodedInputStream} limits how large a message may be. + * The default limit is 64MB. You should set this limit as small + * as you can without harming your app's functionality. Note that + * size limits only apply when reading from an {@code InputStream}, not + * when constructed around a raw byte array (nor with + * {@link ByteString#newCodedInput}). + *

+ * If you want to read several messages from a single CodedInputStream, you + * could call {@link #resetSizeCounter()} after each one to avoid hitting the + * size limit. + * + * @return the old limit. + */ + public int setSizeLimit(final int limit) { + if (limit < 0) { + throw new IllegalArgumentException( + "Size limit cannot be negative: " + limit); + } + final int oldLimit = sizeLimit; + sizeLimit = limit; + return oldLimit; + } + + /** + * Resets the current size counter to zero (see {@link #setSizeLimit(int)}). + */ + public void resetSizeCounter() { + totalBytesRetired = -bufferPos; + } + + /** + * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This + * is called when descending into a length-delimited embedded message. + * + *

Note that {@code pushLimit()} does NOT affect how many bytes the + * {@code CodedInputStream} reads from an underlying {@code InputStream} when + * refreshing its buffer. If you need to prevent reading past a certain + * point in the underlying {@code InputStream} (e.g. because you expect it to + * contain more data after the end of the message which you need to handle + * differently) then you must place a wrapper around your {@code InputStream} + * which limits the amount of data that can be read from it. + * + * @return the old limit. + */ + public int pushLimit(int byteLimit) throws InvalidProtocolBufferException { + if (byteLimit < 0) { + throw InvalidProtocolBufferException.negativeSize(); + } + byteLimit += totalBytesRetired + bufferPos; + final int oldLimit = currentLimit; + if (byteLimit > oldLimit) { + throw InvalidProtocolBufferException.truncatedMessage(); + } + currentLimit = byteLimit; + + recomputeBufferSizeAfterLimit(); + + return oldLimit; + } + + private void recomputeBufferSizeAfterLimit() { + bufferSize += bufferSizeAfterLimit; + final int bufferEnd = totalBytesRetired + bufferSize; + if (bufferEnd > currentLimit) { + // Limit is in current buffer. + bufferSizeAfterLimit = bufferEnd - currentLimit; + bufferSize -= bufferSizeAfterLimit; + } else { + bufferSizeAfterLimit = 0; + } + } + + /** + * Discards the current limit, returning to the previous limit. + * + * @param oldLimit The old limit, as returned by {@code pushLimit}. + */ + public void popLimit(final int oldLimit) { + currentLimit = oldLimit; + recomputeBufferSizeAfterLimit(); + } + + /** + * Returns the number of bytes to be read before the current limit. + * If no limit is set, returns -1. + */ + public int getBytesUntilLimit() { + if (currentLimit == Integer.MAX_VALUE) { + return -1; + } + + final int currentAbsolutePosition = totalBytesRetired + bufferPos; + return currentLimit - currentAbsolutePosition; + } + + /** + * Returns true if the stream has reached the end of the input. This is the + * case if either the end of the underlying input source has been reached or + * if the stream has reached a limit created using {@link #pushLimit(int)}. + */ + public boolean isAtEnd() throws IOException { + return bufferPos == bufferSize && !refillBuffer(false); + } + + /** + * The total bytes read up to the current position. Calling + * {@link #resetSizeCounter()} resets this value to zero. + */ + public int getTotalBytesRead() { + return totalBytesRetired + bufferPos; + } + + /** + * Called with {@code this.buffer} is empty to read more bytes from the + * input. If {@code mustSucceed} is true, refillBuffer() guarantees that + * either there will be at least one byte in the buffer when it returns + * or it will throw an exception. If {@code mustSucceed} is false, + * refillBuffer() returns false if no more bytes were available. + */ + private boolean refillBuffer(final boolean mustSucceed) throws IOException { + if (bufferPos < bufferSize) { + throw new IllegalStateException( + "refillBuffer() called when buffer wasn't empty."); + } + + if (totalBytesRetired + bufferSize == currentLimit) { + // Oops, we hit a limit. + if (mustSucceed) { + throw InvalidProtocolBufferException.truncatedMessage(); + } else { + return false; + } + } + + totalBytesRetired += bufferSize; + + bufferPos = 0; + bufferSize = (input == null) ? -1 : input.read(buffer); + if (bufferSize == 0 || bufferSize < -1) { + throw new IllegalStateException( + "InputStream#read(byte[]) returned invalid result: " + bufferSize + + "\nThe InputStream implementation is buggy."); + } + if (bufferSize == -1) { + bufferSize = 0; + if (mustSucceed) { + throw InvalidProtocolBufferException.truncatedMessage(); + } else { + return false; + } + } else { + recomputeBufferSizeAfterLimit(); + final int totalBytesRead = + totalBytesRetired + bufferSize + bufferSizeAfterLimit; + if (totalBytesRead > sizeLimit || totalBytesRead < 0) { + throw InvalidProtocolBufferException.sizeLimitExceeded(); + } + return true; + } + } + + /** + * Read one byte from the input. + * + * @throws InvalidProtocolBufferException The end of the stream or the current + * limit was reached. + */ + public byte readRawByte() throws IOException { + if (bufferPos == bufferSize) { + refillBuffer(true); + } + return buffer[bufferPos++]; + } + + /** + * Read a fixed size of bytes from the input. + * + * @throws InvalidProtocolBufferException The end of the stream or the current + * limit was reached. + */ + public byte[] readRawBytes(final int size) throws IOException { + if (size < 0) { + throw InvalidProtocolBufferException.negativeSize(); + } + + if (totalBytesRetired + bufferPos + size > currentLimit) { + // Read to the end of the stream anyway. + skipRawBytes(currentLimit - totalBytesRetired - bufferPos); + // Then fail. + throw InvalidProtocolBufferException.truncatedMessage(); + } + + if (size <= bufferSize - bufferPos) { + // We have all the bytes we need already. + final byte[] bytes = new byte[size]; + System.arraycopy(buffer, bufferPos, bytes, 0, size); + bufferPos += size; + return bytes; + } else if (size < BUFFER_SIZE) { + // Reading more bytes than are in the buffer, but not an excessive number + // of bytes. We can safely allocate the resulting array ahead of time. + + // First copy what we have. + final byte[] bytes = new byte[size]; + int pos = bufferSize - bufferPos; + System.arraycopy(buffer, bufferPos, bytes, 0, pos); + bufferPos = bufferSize; + + // We want to use refillBuffer() and then copy from the buffer into our + // byte array rather than reading directly into our byte array because + // the input may be unbuffered. + refillBuffer(true); + + while (size - pos > bufferSize) { + System.arraycopy(buffer, 0, bytes, pos, bufferSize); + pos += bufferSize; + bufferPos = bufferSize; + refillBuffer(true); + } + + System.arraycopy(buffer, 0, bytes, pos, size - pos); + bufferPos = size - pos; + + return bytes; + } else { + // The size is very large. For security reasons, we can't allocate the + // entire byte array yet. The size comes directly from the input, so a + // maliciously-crafted message could provide a bogus very large size in + // order to trick the app into allocating a lot of memory. We avoid this + // by allocating and reading only a small chunk at a time, so that the + // malicious message must actually *be* extremely large to cause + // problems. Meanwhile, we limit the allowed size of a message elsewhere. + + // Remember the buffer markers since we'll have to copy the bytes out of + // it later. + final int originalBufferPos = bufferPos; + final int originalBufferSize = bufferSize; + + // Mark the current buffer consumed. + totalBytesRetired += bufferSize; + bufferPos = 0; + bufferSize = 0; + + // Read all the rest of the bytes we need. + int sizeLeft = size - (originalBufferSize - originalBufferPos); + final List chunks = new ArrayList(); + + while (sizeLeft > 0) { + final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)]; + int pos = 0; + while (pos < chunk.length) { + final int n = (input == null) ? -1 : + input.read(chunk, pos, chunk.length - pos); + if (n == -1) { + throw InvalidProtocolBufferException.truncatedMessage(); + } + totalBytesRetired += n; + pos += n; + } + sizeLeft -= chunk.length; + chunks.add(chunk); + } + + // OK, got everything. Now concatenate it all into one buffer. + final byte[] bytes = new byte[size]; + + // Start by copying the leftover bytes from this.buffer. + int pos = originalBufferSize - originalBufferPos; + System.arraycopy(buffer, originalBufferPos, bytes, 0, pos); + + // And now all the chunks. + for (final byte[] chunk : chunks) { + System.arraycopy(chunk, 0, bytes, pos, chunk.length); + pos += chunk.length; + } + + // Done. + return bytes; + } + } + + /** + * Reads and discards {@code size} bytes. + * + * @throws InvalidProtocolBufferException The end of the stream or the current + * limit was reached. + */ + public void skipRawBytes(final int size) throws IOException { + if (size < 0) { + throw InvalidProtocolBufferException.negativeSize(); + } + + if (totalBytesRetired + bufferPos + size > currentLimit) { + // Read to the end of the stream anyway. + skipRawBytes(currentLimit - totalBytesRetired - bufferPos); + // Then fail. + throw InvalidProtocolBufferException.truncatedMessage(); + } + + if (size <= bufferSize - bufferPos) { + // We have all the bytes we need already. + bufferPos += size; + } else { + // Skipping more bytes than are in the buffer. First skip what we have. + int pos = bufferSize - bufferPos; + bufferPos = bufferSize; + + // Keep refilling the buffer until we get to the point we wanted to skip + // to. This has the side effect of ensuring the limits are updated + // correctly. + refillBuffer(true); + while (size - pos > bufferSize) { + pos += bufferSize; + bufferPos = bufferSize; + refillBuffer(true); + } + + bufferPos = size - pos; + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/CodedOutputStream.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/CodedOutputStream.java new file mode 100644 index 0000000..ca24638 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/CodedOutputStream.java @@ -0,0 +1,1111 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +/** + * Encodes and writes protocol message fields. + * + *

This class contains two kinds of methods: methods that write specific + * protocol message constructs and field types (e.g. {@link #writeTag} and + * {@link #writeInt32}) and methods that write low-level values (e.g. + * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are + * writing encoded protocol messages, you should use the former methods, but if + * you are writing some other format of your own design, use the latter. + * + *

This class is totally unsynchronized. + * + * @author kneton@google.com Kenton Varda + */ +public final class CodedOutputStream { + private final byte[] buffer; + private final int limit; + private int position; + + private final OutputStream output; + + /** + * The buffer size used in {@link #newInstance(OutputStream)}. + */ + public static final int DEFAULT_BUFFER_SIZE = 4096; + + /** + * Returns the buffer size to efficiently write dataLength bytes to this + * CodedOutputStream. Used by AbstractMessageLite. + * + * @return the buffer size to efficiently write dataLength bytes to this + * CodedOutputStream. + */ + static int computePreferredBufferSize(int dataLength) { + if (dataLength > DEFAULT_BUFFER_SIZE) return DEFAULT_BUFFER_SIZE; + return dataLength; + } + + private CodedOutputStream(final byte[] buffer, final int offset, + final int length) { + output = null; + this.buffer = buffer; + position = offset; + limit = offset + length; + } + + private CodedOutputStream(final OutputStream output, final byte[] buffer) { + this.output = output; + this.buffer = buffer; + position = 0; + limit = buffer.length; + } + + /** + * Create a new {@code CodedOutputStream} wrapping the given + * {@code OutputStream}. + */ + public static CodedOutputStream newInstance(final OutputStream output) { + return newInstance(output, DEFAULT_BUFFER_SIZE); + } + + /** + * Create a new {@code CodedOutputStream} wrapping the given + * {@code OutputStream} with a given buffer size. + */ + public static CodedOutputStream newInstance(final OutputStream output, + final int bufferSize) { + return new CodedOutputStream(output, new byte[bufferSize]); + } + + /** + * Create a new {@code CodedOutputStream} that writes directly to the given + * byte array. If more bytes are written than fit in the array, + * {@link OutOfSpaceException} will be thrown. Writing directly to a flat + * array is faster than writing to an {@code OutputStream}. See also + * {@link ByteString#newCodedBuilder}. + */ + public static CodedOutputStream newInstance(final byte[] flatArray) { + return newInstance(flatArray, 0, flatArray.length); + } + + /** + * Create a new {@code CodedOutputStream} that writes directly to the given + * byte array slice. If more bytes are written than fit in the slice, + * {@link OutOfSpaceException} will be thrown. Writing directly to a flat + * array is faster than writing to an {@code OutputStream}. See also + * {@link ByteString#newCodedBuilder}. + */ + public static CodedOutputStream newInstance(final byte[] flatArray, + final int offset, + final int length) { + return new CodedOutputStream(flatArray, offset, length); + } + + // ----------------------------------------------------------------- + + /** Write a {@code double} field, including tag, to the stream. */ + public void writeDouble(final int fieldNumber, final double value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64); + writeDoubleNoTag(value); + } + + /** Write a {@code float} field, including tag, to the stream. */ + public void writeFloat(final int fieldNumber, final float value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32); + writeFloatNoTag(value); + } + + /** Write a {@code uint64} field, including tag, to the stream. */ + public void writeUInt64(final int fieldNumber, final long value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); + writeUInt64NoTag(value); + } + + /** Write an {@code int64} field, including tag, to the stream. */ + public void writeInt64(final int fieldNumber, final long value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); + writeInt64NoTag(value); + } + + /** Write an {@code int32} field, including tag, to the stream. */ + public void writeInt32(final int fieldNumber, final int value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); + writeInt32NoTag(value); + } + + /** Write a {@code fixed64} field, including tag, to the stream. */ + public void writeFixed64(final int fieldNumber, final long value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64); + writeFixed64NoTag(value); + } + + /** Write a {@code fixed32} field, including tag, to the stream. */ + public void writeFixed32(final int fieldNumber, final int value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32); + writeFixed32NoTag(value); + } + + /** Write a {@code bool} field, including tag, to the stream. */ + public void writeBool(final int fieldNumber, final boolean value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); + writeBoolNoTag(value); + } + + /** Write a {@code string} field, including tag, to the stream. */ + public void writeString(final int fieldNumber, final String value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED); + writeStringNoTag(value); + } + + /** Write a {@code group} field, including tag, to the stream. */ + public void writeGroup(final int fieldNumber, final MessageLite value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP); + writeGroupNoTag(value); + writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP); + } + + /** + * Write a group represented by an {@link UnknownFieldSet}. + * + * @deprecated UnknownFieldSet now implements MessageLite, so you can just + * call {@link #writeGroup}. + */ + @Deprecated + public void writeUnknownGroup(final int fieldNumber, + final MessageLite value) + throws IOException { + writeGroup(fieldNumber, value); + } + + /** Write an embedded message field, including tag, to the stream. */ + public void writeMessage(final int fieldNumber, final MessageLite value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED); + writeMessageNoTag(value); + } + + /** Write a {@code bytes} field, including tag, to the stream. */ + public void writeBytes(final int fieldNumber, final ByteString value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED); + writeBytesNoTag(value); + } + + /** Write a {@code uint32} field, including tag, to the stream. */ + public void writeUInt32(final int fieldNumber, final int value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); + writeUInt32NoTag(value); + } + + /** + * Write an enum field, including tag, to the stream. Caller is responsible + * for converting the enum value to its numeric value. + */ + public void writeEnum(final int fieldNumber, final int value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); + writeEnumNoTag(value); + } + + /** Write an {@code sfixed32} field, including tag, to the stream. */ + public void writeSFixed32(final int fieldNumber, final int value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32); + writeSFixed32NoTag(value); + } + + /** Write an {@code sfixed64} field, including tag, to the stream. */ + public void writeSFixed64(final int fieldNumber, final long value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64); + writeSFixed64NoTag(value); + } + + /** Write an {@code sint32} field, including tag, to the stream. */ + public void writeSInt32(final int fieldNumber, final int value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); + writeSInt32NoTag(value); + } + + /** Write an {@code sint64} field, including tag, to the stream. */ + public void writeSInt64(final int fieldNumber, final long value) + throws IOException { + writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); + writeSInt64NoTag(value); + } + + /** + * Write a MessageSet extension field to the stream. For historical reasons, + * the wire format differs from normal fields. + */ + public void writeMessageSetExtension(final int fieldNumber, + final MessageLite value) + throws IOException { + writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP); + writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber); + writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value); + writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP); + } + + /** + * Write an unparsed MessageSet extension field to the stream. For + * historical reasons, the wire format differs from normal fields. + */ + public void writeRawMessageSetExtension(final int fieldNumber, + final ByteString value) + throws IOException { + writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP); + writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber); + writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value); + writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP); + } + + // ----------------------------------------------------------------- + + /** Write a {@code double} field to the stream. */ + public void writeDoubleNoTag(final double value) throws IOException { + writeRawLittleEndian64(Double.doubleToRawLongBits(value)); + } + + /** Write a {@code float} field to the stream. */ + public void writeFloatNoTag(final float value) throws IOException { + writeRawLittleEndian32(Float.floatToRawIntBits(value)); + } + + /** Write a {@code uint64} field to the stream. */ + public void writeUInt64NoTag(final long value) throws IOException { + writeRawVarint64(value); + } + + /** Write an {@code int64} field to the stream. */ + public void writeInt64NoTag(final long value) throws IOException { + writeRawVarint64(value); + } + + /** Write an {@code int32} field to the stream. */ + public void writeInt32NoTag(final int value) throws IOException { + if (value >= 0) { + writeRawVarint32(value); + } else { + // Must sign-extend. + writeRawVarint64(value); + } + } + + /** Write a {@code fixed64} field to the stream. */ + public void writeFixed64NoTag(final long value) throws IOException { + writeRawLittleEndian64(value); + } + + /** Write a {@code fixed32} field to the stream. */ + public void writeFixed32NoTag(final int value) throws IOException { + writeRawLittleEndian32(value); + } + + /** Write a {@code bool} field to the stream. */ + public void writeBoolNoTag(final boolean value) throws IOException { + writeRawByte(value ? 1 : 0); + } + + /** Write a {@code string} field to the stream. */ + public void writeStringNoTag(final String value) throws IOException { + // Unfortunately there does not appear to be any way to tell Java to encode + // UTF-8 directly into our buffer, so we have to let it create its own byte + // array and then copy. + final byte[] bytes = value.getBytes("UTF-8"); + writeRawVarint32(bytes.length); + writeRawBytes(bytes); + } + + /** Write a {@code group} field to the stream. */ + public void writeGroupNoTag(final MessageLite value) throws IOException { + value.writeTo(this); + } + + /** + * Write a group represented by an {@link UnknownFieldSet}. + * + * @deprecated UnknownFieldSet now implements MessageLite, so you can just + * call {@link #writeGroupNoTag}. + */ + @Deprecated + public void writeUnknownGroupNoTag(final MessageLite value) + throws IOException { + writeGroupNoTag(value); + } + + /** Write an embedded message field to the stream. */ + public void writeMessageNoTag(final MessageLite value) throws IOException { + writeRawVarint32(value.getSerializedSize()); + value.writeTo(this); + } + + /** Write a {@code bytes} field to the stream. */ + public void writeBytesNoTag(final ByteString value) throws IOException { + writeRawVarint32(value.size()); + writeRawBytes(value); + } + + /** Write a {@code uint32} field to the stream. */ + public void writeUInt32NoTag(final int value) throws IOException { + writeRawVarint32(value); + } + + /** + * Write an enum field to the stream. Caller is responsible + * for converting the enum value to its numeric value. + */ + public void writeEnumNoTag(final int value) throws IOException { + writeInt32NoTag(value); + } + + /** Write an {@code sfixed32} field to the stream. */ + public void writeSFixed32NoTag(final int value) throws IOException { + writeRawLittleEndian32(value); + } + + /** Write an {@code sfixed64} field to the stream. */ + public void writeSFixed64NoTag(final long value) throws IOException { + writeRawLittleEndian64(value); + } + + /** Write an {@code sint32} field to the stream. */ + public void writeSInt32NoTag(final int value) throws IOException { + writeRawVarint32(encodeZigZag32(value)); + } + + /** Write an {@code sint64} field to the stream. */ + public void writeSInt64NoTag(final long value) throws IOException { + writeRawVarint64(encodeZigZag64(value)); + } + + // ================================================================= + + /** + * Compute the number of bytes that would be needed to encode a + * {@code double} field, including tag. + */ + public static int computeDoubleSize(final int fieldNumber, + final double value) { + return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code float} field, including tag. + */ + public static int computeFloatSize(final int fieldNumber, final float value) { + return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code uint64} field, including tag. + */ + public static int computeUInt64Size(final int fieldNumber, final long value) { + return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code int64} field, including tag. + */ + public static int computeInt64Size(final int fieldNumber, final long value) { + return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code int32} field, including tag. + */ + public static int computeInt32Size(final int fieldNumber, final int value) { + return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code fixed64} field, including tag. + */ + public static int computeFixed64Size(final int fieldNumber, + final long value) { + return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code fixed32} field, including tag. + */ + public static int computeFixed32Size(final int fieldNumber, + final int value) { + return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code bool} field, including tag. + */ + public static int computeBoolSize(final int fieldNumber, + final boolean value) { + return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code string} field, including tag. + */ + public static int computeStringSize(final int fieldNumber, + final String value) { + return computeTagSize(fieldNumber) + computeStringSizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code group} field, including tag. + */ + public static int computeGroupSize(final int fieldNumber, + final MessageLite value) { + return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code group} field represented by an {@code UnknownFieldSet}, including + * tag. + * + * @deprecated UnknownFieldSet now implements MessageLite, so you can just + * call {@link #computeGroupSize}. + */ + @Deprecated + public static int computeUnknownGroupSize(final int fieldNumber, + final MessageLite value) { + return computeGroupSize(fieldNumber, value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * embedded message field, including tag. + */ + public static int computeMessageSize(final int fieldNumber, + final MessageLite value) { + return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code bytes} field, including tag. + */ + public static int computeBytesSize(final int fieldNumber, + final ByteString value) { + return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * embedded message in lazy field, including tag. + */ + public static int computeLazyFieldSize(final int fieldNumber, + final LazyField value) { + return computeTagSize(fieldNumber) + computeLazyFieldSizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code uint32} field, including tag. + */ + public static int computeUInt32Size(final int fieldNumber, final int value) { + return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * enum field, including tag. Caller is responsible for converting the + * enum value to its numeric value. + */ + public static int computeEnumSize(final int fieldNumber, final int value) { + return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code sfixed32} field, including tag. + */ + public static int computeSFixed32Size(final int fieldNumber, + final int value) { + return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code sfixed64} field, including tag. + */ + public static int computeSFixed64Size(final int fieldNumber, + final long value) { + return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code sint32} field, including tag. + */ + public static int computeSInt32Size(final int fieldNumber, final int value) { + return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code sint64} field, including tag. + */ + public static int computeSInt64Size(final int fieldNumber, final long value) { + return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * MessageSet extension to the stream. For historical reasons, + * the wire format differs from normal fields. + */ + public static int computeMessageSetExtensionSize( + final int fieldNumber, final MessageLite value) { + return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 + + computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) + + computeMessageSize(WireFormat.MESSAGE_SET_MESSAGE, value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * unparsed MessageSet extension field to the stream. For + * historical reasons, the wire format differs from normal fields. + */ + public static int computeRawMessageSetExtensionSize( + final int fieldNumber, final ByteString value) { + return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 + + computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) + + computeBytesSize(WireFormat.MESSAGE_SET_MESSAGE, value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * lazily parsed MessageSet extension field to the stream. For + * historical reasons, the wire format differs from normal fields. + */ + public static int computeLazyFieldMessageSetExtensionSize( + final int fieldNumber, final LazyField value) { + return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 + + computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) + + computeLazyFieldSize(WireFormat.MESSAGE_SET_MESSAGE, value); + } + + // ----------------------------------------------------------------- + + /** + * Compute the number of bytes that would be needed to encode a + * {@code double} field, including tag. + */ + public static int computeDoubleSizeNoTag(final double value) { + return LITTLE_ENDIAN_64_SIZE; + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code float} field, including tag. + */ + public static int computeFloatSizeNoTag(final float value) { + return LITTLE_ENDIAN_32_SIZE; + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code uint64} field, including tag. + */ + public static int computeUInt64SizeNoTag(final long value) { + return computeRawVarint64Size(value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code int64} field, including tag. + */ + public static int computeInt64SizeNoTag(final long value) { + return computeRawVarint64Size(value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code int32} field, including tag. + */ + public static int computeInt32SizeNoTag(final int value) { + if (value >= 0) { + return computeRawVarint32Size(value); + } else { + // Must sign-extend. + return 10; + } + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code fixed64} field. + */ + public static int computeFixed64SizeNoTag(final long value) { + return LITTLE_ENDIAN_64_SIZE; + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code fixed32} field. + */ + public static int computeFixed32SizeNoTag(final int value) { + return LITTLE_ENDIAN_32_SIZE; + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code bool} field. + */ + public static int computeBoolSizeNoTag(final boolean value) { + return 1; + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code string} field. + */ + public static int computeStringSizeNoTag(final String value) { + try { + final byte[] bytes = value.getBytes("UTF-8"); + return computeRawVarint32Size(bytes.length) + + bytes.length; + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("UTF-8 not supported.", e); + } + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code group} field. + */ + public static int computeGroupSizeNoTag(final MessageLite value) { + return value.getSerializedSize(); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code group} field represented by an {@code UnknownFieldSet}, including + * tag. + * + * @deprecated UnknownFieldSet now implements MessageLite, so you can just + * call {@link #computeUnknownGroupSizeNoTag}. + */ + @Deprecated + public static int computeUnknownGroupSizeNoTag(final MessageLite value) { + return computeGroupSizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode an embedded + * message field. + */ + public static int computeMessageSizeNoTag(final MessageLite value) { + final int size = value.getSerializedSize(); + return computeRawVarint32Size(size) + size; + } + + /** + * Compute the number of bytes that would be needed to encode an embedded + * message stored in lazy field. + */ + public static int computeLazyFieldSizeNoTag(final LazyField value) { + final int size = value.getSerializedSize(); + return computeRawVarint32Size(size) + size; + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code bytes} field. + */ + public static int computeBytesSizeNoTag(final ByteString value) { + return computeRawVarint32Size(value.size()) + + value.size(); + } + + /** + * Compute the number of bytes that would be needed to encode a + * {@code uint32} field. + */ + public static int computeUInt32SizeNoTag(final int value) { + return computeRawVarint32Size(value); + } + + /** + * Compute the number of bytes that would be needed to encode an enum field. + * Caller is responsible for converting the enum value to its numeric value. + */ + public static int computeEnumSizeNoTag(final int value) { + return computeInt32SizeNoTag(value); + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code sfixed32} field. + */ + public static int computeSFixed32SizeNoTag(final int value) { + return LITTLE_ENDIAN_32_SIZE; + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code sfixed64} field. + */ + public static int computeSFixed64SizeNoTag(final long value) { + return LITTLE_ENDIAN_64_SIZE; + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code sint32} field. + */ + public static int computeSInt32SizeNoTag(final int value) { + return computeRawVarint32Size(encodeZigZag32(value)); + } + + /** + * Compute the number of bytes that would be needed to encode an + * {@code sint64} field. + */ + public static int computeSInt64SizeNoTag(final long value) { + return computeRawVarint64Size(encodeZigZag64(value)); + } + + // ================================================================= + + /** + * Internal helper that writes the current buffer to the output. The + * buffer position is reset to its initial value when this returns. + */ + private void refreshBuffer() throws IOException { + if (output == null) { + // We're writing to a single buffer. + throw new OutOfSpaceException(); + } + + // Since we have an output stream, this is our buffer + // and buffer offset == 0 + output.write(buffer, 0, position); + position = 0; + } + + /** + * Flushes the stream and forces any buffered bytes to be written. This + * does not flush the underlying OutputStream. + */ + public void flush() throws IOException { + if (output != null) { + refreshBuffer(); + } + } + + /** + * If writing to a flat array, return the space left in the array. + * Otherwise, throws {@code UnsupportedOperationException}. + */ + public int spaceLeft() { + if (output == null) { + return limit - position; + } else { + throw new UnsupportedOperationException( + "spaceLeft() can only be called on CodedOutputStreams that are " + + "writing to a flat array."); + } + } + + /** + * Verifies that {@link #spaceLeft()} returns zero. It's common to create + * a byte array that is exactly big enough to hold a message, then write to + * it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()} + * after writing verifies that the message was actually as big as expected, + * which can help catch bugs. + */ + public void checkNoSpaceLeft() { + if (spaceLeft() != 0) { + throw new IllegalStateException( + "Did not write as much data as expected."); + } + } + + /** + * If you create a CodedOutputStream around a simple flat array, you must + * not attempt to write more bytes than the array has space. Otherwise, + * this exception will be thrown. + */ + public static class OutOfSpaceException extends IOException { + private static final long serialVersionUID = -6947486886997889499L; + + OutOfSpaceException() { + super("CodedOutputStream was writing to a flat byte array and ran " + + "out of space."); + } + } + + /** Write a single byte. */ + public void writeRawByte(final byte value) throws IOException { + if (position == limit) { + refreshBuffer(); + } + + buffer[position++] = value; + } + + /** Write a single byte, represented by an integer value. */ + public void writeRawByte(final int value) throws IOException { + writeRawByte((byte) value); + } + + /** Write a byte string. */ + public void writeRawBytes(final ByteString value) throws IOException { + writeRawBytes(value, 0, value.size()); + } + + /** Write an array of bytes. */ + public void writeRawBytes(final byte[] value) throws IOException { + writeRawBytes(value, 0, value.length); + } + + /** Write part of an array of bytes. */ + public void writeRawBytes(final byte[] value, int offset, int length) + throws IOException { + if (limit - position >= length) { + // We have room in the current buffer. + System.arraycopy(value, offset, buffer, position, length); + position += length; + } else { + // Write extends past current buffer. Fill the rest of this buffer and + // flush. + final int bytesWritten = limit - position; + System.arraycopy(value, offset, buffer, position, bytesWritten); + offset += bytesWritten; + length -= bytesWritten; + position = limit; + refreshBuffer(); + + // Now deal with the rest. + // Since we have an output stream, this is our buffer + // and buffer offset == 0 + if (length <= limit) { + // Fits in new buffer. + System.arraycopy(value, offset, buffer, 0, length); + position = length; + } else { + // Write is very big. Let's do it all at once. + output.write(value, offset, length); + } + } + } + + /** Write part of a byte string. */ + public void writeRawBytes(final ByteString value, int offset, int length) + throws IOException { + if (limit - position >= length) { + // We have room in the current buffer. + value.copyTo(buffer, offset, position, length); + position += length; + } else { + // Write extends past current buffer. Fill the rest of this buffer and + // flush. + final int bytesWritten = limit - position; + value.copyTo(buffer, offset, position, bytesWritten); + offset += bytesWritten; + length -= bytesWritten; + position = limit; + refreshBuffer(); + + // Now deal with the rest. + // Since we have an output stream, this is our buffer + // and buffer offset == 0 + if (length <= limit) { + // Fits in new buffer. + value.copyTo(buffer, offset, 0, length); + position = length; + } else { + // Write is very big, but we can't do it all at once without allocating + // an a copy of the byte array since ByteString does not give us access + // to the underlying bytes. Use the InputStream interface on the + // ByteString and our buffer to copy between the two. + InputStream inputStreamFrom = value.newInput(); + if (offset != inputStreamFrom.skip(offset)) { + throw new IllegalStateException("Skip failed? Should never happen."); + } + // Use the buffer as the temporary buffer to avoid allocating memory. + while (length > 0) { + int bytesToRead = Math.min(length, limit); + int bytesRead = inputStreamFrom.read(buffer, 0, bytesToRead); + if (bytesRead != bytesToRead) { + throw new IllegalStateException("Read failed? Should never happen"); + } + output.write(buffer, 0, bytesRead); + length -= bytesRead; + } + } + } + } + + /** Encode and write a tag. */ + public void writeTag(final int fieldNumber, final int wireType) + throws IOException { + writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType)); + } + + /** Compute the number of bytes that would be needed to encode a tag. */ + public static int computeTagSize(final int fieldNumber) { + return computeRawVarint32Size(WireFormat.makeTag(fieldNumber, 0)); + } + + /** + * Encode and write a varint. {@code value} is treated as + * unsigned, so it won't be sign-extended if negative. + */ + public void writeRawVarint32(int value) throws IOException { + while (true) { + if ((value & ~0x7F) == 0) { + writeRawByte(value); + return; + } else { + writeRawByte((value & 0x7F) | 0x80); + value >>>= 7; + } + } + } + + /** + * Compute the number of bytes that would be needed to encode a varint. + * {@code value} is treated as unsigned, so it won't be sign-extended if + * negative. + */ + public static int computeRawVarint32Size(final int 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; + } + + /** Encode and write a varint. */ + public void writeRawVarint64(long value) throws IOException { + while (true) { + if ((value & ~0x7FL) == 0) { + writeRawByte((int)value); + return; + } else { + writeRawByte(((int)value & 0x7F) | 0x80); + value >>>= 7; + } + } + } + + /** Compute the number of bytes that would be needed to encode a varint. */ + public static int computeRawVarint64Size(final long 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; + } + + /** Write a little-endian 32-bit integer. */ + public void writeRawLittleEndian32(final int value) throws IOException { + writeRawByte((value ) & 0xFF); + writeRawByte((value >> 8) & 0xFF); + writeRawByte((value >> 16) & 0xFF); + writeRawByte((value >> 24) & 0xFF); + } + + public static final int LITTLE_ENDIAN_32_SIZE = 4; + + /** Write a little-endian 64-bit integer. */ + public void writeRawLittleEndian64(final long value) throws IOException { + writeRawByte((int)(value ) & 0xFF); + writeRawByte((int)(value >> 8) & 0xFF); + writeRawByte((int)(value >> 16) & 0xFF); + writeRawByte((int)(value >> 24) & 0xFF); + writeRawByte((int)(value >> 32) & 0xFF); + writeRawByte((int)(value >> 40) & 0xFF); + writeRawByte((int)(value >> 48) & 0xFF); + writeRawByte((int)(value >> 56) & 0xFF); + } + + public static final int LITTLE_ENDIAN_64_SIZE = 8; + + /** + * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers + * into values that can be efficiently encoded with varint. (Otherwise, + * negative values must be sign-extended to 64 bits to be varint encoded, + * thus always taking 10 bytes on the wire.) + * + * @param n A signed 32-bit integer. + * @return An unsigned 32-bit integer, stored in a signed int because + * Java has no explicit unsigned support. + */ + public static int encodeZigZag32(final int n) { + // Note: the right-shift must be arithmetic + return (n << 1) ^ (n >> 31); + } + + /** + * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers + * into values that can be efficiently encoded with varint. (Otherwise, + * negative values must be sign-extended to 64 bits to be varint encoded, + * thus always taking 10 bytes on the wire.) + * + * @param n A signed 64-bit integer. + * @return An unsigned 64-bit integer, stored in a signed int because + * Java has no explicit unsigned support. + */ + public static long encodeZigZag64(final long n) { + // Note: the right-shift must be arithmetic + return (n << 1) ^ (n >> 63); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Descriptors.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Descriptors.java new file mode 100644 index 0000000..a491305 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Descriptors.java @@ -0,0 +1,1970 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.DescriptorProtos.*; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.io.UnsupportedEncodingException; + +/** + * Contains a collection of classes which describe protocol message types. + * + * Every message type has a {@link Descriptor}, which lists all + * its fields and other information about a type. You can get a message + * type's descriptor by calling {@code MessageType.getDescriptor()}, or + * (given a message object of the type) {@code message.getDescriptorForType()}. + * Furthermore, each message is associated with a {@link FileDescriptor} for + * a relevant {@code .proto} file. You can obtain it by calling + * {@code Descriptor.getFile()}. A {@link FileDescriptor} contains descriptors + * for all the messages defined in that file, and file descriptors for all the + * imported {@code .proto} files. + * + * Descriptors are built from DescriptorProtos, as defined in + * {@code google/protobuf/descriptor.proto}. + * + * @author kenton@google.com Kenton Varda + */ +public final class Descriptors { + /** + * Describes a {@code .proto} file, including everything defined within. + * That includes, in particular, descriptors for all the messages and + * file descriptors for all other imported {@code .proto} files + * (dependencies). + */ + public static final class FileDescriptor { + /** Convert the descriptor to its protocol message representation. */ + public FileDescriptorProto toProto() { return proto; } + + /** Get the file name. */ + public String getName() { return proto.getName(); } + + /** + * Get the proto package name. This is the package name given by the + * {@code package} statement in the {@code .proto} file, which differs + * from the Java package. + */ + public String getPackage() { return proto.getPackage(); } + + /** Get the {@code FileOptions}, defined in {@code descriptor.proto}. */ + public FileOptions getOptions() { return proto.getOptions(); } + + /** Get a list of top-level message types declared in this file. */ + public List getMessageTypes() { + return Collections.unmodifiableList(Arrays.asList(messageTypes)); + } + + /** Get a list of top-level enum types declared in this file. */ + public List getEnumTypes() { + return Collections.unmodifiableList(Arrays.asList(enumTypes)); + } + + /** Get a list of top-level services declared in this file. */ + public List getServices() { + return Collections.unmodifiableList(Arrays.asList(services)); + } + + /** Get a list of top-level extensions declared in this file. */ + public List getExtensions() { + return Collections.unmodifiableList(Arrays.asList(extensions)); + } + + /** Get a list of this file's dependencies (imports). */ + public List getDependencies() { + return Collections.unmodifiableList(Arrays.asList(dependencies)); + } + + /** Get a list of this file's public dependencies (public imports). */ + public List getPublicDependencies() { + return Collections.unmodifiableList(Arrays.asList(publicDependencies)); + } + + /** + * Find a message type in the file by name. Does not find nested types. + * + * @param name The unqualified type name to look for. + * @return The message type's descriptor, or {@code null} if not found. + */ + public Descriptor findMessageTypeByName(String name) { + // Don't allow looking up nested types. This will make optimization + // easier later. + if (name.indexOf('.') != -1) { + return null; + } + if (getPackage().length() > 0) { + name = getPackage() + '.' + name; + } + final GenericDescriptor result = pool.findSymbol(name); + if (result != null && result instanceof Descriptor && + result.getFile() == this) { + return (Descriptor)result; + } else { + return null; + } + } + + /** + * Find an enum type in the file by name. Does not find nested types. + * + * @param name The unqualified type name to look for. + * @return The enum type's descriptor, or {@code null} if not found. + */ + public EnumDescriptor findEnumTypeByName(String name) { + // Don't allow looking up nested types. This will make optimization + // easier later. + if (name.indexOf('.') != -1) { + return null; + } + if (getPackage().length() > 0) { + name = getPackage() + '.' + name; + } + final GenericDescriptor result = pool.findSymbol(name); + if (result != null && result instanceof EnumDescriptor && + result.getFile() == this) { + return (EnumDescriptor)result; + } else { + return null; + } + } + + /** + * Find a service type in the file by name. + * + * @param name The unqualified type name to look for. + * @return The service type's descriptor, or {@code null} if not found. + */ + public ServiceDescriptor findServiceByName(String name) { + // Don't allow looking up nested types. This will make optimization + // easier later. + if (name.indexOf('.') != -1) { + return null; + } + if (getPackage().length() > 0) { + name = getPackage() + '.' + name; + } + final GenericDescriptor result = pool.findSymbol(name); + if (result != null && result instanceof ServiceDescriptor && + result.getFile() == this) { + return (ServiceDescriptor)result; + } else { + return null; + } + } + + /** + * Find an extension in the file by name. Does not find extensions nested + * inside message types. + * + * @param name The unqualified extension name to look for. + * @return The extension's descriptor, or {@code null} if not found. + */ + public FieldDescriptor findExtensionByName(String name) { + if (name.indexOf('.') != -1) { + return null; + } + if (getPackage().length() > 0) { + name = getPackage() + '.' + name; + } + final GenericDescriptor result = pool.findSymbol(name); + if (result != null && result instanceof FieldDescriptor && + result.getFile() == this) { + return (FieldDescriptor)result; + } else { + return null; + } + } + + /** + * Construct a {@code FileDescriptor}. + * + * @param proto The protocol message form of the FileDescriptor. + * @param dependencies {@code FileDescriptor}s corresponding to all of + * the file's dependencies, in the exact order listed + * in {@code proto}. + * @throws DescriptorValidationException {@code proto} is not a valid + * descriptor. This can occur for a number of reasons, e.g. + * because a field has an undefined type or because two messages + * were defined with the same name. + */ + public static FileDescriptor buildFrom(final FileDescriptorProto proto, + final FileDescriptor[] dependencies) + throws DescriptorValidationException { + // Building descriptors involves two steps: translating and linking. + // In the translation step (implemented by FileDescriptor's + // constructor), we build an object tree mirroring the + // FileDescriptorProto's tree and put all of the descriptors into the + // DescriptorPool's lookup tables. In the linking step, we look up all + // type references in the DescriptorPool, so that, for example, a + // FieldDescriptor for an embedded message contains a pointer directly + // to the Descriptor for that message's type. We also detect undefined + // types in the linking step. + final DescriptorPool pool = new DescriptorPool(dependencies); + final FileDescriptor result = + new FileDescriptor(proto, dependencies, pool); + + if (dependencies.length != proto.getDependencyCount()) { + throw new DescriptorValidationException(result, + "Dependencies passed to FileDescriptor.buildFrom() don't match " + + "those listed in the FileDescriptorProto."); + } + for (int i = 0; i < proto.getDependencyCount(); i++) { + if (!dependencies[i].getName().equals(proto.getDependency(i))) { + throw new DescriptorValidationException(result, + "Dependencies passed to FileDescriptor.buildFrom() don't match " + + "those listed in the FileDescriptorProto."); + } + } + + result.crossLink(); + return result; + } + + /** + * This method is to be called by generated code only. It is equivalent + * to {@code buildFrom} except that the {@code FileDescriptorProto} is + * encoded in protocol buffer wire format. + */ + public static void internalBuildGeneratedFileFrom( + final String[] descriptorDataParts, + final FileDescriptor[] dependencies, + final InternalDescriptorAssigner descriptorAssigner) { + // Hack: We can't embed a raw byte array inside generated Java code + // (at least, not efficiently), but we can embed Strings. So, the + // protocol compiler embeds the FileDescriptorProto as a giant + // string literal which is passed to this function to construct the + // file's FileDescriptor. The string literal contains only 8-bit + // characters, each one representing a byte of the FileDescriptorProto's + // serialized form. So, if we convert it to bytes in ISO-8859-1, we + // should get the original bytes that we want. + + // descriptorData may contain multiple strings in order to get around the + // Java 64k string literal limit. + StringBuilder descriptorData = new StringBuilder(); + for (String part : descriptorDataParts) { + descriptorData.append(part); + } + + final byte[] descriptorBytes; + try { + descriptorBytes = descriptorData.toString().getBytes("ISO-8859-1"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException( + "Standard encoding ISO-8859-1 not supported by JVM.", e); + } + + FileDescriptorProto proto; + try { + proto = FileDescriptorProto.parseFrom(descriptorBytes); + } catch (InvalidProtocolBufferException e) { + throw new IllegalArgumentException( + "Failed to parse protocol buffer descriptor for generated code.", e); + } + + final FileDescriptor result; + try { + result = buildFrom(proto, dependencies); + } catch (DescriptorValidationException e) { + throw new IllegalArgumentException( + "Invalid embedded descriptor for \"" + proto.getName() + "\".", e); + } + + final ExtensionRegistry registry = + descriptorAssigner.assignDescriptors(result); + + if (registry != null) { + // We must re-parse the proto using the registry. + try { + proto = FileDescriptorProto.parseFrom(descriptorBytes, registry); + } catch (InvalidProtocolBufferException e) { + throw new IllegalArgumentException( + "Failed to parse protocol buffer descriptor for generated code.", + e); + } + + result.setProto(proto); + } + } + + /** + * This class should be used by generated code only. When calling + * {@link FileDescriptor#internalBuildGeneratedFileFrom}, the caller + * provides a callback implementing this interface. The callback is called + * after the FileDescriptor has been constructed, in order to assign all + * the global variables defined in the generated code which point at parts + * of the FileDescriptor. The callback returns an ExtensionRegistry which + * contains any extensions which might be used in the descriptor -- that + * is, extensions of the various "Options" messages defined in + * descriptor.proto. The callback may also return null to indicate that + * no extensions are used in the descriptor. + */ + public interface InternalDescriptorAssigner { + ExtensionRegistry assignDescriptors(FileDescriptor root); + } + + private FileDescriptorProto proto; + private final Descriptor[] messageTypes; + private final EnumDescriptor[] enumTypes; + private final ServiceDescriptor[] services; + private final FieldDescriptor[] extensions; + private final FileDescriptor[] dependencies; + private final FileDescriptor[] publicDependencies; + private final DescriptorPool pool; + + private FileDescriptor(final FileDescriptorProto proto, + final FileDescriptor[] dependencies, + final DescriptorPool pool) + throws DescriptorValidationException { + this.pool = pool; + this.proto = proto; + this.dependencies = dependencies.clone(); + this.publicDependencies = + new FileDescriptor[proto.getPublicDependencyCount()]; + for (int i = 0; i < proto.getPublicDependencyCount(); i++) { + int index = proto.getPublicDependency(i); + if (index < 0 || index >= this.dependencies.length) { + throw new DescriptorValidationException(this, + "Invalid public dependency index."); + } + this.publicDependencies[i] = + this.dependencies[proto.getPublicDependency(i)]; + } + + pool.addPackage(getPackage(), this); + + messageTypes = new Descriptor[proto.getMessageTypeCount()]; + for (int i = 0; i < proto.getMessageTypeCount(); i++) { + messageTypes[i] = + new Descriptor(proto.getMessageType(i), this, null, i); + } + + enumTypes = new EnumDescriptor[proto.getEnumTypeCount()]; + for (int i = 0; i < proto.getEnumTypeCount(); i++) { + enumTypes[i] = new EnumDescriptor(proto.getEnumType(i), this, null, i); + } + + services = new ServiceDescriptor[proto.getServiceCount()]; + for (int i = 0; i < proto.getServiceCount(); i++) { + services[i] = new ServiceDescriptor(proto.getService(i), this, i); + } + + extensions = new FieldDescriptor[proto.getExtensionCount()]; + for (int i = 0; i < proto.getExtensionCount(); i++) { + extensions[i] = new FieldDescriptor( + proto.getExtension(i), this, null, i, true); + } + } + + /** Look up and cross-link all field types, etc. */ + private void crossLink() throws DescriptorValidationException { + for (final Descriptor messageType : messageTypes) { + messageType.crossLink(); + } + + for (final ServiceDescriptor service : services) { + service.crossLink(); + } + + for (final FieldDescriptor extension : extensions) { + extension.crossLink(); + } + } + + /** + * Replace our {@link FileDescriptorProto} with the given one, which is + * identical except that it might contain extensions that weren't present + * in the original. This method is needed for bootstrapping when a file + * defines custom options. The options may be defined in the file itself, + * so we can't actually parse them until we've constructed the descriptors, + * but to construct the descriptors we have to have parsed the descriptor + * protos. So, we have to parse the descriptor protos a second time after + * constructing the descriptors. + */ + private void setProto(final FileDescriptorProto proto) { + this.proto = proto; + + for (int i = 0; i < messageTypes.length; i++) { + messageTypes[i].setProto(proto.getMessageType(i)); + } + + for (int i = 0; i < enumTypes.length; i++) { + enumTypes[i].setProto(proto.getEnumType(i)); + } + + for (int i = 0; i < services.length; i++) { + services[i].setProto(proto.getService(i)); + } + + for (int i = 0; i < extensions.length; i++) { + extensions[i].setProto(proto.getExtension(i)); + } + } + } + + // ================================================================= + + /** Describes a message type. */ + public static final class Descriptor implements GenericDescriptor { + /** + * Get the index of this descriptor within its parent. In other words, + * given a {@link FileDescriptor} {@code file}, the following is true: + *

+     *   for all i in [0, file.getMessageTypeCount()):
+     *     file.getMessageType(i).getIndex() == i
+     * 
+ * Similarly, for a {@link Descriptor} {@code messageType}: + *
+     *   for all i in [0, messageType.getNestedTypeCount()):
+     *     messageType.getNestedType(i).getIndex() == i
+     * 
+ */ + public int getIndex() { return index; } + + /** Convert the descriptor to its protocol message representation. */ + public DescriptorProto toProto() { return proto; } + + /** Get the type's unqualified name. */ + public String getName() { return proto.getName(); } + + /** + * Get the type's fully-qualified name, within the proto language's + * namespace. This differs from the Java name. For example, given this + * {@code .proto}: + *
+     *   package foo.bar;
+     *   option java_package = "com.example.protos"
+     *   message Baz {}
+     * 
+ * {@code Baz}'s full name is "foo.bar.Baz". + */ + public String getFullName() { return fullName; } + + /** Get the {@link FileDescriptor} containing this descriptor. */ + public FileDescriptor getFile() { return file; } + + /** If this is a nested type, get the outer descriptor, otherwise null. */ + public Descriptor getContainingType() { return containingType; } + + /** Get the {@code MessageOptions}, defined in {@code descriptor.proto}. */ + public MessageOptions getOptions() { return proto.getOptions(); } + + /** Get a list of this message type's fields. */ + public List getFields() { + return Collections.unmodifiableList(Arrays.asList(fields)); + } + + /** Get a list of this message type's extensions. */ + public List getExtensions() { + return Collections.unmodifiableList(Arrays.asList(extensions)); + } + + /** Get a list of message types nested within this one. */ + public List getNestedTypes() { + return Collections.unmodifiableList(Arrays.asList(nestedTypes)); + } + + /** Get a list of enum types nested within this one. */ + public List getEnumTypes() { + return Collections.unmodifiableList(Arrays.asList(enumTypes)); + } + + /** Determines if the given field number is an extension. */ + public boolean isExtensionNumber(final int number) { + for (final DescriptorProto.ExtensionRange range : + proto.getExtensionRangeList()) { + if (range.getStart() <= number && number < range.getEnd()) { + return true; + } + } + return false; + } + + /** + * Finds a field by name. + * @param name The unqualified name of the field (e.g. "foo"). + * @return The field's descriptor, or {@code null} if not found. + */ + public FieldDescriptor findFieldByName(final String name) { + final GenericDescriptor result = + file.pool.findSymbol(fullName + '.' + name); + if (result != null && result instanceof FieldDescriptor) { + return (FieldDescriptor)result; + } else { + return null; + } + } + + /** + * Finds a field by field number. + * @param number The field number within this message type. + * @return The field's descriptor, or {@code null} if not found. + */ + public FieldDescriptor findFieldByNumber(final int number) { + return file.pool.fieldsByNumber.get( + new DescriptorPool.DescriptorIntPair(this, number)); + } + + /** + * Finds a nested message type by name. + * @param name The unqualified name of the nested type (e.g. "Foo"). + * @return The types's descriptor, or {@code null} if not found. + */ + public Descriptor findNestedTypeByName(final String name) { + final GenericDescriptor result = + file.pool.findSymbol(fullName + '.' + name); + if (result != null && result instanceof Descriptor) { + return (Descriptor)result; + } else { + return null; + } + } + + /** + * Finds a nested enum type by name. + * @param name The unqualified name of the nested type (e.g. "Foo"). + * @return The types's descriptor, or {@code null} if not found. + */ + public EnumDescriptor findEnumTypeByName(final String name) { + final GenericDescriptor result = + file.pool.findSymbol(fullName + '.' + name); + if (result != null && result instanceof EnumDescriptor) { + return (EnumDescriptor)result; + } else { + return null; + } + } + + private final int index; + private DescriptorProto proto; + private final String fullName; + private final FileDescriptor file; + private final Descriptor containingType; + private final Descriptor[] nestedTypes; + private final EnumDescriptor[] enumTypes; + private final FieldDescriptor[] fields; + private final FieldDescriptor[] extensions; + + private Descriptor(final DescriptorProto proto, + final FileDescriptor file, + final Descriptor parent, + final int index) + throws DescriptorValidationException { + this.index = index; + this.proto = proto; + fullName = computeFullName(file, parent, proto.getName()); + this.file = file; + containingType = parent; + + nestedTypes = new Descriptor[proto.getNestedTypeCount()]; + for (int i = 0; i < proto.getNestedTypeCount(); i++) { + nestedTypes[i] = new Descriptor( + proto.getNestedType(i), file, this, i); + } + + enumTypes = new EnumDescriptor[proto.getEnumTypeCount()]; + for (int i = 0; i < proto.getEnumTypeCount(); i++) { + enumTypes[i] = new EnumDescriptor( + proto.getEnumType(i), file, this, i); + } + + fields = new FieldDescriptor[proto.getFieldCount()]; + for (int i = 0; i < proto.getFieldCount(); i++) { + fields[i] = new FieldDescriptor( + proto.getField(i), file, this, i, false); + } + + extensions = new FieldDescriptor[proto.getExtensionCount()]; + for (int i = 0; i < proto.getExtensionCount(); i++) { + extensions[i] = new FieldDescriptor( + proto.getExtension(i), file, this, i, true); + } + + file.pool.addSymbol(this); + } + + /** Look up and cross-link all field types, etc. */ + private void crossLink() throws DescriptorValidationException { + for (final Descriptor nestedType : nestedTypes) { + nestedType.crossLink(); + } + + for (final FieldDescriptor field : fields) { + field.crossLink(); + } + + for (final FieldDescriptor extension : extensions) { + extension.crossLink(); + } + } + + /** See {@link FileDescriptor#setProto}. */ + private void setProto(final DescriptorProto proto) { + this.proto = proto; + + for (int i = 0; i < nestedTypes.length; i++) { + nestedTypes[i].setProto(proto.getNestedType(i)); + } + + for (int i = 0; i < enumTypes.length; i++) { + enumTypes[i].setProto(proto.getEnumType(i)); + } + + for (int i = 0; i < fields.length; i++) { + fields[i].setProto(proto.getField(i)); + } + + for (int i = 0; i < extensions.length; i++) { + extensions[i].setProto(proto.getExtension(i)); + } + } + } + + // ================================================================= + + /** Describes a field of a message type. */ + public static final class FieldDescriptor + implements GenericDescriptor, Comparable, + FieldSet.FieldDescriptorLite { + /** + * Get the index of this descriptor within its parent. + * @see Descriptors.Descriptor#getIndex() + */ + public int getIndex() { return index; } + + /** Convert the descriptor to its protocol message representation. */ + public FieldDescriptorProto toProto() { return proto; } + + /** Get the field's unqualified name. */ + public String getName() { return proto.getName(); } + + /** Get the field's number. */ + public int getNumber() { return proto.getNumber(); } + + /** + * Get the field's fully-qualified name. + * @see Descriptors.Descriptor#getFullName() + */ + public String getFullName() { return fullName; } + + /** + * Get the field's java type. This is just for convenience. Every + * {@code FieldDescriptorProto.Type} maps to exactly one Java type. + */ + public JavaType getJavaType() { return type.getJavaType(); } + + /** For internal use only. */ + public WireFormat.JavaType getLiteJavaType() { + return getLiteType().getJavaType(); + } + + /** Get the {@code FileDescriptor} containing this descriptor. */ + public FileDescriptor getFile() { return file; } + + /** Get the field's declared type. */ + public Type getType() { return type; } + + /** For internal use only. */ + public WireFormat.FieldType getLiteType() { + return table[type.ordinal()]; + } + // I'm pretty sure values() constructs a new array every time, since there + // is nothing stopping the caller from mutating the array. Therefore we + // make a static copy here. + private static final WireFormat.FieldType[] table = + WireFormat.FieldType.values(); + + /** Is this field declared required? */ + public boolean isRequired() { + return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REQUIRED; + } + + /** Is this field declared optional? */ + public boolean isOptional() { + return proto.getLabel() == FieldDescriptorProto.Label.LABEL_OPTIONAL; + } + + /** Is this field declared repeated? */ + public boolean isRepeated() { + return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED; + } + + /** Does this field have the {@code [packed = true]} option? */ + public boolean isPacked() { + return getOptions().getPacked(); + } + + /** Can this field be packed? i.e. is it a repeated primitive field? */ + public boolean isPackable() { + return isRepeated() && getLiteType().isPackable(); + } + + /** Returns true if the field had an explicitly-defined default value. */ + public boolean hasDefaultValue() { return proto.hasDefaultValue(); } + + /** + * Returns the field's default value. Valid for all types except for + * messages and groups. For all other types, the object returned is of + * the same class that would returned by Message.getField(this). + */ + public Object getDefaultValue() { + if (getJavaType() == JavaType.MESSAGE) { + throw new UnsupportedOperationException( + "FieldDescriptor.getDefaultValue() called on an embedded message " + + "field."); + } + return defaultValue; + } + + /** Get the {@code FieldOptions}, defined in {@code descriptor.proto}. */ + public FieldOptions getOptions() { return proto.getOptions(); } + + /** Is this field an extension? */ + public boolean isExtension() { return proto.hasExtendee(); } + + /** + * Get the field's containing type. For extensions, this is the type being + * extended, not the location where the extension was defined. See + * {@link #getExtensionScope()}. + */ + public Descriptor getContainingType() { return containingType; } + + /** + * For extensions defined nested within message types, gets the outer + * type. Not valid for non-extension fields. For example, consider + * this {@code .proto} file: + *
+     *   message Foo {
+     *     extensions 1000 to max;
+     *   }
+     *   extend Foo {
+     *     optional int32 baz = 1234;
+     *   }
+     *   message Bar {
+     *     extend Foo {
+     *       optional int32 qux = 4321;
+     *     }
+     *   }
+     * 
+ * 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}. + */ + public Descriptor getExtensionScope() { + if (!isExtension()) { + throw new UnsupportedOperationException( + "This field is not an extension."); + } + return extensionScope; + } + + /** For embedded message and group fields, gets the field's type. */ + public Descriptor getMessageType() { + if (getJavaType() != JavaType.MESSAGE) { + throw new UnsupportedOperationException( + "This field is not of message type."); + } + return messageType; + } + + /** For enum fields, gets the field's type. */ + public EnumDescriptor getEnumType() { + if (getJavaType() != JavaType.ENUM) { + throw new UnsupportedOperationException( + "This field is not of enum type."); + } + return enumType; + } + + /** + * 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. + * + * @return negative, zero, or positive if {@code this} is less than, + * equal to, or greater than {@code other}, respectively. + */ + public int compareTo(final FieldDescriptor other) { + if (other.containingType != containingType) { + throw new IllegalArgumentException( + "FieldDescriptors can only be compared to other FieldDescriptors " + + "for fields of the same message type."); + } + return getNumber() - other.getNumber(); + } + + private final int index; + + private FieldDescriptorProto proto; + private final String fullName; + private final FileDescriptor file; + private final Descriptor extensionScope; + + // Possibly initialized during cross-linking. + private Type type; + private Descriptor containingType; + private Descriptor messageType; + private EnumDescriptor enumType; + private Object defaultValue; + + public enum Type { + DOUBLE (JavaType.DOUBLE ), + FLOAT (JavaType.FLOAT ), + INT64 (JavaType.LONG ), + UINT64 (JavaType.LONG ), + INT32 (JavaType.INT ), + FIXED64 (JavaType.LONG ), + FIXED32 (JavaType.INT ), + BOOL (JavaType.BOOLEAN ), + STRING (JavaType.STRING ), + GROUP (JavaType.MESSAGE ), + MESSAGE (JavaType.MESSAGE ), + BYTES (JavaType.BYTE_STRING), + UINT32 (JavaType.INT ), + ENUM (JavaType.ENUM ), + SFIXED32(JavaType.INT ), + SFIXED64(JavaType.LONG ), + SINT32 (JavaType.INT ), + SINT64 (JavaType.LONG ); + + Type(final JavaType javaType) { + this.javaType = javaType; + } + + private JavaType javaType; + + public FieldDescriptorProto.Type toProto() { + return FieldDescriptorProto.Type.valueOf(ordinal() + 1); + } + public JavaType getJavaType() { return javaType; } + + public static Type valueOf(final FieldDescriptorProto.Type type) { + return values()[type.getNumber() - 1]; + } + } + + static { + // Refuse to init if someone added a new declared type. + if (Type.values().length != FieldDescriptorProto.Type.values().length) { + throw new RuntimeException( + "descriptor.proto has a new declared type but Desrciptors.java " + + "wasn't updated."); + } + } + + public enum JavaType { + INT(0), + LONG(0L), + FLOAT(0F), + DOUBLE(0D), + BOOLEAN(false), + STRING(""), + BYTE_STRING(ByteString.EMPTY), + ENUM(null), + MESSAGE(null); + + JavaType(final Object defaultDefault) { + this.defaultDefault = defaultDefault; + } + + /** + * The default default value for fields of this type, if it's a primitive + * type. This is meant for use inside this file only, hence is private. + */ + private final Object defaultDefault; + } + + private FieldDescriptor(final FieldDescriptorProto proto, + final FileDescriptor file, + final Descriptor parent, + final int index, + final boolean isExtension) + throws DescriptorValidationException { + this.index = index; + this.proto = proto; + fullName = computeFullName(file, parent, proto.getName()); + this.file = file; + + if (proto.hasType()) { + type = Type.valueOf(proto.getType()); + } + + if (getNumber() <= 0) { + throw new DescriptorValidationException(this, + "Field numbers must be positive integers."); + } + + // Only repeated primitive fields may be packed. + if (proto.getOptions().getPacked() && !isPackable()) { + throw new DescriptorValidationException(this, + "[packed = true] can only be specified for repeated primitive " + + "fields."); + } + + if (isExtension) { + if (!proto.hasExtendee()) { + throw new DescriptorValidationException(this, + "FieldDescriptorProto.extendee not set for extension field."); + } + containingType = null; // Will be filled in when cross-linking + if (parent != null) { + extensionScope = parent; + } else { + extensionScope = null; + } + } else { + if (proto.hasExtendee()) { + throw new DescriptorValidationException(this, + "FieldDescriptorProto.extendee set for non-extension field."); + } + containingType = parent; + extensionScope = null; + } + + file.pool.addSymbol(this); + } + + /** Look up and cross-link all field types, etc. */ + private void crossLink() throws DescriptorValidationException { + if (proto.hasExtendee()) { + final GenericDescriptor extendee = + file.pool.lookupSymbol(proto.getExtendee(), this, + DescriptorPool.SearchFilter.TYPES_ONLY); + if (!(extendee instanceof Descriptor)) { + throw new DescriptorValidationException(this, + '\"' + proto.getExtendee() + "\" is not a message type."); + } + containingType = (Descriptor)extendee; + + if (!getContainingType().isExtensionNumber(getNumber())) { + throw new DescriptorValidationException(this, + '\"' + getContainingType().getFullName() + + "\" does not declare " + getNumber() + + " as an extension number."); + } + } + + if (proto.hasTypeName()) { + final GenericDescriptor typeDescriptor = + file.pool.lookupSymbol(proto.getTypeName(), this, + DescriptorPool.SearchFilter.TYPES_ONLY); + + if (!proto.hasType()) { + // Choose field type based on symbol. + if (typeDescriptor instanceof Descriptor) { + type = Type.MESSAGE; + } else if (typeDescriptor instanceof EnumDescriptor) { + type = Type.ENUM; + } else { + throw new DescriptorValidationException(this, + '\"' + proto.getTypeName() + "\" is not a type."); + } + } + + if (getJavaType() == JavaType.MESSAGE) { + if (!(typeDescriptor instanceof Descriptor)) { + throw new DescriptorValidationException(this, + '\"' + proto.getTypeName() + "\" is not a message type."); + } + messageType = (Descriptor)typeDescriptor; + + if (proto.hasDefaultValue()) { + throw new DescriptorValidationException(this, + "Messages can't have default values."); + } + } else if (getJavaType() == JavaType.ENUM) { + if (!(typeDescriptor instanceof EnumDescriptor)) { + throw new DescriptorValidationException(this, + '\"' + proto.getTypeName() + "\" is not an enum type."); + } + enumType = (EnumDescriptor)typeDescriptor; + } else { + throw new DescriptorValidationException(this, + "Field with primitive type has type_name."); + } + } else { + if (getJavaType() == JavaType.MESSAGE || + getJavaType() == JavaType.ENUM) { + throw new DescriptorValidationException(this, + "Field with message or enum type missing type_name."); + } + } + + // We don't attempt to parse the default value until here because for + // enums we need the enum type's descriptor. + if (proto.hasDefaultValue()) { + if (isRepeated()) { + throw new DescriptorValidationException(this, + "Repeated fields cannot have default values."); + } + + try { + switch (getType()) { + case INT32: + case SINT32: + case SFIXED32: + defaultValue = TextFormat.parseInt32(proto.getDefaultValue()); + break; + case UINT32: + case FIXED32: + defaultValue = TextFormat.parseUInt32(proto.getDefaultValue()); + break; + case INT64: + case SINT64: + case SFIXED64: + defaultValue = TextFormat.parseInt64(proto.getDefaultValue()); + break; + case UINT64: + case FIXED64: + defaultValue = TextFormat.parseUInt64(proto.getDefaultValue()); + break; + case FLOAT: + if (proto.getDefaultValue().equals("inf")) { + defaultValue = Float.POSITIVE_INFINITY; + } else if (proto.getDefaultValue().equals("-inf")) { + defaultValue = Float.NEGATIVE_INFINITY; + } else if (proto.getDefaultValue().equals("nan")) { + defaultValue = Float.NaN; + } else { + defaultValue = Float.valueOf(proto.getDefaultValue()); + } + break; + case DOUBLE: + if (proto.getDefaultValue().equals("inf")) { + defaultValue = Double.POSITIVE_INFINITY; + } else if (proto.getDefaultValue().equals("-inf")) { + defaultValue = Double.NEGATIVE_INFINITY; + } else if (proto.getDefaultValue().equals("nan")) { + defaultValue = Double.NaN; + } else { + defaultValue = Double.valueOf(proto.getDefaultValue()); + } + break; + case BOOL: + defaultValue = Boolean.valueOf(proto.getDefaultValue()); + break; + case STRING: + defaultValue = proto.getDefaultValue(); + break; + case BYTES: + try { + defaultValue = + TextFormat.unescapeBytes(proto.getDefaultValue()); + } catch (TextFormat.InvalidEscapeSequenceException e) { + throw new DescriptorValidationException(this, + "Couldn't parse default value: " + e.getMessage(), e); + } + break; + case ENUM: + defaultValue = enumType.findValueByName(proto.getDefaultValue()); + if (defaultValue == null) { + throw new DescriptorValidationException(this, + "Unknown enum default value: \"" + + proto.getDefaultValue() + '\"'); + } + break; + case MESSAGE: + case GROUP: + throw new DescriptorValidationException(this, + "Message type had default value."); + } + } catch (NumberFormatException e) { + throw new DescriptorValidationException(this, + "Could not parse default value: \"" + + proto.getDefaultValue() + '\"', e); + } + } else { + // Determine the default default for this field. + if (isRepeated()) { + defaultValue = Collections.emptyList(); + } else { + switch (getJavaType()) { + case ENUM: + // We guarantee elsewhere that an enum type always has at least + // one possible value. + defaultValue = enumType.getValues().get(0); + break; + case MESSAGE: + defaultValue = null; + break; + default: + defaultValue = getJavaType().defaultDefault; + break; + } + } + } + + if (!isExtension()) { + file.pool.addFieldByNumber(this); + } + + if (containingType != null && + containingType.getOptions().getMessageSetWireFormat()) { + if (isExtension()) { + if (!isOptional() || getType() != Type.MESSAGE) { + throw new DescriptorValidationException(this, + "Extensions of MessageSets must be optional messages."); + } + } else { + throw new DescriptorValidationException(this, + "MessageSets cannot have fields, only extensions."); + } + } + } + + /** See {@link FileDescriptor#setProto}. */ + private void setProto(final FieldDescriptorProto proto) { + this.proto = proto; + } + + /** + * For internal use only. This is to satisfy the FieldDescriptorLite + * interface. + */ + public MessageLite.Builder internalMergeFrom( + MessageLite.Builder to, MessageLite from) { + // FieldDescriptors are only used with non-lite messages so we can just + // down-cast and call mergeFrom directly. + return ((Message.Builder) to).mergeFrom((Message) from); + } + } + + // ================================================================= + + /** Describes an enum type. */ + public static final class EnumDescriptor + implements GenericDescriptor, Internal.EnumLiteMap { + /** + * Get the index of this descriptor within its parent. + * @see Descriptors.Descriptor#getIndex() + */ + public int getIndex() { return index; } + + /** Convert the descriptor to its protocol message representation. */ + public EnumDescriptorProto toProto() { return proto; } + + /** Get the type's unqualified name. */ + public String getName() { return proto.getName(); } + + /** + * Get the type's fully-qualified name. + * @see Descriptors.Descriptor#getFullName() + */ + public String getFullName() { return fullName; } + + /** Get the {@link FileDescriptor} containing this descriptor. */ + public FileDescriptor getFile() { return file; } + + /** If this is a nested type, get the outer descriptor, otherwise null. */ + public Descriptor getContainingType() { return containingType; } + + /** Get the {@code EnumOptions}, defined in {@code descriptor.proto}. */ + public EnumOptions getOptions() { return proto.getOptions(); } + + /** Get a list of defined values for this enum. */ + public List getValues() { + return Collections.unmodifiableList(Arrays.asList(values)); + } + + /** + * 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. + */ + public EnumValueDescriptor findValueByName(final String name) { + final GenericDescriptor result = + file.pool.findSymbol(fullName + '.' + name); + if (result != null && result instanceof EnumValueDescriptor) { + return (EnumValueDescriptor)result; + } else { + return null; + } + } + + /** + * Find an enum value by number. If multiple enum values have the same + * number, this returns the first defined value with that number. + * @param number The value's number. + * @return the value's descriptor, or {@code null} if not found. + */ + public EnumValueDescriptor findValueByNumber(final int number) { + return file.pool.enumValuesByNumber.get( + new DescriptorPool.DescriptorIntPair(this, number)); + } + + private final int index; + private EnumDescriptorProto proto; + private final String fullName; + private final FileDescriptor file; + private final Descriptor containingType; + private EnumValueDescriptor[] values; + + private EnumDescriptor(final EnumDescriptorProto proto, + final FileDescriptor file, + final Descriptor parent, + final int index) + throws DescriptorValidationException { + this.index = index; + this.proto = proto; + fullName = computeFullName(file, parent, proto.getName()); + this.file = file; + containingType = parent; + + if (proto.getValueCount() == 0) { + // We cannot allow enums with no values because this would mean there + // would be no valid default value for fields of this type. + throw new DescriptorValidationException(this, + "Enums must contain at least one value."); + } + + values = new EnumValueDescriptor[proto.getValueCount()]; + for (int i = 0; i < proto.getValueCount(); i++) { + values[i] = new EnumValueDescriptor( + proto.getValue(i), file, this, i); + } + + file.pool.addSymbol(this); + } + + /** See {@link FileDescriptor#setProto}. */ + private void setProto(final EnumDescriptorProto proto) { + this.proto = proto; + + for (int i = 0; i < values.length; i++) { + values[i].setProto(proto.getValue(i)); + } + } + } + + // ================================================================= + + /** + * Describes one value within an enum type. Note that multiple defined + * values may have the same number. In generated Java code, all values + * with the same number after the first become aliases of the first. + * However, they still have independent EnumValueDescriptors. + */ + public static final class EnumValueDescriptor + implements GenericDescriptor, Internal.EnumLite { + /** + * Get the index of this descriptor within its parent. + * @see Descriptors.Descriptor#getIndex() + */ + public int getIndex() { return index; } + + /** Convert the descriptor to its protocol message representation. */ + public EnumValueDescriptorProto toProto() { return proto; } + + /** Get the value's unqualified name. */ + public String getName() { return proto.getName(); } + + /** Get the value's number. */ + public int getNumber() { return proto.getNumber(); } + + /** + * Get the value's fully-qualified name. + * @see Descriptors.Descriptor#getFullName() + */ + public String getFullName() { return fullName; } + + /** Get the {@link FileDescriptor} containing this descriptor. */ + public FileDescriptor getFile() { return file; } + + /** Get the value's enum type. */ + public EnumDescriptor getType() { return type; } + + /** + * Get the {@code EnumValueOptions}, defined in {@code descriptor.proto}. + */ + public EnumValueOptions getOptions() { return proto.getOptions(); } + + private final int index; + private EnumValueDescriptorProto proto; + private final String fullName; + private final FileDescriptor file; + private final EnumDescriptor type; + + private EnumValueDescriptor(final EnumValueDescriptorProto proto, + final FileDescriptor file, + final EnumDescriptor parent, + final int index) + throws DescriptorValidationException { + this.index = index; + this.proto = proto; + this.file = file; + type = parent; + + fullName = parent.getFullName() + '.' + proto.getName(); + + file.pool.addSymbol(this); + file.pool.addEnumValueByNumber(this); + } + + /** See {@link FileDescriptor#setProto}. */ + private void setProto(final EnumValueDescriptorProto proto) { + this.proto = proto; + } + } + + // ================================================================= + + /** Describes a service type. */ + public static final class ServiceDescriptor implements GenericDescriptor { + /** + * Get the index of this descriptor within its parent. + * * @see Descriptors.Descriptor#getIndex() + */ + public int getIndex() { return index; } + + /** Convert the descriptor to its protocol message representation. */ + public ServiceDescriptorProto toProto() { return proto; } + + /** Get the type's unqualified name. */ + public String getName() { return proto.getName(); } + + /** + * Get the type's fully-qualified name. + * @see Descriptors.Descriptor#getFullName() + */ + public String getFullName() { return fullName; } + + /** Get the {@link FileDescriptor} containing this descriptor. */ + public FileDescriptor getFile() { return file; } + + /** Get the {@code ServiceOptions}, defined in {@code descriptor.proto}. */ + public ServiceOptions getOptions() { return proto.getOptions(); } + + /** Get a list of methods for this service. */ + public List getMethods() { + return Collections.unmodifiableList(Arrays.asList(methods)); + } + + /** + * 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. + */ + public MethodDescriptor findMethodByName(final String name) { + final GenericDescriptor result = + file.pool.findSymbol(fullName + '.' + name); + if (result != null && result instanceof MethodDescriptor) { + return (MethodDescriptor)result; + } else { + return null; + } + } + + private final int index; + private ServiceDescriptorProto proto; + private final String fullName; + private final FileDescriptor file; + private MethodDescriptor[] methods; + + private ServiceDescriptor(final ServiceDescriptorProto proto, + final FileDescriptor file, + final int index) + throws DescriptorValidationException { + this.index = index; + this.proto = proto; + fullName = computeFullName(file, null, proto.getName()); + this.file = file; + + methods = new MethodDescriptor[proto.getMethodCount()]; + for (int i = 0; i < proto.getMethodCount(); i++) { + methods[i] = new MethodDescriptor( + proto.getMethod(i), file, this, i); + } + + file.pool.addSymbol(this); + } + + private void crossLink() throws DescriptorValidationException { + for (final MethodDescriptor method : methods) { + method.crossLink(); + } + } + + /** See {@link FileDescriptor#setProto}. */ + private void setProto(final ServiceDescriptorProto proto) { + this.proto = proto; + + for (int i = 0; i < methods.length; i++) { + methods[i].setProto(proto.getMethod(i)); + } + } + } + + // ================================================================= + + /** + * Describes one method within a service type. + */ + public static final class MethodDescriptor implements GenericDescriptor { + /** + * Get the index of this descriptor within its parent. + * * @see Descriptors.Descriptor#getIndex() + */ + public int getIndex() { return index; } + + /** Convert the descriptor to its protocol message representation. */ + public MethodDescriptorProto toProto() { return proto; } + + /** Get the method's unqualified name. */ + public String getName() { return proto.getName(); } + + /** + * Get the method's fully-qualified name. + * @see Descriptors.Descriptor#getFullName() + */ + public String getFullName() { return fullName; } + + /** Get the {@link FileDescriptor} containing this descriptor. */ + public FileDescriptor getFile() { return file; } + + /** Get the method's service type. */ + public ServiceDescriptor getService() { return service; } + + /** Get the method's input type. */ + public Descriptor getInputType() { return inputType; } + + /** Get the method's output type. */ + public Descriptor getOutputType() { return outputType; } + + /** + * Get the {@code MethodOptions}, defined in {@code descriptor.proto}. + */ + public MethodOptions getOptions() { return proto.getOptions(); } + + private final int index; + private MethodDescriptorProto proto; + private final String fullName; + private final FileDescriptor file; + private final ServiceDescriptor service; + + // Initialized during cross-linking. + private Descriptor inputType; + private Descriptor outputType; + + private MethodDescriptor(final MethodDescriptorProto proto, + final FileDescriptor file, + final ServiceDescriptor parent, + final int index) + throws DescriptorValidationException { + this.index = index; + this.proto = proto; + this.file = file; + service = parent; + + fullName = parent.getFullName() + '.' + proto.getName(); + + file.pool.addSymbol(this); + } + + private void crossLink() throws DescriptorValidationException { + final GenericDescriptor input = + file.pool.lookupSymbol(proto.getInputType(), this, + DescriptorPool.SearchFilter.TYPES_ONLY); + if (!(input instanceof Descriptor)) { + throw new DescriptorValidationException(this, + '\"' + proto.getInputType() + "\" is not a message type."); + } + inputType = (Descriptor)input; + + final GenericDescriptor output = + file.pool.lookupSymbol(proto.getOutputType(), this, + DescriptorPool.SearchFilter.TYPES_ONLY); + if (!(output instanceof Descriptor)) { + throw new DescriptorValidationException(this, + '\"' + proto.getOutputType() + "\" is not a message type."); + } + outputType = (Descriptor)output; + } + + /** See {@link FileDescriptor#setProto}. */ + private void setProto(final MethodDescriptorProto proto) { + this.proto = proto; + } + } + + // ================================================================= + + private static String computeFullName(final FileDescriptor file, + final Descriptor parent, + final String name) { + if (parent != null) { + return parent.getFullName() + '.' + name; + } else if (file.getPackage().length() > 0) { + return file.getPackage() + '.' + name; + } else { + return name; + } + } + + // ================================================================= + + /** + * All descriptors except {@code FileDescriptor} implement this to make + * {@code DescriptorPool}'s life easier. + */ + private interface GenericDescriptor { + Message toProto(); + String getName(); + String getFullName(); + FileDescriptor getFile(); + } + + /** + * Thrown when building descriptors fails because the source DescriptorProtos + * are not valid. + */ + public static class DescriptorValidationException extends Exception { + private static final long serialVersionUID = 5750205775490483148L; + + /** Gets the full name of the descriptor where the error occurred. */ + public String getProblemSymbolName() { return name; } + + /** + * Gets the protocol message representation of the invalid descriptor. + */ + public Message getProblemProto() { return proto; } + + /** + * Gets a human-readable description of the error. + */ + public String getDescription() { return description; } + + private final String name; + private final Message proto; + private final String description; + + private DescriptorValidationException( + final GenericDescriptor problemDescriptor, + final String description) { + super(problemDescriptor.getFullName() + ": " + description); + + // Note that problemDescriptor may be partially uninitialized, so we + // don't want to expose it directly to the user. So, we only provide + // the name and the original proto. + name = problemDescriptor.getFullName(); + proto = problemDescriptor.toProto(); + this.description = description; + } + + private DescriptorValidationException( + final GenericDescriptor problemDescriptor, + final String description, + final Throwable cause) { + this(problemDescriptor, description); + initCause(cause); + } + + private DescriptorValidationException( + final FileDescriptor problemDescriptor, + final String description) { + super(problemDescriptor.getName() + ": " + description); + + // Note that problemDescriptor may be partially uninitialized, so we + // don't want to expose it directly to the user. So, we only provide + // the name and the original proto. + name = problemDescriptor.getName(); + proto = problemDescriptor.toProto(); + this.description = description; + } + } + + // ================================================================= + + /** + * A private helper class which contains lookup tables containing all the + * descriptors defined in a particular file. + */ + private static final class DescriptorPool { + + /** Defines what subclass of descriptors to search in the descriptor pool. + */ + enum SearchFilter { + TYPES_ONLY, AGGREGATES_ONLY, ALL_SYMBOLS + } + + DescriptorPool(final FileDescriptor[] dependencies) { + this.dependencies = new HashSet(); + + for (int i = 0; i < dependencies.length; i++) { + this.dependencies.add(dependencies[i]); + importPublicDependencies(dependencies[i]); + } + + for (final FileDescriptor dependency : this.dependencies) { + try { + addPackage(dependency.getPackage(), dependency); + } catch (DescriptorValidationException e) { + // Can't happen, because addPackage() only fails when the name + // conflicts with a non-package, but we have not yet added any + // non-packages at this point. + assert false; + } + } + } + + /** Find and put public dependencies of the file into dependencies set.*/ + private void importPublicDependencies(final FileDescriptor file) { + for (FileDescriptor dependency : file.getPublicDependencies()) { + if (dependencies.add(dependency)) { + importPublicDependencies(dependency); + } + } + } + + private final Set dependencies; + + private final Map descriptorsByName = + new HashMap(); + private final Map fieldsByNumber = + new HashMap(); + private final Map enumValuesByNumber + = new HashMap(); + + /** Find a generic descriptor by fully-qualified name. */ + GenericDescriptor findSymbol(final String fullName) { + return findSymbol(fullName, SearchFilter.ALL_SYMBOLS); + } + + /** Find a descriptor by fully-qualified name and given option to only + * search valid field type descriptors. + */ + GenericDescriptor findSymbol(final String fullName, + final SearchFilter filter) { + GenericDescriptor result = descriptorsByName.get(fullName); + if (result != null) { + if ((filter==SearchFilter.ALL_SYMBOLS) || + ((filter==SearchFilter.TYPES_ONLY) && isType(result)) || + ((filter==SearchFilter.AGGREGATES_ONLY) && isAggregate(result))) { + return result; + } + } + + for (final FileDescriptor dependency : dependencies) { + result = dependency.pool.descriptorsByName.get(fullName); + if (result != null) { + if ((filter==SearchFilter.ALL_SYMBOLS) || + ((filter==SearchFilter.TYPES_ONLY) && isType(result)) || + ((filter==SearchFilter.AGGREGATES_ONLY) && isAggregate(result))) { + return result; + } + } + } + + return null; + } + + /** Checks if the descriptor is a valid type for a message field. */ + boolean isType(GenericDescriptor descriptor) { + return (descriptor instanceof Descriptor) || + (descriptor instanceof EnumDescriptor); + } + + /** Checks if the descriptor is a valid namespace type. */ + boolean isAggregate(GenericDescriptor descriptor) { + return (descriptor instanceof Descriptor) || + (descriptor instanceof EnumDescriptor) || + (descriptor instanceof PackageDescriptor) || + (descriptor instanceof ServiceDescriptor); + } + + /** + * Look up a type descriptor by name, relative to some other descriptor. + * The name may be fully-qualified (with a leading '.'), + * partially-qualified, or unqualified. C++-like name lookup semantics + * are used to search for the matching descriptor. + */ + GenericDescriptor lookupSymbol(final String name, + final GenericDescriptor relativeTo, + final DescriptorPool.SearchFilter filter) + throws DescriptorValidationException { + // TODO(kenton): This could be optimized in a number of ways. + + GenericDescriptor result; + if (name.startsWith(".")) { + // Fully-qualified name. + result = findSymbol(name.substring(1), filter); + } else { + // If "name" is a compound identifier, we want to search for the + // first component of it, then search within it for the rest. + // If name is something like "Foo.Bar.baz", and symbols named "Foo" are + // defined in multiple parent scopes, we only want to find "Bar.baz" in + // the innermost one. E.g., the following should produce an error: + // message Bar { message Baz {} } + // message Foo { + // message Bar { + // } + // optional Bar.Baz baz = 1; + // } + // So, we look for just "Foo" first, then look for "Bar.baz" within it + // if found. + final int firstPartLength = name.indexOf('.'); + final String firstPart; + if (firstPartLength == -1) { + firstPart = name; + } else { + firstPart = name.substring(0, firstPartLength); + } + + // We will search each parent scope of "relativeTo" looking for the + // symbol. + final StringBuilder scopeToTry = + new StringBuilder(relativeTo.getFullName()); + + while (true) { + // Chop off the last component of the scope. + final int dotpos = scopeToTry.lastIndexOf("."); + if (dotpos == -1) { + result = findSymbol(name, filter); + break; + } else { + scopeToTry.setLength(dotpos + 1); + + // Append firstPart and try to find + scopeToTry.append(firstPart); + result = findSymbol(scopeToTry.toString(), + DescriptorPool.SearchFilter.AGGREGATES_ONLY); + + if (result != null) { + if (firstPartLength != -1) { + // We only found the first part of the symbol. Now look for + // the whole thing. If this fails, we *don't* want to keep + // searching parent scopes. + scopeToTry.setLength(dotpos + 1); + scopeToTry.append(name); + result = findSymbol(scopeToTry.toString(), filter); + } + break; + } + + // Not found. Remove the name so we can try again. + scopeToTry.setLength(dotpos); + } + } + } + + if (result == null) { + throw new DescriptorValidationException(relativeTo, + '\"' + name + "\" is not defined."); + } else { + return result; + } + } + + /** + * Adds a symbol to the symbol table. If a symbol with the same name + * already exists, throws an error. + */ + void addSymbol(final GenericDescriptor descriptor) + throws DescriptorValidationException { + validateSymbolName(descriptor); + + final String fullName = descriptor.getFullName(); + final int dotpos = fullName.lastIndexOf('.'); + + final GenericDescriptor old = descriptorsByName.put(fullName, descriptor); + if (old != null) { + descriptorsByName.put(fullName, old); + + if (descriptor.getFile() == old.getFile()) { + if (dotpos == -1) { + throw new DescriptorValidationException(descriptor, + '\"' + fullName + "\" is already defined."); + } else { + throw new DescriptorValidationException(descriptor, + '\"' + fullName.substring(dotpos + 1) + + "\" is already defined in \"" + + fullName.substring(0, dotpos) + "\"."); + } + } else { + throw new DescriptorValidationException(descriptor, + '\"' + fullName + "\" is already defined in file \"" + + old.getFile().getName() + "\"."); + } + } + } + + /** + * Represents a package in the symbol table. We use PackageDescriptors + * just as placeholders so that someone cannot define, say, a message type + * that has the same name as an existing package. + */ + private static final class PackageDescriptor implements GenericDescriptor { + public Message toProto() { return file.toProto(); } + public String getName() { return name; } + public String getFullName() { return fullName; } + public FileDescriptor getFile() { return file; } + + PackageDescriptor(final String name, final String fullName, + final FileDescriptor file) { + this.file = file; + this.fullName = fullName; + this.name = name; + } + + private final String name; + private final String fullName; + private final FileDescriptor file; + } + + /** + * Adds a package to the symbol tables. If a package by the same name + * already exists, that is fine, but if some other kind of symbol exists + * under the same name, an exception is thrown. If the package has + * multiple components, this also adds the parent package(s). + */ + void addPackage(final String fullName, final FileDescriptor file) + throws DescriptorValidationException { + final int dotpos = fullName.lastIndexOf('.'); + final String name; + if (dotpos == -1) { + name = fullName; + } else { + addPackage(fullName.substring(0, dotpos), file); + name = fullName.substring(dotpos + 1); + } + + final GenericDescriptor old = + descriptorsByName.put(fullName, + new PackageDescriptor(name, fullName, file)); + if (old != null) { + descriptorsByName.put(fullName, old); + if (!(old instanceof PackageDescriptor)) { + throw new DescriptorValidationException(file, + '\"' + name + "\" is already defined (as something other than a " + + "package) in file \"" + old.getFile().getName() + "\"."); + } + } + } + + /** A (GenericDescriptor, int) pair, used as a map key. */ + private static final class DescriptorIntPair { + private final GenericDescriptor descriptor; + private final int number; + + DescriptorIntPair(final GenericDescriptor descriptor, final int number) { + this.descriptor = descriptor; + this.number = number; + } + + @Override + public int hashCode() { + return descriptor.hashCode() * ((1 << 16) - 1) + number; + } + @Override + public boolean equals(final Object obj) { + if (!(obj instanceof DescriptorIntPair)) { + return false; + } + final DescriptorIntPair other = (DescriptorIntPair)obj; + return descriptor == other.descriptor && number == other.number; + } + } + + /** + * Adds a field to the fieldsByNumber table. Throws an exception if a + * field with the same containing type and number already exists. + */ + void addFieldByNumber(final FieldDescriptor field) + throws DescriptorValidationException { + final DescriptorIntPair key = + new DescriptorIntPair(field.getContainingType(), field.getNumber()); + final FieldDescriptor old = fieldsByNumber.put(key, field); + if (old != null) { + fieldsByNumber.put(key, old); + throw new DescriptorValidationException(field, + "Field number " + field.getNumber() + + "has already been used in \"" + + field.getContainingType().getFullName() + + "\" by field \"" + old.getName() + "\"."); + } + } + + /** + * Adds an enum value to the enumValuesByNumber table. If an enum value + * with the same type and number already exists, does nothing. (This is + * allowed; the first value define with the number takes precedence.) + */ + void addEnumValueByNumber(final EnumValueDescriptor value) { + final DescriptorIntPair key = + new DescriptorIntPair(value.getType(), value.getNumber()); + final EnumValueDescriptor old = enumValuesByNumber.put(key, value); + if (old != null) { + enumValuesByNumber.put(key, old); + // Not an error: Multiple enum values may have the same number, but + // we only want the first one in the map. + } + } + + /** + * Verifies that the descriptor's name is valid (i.e. it contains only + * letters, digits, and underscores, and does not start with a digit). + */ + static void validateSymbolName(final GenericDescriptor descriptor) + throws DescriptorValidationException { + final String name = descriptor.getName(); + if (name.length() == 0) { + throw new DescriptorValidationException(descriptor, "Missing name."); + } else { + boolean valid = true; + for (int i = 0; i < name.length(); i++) { + final char c = name.charAt(i); + // Non-ASCII characters are not valid in protobuf identifiers, even + // if they are letters or digits. + if (c >= 128) { + valid = false; + } + // First character must be letter or _. Subsequent characters may + // be letters, numbers, or digits. + if (Character.isLetter(c) || c == '_' || + (Character.isDigit(c) && i > 0)) { + // Valid + } else { + valid = false; + } + } + if (!valid) { + throw new DescriptorValidationException(descriptor, + '\"' + name + "\" is not a valid identifier."); + } + } + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/DynamicMessage.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/DynamicMessage.java new file mode 100644 index 0000000..c0c9fc9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/DynamicMessage.java @@ -0,0 +1,482 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.FieldDescriptor; + +import java.io.InputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.Map; + +/** + * An implementation of {@link Message} that can represent arbitrary types, + * given a {@link Descriptors.Descriptor}. + * + * @author kenton@google.com Kenton Varda + */ +public final class DynamicMessage extends AbstractMessage { + private final Descriptor type; + private final FieldSet fields; + private final UnknownFieldSet unknownFields; + private int memoizedSize = -1; + + /** + * Construct a {@code DynamicMessage} using the given {@code FieldSet}. + */ + private DynamicMessage(Descriptor type, FieldSet fields, + UnknownFieldSet unknownFields) { + this.type = type; + this.fields = fields; + this.unknownFields = unknownFields; + } + + /** + * Get a {@code DynamicMessage} representing the default instance of the + * given type. + */ + public static DynamicMessage getDefaultInstance(Descriptor type) { + return new DynamicMessage(type, FieldSet.emptySet(), + UnknownFieldSet.getDefaultInstance()); + } + + /** Parse a message of the given type from the given input stream. */ + public static DynamicMessage parseFrom(Descriptor type, + CodedInputStream input) + throws IOException { + return newBuilder(type).mergeFrom(input).buildParsed(); + } + + /** Parse a message of the given type from the given input stream. */ + public static DynamicMessage parseFrom( + Descriptor type, + CodedInputStream input, + ExtensionRegistry extensionRegistry) + throws IOException { + return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed(); + } + + /** Parse {@code data} as a message of the given type and return it. */ + public static DynamicMessage parseFrom(Descriptor type, ByteString data) + throws InvalidProtocolBufferException { + return newBuilder(type).mergeFrom(data).buildParsed(); + } + + /** Parse {@code data} as a message of the given type and return it. */ + public static DynamicMessage parseFrom(Descriptor type, ByteString data, + ExtensionRegistry extensionRegistry) + throws InvalidProtocolBufferException { + return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed(); + } + + /** Parse {@code data} as a message of the given type and return it. */ + public static DynamicMessage parseFrom(Descriptor type, byte[] data) + throws InvalidProtocolBufferException { + return newBuilder(type).mergeFrom(data).buildParsed(); + } + + /** Parse {@code data} as a message of the given type and return it. */ + public static DynamicMessage parseFrom(Descriptor type, byte[] data, + ExtensionRegistry extensionRegistry) + throws InvalidProtocolBufferException { + return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed(); + } + + /** Parse a message of the given type from {@code input} and return it. */ + public static DynamicMessage parseFrom(Descriptor type, InputStream input) + throws IOException { + return newBuilder(type).mergeFrom(input).buildParsed(); + } + + /** Parse a message of the given type from {@code input} and return it. */ + public static DynamicMessage parseFrom(Descriptor type, InputStream input, + ExtensionRegistry extensionRegistry) + throws IOException { + return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed(); + } + + /** Construct a {@link Message.Builder} for the given type. */ + public static Builder newBuilder(Descriptor type) { + return new Builder(type); + } + + /** + * Construct a {@link Message.Builder} for a message of the same type as + * {@code prototype}, and initialize it with {@code prototype}'s contents. + */ + public static Builder newBuilder(Message prototype) { + return new Builder(prototype.getDescriptorForType()).mergeFrom(prototype); + } + + // ----------------------------------------------------------------- + // Implementation of Message interface. + + public Descriptor getDescriptorForType() { + return type; + } + + public DynamicMessage getDefaultInstanceForType() { + return getDefaultInstance(type); + } + + public Map getAllFields() { + return fields.getAllFields(); + } + + public boolean hasField(FieldDescriptor field) { + verifyContainingType(field); + return fields.hasField(field); + } + + public Object getField(FieldDescriptor field) { + verifyContainingType(field); + Object result = fields.getField(field); + if (result == null) { + if (field.isRepeated()) { + result = Collections.emptyList(); + } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + result = getDefaultInstance(field.getMessageType()); + } else { + result = field.getDefaultValue(); + } + } + return result; + } + + public int getRepeatedFieldCount(FieldDescriptor field) { + verifyContainingType(field); + return fields.getRepeatedFieldCount(field); + } + + public Object getRepeatedField(FieldDescriptor field, int index) { + verifyContainingType(field); + return fields.getRepeatedField(field, index); + } + + public UnknownFieldSet getUnknownFields() { + return unknownFields; + } + + private static boolean isInitialized(Descriptor type, + FieldSet fields) { + // Check that all required fields are present. + for (final FieldDescriptor field : type.getFields()) { + if (field.isRequired()) { + if (!fields.hasField(field)) { + return false; + } + } + } + + // Check that embedded messages are initialized. + return fields.isInitialized(); + } + + @Override + public boolean isInitialized() { + return isInitialized(type, fields); + } + + @Override + public void writeTo(CodedOutputStream output) throws IOException { + if (type.getOptions().getMessageSetWireFormat()) { + fields.writeMessageSetTo(output); + unknownFields.writeAsMessageSetTo(output); + } else { + fields.writeTo(output); + unknownFields.writeTo(output); + } + } + + @Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + if (type.getOptions().getMessageSetWireFormat()) { + size = fields.getMessageSetSerializedSize(); + size += unknownFields.getSerializedSizeAsMessageSet(); + } else { + size = fields.getSerializedSize(); + size += unknownFields.getSerializedSize(); + } + + memoizedSize = size; + return size; + } + + public Builder newBuilderForType() { + return new Builder(type); + } + + public Builder toBuilder() { + return newBuilderForType().mergeFrom(this); + } + + public Parser getParserForType() { + return new AbstractParser() { + public DynamicMessage parsePartialFrom( + CodedInputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + Builder builder = newBuilder(type); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (IOException e) { + throw new InvalidProtocolBufferException(e.getMessage()) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + } + + /** Verifies that the field is a field of this message. */ + private void verifyContainingType(FieldDescriptor field) { + if (field.getContainingType() != type) { + throw new IllegalArgumentException( + "FieldDescriptor does not match message type."); + } + } + + // ================================================================= + + /** + * Builder for {@link DynamicMessage}s. + */ + public static final class Builder extends AbstractMessage.Builder { + private final Descriptor type; + private FieldSet fields; + private UnknownFieldSet unknownFields; + + /** Construct a {@code Builder} for the given type. */ + private Builder(Descriptor type) { + this.type = type; + this.fields = FieldSet.newFieldSet(); + this.unknownFields = UnknownFieldSet.getDefaultInstance(); + } + + // --------------------------------------------------------------- + // Implementation of Message.Builder interface. + + @Override + public Builder clear() { + if (fields.isImmutable()) { + fields = FieldSet.newFieldSet(); + } else { + fields.clear(); + } + unknownFields = UnknownFieldSet.getDefaultInstance(); + return this; + } + + @Override + public Builder mergeFrom(Message other) { + if (other instanceof DynamicMessage) { + // This should be somewhat faster than calling super.mergeFrom(). + DynamicMessage otherDynamicMessage = (DynamicMessage) other; + if (otherDynamicMessage.type != type) { + throw new IllegalArgumentException( + "mergeFrom(Message) can only merge messages of the same type."); + } + ensureIsMutable(); + fields.mergeFrom(otherDynamicMessage.fields); + mergeUnknownFields(otherDynamicMessage.unknownFields); + return this; + } else { + return super.mergeFrom(other); + } + } + + public DynamicMessage build() { + if (!isInitialized()) { + throw newUninitializedMessageException( + new DynamicMessage(type, fields, unknownFields)); + } + return buildPartial(); + } + + /** + * Helper for DynamicMessage.parseFrom() methods to call. Throws + * {@link InvalidProtocolBufferException} instead of + * {@link UninitializedMessageException}. + */ + private DynamicMessage buildParsed() throws InvalidProtocolBufferException { + if (!isInitialized()) { + throw newUninitializedMessageException( + new DynamicMessage(type, fields, unknownFields)) + .asInvalidProtocolBufferException(); + } + return buildPartial(); + } + + public DynamicMessage buildPartial() { + fields.makeImmutable(); + DynamicMessage result = + new DynamicMessage(type, fields, unknownFields); + return result; + } + + @Override + public Builder clone() { + Builder result = new Builder(type); + result.fields.mergeFrom(fields); + result.mergeUnknownFields(unknownFields); + return result; + } + + public boolean isInitialized() { + return DynamicMessage.isInitialized(type, fields); + } + + public Descriptor getDescriptorForType() { + return type; + } + + public DynamicMessage getDefaultInstanceForType() { + return getDefaultInstance(type); + } + + public Map getAllFields() { + return fields.getAllFields(); + } + + public Builder newBuilderForField(FieldDescriptor field) { + verifyContainingType(field); + + if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { + throw new IllegalArgumentException( + "newBuilderForField is only valid for fields with message type."); + } + + return new Builder(field.getMessageType()); + } + + public boolean hasField(FieldDescriptor field) { + verifyContainingType(field); + return fields.hasField(field); + } + + public Object getField(FieldDescriptor field) { + verifyContainingType(field); + Object result = fields.getField(field); + if (result == null) { + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + result = getDefaultInstance(field.getMessageType()); + } else { + result = field.getDefaultValue(); + } + } + return result; + } + + public Builder setField(FieldDescriptor field, Object value) { + verifyContainingType(field); + ensureIsMutable(); + fields.setField(field, value); + return this; + } + + public Builder clearField(FieldDescriptor field) { + verifyContainingType(field); + ensureIsMutable(); + fields.clearField(field); + return this; + } + + public int getRepeatedFieldCount(FieldDescriptor field) { + verifyContainingType(field); + return fields.getRepeatedFieldCount(field); + } + + public Object getRepeatedField(FieldDescriptor field, int index) { + verifyContainingType(field); + return fields.getRepeatedField(field, index); + } + + public Builder setRepeatedField(FieldDescriptor field, + int index, Object value) { + verifyContainingType(field); + ensureIsMutable(); + fields.setRepeatedField(field, index, value); + return this; + } + + public Builder addRepeatedField(FieldDescriptor field, Object value) { + verifyContainingType(field); + ensureIsMutable(); + fields.addRepeatedField(field, value); + return this; + } + + public UnknownFieldSet getUnknownFields() { + return unknownFields; + } + + public Builder setUnknownFields(UnknownFieldSet unknownFields) { + this.unknownFields = unknownFields; + return this; + } + + @Override + public Builder mergeUnknownFields(UnknownFieldSet unknownFields) { + this.unknownFields = + UnknownFieldSet.newBuilder(this.unknownFields) + .mergeFrom(unknownFields) + .build(); + return this; + } + + /** Verifies that the field is a field of this message. */ + private void verifyContainingType(FieldDescriptor field) { + if (field.getContainingType() != type) { + throw new IllegalArgumentException( + "FieldDescriptor does not match message type."); + } + } + + private void ensureIsMutable() { + if (fields.isImmutable()) { + fields = fields.clone(); + } + } + + @Override + public com.google.protobuf.Message.Builder getFieldBuilder(FieldDescriptor field) { + // TODO(xiangl): need implementation for dynamic message + throw new UnsupportedOperationException( + "getFieldBuilder() called on a dynamic message type."); + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ExtensionRegistry.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ExtensionRegistry.java new file mode 100644 index 0000000..d4f6ba9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ExtensionRegistry.java @@ -0,0 +1,266 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.FieldDescriptor; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * A table of known extensions, searchable by name or field number. When + * parsing a protocol message that might have extensions, you must provide + * an {@code ExtensionRegistry} in which you have registered any extensions + * that you want to be able to parse. Otherwise, those extensions will just + * be treated like unknown fields. + * + *

For example, if you had the {@code .proto} file: + * + *

+ * option java_class = "MyProto";
+ *
+ * message Foo {
+ *   extensions 1000 to max;
+ * }
+ *
+ * extend Foo {
+ *   optional int32 bar;
+ * }
+ * 
+ * + * Then you might write code like: + * + *
+ * ExtensionRegistry registry = ExtensionRegistry.newInstance();
+ * registry.add(MyProto.bar);
+ * MyProto.Foo message = MyProto.Foo.parseFrom(input, registry);
+ * 
+ * + *

Background: + * + *

You might wonder why this is necessary. Two alternatives might come to + * mind. First, you might imagine a system where generated extensions are + * automatically registered when their containing classes are loaded. This + * is a popular technique, but is bad design; among other things, it creates a + * situation where behavior can change depending on what classes happen to be + * loaded. It also introduces a security vulnerability, because an + * unprivileged class could cause its code to be called unexpectedly from a + * privileged class by registering itself as an extension of the right type. + * + *

Another option you might consider is lazy parsing: do not parse an + * extension until it is first requested, at which point the caller must + * provide a type to use. This introduces a different set of problems. First, + * it would require a mutex lock any time an extension was accessed, which + * would be slow. Second, corrupt data would not be detected until first + * access, at which point it would be much harder to deal with it. Third, it + * could violate the expectation that message objects are immutable, since the + * type provided could be any arbitrary message class. An unprivileged user + * could take advantage of this to inject a mutable object into a message + * belonging to privileged code and create mischief. + * + * @author kenton@google.com Kenton Varda + */ +public final class ExtensionRegistry extends ExtensionRegistryLite { + /** Construct a new, empty instance. */ + public static ExtensionRegistry newInstance() { + return new ExtensionRegistry(); + } + + /** Get the unmodifiable singleton empty instance. */ + public static ExtensionRegistry getEmptyRegistry() { + return EMPTY; + } + + /** Returns an unmodifiable view of the registry. */ + @Override + public ExtensionRegistry getUnmodifiable() { + return new ExtensionRegistry(this); + } + + /** A (Descriptor, Message) pair, returned by lookup methods. */ + public static final class ExtensionInfo { + /** The extension's descriptor. */ + public final FieldDescriptor descriptor; + + /** + * A default instance of the extension's type, if it has a message type. + * Otherwise, {@code null}. + */ + public final Message defaultInstance; + + private ExtensionInfo(final FieldDescriptor descriptor) { + this.descriptor = descriptor; + defaultInstance = null; + } + private ExtensionInfo(final FieldDescriptor descriptor, + final Message defaultInstance) { + this.descriptor = descriptor; + this.defaultInstance = defaultInstance; + } + } + + /** + * Find an extension by fully-qualified field name, in the proto namespace. + * I.e. {@code result.descriptor.fullName()} will match {@code fullName} if + * a match is found. + * + * @return Information about the extension if found, or {@code null} + * otherwise. + */ + public ExtensionInfo findExtensionByName(final String fullName) { + return extensionsByName.get(fullName); + } + + /** + * Find an extension by containing type and field number. + * + * @return Information about the extension if found, or {@code null} + * otherwise. + */ + public ExtensionInfo findExtensionByNumber(final Descriptor containingType, + final int fieldNumber) { + return extensionsByNumber.get( + new DescriptorIntPair(containingType, fieldNumber)); + } + + /** Add an extension from a generated file to the registry. */ + public void add(final GeneratedMessage.GeneratedExtension extension) { + if (extension.getDescriptor().getJavaType() == + FieldDescriptor.JavaType.MESSAGE) { + if (extension.getMessageDefaultInstance() == null) { + throw new IllegalStateException( + "Registered message-type extension had null default instance: " + + extension.getDescriptor().getFullName()); + } + add(new ExtensionInfo(extension.getDescriptor(), + extension.getMessageDefaultInstance())); + } else { + add(new ExtensionInfo(extension.getDescriptor(), null)); + } + } + + /** Add a non-message-type extension to the registry by descriptor. */ + public void add(final FieldDescriptor type) { + if (type.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + throw new IllegalArgumentException( + "ExtensionRegistry.add() must be provided a default instance when " + + "adding an embedded message extension."); + } + add(new ExtensionInfo(type, null)); + } + + /** Add a message-type extension to the registry by descriptor. */ + public void add(final FieldDescriptor type, final Message defaultInstance) { + if (type.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { + throw new IllegalArgumentException( + "ExtensionRegistry.add() provided a default instance for a " + + "non-message extension."); + } + add(new ExtensionInfo(type, defaultInstance)); + } + + // ================================================================= + // Private stuff. + + private ExtensionRegistry() { + this.extensionsByName = new HashMap(); + this.extensionsByNumber = new HashMap(); + } + + private ExtensionRegistry(ExtensionRegistry other) { + super(other); + this.extensionsByName = Collections.unmodifiableMap(other.extensionsByName); + this.extensionsByNumber = + Collections.unmodifiableMap(other.extensionsByNumber); + } + + private final Map extensionsByName; + private final Map extensionsByNumber; + + private ExtensionRegistry(boolean empty) { + super(ExtensionRegistryLite.getEmptyRegistry()); + this.extensionsByName = Collections.emptyMap(); + this.extensionsByNumber = + Collections.emptyMap(); + } + private static final ExtensionRegistry EMPTY = new ExtensionRegistry(true); + + private void add(final ExtensionInfo extension) { + if (!extension.descriptor.isExtension()) { + throw new IllegalArgumentException( + "ExtensionRegistry.add() was given a FieldDescriptor for a regular " + + "(non-extension) field."); + } + + extensionsByName.put(extension.descriptor.getFullName(), extension); + extensionsByNumber.put( + new DescriptorIntPair(extension.descriptor.getContainingType(), + extension.descriptor.getNumber()), + extension); + + final FieldDescriptor field = extension.descriptor; + if (field.getContainingType().getOptions().getMessageSetWireFormat() && + field.getType() == FieldDescriptor.Type.MESSAGE && + field.isOptional() && + field.getExtensionScope() == field.getMessageType()) { + // This is an extension of a MessageSet type defined within the extension + // type's own scope. For backwards-compatibility, allow it to be looked + // up by type name. + extensionsByName.put(field.getMessageType().getFullName(), extension); + } + } + + /** A (GenericDescriptor, int) pair, used as a map key. */ + private static final class DescriptorIntPair { + private final Descriptor descriptor; + private final int number; + + DescriptorIntPair(final Descriptor descriptor, final int number) { + this.descriptor = descriptor; + this.number = number; + } + + @Override + public int hashCode() { + return descriptor.hashCode() * ((1 << 16) - 1) + number; + } + @Override + public boolean equals(final Object obj) { + if (!(obj instanceof DescriptorIntPair)) { + return false; + } + final DescriptorIntPair other = (DescriptorIntPair)obj; + return descriptor == other.descriptor && number == other.number; + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java new file mode 100644 index 0000000..1e1289d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java @@ -0,0 +1,185 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Equivalent to {@link ExtensionRegistry} but supports only "lite" types. + *

+ * If all of your types are lite types, then you only need to use + * {@code ExtensionRegistryLite}. Similarly, if all your types are regular + * types, then you only need {@link ExtensionRegistry}. Typically it does not + * make sense to mix the two, since if you have any regular types in your + * program, you then require the full runtime and lose all the benefits of + * the lite runtime, so you might as well make all your types be regular types. + * However, in some cases (e.g. when depending on multiple third-party libraries + * where one uses lite types and one uses regular), you may find yourself + * wanting to mix the two. In this case things get more complicated. + *

+ * There are three factors to consider: Whether the type being extended is + * lite, whether the embedded type (in the case of a message-typed extension) + * is lite, and whether the extension itself is lite. Since all three are + * declared in different files, they could all be different. Here are all + * the combinations and which type of registry to use: + *

+ *   Extended type     Inner type    Extension         Use registry
+ *   =======================================================================
+ *   lite              lite          lite              ExtensionRegistryLite
+ *   lite              regular       lite              ExtensionRegistry
+ *   regular           regular       regular           ExtensionRegistry
+ *   all other combinations                            not supported
+ * 
+ *

+ * Note that just as regular types are not allowed to contain lite-type fields, + * they are also not allowed to contain lite-type extensions. This is because + * regular types must be fully accessible via reflection, which in turn means + * that all the inner messages must also support reflection. On the other hand, + * since regular types implement the entire lite interface, there is no problem + * with embedding regular types inside lite types. + * + * @author kenton@google.com Kenton Varda + */ +public class ExtensionRegistryLite { + + // Set true to enable lazy parsing feature for MessageSet. + // + // TODO(xiangl): Now we use a global flag to control whether enable lazy + // parsing feature for MessageSet, which may be too crude for some + // applications. Need to support this feature on smaller granularity. + private static volatile boolean eagerlyParseMessageSets = false; + + public static boolean isEagerlyParseMessageSets() { + return eagerlyParseMessageSets; + } + + public static void setEagerlyParseMessageSets(boolean isEagerlyParse) { + eagerlyParseMessageSets = isEagerlyParse; + } + + /** Construct a new, empty instance. */ + public static ExtensionRegistryLite newInstance() { + return new ExtensionRegistryLite(); + } + + /** Get the unmodifiable singleton empty instance. */ + public static ExtensionRegistryLite getEmptyRegistry() { + return EMPTY; + } + + /** Returns an unmodifiable view of the registry. */ + public ExtensionRegistryLite getUnmodifiable() { + return new ExtensionRegistryLite(this); + } + + /** + * Find an extension by containing type and field number. + * + * @return Information about the extension if found, or {@code null} + * otherwise. + */ + @SuppressWarnings("unchecked") + public + GeneratedMessageLite.GeneratedExtension + findLiteExtensionByNumber( + final ContainingType containingTypeDefaultInstance, + final int fieldNumber) { + return (GeneratedMessageLite.GeneratedExtension) + extensionsByNumber.get( + new ObjectIntPair(containingTypeDefaultInstance, fieldNumber)); + } + + /** Add an extension from a lite generated file to the registry. */ + public final void add( + final GeneratedMessageLite.GeneratedExtension extension) { + extensionsByNumber.put( + new ObjectIntPair(extension.getContainingTypeDefaultInstance(), + extension.getNumber()), + extension); + } + + // ================================================================= + // Private stuff. + + // Constructors are package-private so that ExtensionRegistry can subclass + // this. + + ExtensionRegistryLite() { + this.extensionsByNumber = + new HashMap>(); + } + + ExtensionRegistryLite(ExtensionRegistryLite other) { + if (other == EMPTY) { + this.extensionsByNumber = Collections.emptyMap(); + } else { + this.extensionsByNumber = + Collections.unmodifiableMap(other.extensionsByNumber); + } + } + + private final Map> + extensionsByNumber; + + private ExtensionRegistryLite(boolean empty) { + this.extensionsByNumber = Collections.emptyMap(); + } + private static final ExtensionRegistryLite EMPTY = + new ExtensionRegistryLite(true); + + /** A (Object, int) pair, used as a map key. */ + private static final class ObjectIntPair { + private final Object object; + private final int number; + + ObjectIntPair(final Object object, final int number) { + this.object = object; + this.number = number; + } + + @Override + public int hashCode() { + return System.identityHashCode(object) * ((1 << 16) - 1) + number; + } + @Override + public boolean equals(final Object obj) { + if (!(obj instanceof ObjectIntPair)) { + return false; + } + final ObjectIntPair other = (ObjectIntPair)obj; + return object == other.object && number == other.number; + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/FieldSet.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/FieldSet.java new file mode 100644 index 0000000..2663694 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/FieldSet.java @@ -0,0 +1,861 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.LazyField.LazyIterator; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * A class which represents an arbitrary set of fields of some message type. + * This is used to implement {@link DynamicMessage}, and also to represent + * extensions in {@link GeneratedMessage}. This class is package-private, + * since outside users should probably be using {@link DynamicMessage}. + * + * @author kenton@google.com Kenton Varda + */ +final class FieldSet> { + /** + * Interface for a FieldDescriptor or lite extension descriptor. This + * prevents FieldSet from depending on {@link Descriptors.FieldDescriptor}. + */ + public interface FieldDescriptorLite> + extends Comparable { + int getNumber(); + WireFormat.FieldType getLiteType(); + WireFormat.JavaType getLiteJavaType(); + boolean isRepeated(); + boolean isPacked(); + Internal.EnumLiteMap getEnumType(); + + // If getLiteJavaType() == MESSAGE, this merges a message object of the + // type into a builder of the type. Returns {@code to}. + MessageLite.Builder internalMergeFrom( + MessageLite.Builder to, MessageLite from); + } + + private final SmallSortedMap fields; + private boolean isImmutable; + private boolean hasLazyField = false; + + /** Construct a new FieldSet. */ + private FieldSet() { + this.fields = SmallSortedMap.newFieldMap(16); + } + + /** + * Construct an empty FieldSet. This is only used to initialize + * DEFAULT_INSTANCE. + */ + private FieldSet(final boolean dummy) { + this.fields = SmallSortedMap.newFieldMap(0); + makeImmutable(); + } + + /** Construct a new FieldSet. */ + public static > + FieldSet newFieldSet() { + return new FieldSet(); + } + + /** Get an immutable empty FieldSet. */ + @SuppressWarnings("unchecked") + public static > + FieldSet emptySet() { + return DEFAULT_INSTANCE; + } + @SuppressWarnings("rawtypes") + private static final FieldSet DEFAULT_INSTANCE = new FieldSet(true); + + /** Make this FieldSet immutable from this point forward. */ + @SuppressWarnings("unchecked") + public void makeImmutable() { + if (isImmutable) { + return; + } + fields.makeImmutable(); + isImmutable = true; + } + + /** + * Returns whether the FieldSet is immutable. This is true if it is the + * {@link #emptySet} or if {@link #makeImmutable} were called. + * + * @return whether the FieldSet is immutable. + */ + public boolean isImmutable() { + return isImmutable; + } + + /** + * Clones the FieldSet. The returned FieldSet will be mutable even if the + * original FieldSet was immutable. + * + * @return the newly cloned FieldSet + */ + @Override + public FieldSet clone() { + // We can't just call fields.clone because List objects in the map + // should not be shared. + FieldSet clone = FieldSet.newFieldSet(); + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + Map.Entry entry = fields.getArrayEntryAt(i); + FieldDescriptorType descriptor = entry.getKey(); + clone.setField(descriptor, entry.getValue()); + } + for (Map.Entry entry : + fields.getOverflowEntries()) { + FieldDescriptorType descriptor = entry.getKey(); + clone.setField(descriptor, entry.getValue()); + } + clone.hasLazyField = hasLazyField; + return clone; + } + + // ================================================================= + + /** See {@link Message.Builder#clear()}. */ + public void clear() { + fields.clear(); + hasLazyField = false; + } + + /** + * Get a simple map containing all the fields. + */ + public Map getAllFields() { + if (hasLazyField) { + SmallSortedMap result = + SmallSortedMap.newFieldMap(16); + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + cloneFieldEntry(result, fields.getArrayEntryAt(i)); + } + for (Map.Entry entry : + fields.getOverflowEntries()) { + cloneFieldEntry(result, entry); + } + if (fields.isImmutable()) { + result.makeImmutable(); + } + return result; + } + return fields.isImmutable() ? fields : Collections.unmodifiableMap(fields); + } + + private void cloneFieldEntry(Map map, + Map.Entry entry) { + FieldDescriptorType key = entry.getKey(); + Object value = entry.getValue(); + if (value instanceof LazyField) { + map.put(key, ((LazyField) value).getValue()); + } else { + map.put(key, value); + } + } + + /** + * Get an iterator to the field map. This iterator should not be leaked out + * of the protobuf library as it is not protected from mutation when fields + * is not immutable. + */ + public Iterator> iterator() { + if (hasLazyField) { + return new LazyIterator( + fields.entrySet().iterator()); + } + return fields.entrySet().iterator(); + } + + /** + * Useful for implementing + * {@link Message#hasField(Descriptors.FieldDescriptor)}. + */ + public boolean hasField(final FieldDescriptorType descriptor) { + if (descriptor.isRepeated()) { + throw new IllegalArgumentException( + "hasField() can only be called on non-repeated fields."); + } + + return fields.get(descriptor) != null; + } + + /** + * Useful for implementing + * {@link Message#getField(Descriptors.FieldDescriptor)}. This method + * returns {@code null} if the field is not set; in this case it is up + * to the caller to fetch the field's default value. + */ + public Object getField(final FieldDescriptorType descriptor) { + Object o = fields.get(descriptor); + if (o instanceof LazyField) { + return ((LazyField) o).getValue(); + } + return o; + } + + /** + * Useful for implementing + * {@link Message.Builder#setField(Descriptors.FieldDescriptor,Object)}. + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + public void setField(final FieldDescriptorType descriptor, + Object value) { + if (descriptor.isRepeated()) { + if (!(value instanceof List)) { + throw new IllegalArgumentException( + "Wrong object type used with protocol message reflection."); + } + + // Wrap the contents in a new list so that the caller cannot change + // the list's contents after setting it. + final List newList = new ArrayList(); + newList.addAll((List) value); + for (final Object element : newList) { + verifyType(descriptor.getLiteType(), element); + } + value = newList; + } else { + verifyType(descriptor.getLiteType(), value); + } + + if (value instanceof LazyField) { + hasLazyField = true; + } + fields.put(descriptor, value); + } + + /** + * Useful for implementing + * {@link Message.Builder#clearField(Descriptors.FieldDescriptor)}. + */ + public void clearField(final FieldDescriptorType descriptor) { + fields.remove(descriptor); + if (fields.isEmpty()) { + hasLazyField = false; + } + } + + /** + * Useful for implementing + * {@link Message#getRepeatedFieldCount(Descriptors.FieldDescriptor)}. + */ + public int getRepeatedFieldCount(final FieldDescriptorType descriptor) { + if (!descriptor.isRepeated()) { + throw new IllegalArgumentException( + "getRepeatedField() can only be called on repeated fields."); + } + + final Object value = getField(descriptor); + if (value == null) { + return 0; + } else { + return ((List) value).size(); + } + } + + /** + * Useful for implementing + * {@link Message#getRepeatedField(Descriptors.FieldDescriptor,int)}. + */ + public Object getRepeatedField(final FieldDescriptorType descriptor, + final int index) { + if (!descriptor.isRepeated()) { + throw new IllegalArgumentException( + "getRepeatedField() can only be called on repeated fields."); + } + + final Object value = getField(descriptor); + + if (value == null) { + throw new IndexOutOfBoundsException(); + } else { + return ((List) value).get(index); + } + } + + /** + * Useful for implementing + * {@link Message.Builder#setRepeatedField(Descriptors.FieldDescriptor,int,Object)}. + */ + @SuppressWarnings("unchecked") + public void setRepeatedField(final FieldDescriptorType descriptor, + final int index, + final Object value) { + if (!descriptor.isRepeated()) { + throw new IllegalArgumentException( + "getRepeatedField() can only be called on repeated fields."); + } + + final Object list = getField(descriptor); + if (list == null) { + throw new IndexOutOfBoundsException(); + } + + verifyType(descriptor.getLiteType(), value); + ((List) list).set(index, value); + } + + /** + * Useful for implementing + * {@link Message.Builder#addRepeatedField(Descriptors.FieldDescriptor,Object)}. + */ + @SuppressWarnings("unchecked") + public void addRepeatedField(final FieldDescriptorType descriptor, + final Object value) { + if (!descriptor.isRepeated()) { + throw new IllegalArgumentException( + "addRepeatedField() can only be called on repeated fields."); + } + + verifyType(descriptor.getLiteType(), value); + + final Object existingValue = getField(descriptor); + List list; + if (existingValue == null) { + list = new ArrayList(); + fields.put(descriptor, list); + } else { + list = (List) existingValue; + } + + list.add(value); + } + + /** + * Verifies that the given object is of the correct type to be a valid + * value for the given field. (For repeated fields, this checks if the + * object is the right type to be one element of the field.) + * + * @throws IllegalArgumentException The value is not of the right type. + */ + private static void verifyType(final WireFormat.FieldType type, + final Object value) { + if (value == null) { + throw new NullPointerException(); + } + + boolean isValid = false; + switch (type.getJavaType()) { + case INT: isValid = value instanceof Integer ; break; + case LONG: isValid = value instanceof Long ; break; + case FLOAT: isValid = value instanceof Float ; break; + case DOUBLE: isValid = value instanceof Double ; break; + case BOOLEAN: isValid = value instanceof Boolean ; break; + case STRING: isValid = value instanceof String ; break; + case BYTE_STRING: isValid = value instanceof ByteString; break; + case ENUM: + // TODO(kenton): Caller must do type checking here, I guess. + isValid = value instanceof Internal.EnumLite; + break; + case MESSAGE: + // TODO(kenton): Caller must do type checking here, I guess. + isValid = + (value instanceof MessageLite) || (value instanceof LazyField); + break; + } + + if (!isValid) { + // TODO(kenton): When chaining calls to setField(), it can be hard to + // tell from the stack trace which exact call failed, since the whole + // chain is considered one line of code. It would be nice to print + // more information here, e.g. naming the field. We used to do that. + // But we can't now that FieldSet doesn't use descriptors. Maybe this + // isn't a big deal, though, since it would only really apply when using + // reflection and generally people don't chain reflection setters. + throw new IllegalArgumentException( + "Wrong object type used with protocol message reflection."); + } + } + + // ================================================================= + // Parsing and serialization + + /** + * See {@link Message#isInitialized()}. Note: Since {@code FieldSet} + * itself does not have any way of knowing about required fields that + * aren't actually present in the set, it is up to the caller to check + * that all required fields are present. + */ + public boolean isInitialized() { + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + if (!isInitialized(fields.getArrayEntryAt(i))) { + return false; + } + } + for (final Map.Entry entry : + fields.getOverflowEntries()) { + if (!isInitialized(entry)) { + return false; + } + } + return true; + } + + @SuppressWarnings("unchecked") + private boolean isInitialized( + final Map.Entry entry) { + final FieldDescriptorType descriptor = entry.getKey(); + if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) { + if (descriptor.isRepeated()) { + for (final MessageLite element: + (List) entry.getValue()) { + if (!element.isInitialized()) { + return false; + } + } + } else { + Object value = entry.getValue(); + if (value instanceof MessageLite) { + if (!((MessageLite) value).isInitialized()) { + return false; + } + } else if (value instanceof LazyField) { + return true; + } else { + throw new IllegalArgumentException( + "Wrong object type used with protocol message reflection."); + } + } + } + return true; + } + + /** + * Given a field type, return the wire type. + * + * @returns One of the {@code WIRETYPE_} constants defined in + * {@link WireFormat}. + */ + static int getWireFormatForFieldType(final WireFormat.FieldType type, + boolean isPacked) { + if (isPacked) { + return WireFormat.WIRETYPE_LENGTH_DELIMITED; + } else { + return type.getWireType(); + } + } + + /** + * Like {@link Message.Builder#mergeFrom(Message)}, but merges from another + * {@link FieldSet}. + */ + public void mergeFrom(final FieldSet other) { + for (int i = 0; i < other.fields.getNumArrayEntries(); i++) { + mergeFromField(other.fields.getArrayEntryAt(i)); + } + for (final Map.Entry entry : + other.fields.getOverflowEntries()) { + mergeFromField(entry); + } + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + private void mergeFromField( + final Map.Entry entry) { + final FieldDescriptorType descriptor = entry.getKey(); + Object otherValue = entry.getValue(); + if (otherValue instanceof LazyField) { + otherValue = ((LazyField) otherValue).getValue(); + } + + if (descriptor.isRepeated()) { + Object value = getField(descriptor); + if (value == null) { + // Our list is empty, but we still need to make a defensive copy of + // the other list since we don't know if the other FieldSet is still + // mutable. + fields.put(descriptor, new ArrayList((List) otherValue)); + } else { + // Concatenate the lists. + ((List) value).addAll((List) otherValue); + } + } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) { + Object value = getField(descriptor); + if (value == null) { + fields.put(descriptor, otherValue); + } else { + // Merge the messages. + fields.put( + descriptor, + descriptor.internalMergeFrom( + ((MessageLite) value).toBuilder(), (MessageLite) otherValue) + .build()); + } + } else { + fields.put(descriptor, otherValue); + } + } + + // TODO(kenton): Move static parsing and serialization methods into some + // other class. Probably WireFormat. + + /** + * Read a field of any primitive type from a CodedInputStream. Enums, + * groups, and embedded messages are not handled by this method. + * + * @param input The stream from which to read. + * @param type Declared type of the field. + * @return An object representing the field's value, of the exact + * type which would be returned by + * {@link Message#getField(Descriptors.FieldDescriptor)} for + * this field. + */ + public static Object readPrimitiveField( + CodedInputStream input, + final WireFormat.FieldType type) throws IOException { + switch (type) { + case DOUBLE : return input.readDouble (); + case FLOAT : return input.readFloat (); + case INT64 : return input.readInt64 (); + case UINT64 : return input.readUInt64 (); + case INT32 : return input.readInt32 (); + case FIXED64 : return input.readFixed64 (); + case FIXED32 : return input.readFixed32 (); + case BOOL : return input.readBool (); + case STRING : return input.readString (); + case BYTES : return input.readBytes (); + case UINT32 : return input.readUInt32 (); + case SFIXED32: return input.readSFixed32(); + case SFIXED64: return input.readSFixed64(); + case SINT32 : return input.readSInt32 (); + case SINT64 : return input.readSInt64 (); + + case GROUP: + throw new IllegalArgumentException( + "readPrimitiveField() cannot handle nested groups."); + case MESSAGE: + throw new IllegalArgumentException( + "readPrimitiveField() cannot handle embedded messages."); + case ENUM: + // We don't handle enums because we don't know what to do if the + // value is not recognized. + throw new IllegalArgumentException( + "readPrimitiveField() cannot handle enums."); + } + + throw new RuntimeException( + "There is no way to get here, but the compiler thinks otherwise."); + } + + /** See {@link Message#writeTo(CodedOutputStream)}. */ + public void writeTo(final CodedOutputStream output) + throws IOException { + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + final Map.Entry entry = + fields.getArrayEntryAt(i); + writeField(entry.getKey(), entry.getValue(), output); + } + for (final Map.Entry entry : + fields.getOverflowEntries()) { + writeField(entry.getKey(), entry.getValue(), output); + } + } + + /** + * Like {@link #writeTo} but uses MessageSet wire format. + */ + public void writeMessageSetTo(final CodedOutputStream output) + throws IOException { + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + writeMessageSetTo(fields.getArrayEntryAt(i), output); + } + for (final Map.Entry entry : + fields.getOverflowEntries()) { + writeMessageSetTo(entry, output); + } + } + + private void writeMessageSetTo( + final Map.Entry entry, + final CodedOutputStream output) throws IOException { + final FieldDescriptorType descriptor = entry.getKey(); + if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE && + !descriptor.isRepeated() && !descriptor.isPacked()) { + output.writeMessageSetExtension(entry.getKey().getNumber(), + (MessageLite) entry.getValue()); + } else { + writeField(descriptor, entry.getValue(), output); + } + } + + /** + * Write a single tag-value pair to the stream. + * + * @param output The output stream. + * @param type The field's type. + * @param number The field's number. + * @param value Object representing the field's value. Must be of the exact + * type which would be returned by + * {@link Message#getField(Descriptors.FieldDescriptor)} for + * this field. + */ + private static void writeElement(final CodedOutputStream output, + final WireFormat.FieldType type, + final int number, + final Object value) throws IOException { + // Special case for groups, which need a start and end tag; other fields + // can just use writeTag() and writeFieldNoTag(). + if (type == WireFormat.FieldType.GROUP) { + output.writeGroup(number, (MessageLite) value); + } else { + output.writeTag(number, getWireFormatForFieldType(type, false)); + writeElementNoTag(output, type, value); + } + } + + /** + * Write a field of arbitrary type, without its tag, to the stream. + * + * @param output The output stream. + * @param type The field's type. + * @param value Object representing the field's value. Must be of the exact + * type which would be returned by + * {@link Message#getField(Descriptors.FieldDescriptor)} for + * this field. + */ + private static void writeElementNoTag( + final CodedOutputStream output, + final WireFormat.FieldType type, + final Object value) throws IOException { + switch (type) { + case DOUBLE : output.writeDoubleNoTag ((Double ) value); break; + case FLOAT : output.writeFloatNoTag ((Float ) value); break; + case INT64 : output.writeInt64NoTag ((Long ) value); break; + case UINT64 : output.writeUInt64NoTag ((Long ) value); break; + case INT32 : output.writeInt32NoTag ((Integer ) value); break; + case FIXED64 : output.writeFixed64NoTag ((Long ) value); break; + case FIXED32 : output.writeFixed32NoTag ((Integer ) value); break; + case BOOL : output.writeBoolNoTag ((Boolean ) value); break; + case STRING : output.writeStringNoTag ((String ) value); break; + case GROUP : output.writeGroupNoTag ((MessageLite) value); break; + case MESSAGE : output.writeMessageNoTag ((MessageLite) value); break; + case BYTES : output.writeBytesNoTag ((ByteString ) value); break; + case UINT32 : output.writeUInt32NoTag ((Integer ) value); break; + case SFIXED32: output.writeSFixed32NoTag((Integer ) value); break; + case SFIXED64: output.writeSFixed64NoTag((Long ) value); break; + case SINT32 : output.writeSInt32NoTag ((Integer ) value); break; + case SINT64 : output.writeSInt64NoTag ((Long ) value); break; + + case ENUM: + output.writeEnumNoTag(((Internal.EnumLite) value).getNumber()); + break; + } + } + + /** Write a single field. */ + public static void writeField(final FieldDescriptorLite descriptor, + final Object value, + final CodedOutputStream output) + throws IOException { + WireFormat.FieldType type = descriptor.getLiteType(); + int number = descriptor.getNumber(); + if (descriptor.isRepeated()) { + final List valueList = (List)value; + if (descriptor.isPacked()) { + output.writeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED); + // Compute the total data size so the length can be written. + int dataSize = 0; + for (final Object element : valueList) { + dataSize += computeElementSizeNoTag(type, element); + } + output.writeRawVarint32(dataSize); + // Write the data itself, without any tags. + for (final Object element : valueList) { + writeElementNoTag(output, type, element); + } + } else { + for (final Object element : valueList) { + writeElement(output, type, number, element); + } + } + } else { + if (value instanceof LazyField) { + writeElement(output, type, number, ((LazyField) value).getValue()); + } else { + writeElement(output, type, number, value); + } + } + } + + /** + * See {@link Message#getSerializedSize()}. It's up to the caller to cache + * the resulting size if desired. + */ + public int getSerializedSize() { + int size = 0; + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + final Map.Entry entry = + fields.getArrayEntryAt(i); + size += computeFieldSize(entry.getKey(), entry.getValue()); + } + for (final Map.Entry entry : + fields.getOverflowEntries()) { + size += computeFieldSize(entry.getKey(), entry.getValue()); + } + return size; + } + + /** + * Like {@link #getSerializedSize} but uses MessageSet wire format. + */ + public int getMessageSetSerializedSize() { + int size = 0; + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + size += getMessageSetSerializedSize(fields.getArrayEntryAt(i)); + } + for (final Map.Entry entry : + fields.getOverflowEntries()) { + size += getMessageSetSerializedSize(entry); + } + return size; + } + + private int getMessageSetSerializedSize( + final Map.Entry entry) { + final FieldDescriptorType descriptor = entry.getKey(); + Object value = entry.getValue(); + if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE + && !descriptor.isRepeated() && !descriptor.isPacked()) { + if (value instanceof LazyField) { + return CodedOutputStream.computeLazyFieldMessageSetExtensionSize( + entry.getKey().getNumber(), (LazyField) value); + } else { + return CodedOutputStream.computeMessageSetExtensionSize( + entry.getKey().getNumber(), (MessageLite) value); + } + } else { + return computeFieldSize(descriptor, value); + } + } + + /** + * Compute the number of bytes that would be needed to encode a + * single tag/value pair of arbitrary type. + * + * @param type The field's type. + * @param number The field's number. + * @param value Object representing the field's value. Must be of the exact + * type which would be returned by + * {@link Message#getField(Descriptors.FieldDescriptor)} for + * this field. + */ + private static int computeElementSize( + final WireFormat.FieldType type, + final int number, final Object value) { + int tagSize = CodedOutputStream.computeTagSize(number); + if (type == WireFormat.FieldType.GROUP) { + tagSize *= 2; + } + return tagSize + computeElementSizeNoTag(type, value); + } + + /** + * Compute the number of bytes that would be needed to encode a + * particular value of arbitrary type, excluding tag. + * + * @param type The field's type. + * @param value Object representing the field's value. Must be of the exact + * type which would be returned by + * {@link Message#getField(Descriptors.FieldDescriptor)} for + * this field. + */ + private static int computeElementSizeNoTag( + final WireFormat.FieldType type, final Object value) { + switch (type) { + // Note: Minor violation of 80-char limit rule here because this would + // actually be harder to read if we wrapped the lines. + case DOUBLE : return CodedOutputStream.computeDoubleSizeNoTag ((Double )value); + case FLOAT : return CodedOutputStream.computeFloatSizeNoTag ((Float )value); + case INT64 : return CodedOutputStream.computeInt64SizeNoTag ((Long )value); + case UINT64 : return CodedOutputStream.computeUInt64SizeNoTag ((Long )value); + case INT32 : return CodedOutputStream.computeInt32SizeNoTag ((Integer )value); + case FIXED64 : return CodedOutputStream.computeFixed64SizeNoTag ((Long )value); + case FIXED32 : return CodedOutputStream.computeFixed32SizeNoTag ((Integer )value); + case BOOL : return CodedOutputStream.computeBoolSizeNoTag ((Boolean )value); + case STRING : return CodedOutputStream.computeStringSizeNoTag ((String )value); + case GROUP : return CodedOutputStream.computeGroupSizeNoTag ((MessageLite)value); + case BYTES : return CodedOutputStream.computeBytesSizeNoTag ((ByteString )value); + case UINT32 : return CodedOutputStream.computeUInt32SizeNoTag ((Integer )value); + case SFIXED32: return CodedOutputStream.computeSFixed32SizeNoTag((Integer )value); + case SFIXED64: return CodedOutputStream.computeSFixed64SizeNoTag((Long )value); + case SINT32 : return CodedOutputStream.computeSInt32SizeNoTag ((Integer )value); + case SINT64 : return CodedOutputStream.computeSInt64SizeNoTag ((Long )value); + + case MESSAGE: + if (value instanceof LazyField) { + return CodedOutputStream.computeLazyFieldSizeNoTag((LazyField) value); + } else { + return CodedOutputStream.computeMessageSizeNoTag((MessageLite) value); + } + + case ENUM: + return CodedOutputStream.computeEnumSizeNoTag( + ((Internal.EnumLite) value).getNumber()); + } + + throw new RuntimeException( + "There is no way to get here, but the compiler thinks otherwise."); + } + + /** + * Compute the number of bytes needed to encode a particular field. + */ + public static int computeFieldSize(final FieldDescriptorLite descriptor, + final Object value) { + WireFormat.FieldType type = descriptor.getLiteType(); + int number = descriptor.getNumber(); + if (descriptor.isRepeated()) { + if (descriptor.isPacked()) { + int dataSize = 0; + for (final Object element : (List)value) { + dataSize += computeElementSizeNoTag(type, element); + } + return dataSize + + CodedOutputStream.computeTagSize(number) + + CodedOutputStream.computeRawVarint32Size(dataSize); + } else { + int size = 0; + for (final Object element : (List)value) { + size += computeElementSize(type, number, element); + } + return size; + } + } else { + return computeElementSize(type, number, value); + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/GeneratedMessage.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/GeneratedMessage.java new file mode 100644 index 0000000..0c15ca8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/GeneratedMessage.java @@ -0,0 +1,1939 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.EnumValueDescriptor; +import com.google.protobuf.Descriptors.FieldDescriptor; + +import java.io.IOException; +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * All generated protocol message classes extend this class. This class + * implements most of the Message and Builder interfaces using Java reflection. + * Users can ignore this class and pretend that generated messages implement + * the Message interface directly. + * + * @author kenton@google.com Kenton Varda + */ +public abstract class GeneratedMessage extends AbstractMessage + implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * For testing. Allows a test to disable the optimization that avoids using + * field builders for nested messages until they are requested. By disabling + * this optimization, existing tests can be reused to test the field builders. + */ + protected static boolean alwaysUseFieldBuilders = false; + + protected GeneratedMessage() { + } + + protected GeneratedMessage(Builder builder) { + } + + public Parser getParserForType() { + throw new UnsupportedOperationException( + "This is supposed to be overridden by subclasses."); + } + + /** + * For testing. Allows a test to disable the optimization that avoids using + * field builders for nested messages until they are requested. By disabling + * this optimization, existing tests can be reused to test the field builders. + * See {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder}. + */ + static void enableAlwaysUseFieldBuildersForTesting() { + alwaysUseFieldBuilders = true; + } + + /** + * Get the FieldAccessorTable for this type. We can't have the message + * class pass this in to the constructor because of bootstrapping trouble + * with DescriptorProtos. + */ + protected abstract FieldAccessorTable internalGetFieldAccessorTable(); + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Descriptor getDescriptorForType() { + return internalGetFieldAccessorTable().descriptor; + } + + /** Internal helper which returns a mutable map. */ + private Map getAllFieldsMutable() { + final TreeMap result = + new TreeMap(); + final Descriptor descriptor = internalGetFieldAccessorTable().descriptor; + for (final FieldDescriptor field : descriptor.getFields()) { + if (field.isRepeated()) { + final List value = (List) getField(field); + if (!value.isEmpty()) { + result.put(field, value); + } + } else { + if (hasField(field)) { + result.put(field, getField(field)); + } + } + } + return result; + } + + @Override + public boolean isInitialized() { + for (final FieldDescriptor field : getDescriptorForType().getFields()) { + // Check that all required fields are present. + if (field.isRequired()) { + if (!hasField(field)) { + return false; + } + } + // Check that embedded messages are initialized. + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (field.isRepeated()) { + @SuppressWarnings("unchecked") final + List messageList = (List) getField(field); + for (final Message element : messageList) { + if (!element.isInitialized()) { + return false; + } + } + } else { + if (hasField(field) && !((Message) getField(field)).isInitialized()) { + return false; + } + } + } + } + + return true; + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Map getAllFields() { + return Collections.unmodifiableMap(getAllFieldsMutable()); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public boolean hasField(final FieldDescriptor field) { + return internalGetFieldAccessorTable().getField(field).has(this); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Object getField(final FieldDescriptor field) { + return internalGetFieldAccessorTable().getField(field).get(this); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public int getRepeatedFieldCount(final FieldDescriptor field) { + return internalGetFieldAccessorTable().getField(field) + .getRepeatedCount(this); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Object getRepeatedField(final FieldDescriptor field, final int index) { + return internalGetFieldAccessorTable().getField(field) + .getRepeated(this, index); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public UnknownFieldSet getUnknownFields() { + throw new UnsupportedOperationException( + "This is supposed to be overridden by subclasses."); + } + + /** + * Called by subclasses to parse an unknown field. + * @return {@code true} unless the tag is an end-group tag. + */ + protected boolean parseUnknownField( + CodedInputStream input, + UnknownFieldSet.Builder unknownFields, + ExtensionRegistryLite extensionRegistry, + int tag) throws IOException { + return unknownFields.mergeFieldFrom(tag, input); + } + + /** + * Used by parsing constructors in generated classes. + */ + protected void makeExtensionsImmutable() { + // Noop for messages without extensions. + } + + protected abstract Message.Builder newBuilderForType(BuilderParent parent); + + /** + * Interface for the parent of a Builder that allows the builder to + * communicate invalidations back to the parent for use when using nested + * builders. + */ + protected interface BuilderParent { + + /** + * A builder becomes dirty whenever a field is modified -- including fields + * in nested builders -- and becomes clean when build() is called. Thus, + * when a builder becomes dirty, all its parents become dirty as well, and + * when it becomes clean, all its children become clean. The dirtiness + * state is used to invalidate certain cached values. + *
+ * To this end, a builder calls markAsDirty() on its parent whenever it + * transitions from clean to dirty. The parent must propagate this call to + * its own parent, unless it was already dirty, in which case the + * grandparent must necessarily already be dirty as well. The parent can + * only transition back to "clean" after calling build() on all children. + */ + void markDirty(); + } + + @SuppressWarnings("unchecked") + public abstract static class Builder + extends AbstractMessage.Builder { + + private BuilderParent builderParent; + + private BuilderParentImpl meAsParent; + + // Indicates that we've built a message and so we are now obligated + // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener. + private boolean isClean; + + private UnknownFieldSet unknownFields = + UnknownFieldSet.getDefaultInstance(); + + protected Builder() { + this(null); + } + + protected Builder(BuilderParent builderParent) { + this.builderParent = builderParent; + } + + void dispose() { + builderParent = null; + } + + /** + * Called by the subclass when a message is built. + */ + protected void onBuilt() { + if (builderParent != null) { + markClean(); + } + } + + /** + * Called by the subclass or a builder to notify us that a message was + * built and may be cached and therefore invalidations are needed. + */ + protected void markClean() { + this.isClean = true; + } + + /** + * Gets whether invalidations are needed + * + * @return whether invalidations are needed + */ + protected boolean isClean() { + return isClean; + } + + // This is implemented here only to work around an apparent bug in the + // Java compiler and/or build system. See bug #1898463. The mere presence + // of this dummy clone() implementation makes it go away. + @Override + public BuilderType clone() { + throw new UnsupportedOperationException( + "This is supposed to be overridden by subclasses."); + } + + /** + * Called by the initialization and clear code paths to allow subclasses to + * reset any of their builtin fields back to the initial values. + */ + public BuilderType clear() { + unknownFields = UnknownFieldSet.getDefaultInstance(); + onChanged(); + return (BuilderType) this; + } + + /** + * Get the FieldAccessorTable for this type. We can't have the message + * class pass this in to the constructor because of bootstrapping trouble + * with DescriptorProtos. + */ + protected abstract FieldAccessorTable internalGetFieldAccessorTable(); + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Descriptor getDescriptorForType() { + return internalGetFieldAccessorTable().descriptor; + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Map getAllFields() { + return Collections.unmodifiableMap(getAllFieldsMutable()); + } + + /** Internal helper which returns a mutable map. */ + private Map getAllFieldsMutable() { + final TreeMap result = + new TreeMap(); + final Descriptor descriptor = internalGetFieldAccessorTable().descriptor; + for (final FieldDescriptor field : descriptor.getFields()) { + if (field.isRepeated()) { + final List value = (List) getField(field); + if (!value.isEmpty()) { + result.put(field, value); + } + } else { + if (hasField(field)) { + result.put(field, getField(field)); + } + } + } + return result; + } + + public Message.Builder newBuilderForField( + final FieldDescriptor field) { + return internalGetFieldAccessorTable().getField(field).newBuilder(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Message.Builder getFieldBuilder(final FieldDescriptor field) { + return internalGetFieldAccessorTable().getField(field).getBuilder(this); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public boolean hasField(final FieldDescriptor field) { + return internalGetFieldAccessorTable().getField(field).has(this); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Object getField(final FieldDescriptor field) { + Object object = internalGetFieldAccessorTable().getField(field).get(this); + if (field.isRepeated()) { + // The underlying list object is still modifiable at this point. + // Make sure not to expose the modifiable list to the caller. + return Collections.unmodifiableList((List) object); + } else { + return object; + } + } + + public BuilderType setField(final FieldDescriptor field, + final Object value) { + internalGetFieldAccessorTable().getField(field).set(this, value); + return (BuilderType) this; + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public BuilderType clearField(final FieldDescriptor field) { + internalGetFieldAccessorTable().getField(field).clear(this); + return (BuilderType) this; + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public int getRepeatedFieldCount(final FieldDescriptor field) { + return internalGetFieldAccessorTable().getField(field) + .getRepeatedCount(this); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Object getRepeatedField(final FieldDescriptor field, + final int index) { + return internalGetFieldAccessorTable().getField(field) + .getRepeated(this, index); + } + + public BuilderType setRepeatedField(final FieldDescriptor field, + final int index, final Object value) { + internalGetFieldAccessorTable().getField(field) + .setRepeated(this, index, value); + return (BuilderType) this; + } + + public BuilderType addRepeatedField(final FieldDescriptor field, + final Object value) { + internalGetFieldAccessorTable().getField(field).addRepeated(this, value); + return (BuilderType) this; + } + + public final BuilderType setUnknownFields( + final UnknownFieldSet unknownFields) { + this.unknownFields = unknownFields; + onChanged(); + return (BuilderType) this; + } + + @Override + public final BuilderType mergeUnknownFields( + final UnknownFieldSet unknownFields) { + this.unknownFields = + UnknownFieldSet.newBuilder(this.unknownFields) + .mergeFrom(unknownFields) + .build(); + onChanged(); + return (BuilderType) this; + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public boolean isInitialized() { + for (final FieldDescriptor field : getDescriptorForType().getFields()) { + // Check that all required fields are present. + if (field.isRequired()) { + if (!hasField(field)) { + return false; + } + } + // Check that embedded messages are initialized. + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (field.isRepeated()) { + @SuppressWarnings("unchecked") final + List messageList = (List) getField(field); + for (final Message element : messageList) { + if (!element.isInitialized()) { + return false; + } + } + } else { + if (hasField(field) && + !((Message) getField(field)).isInitialized()) { + return false; + } + } + } + } + return true; + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final UnknownFieldSet getUnknownFields() { + return unknownFields; + } + + /** + * Called by subclasses to parse an unknown field. + * @return {@code true} unless the tag is an end-group tag. + */ + protected boolean parseUnknownField( + final CodedInputStream input, + final UnknownFieldSet.Builder unknownFields, + final ExtensionRegistryLite extensionRegistry, + final int tag) throws IOException { + return unknownFields.mergeFieldFrom(tag, input); + } + + /** + * Implementation of {@link BuilderParent} for giving to our children. This + * small inner class makes it so we don't publicly expose the BuilderParent + * methods. + */ + private class BuilderParentImpl implements BuilderParent { + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void markDirty() { + onChanged(); + } + } + + /** + * Gets the {@link BuilderParent} for giving to our children. + * @return The builder parent for our children. + */ + protected BuilderParent getParentForChildren() { + if (meAsParent == null) { + meAsParent = new BuilderParentImpl(); + } + return meAsParent; + } + + /** + * Called when a the builder or one of its nested children has changed + * and any parent should be notified of its invalidation. + */ + protected final void onChanged() { + if (isClean && builderParent != null) { + builderParent.markDirty(); + + // Don't keep dispatching invalidations until build is called again. + isClean = false; + } + } + } + + // ================================================================= + // Extensions-related stuff + + public interface ExtendableMessageOrBuilder< + MessageType extends ExtendableMessage> extends MessageOrBuilder { + + /** Check if a singular extension is present. */ + boolean hasExtension( + GeneratedExtension extension); + + /** Get the number of elements in a repeated extension. */ + int getExtensionCount( + GeneratedExtension> extension); + + /** Get the value of an extension. */ + Type getExtension(GeneratedExtension extension); + + /** Get one element of a repeated extension. */ + Type getExtension( + GeneratedExtension> extension, + int index); + } + + /** + * Generated message classes for message types that contain extension ranges + * subclass this. + * + *

This class implements type-safe accessors for extensions. They + * implement all the same operations that you can do with normal fields -- + * e.g. "has", "get", and "getCount" -- but for extensions. The extensions + * are identified using instances of the class {@link GeneratedExtension}; + * the protocol compiler generates a static instance of this class for every + * extension in its input. Through the magic of generics, all is made + * type-safe. + * + *

For example, imagine you have the {@code .proto} file: + * + *

+   * option java_class = "MyProto";
+   *
+   * message Foo {
+   *   extensions 1000 to max;
+   * }
+   *
+   * extend Foo {
+   *   optional int32 bar;
+   * }
+   * 
+ * + *

Then you might write code like: + * + *

+   * MyProto.Foo foo = getFoo();
+   * int i = foo.getExtension(MyProto.bar);
+   * 
+ * + *

See also {@link ExtendableBuilder}. + */ + public abstract static class ExtendableMessage< + MessageType extends ExtendableMessage> + extends GeneratedMessage + implements ExtendableMessageOrBuilder { + + private final FieldSet extensions; + + protected ExtendableMessage() { + this.extensions = FieldSet.newFieldSet(); + } + + protected ExtendableMessage( + ExtendableBuilder builder) { + super(builder); + this.extensions = builder.buildExtensions(); + } + + private void verifyExtensionContainingType( + final GeneratedExtension extension) { + if (extension.getDescriptor().getContainingType() != + getDescriptorForType()) { + // This can only happen if someone uses unchecked operations. + throw new IllegalArgumentException( + "Extension is for type \"" + + extension.getDescriptor().getContainingType().getFullName() + + "\" which does not match message type \"" + + getDescriptorForType().getFullName() + "\"."); + } + } + + /** Check if a singular extension is present. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final boolean hasExtension( + final GeneratedExtension extension) { + verifyExtensionContainingType(extension); + return extensions.hasField(extension.getDescriptor()); + } + + /** Get the number of elements in a repeated extension. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final int getExtensionCount( + final GeneratedExtension> extension) { + verifyExtensionContainingType(extension); + final FieldDescriptor descriptor = extension.getDescriptor(); + return extensions.getRepeatedFieldCount(descriptor); + } + + /** Get the value of an extension. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + @SuppressWarnings("unchecked") + public final Type getExtension( + final GeneratedExtension extension) { + verifyExtensionContainingType(extension); + FieldDescriptor descriptor = extension.getDescriptor(); + final Object value = extensions.getField(descriptor); + if (value == null) { + if (descriptor.isRepeated()) { + return (Type) Collections.emptyList(); + } else if (descriptor.getJavaType() == + FieldDescriptor.JavaType.MESSAGE) { + return (Type) extension.getMessageDefaultInstance(); + } else { + return (Type) extension.fromReflectionType( + descriptor.getDefaultValue()); + } + } else { + return (Type) extension.fromReflectionType(value); + } + } + + /** Get one element of a repeated extension. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + @SuppressWarnings("unchecked") + public final Type getExtension( + final GeneratedExtension> extension, + final int index) { + verifyExtensionContainingType(extension); + FieldDescriptor descriptor = extension.getDescriptor(); + return (Type) extension.singularFromReflectionType( + extensions.getRepeatedField(descriptor, index)); + } + + /** Called by subclasses to check if all extensions are initialized. */ + protected boolean extensionsAreInitialized() { + return extensions.isInitialized(); + } + + @Override + public boolean isInitialized() { + return super.isInitialized() && extensionsAreInitialized(); + } + + @Override + protected boolean parseUnknownField( + CodedInputStream input, + UnknownFieldSet.Builder unknownFields, + ExtensionRegistryLite extensionRegistry, + int tag) throws IOException { + return AbstractMessage.Builder.mergeFieldFrom( + input, unknownFields, extensionRegistry, getDescriptorForType(), + null, extensions, tag); + } + + /** + * Used by parsing constructors in generated classes. + */ + @Override + protected void makeExtensionsImmutable() { + extensions.makeImmutable(); + } + + /** + * Used by subclasses to serialize extensions. Extension ranges may be + * interleaved with field numbers, but we must write them in canonical + * (sorted by field number) order. ExtensionWriter helps us write + * individual ranges of extensions at once. + */ + protected class ExtensionWriter { + // Imagine how much simpler this code would be if Java iterators had + // a way to get the next element without advancing the iterator. + + private final Iterator> iter = + extensions.iterator(); + private Map.Entry next; + private final boolean messageSetWireFormat; + + private ExtensionWriter(final boolean messageSetWireFormat) { + if (iter.hasNext()) { + next = iter.next(); + } + this.messageSetWireFormat = messageSetWireFormat; + } + + public void writeUntil(final int end, final CodedOutputStream output) + throws IOException { + while (next != null && next.getKey().getNumber() < end) { + FieldDescriptor descriptor = next.getKey(); + if (messageSetWireFormat && descriptor.getLiteJavaType() == + WireFormat.JavaType.MESSAGE && + !descriptor.isRepeated()) { + if (next instanceof LazyField.LazyEntry) { + output.writeRawMessageSetExtension(descriptor.getNumber(), + ((LazyField.LazyEntry) next).getField().toByteString()); + } else { + output.writeMessageSetExtension(descriptor.getNumber(), + (Message) next.getValue()); + } + } else { + // TODO(xiangl): Taken care of following code, it may cause + // problem when we use LazyField for normal fields/extensions. + // Due to the optional field can be duplicated at the end of + // serialized bytes, which will make the serialized size change + // after lazy field parsed. So when we use LazyField globally, + // we need to change the following write method to write cached + // bytes directly rather than write the parsed message. + FieldSet.writeField(descriptor, next.getValue(), output); + } + if (iter.hasNext()) { + next = iter.next(); + } else { + next = null; + } + } + } + } + + protected ExtensionWriter newExtensionWriter() { + return new ExtensionWriter(false); + } + protected ExtensionWriter newMessageSetExtensionWriter() { + return new ExtensionWriter(true); + } + + /** Called by subclasses to compute the size of extensions. */ + protected int extensionsSerializedSize() { + return extensions.getSerializedSize(); + } + protected int extensionsSerializedSizeAsMessageSet() { + return extensions.getMessageSetSerializedSize(); + } + + // --------------------------------------------------------------- + // Reflection + + protected Map getExtensionFields() { + return extensions.getAllFields(); + } + + @Override + public Map getAllFields() { + final Map result = super.getAllFieldsMutable(); + result.putAll(getExtensionFields()); + return Collections.unmodifiableMap(result); + } + + @Override + public boolean hasField(final FieldDescriptor field) { + if (field.isExtension()) { + verifyContainingType(field); + return extensions.hasField(field); + } else { + return super.hasField(field); + } + } + + @Override + public Object getField(final FieldDescriptor field) { + if (field.isExtension()) { + verifyContainingType(field); + final Object value = extensions.getField(field); + if (value == null) { + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + // Lacking an ExtensionRegistry, we have no way to determine the + // extension's real type, so we return a DynamicMessage. + return DynamicMessage.getDefaultInstance(field.getMessageType()); + } else { + return field.getDefaultValue(); + } + } else { + return value; + } + } else { + return super.getField(field); + } + } + + @Override + public int getRepeatedFieldCount(final FieldDescriptor field) { + if (field.isExtension()) { + verifyContainingType(field); + return extensions.getRepeatedFieldCount(field); + } else { + return super.getRepeatedFieldCount(field); + } + } + + @Override + public Object getRepeatedField(final FieldDescriptor field, + final int index) { + if (field.isExtension()) { + verifyContainingType(field); + return extensions.getRepeatedField(field, index); + } else { + return super.getRepeatedField(field, index); + } + } + + private void verifyContainingType(final FieldDescriptor field) { + if (field.getContainingType() != getDescriptorForType()) { + throw new IllegalArgumentException( + "FieldDescriptor does not match message type."); + } + } + } + + /** + * Generated message builders for message types that contain extension ranges + * subclass this. + * + *

This class implements type-safe accessors for extensions. They + * implement all the same operations that you can do with normal fields -- + * e.g. "get", "set", and "add" -- but for extensions. The extensions are + * identified using instances of the class {@link GeneratedExtension}; the + * protocol compiler generates a static instance of this class for every + * extension in its input. Through the magic of generics, all is made + * type-safe. + * + *

For example, imagine you have the {@code .proto} file: + * + *

+   * option java_class = "MyProto";
+   *
+   * message Foo {
+   *   extensions 1000 to max;
+   * }
+   *
+   * extend Foo {
+   *   optional int32 bar;
+   * }
+   * 
+ * + *

Then you might write code like: + * + *

+   * MyProto.Foo foo =
+   *   MyProto.Foo.newBuilder()
+   *     .setExtension(MyProto.bar, 123)
+   *     .build();
+   * 
+ * + *

See also {@link ExtendableMessage}. + */ + @SuppressWarnings("unchecked") + public abstract static class ExtendableBuilder< + MessageType extends ExtendableMessage, + BuilderType extends ExtendableBuilder> + extends Builder + implements ExtendableMessageOrBuilder { + + private FieldSet extensions = FieldSet.emptySet(); + + protected ExtendableBuilder() {} + + protected ExtendableBuilder( + BuilderParent parent) { + super(parent); + } + + @Override + public BuilderType clear() { + extensions = FieldSet.emptySet(); + return super.clear(); + } + + // This is implemented here only to work around an apparent bug in the + // Java compiler and/or build system. See bug #1898463. The mere presence + // of this dummy clone() implementation makes it go away. + @Override + public BuilderType clone() { + throw new UnsupportedOperationException( + "This is supposed to be overridden by subclasses."); + } + + private void ensureExtensionsIsMutable() { + if (extensions.isImmutable()) { + extensions = extensions.clone(); + } + } + + private void verifyExtensionContainingType( + final GeneratedExtension extension) { + if (extension.getDescriptor().getContainingType() != + getDescriptorForType()) { + // This can only happen if someone uses unchecked operations. + throw new IllegalArgumentException( + "Extension is for type \"" + + extension.getDescriptor().getContainingType().getFullName() + + "\" which does not match message type \"" + + getDescriptorForType().getFullName() + "\"."); + } + } + + /** Check if a singular extension is present. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final boolean hasExtension( + final GeneratedExtension extension) { + verifyExtensionContainingType(extension); + return extensions.hasField(extension.getDescriptor()); + } + + /** Get the number of elements in a repeated extension. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final int getExtensionCount( + final GeneratedExtension> extension) { + verifyExtensionContainingType(extension); + final FieldDescriptor descriptor = extension.getDescriptor(); + return extensions.getRepeatedFieldCount(descriptor); + } + + /** Get the value of an extension. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final Type getExtension( + final GeneratedExtension extension) { + verifyExtensionContainingType(extension); + FieldDescriptor descriptor = extension.getDescriptor(); + final Object value = extensions.getField(descriptor); + if (value == null) { + if (descriptor.isRepeated()) { + return (Type) Collections.emptyList(); + } else if (descriptor.getJavaType() == + FieldDescriptor.JavaType.MESSAGE) { + return (Type) extension.getMessageDefaultInstance(); + } else { + return (Type) extension.fromReflectionType( + descriptor.getDefaultValue()); + } + } else { + return (Type) extension.fromReflectionType(value); + } + } + + /** Get one element of a repeated extension. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final Type getExtension( + final GeneratedExtension> extension, + final int index) { + verifyExtensionContainingType(extension); + FieldDescriptor descriptor = extension.getDescriptor(); + return (Type) extension.singularFromReflectionType( + extensions.getRepeatedField(descriptor, index)); + } + + /** Set the value of an extension. */ + public final BuilderType setExtension( + final GeneratedExtension extension, + final Type value) { + verifyExtensionContainingType(extension); + ensureExtensionsIsMutable(); + final FieldDescriptor descriptor = extension.getDescriptor(); + extensions.setField(descriptor, extension.toReflectionType(value)); + onChanged(); + return (BuilderType) this; + } + + /** Set the value of one element of a repeated extension. */ + public final BuilderType setExtension( + final GeneratedExtension> extension, + final int index, final Type value) { + verifyExtensionContainingType(extension); + ensureExtensionsIsMutable(); + final FieldDescriptor descriptor = extension.getDescriptor(); + extensions.setRepeatedField( + descriptor, index, + extension.singularToReflectionType(value)); + onChanged(); + return (BuilderType) this; + } + + /** Append a value to a repeated extension. */ + public final BuilderType addExtension( + final GeneratedExtension> extension, + final Type value) { + verifyExtensionContainingType(extension); + ensureExtensionsIsMutable(); + final FieldDescriptor descriptor = extension.getDescriptor(); + extensions.addRepeatedField( + descriptor, extension.singularToReflectionType(value)); + onChanged(); + return (BuilderType) this; + } + + /** Clear an extension. */ + public final BuilderType clearExtension( + final GeneratedExtension extension) { + verifyExtensionContainingType(extension); + ensureExtensionsIsMutable(); + extensions.clearField(extension.getDescriptor()); + onChanged(); + return (BuilderType) this; + } + + /** Called by subclasses to check if all extensions are initialized. */ + protected boolean extensionsAreInitialized() { + return extensions.isInitialized(); + } + + /** + * Called by the build code path to create a copy of the extensions for + * building the message. + */ + private FieldSet buildExtensions() { + extensions.makeImmutable(); + return extensions; + } + + @Override + public boolean isInitialized() { + return super.isInitialized() && extensionsAreInitialized(); + } + + /** + * Called by subclasses to parse an unknown field or an extension. + * @return {@code true} unless the tag is an end-group tag. + */ + @Override + protected boolean parseUnknownField( + final CodedInputStream input, + final UnknownFieldSet.Builder unknownFields, + final ExtensionRegistryLite extensionRegistry, + final int tag) throws IOException { + return AbstractMessage.Builder.mergeFieldFrom( + input, unknownFields, extensionRegistry, getDescriptorForType(), + this, null, tag); + } + + // --------------------------------------------------------------- + // Reflection + + @Override + public Map getAllFields() { + final Map result = super.getAllFieldsMutable(); + result.putAll(extensions.getAllFields()); + return Collections.unmodifiableMap(result); + } + + @Override + public Object getField(final FieldDescriptor field) { + if (field.isExtension()) { + verifyContainingType(field); + final Object value = extensions.getField(field); + if (value == null) { + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + // Lacking an ExtensionRegistry, we have no way to determine the + // extension's real type, so we return a DynamicMessage. + return DynamicMessage.getDefaultInstance(field.getMessageType()); + } else { + return field.getDefaultValue(); + } + } else { + return value; + } + } else { + return super.getField(field); + } + } + + @Override + public int getRepeatedFieldCount(final FieldDescriptor field) { + if (field.isExtension()) { + verifyContainingType(field); + return extensions.getRepeatedFieldCount(field); + } else { + return super.getRepeatedFieldCount(field); + } + } + + @Override + public Object getRepeatedField(final FieldDescriptor field, + final int index) { + if (field.isExtension()) { + verifyContainingType(field); + return extensions.getRepeatedField(field, index); + } else { + return super.getRepeatedField(field, index); + } + } + + @Override + public boolean hasField(final FieldDescriptor field) { + if (field.isExtension()) { + verifyContainingType(field); + return extensions.hasField(field); + } else { + return super.hasField(field); + } + } + + @Override + public BuilderType setField(final FieldDescriptor field, + final Object value) { + if (field.isExtension()) { + verifyContainingType(field); + ensureExtensionsIsMutable(); + extensions.setField(field, value); + onChanged(); + return (BuilderType) this; + } else { + return super.setField(field, value); + } + } + + @Override + public BuilderType clearField(final FieldDescriptor field) { + if (field.isExtension()) { + verifyContainingType(field); + ensureExtensionsIsMutable(); + extensions.clearField(field); + onChanged(); + return (BuilderType) this; + } else { + return super.clearField(field); + } + } + + @Override + public BuilderType setRepeatedField(final FieldDescriptor field, + final int index, final Object value) { + if (field.isExtension()) { + verifyContainingType(field); + ensureExtensionsIsMutable(); + extensions.setRepeatedField(field, index, value); + onChanged(); + return (BuilderType) this; + } else { + return super.setRepeatedField(field, index, value); + } + } + + @Override + public BuilderType addRepeatedField(final FieldDescriptor field, + final Object value) { + if (field.isExtension()) { + verifyContainingType(field); + ensureExtensionsIsMutable(); + extensions.addRepeatedField(field, value); + onChanged(); + return (BuilderType) this; + } else { + return super.addRepeatedField(field, value); + } + } + + protected final void mergeExtensionFields(final ExtendableMessage other) { + ensureExtensionsIsMutable(); + extensions.mergeFrom(other.extensions); + onChanged(); + } + + private void verifyContainingType(final FieldDescriptor field) { + if (field.getContainingType() != getDescriptorForType()) { + throw new IllegalArgumentException( + "FieldDescriptor does not match message type."); + } + } + } + + // ----------------------------------------------------------------- + + /** + * Gets the descriptor for an extension. The implementation depends on whether + * the extension is scoped in the top level of a file or scoped in a Message. + */ + private static interface ExtensionDescriptorRetriever { + FieldDescriptor getDescriptor(); + } + + /** For use by generated code only. */ + public static + GeneratedExtension + newMessageScopedGeneratedExtension(final Message scope, + final int descriptorIndex, + final Class singularType, + final Message defaultInstance) { + // For extensions scoped within a Message, we use the Message to resolve + // the outer class's descriptor, from which the extension descriptor is + // obtained. + return new GeneratedExtension( + new ExtensionDescriptorRetriever() { + //@Override (Java 1.6 override semantics, but we must support 1.5) + public FieldDescriptor getDescriptor() { + return scope.getDescriptorForType().getExtensions() + .get(descriptorIndex); + } + }, + singularType, + defaultInstance); + } + + /** For use by generated code only. */ + public static + GeneratedExtension + newFileScopedGeneratedExtension(final Class singularType, + final Message defaultInstance) { + // For extensions scoped within a file, we rely on the outer class's + // static initializer to call internalInit() on the extension when the + // descriptor is available. + return new GeneratedExtension( + null, // ExtensionDescriptorRetriever is initialized in internalInit(); + singularType, + defaultInstance); + } + + /** + * Type used to represent generated extensions. The protocol compiler + * generates a static singleton instance of this class for each extension. + * + *

For example, imagine you have the {@code .proto} file: + * + *

+   * option java_class = "MyProto";
+   *
+   * message Foo {
+   *   extensions 1000 to max;
+   * }
+   *
+   * extend Foo {
+   *   optional int32 bar;
+   * }
+   * 
+ * + *

Then, {@code MyProto.Foo.bar} has type + * {@code GeneratedExtension}. + * + *

In general, users should ignore the details of this type, and simply use + * these static singletons as parameters to the extension accessors defined + * in {@link ExtendableMessage} and {@link ExtendableBuilder}. + */ + public static final class GeneratedExtension< + ContainingType extends Message, Type> { + // TODO(kenton): Find ways to avoid using Java reflection within this + // class. Also try to avoid suppressing unchecked warnings. + + // We can't always initialize the descriptor of a GeneratedExtension when + // we first construct it due to initialization order difficulties (namely, + // the descriptor may not have been constructed yet, since it is often + // constructed by the initializer of a separate module). + // + // In the case of nested extensions, we initialize the + // ExtensionDescriptorRetriever with an instance that uses the scoping + // Message's default instance to retrieve the extension's descriptor. + // + // In the case of non-nested extensions, we initialize the + // ExtensionDescriptorRetriever to null and rely on the outer class's static + // initializer to call internalInit() after the descriptor has been parsed. + private GeneratedExtension(ExtensionDescriptorRetriever descriptorRetriever, + Class singularType, + Message messageDefaultInstance) { + if (Message.class.isAssignableFrom(singularType) && + !singularType.isInstance(messageDefaultInstance)) { + throw new IllegalArgumentException( + "Bad messageDefaultInstance for " + singularType.getName()); + } + this.descriptorRetriever = descriptorRetriever; + this.singularType = singularType; + this.messageDefaultInstance = messageDefaultInstance; + + if (ProtocolMessageEnum.class.isAssignableFrom(singularType)) { + this.enumValueOf = getMethodOrDie(singularType, "valueOf", + EnumValueDescriptor.class); + this.enumGetValueDescriptor = + getMethodOrDie(singularType, "getValueDescriptor"); + } else { + this.enumValueOf = null; + this.enumGetValueDescriptor = null; + } + } + + /** For use by generated code only. */ + public void internalInit(final FieldDescriptor descriptor) { + if (descriptorRetriever != null) { + throw new IllegalStateException("Already initialized."); + } + descriptorRetriever = new ExtensionDescriptorRetriever() { + //@Override (Java 1.6 override semantics, but we must support 1.5) + public FieldDescriptor getDescriptor() { + return descriptor; + } + }; + } + + private ExtensionDescriptorRetriever descriptorRetriever; + private final Class singularType; + private final Message messageDefaultInstance; + private final Method enumValueOf; + private final Method enumGetValueDescriptor; + + public FieldDescriptor getDescriptor() { + if (descriptorRetriever == null) { + throw new IllegalStateException( + "getDescriptor() called before internalInit()"); + } + return descriptorRetriever.getDescriptor(); + } + + /** + * If the extension is an embedded message or group, returns the default + * instance of the message. + */ + public Message getMessageDefaultInstance() { + return messageDefaultInstance; + } + + /** + * Convert from the type used by the reflection accessors to the type used + * by native accessors. E.g., for enums, the reflection accessors use + * EnumValueDescriptors but the native accessors use the generated enum + * type. + */ + @SuppressWarnings("unchecked") + private Object fromReflectionType(final Object value) { + FieldDescriptor descriptor = getDescriptor(); + if (descriptor.isRepeated()) { + if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE || + descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) { + // Must convert the whole list. + final List result = new ArrayList(); + for (final Object element : (List) value) { + result.add(singularFromReflectionType(element)); + } + return result; + } else { + return value; + } + } else { + return singularFromReflectionType(value); + } + } + + /** + * Like {@link #fromReflectionType(Object)}, but if the type is a repeated + * type, this converts a single element. + */ + private Object singularFromReflectionType(final Object value) { + FieldDescriptor descriptor = getDescriptor(); + switch (descriptor.getJavaType()) { + case MESSAGE: + if (singularType.isInstance(value)) { + return value; + } else { + // It seems the copy of the embedded message stored inside the + // extended message is not of the exact type the user was + // expecting. This can happen if a user defines a + // GeneratedExtension manually and gives it a different type. + // This should not happen in normal use. But, to be nice, we'll + // copy the message to whatever type the caller was expecting. + return messageDefaultInstance.newBuilderForType() + .mergeFrom((Message) value).build(); + } + case ENUM: + return invokeOrDie(enumValueOf, null, (EnumValueDescriptor) value); + default: + return value; + } + } + + /** + * Convert from the type used by the native accessors to the type used + * by reflection accessors. E.g., for enums, the reflection accessors use + * EnumValueDescriptors but the native accessors use the generated enum + * type. + */ + @SuppressWarnings("unchecked") + private Object toReflectionType(final Object value) { + FieldDescriptor descriptor = getDescriptor(); + if (descriptor.isRepeated()) { + if (descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) { + // Must convert the whole list. + final List result = new ArrayList(); + for (final Object element : (List) value) { + result.add(singularToReflectionType(element)); + } + return result; + } else { + return value; + } + } else { + return singularToReflectionType(value); + } + } + + /** + * Like {@link #toReflectionType(Object)}, but if the type is a repeated + * type, this converts a single element. + */ + private Object singularToReflectionType(final Object value) { + FieldDescriptor descriptor = getDescriptor(); + switch (descriptor.getJavaType()) { + case ENUM: + return invokeOrDie(enumGetValueDescriptor, value); + default: + return value; + } + } + } + + // ================================================================= + + /** Calls Class.getMethod and throws a RuntimeException if it fails. */ + @SuppressWarnings("unchecked") + private static Method getMethodOrDie( + final Class clazz, final String name, final Class... params) { + try { + return clazz.getMethod(name, params); + } catch (NoSuchMethodException e) { + throw new RuntimeException( + "Generated message class \"" + clazz.getName() + + "\" missing method \"" + name + "\".", e); + } + } + + /** Calls invoke and throws a RuntimeException if it fails. */ + private static Object invokeOrDie( + final Method method, final Object object, final Object... params) { + try { + return method.invoke(object, params); + } catch (IllegalAccessException e) { + throw new RuntimeException( + "Couldn't use Java reflection to implement protocol message " + + "reflection.", e); + } catch (InvocationTargetException e) { + final Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else if (cause instanceof Error) { + throw (Error) cause; + } else { + throw new RuntimeException( + "Unexpected exception thrown by generated accessor method.", cause); + } + } + } + + /** + * Users should ignore this class. This class provides the implementation + * with access to the fields of a message object using Java reflection. + */ + public static final class FieldAccessorTable { + + /** + * Construct a FieldAccessorTable for a particular message class. Only + * one FieldAccessorTable should ever be constructed per class. + * + * @param descriptor The type's descriptor. + * @param camelCaseNames The camelcase names of all fields in the message. + * These are used to derive the accessor method names. + * @param messageClass The message type. + * @param builderClass The builder type. + */ + public FieldAccessorTable( + final Descriptor descriptor, + final String[] camelCaseNames, + final Class messageClass, + final Class builderClass) { + this(descriptor, camelCaseNames); + ensureFieldAccessorsInitialized(messageClass, builderClass); + } + + /** + * Construct a FieldAccessorTable for a particular message class without + * initializing FieldAccessors. + */ + public FieldAccessorTable( + final Descriptor descriptor, + final String[] camelCaseNames) { + this.descriptor = descriptor; + this.camelCaseNames = camelCaseNames; + fields = new FieldAccessor[descriptor.getFields().size()]; + initialized = false; + } + + /** + * Ensures the field accessors are initialized. This method is thread-safe. + * + * @param messageClass The message type. + * @param builderClass The builder type. + * @return this + */ + public FieldAccessorTable ensureFieldAccessorsInitialized( + Class messageClass, + Class builderClass) { + if (initialized) { return this; } + synchronized (this) { + if (initialized) { return this; } + for (int i = 0; i < fields.length; i++) { + FieldDescriptor field = descriptor.getFields().get(i); + if (field.isRepeated()) { + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + fields[i] = new RepeatedMessageFieldAccessor( + field, camelCaseNames[i], messageClass, builderClass); + } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) { + fields[i] = new RepeatedEnumFieldAccessor( + field, camelCaseNames[i], messageClass, builderClass); + } else { + fields[i] = new RepeatedFieldAccessor( + field, camelCaseNames[i], messageClass, builderClass); + } + } else { + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + fields[i] = new SingularMessageFieldAccessor( + field, camelCaseNames[i], messageClass, builderClass); + } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) { + fields[i] = new SingularEnumFieldAccessor( + field, camelCaseNames[i], messageClass, builderClass); + } else { + fields[i] = new SingularFieldAccessor( + field, camelCaseNames[i], messageClass, builderClass); + } + } + } + initialized = true; + camelCaseNames = null; + return this; + } + } + + private final Descriptor descriptor; + private final FieldAccessor[] fields; + private String[] camelCaseNames; + private volatile boolean initialized; + + /** Get the FieldAccessor for a particular field. */ + private FieldAccessor getField(final FieldDescriptor field) { + if (field.getContainingType() != descriptor) { + throw new IllegalArgumentException( + "FieldDescriptor does not match message type."); + } else if (field.isExtension()) { + // If this type had extensions, it would subclass ExtendableMessage, + // which overrides the reflection interface to handle extensions. + throw new IllegalArgumentException( + "This type does not have extensions."); + } + return fields[field.getIndex()]; + } + + /** + * Abstract interface that provides access to a single field. This is + * implemented differently depending on the field type and cardinality. + */ + private interface FieldAccessor { + Object get(GeneratedMessage message); + Object get(GeneratedMessage.Builder builder); + void set(Builder builder, Object value); + Object getRepeated(GeneratedMessage message, int index); + Object getRepeated(GeneratedMessage.Builder builder, int index); + void setRepeated(Builder builder, + int index, Object value); + void addRepeated(Builder builder, Object value); + boolean has(GeneratedMessage message); + boolean has(GeneratedMessage.Builder builder); + int getRepeatedCount(GeneratedMessage message); + int getRepeatedCount(GeneratedMessage.Builder builder); + void clear(Builder builder); + Message.Builder newBuilder(); + Message.Builder getBuilder(GeneratedMessage.Builder builder); + } + + // --------------------------------------------------------------- + + private static class SingularFieldAccessor implements FieldAccessor { + SingularFieldAccessor( + final FieldDescriptor descriptor, final String camelCaseName, + final Class messageClass, + final Class builderClass) { + getMethod = getMethodOrDie(messageClass, "get" + camelCaseName); + getMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName); + type = getMethod.getReturnType(); + setMethod = getMethodOrDie(builderClass, "set" + camelCaseName, type); + hasMethod = + getMethodOrDie(messageClass, "has" + camelCaseName); + hasMethodBuilder = + getMethodOrDie(builderClass, "has" + camelCaseName); + clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); + } + + // Note: We use Java reflection to call public methods rather than + // access private fields directly as this avoids runtime security + // checks. + protected final Class type; + protected final Method getMethod; + protected final Method getMethodBuilder; + protected final Method setMethod; + protected final Method hasMethod; + protected final Method hasMethodBuilder; + protected final Method clearMethod; + + public Object get(final GeneratedMessage message) { + return invokeOrDie(getMethod, message); + } + public Object get(GeneratedMessage.Builder builder) { + return invokeOrDie(getMethodBuilder, builder); + } + public void set(final Builder builder, final Object value) { + invokeOrDie(setMethod, builder, value); + } + public Object getRepeated(final GeneratedMessage message, + final int index) { + throw new UnsupportedOperationException( + "getRepeatedField() called on a singular field."); + } + public Object getRepeated(GeneratedMessage.Builder builder, int index) { + throw new UnsupportedOperationException( + "getRepeatedField() called on a singular field."); + } + public void setRepeated(final Builder builder, + final int index, final Object value) { + throw new UnsupportedOperationException( + "setRepeatedField() called on a singular field."); + } + public void addRepeated(final Builder builder, final Object value) { + throw new UnsupportedOperationException( + "addRepeatedField() called on a singular field."); + } + public boolean has(final GeneratedMessage message) { + return (Boolean) invokeOrDie(hasMethod, message); + } + public boolean has(GeneratedMessage.Builder builder) { + return (Boolean) invokeOrDie(hasMethodBuilder, builder); + } + public int getRepeatedCount(final GeneratedMessage message) { + throw new UnsupportedOperationException( + "getRepeatedFieldSize() called on a singular field."); + } + public int getRepeatedCount(GeneratedMessage.Builder builder) { + throw new UnsupportedOperationException( + "getRepeatedFieldSize() called on a singular field."); + } + public void clear(final Builder builder) { + invokeOrDie(clearMethod, builder); + } + public Message.Builder newBuilder() { + throw new UnsupportedOperationException( + "newBuilderForField() called on a non-Message type."); + } + public Message.Builder getBuilder(GeneratedMessage.Builder builder) { + throw new UnsupportedOperationException( + "getFieldBuilder() called on a non-Message type."); + } + } + + private static class RepeatedFieldAccessor implements FieldAccessor { + protected final Class type; + protected final Method getMethod; + protected final Method getMethodBuilder; + protected final Method getRepeatedMethod; + protected final Method getRepeatedMethodBuilder; + protected final Method setRepeatedMethod; + protected final Method addRepeatedMethod; + protected final Method getCountMethod; + protected final Method getCountMethodBuilder; + protected final Method clearMethod; + + RepeatedFieldAccessor( + final FieldDescriptor descriptor, final String camelCaseName, + final Class messageClass, + final Class builderClass) { + getMethod = getMethodOrDie(messageClass, + "get" + camelCaseName + "List"); + getMethodBuilder = getMethodOrDie(builderClass, + "get" + camelCaseName + "List"); + getRepeatedMethod = + getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE); + getRepeatedMethodBuilder = + getMethodOrDie(builderClass, "get" + camelCaseName, Integer.TYPE); + type = getRepeatedMethod.getReturnType(); + setRepeatedMethod = + getMethodOrDie(builderClass, "set" + camelCaseName, + Integer.TYPE, type); + addRepeatedMethod = + getMethodOrDie(builderClass, "add" + camelCaseName, type); + getCountMethod = + getMethodOrDie(messageClass, "get" + camelCaseName + "Count"); + getCountMethodBuilder = + getMethodOrDie(builderClass, "get" + camelCaseName + "Count"); + + clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); + } + + public Object get(final GeneratedMessage message) { + return invokeOrDie(getMethod, message); + } + public Object get(GeneratedMessage.Builder builder) { + return invokeOrDie(getMethodBuilder, builder); + } + public void set(final Builder builder, final Object value) { + // Add all the elements individually. This serves two purposes: + // 1) Verifies that each element has the correct type. + // 2) Insures that the caller cannot modify the list later on and + // have the modifications be reflected in the message. + clear(builder); + for (final Object element : (List) value) { + addRepeated(builder, element); + } + } + public Object getRepeated(final GeneratedMessage message, + final int index) { + return invokeOrDie(getRepeatedMethod, message, index); + } + public Object getRepeated(GeneratedMessage.Builder builder, int index) { + return invokeOrDie(getRepeatedMethodBuilder, builder, index); + } + public void setRepeated(final Builder builder, + final int index, final Object value) { + invokeOrDie(setRepeatedMethod, builder, index, value); + } + public void addRepeated(final Builder builder, final Object value) { + invokeOrDie(addRepeatedMethod, builder, value); + } + public boolean has(final GeneratedMessage message) { + throw new UnsupportedOperationException( + "hasField() called on a repeated field."); + } + public boolean has(GeneratedMessage.Builder builder) { + throw new UnsupportedOperationException( + "hasField() called on a repeated field."); + } + public int getRepeatedCount(final GeneratedMessage message) { + return (Integer) invokeOrDie(getCountMethod, message); + } + public int getRepeatedCount(GeneratedMessage.Builder builder) { + return (Integer) invokeOrDie(getCountMethodBuilder, builder); + } + public void clear(final Builder builder) { + invokeOrDie(clearMethod, builder); + } + public Message.Builder newBuilder() { + throw new UnsupportedOperationException( + "newBuilderForField() called on a non-Message type."); + } + public Message.Builder getBuilder(GeneratedMessage.Builder builder) { + throw new UnsupportedOperationException( + "getFieldBuilder() called on a non-Message type."); + } + } + + // --------------------------------------------------------------- + + private static final class SingularEnumFieldAccessor + extends SingularFieldAccessor { + SingularEnumFieldAccessor( + final FieldDescriptor descriptor, final String camelCaseName, + final Class messageClass, + final Class builderClass) { + super(descriptor, camelCaseName, messageClass, builderClass); + + valueOfMethod = getMethodOrDie(type, "valueOf", + EnumValueDescriptor.class); + getValueDescriptorMethod = + getMethodOrDie(type, "getValueDescriptor"); + } + + private Method valueOfMethod; + private Method getValueDescriptorMethod; + + @Override + public Object get(final GeneratedMessage message) { + return invokeOrDie(getValueDescriptorMethod, super.get(message)); + } + + @Override + public Object get(final GeneratedMessage.Builder builder) { + return invokeOrDie(getValueDescriptorMethod, super.get(builder)); + } + + @Override + public void set(final Builder builder, final Object value) { + super.set(builder, invokeOrDie(valueOfMethod, null, value)); + } + } + + private static final class RepeatedEnumFieldAccessor + extends RepeatedFieldAccessor { + RepeatedEnumFieldAccessor( + final FieldDescriptor descriptor, final String camelCaseName, + final Class messageClass, + final Class builderClass) { + super(descriptor, camelCaseName, messageClass, builderClass); + + valueOfMethod = getMethodOrDie(type, "valueOf", + EnumValueDescriptor.class); + getValueDescriptorMethod = + getMethodOrDie(type, "getValueDescriptor"); + } + + private final Method valueOfMethod; + private final Method getValueDescriptorMethod; + + @Override + @SuppressWarnings("unchecked") + public Object get(final GeneratedMessage message) { + final List newList = new ArrayList(); + for (final Object element : (List) super.get(message)) { + newList.add(invokeOrDie(getValueDescriptorMethod, element)); + } + return Collections.unmodifiableList(newList); + } + + @Override + @SuppressWarnings("unchecked") + public Object get(final GeneratedMessage.Builder builder) { + final List newList = new ArrayList(); + for (final Object element : (List) super.get(builder)) { + newList.add(invokeOrDie(getValueDescriptorMethod, element)); + } + return Collections.unmodifiableList(newList); + } + + @Override + public Object getRepeated(final GeneratedMessage message, + final int index) { + return invokeOrDie(getValueDescriptorMethod, + super.getRepeated(message, index)); + } + @Override + public Object getRepeated(final GeneratedMessage.Builder builder, + final int index) { + return invokeOrDie(getValueDescriptorMethod, + super.getRepeated(builder, index)); + } + @Override + public void setRepeated(final Builder builder, + final int index, final Object value) { + super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null, + value)); + } + @Override + public void addRepeated(final Builder builder, final Object value) { + super.addRepeated(builder, invokeOrDie(valueOfMethod, null, value)); + } + } + + // --------------------------------------------------------------- + + private static final class SingularMessageFieldAccessor + extends SingularFieldAccessor { + SingularMessageFieldAccessor( + final FieldDescriptor descriptor, final String camelCaseName, + final Class messageClass, + final Class builderClass) { + super(descriptor, camelCaseName, messageClass, builderClass); + + newBuilderMethod = getMethodOrDie(type, "newBuilder"); + getBuilderMethodBuilder = + getMethodOrDie(builderClass, "get" + camelCaseName + "Builder"); + } + + private final Method newBuilderMethod; + private final Method getBuilderMethodBuilder; + + private Object coerceType(final Object value) { + if (type.isInstance(value)) { + return value; + } else { + // 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 + // a copy of the message. + return ((Message.Builder) invokeOrDie(newBuilderMethod, null)) + .mergeFrom((Message) value).buildPartial(); + } + } + + @Override + public void set(final Builder builder, final Object value) { + super.set(builder, coerceType(value)); + } + @Override + public Message.Builder newBuilder() { + return (Message.Builder) invokeOrDie(newBuilderMethod, null); + } + @Override + public Message.Builder getBuilder(GeneratedMessage.Builder builder) { + return (Message.Builder) invokeOrDie(getBuilderMethodBuilder, builder); + } + } + + private static final class RepeatedMessageFieldAccessor + extends RepeatedFieldAccessor { + RepeatedMessageFieldAccessor( + final FieldDescriptor descriptor, final String camelCaseName, + final Class messageClass, + final Class builderClass) { + super(descriptor, camelCaseName, messageClass, builderClass); + + newBuilderMethod = getMethodOrDie(type, "newBuilder"); + } + + private final Method newBuilderMethod; + + private Object coerceType(final Object value) { + if (type.isInstance(value)) { + return value; + } else { + // 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 + // a copy of the message. + return ((Message.Builder) invokeOrDie(newBuilderMethod, null)) + .mergeFrom((Message) value).build(); + } + } + + @Override + public void setRepeated(final Builder builder, + final int index, final Object value) { + super.setRepeated(builder, index, coerceType(value)); + } + @Override + public void addRepeated(final Builder builder, final Object value) { + super.addRepeated(builder, coerceType(value)); + } + @Override + public Message.Builder newBuilder() { + return (Message.Builder) invokeOrDie(newBuilderMethod, null); + } + } + } + + /** + * Replaces this object in the output stream with a serialized form. + * Part of Java's serialization magic. Generated sub-classes must override + * this method by calling {@code return super.writeReplace();} + * @return a SerializedForm of this message + */ + protected Object writeReplace() throws ObjectStreamException { + return new GeneratedMessageLite.SerializedForm(this); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java new file mode 100644 index 0000000..437e341 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -0,0 +1,797 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.IOException; +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * Lite version of {@link GeneratedMessage}. + * + * @author kenton@google.com Kenton Varda + */ +public abstract class GeneratedMessageLite extends AbstractMessageLite + implements Serializable { + private static final long serialVersionUID = 1L; + + protected GeneratedMessageLite() { + } + + protected GeneratedMessageLite(Builder builder) { + } + + public Parser getParserForType() { + throw new UnsupportedOperationException( + "This is supposed to be overridden by subclasses."); + } + + /** + * Called by subclasses to parse an unknown field. + * @return {@code true} unless the tag is an end-group tag. + */ + protected boolean parseUnknownField( + CodedInputStream input, + ExtensionRegistryLite extensionRegistry, + int tag) throws IOException { + return input.skipField(tag); + } + + /** + * Used by parsing constructors in generated classes. + */ + protected void makeExtensionsImmutable() { + // Noop for messages without extensions. + } + + @SuppressWarnings("unchecked") + public abstract static class Builder + extends AbstractMessageLite.Builder { + protected Builder() {} + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public BuilderType clear() { + return (BuilderType) this; + } + + // This is implemented here only to work around an apparent bug in the + // Java compiler and/or build system. See bug #1898463. The mere presence + // of this dummy clone() implementation makes it go away. + @Override + public BuilderType clone() { + throw new UnsupportedOperationException( + "This is supposed to be overridden by subclasses."); + } + + /** All subclasses implement this. */ + public abstract BuilderType mergeFrom(MessageType message); + + // Defined here for return type covariance. + public abstract MessageType getDefaultInstanceForType(); + + /** + * Called by subclasses to parse an unknown field. + * @return {@code true} unless the tag is an end-group tag. + */ + protected boolean parseUnknownField( + CodedInputStream input, + ExtensionRegistryLite extensionRegistry, + int tag) throws IOException { + return input.skipField(tag); + } + } + + // ================================================================= + // Extensions-related stuff + + /** + * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}. + */ + public interface ExtendableMessageOrBuilder< + MessageType extends ExtendableMessage> extends MessageLiteOrBuilder { + + /** Check if a singular extension is present. */ + boolean hasExtension( + GeneratedExtension extension); + + /** Get the number of elements in a repeated extension. */ + int getExtensionCount( + GeneratedExtension> extension); + + /** Get the value of an extension. */ + Type getExtension(GeneratedExtension extension); + + /** Get one element of a repeated extension. */ + Type getExtension( + GeneratedExtension> extension, + int index); + } + + /** + * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}. + */ + public abstract static class ExtendableMessage< + MessageType extends ExtendableMessage> + extends GeneratedMessageLite + implements ExtendableMessageOrBuilder { + + private final FieldSet extensions; + + protected ExtendableMessage() { + this.extensions = FieldSet.newFieldSet(); + } + + protected ExtendableMessage(ExtendableBuilder builder) { + this.extensions = builder.buildExtensions(); + } + + private void verifyExtensionContainingType( + final GeneratedExtension extension) { + if (extension.getContainingTypeDefaultInstance() != + getDefaultInstanceForType()) { + // This can only happen if someone uses unchecked operations. + throw new IllegalArgumentException( + "This extension is for a different message type. Please make " + + "sure that you are not suppressing any generics type warnings."); + } + } + + /** Check if a singular extension is present. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final boolean hasExtension( + final GeneratedExtension extension) { + verifyExtensionContainingType(extension); + return extensions.hasField(extension.descriptor); + } + + /** Get the number of elements in a repeated extension. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final int getExtensionCount( + final GeneratedExtension> extension) { + verifyExtensionContainingType(extension); + return extensions.getRepeatedFieldCount(extension.descriptor); + } + + /** Get the value of an extension. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + @SuppressWarnings("unchecked") + public final Type getExtension( + final GeneratedExtension extension) { + verifyExtensionContainingType(extension); + final Object value = extensions.getField(extension.descriptor); + if (value == null) { + return extension.defaultValue; + } else { + return (Type) value; + } + } + + /** Get one element of a repeated extension. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + @SuppressWarnings("unchecked") + public final Type getExtension( + final GeneratedExtension> extension, + final int index) { + verifyExtensionContainingType(extension); + return (Type) extensions.getRepeatedField(extension.descriptor, index); + } + + /** Called by subclasses to check if all extensions are initialized. */ + protected boolean extensionsAreInitialized() { + return extensions.isInitialized(); + } + + /** + * Called by subclasses to parse an unknown field or an extension. + * @return {@code true} unless the tag is an end-group tag. + */ + @Override + protected boolean parseUnknownField( + CodedInputStream input, + ExtensionRegistryLite extensionRegistry, + int tag) throws IOException { + return GeneratedMessageLite.parseUnknownField( + extensions, + getDefaultInstanceForType(), + input, + extensionRegistry, + tag); + } + + /** + * Used by parsing constructors in generated classes. + */ + @Override + protected void makeExtensionsImmutable() { + extensions.makeImmutable(); + } + + /** + * Used by subclasses to serialize extensions. Extension ranges may be + * interleaved with field numbers, but we must write them in canonical + * (sorted by field number) order. ExtensionWriter helps us write + * individual ranges of extensions at once. + */ + protected class ExtensionWriter { + // Imagine how much simpler this code would be if Java iterators had + // a way to get the next element without advancing the iterator. + + private final Iterator> iter = + extensions.iterator(); + private Map.Entry next; + private final boolean messageSetWireFormat; + + private ExtensionWriter(boolean messageSetWireFormat) { + if (iter.hasNext()) { + next = iter.next(); + } + this.messageSetWireFormat = messageSetWireFormat; + } + + public void writeUntil(final int end, final CodedOutputStream output) + throws IOException { + while (next != null && next.getKey().getNumber() < end) { + ExtensionDescriptor extension = next.getKey(); + if (messageSetWireFormat && extension.getLiteJavaType() == + WireFormat.JavaType.MESSAGE && + !extension.isRepeated()) { + output.writeMessageSetExtension(extension.getNumber(), + (MessageLite) next.getValue()); + } else { + FieldSet.writeField(extension, next.getValue(), output); + } + if (iter.hasNext()) { + next = iter.next(); + } else { + next = null; + } + } + } + } + + protected ExtensionWriter newExtensionWriter() { + return new ExtensionWriter(false); + } + protected ExtensionWriter newMessageSetExtensionWriter() { + return new ExtensionWriter(true); + } + + /** Called by subclasses to compute the size of extensions. */ + protected int extensionsSerializedSize() { + return extensions.getSerializedSize(); + } + protected int extensionsSerializedSizeAsMessageSet() { + return extensions.getMessageSetSerializedSize(); + } + } + + /** + * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}. + */ + @SuppressWarnings("unchecked") + public abstract static class ExtendableBuilder< + MessageType extends ExtendableMessage, + BuilderType extends ExtendableBuilder> + extends Builder + implements ExtendableMessageOrBuilder { + protected ExtendableBuilder() {} + + private FieldSet extensions = FieldSet.emptySet(); + private boolean extensionsIsMutable; + + @Override + public BuilderType clear() { + extensions.clear(); + extensionsIsMutable = false; + return super.clear(); + } + + private void ensureExtensionsIsMutable() { + if (!extensionsIsMutable) { + extensions = extensions.clone(); + extensionsIsMutable = true; + } + } + + /** + * Called by the build code path to create a copy of the extensions for + * building the message. + */ + private FieldSet buildExtensions() { + extensions.makeImmutable(); + extensionsIsMutable = false; + return extensions; + } + + private void verifyExtensionContainingType( + final GeneratedExtension extension) { + if (extension.getContainingTypeDefaultInstance() != + getDefaultInstanceForType()) { + // This can only happen if someone uses unchecked operations. + throw new IllegalArgumentException( + "This extension is for a different message type. Please make " + + "sure that you are not suppressing any generics type warnings."); + } + } + + /** Check if a singular extension is present. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final boolean hasExtension( + final GeneratedExtension extension) { + verifyExtensionContainingType(extension); + return extensions.hasField(extension.descriptor); + } + + /** Get the number of elements in a repeated extension. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final int getExtensionCount( + final GeneratedExtension> extension) { + verifyExtensionContainingType(extension); + return extensions.getRepeatedFieldCount(extension.descriptor); + } + + /** Get the value of an extension. */ + //@Override (Java 1.6 override semantics, but we must support 1.5) + @SuppressWarnings("unchecked") + public final Type getExtension( + final GeneratedExtension extension) { + verifyExtensionContainingType(extension); + final Object value = extensions.getField(extension.descriptor); + if (value == null) { + return extension.defaultValue; + } else { + return (Type) value; + } + } + + /** Get one element of a repeated extension. */ + @SuppressWarnings("unchecked") + //@Override (Java 1.6 override semantics, but we must support 1.5) + public final Type getExtension( + final GeneratedExtension> extension, + final int index) { + verifyExtensionContainingType(extension); + return (Type) extensions.getRepeatedField(extension.descriptor, index); + } + + // This is implemented here only to work around an apparent bug in the + // Java compiler and/or build system. See bug #1898463. The mere presence + // of this dummy clone() implementation makes it go away. + @Override + public BuilderType clone() { + throw new UnsupportedOperationException( + "This is supposed to be overridden by subclasses."); + } + + /** Set the value of an extension. */ + public final BuilderType setExtension( + final GeneratedExtension extension, + final Type value) { + verifyExtensionContainingType(extension); + ensureExtensionsIsMutable(); + extensions.setField(extension.descriptor, value); + return (BuilderType) this; + } + + /** Set the value of one element of a repeated extension. */ + public final BuilderType setExtension( + final GeneratedExtension> extension, + final int index, final Type value) { + verifyExtensionContainingType(extension); + ensureExtensionsIsMutable(); + extensions.setRepeatedField(extension.descriptor, index, value); + return (BuilderType) this; + } + + /** Append a value to a repeated extension. */ + public final BuilderType addExtension( + final GeneratedExtension> extension, + final Type value) { + verifyExtensionContainingType(extension); + ensureExtensionsIsMutable(); + extensions.addRepeatedField(extension.descriptor, value); + return (BuilderType) this; + } + + /** Clear an extension. */ + public final BuilderType clearExtension( + final GeneratedExtension extension) { + verifyExtensionContainingType(extension); + ensureExtensionsIsMutable(); + extensions.clearField(extension.descriptor); + return (BuilderType) this; + } + + /** Called by subclasses to check if all extensions are initialized. */ + protected boolean extensionsAreInitialized() { + return extensions.isInitialized(); + } + + /** + * Called by subclasses to parse an unknown field or an extension. + * @return {@code true} unless the tag is an end-group tag. + */ + @Override + protected boolean parseUnknownField( + CodedInputStream input, + ExtensionRegistryLite extensionRegistry, + int tag) throws IOException { + ensureExtensionsIsMutable(); + return GeneratedMessageLite.parseUnknownField( + extensions, + getDefaultInstanceForType(), + input, + extensionRegistry, + tag); + } + + protected final void mergeExtensionFields(final MessageType other) { + ensureExtensionsIsMutable(); + extensions.mergeFrom(((ExtendableMessage) other).extensions); + } + } + + // ----------------------------------------------------------------- + + /** + * Parse an unknown field or an extension. + * @return {@code true} unless the tag is an end-group tag. + */ + private static + boolean parseUnknownField( + FieldSet extensions, + MessageType defaultInstance, + CodedInputStream input, + ExtensionRegistryLite extensionRegistry, + int tag) throws IOException { + int wireType = WireFormat.getTagWireType(tag); + int fieldNumber = WireFormat.getTagFieldNumber(tag); + + GeneratedExtension extension = + extensionRegistry.findLiteExtensionByNumber( + defaultInstance, fieldNumber); + + boolean unknown = false; + boolean packed = false; + if (extension == null) { + unknown = true; // Unknown field. + } else if (wireType == FieldSet.getWireFormatForFieldType( + extension.descriptor.getLiteType(), + false /* isPacked */)) { + packed = false; // Normal, unpacked value. + } else if (extension.descriptor.isRepeated && + extension.descriptor.type.isPackable() && + wireType == FieldSet.getWireFormatForFieldType( + extension.descriptor.getLiteType(), + true /* isPacked */)) { + packed = true; // Packed value. + } else { + unknown = true; // Wrong wire type. + } + + if (unknown) { // Unknown field or wrong wire type. Skip. + return input.skipField(tag); + } + + if (packed) { + int length = input.readRawVarint32(); + int limit = input.pushLimit(length); + if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) { + while (input.getBytesUntilLimit() > 0) { + int rawValue = input.readEnum(); + Object value = + extension.descriptor.getEnumType().findValueByNumber(rawValue); + if (value == null) { + // If the number isn't recognized as a valid value for this + // enum, drop it (don't even add it to unknownFields). + return true; + } + extensions.addRepeatedField(extension.descriptor, value); + } + } else { + while (input.getBytesUntilLimit() > 0) { + Object value = + FieldSet.readPrimitiveField(input, + extension.descriptor.getLiteType()); + extensions.addRepeatedField(extension.descriptor, value); + } + } + input.popLimit(limit); + } else { + Object value; + switch (extension.descriptor.getLiteJavaType()) { + case MESSAGE: { + MessageLite.Builder subBuilder = null; + if (!extension.descriptor.isRepeated()) { + MessageLite existingValue = + (MessageLite) extensions.getField(extension.descriptor); + if (existingValue != null) { + subBuilder = existingValue.toBuilder(); + } + } + if (subBuilder == null) { + subBuilder = extension.messageDefaultInstance.newBuilderForType(); + } + if (extension.descriptor.getLiteType() == + WireFormat.FieldType.GROUP) { + input.readGroup(extension.getNumber(), + subBuilder, extensionRegistry); + } else { + input.readMessage(subBuilder, extensionRegistry); + } + value = subBuilder.build(); + break; + } + case ENUM: + int rawValue = input.readEnum(); + value = extension.descriptor.getEnumType() + .findValueByNumber(rawValue); + // If the number isn't recognized as a valid value for this enum, + // drop it. + if (value == null) { + return true; + } + break; + default: + value = FieldSet.readPrimitiveField(input, + extension.descriptor.getLiteType()); + break; + } + + if (extension.descriptor.isRepeated()) { + extensions.addRepeatedField(extension.descriptor, value); + } else { + extensions.setField(extension.descriptor, value); + } + } + + return true; + } + + // ----------------------------------------------------------------- + + /** For use by generated code only. */ + public static + GeneratedExtension + newSingularGeneratedExtension( + final ContainingType containingTypeDefaultInstance, + final Type defaultValue, + final MessageLite messageDefaultInstance, + final Internal.EnumLiteMap enumTypeMap, + final int number, + final WireFormat.FieldType type) { + return new GeneratedExtension( + containingTypeDefaultInstance, + defaultValue, + messageDefaultInstance, + new ExtensionDescriptor(enumTypeMap, number, type, + false /* isRepeated */, + false /* isPacked */)); + } + + /** For use by generated code only. */ + public static + GeneratedExtension + newRepeatedGeneratedExtension( + final ContainingType containingTypeDefaultInstance, + final MessageLite messageDefaultInstance, + final Internal.EnumLiteMap enumTypeMap, + final int number, + final WireFormat.FieldType type, + final boolean isPacked) { + @SuppressWarnings("unchecked") // Subclasses ensure Type is a List + Type emptyList = (Type) Collections.emptyList(); + return new GeneratedExtension( + containingTypeDefaultInstance, + emptyList, + messageDefaultInstance, + new ExtensionDescriptor( + enumTypeMap, number, type, true /* isRepeated */, isPacked)); + } + + private static final class ExtensionDescriptor + implements FieldSet.FieldDescriptorLite< + ExtensionDescriptor> { + private ExtensionDescriptor( + final Internal.EnumLiteMap enumTypeMap, + final int number, + final WireFormat.FieldType type, + final boolean isRepeated, + final boolean isPacked) { + this.enumTypeMap = enumTypeMap; + this.number = number; + this.type = type; + this.isRepeated = isRepeated; + this.isPacked = isPacked; + } + + private final Internal.EnumLiteMap enumTypeMap; + private final int number; + private final WireFormat.FieldType type; + private final boolean isRepeated; + private final boolean isPacked; + + public int getNumber() { + return number; + } + + public WireFormat.FieldType getLiteType() { + return type; + } + + public WireFormat.JavaType getLiteJavaType() { + return type.getJavaType(); + } + + public boolean isRepeated() { + return isRepeated; + } + + public boolean isPacked() { + return isPacked; + } + + public Internal.EnumLiteMap getEnumType() { + return enumTypeMap; + } + + @SuppressWarnings("unchecked") + public MessageLite.Builder internalMergeFrom( + MessageLite.Builder to, MessageLite from) { + return ((Builder) to).mergeFrom((GeneratedMessageLite) from); + } + + public int compareTo(ExtensionDescriptor other) { + return number - other.number; + } + } + + /** + * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}. + * + * Users should ignore the contents of this class and only use objects of + * this type as parameters to extension accessors and ExtensionRegistry.add(). + */ + public static final class GeneratedExtension< + ContainingType extends MessageLite, Type> { + + private GeneratedExtension( + final ContainingType containingTypeDefaultInstance, + final Type defaultValue, + final MessageLite messageDefaultInstance, + final ExtensionDescriptor descriptor) { + // Defensive checks to verify the correct initialization order of + // GeneratedExtensions and their related GeneratedMessages. + if (containingTypeDefaultInstance == null) { + throw new IllegalArgumentException( + "Null containingTypeDefaultInstance"); + } + if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE && + messageDefaultInstance == null) { + throw new IllegalArgumentException( + "Null messageDefaultInstance"); + } + this.containingTypeDefaultInstance = containingTypeDefaultInstance; + this.defaultValue = defaultValue; + this.messageDefaultInstance = messageDefaultInstance; + this.descriptor = descriptor; + } + + private final ContainingType containingTypeDefaultInstance; + private final Type defaultValue; + private final MessageLite messageDefaultInstance; + private final ExtensionDescriptor descriptor; + + /** + * Default instance of the type being extended, used to identify that type. + */ + public ContainingType getContainingTypeDefaultInstance() { + return containingTypeDefaultInstance; + } + + /** Get the field number. */ + public int getNumber() { + return descriptor.getNumber(); + } + + /** + * If the extension is an embedded message, this is the default instance of + * that type. + */ + public MessageLite getMessageDefaultInstance() { + return messageDefaultInstance; + } + } + + /** + * A serialized (serializable) form of the generated message. Stores the + * message as a class name and a byte array. + */ + static final class SerializedForm implements Serializable { + private static final long serialVersionUID = 0L; + + private String messageClassName; + private byte[] asBytes; + + /** + * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}. + * @param regularForm the message to serialize + */ + SerializedForm(MessageLite regularForm) { + messageClassName = regularForm.getClass().getName(); + asBytes = regularForm.toByteArray(); + } + + /** + * When read from an ObjectInputStream, this method converts this object + * back to the regular form. Part of Java's serialization magic. + * @return a GeneratedMessage of the type that was serialized + */ + @SuppressWarnings("unchecked") + protected Object readResolve() throws ObjectStreamException { + try { + Class messageClass = Class.forName(messageClassName); + Method newBuilder = messageClass.getMethod("newBuilder"); + MessageLite.Builder builder = + (MessageLite.Builder) newBuilder.invoke(null); + builder.mergeFrom(asBytes); + return builder.buildPartial(); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Unable to find proto buffer class", e); + } catch (NoSuchMethodException e) { + throw new RuntimeException("Unable to find newBuilder method", e); + } catch (IllegalAccessException e) { + throw new RuntimeException("Unable to call newBuilder method", e); + } catch (InvocationTargetException e) { + throw new RuntimeException("Error calling newBuilder", e.getCause()); + } catch (InvalidProtocolBufferException e) { + throw new RuntimeException("Unable to understand proto buffer", e); + } + } + } + + /** + * Replaces this object in the output stream with a serialized form. + * Part of Java's serialization magic. Generated sub-classes must override + * this method by calling {@code return super.writeReplace();} + * @return a SerializedForm of this message + */ + protected Object writeReplace() throws ObjectStreamException { + return new SerializedForm(this); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Internal.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Internal.java new file mode 100644 index 0000000..81af258 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Internal.java @@ -0,0 +1,153 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.UnsupportedEncodingException; + +/** + * The classes contained within are used internally by the Protocol Buffer + * library and generated message implementations. They are public only because + * those generated messages do not reside in the {@code protobuf} package. + * Others should not use this class directly. + * + * @author kenton@google.com (Kenton Varda) + */ +public class Internal { + /** + * Helper called by generated code to construct default values for string + * fields. + *

+ * The protocol compiler does not actually contain a UTF-8 decoder -- it + * just pushes UTF-8-encoded text around without touching it. The one place + * where this presents a problem is when generating Java string literals. + * Unicode characters in the string literal would normally need to be encoded + * using a Unicode escape sequence, which would require decoding them. + * To get around this, protoc instead embeds the UTF-8 bytes into the + * generated code and leaves it to the runtime library to decode them. + *

+ * It gets worse, though. If protoc just generated a byte array, like: + * new byte[] {0x12, 0x34, 0x56, 0x78} + * Java actually generates *code* which allocates an array and then fills + * in each value. This is much less efficient than just embedding the bytes + * directly into the bytecode. To get around this, we need another + * work-around. String literals are embedded directly, so protoc actually + * generates a string literal corresponding to the bytes. The easiest way + * to do this is to use the ISO-8859-1 character set, which corresponds to + * the first 256 characters of the Unicode range. Protoc can then use + * good old CEscape to generate the string. + *

+ * So we have a string literal which represents a set of bytes which + * represents another string. This function -- stringDefaultValue -- + * converts from the generated string to the string we actually want. The + * generated code calls this automatically. + */ + public static String stringDefaultValue(String bytes) { + try { + return new String(bytes.getBytes("ISO-8859-1"), "UTF-8"); + } catch (UnsupportedEncodingException e) { + // This should never happen since all JVMs are required to implement + // both of the above character sets. + throw new IllegalStateException( + "Java VM does not support a standard character set.", e); + } + } + + /** + * Helper called by generated code to construct default values for bytes + * fields. + *

+ * This is a lot like {@link #stringDefaultValue}, but for bytes fields. + * In this case we only need the second of the two hacks -- allowing us to + * embed raw bytes as a string literal with ISO-8859-1 encoding. + */ + public static ByteString bytesDefaultValue(String bytes) { + try { + return ByteString.copyFrom(bytes.getBytes("ISO-8859-1")); + } catch (UnsupportedEncodingException e) { + // This should never happen since all JVMs are required to implement + // ISO-8859-1. + throw new IllegalStateException( + "Java VM does not support a standard character set.", e); + } + } + + /** + * Helper called by generated code to determine if a byte array is a valid + * UTF-8 encoded string such that the original bytes can be converted to + * a String object and then back to a byte array round tripping the bytes + * without loss. More precisely, returns {@code true} whenever: + *

   {@code
+   * Arrays.equals(byteString.toByteArray(),
+   *     new String(byteString.toByteArray(), "UTF-8").getBytes("UTF-8"))
+   * }
+ * + *

This method rejects "overlong" byte sequences, as well as + * 3-byte sequences that would map to a surrogate character, in + * accordance with the restricted definition of UTF-8 introduced in + * Unicode 3.1. Note that the UTF-8 decoder included in Oracle's + * JDK has been modified to also reject "overlong" byte sequences, + * but currently (2011) still accepts 3-byte surrogate character + * byte sequences. + * + *

See the Unicode Standard,
+ * Table 3-6. UTF-8 Bit Distribution,
+ * Table 3-7. Well Formed UTF-8 Byte Sequences. + * + *

As of 2011-02, this method simply returns the result of {@link + * ByteString#isValidUtf8()}. Calling that method directly is preferred. + * + * @param byteString the string to check + * @return whether the byte array is round trippable + */ + public static boolean isValidUtf8(ByteString byteString) { + return byteString.isValidUtf8(); + } + + /** + * Interface for an enum value or value descriptor, to be used in FieldSet. + * The lite library stores enum values directly in FieldSets but the full + * library stores EnumValueDescriptors in order to better support reflection. + */ + public interface EnumLite { + int getNumber(); + } + + /** + * Interface for an object which maps integers to {@link EnumLite}s. + * {@link Descriptors.EnumDescriptor} implements this interface by mapping + * numbers to {@link Descriptors.EnumValueDescriptor}s. Additionally, + * every generated enum type has a static method internalGetValueMap() which + * returns an implementation of this type that maps numbers to enum values. + */ + public interface EnumLiteMap { + T findValueByNumber(int number); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java new file mode 100644 index 0000000..72d7ff7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java @@ -0,0 +1,114 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.IOException; + +/** + * Thrown when a protocol message being parsed is invalid in some way, + * e.g. it contains a malformed varint or a negative byte length. + * + * @author kenton@google.com Kenton Varda + */ +public class InvalidProtocolBufferException extends IOException { + private static final long serialVersionUID = -1616151763072450476L; + private MessageLite unfinishedMessage = null; + + public InvalidProtocolBufferException(final String description) { + super(description); + } + + /** + * Attaches an unfinished message to the exception to support best-effort + * parsing in {@code Parser} interface. + * + * @return this + */ + public InvalidProtocolBufferException setUnfinishedMessage( + MessageLite unfinishedMessage) { + this.unfinishedMessage = unfinishedMessage; + return this; + } + + /** + * Returns the unfinished message attached to the exception, or null if + * no message is attached. + */ + public MessageLite getUnfinishedMessage() { + return unfinishedMessage; + } + + 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 than the " + + "input has been truncated or that an embedded message " + + "misreported its own length."); + } + + static InvalidProtocolBufferException negativeSize() { + return new InvalidProtocolBufferException( + "CodedInputStream encountered an embedded string or message " + + "which claimed to have negative size."); + } + + static InvalidProtocolBufferException malformedVarint() { + return new InvalidProtocolBufferException( + "CodedInputStream encountered a malformed varint."); + } + + static InvalidProtocolBufferException invalidTag() { + return new InvalidProtocolBufferException( + "Protocol message contained an invalid tag (zero)."); + } + + static InvalidProtocolBufferException invalidEndTag() { + return new InvalidProtocolBufferException( + "Protocol message end-group tag did not match expected tag."); + } + + static InvalidProtocolBufferException invalidWireType() { + return new InvalidProtocolBufferException( + "Protocol message tag had invalid wire type."); + } + + 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."); + } + + static InvalidProtocolBufferException sizeLimitExceeded() { + return new InvalidProtocolBufferException( + "Protocol message was too large. May be malicious. " + + "Use CodedInputStream.setSizeLimit() to increase the size limit."); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyField.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyField.java new file mode 100644 index 0000000..c4f9201 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyField.java @@ -0,0 +1,210 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.IOException; +import java.util.Iterator; +import java.util.Map.Entry; + +/** + * LazyField encapsulates the logic of lazily parsing message fields. It stores + * the message in a ByteString initially and then parse it on-demand. + * + * LazyField is thread-compatible e.g. concurrent read are safe, however, + * synchronizations are needed under read/write situations. + * + * Now LazyField is only used to lazily load MessageSet. + * TODO(xiangl): Use LazyField to lazily load all messages. + * + * @author xiangl@google.com (Xiang Li) + */ +class LazyField { + + final private MessageLite defaultInstance; + final private ExtensionRegistryLite extensionRegistry; + + // Mutable because it is initialized lazily. + private ByteString bytes; + private volatile MessageLite value; + private volatile boolean isDirty = false; + + public LazyField(MessageLite defaultInstance, + ExtensionRegistryLite extensionRegistry, ByteString bytes) { + this.defaultInstance = defaultInstance; + this.extensionRegistry = extensionRegistry; + this.bytes = bytes; + } + + public MessageLite getValue() { + ensureInitialized(); + return value; + } + + /** + * LazyField is not thread-safe for write access. Synchronizations are needed + * under read/write situations. + */ + public MessageLite setValue(MessageLite value) { + MessageLite originalValue = this.value; + this.value = value; + bytes = null; + isDirty = true; + return originalValue; + } + + /** + * Due to the optional field can be duplicated at the end of serialized + * bytes, which will make the serialized size changed after LazyField + * parsed. Be careful when using this method. + */ + public int getSerializedSize() { + if (isDirty) { + return value.getSerializedSize(); + } + return bytes.size(); + } + + public ByteString toByteString() { + if (!isDirty) { + return bytes; + } + synchronized (this) { + if (!isDirty) { + return bytes; + } + bytes = value.toByteString(); + isDirty = false; + return bytes; + } + } + + @Override + public int hashCode() { + ensureInitialized(); + return value.hashCode(); + } + + @Override + public boolean equals(Object obj) { + ensureInitialized(); + return value.equals(obj); + } + + @Override + public String toString() { + ensureInitialized(); + return value.toString(); + } + + private void ensureInitialized() { + if (value != null) { + return; + } + synchronized (this) { + if (value != null) { + return; + } + try { + if (bytes != null) { + value = defaultInstance.getParserForType() + .parseFrom(bytes, extensionRegistry); + } + } catch (IOException e) { + // TODO(xiangl): Refactory the API to support the exception thrown from + // lazily load messages. + } + } + } + + // ==================================================== + + /** + * LazyEntry and LazyIterator are used to encapsulate the LazyField, when + * users iterate all fields from FieldSet. + */ + static class LazyEntry implements Entry { + private Entry entry; + + private LazyEntry(Entry entry) { + this.entry = entry; + } + + public K getKey() { + return entry.getKey(); + } + + public Object getValue() { + LazyField field = entry.getValue(); + if (field == null) { + return null; + } + return field.getValue(); + } + + public LazyField getField() { + return entry.getValue(); + } + + public Object setValue(Object value) { + if (!(value instanceof MessageLite)) { + throw new IllegalArgumentException( + "LazyField now only used for MessageSet, " + + "and the value of MessageSet must be an instance of MessageLite"); + } + return entry.getValue().setValue((MessageLite) value); + } + } + + static class LazyIterator implements Iterator> { + private Iterator> iterator; + + public LazyIterator(Iterator> iterator) { + this.iterator = iterator; + } + + public boolean hasNext() { + return iterator.hasNext(); + } + + @SuppressWarnings("unchecked") + public Entry next() { + Entry entry = iterator.next(); + if (entry.getValue() instanceof LazyField) { + return new LazyEntry((Entry) entry); + } + return (Entry) entry; + } + + public void remove() { + iterator.remove(); + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyStringArrayList.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyStringArrayList.java new file mode 100644 index 0000000..a5f0bd9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyStringArrayList.java @@ -0,0 +1,178 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.util.List; +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.RandomAccess; + +/** + * An implementation of {@link LazyStringList} that wraps an ArrayList. Each + * element is either a ByteString or a String. It caches the last one requested + * which is most likely the one needed next. This minimizes memory usage while + * satisfying the most common use cases. + *

+ * Note that this implementation is not synchronized. + * If multiple threads access an ArrayList instance concurrently, + * and at least one of the threads modifies the list structurally, it + * must be synchronized externally. (A structural modification is + * any operation that adds or deletes one or more elements, or explicitly + * resizes the backing array; merely setting the value of an element is not + * a structural modification.) This is typically accomplished by + * synchronizing on some object that naturally encapsulates the list. + *

+ * If the implementation is accessed via concurrent reads, this is thread safe. + * Conversions are done in a thread safe manner. It's possible that the + * conversion may happen more than once if two threads attempt to access the + * same element and the modifications were not visible to each other, but this + * will not result in any corruption of the list or change in behavior other + * than performance. + * + * @author jonp@google.com (Jon Perlow) + */ +public class LazyStringArrayList extends AbstractList + implements LazyStringList, RandomAccess { + + public final static LazyStringList EMPTY = new UnmodifiableLazyStringList( + new LazyStringArrayList()); + + private final List list; + + public LazyStringArrayList() { + list = new ArrayList(); + } + + public LazyStringArrayList(LazyStringList from) { + list = new ArrayList(from.size()); + addAll(from); + } + + public LazyStringArrayList(List from) { + list = new ArrayList(from); + } + + @Override + public String get(int index) { + Object o = list.get(index); + if (o instanceof String) { + return (String) o; + } else { + ByteString bs = (ByteString) o; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + list.set(index, s); + } + return s; + } + } + + @Override + public int size() { + return list.size(); + } + + @Override + public String set(int index, String s) { + Object o = list.set(index, s); + return asString(o); + } + + @Override + public void add(int index, String element) { + list.add(index, element); + modCount++; + } + + @Override + public boolean addAll(Collection c) { + // The default implementation of AbstractCollection.addAll(Collection) + // delegates to add(Object). This implementation instead delegates to + // addAll(int, Collection), which makes a special case for Collections + // which are instances of LazyStringList. + return addAll(size(), c); + } + + @Override + public boolean addAll(int index, Collection c) { + // When copying from another LazyStringList, directly copy the underlying + // elements rather than forcing each element to be decoded to a String. + Collection collection = c instanceof LazyStringList + ? ((LazyStringList) c).getUnderlyingElements() : c; + boolean ret = list.addAll(index, collection); + modCount++; + return ret; + } + + @Override + public String remove(int index) { + Object o = list.remove(index); + modCount++; + return asString(o); + } + + public void clear() { + list.clear(); + modCount++; + } + + // @Override + public void add(ByteString element) { + list.add(element); + modCount++; + } + + // @Override + public ByteString getByteString(int index) { + Object o = list.get(index); + if (o instanceof String) { + ByteString b = ByteString.copyFromUtf8((String) o); + list.set(index, b); + return b; + } else { + return (ByteString) o; + } + } + + private String asString(Object o) { + if (o instanceof String) { + return (String) o; + } else { + return ((ByteString) o).toStringUtf8(); + } + } + + public List getUnderlyingElements() { + return Collections.unmodifiableList(list); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyStringList.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyStringList.java new file mode 100644 index 0000000..630932f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LazyStringList.java @@ -0,0 +1,81 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.util.List; + +/** + * An interface extending {@code List} that also provides access to the + * items of the list as UTF8-encoded ByteString objects. This is used by the + * protocol buffer implementation to support lazily converting bytes parsed + * over the wire to String objects until needed and also increases the + * efficiency of serialization if the String was never requested as the + * ByteString is already cached. + *

+ * This only adds additional methods that are required for the use in the + * protocol buffer code in order to be able successfully round trip byte arrays + * through parsing and serialization without conversion to strings. It's not + * attempting to support the functionality of say {@code List}, hence + * why only these two very specific methods are added. + * + * @author jonp@google.com (Jon Perlow) + */ +public interface LazyStringList extends List { + + /** + * Returns the element at the specified position in this list as a ByteString. + * + * @param index index of the element to return + * @return the element at the specified position in this list + * @throws IndexOutOfBoundsException if the index is out of range + * ({@code index < 0 || index >= size()}) + */ + ByteString getByteString(int index); + + /** + * Appends the specified element to the end of this list (optional + * operation). + * + * @param element element to be appended to this list + * @throws UnsupportedOperationException if the add operation + * is not supported by this list + */ + void add(ByteString element); + + /** + * Returns an unmodifiable List of the underlying elements, each of + * which is either a {@code String} or its equivalent UTF-8 encoded + * {@code ByteString}. It is an error for the caller to modify the returned + * List, and attempting to do so will result in an + * {@link UnsupportedOperationException}. + */ + List getUnderlyingElements(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LiteralByteString.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LiteralByteString.java new file mode 100644 index 0000000..93c53dc --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/LiteralByteString.java @@ -0,0 +1,349 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; + +/** + * This class implements a {@link com.google.protobuf.ByteString} backed by a + * single array of bytes, contiguous in memory. It supports substring by + * pointing to only a sub-range of the underlying byte array, meaning that a + * substring will reference the full byte-array of the string it's made from, + * exactly as with {@link String}. + * + * @author carlanton@google.com (Carl Haverl) + */ +class LiteralByteString extends ByteString { + + protected final byte[] bytes; + + /** + * Creates a {@code LiteralByteString} backed by the given array, without + * copying. + * + * @param bytes array to wrap + */ + LiteralByteString(byte[] bytes) { + this.bytes = bytes; + } + + @Override + public byte byteAt(int index) { + // Unlike most methods in this class, this one is a direct implementation + // ignoring the potential offset because we need to do range-checking in the + // substring case anyway. + return bytes[index]; + } + + @Override + public int size() { + return bytes.length; + } + + // ================================================================= + // ByteString -> substring + + @Override + public ByteString substring(int beginIndex, int endIndex) { + if (beginIndex < 0) { + throw new IndexOutOfBoundsException( + "Beginning index: " + beginIndex + " < 0"); + } + if (endIndex > size()) { + throw new IndexOutOfBoundsException("End index: " + endIndex + " > " + + size()); + } + int substringLength = endIndex - beginIndex; + if (substringLength < 0) { + throw new IndexOutOfBoundsException( + "Beginning index larger than ending index: " + beginIndex + ", " + + endIndex); + } + + ByteString result; + if (substringLength == 0) { + result = ByteString.EMPTY; + } else { + result = new BoundedByteString(bytes, getOffsetIntoBytes() + beginIndex, + substringLength); + } + return result; + } + + // ================================================================= + // ByteString -> byte[] + + @Override + protected void copyToInternal(byte[] target, int sourceOffset, + int targetOffset, int numberToCopy) { + // Optimized form, not for subclasses, since we don't call + // getOffsetIntoBytes() or check the 'numberToCopy' parameter. + System.arraycopy(bytes, sourceOffset, target, targetOffset, numberToCopy); + } + + @Override + public void copyTo(ByteBuffer target) { + target.put(bytes, getOffsetIntoBytes(), size()); // Copies bytes + } + + @Override + public ByteBuffer asReadOnlyByteBuffer() { + ByteBuffer byteBuffer = + ByteBuffer.wrap(bytes, getOffsetIntoBytes(), size()); + return byteBuffer.asReadOnlyBuffer(); + } + + @Override + public List asReadOnlyByteBufferList() { + // Return the ByteBuffer generated by asReadOnlyByteBuffer() as a singleton + List result = new ArrayList(1); + result.add(asReadOnlyByteBuffer()); + return result; + } + + @Override + public void writeTo(OutputStream outputStream) throws IOException { + outputStream.write(toByteArray()); + } + + @Override + public String toString(String charsetName) + throws UnsupportedEncodingException { + return new String(bytes, getOffsetIntoBytes(), size(), charsetName); + } + + // ================================================================= + // UTF-8 decoding + + @Override + public boolean isValidUtf8() { + int offset = getOffsetIntoBytes(); + return Utf8.isValidUtf8(bytes, offset, offset + size()); + } + + @Override + protected int partialIsValidUtf8(int state, int offset, int length) { + int index = getOffsetIntoBytes() + offset; + return Utf8.partialIsValidUtf8(state, bytes, index, index + length); + } + + // ================================================================= + // equals() and hashCode() + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if (!(other instanceof ByteString)) { + return false; + } + + if (size() != ((ByteString) other).size()) { + return false; + } + if (size() == 0) { + return true; + } + + if (other instanceof LiteralByteString) { + return equalsRange((LiteralByteString) other, 0, size()); + } else if (other instanceof RopeByteString) { + return other.equals(this); + } else { + throw new IllegalArgumentException( + "Has a new type of ByteString been created? Found " + + other.getClass()); + } + } + + /** + * Check equality of the substring of given length of this object starting at + * zero with another {@code LiteralByteString} substring starting at offset. + * + * @param other what to compare a substring in + * @param offset offset into other + * @param length number of bytes to compare + * @return true for equality of substrings, else false. + */ + boolean equalsRange(LiteralByteString other, int offset, int length) { + if (length > other.size()) { + throw new IllegalArgumentException( + "Length too large: " + length + size()); + } + if (offset + length > other.size()) { + throw new IllegalArgumentException( + "Ran off end of other: " + offset + ", " + length + ", " + + other.size()); + } + + byte[] thisBytes = bytes; + byte[] otherBytes = other.bytes; + int thisLimit = getOffsetIntoBytes() + length; + for (int thisIndex = getOffsetIntoBytes(), otherIndex = + other.getOffsetIntoBytes() + offset; + (thisIndex < thisLimit); ++thisIndex, ++otherIndex) { + if (thisBytes[thisIndex] != otherBytes[otherIndex]) { + return false; + } + } + return true; + } + + /** + * Cached hash value. Intentionally accessed via a data race, which + * is safe because of the Java Memory Model's "no out-of-thin-air values" + * guarantees for ints. + */ + private int hash = 0; + + /** + * Compute the hashCode using the traditional algorithm from {@link + * ByteString}. + * + * @return hashCode value + */ + @Override + public int hashCode() { + int h = hash; + + if (h == 0) { + int size = size(); + h = partialHash(size, 0, size); + if (h == 0) { + h = 1; + } + hash = h; + } + return h; + } + + @Override + protected int peekCachedHashCode() { + return hash; + } + + @Override + protected int partialHash(int h, int offset, int length) { + byte[] thisBytes = bytes; + for (int i = getOffsetIntoBytes() + offset, limit = i + length; i < limit; + i++) { + h = h * 31 + thisBytes[i]; + } + return h; + } + + // ================================================================= + // Input stream + + @Override + public InputStream newInput() { + return new ByteArrayInputStream(bytes, getOffsetIntoBytes(), + size()); // No copy + } + + @Override + public CodedInputStream newCodedInput() { + // We trust CodedInputStream not to modify the bytes, or to give anyone + // else access to them. + return CodedInputStream + .newInstance(bytes, getOffsetIntoBytes(), size()); // No copy + } + + // ================================================================= + // ByteIterator + + @Override + public ByteIterator iterator() { + return new LiteralByteIterator(); + } + + private class LiteralByteIterator implements ByteIterator { + private int position; + private final int limit; + + private LiteralByteIterator() { + position = 0; + limit = size(); + } + + public boolean hasNext() { + return (position < limit); + } + + public Byte next() { + // Boxing calls Byte.valueOf(byte), which does not instantiate. + return nextByte(); + } + + public byte nextByte() { + try { + return bytes[position++]; + } catch (ArrayIndexOutOfBoundsException e) { + throw new NoSuchElementException(e.getMessage()); + } + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + + // ================================================================= + // Internal methods + + @Override + protected int getTreeDepth() { + return 0; + } + + @Override + protected boolean isBalanced() { + return true; + } + + /** + * Offset into {@code bytes[]} to use, non-zero for substrings. + * + * @return always 0 for this class + */ + protected int getOffsetIntoBytes() { + return 0; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Message.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Message.java new file mode 100644 index 0000000..2b88141 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Message.java @@ -0,0 +1,237 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// TODO(kenton): Use generics? E.g. Builder, then +// mergeFrom*() could return BuilderType for better type-safety. + +package com.google.protobuf; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +/** + * Abstract interface implemented by Protocol Message objects. + *

+ * See also {@link MessageLite}, which defines most of the methods that typical + * users care about. {@link Message} adds to it methods that are not available + * in the "lite" runtime. The biggest added features are introspection and + * reflection -- i.e., getting descriptors for the message type and accessing + * the field values dynamically. + * + * @author kenton@google.com Kenton Varda + */ +public interface Message extends MessageLite, MessageOrBuilder { + + // (From MessageLite, re-declared here only for return type covariance.) + Parser getParserForType(); + + // ----------------------------------------------------------------- + // Comparison and hashing + + /** + * Compares the specified object with this message for equality. Returns + * {@code true} if the given object is a message of the same type (as + * defined by {@code getDescriptorForType()}) and has identical values for + * all of its fields. Subclasses must implement this; inheriting + * {@code Object.equals()} is incorrect. + * + * @param other object to be compared for equality with this message + * @return {@code true} if the specified object is equal to this message + */ + @Override + boolean equals(Object other); + + /** + * Returns the hash code value for this message. The hash code of a message + * should mix the message's type (object identity of the descriptor) with its + * contents (known and unknown field values). Subclasses must implement this; + * inheriting {@code Object.hashCode()} is incorrect. + * + * @return the hash code value for this message + * @see Map#hashCode() + */ + @Override + int hashCode(); + + // ----------------------------------------------------------------- + // Convenience methods. + + /** + * Converts the message to a string in protocol buffer text format. This is + * just a trivial wrapper around {@link + * TextFormat#printToString(MessageOrBuilder)}. + */ + @Override + String toString(); + + // ================================================================= + // Builders + + // (From MessageLite, re-declared here only for return type covariance.) + Builder newBuilderForType(); + Builder toBuilder(); + + /** + * Abstract interface implemented by Protocol Message builders. + */ + interface Builder extends MessageLite.Builder, MessageOrBuilder { + // (From MessageLite.Builder, re-declared here only for return type + // covariance.) + Builder clear(); + + /** + * Merge {@code other} into the message being built. {@code other} must + * have the exact same type as {@code this} (i.e. + * {@code getDescriptorForType() == other.getDescriptorForType()}). + * + * Merging occurs as follows. For each field:
+ * * For singular primitive fields, if the field is set in {@code other}, + * then {@code other}'s value overwrites the value in this message.
+ * * For singular message fields, if the field is set in {@code other}, + * it is merged into the corresponding sub-message of this message + * using the same merging rules.
+ * * For repeated fields, the elements in {@code other} are concatenated + * with the elements in this message. + * + * This is equivalent to the {@code Message::MergeFrom} method in C++. + */ + Builder mergeFrom(Message other); + + // (From MessageLite.Builder, re-declared here only for return type + // covariance.) + Message build(); + Message buildPartial(); + Builder clone(); + Builder mergeFrom(CodedInputStream input) throws IOException; + Builder mergeFrom(CodedInputStream input, + ExtensionRegistryLite extensionRegistry) + throws IOException; + + /** + * Get the message's type's descriptor. + * See {@link Message#getDescriptorForType()}. + */ + Descriptors.Descriptor getDescriptorForType(); + + /** + * Create a Builder for messages of the appropriate type for the given + * field. Messages built with this can then be passed to setField(), + * setRepeatedField(), or addRepeatedField(). + */ + Builder newBuilderForField(Descriptors.FieldDescriptor field); + + /** + * Get a nested builder instance for the given field. + *

+ * Normally, we hold a reference to the immutable message object for the + * message type field. Some implementations(the generated message builders), + * however, can also hold a reference to the builder object (a nested + * builder) for the field. + *

+ * If the field is already backed up by a nested builder, the nested builder + * will be returned. Otherwise, a new field builder will be created and + * returned. The original message field (if exist) will be merged into the + * field builder, which will then be nested into its parent builder. + *

+ * NOTE: implementations that do not support nested builders will throw + * UnsupportedException. + */ + Builder getFieldBuilder(Descriptors.FieldDescriptor field); + + /** + * Sets a field to the given value. The value must be of the correct type + * for this field, i.e. the same type that + * {@link Message#getField(Descriptors.FieldDescriptor)} would return. + */ + Builder setField(Descriptors.FieldDescriptor field, Object value); + + /** + * Clears the field. This is exactly equivalent to calling the generated + * "clear" accessor method corresponding to the field. + */ + Builder clearField(Descriptors.FieldDescriptor field); + + /** + * Sets an element of a repeated field to the given value. The value must + * be of the correct type for this field, i.e. the same type that + * {@link Message#getRepeatedField(Descriptors.FieldDescriptor,int)} would + * return. + * @throws IllegalArgumentException The field is not a repeated field, or + * {@code field.getContainingType() != getDescriptorForType()}. + */ + Builder setRepeatedField(Descriptors.FieldDescriptor field, + int index, Object value); + + /** + * Like {@code setRepeatedField}, but appends the value as a new element. + * @throws IllegalArgumentException The field is not a repeated field, or + * {@code field.getContainingType() != getDescriptorForType()}. + */ + Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value); + + /** Set the {@link UnknownFieldSet} for this message. */ + Builder setUnknownFields(UnknownFieldSet unknownFields); + + /** + * Merge some unknown fields into the {@link UnknownFieldSet} for this + * message. + */ + Builder mergeUnknownFields(UnknownFieldSet unknownFields); + + // --------------------------------------------------------------- + // Convenience methods. + + // (From MessageLite.Builder, re-declared here only for return type + // covariance.) + Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException; + Builder mergeFrom(ByteString data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException; + Builder mergeFrom(byte[] data, int off, int len) + throws InvalidProtocolBufferException; + Builder mergeFrom(byte[] data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + Builder mergeFrom(byte[] data, int off, int len, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + Builder mergeFrom(InputStream input) throws IOException; + Builder mergeFrom(InputStream input, + ExtensionRegistryLite extensionRegistry) + throws IOException; + boolean mergeDelimitedFrom(InputStream input) + throws IOException; + boolean mergeDelimitedFrom(InputStream input, + ExtensionRegistryLite extensionRegistry) + throws IOException; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageLite.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageLite.java new file mode 100644 index 0000000..e5b9a47 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageLite.java @@ -0,0 +1,319 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// TODO(kenton): Use generics? E.g. Builder, then +// mergeFrom*() could return BuilderType for better type-safety. + +package com.google.protobuf; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Abstract interface implemented by Protocol Message objects. + * + *

This interface is implemented by all protocol message objects. Non-lite + * messages additionally implement the Message interface, which is a subclass + * of MessageLite. Use MessageLite instead when you only need the subset of + * features which it supports -- namely, nothing that uses descriptors or + * reflection. You can instruct the protocol compiler to generate classes + * which implement only MessageLite, not the full Message interface, by adding + * the follow line to the .proto file: + *

+ *   option optimize_for = LITE_RUNTIME;
+ * 
+ * + *

This is particularly useful on resource-constrained systems where the + * full protocol buffers runtime library is too big. + * + *

Note that on non-constrained systems (e.g. servers) when you need to link + * in lots of protocol definitions, a better way to reduce total code footprint + * is to use {@code optimize_for = CODE_SIZE}. This will make the generated + * code smaller while still supporting all the same features (at the expense of + * speed). {@code optimize_for = LITE_RUNTIME} is best when you only have a + * small number of message types linked into your binary, in which case the + * size of the protocol buffers runtime itself is the biggest problem. + * + * @author kenton@google.com Kenton Varda + */ +public interface MessageLite extends MessageLiteOrBuilder { + + + /** + * Serializes the message and writes it to {@code output}. This does not + * flush or close the stream. + */ + void writeTo(CodedOutputStream output) throws IOException; + + /** + * Get the number of bytes required to encode this message. The result + * is only computed on the first call and memoized after that. + */ + int getSerializedSize(); + + + /** + * Gets the parser for a message of the same type as this message. + */ + Parser getParserForType(); + + // ----------------------------------------------------------------- + // Convenience methods. + + /** + * Serializes the message to a {@code ByteString} and returns it. This is + * just a trivial wrapper around + * {@link #writeTo(CodedOutputStream)}. + */ + ByteString toByteString(); + + /** + * Serializes the message to a {@code byte} array and returns it. This is + * just a trivial wrapper around + * {@link #writeTo(CodedOutputStream)}. + */ + byte[] toByteArray(); + + /** + * Serializes the message and writes it to {@code output}. This is just a + * trivial wrapper around {@link #writeTo(CodedOutputStream)}. This does + * not flush or close the stream. + *

+ * NOTE: Protocol Buffers are not self-delimiting. Therefore, if you write + * any more data to the stream after the message, you must somehow ensure + * that the parser on the receiving end does not interpret this as being + * part of the protocol message. This can be done e.g. by writing the size + * of the message before the data, then making sure to limit the input to + * that size on the receiving end (e.g. by wrapping the InputStream in one + * which limits the input). Alternatively, just use + * {@link #writeDelimitedTo(OutputStream)}. + */ + void writeTo(OutputStream output) throws IOException; + + /** + * Like {@link #writeTo(OutputStream)}, but writes the size of the message + * as a varint before writing the data. This allows more data to be written + * to the stream after the message without the need to delimit the message + * data yourself. Use {@link Builder#mergeDelimitedFrom(InputStream)} (or + * the static method {@code YourMessageType.parseDelimitedFrom(InputStream)}) + * to parse messages written by this method. + */ + void writeDelimitedTo(OutputStream output) throws IOException; + + // ================================================================= + // Builders + + /** + * Constructs a new builder for a message of the same type as this message. + */ + Builder newBuilderForType(); + + /** + * Constructs a builder initialized with the current message. Use this to + * derive a new message from the current one. + */ + Builder toBuilder(); + + /** + * Abstract interface implemented by Protocol Message builders. + */ + interface Builder extends MessageLiteOrBuilder, Cloneable { + /** Resets all fields to their default values. */ + Builder clear(); + + /** + * Constructs the message based on the state of the Builder. Subsequent + * changes to the Builder will not affect the returned message. + * @throws UninitializedMessageException The message is missing one or more + * required fields (i.e. {@link #isInitialized()} returns false). + * Use {@link #buildPartial()} to bypass this check. + */ + MessageLite build(); + + /** + * Like {@link #build()}, but does not throw an exception if the message + * is missing required fields. Instead, a partial message is returned. + * Subsequent changes to the Builder will not affect the returned message. + */ + MessageLite buildPartial(); + + /** + * Clones the Builder. + * @see Object#clone() + */ + Builder clone(); + + /** + * Parses a message of this type from the input and merges it with this + * message. + * + *

Warning: This does not verify that all required fields are present in + * the input message. If you call {@link #build()} without setting all + * required fields, it will throw an {@link UninitializedMessageException}, + * which is a {@code RuntimeException} and thus might not be caught. There + * are a few good ways to deal with this: + *

    + *
  • Call {@link #isInitialized()} to verify that all required fields + * are set before building. + *
  • Use {@code buildPartial()} to build, which ignores missing + * required fields. + *
+ * + *

Note: The caller should call + * {@link CodedInputStream#checkLastTagWas(int)} after calling this to + * verify that the last tag seen was the appropriate end-group tag, + * or zero for EOF. + */ + Builder mergeFrom(CodedInputStream input) throws IOException; + + /** + * Like {@link Builder#mergeFrom(CodedInputStream)}, but also + * parses extensions. The extensions that you want to be able to parse + * must be registered in {@code extensionRegistry}. Extensions not in + * the registry will be treated as unknown fields. + */ + Builder mergeFrom(CodedInputStream input, + ExtensionRegistryLite extensionRegistry) + throws IOException; + + // --------------------------------------------------------------- + // Convenience methods. + + /** + * Parse {@code data} as a message of this type and merge it with the + * message being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream)}. + * + * @return this + */ + Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException; + + /** + * Parse {@code data} as a message of this type and merge it with the + * message being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}. + * + * @return this + */ + Builder mergeFrom(ByteString data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Parse {@code data} as a message of this type and merge it with the + * message being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream)}. + * + * @return this + */ + Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException; + + /** + * Parse {@code data} as a message of this type and merge it with the + * message being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream)}. + * + * @return this + */ + Builder mergeFrom(byte[] data, int off, int len) + throws InvalidProtocolBufferException; + + /** + * Parse {@code data} as a message of this type and merge it with the + * message being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}. + * + * @return this + */ + Builder mergeFrom(byte[] data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Parse {@code data} as a message of this type and merge it with the + * message being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}. + * + * @return this + */ + Builder mergeFrom(byte[] data, int off, int len, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Parse a message of this type from {@code input} and merge it with the + * message being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream)}. Note that this method always + * reads the entire input (unless it throws an exception). If you + * want it to stop earlier, you will need to wrap your input in some + * wrapper stream that limits reading. Or, use + * {@link MessageLite#writeDelimitedTo(OutputStream)} to write your message + * and {@link #mergeDelimitedFrom(InputStream)} to read it. + *

+ * Despite usually reading the entire input, this does not close the stream. + * + * @return this + */ + Builder mergeFrom(InputStream input) throws IOException; + + /** + * Parse a message of this type from {@code input} and merge it with the + * message being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}. + * + * @return this + */ + Builder mergeFrom(InputStream input, + ExtensionRegistryLite extensionRegistry) + throws IOException; + + /** + * Like {@link #mergeFrom(InputStream)}, but does not read until EOF. + * Instead, the size of the message (encoded as a varint) is read first, + * then the message data. Use + * {@link MessageLite#writeDelimitedTo(OutputStream)} to write messages in + * this format. + * + * @return True if successful, or false if the stream is at EOF when the + * method starts. Any other error (including reaching EOF during + * parsing) will cause an exception to be thrown. + */ + boolean mergeDelimitedFrom(InputStream input) + throws IOException; + + /** + * Like {@link #mergeDelimitedFrom(InputStream)} but supporting extensions. + */ + boolean mergeDelimitedFrom(InputStream input, + ExtensionRegistryLite extensionRegistry) + throws IOException; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java new file mode 100644 index 0000000..05b2b16 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java @@ -0,0 +1,60 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + * Base interface for methods common to {@link MessageLite} + * and {@link MessageLite.Builder} to provide type equivalency. + * + * @author jonp@google.com (Jon Perlow) + */ +public interface MessageLiteOrBuilder { + /** + * Get an instance of the type with no fields set. Because no fields are set, + * all getters for singular fields will return default values and repeated + * fields will appear empty. + * This may or may not be a singleton. This differs from the + * {@code getDefaultInstance()} method of generated message classes in that + * this method is an abstract method of the {@code MessageLite} interface + * whereas {@code getDefaultInstance()} is a static method of a specific + * class. They return the same thing. + */ + MessageLite getDefaultInstanceForType(); + + /** + * Returns true if all required fields in the message and all embedded + * messages are set, false otherwise. + * + *

See also: {@link MessageOrBuilder#getInitializationErrorString()} + */ + boolean isInitialized(); + +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageOrBuilder.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageOrBuilder.java new file mode 100644 index 0000000..bf62d45 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/MessageOrBuilder.java @@ -0,0 +1,129 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.util.List; +import java.util.Map; + +/** + * Base interface for methods common to {@link Message} and + * {@link Message.Builder} to provide type equivalency. + * + * @author jonp@google.com (Jon Perlow) + */ +public interface MessageOrBuilder extends MessageLiteOrBuilder { + + // (From MessageLite, re-declared here only for return type covariance.) + //@Override (Java 1.6 override semantics, but we must support 1.5) + Message getDefaultInstanceForType(); + + /** + * Returns a list of field paths (e.g. "foo.bar.baz") of required fields + * which are not set in this message. You should call + * {@link MessageLiteOrBuilder#isInitialized()} first to check if there + * are any missing fields, as that method is likely to be much faster + * than this one even when the message is fully-initialized. + */ + List findInitializationErrors(); + + /** + * Returns a comma-delimited list of required fields which are not set + * in this message object. You should call + * {@link MessageLiteOrBuilder#isInitialized()} first to check if there + * are any missing fields, as that method is likely to be much faster + * than this one even when the message is fully-initialized. + */ + String getInitializationErrorString(); + + /** + * Get the message's type's descriptor. This differs from the + * {@code getDescriptor()} method of generated message classes in that + * this method is an abstract method of the {@code Message} interface + * whereas {@code getDescriptor()} is a static method of a specific class. + * They return the same thing. + */ + Descriptors.Descriptor getDescriptorForType(); + + /** + * Returns a collection of all the fields in this message which are set + * and their corresponding values. A singular ("required" or "optional") + * field is set iff hasField() returns true for that field. A "repeated" + * field is set iff getRepeatedFieldSize() is greater than zero. The + * values are exactly what would be returned by calling + * {@link #getField(Descriptors.FieldDescriptor)} for each field. The map + * is guaranteed to be a sorted map, so iterating over it will return fields + * in order by field number. + *
+ * If this is for a builder, the returned map may or may not reflect future + * changes to the builder. Either way, the returned map is itself + * unmodifiable. + */ + Map getAllFields(); + + /** + * Returns true if the given field is set. This is exactly equivalent to + * calling the generated "has" accessor method corresponding to the field. + * @throws IllegalArgumentException The field is a repeated field, or + * {@code field.getContainingType() != getDescriptorForType()}. + */ + boolean hasField(Descriptors.FieldDescriptor field); + + /** + * Obtains the value of the given field, or the default value if it is + * not set. For primitive fields, the boxed primitive value is returned. + * For enum fields, the EnumValueDescriptor for the value is returned. For + * embedded message fields, the sub-message is returned. For repeated + * fields, a java.util.List is returned. + */ + Object getField(Descriptors.FieldDescriptor field); + + /** + * Gets the number of elements of a repeated field. This is exactly + * equivalent to calling the generated "Count" accessor method corresponding + * to the field. + * @throws IllegalArgumentException The field is not a repeated field, or + * {@code field.getContainingType() != getDescriptorForType()}. + */ + int getRepeatedFieldCount(Descriptors.FieldDescriptor field); + + /** + * Gets an element of a repeated field. For primitive fields, the boxed + * primitive value is returned. For enum fields, the EnumValueDescriptor + * for the value is returned. For embedded message fields, the sub-message + * is returned. + * @throws IllegalArgumentException The field is not a repeated field, or + * {@code field.getContainingType() != getDescriptorForType()}. + */ + Object getRepeatedField(Descriptors.FieldDescriptor field, int index); + + /** Get the {@link UnknownFieldSet} for this message. */ + UnknownFieldSet getUnknownFields(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Parser.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Parser.java new file mode 100644 index 0000000..7d8e821 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Parser.java @@ -0,0 +1,259 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.InputStream; + +/** + * Abstract interface for parsing Protocol Messages. + * + * @author liujisi@google.com (Pherl Liu) + */ +public interface Parser { + /** + * Parses a message of {@code MessageType} from the input. + * + *

Note: The caller should call + * {@link CodedInputStream#checkLastTagWas(int)} after calling this to + * verify that the last tag seen was the appropriate end-group tag, + * or zero for EOF. + */ + public MessageType parseFrom(CodedInputStream input) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(CodedInputStream)}, but also parses extensions. + * The extensions that you want to be able to parse must be registered in + * {@code extensionRegistry}. Extensions not in the registry will be treated + * as unknown fields. + */ + public MessageType parseFrom(CodedInputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(CodedInputStream)}, but does not throw an + * exception if the message is missing required fields. Instead, a partial + * message is returned. + */ + public MessageType parsePartialFrom(CodedInputStream input) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(CodedInputStream input, ExtensionRegistryLite)}, + * but does not throw an exception if the message is missing required fields. + * Instead, a partial message is returned. + */ + public MessageType parsePartialFrom(CodedInputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + // --------------------------------------------------------------- + // Convenience methods. + + /** + * Parses {@code data} as a message of {@code MessageType}. + * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}. + */ + public MessageType parseFrom(ByteString data) + throws InvalidProtocolBufferException; + + /** + * Parses {@code data} as a message of {@code MessageType}. + * This is just a small wrapper around + * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}. + */ + public MessageType parseFrom(ByteString data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(ByteString)}, but does not throw an + * exception if the message is missing required fields. Instead, a partial + * message is returned. + */ + public MessageType parsePartialFrom(ByteString data) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(ByteString, ExtensionRegistryLite)}, + * but does not throw an exception if the message is missing required fields. + * Instead, a partial message is returned. + */ + public MessageType parsePartialFrom(ByteString data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Parses {@code data} as a message of {@code MessageType}. + * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}. + */ + public MessageType parseFrom(byte[] data, int off, int len) + throws InvalidProtocolBufferException; + + /** + * Parses {@code data} as a message of {@code MessageType}. + * This is just a small wrapper around + * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}. + */ + public MessageType parseFrom(byte[] data, int off, int len, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Parses {@code data} as a message of {@code MessageType}. + * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}. + */ + public MessageType parseFrom(byte[] data) + throws InvalidProtocolBufferException; + + /** + * Parses {@code data} as a message of {@code MessageType}. + * This is just a small wrapper around + * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}. + */ + public MessageType parseFrom(byte[] data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(byte[], int, int)}, but does not throw an + * exception if the message is missing required fields. Instead, a partial + * message is returned. + */ + public MessageType parsePartialFrom(byte[] data, int off, int len) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(ByteString, ExtensionRegistryLite)}, + * but does not throw an exception if the message is missing required fields. + * Instead, a partial message is returned. + */ + public MessageType parsePartialFrom(byte[] data, int off, int len, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(byte[])}, but does not throw an + * exception if the message is missing required fields. Instead, a partial + * message is returned. + */ + public MessageType parsePartialFrom(byte[] data) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(byte[], ExtensionRegistryLite)}, + * but does not throw an exception if the message is missing required fields. + * Instead, a partial message is returned. + */ + public MessageType parsePartialFrom(byte[] data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Parse a message of {@code MessageType} from {@code input}. + * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}. + * Note that this method always reads the entire input (unless it + * throws an exception). If you want it to stop earlier, you will need to + * wrap your input in some wrapper stream that limits reading. Or, use + * {@link MessageLite#writeDelimitedTo(java.io.OutputStream)} to write your + * message and {@link #parseDelimitedFrom(InputStream)} to read it. + *

+ * Despite usually reading the entire input, this does not close the stream. + */ + public MessageType parseFrom(InputStream input) + throws InvalidProtocolBufferException; + + /** + * Parses a message of {@code MessageType} from {@code input}. + * This is just a small wrapper around + * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}. + */ + public MessageType parseFrom(InputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(InputStream)}, but does not throw an + * exception if the message is missing required fields. Instead, a partial + * message is returned. + */ + public MessageType parsePartialFrom(InputStream input) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(InputStream, ExtensionRegistryLite)}, + * but does not throw an exception if the message is missing required fields. + * Instead, a partial message is returned. + */ + public MessageType parsePartialFrom(InputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseFrom(InputStream)}, but does not read util EOF. + * Instead, the size of message (encoded as a varint) is read first, + * then the message data. Use + * {@link MessageLite#writeDelimitedTo(java.io.OutputStream)} to write + * messages in this format. + * + * @return True if successful, or false if the stream is at EOF when the + * method starts. Any other error (including reaching EOF during + * parsing) will cause an exception to be thrown. + */ + public MessageType parseDelimitedFrom(InputStream input) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseDelimitedFrom(InputStream)} but supporting extensions. + */ + public MessageType parseDelimitedFrom(InputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseDelimitedFrom(InputStream)}, but does not throw an + * exception if the message is missing required fields. Instead, a partial + * message is returned. + */ + public MessageType parsePartialDelimitedFrom(InputStream input) + throws InvalidProtocolBufferException; + + /** + * Like {@link #parseDelimitedFrom(InputStream, ExtensionRegistryLite)}, + * but does not throw an exception if the message is missing required fields. + * Instead, a partial message is returned. + */ + public MessageType parsePartialDelimitedFrom( + InputStream input, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java new file mode 100644 index 0000000..112400f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java @@ -0,0 +1,58 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.Descriptors.EnumDescriptor; +import com.google.protobuf.Descriptors.EnumValueDescriptor; + +/** + * Interface of useful methods added to all enums generated by the protocol + * compiler. + */ +public interface ProtocolMessageEnum extends Internal.EnumLite { + + /** + * Return the value's numeric value as defined in the .proto file. + */ + int getNumber(); + + /** + * Return the value's descriptor, which contains information such as + * value name, number, and type. + */ + EnumValueDescriptor getValueDescriptor(); + + /** + * Return the enum type's descriptor, which contains information + * about each defined value, etc. + */ + EnumDescriptor getDescriptorForType(); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java new file mode 100644 index 0000000..65d9270 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java @@ -0,0 +1,696 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * {@code RepeatedFieldBuilder} implements a structure that a protocol + * message uses to hold a repeated field of other protocol messages. It supports + * the classical use case of adding immutable {@link Message}'s to the + * repeated field and is highly optimized around this (no extra memory + * allocations and sharing of immutable arrays). + *
+ * It also supports the additional use case of adding a {@link Message.Builder} + * to the repeated field and deferring conversion of that {@code Builder} + * to an immutable {@code Message}. In this way, it's possible to maintain + * a tree of {@code Builder}'s that acts as a fully read/write data + * structure. + *
+ * Logically, one can think of a tree of builders as converting the entire tree + * to messages when build is called on the root or when any method is called + * that desires a Message instead of a Builder. In terms of the implementation, + * the {@code SingleFieldBuilder} and {@code RepeatedFieldBuilder} + * classes cache messages that were created so that messages only need to be + * created when some change occured in its builder or a builder for one of its + * descendants. + * + * @param the type of message for the field + * @param the type of builder for the field + * @param the common interface for the message and the builder + * + * @author jonp@google.com (Jon Perlow) + */ +public class RepeatedFieldBuilder + + implements GeneratedMessage.BuilderParent { + + // Parent to send changes to. + private GeneratedMessage.BuilderParent parent; + + // List of messages. Never null. It may be immutable, in which case + // isMessagesListImmutable will be true. See note below. + private List messages; + + // Whether messages is an mutable array that can be modified. + private boolean isMessagesListMutable; + + // List of builders. May be null, in which case, no nested builders were + // created. If not null, entries represent the builder for that index. + private List> builders; + + // Here are the invariants for messages and builders: + // 1. messages is never null and its count corresponds to the number of items + // in the repeated field. + // 2. If builders is non-null, messages and builders MUST always + // contain the same number of items. + // 3. Entries in either array can be null, but for any index, there MUST be + // either a Message in messages or a builder in builders. + // 4. If the builder at an index is non-null, the builder is + // authoritative. This is the case where a Builder was set on the index. + // Any message in the messages array MUST be ignored. + // t. If the builder at an index is null, the message in the messages + // list is authoritative. This is the case where a Message (not a Builder) + // was set directly for an index. + + // Indicates that we've built a message and so we are now obligated + // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener. + private boolean isClean; + + // A view of this builder that exposes a List interface of messages. This is + // initialized on demand. This is fully backed by this object and all changes + // are reflected in it. Access to any item converts it to a message if it + // was a builder. + private MessageExternalList externalMessageList; + + // A view of this builder that exposes a List interface of builders. This is + // initialized on demand. This is fully backed by this object and all changes + // are reflected in it. Access to any item converts it to a builder if it + // was a message. + private BuilderExternalList externalBuilderList; + + // A view of this builder that exposes a List interface of the interface + // implemented by messages and builders. This is initialized on demand. This + // is fully backed by this object and all changes are reflected in it. + // Access to any item returns either a builder or message depending on + // what is most efficient. + private MessageOrBuilderExternalList + externalMessageOrBuilderList; + + /** + * Constructs a new builder with an empty list of messages. + * + * @param messages the current list of messages + * @param isMessagesListMutable Whether the messages list is mutable + * @param parent a listener to notify of changes + * @param isClean whether the builder is initially marked clean + */ + public RepeatedFieldBuilder( + List messages, + boolean isMessagesListMutable, + GeneratedMessage.BuilderParent parent, + boolean isClean) { + this.messages = messages; + this.isMessagesListMutable = isMessagesListMutable; + this.parent = parent; + this.isClean = isClean; + } + + public void dispose() { + // Null out parent so we stop sending it invalidations. + parent = null; + } + + /** + * Ensures that the list of messages is mutable so it can be updated. If it's + * immutable, a copy is made. + */ + private void ensureMutableMessageList() { + if (!isMessagesListMutable) { + messages = new ArrayList(messages); + isMessagesListMutable = true; + } + } + + /** + * Ensures that the list of builders is not null. If it's null, the list is + * created and initialized to be the same size as the messages list with + * null entries. + */ + private void ensureBuilders() { + if (this.builders == null) { + this.builders = + new ArrayList>( + messages.size()); + for (int i = 0; i < messages.size(); i++) { + builders.add(null); + } + } + } + + /** + * Gets the count of items in the list. + * + * @return the count of items in the list. + */ + public int getCount() { + return messages.size(); + } + + /** + * Gets whether the list is empty. + * + * @return whether the list is empty + */ + public boolean isEmpty() { + return messages.isEmpty(); + } + + /** + * Get the message at the specified index. If the message is currently stored + * as a {@code Builder}, it is converted to a {@code Message} by + * calling {@link Message.Builder#buildPartial} on it. + * + * @param index the index of the message to get + * @return the message for the specified index + */ + public MType getMessage(int index) { + return getMessage(index, false); + } + + /** + * Get the message at the specified index. If the message is currently stored + * as a {@code Builder}, it is converted to a {@code Message} by + * calling {@link Message.Builder#buildPartial} on it. + * + * @param index the index of the message to get + * @param forBuild this is being called for build so we want to make sure + * we SingleFieldBuilder.build to send dirty invalidations + * @return the message for the specified index + */ + private MType getMessage(int index, boolean forBuild) { + if (this.builders == null) { + // We don't have any builders -- return the current Message. + // This is the case where no builder was created, so we MUST have a + // Message. + return messages.get(index); + } + + SingleFieldBuilder builder = builders.get(index); + if (builder == null) { + // We don't have a builder -- return the current message. + // This is the case where no builder was created for the entry at index, + // so we MUST have a message. + return messages.get(index); + + } else { + return forBuild ? builder.build() : builder.getMessage(); + } + } + + /** + * Gets a builder for the specified index. If no builder has been created for + * that index, a builder is created on demand by calling + * {@link Message#toBuilder}. + * + * @param index the index of the message to get + * @return The builder for that index + */ + public BType getBuilder(int index) { + ensureBuilders(); + SingleFieldBuilder builder = builders.get(index); + if (builder == null) { + MType message = messages.get(index); + builder = new SingleFieldBuilder( + message, this, isClean); + builders.set(index, builder); + } + return builder.getBuilder(); + } + + /** + * Gets the base class interface for the specified index. This may either be + * a builder or a message. It will return whatever is more efficient. + * + * @param index the index of the message to get + * @return the message or builder for the index as the base class interface + */ + @SuppressWarnings("unchecked") + public IType getMessageOrBuilder(int index) { + if (this.builders == null) { + // We don't have any builders -- return the current Message. + // This is the case where no builder was created, so we MUST have a + // Message. + return (IType) messages.get(index); + } + + SingleFieldBuilder builder = builders.get(index); + if (builder == null) { + // We don't have a builder -- return the current message. + // This is the case where no builder was created for the entry at index, + // so we MUST have a message. + return (IType) messages.get(index); + + } else { + return builder.getMessageOrBuilder(); + } + } + + /** + * Sets a message at the specified index replacing the existing item at + * that index. + * + * @param index the index to set. + * @param message the message to set + * @return the builder + */ + public RepeatedFieldBuilder setMessage( + int index, MType message) { + if (message == null) { + throw new NullPointerException(); + } + ensureMutableMessageList(); + messages.set(index, message); + if (builders != null) { + SingleFieldBuilder entry = + builders.set(index, null); + if (entry != null) { + entry.dispose(); + } + } + onChanged(); + incrementModCounts(); + return this; + } + + /** + * Appends the specified element to the end of this list. + * + * @param message the message to add + * @return the builder + */ + public RepeatedFieldBuilder addMessage( + MType message) { + if (message == null) { + throw new NullPointerException(); + } + ensureMutableMessageList(); + messages.add(message); + if (builders != null) { + builders.add(null); + } + onChanged(); + incrementModCounts(); + return this; + } + + /** + * Inserts the specified message at the specified position in this list. + * Shifts the element currently at that position (if any) and any subsequent + * elements to the right (adds one to their indices). + * + * @param index the index at which to insert the message + * @param message the message to add + * @return the builder + */ + public RepeatedFieldBuilder addMessage( + int index, MType message) { + if (message == null) { + throw new NullPointerException(); + } + ensureMutableMessageList(); + messages.add(index, message); + if (builders != null) { + builders.add(index, null); + } + onChanged(); + incrementModCounts(); + return this; + } + + /** + * Appends all of the messages in the specified collection to the end of + * this list, in the order that they are returned by the specified + * collection's iterator. + * + * @param values the messages to add + * @return the builder + */ + public RepeatedFieldBuilder addAllMessages( + Iterable values) { + for (final MType value : values) { + if (value == null) { + throw new NullPointerException(); + } + } + if (values instanceof Collection) { + @SuppressWarnings("unchecked") final + Collection collection = (Collection) values; + if (collection.size() == 0) { + return this; + } + ensureMutableMessageList(); + for (MType value : values) { + addMessage(value); + } + } else { + ensureMutableMessageList(); + for (MType value : values) { + addMessage(value); + } + } + onChanged(); + incrementModCounts(); + return this; + } + + /** + * Appends a new builder to the end of this list and returns the builder. + * + * @param message the message to add which is the basis of the builder + * @return the new builder + */ + public BType addBuilder(MType message) { + ensureMutableMessageList(); + ensureBuilders(); + SingleFieldBuilder builder = + new SingleFieldBuilder( + message, this, isClean); + messages.add(null); + builders.add(builder); + onChanged(); + incrementModCounts(); + return builder.getBuilder(); + } + + /** + * Inserts a new builder at the specified position in this list. + * Shifts the element currently at that position (if any) and any subsequent + * elements to the right (adds one to their indices). + * + * @param index the index at which to insert the builder + * @param message the message to add which is the basis of the builder + * @return the builder + */ + public BType addBuilder(int index, MType message) { + ensureMutableMessageList(); + ensureBuilders(); + SingleFieldBuilder builder = + new SingleFieldBuilder( + message, this, isClean); + messages.add(index, null); + builders.add(index, builder); + onChanged(); + incrementModCounts(); + return builder.getBuilder(); + } + + /** + * Removes the element at the specified position in this list. Shifts any + * subsequent elements to the left (subtracts one from their indices). + * Returns the element that was removed from the list. + * + * @param index the index at which to remove the message + */ + public void remove(int index) { + ensureMutableMessageList(); + messages.remove(index); + if (builders != null) { + SingleFieldBuilder entry = + builders.remove(index); + if (entry != null) { + entry.dispose(); + } + } + onChanged(); + incrementModCounts(); + } + + /** + * Removes all of the elements from this list. + * The list will be empty after this call returns. + */ + public void clear() { + messages = Collections.emptyList(); + isMessagesListMutable = false; + if (builders != null) { + for (SingleFieldBuilder entry : + builders) { + if (entry != null) { + entry.dispose(); + } + } + builders = null; + } + onChanged(); + incrementModCounts(); + } + + /** + * Builds the list of messages from the builder and returns them. + * + * @return an immutable list of messages + */ + public List build() { + // Now that build has been called, we are required to dispatch + // invalidations. + isClean = true; + + if (!isMessagesListMutable && builders == null) { + // We still have an immutable list and we never created a builder. + return messages; + } + + boolean allMessagesInSync = true; + if (!isMessagesListMutable) { + // We still have an immutable list. Let's see if any of them are out + // of sync with their builders. + for (int i = 0; i < messages.size(); i++) { + Message message = messages.get(i); + SingleFieldBuilder builder = builders.get(i); + if (builder != null) { + if (builder.build() != message) { + allMessagesInSync = false; + break; + } + } + } + if (allMessagesInSync) { + // Immutable list is still in sync. + return messages; + } + } + + // Need to make sure messages is up to date + ensureMutableMessageList(); + for (int i = 0; i < messages.size(); i++) { + messages.set(i, getMessage(i, true)); + } + + // We're going to return our list as immutable so we mark that we can + // no longer update it. + messages = Collections.unmodifiableList(messages); + isMessagesListMutable = false; + return messages; + } + + /** + * Gets a view of the builder as a list of messages. The returned list is live + * and will reflect any changes to the underlying builder. + * + * @return the messages in the list + */ + public List getMessageList() { + if (externalMessageList == null) { + externalMessageList = + new MessageExternalList(this); + } + return externalMessageList; + } + + /** + * Gets a view of the builder as a list of builders. This returned list is + * live and will reflect any changes to the underlying builder. + * + * @return the builders in the list + */ + public List getBuilderList() { + if (externalBuilderList == null) { + externalBuilderList = + new BuilderExternalList(this); + } + return externalBuilderList; + } + + /** + * Gets a view of the builder as a list of MessageOrBuilders. This returned + * list is live and will reflect any changes to the underlying builder. + * + * @return the builders in the list + */ + public List getMessageOrBuilderList() { + if (externalMessageOrBuilderList == null) { + externalMessageOrBuilderList = + new MessageOrBuilderExternalList(this); + } + return externalMessageOrBuilderList; + } + + /** + * Called when a the builder or one of its nested children has changed + * and any parent should be notified of its invalidation. + */ + private void onChanged() { + if (isClean && parent != null) { + parent.markDirty(); + + // Don't keep dispatching invalidations until build is called again. + isClean = false; + } + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void markDirty() { + onChanged(); + } + + /** + * Increments the mod counts so that an ConcurrentModificationException can + * be thrown if calling code tries to modify the builder while its iterating + * the list. + */ + private void incrementModCounts() { + if (externalMessageList != null) { + externalMessageList.incrementModCount(); + } + if (externalBuilderList != null) { + externalBuilderList.incrementModCount(); + } + if (externalMessageOrBuilderList != null) { + externalMessageOrBuilderList.incrementModCount(); + } + } + + /** + * Provides a live view of the builder as a list of messages. + * + * @param the type of message for the field + * @param the type of builder for the field + * @param the common interface for the message and the builder + */ + private static class MessageExternalList< + MType extends GeneratedMessage, + BType extends GeneratedMessage.Builder, + IType extends MessageOrBuilder> + extends AbstractList implements List { + + RepeatedFieldBuilder builder; + + MessageExternalList( + RepeatedFieldBuilder builder) { + this.builder = builder; + } + + public int size() { + return this.builder.getCount(); + } + + public MType get(int index) { + return builder.getMessage(index); + } + + void incrementModCount() { + modCount++; + } + } + + /** + * Provides a live view of the builder as a list of builders. + * + * @param the type of message for the field + * @param the type of builder for the field + * @param the common interface for the message and the builder + */ + private static class BuilderExternalList< + MType extends GeneratedMessage, + BType extends GeneratedMessage.Builder, + IType extends MessageOrBuilder> + extends AbstractList implements List { + + RepeatedFieldBuilder builder; + + BuilderExternalList( + RepeatedFieldBuilder builder) { + this.builder = builder; + } + + public int size() { + return this.builder.getCount(); + } + + public BType get(int index) { + return builder.getBuilder(index); + } + + void incrementModCount() { + modCount++; + } + } + + /** + * Provides a live view of the builder as a list of builders. + * + * @param the type of message for the field + * @param the type of builder for the field + * @param the common interface for the message and the builder + */ + private static class MessageOrBuilderExternalList< + MType extends GeneratedMessage, + BType extends GeneratedMessage.Builder, + IType extends MessageOrBuilder> + extends AbstractList implements List { + + RepeatedFieldBuilder builder; + + MessageOrBuilderExternalList( + RepeatedFieldBuilder builder) { + this.builder = builder; + } + + public int size() { + return this.builder.getCount(); + } + + public IType get(int index) { + return builder.getMessageOrBuilder(index); + } + + void incrementModCount() { + modCount++; + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RopeByteString.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RopeByteString.java new file mode 100644 index 0000000..4699782 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RopeByteString.java @@ -0,0 +1,943 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.io.ByteArrayInputStream; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Stack; + +/** + * Class to represent {@code ByteStrings} formed by concatenation of other + * ByteStrings, without copying the data in the pieces. The concatenation is + * represented as a tree whose leaf nodes are each a {@link LiteralByteString}. + * + *

Most of the operation here is inspired by the now-famous paper + * BAP95 Ropes: an Alternative to Strings hans-j. boehm, russ atkinson and + * michael plass + * + *

The algorithms described in the paper have been implemented for character + * strings in {@link com.google.common.string.Rope} and in the c++ class {@code + * cord.cc}. + * + *

Fundamentally the Rope algorithm represents the collection of pieces as a + * binary tree. BAP95 uses a Fibonacci bound relating depth to a minimum + * sequence length, sequences that are too short relative to their depth cause a + * tree rebalance. More precisely, a tree of depth d is "balanced" in the + * terminology of BAP95 if its length is at least F(d+2), where F(n) is the + * n-the Fibonacci number. Thus for depths 0, 1, 2, 3, 4, 5,... we have minimum + * lengths 1, 2, 3, 5, 8, 13,... + * + * @author carlanton@google.com (Carl Haverl) + */ +class RopeByteString extends ByteString { + + /** + * BAP95. Let Fn be the nth Fibonacci number. A {@link RopeByteString} of + * depth n is "balanced", i.e flat enough, if its length is at least Fn+2, + * e.g. a "balanced" {@link RopeByteString} of depth 1 must have length at + * least 2, of depth 4 must have length >= 8, etc. + * + *

There's nothing special about using the Fibonacci numbers for this, but + * they are a reasonable sequence for encapsulating the idea that we are OK + * with longer strings being encoded in deeper binary trees. + * + *

For 32-bit integers, this array has length 46. + */ + private static final int[] minLengthByDepth; + + static { + // Dynamically generate the list of Fibonacci numbers the first time this + // class is accessed. + List numbers = new ArrayList(); + + // we skip the first Fibonacci number (1). So instead of: 1 1 2 3 5 8 ... + // we have: 1 2 3 5 8 ... + int f1 = 1; + int f2 = 1; + + // get all the values until we roll over. + while (f2 > 0) { + numbers.add(f2); + int temp = f1 + f2; + f1 = f2; + f2 = temp; + } + + // we include this here so that we can index this array to [x + 1] in the + // loops below. + numbers.add(Integer.MAX_VALUE); + minLengthByDepth = new int[numbers.size()]; + for (int i = 0; i < minLengthByDepth.length; i++) { + // unbox all the values + minLengthByDepth[i] = numbers.get(i); + } + } + + private final int totalLength; + private final ByteString left; + private final ByteString right; + private final int leftLength; + private final int treeDepth; + + /** + * Create a new RopeByteString, which can be thought of as a new tree node, by + * recording references to the two given strings. + * + * @param left string on the left of this node, should have {@code size() > + * 0} + * @param right string on the right of this node, should have {@code size() > + * 0} + */ + private RopeByteString(ByteString left, ByteString right) { + this.left = left; + this.right = right; + leftLength = left.size(); + totalLength = leftLength + right.size(); + treeDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1; + } + + /** + * Concatenate the given strings while performing various optimizations to + * slow the growth rate of tree depth and tree node count. The result is + * either a {@link LiteralByteString} or a {@link RopeByteString} + * depending on which optimizations, if any, were applied. + * + *

Small pieces of length less than {@link + * ByteString#CONCATENATE_BY_COPY_SIZE} may be copied by value here, as in + * BAP95. Large pieces are referenced without copy. + * + * @param left string on the left + * @param right string on the right + * @return concatenation representing the same sequence as the given strings + */ + static ByteString concatenate(ByteString left, ByteString right) { + ByteString result; + RopeByteString leftRope = + (left instanceof RopeByteString) ? (RopeByteString) left : null; + if (right.size() == 0) { + result = left; + } else if (left.size() == 0) { + result = right; + } else { + int newLength = left.size() + right.size(); + if (newLength < ByteString.CONCATENATE_BY_COPY_SIZE) { + // Optimization from BAP95: For short (leaves in paper, but just short + // here) total length, do a copy of data to a new leaf. + result = concatenateBytes(left, right); + } else if (leftRope != null + && leftRope.right.size() + right.size() < CONCATENATE_BY_COPY_SIZE) { + // Optimization from BAP95: As an optimization of the case where the + // ByteString is constructed by repeated concatenate, recognize the case + // where a short string is concatenated to a left-hand node whose + // right-hand branch is short. In the paper this applies to leaves, but + // we just look at the length here. This has the advantage of shedding + // references to unneeded data when substrings have been taken. + // + // When we recognize this case, we do a copy of the data and create a + // new parent node so that the depth of the result is the same as the + // given left tree. + ByteString newRight = concatenateBytes(leftRope.right, right); + result = new RopeByteString(leftRope.left, newRight); + } else if (leftRope != null + && leftRope.left.getTreeDepth() > leftRope.right.getTreeDepth() + && leftRope.getTreeDepth() > right.getTreeDepth()) { + // Typically for concatenate-built strings the left-side is deeper than + // the right. This is our final attempt to concatenate without + // increasing the tree depth. We'll redo the the node on the RHS. This + // is yet another optimization for building the string by repeatedly + // concatenating on the right. + ByteString newRight = new RopeByteString(leftRope.right, right); + result = new RopeByteString(leftRope.left, newRight); + } else { + // Fine, we'll add a node and increase the tree depth--unless we + // rebalance ;^) + int newDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1; + if (newLength >= minLengthByDepth[newDepth]) { + // The tree is shallow enough, so don't rebalance + result = new RopeByteString(left, right); + } else { + result = new Balancer().balance(left, right); + } + } + } + return result; + } + + /** + * Concatenates two strings by copying data values. This is called in a few + * cases in order to reduce the growth of the number of tree nodes. + * + * @param left string on the left + * @param right string on the right + * @return string formed by copying data bytes + */ + private static LiteralByteString concatenateBytes(ByteString left, + ByteString right) { + int leftSize = left.size(); + int rightSize = right.size(); + byte[] bytes = new byte[leftSize + rightSize]; + left.copyTo(bytes, 0, 0, leftSize); + right.copyTo(bytes, 0, leftSize, rightSize); + return new LiteralByteString(bytes); // Constructor wraps bytes + } + + /** + * Create a new RopeByteString for testing only while bypassing all the + * defenses of {@link #concatenate(ByteString, ByteString)}. This allows + * testing trees of specific structure. We are also able to insert empty + * leaves, though these are dis-allowed, so that we can make sure the + * implementation can withstand their presence. + * + * @param left string on the left of this node + * @param right string on the right of this node + * @return an unsafe instance for testing only + */ + static RopeByteString newInstanceForTest(ByteString left, ByteString right) { + return new RopeByteString(left, right); + } + + /** + * Gets the byte at the given index. + * Throws {@link ArrayIndexOutOfBoundsException} for backwards-compatibility + * reasons although it would more properly be {@link + * IndexOutOfBoundsException}. + * + * @param index index of byte + * @return the value + * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size + */ + @Override + public byte byteAt(int index) { + if (index < 0) { + throw new ArrayIndexOutOfBoundsException("Index < 0: " + index); + } + if (index > totalLength) { + throw new ArrayIndexOutOfBoundsException( + "Index > length: " + index + ", " + totalLength); + } + + byte result; + // Find the relevant piece by recursive descent + if (index < leftLength) { + result = left.byteAt(index); + } else { + result = right.byteAt(index - leftLength); + } + return result; + } + + @Override + public int size() { + return totalLength; + } + + // ================================================================= + // Pieces + + @Override + protected int getTreeDepth() { + return treeDepth; + } + + /** + * Determines if the tree is balanced according to BAP95, which means the tree + * is flat-enough with respect to the bounds. Note that this definition of + * balanced is one where sub-trees of balanced trees are not necessarily + * balanced. + * + * @return true if the tree is balanced + */ + @Override + protected boolean isBalanced() { + return totalLength >= minLengthByDepth[treeDepth]; + } + + /** + * Takes a substring of this one. This involves recursive descent along the + * left and right edges of the substring, and referencing any wholly contained + * segments in between. Any leaf nodes entirely uninvolved in the substring + * will not be referenced by the substring. + * + *

Substrings of {@code length < 2} should result in at most a single + * recursive call chain, terminating at a leaf node. Thus the result will be a + * {@link LiteralByteString}. {@link #RopeByteString(ByteString, + * ByteString)}. + * + * @param beginIndex start at this index + * @param endIndex the last character is the one before this index + * @return substring leaf node or tree + */ + @Override + public ByteString substring(int beginIndex, int endIndex) { + if (beginIndex < 0) { + throw new IndexOutOfBoundsException( + "Beginning index: " + beginIndex + " < 0"); + } + if (endIndex > totalLength) { + throw new IndexOutOfBoundsException( + "End index: " + endIndex + " > " + totalLength); + } + int substringLength = endIndex - beginIndex; + if (substringLength < 0) { + throw new IndexOutOfBoundsException( + "Beginning index larger than ending index: " + beginIndex + ", " + + endIndex); + } + + ByteString result; + if (substringLength == 0) { + // Empty substring + result = ByteString.EMPTY; + } else if (substringLength == totalLength) { + // The whole string + result = this; + } else { + // Proper substring + if (endIndex <= leftLength) { + // Substring on the left + result = left.substring(beginIndex, endIndex); + } else if (beginIndex >= leftLength) { + // Substring on the right + result = right + .substring(beginIndex - leftLength, endIndex - leftLength); + } else { + // Split substring + ByteString leftSub = left.substring(beginIndex); + ByteString rightSub = right.substring(0, endIndex - leftLength); + // Intentionally not rebalancing, since in many cases these two + // substrings will already be less deep than the top-level + // RopeByteString we're taking a substring of. + result = new RopeByteString(leftSub, rightSub); + } + } + return result; + } + + // ================================================================= + // ByteString -> byte[] + + @Override + protected void copyToInternal(byte[] target, int sourceOffset, + int targetOffset, int numberToCopy) { + if (sourceOffset + numberToCopy <= leftLength) { + left.copyToInternal(target, sourceOffset, targetOffset, numberToCopy); + } else if (sourceOffset >= leftLength) { + right.copyToInternal(target, sourceOffset - leftLength, targetOffset, + numberToCopy); + } else { + int leftLength = this.leftLength - sourceOffset; + left.copyToInternal(target, sourceOffset, targetOffset, leftLength); + right.copyToInternal(target, 0, targetOffset + leftLength, + numberToCopy - leftLength); + } + } + + @Override + public void copyTo(ByteBuffer target) { + left.copyTo(target); + right.copyTo(target); + } + + @Override + public ByteBuffer asReadOnlyByteBuffer() { + ByteBuffer byteBuffer = ByteBuffer.wrap(toByteArray()); + return byteBuffer.asReadOnlyBuffer(); + } + + @Override + public List asReadOnlyByteBufferList() { + // Walk through the list of LiteralByteString's that make up this + // rope, and add each one as a read-only ByteBuffer. + List result = new ArrayList(); + PieceIterator pieces = new PieceIterator(this); + while (pieces.hasNext()) { + LiteralByteString byteString = pieces.next(); + result.add(byteString.asReadOnlyByteBuffer()); + } + return result; + } + + @Override + public void writeTo(OutputStream outputStream) throws IOException { + left.writeTo(outputStream); + right.writeTo(outputStream); + } + + @Override + public String toString(String charsetName) + throws UnsupportedEncodingException { + return new String(toByteArray(), charsetName); + } + + // ================================================================= + // UTF-8 decoding + + @Override + public boolean isValidUtf8() { + int leftPartial = left.partialIsValidUtf8(Utf8.COMPLETE, 0, leftLength); + int state = right.partialIsValidUtf8(leftPartial, 0, right.size()); + return state == Utf8.COMPLETE; + } + + @Override + protected int partialIsValidUtf8(int state, int offset, int length) { + int toIndex = offset + length; + if (toIndex <= leftLength) { + return left.partialIsValidUtf8(state, offset, length); + } else if (offset >= leftLength) { + return right.partialIsValidUtf8(state, offset - leftLength, length); + } else { + int leftLength = this.leftLength - offset; + int leftPartial = left.partialIsValidUtf8(state, offset, leftLength); + return right.partialIsValidUtf8(leftPartial, 0, length - leftLength); + } + } + + // ================================================================= + // equals() and hashCode() + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if (!(other instanceof ByteString)) { + return false; + } + + ByteString otherByteString = (ByteString) other; + if (totalLength != otherByteString.size()) { + return false; + } + if (totalLength == 0) { + return true; + } + + // You don't really want to be calling equals on long strings, but since + // we cache the hashCode, we effectively cache inequality. We use the cached + // hashCode if it's already computed. It's arguable we should compute the + // hashCode here, and if we're going to be testing a bunch of byteStrings, + // it might even make sense. + if (hash != 0) { + int cachedOtherHash = otherByteString.peekCachedHashCode(); + if (cachedOtherHash != 0 && hash != cachedOtherHash) { + return false; + } + } + + return equalsFragments(otherByteString); + } + + /** + * Determines if this string is equal to another of the same length by + * iterating over the leaf nodes. On each step of the iteration, the + * overlapping segments of the leaves are compared. + * + * @param other string of the same length as this one + * @return true if the values of this string equals the value of the given + * one + */ + private boolean equalsFragments(ByteString other) { + int thisOffset = 0; + Iterator thisIter = new PieceIterator(this); + LiteralByteString thisString = thisIter.next(); + + int thatOffset = 0; + Iterator thatIter = new PieceIterator(other); + LiteralByteString thatString = thatIter.next(); + + int pos = 0; + while (true) { + int thisRemaining = thisString.size() - thisOffset; + int thatRemaining = thatString.size() - thatOffset; + int bytesToCompare = Math.min(thisRemaining, thatRemaining); + + // At least one of the offsets will be zero + boolean stillEqual = (thisOffset == 0) + ? thisString.equalsRange(thatString, thatOffset, bytesToCompare) + : thatString.equalsRange(thisString, thisOffset, bytesToCompare); + if (!stillEqual) { + return false; + } + + pos += bytesToCompare; + if (pos >= totalLength) { + if (pos == totalLength) { + return true; + } + throw new IllegalStateException(); + } + // We always get to the end of at least one of the pieces + if (bytesToCompare == thisRemaining) { // If reached end of this + thisOffset = 0; + thisString = thisIter.next(); + } else { + thisOffset += bytesToCompare; + } + if (bytesToCompare == thatRemaining) { // If reached end of that + thatOffset = 0; + thatString = thatIter.next(); + } else { + thatOffset += bytesToCompare; + } + } + } + + /** + * Cached hash value. Intentionally accessed via a data race, which is safe + * because of the Java Memory Model's "no out-of-thin-air values" guarantees + * for ints. + */ + private int hash = 0; + + @Override + public int hashCode() { + int h = hash; + + if (h == 0) { + h = totalLength; + h = partialHash(h, 0, totalLength); + if (h == 0) { + h = 1; + } + hash = h; + } + return h; + } + + @Override + protected int peekCachedHashCode() { + return hash; + } + + @Override + protected int partialHash(int h, int offset, int length) { + int toIndex = offset + length; + if (toIndex <= leftLength) { + return left.partialHash(h, offset, length); + } else if (offset >= leftLength) { + return right.partialHash(h, offset - leftLength, length); + } else { + int leftLength = this.leftLength - offset; + int leftPartial = left.partialHash(h, offset, leftLength); + return right.partialHash(leftPartial, 0, length - leftLength); + } + } + + // ================================================================= + // Input stream + + @Override + public CodedInputStream newCodedInput() { + return CodedInputStream.newInstance(new RopeInputStream()); + } + + @Override + public InputStream newInput() { + return new RopeInputStream(); + } + + /** + * This class implements the balancing algorithm of BAP95. In the paper the + * authors use an array to keep track of pieces, while here we use a stack. + * The tree is balanced by traversing subtrees in left to right order, and the + * stack always contains the part of the string we've traversed so far. + * + *

One surprising aspect of the algorithm is the result of balancing is not + * necessarily balanced, though it is nearly balanced. For details, see + * BAP95. + */ + private static class Balancer { + // Stack containing the part of the string, starting from the left, that + // we've already traversed. The final string should be the equivalent of + // concatenating the strings on the stack from bottom to top. + private final Stack prefixesStack = new Stack(); + + private ByteString balance(ByteString left, ByteString right) { + doBalance(left); + doBalance(right); + + // Sweep stack to gather the result + ByteString partialString = prefixesStack.pop(); + while (!prefixesStack.isEmpty()) { + ByteString newLeft = prefixesStack.pop(); + partialString = new RopeByteString(newLeft, partialString); + } + // We should end up with a RopeByteString since at a minimum we will + // create one from concatenating left and right + return partialString; + } + + private void doBalance(ByteString root) { + // BAP95: Insert balanced subtrees whole. This means the result might not + // be balanced, leading to repeated rebalancings on concatenate. However, + // these rebalancings are shallow due to ignoring balanced subtrees, and + // relatively few calls to insert() result. + if (root.isBalanced()) { + insert(root); + } else if (root instanceof RopeByteString) { + RopeByteString rbs = (RopeByteString) root; + doBalance(rbs.left); + doBalance(rbs.right); + } else { + throw new IllegalArgumentException( + "Has a new type of ByteString been created? Found " + + root.getClass()); + } + } + + /** + * Push a string on the balance stack (BAP95). BAP95 uses an array and + * calls the elements in the array 'bins'. We instead use a stack, so the + * 'bins' of lengths are represented by differences between the elements of + * minLengthByDepth. + * + *

If the length bin for our string, and all shorter length bins, are + * empty, we just push it on the stack. Otherwise, we need to start + * concatenating, putting the given string in the "middle" and continuing + * until we land in an empty length bin that matches the length of our + * concatenation. + * + * @param byteString string to place on the balance stack + */ + private void insert(ByteString byteString) { + int depthBin = getDepthBinForLength(byteString.size()); + int binEnd = minLengthByDepth[depthBin + 1]; + + // BAP95: Concatenate all trees occupying bins representing the length of + // our new piece or of shorter pieces, to the extent that is possible. + // The goal is to clear the bin which our piece belongs in, but that may + // not be entirely possible if there aren't enough longer bins occupied. + if (prefixesStack.isEmpty() || prefixesStack.peek().size() >= binEnd) { + prefixesStack.push(byteString); + } else { + int binStart = minLengthByDepth[depthBin]; + + // Concatenate the subtrees of shorter length + ByteString newTree = prefixesStack.pop(); + while (!prefixesStack.isEmpty() + && prefixesStack.peek().size() < binStart) { + ByteString left = prefixesStack.pop(); + newTree = new RopeByteString(left, newTree); + } + + // Concatenate the given string + newTree = new RopeByteString(newTree, byteString); + + // Continue concatenating until we land in an empty bin + while (!prefixesStack.isEmpty()) { + depthBin = getDepthBinForLength(newTree.size()); + binEnd = minLengthByDepth[depthBin + 1]; + if (prefixesStack.peek().size() < binEnd) { + ByteString left = prefixesStack.pop(); + newTree = new RopeByteString(left, newTree); + } else { + break; + } + } + prefixesStack.push(newTree); + } + } + + private int getDepthBinForLength(int length) { + int depth = Arrays.binarySearch(minLengthByDepth, length); + if (depth < 0) { + // It wasn't an exact match, so convert to the index of the containing + // fragment, which is one less even than the insertion point. + int insertionPoint = -(depth + 1); + depth = insertionPoint - 1; + } + + return depth; + } + } + + /** + * This class is a continuable tree traversal, which keeps the state + * information which would exist on the stack in a recursive traversal instead + * on a stack of "Bread Crumbs". The maximum depth of the stack in this + * iterator is the same as the depth of the tree being traversed. + * + *

This iterator is used to implement + * {@link RopeByteString#equalsFragments(ByteString)}. + */ + private static class PieceIterator implements Iterator { + + private final Stack breadCrumbs = + new Stack(); + private LiteralByteString next; + + private PieceIterator(ByteString root) { + next = getLeafByLeft(root); + } + + private LiteralByteString getLeafByLeft(ByteString root) { + ByteString pos = root; + while (pos instanceof RopeByteString) { + RopeByteString rbs = (RopeByteString) pos; + breadCrumbs.push(rbs); + pos = rbs.left; + } + return (LiteralByteString) pos; + } + + private LiteralByteString getNextNonEmptyLeaf() { + while (true) { + // Almost always, we go through this loop exactly once. However, if + // we discover an empty string in the rope, we toss it and try again. + if (breadCrumbs.isEmpty()) { + return null; + } else { + LiteralByteString result = getLeafByLeft(breadCrumbs.pop().right); + if (!result.isEmpty()) { + return result; + } + } + } + } + + public boolean hasNext() { + return next != null; + } + + /** + * Returns the next item and advances one {@code LiteralByteString}. + * + * @return next non-empty LiteralByteString or {@code null} + */ + public LiteralByteString next() { + if (next == null) { + throw new NoSuchElementException(); + } + LiteralByteString result = next; + next = getNextNonEmptyLeaf(); + return result; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + + // ================================================================= + // ByteIterator + + @Override + public ByteIterator iterator() { + return new RopeByteIterator(); + } + + private class RopeByteIterator implements ByteString.ByteIterator { + + private final PieceIterator pieces; + private ByteIterator bytes; + int bytesRemaining; + + private RopeByteIterator() { + pieces = new PieceIterator(RopeByteString.this); + bytes = pieces.next().iterator(); + bytesRemaining = size(); + } + + public boolean hasNext() { + return (bytesRemaining > 0); + } + + public Byte next() { + return nextByte(); // Does not instantiate a Byte + } + + public byte nextByte() { + if (!bytes.hasNext()) { + bytes = pieces.next().iterator(); + } + --bytesRemaining; + return bytes.nextByte(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + + /** + * This class is the {@link RopeByteString} equivalent for + * {@link ByteArrayInputStream}. + */ + private class RopeInputStream extends InputStream { + // Iterates through the pieces of the rope + private PieceIterator pieceIterator; + // The current piece + private LiteralByteString currentPiece; + // The size of the current piece + private int currentPieceSize; + // The index of the next byte to read in the current piece + private int currentPieceIndex; + // The offset of the start of the current piece in the rope byte string + private int currentPieceOffsetInRope; + // Offset in the buffer at which user called mark(); + private int mark; + + public RopeInputStream() { + initialize(); + } + + @Override + public int read(byte b[], int offset, int length) { + if (b == null) { + throw new NullPointerException(); + } else if (offset < 0 || length < 0 || length > b.length - offset) { + throw new IndexOutOfBoundsException(); + } + return readSkipInternal(b, offset, length); + } + + @Override + public long skip(long length) { + if (length < 0) { + throw new IndexOutOfBoundsException(); + } else if (length > Integer.MAX_VALUE) { + length = Integer.MAX_VALUE; + } + return readSkipInternal(null, 0, (int) length); + } + + /** + * Internal implementation of read and skip. If b != null, then read the + * next {@code length} bytes into the buffer {@code b} at + * offset {@code offset}. If b == null, then skip the next {@code length) + * bytes. + *

+ * This method assumes that all error checking has already happened. + *

+ * Returns the actual number of bytes read or skipped. + */ + private int readSkipInternal(byte b[], int offset, int length) { + int bytesRemaining = length; + while (bytesRemaining > 0) { + advanceIfCurrentPieceFullyRead(); + if (currentPiece == null) { + if (bytesRemaining == length) { + // We didn't manage to read anything + return -1; + } + break; + } else { + // Copy the bytes from this piece. + int currentPieceRemaining = currentPieceSize - currentPieceIndex; + int count = Math.min(currentPieceRemaining, bytesRemaining); + if (b != null) { + currentPiece.copyTo(b, currentPieceIndex, offset, count); + offset += count; + } + currentPieceIndex += count; + bytesRemaining -= count; + } + } + // Return the number of bytes read. + return length - bytesRemaining; + } + + @Override + public int read() throws IOException { + advanceIfCurrentPieceFullyRead(); + if (currentPiece == null) { + return -1; + } else { + return currentPiece.byteAt(currentPieceIndex++) & 0xFF; + } + } + + @Override + public int available() throws IOException { + int bytesRead = currentPieceOffsetInRope + currentPieceIndex; + return RopeByteString.this.size() - bytesRead; + } + + @Override + public boolean markSupported() { + return true; + } + + @Override + public void mark(int readAheadLimit) { + // Set the mark to our position in the byte string + mark = currentPieceOffsetInRope + currentPieceIndex; + } + + @Override + public synchronized void reset() { + // Just reinitialize and skip the specified number of bytes. + initialize(); + readSkipInternal(null, 0, mark); + } + + /** Common initialization code used by both the constructor and reset() */ + private void initialize() { + pieceIterator = new PieceIterator(RopeByteString.this); + currentPiece = pieceIterator.next(); + currentPieceSize = currentPiece.size(); + currentPieceIndex = 0; + currentPieceOffsetInRope = 0; + } + + /** + * Skips to the next piece if we have read all the data in the current + * piece. Sets currentPiece to null if we have reached the end of the + * input. + */ + private void advanceIfCurrentPieceFullyRead() { + if (currentPiece != null && currentPieceIndex == currentPieceSize) { + // Generally, we can only go through this loop at most once, since + // empty strings can't end up in a rope. But better to test. + currentPieceOffsetInRope += currentPieceSize; + currentPieceIndex = 0; + if (pieceIterator.hasNext()) { + currentPiece = pieceIterator.next(); + currentPieceSize = currentPiece.size(); + } else { + currentPiece = null; + currentPieceSize = 0; + } + } + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcCallback.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcCallback.java new file mode 100644 index 0000000..1fd35ed --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcCallback.java @@ -0,0 +1,47 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + * Interface for an RPC callback, normally called when an RPC completes. + * {@code ParameterType} is normally the method's response message type. + * + *

Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * + * @author kenton@google.com Kenton Varda + */ +public interface RpcCallback { + void run(ParameterType parameter); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcChannel.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcChannel.java new file mode 100644 index 0000000..c6ec54f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcChannel.java @@ -0,0 +1,71 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + *

Abstract interface for an RPC channel. An {@code RpcChannel} represents a + * communication line to a {@link Service} which can be used to call that + * {@link Service}'s methods. The {@link Service} may be running on another + * machine. Normally, you should not call an {@code RpcChannel} directly, but + * instead construct a stub {@link Service} wrapping it. Example: + * + *

+ *   RpcChannel channel = rpcImpl.newChannel("remotehost.example.com:1234");
+ *   RpcController controller = rpcImpl.newController();
+ *   MyService service = MyService.newStub(channel);
+ *   service.myMethod(controller, request, callback);
+ * 
+ * + *

Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * + * @author kenton@google.com Kenton Varda + */ +public interface RpcChannel { + /** + * Call the given method of the remote service. This method is similar to + * {@code Service.callMethod()} with one important difference: the caller + * decides the types of the {@code Message} objects, not the callee. The + * request may be of any type as long as + * {@code request.getDescriptor() == method.getInputType()}. + * The response passed to the callback will be of the same type as + * {@code responsePrototype} (which must have + * {@code getDescriptor() == method.getOutputType()}). + */ + void callMethod(Descriptors.MethodDescriptor method, + RpcController controller, + Message request, + Message responsePrototype, + RpcCallback done); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcController.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcController.java new file mode 100644 index 0000000..aaa5446 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcController.java @@ -0,0 +1,118 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + *

An {@code RpcController} mediates a single method call. The primary + * purpose of the controller is to provide a way to manipulate settings + * specific to the RPC implementation and to find out about RPC-level errors. + * + *

Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * + *

The methods provided by the {@code RpcController} interface are intended + * to be a "least common denominator" set of features which we expect all + * implementations to support. Specific implementations may provide more + * advanced features (e.g. deadline propagation). + * + * @author kenton@google.com Kenton Varda + */ +public interface RpcController { + // ----------------------------------------------------------------- + // These calls may be made from the client side only. Their results + // are undefined on the server side (may throw RuntimeExceptions). + + /** + * Resets the RpcController to its initial state so that it may be reused in + * a new call. This can be called from the client side only. It must not + * be called while an RPC is in progress. + */ + void reset(); + + /** + * After a call has finished, returns true if the call failed. The possible + * reasons for failure depend on the RPC implementation. {@code failed()} + * most only be called on the client side, and must not be called before a + * call has finished. + */ + boolean failed(); + + /** + * If {@code failed()} is {@code true}, returns a human-readable description + * of the error. + */ + String errorText(); + + /** + * Advises the RPC system that the caller desires that the RPC call be + * canceled. The RPC system may cancel it immediately, may wait awhile and + * then cancel it, or may not even cancel the call at all. If the call is + * canceled, the "done" callback will still be called and the RpcController + * will indicate that the call failed at that time. + */ + void startCancel(); + + // ----------------------------------------------------------------- + // These calls may be made from the server side only. Their results + // are undefined on the client side (may throw RuntimeExceptions). + + /** + * Causes {@code failed()} to return true on the client side. {@code reason} + * will be incorporated into the message returned by {@code errorText()}. + * If you find you need to return machine-readable information about + * failures, you should incorporate it into your response protocol buffer + * and should NOT call {@code setFailed()}. + */ + void setFailed(String reason); + + /** + * If {@code true}, indicates that the client canceled the RPC, so the server + * may as well give up on replying to it. This method must be called on the + * server side only. The server should still call the final "done" callback. + */ + boolean isCanceled(); + + /** + * Asks that the given callback be called when the RPC is canceled. The + * parameter passed to the callback will always be {@code null}. The + * callback will always be called exactly once. If the RPC completes without + * being canceled, the callback will be called after completion. If the RPC + * has already been canceled when NotifyOnCancel() is called, the callback + * will be called immediately. + * + *

{@code notifyOnCancel()} must be called no more than once per request. + * It must be called on the server side only. + */ + void notifyOnCancel(RpcCallback callback); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcUtil.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcUtil.java new file mode 100644 index 0000000..b1b959a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/RpcUtil.java @@ -0,0 +1,135 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + * Grab-bag of utility functions useful when dealing with RPCs. + * + * @author kenton@google.com Kenton Varda + */ +public final class RpcUtil { + private RpcUtil() {} + + /** + * Take an {@code RpcCallback} and convert it to an + * {@code RpcCallback} accepting a specific message type. This is always + * type-safe (parameter type contravariance). + */ + @SuppressWarnings("unchecked") + public static RpcCallback + specializeCallback(final RpcCallback originalCallback) { + return (RpcCallback)originalCallback; + // The above cast works, but only due to technical details of the Java + // implementation. A more theoretically correct -- but less efficient -- + // implementation would be as follows: + // return new RpcCallback() { + // public void run(Type parameter) { + // originalCallback.run(parameter); + // } + // }; + } + + /** + * Take an {@code RpcCallback} accepting a specific message type and convert + * it to an {@code RpcCallback}. The generalized callback will + * accept any message object which has the same descriptor, and will convert + * it to the correct class before calling the original callback. However, + * if the generalized callback is given a message with a different descriptor, + * an exception will be thrown. + */ + public static + RpcCallback generalizeCallback( + final RpcCallback originalCallback, + final Class originalClass, + final Type defaultInstance) { + return new RpcCallback() { + public void run(final Message parameter) { + Type typedParameter; + try { + typedParameter = originalClass.cast(parameter); + } catch (ClassCastException ignored) { + typedParameter = copyAsType(defaultInstance, parameter); + } + originalCallback.run(typedParameter); + } + }; + } + + /** + * Creates a new message of type "Type" which is a copy of "source". "source" + * must have the same descriptor but may be a different class (e.g. + * DynamicMessage). + */ + @SuppressWarnings("unchecked") + private static Type copyAsType( + final Type typeDefaultInstance, final Message source) { + return (Type)typeDefaultInstance.newBuilderForType() + .mergeFrom(source) + .build(); + } + + /** + * Creates a callback which can only be called once. This may be useful for + * security, when passing a callback to untrusted code: most callbacks do + * not expect to be called more than once, so doing so may expose bugs if it + * is not prevented. + */ + public static + RpcCallback newOneTimeCallback( + final RpcCallback originalCallback) { + return new RpcCallback() { + private boolean alreadyCalled = false; + + public void run(final ParameterType parameter) { + synchronized(this) { + if (alreadyCalled) { + throw new AlreadyCalledException(); + } + alreadyCalled = true; + } + + originalCallback.run(parameter); + } + }; + } + + /** + * Exception thrown when a one-time callback is called more than once. + */ + public static final class AlreadyCalledException extends RuntimeException { + private static final long serialVersionUID = 5469741279507848266L; + + public AlreadyCalledException() { + super("This RpcCallback was already called and cannot be called " + + "multiple times."); + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Service.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Service.java new file mode 100644 index 0000000..541585f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Service.java @@ -0,0 +1,117 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + * Abstract base interface for protocol-buffer-based RPC services. Services + * themselves are abstract classes (implemented either by servers or as + * stubs), but they subclass this base interface. The methods of this + * interface can be used to call the methods of the service without knowing + * its exact type at compile time (analogous to the Message interface). + * + *

Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * + * @author kenton@google.com Kenton Varda + */ +public interface Service { + /** + * Get the {@code ServiceDescriptor} describing this service and its methods. + */ + Descriptors.ServiceDescriptor getDescriptorForType(); + + /** + *

Call a method of the service specified by MethodDescriptor. This is + * normally implemented as a simple {@code switch()} that calls the standard + * definitions of the service's methods. + * + *

Preconditions: + *

    + *
  • {@code method.getService() == getDescriptorForType()} + *
  • {@code request} is of the exact same class as the object returned by + * {@code getRequestPrototype(method)}. + *
  • {@code controller} is of the correct type for the RPC implementation + * being used by this Service. For stubs, the "correct type" depends + * on the RpcChannel which the stub is using. Server-side Service + * implementations are expected to accept whatever type of + * {@code RpcController} the server-side RPC implementation uses. + *
+ * + *

Postconditions: + *

    + *
  • {@code done} will be called when the method is complete. This may be + * before {@code callMethod()} returns or it may be at some point in + * the future. + *
  • The parameter to {@code done} is the response. It must be of the + * exact same type as would be returned by + * {@code getResponsePrototype(method)}. + *
  • If the RPC failed, the parameter to {@code done} will be + * {@code null}. Further details about the failure can be found by + * querying {@code controller}. + *
+ */ + void callMethod(Descriptors.MethodDescriptor method, + RpcController controller, + Message request, + RpcCallback done); + + /** + *

{@code callMethod()} requires that the request passed in is of a + * particular subclass of {@code Message}. {@code getRequestPrototype()} + * gets the default instances of this type for a given method. You can then + * call {@code Message.newBuilderForType()} on this instance to + * construct a builder to build an object which you can then pass to + * {@code callMethod()}. + * + *

Example: + *

+   *   MethodDescriptor method =
+   *     service.getDescriptorForType().findMethodByName("Foo");
+   *   Message request =
+   *     stub.getRequestPrototype(method).newBuilderForType()
+   *         .mergeFrom(input).build();
+   *   service.callMethod(method, request, callback);
+   * 
+ */ + Message getRequestPrototype(Descriptors.MethodDescriptor method); + + /** + * Like {@code getRequestPrototype()}, but gets a prototype of the response + * message. {@code getResponsePrototype()} is generally not needed because + * the {@code Service} implementation constructs the response message itself, + * but it may be useful in some cases to know ahead of time what type of + * object will be returned. + */ + Message getResponsePrototype(Descriptors.MethodDescriptor method); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ServiceException.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ServiceException.java new file mode 100644 index 0000000..cde669d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/ServiceException.java @@ -0,0 +1,52 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + * Thrown by blocking RPC methods when a failure occurs. + * + * @author cpovirk@google.com (Chris Povirk) + */ +public class ServiceException extends Exception { + private static final long serialVersionUID = -1219262335729891920L; + + public ServiceException(final String message) { + super(message); + } + + public ServiceException(final Throwable cause) { + super(cause); + } + + public ServiceException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java new file mode 100644 index 0000000..4bfc9f3 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java @@ -0,0 +1,241 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + * {@code SingleFieldBuilder} implements a structure that a protocol + * message uses to hold a single field of another protocol message. It supports + * the classical use case of setting an immutable {@link Message} as the value + * of the field and is highly optimized around this. + *
+ * It also supports the additional use case of setting a {@link Message.Builder} + * as the field and deferring conversion of that {@code Builder} + * to an immutable {@code Message}. In this way, it's possible to maintain + * a tree of {@code Builder}'s that acts as a fully read/write data + * structure. + *
+ * Logically, one can think of a tree of builders as converting the entire tree + * to messages when build is called on the root or when any method is called + * that desires a Message instead of a Builder. In terms of the implementation, + * the {@code SingleFieldBuilder} and {@code RepeatedFieldBuilder} + * classes cache messages that were created so that messages only need to be + * created when some change occured in its builder or a builder for one of its + * descendants. + * + * @param the type of message for the field + * @param the type of builder for the field + * @param the common interface for the message and the builder + * + * @author jonp@google.com (Jon Perlow) + */ +public class SingleFieldBuilder + + implements GeneratedMessage.BuilderParent { + + // Parent to send changes to. + private GeneratedMessage.BuilderParent parent; + + // Invariant: one of builder or message fields must be non-null. + + // If set, this is the case where we are backed by a builder. In this case, + // message field represents a cached message for the builder (or null if + // there is no cached message). + private BType builder; + + // If builder is non-null, this represents a cached message from the builder. + // If builder is null, this is the authoritative message for the field. + private MType message; + + // Indicates that we've built a message and so we are now obligated + // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener. + private boolean isClean; + + public SingleFieldBuilder( + MType message, + GeneratedMessage.BuilderParent parent, + boolean isClean) { + if (message == null) { + throw new NullPointerException(); + } + this.message = message; + this.parent = parent; + this.isClean = isClean; + } + + public void dispose() { + // Null out parent so we stop sending it invalidations. + parent = null; + } + + /** + * Get the message for the field. If the message is currently stored + * as a {@code Builder}, it is converted to a {@code Message} by + * calling {@link Message.Builder#buildPartial} on it. If no message has + * been set, returns the default instance of the message. + * + * @return the message for the field + */ + @SuppressWarnings("unchecked") + public MType getMessage() { + if (message == null) { + // If message is null, the invariant is that we must be have a builder. + message = (MType) builder.buildPartial(); + } + return message; + } + + /** + * Builds the message and returns it. + * + * @return the message + */ + public MType build() { + // Now that build has been called, we are required to dispatch + // invalidations. + isClean = true; + return getMessage(); + } + + /** + * Gets a builder for the field. If no builder has been created yet, a + * builder is created on demand by calling {@link Message#toBuilder}. + * + * @return The builder for the field + */ + @SuppressWarnings("unchecked") + public BType getBuilder() { + if (builder == null) { + // builder.mergeFrom() on a fresh builder + // does not create any sub-objects with independent clean/dirty states, + // therefore setting the builder itself to clean without actually calling + // build() cannot break any invariants. + builder = (BType) message.newBuilderForType(this); + builder.mergeFrom(message); // no-op if message is the default message + builder.markClean(); + } + return builder; + } + + /** + * Gets the base class interface for the field. This may either be a builder + * or a message. It will return whatever is more efficient. + * + * @return the message or builder for the field as the base class interface + */ + @SuppressWarnings("unchecked") + public IType getMessageOrBuilder() { + if (builder != null) { + return (IType) builder; + } else { + return (IType) message; + } + } + + /** + * Sets a message for the field replacing any existing value. + * + * @param message the message to set + * @return the builder + */ + public SingleFieldBuilder setMessage( + MType message) { + if (message == null) { + throw new NullPointerException(); + } + this.message = message; + if (builder != null) { + builder.dispose(); + builder = null; + } + onChanged(); + return this; + } + + /** + * Merges the field from another field. + * + * @param value the value to merge from + * @return the builder + */ + public SingleFieldBuilder mergeFrom( + MType value) { + if (builder == null && message == message.getDefaultInstanceForType()) { + message = value; + } else { + getBuilder().mergeFrom(value); + } + onChanged(); + return this; + } + + /** + * Clears the value of the field. + * + * @return the builder + */ + @SuppressWarnings("unchecked") + public SingleFieldBuilder clear() { + message = (MType) (message != null ? + message.getDefaultInstanceForType() : + builder.getDefaultInstanceForType()); + if (builder != null) { + builder.dispose(); + builder = null; + } + onChanged(); + return this; + } + + /** + * Called when a the builder or one of its nested children has changed + * and any parent should be notified of its invalidation. + */ + private void onChanged() { + // If builder is null, this is the case where onChanged is being called + // from setMessage or clear. + if (builder != null) { + message = null; + } + if (isClean && parent != null) { + parent.markDirty(); + + // Don't keep dispatching invalidations until build is called again. + isClean = false; + } + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void markDirty() { + onChanged(); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/SmallSortedMap.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/SmallSortedMap.java new file mode 100644 index 0000000..c6cad6a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/SmallSortedMap.java @@ -0,0 +1,618 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.util.AbstractMap; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.TreeMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.SortedMap; + +/** + * A custom map implementation from FieldDescriptor to Object optimized to + * minimize the number of memory allocations for instances with a small number + * of mappings. The implementation stores the first {@code k} mappings in an + * array for a configurable value of {@code k}, allowing direct access to the + * corresponding {@code Entry}s without the need to create an Iterator. The + * remaining entries are stored in an overflow map. Iteration over the entries + * in the map should be done as follows: + * + *
   {@code
+ * for (int i = 0; i < fieldMap.getNumArrayEntries(); i++) {
+ *   process(fieldMap.getArrayEntryAt(i));
+ * }
+ * for (Map.Entry entry : fieldMap.getOverflowEntries()) {
+ *   process(entry);
+ * }
+ * }
+ * + * The resulting iteration is in order of ascending field tag number. The + * object returned by {@link #entrySet()} adheres to the same contract but is + * less efficient as it necessarily involves creating an object for iteration. + *

+ * The tradeoff for this memory efficiency is that the worst case running time + * of the {@code put()} operation is {@code O(k + lg n)}, which happens when + * entries are added in descending order. {@code k} should be chosen such that + * it covers enough common cases without adversely affecting larger maps. In + * practice, the worst case scenario does not happen for extensions because + * extension fields are serialized and deserialized in order of ascending tag + * number, but the worst case scenario can happen for DynamicMessages. + *

+ * The running time for all other operations is similar to that of + * {@code TreeMap}. + *

+ * Instances are not thread-safe until {@link #makeImmutable()} is called, + * after which any modifying operation will result in an + * {@link UnsupportedOperationException}. + * + * @author darick@google.com Darick Tong + */ +// This class is final for all intents and purposes because the constructor is +// private. However, the FieldDescriptor-specific logic is encapsulated in +// a subclass to aid testability of the core logic. +class SmallSortedMap, V> extends AbstractMap { + + /** + * Creates a new instance for mapping FieldDescriptors to their values. + * The {@link #makeImmutable()} implementation will convert the List values + * of any repeated fields to unmodifiable lists. + * + * @param arraySize The size of the entry array containing the + * lexicographically smallest mappings. + */ + static > + SmallSortedMap newFieldMap(int arraySize) { + return new SmallSortedMap(arraySize) { + @Override + @SuppressWarnings("unchecked") + public void makeImmutable() { + if (!isImmutable()) { + for (int i = 0; i < getNumArrayEntries(); i++) { + final Map.Entry entry = + getArrayEntryAt(i); + if (entry.getKey().isRepeated()) { + final List value = (List) entry.getValue(); + entry.setValue(Collections.unmodifiableList(value)); + } + } + for (Map.Entry entry : + getOverflowEntries()) { + if (entry.getKey().isRepeated()) { + final List value = (List) entry.getValue(); + entry.setValue(Collections.unmodifiableList(value)); + } + } + } + super.makeImmutable(); + } + }; + } + + /** + * Creates a new instance for testing. + * + * @param arraySize The size of the entry array containing the + * lexicographically smallest mappings. + */ + static , V> SmallSortedMap newInstanceForTest( + int arraySize) { + return new SmallSortedMap(arraySize); + } + + private final int maxArraySize; + // The "entry array" is actually a List because generic arrays are not + // allowed. ArrayList also nicely handles the entry shifting on inserts and + // removes. + private List entryList; + private Map overflowEntries; + private boolean isImmutable; + // The EntrySet is a stateless view of the Map. It's initialized the first + // time it is requested and reused henceforth. + private volatile EntrySet lazyEntrySet; + + /** + * @code arraySize Size of the array in which the lexicographically smallest + * mappings are stored. (i.e. the {@code k} referred to in the class + * documentation). + */ + private SmallSortedMap(int arraySize) { + this.maxArraySize = arraySize; + this.entryList = Collections.emptyList(); + this.overflowEntries = Collections.emptyMap(); + } + + /** Make this map immutable from this point forward. */ + public void makeImmutable() { + if (!isImmutable) { + // Note: There's no need to wrap the entryList in an unmodifiableList + // because none of the list's accessors are exposed. The iterator() of + // overflowEntries, on the other hand, is exposed so it must be made + // unmodifiable. + overflowEntries = overflowEntries.isEmpty() ? + Collections.emptyMap() : + Collections.unmodifiableMap(overflowEntries); + isImmutable = true; + } + } + + /** @return Whether {@link #makeImmutable()} has been called. */ + public boolean isImmutable() { + return isImmutable; + } + + /** @return The number of entries in the entry array. */ + public int getNumArrayEntries() { + return entryList.size(); + } + + /** @return The array entry at the given {@code index}. */ + public Map.Entry getArrayEntryAt(int index) { + return entryList.get(index); + } + + /** @return There number of overflow entries. */ + public int getNumOverflowEntries() { + return overflowEntries.size(); + } + + /** @return An iterable over the overflow entries. */ + public Iterable> getOverflowEntries() { + return overflowEntries.isEmpty() ? + EmptySet.>iterable() : + overflowEntries.entrySet(); + } + + @Override + public int size() { + return entryList.size() + overflowEntries.size(); + } + + /** + * The implementation throws a {@code ClassCastException} if o is not an + * object of type {@code K}. + * + * {@inheritDoc} + */ + @Override + public boolean containsKey(Object o) { + @SuppressWarnings("unchecked") + final K key = (K) o; + return binarySearchInArray(key) >= 0 || overflowEntries.containsKey(key); + } + + /** + * The implementation throws a {@code ClassCastException} if o is not an + * object of type {@code K}. + * + * {@inheritDoc} + */ + @Override + public V get(Object o) { + @SuppressWarnings("unchecked") + final K key = (K) o; + final int index = binarySearchInArray(key); + if (index >= 0) { + return entryList.get(index).getValue(); + } + return overflowEntries.get(key); + } + + @Override + public V put(K key, V value) { + checkMutable(); + final int index = binarySearchInArray(key); + if (index >= 0) { + // Replace existing array entry. + return entryList.get(index).setValue(value); + } + ensureEntryArrayMutable(); + final int insertionPoint = -(index + 1); + if (insertionPoint >= maxArraySize) { + // Put directly in overflow. + return getOverflowEntriesMutable().put(key, value); + } + // Insert new Entry in array. + if (entryList.size() == maxArraySize) { + // Shift the last array entry into overflow. + final Entry lastEntryInArray = entryList.remove(maxArraySize - 1); + getOverflowEntriesMutable().put(lastEntryInArray.getKey(), + lastEntryInArray.getValue()); + } + entryList.add(insertionPoint, new Entry(key, value)); + return null; + } + + @Override + public void clear() { + checkMutable(); + if (!entryList.isEmpty()) { + entryList.clear(); + } + if (!overflowEntries.isEmpty()) { + overflowEntries.clear(); + } + } + + /** + * The implementation throws a {@code ClassCastException} if o is not an + * object of type {@code K}. + * + * {@inheritDoc} + */ + @Override + public V remove(Object o) { + checkMutable(); + @SuppressWarnings("unchecked") + final K key = (K) o; + final int index = binarySearchInArray(key); + if (index >= 0) { + return removeArrayEntryAt(index); + } + // overflowEntries might be Collections.unmodifiableMap(), so only + // call remove() if it is non-empty. + if (overflowEntries.isEmpty()) { + return null; + } else { + return overflowEntries.remove(key); + } + } + + private V removeArrayEntryAt(int index) { + checkMutable(); + final V removed = entryList.remove(index).getValue(); + if (!overflowEntries.isEmpty()) { + // Shift the first entry in the overflow to be the last entry in the + // array. + final Iterator> iterator = + getOverflowEntriesMutable().entrySet().iterator(); + entryList.add(new Entry(iterator.next())); + iterator.remove(); + } + return removed; + } + + /** + * @param key The key to find in the entry array. + * @return The returned integer position follows the same semantics as the + * value returned by {@link java.util.Arrays#binarySearch()}. + */ + private int binarySearchInArray(K key) { + int left = 0; + int right = entryList.size() - 1; + + // Optimization: For the common case in which entries are added in + // ascending tag order, check the largest element in the array before + // doing a full binary search. + if (right >= 0) { + int cmp = key.compareTo(entryList.get(right).getKey()); + if (cmp > 0) { + return -(right + 2); // Insert point is after "right". + } else if (cmp == 0) { + return right; + } + } + + while (left <= right) { + int mid = (left + right) / 2; + int cmp = key.compareTo(entryList.get(mid).getKey()); + if (cmp < 0) { + right = mid - 1; + } else if (cmp > 0) { + left = mid + 1; + } else { + return mid; + } + } + return -(left + 1); + } + + /** + * Similar to the AbstractMap implementation of {@code keySet()} and + * {@code values()}, the entry set is created the first time this method is + * called, and returned in response to all subsequent calls. + * + * {@inheritDoc} + */ + @Override + public Set> entrySet() { + if (lazyEntrySet == null) { + lazyEntrySet = new EntrySet(); + } + return lazyEntrySet; + } + + /** + * @throws UnsupportedOperationException if {@link #makeImmutable()} has + * has been called. + */ + private void checkMutable() { + if (isImmutable) { + throw new UnsupportedOperationException(); + } + } + + /** + * @return a {@link SortedMap} to which overflow entries mappings can be + * added or removed. + * @throws UnsupportedOperationException if {@link #makeImmutable()} has been + * called. + */ + @SuppressWarnings("unchecked") + private SortedMap getOverflowEntriesMutable() { + checkMutable(); + if (overflowEntries.isEmpty() && !(overflowEntries instanceof TreeMap)) { + overflowEntries = new TreeMap(); + } + return (SortedMap) overflowEntries; + } + + /** + * Lazily creates the entry list. Any code that adds to the list must first + * call this method. + */ + private void ensureEntryArrayMutable() { + checkMutable(); + if (entryList.isEmpty() && !(entryList instanceof ArrayList)) { + entryList = new ArrayList(maxArraySize); + } + } + + /** + * Entry implementation that implements Comparable in order to support + * binary search within the entry array. Also checks mutability in + * {@link #setValue()}. + */ + private class Entry implements Map.Entry, Comparable { + + private final K key; + private V value; + + Entry(Map.Entry copy) { + this(copy.getKey(), copy.getValue()); + } + + Entry(K key, V value) { + this.key = key; + this.value = value; + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public K getKey() { + return key; + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public V getValue() { + return value; + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public int compareTo(Entry other) { + return getKey().compareTo(other.getKey()); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public V setValue(V newValue) { + checkMutable(); + final V oldValue = this.value; + this.value = newValue; + return oldValue; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Map.Entry)) { + return false; + } + @SuppressWarnings("unchecked") + Map.Entry other = (Map.Entry) o; + return equals(key, other.getKey()) && equals(value, other.getValue()); + } + + @Override + public int hashCode() { + return (key == null ? 0 : key.hashCode()) ^ + (value == null ? 0 : value.hashCode()); + } + + @Override + public String toString() { + return key + "=" + value; + } + + /** equals() that handles null values. */ + private boolean equals(Object o1, Object o2) { + return o1 == null ? o2 == null : o1.equals(o2); + } + } + + /** + * Stateless view of the entries in the field map. + */ + private class EntrySet extends AbstractSet> { + + @Override + public Iterator> iterator() { + return new EntryIterator(); + } + + @Override + public int size() { + return SmallSortedMap.this.size(); + } + + /** + * Throws a {@link ClassCastException} if o is not of the expected type. + * + * {@inheritDoc} + */ + @Override + public boolean contains(Object o) { + @SuppressWarnings("unchecked") + final Map.Entry entry = (Map.Entry) o; + final V existing = get(entry.getKey()); + final V value = entry.getValue(); + return existing == value || + (existing != null && existing.equals(value)); + } + + @Override + public boolean add(Map.Entry entry) { + if (!contains(entry)) { + put(entry.getKey(), entry.getValue()); + return true; + } + return false; + } + + /** + * Throws a {@link ClassCastException} if o is not of the expected type. + * + * {@inheritDoc} + */ + @Override + public boolean remove(Object o) { + @SuppressWarnings("unchecked") + final Map.Entry entry = (Map.Entry) o; + if (contains(entry)) { + SmallSortedMap.this.remove(entry.getKey()); + return true; + } + return false; + } + + @Override + public void clear() { + SmallSortedMap.this.clear(); + } + } + + /** + * Iterator implementation that switches from the entry array to the overflow + * entries appropriately. + */ + private class EntryIterator implements Iterator> { + + private int pos = -1; + private boolean nextCalledBeforeRemove; + private Iterator> lazyOverflowIterator; + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public boolean hasNext() { + return (pos + 1) < entryList.size() || + getOverflowIterator().hasNext(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Map.Entry next() { + nextCalledBeforeRemove = true; + // Always increment pos so that we know whether the last returned value + // was from the array or from overflow. + if (++pos < entryList.size()) { + return entryList.get(pos); + } + return getOverflowIterator().next(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void remove() { + if (!nextCalledBeforeRemove) { + throw new IllegalStateException("remove() was called before next()"); + } + nextCalledBeforeRemove = false; + checkMutable(); + + if (pos < entryList.size()) { + removeArrayEntryAt(pos--); + } else { + getOverflowIterator().remove(); + } + } + + /** + * It is important to create the overflow iterator only after the array + * entries have been iterated over because the overflow entry set changes + * when the client calls remove() on the array entries, which invalidates + * any existing iterators. + */ + private Iterator> getOverflowIterator() { + if (lazyOverflowIterator == null) { + lazyOverflowIterator = overflowEntries.entrySet().iterator(); + } + return lazyOverflowIterator; + } + } + + /** + * Helper class that holds immutable instances of an Iterable/Iterator that + * we return when the overflow entries is empty. This eliminates the creation + * of an Iterator object when there is nothing to iterate over. + */ + private static class EmptySet { + + private static final Iterator ITERATOR = new Iterator() { + //@Override (Java 1.6 override semantics, but we must support 1.5) + public boolean hasNext() { + return false; + } + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Object next() { + throw new NoSuchElementException(); + } + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void remove() { + throw new UnsupportedOperationException(); + } + }; + + private static final Iterable ITERABLE = new Iterable() { + //@Override (Java 1.6 override semantics, but we must support 1.5) + public Iterator iterator() { + return ITERATOR; + } + }; + + @SuppressWarnings("unchecked") + static Iterable iterable() { + return (Iterable) ITERABLE; + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/TextFormat.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/TextFormat.java new file mode 100644 index 0000000..ed46289 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/TextFormat.java @@ -0,0 +1,1559 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.Descriptors.EnumDescriptor; +import com.google.protobuf.Descriptors.EnumValueDescriptor; + +import java.io.IOException; +import java.nio.CharBuffer; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Provide text parsing and formatting support for proto2 instances. + * The implementation largely follows google/protobuf/text_format.cc. + * + * @author wenboz@google.com Wenbo Zhu + * @author kenton@google.com Kenton Varda + */ +public final class TextFormat { + private TextFormat() {} + + private static final Printer DEFAULT_PRINTER = new Printer(); + private static final Printer SINGLE_LINE_PRINTER = + (new Printer()).setSingleLineMode(true); + private static final Printer UNICODE_PRINTER = + (new Printer()).setEscapeNonAscii(false); + + /** + * Outputs a textual representation of the Protocol Message supplied into + * the parameter output. (This representation is the new version of the + * classic "ProtocolPrinter" output from the original Protocol Buffer system) + */ + public static void print(final MessageOrBuilder message, final Appendable output) + throws IOException { + DEFAULT_PRINTER.print(message, new TextGenerator(output)); + } + + /** Outputs a textual representation of {@code fields} to {@code output}. */ + public static void print(final UnknownFieldSet fields, + final Appendable output) + throws IOException { + DEFAULT_PRINTER.printUnknownFields(fields, new TextGenerator(output)); + } + + /** + * Generates a human readable form of this message, useful for debugging and + * other purposes, with no newline characters. + */ + public static String shortDebugString(final MessageOrBuilder message) { + try { + final StringBuilder sb = new StringBuilder(); + SINGLE_LINE_PRINTER.print(message, new TextGenerator(sb)); + // Single line mode currently might have an extra space at the end. + return sb.toString().trim(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + /** + * Generates a human readable form of the unknown fields, useful for debugging + * and other purposes, with no newline characters. + */ + public static String shortDebugString(final UnknownFieldSet fields) { + try { + final StringBuilder sb = new StringBuilder(); + SINGLE_LINE_PRINTER.printUnknownFields(fields, new TextGenerator(sb)); + // Single line mode currently might have an extra space at the end. + return sb.toString().trim(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + /** + * Like {@code print()}, but writes directly to a {@code String} and + * returns it. + */ + public static String printToString(final MessageOrBuilder message) { + try { + final StringBuilder text = new StringBuilder(); + print(message, text); + return text.toString(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + /** + * Like {@code print()}, but writes directly to a {@code String} and + * returns it. + */ + public static String printToString(final UnknownFieldSet fields) { + try { + final StringBuilder text = new StringBuilder(); + print(fields, text); + return text.toString(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + /** + * Same as {@code printToString()}, except that non-ASCII characters + * in string type fields are not escaped in backslash+octals. + */ + public static String printToUnicodeString(final MessageOrBuilder message) { + try { + final StringBuilder text = new StringBuilder(); + UNICODE_PRINTER.print(message, new TextGenerator(text)); + return text.toString(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + /** + * Same as {@code printToString()}, except that non-ASCII characters + * in string type fields are not escaped in backslash+octals. + */ + public static String printToUnicodeString(final UnknownFieldSet fields) { + try { + final StringBuilder text = new StringBuilder(); + UNICODE_PRINTER.printUnknownFields(fields, new TextGenerator(text)); + return text.toString(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + public static void printField(final FieldDescriptor field, + final Object value, + final Appendable output) + throws IOException { + DEFAULT_PRINTER.printField(field, value, new TextGenerator(output)); + } + + public static String printFieldToString(final FieldDescriptor field, + final Object value) { + try { + final StringBuilder text = new StringBuilder(); + printField(field, value, text); + return text.toString(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + /** + * Outputs a textual representation of the value of given field value. + * + * @param field the descriptor of the field + * @param value the value of the field + * @param output the output to which to append the formatted value + * @throws ClassCastException if the value is not appropriate for the + * given field descriptor + * @throws IOException if there is an exception writing to the output + */ + public static void printFieldValue(final FieldDescriptor field, + final Object value, + final Appendable output) + throws IOException { + DEFAULT_PRINTER.printFieldValue(field, value, new TextGenerator(output)); + } + + /** + * Outputs a textual representation of the value of an unknown field. + * + * @param tag the field's tag number + * @param value the value of the field + * @param output the output to which to append the formatted value + * @throws ClassCastException if the value is not appropriate for the + * given field descriptor + * @throws IOException if there is an exception writing to the output + */ + public static void printUnknownFieldValue(final int tag, + final Object value, + final Appendable output) + throws IOException { + printUnknownFieldValue(tag, value, new TextGenerator(output)); + } + + private static void printUnknownFieldValue(final int tag, + final Object value, + final TextGenerator generator) + throws IOException { + switch (WireFormat.getTagWireType(tag)) { + case WireFormat.WIRETYPE_VARINT: + generator.print(unsignedToString((Long) value)); + break; + case WireFormat.WIRETYPE_FIXED32: + generator.print( + String.format((Locale) null, "0x%08x", (Integer) value)); + break; + case WireFormat.WIRETYPE_FIXED64: + generator.print(String.format((Locale) null, "0x%016x", (Long) value)); + break; + case WireFormat.WIRETYPE_LENGTH_DELIMITED: + generator.print("\""); + generator.print(escapeBytes((ByteString) value)); + generator.print("\""); + break; + case WireFormat.WIRETYPE_START_GROUP: + DEFAULT_PRINTER.printUnknownFields((UnknownFieldSet) value, generator); + break; + default: + throw new IllegalArgumentException("Bad tag: " + tag); + } + } + + /** Helper class for converting protobufs to text. */ + private static final class Printer { + /** Whether to omit newlines from the output. */ + boolean singleLineMode = false; + + /** Whether to escape non ASCII characters with backslash and octal. */ + boolean escapeNonAscii = true; + + private Printer() {} + + /** Setter of singleLineMode */ + private Printer setSingleLineMode(boolean singleLineMode) { + this.singleLineMode = singleLineMode; + return this; + } + + /** Setter of escapeNonAscii */ + private Printer setEscapeNonAscii(boolean escapeNonAscii) { + this.escapeNonAscii = escapeNonAscii; + return this; + } + + private void print(final MessageOrBuilder message, final TextGenerator generator) + throws IOException { + for (Map.Entry field + : message.getAllFields().entrySet()) { + printField(field.getKey(), field.getValue(), generator); + } + printUnknownFields(message.getUnknownFields(), generator); + } + + private void printField(final FieldDescriptor field, final Object value, + final TextGenerator generator) throws IOException { + if (field.isRepeated()) { + // Repeated field. Print each element. + for (Object element : (List) value) { + printSingleField(field, element, generator); + } + } else { + printSingleField(field, value, generator); + } + } + + private void printSingleField(final FieldDescriptor field, + final Object value, + final TextGenerator generator) + throws IOException { + if (field.isExtension()) { + generator.print("["); + // We special-case MessageSet elements for compatibility with proto1. + if (field.getContainingType().getOptions().getMessageSetWireFormat() + && (field.getType() == FieldDescriptor.Type.MESSAGE) + && (field.isOptional()) + // object equality + && (field.getExtensionScope() == field.getMessageType())) { + generator.print(field.getMessageType().getFullName()); + } else { + generator.print(field.getFullName()); + } + generator.print("]"); + } else { + if (field.getType() == FieldDescriptor.Type.GROUP) { + // Groups must be serialized with their original capitalization. + generator.print(field.getMessageType().getName()); + } else { + generator.print(field.getName()); + } + } + + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (singleLineMode) { + generator.print(" { "); + } else { + generator.print(" {\n"); + generator.indent(); + } + } else { + generator.print(": "); + } + + printFieldValue(field, value, generator); + + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (singleLineMode) { + generator.print("} "); + } else { + generator.outdent(); + generator.print("}\n"); + } + } else { + if (singleLineMode) { + generator.print(" "); + } else { + generator.print("\n"); + } + } + } + + private void printFieldValue(final FieldDescriptor field, + final Object value, + final TextGenerator generator) + throws IOException { + switch (field.getType()) { + case INT32: + case SINT32: + case SFIXED32: + generator.print(((Integer) value).toString()); + break; + + case INT64: + case SINT64: + case SFIXED64: + generator.print(((Long) value).toString()); + break; + + case BOOL: + generator.print(((Boolean) value).toString()); + break; + + case FLOAT: + generator.print(((Float) value).toString()); + break; + + case DOUBLE: + generator.print(((Double) value).toString()); + break; + + case UINT32: + case FIXED32: + generator.print(unsignedToString((Integer) value)); + break; + + case UINT64: + case FIXED64: + generator.print(unsignedToString((Long) value)); + break; + + case STRING: + generator.print("\""); + generator.print(escapeNonAscii ? + escapeText((String) value) : + (String) value); + generator.print("\""); + break; + + case BYTES: + generator.print("\""); + generator.print(escapeBytes((ByteString) value)); + generator.print("\""); + break; + + case ENUM: + generator.print(((EnumValueDescriptor) value).getName()); + break; + + case MESSAGE: + case GROUP: + print((Message) value, generator); + break; + } + } + + private void printUnknownFields(final UnknownFieldSet unknownFields, + final TextGenerator generator) + throws IOException { + for (Map.Entry entry : + unknownFields.asMap().entrySet()) { + final int number = entry.getKey(); + final UnknownFieldSet.Field field = entry.getValue(); + printUnknownField(number, WireFormat.WIRETYPE_VARINT, + field.getVarintList(), generator); + printUnknownField(number, WireFormat.WIRETYPE_FIXED32, + field.getFixed32List(), generator); + printUnknownField(number, WireFormat.WIRETYPE_FIXED64, + field.getFixed64List(), generator); + printUnknownField(number, WireFormat.WIRETYPE_LENGTH_DELIMITED, + field.getLengthDelimitedList(), generator); + for (final UnknownFieldSet value : field.getGroupList()) { + generator.print(entry.getKey().toString()); + if (singleLineMode) { + generator.print(" { "); + } else { + generator.print(" {\n"); + generator.indent(); + } + printUnknownFields(value, generator); + if (singleLineMode) { + generator.print("} "); + } else { + generator.outdent(); + generator.print("}\n"); + } + } + } + } + + private void printUnknownField(final int number, + final int wireType, + final List values, + final TextGenerator generator) + throws IOException { + for (final Object value : values) { + generator.print(String.valueOf(number)); + generator.print(": "); + printUnknownFieldValue(wireType, value, generator); + generator.print(singleLineMode ? " " : "\n"); + } + } + } + + /** Convert an unsigned 32-bit integer to a string. */ + private static String unsignedToString(final int value) { + if (value >= 0) { + return Integer.toString(value); + } else { + return Long.toString(((long) value) & 0x00000000FFFFFFFFL); + } + } + + /** Convert an unsigned 64-bit integer to a string. */ + private static String unsignedToString(final long value) { + if (value >= 0) { + return Long.toString(value); + } else { + // Pull off the most-significant bit so that BigInteger doesn't think + // the number is negative, then set it again using setBit(). + return BigInteger.valueOf(value & 0x7FFFFFFFFFFFFFFFL) + .setBit(63).toString(); + } + } + + /** + * An inner class for writing text to the output stream. + */ + private static final class TextGenerator { + private final Appendable output; + private final StringBuilder indent = new StringBuilder(); + private boolean atStartOfLine = true; + + private TextGenerator(final Appendable output) { + this.output = output; + } + + /** + * Indent text by two spaces. After calling Indent(), two spaces will be + * inserted at the beginning of each line of text. Indent() may be called + * multiple times to produce deeper indents. + */ + public void indent() { + indent.append(" "); + } + + /** + * Reduces the current indent level by two spaces, or crashes if the indent + * level is zero. + */ + public void outdent() { + final int length = indent.length(); + if (length == 0) { + throw new IllegalArgumentException( + " Outdent() without matching Indent()."); + } + indent.delete(length - 2, length); + } + + /** + * Print text to the output stream. + */ + public void print(final CharSequence text) throws IOException { + final int size = text.length(); + int pos = 0; + + for (int i = 0; i < size; i++) { + if (text.charAt(i) == '\n') { + write(text.subSequence(pos, size), i - pos + 1); + pos = i + 1; + atStartOfLine = true; + } + } + write(text.subSequence(pos, size), size - pos); + } + + private void write(final CharSequence data, final int size) + throws IOException { + if (size == 0) { + return; + } + if (atStartOfLine) { + atStartOfLine = false; + output.append(indent); + } + output.append(data); + } + } + + // ================================================================= + // Parsing + + /** + * Represents a stream of tokens parsed from a {@code String}. + * + *

The Java standard library provides many classes that you might think + * would be useful for implementing this, but aren't. For example: + * + *

    + *
  • {@code java.io.StreamTokenizer}: This almost does what we want -- or, + * at least, something that would get us close to what we want -- except + * for one fatal flaw: It automatically un-escapes strings using Java + * escape sequences, which do not include all the escape sequences we + * need to support (e.g. '\x'). + *
  • {@code java.util.Scanner}: This seems like a great way at least to + * parse regular expressions out of a stream (so we wouldn't have to load + * the entire input into a single string before parsing). Sadly, + * {@code Scanner} requires that tokens be delimited with some delimiter. + * Thus, although the text "foo:" should parse to two tokens ("foo" and + * ":"), {@code Scanner} would recognize it only as a single token. + * Furthermore, {@code Scanner} provides no way to inspect the contents + * of delimiters, making it impossible to keep track of line and column + * numbers. + *
+ * + *

Luckily, Java's regular expression support does manage to be useful to + * us. (Barely: We need {@code Matcher.usePattern()}, which is new in + * Java 1.5.) So, we can use that, at least. Unfortunately, this implies + * that we need to have the entire input in one contiguous string. + */ + private static final class Tokenizer { + private final CharSequence text; + private final Matcher matcher; + private String currentToken; + + // The character index within this.text at which the current token begins. + private int pos = 0; + + // The line and column numbers of the current token. + private int line = 0; + private int column = 0; + + // The line and column numbers of the previous token (allows throwing + // errors *after* consuming). + private int previousLine = 0; + private int previousColumn = 0; + + // We use possessive quantifiers (*+ and ++) because otherwise the Java + // regex matcher has stack overflows on large inputs. + private static final Pattern WHITESPACE = + Pattern.compile("(\\s|(#.*$))++", Pattern.MULTILINE); + private static final Pattern TOKEN = Pattern.compile( + "[a-zA-Z_][0-9a-zA-Z_+-]*+|" + // an identifier + "[.]?[0-9+-][0-9a-zA-Z_.+-]*+|" + // a number + "\"([^\"\n\\\\]|\\\\.)*+(\"|\\\\?$)|" + // a double-quoted string + "\'([^\'\n\\\\]|\\\\.)*+(\'|\\\\?$)", // a single-quoted string + Pattern.MULTILINE); + + private static final Pattern DOUBLE_INFINITY = Pattern.compile( + "-?inf(inity)?", + Pattern.CASE_INSENSITIVE); + private static final Pattern FLOAT_INFINITY = Pattern.compile( + "-?inf(inity)?f?", + Pattern.CASE_INSENSITIVE); + private static final Pattern FLOAT_NAN = Pattern.compile( + "nanf?", + Pattern.CASE_INSENSITIVE); + + /** Construct a tokenizer that parses tokens from the given text. */ + private Tokenizer(final CharSequence text) { + this.text = text; + this.matcher = WHITESPACE.matcher(text); + skipWhitespace(); + nextToken(); + } + + /** Are we at the end of the input? */ + public boolean atEnd() { + return currentToken.length() == 0; + } + + /** Advance to the next token. */ + public void nextToken() { + previousLine = line; + previousColumn = column; + + // Advance the line counter to the current position. + while (pos < matcher.regionStart()) { + if (text.charAt(pos) == '\n') { + ++line; + column = 0; + } else { + ++column; + } + ++pos; + } + + // Match the next token. + if (matcher.regionStart() == matcher.regionEnd()) { + // EOF + currentToken = ""; + } else { + matcher.usePattern(TOKEN); + if (matcher.lookingAt()) { + currentToken = matcher.group(); + matcher.region(matcher.end(), matcher.regionEnd()); + } else { + // Take one character. + currentToken = String.valueOf(text.charAt(pos)); + matcher.region(pos + 1, matcher.regionEnd()); + } + + skipWhitespace(); + } + } + + /** + * Skip over any whitespace so that the matcher region starts at the next + * token. + */ + private void skipWhitespace() { + matcher.usePattern(WHITESPACE); + if (matcher.lookingAt()) { + matcher.region(matcher.end(), matcher.regionEnd()); + } + } + + /** + * If the next token exactly matches {@code token}, consume it and return + * {@code true}. Otherwise, return {@code false} without doing anything. + */ + public boolean tryConsume(final String token) { + if (currentToken.equals(token)) { + nextToken(); + return true; + } else { + return false; + } + } + + /** + * If the next token exactly matches {@code token}, consume it. Otherwise, + * throw a {@link ParseException}. + */ + public void consume(final String token) throws ParseException { + if (!tryConsume(token)) { + throw parseException("Expected \"" + token + "\"."); + } + } + + /** + * Returns {@code true} if the next token is an integer, but does + * not consume it. + */ + public boolean lookingAtInteger() { + if (currentToken.length() == 0) { + return false; + } + + final char c = currentToken.charAt(0); + return ('0' <= c && c <= '9') || + c == '-' || c == '+'; + } + + /** + * If the next token is an identifier, consume it and return its value. + * Otherwise, throw a {@link ParseException}. + */ + public String consumeIdentifier() throws ParseException { + for (int i = 0; i < currentToken.length(); i++) { + final char c = currentToken.charAt(i); + if (('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + ('0' <= c && c <= '9') || + (c == '_') || (c == '.')) { + // OK + } else { + throw parseException("Expected identifier."); + } + } + + final String result = currentToken; + nextToken(); + return result; + } + + /** + * If the next token is a 32-bit signed integer, consume it and return its + * value. Otherwise, throw a {@link ParseException}. + */ + public int consumeInt32() throws ParseException { + try { + final int result = parseInt32(currentToken); + nextToken(); + return result; + } catch (NumberFormatException e) { + throw integerParseException(e); + } + } + + /** + * If the next token is a 32-bit unsigned integer, consume it and return its + * value. Otherwise, throw a {@link ParseException}. + */ + public int consumeUInt32() throws ParseException { + try { + final int result = parseUInt32(currentToken); + nextToken(); + return result; + } catch (NumberFormatException e) { + throw integerParseException(e); + } + } + + /** + * If the next token is a 64-bit signed integer, consume it and return its + * value. Otherwise, throw a {@link ParseException}. + */ + public long consumeInt64() throws ParseException { + try { + final long result = parseInt64(currentToken); + nextToken(); + return result; + } catch (NumberFormatException e) { + throw integerParseException(e); + } + } + + /** + * If the next token is a 64-bit unsigned integer, consume it and return its + * value. Otherwise, throw a {@link ParseException}. + */ + public long consumeUInt64() throws ParseException { + try { + final long result = parseUInt64(currentToken); + nextToken(); + return result; + } catch (NumberFormatException e) { + throw integerParseException(e); + } + } + + /** + * If the next token is a double, consume it and return its value. + * Otherwise, throw a {@link ParseException}. + */ + public double consumeDouble() throws ParseException { + // We need to parse infinity and nan separately because + // Double.parseDouble() does not accept "inf", "infinity", or "nan". + if (DOUBLE_INFINITY.matcher(currentToken).matches()) { + final boolean negative = currentToken.startsWith("-"); + nextToken(); + return negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + } + if (currentToken.equalsIgnoreCase("nan")) { + nextToken(); + return Double.NaN; + } + try { + final double result = Double.parseDouble(currentToken); + nextToken(); + return result; + } catch (NumberFormatException e) { + throw floatParseException(e); + } + } + + /** + * If the next token is a float, consume it and return its value. + * Otherwise, throw a {@link ParseException}. + */ + public float consumeFloat() throws ParseException { + // We need to parse infinity and nan separately because + // Float.parseFloat() does not accept "inf", "infinity", or "nan". + if (FLOAT_INFINITY.matcher(currentToken).matches()) { + final boolean negative = currentToken.startsWith("-"); + nextToken(); + return negative ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY; + } + if (FLOAT_NAN.matcher(currentToken).matches()) { + nextToken(); + return Float.NaN; + } + try { + final float result = Float.parseFloat(currentToken); + nextToken(); + return result; + } catch (NumberFormatException e) { + throw floatParseException(e); + } + } + + /** + * If the next token is a boolean, consume it and return its value. + * Otherwise, throw a {@link ParseException}. + */ + public boolean consumeBoolean() throws ParseException { + if (currentToken.equals("true") || + currentToken.equals("t") || + currentToken.equals("1")) { + nextToken(); + return true; + } else if (currentToken.equals("false") || + currentToken.equals("f") || + currentToken.equals("0")) { + nextToken(); + return false; + } else { + throw parseException("Expected \"true\" or \"false\"."); + } + } + + /** + * If the next token is a string, consume it and return its (unescaped) + * value. Otherwise, throw a {@link ParseException}. + */ + public String consumeString() throws ParseException { + return consumeByteString().toStringUtf8(); + } + + /** + * If the next token is a string, consume it, unescape it as a + * {@link ByteString}, and return it. Otherwise, throw a + * {@link ParseException}. + */ + public ByteString consumeByteString() throws ParseException { + List list = new ArrayList(); + consumeByteString(list); + while (currentToken.startsWith("'") || currentToken.startsWith("\"")) { + consumeByteString(list); + } + return ByteString.copyFrom(list); + } + + /** + * Like {@link #consumeByteString()} but adds each token of the string to + * the given list. String literals (whether bytes or text) may come in + * multiple adjacent tokens which are automatically concatenated, like in + * C or Python. + */ + private void consumeByteString(List list) throws ParseException { + final char quote = currentToken.length() > 0 ? currentToken.charAt(0) + : '\0'; + if (quote != '\"' && quote != '\'') { + throw parseException("Expected string."); + } + + if (currentToken.length() < 2 || + currentToken.charAt(currentToken.length() - 1) != quote) { + throw parseException("String missing ending quote."); + } + + try { + final String escaped = + currentToken.substring(1, currentToken.length() - 1); + final ByteString result = unescapeBytes(escaped); + nextToken(); + list.add(result); + } catch (InvalidEscapeSequenceException e) { + throw parseException(e.getMessage()); + } + } + + /** + * Returns a {@link ParseException} with the current line and column + * numbers in the description, suitable for throwing. + */ + public ParseException parseException(final String description) { + // Note: People generally prefer one-based line and column numbers. + return new ParseException( + line + 1, column + 1, description); + } + + /** + * Returns a {@link ParseException} with the line and column numbers of + * the previous token in the description, suitable for throwing. + */ + public ParseException parseExceptionPreviousToken( + final String description) { + // Note: People generally prefer one-based line and column numbers. + return new ParseException( + previousLine + 1, previousColumn + 1, description); + } + + /** + * Constructs an appropriate {@link ParseException} for the given + * {@code NumberFormatException} when trying to parse an integer. + */ + private ParseException integerParseException( + final NumberFormatException e) { + return parseException("Couldn't parse integer: " + e.getMessage()); + } + + /** + * Constructs an appropriate {@link ParseException} for the given + * {@code NumberFormatException} when trying to parse a float or double. + */ + private ParseException floatParseException(final NumberFormatException e) { + return parseException("Couldn't parse number: " + e.getMessage()); + } + } + + /** Thrown when parsing an invalid text format message. */ + public static class ParseException extends IOException { + private static final long serialVersionUID = 3196188060225107702L; + + private final int line; + private final int column; + + /** Create a new instance, with -1 as the line and column numbers. */ + public ParseException(final String message) { + this(-1, -1, message); + } + + /** + * Create a new instance + * + * @param line the line number where the parse error occurred, + * using 1-offset. + * @param column the column number where the parser error occurred, + * using 1-offset. + */ + public ParseException(final int line, final int column, + final String message) { + super(Integer.toString(line) + ":" + column + ": " + message); + this.line = line; + this.column = column; + } + + /** + * Return the line where the parse exception occurred, or -1 when + * none is provided. The value is specified as 1-offset, so the first + * line is line 1. + */ + public int getLine() { + return line; + } + + /** + * Return the column where the parse exception occurred, or -1 when + * none is provided. The value is specified as 1-offset, so the first + * line is line 1. + */ + public int getColumn() { + return column; + } + } + + /** + * Parse a text-format message from {@code input} and merge the contents + * into {@code builder}. + */ + public static void merge(final Readable input, + final Message.Builder builder) + throws IOException { + merge(input, ExtensionRegistry.getEmptyRegistry(), builder); + } + + /** + * Parse a text-format message from {@code input} and merge the contents + * into {@code builder}. + */ + public static void merge(final CharSequence input, + final Message.Builder builder) + throws ParseException { + merge(input, ExtensionRegistry.getEmptyRegistry(), builder); + } + + /** + * Parse a text-format message from {@code input} and merge the contents + * into {@code builder}. Extensions will be recognized if they are + * registered in {@code extensionRegistry}. + */ + public static void merge(final Readable input, + final ExtensionRegistry extensionRegistry, + final Message.Builder builder) + throws IOException { + // Read the entire input to a String then parse that. + + // If StreamTokenizer were not quite so crippled, or if there were a kind + // of Reader that could read in chunks that match some particular regex, + // or if we wanted to write a custom Reader to tokenize our stream, then + // we would not have to read to one big String. Alas, none of these is + // the case. Oh well. + + merge(toStringBuilder(input), extensionRegistry, builder); + } + + private static final int BUFFER_SIZE = 4096; + + // TODO(chrisn): See if working around java.io.Reader#read(CharBuffer) + // overhead is worthwhile + private static StringBuilder toStringBuilder(final Readable input) + throws IOException { + final StringBuilder text = new StringBuilder(); + final CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE); + while (true) { + final int n = input.read(buffer); + if (n == -1) { + break; + } + buffer.flip(); + text.append(buffer, 0, n); + } + return text; + } + + /** + * Parse a text-format message from {@code input} and merge the contents + * into {@code builder}. Extensions will be recognized if they are + * registered in {@code extensionRegistry}. + */ + public static void merge(final CharSequence input, + final ExtensionRegistry extensionRegistry, + final Message.Builder builder) + throws ParseException { + final Tokenizer tokenizer = new Tokenizer(input); + + while (!tokenizer.atEnd()) { + mergeField(tokenizer, extensionRegistry, builder); + } + } + + /** + * Parse a single field from {@code tokenizer} and merge it into + * {@code builder}. + */ + private static void mergeField(final Tokenizer tokenizer, + final ExtensionRegistry extensionRegistry, + final Message.Builder builder) + throws ParseException { + FieldDescriptor field; + final Descriptor type = builder.getDescriptorForType(); + ExtensionRegistry.ExtensionInfo extension = null; + + if (tokenizer.tryConsume("[")) { + // An extension. + final StringBuilder name = + new StringBuilder(tokenizer.consumeIdentifier()); + while (tokenizer.tryConsume(".")) { + name.append('.'); + name.append(tokenizer.consumeIdentifier()); + } + + extension = extensionRegistry.findExtensionByName(name.toString()); + + if (extension == null) { + throw tokenizer.parseExceptionPreviousToken( + "Extension \"" + name + "\" not found in the ExtensionRegistry."); + } else if (extension.descriptor.getContainingType() != type) { + throw tokenizer.parseExceptionPreviousToken( + "Extension \"" + name + "\" does not extend message type \"" + + type.getFullName() + "\"."); + } + + tokenizer.consume("]"); + + field = extension.descriptor; + } else { + final String name = tokenizer.consumeIdentifier(); + field = type.findFieldByName(name); + + // Group names are expected to be capitalized as they appear in the + // .proto file, which actually matches their type names, not their field + // names. + if (field == null) { + // Explicitly specify US locale so that this code does not break when + // executing in Turkey. + final String lowerName = name.toLowerCase(Locale.US); + field = type.findFieldByName(lowerName); + // If the case-insensitive match worked but the field is NOT a group, + if (field != null && field.getType() != FieldDescriptor.Type.GROUP) { + field = null; + } + } + // Again, special-case group names as described above. + if (field != null && field.getType() == FieldDescriptor.Type.GROUP && + !field.getMessageType().getName().equals(name)) { + field = null; + } + + if (field == null) { + throw tokenizer.parseExceptionPreviousToken( + "Message type \"" + type.getFullName() + + "\" has no field named \"" + name + "\"."); + } + } + + Object value = null; + + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + tokenizer.tryConsume(":"); // optional + + final String endToken; + if (tokenizer.tryConsume("<")) { + endToken = ">"; + } else { + tokenizer.consume("{"); + endToken = "}"; + } + + final Message.Builder subBuilder; + if (extension == null) { + subBuilder = builder.newBuilderForField(field); + } else { + subBuilder = extension.defaultInstance.newBuilderForType(); + } + + while (!tokenizer.tryConsume(endToken)) { + if (tokenizer.atEnd()) { + throw tokenizer.parseException( + "Expected \"" + endToken + "\"."); + } + mergeField(tokenizer, extensionRegistry, subBuilder); + } + + value = subBuilder.buildPartial(); + + } else { + tokenizer.consume(":"); + + switch (field.getType()) { + case INT32: + case SINT32: + case SFIXED32: + value = tokenizer.consumeInt32(); + break; + + case INT64: + case SINT64: + case SFIXED64: + value = tokenizer.consumeInt64(); + break; + + case UINT32: + case FIXED32: + value = tokenizer.consumeUInt32(); + break; + + case UINT64: + case FIXED64: + value = tokenizer.consumeUInt64(); + break; + + case FLOAT: + value = tokenizer.consumeFloat(); + break; + + case DOUBLE: + value = tokenizer.consumeDouble(); + break; + + case BOOL: + value = tokenizer.consumeBoolean(); + break; + + case STRING: + value = tokenizer.consumeString(); + break; + + case BYTES: + value = tokenizer.consumeByteString(); + break; + + case ENUM: + final EnumDescriptor enumType = field.getEnumType(); + + if (tokenizer.lookingAtInteger()) { + final int number = tokenizer.consumeInt32(); + value = enumType.findValueByNumber(number); + if (value == null) { + throw tokenizer.parseExceptionPreviousToken( + "Enum type \"" + enumType.getFullName() + + "\" has no value with number " + number + '.'); + } + } else { + final String id = tokenizer.consumeIdentifier(); + value = enumType.findValueByName(id); + if (value == null) { + throw tokenizer.parseExceptionPreviousToken( + "Enum type \"" + enumType.getFullName() + + "\" has no value named \"" + id + "\"."); + } + } + + break; + + case MESSAGE: + case GROUP: + throw new RuntimeException("Can't get here."); + } + } + + if (field.isRepeated()) { + builder.addRepeatedField(field, value); + } else { + builder.setField(field, value); + } + } + + // ================================================================= + // Utility functions + // + // Some of these methods are package-private because Descriptors.java uses + // them. + + /** + * Escapes bytes in the format used in protocol buffer text format, which + * is the same as the format used for C string literals. All bytes + * that are not printable 7-bit ASCII characters are escaped, as well as + * backslash, single-quote, and double-quote characters. Characters for + * which no defined short-hand escape sequence is defined will be escaped + * using 3-digit octal sequences. + */ + static String escapeBytes(final ByteString input) { + final StringBuilder builder = new StringBuilder(input.size()); + for (int i = 0; i < input.size(); i++) { + final byte b = input.byteAt(i); + switch (b) { + // Java does not recognize \a or \v, apparently. + case 0x07: builder.append("\\a" ); break; + case '\b': builder.append("\\b" ); break; + case '\f': builder.append("\\f" ); break; + case '\n': builder.append("\\n" ); break; + case '\r': builder.append("\\r" ); break; + case '\t': builder.append("\\t" ); break; + case 0x0b: builder.append("\\v" ); break; + case '\\': builder.append("\\\\"); break; + case '\'': builder.append("\\\'"); break; + case '"' : builder.append("\\\""); break; + default: + // Note: Bytes with the high-order bit set should be escaped. Since + // bytes are signed, such bytes will compare less than 0x20, hence + // the following line is correct. + if (b >= 0x20) { + builder.append((char) b); + } else { + builder.append('\\'); + builder.append((char) ('0' + ((b >>> 6) & 3))); + builder.append((char) ('0' + ((b >>> 3) & 7))); + builder.append((char) ('0' + (b & 7))); + } + break; + } + } + return builder.toString(); + } + + /** + * Un-escape a byte sequence as escaped using + * {@link #escapeBytes(ByteString)}. Two-digit hex escapes (starting with + * "\x") are also recognized. + */ + static ByteString unescapeBytes(final CharSequence charString) + throws InvalidEscapeSequenceException { + // First convert the Java character sequence to UTF-8 bytes. + ByteString input = ByteString.copyFromUtf8(charString.toString()); + // Then unescape certain byte sequences introduced by ASCII '\\'. The valid + // escapes can all be expressed with ASCII characters, so it is safe to + // operate on bytes here. + // + // Unescaping the input byte array will result in a byte sequence that's no + // longer than the input. That's because each escape sequence is between + // two and four bytes long and stands for a single byte. + final byte[] result = new byte[input.size()]; + int pos = 0; + for (int i = 0; i < input.size(); i++) { + byte c = input.byteAt(i); + if (c == '\\') { + if (i + 1 < input.size()) { + ++i; + c = input.byteAt(i); + if (isOctal(c)) { + // Octal escape. + int code = digitValue(c); + if (i + 1 < input.size() && isOctal(input.byteAt(i + 1))) { + ++i; + code = code * 8 + digitValue(input.byteAt(i)); + } + if (i + 1 < input.size() && isOctal(input.byteAt(i + 1))) { + ++i; + code = code * 8 + digitValue(input.byteAt(i)); + } + // TODO: Check that 0 <= code && code <= 0xFF. + result[pos++] = (byte)code; + } else { + switch (c) { + case 'a' : result[pos++] = 0x07; break; + case 'b' : result[pos++] = '\b'; break; + case 'f' : result[pos++] = '\f'; break; + case 'n' : result[pos++] = '\n'; break; + case 'r' : result[pos++] = '\r'; break; + case 't' : result[pos++] = '\t'; break; + case 'v' : result[pos++] = 0x0b; break; + case '\\': result[pos++] = '\\'; break; + case '\'': result[pos++] = '\''; break; + case '"' : result[pos++] = '\"'; break; + + case 'x': + // hex escape + int code = 0; + if (i + 1 < input.size() && isHex(input.byteAt(i + 1))) { + ++i; + code = digitValue(input.byteAt(i)); + } else { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\x' with no digits"); + } + if (i + 1 < input.size() && isHex(input.byteAt(i + 1))) { + ++i; + code = code * 16 + digitValue(input.byteAt(i)); + } + result[pos++] = (byte)code; + break; + + default: + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\" + (char)c + '\''); + } + } + } else { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\' at end of string."); + } + } else { + result[pos++] = c; + } + } + + return ByteString.copyFrom(result, 0, pos); + } + + /** + * Thrown by {@link TextFormat#unescapeBytes} and + * {@link TextFormat#unescapeText} when an invalid escape sequence is seen. + */ + static class InvalidEscapeSequenceException extends IOException { + private static final long serialVersionUID = -8164033650142593304L; + + InvalidEscapeSequenceException(final String description) { + super(description); + } + } + + /** + * Like {@link #escapeBytes(ByteString)}, but escapes a text string. + * Non-ASCII characters are first encoded as UTF-8, then each byte is escaped + * individually as a 3-digit octal escape. Yes, it's weird. + */ + static String escapeText(final String input) { + return escapeBytes(ByteString.copyFromUtf8(input)); + } + + /** + * Un-escape a text string as escaped using {@link #escapeText(String)}. + * Two-digit hex escapes (starting with "\x") are also recognized. + */ + static String unescapeText(final String input) + throws InvalidEscapeSequenceException { + return unescapeBytes(input).toStringUtf8(); + } + + /** Is this an octal digit? */ + private static boolean isOctal(final byte c) { + return '0' <= c && c <= '7'; + } + + /** Is this a hex digit? */ + private static boolean isHex(final byte c) { + return ('0' <= c && c <= '9') || + ('a' <= c && c <= 'f') || + ('A' <= c && c <= 'F'); + } + + /** + * Interpret a character as a digit (in any base up to 36) and return the + * numeric value. This is like {@code Character.digit()} but we don't accept + * non-ASCII digits. + */ + private static int digitValue(final byte c) { + if ('0' <= c && c <= '9') { + return c - '0'; + } else if ('a' <= c && c <= 'z') { + return c - 'a' + 10; + } else { + return c - 'A' + 10; + } + } + + /** + * Parse a 32-bit signed integer from the text. Unlike the Java standard + * {@code Integer.parseInt()}, this function recognizes the prefixes "0x" + * and "0" to signify hexadecimal and octal numbers, respectively. + */ + static int parseInt32(final String text) throws NumberFormatException { + return (int) parseInteger(text, true, false); + } + + /** + * Parse a 32-bit unsigned integer from the text. Unlike the Java standard + * {@code Integer.parseInt()}, this function recognizes the prefixes "0x" + * and "0" to signify hexadecimal and octal numbers, respectively. The + * result is coerced to a (signed) {@code int} when returned since Java has + * no unsigned integer type. + */ + static int parseUInt32(final String text) throws NumberFormatException { + return (int) parseInteger(text, false, false); + } + + /** + * Parse a 64-bit signed integer from the text. Unlike the Java standard + * {@code Integer.parseInt()}, this function recognizes the prefixes "0x" + * and "0" to signify hexadecimal and octal numbers, respectively. + */ + static long parseInt64(final String text) throws NumberFormatException { + return parseInteger(text, true, true); + } + + /** + * Parse a 64-bit unsigned integer from the text. Unlike the Java standard + * {@code Integer.parseInt()}, this function recognizes the prefixes "0x" + * and "0" to signify hexadecimal and octal numbers, respectively. The + * result is coerced to a (signed) {@code long} when returned since Java has + * no unsigned long type. + */ + static long parseUInt64(final String text) throws NumberFormatException { + return parseInteger(text, false, true); + } + + private static long parseInteger(final String text, + final boolean isSigned, + final boolean isLong) + throws NumberFormatException { + int pos = 0; + + boolean negative = false; + if (text.startsWith("-", pos)) { + if (!isSigned) { + throw new NumberFormatException("Number must be positive: " + text); + } + ++pos; + negative = true; + } + + int radix = 10; + if (text.startsWith("0x", pos)) { + pos += 2; + radix = 16; + } else if (text.startsWith("0", pos)) { + radix = 8; + } + + final String numberText = text.substring(pos); + + long result = 0; + if (numberText.length() < 16) { + // Can safely assume no overflow. + result = Long.parseLong(numberText, radix); + if (negative) { + result = -result; + } + + // Check bounds. + // No need to check for 64-bit numbers since they'd have to be 16 chars + // or longer to overflow. + if (!isLong) { + if (isSigned) { + if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) { + throw new NumberFormatException( + "Number out of range for 32-bit signed integer: " + text); + } + } else { + if (result >= (1L << 32) || result < 0) { + throw new NumberFormatException( + "Number out of range for 32-bit unsigned integer: " + text); + } + } + } + } else { + BigInteger bigValue = new BigInteger(numberText, radix); + if (negative) { + bigValue = bigValue.negate(); + } + + // Check bounds. + if (!isLong) { + if (isSigned) { + if (bigValue.bitLength() > 31) { + throw new NumberFormatException( + "Number out of range for 32-bit signed integer: " + text); + } + } else { + if (bigValue.bitLength() > 32) { + throw new NumberFormatException( + "Number out of range for 32-bit unsigned integer: " + text); + } + } + } else { + if (isSigned) { + if (bigValue.bitLength() > 63) { + throw new NumberFormatException( + "Number out of range for 64-bit signed integer: " + text); + } + } else { + if (bigValue.bitLength() > 64) { + throw new NumberFormatException( + "Number out of range for 64-bit unsigned integer: " + text); + } + } + } + + result = bigValue.longValue(); + } + + return result; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UninitializedMessageException.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UninitializedMessageException.java new file mode 100644 index 0000000..8743c12 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UninitializedMessageException.java @@ -0,0 +1,99 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.util.Collections; +import java.util.List; + +/** + * Thrown when attempting to build a protocol message that is missing required + * fields. This is a {@code RuntimeException} because it normally represents + * a programming error: it happens when some code which constructs a message + * fails to set all the fields. {@code parseFrom()} methods do not + * throw this; they throw an {@link InvalidProtocolBufferException} if + * required fields are missing, because it is not a programming error to + * receive an incomplete message. In other words, + * {@code UninitializedMessageException} should never be thrown by correct + * code, but {@code InvalidProtocolBufferException} might be. + * + * @author kenton@google.com Kenton Varda + */ +public class UninitializedMessageException extends RuntimeException { + private static final long serialVersionUID = -7466929953374883507L; + + public UninitializedMessageException(final MessageLite message) { + super("Message was missing required fields. (Lite runtime could not " + + "determine which fields were missing)."); + missingFields = null; + } + + public UninitializedMessageException(final List missingFields) { + super(buildDescription(missingFields)); + this.missingFields = missingFields; + } + + private final List missingFields; + + /** + * Get a list of human-readable names of required fields missing from this + * message. Each name is a full path to a field, e.g. "foo.bar[5].baz". + * Returns null if the lite runtime was used, since it lacks the ability to + * find missing fields. + */ + public List getMissingFields() { + return Collections.unmodifiableList(missingFields); + } + + /** + * Converts this exception to an {@link InvalidProtocolBufferException}. + * When a parsed message is missing required fields, this should be thrown + * instead of {@code UninitializedMessageException}. + */ + public InvalidProtocolBufferException asInvalidProtocolBufferException() { + return new InvalidProtocolBufferException(getMessage()); + } + + /** Construct the description string for this exception. */ + private static String buildDescription(final List missingFields) { + final StringBuilder description = + new StringBuilder("Message missing required fields: "); + boolean first = true; + for (final String field : missingFields) { + if (first) { + first = false; + } else { + description.append(", "); + } + description.append(field); + } + return description.toString(); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UnknownFieldSet.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UnknownFieldSet.java new file mode 100644 index 0000000..45e2e6e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UnknownFieldSet.java @@ -0,0 +1,978 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * {@code UnknownFieldSet} is used to keep track of fields which were seen when + * parsing a protocol message but whose field numbers or types are unrecognized. + * This most frequently occurs when new fields are added to a message type + * and then messages containing those fields are read by old software that was + * compiled before the new types were added. + * + *

Every {@link Message} contains an {@code UnknownFieldSet} (and every + * {@link Message.Builder} contains an {@link Builder}). + * + *

Most users will never need to use this class. + * + * @author kenton@google.com Kenton Varda + */ +public final class UnknownFieldSet implements MessageLite { + private UnknownFieldSet() {} + + /** Create a new {@link Builder}. */ + public static Builder newBuilder() { + return Builder.create(); + } + + /** + * Create a new {@link Builder} and initialize it to be a copy + * of {@code copyFrom}. + */ + public static Builder newBuilder(final UnknownFieldSet copyFrom) { + return newBuilder().mergeFrom(copyFrom); + } + + /** Get an empty {@code UnknownFieldSet}. */ + public static UnknownFieldSet getDefaultInstance() { + return defaultInstance; + } + public UnknownFieldSet getDefaultInstanceForType() { + return defaultInstance; + } + private static final UnknownFieldSet defaultInstance = + new UnknownFieldSet(Collections.emptyMap()); + + /** + * Construct an {@code UnknownFieldSet} around the given map. The map is + * expected to be immutable. + */ + private UnknownFieldSet(final Map fields) { + this.fields = fields; + } + private Map fields; + + @Override + public boolean equals(final Object other) { + if (this == other) { + return true; + } + return (other instanceof UnknownFieldSet) && + fields.equals(((UnknownFieldSet) other).fields); + } + + @Override + public int hashCode() { + return fields.hashCode(); + } + + /** Get a map of fields in the set by number. */ + public Map asMap() { + return fields; + } + + /** Check if the given field number is present in the set. */ + public boolean hasField(final int number) { + return fields.containsKey(number); + } + + /** + * Get a field by number. Returns an empty field if not present. Never + * returns {@code null}. + */ + public Field getField(final int number) { + final Field result = fields.get(number); + return (result == null) ? Field.getDefaultInstance() : result; + } + + /** Serializes the set and writes it to {@code output}. */ + public void writeTo(final CodedOutputStream output) throws IOException { + for (final Map.Entry entry : fields.entrySet()) { + entry.getValue().writeTo(entry.getKey(), output); + } + } + + /** + * Converts the set to a string in protocol buffer text format. This is + * just a trivial wrapper around + * {@link TextFormat#printToString(UnknownFieldSet)}. + */ + @Override + public String toString() { + return TextFormat.printToString(this); + } + + /** + * Serializes the message to a {@code ByteString} and returns it. This is + * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}. + */ + public ByteString toByteString() { + try { + final ByteString.CodedBuilder out = + ByteString.newCodedBuilder(getSerializedSize()); + writeTo(out.getCodedOutput()); + return out.build(); + } catch (final IOException e) { + throw new RuntimeException( + "Serializing to a ByteString threw an IOException (should " + + "never happen).", e); + } + } + + /** + * Serializes the message to a {@code byte} array and returns it. This is + * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}. + */ + public byte[] toByteArray() { + try { + final byte[] result = new byte[getSerializedSize()]; + final CodedOutputStream output = CodedOutputStream.newInstance(result); + writeTo(output); + output.checkNoSpaceLeft(); + return result; + } catch (final IOException e) { + throw new RuntimeException( + "Serializing to a byte array threw an IOException " + + "(should never happen).", e); + } + } + + /** + * Serializes the message and writes it to {@code output}. This is just a + * trivial wrapper around {@link #writeTo(CodedOutputStream)}. + */ + public void writeTo(final OutputStream output) throws IOException { + final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); + writeTo(codedOutput); + codedOutput.flush(); + } + + public void writeDelimitedTo(OutputStream output) throws IOException { + final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); + codedOutput.writeRawVarint32(getSerializedSize()); + writeTo(codedOutput); + codedOutput.flush(); + } + + /** Get the number of bytes required to encode this set. */ + public int getSerializedSize() { + int result = 0; + for (final Map.Entry entry : fields.entrySet()) { + result += entry.getValue().getSerializedSize(entry.getKey()); + } + return result; + } + + /** + * Serializes the set and writes it to {@code output} using + * {@code MessageSet} wire format. + */ + public void writeAsMessageSetTo(final CodedOutputStream output) + throws IOException { + for (final Map.Entry entry : fields.entrySet()) { + entry.getValue().writeAsMessageSetExtensionTo( + entry.getKey(), output); + } + } + + /** + * Get the number of bytes required to encode this set using + * {@code MessageSet} wire format. + */ + public int getSerializedSizeAsMessageSet() { + int result = 0; + for (final Map.Entry entry : fields.entrySet()) { + result += entry.getValue().getSerializedSizeAsMessageSetExtension( + entry.getKey()); + } + return result; + } + + public boolean isInitialized() { + // UnknownFieldSets do not have required fields, so they are always + // initialized. + return true; + } + + /** Parse an {@code UnknownFieldSet} from the given input stream. */ + public static UnknownFieldSet parseFrom(final CodedInputStream input) + throws IOException { + return newBuilder().mergeFrom(input).build(); + } + + /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */ + public static UnknownFieldSet parseFrom(final ByteString data) + throws InvalidProtocolBufferException { + return newBuilder().mergeFrom(data).build(); + } + + /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */ + public static UnknownFieldSet parseFrom(final byte[] data) + throws InvalidProtocolBufferException { + return newBuilder().mergeFrom(data).build(); + } + + /** Parse an {@code UnknownFieldSet} from {@code input} and return it. */ + public static UnknownFieldSet parseFrom(final InputStream input) + throws IOException { + return newBuilder().mergeFrom(input).build(); + } + + public Builder newBuilderForType() { + return newBuilder(); + } + + public Builder toBuilder() { + return newBuilder().mergeFrom(this); + } + + /** + * Builder for {@link UnknownFieldSet}s. + * + *

Note that this class maintains {@link Field.Builder}s for all fields + * in the set. Thus, adding one element to an existing {@link Field} does not + * require making a copy. This is important for efficient parsing of + * unknown repeated fields. However, it implies that {@link Field}s cannot + * be constructed independently, nor can two {@link UnknownFieldSet}s share + * the same {@code Field} object. + * + *

Use {@link UnknownFieldSet#newBuilder()} to construct a {@code Builder}. + */ + public static final class Builder implements MessageLite.Builder { + // This constructor should never be called directly (except from 'create'). + private Builder() {} + + private Map fields; + + // Optimization: We keep around a builder for the last field that was + // modified so that we can efficiently add to it multiple times in a + // row (important when parsing an unknown repeated field). + private int lastFieldNumber; + private Field.Builder lastField; + + private static Builder create() { + Builder builder = new Builder(); + builder.reinitialize(); + return builder; + } + + /** + * Get a field builder for the given field number which includes any + * values that already exist. + */ + private Field.Builder getFieldBuilder(final int number) { + if (lastField != null) { + if (number == lastFieldNumber) { + return lastField; + } + // Note: addField() will reset lastField and lastFieldNumber. + addField(lastFieldNumber, lastField.build()); + } + if (number == 0) { + return null; + } else { + final Field existing = fields.get(number); + lastFieldNumber = number; + lastField = Field.newBuilder(); + if (existing != null) { + lastField.mergeFrom(existing); + } + return lastField; + } + } + + /** + * Build the {@link UnknownFieldSet} and return it. + * + *

Once {@code build()} has been called, the {@code Builder} will no + * longer be usable. Calling any method after {@code build()} will result + * in undefined behavior and can cause a {@code NullPointerException} to be + * thrown. + */ + public UnknownFieldSet build() { + getFieldBuilder(0); // Force lastField to be built. + final UnknownFieldSet result; + if (fields.isEmpty()) { + result = getDefaultInstance(); + } else { + result = new UnknownFieldSet(Collections.unmodifiableMap(fields)); + } + fields = null; + return result; + } + + public UnknownFieldSet buildPartial() { + // No required fields, so this is the same as build(). + return build(); + } + + @Override + public Builder clone() { + getFieldBuilder(0); // Force lastField to be built. + return UnknownFieldSet.newBuilder().mergeFrom( + new UnknownFieldSet(fields)); + } + + public UnknownFieldSet getDefaultInstanceForType() { + return UnknownFieldSet.getDefaultInstance(); + } + + private void reinitialize() { + fields = Collections.emptyMap(); + lastFieldNumber = 0; + lastField = null; + } + + /** Reset the builder to an empty set. */ + public Builder clear() { + reinitialize(); + return this; + } + + /** + * Merge the fields from {@code other} into this set. If a field number + * exists in both sets, {@code other}'s values for that field will be + * appended to the values in this set. + */ + public Builder mergeFrom(final UnknownFieldSet other) { + if (other != getDefaultInstance()) { + for (final Map.Entry entry : other.fields.entrySet()) { + mergeField(entry.getKey(), entry.getValue()); + } + } + return this; + } + + /** + * Add a field to the {@code UnknownFieldSet}. If a field with the same + * number already exists, the two are merged. + */ + public Builder mergeField(final int number, final Field field) { + if (number == 0) { + throw new IllegalArgumentException("Zero is not a valid field number."); + } + if (hasField(number)) { + getFieldBuilder(number).mergeFrom(field); + } else { + // Optimization: We could call getFieldBuilder(number).mergeFrom(field) + // in this case, but that would create a copy of the Field object. + // We'd rather reuse the one passed to us, so call addField() instead. + addField(number, field); + } + return this; + } + + /** + * Convenience method for merging a new field containing a single varint + * value. This is used in particular when an unknown enum value is + * encountered. + */ + public Builder mergeVarintField(final int number, final int value) { + if (number == 0) { + throw new IllegalArgumentException("Zero is not a valid field number."); + } + getFieldBuilder(number).addVarint(value); + return this; + } + + /** Check if the given field number is present in the set. */ + public boolean hasField(final int number) { + if (number == 0) { + throw new IllegalArgumentException("Zero is not a valid field number."); + } + return number == lastFieldNumber || fields.containsKey(number); + } + + /** + * Add a field to the {@code UnknownFieldSet}. If a field with the same + * number already exists, it is removed. + */ + public Builder addField(final int number, final Field field) { + if (number == 0) { + throw new IllegalArgumentException("Zero is not a valid field number."); + } + if (lastField != null && lastFieldNumber == number) { + // Discard this. + lastField = null; + lastFieldNumber = 0; + } + if (fields.isEmpty()) { + fields = new TreeMap(); + } + fields.put(number, field); + return this; + } + + /** + * Get all present {@code Field}s as an immutable {@code Map}. If more + * fields are added, the changes may or may not be reflected in this map. + */ + public Map asMap() { + getFieldBuilder(0); // Force lastField to be built. + return Collections.unmodifiableMap(fields); + } + + /** + * Parse an entire message from {@code input} and merge its fields into + * this set. + */ + public Builder mergeFrom(final CodedInputStream input) throws IOException { + while (true) { + final int tag = input.readTag(); + if (tag == 0 || !mergeFieldFrom(tag, input)) { + break; + } + } + return this; + } + + /** + * Parse a single field from {@code input} and merge it into this set. + * @param tag The field's tag number, which was already parsed. + * @return {@code false} if the tag is an end group tag. + */ + public boolean mergeFieldFrom(final int tag, final CodedInputStream input) + throws IOException { + final int number = WireFormat.getTagFieldNumber(tag); + switch (WireFormat.getTagWireType(tag)) { + case WireFormat.WIRETYPE_VARINT: + getFieldBuilder(number).addVarint(input.readInt64()); + return true; + case WireFormat.WIRETYPE_FIXED64: + getFieldBuilder(number).addFixed64(input.readFixed64()); + return true; + case WireFormat.WIRETYPE_LENGTH_DELIMITED: + getFieldBuilder(number).addLengthDelimited(input.readBytes()); + return true; + case WireFormat.WIRETYPE_START_GROUP: + final Builder subBuilder = newBuilder(); + input.readGroup(number, subBuilder, + ExtensionRegistry.getEmptyRegistry()); + getFieldBuilder(number).addGroup(subBuilder.build()); + return true; + case WireFormat.WIRETYPE_END_GROUP: + return false; + case WireFormat.WIRETYPE_FIXED32: + getFieldBuilder(number).addFixed32(input.readFixed32()); + return true; + default: + throw InvalidProtocolBufferException.invalidWireType(); + } + } + + /** + * Parse {@code data} as an {@code UnknownFieldSet} and merge it with the + * set being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream)}. + */ + public Builder mergeFrom(final ByteString data) + throws InvalidProtocolBufferException { + try { + final CodedInputStream input = data.newCodedInput(); + mergeFrom(input); + input.checkLastTagWas(0); + return this; + } catch (final InvalidProtocolBufferException e) { + throw e; + } catch (final IOException e) { + throw new RuntimeException( + "Reading from a ByteString threw an IOException (should " + + "never happen).", e); + } + } + + /** + * Parse {@code data} as an {@code UnknownFieldSet} and merge it with the + * set being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream)}. + */ + public Builder mergeFrom(final byte[] data) + throws InvalidProtocolBufferException { + try { + final CodedInputStream input = CodedInputStream.newInstance(data); + mergeFrom(input); + input.checkLastTagWas(0); + return this; + } catch (final InvalidProtocolBufferException e) { + throw e; + } catch (final IOException e) { + throw new RuntimeException( + "Reading from a byte array threw an IOException (should " + + "never happen).", e); + } + } + + /** + * Parse an {@code UnknownFieldSet} from {@code input} and merge it with the + * set being built. This is just a small wrapper around + * {@link #mergeFrom(CodedInputStream)}. + */ + public Builder mergeFrom(final InputStream input) throws IOException { + final CodedInputStream codedInput = CodedInputStream.newInstance(input); + mergeFrom(codedInput); + codedInput.checkLastTagWas(0); + return this; + } + + public boolean mergeDelimitedFrom(InputStream input) + throws IOException { + final int firstByte = input.read(); + if (firstByte == -1) { + return false; + } + final int size = CodedInputStream.readRawVarint32(firstByte, input); + final InputStream limitedInput = new LimitedInputStream(input, size); + mergeFrom(limitedInput); + return true; + } + + public boolean mergeDelimitedFrom( + InputStream input, + ExtensionRegistryLite extensionRegistry) throws IOException { + // UnknownFieldSet has no extensions. + return mergeDelimitedFrom(input); + } + + public Builder mergeFrom( + CodedInputStream input, + ExtensionRegistryLite extensionRegistry) throws IOException { + // UnknownFieldSet has no extensions. + return mergeFrom(input); + } + + public Builder mergeFrom( + ByteString data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + // UnknownFieldSet has no extensions. + return mergeFrom(data); + } + + public Builder mergeFrom(byte[] data, int off, int len) + throws InvalidProtocolBufferException { + try { + final CodedInputStream input = + CodedInputStream.newInstance(data, off, len); + mergeFrom(input); + input.checkLastTagWas(0); + return this; + } catch (InvalidProtocolBufferException e) { + throw e; + } catch (IOException e) { + throw new RuntimeException( + "Reading from a byte array threw an IOException (should " + + "never happen).", e); + } + } + + public Builder mergeFrom( + byte[] data, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + // UnknownFieldSet has no extensions. + return mergeFrom(data); + } + + public Builder mergeFrom( + byte[] data, int off, int len, + ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + // UnknownFieldSet has no extensions. + return mergeFrom(data, off, len); + } + + public Builder mergeFrom( + InputStream input, + ExtensionRegistryLite extensionRegistry) throws IOException { + // UnknownFieldSet has no extensions. + return mergeFrom(input); + } + + public boolean isInitialized() { + // UnknownFieldSets do not have required fields, so they are always + // initialized. + return true; + } + } + + /** + * Represents a single field in an {@code UnknownFieldSet}. + * + *

A {@code Field} consists of five lists of values. The lists correspond + * to the five "wire types" used in the protocol buffer binary format. + * The wire type of each field can be determined from the encoded form alone, + * without knowing the field's declared type. So, we are able to parse + * unknown values at least this far and separate them. Normally, only one + * of the five lists will contain any values, since it is impossible to + * define a valid message type that declares two different types for the + * same field number. However, the code is designed to allow for the case + * where the same unknown field number is encountered using multiple different + * wire types. + * + *

{@code Field} is an immutable class. To construct one, you must use a + * {@link Builder}. + * + * @see UnknownFieldSet + */ + public static final class Field { + private Field() {} + + /** Construct a new {@link Builder}. */ + public static Builder newBuilder() { + return Builder.create(); + } + + /** + * Construct a new {@link Builder} and initialize it to a copy of + * {@code copyFrom}. + */ + public static Builder newBuilder(final Field copyFrom) { + return newBuilder().mergeFrom(copyFrom); + } + + /** Get an empty {@code Field}. */ + public static Field getDefaultInstance() { + return fieldDefaultInstance; + } + private static final Field fieldDefaultInstance = newBuilder().build(); + + /** Get the list of varint values for this field. */ + public List getVarintList() { return varint; } + + /** Get the list of fixed32 values for this field. */ + public List getFixed32List() { return fixed32; } + + /** Get the list of fixed64 values for this field. */ + public List getFixed64List() { return fixed64; } + + /** Get the list of length-delimited values for this field. */ + public List getLengthDelimitedList() { return lengthDelimited; } + + /** + * Get the list of embedded group values for this field. These are + * represented using {@link UnknownFieldSet}s rather than {@link Message}s + * since the group's type is presumably unknown. + */ + public List getGroupList() { return group; } + + @Override + public boolean equals(final Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Field)) { + return false; + } + return Arrays.equals(getIdentityArray(), + ((Field) other).getIdentityArray()); + } + + @Override + public int hashCode() { + return Arrays.hashCode(getIdentityArray()); + } + + /** + * Returns the array of objects to be used to uniquely identify this + * {@link Field} instance. + */ + private Object[] getIdentityArray() { + return new Object[] { + varint, + fixed32, + fixed64, + lengthDelimited, + group}; + } + + /** + * Serializes the field, including field number, and writes it to + * {@code output}. + */ + public void writeTo(final int fieldNumber, final CodedOutputStream output) + throws IOException { + for (final long value : varint) { + output.writeUInt64(fieldNumber, value); + } + for (final int value : fixed32) { + output.writeFixed32(fieldNumber, value); + } + for (final long value : fixed64) { + output.writeFixed64(fieldNumber, value); + } + for (final ByteString value : lengthDelimited) { + output.writeBytes(fieldNumber, value); + } + for (final UnknownFieldSet value : group) { + output.writeGroup(fieldNumber, value); + } + } + + /** + * Get the number of bytes required to encode this field, including field + * number. + */ + public int getSerializedSize(final int fieldNumber) { + int result = 0; + for (final long value : varint) { + result += CodedOutputStream.computeUInt64Size(fieldNumber, value); + } + for (final int value : fixed32) { + result += CodedOutputStream.computeFixed32Size(fieldNumber, value); + } + for (final long value : fixed64) { + result += CodedOutputStream.computeFixed64Size(fieldNumber, value); + } + for (final ByteString value : lengthDelimited) { + result += CodedOutputStream.computeBytesSize(fieldNumber, value); + } + for (final UnknownFieldSet value : group) { + result += CodedOutputStream.computeGroupSize(fieldNumber, value); + } + return result; + } + + /** + * Serializes the field, including field number, and writes it to + * {@code output}, using {@code MessageSet} wire format. + */ + public void writeAsMessageSetExtensionTo( + final int fieldNumber, + final CodedOutputStream output) + throws IOException { + for (final ByteString value : lengthDelimited) { + output.writeRawMessageSetExtension(fieldNumber, value); + } + } + + /** + * Get the number of bytes required to encode this field, including field + * number, using {@code MessageSet} wire format. + */ + public int getSerializedSizeAsMessageSetExtension(final int fieldNumber) { + int result = 0; + for (final ByteString value : lengthDelimited) { + result += CodedOutputStream.computeRawMessageSetExtensionSize( + fieldNumber, value); + } + return result; + } + + private List varint; + private List fixed32; + private List fixed64; + private List lengthDelimited; + private List group; + + /** + * Used to build a {@link Field} within an {@link UnknownFieldSet}. + * + *

Use {@link Field#newBuilder()} to construct a {@code Builder}. + */ + public static final class Builder { + // This constructor should never be called directly (except from 'create'). + private Builder() {} + + private static Builder create() { + Builder builder = new Builder(); + builder.result = new Field(); + return builder; + } + + private Field result; + + /** + * Build the field. After {@code build()} has been called, the + * {@code Builder} is no longer usable. Calling any other method will + * result in undefined behavior and can cause a + * {@code NullPointerException} to be thrown. + */ + public Field build() { + if (result.varint == null) { + result.varint = Collections.emptyList(); + } else { + result.varint = Collections.unmodifiableList(result.varint); + } + if (result.fixed32 == null) { + result.fixed32 = Collections.emptyList(); + } else { + result.fixed32 = Collections.unmodifiableList(result.fixed32); + } + if (result.fixed64 == null) { + result.fixed64 = Collections.emptyList(); + } else { + result.fixed64 = Collections.unmodifiableList(result.fixed64); + } + if (result.lengthDelimited == null) { + result.lengthDelimited = Collections.emptyList(); + } else { + result.lengthDelimited = + Collections.unmodifiableList(result.lengthDelimited); + } + if (result.group == null) { + result.group = Collections.emptyList(); + } else { + result.group = Collections.unmodifiableList(result.group); + } + + final Field returnMe = result; + result = null; + return returnMe; + } + + /** Discard the field's contents. */ + public Builder clear() { + result = new Field(); + return this; + } + + /** + * Merge the values in {@code other} into this field. For each list + * of values, {@code other}'s values are append to the ones in this + * field. + */ + public Builder mergeFrom(final Field other) { + if (!other.varint.isEmpty()) { + if (result.varint == null) { + result.varint = new ArrayList(); + } + result.varint.addAll(other.varint); + } + if (!other.fixed32.isEmpty()) { + if (result.fixed32 == null) { + result.fixed32 = new ArrayList(); + } + result.fixed32.addAll(other.fixed32); + } + if (!other.fixed64.isEmpty()) { + if (result.fixed64 == null) { + result.fixed64 = new ArrayList(); + } + result.fixed64.addAll(other.fixed64); + } + if (!other.lengthDelimited.isEmpty()) { + if (result.lengthDelimited == null) { + result.lengthDelimited = new ArrayList(); + } + result.lengthDelimited.addAll(other.lengthDelimited); + } + if (!other.group.isEmpty()) { + if (result.group == null) { + result.group = new ArrayList(); + } + result.group.addAll(other.group); + } + return this; + } + + /** Add a varint value. */ + public Builder addVarint(final long value) { + if (result.varint == null) { + result.varint = new ArrayList(); + } + result.varint.add(value); + return this; + } + + /** Add a fixed32 value. */ + public Builder addFixed32(final int value) { + if (result.fixed32 == null) { + result.fixed32 = new ArrayList(); + } + result.fixed32.add(value); + return this; + } + + /** Add a fixed64 value. */ + public Builder addFixed64(final long value) { + if (result.fixed64 == null) { + result.fixed64 = new ArrayList(); + } + result.fixed64.add(value); + return this; + } + + /** Add a length-delimited value. */ + public Builder addLengthDelimited(final ByteString value) { + if (result.lengthDelimited == null) { + result.lengthDelimited = new ArrayList(); + } + result.lengthDelimited.add(value); + return this; + } + + /** Add an embedded group. */ + public Builder addGroup(final UnknownFieldSet value) { + if (result.group == null) { + result.group = new ArrayList(); + } + result.group.add(value); + return this; + } + } + } + + /** + * Parser to implement MessageLite interface. + */ + public static final class Parser extends AbstractParser { + public UnknownFieldSet parsePartialFrom( + CodedInputStream input, ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input); + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (IOException e) { + throw new InvalidProtocolBufferException(e.getMessage()) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + } + + private static final Parser PARSER = new Parser(); + public final Parser getParserForType() { + return PARSER; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java new file mode 100644 index 0000000..591bca5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java @@ -0,0 +1,152 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.util.AbstractList; +import java.util.RandomAccess; +import java.util.List; +import java.util.ListIterator; +import java.util.Iterator; + +/** + * An implementation of {@link LazyStringList} that wraps another + * {@link LazyStringList} such that it cannot be modified via the wrapper. + * + * @author jonp@google.com (Jon Perlow) + */ +public class UnmodifiableLazyStringList extends AbstractList + implements LazyStringList, RandomAccess { + + private final LazyStringList list; + + public UnmodifiableLazyStringList(LazyStringList list) { + this.list = list; + } + + @Override + public String get(int index) { + return list.get(index); + } + + @Override + public int size() { + return list.size(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public ByteString getByteString(int index) { + return list.getByteString(index); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void add(ByteString element) { + throw new UnsupportedOperationException(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public ListIterator listIterator(final int index) { + return new ListIterator() { + ListIterator iter = list.listIterator(index); + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public boolean hasNext() { + return iter.hasNext(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public String next() { + return iter.next(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public boolean hasPrevious() { + return iter.hasPrevious(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public String previous() { + return iter.previous(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public int nextIndex() { + return iter.nextIndex(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public int previousIndex() { + return iter.previousIndex(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void remove() { + throw new UnsupportedOperationException(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void set(String o) { + throw new UnsupportedOperationException(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void add(String o) { + throw new UnsupportedOperationException(); + } + }; + } + + @Override + public Iterator iterator() { + return new Iterator() { + Iterator iter = list.iterator(); + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public boolean hasNext() { + return iter.hasNext(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public String next() { + return iter.next(); + } + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + public List getUnderlyingElements() { + // The returned value is already unmodifiable. + return list.getUnderlyingElements(); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Utf8.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Utf8.java new file mode 100644 index 0000000..388f7fc --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/Utf8.java @@ -0,0 +1,349 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + * A set of low-level, high-performance static utility methods related + * to the UTF-8 character encoding. This class has no dependencies + * outside of the core JDK libraries. + * + *

There are several variants of UTF-8. The one implemented by + * this class is the restricted definition of UTF-8 introduced in + * Unicode 3.1, which mandates the rejection of "overlong" byte + * sequences as well as rejection of 3-byte surrogate codepoint byte + * sequences. Note that the UTF-8 decoder included in Oracle's JDK + * has been modified to also reject "overlong" byte sequences, but (as + * of 2011) still accepts 3-byte surrogate codepoint byte sequences. + * + *

The byte sequences considered valid by this class are exactly + * those that can be roundtrip converted to Strings and back to bytes + * using the UTF-8 charset, without loss:

 {@code
+ * Arrays.equals(bytes, new String(bytes, "UTF-8").getBytes("UTF-8"))
+ * }
+ * + *

See the Unicode Standard,
+ * Table 3-6. UTF-8 Bit Distribution,
+ * Table 3-7. Well Formed UTF-8 Byte Sequences. + * + *

This class supports decoding of partial byte sequences, so that the + * bytes in a complete UTF-8 byte sequences can be stored in multiple + * segments. Methods typically return {@link #MALFORMED} if the partial + * byte sequence is definitely not well-formed, {@link #COMPLETE} if it is + * well-formed in the absence of additional input, or if the byte sequence + * apparently terminated in the middle of a character, an opaque integer + * "state" value containing enough information to decode the character when + * passed to a subsequent invocation of a partial decoding method. + * + * @author martinrb@google.com (Martin Buchholz) + */ +final class Utf8 { + private Utf8() {} + + /** + * State value indicating that the byte sequence is well-formed and + * complete (no further bytes are needed to complete a character). + */ + public static final int COMPLETE = 0; + + /** + * State value indicating that the byte sequence is definitely not + * well-formed. + */ + public static final int MALFORMED = -1; + + // Other state values include the partial bytes of the incomplete + // character to be decoded in the simplest way: we pack the bytes + // into the state int in little-endian order. For example: + // + // int state = byte1 ^ (byte2 << 8) ^ (byte3 << 16); + // + // Such a state is unpacked thus (note the ~ operation for byte2 to + // undo byte1's sign-extension bits): + // + // int byte1 = (byte) state; + // int byte2 = (byte) ~(state >> 8); + // int byte3 = (byte) (state >> 16); + // + // We cannot store a zero byte in the state because it would be + // indistinguishable from the absence of a byte. But we don't need + // to, because partial bytes must always be negative. When building + // a state, we ensure that byte1 is negative and subsequent bytes + // are valid trailing bytes. + + /** + * Returns {@code true} if the given byte array is a well-formed + * UTF-8 byte sequence. + * + *

This is a convenience method, equivalent to a call to {@code + * isValidUtf8(bytes, 0, bytes.length)}. + */ + public static boolean isValidUtf8(byte[] bytes) { + return isValidUtf8(bytes, 0, bytes.length); + } + + /** + * Returns {@code true} if the given byte array slice is a + * well-formed UTF-8 byte sequence. The range of bytes to be + * checked extends from index {@code index}, inclusive, to {@code + * limit}, exclusive. + * + *

This is a convenience method, equivalent to {@code + * partialIsValidUtf8(bytes, index, limit) == Utf8.COMPLETE}. + */ + public static boolean isValidUtf8(byte[] bytes, int index, int limit) { + return partialIsValidUtf8(bytes, index, limit) == COMPLETE; + } + + /** + * Tells whether the given byte array slice is a well-formed, + * malformed, or incomplete UTF-8 byte sequence. The range of bytes + * to be checked extends from index {@code index}, inclusive, to + * {@code limit}, exclusive. + * + * @param state either {@link Utf8#COMPLETE} (if this is the initial decoding + * operation) or the value returned from a call to a partial decoding method + * for the previous bytes + * + * @return {@link #MALFORMED} if the partial byte sequence is + * definitely not well-formed, {@link #COMPLETE} if it is well-formed + * (no additional input needed), or if the byte sequence is + * "incomplete", i.e. apparently terminated in the middle of a character, + * an opaque integer "state" value containing enough information to + * decode the character when passed to a subsequent invocation of a + * partial decoding method. + */ + public static int partialIsValidUtf8( + int state, byte[] bytes, int index, int limit) { + if (state != COMPLETE) { + // The previous decoding operation was incomplete (or malformed). + // We look for a well-formed sequence consisting of bytes from + // the previous decoding operation (stored in state) together + // with bytes from the array slice. + // + // We expect such "straddler characters" to be rare. + + if (index >= limit) { // No bytes? No progress. + return state; + } + int byte1 = (byte) state; + // byte1 is never ASCII. + if (byte1 < (byte) 0xE0) { + // two-byte form + + // Simultaneously checks for illegal trailing-byte in + // leading position and overlong 2-byte form. + if (byte1 < (byte) 0xC2 || + // byte2 trailing-byte test + bytes[index++] > (byte) 0xBF) { + return MALFORMED; + } + } else if (byte1 < (byte) 0xF0) { + // three-byte form + + // Get byte2 from saved state or array + int byte2 = (byte) ~(state >> 8); + if (byte2 == 0) { + byte2 = bytes[index++]; + if (index >= limit) { + return incompleteStateFor(byte1, byte2); + } + } + if (byte2 > (byte) 0xBF || + // overlong? 5 most significant bits must not all be zero + (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0) || + // illegal surrogate codepoint? + (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0) || + // byte3 trailing-byte test + bytes[index++] > (byte) 0xBF) { + return MALFORMED; + } + } else { + // four-byte form + + // Get byte2 and byte3 from saved state or array + int byte2 = (byte) ~(state >> 8); + int byte3 = 0; + if (byte2 == 0) { + byte2 = bytes[index++]; + if (index >= limit) { + return incompleteStateFor(byte1, byte2); + } + } else { + byte3 = (byte) (state >> 16); + } + if (byte3 == 0) { + byte3 = bytes[index++]; + if (index >= limit) { + return incompleteStateFor(byte1, byte2, byte3); + } + } + + // If we were called with state == MALFORMED, then byte1 is 0xFF, + // which never occurs in well-formed UTF-8, and so we will return + // MALFORMED again below. + + if (byte2 > (byte) 0xBF || + // Check that 1 <= plane <= 16. Tricky optimized form of: + // if (byte1 > (byte) 0xF4 || + // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 || + // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F) + (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0 || + // byte3 trailing-byte test + byte3 > (byte) 0xBF || + // byte4 trailing-byte test + bytes[index++] > (byte) 0xBF) { + return MALFORMED; + } + } + } + + return partialIsValidUtf8(bytes, index, limit); + } + + /** + * Tells whether the given byte array slice is a well-formed, + * malformed, or incomplete UTF-8 byte sequence. The range of bytes + * to be checked extends from index {@code index}, inclusive, to + * {@code limit}, exclusive. + * + *

This is a convenience method, equivalent to a call to {@code + * partialIsValidUtf8(Utf8.COMPLETE, bytes, index, limit)}. + * + * @return {@link #MALFORMED} if the partial byte sequence is + * definitely not well-formed, {@link #COMPLETE} if it is well-formed + * (no additional input needed), or if the byte sequence is + * "incomplete", i.e. apparently terminated in the middle of a character, + * an opaque integer "state" value containing enough information to + * decode the character when passed to a subsequent invocation of a + * partial decoding method. + */ + public static int partialIsValidUtf8( + byte[] bytes, int index, int limit) { + // Optimize for 100% ASCII. + // Hotspot loves small simple top-level loops like this. + while (index < limit && bytes[index] >= 0) { + index++; + } + + return (index >= limit) ? COMPLETE : + partialIsValidUtf8NonAscii(bytes, index, limit); + } + + private static int partialIsValidUtf8NonAscii( + byte[] bytes, int index, int limit) { + for (;;) { + int byte1, byte2; + + // Optimize for interior runs of ASCII bytes. + do { + if (index >= limit) { + return COMPLETE; + } + } while ((byte1 = bytes[index++]) >= 0); + + if (byte1 < (byte) 0xE0) { + // two-byte form + + if (index >= limit) { + return byte1; + } + + // Simultaneously checks for illegal trailing-byte in + // leading position and overlong 2-byte form. + if (byte1 < (byte) 0xC2 || + bytes[index++] > (byte) 0xBF) { + return MALFORMED; + } + } else if (byte1 < (byte) 0xF0) { + // three-byte form + + if (index >= limit - 1) { // incomplete sequence + return incompleteStateFor(bytes, index, limit); + } + if ((byte2 = bytes[index++]) > (byte) 0xBF || + // overlong? 5 most significant bits must not all be zero + (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0) || + // check for illegal surrogate codepoints + (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0) || + // byte3 trailing-byte test + bytes[index++] > (byte) 0xBF) { + return MALFORMED; + } + } else { + // four-byte form + + if (index >= limit - 2) { // incomplete sequence + return incompleteStateFor(bytes, index, limit); + } + if ((byte2 = bytes[index++]) > (byte) 0xBF || + // Check that 1 <= plane <= 16. Tricky optimized form of: + // if (byte1 > (byte) 0xF4 || + // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 || + // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F) + (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0 || + // byte3 trailing-byte test + bytes[index++] > (byte) 0xBF || + // byte4 trailing-byte test + bytes[index++] > (byte) 0xBF) { + return MALFORMED; + } + } + } + } + + private static int incompleteStateFor(int byte1) { + return (byte1 > (byte) 0xF4) ? + MALFORMED : byte1; + } + + private static int incompleteStateFor(int byte1, int byte2) { + return (byte1 > (byte) 0xF4 || + byte2 > (byte) 0xBF) ? + MALFORMED : byte1 ^ (byte2 << 8); + } + + private static int incompleteStateFor(int byte1, int byte2, int byte3) { + return (byte1 > (byte) 0xF4 || + byte2 > (byte) 0xBF || + byte3 > (byte) 0xBF) ? + MALFORMED : byte1 ^ (byte2 << 8) ^ (byte3 << 16); + } + + private static int incompleteStateFor(byte[] bytes, int index, int limit) { + int byte1 = bytes[index - 1]; + switch (limit - index) { + case 0: return incompleteStateFor(byte1); + case 1: return incompleteStateFor(byte1, bytes[index]); + case 2: return incompleteStateFor(byte1, bytes[index], bytes[index + 1]); + default: throw new AssertionError(); + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/WireFormat.java b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/WireFormat.java new file mode 100644 index 0000000..dd2d631 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/main/java/com/google/protobuf/WireFormat.java @@ -0,0 +1,163 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + * This class is used internally by the Protocol Buffer library and generated + * message implementations. It is public only because those generated messages + * do not reside in the {@code protobuf} package. Others should not use this + * class directly. + * + * This class contains constants and helper functions useful for dealing with + * the Protocol Buffer wire format. + * + * @author kenton@google.com Kenton Varda + */ +public final class WireFormat { + // Do not allow instantiation. + private WireFormat() {} + + public static final int WIRETYPE_VARINT = 0; + public static final int WIRETYPE_FIXED64 = 1; + public static final int WIRETYPE_LENGTH_DELIMITED = 2; + public static final int WIRETYPE_START_GROUP = 3; + public static final int WIRETYPE_END_GROUP = 4; + public static final int WIRETYPE_FIXED32 = 5; + + static final int TAG_TYPE_BITS = 3; + static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1; + + /** Given a tag value, determines the wire type (the lower 3 bits). */ + static int getTagWireType(final int tag) { + return tag & TAG_TYPE_MASK; + } + + /** Given a tag value, determines the field number (the upper 29 bits). */ + public static int getTagFieldNumber(final int tag) { + return tag >>> TAG_TYPE_BITS; + } + + /** Makes a tag value given a field number and wire type. */ + static int makeTag(final int fieldNumber, final int wireType) { + return (fieldNumber << TAG_TYPE_BITS) | wireType; + } + + /** + * Lite equivalent to {@link Descriptors.FieldDescriptor.JavaType}. This is + * only here to support the lite runtime and should not be used by users. + */ + public enum JavaType { + INT(0), + LONG(0L), + FLOAT(0F), + DOUBLE(0D), + BOOLEAN(false), + STRING(""), + BYTE_STRING(ByteString.EMPTY), + ENUM(null), + MESSAGE(null); + + JavaType(final Object defaultDefault) { + this.defaultDefault = defaultDefault; + } + + /** + * The default default value for fields of this type, if it's a primitive + * type. + */ + Object getDefaultDefault() { + return defaultDefault; + } + + private final Object defaultDefault; + } + + /** + * Lite equivalent to {@link Descriptors.FieldDescriptor.Type}. This is + * only here to support the lite runtime and should not be used by users. + */ + public enum FieldType { + DOUBLE (JavaType.DOUBLE , WIRETYPE_FIXED64 ), + FLOAT (JavaType.FLOAT , WIRETYPE_FIXED32 ), + INT64 (JavaType.LONG , WIRETYPE_VARINT ), + UINT64 (JavaType.LONG , WIRETYPE_VARINT ), + INT32 (JavaType.INT , WIRETYPE_VARINT ), + FIXED64 (JavaType.LONG , WIRETYPE_FIXED64 ), + FIXED32 (JavaType.INT , WIRETYPE_FIXED32 ), + BOOL (JavaType.BOOLEAN , WIRETYPE_VARINT ), + STRING (JavaType.STRING , WIRETYPE_LENGTH_DELIMITED) { + public boolean isPackable() { return false; } + }, + GROUP (JavaType.MESSAGE , WIRETYPE_START_GROUP ) { + public boolean isPackable() { return false; } + }, + MESSAGE (JavaType.MESSAGE , WIRETYPE_LENGTH_DELIMITED) { + public boolean isPackable() { return false; } + }, + BYTES (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED) { + public boolean isPackable() { return false; } + }, + UINT32 (JavaType.INT , WIRETYPE_VARINT ), + ENUM (JavaType.ENUM , WIRETYPE_VARINT ), + SFIXED32(JavaType.INT , WIRETYPE_FIXED32 ), + SFIXED64(JavaType.LONG , WIRETYPE_FIXED64 ), + SINT32 (JavaType.INT , WIRETYPE_VARINT ), + SINT64 (JavaType.LONG , WIRETYPE_VARINT ); + + FieldType(final JavaType javaType, final int wireType) { + this.javaType = javaType; + this.wireType = wireType; + } + + private final JavaType javaType; + private final int wireType; + + public JavaType getJavaType() { return javaType; } + public int getWireType() { return wireType; } + + public boolean isPackable() { return true; } + } + + // Field numbers for fields in MessageSet wire format. + static final int MESSAGE_SET_ITEM = 1; + static final int MESSAGE_SET_TYPE_ID = 2; + static final int MESSAGE_SET_MESSAGE = 3; + + // Tag numbers. + static final int MESSAGE_SET_ITEM_TAG = + makeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP); + static final int MESSAGE_SET_ITEM_END_TAG = + makeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP); + static final int MESSAGE_SET_TYPE_ID_TAG = + makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT); + static final int MESSAGE_SET_MESSAGE_TAG = + makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/AbstractMessageTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/AbstractMessageTest.java new file mode 100644 index 0000000..3d05cb7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/AbstractMessageTest.java @@ -0,0 +1,509 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.Descriptors.FieldDescriptor; +import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize; +import protobuf_unittest.UnittestProto; +import protobuf_unittest.UnittestProto.ForeignMessage; +import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestPackedTypes; +import protobuf_unittest.UnittestProto.TestRequired; +import protobuf_unittest.UnittestProto.TestRequiredForeign; +import protobuf_unittest.UnittestProto.TestUnpackedTypes; + +import junit.framework.TestCase; + +import java.util.Map; + +/** + * Unit test for {@link AbstractMessage}. + * + * @author kenton@google.com Kenton Varda + */ +public class AbstractMessageTest extends TestCase { + /** + * Extends AbstractMessage and wraps some other message object. The methods + * of the Message interface which aren't explicitly implemented by + * AbstractMessage are forwarded to the wrapped object. This allows us to + * test that AbstractMessage's implementations work even if the wrapped + * object does not use them. + */ + private static class AbstractMessageWrapper extends AbstractMessage { + private final Message wrappedMessage; + + public AbstractMessageWrapper(Message wrappedMessage) { + this.wrappedMessage = wrappedMessage; + } + + public Descriptors.Descriptor getDescriptorForType() { + return wrappedMessage.getDescriptorForType(); + } + public AbstractMessageWrapper getDefaultInstanceForType() { + return new AbstractMessageWrapper( + wrappedMessage.getDefaultInstanceForType()); + } + public Map getAllFields() { + return wrappedMessage.getAllFields(); + } + public boolean hasField(Descriptors.FieldDescriptor field) { + return wrappedMessage.hasField(field); + } + public Object getField(Descriptors.FieldDescriptor field) { + return wrappedMessage.getField(field); + } + public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) { + return wrappedMessage.getRepeatedFieldCount(field); + } + public Object getRepeatedField( + Descriptors.FieldDescriptor field, int index) { + return wrappedMessage.getRepeatedField(field, index); + } + public UnknownFieldSet getUnknownFields() { + return wrappedMessage.getUnknownFields(); + } + public Builder newBuilderForType() { + return new Builder(wrappedMessage.newBuilderForType()); + } + public Builder toBuilder() { + return new Builder(wrappedMessage.toBuilder()); + } + + static class Builder extends AbstractMessage.Builder { + private final Message.Builder wrappedBuilder; + + public Builder(Message.Builder wrappedBuilder) { + this.wrappedBuilder = wrappedBuilder; + } + + public AbstractMessageWrapper build() { + return new AbstractMessageWrapper(wrappedBuilder.build()); + } + public AbstractMessageWrapper buildPartial() { + return new AbstractMessageWrapper(wrappedBuilder.buildPartial()); + } + public Builder clone() { + return new Builder(wrappedBuilder.clone()); + } + public boolean isInitialized() { + return clone().buildPartial().isInitialized(); + } + public Descriptors.Descriptor getDescriptorForType() { + return wrappedBuilder.getDescriptorForType(); + } + public AbstractMessageWrapper getDefaultInstanceForType() { + return new AbstractMessageWrapper( + wrappedBuilder.getDefaultInstanceForType()); + } + public Map getAllFields() { + return wrappedBuilder.getAllFields(); + } + public Builder newBuilderForField(Descriptors.FieldDescriptor field) { + return new Builder(wrappedBuilder.newBuilderForField(field)); + } + public boolean hasField(Descriptors.FieldDescriptor field) { + return wrappedBuilder.hasField(field); + } + public Object getField(Descriptors.FieldDescriptor field) { + return wrappedBuilder.getField(field); + } + public Builder setField(Descriptors.FieldDescriptor field, Object value) { + wrappedBuilder.setField(field, value); + return this; + } + public Builder clearField(Descriptors.FieldDescriptor field) { + wrappedBuilder.clearField(field); + return this; + } + public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) { + return wrappedBuilder.getRepeatedFieldCount(field); + } + public Object getRepeatedField( + Descriptors.FieldDescriptor field, int index) { + return wrappedBuilder.getRepeatedField(field, index); + } + public Builder setRepeatedField(Descriptors.FieldDescriptor field, + int index, Object value) { + wrappedBuilder.setRepeatedField(field, index, value); + return this; + } + public Builder addRepeatedField( + Descriptors.FieldDescriptor field, Object value) { + wrappedBuilder.addRepeatedField(field, value); + return this; + } + public UnknownFieldSet getUnknownFields() { + return wrappedBuilder.getUnknownFields(); + } + public Builder setUnknownFields(UnknownFieldSet unknownFields) { + wrappedBuilder.setUnknownFields(unknownFields); + return this; + } + @Override + public Message.Builder getFieldBuilder(FieldDescriptor field) { + return wrappedBuilder.getFieldBuilder(field); + } + } + public Parser getParserForType() { + return wrappedMessage.getParserForType(); + } + } + + // ================================================================= + + TestUtil.ReflectionTester reflectionTester = + new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null); + + TestUtil.ReflectionTester extensionsReflectionTester = + new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(), + TestUtil.getExtensionRegistry()); + + public void testClear() throws Exception { + AbstractMessageWrapper message = + new AbstractMessageWrapper.Builder( + TestAllTypes.newBuilder(TestUtil.getAllSet())) + .clear().build(); + TestUtil.assertClear((TestAllTypes) message.wrappedMessage); + } + + public void testCopy() throws Exception { + AbstractMessageWrapper message = + new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder()) + .mergeFrom(TestUtil.getAllSet()).build(); + TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage); + } + + public void testSerializedSize() throws Exception { + TestAllTypes message = TestUtil.getAllSet(); + Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet()); + + assertEquals(message.getSerializedSize(), + abstractMessage.getSerializedSize()); + } + + public void testSerialization() throws Exception { + Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet()); + + TestUtil.assertAllFieldsSet( + TestAllTypes.parseFrom(abstractMessage.toByteString())); + + assertEquals(TestUtil.getAllSet().toByteString(), + abstractMessage.toByteString()); + } + + public void testParsing() throws Exception { + AbstractMessageWrapper.Builder builder = + new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder()); + AbstractMessageWrapper message = + builder.mergeFrom(TestUtil.getAllSet().toByteString()).build(); + TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage); + } + + public void testParsingUninitialized() throws Exception { + TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder(); + builder.getOptionalMessageBuilder().setDummy2(10); + ByteString bytes = builder.buildPartial().toByteString(); + Message.Builder abstractMessageBuilder = + new AbstractMessageWrapper.Builder(TestRequiredForeign.newBuilder()); + // mergeFrom() should not throw initialization error. + abstractMessageBuilder.mergeFrom(bytes).buildPartial(); + try { + abstractMessageBuilder.mergeFrom(bytes).build(); + fail(); + } catch (UninitializedMessageException ex) { + // pass + } + + // test DynamicMessage directly. + Message.Builder dynamicMessageBuilder = DynamicMessage.newBuilder( + TestRequiredForeign.getDescriptor()); + // mergeFrom() should not throw initialization error. + dynamicMessageBuilder.mergeFrom(bytes).buildPartial(); + try { + dynamicMessageBuilder.mergeFrom(bytes).build(); + fail(); + } catch (UninitializedMessageException ex) { + // pass + } + } + + public void testPackedSerialization() throws Exception { + Message abstractMessage = + new AbstractMessageWrapper(TestUtil.getPackedSet()); + + TestUtil.assertPackedFieldsSet( + TestPackedTypes.parseFrom(abstractMessage.toByteString())); + + assertEquals(TestUtil.getPackedSet().toByteString(), + abstractMessage.toByteString()); + } + + public void testPackedParsing() throws Exception { + AbstractMessageWrapper.Builder builder = + new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder()); + AbstractMessageWrapper message = + builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); + TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage); + } + + public void testUnpackedSerialization() throws Exception { + Message abstractMessage = + new AbstractMessageWrapper(TestUtil.getUnpackedSet()); + + TestUtil.assertUnpackedFieldsSet( + TestUnpackedTypes.parseFrom(abstractMessage.toByteString())); + + assertEquals(TestUtil.getUnpackedSet().toByteString(), + abstractMessage.toByteString()); + } + + public void testParsePackedToUnpacked() throws Exception { + AbstractMessageWrapper.Builder builder = + new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder()); + AbstractMessageWrapper message = + builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); + TestUtil.assertUnpackedFieldsSet( + (TestUnpackedTypes) message.wrappedMessage); + } + + public void testParseUnpackedToPacked() throws Exception { + AbstractMessageWrapper.Builder builder = + new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder()); + AbstractMessageWrapper message = + builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); + TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage); + } + + public void testUnpackedParsing() throws Exception { + AbstractMessageWrapper.Builder builder = + new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder()); + AbstractMessageWrapper message = + builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); + TestUtil.assertUnpackedFieldsSet( + (TestUnpackedTypes) message.wrappedMessage); + } + + public void testOptimizedForSize() throws Exception { + // We're mostly only checking that this class was compiled successfully. + TestOptimizedForSize message = + TestOptimizedForSize.newBuilder().setI(1).build(); + message = TestOptimizedForSize.parseFrom(message.toByteString()); + assertEquals(2, message.getSerializedSize()); + } + + // ----------------------------------------------------------------- + // Tests for isInitialized(). + + private static final TestRequired TEST_REQUIRED_UNINITIALIZED = + TestRequired.getDefaultInstance(); + private static final TestRequired TEST_REQUIRED_INITIALIZED = + TestRequired.newBuilder().setA(1).setB(2).setC(3).build(); + + public void testIsInitialized() throws Exception { + TestRequired.Builder builder = TestRequired.newBuilder(); + AbstractMessageWrapper.Builder abstractBuilder = + new AbstractMessageWrapper.Builder(builder); + + assertFalse(abstractBuilder.isInitialized()); + assertEquals("a, b, c", abstractBuilder.getInitializationErrorString()); + builder.setA(1); + assertFalse(abstractBuilder.isInitialized()); + assertEquals("b, c", abstractBuilder.getInitializationErrorString()); + builder.setB(1); + assertFalse(abstractBuilder.isInitialized()); + assertEquals("c", abstractBuilder.getInitializationErrorString()); + builder.setC(1); + assertTrue(abstractBuilder.isInitialized()); + assertEquals("", abstractBuilder.getInitializationErrorString()); + } + + public void testForeignIsInitialized() throws Exception { + TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder(); + AbstractMessageWrapper.Builder abstractBuilder = + new AbstractMessageWrapper.Builder(builder); + + assertTrue(abstractBuilder.isInitialized()); + assertEquals("", abstractBuilder.getInitializationErrorString()); + + builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED); + assertFalse(abstractBuilder.isInitialized()); + assertEquals( + "optional_message.a, optional_message.b, optional_message.c", + abstractBuilder.getInitializationErrorString()); + + builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED); + assertTrue(abstractBuilder.isInitialized()); + assertEquals("", abstractBuilder.getInitializationErrorString()); + + builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED); + assertFalse(abstractBuilder.isInitialized()); + assertEquals( + "repeated_message[0].a, repeated_message[0].b, repeated_message[0].c", + abstractBuilder.getInitializationErrorString()); + + builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED); + assertTrue(abstractBuilder.isInitialized()); + assertEquals("", abstractBuilder.getInitializationErrorString()); + } + + // ----------------------------------------------------------------- + // Tests for mergeFrom + + static final TestAllTypes MERGE_SOURCE = + TestAllTypes.newBuilder() + .setOptionalInt32(1) + .setOptionalString("foo") + .setOptionalForeignMessage(ForeignMessage.getDefaultInstance()) + .addRepeatedString("bar") + .build(); + + static final TestAllTypes MERGE_DEST = + TestAllTypes.newBuilder() + .setOptionalInt64(2) + .setOptionalString("baz") + .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build()) + .addRepeatedString("qux") + .build(); + + static final String MERGE_RESULT_TEXT = + "optional_int32: 1\n" + + "optional_int64: 2\n" + + "optional_string: \"foo\"\n" + + "optional_foreign_message {\n" + + " c: 3\n" + + "}\n" + + "repeated_string: \"qux\"\n" + + "repeated_string: \"bar\"\n"; + + public void testMergeFrom() throws Exception { + AbstractMessageWrapper result = + new AbstractMessageWrapper.Builder( + TestAllTypes.newBuilder(MERGE_DEST)) + .mergeFrom(MERGE_SOURCE).build(); + + assertEquals(MERGE_RESULT_TEXT, result.toString()); + } + + // ----------------------------------------------------------------- + // Tests for equals and hashCode + + public void testEqualsAndHashCode() throws Exception { + TestAllTypes a = TestUtil.getAllSet(); + TestAllTypes b = TestAllTypes.newBuilder().build(); + TestAllTypes c = TestAllTypes.newBuilder(b).addRepeatedString("x").build(); + TestAllTypes d = TestAllTypes.newBuilder(c).addRepeatedString("y").build(); + TestAllExtensions e = TestUtil.getAllExtensionsSet(); + TestAllExtensions f = TestAllExtensions.newBuilder(e) + .addExtension(UnittestProto.repeatedInt32Extension, 999).build(); + + checkEqualsIsConsistent(a); + checkEqualsIsConsistent(b); + checkEqualsIsConsistent(c); + checkEqualsIsConsistent(d); + checkEqualsIsConsistent(e); + checkEqualsIsConsistent(f); + + checkNotEqual(a, b); + checkNotEqual(a, c); + checkNotEqual(a, d); + checkNotEqual(a, e); + checkNotEqual(a, f); + + checkNotEqual(b, c); + checkNotEqual(b, d); + checkNotEqual(b, e); + checkNotEqual(b, f); + + checkNotEqual(c, d); + checkNotEqual(c, e); + checkNotEqual(c, f); + + checkNotEqual(d, e); + checkNotEqual(d, f); + + checkNotEqual(e, f); + + // Deserializing into the TestEmptyMessage such that every field + // is an {@link UnknownFieldSet.Field}. + UnittestProto.TestEmptyMessage eUnknownFields = + UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray()); + UnittestProto.TestEmptyMessage fUnknownFields = + UnittestProto.TestEmptyMessage.parseFrom(f.toByteArray()); + checkNotEqual(eUnknownFields, fUnknownFields); + checkEqualsIsConsistent(eUnknownFields); + checkEqualsIsConsistent(fUnknownFields); + + // Subsequent reconstitutions should be identical + UnittestProto.TestEmptyMessage eUnknownFields2 = + UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray()); + checkEqualsIsConsistent(eUnknownFields, eUnknownFields2); + } + + + /** + * Asserts that the given proto has symmetric equals and hashCode methods. + */ + private void checkEqualsIsConsistent(Message message) { + // Object should be equal to itself. + assertEquals(message, message); + + // Object should be equal to a dynamic copy of itself. + DynamicMessage dynamic = DynamicMessage.newBuilder(message).build(); + checkEqualsIsConsistent(message, dynamic); + } + + /** + * Asserts that the given protos are equal and have the same hash code. + */ + private void checkEqualsIsConsistent(Message message1, Message message2) { + assertEquals(message1, message2); + assertEquals(message2, message1); + assertEquals(message2.hashCode(), message1.hashCode()); + } + + /** + * Asserts that the given protos are not equal and have different hash codes. + * + * @warning It's valid for non-equal objects to have the same hash code, so + * this test is stricter than it needs to be. However, this should happen + * relatively rarely. + */ + private void checkNotEqual(Message m1, Message m2) { + String equalsError = String.format("%s should not be equal to %s", m1, m2); + assertFalse(equalsError, m1.equals(m2)); + assertFalse(equalsError, m2.equals(m1)); + + assertFalse( + String.format("%s should have a different hash code from %s", m1, m2), + m1.hashCode() == m2.hashCode()); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java new file mode 100644 index 0000000..20fa2df --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java @@ -0,0 +1,68 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.UnsupportedEncodingException; + +/** + * This class tests {@link BoundedByteString}, which extends {@link LiteralByteString}, + * by inheriting the tests from {@link LiteralByteStringTest}. The only method which + * is strange enough that it needs to be overridden here is {@link #testToString()}. + * + * @author carlanton@google.com (Carl Haverl) + */ +public class BoundedByteStringTest extends LiteralByteStringTest { + + @Override + protected void setUp() throws Exception { + classUnderTest = "BoundedByteString"; + byte[] sourceBytes = ByteStringTest.getTestBytes(2341, 11337766L); + int from = 100; + int to = sourceBytes.length - 100; + stringUnderTest = ByteString.copyFrom(sourceBytes).substring(from, to); + referenceBytes = new byte[to - from]; + System.arraycopy(sourceBytes, from, referenceBytes, 0, to - from); + expectedHashCode = 727575887; + } + + @Override + public void testToString() throws UnsupportedEncodingException { + String testString = "I love unicode \u1234\u5678 characters"; + LiteralByteString unicode = new LiteralByteString(testString.getBytes(UTF_8)); + ByteString chopped = unicode.substring(2, unicode.size() - 6); + assertEquals(classUnderTest + ".substring() must have the expected type", + classUnderTest, getActualClassName(chopped)); + + String roundTripString = chopped.toString(UTF_8); + assertEquals(classUnderTest + " unicode bytes must match", + testString.substring(2, testString.length() - 6), roundTripString); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ByteStringTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ByteStringTest.java new file mode 100644 index 0000000..7a1d682 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ByteStringTest.java @@ -0,0 +1,692 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.ByteString.Output; + +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Random; + +/** + * Test methods with implementations in {@link ByteString}, plus do some top-level "integration" + * tests. + * + * @author carlanton@google.com (Carl Haverl) + */ +public class ByteStringTest extends TestCase { + + private static final String UTF_16 = "UTF-16"; + + static byte[] getTestBytes(int size, long seed) { + Random random = new Random(seed); + byte[] result = new byte[size]; + random.nextBytes(result); + return result; + } + + private byte[] getTestBytes(int size) { + return getTestBytes(size, 445566L); + } + + private byte[] getTestBytes() { + return getTestBytes(1000); + } + + // Compare the entire left array with a subset of the right array. + private boolean isArrayRange(byte[] left, byte[] right, int rightOffset, int length) { + boolean stillEqual = (left.length == length); + for (int i = 0; (stillEqual && i < length); ++i) { + stillEqual = (left[i] == right[rightOffset + i]); + } + return stillEqual; + } + + // Returns true only if the given two arrays have identical contents. + private boolean isArray(byte[] left, byte[] right) { + return left.length == right.length && isArrayRange(left, right, 0, left.length); + } + + public void testSubstring_BeginIndex() { + byte[] bytes = getTestBytes(); + ByteString substring = ByteString.copyFrom(bytes).substring(500); + assertTrue("substring must contain the tail of the string", + isArrayRange(substring.toByteArray(), bytes, 500, bytes.length - 500)); + } + + public void testCopyFrom_BytesOffsetSize() { + byte[] bytes = getTestBytes(); + ByteString byteString = ByteString.copyFrom(bytes, 500, 200); + assertTrue("copyFrom sub-range must contain the expected bytes", + isArrayRange(byteString.toByteArray(), bytes, 500, 200)); + } + + public void testCopyFrom_Bytes() { + byte[] bytes = getTestBytes(); + ByteString byteString = ByteString.copyFrom(bytes); + assertTrue("copyFrom must contain the expected bytes", + isArray(byteString.toByteArray(), bytes)); + } + + public void testCopyFrom_ByteBufferSize() { + byte[] bytes = getTestBytes(); + ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length); + byteBuffer.put(bytes); + byteBuffer.position(500); + ByteString byteString = ByteString.copyFrom(byteBuffer, 200); + assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes", + isArrayRange(byteString.toByteArray(), bytes, 500, 200)); + } + + public void testCopyFrom_ByteBuffer() { + byte[] bytes = getTestBytes(); + ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length); + byteBuffer.put(bytes); + byteBuffer.position(500); + ByteString byteString = ByteString.copyFrom(byteBuffer); + assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes", + isArrayRange(byteString.toByteArray(), bytes, 500, bytes.length - 500)); + } + + public void testCopyFrom_StringEncoding() throws UnsupportedEncodingException { + String testString = "I love unicode \u1234\u5678 characters"; + ByteString byteString = ByteString.copyFrom(testString, UTF_16); + byte[] testBytes = testString.getBytes(UTF_16); + assertTrue("copyFrom string must respect the charset", + isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length)); + } + + public void testCopyFrom_Utf8() throws UnsupportedEncodingException { + String testString = "I love unicode \u1234\u5678 characters"; + ByteString byteString = ByteString.copyFromUtf8(testString); + byte[] testBytes = testString.getBytes("UTF-8"); + assertTrue("copyFromUtf8 string must respect the charset", + isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length)); + } + + public void testCopyFrom_Iterable() { + byte[] testBytes = getTestBytes(77777, 113344L); + final List pieces = makeConcretePieces(testBytes); + // Call copyFrom() on a Collection + ByteString byteString = ByteString.copyFrom(pieces); + assertTrue("copyFrom a List must contain the expected bytes", + isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length)); + // Call copyFrom on an iteration that's not a collection + ByteString byteStringAlt = ByteString.copyFrom(new Iterable() { + public Iterator iterator() { + return pieces.iterator(); + } + }); + assertEquals("copyFrom from an Iteration must contain the expected bytes", + byteString, byteStringAlt); + } + + public void testCopyTo_TargetOffset() { + byte[] bytes = getTestBytes(); + ByteString byteString = ByteString.copyFrom(bytes); + byte[] target = new byte[bytes.length + 1000]; + byteString.copyTo(target, 400); + assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes", + isArrayRange(bytes, target, 400, bytes.length)); + } + + public void testReadFrom_emptyStream() throws IOException { + ByteString byteString = + ByteString.readFrom(new ByteArrayInputStream(new byte[0])); + assertSame("reading an empty stream must result in the EMPTY constant " + + "byte string", ByteString.EMPTY, byteString); + } + + public void testReadFrom_smallStream() throws IOException { + assertReadFrom(getTestBytes(10)); + } + + public void testReadFrom_mutating() throws IOException { + byte[] capturedArray = null; + EvilInputStream eis = new EvilInputStream(); + ByteString byteString = ByteString.readFrom(eis); + + capturedArray = eis.capturedArray; + byte[] originalValue = byteString.toByteArray(); + for (int x = 0; x < capturedArray.length; ++x) { + capturedArray[x] = (byte) 0; + } + + byte[] newValue = byteString.toByteArray(); + assertTrue("copyFrom byteBuffer must not grant access to underlying array", + Arrays.equals(originalValue, newValue)); + } + + // Tests sizes that are near the rope copy-out threshold. + public void testReadFrom_mediumStream() throws IOException { + assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE - 1)); + assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE)); + assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE + 1)); + assertReadFrom(getTestBytes(200)); + } + + // Tests sizes that are over multi-segment rope threshold. + public void testReadFrom_largeStream() throws IOException { + assertReadFrom(getTestBytes(0x100)); + assertReadFrom(getTestBytes(0x101)); + assertReadFrom(getTestBytes(0x110)); + assertReadFrom(getTestBytes(0x1000)); + assertReadFrom(getTestBytes(0x1001)); + assertReadFrom(getTestBytes(0x1010)); + assertReadFrom(getTestBytes(0x10000)); + assertReadFrom(getTestBytes(0x10001)); + assertReadFrom(getTestBytes(0x10010)); + } + + // Tests sizes that are near the read buffer size. + public void testReadFrom_byteBoundaries() throws IOException { + final int min = ByteString.MIN_READ_FROM_CHUNK_SIZE; + final int max = ByteString.MAX_READ_FROM_CHUNK_SIZE; + + assertReadFrom(getTestBytes(min - 1)); + assertReadFrom(getTestBytes(min)); + assertReadFrom(getTestBytes(min + 1)); + + assertReadFrom(getTestBytes(min * 2 - 1)); + assertReadFrom(getTestBytes(min * 2)); + assertReadFrom(getTestBytes(min * 2 + 1)); + + assertReadFrom(getTestBytes(min * 4 - 1)); + assertReadFrom(getTestBytes(min * 4)); + assertReadFrom(getTestBytes(min * 4 + 1)); + + assertReadFrom(getTestBytes(min * 8 - 1)); + assertReadFrom(getTestBytes(min * 8)); + assertReadFrom(getTestBytes(min * 8 + 1)); + + assertReadFrom(getTestBytes(max - 1)); + assertReadFrom(getTestBytes(max)); + assertReadFrom(getTestBytes(max + 1)); + + assertReadFrom(getTestBytes(max * 2 - 1)); + assertReadFrom(getTestBytes(max * 2)); + assertReadFrom(getTestBytes(max * 2 + 1)); + } + + // Tests that IOExceptions propagate through ByteString.readFrom(). + public void testReadFrom_IOExceptions() { + try { + ByteString.readFrom(new FailStream()); + fail("readFrom must throw the underlying IOException"); + + } catch (IOException e) { + assertEquals("readFrom must throw the expected exception", + "synthetic failure", e.getMessage()); + } + } + + // Tests that ByteString.readFrom works with streams that don't + // always fill their buffers. + public void testReadFrom_reluctantStream() throws IOException { + final byte[] data = getTestBytes(0x1000); + + ByteString byteString = ByteString.readFrom(new ReluctantStream(data)); + assertTrue("readFrom byte stream must contain the expected bytes", + isArray(byteString.toByteArray(), data)); + + // Same test as above, but with some specific chunk sizes. + assertReadFromReluctantStream(data, 100); + assertReadFromReluctantStream(data, 248); + assertReadFromReluctantStream(data, 249); + assertReadFromReluctantStream(data, 250); + assertReadFromReluctantStream(data, 251); + assertReadFromReluctantStream(data, 0x1000); + assertReadFromReluctantStream(data, 0x1001); + } + + // Fails unless ByteString.readFrom reads the bytes correctly from a + // reluctant stream with the given chunkSize parameter. + private void assertReadFromReluctantStream(byte[] bytes, int chunkSize) + throws IOException { + ByteString b = ByteString.readFrom(new ReluctantStream(bytes), chunkSize); + assertTrue("readFrom byte stream must contain the expected bytes", + isArray(b.toByteArray(), bytes)); + } + + // Tests that ByteString.readFrom works with streams that implement + // available(). + public void testReadFrom_available() throws IOException { + final byte[] data = getTestBytes(0x1001); + + ByteString byteString = ByteString.readFrom(new AvailableStream(data)); + assertTrue("readFrom byte stream must contain the expected bytes", + isArray(byteString.toByteArray(), data)); + } + + // Fails unless ByteString.readFrom reads the bytes correctly. + private void assertReadFrom(byte[] bytes) throws IOException { + ByteString byteString = + ByteString.readFrom(new ByteArrayInputStream(bytes)); + assertTrue("readFrom byte stream must contain the expected bytes", + isArray(byteString.toByteArray(), bytes)); + } + + // A stream that fails when read. + private static final class FailStream extends InputStream { + @Override public int read() throws IOException { + throw new IOException("synthetic failure"); + } + } + + // A stream that simulates blocking by only producing 250 characters + // per call to read(byte[]). + private static class ReluctantStream extends InputStream { + protected final byte[] data; + protected int pos = 0; + + public ReluctantStream(byte[] data) { + this.data = data; + } + + @Override public int read() { + if (pos == data.length) { + return -1; + } else { + return data[pos++]; + } + } + + @Override public int read(byte[] buf) { + return read(buf, 0, buf.length); + } + + @Override public int read(byte[] buf, int offset, int size) { + if (pos == data.length) { + return -1; + } + int count = Math.min(Math.min(size, data.length - pos), 250); + System.arraycopy(data, pos, buf, offset, count); + pos += count; + return count; + } + } + + // Same as above, but also implements available(). + private static final class AvailableStream extends ReluctantStream { + public AvailableStream(byte[] data) { + super(data); + } + + @Override public int available() { + return Math.min(250, data.length - pos); + } + } + + // A stream which exposes the byte array passed into read(byte[], int, int). + private static class EvilInputStream extends InputStream { + public byte[] capturedArray = null; + + @Override + public int read(byte[] buf, int off, int len) { + if (capturedArray != null) { + return -1; + } else { + capturedArray = buf; + for (int x = 0; x < len; ++x) { + buf[x] = (byte) x; + } + return len; + } + } + + @Override + public int read() { + // Purposefully do nothing. + return -1; + } + } + + // A stream which exposes the byte array passed into write(byte[], int, int). + private static class EvilOutputStream extends OutputStream { + public byte[] capturedArray = null; + + @Override + public void write(byte[] buf, int off, int len) { + if (capturedArray == null) { + capturedArray = buf; + } + } + + @Override + public void write(int ignored) { + // Purposefully do nothing. + } + } + + public void testToStringUtf8() throws UnsupportedEncodingException { + String testString = "I love unicode \u1234\u5678 characters"; + byte[] testBytes = testString.getBytes("UTF-8"); + ByteString byteString = ByteString.copyFrom(testBytes); + assertEquals("copyToStringUtf8 must respect the charset", + testString, byteString.toStringUtf8()); + } + + public void testNewOutput_InitialCapacity() throws IOException { + byte[] bytes = getTestBytes(); + ByteString.Output output = ByteString.newOutput(bytes.length + 100); + output.write(bytes); + ByteString byteString = output.toByteString(); + assertTrue( + "String built from newOutput(int) must contain the expected bytes", + isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)); + } + + // Test newOutput() using a variety of buffer sizes and a variety of (fixed) + // write sizes + public void testNewOutput_ArrayWrite() throws IOException { + byte[] bytes = getTestBytes(); + int length = bytes.length; + int[] bufferSizes = {128, 256, length / 2, length - 1, length, length + 1, + 2 * length, 3 * length}; + int[] writeSizes = {1, 4, 5, 7, 23, bytes.length}; + + for (int bufferSize : bufferSizes) { + for (int writeSize : writeSizes) { + // Test writing the entire output writeSize bytes at a time. + ByteString.Output output = ByteString.newOutput(bufferSize); + for (int i = 0; i < length; i += writeSize) { + output.write(bytes, i, Math.min(writeSize, length - i)); + } + ByteString byteString = output.toByteString(); + assertTrue("String built from newOutput() must contain the expected bytes", + isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)); + } + } + } + + // Test newOutput() using a variety of buffer sizes, but writing all the + // characters using write(byte); + public void testNewOutput_WriteChar() throws IOException { + byte[] bytes = getTestBytes(); + int length = bytes.length; + int[] bufferSizes = {0, 1, 128, 256, length / 2, + length - 1, length, length + 1, + 2 * length, 3 * length}; + for (int bufferSize : bufferSizes) { + ByteString.Output output = ByteString.newOutput(bufferSize); + for (byte byteValue : bytes) { + output.write(byteValue); + } + ByteString byteString = output.toByteString(); + assertTrue("String built from newOutput() must contain the expected bytes", + isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)); + } + } + + // Test newOutput() in which we write the bytes using a variety of methods + // and sizes, and in which we repeatedly call toByteString() in the middle. + public void testNewOutput_Mixed() throws IOException { + Random rng = new Random(1); + byte[] bytes = getTestBytes(); + int length = bytes.length; + int[] bufferSizes = {0, 1, 128, 256, length / 2, + length - 1, length, length + 1, + 2 * length, 3 * length}; + + for (int bufferSize : bufferSizes) { + // Test writing the entire output using a mixture of write sizes and + // methods; + ByteString.Output output = ByteString.newOutput(bufferSize); + int position = 0; + while (position < bytes.length) { + if (rng.nextBoolean()) { + int count = 1 + rng.nextInt(bytes.length - position); + output.write(bytes, position, count); + position += count; + } else { + output.write(bytes[position]); + position++; + } + assertEquals("size() returns the right value", position, output.size()); + assertTrue("newOutput() substring must have correct bytes", + isArrayRange(output.toByteString().toByteArray(), + bytes, 0, position)); + } + ByteString byteString = output.toByteString(); + assertTrue("String built from newOutput() must contain the expected bytes", + isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)); + } + } + + public void testNewOutputEmpty() throws IOException { + // Make sure newOutput() correctly builds empty byte strings + ByteString byteString = ByteString.newOutput().toByteString(); + assertEquals(ByteString.EMPTY, byteString); + } + + public void testNewOutput_Mutating() throws IOException { + Output os = ByteString.newOutput(5); + os.write(new byte[] {1, 2, 3, 4, 5}); + EvilOutputStream eos = new EvilOutputStream(); + os.writeTo(eos); + byte[] capturedArray = eos.capturedArray; + ByteString byteString = os.toByteString(); + byte[] oldValue = byteString.toByteArray(); + Arrays.fill(capturedArray, (byte) 0); + byte[] newValue = byteString.toByteArray(); + assertTrue("Output must not provide access to the underlying byte array", + Arrays.equals(oldValue, newValue)); + } + + public void testNewCodedBuilder() throws IOException { + byte[] bytes = getTestBytes(); + ByteString.CodedBuilder builder = ByteString.newCodedBuilder(bytes.length); + builder.getCodedOutput().writeRawBytes(bytes); + ByteString byteString = builder.build(); + assertTrue("String built from newCodedBuilder() must contain the expected bytes", + isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)); + } + + public void testSubstringParity() { + byte[] bigBytes = getTestBytes(2048 * 1024, 113344L); + int start = 512 * 1024 - 3333; + int end = 512 * 1024 + 7777; + ByteString concreteSubstring = ByteString.copyFrom(bigBytes).substring(start, end); + boolean ok = true; + for (int i = start; ok && i < end; ++i) { + ok = (bigBytes[i] == concreteSubstring.byteAt(i - start)); + } + assertTrue("Concrete substring didn't capture the right bytes", ok); + + ByteString literalString = ByteString.copyFrom(bigBytes, start, end - start); + assertTrue("Substring must be equal to literal string", + concreteSubstring.equals(literalString)); + assertEquals("Substring must have same hashcode as literal string", + literalString.hashCode(), concreteSubstring.hashCode()); + } + + public void testCompositeSubstring() { + byte[] referenceBytes = getTestBytes(77748, 113344L); + + List pieces = makeConcretePieces(referenceBytes); + ByteString listString = ByteString.copyFrom(pieces); + + int from = 1000; + int to = 40000; + ByteString compositeSubstring = listString.substring(from, to); + byte[] substringBytes = compositeSubstring.toByteArray(); + boolean stillEqual = true; + for (int i = 0; stillEqual && i < to - from; ++i) { + stillEqual = referenceBytes[from + i] == substringBytes[i]; + } + assertTrue("Substring must return correct bytes", stillEqual); + + stillEqual = true; + for (int i = 0; stillEqual && i < to - from; ++i) { + stillEqual = referenceBytes[from + i] == compositeSubstring.byteAt(i); + } + assertTrue("Substring must support byteAt() correctly", stillEqual); + + ByteString literalSubstring = ByteString.copyFrom(referenceBytes, from, to - from); + assertTrue("Composite substring must equal a literal substring over the same bytes", + compositeSubstring.equals(literalSubstring)); + assertTrue("Literal substring must equal a composite substring over the same bytes", + literalSubstring.equals(compositeSubstring)); + + assertEquals("We must get the same hashcodes for composite and literal substrings", + literalSubstring.hashCode(), compositeSubstring.hashCode()); + + assertFalse("We can't be equal to a proper substring", + compositeSubstring.equals(literalSubstring.substring(0, literalSubstring.size() - 1))); + } + + public void testCopyFromList() { + byte[] referenceBytes = getTestBytes(77748, 113344L); + ByteString literalString = ByteString.copyFrom(referenceBytes); + + List pieces = makeConcretePieces(referenceBytes); + ByteString listString = ByteString.copyFrom(pieces); + + assertTrue("Composite string must be equal to literal string", + listString.equals(literalString)); + assertEquals("Composite string must have same hashcode as literal string", + literalString.hashCode(), listString.hashCode()); + } + + public void testConcat() { + byte[] referenceBytes = getTestBytes(77748, 113344L); + ByteString literalString = ByteString.copyFrom(referenceBytes); + + List pieces = makeConcretePieces(referenceBytes); + + Iterator iter = pieces.iterator(); + ByteString concatenatedString = iter.next(); + while (iter.hasNext()) { + concatenatedString = concatenatedString.concat(iter.next()); + } + + assertTrue("Concatenated string must be equal to literal string", + concatenatedString.equals(literalString)); + assertEquals("Concatenated string must have same hashcode as literal string", + literalString.hashCode(), concatenatedString.hashCode()); + } + + /** + * Test the Rope implementation can deal with Empty nodes, even though we + * guard against them. See also {@link LiteralByteStringTest#testConcat_empty()}. + */ + public void testConcat_empty() { + byte[] referenceBytes = getTestBytes(7748, 113344L); + ByteString literalString = ByteString.copyFrom(referenceBytes); + + ByteString duo = RopeByteString.newInstanceForTest(literalString, literalString); + ByteString temp = RopeByteString.newInstanceForTest( + RopeByteString.newInstanceForTest(literalString, ByteString.EMPTY), + RopeByteString.newInstanceForTest(ByteString.EMPTY, literalString)); + ByteString quintet = RopeByteString.newInstanceForTest(temp, ByteString.EMPTY); + + assertTrue("String with concatenated nulls must equal simple concatenate", + duo.equals(quintet)); + assertEquals("String with concatenated nulls have same hashcode as simple concatenate", + duo.hashCode(), quintet.hashCode()); + + ByteString.ByteIterator duoIter = duo.iterator(); + ByteString.ByteIterator quintetIter = quintet.iterator(); + boolean stillEqual = true; + while (stillEqual && quintetIter.hasNext()) { + stillEqual = (duoIter.nextByte() == quintetIter.nextByte()); + } + assertTrue("We must get the same characters by iterating", stillEqual); + assertFalse("Iterator must be exhausted", duoIter.hasNext()); + try { + duoIter.nextByte(); + fail("Should have thrown an exception."); + } catch (NoSuchElementException e) { + // This is success + } + try { + quintetIter.nextByte(); + fail("Should have thrown an exception."); + } catch (NoSuchElementException e) { + // This is success + } + + // Test that even if we force empty strings in as rope leaves in this + // configuration, we always get a (possibly Bounded) LiteralByteString + // for a length 1 substring. + // + // It is possible, using the testing factory method to create deeply nested + // trees of empty leaves, to make a string that will fail this test. + for (int i = 1; i < duo.size(); ++i) { + assertTrue("Substrings of size() < 2 must not be RopeByteStrings", + duo.substring(i - 1, i) instanceof LiteralByteString); + } + for (int i = 1; i < quintet.size(); ++i) { + assertTrue("Substrings of size() < 2 must not be RopeByteStrings", + quintet.substring(i - 1, i) instanceof LiteralByteString); + } + } + + public void testStartsWith() { + byte[] bytes = getTestBytes(1000, 1234L); + ByteString string = ByteString.copyFrom(bytes); + ByteString prefix = ByteString.copyFrom(bytes, 0, 500); + ByteString suffix = ByteString.copyFrom(bytes, 400, 600); + assertTrue(string.startsWith(ByteString.EMPTY)); + assertTrue(string.startsWith(string)); + assertTrue(string.startsWith(prefix)); + assertFalse(string.startsWith(suffix)); + assertFalse(prefix.startsWith(suffix)); + assertFalse(suffix.startsWith(prefix)); + assertFalse(ByteString.EMPTY.startsWith(prefix)); + assertTrue(ByteString.EMPTY.startsWith(ByteString.EMPTY)); + } + + static List makeConcretePieces(byte[] referenceBytes) { + List pieces = new ArrayList(); + // Starting length should be small enough that we'll do some concatenating by + // copying if we just concatenate all these pieces together. + for (int start = 0, length = 16; start < referenceBytes.length; start += length) { + length = (length << 1) - 1; + if (start + length > referenceBytes.length) { + length = referenceBytes.length - start; + } + pieces.add(ByteString.copyFrom(referenceBytes, start, length)); + } + return pieces; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java new file mode 100644 index 0000000..83f7f8d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java @@ -0,0 +1,528 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestRecursiveMessage; + +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.FilterInputStream; +import java.io.InputStream; +import java.io.IOException; + +/** + * Unit test for {@link CodedInputStream}. + * + * @author kenton@google.com Kenton Varda + */ +public class CodedInputStreamTest extends TestCase { + /** + * Helper to construct a byte array from a bunch of bytes. The inputs are + * actually ints so that I can use hex notation and not get stupid errors + * about precision. + */ + private byte[] bytes(int... bytesAsInts) { + byte[] bytes = new byte[bytesAsInts.length]; + for (int i = 0; i < bytesAsInts.length; i++) { + bytes[i] = (byte) bytesAsInts[i]; + } + return bytes; + } + + /** + * An InputStream which limits the number of bytes it reads at a time. + * We use this to make sure that CodedInputStream doesn't screw up when + * reading in small blocks. + */ + private static final class SmallBlockInputStream extends FilterInputStream { + private final int blockSize; + + public SmallBlockInputStream(byte[] data, int blockSize) { + this(new ByteArrayInputStream(data), blockSize); + } + + public SmallBlockInputStream(InputStream in, int blockSize) { + super(in); + this.blockSize = blockSize; + } + + public int read(byte[] b) throws IOException { + return super.read(b, 0, Math.min(b.length, blockSize)); + } + + public int read(byte[] b, int off, int len) throws IOException { + return super.read(b, off, Math.min(len, blockSize)); + } + } + + /** + * Parses the given bytes using readRawVarint32() and readRawVarint64() and + * checks that the result matches the given value. + */ + private void assertReadVarint(byte[] data, long value) throws Exception { + CodedInputStream input = CodedInputStream.newInstance(data); + assertEquals((int)value, input.readRawVarint32()); + + input = CodedInputStream.newInstance(data); + assertEquals(value, input.readRawVarint64()); + assertTrue(input.isAtEnd()); + + // Try different block sizes. + for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { + input = CodedInputStream.newInstance( + new SmallBlockInputStream(data, blockSize)); + assertEquals((int)value, input.readRawVarint32()); + + input = CodedInputStream.newInstance( + new SmallBlockInputStream(data, blockSize)); + assertEquals(value, input.readRawVarint64()); + assertTrue(input.isAtEnd()); + } + + // Try reading direct from an InputStream. We want to verify that it + // doesn't read past the end of the input, so we copy to a new, bigger + // array first. + byte[] longerData = new byte[data.length + 1]; + System.arraycopy(data, 0, longerData, 0, data.length); + InputStream rawInput = new ByteArrayInputStream(longerData); + assertEquals((int)value, CodedInputStream.readRawVarint32(rawInput)); + assertEquals(1, rawInput.available()); + } + + /** + * Parses the given bytes using readRawVarint32() and readRawVarint64() and + * expects them to fail with an InvalidProtocolBufferException whose + * description matches the given one. + */ + private void assertReadVarintFailure( + InvalidProtocolBufferException expected, byte[] data) + throws Exception { + CodedInputStream input = CodedInputStream.newInstance(data); + try { + input.readRawVarint32(); + fail("Should have thrown an exception."); + } catch (InvalidProtocolBufferException e) { + assertEquals(expected.getMessage(), e.getMessage()); + } + + input = CodedInputStream.newInstance(data); + try { + input.readRawVarint64(); + fail("Should have thrown an exception."); + } catch (InvalidProtocolBufferException e) { + assertEquals(expected.getMessage(), e.getMessage()); + } + + // Make sure we get the same error when reading direct from an InputStream. + try { + CodedInputStream.readRawVarint32(new ByteArrayInputStream(data)); + fail("Should have thrown an exception."); + } catch (InvalidProtocolBufferException e) { + assertEquals(expected.getMessage(), e.getMessage()); + } + } + + /** Tests readRawVarint32() and readRawVarint64(). */ + public void testReadVarint() throws Exception { + assertReadVarint(bytes(0x00), 0); + assertReadVarint(bytes(0x01), 1); + assertReadVarint(bytes(0x7f), 127); + // 14882 + assertReadVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7)); + // 2961488830 + assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b), + (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | + (0x0bL << 28)); + + // 64-bit + // 7256456126 + assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b), + (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | + (0x1bL << 28)); + // 41256202580718336 + assertReadVarint( + bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49), + (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) | + (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49)); + // 11964378330978735131 + assertReadVarint( + bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01), + (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) | + (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) | + (0x05L << 49) | (0x26L << 56) | (0x01L << 63)); + + // Failures + assertReadVarintFailure( + InvalidProtocolBufferException.malformedVarint(), + bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x00)); + assertReadVarintFailure( + InvalidProtocolBufferException.truncatedMessage(), + bytes(0x80)); + } + + /** + * Parses the given bytes using readRawLittleEndian32() and checks + * that the result matches the given value. + */ + private void assertReadLittleEndian32(byte[] data, int value) + throws Exception { + CodedInputStream input = CodedInputStream.newInstance(data); + assertEquals(value, input.readRawLittleEndian32()); + assertTrue(input.isAtEnd()); + + // Try different block sizes. + for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { + input = CodedInputStream.newInstance( + new SmallBlockInputStream(data, blockSize)); + assertEquals(value, input.readRawLittleEndian32()); + assertTrue(input.isAtEnd()); + } + } + + /** + * Parses the given bytes using readRawLittleEndian64() and checks + * that the result matches the given value. + */ + private void assertReadLittleEndian64(byte[] data, long value) + throws Exception { + CodedInputStream input = CodedInputStream.newInstance(data); + assertEquals(value, input.readRawLittleEndian64()); + assertTrue(input.isAtEnd()); + + // Try different block sizes. + for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { + input = CodedInputStream.newInstance( + new SmallBlockInputStream(data, blockSize)); + assertEquals(value, input.readRawLittleEndian64()); + assertTrue(input.isAtEnd()); + } + } + + /** Tests readRawLittleEndian32() and readRawLittleEndian64(). */ + public void testReadLittleEndian() throws Exception { + assertReadLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678); + assertReadLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0); + + assertReadLittleEndian64( + bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12), + 0x123456789abcdef0L); + assertReadLittleEndian64( + bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), + 0x9abcdef012345678L); + } + + /** Test decodeZigZag32() and decodeZigZag64(). */ + public void testDecodeZigZag() throws Exception { + assertEquals( 0, CodedInputStream.decodeZigZag32(0)); + assertEquals(-1, CodedInputStream.decodeZigZag32(1)); + assertEquals( 1, CodedInputStream.decodeZigZag32(2)); + assertEquals(-2, CodedInputStream.decodeZigZag32(3)); + assertEquals(0x3FFFFFFF, CodedInputStream.decodeZigZag32(0x7FFFFFFE)); + assertEquals(0xC0000000, CodedInputStream.decodeZigZag32(0x7FFFFFFF)); + assertEquals(0x7FFFFFFF, CodedInputStream.decodeZigZag32(0xFFFFFFFE)); + assertEquals(0x80000000, CodedInputStream.decodeZigZag32(0xFFFFFFFF)); + + assertEquals( 0, CodedInputStream.decodeZigZag64(0)); + assertEquals(-1, CodedInputStream.decodeZigZag64(1)); + assertEquals( 1, CodedInputStream.decodeZigZag64(2)); + assertEquals(-2, CodedInputStream.decodeZigZag64(3)); + assertEquals(0x000000003FFFFFFFL, + CodedInputStream.decodeZigZag64(0x000000007FFFFFFEL)); + assertEquals(0xFFFFFFFFC0000000L, + CodedInputStream.decodeZigZag64(0x000000007FFFFFFFL)); + assertEquals(0x000000007FFFFFFFL, + CodedInputStream.decodeZigZag64(0x00000000FFFFFFFEL)); + assertEquals(0xFFFFFFFF80000000L, + CodedInputStream.decodeZigZag64(0x00000000FFFFFFFFL)); + assertEquals(0x7FFFFFFFFFFFFFFFL, + CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFEL)); + assertEquals(0x8000000000000000L, + CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFFL)); + } + + /** Tests reading and parsing a whole message with every field type. */ + public void testReadWholeMessage() throws Exception { + TestAllTypes message = TestUtil.getAllSet(); + + byte[] rawBytes = message.toByteArray(); + assertEquals(rawBytes.length, message.getSerializedSize()); + + TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); + TestUtil.assertAllFieldsSet(message2); + + // Try different block sizes. + for (int blockSize = 1; blockSize < 256; blockSize *= 2) { + message2 = TestAllTypes.parseFrom( + new SmallBlockInputStream(rawBytes, blockSize)); + TestUtil.assertAllFieldsSet(message2); + } + } + + /** Tests skipField(). */ + public void testSkipWholeMessage() throws Exception { + TestAllTypes message = TestUtil.getAllSet(); + byte[] rawBytes = message.toByteArray(); + + // Create two parallel inputs. Parse one as unknown fields while using + // skipField() to skip each field on the other. Expect the same tags. + CodedInputStream input1 = CodedInputStream.newInstance(rawBytes); + CodedInputStream input2 = CodedInputStream.newInstance(rawBytes); + UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); + + while (true) { + int tag = input1.readTag(); + assertEquals(tag, input2.readTag()); + if (tag == 0) { + break; + } + unknownFields.mergeFieldFrom(tag, input1); + input2.skipField(tag); + } + } + + /** + * Test that a bug in skipRawBytes() has been fixed: if the skip skips + * exactly up to a limit, this should not break things. + */ + public void testSkipRawBytesBug() throws Exception { + byte[] rawBytes = new byte[] { 1, 2 }; + CodedInputStream input = CodedInputStream.newInstance(rawBytes); + + int limit = input.pushLimit(1); + input.skipRawBytes(1); + input.popLimit(limit); + assertEquals(2, input.readRawByte()); + } + + /** + * Test that a bug in skipRawBytes() has been fixed: if the skip skips + * past the end of a buffer with a limit that has been set past the end of + * that buffer, this should not break things. + */ + public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception { + byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 }; + CodedInputStream input = CodedInputStream.newInstance( + new SmallBlockInputStream(rawBytes, 3)); + + int limit = input.pushLimit(4); + // In order to expose the bug we need to read at least one byte to prime the + // buffer inside the CodedInputStream. + assertEquals(1, input.readRawByte()); + // Skip to the end of the limit. + input.skipRawBytes(3); + assertTrue(input.isAtEnd()); + input.popLimit(limit); + assertEquals(5, input.readRawByte()); + } + + public void testReadHugeBlob() throws Exception { + // Allocate and initialize a 1MB blob. + byte[] blob = new byte[1 << 20]; + for (int i = 0; i < blob.length; i++) { + blob[i] = (byte)i; + } + + // Make a message containing it. + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestUtil.setAllFields(builder); + builder.setOptionalBytes(ByteString.copyFrom(blob)); + TestAllTypes message = builder.build(); + + // Serialize and parse it. Make sure to parse from an InputStream, not + // directly from a ByteString, so that CodedInputStream uses buffered + // reading. + TestAllTypes message2 = + TestAllTypes.parseFrom(message.toByteString().newInput()); + + assertEquals(message.getOptionalBytes(), message2.getOptionalBytes()); + + // Make sure all the other fields were parsed correctly. + TestAllTypes message3 = TestAllTypes.newBuilder(message2) + .setOptionalBytes(TestUtil.getAllSet().getOptionalBytes()) + .build(); + TestUtil.assertAllFieldsSet(message3); + } + + public void testReadMaliciouslyLargeBlob() throws Exception { + ByteString.Output rawOutput = ByteString.newOutput(); + CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); + + int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); + output.writeRawVarint32(tag); + output.writeRawVarint32(0x7FFFFFFF); + output.writeRawBytes(new byte[32]); // Pad with a few random bytes. + output.flush(); + + CodedInputStream input = rawOutput.toByteString().newCodedInput(); + assertEquals(tag, input.readTag()); + + try { + input.readBytes(); + fail("Should have thrown an exception!"); + } catch (InvalidProtocolBufferException e) { + // success. + } + } + + private TestRecursiveMessage makeRecursiveMessage(int depth) { + if (depth == 0) { + return TestRecursiveMessage.newBuilder().setI(5).build(); + } else { + return TestRecursiveMessage.newBuilder() + .setA(makeRecursiveMessage(depth - 1)).build(); + } + } + + private void assertMessageDepth(TestRecursiveMessage message, int depth) { + if (depth == 0) { + assertFalse(message.hasA()); + assertEquals(5, message.getI()); + } else { + assertTrue(message.hasA()); + assertMessageDepth(message.getA(), depth - 1); + } + } + + public void testMaliciousRecursion() throws Exception { + ByteString data64 = makeRecursiveMessage(64).toByteString(); + ByteString data65 = makeRecursiveMessage(65).toByteString(); + + assertMessageDepth(TestRecursiveMessage.parseFrom(data64), 64); + + try { + TestRecursiveMessage.parseFrom(data65); + fail("Should have thrown an exception!"); + } catch (InvalidProtocolBufferException e) { + // success. + } + + CodedInputStream input = data64.newCodedInput(); + input.setRecursionLimit(8); + try { + TestRecursiveMessage.parseFrom(input); + fail("Should have thrown an exception!"); + } catch (InvalidProtocolBufferException e) { + // success. + } + } + + public void testSizeLimit() throws Exception { + CodedInputStream input = CodedInputStream.newInstance( + TestUtil.getAllSet().toByteString().newInput()); + input.setSizeLimit(16); + + try { + TestAllTypes.parseFrom(input); + fail("Should have thrown an exception!"); + } catch (InvalidProtocolBufferException e) { + // success. + } + } + + public void testResetSizeCounter() throws Exception { + CodedInputStream input = CodedInputStream.newInstance( + new SmallBlockInputStream(new byte[256], 8)); + input.setSizeLimit(16); + input.readRawBytes(16); + assertEquals(16, input.getTotalBytesRead()); + + try { + input.readRawByte(); + fail("Should have thrown an exception!"); + } catch (InvalidProtocolBufferException e) { + // success. + } + + input.resetSizeCounter(); + assertEquals(0, input.getTotalBytesRead()); + input.readRawByte(); // No exception thrown. + input.resetSizeCounter(); + assertEquals(0, input.getTotalBytesRead()); + + try { + input.readRawBytes(16); // Hits limit again. + fail("Should have thrown an exception!"); + } catch (InvalidProtocolBufferException e) { + // success. + } + } + + /** + * Tests that if we read an string that contains invalid UTF-8, no exception + * is thrown. Instead, the invalid bytes are replaced with the Unicode + * "replacement character" U+FFFD. + */ + public void testReadInvalidUtf8() throws Exception { + ByteString.Output rawOutput = ByteString.newOutput(); + CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); + + int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); + output.writeRawVarint32(tag); + output.writeRawVarint32(1); + output.writeRawBytes(new byte[] { (byte)0x80 }); + output.flush(); + + CodedInputStream input = rawOutput.toByteString().newCodedInput(); + assertEquals(tag, input.readTag()); + String text = input.readString(); + assertEquals(0xfffd, text.charAt(0)); + } + + public void testReadFromSlice() throws Exception { + byte[] bytes = bytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + CodedInputStream in = CodedInputStream.newInstance(bytes, 3, 5); + assertEquals(0, in.getTotalBytesRead()); + for (int i = 3; i < 8; i++) { + assertEquals(i, in.readRawByte()); + assertEquals(i-2, in.getTotalBytesRead()); + } + // eof + assertEquals(0, in.readTag()); + assertEquals(5, in.getTotalBytesRead()); + } + + public void testInvalidTag() throws Exception { + // Any tag number which corresponds to field number zero is invalid and + // should throw InvalidProtocolBufferException. + for (int i = 0; i < 8; i++) { + try { + CodedInputStream.newInstance(bytes(i)).readTag(); + fail("Should have thrown an exception."); + } catch (InvalidProtocolBufferException e) { + assertEquals(InvalidProtocolBufferException.invalidTag().getMessage(), + e.getMessage()); + } + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java new file mode 100644 index 0000000..8625502 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java @@ -0,0 +1,317 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto.SparseEnumMessage; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestPackedTypes; +import protobuf_unittest.UnittestProto.TestSparseEnum; + +import junit.framework.TestCase; + +import java.io.ByteArrayOutputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * Unit test for {@link CodedOutputStream}. + * + * @author kenton@google.com Kenton Varda + */ +public class CodedOutputStreamTest extends TestCase { + /** + * Helper to construct a byte array from a bunch of bytes. The inputs are + * actually ints so that I can use hex notation and not get stupid errors + * about precision. + */ + private byte[] bytes(int... bytesAsInts) { + byte[] bytes = new byte[bytesAsInts.length]; + for (int i = 0; i < bytesAsInts.length; i++) { + bytes[i] = (byte) bytesAsInts[i]; + } + return bytes; + } + + /** Arrays.asList() does not work with arrays of primitives. :( */ + private List toList(byte[] bytes) { + List result = new ArrayList(); + for (byte b : bytes) { + result.add(b); + } + return result; + } + + private void assertEqualBytes(byte[] a, byte[] b) { + assertEquals(toList(a), toList(b)); + } + + /** + * Writes the given value using writeRawVarint32() and writeRawVarint64() and + * checks that the result matches the given bytes. + */ + private void assertWriteVarint(byte[] data, long value) throws Exception { + // Only do 32-bit write if the value fits in 32 bits. + if ((value >>> 32) == 0) { + ByteArrayOutputStream rawOutput = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); + output.writeRawVarint32((int) value); + output.flush(); + assertEqualBytes(data, rawOutput.toByteArray()); + + // Also try computing size. + assertEquals(data.length, + CodedOutputStream.computeRawVarint32Size((int) value)); + } + + { + ByteArrayOutputStream rawOutput = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); + output.writeRawVarint64(value); + output.flush(); + assertEqualBytes(data, rawOutput.toByteArray()); + + // Also try computing size. + assertEquals(data.length, + CodedOutputStream.computeRawVarint64Size(value)); + } + + // Try different block sizes. + for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { + // Only do 32-bit write if the value fits in 32 bits. + if ((value >>> 32) == 0) { + ByteArrayOutputStream rawOutput = new ByteArrayOutputStream(); + CodedOutputStream output = + CodedOutputStream.newInstance(rawOutput, blockSize); + output.writeRawVarint32((int) value); + output.flush(); + assertEqualBytes(data, rawOutput.toByteArray()); + } + + { + ByteArrayOutputStream rawOutput = new ByteArrayOutputStream(); + CodedOutputStream output = + CodedOutputStream.newInstance(rawOutput, blockSize); + output.writeRawVarint64(value); + output.flush(); + assertEqualBytes(data, rawOutput.toByteArray()); + } + } + } + + /** Tests writeRawVarint32() and writeRawVarint64(). */ + public void testWriteVarint() throws Exception { + assertWriteVarint(bytes(0x00), 0); + assertWriteVarint(bytes(0x01), 1); + assertWriteVarint(bytes(0x7f), 127); + // 14882 + assertWriteVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7)); + // 2961488830 + assertWriteVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b), + (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | + (0x0bL << 28)); + + // 64-bit + // 7256456126 + assertWriteVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b), + (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | + (0x1bL << 28)); + // 41256202580718336 + assertWriteVarint( + bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49), + (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) | + (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49)); + // 11964378330978735131 + assertWriteVarint( + bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01), + (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) | + (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) | + (0x05L << 49) | (0x26L << 56) | (0x01L << 63)); + } + + /** + * Parses the given bytes using writeRawLittleEndian32() and checks + * that the result matches the given value. + */ + private void assertWriteLittleEndian32(byte[] data, int value) + throws Exception { + ByteArrayOutputStream rawOutput = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); + output.writeRawLittleEndian32(value); + output.flush(); + assertEqualBytes(data, rawOutput.toByteArray()); + + // Try different block sizes. + for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { + rawOutput = new ByteArrayOutputStream(); + output = CodedOutputStream.newInstance(rawOutput, blockSize); + output.writeRawLittleEndian32(value); + output.flush(); + assertEqualBytes(data, rawOutput.toByteArray()); + } + } + + /** + * Parses the given bytes using writeRawLittleEndian64() and checks + * that the result matches the given value. + */ + private void assertWriteLittleEndian64(byte[] data, long value) + throws Exception { + ByteArrayOutputStream rawOutput = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); + output.writeRawLittleEndian64(value); + output.flush(); + assertEqualBytes(data, rawOutput.toByteArray()); + + // Try different block sizes. + for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { + rawOutput = new ByteArrayOutputStream(); + output = CodedOutputStream.newInstance(rawOutput, blockSize); + output.writeRawLittleEndian64(value); + output.flush(); + assertEqualBytes(data, rawOutput.toByteArray()); + } + } + + /** Tests writeRawLittleEndian32() and writeRawLittleEndian64(). */ + public void testWriteLittleEndian() throws Exception { + assertWriteLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678); + assertWriteLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0); + + assertWriteLittleEndian64( + bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12), + 0x123456789abcdef0L); + assertWriteLittleEndian64( + bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), + 0x9abcdef012345678L); + } + + /** Test encodeZigZag32() and encodeZigZag64(). */ + public void testEncodeZigZag() throws Exception { + assertEquals(0, CodedOutputStream.encodeZigZag32( 0)); + assertEquals(1, CodedOutputStream.encodeZigZag32(-1)); + assertEquals(2, CodedOutputStream.encodeZigZag32( 1)); + assertEquals(3, CodedOutputStream.encodeZigZag32(-2)); + assertEquals(0x7FFFFFFE, CodedOutputStream.encodeZigZag32(0x3FFFFFFF)); + assertEquals(0x7FFFFFFF, CodedOutputStream.encodeZigZag32(0xC0000000)); + assertEquals(0xFFFFFFFE, CodedOutputStream.encodeZigZag32(0x7FFFFFFF)); + assertEquals(0xFFFFFFFF, CodedOutputStream.encodeZigZag32(0x80000000)); + + assertEquals(0, CodedOutputStream.encodeZigZag64( 0)); + assertEquals(1, CodedOutputStream.encodeZigZag64(-1)); + assertEquals(2, CodedOutputStream.encodeZigZag64( 1)); + assertEquals(3, CodedOutputStream.encodeZigZag64(-2)); + assertEquals(0x000000007FFFFFFEL, + CodedOutputStream.encodeZigZag64(0x000000003FFFFFFFL)); + assertEquals(0x000000007FFFFFFFL, + CodedOutputStream.encodeZigZag64(0xFFFFFFFFC0000000L)); + assertEquals(0x00000000FFFFFFFEL, + CodedOutputStream.encodeZigZag64(0x000000007FFFFFFFL)); + assertEquals(0x00000000FFFFFFFFL, + CodedOutputStream.encodeZigZag64(0xFFFFFFFF80000000L)); + assertEquals(0xFFFFFFFFFFFFFFFEL, + CodedOutputStream.encodeZigZag64(0x7FFFFFFFFFFFFFFFL)); + assertEquals(0xFFFFFFFFFFFFFFFFL, + CodedOutputStream.encodeZigZag64(0x8000000000000000L)); + + // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1) + // were chosen semi-randomly via keyboard bashing. + assertEquals(0, + CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(0))); + assertEquals(1, + CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(1))); + assertEquals(-1, + CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-1))); + assertEquals(14927, + CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(14927))); + assertEquals(-3612, + CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-3612))); + + assertEquals(0, + CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(0))); + assertEquals(1, + CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(1))); + assertEquals(-1, + CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-1))); + assertEquals(14927, + CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(14927))); + assertEquals(-3612, + CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-3612))); + + assertEquals(856912304801416L, + CodedOutputStream.encodeZigZag64( + CodedInputStream.decodeZigZag64( + 856912304801416L))); + assertEquals(-75123905439571256L, + CodedOutputStream.encodeZigZag64( + CodedInputStream.decodeZigZag64( + -75123905439571256L))); + } + + /** Tests writing a whole message with every field type. */ + public void testWriteWholeMessage() throws Exception { + TestAllTypes message = TestUtil.getAllSet(); + + byte[] rawBytes = message.toByteArray(); + assertEqualBytes(TestUtil.getGoldenMessage().toByteArray(), rawBytes); + + // Try different block sizes. + for (int blockSize = 1; blockSize < 256; blockSize *= 2) { + ByteArrayOutputStream rawOutput = new ByteArrayOutputStream(); + CodedOutputStream output = + CodedOutputStream.newInstance(rawOutput, blockSize); + message.writeTo(output); + output.flush(); + assertEqualBytes(rawBytes, rawOutput.toByteArray()); + } + } + + /** Tests writing a whole message with every packed field type. Ensures the + * wire format of packed fields is compatible with C++. */ + public void testWriteWholePackedFieldsMessage() throws Exception { + TestPackedTypes message = TestUtil.getPackedSet(); + + byte[] rawBytes = message.toByteArray(); + assertEqualBytes(TestUtil.getGoldenPackedFieldsMessage().toByteArray(), + rawBytes); + } + + /** Test writing a message containing a negative enum value. This used to + * fail because the size was not properly computed as a sign-extended varint. + */ + public void testWriteMessageWithNegativeEnumValue() throws Exception { + SparseEnumMessage message = SparseEnumMessage.newBuilder() + .setSparseEnum(TestSparseEnum.SPARSE_E) .build(); + assertTrue(message.getSparseEnum().getNumber() < 0); + byte[] rawBytes = message.toByteArray(); + SparseEnumMessage message2 = SparseEnumMessage.parseFrom(rawBytes); + assertEquals(TestSparseEnum.SPARSE_E, message2.getSparseEnum()); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java new file mode 100644 index 0000000..1f8bb44 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java @@ -0,0 +1,80 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto.TestDeprecatedFields; + +import junit.framework.TestCase; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; +/** + * Test field deprecation + * + * @author birdo@google.com (Roberto Scaramuzzi) + */ +public class DeprecatedFieldTest extends TestCase { + private String[] deprecatedGetterNames = { + "hasDeprecatedInt32", + "getDeprecatedInt32"}; + + private String[] deprecatedBuilderGetterNames = { + "hasDeprecatedInt32", + "getDeprecatedInt32", + "clearDeprecatedInt32"}; + + private String[] deprecatedBuilderSetterNames = { + "setDeprecatedInt32"}; + + public void testDeprecatedField() throws Exception { + Class deprecatedFields = TestDeprecatedFields.class; + Class deprecatedFieldsBuilder = TestDeprecatedFields.Builder.class; + for (String name : deprecatedGetterNames) { + Method method = deprecatedFields.getMethod(name); + assertTrue("Method " + name + " should be deprecated", + isDeprecated(method)); + } + for (String name : deprecatedBuilderGetterNames) { + Method method = deprecatedFieldsBuilder.getMethod(name); + assertTrue("Method " + name + " should be deprecated", + isDeprecated(method)); + } + for (String name : deprecatedBuilderSetterNames) { + Method method = deprecatedFieldsBuilder.getMethod(name, int.class); + assertTrue("Method " + name + " should be deprecated", + isDeprecated(method)); + } + } + + private boolean isDeprecated(AnnotatedElement annotated) { + return annotated.isAnnotationPresent(Deprecated.class); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DescriptorsTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DescriptorsTest.java new file mode 100644 index 0000000..9c31091 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DescriptorsTest.java @@ -0,0 +1,648 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.DescriptorProtos.DescriptorProto; +import com.google.protobuf.DescriptorProtos.EnumDescriptorProto; +import com.google.protobuf.DescriptorProtos.EnumValueDescriptorProto; +import com.google.protobuf.DescriptorProtos.FieldDescriptorProto; +import com.google.protobuf.DescriptorProtos.FileDescriptorProto; +import com.google.protobuf.Descriptors.DescriptorValidationException; +import com.google.protobuf.Descriptors.FileDescriptor; +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.Descriptors.EnumDescriptor; +import com.google.protobuf.Descriptors.EnumValueDescriptor; +import com.google.protobuf.Descriptors.ServiceDescriptor; +import com.google.protobuf.Descriptors.MethodDescriptor; + +import com.google.protobuf.test.UnittestImport; +import com.google.protobuf.test.UnittestImport.ImportEnum; +import com.google.protobuf.test.UnittestImport.ImportMessage; +import protobuf_unittest.UnittestProto; +import protobuf_unittest.UnittestProto.ForeignEnum; +import protobuf_unittest.UnittestProto.ForeignMessage; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestExtremeDefaultValues; +import protobuf_unittest.UnittestProto.TestRequired; +import protobuf_unittest.UnittestProto.TestService; +import protobuf_unittest.UnittestCustomOptions; + + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Unit test for {@link Descriptors}. + * + * @author kenton@google.com Kenton Varda + */ +public class DescriptorsTest extends TestCase { + + // Regression test for bug where referencing a FieldDescriptor.Type value + // before a FieldDescriptorProto.Type value would yield a + // ExceptionInInitializerError. + @SuppressWarnings("unused") + private static final Object STATIC_INIT_TEST = FieldDescriptor.Type.BOOL; + + public void testFieldTypeEnumMapping() throws Exception { + assertEquals(FieldDescriptor.Type.values().length, + FieldDescriptorProto.Type.values().length); + for (FieldDescriptor.Type type : FieldDescriptor.Type.values()) { + FieldDescriptorProto.Type protoType = type.toProto(); + assertEquals("TYPE_" + type.name(), protoType.name()); + assertEquals(type, FieldDescriptor.Type.valueOf(protoType)); + } + } + + public void testFileDescriptor() throws Exception { + FileDescriptor file = UnittestProto.getDescriptor(); + + assertEquals("google/protobuf/unittest.proto", file.getName()); + assertEquals("protobuf_unittest", file.getPackage()); + + assertEquals("UnittestProto", file.getOptions().getJavaOuterClassname()); + assertEquals("google/protobuf/unittest.proto", + file.toProto().getName()); + + assertEquals(Arrays.asList(UnittestImport.getDescriptor()), + file.getDependencies()); + + Descriptor messageType = TestAllTypes.getDescriptor(); + assertEquals(messageType, file.getMessageTypes().get(0)); + assertEquals(messageType, file.findMessageTypeByName("TestAllTypes")); + assertNull(file.findMessageTypeByName("NoSuchType")); + assertNull(file.findMessageTypeByName("protobuf_unittest.TestAllTypes")); + for (int i = 0; i < file.getMessageTypes().size(); i++) { + assertEquals(i, file.getMessageTypes().get(i).getIndex()); + } + + EnumDescriptor enumType = ForeignEnum.getDescriptor(); + assertEquals(enumType, file.getEnumTypes().get(0)); + assertEquals(enumType, file.findEnumTypeByName("ForeignEnum")); + assertNull(file.findEnumTypeByName("NoSuchType")); + assertNull(file.findEnumTypeByName("protobuf_unittest.ForeignEnum")); + assertEquals(Arrays.asList(ImportEnum.getDescriptor()), + UnittestImport.getDescriptor().getEnumTypes()); + for (int i = 0; i < file.getEnumTypes().size(); i++) { + assertEquals(i, file.getEnumTypes().get(i).getIndex()); + } + + ServiceDescriptor service = TestService.getDescriptor(); + assertEquals(service, file.getServices().get(0)); + assertEquals(service, file.findServiceByName("TestService")); + assertNull(file.findServiceByName("NoSuchType")); + assertNull(file.findServiceByName("protobuf_unittest.TestService")); + assertEquals(Collections.emptyList(), + UnittestImport.getDescriptor().getServices()); + for (int i = 0; i < file.getServices().size(); i++) { + assertEquals(i, file.getServices().get(i).getIndex()); + } + + FieldDescriptor extension = + UnittestProto.optionalInt32Extension.getDescriptor(); + assertEquals(extension, file.getExtensions().get(0)); + assertEquals(extension, + file.findExtensionByName("optional_int32_extension")); + assertNull(file.findExtensionByName("no_such_ext")); + assertNull(file.findExtensionByName( + "protobuf_unittest.optional_int32_extension")); + assertEquals(Collections.emptyList(), + UnittestImport.getDescriptor().getExtensions()); + for (int i = 0; i < file.getExtensions().size(); i++) { + assertEquals(i, file.getExtensions().get(i).getIndex()); + } + } + + public void testDescriptor() throws Exception { + Descriptor messageType = TestAllTypes.getDescriptor(); + Descriptor nestedType = TestAllTypes.NestedMessage.getDescriptor(); + + assertEquals("TestAllTypes", messageType.getName()); + assertEquals("protobuf_unittest.TestAllTypes", messageType.getFullName()); + assertEquals(UnittestProto.getDescriptor(), messageType.getFile()); + assertNull(messageType.getContainingType()); + assertEquals(DescriptorProtos.MessageOptions.getDefaultInstance(), + messageType.getOptions()); + assertEquals("TestAllTypes", messageType.toProto().getName()); + + assertEquals("NestedMessage", nestedType.getName()); + assertEquals("protobuf_unittest.TestAllTypes.NestedMessage", + nestedType.getFullName()); + assertEquals(UnittestProto.getDescriptor(), nestedType.getFile()); + assertEquals(messageType, nestedType.getContainingType()); + + FieldDescriptor field = messageType.getFields().get(0); + assertEquals("optional_int32", field.getName()); + assertEquals(field, messageType.findFieldByName("optional_int32")); + assertNull(messageType.findFieldByName("no_such_field")); + assertEquals(field, messageType.findFieldByNumber(1)); + assertNull(messageType.findFieldByNumber(571283)); + for (int i = 0; i < messageType.getFields().size(); i++) { + assertEquals(i, messageType.getFields().get(i).getIndex()); + } + + assertEquals(nestedType, messageType.getNestedTypes().get(0)); + assertEquals(nestedType, messageType.findNestedTypeByName("NestedMessage")); + assertNull(messageType.findNestedTypeByName("NoSuchType")); + for (int i = 0; i < messageType.getNestedTypes().size(); i++) { + assertEquals(i, messageType.getNestedTypes().get(i).getIndex()); + } + + EnumDescriptor enumType = TestAllTypes.NestedEnum.getDescriptor(); + assertEquals(enumType, messageType.getEnumTypes().get(0)); + assertEquals(enumType, messageType.findEnumTypeByName("NestedEnum")); + assertNull(messageType.findEnumTypeByName("NoSuchType")); + for (int i = 0; i < messageType.getEnumTypes().size(); i++) { + assertEquals(i, messageType.getEnumTypes().get(i).getIndex()); + } + } + + public void testFieldDescriptor() throws Exception { + Descriptor messageType = TestAllTypes.getDescriptor(); + FieldDescriptor primitiveField = + messageType.findFieldByName("optional_int32"); + FieldDescriptor enumField = + messageType.findFieldByName("optional_nested_enum"); + FieldDescriptor messageField = + messageType.findFieldByName("optional_foreign_message"); + FieldDescriptor cordField = + messageType.findFieldByName("optional_cord"); + FieldDescriptor extension = + UnittestProto.optionalInt32Extension.getDescriptor(); + FieldDescriptor nestedExtension = TestRequired.single.getDescriptor(); + + assertEquals("optional_int32", primitiveField.getName()); + assertEquals("protobuf_unittest.TestAllTypes.optional_int32", + primitiveField.getFullName()); + assertEquals(1, primitiveField.getNumber()); + assertEquals(messageType, primitiveField.getContainingType()); + assertEquals(UnittestProto.getDescriptor(), primitiveField.getFile()); + assertEquals(FieldDescriptor.Type.INT32, primitiveField.getType()); + assertEquals(FieldDescriptor.JavaType.INT, primitiveField.getJavaType()); + assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(), + primitiveField.getOptions()); + assertFalse(primitiveField.isExtension()); + assertEquals("optional_int32", primitiveField.toProto().getName()); + + assertEquals("optional_nested_enum", enumField.getName()); + assertEquals(FieldDescriptor.Type.ENUM, enumField.getType()); + assertEquals(FieldDescriptor.JavaType.ENUM, enumField.getJavaType()); + assertEquals(TestAllTypes.NestedEnum.getDescriptor(), + enumField.getEnumType()); + + assertEquals("optional_foreign_message", messageField.getName()); + assertEquals(FieldDescriptor.Type.MESSAGE, messageField.getType()); + assertEquals(FieldDescriptor.JavaType.MESSAGE, messageField.getJavaType()); + assertEquals(ForeignMessage.getDescriptor(), messageField.getMessageType()); + + assertEquals("optional_cord", cordField.getName()); + assertEquals(FieldDescriptor.Type.STRING, cordField.getType()); + assertEquals(FieldDescriptor.JavaType.STRING, cordField.getJavaType()); + assertEquals(DescriptorProtos.FieldOptions.CType.CORD, + cordField.getOptions().getCtype()); + + assertEquals("optional_int32_extension", extension.getName()); + assertEquals("protobuf_unittest.optional_int32_extension", + extension.getFullName()); + assertEquals(1, extension.getNumber()); + assertEquals(TestAllExtensions.getDescriptor(), + extension.getContainingType()); + assertEquals(UnittestProto.getDescriptor(), extension.getFile()); + assertEquals(FieldDescriptor.Type.INT32, extension.getType()); + assertEquals(FieldDescriptor.JavaType.INT, extension.getJavaType()); + assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(), + extension.getOptions()); + assertTrue(extension.isExtension()); + assertEquals(null, extension.getExtensionScope()); + assertEquals("optional_int32_extension", extension.toProto().getName()); + + assertEquals("single", nestedExtension.getName()); + assertEquals("protobuf_unittest.TestRequired.single", + nestedExtension.getFullName()); + assertEquals(TestRequired.getDescriptor(), + nestedExtension.getExtensionScope()); + } + + public void testFieldDescriptorLabel() throws Exception { + FieldDescriptor requiredField = + TestRequired.getDescriptor().findFieldByName("a"); + FieldDescriptor optionalField = + TestAllTypes.getDescriptor().findFieldByName("optional_int32"); + FieldDescriptor repeatedField = + TestAllTypes.getDescriptor().findFieldByName("repeated_int32"); + + assertTrue(requiredField.isRequired()); + assertFalse(requiredField.isRepeated()); + assertFalse(optionalField.isRequired()); + assertFalse(optionalField.isRepeated()); + assertFalse(repeatedField.isRequired()); + assertTrue(repeatedField.isRepeated()); + } + + public void testFieldDescriptorDefault() throws Exception { + Descriptor d = TestAllTypes.getDescriptor(); + assertFalse(d.findFieldByName("optional_int32").hasDefaultValue()); + assertEquals(0, d.findFieldByName("optional_int32").getDefaultValue()); + assertTrue(d.findFieldByName("default_int32").hasDefaultValue()); + assertEquals(41, d.findFieldByName("default_int32").getDefaultValue()); + + d = TestExtremeDefaultValues.getDescriptor(); + assertEquals( + ByteString.copyFrom( + "\0\001\007\b\f\n\r\t\013\\\'\"\u00fe".getBytes("ISO-8859-1")), + d.findFieldByName("escaped_bytes").getDefaultValue()); + assertEquals(-1, d.findFieldByName("large_uint32").getDefaultValue()); + assertEquals(-1L, d.findFieldByName("large_uint64").getDefaultValue()); + } + + public void testEnumDescriptor() throws Exception { + EnumDescriptor enumType = ForeignEnum.getDescriptor(); + EnumDescriptor nestedType = TestAllTypes.NestedEnum.getDescriptor(); + + assertEquals("ForeignEnum", enumType.getName()); + assertEquals("protobuf_unittest.ForeignEnum", enumType.getFullName()); + assertEquals(UnittestProto.getDescriptor(), enumType.getFile()); + assertNull(enumType.getContainingType()); + assertEquals(DescriptorProtos.EnumOptions.getDefaultInstance(), + enumType.getOptions()); + + assertEquals("NestedEnum", nestedType.getName()); + assertEquals("protobuf_unittest.TestAllTypes.NestedEnum", + nestedType.getFullName()); + assertEquals(UnittestProto.getDescriptor(), nestedType.getFile()); + assertEquals(TestAllTypes.getDescriptor(), nestedType.getContainingType()); + + EnumValueDescriptor value = ForeignEnum.FOREIGN_FOO.getValueDescriptor(); + assertEquals(value, enumType.getValues().get(0)); + assertEquals("FOREIGN_FOO", value.getName()); + assertEquals(4, value.getNumber()); + assertEquals(value, enumType.findValueByName("FOREIGN_FOO")); + assertEquals(value, enumType.findValueByNumber(4)); + assertNull(enumType.findValueByName("NO_SUCH_VALUE")); + for (int i = 0; i < enumType.getValues().size(); i++) { + assertEquals(i, enumType.getValues().get(i).getIndex()); + } + } + + public void testServiceDescriptor() throws Exception { + ServiceDescriptor service = TestService.getDescriptor(); + + assertEquals("TestService", service.getName()); + assertEquals("protobuf_unittest.TestService", service.getFullName()); + assertEquals(UnittestProto.getDescriptor(), service.getFile()); + + assertEquals(2, service.getMethods().size()); + + MethodDescriptor fooMethod = service.getMethods().get(0); + assertEquals("Foo", fooMethod.getName()); + assertEquals(UnittestProto.FooRequest.getDescriptor(), + fooMethod.getInputType()); + assertEquals(UnittestProto.FooResponse.getDescriptor(), + fooMethod.getOutputType()); + assertEquals(fooMethod, service.findMethodByName("Foo")); + + MethodDescriptor barMethod = service.getMethods().get(1); + assertEquals("Bar", barMethod.getName()); + assertEquals(UnittestProto.BarRequest.getDescriptor(), + barMethod.getInputType()); + assertEquals(UnittestProto.BarResponse.getDescriptor(), + barMethod.getOutputType()); + assertEquals(barMethod, service.findMethodByName("Bar")); + + assertNull(service.findMethodByName("NoSuchMethod")); + + for (int i = 0; i < service.getMethods().size(); i++) { + assertEquals(i, service.getMethods().get(i).getIndex()); + } + } + + + public void testCustomOptions() throws Exception { + Descriptor descriptor = + UnittestCustomOptions.TestMessageWithCustomOptions.getDescriptor(); + + assertTrue( + descriptor.getOptions().hasExtension(UnittestCustomOptions.messageOpt1)); + assertEquals(Integer.valueOf(-56), + descriptor.getOptions().getExtension(UnittestCustomOptions.messageOpt1)); + + FieldDescriptor field = descriptor.findFieldByName("field1"); + assertNotNull(field); + + assertTrue( + field.getOptions().hasExtension(UnittestCustomOptions.fieldOpt1)); + assertEquals(Long.valueOf(8765432109L), + field.getOptions().getExtension(UnittestCustomOptions.fieldOpt1)); + + EnumDescriptor enumType = + UnittestCustomOptions.TestMessageWithCustomOptions.AnEnum.getDescriptor(); + + assertTrue( + enumType.getOptions().hasExtension(UnittestCustomOptions.enumOpt1)); + assertEquals(Integer.valueOf(-789), + enumType.getOptions().getExtension(UnittestCustomOptions.enumOpt1)); + + ServiceDescriptor service = + UnittestCustomOptions.TestServiceWithCustomOptions.getDescriptor(); + + assertTrue( + service.getOptions().hasExtension(UnittestCustomOptions.serviceOpt1)); + assertEquals(Long.valueOf(-9876543210L), + service.getOptions().getExtension(UnittestCustomOptions.serviceOpt1)); + + MethodDescriptor method = service.findMethodByName("Foo"); + assertNotNull(method); + + assertTrue( + method.getOptions().hasExtension(UnittestCustomOptions.methodOpt1)); + assertEquals(UnittestCustomOptions.MethodOpt1.METHODOPT1_VAL2, + method.getOptions().getExtension(UnittestCustomOptions.methodOpt1)); + } + + /** + * Test that the FieldDescriptor.Type enum is the same as the + * WireFormat.FieldType enum. + */ + public void testFieldTypeTablesMatch() throws Exception { + FieldDescriptor.Type[] values1 = FieldDescriptor.Type.values(); + WireFormat.FieldType[] values2 = WireFormat.FieldType.values(); + + assertEquals(values1.length, values2.length); + + for (int i = 0; i < values1.length; i++) { + assertEquals(values1[i].toString(), values2[i].toString()); + } + } + + /** + * Test that the FieldDescriptor.JavaType enum is the same as the + * WireFormat.JavaType enum. + */ + public void testJavaTypeTablesMatch() throws Exception { + FieldDescriptor.JavaType[] values1 = FieldDescriptor.JavaType.values(); + WireFormat.JavaType[] values2 = WireFormat.JavaType.values(); + + assertEquals(values1.length, values2.length); + + for (int i = 0; i < values1.length; i++) { + assertEquals(values1[i].toString(), values2[i].toString()); + } + } + + public void testEnormousDescriptor() throws Exception { + // The descriptor for this file is larger than 64k, yet it did not cause + // a compiler error due to an over-long string literal. + assertTrue( + UnittestEnormousDescriptor.getDescriptor() + .toProto().getSerializedSize() > 65536); + } + + /** + * Tests that the DescriptorValidationException works as intended. + */ + public void testDescriptorValidatorException() throws Exception { + FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder() + .setName("foo.proto") + .addMessageType(DescriptorProto.newBuilder() + .setName("Foo") + .addField(FieldDescriptorProto.newBuilder() + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setType(FieldDescriptorProto.Type.TYPE_INT32) + .setName("foo") + .setNumber(1) + .setDefaultValue("invalid") + .build()) + .build()) + .build(); + try { + Descriptors.FileDescriptor.buildFrom(fileDescriptorProto, + new FileDescriptor[0]); + fail("DescriptorValidationException expected"); + } catch (DescriptorValidationException e) { + // Expected; check that the error message contains some useful hints + assertTrue(e.getMessage().indexOf("foo") != -1); + assertTrue(e.getMessage().indexOf("Foo") != -1); + assertTrue(e.getMessage().indexOf("invalid") != -1); + assertTrue(e.getCause() instanceof NumberFormatException); + assertTrue(e.getCause().getMessage().indexOf("invalid") != -1); + } + } + + /** + * Tests the translate/crosslink for an example where a message field's name + * and type name are the same. + */ + public void testDescriptorComplexCrosslink() throws Exception { + FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder() + .setName("foo.proto") + .addMessageType(DescriptorProto.newBuilder() + .setName("Foo") + .addField(FieldDescriptorProto.newBuilder() + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setType(FieldDescriptorProto.Type.TYPE_INT32) + .setName("foo") + .setNumber(1) + .build()) + .build()) + .addMessageType(DescriptorProto.newBuilder() + .setName("Bar") + .addField(FieldDescriptorProto.newBuilder() + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setTypeName("Foo") + .setName("Foo") + .setNumber(1) + .build()) + .build()) + .build(); + // translate and crosslink + FileDescriptor file = + Descriptors.FileDescriptor.buildFrom(fileDescriptorProto, + new FileDescriptor[0]); + // verify resulting descriptors + assertNotNull(file); + List msglist = file.getMessageTypes(); + assertNotNull(msglist); + assertTrue(msglist.size() == 2); + boolean barFound = false; + for (Descriptor desc : msglist) { + if (desc.getName().equals("Bar")) { + barFound = true; + assertNotNull(desc.getFields()); + List fieldlist = desc.getFields(); + assertNotNull(fieldlist); + assertTrue(fieldlist.size() == 1); + assertTrue(fieldlist.get(0).getType() == FieldDescriptor.Type.MESSAGE); + assertTrue(fieldlist.get(0).getMessageType().getName().equals("Foo")); + } + } + assertTrue(barFound); + } + + public void testInvalidPublicDependency() throws Exception { + FileDescriptorProto fooProto = FileDescriptorProto.newBuilder() + .setName("foo.proto") .build(); + FileDescriptorProto barProto = FileDescriptorProto.newBuilder() + .setName("boo.proto") + .addDependency("foo.proto") + .addPublicDependency(1) // Error, should be 0. + .build(); + FileDescriptor fooFile = Descriptors.FileDescriptor.buildFrom(fooProto, + new FileDescriptor[0]); + try { + Descriptors.FileDescriptor.buildFrom(barProto, + new FileDescriptor[] {fooFile}); + fail("DescriptorValidationException expected"); + } catch (DescriptorValidationException e) { + assertTrue( + e.getMessage().indexOf("Invalid public dependency index.") != -1); + } + } + + public void testHiddenDependency() throws Exception { + FileDescriptorProto barProto = FileDescriptorProto.newBuilder() + .setName("bar.proto") + .addMessageType(DescriptorProto.newBuilder().setName("Bar")) + .build(); + FileDescriptorProto forwardProto = FileDescriptorProto.newBuilder() + .setName("forward.proto") + .addDependency("bar.proto") + .build(); + FileDescriptorProto fooProto = FileDescriptorProto.newBuilder() + .setName("foo.proto") + .addDependency("forward.proto") + .addMessageType(DescriptorProto.newBuilder() + .setName("Foo") + .addField(FieldDescriptorProto.newBuilder() + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setTypeName("Bar") + .setName("bar") + .setNumber(1))) + .build(); + FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom( + barProto, new FileDescriptor[0]); + FileDescriptor forwardFile = Descriptors.FileDescriptor.buildFrom( + forwardProto, new FileDescriptor[] {barFile}); + + try { + Descriptors.FileDescriptor.buildFrom( + fooProto, new FileDescriptor[] {forwardFile}); + fail("DescriptorValidationException expected"); + } catch (DescriptorValidationException e) { + assertTrue(e.getMessage().indexOf("Bar") != -1); + assertTrue(e.getMessage().indexOf("is not defined") != -1); + } + } + + public void testPublicDependency() throws Exception { + FileDescriptorProto barProto = FileDescriptorProto.newBuilder() + .setName("bar.proto") + .addMessageType(DescriptorProto.newBuilder().setName("Bar")) + .build(); + FileDescriptorProto forwardProto = FileDescriptorProto.newBuilder() + .setName("forward.proto") + .addDependency("bar.proto") + .addPublicDependency(0) + .build(); + FileDescriptorProto fooProto = FileDescriptorProto.newBuilder() + .setName("foo.proto") + .addDependency("forward.proto") + .addMessageType(DescriptorProto.newBuilder() + .setName("Foo") + .addField(FieldDescriptorProto.newBuilder() + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setTypeName("Bar") + .setName("bar") + .setNumber(1))) + .build(); + FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom( + barProto, new FileDescriptor[0]); + FileDescriptor forwardFile = Descriptors.FileDescriptor.buildFrom( + forwardProto, new FileDescriptor[]{barFile}); + Descriptors.FileDescriptor.buildFrom( + fooProto, new FileDescriptor[] {forwardFile}); + } + + /** + * Tests the translate/crosslink for an example with a more complex namespace + * referencing. + */ + public void testComplexNamespacePublicDependency() throws Exception { + FileDescriptorProto fooProto = FileDescriptorProto.newBuilder() + .setName("bar.proto") + .setPackage("a.b.c.d.bar.shared") + .addEnumType(EnumDescriptorProto.newBuilder() + .setName("MyEnum") + .addValue(EnumValueDescriptorProto.newBuilder() + .setName("BLAH") + .setNumber(1))) + .build(); + FileDescriptorProto barProto = FileDescriptorProto.newBuilder() + .setName("foo.proto") + .addDependency("bar.proto") + .setPackage("a.b.c.d.foo.shared") + .addMessageType(DescriptorProto.newBuilder() + .setName("MyMessage") + .addField(FieldDescriptorProto.newBuilder() + .setLabel(FieldDescriptorProto.Label.LABEL_REPEATED) + .setTypeName("bar.shared.MyEnum") + .setName("MyField") + .setNumber(1))) + .build(); + // translate and crosslink + FileDescriptor fooFile = Descriptors.FileDescriptor.buildFrom( + fooProto, new FileDescriptor[0]); + FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom( + barProto, new FileDescriptor[]{fooFile}); + // verify resulting descriptors + assertNotNull(barFile); + List msglist = barFile.getMessageTypes(); + assertNotNull(msglist); + assertTrue(msglist.size() == 1); + Descriptor desc = msglist.get(0); + if (desc.getName().equals("MyMessage")) { + assertNotNull(desc.getFields()); + List fieldlist = desc.getFields(); + assertNotNull(fieldlist); + assertTrue(fieldlist.size() == 1); + FieldDescriptor field = fieldlist.get(0); + assertTrue(field.getType() == FieldDescriptor.Type.ENUM); + assertTrue(field.getEnumType().getName().equals("MyEnum")); + assertTrue(field.getEnumType().getFile().getName().equals("bar.proto")); + assertTrue(field.getEnumType().getFile().getPackage().equals( + "a.b.c.d.bar.shared")); + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DynamicMessageTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DynamicMessageTest.java new file mode 100644 index 0000000..990e8ca --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/DynamicMessageTest.java @@ -0,0 +1,264 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestEmptyMessage; +import protobuf_unittest.UnittestProto.TestPackedTypes; + +import junit.framework.TestCase; +import java.util.Arrays; + +/** + * Unit test for {@link DynamicMessage}. See also {@link MessageTest}, which + * tests some {@link DynamicMessage} functionality. + * + * @author kenton@google.com Kenton Varda + */ +public class DynamicMessageTest extends TestCase { + TestUtil.ReflectionTester reflectionTester = + new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null); + + TestUtil.ReflectionTester extensionsReflectionTester = + new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(), + TestUtil.getExtensionRegistry()); + TestUtil.ReflectionTester packedReflectionTester = + new TestUtil.ReflectionTester(TestPackedTypes.getDescriptor(), null); + + public void testDynamicMessageAccessors() throws Exception { + Message.Builder builder = + DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); + reflectionTester.setAllFieldsViaReflection(builder); + Message message = builder.build(); + reflectionTester.assertAllFieldsSetViaReflection(message); + } + + public void testSettersAfterBuild() throws Exception { + Message.Builder builder = + DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); + Message firstMessage = builder.build(); + // double build() + builder.build(); + // clear() after build() + builder.clear(); + // setters after build() + reflectionTester.setAllFieldsViaReflection(builder); + Message message = builder.build(); + reflectionTester.assertAllFieldsSetViaReflection(message); + // repeated setters after build() + reflectionTester.modifyRepeatedFieldsViaReflection(builder); + message = builder.build(); + reflectionTester.assertRepeatedFieldsModifiedViaReflection(message); + // firstMessage shouldn't have been modified. + reflectionTester.assertClearViaReflection(firstMessage); + } + + public void testUnknownFields() throws Exception { + Message.Builder builder = + DynamicMessage.newBuilder(TestEmptyMessage.getDescriptor()); + builder.setUnknownFields(UnknownFieldSet.newBuilder() + .addField(1, UnknownFieldSet.Field.newBuilder().addVarint(1).build()) + .addField(2, UnknownFieldSet.Field.newBuilder().addFixed32(1).build()) + .build()); + Message message = builder.build(); + assertEquals(2, message.getUnknownFields().asMap().size()); + // clone() with unknown fields + Message.Builder newBuilder = builder.clone(); + assertEquals(2, newBuilder.getUnknownFields().asMap().size()); + // clear() with unknown fields + newBuilder.clear(); + assertTrue(newBuilder.getUnknownFields().asMap().isEmpty()); + // serialize/parse with unknown fields + newBuilder.mergeFrom(message.toByteString()); + assertEquals(2, newBuilder.getUnknownFields().asMap().size()); + } + + public void testDynamicMessageSettersRejectNull() throws Exception { + Message.Builder builder = + DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); + reflectionTester.assertReflectionSettersRejectNull(builder); + } + + public void testDynamicMessageExtensionAccessors() throws Exception { + // We don't need to extensively test DynamicMessage's handling of + // extensions because, frankly, it doesn't do anything special with them. + // It treats them just like any other fields. + Message.Builder builder = + DynamicMessage.newBuilder(TestAllExtensions.getDescriptor()); + extensionsReflectionTester.setAllFieldsViaReflection(builder); + Message message = builder.build(); + extensionsReflectionTester.assertAllFieldsSetViaReflection(message); + } + + public void testDynamicMessageExtensionSettersRejectNull() throws Exception { + Message.Builder builder = + DynamicMessage.newBuilder(TestAllExtensions.getDescriptor()); + extensionsReflectionTester.assertReflectionSettersRejectNull(builder); + } + + public void testDynamicMessageRepeatedSetters() throws Exception { + Message.Builder builder = + DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); + reflectionTester.setAllFieldsViaReflection(builder); + reflectionTester.modifyRepeatedFieldsViaReflection(builder); + Message message = builder.build(); + reflectionTester.assertRepeatedFieldsModifiedViaReflection(message); + } + + public void testDynamicMessageRepeatedSettersRejectNull() throws Exception { + Message.Builder builder = + DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); + reflectionTester.assertReflectionRepeatedSettersRejectNull(builder); + } + + public void testDynamicMessageDefaults() throws Exception { + reflectionTester.assertClearViaReflection( + DynamicMessage.getDefaultInstance(TestAllTypes.getDescriptor())); + reflectionTester.assertClearViaReflection( + DynamicMessage.newBuilder(TestAllTypes.getDescriptor()).build()); + } + + public void testDynamicMessageSerializedSize() throws Exception { + TestAllTypes message = TestUtil.getAllSet(); + + Message.Builder dynamicBuilder = + DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); + reflectionTester.setAllFieldsViaReflection(dynamicBuilder); + Message dynamicMessage = dynamicBuilder.build(); + + assertEquals(message.getSerializedSize(), + dynamicMessage.getSerializedSize()); + } + + public void testDynamicMessageSerialization() throws Exception { + Message.Builder builder = + DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); + reflectionTester.setAllFieldsViaReflection(builder); + Message message = builder.build(); + + ByteString rawBytes = message.toByteString(); + TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); + + TestUtil.assertAllFieldsSet(message2); + + // In fact, the serialized forms should be exactly the same, byte-for-byte. + assertEquals(TestUtil.getAllSet().toByteString(), rawBytes); + } + + public void testDynamicMessageParsing() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestUtil.setAllFields(builder); + TestAllTypes message = builder.build(); + + ByteString rawBytes = message.toByteString(); + + Message message2 = + DynamicMessage.parseFrom(TestAllTypes.getDescriptor(), rawBytes); + reflectionTester.assertAllFieldsSetViaReflection(message2); + + // Test Parser interface. + Message message3 = message2.getParserForType().parseFrom(rawBytes); + reflectionTester.assertAllFieldsSetViaReflection(message3); + } + + public void testDynamicMessageExtensionParsing() throws Exception { + ByteString rawBytes = TestUtil.getAllExtensionsSet().toByteString(); + Message message = DynamicMessage.parseFrom( + TestAllExtensions.getDescriptor(), rawBytes, + TestUtil.getExtensionRegistry()); + extensionsReflectionTester.assertAllFieldsSetViaReflection(message); + + // Test Parser interface. + Message message2 = message.getParserForType().parseFrom( + rawBytes, TestUtil.getExtensionRegistry()); + extensionsReflectionTester.assertAllFieldsSetViaReflection(message2); + } + + public void testDynamicMessagePackedSerialization() throws Exception { + Message.Builder builder = + DynamicMessage.newBuilder(TestPackedTypes.getDescriptor()); + packedReflectionTester.setPackedFieldsViaReflection(builder); + Message message = builder.build(); + + ByteString rawBytes = message.toByteString(); + TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes); + + TestUtil.assertPackedFieldsSet(message2); + + // In fact, the serialized forms should be exactly the same, byte-for-byte. + assertEquals(TestUtil.getPackedSet().toByteString(), rawBytes); + } + + public void testDynamicMessagePackedParsing() throws Exception { + TestPackedTypes.Builder builder = TestPackedTypes.newBuilder(); + TestUtil.setPackedFields(builder); + TestPackedTypes message = builder.build(); + + ByteString rawBytes = message.toByteString(); + + Message message2 = + DynamicMessage.parseFrom(TestPackedTypes.getDescriptor(), rawBytes); + packedReflectionTester.assertPackedFieldsSetViaReflection(message2); + + // Test Parser interface. + Message message3 = message2.getParserForType().parseFrom(rawBytes); + packedReflectionTester.assertPackedFieldsSetViaReflection(message3); + } + + public void testDynamicMessageCopy() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestUtil.setAllFields(builder); + TestAllTypes message = builder.build(); + + DynamicMessage copy = DynamicMessage.newBuilder(message).build(); + reflectionTester.assertAllFieldsSetViaReflection(copy); + } + + public void testToBuilder() throws Exception { + DynamicMessage.Builder builder = + DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); + reflectionTester.setAllFieldsViaReflection(builder); + int unknownFieldNum = 9; + long unknownFieldVal = 90; + builder.setUnknownFields(UnknownFieldSet.newBuilder() + .addField(unknownFieldNum, + UnknownFieldSet.Field.newBuilder() + .addVarint(unknownFieldVal).build()) + .build()); + DynamicMessage message = builder.build(); + + DynamicMessage derived = message.toBuilder().build(); + reflectionTester.assertAllFieldsSetViaReflection(derived); + assertEquals(Arrays.asList(unknownFieldVal), + derived.getUnknownFields().getField(unknownFieldNum).getVarintList()); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java new file mode 100644 index 0000000..8b78893 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + * A prerun for a test suite that allows running the full protocol buffer + * tests in a mode that disables the optimization for not using + * {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder} until they are + * requested. This allows us to run all the tests through both code paths + * and ensures that both code paths produce identical results. + * + * @author jonp@google.com (Jon Perlow) + */ +public class ForceFieldBuildersPreRun implements Runnable { + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void run() { + GeneratedMessage.enableAlwaysUseFieldBuildersForTesting(); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java new file mode 100644 index 0000000..bf9db75 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java @@ -0,0 +1,1146 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.UnittestLite.TestAllExtensionsLite; +import com.google.protobuf.test.UnittestImport; +import protobuf_unittest.EnumWithNoOuter; +import protobuf_unittest.MessageWithNoOuter; +import protobuf_unittest.MultipleFilesTestProto; +import protobuf_unittest.NestedExtension.MyNestedExtension; +import protobuf_unittest.NestedExtensionLite.MyNestedExtensionLite; +import protobuf_unittest.NonNestedExtension; +import protobuf_unittest.NonNestedExtension.MessageToBeExtended; +import protobuf_unittest.NonNestedExtension.MyNonNestedExtension; +import protobuf_unittest.NonNestedExtensionLite; +import protobuf_unittest.NonNestedExtensionLite.MessageLiteToBeExtended; +import protobuf_unittest.NonNestedExtensionLite.MyNonNestedExtensionLite; +import protobuf_unittest.ServiceWithNoOuter; +import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize; +import protobuf_unittest.UnittestOptimizeFor.TestOptionalOptimizedForSize; +import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize; +import protobuf_unittest.UnittestProto; +import protobuf_unittest.UnittestProto.ForeignEnum; +import protobuf_unittest.UnittestProto.ForeignMessage; +import protobuf_unittest.UnittestProto.ForeignMessageOrBuilder; +import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage; +import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; +import protobuf_unittest.UnittestProto.TestExtremeDefaultValues; +import protobuf_unittest.UnittestProto.TestPackedTypes; +import protobuf_unittest.UnittestProto.TestUnpackedTypes; + +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Unit test for generated messages and generated code. See also + * {@link MessageTest}, which tests some generated message functionality. + * + * @author kenton@google.com Kenton Varda + */ +public class GeneratedMessageTest extends TestCase { + TestUtil.ReflectionTester reflectionTester = + new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null); + + public void testDefaultInstance() throws Exception { + assertSame(TestAllTypes.getDefaultInstance(), + TestAllTypes.getDefaultInstance().getDefaultInstanceForType()); + assertSame(TestAllTypes.getDefaultInstance(), + TestAllTypes.newBuilder().getDefaultInstanceForType()); + } + + public void testMessageOrBuilder() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestUtil.setAllFields(builder); + TestAllTypes message = builder.build(); + TestUtil.assertAllFieldsSet(message); + } + + public void testUsingBuilderMultipleTimes() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + // primitive field scalar and repeated + builder.setOptionalSfixed64(100); + builder.addRepeatedInt32(100); + // enum field scalar and repeated + builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_BAR); + builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR); + // proto field scalar and repeated + builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(1)); + builder.addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(1)); + + TestAllTypes value1 = builder.build(); + + assertEquals(100, value1.getOptionalSfixed64()); + assertEquals(100, value1.getRepeatedInt32(0)); + assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, + value1.getOptionalImportEnum()); + assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, + value1.getRepeatedImportEnum(0)); + assertEquals(1, value1.getOptionalForeignMessage().getC()); + assertEquals(1, value1.getRepeatedForeignMessage(0).getC()); + + // Make sure that builder didn't update previously created values + builder.setOptionalSfixed64(200); + builder.setRepeatedInt32(0, 200); + builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_FOO); + builder.setRepeatedImportEnum(0, UnittestImport.ImportEnum.IMPORT_FOO); + builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(2)); + builder.setRepeatedForeignMessage(0, ForeignMessage.newBuilder().setC(2)); + + TestAllTypes value2 = builder.build(); + + // Make sure value1 didn't change. + assertEquals(100, value1.getOptionalSfixed64()); + assertEquals(100, value1.getRepeatedInt32(0)); + assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, + value1.getOptionalImportEnum()); + assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, + value1.getRepeatedImportEnum(0)); + assertEquals(1, value1.getOptionalForeignMessage().getC()); + assertEquals(1, value1.getRepeatedForeignMessage(0).getC()); + + // Make sure value2 is correct + assertEquals(200, value2.getOptionalSfixed64()); + assertEquals(200, value2.getRepeatedInt32(0)); + assertEquals(UnittestImport.ImportEnum.IMPORT_FOO, + value2.getOptionalImportEnum()); + assertEquals(UnittestImport.ImportEnum.IMPORT_FOO, + value2.getRepeatedImportEnum(0)); + assertEquals(2, value2.getOptionalForeignMessage().getC()); + assertEquals(2, value2.getRepeatedForeignMessage(0).getC()); + } + + public void testProtosShareRepeatedArraysIfDidntChange() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + builder.addRepeatedInt32(100); + builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR); + builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance()); + + TestAllTypes value1 = builder.build(); + TestAllTypes value2 = value1.toBuilder().build(); + + assertSame(value1.getRepeatedInt32List(), value2.getRepeatedInt32List()); + assertSame(value1.getRepeatedImportEnumList(), + value2.getRepeatedImportEnumList()); + assertSame(value1.getRepeatedForeignMessageList(), + value2.getRepeatedForeignMessageList()); + } + + public void testRepeatedArraysAreImmutable() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + builder.addRepeatedInt32(100); + builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR); + builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance()); + assertIsUnmodifiable(builder.getRepeatedInt32List()); + assertIsUnmodifiable(builder.getRepeatedImportEnumList()); + assertIsUnmodifiable(builder.getRepeatedForeignMessageList()); + assertIsUnmodifiable(builder.getRepeatedFloatList()); + + + TestAllTypes value = builder.build(); + assertIsUnmodifiable(value.getRepeatedInt32List()); + assertIsUnmodifiable(value.getRepeatedImportEnumList()); + assertIsUnmodifiable(value.getRepeatedForeignMessageList()); + assertIsUnmodifiable(value.getRepeatedFloatList()); + } + + public void testParsedMessagesAreImmutable() throws Exception { + TestAllTypes value = TestAllTypes.PARSER.parseFrom( + TestUtil.getAllSet().toByteString()); + assertIsUnmodifiable(value.getRepeatedInt32List()); + assertIsUnmodifiable(value.getRepeatedInt64List()); + assertIsUnmodifiable(value.getRepeatedUint32List()); + assertIsUnmodifiable(value.getRepeatedUint64List()); + assertIsUnmodifiable(value.getRepeatedSint32List()); + assertIsUnmodifiable(value.getRepeatedSint64List()); + assertIsUnmodifiable(value.getRepeatedFixed32List()); + assertIsUnmodifiable(value.getRepeatedFixed64List()); + assertIsUnmodifiable(value.getRepeatedSfixed32List()); + assertIsUnmodifiable(value.getRepeatedSfixed64List()); + assertIsUnmodifiable(value.getRepeatedFloatList()); + assertIsUnmodifiable(value.getRepeatedDoubleList()); + assertIsUnmodifiable(value.getRepeatedBoolList()); + assertIsUnmodifiable(value.getRepeatedStringList()); + assertIsUnmodifiable(value.getRepeatedBytesList()); + assertIsUnmodifiable(value.getRepeatedGroupList()); + assertIsUnmodifiable(value.getRepeatedNestedMessageList()); + assertIsUnmodifiable(value.getRepeatedForeignMessageList()); + assertIsUnmodifiable(value.getRepeatedImportMessageList()); + assertIsUnmodifiable(value.getRepeatedNestedEnumList()); + assertIsUnmodifiable(value.getRepeatedForeignEnumList()); + assertIsUnmodifiable(value.getRepeatedImportEnumList()); + } + + private void assertIsUnmodifiable(List list) { + if (list == Collections.emptyList()) { + // OKAY -- Need to check this b/c EmptyList allows you to call clear. + } else { + try { + list.clear(); + fail("List wasn't immutable"); + } catch (UnsupportedOperationException e) { + // good + } + } + } + + public void testSettersRejectNull() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + try { + builder.setOptionalString(null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.setOptionalBytes(null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.setOptionalNestedMessage((TestAllTypes.NestedMessage) null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.setOptionalNestedMessage( + (TestAllTypes.NestedMessage.Builder) null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.setOptionalNestedEnum(null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.addRepeatedString(null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.addRepeatedBytes(null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage) null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.addRepeatedNestedMessage( + (TestAllTypes.NestedMessage.Builder) null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.addRepeatedNestedEnum(null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + } + + public void testRepeatedSetters() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestUtil.setAllFields(builder); + TestUtil.modifyRepeatedFields(builder); + TestAllTypes message = builder.build(); + TestUtil.assertRepeatedFieldsModified(message); + } + + public void testRepeatedSettersRejectNull() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + + builder.addRepeatedString("one"); + builder.addRepeatedString("two"); + try { + builder.setRepeatedString(1, null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + + builder.addRepeatedBytes(TestUtil.toBytes("one")); + builder.addRepeatedBytes(TestUtil.toBytes("two")); + try { + builder.setRepeatedBytes(1, null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + + builder.addRepeatedNestedMessage( + TestAllTypes.NestedMessage.newBuilder().setBb(218).build()); + builder.addRepeatedNestedMessage( + TestAllTypes.NestedMessage.newBuilder().setBb(456).build()); + try { + builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage) null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.setRepeatedNestedMessage( + 1, (TestAllTypes.NestedMessage.Builder) null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + + builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.FOO); + builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR); + try { + builder.setRepeatedNestedEnum(1, null); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + } + + public void testRepeatedAppend() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + + builder.addAllRepeatedInt32(Arrays.asList(1, 2, 3, 4)); + builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ)); + + ForeignMessage foreignMessage = + ForeignMessage.newBuilder().setC(12).build(); + builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage)); + + TestAllTypes message = builder.build(); + assertEquals(message.getRepeatedInt32List(), Arrays.asList(1, 2, 3, 4)); + assertEquals(message.getRepeatedForeignEnumList(), + Arrays.asList(ForeignEnum.FOREIGN_BAZ)); + assertEquals(1, message.getRepeatedForeignMessageCount()); + assertEquals(12, message.getRepeatedForeignMessage(0).getC()); + } + + public void testRepeatedAppendRejectsNull() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + + ForeignMessage foreignMessage = + ForeignMessage.newBuilder().setC(12).build(); + try { + builder.addAllRepeatedForeignMessage( + Arrays.asList(foreignMessage, (ForeignMessage) null)); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + + try { + builder.addAllRepeatedForeignEnum( + Arrays.asList(ForeignEnum.FOREIGN_BAZ, null)); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + + try { + builder.addAllRepeatedString(Arrays.asList("one", null)); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + + try { + builder.addAllRepeatedBytes(Arrays.asList(TestUtil.toBytes("one"), null)); + fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + } + + public void testSettingForeignMessageUsingBuilder() throws Exception { + TestAllTypes message = TestAllTypes.newBuilder() + // Pass builder for foreign message instance. + .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(123)) + .build(); + TestAllTypes expectedMessage = TestAllTypes.newBuilder() + // Create expected version passing foreign message instance explicitly. + .setOptionalForeignMessage( + ForeignMessage.newBuilder().setC(123).build()) + .build(); + // TODO(ngd): Upgrade to using real #equals method once implemented + assertEquals(expectedMessage.toString(), message.toString()); + } + + public void testSettingRepeatedForeignMessageUsingBuilder() throws Exception { + TestAllTypes message = TestAllTypes.newBuilder() + // Pass builder for foreign message instance. + .addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(456)) + .build(); + TestAllTypes expectedMessage = TestAllTypes.newBuilder() + // Create expected version passing foreign message instance explicitly. + .addRepeatedForeignMessage( + ForeignMessage.newBuilder().setC(456).build()) + .build(); + assertEquals(expectedMessage.toString(), message.toString()); + } + + public void testDefaults() throws Exception { + TestUtil.assertClear(TestAllTypes.getDefaultInstance()); + TestUtil.assertClear(TestAllTypes.newBuilder().build()); + + TestExtremeDefaultValues message = + TestExtremeDefaultValues.getDefaultInstance(); + assertEquals("\u1234", message.getUtf8String()); + assertEquals(Double.POSITIVE_INFINITY, message.getInfDouble()); + assertEquals(Double.NEGATIVE_INFINITY, message.getNegInfDouble()); + assertTrue(Double.isNaN(message.getNanDouble())); + assertEquals(Float.POSITIVE_INFINITY, message.getInfFloat()); + assertEquals(Float.NEGATIVE_INFINITY, message.getNegInfFloat()); + assertTrue(Float.isNaN(message.getNanFloat())); + assertEquals("? ? ?? ?? ??? ??/ ??-", message.getCppTrigraph()); + } + + public void testClear() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestUtil.assertClear(builder); + TestUtil.setAllFields(builder); + builder.clear(); + TestUtil.assertClear(builder); + } + + public void testReflectionGetters() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestUtil.setAllFields(builder); + reflectionTester.assertAllFieldsSetViaReflection(builder); + + TestAllTypes message = builder.build(); + reflectionTester.assertAllFieldsSetViaReflection(message); + } + + public void testReflectionSetters() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + reflectionTester.setAllFieldsViaReflection(builder); + TestUtil.assertAllFieldsSet(builder); + + TestAllTypes message = builder.build(); + TestUtil.assertAllFieldsSet(message); + } + + public void testReflectionSettersRejectNull() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + reflectionTester.assertReflectionSettersRejectNull(builder); + } + + public void testReflectionRepeatedSetters() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + reflectionTester.setAllFieldsViaReflection(builder); + reflectionTester.modifyRepeatedFieldsViaReflection(builder); + TestUtil.assertRepeatedFieldsModified(builder); + + TestAllTypes message = builder.build(); + TestUtil.assertRepeatedFieldsModified(message); + } + + public void testReflectionRepeatedSettersRejectNull() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + reflectionTester.assertReflectionRepeatedSettersRejectNull(builder); + } + + public void testReflectionDefaults() throws Exception { + reflectionTester.assertClearViaReflection( + TestAllTypes.getDefaultInstance()); + reflectionTester.assertClearViaReflection( + TestAllTypes.newBuilder().build()); + } + + public void testEnumInterface() throws Exception { + assertTrue(TestAllTypes.getDefaultInstance().getDefaultNestedEnum() + instanceof ProtocolMessageEnum); + } + + public void testEnumMap() throws Exception { + Internal.EnumLiteMap map = ForeignEnum.internalGetValueMap(); + + for (ForeignEnum value : ForeignEnum.values()) { + assertEquals(value, map.findValueByNumber(value.getNumber())); + } + + assertTrue(map.findValueByNumber(12345) == null); + } + + public void testParsePackedToUnpacked() throws Exception { + TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder(); + TestUnpackedTypes message = + builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); + TestUtil.assertUnpackedFieldsSet(message); + } + + public void testParseUnpackedToPacked() throws Exception { + TestPackedTypes.Builder builder = TestPackedTypes.newBuilder(); + TestPackedTypes message = + builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); + TestUtil.assertPackedFieldsSet(message); + } + + // ================================================================= + // Extensions. + + TestUtil.ReflectionTester extensionsReflectionTester = + new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(), + TestUtil.getExtensionRegistry()); + + public void testExtensionMessageOrBuilder() throws Exception { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + TestUtil.setAllExtensions(builder); + TestAllExtensions message = builder.build(); + TestUtil.assertAllExtensionsSet(message); + } + + public void testExtensionRepeatedSetters() throws Exception { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + TestUtil.setAllExtensions(builder); + TestUtil.modifyRepeatedExtensions(builder); + TestAllExtensions message = builder.build(); + TestUtil.assertRepeatedExtensionsModified(message); + } + + public void testExtensionDefaults() throws Exception { + TestUtil.assertExtensionsClear(TestAllExtensions.getDefaultInstance()); + TestUtil.assertExtensionsClear(TestAllExtensions.newBuilder().build()); + } + + public void testExtensionReflectionGetters() throws Exception { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + TestUtil.setAllExtensions(builder); + extensionsReflectionTester.assertAllFieldsSetViaReflection(builder); + + TestAllExtensions message = builder.build(); + extensionsReflectionTester.assertAllFieldsSetViaReflection(message); + } + + public void testExtensionReflectionSetters() throws Exception { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + extensionsReflectionTester.setAllFieldsViaReflection(builder); + TestUtil.assertAllExtensionsSet(builder); + + TestAllExtensions message = builder.build(); + TestUtil.assertAllExtensionsSet(message); + } + + public void testExtensionReflectionSettersRejectNull() throws Exception { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + extensionsReflectionTester.assertReflectionSettersRejectNull(builder); + } + + public void testExtensionReflectionRepeatedSetters() throws Exception { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + extensionsReflectionTester.setAllFieldsViaReflection(builder); + extensionsReflectionTester.modifyRepeatedFieldsViaReflection(builder); + TestUtil.assertRepeatedExtensionsModified(builder); + + TestAllExtensions message = builder.build(); + TestUtil.assertRepeatedExtensionsModified(message); + } + + public void testExtensionReflectionRepeatedSettersRejectNull() + throws Exception { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + extensionsReflectionTester.assertReflectionRepeatedSettersRejectNull( + builder); + } + + public void testExtensionReflectionDefaults() throws Exception { + extensionsReflectionTester.assertClearViaReflection( + TestAllExtensions.getDefaultInstance()); + extensionsReflectionTester.assertClearViaReflection( + TestAllExtensions.newBuilder().build()); + } + + public void testClearExtension() throws Exception { + // clearExtension() is not actually used in TestUtil, so try it manually. + assertFalse( + TestAllExtensions.newBuilder() + .setExtension(UnittestProto.optionalInt32Extension, 1) + .clearExtension(UnittestProto.optionalInt32Extension) + .hasExtension(UnittestProto.optionalInt32Extension)); + assertEquals(0, + TestAllExtensions.newBuilder() + .addExtension(UnittestProto.repeatedInt32Extension, 1) + .clearExtension(UnittestProto.repeatedInt32Extension) + .getExtensionCount(UnittestProto.repeatedInt32Extension)); + } + + public void testExtensionCopy() throws Exception { + TestAllExtensions original = TestUtil.getAllExtensionsSet(); + TestAllExtensions copy = TestAllExtensions.newBuilder(original).build(); + TestUtil.assertAllExtensionsSet(copy); + } + + public void testExtensionMergeFrom() throws Exception { + TestAllExtensions original = + TestAllExtensions.newBuilder() + .setExtension(UnittestProto.optionalInt32Extension, 1).build(); + TestAllExtensions merged = + TestAllExtensions.newBuilder().mergeFrom(original).build(); + assertTrue(merged.hasExtension(UnittestProto.optionalInt32Extension)); + assertEquals( + 1, (int) merged.getExtension(UnittestProto.optionalInt32Extension)); + } + + // ================================================================= + // Lite Extensions. + + // We test lite extensions directly because they have a separate + // implementation from full extensions. In contrast, we do not test + // lite fields directly since they are implemented exactly the same as + // regular fields. + + public void testLiteExtensionMessageOrBuilder() throws Exception { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder(); + TestUtil.setAllExtensions(builder); + TestUtil.assertAllExtensionsSet(builder); + + TestAllExtensionsLite message = builder.build(); + TestUtil.assertAllExtensionsSet(message); + } + + public void testLiteExtensionRepeatedSetters() throws Exception { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder(); + TestUtil.setAllExtensions(builder); + TestUtil.modifyRepeatedExtensions(builder); + TestUtil.assertRepeatedExtensionsModified(builder); + + TestAllExtensionsLite message = builder.build(); + TestUtil.assertRepeatedExtensionsModified(message); + } + + public void testLiteExtensionDefaults() throws Exception { + TestUtil.assertExtensionsClear(TestAllExtensionsLite.getDefaultInstance()); + TestUtil.assertExtensionsClear(TestAllExtensionsLite.newBuilder().build()); + } + + public void testClearLiteExtension() throws Exception { + // clearExtension() is not actually used in TestUtil, so try it manually. + assertFalse( + TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 1) + .clearExtension(UnittestLite.optionalInt32ExtensionLite) + .hasExtension(UnittestLite.optionalInt32ExtensionLite)); + assertEquals(0, + TestAllExtensionsLite.newBuilder() + .addExtension(UnittestLite.repeatedInt32ExtensionLite, 1) + .clearExtension(UnittestLite.repeatedInt32ExtensionLite) + .getExtensionCount(UnittestLite.repeatedInt32ExtensionLite)); + } + + public void testLiteExtensionCopy() throws Exception { + TestAllExtensionsLite original = TestUtil.getAllLiteExtensionsSet(); + TestAllExtensionsLite copy = + TestAllExtensionsLite.newBuilder(original).build(); + TestUtil.assertAllExtensionsSet(copy); + } + + public void testLiteExtensionMergeFrom() throws Exception { + TestAllExtensionsLite original = + TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 1).build(); + TestAllExtensionsLite merged = + TestAllExtensionsLite.newBuilder().mergeFrom(original).build(); + assertTrue(merged.hasExtension(UnittestLite.optionalInt32ExtensionLite)); + assertEquals( + 1, (int) merged.getExtension(UnittestLite.optionalInt32ExtensionLite)); + } + + // ================================================================= + // multiple_files_test + + public void testMultipleFilesOption() throws Exception { + // We mostly just want to check that things compile. + MessageWithNoOuter message = + MessageWithNoOuter.newBuilder() + .setNested(MessageWithNoOuter.NestedMessage.newBuilder().setI(1)) + .addForeign(TestAllTypes.newBuilder().setOptionalInt32(1)) + .setNestedEnum(MessageWithNoOuter.NestedEnum.BAZ) + .setForeignEnum(EnumWithNoOuter.BAR) + .build(); + assertEquals(message, MessageWithNoOuter.parseFrom(message.toByteString())); + + assertEquals(MultipleFilesTestProto.getDescriptor(), + MessageWithNoOuter.getDescriptor().getFile()); + + Descriptors.FieldDescriptor field = + MessageWithNoOuter.getDescriptor().findFieldByName("foreign_enum"); + assertEquals(EnumWithNoOuter.BAR.getValueDescriptor(), + message.getField(field)); + + assertEquals(MultipleFilesTestProto.getDescriptor(), + ServiceWithNoOuter.getDescriptor().getFile()); + + assertFalse( + TestAllExtensions.getDefaultInstance().hasExtension( + MultipleFilesTestProto.extensionWithOuter)); + } + + public void testOptionalFieldWithRequiredSubfieldsOptimizedForSize() + throws Exception { + TestOptionalOptimizedForSize message = + TestOptionalOptimizedForSize.getDefaultInstance(); + assertTrue(message.isInitialized()); + + message = TestOptionalOptimizedForSize.newBuilder().setO( + TestRequiredOptimizedForSize.newBuilder().buildPartial() + ).buildPartial(); + assertFalse(message.isInitialized()); + + message = TestOptionalOptimizedForSize.newBuilder().setO( + TestRequiredOptimizedForSize.newBuilder().setX(5).buildPartial() + ).buildPartial(); + assertTrue(message.isInitialized()); + } + + public void testUninitializedExtensionInOptimizedForSize() + throws Exception { + TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder(); + builder.setExtension(TestOptimizedForSize.testExtension2, + TestRequiredOptimizedForSize.newBuilder().buildPartial()); + assertFalse(builder.isInitialized()); + assertFalse(builder.buildPartial().isInitialized()); + + builder = TestOptimizedForSize.newBuilder(); + builder.setExtension(TestOptimizedForSize.testExtension2, + TestRequiredOptimizedForSize.newBuilder().setX(10).buildPartial()); + assertTrue(builder.isInitialized()); + assertTrue(builder.buildPartial().isInitialized()); + } + + public void testToBuilder() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestUtil.setAllFields(builder); + TestAllTypes message = builder.build(); + TestUtil.assertAllFieldsSet(message); + TestUtil.assertAllFieldsSet(message.toBuilder().build()); + } + + public void testFieldConstantValues() throws Exception { + assertEquals(TestAllTypes.NestedMessage.BB_FIELD_NUMBER, 1); + assertEquals(TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, 1); + assertEquals(TestAllTypes.OPTIONALGROUP_FIELD_NUMBER, 16); + assertEquals(TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER, 18); + assertEquals(TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER, 21); + assertEquals(TestAllTypes.REPEATED_INT32_FIELD_NUMBER, 31); + assertEquals(TestAllTypes.REPEATEDGROUP_FIELD_NUMBER, 46); + assertEquals(TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER, 48); + assertEquals(TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER, 51); + } + + public void testExtensionConstantValues() throws Exception { + assertEquals(UnittestProto.TestRequired.SINGLE_FIELD_NUMBER, 1000); + assertEquals(UnittestProto.TestRequired.MULTI_FIELD_NUMBER, 1001); + assertEquals(UnittestProto.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER, 1); + assertEquals(UnittestProto.OPTIONALGROUP_EXTENSION_FIELD_NUMBER, 16); + assertEquals( + UnittestProto.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 18); + assertEquals(UnittestProto.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 21); + assertEquals(UnittestProto.REPEATED_INT32_EXTENSION_FIELD_NUMBER, 31); + assertEquals(UnittestProto.REPEATEDGROUP_EXTENSION_FIELD_NUMBER, 46); + assertEquals( + UnittestProto.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48); + assertEquals(UnittestProto.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 51); + } + + public void testRecursiveMessageDefaultInstance() throws Exception { + UnittestProto.TestRecursiveMessage message = + UnittestProto.TestRecursiveMessage.getDefaultInstance(); + assertTrue(message != null); + assertTrue(message.getA() != null); + assertTrue(message.getA() == message); + } + + public void testSerialize() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestUtil.setAllFields(builder); + TestAllTypes expected = builder.build(); + ObjectOutputStream out = new ObjectOutputStream(baos); + try { + out.writeObject(expected); + } finally { + out.close(); + } + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bais); + TestAllTypes actual = (TestAllTypes) in.readObject(); + assertEquals(expected, actual); + } + + public void testSerializePartial() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestAllTypes expected = builder.buildPartial(); + ObjectOutputStream out = new ObjectOutputStream(baos); + try { + out.writeObject(expected); + } finally { + out.close(); + } + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bais); + TestAllTypes actual = (TestAllTypes) in.readObject(); + assertEquals(expected, actual); + } + + public void testEnumValues() { + assertEquals( + TestAllTypes.NestedEnum.BAR.getNumber(), + TestAllTypes.NestedEnum.BAR_VALUE); + assertEquals( + TestAllTypes.NestedEnum.BAZ.getNumber(), + TestAllTypes.NestedEnum.BAZ_VALUE); + assertEquals( + TestAllTypes.NestedEnum.FOO.getNumber(), + TestAllTypes.NestedEnum.FOO_VALUE); + } + + public void testNonNestedExtensionInitialization() { + assertTrue(NonNestedExtension.nonNestedExtension + .getMessageDefaultInstance() instanceof MyNonNestedExtension); + assertEquals("nonNestedExtension", + NonNestedExtension.nonNestedExtension.getDescriptor().getName()); + } + + public void testNestedExtensionInitialization() { + assertTrue(MyNestedExtension.recursiveExtension.getMessageDefaultInstance() + instanceof MessageToBeExtended); + assertEquals("recursiveExtension", + MyNestedExtension.recursiveExtension.getDescriptor().getName()); + } + + public void testNonNestedExtensionLiteInitialization() { + assertTrue(NonNestedExtensionLite.nonNestedExtensionLite + .getMessageDefaultInstance() instanceof MyNonNestedExtensionLite); + } + + public void testNestedExtensionLiteInitialization() { + assertTrue(MyNestedExtensionLite.recursiveExtensionLite + .getMessageDefaultInstance() instanceof MessageLiteToBeExtended); + } + + public void testInvalidations() throws Exception { + GeneratedMessage.enableAlwaysUseFieldBuildersForTesting(); + TestAllTypes.NestedMessage nestedMessage1 = + TestAllTypes.NestedMessage.newBuilder().build(); + TestAllTypes.NestedMessage nestedMessage2 = + TestAllTypes.NestedMessage.newBuilder().build(); + + // Set all three flavors (enum, primitive, message and singular/repeated) + // and verify no invalidations fired + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + + TestAllTypes.Builder builder = (TestAllTypes.Builder) + ((GeneratedMessage) TestAllTypes.getDefaultInstance()). + newBuilderForType(mockParent); + builder.setOptionalInt32(1); + builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR); + builder.setOptionalNestedMessage(nestedMessage1); + builder.addRepeatedInt32(1); + builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR); + builder.addRepeatedNestedMessage(nestedMessage1); + assertEquals(0, mockParent.getInvalidationCount()); + + // Now tell it we want changes and make sure it's only fired once + // And do this for each flavor + + // primitive single + builder.buildPartial(); + builder.setOptionalInt32(2); + builder.setOptionalInt32(3); + assertEquals(1, mockParent.getInvalidationCount()); + + // enum single + builder.buildPartial(); + builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ); + builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR); + assertEquals(2, mockParent.getInvalidationCount()); + + // message single + builder.buildPartial(); + builder.setOptionalNestedMessage(nestedMessage2); + builder.setOptionalNestedMessage(nestedMessage1); + assertEquals(3, mockParent.getInvalidationCount()); + + // primitive repeated + builder.buildPartial(); + builder.addRepeatedInt32(2); + builder.addRepeatedInt32(3); + assertEquals(4, mockParent.getInvalidationCount()); + + // enum repeated + builder.buildPartial(); + builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ); + builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ); + assertEquals(5, mockParent.getInvalidationCount()); + + // message repeated + builder.buildPartial(); + builder.addRepeatedNestedMessage(nestedMessage2); + builder.addRepeatedNestedMessage(nestedMessage1); + assertEquals(6, mockParent.getInvalidationCount()); + + } + + public void testInvalidations_Extensions() throws Exception { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + + TestAllExtensions.Builder builder = (TestAllExtensions.Builder) + ((GeneratedMessage) TestAllExtensions.getDefaultInstance()). + newBuilderForType(mockParent); + + builder.addExtension(UnittestProto.repeatedInt32Extension, 1); + builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 2); + builder.clearExtension(UnittestProto.repeatedInt32Extension); + assertEquals(0, mockParent.getInvalidationCount()); + + // Now tell it we want changes and make sure it's only fired once + builder.buildPartial(); + builder.addExtension(UnittestProto.repeatedInt32Extension, 2); + builder.addExtension(UnittestProto.repeatedInt32Extension, 3); + assertEquals(1, mockParent.getInvalidationCount()); + + builder.buildPartial(); + builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 4); + builder.setExtension(UnittestProto.repeatedInt32Extension, 1, 5); + assertEquals(2, mockParent.getInvalidationCount()); + + builder.buildPartial(); + builder.clearExtension(UnittestProto.repeatedInt32Extension); + builder.clearExtension(UnittestProto.repeatedInt32Extension); + assertEquals(3, mockParent.getInvalidationCount()); + } + + public void testBaseMessageOrBuilder() { + // Mostly just makes sure the base interface exists and has some methods. + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestAllTypes message = builder.buildPartial(); + TestAllTypesOrBuilder builderAsInterface = (TestAllTypesOrBuilder) builder; + TestAllTypesOrBuilder messageAsInterface = (TestAllTypesOrBuilder) message; + + assertEquals( + messageAsInterface.getDefaultBool(), + messageAsInterface.getDefaultBool()); + assertEquals( + messageAsInterface.getOptionalDouble(), + messageAsInterface.getOptionalDouble()); + } + + public void testMessageOrBuilderGetters() { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + + // single fields + assertSame(ForeignMessage.getDefaultInstance(), + builder.getOptionalForeignMessageOrBuilder()); + ForeignMessage.Builder subBuilder = + builder.getOptionalForeignMessageBuilder(); + assertSame(subBuilder, builder.getOptionalForeignMessageOrBuilder()); + + // repeated fields + ForeignMessage m0 = ForeignMessage.newBuilder().buildPartial(); + ForeignMessage m1 = ForeignMessage.newBuilder().buildPartial(); + ForeignMessage m2 = ForeignMessage.newBuilder().buildPartial(); + builder.addRepeatedForeignMessage(m0); + builder.addRepeatedForeignMessage(m1); + builder.addRepeatedForeignMessage(m2); + assertSame(m0, builder.getRepeatedForeignMessageOrBuilder(0)); + assertSame(m1, builder.getRepeatedForeignMessageOrBuilder(1)); + assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2)); + ForeignMessage.Builder b0 = builder.getRepeatedForeignMessageBuilder(0); + ForeignMessage.Builder b1 = builder.getRepeatedForeignMessageBuilder(1); + assertSame(b0, builder.getRepeatedForeignMessageOrBuilder(0)); + assertSame(b1, builder.getRepeatedForeignMessageOrBuilder(1)); + assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2)); + + List messageOrBuilderList = + builder.getRepeatedForeignMessageOrBuilderList(); + assertSame(b0, messageOrBuilderList.get(0)); + assertSame(b1, messageOrBuilderList.get(1)); + assertSame(m2, messageOrBuilderList.get(2)); + } + + public void testGetFieldBuilder() { + Descriptor descriptor = TestAllTypes.getDescriptor(); + + FieldDescriptor fieldDescriptor = + descriptor.findFieldByName("optional_nested_message"); + FieldDescriptor foreignFieldDescriptor = + descriptor.findFieldByName("optional_foreign_message"); + FieldDescriptor importFieldDescriptor = + descriptor.findFieldByName("optional_import_message"); + + // Mutate the message with new field builder + // Mutate nested message + TestAllTypes.Builder builder1 = TestAllTypes.newBuilder(); + Message.Builder fieldBuilder1 = builder1.newBuilderForField(fieldDescriptor) + .mergeFrom((Message) builder1.getField(fieldDescriptor)); + FieldDescriptor subFieldDescriptor1 = + fieldBuilder1.getDescriptorForType().findFieldByName("bb"); + fieldBuilder1.setField(subFieldDescriptor1, 1); + builder1.setField(fieldDescriptor, fieldBuilder1.build()); + + // Mutate foreign message + Message.Builder foreignFieldBuilder1 = builder1.newBuilderForField( + foreignFieldDescriptor) + .mergeFrom((Message) builder1.getField(foreignFieldDescriptor)); + FieldDescriptor subForeignFieldDescriptor1 = + foreignFieldBuilder1.getDescriptorForType().findFieldByName("c"); + foreignFieldBuilder1.setField(subForeignFieldDescriptor1, 2); + builder1.setField(foreignFieldDescriptor, foreignFieldBuilder1.build()); + + // Mutate import message + Message.Builder importFieldBuilder1 = builder1.newBuilderForField( + importFieldDescriptor) + .mergeFrom((Message) builder1.getField(importFieldDescriptor)); + FieldDescriptor subImportFieldDescriptor1 = + importFieldBuilder1.getDescriptorForType().findFieldByName("d"); + importFieldBuilder1.setField(subImportFieldDescriptor1, 3); + builder1.setField(importFieldDescriptor, importFieldBuilder1.build()); + + Message newMessage1 = builder1.build(); + + // Mutate the message with existing field builder + // Mutate nested message + TestAllTypes.Builder builder2 = TestAllTypes.newBuilder(); + Message.Builder fieldBuilder2 = builder2.getFieldBuilder(fieldDescriptor); + FieldDescriptor subFieldDescriptor2 = + fieldBuilder2.getDescriptorForType().findFieldByName("bb"); + fieldBuilder2.setField(subFieldDescriptor2, 1); + builder2.setField(fieldDescriptor, fieldBuilder2.build()); + + // Mutate foreign message + Message.Builder foreignFieldBuilder2 = builder2.newBuilderForField( + foreignFieldDescriptor) + .mergeFrom((Message) builder2.getField(foreignFieldDescriptor)); + FieldDescriptor subForeignFieldDescriptor2 = + foreignFieldBuilder2.getDescriptorForType().findFieldByName("c"); + foreignFieldBuilder2.setField(subForeignFieldDescriptor2, 2); + builder2.setField(foreignFieldDescriptor, foreignFieldBuilder2.build()); + + // Mutate import message + Message.Builder importFieldBuilder2 = builder2.newBuilderForField( + importFieldDescriptor) + .mergeFrom((Message) builder2.getField(importFieldDescriptor)); + FieldDescriptor subImportFieldDescriptor2 = + importFieldBuilder2.getDescriptorForType().findFieldByName("d"); + importFieldBuilder2.setField(subImportFieldDescriptor2, 3); + builder2.setField(importFieldDescriptor, importFieldBuilder2.build()); + + Message newMessage2 = builder2.build(); + + // These two messages should be equal. + assertEquals(newMessage1, newMessage2); + } + + public void testGetFieldBuilderWithInitializedValue() { + Descriptor descriptor = TestAllTypes.getDescriptor(); + FieldDescriptor fieldDescriptor = + descriptor.findFieldByName("optional_nested_message"); + + // Before setting field, builder is initialized by default value. + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + NestedMessage.Builder fieldBuilder = + (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor); + assertEquals(0, fieldBuilder.getBb()); + + // Setting field value with new field builder instance. + builder = TestAllTypes.newBuilder(); + NestedMessage.Builder newFieldBuilder = + builder.getOptionalNestedMessageBuilder(); + newFieldBuilder.setBb(2); + // Then get the field builder instance by getFieldBuilder(). + fieldBuilder = + (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor); + // It should contain new value. + assertEquals(2, fieldBuilder.getBb()); + // These two builder should be equal. + assertSame(fieldBuilder, newFieldBuilder); + } + + public void testGetFieldBuilderNotSupportedException() { + Descriptor descriptor = TestAllTypes.getDescriptor(); + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + try { + builder.getFieldBuilder(descriptor.findFieldByName("optional_int32")); + fail("Exception was not thrown"); + } catch (UnsupportedOperationException e) { + // We expect this exception. + } + try { + builder.getFieldBuilder( + descriptor.findFieldByName("optional_nested_enum")); + fail("Exception was not thrown"); + } catch (UnsupportedOperationException e) { + // We expect this exception. + } + try { + builder.getFieldBuilder(descriptor.findFieldByName("repeated_int32")); + fail("Exception was not thrown"); + } catch (UnsupportedOperationException e) { + // We expect this exception. + } + try { + builder.getFieldBuilder( + descriptor.findFieldByName("repeated_nested_enum")); + fail("Exception was not thrown"); + } catch (UnsupportedOperationException e) { + // We expect this exception. + } + try { + builder.getFieldBuilder( + descriptor.findFieldByName("repeated_nested_message")); + fail("Exception was not thrown"); + } catch (UnsupportedOperationException e) { + // We expect this exception. + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java new file mode 100644 index 0000000..b204b60 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java @@ -0,0 +1,180 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.IsValidUtf8TestUtil.Shard; + +import junit.framework.TestCase; + +import java.io.UnsupportedEncodingException; + +/** + * Tests cases for {@link ByteString#isValidUtf8()}. This includes three + * brute force tests that actually test every permutation of one byte, two byte, + * and three byte sequences to ensure that the method produces the right result + * for every possible byte encoding where "right" means it's consistent with + * java's UTF-8 string encoding/decoding such that the method returns true for + * any sequence that will round trip when converted to a String and then back to + * bytes and will return false for any sequence that will not round trip. + * See also {@link IsValidUtf8FourByteTest}. It also includes some + * other more targeted tests. + * + * @author jonp@google.com (Jon Perlow) + * @author martinrb@google.com (Martin Buchholz) + */ +public class IsValidUtf8Test extends TestCase { + + /** + * Tests that round tripping of all two byte permutations work. + */ + public void testIsValidUtf8_1Byte() throws UnsupportedEncodingException { + IsValidUtf8TestUtil.testBytes(1, + IsValidUtf8TestUtil.EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT); + } + + /** + * Tests that round tripping of all two byte permutations work. + */ + public void testIsValidUtf8_2Bytes() throws UnsupportedEncodingException { + IsValidUtf8TestUtil.testBytes(2, + IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT); + } + + /** + * Tests that round tripping of all three byte permutations work. + */ + public void testIsValidUtf8_3Bytes() throws UnsupportedEncodingException { + IsValidUtf8TestUtil.testBytes(3, + IsValidUtf8TestUtil.EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT); + } + + /** + * Tests that round tripping of a sample of four byte permutations work. + * All permutations are prohibitively expensive to test for automated runs; + * {@link IsValidUtf8FourByteTest} is used for full coverage. This method + * tests specific four-byte cases. + */ + public void testIsValidUtf8_4BytesSamples() + throws UnsupportedEncodingException { + // Valid 4 byte. + assertValidUtf8(0xF0, 0xA4, 0xAD, 0xA2); + + // Bad trailing bytes + assertInvalidUtf8(0xF0, 0xA4, 0xAD, 0x7F); + assertInvalidUtf8(0xF0, 0xA4, 0xAD, 0xC0); + + // Special cases for byte2 + assertInvalidUtf8(0xF0, 0x8F, 0xAD, 0xA2); + assertInvalidUtf8(0xF4, 0x90, 0xAD, 0xA2); + } + + /** + * Tests some hard-coded test cases. + */ + public void testSomeSequences() { + // Empty + assertTrue(asBytes("").isValidUtf8()); + + // One-byte characters, including control characters + assertTrue(asBytes("\u0000abc\u007f").isValidUtf8()); + + // Two-byte characters + assertTrue(asBytes("\u00a2\u00a2").isValidUtf8()); + + // Three-byte characters + assertTrue(asBytes("\u020ac\u020ac").isValidUtf8()); + + // Four-byte characters + assertTrue(asBytes("\u024B62\u024B62").isValidUtf8()); + + // Mixed string + assertTrue( + asBytes("a\u020ac\u00a2b\\u024B62u020acc\u00a2de\u024B62") + .isValidUtf8()); + + // Not a valid string + assertInvalidUtf8(-1, 0, -1, 0); + } + + private byte[] toByteArray(int... bytes) { + byte[] realBytes = new byte[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + realBytes[i] = (byte) bytes[i]; + } + return realBytes; + } + + private ByteString toByteString(int... bytes) { + return ByteString.copyFrom(toByteArray(bytes)); + } + + private void assertValidUtf8(int[] bytes, boolean not) { + byte[] realBytes = toByteArray(bytes); + assertTrue(not ^ Utf8.isValidUtf8(realBytes)); + assertTrue(not ^ Utf8.isValidUtf8(realBytes, 0, bytes.length)); + ByteString lit = ByteString.copyFrom(realBytes); + ByteString sub = lit.substring(0, bytes.length); + assertTrue(not ^ lit.isValidUtf8()); + assertTrue(not ^ sub.isValidUtf8()); + ByteString[] ropes = { + RopeByteString.newInstanceForTest(ByteString.EMPTY, lit), + RopeByteString.newInstanceForTest(ByteString.EMPTY, sub), + RopeByteString.newInstanceForTest(lit, ByteString.EMPTY), + RopeByteString.newInstanceForTest(sub, ByteString.EMPTY), + RopeByteString.newInstanceForTest(sub, lit) + }; + for (ByteString rope : ropes) { + assertTrue(not ^ rope.isValidUtf8()); + } + } + + private void assertValidUtf8(int... bytes) { + assertValidUtf8(bytes, false); + } + + private void assertInvalidUtf8(int... bytes) { + assertValidUtf8(bytes, true); + } + + private static ByteString asBytes(String s) { + return ByteString.copyFromUtf8(s); + } + + public void testShardsHaveExpectedRoundTrippables() { + // A sanity check. + int actual = 0; + for (Shard shard : IsValidUtf8TestUtil.FOUR_BYTE_SHARDS) { + actual += shard.expected; + } + assertEquals(IsValidUtf8TestUtil.EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT, + actual); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java new file mode 100644 index 0000000..4cb3d5b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java @@ -0,0 +1,421 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import static junit.framework.Assert.*; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.logging.Logger; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.Charset; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; + +/** + * Shared testing code for {@link IsValidUtf8Test} and + * {@link IsValidUtf8FourByteTest}. + * + * @author jonp@google.com (Jon Perlow) + * @author martinrb@google.com (Martin Buchholz) + */ +class IsValidUtf8TestUtil { + private static Logger logger = Logger.getLogger( + IsValidUtf8TestUtil.class.getName()); + + // 128 - [chars 0x0000 to 0x007f] + static long ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x007f - 0x0000 + 1; + + // 128 + static long EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT = + ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS; + + // 1920 [chars 0x0080 to 0x07FF] + static long TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x07FF - 0x0080 + 1; + + // 18,304 + static long EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT = + // Both bytes are one byte characters + (long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 2) + + // The possible number of two byte characters + TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS; + + // 2048 + static long THREE_BYTE_SURROGATES = 2 * 1024; + + // 61,440 [chars 0x0800 to 0xFFFF, minus surrogates] + static long THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS = + 0xFFFF - 0x0800 + 1 - THREE_BYTE_SURROGATES; + + // 2,650,112 + static long EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT = + // All one byte characters + (long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 3) + + // One two byte character and a one byte character + 2 * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS * + ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS + + // Three byte characters + THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS; + + // 1,048,576 [chars 0x10000L to 0x10FFFF] + static long FOUR_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x10FFFF - 0x10000L + 1; + + // 289,571,839 + static long EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT = + // All one byte characters + (long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 4) + + // One and three byte characters + 2 * THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS * + ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS + + // Two two byte characters + TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS + + // Permutations of one and two byte characters + 3 * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS * + ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS * + ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS + + // Four byte characters + FOUR_BYTE_ROUNDTRIPPABLE_CHARACTERS; + + static class Shard { + final long index; + final long start; + final long lim; + final long expected; + + + public Shard(long index, long start, long lim, long expected) { + assertTrue(start < lim); + this.index = index; + this.start = start; + this.lim = lim; + this.expected = expected; + } + } + + static final long[] FOUR_BYTE_SHARDS_EXPECTED_ROUNTRIPPABLES = + generateFourByteShardsExpectedRunnables(); + + private static long[] generateFourByteShardsExpectedRunnables() { + long[] expected = new long[128]; + + // 0-63 are all 5300224 + for (int i = 0; i <= 63; i++) { + expected[i] = 5300224; + } + + // 97-111 are all 2342912 + for (int i = 97; i <= 111; i++) { + expected[i] = 2342912; + } + + // 113-117 are all 1048576 + for (int i = 113; i <= 117; i++) { + expected[i] = 1048576; + } + + // One offs + expected[112] = 786432; + expected[118] = 786432; + expected[119] = 1048576; + expected[120] = 458752; + expected[121] = 524288; + expected[122] = 65536; + + // Anything not assigned was the default 0. + return expected; + } + + static final List FOUR_BYTE_SHARDS = generateFourByteShards( + 128, FOUR_BYTE_SHARDS_EXPECTED_ROUNTRIPPABLES); + + + private static List generateFourByteShards( + int numShards, long[] expected) { + assertEquals(numShards, expected.length); + List shards = new ArrayList(numShards); + long LIM = 1L << 32; + long increment = LIM / numShards; + assertTrue(LIM % numShards == 0); + for (int i = 0; i < numShards; i++) { + shards.add(new Shard(i, + increment * i, + increment * (i + 1), + expected[i])); + } + return shards; + } + + /** + * Helper to run the loop to test all the permutations for the number of bytes + * specified. + * + * @param numBytes the number of bytes in the byte array + * @param expectedCount the expected number of roundtrippable permutations + */ + static void testBytes(int numBytes, long expectedCount) + throws UnsupportedEncodingException { + testBytes(numBytes, expectedCount, 0, -1); + } + + /** + * Helper to run the loop to test all the permutations for the number of bytes + * specified. This overload is useful for debugging to get the loop to start + * at a certain character. + * + * @param numBytes the number of bytes in the byte array + * @param expectedCount the expected number of roundtrippable permutations + * @param start the starting bytes encoded as a long as big-endian + * @param lim the limit of bytes to process encoded as a long as big-endian, + * or -1 to mean the max limit for numBytes + */ + static void testBytes(int numBytes, long expectedCount, long start, long lim) + throws UnsupportedEncodingException { + Random rnd = new Random(); + byte[] bytes = new byte[numBytes]; + + if (lim == -1) { + lim = 1L << (numBytes * 8); + } + long count = 0; + long countRoundTripped = 0; + for (long byteChar = start; byteChar < lim; byteChar++) { + long tmpByteChar = byteChar; + for (int i = 0; i < numBytes; i++) { + bytes[bytes.length - i - 1] = (byte) tmpByteChar; + tmpByteChar = tmpByteChar >> 8; + } + ByteString bs = ByteString.copyFrom(bytes); + boolean isRoundTrippable = bs.isValidUtf8(); + String s = new String(bytes, "UTF-8"); + byte[] bytesReencoded = s.getBytes("UTF-8"); + boolean bytesEqual = Arrays.equals(bytes, bytesReencoded); + + if (bytesEqual != isRoundTrippable) { + outputFailure(byteChar, bytes, bytesReencoded); + } + + // Check agreement with static Utf8 methods. + assertEquals(isRoundTrippable, Utf8.isValidUtf8(bytes)); + assertEquals(isRoundTrippable, Utf8.isValidUtf8(bytes, 0, numBytes)); + + // Test partial sequences. + // Partition numBytes into three segments (not necessarily non-empty). + int i = rnd.nextInt(numBytes); + int j = rnd.nextInt(numBytes); + if (j < i) { + int tmp = i; i = j; j = tmp; + } + int state1 = Utf8.partialIsValidUtf8(Utf8.COMPLETE, bytes, 0, i); + int state2 = Utf8.partialIsValidUtf8(state1, bytes, i, j); + int state3 = Utf8.partialIsValidUtf8(state2, bytes, j, numBytes); + if (isRoundTrippable != (state3 == Utf8.COMPLETE)) { + System.out.printf("state=%04x %04x %04x i=%d j=%d%n", + state1, state2, state3, i, j); + outputFailure(byteChar, bytes, bytesReencoded); + } + assertEquals(isRoundTrippable, (state3 == Utf8.COMPLETE)); + + // Test ropes built out of small partial sequences + ByteString rope = RopeByteString.newInstanceForTest( + bs.substring(0, i), + RopeByteString.newInstanceForTest( + bs.substring(i, j), + bs.substring(j, numBytes))); + assertSame(RopeByteString.class, rope.getClass()); + + ByteString[] byteStrings = { bs, bs.substring(0, numBytes), rope }; + for (ByteString x : byteStrings) { + assertEquals(isRoundTrippable, + x.isValidUtf8()); + assertEquals(state3, + x.partialIsValidUtf8(Utf8.COMPLETE, 0, numBytes)); + + assertEquals(state1, + x.partialIsValidUtf8(Utf8.COMPLETE, 0, i)); + assertEquals(state1, + x.substring(0, i).partialIsValidUtf8(Utf8.COMPLETE, 0, i)); + assertEquals(state2, + x.partialIsValidUtf8(state1, i, j - i)); + assertEquals(state2, + x.substring(i, j).partialIsValidUtf8(state1, 0, j - i)); + assertEquals(state3, + x.partialIsValidUtf8(state2, j, numBytes - j)); + assertEquals(state3, + x.substring(j, numBytes) + .partialIsValidUtf8(state2, 0, numBytes - j)); + } + + // ByteString reduplication should not affect its UTF-8 validity. + ByteString ropeADope = + RopeByteString.newInstanceForTest(bs, bs.substring(0, numBytes)); + assertEquals(isRoundTrippable, ropeADope.isValidUtf8()); + + if (isRoundTrippable) { + countRoundTripped++; + } + count++; + if (byteChar != 0 && byteChar % 1000000L == 0) { + logger.info("Processed " + (byteChar / 1000000L) + + " million characters"); + } + } + logger.info("Round tripped " + countRoundTripped + " of " + count); + assertEquals(expectedCount, countRoundTripped); + } + + /** + * Variation of {@link #testBytes} that does less allocation using the + * low-level encoders/decoders directly. Checked in because it's useful for + * debugging when trying to process bytes faster, but since it doesn't use the + * actual String class, it's possible for incompatibilities to develop + * (although unlikely). + * + * @param numBytes the number of bytes in the byte array + * @param expectedCount the expected number of roundtrippable permutations + * @param start the starting bytes encoded as a long as big-endian + * @param lim the limit of bytes to process encoded as a long as big-endian, + * or -1 to mean the max limit for numBytes + */ + void testBytesUsingByteBuffers( + int numBytes, long expectedCount, long start, long lim) + throws UnsupportedEncodingException { + CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); + CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); + byte[] bytes = new byte[numBytes]; + int maxChars = (int) (decoder.maxCharsPerByte() * numBytes) + 1; + char[] charsDecoded = + new char[(int) (decoder.maxCharsPerByte() * numBytes) + 1]; + int maxBytes = (int) (encoder.maxBytesPerChar() * maxChars) + 1; + byte[] bytesReencoded = new byte[maxBytes]; + + ByteBuffer bb = ByteBuffer.wrap(bytes); + CharBuffer cb = CharBuffer.wrap(charsDecoded); + ByteBuffer bbReencoded = ByteBuffer.wrap(bytesReencoded); + if (lim == -1) { + lim = 1L << (numBytes * 8); + } + long count = 0; + long countRoundTripped = 0; + for (long byteChar = start; byteChar < lim; byteChar++) { + bb.rewind(); + bb.limit(bytes.length); + cb.rewind(); + cb.limit(charsDecoded.length); + bbReencoded.rewind(); + bbReencoded.limit(bytesReencoded.length); + encoder.reset(); + decoder.reset(); + long tmpByteChar = byteChar; + for (int i = 0; i < bytes.length; i++) { + bytes[bytes.length - i - 1] = (byte) tmpByteChar; + tmpByteChar = tmpByteChar >> 8; + } + boolean isRoundTrippable = ByteString.copyFrom(bytes).isValidUtf8(); + CoderResult result = decoder.decode(bb, cb, true); + assertFalse(result.isError()); + result = decoder.flush(cb); + assertFalse(result.isError()); + + int charLen = cb.position(); + cb.rewind(); + cb.limit(charLen); + result = encoder.encode(cb, bbReencoded, true); + assertFalse(result.isError()); + result = encoder.flush(bbReencoded); + assertFalse(result.isError()); + + boolean bytesEqual = true; + int bytesLen = bbReencoded.position(); + if (bytesLen != numBytes) { + bytesEqual = false; + } else { + for (int i = 0; i < numBytes; i++) { + if (bytes[i] != bytesReencoded[i]) { + bytesEqual = false; + break; + } + } + } + if (bytesEqual != isRoundTrippable) { + outputFailure(byteChar, bytes, bytesReencoded, bytesLen); + } + + count++; + if (isRoundTrippable) { + countRoundTripped++; + } + if (byteChar != 0 && byteChar % 1000000 == 0) { + logger.info("Processed " + (byteChar / 1000000) + + " million characters"); + } + } + logger.info("Round tripped " + countRoundTripped + " of " + count); + assertEquals(expectedCount, countRoundTripped); + } + + private static void outputFailure(long byteChar, byte[] bytes, byte[] after) { + outputFailure(byteChar, bytes, after, after.length); + } + + private static void outputFailure(long byteChar, byte[] bytes, byte[] after, + int len) { + fail("Failure: (" + Long.toHexString(byteChar) + ") " + + toHexString(bytes) + " => " + toHexString(after, len)); + } + + private static String toHexString(byte[] b) { + return toHexString(b, b.length); + } + + private static String toHexString(byte[] b, int len) { + StringBuilder s = new StringBuilder(); + s.append("\""); + for (int i = 0; i < len; i++) { + if (i > 0) { + s.append(" "); + } + s.append(String.format("%02x", b[i] & 0xFF)); + } + s.append("\""); + return s.toString(); + } + +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java new file mode 100644 index 0000000..d500595 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java @@ -0,0 +1,162 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tests for {@link LazyStringArrayList}. + * + * @author jonp@google.com (Jon Perlow) + */ +public class LazyStringArrayListTest extends TestCase { + + private static String STRING_A = "A"; + private static String STRING_B = "B"; + private static String STRING_C = "C"; + + private static ByteString BYTE_STRING_A = ByteString.copyFromUtf8("A"); + private static ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B"); + private static ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C"); + + public void testJustStrings() { + LazyStringArrayList list = new LazyStringArrayList(); + list.add(STRING_A); + list.add(STRING_B); + list.add(STRING_C); + + assertEquals(3, list.size()); + assertSame(STRING_A, list.get(0)); + assertSame(STRING_B, list.get(1)); + assertSame(STRING_C, list.get(2)); + + list.set(1, STRING_C); + assertSame(STRING_C, list.get(1)); + + list.remove(1); + assertSame(STRING_A, list.get(0)); + assertSame(STRING_C, list.get(1)); + } + + public void testJustByteString() { + LazyStringArrayList list = new LazyStringArrayList(); + list.add(BYTE_STRING_A); + list.add(BYTE_STRING_B); + list.add(BYTE_STRING_C); + + assertEquals(3, list.size()); + assertSame(BYTE_STRING_A, list.getByteString(0)); + assertSame(BYTE_STRING_B, list.getByteString(1)); + assertSame(BYTE_STRING_C, list.getByteString(2)); + + list.remove(1); + assertSame(BYTE_STRING_A, list.getByteString(0)); + assertSame(BYTE_STRING_C, list.getByteString(1)); + } + + public void testConversionBackAndForth() { + LazyStringArrayList list = new LazyStringArrayList(); + list.add(STRING_A); + list.add(BYTE_STRING_B); + list.add(BYTE_STRING_C); + + // String a should be the same because it was originally a string + assertSame(STRING_A, list.get(0)); + + // String b and c should be different because the string has to be computed + // from the ByteString + String bPrime = list.get(1); + assertNotSame(STRING_B, bPrime); + assertEquals(STRING_B, bPrime); + String cPrime = list.get(2); + assertNotSame(STRING_C, cPrime); + assertEquals(STRING_C, cPrime); + + // String c and c should stay the same once cached. + assertSame(bPrime, list.get(1)); + assertSame(cPrime, list.get(2)); + + // ByteString needs to be computed from string for both a and b + ByteString aPrimeByteString = list.getByteString(0); + assertEquals(BYTE_STRING_A, aPrimeByteString); + ByteString bPrimeByteString = list.getByteString(1); + assertNotSame(BYTE_STRING_B, bPrimeByteString); + assertEquals(BYTE_STRING_B, list.getByteString(1)); + + // Once cached, ByteString should stay cached. + assertSame(aPrimeByteString, list.getByteString(0)); + assertSame(bPrimeByteString, list.getByteString(1)); + } + + public void testCopyConstructorCopiesByReference() { + LazyStringArrayList list1 = new LazyStringArrayList(); + list1.add(STRING_A); + list1.add(BYTE_STRING_B); + list1.add(BYTE_STRING_C); + + LazyStringArrayList list2 = new LazyStringArrayList(list1); + assertEquals(3, list2.size()); + assertSame(STRING_A, list2.get(0)); + assertSame(BYTE_STRING_B, list2.getByteString(1)); + assertSame(BYTE_STRING_C, list2.getByteString(2)); + } + + public void testListCopyConstructor() { + List list1 = new ArrayList(); + list1.add(STRING_A); + list1.add(STRING_B); + list1.add(STRING_C); + + LazyStringArrayList list2 = new LazyStringArrayList(list1); + assertEquals(3, list2.size()); + assertSame(STRING_A, list2.get(0)); + assertSame(STRING_B, list2.get(1)); + assertSame(STRING_C, list2.get(2)); + } + + public void testAddAllCopiesByReferenceIfPossible() { + LazyStringArrayList list1 = new LazyStringArrayList(); + list1.add(STRING_A); + list1.add(BYTE_STRING_B); + list1.add(BYTE_STRING_C); + + LazyStringArrayList list2 = new LazyStringArrayList(); + list2.addAll(list1); + + assertEquals(3, list2.size()); + assertSame(STRING_A, list2.get(0)); + assertSame(BYTE_STRING_B, list2.getByteString(1)); + assertSame(BYTE_STRING_C, list2.getByteString(2)); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java new file mode 100644 index 0000000..fe9599e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java @@ -0,0 +1,143 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + + +import protobuf_unittest.UnittestProto; + +import junit.framework.TestCase; + +import java.io.IOException; + +/** + * Tests to make sure the lazy conversion of UTF8-encoded byte arrays to + * strings works correctly. + * + * @author jonp@google.com (Jon Perlow) + */ +public class LazyStringEndToEndTest extends TestCase { + + private static ByteString TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8 = + ByteString.copyFrom(new byte[] { + 114, 4, -1, 0, -1, 0, -30, 2, 4, -1, + 0, -1, 0, -30, 2, 4, -1, 0, -1, 0, }); + + private ByteString encodedTestAllTypes; + + @Override + protected void setUp() throws Exception { + super.setUp(); + this.encodedTestAllTypes = UnittestProto.TestAllTypes.newBuilder() + .setOptionalString("foo") + .addRepeatedString("bar") + .addRepeatedString("baz") + .build() + .toByteString(); + } + + /** + * Tests that an invalid UTF8 string will roundtrip through a parse + * and serialization. + */ + public void testParseAndSerialize() throws InvalidProtocolBufferException { + UnittestProto.TestAllTypes tV2 = UnittestProto.TestAllTypes.parseFrom( + TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8); + ByteString bytes = tV2.toByteString(); + assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes); + + tV2.getOptionalString(); + bytes = tV2.toByteString(); + assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes); + } + + public void testParseAndWrite() throws IOException { + UnittestProto.TestAllTypes tV2 = UnittestProto.TestAllTypes.parseFrom( + TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8); + byte[] sink = new byte[TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8.size()]; + CodedOutputStream outputStream = CodedOutputStream.newInstance(sink); + tV2.writeTo(outputStream); + outputStream.flush(); + assertEquals( + TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, + ByteString.copyFrom(sink)); + } + + public void testCaching() { + String a = "a"; + String b = "b"; + String c = "c"; + UnittestProto.TestAllTypes proto = UnittestProto.TestAllTypes.newBuilder() + .setOptionalString(a) + .addRepeatedString(b) + .addRepeatedString(c) + .build(); + + // String should be the one we passed it. + assertSame(a, proto.getOptionalString()); + assertSame(b, proto.getRepeatedString(0)); + assertSame(c, proto.getRepeatedString(1)); + + + // There's no way to directly observe that the ByteString is cached + // correctly on serialization, but we can observe that it had to recompute + // the string after serialization. + proto.toByteString(); + String aPrime = proto.getOptionalString(); + assertNotSame(a, aPrime); + assertEquals(a, aPrime); + String bPrime = proto.getRepeatedString(0); + assertNotSame(b, bPrime); + assertEquals(b, bPrime); + String cPrime = proto.getRepeatedString(1); + assertNotSame(c, cPrime); + assertEquals(c, cPrime); + + // And now the string should stay cached. + assertSame(aPrime, proto.getOptionalString()); + assertSame(bPrime, proto.getRepeatedString(0)); + assertSame(cPrime, proto.getRepeatedString(1)); + } + + public void testNoStringCachingIfOnlyBytesAccessed() throws Exception { + UnittestProto.TestAllTypes proto = + UnittestProto.TestAllTypes.parseFrom(encodedTestAllTypes); + ByteString optional = proto.getOptionalStringBytes(); + assertSame(optional, proto.getOptionalStringBytes()); + assertSame(optional, proto.toBuilder().getOptionalStringBytes()); + + ByteString repeated0 = proto.getRepeatedStringBytes(0); + ByteString repeated1 = proto.getRepeatedStringBytes(1); + assertSame(repeated0, proto.getRepeatedStringBytes(0)); + assertSame(repeated1, proto.getRepeatedStringBytes(1)); + assertSame(repeated0, proto.toBuilder().getRepeatedStringBytes(0)); + assertSame(repeated1, proto.toBuilder().getRepeatedStringBytes(1)); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LiteTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LiteTest.java new file mode 100644 index 0000000..839694d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LiteTest.java @@ -0,0 +1,148 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.UnittestLite; +import com.google.protobuf.UnittestLite.TestAllTypesLite; +import com.google.protobuf.UnittestLite.TestAllExtensionsLite; +import com.google.protobuf.UnittestLite.TestNestedExtensionLite; + +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * Test lite runtime. + * + * @author kenton@google.com Kenton Varda + */ +public class LiteTest extends TestCase { + public void setUp() throws Exception { + // Test that nested extensions are initialized correctly even if the outer + // class has not been accessed directly. This was once a bug with lite + // messages. + // + // We put this in setUp() rather than in its own test method because we + // need to make sure it runs before any actual tests. + assertTrue(TestNestedExtensionLite.nestedExtension != null); + } + + public void testLite() throws Exception { + // Since lite messages are a subset of regular messages, we can mostly + // assume that the functionality of lite messages is already thoroughly + // tested by the regular tests. All this test really verifies is that + // a proto with optimize_for = LITE_RUNTIME compiles correctly when + // linked only against the lite library. That is all tested at compile + // time, leaving not much to do in this method. Let's just do some random + // stuff to make sure the lite message is actually here and usable. + + TestAllTypesLite message = + TestAllTypesLite.newBuilder() + .setOptionalInt32(123) + .addRepeatedString("hello") + .setOptionalNestedMessage( + TestAllTypesLite.NestedMessage.newBuilder().setBb(7)) + .build(); + + ByteString data = message.toByteString(); + + TestAllTypesLite message2 = TestAllTypesLite.parseFrom(data); + + assertEquals(123, message2.getOptionalInt32()); + assertEquals(1, message2.getRepeatedStringCount()); + assertEquals("hello", message2.getRepeatedString(0)); + assertEquals(7, message2.getOptionalNestedMessage().getBb()); + } + + public void testLiteExtensions() throws Exception { + // TODO(kenton): Unlike other features of the lite library, extensions are + // implemented completely differently from the regular library. We + // should probably test them more thoroughly. + + TestAllExtensionsLite message = + TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 123) + .addExtension(UnittestLite.repeatedStringExtensionLite, "hello") + .setExtension(UnittestLite.optionalNestedEnumExtensionLite, + TestAllTypesLite.NestedEnum.BAZ) + .setExtension(UnittestLite.optionalNestedMessageExtensionLite, + TestAllTypesLite.NestedMessage.newBuilder().setBb(7).build()) + .build(); + + // Test copying a message, since coping extensions actually does use a + // different code path between lite and regular libraries, and as of this + // writing, parsing hasn't been implemented yet. + TestAllExtensionsLite message2 = message.toBuilder().build(); + + assertEquals(123, (int) message2.getExtension( + UnittestLite.optionalInt32ExtensionLite)); + assertEquals(1, message2.getExtensionCount( + UnittestLite.repeatedStringExtensionLite)); + assertEquals(1, message2.getExtension( + UnittestLite.repeatedStringExtensionLite).size()); + assertEquals("hello", message2.getExtension( + UnittestLite.repeatedStringExtensionLite, 0)); + assertEquals(TestAllTypesLite.NestedEnum.BAZ, message2.getExtension( + UnittestLite.optionalNestedEnumExtensionLite)); + assertEquals(7, message2.getExtension( + UnittestLite.optionalNestedMessageExtensionLite).getBb()); + } + + public void testSerialize() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + TestAllTypesLite expected = + TestAllTypesLite.newBuilder() + .setOptionalInt32(123) + .addRepeatedString("hello") + .setOptionalNestedMessage( + TestAllTypesLite.NestedMessage.newBuilder().setBb(7)) + .build(); + ObjectOutputStream out = new ObjectOutputStream(baos); + try { + out.writeObject(expected); + } finally { + out.close(); + } + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bais); + TestAllTypesLite actual = (TestAllTypesLite) in.readObject(); + assertEquals(expected.getOptionalInt32(), actual.getOptionalInt32()); + assertEquals(expected.getRepeatedStringCount(), + actual.getRepeatedStringCount()); + assertEquals(expected.getRepeatedString(0), + actual.getRepeatedString(0)); + assertEquals(expected.getOptionalNestedMessage().getBb(), + actual.getOptionalNestedMessage().getBb()); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java new file mode 100644 index 0000000..deee1ee --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java @@ -0,0 +1,396 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import junit.framework.TestCase; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; +import java.util.NoSuchElementException; + +/** + * Test {@link LiteralByteString} by setting up a reference string in {@link #setUp()}. + * This class is designed to be extended for testing extensions of {@link LiteralByteString} + * such as {@link BoundedByteString}, see {@link BoundedByteStringTest}. + * + * @author carlanton@google.com (Carl Haverl) + */ +public class LiteralByteStringTest extends TestCase { + protected static final String UTF_8 = "UTF-8"; + + protected String classUnderTest; + protected byte[] referenceBytes; + protected ByteString stringUnderTest; + protected int expectedHashCode; + + @Override + protected void setUp() throws Exception { + classUnderTest = "LiteralByteString"; + referenceBytes = ByteStringTest.getTestBytes(1234, 11337766L); + stringUnderTest = ByteString.copyFrom(referenceBytes); + expectedHashCode = 331161852; + } + + public void testExpectedType() { + String actualClassName = getActualClassName(stringUnderTest); + assertEquals(classUnderTest + " should match type exactly", classUnderTest, actualClassName); + } + + protected String getActualClassName(Object object) { + String actualClassName = object.getClass().getName(); + actualClassName = actualClassName.substring(actualClassName.lastIndexOf('.') + 1); + return actualClassName; + } + + public void testByteAt() { + boolean stillEqual = true; + for (int i = 0; stillEqual && i < referenceBytes.length; ++i) { + stillEqual = (referenceBytes[i] == stringUnderTest.byteAt(i)); + } + assertTrue(classUnderTest + " must capture the right bytes", stillEqual); + } + + public void testByteIterator() { + boolean stillEqual = true; + ByteString.ByteIterator iter = stringUnderTest.iterator(); + for (int i = 0; stillEqual && i < referenceBytes.length; ++i) { + stillEqual = (iter.hasNext() && referenceBytes[i] == iter.nextByte()); + } + assertTrue(classUnderTest + " must capture the right bytes", stillEqual); + assertFalse(classUnderTest + " must have exhausted the itertor", iter.hasNext()); + + try { + iter.nextByte(); + fail("Should have thrown an exception."); + } catch (NoSuchElementException e) { + // This is success + } + } + + public void testByteIterable() { + boolean stillEqual = true; + int j = 0; + for (byte quantum : stringUnderTest) { + stillEqual = (referenceBytes[j] == quantum); + ++j; + } + assertTrue(classUnderTest + " must capture the right bytes as Bytes", stillEqual); + assertEquals(classUnderTest + " iterable character count", referenceBytes.length, j); + } + + public void testSize() { + assertEquals(classUnderTest + " must have the expected size", referenceBytes.length, + stringUnderTest.size()); + } + + public void testGetTreeDepth() { + assertEquals(classUnderTest + " must have depth 0", 0, stringUnderTest.getTreeDepth()); + } + + public void testIsBalanced() { + assertTrue(classUnderTest + " is technically balanced", stringUnderTest.isBalanced()); + } + + public void testCopyTo_ByteArrayOffsetLength() { + int destinationOffset = 50; + int length = 100; + byte[] destination = new byte[destinationOffset + length]; + int sourceOffset = 213; + stringUnderTest.copyTo(destination, sourceOffset, destinationOffset, length); + boolean stillEqual = true; + for (int i = 0; stillEqual && i < length; ++i) { + stillEqual = referenceBytes[i + sourceOffset] == destination[i + destinationOffset]; + } + assertTrue(classUnderTest + ".copyTo(4 arg) must give the expected bytes", stillEqual); + } + + public void testCopyTo_ByteArrayOffsetLengthErrors() { + int destinationOffset = 50; + int length = 100; + byte[] destination = new byte[destinationOffset + length]; + + try { + // Copy one too many bytes + stringUnderTest.copyTo(destination, stringUnderTest.size() + 1 - length, + destinationOffset, length); + fail("Should have thrown an exception when copying too many bytes of a " + + classUnderTest); + } catch (IndexOutOfBoundsException expected) { + // This is success + } + + try { + // Copy with illegal negative sourceOffset + stringUnderTest.copyTo(destination, -1, destinationOffset, length); + fail("Should have thrown an exception when given a negative sourceOffset in " + + classUnderTest); + } catch (IndexOutOfBoundsException expected) { + // This is success + } + + try { + // Copy with illegal negative destinationOffset + stringUnderTest.copyTo(destination, 0, -1, length); + fail("Should have thrown an exception when given a negative destinationOffset in " + + classUnderTest); + } catch (IndexOutOfBoundsException expected) { + // This is success + } + + try { + // Copy with illegal negative size + stringUnderTest.copyTo(destination, 0, 0, -1); + fail("Should have thrown an exception when given a negative size in " + + classUnderTest); + } catch (IndexOutOfBoundsException expected) { + // This is success + } + + try { + // Copy with illegal too-large sourceOffset + stringUnderTest.copyTo(destination, 2 * stringUnderTest.size(), 0, length); + fail("Should have thrown an exception when the destinationOffset is too large in " + + classUnderTest); + } catch (IndexOutOfBoundsException expected) { + // This is success + } + + try { + // Copy with illegal too-large destinationOffset + stringUnderTest.copyTo(destination, 0, 2 * destination.length, length); + fail("Should have thrown an exception when the destinationOffset is too large in " + + classUnderTest); + } catch (IndexOutOfBoundsException expected) { + // This is success + } + } + + public void testCopyTo_ByteBuffer() { + ByteBuffer myBuffer = ByteBuffer.allocate(referenceBytes.length); + stringUnderTest.copyTo(myBuffer); + assertTrue(classUnderTest + ".copyTo(ByteBuffer) must give back the same bytes", + Arrays.equals(referenceBytes, myBuffer.array())); + } + + public void testAsReadOnlyByteBuffer() { + ByteBuffer byteBuffer = stringUnderTest.asReadOnlyByteBuffer(); + byte[] roundTripBytes = new byte[referenceBytes.length]; + assertTrue(byteBuffer.remaining() == referenceBytes.length); + assertTrue(byteBuffer.isReadOnly()); + byteBuffer.get(roundTripBytes); + assertTrue(classUnderTest + ".asReadOnlyByteBuffer() must give back the same bytes", + Arrays.equals(referenceBytes, roundTripBytes)); + } + + public void testAsReadOnlyByteBufferList() { + List byteBuffers = stringUnderTest.asReadOnlyByteBufferList(); + int bytesSeen = 0; + byte[] roundTripBytes = new byte[referenceBytes.length]; + for (ByteBuffer byteBuffer : byteBuffers) { + int thisLength = byteBuffer.remaining(); + assertTrue(byteBuffer.isReadOnly()); + assertTrue(bytesSeen + thisLength <= referenceBytes.length); + byteBuffer.get(roundTripBytes, bytesSeen, thisLength); + bytesSeen += thisLength; + } + assertTrue(bytesSeen == referenceBytes.length); + assertTrue(classUnderTest + ".asReadOnlyByteBufferTest() must give back the same bytes", + Arrays.equals(referenceBytes, roundTripBytes)); + } + + public void testToByteArray() { + byte[] roundTripBytes = stringUnderTest.toByteArray(); + assertTrue(classUnderTest + ".toByteArray() must give back the same bytes", + Arrays.equals(referenceBytes, roundTripBytes)); + } + + public void testWriteTo() throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + stringUnderTest.writeTo(bos); + byte[] roundTripBytes = bos.toByteArray(); + assertTrue(classUnderTest + ".writeTo() must give back the same bytes", + Arrays.equals(referenceBytes, roundTripBytes)); + } + + public void testWriteTo_mutating() throws IOException { + OutputStream os = new OutputStream() { + @Override + public void write(byte[] b, int off, int len) { + for (int x = 0; x < len; ++x) { + b[off + x] = (byte) 0; + } + } + + @Override + public void write(int b) { + // Purposefully left blank. + } + }; + + stringUnderTest.writeTo(os); + byte[] newBytes = stringUnderTest.toByteArray(); + assertTrue(classUnderTest + ".writeTo() must not grant access to underlying array", + Arrays.equals(referenceBytes, newBytes)); + } + + public void testNewOutput() throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ByteString.Output output = ByteString.newOutput(); + stringUnderTest.writeTo(output); + assertEquals("Output Size returns correct result", + output.size(), stringUnderTest.size()); + output.writeTo(bos); + assertTrue("Output.writeTo() must give back the same bytes", + Arrays.equals(referenceBytes, bos.toByteArray())); + + // write the output stream to itself! This should cause it to double + output.writeTo(output); + assertEquals("Writing an output stream to itself is successful", + stringUnderTest.concat(stringUnderTest), output.toByteString()); + + output.reset(); + assertEquals("Output.reset() resets the output", 0, output.size()); + assertEquals("Output.reset() resets the output", + ByteString.EMPTY, output.toByteString()); + + } + + public void testToString() throws UnsupportedEncodingException { + String testString = "I love unicode \u1234\u5678 characters"; + LiteralByteString unicode = new LiteralByteString(testString.getBytes(UTF_8)); + String roundTripString = unicode.toString(UTF_8); + assertEquals(classUnderTest + " unicode must match", testString, roundTripString); + } + + public void testEquals() { + assertEquals(classUnderTest + " must not equal null", false, stringUnderTest.equals(null)); + assertEquals(classUnderTest + " must equal self", stringUnderTest, stringUnderTest); + assertFalse(classUnderTest + " must not equal the empty string", + stringUnderTest.equals(ByteString.EMPTY)); + assertEquals(classUnderTest + " empty strings must be equal", + new LiteralByteString(new byte[]{}), stringUnderTest.substring(55, 55)); + assertEquals(classUnderTest + " must equal another string with the same value", + stringUnderTest, new LiteralByteString(referenceBytes)); + + byte[] mungedBytes = new byte[referenceBytes.length]; + System.arraycopy(referenceBytes, 0, mungedBytes, 0, referenceBytes.length); + mungedBytes[mungedBytes.length - 5] ^= 0xFF; + assertFalse(classUnderTest + " must not equal every string with the same length", + stringUnderTest.equals(new LiteralByteString(mungedBytes))); + } + + public void testHashCode() { + int hash = stringUnderTest.hashCode(); + assertEquals(classUnderTest + " must have expected hashCode", expectedHashCode, hash); + } + + public void testPeekCachedHashCode() { + assertEquals(classUnderTest + ".peekCachedHashCode() should return zero at first", 0, + stringUnderTest.peekCachedHashCode()); + stringUnderTest.hashCode(); + assertEquals(classUnderTest + ".peekCachedHashCode should return zero at first", + expectedHashCode, stringUnderTest.peekCachedHashCode()); + } + + public void testPartialHash() { + // partialHash() is more strenuously tested elsewhere by testing hashes of substrings. + // This test would fail if the expected hash were 1. It's not. + int hash = stringUnderTest.partialHash(stringUnderTest.size(), 0, stringUnderTest.size()); + assertEquals(classUnderTest + ".partialHash() must yield expected hashCode", + expectedHashCode, hash); + } + + public void testNewInput() throws IOException { + InputStream input = stringUnderTest.newInput(); + assertEquals("InputStream.available() returns correct value", + stringUnderTest.size(), input.available()); + boolean stillEqual = true; + for (byte referenceByte : referenceBytes) { + int expectedInt = (referenceByte & 0xFF); + stillEqual = (expectedInt == input.read()); + } + assertEquals("InputStream.available() returns correct value", + 0, input.available()); + assertTrue(classUnderTest + " must give the same bytes from the InputStream", stillEqual); + assertEquals(classUnderTest + " InputStream must now be exhausted", -1, input.read()); + } + + public void testNewInput_skip() throws IOException { + InputStream input = stringUnderTest.newInput(); + int stringSize = stringUnderTest.size(); + int nearEndIndex = stringSize * 2 / 3; + long skipped1 = input.skip(nearEndIndex); + assertEquals("InputStream.skip()", skipped1, nearEndIndex); + assertEquals("InputStream.available()", + stringSize - skipped1, input.available()); + assertTrue("InputStream.mark() is available", input.markSupported()); + input.mark(0); + assertEquals("InputStream.skip(), read()", + stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read()); + assertEquals("InputStream.available()", + stringSize - skipped1 - 1, input.available()); + long skipped2 = input.skip(stringSize); + assertEquals("InputStream.skip() incomplete", + skipped2, stringSize - skipped1 - 1); + assertEquals("InputStream.skip(), no more input", 0, input.available()); + assertEquals("InputStream.skip(), no more input", -1, input.read()); + input.reset(); + assertEquals("InputStream.reset() succeded", + stringSize - skipped1, input.available()); + assertEquals("InputStream.reset(), read()", + stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read()); + } + + public void testNewCodedInput() throws IOException { + CodedInputStream cis = stringUnderTest.newCodedInput(); + byte[] roundTripBytes = cis.readRawBytes(referenceBytes.length); + assertTrue(classUnderTest + " must give the same bytes back from the CodedInputStream", + Arrays.equals(referenceBytes, roundTripBytes)); + assertTrue(classUnderTest + " CodedInputStream must now be exhausted", cis.isAtEnd()); + } + + /** + * Make sure we keep things simple when concatenating with empty. See also + * {@link ByteStringTest#testConcat_empty()}. + */ + public void testConcat_empty() { + assertSame(classUnderTest + " concatenated with empty must give " + classUnderTest, + stringUnderTest.concat(ByteString.EMPTY), stringUnderTest); + assertSame("empty concatenated with " + classUnderTest + " must give " + classUnderTest, + ByteString.EMPTY.concat(stringUnderTest), stringUnderTest); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/MessageTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/MessageTest.java new file mode 100644 index 0000000..747fed7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/MessageTest.java @@ -0,0 +1,353 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestRequired; +import protobuf_unittest.UnittestProto.TestRequiredForeign; +import protobuf_unittest.UnittestProto.ForeignMessage; + +import junit.framework.TestCase; + +import java.util.List; + +/** + * Misc. unit tests for message operations that apply to both generated + * and dynamic messages. + * + * @author kenton@google.com Kenton Varda + */ +public class MessageTest extends TestCase { + // ================================================================= + // Message-merging tests. + + static final TestAllTypes MERGE_SOURCE = + TestAllTypes.newBuilder() + .setOptionalInt32(1) + .setOptionalString("foo") + .setOptionalForeignMessage(ForeignMessage.getDefaultInstance()) + .addRepeatedString("bar") + .build(); + + static final TestAllTypes MERGE_DEST = + TestAllTypes.newBuilder() + .setOptionalInt64(2) + .setOptionalString("baz") + .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build()) + .addRepeatedString("qux") + .build(); + + static final String MERGE_RESULT_TEXT = + "optional_int32: 1\n" + + "optional_int64: 2\n" + + "optional_string: \"foo\"\n" + + "optional_foreign_message {\n" + + " c: 3\n" + + "}\n" + + "repeated_string: \"qux\"\n" + + "repeated_string: \"bar\"\n"; + + public void testMergeFrom() throws Exception { + TestAllTypes result = + TestAllTypes.newBuilder(MERGE_DEST) + .mergeFrom(MERGE_SOURCE).build(); + + assertEquals(MERGE_RESULT_TEXT, result.toString()); + } + + /** + * Test merging a DynamicMessage into a GeneratedMessage. As long as they + * have the same descriptor, this should work, but it is an entirely different + * code path. + */ + public void testMergeFromDynamic() throws Exception { + TestAllTypes result = + TestAllTypes.newBuilder(MERGE_DEST) + .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build()) + .build(); + + assertEquals(MERGE_RESULT_TEXT, result.toString()); + } + + /** Test merging two DynamicMessages. */ + public void testDynamicMergeFrom() throws Exception { + DynamicMessage result = + DynamicMessage.newBuilder(MERGE_DEST) + .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build()) + .build(); + + assertEquals(MERGE_RESULT_TEXT, result.toString()); + } + + // ================================================================= + // Required-field-related tests. + + private static final TestRequired TEST_REQUIRED_UNINITIALIZED = + TestRequired.getDefaultInstance(); + private static final TestRequired TEST_REQUIRED_INITIALIZED = + TestRequired.newBuilder().setA(1).setB(2).setC(3).build(); + + public void testRequired() throws Exception { + TestRequired.Builder builder = TestRequired.newBuilder(); + + assertFalse(builder.isInitialized()); + builder.setA(1); + assertFalse(builder.isInitialized()); + builder.setB(1); + assertFalse(builder.isInitialized()); + builder.setC(1); + assertTrue(builder.isInitialized()); + } + + public void testRequiredForeign() throws Exception { + TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder(); + + assertTrue(builder.isInitialized()); + + builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED); + assertFalse(builder.isInitialized()); + + builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED); + assertTrue(builder.isInitialized()); + + builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED); + assertFalse(builder.isInitialized()); + + builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED); + assertTrue(builder.isInitialized()); + } + + public void testRequiredExtension() throws Exception { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + + assertTrue(builder.isInitialized()); + + builder.setExtension(TestRequired.single, TEST_REQUIRED_UNINITIALIZED); + assertFalse(builder.isInitialized()); + + builder.setExtension(TestRequired.single, TEST_REQUIRED_INITIALIZED); + assertTrue(builder.isInitialized()); + + builder.addExtension(TestRequired.multi, TEST_REQUIRED_UNINITIALIZED); + assertFalse(builder.isInitialized()); + + builder.setExtension(TestRequired.multi, 0, TEST_REQUIRED_INITIALIZED); + assertTrue(builder.isInitialized()); + } + + public void testRequiredDynamic() throws Exception { + Descriptors.Descriptor descriptor = TestRequired.getDescriptor(); + DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor); + + assertFalse(builder.isInitialized()); + builder.setField(descriptor.findFieldByName("a"), 1); + assertFalse(builder.isInitialized()); + builder.setField(descriptor.findFieldByName("b"), 1); + assertFalse(builder.isInitialized()); + builder.setField(descriptor.findFieldByName("c"), 1); + assertTrue(builder.isInitialized()); + } + + public void testRequiredDynamicForeign() throws Exception { + Descriptors.Descriptor descriptor = TestRequiredForeign.getDescriptor(); + DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor); + + assertTrue(builder.isInitialized()); + + builder.setField(descriptor.findFieldByName("optional_message"), + TEST_REQUIRED_UNINITIALIZED); + assertFalse(builder.isInitialized()); + + builder.setField(descriptor.findFieldByName("optional_message"), + TEST_REQUIRED_INITIALIZED); + assertTrue(builder.isInitialized()); + + builder.addRepeatedField(descriptor.findFieldByName("repeated_message"), + TEST_REQUIRED_UNINITIALIZED); + assertFalse(builder.isInitialized()); + + builder.setRepeatedField(descriptor.findFieldByName("repeated_message"), 0, + TEST_REQUIRED_INITIALIZED); + assertTrue(builder.isInitialized()); + } + + public void testUninitializedException() throws Exception { + try { + TestRequired.newBuilder().build(); + fail("Should have thrown an exception."); + } catch (UninitializedMessageException e) { + assertEquals("Message missing required fields: a, b, c", e.getMessage()); + } + } + + public void testBuildPartial() throws Exception { + // We're mostly testing that no exception is thrown. + TestRequired message = TestRequired.newBuilder().buildPartial(); + assertFalse(message.isInitialized()); + } + + public void testNestedUninitializedException() throws Exception { + try { + TestRequiredForeign.newBuilder() + .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED) + .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED) + .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED) + .build(); + fail("Should have thrown an exception."); + } catch (UninitializedMessageException e) { + assertEquals( + "Message missing required fields: " + + "optional_message.a, " + + "optional_message.b, " + + "optional_message.c, " + + "repeated_message[0].a, " + + "repeated_message[0].b, " + + "repeated_message[0].c, " + + "repeated_message[1].a, " + + "repeated_message[1].b, " + + "repeated_message[1].c", + e.getMessage()); + } + } + + public void testBuildNestedPartial() throws Exception { + // We're mostly testing that no exception is thrown. + TestRequiredForeign message = + TestRequiredForeign.newBuilder() + .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED) + .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED) + .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED) + .buildPartial(); + assertFalse(message.isInitialized()); + } + + public void testParseUnititialized() throws Exception { + try { + TestRequired.parseFrom(ByteString.EMPTY); + fail("Should have thrown an exception."); + } catch (InvalidProtocolBufferException e) { + assertEquals("Message missing required fields: a, b, c", e.getMessage()); + } + } + + public void testParseNestedUnititialized() throws Exception { + ByteString data = + TestRequiredForeign.newBuilder() + .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED) + .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED) + .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED) + .buildPartial().toByteString(); + + try { + TestRequiredForeign.parseFrom(data); + fail("Should have thrown an exception."); + } catch (InvalidProtocolBufferException e) { + assertEquals( + "Message missing required fields: " + + "optional_message.a, " + + "optional_message.b, " + + "optional_message.c, " + + "repeated_message[0].a, " + + "repeated_message[0].b, " + + "repeated_message[0].c, " + + "repeated_message[1].a, " + + "repeated_message[1].b, " + + "repeated_message[1].c", + e.getMessage()); + } + } + + public void testDynamicUninitializedException() throws Exception { + try { + DynamicMessage.newBuilder(TestRequired.getDescriptor()).build(); + fail("Should have thrown an exception."); + } catch (UninitializedMessageException e) { + assertEquals("Message missing required fields: a, b, c", e.getMessage()); + } + } + + public void testDynamicBuildPartial() throws Exception { + // We're mostly testing that no exception is thrown. + DynamicMessage message = + DynamicMessage.newBuilder(TestRequired.getDescriptor()) + .buildPartial(); + assertFalse(message.isInitialized()); + } + + public void testDynamicParseUnititialized() throws Exception { + try { + Descriptors.Descriptor descriptor = TestRequired.getDescriptor(); + DynamicMessage.parseFrom(descriptor, ByteString.EMPTY); + fail("Should have thrown an exception."); + } catch (InvalidProtocolBufferException e) { + assertEquals("Message missing required fields: a, b, c", e.getMessage()); + } + } + + /** Test reading unset repeated message from DynamicMessage. */ + public void testDynamicRepeatedMessageNull() throws Exception { + Descriptors.Descriptor descriptor = TestRequired.getDescriptor(); + DynamicMessage result = + DynamicMessage.newBuilder(TestAllTypes.getDescriptor()) + .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build()) + .build(); + + assertTrue(result.getField(result.getDescriptorForType() + .findFieldByName("repeated_foreign_message")) instanceof List); + assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType() + .findFieldByName("repeated_foreign_message")), 0); + } + + /** Test reading repeated message from DynamicMessage. */ + public void testDynamicRepeatedMessageNotNull() throws Exception { + + TestAllTypes REPEATED_NESTED = + TestAllTypes.newBuilder() + .setOptionalInt32(1) + .setOptionalString("foo") + .setOptionalForeignMessage(ForeignMessage.getDefaultInstance()) + .addRepeatedString("bar") + .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance()) + .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance()) + .build(); + Descriptors.Descriptor descriptor = TestRequired.getDescriptor(); + DynamicMessage result = + DynamicMessage.newBuilder(TestAllTypes.getDescriptor()) + .mergeFrom(DynamicMessage.newBuilder(REPEATED_NESTED).build()) + .build(); + + assertTrue(result.getField(result.getDescriptorForType() + .findFieldByName("repeated_foreign_message")) instanceof List); + assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType() + .findFieldByName("repeated_foreign_message")), 2); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/NestedBuildersTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/NestedBuildersTest.java new file mode 100644 index 0000000..f537580 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/NestedBuildersTest.java @@ -0,0 +1,185 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.Vehicle; +import protobuf_unittest.Wheel; + +import junit.framework.TestCase; + +import java.util.List; +import java.util.ArrayList; + +/** + * Test cases that exercise end-to-end use cases involving + * {@link SingleFieldBuilder} and {@link RepeatedFieldBuilder}. + * + * @author jonp@google.com (Jon Perlow) + */ +public class NestedBuildersTest extends TestCase { + + public void testMessagesAndBuilders() { + Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); + vehicleBuilder.addWheelBuilder() + .setRadius(4) + .setWidth(1); + vehicleBuilder.addWheelBuilder() + .setRadius(4) + .setWidth(2); + vehicleBuilder.addWheelBuilder() + .setRadius(4) + .setWidth(3); + vehicleBuilder.addWheelBuilder() + .setRadius(4) + .setWidth(4); + vehicleBuilder.getEngineBuilder() + .setLiters(10); + + Vehicle vehicle = vehicleBuilder.build(); + assertEquals(4, vehicle.getWheelCount()); + for (int i = 0; i < 4; i++) { + Wheel wheel = vehicle.getWheel(i); + assertEquals(4, wheel.getRadius()); + assertEquals(i + 1, wheel.getWidth()); + } + assertEquals(10, vehicle.getEngine().getLiters()); + + for (int i = 0; i < 4; i++) { + vehicleBuilder.getWheelBuilder(i) + .setRadius(5) + .setWidth(i + 10); + } + vehicleBuilder.getEngineBuilder().setLiters(20); + + vehicle = vehicleBuilder.build(); + for (int i = 0; i < 4; i++) { + Wheel wheel = vehicle.getWheel(i); + assertEquals(5, wheel.getRadius()); + assertEquals(i + 10, wheel.getWidth()); + } + assertEquals(20, vehicle.getEngine().getLiters()); + assertTrue(vehicle.hasEngine()); + } + + public void testMessagesAreCached() { + Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); + vehicleBuilder.addWheelBuilder() + .setRadius(1) + .setWidth(2); + vehicleBuilder.addWheelBuilder() + .setRadius(3) + .setWidth(4); + vehicleBuilder.addWheelBuilder() + .setRadius(5) + .setWidth(6); + vehicleBuilder.addWheelBuilder() + .setRadius(7) + .setWidth(8); + + // Make sure messages are cached. + List wheels = new ArrayList(vehicleBuilder.getWheelList()); + for (int i = 0; i < wheels.size(); i++) { + assertSame(wheels.get(i), vehicleBuilder.getWheel(i)); + } + + // Now get builders and check they didn't change. + for (int i = 0; i < wheels.size(); i++) { + vehicleBuilder.getWheel(i); + } + for (int i = 0; i < wheels.size(); i++) { + assertSame(wheels.get(i), vehicleBuilder.getWheel(i)); + } + + // Change just one + vehicleBuilder.getWheelBuilder(3) + .setRadius(20).setWidth(20); + + // Now get wheels and check that only that one changed + for (int i = 0; i < wheels.size(); i++) { + if (i < 3) { + assertSame(wheels.get(i), vehicleBuilder.getWheel(i)); + } else { + assertNotSame(wheels.get(i), vehicleBuilder.getWheel(i)); + } + } + } + + public void testRemove_WithNestedBuilders() { + Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); + vehicleBuilder.addWheelBuilder() + .setRadius(1) + .setWidth(1); + vehicleBuilder.addWheelBuilder() + .setRadius(2) + .setWidth(2); + vehicleBuilder.removeWheel(0); + + assertEquals(1, vehicleBuilder.getWheelCount()); + assertEquals(2, vehicleBuilder.getWheel(0).getRadius()); + } + + public void testRemove_WithNestedMessages() { + Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); + vehicleBuilder.addWheel(Wheel.newBuilder() + .setRadius(1) + .setWidth(1)); + vehicleBuilder.addWheel(Wheel.newBuilder() + .setRadius(2) + .setWidth(2)); + vehicleBuilder.removeWheel(0); + + assertEquals(1, vehicleBuilder.getWheelCount()); + assertEquals(2, vehicleBuilder.getWheel(0).getRadius()); + } + + public void testMerge() { + Vehicle vehicle1 = Vehicle.newBuilder() + .addWheel(Wheel.newBuilder().setRadius(1).build()) + .addWheel(Wheel.newBuilder().setRadius(2).build()) + .build(); + + Vehicle vehicle2 = Vehicle.newBuilder() + .mergeFrom(vehicle1) + .build(); + // List should be the same -- no allocation + assertSame(vehicle1.getWheelList(), vehicle2.getWheelList()); + + Vehicle vehicle3 = vehicle1.toBuilder().build(); + assertSame(vehicle1.getWheelList(), vehicle3.getWheelList()); + } + + public void testGettingBuilderMarksFieldAsHaving() { + Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); + vehicleBuilder.getEngineBuilder(); + Vehicle vehicle = vehicleBuilder.buildPartial(); + assertTrue(vehicle.hasEngine()); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ParserTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ParserTest.java new file mode 100644 index 0000000..396902c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ParserTest.java @@ -0,0 +1,375 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.UnittestLite.TestAllTypesLite; +import com.google.protobuf.UnittestLite.TestPackedExtensionsLite; +import com.google.protobuf.UnittestLite.TestParsingMergeLite; +import com.google.protobuf.UnittestLite; +import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize; +import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize; +import protobuf_unittest.UnittestOptimizeFor; +import protobuf_unittest.UnittestProto.ForeignMessage; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestEmptyMessage; +import protobuf_unittest.UnittestProto.TestRequired; +import protobuf_unittest.UnittestProto.TestParsingMerge; +import protobuf_unittest.UnittestProto; + +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Unit test for {@link Parser}. + * + * @author liujisi@google.com (Pherl Liu) + */ +public class ParserTest extends TestCase { + public void testGeneratedMessageParserSingleton() throws Exception { + for (int i = 0; i < 10; i++) { + assertEquals(TestAllTypes.PARSER, + TestUtil.getAllSet().getParserForType()); + } + } + + private void assertRoundTripEquals(MessageLite message, + ExtensionRegistryLite registry) + throws Exception { + final byte[] data = message.toByteArray(); + final int offset = 20; + final int length = data.length; + final int padding = 30; + Parser parser = message.getParserForType(); + assertMessageEquals(message, parser.parseFrom(data, registry)); + assertMessageEquals(message, parser.parseFrom( + generatePaddingArray(data, offset, padding), + offset, length, registry)); + assertMessageEquals(message, parser.parseFrom( + message.toByteString(), registry)); + assertMessageEquals(message, parser.parseFrom( + new ByteArrayInputStream(data), registry)); + assertMessageEquals(message, parser.parseFrom( + CodedInputStream.newInstance(data), registry)); + } + + private void assertRoundTripEquals(MessageLite message) throws Exception { + final byte[] data = message.toByteArray(); + final int offset = 20; + final int length = data.length; + final int padding = 30; + Parser parser = message.getParserForType(); + assertMessageEquals(message, parser.parseFrom(data)); + assertMessageEquals(message, parser.parseFrom( + generatePaddingArray(data, offset, padding), + offset, length)); + assertMessageEquals(message, parser.parseFrom(message.toByteString())); + assertMessageEquals(message, parser.parseFrom( + new ByteArrayInputStream(data))); + assertMessageEquals(message, parser.parseFrom( + CodedInputStream.newInstance(data))); + } + + private void assertMessageEquals(MessageLite expected, MessageLite actual) + throws Exception { + if (expected instanceof Message) { + assertEquals(expected, actual); + } else { + assertEquals(expected.toByteString(), actual.toByteString()); + } + } + + private byte[] generatePaddingArray(byte[] data, int offset, int padding) { + byte[] result = new byte[offset + data.length + padding]; + System.arraycopy(data, 0, result, offset, data.length); + return result; + } + + public void testNormalMessage() throws Exception { + assertRoundTripEquals(TestUtil.getAllSet()); + } + + public void testParsePartial() throws Exception { + Parser parser = TestRequired.PARSER; + final String errorString = + "Should throw exceptions when the parsed message isn't initialized."; + + // TestRequired.b and TestRequired.c are not set. + TestRequired partialMessage = TestRequired.newBuilder() + .setA(1).buildPartial(); + + // parsePartialFrom should pass. + byte[] data = partialMessage.toByteArray(); + assertEquals(partialMessage, parser.parsePartialFrom(data)); + assertEquals(partialMessage, parser.parsePartialFrom( + partialMessage.toByteString())); + assertEquals(partialMessage, parser.parsePartialFrom( + new ByteArrayInputStream(data))); + assertEquals(partialMessage, parser.parsePartialFrom( + CodedInputStream.newInstance(data))); + + // parseFrom(ByteArray) + try { + parser.parseFrom(partialMessage.toByteArray()); + fail(errorString); + } catch (InvalidProtocolBufferException e) { + // pass. + } + + // parseFrom(ByteString) + try { + parser.parseFrom(partialMessage.toByteString()); + fail(errorString); + } catch (InvalidProtocolBufferException e) { + // pass. + } + + // parseFrom(InputStream) + try { + parser.parseFrom(new ByteArrayInputStream(partialMessage.toByteArray())); + fail(errorString); + } catch (IOException e) { + // pass. + } + + // parseFrom(CodedInputStream) + try { + parser.parseFrom(CodedInputStream.newInstance( + partialMessage.toByteArray())); + fail(errorString); + } catch (IOException e) { + // pass. + } + } + + public void testParseExtensions() throws Exception { + assertRoundTripEquals(TestUtil.getAllExtensionsSet(), + TestUtil.getExtensionRegistry()); + assertRoundTripEquals(TestUtil.getAllLiteExtensionsSet(), + TestUtil.getExtensionRegistryLite()); + } + + public void testParsePacked() throws Exception { + assertRoundTripEquals(TestUtil.getPackedSet()); + assertRoundTripEquals(TestUtil.getPackedExtensionsSet(), + TestUtil.getExtensionRegistry()); + assertRoundTripEquals(TestUtil.getLitePackedExtensionsSet(), + TestUtil.getExtensionRegistryLite()); + } + + public void testParseDelimitedTo() throws Exception { + // Write normal Message. + TestAllTypes normalMessage = TestUtil.getAllSet(); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + normalMessage.writeDelimitedTo(output); + + // Write MessageLite with packed extension fields. + TestPackedExtensionsLite packedMessage = + TestUtil.getLitePackedExtensionsSet(); + packedMessage.writeDelimitedTo(output); + + InputStream input = new ByteArrayInputStream(output.toByteArray()); + assertMessageEquals( + normalMessage, + normalMessage.getParserForType().parseDelimitedFrom(input)); + assertMessageEquals( + packedMessage, + packedMessage.getParserForType().parseDelimitedFrom( + input, TestUtil.getExtensionRegistryLite())); + } + + public void testParseUnknownFields() throws Exception { + // All fields will be treated as unknown fields in emptyMessage. + TestEmptyMessage emptyMessage = TestEmptyMessage.PARSER.parseFrom( + TestUtil.getAllSet().toByteString()); + assertEquals( + TestUtil.getAllSet().toByteString(), + emptyMessage.toByteString()); + } + + public void testOptimizeForSize() throws Exception { + TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder(); + builder.setI(12).setMsg(ForeignMessage.newBuilder().setC(34).build()); + builder.setExtension(TestOptimizedForSize.testExtension, 56); + builder.setExtension(TestOptimizedForSize.testExtension2, + TestRequiredOptimizedForSize.newBuilder().setX(78).build()); + + TestOptimizedForSize message = builder.build(); + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + UnittestOptimizeFor.registerAllExtensions(registry); + + assertRoundTripEquals(message, registry); + } + + /** Helper method for {@link #testParsingMerge()}.*/ + private void assertMessageMerged(TestAllTypes allTypes) + throws Exception { + assertEquals(3, allTypes.getOptionalInt32()); + assertEquals(2, allTypes.getOptionalInt64()); + assertEquals("hello", allTypes.getOptionalString()); + } + + /** Helper method for {@link #testParsingMergeLite()}.*/ + private void assertMessageMerged(TestAllTypesLite allTypes) + throws Exception { + assertEquals(3, allTypes.getOptionalInt32()); + assertEquals(2, allTypes.getOptionalInt64()); + assertEquals("hello", allTypes.getOptionalString()); + } + + public void testParsingMerge() throws Exception { + // Build messages. + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestAllTypes msg1 = builder.setOptionalInt32(1).build(); + builder.clear(); + TestAllTypes msg2 = builder.setOptionalInt64(2).build(); + builder.clear(); + TestAllTypes msg3 = builder.setOptionalInt32(3) + .setOptionalString("hello").build(); + + // Build groups. + TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG1 = + TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder() + .setField1(msg1).build(); + TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG2 = + TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder() + .setField1(msg2).build(); + TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG3 = + TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder() + .setField1(msg3).build(); + TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG1 = + TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder() + .setField1(msg1).build(); + TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG2 = + TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder() + .setField1(msg2).build(); + TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG3 = + TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder() + .setField1(msg3).build(); + + // Assign and serialize RepeatedFieldsGenerator. + ByteString data = TestParsingMerge.RepeatedFieldsGenerator.newBuilder() + .addField1(msg1).addField1(msg2).addField1(msg3) + .addField2(msg1).addField2(msg2).addField2(msg3) + .addField3(msg1).addField3(msg2).addField3(msg3) + .addGroup1(optionalG1).addGroup1(optionalG2).addGroup1(optionalG3) + .addGroup2(repeatedG1).addGroup2(repeatedG2).addGroup2(repeatedG3) + .addExt1(msg1).addExt1(msg2).addExt1(msg3) + .addExt2(msg1).addExt2(msg2).addExt2(msg3) + .build().toByteString(); + + // Parse TestParsingMerge. + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + UnittestProto.registerAllExtensions(registry); + TestParsingMerge parsingMerge = + TestParsingMerge.PARSER.parseFrom(data, registry); + + // Required and optional fields should be merged. + assertMessageMerged(parsingMerge.getRequiredAllTypes()); + assertMessageMerged(parsingMerge.getOptionalAllTypes()); + assertMessageMerged( + parsingMerge.getOptionalGroup().getOptionalGroupAllTypes()); + assertMessageMerged(parsingMerge.getExtension( + TestParsingMerge.optionalExt)); + + // Repeated fields should not be merged. + assertEquals(3, parsingMerge.getRepeatedAllTypesCount()); + assertEquals(3, parsingMerge.getRepeatedGroupCount()); + assertEquals(3, parsingMerge.getExtensionCount( + TestParsingMerge.repeatedExt)); + } + + public void testParsingMergeLite() throws Exception { + // Build messages. + TestAllTypesLite.Builder builder = + TestAllTypesLite.newBuilder(); + TestAllTypesLite msg1 = builder.setOptionalInt32(1).build(); + builder.clear(); + TestAllTypesLite msg2 = builder.setOptionalInt64(2).build(); + builder.clear(); + TestAllTypesLite msg3 = builder.setOptionalInt32(3) + .setOptionalString("hello").build(); + + // Build groups. + TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG1 = + TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder() + .setField1(msg1).build(); + TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG2 = + TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder() + .setField1(msg2).build(); + TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG3 = + TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder() + .setField1(msg3).build(); + TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG1 = + TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder() + .setField1(msg1).build(); + TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG2 = + TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder() + .setField1(msg2).build(); + TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG3 = + TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder() + .setField1(msg3).build(); + + // Assign and serialize RepeatedFieldsGenerator. + ByteString data = TestParsingMergeLite.RepeatedFieldsGenerator.newBuilder() + .addField1(msg1).addField1(msg2).addField1(msg3) + .addField2(msg1).addField2(msg2).addField2(msg3) + .addField3(msg1).addField3(msg2).addField3(msg3) + .addGroup1(optionalG1).addGroup1(optionalG2).addGroup1(optionalG3) + .addGroup2(repeatedG1).addGroup2(repeatedG2).addGroup2(repeatedG3) + .addExt1(msg1).addExt1(msg2).addExt1(msg3) + .addExt2(msg1).addExt2(msg2).addExt2(msg3) + .build().toByteString(); + + // Parse TestParsingMergeLite. + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + UnittestLite.registerAllExtensions(registry); + TestParsingMergeLite parsingMerge = + TestParsingMergeLite.PARSER.parseFrom(data, registry); + + // Required and optional fields should be merged. + assertMessageMerged(parsingMerge.getRequiredAllTypes()); + assertMessageMerged(parsingMerge.getOptionalAllTypes()); + assertMessageMerged( + parsingMerge.getOptionalGroup().getOptionalGroupAllTypes()); + assertMessageMerged(parsingMerge.getExtension( + TestParsingMergeLite.optionalExt)); + + // Repeated fields should not be merged. + assertEquals(3, parsingMerge.getRepeatedAllTypesCount()); + assertEquals(3, parsingMerge.getRepeatedGroupCount()); + assertEquals(3, parsingMerge.getExtensionCount( + TestParsingMergeLite.repeatedExt)); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java new file mode 100644 index 0000000..cdcdcb2 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java @@ -0,0 +1,190 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; + +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.List; + +/** + * Tests for {@link RepeatedFieldBuilder}. This tests basic functionality. + * More extensive testing is provided via other tests that exercise the + * builder. + * + * @author jonp@google.com (Jon Perlow) + */ +public class RepeatedFieldBuilderTest extends TestCase { + + public void testBasicUse() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + RepeatedFieldBuilder builder = newRepeatedFieldBuilder(mockParent); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); + assertEquals(0, builder.getMessage(0).getOptionalInt32()); + assertEquals(1, builder.getMessage(1).getOptionalInt32()); + + List list = builder.build(); + assertEquals(2, list.size()); + assertEquals(0, list.get(0).getOptionalInt32()); + assertEquals(1, list.get(1).getOptionalInt32()); + assertIsUnmodifiable(list); + + // Make sure it doesn't change. + List list2 = builder.build(); + assertSame(list, list2); + assertEquals(0, mockParent.getInvalidationCount()); + } + + public void testGoingBackAndForth() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + RepeatedFieldBuilder builder = newRepeatedFieldBuilder(mockParent); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); + assertEquals(0, builder.getMessage(0).getOptionalInt32()); + assertEquals(1, builder.getMessage(1).getOptionalInt32()); + + // Convert to list + List list = builder.build(); + assertEquals(2, list.size()); + assertEquals(0, list.get(0).getOptionalInt32()); + assertEquals(1, list.get(1).getOptionalInt32()); + assertIsUnmodifiable(list); + + // Update 0th item + assertEquals(0, mockParent.getInvalidationCount()); + builder.getBuilder(0).setOptionalString("foo"); + assertEquals(1, mockParent.getInvalidationCount()); + list = builder.build(); + assertEquals(2, list.size()); + assertEquals(0, list.get(0).getOptionalInt32()); + assertEquals("foo", list.get(0).getOptionalString()); + assertEquals(1, list.get(1).getOptionalInt32()); + assertIsUnmodifiable(list); + assertEquals(1, mockParent.getInvalidationCount()); + } + + public void testVariousMethods() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + RepeatedFieldBuilder builder = newRepeatedFieldBuilder(mockParent); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(2).build()); + builder.addBuilder(0, TestAllTypes.getDefaultInstance()) + .setOptionalInt32(0); + builder.addBuilder(TestAllTypes.getDefaultInstance()).setOptionalInt32(3); + + assertEquals(0, builder.getMessage(0).getOptionalInt32()); + assertEquals(1, builder.getMessage(1).getOptionalInt32()); + assertEquals(2, builder.getMessage(2).getOptionalInt32()); + assertEquals(3, builder.getMessage(3).getOptionalInt32()); + + assertEquals(0, mockParent.getInvalidationCount()); + List messages = builder.build(); + assertEquals(4, messages.size()); + assertSame(messages, builder.build()); // expect same list + + // Remove a message. + builder.remove(2); + assertEquals(1, mockParent.getInvalidationCount()); + assertEquals(3, builder.getCount()); + assertEquals(0, builder.getMessage(0).getOptionalInt32()); + assertEquals(1, builder.getMessage(1).getOptionalInt32()); + assertEquals(3, builder.getMessage(2).getOptionalInt32()); + + // Remove a builder. + builder.remove(0); + assertEquals(1, mockParent.getInvalidationCount()); + assertEquals(2, builder.getCount()); + assertEquals(1, builder.getMessage(0).getOptionalInt32()); + assertEquals(3, builder.getMessage(1).getOptionalInt32()); + + // Test clear. + builder.clear(); + assertEquals(1, mockParent.getInvalidationCount()); + assertEquals(0, builder.getCount()); + assertTrue(builder.isEmpty()); + } + + public void testLists() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + RepeatedFieldBuilder builder = newRepeatedFieldBuilder(mockParent); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); + builder.addMessage(0, + TestAllTypes.newBuilder().setOptionalInt32(0).build()); + assertEquals(0, builder.getMessage(0).getOptionalInt32()); + assertEquals(1, builder.getMessage(1).getOptionalInt32()); + + // Use list of builders. + List builders = builder.getBuilderList(); + assertEquals(0, builders.get(0).getOptionalInt32()); + assertEquals(1, builders.get(1).getOptionalInt32()); + builders.get(0).setOptionalInt32(10); + builders.get(1).setOptionalInt32(11); + + // Use list of protos + List protos = builder.getMessageList(); + assertEquals(10, protos.get(0).getOptionalInt32()); + assertEquals(11, protos.get(1).getOptionalInt32()); + + // Add an item to the builders and verify it's updated in both + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(12).build()); + assertEquals(3, builders.size()); + assertEquals(3, protos.size()); + } + + private void assertIsUnmodifiable(List list) { + if (list == Collections.emptyList()) { + // OKAY -- Need to check this b/c EmptyList allows you to call clear. + } else { + try { + list.clear(); + fail("List wasn't immutable"); + } catch (UnsupportedOperationException e) { + // good + } + } + } + + private RepeatedFieldBuilder + newRepeatedFieldBuilder(GeneratedMessage.BuilderParent parent) { + return new RepeatedFieldBuilder(Collections.emptyList(), false, + parent, false); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java new file mode 100644 index 0000000..06707a2 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java @@ -0,0 +1,97 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.UnsupportedEncodingException; +import java.util.Iterator; + +/** + * This class tests {@link RopeByteString#substring(int, int)} by inheriting the tests from + * {@link LiteralByteStringTest}. Only a couple of methods are overridden. + * + * @author carlanton@google.com (Carl Haverl) + */ +public class RopeByteStringSubstringTest extends LiteralByteStringTest { + + @Override + protected void setUp() throws Exception { + classUnderTest = "RopeByteString"; + byte[] sourceBytes = ByteStringTest.getTestBytes(22341, 22337766L); + Iterator iter = ByteStringTest.makeConcretePieces(sourceBytes).iterator(); + ByteString sourceString = iter.next(); + while (iter.hasNext()) { + sourceString = sourceString.concat(iter.next()); + } + + int from = 1130; + int to = sourceBytes.length - 5555; + stringUnderTest = sourceString.substring(from, to); + referenceBytes = new byte[to - from]; + System.arraycopy(sourceBytes, from, referenceBytes, 0, to - from); + expectedHashCode = -1259260680; + } + + @Override + public void testGetTreeDepth() { + assertEquals(classUnderTest + " must have the expected tree depth", + 3, stringUnderTest.getTreeDepth()); + } + + @Override + public void testToString() throws UnsupportedEncodingException { + String sourceString = "I love unicode \u1234\u5678 characters"; + ByteString sourceByteString = ByteString.copyFromUtf8(sourceString); + int copies = 250; + + // By building the RopeByteString by concatenating, this is actually a fairly strenuous test. + StringBuilder builder = new StringBuilder(copies * sourceString.length()); + ByteString unicode = ByteString.EMPTY; + for (int i = 0; i < copies; ++i) { + builder.append(sourceString); + unicode = RopeByteString.concatenate(unicode, sourceByteString); + } + String testString = builder.toString(); + + // Do the substring part + testString = testString.substring(2, testString.length() - 6); + unicode = unicode.substring(2, unicode.size() - 6); + + assertEquals(classUnderTest + " from string must have the expected type", + classUnderTest, getActualClassName(unicode)); + String roundTripString = unicode.toString(UTF_8); + assertEquals(classUnderTest + " unicode bytes must match", + testString, roundTripString); + ByteString flatString = ByteString.copyFromUtf8(testString); + assertEquals(classUnderTest + " string must equal the flat string", flatString, unicode); + assertEquals(classUnderTest + " string must must have same hashCode as the flat string", + flatString.hashCode(), unicode.hashCode()); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RopeByteStringTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RopeByteStringTest.java new file mode 100644 index 0000000..15f660d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/RopeByteStringTest.java @@ -0,0 +1,115 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.Iterator; + +/** + * This class tests {@link RopeByteString} by inheriting the tests from + * {@link LiteralByteStringTest}. Only a couple of methods are overridden. + * + *

A full test of the result of {@link RopeByteString#substring(int, int)} is found in the + * separate class {@link RopeByteStringSubstringTest}. + * + * @author carlanton@google.com (Carl Haverl) + */ +public class RopeByteStringTest extends LiteralByteStringTest { + + @Override + protected void setUp() throws Exception { + classUnderTest = "RopeByteString"; + referenceBytes = ByteStringTest.getTestBytes(22341, 22337766L); + Iterator iter = ByteStringTest.makeConcretePieces(referenceBytes).iterator(); + stringUnderTest = iter.next(); + while (iter.hasNext()) { + stringUnderTest = stringUnderTest.concat(iter.next()); + } + expectedHashCode = -1214197238; + } + + @Override + public void testGetTreeDepth() { + assertEquals(classUnderTest + " must have the expected tree depth", + 4, stringUnderTest.getTreeDepth()); + } + + public void testBalance() { + int numberOfPieces = 10000; + int pieceSize = 64; + byte[] testBytes = ByteStringTest.getTestBytes(numberOfPieces * pieceSize, 113377L); + + // Build up a big ByteString from smaller pieces to force a rebalance + ByteString concatenated = ByteString.EMPTY; + for (int i = 0; i < numberOfPieces; ++i) { + concatenated = concatenated.concat(ByteString.copyFrom(testBytes, i * pieceSize, pieceSize)); + } + + assertEquals(classUnderTest + " from string must have the expected type", + classUnderTest, getActualClassName(concatenated)); + assertTrue(classUnderTest + " underlying bytes must match after balancing", + Arrays.equals(testBytes, concatenated.toByteArray())); + ByteString testString = ByteString.copyFrom(testBytes); + assertTrue(classUnderTest + " balanced string must equal flat string", + concatenated.equals(testString)); + assertTrue(classUnderTest + " flat string must equal balanced string", + testString.equals(concatenated)); + assertEquals(classUnderTest + " balanced string must have same hash code as flat string", + testString.hashCode(), concatenated.hashCode()); + } + + @Override + public void testToString() throws UnsupportedEncodingException { + String sourceString = "I love unicode \u1234\u5678 characters"; + ByteString sourceByteString = ByteString.copyFromUtf8(sourceString); + int copies = 250; + + // By building the RopeByteString by concatenating, this is actually a fairly strenuous test. + StringBuilder builder = new StringBuilder(copies * sourceString.length()); + ByteString unicode = ByteString.EMPTY; + for (int i = 0; i < copies; ++i) { + builder.append(sourceString); + unicode = RopeByteString.concatenate(unicode, sourceByteString); + } + String testString = builder.toString(); + + assertEquals(classUnderTest + " from string must have the expected type", + classUnderTest, getActualClassName(unicode)); + String roundTripString = unicode.toString(UTF_8); + assertEquals(classUnderTest + " unicode bytes must match", + testString, roundTripString); + ByteString flatString = ByteString.copyFromUtf8(testString); + assertEquals(classUnderTest + " string must equal the flat string", flatString, unicode); + assertEquals(classUnderTest + " string must must have same hashCode as the flat string", + flatString.hashCode(), unicode.hashCode()); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ServiceTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ServiceTest.java new file mode 100644 index 0000000..4be84f5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/ServiceTest.java @@ -0,0 +1,320 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.Descriptors.FileDescriptor; +import com.google.protobuf.Descriptors.MethodDescriptor; +import google.protobuf.no_generic_services_test.UnittestNoGenericServices; +import protobuf_unittest.MessageWithNoOuter; +import protobuf_unittest.ServiceWithNoOuter; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestService; +import protobuf_unittest.UnittestProto.FooRequest; +import protobuf_unittest.UnittestProto.FooResponse; +import protobuf_unittest.UnittestProto.BarRequest; +import protobuf_unittest.UnittestProto.BarResponse; + +import org.easymock.classextension.EasyMock; +import org.easymock.classextension.IMocksControl; +import org.easymock.IArgumentMatcher; + +import java.util.HashSet; +import java.util.Set; + +import junit.framework.TestCase; + +/** + * Tests services and stubs. + * + * @author kenton@google.com Kenton Varda + */ +public class ServiceTest extends TestCase { + private IMocksControl control; + private RpcController mockController; + + private final Descriptors.MethodDescriptor fooDescriptor = + TestService.getDescriptor().getMethods().get(0); + private final Descriptors.MethodDescriptor barDescriptor = + TestService.getDescriptor().getMethods().get(1); + + @Override + protected void setUp() throws Exception { + super.setUp(); + control = EasyMock.createStrictControl(); + mockController = control.createMock(RpcController.class); + } + + // ================================================================= + + /** Tests Service.callMethod(). */ + public void testCallMethod() throws Exception { + FooRequest fooRequest = FooRequest.newBuilder().build(); + BarRequest barRequest = BarRequest.newBuilder().build(); + MockCallback fooCallback = new MockCallback(); + MockCallback barCallback = new MockCallback(); + TestService mockService = control.createMock(TestService.class); + + mockService.foo(EasyMock.same(mockController), EasyMock.same(fooRequest), + this.wrapsCallback(fooCallback)); + mockService.bar(EasyMock.same(mockController), EasyMock.same(barRequest), + this.wrapsCallback(barCallback)); + control.replay(); + + mockService.callMethod(fooDescriptor, mockController, + fooRequest, fooCallback); + mockService.callMethod(barDescriptor, mockController, + barRequest, barCallback); + control.verify(); + } + + /** Tests Service.get{Request,Response}Prototype(). */ + public void testGetPrototype() throws Exception { + TestService mockService = control.createMock(TestService.class); + + assertSame(mockService.getRequestPrototype(fooDescriptor), + FooRequest.getDefaultInstance()); + assertSame(mockService.getResponsePrototype(fooDescriptor), + FooResponse.getDefaultInstance()); + assertSame(mockService.getRequestPrototype(barDescriptor), + BarRequest.getDefaultInstance()); + assertSame(mockService.getResponsePrototype(barDescriptor), + BarResponse.getDefaultInstance()); + } + + /** Tests generated stubs. */ + public void testStub() throws Exception { + FooRequest fooRequest = FooRequest.newBuilder().build(); + BarRequest barRequest = BarRequest.newBuilder().build(); + MockCallback fooCallback = new MockCallback(); + MockCallback barCallback = new MockCallback(); + RpcChannel mockChannel = control.createMock(RpcChannel.class); + TestService stub = TestService.newStub(mockChannel); + + mockChannel.callMethod( + EasyMock.same(fooDescriptor), + EasyMock.same(mockController), + EasyMock.same(fooRequest), + EasyMock.same(FooResponse.getDefaultInstance()), + this.wrapsCallback(fooCallback)); + mockChannel.callMethod( + EasyMock.same(barDescriptor), + EasyMock.same(mockController), + EasyMock.same(barRequest), + EasyMock.same(BarResponse.getDefaultInstance()), + this.wrapsCallback(barCallback)); + control.replay(); + + stub.foo(mockController, fooRequest, fooCallback); + stub.bar(mockController, barRequest, barCallback); + control.verify(); + } + + /** Tests generated blocking stubs. */ + public void testBlockingStub() throws Exception { + FooRequest fooRequest = FooRequest.newBuilder().build(); + BarRequest barRequest = BarRequest.newBuilder().build(); + BlockingRpcChannel mockChannel = + control.createMock(BlockingRpcChannel.class); + TestService.BlockingInterface stub = + TestService.newBlockingStub(mockChannel); + + FooResponse fooResponse = FooResponse.newBuilder().build(); + BarResponse barResponse = BarResponse.newBuilder().build(); + + EasyMock.expect(mockChannel.callBlockingMethod( + EasyMock.same(fooDescriptor), + EasyMock.same(mockController), + EasyMock.same(fooRequest), + EasyMock.same(FooResponse.getDefaultInstance()))).andReturn(fooResponse); + EasyMock.expect(mockChannel.callBlockingMethod( + EasyMock.same(barDescriptor), + EasyMock.same(mockController), + EasyMock.same(barRequest), + EasyMock.same(BarResponse.getDefaultInstance()))).andReturn(barResponse); + control.replay(); + + assertSame(fooResponse, stub.foo(mockController, fooRequest)); + assertSame(barResponse, stub.bar(mockController, barRequest)); + control.verify(); + } + + public void testNewReflectiveService() { + ServiceWithNoOuter.Interface impl = + control.createMock(ServiceWithNoOuter.Interface.class); + RpcController controller = control.createMock(RpcController.class); + Service service = ServiceWithNoOuter.newReflectiveService(impl); + + MethodDescriptor fooMethod = + ServiceWithNoOuter.getDescriptor().findMethodByName("Foo"); + MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance(); + RpcCallback callback = new RpcCallback() { + public void run(Message parameter) { + // No reason this should be run. + fail(); + } + }; + RpcCallback specializedCallback = + RpcUtil.specializeCallback(callback); + + impl.foo(EasyMock.same(controller), EasyMock.same(request), + EasyMock.same(specializedCallback)); + EasyMock.expectLastCall(); + + control.replay(); + + service.callMethod(fooMethod, controller, request, callback); + + control.verify(); + } + + public void testNewReflectiveBlockingService() throws ServiceException { + ServiceWithNoOuter.BlockingInterface impl = + control.createMock(ServiceWithNoOuter.BlockingInterface.class); + RpcController controller = control.createMock(RpcController.class); + BlockingService service = + ServiceWithNoOuter.newReflectiveBlockingService(impl); + + MethodDescriptor fooMethod = + ServiceWithNoOuter.getDescriptor().findMethodByName("Foo"); + MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance(); + + TestAllTypes expectedResponse = TestAllTypes.getDefaultInstance(); + EasyMock.expect(impl.foo(EasyMock.same(controller), EasyMock.same(request))) + .andReturn(expectedResponse); + + control.replay(); + + Message response = + service.callBlockingMethod(fooMethod, controller, request); + assertEquals(expectedResponse, response); + + control.verify(); + } + + public void testNoGenericServices() throws Exception { + // Non-services should be usable. + UnittestNoGenericServices.TestMessage message = + UnittestNoGenericServices.TestMessage.newBuilder() + .setA(123) + .setExtension(UnittestNoGenericServices.testExtension, 456) + .build(); + assertEquals(123, message.getA()); + assertEquals(1, UnittestNoGenericServices.TestEnum.FOO.getNumber()); + + // Build a list of the class names nested in UnittestNoGenericServices. + String outerName = "google.protobuf.no_generic_services_test." + + "UnittestNoGenericServices"; + Class outerClass = Class.forName(outerName); + + Set innerClassNames = new HashSet(); + for (Class innerClass : outerClass.getClasses()) { + String fullName = innerClass.getName(); + // Figure out the unqualified name of the inner class. + // Note: Surprisingly, the full name of an inner class will be separated + // from the outer class name by a '$' rather than a '.'. This is not + // mentioned in the documentation for java.lang.Class. I don't want to + // make assumptions, so I'm just going to accept any character as the + // separator. + assertTrue(fullName.startsWith(outerName)); + + if (!Service.class.isAssignableFrom(innerClass) && + !Message.class.isAssignableFrom(innerClass) && + !ProtocolMessageEnum.class.isAssignableFrom(innerClass)) { + // Ignore any classes not generated by the base code generator. + continue; + } + + innerClassNames.add(fullName.substring(outerName.length() + 1)); + } + + // No service class should have been generated. + assertTrue(innerClassNames.contains("TestMessage")); + assertTrue(innerClassNames.contains("TestEnum")); + assertFalse(innerClassNames.contains("TestService")); + + // But descriptors are there. + FileDescriptor file = UnittestNoGenericServices.getDescriptor(); + assertEquals(1, file.getServices().size()); + assertEquals("TestService", file.getServices().get(0).getName()); + assertEquals(1, file.getServices().get(0).getMethods().size()); + assertEquals("Foo", + file.getServices().get(0).getMethods().get(0).getName()); + } + + // ================================================================= + + /** + * wrapsCallback() is an EasyMock argument predicate. wrapsCallback(c) + * matches a callback if calling that callback causes c to be called. + * In other words, c wraps the given callback. + */ + private RpcCallback wrapsCallback( + MockCallback callback) { + EasyMock.reportMatcher(new WrapsCallback(callback)); + return null; + } + + /** The parameter to wrapsCallback() must be a MockCallback. */ + private static class MockCallback + implements RpcCallback { + private boolean called = false; + + public boolean isCalled() { return called; } + + public void reset() { called = false; } + public void run(Type message) { called = true; } + } + + /** Implementation of the wrapsCallback() argument matcher. */ + private static class WrapsCallback implements IArgumentMatcher { + private MockCallback callback; + + public WrapsCallback(MockCallback callback) { + this.callback = callback; + } + + @SuppressWarnings("unchecked") + public boolean matches(Object actual) { + if (!(actual instanceof RpcCallback)) { + return false; + } + RpcCallback actualCallback = (RpcCallback)actual; + + callback.reset(); + actualCallback.run(null); + return callback.isCalled(); + } + + public void appendTo(StringBuffer buffer) { + buffer.append("wrapsCallback(mockCallback)"); + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java new file mode 100644 index 0000000..5c2f7e7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java @@ -0,0 +1,155 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; + +import junit.framework.TestCase; + +/** + * Tests for {@link SingleFieldBuilder}. This tests basic functionality. + * More extensive testing is provided via other tests that exercise the + * builder. + * + * @author jonp@google.com (Jon Perlow) + */ +public class SingleFieldBuilderTest extends TestCase { + + public void testBasicUseAndInvalidations() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + SingleFieldBuilder builder = + new SingleFieldBuilder( + TestAllTypes.getDefaultInstance(), + mockParent, + false); + assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + assertEquals(TestAllTypes.getDefaultInstance(), + builder.getBuilder().buildPartial()); + assertEquals(0, mockParent.getInvalidationCount()); + + builder.getBuilder().setOptionalInt32(10); + assertEquals(0, mockParent.getInvalidationCount()); + TestAllTypes message = builder.build(); + assertEquals(10, message.getOptionalInt32()); + + // Test that we receive invalidations now that build has been called. + assertEquals(0, mockParent.getInvalidationCount()); + builder.getBuilder().setOptionalInt32(20); + assertEquals(1, mockParent.getInvalidationCount()); + + // Test that we don't keep getting invalidations on every change + builder.getBuilder().setOptionalInt32(30); + assertEquals(1, mockParent.getInvalidationCount()); + + } + + public void testSetMessage() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + SingleFieldBuilder builder = + new SingleFieldBuilder( + TestAllTypes.getDefaultInstance(), + mockParent, + false); + builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); + assertEquals(0, builder.getMessage().getOptionalInt32()); + + // Update message using the builder + builder.getBuilder().setOptionalInt32(1); + assertEquals(0, mockParent.getInvalidationCount()); + assertEquals(1, builder.getBuilder().getOptionalInt32()); + assertEquals(1, builder.getMessage().getOptionalInt32()); + builder.build(); + builder.getBuilder().setOptionalInt32(2); + assertEquals(2, builder.getBuilder().getOptionalInt32()); + assertEquals(2, builder.getMessage().getOptionalInt32()); + + // Make sure message stays cached + assertSame(builder.getMessage(), builder.getMessage()); + } + + public void testClear() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + SingleFieldBuilder builder = + new SingleFieldBuilder( + TestAllTypes.getDefaultInstance(), + mockParent, + false); + builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); + assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + builder.clear(); + assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + + builder.getBuilder().setOptionalInt32(1); + assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + builder.clear(); + assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + } + + public void testMerge() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + SingleFieldBuilder builder = + new SingleFieldBuilder( + TestAllTypes.getDefaultInstance(), + mockParent, + false); + + // Merge into default field. + builder.mergeFrom(TestAllTypes.getDefaultInstance()); + assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + + // Merge into non-default field on existing builder. + builder.getBuilder().setOptionalInt32(2); + builder.mergeFrom(TestAllTypes.newBuilder() + .setOptionalDouble(4.0) + .buildPartial()); + assertEquals(2, builder.getMessage().getOptionalInt32()); + assertEquals(4.0, builder.getMessage().getOptionalDouble()); + + // Merge into non-default field on existing message + builder.setMessage(TestAllTypes.newBuilder() + .setOptionalInt32(10) + .buildPartial()); + builder.mergeFrom(TestAllTypes.newBuilder() + .setOptionalDouble(5.0) + .buildPartial()); + assertEquals(10, builder.getMessage().getOptionalInt32()); + assertEquals(5.0, builder.getMessage().getOptionalDouble()); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java new file mode 100644 index 0000000..8f77a03 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java @@ -0,0 +1,420 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +/** + * @author darick@google.com Darick Tong + */ +public class SmallSortedMapTest extends TestCase { + // java.util.AbstractMap.SimpleEntry is private in JDK 1.5. We re-implement it + // here for JDK 1.5 users. + private static class SimpleEntry implements Map.Entry { + private final K key; + private V value; + + SimpleEntry(K key, V value) { + this.key = key; + this.value = value; + } + + public K getKey() { + return key; + } + + public V getValue() { + return value; + } + + public V setValue(V value) { + V oldValue = this.value; + this.value = value; + return oldValue; + } + + private static boolean eq(Object o1, Object o2) { + return o1 == null ? o2 == null : o1.equals(o2); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Map.Entry)) + return false; + Map.Entry e = (Map.Entry) o; + return eq(key, e.getKey()) && eq(value, e.getValue()); + } + + @Override + public int hashCode() { + return ((key == null) ? 0 : key.hashCode()) ^ + ((value == null) ? 0 : value.hashCode()); + } + } + + public void testPutAndGetArrayEntriesOnly() { + runPutAndGetTest(3); + } + + public void testPutAndGetOverflowEntries() { + runPutAndGetTest(6); + } + + private void runPutAndGetTest(int numElements) { + // Test with even and odd arraySize + SmallSortedMap map1 = + SmallSortedMap.newInstanceForTest(3); + SmallSortedMap map2 = + SmallSortedMap.newInstanceForTest(4); + SmallSortedMap map3 = + SmallSortedMap.newInstanceForTest(3); + SmallSortedMap map4 = + SmallSortedMap.newInstanceForTest(4); + + // Test with puts in ascending order. + for (int i = 0; i < numElements; i++) { + assertNull(map1.put(i, i + 1)); + assertNull(map2.put(i, i + 1)); + } + // Test with puts in descending order. + for (int i = numElements - 1; i >= 0; i--) { + assertNull(map3.put(i, i + 1)); + assertNull(map4.put(i, i + 1)); + } + + assertEquals(Math.min(3, numElements), map1.getNumArrayEntries()); + assertEquals(Math.min(4, numElements), map2.getNumArrayEntries()); + assertEquals(Math.min(3, numElements), map3.getNumArrayEntries()); + assertEquals(Math.min(4, numElements), map4.getNumArrayEntries()); + + List> allMaps = + new ArrayList>(); + allMaps.add(map1); + allMaps.add(map2); + allMaps.add(map3); + allMaps.add(map4); + + for (SmallSortedMap map : allMaps) { + assertEquals(numElements, map.size()); + for (int i = 0; i < numElements; i++) { + assertEquals(new Integer(i + 1), map.get(i)); + } + } + + assertEquals(map1, map2); + assertEquals(map2, map3); + assertEquals(map3, map4); + } + + public void testReplacingPut() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + assertNull(map.remove(i + 1)); + } + for (int i = 0; i < 6; i++) { + assertEquals(new Integer(i + 1), map.put(i, i + 2)); + } + } + + public void testRemove() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + assertNull(map.remove(i + 1)); + } + + assertEquals(3, map.getNumArrayEntries()); + assertEquals(3, map.getNumOverflowEntries()); + assertEquals(6, map.size()); + assertEquals(makeSortedKeySet(0, 1, 2, 3, 4, 5), map.keySet()); + + assertEquals(new Integer(2), map.remove(1)); + assertEquals(3, map.getNumArrayEntries()); + assertEquals(2, map.getNumOverflowEntries()); + assertEquals(5, map.size()); + assertEquals(makeSortedKeySet(0, 2, 3, 4, 5), map.keySet()); + + assertEquals(new Integer(5), map.remove(4)); + assertEquals(3, map.getNumArrayEntries()); + assertEquals(1, map.getNumOverflowEntries()); + assertEquals(4, map.size()); + assertEquals(makeSortedKeySet(0, 2, 3, 5), map.keySet()); + + assertEquals(new Integer(4), map.remove(3)); + assertEquals(3, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(3, map.size()); + assertEquals(makeSortedKeySet(0, 2, 5), map.keySet()); + + assertNull(map.remove(3)); + assertEquals(3, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(3, map.size()); + + assertEquals(new Integer(1), map.remove(0)); + assertEquals(2, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(2, map.size()); + } + + public void testClear() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + map.clear(); + assertEquals(0, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(0, map.size()); + } + + public void testGetArrayEntryAndOverflowEntries() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + assertEquals(3, map.getNumArrayEntries()); + for (int i = 0; i < 3; i++) { + Map.Entry entry = map.getArrayEntryAt(i); + assertEquals(new Integer(i), entry.getKey()); + assertEquals(new Integer(i + 1), entry.getValue()); + } + Iterator> it = + map.getOverflowEntries().iterator(); + for (int i = 3; i < 6; i++) { + assertTrue(it.hasNext()); + Map.Entry entry = it.next(); + assertEquals(new Integer(i), entry.getKey()); + assertEquals(new Integer(i + 1), entry.getValue()); + } + assertFalse(it.hasNext()); + } + + public void testEntrySetContains() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + Set> entrySet = map.entrySet(); + for (int i = 0; i < 6; i++) { + assertTrue( + entrySet.contains(new SimpleEntry(i, i + 1))); + assertFalse( + entrySet.contains(new SimpleEntry(i, i))); + } + } + + public void testEntrySetAdd() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + Set> entrySet = map.entrySet(); + for (int i = 0; i < 6; i++) { + Map.Entry entry = + new SimpleEntry(i, i + 1); + assertTrue(entrySet.add(entry)); + assertFalse(entrySet.add(entry)); + } + for (int i = 0; i < 6; i++) { + assertEquals(new Integer(i + 1), map.get(i)); + } + assertEquals(3, map.getNumArrayEntries()); + assertEquals(3, map.getNumOverflowEntries()); + assertEquals(6, map.size()); + } + + public void testEntrySetRemove() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + Set> entrySet = map.entrySet(); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + for (int i = 0; i < 6; i++) { + Map.Entry entry = + new SimpleEntry(i, i + 1); + assertTrue(entrySet.remove(entry)); + assertFalse(entrySet.remove(entry)); + } + assertTrue(map.isEmpty()); + assertEquals(0, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(0, map.size()); + } + + public void testEntrySetClear() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + map.entrySet().clear(); + assertTrue(map.isEmpty()); + assertEquals(0, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(0, map.size()); + } + + public void testEntrySetIteratorNext() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + Iterator> it = map.entrySet().iterator(); + for (int i = 0; i < 6; i++) { + assertTrue(it.hasNext()); + Map.Entry entry = it.next(); + assertEquals(new Integer(i), entry.getKey()); + assertEquals(new Integer(i + 1), entry.getValue()); + } + assertFalse(it.hasNext()); + } + + public void testEntrySetIteratorRemove() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + Iterator> it = map.entrySet().iterator(); + for (int i = 0; i < 6; i++) { + assertTrue(map.containsKey(i)); + it.next(); + it.remove(); + assertFalse(map.containsKey(i)); + assertEquals(6 - i - 1, map.size()); + } + } + + public void testMapEntryModification() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + Iterator> it = map.entrySet().iterator(); + for (int i = 0; i < 6; i++) { + Map.Entry entry = it.next(); + entry.setValue(i + 23); + } + for (int i = 0; i < 6; i++) { + assertEquals(new Integer(i + 23), map.get(i)); + } + } + + public void testMakeImmutable() { + SmallSortedMap map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + map.makeImmutable(); + assertEquals(new Integer(1), map.get(0)); + assertEquals(6, map.size()); + + try { + map.put(23, 23); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + Map other = new HashMap(); + other.put(23, 23); + try { + map.putAll(other); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + try { + map.remove(0); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + try { + map.clear(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + Set> entrySet = map.entrySet(); + try { + entrySet.clear(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + Iterator> it = entrySet.iterator(); + while (it.hasNext()) { + Map.Entry entry = it.next(); + try { + entry.setValue(0); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + try { + it.remove(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + } + + Set keySet = map.keySet(); + try { + keySet.clear(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + Iterator keys = keySet.iterator(); + while (keys.hasNext()) { + Integer key = keys.next(); + try { + keySet.remove(key); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + try { + keys.remove(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + } + } + + private Set makeSortedKeySet(Integer... keys) { + return new TreeSet(Arrays.asList(keys)); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java new file mode 100644 index 0000000..382acf0 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java @@ -0,0 +1,63 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import junit.framework.TestCase; + +/** + * Tests that proto2 api generation doesn't cause compile errors when + * compiling protocol buffers that have names that would otherwise conflict + * if not fully qualified (like @Deprecated and @Override). + * + * @author jonp@google.com (Jon Perlow) + */ +public class TestBadIdentifiers extends TestCase { + + public void testCompilation() { + // If this compiles, it means the generation was correct. + TestBadIdentifiersProto.Deprecated.newBuilder(); + TestBadIdentifiersProto.Override.newBuilder(); + } + + public void testGetDescriptor() { + Descriptors.FileDescriptor fileDescriptor = + TestBadIdentifiersProto.getDescriptor(); + String descriptorField = TestBadIdentifiersProto.Descriptor + .getDefaultInstance().getDescriptor(); + Descriptors.Descriptor protoDescriptor = TestBadIdentifiersProto.Descriptor + .getDefaultInstance().getDescriptorForType(); + String nestedDescriptorField = TestBadIdentifiersProto.Descriptor + .NestedDescriptor.getDefaultInstance().getDescriptor(); + Descriptors.Descriptor nestedProtoDescriptor = TestBadIdentifiersProto + .Descriptor.NestedDescriptor.getDefaultInstance() + .getDescriptorForType(); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TestUtil.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TestUtil.java new file mode 100644 index 0000000..76f5c60 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TestUtil.java @@ -0,0 +1,3955 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto; +import com.google.protobuf.UnittestLite; + +// The static imports are to avoid 100+ char lines. The following is roughly equivalent to +// import static protobuf_unittest.UnittestProto.*; +import static protobuf_unittest.UnittestProto.defaultInt32Extension; +import static protobuf_unittest.UnittestProto.defaultInt64Extension; +import static protobuf_unittest.UnittestProto.defaultUint32Extension; +import static protobuf_unittest.UnittestProto.defaultUint64Extension; +import static protobuf_unittest.UnittestProto.defaultSint32Extension; +import static protobuf_unittest.UnittestProto.defaultSint64Extension; +import static protobuf_unittest.UnittestProto.defaultFixed32Extension; +import static protobuf_unittest.UnittestProto.defaultFixed64Extension; +import static protobuf_unittest.UnittestProto.defaultSfixed32Extension; +import static protobuf_unittest.UnittestProto.defaultSfixed64Extension; +import static protobuf_unittest.UnittestProto.defaultFloatExtension; +import static protobuf_unittest.UnittestProto.defaultDoubleExtension; +import static protobuf_unittest.UnittestProto.defaultBoolExtension; +import static protobuf_unittest.UnittestProto.defaultStringExtension; +import static protobuf_unittest.UnittestProto.defaultBytesExtension; +import static protobuf_unittest.UnittestProto.defaultNestedEnumExtension; +import static protobuf_unittest.UnittestProto.defaultForeignEnumExtension; +import static protobuf_unittest.UnittestProto.defaultImportEnumExtension; +import static protobuf_unittest.UnittestProto.defaultStringPieceExtension; +import static protobuf_unittest.UnittestProto.defaultCordExtension; + +import static protobuf_unittest.UnittestProto.optionalInt32Extension; +import static protobuf_unittest.UnittestProto.optionalInt64Extension; +import static protobuf_unittest.UnittestProto.optionalUint32Extension; +import static protobuf_unittest.UnittestProto.optionalUint64Extension; +import static protobuf_unittest.UnittestProto.optionalSint32Extension; +import static protobuf_unittest.UnittestProto.optionalSint64Extension; +import static protobuf_unittest.UnittestProto.optionalFixed32Extension; +import static protobuf_unittest.UnittestProto.optionalFixed64Extension; +import static protobuf_unittest.UnittestProto.optionalSfixed32Extension; +import static protobuf_unittest.UnittestProto.optionalSfixed64Extension; +import static protobuf_unittest.UnittestProto.optionalFloatExtension; +import static protobuf_unittest.UnittestProto.optionalDoubleExtension; +import static protobuf_unittest.UnittestProto.optionalBoolExtension; +import static protobuf_unittest.UnittestProto.optionalStringExtension; +import static protobuf_unittest.UnittestProto.optionalBytesExtension; +import static protobuf_unittest.UnittestProto.optionalGroupExtension; +import static protobuf_unittest.UnittestProto.optionalCordExtension; +import static protobuf_unittest.UnittestProto.optionalForeignEnumExtension; +import static protobuf_unittest.UnittestProto.optionalForeignMessageExtension; +import static protobuf_unittest.UnittestProto.optionalImportEnumExtension; +import static protobuf_unittest.UnittestProto.optionalImportMessageExtension; +import static protobuf_unittest.UnittestProto.optionalNestedEnumExtension; +import static protobuf_unittest.UnittestProto.optionalNestedMessageExtension; +import static protobuf_unittest.UnittestProto.optionalPublicImportMessageExtension; +import static protobuf_unittest.UnittestProto.optionalLazyMessageExtension; +import static protobuf_unittest.UnittestProto.optionalStringPieceExtension; + +import static protobuf_unittest.UnittestProto.repeatedInt32Extension; +import static protobuf_unittest.UnittestProto.repeatedInt64Extension; +import static protobuf_unittest.UnittestProto.repeatedUint32Extension; +import static protobuf_unittest.UnittestProto.repeatedUint64Extension; +import static protobuf_unittest.UnittestProto.repeatedSint32Extension; +import static protobuf_unittest.UnittestProto.repeatedSint64Extension; +import static protobuf_unittest.UnittestProto.repeatedFixed32Extension; +import static protobuf_unittest.UnittestProto.repeatedFixed64Extension; +import static protobuf_unittest.UnittestProto.repeatedSfixed32Extension; +import static protobuf_unittest.UnittestProto.repeatedSfixed64Extension; +import static protobuf_unittest.UnittestProto.repeatedFloatExtension; +import static protobuf_unittest.UnittestProto.repeatedDoubleExtension; +import static protobuf_unittest.UnittestProto.repeatedBoolExtension; +import static protobuf_unittest.UnittestProto.repeatedStringExtension; +import static protobuf_unittest.UnittestProto.repeatedBytesExtension; +import static protobuf_unittest.UnittestProto.repeatedGroupExtension; +import static protobuf_unittest.UnittestProto.repeatedNestedMessageExtension; +import static protobuf_unittest.UnittestProto.repeatedForeignMessageExtension; +import static protobuf_unittest.UnittestProto.repeatedImportMessageExtension; +import static protobuf_unittest.UnittestProto.repeatedLazyMessageExtension; +import static protobuf_unittest.UnittestProto.repeatedNestedEnumExtension; +import static protobuf_unittest.UnittestProto.repeatedForeignEnumExtension; +import static protobuf_unittest.UnittestProto.repeatedImportEnumExtension; +import static protobuf_unittest.UnittestProto.repeatedStringPieceExtension; +import static protobuf_unittest.UnittestProto.repeatedCordExtension; + +import static protobuf_unittest.UnittestProto.OptionalGroup_extension; +import static protobuf_unittest.UnittestProto.RepeatedGroup_extension; + +import static protobuf_unittest.UnittestProto.packedInt32Extension; +import static protobuf_unittest.UnittestProto.packedInt64Extension; +import static protobuf_unittest.UnittestProto.packedUint32Extension; +import static protobuf_unittest.UnittestProto.packedUint64Extension; +import static protobuf_unittest.UnittestProto.packedSint32Extension; +import static protobuf_unittest.UnittestProto.packedSint64Extension; +import static protobuf_unittest.UnittestProto.packedFixed32Extension; +import static protobuf_unittest.UnittestProto.packedFixed64Extension; +import static protobuf_unittest.UnittestProto.packedSfixed32Extension; +import static protobuf_unittest.UnittestProto.packedSfixed64Extension; +import static protobuf_unittest.UnittestProto.packedFloatExtension; +import static protobuf_unittest.UnittestProto.packedDoubleExtension; +import static protobuf_unittest.UnittestProto.packedBoolExtension; +import static protobuf_unittest.UnittestProto.packedEnumExtension; + +import static com.google.protobuf.UnittestLite.defaultInt32ExtensionLite; +import static com.google.protobuf.UnittestLite.defaultInt64ExtensionLite; +import static com.google.protobuf.UnittestLite.defaultUint32ExtensionLite; +import static com.google.protobuf.UnittestLite.defaultUint64ExtensionLite; +import static com.google.protobuf.UnittestLite.defaultSint32ExtensionLite; +import static com.google.protobuf.UnittestLite.defaultSint64ExtensionLite; +import static com.google.protobuf.UnittestLite.defaultFixed32ExtensionLite; +import static com.google.protobuf.UnittestLite.defaultFixed64ExtensionLite; +import static com.google.protobuf.UnittestLite.defaultSfixed32ExtensionLite; +import static com.google.protobuf.UnittestLite.defaultSfixed64ExtensionLite; +import static com.google.protobuf.UnittestLite.defaultFloatExtensionLite; +import static com.google.protobuf.UnittestLite.defaultDoubleExtensionLite; +import static com.google.protobuf.UnittestLite.defaultBoolExtensionLite; +import static com.google.protobuf.UnittestLite.defaultStringExtensionLite; +import static com.google.protobuf.UnittestLite.defaultBytesExtensionLite; +import static com.google.protobuf.UnittestLite.defaultNestedEnumExtensionLite; +import static com.google.protobuf.UnittestLite.defaultForeignEnumExtensionLite; +import static com.google.protobuf.UnittestLite.defaultImportEnumExtensionLite; +import static com.google.protobuf.UnittestLite.defaultStringPieceExtensionLite; +import static com.google.protobuf.UnittestLite.defaultCordExtensionLite; + +import static com.google.protobuf.UnittestLite.optionalInt32ExtensionLite; +import static com.google.protobuf.UnittestLite.optionalInt64ExtensionLite; +import static com.google.protobuf.UnittestLite.optionalUint32ExtensionLite; +import static com.google.protobuf.UnittestLite.optionalUint64ExtensionLite; +import static com.google.protobuf.UnittestLite.optionalSint32ExtensionLite; +import static com.google.protobuf.UnittestLite.optionalSint64ExtensionLite; +import static com.google.protobuf.UnittestLite.optionalFixed32ExtensionLite; +import static com.google.protobuf.UnittestLite.optionalFixed64ExtensionLite; +import static com.google.protobuf.UnittestLite.optionalSfixed32ExtensionLite; +import static com.google.protobuf.UnittestLite.optionalSfixed64ExtensionLite; +import static com.google.protobuf.UnittestLite.optionalFloatExtensionLite; +import static com.google.protobuf.UnittestLite.optionalDoubleExtensionLite; +import static com.google.protobuf.UnittestLite.optionalBoolExtensionLite; +import static com.google.protobuf.UnittestLite.optionalStringExtensionLite; +import static com.google.protobuf.UnittestLite.optionalBytesExtensionLite; +import static com.google.protobuf.UnittestLite.optionalGroupExtensionLite; +import static com.google.protobuf.UnittestLite.optionalNestedMessageExtensionLite; +import static com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite; +import static com.google.protobuf.UnittestLite.optionalForeignMessageExtensionLite; +import static com.google.protobuf.UnittestLite.optionalImportEnumExtensionLite; +import static com.google.protobuf.UnittestLite.optionalImportMessageExtensionLite; +import static com.google.protobuf.UnittestLite.optionalNestedEnumExtensionLite; +import static com.google.protobuf.UnittestLite.optionalPublicImportMessageExtensionLite; +import static com.google.protobuf.UnittestLite.optionalLazyMessageExtensionLite; +import static com.google.protobuf.UnittestLite.optionalStringPieceExtensionLite; +import static com.google.protobuf.UnittestLite.optionalCordExtensionLite; + +import static com.google.protobuf.UnittestLite.repeatedInt32ExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedInt64ExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedUint32ExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedUint64ExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedSint32ExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedSint64ExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedFixed32ExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedFixed64ExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedSfixed32ExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedSfixed64ExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedFloatExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedDoubleExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedBoolExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedStringExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedBytesExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedGroupExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedNestedMessageExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedForeignMessageExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedImportMessageExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedLazyMessageExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedNestedEnumExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedForeignEnumExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedImportEnumExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedStringPieceExtensionLite; +import static com.google.protobuf.UnittestLite.repeatedCordExtensionLite; + +import static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite; +import static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite; + +import static com.google.protobuf.UnittestLite.packedInt32ExtensionLite; +import static com.google.protobuf.UnittestLite.packedInt64ExtensionLite; +import static com.google.protobuf.UnittestLite.packedUint32ExtensionLite; +import static com.google.protobuf.UnittestLite.packedUint64ExtensionLite; +import static com.google.protobuf.UnittestLite.packedSint32ExtensionLite; +import static com.google.protobuf.UnittestLite.packedSint64ExtensionLite; +import static com.google.protobuf.UnittestLite.packedFixed32ExtensionLite; +import static com.google.protobuf.UnittestLite.packedFixed64ExtensionLite; +import static com.google.protobuf.UnittestLite.packedSfixed32ExtensionLite; +import static com.google.protobuf.UnittestLite.packedSfixed64ExtensionLite; +import static com.google.protobuf.UnittestLite.packedFloatExtensionLite; +import static com.google.protobuf.UnittestLite.packedDoubleExtensionLite; +import static com.google.protobuf.UnittestLite.packedBoolExtensionLite; +import static com.google.protobuf.UnittestLite.packedEnumExtensionLite; + +import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestAllExtensionsOrBuilder; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; +import protobuf_unittest.UnittestProto.TestPackedExtensions; +import protobuf_unittest.UnittestProto.TestPackedTypes; +import protobuf_unittest.UnittestProto.TestUnpackedTypes; +import protobuf_unittest.UnittestProto.ForeignMessage; +import protobuf_unittest.UnittestProto.ForeignEnum; +import com.google.protobuf.test.UnittestImport.ImportEnum; +import com.google.protobuf.test.UnittestImport.ImportMessage; +import com.google.protobuf.test.UnittestImportPublic.PublicImportMessage; + +import com.google.protobuf.UnittestLite.TestAllTypesLite; +import com.google.protobuf.UnittestLite.TestAllExtensionsLite; +import com.google.protobuf.UnittestLite.TestAllExtensionsLiteOrBuilder; +import com.google.protobuf.UnittestLite.TestPackedExtensionsLite; +import com.google.protobuf.UnittestLite.ForeignMessageLite; +import com.google.protobuf.UnittestLite.ForeignEnumLite; +import com.google.protobuf.UnittestImportLite.ImportEnumLite; +import com.google.protobuf.UnittestImportLite.ImportMessageLite; +import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite; + +import junit.framework.Assert; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; + +/** + * Contains methods for setting all fields of {@code TestAllTypes} to + * some values as well as checking that all the fields are set to those values. + * These are useful for testing various protocol message features, e.g. + * set all fields of a message, serialize it, parse it, and check that all + * fields are set. + * + *

This code is not to be used outside of {@code com.google.protobuf} and + * subpackages. + * + * @author kenton@google.com Kenton Varda + */ +public final class TestUtil { + private TestUtil() {} + + /** Helper to convert a String to ByteString. */ + static ByteString toBytes(String str) { + try { + return ByteString.copyFrom(str.getBytes("UTF-8")); + } catch(java.io.UnsupportedEncodingException e) { + throw new RuntimeException("UTF-8 not supported.", e); + } + } + + /** + * Get a {@code TestAllTypes} with all fields set as they would be by + * {@link #setAllFields(TestAllTypes.Builder)}. + */ + public static TestAllTypes getAllSet() { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + setAllFields(builder); + return builder.build(); + } + + /** + * Get a {@code TestAllTypes.Builder} with all fields set as they would be by + * {@link #setAllFields(TestAllTypes.Builder)}. + */ + public static TestAllTypes.Builder getAllSetBuilder() { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + setAllFields(builder); + return builder; + } + + /** + * Get a {@code TestAllExtensions} with all fields set as they would be by + * {@link #setAllExtensions(TestAllExtensions.Builder)}. + */ + public static TestAllExtensions getAllExtensionsSet() { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + setAllExtensions(builder); + return builder.build(); + } + + public static TestAllExtensionsLite getAllLiteExtensionsSet() { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder(); + setAllExtensions(builder); + return builder.build(); + } + + public static TestPackedTypes getPackedSet() { + TestPackedTypes.Builder builder = TestPackedTypes.newBuilder(); + setPackedFields(builder); + return builder.build(); + } + + public static TestUnpackedTypes getUnpackedSet() { + TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder(); + setUnpackedFields(builder); + return builder.build(); + } + + public static TestPackedExtensions getPackedExtensionsSet() { + TestPackedExtensions.Builder builder = TestPackedExtensions.newBuilder(); + setPackedExtensions(builder); + return builder.build(); + } + + public static TestPackedExtensionsLite getLitePackedExtensionsSet() { + TestPackedExtensionsLite.Builder builder = + TestPackedExtensionsLite.newBuilder(); + setPackedExtensions(builder); + return builder.build(); + } + + /** + * Set every field of {@code message} to the values expected by + * {@code assertAllFieldsSet()}. + */ + public static void setAllFields(TestAllTypes.Builder message) { + message.setOptionalInt32 (101); + message.setOptionalInt64 (102); + message.setOptionalUint32 (103); + message.setOptionalUint64 (104); + message.setOptionalSint32 (105); + message.setOptionalSint64 (106); + message.setOptionalFixed32 (107); + message.setOptionalFixed64 (108); + message.setOptionalSfixed32(109); + message.setOptionalSfixed64(110); + message.setOptionalFloat (111); + message.setOptionalDouble (112); + message.setOptionalBool (true); + message.setOptionalString ("115"); + message.setOptionalBytes (toBytes("116")); + + message.setOptionalGroup( + TestAllTypes.OptionalGroup.newBuilder().setA(117).build()); + message.setOptionalNestedMessage( + TestAllTypes.NestedMessage.newBuilder().setBb(118).build()); + message.setOptionalForeignMessage( + ForeignMessage.newBuilder().setC(119).build()); + message.setOptionalImportMessage( + ImportMessage.newBuilder().setD(120).build()); + message.setOptionalPublicImportMessage( + PublicImportMessage.newBuilder().setE(126).build()); + message.setOptionalLazyMessage( + TestAllTypes.NestedMessage.newBuilder().setBb(127).build()); + + message.setOptionalNestedEnum (TestAllTypes.NestedEnum.BAZ); + message.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAZ); + message.setOptionalImportEnum (ImportEnum.IMPORT_BAZ); + + message.setOptionalStringPiece("124"); + message.setOptionalCord("125"); + + // ----------------------------------------------------------------- + + message.addRepeatedInt32 (201); + message.addRepeatedInt64 (202); + message.addRepeatedUint32 (203); + message.addRepeatedUint64 (204); + message.addRepeatedSint32 (205); + message.addRepeatedSint64 (206); + message.addRepeatedFixed32 (207); + message.addRepeatedFixed64 (208); + message.addRepeatedSfixed32(209); + message.addRepeatedSfixed64(210); + message.addRepeatedFloat (211); + message.addRepeatedDouble (212); + message.addRepeatedBool (true); + message.addRepeatedString ("215"); + message.addRepeatedBytes (toBytes("216")); + + message.addRepeatedGroup( + TestAllTypes.RepeatedGroup.newBuilder().setA(217).build()); + message.addRepeatedNestedMessage( + TestAllTypes.NestedMessage.newBuilder().setBb(218).build()); + message.addRepeatedForeignMessage( + ForeignMessage.newBuilder().setC(219).build()); + message.addRepeatedImportMessage( + ImportMessage.newBuilder().setD(220).build()); + message.addRepeatedLazyMessage( + TestAllTypes.NestedMessage.newBuilder().setBb(227).build()); + + message.addRepeatedNestedEnum (TestAllTypes.NestedEnum.BAR); + message.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAR); + message.addRepeatedImportEnum (ImportEnum.IMPORT_BAR); + + message.addRepeatedStringPiece("224"); + message.addRepeatedCord("225"); + + // Add a second one of each field. + message.addRepeatedInt32 (301); + message.addRepeatedInt64 (302); + message.addRepeatedUint32 (303); + message.addRepeatedUint64 (304); + message.addRepeatedSint32 (305); + message.addRepeatedSint64 (306); + message.addRepeatedFixed32 (307); + message.addRepeatedFixed64 (308); + message.addRepeatedSfixed32(309); + message.addRepeatedSfixed64(310); + message.addRepeatedFloat (311); + message.addRepeatedDouble (312); + message.addRepeatedBool (false); + message.addRepeatedString ("315"); + message.addRepeatedBytes (toBytes("316")); + + message.addRepeatedGroup( + TestAllTypes.RepeatedGroup.newBuilder().setA(317).build()); + message.addRepeatedNestedMessage( + TestAllTypes.NestedMessage.newBuilder().setBb(318).build()); + message.addRepeatedForeignMessage( + ForeignMessage.newBuilder().setC(319).build()); + message.addRepeatedImportMessage( + ImportMessage.newBuilder().setD(320).build()); + message.addRepeatedLazyMessage( + TestAllTypes.NestedMessage.newBuilder().setBb(327).build()); + + message.addRepeatedNestedEnum (TestAllTypes.NestedEnum.BAZ); + message.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAZ); + message.addRepeatedImportEnum (ImportEnum.IMPORT_BAZ); + + message.addRepeatedStringPiece("324"); + message.addRepeatedCord("325"); + + // ----------------------------------------------------------------- + + message.setDefaultInt32 (401); + message.setDefaultInt64 (402); + message.setDefaultUint32 (403); + message.setDefaultUint64 (404); + message.setDefaultSint32 (405); + message.setDefaultSint64 (406); + message.setDefaultFixed32 (407); + message.setDefaultFixed64 (408); + message.setDefaultSfixed32(409); + message.setDefaultSfixed64(410); + message.setDefaultFloat (411); + message.setDefaultDouble (412); + message.setDefaultBool (false); + message.setDefaultString ("415"); + message.setDefaultBytes (toBytes("416")); + + message.setDefaultNestedEnum (TestAllTypes.NestedEnum.FOO); + message.setDefaultForeignEnum(ForeignEnum.FOREIGN_FOO); + message.setDefaultImportEnum (ImportEnum.IMPORT_FOO); + + message.setDefaultStringPiece("424"); + message.setDefaultCord("425"); + } + + // ------------------------------------------------------------------- + + /** + * Modify the repeated fields of {@code message} to contain the values + * expected by {@code assertRepeatedFieldsModified()}. + */ + public static void modifyRepeatedFields(TestAllTypes.Builder message) { + message.setRepeatedInt32 (1, 501); + message.setRepeatedInt64 (1, 502); + message.setRepeatedUint32 (1, 503); + message.setRepeatedUint64 (1, 504); + message.setRepeatedSint32 (1, 505); + message.setRepeatedSint64 (1, 506); + message.setRepeatedFixed32 (1, 507); + message.setRepeatedFixed64 (1, 508); + message.setRepeatedSfixed32(1, 509); + message.setRepeatedSfixed64(1, 510); + message.setRepeatedFloat (1, 511); + message.setRepeatedDouble (1, 512); + message.setRepeatedBool (1, true); + message.setRepeatedString (1, "515"); + message.setRepeatedBytes (1, toBytes("516")); + + message.setRepeatedGroup(1, + TestAllTypes.RepeatedGroup.newBuilder().setA(517).build()); + message.setRepeatedNestedMessage(1, + TestAllTypes.NestedMessage.newBuilder().setBb(518).build()); + message.setRepeatedForeignMessage(1, + ForeignMessage.newBuilder().setC(519).build()); + message.setRepeatedImportMessage(1, + ImportMessage.newBuilder().setD(520).build()); + message.setRepeatedLazyMessage(1, + TestAllTypes.NestedMessage.newBuilder().setBb(527).build()); + + message.setRepeatedNestedEnum (1, TestAllTypes.NestedEnum.FOO); + message.setRepeatedForeignEnum(1, ForeignEnum.FOREIGN_FOO); + message.setRepeatedImportEnum (1, ImportEnum.IMPORT_FOO); + + message.setRepeatedStringPiece(1, "524"); + message.setRepeatedCord(1, "525"); + } + + // ------------------------------------------------------------------- + + /** + * Assert (using {@code junit.framework.Assert}} that all fields of + * {@code message} are set to the values assigned by {@code setAllFields}. + */ + public static void assertAllFieldsSet(TestAllTypesOrBuilder message) { + Assert.assertTrue(message.hasOptionalInt32 ()); + Assert.assertTrue(message.hasOptionalInt64 ()); + Assert.assertTrue(message.hasOptionalUint32 ()); + Assert.assertTrue(message.hasOptionalUint64 ()); + Assert.assertTrue(message.hasOptionalSint32 ()); + Assert.assertTrue(message.hasOptionalSint64 ()); + Assert.assertTrue(message.hasOptionalFixed32 ()); + Assert.assertTrue(message.hasOptionalFixed64 ()); + Assert.assertTrue(message.hasOptionalSfixed32()); + Assert.assertTrue(message.hasOptionalSfixed64()); + Assert.assertTrue(message.hasOptionalFloat ()); + Assert.assertTrue(message.hasOptionalDouble ()); + Assert.assertTrue(message.hasOptionalBool ()); + Assert.assertTrue(message.hasOptionalString ()); + Assert.assertTrue(message.hasOptionalBytes ()); + + Assert.assertTrue(message.hasOptionalGroup ()); + Assert.assertTrue(message.hasOptionalNestedMessage ()); + Assert.assertTrue(message.hasOptionalForeignMessage()); + Assert.assertTrue(message.hasOptionalImportMessage ()); + + Assert.assertTrue(message.getOptionalGroup ().hasA()); + Assert.assertTrue(message.getOptionalNestedMessage ().hasBb()); + Assert.assertTrue(message.getOptionalForeignMessage().hasC()); + Assert.assertTrue(message.getOptionalImportMessage ().hasD()); + + Assert.assertTrue(message.hasOptionalNestedEnum ()); + Assert.assertTrue(message.hasOptionalForeignEnum()); + Assert.assertTrue(message.hasOptionalImportEnum ()); + + Assert.assertTrue(message.hasOptionalStringPiece()); + Assert.assertTrue(message.hasOptionalCord()); + + Assert.assertEquals(101 , message.getOptionalInt32 ()); + Assert.assertEquals(102 , message.getOptionalInt64 ()); + Assert.assertEquals(103 , message.getOptionalUint32 ()); + Assert.assertEquals(104 , message.getOptionalUint64 ()); + Assert.assertEquals(105 , message.getOptionalSint32 ()); + Assert.assertEquals(106 , message.getOptionalSint64 ()); + Assert.assertEquals(107 , message.getOptionalFixed32 ()); + Assert.assertEquals(108 , message.getOptionalFixed64 ()); + Assert.assertEquals(109 , message.getOptionalSfixed32()); + Assert.assertEquals(110 , message.getOptionalSfixed64()); + Assert.assertEquals(111 , message.getOptionalFloat (), 0.0); + Assert.assertEquals(112 , message.getOptionalDouble (), 0.0); + Assert.assertEquals(true , message.getOptionalBool ()); + Assert.assertEquals("115", message.getOptionalString ()); + Assert.assertEquals(toBytes("116"), message.getOptionalBytes()); + + Assert.assertEquals(117, message.getOptionalGroup ().getA()); + Assert.assertEquals(118, message.getOptionalNestedMessage ().getBb()); + Assert.assertEquals(119, message.getOptionalForeignMessage ().getC()); + Assert.assertEquals(120, message.getOptionalImportMessage ().getD()); + Assert.assertEquals(126, message.getOptionalPublicImportMessage().getE()); + Assert.assertEquals(127, message.getOptionalLazyMessage ().getBb()); + + Assert.assertEquals(TestAllTypes.NestedEnum.BAZ, message.getOptionalNestedEnum()); + Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getOptionalForeignEnum()); + Assert.assertEquals(ImportEnum.IMPORT_BAZ, message.getOptionalImportEnum()); + + Assert.assertEquals("124", message.getOptionalStringPiece()); + Assert.assertEquals("125", message.getOptionalCord()); + + // ----------------------------------------------------------------- + + Assert.assertEquals(2, message.getRepeatedInt32Count ()); + Assert.assertEquals(2, message.getRepeatedInt64Count ()); + Assert.assertEquals(2, message.getRepeatedUint32Count ()); + Assert.assertEquals(2, message.getRepeatedUint64Count ()); + Assert.assertEquals(2, message.getRepeatedSint32Count ()); + Assert.assertEquals(2, message.getRepeatedSint64Count ()); + Assert.assertEquals(2, message.getRepeatedFixed32Count ()); + Assert.assertEquals(2, message.getRepeatedFixed64Count ()); + Assert.assertEquals(2, message.getRepeatedSfixed32Count()); + Assert.assertEquals(2, message.getRepeatedSfixed64Count()); + Assert.assertEquals(2, message.getRepeatedFloatCount ()); + Assert.assertEquals(2, message.getRepeatedDoubleCount ()); + Assert.assertEquals(2, message.getRepeatedBoolCount ()); + Assert.assertEquals(2, message.getRepeatedStringCount ()); + Assert.assertEquals(2, message.getRepeatedBytesCount ()); + + Assert.assertEquals(2, message.getRepeatedGroupCount ()); + Assert.assertEquals(2, message.getRepeatedNestedMessageCount ()); + Assert.assertEquals(2, message.getRepeatedForeignMessageCount()); + Assert.assertEquals(2, message.getRepeatedImportMessageCount ()); + Assert.assertEquals(2, message.getRepeatedLazyMessageCount ()); + Assert.assertEquals(2, message.getRepeatedNestedEnumCount ()); + Assert.assertEquals(2, message.getRepeatedForeignEnumCount ()); + Assert.assertEquals(2, message.getRepeatedImportEnumCount ()); + + Assert.assertEquals(2, message.getRepeatedStringPieceCount()); + Assert.assertEquals(2, message.getRepeatedCordCount()); + + Assert.assertEquals(201 , message.getRepeatedInt32 (0)); + Assert.assertEquals(202 , message.getRepeatedInt64 (0)); + Assert.assertEquals(203 , message.getRepeatedUint32 (0)); + Assert.assertEquals(204 , message.getRepeatedUint64 (0)); + Assert.assertEquals(205 , message.getRepeatedSint32 (0)); + Assert.assertEquals(206 , message.getRepeatedSint64 (0)); + Assert.assertEquals(207 , message.getRepeatedFixed32 (0)); + Assert.assertEquals(208 , message.getRepeatedFixed64 (0)); + Assert.assertEquals(209 , message.getRepeatedSfixed32(0)); + Assert.assertEquals(210 , message.getRepeatedSfixed64(0)); + Assert.assertEquals(211 , message.getRepeatedFloat (0), 0.0); + Assert.assertEquals(212 , message.getRepeatedDouble (0), 0.0); + Assert.assertEquals(true , message.getRepeatedBool (0)); + Assert.assertEquals("215", message.getRepeatedString (0)); + Assert.assertEquals(toBytes("216"), message.getRepeatedBytes(0)); + + Assert.assertEquals(217, message.getRepeatedGroup (0).getA()); + Assert.assertEquals(218, message.getRepeatedNestedMessage (0).getBb()); + Assert.assertEquals(219, message.getRepeatedForeignMessage(0).getC()); + Assert.assertEquals(220, message.getRepeatedImportMessage (0).getD()); + Assert.assertEquals(227, message.getRepeatedLazyMessage (0).getBb()); + + Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnum (0)); + Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnum(0)); + Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnum(0)); + + Assert.assertEquals("224", message.getRepeatedStringPiece(0)); + Assert.assertEquals("225", message.getRepeatedCord(0)); + + Assert.assertEquals(301 , message.getRepeatedInt32 (1)); + Assert.assertEquals(302 , message.getRepeatedInt64 (1)); + Assert.assertEquals(303 , message.getRepeatedUint32 (1)); + Assert.assertEquals(304 , message.getRepeatedUint64 (1)); + Assert.assertEquals(305 , message.getRepeatedSint32 (1)); + Assert.assertEquals(306 , message.getRepeatedSint64 (1)); + Assert.assertEquals(307 , message.getRepeatedFixed32 (1)); + Assert.assertEquals(308 , message.getRepeatedFixed64 (1)); + Assert.assertEquals(309 , message.getRepeatedSfixed32(1)); + Assert.assertEquals(310 , message.getRepeatedSfixed64(1)); + Assert.assertEquals(311 , message.getRepeatedFloat (1), 0.0); + Assert.assertEquals(312 , message.getRepeatedDouble (1), 0.0); + Assert.assertEquals(false, message.getRepeatedBool (1)); + Assert.assertEquals("315", message.getRepeatedString (1)); + Assert.assertEquals(toBytes("316"), message.getRepeatedBytes(1)); + + Assert.assertEquals(317, message.getRepeatedGroup (1).getA()); + Assert.assertEquals(318, message.getRepeatedNestedMessage (1).getBb()); + Assert.assertEquals(319, message.getRepeatedForeignMessage(1).getC()); + Assert.assertEquals(320, message.getRepeatedImportMessage (1).getD()); + Assert.assertEquals(327, message.getRepeatedLazyMessage (1).getBb()); + + Assert.assertEquals(TestAllTypes.NestedEnum.BAZ, message.getRepeatedNestedEnum (1)); + Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getRepeatedForeignEnum(1)); + Assert.assertEquals(ImportEnum.IMPORT_BAZ, message.getRepeatedImportEnum(1)); + + Assert.assertEquals("324", message.getRepeatedStringPiece(1)); + Assert.assertEquals("325", message.getRepeatedCord(1)); + + // ----------------------------------------------------------------- + + Assert.assertTrue(message.hasDefaultInt32 ()); + Assert.assertTrue(message.hasDefaultInt64 ()); + Assert.assertTrue(message.hasDefaultUint32 ()); + Assert.assertTrue(message.hasDefaultUint64 ()); + Assert.assertTrue(message.hasDefaultSint32 ()); + Assert.assertTrue(message.hasDefaultSint64 ()); + Assert.assertTrue(message.hasDefaultFixed32 ()); + Assert.assertTrue(message.hasDefaultFixed64 ()); + Assert.assertTrue(message.hasDefaultSfixed32()); + Assert.assertTrue(message.hasDefaultSfixed64()); + Assert.assertTrue(message.hasDefaultFloat ()); + Assert.assertTrue(message.hasDefaultDouble ()); + Assert.assertTrue(message.hasDefaultBool ()); + Assert.assertTrue(message.hasDefaultString ()); + Assert.assertTrue(message.hasDefaultBytes ()); + + Assert.assertTrue(message.hasDefaultNestedEnum ()); + Assert.assertTrue(message.hasDefaultForeignEnum()); + Assert.assertTrue(message.hasDefaultImportEnum ()); + + Assert.assertTrue(message.hasDefaultStringPiece()); + Assert.assertTrue(message.hasDefaultCord()); + + Assert.assertEquals(401 , message.getDefaultInt32 ()); + Assert.assertEquals(402 , message.getDefaultInt64 ()); + Assert.assertEquals(403 , message.getDefaultUint32 ()); + Assert.assertEquals(404 , message.getDefaultUint64 ()); + Assert.assertEquals(405 , message.getDefaultSint32 ()); + Assert.assertEquals(406 , message.getDefaultSint64 ()); + Assert.assertEquals(407 , message.getDefaultFixed32 ()); + Assert.assertEquals(408 , message.getDefaultFixed64 ()); + Assert.assertEquals(409 , message.getDefaultSfixed32()); + Assert.assertEquals(410 , message.getDefaultSfixed64()); + Assert.assertEquals(411 , message.getDefaultFloat (), 0.0); + Assert.assertEquals(412 , message.getDefaultDouble (), 0.0); + Assert.assertEquals(false, message.getDefaultBool ()); + Assert.assertEquals("415", message.getDefaultString ()); + Assert.assertEquals(toBytes("416"), message.getDefaultBytes()); + + Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getDefaultNestedEnum ()); + Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getDefaultForeignEnum()); + Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getDefaultImportEnum()); + + Assert.assertEquals("424", message.getDefaultStringPiece()); + Assert.assertEquals("425", message.getDefaultCord()); + } + + // ------------------------------------------------------------------- + /** + * Assert (using {@code junit.framework.Assert}} that all fields of + * {@code message} are cleared, and that getting the fields returns their + * default values. + */ + public static void assertClear(TestAllTypesOrBuilder message) { + // hasBlah() should initially be false for all optional fields. + Assert.assertFalse(message.hasOptionalInt32 ()); + Assert.assertFalse(message.hasOptionalInt64 ()); + Assert.assertFalse(message.hasOptionalUint32 ()); + Assert.assertFalse(message.hasOptionalUint64 ()); + Assert.assertFalse(message.hasOptionalSint32 ()); + Assert.assertFalse(message.hasOptionalSint64 ()); + Assert.assertFalse(message.hasOptionalFixed32 ()); + Assert.assertFalse(message.hasOptionalFixed64 ()); + Assert.assertFalse(message.hasOptionalSfixed32()); + Assert.assertFalse(message.hasOptionalSfixed64()); + Assert.assertFalse(message.hasOptionalFloat ()); + Assert.assertFalse(message.hasOptionalDouble ()); + Assert.assertFalse(message.hasOptionalBool ()); + Assert.assertFalse(message.hasOptionalString ()); + Assert.assertFalse(message.hasOptionalBytes ()); + + Assert.assertFalse(message.hasOptionalGroup ()); + Assert.assertFalse(message.hasOptionalNestedMessage ()); + Assert.assertFalse(message.hasOptionalForeignMessage()); + Assert.assertFalse(message.hasOptionalImportMessage ()); + + Assert.assertFalse(message.hasOptionalNestedEnum ()); + Assert.assertFalse(message.hasOptionalForeignEnum()); + Assert.assertFalse(message.hasOptionalImportEnum ()); + + Assert.assertFalse(message.hasOptionalStringPiece()); + Assert.assertFalse(message.hasOptionalCord()); + + // Optional fields without defaults are set to zero or something like it. + Assert.assertEquals(0 , message.getOptionalInt32 ()); + Assert.assertEquals(0 , message.getOptionalInt64 ()); + Assert.assertEquals(0 , message.getOptionalUint32 ()); + Assert.assertEquals(0 , message.getOptionalUint64 ()); + Assert.assertEquals(0 , message.getOptionalSint32 ()); + Assert.assertEquals(0 , message.getOptionalSint64 ()); + Assert.assertEquals(0 , message.getOptionalFixed32 ()); + Assert.assertEquals(0 , message.getOptionalFixed64 ()); + Assert.assertEquals(0 , message.getOptionalSfixed32()); + Assert.assertEquals(0 , message.getOptionalSfixed64()); + Assert.assertEquals(0 , message.getOptionalFloat (), 0.0); + Assert.assertEquals(0 , message.getOptionalDouble (), 0.0); + Assert.assertEquals(false, message.getOptionalBool ()); + Assert.assertEquals("" , message.getOptionalString ()); + Assert.assertEquals(ByteString.EMPTY, message.getOptionalBytes()); + + // Embedded messages should also be clear. + Assert.assertFalse(message.getOptionalGroup ().hasA()); + Assert.assertFalse(message.getOptionalNestedMessage ().hasBb()); + Assert.assertFalse(message.getOptionalForeignMessage ().hasC()); + Assert.assertFalse(message.getOptionalImportMessage ().hasD()); + Assert.assertFalse(message.getOptionalPublicImportMessage().hasE()); + Assert.assertFalse(message.getOptionalLazyMessage ().hasBb()); + + Assert.assertEquals(0, message.getOptionalGroup ().getA()); + Assert.assertEquals(0, message.getOptionalNestedMessage ().getBb()); + Assert.assertEquals(0, message.getOptionalForeignMessage ().getC()); + Assert.assertEquals(0, message.getOptionalImportMessage ().getD()); + Assert.assertEquals(0, message.getOptionalPublicImportMessage().getE()); + Assert.assertEquals(0, message.getOptionalLazyMessage ().getBb()); + + // Enums without defaults are set to the first value in the enum. + Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getOptionalNestedEnum ()); + Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getOptionalForeignEnum()); + Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getOptionalImportEnum()); + + Assert.assertEquals("", message.getOptionalStringPiece()); + Assert.assertEquals("", message.getOptionalCord()); + + // Repeated fields are empty. + Assert.assertEquals(0, message.getRepeatedInt32Count ()); + Assert.assertEquals(0, message.getRepeatedInt64Count ()); + Assert.assertEquals(0, message.getRepeatedUint32Count ()); + Assert.assertEquals(0, message.getRepeatedUint64Count ()); + Assert.assertEquals(0, message.getRepeatedSint32Count ()); + Assert.assertEquals(0, message.getRepeatedSint64Count ()); + Assert.assertEquals(0, message.getRepeatedFixed32Count ()); + Assert.assertEquals(0, message.getRepeatedFixed64Count ()); + Assert.assertEquals(0, message.getRepeatedSfixed32Count()); + Assert.assertEquals(0, message.getRepeatedSfixed64Count()); + Assert.assertEquals(0, message.getRepeatedFloatCount ()); + Assert.assertEquals(0, message.getRepeatedDoubleCount ()); + Assert.assertEquals(0, message.getRepeatedBoolCount ()); + Assert.assertEquals(0, message.getRepeatedStringCount ()); + Assert.assertEquals(0, message.getRepeatedBytesCount ()); + + Assert.assertEquals(0, message.getRepeatedGroupCount ()); + Assert.assertEquals(0, message.getRepeatedNestedMessageCount ()); + Assert.assertEquals(0, message.getRepeatedForeignMessageCount()); + Assert.assertEquals(0, message.getRepeatedImportMessageCount ()); + Assert.assertEquals(0, message.getRepeatedLazyMessageCount ()); + Assert.assertEquals(0, message.getRepeatedNestedEnumCount ()); + Assert.assertEquals(0, message.getRepeatedForeignEnumCount ()); + Assert.assertEquals(0, message.getRepeatedImportEnumCount ()); + + Assert.assertEquals(0, message.getRepeatedStringPieceCount()); + Assert.assertEquals(0, message.getRepeatedCordCount()); + + // hasBlah() should also be false for all default fields. + Assert.assertFalse(message.hasDefaultInt32 ()); + Assert.assertFalse(message.hasDefaultInt64 ()); + Assert.assertFalse(message.hasDefaultUint32 ()); + Assert.assertFalse(message.hasDefaultUint64 ()); + Assert.assertFalse(message.hasDefaultSint32 ()); + Assert.assertFalse(message.hasDefaultSint64 ()); + Assert.assertFalse(message.hasDefaultFixed32 ()); + Assert.assertFalse(message.hasDefaultFixed64 ()); + Assert.assertFalse(message.hasDefaultSfixed32()); + Assert.assertFalse(message.hasDefaultSfixed64()); + Assert.assertFalse(message.hasDefaultFloat ()); + Assert.assertFalse(message.hasDefaultDouble ()); + Assert.assertFalse(message.hasDefaultBool ()); + Assert.assertFalse(message.hasDefaultString ()); + Assert.assertFalse(message.hasDefaultBytes ()); + + Assert.assertFalse(message.hasDefaultNestedEnum ()); + Assert.assertFalse(message.hasDefaultForeignEnum()); + Assert.assertFalse(message.hasDefaultImportEnum ()); + + Assert.assertFalse(message.hasDefaultStringPiece()); + Assert.assertFalse(message.hasDefaultCord()); + + // Fields with defaults have their default values (duh). + Assert.assertEquals( 41 , message.getDefaultInt32 ()); + Assert.assertEquals( 42 , message.getDefaultInt64 ()); + Assert.assertEquals( 43 , message.getDefaultUint32 ()); + Assert.assertEquals( 44 , message.getDefaultUint64 ()); + Assert.assertEquals(-45 , message.getDefaultSint32 ()); + Assert.assertEquals( 46 , message.getDefaultSint64 ()); + Assert.assertEquals( 47 , message.getDefaultFixed32 ()); + Assert.assertEquals( 48 , message.getDefaultFixed64 ()); + Assert.assertEquals( 49 , message.getDefaultSfixed32()); + Assert.assertEquals(-50 , message.getDefaultSfixed64()); + Assert.assertEquals( 51.5 , message.getDefaultFloat (), 0.0); + Assert.assertEquals( 52e3 , message.getDefaultDouble (), 0.0); + Assert.assertEquals(true , message.getDefaultBool ()); + Assert.assertEquals("hello", message.getDefaultString ()); + Assert.assertEquals(toBytes("world"), message.getDefaultBytes()); + + Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getDefaultNestedEnum ()); + Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getDefaultForeignEnum()); + Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getDefaultImportEnum()); + + Assert.assertEquals("abc", message.getDefaultStringPiece()); + Assert.assertEquals("123", message.getDefaultCord()); + } + + // ------------------------------------------------------------------- + + /** + * Assert (using {@code junit.framework.Assert}} that all fields of + * {@code message} are set to the values assigned by {@code setAllFields} + * followed by {@code modifyRepeatedFields}. + */ + public static void assertRepeatedFieldsModified( + TestAllTypesOrBuilder message) { + // ModifyRepeatedFields only sets the second repeated element of each + // field. In addition to verifying this, we also verify that the first + // element and size were *not* modified. + Assert.assertEquals(2, message.getRepeatedInt32Count ()); + Assert.assertEquals(2, message.getRepeatedInt64Count ()); + Assert.assertEquals(2, message.getRepeatedUint32Count ()); + Assert.assertEquals(2, message.getRepeatedUint64Count ()); + Assert.assertEquals(2, message.getRepeatedSint32Count ()); + Assert.assertEquals(2, message.getRepeatedSint64Count ()); + Assert.assertEquals(2, message.getRepeatedFixed32Count ()); + Assert.assertEquals(2, message.getRepeatedFixed64Count ()); + Assert.assertEquals(2, message.getRepeatedSfixed32Count()); + Assert.assertEquals(2, message.getRepeatedSfixed64Count()); + Assert.assertEquals(2, message.getRepeatedFloatCount ()); + Assert.assertEquals(2, message.getRepeatedDoubleCount ()); + Assert.assertEquals(2, message.getRepeatedBoolCount ()); + Assert.assertEquals(2, message.getRepeatedStringCount ()); + Assert.assertEquals(2, message.getRepeatedBytesCount ()); + + Assert.assertEquals(2, message.getRepeatedGroupCount ()); + Assert.assertEquals(2, message.getRepeatedNestedMessageCount ()); + Assert.assertEquals(2, message.getRepeatedForeignMessageCount()); + Assert.assertEquals(2, message.getRepeatedImportMessageCount ()); + Assert.assertEquals(2, message.getRepeatedLazyMessageCount ()); + Assert.assertEquals(2, message.getRepeatedNestedEnumCount ()); + Assert.assertEquals(2, message.getRepeatedForeignEnumCount ()); + Assert.assertEquals(2, message.getRepeatedImportEnumCount ()); + + Assert.assertEquals(2, message.getRepeatedStringPieceCount()); + Assert.assertEquals(2, message.getRepeatedCordCount()); + + Assert.assertEquals(201 , message.getRepeatedInt32 (0)); + Assert.assertEquals(202L , message.getRepeatedInt64 (0)); + Assert.assertEquals(203 , message.getRepeatedUint32 (0)); + Assert.assertEquals(204L , message.getRepeatedUint64 (0)); + Assert.assertEquals(205 , message.getRepeatedSint32 (0)); + Assert.assertEquals(206L , message.getRepeatedSint64 (0)); + Assert.assertEquals(207 , message.getRepeatedFixed32 (0)); + Assert.assertEquals(208L , message.getRepeatedFixed64 (0)); + Assert.assertEquals(209 , message.getRepeatedSfixed32(0)); + Assert.assertEquals(210L , message.getRepeatedSfixed64(0)); + Assert.assertEquals(211F , message.getRepeatedFloat (0)); + Assert.assertEquals(212D , message.getRepeatedDouble (0)); + Assert.assertEquals(true , message.getRepeatedBool (0)); + Assert.assertEquals("215", message.getRepeatedString (0)); + Assert.assertEquals(toBytes("216"), message.getRepeatedBytes(0)); + + Assert.assertEquals(217, message.getRepeatedGroup (0).getA()); + Assert.assertEquals(218, message.getRepeatedNestedMessage (0).getBb()); + Assert.assertEquals(219, message.getRepeatedForeignMessage(0).getC()); + Assert.assertEquals(220, message.getRepeatedImportMessage (0).getD()); + Assert.assertEquals(227, message.getRepeatedLazyMessage (0).getBb()); + + Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnum (0)); + Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnum(0)); + Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnum(0)); + + Assert.assertEquals("224", message.getRepeatedStringPiece(0)); + Assert.assertEquals("225", message.getRepeatedCord(0)); + + // Actually verify the second (modified) elements now. + Assert.assertEquals(501 , message.getRepeatedInt32 (1)); + Assert.assertEquals(502L , message.getRepeatedInt64 (1)); + Assert.assertEquals(503 , message.getRepeatedUint32 (1)); + Assert.assertEquals(504L , message.getRepeatedUint64 (1)); + Assert.assertEquals(505 , message.getRepeatedSint32 (1)); + Assert.assertEquals(506L , message.getRepeatedSint64 (1)); + Assert.assertEquals(507 , message.getRepeatedFixed32 (1)); + Assert.assertEquals(508L , message.getRepeatedFixed64 (1)); + Assert.assertEquals(509 , message.getRepeatedSfixed32(1)); + Assert.assertEquals(510L , message.getRepeatedSfixed64(1)); + Assert.assertEquals(511F , message.getRepeatedFloat (1)); + Assert.assertEquals(512D , message.getRepeatedDouble (1)); + Assert.assertEquals(true , message.getRepeatedBool (1)); + Assert.assertEquals("515", message.getRepeatedString (1)); + Assert.assertEquals(toBytes("516"), message.getRepeatedBytes(1)); + + Assert.assertEquals(517, message.getRepeatedGroup (1).getA()); + Assert.assertEquals(518, message.getRepeatedNestedMessage (1).getBb()); + Assert.assertEquals(519, message.getRepeatedForeignMessage(1).getC()); + Assert.assertEquals(520, message.getRepeatedImportMessage (1).getD()); + Assert.assertEquals(527, message.getRepeatedLazyMessage (1).getBb()); + + Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getRepeatedNestedEnum (1)); + Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getRepeatedForeignEnum(1)); + Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getRepeatedImportEnum(1)); + + Assert.assertEquals("524", message.getRepeatedStringPiece(1)); + Assert.assertEquals("525", message.getRepeatedCord(1)); + } + + /** + * Set every field of {@code message} to a unique value. + */ + public static void setPackedFields(TestPackedTypes.Builder message) { + message.addPackedInt32 (601); + message.addPackedInt64 (602); + message.addPackedUint32 (603); + message.addPackedUint64 (604); + message.addPackedSint32 (605); + message.addPackedSint64 (606); + message.addPackedFixed32 (607); + message.addPackedFixed64 (608); + message.addPackedSfixed32(609); + message.addPackedSfixed64(610); + message.addPackedFloat (611); + message.addPackedDouble (612); + message.addPackedBool (true); + message.addPackedEnum (ForeignEnum.FOREIGN_BAR); + // Add a second one of each field. + message.addPackedInt32 (701); + message.addPackedInt64 (702); + message.addPackedUint32 (703); + message.addPackedUint64 (704); + message.addPackedSint32 (705); + message.addPackedSint64 (706); + message.addPackedFixed32 (707); + message.addPackedFixed64 (708); + message.addPackedSfixed32(709); + message.addPackedSfixed64(710); + message.addPackedFloat (711); + message.addPackedDouble (712); + message.addPackedBool (false); + message.addPackedEnum (ForeignEnum.FOREIGN_BAZ); + } + + /** + * Set every field of {@code message} to a unique value. Must correspond with + * the values applied by {@code setPackedFields}. + */ + public static void setUnpackedFields(TestUnpackedTypes.Builder message) { + message.addUnpackedInt32 (601); + message.addUnpackedInt64 (602); + message.addUnpackedUint32 (603); + message.addUnpackedUint64 (604); + message.addUnpackedSint32 (605); + message.addUnpackedSint64 (606); + message.addUnpackedFixed32 (607); + message.addUnpackedFixed64 (608); + message.addUnpackedSfixed32(609); + message.addUnpackedSfixed64(610); + message.addUnpackedFloat (611); + message.addUnpackedDouble (612); + message.addUnpackedBool (true); + message.addUnpackedEnum (ForeignEnum.FOREIGN_BAR); + // Add a second one of each field. + message.addUnpackedInt32 (701); + message.addUnpackedInt64 (702); + message.addUnpackedUint32 (703); + message.addUnpackedUint64 (704); + message.addUnpackedSint32 (705); + message.addUnpackedSint64 (706); + message.addUnpackedFixed32 (707); + message.addUnpackedFixed64 (708); + message.addUnpackedSfixed32(709); + message.addUnpackedSfixed64(710); + message.addUnpackedFloat (711); + message.addUnpackedDouble (712); + message.addUnpackedBool (false); + message.addUnpackedEnum (ForeignEnum.FOREIGN_BAZ); + } + + /** + * Assert (using {@code junit.framework.Assert}} that all fields of + * {@code message} are set to the values assigned by {@code setPackedFields}. + */ + public static void assertPackedFieldsSet(TestPackedTypes message) { + Assert.assertEquals(2, message.getPackedInt32Count ()); + Assert.assertEquals(2, message.getPackedInt64Count ()); + Assert.assertEquals(2, message.getPackedUint32Count ()); + Assert.assertEquals(2, message.getPackedUint64Count ()); + Assert.assertEquals(2, message.getPackedSint32Count ()); + Assert.assertEquals(2, message.getPackedSint64Count ()); + Assert.assertEquals(2, message.getPackedFixed32Count ()); + Assert.assertEquals(2, message.getPackedFixed64Count ()); + Assert.assertEquals(2, message.getPackedSfixed32Count()); + Assert.assertEquals(2, message.getPackedSfixed64Count()); + Assert.assertEquals(2, message.getPackedFloatCount ()); + Assert.assertEquals(2, message.getPackedDoubleCount ()); + Assert.assertEquals(2, message.getPackedBoolCount ()); + Assert.assertEquals(2, message.getPackedEnumCount ()); + Assert.assertEquals(601 , message.getPackedInt32 (0)); + Assert.assertEquals(602 , message.getPackedInt64 (0)); + Assert.assertEquals(603 , message.getPackedUint32 (0)); + Assert.assertEquals(604 , message.getPackedUint64 (0)); + Assert.assertEquals(605 , message.getPackedSint32 (0)); + Assert.assertEquals(606 , message.getPackedSint64 (0)); + Assert.assertEquals(607 , message.getPackedFixed32 (0)); + Assert.assertEquals(608 , message.getPackedFixed64 (0)); + Assert.assertEquals(609 , message.getPackedSfixed32(0)); + Assert.assertEquals(610 , message.getPackedSfixed64(0)); + Assert.assertEquals(611 , message.getPackedFloat (0), 0.0); + Assert.assertEquals(612 , message.getPackedDouble (0), 0.0); + Assert.assertEquals(true , message.getPackedBool (0)); + Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getPackedEnum(0)); + Assert.assertEquals(701 , message.getPackedInt32 (1)); + Assert.assertEquals(702 , message.getPackedInt64 (1)); + Assert.assertEquals(703 , message.getPackedUint32 (1)); + Assert.assertEquals(704 , message.getPackedUint64 (1)); + Assert.assertEquals(705 , message.getPackedSint32 (1)); + Assert.assertEquals(706 , message.getPackedSint64 (1)); + Assert.assertEquals(707 , message.getPackedFixed32 (1)); + Assert.assertEquals(708 , message.getPackedFixed64 (1)); + Assert.assertEquals(709 , message.getPackedSfixed32(1)); + Assert.assertEquals(710 , message.getPackedSfixed64(1)); + Assert.assertEquals(711 , message.getPackedFloat (1), 0.0); + Assert.assertEquals(712 , message.getPackedDouble (1), 0.0); + Assert.assertEquals(false, message.getPackedBool (1)); + Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getPackedEnum(1)); + } + + /** + * Assert (using {@code junit.framework.Assert}} that all fields of + * {@code message} are set to the values assigned by {@code setUnpackedFields}. + */ + public static void assertUnpackedFieldsSet(TestUnpackedTypes message) { + Assert.assertEquals(2, message.getUnpackedInt32Count ()); + Assert.assertEquals(2, message.getUnpackedInt64Count ()); + Assert.assertEquals(2, message.getUnpackedUint32Count ()); + Assert.assertEquals(2, message.getUnpackedUint64Count ()); + Assert.assertEquals(2, message.getUnpackedSint32Count ()); + Assert.assertEquals(2, message.getUnpackedSint64Count ()); + Assert.assertEquals(2, message.getUnpackedFixed32Count ()); + Assert.assertEquals(2, message.getUnpackedFixed64Count ()); + Assert.assertEquals(2, message.getUnpackedSfixed32Count()); + Assert.assertEquals(2, message.getUnpackedSfixed64Count()); + Assert.assertEquals(2, message.getUnpackedFloatCount ()); + Assert.assertEquals(2, message.getUnpackedDoubleCount ()); + Assert.assertEquals(2, message.getUnpackedBoolCount ()); + Assert.assertEquals(2, message.getUnpackedEnumCount ()); + Assert.assertEquals(601 , message.getUnpackedInt32 (0)); + Assert.assertEquals(602 , message.getUnpackedInt64 (0)); + Assert.assertEquals(603 , message.getUnpackedUint32 (0)); + Assert.assertEquals(604 , message.getUnpackedUint64 (0)); + Assert.assertEquals(605 , message.getUnpackedSint32 (0)); + Assert.assertEquals(606 , message.getUnpackedSint64 (0)); + Assert.assertEquals(607 , message.getUnpackedFixed32 (0)); + Assert.assertEquals(608 , message.getUnpackedFixed64 (0)); + Assert.assertEquals(609 , message.getUnpackedSfixed32(0)); + Assert.assertEquals(610 , message.getUnpackedSfixed64(0)); + Assert.assertEquals(611 , message.getUnpackedFloat (0), 0.0); + Assert.assertEquals(612 , message.getUnpackedDouble (0), 0.0); + Assert.assertEquals(true , message.getUnpackedBool (0)); + Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getUnpackedEnum(0)); + Assert.assertEquals(701 , message.getUnpackedInt32 (1)); + Assert.assertEquals(702 , message.getUnpackedInt64 (1)); + Assert.assertEquals(703 , message.getUnpackedUint32 (1)); + Assert.assertEquals(704 , message.getUnpackedUint64 (1)); + Assert.assertEquals(705 , message.getUnpackedSint32 (1)); + Assert.assertEquals(706 , message.getUnpackedSint64 (1)); + Assert.assertEquals(707 , message.getUnpackedFixed32 (1)); + Assert.assertEquals(708 , message.getUnpackedFixed64 (1)); + Assert.assertEquals(709 , message.getUnpackedSfixed32(1)); + Assert.assertEquals(710 , message.getUnpackedSfixed64(1)); + Assert.assertEquals(711 , message.getUnpackedFloat (1), 0.0); + Assert.assertEquals(712 , message.getUnpackedDouble (1), 0.0); + Assert.assertEquals(false, message.getUnpackedBool (1)); + Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getUnpackedEnum(1)); + } + + // =================================================================== + // Like above, but for extensions + + // Java gets confused with things like assertEquals(int, Integer): it can't + // decide whether to call assertEquals(int, int) or assertEquals(Object, + // Object). So we define these methods to help it. + private static void assertEqualsExactType(int a, int b) { + Assert.assertEquals(a, b); + } + private static void assertEqualsExactType(long a, long b) { + Assert.assertEquals(a, b); + } + private static void assertEqualsExactType(float a, float b) { + Assert.assertEquals(a, b, 0.0); + } + private static void assertEqualsExactType(double a, double b) { + Assert.assertEquals(a, b, 0.0); + } + private static void assertEqualsExactType(boolean a, boolean b) { + Assert.assertEquals(a, b); + } + private static void assertEqualsExactType(String a, String b) { + Assert.assertEquals(a, b); + } + private static void assertEqualsExactType(ByteString a, ByteString b) { + Assert.assertEquals(a, b); + } + private static void assertEqualsExactType(TestAllTypes.NestedEnum a, + TestAllTypes.NestedEnum b) { + Assert.assertEquals(a, b); + } + private static void assertEqualsExactType(ForeignEnum a, ForeignEnum b) { + Assert.assertEquals(a, b); + } + private static void assertEqualsExactType(ImportEnum a, ImportEnum b) { + Assert.assertEquals(a, b); + } + private static void assertEqualsExactType(TestAllTypesLite.NestedEnum a, + TestAllTypesLite.NestedEnum b) { + Assert.assertEquals(a, b); + } + private static void assertEqualsExactType(ForeignEnumLite a, + ForeignEnumLite b) { + Assert.assertEquals(a, b); + } + private static void assertEqualsExactType(ImportEnumLite a, + ImportEnumLite b) { + Assert.assertEquals(a, b); + } + + /** + * Get an unmodifiable {@link ExtensionRegistry} containing all the + * extensions of {@code TestAllExtensions}. + */ + public static ExtensionRegistry getExtensionRegistry() { + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + registerAllExtensions(registry); + return registry.getUnmodifiable(); + } + + public static ExtensionRegistryLite getExtensionRegistryLite() { + ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); + registerAllExtensionsLite(registry); + return registry.getUnmodifiable(); + } + + /** + * Register all of {@code TestAllExtensions}'s extensions with the + * given {@link ExtensionRegistry}. + */ + public static void registerAllExtensions(ExtensionRegistry registry) { + UnittestProto.registerAllExtensions(registry); + registerAllExtensionsLite(registry); + } + + public static void registerAllExtensionsLite(ExtensionRegistryLite registry) { + UnittestLite.registerAllExtensions(registry); + } + + /** + * Set every field of {@code message} to the values expected by + * {@code assertAllExtensionsSet()}. + */ + public static void setAllExtensions(TestAllExtensions.Builder message) { + message.setExtension(optionalInt32Extension , 101); + message.setExtension(optionalInt64Extension , 102L); + message.setExtension(optionalUint32Extension , 103); + message.setExtension(optionalUint64Extension , 104L); + message.setExtension(optionalSint32Extension , 105); + message.setExtension(optionalSint64Extension , 106L); + message.setExtension(optionalFixed32Extension , 107); + message.setExtension(optionalFixed64Extension , 108L); + message.setExtension(optionalSfixed32Extension, 109); + message.setExtension(optionalSfixed64Extension, 110L); + message.setExtension(optionalFloatExtension , 111F); + message.setExtension(optionalDoubleExtension , 112D); + message.setExtension(optionalBoolExtension , true); + message.setExtension(optionalStringExtension , "115"); + message.setExtension(optionalBytesExtension , toBytes("116")); + + message.setExtension(optionalGroupExtension, + OptionalGroup_extension.newBuilder().setA(117).build()); + message.setExtension(optionalNestedMessageExtension, + TestAllTypes.NestedMessage.newBuilder().setBb(118).build()); + message.setExtension(optionalForeignMessageExtension, + ForeignMessage.newBuilder().setC(119).build()); + message.setExtension(optionalImportMessageExtension, + ImportMessage.newBuilder().setD(120).build()); + message.setExtension(optionalPublicImportMessageExtension, + PublicImportMessage.newBuilder().setE(126).build()); + message.setExtension(optionalLazyMessageExtension, + TestAllTypes.NestedMessage.newBuilder().setBb(127).build()); + + message.setExtension(optionalNestedEnumExtension, TestAllTypes.NestedEnum.BAZ); + message.setExtension(optionalForeignEnumExtension, ForeignEnum.FOREIGN_BAZ); + message.setExtension(optionalImportEnumExtension, ImportEnum.IMPORT_BAZ); + + message.setExtension(optionalStringPieceExtension, "124"); + message.setExtension(optionalCordExtension, "125"); + + // ----------------------------------------------------------------- + + message.addExtension(repeatedInt32Extension , 201); + message.addExtension(repeatedInt64Extension , 202L); + message.addExtension(repeatedUint32Extension , 203); + message.addExtension(repeatedUint64Extension , 204L); + message.addExtension(repeatedSint32Extension , 205); + message.addExtension(repeatedSint64Extension , 206L); + message.addExtension(repeatedFixed32Extension , 207); + message.addExtension(repeatedFixed64Extension , 208L); + message.addExtension(repeatedSfixed32Extension, 209); + message.addExtension(repeatedSfixed64Extension, 210L); + message.addExtension(repeatedFloatExtension , 211F); + message.addExtension(repeatedDoubleExtension , 212D); + message.addExtension(repeatedBoolExtension , true); + message.addExtension(repeatedStringExtension , "215"); + message.addExtension(repeatedBytesExtension , toBytes("216")); + + message.addExtension(repeatedGroupExtension, + RepeatedGroup_extension.newBuilder().setA(217).build()); + message.addExtension(repeatedNestedMessageExtension, + TestAllTypes.NestedMessage.newBuilder().setBb(218).build()); + message.addExtension(repeatedForeignMessageExtension, + ForeignMessage.newBuilder().setC(219).build()); + message.addExtension(repeatedImportMessageExtension, + ImportMessage.newBuilder().setD(220).build()); + message.addExtension(repeatedLazyMessageExtension, + TestAllTypes.NestedMessage.newBuilder().setBb(227).build()); + + message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAR); + message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAR); + message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAR); + + message.addExtension(repeatedStringPieceExtension, "224"); + message.addExtension(repeatedCordExtension, "225"); + + // Add a second one of each field. + message.addExtension(repeatedInt32Extension , 301); + message.addExtension(repeatedInt64Extension , 302L); + message.addExtension(repeatedUint32Extension , 303); + message.addExtension(repeatedUint64Extension , 304L); + message.addExtension(repeatedSint32Extension , 305); + message.addExtension(repeatedSint64Extension , 306L); + message.addExtension(repeatedFixed32Extension , 307); + message.addExtension(repeatedFixed64Extension , 308L); + message.addExtension(repeatedSfixed32Extension, 309); + message.addExtension(repeatedSfixed64Extension, 310L); + message.addExtension(repeatedFloatExtension , 311F); + message.addExtension(repeatedDoubleExtension , 312D); + message.addExtension(repeatedBoolExtension , false); + message.addExtension(repeatedStringExtension , "315"); + message.addExtension(repeatedBytesExtension , toBytes("316")); + + message.addExtension(repeatedGroupExtension, + RepeatedGroup_extension.newBuilder().setA(317).build()); + message.addExtension(repeatedNestedMessageExtension, + TestAllTypes.NestedMessage.newBuilder().setBb(318).build()); + message.addExtension(repeatedForeignMessageExtension, + ForeignMessage.newBuilder().setC(319).build()); + message.addExtension(repeatedImportMessageExtension, + ImportMessage.newBuilder().setD(320).build()); + message.addExtension(repeatedLazyMessageExtension, + TestAllTypes.NestedMessage.newBuilder().setBb(327).build()); + + message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAZ); + message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAZ); + message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAZ); + + message.addExtension(repeatedStringPieceExtension, "324"); + message.addExtension(repeatedCordExtension, "325"); + + // ----------------------------------------------------------------- + + message.setExtension(defaultInt32Extension , 401); + message.setExtension(defaultInt64Extension , 402L); + message.setExtension(defaultUint32Extension , 403); + message.setExtension(defaultUint64Extension , 404L); + message.setExtension(defaultSint32Extension , 405); + message.setExtension(defaultSint64Extension , 406L); + message.setExtension(defaultFixed32Extension , 407); + message.setExtension(defaultFixed64Extension , 408L); + message.setExtension(defaultSfixed32Extension, 409); + message.setExtension(defaultSfixed64Extension, 410L); + message.setExtension(defaultFloatExtension , 411F); + message.setExtension(defaultDoubleExtension , 412D); + message.setExtension(defaultBoolExtension , false); + message.setExtension(defaultStringExtension , "415"); + message.setExtension(defaultBytesExtension , toBytes("416")); + + message.setExtension(defaultNestedEnumExtension, TestAllTypes.NestedEnum.FOO); + message.setExtension(defaultForeignEnumExtension, ForeignEnum.FOREIGN_FOO); + message.setExtension(defaultImportEnumExtension, ImportEnum.IMPORT_FOO); + + message.setExtension(defaultStringPieceExtension, "424"); + message.setExtension(defaultCordExtension, "425"); + } + + // ------------------------------------------------------------------- + + /** + * Modify the repeated extensions of {@code message} to contain the values + * expected by {@code assertRepeatedExtensionsModified()}. + */ + public static void modifyRepeatedExtensions( + TestAllExtensions.Builder message) { + message.setExtension(repeatedInt32Extension , 1, 501); + message.setExtension(repeatedInt64Extension , 1, 502L); + message.setExtension(repeatedUint32Extension , 1, 503); + message.setExtension(repeatedUint64Extension , 1, 504L); + message.setExtension(repeatedSint32Extension , 1, 505); + message.setExtension(repeatedSint64Extension , 1, 506L); + message.setExtension(repeatedFixed32Extension , 1, 507); + message.setExtension(repeatedFixed64Extension , 1, 508L); + message.setExtension(repeatedSfixed32Extension, 1, 509); + message.setExtension(repeatedSfixed64Extension, 1, 510L); + message.setExtension(repeatedFloatExtension , 1, 511F); + message.setExtension(repeatedDoubleExtension , 1, 512D); + message.setExtension(repeatedBoolExtension , 1, true); + message.setExtension(repeatedStringExtension , 1, "515"); + message.setExtension(repeatedBytesExtension , 1, toBytes("516")); + + message.setExtension(repeatedGroupExtension, 1, + RepeatedGroup_extension.newBuilder().setA(517).build()); + message.setExtension(repeatedNestedMessageExtension, 1, + TestAllTypes.NestedMessage.newBuilder().setBb(518).build()); + message.setExtension(repeatedForeignMessageExtension, 1, + ForeignMessage.newBuilder().setC(519).build()); + message.setExtension(repeatedImportMessageExtension, 1, + ImportMessage.newBuilder().setD(520).build()); + message.setExtension(repeatedLazyMessageExtension, 1, + TestAllTypes.NestedMessage.newBuilder().setBb(527).build()); + + message.setExtension(repeatedNestedEnumExtension , 1, TestAllTypes.NestedEnum.FOO); + message.setExtension(repeatedForeignEnumExtension, 1, ForeignEnum.FOREIGN_FOO); + message.setExtension(repeatedImportEnumExtension , 1, ImportEnum.IMPORT_FOO); + + message.setExtension(repeatedStringPieceExtension, 1, "524"); + message.setExtension(repeatedCordExtension, 1, "525"); + } + + // ------------------------------------------------------------------- + + /** + * Assert (using {@code junit.framework.Assert}} that all extensions of + * {@code message} are set to the values assigned by {@code setAllExtensions}. + */ + public static void assertAllExtensionsSet( + TestAllExtensionsOrBuilder message) { + Assert.assertTrue(message.hasExtension(optionalInt32Extension )); + Assert.assertTrue(message.hasExtension(optionalInt64Extension )); + Assert.assertTrue(message.hasExtension(optionalUint32Extension )); + Assert.assertTrue(message.hasExtension(optionalUint64Extension )); + Assert.assertTrue(message.hasExtension(optionalSint32Extension )); + Assert.assertTrue(message.hasExtension(optionalSint64Extension )); + Assert.assertTrue(message.hasExtension(optionalFixed32Extension )); + Assert.assertTrue(message.hasExtension(optionalFixed64Extension )); + Assert.assertTrue(message.hasExtension(optionalSfixed32Extension)); + Assert.assertTrue(message.hasExtension(optionalSfixed64Extension)); + Assert.assertTrue(message.hasExtension(optionalFloatExtension )); + Assert.assertTrue(message.hasExtension(optionalDoubleExtension )); + Assert.assertTrue(message.hasExtension(optionalBoolExtension )); + Assert.assertTrue(message.hasExtension(optionalStringExtension )); + Assert.assertTrue(message.hasExtension(optionalBytesExtension )); + + Assert.assertTrue(message.hasExtension(optionalGroupExtension )); + Assert.assertTrue(message.hasExtension(optionalNestedMessageExtension )); + Assert.assertTrue(message.hasExtension(optionalForeignMessageExtension)); + Assert.assertTrue(message.hasExtension(optionalImportMessageExtension )); + + Assert.assertTrue(message.getExtension(optionalGroupExtension ).hasA()); + Assert.assertTrue(message.getExtension(optionalNestedMessageExtension ).hasBb()); + Assert.assertTrue(message.getExtension(optionalForeignMessageExtension).hasC()); + Assert.assertTrue(message.getExtension(optionalImportMessageExtension ).hasD()); + + Assert.assertTrue(message.hasExtension(optionalNestedEnumExtension )); + Assert.assertTrue(message.hasExtension(optionalForeignEnumExtension)); + Assert.assertTrue(message.hasExtension(optionalImportEnumExtension )); + + Assert.assertTrue(message.hasExtension(optionalStringPieceExtension)); + Assert.assertTrue(message.hasExtension(optionalCordExtension)); + + assertEqualsExactType(101 , message.getExtension(optionalInt32Extension )); + assertEqualsExactType(102L , message.getExtension(optionalInt64Extension )); + assertEqualsExactType(103 , message.getExtension(optionalUint32Extension )); + assertEqualsExactType(104L , message.getExtension(optionalUint64Extension )); + assertEqualsExactType(105 , message.getExtension(optionalSint32Extension )); + assertEqualsExactType(106L , message.getExtension(optionalSint64Extension )); + assertEqualsExactType(107 , message.getExtension(optionalFixed32Extension )); + assertEqualsExactType(108L , message.getExtension(optionalFixed64Extension )); + assertEqualsExactType(109 , message.getExtension(optionalSfixed32Extension)); + assertEqualsExactType(110L , message.getExtension(optionalSfixed64Extension)); + assertEqualsExactType(111F , message.getExtension(optionalFloatExtension )); + assertEqualsExactType(112D , message.getExtension(optionalDoubleExtension )); + assertEqualsExactType(true , message.getExtension(optionalBoolExtension )); + assertEqualsExactType("115", message.getExtension(optionalStringExtension )); + assertEqualsExactType(toBytes("116"), message.getExtension(optionalBytesExtension)); + + assertEqualsExactType(117, message.getExtension(optionalGroupExtension ).getA()); + assertEqualsExactType(118, message.getExtension(optionalNestedMessageExtension ).getBb()); + assertEqualsExactType(119, message.getExtension(optionalForeignMessageExtension ).getC()); + assertEqualsExactType(120, message.getExtension(optionalImportMessageExtension ).getD()); + assertEqualsExactType(126, message.getExtension(optionalPublicImportMessageExtension).getE()); + assertEqualsExactType(127, message.getExtension(optionalLazyMessageExtension ).getBb()); + + assertEqualsExactType(TestAllTypes.NestedEnum.BAZ, + message.getExtension(optionalNestedEnumExtension)); + assertEqualsExactType(ForeignEnum.FOREIGN_BAZ, + message.getExtension(optionalForeignEnumExtension)); + assertEqualsExactType(ImportEnum.IMPORT_BAZ, + message.getExtension(optionalImportEnumExtension)); + + assertEqualsExactType("124", message.getExtension(optionalStringPieceExtension)); + assertEqualsExactType("125", message.getExtension(optionalCordExtension)); + + // ----------------------------------------------------------------- + + Assert.assertEquals(2, message.getExtensionCount(repeatedInt32Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension)); + Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension)); + Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension )); + + Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension)); + Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension )); + + Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension)); + Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension)); + + assertEqualsExactType(201 , message.getExtension(repeatedInt32Extension , 0)); + assertEqualsExactType(202L , message.getExtension(repeatedInt64Extension , 0)); + assertEqualsExactType(203 , message.getExtension(repeatedUint32Extension , 0)); + assertEqualsExactType(204L , message.getExtension(repeatedUint64Extension , 0)); + assertEqualsExactType(205 , message.getExtension(repeatedSint32Extension , 0)); + assertEqualsExactType(206L , message.getExtension(repeatedSint64Extension , 0)); + assertEqualsExactType(207 , message.getExtension(repeatedFixed32Extension , 0)); + assertEqualsExactType(208L , message.getExtension(repeatedFixed64Extension , 0)); + assertEqualsExactType(209 , message.getExtension(repeatedSfixed32Extension, 0)); + assertEqualsExactType(210L , message.getExtension(repeatedSfixed64Extension, 0)); + assertEqualsExactType(211F , message.getExtension(repeatedFloatExtension , 0)); + assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtension , 0)); + assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 0)); + assertEqualsExactType("215", message.getExtension(repeatedStringExtension , 0)); + assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0)); + + assertEqualsExactType(217, message.getExtension(repeatedGroupExtension , 0).getA()); + assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension , 0).getBb()); + assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC()); + assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension , 0).getD()); + assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtension , 0).getBb()); + + assertEqualsExactType(TestAllTypes.NestedEnum.BAR, + message.getExtension(repeatedNestedEnumExtension, 0)); + assertEqualsExactType(ForeignEnum.FOREIGN_BAR, + message.getExtension(repeatedForeignEnumExtension, 0)); + assertEqualsExactType(ImportEnum.IMPORT_BAR, + message.getExtension(repeatedImportEnumExtension, 0)); + + assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0)); + assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0)); + + assertEqualsExactType(301 , message.getExtension(repeatedInt32Extension , 1)); + assertEqualsExactType(302L , message.getExtension(repeatedInt64Extension , 1)); + assertEqualsExactType(303 , message.getExtension(repeatedUint32Extension , 1)); + assertEqualsExactType(304L , message.getExtension(repeatedUint64Extension , 1)); + assertEqualsExactType(305 , message.getExtension(repeatedSint32Extension , 1)); + assertEqualsExactType(306L , message.getExtension(repeatedSint64Extension , 1)); + assertEqualsExactType(307 , message.getExtension(repeatedFixed32Extension , 1)); + assertEqualsExactType(308L , message.getExtension(repeatedFixed64Extension , 1)); + assertEqualsExactType(309 , message.getExtension(repeatedSfixed32Extension, 1)); + assertEqualsExactType(310L , message.getExtension(repeatedSfixed64Extension, 1)); + assertEqualsExactType(311F , message.getExtension(repeatedFloatExtension , 1)); + assertEqualsExactType(312D , message.getExtension(repeatedDoubleExtension , 1)); + assertEqualsExactType(false, message.getExtension(repeatedBoolExtension , 1)); + assertEqualsExactType("315", message.getExtension(repeatedStringExtension , 1)); + assertEqualsExactType(toBytes("316"), message.getExtension(repeatedBytesExtension, 1)); + + assertEqualsExactType(317, message.getExtension(repeatedGroupExtension , 1).getA()); + assertEqualsExactType(318, message.getExtension(repeatedNestedMessageExtension , 1).getBb()); + assertEqualsExactType(319, message.getExtension(repeatedForeignMessageExtension, 1).getC()); + assertEqualsExactType(320, message.getExtension(repeatedImportMessageExtension , 1).getD()); + assertEqualsExactType(327, message.getExtension(repeatedLazyMessageExtension , 1).getBb()); + + assertEqualsExactType(TestAllTypes.NestedEnum.BAZ, + message.getExtension(repeatedNestedEnumExtension, 1)); + assertEqualsExactType(ForeignEnum.FOREIGN_BAZ, + message.getExtension(repeatedForeignEnumExtension, 1)); + assertEqualsExactType(ImportEnum.IMPORT_BAZ, + message.getExtension(repeatedImportEnumExtension, 1)); + + assertEqualsExactType("324", message.getExtension(repeatedStringPieceExtension, 1)); + assertEqualsExactType("325", message.getExtension(repeatedCordExtension, 1)); + + // ----------------------------------------------------------------- + + Assert.assertTrue(message.hasExtension(defaultInt32Extension )); + Assert.assertTrue(message.hasExtension(defaultInt64Extension )); + Assert.assertTrue(message.hasExtension(defaultUint32Extension )); + Assert.assertTrue(message.hasExtension(defaultUint64Extension )); + Assert.assertTrue(message.hasExtension(defaultSint32Extension )); + Assert.assertTrue(message.hasExtension(defaultSint64Extension )); + Assert.assertTrue(message.hasExtension(defaultFixed32Extension )); + Assert.assertTrue(message.hasExtension(defaultFixed64Extension )); + Assert.assertTrue(message.hasExtension(defaultSfixed32Extension)); + Assert.assertTrue(message.hasExtension(defaultSfixed64Extension)); + Assert.assertTrue(message.hasExtension(defaultFloatExtension )); + Assert.assertTrue(message.hasExtension(defaultDoubleExtension )); + Assert.assertTrue(message.hasExtension(defaultBoolExtension )); + Assert.assertTrue(message.hasExtension(defaultStringExtension )); + Assert.assertTrue(message.hasExtension(defaultBytesExtension )); + + Assert.assertTrue(message.hasExtension(defaultNestedEnumExtension )); + Assert.assertTrue(message.hasExtension(defaultForeignEnumExtension)); + Assert.assertTrue(message.hasExtension(defaultImportEnumExtension )); + + Assert.assertTrue(message.hasExtension(defaultStringPieceExtension)); + Assert.assertTrue(message.hasExtension(defaultCordExtension)); + + assertEqualsExactType(401 , message.getExtension(defaultInt32Extension )); + assertEqualsExactType(402L , message.getExtension(defaultInt64Extension )); + assertEqualsExactType(403 , message.getExtension(defaultUint32Extension )); + assertEqualsExactType(404L , message.getExtension(defaultUint64Extension )); + assertEqualsExactType(405 , message.getExtension(defaultSint32Extension )); + assertEqualsExactType(406L , message.getExtension(defaultSint64Extension )); + assertEqualsExactType(407 , message.getExtension(defaultFixed32Extension )); + assertEqualsExactType(408L , message.getExtension(defaultFixed64Extension )); + assertEqualsExactType(409 , message.getExtension(defaultSfixed32Extension)); + assertEqualsExactType(410L , message.getExtension(defaultSfixed64Extension)); + assertEqualsExactType(411F , message.getExtension(defaultFloatExtension )); + assertEqualsExactType(412D , message.getExtension(defaultDoubleExtension )); + assertEqualsExactType(false, message.getExtension(defaultBoolExtension )); + assertEqualsExactType("415", message.getExtension(defaultStringExtension )); + assertEqualsExactType(toBytes("416"), message.getExtension(defaultBytesExtension)); + + assertEqualsExactType(TestAllTypes.NestedEnum.FOO, + message.getExtension(defaultNestedEnumExtension )); + assertEqualsExactType(ForeignEnum.FOREIGN_FOO, + message.getExtension(defaultForeignEnumExtension)); + assertEqualsExactType(ImportEnum.IMPORT_FOO, + message.getExtension(defaultImportEnumExtension)); + + assertEqualsExactType("424", message.getExtension(defaultStringPieceExtension)); + assertEqualsExactType("425", message.getExtension(defaultCordExtension)); + } + + // ------------------------------------------------------------------- + + /** + * Assert (using {@code junit.framework.Assert}} that all extensions of + * {@code message} are cleared, and that getting the extensions returns their + * default values. + */ + public static void assertExtensionsClear(TestAllExtensionsOrBuilder message) { + // hasBlah() should initially be false for all optional fields. + Assert.assertFalse(message.hasExtension(optionalInt32Extension )); + Assert.assertFalse(message.hasExtension(optionalInt64Extension )); + Assert.assertFalse(message.hasExtension(optionalUint32Extension )); + Assert.assertFalse(message.hasExtension(optionalUint64Extension )); + Assert.assertFalse(message.hasExtension(optionalSint32Extension )); + Assert.assertFalse(message.hasExtension(optionalSint64Extension )); + Assert.assertFalse(message.hasExtension(optionalFixed32Extension )); + Assert.assertFalse(message.hasExtension(optionalFixed64Extension )); + Assert.assertFalse(message.hasExtension(optionalSfixed32Extension)); + Assert.assertFalse(message.hasExtension(optionalSfixed64Extension)); + Assert.assertFalse(message.hasExtension(optionalFloatExtension )); + Assert.assertFalse(message.hasExtension(optionalDoubleExtension )); + Assert.assertFalse(message.hasExtension(optionalBoolExtension )); + Assert.assertFalse(message.hasExtension(optionalStringExtension )); + Assert.assertFalse(message.hasExtension(optionalBytesExtension )); + + Assert.assertFalse(message.hasExtension(optionalGroupExtension )); + Assert.assertFalse(message.hasExtension(optionalNestedMessageExtension )); + Assert.assertFalse(message.hasExtension(optionalForeignMessageExtension)); + Assert.assertFalse(message.hasExtension(optionalImportMessageExtension )); + + Assert.assertFalse(message.hasExtension(optionalNestedEnumExtension )); + Assert.assertFalse(message.hasExtension(optionalForeignEnumExtension)); + Assert.assertFalse(message.hasExtension(optionalImportEnumExtension )); + + Assert.assertFalse(message.hasExtension(optionalStringPieceExtension)); + Assert.assertFalse(message.hasExtension(optionalCordExtension)); + + // Optional fields without defaults are set to zero or something like it. + assertEqualsExactType(0 , message.getExtension(optionalInt32Extension )); + assertEqualsExactType(0L , message.getExtension(optionalInt64Extension )); + assertEqualsExactType(0 , message.getExtension(optionalUint32Extension )); + assertEqualsExactType(0L , message.getExtension(optionalUint64Extension )); + assertEqualsExactType(0 , message.getExtension(optionalSint32Extension )); + assertEqualsExactType(0L , message.getExtension(optionalSint64Extension )); + assertEqualsExactType(0 , message.getExtension(optionalFixed32Extension )); + assertEqualsExactType(0L , message.getExtension(optionalFixed64Extension )); + assertEqualsExactType(0 , message.getExtension(optionalSfixed32Extension)); + assertEqualsExactType(0L , message.getExtension(optionalSfixed64Extension)); + assertEqualsExactType(0F , message.getExtension(optionalFloatExtension )); + assertEqualsExactType(0D , message.getExtension(optionalDoubleExtension )); + assertEqualsExactType(false, message.getExtension(optionalBoolExtension )); + assertEqualsExactType("" , message.getExtension(optionalStringExtension )); + assertEqualsExactType(ByteString.EMPTY, message.getExtension(optionalBytesExtension)); + + // Embedded messages should also be clear. + Assert.assertFalse(message.getExtension(optionalGroupExtension ).hasA()); + Assert.assertFalse(message.getExtension(optionalNestedMessageExtension ).hasBb()); + Assert.assertFalse(message.getExtension(optionalForeignMessageExtension).hasC()); + Assert.assertFalse(message.getExtension(optionalImportMessageExtension ).hasD()); + + assertEqualsExactType(0, message.getExtension(optionalGroupExtension ).getA()); + assertEqualsExactType(0, message.getExtension(optionalNestedMessageExtension ).getBb()); + assertEqualsExactType(0, message.getExtension(optionalForeignMessageExtension).getC()); + assertEqualsExactType(0, message.getExtension(optionalImportMessageExtension ).getD()); + + // Enums without defaults are set to the first value in the enum. + assertEqualsExactType(TestAllTypes.NestedEnum.FOO, + message.getExtension(optionalNestedEnumExtension )); + assertEqualsExactType(ForeignEnum.FOREIGN_FOO, + message.getExtension(optionalForeignEnumExtension)); + assertEqualsExactType(ImportEnum.IMPORT_FOO, + message.getExtension(optionalImportEnumExtension)); + + assertEqualsExactType("", message.getExtension(optionalStringPieceExtension)); + assertEqualsExactType("", message.getExtension(optionalCordExtension)); + + // Repeated fields are empty. + Assert.assertEquals(0, message.getExtensionCount(repeatedInt32Extension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedInt64Extension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedUint32Extension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedUint64Extension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedSint32Extension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedSint64Extension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedFixed32Extension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedFixed64Extension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed32Extension)); + Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed64Extension)); + Assert.assertEquals(0, message.getExtensionCount(repeatedFloatExtension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedDoubleExtension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedBoolExtension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedStringExtension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedBytesExtension )); + + Assert.assertEquals(0, message.getExtensionCount(repeatedGroupExtension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedNestedMessageExtension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedForeignMessageExtension)); + Assert.assertEquals(0, message.getExtensionCount(repeatedImportMessageExtension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedLazyMessageExtension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedNestedEnumExtension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedForeignEnumExtension )); + Assert.assertEquals(0, message.getExtensionCount(repeatedImportEnumExtension )); + + Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtension)); + Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtension)); + + // Repeated fields are empty via getExtension().size(). + Assert.assertEquals(0, message.getExtension(repeatedInt32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedInt64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedUint32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedUint64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedSint32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedSint64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedFixed32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedFixed64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedSfixed32Extension).size()); + Assert.assertEquals(0, message.getExtension(repeatedSfixed64Extension).size()); + Assert.assertEquals(0, message.getExtension(repeatedFloatExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedDoubleExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedBoolExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedStringExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedBytesExtension ).size()); + + Assert.assertEquals(0, message.getExtension(repeatedGroupExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedNestedMessageExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedForeignMessageExtension).size()); + Assert.assertEquals(0, message.getExtension(repeatedImportMessageExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedLazyMessageExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedNestedEnumExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedForeignEnumExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedImportEnumExtension ).size()); + + Assert.assertEquals(0, message.getExtension(repeatedStringPieceExtension).size()); + Assert.assertEquals(0, message.getExtension(repeatedCordExtension).size()); + + // hasBlah() should also be false for all default fields. + Assert.assertFalse(message.hasExtension(defaultInt32Extension )); + Assert.assertFalse(message.hasExtension(defaultInt64Extension )); + Assert.assertFalse(message.hasExtension(defaultUint32Extension )); + Assert.assertFalse(message.hasExtension(defaultUint64Extension )); + Assert.assertFalse(message.hasExtension(defaultSint32Extension )); + Assert.assertFalse(message.hasExtension(defaultSint64Extension )); + Assert.assertFalse(message.hasExtension(defaultFixed32Extension )); + Assert.assertFalse(message.hasExtension(defaultFixed64Extension )); + Assert.assertFalse(message.hasExtension(defaultSfixed32Extension)); + Assert.assertFalse(message.hasExtension(defaultSfixed64Extension)); + Assert.assertFalse(message.hasExtension(defaultFloatExtension )); + Assert.assertFalse(message.hasExtension(defaultDoubleExtension )); + Assert.assertFalse(message.hasExtension(defaultBoolExtension )); + Assert.assertFalse(message.hasExtension(defaultStringExtension )); + Assert.assertFalse(message.hasExtension(defaultBytesExtension )); + + Assert.assertFalse(message.hasExtension(defaultNestedEnumExtension )); + Assert.assertFalse(message.hasExtension(defaultForeignEnumExtension)); + Assert.assertFalse(message.hasExtension(defaultImportEnumExtension )); + + Assert.assertFalse(message.hasExtension(defaultStringPieceExtension)); + Assert.assertFalse(message.hasExtension(defaultCordExtension)); + + // Fields with defaults have their default values (duh). + assertEqualsExactType( 41 , message.getExtension(defaultInt32Extension )); + assertEqualsExactType( 42L , message.getExtension(defaultInt64Extension )); + assertEqualsExactType( 43 , message.getExtension(defaultUint32Extension )); + assertEqualsExactType( 44L , message.getExtension(defaultUint64Extension )); + assertEqualsExactType(-45 , message.getExtension(defaultSint32Extension )); + assertEqualsExactType( 46L , message.getExtension(defaultSint64Extension )); + assertEqualsExactType( 47 , message.getExtension(defaultFixed32Extension )); + assertEqualsExactType( 48L , message.getExtension(defaultFixed64Extension )); + assertEqualsExactType( 49 , message.getExtension(defaultSfixed32Extension)); + assertEqualsExactType(-50L , message.getExtension(defaultSfixed64Extension)); + assertEqualsExactType( 51.5F , message.getExtension(defaultFloatExtension )); + assertEqualsExactType( 52e3D , message.getExtension(defaultDoubleExtension )); + assertEqualsExactType(true , message.getExtension(defaultBoolExtension )); + assertEqualsExactType("hello", message.getExtension(defaultStringExtension )); + assertEqualsExactType(toBytes("world"), message.getExtension(defaultBytesExtension)); + + assertEqualsExactType(TestAllTypes.NestedEnum.BAR, + message.getExtension(defaultNestedEnumExtension )); + assertEqualsExactType(ForeignEnum.FOREIGN_BAR, + message.getExtension(defaultForeignEnumExtension)); + assertEqualsExactType(ImportEnum.IMPORT_BAR, + message.getExtension(defaultImportEnumExtension)); + + assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtension)); + assertEqualsExactType("123", message.getExtension(defaultCordExtension)); + } + + // ------------------------------------------------------------------- + + /** + * Assert (using {@code junit.framework.Assert}} that all extensions of + * {@code message} are set to the values assigned by {@code setAllExtensions} + * followed by {@code modifyRepeatedExtensions}. + */ + public static void assertRepeatedExtensionsModified( + TestAllExtensionsOrBuilder message) { + // ModifyRepeatedFields only sets the second repeated element of each + // field. In addition to verifying this, we also verify that the first + // element and size were *not* modified. + Assert.assertEquals(2, message.getExtensionCount(repeatedInt32Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension)); + Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension)); + Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension )); + + Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension)); + Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension )); + Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension )); + + Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension)); + Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension)); + + assertEqualsExactType(201 , message.getExtension(repeatedInt32Extension , 0)); + assertEqualsExactType(202L , message.getExtension(repeatedInt64Extension , 0)); + assertEqualsExactType(203 , message.getExtension(repeatedUint32Extension , 0)); + assertEqualsExactType(204L , message.getExtension(repeatedUint64Extension , 0)); + assertEqualsExactType(205 , message.getExtension(repeatedSint32Extension , 0)); + assertEqualsExactType(206L , message.getExtension(repeatedSint64Extension , 0)); + assertEqualsExactType(207 , message.getExtension(repeatedFixed32Extension , 0)); + assertEqualsExactType(208L , message.getExtension(repeatedFixed64Extension , 0)); + assertEqualsExactType(209 , message.getExtension(repeatedSfixed32Extension, 0)); + assertEqualsExactType(210L , message.getExtension(repeatedSfixed64Extension, 0)); + assertEqualsExactType(211F , message.getExtension(repeatedFloatExtension , 0)); + assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtension , 0)); + assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 0)); + assertEqualsExactType("215", message.getExtension(repeatedStringExtension , 0)); + assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0)); + + assertEqualsExactType(217, message.getExtension(repeatedGroupExtension , 0).getA()); + assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension , 0).getBb()); + assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC()); + assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension , 0).getD()); + assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtension , 0).getBb()); + + assertEqualsExactType(TestAllTypes.NestedEnum.BAR, + message.getExtension(repeatedNestedEnumExtension, 0)); + assertEqualsExactType(ForeignEnum.FOREIGN_BAR, + message.getExtension(repeatedForeignEnumExtension, 0)); + assertEqualsExactType(ImportEnum.IMPORT_BAR, + message.getExtension(repeatedImportEnumExtension, 0)); + + assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0)); + assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0)); + + // Actually verify the second (modified) elements now. + assertEqualsExactType(501 , message.getExtension(repeatedInt32Extension , 1)); + assertEqualsExactType(502L , message.getExtension(repeatedInt64Extension , 1)); + assertEqualsExactType(503 , message.getExtension(repeatedUint32Extension , 1)); + assertEqualsExactType(504L , message.getExtension(repeatedUint64Extension , 1)); + assertEqualsExactType(505 , message.getExtension(repeatedSint32Extension , 1)); + assertEqualsExactType(506L , message.getExtension(repeatedSint64Extension , 1)); + assertEqualsExactType(507 , message.getExtension(repeatedFixed32Extension , 1)); + assertEqualsExactType(508L , message.getExtension(repeatedFixed64Extension , 1)); + assertEqualsExactType(509 , message.getExtension(repeatedSfixed32Extension, 1)); + assertEqualsExactType(510L , message.getExtension(repeatedSfixed64Extension, 1)); + assertEqualsExactType(511F , message.getExtension(repeatedFloatExtension , 1)); + assertEqualsExactType(512D , message.getExtension(repeatedDoubleExtension , 1)); + assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 1)); + assertEqualsExactType("515", message.getExtension(repeatedStringExtension , 1)); + assertEqualsExactType(toBytes("516"), message.getExtension(repeatedBytesExtension, 1)); + + assertEqualsExactType(517, message.getExtension(repeatedGroupExtension , 1).getA()); + assertEqualsExactType(518, message.getExtension(repeatedNestedMessageExtension , 1).getBb()); + assertEqualsExactType(519, message.getExtension(repeatedForeignMessageExtension, 1).getC()); + assertEqualsExactType(520, message.getExtension(repeatedImportMessageExtension , 1).getD()); + assertEqualsExactType(527, message.getExtension(repeatedLazyMessageExtension , 1).getBb()); + + assertEqualsExactType(TestAllTypes.NestedEnum.FOO, + message.getExtension(repeatedNestedEnumExtension, 1)); + assertEqualsExactType(ForeignEnum.FOREIGN_FOO, + message.getExtension(repeatedForeignEnumExtension, 1)); + assertEqualsExactType(ImportEnum.IMPORT_FOO, + message.getExtension(repeatedImportEnumExtension, 1)); + + assertEqualsExactType("524", message.getExtension(repeatedStringPieceExtension, 1)); + assertEqualsExactType("525", message.getExtension(repeatedCordExtension, 1)); + } + + public static void setPackedExtensions(TestPackedExtensions.Builder message) { + message.addExtension(packedInt32Extension , 601); + message.addExtension(packedInt64Extension , 602L); + message.addExtension(packedUint32Extension , 603); + message.addExtension(packedUint64Extension , 604L); + message.addExtension(packedSint32Extension , 605); + message.addExtension(packedSint64Extension , 606L); + message.addExtension(packedFixed32Extension , 607); + message.addExtension(packedFixed64Extension , 608L); + message.addExtension(packedSfixed32Extension, 609); + message.addExtension(packedSfixed64Extension, 610L); + message.addExtension(packedFloatExtension , 611F); + message.addExtension(packedDoubleExtension , 612D); + message.addExtension(packedBoolExtension , true); + message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAR); + // Add a second one of each field. + message.addExtension(packedInt32Extension , 701); + message.addExtension(packedInt64Extension , 702L); + message.addExtension(packedUint32Extension , 703); + message.addExtension(packedUint64Extension , 704L); + message.addExtension(packedSint32Extension , 705); + message.addExtension(packedSint64Extension , 706L); + message.addExtension(packedFixed32Extension , 707); + message.addExtension(packedFixed64Extension , 708L); + message.addExtension(packedSfixed32Extension, 709); + message.addExtension(packedSfixed64Extension, 710L); + message.addExtension(packedFloatExtension , 711F); + message.addExtension(packedDoubleExtension , 712D); + message.addExtension(packedBoolExtension , false); + message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAZ); + } + + public static void assertPackedExtensionsSet(TestPackedExtensions message) { + Assert.assertEquals(2, message.getExtensionCount(packedInt32Extension )); + Assert.assertEquals(2, message.getExtensionCount(packedInt64Extension )); + Assert.assertEquals(2, message.getExtensionCount(packedUint32Extension )); + Assert.assertEquals(2, message.getExtensionCount(packedUint64Extension )); + Assert.assertEquals(2, message.getExtensionCount(packedSint32Extension )); + Assert.assertEquals(2, message.getExtensionCount(packedSint64Extension )); + Assert.assertEquals(2, message.getExtensionCount(packedFixed32Extension )); + Assert.assertEquals(2, message.getExtensionCount(packedFixed64Extension )); + Assert.assertEquals(2, message.getExtensionCount(packedSfixed32Extension)); + Assert.assertEquals(2, message.getExtensionCount(packedSfixed64Extension)); + Assert.assertEquals(2, message.getExtensionCount(packedFloatExtension )); + Assert.assertEquals(2, message.getExtensionCount(packedDoubleExtension )); + Assert.assertEquals(2, message.getExtensionCount(packedBoolExtension )); + Assert.assertEquals(2, message.getExtensionCount(packedEnumExtension)); + assertEqualsExactType(601 , message.getExtension(packedInt32Extension , 0)); + assertEqualsExactType(602L , message.getExtension(packedInt64Extension , 0)); + assertEqualsExactType(603 , message.getExtension(packedUint32Extension , 0)); + assertEqualsExactType(604L , message.getExtension(packedUint64Extension , 0)); + assertEqualsExactType(605 , message.getExtension(packedSint32Extension , 0)); + assertEqualsExactType(606L , message.getExtension(packedSint64Extension , 0)); + assertEqualsExactType(607 , message.getExtension(packedFixed32Extension , 0)); + assertEqualsExactType(608L , message.getExtension(packedFixed64Extension , 0)); + assertEqualsExactType(609 , message.getExtension(packedSfixed32Extension, 0)); + assertEqualsExactType(610L , message.getExtension(packedSfixed64Extension, 0)); + assertEqualsExactType(611F , message.getExtension(packedFloatExtension , 0)); + assertEqualsExactType(612D , message.getExtension(packedDoubleExtension , 0)); + assertEqualsExactType(true , message.getExtension(packedBoolExtension , 0)); + assertEqualsExactType(ForeignEnum.FOREIGN_BAR, + message.getExtension(packedEnumExtension, 0)); + assertEqualsExactType(701 , message.getExtension(packedInt32Extension , 1)); + assertEqualsExactType(702L , message.getExtension(packedInt64Extension , 1)); + assertEqualsExactType(703 , message.getExtension(packedUint32Extension , 1)); + assertEqualsExactType(704L , message.getExtension(packedUint64Extension , 1)); + assertEqualsExactType(705 , message.getExtension(packedSint32Extension , 1)); + assertEqualsExactType(706L , message.getExtension(packedSint64Extension , 1)); + assertEqualsExactType(707 , message.getExtension(packedFixed32Extension , 1)); + assertEqualsExactType(708L , message.getExtension(packedFixed64Extension , 1)); + assertEqualsExactType(709 , message.getExtension(packedSfixed32Extension, 1)); + assertEqualsExactType(710L , message.getExtension(packedSfixed64Extension, 1)); + assertEqualsExactType(711F , message.getExtension(packedFloatExtension , 1)); + assertEqualsExactType(712D , message.getExtension(packedDoubleExtension , 1)); + assertEqualsExactType(false, message.getExtension(packedBoolExtension , 1)); + assertEqualsExactType(ForeignEnum.FOREIGN_BAZ, + message.getExtension(packedEnumExtension, 1)); + } + + // =================================================================== + // Lite extensions + + /** + * Set every field of {@code message} to the values expected by + * {@code assertAllExtensionsSet()}. + */ + public static void setAllExtensions(TestAllExtensionsLite.Builder message) { + message.setExtension(optionalInt32ExtensionLite , 101); + message.setExtension(optionalInt64ExtensionLite , 102L); + message.setExtension(optionalUint32ExtensionLite , 103); + message.setExtension(optionalUint64ExtensionLite , 104L); + message.setExtension(optionalSint32ExtensionLite , 105); + message.setExtension(optionalSint64ExtensionLite , 106L); + message.setExtension(optionalFixed32ExtensionLite , 107); + message.setExtension(optionalFixed64ExtensionLite , 108L); + message.setExtension(optionalSfixed32ExtensionLite, 109); + message.setExtension(optionalSfixed64ExtensionLite, 110L); + message.setExtension(optionalFloatExtensionLite , 111F); + message.setExtension(optionalDoubleExtensionLite , 112D); + message.setExtension(optionalBoolExtensionLite , true); + message.setExtension(optionalStringExtensionLite , "115"); + message.setExtension(optionalBytesExtensionLite , toBytes("116")); + + message.setExtension(optionalGroupExtensionLite, + OptionalGroup_extension_lite.newBuilder().setA(117).build()); + message.setExtension(optionalNestedMessageExtensionLite, + TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build()); + message.setExtension(optionalForeignMessageExtensionLite, + ForeignMessageLite.newBuilder().setC(119).build()); + message.setExtension(optionalImportMessageExtensionLite, + ImportMessageLite.newBuilder().setD(120).build()); + message.setExtension(optionalPublicImportMessageExtensionLite, + PublicImportMessageLite.newBuilder().setE(126).build()); + message.setExtension(optionalLazyMessageExtensionLite, + TestAllTypesLite.NestedMessage.newBuilder().setBb(127).build()); + + message.setExtension(optionalNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ); + message.setExtension(optionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ); + message.setExtension(optionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ); + + message.setExtension(optionalStringPieceExtensionLite, "124"); + message.setExtension(optionalCordExtensionLite, "125"); + + // ----------------------------------------------------------------- + + message.addExtension(repeatedInt32ExtensionLite , 201); + message.addExtension(repeatedInt64ExtensionLite , 202L); + message.addExtension(repeatedUint32ExtensionLite , 203); + message.addExtension(repeatedUint64ExtensionLite , 204L); + message.addExtension(repeatedSint32ExtensionLite , 205); + message.addExtension(repeatedSint64ExtensionLite , 206L); + message.addExtension(repeatedFixed32ExtensionLite , 207); + message.addExtension(repeatedFixed64ExtensionLite , 208L); + message.addExtension(repeatedSfixed32ExtensionLite, 209); + message.addExtension(repeatedSfixed64ExtensionLite, 210L); + message.addExtension(repeatedFloatExtensionLite , 211F); + message.addExtension(repeatedDoubleExtensionLite , 212D); + message.addExtension(repeatedBoolExtensionLite , true); + message.addExtension(repeatedStringExtensionLite , "215"); + message.addExtension(repeatedBytesExtensionLite , toBytes("216")); + + message.addExtension(repeatedGroupExtensionLite, + RepeatedGroup_extension_lite.newBuilder().setA(217).build()); + message.addExtension(repeatedNestedMessageExtensionLite, + TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build()); + message.addExtension(repeatedForeignMessageExtensionLite, + ForeignMessageLite.newBuilder().setC(219).build()); + message.addExtension(repeatedImportMessageExtensionLite, + ImportMessageLite.newBuilder().setD(220).build()); + message.addExtension(repeatedLazyMessageExtensionLite, + TestAllTypesLite.NestedMessage.newBuilder().setBb(227).build()); + + message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAR); + message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR); + message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAR); + + message.addExtension(repeatedStringPieceExtensionLite, "224"); + message.addExtension(repeatedCordExtensionLite, "225"); + + // Add a second one of each field. + message.addExtension(repeatedInt32ExtensionLite , 301); + message.addExtension(repeatedInt64ExtensionLite , 302L); + message.addExtension(repeatedUint32ExtensionLite , 303); + message.addExtension(repeatedUint64ExtensionLite , 304L); + message.addExtension(repeatedSint32ExtensionLite , 305); + message.addExtension(repeatedSint64ExtensionLite , 306L); + message.addExtension(repeatedFixed32ExtensionLite , 307); + message.addExtension(repeatedFixed64ExtensionLite , 308L); + message.addExtension(repeatedSfixed32ExtensionLite, 309); + message.addExtension(repeatedSfixed64ExtensionLite, 310L); + message.addExtension(repeatedFloatExtensionLite , 311F); + message.addExtension(repeatedDoubleExtensionLite , 312D); + message.addExtension(repeatedBoolExtensionLite , false); + message.addExtension(repeatedStringExtensionLite , "315"); + message.addExtension(repeatedBytesExtensionLite , toBytes("316")); + + message.addExtension(repeatedGroupExtensionLite, + RepeatedGroup_extension_lite.newBuilder().setA(317).build()); + message.addExtension(repeatedNestedMessageExtensionLite, + TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build()); + message.addExtension(repeatedForeignMessageExtensionLite, + ForeignMessageLite.newBuilder().setC(319).build()); + message.addExtension(repeatedImportMessageExtensionLite, + ImportMessageLite.newBuilder().setD(320).build()); + message.addExtension(repeatedLazyMessageExtensionLite, + TestAllTypesLite.NestedMessage.newBuilder().setBb(327).build()); + + message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ); + message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ); + message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ); + + message.addExtension(repeatedStringPieceExtensionLite, "324"); + message.addExtension(repeatedCordExtensionLite, "325"); + + // ----------------------------------------------------------------- + + message.setExtension(defaultInt32ExtensionLite , 401); + message.setExtension(defaultInt64ExtensionLite , 402L); + message.setExtension(defaultUint32ExtensionLite , 403); + message.setExtension(defaultUint64ExtensionLite , 404L); + message.setExtension(defaultSint32ExtensionLite , 405); + message.setExtension(defaultSint64ExtensionLite , 406L); + message.setExtension(defaultFixed32ExtensionLite , 407); + message.setExtension(defaultFixed64ExtensionLite , 408L); + message.setExtension(defaultSfixed32ExtensionLite, 409); + message.setExtension(defaultSfixed64ExtensionLite, 410L); + message.setExtension(defaultFloatExtensionLite , 411F); + message.setExtension(defaultDoubleExtensionLite , 412D); + message.setExtension(defaultBoolExtensionLite , false); + message.setExtension(defaultStringExtensionLite , "415"); + message.setExtension(defaultBytesExtensionLite , toBytes("416")); + + message.setExtension(defaultNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.FOO); + message.setExtension(defaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_FOO); + message.setExtension(defaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_FOO); + + message.setExtension(defaultStringPieceExtensionLite, "424"); + message.setExtension(defaultCordExtensionLite, "425"); + } + + // ------------------------------------------------------------------- + + /** + * Modify the repeated extensions of {@code message} to contain the values + * expected by {@code assertRepeatedExtensionsModified()}. + */ + public static void modifyRepeatedExtensions( + TestAllExtensionsLite.Builder message) { + message.setExtension(repeatedInt32ExtensionLite , 1, 501); + message.setExtension(repeatedInt64ExtensionLite , 1, 502L); + message.setExtension(repeatedUint32ExtensionLite , 1, 503); + message.setExtension(repeatedUint64ExtensionLite , 1, 504L); + message.setExtension(repeatedSint32ExtensionLite , 1, 505); + message.setExtension(repeatedSint64ExtensionLite , 1, 506L); + message.setExtension(repeatedFixed32ExtensionLite , 1, 507); + message.setExtension(repeatedFixed64ExtensionLite , 1, 508L); + message.setExtension(repeatedSfixed32ExtensionLite, 1, 509); + message.setExtension(repeatedSfixed64ExtensionLite, 1, 510L); + message.setExtension(repeatedFloatExtensionLite , 1, 511F); + message.setExtension(repeatedDoubleExtensionLite , 1, 512D); + message.setExtension(repeatedBoolExtensionLite , 1, true); + message.setExtension(repeatedStringExtensionLite , 1, "515"); + message.setExtension(repeatedBytesExtensionLite , 1, toBytes("516")); + + message.setExtension(repeatedGroupExtensionLite, 1, + RepeatedGroup_extension_lite.newBuilder().setA(517).build()); + message.setExtension(repeatedNestedMessageExtensionLite, 1, + TestAllTypesLite.NestedMessage.newBuilder().setBb(518).build()); + message.setExtension(repeatedForeignMessageExtensionLite, 1, + ForeignMessageLite.newBuilder().setC(519).build()); + message.setExtension(repeatedImportMessageExtensionLite, 1, + ImportMessageLite.newBuilder().setD(520).build()); + message.setExtension(repeatedLazyMessageExtensionLite, 1, + TestAllTypesLite.NestedMessage.newBuilder().setBb(527).build()); + + message.setExtension(repeatedNestedEnumExtensionLite , 1, TestAllTypesLite.NestedEnum.FOO); + message.setExtension(repeatedForeignEnumExtensionLite, 1, ForeignEnumLite.FOREIGN_LITE_FOO); + message.setExtension(repeatedImportEnumExtensionLite , 1, ImportEnumLite.IMPORT_LITE_FOO); + + message.setExtension(repeatedStringPieceExtensionLite, 1, "524"); + message.setExtension(repeatedCordExtensionLite, 1, "525"); + } + + // ------------------------------------------------------------------- + + /** + * Assert (using {@code junit.framework.Assert}} that all extensions of + * {@code message} are set to the values assigned by {@code setAllExtensions}. + */ + public static void assertAllExtensionsSet( + TestAllExtensionsLiteOrBuilder message) { + Assert.assertTrue(message.hasExtension(optionalInt32ExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalInt64ExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalUint32ExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalUint64ExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalSint32ExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalSint64ExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalFixed32ExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalFixed64ExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalSfixed32ExtensionLite)); + Assert.assertTrue(message.hasExtension(optionalSfixed64ExtensionLite)); + Assert.assertTrue(message.hasExtension(optionalFloatExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalDoubleExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalBoolExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalStringExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalBytesExtensionLite )); + + Assert.assertTrue(message.hasExtension(optionalGroupExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalNestedMessageExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalForeignMessageExtensionLite)); + Assert.assertTrue(message.hasExtension(optionalImportMessageExtensionLite )); + + Assert.assertTrue(message.getExtension(optionalGroupExtensionLite ).hasA()); + Assert.assertTrue(message.getExtension(optionalNestedMessageExtensionLite ).hasBb()); + Assert.assertTrue(message.getExtension(optionalForeignMessageExtensionLite).hasC()); + Assert.assertTrue(message.getExtension(optionalImportMessageExtensionLite ).hasD()); + + Assert.assertTrue(message.hasExtension(optionalNestedEnumExtensionLite )); + Assert.assertTrue(message.hasExtension(optionalForeignEnumExtensionLite)); + Assert.assertTrue(message.hasExtension(optionalImportEnumExtensionLite )); + + Assert.assertTrue(message.hasExtension(optionalStringPieceExtensionLite)); + Assert.assertTrue(message.hasExtension(optionalCordExtensionLite)); + + assertEqualsExactType(101 , message.getExtension(optionalInt32ExtensionLite )); + assertEqualsExactType(102L , message.getExtension(optionalInt64ExtensionLite )); + assertEqualsExactType(103 , message.getExtension(optionalUint32ExtensionLite )); + assertEqualsExactType(104L , message.getExtension(optionalUint64ExtensionLite )); + assertEqualsExactType(105 , message.getExtension(optionalSint32ExtensionLite )); + assertEqualsExactType(106L , message.getExtension(optionalSint64ExtensionLite )); + assertEqualsExactType(107 , message.getExtension(optionalFixed32ExtensionLite )); + assertEqualsExactType(108L , message.getExtension(optionalFixed64ExtensionLite )); + assertEqualsExactType(109 , message.getExtension(optionalSfixed32ExtensionLite)); + assertEqualsExactType(110L , message.getExtension(optionalSfixed64ExtensionLite)); + assertEqualsExactType(111F , message.getExtension(optionalFloatExtensionLite )); + assertEqualsExactType(112D , message.getExtension(optionalDoubleExtensionLite )); + assertEqualsExactType(true , message.getExtension(optionalBoolExtensionLite )); + assertEqualsExactType("115", message.getExtension(optionalStringExtensionLite )); + assertEqualsExactType(toBytes("116"), message.getExtension(optionalBytesExtensionLite)); + + assertEqualsExactType(117, message.getExtension(optionalGroupExtensionLite ).getA()); + assertEqualsExactType(118, message.getExtension(optionalNestedMessageExtensionLite ).getBb()); + assertEqualsExactType(119, message.getExtension(optionalForeignMessageExtensionLite).getC()); + assertEqualsExactType(120, message.getExtension(optionalImportMessageExtensionLite ).getD()); + assertEqualsExactType(126, message.getExtension( + optionalPublicImportMessageExtensionLite).getE()); + assertEqualsExactType(127, message.getExtension(optionalLazyMessageExtensionLite).getBb()); + + assertEqualsExactType(TestAllTypesLite.NestedEnum.BAZ, + message.getExtension(optionalNestedEnumExtensionLite)); + assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAZ, + message.getExtension(optionalForeignEnumExtensionLite)); + assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAZ, + message.getExtension(optionalImportEnumExtensionLite)); + + assertEqualsExactType("124", message.getExtension(optionalStringPieceExtensionLite)); + assertEqualsExactType("125", message.getExtension(optionalCordExtensionLite)); + + // ----------------------------------------------------------------- + + Assert.assertEquals(2, message.getExtensionCount(repeatedInt32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedInt64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedUint32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedUint64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSint32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSint64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32ExtensionLite)); + Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64ExtensionLite)); + Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtensionLite )); + + Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtensionLite)); + Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtensionLite )); + + Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtensionLite)); + Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtensionLite)); + + assertEqualsExactType(201 , message.getExtension(repeatedInt32ExtensionLite , 0)); + assertEqualsExactType(202L , message.getExtension(repeatedInt64ExtensionLite , 0)); + assertEqualsExactType(203 , message.getExtension(repeatedUint32ExtensionLite , 0)); + assertEqualsExactType(204L , message.getExtension(repeatedUint64ExtensionLite , 0)); + assertEqualsExactType(205 , message.getExtension(repeatedSint32ExtensionLite , 0)); + assertEqualsExactType(206L , message.getExtension(repeatedSint64ExtensionLite , 0)); + assertEqualsExactType(207 , message.getExtension(repeatedFixed32ExtensionLite , 0)); + assertEqualsExactType(208L , message.getExtension(repeatedFixed64ExtensionLite , 0)); + assertEqualsExactType(209 , message.getExtension(repeatedSfixed32ExtensionLite, 0)); + assertEqualsExactType(210L , message.getExtension(repeatedSfixed64ExtensionLite, 0)); + assertEqualsExactType(211F , message.getExtension(repeatedFloatExtensionLite , 0)); + assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtensionLite , 0)); + assertEqualsExactType(true , message.getExtension(repeatedBoolExtensionLite , 0)); + assertEqualsExactType("215", message.getExtension(repeatedStringExtensionLite , 0)); + assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtensionLite, 0)); + + assertEqualsExactType(217, message.getExtension(repeatedGroupExtensionLite ,0).getA()); + assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtensionLite ,0).getBb()); + assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtensionLite,0).getC()); + assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtensionLite ,0).getD()); + assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtensionLite ,0).getBb()); + + assertEqualsExactType(TestAllTypesLite.NestedEnum.BAR, + message.getExtension(repeatedNestedEnumExtensionLite, 0)); + assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR, + message.getExtension(repeatedForeignEnumExtensionLite, 0)); + assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAR, + message.getExtension(repeatedImportEnumExtensionLite, 0)); + + assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtensionLite, 0)); + assertEqualsExactType("225", message.getExtension(repeatedCordExtensionLite, 0)); + + assertEqualsExactType(301 , message.getExtension(repeatedInt32ExtensionLite , 1)); + assertEqualsExactType(302L , message.getExtension(repeatedInt64ExtensionLite , 1)); + assertEqualsExactType(303 , message.getExtension(repeatedUint32ExtensionLite , 1)); + assertEqualsExactType(304L , message.getExtension(repeatedUint64ExtensionLite , 1)); + assertEqualsExactType(305 , message.getExtension(repeatedSint32ExtensionLite , 1)); + assertEqualsExactType(306L , message.getExtension(repeatedSint64ExtensionLite , 1)); + assertEqualsExactType(307 , message.getExtension(repeatedFixed32ExtensionLite , 1)); + assertEqualsExactType(308L , message.getExtension(repeatedFixed64ExtensionLite , 1)); + assertEqualsExactType(309 , message.getExtension(repeatedSfixed32ExtensionLite, 1)); + assertEqualsExactType(310L , message.getExtension(repeatedSfixed64ExtensionLite, 1)); + assertEqualsExactType(311F , message.getExtension(repeatedFloatExtensionLite , 1)); + assertEqualsExactType(312D , message.getExtension(repeatedDoubleExtensionLite , 1)); + assertEqualsExactType(false, message.getExtension(repeatedBoolExtensionLite , 1)); + assertEqualsExactType("315", message.getExtension(repeatedStringExtensionLite , 1)); + assertEqualsExactType(toBytes("316"), message.getExtension(repeatedBytesExtensionLite, 1)); + + assertEqualsExactType(317, message.getExtension(repeatedGroupExtensionLite ,1).getA()); + assertEqualsExactType(318, message.getExtension(repeatedNestedMessageExtensionLite ,1).getBb()); + assertEqualsExactType(319, message.getExtension(repeatedForeignMessageExtensionLite,1).getC()); + assertEqualsExactType(320, message.getExtension(repeatedImportMessageExtensionLite ,1).getD()); + assertEqualsExactType(327, message.getExtension(repeatedLazyMessageExtensionLite ,1).getBb()); + + assertEqualsExactType(TestAllTypesLite.NestedEnum.BAZ, + message.getExtension(repeatedNestedEnumExtensionLite, 1)); + assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAZ, + message.getExtension(repeatedForeignEnumExtensionLite, 1)); + assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAZ, + message.getExtension(repeatedImportEnumExtensionLite, 1)); + + assertEqualsExactType("324", message.getExtension(repeatedStringPieceExtensionLite, 1)); + assertEqualsExactType("325", message.getExtension(repeatedCordExtensionLite, 1)); + + // ----------------------------------------------------------------- + + Assert.assertTrue(message.hasExtension(defaultInt32ExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultInt64ExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultUint32ExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultUint64ExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultSint32ExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultSint64ExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultFixed32ExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultFixed64ExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultSfixed32ExtensionLite)); + Assert.assertTrue(message.hasExtension(defaultSfixed64ExtensionLite)); + Assert.assertTrue(message.hasExtension(defaultFloatExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultDoubleExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultBoolExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultStringExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultBytesExtensionLite )); + + Assert.assertTrue(message.hasExtension(defaultNestedEnumExtensionLite )); + Assert.assertTrue(message.hasExtension(defaultForeignEnumExtensionLite)); + Assert.assertTrue(message.hasExtension(defaultImportEnumExtensionLite )); + + Assert.assertTrue(message.hasExtension(defaultStringPieceExtensionLite)); + Assert.assertTrue(message.hasExtension(defaultCordExtensionLite)); + + assertEqualsExactType(401 , message.getExtension(defaultInt32ExtensionLite )); + assertEqualsExactType(402L , message.getExtension(defaultInt64ExtensionLite )); + assertEqualsExactType(403 , message.getExtension(defaultUint32ExtensionLite )); + assertEqualsExactType(404L , message.getExtension(defaultUint64ExtensionLite )); + assertEqualsExactType(405 , message.getExtension(defaultSint32ExtensionLite )); + assertEqualsExactType(406L , message.getExtension(defaultSint64ExtensionLite )); + assertEqualsExactType(407 , message.getExtension(defaultFixed32ExtensionLite )); + assertEqualsExactType(408L , message.getExtension(defaultFixed64ExtensionLite )); + assertEqualsExactType(409 , message.getExtension(defaultSfixed32ExtensionLite)); + assertEqualsExactType(410L , message.getExtension(defaultSfixed64ExtensionLite)); + assertEqualsExactType(411F , message.getExtension(defaultFloatExtensionLite )); + assertEqualsExactType(412D , message.getExtension(defaultDoubleExtensionLite )); + assertEqualsExactType(false, message.getExtension(defaultBoolExtensionLite )); + assertEqualsExactType("415", message.getExtension(defaultStringExtensionLite )); + assertEqualsExactType(toBytes("416"), message.getExtension(defaultBytesExtensionLite)); + + assertEqualsExactType(TestAllTypesLite.NestedEnum.FOO, + message.getExtension(defaultNestedEnumExtensionLite )); + assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_FOO, + message.getExtension(defaultForeignEnumExtensionLite)); + assertEqualsExactType(ImportEnumLite.IMPORT_LITE_FOO, + message.getExtension(defaultImportEnumExtensionLite)); + + assertEqualsExactType("424", message.getExtension(defaultStringPieceExtensionLite)); + assertEqualsExactType("425", message.getExtension(defaultCordExtensionLite)); + } + + // ------------------------------------------------------------------- + + /** + * Assert (using {@code junit.framework.Assert}} that all extensions of + * {@code message} are cleared, and that getting the extensions returns their + * default values. + */ + public static void assertExtensionsClear( + TestAllExtensionsLiteOrBuilder message) { + // hasBlah() should initially be false for all optional fields. + Assert.assertFalse(message.hasExtension(optionalInt32ExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalInt64ExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalUint32ExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalUint64ExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalSint32ExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalSint64ExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalFixed32ExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalFixed64ExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalSfixed32ExtensionLite)); + Assert.assertFalse(message.hasExtension(optionalSfixed64ExtensionLite)); + Assert.assertFalse(message.hasExtension(optionalFloatExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalDoubleExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalBoolExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalStringExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalBytesExtensionLite )); + + Assert.assertFalse(message.hasExtension(optionalGroupExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalNestedMessageExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalForeignMessageExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalImportMessageExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalPublicImportMessageExtensionLite)); + Assert.assertFalse(message.hasExtension(optionalLazyMessageExtensionLite )); + + Assert.assertFalse(message.hasExtension(optionalNestedEnumExtensionLite )); + Assert.assertFalse(message.hasExtension(optionalForeignEnumExtensionLite)); + Assert.assertFalse(message.hasExtension(optionalImportEnumExtensionLite )); + + Assert.assertFalse(message.hasExtension(optionalStringPieceExtensionLite)); + Assert.assertFalse(message.hasExtension(optionalCordExtensionLite)); + + // Optional fields without defaults are set to zero or something like it. + assertEqualsExactType(0 , message.getExtension(optionalInt32ExtensionLite )); + assertEqualsExactType(0L , message.getExtension(optionalInt64ExtensionLite )); + assertEqualsExactType(0 , message.getExtension(optionalUint32ExtensionLite )); + assertEqualsExactType(0L , message.getExtension(optionalUint64ExtensionLite )); + assertEqualsExactType(0 , message.getExtension(optionalSint32ExtensionLite )); + assertEqualsExactType(0L , message.getExtension(optionalSint64ExtensionLite )); + assertEqualsExactType(0 , message.getExtension(optionalFixed32ExtensionLite )); + assertEqualsExactType(0L , message.getExtension(optionalFixed64ExtensionLite )); + assertEqualsExactType(0 , message.getExtension(optionalSfixed32ExtensionLite)); + assertEqualsExactType(0L , message.getExtension(optionalSfixed64ExtensionLite)); + assertEqualsExactType(0F , message.getExtension(optionalFloatExtensionLite )); + assertEqualsExactType(0D , message.getExtension(optionalDoubleExtensionLite )); + assertEqualsExactType(false, message.getExtension(optionalBoolExtensionLite )); + assertEqualsExactType("" , message.getExtension(optionalStringExtensionLite )); + assertEqualsExactType(ByteString.EMPTY, message.getExtension(optionalBytesExtensionLite)); + + // Embedded messages should also be clear. + Assert.assertFalse(message.getExtension(optionalGroupExtensionLite ).hasA()); + Assert.assertFalse(message.getExtension(optionalNestedMessageExtensionLite ).hasBb()); + Assert.assertFalse(message.getExtension(optionalForeignMessageExtensionLite ).hasC()); + Assert.assertFalse(message.getExtension(optionalImportMessageExtensionLite ).hasD()); + Assert.assertFalse(message.getExtension(optionalPublicImportMessageExtensionLite).hasE()); + Assert.assertFalse(message.getExtension(optionalLazyMessageExtensionLite ).hasBb()); + + assertEqualsExactType(0, message.getExtension(optionalGroupExtensionLite ).getA()); + assertEqualsExactType(0, message.getExtension(optionalNestedMessageExtensionLite ).getBb()); + assertEqualsExactType(0, message.getExtension(optionalForeignMessageExtensionLite).getC()); + assertEqualsExactType(0, message.getExtension(optionalImportMessageExtensionLite ).getD()); + assertEqualsExactType(0, message.getExtension( + optionalPublicImportMessageExtensionLite).getE()); + assertEqualsExactType(0, message.getExtension(optionalLazyMessageExtensionLite ).getBb()); + + // Enums without defaults are set to the first value in the enum. + assertEqualsExactType(TestAllTypesLite.NestedEnum.FOO, + message.getExtension(optionalNestedEnumExtensionLite )); + assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_FOO, + message.getExtension(optionalForeignEnumExtensionLite)); + assertEqualsExactType(ImportEnumLite.IMPORT_LITE_FOO, + message.getExtension(optionalImportEnumExtensionLite)); + + assertEqualsExactType("", message.getExtension(optionalStringPieceExtensionLite)); + assertEqualsExactType("", message.getExtension(optionalCordExtensionLite)); + + // Repeated fields are empty. + Assert.assertEquals(0, message.getExtensionCount(repeatedInt32ExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedInt64ExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedUint32ExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedUint64ExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedSint32ExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedSint64ExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedFixed32ExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedFixed64ExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed32ExtensionLite)); + Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed64ExtensionLite)); + Assert.assertEquals(0, message.getExtensionCount(repeatedFloatExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedDoubleExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedBoolExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedStringExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedBytesExtensionLite )); + + Assert.assertEquals(0, message.getExtensionCount(repeatedGroupExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedNestedMessageExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedForeignMessageExtensionLite)); + Assert.assertEquals(0, message.getExtensionCount(repeatedImportMessageExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedLazyMessageExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedNestedEnumExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedForeignEnumExtensionLite )); + Assert.assertEquals(0, message.getExtensionCount(repeatedImportEnumExtensionLite )); + + Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtensionLite)); + Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtensionLite)); + + // hasBlah() should also be false for all default fields. + Assert.assertFalse(message.hasExtension(defaultInt32ExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultInt64ExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultUint32ExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultUint64ExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultSint32ExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultSint64ExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultFixed32ExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultFixed64ExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultSfixed32ExtensionLite)); + Assert.assertFalse(message.hasExtension(defaultSfixed64ExtensionLite)); + Assert.assertFalse(message.hasExtension(defaultFloatExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultDoubleExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultBoolExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultStringExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultBytesExtensionLite )); + + Assert.assertFalse(message.hasExtension(defaultNestedEnumExtensionLite )); + Assert.assertFalse(message.hasExtension(defaultForeignEnumExtensionLite)); + Assert.assertFalse(message.hasExtension(defaultImportEnumExtensionLite )); + + Assert.assertFalse(message.hasExtension(defaultStringPieceExtensionLite)); + Assert.assertFalse(message.hasExtension(defaultCordExtensionLite)); + + // Fields with defaults have their default values (duh). + assertEqualsExactType( 41 , message.getExtension(defaultInt32ExtensionLite )); + assertEqualsExactType( 42L , message.getExtension(defaultInt64ExtensionLite )); + assertEqualsExactType( 43 , message.getExtension(defaultUint32ExtensionLite )); + assertEqualsExactType( 44L , message.getExtension(defaultUint64ExtensionLite )); + assertEqualsExactType(-45 , message.getExtension(defaultSint32ExtensionLite )); + assertEqualsExactType( 46L , message.getExtension(defaultSint64ExtensionLite )); + assertEqualsExactType( 47 , message.getExtension(defaultFixed32ExtensionLite )); + assertEqualsExactType( 48L , message.getExtension(defaultFixed64ExtensionLite )); + assertEqualsExactType( 49 , message.getExtension(defaultSfixed32ExtensionLite)); + assertEqualsExactType(-50L , message.getExtension(defaultSfixed64ExtensionLite)); + assertEqualsExactType( 51.5F , message.getExtension(defaultFloatExtensionLite )); + assertEqualsExactType( 52e3D , message.getExtension(defaultDoubleExtensionLite )); + assertEqualsExactType(true , message.getExtension(defaultBoolExtensionLite )); + assertEqualsExactType("hello", message.getExtension(defaultStringExtensionLite )); + assertEqualsExactType(toBytes("world"), message.getExtension(defaultBytesExtensionLite)); + + assertEqualsExactType(TestAllTypesLite.NestedEnum.BAR, + message.getExtension(defaultNestedEnumExtensionLite )); + assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR, + message.getExtension(defaultForeignEnumExtensionLite)); + assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAR, + message.getExtension(defaultImportEnumExtensionLite)); + + assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtensionLite)); + assertEqualsExactType("123", message.getExtension(defaultCordExtensionLite)); + } + + // ------------------------------------------------------------------- + + /** + * Assert (using {@code junit.framework.Assert}} that all extensions of + * {@code message} are set to the values assigned by {@code setAllExtensions} + * followed by {@code modifyRepeatedExtensions}. + */ + public static void assertRepeatedExtensionsModified( + TestAllExtensionsLiteOrBuilder message) { + // ModifyRepeatedFields only sets the second repeated element of each + // field. In addition to verifying this, we also verify that the first + // element and size were *not* modified. + Assert.assertEquals(2, message.getExtensionCount(repeatedInt32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedInt64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedUint32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedUint64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSint32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSint64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32ExtensionLite)); + Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64ExtensionLite)); + Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtensionLite )); + + Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtensionLite)); + Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtensionLite )); + + Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtensionLite)); + Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtensionLite)); + + assertEqualsExactType(201 , message.getExtension(repeatedInt32ExtensionLite , 0)); + assertEqualsExactType(202L , message.getExtension(repeatedInt64ExtensionLite , 0)); + assertEqualsExactType(203 , message.getExtension(repeatedUint32ExtensionLite , 0)); + assertEqualsExactType(204L , message.getExtension(repeatedUint64ExtensionLite , 0)); + assertEqualsExactType(205 , message.getExtension(repeatedSint32ExtensionLite , 0)); + assertEqualsExactType(206L , message.getExtension(repeatedSint64ExtensionLite , 0)); + assertEqualsExactType(207 , message.getExtension(repeatedFixed32ExtensionLite , 0)); + assertEqualsExactType(208L , message.getExtension(repeatedFixed64ExtensionLite , 0)); + assertEqualsExactType(209 , message.getExtension(repeatedSfixed32ExtensionLite, 0)); + assertEqualsExactType(210L , message.getExtension(repeatedSfixed64ExtensionLite, 0)); + assertEqualsExactType(211F , message.getExtension(repeatedFloatExtensionLite , 0)); + assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtensionLite , 0)); + assertEqualsExactType(true , message.getExtension(repeatedBoolExtensionLite , 0)); + assertEqualsExactType("215", message.getExtension(repeatedStringExtensionLite , 0)); + assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtensionLite, 0)); + + assertEqualsExactType(217, message.getExtension(repeatedGroupExtensionLite ,0).getA()); + assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtensionLite ,0).getBb()); + assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtensionLite,0).getC()); + assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtensionLite ,0).getD()); + assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtensionLite ,0).getBb()); + + assertEqualsExactType(TestAllTypesLite.NestedEnum.BAR, + message.getExtension(repeatedNestedEnumExtensionLite, 0)); + assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR, + message.getExtension(repeatedForeignEnumExtensionLite, 0)); + assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAR, + message.getExtension(repeatedImportEnumExtensionLite, 0)); + + assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtensionLite, 0)); + assertEqualsExactType("225", message.getExtension(repeatedCordExtensionLite, 0)); + + // Actually verify the second (modified) elements now. + assertEqualsExactType(501 , message.getExtension(repeatedInt32ExtensionLite , 1)); + assertEqualsExactType(502L , message.getExtension(repeatedInt64ExtensionLite , 1)); + assertEqualsExactType(503 , message.getExtension(repeatedUint32ExtensionLite , 1)); + assertEqualsExactType(504L , message.getExtension(repeatedUint64ExtensionLite , 1)); + assertEqualsExactType(505 , message.getExtension(repeatedSint32ExtensionLite , 1)); + assertEqualsExactType(506L , message.getExtension(repeatedSint64ExtensionLite , 1)); + assertEqualsExactType(507 , message.getExtension(repeatedFixed32ExtensionLite , 1)); + assertEqualsExactType(508L , message.getExtension(repeatedFixed64ExtensionLite , 1)); + assertEqualsExactType(509 , message.getExtension(repeatedSfixed32ExtensionLite, 1)); + assertEqualsExactType(510L , message.getExtension(repeatedSfixed64ExtensionLite, 1)); + assertEqualsExactType(511F , message.getExtension(repeatedFloatExtensionLite , 1)); + assertEqualsExactType(512D , message.getExtension(repeatedDoubleExtensionLite , 1)); + assertEqualsExactType(true , message.getExtension(repeatedBoolExtensionLite , 1)); + assertEqualsExactType("515", message.getExtension(repeatedStringExtensionLite , 1)); + assertEqualsExactType(toBytes("516"), message.getExtension(repeatedBytesExtensionLite, 1)); + + assertEqualsExactType(517, message.getExtension(repeatedGroupExtensionLite ,1).getA()); + assertEqualsExactType(518, message.getExtension(repeatedNestedMessageExtensionLite ,1).getBb()); + assertEqualsExactType(519, message.getExtension(repeatedForeignMessageExtensionLite,1).getC()); + assertEqualsExactType(520, message.getExtension(repeatedImportMessageExtensionLite ,1).getD()); + assertEqualsExactType(527, message.getExtension(repeatedLazyMessageExtensionLite ,1).getBb()); + + assertEqualsExactType(TestAllTypesLite.NestedEnum.FOO, + message.getExtension(repeatedNestedEnumExtensionLite, 1)); + assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_FOO, + message.getExtension(repeatedForeignEnumExtensionLite, 1)); + assertEqualsExactType(ImportEnumLite.IMPORT_LITE_FOO, + message.getExtension(repeatedImportEnumExtensionLite, 1)); + + assertEqualsExactType("524", message.getExtension(repeatedStringPieceExtensionLite, 1)); + assertEqualsExactType("525", message.getExtension(repeatedCordExtensionLite, 1)); + } + + public static void setPackedExtensions(TestPackedExtensionsLite.Builder message) { + message.addExtension(packedInt32ExtensionLite , 601); + message.addExtension(packedInt64ExtensionLite , 602L); + message.addExtension(packedUint32ExtensionLite , 603); + message.addExtension(packedUint64ExtensionLite , 604L); + message.addExtension(packedSint32ExtensionLite , 605); + message.addExtension(packedSint64ExtensionLite , 606L); + message.addExtension(packedFixed32ExtensionLite , 607); + message.addExtension(packedFixed64ExtensionLite , 608L); + message.addExtension(packedSfixed32ExtensionLite, 609); + message.addExtension(packedSfixed64ExtensionLite, 610L); + message.addExtension(packedFloatExtensionLite , 611F); + message.addExtension(packedDoubleExtensionLite , 612D); + message.addExtension(packedBoolExtensionLite , true); + message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR); + // Add a second one of each field. + message.addExtension(packedInt32ExtensionLite , 701); + message.addExtension(packedInt64ExtensionLite , 702L); + message.addExtension(packedUint32ExtensionLite , 703); + message.addExtension(packedUint64ExtensionLite , 704L); + message.addExtension(packedSint32ExtensionLite , 705); + message.addExtension(packedSint64ExtensionLite , 706L); + message.addExtension(packedFixed32ExtensionLite , 707); + message.addExtension(packedFixed64ExtensionLite , 708L); + message.addExtension(packedSfixed32ExtensionLite, 709); + message.addExtension(packedSfixed64ExtensionLite, 710L); + message.addExtension(packedFloatExtensionLite , 711F); + message.addExtension(packedDoubleExtensionLite , 712D); + message.addExtension(packedBoolExtensionLite , false); + message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ); + } + + public static void assertPackedExtensionsSet(TestPackedExtensionsLite message) { + Assert.assertEquals(2, message.getExtensionCount(packedInt32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(packedInt64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(packedUint32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(packedUint64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(packedSint32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(packedSint64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(packedFixed32ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(packedFixed64ExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(packedSfixed32ExtensionLite)); + Assert.assertEquals(2, message.getExtensionCount(packedSfixed64ExtensionLite)); + Assert.assertEquals(2, message.getExtensionCount(packedFloatExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(packedDoubleExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(packedBoolExtensionLite )); + Assert.assertEquals(2, message.getExtensionCount(packedEnumExtensionLite)); + assertEqualsExactType(601 , message.getExtension(packedInt32ExtensionLite , 0)); + assertEqualsExactType(602L , message.getExtension(packedInt64ExtensionLite , 0)); + assertEqualsExactType(603 , message.getExtension(packedUint32ExtensionLite , 0)); + assertEqualsExactType(604L , message.getExtension(packedUint64ExtensionLite , 0)); + assertEqualsExactType(605 , message.getExtension(packedSint32ExtensionLite , 0)); + assertEqualsExactType(606L , message.getExtension(packedSint64ExtensionLite , 0)); + assertEqualsExactType(607 , message.getExtension(packedFixed32ExtensionLite , 0)); + assertEqualsExactType(608L , message.getExtension(packedFixed64ExtensionLite , 0)); + assertEqualsExactType(609 , message.getExtension(packedSfixed32ExtensionLite, 0)); + assertEqualsExactType(610L , message.getExtension(packedSfixed64ExtensionLite, 0)); + assertEqualsExactType(611F , message.getExtension(packedFloatExtensionLite , 0)); + assertEqualsExactType(612D , message.getExtension(packedDoubleExtensionLite , 0)); + assertEqualsExactType(true , message.getExtension(packedBoolExtensionLite , 0)); + assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR, + message.getExtension(packedEnumExtensionLite, 0)); + assertEqualsExactType(701 , message.getExtension(packedInt32ExtensionLite , 1)); + assertEqualsExactType(702L , message.getExtension(packedInt64ExtensionLite , 1)); + assertEqualsExactType(703 , message.getExtension(packedUint32ExtensionLite , 1)); + assertEqualsExactType(704L , message.getExtension(packedUint64ExtensionLite , 1)); + assertEqualsExactType(705 , message.getExtension(packedSint32ExtensionLite , 1)); + assertEqualsExactType(706L , message.getExtension(packedSint64ExtensionLite , 1)); + assertEqualsExactType(707 , message.getExtension(packedFixed32ExtensionLite , 1)); + assertEqualsExactType(708L , message.getExtension(packedFixed64ExtensionLite , 1)); + assertEqualsExactType(709 , message.getExtension(packedSfixed32ExtensionLite, 1)); + assertEqualsExactType(710L , message.getExtension(packedSfixed64ExtensionLite, 1)); + assertEqualsExactType(711F , message.getExtension(packedFloatExtensionLite , 1)); + assertEqualsExactType(712D , message.getExtension(packedDoubleExtensionLite , 1)); + assertEqualsExactType(false, message.getExtension(packedBoolExtensionLite , 1)); + assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAZ, + message.getExtension(packedEnumExtensionLite, 1)); + } + + // ================================================================= + + /** + * Performs the same things that the methods of {@code TestUtil} do, but + * via the reflection interface. This is its own class because it needs + * to know what descriptor to use. + */ + public static class ReflectionTester { + private final Descriptors.Descriptor baseDescriptor; + private final ExtensionRegistry extensionRegistry; + + private final Descriptors.FileDescriptor file; + private final Descriptors.FileDescriptor importFile; + private final Descriptors.FileDescriptor publicImportFile; + + private final Descriptors.Descriptor optionalGroup; + private final Descriptors.Descriptor repeatedGroup; + private final Descriptors.Descriptor nestedMessage; + private final Descriptors.Descriptor foreignMessage; + private final Descriptors.Descriptor importMessage; + private final Descriptors.Descriptor publicImportMessage; + + private final Descriptors.FieldDescriptor groupA; + private final Descriptors.FieldDescriptor repeatedGroupA; + private final Descriptors.FieldDescriptor nestedB; + private final Descriptors.FieldDescriptor foreignC; + private final Descriptors.FieldDescriptor importD; + private final Descriptors.FieldDescriptor importE; + + private final Descriptors.EnumDescriptor nestedEnum; + private final Descriptors.EnumDescriptor foreignEnum; + private final Descriptors.EnumDescriptor importEnum; + + private final Descriptors.EnumValueDescriptor nestedFoo; + private final Descriptors.EnumValueDescriptor nestedBar; + private final Descriptors.EnumValueDescriptor nestedBaz; + private final Descriptors.EnumValueDescriptor foreignFoo; + private final Descriptors.EnumValueDescriptor foreignBar; + private final Descriptors.EnumValueDescriptor foreignBaz; + private final Descriptors.EnumValueDescriptor importFoo; + private final Descriptors.EnumValueDescriptor importBar; + private final Descriptors.EnumValueDescriptor importBaz; + + /** + * Construct a {@code ReflectionTester} that will expect messages using + * the given descriptor. + * + * Normally {@code baseDescriptor} should be a descriptor for the type + * {@code TestAllTypes}, defined in + * {@code google/protobuf/unittest.proto}. However, if + * {@code extensionRegistry} is non-null, then {@code baseDescriptor} should + * be for {@code TestAllExtensions} instead, and instead of reading and + * writing normal fields, the tester will read and write extensions. + * All of {@code TestAllExtensions}' extensions must be registered in the + * registry. + */ + public ReflectionTester(Descriptors.Descriptor baseDescriptor, + ExtensionRegistry extensionRegistry) { + this.baseDescriptor = baseDescriptor; + this.extensionRegistry = extensionRegistry; + + this.file = baseDescriptor.getFile(); + Assert.assertEquals(1, file.getDependencies().size()); + this.importFile = file.getDependencies().get(0); + this.publicImportFile = importFile.getDependencies().get(0); + + Descriptors.Descriptor testAllTypes; + if (baseDescriptor.getName() == "TestAllTypes") { + testAllTypes = baseDescriptor; + } else { + testAllTypes = file.findMessageTypeByName("TestAllTypes"); + Assert.assertNotNull(testAllTypes); + } + + if (extensionRegistry == null) { + // Use testAllTypes, rather than baseDescriptor, to allow + // initialization using TestPackedTypes descriptors. These objects + // won't be used by the methods for packed fields. + this.optionalGroup = + testAllTypes.findNestedTypeByName("OptionalGroup"); + this.repeatedGroup = + testAllTypes.findNestedTypeByName("RepeatedGroup"); + } else { + this.optionalGroup = + file.findMessageTypeByName("OptionalGroup_extension"); + this.repeatedGroup = + file.findMessageTypeByName("RepeatedGroup_extension"); + } + this.nestedMessage = testAllTypes.findNestedTypeByName("NestedMessage"); + this.foreignMessage = file.findMessageTypeByName("ForeignMessage"); + this.importMessage = importFile.findMessageTypeByName("ImportMessage"); + this.publicImportMessage = publicImportFile.findMessageTypeByName( + "PublicImportMessage"); + + this.nestedEnum = testAllTypes.findEnumTypeByName("NestedEnum"); + this.foreignEnum = file.findEnumTypeByName("ForeignEnum"); + this.importEnum = importFile.findEnumTypeByName("ImportEnum"); + + Assert.assertNotNull(optionalGroup ); + Assert.assertNotNull(repeatedGroup ); + Assert.assertNotNull(nestedMessage ); + Assert.assertNotNull(foreignMessage); + Assert.assertNotNull(importMessage ); + Assert.assertNotNull(nestedEnum ); + Assert.assertNotNull(foreignEnum ); + Assert.assertNotNull(importEnum ); + + this.nestedB = nestedMessage .findFieldByName("bb"); + this.foreignC = foreignMessage.findFieldByName("c"); + this.importD = importMessage .findFieldByName("d"); + this.importE = publicImportMessage.findFieldByName("e"); + this.nestedFoo = nestedEnum.findValueByName("FOO"); + this.nestedBar = nestedEnum.findValueByName("BAR"); + this.nestedBaz = nestedEnum.findValueByName("BAZ"); + this.foreignFoo = foreignEnum.findValueByName("FOREIGN_FOO"); + this.foreignBar = foreignEnum.findValueByName("FOREIGN_BAR"); + this.foreignBaz = foreignEnum.findValueByName("FOREIGN_BAZ"); + this.importFoo = importEnum.findValueByName("IMPORT_FOO"); + this.importBar = importEnum.findValueByName("IMPORT_BAR"); + this.importBaz = importEnum.findValueByName("IMPORT_BAZ"); + + this.groupA = optionalGroup.findFieldByName("a"); + this.repeatedGroupA = repeatedGroup.findFieldByName("a"); + + Assert.assertNotNull(groupA ); + Assert.assertNotNull(repeatedGroupA); + Assert.assertNotNull(nestedB ); + Assert.assertNotNull(foreignC ); + Assert.assertNotNull(importD ); + Assert.assertNotNull(importE ); + Assert.assertNotNull(nestedFoo ); + Assert.assertNotNull(nestedBar ); + Assert.assertNotNull(nestedBaz ); + Assert.assertNotNull(foreignFoo ); + Assert.assertNotNull(foreignBar ); + Assert.assertNotNull(foreignBaz ); + Assert.assertNotNull(importFoo ); + Assert.assertNotNull(importBar ); + Assert.assertNotNull(importBaz ); + } + + /** + * Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. + */ + private Descriptors.FieldDescriptor f(String name) { + Descriptors.FieldDescriptor result; + if (extensionRegistry == null) { + result = baseDescriptor.findFieldByName(name); + } else { + result = file.findExtensionByName(name + "_extension"); + } + Assert.assertNotNull(result); + return result; + } + + /** + * Calls {@code parent.newBuilderForField()} or uses the + * {@code ExtensionRegistry} to find an appropriate builder, depending + * on what type is being tested. + */ + private Message.Builder newBuilderForField( + Message.Builder parent, Descriptors.FieldDescriptor field) { + if (extensionRegistry == null) { + return parent.newBuilderForField(field); + } else { + ExtensionRegistry.ExtensionInfo extension = + extensionRegistry.findExtensionByNumber(field.getContainingType(), + field.getNumber()); + Assert.assertNotNull(extension); + Assert.assertNotNull(extension.defaultInstance); + return extension.defaultInstance.newBuilderForType(); + } + } + + // ------------------------------------------------------------------- + + /** + * Set every field of {@code message} to the values expected by + * {@code assertAllFieldsSet()}, using the {@link Message.Builder} + * reflection interface. + */ + void setAllFieldsViaReflection(Message.Builder message) { + message.setField(f("optional_int32" ), 101 ); + message.setField(f("optional_int64" ), 102L); + message.setField(f("optional_uint32" ), 103 ); + message.setField(f("optional_uint64" ), 104L); + message.setField(f("optional_sint32" ), 105 ); + message.setField(f("optional_sint64" ), 106L); + message.setField(f("optional_fixed32" ), 107 ); + message.setField(f("optional_fixed64" ), 108L); + message.setField(f("optional_sfixed32"), 109 ); + message.setField(f("optional_sfixed64"), 110L); + message.setField(f("optional_float" ), 111F); + message.setField(f("optional_double" ), 112D); + message.setField(f("optional_bool" ), true); + message.setField(f("optional_string" ), "115"); + message.setField(f("optional_bytes" ), toBytes("116")); + + message.setField(f("optionalgroup"), + newBuilderForField(message, f("optionalgroup")) + .setField(groupA, 117).build()); + message.setField(f("optional_nested_message"), + newBuilderForField(message, f("optional_nested_message")) + .setField(nestedB, 118).build()); + message.setField(f("optional_foreign_message"), + newBuilderForField(message, f("optional_foreign_message")) + .setField(foreignC, 119).build()); + message.setField(f("optional_import_message"), + newBuilderForField(message, f("optional_import_message")) + .setField(importD, 120).build()); + message.setField(f("optional_public_import_message"), + newBuilderForField(message, f("optional_public_import_message")) + .setField(importE, 126).build()); + message.setField(f("optional_lazy_message"), + newBuilderForField(message, f("optional_lazy_message")) + .setField(nestedB, 127).build()); + + message.setField(f("optional_nested_enum" ), nestedBaz); + message.setField(f("optional_foreign_enum"), foreignBaz); + message.setField(f("optional_import_enum" ), importBaz); + + message.setField(f("optional_string_piece" ), "124"); + message.setField(f("optional_cord" ), "125"); + + // ----------------------------------------------------------------- + + message.addRepeatedField(f("repeated_int32" ), 201 ); + message.addRepeatedField(f("repeated_int64" ), 202L); + message.addRepeatedField(f("repeated_uint32" ), 203 ); + message.addRepeatedField(f("repeated_uint64" ), 204L); + message.addRepeatedField(f("repeated_sint32" ), 205 ); + message.addRepeatedField(f("repeated_sint64" ), 206L); + message.addRepeatedField(f("repeated_fixed32" ), 207 ); + message.addRepeatedField(f("repeated_fixed64" ), 208L); + message.addRepeatedField(f("repeated_sfixed32"), 209 ); + message.addRepeatedField(f("repeated_sfixed64"), 210L); + message.addRepeatedField(f("repeated_float" ), 211F); + message.addRepeatedField(f("repeated_double" ), 212D); + message.addRepeatedField(f("repeated_bool" ), true); + message.addRepeatedField(f("repeated_string" ), "215"); + message.addRepeatedField(f("repeated_bytes" ), toBytes("216")); + + message.addRepeatedField(f("repeatedgroup"), + newBuilderForField(message, f("repeatedgroup")) + .setField(repeatedGroupA, 217).build()); + message.addRepeatedField(f("repeated_nested_message"), + newBuilderForField(message, f("repeated_nested_message")) + .setField(nestedB, 218).build()); + message.addRepeatedField(f("repeated_foreign_message"), + newBuilderForField(message, f("repeated_foreign_message")) + .setField(foreignC, 219).build()); + message.addRepeatedField(f("repeated_import_message"), + newBuilderForField(message, f("repeated_import_message")) + .setField(importD, 220).build()); + message.addRepeatedField(f("repeated_lazy_message"), + newBuilderForField(message, f("repeated_lazy_message")) + .setField(nestedB, 227).build()); + + message.addRepeatedField(f("repeated_nested_enum" ), nestedBar); + message.addRepeatedField(f("repeated_foreign_enum"), foreignBar); + message.addRepeatedField(f("repeated_import_enum" ), importBar); + + message.addRepeatedField(f("repeated_string_piece" ), "224"); + message.addRepeatedField(f("repeated_cord" ), "225"); + + // Add a second one of each field. + message.addRepeatedField(f("repeated_int32" ), 301 ); + message.addRepeatedField(f("repeated_int64" ), 302L); + message.addRepeatedField(f("repeated_uint32" ), 303 ); + message.addRepeatedField(f("repeated_uint64" ), 304L); + message.addRepeatedField(f("repeated_sint32" ), 305 ); + message.addRepeatedField(f("repeated_sint64" ), 306L); + message.addRepeatedField(f("repeated_fixed32" ), 307 ); + message.addRepeatedField(f("repeated_fixed64" ), 308L); + message.addRepeatedField(f("repeated_sfixed32"), 309 ); + message.addRepeatedField(f("repeated_sfixed64"), 310L); + message.addRepeatedField(f("repeated_float" ), 311F); + message.addRepeatedField(f("repeated_double" ), 312D); + message.addRepeatedField(f("repeated_bool" ), false); + message.addRepeatedField(f("repeated_string" ), "315"); + message.addRepeatedField(f("repeated_bytes" ), toBytes("316")); + + message.addRepeatedField(f("repeatedgroup"), + newBuilderForField(message, f("repeatedgroup")) + .setField(repeatedGroupA, 317).build()); + message.addRepeatedField(f("repeated_nested_message"), + newBuilderForField(message, f("repeated_nested_message")) + .setField(nestedB, 318).build()); + message.addRepeatedField(f("repeated_foreign_message"), + newBuilderForField(message, f("repeated_foreign_message")) + .setField(foreignC, 319).build()); + message.addRepeatedField(f("repeated_import_message"), + newBuilderForField(message, f("repeated_import_message")) + .setField(importD, 320).build()); + message.addRepeatedField(f("repeated_lazy_message"), + newBuilderForField(message, f("repeated_lazy_message")) + .setField(nestedB, 327).build()); + + message.addRepeatedField(f("repeated_nested_enum" ), nestedBaz); + message.addRepeatedField(f("repeated_foreign_enum"), foreignBaz); + message.addRepeatedField(f("repeated_import_enum" ), importBaz); + + message.addRepeatedField(f("repeated_string_piece" ), "324"); + message.addRepeatedField(f("repeated_cord" ), "325"); + + // ----------------------------------------------------------------- + + message.setField(f("default_int32" ), 401 ); + message.setField(f("default_int64" ), 402L); + message.setField(f("default_uint32" ), 403 ); + message.setField(f("default_uint64" ), 404L); + message.setField(f("default_sint32" ), 405 ); + message.setField(f("default_sint64" ), 406L); + message.setField(f("default_fixed32" ), 407 ); + message.setField(f("default_fixed64" ), 408L); + message.setField(f("default_sfixed32"), 409 ); + message.setField(f("default_sfixed64"), 410L); + message.setField(f("default_float" ), 411F); + message.setField(f("default_double" ), 412D); + message.setField(f("default_bool" ), false); + message.setField(f("default_string" ), "415"); + message.setField(f("default_bytes" ), toBytes("416")); + + message.setField(f("default_nested_enum" ), nestedFoo); + message.setField(f("default_foreign_enum"), foreignFoo); + message.setField(f("default_import_enum" ), importFoo); + + message.setField(f("default_string_piece" ), "424"); + message.setField(f("default_cord" ), "425"); + } + + // ------------------------------------------------------------------- + + /** + * Modify the repeated fields of {@code message} to contain the values + * expected by {@code assertRepeatedFieldsModified()}, using the + * {@link Message.Builder} reflection interface. + */ + void modifyRepeatedFieldsViaReflection(Message.Builder message) { + message.setRepeatedField(f("repeated_int32" ), 1, 501 ); + message.setRepeatedField(f("repeated_int64" ), 1, 502L); + message.setRepeatedField(f("repeated_uint32" ), 1, 503 ); + message.setRepeatedField(f("repeated_uint64" ), 1, 504L); + message.setRepeatedField(f("repeated_sint32" ), 1, 505 ); + message.setRepeatedField(f("repeated_sint64" ), 1, 506L); + message.setRepeatedField(f("repeated_fixed32" ), 1, 507 ); + message.setRepeatedField(f("repeated_fixed64" ), 1, 508L); + message.setRepeatedField(f("repeated_sfixed32"), 1, 509 ); + message.setRepeatedField(f("repeated_sfixed64"), 1, 510L); + message.setRepeatedField(f("repeated_float" ), 1, 511F); + message.setRepeatedField(f("repeated_double" ), 1, 512D); + message.setRepeatedField(f("repeated_bool" ), 1, true); + message.setRepeatedField(f("repeated_string" ), 1, "515"); + message.setRepeatedField(f("repeated_bytes" ), 1, toBytes("516")); + + message.setRepeatedField(f("repeatedgroup"), 1, + newBuilderForField(message, f("repeatedgroup")) + .setField(repeatedGroupA, 517).build()); + message.setRepeatedField(f("repeated_nested_message"), 1, + newBuilderForField(message, f("repeated_nested_message")) + .setField(nestedB, 518).build()); + message.setRepeatedField(f("repeated_foreign_message"), 1, + newBuilderForField(message, f("repeated_foreign_message")) + .setField(foreignC, 519).build()); + message.setRepeatedField(f("repeated_import_message"), 1, + newBuilderForField(message, f("repeated_import_message")) + .setField(importD, 520).build()); + message.setRepeatedField(f("repeated_lazy_message"), 1, + newBuilderForField(message, f("repeated_lazy_message")) + .setField(nestedB, 527).build()); + + message.setRepeatedField(f("repeated_nested_enum" ), 1, nestedFoo); + message.setRepeatedField(f("repeated_foreign_enum"), 1, foreignFoo); + message.setRepeatedField(f("repeated_import_enum" ), 1, importFoo); + + message.setRepeatedField(f("repeated_string_piece"), 1, "524"); + message.setRepeatedField(f("repeated_cord"), 1, "525"); + } + + // ------------------------------------------------------------------- + + /** + * Assert (using {@code junit.framework.Assert}} that all fields of + * {@code message} are set to the values assigned by {@code setAllFields}, + * using the {@link Message} reflection interface. + */ + public void assertAllFieldsSetViaReflection(MessageOrBuilder message) { + Assert.assertTrue(message.hasField(f("optional_int32" ))); + Assert.assertTrue(message.hasField(f("optional_int64" ))); + Assert.assertTrue(message.hasField(f("optional_uint32" ))); + Assert.assertTrue(message.hasField(f("optional_uint64" ))); + Assert.assertTrue(message.hasField(f("optional_sint32" ))); + Assert.assertTrue(message.hasField(f("optional_sint64" ))); + Assert.assertTrue(message.hasField(f("optional_fixed32" ))); + Assert.assertTrue(message.hasField(f("optional_fixed64" ))); + Assert.assertTrue(message.hasField(f("optional_sfixed32"))); + Assert.assertTrue(message.hasField(f("optional_sfixed64"))); + Assert.assertTrue(message.hasField(f("optional_float" ))); + Assert.assertTrue(message.hasField(f("optional_double" ))); + Assert.assertTrue(message.hasField(f("optional_bool" ))); + Assert.assertTrue(message.hasField(f("optional_string" ))); + Assert.assertTrue(message.hasField(f("optional_bytes" ))); + + Assert.assertTrue(message.hasField(f("optionalgroup" ))); + Assert.assertTrue(message.hasField(f("optional_nested_message" ))); + Assert.assertTrue(message.hasField(f("optional_foreign_message"))); + Assert.assertTrue(message.hasField(f("optional_import_message" ))); + + Assert.assertTrue( + ((Message)message.getField(f("optionalgroup"))).hasField(groupA)); + Assert.assertTrue( + ((Message)message.getField(f("optional_nested_message"))) + .hasField(nestedB)); + Assert.assertTrue( + ((Message)message.getField(f("optional_foreign_message"))) + .hasField(foreignC)); + Assert.assertTrue( + ((Message)message.getField(f("optional_import_message"))) + .hasField(importD)); + + Assert.assertTrue(message.hasField(f("optional_nested_enum" ))); + Assert.assertTrue(message.hasField(f("optional_foreign_enum"))); + Assert.assertTrue(message.hasField(f("optional_import_enum" ))); + + Assert.assertTrue(message.hasField(f("optional_string_piece"))); + Assert.assertTrue(message.hasField(f("optional_cord"))); + + Assert.assertEquals(101 , message.getField(f("optional_int32" ))); + Assert.assertEquals(102L , message.getField(f("optional_int64" ))); + Assert.assertEquals(103 , message.getField(f("optional_uint32" ))); + Assert.assertEquals(104L , message.getField(f("optional_uint64" ))); + Assert.assertEquals(105 , message.getField(f("optional_sint32" ))); + Assert.assertEquals(106L , message.getField(f("optional_sint64" ))); + Assert.assertEquals(107 , message.getField(f("optional_fixed32" ))); + Assert.assertEquals(108L , message.getField(f("optional_fixed64" ))); + Assert.assertEquals(109 , message.getField(f("optional_sfixed32"))); + Assert.assertEquals(110L , message.getField(f("optional_sfixed64"))); + Assert.assertEquals(111F , message.getField(f("optional_float" ))); + Assert.assertEquals(112D , message.getField(f("optional_double" ))); + Assert.assertEquals(true , message.getField(f("optional_bool" ))); + Assert.assertEquals("115", message.getField(f("optional_string" ))); + Assert.assertEquals(toBytes("116"), message.getField(f("optional_bytes"))); + + Assert.assertEquals(117, + ((Message)message.getField(f("optionalgroup"))).getField(groupA)); + Assert.assertEquals(118, + ((Message)message.getField(f("optional_nested_message"))) + .getField(nestedB)); + Assert.assertEquals(119, + ((Message)message.getField(f("optional_foreign_message"))) + .getField(foreignC)); + Assert.assertEquals(120, + ((Message)message.getField(f("optional_import_message"))) + .getField(importD)); + Assert.assertEquals(126, + ((Message)message.getField(f("optional_public_import_message"))) + .getField(importE)); + Assert.assertEquals(127, + ((Message)message.getField(f("optional_lazy_message"))) + .getField(nestedB)); + + Assert.assertEquals( nestedBaz, message.getField(f("optional_nested_enum" ))); + Assert.assertEquals(foreignBaz, message.getField(f("optional_foreign_enum"))); + Assert.assertEquals( importBaz, message.getField(f("optional_import_enum" ))); + + Assert.assertEquals("124", message.getField(f("optional_string_piece"))); + Assert.assertEquals("125", message.getField(f("optional_cord"))); + + // ----------------------------------------------------------------- + + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed32"))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed64"))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_float" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_double" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bool" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bytes" ))); + + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeatedgroup" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_message" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_message"))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_message" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_lazy_message" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_enum" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_enum" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_enum" ))); + + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string_piece"))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_cord"))); + + Assert.assertEquals(201 , message.getRepeatedField(f("repeated_int32" ), 0)); + Assert.assertEquals(202L , message.getRepeatedField(f("repeated_int64" ), 0)); + Assert.assertEquals(203 , message.getRepeatedField(f("repeated_uint32" ), 0)); + Assert.assertEquals(204L , message.getRepeatedField(f("repeated_uint64" ), 0)); + Assert.assertEquals(205 , message.getRepeatedField(f("repeated_sint32" ), 0)); + Assert.assertEquals(206L , message.getRepeatedField(f("repeated_sint64" ), 0)); + Assert.assertEquals(207 , message.getRepeatedField(f("repeated_fixed32" ), 0)); + Assert.assertEquals(208L , message.getRepeatedField(f("repeated_fixed64" ), 0)); + Assert.assertEquals(209 , message.getRepeatedField(f("repeated_sfixed32"), 0)); + Assert.assertEquals(210L , message.getRepeatedField(f("repeated_sfixed64"), 0)); + Assert.assertEquals(211F , message.getRepeatedField(f("repeated_float" ), 0)); + Assert.assertEquals(212D , message.getRepeatedField(f("repeated_double" ), 0)); + Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool" ), 0)); + Assert.assertEquals("215", message.getRepeatedField(f("repeated_string" ), 0)); + Assert.assertEquals(toBytes("216"), message.getRepeatedField(f("repeated_bytes"), 0)); + + Assert.assertEquals(217, + ((Message)message.getRepeatedField(f("repeatedgroup"), 0)) + .getField(repeatedGroupA)); + Assert.assertEquals(218, + ((Message)message.getRepeatedField(f("repeated_nested_message"), 0)) + .getField(nestedB)); + Assert.assertEquals(219, + ((Message)message.getRepeatedField(f("repeated_foreign_message"), 0)) + .getField(foreignC)); + Assert.assertEquals(220, + ((Message)message.getRepeatedField(f("repeated_import_message"), 0)) + .getField(importD)); + Assert.assertEquals(227, + ((Message)message.getRepeatedField(f("repeated_lazy_message"), 0)) + .getField(nestedB)); + + Assert.assertEquals( nestedBar, message.getRepeatedField(f("repeated_nested_enum" ),0)); + Assert.assertEquals(foreignBar, message.getRepeatedField(f("repeated_foreign_enum"),0)); + Assert.assertEquals( importBar, message.getRepeatedField(f("repeated_import_enum" ),0)); + + Assert.assertEquals("224", message.getRepeatedField(f("repeated_string_piece"), 0)); + Assert.assertEquals("225", message.getRepeatedField(f("repeated_cord"), 0)); + + Assert.assertEquals(301 , message.getRepeatedField(f("repeated_int32" ), 1)); + Assert.assertEquals(302L , message.getRepeatedField(f("repeated_int64" ), 1)); + Assert.assertEquals(303 , message.getRepeatedField(f("repeated_uint32" ), 1)); + Assert.assertEquals(304L , message.getRepeatedField(f("repeated_uint64" ), 1)); + Assert.assertEquals(305 , message.getRepeatedField(f("repeated_sint32" ), 1)); + Assert.assertEquals(306L , message.getRepeatedField(f("repeated_sint64" ), 1)); + Assert.assertEquals(307 , message.getRepeatedField(f("repeated_fixed32" ), 1)); + Assert.assertEquals(308L , message.getRepeatedField(f("repeated_fixed64" ), 1)); + Assert.assertEquals(309 , message.getRepeatedField(f("repeated_sfixed32"), 1)); + Assert.assertEquals(310L , message.getRepeatedField(f("repeated_sfixed64"), 1)); + Assert.assertEquals(311F , message.getRepeatedField(f("repeated_float" ), 1)); + Assert.assertEquals(312D , message.getRepeatedField(f("repeated_double" ), 1)); + Assert.assertEquals(false, message.getRepeatedField(f("repeated_bool" ), 1)); + Assert.assertEquals("315", message.getRepeatedField(f("repeated_string" ), 1)); + Assert.assertEquals(toBytes("316"), message.getRepeatedField(f("repeated_bytes"), 1)); + + Assert.assertEquals(317, + ((Message)message.getRepeatedField(f("repeatedgroup"), 1)) + .getField(repeatedGroupA)); + Assert.assertEquals(318, + ((Message)message.getRepeatedField(f("repeated_nested_message"), 1)) + .getField(nestedB)); + Assert.assertEquals(319, + ((Message)message.getRepeatedField(f("repeated_foreign_message"), 1)) + .getField(foreignC)); + Assert.assertEquals(320, + ((Message)message.getRepeatedField(f("repeated_import_message"), 1)) + .getField(importD)); + Assert.assertEquals(327, + ((Message)message.getRepeatedField(f("repeated_lazy_message"), 1)) + .getField(nestedB)); + + Assert.assertEquals( nestedBaz, message.getRepeatedField(f("repeated_nested_enum" ),1)); + Assert.assertEquals(foreignBaz, message.getRepeatedField(f("repeated_foreign_enum"),1)); + Assert.assertEquals( importBaz, message.getRepeatedField(f("repeated_import_enum" ),1)); + + Assert.assertEquals("324", message.getRepeatedField(f("repeated_string_piece"), 1)); + Assert.assertEquals("325", message.getRepeatedField(f("repeated_cord"), 1)); + + // ----------------------------------------------------------------- + + Assert.assertTrue(message.hasField(f("default_int32" ))); + Assert.assertTrue(message.hasField(f("default_int64" ))); + Assert.assertTrue(message.hasField(f("default_uint32" ))); + Assert.assertTrue(message.hasField(f("default_uint64" ))); + Assert.assertTrue(message.hasField(f("default_sint32" ))); + Assert.assertTrue(message.hasField(f("default_sint64" ))); + Assert.assertTrue(message.hasField(f("default_fixed32" ))); + Assert.assertTrue(message.hasField(f("default_fixed64" ))); + Assert.assertTrue(message.hasField(f("default_sfixed32"))); + Assert.assertTrue(message.hasField(f("default_sfixed64"))); + Assert.assertTrue(message.hasField(f("default_float" ))); + Assert.assertTrue(message.hasField(f("default_double" ))); + Assert.assertTrue(message.hasField(f("default_bool" ))); + Assert.assertTrue(message.hasField(f("default_string" ))); + Assert.assertTrue(message.hasField(f("default_bytes" ))); + + Assert.assertTrue(message.hasField(f("default_nested_enum" ))); + Assert.assertTrue(message.hasField(f("default_foreign_enum"))); + Assert.assertTrue(message.hasField(f("default_import_enum" ))); + + Assert.assertTrue(message.hasField(f("default_string_piece"))); + Assert.assertTrue(message.hasField(f("default_cord"))); + + Assert.assertEquals(401 , message.getField(f("default_int32" ))); + Assert.assertEquals(402L , message.getField(f("default_int64" ))); + Assert.assertEquals(403 , message.getField(f("default_uint32" ))); + Assert.assertEquals(404L , message.getField(f("default_uint64" ))); + Assert.assertEquals(405 , message.getField(f("default_sint32" ))); + Assert.assertEquals(406L , message.getField(f("default_sint64" ))); + Assert.assertEquals(407 , message.getField(f("default_fixed32" ))); + Assert.assertEquals(408L , message.getField(f("default_fixed64" ))); + Assert.assertEquals(409 , message.getField(f("default_sfixed32"))); + Assert.assertEquals(410L , message.getField(f("default_sfixed64"))); + Assert.assertEquals(411F , message.getField(f("default_float" ))); + Assert.assertEquals(412D , message.getField(f("default_double" ))); + Assert.assertEquals(false, message.getField(f("default_bool" ))); + Assert.assertEquals("415", message.getField(f("default_string" ))); + Assert.assertEquals(toBytes("416"), message.getField(f("default_bytes"))); + + Assert.assertEquals( nestedFoo, message.getField(f("default_nested_enum" ))); + Assert.assertEquals(foreignFoo, message.getField(f("default_foreign_enum"))); + Assert.assertEquals( importFoo, message.getField(f("default_import_enum" ))); + + Assert.assertEquals("424", message.getField(f("default_string_piece"))); + Assert.assertEquals("425", message.getField(f("default_cord"))); + } + + // ------------------------------------------------------------------- + + /** + * Assert (using {@code junit.framework.Assert}} that all fields of + * {@code message} are cleared, and that getting the fields returns their + * default values, using the {@link Message} reflection interface. + */ + public void assertClearViaReflection(MessageOrBuilder message) { + // has_blah() should initially be false for all optional fields. + Assert.assertFalse(message.hasField(f("optional_int32" ))); + Assert.assertFalse(message.hasField(f("optional_int64" ))); + Assert.assertFalse(message.hasField(f("optional_uint32" ))); + Assert.assertFalse(message.hasField(f("optional_uint64" ))); + Assert.assertFalse(message.hasField(f("optional_sint32" ))); + Assert.assertFalse(message.hasField(f("optional_sint64" ))); + Assert.assertFalse(message.hasField(f("optional_fixed32" ))); + Assert.assertFalse(message.hasField(f("optional_fixed64" ))); + Assert.assertFalse(message.hasField(f("optional_sfixed32"))); + Assert.assertFalse(message.hasField(f("optional_sfixed64"))); + Assert.assertFalse(message.hasField(f("optional_float" ))); + Assert.assertFalse(message.hasField(f("optional_double" ))); + Assert.assertFalse(message.hasField(f("optional_bool" ))); + Assert.assertFalse(message.hasField(f("optional_string" ))); + Assert.assertFalse(message.hasField(f("optional_bytes" ))); + + Assert.assertFalse(message.hasField(f("optionalgroup" ))); + Assert.assertFalse(message.hasField(f("optional_nested_message" ))); + Assert.assertFalse(message.hasField(f("optional_foreign_message"))); + Assert.assertFalse(message.hasField(f("optional_import_message" ))); + + Assert.assertFalse(message.hasField(f("optional_nested_enum" ))); + Assert.assertFalse(message.hasField(f("optional_foreign_enum"))); + Assert.assertFalse(message.hasField(f("optional_import_enum" ))); + + Assert.assertFalse(message.hasField(f("optional_string_piece"))); + Assert.assertFalse(message.hasField(f("optional_cord"))); + + // Optional fields without defaults are set to zero or something like it. + Assert.assertEquals(0 , message.getField(f("optional_int32" ))); + Assert.assertEquals(0L , message.getField(f("optional_int64" ))); + Assert.assertEquals(0 , message.getField(f("optional_uint32" ))); + Assert.assertEquals(0L , message.getField(f("optional_uint64" ))); + Assert.assertEquals(0 , message.getField(f("optional_sint32" ))); + Assert.assertEquals(0L , message.getField(f("optional_sint64" ))); + Assert.assertEquals(0 , message.getField(f("optional_fixed32" ))); + Assert.assertEquals(0L , message.getField(f("optional_fixed64" ))); + Assert.assertEquals(0 , message.getField(f("optional_sfixed32"))); + Assert.assertEquals(0L , message.getField(f("optional_sfixed64"))); + Assert.assertEquals(0F , message.getField(f("optional_float" ))); + Assert.assertEquals(0D , message.getField(f("optional_double" ))); + Assert.assertEquals(false, message.getField(f("optional_bool" ))); + Assert.assertEquals("" , message.getField(f("optional_string" ))); + Assert.assertEquals(ByteString.EMPTY, message.getField(f("optional_bytes"))); + + // Embedded messages should also be clear. + Assert.assertFalse( + ((Message)message.getField(f("optionalgroup"))).hasField(groupA)); + Assert.assertFalse( + ((Message)message.getField(f("optional_nested_message"))) + .hasField(nestedB)); + Assert.assertFalse( + ((Message)message.getField(f("optional_foreign_message"))) + .hasField(foreignC)); + Assert.assertFalse( + ((Message)message.getField(f("optional_import_message"))) + .hasField(importD)); + Assert.assertFalse( + ((Message)message.getField(f("optional_public_import_message"))) + .hasField(importE)); + Assert.assertFalse( + ((Message)message.getField(f("optional_lazy_message"))) + .hasField(nestedB)); + + Assert.assertEquals(0, + ((Message)message.getField(f("optionalgroup"))).getField(groupA)); + Assert.assertEquals(0, + ((Message)message.getField(f("optional_nested_message"))) + .getField(nestedB)); + Assert.assertEquals(0, + ((Message)message.getField(f("optional_foreign_message"))) + .getField(foreignC)); + Assert.assertEquals(0, + ((Message)message.getField(f("optional_import_message"))) + .getField(importD)); + Assert.assertEquals(0, + ((Message)message.getField(f("optional_public_import_message"))) + .getField(importE)); + Assert.assertEquals(0, + ((Message)message.getField(f("optional_lazy_message"))) + .getField(nestedB)); + + // Enums without defaults are set to the first value in the enum. + Assert.assertEquals( nestedFoo, message.getField(f("optional_nested_enum" ))); + Assert.assertEquals(foreignFoo, message.getField(f("optional_foreign_enum"))); + Assert.assertEquals( importFoo, message.getField(f("optional_import_enum" ))); + + Assert.assertEquals("", message.getField(f("optional_string_piece"))); + Assert.assertEquals("", message.getField(f("optional_cord"))); + + // Repeated fields are empty. + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_int32" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_int64" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_uint32" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_uint64" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sint32" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sint64" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_fixed32" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_fixed64" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sfixed32"))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sfixed64"))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_float" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_double" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_bool" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_string" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_bytes" ))); + + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeatedgroup" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_nested_message" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_foreign_message"))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_import_message" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_lazy_message" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_nested_enum" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_foreign_enum" ))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_import_enum" ))); + + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_string_piece"))); + Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_cord"))); + + // has_blah() should also be false for all default fields. + Assert.assertFalse(message.hasField(f("default_int32" ))); + Assert.assertFalse(message.hasField(f("default_int64" ))); + Assert.assertFalse(message.hasField(f("default_uint32" ))); + Assert.assertFalse(message.hasField(f("default_uint64" ))); + Assert.assertFalse(message.hasField(f("default_sint32" ))); + Assert.assertFalse(message.hasField(f("default_sint64" ))); + Assert.assertFalse(message.hasField(f("default_fixed32" ))); + Assert.assertFalse(message.hasField(f("default_fixed64" ))); + Assert.assertFalse(message.hasField(f("default_sfixed32"))); + Assert.assertFalse(message.hasField(f("default_sfixed64"))); + Assert.assertFalse(message.hasField(f("default_float" ))); + Assert.assertFalse(message.hasField(f("default_double" ))); + Assert.assertFalse(message.hasField(f("default_bool" ))); + Assert.assertFalse(message.hasField(f("default_string" ))); + Assert.assertFalse(message.hasField(f("default_bytes" ))); + + Assert.assertFalse(message.hasField(f("default_nested_enum" ))); + Assert.assertFalse(message.hasField(f("default_foreign_enum"))); + Assert.assertFalse(message.hasField(f("default_import_enum" ))); + + Assert.assertFalse(message.hasField(f("default_string_piece" ))); + Assert.assertFalse(message.hasField(f("default_cord" ))); + + // Fields with defaults have their default values (duh). + Assert.assertEquals( 41 , message.getField(f("default_int32" ))); + Assert.assertEquals( 42L , message.getField(f("default_int64" ))); + Assert.assertEquals( 43 , message.getField(f("default_uint32" ))); + Assert.assertEquals( 44L , message.getField(f("default_uint64" ))); + Assert.assertEquals(-45 , message.getField(f("default_sint32" ))); + Assert.assertEquals( 46L , message.getField(f("default_sint64" ))); + Assert.assertEquals( 47 , message.getField(f("default_fixed32" ))); + Assert.assertEquals( 48L , message.getField(f("default_fixed64" ))); + Assert.assertEquals( 49 , message.getField(f("default_sfixed32"))); + Assert.assertEquals(-50L , message.getField(f("default_sfixed64"))); + Assert.assertEquals( 51.5F , message.getField(f("default_float" ))); + Assert.assertEquals( 52e3D , message.getField(f("default_double" ))); + Assert.assertEquals(true , message.getField(f("default_bool" ))); + Assert.assertEquals("hello", message.getField(f("default_string" ))); + Assert.assertEquals(toBytes("world"), message.getField(f("default_bytes"))); + + Assert.assertEquals( nestedBar, message.getField(f("default_nested_enum" ))); + Assert.assertEquals(foreignBar, message.getField(f("default_foreign_enum"))); + Assert.assertEquals( importBar, message.getField(f("default_import_enum" ))); + + Assert.assertEquals("abc", message.getField(f("default_string_piece"))); + Assert.assertEquals("123", message.getField(f("default_cord"))); + } + + + // --------------------------------------------------------------- + + public void assertRepeatedFieldsModifiedViaReflection( + MessageOrBuilder message) { + // ModifyRepeatedFields only sets the second repeated element of each + // field. In addition to verifying this, we also verify that the first + // element and size were *not* modified. + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed32"))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed64"))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_float" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_double" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bool" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bytes" ))); + + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeatedgroup" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_message" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_message"))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_message" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_lazy_message" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_enum" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_enum" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_enum" ))); + + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string_piece"))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_cord"))); + + Assert.assertEquals(201 , message.getRepeatedField(f("repeated_int32" ), 0)); + Assert.assertEquals(202L , message.getRepeatedField(f("repeated_int64" ), 0)); + Assert.assertEquals(203 , message.getRepeatedField(f("repeated_uint32" ), 0)); + Assert.assertEquals(204L , message.getRepeatedField(f("repeated_uint64" ), 0)); + Assert.assertEquals(205 , message.getRepeatedField(f("repeated_sint32" ), 0)); + Assert.assertEquals(206L , message.getRepeatedField(f("repeated_sint64" ), 0)); + Assert.assertEquals(207 , message.getRepeatedField(f("repeated_fixed32" ), 0)); + Assert.assertEquals(208L , message.getRepeatedField(f("repeated_fixed64" ), 0)); + Assert.assertEquals(209 , message.getRepeatedField(f("repeated_sfixed32"), 0)); + Assert.assertEquals(210L , message.getRepeatedField(f("repeated_sfixed64"), 0)); + Assert.assertEquals(211F , message.getRepeatedField(f("repeated_float" ), 0)); + Assert.assertEquals(212D , message.getRepeatedField(f("repeated_double" ), 0)); + Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool" ), 0)); + Assert.assertEquals("215", message.getRepeatedField(f("repeated_string" ), 0)); + Assert.assertEquals(toBytes("216"), message.getRepeatedField(f("repeated_bytes"), 0)); + + Assert.assertEquals(217, + ((Message)message.getRepeatedField(f("repeatedgroup"), 0)) + .getField(repeatedGroupA)); + Assert.assertEquals(218, + ((Message)message.getRepeatedField(f("repeated_nested_message"), 0)) + .getField(nestedB)); + Assert.assertEquals(219, + ((Message)message.getRepeatedField(f("repeated_foreign_message"), 0)) + .getField(foreignC)); + Assert.assertEquals(220, + ((Message)message.getRepeatedField(f("repeated_import_message"), 0)) + .getField(importD)); + Assert.assertEquals(227, + ((Message)message.getRepeatedField(f("repeated_lazy_message"), 0)) + .getField(nestedB)); + + Assert.assertEquals( nestedBar, message.getRepeatedField(f("repeated_nested_enum" ),0)); + Assert.assertEquals(foreignBar, message.getRepeatedField(f("repeated_foreign_enum"),0)); + Assert.assertEquals( importBar, message.getRepeatedField(f("repeated_import_enum" ),0)); + + Assert.assertEquals("224", message.getRepeatedField(f("repeated_string_piece"), 0)); + Assert.assertEquals("225", message.getRepeatedField(f("repeated_cord"), 0)); + + Assert.assertEquals(501 , message.getRepeatedField(f("repeated_int32" ), 1)); + Assert.assertEquals(502L , message.getRepeatedField(f("repeated_int64" ), 1)); + Assert.assertEquals(503 , message.getRepeatedField(f("repeated_uint32" ), 1)); + Assert.assertEquals(504L , message.getRepeatedField(f("repeated_uint64" ), 1)); + Assert.assertEquals(505 , message.getRepeatedField(f("repeated_sint32" ), 1)); + Assert.assertEquals(506L , message.getRepeatedField(f("repeated_sint64" ), 1)); + Assert.assertEquals(507 , message.getRepeatedField(f("repeated_fixed32" ), 1)); + Assert.assertEquals(508L , message.getRepeatedField(f("repeated_fixed64" ), 1)); + Assert.assertEquals(509 , message.getRepeatedField(f("repeated_sfixed32"), 1)); + Assert.assertEquals(510L , message.getRepeatedField(f("repeated_sfixed64"), 1)); + Assert.assertEquals(511F , message.getRepeatedField(f("repeated_float" ), 1)); + Assert.assertEquals(512D , message.getRepeatedField(f("repeated_double" ), 1)); + Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool" ), 1)); + Assert.assertEquals("515", message.getRepeatedField(f("repeated_string" ), 1)); + Assert.assertEquals(toBytes("516"), message.getRepeatedField(f("repeated_bytes"), 1)); + + Assert.assertEquals(517, + ((Message)message.getRepeatedField(f("repeatedgroup"), 1)) + .getField(repeatedGroupA)); + Assert.assertEquals(518, + ((Message)message.getRepeatedField(f("repeated_nested_message"), 1)) + .getField(nestedB)); + Assert.assertEquals(519, + ((Message)message.getRepeatedField(f("repeated_foreign_message"), 1)) + .getField(foreignC)); + Assert.assertEquals(520, + ((Message)message.getRepeatedField(f("repeated_import_message"), 1)) + .getField(importD)); + Assert.assertEquals(527, + ((Message)message.getRepeatedField(f("repeated_lazy_message"), 1)) + .getField(nestedB)); + + Assert.assertEquals( nestedFoo, message.getRepeatedField(f("repeated_nested_enum" ),1)); + Assert.assertEquals(foreignFoo, message.getRepeatedField(f("repeated_foreign_enum"),1)); + Assert.assertEquals( importFoo, message.getRepeatedField(f("repeated_import_enum" ),1)); + + Assert.assertEquals("524", message.getRepeatedField(f("repeated_string_piece"), 1)); + Assert.assertEquals("525", message.getRepeatedField(f("repeated_cord"), 1)); + } + + public void setPackedFieldsViaReflection(Message.Builder message) { + message.addRepeatedField(f("packed_int32" ), 601 ); + message.addRepeatedField(f("packed_int64" ), 602L); + message.addRepeatedField(f("packed_uint32" ), 603 ); + message.addRepeatedField(f("packed_uint64" ), 604L); + message.addRepeatedField(f("packed_sint32" ), 605 ); + message.addRepeatedField(f("packed_sint64" ), 606L); + message.addRepeatedField(f("packed_fixed32" ), 607 ); + message.addRepeatedField(f("packed_fixed64" ), 608L); + message.addRepeatedField(f("packed_sfixed32"), 609 ); + message.addRepeatedField(f("packed_sfixed64"), 610L); + message.addRepeatedField(f("packed_float" ), 611F); + message.addRepeatedField(f("packed_double" ), 612D); + message.addRepeatedField(f("packed_bool" ), true); + message.addRepeatedField(f("packed_enum" ), foreignBar); + // Add a second one of each field. + message.addRepeatedField(f("packed_int32" ), 701 ); + message.addRepeatedField(f("packed_int64" ), 702L); + message.addRepeatedField(f("packed_uint32" ), 703 ); + message.addRepeatedField(f("packed_uint64" ), 704L); + message.addRepeatedField(f("packed_sint32" ), 705 ); + message.addRepeatedField(f("packed_sint64" ), 706L); + message.addRepeatedField(f("packed_fixed32" ), 707 ); + message.addRepeatedField(f("packed_fixed64" ), 708L); + message.addRepeatedField(f("packed_sfixed32"), 709 ); + message.addRepeatedField(f("packed_sfixed64"), 710L); + message.addRepeatedField(f("packed_float" ), 711F); + message.addRepeatedField(f("packed_double" ), 712D); + message.addRepeatedField(f("packed_bool" ), false); + message.addRepeatedField(f("packed_enum" ), foreignBaz); + } + + public void assertPackedFieldsSetViaReflection(MessageOrBuilder message) { + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_uint32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_uint64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sint32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sint64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_fixed32" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_fixed64" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sfixed32"))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sfixed64"))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_float" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_double" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_bool" ))); + Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_enum" ))); + Assert.assertEquals(601 , message.getRepeatedField(f("packed_int32" ), 0)); + Assert.assertEquals(602L , message.getRepeatedField(f("packed_int64" ), 0)); + Assert.assertEquals(603 , message.getRepeatedField(f("packed_uint32" ), 0)); + Assert.assertEquals(604L , message.getRepeatedField(f("packed_uint64" ), 0)); + Assert.assertEquals(605 , message.getRepeatedField(f("packed_sint32" ), 0)); + Assert.assertEquals(606L , message.getRepeatedField(f("packed_sint64" ), 0)); + Assert.assertEquals(607 , message.getRepeatedField(f("packed_fixed32" ), 0)); + Assert.assertEquals(608L , message.getRepeatedField(f("packed_fixed64" ), 0)); + Assert.assertEquals(609 , message.getRepeatedField(f("packed_sfixed32"), 0)); + Assert.assertEquals(610L , message.getRepeatedField(f("packed_sfixed64"), 0)); + Assert.assertEquals(611F , message.getRepeatedField(f("packed_float" ), 0)); + Assert.assertEquals(612D , message.getRepeatedField(f("packed_double" ), 0)); + Assert.assertEquals(true , message.getRepeatedField(f("packed_bool" ), 0)); + Assert.assertEquals(foreignBar, message.getRepeatedField(f("packed_enum" ),0)); + Assert.assertEquals(701 , message.getRepeatedField(f("packed_int32" ), 1)); + Assert.assertEquals(702L , message.getRepeatedField(f("packed_int64" ), 1)); + Assert.assertEquals(703 , message.getRepeatedField(f("packed_uint32" ), 1)); + Assert.assertEquals(704L , message.getRepeatedField(f("packed_uint64" ), 1)); + Assert.assertEquals(705 , message.getRepeatedField(f("packed_sint32" ), 1)); + Assert.assertEquals(706L , message.getRepeatedField(f("packed_sint64" ), 1)); + Assert.assertEquals(707 , message.getRepeatedField(f("packed_fixed32" ), 1)); + Assert.assertEquals(708L , message.getRepeatedField(f("packed_fixed64" ), 1)); + Assert.assertEquals(709 , message.getRepeatedField(f("packed_sfixed32"), 1)); + Assert.assertEquals(710L , message.getRepeatedField(f("packed_sfixed64"), 1)); + Assert.assertEquals(711F , message.getRepeatedField(f("packed_float" ), 1)); + Assert.assertEquals(712D , message.getRepeatedField(f("packed_double" ), 1)); + Assert.assertEquals(false, message.getRepeatedField(f("packed_bool" ), 1)); + Assert.assertEquals(foreignBaz, message.getRepeatedField(f("packed_enum" ),1)); + } + + /** + * Verifies that the reflection setters for the given.Builder object throw a + * NullPointerException if they are passed a null value. Uses Assert to throw an + * appropriate assertion failure, if the condition is not verified. + */ + public void assertReflectionSettersRejectNull(Message.Builder builder) + throws Exception { + try { + builder.setField(f("optional_string"), null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.setField(f("optional_bytes"), null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.setField(f("optional_nested_enum"), null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.setField(f("optional_nested_message"), + (TestAllTypes.NestedMessage) null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.setField(f("optional_nested_message"), + (TestAllTypes.NestedMessage.Builder) null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + + try { + builder.addRepeatedField(f("repeated_string"), null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.addRepeatedField(f("repeated_bytes"), null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.addRepeatedField(f("repeated_nested_enum"), null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + try { + builder.addRepeatedField(f("repeated_nested_message"), null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + } + + /** + * Verifies that the reflection repeated setters for the given Builder object throw a + * NullPointerException if they are passed a null value. Uses Assert to throw an appropriate + * assertion failure, if the condition is not verified. + */ + public void assertReflectionRepeatedSettersRejectNull(Message.Builder builder) + throws Exception { + builder.addRepeatedField(f("repeated_string"), "one"); + try { + builder.setRepeatedField(f("repeated_string"), 0, null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + + builder.addRepeatedField(f("repeated_bytes"), toBytes("one")); + try { + builder.setRepeatedField(f("repeated_bytes"), 0, null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + + builder.addRepeatedField(f("repeated_nested_enum"), nestedBaz); + try { + builder.setRepeatedField(f("repeated_nested_enum"), 0, null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + + builder.addRepeatedField( + f("repeated_nested_message"), + TestAllTypes.NestedMessage.newBuilder().setBb(218).build()); + try { + builder.setRepeatedField(f("repeated_nested_message"), 0, null); + Assert.fail("Exception was not thrown"); + } catch (NullPointerException e) { + // We expect this exception. + } + } + } + + /** + * @param filePath The path relative to + * {@link #getTestDataDir}. + */ + public static String readTextFromFile(String filePath) { + return readBytesFromFile(filePath).toStringUtf8(); + } + + private static File getTestDataDir() { + // Search each parent directory looking for "src/google/protobuf". + File ancestor = new File("."); + try { + ancestor = ancestor.getCanonicalFile(); + } catch (IOException e) { + throw new RuntimeException( + "Couldn't get canonical name of working directory.", e); + } + while (ancestor != null && ancestor.exists()) { + if (new File(ancestor, "src/google/protobuf").exists()) { + return new File(ancestor, "src/google/protobuf/testdata"); + } + ancestor = ancestor.getParentFile(); + } + + throw new RuntimeException( + "Could not find golden files. This test must be run from within the " + + "protobuf source package so that it can read test data files from the " + + "C++ source tree."); + } + + /** + * @param filename The path relative to + * {@link #getTestDataDir}. + */ + public static ByteString readBytesFromFile(String filename) { + File fullPath = new File(getTestDataDir(), filename); + try { + RandomAccessFile file = new RandomAccessFile(fullPath, "r"); + byte[] content = new byte[(int) file.length()]; + file.readFully(content); + return ByteString.copyFrom(content); + } catch (IOException e) { + // Throw a RuntimeException here so that we can call this function from + // static initializers. + throw new IllegalArgumentException( + "Couldn't read file: " + fullPath.getPath(), e); + } + } + + /** + * Get the bytes of the "golden message". This is a serialized TestAllTypes + * with all fields set as they would be by + * {@link #setAllFields(TestAllTypes.Builder)}, but it is loaded from a file + * on disk rather than generated dynamically. The file is actually generated + * by C++ code, so testing against it verifies compatibility with C++. + */ + public static ByteString getGoldenMessage() { + if (goldenMessage == null) { + goldenMessage = readBytesFromFile("golden_message"); + } + return goldenMessage; + } + private static ByteString goldenMessage = null; + + /** + * Get the bytes of the "golden packed fields message". This is a serialized + * TestPackedTypes with all fields set as they would be by + * {@link #setPackedFields(TestPackedTypes.Builder)}, but it is loaded from a + * file on disk rather than generated dynamically. The file is actually + * generated by C++ code, so testing against it verifies compatibility with + * C++. + */ + public static ByteString getGoldenPackedFieldsMessage() { + if (goldenPackedFieldsMessage == null) { + goldenPackedFieldsMessage = + readBytesFromFile("golden_packed_fields_message"); + } + return goldenPackedFieldsMessage; + } + private static ByteString goldenPackedFieldsMessage = null; + + /** + * Mock implementation of {@link GeneratedMessage.BuilderParent} for testing. + * + * @author jonp@google.com (Jon Perlow) + */ + public static class MockBuilderParent + implements GeneratedMessage.BuilderParent { + + private int invalidations; + + //@Override (Java 1.6 override semantics, but we must support 1.5) + public void markDirty() { + invalidations++; + } + + public int getInvalidationCount() { + return invalidations; + } + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TextFormatTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TextFormatTest.java new file mode 100644 index 0000000..5323d70 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/TextFormatTest.java @@ -0,0 +1,786 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import com.google.protobuf.Descriptors.FieldDescriptor; +import protobuf_unittest.UnittestMset.TestMessageSet; +import protobuf_unittest.UnittestMset.TestMessageSetExtension1; +import protobuf_unittest.UnittestMset.TestMessageSetExtension2; +import protobuf_unittest.UnittestProto.OneString; +import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage; +import protobuf_unittest.UnittestProto.TestEmptyMessage; + +import junit.framework.TestCase; + +import java.io.StringReader; + +/** + * Test case for {@link TextFormat}. + * + * TODO(wenboz): ExtensionTest and rest of text_format_unittest.cc. + * + * @author wenboz@google.com (Wenbo Zhu) + */ +public class TextFormatTest extends TestCase { + + // A basic string with different escapable characters for testing. + private final static String kEscapeTestString = + "\"A string with ' characters \n and \r newlines and \t tabs and \001 " + + "slashes \\"; + + // A representation of the above string with all the characters escaped. + private final static String kEscapeTestStringEscaped = + "\\\"A string with \\' characters \\n and \\r newlines " + + "and \\t tabs and \\001 slashes \\\\"; + + private static String allFieldsSetText = TestUtil.readTextFromFile( + "text_format_unittest_data.txt"); + private static String allExtensionsSetText = TestUtil.readTextFromFile( + "text_format_unittest_extensions_data.txt"); + + private static String exoticText = + "repeated_int32: -1\n" + + "repeated_int32: -2147483648\n" + + "repeated_int64: -1\n" + + "repeated_int64: -9223372036854775808\n" + + "repeated_uint32: 4294967295\n" + + "repeated_uint32: 2147483648\n" + + "repeated_uint64: 18446744073709551615\n" + + "repeated_uint64: 9223372036854775808\n" + + "repeated_double: 123.0\n" + + "repeated_double: 123.5\n" + + "repeated_double: 0.125\n" + + "repeated_double: .125\n" + + "repeated_double: -.125\n" + + "repeated_double: 1.23E17\n" + + "repeated_double: 1.23E+17\n" + + "repeated_double: -1.23e-17\n" + + "repeated_double: .23e+17\n" + + "repeated_double: -.23E17\n" + + "repeated_double: 1.235E22\n" + + "repeated_double: 1.235E-18\n" + + "repeated_double: 123.456789\n" + + "repeated_double: Infinity\n" + + "repeated_double: -Infinity\n" + + "repeated_double: NaN\n" + + "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"" + + "\\341\\210\\264\"\n" + + "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n"; + + private static String canonicalExoticText = + exoticText.replace(": .", ": 0.").replace(": -.", ": -0.") // short-form double + .replace("23e", "23E").replace("E+", "E").replace("0.23E17", "2.3E16"); + + private String messageSetText = + "[protobuf_unittest.TestMessageSetExtension1] {\n" + + " i: 123\n" + + "}\n" + + "[protobuf_unittest.TestMessageSetExtension2] {\n" + + " str: \"foo\"\n" + + "}\n"; + + /** Print TestAllTypes and compare with golden file. */ + public void testPrintMessage() throws Exception { + String javaText = TextFormat.printToString(TestUtil.getAllSet()); + + // Java likes to add a trailing ".0" to floats and doubles. C printf + // (with %g format) does not. Our golden files are used for both + // C++ and Java TextFormat classes, so we need to conform. + javaText = javaText.replace(".0\n", "\n"); + + assertEquals(allFieldsSetText, javaText); + } + + /** Print TestAllTypes as Builder and compare with golden file. */ + public void testPrintMessageBuilder() throws Exception { + String javaText = TextFormat.printToString(TestUtil.getAllSetBuilder()); + + // Java likes to add a trailing ".0" to floats and doubles. C printf + // (with %g format) does not. Our golden files are used for both + // C++ and Java TextFormat classes, so we need to conform. + javaText = javaText.replace(".0\n", "\n"); + + assertEquals(allFieldsSetText, javaText); + } + + /** Print TestAllExtensions and compare with golden file. */ + public void testPrintExtensions() throws Exception { + String javaText = TextFormat.printToString(TestUtil.getAllExtensionsSet()); + + // Java likes to add a trailing ".0" to floats and doubles. C printf + // (with %g format) does not. Our golden files are used for both + // C++ and Java TextFormat classes, so we need to conform. + javaText = javaText.replace(".0\n", "\n"); + + assertEquals(allExtensionsSetText, javaText); + } + + // Creates an example unknown field set. + private UnknownFieldSet makeUnknownFieldSet() { + return UnknownFieldSet.newBuilder() + .addField(5, + UnknownFieldSet.Field.newBuilder() + .addVarint(1) + .addFixed32(2) + .addFixed64(3) + .addLengthDelimited(ByteString.copyFromUtf8("4")) + .addGroup( + UnknownFieldSet.newBuilder() + .addField(10, + UnknownFieldSet.Field.newBuilder() + .addVarint(5) + .build()) + .build()) + .build()) + .addField(8, + UnknownFieldSet.Field.newBuilder() + .addVarint(1) + .addVarint(2) + .addVarint(3) + .build()) + .addField(15, + UnknownFieldSet.Field.newBuilder() + .addVarint(0xABCDEF1234567890L) + .addFixed32(0xABCD1234) + .addFixed64(0xABCDEF1234567890L) + .build()) + .build(); + } + + public void testPrintUnknownFields() throws Exception { + // Test printing of unknown fields in a message. + + TestEmptyMessage message = + TestEmptyMessage.newBuilder() + .setUnknownFields(makeUnknownFieldSet()) + .build(); + + assertEquals( + "5: 1\n" + + "5: 0x00000002\n" + + "5: 0x0000000000000003\n" + + "5: \"4\"\n" + + "5 {\n" + + " 10: 5\n" + + "}\n" + + "8: 1\n" + + "8: 2\n" + + "8: 3\n" + + "15: 12379813812177893520\n" + + "15: 0xabcd1234\n" + + "15: 0xabcdef1234567890\n", + TextFormat.printToString(message)); + } + + public void testPrintField() throws Exception { + final FieldDescriptor dataField = + OneString.getDescriptor().findFieldByName("data"); + assertEquals( + "data: \"test data\"\n", + TextFormat.printFieldToString(dataField, "test data")); + + final FieldDescriptor optionalField = + TestAllTypes.getDescriptor().findFieldByName("optional_nested_message"); + final Object value = NestedMessage.newBuilder().setBb(42).build(); + + assertEquals( + "optional_nested_message {\n bb: 42\n}\n", + TextFormat.printFieldToString(optionalField, value)); + } + + /** + * Helper to construct a ByteString from a String containing only 8-bit + * characters. The characters are converted directly to bytes, *not* + * encoded using UTF-8. + */ + private ByteString bytes(String str) throws Exception { + return ByteString.copyFrom(str.getBytes("ISO-8859-1")); + } + + /** + * Helper to construct a ByteString from a bunch of bytes. The inputs are + * actually ints so that I can use hex notation and not get stupid errors + * about precision. + */ + private ByteString bytes(int... bytesAsInts) { + byte[] bytes = new byte[bytesAsInts.length]; + for (int i = 0; i < bytesAsInts.length; i++) { + bytes[i] = (byte) bytesAsInts[i]; + } + return ByteString.copyFrom(bytes); + } + + public void testPrintExotic() throws Exception { + Message message = TestAllTypes.newBuilder() + // Signed vs. unsigned numbers. + .addRepeatedInt32 (-1) + .addRepeatedUint32(-1) + .addRepeatedInt64 (-1) + .addRepeatedUint64(-1) + + .addRepeatedInt32 (1 << 31) + .addRepeatedUint32(1 << 31) + .addRepeatedInt64 (1l << 63) + .addRepeatedUint64(1l << 63) + + // Floats of various precisions and exponents. + .addRepeatedDouble(123) + .addRepeatedDouble(123.5) + .addRepeatedDouble(0.125) + .addRepeatedDouble(.125) + .addRepeatedDouble(-.125) + .addRepeatedDouble(123e15) + .addRepeatedDouble(123e15) + .addRepeatedDouble(-1.23e-17) + .addRepeatedDouble(.23e17) + .addRepeatedDouble(-23e15) + .addRepeatedDouble(123.5e20) + .addRepeatedDouble(123.5e-20) + .addRepeatedDouble(123.456789) + .addRepeatedDouble(Double.POSITIVE_INFINITY) + .addRepeatedDouble(Double.NEGATIVE_INFINITY) + .addRepeatedDouble(Double.NaN) + + // Strings and bytes that needing escaping. + .addRepeatedString("\0\001\007\b\f\n\r\t\013\\\'\"\u1234") + .addRepeatedBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"\u00fe")) + .build(); + + assertEquals(canonicalExoticText, message.toString()); + } + + public void testPrintMessageSet() throws Exception { + TestMessageSet messageSet = + TestMessageSet.newBuilder() + .setExtension( + TestMessageSetExtension1.messageSetExtension, + TestMessageSetExtension1.newBuilder().setI(123).build()) + .setExtension( + TestMessageSetExtension2.messageSetExtension, + TestMessageSetExtension2.newBuilder().setStr("foo").build()) + .build(); + + assertEquals(messageSetText, messageSet.toString()); + } + + // ================================================================= + + public void testParse() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge(allFieldsSetText, builder); + TestUtil.assertAllFieldsSet(builder.build()); + } + + public void testParseReader() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge(new StringReader(allFieldsSetText), builder); + TestUtil.assertAllFieldsSet(builder.build()); + } + + public void testParseExtensions() throws Exception { + TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); + TextFormat.merge(allExtensionsSetText, + TestUtil.getExtensionRegistry(), + builder); + TestUtil.assertAllExtensionsSet(builder.build()); + } + + public void testParseCompatibility() throws Exception { + String original = "repeated_float: inf\n" + + "repeated_float: -inf\n" + + "repeated_float: nan\n" + + "repeated_float: inff\n" + + "repeated_float: -inff\n" + + "repeated_float: nanf\n" + + "repeated_float: 1.0f\n" + + "repeated_float: infinityf\n" + + "repeated_float: -Infinityf\n" + + "repeated_double: infinity\n" + + "repeated_double: -infinity\n" + + "repeated_double: nan\n"; + String canonical = "repeated_float: Infinity\n" + + "repeated_float: -Infinity\n" + + "repeated_float: NaN\n" + + "repeated_float: Infinity\n" + + "repeated_float: -Infinity\n" + + "repeated_float: NaN\n" + + "repeated_float: 1.0\n" + + "repeated_float: Infinity\n" + + "repeated_float: -Infinity\n" + + "repeated_double: Infinity\n" + + "repeated_double: -Infinity\n" + + "repeated_double: NaN\n"; + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge(original, builder); + assertEquals(canonical, builder.build().toString()); + } + + public void testParseExotic() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge(exoticText, builder); + + // Too lazy to check things individually. Don't try to debug this + // if testPrintExotic() is failing. + assertEquals(canonicalExoticText, builder.build().toString()); + } + + public void testParseMessageSet() throws Exception { + ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); + extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); + extensionRegistry.add(TestMessageSetExtension2.messageSetExtension); + + TestMessageSet.Builder builder = TestMessageSet.newBuilder(); + TextFormat.merge(messageSetText, extensionRegistry, builder); + TestMessageSet messageSet = builder.build(); + + assertTrue(messageSet.hasExtension( + TestMessageSetExtension1.messageSetExtension)); + assertEquals(123, messageSet.getExtension( + TestMessageSetExtension1.messageSetExtension).getI()); + assertTrue(messageSet.hasExtension( + TestMessageSetExtension2.messageSetExtension)); + assertEquals("foo", messageSet.getExtension( + TestMessageSetExtension2.messageSetExtension).getStr()); + } + + public void testParseNumericEnum() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge("optional_nested_enum: 2", builder); + assertEquals(TestAllTypes.NestedEnum.BAR, builder.getOptionalNestedEnum()); + } + + public void testParseAngleBrackets() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge("OptionalGroup: < a: 1 >", builder); + assertTrue(builder.hasOptionalGroup()); + assertEquals(1, builder.getOptionalGroup().getA()); + } + + public void testParseComment() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge( + "# this is a comment\n" + + "optional_int32: 1 # another comment\n" + + "optional_int64: 2\n" + + "# EOF comment", builder); + assertEquals(1, builder.getOptionalInt32()); + assertEquals(2, builder.getOptionalInt64()); + } + + private void assertParseError(String error, String text) { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + try { + TextFormat.merge(text, TestUtil.getExtensionRegistry(), builder); + fail("Expected parse exception."); + } catch (TextFormat.ParseException e) { + assertEquals(error, e.getMessage()); + } + } + + public void testParseErrors() throws Exception { + assertParseError( + "1:16: Expected \":\".", + "optional_int32 123"); + assertParseError( + "1:23: Expected identifier.", + "optional_nested_enum: ?"); + assertParseError( + "1:18: Couldn't parse integer: Number must be positive: -1", + "optional_uint32: -1"); + assertParseError( + "1:17: Couldn't parse integer: Number out of range for 32-bit signed " + + "integer: 82301481290849012385230157", + "optional_int32: 82301481290849012385230157"); + assertParseError( + "1:16: Expected \"true\" or \"false\".", + "optional_bool: maybe"); + assertParseError( + "1:16: Expected \"true\" or \"false\".", + "optional_bool: 2"); + assertParseError( + "1:18: Expected string.", + "optional_string: 123"); + assertParseError( + "1:18: String missing ending quote.", + "optional_string: \"ueoauaoe"); + assertParseError( + "1:18: String missing ending quote.", + "optional_string: \"ueoauaoe\n" + + "optional_int32: 123"); + assertParseError( + "1:18: Invalid escape sequence: '\\z'", + "optional_string: \"\\z\""); + assertParseError( + "1:18: String missing ending quote.", + "optional_string: \"ueoauaoe\n" + + "optional_int32: 123"); + assertParseError( + "1:2: Extension \"nosuchext\" not found in the ExtensionRegistry.", + "[nosuchext]: 123"); + assertParseError( + "1:20: Extension \"protobuf_unittest.optional_int32_extension\" does " + + "not extend message type \"protobuf_unittest.TestAllTypes\".", + "[protobuf_unittest.optional_int32_extension]: 123"); + assertParseError( + "1:1: Message type \"protobuf_unittest.TestAllTypes\" has no field " + + "named \"nosuchfield\".", + "nosuchfield: 123"); + assertParseError( + "1:21: Expected \">\".", + "OptionalGroup < a: 1"); + assertParseError( + "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " + + "value named \"NO_SUCH_VALUE\".", + "optional_nested_enum: NO_SUCH_VALUE"); + assertParseError( + "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " + + "value with number 123.", + "optional_nested_enum: 123"); + + // Delimiters must match. + assertParseError( + "1:22: Expected identifier.", + "OptionalGroup < a: 1 }"); + assertParseError( + "1:22: Expected identifier.", + "OptionalGroup { a: 1 >"); + } + + // ================================================================= + + public void testEscape() throws Exception { + // Escape sequences. + assertEquals("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"", + TextFormat.escapeBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\""))); + assertEquals("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"", + TextFormat.escapeText("\0\001\007\b\f\n\r\t\013\\\'\"")); + assertEquals(bytes("\0\001\007\b\f\n\r\t\013\\\'\""), + TextFormat.unescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"")); + assertEquals("\0\001\007\b\f\n\r\t\013\\\'\"", + TextFormat.unescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"")); + assertEquals(kEscapeTestStringEscaped, + TextFormat.escapeText(kEscapeTestString)); + assertEquals(kEscapeTestString, + TextFormat.unescapeText(kEscapeTestStringEscaped)); + + // Unicode handling. + assertEquals("\\341\\210\\264", TextFormat.escapeText("\u1234")); + assertEquals("\\341\\210\\264", + TextFormat.escapeBytes(bytes(0xe1, 0x88, 0xb4))); + assertEquals("\u1234", TextFormat.unescapeText("\\341\\210\\264")); + assertEquals(bytes(0xe1, 0x88, 0xb4), + TextFormat.unescapeBytes("\\341\\210\\264")); + assertEquals("\u1234", TextFormat.unescapeText("\\xe1\\x88\\xb4")); + assertEquals(bytes(0xe1, 0x88, 0xb4), + TextFormat.unescapeBytes("\\xe1\\x88\\xb4")); + + // Handling of strings with unescaped Unicode characters > 255. + final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c"; + ByteString zhByteString = ByteString.copyFromUtf8(zh); + assertEquals(zhByteString, TextFormat.unescapeBytes(zh)); + + // Errors. + try { + TextFormat.unescapeText("\\x"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + // success + } + + try { + TextFormat.unescapeText("\\z"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + // success + } + + try { + TextFormat.unescapeText("\\"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + // success + } + } + + public void testParseInteger() throws Exception { + assertEquals( 0, TextFormat.parseInt32( "0")); + assertEquals( 1, TextFormat.parseInt32( "1")); + assertEquals( -1, TextFormat.parseInt32( "-1")); + assertEquals( 12345, TextFormat.parseInt32( "12345")); + assertEquals( -12345, TextFormat.parseInt32( "-12345")); + assertEquals( 2147483647, TextFormat.parseInt32( "2147483647")); + assertEquals(-2147483648, TextFormat.parseInt32("-2147483648")); + + assertEquals( 0, TextFormat.parseUInt32( "0")); + assertEquals( 1, TextFormat.parseUInt32( "1")); + assertEquals( 12345, TextFormat.parseUInt32( "12345")); + assertEquals( 2147483647, TextFormat.parseUInt32("2147483647")); + assertEquals((int) 2147483648L, TextFormat.parseUInt32("2147483648")); + assertEquals((int) 4294967295L, TextFormat.parseUInt32("4294967295")); + + assertEquals( 0L, TextFormat.parseInt64( "0")); + assertEquals( 1L, TextFormat.parseInt64( "1")); + assertEquals( -1L, TextFormat.parseInt64( "-1")); + assertEquals( 12345L, TextFormat.parseInt64( "12345")); + assertEquals( -12345L, TextFormat.parseInt64( "-12345")); + assertEquals( 2147483647L, TextFormat.parseInt64( "2147483647")); + assertEquals(-2147483648L, TextFormat.parseInt64("-2147483648")); + assertEquals( 4294967295L, TextFormat.parseInt64( "4294967295")); + assertEquals( 4294967296L, TextFormat.parseInt64( "4294967296")); + assertEquals(9223372036854775807L, + TextFormat.parseInt64("9223372036854775807")); + assertEquals(-9223372036854775808L, + TextFormat.parseInt64("-9223372036854775808")); + + assertEquals( 0L, TextFormat.parseUInt64( "0")); + assertEquals( 1L, TextFormat.parseUInt64( "1")); + assertEquals( 12345L, TextFormat.parseUInt64( "12345")); + assertEquals( 2147483647L, TextFormat.parseUInt64( "2147483647")); + assertEquals( 4294967295L, TextFormat.parseUInt64( "4294967295")); + assertEquals( 4294967296L, TextFormat.parseUInt64( "4294967296")); + assertEquals(9223372036854775807L, + TextFormat.parseUInt64("9223372036854775807")); + assertEquals(-9223372036854775808L, + TextFormat.parseUInt64("9223372036854775808")); + assertEquals(-1L, TextFormat.parseUInt64("18446744073709551615")); + + // Hex + assertEquals(0x1234abcd, TextFormat.parseInt32("0x1234abcd")); + assertEquals(-0x1234abcd, TextFormat.parseInt32("-0x1234abcd")); + assertEquals(-1, TextFormat.parseUInt64("0xffffffffffffffff")); + assertEquals(0x7fffffffffffffffL, + TextFormat.parseInt64("0x7fffffffffffffff")); + + // Octal + assertEquals(01234567, TextFormat.parseInt32("01234567")); + + // Out-of-range + try { + TextFormat.parseInt32("2147483648"); + fail("Should have thrown an exception."); + } catch (NumberFormatException e) { + // success + } + + try { + TextFormat.parseInt32("-2147483649"); + fail("Should have thrown an exception."); + } catch (NumberFormatException e) { + // success + } + + try { + TextFormat.parseUInt32("4294967296"); + fail("Should have thrown an exception."); + } catch (NumberFormatException e) { + // success + } + + try { + TextFormat.parseUInt32("-1"); + fail("Should have thrown an exception."); + } catch (NumberFormatException e) { + // success + } + + try { + TextFormat.parseInt64("9223372036854775808"); + fail("Should have thrown an exception."); + } catch (NumberFormatException e) { + // success + } + + try { + TextFormat.parseInt64("-9223372036854775809"); + fail("Should have thrown an exception."); + } catch (NumberFormatException e) { + // success + } + + try { + TextFormat.parseUInt64("18446744073709551616"); + fail("Should have thrown an exception."); + } catch (NumberFormatException e) { + // success + } + + try { + TextFormat.parseUInt64("-1"); + fail("Should have thrown an exception."); + } catch (NumberFormatException e) { + // success + } + + // Not a number. + try { + TextFormat.parseInt32("abcd"); + fail("Should have thrown an exception."); + } catch (NumberFormatException e) { + // success + } + } + + public void testParseString() throws Exception { + final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c"; + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge("optional_string: \"" + zh + "\"", builder); + assertEquals(zh, builder.getOptionalString()); + } + + public void testParseLongString() throws Exception { + String longText = + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890123456789012345678901234567890"; + + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge("optional_string: \"" + longText + "\"", builder); + assertEquals(longText, builder.getOptionalString()); + } + + public void testParseBoolean() throws Exception { + String goodText = + "repeated_bool: t repeated_bool : 0\n" + + "repeated_bool :f repeated_bool:1"; + String goodTextCanonical = + "repeated_bool: true\n" + + "repeated_bool: false\n" + + "repeated_bool: false\n" + + "repeated_bool: true\n"; + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge(goodText, builder); + assertEquals(goodTextCanonical, builder.build().toString()); + + try { + TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder(); + TextFormat.merge("optional_bool:2", badBuilder); + fail("Should have thrown an exception."); + } catch (TextFormat.ParseException e) { + // success + } + try { + TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder(); + TextFormat.merge("optional_bool: foo", badBuilder); + fail("Should have thrown an exception."); + } catch (TextFormat.ParseException e) { + // success + } + } + + public void testParseAdjacentStringLiterals() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge("optional_string: \"foo\" 'corge' \"grault\"", builder); + assertEquals("foocorgegrault", builder.getOptionalString()); + } + + public void testPrintFieldValue() throws Exception { + assertPrintFieldValue("\"Hello\"", "Hello", "repeated_string"); + assertPrintFieldValue("123.0", 123f, "repeated_float"); + assertPrintFieldValue("123.0", 123d, "repeated_double"); + assertPrintFieldValue("123", 123, "repeated_int32"); + assertPrintFieldValue("123", 123L, "repeated_int64"); + assertPrintFieldValue("true", true, "repeated_bool"); + assertPrintFieldValue("4294967295", 0xFFFFFFFF, "repeated_uint32"); + assertPrintFieldValue("18446744073709551615", 0xFFFFFFFFFFFFFFFFL, + "repeated_uint64"); + assertPrintFieldValue("\"\\001\\002\\003\"", + ByteString.copyFrom(new byte[] {1, 2, 3}), "repeated_bytes"); + } + + private void assertPrintFieldValue(String expect, Object value, + String fieldName) throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + StringBuilder sb = new StringBuilder(); + TextFormat.printFieldValue( + TestAllTypes.getDescriptor().findFieldByName(fieldName), + value, sb); + assertEquals(expect, sb.toString()); + } + + public void testShortDebugString() { + assertEquals("optional_nested_message { bb: 42 } repeated_int32: 1" + + " repeated_uint32: 2", + TextFormat.shortDebugString(TestAllTypes.newBuilder() + .addRepeatedInt32(1) + .addRepeatedUint32(2) + .setOptionalNestedMessage( + NestedMessage.newBuilder().setBb(42).build()) + .build())); + } + + public void testShortDebugString_unknown() { + assertEquals("5: 1 5: 0x00000002 5: 0x0000000000000003 5: \"4\" 5 { 10: 5 }" + + " 8: 1 8: 2 8: 3 15: 12379813812177893520 15: 0xabcd1234 15:" + + " 0xabcdef1234567890", + TextFormat.shortDebugString(makeUnknownFieldSet())); + } + + public void testPrintToUnicodeString() { + assertEquals( + "optional_string: \"abc\u3042efg\"\n" + + "optional_bytes: \"\\343\\201\\202\"\n" + + "repeated_string: \"\u3093XYZ\"\n", + TextFormat.printToUnicodeString(TestAllTypes.newBuilder() + .setOptionalString("abc\u3042efg") + .setOptionalBytes(bytes(0xe3, 0x81, 0x82)) + .addRepeatedString("\u3093XYZ") + .build())); + } + + public void testPrintToUnicodeString_unknown() { + assertEquals( + "1: \"\\343\\201\\202\"\n", + TextFormat.printToUnicodeString(UnknownFieldSet.newBuilder() + .addField(1, + UnknownFieldSet.Field.newBuilder() + .addLengthDelimited(bytes(0xe3, 0x81, 0x82)).build()) + .build())); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java new file mode 100644 index 0000000..ea088b3 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java @@ -0,0 +1,437 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto; +import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestEmptyMessage; +import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.Map; + +/** + * Tests related to unknown field handling. + * + * @author kenton@google.com (Kenton Varda) + */ +public class UnknownFieldSetTest extends TestCase { + public void setUp() throws Exception { + descriptor = TestAllTypes.getDescriptor(); + allFields = TestUtil.getAllSet(); + allFieldsData = allFields.toByteString(); + emptyMessage = TestEmptyMessage.parseFrom(allFieldsData); + unknownFields = emptyMessage.getUnknownFields(); + } + + UnknownFieldSet.Field getField(String name) { + Descriptors.FieldDescriptor field = descriptor.findFieldByName(name); + assertNotNull(field); + return unknownFields.getField(field.getNumber()); + } + + // Constructs a protocol buffer which contains fields with all the same + // numbers as allFieldsData except that each field is some other wire + // type. + ByteString getBizarroData() throws Exception { + UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.newBuilder(); + + UnknownFieldSet.Field varintField = + UnknownFieldSet.Field.newBuilder().addVarint(1).build(); + UnknownFieldSet.Field fixed32Field = + UnknownFieldSet.Field.newBuilder().addFixed32(1).build(); + + for (Map.Entry entry : + unknownFields.asMap().entrySet()) { + if (entry.getValue().getVarintList().isEmpty()) { + // Original field is not a varint, so use a varint. + bizarroFields.addField(entry.getKey(), varintField); + } else { + // Original field *is* a varint, so use something else. + bizarroFields.addField(entry.getKey(), fixed32Field); + } + } + + return bizarroFields.build().toByteString(); + } + + Descriptors.Descriptor descriptor; + TestAllTypes allFields; + ByteString allFieldsData; + + // An empty message that has been parsed from allFieldsData. So, it has + // unknown fields of every type. + TestEmptyMessage emptyMessage; + UnknownFieldSet unknownFields; + + // ================================================================= + + public void testVarint() throws Exception { + UnknownFieldSet.Field field = getField("optional_int32"); + assertEquals(1, field.getVarintList().size()); + assertEquals(allFields.getOptionalInt32(), + (long) field.getVarintList().get(0)); + } + + public void testFixed32() throws Exception { + UnknownFieldSet.Field field = getField("optional_fixed32"); + assertEquals(1, field.getFixed32List().size()); + assertEquals(allFields.getOptionalFixed32(), + (int) field.getFixed32List().get(0)); + } + + public void testFixed64() throws Exception { + UnknownFieldSet.Field field = getField("optional_fixed64"); + assertEquals(1, field.getFixed64List().size()); + assertEquals(allFields.getOptionalFixed64(), + (long) field.getFixed64List().get(0)); + } + + public void testLengthDelimited() throws Exception { + UnknownFieldSet.Field field = getField("optional_bytes"); + assertEquals(1, field.getLengthDelimitedList().size()); + assertEquals(allFields.getOptionalBytes(), + field.getLengthDelimitedList().get(0)); + } + + public void testGroup() throws Exception { + Descriptors.FieldDescriptor nestedFieldDescriptor = + TestAllTypes.OptionalGroup.getDescriptor().findFieldByName("a"); + assertNotNull(nestedFieldDescriptor); + + UnknownFieldSet.Field field = getField("optionalgroup"); + assertEquals(1, field.getGroupList().size()); + + UnknownFieldSet group = field.getGroupList().get(0); + assertEquals(1, group.asMap().size()); + assertTrue(group.hasField(nestedFieldDescriptor.getNumber())); + + UnknownFieldSet.Field nestedField = + group.getField(nestedFieldDescriptor.getNumber()); + assertEquals(1, nestedField.getVarintList().size()); + assertEquals(allFields.getOptionalGroup().getA(), + (long) nestedField.getVarintList().get(0)); + } + + public void testSerialize() throws Exception { + // Check that serializing the UnknownFieldSet produces the original data + // again. + ByteString data = emptyMessage.toByteString(); + assertEquals(allFieldsData, data); + } + + public void testCopyFrom() throws Exception { + TestEmptyMessage message = + TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).build(); + + assertEquals(emptyMessage.toString(), message.toString()); + } + + public void testMergeFrom() throws Exception { + TestEmptyMessage source = + TestEmptyMessage.newBuilder() + .setUnknownFields( + UnknownFieldSet.newBuilder() + .addField(2, + UnknownFieldSet.Field.newBuilder() + .addVarint(2).build()) + .addField(3, + UnknownFieldSet.Field.newBuilder() + .addVarint(4).build()) + .build()) + .build(); + TestEmptyMessage destination = + TestEmptyMessage.newBuilder() + .setUnknownFields( + UnknownFieldSet.newBuilder() + .addField(1, + UnknownFieldSet.Field.newBuilder() + .addVarint(1).build()) + .addField(3, + UnknownFieldSet.Field.newBuilder() + .addVarint(3).build()) + .build()) + .mergeFrom(source) + .build(); + + assertEquals( + "1: 1\n" + + "2: 2\n" + + "3: 3\n" + + "3: 4\n", + destination.toString()); + } + + public void testClear() throws Exception { + UnknownFieldSet fields = + UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build(); + assertTrue(fields.asMap().isEmpty()); + } + + public void testClearMessage() throws Exception { + TestEmptyMessage message = + TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).clear().build(); + assertEquals(0, message.getSerializedSize()); + } + + public void testParseKnownAndUnknown() throws Exception { + // Test mixing known and unknown fields when parsing. + + UnknownFieldSet fields = + UnknownFieldSet.newBuilder(unknownFields) + .addField(123456, + UnknownFieldSet.Field.newBuilder().addVarint(654321).build()) + .build(); + + ByteString data = fields.toByteString(); + TestAllTypes destination = TestAllTypes.parseFrom(data); + + TestUtil.assertAllFieldsSet(destination); + assertEquals(1, destination.getUnknownFields().asMap().size()); + + UnknownFieldSet.Field field = + destination.getUnknownFields().getField(123456); + assertEquals(1, field.getVarintList().size()); + assertEquals(654321, (long) field.getVarintList().get(0)); + } + + public void testWrongTypeTreatedAsUnknown() throws Exception { + // Test that fields of the wrong wire type are treated like unknown fields + // when parsing. + + ByteString bizarroData = getBizarroData(); + TestAllTypes allTypesMessage = TestAllTypes.parseFrom(bizarroData); + TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData); + + // All fields should have been interpreted as unknown, so the debug strings + // should be the same. + assertEquals(emptyMessage.toString(), allTypesMessage.toString()); + } + + public void testUnknownExtensions() throws Exception { + // Make sure fields are properly parsed to the UnknownFieldSet even when + // they are declared as extension numbers. + + TestEmptyMessageWithExtensions message = + TestEmptyMessageWithExtensions.parseFrom(allFieldsData); + + assertEquals(unknownFields.asMap().size(), + message.getUnknownFields().asMap().size()); + assertEquals(allFieldsData, message.toByteString()); + } + + public void testWrongExtensionTypeTreatedAsUnknown() throws Exception { + // Test that fields of the wrong wire type are treated like unknown fields + // when parsing extensions. + + ByteString bizarroData = getBizarroData(); + TestAllExtensions allExtensionsMessage = + TestAllExtensions.parseFrom(bizarroData); + TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData); + + // All fields should have been interpreted as unknown, so the debug strings + // should be the same. + assertEquals(emptyMessage.toString(), + allExtensionsMessage.toString()); + } + + public void testParseUnknownEnumValue() throws Exception { + Descriptors.FieldDescriptor singularField = + TestAllTypes.getDescriptor().findFieldByName("optional_nested_enum"); + Descriptors.FieldDescriptor repeatedField = + TestAllTypes.getDescriptor().findFieldByName("repeated_nested_enum"); + assertNotNull(singularField); + assertNotNull(repeatedField); + + ByteString data = + UnknownFieldSet.newBuilder() + .addField(singularField.getNumber(), + UnknownFieldSet.Field.newBuilder() + .addVarint(TestAllTypes.NestedEnum.BAR.getNumber()) + .addVarint(5) // not valid + .build()) + .addField(repeatedField.getNumber(), + UnknownFieldSet.Field.newBuilder() + .addVarint(TestAllTypes.NestedEnum.FOO.getNumber()) + .addVarint(4) // not valid + .addVarint(TestAllTypes.NestedEnum.BAZ.getNumber()) + .addVarint(6) // not valid + .build()) + .build() + .toByteString(); + + { + TestAllTypes message = TestAllTypes.parseFrom(data); + assertEquals(TestAllTypes.NestedEnum.BAR, + message.getOptionalNestedEnum()); + assertEquals( + Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ), + message.getRepeatedNestedEnumList()); + assertEquals(Arrays.asList(5L), + message.getUnknownFields() + .getField(singularField.getNumber()) + .getVarintList()); + assertEquals(Arrays.asList(4L, 6L), + message.getUnknownFields() + .getField(repeatedField.getNumber()) + .getVarintList()); + } + + { + TestAllExtensions message = + TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry()); + assertEquals(TestAllTypes.NestedEnum.BAR, + message.getExtension(UnittestProto.optionalNestedEnumExtension)); + assertEquals( + Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ), + message.getExtension(UnittestProto.repeatedNestedEnumExtension)); + assertEquals(Arrays.asList(5L), + message.getUnknownFields() + .getField(singularField.getNumber()) + .getVarintList()); + assertEquals(Arrays.asList(4L, 6L), + message.getUnknownFields() + .getField(repeatedField.getNumber()) + .getVarintList()); + } + } + + public void testLargeVarint() throws Exception { + ByteString data = + UnknownFieldSet.newBuilder() + .addField(1, + UnknownFieldSet.Field.newBuilder() + .addVarint(0x7FFFFFFFFFFFFFFFL) + .build()) + .build() + .toByteString(); + UnknownFieldSet parsed = UnknownFieldSet.parseFrom(data); + UnknownFieldSet.Field field = parsed.getField(1); + assertEquals(1, field.getVarintList().size()); + assertEquals(0x7FFFFFFFFFFFFFFFL, (long)field.getVarintList().get(0)); + } + + public void testEqualsAndHashCode() { + UnknownFieldSet.Field fixed32Field = + UnknownFieldSet.Field.newBuilder() + .addFixed32(1) + .build(); + UnknownFieldSet.Field fixed64Field = + UnknownFieldSet.Field.newBuilder() + .addFixed64(1) + .build(); + UnknownFieldSet.Field varIntField = + UnknownFieldSet.Field.newBuilder() + .addVarint(1) + .build(); + UnknownFieldSet.Field lengthDelimitedField = + UnknownFieldSet.Field.newBuilder() + .addLengthDelimited(ByteString.EMPTY) + .build(); + UnknownFieldSet.Field groupField = + UnknownFieldSet.Field.newBuilder() + .addGroup(unknownFields) + .build(); + + UnknownFieldSet a = + UnknownFieldSet.newBuilder() + .addField(1, fixed32Field) + .build(); + UnknownFieldSet b = + UnknownFieldSet.newBuilder() + .addField(1, fixed64Field) + .build(); + UnknownFieldSet c = + UnknownFieldSet.newBuilder() + .addField(1, varIntField) + .build(); + UnknownFieldSet d = + UnknownFieldSet.newBuilder() + .addField(1, lengthDelimitedField) + .build(); + UnknownFieldSet e = + UnknownFieldSet.newBuilder() + .addField(1, groupField) + .build(); + + checkEqualsIsConsistent(a); + checkEqualsIsConsistent(b); + checkEqualsIsConsistent(c); + checkEqualsIsConsistent(d); + checkEqualsIsConsistent(e); + + checkNotEqual(a, b); + checkNotEqual(a, c); + checkNotEqual(a, d); + checkNotEqual(a, e); + checkNotEqual(b, c); + checkNotEqual(b, d); + checkNotEqual(b, e); + checkNotEqual(c, d); + checkNotEqual(c, e); + checkNotEqual(d, e); + } + + /** + * Asserts that the given field sets are not equal and have different + * hash codes. + * + * @warning It's valid for non-equal objects to have the same hash code, so + * this test is stricter than it needs to be. However, this should happen + * relatively rarely. + */ + private void checkNotEqual(UnknownFieldSet s1, UnknownFieldSet s2) { + String equalsError = String.format("%s should not be equal to %s", s1, s2); + assertFalse(equalsError, s1.equals(s2)); + assertFalse(equalsError, s2.equals(s1)); + + assertFalse( + String.format("%s should have a different hash code from %s", s1, s2), + s1.hashCode() == s2.hashCode()); + } + + /** + * Asserts that the given field sets are equal and have identical hash codes. + */ + private void checkEqualsIsConsistent(UnknownFieldSet set) { + // Object should be equal to itself. + assertEquals(set, set); + + // Object should be equal to a copy of itself. + UnknownFieldSet copy = UnknownFieldSet.newBuilder(set).build(); + assertEquals(set, copy); + assertEquals(copy, set); + assertEquals(set.hashCode(), copy.hashCode()); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java new file mode 100644 index 0000000..ed5d069 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java @@ -0,0 +1,152 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import junit.framework.TestCase; + +import java.util.Iterator; +import java.util.ListIterator; + +/** + * Tests for {@link UnmodifiableLazyStringList}. + * + * @author jonp@google.com (Jon Perlow) + */ +public class UnmodifiableLazyStringListTest extends TestCase { + + private static String STRING_A = "A"; + private static String STRING_B = "B"; + private static String STRING_C = "C"; + + private static ByteString BYTE_STRING_A = ByteString.copyFromUtf8("A"); + private static ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B"); + private static ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C"); + + public void testReadOnlyMethods() { + LazyStringArrayList rawList = createSampleList(); + UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); + assertEquals(3, list.size()); + assertSame(STRING_A, list.get(0)); + assertSame(STRING_B, list.get(1)); + assertSame(STRING_C, list.get(2)); + assertEquals(BYTE_STRING_A, list.getByteString(0)); + assertEquals(BYTE_STRING_B, list.getByteString(1)); + assertEquals(BYTE_STRING_C, list.getByteString(2)); + } + + public void testModifyMethods() { + LazyStringArrayList rawList = createSampleList(); + UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); + + try { + list.remove(0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(3, list.size()); + + try { + list.add(STRING_B); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(3, list.size()); + + try { + list.set(1, STRING_B); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + + public void testIterator() { + LazyStringArrayList rawList = createSampleList(); + UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); + + Iterator iter = list.iterator(); + int count = 0; + while (iter.hasNext()) { + iter.next(); + count++; + try { + iter.remove(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + assertEquals(3, count); + + } + + public void testListIterator() { + LazyStringArrayList rawList = createSampleList(); + UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); + + ListIterator iter = list.listIterator(); + int count = 0; + while (iter.hasNext()) { + iter.next(); + count++; + try { + iter.remove(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + iter.set("bar"); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + iter.add("bar"); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + assertEquals(3, count); + + } + + private LazyStringArrayList createSampleList() { + LazyStringArrayList rawList = new LazyStringArrayList(); + rawList.add(STRING_A); + rawList.add(STRING_B); + rawList.add(STRING_C); + return rawList; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/WireFormatTest.java b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/WireFormatTest.java new file mode 100644 index 0000000..94f6213 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/WireFormatTest.java @@ -0,0 +1,580 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.List; + +import protobuf_unittest.UnittestProto; +import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestFieldOrderings; +import protobuf_unittest.UnittestProto.TestPackedExtensions; +import protobuf_unittest.UnittestProto.TestPackedTypes; +import protobuf_unittest.UnittestMset.TestMessageSet; +import protobuf_unittest.UnittestMset.RawMessageSet; +import protobuf_unittest.UnittestMset.TestMessageSetExtension1; +import protobuf_unittest.UnittestMset.TestMessageSetExtension2; +import com.google.protobuf.UnittestLite.TestAllExtensionsLite; +import com.google.protobuf.UnittestLite.TestPackedExtensionsLite; + +/** + * Tests related to parsing and serialization. + * + * @author kenton@google.com (Kenton Varda) + */ +public class WireFormatTest extends TestCase { + public void testSerialization() throws Exception { + TestAllTypes message = TestUtil.getAllSet(); + + ByteString rawBytes = message.toByteString(); + assertEquals(rawBytes.size(), message.getSerializedSize()); + + TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); + + TestUtil.assertAllFieldsSet(message2); + } + + public void testSerializationPacked() throws Exception { + TestPackedTypes message = TestUtil.getPackedSet(); + + ByteString rawBytes = message.toByteString(); + assertEquals(rawBytes.size(), message.getSerializedSize()); + + TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes); + + TestUtil.assertPackedFieldsSet(message2); + } + + public void testSerializeExtensions() throws Exception { + // TestAllTypes and TestAllExtensions should have compatible wire formats, + // so if we serialize a TestAllExtensions then parse it as TestAllTypes + // it should work. + + TestAllExtensions message = TestUtil.getAllExtensionsSet(); + ByteString rawBytes = message.toByteString(); + assertEquals(rawBytes.size(), message.getSerializedSize()); + + TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); + + TestUtil.assertAllFieldsSet(message2); + } + + public void testSerializePackedExtensions() throws Exception { + // TestPackedTypes and TestPackedExtensions should have compatible wire + // formats; check that they serialize to the same string. + TestPackedExtensions message = TestUtil.getPackedExtensionsSet(); + ByteString rawBytes = message.toByteString(); + + TestPackedTypes message2 = TestUtil.getPackedSet(); + ByteString rawBytes2 = message2.toByteString(); + + assertEquals(rawBytes, rawBytes2); + } + + public void testSerializationPackedWithoutGetSerializedSize() + throws Exception { + // Write directly to an OutputStream, without invoking getSerializedSize() + // This used to be a bug where the size of a packed field was incorrect, + // since getSerializedSize() was never invoked. + TestPackedTypes message = TestUtil.getPackedSet(); + + // Directly construct a CodedOutputStream around the actual OutputStream, + // in case writeTo(OutputStream output) invokes getSerializedSize(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + CodedOutputStream codedOutput = CodedOutputStream.newInstance(outputStream); + + message.writeTo(codedOutput); + + codedOutput.flush(); + + TestPackedTypes message2 = TestPackedTypes.parseFrom( + outputStream.toByteArray()); + + TestUtil.assertPackedFieldsSet(message2); + } + + public void testSerializeExtensionsLite() throws Exception { + // TestAllTypes and TestAllExtensions should have compatible wire formats, + // so if we serialize a TestAllExtensions then parse it as TestAllTypes + // it should work. + + TestAllExtensionsLite message = TestUtil.getAllLiteExtensionsSet(); + ByteString rawBytes = message.toByteString(); + assertEquals(rawBytes.size(), message.getSerializedSize()); + + TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); + + TestUtil.assertAllFieldsSet(message2); + } + + public void testSerializePackedExtensionsLite() throws Exception { + // TestPackedTypes and TestPackedExtensions should have compatible wire + // formats; check that they serialize to the same string. + TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet(); + ByteString rawBytes = message.toByteString(); + + TestPackedTypes message2 = TestUtil.getPackedSet(); + ByteString rawBytes2 = message2.toByteString(); + + assertEquals(rawBytes, rawBytes2); + } + + public void testParseExtensions() throws Exception { + // TestAllTypes and TestAllExtensions should have compatible wire formats, + // so if we serialize a TestAllTypes then parse it as TestAllExtensions + // it should work. + + TestAllTypes message = TestUtil.getAllSet(); + ByteString rawBytes = message.toByteString(); + + ExtensionRegistry registry = TestUtil.getExtensionRegistry(); + + TestAllExtensions message2 = + TestAllExtensions.parseFrom(rawBytes, registry); + + TestUtil.assertAllExtensionsSet(message2); + } + + public void testParsePackedExtensions() throws Exception { + // Ensure that packed extensions can be properly parsed. + TestPackedExtensions message = TestUtil.getPackedExtensionsSet(); + ByteString rawBytes = message.toByteString(); + + ExtensionRegistry registry = TestUtil.getExtensionRegistry(); + + TestPackedExtensions message2 = + TestPackedExtensions.parseFrom(rawBytes, registry); + + TestUtil.assertPackedExtensionsSet(message2); + } + + public void testParseExtensionsLite() throws Exception { + // TestAllTypes and TestAllExtensions should have compatible wire formats, + // so if we serialize a TestAllTypes then parse it as TestAllExtensions + // it should work. + + TestAllTypes message = TestUtil.getAllSet(); + ByteString rawBytes = message.toByteString(); + + ExtensionRegistryLite registry_lite = TestUtil.getExtensionRegistryLite(); + + TestAllExtensionsLite message2 = + TestAllExtensionsLite.parseFrom(rawBytes, registry_lite); + + TestUtil.assertAllExtensionsSet(message2); + + // Try again using a full extension registry. + ExtensionRegistry registry = TestUtil.getExtensionRegistry(); + + TestAllExtensionsLite message3 = + TestAllExtensionsLite.parseFrom(rawBytes, registry); + + TestUtil.assertAllExtensionsSet(message3); + } + + public void testParsePackedExtensionsLite() throws Exception { + // Ensure that packed extensions can be properly parsed. + TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet(); + ByteString rawBytes = message.toByteString(); + + ExtensionRegistryLite registry = TestUtil.getExtensionRegistryLite(); + + TestPackedExtensionsLite message2 = + TestPackedExtensionsLite.parseFrom(rawBytes, registry); + + TestUtil.assertPackedExtensionsSet(message2); + } + + public void testExtensionsSerializedSize() throws Exception { + assertEquals(TestUtil.getAllSet().getSerializedSize(), + TestUtil.getAllExtensionsSet().getSerializedSize()); + } + + public void testSerializeDelimited() throws Exception { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + TestUtil.getAllSet().writeDelimitedTo(output); + output.write(12); + TestUtil.getPackedSet().writeDelimitedTo(output); + output.write(34); + + ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); + + TestUtil.assertAllFieldsSet(TestAllTypes.parseDelimitedFrom(input)); + assertEquals(12, input.read()); + TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input)); + assertEquals(34, input.read()); + assertEquals(-1, input.read()); + + // We're at EOF, so parsing again should return null. + assertTrue(TestAllTypes.parseDelimitedFrom(input) == null); + } + + private void assertFieldsInOrder(ByteString data) throws Exception { + CodedInputStream input = data.newCodedInput(); + int previousTag = 0; + + while (true) { + int tag = input.readTag(); + if (tag == 0) { + break; + } + + assertTrue(tag > previousTag); + previousTag = tag; + input.skipField(tag); + } + } + + public void testInterleavedFieldsAndExtensions() throws Exception { + // Tests that fields are written in order even when extension ranges + // are interleaved with field numbers. + ByteString data = + TestFieldOrderings.newBuilder() + .setMyInt(1) + .setMyString("foo") + .setMyFloat(1.0F) + .setExtension(UnittestProto.myExtensionInt, 23) + .setExtension(UnittestProto.myExtensionString, "bar") + .build().toByteString(); + assertFieldsInOrder(data); + + Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor(); + ByteString dynamic_data = + DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor()) + .setField(descriptor.findFieldByName("my_int"), 1L) + .setField(descriptor.findFieldByName("my_string"), "foo") + .setField(descriptor.findFieldByName("my_float"), 1.0F) + .setField(UnittestProto.myExtensionInt.getDescriptor(), 23) + .setField(UnittestProto.myExtensionString.getDescriptor(), "bar") + .build().toByteString(); + assertFieldsInOrder(dynamic_data); + } + + private ExtensionRegistry getTestFieldOrderingsRegistry() { + ExtensionRegistry result = ExtensionRegistry.newInstance(); + result.add(UnittestProto.myExtensionInt); + result.add(UnittestProto.myExtensionString); + return result; + } + + public void testParseMultipleExtensionRanges() throws Exception { + // Make sure we can parse a message that contains multiple extensions + // ranges. + TestFieldOrderings source = + TestFieldOrderings.newBuilder() + .setMyInt(1) + .setMyString("foo") + .setMyFloat(1.0F) + .setExtension(UnittestProto.myExtensionInt, 23) + .setExtension(UnittestProto.myExtensionString, "bar") + .build(); + TestFieldOrderings dest = + TestFieldOrderings.parseFrom(source.toByteString(), + getTestFieldOrderingsRegistry()); + assertEquals(source, dest); + } + + public void testParseMultipleExtensionRangesDynamic() throws Exception { + // Same as above except with DynamicMessage. + Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor(); + DynamicMessage source = + DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor()) + .setField(descriptor.findFieldByName("my_int"), 1L) + .setField(descriptor.findFieldByName("my_string"), "foo") + .setField(descriptor.findFieldByName("my_float"), 1.0F) + .setField(UnittestProto.myExtensionInt.getDescriptor(), 23) + .setField(UnittestProto.myExtensionString.getDescriptor(), "bar") + .build(); + DynamicMessage dest = + DynamicMessage.parseFrom(descriptor, source.toByteString(), + getTestFieldOrderingsRegistry()); + assertEquals(source, dest); + } + + private static final int UNKNOWN_TYPE_ID = 1550055; + private static final int TYPE_ID_1 = + TestMessageSetExtension1.getDescriptor().getExtensions().get(0).getNumber(); + private static final int TYPE_ID_2 = + TestMessageSetExtension2.getDescriptor().getExtensions().get(0).getNumber(); + + public void testSerializeMessageSetEagerly() throws Exception { + testSerializeMessageSetWithFlag(true); + } + + public void testSerializeMessageSetNotEagerly() throws Exception { + testSerializeMessageSetWithFlag(false); + } + + private void testSerializeMessageSetWithFlag(boolean eagerParsing) + throws Exception { + ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing); + // Set up a TestMessageSet with two known messages and an unknown one. + TestMessageSet messageSet = + TestMessageSet.newBuilder() + .setExtension( + TestMessageSetExtension1.messageSetExtension, + TestMessageSetExtension1.newBuilder().setI(123).build()) + .setExtension( + TestMessageSetExtension2.messageSetExtension, + TestMessageSetExtension2.newBuilder().setStr("foo").build()) + .setUnknownFields( + UnknownFieldSet.newBuilder() + .addField(UNKNOWN_TYPE_ID, + UnknownFieldSet.Field.newBuilder() + .addLengthDelimited(ByteString.copyFromUtf8("bar")) + .build()) + .build()) + .build(); + + ByteString data = messageSet.toByteString(); + + // Parse back using RawMessageSet and check the contents. + RawMessageSet raw = RawMessageSet.parseFrom(data); + + assertTrue(raw.getUnknownFields().asMap().isEmpty()); + + assertEquals(3, raw.getItemCount()); + assertEquals(TYPE_ID_1, raw.getItem(0).getTypeId()); + assertEquals(TYPE_ID_2, raw.getItem(1).getTypeId()); + assertEquals(UNKNOWN_TYPE_ID, raw.getItem(2).getTypeId()); + + TestMessageSetExtension1 message1 = + TestMessageSetExtension1.parseFrom( + raw.getItem(0).getMessage().toByteArray()); + assertEquals(123, message1.getI()); + + TestMessageSetExtension2 message2 = + TestMessageSetExtension2.parseFrom( + raw.getItem(1).getMessage().toByteArray()); + assertEquals("foo", message2.getStr()); + + assertEquals("bar", raw.getItem(2).getMessage().toStringUtf8()); + } + + public void testParseMessageSetEagerly() throws Exception { + testParseMessageSetWithFlag(true); + } + + public void testParseMessageSetNotEagerly()throws Exception { + testParseMessageSetWithFlag(false); + } + + private void testParseMessageSetWithFlag(boolean eagerParsing) + throws Exception { + ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing); + ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); + extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); + extensionRegistry.add(TestMessageSetExtension2.messageSetExtension); + + // Set up a RawMessageSet with two known messages and an unknown one. + RawMessageSet raw = + RawMessageSet.newBuilder() + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(TYPE_ID_1) + .setMessage( + TestMessageSetExtension1.newBuilder() + .setI(123) + .build().toByteString()) + .build()) + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(TYPE_ID_2) + .setMessage( + TestMessageSetExtension2.newBuilder() + .setStr("foo") + .build().toByteString()) + .build()) + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(UNKNOWN_TYPE_ID) + .setMessage(ByteString.copyFromUtf8("bar")) + .build()) + .build(); + + ByteString data = raw.toByteString(); + + // Parse as a TestMessageSet and check the contents. + TestMessageSet messageSet = + TestMessageSet.parseFrom(data, extensionRegistry); + + assertEquals(123, messageSet.getExtension( + TestMessageSetExtension1.messageSetExtension).getI()); + assertEquals("foo", messageSet.getExtension( + TestMessageSetExtension2.messageSetExtension).getStr()); + + // Check for unknown field with type LENGTH_DELIMITED, + // number UNKNOWN_TYPE_ID, and contents "bar". + UnknownFieldSet unknownFields = messageSet.getUnknownFields(); + assertEquals(1, unknownFields.asMap().size()); + assertTrue(unknownFields.hasField(UNKNOWN_TYPE_ID)); + + UnknownFieldSet.Field field = unknownFields.getField(UNKNOWN_TYPE_ID); + assertEquals(1, field.getLengthDelimitedList().size()); + assertEquals("bar", field.getLengthDelimitedList().get(0).toStringUtf8()); + } + + public void testParseMessageSetExtensionEagerly() throws Exception { + testParseMessageSetExtensionWithFlag(true); + } + + public void testParseMessageSetExtensionNotEagerly() throws Exception { + testParseMessageSetExtensionWithFlag(false); + } + + private void testParseMessageSetExtensionWithFlag(boolean eagerParsing) + throws Exception { + ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing); + ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); + extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); + + // Set up a RawMessageSet with a known messages. + int TYPE_ID_1 = + TestMessageSetExtension1 + .getDescriptor().getExtensions().get(0).getNumber(); + RawMessageSet raw = + RawMessageSet.newBuilder() + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(TYPE_ID_1) + .setMessage( + TestMessageSetExtension1.newBuilder() + .setI(123) + .build().toByteString()) + .build()) + .build(); + + ByteString data = raw.toByteString(); + + // Parse as a TestMessageSet and check the contents. + TestMessageSet messageSet = + TestMessageSet.parseFrom(data, extensionRegistry); + assertEquals(123, messageSet.getExtension( + TestMessageSetExtension1.messageSetExtension).getI()); + } + + public void testMergeLazyMessageSetExtensionEagerly() throws Exception { + testMergeLazyMessageSetExtensionWithFlag(true); + } + + public void testMergeLazyMessageSetExtensionNotEagerly() throws Exception { + testMergeLazyMessageSetExtensionWithFlag(false); + } + + private void testMergeLazyMessageSetExtensionWithFlag(boolean eagerParsing) + throws Exception { + ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing); + ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); + extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); + + // Set up a RawMessageSet with a known messages. + int TYPE_ID_1 = + TestMessageSetExtension1 + .getDescriptor().getExtensions().get(0).getNumber(); + RawMessageSet raw = + RawMessageSet.newBuilder() + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(TYPE_ID_1) + .setMessage( + TestMessageSetExtension1.newBuilder() + .setI(123) + .build().toByteString()) + .build()) + .build(); + + ByteString data = raw.toByteString(); + + // Parse as a TestMessageSet and store value into lazy field + TestMessageSet messageSet = + TestMessageSet.parseFrom(data, extensionRegistry); + // Merge lazy field check the contents. + messageSet = + messageSet.toBuilder().mergeFrom(data, extensionRegistry).build(); + assertEquals(123, messageSet.getExtension( + TestMessageSetExtension1.messageSetExtension).getI()); + } + + public void testMergeMessageSetExtensionEagerly() throws Exception { + testMergeMessageSetExtensionWithFlag(true); + } + + public void testMergeMessageSetExtensionNotEagerly() throws Exception { + testMergeMessageSetExtensionWithFlag(false); + } + + private void testMergeMessageSetExtensionWithFlag(boolean eagerParsing) + throws Exception { + ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing); + ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); + extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); + + // Set up a RawMessageSet with a known messages. + int TYPE_ID_1 = + TestMessageSetExtension1 + .getDescriptor().getExtensions().get(0).getNumber(); + RawMessageSet raw = + RawMessageSet.newBuilder() + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(TYPE_ID_1) + .setMessage( + TestMessageSetExtension1.newBuilder() + .setI(123) + .build().toByteString()) + .build()) + .build(); + + // Serialize RawMessageSet unnormally (message value before type id) + ByteString.CodedBuilder out = ByteString.newCodedBuilder( + raw.getSerializedSize()); + CodedOutputStream output = out.getCodedOutput(); + List items = raw.getItemList(); + for (int i = 0; i < items.size(); i++) { + RawMessageSet.Item item = items.get(i); + output.writeTag(1, WireFormat.WIRETYPE_START_GROUP); + output.writeBytes(3, item.getMessage()); + output.writeInt32(2, item.getTypeId()); + output.writeTag(1, WireFormat.WIRETYPE_END_GROUP); + } + ByteString data = out.build(); + + // Merge bytes into TestMessageSet and check the contents. + TestMessageSet messageSet = + TestMessageSet.newBuilder().mergeFrom(data, extensionRegistry).build(); + assertEquals(123, messageSet.getExtension( + TestMessageSetExtension1.messageSetExtension).getI()); + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/multiple_files_test.proto b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/multiple_files_test.proto new file mode 100644 index 0000000..9a04014 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/multiple_files_test.proto @@ -0,0 +1,71 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// A proto file which tests the java_multiple_files option. + + +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +option java_generic_services = true; // auto-added + +import "google/protobuf/unittest.proto"; + +package protobuf_unittest; + +option java_multiple_files = true; +option java_outer_classname = "MultipleFilesTestProto"; + +message MessageWithNoOuter { + message NestedMessage { + optional int32 i = 1; + } + enum NestedEnum { + BAZ = 3; + } + optional NestedMessage nested = 1; + repeated TestAllTypes foreign = 2; + optional NestedEnum nested_enum = 3; + optional EnumWithNoOuter foreign_enum = 4; +} + +enum EnumWithNoOuter { + FOO = 1; + BAR = 2; +} + +service ServiceWithNoOuter { + rpc Foo(MessageWithNoOuter) returns(TestAllTypes); +} + +extend TestAllExtensions { + optional int32 extension_with_outer = 1234567; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_builders_test.proto b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_builders_test.proto new file mode 100644 index 0000000..abffb9d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_builders_test.proto @@ -0,0 +1,53 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jonp@google.com (Jon Perlow) +// + +package protobuf_unittest; + +option java_multiple_files = true; +option java_outer_classname = "NestedBuilders"; + + +message Vehicle { + optional Engine engine = 1; + repeated Wheel wheel = 2; +} + +message Engine { + optional int32 cylinder = 1; + optional int32 liters = 2; +} + +message Wheel { + optional int32 radius = 1; + optional int32 width = 2; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_extension.proto b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_extension.proto new file mode 100644 index 0000000..9fe5d56 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_extension.proto @@ -0,0 +1,45 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: Darick Tong (darick@google.com) +// +// A proto file with nested extensions. Note that this must be defined in +// a separate file to properly test the initialization of the outer class. + + +import "com/google/protobuf/non_nested_extension.proto"; + +package protobuf_unittest; + +message MyNestedExtension { + extend MessageToBeExtended { + optional MessageToBeExtended recursiveExtension = 2; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_extension_lite.proto b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_extension_lite.proto new file mode 100644 index 0000000..16ee46e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/nested_extension_lite.proto @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: Darick Tong (darick@google.com) +// +// A proto file with nested extensions for a MessageLite messages. Note that +// this must be defined in a separate file to properly test the initialization +// of the outer class. + + +package protobuf_unittest; + +option optimize_for = LITE_RUNTIME; + +import "com/google/protobuf/non_nested_extension_lite.proto"; + +message MyNestedExtensionLite { + extend MessageLiteToBeExtended { + optional MessageLiteToBeExtended recursiveExtensionLite = 3; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/non_nested_extension.proto b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/non_nested_extension.proto new file mode 100644 index 0000000..f61b419 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/non_nested_extension.proto @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: Darick Tong (darick@google.com) +// +// A proto file with extensions. + + +package protobuf_unittest; + +message MessageToBeExtended { + extensions 1 to max; +} + +message MyNonNestedExtension { +} + +extend MessageToBeExtended { + optional MyNonNestedExtension nonNestedExtension = 1; +} + diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto new file mode 100644 index 0000000..3c82659 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto @@ -0,0 +1,50 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: Darick Tong (darick@google.com) +// +// A proto file with extensions for a MessageLite messages. + + +package protobuf_unittest; + +option optimize_for = LITE_RUNTIME; + +message MessageLiteToBeExtended { + extensions 1 to max; +} + +message MyNonNestedExtensionLite { +} + +extend MessageLiteToBeExtended { + optional MyNonNestedExtensionLite nonNestedExtensionLite = 1; +} + diff --git a/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto new file mode 100644 index 0000000..6e67d97 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto @@ -0,0 +1,108 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jonp@google.com (Jon Perlow) + +// This file tests that various identifiers work as field and type names even +// though the same identifiers are used internally by the java code generator. + + +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +option java_generic_services = true; // auto-added + +package io_protocol_tests; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "TestBadIdentifiersProto"; + +message TestMessage { +} + +message Descriptor { + option no_standard_descriptor_accessor = true; + optional string descriptor = 1; + message NestedDescriptor { + option no_standard_descriptor_accessor = true; + optional string descriptor = 1; + } + optional NestedDescriptor nested_descriptor = 2; +} + +message Parser { + enum ParserEnum { + PARSER = 1; + } + optional ParserEnum parser = 1; +} + +message Deprecated { + enum TestEnum { + FOO = 1; + } + + optional int32 field1 = 1 [deprecated=true]; + optional TestEnum field2 = 2 [deprecated=true]; + optional TestMessage field3 = 3 [deprecated=true]; +} + +message Override { + optional int32 override = 1; +} + +message Object { + optional int32 object = 1; + optional string string_object = 2; +} + +message String { + optional string string = 1; +} + +message Integer { + optional int32 integer = 1; +} + +message Long { + optional int32 long = 1; +} + +message Float { + optional float float = 1; +} + +message Double { + optional double double = 1; +} + +service TestConflictingMethodNames { + rpc Override(TestMessage) returns (TestMessage); +} + diff --git a/cpp/thirdparty/protobuf-2.5.0/ltmain.sh b/cpp/thirdparty/protobuf-2.5.0/ltmain.sh new file mode 100644 index 0000000..c2852d8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/ltmain.sh @@ -0,0 +1,9661 @@ + +# libtool (GNU libtool) 2.4.2 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --no-warn don't display warning messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . +# GNU libtool home page: . +# General help using GNU software: . + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.2 Debian-2.4.2-1ubuntu1" +TIMESTAMP="" +package_revision=1.3337 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_warning=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-warning|--no-warn) + opt_warning=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$absdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type \`$version_type'" + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Remove ${wl} instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + func_resolve_sysroot "$deplib" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/cpp/thirdparty/protobuf-2.5.0/m4/ac_system_extensions.m4 b/cpp/thirdparty/protobuf-2.5.0/m4/ac_system_extensions.m4 new file mode 100644 index 0000000..1ca2eeb --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/m4/ac_system_extensions.m4 @@ -0,0 +1,37 @@ +dnl Provide AC_USE_SYSTEM_EXTENSIONS for old autoconf machines. +AC_DEFUN([ACX_USE_SYSTEM_EXTENSIONS],[ + ifdef([AC_USE_SYSTEM_EXTENSIONS],[ + AC_USE_SYSTEM_EXTENSIONS + ],[ + AC_BEFORE([$0], [AC_COMPILE_IFELSE]) + AC_BEFORE([$0], [AC_RUN_IFELSE]) + + AC_REQUIRE([AC_GNU_SOURCE]) + AC_REQUIRE([AC_AIX]) + AC_REQUIRE([AC_MINIX]) + + AH_VERBATIM([__EXTENSIONS__], +[/* Enable extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif]) + AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], + [ac_cv_safe_to_define___extensions__], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([ +# define __EXTENSIONS__ 1 + AC_INCLUDES_DEFAULT])], + [ac_cv_safe_to_define___extensions__=yes], + [ac_cv_safe_to_define___extensions__=no])]) + test $ac_cv_safe_to_define___extensions__ = yes && + AC_DEFINE([__EXTENSIONS__]) + AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) + AC_DEFINE([_TANDEM_SOURCE]) + ]) +]) diff --git a/cpp/thirdparty/protobuf-2.5.0/m4/acx_check_suncc.m4 b/cpp/thirdparty/protobuf-2.5.0/m4/acx_check_suncc.m4 new file mode 100644 index 0000000..4e8f961 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/m4/acx_check_suncc.m4 @@ -0,0 +1,74 @@ +dnl Check for the presence of the Sun Studio compiler. +dnl If Sun Studio compiler is found, set appropriate flags. +dnl Additionally, Sun Studio doesn't default to 64-bit by itself, +dnl nor does it automatically look in standard Solaris places for +dnl 64-bit libs, so we must add those options and paths to the search +dnl paths. + +dnl TODO(kenton): This is pretty hacky. It sets CXXFLAGS, which the autoconf +dnl docs say should never be overridden except by the user. It also isn't +dnl cross-compile safe. We should fix these problems, but since I don't have +dnl Sun CC at my disposal for testing, someone else will have to do it. + +AC_DEFUN([ACX_CHECK_SUNCC],[ + + AC_LANG_PUSH([C++]) + AC_CHECK_DECL([__SUNPRO_CC], [SUNCC="yes"], [SUNCC="no"]) + AC_LANG_POP() + + + AC_ARG_ENABLE([64bit-solaris], + [AS_HELP_STRING([--disable-64bit-solaris], + [Build 64 bit binary on Solaris @<:@default=on@:>@])], + [ac_enable_64bit="$enableval"], + [ac_enable_64bit="yes"]) + + AS_IF([test "$SUNCC" = "yes" -a "x${ac_cv_env_CXXFLAGS_set}" = "x"],[ + dnl Sun Studio has a crashing bug with -xO4 in some cases. Keep this + dnl at -xO3 until a proper test to detect those crashes can be done. + CXXFLAGS="-g0 -xO3 -xlibmil -xdepend -xbuiltin -mt -compat=5 -library=stlport4 -library=Crun -template=no%extdef ${CXXFLAGS}" + ]) + + case $host_os in + *solaris*) + AC_CHECK_PROGS(ISAINFO, [isainfo], [no]) + AS_IF([test "x$ISAINFO" != "xno"], + [isainfo_b=`${ISAINFO} -b`], + [isainfo_b="x"]) + + AS_IF([test "$isainfo_b" != "x"],[ + + isainfo_k=`${ISAINFO} -k` + + AS_IF([test "x$ac_enable_64bit" = "xyes"],[ + + AS_IF([test "x$libdir" = "x\${exec_prefix}/lib"],[ + dnl The user hasn't overridden the default libdir, so we'll + dnl the dir suffix to match solaris 32/64-bit policy + libdir="${libdir}/${isainfo_k}" + ]) + + dnl This should just be set in CPPFLAGS and in LDFLAGS, but libtool + dnl does the wrong thing if you don't put it into CXXFLAGS. sigh. + dnl (It also needs it in CFLAGS, or it does a different wrong thing!) + AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],[ + CXXFLAGS="${CXXFLAGS} -m64" + ac_cv_env_CXXFLAGS_set=set + ac_cv_env_CXXFLAGS_value='-m64' + ]) + + AS_IF([test "x${ac_cv_env_CFLAGS_set}" = "x"],[ + CFLAGS="${CFLAGS} -m64" + ac_cv_env_CFLAGS_set=set + ac_cv_env_CFLAGS_value='-m64' + ]) + + AS_IF([test "$target_cpu" = "sparc" -a "x$SUNCC" = "xyes" ],[ + CXXFLAGS="-xmemalign=8s ${CXXFLAGS}" + ]) + ]) + ]) + ;; + esac + +]) diff --git a/cpp/thirdparty/protobuf-2.5.0/m4/acx_pthread.m4 b/cpp/thirdparty/protobuf-2.5.0/m4/acx_pthread.m4 new file mode 100644 index 0000000..89d42c7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/m4/acx_pthread.m4 @@ -0,0 +1,397 @@ +# This was retrieved from +# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi +# See also (perhaps for new versions?) +# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi +# +# We've rewritten the inconsistency check code (from avahi), to work +# more broadly. In particular, it no longer assumes ld accepts -zdefs. +# This caused a restructing of the code, but the functionality has only +# changed a little. + +dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +dnl +dnl @summary figure out how to build C programs using POSIX threads +dnl +dnl This macro figures out how to build C programs using POSIX threads. +dnl It sets the PTHREAD_LIBS output variable to the threads library and +dnl linker flags, and the PTHREAD_CFLAGS output variable to any special +dnl C compiler flags that are needed. (The user can also force certain +dnl compiler flags/libs to be tested by setting these environment +dnl variables.) +dnl +dnl Also sets PTHREAD_CC to any special C compiler that is needed for +dnl multi-threaded programs (defaults to the value of CC otherwise). +dnl (This is necessary on AIX to use the special cc_r compiler alias.) +dnl +dnl NOTE: You are assumed to not only compile your program with these +dnl flags, but also link it with them as well. e.g. you should link +dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS +dnl $LIBS +dnl +dnl If you are only building threads programs, you may wish to use +dnl these variables in your default LIBS, CFLAGS, and CC: +dnl +dnl LIBS="$PTHREAD_LIBS $LIBS" +dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +dnl CC="$PTHREAD_CC" +dnl +dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute +dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to +dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +dnl +dnl ACTION-IF-FOUND is a list of shell commands to run if a threads +dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to +dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the +dnl default action will define HAVE_PTHREAD. +dnl +dnl Please let the authors know if this macro fails on any platform, or +dnl if you have any other suggestions or comments. This macro was based +dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with +dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros +dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. +dnl We are also grateful for the helpful feedback of numerous users. +dnl +dnl @category InstalledPackages +dnl @author Steven G. Johnson +dnl @version 2006-05-29 +dnl @license GPLWithACException +dnl +dnl Checks for GCC shared/pthread inconsistency based on work by +dnl Marcin Owsiany + + +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_TRY_LINK([#include ], [int attr=$attr; return attr;], + [attr_name=$attr; break]) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi + + # The next part tries to detect GCC inconsistency with -shared on some + # architectures and systems. The problem is that in certain + # configurations, when -shared is specified, GCC "forgets" to + # internally use various flags which are still necessary. + + # + # Prepare the flags + # + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_CC="$CC" + + # Try with the flags determined by the earlier checks. + # + # -Wl,-z,defs forces link-time symbol resolution, so that the + # linking checks with -shared actually have any value + # + # FIXME: -fPIC is required for -shared on many architectures, + # so we specify it here, but the right way would probably be to + # properly detect whether it is actually required. + CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CC="$PTHREAD_CC" + + # In order not to create several levels of indentation, we test + # the value of "$done" until we find the cure or run out of ideas. + done="no" + + # First, make sure the CFLAGS we added are actually accepted by our + # compiler. If not (and OS X's ld, for instance, does not accept -z), + # then we can't do this test. + if test x"$done" = xno; then + AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies]) + AC_TRY_LINK(,, , [done=yes]) + + if test "x$done" = xyes ; then + AC_MSG_RESULT([no]) + else + AC_MSG_RESULT([yes]) + fi + fi + + if test x"$done" = xno; then + AC_MSG_CHECKING([whether -pthread is sufficient with -shared]) + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [done=yes]) + + if test "x$done" = xyes; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + fi + + # + # Linux gcc on some architectures such as mips/mipsel forgets + # about -lpthread + # + if test x"$done" = xno; then + AC_MSG_CHECKING([whether -lpthread fixes that]) + LIBS="-lpthread $PTHREAD_LIBS $save_LIBS" + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [done=yes]) + + if test "x$done" = xyes; then + AC_MSG_RESULT([yes]) + PTHREAD_LIBS="-lpthread $PTHREAD_LIBS" + else + AC_MSG_RESULT([no]) + fi + fi + # + # FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc + # + if test x"$done" = xno; then + AC_MSG_CHECKING([whether -lc_r fixes that]) + LIBS="-lc_r $PTHREAD_LIBS $save_LIBS" + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [done=yes]) + + if test "x$done" = xyes; then + AC_MSG_RESULT([yes]) + PTHREAD_LIBS="-lc_r $PTHREAD_LIBS" + else + AC_MSG_RESULT([no]) + fi + fi + if test x"$done" = xno; then + # OK, we have run out of ideas + AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries]) + + # so it's not safe to assume that we may use pthreads + acx_pthread_ok=no + fi + + AC_MSG_CHECKING([whether what we have so far is sufficient with -nostdlib]) + CFLAGS="-nostdlib $CFLAGS" + # we need c with nostdlib + LIBS="$LIBS -lc" + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [done=yes],[done=no]) + + if test "x$done" = xyes; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + + if test x"$done" = xno; then + AC_MSG_CHECKING([whether -lpthread saves the day]) + LIBS="-lpthread $LIBS" + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [done=yes],[done=no]) + + if test "x$done" = xyes; then + AC_MSG_RESULT([yes]) + PTHREAD_LIBS="$PTHREAD_LIBS -lpthread" + else + AC_MSG_RESULT([no]) + AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries and -nostdlib]) + fi + fi + + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + CC="$save_CC" +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/cpp/thirdparty/protobuf-2.5.0/m4/libtool.m4 b/cpp/thirdparty/protobuf-2.5.0/m4/libtool.m4 new file mode 100644 index 0000000..828104c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/m4/libtool.m4 @@ -0,0 +1,8001 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/cpp/thirdparty/protobuf-2.5.0/m4/ltoptions.m4 b/cpp/thirdparty/protobuf-2.5.0/m4/ltoptions.m4 new file mode 100644 index 0000000..5d9acd8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/m4/ltoptions.m4 @@ -0,0 +1,384 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/cpp/thirdparty/protobuf-2.5.0/m4/ltsugar.m4 b/cpp/thirdparty/protobuf-2.5.0/m4/ltsugar.m4 new file mode 100644 index 0000000..9000a05 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/cpp/thirdparty/protobuf-2.5.0/m4/ltversion.m4 b/cpp/thirdparty/protobuf-2.5.0/m4/ltversion.m4 new file mode 100644 index 0000000..07a8602 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/cpp/thirdparty/protobuf-2.5.0/m4/lt~obsolete.m4 b/cpp/thirdparty/protobuf-2.5.0/m4/lt~obsolete.m4 new file mode 100644 index 0000000..c573da9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/cpp/thirdparty/protobuf-2.5.0/m4/stl_hash.m4 b/cpp/thirdparty/protobuf-2.5.0/m4/stl_hash.m4 new file mode 100644 index 0000000..0722b14 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/m4/stl_hash.m4 @@ -0,0 +1,72 @@ +# We check two things: where the include file is for +# unordered_map/hash_map (we prefer the first form), and what +# namespace unordered/hash_map lives in within that include file. We +# include AC_TRY_COMPILE for all the combinations we've seen in the +# wild. We define HASH_MAP_H to the location of the header file, and +# HASH_NAMESPACE to the namespace the class (unordered_map or +# hash_map) is in. We define HAVE_UNORDERED_MAP if the class we found +# is named unordered_map, or leave it undefined if not. + +# This also checks if unordered map exists. +AC_DEFUN([AC_CXX_STL_HASH], + [ + AC_MSG_CHECKING(the location of hash_map) + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_cv_cxx_hash_map="" + # First try unordered_map, but not on gcc's before 4.2 -- I've + # seen unexplainable unordered_map bugs with -O2 on older gcc's. + AC_TRY_COMPILE([#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)) + # error GCC too old for unordered_map + #endif + ], + [/* no program body necessary */], + [stl_hash_old_gcc=no], + [stl_hash_old_gcc=yes]) + for location in unordered_map tr1/unordered_map; do + for namespace in std std::tr1; do + if test -z "$ac_cv_cxx_hash_map" -a "$stl_hash_old_gcc" != yes; then + # Some older gcc's have a buggy tr1, so test a bit of code. + AC_TRY_COMPILE([#include <$location>], + [const ${namespace}::unordered_map t; + return t.find(5) == t.end();], + [ac_cv_cxx_hash_map="<$location>"; + ac_cv_cxx_hash_namespace="$namespace"; + ac_cv_cxx_hash_map_class="unordered_map";]) + fi + done + done + # Now try hash_map + for location in ext/hash_map hash_map; do + for namespace in __gnu_cxx "" std stdext; do + if test -z "$ac_cv_cxx_hash_map"; then + AC_TRY_COMPILE([#include <$location>], + [${namespace}::hash_map t], + [ac_cv_cxx_hash_map="<$location>"; + ac_cv_cxx_hash_namespace="$namespace"; + ac_cv_cxx_hash_map_class="hash_map";]) + fi + done + done + ac_cv_cxx_hash_set=`echo "$ac_cv_cxx_hash_map" | sed s/map/set/`; + ac_cv_cxx_hash_set_class=`echo "$ac_cv_cxx_hash_map_class" | sed s/map/set/`; + if test -n "$ac_cv_cxx_hash_map"; then + AC_DEFINE(HAVE_HASH_MAP, 1, [define if the compiler has hash_map]) + AC_DEFINE(HAVE_HASH_SET, 1, [define if the compiler has hash_set]) + AC_DEFINE_UNQUOTED(HASH_MAP_H,$ac_cv_cxx_hash_map, + [the location of or ]) + AC_DEFINE_UNQUOTED(HASH_SET_H,$ac_cv_cxx_hash_set, + [the location of or ]) + AC_DEFINE_UNQUOTED(HASH_NAMESPACE,$ac_cv_cxx_hash_namespace, + [the namespace of hash_map/hash_set]) + AC_DEFINE_UNQUOTED(HASH_MAP_CLASS,$ac_cv_cxx_hash_map_class, + [the name of ]) + AC_DEFINE_UNQUOTED(HASH_SET_CLASS,$ac_cv_cxx_hash_set_class, + [the name of ]) + AC_MSG_RESULT([$ac_cv_cxx_hash_map]) + else + AC_MSG_RESULT() + AC_MSG_WARN([could not find an STL hash_map]) + fi +]) + diff --git a/cpp/thirdparty/protobuf-2.5.0/missing b/cpp/thirdparty/protobuf-2.5.0/missing new file mode 100755 index 0000000..86a8fc3 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/missing @@ -0,0 +1,331 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2012-01-06.13; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/cpp/thirdparty/protobuf-2.5.0/protobuf-lite.pc.in b/cpp/thirdparty/protobuf-2.5.0/protobuf-lite.pc.in new file mode 100644 index 0000000..29c218e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/protobuf-lite.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Protocol Buffers +Description: Google's Data Interchange Format +Version: @VERSION@ +Libs: -L${libdir} -lprotobuf-lite @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ +Cflags: -I${includedir} @PTHREAD_CFLAGS@ +# Commented out because it crashes pkg-config *sigh*: +# http://bugs.freedesktop.org/show_bug.cgi?id=13265 +# Conflicts: protobuf diff --git a/cpp/thirdparty/protobuf-2.5.0/protobuf.pc.in b/cpp/thirdparty/protobuf-2.5.0/protobuf.pc.in new file mode 100644 index 0000000..29f2487 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/protobuf.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Protocol Buffers +Description: Google's Data Interchange Format +Version: @VERSION@ +Libs: -L${libdir} -lprotobuf @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ +Libs.private: @LIBS@ +Cflags: -I${includedir} @PTHREAD_CFLAGS@ +# Commented out because it crashes pkg-config *sigh*: +# http://bugs.freedesktop.org/show_bug.cgi?id=13265 +# Conflicts: protobuf-lite diff --git a/cpp/thirdparty/protobuf-2.5.0/python/README.txt b/cpp/thirdparty/protobuf-2.5.0/python/README.txt new file mode 100644 index 0000000..bb0032f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/README.txt @@ -0,0 +1,101 @@ +Protocol Buffers - Google's data interchange format +Copyright 2008 Google Inc. + +This directory contains the Python Protocol Buffers runtime library. + +Normally, this directory comes as part of the protobuf package, available +from: + + http://code.google.com/p/protobuf + +The complete package includes the C++ source code, which includes the +Protocol Compiler (protoc). If you downloaded this package from PyPI +or some other Python-specific source, you may have received only the +Python part of the code. In this case, you will need to obtain the +Protocol Compiler from some other source before you can use this +package. + +Development Warning +=================== + +The Python implementation of Protocol Buffers is not as mature as the C++ +and Java implementations. It may be more buggy, and it is known to be +pretty slow at this time. If you would like to help fix these issues, +join the Protocol Buffers discussion list and let us know! + +Installation +============ + +1) Make sure you have Python 2.4 or newer. If in doubt, run: + + $ python -V + +2) If you do not have setuptools installed, note that it will be + downloaded and installed automatically as soon as you run setup.py. + If you would rather install it manually, you may do so by following + the instructions on this page: + + http://peak.telecommunity.com/DevCenter/EasyInstall#installation-instructions + +3) Build the C++ code, or install a binary distribution of protoc. If + you install a binary distribution, make sure that it is the same + version as this package. If in doubt, run: + + $ protoc --version + +4) Build and run the tests: + + $ python setup.py build + $ python setup.py test + + If some tests fail, this library may not work correctly on your + system. Continue at your own risk. + + Please note that there is a known problem with some versions of + Python on Cygwin which causes the tests to fail after printing the + error: "sem_init: Resource temporarily unavailable". This appears + to be a bug either in Cygwin or in Python: + http://www.cygwin.com/ml/cygwin/2005-07/msg01378.html + We do not know if or when it might me fixed. We also do not know + how likely it is that this bug will affect users in practice. + +5) Install: + + $ python setup.py install + + This step may require superuser privileges. + NOTE: To use C++ implementation, you need to install C++ protobuf runtime + library of the same version and export the environment variable before this + step. See the "C++ Implementation" section below for more details. + +Usage +===== + +The complete documentation for Protocol Buffers is available via the +web at: + + http://code.google.com/apis/protocolbuffers/ + +C++ Implementation +================== + +WARNING: This is EXPERIMENTAL and only available for CPython platforms. + +The C++ implementation for Python messages is built as a Python extension to +improve the overall protobuf Python performance. + +To use the C++ implementation, you need to: +1) Install the C++ protobuf runtime library, please see instructions in the + parent directory. +2) Export an environment variable: + + $ export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp + +You need to export this variable before running setup.py script to build and +install the extension. You must also set the variable at runtime, otherwise +the pure-Python implementation will be used. In a future release, we will +change the default so that C++ implementation is used whenever it is available. +It is strongly recommended to run `python setup.py test` after setting the +variable to "cpp", so the tests will be against C++ implemented Python +messages. + diff --git a/cpp/thirdparty/protobuf-2.5.0/python/ez_setup.py b/cpp/thirdparty/protobuf-2.5.0/python/ez_setup.py new file mode 100755 index 0000000..a2cf777 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/ez_setup.py @@ -0,0 +1,283 @@ +#!python + +# This file was obtained from: +# http://peak.telecommunity.com/dist/ez_setup.py +# on 2011/1/21. + +"""Bootstrap setuptools installation + +If you want to use setuptools in your package's setup.py, just include this +file in the same directory with it, and add this to the top of your setup.py:: + + from ez_setup import use_setuptools + use_setuptools() + +If you want to require a specific version of setuptools, set a download +mirror, or use an alternate download directory, you can do so by supplying +the appropriate options to ``use_setuptools()``. + +This file can also be run as a script to install or upgrade setuptools. +""" +import sys +DEFAULT_VERSION = "0.6c11" +DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] + +md5_data = { + 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', + 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', + 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', + 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', + 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', + 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', + 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', + 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', + 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', + 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', + 'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090', + 'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4', + 'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7', + 'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5', + 'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de', + 'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b', + 'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2', + 'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086', + 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', + 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', + 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', + 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', + 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', + 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', + 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', + 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', + 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', + 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', + 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', + 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', + 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', + 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', + 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', + 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', + 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', + 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', + 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', + 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', + 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', + 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', + 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', + 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', +} + +import sys, os +try: from hashlib import md5 +except ImportError: from md5 import md5 + +def _validate_md5(egg_name, data): + if egg_name in md5_data: + digest = md5(data).hexdigest() + if digest != md5_data[egg_name]: + print >>sys.stderr, ( + "md5 validation of %s failed! (Possible download problem?)" + % egg_name + ) + sys.exit(2) + return data + +def use_setuptools( + version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, + download_delay=15 +): + """Automatically find/download setuptools and make it available on sys.path + + `version` should be a valid setuptools version number that is available + as an egg for download under the `download_base` URL (which should end with + a '/'). `to_dir` is the directory where setuptools will be downloaded, if + it is not already available. If `download_delay` is specified, it should + be the number of seconds that will be paused before initiating a download, + should one be required. If an older version of setuptools is installed, + this routine will print a message to ``sys.stderr`` and raise SystemExit in + an attempt to abort the calling script. + """ + was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules + def do_download(): + egg = download_setuptools(version, download_base, to_dir, download_delay) + sys.path.insert(0, egg) + import setuptools; setuptools.bootstrap_install_from = egg + try: + import pkg_resources + except ImportError: + return do_download() + try: + pkg_resources.require("setuptools>="+version); return + except pkg_resources.VersionConflict, e: + if was_imported: + print >>sys.stderr, ( + "The required version of setuptools (>=%s) is not available, and\n" + "can't be installed while this script is running. Please install\n" + " a more recent version first, using 'easy_install -U setuptools'." + "\n\n(Currently using %r)" + ) % (version, e.args[0]) + sys.exit(2) + except pkg_resources.DistributionNotFound: + pass + + del pkg_resources, sys.modules['pkg_resources'] # reload ok + return do_download() + +def download_setuptools( + version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, + delay = 15 +): + """Download setuptools from a specified location and return its filename + + `version` should be a valid setuptools version number that is available + as an egg for download under the `download_base` URL (which should end + with a '/'). `to_dir` is the directory where the egg will be downloaded. + `delay` is the number of seconds to pause before an actual download attempt. + """ + import urllib2, shutil + egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) + url = download_base + egg_name + saveto = os.path.join(to_dir, egg_name) + src = dst = None + if not os.path.exists(saveto): # Avoid repeated downloads + try: + from distutils import log + if delay: + log.warn(""" +--------------------------------------------------------------------------- +This script requires setuptools version %s to run (even to display +help). I will attempt to download it for you (from +%s), but +you may need to enable firewall access for this script first. +I will start the download in %d seconds. + +(Note: if this machine does not have network access, please obtain the file + + %s + +and place it in this directory before rerunning this script.) +---------------------------------------------------------------------------""", + version, download_base, delay, url + ); from time import sleep; sleep(delay) + log.warn("Downloading %s", url) + src = urllib2.urlopen(url) + # Read/write all in one block, so we don't create a corrupt file + # if the download is interrupted. + data = _validate_md5(egg_name, src.read()) + dst = open(saveto,"wb"); dst.write(data) + finally: + if src: src.close() + if dst: dst.close() + return os.path.realpath(saveto) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +def main(argv, version=DEFAULT_VERSION): + """Install or upgrade setuptools and EasyInstall""" + try: + import setuptools + except ImportError: + egg = None + try: + egg = download_setuptools(version, delay=0) + sys.path.insert(0,egg) + from setuptools.command.easy_install import main + return main(list(argv)+[egg]) # we're done here + finally: + if egg and os.path.exists(egg): + os.unlink(egg) + else: + if setuptools.__version__ == '0.0.1': + print >>sys.stderr, ( + "You have an obsolete version of setuptools installed. Please\n" + "remove it from your system entirely before rerunning this script." + ) + sys.exit(2) + + req = "setuptools>="+version + import pkg_resources + try: + pkg_resources.require(req) + except pkg_resources.VersionConflict: + try: + from setuptools.command.easy_install import main + except ImportError: + from easy_install import main + main(list(argv)+[download_setuptools(delay=0)]) + sys.exit(0) # try to force an exit + else: + if argv: + from setuptools.command.easy_install import main + main(argv) + else: + print "Setuptools version",version,"or greater has been installed." + print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' + +def update_md5(filenames): + """Update our built-in md5 registry""" + + import re + + for name in filenames: + base = os.path.basename(name) + f = open(name,'rb') + md5_data[base] = md5(f.read()).hexdigest() + f.close() + + data = [" %r: %r,\n" % it for it in md5_data.items()] + data.sort() + repl = "".join(data) + + import inspect + srcfile = inspect.getsourcefile(sys.modules[__name__]) + f = open(srcfile, 'rb'); src = f.read(); f.close() + + match = re.search("\nmd5_data = {\n([^}]+)}", src) + if not match: + print >>sys.stderr, "Internal error!" + sys.exit(2) + + src = src[:match.start(1)] + repl + src[match.end(1):] + f = open(srcfile,'w') + f.write(src) + f.close() + + +if __name__=='__main__': + if len(sys.argv)>2 and sys.argv[1]=='--md5update': + update_md5(sys.argv[2:]) + else: + main(sys.argv[1:]) diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/__init__.py b/cpp/thirdparty/protobuf-2.5.0/python/google/__init__.py new file mode 100755 index 0000000..de40ea7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/__init__.py @@ -0,0 +1 @@ +__import__('pkg_resources').declare_namespace(__name__) diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/__init__.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor.py new file mode 100755 index 0000000..eb13eda --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor.py @@ -0,0 +1,713 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Descriptors essentially contain exactly the information found in a .proto +file, in types that make this information accessible in Python. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + + +from google.protobuf.internal import api_implementation + + +if api_implementation.Type() == 'cpp': + if api_implementation.Version() == 2: + from google.protobuf.internal.cpp import _message + else: + from google.protobuf.internal import cpp_message + + +class Error(Exception): + """Base error for this module.""" + + +class TypeTransformationError(Error): + """Error transforming between python proto type and corresponding C++ type.""" + + +class DescriptorBase(object): + + """Descriptors base class. + + This class is the base of all descriptor classes. It provides common options + related functionaility. + + Attributes: + has_options: True if the descriptor has non-default options. Usually it + is not necessary to read this -- just call GetOptions() which will + happily return the default instance. However, it's sometimes useful + for efficiency, and also useful inside the protobuf implementation to + avoid some bootstrapping issues. + """ + + def __init__(self, options, options_class_name): + """Initialize the descriptor given its options message and the name of the + class of the options message. The name of the class is required in case + the options message is None and has to be created. + """ + self._options = options + self._options_class_name = options_class_name + + # Does this descriptor have non-default options? + self.has_options = options is not None + + def _SetOptions(self, options, options_class_name): + """Sets the descriptor's options + + This function is used in generated proto2 files to update descriptor + options. It must not be used outside proto2. + """ + self._options = options + self._options_class_name = options_class_name + + # Does this descriptor have non-default options? + self.has_options = options is not None + + def GetOptions(self): + """Retrieves descriptor options. + + This method returns the options set or creates the default options for the + descriptor. + """ + if self._options: + return self._options + from google.protobuf import descriptor_pb2 + try: + options_class = getattr(descriptor_pb2, self._options_class_name) + except AttributeError: + raise RuntimeError('Unknown options class name %s!' % + (self._options_class_name)) + self._options = options_class() + return self._options + + +class _NestedDescriptorBase(DescriptorBase): + """Common class for descriptors that can be nested.""" + + def __init__(self, options, options_class_name, name, full_name, + file, containing_type, serialized_start=None, + serialized_end=None): + """Constructor. + + Args: + options: Protocol message options or None + to use default message options. + options_class_name: (str) The class name of the above options. + + name: (str) Name of this protocol message type. + full_name: (str) Fully-qualified name of this protocol message type, + which will include protocol "package" name and the name of any + enclosing types. + file: (FileDescriptor) Reference to file info. + containing_type: if provided, this is a nested descriptor, with this + descriptor as parent, otherwise None. + serialized_start: The start index (inclusive) in block in the + file.serialized_pb that describes this descriptor. + serialized_end: The end index (exclusive) in block in the + file.serialized_pb that describes this descriptor. + """ + super(_NestedDescriptorBase, self).__init__( + options, options_class_name) + + self.name = name + # TODO(falk): Add function to calculate full_name instead of having it in + # memory? + self.full_name = full_name + self.file = file + self.containing_type = containing_type + + self._serialized_start = serialized_start + self._serialized_end = serialized_end + + def GetTopLevelContainingType(self): + """Returns the root if this is a nested type, or itself if its the root.""" + desc = self + while desc.containing_type is not None: + desc = desc.containing_type + return desc + + def CopyToProto(self, proto): + """Copies this to the matching proto in descriptor_pb2. + + Args: + proto: An empty proto instance from descriptor_pb2. + + Raises: + Error: If self couldnt be serialized, due to to few constructor arguments. + """ + if (self.file is not None and + self._serialized_start is not None and + self._serialized_end is not None): + proto.ParseFromString(self.file.serialized_pb[ + self._serialized_start:self._serialized_end]) + else: + raise Error('Descriptor does not contain serialization.') + + +class Descriptor(_NestedDescriptorBase): + + """Descriptor for a protocol message type. + + A Descriptor instance has the following attributes: + + name: (str) Name of this protocol message type. + full_name: (str) Fully-qualified name of this protocol message type, + which will include protocol "package" name and the name of any + enclosing types. + + containing_type: (Descriptor) Reference to the descriptor of the + type containing us, or None if this is top-level. + + fields: (list of FieldDescriptors) Field descriptors for all + fields in this type. + fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor + objects as in |fields|, but indexed by "number" attribute in each + FieldDescriptor. + fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor + objects as in |fields|, but indexed by "name" attribute in each + FieldDescriptor. + + nested_types: (list of Descriptors) Descriptor references + for all protocol message types nested within this one. + nested_types_by_name: (dict str -> Descriptor) Same Descriptor + objects as in |nested_types|, but indexed by "name" attribute + in each Descriptor. + + enum_types: (list of EnumDescriptors) EnumDescriptor references + for all enums contained within this type. + enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor + objects as in |enum_types|, but indexed by "name" attribute + in each EnumDescriptor. + enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping + from enum value name to EnumValueDescriptor for that value. + + extensions: (list of FieldDescriptor) All extensions defined directly + within this message type (NOT within a nested type). + extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor + objects as |extensions|, but indexed by "name" attribute of each + FieldDescriptor. + + is_extendable: Does this type define any extension ranges? + + options: (descriptor_pb2.MessageOptions) Protocol message options or None + to use default message options. + + file: (FileDescriptor) Reference to file descriptor. + """ + + def __init__(self, name, full_name, filename, containing_type, fields, + nested_types, enum_types, extensions, options=None, + is_extendable=True, extension_ranges=None, file=None, + serialized_start=None, serialized_end=None): + """Arguments to __init__() are as described in the description + of Descriptor fields above. + + Note that filename is an obsolete argument, that is not used anymore. + Please use file.name to access this as an attribute. + """ + super(Descriptor, self).__init__( + options, 'MessageOptions', name, full_name, file, + containing_type, serialized_start=serialized_start, + serialized_end=serialized_start) + + # We have fields in addition to fields_by_name and fields_by_number, + # so that: + # 1. Clients can index fields by "order in which they're listed." + # 2. Clients can easily iterate over all fields with the terse + # syntax: for f in descriptor.fields: ... + self.fields = fields + for field in self.fields: + field.containing_type = self + self.fields_by_number = dict((f.number, f) for f in fields) + self.fields_by_name = dict((f.name, f) for f in fields) + + self.nested_types = nested_types + self.nested_types_by_name = dict((t.name, t) for t in nested_types) + + self.enum_types = enum_types + for enum_type in self.enum_types: + enum_type.containing_type = self + self.enum_types_by_name = dict((t.name, t) for t in enum_types) + self.enum_values_by_name = dict( + (v.name, v) for t in enum_types for v in t.values) + + self.extensions = extensions + for extension in self.extensions: + extension.extension_scope = self + self.extensions_by_name = dict((f.name, f) for f in extensions) + self.is_extendable = is_extendable + self.extension_ranges = extension_ranges + + self._serialized_start = serialized_start + self._serialized_end = serialized_end + + def EnumValueName(self, enum, value): + """Returns the string name of an enum value. + + This is just a small helper method to simplify a common operation. + + Args: + enum: string name of the Enum. + value: int, value of the enum. + + Returns: + string name of the enum value. + + Raises: + KeyError if either the Enum doesn't exist or the value is not a valid + value for the enum. + """ + return self.enum_types_by_name[enum].values_by_number[value].name + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.DescriptorProto. + + Args: + proto: An empty descriptor_pb2.DescriptorProto. + """ + # This function is overriden to give a better doc comment. + super(Descriptor, self).CopyToProto(proto) + + +# TODO(robinson): We should have aggressive checking here, +# for example: +# * If you specify a repeated field, you should not be allowed +# to specify a default value. +# * [Other examples here as needed]. +# +# TODO(robinson): for this and other *Descriptor classes, we +# might also want to lock things down aggressively (e.g., +# prevent clients from setting the attributes). Having +# stronger invariants here in general will reduce the number +# of runtime checks we must do in reflection.py... +class FieldDescriptor(DescriptorBase): + + """Descriptor for a single field in a .proto file. + + A FieldDescriptor instance has the following attributes: + + name: (str) Name of this field, exactly as it appears in .proto. + full_name: (str) Name of this field, including containing scope. This is + particularly relevant for extensions. + index: (int) Dense, 0-indexed index giving the order that this + field textually appears within its message in the .proto file. + number: (int) Tag number declared for this field in the .proto file. + + type: (One of the TYPE_* constants below) Declared type. + cpp_type: (One of the CPPTYPE_* constants below) C++ type used to + represent this field. + + label: (One of the LABEL_* constants below) Tells whether this + field is optional, required, or repeated. + has_default_value: (bool) True if this field has a default value defined, + otherwise false. + default_value: (Varies) Default value of this field. Only + meaningful for non-repeated scalar fields. Repeated fields + should always set this to [], and non-repeated composite + fields should always set this to None. + + containing_type: (Descriptor) Descriptor of the protocol message + type that contains this field. Set by the Descriptor constructor + if we're passed into one. + Somewhat confusingly, for extension fields, this is the + descriptor of the EXTENDED message, not the descriptor + of the message containing this field. (See is_extension and + extension_scope below). + message_type: (Descriptor) If a composite field, a descriptor + of the message type contained in this field. Otherwise, this is None. + enum_type: (EnumDescriptor) If this field contains an enum, a + descriptor of that enum. Otherwise, this is None. + + is_extension: True iff this describes an extension field. + extension_scope: (Descriptor) Only meaningful if is_extension is True. + Gives the message that immediately contains this extension field. + Will be None iff we're a top-level (file-level) extension field. + + options: (descriptor_pb2.FieldOptions) Protocol message field options or + None to use default field options. + """ + + # Must be consistent with C++ FieldDescriptor::Type enum in + # descriptor.h. + # + # TODO(robinson): Find a way to eliminate this repetition. + TYPE_DOUBLE = 1 + TYPE_FLOAT = 2 + TYPE_INT64 = 3 + TYPE_UINT64 = 4 + TYPE_INT32 = 5 + TYPE_FIXED64 = 6 + TYPE_FIXED32 = 7 + TYPE_BOOL = 8 + TYPE_STRING = 9 + TYPE_GROUP = 10 + TYPE_MESSAGE = 11 + TYPE_BYTES = 12 + TYPE_UINT32 = 13 + TYPE_ENUM = 14 + TYPE_SFIXED32 = 15 + TYPE_SFIXED64 = 16 + TYPE_SINT32 = 17 + TYPE_SINT64 = 18 + MAX_TYPE = 18 + + # Must be consistent with C++ FieldDescriptor::CppType enum in + # descriptor.h. + # + # TODO(robinson): Find a way to eliminate this repetition. + CPPTYPE_INT32 = 1 + CPPTYPE_INT64 = 2 + CPPTYPE_UINT32 = 3 + CPPTYPE_UINT64 = 4 + CPPTYPE_DOUBLE = 5 + CPPTYPE_FLOAT = 6 + CPPTYPE_BOOL = 7 + CPPTYPE_ENUM = 8 + CPPTYPE_STRING = 9 + CPPTYPE_MESSAGE = 10 + MAX_CPPTYPE = 10 + + _PYTHON_TO_CPP_PROTO_TYPE_MAP = { + TYPE_DOUBLE: CPPTYPE_DOUBLE, + TYPE_FLOAT: CPPTYPE_FLOAT, + TYPE_ENUM: CPPTYPE_ENUM, + TYPE_INT64: CPPTYPE_INT64, + TYPE_SINT64: CPPTYPE_INT64, + TYPE_SFIXED64: CPPTYPE_INT64, + TYPE_UINT64: CPPTYPE_UINT64, + TYPE_FIXED64: CPPTYPE_UINT64, + TYPE_INT32: CPPTYPE_INT32, + TYPE_SFIXED32: CPPTYPE_INT32, + TYPE_SINT32: CPPTYPE_INT32, + TYPE_UINT32: CPPTYPE_UINT32, + TYPE_FIXED32: CPPTYPE_UINT32, + TYPE_BYTES: CPPTYPE_STRING, + TYPE_STRING: CPPTYPE_STRING, + TYPE_BOOL: CPPTYPE_BOOL, + TYPE_MESSAGE: CPPTYPE_MESSAGE, + TYPE_GROUP: CPPTYPE_MESSAGE + } + + # Must be consistent with C++ FieldDescriptor::Label enum in + # descriptor.h. + # + # TODO(robinson): Find a way to eliminate this repetition. + LABEL_OPTIONAL = 1 + LABEL_REQUIRED = 2 + LABEL_REPEATED = 3 + MAX_LABEL = 3 + + def __init__(self, name, full_name, index, number, type, cpp_type, label, + default_value, message_type, enum_type, containing_type, + is_extension, extension_scope, options=None, + has_default_value=True): + """The arguments are as described in the description of FieldDescriptor + attributes above. + + Note that containing_type may be None, and may be set later if necessary + (to deal with circular references between message types, for example). + Likewise for extension_scope. + """ + super(FieldDescriptor, self).__init__(options, 'FieldOptions') + self.name = name + self.full_name = full_name + self.index = index + self.number = number + self.type = type + self.cpp_type = cpp_type + self.label = label + self.has_default_value = has_default_value + self.default_value = default_value + self.containing_type = containing_type + self.message_type = message_type + self.enum_type = enum_type + self.is_extension = is_extension + self.extension_scope = extension_scope + if api_implementation.Type() == 'cpp': + if is_extension: + if api_implementation.Version() == 2: + self._cdescriptor = _message.GetExtensionDescriptor(full_name) + else: + self._cdescriptor = cpp_message.GetExtensionDescriptor(full_name) + else: + if api_implementation.Version() == 2: + self._cdescriptor = _message.GetFieldDescriptor(full_name) + else: + self._cdescriptor = cpp_message.GetFieldDescriptor(full_name) + else: + self._cdescriptor = None + + @staticmethod + def ProtoTypeToCppProtoType(proto_type): + """Converts from a Python proto type to a C++ Proto Type. + + The Python ProtocolBuffer classes specify both the 'Python' datatype and the + 'C++' datatype - and they're not the same. This helper method should + translate from one to another. + + Args: + proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*) + Returns: + descriptor.FieldDescriptor.CPPTYPE_*, the C++ type. + Raises: + TypeTransformationError: when the Python proto type isn't known. + """ + try: + return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type] + except KeyError: + raise TypeTransformationError('Unknown proto_type: %s' % proto_type) + + +class EnumDescriptor(_NestedDescriptorBase): + + """Descriptor for an enum defined in a .proto file. + + An EnumDescriptor instance has the following attributes: + + name: (str) Name of the enum type. + full_name: (str) Full name of the type, including package name + and any enclosing type(s). + + values: (list of EnumValueDescriptors) List of the values + in this enum. + values_by_name: (dict str -> EnumValueDescriptor) Same as |values|, + but indexed by the "name" field of each EnumValueDescriptor. + values_by_number: (dict int -> EnumValueDescriptor) Same as |values|, + but indexed by the "number" field of each EnumValueDescriptor. + containing_type: (Descriptor) Descriptor of the immediate containing + type of this enum, or None if this is an enum defined at the + top level in a .proto file. Set by Descriptor's constructor + if we're passed into one. + file: (FileDescriptor) Reference to file descriptor. + options: (descriptor_pb2.EnumOptions) Enum options message or + None to use default enum options. + """ + + def __init__(self, name, full_name, filename, values, + containing_type=None, options=None, file=None, + serialized_start=None, serialized_end=None): + """Arguments are as described in the attribute description above. + + Note that filename is an obsolete argument, that is not used anymore. + Please use file.name to access this as an attribute. + """ + super(EnumDescriptor, self).__init__( + options, 'EnumOptions', name, full_name, file, + containing_type, serialized_start=serialized_start, + serialized_end=serialized_start) + + self.values = values + for value in self.values: + value.type = self + self.values_by_name = dict((v.name, v) for v in values) + self.values_by_number = dict((v.number, v) for v in values) + + self._serialized_start = serialized_start + self._serialized_end = serialized_end + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.EnumDescriptorProto. + + Args: + proto: An empty descriptor_pb2.EnumDescriptorProto. + """ + # This function is overriden to give a better doc comment. + super(EnumDescriptor, self).CopyToProto(proto) + + +class EnumValueDescriptor(DescriptorBase): + + """Descriptor for a single value within an enum. + + name: (str) Name of this value. + index: (int) Dense, 0-indexed index giving the order that this + value appears textually within its enum in the .proto file. + number: (int) Actual number assigned to this enum value. + type: (EnumDescriptor) EnumDescriptor to which this value + belongs. Set by EnumDescriptor's constructor if we're + passed into one. + options: (descriptor_pb2.EnumValueOptions) Enum value options message or + None to use default enum value options options. + """ + + def __init__(self, name, index, number, type=None, options=None): + """Arguments are as described in the attribute description above.""" + super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions') + self.name = name + self.index = index + self.number = number + self.type = type + + +class ServiceDescriptor(_NestedDescriptorBase): + + """Descriptor for a service. + + name: (str) Name of the service. + full_name: (str) Full name of the service, including package name. + index: (int) 0-indexed index giving the order that this services + definition appears withing the .proto file. + methods: (list of MethodDescriptor) List of methods provided by this + service. + options: (descriptor_pb2.ServiceOptions) Service options message or + None to use default service options. + file: (FileDescriptor) Reference to file info. + """ + + def __init__(self, name, full_name, index, methods, options=None, file=None, + serialized_start=None, serialized_end=None): + super(ServiceDescriptor, self).__init__( + options, 'ServiceOptions', name, full_name, file, + None, serialized_start=serialized_start, + serialized_end=serialized_end) + self.index = index + self.methods = methods + # Set the containing service for each method in this service. + for method in self.methods: + method.containing_service = self + + def FindMethodByName(self, name): + """Searches for the specified method, and returns its descriptor.""" + for method in self.methods: + if name == method.name: + return method + return None + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.ServiceDescriptorProto. + + Args: + proto: An empty descriptor_pb2.ServiceDescriptorProto. + """ + # This function is overriden to give a better doc comment. + super(ServiceDescriptor, self).CopyToProto(proto) + + +class MethodDescriptor(DescriptorBase): + + """Descriptor for a method in a service. + + name: (str) Name of the method within the service. + full_name: (str) Full name of method. + index: (int) 0-indexed index of the method inside the service. + containing_service: (ServiceDescriptor) The service that contains this + method. + input_type: The descriptor of the message that this method accepts. + output_type: The descriptor of the message that this method returns. + options: (descriptor_pb2.MethodOptions) Method options message or + None to use default method options. + """ + + def __init__(self, name, full_name, index, containing_service, + input_type, output_type, options=None): + """The arguments are as described in the description of MethodDescriptor + attributes above. + + Note that containing_service may be None, and may be set later if necessary. + """ + super(MethodDescriptor, self).__init__(options, 'MethodOptions') + self.name = name + self.full_name = full_name + self.index = index + self.containing_service = containing_service + self.input_type = input_type + self.output_type = output_type + + +class FileDescriptor(DescriptorBase): + """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. + + name: name of file, relative to root of source tree. + package: name of the package + serialized_pb: (str) Byte string of serialized + descriptor_pb2.FileDescriptorProto. + """ + + def __init__(self, name, package, options=None, serialized_pb=None): + """Constructor.""" + super(FileDescriptor, self).__init__(options, 'FileOptions') + + self.message_types_by_name = {} + self.name = name + self.package = package + self.serialized_pb = serialized_pb + if (api_implementation.Type() == 'cpp' and + self.serialized_pb is not None): + if api_implementation.Version() == 2: + _message.BuildFile(self.serialized_pb) + else: + cpp_message.BuildFile(self.serialized_pb) + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.FileDescriptorProto. + + Args: + proto: An empty descriptor_pb2.FileDescriptorProto. + """ + proto.ParseFromString(self.serialized_pb) + + +def _ParseOptions(message, string): + """Parses serialized options. + + This helper function is used to parse serialized options in generated + proto2 files. It must not be used outside proto2. + """ + message.ParseFromString(string) + return message + + +def MakeDescriptor(desc_proto, package=''): + """Make a protobuf Descriptor given a DescriptorProto protobuf. + + Args: + desc_proto: The descriptor_pb2.DescriptorProto protobuf message. + package: Optional package name for the new message Descriptor (string). + + Returns: + A Descriptor for protobuf messages. + """ + full_message_name = [desc_proto.name] + if package: full_message_name.insert(0, package) + fields = [] + for field_proto in desc_proto.field: + full_name = '.'.join(full_message_name + [field_proto.name]) + field = FieldDescriptor( + field_proto.name, full_name, field_proto.number - 1, + field_proto.number, field_proto.type, + FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), + field_proto.label, None, None, None, None, False, None, + has_default_value=False) + fields.append(field) + + desc_name = '.'.join(full_message_name) + return Descriptor(desc_proto.name, desc_name, None, None, fields, + [], [], []) diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor_database.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor_database.py new file mode 100644 index 0000000..8665d3c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor_database.py @@ -0,0 +1,120 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Provides a container for DescriptorProtos.""" + +__author__ = 'matthewtoia@google.com (Matt Toia)' + + +class DescriptorDatabase(object): + """A container accepting FileDescriptorProtos and maps DescriptorProtos.""" + + def __init__(self): + self._file_desc_protos_by_file = {} + self._file_desc_protos_by_symbol = {} + + def Add(self, file_desc_proto): + """Adds the FileDescriptorProto and its types to this database. + + Args: + file_desc_proto: The FileDescriptorProto to add. + """ + + self._file_desc_protos_by_file[file_desc_proto.name] = file_desc_proto + package = file_desc_proto.package + for message in file_desc_proto.message_type: + self._file_desc_protos_by_symbol.update( + (name, file_desc_proto) for name in _ExtractSymbols(message, package)) + for enum in file_desc_proto.enum_type: + self._file_desc_protos_by_symbol[ + '.'.join((package, enum.name))] = file_desc_proto + + def FindFileByName(self, name): + """Finds the file descriptor proto by file name. + + Typically the file name is a relative path ending to a .proto file. The + proto with the given name will have to have been added to this database + using the Add method or else an error will be raised. + + Args: + name: The file name to find. + + Returns: + The file descriptor proto matching the name. + + Raises: + KeyError if no file by the given name was added. + """ + + return self._file_desc_protos_by_file[name] + + def FindFileContainingSymbol(self, symbol): + """Finds the file descriptor proto containing the specified symbol. + + The symbol should be a fully qualified name including the file descriptor's + package and any containing messages. Some examples: + + 'some.package.name.Message' + 'some.package.name.Message.NestedEnum' + + The file descriptor proto containing the specified symbol must be added to + this database using the Add method or else an error will be raised. + + Args: + symbol: The fully qualified symbol name. + + Returns: + The file descriptor proto containing the symbol. + + Raises: + KeyError if no file contains the specified symbol. + """ + + return self._file_desc_protos_by_symbol[symbol] + + +def _ExtractSymbols(desc_proto, package): + """Pulls out all the symbols from a descriptor proto. + + Args: + desc_proto: The proto to extract symbols from. + package: The package containing the descriptor type. + + Yields: + The fully qualified name found in the descriptor. + """ + + message_name = '.'.join((package, desc_proto.name)) + yield message_name + for nested_type in desc_proto.nested_type: + for symbol in _ExtractSymbols(nested_type, message_name): + yield symbol + for enum_type in desc_proto.enum_type: + yield '.'.join((message_name, enum_type.name)) diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor_pool.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor_pool.py new file mode 100644 index 0000000..8f1f445 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/descriptor_pool.py @@ -0,0 +1,527 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Provides DescriptorPool to use as a container for proto2 descriptors. + +The DescriptorPool is used in conjection with a DescriptorDatabase to maintain +a collection of protocol buffer descriptors for use when dynamically creating +message types at runtime. + +For most applications protocol buffers should be used via modules generated by +the protocol buffer compiler tool. This should only be used when the type of +protocol buffers used in an application or library cannot be predetermined. + +Below is a straightforward example on how to use this class: + + pool = DescriptorPool() + file_descriptor_protos = [ ... ] + for file_descriptor_proto in file_descriptor_protos: + pool.Add(file_descriptor_proto) + my_message_descriptor = pool.FindMessageTypeByName('some.package.MessageType') + +The message descriptor can be used in conjunction with the message_factory +module in order to create a protocol buffer class that can be encoded and +decoded. +""" + +__author__ = 'matthewtoia@google.com (Matt Toia)' + +from google.protobuf import descriptor_pb2 +from google.protobuf import descriptor +from google.protobuf import descriptor_database + + +class DescriptorPool(object): + """A collection of protobufs dynamically constructed by descriptor protos.""" + + def __init__(self, descriptor_db=None): + """Initializes a Pool of proto buffs. + + The descriptor_db argument to the constructor is provided to allow + specialized file descriptor proto lookup code to be triggered on demand. An + example would be an implementation which will read and compile a file + specified in a call to FindFileByName() and not require the call to Add() + at all. Results from this database will be cached internally here as well. + + Args: + descriptor_db: A secondary source of file descriptors. + """ + + self._internal_db = descriptor_database.DescriptorDatabase() + self._descriptor_db = descriptor_db + self._descriptors = {} + self._enum_descriptors = {} + self._file_descriptors = {} + + def Add(self, file_desc_proto): + """Adds the FileDescriptorProto and its types to this pool. + + Args: + file_desc_proto: The FileDescriptorProto to add. + """ + + self._internal_db.Add(file_desc_proto) + + def FindFileByName(self, file_name): + """Gets a FileDescriptor by file name. + + Args: + file_name: The path to the file to get a descriptor for. + + Returns: + A FileDescriptor for the named file. + + Raises: + KeyError: if the file can not be found in the pool. + """ + + try: + file_proto = self._internal_db.FindFileByName(file_name) + except KeyError as error: + if self._descriptor_db: + file_proto = self._descriptor_db.FindFileByName(file_name) + else: + raise error + if not file_proto: + raise KeyError('Cannot find a file named %s' % file_name) + return self._ConvertFileProtoToFileDescriptor(file_proto) + + def FindFileContainingSymbol(self, symbol): + """Gets the FileDescriptor for the file containing the specified symbol. + + Args: + symbol: The name of the symbol to search for. + + Returns: + A FileDescriptor that contains the specified symbol. + + Raises: + KeyError: if the file can not be found in the pool. + """ + + try: + file_proto = self._internal_db.FindFileContainingSymbol(symbol) + except KeyError as error: + if self._descriptor_db: + file_proto = self._descriptor_db.FindFileContainingSymbol(symbol) + else: + raise error + if not file_proto: + raise KeyError('Cannot find a file containing %s' % symbol) + return self._ConvertFileProtoToFileDescriptor(file_proto) + + def FindMessageTypeByName(self, full_name): + """Loads the named descriptor from the pool. + + Args: + full_name: The full name of the descriptor to load. + + Returns: + The descriptor for the named type. + """ + + full_name = full_name.lstrip('.') # fix inconsistent qualified name formats + if full_name not in self._descriptors: + self.FindFileContainingSymbol(full_name) + return self._descriptors[full_name] + + def FindEnumTypeByName(self, full_name): + """Loads the named enum descriptor from the pool. + + Args: + full_name: The full name of the enum descriptor to load. + + Returns: + The enum descriptor for the named type. + """ + + full_name = full_name.lstrip('.') # fix inconsistent qualified name formats + if full_name not in self._enum_descriptors: + self.FindFileContainingSymbol(full_name) + return self._enum_descriptors[full_name] + + def _ConvertFileProtoToFileDescriptor(self, file_proto): + """Creates a FileDescriptor from a proto or returns a cached copy. + + This method also has the side effect of loading all the symbols found in + the file into the appropriate dictionaries in the pool. + + Args: + file_proto: The proto to convert. + + Returns: + A FileDescriptor matching the passed in proto. + """ + + if file_proto.name not in self._file_descriptors: + file_descriptor = descriptor.FileDescriptor( + name=file_proto.name, + package=file_proto.package, + options=file_proto.options, + serialized_pb=file_proto.SerializeToString()) + scope = {} + dependencies = list(self._GetDeps(file_proto)) + + for dependency in dependencies: + dep_desc = self.FindFileByName(dependency.name) + dep_proto = descriptor_pb2.FileDescriptorProto.FromString( + dep_desc.serialized_pb) + package = '.' + dep_proto.package + package_prefix = package + '.' + + def _strip_package(symbol): + if symbol.startswith(package_prefix): + return symbol[len(package_prefix):] + return symbol + + symbols = list(self._ExtractSymbols(dep_proto.message_type, package)) + scope.update(symbols) + scope.update((_strip_package(k), v) for k, v in symbols) + + symbols = list(self._ExtractEnums(dep_proto.enum_type, package)) + scope.update(symbols) + scope.update((_strip_package(k), v) for k, v in symbols) + + for message_type in file_proto.message_type: + message_desc = self._ConvertMessageDescriptor( + message_type, file_proto.package, file_descriptor, scope) + file_descriptor.message_types_by_name[message_desc.name] = message_desc + for enum_type in file_proto.enum_type: + self._ConvertEnumDescriptor(enum_type, file_proto.package, + file_descriptor, None, scope) + for desc_proto in self._ExtractMessages(file_proto.message_type): + self._SetFieldTypes(desc_proto, scope) + + for desc_proto in file_proto.message_type: + desc = scope[desc_proto.name] + file_descriptor.message_types_by_name[desc_proto.name] = desc + self.Add(file_proto) + self._file_descriptors[file_proto.name] = file_descriptor + + return self._file_descriptors[file_proto.name] + + def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None, + scope=None): + """Adds the proto to the pool in the specified package. + + Args: + desc_proto: The descriptor_pb2.DescriptorProto protobuf message. + package: The package the proto should be located in. + file_desc: The file containing this message. + scope: Dict mapping short and full symbols to message and enum types. + + Returns: + The added descriptor. + """ + + if package: + desc_name = '.'.join((package, desc_proto.name)) + else: + desc_name = desc_proto.name + + if file_desc is None: + file_name = None + else: + file_name = file_desc.name + + if scope is None: + scope = {} + + nested = [ + self._ConvertMessageDescriptor(nested, desc_name, file_desc, scope) + for nested in desc_proto.nested_type] + enums = [ + self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope) + for enum in desc_proto.enum_type] + fields = [self._MakeFieldDescriptor(field, desc_name, index) + for index, field in enumerate(desc_proto.field)] + extensions = [self._MakeFieldDescriptor(extension, desc_name, True) + for index, extension in enumerate(desc_proto.extension)] + extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range] + if extension_ranges: + is_extendable = True + else: + is_extendable = False + desc = descriptor.Descriptor( + name=desc_proto.name, + full_name=desc_name, + filename=file_name, + containing_type=None, + fields=fields, + nested_types=nested, + enum_types=enums, + extensions=extensions, + options=desc_proto.options, + is_extendable=is_extendable, + extension_ranges=extension_ranges, + file=file_desc, + serialized_start=None, + serialized_end=None) + for nested in desc.nested_types: + nested.containing_type = desc + for enum in desc.enum_types: + enum.containing_type = desc + scope[desc_proto.name] = desc + scope['.' + desc_name] = desc + self._descriptors[desc_name] = desc + return desc + + def _ConvertEnumDescriptor(self, enum_proto, package=None, file_desc=None, + containing_type=None, scope=None): + """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf. + + Args: + enum_proto: The descriptor_pb2.EnumDescriptorProto protobuf message. + package: Optional package name for the new message EnumDescriptor. + file_desc: The file containing the enum descriptor. + containing_type: The type containing this enum. + scope: Scope containing available types. + + Returns: + The added descriptor + """ + + if package: + enum_name = '.'.join((package, enum_proto.name)) + else: + enum_name = enum_proto.name + + if file_desc is None: + file_name = None + else: + file_name = file_desc.name + + values = [self._MakeEnumValueDescriptor(value, index) + for index, value in enumerate(enum_proto.value)] + desc = descriptor.EnumDescriptor(name=enum_proto.name, + full_name=enum_name, + filename=file_name, + file=file_desc, + values=values, + containing_type=containing_type, + options=enum_proto.options) + scope[enum_proto.name] = desc + scope['.%s' % enum_name] = desc + self._enum_descriptors[enum_name] = desc + return desc + + def _MakeFieldDescriptor(self, field_proto, message_name, index, + is_extension=False): + """Creates a field descriptor from a FieldDescriptorProto. + + For message and enum type fields, this method will do a look up + in the pool for the appropriate descriptor for that type. If it + is unavailable, it will fall back to the _source function to + create it. If this type is still unavailable, construction will + fail. + + Args: + field_proto: The proto describing the field. + message_name: The name of the containing message. + index: Index of the field + is_extension: Indication that this field is for an extension. + + Returns: + An initialized FieldDescriptor object + """ + + if message_name: + full_name = '.'.join((message_name, field_proto.name)) + else: + full_name = field_proto.name + + return descriptor.FieldDescriptor( + name=field_proto.name, + full_name=full_name, + index=index, + number=field_proto.number, + type=field_proto.type, + cpp_type=None, + message_type=None, + enum_type=None, + containing_type=None, + label=field_proto.label, + has_default_value=False, + default_value=None, + is_extension=is_extension, + extension_scope=None, + options=field_proto.options) + + def _SetFieldTypes(self, desc_proto, scope): + """Sets the field's type, cpp_type, message_type and enum_type. + + Args: + desc_proto: The message descriptor to update. + scope: Enclosing scope of available types. + """ + + desc = scope[desc_proto.name] + for field_proto, field_desc in zip(desc_proto.field, desc.fields): + if field_proto.type_name: + type_name = field_proto.type_name + if type_name not in scope: + type_name = '.' + type_name + desc = scope[type_name] + else: + desc = None + + if not field_proto.HasField('type'): + if isinstance(desc, descriptor.Descriptor): + field_proto.type = descriptor.FieldDescriptor.TYPE_MESSAGE + else: + field_proto.type = descriptor.FieldDescriptor.TYPE_ENUM + + field_desc.cpp_type = descriptor.FieldDescriptor.ProtoTypeToCppProtoType( + field_proto.type) + + if (field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE + or field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP): + field_desc.message_type = desc + + if field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: + field_desc.enum_type = desc + + if field_proto.label == descriptor.FieldDescriptor.LABEL_REPEATED: + field_desc.has_default = False + field_desc.default_value = [] + elif field_proto.HasField('default_value'): + field_desc.has_default = True + if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or + field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT): + field_desc.default_value = float(field_proto.default_value) + elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING: + field_desc.default_value = field_proto.default_value + elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL: + field_desc.default_value = field_proto.default_value.lower() == 'true' + elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: + field_desc.default_value = field_desc.enum_type.values_by_name[ + field_proto.default_value].index + else: + field_desc.default_value = int(field_proto.default_value) + else: + field_desc.has_default = False + field_desc.default_value = None + + field_desc.type = field_proto.type + + for nested_type in desc_proto.nested_type: + self._SetFieldTypes(nested_type, scope) + + def _MakeEnumValueDescriptor(self, value_proto, index): + """Creates a enum value descriptor object from a enum value proto. + + Args: + value_proto: The proto describing the enum value. + index: The index of the enum value. + + Returns: + An initialized EnumValueDescriptor object. + """ + + return descriptor.EnumValueDescriptor( + name=value_proto.name, + index=index, + number=value_proto.number, + options=value_proto.options, + type=None) + + def _ExtractSymbols(self, desc_protos, package): + """Pulls out all the symbols from descriptor protos. + + Args: + desc_protos: The protos to extract symbols from. + package: The package containing the descriptor type. + Yields: + A two element tuple of the type name and descriptor object. + """ + + for desc_proto in desc_protos: + if package: + message_name = '.'.join((package, desc_proto.name)) + else: + message_name = desc_proto.name + message_desc = self.FindMessageTypeByName(message_name) + yield (message_name, message_desc) + for symbol in self._ExtractSymbols(desc_proto.nested_type, message_name): + yield symbol + for symbol in self._ExtractEnums(desc_proto.enum_type, message_name): + yield symbol + + def _ExtractEnums(self, enum_protos, package): + """Pulls out all the symbols from enum protos. + + Args: + enum_protos: The protos to extract symbols from. + package: The package containing the enum type. + + Yields: + A two element tuple of the type name and enum descriptor object. + """ + + for enum_proto in enum_protos: + if package: + enum_name = '.'.join((package, enum_proto.name)) + else: + enum_name = enum_proto.name + enum_desc = self.FindEnumTypeByName(enum_name) + yield (enum_name, enum_desc) + + def _ExtractMessages(self, desc_protos): + """Pulls out all the message protos from descriptos. + + Args: + desc_protos: The protos to extract symbols from. + + Yields: + Descriptor protos. + """ + + for desc_proto in desc_protos: + yield desc_proto + for message in self._ExtractMessages(desc_proto.nested_type): + yield message + + def _GetDeps(self, file_proto): + """Recursively finds dependencies for file protos. + + Args: + file_proto: The proto to get dependencies from. + + Yields: + Each direct and indirect dependency. + """ + + for dependency in file_proto.dependency: + dep_desc = self.FindFileByName(dependency) + dep_proto = descriptor_pb2.FileDescriptorProto.FromString( + dep_desc.serialized_pb) + yield dep_proto + for parent_dep in self._GetDeps(dep_proto): + yield parent_dep diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/__init__.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/api_implementation.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/api_implementation.py new file mode 100755 index 0000000..ce02a32 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/api_implementation.py @@ -0,0 +1,87 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""" +This module is the central entity that determines which implementation of the +API is used. +""" + +__author__ = 'petar@google.com (Petar Petrov)' + +import os +# This environment variable can be used to switch to a certain implementation +# of the Python API. Right now only 'python' and 'cpp' are valid values. Any +# other value will be ignored. +_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION', + 'python') + + +if _implementation_type != 'python': + # For now, by default use the pure-Python implementation. + # The code below checks if the C extension is available and + # uses it if it is available. + _implementation_type = 'cpp' + ## Determine automatically which implementation to use. + #try: + # from google.protobuf.internal import cpp_message + # _implementation_type = 'cpp' + #except ImportError, e: + # _implementation_type = 'python' + + +# This environment variable can be used to switch between the two +# 'cpp' implementations. Right now only 1 and 2 are valid values. Any +# other value will be ignored. +_implementation_version_str = os.getenv( + 'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION', + '1') + + +if _implementation_version_str not in ('1', '2'): + raise ValueError( + "unsupported PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION: '" + + _implementation_version_str + "' (supported versions: 1, 2)" + ) + + +_implementation_version = int(_implementation_version_str) + + + +# Usage of this function is discouraged. Clients shouldn't care which +# implementation of the API is in use. Note that there is no guarantee +# that differences between APIs will be maintained. +# Please don't use this function if possible. +def Type(): + return _implementation_type + +# See comment on 'Type' above. +def Version(): + return _implementation_version diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/containers.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/containers.py new file mode 100755 index 0000000..34b35f8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/containers.py @@ -0,0 +1,269 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Contains container classes to represent different protocol buffer types. + +This file defines container classes which represent categories of protocol +buffer field types which need extra maintenance. Currently these categories +are: + - Repeated scalar fields - These are all repeated fields which aren't + composite (e.g. they are of simple types like int32, string, etc). + - Repeated composite fields - Repeated fields which are composite. This + includes groups and nested messages. +""" + +__author__ = 'petar@google.com (Petar Petrov)' + + +class BaseContainer(object): + + """Base container class.""" + + # Minimizes memory usage and disallows assignment to other attributes. + __slots__ = ['_message_listener', '_values'] + + def __init__(self, message_listener): + """ + Args: + message_listener: A MessageListener implementation. + The RepeatedScalarFieldContainer will call this object's + Modified() method when it is modified. + """ + self._message_listener = message_listener + self._values = [] + + def __getitem__(self, key): + """Retrieves item by the specified key.""" + return self._values[key] + + def __len__(self): + """Returns the number of elements in the container.""" + return len(self._values) + + def __ne__(self, other): + """Checks if another instance isn't equal to this one.""" + # The concrete classes should define __eq__. + return not self == other + + def __hash__(self): + raise TypeError('unhashable object') + + def __repr__(self): + return repr(self._values) + + def sort(self, *args, **kwargs): + # Continue to support the old sort_function keyword argument. + # This is expected to be a rare occurrence, so use LBYL to avoid + # the overhead of actually catching KeyError. + if 'sort_function' in kwargs: + kwargs['cmp'] = kwargs.pop('sort_function') + self._values.sort(*args, **kwargs) + + +class RepeatedScalarFieldContainer(BaseContainer): + + """Simple, type-checked, list-like container for holding repeated scalars.""" + + # Disallows assignment to other attributes. + __slots__ = ['_type_checker'] + + def __init__(self, message_listener, type_checker): + """ + Args: + message_listener: A MessageListener implementation. + The RepeatedScalarFieldContainer will call this object's + Modified() method when it is modified. + type_checker: A type_checkers.ValueChecker instance to run on elements + inserted into this container. + """ + super(RepeatedScalarFieldContainer, self).__init__(message_listener) + self._type_checker = type_checker + + def append(self, value): + """Appends an item to the list. Similar to list.append().""" + self._type_checker.CheckValue(value) + self._values.append(value) + if not self._message_listener.dirty: + self._message_listener.Modified() + + def insert(self, key, value): + """Inserts the item at the specified position. Similar to list.insert().""" + self._type_checker.CheckValue(value) + self._values.insert(key, value) + if not self._message_listener.dirty: + self._message_listener.Modified() + + def extend(self, elem_seq): + """Extends by appending the given sequence. Similar to list.extend().""" + if not elem_seq: + return + + new_values = [] + for elem in elem_seq: + self._type_checker.CheckValue(elem) + new_values.append(elem) + self._values.extend(new_values) + self._message_listener.Modified() + + def MergeFrom(self, other): + """Appends the contents of another repeated field of the same type to this + one. We do not check the types of the individual fields. + """ + self._values.extend(other._values) + self._message_listener.Modified() + + def remove(self, elem): + """Removes an item from the list. Similar to list.remove().""" + self._values.remove(elem) + self._message_listener.Modified() + + def __setitem__(self, key, value): + """Sets the item on the specified position.""" + self._type_checker.CheckValue(value) + self._values[key] = value + self._message_listener.Modified() + + def __getslice__(self, start, stop): + """Retrieves the subset of items from between the specified indices.""" + return self._values[start:stop] + + def __setslice__(self, start, stop, values): + """Sets the subset of items from between the specified indices.""" + new_values = [] + for value in values: + self._type_checker.CheckValue(value) + new_values.append(value) + self._values[start:stop] = new_values + self._message_listener.Modified() + + def __delitem__(self, key): + """Deletes the item at the specified position.""" + del self._values[key] + self._message_listener.Modified() + + def __delslice__(self, start, stop): + """Deletes the subset of items from between the specified indices.""" + del self._values[start:stop] + self._message_listener.Modified() + + def __eq__(self, other): + """Compares the current instance with another one.""" + if self is other: + return True + # Special case for the same type which should be common and fast. + if isinstance(other, self.__class__): + return other._values == self._values + # We are presumably comparing against some other sequence type. + return other == self._values + + +class RepeatedCompositeFieldContainer(BaseContainer): + + """Simple, list-like container for holding repeated composite fields.""" + + # Disallows assignment to other attributes. + __slots__ = ['_message_descriptor'] + + def __init__(self, message_listener, message_descriptor): + """ + Note that we pass in a descriptor instead of the generated directly, + since at the time we construct a _RepeatedCompositeFieldContainer we + haven't yet necessarily initialized the type that will be contained in the + container. + + Args: + message_listener: A MessageListener implementation. + The RepeatedCompositeFieldContainer will call this object's + Modified() method when it is modified. + message_descriptor: A Descriptor instance describing the protocol type + that should be present in this container. We'll use the + _concrete_class field of this descriptor when the client calls add(). + """ + super(RepeatedCompositeFieldContainer, self).__init__(message_listener) + self._message_descriptor = message_descriptor + + def add(self, **kwargs): + """Adds a new element at the end of the list and returns it. Keyword + arguments may be used to initialize the element. + """ + new_element = self._message_descriptor._concrete_class(**kwargs) + new_element._SetListener(self._message_listener) + self._values.append(new_element) + if not self._message_listener.dirty: + self._message_listener.Modified() + return new_element + + def extend(self, elem_seq): + """Extends by appending the given sequence of elements of the same type + as this one, copying each individual message. + """ + message_class = self._message_descriptor._concrete_class + listener = self._message_listener + values = self._values + for message in elem_seq: + new_element = message_class() + new_element._SetListener(listener) + new_element.MergeFrom(message) + values.append(new_element) + listener.Modified() + + def MergeFrom(self, other): + """Appends the contents of another repeated field of the same type to this + one, copying each individual message. + """ + self.extend(other._values) + + def remove(self, elem): + """Removes an item from the list. Similar to list.remove().""" + self._values.remove(elem) + self._message_listener.Modified() + + def __getslice__(self, start, stop): + """Retrieves the subset of items from between the specified indices.""" + return self._values[start:stop] + + def __delitem__(self, key): + """Deletes the item at the specified position.""" + del self._values[key] + self._message_listener.Modified() + + def __delslice__(self, start, stop): + """Deletes the subset of items from between the specified indices.""" + del self._values[start:stop] + self._message_listener.Modified() + + def __eq__(self, other): + """Compares the current instance with another one.""" + if self is other: + return True + if not isinstance(other, self.__class__): + raise TypeError('Can only compare repeated composite fields against ' + 'other repeated composite fields.') + return self._values == other._values diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/cpp_message.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/cpp_message.py new file mode 100755 index 0000000..23ab9ba --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/cpp_message.py @@ -0,0 +1,663 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Contains helper functions used to create protocol message classes from +Descriptor objects at runtime backed by the protocol buffer C++ API. +""" + +__author__ = 'petar@google.com (Petar Petrov)' + +import copy_reg +import operator +from google.protobuf.internal import _net_proto2___python +from google.protobuf.internal import enum_type_wrapper +from google.protobuf import message + + +_LABEL_REPEATED = _net_proto2___python.LABEL_REPEATED +_LABEL_OPTIONAL = _net_proto2___python.LABEL_OPTIONAL +_CPPTYPE_MESSAGE = _net_proto2___python.CPPTYPE_MESSAGE +_TYPE_MESSAGE = _net_proto2___python.TYPE_MESSAGE + + +def GetDescriptorPool(): + """Creates a new DescriptorPool C++ object.""" + return _net_proto2___python.NewCDescriptorPool() + + +_pool = GetDescriptorPool() + + +def GetFieldDescriptor(full_field_name): + """Searches for a field descriptor given a full field name.""" + return _pool.FindFieldByName(full_field_name) + + +def BuildFile(content): + """Registers a new proto file in the underlying C++ descriptor pool.""" + _net_proto2___python.BuildFile(content) + + +def GetExtensionDescriptor(full_extension_name): + """Searches for extension descriptor given a full field name.""" + return _pool.FindExtensionByName(full_extension_name) + + +def NewCMessage(full_message_name): + """Creates a new C++ protocol message by its name.""" + return _net_proto2___python.NewCMessage(full_message_name) + + +def ScalarProperty(cdescriptor): + """Returns a scalar property for the given descriptor.""" + + def Getter(self): + return self._cmsg.GetScalar(cdescriptor) + + def Setter(self, value): + self._cmsg.SetScalar(cdescriptor, value) + + return property(Getter, Setter) + + +def CompositeProperty(cdescriptor, message_type): + """Returns a Python property the given composite field.""" + + def Getter(self): + sub_message = self._composite_fields.get(cdescriptor.name, None) + if sub_message is None: + cmessage = self._cmsg.NewSubMessage(cdescriptor) + sub_message = message_type._concrete_class(__cmessage=cmessage) + self._composite_fields[cdescriptor.name] = sub_message + return sub_message + + return property(Getter) + + +class RepeatedScalarContainer(object): + """Container for repeated scalar fields.""" + + __slots__ = ['_message', '_cfield_descriptor', '_cmsg'] + + def __init__(self, msg, cfield_descriptor): + self._message = msg + self._cmsg = msg._cmsg + self._cfield_descriptor = cfield_descriptor + + def append(self, value): + self._cmsg.AddRepeatedScalar( + self._cfield_descriptor, value) + + def extend(self, sequence): + for element in sequence: + self.append(element) + + def insert(self, key, value): + values = self[slice(None, None, None)] + values.insert(key, value) + self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values) + + def remove(self, value): + values = self[slice(None, None, None)] + values.remove(value) + self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values) + + def __setitem__(self, key, value): + values = self[slice(None, None, None)] + values[key] = value + self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values) + + def __getitem__(self, key): + return self._cmsg.GetRepeatedScalar(self._cfield_descriptor, key) + + def __delitem__(self, key): + self._cmsg.DeleteRepeatedField(self._cfield_descriptor, key) + + def __len__(self): + return len(self[slice(None, None, None)]) + + def __eq__(self, other): + if self is other: + return True + if not operator.isSequenceType(other): + raise TypeError( + 'Can only compare repeated scalar fields against sequences.') + # We are presumably comparing against some other sequence type. + return other == self[slice(None, None, None)] + + def __ne__(self, other): + return not self == other + + def __hash__(self): + raise TypeError('unhashable object') + + def sort(self, *args, **kwargs): + # Maintain compatibility with the previous interface. + if 'sort_function' in kwargs: + kwargs['cmp'] = kwargs.pop('sort_function') + self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, + sorted(self, *args, **kwargs)) + + +def RepeatedScalarProperty(cdescriptor): + """Returns a Python property the given repeated scalar field.""" + + def Getter(self): + container = self._composite_fields.get(cdescriptor.name, None) + if container is None: + container = RepeatedScalarContainer(self, cdescriptor) + self._composite_fields[cdescriptor.name] = container + return container + + def Setter(self, new_value): + raise AttributeError('Assignment not allowed to repeated field ' + '"%s" in protocol message object.' % cdescriptor.name) + + doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name + return property(Getter, Setter, doc=doc) + + +class RepeatedCompositeContainer(object): + """Container for repeated composite fields.""" + + __slots__ = ['_message', '_subclass', '_cfield_descriptor', '_cmsg'] + + def __init__(self, msg, cfield_descriptor, subclass): + self._message = msg + self._cmsg = msg._cmsg + self._subclass = subclass + self._cfield_descriptor = cfield_descriptor + + def add(self, **kwargs): + cmessage = self._cmsg.AddMessage(self._cfield_descriptor) + return self._subclass(__cmessage=cmessage, __owner=self._message, **kwargs) + + def extend(self, elem_seq): + """Extends by appending the given sequence of elements of the same type + as this one, copying each individual message. + """ + for message in elem_seq: + self.add().MergeFrom(message) + + def remove(self, value): + # TODO(protocol-devel): This is inefficient as it needs to generate a + # message pointer for each message only to do index(). Move this to a C++ + # extension function. + self.__delitem__(self[slice(None, None, None)].index(value)) + + def MergeFrom(self, other): + for message in other[:]: + self.add().MergeFrom(message) + + def __getitem__(self, key): + cmessages = self._cmsg.GetRepeatedMessage( + self._cfield_descriptor, key) + subclass = self._subclass + if not isinstance(cmessages, list): + return subclass(__cmessage=cmessages, __owner=self._message) + + return [subclass(__cmessage=m, __owner=self._message) for m in cmessages] + + def __delitem__(self, key): + self._cmsg.DeleteRepeatedField( + self._cfield_descriptor, key) + + def __len__(self): + return self._cmsg.FieldLength(self._cfield_descriptor) + + def __eq__(self, other): + """Compares the current instance with another one.""" + if self is other: + return True + if not isinstance(other, self.__class__): + raise TypeError('Can only compare repeated composite fields against ' + 'other repeated composite fields.') + messages = self[slice(None, None, None)] + other_messages = other[slice(None, None, None)] + return messages == other_messages + + def __hash__(self): + raise TypeError('unhashable object') + + def sort(self, cmp=None, key=None, reverse=False, **kwargs): + # Maintain compatibility with the old interface. + if cmp is None and 'sort_function' in kwargs: + cmp = kwargs.pop('sort_function') + + # The cmp function, if provided, is passed the results of the key function, + # so we only need to wrap one of them. + if key is None: + index_key = self.__getitem__ + else: + index_key = lambda i: key(self[i]) + + # Sort the list of current indexes by the underlying object. + indexes = range(len(self)) + indexes.sort(cmp=cmp, key=index_key, reverse=reverse) + + # Apply the transposition. + for dest, src in enumerate(indexes): + if dest == src: + continue + self._cmsg.SwapRepeatedFieldElements(self._cfield_descriptor, dest, src) + # Don't swap the same value twice. + indexes[src] = src + + +def RepeatedCompositeProperty(cdescriptor, message_type): + """Returns a Python property for the given repeated composite field.""" + + def Getter(self): + container = self._composite_fields.get(cdescriptor.name, None) + if container is None: + container = RepeatedCompositeContainer( + self, cdescriptor, message_type._concrete_class) + self._composite_fields[cdescriptor.name] = container + return container + + def Setter(self, new_value): + raise AttributeError('Assignment not allowed to repeated field ' + '"%s" in protocol message object.' % cdescriptor.name) + + doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name + return property(Getter, Setter, doc=doc) + + +class ExtensionDict(object): + """Extension dictionary added to each protocol message.""" + + def __init__(self, msg): + self._message = msg + self._cmsg = msg._cmsg + self._values = {} + + def __setitem__(self, extension, value): + from google.protobuf import descriptor + if not isinstance(extension, descriptor.FieldDescriptor): + raise KeyError('Bad extension %r.' % (extension,)) + cdescriptor = extension._cdescriptor + if (cdescriptor.label != _LABEL_OPTIONAL or + cdescriptor.cpp_type == _CPPTYPE_MESSAGE): + raise TypeError('Extension %r is repeated and/or a composite type.' % ( + extension.full_name,)) + self._cmsg.SetScalar(cdescriptor, value) + self._values[extension] = value + + def __getitem__(self, extension): + from google.protobuf import descriptor + if not isinstance(extension, descriptor.FieldDescriptor): + raise KeyError('Bad extension %r.' % (extension,)) + + cdescriptor = extension._cdescriptor + if (cdescriptor.label != _LABEL_REPEATED and + cdescriptor.cpp_type != _CPPTYPE_MESSAGE): + return self._cmsg.GetScalar(cdescriptor) + + ext = self._values.get(extension, None) + if ext is not None: + return ext + + ext = self._CreateNewHandle(extension) + self._values[extension] = ext + return ext + + def ClearExtension(self, extension): + from google.protobuf import descriptor + if not isinstance(extension, descriptor.FieldDescriptor): + raise KeyError('Bad extension %r.' % (extension,)) + self._cmsg.ClearFieldByDescriptor(extension._cdescriptor) + if extension in self._values: + del self._values[extension] + + def HasExtension(self, extension): + from google.protobuf import descriptor + if not isinstance(extension, descriptor.FieldDescriptor): + raise KeyError('Bad extension %r.' % (extension,)) + return self._cmsg.HasFieldByDescriptor(extension._cdescriptor) + + def _FindExtensionByName(self, name): + """Tries to find a known extension with the specified name. + + Args: + name: Extension full name. + + Returns: + Extension field descriptor. + """ + return self._message._extensions_by_name.get(name, None) + + def _CreateNewHandle(self, extension): + cdescriptor = extension._cdescriptor + if (cdescriptor.label != _LABEL_REPEATED and + cdescriptor.cpp_type == _CPPTYPE_MESSAGE): + cmessage = self._cmsg.NewSubMessage(cdescriptor) + return extension.message_type._concrete_class(__cmessage=cmessage) + + if cdescriptor.label == _LABEL_REPEATED: + if cdescriptor.cpp_type == _CPPTYPE_MESSAGE: + return RepeatedCompositeContainer( + self._message, cdescriptor, extension.message_type._concrete_class) + else: + return RepeatedScalarContainer(self._message, cdescriptor) + # This shouldn't happen! + assert False + return None + + +def NewMessage(bases, message_descriptor, dictionary): + """Creates a new protocol message *class*.""" + _AddClassAttributesForNestedExtensions(message_descriptor, dictionary) + _AddEnumValues(message_descriptor, dictionary) + _AddDescriptors(message_descriptor, dictionary) + return bases + + +def InitMessage(message_descriptor, cls): + """Constructs a new message instance (called before instance's __init__).""" + cls._extensions_by_name = {} + _AddInitMethod(message_descriptor, cls) + _AddMessageMethods(message_descriptor, cls) + _AddPropertiesForExtensions(message_descriptor, cls) + copy_reg.pickle(cls, lambda obj: (cls, (), obj.__getstate__())) + + +def _AddDescriptors(message_descriptor, dictionary): + """Sets up a new protocol message class dictionary. + + Args: + message_descriptor: A Descriptor instance describing this message type. + dictionary: Class dictionary to which we'll add a '__slots__' entry. + """ + dictionary['__descriptors'] = {} + for field in message_descriptor.fields: + dictionary['__descriptors'][field.name] = GetFieldDescriptor( + field.full_name) + + dictionary['__slots__'] = list(dictionary['__descriptors'].iterkeys()) + [ + '_cmsg', '_owner', '_composite_fields', 'Extensions', '_HACK_REFCOUNTS'] + + +def _AddEnumValues(message_descriptor, dictionary): + """Sets class-level attributes for all enum fields defined in this message. + + Args: + message_descriptor: Descriptor object for this message type. + dictionary: Class dictionary that should be populated. + """ + for enum_type in message_descriptor.enum_types: + dictionary[enum_type.name] = enum_type_wrapper.EnumTypeWrapper(enum_type) + for enum_value in enum_type.values: + dictionary[enum_value.name] = enum_value.number + + +def _AddClassAttributesForNestedExtensions(message_descriptor, dictionary): + """Adds class attributes for the nested extensions.""" + extension_dict = message_descriptor.extensions_by_name + for extension_name, extension_field in extension_dict.iteritems(): + assert extension_name not in dictionary + dictionary[extension_name] = extension_field + + +def _AddInitMethod(message_descriptor, cls): + """Adds an __init__ method to cls.""" + + # Create and attach message field properties to the message class. + # This can be done just once per message class, since property setters and + # getters are passed the message instance. + # This makes message instantiation extremely fast, and at the same time it + # doesn't require the creation of property objects for each message instance, + # which saves a lot of memory. + for field in message_descriptor.fields: + field_cdescriptor = cls.__descriptors[field.name] + if field.label == _LABEL_REPEATED: + if field.cpp_type == _CPPTYPE_MESSAGE: + value = RepeatedCompositeProperty(field_cdescriptor, field.message_type) + else: + value = RepeatedScalarProperty(field_cdescriptor) + elif field.cpp_type == _CPPTYPE_MESSAGE: + value = CompositeProperty(field_cdescriptor, field.message_type) + else: + value = ScalarProperty(field_cdescriptor) + setattr(cls, field.name, value) + + # Attach a constant with the field number. + constant_name = field.name.upper() + '_FIELD_NUMBER' + setattr(cls, constant_name, field.number) + + def Init(self, **kwargs): + """Message constructor.""" + cmessage = kwargs.pop('__cmessage', None) + if cmessage: + self._cmsg = cmessage + else: + self._cmsg = NewCMessage(message_descriptor.full_name) + + # Keep a reference to the owner, as the owner keeps a reference to the + # underlying protocol buffer message. + owner = kwargs.pop('__owner', None) + if owner: + self._owner = owner + + if message_descriptor.is_extendable: + self.Extensions = ExtensionDict(self) + else: + # Reference counting in the C++ code is broken and depends on + # the Extensions reference to keep this object alive during unit + # tests (see b/4856052). Remove this once b/4945904 is fixed. + self._HACK_REFCOUNTS = self + self._composite_fields = {} + + for field_name, field_value in kwargs.iteritems(): + field_cdescriptor = self.__descriptors.get(field_name, None) + if not field_cdescriptor: + raise ValueError('Protocol message has no "%s" field.' % field_name) + if field_cdescriptor.label == _LABEL_REPEATED: + if field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE: + field_name = getattr(self, field_name) + for val in field_value: + field_name.add().MergeFrom(val) + else: + getattr(self, field_name).extend(field_value) + elif field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE: + getattr(self, field_name).MergeFrom(field_value) + else: + setattr(self, field_name, field_value) + + Init.__module__ = None + Init.__doc__ = None + cls.__init__ = Init + + +def _IsMessageSetExtension(field): + """Checks if a field is a message set extension.""" + return (field.is_extension and + field.containing_type.has_options and + field.containing_type.GetOptions().message_set_wire_format and + field.type == _TYPE_MESSAGE and + field.message_type == field.extension_scope and + field.label == _LABEL_OPTIONAL) + + +def _AddMessageMethods(message_descriptor, cls): + """Adds the methods to a protocol message class.""" + if message_descriptor.is_extendable: + + def ClearExtension(self, extension): + self.Extensions.ClearExtension(extension) + + def HasExtension(self, extension): + return self.Extensions.HasExtension(extension) + + def HasField(self, field_name): + return self._cmsg.HasField(field_name) + + def ClearField(self, field_name): + child_cmessage = None + if field_name in self._composite_fields: + child_field = self._composite_fields[field_name] + del self._composite_fields[field_name] + + child_cdescriptor = self.__descriptors[field_name] + # TODO(anuraag): Support clearing repeated message fields as well. + if (child_cdescriptor.label != _LABEL_REPEATED and + child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE): + child_field._owner = None + child_cmessage = child_field._cmsg + + if child_cmessage is not None: + self._cmsg.ClearField(field_name, child_cmessage) + else: + self._cmsg.ClearField(field_name) + + def Clear(self): + cmessages_to_release = [] + for field_name, child_field in self._composite_fields.iteritems(): + child_cdescriptor = self.__descriptors[field_name] + # TODO(anuraag): Support clearing repeated message fields as well. + if (child_cdescriptor.label != _LABEL_REPEATED and + child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE): + child_field._owner = None + cmessages_to_release.append((child_cdescriptor, child_field._cmsg)) + self._composite_fields.clear() + self._cmsg.Clear(cmessages_to_release) + + def IsInitialized(self, errors=None): + if self._cmsg.IsInitialized(): + return True + if errors is not None: + errors.extend(self.FindInitializationErrors()); + return False + + def SerializeToString(self): + if not self.IsInitialized(): + raise message.EncodeError( + 'Message %s is missing required fields: %s' % ( + self._cmsg.full_name, ','.join(self.FindInitializationErrors()))) + return self._cmsg.SerializeToString() + + def SerializePartialToString(self): + return self._cmsg.SerializePartialToString() + + def ParseFromString(self, serialized): + self.Clear() + self.MergeFromString(serialized) + + def MergeFromString(self, serialized): + byte_size = self._cmsg.MergeFromString(serialized) + if byte_size < 0: + raise message.DecodeError('Unable to merge from string.') + return byte_size + + def MergeFrom(self, msg): + if not isinstance(msg, cls): + raise TypeError( + "Parameter to MergeFrom() must be instance of same class: " + "expected %s got %s." % (cls.__name__, type(msg).__name__)) + self._cmsg.MergeFrom(msg._cmsg) + + def CopyFrom(self, msg): + self._cmsg.CopyFrom(msg._cmsg) + + def ByteSize(self): + return self._cmsg.ByteSize() + + def SetInParent(self): + return self._cmsg.SetInParent() + + def ListFields(self): + all_fields = [] + field_list = self._cmsg.ListFields() + fields_by_name = cls.DESCRIPTOR.fields_by_name + for is_extension, field_name in field_list: + if is_extension: + extension = cls._extensions_by_name[field_name] + all_fields.append((extension, self.Extensions[extension])) + else: + field_descriptor = fields_by_name[field_name] + all_fields.append( + (field_descriptor, getattr(self, field_name))) + all_fields.sort(key=lambda item: item[0].number) + return all_fields + + def FindInitializationErrors(self): + return self._cmsg.FindInitializationErrors() + + def __str__(self): + return self._cmsg.DebugString() + + def __eq__(self, other): + if self is other: + return True + if not isinstance(other, self.__class__): + return False + return self.ListFields() == other.ListFields() + + def __ne__(self, other): + return not self == other + + def __hash__(self): + raise TypeError('unhashable object') + + def __unicode__(self): + # Lazy import to prevent circular import when text_format imports this file. + from google.protobuf import text_format + return text_format.MessageToString(self, as_utf8=True).decode('utf-8') + + # Attach the local methods to the message class. + for key, value in locals().copy().iteritems(): + if key not in ('key', 'value', '__builtins__', '__name__', '__doc__'): + setattr(cls, key, value) + + # Static methods: + + def RegisterExtension(extension_handle): + extension_handle.containing_type = cls.DESCRIPTOR + cls._extensions_by_name[extension_handle.full_name] = extension_handle + + if _IsMessageSetExtension(extension_handle): + # MessageSet extension. Also register under type name. + cls._extensions_by_name[ + extension_handle.message_type.full_name] = extension_handle + cls.RegisterExtension = staticmethod(RegisterExtension) + + def FromString(string): + msg = cls() + msg.MergeFromString(string) + return msg + cls.FromString = staticmethod(FromString) + + + +def _AddPropertiesForExtensions(message_descriptor, cls): + """Adds properties for all fields in this protocol message type.""" + extension_dict = message_descriptor.extensions_by_name + for extension_name, extension_field in extension_dict.iteritems(): + constant_name = extension_name.upper() + '_FIELD_NUMBER' + setattr(cls, constant_name, extension_field.number) diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/decoder.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/decoder.py new file mode 100755 index 0000000..cb6f572 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/decoder.py @@ -0,0 +1,720 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Code for decoding protocol buffer primitives. + +This code is very similar to encoder.py -- read the docs for that module first. + +A "decoder" is a function with the signature: + Decode(buffer, pos, end, message, field_dict) +The arguments are: + buffer: The string containing the encoded message. + pos: The current position in the string. + end: The position in the string where the current message ends. May be + less than len(buffer) if we're reading a sub-message. + message: The message object into which we're parsing. + field_dict: message._fields (avoids a hashtable lookup). +The decoder reads the field and stores it into field_dict, returning the new +buffer position. A decoder for a repeated field may proactively decode all of +the elements of that field, if they appear consecutively. + +Note that decoders may throw any of the following: + IndexError: Indicates a truncated message. + struct.error: Unpacking of a fixed-width field failed. + message.DecodeError: Other errors. + +Decoders are expected to raise an exception if they are called with pos > end. +This allows callers to be lax about bounds checking: it's fineto read past +"end" as long as you are sure that someone else will notice and throw an +exception later on. + +Something up the call stack is expected to catch IndexError and struct.error +and convert them to message.DecodeError. + +Decoders are constructed using decoder constructors with the signature: + MakeDecoder(field_number, is_repeated, is_packed, key, new_default) +The arguments are: + field_number: The field number of the field we want to decode. + is_repeated: Is the field a repeated field? (bool) + is_packed: Is the field a packed field? (bool) + key: The key to use when looking up the field within field_dict. + (This is actually the FieldDescriptor but nothing in this + file should depend on that.) + new_default: A function which takes a message object as a parameter and + returns a new instance of the default value for this field. + (This is called for repeated fields and sub-messages, when an + instance does not already exist.) + +As with encoders, we define a decoder constructor for every type of field. +Then, for every field of every message class we construct an actual decoder. +That decoder goes into a dict indexed by tag, so when we decode a message +we repeatedly read a tag, look up the corresponding decoder, and invoke it. +""" + +__author__ = 'kenton@google.com (Kenton Varda)' + +import struct +from google.protobuf.internal import encoder +from google.protobuf.internal import wire_format +from google.protobuf import message + + +# This will overflow and thus become IEEE-754 "infinity". We would use +# "float('inf')" but it doesn't work on Windows pre-Python-2.6. +_POS_INF = 1e10000 +_NEG_INF = -_POS_INF +_NAN = _POS_INF * 0 + + +# This is not for optimization, but rather to avoid conflicts with local +# variables named "message". +_DecodeError = message.DecodeError + + +def _VarintDecoder(mask): + """Return an encoder for a basic varint value (does not include tag). + + Decoded values will be bitwise-anded with the given mask before being + returned, e.g. to limit them to 32 bits. The returned decoder does not + take the usual "end" parameter -- the caller is expected to do bounds checking + after the fact (often the caller can defer such checking until later). The + decoder returns a (value, new_pos) pair. + """ + + local_ord = ord + def DecodeVarint(buffer, pos): + result = 0 + shift = 0 + while 1: + b = local_ord(buffer[pos]) + result |= ((b & 0x7f) << shift) + pos += 1 + if not (b & 0x80): + result &= mask + return (result, pos) + shift += 7 + if shift >= 64: + raise _DecodeError('Too many bytes when decoding varint.') + return DecodeVarint + + +def _SignedVarintDecoder(mask): + """Like _VarintDecoder() but decodes signed values.""" + + local_ord = ord + def DecodeVarint(buffer, pos): + result = 0 + shift = 0 + while 1: + b = local_ord(buffer[pos]) + result |= ((b & 0x7f) << shift) + pos += 1 + if not (b & 0x80): + if result > 0x7fffffffffffffff: + result -= (1 << 64) + result |= ~mask + else: + result &= mask + return (result, pos) + shift += 7 + if shift >= 64: + raise _DecodeError('Too many bytes when decoding varint.') + return DecodeVarint + + +_DecodeVarint = _VarintDecoder((1 << 64) - 1) +_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1) + +# Use these versions for values which must be limited to 32 bits. +_DecodeVarint32 = _VarintDecoder((1 << 32) - 1) +_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1) + + +def ReadTag(buffer, pos): + """Read a tag from the buffer, and return a (tag_bytes, new_pos) tuple. + + We return the raw bytes of the tag rather than decoding them. The raw + bytes can then be used to look up the proper decoder. This effectively allows + us to trade some work that would be done in pure-python (decoding a varint) + for work that is done in C (searching for a byte string in a hash table). + In a low-level language it would be much cheaper to decode the varint and + use that, but not in Python. + """ + + start = pos + while ord(buffer[pos]) & 0x80: + pos += 1 + pos += 1 + return (buffer[start:pos], pos) + + +# -------------------------------------------------------------------- + + +def _SimpleDecoder(wire_type, decode_value): + """Return a constructor for a decoder for fields of a particular type. + + Args: + wire_type: The field's wire type. + decode_value: A function which decodes an individual value, e.g. + _DecodeVarint() + """ + + def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default): + if is_packed: + local_DecodeVarint = _DecodeVarint + def DecodePackedField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + (endpoint, pos) = local_DecodeVarint(buffer, pos) + endpoint += pos + if endpoint > end: + raise _DecodeError('Truncated message.') + while pos < endpoint: + (element, pos) = decode_value(buffer, pos) + value.append(element) + if pos > endpoint: + del value[-1] # Discard corrupt value. + raise _DecodeError('Packed element was truncated.') + return pos + return DecodePackedField + elif is_repeated: + tag_bytes = encoder.TagBytes(field_number, wire_type) + tag_len = len(tag_bytes) + def DecodeRepeatedField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + (element, new_pos) = decode_value(buffer, pos) + value.append(element) + # Predict that the next tag is another copy of the same repeated + # field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos >= end: + # Prediction failed. Return. + if new_pos > end: + raise _DecodeError('Truncated message.') + return new_pos + return DecodeRepeatedField + else: + def DecodeField(buffer, pos, end, message, field_dict): + (field_dict[key], pos) = decode_value(buffer, pos) + if pos > end: + del field_dict[key] # Discard corrupt value. + raise _DecodeError('Truncated message.') + return pos + return DecodeField + + return SpecificDecoder + + +def _ModifiedDecoder(wire_type, decode_value, modify_value): + """Like SimpleDecoder but additionally invokes modify_value on every value + before storing it. Usually modify_value is ZigZagDecode. + """ + + # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but + # not enough to make a significant difference. + + def InnerDecode(buffer, pos): + (result, new_pos) = decode_value(buffer, pos) + return (modify_value(result), new_pos) + return _SimpleDecoder(wire_type, InnerDecode) + + +def _StructPackDecoder(wire_type, format): + """Return a constructor for a decoder for a fixed-width field. + + Args: + wire_type: The field's wire type. + format: The format string to pass to struct.unpack(). + """ + + value_size = struct.calcsize(format) + local_unpack = struct.unpack + + # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but + # not enough to make a significant difference. + + # Note that we expect someone up-stack to catch struct.error and convert + # it to _DecodeError -- this way we don't have to set up exception- + # handling blocks every time we parse one value. + + def InnerDecode(buffer, pos): + new_pos = pos + value_size + result = local_unpack(format, buffer[pos:new_pos])[0] + return (result, new_pos) + return _SimpleDecoder(wire_type, InnerDecode) + + +def _FloatDecoder(): + """Returns a decoder for a float field. + + This code works around a bug in struct.unpack for non-finite 32-bit + floating-point values. + """ + + local_unpack = struct.unpack + + def InnerDecode(buffer, pos): + # We expect a 32-bit value in little-endian byte order. Bit 1 is the sign + # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand. + new_pos = pos + 4 + float_bytes = buffer[pos:new_pos] + + # If this value has all its exponent bits set, then it's non-finite. + # In Python 2.4, struct.unpack will convert it to a finite 64-bit value. + # To avoid that, we parse it specially. + if ((float_bytes[3] in '\x7F\xFF') + and (float_bytes[2] >= '\x80')): + # If at least one significand bit is set... + if float_bytes[0:3] != '\x00\x00\x80': + return (_NAN, new_pos) + # If sign bit is set... + if float_bytes[3] == '\xFF': + return (_NEG_INF, new_pos) + return (_POS_INF, new_pos) + + # Note that we expect someone up-stack to catch struct.error and convert + # it to _DecodeError -- this way we don't have to set up exception- + # handling blocks every time we parse one value. + result = local_unpack('= '\xF0') + and (double_bytes[0:7] != '\x00\x00\x00\x00\x00\x00\xF0')): + return (_NAN, new_pos) + + # Note that we expect someone up-stack to catch struct.error and convert + # it to _DecodeError -- this way we don't have to set up exception- + # handling blocks every time we parse one value. + result = local_unpack(' end: + raise _DecodeError('Truncated string.') + value.append(local_unicode(buffer[pos:new_pos], 'utf-8')) + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + return DecodeRepeatedField + else: + def DecodeField(buffer, pos, end, message, field_dict): + (size, pos) = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated string.') + field_dict[key] = local_unicode(buffer[pos:new_pos], 'utf-8') + return new_pos + return DecodeField + + +def BytesDecoder(field_number, is_repeated, is_packed, key, new_default): + """Returns a decoder for a bytes field.""" + + local_DecodeVarint = _DecodeVarint + + assert not is_packed + if is_repeated: + tag_bytes = encoder.TagBytes(field_number, + wire_format.WIRETYPE_LENGTH_DELIMITED) + tag_len = len(tag_bytes) + def DecodeRepeatedField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + (size, pos) = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated string.') + value.append(buffer[pos:new_pos]) + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + return DecodeRepeatedField + else: + def DecodeField(buffer, pos, end, message, field_dict): + (size, pos) = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated string.') + field_dict[key] = buffer[pos:new_pos] + return new_pos + return DecodeField + + +def GroupDecoder(field_number, is_repeated, is_packed, key, new_default): + """Returns a decoder for a group field.""" + + end_tag_bytes = encoder.TagBytes(field_number, + wire_format.WIRETYPE_END_GROUP) + end_tag_len = len(end_tag_bytes) + + assert not is_packed + if is_repeated: + tag_bytes = encoder.TagBytes(field_number, + wire_format.WIRETYPE_START_GROUP) + tag_len = len(tag_bytes) + def DecodeRepeatedField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + # Read sub-message. + pos = value.add()._InternalParse(buffer, pos, end) + # Read end tag. + new_pos = pos+end_tag_len + if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: + raise _DecodeError('Missing group end tag.') + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + return DecodeRepeatedField + else: + def DecodeField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + # Read sub-message. + pos = value._InternalParse(buffer, pos, end) + # Read end tag. + new_pos = pos+end_tag_len + if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: + raise _DecodeError('Missing group end tag.') + return new_pos + return DecodeField + + +def MessageDecoder(field_number, is_repeated, is_packed, key, new_default): + """Returns a decoder for a message field.""" + + local_DecodeVarint = _DecodeVarint + + assert not is_packed + if is_repeated: + tag_bytes = encoder.TagBytes(field_number, + wire_format.WIRETYPE_LENGTH_DELIMITED) + tag_len = len(tag_bytes) + def DecodeRepeatedField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + # Read length. + (size, pos) = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated message.') + # Read sub-message. + if value.add()._InternalParse(buffer, pos, new_pos) != new_pos: + # The only reason _InternalParse would return early is if it + # encountered an end-group tag. + raise _DecodeError('Unexpected end-group tag.') + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + return DecodeRepeatedField + else: + def DecodeField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + # Read length. + (size, pos) = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated message.') + # Read sub-message. + if value._InternalParse(buffer, pos, new_pos) != new_pos: + # The only reason _InternalParse would return early is if it encountered + # an end-group tag. + raise _DecodeError('Unexpected end-group tag.') + return new_pos + return DecodeField + + +# -------------------------------------------------------------------- + +MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP) + +def MessageSetItemDecoder(extensions_by_number): + """Returns a decoder for a MessageSet item. + + The parameter is the _extensions_by_number map for the message class. + + The message set message looks like this: + message MessageSet { + repeated group Item = 1 { + required int32 type_id = 2; + required string message = 3; + } + } + """ + + type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT) + message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED) + item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP) + + local_ReadTag = ReadTag + local_DecodeVarint = _DecodeVarint + local_SkipField = SkipField + + def DecodeItem(buffer, pos, end, message, field_dict): + message_set_item_start = pos + type_id = -1 + message_start = -1 + message_end = -1 + + # Technically, type_id and message can appear in any order, so we need + # a little loop here. + while 1: + (tag_bytes, pos) = local_ReadTag(buffer, pos) + if tag_bytes == type_id_tag_bytes: + (type_id, pos) = local_DecodeVarint(buffer, pos) + elif tag_bytes == message_tag_bytes: + (size, message_start) = local_DecodeVarint(buffer, pos) + pos = message_end = message_start + size + elif tag_bytes == item_end_tag_bytes: + break + else: + pos = SkipField(buffer, pos, end, tag_bytes) + if pos == -1: + raise _DecodeError('Missing group end tag.') + + if pos > end: + raise _DecodeError('Truncated message.') + + if type_id == -1: + raise _DecodeError('MessageSet item missing type_id.') + if message_start == -1: + raise _DecodeError('MessageSet item missing message.') + + extension = extensions_by_number.get(type_id) + if extension is not None: + value = field_dict.get(extension) + if value is None: + value = field_dict.setdefault( + extension, extension.message_type._concrete_class()) + if value._InternalParse(buffer, message_start,message_end) != message_end: + # The only reason _InternalParse would return early is if it encountered + # an end-group tag. + raise _DecodeError('Unexpected end-group tag.') + else: + if not message._unknown_fields: + message._unknown_fields = [] + message._unknown_fields.append((MESSAGE_SET_ITEM_TAG, + buffer[message_set_item_start:pos])) + + return pos + + return DecodeItem + +# -------------------------------------------------------------------- +# Optimization is not as heavy here because calls to SkipField() are rare, +# except for handling end-group tags. + +def _SkipVarint(buffer, pos, end): + """Skip a varint value. Returns the new position.""" + + while ord(buffer[pos]) & 0x80: + pos += 1 + pos += 1 + if pos > end: + raise _DecodeError('Truncated message.') + return pos + +def _SkipFixed64(buffer, pos, end): + """Skip a fixed64 value. Returns the new position.""" + + pos += 8 + if pos > end: + raise _DecodeError('Truncated message.') + return pos + +def _SkipLengthDelimited(buffer, pos, end): + """Skip a length-delimited value. Returns the new position.""" + + (size, pos) = _DecodeVarint(buffer, pos) + pos += size + if pos > end: + raise _DecodeError('Truncated message.') + return pos + +def _SkipGroup(buffer, pos, end): + """Skip sub-group. Returns the new position.""" + + while 1: + (tag_bytes, pos) = ReadTag(buffer, pos) + new_pos = SkipField(buffer, pos, end, tag_bytes) + if new_pos == -1: + return pos + pos = new_pos + +def _EndGroup(buffer, pos, end): + """Skipping an END_GROUP tag returns -1 to tell the parent loop to break.""" + + return -1 + +def _SkipFixed32(buffer, pos, end): + """Skip a fixed32 value. Returns the new position.""" + + pos += 4 + if pos > end: + raise _DecodeError('Truncated message.') + return pos + +def _RaiseInvalidWireType(buffer, pos, end): + """Skip function for unknown wire types. Raises an exception.""" + + raise _DecodeError('Tag had invalid wire type.') + +def _FieldSkipper(): + """Constructs the SkipField function.""" + + WIRETYPE_TO_SKIPPER = [ + _SkipVarint, + _SkipFixed64, + _SkipLengthDelimited, + _SkipGroup, + _EndGroup, + _SkipFixed32, + _RaiseInvalidWireType, + _RaiseInvalidWireType, + ] + + wiretype_mask = wire_format.TAG_TYPE_MASK + local_ord = ord + + def SkipField(buffer, pos, end, tag_bytes): + """Skips a field with the specified tag. + + |pos| should point to the byte immediately after the tag. + + Returns: + The new position (after the tag value), or -1 if the tag is an end-group + tag (in which case the calling loop should break). + """ + + # The wire type is always in the first byte since varints are little-endian. + wire_type = local_ord(tag_bytes[0]) & wiretype_mask + return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end) + + return SkipField + +SkipField = _FieldSkipper() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_database_test.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_database_test.py new file mode 100644 index 0000000..d0ca789 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_database_test.py @@ -0,0 +1,63 @@ +#! /usr/bin/python +# +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests for google.protobuf.descriptor_database.""" + +__author__ = 'matthewtoia@google.com (Matt Toia)' + +import unittest +from google.protobuf import descriptor_pb2 +from google.protobuf.internal import factory_test2_pb2 +from google.protobuf import descriptor_database + + +class DescriptorDatabaseTest(unittest.TestCase): + + def testAdd(self): + db = descriptor_database.DescriptorDatabase() + file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString( + factory_test2_pb2.DESCRIPTOR.serialized_pb) + db.Add(file_desc_proto) + + self.assertEquals(file_desc_proto, db.FindFileByName( + 'net/proto2/python/internal/factory_test2.proto')) + self.assertEquals(file_desc_proto, db.FindFileContainingSymbol( + 'net.proto2.python.internal.Factory2Message')) + self.assertEquals(file_desc_proto, db.FindFileContainingSymbol( + 'net.proto2.python.internal.Factory2Message.NestedFactory2Message')) + self.assertEquals(file_desc_proto, db.FindFileContainingSymbol( + 'net.proto2.python.internal.Factory2Enum')) + self.assertEquals(file_desc_proto, db.FindFileContainingSymbol( + 'net.proto2.python.internal.Factory2Message.NestedFactory2Enum')) + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_pool_test.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_pool_test.py new file mode 100644 index 0000000..a615d78 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_pool_test.py @@ -0,0 +1,220 @@ +#! /usr/bin/python +# +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests for google.protobuf.descriptor_pool.""" + +__author__ = 'matthewtoia@google.com (Matt Toia)' + +import unittest +from google.protobuf import descriptor_pb2 +from google.protobuf.internal import factory_test1_pb2 +from google.protobuf.internal import factory_test2_pb2 +from google.protobuf import descriptor +from google.protobuf import descriptor_database +from google.protobuf import descriptor_pool + + +class DescriptorPoolTest(unittest.TestCase): + + def setUp(self): + self.pool = descriptor_pool.DescriptorPool() + self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString( + factory_test1_pb2.DESCRIPTOR.serialized_pb) + self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString( + factory_test2_pb2.DESCRIPTOR.serialized_pb) + self.pool.Add(self.factory_test1_fd) + self.pool.Add(self.factory_test2_fd) + + def testFindFileByName(self): + name1 = 'net/proto2/python/internal/factory_test1.proto' + file_desc1 = self.pool.FindFileByName(name1) + self.assertIsInstance(file_desc1, descriptor.FileDescriptor) + self.assertEquals(name1, file_desc1.name) + self.assertEquals('net.proto2.python.internal', file_desc1.package) + self.assertIn('Factory1Message', file_desc1.message_types_by_name) + + name2 = 'net/proto2/python/internal/factory_test2.proto' + file_desc2 = self.pool.FindFileByName(name2) + self.assertIsInstance(file_desc2, descriptor.FileDescriptor) + self.assertEquals(name2, file_desc2.name) + self.assertEquals('net.proto2.python.internal', file_desc2.package) + self.assertIn('Factory2Message', file_desc2.message_types_by_name) + + def testFindFileByNameFailure(self): + try: + self.pool.FindFileByName('Does not exist') + self.fail('Expected KeyError') + except KeyError: + pass + + def testFindFileContainingSymbol(self): + file_desc1 = self.pool.FindFileContainingSymbol( + 'net.proto2.python.internal.Factory1Message') + self.assertIsInstance(file_desc1, descriptor.FileDescriptor) + self.assertEquals('net/proto2/python/internal/factory_test1.proto', + file_desc1.name) + self.assertEquals('net.proto2.python.internal', file_desc1.package) + self.assertIn('Factory1Message', file_desc1.message_types_by_name) + + file_desc2 = self.pool.FindFileContainingSymbol( + 'net.proto2.python.internal.Factory2Message') + self.assertIsInstance(file_desc2, descriptor.FileDescriptor) + self.assertEquals('net/proto2/python/internal/factory_test2.proto', + file_desc2.name) + self.assertEquals('net.proto2.python.internal', file_desc2.package) + self.assertIn('Factory2Message', file_desc2.message_types_by_name) + + def testFindFileContainingSymbolFailure(self): + try: + self.pool.FindFileContainingSymbol('Does not exist') + self.fail('Expected KeyError') + except KeyError: + pass + + def testFindMessageTypeByName(self): + msg1 = self.pool.FindMessageTypeByName( + 'net.proto2.python.internal.Factory1Message') + self.assertIsInstance(msg1, descriptor.Descriptor) + self.assertEquals('Factory1Message', msg1.name) + self.assertEquals('net.proto2.python.internal.Factory1Message', + msg1.full_name) + self.assertEquals(None, msg1.containing_type) + + nested_msg1 = msg1.nested_types[0] + self.assertEquals('NestedFactory1Message', nested_msg1.name) + self.assertEquals(msg1, nested_msg1.containing_type) + + nested_enum1 = msg1.enum_types[0] + self.assertEquals('NestedFactory1Enum', nested_enum1.name) + self.assertEquals(msg1, nested_enum1.containing_type) + + self.assertEquals(nested_msg1, msg1.fields_by_name[ + 'nested_factory_1_message'].message_type) + self.assertEquals(nested_enum1, msg1.fields_by_name[ + 'nested_factory_1_enum'].enum_type) + + msg2 = self.pool.FindMessageTypeByName( + 'net.proto2.python.internal.Factory2Message') + self.assertIsInstance(msg2, descriptor.Descriptor) + self.assertEquals('Factory2Message', msg2.name) + self.assertEquals('net.proto2.python.internal.Factory2Message', + msg2.full_name) + self.assertIsNone(msg2.containing_type) + + nested_msg2 = msg2.nested_types[0] + self.assertEquals('NestedFactory2Message', nested_msg2.name) + self.assertEquals(msg2, nested_msg2.containing_type) + + nested_enum2 = msg2.enum_types[0] + self.assertEquals('NestedFactory2Enum', nested_enum2.name) + self.assertEquals(msg2, nested_enum2.containing_type) + + self.assertEquals(nested_msg2, msg2.fields_by_name[ + 'nested_factory_2_message'].message_type) + self.assertEquals(nested_enum2, msg2.fields_by_name[ + 'nested_factory_2_enum'].enum_type) + + self.assertTrue(msg2.fields_by_name['int_with_default'].has_default) + self.assertEquals( + 1776, msg2.fields_by_name['int_with_default'].default_value) + + self.assertTrue(msg2.fields_by_name['double_with_default'].has_default) + self.assertEquals( + 9.99, msg2.fields_by_name['double_with_default'].default_value) + + self.assertTrue(msg2.fields_by_name['string_with_default'].has_default) + self.assertEquals( + 'hello world', msg2.fields_by_name['string_with_default'].default_value) + + self.assertTrue(msg2.fields_by_name['bool_with_default'].has_default) + self.assertFalse(msg2.fields_by_name['bool_with_default'].default_value) + + self.assertTrue(msg2.fields_by_name['enum_with_default'].has_default) + self.assertEquals( + 1, msg2.fields_by_name['enum_with_default'].default_value) + + msg3 = self.pool.FindMessageTypeByName( + 'net.proto2.python.internal.Factory2Message.NestedFactory2Message') + self.assertEquals(nested_msg2, msg3) + + def testFindMessageTypeByNameFailure(self): + try: + self.pool.FindMessageTypeByName('Does not exist') + self.fail('Expected KeyError') + except KeyError: + pass + + def testFindEnumTypeByName(self): + enum1 = self.pool.FindEnumTypeByName( + 'net.proto2.python.internal.Factory1Enum') + self.assertIsInstance(enum1, descriptor.EnumDescriptor) + self.assertEquals(0, enum1.values_by_name['FACTORY_1_VALUE_0'].number) + self.assertEquals(1, enum1.values_by_name['FACTORY_1_VALUE_1'].number) + + nested_enum1 = self.pool.FindEnumTypeByName( + 'net.proto2.python.internal.Factory1Message.NestedFactory1Enum') + self.assertIsInstance(nested_enum1, descriptor.EnumDescriptor) + self.assertEquals( + 0, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_0'].number) + self.assertEquals( + 1, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_1'].number) + + enum2 = self.pool.FindEnumTypeByName( + 'net.proto2.python.internal.Factory2Enum') + self.assertIsInstance(enum2, descriptor.EnumDescriptor) + self.assertEquals(0, enum2.values_by_name['FACTORY_2_VALUE_0'].number) + self.assertEquals(1, enum2.values_by_name['FACTORY_2_VALUE_1'].number) + + nested_enum2 = self.pool.FindEnumTypeByName( + 'net.proto2.python.internal.Factory2Message.NestedFactory2Enum') + self.assertIsInstance(nested_enum2, descriptor.EnumDescriptor) + self.assertEquals( + 0, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_0'].number) + self.assertEquals( + 1, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_1'].number) + + def testFindEnumTypeByNameFailure(self): + try: + self.pool.FindEnumTypeByName('Does not exist') + self.fail('Expected KeyError') + except KeyError: + pass + + def testUserDefinedDB(self): + db = descriptor_database.DescriptorDatabase() + self.pool = descriptor_pool.DescriptorPool(db) + db.Add(self.factory_test1_fd) + db.Add(self.factory_test2_fd) + self.testFindMessageTypeByName() + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_test.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_test.py new file mode 100755 index 0000000..c74f882 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/descriptor_test.py @@ -0,0 +1,613 @@ +#! /usr/bin/python +# +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unittest for google.protobuf.internal.descriptor.""" + +__author__ = 'robinson@google.com (Will Robinson)' + +import unittest +from google.protobuf import unittest_custom_options_pb2 +from google.protobuf import unittest_import_pb2 +from google.protobuf import unittest_pb2 +from google.protobuf import descriptor_pb2 +from google.protobuf import descriptor +from google.protobuf import text_format + + +TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII = """ +name: 'TestEmptyMessage' +""" + + +class DescriptorTest(unittest.TestCase): + + def setUp(self): + self.my_file = descriptor.FileDescriptor( + name='some/filename/some.proto', + package='protobuf_unittest' + ) + self.my_enum = descriptor.EnumDescriptor( + name='ForeignEnum', + full_name='protobuf_unittest.ForeignEnum', + filename=None, + file=self.my_file, + values=[ + descriptor.EnumValueDescriptor(name='FOREIGN_FOO', index=0, number=4), + descriptor.EnumValueDescriptor(name='FOREIGN_BAR', index=1, number=5), + descriptor.EnumValueDescriptor(name='FOREIGN_BAZ', index=2, number=6), + ]) + self.my_message = descriptor.Descriptor( + name='NestedMessage', + full_name='protobuf_unittest.TestAllTypes.NestedMessage', + filename=None, + file=self.my_file, + containing_type=None, + fields=[ + descriptor.FieldDescriptor( + name='bb', + full_name='protobuf_unittest.TestAllTypes.NestedMessage.bb', + index=0, number=1, + type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None), + ], + nested_types=[], + enum_types=[ + self.my_enum, + ], + extensions=[]) + self.my_method = descriptor.MethodDescriptor( + name='Bar', + full_name='protobuf_unittest.TestService.Bar', + index=0, + containing_service=None, + input_type=None, + output_type=None) + self.my_service = descriptor.ServiceDescriptor( + name='TestServiceWithOptions', + full_name='protobuf_unittest.TestServiceWithOptions', + file=self.my_file, + index=0, + methods=[ + self.my_method + ]) + + def testEnumValueName(self): + self.assertEqual(self.my_message.EnumValueName('ForeignEnum', 4), + 'FOREIGN_FOO') + + self.assertEqual( + self.my_message.enum_types_by_name[ + 'ForeignEnum'].values_by_number[4].name, + self.my_message.EnumValueName('ForeignEnum', 4)) + + def testEnumFixups(self): + self.assertEqual(self.my_enum, self.my_enum.values[0].type) + + def testContainingTypeFixups(self): + self.assertEqual(self.my_message, self.my_message.fields[0].containing_type) + self.assertEqual(self.my_message, self.my_enum.containing_type) + + def testContainingServiceFixups(self): + self.assertEqual(self.my_service, self.my_method.containing_service) + + def testGetOptions(self): + self.assertEqual(self.my_enum.GetOptions(), + descriptor_pb2.EnumOptions()) + self.assertEqual(self.my_enum.values[0].GetOptions(), + descriptor_pb2.EnumValueOptions()) + self.assertEqual(self.my_message.GetOptions(), + descriptor_pb2.MessageOptions()) + self.assertEqual(self.my_message.fields[0].GetOptions(), + descriptor_pb2.FieldOptions()) + self.assertEqual(self.my_method.GetOptions(), + descriptor_pb2.MethodOptions()) + self.assertEqual(self.my_service.GetOptions(), + descriptor_pb2.ServiceOptions()) + + def testSimpleCustomOptions(self): + file_descriptor = unittest_custom_options_pb2.DESCRIPTOR + message_descriptor =\ + unittest_custom_options_pb2.TestMessageWithCustomOptions.DESCRIPTOR + field_descriptor = message_descriptor.fields_by_name["field1"] + enum_descriptor = message_descriptor.enum_types_by_name["AnEnum"] + enum_value_descriptor =\ + message_descriptor.enum_values_by_name["ANENUM_VAL2"] + service_descriptor =\ + unittest_custom_options_pb2.TestServiceWithCustomOptions.DESCRIPTOR + method_descriptor = service_descriptor.FindMethodByName("Foo") + + file_options = file_descriptor.GetOptions() + file_opt1 = unittest_custom_options_pb2.file_opt1 + self.assertEqual(9876543210, file_options.Extensions[file_opt1]) + message_options = message_descriptor.GetOptions() + message_opt1 = unittest_custom_options_pb2.message_opt1 + self.assertEqual(-56, message_options.Extensions[message_opt1]) + field_options = field_descriptor.GetOptions() + field_opt1 = unittest_custom_options_pb2.field_opt1 + self.assertEqual(8765432109, field_options.Extensions[field_opt1]) + field_opt2 = unittest_custom_options_pb2.field_opt2 + self.assertEqual(42, field_options.Extensions[field_opt2]) + enum_options = enum_descriptor.GetOptions() + enum_opt1 = unittest_custom_options_pb2.enum_opt1 + self.assertEqual(-789, enum_options.Extensions[enum_opt1]) + enum_value_options = enum_value_descriptor.GetOptions() + enum_value_opt1 = unittest_custom_options_pb2.enum_value_opt1 + self.assertEqual(123, enum_value_options.Extensions[enum_value_opt1]) + + service_options = service_descriptor.GetOptions() + service_opt1 = unittest_custom_options_pb2.service_opt1 + self.assertEqual(-9876543210, service_options.Extensions[service_opt1]) + method_options = method_descriptor.GetOptions() + method_opt1 = unittest_custom_options_pb2.method_opt1 + self.assertEqual(unittest_custom_options_pb2.METHODOPT1_VAL2, + method_options.Extensions[method_opt1]) + + def testDifferentCustomOptionTypes(self): + kint32min = -2**31 + kint64min = -2**63 + kint32max = 2**31 - 1 + kint64max = 2**63 - 1 + kuint32max = 2**32 - 1 + kuint64max = 2**64 - 1 + + message_descriptor =\ + unittest_custom_options_pb2.CustomOptionMinIntegerValues.DESCRIPTOR + message_options = message_descriptor.GetOptions() + self.assertEqual(False, message_options.Extensions[ + unittest_custom_options_pb2.bool_opt]) + self.assertEqual(kint32min, message_options.Extensions[ + unittest_custom_options_pb2.int32_opt]) + self.assertEqual(kint64min, message_options.Extensions[ + unittest_custom_options_pb2.int64_opt]) + self.assertEqual(0, message_options.Extensions[ + unittest_custom_options_pb2.uint32_opt]) + self.assertEqual(0, message_options.Extensions[ + unittest_custom_options_pb2.uint64_opt]) + self.assertEqual(kint32min, message_options.Extensions[ + unittest_custom_options_pb2.sint32_opt]) + self.assertEqual(kint64min, message_options.Extensions[ + unittest_custom_options_pb2.sint64_opt]) + self.assertEqual(0, message_options.Extensions[ + unittest_custom_options_pb2.fixed32_opt]) + self.assertEqual(0, message_options.Extensions[ + unittest_custom_options_pb2.fixed64_opt]) + self.assertEqual(kint32min, message_options.Extensions[ + unittest_custom_options_pb2.sfixed32_opt]) + self.assertEqual(kint64min, message_options.Extensions[ + unittest_custom_options_pb2.sfixed64_opt]) + + message_descriptor =\ + unittest_custom_options_pb2.CustomOptionMaxIntegerValues.DESCRIPTOR + message_options = message_descriptor.GetOptions() + self.assertEqual(True, message_options.Extensions[ + unittest_custom_options_pb2.bool_opt]) + self.assertEqual(kint32max, message_options.Extensions[ + unittest_custom_options_pb2.int32_opt]) + self.assertEqual(kint64max, message_options.Extensions[ + unittest_custom_options_pb2.int64_opt]) + self.assertEqual(kuint32max, message_options.Extensions[ + unittest_custom_options_pb2.uint32_opt]) + self.assertEqual(kuint64max, message_options.Extensions[ + unittest_custom_options_pb2.uint64_opt]) + self.assertEqual(kint32max, message_options.Extensions[ + unittest_custom_options_pb2.sint32_opt]) + self.assertEqual(kint64max, message_options.Extensions[ + unittest_custom_options_pb2.sint64_opt]) + self.assertEqual(kuint32max, message_options.Extensions[ + unittest_custom_options_pb2.fixed32_opt]) + self.assertEqual(kuint64max, message_options.Extensions[ + unittest_custom_options_pb2.fixed64_opt]) + self.assertEqual(kint32max, message_options.Extensions[ + unittest_custom_options_pb2.sfixed32_opt]) + self.assertEqual(kint64max, message_options.Extensions[ + unittest_custom_options_pb2.sfixed64_opt]) + + message_descriptor =\ + unittest_custom_options_pb2.CustomOptionOtherValues.DESCRIPTOR + message_options = message_descriptor.GetOptions() + self.assertEqual(-100, message_options.Extensions[ + unittest_custom_options_pb2.int32_opt]) + self.assertAlmostEqual(12.3456789, message_options.Extensions[ + unittest_custom_options_pb2.float_opt], 6) + self.assertAlmostEqual(1.234567890123456789, message_options.Extensions[ + unittest_custom_options_pb2.double_opt]) + self.assertEqual("Hello, \"World\"", message_options.Extensions[ + unittest_custom_options_pb2.string_opt]) + self.assertEqual("Hello\0World", message_options.Extensions[ + unittest_custom_options_pb2.bytes_opt]) + dummy_enum = unittest_custom_options_pb2.DummyMessageContainingEnum + self.assertEqual( + dummy_enum.TEST_OPTION_ENUM_TYPE2, + message_options.Extensions[unittest_custom_options_pb2.enum_opt]) + + message_descriptor =\ + unittest_custom_options_pb2.SettingRealsFromPositiveInts.DESCRIPTOR + message_options = message_descriptor.GetOptions() + self.assertAlmostEqual(12, message_options.Extensions[ + unittest_custom_options_pb2.float_opt], 6) + self.assertAlmostEqual(154, message_options.Extensions[ + unittest_custom_options_pb2.double_opt]) + + message_descriptor =\ + unittest_custom_options_pb2.SettingRealsFromNegativeInts.DESCRIPTOR + message_options = message_descriptor.GetOptions() + self.assertAlmostEqual(-12, message_options.Extensions[ + unittest_custom_options_pb2.float_opt], 6) + self.assertAlmostEqual(-154, message_options.Extensions[ + unittest_custom_options_pb2.double_opt]) + + def testComplexExtensionOptions(self): + descriptor =\ + unittest_custom_options_pb2.VariousComplexOptions.DESCRIPTOR + options = descriptor.GetOptions() + self.assertEqual(42, options.Extensions[ + unittest_custom_options_pb2.complex_opt1].foo) + self.assertEqual(324, options.Extensions[ + unittest_custom_options_pb2.complex_opt1].Extensions[ + unittest_custom_options_pb2.quux]) + self.assertEqual(876, options.Extensions[ + unittest_custom_options_pb2.complex_opt1].Extensions[ + unittest_custom_options_pb2.corge].qux) + self.assertEqual(987, options.Extensions[ + unittest_custom_options_pb2.complex_opt2].baz) + self.assertEqual(654, options.Extensions[ + unittest_custom_options_pb2.complex_opt2].Extensions[ + unittest_custom_options_pb2.grault]) + self.assertEqual(743, options.Extensions[ + unittest_custom_options_pb2.complex_opt2].bar.foo) + self.assertEqual(1999, options.Extensions[ + unittest_custom_options_pb2.complex_opt2].bar.Extensions[ + unittest_custom_options_pb2.quux]) + self.assertEqual(2008, options.Extensions[ + unittest_custom_options_pb2.complex_opt2].bar.Extensions[ + unittest_custom_options_pb2.corge].qux) + self.assertEqual(741, options.Extensions[ + unittest_custom_options_pb2.complex_opt2].Extensions[ + unittest_custom_options_pb2.garply].foo) + self.assertEqual(1998, options.Extensions[ + unittest_custom_options_pb2.complex_opt2].Extensions[ + unittest_custom_options_pb2.garply].Extensions[ + unittest_custom_options_pb2.quux]) + self.assertEqual(2121, options.Extensions[ + unittest_custom_options_pb2.complex_opt2].Extensions[ + unittest_custom_options_pb2.garply].Extensions[ + unittest_custom_options_pb2.corge].qux) + self.assertEqual(1971, options.Extensions[ + unittest_custom_options_pb2.ComplexOptionType2 + .ComplexOptionType4.complex_opt4].waldo) + self.assertEqual(321, options.Extensions[ + unittest_custom_options_pb2.complex_opt2].fred.waldo) + self.assertEqual(9, options.Extensions[ + unittest_custom_options_pb2.complex_opt3].qux) + self.assertEqual(22, options.Extensions[ + unittest_custom_options_pb2.complex_opt3].complexoptiontype5.plugh) + self.assertEqual(24, options.Extensions[ + unittest_custom_options_pb2.complexopt6].xyzzy) + + # Check that aggregate options were parsed and saved correctly in + # the appropriate descriptors. + def testAggregateOptions(self): + file_descriptor = unittest_custom_options_pb2.DESCRIPTOR + message_descriptor =\ + unittest_custom_options_pb2.AggregateMessage.DESCRIPTOR + field_descriptor = message_descriptor.fields_by_name["fieldname"] + enum_descriptor = unittest_custom_options_pb2.AggregateEnum.DESCRIPTOR + enum_value_descriptor = enum_descriptor.values_by_name["VALUE"] + service_descriptor =\ + unittest_custom_options_pb2.AggregateService.DESCRIPTOR + method_descriptor = service_descriptor.FindMethodByName("Method") + + # Tests for the different types of data embedded in fileopt + file_options = file_descriptor.GetOptions().Extensions[ + unittest_custom_options_pb2.fileopt] + self.assertEqual(100, file_options.i) + self.assertEqual("FileAnnotation", file_options.s) + self.assertEqual("NestedFileAnnotation", file_options.sub.s) + self.assertEqual("FileExtensionAnnotation", file_options.file.Extensions[ + unittest_custom_options_pb2.fileopt].s) + self.assertEqual("EmbeddedMessageSetElement", file_options.mset.Extensions[ + unittest_custom_options_pb2.AggregateMessageSetElement + .message_set_extension].s) + + # Simple tests for all the other types of annotations + self.assertEqual( + "MessageAnnotation", + message_descriptor.GetOptions().Extensions[ + unittest_custom_options_pb2.msgopt].s) + self.assertEqual( + "FieldAnnotation", + field_descriptor.GetOptions().Extensions[ + unittest_custom_options_pb2.fieldopt].s) + self.assertEqual( + "EnumAnnotation", + enum_descriptor.GetOptions().Extensions[ + unittest_custom_options_pb2.enumopt].s) + self.assertEqual( + "EnumValueAnnotation", + enum_value_descriptor.GetOptions().Extensions[ + unittest_custom_options_pb2.enumvalopt].s) + self.assertEqual( + "ServiceAnnotation", + service_descriptor.GetOptions().Extensions[ + unittest_custom_options_pb2.serviceopt].s) + self.assertEqual( + "MethodAnnotation", + method_descriptor.GetOptions().Extensions[ + unittest_custom_options_pb2.methodopt].s) + + def testNestedOptions(self): + nested_message =\ + unittest_custom_options_pb2.NestedOptionType.NestedMessage.DESCRIPTOR + self.assertEqual(1001, nested_message.GetOptions().Extensions[ + unittest_custom_options_pb2.message_opt1]) + nested_field = nested_message.fields_by_name["nested_field"] + self.assertEqual(1002, nested_field.GetOptions().Extensions[ + unittest_custom_options_pb2.field_opt1]) + outer_message =\ + unittest_custom_options_pb2.NestedOptionType.DESCRIPTOR + nested_enum = outer_message.enum_types_by_name["NestedEnum"] + self.assertEqual(1003, nested_enum.GetOptions().Extensions[ + unittest_custom_options_pb2.enum_opt1]) + nested_enum_value = outer_message.enum_values_by_name["NESTED_ENUM_VALUE"] + self.assertEqual(1004, nested_enum_value.GetOptions().Extensions[ + unittest_custom_options_pb2.enum_value_opt1]) + nested_extension = outer_message.extensions_by_name["nested_extension"] + self.assertEqual(1005, nested_extension.GetOptions().Extensions[ + unittest_custom_options_pb2.field_opt2]) + + def testFileDescriptorReferences(self): + self.assertEqual(self.my_enum.file, self.my_file) + self.assertEqual(self.my_message.file, self.my_file) + + def testFileDescriptor(self): + self.assertEqual(self.my_file.name, 'some/filename/some.proto') + self.assertEqual(self.my_file.package, 'protobuf_unittest') + + +class DescriptorCopyToProtoTest(unittest.TestCase): + """Tests for CopyTo functions of Descriptor.""" + + def _AssertProtoEqual(self, actual_proto, expected_class, expected_ascii): + expected_proto = expected_class() + text_format.Merge(expected_ascii, expected_proto) + + self.assertEqual( + actual_proto, expected_proto, + 'Not equal,\nActual:\n%s\nExpected:\n%s\n' + % (str(actual_proto), str(expected_proto))) + + def _InternalTestCopyToProto(self, desc, expected_proto_class, + expected_proto_ascii): + actual = expected_proto_class() + desc.CopyToProto(actual) + self._AssertProtoEqual( + actual, expected_proto_class, expected_proto_ascii) + + def testCopyToProto_EmptyMessage(self): + self._InternalTestCopyToProto( + unittest_pb2.TestEmptyMessage.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII) + + def testCopyToProto_NestedMessage(self): + TEST_NESTED_MESSAGE_ASCII = """ + name: 'NestedMessage' + field: < + name: 'bb' + number: 1 + label: 1 # Optional + type: 5 # TYPE_INT32 + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_NESTED_MESSAGE_ASCII) + + def testCopyToProto_ForeignNestedMessage(self): + TEST_FOREIGN_NESTED_ASCII = """ + name: 'TestForeignNested' + field: < + name: 'foreign_nested' + number: 1 + label: 1 # Optional + type: 11 # TYPE_MESSAGE + type_name: '.protobuf_unittest.TestAllTypes.NestedMessage' + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestForeignNested.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_FOREIGN_NESTED_ASCII) + + def testCopyToProto_ForeignEnum(self): + TEST_FOREIGN_ENUM_ASCII = """ + name: 'ForeignEnum' + value: < + name: 'FOREIGN_FOO' + number: 4 + > + value: < + name: 'FOREIGN_BAR' + number: 5 + > + value: < + name: 'FOREIGN_BAZ' + number: 6 + > + """ + + self._InternalTestCopyToProto( + unittest_pb2._FOREIGNENUM, + descriptor_pb2.EnumDescriptorProto, + TEST_FOREIGN_ENUM_ASCII) + + def testCopyToProto_Options(self): + TEST_DEPRECATED_FIELDS_ASCII = """ + name: 'TestDeprecatedFields' + field: < + name: 'deprecated_int32' + number: 1 + label: 1 # Optional + type: 5 # TYPE_INT32 + options: < + deprecated: true + > + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestDeprecatedFields.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_DEPRECATED_FIELDS_ASCII) + + def testCopyToProto_AllExtensions(self): + TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII = """ + name: 'TestEmptyMessageWithExtensions' + extension_range: < + start: 1 + end: 536870912 + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestEmptyMessageWithExtensions.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII) + + def testCopyToProto_SeveralExtensions(self): + TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII = """ + name: 'TestMultipleExtensionRanges' + extension_range: < + start: 42 + end: 43 + > + extension_range: < + start: 4143 + end: 4244 + > + extension_range: < + start: 65536 + end: 536870912 + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII) + + def testCopyToProto_FileDescriptor(self): + UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = (""" + name: 'google/protobuf/unittest_import.proto' + package: 'protobuf_unittest_import' + dependency: 'google/protobuf/unittest_import_public.proto' + message_type: < + name: 'ImportMessage' + field: < + name: 'd' + number: 1 + label: 1 # Optional + type: 5 # TYPE_INT32 + > + > + """ + + """enum_type: < + name: 'ImportEnum' + value: < + name: 'IMPORT_FOO' + number: 7 + > + value: < + name: 'IMPORT_BAR' + number: 8 + > + value: < + name: 'IMPORT_BAZ' + number: 9 + > + > + options: < + java_package: 'com.google.protobuf.test' + optimize_for: 1 # SPEED + > + public_dependency: 0 + """) + + self._InternalTestCopyToProto( + unittest_import_pb2.DESCRIPTOR, + descriptor_pb2.FileDescriptorProto, + UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII) + + def testCopyToProto_ServiceDescriptor(self): + TEST_SERVICE_ASCII = """ + name: 'TestService' + method: < + name: 'Foo' + input_type: '.protobuf_unittest.FooRequest' + output_type: '.protobuf_unittest.FooResponse' + > + method: < + name: 'Bar' + input_type: '.protobuf_unittest.BarRequest' + output_type: '.protobuf_unittest.BarResponse' + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestService.DESCRIPTOR, + descriptor_pb2.ServiceDescriptorProto, + TEST_SERVICE_ASCII) + + +class MakeDescriptorTest(unittest.TestCase): + def testMakeDescriptorWithUnsignedIntField(self): + file_descriptor_proto = descriptor_pb2.FileDescriptorProto() + file_descriptor_proto.name = 'Foo' + message_type = file_descriptor_proto.message_type.add() + message_type.name = file_descriptor_proto.name + field = message_type.field.add() + field.number = 1 + field.name = 'uint64_field' + field.label = descriptor.FieldDescriptor.LABEL_REQUIRED + field.type = descriptor.FieldDescriptor.TYPE_UINT64 + result = descriptor.MakeDescriptor(message_type) + self.assertEqual(result.fields[0].cpp_type, + descriptor.FieldDescriptor.CPPTYPE_UINT64) + + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/encoder.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/encoder.py new file mode 100755 index 0000000..777975e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/encoder.py @@ -0,0 +1,769 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Code for encoding protocol message primitives. + +Contains the logic for encoding every logical protocol field type +into one of the 5 physical wire types. + +This code is designed to push the Python interpreter's performance to the +limits. + +The basic idea is that at startup time, for every field (i.e. every +FieldDescriptor) we construct two functions: a "sizer" and an "encoder". The +sizer takes a value of this field's type and computes its byte size. The +encoder takes a writer function and a value. It encodes the value into byte +strings and invokes the writer function to write those strings. Typically the +writer function is the write() method of a cStringIO. + +We try to do as much work as possible when constructing the writer and the +sizer rather than when calling them. In particular: +* We copy any needed global functions to local variables, so that we do not need + to do costly global table lookups at runtime. +* Similarly, we try to do any attribute lookups at startup time if possible. +* Every field's tag is encoded to bytes at startup, since it can't change at + runtime. +* Whatever component of the field size we can compute at startup, we do. +* We *avoid* sharing code if doing so would make the code slower and not sharing + does not burden us too much. For example, encoders for repeated fields do + not just call the encoders for singular fields in a loop because this would + add an extra function call overhead for every loop iteration; instead, we + manually inline the single-value encoder into the loop. +* If a Python function lacks a return statement, Python actually generates + instructions to pop the result of the last statement off the stack, push + None onto the stack, and then return that. If we really don't care what + value is returned, then we can save two instructions by returning the + result of the last statement. It looks funny but it helps. +* We assume that type and bounds checking has happened at a higher level. +""" + +__author__ = 'kenton@google.com (Kenton Varda)' + +import struct +from google.protobuf.internal import wire_format + + +# This will overflow and thus become IEEE-754 "infinity". We would use +# "float('inf')" but it doesn't work on Windows pre-Python-2.6. +_POS_INF = 1e10000 +_NEG_INF = -_POS_INF + + +def _VarintSize(value): + """Compute the size of a varint value.""" + if value <= 0x7f: return 1 + if value <= 0x3fff: return 2 + if value <= 0x1fffff: return 3 + if value <= 0xfffffff: return 4 + if value <= 0x7ffffffff: return 5 + if value <= 0x3ffffffffff: return 6 + if value <= 0x1ffffffffffff: return 7 + if value <= 0xffffffffffffff: return 8 + if value <= 0x7fffffffffffffff: return 9 + return 10 + + +def _SignedVarintSize(value): + """Compute the size of a signed varint value.""" + if value < 0: return 10 + if value <= 0x7f: return 1 + if value <= 0x3fff: return 2 + if value <= 0x1fffff: return 3 + if value <= 0xfffffff: return 4 + if value <= 0x7ffffffff: return 5 + if value <= 0x3ffffffffff: return 6 + if value <= 0x1ffffffffffff: return 7 + if value <= 0xffffffffffffff: return 8 + if value <= 0x7fffffffffffffff: return 9 + return 10 + + +def _TagSize(field_number): + """Returns the number of bytes required to serialize a tag with this field + number.""" + # Just pass in type 0, since the type won't affect the tag+type size. + return _VarintSize(wire_format.PackTag(field_number, 0)) + + +# -------------------------------------------------------------------- +# In this section we define some generic sizers. Each of these functions +# takes parameters specific to a particular field type, e.g. int32 or fixed64. +# It returns another function which in turn takes parameters specific to a +# particular field, e.g. the field number and whether it is repeated or packed. +# Look at the next section to see how these are used. + + +def _SimpleSizer(compute_value_size): + """A sizer which uses the function compute_value_size to compute the size of + each value. Typically compute_value_size is _VarintSize.""" + + def SpecificSizer(field_number, is_repeated, is_packed): + tag_size = _TagSize(field_number) + if is_packed: + local_VarintSize = _VarintSize + def PackedFieldSize(value): + result = 0 + for element in value: + result += compute_value_size(element) + return result + local_VarintSize(result) + tag_size + return PackedFieldSize + elif is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + result += compute_value_size(element) + return result + return RepeatedFieldSize + else: + def FieldSize(value): + return tag_size + compute_value_size(value) + return FieldSize + + return SpecificSizer + + +def _ModifiedSizer(compute_value_size, modify_value): + """Like SimpleSizer, but modify_value is invoked on each value before it is + passed to compute_value_size. modify_value is typically ZigZagEncode.""" + + def SpecificSizer(field_number, is_repeated, is_packed): + tag_size = _TagSize(field_number) + if is_packed: + local_VarintSize = _VarintSize + def PackedFieldSize(value): + result = 0 + for element in value: + result += compute_value_size(modify_value(element)) + return result + local_VarintSize(result) + tag_size + return PackedFieldSize + elif is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + result += compute_value_size(modify_value(element)) + return result + return RepeatedFieldSize + else: + def FieldSize(value): + return tag_size + compute_value_size(modify_value(value)) + return FieldSize + + return SpecificSizer + + +def _FixedSizer(value_size): + """Like _SimpleSizer except for a fixed-size field. The input is the size + of one value.""" + + def SpecificSizer(field_number, is_repeated, is_packed): + tag_size = _TagSize(field_number) + if is_packed: + local_VarintSize = _VarintSize + def PackedFieldSize(value): + result = len(value) * value_size + return result + local_VarintSize(result) + tag_size + return PackedFieldSize + elif is_repeated: + element_size = value_size + tag_size + def RepeatedFieldSize(value): + return len(value) * element_size + return RepeatedFieldSize + else: + field_size = value_size + tag_size + def FieldSize(value): + return field_size + return FieldSize + + return SpecificSizer + + +# ==================================================================== +# Here we declare a sizer constructor for each field type. Each "sizer +# constructor" is a function that takes (field_number, is_repeated, is_packed) +# as parameters and returns a sizer, which in turn takes a field value as +# a parameter and returns its encoded size. + + +Int32Sizer = Int64Sizer = EnumSizer = _SimpleSizer(_SignedVarintSize) + +UInt32Sizer = UInt64Sizer = _SimpleSizer(_VarintSize) + +SInt32Sizer = SInt64Sizer = _ModifiedSizer( + _SignedVarintSize, wire_format.ZigZagEncode) + +Fixed32Sizer = SFixed32Sizer = FloatSizer = _FixedSizer(4) +Fixed64Sizer = SFixed64Sizer = DoubleSizer = _FixedSizer(8) + +BoolSizer = _FixedSizer(1) + + +def StringSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a string field.""" + + tag_size = _TagSize(field_number) + local_VarintSize = _VarintSize + local_len = len + assert not is_packed + if is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + l = local_len(element.encode('utf-8')) + result += local_VarintSize(l) + l + return result + return RepeatedFieldSize + else: + def FieldSize(value): + l = local_len(value.encode('utf-8')) + return tag_size + local_VarintSize(l) + l + return FieldSize + + +def BytesSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a bytes field.""" + + tag_size = _TagSize(field_number) + local_VarintSize = _VarintSize + local_len = len + assert not is_packed + if is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + l = local_len(element) + result += local_VarintSize(l) + l + return result + return RepeatedFieldSize + else: + def FieldSize(value): + l = local_len(value) + return tag_size + local_VarintSize(l) + l + return FieldSize + + +def GroupSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a group field.""" + + tag_size = _TagSize(field_number) * 2 + assert not is_packed + if is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + result += element.ByteSize() + return result + return RepeatedFieldSize + else: + def FieldSize(value): + return tag_size + value.ByteSize() + return FieldSize + + +def MessageSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a message field.""" + + tag_size = _TagSize(field_number) + local_VarintSize = _VarintSize + assert not is_packed + if is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + l = element.ByteSize() + result += local_VarintSize(l) + l + return result + return RepeatedFieldSize + else: + def FieldSize(value): + l = value.ByteSize() + return tag_size + local_VarintSize(l) + l + return FieldSize + + +# -------------------------------------------------------------------- +# MessageSet is special. + + +def MessageSetItemSizer(field_number): + """Returns a sizer for extensions of MessageSet. + + The message set message looks like this: + message MessageSet { + repeated group Item = 1 { + required int32 type_id = 2; + required string message = 3; + } + } + """ + static_size = (_TagSize(1) * 2 + _TagSize(2) + _VarintSize(field_number) + + _TagSize(3)) + local_VarintSize = _VarintSize + + def FieldSize(value): + l = value.ByteSize() + return static_size + local_VarintSize(l) + l + + return FieldSize + + +# ==================================================================== +# Encoders! + + +def _VarintEncoder(): + """Return an encoder for a basic varint value (does not include tag).""" + + local_chr = chr + def EncodeVarint(write, value): + bits = value & 0x7f + value >>= 7 + while value: + write(local_chr(0x80|bits)) + bits = value & 0x7f + value >>= 7 + return write(local_chr(bits)) + + return EncodeVarint + + +def _SignedVarintEncoder(): + """Return an encoder for a basic signed varint value (does not include + tag).""" + + local_chr = chr + def EncodeSignedVarint(write, value): + if value < 0: + value += (1 << 64) + bits = value & 0x7f + value >>= 7 + while value: + write(local_chr(0x80|bits)) + bits = value & 0x7f + value >>= 7 + return write(local_chr(bits)) + + return EncodeSignedVarint + + +_EncodeVarint = _VarintEncoder() +_EncodeSignedVarint = _SignedVarintEncoder() + + +def _VarintBytes(value): + """Encode the given integer as a varint and return the bytes. This is only + called at startup time so it doesn't need to be fast.""" + + pieces = [] + _EncodeVarint(pieces.append, value) + return "".join(pieces) + + +def TagBytes(field_number, wire_type): + """Encode the given tag and return the bytes. Only called at startup.""" + + return _VarintBytes(wire_format.PackTag(field_number, wire_type)) + +# -------------------------------------------------------------------- +# As with sizers (see above), we have a number of common encoder +# implementations. + + +def _SimpleEncoder(wire_type, encode_value, compute_value_size): + """Return a constructor for an encoder for fields of a particular type. + + Args: + wire_type: The field's wire type, for encoding tags. + encode_value: A function which encodes an individual value, e.g. + _EncodeVarint(). + compute_value_size: A function which computes the size of an individual + value, e.g. _VarintSize(). + """ + + def SpecificEncoder(field_number, is_repeated, is_packed): + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + def EncodePackedField(write, value): + write(tag_bytes) + size = 0 + for element in value: + size += compute_value_size(element) + local_EncodeVarint(write, size) + for element in value: + encode_value(write, element) + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeRepeatedField(write, value): + for element in value: + write(tag_bytes) + encode_value(write, element) + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeField(write, value): + write(tag_bytes) + return encode_value(write, value) + return EncodeField + + return SpecificEncoder + + +def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value): + """Like SimpleEncoder but additionally invokes modify_value on every value + before passing it to encode_value. Usually modify_value is ZigZagEncode.""" + + def SpecificEncoder(field_number, is_repeated, is_packed): + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + def EncodePackedField(write, value): + write(tag_bytes) + size = 0 + for element in value: + size += compute_value_size(modify_value(element)) + local_EncodeVarint(write, size) + for element in value: + encode_value(write, modify_value(element)) + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeRepeatedField(write, value): + for element in value: + write(tag_bytes) + encode_value(write, modify_value(element)) + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeField(write, value): + write(tag_bytes) + return encode_value(write, modify_value(value)) + return EncodeField + + return SpecificEncoder + + +def _StructPackEncoder(wire_type, format): + """Return a constructor for an encoder for a fixed-width field. + + Args: + wire_type: The field's wire type, for encoding tags. + format: The format string to pass to struct.pack(). + """ + + value_size = struct.calcsize(format) + + def SpecificEncoder(field_number, is_repeated, is_packed): + local_struct_pack = struct.pack + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + def EncodePackedField(write, value): + write(tag_bytes) + local_EncodeVarint(write, len(value) * value_size) + for element in value: + write(local_struct_pack(format, element)) + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeRepeatedField(write, value): + for element in value: + write(tag_bytes) + write(local_struct_pack(format, element)) + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeField(write, value): + write(tag_bytes) + return write(local_struct_pack(format, value)) + return EncodeField + + return SpecificEncoder + + +def _FloatingPointEncoder(wire_type, format): + """Return a constructor for an encoder for float fields. + + This is like StructPackEncoder, but catches errors that may be due to + passing non-finite floating-point values to struct.pack, and makes a + second attempt to encode those values. + + Args: + wire_type: The field's wire type, for encoding tags. + format: The format string to pass to struct.pack(). + """ + + value_size = struct.calcsize(format) + if value_size == 4: + def EncodeNonFiniteOrRaise(write, value): + # Remember that the serialized form uses little-endian byte order. + if value == _POS_INF: + write('\x00\x00\x80\x7F') + elif value == _NEG_INF: + write('\x00\x00\x80\xFF') + elif value != value: # NaN + write('\x00\x00\xC0\x7F') + else: + raise + elif value_size == 8: + def EncodeNonFiniteOrRaise(write, value): + if value == _POS_INF: + write('\x00\x00\x00\x00\x00\x00\xF0\x7F') + elif value == _NEG_INF: + write('\x00\x00\x00\x00\x00\x00\xF0\xFF') + elif value != value: # NaN + write('\x00\x00\x00\x00\x00\x00\xF8\x7F') + else: + raise + else: + raise ValueError('Can\'t encode floating-point values that are ' + '%d bytes long (only 4 or 8)' % value_size) + + def SpecificEncoder(field_number, is_repeated, is_packed): + local_struct_pack = struct.pack + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + def EncodePackedField(write, value): + write(tag_bytes) + local_EncodeVarint(write, len(value) * value_size) + for element in value: + # This try/except block is going to be faster than any code that + # we could write to check whether element is finite. + try: + write(local_struct_pack(format, element)) + except SystemError: + EncodeNonFiniteOrRaise(write, element) + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeRepeatedField(write, value): + for element in value: + write(tag_bytes) + try: + write(local_struct_pack(format, element)) + except SystemError: + EncodeNonFiniteOrRaise(write, element) + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeField(write, value): + write(tag_bytes) + try: + write(local_struct_pack(format, value)) + except SystemError: + EncodeNonFiniteOrRaise(write, value) + return EncodeField + + return SpecificEncoder + + +# ==================================================================== +# Here we declare an encoder constructor for each field type. These work +# very similarly to sizer constructors, described earlier. + + +Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder( + wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize) + +UInt32Encoder = UInt64Encoder = _SimpleEncoder( + wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize) + +SInt32Encoder = SInt64Encoder = _ModifiedEncoder( + wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize, + wire_format.ZigZagEncode) + +# Note that Python conveniently guarantees that when using the '<' prefix on +# formats, they will also have the same size across all platforms (as opposed +# to without the prefix, where their sizes depend on the C compiler's basic +# type sizes). +Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, ' 0) + self.assertTrue(isinf(message.neg_inf_double)) + self.assertTrue(message.neg_inf_double < 0) + self.assertTrue(isnan(message.nan_double)) + + self.assertTrue(isinf(message.inf_float)) + self.assertTrue(message.inf_float > 0) + self.assertTrue(isinf(message.neg_inf_float)) + self.assertTrue(message.neg_inf_float < 0) + self.assertTrue(isnan(message.nan_float)) + self.assertEqual("? ? ?? ?? ??? ??/ ??-", message.cpp_trigraph) + + def testHasDefaultValues(self): + desc = unittest_pb2.TestAllTypes.DESCRIPTOR + + expected_has_default_by_name = { + 'optional_int32': False, + 'repeated_int32': False, + 'optional_nested_message': False, + 'default_int32': True, + } + + has_default_by_name = dict( + [(f.name, f.has_default_value) + for f in desc.fields + if f.name in expected_has_default_by_name]) + self.assertEqual(expected_has_default_by_name, has_default_by_name) + + def testContainingTypeBehaviorForExtensions(self): + self.assertEqual(unittest_pb2.optional_int32_extension.containing_type, + unittest_pb2.TestAllExtensions.DESCRIPTOR) + self.assertEqual(unittest_pb2.TestRequired.single.containing_type, + unittest_pb2.TestAllExtensions.DESCRIPTOR) + + def testExtensionScope(self): + self.assertEqual(unittest_pb2.optional_int32_extension.extension_scope, + None) + self.assertEqual(unittest_pb2.TestRequired.single.extension_scope, + unittest_pb2.TestRequired.DESCRIPTOR) + + def testIsExtension(self): + self.assertTrue(unittest_pb2.optional_int32_extension.is_extension) + self.assertTrue(unittest_pb2.TestRequired.single.is_extension) + + message_descriptor = unittest_pb2.TestRequired.DESCRIPTOR + non_extension_descriptor = message_descriptor.fields_by_name['a'] + self.assertTrue(not non_extension_descriptor.is_extension) + + def testOptions(self): + proto = unittest_mset_pb2.TestMessageSet() + self.assertTrue(proto.DESCRIPTOR.GetOptions().message_set_wire_format) + + def testMessageWithCustomOptions(self): + proto = unittest_custom_options_pb2.TestMessageWithCustomOptions() + enum_options = proto.DESCRIPTOR.enum_types_by_name['AnEnum'].GetOptions() + self.assertTrue(enum_options is not None) + # TODO(gps): We really should test for the presense of the enum_opt1 + # extension and for its value to be set to -789. + + def testNestedTypes(self): + self.assertEquals( + set(unittest_pb2.TestAllTypes.DESCRIPTOR.nested_types), + set([ + unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR, + unittest_pb2.TestAllTypes.OptionalGroup.DESCRIPTOR, + unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR, + ])) + self.assertEqual(unittest_pb2.TestEmptyMessage.DESCRIPTOR.nested_types, []) + self.assertEqual( + unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.nested_types, []) + + def testContainingType(self): + self.assertTrue( + unittest_pb2.TestEmptyMessage.DESCRIPTOR.containing_type is None) + self.assertTrue( + unittest_pb2.TestAllTypes.DESCRIPTOR.containing_type is None) + self.assertEqual( + unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type, + unittest_pb2.TestAllTypes.DESCRIPTOR) + self.assertEqual( + unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type, + unittest_pb2.TestAllTypes.DESCRIPTOR) + self.assertEqual( + unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR.containing_type, + unittest_pb2.TestAllTypes.DESCRIPTOR) + + def testContainingTypeInEnumDescriptor(self): + self.assertTrue(unittest_pb2._FOREIGNENUM.containing_type is None) + self.assertEqual(unittest_pb2._TESTALLTYPES_NESTEDENUM.containing_type, + unittest_pb2.TestAllTypes.DESCRIPTOR) + + def testPackage(self): + self.assertEqual( + unittest_pb2.TestAllTypes.DESCRIPTOR.file.package, + 'protobuf_unittest') + desc = unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR + self.assertEqual(desc.file.package, 'protobuf_unittest') + self.assertEqual( + unittest_import_pb2.ImportMessage.DESCRIPTOR.file.package, + 'protobuf_unittest_import') + + self.assertEqual( + unittest_pb2._FOREIGNENUM.file.package, 'protobuf_unittest') + self.assertEqual( + unittest_pb2._TESTALLTYPES_NESTEDENUM.file.package, + 'protobuf_unittest') + self.assertEqual( + unittest_import_pb2._IMPORTENUM.file.package, + 'protobuf_unittest_import') + + def testExtensionRange(self): + self.assertEqual( + unittest_pb2.TestAllTypes.DESCRIPTOR.extension_ranges, []) + self.assertEqual( + unittest_pb2.TestAllExtensions.DESCRIPTOR.extension_ranges, + [(1, MAX_EXTENSION)]) + self.assertEqual( + unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR.extension_ranges, + [(42, 43), (4143, 4244), (65536, MAX_EXTENSION)]) + + def testFileDescriptor(self): + self.assertEqual(unittest_pb2.DESCRIPTOR.name, + 'google/protobuf/unittest.proto') + self.assertEqual(unittest_pb2.DESCRIPTOR.package, 'protobuf_unittest') + self.assertFalse(unittest_pb2.DESCRIPTOR.serialized_pb is None) + + def testNoGenericServices(self): + self.assertTrue(hasattr(unittest_no_generic_services_pb2, "TestMessage")) + self.assertTrue(hasattr(unittest_no_generic_services_pb2, "FOO")) + self.assertTrue(hasattr(unittest_no_generic_services_pb2, "test_extension")) + + # Make sure unittest_no_generic_services_pb2 has no services subclassing + # Proto2 Service class. + if hasattr(unittest_no_generic_services_pb2, "TestService"): + self.assertFalse(issubclass(unittest_no_generic_services_pb2.TestService, + service.Service)) + + def testMessageTypesByName(self): + file_type = unittest_pb2.DESCRIPTOR + self.assertEqual( + unittest_pb2._TESTALLTYPES, + file_type.message_types_by_name[unittest_pb2._TESTALLTYPES.name]) + + # Nested messages shouldn't be included in the message_types_by_name + # dictionary (like in the C++ API). + self.assertFalse( + unittest_pb2._TESTALLTYPES_NESTEDMESSAGE.name in + file_type.message_types_by_name) + + def testPublicImports(self): + # Test public imports as embedded message. + all_type_proto = unittest_pb2.TestAllTypes() + self.assertEqual(0, all_type_proto.optional_public_import_message.e) + + # PublicImportMessage is actually defined in unittest_import_public_pb2 + # module, and is public imported by unittest_import_pb2 module. + public_import_proto = unittest_import_pb2.PublicImportMessage() + self.assertEqual(0, public_import_proto.e) + self.assertTrue(unittest_import_public_pb2.PublicImportMessage is + unittest_import_pb2.PublicImportMessage) + + def testBadIdentifiers(self): + # We're just testing that the code was imported without problems. + message = test_bad_identifiers_pb2.TestBadIdentifiers() + self.assertEqual(message.Extensions[test_bad_identifiers_pb2.message], + "foo") + self.assertEqual(message.Extensions[test_bad_identifiers_pb2.descriptor], + "bar") + self.assertEqual(message.Extensions[test_bad_identifiers_pb2.reflection], + "baz") + self.assertEqual(message.Extensions[test_bad_identifiers_pb2.service], + "qux") + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_cpp_test.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_cpp_test.py new file mode 100644 index 0000000..0d84b32 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_cpp_test.py @@ -0,0 +1,45 @@ +#! /usr/bin/python +# +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests for google.protobuf.internal.message_cpp.""" + +__author__ = 'shahms@google.com (Shahms King)' + +import os +os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp' + +import unittest +from google.protobuf.internal.message_test import * + + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_factory_test.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_factory_test.py new file mode 100644 index 0000000..0bc9be9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_factory_test.py @@ -0,0 +1,113 @@ +#! /usr/bin/python +# +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests for google.protobuf.message_factory.""" + +__author__ = 'matthewtoia@google.com (Matt Toia)' + +import unittest +from google.protobuf import descriptor_pb2 +from google.protobuf.internal import factory_test1_pb2 +from google.protobuf.internal import factory_test2_pb2 +from google.protobuf import descriptor_database +from google.protobuf import descriptor_pool +from google.protobuf import message_factory + + +class MessageFactoryTest(unittest.TestCase): + + def setUp(self): + self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString( + factory_test1_pb2.DESCRIPTOR.serialized_pb) + self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString( + factory_test2_pb2.DESCRIPTOR.serialized_pb) + + def _ExerciseDynamicClass(self, cls): + msg = cls() + msg.mandatory = 42 + msg.nested_factory_2_enum = 0 + msg.nested_factory_2_message.value = 'nested message value' + msg.factory_1_message.factory_1_enum = 1 + msg.factory_1_message.nested_factory_1_enum = 0 + msg.factory_1_message.nested_factory_1_message.value = ( + 'nested message value') + msg.factory_1_message.scalar_value = 22 + msg.factory_1_message.list_value.extend(['one', 'two', 'three']) + msg.factory_1_message.list_value.append('four') + msg.factory_1_enum = 1 + msg.nested_factory_1_enum = 0 + msg.nested_factory_1_message.value = 'nested message value' + msg.circular_message.mandatory = 1 + msg.circular_message.circular_message.mandatory = 2 + msg.circular_message.scalar_value = 'one deep' + msg.scalar_value = 'zero deep' + msg.list_value.extend(['four', 'three', 'two']) + msg.list_value.append('one') + msg.grouped.add() + msg.grouped[0].part_1 = 'hello' + msg.grouped[0].part_2 = 'world' + msg.grouped.add(part_1='testing', part_2='123') + msg.loop.loop.mandatory = 2 + msg.loop.loop.loop.loop.mandatory = 4 + serialized = msg.SerializeToString() + converted = factory_test2_pb2.Factory2Message.FromString(serialized) + reserialized = converted.SerializeToString() + self.assertEquals(serialized, reserialized) + result = cls.FromString(reserialized) + self.assertEquals(msg, result) + + def testGetPrototype(self): + db = descriptor_database.DescriptorDatabase() + pool = descriptor_pool.DescriptorPool(db) + db.Add(self.factory_test1_fd) + db.Add(self.factory_test2_fd) + factory = message_factory.MessageFactory() + cls = factory.GetPrototype(pool.FindMessageTypeByName( + 'net.proto2.python.internal.Factory2Message')) + self.assertIsNot(cls, factory_test2_pb2.Factory2Message) + self._ExerciseDynamicClass(cls) + cls2 = factory.GetPrototype(pool.FindMessageTypeByName( + 'net.proto2.python.internal.Factory2Message')) + self.assertIs(cls, cls2) + + def testGetMessages(self): + messages = message_factory.GetMessages([self.factory_test2_fd, + self.factory_test1_fd]) + self.assertContainsSubset( + ['net.proto2.python.internal.Factory2Message', + 'net.proto2.python.internal.Factory1Message'], + messages.keys()) + self._ExerciseDynamicClass( + messages['net.proto2.python.internal.Factory2Message']) + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_listener.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_listener.py new file mode 100755 index 0000000..1080234 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_listener.py @@ -0,0 +1,78 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Defines a listener interface for observing certain +state transitions on Message objects. + +Also defines a null implementation of this interface. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + + +class MessageListener(object): + + """Listens for modifications made to a message. Meant to be registered via + Message._SetListener(). + + Attributes: + dirty: If True, then calling Modified() would be a no-op. This can be + used to avoid these calls entirely in the common case. + """ + + def Modified(self): + """Called every time the message is modified in such a way that the parent + message may need to be updated. This currently means either: + (a) The message was modified for the first time, so the parent message + should henceforth mark the message as present. + (b) The message's cached byte size became dirty -- i.e. the message was + modified for the first time after a previous call to ByteSize(). + Therefore the parent should also mark its byte size as dirty. + Note that (a) implies (b), since new objects start out with a client cached + size (zero). However, we document (a) explicitly because it is important. + + Modified() will *only* be called in response to one of these two events -- + not every time the sub-message is modified. + + Note that if the listener's |dirty| attribute is true, then calling + Modified at the moment would be a no-op, so it can be skipped. Performance- + sensitive callers should check this attribute directly before calling since + it will be true most of the time. + """ + + raise NotImplementedError + + +class NullMessageListener(object): + + """No-op MessageListener implementation.""" + + def Modified(self): + pass diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_test.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_test.py new file mode 100755 index 0000000..53e9d50 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/message_test.py @@ -0,0 +1,494 @@ +#! /usr/bin/python +# +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests python protocol buffers against the golden message. + +Note that the golden messages exercise every known field type, thus this +test ends up exercising and verifying nearly all of the parsing and +serialization code in the whole library. + +TODO(kenton): Merge with wire_format_test? It doesn't make a whole lot of +sense to call this a test of the "message" module, which only declares an +abstract interface. +""" + +__author__ = 'gps@google.com (Gregory P. Smith)' + +import copy +import math +import operator +import pickle + +import unittest +from google.protobuf import unittest_import_pb2 +from google.protobuf import unittest_pb2 +from google.protobuf.internal import api_implementation +from google.protobuf.internal import test_util +from google.protobuf import message + +# Python pre-2.6 does not have isinf() or isnan() functions, so we have +# to provide our own. +def isnan(val): + # NaN is never equal to itself. + return val != val +def isinf(val): + # Infinity times zero equals NaN. + return not isnan(val) and isnan(val * 0) +def IsPosInf(val): + return isinf(val) and (val > 0) +def IsNegInf(val): + return isinf(val) and (val < 0) + +class MessageTest(unittest.TestCase): + + def testGoldenMessage(self): + golden_data = test_util.GoldenFile('golden_message').read() + golden_message = unittest_pb2.TestAllTypes() + golden_message.ParseFromString(golden_data) + test_util.ExpectAllFieldsSet(self, golden_message) + self.assertEqual(golden_data, golden_message.SerializeToString()) + golden_copy = copy.deepcopy(golden_message) + self.assertEqual(golden_data, golden_copy.SerializeToString()) + + def testGoldenExtensions(self): + golden_data = test_util.GoldenFile('golden_message').read() + golden_message = unittest_pb2.TestAllExtensions() + golden_message.ParseFromString(golden_data) + all_set = unittest_pb2.TestAllExtensions() + test_util.SetAllExtensions(all_set) + self.assertEquals(all_set, golden_message) + self.assertEqual(golden_data, golden_message.SerializeToString()) + golden_copy = copy.deepcopy(golden_message) + self.assertEqual(golden_data, golden_copy.SerializeToString()) + + def testGoldenPackedMessage(self): + golden_data = test_util.GoldenFile('golden_packed_fields_message').read() + golden_message = unittest_pb2.TestPackedTypes() + golden_message.ParseFromString(golden_data) + all_set = unittest_pb2.TestPackedTypes() + test_util.SetAllPackedFields(all_set) + self.assertEquals(all_set, golden_message) + self.assertEqual(golden_data, all_set.SerializeToString()) + golden_copy = copy.deepcopy(golden_message) + self.assertEqual(golden_data, golden_copy.SerializeToString()) + + def testGoldenPackedExtensions(self): + golden_data = test_util.GoldenFile('golden_packed_fields_message').read() + golden_message = unittest_pb2.TestPackedExtensions() + golden_message.ParseFromString(golden_data) + all_set = unittest_pb2.TestPackedExtensions() + test_util.SetAllPackedExtensions(all_set) + self.assertEquals(all_set, golden_message) + self.assertEqual(golden_data, all_set.SerializeToString()) + golden_copy = copy.deepcopy(golden_message) + self.assertEqual(golden_data, golden_copy.SerializeToString()) + + def testPickleSupport(self): + golden_data = test_util.GoldenFile('golden_message').read() + golden_message = unittest_pb2.TestAllTypes() + golden_message.ParseFromString(golden_data) + pickled_message = pickle.dumps(golden_message) + + unpickled_message = pickle.loads(pickled_message) + self.assertEquals(unpickled_message, golden_message) + + def testPickleIncompleteProto(self): + golden_message = unittest_pb2.TestRequired(a=1) + pickled_message = pickle.dumps(golden_message) + + unpickled_message = pickle.loads(pickled_message) + self.assertEquals(unpickled_message, golden_message) + self.assertEquals(unpickled_message.a, 1) + # This is still an incomplete proto - so serializing should fail + self.assertRaises(message.EncodeError, unpickled_message.SerializeToString) + + def testPositiveInfinity(self): + golden_data = ('\x5D\x00\x00\x80\x7F' + '\x61\x00\x00\x00\x00\x00\x00\xF0\x7F' + '\xCD\x02\x00\x00\x80\x7F' + '\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\x7F') + golden_message = unittest_pb2.TestAllTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(IsPosInf(golden_message.optional_float)) + self.assertTrue(IsPosInf(golden_message.optional_double)) + self.assertTrue(IsPosInf(golden_message.repeated_float[0])) + self.assertTrue(IsPosInf(golden_message.repeated_double[0])) + self.assertEqual(golden_data, golden_message.SerializeToString()) + + def testNegativeInfinity(self): + golden_data = ('\x5D\x00\x00\x80\xFF' + '\x61\x00\x00\x00\x00\x00\x00\xF0\xFF' + '\xCD\x02\x00\x00\x80\xFF' + '\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\xFF') + golden_message = unittest_pb2.TestAllTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(IsNegInf(golden_message.optional_float)) + self.assertTrue(IsNegInf(golden_message.optional_double)) + self.assertTrue(IsNegInf(golden_message.repeated_float[0])) + self.assertTrue(IsNegInf(golden_message.repeated_double[0])) + self.assertEqual(golden_data, golden_message.SerializeToString()) + + def testNotANumber(self): + golden_data = ('\x5D\x00\x00\xC0\x7F' + '\x61\x00\x00\x00\x00\x00\x00\xF8\x7F' + '\xCD\x02\x00\x00\xC0\x7F' + '\xD1\x02\x00\x00\x00\x00\x00\x00\xF8\x7F') + golden_message = unittest_pb2.TestAllTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(isnan(golden_message.optional_float)) + self.assertTrue(isnan(golden_message.optional_double)) + self.assertTrue(isnan(golden_message.repeated_float[0])) + self.assertTrue(isnan(golden_message.repeated_double[0])) + + # The protocol buffer may serialize to any one of multiple different + # representations of a NaN. Rather than verify a specific representation, + # verify the serialized string can be converted into a correctly + # behaving protocol buffer. + serialized = golden_message.SerializeToString() + message = unittest_pb2.TestAllTypes() + message.ParseFromString(serialized) + self.assertTrue(isnan(message.optional_float)) + self.assertTrue(isnan(message.optional_double)) + self.assertTrue(isnan(message.repeated_float[0])) + self.assertTrue(isnan(message.repeated_double[0])) + + def testPositiveInfinityPacked(self): + golden_data = ('\xA2\x06\x04\x00\x00\x80\x7F' + '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\x7F') + golden_message = unittest_pb2.TestPackedTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(IsPosInf(golden_message.packed_float[0])) + self.assertTrue(IsPosInf(golden_message.packed_double[0])) + self.assertEqual(golden_data, golden_message.SerializeToString()) + + def testNegativeInfinityPacked(self): + golden_data = ('\xA2\x06\x04\x00\x00\x80\xFF' + '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\xFF') + golden_message = unittest_pb2.TestPackedTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(IsNegInf(golden_message.packed_float[0])) + self.assertTrue(IsNegInf(golden_message.packed_double[0])) + self.assertEqual(golden_data, golden_message.SerializeToString()) + + def testNotANumberPacked(self): + golden_data = ('\xA2\x06\x04\x00\x00\xC0\x7F' + '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF8\x7F') + golden_message = unittest_pb2.TestPackedTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(isnan(golden_message.packed_float[0])) + self.assertTrue(isnan(golden_message.packed_double[0])) + + serialized = golden_message.SerializeToString() + message = unittest_pb2.TestPackedTypes() + message.ParseFromString(serialized) + self.assertTrue(isnan(message.packed_float[0])) + self.assertTrue(isnan(message.packed_double[0])) + + def testExtremeFloatValues(self): + message = unittest_pb2.TestAllTypes() + + # Most positive exponent, no significand bits set. + kMostPosExponentNoSigBits = math.pow(2, 127) + message.optional_float = kMostPosExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == kMostPosExponentNoSigBits) + + # Most positive exponent, one significand bit set. + kMostPosExponentOneSigBit = 1.5 * math.pow(2, 127) + message.optional_float = kMostPosExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == kMostPosExponentOneSigBit) + + # Repeat last two cases with values of same magnitude, but negative. + message.optional_float = -kMostPosExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == -kMostPosExponentNoSigBits) + + message.optional_float = -kMostPosExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == -kMostPosExponentOneSigBit) + + # Most negative exponent, no significand bits set. + kMostNegExponentNoSigBits = math.pow(2, -127) + message.optional_float = kMostNegExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == kMostNegExponentNoSigBits) + + # Most negative exponent, one significand bit set. + kMostNegExponentOneSigBit = 1.5 * math.pow(2, -127) + message.optional_float = kMostNegExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == kMostNegExponentOneSigBit) + + # Repeat last two cases with values of the same magnitude, but negative. + message.optional_float = -kMostNegExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == -kMostNegExponentNoSigBits) + + message.optional_float = -kMostNegExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == -kMostNegExponentOneSigBit) + + def testExtremeDoubleValues(self): + message = unittest_pb2.TestAllTypes() + + # Most positive exponent, no significand bits set. + kMostPosExponentNoSigBits = math.pow(2, 1023) + message.optional_double = kMostPosExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == kMostPosExponentNoSigBits) + + # Most positive exponent, one significand bit set. + kMostPosExponentOneSigBit = 1.5 * math.pow(2, 1023) + message.optional_double = kMostPosExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == kMostPosExponentOneSigBit) + + # Repeat last two cases with values of same magnitude, but negative. + message.optional_double = -kMostPosExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == -kMostPosExponentNoSigBits) + + message.optional_double = -kMostPosExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == -kMostPosExponentOneSigBit) + + # Most negative exponent, no significand bits set. + kMostNegExponentNoSigBits = math.pow(2, -1023) + message.optional_double = kMostNegExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == kMostNegExponentNoSigBits) + + # Most negative exponent, one significand bit set. + kMostNegExponentOneSigBit = 1.5 * math.pow(2, -1023) + message.optional_double = kMostNegExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == kMostNegExponentOneSigBit) + + # Repeat last two cases with values of the same magnitude, but negative. + message.optional_double = -kMostNegExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == -kMostNegExponentNoSigBits) + + message.optional_double = -kMostNegExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == -kMostNegExponentOneSigBit) + + def testSortingRepeatedScalarFieldsDefaultComparator(self): + """Check some different types with the default comparator.""" + message = unittest_pb2.TestAllTypes() + + # TODO(mattp): would testing more scalar types strengthen test? + message.repeated_int32.append(1) + message.repeated_int32.append(3) + message.repeated_int32.append(2) + message.repeated_int32.sort() + self.assertEqual(message.repeated_int32[0], 1) + self.assertEqual(message.repeated_int32[1], 2) + self.assertEqual(message.repeated_int32[2], 3) + + message.repeated_float.append(1.1) + message.repeated_float.append(1.3) + message.repeated_float.append(1.2) + message.repeated_float.sort() + self.assertAlmostEqual(message.repeated_float[0], 1.1) + self.assertAlmostEqual(message.repeated_float[1], 1.2) + self.assertAlmostEqual(message.repeated_float[2], 1.3) + + message.repeated_string.append('a') + message.repeated_string.append('c') + message.repeated_string.append('b') + message.repeated_string.sort() + self.assertEqual(message.repeated_string[0], 'a') + self.assertEqual(message.repeated_string[1], 'b') + self.assertEqual(message.repeated_string[2], 'c') + + message.repeated_bytes.append('a') + message.repeated_bytes.append('c') + message.repeated_bytes.append('b') + message.repeated_bytes.sort() + self.assertEqual(message.repeated_bytes[0], 'a') + self.assertEqual(message.repeated_bytes[1], 'b') + self.assertEqual(message.repeated_bytes[2], 'c') + + def testSortingRepeatedScalarFieldsCustomComparator(self): + """Check some different types with custom comparator.""" + message = unittest_pb2.TestAllTypes() + + message.repeated_int32.append(-3) + message.repeated_int32.append(-2) + message.repeated_int32.append(-1) + message.repeated_int32.sort(lambda x,y: cmp(abs(x), abs(y))) + self.assertEqual(message.repeated_int32[0], -1) + self.assertEqual(message.repeated_int32[1], -2) + self.assertEqual(message.repeated_int32[2], -3) + + message.repeated_string.append('aaa') + message.repeated_string.append('bb') + message.repeated_string.append('c') + message.repeated_string.sort(lambda x,y: cmp(len(x), len(y))) + self.assertEqual(message.repeated_string[0], 'c') + self.assertEqual(message.repeated_string[1], 'bb') + self.assertEqual(message.repeated_string[2], 'aaa') + + def testSortingRepeatedCompositeFieldsCustomComparator(self): + """Check passing a custom comparator to sort a repeated composite field.""" + message = unittest_pb2.TestAllTypes() + + message.repeated_nested_message.add().bb = 1 + message.repeated_nested_message.add().bb = 3 + message.repeated_nested_message.add().bb = 2 + message.repeated_nested_message.add().bb = 6 + message.repeated_nested_message.add().bb = 5 + message.repeated_nested_message.add().bb = 4 + message.repeated_nested_message.sort(lambda x,y: cmp(x.bb, y.bb)) + self.assertEqual(message.repeated_nested_message[0].bb, 1) + self.assertEqual(message.repeated_nested_message[1].bb, 2) + self.assertEqual(message.repeated_nested_message[2].bb, 3) + self.assertEqual(message.repeated_nested_message[3].bb, 4) + self.assertEqual(message.repeated_nested_message[4].bb, 5) + self.assertEqual(message.repeated_nested_message[5].bb, 6) + + def testRepeatedCompositeFieldSortArguments(self): + """Check sorting a repeated composite field using list.sort() arguments.""" + message = unittest_pb2.TestAllTypes() + + get_bb = operator.attrgetter('bb') + cmp_bb = lambda a, b: cmp(a.bb, b.bb) + message.repeated_nested_message.add().bb = 1 + message.repeated_nested_message.add().bb = 3 + message.repeated_nested_message.add().bb = 2 + message.repeated_nested_message.add().bb = 6 + message.repeated_nested_message.add().bb = 5 + message.repeated_nested_message.add().bb = 4 + message.repeated_nested_message.sort(key=get_bb) + self.assertEqual([k.bb for k in message.repeated_nested_message], + [1, 2, 3, 4, 5, 6]) + message.repeated_nested_message.sort(key=get_bb, reverse=True) + self.assertEqual([k.bb for k in message.repeated_nested_message], + [6, 5, 4, 3, 2, 1]) + message.repeated_nested_message.sort(sort_function=cmp_bb) + self.assertEqual([k.bb for k in message.repeated_nested_message], + [1, 2, 3, 4, 5, 6]) + message.repeated_nested_message.sort(cmp=cmp_bb, reverse=True) + self.assertEqual([k.bb for k in message.repeated_nested_message], + [6, 5, 4, 3, 2, 1]) + + def testRepeatedScalarFieldSortArguments(self): + """Check sorting a scalar field using list.sort() arguments.""" + message = unittest_pb2.TestAllTypes() + + abs_cmp = lambda a, b: cmp(abs(a), abs(b)) + message.repeated_int32.append(-3) + message.repeated_int32.append(-2) + message.repeated_int32.append(-1) + message.repeated_int32.sort(key=abs) + self.assertEqual(list(message.repeated_int32), [-1, -2, -3]) + message.repeated_int32.sort(key=abs, reverse=True) + self.assertEqual(list(message.repeated_int32), [-3, -2, -1]) + message.repeated_int32.sort(sort_function=abs_cmp) + self.assertEqual(list(message.repeated_int32), [-1, -2, -3]) + message.repeated_int32.sort(cmp=abs_cmp, reverse=True) + self.assertEqual(list(message.repeated_int32), [-3, -2, -1]) + + len_cmp = lambda a, b: cmp(len(a), len(b)) + message.repeated_string.append('aaa') + message.repeated_string.append('bb') + message.repeated_string.append('c') + message.repeated_string.sort(key=len) + self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa']) + message.repeated_string.sort(key=len, reverse=True) + self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c']) + message.repeated_string.sort(sort_function=len_cmp) + self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa']) + message.repeated_string.sort(cmp=len_cmp, reverse=True) + self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c']) + + def testParsingMerge(self): + """Check the merge behavior when a required or optional field appears + multiple times in the input.""" + messages = [ + unittest_pb2.TestAllTypes(), + unittest_pb2.TestAllTypes(), + unittest_pb2.TestAllTypes() ] + messages[0].optional_int32 = 1 + messages[1].optional_int64 = 2 + messages[2].optional_int32 = 3 + messages[2].optional_string = 'hello' + + merged_message = unittest_pb2.TestAllTypes() + merged_message.optional_int32 = 3 + merged_message.optional_int64 = 2 + merged_message.optional_string = 'hello' + + generator = unittest_pb2.TestParsingMerge.RepeatedFieldsGenerator() + generator.field1.extend(messages) + generator.field2.extend(messages) + generator.field3.extend(messages) + generator.ext1.extend(messages) + generator.ext2.extend(messages) + generator.group1.add().field1.MergeFrom(messages[0]) + generator.group1.add().field1.MergeFrom(messages[1]) + generator.group1.add().field1.MergeFrom(messages[2]) + generator.group2.add().field1.MergeFrom(messages[0]) + generator.group2.add().field1.MergeFrom(messages[1]) + generator.group2.add().field1.MergeFrom(messages[2]) + + data = generator.SerializeToString() + parsing_merge = unittest_pb2.TestParsingMerge() + parsing_merge.ParseFromString(data) + + # Required and optional fields should be merged. + self.assertEqual(parsing_merge.required_all_types, merged_message) + self.assertEqual(parsing_merge.optional_all_types, merged_message) + self.assertEqual(parsing_merge.optionalgroup.optional_group_all_types, + merged_message) + self.assertEqual(parsing_merge.Extensions[ + unittest_pb2.TestParsingMerge.optional_ext], + merged_message) + + # Repeated fields should not be merged. + self.assertEqual(len(parsing_merge.repeated_all_types), 3) + self.assertEqual(len(parsing_merge.repeatedgroup), 3) + self.assertEqual(len(parsing_merge.Extensions[ + unittest_pb2.TestParsingMerge.repeated_ext]), 3) + + + def testSortEmptyRepeatedCompositeContainer(self): + """Exercise a scenario that has led to segfaults in the past. + """ + m = unittest_pb2.TestAllTypes() + m.repeated_nested_message.sort() + + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_extensions.proto b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_extensions.proto new file mode 100644 index 0000000..e2d9701 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_extensions.proto @@ -0,0 +1,58 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: robinson@google.com (Will Robinson) + + +package google.protobuf.internal; + + +message TopLevelMessage { + optional ExtendedMessage submessage = 1; +} + + +message ExtendedMessage { + extensions 1 to max; +} + + +message ForeignMessage { + optional int32 foreign_message_int = 1; +} + + +extend ExtendedMessage { + optional int32 optional_int_extension = 1; + optional ForeignMessage optional_message_extension = 2; + + repeated int32 repeated_int_extension = 3; + repeated ForeignMessage repeated_message_extension = 4; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_extensions_dynamic.proto b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_extensions_dynamic.proto new file mode 100644 index 0000000..df98ac4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_extensions_dynamic.proto @@ -0,0 +1,49 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jasonh@google.com (Jason Hsueh) +// +// This file is used to test a corner case in the CPP implementation where the +// generated C++ type is available for the extendee, but the extension is +// defined in a file whose C++ type is not in the binary. + + +import "google/protobuf/internal/more_extensions.proto"; + +package google.protobuf.internal; + +message DynamicMessageType { + optional int32 a = 1; +} + +extend ExtendedMessage { + optional int32 dynamic_int32_extension = 100; + optional DynamicMessageType dynamic_message_extension = 101; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_messages.proto b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_messages.proto new file mode 100644 index 0000000..c701b44 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/more_messages.proto @@ -0,0 +1,51 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: robinson@google.com (Will Robinson) + + +package google.protobuf.internal; + +// A message where tag numbers are listed out of order, to allow us to test our +// canonicalization of serialized output, which should always be in tag order. +// We also mix in some extensions for extra fun. +message OutOfOrderFields { + optional sint32 optional_sint32 = 5; + extensions 4 to 4; + optional uint32 optional_uint32 = 3; + extensions 2 to 2; + optional int32 optional_int32 = 1; +}; + + +extend OutOfOrderFields { + optional uint64 optional_uint64 = 4; + optional int64 optional_int64 = 2; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/python_message.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/python_message.py new file mode 100755 index 0000000..4bea57a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/python_message.py @@ -0,0 +1,1150 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# This code is meant to work on Python 2.4 and above only. +# +# TODO(robinson): Helpers for verbose, common checks like seeing if a +# descriptor's cpp_type is CPPTYPE_MESSAGE. + +"""Contains a metaclass and helper functions used to create +protocol message classes from Descriptor objects at runtime. + +Recall that a metaclass is the "type" of a class. +(A class is to a metaclass what an instance is to a class.) + +In this case, we use the GeneratedProtocolMessageType metaclass +to inject all the useful functionality into the classes +output by the protocol compiler at compile-time. + +The upshot of all this is that the real implementation +details for ALL pure-Python protocol buffers are *here in +this file*. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO +import copy_reg +import struct +import weakref + +# We use "as" to avoid name collisions with variables. +from google.protobuf.internal import containers +from google.protobuf.internal import decoder +from google.protobuf.internal import encoder +from google.protobuf.internal import enum_type_wrapper +from google.protobuf.internal import message_listener as message_listener_mod +from google.protobuf.internal import type_checkers +from google.protobuf.internal import wire_format +from google.protobuf import descriptor as descriptor_mod +from google.protobuf import message as message_mod +from google.protobuf import text_format + +_FieldDescriptor = descriptor_mod.FieldDescriptor + + +def NewMessage(bases, descriptor, dictionary): + _AddClassAttributesForNestedExtensions(descriptor, dictionary) + _AddSlots(descriptor, dictionary) + return bases + + +def InitMessage(descriptor, cls): + cls._decoders_by_tag = {} + cls._extensions_by_name = {} + cls._extensions_by_number = {} + if (descriptor.has_options and + descriptor.GetOptions().message_set_wire_format): + cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = ( + decoder.MessageSetItemDecoder(cls._extensions_by_number)) + + # Attach stuff to each FieldDescriptor for quick lookup later on. + for field in descriptor.fields: + _AttachFieldHelpers(cls, field) + + _AddEnumValues(descriptor, cls) + _AddInitMethod(descriptor, cls) + _AddPropertiesForFields(descriptor, cls) + _AddPropertiesForExtensions(descriptor, cls) + _AddStaticMethods(cls) + _AddMessageMethods(descriptor, cls) + _AddPrivateHelperMethods(cls) + copy_reg.pickle(cls, lambda obj: (cls, (), obj.__getstate__())) + + +# Stateless helpers for GeneratedProtocolMessageType below. +# Outside clients should not access these directly. +# +# I opted not to make any of these methods on the metaclass, to make it more +# clear that I'm not really using any state there and to keep clients from +# thinking that they have direct access to these construction helpers. + + +def _PropertyName(proto_field_name): + """Returns the name of the public property attribute which + clients can use to get and (in some cases) set the value + of a protocol message field. + + Args: + proto_field_name: The protocol message field name, exactly + as it appears (or would appear) in a .proto file. + """ + # TODO(robinson): Escape Python keywords (e.g., yield), and test this support. + # nnorwitz makes my day by writing: + # """ + # FYI. See the keyword module in the stdlib. This could be as simple as: + # + # if keyword.iskeyword(proto_field_name): + # return proto_field_name + "_" + # return proto_field_name + # """ + # Kenton says: The above is a BAD IDEA. People rely on being able to use + # getattr() and setattr() to reflectively manipulate field values. If we + # rename the properties, then every such user has to also make sure to apply + # the same transformation. Note that currently if you name a field "yield", + # you can still access it just fine using getattr/setattr -- it's not even + # that cumbersome to do so. + # TODO(kenton): Remove this method entirely if/when everyone agrees with my + # position. + return proto_field_name + + +def _VerifyExtensionHandle(message, extension_handle): + """Verify that the given extension handle is valid.""" + + if not isinstance(extension_handle, _FieldDescriptor): + raise KeyError('HasExtension() expects an extension handle, got: %s' % + extension_handle) + + if not extension_handle.is_extension: + raise KeyError('"%s" is not an extension.' % extension_handle.full_name) + + if not extension_handle.containing_type: + raise KeyError('"%s" is missing a containing_type.' + % extension_handle.full_name) + + if extension_handle.containing_type is not message.DESCRIPTOR: + raise KeyError('Extension "%s" extends message type "%s", but this ' + 'message is of type "%s".' % + (extension_handle.full_name, + extension_handle.containing_type.full_name, + message.DESCRIPTOR.full_name)) + + +def _AddSlots(message_descriptor, dictionary): + """Adds a __slots__ entry to dictionary, containing the names of all valid + attributes for this message type. + + Args: + message_descriptor: A Descriptor instance describing this message type. + dictionary: Class dictionary to which we'll add a '__slots__' entry. + """ + dictionary['__slots__'] = ['_cached_byte_size', + '_cached_byte_size_dirty', + '_fields', + '_unknown_fields', + '_is_present_in_parent', + '_listener', + '_listener_for_children', + '__weakref__'] + + +def _IsMessageSetExtension(field): + return (field.is_extension and + field.containing_type.has_options and + field.containing_type.GetOptions().message_set_wire_format and + field.type == _FieldDescriptor.TYPE_MESSAGE and + field.message_type == field.extension_scope and + field.label == _FieldDescriptor.LABEL_OPTIONAL) + + +def _AttachFieldHelpers(cls, field_descriptor): + is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED) + is_packed = (field_descriptor.has_options and + field_descriptor.GetOptions().packed) + + if _IsMessageSetExtension(field_descriptor): + field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number) + sizer = encoder.MessageSetItemSizer(field_descriptor.number) + else: + field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type]( + field_descriptor.number, is_repeated, is_packed) + sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type]( + field_descriptor.number, is_repeated, is_packed) + + field_descriptor._encoder = field_encoder + field_descriptor._sizer = sizer + field_descriptor._default_constructor = _DefaultValueConstructorForField( + field_descriptor) + + def AddDecoder(wiretype, is_packed): + tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype) + cls._decoders_by_tag[tag_bytes] = ( + type_checkers.TYPE_TO_DECODER[field_descriptor.type]( + field_descriptor.number, is_repeated, is_packed, + field_descriptor, field_descriptor._default_constructor)) + + AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], + False) + + if is_repeated and wire_format.IsTypePackable(field_descriptor.type): + # To support wire compatibility of adding packed = true, add a decoder for + # packed values regardless of the field's options. + AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True) + + +def _AddClassAttributesForNestedExtensions(descriptor, dictionary): + extension_dict = descriptor.extensions_by_name + for extension_name, extension_field in extension_dict.iteritems(): + assert extension_name not in dictionary + dictionary[extension_name] = extension_field + + +def _AddEnumValues(descriptor, cls): + """Sets class-level attributes for all enum fields defined in this message. + + Also exporting a class-level object that can name enum values. + + Args: + descriptor: Descriptor object for this message type. + cls: Class we're constructing for this message type. + """ + for enum_type in descriptor.enum_types: + setattr(cls, enum_type.name, enum_type_wrapper.EnumTypeWrapper(enum_type)) + for enum_value in enum_type.values: + setattr(cls, enum_value.name, enum_value.number) + + +def _DefaultValueConstructorForField(field): + """Returns a function which returns a default value for a field. + + Args: + field: FieldDescriptor object for this field. + + The returned function has one argument: + message: Message instance containing this field, or a weakref proxy + of same. + + That function in turn returns a default value for this field. The default + value may refer back to |message| via a weak reference. + """ + + if field.label == _FieldDescriptor.LABEL_REPEATED: + if field.has_default_value and field.default_value != []: + raise ValueError('Repeated field default value not empty list: %s' % ( + field.default_value)) + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + # We can't look at _concrete_class yet since it might not have + # been set. (Depends on order in which we initialize the classes). + message_type = field.message_type + def MakeRepeatedMessageDefault(message): + return containers.RepeatedCompositeFieldContainer( + message._listener_for_children, field.message_type) + return MakeRepeatedMessageDefault + else: + type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) + def MakeRepeatedScalarDefault(message): + return containers.RepeatedScalarFieldContainer( + message._listener_for_children, type_checker) + return MakeRepeatedScalarDefault + + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + # _concrete_class may not yet be initialized. + message_type = field.message_type + def MakeSubMessageDefault(message): + result = message_type._concrete_class() + result._SetListener(message._listener_for_children) + return result + return MakeSubMessageDefault + + def MakeScalarDefault(message): + # TODO(protobuf-team): This may be broken since there may not be + # default_value. Combine with has_default_value somehow. + return field.default_value + return MakeScalarDefault + + +def _AddInitMethod(message_descriptor, cls): + """Adds an __init__ method to cls.""" + fields = message_descriptor.fields + def init(self, **kwargs): + self._cached_byte_size = 0 + self._cached_byte_size_dirty = len(kwargs) > 0 + self._fields = {} + # _unknown_fields is () when empty for efficiency, and will be turned into + # a list if fields are added. + self._unknown_fields = () + self._is_present_in_parent = False + self._listener = message_listener_mod.NullMessageListener() + self._listener_for_children = _Listener(self) + for field_name, field_value in kwargs.iteritems(): + field = _GetFieldByName(message_descriptor, field_name) + if field is None: + raise TypeError("%s() got an unexpected keyword argument '%s'" % + (message_descriptor.name, field_name)) + if field.label == _FieldDescriptor.LABEL_REPEATED: + copy = field._default_constructor(self) + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite + for val in field_value: + copy.add().MergeFrom(val) + else: # Scalar + copy.extend(field_value) + self._fields[field] = copy + elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + copy = field._default_constructor(self) + copy.MergeFrom(field_value) + self._fields[field] = copy + else: + setattr(self, field_name, field_value) + + init.__module__ = None + init.__doc__ = None + cls.__init__ = init + + +def _GetFieldByName(message_descriptor, field_name): + """Returns a field descriptor by field name. + + Args: + message_descriptor: A Descriptor describing all fields in message. + field_name: The name of the field to retrieve. + Returns: + The field descriptor associated with the field name. + """ + try: + return message_descriptor.fields_by_name[field_name] + except KeyError: + raise ValueError('Protocol message has no "%s" field.' % field_name) + + +def _AddPropertiesForFields(descriptor, cls): + """Adds properties for all fields in this protocol message type.""" + for field in descriptor.fields: + _AddPropertiesForField(field, cls) + + if descriptor.is_extendable: + # _ExtensionDict is just an adaptor with no state so we allocate a new one + # every time it is accessed. + cls.Extensions = property(lambda self: _ExtensionDict(self)) + + +def _AddPropertiesForField(field, cls): + """Adds a public property for a protocol message field. + Clients can use this property to get and (in the case + of non-repeated scalar fields) directly set the value + of a protocol message field. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + # Catch it if we add other types that we should + # handle specially here. + assert _FieldDescriptor.MAX_CPPTYPE == 10 + + constant_name = field.name.upper() + "_FIELD_NUMBER" + setattr(cls, constant_name, field.number) + + if field.label == _FieldDescriptor.LABEL_REPEATED: + _AddPropertiesForRepeatedField(field, cls) + elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + _AddPropertiesForNonRepeatedCompositeField(field, cls) + else: + _AddPropertiesForNonRepeatedScalarField(field, cls) + + +def _AddPropertiesForRepeatedField(field, cls): + """Adds a public property for a "repeated" protocol message field. Clients + can use this property to get the value of the field, which will be either a + _RepeatedScalarFieldContainer or _RepeatedCompositeFieldContainer (see + below). + + Note that when clients add values to these containers, we perform + type-checking in the case of repeated scalar fields, and we also set any + necessary "has" bits as a side-effect. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + proto_field_name = field.name + property_name = _PropertyName(proto_field_name) + + def getter(self): + field_value = self._fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + field_value = self._fields.setdefault(field, field_value) + return field_value + getter.__module__ = None + getter.__doc__ = 'Getter for %s.' % proto_field_name + + # We define a setter just so we can throw an exception with a more + # helpful error message. + def setter(self, new_value): + raise AttributeError('Assignment not allowed to repeated field ' + '"%s" in protocol message object.' % proto_field_name) + + doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name + setattr(cls, property_name, property(getter, setter, doc=doc)) + + +def _AddPropertiesForNonRepeatedScalarField(field, cls): + """Adds a public property for a nonrepeated, scalar protocol message field. + Clients can use this property to get and directly set the value of the field. + Note that when the client sets the value of a field by using this property, + all necessary "has" bits are set as a side-effect, and we also perform + type-checking. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + proto_field_name = field.name + property_name = _PropertyName(proto_field_name) + type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) + default_value = field.default_value + valid_values = set() + + def getter(self): + # TODO(protobuf-team): This may be broken since there may not be + # default_value. Combine with has_default_value somehow. + return self._fields.get(field, default_value) + getter.__module__ = None + getter.__doc__ = 'Getter for %s.' % proto_field_name + def setter(self, new_value): + type_checker.CheckValue(new_value) + self._fields[field] = new_value + # Check _cached_byte_size_dirty inline to improve performance, since scalar + # setters are called frequently. + if not self._cached_byte_size_dirty: + self._Modified() + + setter.__module__ = None + setter.__doc__ = 'Setter for %s.' % proto_field_name + + # Add a property to encapsulate the getter/setter. + doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name + setattr(cls, property_name, property(getter, setter, doc=doc)) + + +def _AddPropertiesForNonRepeatedCompositeField(field, cls): + """Adds a public property for a nonrepeated, composite protocol message field. + A composite field is a "group" or "message" field. + + Clients can use this property to get the value of the field, but cannot + assign to the property directly. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + # TODO(robinson): Remove duplication with similar method + # for non-repeated scalars. + proto_field_name = field.name + property_name = _PropertyName(proto_field_name) + + # TODO(komarek): Can anyone explain to me why we cache the message_type this + # way, instead of referring to field.message_type inside of getter(self)? + # What if someone sets message_type later on (which makes for simpler + # dyanmic proto descriptor and class creation code). + message_type = field.message_type + + def getter(self): + field_value = self._fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = message_type._concrete_class() # use field.message_type? + field_value._SetListener(self._listener_for_children) + + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + field_value = self._fields.setdefault(field, field_value) + return field_value + getter.__module__ = None + getter.__doc__ = 'Getter for %s.' % proto_field_name + + # We define a setter just so we can throw an exception with a more + # helpful error message. + def setter(self, new_value): + raise AttributeError('Assignment not allowed to composite field ' + '"%s" in protocol message object.' % proto_field_name) + + # Add a property to encapsulate the getter. + doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name + setattr(cls, property_name, property(getter, setter, doc=doc)) + + +def _AddPropertiesForExtensions(descriptor, cls): + """Adds properties for all fields in this protocol message type.""" + extension_dict = descriptor.extensions_by_name + for extension_name, extension_field in extension_dict.iteritems(): + constant_name = extension_name.upper() + "_FIELD_NUMBER" + setattr(cls, constant_name, extension_field.number) + + +def _AddStaticMethods(cls): + # TODO(robinson): This probably needs to be thread-safe(?) + def RegisterExtension(extension_handle): + extension_handle.containing_type = cls.DESCRIPTOR + _AttachFieldHelpers(cls, extension_handle) + + # Try to insert our extension, failing if an extension with the same number + # already exists. + actual_handle = cls._extensions_by_number.setdefault( + extension_handle.number, extension_handle) + if actual_handle is not extension_handle: + raise AssertionError( + 'Extensions "%s" and "%s" both try to extend message type "%s" with ' + 'field number %d.' % + (extension_handle.full_name, actual_handle.full_name, + cls.DESCRIPTOR.full_name, extension_handle.number)) + + cls._extensions_by_name[extension_handle.full_name] = extension_handle + + handle = extension_handle # avoid line wrapping + if _IsMessageSetExtension(handle): + # MessageSet extension. Also register under type name. + cls._extensions_by_name[ + extension_handle.message_type.full_name] = extension_handle + + cls.RegisterExtension = staticmethod(RegisterExtension) + + def FromString(s): + message = cls() + message.MergeFromString(s) + return message + cls.FromString = staticmethod(FromString) + + +def _IsPresent(item): + """Given a (FieldDescriptor, value) tuple from _fields, return true if the + value should be included in the list returned by ListFields().""" + + if item[0].label == _FieldDescriptor.LABEL_REPEATED: + return bool(item[1]) + elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + return item[1]._is_present_in_parent + else: + return True + + +def _AddListFieldsMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def ListFields(self): + all_fields = [item for item in self._fields.iteritems() if _IsPresent(item)] + all_fields.sort(key = lambda item: item[0].number) + return all_fields + + cls.ListFields = ListFields + + +def _AddHasFieldMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + singular_fields = {} + for field in message_descriptor.fields: + if field.label != _FieldDescriptor.LABEL_REPEATED: + singular_fields[field.name] = field + + def HasField(self, field_name): + try: + field = singular_fields[field_name] + except KeyError: + raise ValueError( + 'Protocol message has no singular "%s" field.' % field_name) + + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + value = self._fields.get(field) + return value is not None and value._is_present_in_parent + else: + return field in self._fields + cls.HasField = HasField + + +def _AddClearFieldMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + def ClearField(self, field_name): + try: + field = message_descriptor.fields_by_name[field_name] + except KeyError: + raise ValueError('Protocol message has no "%s" field.' % field_name) + + if field in self._fields: + # Note: If the field is a sub-message, its listener will still point + # at us. That's fine, because the worst than can happen is that it + # will call _Modified() and invalidate our byte size. Big deal. + del self._fields[field] + + # Always call _Modified() -- even if nothing was changed, this is + # a mutating method, and thus calling it should cause the field to become + # present in the parent message. + self._Modified() + + cls.ClearField = ClearField + + +def _AddClearExtensionMethod(cls): + """Helper for _AddMessageMethods().""" + def ClearExtension(self, extension_handle): + _VerifyExtensionHandle(self, extension_handle) + + # Similar to ClearField(), above. + if extension_handle in self._fields: + del self._fields[extension_handle] + self._Modified() + cls.ClearExtension = ClearExtension + + +def _AddClearMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + def Clear(self): + # Clear fields. + self._fields = {} + self._unknown_fields = () + self._Modified() + cls.Clear = Clear + + +def _AddHasExtensionMethod(cls): + """Helper for _AddMessageMethods().""" + def HasExtension(self, extension_handle): + _VerifyExtensionHandle(self, extension_handle) + if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: + raise KeyError('"%s" is repeated.' % extension_handle.full_name) + + if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + value = self._fields.get(extension_handle) + return value is not None and value._is_present_in_parent + else: + return extension_handle in self._fields + cls.HasExtension = HasExtension + + +def _AddEqualsMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + def __eq__(self, other): + if (not isinstance(other, message_mod.Message) or + other.DESCRIPTOR != self.DESCRIPTOR): + return False + + if self is other: + return True + + if not self.ListFields() == other.ListFields(): + return False + + # Sort unknown fields because their order shouldn't affect equality test. + unknown_fields = list(self._unknown_fields) + unknown_fields.sort() + other_unknown_fields = list(other._unknown_fields) + other_unknown_fields.sort() + + return unknown_fields == other_unknown_fields + + cls.__eq__ = __eq__ + + +def _AddStrMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + def __str__(self): + return text_format.MessageToString(self) + cls.__str__ = __str__ + + +def _AddUnicodeMethod(unused_message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def __unicode__(self): + return text_format.MessageToString(self, as_utf8=True).decode('utf-8') + cls.__unicode__ = __unicode__ + + +def _AddSetListenerMethod(cls): + """Helper for _AddMessageMethods().""" + def SetListener(self, listener): + if listener is None: + self._listener = message_listener_mod.NullMessageListener() + else: + self._listener = listener + cls._SetListener = SetListener + + +def _BytesForNonRepeatedElement(value, field_number, field_type): + """Returns the number of bytes needed to serialize a non-repeated element. + The returned byte count includes space for tag information and any + other additional space associated with serializing value. + + Args: + value: Value we're serializing. + field_number: Field number of this value. (Since the field number + is stored as part of a varint-encoded tag, this has an impact + on the total bytes required to serialize the value). + field_type: The type of the field. One of the TYPE_* constants + within FieldDescriptor. + """ + try: + fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type] + return fn(field_number, value) + except KeyError: + raise message_mod.EncodeError('Unrecognized field type: %d' % field_type) + + +def _AddByteSizeMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def ByteSize(self): + if not self._cached_byte_size_dirty: + return self._cached_byte_size + + size = 0 + for field_descriptor, field_value in self.ListFields(): + size += field_descriptor._sizer(field_value) + + for tag_bytes, value_bytes in self._unknown_fields: + size += len(tag_bytes) + len(value_bytes) + + self._cached_byte_size = size + self._cached_byte_size_dirty = False + self._listener_for_children.dirty = False + return size + + cls.ByteSize = ByteSize + + +def _AddSerializeToStringMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def SerializeToString(self): + # Check if the message has all of its required fields set. + errors = [] + if not self.IsInitialized(): + raise message_mod.EncodeError( + 'Message %s is missing required fields: %s' % ( + self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors()))) + return self.SerializePartialToString() + cls.SerializeToString = SerializeToString + + +def _AddSerializePartialToStringMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def SerializePartialToString(self): + out = StringIO() + self._InternalSerialize(out.write) + return out.getvalue() + cls.SerializePartialToString = SerializePartialToString + + def InternalSerialize(self, write_bytes): + for field_descriptor, field_value in self.ListFields(): + field_descriptor._encoder(write_bytes, field_value) + for tag_bytes, value_bytes in self._unknown_fields: + write_bytes(tag_bytes) + write_bytes(value_bytes) + cls._InternalSerialize = InternalSerialize + + +def _AddMergeFromStringMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + def MergeFromString(self, serialized): + length = len(serialized) + try: + if self._InternalParse(serialized, 0, length) != length: + # The only reason _InternalParse would return early is if it + # encountered an end-group tag. + raise message_mod.DecodeError('Unexpected end-group tag.') + except IndexError: + raise message_mod.DecodeError('Truncated message.') + except struct.error, e: + raise message_mod.DecodeError(e) + return length # Return this for legacy reasons. + cls.MergeFromString = MergeFromString + + local_ReadTag = decoder.ReadTag + local_SkipField = decoder.SkipField + decoders_by_tag = cls._decoders_by_tag + + def InternalParse(self, buffer, pos, end): + self._Modified() + field_dict = self._fields + unknown_field_list = self._unknown_fields + while pos != end: + (tag_bytes, new_pos) = local_ReadTag(buffer, pos) + field_decoder = decoders_by_tag.get(tag_bytes) + if field_decoder is None: + value_start_pos = new_pos + new_pos = local_SkipField(buffer, new_pos, end, tag_bytes) + if new_pos == -1: + return pos + if not unknown_field_list: + unknown_field_list = self._unknown_fields = [] + unknown_field_list.append((tag_bytes, buffer[value_start_pos:new_pos])) + pos = new_pos + else: + pos = field_decoder(buffer, new_pos, end, self, field_dict) + return pos + cls._InternalParse = InternalParse + + +def _AddIsInitializedMethod(message_descriptor, cls): + """Adds the IsInitialized and FindInitializationError methods to the + protocol message class.""" + + required_fields = [field for field in message_descriptor.fields + if field.label == _FieldDescriptor.LABEL_REQUIRED] + + def IsInitialized(self, errors=None): + """Checks if all required fields of a message are set. + + Args: + errors: A list which, if provided, will be populated with the field + paths of all missing required fields. + + Returns: + True iff the specified message has all required fields set. + """ + + # Performance is critical so we avoid HasField() and ListFields(). + + for field in required_fields: + if (field not in self._fields or + (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and + not self._fields[field]._is_present_in_parent)): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False + + for field, value in self._fields.iteritems(): + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + if field.label == _FieldDescriptor.LABEL_REPEATED: + for element in value: + if not element.IsInitialized(): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False + elif value._is_present_in_parent and not value.IsInitialized(): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False + + return True + + cls.IsInitialized = IsInitialized + + def FindInitializationErrors(self): + """Finds required fields which are not initialized. + + Returns: + A list of strings. Each string is a path to an uninitialized field from + the top-level message, e.g. "foo.bar[5].baz". + """ + + errors = [] # simplify things + + for field in required_fields: + if not self.HasField(field.name): + errors.append(field.name) + + for field, value in self.ListFields(): + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + if field.is_extension: + name = "(%s)" % field.full_name + else: + name = field.name + + if field.label == _FieldDescriptor.LABEL_REPEATED: + for i in xrange(len(value)): + element = value[i] + prefix = "%s[%d]." % (name, i) + sub_errors = element.FindInitializationErrors() + errors += [ prefix + error for error in sub_errors ] + else: + prefix = name + "." + sub_errors = value.FindInitializationErrors() + errors += [ prefix + error for error in sub_errors ] + + return errors + + cls.FindInitializationErrors = FindInitializationErrors + + +def _AddMergeFromMethod(cls): + LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED + CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE + + def MergeFrom(self, msg): + if not isinstance(msg, cls): + raise TypeError( + "Parameter to MergeFrom() must be instance of same class: " + "expected %s got %s." % (cls.__name__, type(msg).__name__)) + + assert msg is not self + self._Modified() + + fields = self._fields + + for field, value in msg._fields.iteritems(): + if field.label == LABEL_REPEATED: + field_value = fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + fields[field] = field_value + field_value.MergeFrom(value) + elif field.cpp_type == CPPTYPE_MESSAGE: + if value._is_present_in_parent: + field_value = fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + fields[field] = field_value + field_value.MergeFrom(value) + else: + self._fields[field] = value + + if msg._unknown_fields: + if not self._unknown_fields: + self._unknown_fields = [] + self._unknown_fields.extend(msg._unknown_fields) + + cls.MergeFrom = MergeFrom + + +def _AddMessageMethods(message_descriptor, cls): + """Adds implementations of all Message methods to cls.""" + _AddListFieldsMethod(message_descriptor, cls) + _AddHasFieldMethod(message_descriptor, cls) + _AddClearFieldMethod(message_descriptor, cls) + if message_descriptor.is_extendable: + _AddClearExtensionMethod(cls) + _AddHasExtensionMethod(cls) + _AddClearMethod(message_descriptor, cls) + _AddEqualsMethod(message_descriptor, cls) + _AddStrMethod(message_descriptor, cls) + _AddUnicodeMethod(message_descriptor, cls) + _AddSetListenerMethod(cls) + _AddByteSizeMethod(message_descriptor, cls) + _AddSerializeToStringMethod(message_descriptor, cls) + _AddSerializePartialToStringMethod(message_descriptor, cls) + _AddMergeFromStringMethod(message_descriptor, cls) + _AddIsInitializedMethod(message_descriptor, cls) + _AddMergeFromMethod(cls) + + +def _AddPrivateHelperMethods(cls): + """Adds implementation of private helper methods to cls.""" + + def Modified(self): + """Sets the _cached_byte_size_dirty bit to true, + and propagates this to our listener iff this was a state change. + """ + + # Note: Some callers check _cached_byte_size_dirty before calling + # _Modified() as an extra optimization. So, if this method is ever + # changed such that it does stuff even when _cached_byte_size_dirty is + # already true, the callers need to be updated. + if not self._cached_byte_size_dirty: + self._cached_byte_size_dirty = True + self._listener_for_children.dirty = True + self._is_present_in_parent = True + self._listener.Modified() + + cls._Modified = Modified + cls.SetInParent = Modified + + +class _Listener(object): + + """MessageListener implementation that a parent message registers with its + child message. + + In order to support semantics like: + + foo.bar.baz.qux = 23 + assert foo.HasField('bar') + + ...child objects must have back references to their parents. + This helper class is at the heart of this support. + """ + + def __init__(self, parent_message): + """Args: + parent_message: The message whose _Modified() method we should call when + we receive Modified() messages. + """ + # This listener establishes a back reference from a child (contained) object + # to its parent (containing) object. We make this a weak reference to avoid + # creating cyclic garbage when the client finishes with the 'parent' object + # in the tree. + if isinstance(parent_message, weakref.ProxyType): + self._parent_message_weakref = parent_message + else: + self._parent_message_weakref = weakref.proxy(parent_message) + + # As an optimization, we also indicate directly on the listener whether + # or not the parent message is dirty. This way we can avoid traversing + # up the tree in the common case. + self.dirty = False + + def Modified(self): + if self.dirty: + return + try: + # Propagate the signal to our parents iff this is the first field set. + self._parent_message_weakref._Modified() + except ReferenceError: + # We can get here if a client has kept a reference to a child object, + # and is now setting a field on it, but the child's parent has been + # garbage-collected. This is not an error. + pass + + +# TODO(robinson): Move elsewhere? This file is getting pretty ridiculous... +# TODO(robinson): Unify error handling of "unknown extension" crap. +# TODO(robinson): Support iteritems()-style iteration over all +# extensions with the "has" bits turned on? +class _ExtensionDict(object): + + """Dict-like container for supporting an indexable "Extensions" + field on proto instances. + + Note that in all cases we expect extension handles to be + FieldDescriptors. + """ + + def __init__(self, extended_message): + """extended_message: Message instance for which we are the Extensions dict. + """ + + self._extended_message = extended_message + + def __getitem__(self, extension_handle): + """Returns the current value of the given extension handle.""" + + _VerifyExtensionHandle(self._extended_message, extension_handle) + + result = self._extended_message._fields.get(extension_handle) + if result is not None: + return result + + if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: + result = extension_handle._default_constructor(self._extended_message) + elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + result = extension_handle.message_type._concrete_class() + try: + result._SetListener(self._extended_message._listener_for_children) + except ReferenceError: + pass + else: + # Singular scalar -- just return the default without inserting into the + # dict. + return extension_handle.default_value + + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + result = self._extended_message._fields.setdefault( + extension_handle, result) + + return result + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return False + + my_fields = self._extended_message.ListFields() + other_fields = other._extended_message.ListFields() + + # Get rid of non-extension fields. + my_fields = [ field for field in my_fields if field.is_extension ] + other_fields = [ field for field in other_fields if field.is_extension ] + + return my_fields == other_fields + + def __ne__(self, other): + return not self == other + + def __hash__(self): + raise TypeError('unhashable object') + + # Note that this is only meaningful for non-repeated, scalar extension + # fields. Note also that we may have to call _Modified() when we do + # successfully set a field this way, to set any necssary "has" bits in the + # ancestors of the extended message. + def __setitem__(self, extension_handle, value): + """If extension_handle specifies a non-repeated, scalar extension + field, sets the value of that field. + """ + + _VerifyExtensionHandle(self._extended_message, extension_handle) + + if (extension_handle.label == _FieldDescriptor.LABEL_REPEATED or + extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE): + raise TypeError( + 'Cannot assign to extension "%s" because it is a repeated or ' + 'composite type.' % extension_handle.full_name) + + # It's slightly wasteful to lookup the type checker each time, + # but we expect this to be a vanishingly uncommon case anyway. + type_checker = type_checkers.GetTypeChecker( + extension_handle.cpp_type, extension_handle.type) + type_checker.CheckValue(value) + self._extended_message._fields[extension_handle] = value + self._extended_message._Modified() + + def _FindExtensionByName(self, name): + """Tries to find a known extension with the specified name. + + Args: + name: Extension full name. + + Returns: + Extension field descriptor. + """ + return self._extended_message._extensions_by_name.get(name, None) diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/reflection_cpp_generated_test.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/reflection_cpp_generated_test.py new file mode 100755 index 0000000..2a0a512 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/reflection_cpp_generated_test.py @@ -0,0 +1,91 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- +# +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unittest for reflection.py, which tests the generated C++ implementation.""" + +__author__ = 'jasonh@google.com (Jason Hsueh)' + +import os +os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp' + +import unittest +from google.protobuf.internal import api_implementation +from google.protobuf.internal import more_extensions_dynamic_pb2 +from google.protobuf.internal import more_extensions_pb2 +from google.protobuf.internal.reflection_test import * + + +class ReflectionCppTest(unittest.TestCase): + def testImplementationSetting(self): + self.assertEqual('cpp', api_implementation.Type()) + + def testExtensionOfGeneratedTypeInDynamicFile(self): + """Tests that a file built dynamically can extend a generated C++ type. + + The C++ implementation uses a DescriptorPool that has the generated + DescriptorPool as an underlay. Typically, a type can only find + extensions in its own pool. With the python C-extension, the generated C++ + extendee may be available, but not the extension. This tests that the + C-extension implements the correct special handling to make such extensions + available. + """ + pb1 = more_extensions_pb2.ExtendedMessage() + # Test that basic accessors work. + self.assertFalse( + pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension)) + self.assertFalse( + pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension)) + pb1.Extensions[more_extensions_dynamic_pb2.dynamic_int32_extension] = 17 + pb1.Extensions[more_extensions_dynamic_pb2.dynamic_message_extension].a = 24 + self.assertTrue( + pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension)) + self.assertTrue( + pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension)) + + # Now serialize the data and parse to a new message. + pb2 = more_extensions_pb2.ExtendedMessage() + pb2.MergeFromString(pb1.SerializeToString()) + + self.assertTrue( + pb2.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension)) + self.assertTrue( + pb2.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension)) + self.assertEqual( + 17, pb2.Extensions[more_extensions_dynamic_pb2.dynamic_int32_extension]) + self.assertEqual( + 24, + pb2.Extensions[more_extensions_dynamic_pb2.dynamic_message_extension].a) + + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/reflection_test.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/reflection_test.py new file mode 100755 index 0000000..ed28646 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/reflection_test.py @@ -0,0 +1,2671 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- +# +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unittest for reflection.py, which also indirectly tests the output of the +pure-Python protocol compiler. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + +import gc +import operator +import struct + +import unittest +from google.protobuf import unittest_import_pb2 +from google.protobuf import unittest_mset_pb2 +from google.protobuf import unittest_pb2 +from google.protobuf import descriptor_pb2 +from google.protobuf import descriptor +from google.protobuf import message +from google.protobuf import reflection +from google.protobuf.internal import api_implementation +from google.protobuf.internal import more_extensions_pb2 +from google.protobuf.internal import more_messages_pb2 +from google.protobuf.internal import wire_format +from google.protobuf.internal import test_util +from google.protobuf.internal import decoder + + +class _MiniDecoder(object): + """Decodes a stream of values from a string. + + Once upon a time we actually had a class called decoder.Decoder. Then we + got rid of it during a redesign that made decoding much, much faster overall. + But a couple tests in this file used it to check that the serialized form of + a message was correct. So, this class implements just the methods that were + used by said tests, so that we don't have to rewrite the tests. + """ + + def __init__(self, bytes): + self._bytes = bytes + self._pos = 0 + + def ReadVarint(self): + result, self._pos = decoder._DecodeVarint(self._bytes, self._pos) + return result + + ReadInt32 = ReadVarint + ReadInt64 = ReadVarint + ReadUInt32 = ReadVarint + ReadUInt64 = ReadVarint + + def ReadSInt64(self): + return wire_format.ZigZagDecode(self.ReadVarint()) + + ReadSInt32 = ReadSInt64 + + def ReadFieldNumberAndWireType(self): + return wire_format.UnpackTag(self.ReadVarint()) + + def ReadFloat(self): + result = struct.unpack("".', + text_format.Merge, text, message) + + text = 'RepeatedGroup: {' + self.assertRaisesWithMessage( + text_format.ParseError, '1:16 : Expected "}".', + text_format.Merge, text, message) + + def testMergeEmptyGroup(self): + message = unittest_pb2.TestAllTypes() + text = 'OptionalGroup: {}' + text_format.Merge(text, message) + self.assertTrue(message.HasField('optionalgroup')) + + message.Clear() + + message = unittest_pb2.TestAllTypes() + text = 'OptionalGroup: <>' + text_format.Merge(text, message) + self.assertTrue(message.HasField('optionalgroup')) + + def testMergeBadEnumValue(self): + message = unittest_pb2.TestAllTypes() + text = 'optional_nested_enum: BARR' + self.assertRaisesWithMessage( + text_format.ParseError, + ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" ' + 'has no value named BARR.'), + text_format.Merge, text, message) + + message = unittest_pb2.TestAllTypes() + text = 'optional_nested_enum: 100' + self.assertRaisesWithMessage( + text_format.ParseError, + ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" ' + 'has no value with number 100.'), + text_format.Merge, text, message) + + def testMergeBadIntValue(self): + message = unittest_pb2.TestAllTypes() + text = 'optional_int32: bork' + self.assertRaisesWithMessage( + text_format.ParseError, + ('1:17 : Couldn\'t parse integer: bork'), + text_format.Merge, text, message) + + def testMergeStringFieldUnescape(self): + message = unittest_pb2.TestAllTypes() + text = r'''repeated_string: "\xf\x62" + repeated_string: "\\xf\\x62" + repeated_string: "\\\xf\\\x62" + repeated_string: "\\\\xf\\\\x62" + repeated_string: "\\\\\xf\\\\\x62" + repeated_string: "\x5cx20"''' + text_format.Merge(text, message) + + SLASH = '\\' + self.assertEqual('\x0fb', message.repeated_string[0]) + self.assertEqual(SLASH + 'xf' + SLASH + 'x62', message.repeated_string[1]) + self.assertEqual(SLASH + '\x0f' + SLASH + 'b', message.repeated_string[2]) + self.assertEqual(SLASH + SLASH + 'xf' + SLASH + SLASH + 'x62', + message.repeated_string[3]) + self.assertEqual(SLASH + SLASH + '\x0f' + SLASH + SLASH + 'b', + message.repeated_string[4]) + self.assertEqual(SLASH + 'x20', message.repeated_string[5]) + + def assertRaisesWithMessage(self, e_class, e, func, *args, **kwargs): + """Same as assertRaises, but also compares the exception message.""" + if hasattr(e_class, '__name__'): + exc_name = e_class.__name__ + else: + exc_name = str(e_class) + + try: + func(*args, **kwargs) + except e_class as expr: + if str(expr) != e: + msg = '%s raised, but with wrong message: "%s" instead of "%s"' + raise self.failureException(msg % (exc_name, + str(expr).encode('string_escape'), + e.encode('string_escape'))) + return + else: + raise self.failureException('%s not raised' % exc_name) + + +class TokenizerTest(unittest.TestCase): + + def testSimpleTokenCases(self): + text = ('identifier1:"string1"\n \n\n' + 'identifier2 : \n \n123 \n identifier3 :\'string\'\n' + 'identifiER_4 : 1.1e+2 ID5:-0.23 ID6:\'aaaa\\\'bbbb\'\n' + 'ID7 : "aa\\"bb"\n\n\n\n ID8: {A:inf B:-inf C:true D:false}\n' + 'ID9: 22 ID10: -111111111111111111 ID11: -22\n' + 'ID12: 2222222222222222222 ID13: 1.23456f ID14: 1.2e+2f ' + 'false_bool: 0 true_BOOL:t \n true_bool1: 1 false_BOOL1:f ' ) + tokenizer = text_format._Tokenizer(text) + methods = [(tokenizer.ConsumeIdentifier, 'identifier1'), + ':', + (tokenizer.ConsumeString, 'string1'), + (tokenizer.ConsumeIdentifier, 'identifier2'), + ':', + (tokenizer.ConsumeInt32, 123), + (tokenizer.ConsumeIdentifier, 'identifier3'), + ':', + (tokenizer.ConsumeString, 'string'), + (tokenizer.ConsumeIdentifier, 'identifiER_4'), + ':', + (tokenizer.ConsumeFloat, 1.1e+2), + (tokenizer.ConsumeIdentifier, 'ID5'), + ':', + (tokenizer.ConsumeFloat, -0.23), + (tokenizer.ConsumeIdentifier, 'ID6'), + ':', + (tokenizer.ConsumeString, 'aaaa\'bbbb'), + (tokenizer.ConsumeIdentifier, 'ID7'), + ':', + (tokenizer.ConsumeString, 'aa\"bb'), + (tokenizer.ConsumeIdentifier, 'ID8'), + ':', + '{', + (tokenizer.ConsumeIdentifier, 'A'), + ':', + (tokenizer.ConsumeFloat, float('inf')), + (tokenizer.ConsumeIdentifier, 'B'), + ':', + (tokenizer.ConsumeFloat, -float('inf')), + (tokenizer.ConsumeIdentifier, 'C'), + ':', + (tokenizer.ConsumeBool, True), + (tokenizer.ConsumeIdentifier, 'D'), + ':', + (tokenizer.ConsumeBool, False), + '}', + (tokenizer.ConsumeIdentifier, 'ID9'), + ':', + (tokenizer.ConsumeUint32, 22), + (tokenizer.ConsumeIdentifier, 'ID10'), + ':', + (tokenizer.ConsumeInt64, -111111111111111111), + (tokenizer.ConsumeIdentifier, 'ID11'), + ':', + (tokenizer.ConsumeInt32, -22), + (tokenizer.ConsumeIdentifier, 'ID12'), + ':', + (tokenizer.ConsumeUint64, 2222222222222222222), + (tokenizer.ConsumeIdentifier, 'ID13'), + ':', + (tokenizer.ConsumeFloat, 1.23456), + (tokenizer.ConsumeIdentifier, 'ID14'), + ':', + (tokenizer.ConsumeFloat, 1.2e+2), + (tokenizer.ConsumeIdentifier, 'false_bool'), + ':', + (tokenizer.ConsumeBool, False), + (tokenizer.ConsumeIdentifier, 'true_BOOL'), + ':', + (tokenizer.ConsumeBool, True), + (tokenizer.ConsumeIdentifier, 'true_bool1'), + ':', + (tokenizer.ConsumeBool, True), + (tokenizer.ConsumeIdentifier, 'false_BOOL1'), + ':', + (tokenizer.ConsumeBool, False)] + + i = 0 + while not tokenizer.AtEnd(): + m = methods[i] + if type(m) == str: + token = tokenizer.token + self.assertEqual(token, m) + tokenizer.NextToken() + else: + self.assertEqual(m[1], m[0]()) + i += 1 + + def testConsumeIntegers(self): + # This test only tests the failures in the integer parsing methods as well + # as the '0' special cases. + int64_max = (1 << 63) - 1 + uint32_max = (1 << 32) - 1 + text = '-1 %d %d' % (uint32_max + 1, int64_max + 1) + tokenizer = text_format._Tokenizer(text) + self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32) + self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint64) + self.assertEqual(-1, tokenizer.ConsumeInt32()) + + self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32) + self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt32) + self.assertEqual(uint32_max + 1, tokenizer.ConsumeInt64()) + + self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt64) + self.assertEqual(int64_max + 1, tokenizer.ConsumeUint64()) + self.assertTrue(tokenizer.AtEnd()) + + text = '-0 -0 0 0' + tokenizer = text_format._Tokenizer(text) + self.assertEqual(0, tokenizer.ConsumeUint32()) + self.assertEqual(0, tokenizer.ConsumeUint64()) + self.assertEqual(0, tokenizer.ConsumeUint32()) + self.assertEqual(0, tokenizer.ConsumeUint64()) + self.assertTrue(tokenizer.AtEnd()) + + def testConsumeByteString(self): + text = '"string1\'' + tokenizer = text_format._Tokenizer(text) + self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) + + text = 'string1"' + tokenizer = text_format._Tokenizer(text) + self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) + + text = '\n"\\xt"' + tokenizer = text_format._Tokenizer(text) + self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) + + text = '\n"\\"' + tokenizer = text_format._Tokenizer(text) + self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) + + text = '\n"\\x"' + tokenizer = text_format._Tokenizer(text) + self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) + + def testConsumeBool(self): + text = 'not-a-bool' + tokenizer = text_format._Tokenizer(text) + self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool) + + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/type_checkers.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/type_checkers.py new file mode 100755 index 0000000..2b3cd4d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/type_checkers.py @@ -0,0 +1,286 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Provides type checking routines. + +This module defines type checking utilities in the forms of dictionaries: + +VALUE_CHECKERS: A dictionary of field types and a value validation object. +TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing + function. +TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization + function. +FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their + coresponding wire types. +TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization + function. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + +from google.protobuf.internal import decoder +from google.protobuf.internal import encoder +from google.protobuf.internal import wire_format +from google.protobuf import descriptor + +_FieldDescriptor = descriptor.FieldDescriptor + + +def GetTypeChecker(cpp_type, field_type): + """Returns a type checker for a message field of the specified types. + + Args: + cpp_type: C++ type of the field (see descriptor.py). + field_type: Protocol message field type (see descriptor.py). + + Returns: + An instance of TypeChecker which can be used to verify the types + of values assigned to a field of the specified type. + """ + if (cpp_type == _FieldDescriptor.CPPTYPE_STRING and + field_type == _FieldDescriptor.TYPE_STRING): + return UnicodeValueChecker() + return _VALUE_CHECKERS[cpp_type] + + +# None of the typecheckers below make any attempt to guard against people +# subclassing builtin types and doing weird things. We're not trying to +# protect against malicious clients here, just people accidentally shooting +# themselves in the foot in obvious ways. + +class TypeChecker(object): + + """Type checker used to catch type errors as early as possible + when the client is setting scalar fields in protocol messages. + """ + + def __init__(self, *acceptable_types): + self._acceptable_types = acceptable_types + + def CheckValue(self, proposed_value): + if not isinstance(proposed_value, self._acceptable_types): + message = ('%.1024r has type %s, but expected one of: %s' % + (proposed_value, type(proposed_value), self._acceptable_types)) + raise TypeError(message) + + +# IntValueChecker and its subclasses perform integer type-checks +# and bounds-checks. +class IntValueChecker(object): + + """Checker used for integer fields. Performs type-check and range check.""" + + def CheckValue(self, proposed_value): + if not isinstance(proposed_value, (int, long)): + message = ('%.1024r has type %s, but expected one of: %s' % + (proposed_value, type(proposed_value), (int, long))) + raise TypeError(message) + if not self._MIN <= proposed_value <= self._MAX: + raise ValueError('Value out of range: %d' % proposed_value) + + +class UnicodeValueChecker(object): + + """Checker used for string fields.""" + + def CheckValue(self, proposed_value): + if not isinstance(proposed_value, (str, unicode)): + message = ('%.1024r has type %s, but expected one of: %s' % + (proposed_value, type(proposed_value), (str, unicode))) + raise TypeError(message) + + # If the value is of type 'str' make sure that it is in 7-bit ASCII + # encoding. + if isinstance(proposed_value, str): + try: + unicode(proposed_value, 'ascii') + except UnicodeDecodeError: + raise ValueError('%.1024r has type str, but isn\'t in 7-bit ASCII ' + 'encoding. Non-ASCII strings must be converted to ' + 'unicode objects before being added.' % + (proposed_value)) + + +class Int32ValueChecker(IntValueChecker): + # We're sure to use ints instead of longs here since comparison may be more + # efficient. + _MIN = -2147483648 + _MAX = 2147483647 + + +class Uint32ValueChecker(IntValueChecker): + _MIN = 0 + _MAX = (1 << 32) - 1 + + +class Int64ValueChecker(IntValueChecker): + _MIN = -(1 << 63) + _MAX = (1 << 63) - 1 + + +class Uint64ValueChecker(IntValueChecker): + _MIN = 0 + _MAX = (1 << 64) - 1 + + +# Type-checkers for all scalar CPPTYPEs. +_VALUE_CHECKERS = { + _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(), + _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(), + _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(), + _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(), + _FieldDescriptor.CPPTYPE_DOUBLE: TypeChecker( + float, int, long), + _FieldDescriptor.CPPTYPE_FLOAT: TypeChecker( + float, int, long), + _FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int), + _FieldDescriptor.CPPTYPE_ENUM: Int32ValueChecker(), + _FieldDescriptor.CPPTYPE_STRING: TypeChecker(str), + } + + +# Map from field type to a function F, such that F(field_num, value) +# gives the total byte size for a value of the given type. This +# byte size includes tag information and any other additional space +# associated with serializing "value". +TYPE_TO_BYTE_SIZE_FN = { + _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize, + _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize, + _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize, + _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize, + _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize, + _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize, + _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize, + _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize, + _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize, + _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize, + _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize, + _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize, + _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize, + _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize, + _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize, + _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize, + _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize, + _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize + } + + +# Maps from field types to encoder constructors. +TYPE_TO_ENCODER = { + _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder, + _FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder, + _FieldDescriptor.TYPE_INT64: encoder.Int64Encoder, + _FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder, + _FieldDescriptor.TYPE_INT32: encoder.Int32Encoder, + _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder, + _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder, + _FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder, + _FieldDescriptor.TYPE_STRING: encoder.StringEncoder, + _FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder, + _FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder, + _FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder, + _FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder, + _FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder, + _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder, + _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder, + _FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder, + _FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder, + } + + +# Maps from field types to sizer constructors. +TYPE_TO_SIZER = { + _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer, + _FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer, + _FieldDescriptor.TYPE_INT64: encoder.Int64Sizer, + _FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer, + _FieldDescriptor.TYPE_INT32: encoder.Int32Sizer, + _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer, + _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer, + _FieldDescriptor.TYPE_BOOL: encoder.BoolSizer, + _FieldDescriptor.TYPE_STRING: encoder.StringSizer, + _FieldDescriptor.TYPE_GROUP: encoder.GroupSizer, + _FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer, + _FieldDescriptor.TYPE_BYTES: encoder.BytesSizer, + _FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer, + _FieldDescriptor.TYPE_ENUM: encoder.EnumSizer, + _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer, + _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer, + _FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer, + _FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer, + } + + +# Maps from field type to a decoder constructor. +TYPE_TO_DECODER = { + _FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder, + _FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder, + _FieldDescriptor.TYPE_INT64: decoder.Int64Decoder, + _FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder, + _FieldDescriptor.TYPE_INT32: decoder.Int32Decoder, + _FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder, + _FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder, + _FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder, + _FieldDescriptor.TYPE_STRING: decoder.StringDecoder, + _FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder, + _FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder, + _FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder, + _FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder, + _FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder, + _FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder, + _FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder, + _FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder, + _FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder, + } + +# Maps from field type to expected wiretype. +FIELD_TYPE_TO_WIRE_TYPE = { + _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64, + _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32, + _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64, + _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32, + _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_STRING: + wire_format.WIRETYPE_LENGTH_DELIMITED, + _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP, + _FieldDescriptor.TYPE_MESSAGE: + wire_format.WIRETYPE_LENGTH_DELIMITED, + _FieldDescriptor.TYPE_BYTES: + wire_format.WIRETYPE_LENGTH_DELIMITED, + _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32, + _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64, + _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT, + } diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/unknown_fields_test.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/unknown_fields_test.py new file mode 100755 index 0000000..84984b4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/unknown_fields_test.py @@ -0,0 +1,170 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- +# +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Test for preservation of unknown fields in the pure Python implementation.""" + +__author__ = 'bohdank@google.com (Bohdan Koval)' + +import unittest +from google.protobuf import unittest_mset_pb2 +from google.protobuf import unittest_pb2 +from google.protobuf.internal import encoder +from google.protobuf.internal import test_util +from google.protobuf.internal import type_checkers + + +class UnknownFieldsTest(unittest.TestCase): + + def setUp(self): + self.descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR + self.all_fields = unittest_pb2.TestAllTypes() + test_util.SetAllFields(self.all_fields) + self.all_fields_data = self.all_fields.SerializeToString() + self.empty_message = unittest_pb2.TestEmptyMessage() + self.empty_message.ParseFromString(self.all_fields_data) + self.unknown_fields = self.empty_message._unknown_fields + + def GetField(self, name): + field_descriptor = self.descriptor.fields_by_name[name] + wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type] + field_tag = encoder.TagBytes(field_descriptor.number, wire_type) + for tag_bytes, value in self.unknown_fields: + if tag_bytes == field_tag: + decoder = unittest_pb2.TestAllTypes._decoders_by_tag[tag_bytes] + result_dict = {} + decoder(value, 0, len(value), self.all_fields, result_dict) + return result_dict[field_descriptor] + + def testVarint(self): + value = self.GetField('optional_int32') + self.assertEqual(self.all_fields.optional_int32, value) + + def testFixed32(self): + value = self.GetField('optional_fixed32') + self.assertEqual(self.all_fields.optional_fixed32, value) + + def testFixed64(self): + value = self.GetField('optional_fixed64') + self.assertEqual(self.all_fields.optional_fixed64, value) + + def testLengthDelimited(self): + value = self.GetField('optional_string') + self.assertEqual(self.all_fields.optional_string, value) + + def testGroup(self): + value = self.GetField('optionalgroup') + self.assertEqual(self.all_fields.optionalgroup, value) + + def testSerialize(self): + data = self.empty_message.SerializeToString() + + # Don't use assertEqual because we don't want to dump raw binary data to + # stdout. + self.assertTrue(data == self.all_fields_data) + + def testCopyFrom(self): + message = unittest_pb2.TestEmptyMessage() + message.CopyFrom(self.empty_message) + self.assertEqual(self.unknown_fields, message._unknown_fields) + + def testMergeFrom(self): + message = unittest_pb2.TestAllTypes() + message.optional_int32 = 1 + message.optional_uint32 = 2 + source = unittest_pb2.TestEmptyMessage() + source.ParseFromString(message.SerializeToString()) + + message.ClearField('optional_int32') + message.optional_int64 = 3 + message.optional_uint32 = 4 + destination = unittest_pb2.TestEmptyMessage() + destination.ParseFromString(message.SerializeToString()) + unknown_fields = destination._unknown_fields[:] + + destination.MergeFrom(source) + self.assertEqual(unknown_fields + source._unknown_fields, + destination._unknown_fields) + + def testClear(self): + self.empty_message.Clear() + self.assertEqual(0, len(self.empty_message._unknown_fields)) + + def testByteSize(self): + self.assertEqual(self.all_fields.ByteSize(), self.empty_message.ByteSize()) + + def testUnknownExtensions(self): + message = unittest_pb2.TestEmptyMessageWithExtensions() + message.ParseFromString(self.all_fields_data) + self.assertEqual(self.empty_message._unknown_fields, + message._unknown_fields) + + def testListFields(self): + # Make sure ListFields doesn't return unknown fields. + self.assertEqual(0, len(self.empty_message.ListFields())) + + def testSerializeMessageSetWireFormatUnknownExtension(self): + # Create a message using the message set wire format with an unknown + # message. + raw = unittest_mset_pb2.RawMessageSet() + + # Add an unknown extension. + item = raw.item.add() + item.type_id = 1545009 + message1 = unittest_mset_pb2.TestMessageSetExtension1() + message1.i = 12345 + item.message = message1.SerializeToString() + + serialized = raw.SerializeToString() + + # Parse message using the message set wire format. + proto = unittest_mset_pb2.TestMessageSet() + proto.MergeFromString(serialized) + + # Verify that the unknown extension is serialized unchanged + reserialized = proto.SerializeToString() + new_raw = unittest_mset_pb2.RawMessageSet() + new_raw.MergeFromString(reserialized) + self.assertEqual(raw, new_raw) + + def testEquals(self): + message = unittest_pb2.TestEmptyMessage() + message.ParseFromString(self.all_fields_data) + self.assertEqual(self.empty_message, message) + + self.all_fields.ClearField('optional_string') + message.ParseFromString(self.all_fields.SerializeToString()) + self.assertNotEqual(self.empty_message, message) + + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/wire_format.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/wire_format.py new file mode 100755 index 0000000..c941fe1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/wire_format.py @@ -0,0 +1,268 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Constants and static functions to support protocol buffer wire format.""" + +__author__ = 'robinson@google.com (Will Robinson)' + +import struct +from google.protobuf import descriptor +from google.protobuf import message + + +TAG_TYPE_BITS = 3 # Number of bits used to hold type info in a proto tag. +TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7 + +# These numbers identify the wire type of a protocol buffer value. +# We use the least-significant TAG_TYPE_BITS bits of the varint-encoded +# tag-and-type to store one of these WIRETYPE_* constants. +# These values must match WireType enum in google/protobuf/wire_format.h. +WIRETYPE_VARINT = 0 +WIRETYPE_FIXED64 = 1 +WIRETYPE_LENGTH_DELIMITED = 2 +WIRETYPE_START_GROUP = 3 +WIRETYPE_END_GROUP = 4 +WIRETYPE_FIXED32 = 5 +_WIRETYPE_MAX = 5 + + +# Bounds for various integer types. +INT32_MAX = int((1 << 31) - 1) +INT32_MIN = int(-(1 << 31)) +UINT32_MAX = (1 << 32) - 1 + +INT64_MAX = (1 << 63) - 1 +INT64_MIN = -(1 << 63) +UINT64_MAX = (1 << 64) - 1 + +# "struct" format strings that will encode/decode the specified formats. +FORMAT_UINT32_LITTLE_ENDIAN = '> TAG_TYPE_BITS), (tag & TAG_TYPE_MASK) + + +def ZigZagEncode(value): + """ZigZag Transform: Encodes signed integers so that they can be + effectively used with varint encoding. See wire_format.h for + more details. + """ + if value >= 0: + return value << 1 + return (value << 1) ^ (~0) + + +def ZigZagDecode(value): + """Inverse of ZigZagEncode().""" + if not value & 0x1: + return value >> 1 + return (value >> 1) ^ (~0) + + + +# The *ByteSize() functions below return the number of bytes required to +# serialize "field number + type" information and then serialize the value. + + +def Int32ByteSize(field_number, int32): + return Int64ByteSize(field_number, int32) + + +def Int32ByteSizeNoTag(int32): + return _VarUInt64ByteSizeNoTag(0xffffffffffffffff & int32) + + +def Int64ByteSize(field_number, int64): + # Have to convert to uint before calling UInt64ByteSize(). + return UInt64ByteSize(field_number, 0xffffffffffffffff & int64) + + +def UInt32ByteSize(field_number, uint32): + return UInt64ByteSize(field_number, uint32) + + +def UInt64ByteSize(field_number, uint64): + return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64) + + +def SInt32ByteSize(field_number, int32): + return UInt32ByteSize(field_number, ZigZagEncode(int32)) + + +def SInt64ByteSize(field_number, int64): + return UInt64ByteSize(field_number, ZigZagEncode(int64)) + + +def Fixed32ByteSize(field_number, fixed32): + return TagByteSize(field_number) + 4 + + +def Fixed64ByteSize(field_number, fixed64): + return TagByteSize(field_number) + 8 + + +def SFixed32ByteSize(field_number, sfixed32): + return TagByteSize(field_number) + 4 + + +def SFixed64ByteSize(field_number, sfixed64): + return TagByteSize(field_number) + 8 + + +def FloatByteSize(field_number, flt): + return TagByteSize(field_number) + 4 + + +def DoubleByteSize(field_number, double): + return TagByteSize(field_number) + 8 + + +def BoolByteSize(field_number, b): + return TagByteSize(field_number) + 1 + + +def EnumByteSize(field_number, enum): + return UInt32ByteSize(field_number, enum) + + +def StringByteSize(field_number, string): + return BytesByteSize(field_number, string.encode('utf-8')) + + +def BytesByteSize(field_number, b): + return (TagByteSize(field_number) + + _VarUInt64ByteSizeNoTag(len(b)) + + len(b)) + + +def GroupByteSize(field_number, message): + return (2 * TagByteSize(field_number) # START and END group. + + message.ByteSize()) + + +def MessageByteSize(field_number, message): + return (TagByteSize(field_number) + + _VarUInt64ByteSizeNoTag(message.ByteSize()) + + message.ByteSize()) + + +def MessageSetItemByteSize(field_number, msg): + # First compute the sizes of the tags. + # There are 2 tags for the beginning and ending of the repeated group, that + # is field number 1, one with field number 2 (type_id) and one with field + # number 3 (message). + total_size = (2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3)) + + # Add the number of bytes for type_id. + total_size += _VarUInt64ByteSizeNoTag(field_number) + + message_size = msg.ByteSize() + + # The number of bytes for encoding the length of the message. + total_size += _VarUInt64ByteSizeNoTag(message_size) + + # The size of the message. + total_size += message_size + return total_size + + +def TagByteSize(field_number): + """Returns the bytes required to serialize a tag with this field number.""" + # Just pass in type 0, since the type won't affect the tag+type size. + return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0)) + + +# Private helper function for the *ByteSize() functions above. + +def _VarUInt64ByteSizeNoTag(uint64): + """Returns the number of bytes required to serialize a single varint + using boundary value comparisons. (unrolled loop optimization -WPierce) + uint64 must be unsigned. + """ + if uint64 <= 0x7f: return 1 + if uint64 <= 0x3fff: return 2 + if uint64 <= 0x1fffff: return 3 + if uint64 <= 0xfffffff: return 4 + if uint64 <= 0x7ffffffff: return 5 + if uint64 <= 0x3ffffffffff: return 6 + if uint64 <= 0x1ffffffffffff: return 7 + if uint64 <= 0xffffffffffffff: return 8 + if uint64 <= 0x7fffffffffffffff: return 9 + if uint64 > UINT64_MAX: + raise message.EncodeError('Value out of range: %d' % uint64) + return 10 + + +NON_PACKABLE_TYPES = ( + descriptor.FieldDescriptor.TYPE_STRING, + descriptor.FieldDescriptor.TYPE_GROUP, + descriptor.FieldDescriptor.TYPE_MESSAGE, + descriptor.FieldDescriptor.TYPE_BYTES +) + + +def IsTypePackable(field_type): + """Return true iff packable = true is valid for fields of this type. + + Args: + field_type: a FieldDescriptor::Type value. + + Returns: + True iff fields of this type are packable. + """ + return field_type not in NON_PACKABLE_TYPES diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/wire_format_test.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/wire_format_test.py new file mode 100755 index 0000000..7600778 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/internal/wire_format_test.py @@ -0,0 +1,253 @@ +#! /usr/bin/python +# +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Test for google.protobuf.internal.wire_format.""" + +__author__ = 'robinson@google.com (Will Robinson)' + +import unittest +from google.protobuf import message +from google.protobuf.internal import wire_format + + +class WireFormatTest(unittest.TestCase): + + def testPackTag(self): + field_number = 0xabc + tag_type = 2 + self.assertEqual((field_number << 3) | tag_type, + wire_format.PackTag(field_number, tag_type)) + PackTag = wire_format.PackTag + # Number too high. + self.assertRaises(message.EncodeError, PackTag, field_number, 6) + # Number too low. + self.assertRaises(message.EncodeError, PackTag, field_number, -1) + + def testUnpackTag(self): + # Test field numbers that will require various varint sizes. + for expected_field_number in (1, 15, 16, 2047, 2048): + for expected_wire_type in range(6): # Highest-numbered wiretype is 5. + field_number, wire_type = wire_format.UnpackTag( + wire_format.PackTag(expected_field_number, expected_wire_type)) + self.assertEqual(expected_field_number, field_number) + self.assertEqual(expected_wire_type, wire_type) + + self.assertRaises(TypeError, wire_format.UnpackTag, None) + self.assertRaises(TypeError, wire_format.UnpackTag, 'abc') + self.assertRaises(TypeError, wire_format.UnpackTag, 0.0) + self.assertRaises(TypeError, wire_format.UnpackTag, object()) + + def testZigZagEncode(self): + Z = wire_format.ZigZagEncode + self.assertEqual(0, Z(0)) + self.assertEqual(1, Z(-1)) + self.assertEqual(2, Z(1)) + self.assertEqual(3, Z(-2)) + self.assertEqual(4, Z(2)) + self.assertEqual(0xfffffffe, Z(0x7fffffff)) + self.assertEqual(0xffffffff, Z(-0x80000000)) + self.assertEqual(0xfffffffffffffffe, Z(0x7fffffffffffffff)) + self.assertEqual(0xffffffffffffffff, Z(-0x8000000000000000)) + + self.assertRaises(TypeError, Z, None) + self.assertRaises(TypeError, Z, 'abcd') + self.assertRaises(TypeError, Z, 0.0) + self.assertRaises(TypeError, Z, object()) + + def testZigZagDecode(self): + Z = wire_format.ZigZagDecode + self.assertEqual(0, Z(0)) + self.assertEqual(-1, Z(1)) + self.assertEqual(1, Z(2)) + self.assertEqual(-2, Z(3)) + self.assertEqual(2, Z(4)) + self.assertEqual(0x7fffffff, Z(0xfffffffe)) + self.assertEqual(-0x80000000, Z(0xffffffff)) + self.assertEqual(0x7fffffffffffffff, Z(0xfffffffffffffffe)) + self.assertEqual(-0x8000000000000000, Z(0xffffffffffffffff)) + + self.assertRaises(TypeError, Z, None) + self.assertRaises(TypeError, Z, 'abcd') + self.assertRaises(TypeError, Z, 0.0) + self.assertRaises(TypeError, Z, object()) + + def NumericByteSizeTestHelper(self, byte_size_fn, value, expected_value_size): + # Use field numbers that cause various byte sizes for the tag information. + for field_number, tag_bytes in ((15, 1), (16, 2), (2047, 2), (2048, 3)): + expected_size = expected_value_size + tag_bytes + actual_size = byte_size_fn(field_number, value) + self.assertEqual(expected_size, actual_size, + 'byte_size_fn: %s, field_number: %d, value: %r\n' + 'Expected: %d, Actual: %d'% ( + byte_size_fn, field_number, value, expected_size, actual_size)) + + def testByteSizeFunctions(self): + # Test all numeric *ByteSize() functions. + NUMERIC_ARGS = [ + # Int32ByteSize(). + [wire_format.Int32ByteSize, 0, 1], + [wire_format.Int32ByteSize, 127, 1], + [wire_format.Int32ByteSize, 128, 2], + [wire_format.Int32ByteSize, -1, 10], + # Int64ByteSize(). + [wire_format.Int64ByteSize, 0, 1], + [wire_format.Int64ByteSize, 127, 1], + [wire_format.Int64ByteSize, 128, 2], + [wire_format.Int64ByteSize, -1, 10], + # UInt32ByteSize(). + [wire_format.UInt32ByteSize, 0, 1], + [wire_format.UInt32ByteSize, 127, 1], + [wire_format.UInt32ByteSize, 128, 2], + [wire_format.UInt32ByteSize, wire_format.UINT32_MAX, 5], + # UInt64ByteSize(). + [wire_format.UInt64ByteSize, 0, 1], + [wire_format.UInt64ByteSize, 127, 1], + [wire_format.UInt64ByteSize, 128, 2], + [wire_format.UInt64ByteSize, wire_format.UINT64_MAX, 10], + # SInt32ByteSize(). + [wire_format.SInt32ByteSize, 0, 1], + [wire_format.SInt32ByteSize, -1, 1], + [wire_format.SInt32ByteSize, 1, 1], + [wire_format.SInt32ByteSize, -63, 1], + [wire_format.SInt32ByteSize, 63, 1], + [wire_format.SInt32ByteSize, -64, 1], + [wire_format.SInt32ByteSize, 64, 2], + # SInt64ByteSize(). + [wire_format.SInt64ByteSize, 0, 1], + [wire_format.SInt64ByteSize, -1, 1], + [wire_format.SInt64ByteSize, 1, 1], + [wire_format.SInt64ByteSize, -63, 1], + [wire_format.SInt64ByteSize, 63, 1], + [wire_format.SInt64ByteSize, -64, 1], + [wire_format.SInt64ByteSize, 64, 2], + # Fixed32ByteSize(). + [wire_format.Fixed32ByteSize, 0, 4], + [wire_format.Fixed32ByteSize, wire_format.UINT32_MAX, 4], + # Fixed64ByteSize(). + [wire_format.Fixed64ByteSize, 0, 8], + [wire_format.Fixed64ByteSize, wire_format.UINT64_MAX, 8], + # SFixed32ByteSize(). + [wire_format.SFixed32ByteSize, 0, 4], + [wire_format.SFixed32ByteSize, wire_format.INT32_MIN, 4], + [wire_format.SFixed32ByteSize, wire_format.INT32_MAX, 4], + # SFixed64ByteSize(). + [wire_format.SFixed64ByteSize, 0, 8], + [wire_format.SFixed64ByteSize, wire_format.INT64_MIN, 8], + [wire_format.SFixed64ByteSize, wire_format.INT64_MAX, 8], + # FloatByteSize(). + [wire_format.FloatByteSize, 0.0, 4], + [wire_format.FloatByteSize, 1000000000.0, 4], + [wire_format.FloatByteSize, -1000000000.0, 4], + # DoubleByteSize(). + [wire_format.DoubleByteSize, 0.0, 8], + [wire_format.DoubleByteSize, 1000000000.0, 8], + [wire_format.DoubleByteSize, -1000000000.0, 8], + # BoolByteSize(). + [wire_format.BoolByteSize, False, 1], + [wire_format.BoolByteSize, True, 1], + # EnumByteSize(). + [wire_format.EnumByteSize, 0, 1], + [wire_format.EnumByteSize, 127, 1], + [wire_format.EnumByteSize, 128, 2], + [wire_format.EnumByteSize, wire_format.UINT32_MAX, 5], + ] + for args in NUMERIC_ARGS: + self.NumericByteSizeTestHelper(*args) + + # Test strings and bytes. + for byte_size_fn in (wire_format.StringByteSize, wire_format.BytesByteSize): + # 1 byte for tag, 1 byte for length, 3 bytes for contents. + self.assertEqual(5, byte_size_fn(10, 'abc')) + # 2 bytes for tag, 1 byte for length, 3 bytes for contents. + self.assertEqual(6, byte_size_fn(16, 'abc')) + # 2 bytes for tag, 2 bytes for length, 128 bytes for contents. + self.assertEqual(132, byte_size_fn(16, 'a' * 128)) + + # Test UTF-8 string byte size calculation. + # 1 byte for tag, 1 byte for length, 8 bytes for content. + self.assertEqual(10, wire_format.StringByteSize( + 5, unicode('\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82', 'utf-8'))) + + class MockMessage(object): + def __init__(self, byte_size): + self.byte_size = byte_size + def ByteSize(self): + return self.byte_size + + message_byte_size = 10 + mock_message = MockMessage(byte_size=message_byte_size) + # Test groups. + # (2 * 1) bytes for begin and end tags, plus message_byte_size. + self.assertEqual(2 + message_byte_size, + wire_format.GroupByteSize(1, mock_message)) + # (2 * 2) bytes for begin and end tags, plus message_byte_size. + self.assertEqual(4 + message_byte_size, + wire_format.GroupByteSize(16, mock_message)) + + # Test messages. + # 1 byte for tag, plus 1 byte for length, plus contents. + self.assertEqual(2 + mock_message.byte_size, + wire_format.MessageByteSize(1, mock_message)) + # 2 bytes for tag, plus 1 byte for length, plus contents. + self.assertEqual(3 + mock_message.byte_size, + wire_format.MessageByteSize(16, mock_message)) + # 2 bytes for tag, plus 2 bytes for length, plus contents. + mock_message.byte_size = 128 + self.assertEqual(4 + mock_message.byte_size, + wire_format.MessageByteSize(16, mock_message)) + + + # Test message set item byte size. + # 4 bytes for tags, plus 1 byte for length, plus 1 byte for type_id, + # plus contents. + mock_message.byte_size = 10 + self.assertEqual(mock_message.byte_size + 6, + wire_format.MessageSetItemByteSize(1, mock_message)) + + # 4 bytes for tags, plus 2 bytes for length, plus 1 byte for type_id, + # plus contents. + mock_message.byte_size = 128 + self.assertEqual(mock_message.byte_size + 7, + wire_format.MessageSetItemByteSize(1, mock_message)) + + # 4 bytes for tags, plus 2 bytes for length, plus 2 byte for type_id, + # plus contents. + self.assertEqual(mock_message.byte_size + 8, + wire_format.MessageSetItemByteSize(128, mock_message)) + + # Too-long varint. + self.assertRaises(message.EncodeError, + wire_format.UInt64ByteSize, 1, 1 << 128) + + +if __name__ == '__main__': + unittest.main() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/message.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/message.py new file mode 100755 index 0000000..6ec2f8b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/message.py @@ -0,0 +1,280 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# TODO(robinson): We should just make these methods all "pure-virtual" and move +# all implementation out, into reflection.py for now. + + +"""Contains an abstract base class for protocol messages.""" + +__author__ = 'robinson@google.com (Will Robinson)' + + +class Error(Exception): pass +class DecodeError(Error): pass +class EncodeError(Error): pass + + +class Message(object): + + """Abstract base class for protocol messages. + + Protocol message classes are almost always generated by the protocol + compiler. These generated types subclass Message and implement the methods + shown below. + + TODO(robinson): Link to an HTML document here. + + TODO(robinson): Document that instances of this class will also + have an Extensions attribute with __getitem__ and __setitem__. + Again, not sure how to best convey this. + + TODO(robinson): Document that the class must also have a static + RegisterExtension(extension_field) method. + Not sure how to best express at this point. + """ + + # TODO(robinson): Document these fields and methods. + + __slots__ = [] + + DESCRIPTOR = None + + def __deepcopy__(self, memo=None): + clone = type(self)() + clone.MergeFrom(self) + return clone + + def __eq__(self, other_msg): + """Recursively compares two messages by value and structure.""" + raise NotImplementedError + + def __ne__(self, other_msg): + # Can't just say self != other_msg, since that would infinitely recurse. :) + return not self == other_msg + + def __hash__(self): + raise TypeError('unhashable object') + + def __str__(self): + """Outputs a human-readable representation of the message.""" + raise NotImplementedError + + def __unicode__(self): + """Outputs a human-readable representation of the message.""" + raise NotImplementedError + + def MergeFrom(self, other_msg): + """Merges the contents of the specified message into current message. + + This method merges the contents of the specified message into the current + message. Singular fields that are set in the specified message overwrite + the corresponding fields in the current message. Repeated fields are + appended. Singular sub-messages and groups are recursively merged. + + Args: + other_msg: Message to merge into the current message. + """ + raise NotImplementedError + + def CopyFrom(self, other_msg): + """Copies the content of the specified message into the current message. + + The method clears the current message and then merges the specified + message using MergeFrom. + + Args: + other_msg: Message to copy into the current one. + """ + if self is other_msg: + return + self.Clear() + self.MergeFrom(other_msg) + + def Clear(self): + """Clears all data that was set in the message.""" + raise NotImplementedError + + def SetInParent(self): + """Mark this as present in the parent. + + This normally happens automatically when you assign a field of a + sub-message, but sometimes you want to make the sub-message + present while keeping it empty. If you find yourself using this, + you may want to reconsider your design.""" + raise NotImplementedError + + def IsInitialized(self): + """Checks if the message is initialized. + + Returns: + The method returns True if the message is initialized (i.e. all of its + required fields are set). + """ + raise NotImplementedError + + # TODO(robinson): MergeFromString() should probably return None and be + # implemented in terms of a helper that returns the # of bytes read. Our + # deserialization routines would use the helper when recursively + # deserializing, but the end user would almost always just want the no-return + # MergeFromString(). + + def MergeFromString(self, serialized): + """Merges serialized protocol buffer data into this message. + + When we find a field in |serialized| that is already present + in this message: + - If it's a "repeated" field, we append to the end of our list. + - Else, if it's a scalar, we overwrite our field. + - Else, (it's a nonrepeated composite), we recursively merge + into the existing composite. + + TODO(robinson): Document handling of unknown fields. + + Args: + serialized: Any object that allows us to call buffer(serialized) + to access a string of bytes using the buffer interface. + + TODO(robinson): When we switch to a helper, this will return None. + + Returns: + The number of bytes read from |serialized|. + For non-group messages, this will always be len(serialized), + but for messages which are actually groups, this will + generally be less than len(serialized), since we must + stop when we reach an END_GROUP tag. Note that if + we *do* stop because of an END_GROUP tag, the number + of bytes returned does not include the bytes + for the END_GROUP tag information. + """ + raise NotImplementedError + + def ParseFromString(self, serialized): + """Like MergeFromString(), except we clear the object first.""" + self.Clear() + self.MergeFromString(serialized) + + def SerializeToString(self): + """Serializes the protocol message to a binary string. + + Returns: + A binary string representation of the message if all of the required + fields in the message are set (i.e. the message is initialized). + + Raises: + message.EncodeError if the message isn't initialized. + """ + raise NotImplementedError + + def SerializePartialToString(self): + """Serializes the protocol message to a binary string. + + This method is similar to SerializeToString but doesn't check if the + message is initialized. + + Returns: + A string representation of the partial message. + """ + raise NotImplementedError + + # TODO(robinson): Decide whether we like these better + # than auto-generated has_foo() and clear_foo() methods + # on the instances themselves. This way is less consistent + # with C++, but it makes reflection-type access easier and + # reduces the number of magically autogenerated things. + # + # TODO(robinson): Be sure to document (and test) exactly + # which field names are accepted here. Are we case-sensitive? + # What do we do with fields that share names with Python keywords + # like 'lambda' and 'yield'? + # + # nnorwitz says: + # """ + # Typically (in python), an underscore is appended to names that are + # keywords. So they would become lambda_ or yield_. + # """ + def ListFields(self): + """Returns a list of (FieldDescriptor, value) tuples for all + fields in the message which are not empty. A singular field is non-empty + if HasField() would return true, and a repeated field is non-empty if + it contains at least one element. The fields are ordered by field + number""" + raise NotImplementedError + + def HasField(self, field_name): + """Checks if a certain field is set for the message. Note if the + field_name is not defined in the message descriptor, ValueError will be + raised.""" + raise NotImplementedError + + def ClearField(self, field_name): + raise NotImplementedError + + def HasExtension(self, extension_handle): + raise NotImplementedError + + def ClearExtension(self, extension_handle): + raise NotImplementedError + + def ByteSize(self): + """Returns the serialized size of this message. + Recursively calls ByteSize() on all contained messages. + """ + raise NotImplementedError + + def _SetListener(self, message_listener): + """Internal method used by the protocol message implementation. + Clients should not call this directly. + + Sets a listener that this message will call on certain state transitions. + + The purpose of this method is to register back-edges from children to + parents at runtime, for the purpose of setting "has" bits and + byte-size-dirty bits in the parent and ancestor objects whenever a child or + descendant object is modified. + + If the client wants to disconnect this Message from the object tree, she + explicitly sets callback to None. + + If message_listener is None, unregisters any existing listener. Otherwise, + message_listener must implement the MessageListener interface in + internal/message_listener.py, and we discard any listener registered + via a previous _SetListener() call. + """ + raise NotImplementedError + + def __getstate__(self): + """Support the pickle protocol.""" + return dict(serialized=self.SerializePartialToString()) + + def __setstate__(self, state): + """Support the pickle protocol.""" + self.__init__() + self.ParseFromString(state['serialized']) diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/message_factory.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/message_factory.py new file mode 100644 index 0000000..36e2fef --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/message_factory.py @@ -0,0 +1,113 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Provides a factory class for generating dynamic messages.""" + +__author__ = 'matthewtoia@google.com (Matt Toia)' + +from google.protobuf import descriptor_database +from google.protobuf import descriptor_pool +from google.protobuf import message +from google.protobuf import reflection + + +class MessageFactory(object): + """Factory for creating Proto2 messages from descriptors in a pool.""" + + def __init__(self): + """Initializes a new factory.""" + self._classes = {} + + def GetPrototype(self, descriptor): + """Builds a proto2 message class based on the passed in descriptor. + + Passing a descriptor with a fully qualified name matching a previous + invocation will cause the same class to be returned. + + Args: + descriptor: The descriptor to build from. + + Returns: + A class describing the passed in descriptor. + """ + + if descriptor.full_name not in self._classes: + result_class = reflection.GeneratedProtocolMessageType( + descriptor.name.encode('ascii', 'ignore'), + (message.Message,), + {'DESCRIPTOR': descriptor}) + self._classes[descriptor.full_name] = result_class + for field in descriptor.fields: + if field.message_type: + self.GetPrototype(field.message_type) + return self._classes[descriptor.full_name] + + +_DB = descriptor_database.DescriptorDatabase() +_POOL = descriptor_pool.DescriptorPool(_DB) +_FACTORY = MessageFactory() + + +def GetMessages(file_protos): + """Builds a dictionary of all the messages available in a set of files. + + Args: + file_protos: A sequence of file protos to build messages out of. + + Returns: + A dictionary containing all the message types in the files mapping the + fully qualified name to a Message subclass for the descriptor. + """ + + result = {} + for file_proto in file_protos: + _DB.Add(file_proto) + for file_proto in file_protos: + for desc in _GetAllDescriptors(file_proto.message_type, file_proto.package): + result[desc.full_name] = _FACTORY.GetPrototype(desc) + return result + + +def _GetAllDescriptors(desc_protos, package): + """Gets all levels of nested message types as a flattened list of descriptors. + + Args: + desc_protos: The descriptor protos to process. + package: The package where the protos are defined. + + Yields: + Each message descriptor for each nested type. + """ + + for desc_proto in desc_protos: + name = '.'.join((package, desc_proto.name)) + yield _POOL.FindMessageTypeByName(name) + for nested_desc in _GetAllDescriptors(desc_proto.nested_type, name): + yield nested_desc diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python-proto2.cc b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python-proto2.cc new file mode 100644 index 0000000..eebb752 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python-proto2.cc @@ -0,0 +1,1717 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: petar@google.com (Petar Petrov) + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Is 64bit */ +#define IS_64BIT (SIZEOF_LONG == 8) + +#define FIELD_BELONGS_TO_MESSAGE(field_descriptor, message) \ + ((message)->GetDescriptor() == (field_descriptor)->containing_type()) + +#define FIELD_IS_REPEATED(field_descriptor) \ + ((field_descriptor)->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) + +#define GOOGLE_CHECK_GET_INT32(arg, value) \ + int32 value; \ + if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \ + return NULL; \ + } + +#define GOOGLE_CHECK_GET_INT64(arg, value) \ + int64 value; \ + if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \ + return NULL; \ + } + +#define GOOGLE_CHECK_GET_UINT32(arg, value) \ + uint32 value; \ + if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \ + return NULL; \ + } + +#define GOOGLE_CHECK_GET_UINT64(arg, value) \ + uint64 value; \ + if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \ + return NULL; \ + } + +#define GOOGLE_CHECK_GET_FLOAT(arg, value) \ + float value; \ + if (!CheckAndGetFloat(arg, &value)) { \ + return NULL; \ + } \ + +#define GOOGLE_CHECK_GET_DOUBLE(arg, value) \ + double value; \ + if (!CheckAndGetDouble(arg, &value)) { \ + return NULL; \ + } + +#define GOOGLE_CHECK_GET_BOOL(arg, value) \ + bool value; \ + if (!CheckAndGetBool(arg, &value)) { \ + return NULL; \ + } + +#define C(str) const_cast(str) + +// --- Globals: + +// Constants used for integer type range checking. +static PyObject* kPythonZero; +static PyObject* kint32min_py; +static PyObject* kint32max_py; +static PyObject* kuint32max_py; +static PyObject* kint64min_py; +static PyObject* kint64max_py; +static PyObject* kuint64max_py; + +namespace google { +namespace protobuf { +namespace python { + +// --- Support Routines: + +static void AddConstants(PyObject* module) { + struct NameValue { + char* name; + int32 value; + } constants[] = { + // Labels: + {"LABEL_OPTIONAL", google::protobuf::FieldDescriptor::LABEL_OPTIONAL}, + {"LABEL_REQUIRED", google::protobuf::FieldDescriptor::LABEL_REQUIRED}, + {"LABEL_REPEATED", google::protobuf::FieldDescriptor::LABEL_REPEATED}, + // CPP types: + {"CPPTYPE_MESSAGE", google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE}, + // Field Types: + {"TYPE_MESSAGE", google::protobuf::FieldDescriptor::TYPE_MESSAGE}, + // End. + {NULL, 0} + }; + + for (NameValue* constant = constants; + constant->name != NULL; constant++) { + PyModule_AddIntConstant(module, constant->name, constant->value); + } +} + +// --- CMessage Custom Type: + +// ------ Type Forward Declaration: + +struct CMessage; +struct CMessage_Type; + +static void CMessageDealloc(CMessage* self); +static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds); +static PyObject* CMessageStr(CMessage* self); + +static PyObject* CMessage_AddMessage(CMessage* self, PyObject* args); +static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args); +static PyObject* CMessage_AssignRepeatedScalar(CMessage* self, PyObject* args); +static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args); +static PyObject* CMessage_Clear(CMessage* self, PyObject* args); +static PyObject* CMessage_ClearField(CMessage* self, PyObject* args); +static PyObject* CMessage_ClearFieldByDescriptor( + CMessage* self, PyObject* args); +static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* args); +static PyObject* CMessage_DebugString(CMessage* self, PyObject* args); +static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args); +static PyObject* CMessage_Equals(CMessage* self, PyObject* args); +static PyObject* CMessage_FieldLength(CMessage* self, PyObject* args); +static PyObject* CMessage_FindInitializationErrors(CMessage* self); +static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args); +static PyObject* CMessage_GetRepeatedScalar(CMessage* self, PyObject* args); +static PyObject* CMessage_GetScalar(CMessage* self, PyObject* args); +static PyObject* CMessage_HasField(CMessage* self, PyObject* args); +static PyObject* CMessage_HasFieldByDescriptor(CMessage* self, PyObject* args); +static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args); +static PyObject* CMessage_ListFields(CMessage* self, PyObject* args); +static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* args); +static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* args); +static PyObject* CMessage_MutableMessage(CMessage* self, PyObject* args); +static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* args); +static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args); +static PyObject* CMessage_SerializePartialToString( + CMessage* self, PyObject* args); +static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args); +static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args); +static PyObject* CMessage_SwapRepeatedFieldElements( + CMessage* self, PyObject* args); + +// ------ Object Definition: + +typedef struct CMessage { + PyObject_HEAD + + struct CMessage* parent; // NULL if wasn't created from another message. + CFieldDescriptor* parent_field; + const char* full_name; + google::protobuf::Message* message; + bool free_message; + bool read_only; +} CMessage; + +// ------ Method Table: + +#define CMETHOD(name, args, doc) \ + { C(#name), (PyCFunction)CMessage_##name, args, C(doc) } +static PyMethodDef CMessageMethods[] = { + CMETHOD(AddMessage, METH_O, + "Adds a new message to a repeated composite field."), + CMETHOD(AddRepeatedScalar, METH_VARARGS, + "Adds a scalar to a repeated scalar field."), + CMETHOD(AssignRepeatedScalar, METH_VARARGS, + "Clears and sets the values of a repeated scalar field."), + CMETHOD(ByteSize, METH_NOARGS, + "Returns the size of the message in bytes."), + CMETHOD(Clear, METH_O, + "Clears a protocol message."), + CMETHOD(ClearField, METH_VARARGS, + "Clears a protocol message field by name."), + CMETHOD(ClearFieldByDescriptor, METH_O, + "Clears a protocol message field by descriptor."), + CMETHOD(CopyFrom, METH_O, + "Copies a protocol message into the current message."), + CMETHOD(DebugString, METH_NOARGS, + "Returns the debug string of a protocol message."), + CMETHOD(DeleteRepeatedField, METH_VARARGS, + "Deletes a slice of values from a repeated field."), + CMETHOD(Equals, METH_O, + "Checks if two protocol messages are equal (by identity)."), + CMETHOD(FieldLength, METH_O, + "Returns the number of elements in a repeated field."), + CMETHOD(FindInitializationErrors, METH_NOARGS, + "Returns the initialization errors of a message."), + CMETHOD(GetRepeatedMessage, METH_VARARGS, + "Returns a message from a repeated composite field."), + CMETHOD(GetRepeatedScalar, METH_VARARGS, + "Returns a scalar value from a repeated scalar field."), + CMETHOD(GetScalar, METH_O, + "Returns the scalar value of a field."), + CMETHOD(HasField, METH_O, + "Checks if a message field is set."), + CMETHOD(HasFieldByDescriptor, METH_O, + "Checks if a message field is set by given its descriptor"), + CMETHOD(IsInitialized, METH_NOARGS, + "Checks if all required fields of a protocol message are set."), + CMETHOD(ListFields, METH_NOARGS, + "Lists all set fields of a message."), + CMETHOD(MergeFrom, METH_O, + "Merges a protocol message into the current message."), + CMETHOD(MergeFromString, METH_O, + "Merges a serialized message into the current message."), + CMETHOD(MutableMessage, METH_O, + "Returns a new instance of a nested protocol message."), + CMETHOD(NewSubMessage, METH_O, + "Creates and returns a python message given the descriptor of a " + "composite field of the current message."), + CMETHOD(SetScalar, METH_VARARGS, + "Sets the value of a singular scalar field."), + CMETHOD(SerializePartialToString, METH_VARARGS, + "Serializes the message to a string, even if it isn't initialized."), + CMETHOD(SerializeToString, METH_NOARGS, + "Serializes the message to a string, only for initialized messages."), + CMETHOD(SetInParent, METH_NOARGS, + "Sets the has bit of the given field in its parent message."), + CMETHOD(SwapRepeatedFieldElements, METH_VARARGS, + "Swaps the elements in two positions in a repeated field."), + { NULL, NULL } +}; +#undef CMETHOD + +static PyMemberDef CMessageMembers[] = { + { C("full_name"), T_STRING, offsetof(CMessage, full_name), 0, "Full name" }, + { NULL } +}; + +// ------ Type Definition: + +// The definition for the type object that captures the type of CMessage +// in Python. +PyTypeObject CMessage_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + C("google.protobuf.internal." + "_net_proto2___python." + "CMessage"), // tp_name + sizeof(CMessage), // tp_basicsize + 0, // tp_itemsize + (destructor)CMessageDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + (reprfunc)CMessageStr, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + C("A ProtocolMessage"), // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + CMessageMethods, // tp_methods + CMessageMembers, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + (initproc)CMessageInit, // tp_init + PyType_GenericAlloc, // tp_alloc + PyType_GenericNew, // tp_new + PyObject_Del, // tp_free +}; + +// ------ Helper Functions: + +static void FormatTypeError(PyObject* arg, char* expected_types) { + PyObject* repr = PyObject_Repr(arg); + PyErr_Format(PyExc_TypeError, + "%.100s has type %.100s, but expected one of: %s", + PyString_AS_STRING(repr), + arg->ob_type->tp_name, + expected_types); + Py_DECREF(repr); +} + +template +static bool CheckAndGetInteger( + PyObject* arg, T* value, PyObject* min, PyObject* max) { + bool is_long = PyLong_Check(arg); + if (!PyInt_Check(arg) && !is_long) { + FormatTypeError(arg, "int, long"); + return false; + } + + if (PyObject_Compare(min, arg) > 0 || PyObject_Compare(max, arg) < 0) { + PyObject* s = PyObject_Str(arg); + PyErr_Format(PyExc_ValueError, + "Value out of range: %s", + PyString_AS_STRING(s)); + Py_DECREF(s); + return false; + } + if (is_long) { + if (min == kPythonZero) { + *value = static_cast(PyLong_AsUnsignedLongLong(arg)); + } else { + *value = static_cast(PyLong_AsLongLong(arg)); + } + } else { + *value = static_cast(PyInt_AsLong(arg)); + } + return true; +} + +static bool CheckAndGetDouble(PyObject* arg, double* value) { + if (!PyInt_Check(arg) && !PyLong_Check(arg) && + !PyFloat_Check(arg)) { + FormatTypeError(arg, "int, long, float"); + return false; + } + *value = PyFloat_AsDouble(arg); + return true; +} + +static bool CheckAndGetFloat(PyObject* arg, float* value) { + double double_value; + if (!CheckAndGetDouble(arg, &double_value)) { + return false; + } + *value = static_cast(double_value); + return true; +} + +static bool CheckAndGetBool(PyObject* arg, bool* value) { + if (!PyInt_Check(arg) && !PyBool_Check(arg) && !PyLong_Check(arg)) { + FormatTypeError(arg, "int, long, bool"); + return false; + } + *value = static_cast(PyInt_AsLong(arg)); + return true; +} + +google::protobuf::DynamicMessageFactory* global_message_factory = NULL; +static const google::protobuf::Message* CreateMessage(const char* message_type) { + string message_name(message_type); + const google::protobuf::Descriptor* descriptor = + GetDescriptorPool()->FindMessageTypeByName(message_name); + if (descriptor == NULL) { + return NULL; + } + return global_message_factory->GetPrototype(descriptor); +} + +static void ReleaseSubMessage(google::protobuf::Message* message, + const google::protobuf::FieldDescriptor* field_descriptor, + CMessage* child_cmessage) { + Message* released_message = message->GetReflection()->ReleaseMessage( + message, field_descriptor, global_message_factory); + GOOGLE_DCHECK(child_cmessage->message != NULL); + // ReleaseMessage will return NULL which differs from + // child_cmessage->message, if the field does not exist. In this case, + // the latter points to the default instance via a const_cast<>, so we + // have to reset it to a new mutable object since we are taking ownership. + if (released_message == NULL) { + const Message* prototype = global_message_factory->GetPrototype( + child_cmessage->message->GetDescriptor()); + GOOGLE_DCHECK(prototype != NULL); + child_cmessage->message = prototype->New(); + } + child_cmessage->parent = NULL; + child_cmessage->parent_field = NULL; + child_cmessage->free_message = true; + child_cmessage->read_only = false; +} + +static bool CheckAndSetString( + PyObject* arg, google::protobuf::Message* message, + const google::protobuf::FieldDescriptor* descriptor, + const google::protobuf::Reflection* reflection, + bool append, + int index) { + GOOGLE_DCHECK(descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING || + descriptor->type() == google::protobuf::FieldDescriptor::TYPE_BYTES); + if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) { + if (!PyString_Check(arg) && !PyUnicode_Check(arg)) { + FormatTypeError(arg, "str, unicode"); + return false; + } + + if (PyString_Check(arg)) { + PyObject* unicode = PyUnicode_FromEncodedObject(arg, "ascii", NULL); + if (unicode == NULL) { + PyObject* repr = PyObject_Repr(arg); + PyErr_Format(PyExc_ValueError, + "%s has type str, but isn't in 7-bit ASCII " + "encoding. Non-ASCII strings must be converted to " + "unicode objects before being added.", + PyString_AS_STRING(repr)); + Py_DECREF(repr); + return false; + } else { + Py_DECREF(unicode); + } + } + } else if (!PyString_Check(arg)) { + FormatTypeError(arg, "str"); + return false; + } + + PyObject* encoded_string = NULL; + if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) { + if (PyString_Check(arg)) { + encoded_string = PyString_AsEncodedObject(arg, "utf-8", NULL); + } else { + encoded_string = PyUnicode_AsEncodedObject(arg, "utf-8", NULL); + } + } else { + // In this case field type is "bytes". + encoded_string = arg; + Py_INCREF(encoded_string); + } + + if (encoded_string == NULL) { + return false; + } + + char* value; + Py_ssize_t value_len; + if (PyString_AsStringAndSize(encoded_string, &value, &value_len) < 0) { + Py_DECREF(encoded_string); + return false; + } + + string value_string(value, value_len); + if (append) { + reflection->AddString(message, descriptor, value_string); + } else if (index < 0) { + reflection->SetString(message, descriptor, value_string); + } else { + reflection->SetRepeatedString(message, descriptor, index, value_string); + } + Py_DECREF(encoded_string); + return true; +} + +static PyObject* ToStringObject( + const google::protobuf::FieldDescriptor* descriptor, string value) { + if (descriptor->type() != google::protobuf::FieldDescriptor::TYPE_STRING) { + return PyString_FromStringAndSize(value.c_str(), value.length()); + } + + PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL); + // If the string can't be decoded in UTF-8, just return a string object that + // contains the raw bytes. This can't happen if the value was assigned using + // the members of the Python message object, but can happen if the values were + // parsed from the wire (binary). + if (result == NULL) { + PyErr_Clear(); + result = PyString_FromStringAndSize(value.c_str(), value.length()); + } + return result; +} + +static void AssureWritable(CMessage* self) { + if (self == NULL || + self->parent == NULL || + self->parent_field == NULL) { + return; + } + + if (!self->read_only) { + return; + } + + AssureWritable(self->parent); + + google::protobuf::Message* message = self->parent->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + self->message = reflection->MutableMessage( + message, self->parent_field->descriptor, global_message_factory); + self->read_only = false; +} + +static PyObject* InternalGetScalar( + google::protobuf::Message* message, + const google::protobuf::FieldDescriptor* field_descriptor) { + const google::protobuf::Reflection* reflection = message->GetReflection(); + + if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { + PyErr_SetString( + PyExc_KeyError, "Field does not belong to message!"); + return NULL; + } + + PyObject* result = NULL; + switch (field_descriptor->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { + int32 value = reflection->GetInt32(*message, field_descriptor); + result = PyInt_FromLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { + int64 value = reflection->GetInt64(*message, field_descriptor); +#if IS_64BIT + result = PyInt_FromLong(value); +#else + result = PyLong_FromLongLong(value); +#endif + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { + uint32 value = reflection->GetUInt32(*message, field_descriptor); +#if IS_64BIT + result = PyInt_FromLong(value); +#else + result = PyLong_FromLongLong(value); +#endif + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { + uint64 value = reflection->GetUInt64(*message, field_descriptor); +#if IS_64BIT + if (value <= static_cast(kint64max)) { + result = PyInt_FromLong(static_cast(value)); + } +#else + if (value <= static_cast(kint32max)) { + result = PyInt_FromLong(static_cast(value)); + } +#endif + else { // NOLINT + result = PyLong_FromUnsignedLongLong(value); + } + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { + float value = reflection->GetFloat(*message, field_descriptor); + result = PyFloat_FromDouble(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { + double value = reflection->GetDouble(*message, field_descriptor); + result = PyFloat_FromDouble(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { + bool value = reflection->GetBool(*message, field_descriptor); + result = PyBool_FromLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + string value = reflection->GetString(*message, field_descriptor); + result = ToStringObject(field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { + if (!message->GetReflection()->HasField(*message, field_descriptor)) { + // Look for the value in the unknown fields. + google::protobuf::UnknownFieldSet* unknown_field_set = + message->GetReflection()->MutableUnknownFields(message); + for (int i = 0; i < unknown_field_set->field_count(); ++i) { + if (unknown_field_set->field(i).number() == + field_descriptor->number()) { + result = PyInt_FromLong(unknown_field_set->field(i).varint()); + break; + } + } + } + + if (result == NULL) { + const google::protobuf::EnumValueDescriptor* enum_value = + message->GetReflection()->GetEnum(*message, field_descriptor); + result = PyInt_FromLong(enum_value->number()); + } + break; + } + default: + PyErr_Format( + PyExc_SystemError, "Getting a value from a field of unknown type %d", + field_descriptor->cpp_type()); + } + + return result; +} + +static PyObject* InternalSetScalar( + google::protobuf::Message* message, const google::protobuf::FieldDescriptor* field_descriptor, + PyObject* arg) { + const google::protobuf::Reflection* reflection = message->GetReflection(); + + if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { + PyErr_SetString( + PyExc_KeyError, "Field does not belong to message!"); + return NULL; + } + + switch (field_descriptor->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { + GOOGLE_CHECK_GET_INT32(arg, value); + reflection->SetInt32(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { + GOOGLE_CHECK_GET_INT64(arg, value); + reflection->SetInt64(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { + GOOGLE_CHECK_GET_UINT32(arg, value); + reflection->SetUInt32(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { + GOOGLE_CHECK_GET_UINT64(arg, value); + reflection->SetUInt64(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { + GOOGLE_CHECK_GET_FLOAT(arg, value); + reflection->SetFloat(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { + GOOGLE_CHECK_GET_DOUBLE(arg, value); + reflection->SetDouble(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { + GOOGLE_CHECK_GET_BOOL(arg, value); + reflection->SetBool(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + if (!CheckAndSetString( + arg, message, field_descriptor, reflection, false, -1)) { + return NULL; + } + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { + GOOGLE_CHECK_GET_INT32(arg, value); + const google::protobuf::EnumDescriptor* enum_descriptor = + field_descriptor->enum_type(); + const google::protobuf::EnumValueDescriptor* enum_value = + enum_descriptor->FindValueByNumber(value); + if (enum_value != NULL) { + reflection->SetEnum(message, field_descriptor, enum_value); + } else { + bool added = false; + // Add the value to the unknown fields. + google::protobuf::UnknownFieldSet* unknown_field_set = + message->GetReflection()->MutableUnknownFields(message); + for (int i = 0; i < unknown_field_set->field_count(); ++i) { + if (unknown_field_set->field(i).number() == + field_descriptor->number()) { + unknown_field_set->mutable_field(i)->set_varint(value); + added = true; + break; + } + } + + if (!added) { + unknown_field_set->AddVarint(field_descriptor->number(), value); + } + reflection->ClearField(message, field_descriptor); + } + break; + } + default: + PyErr_Format( + PyExc_SystemError, "Setting value to a field of unknown type %d", + field_descriptor->cpp_type()); + } + + Py_RETURN_NONE; +} + +static PyObject* InternalAddRepeatedScalar( + google::protobuf::Message* message, const google::protobuf::FieldDescriptor* field_descriptor, + PyObject* arg) { + + if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { + PyErr_SetString( + PyExc_KeyError, "Field does not belong to message!"); + return NULL; + } + + const google::protobuf::Reflection* reflection = message->GetReflection(); + switch (field_descriptor->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { + GOOGLE_CHECK_GET_INT32(arg, value); + reflection->AddInt32(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { + GOOGLE_CHECK_GET_INT64(arg, value); + reflection->AddInt64(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { + GOOGLE_CHECK_GET_UINT32(arg, value); + reflection->AddUInt32(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { + GOOGLE_CHECK_GET_UINT64(arg, value); + reflection->AddUInt64(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { + GOOGLE_CHECK_GET_FLOAT(arg, value); + reflection->AddFloat(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { + GOOGLE_CHECK_GET_DOUBLE(arg, value); + reflection->AddDouble(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { + GOOGLE_CHECK_GET_BOOL(arg, value); + reflection->AddBool(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + if (!CheckAndSetString( + arg, message, field_descriptor, reflection, true, -1)) { + return NULL; + } + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { + GOOGLE_CHECK_GET_INT32(arg, value); + const google::protobuf::EnumDescriptor* enum_descriptor = + field_descriptor->enum_type(); + const google::protobuf::EnumValueDescriptor* enum_value = + enum_descriptor->FindValueByNumber(value); + if (enum_value != NULL) { + reflection->AddEnum(message, field_descriptor, enum_value); + } else { + PyObject* s = PyObject_Str(arg); + PyErr_Format(PyExc_ValueError, "Unknown enum value: %s", + PyString_AS_STRING(s)); + Py_DECREF(s); + return NULL; + } + break; + } + default: + PyErr_Format( + PyExc_SystemError, "Adding value to a field of unknown type %d", + field_descriptor->cpp_type()); + } + + Py_RETURN_NONE; +} + +static PyObject* InternalGetRepeatedScalar( + CMessage* cmessage, const google::protobuf::FieldDescriptor* field_descriptor, + int index) { + google::protobuf::Message* message = cmessage->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + + int field_size = reflection->FieldSize(*message, field_descriptor); + if (index < 0) { + index = field_size + index; + } + if (index < 0 || index >= field_size) { + PyErr_Format(PyExc_IndexError, + "list assignment index (%d) out of range", index); + return NULL; + } + + PyObject* result = NULL; + switch (field_descriptor->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { + int32 value = reflection->GetRepeatedInt32( + *message, field_descriptor, index); + result = PyInt_FromLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { + int64 value = reflection->GetRepeatedInt64( + *message, field_descriptor, index); + result = PyLong_FromLongLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { + uint32 value = reflection->GetRepeatedUInt32( + *message, field_descriptor, index); + result = PyLong_FromLongLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { + uint64 value = reflection->GetRepeatedUInt64( + *message, field_descriptor, index); + result = PyLong_FromUnsignedLongLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { + float value = reflection->GetRepeatedFloat( + *message, field_descriptor, index); + result = PyFloat_FromDouble(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { + double value = reflection->GetRepeatedDouble( + *message, field_descriptor, index); + result = PyFloat_FromDouble(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { + bool value = reflection->GetRepeatedBool( + *message, field_descriptor, index); + result = PyBool_FromLong(value ? 1 : 0); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { + const google::protobuf::EnumValueDescriptor* enum_value = + message->GetReflection()->GetRepeatedEnum( + *message, field_descriptor, index); + result = PyInt_FromLong(enum_value->number()); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + string value = reflection->GetRepeatedString( + *message, field_descriptor, index); + result = ToStringObject(field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: { + CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); + if (py_cmsg == NULL) { + return NULL; + } + const google::protobuf::Message& msg = reflection->GetRepeatedMessage( + *message, field_descriptor, index); + py_cmsg->parent = cmessage; + py_cmsg->full_name = field_descriptor->full_name().c_str(); + py_cmsg->message = const_cast(&msg); + py_cmsg->free_message = false; + py_cmsg->read_only = false; + result = reinterpret_cast(py_cmsg); + break; + } + default: + PyErr_Format( + PyExc_SystemError, + "Getting value from a repeated field of unknown type %d", + field_descriptor->cpp_type()); + } + + return result; +} + +static PyObject* InternalGetRepeatedScalarSlice( + CMessage* cmessage, const google::protobuf::FieldDescriptor* field_descriptor, + PyObject* slice) { + Py_ssize_t from; + Py_ssize_t to; + Py_ssize_t step; + Py_ssize_t length; + bool return_list = false; + google::protobuf::Message* message = cmessage->message; + + if (PyInt_Check(slice)) { + from = to = PyInt_AsLong(slice); + } else if (PyLong_Check(slice)) { + from = to = PyLong_AsLong(slice); + } else if (PySlice_Check(slice)) { + const google::protobuf::Reflection* reflection = message->GetReflection(); + length = reflection->FieldSize(*message, field_descriptor); + PySlice_GetIndices( + reinterpret_cast(slice), length, &from, &to, &step); + return_list = true; + } else { + PyErr_SetString(PyExc_TypeError, "list indices must be integers"); + return NULL; + } + + if (!return_list) { + return InternalGetRepeatedScalar(cmessage, field_descriptor, from); + } + + PyObject* list = PyList_New(0); + if (list == NULL) { + return NULL; + } + + if (from <= to) { + if (step < 0) return list; + for (Py_ssize_t index = from; index < to; index += step) { + if (index < 0 || index >= length) break; + PyObject* s = InternalGetRepeatedScalar( + cmessage, field_descriptor, index); + PyList_Append(list, s); + Py_DECREF(s); + } + } else { + if (step > 0) return list; + for (Py_ssize_t index = from; index > to; index += step) { + if (index < 0 || index >= length) break; + PyObject* s = InternalGetRepeatedScalar( + cmessage, field_descriptor, index); + PyList_Append(list, s); + Py_DECREF(s); + } + } + return list; +} + +// ------ C Constructor/Destructor: + +static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds) { + self->message = NULL; + return 0; +} + +static void CMessageDealloc(CMessage* self) { + if (self->free_message) { + if (self->read_only) { + PyErr_WriteUnraisable(reinterpret_cast(self)); + } + delete self->message; + } + self->ob_type->tp_free(reinterpret_cast(self)); +} + +// ------ Methods: + +static PyObject* CMessage_Clear(CMessage* self, PyObject* arg) { + AssureWritable(self); + google::protobuf::Message* message = self->message; + + // This block of code is equivalent to the following: + // for cfield_descriptor, child_cmessage in arg: + // ReleaseSubMessage(cfield_descriptor, child_cmessage) + if (!PyList_Check(arg)) { + PyErr_SetString(PyExc_TypeError, "Must be a list"); + return NULL; + } + PyObject* messages_to_clear = arg; + Py_ssize_t num_messages_to_clear = PyList_GET_SIZE(messages_to_clear); + for(int i = 0; i < num_messages_to_clear; ++i) { + PyObject* message_tuple = PyList_GET_ITEM(messages_to_clear, i); + if (!PyTuple_Check(message_tuple) || PyTuple_GET_SIZE(message_tuple) != 2) { + PyErr_SetString(PyExc_TypeError, "Must be a tuple of size 2"); + return NULL; + } + + PyObject* py_cfield_descriptor = PyTuple_GET_ITEM(message_tuple, 0); + PyObject* py_child_cmessage = PyTuple_GET_ITEM(message_tuple, 1); + if (!PyObject_TypeCheck(py_cfield_descriptor, &CFieldDescriptor_Type) || + !PyObject_TypeCheck(py_child_cmessage, &CMessage_Type)) { + PyErr_SetString(PyExc_ValueError, "Invalid Tuple"); + return NULL; + } + + CFieldDescriptor* cfield_descriptor = reinterpret_cast( + py_cfield_descriptor); + CMessage* child_cmessage = reinterpret_cast(py_child_cmessage); + ReleaseSubMessage(message, cfield_descriptor->descriptor, child_cmessage); + } + + message->Clear(); + Py_RETURN_NONE; +} + +static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args) { + return PyBool_FromLong(self->message->IsInitialized() ? 1 : 0); +} + +static PyObject* CMessage_HasField(CMessage* self, PyObject* arg) { + char* field_name; + if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Descriptor* descriptor = message->GetDescriptor(); + const google::protobuf::FieldDescriptor* field_descriptor = + descriptor->FindFieldByName(field_name); + if (field_descriptor == NULL) { + PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name); + return NULL; + } + + bool has_field = + message->GetReflection()->HasField(*message, field_descriptor); + return PyBool_FromLong(has_field ? 1 : 0); +} + +static PyObject* CMessage_HasFieldByDescriptor(CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor = NULL; + if (!PyObject_TypeCheck(reinterpret_cast(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast(arg); + + google::protobuf::Message* message = self->message; + const google::protobuf::FieldDescriptor* field_descriptor = + cfield_descriptor->descriptor; + + if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { + PyErr_SetString(PyExc_KeyError, + "Field does not belong to message!"); + return NULL; + } + + if (FIELD_IS_REPEATED(field_descriptor)) { + PyErr_SetString(PyExc_KeyError, + "Field is repeated. A singular method is required."); + return NULL; + } + + bool has_field = + message->GetReflection()->HasField(*message, field_descriptor); + return PyBool_FromLong(has_field ? 1 : 0); +} + +static PyObject* CMessage_ClearFieldByDescriptor( + CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor = NULL; + if (!PyObject_TypeCheck(reinterpret_cast(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast(arg); + + google::protobuf::Message* message = self->message; + const google::protobuf::FieldDescriptor* field_descriptor = + cfield_descriptor->descriptor; + + if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { + PyErr_SetString(PyExc_KeyError, + "Field does not belong to message!"); + return NULL; + } + + message->GetReflection()->ClearField(message, field_descriptor); + Py_RETURN_NONE; +} + +static PyObject* CMessage_ClearField(CMessage* self, PyObject* args) { + char* field_name; + CMessage* child_cmessage = NULL; + if (!PyArg_ParseTuple(args, C("s|O!:ClearField"), &field_name, + &CMessage_Type, &child_cmessage)) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Descriptor* descriptor = message->GetDescriptor(); + const google::protobuf::FieldDescriptor* field_descriptor = + descriptor->FindFieldByName(field_name); + if (field_descriptor == NULL) { + PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name); + return NULL; + } + + if (child_cmessage != NULL && !FIELD_IS_REPEATED(field_descriptor)) { + ReleaseSubMessage(message, field_descriptor, child_cmessage); + } else { + message->GetReflection()->ClearField(message, field_descriptor); + } + Py_RETURN_NONE; +} + +static PyObject* CMessage_GetScalar(CMessage* self, PyObject* arg) { + CFieldDescriptor* cdescriptor = NULL; + if (!PyObject_TypeCheck(reinterpret_cast(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cdescriptor = reinterpret_cast(arg); + + google::protobuf::Message* message = self->message; + return InternalGetScalar(message, cdescriptor->descriptor); +} + +static PyObject* CMessage_GetRepeatedScalar(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* slice; + if (!PyArg_ParseTuple(args, C("O!O:GetRepeatedScalar"), + &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { + return NULL; + } + + return InternalGetRepeatedScalarSlice( + self, cfield_descriptor->descriptor, slice); +} + +static PyObject* CMessage_AssignRepeatedScalar(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* slice; + if (!PyArg_ParseTuple(args, C("O!O:AssignRepeatedScalar"), + &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { + return NULL; + } + + AssureWritable(self); + google::protobuf::Message* message = self->message; + message->GetReflection()->ClearField(message, cfield_descriptor->descriptor); + + PyObject* iter = PyObject_GetIter(slice); + PyObject* next; + while ((next = PyIter_Next(iter)) != NULL) { + if (InternalAddRepeatedScalar( + message, cfield_descriptor->descriptor, next) == NULL) { + Py_DECREF(next); + Py_DECREF(iter); + return NULL; + } + Py_DECREF(next); + } + Py_DECREF(iter); + Py_RETURN_NONE; +} + +static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* slice; + if (!PyArg_ParseTuple(args, C("O!O:DeleteRepeatedField"), + &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { + return NULL; + } + AssureWritable(self); + + Py_ssize_t length, from, to, step, slice_length; + google::protobuf::Message* message = self->message; + const google::protobuf::FieldDescriptor* field_descriptor = + cfield_descriptor->descriptor; + const google::protobuf::Reflection* reflection = message->GetReflection(); + int min, max; + length = reflection->FieldSize(*message, field_descriptor); + + if (PyInt_Check(slice) || PyLong_Check(slice)) { + from = to = PyLong_AsLong(slice); + if (from < 0) { + from = to = length + from; + } + step = 1; + min = max = from; + + // Range check. + if (from < 0 || from >= length) { + PyErr_Format(PyExc_IndexError, "list assignment index out of range"); + return NULL; + } + } else if (PySlice_Check(slice)) { + from = to = step = slice_length = 0; + PySlice_GetIndicesEx( + reinterpret_cast(slice), + length, &from, &to, &step, &slice_length); + if (from < to) { + min = from; + max = to - 1; + } else { + min = to + 1; + max = from; + } + } else { + PyErr_SetString(PyExc_TypeError, "list indices must be integers"); + return NULL; + } + + Py_ssize_t i = from; + std::vector to_delete(length, false); + while (i >= min && i <= max) { + to_delete[i] = true; + i += step; + } + + to = 0; + for (i = 0; i < length; ++i) { + if (!to_delete[i]) { + if (i != to) { + reflection->SwapElements(message, field_descriptor, i, to); + } + ++to; + } + } + + while (i > to) { + reflection->RemoveLast(message, field_descriptor); + --i; + } + + Py_RETURN_NONE; +} + + +static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* arg; + if (!PyArg_ParseTuple(args, C("O!O:SetScalar"), + &CFieldDescriptor_Type, &cfield_descriptor, &arg)) { + return NULL; + } + AssureWritable(self); + + return InternalSetScalar(self->message, cfield_descriptor->descriptor, arg); +} + +static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* value; + if (!PyArg_ParseTuple(args, C("O!O:AddRepeatedScalar"), + &CFieldDescriptor_Type, &cfield_descriptor, &value)) { + return NULL; + } + AssureWritable(self); + + return InternalAddRepeatedScalar( + self->message, cfield_descriptor->descriptor, value); +} + +static PyObject* CMessage_FieldLength(CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor; + if (!PyObject_TypeCheck(reinterpret_cast(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast(arg); + + google::protobuf::Message* message = self->message; + int length = message->GetReflection()->FieldSize( + *message, cfield_descriptor->descriptor); + return PyInt_FromLong(length); +} + +static PyObject* CMessage_DebugString(CMessage* self, PyObject* args) { + return PyString_FromString(self->message->DebugString().c_str()); +} + +static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args) { + int size = self->message->ByteSize(); + if (size <= 0) { + return PyString_FromString(""); + } + PyObject* result = PyString_FromStringAndSize(NULL, size); + if (result == NULL) { + return NULL; + } + char* buffer = PyString_AS_STRING(result); + self->message->SerializeWithCachedSizesToArray( + reinterpret_cast(buffer)); + return result; +} + +static PyObject* CMessage_SerializePartialToString( + CMessage* self, PyObject* args) { + string contents; + self->message->SerializePartialToString(&contents); + return PyString_FromStringAndSize(contents.c_str(), contents.size()); +} + +static PyObject* CMessageStr(CMessage* self) { + char str[1024]; + str[sizeof(str) - 1] = 0; + snprintf(str, sizeof(str) - 1, "CMessage: <%p>", self->message); + return PyString_FromString(str); +} + +static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* arg) { + CMessage* other_message; + if (!PyObject_TypeCheck(reinterpret_cast(arg), &CMessage_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a message"); + return NULL; + } + + other_message = reinterpret_cast(arg); + if (other_message->message->GetDescriptor() != + self->message->GetDescriptor()) { + PyErr_Format(PyExc_TypeError, + "Tried to merge from a message with a different type. " + "to: %s, from: %s", + self->message->GetDescriptor()->full_name().c_str(), + other_message->message->GetDescriptor()->full_name().c_str()); + return NULL; + } + AssureWritable(self); + + self->message->MergeFrom(*other_message->message); + Py_RETURN_NONE; +} + +static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* arg) { + CMessage* other_message; + if (!PyObject_TypeCheck(reinterpret_cast(arg), &CMessage_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a message"); + return NULL; + } + + other_message = reinterpret_cast(arg); + if (other_message->message->GetDescriptor() != + self->message->GetDescriptor()) { + PyErr_Format(PyExc_TypeError, + "Tried to copy from a message with a different type. " + "to: %s, from: %s", + self->message->GetDescriptor()->full_name().c_str(), + other_message->message->GetDescriptor()->full_name().c_str()); + return NULL; + } + + AssureWritable(self); + + self->message->CopyFrom(*other_message->message); + Py_RETURN_NONE; +} + +static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* arg) { + const void* data; + Py_ssize_t data_length; + if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) { + return NULL; + } + + AssureWritable(self); + google::protobuf::io::CodedInputStream input( + reinterpret_cast(data), data_length); + input.SetExtensionRegistry(GetDescriptorPool(), global_message_factory); + bool success = self->message->MergePartialFromCodedStream(&input); + if (success) { + return PyInt_FromLong(self->message->ByteSize()); + } else { + return PyInt_FromLong(-1); + } +} + +static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args) { + return PyLong_FromLong(self->message->ByteSize()); +} + +static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args) { + AssureWritable(self); + Py_RETURN_NONE; +} + +static PyObject* CMessage_SwapRepeatedFieldElements( + CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + int index1, index2; + if (!PyArg_ParseTuple(args, C("O!ii:SwapRepeatedFieldElements"), + &CFieldDescriptor_Type, &cfield_descriptor, + &index1, &index2)) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + + reflection->SwapElements( + message, cfield_descriptor->descriptor, index1, index2); + Py_RETURN_NONE; +} + +static PyObject* CMessage_AddMessage(CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor; + if (!PyObject_TypeCheck(reinterpret_cast(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast(arg); + AssureWritable(self); + + CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); + if (py_cmsg == NULL) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + google::protobuf::Message* sub_message = + reflection->AddMessage(message, cfield_descriptor->descriptor); + + py_cmsg->parent = NULL; + py_cmsg->full_name = sub_message->GetDescriptor()->full_name().c_str(); + py_cmsg->message = sub_message; + py_cmsg->free_message = false; + py_cmsg->read_only = false; + return reinterpret_cast(py_cmsg); +} + +static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* slice; + if (!PyArg_ParseTuple(args, C("O!O:GetRepeatedMessage"), + &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { + return NULL; + } + + return InternalGetRepeatedScalarSlice( + self, cfield_descriptor->descriptor, slice); +} + +static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor; + if (!PyObject_TypeCheck(reinterpret_cast(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast(arg); + + CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); + if (py_cmsg == NULL) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + const google::protobuf::Message& sub_message = + reflection->GetMessage(*message, cfield_descriptor->descriptor, + global_message_factory); + + py_cmsg->full_name = sub_message.GetDescriptor()->full_name().c_str(); + py_cmsg->parent = self; + py_cmsg->parent_field = cfield_descriptor; + py_cmsg->message = const_cast(&sub_message); + py_cmsg->free_message = false; + py_cmsg->read_only = true; + return reinterpret_cast(py_cmsg); +} + +static PyObject* CMessage_MutableMessage(CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor; + if (!PyObject_TypeCheck(reinterpret_cast(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast(arg); + AssureWritable(self); + + CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); + if (py_cmsg == NULL) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + google::protobuf::Message* mutable_message = + reflection->MutableMessage(message, cfield_descriptor->descriptor, + global_message_factory); + + py_cmsg->full_name = mutable_message->GetDescriptor()->full_name().c_str(); + py_cmsg->message = mutable_message; + py_cmsg->free_message = false; + py_cmsg->read_only = false; + return reinterpret_cast(py_cmsg); +} + +static PyObject* CMessage_Equals(CMessage* self, PyObject* arg) { + CMessage* other_message; + if (!PyObject_TypeCheck(reinterpret_cast(arg), &CMessage_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a message"); + return NULL; + } + other_message = reinterpret_cast(arg); + + if (other_message->message == self->message) { + return PyBool_FromLong(1); + } + + if (other_message->message->GetDescriptor() != + self->message->GetDescriptor()) { + return PyBool_FromLong(0); + } + + return PyBool_FromLong(1); +} + +static PyObject* CMessage_ListFields(CMessage* self, PyObject* args) { + google::protobuf::Message* message = self->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + vector fields; + reflection->ListFields(*message, &fields); + + PyObject* list = PyList_New(fields.size()); + if (list == NULL) { + return NULL; + } + + for (unsigned int i = 0; i < fields.size(); ++i) { + bool is_extension = fields[i]->is_extension(); + PyObject* t = PyTuple_New(2); + if (t == NULL) { + Py_DECREF(list); + return NULL; + } + + PyObject* is_extension_object = PyBool_FromLong(is_extension ? 1 : 0); + + PyObject* field_name; + const string* s; + if (is_extension) { + s = &fields[i]->full_name(); + } else { + s = &fields[i]->name(); + } + field_name = PyString_FromStringAndSize(s->c_str(), s->length()); + if (field_name == NULL) { + Py_DECREF(list); + Py_DECREF(t); + return NULL; + } + + PyTuple_SET_ITEM(t, 0, is_extension_object); + PyTuple_SET_ITEM(t, 1, field_name); + PyList_SET_ITEM(list, i, t); + } + + return list; +} + +static PyObject* CMessage_FindInitializationErrors(CMessage* self) { + google::protobuf::Message* message = self->message; + vector errors; + message->FindInitializationErrors(&errors); + + PyObject* error_list = PyList_New(errors.size()); + if (error_list == NULL) { + return NULL; + } + for (unsigned int i = 0; i < errors.size(); ++i) { + const string& error = errors[i]; + PyObject* error_string = PyString_FromStringAndSize( + error.c_str(), error.length()); + if (error_string == NULL) { + Py_DECREF(error_list); + return NULL; + } + PyList_SET_ITEM(error_list, i, error_string); + } + return error_list; +} + +// ------ Python Constructor: + +PyObject* Python_NewCMessage(PyObject* ignored, PyObject* arg) { + const char* message_type = PyString_AsString(arg); + if (message_type == NULL) { + return NULL; + } + + const google::protobuf::Message* message = CreateMessage(message_type); + if (message == NULL) { + PyErr_Format(PyExc_TypeError, "Couldn't create message of type %s!", + message_type); + return NULL; + } + + CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); + if (py_cmsg == NULL) { + return NULL; + } + py_cmsg->message = message->New(); + py_cmsg->free_message = true; + py_cmsg->full_name = message->GetDescriptor()->full_name().c_str(); + py_cmsg->read_only = false; + py_cmsg->parent = NULL; + py_cmsg->parent_field = NULL; + return reinterpret_cast(py_cmsg); +} + +// --- Module Functions (exposed to Python): + +PyMethodDef methods[] = { + { C("NewCMessage"), (PyCFunction)Python_NewCMessage, + METH_O, + C("Creates a new C++ protocol message, given its full name.") }, + { C("NewCDescriptorPool"), (PyCFunction)Python_NewCDescriptorPool, + METH_NOARGS, + C("Creates a new C++ descriptor pool.") }, + { C("BuildFile"), (PyCFunction)Python_BuildFile, + METH_O, + C("Registers a new protocol buffer file in the global C++ descriptor " + "pool.") }, + {NULL} +}; + +// --- Exposing the C proto living inside Python proto to C code: + +extern const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg); +extern Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg); + +static const google::protobuf::Message* GetCProtoInsidePyProtoImpl(PyObject* msg) { + PyObject* c_msg_obj = PyObject_GetAttrString(msg, "_cmsg"); + if (c_msg_obj == NULL) { + PyErr_Clear(); + return NULL; + } + Py_DECREF(c_msg_obj); + if (!PyObject_TypeCheck(c_msg_obj, &CMessage_Type)) { + return NULL; + } + CMessage* c_msg = reinterpret_cast(c_msg_obj); + return c_msg->message; +} + +static google::protobuf::Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) { + PyObject* c_msg_obj = PyObject_GetAttrString(msg, "_cmsg"); + if (c_msg_obj == NULL) { + PyErr_Clear(); + return NULL; + } + Py_DECREF(c_msg_obj); + if (!PyObject_TypeCheck(c_msg_obj, &CMessage_Type)) { + return NULL; + } + CMessage* c_msg = reinterpret_cast(c_msg_obj); + AssureWritable(c_msg); + return c_msg->message; +} + +// --- Module Init Function: + +static const char module_docstring[] = +"python-proto2 is a module that can be used to enhance proto2 Python API\n" +"performance.\n" +"\n" +"It provides access to the protocol buffers C++ reflection API that\n" +"implements the basic protocol buffer functions."; + +extern "C" { + void init_net_proto2___python() { + // Initialize constants. + kPythonZero = PyInt_FromLong(0); + kint32min_py = PyInt_FromLong(kint32min); + kint32max_py = PyInt_FromLong(kint32max); + kuint32max_py = PyLong_FromLongLong(kuint32max); + kint64min_py = PyLong_FromLongLong(kint64min); + kint64max_py = PyLong_FromLongLong(kint64max); + kuint64max_py = PyLong_FromUnsignedLongLong(kuint64max); + + global_message_factory = new DynamicMessageFactory(GetDescriptorPool()); + global_message_factory->SetDelegateToGeneratedFactory(true); + + // Export our functions to Python. + PyObject *m; + m = Py_InitModule3(C("_net_proto2___python"), methods, C(module_docstring)); + if (m == NULL) { + return; + } + + AddConstants(m); + + CMessage_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&CMessage_Type) < 0) { + return; + } + + if (!InitDescriptor()) { + return; + } + + // Override {Get,Mutable}CProtoInsidePyProto. + GetCProtoInsidePyProtoPtr = GetCProtoInsidePyProtoImpl; + MutableCProtoInsidePyProtoPtr = MutableCProtoInsidePyProtoImpl; + } +} + +} // namespace python +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_descriptor.cc b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_descriptor.cc new file mode 100644 index 0000000..5e3e9ea --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_descriptor.cc @@ -0,0 +1,337 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: petar@google.com (Petar Petrov) + +#include +#include + +#include +#include + +#define C(str) const_cast(str) + +namespace google { +namespace protobuf { +namespace python { + + +static void CFieldDescriptorDealloc(CFieldDescriptor* self); + +static google::protobuf::DescriptorPool* g_descriptor_pool = NULL; + +static PyObject* CFieldDescriptor_GetFullName( + CFieldDescriptor* self, void *closure) { + Py_XINCREF(self->full_name); + return self->full_name; +} + +static PyObject* CFieldDescriptor_GetName( + CFieldDescriptor *self, void *closure) { + Py_XINCREF(self->name); + return self->name; +} + +static PyObject* CFieldDescriptor_GetCppType( + CFieldDescriptor *self, void *closure) { + Py_XINCREF(self->cpp_type); + return self->cpp_type; +} + +static PyObject* CFieldDescriptor_GetLabel( + CFieldDescriptor *self, void *closure) { + Py_XINCREF(self->label); + return self->label; +} + +static PyObject* CFieldDescriptor_GetID( + CFieldDescriptor *self, void *closure) { + Py_XINCREF(self->id); + return self->id; +} + + +static PyGetSetDef CFieldDescriptorGetters[] = { + { C("full_name"), + (getter)CFieldDescriptor_GetFullName, NULL, "Full name", NULL}, + { C("name"), + (getter)CFieldDescriptor_GetName, NULL, "last name", NULL}, + { C("cpp_type"), + (getter)CFieldDescriptor_GetCppType, NULL, "C++ Type", NULL}, + { C("label"), + (getter)CFieldDescriptor_GetLabel, NULL, "Label", NULL}, + { C("id"), + (getter)CFieldDescriptor_GetID, NULL, "ID", NULL}, + {NULL} +}; + +PyTypeObject CFieldDescriptor_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + C("google.protobuf.internal." + "_net_proto2___python." + "CFieldDescriptor"), // tp_name + sizeof(CFieldDescriptor), // tp_basicsize + 0, // tp_itemsize + (destructor)CFieldDescriptorDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + C("A Field Descriptor"), // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + CFieldDescriptorGetters, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + PyType_GenericAlloc, // tp_alloc + PyType_GenericNew, // tp_new + PyObject_Del, // tp_free +}; + +static void CFieldDescriptorDealloc(CFieldDescriptor* self) { + Py_DECREF(self->full_name); + Py_DECREF(self->name); + Py_DECREF(self->cpp_type); + Py_DECREF(self->label); + Py_DECREF(self->id); + self->ob_type->tp_free(reinterpret_cast(self)); +} + +typedef struct { + PyObject_HEAD + + const google::protobuf::DescriptorPool* pool; +} CDescriptorPool; + +static void CDescriptorPoolDealloc(CDescriptorPool* self); + +static PyObject* CDescriptorPool_NewCDescriptor( + const google::protobuf::FieldDescriptor* field_descriptor) { + CFieldDescriptor* cfield_descriptor = PyObject_New( + CFieldDescriptor, &CFieldDescriptor_Type); + if (cfield_descriptor == NULL) { + return NULL; + } + cfield_descriptor->descriptor = field_descriptor; + + cfield_descriptor->full_name = PyString_FromString( + field_descriptor->full_name().c_str()); + cfield_descriptor->name = PyString_FromString( + field_descriptor->name().c_str()); + cfield_descriptor->cpp_type = PyLong_FromLong(field_descriptor->cpp_type()); + cfield_descriptor->label = PyLong_FromLong(field_descriptor->label()); + cfield_descriptor->id = PyLong_FromVoidPtr(cfield_descriptor); + return reinterpret_cast(cfield_descriptor); +} + +static PyObject* CDescriptorPool_FindFieldByName( + CDescriptorPool* self, PyObject* arg) { + const char* full_field_name = PyString_AsString(arg); + if (full_field_name == NULL) { + return NULL; + } + + const google::protobuf::FieldDescriptor* field_descriptor = NULL; + + field_descriptor = self->pool->FindFieldByName(full_field_name); + + + if (field_descriptor == NULL) { + PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s", + full_field_name); + return NULL; + } + + return CDescriptorPool_NewCDescriptor(field_descriptor); +} + +static PyObject* CDescriptorPool_FindExtensionByName( + CDescriptorPool* self, PyObject* arg) { + const char* full_field_name = PyString_AsString(arg); + if (full_field_name == NULL) { + return NULL; + } + + const google::protobuf::FieldDescriptor* field_descriptor = + self->pool->FindExtensionByName(full_field_name); + if (field_descriptor == NULL) { + PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s", + full_field_name); + return NULL; + } + + return CDescriptorPool_NewCDescriptor(field_descriptor); +} + +static PyMethodDef CDescriptorPoolMethods[] = { + { C("FindFieldByName"), + (PyCFunction)CDescriptorPool_FindFieldByName, + METH_O, + C("Searches for a field descriptor by full name.") }, + { C("FindExtensionByName"), + (PyCFunction)CDescriptorPool_FindExtensionByName, + METH_O, + C("Searches for extension descriptor by full name.") }, + {NULL} +}; + +PyTypeObject CDescriptorPool_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + C("google.protobuf.internal." + "_net_proto2___python." + "CFieldDescriptor"), // tp_name + sizeof(CDescriptorPool), // tp_basicsize + 0, // tp_itemsize + (destructor)CDescriptorPoolDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + C("A Descriptor Pool"), // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + CDescriptorPoolMethods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + PyType_GenericAlloc, // tp_alloc + PyType_GenericNew, // tp_new + PyObject_Del, // tp_free +}; + +static void CDescriptorPoolDealloc(CDescriptorPool* self) { + self->ob_type->tp_free(reinterpret_cast(self)); +} + +google::protobuf::DescriptorPool* GetDescriptorPool() { + if (g_descriptor_pool == NULL) { + g_descriptor_pool = new google::protobuf::DescriptorPool( + google::protobuf::DescriptorPool::generated_pool()); + } + return g_descriptor_pool; +} + +PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args) { + CDescriptorPool* cdescriptor_pool = PyObject_New( + CDescriptorPool, &CDescriptorPool_Type); + if (cdescriptor_pool == NULL) { + return NULL; + } + cdescriptor_pool->pool = GetDescriptorPool(); + return reinterpret_cast(cdescriptor_pool); +} + +PyObject* Python_BuildFile(PyObject* ignored, PyObject* arg) { + char* message_type; + Py_ssize_t message_len; + + if (PyString_AsStringAndSize(arg, &message_type, &message_len) < 0) { + return NULL; + } + + google::protobuf::FileDescriptorProto file_proto; + if (!file_proto.ParseFromArray(message_type, message_len)) { + PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!"); + return NULL; + } + + if (google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + file_proto.name()) != NULL) { + Py_RETURN_NONE; + } + + const google::protobuf::FileDescriptor* descriptor = GetDescriptorPool()->BuildFile( + file_proto); + if (descriptor == NULL) { + PyErr_SetString(PyExc_TypeError, + "Couldn't build proto file into descriptor pool!"); + return NULL; + } + + Py_RETURN_NONE; +} + +bool InitDescriptor() { + CFieldDescriptor_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&CFieldDescriptor_Type) < 0) + return false; + + CDescriptorPool_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&CDescriptorPool_Type) < 0) + return false; + return true; +} + +} // namespace python +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_descriptor.h b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_descriptor.h new file mode 100644 index 0000000..5232680 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_descriptor.h @@ -0,0 +1,87 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: petar@google.com (Petar Petrov) + +#ifndef GOOGLE_PROTOBUF_PYTHON_DESCRIPTOR_H__ +#define GOOGLE_PROTOBUF_PYTHON_DESCRIPTOR_H__ + +#include +#include + +#include + +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +#define PY_SSIZE_T_MAX INT_MAX +#define PY_SSIZE_T_MIN INT_MIN +#endif + +namespace google { +namespace protobuf { +namespace python { + +typedef struct { + PyObject_HEAD + + // The proto2 descriptor that this object represents. + const google::protobuf::FieldDescriptor* descriptor; + + // Full name of the field (PyString). + PyObject* full_name; + + // Name of the field (PyString). + PyObject* name; + + // C++ type of the field (PyLong). + PyObject* cpp_type; + + // Name of the field (PyLong). + PyObject* label; + + // Identity of the descriptor (PyLong used as a poiner). + PyObject* id; +} CFieldDescriptor; + +extern PyTypeObject CFieldDescriptor_Type; + +extern PyTypeObject CDescriptorPool_Type; + + +PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args); +PyObject* Python_BuildFile(PyObject* ignored, PyObject* args); +bool InitDescriptor(); +google::protobuf::DescriptorPool* GetDescriptorPool(); + +} // namespace python +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_PYTHON_DESCRIPTOR_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_protobuf.cc b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_protobuf.cc new file mode 100644 index 0000000..1b1ab5d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_protobuf.cc @@ -0,0 +1,63 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: qrczak@google.com (Marcin Kowalczyk) + +#include + +namespace google { +namespace protobuf { +namespace python { + +static const Message* GetCProtoInsidePyProtoStub(PyObject* msg) { + return NULL; +} +static Message* MutableCProtoInsidePyProtoStub(PyObject* msg) { + return NULL; +} + +// This is initialized with a default, stub implementation. +// If python-google.protobuf.cc is loaded, the function pointer is overridden +// with a full implementation. +const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg) = + GetCProtoInsidePyProtoStub; +Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg) = + MutableCProtoInsidePyProtoStub; + +const Message* GetCProtoInsidePyProto(PyObject* msg) { + return GetCProtoInsidePyProtoPtr(msg); +} +Message* MutableCProtoInsidePyProto(PyObject* msg) { + return MutableCProtoInsidePyProtoPtr(msg); +} + +} // namespace python +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_protobuf.h b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_protobuf.h new file mode 100644 index 0000000..c5b0b1c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/pyext/python_protobuf.h @@ -0,0 +1,57 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: qrczak@google.com (Marcin Kowalczyk) +// +// This module exposes the C proto inside the given Python proto, in +// case the Python proto is implemented with a C proto. + +#ifndef GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ +#define GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ + +#include + +namespace google { +namespace protobuf { + +class Message; + +namespace python { + +// Return the pointer to the C proto inside the given Python proto, +// or NULL when this is not a Python proto implemented with a C proto. +const Message* GetCProtoInsidePyProto(PyObject* msg); +Message* MutableCProtoInsidePyProto(PyObject* msg); + +} // namespace python +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/reflection.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/reflection.py new file mode 100755 index 0000000..9570fd5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/reflection.py @@ -0,0 +1,169 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# This code is meant to work on Python 2.4 and above only. + +"""Contains a metaclass and helper functions used to create +protocol message classes from Descriptor objects at runtime. + +Recall that a metaclass is the "type" of a class. +(A class is to a metaclass what an instance is to a class.) + +In this case, we use the GeneratedProtocolMessageType metaclass +to inject all the useful functionality into the classes +output by the protocol compiler at compile-time. + +The upshot of all this is that the real implementation +details for ALL pure-Python protocol buffers are *here in +this file*. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + + +from google.protobuf.internal import api_implementation +from google.protobuf import descriptor as descriptor_mod +from google.protobuf import message + +_FieldDescriptor = descriptor_mod.FieldDescriptor + + +if api_implementation.Type() == 'cpp': + if api_implementation.Version() == 2: + from google.protobuf.internal.cpp import cpp_message + _NewMessage = cpp_message.NewMessage + _InitMessage = cpp_message.InitMessage + else: + from google.protobuf.internal import cpp_message + _NewMessage = cpp_message.NewMessage + _InitMessage = cpp_message.InitMessage +else: + from google.protobuf.internal import python_message + _NewMessage = python_message.NewMessage + _InitMessage = python_message.InitMessage + + +class GeneratedProtocolMessageType(type): + + """Metaclass for protocol message classes created at runtime from Descriptors. + + We add implementations for all methods described in the Message class. We + also create properties to allow getting/setting all fields in the protocol + message. Finally, we create slots to prevent users from accidentally + "setting" nonexistent fields in the protocol message, which then wouldn't get + serialized / deserialized properly. + + The protocol compiler currently uses this metaclass to create protocol + message classes at runtime. Clients can also manually create their own + classes at runtime, as in this example: + + mydescriptor = Descriptor(.....) + class MyProtoClass(Message): + __metaclass__ = GeneratedProtocolMessageType + DESCRIPTOR = mydescriptor + myproto_instance = MyProtoClass() + myproto.foo_field = 23 + ... + """ + + # Must be consistent with the protocol-compiler code in + # proto2/compiler/internal/generator.*. + _DESCRIPTOR_KEY = 'DESCRIPTOR' + + def __new__(cls, name, bases, dictionary): + """Custom allocation for runtime-generated class types. + + We override __new__ because this is apparently the only place + where we can meaningfully set __slots__ on the class we're creating(?). + (The interplay between metaclasses and slots is not very well-documented). + + Args: + name: Name of the class (ignored, but required by the + metaclass protocol). + bases: Base classes of the class we're constructing. + (Should be message.Message). We ignore this field, but + it's required by the metaclass protocol + dictionary: The class dictionary of the class we're + constructing. dictionary[_DESCRIPTOR_KEY] must contain + a Descriptor object describing this protocol message + type. + + Returns: + Newly-allocated class. + """ + descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] + bases = _NewMessage(bases, descriptor, dictionary) + superclass = super(GeneratedProtocolMessageType, cls) + + new_class = superclass.__new__(cls, name, bases, dictionary) + setattr(descriptor, '_concrete_class', new_class) + return new_class + + def __init__(cls, name, bases, dictionary): + """Here we perform the majority of our work on the class. + We add enum getters, an __init__ method, implementations + of all Message methods, and properties for all fields + in the protocol type. + + Args: + name: Name of the class (ignored, but required by the + metaclass protocol). + bases: Base classes of the class we're constructing. + (Should be message.Message). We ignore this field, but + it's required by the metaclass protocol + dictionary: The class dictionary of the class we're + constructing. dictionary[_DESCRIPTOR_KEY] must contain + a Descriptor object describing this protocol message + type. + """ + descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] + _InitMessage(descriptor, cls) + superclass = super(GeneratedProtocolMessageType, cls) + superclass.__init__(name, bases, dictionary) + + +def ParseMessage(descriptor, byte_str): + """Generate a new Message instance from this Descriptor and a byte string. + + Args: + descriptor: Protobuf Descriptor object + byte_str: Serialized protocol buffer byte string + + Returns: + Newly created protobuf Message object. + """ + + class _ResultClass(message.Message): + __metaclass__ = GeneratedProtocolMessageType + DESCRIPTOR = descriptor + + new_msg = _ResultClass() + new_msg.ParseFromString(byte_str) + return new_msg diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/service.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/service.py new file mode 100755 index 0000000..180b70e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/service.py @@ -0,0 +1,226 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""DEPRECATED: Declares the RPC service interfaces. + +This module declares the abstract interfaces underlying proto2 RPC +services. These are intended to be independent of any particular RPC +implementation, so that proto2 services can be used on top of a variety +of implementations. Starting with version 2.3.0, RPC implementations should +not try to build on these, but should instead provide code generator plugins +which generate code specific to the particular RPC implementation. This way +the generated code can be more appropriate for the implementation in use +and can avoid unnecessary layers of indirection. +""" + +__author__ = 'petar@google.com (Petar Petrov)' + + +class RpcException(Exception): + """Exception raised on failed blocking RPC method call.""" + pass + + +class Service(object): + + """Abstract base interface for protocol-buffer-based RPC services. + + Services themselves are abstract classes (implemented either by servers or as + stubs), but they subclass this base interface. The methods of this + interface can be used to call the methods of the service without knowing + its exact type at compile time (analogous to the Message interface). + """ + + def GetDescriptor(): + """Retrieves this service's descriptor.""" + raise NotImplementedError + + def CallMethod(self, method_descriptor, rpc_controller, + request, done): + """Calls a method of the service specified by method_descriptor. + + If "done" is None then the call is blocking and the response + message will be returned directly. Otherwise the call is asynchronous + and "done" will later be called with the response value. + + In the blocking case, RpcException will be raised on error. + + Preconditions: + * method_descriptor.service == GetDescriptor + * request is of the exact same classes as returned by + GetRequestClass(method). + * After the call has started, the request must not be modified. + * "rpc_controller" is of the correct type for the RPC implementation being + used by this Service. For stubs, the "correct type" depends on the + RpcChannel which the stub is using. + + Postconditions: + * "done" will be called when the method is complete. This may be + before CallMethod() returns or it may be at some point in the future. + * If the RPC failed, the response value passed to "done" will be None. + Further details about the failure can be found by querying the + RpcController. + """ + raise NotImplementedError + + def GetRequestClass(self, method_descriptor): + """Returns the class of the request message for the specified method. + + CallMethod() requires that the request is of a particular subclass of + Message. GetRequestClass() gets the default instance of this required + type. + + Example: + method = service.GetDescriptor().FindMethodByName("Foo") + request = stub.GetRequestClass(method)() + request.ParseFromString(input) + service.CallMethod(method, request, callback) + """ + raise NotImplementedError + + def GetResponseClass(self, method_descriptor): + """Returns the class of the response message for the specified method. + + This method isn't really needed, as the RpcChannel's CallMethod constructs + the response protocol message. It's provided anyway in case it is useful + for the caller to know the response type in advance. + """ + raise NotImplementedError + + +class RpcController(object): + + """An RpcController mediates a single method call. + + The primary purpose of the controller is to provide a way to manipulate + settings specific to the RPC implementation and to find out about RPC-level + errors. The methods provided by the RpcController interface are intended + to be a "least common denominator" set of features which we expect all + implementations to support. Specific implementations may provide more + advanced features (e.g. deadline propagation). + """ + + # Client-side methods below + + def Reset(self): + """Resets the RpcController to its initial state. + + After the RpcController has been reset, it may be reused in + a new call. Must not be called while an RPC is in progress. + """ + raise NotImplementedError + + def Failed(self): + """Returns true if the call failed. + + After a call has finished, returns true if the call failed. The possible + reasons for failure depend on the RPC implementation. Failed() must not + be called before a call has finished. If Failed() returns true, the + contents of the response message are undefined. + """ + raise NotImplementedError + + def ErrorText(self): + """If Failed is true, returns a human-readable description of the error.""" + raise NotImplementedError + + def StartCancel(self): + """Initiate cancellation. + + Advises the RPC system that the caller desires that the RPC call be + canceled. The RPC system may cancel it immediately, may wait awhile and + then cancel it, or may not even cancel the call at all. If the call is + canceled, the "done" callback will still be called and the RpcController + will indicate that the call failed at that time. + """ + raise NotImplementedError + + # Server-side methods below + + def SetFailed(self, reason): + """Sets a failure reason. + + Causes Failed() to return true on the client side. "reason" will be + incorporated into the message returned by ErrorText(). If you find + you need to return machine-readable information about failures, you + should incorporate it into your response protocol buffer and should + NOT call SetFailed(). + """ + raise NotImplementedError + + def IsCanceled(self): + """Checks if the client cancelled the RPC. + + If true, indicates that the client canceled the RPC, so the server may + as well give up on replying to it. The server should still call the + final "done" callback. + """ + raise NotImplementedError + + def NotifyOnCancel(self, callback): + """Sets a callback to invoke on cancel. + + Asks that the given callback be called when the RPC is canceled. The + callback will always be called exactly once. If the RPC completes without + being canceled, the callback will be called after completion. If the RPC + has already been canceled when NotifyOnCancel() is called, the callback + will be called immediately. + + NotifyOnCancel() must be called no more than once per request. + """ + raise NotImplementedError + + +class RpcChannel(object): + + """Abstract interface for an RPC channel. + + An RpcChannel represents a communication line to a service which can be used + to call that service's methods. The service may be running on another + machine. Normally, you should not use an RpcChannel directly, but instead + construct a stub {@link Service} wrapping it. Example: + + Example: + RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234") + RpcController controller = rpcImpl.Controller() + MyService service = MyService_Stub(channel) + service.MyMethod(controller, request, callback) + """ + + def CallMethod(self, method_descriptor, rpc_controller, + request, response_class, done): + """Calls the method identified by the descriptor. + + Call the given method of the remote service. The signature of this + procedure looks the same as Service.CallMethod(), but the requirements + are less strict in one important way: the request object doesn't have to + be of any specific class as long as its descriptor is method.input_type. + """ + raise NotImplementedError diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/service_reflection.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/service_reflection.py new file mode 100755 index 0000000..851e83e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/service_reflection.py @@ -0,0 +1,284 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Contains metaclasses used to create protocol service and service stub +classes from ServiceDescriptor objects at runtime. + +The GeneratedServiceType and GeneratedServiceStubType metaclasses are used to +inject all useful functionality into the classes output by the protocol +compiler at compile-time. +""" + +__author__ = 'petar@google.com (Petar Petrov)' + + +class GeneratedServiceType(type): + + """Metaclass for service classes created at runtime from ServiceDescriptors. + + Implementations for all methods described in the Service class are added here + by this class. We also create properties to allow getting/setting all fields + in the protocol message. + + The protocol compiler currently uses this metaclass to create protocol service + classes at runtime. Clients can also manually create their own classes at + runtime, as in this example: + + mydescriptor = ServiceDescriptor(.....) + class MyProtoService(service.Service): + __metaclass__ = GeneratedServiceType + DESCRIPTOR = mydescriptor + myservice_instance = MyProtoService() + ... + """ + + _DESCRIPTOR_KEY = 'DESCRIPTOR' + + def __init__(cls, name, bases, dictionary): + """Creates a message service class. + + Args: + name: Name of the class (ignored, but required by the metaclass + protocol). + bases: Base classes of the class being constructed. + dictionary: The class dictionary of the class being constructed. + dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object + describing this protocol service type. + """ + # Don't do anything if this class doesn't have a descriptor. This happens + # when a service class is subclassed. + if GeneratedServiceType._DESCRIPTOR_KEY not in dictionary: + return + descriptor = dictionary[GeneratedServiceType._DESCRIPTOR_KEY] + service_builder = _ServiceBuilder(descriptor) + service_builder.BuildService(cls) + + +class GeneratedServiceStubType(GeneratedServiceType): + + """Metaclass for service stubs created at runtime from ServiceDescriptors. + + This class has similar responsibilities as GeneratedServiceType, except that + it creates the service stub classes. + """ + + _DESCRIPTOR_KEY = 'DESCRIPTOR' + + def __init__(cls, name, bases, dictionary): + """Creates a message service stub class. + + Args: + name: Name of the class (ignored, here). + bases: Base classes of the class being constructed. + dictionary: The class dictionary of the class being constructed. + dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object + describing this protocol service type. + """ + super(GeneratedServiceStubType, cls).__init__(name, bases, dictionary) + # Don't do anything if this class doesn't have a descriptor. This happens + # when a service stub is subclassed. + if GeneratedServiceStubType._DESCRIPTOR_KEY not in dictionary: + return + descriptor = dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY] + service_stub_builder = _ServiceStubBuilder(descriptor) + service_stub_builder.BuildServiceStub(cls) + + +class _ServiceBuilder(object): + + """This class constructs a protocol service class using a service descriptor. + + Given a service descriptor, this class constructs a class that represents + the specified service descriptor. One service builder instance constructs + exactly one service class. That means all instances of that class share the + same builder. + """ + + def __init__(self, service_descriptor): + """Initializes an instance of the service class builder. + + Args: + service_descriptor: ServiceDescriptor to use when constructing the + service class. + """ + self.descriptor = service_descriptor + + def BuildService(self, cls): + """Constructs the service class. + + Args: + cls: The class that will be constructed. + """ + + # CallMethod needs to operate with an instance of the Service class. This + # internal wrapper function exists only to be able to pass the service + # instance to the method that does the real CallMethod work. + def _WrapCallMethod(srvc, method_descriptor, + rpc_controller, request, callback): + return self._CallMethod(srvc, method_descriptor, + rpc_controller, request, callback) + self.cls = cls + cls.CallMethod = _WrapCallMethod + cls.GetDescriptor = staticmethod(lambda: self.descriptor) + cls.GetDescriptor.__doc__ = "Returns the service descriptor." + cls.GetRequestClass = self._GetRequestClass + cls.GetResponseClass = self._GetResponseClass + for method in self.descriptor.methods: + setattr(cls, method.name, self._GenerateNonImplementedMethod(method)) + + def _CallMethod(self, srvc, method_descriptor, + rpc_controller, request, callback): + """Calls the method described by a given method descriptor. + + Args: + srvc: Instance of the service for which this method is called. + method_descriptor: Descriptor that represent the method to call. + rpc_controller: RPC controller to use for this method's execution. + request: Request protocol message. + callback: A callback to invoke after the method has completed. + """ + if method_descriptor.containing_service != self.descriptor: + raise RuntimeError( + 'CallMethod() given method descriptor for wrong service type.') + method = getattr(srvc, method_descriptor.name) + return method(rpc_controller, request, callback) + + def _GetRequestClass(self, method_descriptor): + """Returns the class of the request protocol message. + + Args: + method_descriptor: Descriptor of the method for which to return the + request protocol message class. + + Returns: + A class that represents the input protocol message of the specified + method. + """ + if method_descriptor.containing_service != self.descriptor: + raise RuntimeError( + 'GetRequestClass() given method descriptor for wrong service type.') + return method_descriptor.input_type._concrete_class + + def _GetResponseClass(self, method_descriptor): + """Returns the class of the response protocol message. + + Args: + method_descriptor: Descriptor of the method for which to return the + response protocol message class. + + Returns: + A class that represents the output protocol message of the specified + method. + """ + if method_descriptor.containing_service != self.descriptor: + raise RuntimeError( + 'GetResponseClass() given method descriptor for wrong service type.') + return method_descriptor.output_type._concrete_class + + def _GenerateNonImplementedMethod(self, method): + """Generates and returns a method that can be set for a service methods. + + Args: + method: Descriptor of the service method for which a method is to be + generated. + + Returns: + A method that can be added to the service class. + """ + return lambda inst, rpc_controller, request, callback: ( + self._NonImplementedMethod(method.name, rpc_controller, callback)) + + def _NonImplementedMethod(self, method_name, rpc_controller, callback): + """The body of all methods in the generated service class. + + Args: + method_name: Name of the method being executed. + rpc_controller: RPC controller used to execute this method. + callback: A callback which will be invoked when the method finishes. + """ + rpc_controller.SetFailed('Method %s not implemented.' % method_name) + callback(None) + + +class _ServiceStubBuilder(object): + + """Constructs a protocol service stub class using a service descriptor. + + Given a service descriptor, this class constructs a suitable stub class. + A stub is just a type-safe wrapper around an RpcChannel which emulates a + local implementation of the service. + + One service stub builder instance constructs exactly one class. It means all + instances of that class share the same service stub builder. + """ + + def __init__(self, service_descriptor): + """Initializes an instance of the service stub class builder. + + Args: + service_descriptor: ServiceDescriptor to use when constructing the + stub class. + """ + self.descriptor = service_descriptor + + def BuildServiceStub(self, cls): + """Constructs the stub class. + + Args: + cls: The class that will be constructed. + """ + + def _ServiceStubInit(stub, rpc_channel): + stub.rpc_channel = rpc_channel + self.cls = cls + cls.__init__ = _ServiceStubInit + for method in self.descriptor.methods: + setattr(cls, method.name, self._GenerateStubMethod(method)) + + def _GenerateStubMethod(self, method): + return (lambda inst, rpc_controller, request, callback=None: + self._StubMethod(inst, method, rpc_controller, request, callback)) + + def _StubMethod(self, stub, method_descriptor, + rpc_controller, request, callback): + """The body of all service methods in the generated stub class. + + Args: + stub: Stub instance. + method_descriptor: Descriptor of the invoked method. + rpc_controller: Rpc controller to execute the method. + request: Request protocol message. + callback: A callback to execute when the method finishes. + Returns: + Response message (in case of blocking call). + """ + return stub.rpc_channel.CallMethod( + method_descriptor, rpc_controller, request, + method_descriptor.output_type._concrete_class, callback) diff --git a/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/text_format.py b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/text_format.py new file mode 100755 index 0000000..24dd07f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/google/protobuf/text_format.py @@ -0,0 +1,739 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Contains routines for printing protocol messages in text format.""" + +__author__ = 'kenton@google.com (Kenton Varda)' + +import cStringIO +import re + +from collections import deque +from google.protobuf.internal import type_checkers +from google.protobuf import descriptor + +__all__ = [ 'MessageToString', 'PrintMessage', 'PrintField', + 'PrintFieldValue', 'Merge' ] + + +_INTEGER_CHECKERS = (type_checkers.Uint32ValueChecker(), + type_checkers.Int32ValueChecker(), + type_checkers.Uint64ValueChecker(), + type_checkers.Int64ValueChecker()) +_FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?', re.IGNORECASE) +_FLOAT_NAN = re.compile('nanf?', re.IGNORECASE) + + +class ParseError(Exception): + """Thrown in case of ASCII parsing error.""" + + +def MessageToString(message, as_utf8=False, as_one_line=False): + out = cStringIO.StringIO() + PrintMessage(message, out, as_utf8=as_utf8, as_one_line=as_one_line) + result = out.getvalue() + out.close() + if as_one_line: + return result.rstrip() + return result + + +def PrintMessage(message, out, indent=0, as_utf8=False, as_one_line=False): + for field, value in message.ListFields(): + if field.label == descriptor.FieldDescriptor.LABEL_REPEATED: + for element in value: + PrintField(field, element, out, indent, as_utf8, as_one_line) + else: + PrintField(field, value, out, indent, as_utf8, as_one_line) + + +def PrintField(field, value, out, indent=0, as_utf8=False, as_one_line=False): + """Print a single field name/value pair. For repeated fields, the value + should be a single element.""" + + out.write(' ' * indent); + if field.is_extension: + out.write('[') + if (field.containing_type.GetOptions().message_set_wire_format and + field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and + field.message_type == field.extension_scope and + field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL): + out.write(field.message_type.full_name) + else: + out.write(field.full_name) + out.write(']') + elif field.type == descriptor.FieldDescriptor.TYPE_GROUP: + # For groups, use the capitalized name. + out.write(field.message_type.name) + else: + out.write(field.name) + + if field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE: + # The colon is optional in this case, but our cross-language golden files + # don't include it. + out.write(': ') + + PrintFieldValue(field, value, out, indent, as_utf8, as_one_line) + if as_one_line: + out.write(' ') + else: + out.write('\n') + + +def PrintFieldValue(field, value, out, indent=0, + as_utf8=False, as_one_line=False): + """Print a single field value (not including name). For repeated fields, + the value should be a single element.""" + + if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: + if as_one_line: + out.write(' { ') + PrintMessage(value, out, indent, as_utf8, as_one_line) + out.write('}') + else: + out.write(' {\n') + PrintMessage(value, out, indent + 2, as_utf8, as_one_line) + out.write(' ' * indent + '}') + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: + enum_value = field.enum_type.values_by_number.get(value, None) + if enum_value is not None: + out.write(enum_value.name) + else: + out.write(str(value)) + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: + out.write('\"') + if type(value) is unicode: + out.write(_CEscape(value.encode('utf-8'), as_utf8)) + else: + out.write(_CEscape(value, as_utf8)) + out.write('\"') + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: + if value: + out.write("true") + else: + out.write("false") + else: + out.write(str(value)) + + +def Merge(text, message): + """Merges an ASCII representation of a protocol message into a message. + + Args: + text: Message ASCII representation. + message: A protocol buffer message to merge into. + + Raises: + ParseError: On ASCII parsing problems. + """ + tokenizer = _Tokenizer(text) + while not tokenizer.AtEnd(): + _MergeField(tokenizer, message) + + +def _MergeField(tokenizer, message): + """Merges a single protocol message field into a message. + + Args: + tokenizer: A tokenizer to parse the field name and values. + message: A protocol message to record the data. + + Raises: + ParseError: In case of ASCII parsing problems. + """ + message_descriptor = message.DESCRIPTOR + if tokenizer.TryConsume('['): + name = [tokenizer.ConsumeIdentifier()] + while tokenizer.TryConsume('.'): + name.append(tokenizer.ConsumeIdentifier()) + name = '.'.join(name) + + if not message_descriptor.is_extendable: + raise tokenizer.ParseErrorPreviousToken( + 'Message type "%s" does not have extensions.' % + message_descriptor.full_name) + field = message.Extensions._FindExtensionByName(name) + if not field: + raise tokenizer.ParseErrorPreviousToken( + 'Extension "%s" not registered.' % name) + elif message_descriptor != field.containing_type: + raise tokenizer.ParseErrorPreviousToken( + 'Extension "%s" does not extend message type "%s".' % ( + name, message_descriptor.full_name)) + tokenizer.Consume(']') + else: + name = tokenizer.ConsumeIdentifier() + field = message_descriptor.fields_by_name.get(name, None) + + # Group names are expected to be capitalized as they appear in the + # .proto file, which actually matches their type names, not their field + # names. + if not field: + field = message_descriptor.fields_by_name.get(name.lower(), None) + if field and field.type != descriptor.FieldDescriptor.TYPE_GROUP: + field = None + + if (field and field.type == descriptor.FieldDescriptor.TYPE_GROUP and + field.message_type.name != name): + field = None + + if not field: + raise tokenizer.ParseErrorPreviousToken( + 'Message type "%s" has no field named "%s".' % ( + message_descriptor.full_name, name)) + + if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: + tokenizer.TryConsume(':') + + if tokenizer.TryConsume('<'): + end_token = '>' + else: + tokenizer.Consume('{') + end_token = '}' + + if field.label == descriptor.FieldDescriptor.LABEL_REPEATED: + if field.is_extension: + sub_message = message.Extensions[field].add() + else: + sub_message = getattr(message, field.name).add() + else: + if field.is_extension: + sub_message = message.Extensions[field] + else: + sub_message = getattr(message, field.name) + sub_message.SetInParent() + + while not tokenizer.TryConsume(end_token): + if tokenizer.AtEnd(): + raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token)) + _MergeField(tokenizer, sub_message) + else: + _MergeScalarField(tokenizer, message, field) + + +def _MergeScalarField(tokenizer, message, field): + """Merges a single protocol message scalar field into a message. + + Args: + tokenizer: A tokenizer to parse the field value. + message: A protocol message to record the data. + field: The descriptor of the field to be merged. + + Raises: + ParseError: In case of ASCII parsing problems. + RuntimeError: On runtime errors. + """ + tokenizer.Consume(':') + value = None + + if field.type in (descriptor.FieldDescriptor.TYPE_INT32, + descriptor.FieldDescriptor.TYPE_SINT32, + descriptor.FieldDescriptor.TYPE_SFIXED32): + value = tokenizer.ConsumeInt32() + elif field.type in (descriptor.FieldDescriptor.TYPE_INT64, + descriptor.FieldDescriptor.TYPE_SINT64, + descriptor.FieldDescriptor.TYPE_SFIXED64): + value = tokenizer.ConsumeInt64() + elif field.type in (descriptor.FieldDescriptor.TYPE_UINT32, + descriptor.FieldDescriptor.TYPE_FIXED32): + value = tokenizer.ConsumeUint32() + elif field.type in (descriptor.FieldDescriptor.TYPE_UINT64, + descriptor.FieldDescriptor.TYPE_FIXED64): + value = tokenizer.ConsumeUint64() + elif field.type in (descriptor.FieldDescriptor.TYPE_FLOAT, + descriptor.FieldDescriptor.TYPE_DOUBLE): + value = tokenizer.ConsumeFloat() + elif field.type == descriptor.FieldDescriptor.TYPE_BOOL: + value = tokenizer.ConsumeBool() + elif field.type == descriptor.FieldDescriptor.TYPE_STRING: + value = tokenizer.ConsumeString() + elif field.type == descriptor.FieldDescriptor.TYPE_BYTES: + value = tokenizer.ConsumeByteString() + elif field.type == descriptor.FieldDescriptor.TYPE_ENUM: + value = tokenizer.ConsumeEnum(field) + else: + raise RuntimeError('Unknown field type %d' % field.type) + + if field.label == descriptor.FieldDescriptor.LABEL_REPEATED: + if field.is_extension: + message.Extensions[field].append(value) + else: + getattr(message, field.name).append(value) + else: + if field.is_extension: + message.Extensions[field] = value + else: + setattr(message, field.name, value) + + +class _Tokenizer(object): + """Protocol buffer ASCII representation tokenizer. + + This class handles the lower level string parsing by splitting it into + meaningful tokens. + + It was directly ported from the Java protocol buffer API. + """ + + _WHITESPACE = re.compile('(\\s|(#.*$))+', re.MULTILINE) + _TOKEN = re.compile( + '[a-zA-Z_][0-9a-zA-Z_+-]*|' # an identifier + '[0-9+-][0-9a-zA-Z_.+-]*|' # a number + '\"([^\"\n\\\\]|\\\\.)*(\"|\\\\?$)|' # a double-quoted string + '\'([^\'\n\\\\]|\\\\.)*(\'|\\\\?$)') # a single-quoted string + _IDENTIFIER = re.compile('\w+') + + def __init__(self, text_message): + self._text_message = text_message + + self._position = 0 + self._line = -1 + self._column = 0 + self._token_start = None + self.token = '' + self._lines = deque(text_message.split('\n')) + self._current_line = '' + self._previous_line = 0 + self._previous_column = 0 + self._SkipWhitespace() + self.NextToken() + + def AtEnd(self): + """Checks the end of the text was reached. + + Returns: + True iff the end was reached. + """ + return self.token == '' + + def _PopLine(self): + while len(self._current_line) <= self._column: + if not self._lines: + self._current_line = '' + return + self._line += 1 + self._column = 0 + self._current_line = self._lines.popleft() + + def _SkipWhitespace(self): + while True: + self._PopLine() + match = self._WHITESPACE.match(self._current_line, self._column) + if not match: + break + length = len(match.group(0)) + self._column += length + + def TryConsume(self, token): + """Tries to consume a given piece of text. + + Args: + token: Text to consume. + + Returns: + True iff the text was consumed. + """ + if self.token == token: + self.NextToken() + return True + return False + + def Consume(self, token): + """Consumes a piece of text. + + Args: + token: Text to consume. + + Raises: + ParseError: If the text couldn't be consumed. + """ + if not self.TryConsume(token): + raise self._ParseError('Expected "%s".' % token) + + def ConsumeIdentifier(self): + """Consumes protocol message field identifier. + + Returns: + Identifier string. + + Raises: + ParseError: If an identifier couldn't be consumed. + """ + result = self.token + if not self._IDENTIFIER.match(result): + raise self._ParseError('Expected identifier.') + self.NextToken() + return result + + def ConsumeInt32(self): + """Consumes a signed 32bit integer number. + + Returns: + The integer parsed. + + Raises: + ParseError: If a signed 32bit integer couldn't be consumed. + """ + try: + result = ParseInteger(self.token, is_signed=True, is_long=False) + except ValueError, e: + raise self._ParseError(str(e)) + self.NextToken() + return result + + def ConsumeUint32(self): + """Consumes an unsigned 32bit integer number. + + Returns: + The integer parsed. + + Raises: + ParseError: If an unsigned 32bit integer couldn't be consumed. + """ + try: + result = ParseInteger(self.token, is_signed=False, is_long=False) + except ValueError, e: + raise self._ParseError(str(e)) + self.NextToken() + return result + + def ConsumeInt64(self): + """Consumes a signed 64bit integer number. + + Returns: + The integer parsed. + + Raises: + ParseError: If a signed 64bit integer couldn't be consumed. + """ + try: + result = ParseInteger(self.token, is_signed=True, is_long=True) + except ValueError, e: + raise self._ParseError(str(e)) + self.NextToken() + return result + + def ConsumeUint64(self): + """Consumes an unsigned 64bit integer number. + + Returns: + The integer parsed. + + Raises: + ParseError: If an unsigned 64bit integer couldn't be consumed. + """ + try: + result = ParseInteger(self.token, is_signed=False, is_long=True) + except ValueError, e: + raise self._ParseError(str(e)) + self.NextToken() + return result + + def ConsumeFloat(self): + """Consumes an floating point number. + + Returns: + The number parsed. + + Raises: + ParseError: If a floating point number couldn't be consumed. + """ + try: + result = ParseFloat(self.token) + except ValueError, e: + raise self._ParseError(str(e)) + self.NextToken() + return result + + def ConsumeBool(self): + """Consumes a boolean value. + + Returns: + The bool parsed. + + Raises: + ParseError: If a boolean value couldn't be consumed. + """ + try: + result = ParseBool(self.token) + except ValueError, e: + raise self._ParseError(str(e)) + self.NextToken() + return result + + def ConsumeString(self): + """Consumes a string value. + + Returns: + The string parsed. + + Raises: + ParseError: If a string value couldn't be consumed. + """ + bytes = self.ConsumeByteString() + try: + return unicode(bytes, 'utf-8') + except UnicodeDecodeError, e: + raise self._StringParseError(e) + + def ConsumeByteString(self): + """Consumes a byte array value. + + Returns: + The array parsed (as a string). + + Raises: + ParseError: If a byte array value couldn't be consumed. + """ + list = [self._ConsumeSingleByteString()] + while len(self.token) > 0 and self.token[0] in ('\'', '"'): + list.append(self._ConsumeSingleByteString()) + return "".join(list) + + def _ConsumeSingleByteString(self): + """Consume one token of a string literal. + + String literals (whether bytes or text) can come in multiple adjacent + tokens which are automatically concatenated, like in C or Python. This + method only consumes one token. + """ + text = self.token + if len(text) < 1 or text[0] not in ('\'', '"'): + raise self._ParseError('Expected string.') + + if len(text) < 2 or text[-1] != text[0]: + raise self._ParseError('String missing ending quote.') + + try: + result = _CUnescape(text[1:-1]) + except ValueError, e: + raise self._ParseError(str(e)) + self.NextToken() + return result + + def ConsumeEnum(self, field): + try: + result = ParseEnum(field, self.token) + except ValueError, e: + raise self._ParseError(str(e)) + self.NextToken() + return result + + def ParseErrorPreviousToken(self, message): + """Creates and *returns* a ParseError for the previously read token. + + Args: + message: A message to set for the exception. + + Returns: + A ParseError instance. + """ + return ParseError('%d:%d : %s' % ( + self._previous_line + 1, self._previous_column + 1, message)) + + def _ParseError(self, message): + """Creates and *returns* a ParseError for the current token.""" + return ParseError('%d:%d : %s' % ( + self._line + 1, self._column + 1, message)) + + def _StringParseError(self, e): + return self._ParseError('Couldn\'t parse string: ' + str(e)) + + def NextToken(self): + """Reads the next meaningful token.""" + self._previous_line = self._line + self._previous_column = self._column + + self._column += len(self.token) + self._SkipWhitespace() + + if not self._lines and len(self._current_line) <= self._column: + self.token = '' + return + + match = self._TOKEN.match(self._current_line, self._column) + if match: + token = match.group(0) + self.token = token + else: + self.token = self._current_line[self._column] + + +# text.encode('string_escape') does not seem to satisfy our needs as it +# encodes unprintable characters using two-digit hex escapes whereas our +# C++ unescaping function allows hex escapes to be any length. So, +# "\0011".encode('string_escape') ends up being "\\x011", which will be +# decoded in C++ as a single-character string with char code 0x11. +def _CEscape(text, as_utf8): + def escape(c): + o = ord(c) + if o == 10: return r"\n" # optional escape + if o == 13: return r"\r" # optional escape + if o == 9: return r"\t" # optional escape + if o == 39: return r"\'" # optional escape + + if o == 34: return r'\"' # necessary escape + if o == 92: return r"\\" # necessary escape + + # necessary escapes + if not as_utf8 and (o >= 127 or o < 32): return "\\%03o" % o + return c + return "".join([escape(c) for c in text]) + + +_CUNESCAPE_HEX = re.compile(r'(\\+)x([0-9a-fA-F])(?![0-9a-fA-F])') + + +def _CUnescape(text): + def ReplaceHex(m): + # Only replace the match if the number of leading back slashes is odd. i.e. + # the slash itself is not escaped. + if len(m.group(1)) & 1: + return m.group(1) + 'x0' + m.group(2) + return m.group(0) + + # This is required because the 'string_escape' encoding doesn't + # allow single-digit hex escapes (like '\xf'). + result = _CUNESCAPE_HEX.sub(ReplaceHex, text) + return result.decode('string_escape') + + +def ParseInteger(text, is_signed=False, is_long=False): + """Parses an integer. + + Args: + text: The text to parse. + is_signed: True if a signed integer must be parsed. + is_long: True if a long integer must be parsed. + + Returns: + The integer value. + + Raises: + ValueError: Thrown Iff the text is not a valid integer. + """ + # Do the actual parsing. Exception handling is propagated to caller. + try: + result = int(text, 0) + except ValueError: + raise ValueError('Couldn\'t parse integer: %s' % text) + + # Check if the integer is sane. Exceptions handled by callers. + checker = _INTEGER_CHECKERS[2 * int(is_long) + int(is_signed)] + checker.CheckValue(result) + return result + + +def ParseFloat(text): + """Parse a floating point number. + + Args: + text: Text to parse. + + Returns: + The number parsed. + + Raises: + ValueError: If a floating point number couldn't be parsed. + """ + try: + # Assume Python compatible syntax. + return float(text) + except ValueError: + # Check alternative spellings. + if _FLOAT_INFINITY.match(text): + if text[0] == '-': + return float('-inf') + else: + return float('inf') + elif _FLOAT_NAN.match(text): + return float('nan') + else: + # assume '1.0f' format + try: + return float(text.rstrip('f')) + except ValueError: + raise ValueError('Couldn\'t parse float: %s' % text) + + +def ParseBool(text): + """Parse a boolean value. + + Args: + text: Text to parse. + + Returns: + Boolean values parsed + + Raises: + ValueError: If text is not a valid boolean. + """ + if text in ('true', 't', '1'): + return True + elif text in ('false', 'f', '0'): + return False + else: + raise ValueError('Expected "true" or "false".') + + +def ParseEnum(field, value): + """Parse an enum value. + + The value can be specified by a number (the enum value), or by + a string literal (the enum name). + + Args: + field: Enum field descriptor. + value: String value. + + Returns: + Enum value number. + + Raises: + ValueError: If the enum value could not be parsed. + """ + enum_descriptor = field.enum_type + try: + number = int(value, 0) + except ValueError: + # Identifier. + enum_value = enum_descriptor.values_by_name.get(value, None) + if enum_value is None: + raise ValueError( + 'Enum type "%s" has no value named %s.' % ( + enum_descriptor.full_name, value)) + else: + # Numeric value. + enum_value = enum_descriptor.values_by_number.get(number, None) + if enum_value is None: + raise ValueError( + 'Enum type "%s" has no value with number %d.' % ( + enum_descriptor.full_name, number)) + return enum_value.number diff --git a/cpp/thirdparty/protobuf-2.5.0/python/mox.py b/cpp/thirdparty/protobuf-2.5.0/python/mox.py new file mode 100755 index 0000000..ce80ba5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/mox.py @@ -0,0 +1,1401 @@ +#!/usr/bin/python2.4 +# +# Copyright 2008 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file is used for testing. The original is at: +# http://code.google.com/p/pymox/ + +"""Mox, an object-mocking framework for Python. + +Mox works in the record-replay-verify paradigm. When you first create +a mock object, it is in record mode. You then programmatically set +the expected behavior of the mock object (what methods are to be +called on it, with what parameters, what they should return, and in +what order). + +Once you have set up the expected mock behavior, you put it in replay +mode. Now the mock responds to method calls just as you told it to. +If an unexpected method (or an expected method with unexpected +parameters) is called, then an exception will be raised. + +Once you are done interacting with the mock, you need to verify that +all the expected interactions occured. (Maybe your code exited +prematurely without calling some cleanup method!) The verify phase +ensures that every expected method was called; otherwise, an exception +will be raised. + +Suggested usage / workflow: + + # Create Mox factory + my_mox = Mox() + + # Create a mock data access object + mock_dao = my_mox.CreateMock(DAOClass) + + # Set up expected behavior + mock_dao.RetrievePersonWithIdentifier('1').AndReturn(person) + mock_dao.DeletePerson(person) + + # Put mocks in replay mode + my_mox.ReplayAll() + + # Inject mock object and run test + controller.SetDao(mock_dao) + controller.DeletePersonById('1') + + # Verify all methods were called as expected + my_mox.VerifyAll() +""" + +from collections import deque +import re +import types +import unittest + +import stubout + +class Error(AssertionError): + """Base exception for this module.""" + + pass + + +class ExpectedMethodCallsError(Error): + """Raised when Verify() is called before all expected methods have been called + """ + + def __init__(self, expected_methods): + """Init exception. + + Args: + # expected_methods: A sequence of MockMethod objects that should have been + # called. + expected_methods: [MockMethod] + + Raises: + ValueError: if expected_methods contains no methods. + """ + + if not expected_methods: + raise ValueError("There must be at least one expected method") + Error.__init__(self) + self._expected_methods = expected_methods + + def __str__(self): + calls = "\n".join(["%3d. %s" % (i, m) + for i, m in enumerate(self._expected_methods)]) + return "Verify: Expected methods never called:\n%s" % (calls,) + + +class UnexpectedMethodCallError(Error): + """Raised when an unexpected method is called. + + This can occur if a method is called with incorrect parameters, or out of the + specified order. + """ + + def __init__(self, unexpected_method, expected): + """Init exception. + + Args: + # unexpected_method: MockMethod that was called but was not at the head of + # the expected_method queue. + # expected: MockMethod or UnorderedGroup the method should have + # been in. + unexpected_method: MockMethod + expected: MockMethod or UnorderedGroup + """ + + Error.__init__(self) + self._unexpected_method = unexpected_method + self._expected = expected + + def __str__(self): + return "Unexpected method call: %s. Expecting: %s" % \ + (self._unexpected_method, self._expected) + + +class UnknownMethodCallError(Error): + """Raised if an unknown method is requested of the mock object.""" + + def __init__(self, unknown_method_name): + """Init exception. + + Args: + # unknown_method_name: Method call that is not part of the mocked class's + # public interface. + unknown_method_name: str + """ + + Error.__init__(self) + self._unknown_method_name = unknown_method_name + + def __str__(self): + return "Method called is not a member of the object: %s" % \ + self._unknown_method_name + + +class Mox(object): + """Mox: a factory for creating mock objects.""" + + # A list of types that should be stubbed out with MockObjects (as + # opposed to MockAnythings). + _USE_MOCK_OBJECT = [types.ClassType, types.InstanceType, types.ModuleType, + types.ObjectType, types.TypeType] + + def __init__(self): + """Initialize a new Mox.""" + + self._mock_objects = [] + self.stubs = stubout.StubOutForTesting() + + def CreateMock(self, class_to_mock): + """Create a new mock object. + + Args: + # class_to_mock: the class to be mocked + class_to_mock: class + + Returns: + MockObject that can be used as the class_to_mock would be. + """ + + new_mock = MockObject(class_to_mock) + self._mock_objects.append(new_mock) + return new_mock + + def CreateMockAnything(self): + """Create a mock that will accept any method calls. + + This does not enforce an interface. + """ + + new_mock = MockAnything() + self._mock_objects.append(new_mock) + return new_mock + + def ReplayAll(self): + """Set all mock objects to replay mode.""" + + for mock_obj in self._mock_objects: + mock_obj._Replay() + + + def VerifyAll(self): + """Call verify on all mock objects created.""" + + for mock_obj in self._mock_objects: + mock_obj._Verify() + + def ResetAll(self): + """Call reset on all mock objects. This does not unset stubs.""" + + for mock_obj in self._mock_objects: + mock_obj._Reset() + + def StubOutWithMock(self, obj, attr_name, use_mock_anything=False): + """Replace a method, attribute, etc. with a Mock. + + This will replace a class or module with a MockObject, and everything else + (method, function, etc) with a MockAnything. This can be overridden to + always use a MockAnything by setting use_mock_anything to True. + + Args: + obj: A Python object (class, module, instance, callable). + attr_name: str. The name of the attribute to replace with a mock. + use_mock_anything: bool. True if a MockAnything should be used regardless + of the type of attribute. + """ + + attr_to_replace = getattr(obj, attr_name) + if type(attr_to_replace) in self._USE_MOCK_OBJECT and not use_mock_anything: + stub = self.CreateMock(attr_to_replace) + else: + stub = self.CreateMockAnything() + + self.stubs.Set(obj, attr_name, stub) + + def UnsetStubs(self): + """Restore stubs to their original state.""" + + self.stubs.UnsetAll() + +def Replay(*args): + """Put mocks into Replay mode. + + Args: + # args is any number of mocks to put into replay mode. + """ + + for mock in args: + mock._Replay() + + +def Verify(*args): + """Verify mocks. + + Args: + # args is any number of mocks to be verified. + """ + + for mock in args: + mock._Verify() + + +def Reset(*args): + """Reset mocks. + + Args: + # args is any number of mocks to be reset. + """ + + for mock in args: + mock._Reset() + + +class MockAnything: + """A mock that can be used to mock anything. + + This is helpful for mocking classes that do not provide a public interface. + """ + + def __init__(self): + """ """ + self._Reset() + + def __getattr__(self, method_name): + """Intercept method calls on this object. + + A new MockMethod is returned that is aware of the MockAnything's + state (record or replay). The call will be recorded or replayed + by the MockMethod's __call__. + + Args: + # method name: the name of the method being called. + method_name: str + + Returns: + A new MockMethod aware of MockAnything's state (record or replay). + """ + + return self._CreateMockMethod(method_name) + + def _CreateMockMethod(self, method_name): + """Create a new mock method call and return it. + + Args: + # method name: the name of the method being called. + method_name: str + + Returns: + A new MockMethod aware of MockAnything's state (record or replay). + """ + + return MockMethod(method_name, self._expected_calls_queue, + self._replay_mode) + + def __nonzero__(self): + """Return 1 for nonzero so the mock can be used as a conditional.""" + + return 1 + + def __eq__(self, rhs): + """Provide custom logic to compare objects.""" + + return (isinstance(rhs, MockAnything) and + self._replay_mode == rhs._replay_mode and + self._expected_calls_queue == rhs._expected_calls_queue) + + def __ne__(self, rhs): + """Provide custom logic to compare objects.""" + + return not self == rhs + + def _Replay(self): + """Start replaying expected method calls.""" + + self._replay_mode = True + + def _Verify(self): + """Verify that all of the expected calls have been made. + + Raises: + ExpectedMethodCallsError: if there are still more method calls in the + expected queue. + """ + + # If the list of expected calls is not empty, raise an exception + if self._expected_calls_queue: + # The last MultipleTimesGroup is not popped from the queue. + if (len(self._expected_calls_queue) == 1 and + isinstance(self._expected_calls_queue[0], MultipleTimesGroup) and + self._expected_calls_queue[0].IsSatisfied()): + pass + else: + raise ExpectedMethodCallsError(self._expected_calls_queue) + + def _Reset(self): + """Reset the state of this mock to record mode with an empty queue.""" + + # Maintain a list of method calls we are expecting + self._expected_calls_queue = deque() + + # Make sure we are in setup mode, not replay mode + self._replay_mode = False + + +class MockObject(MockAnything, object): + """A mock object that simulates the public/protected interface of a class.""" + + def __init__(self, class_to_mock): + """Initialize a mock object. + + This determines the methods and properties of the class and stores them. + + Args: + # class_to_mock: class to be mocked + class_to_mock: class + """ + + # This is used to hack around the mixin/inheritance of MockAnything, which + # is not a proper object (it can be anything. :-) + MockAnything.__dict__['__init__'](self) + + # Get a list of all the public and special methods we should mock. + self._known_methods = set() + self._known_vars = set() + self._class_to_mock = class_to_mock + for method in dir(class_to_mock): + if callable(getattr(class_to_mock, method)): + self._known_methods.add(method) + else: + self._known_vars.add(method) + + def __getattr__(self, name): + """Intercept attribute request on this object. + + If the attribute is a public class variable, it will be returned and not + recorded as a call. + + If the attribute is not a variable, it is handled like a method + call. The method name is checked against the set of mockable + methods, and a new MockMethod is returned that is aware of the + MockObject's state (record or replay). The call will be recorded + or replayed by the MockMethod's __call__. + + Args: + # name: the name of the attribute being requested. + name: str + + Returns: + Either a class variable or a new MockMethod that is aware of the state + of the mock (record or replay). + + Raises: + UnknownMethodCallError if the MockObject does not mock the requested + method. + """ + + if name in self._known_vars: + return getattr(self._class_to_mock, name) + + if name in self._known_methods: + return self._CreateMockMethod(name) + + raise UnknownMethodCallError(name) + + def __eq__(self, rhs): + """Provide custom logic to compare objects.""" + + return (isinstance(rhs, MockObject) and + self._class_to_mock == rhs._class_to_mock and + self._replay_mode == rhs._replay_mode and + self._expected_calls_queue == rhs._expected_calls_queue) + + def __setitem__(self, key, value): + """Provide custom logic for mocking classes that support item assignment. + + Args: + key: Key to set the value for. + value: Value to set. + + Returns: + Expected return value in replay mode. A MockMethod object for the + __setitem__ method that has already been called if not in replay mode. + + Raises: + TypeError if the underlying class does not support item assignment. + UnexpectedMethodCallError if the object does not expect the call to + __setitem__. + + """ + setitem = self._class_to_mock.__dict__.get('__setitem__', None) + + # Verify the class supports item assignment. + if setitem is None: + raise TypeError('object does not support item assignment') + + # If we are in replay mode then simply call the mock __setitem__ method. + if self._replay_mode: + return MockMethod('__setitem__', self._expected_calls_queue, + self._replay_mode)(key, value) + + + # Otherwise, create a mock method __setitem__. + return self._CreateMockMethod('__setitem__')(key, value) + + def __getitem__(self, key): + """Provide custom logic for mocking classes that are subscriptable. + + Args: + key: Key to return the value for. + + Returns: + Expected return value in replay mode. A MockMethod object for the + __getitem__ method that has already been called if not in replay mode. + + Raises: + TypeError if the underlying class is not subscriptable. + UnexpectedMethodCallError if the object does not expect the call to + __setitem__. + + """ + getitem = self._class_to_mock.__dict__.get('__getitem__', None) + + # Verify the class supports item assignment. + if getitem is None: + raise TypeError('unsubscriptable object') + + # If we are in replay mode then simply call the mock __getitem__ method. + if self._replay_mode: + return MockMethod('__getitem__', self._expected_calls_queue, + self._replay_mode)(key) + + + # Otherwise, create a mock method __getitem__. + return self._CreateMockMethod('__getitem__')(key) + + def __call__(self, *params, **named_params): + """Provide custom logic for mocking classes that are callable.""" + + # Verify the class we are mocking is callable + callable = self._class_to_mock.__dict__.get('__call__', None) + if callable is None: + raise TypeError('Not callable') + + # Because the call is happening directly on this object instead of a method, + # the call on the mock method is made right here + mock_method = self._CreateMockMethod('__call__') + return mock_method(*params, **named_params) + + @property + def __class__(self): + """Return the class that is being mocked.""" + + return self._class_to_mock + + +class MockMethod(object): + """Callable mock method. + + A MockMethod should act exactly like the method it mocks, accepting parameters + and returning a value, or throwing an exception (as specified). When this + method is called, it can optionally verify whether the called method (name and + signature) matches the expected method. + """ + + def __init__(self, method_name, call_queue, replay_mode): + """Construct a new mock method. + + Args: + # method_name: the name of the method + # call_queue: deque of calls, verify this call against the head, or add + # this call to the queue. + # replay_mode: False if we are recording, True if we are verifying calls + # against the call queue. + method_name: str + call_queue: list or deque + replay_mode: bool + """ + + self._name = method_name + self._call_queue = call_queue + if not isinstance(call_queue, deque): + self._call_queue = deque(self._call_queue) + self._replay_mode = replay_mode + + self._params = None + self._named_params = None + self._return_value = None + self._exception = None + self._side_effects = None + + def __call__(self, *params, **named_params): + """Log parameters and return the specified return value. + + If the Mock(Anything/Object) associated with this call is in record mode, + this MockMethod will be pushed onto the expected call queue. If the mock + is in replay mode, this will pop a MockMethod off the top of the queue and + verify this call is equal to the expected call. + + Raises: + UnexpectedMethodCall if this call is supposed to match an expected method + call and it does not. + """ + + self._params = params + self._named_params = named_params + + if not self._replay_mode: + self._call_queue.append(self) + return self + + expected_method = self._VerifyMethodCall() + + if expected_method._side_effects: + expected_method._side_effects(*params, **named_params) + + if expected_method._exception: + raise expected_method._exception + + return expected_method._return_value + + def __getattr__(self, name): + """Raise an AttributeError with a helpful message.""" + + raise AttributeError('MockMethod has no attribute "%s". ' + 'Did you remember to put your mocks in replay mode?' % name) + + def _PopNextMethod(self): + """Pop the next method from our call queue.""" + try: + return self._call_queue.popleft() + except IndexError: + raise UnexpectedMethodCallError(self, None) + + def _VerifyMethodCall(self): + """Verify the called method is expected. + + This can be an ordered method, or part of an unordered set. + + Returns: + The expected mock method. + + Raises: + UnexpectedMethodCall if the method called was not expected. + """ + + expected = self._PopNextMethod() + + # Loop here, because we might have a MethodGroup followed by another + # group. + while isinstance(expected, MethodGroup): + expected, method = expected.MethodCalled(self) + if method is not None: + return method + + # This is a mock method, so just check equality. + if expected != self: + raise UnexpectedMethodCallError(self, expected) + + return expected + + def __str__(self): + params = ', '.join( + [repr(p) for p in self._params or []] + + ['%s=%r' % x for x in sorted((self._named_params or {}).items())]) + desc = "%s(%s) -> %r" % (self._name, params, self._return_value) + return desc + + def __eq__(self, rhs): + """Test whether this MockMethod is equivalent to another MockMethod. + + Args: + # rhs: the right hand side of the test + rhs: MockMethod + """ + + return (isinstance(rhs, MockMethod) and + self._name == rhs._name and + self._params == rhs._params and + self._named_params == rhs._named_params) + + def __ne__(self, rhs): + """Test whether this MockMethod is not equivalent to another MockMethod. + + Args: + # rhs: the right hand side of the test + rhs: MockMethod + """ + + return not self == rhs + + def GetPossibleGroup(self): + """Returns a possible group from the end of the call queue or None if no + other methods are on the stack. + """ + + # Remove this method from the tail of the queue so we can add it to a group. + this_method = self._call_queue.pop() + assert this_method == self + + # Determine if the tail of the queue is a group, or just a regular ordered + # mock method. + group = None + try: + group = self._call_queue[-1] + except IndexError: + pass + + return group + + def _CheckAndCreateNewGroup(self, group_name, group_class): + """Checks if the last method (a possible group) is an instance of our + group_class. Adds the current method to this group or creates a new one. + + Args: + + group_name: the name of the group. + group_class: the class used to create instance of this new group + """ + group = self.GetPossibleGroup() + + # If this is a group, and it is the correct group, add the method. + if isinstance(group, group_class) and group.group_name() == group_name: + group.AddMethod(self) + return self + + # Create a new group and add the method. + new_group = group_class(group_name) + new_group.AddMethod(self) + self._call_queue.append(new_group) + return self + + def InAnyOrder(self, group_name="default"): + """Move this method into a group of unordered calls. + + A group of unordered calls must be defined together, and must be executed + in full before the next expected method can be called. There can be + multiple groups that are expected serially, if they are given + different group names. The same group name can be reused if there is a + standard method call, or a group with a different name, spliced between + usages. + + Args: + group_name: the name of the unordered group. + + Returns: + self + """ + return self._CheckAndCreateNewGroup(group_name, UnorderedGroup) + + def MultipleTimes(self, group_name="default"): + """Move this method into group of calls which may be called multiple times. + + A group of repeating calls must be defined together, and must be executed in + full before the next expected mehtod can be called. + + Args: + group_name: the name of the unordered group. + + Returns: + self + """ + return self._CheckAndCreateNewGroup(group_name, MultipleTimesGroup) + + def AndReturn(self, return_value): + """Set the value to return when this method is called. + + Args: + # return_value can be anything. + """ + + self._return_value = return_value + return return_value + + def AndRaise(self, exception): + """Set the exception to raise when this method is called. + + Args: + # exception: the exception to raise when this method is called. + exception: Exception + """ + + self._exception = exception + + def WithSideEffects(self, side_effects): + """Set the side effects that are simulated when this method is called. + + Args: + side_effects: A callable which modifies the parameters or other relevant + state which a given test case depends on. + + Returns: + Self for chaining with AndReturn and AndRaise. + """ + self._side_effects = side_effects + return self + +class Comparator: + """Base class for all Mox comparators. + + A Comparator can be used as a parameter to a mocked method when the exact + value is not known. For example, the code you are testing might build up a + long SQL string that is passed to your mock DAO. You're only interested that + the IN clause contains the proper primary keys, so you can set your mock + up as follows: + + mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result) + + Now whatever query is passed in must contain the string 'IN (1, 2, 4, 5)'. + + A Comparator may replace one or more parameters, for example: + # return at most 10 rows + mock_dao.RunQuery(StrContains('SELECT'), 10) + + or + + # Return some non-deterministic number of rows + mock_dao.RunQuery(StrContains('SELECT'), IsA(int)) + """ + + def equals(self, rhs): + """Special equals method that all comparators must implement. + + Args: + rhs: any python object + """ + + raise NotImplementedError, 'method must be implemented by a subclass.' + + def __eq__(self, rhs): + return self.equals(rhs) + + def __ne__(self, rhs): + return not self.equals(rhs) + + +class IsA(Comparator): + """This class wraps a basic Python type or class. It is used to verify + that a parameter is of the given type or class. + + Example: + mock_dao.Connect(IsA(DbConnectInfo)) + """ + + def __init__(self, class_name): + """Initialize IsA + + Args: + class_name: basic python type or a class + """ + + self._class_name = class_name + + def equals(self, rhs): + """Check to see if the RHS is an instance of class_name. + + Args: + # rhs: the right hand side of the test + rhs: object + + Returns: + bool + """ + + try: + return isinstance(rhs, self._class_name) + except TypeError: + # Check raw types if there was a type error. This is helpful for + # things like cStringIO.StringIO. + return type(rhs) == type(self._class_name) + + def __repr__(self): + return str(self._class_name) + +class IsAlmost(Comparator): + """Comparison class used to check whether a parameter is nearly equal + to a given value. Generally useful for floating point numbers. + + Example mock_dao.SetTimeout((IsAlmost(3.9))) + """ + + def __init__(self, float_value, places=7): + """Initialize IsAlmost. + + Args: + float_value: The value for making the comparison. + places: The number of decimal places to round to. + """ + + self._float_value = float_value + self._places = places + + def equals(self, rhs): + """Check to see if RHS is almost equal to float_value + + Args: + rhs: the value to compare to float_value + + Returns: + bool + """ + + try: + return round(rhs-self._float_value, self._places) == 0 + except TypeError: + # This is probably because either float_value or rhs is not a number. + return False + + def __repr__(self): + return str(self._float_value) + +class StrContains(Comparator): + """Comparison class used to check whether a substring exists in a + string parameter. This can be useful in mocking a database with SQL + passed in as a string parameter, for example. + + Example: + mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result) + """ + + def __init__(self, search_string): + """Initialize. + + Args: + # search_string: the string you are searching for + search_string: str + """ + + self._search_string = search_string + + def equals(self, rhs): + """Check to see if the search_string is contained in the rhs string. + + Args: + # rhs: the right hand side of the test + rhs: object + + Returns: + bool + """ + + try: + return rhs.find(self._search_string) > -1 + except Exception: + return False + + def __repr__(self): + return '' % self._search_string + + +class Regex(Comparator): + """Checks if a string matches a regular expression. + + This uses a given regular expression to determine equality. + """ + + def __init__(self, pattern, flags=0): + """Initialize. + + Args: + # pattern is the regular expression to search for + pattern: str + # flags passed to re.compile function as the second argument + flags: int + """ + + self.regex = re.compile(pattern, flags=flags) + + def equals(self, rhs): + """Check to see if rhs matches regular expression pattern. + + Returns: + bool + """ + + return self.regex.search(rhs) is not None + + def __repr__(self): + s = '' % self._key + + +class ContainsKeyValue(Comparator): + """Checks whether a key/value pair is in a dict parameter. + + Example: + mock_dao.UpdateUsers(ContainsKeyValue('stevepm', stevepm_user_info)) + """ + + def __init__(self, key, value): + """Initialize. + + Args: + # key: a key in a dict + # value: the corresponding value + """ + + self._key = key + self._value = value + + def equals(self, rhs): + """Check whether the given key/value pair is in the rhs dict. + + Returns: + bool + """ + + try: + return rhs[self._key] == self._value + except Exception: + return False + + def __repr__(self): + return '' % (self._key, self._value) + + +class SameElementsAs(Comparator): + """Checks whether iterables contain the same elements (ignoring order). + + Example: + mock_dao.ProcessUsers(SameElementsAs('stevepm', 'salomaki')) + """ + + def __init__(self, expected_seq): + """Initialize. + + Args: + expected_seq: a sequence + """ + + self._expected_seq = expected_seq + + def equals(self, actual_seq): + """Check to see whether actual_seq has same elements as expected_seq. + + Args: + actual_seq: sequence + + Returns: + bool + """ + + try: + expected = dict([(element, None) for element in self._expected_seq]) + actual = dict([(element, None) for element in actual_seq]) + except TypeError: + # Fall back to slower list-compare if any of the objects are unhashable. + expected = list(self._expected_seq) + actual = list(actual_seq) + expected.sort() + actual.sort() + return expected == actual + + def __repr__(self): + return '' % self._expected_seq + + +class And(Comparator): + """Evaluates one or more Comparators on RHS and returns an AND of the results. + """ + + def __init__(self, *args): + """Initialize. + + Args: + *args: One or more Comparator + """ + + self._comparators = args + + def equals(self, rhs): + """Checks whether all Comparators are equal to rhs. + + Args: + # rhs: can be anything + + Returns: + bool + """ + + for comparator in self._comparators: + if not comparator.equals(rhs): + return False + + return True + + def __repr__(self): + return '' % str(self._comparators) + + +class Or(Comparator): + """Evaluates one or more Comparators on RHS and returns an OR of the results. + """ + + def __init__(self, *args): + """Initialize. + + Args: + *args: One or more Mox comparators + """ + + self._comparators = args + + def equals(self, rhs): + """Checks whether any Comparator is equal to rhs. + + Args: + # rhs: can be anything + + Returns: + bool + """ + + for comparator in self._comparators: + if comparator.equals(rhs): + return True + + return False + + def __repr__(self): + return '' % str(self._comparators) + + +class Func(Comparator): + """Call a function that should verify the parameter passed in is correct. + + You may need the ability to perform more advanced operations on the parameter + in order to validate it. You can use this to have a callable validate any + parameter. The callable should return either True or False. + + + Example: + + def myParamValidator(param): + # Advanced logic here + return True + + mock_dao.DoSomething(Func(myParamValidator), true) + """ + + def __init__(self, func): + """Initialize. + + Args: + func: callable that takes one parameter and returns a bool + """ + + self._func = func + + def equals(self, rhs): + """Test whether rhs passes the function test. + + rhs is passed into func. + + Args: + rhs: any python object + + Returns: + the result of func(rhs) + """ + + return self._func(rhs) + + def __repr__(self): + return str(self._func) + + +class IgnoreArg(Comparator): + """Ignore an argument. + + This can be used when we don't care about an argument of a method call. + + Example: + # Check if CastMagic is called with 3 as first arg and 'disappear' as third. + mymock.CastMagic(3, IgnoreArg(), 'disappear') + """ + + def equals(self, unused_rhs): + """Ignores arguments and returns True. + + Args: + unused_rhs: any python object + + Returns: + always returns True + """ + + return True + + def __repr__(self): + return '' + + +class MethodGroup(object): + """Base class containing common behaviour for MethodGroups.""" + + def __init__(self, group_name): + self._group_name = group_name + + def group_name(self): + return self._group_name + + def __str__(self): + return '<%s "%s">' % (self.__class__.__name__, self._group_name) + + def AddMethod(self, mock_method): + raise NotImplementedError + + def MethodCalled(self, mock_method): + raise NotImplementedError + + def IsSatisfied(self): + raise NotImplementedError + +class UnorderedGroup(MethodGroup): + """UnorderedGroup holds a set of method calls that may occur in any order. + + This construct is helpful for non-deterministic events, such as iterating + over the keys of a dict. + """ + + def __init__(self, group_name): + super(UnorderedGroup, self).__init__(group_name) + self._methods = [] + + def AddMethod(self, mock_method): + """Add a method to this group. + + Args: + mock_method: A mock method to be added to this group. + """ + + self._methods.append(mock_method) + + def MethodCalled(self, mock_method): + """Remove a method call from the group. + + If the method is not in the set, an UnexpectedMethodCallError will be + raised. + + Args: + mock_method: a mock method that should be equal to a method in the group. + + Returns: + The mock method from the group + + Raises: + UnexpectedMethodCallError if the mock_method was not in the group. + """ + + # Check to see if this method exists, and if so, remove it from the set + # and return it. + for method in self._methods: + if method == mock_method: + # Remove the called mock_method instead of the method in the group. + # The called method will match any comparators when equality is checked + # during removal. The method in the group could pass a comparator to + # another comparator during the equality check. + self._methods.remove(mock_method) + + # If this group is not empty, put it back at the head of the queue. + if not self.IsSatisfied(): + mock_method._call_queue.appendleft(self) + + return self, method + + raise UnexpectedMethodCallError(mock_method, self) + + def IsSatisfied(self): + """Return True if there are not any methods in this group.""" + + return len(self._methods) == 0 + + +class MultipleTimesGroup(MethodGroup): + """MultipleTimesGroup holds methods that may be called any number of times. + + Note: Each method must be called at least once. + + This is helpful, if you don't know or care how many times a method is called. + """ + + def __init__(self, group_name): + super(MultipleTimesGroup, self).__init__(group_name) + self._methods = set() + self._methods_called = set() + + def AddMethod(self, mock_method): + """Add a method to this group. + + Args: + mock_method: A mock method to be added to this group. + """ + + self._methods.add(mock_method) + + def MethodCalled(self, mock_method): + """Remove a method call from the group. + + If the method is not in the set, an UnexpectedMethodCallError will be + raised. + + Args: + mock_method: a mock method that should be equal to a method in the group. + + Returns: + The mock method from the group + + Raises: + UnexpectedMethodCallError if the mock_method was not in the group. + """ + + # Check to see if this method exists, and if so add it to the set of + # called methods. + + for method in self._methods: + if method == mock_method: + self._methods_called.add(mock_method) + # Always put this group back on top of the queue, because we don't know + # when we are done. + mock_method._call_queue.appendleft(self) + return self, method + + if self.IsSatisfied(): + next_method = mock_method._PopNextMethod(); + return next_method, None + else: + raise UnexpectedMethodCallError(mock_method, self) + + def IsSatisfied(self): + """Return True if all methods in this group are called at least once.""" + # NOTE(psycho): We can't use the simple set difference here because we want + # to match different parameters which are considered the same e.g. IsA(str) + # and some string. This solution is O(n^2) but n should be small. + tmp = self._methods.copy() + for called in self._methods_called: + for expected in tmp: + if called == expected: + tmp.remove(expected) + if not tmp: + return True + break + return False + + +class MoxMetaTestBase(type): + """Metaclass to add mox cleanup and verification to every test. + + As the mox unit testing class is being constructed (MoxTestBase or a + subclass), this metaclass will modify all test functions to call the + CleanUpMox method of the test class after they finish. This means that + unstubbing and verifying will happen for every test with no additional code, + and any failures will result in test failures as opposed to errors. + """ + + def __init__(cls, name, bases, d): + type.__init__(cls, name, bases, d) + + # also get all the attributes from the base classes to account + # for a case when test class is not the immediate child of MoxTestBase + for base in bases: + for attr_name in dir(base): + d[attr_name] = getattr(base, attr_name) + + for func_name, func in d.items(): + if func_name.startswith('test') and callable(func): + setattr(cls, func_name, MoxMetaTestBase.CleanUpTest(cls, func)) + + @staticmethod + def CleanUpTest(cls, func): + """Adds Mox cleanup code to any MoxTestBase method. + + Always unsets stubs after a test. Will verify all mocks for tests that + otherwise pass. + + Args: + cls: MoxTestBase or subclass; the class whose test method we are altering. + func: method; the method of the MoxTestBase test class we wish to alter. + + Returns: + The modified method. + """ + def new_method(self, *args, **kwargs): + mox_obj = getattr(self, 'mox', None) + cleanup_mox = False + if mox_obj and isinstance(mox_obj, Mox): + cleanup_mox = True + try: + func(self, *args, **kwargs) + finally: + if cleanup_mox: + mox_obj.UnsetStubs() + if cleanup_mox: + mox_obj.VerifyAll() + new_method.__name__ = func.__name__ + new_method.__doc__ = func.__doc__ + new_method.__module__ = func.__module__ + return new_method + + +class MoxTestBase(unittest.TestCase): + """Convenience test class to make stubbing easier. + + Sets up a "mox" attribute which is an instance of Mox - any mox tests will + want this. Also automatically unsets any stubs and verifies that all mock + methods have been called at the end of each test, eliminating boilerplate + code. + """ + + __metaclass__ = MoxMetaTestBase + + def setUp(self): + self.mox = Mox() diff --git a/cpp/thirdparty/protobuf-2.5.0/python/setup.py b/cpp/thirdparty/protobuf-2.5.0/python/setup.py new file mode 100755 index 0000000..777839a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/setup.py @@ -0,0 +1,196 @@ +#! /usr/bin/python +# +# See README for usage instructions. +import sys +import os +import subprocess + +# We must use setuptools, not distutils, because we need to use the +# namespace_packages option for the "google" package. +try: + from setuptools import setup, Extension +except ImportError: + try: + from ez_setup import use_setuptools + use_setuptools() + from setuptools import setup, Extension + except ImportError: + sys.stderr.write( + "Could not import setuptools; make sure you have setuptools or " + "ez_setup installed.\n") + raise +from distutils.command.clean import clean as _clean +from distutils.command.build_py import build_py as _build_py +from distutils.spawn import find_executable + +maintainer_email = "protobuf@googlegroups.com" + +# Find the Protocol Compiler. +if 'PROTOC' in os.environ and os.path.exists(os.environ['PROTOC']): + protoc = os.environ['PROTOC'] +elif os.path.exists("../src/protoc"): + protoc = "../src/protoc" +elif os.path.exists("../src/protoc.exe"): + protoc = "../src/protoc.exe" +elif os.path.exists("../vsprojects/Debug/protoc.exe"): + protoc = "../vsprojects/Debug/protoc.exe" +elif os.path.exists("../vsprojects/Release/protoc.exe"): + protoc = "../vsprojects/Release/protoc.exe" +else: + protoc = find_executable("protoc") + +def generate_proto(source): + """Invokes the Protocol Compiler to generate a _pb2.py from the given + .proto file. Does nothing if the output already exists and is newer than + the input.""" + + output = source.replace(".proto", "_pb2.py").replace("../src/", "") + + if (not os.path.exists(output) or + (os.path.exists(source) and + os.path.getmtime(source) > os.path.getmtime(output))): + print "Generating %s..." % output + + if not os.path.exists(source): + sys.stderr.write("Can't find required file: %s\n" % source) + sys.exit(-1) + + if protoc == None: + sys.stderr.write( + "protoc is not installed nor found in ../src. Please compile it " + "or install the binary package.\n") + sys.exit(-1) + + protoc_command = [ protoc, "-I../src", "-I.", "--python_out=.", source ] + if subprocess.call(protoc_command) != 0: + sys.exit(-1) + +def GenerateUnittestProtos(): + generate_proto("../src/google/protobuf/unittest.proto") + generate_proto("../src/google/protobuf/unittest_custom_options.proto") + generate_proto("../src/google/protobuf/unittest_import.proto") + generate_proto("../src/google/protobuf/unittest_import_public.proto") + generate_proto("../src/google/protobuf/unittest_mset.proto") + generate_proto("../src/google/protobuf/unittest_no_generic_services.proto") + generate_proto("google/protobuf/internal/test_bad_identifiers.proto") + generate_proto("google/protobuf/internal/more_extensions.proto") + generate_proto("google/protobuf/internal/more_extensions_dynamic.proto") + generate_proto("google/protobuf/internal/more_messages.proto") + generate_proto("google/protobuf/internal/factory_test1.proto") + generate_proto("google/protobuf/internal/factory_test2.proto") + +def MakeTestSuite(): + # This is apparently needed on some systems to make sure that the tests + # work even if a previous version is already installed. + if 'google' in sys.modules: + del sys.modules['google'] + GenerateUnittestProtos() + + import unittest + import google.protobuf.internal.generator_test as generator_test + import google.protobuf.internal.descriptor_test as descriptor_test + import google.protobuf.internal.reflection_test as reflection_test + import google.protobuf.internal.service_reflection_test \ + as service_reflection_test + import google.protobuf.internal.text_format_test as text_format_test + import google.protobuf.internal.wire_format_test as wire_format_test + import google.protobuf.internal.unknown_fields_test as unknown_fields_test + import google.protobuf.internal.descriptor_database_test \ + as descriptor_database_test + import google.protobuf.internal.descriptor_pool_test as descriptor_pool_test + import google.protobuf.internal.message_factory_test as message_factory_test + import google.protobuf.internal.message_cpp_test as message_cpp_test + import google.protobuf.internal.reflection_cpp_generated_test \ + as reflection_cpp_generated_test + + loader = unittest.defaultTestLoader + suite = unittest.TestSuite() + for test in [ generator_test, + descriptor_test, + reflection_test, + service_reflection_test, + text_format_test, + wire_format_test ]: + suite.addTest(loader.loadTestsFromModule(test)) + + return suite + + +class clean(_clean): + def run(self): + # Delete generated files in the code tree. + for (dirpath, dirnames, filenames) in os.walk("."): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \ + filepath.endswith(".so") or filepath.endswith(".o") or \ + filepath.endswith('google/protobuf/compiler/__init__.py'): + os.remove(filepath) + # _clean is an old-style class, so super() doesn't work. + _clean.run(self) + +class build_py(_build_py): + def run(self): + # Generate necessary .proto file if it doesn't exist. + generate_proto("../src/google/protobuf/descriptor.proto") + generate_proto("../src/google/protobuf/compiler/plugin.proto") + + GenerateUnittestProtos() + # Make sure google.protobuf.compiler is a valid package. + open('google/protobuf/compiler/__init__.py', 'a').close() + # _build_py is an old-style class, so super() doesn't work. + _build_py.run(self) + +if __name__ == '__main__': + ext_module_list = [] + + # C++ implementation extension + if os.getenv("PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION", "python") == "cpp": + print "Using EXPERIMENTAL C++ Implmenetation." + ext_module_list.append(Extension( + "google.protobuf.internal._net_proto2___python", + [ "google/protobuf/pyext/python_descriptor.cc", + "google/protobuf/pyext/python_protobuf.cc", + "google/protobuf/pyext/python-proto2.cc" ], + include_dirs = [ "." ], + libraries = [ "protobuf" ])) + + setup(name = 'protobuf', + version = '2.5.0', + packages = [ 'google' ], + namespace_packages = [ 'google' ], + test_suite = 'setup.MakeTestSuite', + # Must list modules explicitly so that we don't install tests. + py_modules = [ + 'google.protobuf.internal.api_implementation', + 'google.protobuf.internal.containers', + 'google.protobuf.internal.cpp_message', + 'google.protobuf.internal.decoder', + 'google.protobuf.internal.encoder', + 'google.protobuf.internal.enum_type_wrapper', + 'google.protobuf.internal.message_listener', + 'google.protobuf.internal.python_message', + 'google.protobuf.internal.type_checkers', + 'google.protobuf.internal.wire_format', + 'google.protobuf.descriptor', + 'google.protobuf.descriptor_pb2', + 'google.protobuf.compiler.plugin_pb2', + 'google.protobuf.message', + 'google.protobuf.descriptor_database', + 'google.protobuf.descriptor_pool', + 'google.protobuf.message_factory', + 'google.protobuf.reflection', + 'google.protobuf.service', + 'google.protobuf.service_reflection', + 'google.protobuf.text_format' ], + cmdclass = { 'clean': clean, 'build_py': build_py }, + install_requires = ['setuptools'], + ext_modules = ext_module_list, + url = 'http://code.google.com/p/protobuf/', + maintainer = maintainer_email, + maintainer_email = 'protobuf@googlegroups.com', + license = 'New BSD License', + description = 'Protocol Buffers', + long_description = + "Protocol Buffers are Google's data interchange format.", + ) diff --git a/cpp/thirdparty/protobuf-2.5.0/python/stubout.py b/cpp/thirdparty/protobuf-2.5.0/python/stubout.py new file mode 100755 index 0000000..aee4f2d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/python/stubout.py @@ -0,0 +1,140 @@ +#!/usr/bin/python2.4 +# +# Copyright 2008 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file is used for testing. The original is at: +# http://code.google.com/p/pymox/ + +class StubOutForTesting: + """Sample Usage: + You want os.path.exists() to always return true during testing. + + stubs = StubOutForTesting() + stubs.Set(os.path, 'exists', lambda x: 1) + ... + stubs.UnsetAll() + + The above changes os.path.exists into a lambda that returns 1. Once + the ... part of the code finishes, the UnsetAll() looks up the old value + of os.path.exists and restores it. + + """ + def __init__(self): + self.cache = [] + self.stubs = [] + + def __del__(self): + self.SmartUnsetAll() + self.UnsetAll() + + def SmartSet(self, obj, attr_name, new_attr): + """Replace obj.attr_name with new_attr. This method is smart and works + at the module, class, and instance level while preserving proper + inheritance. It will not stub out C types however unless that has been + explicitly allowed by the type. + + This method supports the case where attr_name is a staticmethod or a + classmethod of obj. + + Notes: + - If obj is an instance, then it is its class that will actually be + stubbed. Note that the method Set() does not do that: if obj is + an instance, it (and not its class) will be stubbed. + - The stubbing is using the builtin getattr and setattr. So, the __get__ + and __set__ will be called when stubbing (TODO: A better idea would + probably be to manipulate obj.__dict__ instead of getattr() and + setattr()). + + Raises AttributeError if the attribute cannot be found. + """ + if (inspect.ismodule(obj) or + (not inspect.isclass(obj) and obj.__dict__.has_key(attr_name))): + orig_obj = obj + orig_attr = getattr(obj, attr_name) + + else: + if not inspect.isclass(obj): + mro = list(inspect.getmro(obj.__class__)) + else: + mro = list(inspect.getmro(obj)) + + mro.reverse() + + orig_attr = None + + for cls in mro: + try: + orig_obj = cls + orig_attr = getattr(obj, attr_name) + except AttributeError: + continue + + if orig_attr is None: + raise AttributeError("Attribute not found.") + + # Calling getattr() on a staticmethod transforms it to a 'normal' function. + # We need to ensure that we put it back as a staticmethod. + old_attribute = obj.__dict__.get(attr_name) + if old_attribute is not None and isinstance(old_attribute, staticmethod): + orig_attr = staticmethod(orig_attr) + + self.stubs.append((orig_obj, attr_name, orig_attr)) + setattr(orig_obj, attr_name, new_attr) + + def SmartUnsetAll(self): + """Reverses all the SmartSet() calls, restoring things to their original + definition. Its okay to call SmartUnsetAll() repeatedly, as later calls + have no effect if no SmartSet() calls have been made. + + """ + self.stubs.reverse() + + for args in self.stubs: + setattr(*args) + + self.stubs = [] + + def Set(self, parent, child_name, new_child): + """Replace child_name's old definition with new_child, in the context + of the given parent. The parent could be a module when the child is a + function at module scope. Or the parent could be a class when a class' + method is being replaced. The named child is set to new_child, while + the prior definition is saved away for later, when UnsetAll() is called. + + This method supports the case where child_name is a staticmethod or a + classmethod of parent. + """ + old_child = getattr(parent, child_name) + + old_attribute = parent.__dict__.get(child_name) + if old_attribute is not None and isinstance(old_attribute, staticmethod): + old_child = staticmethod(old_child) + + self.cache.append((parent, old_child, child_name)) + setattr(parent, child_name, new_child) + + def UnsetAll(self): + """Reverses all the Set() calls, restoring things to their original + definition. Its okay to call UnsetAll() repeatedly, as later calls have + no effect if no Set() calls have been made. + + """ + # Undo calls to Set() in reverse order, in case Set() was called on the + # same arguments repeatedly (want the original call to be last one undone) + self.cache.reverse() + + for (parent, old_child, child_name) in self.cache: + setattr(parent, child_name, old_child) + self.cache = [] diff --git a/cpp/thirdparty/protobuf-2.5.0/src/Makefile.am b/cpp/thirdparty/protobuf-2.5.0/src/Makefile.am new file mode 100644 index 0000000..df733d9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/Makefile.am @@ -0,0 +1,395 @@ +## Process this file with automake to produce Makefile.in + +if HAVE_ZLIB +GZCHECKPROGRAMS = zcgzip zcgunzip +GZHEADERS = google/protobuf/io/gzip_stream.h +GZTESTS = google/protobuf/io/gzip_stream_unittest.sh +else +GZCHECKPROGRAMS = +GZHEADERS = +GZTESTS = +endif + +if GCC +# These are good warnings to turn on by default +NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare +else +NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) +endif + +AM_CXXFLAGS = $(NO_OPT_CXXFLAGS) $(PROTOBUF_OPT_FLAG) + +AM_LDFLAGS = $(PTHREAD_CFLAGS) + +# If I say "dist_include_DATA", automake complains that $(includedir) is not +# a "legitimate" directory for DATA. Screw you, automake. +protodir = $(includedir) +nobase_dist_proto_DATA = google/protobuf/descriptor.proto \ + google/protobuf/compiler/plugin.proto + +# Not sure why these don't get cleaned automatically. +clean-local: + rm -f *.loT + +CLEANFILES = $(protoc_outputs) unittest_proto_middleman \ + testzip.jar testzip.list testzip.proto testzip.zip + +MAINTAINERCLEANFILES = \ + Makefile.in + +nobase_include_HEADERS = \ + google/protobuf/stubs/atomicops.h \ + google/protobuf/stubs/atomicops_internals_arm_gcc.h \ + google/protobuf/stubs/atomicops_internals_arm_qnx.h \ + google/protobuf/stubs/atomicops_internals_atomicword_compat.h \ + google/protobuf/stubs/atomicops_internals_macosx.h \ + google/protobuf/stubs/atomicops_internals_mips_gcc.h \ + google/protobuf/stubs/atomicops_internals_pnacl.h \ + google/protobuf/stubs/atomicops_internals_x86_gcc.h \ + google/protobuf/stubs/atomicops_internals_x86_msvc.h \ + google/protobuf/stubs/common.h \ + google/protobuf/stubs/platform_macros.h \ + google/protobuf/stubs/once.h \ + google/protobuf/stubs/template_util.h \ + google/protobuf/stubs/type_traits.h \ + google/protobuf/descriptor.h \ + google/protobuf/descriptor.pb.h \ + google/protobuf/descriptor_database.h \ + google/protobuf/dynamic_message.h \ + google/protobuf/extension_set.h \ + google/protobuf/generated_enum_reflection.h \ + google/protobuf/generated_message_util.h \ + google/protobuf/generated_message_reflection.h \ + google/protobuf/message.h \ + google/protobuf/message_lite.h \ + google/protobuf/reflection_ops.h \ + google/protobuf/repeated_field.h \ + google/protobuf/service.h \ + google/protobuf/text_format.h \ + google/protobuf/unknown_field_set.h \ + google/protobuf/wire_format.h \ + google/protobuf/wire_format_lite.h \ + google/protobuf/wire_format_lite_inl.h \ + google/protobuf/io/coded_stream.h \ + $(GZHEADERS) \ + google/protobuf/io/printer.h \ + google/protobuf/io/tokenizer.h \ + google/protobuf/io/zero_copy_stream.h \ + google/protobuf/io/zero_copy_stream_impl.h \ + google/protobuf/io/zero_copy_stream_impl_lite.h \ + google/protobuf/compiler/code_generator.h \ + google/protobuf/compiler/command_line_interface.h \ + google/protobuf/compiler/importer.h \ + google/protobuf/compiler/parser.h \ + google/protobuf/compiler/plugin.h \ + google/protobuf/compiler/plugin.pb.h \ + google/protobuf/compiler/cpp/cpp_generator.h \ + google/protobuf/compiler/java/java_generator.h \ + google/protobuf/compiler/python/python_generator.h + +lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la + +libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS) +libprotobuf_lite_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined +libprotobuf_lite_la_SOURCES = \ + google/protobuf/stubs/atomicops_internals_x86_gcc.cc \ + google/protobuf/stubs/atomicops_internals_x86_msvc.cc \ + google/protobuf/stubs/common.cc \ + google/protobuf/stubs/once.cc \ + google/protobuf/stubs/hash.h \ + google/protobuf/stubs/map-util.h \ + google/protobuf/stubs/stl_util.h \ + google/protobuf/stubs/stringprintf.cc \ + google/protobuf/stubs/stringprintf.h \ + google/protobuf/extension_set.cc \ + google/protobuf/generated_message_util.cc \ + google/protobuf/message_lite.cc \ + google/protobuf/repeated_field.cc \ + google/protobuf/wire_format_lite.cc \ + google/protobuf/io/coded_stream.cc \ + google/protobuf/io/coded_stream_inl.h \ + google/protobuf/io/zero_copy_stream.cc \ + google/protobuf/io/zero_copy_stream_impl_lite.cc + +libprotobuf_la_LIBADD = $(PTHREAD_LIBS) +libprotobuf_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined +libprotobuf_la_SOURCES = \ + $(libprotobuf_lite_la_SOURCES) \ + google/protobuf/stubs/strutil.cc \ + google/protobuf/stubs/strutil.h \ + google/protobuf/stubs/substitute.cc \ + google/protobuf/stubs/substitute.h \ + google/protobuf/stubs/structurally_valid.cc \ + google/protobuf/descriptor.cc \ + google/protobuf/descriptor.pb.cc \ + google/protobuf/descriptor_database.cc \ + google/protobuf/dynamic_message.cc \ + google/protobuf/extension_set_heavy.cc \ + google/protobuf/generated_message_reflection.cc \ + google/protobuf/message.cc \ + google/protobuf/reflection_ops.cc \ + google/protobuf/service.cc \ + google/protobuf/text_format.cc \ + google/protobuf/unknown_field_set.cc \ + google/protobuf/wire_format.cc \ + google/protobuf/io/gzip_stream.cc \ + google/protobuf/io/printer.cc \ + google/protobuf/io/tokenizer.cc \ + google/protobuf/io/zero_copy_stream_impl.cc \ + google/protobuf/compiler/importer.cc \ + google/protobuf/compiler/parser.cc + +libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la +libprotoc_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined +libprotoc_la_SOURCES = \ + google/protobuf/compiler/code_generator.cc \ + google/protobuf/compiler/command_line_interface.cc \ + google/protobuf/compiler/plugin.cc \ + google/protobuf/compiler/plugin.pb.cc \ + google/protobuf/compiler/subprocess.cc \ + google/protobuf/compiler/subprocess.h \ + google/protobuf/compiler/zip_writer.cc \ + google/protobuf/compiler/zip_writer.h \ + google/protobuf/compiler/cpp/cpp_enum.cc \ + google/protobuf/compiler/cpp/cpp_enum.h \ + google/protobuf/compiler/cpp/cpp_enum_field.cc \ + google/protobuf/compiler/cpp/cpp_enum_field.h \ + google/protobuf/compiler/cpp/cpp_extension.cc \ + google/protobuf/compiler/cpp/cpp_extension.h \ + google/protobuf/compiler/cpp/cpp_field.cc \ + google/protobuf/compiler/cpp/cpp_field.h \ + google/protobuf/compiler/cpp/cpp_file.cc \ + google/protobuf/compiler/cpp/cpp_file.h \ + google/protobuf/compiler/cpp/cpp_generator.cc \ + google/protobuf/compiler/cpp/cpp_helpers.cc \ + google/protobuf/compiler/cpp/cpp_helpers.h \ + google/protobuf/compiler/cpp/cpp_message.cc \ + google/protobuf/compiler/cpp/cpp_message.h \ + google/protobuf/compiler/cpp/cpp_message_field.cc \ + google/protobuf/compiler/cpp/cpp_message_field.h \ + google/protobuf/compiler/cpp/cpp_options.h \ + google/protobuf/compiler/cpp/cpp_primitive_field.cc \ + google/protobuf/compiler/cpp/cpp_primitive_field.h \ + google/protobuf/compiler/cpp/cpp_service.cc \ + google/protobuf/compiler/cpp/cpp_service.h \ + google/protobuf/compiler/cpp/cpp_string_field.cc \ + google/protobuf/compiler/cpp/cpp_string_field.h \ + google/protobuf/compiler/java/java_enum.cc \ + google/protobuf/compiler/java/java_enum.h \ + google/protobuf/compiler/java/java_enum_field.cc \ + google/protobuf/compiler/java/java_enum_field.h \ + google/protobuf/compiler/java/java_extension.cc \ + google/protobuf/compiler/java/java_extension.h \ + google/protobuf/compiler/java/java_field.cc \ + google/protobuf/compiler/java/java_field.h \ + google/protobuf/compiler/java/java_file.cc \ + google/protobuf/compiler/java/java_file.h \ + google/protobuf/compiler/java/java_generator.cc \ + google/protobuf/compiler/java/java_helpers.cc \ + google/protobuf/compiler/java/java_helpers.h \ + google/protobuf/compiler/java/java_message.cc \ + google/protobuf/compiler/java/java_message.h \ + google/protobuf/compiler/java/java_message_field.cc \ + google/protobuf/compiler/java/java_message_field.h \ + google/protobuf/compiler/java/java_primitive_field.cc \ + google/protobuf/compiler/java/java_primitive_field.h \ + google/protobuf/compiler/java/java_service.cc \ + google/protobuf/compiler/java/java_service.h \ + google/protobuf/compiler/java/java_string_field.cc \ + google/protobuf/compiler/java/java_string_field.h \ + google/protobuf/compiler/java/java_doc_comment.cc \ + google/protobuf/compiler/java/java_doc_comment.h \ + google/protobuf/compiler/python/python_generator.cc + +bin_PROGRAMS = protoc +protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la +protoc_SOURCES = google/protobuf/compiler/main.cc + +# Tests ============================================================== + +protoc_inputs = \ + google/protobuf/unittest.proto \ + google/protobuf/unittest_empty.proto \ + google/protobuf/unittest_import.proto \ + google/protobuf/unittest_import_public.proto \ + google/protobuf/unittest_mset.proto \ + google/protobuf/unittest_optimize_for.proto \ + google/protobuf/unittest_embed_optimize_for.proto \ + google/protobuf/unittest_custom_options.proto \ + google/protobuf/unittest_lite.proto \ + google/protobuf/unittest_import_lite.proto \ + google/protobuf/unittest_import_public_lite.proto \ + google/protobuf/unittest_lite_imports_nonlite.proto \ + google/protobuf/unittest_no_generic_services.proto \ + google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto + +EXTRA_DIST = \ + $(protoc_inputs) \ + solaris/libstdc++.la \ + google/protobuf/io/gzip_stream.h \ + google/protobuf/io/gzip_stream_unittest.sh \ + google/protobuf/testdata/golden_message \ + google/protobuf/testdata/golden_packed_fields_message \ + google/protobuf/testdata/text_format_unittest_data.txt \ + google/protobuf/testdata/text_format_unittest_extensions_data.txt \ + google/protobuf/package_info.h \ + google/protobuf/io/package_info.h \ + google/protobuf/compiler/package_info.h \ + google/protobuf/compiler/zip_output_unittest.sh \ + google/protobuf/unittest_enormous_descriptor.proto + +protoc_lite_outputs = \ + google/protobuf/unittest_lite.pb.cc \ + google/protobuf/unittest_lite.pb.h \ + google/protobuf/unittest_import_lite.pb.cc \ + google/protobuf/unittest_import_lite.pb.h \ + google/protobuf/unittest_import_public_lite.pb.cc \ + google/protobuf/unittest_import_public_lite.pb.h + +protoc_outputs = \ + $(protoc_lite_outputs) \ + google/protobuf/unittest.pb.cc \ + google/protobuf/unittest.pb.h \ + google/protobuf/unittest_empty.pb.cc \ + google/protobuf/unittest_empty.pb.h \ + google/protobuf/unittest_import.pb.cc \ + google/protobuf/unittest_import.pb.h \ + google/protobuf/unittest_import_public.pb.cc \ + google/protobuf/unittest_import_public.pb.h \ + google/protobuf/unittest_mset.pb.cc \ + google/protobuf/unittest_mset.pb.h \ + google/protobuf/unittest_optimize_for.pb.cc \ + google/protobuf/unittest_optimize_for.pb.h \ + google/protobuf/unittest_embed_optimize_for.pb.cc \ + google/protobuf/unittest_embed_optimize_for.pb.h \ + google/protobuf/unittest_custom_options.pb.cc \ + google/protobuf/unittest_custom_options.pb.h \ + google/protobuf/unittest_lite_imports_nonlite.pb.cc \ + google/protobuf/unittest_lite_imports_nonlite.pb.h \ + google/protobuf/unittest_no_generic_services.pb.cc \ + google/protobuf/unittest_no_generic_services.pb.h \ + google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc \ + google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h + +BUILT_SOURCES = $(protoc_outputs) + +if USE_EXTERNAL_PROTOC + +unittest_proto_middleman: $(protoc_inputs) + $(PROTOC) -I$(srcdir) --cpp_out=. $^ + touch unittest_proto_middleman + +else + +# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is +# relative to srcdir, which may not be the same as the current directory when +# building out-of-tree. +unittest_proto_middleman: protoc$(EXEEXT) $(protoc_inputs) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd $(protoc_inputs) ) + touch unittest_proto_middleman + +endif + +$(protoc_outputs): unittest_proto_middleman + +COMMON_TEST_SOURCES = \ + google/protobuf/test_util.cc \ + google/protobuf/test_util.h \ + google/protobuf/testing/googletest.cc \ + google/protobuf/testing/googletest.h \ + google/protobuf/testing/file.cc \ + google/protobuf/testing/file.h + +check_PROGRAMS = protoc protobuf-test protobuf-lazy-descriptor-test \ + protobuf-lite-test test_plugin $(GZCHECKPROGRAMS) +protobuf_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \ + $(top_builddir)/gtest/lib/libgtest.la \ + $(top_builddir)/gtest/lib/libgtest_main.la +protobuf_test_CPPFLAGS = -I$(top_srcdir)/gtest/include \ + -I$(top_builddir)/gtest/include +# Disable optimization for tests unless the user explicitly asked for it, +# since test_util.cc takes forever to compile with optimization (with GCC). +# See configure.ac for more info. +protobuf_test_CXXFLAGS = $(NO_OPT_CXXFLAGS) +protobuf_test_SOURCES = \ + google/protobuf/stubs/common_unittest.cc \ + google/protobuf/stubs/once_unittest.cc \ + google/protobuf/stubs/strutil_unittest.cc \ + google/protobuf/stubs/structurally_valid_unittest.cc \ + google/protobuf/stubs/stringprintf_unittest.cc \ + google/protobuf/stubs/template_util_unittest.cc \ + google/protobuf/stubs/type_traits_unittest.cc \ + google/protobuf/descriptor_database_unittest.cc \ + google/protobuf/descriptor_unittest.cc \ + google/protobuf/dynamic_message_unittest.cc \ + google/protobuf/extension_set_unittest.cc \ + google/protobuf/generated_message_reflection_unittest.cc \ + google/protobuf/message_unittest.cc \ + google/protobuf/reflection_ops_unittest.cc \ + google/protobuf/repeated_field_unittest.cc \ + google/protobuf/repeated_field_reflection_unittest.cc \ + google/protobuf/text_format_unittest.cc \ + google/protobuf/unknown_field_set_unittest.cc \ + google/protobuf/wire_format_unittest.cc \ + google/protobuf/io/coded_stream_unittest.cc \ + google/protobuf/io/printer_unittest.cc \ + google/protobuf/io/tokenizer_unittest.cc \ + google/protobuf/io/zero_copy_stream_unittest.cc \ + google/protobuf/compiler/command_line_interface_unittest.cc \ + google/protobuf/compiler/importer_unittest.cc \ + google/protobuf/compiler/mock_code_generator.cc \ + google/protobuf/compiler/mock_code_generator.h \ + google/protobuf/compiler/parser_unittest.cc \ + google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc \ + google/protobuf/compiler/cpp/cpp_unittest.h \ + google/protobuf/compiler/cpp/cpp_unittest.cc \ + google/protobuf/compiler/cpp/cpp_plugin_unittest.cc \ + google/protobuf/compiler/java/java_plugin_unittest.cc \ + google/protobuf/compiler/java/java_doc_comment_unittest.cc \ + google/protobuf/compiler/python/python_plugin_unittest.cc \ + $(COMMON_TEST_SOURCES) +nodist_protobuf_test_SOURCES = $(protoc_outputs) + +# Run cpp_unittest again with PROTOBUF_TEST_NO_DESCRIPTORS defined. +protobuf_lazy_descriptor_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la \ + $(top_builddir)/gtest/lib/libgtest.la \ + $(top_builddir)/gtest/lib/libgtest_main.la +protobuf_lazy_descriptor_test_CPPFLAGS = -I$(top_srcdir)/gtest/include \ + -I$(top_builddir)/gtest/include \ + -DPROTOBUF_TEST_NO_DESCRIPTORS +protobuf_lazy_descriptor_test_CXXFLAGS = $(NO_OPT_CXXFLAGS) +protobuf_lazy_descriptor_test_SOURCES = \ + google/protobuf/compiler/cpp/cpp_unittest.cc \ + $(COMMON_TEST_SOURCES) +nodist_protobuf_lazy_descriptor_test_SOURCES = $(protoc_outputs) + +# Build lite_unittest separately, since it doesn't use gtest. +protobuf_lite_test_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la +protobuf_lite_test_CXXFLAGS = $(NO_OPT_CXXFLAGS) +protobuf_lite_test_SOURCES = \ + google/protobuf/lite_unittest.cc \ + google/protobuf/test_util_lite.cc \ + google/protobuf/test_util_lite.h +nodist_protobuf_lite_test_SOURCES = $(protoc_lite_outputs) + +# Test plugin binary. +test_plugin_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \ + $(top_builddir)/gtest/lib/libgtest.la +test_plugin_CPPFLAGS = -I$(top_srcdir)/gtest/include \ + -I$(top_builddir)/gtest/include +test_plugin_SOURCES = \ + google/protobuf/compiler/mock_code_generator.cc \ + google/protobuf/testing/file.cc \ + google/protobuf/testing/file.h \ + google/protobuf/compiler/test_plugin.cc + +if HAVE_ZLIB +zcgzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la +zcgzip_SOURCES = google/protobuf/testing/zcgzip.cc + +zcgunzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la +zcgunzip_SOURCES = google/protobuf/testing/zcgunzip.cc +endif + +TESTS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test \ + google/protobuf/compiler/zip_output_unittest.sh $(GZTESTS) diff --git a/cpp/thirdparty/protobuf-2.5.0/src/Makefile.in b/cpp/thirdparty/protobuf-2.5.0/src/Makefile.in new file mode 100644 index 0000000..43d96ce --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/Makefile.in @@ -0,0 +1,3121 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = protoc$(EXEEXT) +check_PROGRAMS = protoc$(EXEEXT) protobuf-test$(EXEEXT) \ + protobuf-lazy-descriptor-test$(EXEEXT) \ + protobuf-lite-test$(EXEEXT) test_plugin$(EXEEXT) \ + $(am__EXEEXT_1) +TESTS = protobuf-test$(EXEEXT) protobuf-lazy-descriptor-test$(EXEEXT) \ + protobuf-lite-test$(EXEEXT) \ + google/protobuf/compiler/zip_output_unittest.sh \ + $(am__EXEEXT_2) +subdir = src +DIST_COMMON = $(am__nobase_include_HEADERS_DIST) \ + $(nobase_dist_proto_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_system_extensions.m4 \ + $(top_srcdir)/m4/acx_check_suncc.m4 \ + $(top_srcdir)/m4/acx_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/stl_hash.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(protodir)" "$(DESTDIR)$(includedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libprotobuf_lite_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libprotobuf_lite_la_OBJECTS = atomicops_internals_x86_gcc.lo \ + atomicops_internals_x86_msvc.lo common.lo once.lo \ + stringprintf.lo extension_set.lo generated_message_util.lo \ + message_lite.lo repeated_field.lo wire_format_lite.lo \ + coded_stream.lo zero_copy_stream.lo \ + zero_copy_stream_impl_lite.lo +libprotobuf_lite_la_OBJECTS = $(am_libprotobuf_lite_la_OBJECTS) +libprotobuf_lite_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libprotobuf_lite_la_LDFLAGS) $(LDFLAGS) -o $@ +libprotobuf_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__objects_1 = atomicops_internals_x86_gcc.lo \ + atomicops_internals_x86_msvc.lo common.lo once.lo \ + stringprintf.lo extension_set.lo generated_message_util.lo \ + message_lite.lo repeated_field.lo wire_format_lite.lo \ + coded_stream.lo zero_copy_stream.lo \ + zero_copy_stream_impl_lite.lo +am_libprotobuf_la_OBJECTS = $(am__objects_1) strutil.lo substitute.lo \ + structurally_valid.lo descriptor.lo descriptor.pb.lo \ + descriptor_database.lo dynamic_message.lo \ + extension_set_heavy.lo generated_message_reflection.lo \ + message.lo reflection_ops.lo service.lo text_format.lo \ + unknown_field_set.lo wire_format.lo gzip_stream.lo printer.lo \ + tokenizer.lo zero_copy_stream_impl.lo importer.lo parser.lo +libprotobuf_la_OBJECTS = $(am_libprotobuf_la_OBJECTS) +libprotobuf_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libprotobuf_la_LDFLAGS) $(LDFLAGS) -o $@ +libprotoc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la +am_libprotoc_la_OBJECTS = code_generator.lo command_line_interface.lo \ + plugin.lo plugin.pb.lo subprocess.lo zip_writer.lo cpp_enum.lo \ + cpp_enum_field.lo cpp_extension.lo cpp_field.lo cpp_file.lo \ + cpp_generator.lo cpp_helpers.lo cpp_message.lo \ + cpp_message_field.lo cpp_primitive_field.lo cpp_service.lo \ + cpp_string_field.lo java_enum.lo java_enum_field.lo \ + java_extension.lo java_field.lo java_file.lo java_generator.lo \ + java_helpers.lo java_message.lo java_message_field.lo \ + java_primitive_field.lo java_service.lo java_string_field.lo \ + java_doc_comment.lo python_generator.lo +libprotoc_la_OBJECTS = $(am_libprotoc_la_OBJECTS) +libprotoc_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libprotoc_la_LDFLAGS) $(LDFLAGS) -o $@ +@HAVE_ZLIB_TRUE@am__EXEEXT_1 = zcgzip$(EXEEXT) zcgunzip$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) +am__objects_2 = protobuf_lazy_descriptor_test-test_util.$(OBJEXT) \ + protobuf_lazy_descriptor_test-googletest.$(OBJEXT) \ + protobuf_lazy_descriptor_test-file.$(OBJEXT) +am_protobuf_lazy_descriptor_test_OBJECTS = \ + protobuf_lazy_descriptor_test-cpp_unittest.$(OBJEXT) \ + $(am__objects_2) +am__objects_3 = \ + protobuf_lazy_descriptor_test-unittest_lite.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_import_lite.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.$(OBJEXT) +am__objects_4 = $(am__objects_3) \ + protobuf_lazy_descriptor_test-unittest.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_empty.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_import.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_import_public.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_mset.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_optimize_for.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_custom_options.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.$(OBJEXT) +nodist_protobuf_lazy_descriptor_test_OBJECTS = $(am__objects_4) +protobuf_lazy_descriptor_test_OBJECTS = \ + $(am_protobuf_lazy_descriptor_test_OBJECTS) \ + $(nodist_protobuf_lazy_descriptor_test_OBJECTS) +protobuf_lazy_descriptor_test_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + libprotobuf.la $(top_builddir)/gtest/lib/libgtest.la \ + $(top_builddir)/gtest/lib/libgtest_main.la +protobuf_lazy_descriptor_test_LINK = $(LIBTOOL) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_protobuf_lite_test_OBJECTS = \ + protobuf_lite_test-lite_unittest.$(OBJEXT) \ + protobuf_lite_test-test_util_lite.$(OBJEXT) +am__objects_5 = protobuf_lite_test-unittest_lite.pb.$(OBJEXT) \ + protobuf_lite_test-unittest_import_lite.pb.$(OBJEXT) \ + protobuf_lite_test-unittest_import_public_lite.pb.$(OBJEXT) +nodist_protobuf_lite_test_OBJECTS = $(am__objects_5) +protobuf_lite_test_OBJECTS = $(am_protobuf_lite_test_OBJECTS) \ + $(nodist_protobuf_lite_test_OBJECTS) +protobuf_lite_test_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + libprotobuf-lite.la +protobuf_lite_test_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__objects_6 = protobuf_test-test_util.$(OBJEXT) \ + protobuf_test-googletest.$(OBJEXT) \ + protobuf_test-file.$(OBJEXT) +am_protobuf_test_OBJECTS = protobuf_test-common_unittest.$(OBJEXT) \ + protobuf_test-once_unittest.$(OBJEXT) \ + protobuf_test-strutil_unittest.$(OBJEXT) \ + protobuf_test-structurally_valid_unittest.$(OBJEXT) \ + protobuf_test-stringprintf_unittest.$(OBJEXT) \ + protobuf_test-template_util_unittest.$(OBJEXT) \ + protobuf_test-type_traits_unittest.$(OBJEXT) \ + protobuf_test-descriptor_database_unittest.$(OBJEXT) \ + protobuf_test-descriptor_unittest.$(OBJEXT) \ + protobuf_test-dynamic_message_unittest.$(OBJEXT) \ + protobuf_test-extension_set_unittest.$(OBJEXT) \ + protobuf_test-generated_message_reflection_unittest.$(OBJEXT) \ + protobuf_test-message_unittest.$(OBJEXT) \ + protobuf_test-reflection_ops_unittest.$(OBJEXT) \ + protobuf_test-repeated_field_unittest.$(OBJEXT) \ + protobuf_test-repeated_field_reflection_unittest.$(OBJEXT) \ + protobuf_test-text_format_unittest.$(OBJEXT) \ + protobuf_test-unknown_field_set_unittest.$(OBJEXT) \ + protobuf_test-wire_format_unittest.$(OBJEXT) \ + protobuf_test-coded_stream_unittest.$(OBJEXT) \ + protobuf_test-printer_unittest.$(OBJEXT) \ + protobuf_test-tokenizer_unittest.$(OBJEXT) \ + protobuf_test-zero_copy_stream_unittest.$(OBJEXT) \ + protobuf_test-command_line_interface_unittest.$(OBJEXT) \ + protobuf_test-importer_unittest.$(OBJEXT) \ + protobuf_test-mock_code_generator.$(OBJEXT) \ + protobuf_test-parser_unittest.$(OBJEXT) \ + protobuf_test-cpp_bootstrap_unittest.$(OBJEXT) \ + protobuf_test-cpp_unittest.$(OBJEXT) \ + protobuf_test-cpp_plugin_unittest.$(OBJEXT) \ + protobuf_test-java_plugin_unittest.$(OBJEXT) \ + protobuf_test-java_doc_comment_unittest.$(OBJEXT) \ + protobuf_test-python_plugin_unittest.$(OBJEXT) \ + $(am__objects_6) +am__objects_7 = protobuf_test-unittest_lite.pb.$(OBJEXT) \ + protobuf_test-unittest_import_lite.pb.$(OBJEXT) \ + protobuf_test-unittest_import_public_lite.pb.$(OBJEXT) +am__objects_8 = $(am__objects_7) protobuf_test-unittest.pb.$(OBJEXT) \ + protobuf_test-unittest_empty.pb.$(OBJEXT) \ + protobuf_test-unittest_import.pb.$(OBJEXT) \ + protobuf_test-unittest_import_public.pb.$(OBJEXT) \ + protobuf_test-unittest_mset.pb.$(OBJEXT) \ + protobuf_test-unittest_optimize_for.pb.$(OBJEXT) \ + protobuf_test-unittest_embed_optimize_for.pb.$(OBJEXT) \ + protobuf_test-unittest_custom_options.pb.$(OBJEXT) \ + protobuf_test-unittest_lite_imports_nonlite.pb.$(OBJEXT) \ + protobuf_test-unittest_no_generic_services.pb.$(OBJEXT) \ + protobuf_test-cpp_test_bad_identifiers.pb.$(OBJEXT) +nodist_protobuf_test_OBJECTS = $(am__objects_8) +protobuf_test_OBJECTS = $(am_protobuf_test_OBJECTS) \ + $(nodist_protobuf_test_OBJECTS) +protobuf_test_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la \ + libprotoc.la $(top_builddir)/gtest/lib/libgtest.la \ + $(top_builddir)/gtest/lib/libgtest_main.la +protobuf_test_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(protobuf_test_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_protoc_OBJECTS = main.$(OBJEXT) +protoc_OBJECTS = $(am_protoc_OBJECTS) +protoc_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la \ + libprotoc.la +am_test_plugin_OBJECTS = test_plugin-mock_code_generator.$(OBJEXT) \ + test_plugin-file.$(OBJEXT) test_plugin-test_plugin.$(OBJEXT) +test_plugin_OBJECTS = $(am_test_plugin_OBJECTS) +test_plugin_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la \ + libprotoc.la $(top_builddir)/gtest/lib/libgtest.la +am__zcgunzip_SOURCES_DIST = google/protobuf/testing/zcgunzip.cc +@HAVE_ZLIB_TRUE@am_zcgunzip_OBJECTS = zcgunzip.$(OBJEXT) +zcgunzip_OBJECTS = $(am_zcgunzip_OBJECTS) +@HAVE_ZLIB_TRUE@zcgunzip_DEPENDENCIES = $(am__DEPENDENCIES_1) \ +@HAVE_ZLIB_TRUE@ libprotobuf.la +am__zcgzip_SOURCES_DIST = google/protobuf/testing/zcgzip.cc +@HAVE_ZLIB_TRUE@am_zcgzip_OBJECTS = zcgzip.$(OBJEXT) +zcgzip_OBJECTS = $(am_zcgzip_OBJECTS) +@HAVE_ZLIB_TRUE@zcgzip_DEPENDENCIES = $(am__DEPENDENCIES_1) \ +@HAVE_ZLIB_TRUE@ libprotobuf.la +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libprotobuf_lite_la_SOURCES) $(libprotobuf_la_SOURCES) \ + $(libprotoc_la_SOURCES) \ + $(protobuf_lazy_descriptor_test_SOURCES) \ + $(nodist_protobuf_lazy_descriptor_test_SOURCES) \ + $(protobuf_lite_test_SOURCES) \ + $(nodist_protobuf_lite_test_SOURCES) $(protobuf_test_SOURCES) \ + $(nodist_protobuf_test_SOURCES) $(protoc_SOURCES) \ + $(test_plugin_SOURCES) $(zcgunzip_SOURCES) $(zcgzip_SOURCES) +DIST_SOURCES = $(libprotobuf_lite_la_SOURCES) \ + $(libprotobuf_la_SOURCES) $(libprotoc_la_SOURCES) \ + $(protobuf_lazy_descriptor_test_SOURCES) \ + $(protobuf_lite_test_SOURCES) $(protobuf_test_SOURCES) \ + $(protoc_SOURCES) $(test_plugin_SOURCES) \ + $(am__zcgunzip_SOURCES_DIST) $(am__zcgzip_SOURCES_DIST) +DATA = $(nobase_dist_proto_DATA) +am__nobase_include_HEADERS_DIST = google/protobuf/stubs/atomicops.h \ + google/protobuf/stubs/atomicops_internals_arm_gcc.h \ + google/protobuf/stubs/atomicops_internals_arm_qnx.h \ + google/protobuf/stubs/atomicops_internals_atomicword_compat.h \ + google/protobuf/stubs/atomicops_internals_macosx.h \ + google/protobuf/stubs/atomicops_internals_mips_gcc.h \ + google/protobuf/stubs/atomicops_internals_pnacl.h \ + google/protobuf/stubs/atomicops_internals_x86_gcc.h \ + google/protobuf/stubs/atomicops_internals_x86_msvc.h \ + google/protobuf/stubs/common.h \ + google/protobuf/stubs/platform_macros.h \ + google/protobuf/stubs/once.h \ + google/protobuf/stubs/template_util.h \ + google/protobuf/stubs/type_traits.h \ + google/protobuf/descriptor.h google/protobuf/descriptor.pb.h \ + google/protobuf/descriptor_database.h \ + google/protobuf/dynamic_message.h \ + google/protobuf/extension_set.h \ + google/protobuf/generated_enum_reflection.h \ + google/protobuf/generated_message_util.h \ + google/protobuf/generated_message_reflection.h \ + google/protobuf/message.h google/protobuf/message_lite.h \ + google/protobuf/reflection_ops.h \ + google/protobuf/repeated_field.h google/protobuf/service.h \ + google/protobuf/text_format.h \ + google/protobuf/unknown_field_set.h \ + google/protobuf/wire_format.h \ + google/protobuf/wire_format_lite.h \ + google/protobuf/wire_format_lite_inl.h \ + google/protobuf/io/coded_stream.h \ + google/protobuf/io/gzip_stream.h google/protobuf/io/printer.h \ + google/protobuf/io/tokenizer.h \ + google/protobuf/io/zero_copy_stream.h \ + google/protobuf/io/zero_copy_stream_impl.h \ + google/protobuf/io/zero_copy_stream_impl_lite.h \ + google/protobuf/compiler/code_generator.h \ + google/protobuf/compiler/command_line_interface.h \ + google/protobuf/compiler/importer.h \ + google/protobuf/compiler/parser.h \ + google/protobuf/compiler/plugin.h \ + google/protobuf/compiler/plugin.pb.h \ + google/protobuf/compiler/cpp/cpp_generator.h \ + google/protobuf/compiler/java/java_generator.h \ + google/protobuf/compiler/python/python_generator.h +HEADERS = $(nobase_include_HEADERS) +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +@HAVE_ZLIB_TRUE@am__EXEEXT_2 = \ +@HAVE_ZLIB_TRUE@ google/protobuf/io/gzip_stream_unittest.sh +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +ISAINFO = @ISAINFO@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POW_LIB = @POW_LIB@ +PROTOBUF_OPT_FLAG = @PROTOBUF_OPT_FLAG@ +PROTOC = @PROTOC@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@HAVE_ZLIB_FALSE@GZCHECKPROGRAMS = +@HAVE_ZLIB_TRUE@GZCHECKPROGRAMS = zcgzip zcgunzip +@HAVE_ZLIB_FALSE@GZHEADERS = +@HAVE_ZLIB_TRUE@GZHEADERS = google/protobuf/io/gzip_stream.h +@HAVE_ZLIB_FALSE@GZTESTS = +@HAVE_ZLIB_TRUE@GZTESTS = google/protobuf/io/gzip_stream_unittest.sh +@GCC_FALSE@NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) + +# These are good warnings to turn on by default +@GCC_TRUE@NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare +AM_CXXFLAGS = $(NO_OPT_CXXFLAGS) $(PROTOBUF_OPT_FLAG) +AM_LDFLAGS = $(PTHREAD_CFLAGS) + +# If I say "dist_include_DATA", automake complains that $(includedir) is not +# a "legitimate" directory for DATA. Screw you, automake. +protodir = $(includedir) +nobase_dist_proto_DATA = google/protobuf/descriptor.proto \ + google/protobuf/compiler/plugin.proto + +CLEANFILES = $(protoc_outputs) unittest_proto_middleman \ + testzip.jar testzip.list testzip.proto testzip.zip + +MAINTAINERCLEANFILES = \ + Makefile.in + +nobase_include_HEADERS = \ + google/protobuf/stubs/atomicops.h \ + google/protobuf/stubs/atomicops_internals_arm_gcc.h \ + google/protobuf/stubs/atomicops_internals_arm_qnx.h \ + google/protobuf/stubs/atomicops_internals_atomicword_compat.h \ + google/protobuf/stubs/atomicops_internals_macosx.h \ + google/protobuf/stubs/atomicops_internals_mips_gcc.h \ + google/protobuf/stubs/atomicops_internals_pnacl.h \ + google/protobuf/stubs/atomicops_internals_x86_gcc.h \ + google/protobuf/stubs/atomicops_internals_x86_msvc.h \ + google/protobuf/stubs/common.h \ + google/protobuf/stubs/platform_macros.h \ + google/protobuf/stubs/once.h \ + google/protobuf/stubs/template_util.h \ + google/protobuf/stubs/type_traits.h \ + google/protobuf/descriptor.h \ + google/protobuf/descriptor.pb.h \ + google/protobuf/descriptor_database.h \ + google/protobuf/dynamic_message.h \ + google/protobuf/extension_set.h \ + google/protobuf/generated_enum_reflection.h \ + google/protobuf/generated_message_util.h \ + google/protobuf/generated_message_reflection.h \ + google/protobuf/message.h \ + google/protobuf/message_lite.h \ + google/protobuf/reflection_ops.h \ + google/protobuf/repeated_field.h \ + google/protobuf/service.h \ + google/protobuf/text_format.h \ + google/protobuf/unknown_field_set.h \ + google/protobuf/wire_format.h \ + google/protobuf/wire_format_lite.h \ + google/protobuf/wire_format_lite_inl.h \ + google/protobuf/io/coded_stream.h \ + $(GZHEADERS) \ + google/protobuf/io/printer.h \ + google/protobuf/io/tokenizer.h \ + google/protobuf/io/zero_copy_stream.h \ + google/protobuf/io/zero_copy_stream_impl.h \ + google/protobuf/io/zero_copy_stream_impl_lite.h \ + google/protobuf/compiler/code_generator.h \ + google/protobuf/compiler/command_line_interface.h \ + google/protobuf/compiler/importer.h \ + google/protobuf/compiler/parser.h \ + google/protobuf/compiler/plugin.h \ + google/protobuf/compiler/plugin.pb.h \ + google/protobuf/compiler/cpp/cpp_generator.h \ + google/protobuf/compiler/java/java_generator.h \ + google/protobuf/compiler/python/python_generator.h + +lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la +libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS) +libprotobuf_lite_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined +libprotobuf_lite_la_SOURCES = \ + google/protobuf/stubs/atomicops_internals_x86_gcc.cc \ + google/protobuf/stubs/atomicops_internals_x86_msvc.cc \ + google/protobuf/stubs/common.cc \ + google/protobuf/stubs/once.cc \ + google/protobuf/stubs/hash.h \ + google/protobuf/stubs/map-util.h \ + google/protobuf/stubs/stl_util.h \ + google/protobuf/stubs/stringprintf.cc \ + google/protobuf/stubs/stringprintf.h \ + google/protobuf/extension_set.cc \ + google/protobuf/generated_message_util.cc \ + google/protobuf/message_lite.cc \ + google/protobuf/repeated_field.cc \ + google/protobuf/wire_format_lite.cc \ + google/protobuf/io/coded_stream.cc \ + google/protobuf/io/coded_stream_inl.h \ + google/protobuf/io/zero_copy_stream.cc \ + google/protobuf/io/zero_copy_stream_impl_lite.cc + +libprotobuf_la_LIBADD = $(PTHREAD_LIBS) +libprotobuf_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined +libprotobuf_la_SOURCES = \ + $(libprotobuf_lite_la_SOURCES) \ + google/protobuf/stubs/strutil.cc \ + google/protobuf/stubs/strutil.h \ + google/protobuf/stubs/substitute.cc \ + google/protobuf/stubs/substitute.h \ + google/protobuf/stubs/structurally_valid.cc \ + google/protobuf/descriptor.cc \ + google/protobuf/descriptor.pb.cc \ + google/protobuf/descriptor_database.cc \ + google/protobuf/dynamic_message.cc \ + google/protobuf/extension_set_heavy.cc \ + google/protobuf/generated_message_reflection.cc \ + google/protobuf/message.cc \ + google/protobuf/reflection_ops.cc \ + google/protobuf/service.cc \ + google/protobuf/text_format.cc \ + google/protobuf/unknown_field_set.cc \ + google/protobuf/wire_format.cc \ + google/protobuf/io/gzip_stream.cc \ + google/protobuf/io/printer.cc \ + google/protobuf/io/tokenizer.cc \ + google/protobuf/io/zero_copy_stream_impl.cc \ + google/protobuf/compiler/importer.cc \ + google/protobuf/compiler/parser.cc + +libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la +libprotoc_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined +libprotoc_la_SOURCES = \ + google/protobuf/compiler/code_generator.cc \ + google/protobuf/compiler/command_line_interface.cc \ + google/protobuf/compiler/plugin.cc \ + google/protobuf/compiler/plugin.pb.cc \ + google/protobuf/compiler/subprocess.cc \ + google/protobuf/compiler/subprocess.h \ + google/protobuf/compiler/zip_writer.cc \ + google/protobuf/compiler/zip_writer.h \ + google/protobuf/compiler/cpp/cpp_enum.cc \ + google/protobuf/compiler/cpp/cpp_enum.h \ + google/protobuf/compiler/cpp/cpp_enum_field.cc \ + google/protobuf/compiler/cpp/cpp_enum_field.h \ + google/protobuf/compiler/cpp/cpp_extension.cc \ + google/protobuf/compiler/cpp/cpp_extension.h \ + google/protobuf/compiler/cpp/cpp_field.cc \ + google/protobuf/compiler/cpp/cpp_field.h \ + google/protobuf/compiler/cpp/cpp_file.cc \ + google/protobuf/compiler/cpp/cpp_file.h \ + google/protobuf/compiler/cpp/cpp_generator.cc \ + google/protobuf/compiler/cpp/cpp_helpers.cc \ + google/protobuf/compiler/cpp/cpp_helpers.h \ + google/protobuf/compiler/cpp/cpp_message.cc \ + google/protobuf/compiler/cpp/cpp_message.h \ + google/protobuf/compiler/cpp/cpp_message_field.cc \ + google/protobuf/compiler/cpp/cpp_message_field.h \ + google/protobuf/compiler/cpp/cpp_options.h \ + google/protobuf/compiler/cpp/cpp_primitive_field.cc \ + google/protobuf/compiler/cpp/cpp_primitive_field.h \ + google/protobuf/compiler/cpp/cpp_service.cc \ + google/protobuf/compiler/cpp/cpp_service.h \ + google/protobuf/compiler/cpp/cpp_string_field.cc \ + google/protobuf/compiler/cpp/cpp_string_field.h \ + google/protobuf/compiler/java/java_enum.cc \ + google/protobuf/compiler/java/java_enum.h \ + google/protobuf/compiler/java/java_enum_field.cc \ + google/protobuf/compiler/java/java_enum_field.h \ + google/protobuf/compiler/java/java_extension.cc \ + google/protobuf/compiler/java/java_extension.h \ + google/protobuf/compiler/java/java_field.cc \ + google/protobuf/compiler/java/java_field.h \ + google/protobuf/compiler/java/java_file.cc \ + google/protobuf/compiler/java/java_file.h \ + google/protobuf/compiler/java/java_generator.cc \ + google/protobuf/compiler/java/java_helpers.cc \ + google/protobuf/compiler/java/java_helpers.h \ + google/protobuf/compiler/java/java_message.cc \ + google/protobuf/compiler/java/java_message.h \ + google/protobuf/compiler/java/java_message_field.cc \ + google/protobuf/compiler/java/java_message_field.h \ + google/protobuf/compiler/java/java_primitive_field.cc \ + google/protobuf/compiler/java/java_primitive_field.h \ + google/protobuf/compiler/java/java_service.cc \ + google/protobuf/compiler/java/java_service.h \ + google/protobuf/compiler/java/java_string_field.cc \ + google/protobuf/compiler/java/java_string_field.h \ + google/protobuf/compiler/java/java_doc_comment.cc \ + google/protobuf/compiler/java/java_doc_comment.h \ + google/protobuf/compiler/python/python_generator.cc + +protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la +protoc_SOURCES = google/protobuf/compiler/main.cc + +# Tests ============================================================== +protoc_inputs = \ + google/protobuf/unittest.proto \ + google/protobuf/unittest_empty.proto \ + google/protobuf/unittest_import.proto \ + google/protobuf/unittest_import_public.proto \ + google/protobuf/unittest_mset.proto \ + google/protobuf/unittest_optimize_for.proto \ + google/protobuf/unittest_embed_optimize_for.proto \ + google/protobuf/unittest_custom_options.proto \ + google/protobuf/unittest_lite.proto \ + google/protobuf/unittest_import_lite.proto \ + google/protobuf/unittest_import_public_lite.proto \ + google/protobuf/unittest_lite_imports_nonlite.proto \ + google/protobuf/unittest_no_generic_services.proto \ + google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto + +EXTRA_DIST = \ + $(protoc_inputs) \ + solaris/libstdc++.la \ + google/protobuf/io/gzip_stream.h \ + google/protobuf/io/gzip_stream_unittest.sh \ + google/protobuf/testdata/golden_message \ + google/protobuf/testdata/golden_packed_fields_message \ + google/protobuf/testdata/text_format_unittest_data.txt \ + google/protobuf/testdata/text_format_unittest_extensions_data.txt \ + google/protobuf/package_info.h \ + google/protobuf/io/package_info.h \ + google/protobuf/compiler/package_info.h \ + google/protobuf/compiler/zip_output_unittest.sh \ + google/protobuf/unittest_enormous_descriptor.proto + +protoc_lite_outputs = \ + google/protobuf/unittest_lite.pb.cc \ + google/protobuf/unittest_lite.pb.h \ + google/protobuf/unittest_import_lite.pb.cc \ + google/protobuf/unittest_import_lite.pb.h \ + google/protobuf/unittest_import_public_lite.pb.cc \ + google/protobuf/unittest_import_public_lite.pb.h + +protoc_outputs = \ + $(protoc_lite_outputs) \ + google/protobuf/unittest.pb.cc \ + google/protobuf/unittest.pb.h \ + google/protobuf/unittest_empty.pb.cc \ + google/protobuf/unittest_empty.pb.h \ + google/protobuf/unittest_import.pb.cc \ + google/protobuf/unittest_import.pb.h \ + google/protobuf/unittest_import_public.pb.cc \ + google/protobuf/unittest_import_public.pb.h \ + google/protobuf/unittest_mset.pb.cc \ + google/protobuf/unittest_mset.pb.h \ + google/protobuf/unittest_optimize_for.pb.cc \ + google/protobuf/unittest_optimize_for.pb.h \ + google/protobuf/unittest_embed_optimize_for.pb.cc \ + google/protobuf/unittest_embed_optimize_for.pb.h \ + google/protobuf/unittest_custom_options.pb.cc \ + google/protobuf/unittest_custom_options.pb.h \ + google/protobuf/unittest_lite_imports_nonlite.pb.cc \ + google/protobuf/unittest_lite_imports_nonlite.pb.h \ + google/protobuf/unittest_no_generic_services.pb.cc \ + google/protobuf/unittest_no_generic_services.pb.h \ + google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc \ + google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h + +BUILT_SOURCES = $(protoc_outputs) +COMMON_TEST_SOURCES = \ + google/protobuf/test_util.cc \ + google/protobuf/test_util.h \ + google/protobuf/testing/googletest.cc \ + google/protobuf/testing/googletest.h \ + google/protobuf/testing/file.cc \ + google/protobuf/testing/file.h + +protobuf_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \ + $(top_builddir)/gtest/lib/libgtest.la \ + $(top_builddir)/gtest/lib/libgtest_main.la + +protobuf_test_CPPFLAGS = -I$(top_srcdir)/gtest/include \ + -I$(top_builddir)/gtest/include + +# Disable optimization for tests unless the user explicitly asked for it, +# since test_util.cc takes forever to compile with optimization (with GCC). +# See configure.ac for more info. +protobuf_test_CXXFLAGS = $(NO_OPT_CXXFLAGS) +protobuf_test_SOURCES = \ + google/protobuf/stubs/common_unittest.cc \ + google/protobuf/stubs/once_unittest.cc \ + google/protobuf/stubs/strutil_unittest.cc \ + google/protobuf/stubs/structurally_valid_unittest.cc \ + google/protobuf/stubs/stringprintf_unittest.cc \ + google/protobuf/stubs/template_util_unittest.cc \ + google/protobuf/stubs/type_traits_unittest.cc \ + google/protobuf/descriptor_database_unittest.cc \ + google/protobuf/descriptor_unittest.cc \ + google/protobuf/dynamic_message_unittest.cc \ + google/protobuf/extension_set_unittest.cc \ + google/protobuf/generated_message_reflection_unittest.cc \ + google/protobuf/message_unittest.cc \ + google/protobuf/reflection_ops_unittest.cc \ + google/protobuf/repeated_field_unittest.cc \ + google/protobuf/repeated_field_reflection_unittest.cc \ + google/protobuf/text_format_unittest.cc \ + google/protobuf/unknown_field_set_unittest.cc \ + google/protobuf/wire_format_unittest.cc \ + google/protobuf/io/coded_stream_unittest.cc \ + google/protobuf/io/printer_unittest.cc \ + google/protobuf/io/tokenizer_unittest.cc \ + google/protobuf/io/zero_copy_stream_unittest.cc \ + google/protobuf/compiler/command_line_interface_unittest.cc \ + google/protobuf/compiler/importer_unittest.cc \ + google/protobuf/compiler/mock_code_generator.cc \ + google/protobuf/compiler/mock_code_generator.h \ + google/protobuf/compiler/parser_unittest.cc \ + google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc \ + google/protobuf/compiler/cpp/cpp_unittest.h \ + google/protobuf/compiler/cpp/cpp_unittest.cc \ + google/protobuf/compiler/cpp/cpp_plugin_unittest.cc \ + google/protobuf/compiler/java/java_plugin_unittest.cc \ + google/protobuf/compiler/java/java_doc_comment_unittest.cc \ + google/protobuf/compiler/python/python_plugin_unittest.cc \ + $(COMMON_TEST_SOURCES) + +nodist_protobuf_test_SOURCES = $(protoc_outputs) + +# Run cpp_unittest again with PROTOBUF_TEST_NO_DESCRIPTORS defined. +protobuf_lazy_descriptor_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la \ + $(top_builddir)/gtest/lib/libgtest.la \ + $(top_builddir)/gtest/lib/libgtest_main.la + +protobuf_lazy_descriptor_test_CPPFLAGS = -I$(top_srcdir)/gtest/include \ + -I$(top_builddir)/gtest/include \ + -DPROTOBUF_TEST_NO_DESCRIPTORS + +protobuf_lazy_descriptor_test_CXXFLAGS = $(NO_OPT_CXXFLAGS) +protobuf_lazy_descriptor_test_SOURCES = \ + google/protobuf/compiler/cpp/cpp_unittest.cc \ + $(COMMON_TEST_SOURCES) + +nodist_protobuf_lazy_descriptor_test_SOURCES = $(protoc_outputs) + +# Build lite_unittest separately, since it doesn't use gtest. +protobuf_lite_test_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la +protobuf_lite_test_CXXFLAGS = $(NO_OPT_CXXFLAGS) +protobuf_lite_test_SOURCES = \ + google/protobuf/lite_unittest.cc \ + google/protobuf/test_util_lite.cc \ + google/protobuf/test_util_lite.h + +nodist_protobuf_lite_test_SOURCES = $(protoc_lite_outputs) + +# Test plugin binary. +test_plugin_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \ + $(top_builddir)/gtest/lib/libgtest.la + +test_plugin_CPPFLAGS = -I$(top_srcdir)/gtest/include \ + -I$(top_builddir)/gtest/include + +test_plugin_SOURCES = \ + google/protobuf/compiler/mock_code_generator.cc \ + google/protobuf/testing/file.cc \ + google/protobuf/testing/file.h \ + google/protobuf/compiler/test_plugin.cc + +@HAVE_ZLIB_TRUE@zcgzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la +@HAVE_ZLIB_TRUE@zcgzip_SOURCES = google/protobuf/testing/zcgzip.cc +@HAVE_ZLIB_TRUE@zcgunzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la +@HAVE_ZLIB_TRUE@zcgunzip_SOURCES = google/protobuf/testing/zcgunzip.cc +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .cc .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libprotobuf-lite.la: $(libprotobuf_lite_la_OBJECTS) $(libprotobuf_lite_la_DEPENDENCIES) $(EXTRA_libprotobuf_lite_la_DEPENDENCIES) + $(libprotobuf_lite_la_LINK) -rpath $(libdir) $(libprotobuf_lite_la_OBJECTS) $(libprotobuf_lite_la_LIBADD) $(LIBS) +libprotobuf.la: $(libprotobuf_la_OBJECTS) $(libprotobuf_la_DEPENDENCIES) $(EXTRA_libprotobuf_la_DEPENDENCIES) + $(libprotobuf_la_LINK) -rpath $(libdir) $(libprotobuf_la_OBJECTS) $(libprotobuf_la_LIBADD) $(LIBS) +libprotoc.la: $(libprotoc_la_OBJECTS) $(libprotoc_la_DEPENDENCIES) $(EXTRA_libprotoc_la_DEPENDENCIES) + $(libprotoc_la_LINK) -rpath $(libdir) $(libprotoc_la_OBJECTS) $(libprotoc_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +protobuf-lazy-descriptor-test$(EXEEXT): $(protobuf_lazy_descriptor_test_OBJECTS) $(protobuf_lazy_descriptor_test_DEPENDENCIES) $(EXTRA_protobuf_lazy_descriptor_test_DEPENDENCIES) + @rm -f protobuf-lazy-descriptor-test$(EXEEXT) + $(protobuf_lazy_descriptor_test_LINK) $(protobuf_lazy_descriptor_test_OBJECTS) $(protobuf_lazy_descriptor_test_LDADD) $(LIBS) +protobuf-lite-test$(EXEEXT): $(protobuf_lite_test_OBJECTS) $(protobuf_lite_test_DEPENDENCIES) $(EXTRA_protobuf_lite_test_DEPENDENCIES) + @rm -f protobuf-lite-test$(EXEEXT) + $(protobuf_lite_test_LINK) $(protobuf_lite_test_OBJECTS) $(protobuf_lite_test_LDADD) $(LIBS) +protobuf-test$(EXEEXT): $(protobuf_test_OBJECTS) $(protobuf_test_DEPENDENCIES) $(EXTRA_protobuf_test_DEPENDENCIES) + @rm -f protobuf-test$(EXEEXT) + $(protobuf_test_LINK) $(protobuf_test_OBJECTS) $(protobuf_test_LDADD) $(LIBS) +protoc$(EXEEXT): $(protoc_OBJECTS) $(protoc_DEPENDENCIES) $(EXTRA_protoc_DEPENDENCIES) + @rm -f protoc$(EXEEXT) + $(CXXLINK) $(protoc_OBJECTS) $(protoc_LDADD) $(LIBS) +test_plugin$(EXEEXT): $(test_plugin_OBJECTS) $(test_plugin_DEPENDENCIES) $(EXTRA_test_plugin_DEPENDENCIES) + @rm -f test_plugin$(EXEEXT) + $(CXXLINK) $(test_plugin_OBJECTS) $(test_plugin_LDADD) $(LIBS) +zcgunzip$(EXEEXT): $(zcgunzip_OBJECTS) $(zcgunzip_DEPENDENCIES) $(EXTRA_zcgunzip_DEPENDENCIES) + @rm -f zcgunzip$(EXEEXT) + $(CXXLINK) $(zcgunzip_OBJECTS) $(zcgunzip_LDADD) $(LIBS) +zcgzip$(EXEEXT): $(zcgzip_OBJECTS) $(zcgzip_DEPENDENCIES) $(EXTRA_zcgzip_DEPENDENCIES) + @rm -f zcgzip$(EXEEXT) + $(CXXLINK) $(zcgzip_OBJECTS) $(zcgzip_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomicops_internals_x86_gcc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomicops_internals_x86_msvc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/code_generator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coded_stream.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command_line_interface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_enum.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_enum_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_extension.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_file.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_generator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_helpers.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_message.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_message_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_primitive_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_service.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_string_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/descriptor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/descriptor.pb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/descriptor_database.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynamic_message.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extension_set.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extension_set_heavy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generated_message_reflection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generated_message_util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gzip_stream.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/importer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_doc_comment.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_enum.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_enum_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_extension.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_file.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_generator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_helpers.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_message.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_message_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_primitive_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_service.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_string_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message_lite.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/once.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.pb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-lite_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-test_util_lite.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-coded_stream_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-command_line_interface_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-common_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-descriptor_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-extension_set_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-googletest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-importer_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-java_plugin_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-message_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-mock_code_generator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-once_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-parser_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-printer_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-python_plugin_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-reflection_ops_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-repeated_field_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-stringprintf_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-structurally_valid_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-strutil_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-template_util_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-test_util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-text_format_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-tokenizer_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-type_traits_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_empty.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_import.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_import_public.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_lite.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_mset.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-wire_format_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/python_generator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reflection_ops.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repeated_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/service.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stringprintf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/structurally_valid.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strutil.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subprocess.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/substitute.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin-file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin-mock_code_generator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin-test_plugin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/text_format.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tokenizer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unknown_field_set.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wire_format.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wire_format_lite.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zcgunzip.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zcgzip.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zero_copy_stream.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zero_copy_stream_impl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zero_copy_stream_impl_lite.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zip_writer.Plo@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +atomicops_internals_x86_gcc.lo: google/protobuf/stubs/atomicops_internals_x86_gcc.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT atomicops_internals_x86_gcc.lo -MD -MP -MF $(DEPDIR)/atomicops_internals_x86_gcc.Tpo -c -o atomicops_internals_x86_gcc.lo `test -f 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc' || echo '$(srcdir)/'`google/protobuf/stubs/atomicops_internals_x86_gcc.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/atomicops_internals_x86_gcc.Tpo $(DEPDIR)/atomicops_internals_x86_gcc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/atomicops_internals_x86_gcc.cc' object='atomicops_internals_x86_gcc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o atomicops_internals_x86_gcc.lo `test -f 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc' || echo '$(srcdir)/'`google/protobuf/stubs/atomicops_internals_x86_gcc.cc + +atomicops_internals_x86_msvc.lo: google/protobuf/stubs/atomicops_internals_x86_msvc.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT atomicops_internals_x86_msvc.lo -MD -MP -MF $(DEPDIR)/atomicops_internals_x86_msvc.Tpo -c -o atomicops_internals_x86_msvc.lo `test -f 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc' || echo '$(srcdir)/'`google/protobuf/stubs/atomicops_internals_x86_msvc.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/atomicops_internals_x86_msvc.Tpo $(DEPDIR)/atomicops_internals_x86_msvc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/atomicops_internals_x86_msvc.cc' object='atomicops_internals_x86_msvc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o atomicops_internals_x86_msvc.lo `test -f 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc' || echo '$(srcdir)/'`google/protobuf/stubs/atomicops_internals_x86_msvc.cc + +common.lo: google/protobuf/stubs/common.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT common.lo -MD -MP -MF $(DEPDIR)/common.Tpo -c -o common.lo `test -f 'google/protobuf/stubs/common.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/common.Tpo $(DEPDIR)/common.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/common.cc' object='common.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o common.lo `test -f 'google/protobuf/stubs/common.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common.cc + +once.lo: google/protobuf/stubs/once.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT once.lo -MD -MP -MF $(DEPDIR)/once.Tpo -c -o once.lo `test -f 'google/protobuf/stubs/once.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/once.Tpo $(DEPDIR)/once.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/once.cc' object='once.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o once.lo `test -f 'google/protobuf/stubs/once.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once.cc + +stringprintf.lo: google/protobuf/stubs/stringprintf.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT stringprintf.lo -MD -MP -MF $(DEPDIR)/stringprintf.Tpo -c -o stringprintf.lo `test -f 'google/protobuf/stubs/stringprintf.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/stringprintf.Tpo $(DEPDIR)/stringprintf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/stringprintf.cc' object='stringprintf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o stringprintf.lo `test -f 'google/protobuf/stubs/stringprintf.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf.cc + +extension_set.lo: google/protobuf/extension_set.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extension_set.lo -MD -MP -MF $(DEPDIR)/extension_set.Tpo -c -o extension_set.lo `test -f 'google/protobuf/extension_set.cc' || echo '$(srcdir)/'`google/protobuf/extension_set.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/extension_set.Tpo $(DEPDIR)/extension_set.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/extension_set.cc' object='extension_set.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extension_set.lo `test -f 'google/protobuf/extension_set.cc' || echo '$(srcdir)/'`google/protobuf/extension_set.cc + +generated_message_util.lo: google/protobuf/generated_message_util.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT generated_message_util.lo -MD -MP -MF $(DEPDIR)/generated_message_util.Tpo -c -o generated_message_util.lo `test -f 'google/protobuf/generated_message_util.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_util.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/generated_message_util.Tpo $(DEPDIR)/generated_message_util.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/generated_message_util.cc' object='generated_message_util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o generated_message_util.lo `test -f 'google/protobuf/generated_message_util.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_util.cc + +message_lite.lo: google/protobuf/message_lite.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT message_lite.lo -MD -MP -MF $(DEPDIR)/message_lite.Tpo -c -o message_lite.lo `test -f 'google/protobuf/message_lite.cc' || echo '$(srcdir)/'`google/protobuf/message_lite.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/message_lite.Tpo $(DEPDIR)/message_lite.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/message_lite.cc' object='message_lite.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o message_lite.lo `test -f 'google/protobuf/message_lite.cc' || echo '$(srcdir)/'`google/protobuf/message_lite.cc + +repeated_field.lo: google/protobuf/repeated_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT repeated_field.lo -MD -MP -MF $(DEPDIR)/repeated_field.Tpo -c -o repeated_field.lo `test -f 'google/protobuf/repeated_field.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/repeated_field.Tpo $(DEPDIR)/repeated_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/repeated_field.cc' object='repeated_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o repeated_field.lo `test -f 'google/protobuf/repeated_field.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field.cc + +wire_format_lite.lo: google/protobuf/wire_format_lite.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wire_format_lite.lo -MD -MP -MF $(DEPDIR)/wire_format_lite.Tpo -c -o wire_format_lite.lo `test -f 'google/protobuf/wire_format_lite.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_lite.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wire_format_lite.Tpo $(DEPDIR)/wire_format_lite.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/wire_format_lite.cc' object='wire_format_lite.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wire_format_lite.lo `test -f 'google/protobuf/wire_format_lite.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_lite.cc + +coded_stream.lo: google/protobuf/io/coded_stream.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT coded_stream.lo -MD -MP -MF $(DEPDIR)/coded_stream.Tpo -c -o coded_stream.lo `test -f 'google/protobuf/io/coded_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/coded_stream.Tpo $(DEPDIR)/coded_stream.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/coded_stream.cc' object='coded_stream.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o coded_stream.lo `test -f 'google/protobuf/io/coded_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream.cc + +zero_copy_stream.lo: google/protobuf/io/zero_copy_stream.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zero_copy_stream.lo -MD -MP -MF $(DEPDIR)/zero_copy_stream.Tpo -c -o zero_copy_stream.lo `test -f 'google/protobuf/io/zero_copy_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zero_copy_stream.Tpo $(DEPDIR)/zero_copy_stream.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/zero_copy_stream.cc' object='zero_copy_stream.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zero_copy_stream.lo `test -f 'google/protobuf/io/zero_copy_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream.cc + +zero_copy_stream_impl_lite.lo: google/protobuf/io/zero_copy_stream_impl_lite.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zero_copy_stream_impl_lite.lo -MD -MP -MF $(DEPDIR)/zero_copy_stream_impl_lite.Tpo -c -o zero_copy_stream_impl_lite.lo `test -f 'google/protobuf/io/zero_copy_stream_impl_lite.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_impl_lite.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zero_copy_stream_impl_lite.Tpo $(DEPDIR)/zero_copy_stream_impl_lite.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/zero_copy_stream_impl_lite.cc' object='zero_copy_stream_impl_lite.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zero_copy_stream_impl_lite.lo `test -f 'google/protobuf/io/zero_copy_stream_impl_lite.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_impl_lite.cc + +strutil.lo: google/protobuf/stubs/strutil.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT strutil.lo -MD -MP -MF $(DEPDIR)/strutil.Tpo -c -o strutil.lo `test -f 'google/protobuf/stubs/strutil.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/strutil.Tpo $(DEPDIR)/strutil.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/strutil.cc' object='strutil.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o strutil.lo `test -f 'google/protobuf/stubs/strutil.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil.cc + +substitute.lo: google/protobuf/stubs/substitute.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT substitute.lo -MD -MP -MF $(DEPDIR)/substitute.Tpo -c -o substitute.lo `test -f 'google/protobuf/stubs/substitute.cc' || echo '$(srcdir)/'`google/protobuf/stubs/substitute.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/substitute.Tpo $(DEPDIR)/substitute.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/substitute.cc' object='substitute.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o substitute.lo `test -f 'google/protobuf/stubs/substitute.cc' || echo '$(srcdir)/'`google/protobuf/stubs/substitute.cc + +structurally_valid.lo: google/protobuf/stubs/structurally_valid.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT structurally_valid.lo -MD -MP -MF $(DEPDIR)/structurally_valid.Tpo -c -o structurally_valid.lo `test -f 'google/protobuf/stubs/structurally_valid.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/structurally_valid.Tpo $(DEPDIR)/structurally_valid.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/structurally_valid.cc' object='structurally_valid.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o structurally_valid.lo `test -f 'google/protobuf/stubs/structurally_valid.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid.cc + +descriptor.lo: google/protobuf/descriptor.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT descriptor.lo -MD -MP -MF $(DEPDIR)/descriptor.Tpo -c -o descriptor.lo `test -f 'google/protobuf/descriptor.cc' || echo '$(srcdir)/'`google/protobuf/descriptor.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/descriptor.Tpo $(DEPDIR)/descriptor.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor.cc' object='descriptor.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o descriptor.lo `test -f 'google/protobuf/descriptor.cc' || echo '$(srcdir)/'`google/protobuf/descriptor.cc + +descriptor.pb.lo: google/protobuf/descriptor.pb.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT descriptor.pb.lo -MD -MP -MF $(DEPDIR)/descriptor.pb.Tpo -c -o descriptor.pb.lo `test -f 'google/protobuf/descriptor.pb.cc' || echo '$(srcdir)/'`google/protobuf/descriptor.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/descriptor.pb.Tpo $(DEPDIR)/descriptor.pb.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor.pb.cc' object='descriptor.pb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o descriptor.pb.lo `test -f 'google/protobuf/descriptor.pb.cc' || echo '$(srcdir)/'`google/protobuf/descriptor.pb.cc + +descriptor_database.lo: google/protobuf/descriptor_database.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT descriptor_database.lo -MD -MP -MF $(DEPDIR)/descriptor_database.Tpo -c -o descriptor_database.lo `test -f 'google/protobuf/descriptor_database.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/descriptor_database.Tpo $(DEPDIR)/descriptor_database.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor_database.cc' object='descriptor_database.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o descriptor_database.lo `test -f 'google/protobuf/descriptor_database.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database.cc + +dynamic_message.lo: google/protobuf/dynamic_message.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dynamic_message.lo -MD -MP -MF $(DEPDIR)/dynamic_message.Tpo -c -o dynamic_message.lo `test -f 'google/protobuf/dynamic_message.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/dynamic_message.Tpo $(DEPDIR)/dynamic_message.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/dynamic_message.cc' object='dynamic_message.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dynamic_message.lo `test -f 'google/protobuf/dynamic_message.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message.cc + +extension_set_heavy.lo: google/protobuf/extension_set_heavy.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extension_set_heavy.lo -MD -MP -MF $(DEPDIR)/extension_set_heavy.Tpo -c -o extension_set_heavy.lo `test -f 'google/protobuf/extension_set_heavy.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_heavy.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/extension_set_heavy.Tpo $(DEPDIR)/extension_set_heavy.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/extension_set_heavy.cc' object='extension_set_heavy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extension_set_heavy.lo `test -f 'google/protobuf/extension_set_heavy.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_heavy.cc + +generated_message_reflection.lo: google/protobuf/generated_message_reflection.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT generated_message_reflection.lo -MD -MP -MF $(DEPDIR)/generated_message_reflection.Tpo -c -o generated_message_reflection.lo `test -f 'google/protobuf/generated_message_reflection.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/generated_message_reflection.Tpo $(DEPDIR)/generated_message_reflection.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/generated_message_reflection.cc' object='generated_message_reflection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o generated_message_reflection.lo `test -f 'google/protobuf/generated_message_reflection.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection.cc + +message.lo: google/protobuf/message.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT message.lo -MD -MP -MF $(DEPDIR)/message.Tpo -c -o message.lo `test -f 'google/protobuf/message.cc' || echo '$(srcdir)/'`google/protobuf/message.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/message.Tpo $(DEPDIR)/message.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/message.cc' object='message.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o message.lo `test -f 'google/protobuf/message.cc' || echo '$(srcdir)/'`google/protobuf/message.cc + +reflection_ops.lo: google/protobuf/reflection_ops.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT reflection_ops.lo -MD -MP -MF $(DEPDIR)/reflection_ops.Tpo -c -o reflection_ops.lo `test -f 'google/protobuf/reflection_ops.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/reflection_ops.Tpo $(DEPDIR)/reflection_ops.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/reflection_ops.cc' object='reflection_ops.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o reflection_ops.lo `test -f 'google/protobuf/reflection_ops.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops.cc + +service.lo: google/protobuf/service.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT service.lo -MD -MP -MF $(DEPDIR)/service.Tpo -c -o service.lo `test -f 'google/protobuf/service.cc' || echo '$(srcdir)/'`google/protobuf/service.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/service.Tpo $(DEPDIR)/service.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/service.cc' object='service.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o service.lo `test -f 'google/protobuf/service.cc' || echo '$(srcdir)/'`google/protobuf/service.cc + +text_format.lo: google/protobuf/text_format.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT text_format.lo -MD -MP -MF $(DEPDIR)/text_format.Tpo -c -o text_format.lo `test -f 'google/protobuf/text_format.cc' || echo '$(srcdir)/'`google/protobuf/text_format.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/text_format.Tpo $(DEPDIR)/text_format.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/text_format.cc' object='text_format.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o text_format.lo `test -f 'google/protobuf/text_format.cc' || echo '$(srcdir)/'`google/protobuf/text_format.cc + +unknown_field_set.lo: google/protobuf/unknown_field_set.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unknown_field_set.lo -MD -MP -MF $(DEPDIR)/unknown_field_set.Tpo -c -o unknown_field_set.lo `test -f 'google/protobuf/unknown_field_set.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/unknown_field_set.Tpo $(DEPDIR)/unknown_field_set.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unknown_field_set.cc' object='unknown_field_set.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unknown_field_set.lo `test -f 'google/protobuf/unknown_field_set.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set.cc + +wire_format.lo: google/protobuf/wire_format.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wire_format.lo -MD -MP -MF $(DEPDIR)/wire_format.Tpo -c -o wire_format.lo `test -f 'google/protobuf/wire_format.cc' || echo '$(srcdir)/'`google/protobuf/wire_format.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wire_format.Tpo $(DEPDIR)/wire_format.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/wire_format.cc' object='wire_format.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wire_format.lo `test -f 'google/protobuf/wire_format.cc' || echo '$(srcdir)/'`google/protobuf/wire_format.cc + +gzip_stream.lo: google/protobuf/io/gzip_stream.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gzip_stream.lo -MD -MP -MF $(DEPDIR)/gzip_stream.Tpo -c -o gzip_stream.lo `test -f 'google/protobuf/io/gzip_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/gzip_stream.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/gzip_stream.Tpo $(DEPDIR)/gzip_stream.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/gzip_stream.cc' object='gzip_stream.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gzip_stream.lo `test -f 'google/protobuf/io/gzip_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/gzip_stream.cc + +printer.lo: google/protobuf/io/printer.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT printer.lo -MD -MP -MF $(DEPDIR)/printer.Tpo -c -o printer.lo `test -f 'google/protobuf/io/printer.cc' || echo '$(srcdir)/'`google/protobuf/io/printer.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/printer.Tpo $(DEPDIR)/printer.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/printer.cc' object='printer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o printer.lo `test -f 'google/protobuf/io/printer.cc' || echo '$(srcdir)/'`google/protobuf/io/printer.cc + +tokenizer.lo: google/protobuf/io/tokenizer.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT tokenizer.lo -MD -MP -MF $(DEPDIR)/tokenizer.Tpo -c -o tokenizer.lo `test -f 'google/protobuf/io/tokenizer.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/tokenizer.Tpo $(DEPDIR)/tokenizer.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/tokenizer.cc' object='tokenizer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o tokenizer.lo `test -f 'google/protobuf/io/tokenizer.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer.cc + +zero_copy_stream_impl.lo: google/protobuf/io/zero_copy_stream_impl.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zero_copy_stream_impl.lo -MD -MP -MF $(DEPDIR)/zero_copy_stream_impl.Tpo -c -o zero_copy_stream_impl.lo `test -f 'google/protobuf/io/zero_copy_stream_impl.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_impl.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zero_copy_stream_impl.Tpo $(DEPDIR)/zero_copy_stream_impl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/zero_copy_stream_impl.cc' object='zero_copy_stream_impl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zero_copy_stream_impl.lo `test -f 'google/protobuf/io/zero_copy_stream_impl.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_impl.cc + +importer.lo: google/protobuf/compiler/importer.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT importer.lo -MD -MP -MF $(DEPDIR)/importer.Tpo -c -o importer.lo `test -f 'google/protobuf/compiler/importer.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/importer.Tpo $(DEPDIR)/importer.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/importer.cc' object='importer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o importer.lo `test -f 'google/protobuf/compiler/importer.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer.cc + +parser.lo: google/protobuf/compiler/parser.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT parser.lo -MD -MP -MF $(DEPDIR)/parser.Tpo -c -o parser.lo `test -f 'google/protobuf/compiler/parser.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/parser.Tpo $(DEPDIR)/parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/parser.cc' object='parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o parser.lo `test -f 'google/protobuf/compiler/parser.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser.cc + +code_generator.lo: google/protobuf/compiler/code_generator.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT code_generator.lo -MD -MP -MF $(DEPDIR)/code_generator.Tpo -c -o code_generator.lo `test -f 'google/protobuf/compiler/code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/code_generator.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/code_generator.Tpo $(DEPDIR)/code_generator.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/code_generator.cc' object='code_generator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o code_generator.lo `test -f 'google/protobuf/compiler/code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/code_generator.cc + +command_line_interface.lo: google/protobuf/compiler/command_line_interface.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT command_line_interface.lo -MD -MP -MF $(DEPDIR)/command_line_interface.Tpo -c -o command_line_interface.lo `test -f 'google/protobuf/compiler/command_line_interface.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/command_line_interface.Tpo $(DEPDIR)/command_line_interface.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/command_line_interface.cc' object='command_line_interface.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o command_line_interface.lo `test -f 'google/protobuf/compiler/command_line_interface.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface.cc + +plugin.lo: google/protobuf/compiler/plugin.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT plugin.lo -MD -MP -MF $(DEPDIR)/plugin.Tpo -c -o plugin.lo `test -f 'google/protobuf/compiler/plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/plugin.Tpo $(DEPDIR)/plugin.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/plugin.cc' object='plugin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o plugin.lo `test -f 'google/protobuf/compiler/plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.cc + +plugin.pb.lo: google/protobuf/compiler/plugin.pb.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT plugin.pb.lo -MD -MP -MF $(DEPDIR)/plugin.pb.Tpo -c -o plugin.pb.lo `test -f 'google/protobuf/compiler/plugin.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/plugin.pb.Tpo $(DEPDIR)/plugin.pb.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/plugin.pb.cc' object='plugin.pb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o plugin.pb.lo `test -f 'google/protobuf/compiler/plugin.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.pb.cc + +subprocess.lo: google/protobuf/compiler/subprocess.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT subprocess.lo -MD -MP -MF $(DEPDIR)/subprocess.Tpo -c -o subprocess.lo `test -f 'google/protobuf/compiler/subprocess.cc' || echo '$(srcdir)/'`google/protobuf/compiler/subprocess.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/subprocess.Tpo $(DEPDIR)/subprocess.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/subprocess.cc' object='subprocess.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o subprocess.lo `test -f 'google/protobuf/compiler/subprocess.cc' || echo '$(srcdir)/'`google/protobuf/compiler/subprocess.cc + +zip_writer.lo: google/protobuf/compiler/zip_writer.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zip_writer.lo -MD -MP -MF $(DEPDIR)/zip_writer.Tpo -c -o zip_writer.lo `test -f 'google/protobuf/compiler/zip_writer.cc' || echo '$(srcdir)/'`google/protobuf/compiler/zip_writer.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zip_writer.Tpo $(DEPDIR)/zip_writer.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/zip_writer.cc' object='zip_writer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zip_writer.lo `test -f 'google/protobuf/compiler/zip_writer.cc' || echo '$(srcdir)/'`google/protobuf/compiler/zip_writer.cc + +cpp_enum.lo: google/protobuf/compiler/cpp/cpp_enum.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_enum.lo -MD -MP -MF $(DEPDIR)/cpp_enum.Tpo -c -o cpp_enum.lo `test -f 'google/protobuf/compiler/cpp/cpp_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_enum.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_enum.Tpo $(DEPDIR)/cpp_enum.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_enum.cc' object='cpp_enum.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_enum.lo `test -f 'google/protobuf/compiler/cpp/cpp_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_enum.cc + +cpp_enum_field.lo: google/protobuf/compiler/cpp/cpp_enum_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_enum_field.lo -MD -MP -MF $(DEPDIR)/cpp_enum_field.Tpo -c -o cpp_enum_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_enum_field.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_enum_field.Tpo $(DEPDIR)/cpp_enum_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_enum_field.cc' object='cpp_enum_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_enum_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_enum_field.cc + +cpp_extension.lo: google/protobuf/compiler/cpp/cpp_extension.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_extension.lo -MD -MP -MF $(DEPDIR)/cpp_extension.Tpo -c -o cpp_extension.lo `test -f 'google/protobuf/compiler/cpp/cpp_extension.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_extension.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_extension.Tpo $(DEPDIR)/cpp_extension.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_extension.cc' object='cpp_extension.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_extension.lo `test -f 'google/protobuf/compiler/cpp/cpp_extension.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_extension.cc + +cpp_field.lo: google/protobuf/compiler/cpp/cpp_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_field.lo -MD -MP -MF $(DEPDIR)/cpp_field.Tpo -c -o cpp_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_field.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_field.Tpo $(DEPDIR)/cpp_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_field.cc' object='cpp_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_field.cc + +cpp_file.lo: google/protobuf/compiler/cpp/cpp_file.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_file.lo -MD -MP -MF $(DEPDIR)/cpp_file.Tpo -c -o cpp_file.lo `test -f 'google/protobuf/compiler/cpp/cpp_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_file.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_file.Tpo $(DEPDIR)/cpp_file.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_file.cc' object='cpp_file.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_file.lo `test -f 'google/protobuf/compiler/cpp/cpp_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_file.cc + +cpp_generator.lo: google/protobuf/compiler/cpp/cpp_generator.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_generator.lo -MD -MP -MF $(DEPDIR)/cpp_generator.Tpo -c -o cpp_generator.lo `test -f 'google/protobuf/compiler/cpp/cpp_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_generator.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_generator.Tpo $(DEPDIR)/cpp_generator.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_generator.cc' object='cpp_generator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_generator.lo `test -f 'google/protobuf/compiler/cpp/cpp_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_generator.cc + +cpp_helpers.lo: google/protobuf/compiler/cpp/cpp_helpers.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_helpers.lo -MD -MP -MF $(DEPDIR)/cpp_helpers.Tpo -c -o cpp_helpers.lo `test -f 'google/protobuf/compiler/cpp/cpp_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_helpers.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_helpers.Tpo $(DEPDIR)/cpp_helpers.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_helpers.cc' object='cpp_helpers.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_helpers.lo `test -f 'google/protobuf/compiler/cpp/cpp_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_helpers.cc + +cpp_message.lo: google/protobuf/compiler/cpp/cpp_message.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_message.lo -MD -MP -MF $(DEPDIR)/cpp_message.Tpo -c -o cpp_message.lo `test -f 'google/protobuf/compiler/cpp/cpp_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_message.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_message.Tpo $(DEPDIR)/cpp_message.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_message.cc' object='cpp_message.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_message.lo `test -f 'google/protobuf/compiler/cpp/cpp_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_message.cc + +cpp_message_field.lo: google/protobuf/compiler/cpp/cpp_message_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_message_field.lo -MD -MP -MF $(DEPDIR)/cpp_message_field.Tpo -c -o cpp_message_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_message_field.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_message_field.Tpo $(DEPDIR)/cpp_message_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_message_field.cc' object='cpp_message_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_message_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_message_field.cc + +cpp_primitive_field.lo: google/protobuf/compiler/cpp/cpp_primitive_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_primitive_field.lo -MD -MP -MF $(DEPDIR)/cpp_primitive_field.Tpo -c -o cpp_primitive_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_primitive_field.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_primitive_field.Tpo $(DEPDIR)/cpp_primitive_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_primitive_field.cc' object='cpp_primitive_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_primitive_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_primitive_field.cc + +cpp_service.lo: google/protobuf/compiler/cpp/cpp_service.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_service.lo -MD -MP -MF $(DEPDIR)/cpp_service.Tpo -c -o cpp_service.lo `test -f 'google/protobuf/compiler/cpp/cpp_service.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_service.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_service.Tpo $(DEPDIR)/cpp_service.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_service.cc' object='cpp_service.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_service.lo `test -f 'google/protobuf/compiler/cpp/cpp_service.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_service.cc + +cpp_string_field.lo: google/protobuf/compiler/cpp/cpp_string_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_string_field.lo -MD -MP -MF $(DEPDIR)/cpp_string_field.Tpo -c -o cpp_string_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_string_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_string_field.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_string_field.Tpo $(DEPDIR)/cpp_string_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_string_field.cc' object='cpp_string_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_string_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_string_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_string_field.cc + +java_enum.lo: google/protobuf/compiler/java/java_enum.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_enum.lo -MD -MP -MF $(DEPDIR)/java_enum.Tpo -c -o java_enum.lo `test -f 'google/protobuf/compiler/java/java_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_enum.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_enum.Tpo $(DEPDIR)/java_enum.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_enum.cc' object='java_enum.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_enum.lo `test -f 'google/protobuf/compiler/java/java_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_enum.cc + +java_enum_field.lo: google/protobuf/compiler/java/java_enum_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_enum_field.lo -MD -MP -MF $(DEPDIR)/java_enum_field.Tpo -c -o java_enum_field.lo `test -f 'google/protobuf/compiler/java/java_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_enum_field.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_enum_field.Tpo $(DEPDIR)/java_enum_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_enum_field.cc' object='java_enum_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_enum_field.lo `test -f 'google/protobuf/compiler/java/java_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_enum_field.cc + +java_extension.lo: google/protobuf/compiler/java/java_extension.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_extension.lo -MD -MP -MF $(DEPDIR)/java_extension.Tpo -c -o java_extension.lo `test -f 'google/protobuf/compiler/java/java_extension.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_extension.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_extension.Tpo $(DEPDIR)/java_extension.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_extension.cc' object='java_extension.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_extension.lo `test -f 'google/protobuf/compiler/java/java_extension.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_extension.cc + +java_field.lo: google/protobuf/compiler/java/java_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_field.lo -MD -MP -MF $(DEPDIR)/java_field.Tpo -c -o java_field.lo `test -f 'google/protobuf/compiler/java/java_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_field.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_field.Tpo $(DEPDIR)/java_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_field.cc' object='java_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_field.lo `test -f 'google/protobuf/compiler/java/java_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_field.cc + +java_file.lo: google/protobuf/compiler/java/java_file.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_file.lo -MD -MP -MF $(DEPDIR)/java_file.Tpo -c -o java_file.lo `test -f 'google/protobuf/compiler/java/java_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_file.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_file.Tpo $(DEPDIR)/java_file.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_file.cc' object='java_file.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_file.lo `test -f 'google/protobuf/compiler/java/java_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_file.cc + +java_generator.lo: google/protobuf/compiler/java/java_generator.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_generator.lo -MD -MP -MF $(DEPDIR)/java_generator.Tpo -c -o java_generator.lo `test -f 'google/protobuf/compiler/java/java_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_generator.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_generator.Tpo $(DEPDIR)/java_generator.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_generator.cc' object='java_generator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_generator.lo `test -f 'google/protobuf/compiler/java/java_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_generator.cc + +java_helpers.lo: google/protobuf/compiler/java/java_helpers.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_helpers.lo -MD -MP -MF $(DEPDIR)/java_helpers.Tpo -c -o java_helpers.lo `test -f 'google/protobuf/compiler/java/java_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_helpers.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_helpers.Tpo $(DEPDIR)/java_helpers.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_helpers.cc' object='java_helpers.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_helpers.lo `test -f 'google/protobuf/compiler/java/java_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_helpers.cc + +java_message.lo: google/protobuf/compiler/java/java_message.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_message.lo -MD -MP -MF $(DEPDIR)/java_message.Tpo -c -o java_message.lo `test -f 'google/protobuf/compiler/java/java_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_message.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_message.Tpo $(DEPDIR)/java_message.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_message.cc' object='java_message.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_message.lo `test -f 'google/protobuf/compiler/java/java_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_message.cc + +java_message_field.lo: google/protobuf/compiler/java/java_message_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_message_field.lo -MD -MP -MF $(DEPDIR)/java_message_field.Tpo -c -o java_message_field.lo `test -f 'google/protobuf/compiler/java/java_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_message_field.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_message_field.Tpo $(DEPDIR)/java_message_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_message_field.cc' object='java_message_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_message_field.lo `test -f 'google/protobuf/compiler/java/java_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_message_field.cc + +java_primitive_field.lo: google/protobuf/compiler/java/java_primitive_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_primitive_field.lo -MD -MP -MF $(DEPDIR)/java_primitive_field.Tpo -c -o java_primitive_field.lo `test -f 'google/protobuf/compiler/java/java_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_primitive_field.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_primitive_field.Tpo $(DEPDIR)/java_primitive_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_primitive_field.cc' object='java_primitive_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_primitive_field.lo `test -f 'google/protobuf/compiler/java/java_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_primitive_field.cc + +java_service.lo: google/protobuf/compiler/java/java_service.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_service.lo -MD -MP -MF $(DEPDIR)/java_service.Tpo -c -o java_service.lo `test -f 'google/protobuf/compiler/java/java_service.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_service.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_service.Tpo $(DEPDIR)/java_service.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_service.cc' object='java_service.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_service.lo `test -f 'google/protobuf/compiler/java/java_service.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_service.cc + +java_string_field.lo: google/protobuf/compiler/java/java_string_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_string_field.lo -MD -MP -MF $(DEPDIR)/java_string_field.Tpo -c -o java_string_field.lo `test -f 'google/protobuf/compiler/java/java_string_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_string_field.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_string_field.Tpo $(DEPDIR)/java_string_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_string_field.cc' object='java_string_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_string_field.lo `test -f 'google/protobuf/compiler/java/java_string_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_string_field.cc + +java_doc_comment.lo: google/protobuf/compiler/java/java_doc_comment.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_doc_comment.lo -MD -MP -MF $(DEPDIR)/java_doc_comment.Tpo -c -o java_doc_comment.lo `test -f 'google/protobuf/compiler/java/java_doc_comment.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_doc_comment.Tpo $(DEPDIR)/java_doc_comment.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_doc_comment.cc' object='java_doc_comment.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_doc_comment.lo `test -f 'google/protobuf/compiler/java/java_doc_comment.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment.cc + +python_generator.lo: google/protobuf/compiler/python/python_generator.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT python_generator.lo -MD -MP -MF $(DEPDIR)/python_generator.Tpo -c -o python_generator.lo `test -f 'google/protobuf/compiler/python/python_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_generator.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/python_generator.Tpo $(DEPDIR)/python_generator.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/python/python_generator.cc' object='python_generator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o python_generator.lo `test -f 'google/protobuf/compiler/python/python_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_generator.cc + +protobuf_lazy_descriptor_test-cpp_unittest.o: google/protobuf/compiler/cpp/cpp_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-cpp_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo -c -o protobuf_lazy_descriptor_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='protobuf_lazy_descriptor_test-cpp_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc + +protobuf_lazy_descriptor_test-cpp_unittest.obj: google/protobuf/compiler/cpp/cpp_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-cpp_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo -c -o protobuf_lazy_descriptor_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='protobuf_lazy_descriptor_test-cpp_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi` + +protobuf_lazy_descriptor_test-test_util.o: google/protobuf/test_util.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-test_util.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo -c -o protobuf_lazy_descriptor_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util.cc' object='protobuf_lazy_descriptor_test-test_util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc + +protobuf_lazy_descriptor_test-test_util.obj: google/protobuf/test_util.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-test_util.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo -c -o protobuf_lazy_descriptor_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util.cc' object='protobuf_lazy_descriptor_test-test_util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi` + +protobuf_lazy_descriptor_test-googletest.o: google/protobuf/testing/googletest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-googletest.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo -c -o protobuf_lazy_descriptor_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/googletest.cc' object='protobuf_lazy_descriptor_test-googletest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc + +protobuf_lazy_descriptor_test-googletest.obj: google/protobuf/testing/googletest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-googletest.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo -c -o protobuf_lazy_descriptor_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/googletest.cc' object='protobuf_lazy_descriptor_test-googletest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi` + +protobuf_lazy_descriptor_test-file.o: google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-file.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo -c -o protobuf_lazy_descriptor_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='protobuf_lazy_descriptor_test-file.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc + +protobuf_lazy_descriptor_test-file.obj: google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-file.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo -c -o protobuf_lazy_descriptor_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='protobuf_lazy_descriptor_test-file.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc + +protobuf_lazy_descriptor_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc + +protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc + +protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest.pb.o: google/protobuf/unittest.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest.pb.cc' object='protobuf_lazy_descriptor_test-unittest.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc + +protobuf_lazy_descriptor_test-unittest.pb.obj: google/protobuf/unittest.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest.pb.cc' object='protobuf_lazy_descriptor_test-unittest.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_empty.pb.o: google/protobuf/unittest_empty.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_empty.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_empty.pb.cc' object='protobuf_lazy_descriptor_test-unittest_empty.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc + +protobuf_lazy_descriptor_test-unittest_empty.pb.obj: google/protobuf/unittest_empty.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_empty.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_empty.pb.cc' object='protobuf_lazy_descriptor_test-unittest_empty.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_import.pb.o: google/protobuf/unittest_import.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc + +protobuf_lazy_descriptor_test-unittest_import.pb.obj: google/protobuf/unittest_import.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_import_public.pb.o: google/protobuf/unittest_import_public.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import_public.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_public.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc + +protobuf_lazy_descriptor_test-unittest_import_public.pb.obj: google/protobuf/unittest_import_public.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import_public.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_public.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_mset.pb.o: google/protobuf/unittest_mset.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_mset.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_mset.pb.cc' object='protobuf_lazy_descriptor_test-unittest_mset.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc + +protobuf_lazy_descriptor_test-unittest_mset.pb.obj: google/protobuf/unittest_mset.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_mset.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_mset.pb.cc' object='protobuf_lazy_descriptor_test-unittest_mset.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o: google/protobuf/unittest_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_optimize_for.pb.cc' object='protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc + +protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj: google/protobuf/unittest_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_optimize_for.pb.cc' object='protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o: google/protobuf/unittest_embed_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc + +protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj: google/protobuf/unittest_embed_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_custom_options.pb.o: google/protobuf/unittest_custom_options.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_custom_options.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_custom_options.pb.cc' object='protobuf_lazy_descriptor_test-unittest_custom_options.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc + +protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj: google/protobuf/unittest_custom_options.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_custom_options.pb.cc' object='protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o: google/protobuf/unittest_lite_imports_nonlite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc + +protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj: google/protobuf/unittest_lite_imports_nonlite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi` + +protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o: google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc + +protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj: google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi` + +protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo -c -o protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc + +protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo -c -o protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi` + +protobuf_lite_test-lite_unittest.o: google/protobuf/lite_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-lite_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo -c -o protobuf_lite_test-lite_unittest.o `test -f 'google/protobuf/lite_unittest.cc' || echo '$(srcdir)/'`google/protobuf/lite_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo $(DEPDIR)/protobuf_lite_test-lite_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/lite_unittest.cc' object='protobuf_lite_test-lite_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-lite_unittest.o `test -f 'google/protobuf/lite_unittest.cc' || echo '$(srcdir)/'`google/protobuf/lite_unittest.cc + +protobuf_lite_test-lite_unittest.obj: google/protobuf/lite_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-lite_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo -c -o protobuf_lite_test-lite_unittest.obj `if test -f 'google/protobuf/lite_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/lite_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/lite_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo $(DEPDIR)/protobuf_lite_test-lite_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/lite_unittest.cc' object='protobuf_lite_test-lite_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-lite_unittest.obj `if test -f 'google/protobuf/lite_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/lite_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/lite_unittest.cc'; fi` + +protobuf_lite_test-test_util_lite.o: google/protobuf/test_util_lite.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-test_util_lite.o -MD -MP -MF $(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo -c -o protobuf_lite_test-test_util_lite.o `test -f 'google/protobuf/test_util_lite.cc' || echo '$(srcdir)/'`google/protobuf/test_util_lite.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo $(DEPDIR)/protobuf_lite_test-test_util_lite.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util_lite.cc' object='protobuf_lite_test-test_util_lite.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-test_util_lite.o `test -f 'google/protobuf/test_util_lite.cc' || echo '$(srcdir)/'`google/protobuf/test_util_lite.cc + +protobuf_lite_test-test_util_lite.obj: google/protobuf/test_util_lite.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-test_util_lite.obj -MD -MP -MF $(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo -c -o protobuf_lite_test-test_util_lite.obj `if test -f 'google/protobuf/test_util_lite.cc'; then $(CYGPATH_W) 'google/protobuf/test_util_lite.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util_lite.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo $(DEPDIR)/protobuf_lite_test-test_util_lite.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util_lite.cc' object='protobuf_lite_test-test_util_lite.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-test_util_lite.obj `if test -f 'google/protobuf/test_util_lite.cc'; then $(CYGPATH_W) 'google/protobuf/test_util_lite.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util_lite.cc'; fi` + +protobuf_lite_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo -c -o protobuf_lite_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_lite_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc + +protobuf_lite_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo -c -o protobuf_lite_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_lite_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi` + +protobuf_lite_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_import_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo -c -o protobuf_lite_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_lite_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc + +protobuf_lite_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_import_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo -c -o protobuf_lite_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_lite_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi` + +protobuf_lite_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_import_public_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_lite_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_lite_test-unittest_import_public_lite.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc + +protobuf_lite_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_import_public_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_lite_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_lite_test-unittest_import_public_lite.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi` + +protobuf_test-common_unittest.o: google/protobuf/stubs/common_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-common_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-common_unittest.Tpo -c -o protobuf_test-common_unittest.o `test -f 'google/protobuf/stubs/common_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-common_unittest.Tpo $(DEPDIR)/protobuf_test-common_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/common_unittest.cc' object='protobuf_test-common_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-common_unittest.o `test -f 'google/protobuf/stubs/common_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common_unittest.cc + +protobuf_test-common_unittest.obj: google/protobuf/stubs/common_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-common_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-common_unittest.Tpo -c -o protobuf_test-common_unittest.obj `if test -f 'google/protobuf/stubs/common_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/common_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/common_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-common_unittest.Tpo $(DEPDIR)/protobuf_test-common_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/common_unittest.cc' object='protobuf_test-common_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-common_unittest.obj `if test -f 'google/protobuf/stubs/common_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/common_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/common_unittest.cc'; fi` + +protobuf_test-once_unittest.o: google/protobuf/stubs/once_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-once_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-once_unittest.Tpo -c -o protobuf_test-once_unittest.o `test -f 'google/protobuf/stubs/once_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-once_unittest.Tpo $(DEPDIR)/protobuf_test-once_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/once_unittest.cc' object='protobuf_test-once_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-once_unittest.o `test -f 'google/protobuf/stubs/once_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once_unittest.cc + +protobuf_test-once_unittest.obj: google/protobuf/stubs/once_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-once_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-once_unittest.Tpo -c -o protobuf_test-once_unittest.obj `if test -f 'google/protobuf/stubs/once_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/once_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/once_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-once_unittest.Tpo $(DEPDIR)/protobuf_test-once_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/once_unittest.cc' object='protobuf_test-once_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-once_unittest.obj `if test -f 'google/protobuf/stubs/once_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/once_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/once_unittest.cc'; fi` + +protobuf_test-strutil_unittest.o: google/protobuf/stubs/strutil_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-strutil_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-strutil_unittest.Tpo -c -o protobuf_test-strutil_unittest.o `test -f 'google/protobuf/stubs/strutil_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-strutil_unittest.Tpo $(DEPDIR)/protobuf_test-strutil_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/strutil_unittest.cc' object='protobuf_test-strutil_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-strutil_unittest.o `test -f 'google/protobuf/stubs/strutil_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil_unittest.cc + +protobuf_test-strutil_unittest.obj: google/protobuf/stubs/strutil_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-strutil_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-strutil_unittest.Tpo -c -o protobuf_test-strutil_unittest.obj `if test -f 'google/protobuf/stubs/strutil_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/strutil_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/strutil_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-strutil_unittest.Tpo $(DEPDIR)/protobuf_test-strutil_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/strutil_unittest.cc' object='protobuf_test-strutil_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-strutil_unittest.obj `if test -f 'google/protobuf/stubs/strutil_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/strutil_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/strutil_unittest.cc'; fi` + +protobuf_test-structurally_valid_unittest.o: google/protobuf/stubs/structurally_valid_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-structurally_valid_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo -c -o protobuf_test-structurally_valid_unittest.o `test -f 'google/protobuf/stubs/structurally_valid_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo $(DEPDIR)/protobuf_test-structurally_valid_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/structurally_valid_unittest.cc' object='protobuf_test-structurally_valid_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-structurally_valid_unittest.o `test -f 'google/protobuf/stubs/structurally_valid_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid_unittest.cc + +protobuf_test-structurally_valid_unittest.obj: google/protobuf/stubs/structurally_valid_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-structurally_valid_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo -c -o protobuf_test-structurally_valid_unittest.obj `if test -f 'google/protobuf/stubs/structurally_valid_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/structurally_valid_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/structurally_valid_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo $(DEPDIR)/protobuf_test-structurally_valid_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/structurally_valid_unittest.cc' object='protobuf_test-structurally_valid_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-structurally_valid_unittest.obj `if test -f 'google/protobuf/stubs/structurally_valid_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/structurally_valid_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/structurally_valid_unittest.cc'; fi` + +protobuf_test-stringprintf_unittest.o: google/protobuf/stubs/stringprintf_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-stringprintf_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo -c -o protobuf_test-stringprintf_unittest.o `test -f 'google/protobuf/stubs/stringprintf_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo $(DEPDIR)/protobuf_test-stringprintf_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/stringprintf_unittest.cc' object='protobuf_test-stringprintf_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-stringprintf_unittest.o `test -f 'google/protobuf/stubs/stringprintf_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf_unittest.cc + +protobuf_test-stringprintf_unittest.obj: google/protobuf/stubs/stringprintf_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-stringprintf_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo -c -o protobuf_test-stringprintf_unittest.obj `if test -f 'google/protobuf/stubs/stringprintf_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/stringprintf_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/stringprintf_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo $(DEPDIR)/protobuf_test-stringprintf_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/stringprintf_unittest.cc' object='protobuf_test-stringprintf_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-stringprintf_unittest.obj `if test -f 'google/protobuf/stubs/stringprintf_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/stringprintf_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/stringprintf_unittest.cc'; fi` + +protobuf_test-template_util_unittest.o: google/protobuf/stubs/template_util_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-template_util_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-template_util_unittest.Tpo -c -o protobuf_test-template_util_unittest.o `test -f 'google/protobuf/stubs/template_util_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/template_util_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-template_util_unittest.Tpo $(DEPDIR)/protobuf_test-template_util_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/template_util_unittest.cc' object='protobuf_test-template_util_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-template_util_unittest.o `test -f 'google/protobuf/stubs/template_util_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/template_util_unittest.cc + +protobuf_test-template_util_unittest.obj: google/protobuf/stubs/template_util_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-template_util_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-template_util_unittest.Tpo -c -o protobuf_test-template_util_unittest.obj `if test -f 'google/protobuf/stubs/template_util_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/template_util_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/template_util_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-template_util_unittest.Tpo $(DEPDIR)/protobuf_test-template_util_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/template_util_unittest.cc' object='protobuf_test-template_util_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-template_util_unittest.obj `if test -f 'google/protobuf/stubs/template_util_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/template_util_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/template_util_unittest.cc'; fi` + +protobuf_test-type_traits_unittest.o: google/protobuf/stubs/type_traits_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-type_traits_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-type_traits_unittest.Tpo -c -o protobuf_test-type_traits_unittest.o `test -f 'google/protobuf/stubs/type_traits_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/type_traits_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-type_traits_unittest.Tpo $(DEPDIR)/protobuf_test-type_traits_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/type_traits_unittest.cc' object='protobuf_test-type_traits_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-type_traits_unittest.o `test -f 'google/protobuf/stubs/type_traits_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/type_traits_unittest.cc + +protobuf_test-type_traits_unittest.obj: google/protobuf/stubs/type_traits_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-type_traits_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-type_traits_unittest.Tpo -c -o protobuf_test-type_traits_unittest.obj `if test -f 'google/protobuf/stubs/type_traits_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/type_traits_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/type_traits_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-type_traits_unittest.Tpo $(DEPDIR)/protobuf_test-type_traits_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/type_traits_unittest.cc' object='protobuf_test-type_traits_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-type_traits_unittest.obj `if test -f 'google/protobuf/stubs/type_traits_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/type_traits_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/type_traits_unittest.cc'; fi` + +protobuf_test-descriptor_database_unittest.o: google/protobuf/descriptor_database_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-descriptor_database_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo -c -o protobuf_test-descriptor_database_unittest.o `test -f 'google/protobuf/descriptor_database_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo $(DEPDIR)/protobuf_test-descriptor_database_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor_database_unittest.cc' object='protobuf_test-descriptor_database_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-descriptor_database_unittest.o `test -f 'google/protobuf/descriptor_database_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database_unittest.cc + +protobuf_test-descriptor_database_unittest.obj: google/protobuf/descriptor_database_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-descriptor_database_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo -c -o protobuf_test-descriptor_database_unittest.obj `if test -f 'google/protobuf/descriptor_database_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_database_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_database_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo $(DEPDIR)/protobuf_test-descriptor_database_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor_database_unittest.cc' object='protobuf_test-descriptor_database_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-descriptor_database_unittest.obj `if test -f 'google/protobuf/descriptor_database_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_database_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_database_unittest.cc'; fi` + +protobuf_test-descriptor_unittest.o: google/protobuf/descriptor_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-descriptor_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-descriptor_unittest.Tpo -c -o protobuf_test-descriptor_unittest.o `test -f 'google/protobuf/descriptor_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-descriptor_unittest.Tpo $(DEPDIR)/protobuf_test-descriptor_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor_unittest.cc' object='protobuf_test-descriptor_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-descriptor_unittest.o `test -f 'google/protobuf/descriptor_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_unittest.cc + +protobuf_test-descriptor_unittest.obj: google/protobuf/descriptor_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-descriptor_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-descriptor_unittest.Tpo -c -o protobuf_test-descriptor_unittest.obj `if test -f 'google/protobuf/descriptor_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-descriptor_unittest.Tpo $(DEPDIR)/protobuf_test-descriptor_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor_unittest.cc' object='protobuf_test-descriptor_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-descriptor_unittest.obj `if test -f 'google/protobuf/descriptor_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_unittest.cc'; fi` + +protobuf_test-dynamic_message_unittest.o: google/protobuf/dynamic_message_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-dynamic_message_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo -c -o protobuf_test-dynamic_message_unittest.o `test -f 'google/protobuf/dynamic_message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo $(DEPDIR)/protobuf_test-dynamic_message_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/dynamic_message_unittest.cc' object='protobuf_test-dynamic_message_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-dynamic_message_unittest.o `test -f 'google/protobuf/dynamic_message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message_unittest.cc + +protobuf_test-dynamic_message_unittest.obj: google/protobuf/dynamic_message_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-dynamic_message_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo -c -o protobuf_test-dynamic_message_unittest.obj `if test -f 'google/protobuf/dynamic_message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/dynamic_message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/dynamic_message_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo $(DEPDIR)/protobuf_test-dynamic_message_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/dynamic_message_unittest.cc' object='protobuf_test-dynamic_message_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-dynamic_message_unittest.obj `if test -f 'google/protobuf/dynamic_message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/dynamic_message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/dynamic_message_unittest.cc'; fi` + +protobuf_test-extension_set_unittest.o: google/protobuf/extension_set_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-extension_set_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-extension_set_unittest.Tpo -c -o protobuf_test-extension_set_unittest.o `test -f 'google/protobuf/extension_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-extension_set_unittest.Tpo $(DEPDIR)/protobuf_test-extension_set_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/extension_set_unittest.cc' object='protobuf_test-extension_set_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-extension_set_unittest.o `test -f 'google/protobuf/extension_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_unittest.cc + +protobuf_test-extension_set_unittest.obj: google/protobuf/extension_set_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-extension_set_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-extension_set_unittest.Tpo -c -o protobuf_test-extension_set_unittest.obj `if test -f 'google/protobuf/extension_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/extension_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/extension_set_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-extension_set_unittest.Tpo $(DEPDIR)/protobuf_test-extension_set_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/extension_set_unittest.cc' object='protobuf_test-extension_set_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-extension_set_unittest.obj `if test -f 'google/protobuf/extension_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/extension_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/extension_set_unittest.cc'; fi` + +protobuf_test-generated_message_reflection_unittest.o: google/protobuf/generated_message_reflection_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-generated_message_reflection_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo -c -o protobuf_test-generated_message_reflection_unittest.o `test -f 'google/protobuf/generated_message_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/generated_message_reflection_unittest.cc' object='protobuf_test-generated_message_reflection_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-generated_message_reflection_unittest.o `test -f 'google/protobuf/generated_message_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection_unittest.cc + +protobuf_test-generated_message_reflection_unittest.obj: google/protobuf/generated_message_reflection_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-generated_message_reflection_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo -c -o protobuf_test-generated_message_reflection_unittest.obj `if test -f 'google/protobuf/generated_message_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/generated_message_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/generated_message_reflection_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/generated_message_reflection_unittest.cc' object='protobuf_test-generated_message_reflection_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-generated_message_reflection_unittest.obj `if test -f 'google/protobuf/generated_message_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/generated_message_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/generated_message_reflection_unittest.cc'; fi` + +protobuf_test-message_unittest.o: google/protobuf/message_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-message_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-message_unittest.Tpo -c -o protobuf_test-message_unittest.o `test -f 'google/protobuf/message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/message_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-message_unittest.Tpo $(DEPDIR)/protobuf_test-message_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/message_unittest.cc' object='protobuf_test-message_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-message_unittest.o `test -f 'google/protobuf/message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/message_unittest.cc + +protobuf_test-message_unittest.obj: google/protobuf/message_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-message_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-message_unittest.Tpo -c -o protobuf_test-message_unittest.obj `if test -f 'google/protobuf/message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/message_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-message_unittest.Tpo $(DEPDIR)/protobuf_test-message_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/message_unittest.cc' object='protobuf_test-message_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-message_unittest.obj `if test -f 'google/protobuf/message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/message_unittest.cc'; fi` + +protobuf_test-reflection_ops_unittest.o: google/protobuf/reflection_ops_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-reflection_ops_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo -c -o protobuf_test-reflection_ops_unittest.o `test -f 'google/protobuf/reflection_ops_unittest.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo $(DEPDIR)/protobuf_test-reflection_ops_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/reflection_ops_unittest.cc' object='protobuf_test-reflection_ops_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-reflection_ops_unittest.o `test -f 'google/protobuf/reflection_ops_unittest.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops_unittest.cc + +protobuf_test-reflection_ops_unittest.obj: google/protobuf/reflection_ops_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-reflection_ops_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo -c -o protobuf_test-reflection_ops_unittest.obj `if test -f 'google/protobuf/reflection_ops_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/reflection_ops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/reflection_ops_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo $(DEPDIR)/protobuf_test-reflection_ops_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/reflection_ops_unittest.cc' object='protobuf_test-reflection_ops_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-reflection_ops_unittest.obj `if test -f 'google/protobuf/reflection_ops_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/reflection_ops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/reflection_ops_unittest.cc'; fi` + +protobuf_test-repeated_field_unittest.o: google/protobuf/repeated_field_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-repeated_field_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo -c -o protobuf_test-repeated_field_unittest.o `test -f 'google/protobuf/repeated_field_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo $(DEPDIR)/protobuf_test-repeated_field_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/repeated_field_unittest.cc' object='protobuf_test-repeated_field_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-repeated_field_unittest.o `test -f 'google/protobuf/repeated_field_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_unittest.cc + +protobuf_test-repeated_field_unittest.obj: google/protobuf/repeated_field_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-repeated_field_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo -c -o protobuf_test-repeated_field_unittest.obj `if test -f 'google/protobuf/repeated_field_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo $(DEPDIR)/protobuf_test-repeated_field_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/repeated_field_unittest.cc' object='protobuf_test-repeated_field_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-repeated_field_unittest.obj `if test -f 'google/protobuf/repeated_field_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_unittest.cc'; fi` + +protobuf_test-repeated_field_reflection_unittest.o: google/protobuf/repeated_field_reflection_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-repeated_field_reflection_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo -c -o protobuf_test-repeated_field_reflection_unittest.o `test -f 'google/protobuf/repeated_field_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_reflection_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/repeated_field_reflection_unittest.cc' object='protobuf_test-repeated_field_reflection_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-repeated_field_reflection_unittest.o `test -f 'google/protobuf/repeated_field_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_reflection_unittest.cc + +protobuf_test-repeated_field_reflection_unittest.obj: google/protobuf/repeated_field_reflection_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-repeated_field_reflection_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo -c -o protobuf_test-repeated_field_reflection_unittest.obj `if test -f 'google/protobuf/repeated_field_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_reflection_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/repeated_field_reflection_unittest.cc' object='protobuf_test-repeated_field_reflection_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-repeated_field_reflection_unittest.obj `if test -f 'google/protobuf/repeated_field_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_reflection_unittest.cc'; fi` + +protobuf_test-text_format_unittest.o: google/protobuf/text_format_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-text_format_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-text_format_unittest.Tpo -c -o protobuf_test-text_format_unittest.o `test -f 'google/protobuf/text_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/text_format_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-text_format_unittest.Tpo $(DEPDIR)/protobuf_test-text_format_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/text_format_unittest.cc' object='protobuf_test-text_format_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-text_format_unittest.o `test -f 'google/protobuf/text_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/text_format_unittest.cc + +protobuf_test-text_format_unittest.obj: google/protobuf/text_format_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-text_format_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-text_format_unittest.Tpo -c -o protobuf_test-text_format_unittest.obj `if test -f 'google/protobuf/text_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/text_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/text_format_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-text_format_unittest.Tpo $(DEPDIR)/protobuf_test-text_format_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/text_format_unittest.cc' object='protobuf_test-text_format_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-text_format_unittest.obj `if test -f 'google/protobuf/text_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/text_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/text_format_unittest.cc'; fi` + +protobuf_test-unknown_field_set_unittest.o: google/protobuf/unknown_field_set_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unknown_field_set_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo -c -o protobuf_test-unknown_field_set_unittest.o `test -f 'google/protobuf/unknown_field_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unknown_field_set_unittest.cc' object='protobuf_test-unknown_field_set_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unknown_field_set_unittest.o `test -f 'google/protobuf/unknown_field_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set_unittest.cc + +protobuf_test-unknown_field_set_unittest.obj: google/protobuf/unknown_field_set_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unknown_field_set_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo -c -o protobuf_test-unknown_field_set_unittest.obj `if test -f 'google/protobuf/unknown_field_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/unknown_field_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unknown_field_set_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unknown_field_set_unittest.cc' object='protobuf_test-unknown_field_set_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unknown_field_set_unittest.obj `if test -f 'google/protobuf/unknown_field_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/unknown_field_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unknown_field_set_unittest.cc'; fi` + +protobuf_test-wire_format_unittest.o: google/protobuf/wire_format_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-wire_format_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-wire_format_unittest.Tpo -c -o protobuf_test-wire_format_unittest.o `test -f 'google/protobuf/wire_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-wire_format_unittest.Tpo $(DEPDIR)/protobuf_test-wire_format_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/wire_format_unittest.cc' object='protobuf_test-wire_format_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-wire_format_unittest.o `test -f 'google/protobuf/wire_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_unittest.cc + +protobuf_test-wire_format_unittest.obj: google/protobuf/wire_format_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-wire_format_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-wire_format_unittest.Tpo -c -o protobuf_test-wire_format_unittest.obj `if test -f 'google/protobuf/wire_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/wire_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/wire_format_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-wire_format_unittest.Tpo $(DEPDIR)/protobuf_test-wire_format_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/wire_format_unittest.cc' object='protobuf_test-wire_format_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-wire_format_unittest.obj `if test -f 'google/protobuf/wire_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/wire_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/wire_format_unittest.cc'; fi` + +protobuf_test-coded_stream_unittest.o: google/protobuf/io/coded_stream_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-coded_stream_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo -c -o protobuf_test-coded_stream_unittest.o `test -f 'google/protobuf/io/coded_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo $(DEPDIR)/protobuf_test-coded_stream_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/coded_stream_unittest.cc' object='protobuf_test-coded_stream_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-coded_stream_unittest.o `test -f 'google/protobuf/io/coded_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream_unittest.cc + +protobuf_test-coded_stream_unittest.obj: google/protobuf/io/coded_stream_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-coded_stream_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo -c -o protobuf_test-coded_stream_unittest.obj `if test -f 'google/protobuf/io/coded_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/coded_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/coded_stream_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo $(DEPDIR)/protobuf_test-coded_stream_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/coded_stream_unittest.cc' object='protobuf_test-coded_stream_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-coded_stream_unittest.obj `if test -f 'google/protobuf/io/coded_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/coded_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/coded_stream_unittest.cc'; fi` + +protobuf_test-printer_unittest.o: google/protobuf/io/printer_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-printer_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-printer_unittest.Tpo -c -o protobuf_test-printer_unittest.o `test -f 'google/protobuf/io/printer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/printer_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-printer_unittest.Tpo $(DEPDIR)/protobuf_test-printer_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/printer_unittest.cc' object='protobuf_test-printer_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-printer_unittest.o `test -f 'google/protobuf/io/printer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/printer_unittest.cc + +protobuf_test-printer_unittest.obj: google/protobuf/io/printer_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-printer_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-printer_unittest.Tpo -c -o protobuf_test-printer_unittest.obj `if test -f 'google/protobuf/io/printer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/printer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/printer_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-printer_unittest.Tpo $(DEPDIR)/protobuf_test-printer_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/printer_unittest.cc' object='protobuf_test-printer_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-printer_unittest.obj `if test -f 'google/protobuf/io/printer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/printer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/printer_unittest.cc'; fi` + +protobuf_test-tokenizer_unittest.o: google/protobuf/io/tokenizer_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-tokenizer_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo -c -o protobuf_test-tokenizer_unittest.o `test -f 'google/protobuf/io/tokenizer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo $(DEPDIR)/protobuf_test-tokenizer_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/tokenizer_unittest.cc' object='protobuf_test-tokenizer_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-tokenizer_unittest.o `test -f 'google/protobuf/io/tokenizer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer_unittest.cc + +protobuf_test-tokenizer_unittest.obj: google/protobuf/io/tokenizer_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-tokenizer_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo -c -o protobuf_test-tokenizer_unittest.obj `if test -f 'google/protobuf/io/tokenizer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/tokenizer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/tokenizer_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo $(DEPDIR)/protobuf_test-tokenizer_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/tokenizer_unittest.cc' object='protobuf_test-tokenizer_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-tokenizer_unittest.obj `if test -f 'google/protobuf/io/tokenizer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/tokenizer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/tokenizer_unittest.cc'; fi` + +protobuf_test-zero_copy_stream_unittest.o: google/protobuf/io/zero_copy_stream_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-zero_copy_stream_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo -c -o protobuf_test-zero_copy_stream_unittest.o `test -f 'google/protobuf/io/zero_copy_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/zero_copy_stream_unittest.cc' object='protobuf_test-zero_copy_stream_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-zero_copy_stream_unittest.o `test -f 'google/protobuf/io/zero_copy_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_unittest.cc + +protobuf_test-zero_copy_stream_unittest.obj: google/protobuf/io/zero_copy_stream_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-zero_copy_stream_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo -c -o protobuf_test-zero_copy_stream_unittest.obj `if test -f 'google/protobuf/io/zero_copy_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/zero_copy_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/zero_copy_stream_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/zero_copy_stream_unittest.cc' object='protobuf_test-zero_copy_stream_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-zero_copy_stream_unittest.obj `if test -f 'google/protobuf/io/zero_copy_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/zero_copy_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/zero_copy_stream_unittest.cc'; fi` + +protobuf_test-command_line_interface_unittest.o: google/protobuf/compiler/command_line_interface_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-command_line_interface_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo -c -o protobuf_test-command_line_interface_unittest.o `test -f 'google/protobuf/compiler/command_line_interface_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo $(DEPDIR)/protobuf_test-command_line_interface_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/command_line_interface_unittest.cc' object='protobuf_test-command_line_interface_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-command_line_interface_unittest.o `test -f 'google/protobuf/compiler/command_line_interface_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface_unittest.cc + +protobuf_test-command_line_interface_unittest.obj: google/protobuf/compiler/command_line_interface_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-command_line_interface_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo -c -o protobuf_test-command_line_interface_unittest.obj `if test -f 'google/protobuf/compiler/command_line_interface_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/command_line_interface_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/command_line_interface_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo $(DEPDIR)/protobuf_test-command_line_interface_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/command_line_interface_unittest.cc' object='protobuf_test-command_line_interface_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-command_line_interface_unittest.obj `if test -f 'google/protobuf/compiler/command_line_interface_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/command_line_interface_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/command_line_interface_unittest.cc'; fi` + +protobuf_test-importer_unittest.o: google/protobuf/compiler/importer_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-importer_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-importer_unittest.Tpo -c -o protobuf_test-importer_unittest.o `test -f 'google/protobuf/compiler/importer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-importer_unittest.Tpo $(DEPDIR)/protobuf_test-importer_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/importer_unittest.cc' object='protobuf_test-importer_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-importer_unittest.o `test -f 'google/protobuf/compiler/importer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer_unittest.cc + +protobuf_test-importer_unittest.obj: google/protobuf/compiler/importer_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-importer_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-importer_unittest.Tpo -c -o protobuf_test-importer_unittest.obj `if test -f 'google/protobuf/compiler/importer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/importer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/importer_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-importer_unittest.Tpo $(DEPDIR)/protobuf_test-importer_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/importer_unittest.cc' object='protobuf_test-importer_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-importer_unittest.obj `if test -f 'google/protobuf/compiler/importer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/importer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/importer_unittest.cc'; fi` + +protobuf_test-mock_code_generator.o: google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-mock_code_generator.o -MD -MP -MF $(DEPDIR)/protobuf_test-mock_code_generator.Tpo -c -o protobuf_test-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-mock_code_generator.Tpo $(DEPDIR)/protobuf_test-mock_code_generator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='protobuf_test-mock_code_generator.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc + +protobuf_test-mock_code_generator.obj: google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-mock_code_generator.obj -MD -MP -MF $(DEPDIR)/protobuf_test-mock_code_generator.Tpo -c -o protobuf_test-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-mock_code_generator.Tpo $(DEPDIR)/protobuf_test-mock_code_generator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='protobuf_test-mock_code_generator.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi` + +protobuf_test-parser_unittest.o: google/protobuf/compiler/parser_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-parser_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-parser_unittest.Tpo -c -o protobuf_test-parser_unittest.o `test -f 'google/protobuf/compiler/parser_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-parser_unittest.Tpo $(DEPDIR)/protobuf_test-parser_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/parser_unittest.cc' object='protobuf_test-parser_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-parser_unittest.o `test -f 'google/protobuf/compiler/parser_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser_unittest.cc + +protobuf_test-parser_unittest.obj: google/protobuf/compiler/parser_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-parser_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-parser_unittest.Tpo -c -o protobuf_test-parser_unittest.obj `if test -f 'google/protobuf/compiler/parser_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/parser_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/parser_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-parser_unittest.Tpo $(DEPDIR)/protobuf_test-parser_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/parser_unittest.cc' object='protobuf_test-parser_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-parser_unittest.obj `if test -f 'google/protobuf/compiler/parser_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/parser_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/parser_unittest.cc'; fi` + +protobuf_test-cpp_bootstrap_unittest.o: google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_bootstrap_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo -c -o protobuf_test-cpp_bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' object='protobuf_test-cpp_bootstrap_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc + +protobuf_test-cpp_bootstrap_unittest.obj: google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_bootstrap_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo -c -o protobuf_test-cpp_bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' object='protobuf_test-cpp_bootstrap_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; fi` + +protobuf_test-cpp_unittest.o: google/protobuf/compiler/cpp/cpp_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_unittest.Tpo -c -o protobuf_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='protobuf_test-cpp_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc + +protobuf_test-cpp_unittest.obj: google/protobuf/compiler/cpp/cpp_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_unittest.Tpo -c -o protobuf_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='protobuf_test-cpp_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi` + +protobuf_test-cpp_plugin_unittest.o: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_plugin_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='protobuf_test-cpp_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc + +protobuf_test-cpp_plugin_unittest.obj: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_plugin_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='protobuf_test-cpp_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi` + +protobuf_test-java_plugin_unittest.o: google/protobuf/compiler/java/java_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-java_plugin_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-java_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='protobuf_test-java_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc + +protobuf_test-java_plugin_unittest.obj: google/protobuf/compiler/java/java_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-java_plugin_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-java_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='protobuf_test-java_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi` + +protobuf_test-java_doc_comment_unittest.o: google/protobuf/compiler/java/java_doc_comment_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-java_doc_comment_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo -c -o protobuf_test-java_doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_doc_comment_unittest.cc' object='protobuf_test-java_doc_comment_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-java_doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment_unittest.cc + +protobuf_test-java_doc_comment_unittest.obj: google/protobuf/compiler/java/java_doc_comment_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-java_doc_comment_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo -c -o protobuf_test-java_doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_doc_comment_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_doc_comment_unittest.cc' object='protobuf_test-java_doc_comment_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-java_doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_doc_comment_unittest.cc'; fi` + +protobuf_test-python_plugin_unittest.o: google/protobuf/compiler/python/python_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-python_plugin_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-python_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='protobuf_test-python_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc + +protobuf_test-python_plugin_unittest.obj: google/protobuf/compiler/python/python_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-python_plugin_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-python_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='protobuf_test-python_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi` + +protobuf_test-test_util.o: google/protobuf/test_util.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-test_util.o -MD -MP -MF $(DEPDIR)/protobuf_test-test_util.Tpo -c -o protobuf_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-test_util.Tpo $(DEPDIR)/protobuf_test-test_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util.cc' object='protobuf_test-test_util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc + +protobuf_test-test_util.obj: google/protobuf/test_util.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-test_util.obj -MD -MP -MF $(DEPDIR)/protobuf_test-test_util.Tpo -c -o protobuf_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-test_util.Tpo $(DEPDIR)/protobuf_test-test_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util.cc' object='protobuf_test-test_util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi` + +protobuf_test-googletest.o: google/protobuf/testing/googletest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-googletest.o -MD -MP -MF $(DEPDIR)/protobuf_test-googletest.Tpo -c -o protobuf_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-googletest.Tpo $(DEPDIR)/protobuf_test-googletest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/googletest.cc' object='protobuf_test-googletest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc + +protobuf_test-googletest.obj: google/protobuf/testing/googletest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-googletest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-googletest.Tpo -c -o protobuf_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-googletest.Tpo $(DEPDIR)/protobuf_test-googletest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/googletest.cc' object='protobuf_test-googletest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi` + +protobuf_test-file.o: google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-file.o -MD -MP -MF $(DEPDIR)/protobuf_test-file.Tpo -c -o protobuf_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-file.Tpo $(DEPDIR)/protobuf_test-file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='protobuf_test-file.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc + +protobuf_test-file.obj: google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-file.obj -MD -MP -MF $(DEPDIR)/protobuf_test-file.Tpo -c -o protobuf_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-file.Tpo $(DEPDIR)/protobuf_test-file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='protobuf_test-file.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi` + +protobuf_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo -c -o protobuf_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc + +protobuf_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo -c -o protobuf_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi` + +protobuf_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo -c -o protobuf_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc + +protobuf_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo -c -o protobuf_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi` + +protobuf_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_public_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_test-unittest_import_public_lite.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc + +protobuf_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_public_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_test-unittest_import_public_lite.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi` + +protobuf_test-unittest.pb.o: google/protobuf/unittest.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest.pb.Tpo -c -o protobuf_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest.pb.Tpo $(DEPDIR)/protobuf_test-unittest.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest.pb.cc' object='protobuf_test-unittest.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc + +protobuf_test-unittest.pb.obj: google/protobuf/unittest.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest.pb.Tpo -c -o protobuf_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest.pb.Tpo $(DEPDIR)/protobuf_test-unittest.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest.pb.cc' object='protobuf_test-unittest.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi` + +protobuf_test-unittest_empty.pb.o: google/protobuf/unittest_empty.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_empty.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo -c -o protobuf_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo $(DEPDIR)/protobuf_test-unittest_empty.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_empty.pb.cc' object='protobuf_test-unittest_empty.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc + +protobuf_test-unittest_empty.pb.obj: google/protobuf/unittest_empty.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_empty.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo -c -o protobuf_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo $(DEPDIR)/protobuf_test-unittest_empty.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_empty.pb.cc' object='protobuf_test-unittest_empty.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi` + +protobuf_test-unittest_import.pb.o: google/protobuf/unittest_import.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import.pb.Tpo -c -o protobuf_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import.pb.cc' object='protobuf_test-unittest_import.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc + +protobuf_test-unittest_import.pb.obj: google/protobuf/unittest_import.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import.pb.Tpo -c -o protobuf_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import.pb.cc' object='protobuf_test-unittest_import.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi` + +protobuf_test-unittest_import_public.pb.o: google/protobuf/unittest_import_public.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_public.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo -c -o protobuf_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_public.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public.pb.cc' object='protobuf_test-unittest_import_public.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc + +protobuf_test-unittest_import_public.pb.obj: google/protobuf/unittest_import_public.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_public.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo -c -o protobuf_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_public.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public.pb.cc' object='protobuf_test-unittest_import_public.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi` + +protobuf_test-unittest_mset.pb.o: google/protobuf/unittest_mset.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_mset.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo -c -o protobuf_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo $(DEPDIR)/protobuf_test-unittest_mset.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_mset.pb.cc' object='protobuf_test-unittest_mset.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc + +protobuf_test-unittest_mset.pb.obj: google/protobuf/unittest_mset.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_mset.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo -c -o protobuf_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo $(DEPDIR)/protobuf_test-unittest_mset.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_mset.pb.cc' object='protobuf_test-unittest_mset.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi` + +protobuf_test-unittest_optimize_for.pb.o: google/protobuf/unittest_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_optimize_for.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo -c -o protobuf_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_optimize_for.pb.cc' object='protobuf_test-unittest_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc + +protobuf_test-unittest_optimize_for.pb.obj: google/protobuf/unittest_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_optimize_for.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo -c -o protobuf_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_optimize_for.pb.cc' object='protobuf_test-unittest_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi` + +protobuf_test-unittest_embed_optimize_for.pb.o: google/protobuf/unittest_embed_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_embed_optimize_for.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo -c -o protobuf_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='protobuf_test-unittest_embed_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc + +protobuf_test-unittest_embed_optimize_for.pb.obj: google/protobuf/unittest_embed_optimize_for.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_embed_optimize_for.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo -c -o protobuf_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='protobuf_test-unittest_embed_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi` + +protobuf_test-unittest_custom_options.pb.o: google/protobuf/unittest_custom_options.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_custom_options.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo -c -o protobuf_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_custom_options.pb.cc' object='protobuf_test-unittest_custom_options.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc + +protobuf_test-unittest_custom_options.pb.obj: google/protobuf/unittest_custom_options.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_custom_options.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo -c -o protobuf_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_custom_options.pb.cc' object='protobuf_test-unittest_custom_options.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi` + +protobuf_test-unittest_lite_imports_nonlite.pb.o: google/protobuf/unittest_lite_imports_nonlite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_lite_imports_nonlite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo -c -o protobuf_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='protobuf_test-unittest_lite_imports_nonlite.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc + +protobuf_test-unittest_lite_imports_nonlite.pb.obj: google/protobuf/unittest_lite_imports_nonlite.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_lite_imports_nonlite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo -c -o protobuf_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='protobuf_test-unittest_lite_imports_nonlite.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi` + +protobuf_test-unittest_no_generic_services.pb.o: google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_no_generic_services.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_test-unittest_no_generic_services.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc + +protobuf_test-unittest_no_generic_services.pb.obj: google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_no_generic_services.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_test-unittest_no_generic_services.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi` + +protobuf_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo -c -o protobuf_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='protobuf_test-cpp_test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc + +protobuf_test-cpp_test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_test_bad_identifiers.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo -c -o protobuf_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='protobuf_test-cpp_test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi` + +main.o: google/protobuf/compiler/main.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT main.o -MD -MP -MF $(DEPDIR)/main.Tpo -c -o main.o `test -f 'google/protobuf/compiler/main.cc' || echo '$(srcdir)/'`google/protobuf/compiler/main.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/main.Tpo $(DEPDIR)/main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/main.cc' object='main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o main.o `test -f 'google/protobuf/compiler/main.cc' || echo '$(srcdir)/'`google/protobuf/compiler/main.cc + +main.obj: google/protobuf/compiler/main.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT main.obj -MD -MP -MF $(DEPDIR)/main.Tpo -c -o main.obj `if test -f 'google/protobuf/compiler/main.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/main.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/main.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/main.Tpo $(DEPDIR)/main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/main.cc' object='main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o main.obj `if test -f 'google/protobuf/compiler/main.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/main.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/main.cc'; fi` + +test_plugin-mock_code_generator.o: google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-mock_code_generator.o -MD -MP -MF $(DEPDIR)/test_plugin-mock_code_generator.Tpo -c -o test_plugin-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-mock_code_generator.Tpo $(DEPDIR)/test_plugin-mock_code_generator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='test_plugin-mock_code_generator.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc + +test_plugin-mock_code_generator.obj: google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-mock_code_generator.obj -MD -MP -MF $(DEPDIR)/test_plugin-mock_code_generator.Tpo -c -o test_plugin-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-mock_code_generator.Tpo $(DEPDIR)/test_plugin-mock_code_generator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='test_plugin-mock_code_generator.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi` + +test_plugin-file.o: google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-file.o -MD -MP -MF $(DEPDIR)/test_plugin-file.Tpo -c -o test_plugin-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-file.Tpo $(DEPDIR)/test_plugin-file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='test_plugin-file.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc + +test_plugin-file.obj: google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-file.obj -MD -MP -MF $(DEPDIR)/test_plugin-file.Tpo -c -o test_plugin-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-file.Tpo $(DEPDIR)/test_plugin-file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='test_plugin-file.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi` + +test_plugin-test_plugin.o: google/protobuf/compiler/test_plugin.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-test_plugin.o -MD -MP -MF $(DEPDIR)/test_plugin-test_plugin.Tpo -c -o test_plugin-test_plugin.o `test -f 'google/protobuf/compiler/test_plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/test_plugin.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-test_plugin.Tpo $(DEPDIR)/test_plugin-test_plugin.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/test_plugin.cc' object='test_plugin-test_plugin.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-test_plugin.o `test -f 'google/protobuf/compiler/test_plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/test_plugin.cc + +test_plugin-test_plugin.obj: google/protobuf/compiler/test_plugin.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-test_plugin.obj -MD -MP -MF $(DEPDIR)/test_plugin-test_plugin.Tpo -c -o test_plugin-test_plugin.obj `if test -f 'google/protobuf/compiler/test_plugin.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/test_plugin.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/test_plugin.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-test_plugin.Tpo $(DEPDIR)/test_plugin-test_plugin.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/test_plugin.cc' object='test_plugin-test_plugin.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-test_plugin.obj `if test -f 'google/protobuf/compiler/test_plugin.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/test_plugin.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/test_plugin.cc'; fi` + +zcgunzip.o: google/protobuf/testing/zcgunzip.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zcgunzip.o -MD -MP -MF $(DEPDIR)/zcgunzip.Tpo -c -o zcgunzip.o `test -f 'google/protobuf/testing/zcgunzip.cc' || echo '$(srcdir)/'`google/protobuf/testing/zcgunzip.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zcgunzip.Tpo $(DEPDIR)/zcgunzip.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/zcgunzip.cc' object='zcgunzip.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zcgunzip.o `test -f 'google/protobuf/testing/zcgunzip.cc' || echo '$(srcdir)/'`google/protobuf/testing/zcgunzip.cc + +zcgunzip.obj: google/protobuf/testing/zcgunzip.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zcgunzip.obj -MD -MP -MF $(DEPDIR)/zcgunzip.Tpo -c -o zcgunzip.obj `if test -f 'google/protobuf/testing/zcgunzip.cc'; then $(CYGPATH_W) 'google/protobuf/testing/zcgunzip.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/zcgunzip.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zcgunzip.Tpo $(DEPDIR)/zcgunzip.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/zcgunzip.cc' object='zcgunzip.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zcgunzip.obj `if test -f 'google/protobuf/testing/zcgunzip.cc'; then $(CYGPATH_W) 'google/protobuf/testing/zcgunzip.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/zcgunzip.cc'; fi` + +zcgzip.o: google/protobuf/testing/zcgzip.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zcgzip.o -MD -MP -MF $(DEPDIR)/zcgzip.Tpo -c -o zcgzip.o `test -f 'google/protobuf/testing/zcgzip.cc' || echo '$(srcdir)/'`google/protobuf/testing/zcgzip.cc +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zcgzip.Tpo $(DEPDIR)/zcgzip.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/zcgzip.cc' object='zcgzip.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zcgzip.o `test -f 'google/protobuf/testing/zcgzip.cc' || echo '$(srcdir)/'`google/protobuf/testing/zcgzip.cc + +zcgzip.obj: google/protobuf/testing/zcgzip.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zcgzip.obj -MD -MP -MF $(DEPDIR)/zcgzip.Tpo -c -o zcgzip.obj `if test -f 'google/protobuf/testing/zcgzip.cc'; then $(CYGPATH_W) 'google/protobuf/testing/zcgzip.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/zcgzip.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zcgzip.Tpo $(DEPDIR)/zcgzip.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/zcgzip.cc' object='zcgzip.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zcgzip.obj `if test -f 'google/protobuf/testing/zcgzip.cc'; then $(CYGPATH_W) 'google/protobuf/testing/zcgzip.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/zcgzip.cc'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-nobase_dist_protoDATA: $(nobase_dist_proto_DATA) + @$(NORMAL_INSTALL) + test -z "$(protodir)" || $(MKDIR_P) "$(DESTDIR)$(protodir)" + @list='$(nobase_dist_proto_DATA)'; test -n "$(protodir)" || list=; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo "$(MKDIR_P) '$(DESTDIR)$(protodir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(protodir)/$$dir"; }; \ + echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(protodir)/$$dir'"; \ + $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(protodir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_dist_protoDATA: + @$(NORMAL_UNINSTALL) + @list='$(nobase_dist_proto_DATA)'; test -n "$(protodir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(protodir)'; $(am__uninstall_files_from_dir) +install-nobase_includeHEADERS: $(nobase_include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo "$(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS) +install-binPROGRAMS: install-libLTLIBRARIES + +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(protodir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-local mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-nobase_dist_protoDATA \ + install-nobase_includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ + uninstall-nobase_dist_protoDATA \ + uninstall-nobase_includeHEADERS + +.MAKE: all check check-am install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-local ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man \ + install-nobase_dist_protoDATA install-nobase_includeHEADERS \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ + uninstall-nobase_dist_protoDATA \ + uninstall-nobase_includeHEADERS + + +# Not sure why these don't get cleaned automatically. +clean-local: + rm -f *.loT + +@USE_EXTERNAL_PROTOC_TRUE@unittest_proto_middleman: $(protoc_inputs) +@USE_EXTERNAL_PROTOC_TRUE@ $(PROTOC) -I$(srcdir) --cpp_out=. $^ +@USE_EXTERNAL_PROTOC_TRUE@ touch unittest_proto_middleman + +# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is +# relative to srcdir, which may not be the same as the current directory when +# building out-of-tree. +@USE_EXTERNAL_PROTOC_FALSE@unittest_proto_middleman: protoc$(EXEEXT) $(protoc_inputs) +@USE_EXTERNAL_PROTOC_FALSE@ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd $(protoc_inputs) ) +@USE_EXTERNAL_PROTOC_FALSE@ touch unittest_proto_middleman + +$(protoc_outputs): unittest_proto_middleman + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/code_generator.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/code_generator.cc new file mode 100644 index 0000000..455c239 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/code_generator.cc @@ -0,0 +1,80 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { + +CodeGenerator::~CodeGenerator() {} +GeneratorContext::~GeneratorContext() {} + +io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert( + const string& filename, const string& insertion_point) { + GOOGLE_LOG(FATAL) << "This GeneratorContext does not support insertion."; + return NULL; // make compiler happy +} + +void GeneratorContext::ListParsedFiles( + vector* output) { + GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles"; +} + +// Parses a set of comma-delimited name/value pairs. +void ParseGeneratorParameter(const string& text, + vector >* output) { + vector parts; + SplitStringUsing(text, ",", &parts); + + for (int i = 0; i < parts.size(); i++) { + string::size_type equals_pos = parts[i].find_first_of('='); + pair value; + if (equals_pos == string::npos) { + value.first = parts[i]; + value.second = ""; + } else { + value.first = parts[i].substr(0, equals_pos); + value.second = parts[i].substr(equals_pos + 1); + } + output->push_back(value); + } +} + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/code_generator.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/code_generator.h new file mode 100644 index 0000000..252f68d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/code_generator.h @@ -0,0 +1,142 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Defines the abstract interface implemented by each of the language-specific +// code generators. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__ + +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +namespace io { class ZeroCopyOutputStream; } +class FileDescriptor; + +namespace compiler { + +// Defined in this file. +class CodeGenerator; +class GeneratorContext; + +// The abstract interface to a class which generates code implementing a +// particular proto file in a particular language. A number of these may +// be registered with CommandLineInterface to support various languages. +class LIBPROTOC_EXPORT CodeGenerator { + public: + inline CodeGenerator() {} + virtual ~CodeGenerator(); + + // Generates code for the given proto file, generating one or more files in + // the given output directory. + // + // A parameter to be passed to the generator can be specified on the + // command line. This is intended to be used by Java and similar languages + // to specify which specific class from the proto file is to be generated, + // though it could have other uses as well. It is empty if no parameter was + // given. + // + // Returns true if successful. Otherwise, sets *error to a description of + // the problem (e.g. "invalid parameter") and returns false. + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodeGenerator); +}; + +// CodeGenerators generate one or more files in a given directory. This +// abstract interface represents the directory to which the CodeGenerator is +// to write and other information about the context in which the Generator +// runs. +class LIBPROTOC_EXPORT GeneratorContext { + public: + inline GeneratorContext() {} + virtual ~GeneratorContext(); + + // Opens the given file, truncating it if it exists, and returns a + // ZeroCopyOutputStream that writes to the file. The caller takes ownership + // of the returned object. This method never fails (a dummy stream will be + // returned instead). + // + // The filename given should be relative to the root of the source tree. + // E.g. the C++ generator, when generating code for "foo/bar.proto", will + // generate the files "foo/bar.pb.h" and "foo/bar.pb.cc"; note that + // "foo/" is included in these filenames. The filename is not allowed to + // contain "." or ".." components. + virtual io::ZeroCopyOutputStream* Open(const string& filename) = 0; + + // Creates a ZeroCopyOutputStream which will insert code into the given file + // at the given insertion point. See plugin.proto (plugin.pb.h) for more + // information on insertion points. The default implementation + // assert-fails -- it exists only for backwards-compatibility. + // + // WARNING: This feature is currently EXPERIMENTAL and is subject to change. + virtual io::ZeroCopyOutputStream* OpenForInsert( + const string& filename, const string& insertion_point); + + // Returns a vector of FileDescriptors for all the files being compiled + // in this run. Useful for languages, such as Go, that treat files + // differently when compiled as a set rather than individually. + virtual void ListParsedFiles(vector* output); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext); +}; + +// The type GeneratorContext was once called OutputDirectory. This typedef +// provides backward compatibility. +typedef GeneratorContext OutputDirectory; + +// Several code generators treat the parameter argument as holding a +// list of options separated by commas. This helper function parses +// a set of comma-delimited name/value pairs: e.g., +// "foo=bar,baz,qux=corge" +// parses to the pairs: +// ("foo", "bar"), ("baz", ""), ("qux", "corge") +extern void ParseGeneratorParameter(const string&, + vector >*); + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface.cc new file mode 100644 index 0000000..b9293c9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface.cc @@ -0,0 +1,1437 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#include +#else +#include +#endif +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace compiler { + +#if defined(_WIN32) +#define mkdir(name, mode) mkdir(name) +#ifndef W_OK +#define W_OK 02 // not defined by MSVC for whatever reason +#endif +#ifndef F_OK +#define F_OK 00 // not defined by MSVC for whatever reason +#endif +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif +#endif + +#ifndef O_BINARY +#ifdef _O_BINARY +#define O_BINARY _O_BINARY +#else +#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. +#endif +#endif + +namespace { +#if defined(_WIN32) && !defined(__CYGWIN__) +static const char* kPathSeparator = ";"; +#else +static const char* kPathSeparator = ":"; +#endif + +// Returns true if the text looks like a Windows-style absolute path, starting +// with a drive letter. Example: "C:\foo". TODO(kenton): Share this with +// copy in importer.cc? +static bool IsWindowsAbsolutePath(const string& text) { +#if defined(_WIN32) || defined(__CYGWIN__) + return text.size() >= 3 && text[1] == ':' && + isalpha(text[0]) && + (text[2] == '/' || text[2] == '\\') && + text.find_last_of(':') == 1; +#else + return false; +#endif +} + +void SetFdToTextMode(int fd) { +#ifdef _WIN32 + if (_setmode(fd, _O_TEXT) == -1) { + // This should never happen, I think. + GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_TEXT): " << strerror(errno); + } +#endif + // (Text and binary are the same on non-Windows platforms.) +} + +void SetFdToBinaryMode(int fd) { +#ifdef _WIN32 + if (_setmode(fd, _O_BINARY) == -1) { + // This should never happen, I think. + GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_BINARY): " << strerror(errno); + } +#endif + // (Text and binary are the same on non-Windows platforms.) +} + +void AddTrailingSlash(string* path) { + if (!path->empty() && path->at(path->size() - 1) != '/') { + path->push_back('/'); + } +} + +bool VerifyDirectoryExists(const string& path) { + if (path.empty()) return true; + + if (access(path.c_str(), F_OK) == -1) { + cerr << path << ": " << strerror(errno) << endl; + return false; + } else { + return true; + } +} + +// Try to create the parent directory of the given file, creating the parent's +// parent if necessary, and so on. The full file name is actually +// (prefix + filename), but we assume |prefix| already exists and only create +// directories listed in |filename|. +bool TryCreateParentDirectory(const string& prefix, const string& filename) { + // Recursively create parent directories to the output file. + vector parts; + SplitStringUsing(filename, "/", &parts); + string path_so_far = prefix; + for (int i = 0; i < parts.size() - 1; i++) { + path_so_far += parts[i]; + if (mkdir(path_so_far.c_str(), 0777) != 0) { + if (errno != EEXIST) { + cerr << filename << ": while trying to create directory " + << path_so_far << ": " << strerror(errno) << endl; + return false; + } + } + path_so_far += '/'; + } + + return true; +} + +} // namespace + +// A MultiFileErrorCollector that prints errors to stderr. +class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, + public io::ErrorCollector { + public: + ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL) + : format_(format), tree_(tree) {} + ~ErrorPrinter() {} + + // implements MultiFileErrorCollector ------------------------------ + void AddError(const string& filename, int line, int column, + const string& message) { + + // Print full path when running under MSVS + string dfile; + if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS && + tree_ != NULL && + tree_->VirtualFileToDiskFile(filename, &dfile)) { + cerr << dfile; + } else { + cerr << filename; + } + + // Users typically expect 1-based line/column numbers, so we add 1 + // to each here. + if (line != -1) { + // Allow for both GCC- and Visual-Studio-compatible output. + switch (format_) { + case CommandLineInterface::ERROR_FORMAT_GCC: + cerr << ":" << (line + 1) << ":" << (column + 1); + break; + case CommandLineInterface::ERROR_FORMAT_MSVS: + cerr << "(" << (line + 1) << ") : error in column=" << (column + 1); + break; + } + } + + cerr << ": " << message << endl; + } + + // implements io::ErrorCollector ----------------------------------- + void AddError(int line, int column, const string& message) { + AddError("input", line, column, message); + } + + private: + const ErrorFormat format_; + DiskSourceTree *tree_; +}; + +// ------------------------------------------------------------------- + +// A GeneratorContext implementation that buffers files in memory, then dumps +// them all to disk on demand. +class CommandLineInterface::GeneratorContextImpl : public GeneratorContext { + public: + GeneratorContextImpl(const vector& parsed_files); + ~GeneratorContextImpl(); + + // Write all files in the directory to disk at the given output location, + // which must end in a '/'. + bool WriteAllToDisk(const string& prefix); + + // Write the contents of this directory to a ZIP-format archive with the + // given name. + bool WriteAllToZip(const string& filename); + + // Add a boilerplate META-INF/MANIFEST.MF file as required by the Java JAR + // format, unless one has already been written. + void AddJarManifest(); + + // implements GeneratorContext -------------------------------------- + io::ZeroCopyOutputStream* Open(const string& filename); + io::ZeroCopyOutputStream* OpenForInsert( + const string& filename, const string& insertion_point); + void ListParsedFiles(vector* output) { + *output = parsed_files_; + } + + private: + friend class MemoryOutputStream; + + // map instead of hash_map so that files are written in order (good when + // writing zips). + map files_; + const vector& parsed_files_; + bool had_error_; +}; + +class CommandLineInterface::MemoryOutputStream + : public io::ZeroCopyOutputStream { + public: + MemoryOutputStream(GeneratorContextImpl* directory, const string& filename); + MemoryOutputStream(GeneratorContextImpl* directory, const string& filename, + const string& insertion_point); + virtual ~MemoryOutputStream(); + + // implements ZeroCopyOutputStream --------------------------------- + virtual bool Next(void** data, int* size) { return inner_->Next(data, size); } + virtual void BackUp(int count) { inner_->BackUp(count); } + virtual int64 ByteCount() const { return inner_->ByteCount(); } + + private: + // Where to insert the string when it's done. + GeneratorContextImpl* directory_; + string filename_; + string insertion_point_; + + // The string we're building. + string data_; + + // StringOutputStream writing to data_. + scoped_ptr inner_; +}; + +// ------------------------------------------------------------------- + +CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl( + const vector& parsed_files) + : parsed_files_(parsed_files), + had_error_(false) { +} + +CommandLineInterface::GeneratorContextImpl::~GeneratorContextImpl() { + STLDeleteValues(&files_); +} + +bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk( + const string& prefix) { + if (had_error_) { + return false; + } + + if (!VerifyDirectoryExists(prefix)) { + return false; + } + + for (map::const_iterator iter = files_.begin(); + iter != files_.end(); ++iter) { + const string& relative_filename = iter->first; + const char* data = iter->second->data(); + int size = iter->second->size(); + + if (!TryCreateParentDirectory(prefix, relative_filename)) { + return false; + } + string filename = prefix + relative_filename; + + // Create the output file. + int file_descriptor; + do { + file_descriptor = + open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); + } while (file_descriptor < 0 && errno == EINTR); + + if (file_descriptor < 0) { + int error = errno; + cerr << filename << ": " << strerror(error); + return false; + } + + // Write the file. + while (size > 0) { + int write_result; + do { + write_result = write(file_descriptor, data, size); + } while (write_result < 0 && errno == EINTR); + + if (write_result <= 0) { + // Write error. + + // FIXME(kenton): According to the man page, if write() returns zero, + // there was no error; write() simply did not write anything. It's + // unclear under what circumstances this might happen, but presumably + // errno won't be set in this case. I am confused as to how such an + // event should be handled. For now I'm treating it as an error, + // since retrying seems like it could lead to an infinite loop. I + // suspect this never actually happens anyway. + + if (write_result < 0) { + int error = errno; + cerr << filename << ": write: " << strerror(error); + } else { + cerr << filename << ": write() returned zero?" << endl; + } + return false; + } + + data += write_result; + size -= write_result; + } + + if (close(file_descriptor) != 0) { + int error = errno; + cerr << filename << ": close: " << strerror(error); + return false; + } + } + + return true; +} + +bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip( + const string& filename) { + if (had_error_) { + return false; + } + + // Create the output file. + int file_descriptor; + do { + file_descriptor = + open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); + } while (file_descriptor < 0 && errno == EINTR); + + if (file_descriptor < 0) { + int error = errno; + cerr << filename << ": " << strerror(error); + return false; + } + + // Create the ZipWriter + io::FileOutputStream stream(file_descriptor); + ZipWriter zip_writer(&stream); + + for (map::const_iterator iter = files_.begin(); + iter != files_.end(); ++iter) { + zip_writer.Write(iter->first, *iter->second); + } + + zip_writer.WriteDirectory(); + + if (stream.GetErrno() != 0) { + cerr << filename << ": " << strerror(stream.GetErrno()) << endl; + } + + if (!stream.Close()) { + cerr << filename << ": " << strerror(stream.GetErrno()) << endl; + } + + return true; +} + +void CommandLineInterface::GeneratorContextImpl::AddJarManifest() { + string** map_slot = &files_["META-INF/MANIFEST.MF"]; + if (*map_slot == NULL) { + *map_slot = new string( + "Manifest-Version: 1.0\n" + "Created-By: 1.6.0 (protoc)\n" + "\n"); + } +} + +io::ZeroCopyOutputStream* CommandLineInterface::GeneratorContextImpl::Open( + const string& filename) { + return new MemoryOutputStream(this, filename); +} + +io::ZeroCopyOutputStream* +CommandLineInterface::GeneratorContextImpl::OpenForInsert( + const string& filename, const string& insertion_point) { + return new MemoryOutputStream(this, filename, insertion_point); +} + +// ------------------------------------------------------------------- + +CommandLineInterface::MemoryOutputStream::MemoryOutputStream( + GeneratorContextImpl* directory, const string& filename) + : directory_(directory), + filename_(filename), + inner_(new io::StringOutputStream(&data_)) { +} + +CommandLineInterface::MemoryOutputStream::MemoryOutputStream( + GeneratorContextImpl* directory, const string& filename, + const string& insertion_point) + : directory_(directory), + filename_(filename), + insertion_point_(insertion_point), + inner_(new io::StringOutputStream(&data_)) { +} + +CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { + // Make sure all data has been written. + inner_.reset(); + + // Insert into the directory. + string** map_slot = &directory_->files_[filename_]; + + if (insertion_point_.empty()) { + // This was just a regular Open(). + if (*map_slot != NULL) { + cerr << filename_ << ": Tried to write the same file twice." << endl; + directory_->had_error_ = true; + return; + } + + *map_slot = new string; + (*map_slot)->swap(data_); + } else { + // This was an OpenForInsert(). + + // If the data doens't end with a clean line break, add one. + if (!data_.empty() && data_[data_.size() - 1] != '\n') { + data_.push_back('\n'); + } + + // Find the file we are going to insert into. + if (*map_slot == NULL) { + cerr << filename_ << ": Tried to insert into file that doesn't exist." + << endl; + directory_->had_error_ = true; + return; + } + string* target = *map_slot; + + // Find the insertion point. + string magic_string = strings::Substitute( + "@@protoc_insertion_point($0)", insertion_point_); + string::size_type pos = target->find(magic_string); + + if (pos == string::npos) { + cerr << filename_ << ": insertion point \"" << insertion_point_ + << "\" not found." << endl; + directory_->had_error_ = true; + return; + } + + // Seek backwards to the beginning of the line, which is where we will + // insert the data. Note that this has the effect of pushing the insertion + // point down, so the data is inserted before it. This is intentional + // because it means that multiple insertions at the same point will end + // up in the expected order in the final output. + pos = target->find_last_of('\n', pos); + if (pos == string::npos) { + // Insertion point is on the first line. + pos = 0; + } else { + // Advance to character after '\n'. + ++pos; + } + + // Extract indent. + string indent_(*target, pos, target->find_first_not_of(" \t", pos) - pos); + + if (indent_.empty()) { + // No indent. This makes things easier. + target->insert(pos, data_); + } else { + // Calculate how much space we need. + int indent_size = 0; + for (int i = 0; i < data_.size(); i++) { + if (data_[i] == '\n') indent_size += indent_.size(); + } + + // Make a hole for it. + target->insert(pos, data_.size() + indent_size, '\0'); + + // Now copy in the data. + string::size_type data_pos = 0; + char* target_ptr = string_as_array(target) + pos; + while (data_pos < data_.size()) { + // Copy indent. + memcpy(target_ptr, indent_.data(), indent_.size()); + target_ptr += indent_.size(); + + // Copy line from data_. + // We already guaranteed that data_ ends with a newline (above), so this + // search can't fail. + string::size_type line_length = + data_.find_first_of('\n', data_pos) + 1 - data_pos; + memcpy(target_ptr, data_.data() + data_pos, line_length); + target_ptr += line_length; + data_pos += line_length; + } + + GOOGLE_CHECK_EQ(target_ptr, + string_as_array(target) + pos + data_.size() + indent_size); + } + } +} + +// =================================================================== + +CommandLineInterface::CommandLineInterface() + : mode_(MODE_COMPILE), + error_format_(ERROR_FORMAT_GCC), + imports_in_descriptor_set_(false), + source_info_in_descriptor_set_(false), + disallow_services_(false), + inputs_are_proto_path_relative_(false) {} +CommandLineInterface::~CommandLineInterface() {} + +void CommandLineInterface::RegisterGenerator(const string& flag_name, + CodeGenerator* generator, + const string& help_text) { + GeneratorInfo info; + info.flag_name = flag_name; + info.generator = generator; + info.help_text = help_text; + generators_by_flag_name_[flag_name] = info; +} + +void CommandLineInterface::RegisterGenerator(const string& flag_name, + const string& option_flag_name, + CodeGenerator* generator, + const string& help_text) { + GeneratorInfo info; + info.flag_name = flag_name; + info.option_flag_name = option_flag_name; + info.generator = generator; + info.help_text = help_text; + generators_by_flag_name_[flag_name] = info; + generators_by_option_name_[option_flag_name] = info; +} + +void CommandLineInterface::AllowPlugins(const string& exe_name_prefix) { + plugin_prefix_ = exe_name_prefix; +} + +int CommandLineInterface::Run(int argc, const char* const argv[]) { + Clear(); + switch (ParseArguments(argc, argv)) { + case PARSE_ARGUMENT_DONE_AND_EXIT: + return 0; + case PARSE_ARGUMENT_FAIL: + return 1; + case PARSE_ARGUMENT_DONE_AND_CONTINUE: + break; + } + + // Set up the source tree. + DiskSourceTree source_tree; + for (int i = 0; i < proto_path_.size(); i++) { + source_tree.MapPath(proto_path_[i].first, proto_path_[i].second); + } + + // Map input files to virtual paths if necessary. + if (!inputs_are_proto_path_relative_) { + if (!MakeInputsBeProtoPathRelative(&source_tree)) { + return 1; + } + } + + // Allocate the Importer. + ErrorPrinter error_collector(error_format_, &source_tree); + Importer importer(&source_tree, &error_collector); + + vector parsed_files; + + // Parse each file. + for (int i = 0; i < input_files_.size(); i++) { + // Import the file. + const FileDescriptor* parsed_file = importer.Import(input_files_[i]); + if (parsed_file == NULL) return 1; + parsed_files.push_back(parsed_file); + + // Enforce --disallow_services. + if (disallow_services_ && parsed_file->service_count() > 0) { + cerr << parsed_file->name() << ": This file contains services, but " + "--disallow_services was used." << endl; + return 1; + } + } + + // We construct a separate GeneratorContext for each output location. Note + // that two code generators may output to the same location, in which case + // they should share a single GeneratorContext so that OpenForInsert() works. + typedef hash_map GeneratorContextMap; + GeneratorContextMap output_directories; + + // Generate output. + if (mode_ == MODE_COMPILE) { + for (int i = 0; i < output_directives_.size(); i++) { + string output_location = output_directives_[i].output_location; + if (!HasSuffixString(output_location, ".zip") && + !HasSuffixString(output_location, ".jar")) { + AddTrailingSlash(&output_location); + } + GeneratorContextImpl** map_slot = &output_directories[output_location]; + + if (*map_slot == NULL) { + // First time we've seen this output location. + *map_slot = new GeneratorContextImpl(parsed_files); + } + + if (!GenerateOutput(parsed_files, output_directives_[i], *map_slot)) { + STLDeleteValues(&output_directories); + return 1; + } + } + } + + // Write all output to disk. + for (GeneratorContextMap::iterator iter = output_directories.begin(); + iter != output_directories.end(); ++iter) { + const string& location = iter->first; + GeneratorContextImpl* directory = iter->second; + if (HasSuffixString(location, "/")) { + if (!directory->WriteAllToDisk(location)) { + STLDeleteValues(&output_directories); + return 1; + } + } else { + if (HasSuffixString(location, ".jar")) { + directory->AddJarManifest(); + } + + if (!directory->WriteAllToZip(location)) { + STLDeleteValues(&output_directories); + return 1; + } + } + } + + STLDeleteValues(&output_directories); + + if (!descriptor_set_name_.empty()) { + if (!WriteDescriptorSet(parsed_files)) { + return 1; + } + } + + if (mode_ == MODE_ENCODE || mode_ == MODE_DECODE) { + if (codec_type_.empty()) { + // HACK: Define an EmptyMessage type to use for decoding. + DescriptorPool pool; + FileDescriptorProto file; + file.set_name("empty_message.proto"); + file.add_message_type()->set_name("EmptyMessage"); + GOOGLE_CHECK(pool.BuildFile(file) != NULL); + codec_type_ = "EmptyMessage"; + if (!EncodeOrDecode(&pool)) { + return 1; + } + } else { + if (!EncodeOrDecode(importer.pool())) { + return 1; + } + } + } + + return 0; +} + +void CommandLineInterface::Clear() { + // Clear all members that are set by Run(). Note that we must not clear + // members which are set by other methods before Run() is called. + executable_name_.clear(); + proto_path_.clear(); + input_files_.clear(); + output_directives_.clear(); + codec_type_.clear(); + descriptor_set_name_.clear(); + + mode_ = MODE_COMPILE; + imports_in_descriptor_set_ = false; + source_info_in_descriptor_set_ = false; + disallow_services_ = false; +} + +bool CommandLineInterface::MakeInputsBeProtoPathRelative( + DiskSourceTree* source_tree) { + for (int i = 0; i < input_files_.size(); i++) { + string virtual_file, shadowing_disk_file; + switch (source_tree->DiskFileToVirtualFile( + input_files_[i], &virtual_file, &shadowing_disk_file)) { + case DiskSourceTree::SUCCESS: + input_files_[i] = virtual_file; + break; + case DiskSourceTree::SHADOWED: + cerr << input_files_[i] << ": Input is shadowed in the --proto_path " + "by \"" << shadowing_disk_file << "\". Either use the latter " + "file as your input or reorder the --proto_path so that the " + "former file's location comes first." << endl; + return false; + case DiskSourceTree::CANNOT_OPEN: + cerr << input_files_[i] << ": " << strerror(errno) << endl; + return false; + case DiskSourceTree::NO_MAPPING: + // First check if the file exists at all. + if (access(input_files_[i].c_str(), F_OK) < 0) { + // File does not even exist. + cerr << input_files_[i] << ": " << strerror(ENOENT) << endl; + } else { + cerr << input_files_[i] << ": File does not reside within any path " + "specified using --proto_path (or -I). You must specify a " + "--proto_path which encompasses this file. Note that the " + "proto_path must be an exact prefix of the .proto file " + "names -- protoc is too dumb to figure out when two paths " + "(e.g. absolute and relative) are equivalent (it's harder " + "than you think)." << endl; + } + return false; + } + } + + return true; +} + +CommandLineInterface::ParseArgumentStatus +CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { + executable_name_ = argv[0]; + + // Iterate through all arguments and parse them. + for (int i = 1; i < argc; i++) { + string name, value; + + if (ParseArgument(argv[i], &name, &value)) { + // Returned true => Use the next argument as the flag value. + if (i + 1 == argc || argv[i+1][0] == '-') { + cerr << "Missing value for flag: " << name << endl; + if (name == "--decode") { + cerr << "To decode an unknown message, use --decode_raw." << endl; + } + return PARSE_ARGUMENT_FAIL; + } else { + ++i; + value = argv[i]; + } + } + + ParseArgumentStatus status = InterpretArgument(name, value); + if (status != PARSE_ARGUMENT_DONE_AND_CONTINUE) + return status; + } + + // If no --proto_path was given, use the current working directory. + if (proto_path_.empty()) { + // Don't use make_pair as the old/default standard library on Solaris + // doesn't support it without explicit template parameters, which are + // incompatible with C++0x's make_pair. + proto_path_.push_back(pair("", ".")); + } + + // Check some errror cases. + bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty(); + if (decoding_raw && !input_files_.empty()) { + cerr << "When using --decode_raw, no input files should be given." << endl; + return PARSE_ARGUMENT_FAIL; + } else if (!decoding_raw && input_files_.empty()) { + cerr << "Missing input file." << endl; + return PARSE_ARGUMENT_FAIL; + } + if (mode_ == MODE_COMPILE && output_directives_.empty() && + descriptor_set_name_.empty()) { + cerr << "Missing output directives." << endl; + return PARSE_ARGUMENT_FAIL; + } + if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) { + cerr << "--include_imports only makes sense when combined with " + "--descriptor_set_out." << endl; + } + if (source_info_in_descriptor_set_ && descriptor_set_name_.empty()) { + cerr << "--include_source_info only makes sense when combined with " + "--descriptor_set_out." << endl; + } + + return PARSE_ARGUMENT_DONE_AND_CONTINUE; +} + +bool CommandLineInterface::ParseArgument(const char* arg, + string* name, string* value) { + bool parsed_value = false; + + if (arg[0] != '-') { + // Not a flag. + name->clear(); + parsed_value = true; + *value = arg; + } else if (arg[1] == '-') { + // Two dashes: Multi-character name, with '=' separating name and + // value. + const char* equals_pos = strchr(arg, '='); + if (equals_pos != NULL) { + *name = string(arg, equals_pos - arg); + *value = equals_pos + 1; + parsed_value = true; + } else { + *name = arg; + } + } else { + // One dash: One-character name, all subsequent characters are the + // value. + if (arg[1] == '\0') { + // arg is just "-". We treat this as an input file, except that at + // present this will just lead to a "file not found" error. + name->clear(); + *value = arg; + parsed_value = true; + } else { + *name = string(arg, 2); + *value = arg + 2; + parsed_value = !value->empty(); + } + } + + // Need to return true iff the next arg should be used as the value for this + // one, false otherwise. + + if (parsed_value) { + // We already parsed a value for this flag. + return false; + } + + if (*name == "-h" || *name == "--help" || + *name == "--disallow_services" || + *name == "--include_imports" || + *name == "--include_source_info" || + *name == "--version" || + *name == "--decode_raw") { + // HACK: These are the only flags that don't take a value. + // They probably should not be hard-coded like this but for now it's + // not worth doing better. + return false; + } + + // Next argument is the flag value. + return true; +} + +CommandLineInterface::ParseArgumentStatus +CommandLineInterface::InterpretArgument(const string& name, + const string& value) { + if (name.empty()) { + // Not a flag. Just a filename. + if (value.empty()) { + cerr << "You seem to have passed an empty string as one of the " + "arguments to " << executable_name_ << ". This is actually " + "sort of hard to do. Congrats. Unfortunately it is not valid " + "input so the program is going to die now." << endl; + return PARSE_ARGUMENT_FAIL; + } + + input_files_.push_back(value); + + } else if (name == "-I" || name == "--proto_path") { + // Java's -classpath (and some other languages) delimits path components + // with colons. Let's accept that syntax too just to make things more + // intuitive. + vector parts; + SplitStringUsing(value, kPathSeparator, &parts); + + for (int i = 0; i < parts.size(); i++) { + string virtual_path; + string disk_path; + + string::size_type equals_pos = parts[i].find_first_of('='); + if (equals_pos == string::npos) { + virtual_path = ""; + disk_path = parts[i]; + } else { + virtual_path = parts[i].substr(0, equals_pos); + disk_path = parts[i].substr(equals_pos + 1); + } + + if (disk_path.empty()) { + cerr << "--proto_path passed empty directory name. (Use \".\" for " + "current directory.)" << endl; + return PARSE_ARGUMENT_FAIL; + } + + // Make sure disk path exists, warn otherwise. + if (access(disk_path.c_str(), F_OK) < 0) { + cerr << disk_path << ": warning: directory does not exist." << endl; + } + + // Don't use make_pair as the old/default standard library on Solaris + // doesn't support it without explicit template parameters, which are + // incompatible with C++0x's make_pair. + proto_path_.push_back(pair(virtual_path, disk_path)); + } + + } else if (name == "-o" || name == "--descriptor_set_out") { + if (!descriptor_set_name_.empty()) { + cerr << name << " may only be passed once." << endl; + return PARSE_ARGUMENT_FAIL; + } + if (value.empty()) { + cerr << name << " requires a non-empty value." << endl; + return PARSE_ARGUMENT_FAIL; + } + if (mode_ != MODE_COMPILE) { + cerr << "Cannot use --encode or --decode and generate descriptors at the " + "same time." << endl; + return PARSE_ARGUMENT_FAIL; + } + descriptor_set_name_ = value; + + } else if (name == "--include_imports") { + if (imports_in_descriptor_set_) { + cerr << name << " may only be passed once." << endl; + return PARSE_ARGUMENT_FAIL; + } + imports_in_descriptor_set_ = true; + + } else if (name == "--include_source_info") { + if (source_info_in_descriptor_set_) { + cerr << name << " may only be passed once." << endl; + return PARSE_ARGUMENT_FAIL; + } + source_info_in_descriptor_set_ = true; + + } else if (name == "-h" || name == "--help") { + PrintHelpText(); + return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler. + + } else if (name == "--version") { + if (!version_info_.empty()) { + cout << version_info_ << endl; + } + cout << "libprotoc " + << protobuf::internal::VersionString(GOOGLE_PROTOBUF_VERSION) + << endl; + return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler. + + } else if (name == "--disallow_services") { + disallow_services_ = true; + + } else if (name == "--encode" || name == "--decode" || + name == "--decode_raw") { + if (mode_ != MODE_COMPILE) { + cerr << "Only one of --encode and --decode can be specified." << endl; + return PARSE_ARGUMENT_FAIL; + } + if (!output_directives_.empty() || !descriptor_set_name_.empty()) { + cerr << "Cannot use " << name + << " and generate code or descriptors at the same time." << endl; + return PARSE_ARGUMENT_FAIL; + } + + mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE; + + if (value.empty() && name != "--decode_raw") { + cerr << "Type name for " << name << " cannot be blank." << endl; + if (name == "--decode") { + cerr << "To decode an unknown message, use --decode_raw." << endl; + } + return PARSE_ARGUMENT_FAIL; + } else if (!value.empty() && name == "--decode_raw") { + cerr << "--decode_raw does not take a parameter." << endl; + return PARSE_ARGUMENT_FAIL; + } + + codec_type_ = value; + + } else if (name == "--error_format") { + if (value == "gcc") { + error_format_ = ERROR_FORMAT_GCC; + } else if (value == "msvs") { + error_format_ = ERROR_FORMAT_MSVS; + } else { + cerr << "Unknown error format: " << value << endl; + return PARSE_ARGUMENT_FAIL; + } + + } else if (name == "--plugin") { + if (plugin_prefix_.empty()) { + cerr << "This compiler does not support plugins." << endl; + return PARSE_ARGUMENT_FAIL; + } + + string plugin_name; + string path; + + string::size_type equals_pos = value.find_first_of('='); + if (equals_pos == string::npos) { + // Use the basename of the file. + string::size_type slash_pos = value.find_last_of('/'); + if (slash_pos == string::npos) { + plugin_name = value; + } else { + plugin_name = value.substr(slash_pos + 1); + } + path = value; + } else { + plugin_name = value.substr(0, equals_pos); + path = value.substr(equals_pos + 1); + } + + plugins_[plugin_name] = path; + + } else { + // Some other flag. Look it up in the generators list. + const GeneratorInfo* generator_info = + FindOrNull(generators_by_flag_name_, name); + if (generator_info == NULL && + (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) { + // Check if it's a generator option flag. + generator_info = FindOrNull(generators_by_option_name_, name); + if (generator_info == NULL) { + cerr << "Unknown flag: " << name << endl; + return PARSE_ARGUMENT_FAIL; + } else { + string* parameters = &generator_parameters_[generator_info->flag_name]; + if (!parameters->empty()) { + parameters->append(","); + } + parameters->append(value); + } + } else { + // It's an output flag. Add it to the output directives. + if (mode_ != MODE_COMPILE) { + cerr << "Cannot use --encode or --decode and generate code at the " + "same time." << endl; + return PARSE_ARGUMENT_FAIL; + } + + OutputDirective directive; + directive.name = name; + if (generator_info == NULL) { + directive.generator = NULL; + } else { + directive.generator = generator_info->generator; + } + + // Split value at ':' to separate the generator parameter from the + // filename. However, avoid doing this if the colon is part of a valid + // Windows-style absolute path. + string::size_type colon_pos = value.find_first_of(':'); + if (colon_pos == string::npos || IsWindowsAbsolutePath(value)) { + directive.output_location = value; + } else { + directive.parameter = value.substr(0, colon_pos); + directive.output_location = value.substr(colon_pos + 1); + } + + output_directives_.push_back(directive); + } + } + + return PARSE_ARGUMENT_DONE_AND_CONTINUE; +} + +void CommandLineInterface::PrintHelpText() { + // Sorry for indentation here; line wrapping would be uglier. + cerr << +"Usage: " << executable_name_ << " [OPTION] PROTO_FILES\n" +"Parse PROTO_FILES and generate output based on the options given:\n" +" -IPATH, --proto_path=PATH Specify the directory in which to search for\n" +" imports. May be specified multiple times;\n" +" directories will be searched in order. If not\n" +" given, the current working directory is used.\n" +" --version Show version info and exit.\n" +" -h, --help Show this text and exit.\n" +" --encode=MESSAGE_TYPE Read a text-format message of the given type\n" +" from standard input and write it in binary\n" +" to standard output. The message type must\n" +" be defined in PROTO_FILES or their imports.\n" +" --decode=MESSAGE_TYPE Read a binary message of the given type from\n" +" standard input and write it in text format\n" +" to standard output. The message type must\n" +" be defined in PROTO_FILES or their imports.\n" +" --decode_raw Read an arbitrary protocol message from\n" +" standard input and write the raw tag/value\n" +" pairs in text format to standard output. No\n" +" PROTO_FILES should be given when using this\n" +" flag.\n" +" -oFILE, Writes a FileDescriptorSet (a protocol buffer,\n" +" --descriptor_set_out=FILE defined in descriptor.proto) containing all of\n" +" the input files to FILE.\n" +" --include_imports When using --descriptor_set_out, also include\n" +" all dependencies of the input files in the\n" +" set, so that the set is self-contained.\n" +" --include_source_info When using --descriptor_set_out, do not strip\n" +" SourceCodeInfo from the FileDescriptorProto.\n" +" This results in vastly larger descriptors that\n" +" include information about the original\n" +" location of each decl in the source file as\n" +" well as surrounding comments.\n" +" --error_format=FORMAT Set the format in which to print errors.\n" +" FORMAT may be 'gcc' (the default) or 'msvs'\n" +" (Microsoft Visual Studio format)." << endl; + if (!plugin_prefix_.empty()) { + cerr << +" --plugin=EXECUTABLE Specifies a plugin executable to use.\n" +" Normally, protoc searches the PATH for\n" +" plugins, but you may specify additional\n" +" executables not in the path using this flag.\n" +" Additionally, EXECUTABLE may be of the form\n" +" NAME=PATH, in which case the given plugin name\n" +" is mapped to the given executable even if\n" +" the executable's own name differs." << endl; + } + + for (GeneratorMap::iterator iter = generators_by_flag_name_.begin(); + iter != generators_by_flag_name_.end(); ++iter) { + // FIXME(kenton): If the text is long enough it will wrap, which is ugly, + // but fixing this nicely (e.g. splitting on spaces) is probably more + // trouble than it's worth. + cerr << " " << iter->first << "=OUT_DIR " + << string(19 - iter->first.size(), ' ') // Spaces for alignment. + << iter->second.help_text << endl; + } +} + +bool CommandLineInterface::GenerateOutput( + const vector& parsed_files, + const OutputDirective& output_directive, + GeneratorContext* generator_context) { + // Call the generator. + string error; + if (output_directive.generator == NULL) { + // This is a plugin. + GOOGLE_CHECK(HasPrefixString(output_directive.name, "--") && + HasSuffixString(output_directive.name, "_out")) + << "Bad name for plugin generator: " << output_directive.name; + + // Strip the "--" and "_out" and add the plugin prefix. + string plugin_name = plugin_prefix_ + "gen-" + + output_directive.name.substr(2, output_directive.name.size() - 6); + + if (!GeneratePluginOutput(parsed_files, plugin_name, + output_directive.parameter, + generator_context, &error)) { + cerr << output_directive.name << ": " << error << endl; + return false; + } + } else { + // Regular generator. + string parameters = output_directive.parameter; + if (!generator_parameters_[output_directive.name].empty()) { + if (!parameters.empty()) { + parameters.append(","); + } + parameters.append(generator_parameters_[output_directive.name]); + } + for (int i = 0; i < parsed_files.size(); i++) { + if (!output_directive.generator->Generate(parsed_files[i], parameters, + generator_context, &error)) { + // Generator returned an error. + cerr << output_directive.name << ": " << parsed_files[i]->name() << ": " + << error << endl; + return false; + } + } + } + + return true; +} + +bool CommandLineInterface::GeneratePluginOutput( + const vector& parsed_files, + const string& plugin_name, + const string& parameter, + GeneratorContext* generator_context, + string* error) { + CodeGeneratorRequest request; + CodeGeneratorResponse response; + + // Build the request. + if (!parameter.empty()) { + request.set_parameter(parameter); + } + + set already_seen; + for (int i = 0; i < parsed_files.size(); i++) { + request.add_file_to_generate(parsed_files[i]->name()); + GetTransitiveDependencies(parsed_files[i], + true, // Include source code info. + &already_seen, request.mutable_proto_file()); + } + + // Invoke the plugin. + Subprocess subprocess; + + if (plugins_.count(plugin_name) > 0) { + subprocess.Start(plugins_[plugin_name], Subprocess::EXACT_NAME); + } else { + subprocess.Start(plugin_name, Subprocess::SEARCH_PATH); + } + + string communicate_error; + if (!subprocess.Communicate(request, &response, &communicate_error)) { + *error = strings::Substitute("$0: $1", plugin_name, communicate_error); + return false; + } + + // Write the files. We do this even if there was a generator error in order + // to match the behavior of a compiled-in generator. + scoped_ptr current_output; + for (int i = 0; i < response.file_size(); i++) { + const CodeGeneratorResponse::File& output_file = response.file(i); + + if (!output_file.insertion_point().empty()) { + // Open a file for insert. + // We reset current_output to NULL first so that the old file is closed + // before the new one is opened. + current_output.reset(); + current_output.reset(generator_context->OpenForInsert( + output_file.name(), output_file.insertion_point())); + } else if (!output_file.name().empty()) { + // Starting a new file. Open it. + // We reset current_output to NULL first so that the old file is closed + // before the new one is opened. + current_output.reset(); + current_output.reset(generator_context->Open(output_file.name())); + } else if (current_output == NULL) { + *error = strings::Substitute( + "$0: First file chunk returned by plugin did not specify a file name.", + plugin_name); + return false; + } + + // Use CodedOutputStream for convenience; otherwise we'd need to provide + // our own buffer-copying loop. + io::CodedOutputStream writer(current_output.get()); + writer.WriteString(output_file.content()); + } + + // Check for errors. + if (!response.error().empty()) { + // Generator returned an error. + *error = response.error(); + return false; + } + + return true; +} + +bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { + // Look up the type. + const Descriptor* type = pool->FindMessageTypeByName(codec_type_); + if (type == NULL) { + cerr << "Type not defined: " << codec_type_ << endl; + return false; + } + + DynamicMessageFactory dynamic_factory(pool); + scoped_ptr message(dynamic_factory.GetPrototype(type)->New()); + + if (mode_ == MODE_ENCODE) { + SetFdToTextMode(STDIN_FILENO); + SetFdToBinaryMode(STDOUT_FILENO); + } else { + SetFdToBinaryMode(STDIN_FILENO); + SetFdToTextMode(STDOUT_FILENO); + } + + io::FileInputStream in(STDIN_FILENO); + io::FileOutputStream out(STDOUT_FILENO); + + if (mode_ == MODE_ENCODE) { + // Input is text. + ErrorPrinter error_collector(error_format_); + TextFormat::Parser parser; + parser.RecordErrorsTo(&error_collector); + parser.AllowPartialMessage(true); + + if (!parser.Parse(&in, message.get())) { + cerr << "Failed to parse input." << endl; + return false; + } + } else { + // Input is binary. + if (!message->ParsePartialFromZeroCopyStream(&in)) { + cerr << "Failed to parse input." << endl; + return false; + } + } + + if (!message->IsInitialized()) { + cerr << "warning: Input message is missing required fields: " + << message->InitializationErrorString() << endl; + } + + if (mode_ == MODE_ENCODE) { + // Output is binary. + if (!message->SerializePartialToZeroCopyStream(&out)) { + cerr << "output: I/O error." << endl; + return false; + } + } else { + // Output is text. + if (!TextFormat::Print(*message, &out)) { + cerr << "output: I/O error." << endl; + return false; + } + } + + return true; +} + +bool CommandLineInterface::WriteDescriptorSet( + const vector parsed_files) { + FileDescriptorSet file_set; + + if (imports_in_descriptor_set_) { + set already_seen; + for (int i = 0; i < parsed_files.size(); i++) { + GetTransitiveDependencies(parsed_files[i], + source_info_in_descriptor_set_, + &already_seen, file_set.mutable_file()); + } + } else { + for (int i = 0; i < parsed_files.size(); i++) { + FileDescriptorProto* file_proto = file_set.add_file(); + parsed_files[i]->CopyTo(file_proto); + if (source_info_in_descriptor_set_) { + parsed_files[i]->CopySourceCodeInfoTo(file_proto); + } + } + } + + int fd; + do { + fd = open(descriptor_set_name_.c_str(), + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); + } while (fd < 0 && errno == EINTR); + + if (fd < 0) { + perror(descriptor_set_name_.c_str()); + return false; + } + + io::FileOutputStream out(fd); + if (!file_set.SerializeToZeroCopyStream(&out)) { + cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl; + out.Close(); + return false; + } + if (!out.Close()) { + cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl; + return false; + } + + return true; +} + +void CommandLineInterface::GetTransitiveDependencies( + const FileDescriptor* file, bool include_source_code_info, + set* already_seen, + RepeatedPtrField* output) { + if (!already_seen->insert(file).second) { + // Already saw this file. Skip. + return; + } + + // Add all dependencies. + for (int i = 0; i < file->dependency_count(); i++) { + GetTransitiveDependencies(file->dependency(i), include_source_code_info, + already_seen, output); + } + + // Add this file. + FileDescriptorProto* new_descriptor = output->Add(); + file->CopyTo(new_descriptor); + if (include_source_code_info) { + file->CopySourceCodeInfoTo(new_descriptor); + } +} + + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface.h new file mode 100644 index 0000000..86ea9bd --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface.h @@ -0,0 +1,353 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Implements the Protocol Compiler front-end such that it may be reused by +// custom compilers written to support other languages. + +#ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ +#define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +class FileDescriptor; // descriptor.h +class DescriptorPool; // descriptor.h +class FileDescriptorProto; // descriptor.pb.h +template class RepeatedPtrField; // repeated_field.h + +namespace compiler { + +class CodeGenerator; // code_generator.h +class GeneratorContext; // code_generator.h +class DiskSourceTree; // importer.h + +// This class implements the command-line interface to the protocol compiler. +// It is designed to make it very easy to create a custom protocol compiler +// supporting the languages of your choice. For example, if you wanted to +// create a custom protocol compiler binary which includes both the regular +// C++ support plus support for your own custom output "Foo", you would +// write a class "FooGenerator" which implements the CodeGenerator interface, +// then write a main() procedure like this: +// +// int main(int argc, char* argv[]) { +// google::protobuf::compiler::CommandLineInterface cli; +// +// // Support generation of C++ source and headers. +// google::protobuf::compiler::cpp::CppGenerator cpp_generator; +// cli.RegisterGenerator("--cpp_out", &cpp_generator, +// "Generate C++ source and header."); +// +// // Support generation of Foo code. +// FooGenerator foo_generator; +// cli.RegisterGenerator("--foo_out", &foo_generator, +// "Generate Foo file."); +// +// return cli.Run(argc, argv); +// } +// +// The compiler is invoked with syntax like: +// protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto +// +// For a full description of the command-line syntax, invoke it with --help. +class LIBPROTOC_EXPORT CommandLineInterface { + public: + CommandLineInterface(); + ~CommandLineInterface(); + + // Register a code generator for a language. + // + // Parameters: + // * flag_name: The command-line flag used to specify an output file of + // this type. The name must start with a '-'. If the name is longer + // than one letter, it must start with two '-'s. + // * generator: The CodeGenerator which will be called to generate files + // of this type. + // * help_text: Text describing this flag in the --help output. + // + // Some generators accept extra parameters. You can specify this parameter + // on the command-line by placing it before the output directory, separated + // by a colon: + // protoc --foo_out=enable_bar:outdir + // The text before the colon is passed to CodeGenerator::Generate() as the + // "parameter". + void RegisterGenerator(const string& flag_name, + CodeGenerator* generator, + const string& help_text); + + // Register a code generator for a language. + // Besides flag_name you can specify another option_flag_name that could be + // used to pass extra parameters to the registered code generator. + // Suppose you have registered a generator by calling: + // command_line_interface.RegisterGenerator("--foo_out", "--foo_opt", ...) + // Then you could invoke the compiler with a command like: + // protoc --foo_out=enable_bar:outdir --foo_opt=enable_baz + // This will pass "enable_bar,enable_baz" as the parameter to the generator. + void RegisterGenerator(const string& flag_name, + const string& option_flag_name, + CodeGenerator* generator, + const string& help_text); + + // Enables "plugins". In this mode, if a command-line flag ends with "_out" + // but does not match any registered generator, the compiler will attempt to + // find a "plugin" to implement the generator. Plugins are just executables. + // They should live somewhere in the PATH. + // + // The compiler determines the executable name to search for by concatenating + // exe_name_prefix with the unrecognized flag name, removing "_out". So, for + // example, if exe_name_prefix is "protoc-" and you pass the flag --foo_out, + // the compiler will try to run the program "protoc-foo". + // + // The plugin program should implement the following usage: + // plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS + // --out indicates the output directory (as passed to the --foo_out + // parameter); if omitted, the current directory should be used. --parameter + // gives the generator parameter, if any was provided. The PROTO_FILES list + // the .proto files which were given on the compiler command-line; these are + // the files for which the plugin is expected to generate output code. + // Finally, DESCRIPTORS is an encoded FileDescriptorSet (as defined in + // descriptor.proto). This is piped to the plugin's stdin. The set will + // include descriptors for all the files listed in PROTO_FILES as well as + // all files that they import. The plugin MUST NOT attempt to read the + // PROTO_FILES directly -- it must use the FileDescriptorSet. + // + // The plugin should generate whatever files are necessary, as code generators + // normally do. It should write the names of all files it generates to + // stdout. The names should be relative to the output directory, NOT absolute + // names or relative to the current directory. If any errors occur, error + // messages should be written to stderr. If an error is fatal, the plugin + // should exit with a non-zero exit code. + void AllowPlugins(const string& exe_name_prefix); + + // Run the Protocol Compiler with the given command-line parameters. + // Returns the error code which should be returned by main(). + // + // It may not be safe to call Run() in a multi-threaded environment because + // it calls strerror(). I'm not sure why you'd want to do this anyway. + int Run(int argc, const char* const argv[]); + + // Call SetInputsAreCwdRelative(true) if the input files given on the command + // line should be interpreted relative to the proto import path specified + // using --proto_path or -I flags. Otherwise, input file names will be + // interpreted relative to the current working directory (or as absolute + // paths if they start with '/'), though they must still reside inside + // a directory given by --proto_path or the compiler will fail. The latter + // mode is generally more intuitive and easier to use, especially e.g. when + // defining implicit rules in Makefiles. + void SetInputsAreProtoPathRelative(bool enable) { + inputs_are_proto_path_relative_ = enable; + } + + // Provides some text which will be printed when the --version flag is + // used. The version of libprotoc will also be printed on the next line + // after this text. + void SetVersionInfo(const string& text) { + version_info_ = text; + } + + + private: + // ----------------------------------------------------------------- + + class ErrorPrinter; + class GeneratorContextImpl; + class MemoryOutputStream; + + // Clear state from previous Run(). + void Clear(); + + // Remaps each file in input_files_ so that it is relative to one of the + // directories in proto_path_. Returns false if an error occurred. This + // is only used if inputs_are_proto_path_relative_ is false. + bool MakeInputsBeProtoPathRelative( + DiskSourceTree* source_tree); + + // Return status for ParseArguments() and InterpretArgument(). + enum ParseArgumentStatus { + PARSE_ARGUMENT_DONE_AND_CONTINUE, + PARSE_ARGUMENT_DONE_AND_EXIT, + PARSE_ARGUMENT_FAIL + }; + + // Parse all command-line arguments. + ParseArgumentStatus ParseArguments(int argc, const char* const argv[]); + + // Parses a command-line argument into a name/value pair. Returns + // true if the next argument in the argv should be used as the value, + // false otherwise. + // + // Exmaples: + // "-Isrc/protos" -> + // name = "-I", value = "src/protos" + // "--cpp_out=src/foo.pb2.cc" -> + // name = "--cpp_out", value = "src/foo.pb2.cc" + // "foo.proto" -> + // name = "", value = "foo.proto" + bool ParseArgument(const char* arg, string* name, string* value); + + // Interprets arguments parsed with ParseArgument. + ParseArgumentStatus InterpretArgument(const string& name, + const string& value); + + // Print the --help text to stderr. + void PrintHelpText(); + + // Generate the given output file from the given input. + struct OutputDirective; // see below + bool GenerateOutput(const vector& parsed_files, + const OutputDirective& output_directive, + GeneratorContext* generator_context); + bool GeneratePluginOutput(const vector& parsed_files, + const string& plugin_name, + const string& parameter, + GeneratorContext* generator_context, + string* error); + + // Implements --encode and --decode. + bool EncodeOrDecode(const DescriptorPool* pool); + + // Implements the --descriptor_set_out option. + bool WriteDescriptorSet(const vector parsed_files); + + // Get all transitive dependencies of the given file (including the file + // itself), adding them to the given list of FileDescriptorProtos. The + // protos will be ordered such that every file is listed before any file that + // depends on it, so that you can call DescriptorPool::BuildFile() on them + // in order. Any files in *already_seen will not be added, and each file + // added will be inserted into *already_seen. If include_source_code_info is + // true then include the source code information in the FileDescriptorProtos. + static void GetTransitiveDependencies( + const FileDescriptor* file, + bool include_source_code_info, + set* already_seen, + RepeatedPtrField* output); + + // ----------------------------------------------------------------- + + // The name of the executable as invoked (i.e. argv[0]). + string executable_name_; + + // Version info set with SetVersionInfo(). + string version_info_; + + // Registered generators. + struct GeneratorInfo { + string flag_name; + string option_flag_name; + CodeGenerator* generator; + string help_text; + }; + typedef map GeneratorMap; + GeneratorMap generators_by_flag_name_; + GeneratorMap generators_by_option_name_; + // A map from generator names to the parameters specified using the option + // flag. For example, if the user invokes the compiler with: + // protoc --foo_out=outputdir --foo_opt=enable_bar ... + // Then there will be an entry ("--foo_out", "enable_bar") in this map. + map generator_parameters_; + + // See AllowPlugins(). If this is empty, plugins aren't allowed. + string plugin_prefix_; + + // Maps specific plugin names to files. When executing a plugin, this map + // is searched first to find the plugin executable. If not found here, the + // PATH (or other OS-specific search strategy) is searched. + map plugins_; + + // Stuff parsed from command line. + enum Mode { + MODE_COMPILE, // Normal mode: parse .proto files and compile them. + MODE_ENCODE, // --encode: read text from stdin, write binary to stdout. + MODE_DECODE // --decode: read binary from stdin, write text to stdout. + }; + + Mode mode_; + + enum ErrorFormat { + ERROR_FORMAT_GCC, // GCC error output format (default). + ERROR_FORMAT_MSVS // Visual Studio output (--error_format=msvs). + }; + + ErrorFormat error_format_; + + vector > proto_path_; // Search path for proto files. + vector input_files_; // Names of the input proto files. + + // output_directives_ lists all the files we are supposed to output and what + // generator to use for each. + struct OutputDirective { + string name; // E.g. "--foo_out" + CodeGenerator* generator; // NULL for plugins + string parameter; + string output_location; + }; + vector output_directives_; + + // When using --encode or --decode, this names the type we are encoding or + // decoding. (Empty string indicates --decode_raw.) + string codec_type_; + + // If --descriptor_set_out was given, this is the filename to which the + // FileDescriptorSet should be written. Otherwise, empty. + string descriptor_set_name_; + + // True if --include_imports was given, meaning that we should + // write all transitive dependencies to the DescriptorSet. Otherwise, only + // the .proto files listed on the command-line are added. + bool imports_in_descriptor_set_; + + // True if --include_source_info was given, meaning that we should not strip + // SourceCodeInfo from the DescriptorSet. + bool source_info_in_descriptor_set_; + + // Was the --disallow_services flag used? + bool disallow_services_; + + // See SetInputsAreProtoPathRelative(). + bool inputs_are_proto_path_relative_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface); +}; + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface_unittest.cc new file mode 100644 index 0000000..1655992 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -0,0 +1,1560 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#ifdef _MSC_VER +#include +#else +#include +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { + +#if defined(_WIN32) +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif +#ifndef F_OK +#define F_OK 00 // not defined by MSVC for whatever reason +#endif +#endif + +namespace { + +class CommandLineInterfaceTest : public testing::Test { + protected: + virtual void SetUp(); + virtual void TearDown(); + + // Runs the CommandLineInterface with the given command line. The + // command is automatically split on spaces, and the string "$tmpdir" + // is replaced with TestTempDir(). + void Run(const string& command); + + // ----------------------------------------------------------------- + // Methods to set up the test (called before Run()). + + class NullCodeGenerator; + + // Normally plugins are allowed for all tests. Call this to explicitly + // disable them. + void DisallowPlugins() { disallow_plugins_ = true; } + + // Create a temp file within temp_directory_ with the given name. + // The containing directory is also created if necessary. + void CreateTempFile(const string& name, const string& contents); + + // Create a subdirectory within temp_directory_. + void CreateTempDir(const string& name); + + void SetInputsAreProtoPathRelative(bool enable) { + cli_.SetInputsAreProtoPathRelative(enable); + } + + // ----------------------------------------------------------------- + // Methods to check the test results (called after Run()). + + // Checks that no text was written to stderr during Run(), and Run() + // returned 0. + void ExpectNoErrors(); + + // Checks that Run() returned non-zero and the stderr output is exactly + // the text given. expected_test may contain references to "$tmpdir", + // which will be replaced by the temporary directory path. + void ExpectErrorText(const string& expected_text); + + // Checks that Run() returned non-zero and the stderr contains the given + // substring. + void ExpectErrorSubstring(const string& expected_substring); + + // Like ExpectErrorSubstring, but checks that Run() returned zero. + void ExpectErrorSubstringWithZeroReturnCode( + const string& expected_substring); + + // Returns true if ExpectErrorSubstring(expected_substring) would pass, but + // does not fail otherwise. + bool HasAlternateErrorSubstring(const string& expected_substring); + + // Checks that MockCodeGenerator::Generate() was called in the given + // context (or the generator in test_plugin.cc, which produces the same + // output). That is, this tests if the generator with the given name + // was called with the given parameter and proto file and produced the + // given output file. This is checked by reading the output file and + // checking that it contains the content that MockCodeGenerator would + // generate given these inputs. message_name is the name of the first + // message that appeared in the proto file; this is just to make extra + // sure that the correct file was parsed. + void ExpectGenerated(const string& generator_name, + const string& parameter, + const string& proto_name, + const string& message_name); + void ExpectGenerated(const string& generator_name, + const string& parameter, + const string& proto_name, + const string& message_name, + const string& output_directory); + void ExpectGeneratedWithMultipleInputs(const string& generator_name, + const string& all_proto_names, + const string& proto_name, + const string& message_name); + void ExpectGeneratedWithInsertions(const string& generator_name, + const string& parameter, + const string& insertions, + const string& proto_name, + const string& message_name); + + void ExpectNullCodeGeneratorCalled(const string& parameter); + + void ReadDescriptorSet(const string& filename, + FileDescriptorSet* descriptor_set); + + private: + // The object we are testing. + CommandLineInterface cli_; + + // Was DisallowPlugins() called? + bool disallow_plugins_; + + // We create a directory within TestTempDir() in order to add extra + // protection against accidentally deleting user files (since we recursively + // delete this directory during the test). This is the full path of that + // directory. + string temp_directory_; + + // The result of Run(). + int return_code_; + + // The captured stderr output. + string error_text_; + + // Pointers which need to be deleted later. + vector mock_generators_to_delete_; + + NullCodeGenerator* null_generator_; +}; + +class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { + public: + NullCodeGenerator() : called_(false) {} + ~NullCodeGenerator() {} + + mutable bool called_; + mutable string parameter_; + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const { + called_ = true; + parameter_ = parameter; + return true; + } +}; + +// =================================================================== + +void CommandLineInterfaceTest::SetUp() { + // Most of these tests were written before this option was added, so we + // run with the option on (which used to be the only way) except in certain + // tests where we turn it off. + cli_.SetInputsAreProtoPathRelative(true); + + temp_directory_ = TestTempDir() + "/proto2_cli_test_temp"; + + // If the temp directory already exists, it must be left over from a + // previous run. Delete it. + if (File::Exists(temp_directory_)) { + File::DeleteRecursively(temp_directory_, NULL, NULL); + } + + // Create the temp directory. + GOOGLE_CHECK(File::CreateDir(temp_directory_.c_str(), DEFAULT_FILE_MODE)); + + // Register generators. + CodeGenerator* generator = new MockCodeGenerator("test_generator"); + mock_generators_to_delete_.push_back(generator); + cli_.RegisterGenerator("--test_out", "--test_opt", generator, "Test output."); + cli_.RegisterGenerator("-t", generator, "Test output."); + + generator = new MockCodeGenerator("alt_generator"); + mock_generators_to_delete_.push_back(generator); + cli_.RegisterGenerator("--alt_out", generator, "Alt output."); + + generator = null_generator_ = new NullCodeGenerator(); + mock_generators_to_delete_.push_back(generator); + cli_.RegisterGenerator("--null_out", generator, "Null output."); + + disallow_plugins_ = false; +} + +void CommandLineInterfaceTest::TearDown() { + // Delete the temp directory. + File::DeleteRecursively(temp_directory_, NULL, NULL); + + // Delete all the MockCodeGenerators. + for (int i = 0; i < mock_generators_to_delete_.size(); i++) { + delete mock_generators_to_delete_[i]; + } + mock_generators_to_delete_.clear(); +} + +void CommandLineInterfaceTest::Run(const string& command) { + vector args; + SplitStringUsing(command, " ", &args); + + if (!disallow_plugins_) { + cli_.AllowPlugins("prefix-"); + const char* possible_paths[] = { + // When building with shared libraries, libtool hides the real executable + // in .libs and puts a fake wrapper in the current directory. + // Unfortunately, due to an apparent bug on Cygwin/MinGW, if one program + // wrapped in this way (e.g. protobuf-tests.exe) tries to execute another + // program wrapped in this way (e.g. test_plugin.exe), the latter fails + // with error code 127 and no explanation message. Presumably the problem + // is that the wrapper for protobuf-tests.exe set some environment + // variables that confuse the wrapper for test_plugin.exe. Luckily, it + // turns out that if we simply invoke the wrapped test_plugin.exe + // directly, it works -- I guess the environment variables set by the + // protobuf-tests.exe wrapper happen to be correct for it too. So we do + // that. + ".libs/test_plugin.exe", // Win32 w/autotool (Cygwin / MinGW) + "test_plugin.exe", // Other Win32 (MSVC) + "test_plugin", // Unix + }; + + string plugin_path; + + for (int i = 0; i < GOOGLE_ARRAYSIZE(possible_paths); i++) { + if (access(possible_paths[i], F_OK) == 0) { + plugin_path = possible_paths[i]; + break; + } + } + + if (plugin_path.empty()) { + GOOGLE_LOG(ERROR) + << "Plugin executable not found. Plugin tests are likely to fail."; + } else { + args.push_back("--plugin=prefix-gen-plug=" + plugin_path); + } + } + + scoped_array argv(new const char*[args.size()]); + + for (int i = 0; i < args.size(); i++) { + args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true); + argv[i] = args[i].c_str(); + } + + CaptureTestStderr(); + + return_code_ = cli_.Run(args.size(), argv.get()); + + error_text_ = GetCapturedTestStderr(); +} + +// ------------------------------------------------------------------- + +void CommandLineInterfaceTest::CreateTempFile( + const string& name, + const string& contents) { + // Create parent directory, if necessary. + string::size_type slash_pos = name.find_last_of('/'); + if (slash_pos != string::npos) { + string dir = name.substr(0, slash_pos); + File::RecursivelyCreateDir(temp_directory_ + "/" + dir, 0777); + } + + // Write file. + string full_name = temp_directory_ + "/" + name; + File::WriteStringToFileOrDie(contents, full_name); +} + +void CommandLineInterfaceTest::CreateTempDir(const string& name) { + File::RecursivelyCreateDir(temp_directory_ + "/" + name, 0777); +} + +// ------------------------------------------------------------------- + +void CommandLineInterfaceTest::ExpectNoErrors() { + EXPECT_EQ(0, return_code_); + EXPECT_EQ("", error_text_); +} + +void CommandLineInterfaceTest::ExpectErrorText(const string& expected_text) { + EXPECT_NE(0, return_code_); + EXPECT_EQ(StringReplace(expected_text, "$tmpdir", temp_directory_, true), + error_text_); +} + +void CommandLineInterfaceTest::ExpectErrorSubstring( + const string& expected_substring) { + EXPECT_NE(0, return_code_); + EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_); +} + +void CommandLineInterfaceTest::ExpectErrorSubstringWithZeroReturnCode( + const string& expected_substring) { + EXPECT_EQ(0, return_code_); + EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_); +} + +bool CommandLineInterfaceTest::HasAlternateErrorSubstring( + const string& expected_substring) { + EXPECT_NE(0, return_code_); + return error_text_.find(expected_substring) != string::npos; +} + +void CommandLineInterfaceTest::ExpectGenerated( + const string& generator_name, + const string& parameter, + const string& proto_name, + const string& message_name) { + MockCodeGenerator::ExpectGenerated( + generator_name, parameter, "", proto_name, message_name, proto_name, + temp_directory_); +} + +void CommandLineInterfaceTest::ExpectGenerated( + const string& generator_name, + const string& parameter, + const string& proto_name, + const string& message_name, + const string& output_directory) { + MockCodeGenerator::ExpectGenerated( + generator_name, parameter, "", proto_name, message_name, proto_name, + temp_directory_ + "/" + output_directory); +} + +void CommandLineInterfaceTest::ExpectGeneratedWithMultipleInputs( + const string& generator_name, + const string& all_proto_names, + const string& proto_name, + const string& message_name) { + MockCodeGenerator::ExpectGenerated( + generator_name, "", "", proto_name, message_name, + all_proto_names, + temp_directory_); +} + +void CommandLineInterfaceTest::ExpectGeneratedWithInsertions( + const string& generator_name, + const string& parameter, + const string& insertions, + const string& proto_name, + const string& message_name) { + MockCodeGenerator::ExpectGenerated( + generator_name, parameter, insertions, proto_name, message_name, + proto_name, temp_directory_); +} + +void CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled( + const string& parameter) { + EXPECT_TRUE(null_generator_->called_); + EXPECT_EQ(parameter, null_generator_->parameter_); +} + +void CommandLineInterfaceTest::ReadDescriptorSet( + const string& filename, FileDescriptorSet* descriptor_set) { + string path = temp_directory_ + "/" + filename; + string file_contents; + if (!File::ReadFileToString(path, &file_contents)) { + FAIL() << "File not found: " << path; + } + if (!descriptor_set->ParseFromString(file_contents)) { + FAIL() << "Could not parse file contents: " << path; + } +} + +// =================================================================== + +TEST_F(CommandLineInterfaceTest, BasicOutput) { + // Test that the common case works. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, BasicPlugin) { + // Test that basic plugins work. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --plug_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) { + // Invoke a generator and a plugin at the same time. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); + ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, MultipleInputs) { + // Test parsing multiple input files. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + CreateTempFile("bar.proto", + "syntax = \"proto2\";\n" + "message Bar {}\n"); + + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--proto_path=$tmpdir foo.proto bar.proto"); + + ExpectNoErrors(); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "bar.proto", "Bar"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "bar.proto", "Bar"); +} + +TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) { + // Test parsing multiple input files with an import of a separate file. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + CreateTempFile("bar.proto", + "syntax = \"proto2\";\n" + "import \"baz.proto\";\n" + "message Bar {\n" + " optional Baz a = 1;\n" + "}\n"); + CreateTempFile("baz.proto", + "syntax = \"proto2\";\n" + "message Baz {}\n"); + + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--proto_path=$tmpdir foo.proto bar.proto"); + + ExpectNoErrors(); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "bar.proto", "Bar"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "bar.proto", "Bar"); +} + +TEST_F(CommandLineInterfaceTest, CreateDirectory) { + // Test that when we output to a sub-directory, it is created. + + CreateTempFile("bar/baz/foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + CreateTempDir("out"); + CreateTempDir("plugout"); + + Run("protocol_compiler --test_out=$tmpdir/out --plug_out=$tmpdir/plugout " + "--proto_path=$tmpdir bar/baz/foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "bar/baz/foo.proto", "Foo", "out"); + ExpectGenerated("test_plugin", "", "bar/baz/foo.proto", "Foo", "plugout"); +} + +TEST_F(CommandLineInterfaceTest, GeneratorParameters) { + // Test that generator parameters are correctly parsed from the command line. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --test_out=TestParameter:$tmpdir " + "--plug_out=TestPluginParameter:$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "TestParameter", "foo.proto", "Foo"); + ExpectGenerated("test_plugin", "TestPluginParameter", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, ExtraGeneratorParameters) { + // Test that generator parameters specified with the option flag are + // correctly passed to the code generator. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + // Create the "a" and "b" sub-directories. + CreateTempDir("a"); + CreateTempDir("b"); + + Run("protocol_compiler " + "--test_opt=foo1 " + "--test_out=bar:$tmpdir/a " + "--test_opt=foo2 " + "--test_out=baz:$tmpdir/b " + "--test_opt=foo3 " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated( + "test_generator", "bar,foo1,foo2,foo3", "foo.proto", "Foo", "a"); + ExpectGenerated( + "test_generator", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b"); +} + +TEST_F(CommandLineInterfaceTest, Insert) { + // Test running a generator that inserts code into another's output. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler " + "--test_out=TestParameter:$tmpdir " + "--plug_out=TestPluginParameter:$tmpdir " + "--test_out=insert=test_generator,test_plugin:$tmpdir " + "--plug_out=insert=test_generator,test_plugin:$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGeneratedWithInsertions( + "test_generator", "TestParameter", "test_generator,test_plugin", + "foo.proto", "Foo"); + ExpectGeneratedWithInsertions( + "test_plugin", "TestPluginParameter", "test_generator,test_plugin", + "foo.proto", "Foo"); +} + +#if defined(_WIN32) + +TEST_F(CommandLineInterfaceTest, WindowsOutputPath) { + // Test that the output path can be a Windows-style path. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n"); + + Run("protocol_compiler --null_out=C:\\ " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectNullCodeGeneratorCalled(""); +} + +TEST_F(CommandLineInterfaceTest, WindowsOutputPathAndParameter) { + // Test that we can have a windows-style output path and a parameter. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n"); + + Run("protocol_compiler --null_out=bar:C:\\ " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectNullCodeGeneratorCalled("bar"); +} + +TEST_F(CommandLineInterfaceTest, TrailingBackslash) { + // Test that the directories can end in backslashes. Some users claim this + // doesn't work on their system. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --test_out=$tmpdir\\ " + "--proto_path=$tmpdir\\ foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + +#endif // defined(_WIN32) || defined(__CYGWIN__) + +TEST_F(CommandLineInterfaceTest, PathLookup) { + // Test that specifying multiple directories in the proto search path works. + + CreateTempFile("b/bar.proto", + "syntax = \"proto2\";\n" + "message Bar {}\n"); + CreateTempFile("a/foo.proto", + "syntax = \"proto2\";\n" + "import \"bar.proto\";\n" + "message Foo {\n" + " optional Bar a = 1;\n" + "}\n"); + CreateTempFile("b/foo.proto", "this should not be parsed\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir/a --proto_path=$tmpdir/b foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) { + // Same as PathLookup, but we provide the proto_path in a single flag. + + CreateTempFile("b/bar.proto", + "syntax = \"proto2\";\n" + "message Bar {}\n"); + CreateTempFile("a/foo.proto", + "syntax = \"proto2\";\n" + "import \"bar.proto\";\n" + "message Foo {\n" + " optional Bar a = 1;\n" + "}\n"); + CreateTempFile("b/foo.proto", "this should not be parsed\n"); + +#undef PATH_SEPARATOR +#if defined(_WIN32) +#define PATH_SEPARATOR ";" +#else +#define PATH_SEPARATOR ":" +#endif + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir/a"PATH_SEPARATOR"$tmpdir/b foo.proto"); + +#undef PATH_SEPARATOR + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, NonRootMapping) { + // Test setting up a search path mapping a directory to a non-root location. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=bar=$tmpdir bar/foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, MultipleGenerators) { + // Test that we can have multiple generators and use both in one invocation, + // each with a different output directory. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + // Create the "a" and "b" sub-directories. + CreateTempDir("a"); + CreateTempDir("b"); + + Run("protocol_compiler " + "--test_out=$tmpdir/a " + "--alt_out=$tmpdir/b " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo", "a"); + ExpectGenerated("alt_generator", "", "foo.proto", "Foo", "b"); +} + +TEST_F(CommandLineInterfaceTest, DisallowServicesNoServices) { + // Test that --disallow_services doesn't cause a problem when there are no + // services. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --disallow_services --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, DisallowServicesHasService) { + // Test that --disallow_services produces an error when there are services. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n" + "service Bar {}\n"); + + Run("protocol_compiler --disallow_services --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring("foo.proto: This file contains services"); +} + +TEST_F(CommandLineInterfaceTest, AllowServicesHasService) { + // Test that services work fine as long as --disallow_services is not used. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n" + "service Bar {}\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) { + // Test that we can accept working-directory-relative input files. + + SetInputsAreProtoPathRelative(false); + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir $tmpdir/foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + CreateTempFile("bar.proto", + "syntax = \"proto2\";\n" + "import \"foo.proto\";\n" + "message Bar {\n" + " optional Foo foo = 1;\n" + "}\n"); + + Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set " + "--proto_path=$tmpdir bar.proto"); + + ExpectNoErrors(); + + FileDescriptorSet descriptor_set; + ReadDescriptorSet("descriptor_set", &descriptor_set); + if (HasFatalFailure()) return; + ASSERT_EQ(1, descriptor_set.file_size()); + EXPECT_EQ("bar.proto", descriptor_set.file(0).name()); + // Descriptor set should not have source code info. + EXPECT_FALSE(descriptor_set.file(0).has_source_code_info()); +} + +TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + CreateTempFile("bar.proto", + "syntax = \"proto2\";\n" + "import \"foo.proto\";\n" + "message Bar {\n" + " optional Foo foo = 1;\n" + "}\n"); + + Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set " + "--include_source_info --proto_path=$tmpdir bar.proto"); + + ExpectNoErrors(); + + FileDescriptorSet descriptor_set; + ReadDescriptorSet("descriptor_set", &descriptor_set); + if (HasFatalFailure()) return; + ASSERT_EQ(1, descriptor_set.file_size()); + EXPECT_EQ("bar.proto", descriptor_set.file(0).name()); + // Source code info included. + EXPECT_TRUE(descriptor_set.file(0).has_source_code_info()); +} + +TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + CreateTempFile("bar.proto", + "syntax = \"proto2\";\n" + "import \"foo.proto\";\n" + "message Bar {\n" + " optional Foo foo = 1;\n" + "}\n"); + + Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set " + "--include_imports --proto_path=$tmpdir bar.proto"); + + ExpectNoErrors(); + + FileDescriptorSet descriptor_set; + ReadDescriptorSet("descriptor_set", &descriptor_set); + if (HasFatalFailure()) return; + ASSERT_EQ(2, descriptor_set.file_size()); + if (descriptor_set.file(0).name() == "bar.proto") { + std::swap(descriptor_set.mutable_file()->mutable_data()[0], + descriptor_set.mutable_file()->mutable_data()[1]); + } + EXPECT_EQ("foo.proto", descriptor_set.file(0).name()); + EXPECT_EQ("bar.proto", descriptor_set.file(1).name()); + // Descriptor set should not have source code info. + EXPECT_FALSE(descriptor_set.file(0).has_source_code_info()); + EXPECT_FALSE(descriptor_set.file(1).has_source_code_info()); +} + +TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSetWithSourceInfo) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + CreateTempFile("bar.proto", + "syntax = \"proto2\";\n" + "import \"foo.proto\";\n" + "message Bar {\n" + " optional Foo foo = 1;\n" + "}\n"); + + Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set " + "--include_imports --include_source_info --proto_path=$tmpdir bar.proto"); + + ExpectNoErrors(); + + FileDescriptorSet descriptor_set; + ReadDescriptorSet("descriptor_set", &descriptor_set); + if (HasFatalFailure()) return; + ASSERT_EQ(2, descriptor_set.file_size()); + if (descriptor_set.file(0).name() == "bar.proto") { + std::swap(descriptor_set.mutable_file()->mutable_data()[0], + descriptor_set.mutable_file()->mutable_data()[1]); + } + EXPECT_EQ("foo.proto", descriptor_set.file(0).name()); + EXPECT_EQ("bar.proto", descriptor_set.file(1).name()); + // Source code info included. + EXPECT_TRUE(descriptor_set.file(0).has_source_code_info()); + EXPECT_TRUE(descriptor_set.file(1).has_source_code_info()); +} + +// ------------------------------------------------------------------- + +TEST_F(CommandLineInterfaceTest, ParseErrors) { + // Test that parse errors are reported. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "badsyntax\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorText( + "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n"); +} + +TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) { + // Test that parse errors are reported from multiple files. + + // We set up files such that foo.proto actually depends on bar.proto in + // two ways: Directly and through baz.proto. bar.proto's errors should + // only be reported once. + CreateTempFile("bar.proto", + "syntax = \"proto2\";\n" + "badsyntax\n"); + CreateTempFile("baz.proto", + "syntax = \"proto2\";\n" + "import \"bar.proto\";\n"); + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "import \"bar.proto\";\n" + "import \"baz.proto\";\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorText( + "bar.proto:2:1: Expected top-level statement (e.g. \"message\").\n" + "baz.proto: Import \"bar.proto\" was not found or had errors.\n" + "foo.proto: Import \"bar.proto\" was not found or had errors.\n" + "foo.proto: Import \"baz.proto\" was not found or had errors.\n"); +} + +TEST_F(CommandLineInterfaceTest, InputNotFoundError) { + // Test what happens if the input file is not found. + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorText( + "foo.proto: File not found.\n"); +} + +TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) { + // Test what happens when a working-directory-relative input file is not + // found. + + SetInputsAreProtoPathRelative(false); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir $tmpdir/foo.proto"); + + ExpectErrorText( + "$tmpdir/foo.proto: No such file or directory\n"); +} + +TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) { + // Test what happens when a working-directory-relative input file is not + // mapped to a virtual path. + + SetInputsAreProtoPathRelative(false); + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + // Create a directory called "bar" so that we can point --proto_path at it. + CreateTempFile("bar/dummy", ""); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir/bar $tmpdir/foo.proto"); + + ExpectErrorText( + "$tmpdir/foo.proto: File does not reside within any path " + "specified using --proto_path (or -I). You must specify a " + "--proto_path which encompasses this file. Note that the " + "proto_path must be an exact prefix of the .proto file " + "names -- protoc is too dumb to figure out when two paths " + "(e.g. absolute and relative) are equivalent (it's harder " + "than you think).\n"); +} + +TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) { + // Check what happens if the input file is not found *and* is not mapped + // in the proto_path. + + SetInputsAreProtoPathRelative(false); + + // Create a directory called "bar" so that we can point --proto_path at it. + CreateTempFile("bar/dummy", ""); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir/bar $tmpdir/foo.proto"); + + ExpectErrorText( + "$tmpdir/foo.proto: No such file or directory\n"); +} + +TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) { + // Test what happens when a working-directory-relative input file is shadowed + // by another file in the virtual path. + + SetInputsAreProtoPathRelative(false); + + CreateTempFile("foo/foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + CreateTempFile("bar/foo.proto", + "syntax = \"proto2\";\n" + "message Bar {}\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir/foo --proto_path=$tmpdir/bar " + "$tmpdir/bar/foo.proto"); + + ExpectErrorText( + "$tmpdir/bar/foo.proto: Input is shadowed in the --proto_path " + "by \"$tmpdir/foo/foo.proto\". Either use the latter " + "file as your input or reorder the --proto_path so that the " + "former file's location comes first.\n"); +} + +TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) { + // Test what happens if the input file is not found. + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir/foo foo.proto"); + + ExpectErrorText( + "$tmpdir/foo: warning: directory does not exist.\n" + "foo.proto: File not found.\n"); +} + +TEST_F(CommandLineInterfaceTest, MissingInputError) { + // Test that we get an error if no inputs are given. + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir"); + + ExpectErrorText("Missing input file.\n"); +} + +TEST_F(CommandLineInterfaceTest, MissingOutputError) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --proto_path=$tmpdir foo.proto"); + + ExpectErrorText("Missing output directives.\n"); +} + +TEST_F(CommandLineInterfaceTest, OutputWriteError) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + string output_file = + MockCodeGenerator::GetOutputFileName("test_generator", "foo.proto"); + + // Create a directory blocking our output location. + CreateTempDir(output_file); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + // MockCodeGenerator no longer detects an error because we actually write to + // an in-memory location first, then dump to disk at the end. This is no + // big deal. + // ExpectErrorSubstring("MockCodeGenerator detected write error."); + +#if defined(_WIN32) && !defined(__CYGWIN__) + // Windows with MSVCRT.dll produces EPERM instead of EISDIR. + if (HasAlternateErrorSubstring(output_file + ": Permission denied")) { + return; + } +#endif + + ExpectErrorSubstring(output_file + ": Is a directory"); +} + +TEST_F(CommandLineInterfaceTest, PluginOutputWriteError) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + string output_file = + MockCodeGenerator::GetOutputFileName("test_plugin", "foo.proto"); + + // Create a directory blocking our output location. + CreateTempDir(output_file); + + Run("protocol_compiler --plug_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + +#if defined(_WIN32) && !defined(__CYGWIN__) + // Windows with MSVCRT.dll produces EPERM instead of EISDIR. + if (HasAlternateErrorSubstring(output_file + ": Permission denied")) { + return; + } +#endif + + ExpectErrorSubstring(output_file + ": Is a directory"); +} + +TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --test_out=$tmpdir/nosuchdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring("nosuchdir/: No such file or directory"); +} + +TEST_F(CommandLineInterfaceTest, PluginOutputDirectoryNotFoundError) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --plug_out=$tmpdir/nosuchdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring("nosuchdir/: No such file or directory"); +} + +TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --test_out=$tmpdir/foo.proto " + "--proto_path=$tmpdir foo.proto"); + +#if defined(_WIN32) && !defined(__CYGWIN__) + // Windows with MSVCRT.dll produces EINVAL instead of ENOTDIR. + if (HasAlternateErrorSubstring("foo.proto/: Invalid argument")) { + return; + } +#endif + + ExpectErrorSubstring("foo.proto/: Not a directory"); +} + +TEST_F(CommandLineInterfaceTest, GeneratorError) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message MockCodeGenerator_Error {}\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring( + "--test_out: foo.proto: Saw message type MockCodeGenerator_Error."); +} + +TEST_F(CommandLineInterfaceTest, GeneratorPluginError) { + // Test a generator plugin that returns an error. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message MockCodeGenerator_Error {}\n"); + + Run("protocol_compiler --plug_out=TestParameter:$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring( + "--plug_out: foo.proto: Saw message type MockCodeGenerator_Error."); +} + +TEST_F(CommandLineInterfaceTest, GeneratorPluginFail) { + // Test a generator plugin that exits with an error code. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message MockCodeGenerator_Exit {}\n"); + + Run("protocol_compiler --plug_out=TestParameter:$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring("Saw message type MockCodeGenerator_Exit."); + ExpectErrorSubstring( + "--plug_out: prefix-gen-plug: Plugin failed with status code 123."); +} + +TEST_F(CommandLineInterfaceTest, GeneratorPluginCrash) { + // Test a generator plugin that crashes. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message MockCodeGenerator_Abort {}\n"); + + Run("protocol_compiler --plug_out=TestParameter:$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring("Saw message type MockCodeGenerator_Abort."); + +#ifdef _WIN32 + // Windows doesn't have signals. It looks like abort()ing causes the process + // to exit with status code 3, but let's not depend on the exact number here. + ExpectErrorSubstring( + "--plug_out: prefix-gen-plug: Plugin failed with status code"); +#else + // Don't depend on the exact signal number. + ExpectErrorSubstring( + "--plug_out: prefix-gen-plug: Plugin killed by signal"); +#endif +} + +TEST_F(CommandLineInterfaceTest, PluginReceivesSourceCodeInfo) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message MockCodeGenerator_HasSourceCodeInfo {}\n"); + + Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring( + "Saw message type MockCodeGenerator_HasSourceCodeInfo: 1."); +} + +TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) { + // Test what happens if the plugin isn't found. + + CreateTempFile("error.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --badplug_out=TestParameter:$tmpdir " + "--plugin=prefix-gen-badplug=no_such_file " + "--proto_path=$tmpdir error.proto"); + +#ifdef _WIN32 + ExpectErrorSubstring("--badplug_out: prefix-gen-badplug: " + + Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND)); +#else + // Error written to stdout by child process after exec() fails. + ExpectErrorSubstring( + "no_such_file: program not found or is not executable"); + + // Error written by parent process when child fails. + ExpectErrorSubstring( + "--badplug_out: prefix-gen-badplug: Plugin failed with status code 1."); +#endif +} + +TEST_F(CommandLineInterfaceTest, GeneratorPluginNotAllowed) { + // Test what happens if plugins aren't allowed. + + CreateTempFile("error.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + DisallowPlugins(); + Run("protocol_compiler --plug_out=TestParameter:$tmpdir " + "--proto_path=$tmpdir error.proto"); + + ExpectErrorSubstring("Unknown flag: --plug_out"); +} + +TEST_F(CommandLineInterfaceTest, HelpText) { + Run("test_exec_name --help"); + + ExpectErrorSubstringWithZeroReturnCode("Usage: test_exec_name "); + ExpectErrorSubstringWithZeroReturnCode("--test_out=OUT_DIR"); + ExpectErrorSubstringWithZeroReturnCode("Test output."); + ExpectErrorSubstringWithZeroReturnCode("--alt_out=OUT_DIR"); + ExpectErrorSubstringWithZeroReturnCode("Alt output."); +} + +TEST_F(CommandLineInterfaceTest, GccFormatErrors) { + // Test --error_format=gcc (which is the default, but we want to verify + // that it can be set explicitly). + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "badsyntax\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir --error_format=gcc foo.proto"); + + ExpectErrorText( + "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n"); +} + +TEST_F(CommandLineInterfaceTest, MsvsFormatErrors) { + // Test --error_format=msvs + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "badsyntax\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir --error_format=msvs foo.proto"); + + ExpectErrorText( + "$tmpdir/foo.proto(2) : error in column=1: Expected top-level statement " + "(e.g. \"message\").\n"); +} + +TEST_F(CommandLineInterfaceTest, InvalidErrorFormat) { + // Test --error_format=msvs + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "badsyntax\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir --error_format=invalid foo.proto"); + + ExpectErrorText( + "Unknown error format: invalid\n"); +} + +// ------------------------------------------------------------------- +// Flag parsing tests + +TEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) { + // Test that a single-character flag works. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler -t$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, ParseSpaceDelimitedValue) { + // Test that separating the flag value with a space works. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --test_out $tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) { + // Test that separating the flag value with a space works for + // single-character flags. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler -t $tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, MissingValueError) { + // Test that we get an error if a flag is missing its value. + + Run("protocol_compiler --test_out --proto_path=$tmpdir foo.proto"); + + ExpectErrorText("Missing value for flag: --test_out\n"); +} + +TEST_F(CommandLineInterfaceTest, MissingValueAtEndError) { + // Test that we get an error if the last argument is a flag requiring a + // value. + + Run("protocol_compiler --test_out"); + + ExpectErrorText("Missing value for flag: --test_out\n"); +} + +// =================================================================== + +// Test for --encode and --decode. Note that it would be easier to do this +// test as a shell script, but we'd like to be able to run the test on +// platforms that don't have a Bourne-compatible shell available (especially +// Windows/MSVC). +class EncodeDecodeTest : public testing::Test { + protected: + virtual void SetUp() { + duped_stdin_ = dup(STDIN_FILENO); + } + + virtual void TearDown() { + dup2(duped_stdin_, STDIN_FILENO); + close(duped_stdin_); + } + + void RedirectStdinFromText(const string& input) { + string filename = TestTempDir() + "/test_stdin"; + File::WriteStringToFileOrDie(input, filename); + GOOGLE_CHECK(RedirectStdinFromFile(filename)); + } + + bool RedirectStdinFromFile(const string& filename) { + int fd = open(filename.c_str(), O_RDONLY); + if (fd < 0) return false; + dup2(fd, STDIN_FILENO); + close(fd); + return true; + } + + // Remove '\r' characters from text. + string StripCR(const string& text) { + string result; + + for (int i = 0; i < text.size(); i++) { + if (text[i] != '\r') { + result.push_back(text[i]); + } + } + + return result; + } + + enum Type { TEXT, BINARY }; + enum ReturnCode { SUCCESS, ERROR }; + + bool Run(const string& command) { + vector args; + args.push_back("protoc"); + SplitStringUsing(command, " ", &args); + args.push_back("--proto_path=" + TestSourceDir()); + + scoped_array argv(new const char*[args.size()]); + for (int i = 0; i < args.size(); i++) { + argv[i] = args[i].c_str(); + } + + CommandLineInterface cli; + cli.SetInputsAreProtoPathRelative(true); + + CaptureTestStdout(); + CaptureTestStderr(); + + int result = cli.Run(args.size(), argv.get()); + + captured_stdout_ = GetCapturedTestStdout(); + captured_stderr_ = GetCapturedTestStderr(); + + return result == 0; + } + + void ExpectStdoutMatchesBinaryFile(const string& filename) { + string expected_output; + ASSERT_TRUE(File::ReadFileToString(filename, &expected_output)); + + // Don't use EXPECT_EQ because we don't want to print raw binary data to + // stdout on failure. + EXPECT_TRUE(captured_stdout_ == expected_output); + } + + void ExpectStdoutMatchesTextFile(const string& filename) { + string expected_output; + ASSERT_TRUE(File::ReadFileToString(filename, &expected_output)); + + ExpectStdoutMatchesText(expected_output); + } + + void ExpectStdoutMatchesText(const string& expected_text) { + EXPECT_EQ(StripCR(expected_text), StripCR(captured_stdout_)); + } + + void ExpectStderrMatchesText(const string& expected_text) { + EXPECT_EQ(StripCR(expected_text), StripCR(captured_stderr_)); + } + + private: + int duped_stdin_; + string captured_stdout_; + string captured_stderr_; +}; + +TEST_F(EncodeDecodeTest, Encode) { + RedirectStdinFromFile(TestSourceDir() + + "/google/protobuf/testdata/text_format_unittest_data.txt"); + EXPECT_TRUE(Run("google/protobuf/unittest.proto " + "--encode=protobuf_unittest.TestAllTypes")); + ExpectStdoutMatchesBinaryFile(TestSourceDir() + + "/google/protobuf/testdata/golden_message"); + ExpectStderrMatchesText(""); +} + +TEST_F(EncodeDecodeTest, Decode) { + RedirectStdinFromFile(TestSourceDir() + + "/google/protobuf/testdata/golden_message"); + EXPECT_TRUE(Run("google/protobuf/unittest.proto " + "--decode=protobuf_unittest.TestAllTypes")); + ExpectStdoutMatchesTextFile(TestSourceDir() + + "/google/protobuf/testdata/text_format_unittest_data.txt"); + ExpectStderrMatchesText(""); +} + +TEST_F(EncodeDecodeTest, Partial) { + RedirectStdinFromText(""); + EXPECT_TRUE(Run("google/protobuf/unittest.proto " + "--encode=protobuf_unittest.TestRequired")); + ExpectStdoutMatchesText(""); + ExpectStderrMatchesText( + "warning: Input message is missing required fields: a, b, c\n"); +} + +TEST_F(EncodeDecodeTest, DecodeRaw) { + protobuf_unittest::TestAllTypes message; + message.set_optional_int32(123); + message.set_optional_string("foo"); + string data; + message.SerializeToString(&data); + + RedirectStdinFromText(data); + EXPECT_TRUE(Run("--decode_raw")); + ExpectStdoutMatchesText("1: 123\n" + "14: \"foo\"\n"); + ExpectStderrMatchesText(""); +} + +TEST_F(EncodeDecodeTest, UnknownType) { + EXPECT_FALSE(Run("google/protobuf/unittest.proto " + "--encode=NoSuchType")); + ExpectStdoutMatchesText(""); + ExpectStderrMatchesText("Type not defined: NoSuchType\n"); +} + +TEST_F(EncodeDecodeTest, ProtoParseError) { + EXPECT_FALSE(Run("google/protobuf/no_such_file.proto " + "--encode=NoSuchType")); + ExpectStdoutMatchesText(""); + ExpectStderrMatchesText( + "google/protobuf/no_such_file.proto: File not found.\n"); +} + +} // anonymous namespace + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc new file mode 100644 index 0000000..b7c1766 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -0,0 +1,158 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This test insures that google/protobuf/descriptor.pb.{h,cc} match exactly +// what would be generated by the protocol compiler. These files are not +// generated automatically at build time because they are compiled into the +// protocol compiler itself. So, if they were auto-generated, you'd have a +// chicken-and-egg problem. +// +// If this test fails, run the script +// "generate_descriptor_proto.sh" and add +// descriptor.pb.{h,cc} to your changelist. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +namespace { + +class MockErrorCollector : public MultiFileErrorCollector { + public: + MockErrorCollector() {} + ~MockErrorCollector() {} + + string text_; + + // implements ErrorCollector --------------------------------------- + void AddError(const string& filename, int line, int column, + const string& message) { + strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", + filename, line, column, message); + } +}; + +class MockGeneratorContext : public GeneratorContext { + public: + MockGeneratorContext() {} + ~MockGeneratorContext() { + STLDeleteValues(&files_); + } + + void ExpectFileMatches(const string& virtual_filename, + const string& physical_filename) { + string* expected_contents = FindPtrOrNull(files_, virtual_filename); + ASSERT_TRUE(expected_contents != NULL) + << "Generator failed to generate file: " << virtual_filename; + + string actual_contents; + File::ReadFileToStringOrDie( + TestSourceDir() + "/" + physical_filename, + &actual_contents); + EXPECT_TRUE(actual_contents == *expected_contents) + << physical_filename << " needs to be regenerated. Please run " + "generate_descriptor_proto.sh and add this file " + "to your CL."; + } + + // implements GeneratorContext -------------------------------------- + + virtual io::ZeroCopyOutputStream* Open(const string& filename) { + string** map_slot = &files_[filename]; + if (*map_slot != NULL) delete *map_slot; + *map_slot = new string; + + return new io::StringOutputStream(*map_slot); + } + + private: + map files_; +}; + +TEST(BootstrapTest, GeneratedDescriptorMatches) { + MockErrorCollector error_collector; + DiskSourceTree source_tree; + source_tree.MapPath("", TestSourceDir()); + Importer importer(&source_tree, &error_collector); + const FileDescriptor* proto_file = + importer.Import("google/protobuf/descriptor.proto"); + const FileDescriptor* plugin_proto_file = + importer.Import("google/protobuf/compiler/plugin.proto"); + EXPECT_EQ("", error_collector.text_); + ASSERT_TRUE(proto_file != NULL); + ASSERT_TRUE(plugin_proto_file != NULL); + + CppGenerator generator; + MockGeneratorContext context; + string error; + string parameter; + parameter = "dllexport_decl=LIBPROTOBUF_EXPORT"; + ASSERT_TRUE(generator.Generate(proto_file, parameter, + &context, &error)); + parameter = "dllexport_decl=LIBPROTOC_EXPORT"; + ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter, + &context, &error)); + + context.ExpectFileMatches("google/protobuf/descriptor.pb.h", + "google/protobuf/descriptor.pb.h"); + context.ExpectFileMatches("google/protobuf/descriptor.pb.cc", + "google/protobuf/descriptor.pb.cc"); + context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h", + "google/protobuf/compiler/plugin.pb.h"); + context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc", + "google/protobuf/compiler/plugin.pb.cc"); +} + +} // namespace + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum.cc new file mode 100644 index 0000000..67c12d7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum.cc @@ -0,0 +1,258 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor), + classname_(ClassName(descriptor, false)), + options_(options) { +} + +EnumGenerator::~EnumGenerator() {} + +void EnumGenerator::GenerateDefinition(io::Printer* printer) { + map vars; + vars["classname"] = classname_; + vars["short_name"] = descriptor_->name(); + + printer->Print(vars, "enum $classname$ {\n"); + printer->Indent(); + + const EnumValueDescriptor* min_value = descriptor_->value(0); + const EnumValueDescriptor* max_value = descriptor_->value(0); + + for (int i = 0; i < descriptor_->value_count(); i++) { + vars["name"] = descriptor_->value(i)->name(); + vars["number"] = SimpleItoa(descriptor_->value(i)->number()); + vars["prefix"] = (descriptor_->containing_type() == NULL) ? + "" : classname_ + "_"; + + if (i > 0) printer->Print(",\n"); + printer->Print(vars, "$prefix$$name$ = $number$"); + + if (descriptor_->value(i)->number() < min_value->number()) { + min_value = descriptor_->value(i); + } + if (descriptor_->value(i)->number() > max_value->number()) { + max_value = descriptor_->value(i); + } + } + + printer->Outdent(); + printer->Print("\n};\n"); + + vars["min_name"] = min_value->name(); + vars["max_name"] = max_value->name(); + + if (options_.dllexport_decl.empty()) { + vars["dllexport"] = ""; + } else { + vars["dllexport"] = options_.dllexport_decl + " "; + } + + printer->Print(vars, + "$dllexport$bool $classname$_IsValid(int value);\n" + "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n" + "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n" + "const int $prefix$$short_name$_ARRAYSIZE = $prefix$$short_name$_MAX + 1;\n" + "\n"); + + if (HasDescriptorMethods(descriptor_->file())) { + printer->Print(vars, + "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n"); + // The _Name and _Parse methods + printer->Print(vars, + "inline const ::std::string& $classname$_Name($classname$ value) {\n" + " return ::google::protobuf::internal::NameOfEnum(\n" + " $classname$_descriptor(), value);\n" + "}\n"); + printer->Print(vars, + "inline bool $classname$_Parse(\n" + " const ::std::string& name, $classname$* value) {\n" + " return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n" + " $classname$_descriptor(), name, value);\n" + "}\n"); + } +} + +void EnumGenerator:: +GenerateGetEnumDescriptorSpecializations(io::Printer* printer) { + if (HasDescriptorMethods(descriptor_->file())) { + printer->Print( + "template <>\n" + "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n" + " return $classname$_descriptor();\n" + "}\n", + "classname", ClassName(descriptor_, true)); + } +} + +void EnumGenerator::GenerateSymbolImports(io::Printer* printer) { + map vars; + vars["nested_name"] = descriptor_->name(); + vars["classname"] = classname_; + printer->Print(vars, "typedef $classname$ $nested_name$;\n"); + + for (int j = 0; j < descriptor_->value_count(); j++) { + vars["tag"] = descriptor_->value(j)->name(); + printer->Print(vars, + "static const $nested_name$ $tag$ = $classname$_$tag$;\n"); + } + + printer->Print(vars, + "static inline bool $nested_name$_IsValid(int value) {\n" + " return $classname$_IsValid(value);\n" + "}\n" + "static const $nested_name$ $nested_name$_MIN =\n" + " $classname$_$nested_name$_MIN;\n" + "static const $nested_name$ $nested_name$_MAX =\n" + " $classname$_$nested_name$_MAX;\n" + "static const int $nested_name$_ARRAYSIZE =\n" + " $classname$_$nested_name$_ARRAYSIZE;\n"); + + if (HasDescriptorMethods(descriptor_->file())) { + printer->Print(vars, + "static inline const ::google::protobuf::EnumDescriptor*\n" + "$nested_name$_descriptor() {\n" + " return $classname$_descriptor();\n" + "}\n"); + printer->Print(vars, + "static inline const ::std::string& $nested_name$_Name($nested_name$ value) {\n" + " return $classname$_Name(value);\n" + "}\n"); + printer->Print(vars, + "static inline bool $nested_name$_Parse(const ::std::string& name,\n" + " $nested_name$* value) {\n" + " return $classname$_Parse(name, value);\n" + "}\n"); + } +} + +void EnumGenerator::GenerateDescriptorInitializer( + io::Printer* printer, int index) { + map vars; + vars["classname"] = classname_; + vars["index"] = SimpleItoa(index); + + if (descriptor_->containing_type() == NULL) { + printer->Print(vars, + "$classname$_descriptor_ = file->enum_type($index$);\n"); + } else { + vars["parent"] = ClassName(descriptor_->containing_type(), false); + printer->Print(vars, + "$classname$_descriptor_ = $parent$_descriptor_->enum_type($index$);\n"); + } +} + +void EnumGenerator::GenerateMethods(io::Printer* printer) { + map vars; + vars["classname"] = classname_; + + if (HasDescriptorMethods(descriptor_->file())) { + printer->Print(vars, + "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n" + " protobuf_AssignDescriptorsOnce();\n" + " return $classname$_descriptor_;\n" + "}\n"); + } + + printer->Print(vars, + "bool $classname$_IsValid(int value) {\n" + " switch(value) {\n"); + + // Multiple values may have the same number. Make sure we only cover + // each number once by first constructing a set containing all valid + // numbers, then printing a case statement for each element. + + set numbers; + for (int j = 0; j < descriptor_->value_count(); j++) { + const EnumValueDescriptor* value = descriptor_->value(j); + numbers.insert(value->number()); + } + + for (set::iterator iter = numbers.begin(); + iter != numbers.end(); ++iter) { + printer->Print( + " case $number$:\n", + "number", SimpleItoa(*iter)); + } + + printer->Print(vars, + " return true;\n" + " default:\n" + " return false;\n" + " }\n" + "}\n" + "\n"); + + if (descriptor_->containing_type() != NULL) { + // We need to "define" the static constants which were declared in the + // header, to give the linker a place to put them. Or at least the C++ + // standard says we have to. MSVC actually insists tha we do _not_ define + // them again in the .cc file. + printer->Print("#ifndef _MSC_VER\n"); + + vars["parent"] = ClassName(descriptor_->containing_type(), false); + vars["nested_name"] = descriptor_->name(); + for (int i = 0; i < descriptor_->value_count(); i++) { + vars["value"] = descriptor_->value(i)->name(); + printer->Print(vars, + "const $classname$ $parent$::$value$;\n"); + } + printer->Print(vars, + "const $classname$ $parent$::$nested_name$_MIN;\n" + "const $classname$ $parent$::$nested_name$_MAX;\n" + "const int $parent$::$nested_name$_ARRAYSIZE;\n"); + + printer->Print("#endif // _MSC_VER\n"); + } +} + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum.h new file mode 100644 index 0000000..2e85a0b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum.h @@ -0,0 +1,101 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__ + +#include +#include +#include + + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace cpp { + +class EnumGenerator { + public: + // See generator.cc for the meaning of dllexport_decl. + explicit EnumGenerator(const EnumDescriptor* descriptor, + const Options& options); + ~EnumGenerator(); + + // Header stuff. + + // Generate header code defining the enum. This code should be placed + // within the enum's package namespace, but NOT within any class, even for + // nested enums. + void GenerateDefinition(io::Printer* printer); + + // Generate specialization of GetEnumDescriptor(). + // Precondition: in ::google::protobuf namespace. + void GenerateGetEnumDescriptorSpecializations(io::Printer* printer); + + // For enums nested within a message, generate code to import all the enum's + // symbols (e.g. the enum type name, all its values, etc.) into the class's + // namespace. This should be placed inside the class definition in the + // header. + void GenerateSymbolImports(io::Printer* printer); + + // Source file stuff. + + // Generate code that initializes the global variable storing the enum's + // descriptor. + void GenerateDescriptorInitializer(io::Printer* printer, int index); + + // Generate non-inline methods related to the enum, such as IsValidValue(). + // Goes in the .cc file. + void GenerateMethods(io::Printer* printer); + + private: + const EnumDescriptor* descriptor_; + string classname_; + Options options_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum_field.cc new file mode 100644 index 0000000..6e1620d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -0,0 +1,366 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +namespace { + +void SetEnumVariables(const FieldDescriptor* descriptor, + map* variables, + const Options& options) { + SetCommonFieldVariables(descriptor, variables, options); + const EnumValueDescriptor* default_value = descriptor->default_value_enum(); + (*variables)["type"] = ClassName(descriptor->enum_type(), true); + (*variables)["default"] = SimpleItoa(default_value->number()); +} + +} // namespace + +// =================================================================== + +EnumFieldGenerator:: +EnumFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor) { + SetEnumVariables(descriptor, &variables_, options); +} + +EnumFieldGenerator::~EnumFieldGenerator() {} + +void EnumFieldGenerator:: +GeneratePrivateMembers(io::Printer* printer) const { + printer->Print(variables_, "int $name$_;\n"); +} + +void EnumFieldGenerator:: +GenerateAccessorDeclarations(io::Printer* printer) const { + printer->Print(variables_, + "inline $type$ $name$() const$deprecation$;\n" + "inline void set_$name$($type$ value)$deprecation$;\n"); +} + +void EnumFieldGenerator:: +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + printer->Print(variables_, + "inline $type$ $classname$::$name$() const {\n" + " return static_cast< $type$ >($name$_);\n" + "}\n" + "inline void $classname$::set_$name$($type$ value) {\n" + " assert($type$_IsValid(value));\n" + " set_has_$name$();\n" + " $name$_ = value;\n" + "}\n"); +} + +void EnumFieldGenerator:: +GenerateClearingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void EnumFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, "set_$name$(from.$name$());\n"); +} + +void EnumFieldGenerator:: +GenerateSwappingCode(io::Printer* printer) const { + printer->Print(variables_, "std::swap($name$_, other->$name$_);\n"); +} + +void EnumFieldGenerator:: +GenerateConstructorCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void EnumFieldGenerator:: +GenerateMergeFromCodedStream(io::Printer* printer) const { + printer->Print(variables_, + "int value;\n" + "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" + " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n" + " input, &value)));\n" + "if ($type$_IsValid(value)) {\n" + " set_$name$(static_cast< $type$ >(value));\n"); + if (HasUnknownFields(descriptor_->file())) { + printer->Print(variables_, + "} else {\n" + " mutable_unknown_fields()->AddVarint($number$, value);\n"); + } + printer->Print(variables_, + "}\n"); +} + +void EnumFieldGenerator:: +GenerateSerializeWithCachedSizes(io::Printer* printer) const { + printer->Print(variables_, + "::google::protobuf::internal::WireFormatLite::WriteEnum(\n" + " $number$, this->$name$(), output);\n"); +} + +void EnumFieldGenerator:: +GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { + printer->Print(variables_, + "target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n" + " $number$, this->$name$(), target);\n"); +} + +void EnumFieldGenerator:: +GenerateByteSize(io::Printer* printer) const { + printer->Print(variables_, + "total_size += $tag_size$ +\n" + " ::google::protobuf::internal::WireFormatLite::EnumSize(this->$name$());\n"); +} + +// =================================================================== + +RepeatedEnumFieldGenerator:: +RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor) { + SetEnumVariables(descriptor, &variables_, options); +} + +RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} + +void RepeatedEnumFieldGenerator:: +GeneratePrivateMembers(io::Printer* printer) const { + printer->Print(variables_, + "::google::protobuf::RepeatedField $name$_;\n"); + if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) { + printer->Print(variables_, + "mutable int _$name$_cached_byte_size_;\n"); + } +} + +void RepeatedEnumFieldGenerator:: +GenerateAccessorDeclarations(io::Printer* printer) const { + printer->Print(variables_, + "inline $type$ $name$(int index) const$deprecation$;\n" + "inline void set_$name$(int index, $type$ value)$deprecation$;\n" + "inline void add_$name$($type$ value)$deprecation$;\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedField& $name$() const$deprecation$;\n" + "inline ::google::protobuf::RepeatedField* mutable_$name$()$deprecation$;\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + printer->Print(variables_, + "inline $type$ $classname$::$name$(int index) const {\n" + " return static_cast< $type$ >($name$_.Get(index));\n" + "}\n" + "inline void $classname$::set_$name$(int index, $type$ value) {\n" + " assert($type$_IsValid(value));\n" + " $name$_.Set(index, value);\n" + "}\n" + "inline void $classname$::add_$name$($type$ value) {\n" + " assert($type$_IsValid(value));\n" + " $name$_.Add(value);\n" + "}\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedField&\n" + "$classname$::$name$() const {\n" + " return $name$_;\n" + "}\n" + "inline ::google::protobuf::RepeatedField*\n" + "$classname$::mutable_$name$() {\n" + " return &$name$_;\n" + "}\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateClearingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.Clear();\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateSwappingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateConstructorCode(io::Printer* printer) const { + // Not needed for repeated fields. +} + +void RepeatedEnumFieldGenerator:: +GenerateMergeFromCodedStream(io::Printer* printer) const { + // Don't use ReadRepeatedPrimitive here so that the enum can be validated. + printer->Print(variables_, + "int value;\n" + "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" + " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n" + " input, &value)));\n" + "if ($type$_IsValid(value)) {\n" + " add_$name$(static_cast< $type$ >(value));\n"); + if (HasUnknownFields(descriptor_->file())) { + printer->Print(variables_, + "} else {\n" + " mutable_unknown_fields()->AddVarint($number$, value);\n"); + } + printer->Print("}\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { + if (!descriptor_->options().packed()) { + // We use a non-inlined implementation in this case, since this path will + // rarely be executed. + printer->Print(variables_, + "DO_((::google::protobuf::internal::WireFormatLite::ReadPackedEnumNoInline(\n" + " input,\n" + " &$type$_IsValid,\n" + " this->mutable_$name$())));\n"); + } else { + printer->Print(variables_, + "::google::protobuf::uint32 length;\n" + "DO_(input->ReadVarint32(&length));\n" + "::google::protobuf::io::CodedInputStream::Limit limit = " + "input->PushLimit(length);\n" + "while (input->BytesUntilLimit() > 0) {\n" + " int value;\n" + " DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" + " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n" + " input, &value)));\n" + " if ($type$_IsValid(value)) {\n" + " add_$name$(static_cast< $type$ >(value));\n" + " }\n" + "}\n" + "input->PopLimit(limit);\n"); + } +} + +void RepeatedEnumFieldGenerator:: +GenerateSerializeWithCachedSizes(io::Printer* printer) const { + if (descriptor_->options().packed()) { + // Write the tag and the size. + printer->Print(variables_, + "if (this->$name$_size() > 0) {\n" + " ::google::protobuf::internal::WireFormatLite::WriteTag(\n" + " $number$,\n" + " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n" + " output);\n" + " output->WriteVarint32(_$name$_cached_byte_size_);\n" + "}\n"); + } + printer->Print(variables_, + "for (int i = 0; i < this->$name$_size(); i++) {\n"); + if (descriptor_->options().packed()) { + printer->Print(variables_, + " ::google::protobuf::internal::WireFormatLite::WriteEnumNoTag(\n" + " this->$name$(i), output);\n"); + } else { + printer->Print(variables_, + " ::google::protobuf::internal::WireFormatLite::WriteEnum(\n" + " $number$, this->$name$(i), output);\n"); + } + printer->Print("}\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { + if (descriptor_->options().packed()) { + // Write the tag and the size. + printer->Print(variables_, + "if (this->$name$_size() > 0) {\n" + " target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n" + " $number$,\n" + " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n" + " target);\n" + " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(" + " _$name$_cached_byte_size_, target);\n" + "}\n"); + } + printer->Print(variables_, + "for (int i = 0; i < this->$name$_size(); i++) {\n"); + if (descriptor_->options().packed()) { + printer->Print(variables_, + " target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n" + " this->$name$(i), target);\n"); + } else { + printer->Print(variables_, + " target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n" + " $number$, this->$name$(i), target);\n"); + } + printer->Print("}\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateByteSize(io::Printer* printer) const { + printer->Print(variables_, + "{\n" + " int data_size = 0;\n"); + printer->Indent(); + printer->Print(variables_, + "for (int i = 0; i < this->$name$_size(); i++) {\n" + " data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(\n" + " this->$name$(i));\n" + "}\n"); + + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (data_size > 0) {\n" + " total_size += $tag_size$ +\n" + " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n" + "}\n" + "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" + "_$name$_cached_byte_size_ = data_size;\n" + "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" + "total_size += data_size;\n"); + } else { + printer->Print(variables_, + "total_size += $tag_size$ * this->$name$_size() + data_size;\n"); + } + printer->Outdent(); + printer->Print("}\n"); +} + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum_field.h new file mode 100644 index 0000000..6577008 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_enum_field.h @@ -0,0 +1,105 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +class EnumFieldGenerator : public FieldGenerator { + public: + explicit EnumFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + ~EnumFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GeneratePrivateMembers(io::Printer* printer) const; + void GenerateAccessorDeclarations(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateClearingCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateSwappingCode(io::Printer* printer) const; + void GenerateConstructorCode(io::Printer* printer) const; + void GenerateMergeFromCodedStream(io::Printer* printer) const; + void GenerateSerializeWithCachedSizes(io::Printer* printer) const; + void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; + void GenerateByteSize(io::Printer* printer) const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); +}; + +class RepeatedEnumFieldGenerator : public FieldGenerator { + public: + explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + ~RepeatedEnumFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GeneratePrivateMembers(io::Printer* printer) const; + void GenerateAccessorDeclarations(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateClearingCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateSwappingCode(io::Printer* printer) const; + void GenerateConstructorCode(io::Printer* printer) const; + void GenerateMergeFromCodedStream(io::Printer* printer) const; + void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const; + void GenerateSerializeWithCachedSizes(io::Printer* printer) const; + void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; + void GenerateByteSize(io::Printer* printer) const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_extension.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_extension.cc new file mode 100644 index 0000000..ef56b5e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_extension.cc @@ -0,0 +1,210 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +namespace { + +// Returns the fully-qualified class name of the message that this field +// extends. This function is used in the Google-internal code to handle some +// legacy cases. +string ExtendeeClassName(const FieldDescriptor* descriptor) { + const Descriptor* extendee = descriptor->containing_type(); + return ClassName(extendee, true); +} + +} // anonymous namespace + +ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor), + options_(options) { + // Construct type_traits_. + if (descriptor_->is_repeated()) { + type_traits_ = "Repeated"; + } + + switch (descriptor_->cpp_type()) { + case FieldDescriptor::CPPTYPE_ENUM: + type_traits_.append("EnumTypeTraits< "); + type_traits_.append(ClassName(descriptor_->enum_type(), true)); + type_traits_.append(", "); + type_traits_.append(ClassName(descriptor_->enum_type(), true)); + type_traits_.append("_IsValid>"); + break; + case FieldDescriptor::CPPTYPE_STRING: + type_traits_.append("StringTypeTraits"); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + type_traits_.append("MessageTypeTraits< "); + type_traits_.append(ClassName(descriptor_->message_type(), true)); + type_traits_.append(" >"); + break; + default: + type_traits_.append("PrimitiveTypeTraits< "); + type_traits_.append(PrimitiveTypeName(descriptor_->cpp_type())); + type_traits_.append(" >"); + break; + } +} + +ExtensionGenerator::~ExtensionGenerator() {} + +void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) { + map vars; + vars["extendee" ] = ExtendeeClassName(descriptor_); + vars["number" ] = SimpleItoa(descriptor_->number()); + vars["type_traits" ] = type_traits_; + vars["name" ] = descriptor_->name(); + vars["field_type" ] = SimpleItoa(static_cast(descriptor_->type())); + vars["packed" ] = descriptor_->options().packed() ? "true" : "false"; + vars["constant_name"] = FieldConstantName(descriptor_); + + // If this is a class member, it needs to be declared "static". Otherwise, + // it needs to be "extern". In the latter case, it also needs the DLL + // export/import specifier. + if (descriptor_->extension_scope() == NULL) { + vars["qualifier"] = "extern"; + if (!options_.dllexport_decl.empty()) { + vars["qualifier"] = options_.dllexport_decl + " " + vars["qualifier"]; + } + } else { + vars["qualifier"] = "static"; + } + + printer->Print(vars, + "static const int $constant_name$ = $number$;\n" + "$qualifier$ ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n" + " ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n" + " $name$;\n" + ); + +} + +void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { + // If this is a class member, it needs to be declared in its class scope. + string scope = (descriptor_->extension_scope() == NULL) ? "" : + ClassName(descriptor_->extension_scope(), false) + "::"; + string name = scope + descriptor_->name(); + + map vars; + vars["extendee" ] = ExtendeeClassName(descriptor_); + vars["type_traits" ] = type_traits_; + vars["name" ] = name; + vars["constant_name"] = FieldConstantName(descriptor_); + vars["default" ] = DefaultValue(descriptor_); + vars["field_type" ] = SimpleItoa(static_cast(descriptor_->type())); + vars["packed" ] = descriptor_->options().packed() ? "true" : "false"; + vars["scope" ] = scope; + + if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + // We need to declare a global string which will contain the default value. + // We cannot declare it at class scope because that would require exposing + // it in the header which would be annoying for other reasons. So we + // replace :: with _ in the name and declare it as a global. + string global_name = StringReplace(name, "::", "_", true); + vars["global_name"] = global_name; + printer->Print(vars, + "const ::std::string $global_name$_default($default$);\n"); + + // Update the default to refer to the string global. + vars["default"] = global_name + "_default"; + } + + // Likewise, class members need to declare the field constant variable. + if (descriptor_->extension_scope() != NULL) { + printer->Print(vars, + "#ifndef _MSC_VER\n" + "const int $scope$$constant_name$;\n" + "#endif\n"); + } + + printer->Print(vars, + "::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n" + " ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n" + " $name$($constant_name$, $default$);\n"); +} + +void ExtensionGenerator::GenerateRegistration(io::Printer* printer) { + map vars; + vars["extendee" ] = ExtendeeClassName(descriptor_); + vars["number" ] = SimpleItoa(descriptor_->number()); + vars["field_type" ] = SimpleItoa(static_cast(descriptor_->type())); + vars["is_repeated"] = descriptor_->is_repeated() ? "true" : "false"; + vars["is_packed" ] = (descriptor_->is_repeated() && + descriptor_->options().packed()) + ? "true" : "false"; + + switch (descriptor_->cpp_type()) { + case FieldDescriptor::CPPTYPE_ENUM: + printer->Print(vars, + "::google::protobuf::internal::ExtensionSet::RegisterEnumExtension(\n" + " &$extendee$::default_instance(),\n" + " $number$, $field_type$, $is_repeated$, $is_packed$,\n"); + printer->Print( + " &$type$_IsValid);\n", + "type", ClassName(descriptor_->enum_type(), true)); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + printer->Print(vars, + "::google::protobuf::internal::ExtensionSet::RegisterMessageExtension(\n" + " &$extendee$::default_instance(),\n" + " $number$, $field_type$, $is_repeated$, $is_packed$,\n"); + printer->Print( + " &$type$::default_instance());\n", + "type", ClassName(descriptor_->message_type(), true)); + break; + default: + printer->Print(vars, + "::google::protobuf::internal::ExtensionSet::RegisterExtension(\n" + " &$extendee$::default_instance(),\n" + " $number$, $field_type$, $is_repeated$, $is_packed$);\n"); + break; + } +} + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_extension.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_extension.h new file mode 100644 index 0000000..50ad035 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_extension.h @@ -0,0 +1,86 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { + class FieldDescriptor; // descriptor.h + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace cpp { + +// Generates code for an extension, which may be within the scope of some +// message or may be at file scope. This is much simpler than FieldGenerator +// since extensions are just simple identifiers with interesting types. +class ExtensionGenerator { + public: + // See generator.cc for the meaning of dllexport_decl. + explicit ExtensionGenerator(const FieldDescriptor* desycriptor, + const Options& options); + ~ExtensionGenerator(); + + // Header stuff. + void GenerateDeclaration(io::Printer* printer); + + // Source file stuff. + void GenerateDefinition(io::Printer* printer); + + // Generate code to register the extension. + void GenerateRegistration(io::Printer* printer); + + private: + const FieldDescriptor* descriptor_; + string type_traits_; + Options options_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_field.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_field.cc new file mode 100644 index 0000000..0786176 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_field.cc @@ -0,0 +1,142 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +using internal::WireFormat; + +void SetCommonFieldVariables(const FieldDescriptor* descriptor, + map* variables, + const Options& options) { + (*variables)["name"] = FieldName(descriptor); + (*variables)["index"] = SimpleItoa(descriptor->index()); + (*variables)["number"] = SimpleItoa(descriptor->number()); + (*variables)["classname"] = ClassName(FieldScope(descriptor), false); + (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type()); + + (*variables)["tag_size"] = SimpleItoa( + WireFormat::TagSize(descriptor->number(), descriptor->type())); + (*variables)["deprecation"] = descriptor->options().deprecated() + ? " PROTOBUF_DEPRECATED" : ""; + + (*variables)["cppget"] = "Get"; +} + +FieldGenerator::~FieldGenerator() {} + +void FieldGenerator:: +GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { + // Reaching here indicates a bug. Cases are: + // - This FieldGenerator should support packing, but this method should be + // overridden. + // - This FieldGenerator doesn't support packing, and this method should + // never have been called. + GOOGLE_LOG(FATAL) << "GenerateMergeFromCodedStreamWithPacking() " + << "called on field generator that does not support packing."; + +} + +FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, + const Options& options) + : descriptor_(descriptor), + field_generators_(new scoped_ptr[descriptor->field_count()]) { + // Construct all the FieldGenerators. + for (int i = 0; i < descriptor->field_count(); i++) { + field_generators_[i].reset(MakeGenerator(descriptor->field(i), options)); + } +} + +FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field, + const Options& options) { + if (field->is_repeated()) { + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_MESSAGE: + return new RepeatedMessageFieldGenerator(field, options); + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // RepeatedStringFieldGenerator handles unknown ctypes. + case FieldOptions::STRING: + return new RepeatedStringFieldGenerator(field, options); + } + case FieldDescriptor::CPPTYPE_ENUM: + return new RepeatedEnumFieldGenerator(field, options); + default: + return new RepeatedPrimitiveFieldGenerator(field, options); + } + } else { + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_MESSAGE: + return new MessageFieldGenerator(field, options); + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // StringFieldGenerator handles unknown ctypes. + case FieldOptions::STRING: + return new StringFieldGenerator(field, options); + } + case FieldDescriptor::CPPTYPE_ENUM: + return new EnumFieldGenerator(field, options); + default: + return new PrimitiveFieldGenerator(field, options); + } + } +} + +FieldGeneratorMap::~FieldGeneratorMap() {} + +const FieldGenerator& FieldGeneratorMap::get( + const FieldDescriptor* field) const { + GOOGLE_CHECK_EQ(field->containing_type(), descriptor_); + return *field_generators_[field->index()]; +} + + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_field.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_field.h new file mode 100644 index 0000000..f7d99b1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_field.h @@ -0,0 +1,177 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__ + +#include +#include + +#include +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace cpp { + +// Helper function: set variables in the map that are the same for all +// field code generators. +// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size', +// 'deprecation']. +void SetCommonFieldVariables(const FieldDescriptor* descriptor, + map* variables, + const Options& options); + +class FieldGenerator { + public: + FieldGenerator() {} + virtual ~FieldGenerator(); + + // Generate lines of code declaring members fields of the message class + // needed to represent this field. These are placed inside the message + // class. + virtual void GeneratePrivateMembers(io::Printer* printer) const = 0; + + // Generate prototypes for all of the accessor functions related to this + // field. These are placed inside the class definition. + virtual void GenerateAccessorDeclarations(io::Printer* printer) const = 0; + + // Generate inline definitions of accessor functions for this field. + // These are placed inside the header after all class definitions. + virtual void GenerateInlineAccessorDefinitions( + io::Printer* printer) const = 0; + + // Generate definitions of accessors that aren't inlined. These are + // placed somewhere in the .cc file. + // Most field types don't need this, so the default implementation is empty. + virtual void GenerateNonInlineAccessorDefinitions( + io::Printer* printer) const {} + + // Generate lines of code (statements, not declarations) which clear the + // field. This is used to define the clear_$name$() method as well as + // the Clear() method for the whole message. + virtual void GenerateClearingCode(io::Printer* printer) const = 0; + + // Generate lines of code (statements, not declarations) which merges the + // contents of the field from the current message to the target message, + // which is stored in the generated code variable "from". + // This is used to fill in the MergeFrom method for the whole message. + // Details of this usage can be found in message.cc under the + // GenerateMergeFrom method. + virtual void GenerateMergingCode(io::Printer* printer) const = 0; + + // Generate lines of code (statements, not declarations) which swaps + // this field and the corresponding field of another message, which + // is stored in the generated code variable "other". This is used to + // define the Swap method. Details of usage can be found in + // message.cc under the GenerateSwap method. + virtual void GenerateSwappingCode(io::Printer* printer) const = 0; + + // Generate initialization code for private members declared by + // GeneratePrivateMembers(). These go into the message class's SharedCtor() + // method, invoked by each of the generated constructors. + virtual void GenerateConstructorCode(io::Printer* printer) const = 0; + + // Generate any code that needs to go in the class's SharedDtor() method, + // invoked by the destructor. + // Most field types don't need this, so the default implementation is empty. + virtual void GenerateDestructorCode(io::Printer* printer) const {} + + // Generate code that allocates the fields's default instance. + virtual void GenerateDefaultInstanceAllocator(io::Printer* printer) const {} + + // Generate code that should be run when ShutdownProtobufLibrary() is called, + // to delete all dynamically-allocated objects. + virtual void GenerateShutdownCode(io::Printer* printer) const {} + + // Generate lines to decode this field, which will be placed inside the + // message's MergeFromCodedStream() method. + virtual void GenerateMergeFromCodedStream(io::Printer* printer) const = 0; + + // Generate lines to decode this field from a packed value, which will be + // placed inside the message's MergeFromCodedStream() method. + virtual void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) + const; + + // Generate lines to serialize this field, which are placed within the + // message's SerializeWithCachedSizes() method. + virtual void GenerateSerializeWithCachedSizes(io::Printer* printer) const = 0; + + // Generate lines to serialize this field directly to the array "target", + // which are placed within the message's SerializeWithCachedSizesToArray() + // method. This must also advance "target" past the written bytes. + virtual void GenerateSerializeWithCachedSizesToArray( + io::Printer* printer) const = 0; + + // Generate lines to compute the serialized size of this field, which + // are placed in the message's ByteSize() method. + virtual void GenerateByteSize(io::Printer* printer) const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); +}; + +// Convenience class which constructs FieldGenerators for a Descriptor. +class FieldGeneratorMap { + public: + explicit FieldGeneratorMap(const Descriptor* descriptor, const Options& options); + ~FieldGeneratorMap(); + + const FieldGenerator& get(const FieldDescriptor* field) const; + + private: + const Descriptor* descriptor_; + scoped_array > field_generators_; + + static FieldGenerator* MakeGenerator(const FieldDescriptor* field, + const Options& options); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); +}; + + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_file.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_file.cc new file mode 100644 index 0000000..cfe96c8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -0,0 +1,652 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +// =================================================================== + +FileGenerator::FileGenerator(const FileDescriptor* file, + const Options& options) + : file_(file), + message_generators_( + new scoped_ptr[file->message_type_count()]), + enum_generators_( + new scoped_ptr[file->enum_type_count()]), + service_generators_( + new scoped_ptr[file->service_count()]), + extension_generators_( + new scoped_ptr[file->extension_count()]), + options_(options) { + + for (int i = 0; i < file->message_type_count(); i++) { + message_generators_[i].reset( + new MessageGenerator(file->message_type(i), options)); + } + + for (int i = 0; i < file->enum_type_count(); i++) { + enum_generators_[i].reset( + new EnumGenerator(file->enum_type(i), options)); + } + + for (int i = 0; i < file->service_count(); i++) { + service_generators_[i].reset( + new ServiceGenerator(file->service(i), options)); + } + + for (int i = 0; i < file->extension_count(); i++) { + extension_generators_[i].reset( + new ExtensionGenerator(file->extension(i), options)); + } + + SplitStringUsing(file_->package(), ".", &package_parts_); +} + +FileGenerator::~FileGenerator() {} + +void FileGenerator::GenerateHeader(io::Printer* printer) { + string filename_identifier = FilenameIdentifier(file_->name()); + + // Generate top of header. + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n" + "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n" + "#define PROTOBUF_$filename_identifier$__INCLUDED\n" + "\n" + "#include \n" + "\n", + "filename", file_->name(), + "filename_identifier", filename_identifier); + + + printer->Print( + "#include \n" + "\n"); + + // Verify the protobuf library header version is compatible with the protoc + // version before going any further. + printer->Print( + "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n" + "#error This file was generated by a newer version of protoc which is\n" + "#error incompatible with your Protocol Buffer headers. Please update\n" + "#error your headers.\n" + "#endif\n" + "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n" + "#error This file was generated by an older version of protoc which is\n" + "#error incompatible with your Protocol Buffer headers. Please\n" + "#error regenerate this file with a newer version of protoc.\n" + "#endif\n" + "\n", + "min_header_version", + SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc), + "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION)); + + // OK, it's now safe to #include other files. + printer->Print( + "#include \n"); + if (file_->message_type_count() > 0) { + if (HasDescriptorMethods(file_)) { + printer->Print( + "#include \n"); + } else { + printer->Print( + "#include \n"); + } + } + printer->Print( + "#include \n" + "#include \n"); + + if (HasDescriptorMethods(file_) && HasEnumDefinitions(file_)) { + printer->Print( + "#include \n"); + } + + if (HasGenericServices(file_)) { + printer->Print( + "#include \n"); + } + + if (HasUnknownFields(file_) && file_->message_type_count() > 0) { + printer->Print( + "#include \n"); + } + + + for (int i = 0; i < file_->dependency_count(); i++) { + printer->Print( + "#include \"$dependency$.pb.h\"\n", + "dependency", StripProto(file_->dependency(i)->name())); + } + + + printer->Print( + "// @@protoc_insertion_point(includes)\n"); + + + // Open namespace. + GenerateNamespaceOpeners(printer); + + // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile + // functions, so that we can declare them to be friends of each class. + printer->Print( + "\n" + "// Internal implementation detail -- do not call these.\n" + "void $dllexport_decl$ $adddescriptorsname$();\n", + "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), + "dllexport_decl", options_.dllexport_decl); + + printer->Print( + // Note that we don't put dllexport_decl on these because they are only + // called by the .pb.cc file in which they are defined. + "void $assigndescriptorsname$();\n" + "void $shutdownfilename$();\n" + "\n", + "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()), + "shutdownfilename", GlobalShutdownFileName(file_->name())); + + // Generate forward declarations of classes. + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateForwardDeclaration(printer); + } + + printer->Print("\n"); + + // Generate enum definitions. + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateEnumDefinitions(printer); + } + for (int i = 0; i < file_->enum_type_count(); i++) { + enum_generators_[i]->GenerateDefinition(printer); + } + + printer->Print(kThickSeparator); + printer->Print("\n"); + + // Generate class definitions. + for (int i = 0; i < file_->message_type_count(); i++) { + if (i > 0) { + printer->Print("\n"); + printer->Print(kThinSeparator); + printer->Print("\n"); + } + message_generators_[i]->GenerateClassDefinition(printer); + } + + printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); + + if (HasGenericServices(file_)) { + // Generate service definitions. + for (int i = 0; i < file_->service_count(); i++) { + if (i > 0) { + printer->Print("\n"); + printer->Print(kThinSeparator); + printer->Print("\n"); + } + service_generators_[i]->GenerateDeclarations(printer); + } + + printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); + } + + // Declare extension identifiers. + for (int i = 0; i < file_->extension_count(); i++) { + extension_generators_[i]->GenerateDeclaration(printer); + } + + printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); + + // Generate class inline methods. + for (int i = 0; i < file_->message_type_count(); i++) { + if (i > 0) { + printer->Print(kThinSeparator); + printer->Print("\n"); + } + message_generators_[i]->GenerateInlineMethods(printer); + } + + printer->Print( + "\n" + "// @@protoc_insertion_point(namespace_scope)\n"); + + // Close up namespace. + GenerateNamespaceClosers(printer); + + // Emit GetEnumDescriptor specializations into google::protobuf namespace: + if (HasDescriptorMethods(file_)) { + // The SWIG conditional is to avoid a null-pointer dereference + // (bug 1984964) in swig-1.3.21 resulting from the following syntax: + // namespace X { void Y(); } + // which appears in GetEnumDescriptor() specializations. + printer->Print( + "\n" + "#ifndef SWIG\n" + "namespace google {\nnamespace protobuf {\n" + "\n"); + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); + } + for (int i = 0; i < file_->enum_type_count(); i++) { + enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); + } + printer->Print( + "\n" + "} // namespace google\n} // namespace protobuf\n" + "#endif // SWIG\n"); + } + + printer->Print( + "\n" + "// @@protoc_insertion_point(global_scope)\n" + "\n"); + + printer->Print( + "#endif // PROTOBUF_$filename_identifier$__INCLUDED\n", + "filename_identifier", filename_identifier); +} + +void FileGenerator::GenerateSource(io::Printer* printer) { + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n" + + // The generated code calls accessors that might be deprecated. We don't + // want the compiler to warn in generated code. + "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n" + "#include \"$basename$.pb.h\"\n" + "\n" + "#include \n" // for swap() + "\n" + "#include \n" + "#include \n" + "#include \n" + "#include \n", + "filename", file_->name(), + "basename", StripProto(file_->name())); + + if (HasDescriptorMethods(file_)) { + printer->Print( + "#include \n" + "#include \n" + "#include \n" + "#include \n"); + } + + printer->Print( + "// @@protoc_insertion_point(includes)\n"); + + GenerateNamespaceOpeners(printer); + + if (HasDescriptorMethods(file_)) { + printer->Print( + "\n" + "namespace {\n" + "\n"); + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateDescriptorDeclarations(printer); + } + for (int i = 0; i < file_->enum_type_count(); i++) { + printer->Print( + "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", + "name", ClassName(file_->enum_type(i), false)); + } + + if (HasGenericServices(file_)) { + for (int i = 0; i < file_->service_count(); i++) { + printer->Print( + "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n", + "name", file_->service(i)->name()); + } + } + + printer->Print( + "\n" + "} // namespace\n" + "\n"); + } + + // Define our externally-visible BuildDescriptors() function. (For the lite + // library, all this does is initialize default instances.) + GenerateBuildDescriptors(printer); + + // Generate enums. + for (int i = 0; i < file_->enum_type_count(); i++) { + enum_generators_[i]->GenerateMethods(printer); + } + + // Generate classes. + for (int i = 0; i < file_->message_type_count(); i++) { + printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); + message_generators_[i]->GenerateClassMethods(printer); + } + + if (HasGenericServices(file_)) { + // Generate services. + for (int i = 0; i < file_->service_count(); i++) { + if (i == 0) printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); + service_generators_[i]->GenerateImplementation(printer); + } + } + + // Define extensions. + for (int i = 0; i < file_->extension_count(); i++) { + extension_generators_[i]->GenerateDefinition(printer); + } + + printer->Print( + "\n" + "// @@protoc_insertion_point(namespace_scope)\n"); + + GenerateNamespaceClosers(printer); + + printer->Print( + "\n" + "// @@protoc_insertion_point(global_scope)\n"); +} + +void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { + // AddDescriptors() is a file-level procedure which adds the encoded + // FileDescriptorProto for this .proto file to the global DescriptorPool for + // generated files (DescriptorPool::generated_pool()). It either runs at + // static initialization time (by default) or when default_instance() is + // called for the first time (in LITE_RUNTIME mode with + // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also + // constructs default instances and registers extensions. + // + // Its sibling, AssignDescriptors(), actually pulls the compiled + // FileDescriptor from the DescriptorPool and uses it to populate all of + // the global variables which store pointers to the descriptor objects. + // It also constructs the reflection objects. It is called the first time + // anyone calls descriptor() or GetReflection() on one of the types defined + // in the file. + + // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors() + // and we only use AddDescriptors() to allocate default instances. + if (HasDescriptorMethods(file_)) { + printer->Print( + "\n" + "void $assigndescriptorsname$() {\n", + "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name())); + printer->Indent(); + + // Make sure the file has found its way into the pool. If a descriptor + // is requested *during* static init then AddDescriptors() may not have + // been called yet, so we call it manually. Note that it's fine if + // AddDescriptors() is called multiple times. + printer->Print( + "$adddescriptorsname$();\n", + "adddescriptorsname", GlobalAddDescriptorsName(file_->name())); + + // Get the file's descriptor from the pool. + printer->Print( + "const ::google::protobuf::FileDescriptor* file =\n" + " ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n" + " \"$filename$\");\n" + // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file" + // being unused when compiling an empty .proto file. + "GOOGLE_CHECK(file != NULL);\n", + "filename", file_->name()); + + // Go through all the stuff defined in this file and generated code to + // assign the global descriptor pointers based on the file descriptor. + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateDescriptorInitializer(printer, i); + } + for (int i = 0; i < file_->enum_type_count(); i++) { + enum_generators_[i]->GenerateDescriptorInitializer(printer, i); + } + if (HasGenericServices(file_)) { + for (int i = 0; i < file_->service_count(); i++) { + service_generators_[i]->GenerateDescriptorInitializer(printer, i); + } + } + + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + + // --------------------------------------------------------------- + + // protobuf_AssignDescriptorsOnce(): The first time it is called, calls + // AssignDescriptors(). All later times, waits for the first call to + // complete and then returns. + printer->Print( + "namespace {\n" + "\n" + "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n" + "inline void protobuf_AssignDescriptorsOnce() {\n" + " ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n" + " &$assigndescriptorsname$);\n" + "}\n" + "\n", + "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name())); + + // protobuf_RegisterTypes(): Calls + // MessageFactory::InternalRegisterGeneratedType() for each message type. + printer->Print( + "void protobuf_RegisterTypes(const ::std::string&) {\n" + " protobuf_AssignDescriptorsOnce();\n"); + printer->Indent(); + + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateTypeRegistrations(printer); + } + + printer->Outdent(); + printer->Print( + "}\n" + "\n" + "} // namespace\n"); + } + + // ----------------------------------------------------------------- + + // ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown. + printer->Print( + "\n" + "void $shutdownfilename$() {\n", + "shutdownfilename", GlobalShutdownFileName(file_->name())); + printer->Indent(); + + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateShutdownCode(printer); + } + + printer->Outdent(); + printer->Print( + "}\n\n"); + + // ----------------------------------------------------------------- + + // Now generate the AddDescriptors() function. + PrintHandlingOptionalStaticInitializers( + file_, printer, + // With static initializers. + // Note that we don't need any special synchronization in the following code + // because it is called at static init time before any threads exist. + "void $adddescriptorsname$() {\n" + " static bool already_here = false;\n" + " if (already_here) return;\n" + " already_here = true;\n" + " GOOGLE_PROTOBUF_VERIFY_VERSION;\n" + "\n", + // Without. + "void $adddescriptorsname$_impl() {\n" + " GOOGLE_PROTOBUF_VERIFY_VERSION;\n" + "\n", + // Vars. + "adddescriptorsname", GlobalAddDescriptorsName(file_->name())); + + printer->Indent(); + + // Call the AddDescriptors() methods for all of our dependencies, to make + // sure they get added first. + for (int i = 0; i < file_->dependency_count(); i++) { + const FileDescriptor* dependency = file_->dependency(i); + // Print the namespace prefix for the dependency. + vector dependency_package_parts; + SplitStringUsing(dependency->package(), ".", &dependency_package_parts); + printer->Print("::"); + for (int j = 0; j < dependency_package_parts.size(); j++) { + printer->Print("$name$::", + "name", dependency_package_parts[j]); + } + // Call its AddDescriptors function. + printer->Print( + "$name$();\n", + "name", GlobalAddDescriptorsName(dependency->name())); + } + + if (HasDescriptorMethods(file_)) { + // Embed the descriptor. We simply serialize the entire FileDescriptorProto + // and embed it as a string literal, which is parsed and built into real + // descriptors at initialization time. + FileDescriptorProto file_proto; + file_->CopyTo(&file_proto); + string file_data; + file_proto.SerializeToString(&file_data); + + printer->Print( + "::google::protobuf::DescriptorPool::InternalAddGeneratedFile("); + + // Only write 40 bytes per line. + static const int kBytesPerLine = 40; + for (int i = 0; i < file_data.size(); i += kBytesPerLine) { + printer->Print("\n \"$data$\"", + "data", + EscapeTrigraphs( + CEscape(file_data.substr(i, kBytesPerLine)))); + } + printer->Print( + ", $size$);\n", + "size", SimpleItoa(file_data.size())); + + // Call MessageFactory::InternalRegisterGeneratedFile(). + printer->Print( + "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n" + " \"$filename$\", &protobuf_RegisterTypes);\n", + "filename", file_->name()); + } + + // Allocate and initialize default instances. This can't be done lazily + // since default instances are returned by simple accessors and are used with + // extensions. Speaking of which, we also register extensions at this time. + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateDefaultInstanceAllocator(printer); + } + for (int i = 0; i < file_->extension_count(); i++) { + extension_generators_[i]->GenerateRegistration(printer); + } + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateDefaultInstanceInitializer(printer); + } + + printer->Print( + "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n", + "shutdownfilename", GlobalShutdownFileName(file_->name())); + + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + + PrintHandlingOptionalStaticInitializers( + file_, printer, + // With static initializers. + "// Force AddDescriptors() to be called at static initialization time.\n" + "struct StaticDescriptorInitializer_$filename$ {\n" + " StaticDescriptorInitializer_$filename$() {\n" + " $adddescriptorsname$();\n" + " }\n" + "} static_descriptor_initializer_$filename$_;\n", + // Without. + "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n" + "void $adddescriptorsname$() {\n" + " ::google::protobuf::::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n" + " &$adddescriptorsname$_impl);\n" + "}\n", + // Vars. + "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), + "filename", FilenameIdentifier(file_->name())); +} + +void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) { + if (package_parts_.size() > 0) printer->Print("\n"); + + for (int i = 0; i < package_parts_.size(); i++) { + printer->Print("namespace $part$ {\n", + "part", package_parts_[i]); + } +} + +void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) { + if (package_parts_.size() > 0) printer->Print("\n"); + + for (int i = package_parts_.size() - 1; i >= 0; i--) { + printer->Print("} // namespace $part$\n", + "part", package_parts_[i]); + } +} + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_file.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_file.h new file mode 100644 index 0000000..2deefaa --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_file.h @@ -0,0 +1,99 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__ + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + class FileDescriptor; // descriptor.h + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace cpp { + +class EnumGenerator; // enum.h +class MessageGenerator; // message.h +class ServiceGenerator; // service.h +class ExtensionGenerator; // extension.h + +class FileGenerator { + public: + // See generator.cc for the meaning of dllexport_decl. + explicit FileGenerator(const FileDescriptor* file, + const Options& options); + ~FileGenerator(); + + void GenerateHeader(io::Printer* printer); + void GenerateSource(io::Printer* printer); + + private: + // Generate the BuildDescriptors() procedure, which builds all descriptors + // for types defined in the file. + void GenerateBuildDescriptors(io::Printer* printer); + + void GenerateNamespaceOpeners(io::Printer* printer); + void GenerateNamespaceClosers(io::Printer* printer); + + const FileDescriptor* file_; + + scoped_array > message_generators_; + scoped_array > enum_generators_; + scoped_array > service_generators_; + scoped_array > extension_generators_; + + // E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}. + vector package_parts_; + + const Options options_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_generator.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_generator.cc new file mode 100644 index 0000000..1813510 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_generator.cc @@ -0,0 +1,124 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +CppGenerator::CppGenerator() {} +CppGenerator::~CppGenerator() {} + +bool CppGenerator::Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const { + vector > options; + ParseGeneratorParameter(parameter, &options); + + // ----------------------------------------------------------------- + // parse generator options + + // TODO(kenton): If we ever have more options, we may want to create a + // class that encapsulates them which we can pass down to all the + // generator classes. Currently we pass dllexport_decl down to all of + // them via the constructors, but we don't want to have to add another + // constructor parameter for every option. + + // If the dllexport_decl option is passed to the compiler, we need to write + // it in front of every symbol that should be exported if this .proto is + // compiled into a Windows DLL. E.g., if the user invokes the protocol + // compiler as: + // protoc --cpp_out=dllexport_decl=FOO_EXPORT:outdir foo.proto + // then we'll define classes like this: + // class FOO_EXPORT Foo { + // ... + // } + // FOO_EXPORT is a macro which should expand to __declspec(dllexport) or + // __declspec(dllimport) depending on what is being compiled. + Options file_options; + + for (int i = 0; i < options.size(); i++) { + if (options[i].first == "dllexport_decl") { + file_options.dllexport_decl = options[i].second; + } else if (options[i].first == "safe_boundary_check") { + file_options.safe_boundary_check = true; + } else { + *error = "Unknown generator option: " + options[i].first; + return false; + } + } + + // ----------------------------------------------------------------- + + + string basename = StripProto(file->name()); + basename.append(".pb"); + + FileGenerator file_generator(file, file_options); + + // Generate header. + { + scoped_ptr output( + generator_context->Open(basename + ".h")); + io::Printer printer(output.get(), '$'); + file_generator.GenerateHeader(&printer); + } + + // Generate cc file. + { + scoped_ptr output( + generator_context->Open(basename + ".cc")); + io::Printer printer(output.get(), '$'); + file_generator.GenerateSource(&printer); + } + + return true; +} + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_generator.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_generator.h new file mode 100644 index 0000000..a90e84d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_generator.h @@ -0,0 +1,72 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Generates C++ code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +// CodeGenerator implementation which generates a C++ source file and +// header. If you create your own protocol compiler binary and you want +// it to support C++ output, you can do so by registering an instance of this +// CodeGenerator with the CommandLineInterface in your main() function. +class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator { + public: + CppGenerator(); + ~CppGenerator(); + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_helpers.cc new file mode 100644 index 0000000..28911ab --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -0,0 +1,438 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +namespace { + +string DotsToUnderscores(const string& name) { + return StringReplace(name, ".", "_", true); +} + +string DotsToColons(const string& name) { + return StringReplace(name, ".", "::", true); +} + +const char* const kKeywordList[] = { + "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case", + "catch", "char", "class", "compl", "const", "const_cast", "continue", + "default", "delete", "do", "double", "dynamic_cast", "else", "enum", + "explicit", "extern", "false", "float", "for", "friend", "goto", "if", + "inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq", + "operator", "or", "or_eq", "private", "protected", "public", "register", + "reinterpret_cast", "return", "short", "signed", "sizeof", "static", + "static_cast", "struct", "switch", "template", "this", "throw", "true", "try", + "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", + "void", "volatile", "wchar_t", "while", "xor", "xor_eq" +}; + +hash_set MakeKeywordsMap() { + hash_set result; + for (int i = 0; i < GOOGLE_ARRAYSIZE(kKeywordList); i++) { + result.insert(kKeywordList[i]); + } + return result; +} + +hash_set kKeywords = MakeKeywordsMap(); + +string UnderscoresToCamelCase(const string& input, bool cap_next_letter) { + string result; + // Note: I distrust ctype.h due to locales. + for (int i = 0; i < input.size(); i++) { + if ('a' <= input[i] && input[i] <= 'z') { + if (cap_next_letter) { + result += input[i] + ('A' - 'a'); + } else { + result += input[i]; + } + cap_next_letter = false; + } else if ('A' <= input[i] && input[i] <= 'Z') { + // Capital letters are left as-is. + result += input[i]; + cap_next_letter = false; + } else if ('0' <= input[i] && input[i] <= '9') { + result += input[i]; + cap_next_letter = true; + } else { + cap_next_letter = true; + } + } + return result; +} + +// Returns whether the provided descriptor has an extension. This includes its +// nested types. +bool HasExtension(const Descriptor* descriptor) { + if (descriptor->extension_count() > 0) { + return true; + } + for (int i = 0; i < descriptor->nested_type_count(); ++i) { + if (HasExtension(descriptor->nested_type(i))) { + return true; + } + } + return false; +} + +} // namespace + +const char kThickSeparator[] = + "// ===================================================================\n"; +const char kThinSeparator[] = + "// -------------------------------------------------------------------\n"; + +string ClassName(const Descriptor* descriptor, bool qualified) { + + // Find "outer", the descriptor of the top-level message in which + // "descriptor" is embedded. + const Descriptor* outer = descriptor; + while (outer->containing_type() != NULL) outer = outer->containing_type(); + + const string& outer_name = outer->full_name(); + string inner_name = descriptor->full_name().substr(outer_name.size()); + + if (qualified) { + return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name); + } else { + return outer->name() + DotsToUnderscores(inner_name); + } +} + +string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) { + if (enum_descriptor->containing_type() == NULL) { + if (qualified) { + return "::" + DotsToColons(enum_descriptor->full_name()); + } else { + return enum_descriptor->name(); + } + } else { + string result = ClassName(enum_descriptor->containing_type(), qualified); + result += '_'; + result += enum_descriptor->name(); + return result; + } +} + + +string SuperClassName(const Descriptor* descriptor) { + return HasDescriptorMethods(descriptor->file()) ? + "::google::protobuf::Message" : "::google::protobuf::MessageLite"; +} + +string FieldName(const FieldDescriptor* field) { + string result = field->name(); + LowerString(&result); + if (kKeywords.count(result) > 0) { + result.append("_"); + } + return result; +} + +string FieldConstantName(const FieldDescriptor *field) { + string field_name = UnderscoresToCamelCase(field->name(), true); + string result = "k" + field_name + "FieldNumber"; + + if (!field->is_extension() && + field->containing_type()->FindFieldByCamelcaseName( + field->camelcase_name()) != field) { + // This field's camelcase name is not unique. As a hack, add the field + // number to the constant name. This makes the constant rather useless, + // but what can we do? + result += "_" + SimpleItoa(field->number()); + } + + return result; +} + +string FieldMessageTypeName(const FieldDescriptor* field) { + // Note: The Google-internal version of Protocol Buffers uses this function + // as a hook point for hacks to support legacy code. + return ClassName(field->message_type(), true); +} + +string StripProto(const string& filename) { + if (HasSuffixString(filename, ".protodevel")) { + return StripSuffixString(filename, ".protodevel"); + } else { + return StripSuffixString(filename, ".proto"); + } +} + +const char* PrimitiveTypeName(FieldDescriptor::CppType type) { + switch (type) { + case FieldDescriptor::CPPTYPE_INT32 : return "::google::protobuf::int32"; + case FieldDescriptor::CPPTYPE_INT64 : return "::google::protobuf::int64"; + case FieldDescriptor::CPPTYPE_UINT32 : return "::google::protobuf::uint32"; + case FieldDescriptor::CPPTYPE_UINT64 : return "::google::protobuf::uint64"; + case FieldDescriptor::CPPTYPE_DOUBLE : return "double"; + case FieldDescriptor::CPPTYPE_FLOAT : return "float"; + case FieldDescriptor::CPPTYPE_BOOL : return "bool"; + case FieldDescriptor::CPPTYPE_ENUM : return "int"; + case FieldDescriptor::CPPTYPE_STRING : return "::std::string"; + case FieldDescriptor::CPPTYPE_MESSAGE: return NULL; + + // No default because we want the compiler to complain if any new + // CppTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +const char* DeclaredTypeMethodName(FieldDescriptor::Type type) { + switch (type) { + case FieldDescriptor::TYPE_INT32 : return "Int32"; + case FieldDescriptor::TYPE_INT64 : return "Int64"; + case FieldDescriptor::TYPE_UINT32 : return "UInt32"; + case FieldDescriptor::TYPE_UINT64 : return "UInt64"; + case FieldDescriptor::TYPE_SINT32 : return "SInt32"; + case FieldDescriptor::TYPE_SINT64 : return "SInt64"; + case FieldDescriptor::TYPE_FIXED32 : return "Fixed32"; + case FieldDescriptor::TYPE_FIXED64 : return "Fixed64"; + case FieldDescriptor::TYPE_SFIXED32: return "SFixed32"; + case FieldDescriptor::TYPE_SFIXED64: return "SFixed64"; + case FieldDescriptor::TYPE_FLOAT : return "Float"; + case FieldDescriptor::TYPE_DOUBLE : return "Double"; + + case FieldDescriptor::TYPE_BOOL : return "Bool"; + case FieldDescriptor::TYPE_ENUM : return "Enum"; + + case FieldDescriptor::TYPE_STRING : return "String"; + case FieldDescriptor::TYPE_BYTES : return "Bytes"; + case FieldDescriptor::TYPE_GROUP : return "Group"; + case FieldDescriptor::TYPE_MESSAGE : return "Message"; + + // No default because we want the compiler to complain if any new + // types are added. + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return ""; +} + +string DefaultValue(const FieldDescriptor* field) { + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + // gcc rejects the decimal form of kint32min and kint64min. + if (field->default_value_int32() == kint32min) { + // Make sure we are in a 2's complement system. + GOOGLE_COMPILE_ASSERT(kint32min == -0x80000000, kint32min_value_error); + return "-0x80000000"; + } + return SimpleItoa(field->default_value_int32()); + case FieldDescriptor::CPPTYPE_UINT32: + return SimpleItoa(field->default_value_uint32()) + "u"; + case FieldDescriptor::CPPTYPE_INT64: + // See the comments for CPPTYPE_INT32. + if (field->default_value_int64() == kint64min) { + // Make sure we are in a 2's complement system. + GOOGLE_COMPILE_ASSERT(kint64min == GOOGLE_LONGLONG(-0x8000000000000000), + kint64min_value_error); + return "GOOGLE_LONGLONG(-0x8000000000000000)"; + } + return "GOOGLE_LONGLONG(" + SimpleItoa(field->default_value_int64()) + ")"; + case FieldDescriptor::CPPTYPE_UINT64: + return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")"; + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value = field->default_value_double(); + if (value == numeric_limits::infinity()) { + return "::google::protobuf::internal::Infinity()"; + } else if (value == -numeric_limits::infinity()) { + return "-::google::protobuf::internal::Infinity()"; + } else if (value != value) { + return "::google::protobuf::internal::NaN()"; + } else { + return SimpleDtoa(value); + } + } + case FieldDescriptor::CPPTYPE_FLOAT: + { + float value = field->default_value_float(); + if (value == numeric_limits::infinity()) { + return "static_cast(::google::protobuf::internal::Infinity())"; + } else if (value == -numeric_limits::infinity()) { + return "static_cast(-::google::protobuf::internal::Infinity())"; + } else if (value != value) { + return "static_cast(::google::protobuf::internal::NaN())"; + } else { + string float_value = SimpleFtoa(value); + // If floating point value contains a period (.) or an exponent + // (either E or e), then append suffix 'f' to make it a float + // literal. + if (float_value.find_first_of(".eE") != string::npos) { + float_value.push_back('f'); + } + return float_value; + } + } + case FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool() ? "true" : "false"; + case FieldDescriptor::CPPTYPE_ENUM: + // Lazy: Generate a static_cast because we don't have a helper function + // that constructs the full name of an enum value. + return strings::Substitute( + "static_cast< $0 >($1)", + ClassName(field->enum_type(), true), + field->default_value_enum()->number()); + case FieldDescriptor::CPPTYPE_STRING: + return "\"" + EscapeTrigraphs( + CEscape(field->default_value_string())) + + "\""; + case FieldDescriptor::CPPTYPE_MESSAGE: + return FieldMessageTypeName(field) + "::default_instance()"; + } + // Can't actually get here; make compiler happy. (We could add a default + // case above but then we wouldn't get the nice compiler warning when a + // new type is added.) + GOOGLE_LOG(FATAL) << "Can't get here."; + return ""; +} + +// Convert a file name into a valid identifier. +string FilenameIdentifier(const string& filename) { + string result; + for (int i = 0; i < filename.size(); i++) { + if (ascii_isalnum(filename[i])) { + result.push_back(filename[i]); + } else { + // Not alphanumeric. To avoid any possibility of name conflicts we + // use the hex code for the character. + result.push_back('_'); + char buffer[kFastToBufferSize]; + result.append(FastHexToBuffer(static_cast(filename[i]), buffer)); + } + } + return result; +} + +// Return the name of the AddDescriptors() function for a given file. +string GlobalAddDescriptorsName(const string& filename) { + return "protobuf_AddDesc_" + FilenameIdentifier(filename); +} + +// Return the name of the AssignDescriptors() function for a given file. +string GlobalAssignDescriptorsName(const string& filename) { + return "protobuf_AssignDesc_" + FilenameIdentifier(filename); +} + +// Return the name of the ShutdownFile() function for a given file. +string GlobalShutdownFileName(const string& filename) { + return "protobuf_ShutdownFile_" + FilenameIdentifier(filename); +} + +// Escape C++ trigraphs by escaping question marks to \? +string EscapeTrigraphs(const string& to_escape) { + return StringReplace(to_escape, "?", "\\?", true); +} + +bool StaticInitializersForced(const FileDescriptor* file) { + if (HasDescriptorMethods(file) || file->extension_count() > 0) { + return true; + } + for (int i = 0; i < file->message_type_count(); ++i) { + if (HasExtension(file->message_type(i))) { + return true; + } + } + return false; +} + +void PrintHandlingOptionalStaticInitializers( + const FileDescriptor* file, io::Printer* printer, + const char* with_static_init, const char* without_static_init, + const char* var1, const string& val1, + const char* var2, const string& val2) { + map vars; + if (var1) { + vars[var1] = val1; + } + if (var2) { + vars[var2] = val2; + } + PrintHandlingOptionalStaticInitializers( + vars, file, printer, with_static_init, without_static_init); +} + +void PrintHandlingOptionalStaticInitializers( + const map& vars, const FileDescriptor* file, + io::Printer* printer, const char* with_static_init, + const char* without_static_init) { + if (StaticInitializersForced(file)) { + printer->Print(vars, with_static_init); + } else { + printer->Print(vars, (string( + "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n") + + without_static_init + + "#else\n" + + with_static_init + + "#endif\n").c_str()); + } +} + + +static bool HasEnumDefinitions(const Descriptor* message_type) { + if (message_type->enum_type_count() > 0) return true; + for (int i = 0; i < message_type->nested_type_count(); ++i) { + if (HasEnumDefinitions(message_type->nested_type(i))) return true; + } + return false; +} + +bool HasEnumDefinitions(const FileDescriptor* file) { + if (file->enum_type_count() > 0) return true; + for (int i = 0; i < file->message_type_count(); ++i) { + if (HasEnumDefinitions(file->message_type(i))) return true; + } + return false; +} + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_helpers.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_helpers.h new file mode 100644 index 0000000..526e19c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -0,0 +1,186 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ + +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +namespace io { +class Printer; +} + +namespace compiler { +namespace cpp { + +// Commonly-used separator comments. Thick is a line of '=', thin is a line +// of '-'. +extern const char kThickSeparator[]; +extern const char kThinSeparator[]; + +// Returns the non-nested type name for the given type. If "qualified" is +// true, prefix the type with the full namespace. For example, if you had: +// package foo.bar; +// message Baz { message Qux {} } +// Then the qualified ClassName for Qux would be: +// ::foo::bar::Baz_Qux +// While the non-qualified version would be: +// Baz_Qux +string ClassName(const Descriptor* descriptor, bool qualified); +string ClassName(const EnumDescriptor* enum_descriptor, bool qualified); + +string SuperClassName(const Descriptor* descriptor); + +// Get the (unqualified) name that should be used for this field in C++ code. +// The name is coerced to lower-case to emulate proto1 behavior. People +// should be using lowercase-with-underscores style for proto field names +// anyway, so normally this just returns field->name(). +string FieldName(const FieldDescriptor* field); + +// Get the unqualified name that should be used for a field's field +// number constant. +string FieldConstantName(const FieldDescriptor *field); + +// Returns the scope where the field was defined (for extensions, this is +// different from the message type to which the field applies). +inline const Descriptor* FieldScope(const FieldDescriptor* field) { + return field->is_extension() ? + field->extension_scope() : field->containing_type(); +} + +// Returns the fully-qualified type name field->message_type(). Usually this +// is just ClassName(field->message_type(), true); +string FieldMessageTypeName(const FieldDescriptor* field); + +// Strips ".proto" or ".protodevel" from the end of a filename. +string StripProto(const string& filename); + +// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.). +// Note: non-built-in type names will be qualified, meaning they will start +// with a ::. If you are using the type as a template parameter, you will +// need to insure there is a space between the < and the ::, because the +// ridiculous C++ standard defines "<:" to be a synonym for "[". +const char* PrimitiveTypeName(FieldDescriptor::CppType type); + +// Get the declared type name in CamelCase format, as is used e.g. for the +// methods of WireFormat. For example, TYPE_INT32 becomes "Int32". +const char* DeclaredTypeMethodName(FieldDescriptor::Type type); + +// Get code that evaluates to the field's default value. +string DefaultValue(const FieldDescriptor* field); + +// Convert a file name into a valid identifier. +string FilenameIdentifier(const string& filename); + +// Return the name of the AddDescriptors() function for a given file. +string GlobalAddDescriptorsName(const string& filename); + +// Return the name of the AssignDescriptors() function for a given file. +string GlobalAssignDescriptorsName(const string& filename); + +// Return the name of the ShutdownFile() function for a given file. +string GlobalShutdownFileName(const string& filename); + +// Escape C++ trigraphs by escaping question marks to \? +string EscapeTrigraphs(const string& to_escape); + +// Do message classes in this file keep track of unknown fields? +inline bool HasUnknownFields(const FileDescriptor* file) { + return file->options().optimize_for() != FileOptions::LITE_RUNTIME; +} + + +// Does this file have any enum type definitions? +bool HasEnumDefinitions(const FileDescriptor* file); + +// Does this file have generated parsing, serialization, and other +// standard methods for which reflection-based fallback implementations exist? +inline bool HasGeneratedMethods(const FileDescriptor* file) { + return file->options().optimize_for() != FileOptions::CODE_SIZE; +} + +// Do message classes in this file have descriptor and reflection methods? +inline bool HasDescriptorMethods(const FileDescriptor* file) { + return file->options().optimize_for() != FileOptions::LITE_RUNTIME; +} + +// Should we generate generic services for this file? +inline bool HasGenericServices(const FileDescriptor* file) { + return file->service_count() > 0 && + file->options().optimize_for() != FileOptions::LITE_RUNTIME && + file->options().cc_generic_services(); +} + +// Should string fields in this file verify that their contents are UTF-8? +inline bool HasUtf8Verification(const FileDescriptor* file) { + return file->options().optimize_for() != FileOptions::LITE_RUNTIME; +} + +// Should we generate a separate, super-optimized code path for serializing to +// flat arrays? We don't do this in Lite mode because we'd rather reduce code +// size. +inline bool HasFastArraySerialization(const FileDescriptor* file) { + return file->options().optimize_for() == FileOptions::SPEED; +} + +// Returns whether we have to generate code with static initializers. +bool StaticInitializersForced(const FileDescriptor* file); + +// Prints 'with_static_init' if static initializers have to be used for the +// provided file. Otherwise emits both 'with_static_init' and +// 'without_static_init' using #ifdef. +void PrintHandlingOptionalStaticInitializers( + const FileDescriptor* file, io::Printer* printer, + const char* with_static_init, const char* without_static_init, + const char* var1 = NULL, const string& val1 = "", + const char* var2 = NULL, const string& val2 = ""); + +void PrintHandlingOptionalStaticInitializers( + const map& vars, const FileDescriptor* file, + io::Printer* printer, const char* with_static_init, + const char* without_static_init); + + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message.cc new file mode 100644 index 0000000..1ea4f13 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -0,0 +1,2020 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { + +void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { + // Print the field's proto-syntax definition as a comment. We don't want to + // print group bodies so we cut off after the first line. + string def = field->DebugString(); + printer->Print("// $def$\n", + "def", def.substr(0, def.find_first_of('\n'))); +} + +struct FieldOrderingByNumber { + inline bool operator()(const FieldDescriptor* a, + const FieldDescriptor* b) const { + return a->number() < b->number(); + } +}; + +const char* kWireTypeNames[] = { + "VARINT", + "FIXED64", + "LENGTH_DELIMITED", + "START_GROUP", + "END_GROUP", + "FIXED32", +}; + +// Sort the fields of the given Descriptor by number into a new[]'d array +// and return it. +const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { + const FieldDescriptor** fields = + new const FieldDescriptor*[descriptor->field_count()]; + for (int i = 0; i < descriptor->field_count(); i++) { + fields[i] = descriptor->field(i); + } + sort(fields, fields + descriptor->field_count(), + FieldOrderingByNumber()); + return fields; +} + +// Functor for sorting extension ranges by their "start" field number. +struct ExtensionRangeSorter { + bool operator()(const Descriptor::ExtensionRange* left, + const Descriptor::ExtensionRange* right) const { + return left->start < right->start; + } +}; + +// Returns true if the "required" restriction check should be ignored for the +// given field. +inline static bool ShouldIgnoreRequiredFieldCheck( + const FieldDescriptor* field) { + return false; +} + +// Returns true if the message type has any required fields. If it doesn't, +// we can optimize out calls to its IsInitialized() method. +// +// already_seen is used to avoid checking the same type multiple times +// (and also to protect against recursion). +static bool HasRequiredFields( + const Descriptor* type, + hash_set* already_seen) { + if (already_seen->count(type) > 0) { + // Since the first occurrence of a required field causes the whole + // function to return true, we can assume that if the type is already + // in the cache it didn't have any required fields. + return false; + } + already_seen->insert(type); + + // If the type has extensions, an extension with message type could contain + // required fields, so we have to be conservative and assume such an + // extension exists. + if (type->extension_range_count() > 0) return true; + + for (int i = 0; i < type->field_count(); i++) { + const FieldDescriptor* field = type->field(i); + if (field->is_required()) { + return true; + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + !ShouldIgnoreRequiredFieldCheck(field)) { + if (HasRequiredFields(field->message_type(), already_seen)) { + return true; + } + } + } + + return false; +} + +static bool HasRequiredFields(const Descriptor* type) { + hash_set already_seen; + return HasRequiredFields(type, &already_seen); +} + +// This returns an estimate of the compiler's alignment for the field. This +// can't guarantee to be correct because the generated code could be compiled on +// different systems with different alignment rules. The estimates below assume +// 64-bit pointers. +int EstimateAlignmentSize(const FieldDescriptor* field) { + if (field == NULL) return 0; + if (field->is_repeated()) return 8; + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_BOOL: + return 1; + + case FieldDescriptor::CPPTYPE_INT32: + case FieldDescriptor::CPPTYPE_UINT32: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_FLOAT: + return 4; + + case FieldDescriptor::CPPTYPE_INT64: + case FieldDescriptor::CPPTYPE_UINT64: + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + return 8; + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return -1; // Make compiler happy. +} + +// FieldGroup is just a helper for OptimizePadding below. It holds a vector of +// fields that are grouped together because they have compatible alignment, and +// a preferred location in the final field ordering. +class FieldGroup { + public: + FieldGroup() + : preferred_location_(0) {} + + // A group with a single field. + FieldGroup(float preferred_location, const FieldDescriptor* field) + : preferred_location_(preferred_location), + fields_(1, field) {} + + // Append the fields in 'other' to this group. + void Append(const FieldGroup& other) { + if (other.fields_.empty()) { + return; + } + // Preferred location is the average among all the fields, so we weight by + // the number of fields on each FieldGroup object. + preferred_location_ = + (preferred_location_ * fields_.size() + + (other.preferred_location_ * other.fields_.size())) / + (fields_.size() + other.fields_.size()); + fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end()); + } + + void SetPreferredLocation(float location) { preferred_location_ = location; } + const vector& fields() const { return fields_; } + + // FieldGroup objects sort by their preferred location. + bool operator<(const FieldGroup& other) const { + return preferred_location_ < other.preferred_location_; + } + + private: + // "preferred_location_" is an estimate of where this group should go in the + // final list of fields. We compute this by taking the average index of each + // field in this group in the original ordering of fields. This is very + // approximate, but should put this group close to where its member fields + // originally went. + float preferred_location_; + vector fields_; + // We rely on the default copy constructor and operator= so this type can be + // used in a vector. +}; + +// Reorder 'fields' so that if the fields are output into a c++ class in the new +// order, the alignment padding is minimized. We try to do this while keeping +// each field as close as possible to its original position so that we don't +// reduce cache locality much for function that access each field in order. +void OptimizePadding(vector* fields) { + // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes. + vector aligned_to_1, aligned_to_4, aligned_to_8; + for (int i = 0; i < fields->size(); ++i) { + switch (EstimateAlignmentSize((*fields)[i])) { + case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break; + case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break; + case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break; + default: + GOOGLE_LOG(FATAL) << "Unknown alignment size."; + } + } + + // Now group fields aligned to 1 byte into sets of 4, and treat those like a + // single field aligned to 4 bytes. + for (int i = 0; i < aligned_to_1.size(); i += 4) { + FieldGroup field_group; + for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) { + field_group.Append(aligned_to_1[j]); + } + aligned_to_4.push_back(field_group); + } + // Sort by preferred location to keep fields as close to their original + // location as possible. + sort(aligned_to_4.begin(), aligned_to_4.end()); + + // Now group fields aligned to 4 bytes (or the 4-field groups created above) + // into pairs, and treat those like a single field aligned to 8 bytes. + for (int i = 0; i < aligned_to_4.size(); i += 2) { + FieldGroup field_group; + for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) { + field_group.Append(aligned_to_4[j]); + } + if (i == aligned_to_4.size() - 1) { + // Move incomplete 4-byte block to the end. + field_group.SetPreferredLocation(fields->size() + 1); + } + aligned_to_8.push_back(field_group); + } + // Sort by preferred location to keep fields as close to their original + // location as possible. + sort(aligned_to_8.begin(), aligned_to_8.end()); + + // Now pull out all the FieldDescriptors in order. + fields->clear(); + for (int i = 0; i < aligned_to_8.size(); ++i) { + fields->insert(fields->end(), + aligned_to_8[i].fields().begin(), + aligned_to_8[i].fields().end()); + } +} + +} + +// =================================================================== + +MessageGenerator::MessageGenerator(const Descriptor* descriptor, + const Options& options) + : descriptor_(descriptor), + classname_(ClassName(descriptor, false)), + options_(options), + field_generators_(descriptor, options), + nested_generators_(new scoped_ptr[ + descriptor->nested_type_count()]), + enum_generators_(new scoped_ptr[ + descriptor->enum_type_count()]), + extension_generators_(new scoped_ptr[ + descriptor->extension_count()]) { + + for (int i = 0; i < descriptor->nested_type_count(); i++) { + nested_generators_[i].reset( + new MessageGenerator(descriptor->nested_type(i), options)); + } + + for (int i = 0; i < descriptor->enum_type_count(); i++) { + enum_generators_[i].reset( + new EnumGenerator(descriptor->enum_type(i), options)); + } + + for (int i = 0; i < descriptor->extension_count(); i++) { + extension_generators_[i].reset( + new ExtensionGenerator(descriptor->extension(i), options)); + } +} + +MessageGenerator::~MessageGenerator() {} + +void MessageGenerator:: +GenerateForwardDeclaration(io::Printer* printer) { + printer->Print("class $classname$;\n", + "classname", classname_); + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateForwardDeclaration(printer); + } +} + +void MessageGenerator:: +GenerateEnumDefinitions(io::Printer* printer) { + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateEnumDefinitions(printer); + } + + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + enum_generators_[i]->GenerateDefinition(printer); + } +} + +void MessageGenerator:: +GenerateGetEnumDescriptorSpecializations(io::Printer* printer) { + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); + } + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); + } +} + +void MessageGenerator:: +GenerateFieldAccessorDeclarations(io::Printer* printer) { + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + PrintFieldComment(printer, field); + + map vars; + SetCommonFieldVariables(field, &vars, options_); + vars["constant_name"] = FieldConstantName(field); + + if (field->is_repeated()) { + printer->Print(vars, "inline int $name$_size() const$deprecation$;\n"); + } else { + printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n"); + } + + printer->Print(vars, "inline void clear_$name$()$deprecation$;\n"); + printer->Print(vars, "static const int $constant_name$ = $number$;\n"); + + // Generate type-specific accessor declarations. + field_generators_.get(field).GenerateAccessorDeclarations(printer); + + printer->Print("\n"); + } + + if (descriptor_->extension_range_count() > 0) { + // Generate accessors for extensions. We just call a macro located in + // extension_set.h since the accessors about 80 lines of static code. + printer->Print( + "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n", + "classname", classname_); + } +} + +void MessageGenerator:: +GenerateFieldAccessorDefinitions(io::Printer* printer) { + printer->Print("// $classname$\n\n", "classname", classname_); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + PrintFieldComment(printer, field); + + map vars; + SetCommonFieldVariables(field, &vars, options_); + + // Generate has_$name$() or $name$_size(). + if (field->is_repeated()) { + printer->Print(vars, + "inline int $classname$::$name$_size() const {\n" + " return $name$_.size();\n" + "}\n"); + } else { + // Singular field. + char buffer[kFastToBufferSize]; + vars["has_array_index"] = SimpleItoa(field->index() / 32); + vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer); + printer->Print(vars, + "inline bool $classname$::has_$name$() const {\n" + " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n" + "}\n" + "inline void $classname$::set_has_$name$() {\n" + " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n" + "}\n" + "inline void $classname$::clear_has_$name$() {\n" + " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n" + "}\n" + ); + } + + // Generate clear_$name$() + printer->Print(vars, + "inline void $classname$::clear_$name$() {\n"); + + printer->Indent(); + field_generators_.get(field).GenerateClearingCode(printer); + printer->Outdent(); + + if (!field->is_repeated()) { + printer->Print(vars, + " clear_has_$name$();\n"); + } + + printer->Print("}\n"); + + // Generate type-specific accessors. + field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); + + printer->Print("\n"); + } +} + +void MessageGenerator:: +GenerateClassDefinition(io::Printer* printer) { + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateClassDefinition(printer); + printer->Print("\n"); + printer->Print(kThinSeparator); + printer->Print("\n"); + } + + map vars; + vars["classname"] = classname_; + vars["field_count"] = SimpleItoa(descriptor_->field_count()); + if (options_.dllexport_decl.empty()) { + vars["dllexport"] = ""; + } else { + vars["dllexport"] = options_.dllexport_decl + " "; + } + vars["superclass"] = SuperClassName(descriptor_); + + printer->Print(vars, + "class $dllexport$$classname$ : public $superclass$ {\n" + " public:\n"); + printer->Indent(); + + printer->Print(vars, + "$classname$();\n" + "virtual ~$classname$();\n" + "\n" + "$classname$(const $classname$& from);\n" + "\n" + "inline $classname$& operator=(const $classname$& from) {\n" + " CopyFrom(from);\n" + " return *this;\n" + "}\n" + "\n"); + + if (HasUnknownFields(descriptor_->file())) { + printer->Print( + "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n" + " return _unknown_fields_;\n" + "}\n" + "\n" + "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n" + " return &_unknown_fields_;\n" + "}\n" + "\n"); + } + + // Only generate this member if it's not disabled. + if (HasDescriptorMethods(descriptor_->file()) && + !descriptor_->options().no_standard_descriptor_accessor()) { + printer->Print(vars, + "static const ::google::protobuf::Descriptor* descriptor();\n"); + } + + printer->Print(vars, + "static const $classname$& default_instance();\n" + "\n"); + + if (!StaticInitializersForced(descriptor_->file())) { + printer->Print(vars, + "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n" + "// Returns the internal default instance pointer. This function can\n" + "// return NULL thus should not be used by the user. This is intended\n" + "// for Protobuf internal code. Please use default_instance() declared\n" + "// above instead.\n" + "static inline const $classname$* internal_default_instance() {\n" + " return default_instance_;\n" + "}\n" + "#endif\n" + "\n"); + } + + + printer->Print(vars, + "void Swap($classname$* other);\n" + "\n" + "// implements Message ----------------------------------------------\n" + "\n" + "$classname$* New() const;\n"); + + if (HasGeneratedMethods(descriptor_->file())) { + if (HasDescriptorMethods(descriptor_->file())) { + printer->Print(vars, + "void CopyFrom(const ::google::protobuf::Message& from);\n" + "void MergeFrom(const ::google::protobuf::Message& from);\n"); + } else { + printer->Print(vars, + "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n"); + } + + printer->Print(vars, + "void CopyFrom(const $classname$& from);\n" + "void MergeFrom(const $classname$& from);\n" + "void Clear();\n" + "bool IsInitialized() const;\n" + "\n" + "int ByteSize() const;\n" + "bool MergePartialFromCodedStream(\n" + " ::google::protobuf::io::CodedInputStream* input);\n" + "void SerializeWithCachedSizes(\n" + " ::google::protobuf::io::CodedOutputStream* output) const;\n"); + if (HasFastArraySerialization(descriptor_->file())) { + printer->Print( + "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n"); + } + } + + printer->Print(vars, + "int GetCachedSize() const { return _cached_size_; }\n" + "private:\n" + "void SharedCtor();\n" + "void SharedDtor();\n" + "void SetCachedSize(int size) const;\n" + "public:\n" + "\n"); + + if (HasDescriptorMethods(descriptor_->file())) { + printer->Print( + "::google::protobuf::Metadata GetMetadata() const;\n" + "\n"); + } else { + printer->Print( + "::std::string GetTypeName() const;\n" + "\n"); + } + + printer->Print( + "// nested types ----------------------------------------------------\n" + "\n"); + + // Import all nested message classes into this class's scope with typedefs. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + const Descriptor* nested_type = descriptor_->nested_type(i); + printer->Print("typedef $nested_full_name$ $nested_name$;\n", + "nested_name", nested_type->name(), + "nested_full_name", ClassName(nested_type, false)); + } + + if (descriptor_->nested_type_count() > 0) { + printer->Print("\n"); + } + + // Import all nested enums and their values into this class's scope with + // typedefs and constants. + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + enum_generators_[i]->GenerateSymbolImports(printer); + printer->Print("\n"); + } + + printer->Print( + "// accessors -------------------------------------------------------\n" + "\n"); + + // Generate accessor methods for all fields. + GenerateFieldAccessorDeclarations(printer); + + // Declare extension identifiers. + for (int i = 0; i < descriptor_->extension_count(); i++) { + extension_generators_[i]->GenerateDeclaration(printer); + } + + + printer->Print( + "// @@protoc_insertion_point(class_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + + // Generate private members. + printer->Outdent(); + printer->Print(" private:\n"); + printer->Indent(); + + + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!descriptor_->field(i)->is_repeated()) { + printer->Print( + "inline void set_has_$name$();\n", + "name", FieldName(descriptor_->field(i))); + printer->Print( + "inline void clear_has_$name$();\n", + "name", FieldName(descriptor_->field(i))); + } + } + printer->Print("\n"); + + // To minimize padding, data members are divided into three sections: + // (1) members assumed to align to 8 bytes + // (2) members corresponding to message fields, re-ordered to optimize + // alignment. + // (3) members assumed to align to 4 bytes. + + // Members assumed to align to 8 bytes: + + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "::google::protobuf::internal::ExtensionSet _extensions_;\n" + "\n"); + } + + if (HasUnknownFields(descriptor_->file())) { + printer->Print( + "::google::protobuf::UnknownFieldSet _unknown_fields_;\n" + "\n"); + } + + // Field members: + + vector fields; + for (int i = 0; i < descriptor_->field_count(); i++) { + fields.push_back(descriptor_->field(i)); + } + OptimizePadding(&fields); + for (int i = 0; i < fields.size(); ++i) { + field_generators_.get(fields[i]).GeneratePrivateMembers(printer); + } + + // Members assumed to align to 4 bytes: + + // TODO(kenton): Make _cached_size_ an atomic when C++ supports it. + printer->Print( + "\n" + "mutable int _cached_size_;\n"); + + // Generate _has_bits_. + if (descriptor_->field_count() > 0) { + printer->Print(vars, + "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n" + "\n"); + } else { + // Zero-size arrays aren't technically allowed, and MSVC in particular + // doesn't like them. We still need to declare these arrays to make + // other code compile. Since this is an uncommon case, we'll just declare + // them with size 1 and waste some space. Oh well. + printer->Print( + "::google::protobuf::uint32 _has_bits_[1];\n" + "\n"); + } + + // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as + // friends so that they can access private static variables like + // default_instance_ and reflection_. + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. + "friend void $dllexport_decl$ $adddescriptorsname$();\n", + // Without. + "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n", + // Vars. + "dllexport_decl", options_.dllexport_decl, + "adddescriptorsname", + GlobalAddDescriptorsName(descriptor_->file()->name())); + + printer->Print( + "friend void $assigndescriptorsname$();\n" + "friend void $shutdownfilename$();\n" + "\n", + "assigndescriptorsname", + GlobalAssignDescriptorsName(descriptor_->file()->name()), + "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name())); + + printer->Print( + "void InitAsDefaultInstance();\n" + "static $classname$* default_instance_;\n", + "classname", classname_); + + printer->Outdent(); + printer->Print(vars, "};"); +} + +void MessageGenerator:: +GenerateInlineMethods(io::Printer* printer) { + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateInlineMethods(printer); + printer->Print(kThinSeparator); + printer->Print("\n"); + } + + GenerateFieldAccessorDefinitions(printer); +} + +void MessageGenerator:: +GenerateDescriptorDeclarations(io::Printer* printer) { + printer->Print( + "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n" + "const ::google::protobuf::internal::GeneratedMessageReflection*\n" + " $name$_reflection_ = NULL;\n", + "name", classname_); + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateDescriptorDeclarations(printer); + } + + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + printer->Print( + "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", + "name", ClassName(descriptor_->enum_type(i), false)); + } +} + +void MessageGenerator:: +GenerateDescriptorInitializer(io::Printer* printer, int index) { + // TODO(kenton): Passing the index to this method is redundant; just use + // descriptor_->index() instead. + map vars; + vars["classname"] = classname_; + vars["index"] = SimpleItoa(index); + + // Obtain the descriptor from the parent's descriptor. + if (descriptor_->containing_type() == NULL) { + printer->Print(vars, + "$classname$_descriptor_ = file->message_type($index$);\n"); + } else { + vars["parent"] = ClassName(descriptor_->containing_type(), false); + printer->Print(vars, + "$classname$_descriptor_ = " + "$parent$_descriptor_->nested_type($index$);\n"); + } + + // Generate the offsets. + GenerateOffsets(printer); + + // Construct the reflection object. + printer->Print(vars, + "$classname$_reflection_ =\n" + " new ::google::protobuf::internal::GeneratedMessageReflection(\n" + " $classname$_descriptor_,\n" + " $classname$::default_instance_,\n" + " $classname$_offsets_,\n" + " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n" + " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" + "$classname$, _unknown_fields_),\n"); + if (descriptor_->extension_range_count() > 0) { + printer->Print(vars, + " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" + "$classname$, _extensions_),\n"); + } else { + // No extensions. + printer->Print(vars, + " -1,\n"); + } + printer->Print( + " ::google::protobuf::DescriptorPool::generated_pool(),\n"); + printer->Print(vars, + " ::google::protobuf::MessageFactory::generated_factory(),\n"); + printer->Print(vars, + " sizeof($classname$));\n"); + + // Handle nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateDescriptorInitializer(printer, i); + } + + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + enum_generators_[i]->GenerateDescriptorInitializer(printer, i); + } +} + +void MessageGenerator:: +GenerateTypeRegistrations(io::Printer* printer) { + // Register this message type with the message factory. + printer->Print( + "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n" + " $classname$_descriptor_, &$classname$::default_instance());\n", + "classname", classname_); + + // Handle nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateTypeRegistrations(printer); + } +} + +void MessageGenerator:: +GenerateDefaultInstanceAllocator(io::Printer* printer) { + // Construct the default instances of all fields, as they will be used + // when creating the default instance of the entire message. + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateDefaultInstanceAllocator(printer); + } + + // Construct the default instance. We can't call InitAsDefaultInstance() yet + // because we need to make sure all default instances that this one might + // depend on are constructed first. + printer->Print( + "$classname$::default_instance_ = new $classname$();\n", + "classname", classname_); + + // Handle nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateDefaultInstanceAllocator(printer); + } + +} + +void MessageGenerator:: +GenerateDefaultInstanceInitializer(io::Printer* printer) { + printer->Print( + "$classname$::default_instance_->InitAsDefaultInstance();\n", + "classname", classname_); + + // Register extensions. + for (int i = 0; i < descriptor_->extension_count(); i++) { + extension_generators_[i]->GenerateRegistration(printer); + } + + // Handle nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateDefaultInstanceInitializer(printer); + } +} + +void MessageGenerator:: +GenerateShutdownCode(io::Printer* printer) { + printer->Print( + "delete $classname$::default_instance_;\n", + "classname", classname_); + + if (HasDescriptorMethods(descriptor_->file())) { + printer->Print( + "delete $classname$_reflection_;\n", + "classname", classname_); + } + + // Handle default instances of fields. + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateShutdownCode(printer); + } + + // Handle nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateShutdownCode(printer); + } +} + +void MessageGenerator:: +GenerateClassMethods(io::Printer* printer) { + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + enum_generators_[i]->GenerateMethods(printer); + } + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateClassMethods(printer); + printer->Print("\n"); + printer->Print(kThinSeparator); + printer->Print("\n"); + } + + // Generate non-inline field definitions. + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateNonInlineAccessorDefinitions(printer); + } + + // Generate field number constants. + printer->Print("#ifndef _MSC_VER\n"); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor *field = descriptor_->field(i); + printer->Print( + "const int $classname$::$constant_name$;\n", + "classname", ClassName(FieldScope(field), false), + "constant_name", FieldConstantName(field)); + } + printer->Print( + "#endif // !_MSC_VER\n" + "\n"); + + // Define extension identifiers. + for (int i = 0; i < descriptor_->extension_count(); i++) { + extension_generators_[i]->GenerateDefinition(printer); + } + + GenerateStructors(printer); + printer->Print("\n"); + + if (HasGeneratedMethods(descriptor_->file())) { + GenerateClear(printer); + printer->Print("\n"); + + GenerateMergeFromCodedStream(printer); + printer->Print("\n"); + + GenerateSerializeWithCachedSizes(printer); + printer->Print("\n"); + + if (HasFastArraySerialization(descriptor_->file())) { + GenerateSerializeWithCachedSizesToArray(printer); + printer->Print("\n"); + } + + GenerateByteSize(printer); + printer->Print("\n"); + + GenerateMergeFrom(printer); + printer->Print("\n"); + + GenerateCopyFrom(printer); + printer->Print("\n"); + + GenerateIsInitialized(printer); + printer->Print("\n"); + } + + GenerateSwap(printer); + printer->Print("\n"); + + if (HasDescriptorMethods(descriptor_->file())) { + printer->Print( + "::google::protobuf::Metadata $classname$::GetMetadata() const {\n" + " protobuf_AssignDescriptorsOnce();\n" + " ::google::protobuf::Metadata metadata;\n" + " metadata.descriptor = $classname$_descriptor_;\n" + " metadata.reflection = $classname$_reflection_;\n" + " return metadata;\n" + "}\n" + "\n", + "classname", classname_); + } else { + printer->Print( + "::std::string $classname$::GetTypeName() const {\n" + " return \"$type_name$\";\n" + "}\n" + "\n", + "classname", classname_, + "type_name", descriptor_->full_name()); + } + +} + +void MessageGenerator:: +GenerateOffsets(io::Printer* printer) { + printer->Print( + "static const int $classname$_offsets_[$field_count$] = {\n", + "classname", classname_, + "field_count", SimpleItoa(max(1, descriptor_->field_count()))); + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + printer->Print( + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n", + "classname", classname_, + "name", FieldName(field)); + } + + printer->Outdent(); + printer->Print("};\n"); +} + +void MessageGenerator:: +GenerateSharedConstructorCode(io::Printer* printer) { + printer->Print( + "void $classname$::SharedCtor() {\n", + "classname", classname_); + printer->Indent(); + + printer->Print( + "_cached_size_ = 0;\n"); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateConstructorCode(printer); + } + + printer->Print( + "::memset(_has_bits_, 0, sizeof(_has_bits_));\n"); + + printer->Outdent(); + printer->Print("}\n\n"); +} + +void MessageGenerator:: +GenerateSharedDestructorCode(io::Printer* printer) { + printer->Print( + "void $classname$::SharedDtor() {\n", + "classname", classname_); + printer->Indent(); + // Write the destructors for each field. + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateDestructorCode(printer); + } + + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. + "if (this != default_instance_) {\n", + // Without. + "if (this != &default_instance()) {\n"); + + // We need to delete all embedded messages. + // TODO(kenton): If we make unset messages point at default instances + // instead of NULL, then it would make sense to move this code into + // MessageFieldGenerator::GenerateDestructorCode(). + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + if (!field->is_repeated() && + field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer->Print(" delete $name$_;\n", + "name", FieldName(field)); + } + } + + printer->Outdent(); + printer->Print( + " }\n" + "}\n" + "\n"); +} + +void MessageGenerator:: +GenerateStructors(io::Printer* printer) { + string superclass = SuperClassName(descriptor_); + + // Generate the default constructor. + printer->Print( + "$classname$::$classname$()\n" + " : $superclass$() {\n" + " SharedCtor();\n" + "}\n", + "classname", classname_, + "superclass", superclass); + + printer->Print( + "\n" + "void $classname$::InitAsDefaultInstance() {\n", + "classname", classname_); + + // The default instance needs all of its embedded message pointers + // cross-linked to other default instances. We can't do this initialization + // in the constructor because some other default instances may not have been + // constructed yet at that time. + // TODO(kenton): Maybe all message fields (even for non-default messages) + // should be initialized to point at default instances rather than NULL? + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + if (!field->is_repeated() && + field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. + " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n", + // Without. + " $name$_ = const_cast< $type$*>(\n" + " $type$::internal_default_instance());\n", + // Vars. + "name", FieldName(field), + "type", FieldMessageTypeName(field)); + } + } + printer->Print( + "}\n" + "\n"); + + // Generate the copy constructor. + printer->Print( + "$classname$::$classname$(const $classname$& from)\n" + " : $superclass$() {\n" + " SharedCtor();\n" + " MergeFrom(from);\n" + "}\n" + "\n", + "classname", classname_, + "superclass", superclass); + + // Generate the shared constructor code. + GenerateSharedConstructorCode(printer); + + // Generate the destructor. + printer->Print( + "$classname$::~$classname$() {\n" + " SharedDtor();\n" + "}\n" + "\n", + "classname", classname_); + + // Generate the shared destructor code. + GenerateSharedDestructorCode(printer); + + // Generate SetCachedSize. + printer->Print( + "void $classname$::SetCachedSize(int size) const {\n" + " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" + " _cached_size_ = size;\n" + " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" + "}\n", + "classname", classname_); + + // Only generate this member if it's not disabled. + if (HasDescriptorMethods(descriptor_->file()) && + !descriptor_->options().no_standard_descriptor_accessor()) { + printer->Print( + "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n" + " protobuf_AssignDescriptorsOnce();\n" + " return $classname$_descriptor_;\n" + "}\n" + "\n", + "classname", classname_, + "adddescriptorsname", + GlobalAddDescriptorsName(descriptor_->file()->name())); + } + + printer->Print( + "const $classname$& $classname$::default_instance() {\n", + "classname", classname_); + + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. + " if (default_instance_ == NULL) $adddescriptorsname$();\n", + // Without. + " $adddescriptorsname$();\n", + // Vars. + "adddescriptorsname", + GlobalAddDescriptorsName(descriptor_->file()->name())); + + printer->Print( + " return *default_instance_;\n" + "}\n" + "\n" + "$classname$* $classname$::default_instance_ = NULL;\n" + "\n" + "$classname$* $classname$::New() const {\n" + " return new $classname$;\n" + "}\n", + "classname", classname_, + "adddescriptorsname", + GlobalAddDescriptorsName(descriptor_->file()->name())); +} + +void MessageGenerator:: +GenerateClear(io::Printer* printer) { + printer->Print("void $classname$::Clear() {\n", + "classname", classname_); + printer->Indent(); + + int last_index = -1; + + if (descriptor_->extension_range_count() > 0) { + printer->Print("_extensions_.Clear();\n"); + } + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + if (!field->is_repeated()) { + // We can use the fact that _has_bits_ is a giant bitfield to our + // advantage: We can check up to 32 bits at a time for equality to + // zero, and skip the whole range if so. This can improve the speed + // of Clear() for messages which contain a very large number of + // optional fields of which only a few are used at a time. Here, + // we've chosen to check 8 bits at a time rather than 32. + if (i / 8 != last_index / 8 || last_index < 0) { + if (last_index >= 0) { + printer->Outdent(); + printer->Print("}\n"); + } + printer->Print( + "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", + "index", SimpleItoa(field->index())); + printer->Indent(); + } + last_index = i; + + // It's faster to just overwrite primitive types, but we should + // only clear strings and messages if they were set. + // TODO(kenton): Let the CppFieldGenerator decide this somehow. + bool should_check_bit = + field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || + field->cpp_type() == FieldDescriptor::CPPTYPE_STRING; + + if (should_check_bit) { + printer->Print( + "if (has_$name$()) {\n", + "name", FieldName(field)); + printer->Indent(); + } + + field_generators_.get(field).GenerateClearingCode(printer); + + if (should_check_bit) { + printer->Outdent(); + printer->Print("}\n"); + } + } + } + + if (last_index >= 0) { + printer->Outdent(); + printer->Print("}\n"); + } + + // Repeated fields don't use _has_bits_ so we clear them in a separate + // pass. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + if (field->is_repeated()) { + field_generators_.get(field).GenerateClearingCode(printer); + } + } + + printer->Print( + "::memset(_has_bits_, 0, sizeof(_has_bits_));\n"); + + if (HasUnknownFields(descriptor_->file())) { + printer->Print( + "mutable_unknown_fields()->Clear();\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void MessageGenerator:: +GenerateSwap(io::Printer* printer) { + // Generate the Swap member function. + printer->Print("void $classname$::Swap($classname$* other) {\n", + "classname", classname_); + printer->Indent(); + printer->Print("if (other != this) {\n"); + printer->Indent(); + + if (HasGeneratedMethods(descriptor_->file())) { + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + field_generators_.get(field).GenerateSwappingCode(printer); + } + + for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) { + printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n", + "i", SimpleItoa(i)); + } + + if (HasUnknownFields(descriptor_->file())) { + printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n"); + } + printer->Print("std::swap(_cached_size_, other->_cached_size_);\n"); + if (descriptor_->extension_range_count() > 0) { + printer->Print("_extensions_.Swap(&other->_extensions_);\n"); + } + } else { + printer->Print("GetReflection()->Swap(this, other);"); + } + + printer->Outdent(); + printer->Print("}\n"); + printer->Outdent(); + printer->Print("}\n"); +} + +void MessageGenerator:: +GenerateMergeFrom(io::Printer* printer) { + if (HasDescriptorMethods(descriptor_->file())) { + // Generate the generalized MergeFrom (aka that which takes in the Message + // base class as a parameter). + printer->Print( + "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n" + " GOOGLE_CHECK_NE(&from, this);\n", + "classname", classname_); + printer->Indent(); + + // Cast the message to the proper type. If we find that the message is + // *not* of the proper type, we can still call Merge via the reflection + // system, as the GOOGLE_CHECK above ensured that we have the same descriptor + // for each message. + printer->Print( + "const $classname$* source =\n" + " ::google::protobuf::internal::dynamic_cast_if_available(\n" + " &from);\n" + "if (source == NULL) {\n" + " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n" + "} else {\n" + " MergeFrom(*source);\n" + "}\n", + "classname", classname_); + + printer->Outdent(); + printer->Print("}\n\n"); + } else { + // Generate CheckTypeAndMergeFrom(). + printer->Print( + "void $classname$::CheckTypeAndMergeFrom(\n" + " const ::google::protobuf::MessageLite& from) {\n" + " MergeFrom(*::google::protobuf::down_cast(&from));\n" + "}\n" + "\n", + "classname", classname_); + } + + // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast. + printer->Print( + "void $classname$::MergeFrom(const $classname$& from) {\n" + " GOOGLE_CHECK_NE(&from, this);\n", + "classname", classname_); + printer->Indent(); + + // Merge Repeated fields. These fields do not require a + // check as we can simply iterate over them. + for (int i = 0; i < descriptor_->field_count(); ++i) { + const FieldDescriptor* field = descriptor_->field(i); + + if (field->is_repeated()) { + field_generators_.get(field).GenerateMergingCode(printer); + } + } + + // Merge Optional and Required fields (after a _has_bit check). + int last_index = -1; + + for (int i = 0; i < descriptor_->field_count(); ++i) { + const FieldDescriptor* field = descriptor_->field(i); + + if (!field->is_repeated()) { + // See above in GenerateClear for an explanation of this. + if (i / 8 != last_index / 8 || last_index < 0) { + if (last_index >= 0) { + printer->Outdent(); + printer->Print("}\n"); + } + printer->Print( + "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", + "index", SimpleItoa(field->index())); + printer->Indent(); + } + + last_index = i; + + printer->Print( + "if (from.has_$name$()) {\n", + "name", FieldName(field)); + printer->Indent(); + + field_generators_.get(field).GenerateMergingCode(printer); + + printer->Outdent(); + printer->Print("}\n"); + } + } + + if (last_index >= 0) { + printer->Outdent(); + printer->Print("}\n"); + } + + if (descriptor_->extension_range_count() > 0) { + printer->Print("_extensions_.MergeFrom(from._extensions_);\n"); + } + + if (HasUnknownFields(descriptor_->file())) { + printer->Print( + "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void MessageGenerator:: +GenerateCopyFrom(io::Printer* printer) { + if (HasDescriptorMethods(descriptor_->file())) { + // Generate the generalized CopyFrom (aka that which takes in the Message + // base class as a parameter). + printer->Print( + "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n", + "classname", classname_); + printer->Indent(); + + printer->Print( + "if (&from == this) return;\n" + "Clear();\n" + "MergeFrom(from);\n"); + + printer->Outdent(); + printer->Print("}\n\n"); + } + + // Generate the class-specific CopyFrom. + printer->Print( + "void $classname$::CopyFrom(const $classname$& from) {\n", + "classname", classname_); + printer->Indent(); + + printer->Print( + "if (&from == this) return;\n" + "Clear();\n" + "MergeFrom(from);\n"); + + printer->Outdent(); + printer->Print("}\n"); +} + +void MessageGenerator:: +GenerateMergeFromCodedStream(io::Printer* printer) { + if (descriptor_->options().message_set_wire_format()) { + // Special-case MessageSet. + printer->Print( + "bool $classname$::MergePartialFromCodedStream(\n" + " ::google::protobuf::io::CodedInputStream* input) {\n", + "classname", classname_); + + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. + " return _extensions_.ParseMessageSet(input, default_instance_,\n" + " mutable_unknown_fields());\n", + // Without. + " return _extensions_.ParseMessageSet(input, &default_instance(),\n" + " mutable_unknown_fields());\n", + // Vars. + "classname", classname_); + + printer->Print( + "}\n"); + return; + } + + printer->Print( + "bool $classname$::MergePartialFromCodedStream(\n" + " ::google::protobuf::io::CodedInputStream* input) {\n" + "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n" + " ::google::protobuf::uint32 tag;\n" + " while ((tag = input->ReadTag()) != 0) {\n", + "classname", classname_); + + printer->Indent(); + printer->Indent(); + + if (descriptor_->field_count() > 0) { + // We don't even want to print the switch() if we have no fields because + // MSVC dislikes switch() statements that contain only a default value. + + // Note: If we just switched on the tag rather than the field number, we + // could avoid the need for the if() to check the wire type at the beginning + // of each case. However, this is actually a bit slower in practice as it + // creates a jump table that is 8x larger and sparser, and meanwhile the + // if()s are highly predictable. + printer->Print( + "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n"); + + printer->Indent(); + + scoped_array ordered_fields( + SortFieldsByNumber(descriptor_)); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = ordered_fields[i]; + + PrintFieldComment(printer, field); + + printer->Print( + "case $number$: {\n", + "number", SimpleItoa(field->number())); + printer->Indent(); + const FieldGenerator& field_generator = field_generators_.get(field); + + // Emit code to parse the common, expected case. + printer->Print( + "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" + " ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n", + "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]); + + if (i > 0 || (field->is_repeated() && !field->options().packed())) { + printer->Print( + " parse_$name$:\n", + "name", field->name()); + } + + printer->Indent(); + if (field->options().packed()) { + field_generator.GenerateMergeFromCodedStreamWithPacking(printer); + } else { + field_generator.GenerateMergeFromCodedStream(printer); + } + printer->Outdent(); + + // Emit code to parse unexpectedly packed or unpacked values. + if (field->is_packable() && field->options().packed()) { + printer->Print( + "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n" + " == ::google::protobuf::internal::WireFormatLite::\n" + " WIRETYPE_$wiretype$) {\n", + "wiretype", + kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]); + printer->Indent(); + field_generator.GenerateMergeFromCodedStream(printer); + printer->Outdent(); + } else if (field->is_packable() && !field->options().packed()) { + printer->Print( + "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n" + " == ::google::protobuf::internal::WireFormatLite::\n" + " WIRETYPE_LENGTH_DELIMITED) {\n"); + printer->Indent(); + field_generator.GenerateMergeFromCodedStreamWithPacking(printer); + printer->Outdent(); + } + + printer->Print( + "} else {\n" + " goto handle_uninterpreted;\n" + "}\n"); + + // switch() is slow since it can't be predicted well. Insert some if()s + // here that attempt to predict the next tag. + if (field->is_repeated() && !field->options().packed()) { + // Expect repeats of this field. + printer->Print( + "if (input->ExpectTag($tag$)) goto parse_$name$;\n", + "tag", SimpleItoa(WireFormat::MakeTag(field)), + "name", field->name()); + } + + if (i + 1 < descriptor_->field_count()) { + // Expect the next field in order. + const FieldDescriptor* next_field = ordered_fields[i + 1]; + printer->Print( + "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n", + "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)), + "next_name", next_field->name()); + } else { + // Expect EOF. + // TODO(kenton): Expect group end-tag? + printer->Print( + "if (input->ExpectAtEnd()) return true;\n"); + } + + printer->Print( + "break;\n"); + + printer->Outdent(); + printer->Print("}\n\n"); + } + + printer->Print( + "default: {\n" + "handle_uninterpreted:\n"); + printer->Indent(); + } + + // Is this an end-group tag? If so, this must be the end of the message. + printer->Print( + "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" + " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n" + " return true;\n" + "}\n"); + + // Handle extension ranges. + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "if ("); + for (int i = 0; i < descriptor_->extension_range_count(); i++) { + const Descriptor::ExtensionRange* range = + descriptor_->extension_range(i); + if (i > 0) printer->Print(" ||\n "); + + uint32 start_tag = WireFormatLite::MakeTag( + range->start, static_cast(0)); + uint32 end_tag = WireFormatLite::MakeTag( + range->end, static_cast(0)); + + if (range->end > FieldDescriptor::kMaxNumber) { + printer->Print( + "($start$u <= tag)", + "start", SimpleItoa(start_tag)); + } else { + printer->Print( + "($start$u <= tag && tag < $end$u)", + "start", SimpleItoa(start_tag), + "end", SimpleItoa(end_tag)); + } + } + printer->Print(") {\n"); + if (HasUnknownFields(descriptor_->file())) { + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. + " DO_(_extensions_.ParseField(tag, input, default_instance_,\n" + " mutable_unknown_fields()));\n", + // Without. + " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n" + " mutable_unknown_fields()));\n"); + } else { + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. + " DO_(_extensions_.ParseField(tag, input, default_instance_));\n", + // Without. + " DO_(_extensions_.ParseField(tag, input, &default_instance()));\n"); + } + printer->Print( + " continue;\n" + "}\n"); + } + + // We really don't recognize this tag. Skip it. + if (HasUnknownFields(descriptor_->file())) { + printer->Print( + "DO_(::google::protobuf::internal::WireFormat::SkipField(\n" + " input, tag, mutable_unknown_fields()));\n"); + } else { + printer->Print( + "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n"); + } + + if (descriptor_->field_count() > 0) { + printer->Print("break;\n"); + printer->Outdent(); + printer->Print("}\n"); // default: + printer->Outdent(); + printer->Print("}\n"); // switch + } + + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" // while + " return true;\n" + "#undef DO_\n" + "}\n"); +} + +void MessageGenerator::GenerateSerializeOneField( + io::Printer* printer, const FieldDescriptor* field, bool to_array) { + PrintFieldComment(printer, field); + + if (!field->is_repeated()) { + printer->Print( + "if (has_$name$()) {\n", + "name", FieldName(field)); + printer->Indent(); + } + + if (to_array) { + field_generators_.get(field).GenerateSerializeWithCachedSizesToArray( + printer); + } else { + field_generators_.get(field).GenerateSerializeWithCachedSizes(printer); + } + + if (!field->is_repeated()) { + printer->Outdent(); + printer->Print("}\n"); + } + printer->Print("\n"); +} + +void MessageGenerator::GenerateSerializeOneExtensionRange( + io::Printer* printer, const Descriptor::ExtensionRange* range, + bool to_array) { + map vars; + vars["start"] = SimpleItoa(range->start); + vars["end"] = SimpleItoa(range->end); + printer->Print(vars, + "// Extension range [$start$, $end$)\n"); + if (to_array) { + printer->Print(vars, + "target = _extensions_.SerializeWithCachedSizesToArray(\n" + " $start$, $end$, target);\n\n"); + } else { + printer->Print(vars, + "_extensions_.SerializeWithCachedSizes(\n" + " $start$, $end$, output);\n\n"); + } +} + +void MessageGenerator:: +GenerateSerializeWithCachedSizes(io::Printer* printer) { + if (descriptor_->options().message_set_wire_format()) { + // Special-case MessageSet. + printer->Print( + "void $classname$::SerializeWithCachedSizes(\n" + " ::google::protobuf::io::CodedOutputStream* output) const {\n" + " _extensions_.SerializeMessageSetWithCachedSizes(output);\n", + "classname", classname_); + if (HasUnknownFields(descriptor_->file())) { + printer->Print( + " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n" + " unknown_fields(), output);\n"); + } + printer->Print( + "}\n"); + return; + } + + printer->Print( + "void $classname$::SerializeWithCachedSizes(\n" + " ::google::protobuf::io::CodedOutputStream* output) const {\n", + "classname", classname_); + printer->Indent(); + + GenerateSerializeWithCachedSizesBody(printer, false); + + printer->Outdent(); + printer->Print( + "}\n"); +} + +void MessageGenerator:: +GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { + if (descriptor_->options().message_set_wire_format()) { + // Special-case MessageSet. + printer->Print( + "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" + " ::google::protobuf::uint8* target) const {\n" + " target =\n" + " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n", + "classname", classname_); + if (HasUnknownFields(descriptor_->file())) { + printer->Print( + " target = ::google::protobuf::internal::WireFormat::\n" + " SerializeUnknownMessageSetItemsToArray(\n" + " unknown_fields(), target);\n"); + } + printer->Print( + " return target;\n" + "}\n"); + return; + } + + printer->Print( + "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" + " ::google::protobuf::uint8* target) const {\n", + "classname", classname_); + printer->Indent(); + + GenerateSerializeWithCachedSizesBody(printer, true); + + printer->Outdent(); + printer->Print( + " return target;\n" + "}\n"); +} + +void MessageGenerator:: +GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { + scoped_array ordered_fields( + SortFieldsByNumber(descriptor_)); + + vector sorted_extensions; + for (int i = 0; i < descriptor_->extension_range_count(); ++i) { + sorted_extensions.push_back(descriptor_->extension_range(i)); + } + sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeSorter()); + + // Merge the fields and the extension ranges, both sorted by field number. + int i, j; + for (i = 0, j = 0; + i < descriptor_->field_count() || j < sorted_extensions.size(); + ) { + if (i == descriptor_->field_count()) { + GenerateSerializeOneExtensionRange(printer, + sorted_extensions[j++], + to_array); + } else if (j == sorted_extensions.size()) { + GenerateSerializeOneField(printer, ordered_fields[i++], to_array); + } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) { + GenerateSerializeOneField(printer, ordered_fields[i++], to_array); + } else { + GenerateSerializeOneExtensionRange(printer, + sorted_extensions[j++], + to_array); + } + } + + if (HasUnknownFields(descriptor_->file())) { + printer->Print("if (!unknown_fields().empty()) {\n"); + printer->Indent(); + if (to_array) { + printer->Print( + "target = " + "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n" + " unknown_fields(), target);\n"); + } else { + printer->Print( + "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n" + " unknown_fields(), output);\n"); + } + printer->Outdent(); + + printer->Print( + "}\n"); + } +} + +void MessageGenerator:: +GenerateByteSize(io::Printer* printer) { + if (descriptor_->options().message_set_wire_format()) { + // Special-case MessageSet. + printer->Print( + "int $classname$::ByteSize() const {\n" + " int total_size = _extensions_.MessageSetByteSize();\n", + "classname", classname_); + if (HasUnknownFields(descriptor_->file())) { + printer->Print( + " total_size += ::google::protobuf::internal::WireFormat::\n" + " ComputeUnknownMessageSetItemsSize(unknown_fields());\n"); + } + printer->Print( + " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" + " _cached_size_ = total_size;\n" + " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" + " return total_size;\n" + "}\n"); + return; + } + + printer->Print( + "int $classname$::ByteSize() const {\n", + "classname", classname_); + printer->Indent(); + printer->Print( + "int total_size = 0;\n" + "\n"); + + int last_index = -1; + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + if (!field->is_repeated()) { + // See above in GenerateClear for an explanation of this. + // TODO(kenton): Share code? Unclear how to do so without + // over-engineering. + if ((i / 8) != (last_index / 8) || + last_index < 0) { + if (last_index >= 0) { + printer->Outdent(); + printer->Print("}\n"); + } + printer->Print( + "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", + "index", SimpleItoa(field->index())); + printer->Indent(); + } + last_index = i; + + PrintFieldComment(printer, field); + + printer->Print( + "if (has_$name$()) {\n", + "name", FieldName(field)); + printer->Indent(); + + field_generators_.get(field).GenerateByteSize(printer); + + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + } + } + + if (last_index >= 0) { + printer->Outdent(); + printer->Print("}\n"); + } + + // Repeated fields don't use _has_bits_ so we count them in a separate + // pass. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + if (field->is_repeated()) { + PrintFieldComment(printer, field); + field_generators_.get(field).GenerateByteSize(printer); + printer->Print("\n"); + } + } + + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "total_size += _extensions_.ByteSize();\n" + "\n"); + } + + if (HasUnknownFields(descriptor_->file())) { + printer->Print("if (!unknown_fields().empty()) {\n"); + printer->Indent(); + printer->Print( + "total_size +=\n" + " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n" + " unknown_fields());\n"); + printer->Outdent(); + printer->Print("}\n"); + } + + // We update _cached_size_ even though this is a const method. In theory, + // this is not thread-compatible, because concurrent writes have undefined + // results. In practice, since any concurrent writes will be writing the + // exact same value, it works on all common processors. In a future version + // of C++, _cached_size_ should be made into an atomic. + printer->Print( + "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" + "_cached_size_ = total_size;\n" + "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" + "return total_size;\n"); + + printer->Outdent(); + printer->Print("}\n"); +} + +void MessageGenerator:: +GenerateIsInitialized(io::Printer* printer) { + printer->Print( + "bool $classname$::IsInitialized() const {\n", + "classname", classname_); + printer->Indent(); + + // Check that all required fields in this message are set. We can do this + // most efficiently by checking 32 "has bits" at a time. + int has_bits_array_size = (descriptor_->field_count() + 31) / 32; + for (int i = 0; i < has_bits_array_size; i++) { + uint32 mask = 0; + for (int bit = 0; bit < 32; bit++) { + int index = i * 32 + bit; + if (index >= descriptor_->field_count()) break; + const FieldDescriptor* field = descriptor_->field(index); + + if (field->is_required()) { + mask |= 1 << bit; + } + } + + if (mask != 0) { + char buffer[kFastToBufferSize]; + printer->Print( + "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n", + "i", SimpleItoa(i), + "mask", FastHex32ToBuffer(mask, buffer)); + } + } + + // Now check that all embedded messages are initialized. + printer->Print("\n"); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + !ShouldIgnoreRequiredFieldCheck(field) && + HasRequiredFields(field->message_type())) { + if (field->is_repeated()) { + printer->Print( + "for (int i = 0; i < $name$_size(); i++) {\n" + " if (!this->$name$(i).IsInitialized()) return false;\n" + "}\n", + "name", FieldName(field)); + } else { + printer->Print( + "if (has_$name$()) {\n" + " if (!this->$name$().IsInitialized()) return false;\n" + "}\n", + "name", FieldName(field)); + } + } + } + + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "\n" + "if (!_extensions_.IsInitialized()) return false;"); + } + + printer->Outdent(); + printer->Print( + " return true;\n" + "}\n"); +} + + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message.h new file mode 100644 index 0000000..a7e43d9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message.h @@ -0,0 +1,171 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ + +#include +#include +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace cpp { + +class EnumGenerator; // enum.h +class ExtensionGenerator; // extension.h + +class MessageGenerator { + public: + // See generator.cc for the meaning of dllexport_decl. + explicit MessageGenerator(const Descriptor* descriptor, + const Options& options); + ~MessageGenerator(); + + // Header stuff. + + // Generate foward declarations for this class and all its nested types. + void GenerateForwardDeclaration(io::Printer* printer); + + // Generate definitions of all nested enums (must come before class + // definitions because those classes use the enums definitions). + void GenerateEnumDefinitions(io::Printer* printer); + + // Generate specializations of GetEnumDescriptor(). + // Precondition: in ::google::protobuf namespace. + void GenerateGetEnumDescriptorSpecializations(io::Printer* printer); + + // Generate definitions for this class and all its nested types. + void GenerateClassDefinition(io::Printer* printer); + + // Generate definitions of inline methods (placed at the end of the header + // file). + void GenerateInlineMethods(io::Printer* printer); + + // Source file stuff. + + // Generate code which declares all the global descriptor pointers which + // will be initialized by the methods below. + void GenerateDescriptorDeclarations(io::Printer* printer); + + // Generate code that initializes the global variable storing the message's + // descriptor. + void GenerateDescriptorInitializer(io::Printer* printer, int index); + + // Generate code that calls MessageFactory::InternalRegisterGeneratedMessage() + // for all types. + void GenerateTypeRegistrations(io::Printer* printer); + + // Generates code that allocates the message's default instance. + void GenerateDefaultInstanceAllocator(io::Printer* printer); + + // Generates code that initializes the message's default instance. This + // is separate from allocating because all default instances must be + // allocated before any can be initialized. + void GenerateDefaultInstanceInitializer(io::Printer* printer); + + // Generates code that should be run when ShutdownProtobufLibrary() is called, + // to delete all dynamically-allocated objects. + void GenerateShutdownCode(io::Printer* printer); + + // Generate all non-inline methods for this class. + void GenerateClassMethods(io::Printer* printer); + + private: + // Generate declarations and definitions of accessors for fields. + void GenerateFieldAccessorDeclarations(io::Printer* printer); + void GenerateFieldAccessorDefinitions(io::Printer* printer); + + // Generate the field offsets array. + void GenerateOffsets(io::Printer* printer); + + // Generate constructors and destructor. + void GenerateStructors(io::Printer* printer); + + // The compiler typically generates multiple copies of each constructor and + // destructor: http://gcc.gnu.org/bugs.html#nonbugs_cxx + // Placing common code in a separate method reduces the generated code size. + // + // Generate the shared constructor code. + void GenerateSharedConstructorCode(io::Printer* printer); + // Generate the shared destructor code. + void GenerateSharedDestructorCode(io::Printer* printer); + + // Generate standard Message methods. + void GenerateClear(io::Printer* printer); + void GenerateMergeFromCodedStream(io::Printer* printer); + void GenerateSerializeWithCachedSizes(io::Printer* printer); + void GenerateSerializeWithCachedSizesToArray(io::Printer* printer); + void GenerateSerializeWithCachedSizesBody(io::Printer* printer, + bool to_array); + void GenerateByteSize(io::Printer* printer); + void GenerateMergeFrom(io::Printer* printer); + void GenerateCopyFrom(io::Printer* printer); + void GenerateSwap(io::Printer* printer); + void GenerateIsInitialized(io::Printer* printer); + + // Helpers for GenerateSerializeWithCachedSizes(). + void GenerateSerializeOneField(io::Printer* printer, + const FieldDescriptor* field, + bool unbounded); + void GenerateSerializeOneExtensionRange( + io::Printer* printer, const Descriptor::ExtensionRange* range, + bool unbounded); + + + const Descriptor* descriptor_; + string classname_; + Options options_; + FieldGeneratorMap field_generators_; + scoped_array > nested_generators_; + scoped_array > enum_generators_; + scoped_array > extension_generators_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message_field.cc new file mode 100644 index 0000000..447f975 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -0,0 +1,298 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +namespace { + +void SetMessageVariables(const FieldDescriptor* descriptor, + map* variables, + const Options& options) { + SetCommonFieldVariables(descriptor, variables, options); + (*variables)["type"] = FieldMessageTypeName(descriptor); + (*variables)["stream_writer"] = (*variables)["declared_type"] + + (HasFastArraySerialization(descriptor->message_type()->file()) ? + "MaybeToArray" : + ""); +} + +} // namespace + +// =================================================================== + +MessageFieldGenerator:: +MessageFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor) { + SetMessageVariables(descriptor, &variables_, options); +} + +MessageFieldGenerator::~MessageFieldGenerator() {} + +void MessageFieldGenerator:: +GeneratePrivateMembers(io::Printer* printer) const { + printer->Print(variables_, "$type$* $name$_;\n"); +} + +void MessageFieldGenerator:: +GenerateAccessorDeclarations(io::Printer* printer) const { + printer->Print(variables_, + "inline const $type$& $name$() const$deprecation$;\n" + "inline $type$* mutable_$name$()$deprecation$;\n" + "inline $type$* release_$name$()$deprecation$;\n" + "inline void set_allocated_$name$($type$* $name$)$deprecation$;\n"); +} + +void MessageFieldGenerator:: +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + printer->Print(variables_, + "inline const $type$& $classname$::$name$() const {\n"); + + PrintHandlingOptionalStaticInitializers( + variables_, descriptor_->file(), printer, + // With static initializers. + " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n", + // Without. + " return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n"); + + printer->Print(variables_, + "}\n" + "inline $type$* $classname$::mutable_$name$() {\n" + " set_has_$name$();\n" + " if ($name$_ == NULL) $name$_ = new $type$;\n" + " return $name$_;\n" + "}\n" + "inline $type$* $classname$::release_$name$() {\n" + " clear_has_$name$();\n" + " $type$* temp = $name$_;\n" + " $name$_ = NULL;\n" + " return temp;\n" + "}\n" + "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" + " delete $name$_;\n" + " $name$_ = $name$;\n" + " if ($name$) {\n" + " set_has_$name$();\n" + " } else {\n" + " clear_has_$name$();\n" + " }\n" + "}\n"); +} + +void MessageFieldGenerator:: +GenerateClearingCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($name$_ != NULL) $name$_->$type$::Clear();\n"); +} + +void MessageFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "mutable_$name$()->$type$::MergeFrom(from.$name$());\n"); +} + +void MessageFieldGenerator:: +GenerateSwappingCode(io::Printer* printer) const { + printer->Print(variables_, "std::swap($name$_, other->$name$_);\n"); +} + +void MessageFieldGenerator:: +GenerateConstructorCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = NULL;\n"); +} + +void MessageFieldGenerator:: +GenerateMergeFromCodedStream(io::Printer* printer) const { + if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { + printer->Print(variables_, + "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n" + " input, mutable_$name$()));\n"); + } else { + printer->Print(variables_, + "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n" + " $number$, input, mutable_$name$()));\n"); + } +} + +void MessageFieldGenerator:: +GenerateSerializeWithCachedSizes(io::Printer* printer) const { + printer->Print(variables_, + "::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n" + " $number$, this->$name$(), output);\n"); +} + +void MessageFieldGenerator:: +GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { + printer->Print(variables_, + "target = ::google::protobuf::internal::WireFormatLite::\n" + " Write$declared_type$NoVirtualToArray(\n" + " $number$, this->$name$(), target);\n"); +} + +void MessageFieldGenerator:: +GenerateByteSize(io::Printer* printer) const { + printer->Print(variables_, + "total_size += $tag_size$ +\n" + " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n" + " this->$name$());\n"); +} + +// =================================================================== + +RepeatedMessageFieldGenerator:: +RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor) { + SetMessageVariables(descriptor, &variables_, options); +} + +RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} + +void RepeatedMessageFieldGenerator:: +GeneratePrivateMembers(io::Printer* printer) const { + printer->Print(variables_, + "::google::protobuf::RepeatedPtrField< $type$ > $name$_;\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateAccessorDeclarations(io::Printer* printer) const { + printer->Print(variables_, + "inline const $type$& $name$(int index) const$deprecation$;\n" + "inline $type$* mutable_$name$(int index)$deprecation$;\n" + "inline $type$* add_$name$()$deprecation$;\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" + " $name$() const$deprecation$;\n" + "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n" + " mutable_$name$()$deprecation$;\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + printer->Print(variables_, + "inline const $type$& $classname$::$name$(int index) const {\n" + " return $name$_.$cppget$(index);\n" + "}\n" + "inline $type$* $classname$::mutable_$name$(int index) {\n" + " return $name$_.Mutable(index);\n" + "}\n" + "inline $type$* $classname$::add_$name$() {\n" + " return $name$_.Add();\n" + "}\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" + "$classname$::$name$() const {\n" + " return $name$_;\n" + "}\n" + "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n" + "$classname$::mutable_$name$() {\n" + " return &$name$_;\n" + "}\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateClearingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.Clear();\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateSwappingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateConstructorCode(io::Printer* printer) const { + // Not needed for repeated fields. +} + +void RepeatedMessageFieldGenerator:: +GenerateMergeFromCodedStream(io::Printer* printer) const { + if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { + printer->Print(variables_, + "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n" + " input, add_$name$()));\n"); + } else { + printer->Print(variables_, + "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n" + " $number$, input, add_$name$()));\n"); + } +} + +void RepeatedMessageFieldGenerator:: +GenerateSerializeWithCachedSizes(io::Printer* printer) const { + printer->Print(variables_, + "for (int i = 0; i < this->$name$_size(); i++) {\n" + " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n" + " $number$, this->$name$(i), output);\n" + "}\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { + printer->Print(variables_, + "for (int i = 0; i < this->$name$_size(); i++) {\n" + " target = ::google::protobuf::internal::WireFormatLite::\n" + " Write$declared_type$NoVirtualToArray(\n" + " $number$, this->$name$(i), target);\n" + "}\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateByteSize(io::Printer* printer) const { + printer->Print(variables_, + "total_size += $tag_size$ * this->$name$_size();\n" + "for (int i = 0; i < this->$name$_size(); i++) {\n" + " total_size +=\n" + " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n" + " this->$name$(i));\n" + "}\n"); +} + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message_field.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message_field.h new file mode 100644 index 0000000..a5ed68a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_message_field.h @@ -0,0 +1,104 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +class MessageFieldGenerator : public FieldGenerator { + public: + explicit MessageFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + ~MessageFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GeneratePrivateMembers(io::Printer* printer) const; + void GenerateAccessorDeclarations(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateClearingCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateSwappingCode(io::Printer* printer) const; + void GenerateConstructorCode(io::Printer* printer) const; + void GenerateMergeFromCodedStream(io::Printer* printer) const; + void GenerateSerializeWithCachedSizes(io::Printer* printer) const; + void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; + void GenerateByteSize(io::Printer* printer) const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); +}; + +class RepeatedMessageFieldGenerator : public FieldGenerator { + public: + explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + ~RepeatedMessageFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GeneratePrivateMembers(io::Printer* printer) const; + void GenerateAccessorDeclarations(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateClearingCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateSwappingCode(io::Printer* printer) const; + void GenerateConstructorCode(io::Printer* printer) const; + void GenerateMergeFromCodedStream(io::Printer* printer) const; + void GenerateSerializeWithCachedSizes(io::Printer* printer) const; + void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; + void GenerateByteSize(io::Printer* printer) const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_options.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_options.h new file mode 100644 index 0000000..7877066 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_options.h @@ -0,0 +1,58 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: rennie@google.com (Jeffrey Rennie) + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__ + +#include + +#include +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +// Generator options: +struct Options { + Options() : safe_boundary_check(false) { + } + string dllexport_decl; + bool safe_boundary_check; +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc new file mode 100644 index 0000000..5c4aa4f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc @@ -0,0 +1,121 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// TODO(kenton): Share code with the versions of this test in other languages? +// It seemed like parameterizing it would add more complexity than it is +// worth. + +#include +#include +#include +#include + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { +namespace { + +class TestGenerator : public CodeGenerator { + public: + TestGenerator() {} + ~TestGenerator() {} + + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const { + TryInsert("test.pb.h", "includes", context); + TryInsert("test.pb.h", "namespace_scope", context); + TryInsert("test.pb.h", "global_scope", context); + TryInsert("test.pb.h", "class_scope:foo.Bar", context); + TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", context); + + TryInsert("test.pb.cc", "includes", context); + TryInsert("test.pb.cc", "namespace_scope", context); + TryInsert("test.pb.cc", "global_scope", context); + return true; + } + + void TryInsert(const string& filename, const string& insertion_point, + GeneratorContext* context) const { + scoped_ptr output( + context->OpenForInsert(filename, insertion_point)); + io::Printer printer(output.get(), '$'); + printer.Print("// inserted $name$\n", "name", insertion_point); + } +}; + +// This test verifies that all the expected insertion points exist. It does +// not verify that they are correctly-placed; that would require actually +// compiling the output which is a bit more than I care to do for this test. +TEST(CppPluginTest, PluginTest) { + File::WriteStringToFileOrDie( + "syntax = \"proto2\";\n" + "package foo;\n" + "message Bar {\n" + " message Baz {}\n" + "}\n", + TestTempDir() + "/test.proto"); + + google::protobuf::compiler::CommandLineInterface cli; + cli.SetInputsAreProtoPathRelative(true); + + CppGenerator cpp_generator; + TestGenerator test_generator; + cli.RegisterGenerator("--cpp_out", &cpp_generator, ""); + cli.RegisterGenerator("--test_out", &test_generator, ""); + + string proto_path = "-I" + TestTempDir(); + string cpp_out = "--cpp_out=" + TestTempDir(); + string test_out = "--test_out=" + TestTempDir(); + + const char* argv[] = { + "protoc", + proto_path.c_str(), + cpp_out.c_str(), + test_out.c_str(), + "test.proto" + }; + + EXPECT_EQ(0, cli.Run(5, argv)); +} + +} // namespace +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc new file mode 100644 index 0000000..1c35fef --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc @@ -0,0 +1,387 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +using internal::WireFormatLite; + +namespace { + +// For encodings with fixed sizes, returns that size in bytes. Otherwise +// returns -1. +int FixedSize(FieldDescriptor::Type type) { + switch (type) { + case FieldDescriptor::TYPE_INT32 : return -1; + case FieldDescriptor::TYPE_INT64 : return -1; + case FieldDescriptor::TYPE_UINT32 : return -1; + case FieldDescriptor::TYPE_UINT64 : return -1; + case FieldDescriptor::TYPE_SINT32 : return -1; + case FieldDescriptor::TYPE_SINT64 : return -1; + case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size; + case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size; + case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size; + case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size; + case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize; + case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize; + + case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize; + case FieldDescriptor::TYPE_ENUM : return -1; + + case FieldDescriptor::TYPE_STRING : return -1; + case FieldDescriptor::TYPE_BYTES : return -1; + case FieldDescriptor::TYPE_GROUP : return -1; + case FieldDescriptor::TYPE_MESSAGE : return -1; + + // No default because we want the compiler to complain if any new + // types are added. + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return -1; +} + +void SetPrimitiveVariables(const FieldDescriptor* descriptor, + map* variables, + const Options& options) { + SetCommonFieldVariables(descriptor, variables, options); + (*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type()); + (*variables)["default"] = DefaultValue(descriptor); + (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); + int fixed_size = FixedSize(descriptor->type()); + if (fixed_size != -1) { + (*variables)["fixed_size"] = SimpleItoa(fixed_size); + } + (*variables)["wire_format_field_type"] = + "::google::protobuf::internal::WireFormatLite::" + FieldDescriptorProto_Type_Name( + static_cast(descriptor->type())); +} + +} // namespace + +// =================================================================== + +PrimitiveFieldGenerator:: +PrimitiveFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor) { + SetPrimitiveVariables(descriptor, &variables_, options); +} + +PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} + +void PrimitiveFieldGenerator:: +GeneratePrivateMembers(io::Printer* printer) const { + printer->Print(variables_, "$type$ $name$_;\n"); +} + +void PrimitiveFieldGenerator:: +GenerateAccessorDeclarations(io::Printer* printer) const { + printer->Print(variables_, + "inline $type$ $name$() const$deprecation$;\n" + "inline void set_$name$($type$ value)$deprecation$;\n"); +} + +void PrimitiveFieldGenerator:: +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + printer->Print(variables_, + "inline $type$ $classname$::$name$() const {\n" + " return $name$_;\n" + "}\n" + "inline void $classname$::set_$name$($type$ value) {\n" + " set_has_$name$();\n" + " $name$_ = value;\n" + "}\n"); +} + +void PrimitiveFieldGenerator:: +GenerateClearingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void PrimitiveFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, "set_$name$(from.$name$());\n"); +} + +void PrimitiveFieldGenerator:: +GenerateSwappingCode(io::Printer* printer) const { + printer->Print(variables_, "std::swap($name$_, other->$name$_);\n"); +} + +void PrimitiveFieldGenerator:: +GenerateConstructorCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void PrimitiveFieldGenerator:: +GenerateMergeFromCodedStream(io::Printer* printer) const { + printer->Print(variables_, + "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" + " $type$, $wire_format_field_type$>(\n" + " input, &$name$_)));\n" + "set_has_$name$();\n"); +} + +void PrimitiveFieldGenerator:: +GenerateSerializeWithCachedSizes(io::Printer* printer) const { + printer->Print(variables_, + "::google::protobuf::internal::WireFormatLite::Write$declared_type$(" + "$number$, this->$name$(), output);\n"); +} + +void PrimitiveFieldGenerator:: +GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { + printer->Print(variables_, + "target = ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray(" + "$number$, this->$name$(), target);\n"); +} + +void PrimitiveFieldGenerator:: +GenerateByteSize(io::Printer* printer) const { + int fixed_size = FixedSize(descriptor_->type()); + if (fixed_size == -1) { + printer->Print(variables_, + "total_size += $tag_size$ +\n" + " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n" + " this->$name$());\n"); + } else { + printer->Print(variables_, + "total_size += $tag_size$ + $fixed_size$;\n"); + } +} + +// =================================================================== + +RepeatedPrimitiveFieldGenerator:: +RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor) { + SetPrimitiveVariables(descriptor, &variables_, options); + + if (descriptor->options().packed()) { + variables_["packed_reader"] = "ReadPackedPrimitive"; + variables_["repeated_reader"] = "ReadRepeatedPrimitiveNoInline"; + } else { + variables_["packed_reader"] = "ReadPackedPrimitiveNoInline"; + variables_["repeated_reader"] = "ReadRepeatedPrimitive"; + } +} + +RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} + +void RepeatedPrimitiveFieldGenerator:: +GeneratePrivateMembers(io::Printer* printer) const { + printer->Print(variables_, + "::google::protobuf::RepeatedField< $type$ > $name$_;\n"); + if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) { + printer->Print(variables_, + "mutable int _$name$_cached_byte_size_;\n"); + } +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateAccessorDeclarations(io::Printer* printer) const { + printer->Print(variables_, + "inline $type$ $name$(int index) const$deprecation$;\n" + "inline void set_$name$(int index, $type$ value)$deprecation$;\n" + "inline void add_$name$($type$ value)$deprecation$;\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedField< $type$ >&\n" + " $name$() const$deprecation$;\n" + "inline ::google::protobuf::RepeatedField< $type$ >*\n" + " mutable_$name$()$deprecation$;\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + printer->Print(variables_, + "inline $type$ $classname$::$name$(int index) const {\n" + " return $name$_.Get(index);\n" + "}\n" + "inline void $classname$::set_$name$(int index, $type$ value) {\n" + " $name$_.Set(index, value);\n" + "}\n" + "inline void $classname$::add_$name$($type$ value) {\n" + " $name$_.Add(value);\n" + "}\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedField< $type$ >&\n" + "$classname$::$name$() const {\n" + " return $name$_;\n" + "}\n" + "inline ::google::protobuf::RepeatedField< $type$ >*\n" + "$classname$::mutable_$name$() {\n" + " return &$name$_;\n" + "}\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateClearingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.Clear();\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateSwappingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateConstructorCode(io::Printer* printer) const { + // Not needed for repeated fields. +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateMergeFromCodedStream(io::Printer* printer) const { + printer->Print(variables_, + "DO_((::google::protobuf::internal::WireFormatLite::$repeated_reader$<\n" + " $type$, $wire_format_field_type$>(\n" + " $tag_size$, $tag$, input, this->mutable_$name$())));\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { + printer->Print(variables_, + "DO_((::google::protobuf::internal::WireFormatLite::$packed_reader$<\n" + " $type$, $wire_format_field_type$>(\n" + " input, this->mutable_$name$())));\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateSerializeWithCachedSizes(io::Printer* printer) const { + if (descriptor_->options().packed()) { + // Write the tag and the size. + printer->Print(variables_, + "if (this->$name$_size() > 0) {\n" + " ::google::protobuf::internal::WireFormatLite::WriteTag(" + "$number$, " + "::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, " + "output);\n" + " output->WriteVarint32(_$name$_cached_byte_size_);\n" + "}\n"); + } + printer->Print(variables_, + "for (int i = 0; i < this->$name$_size(); i++) {\n"); + if (descriptor_->options().packed()) { + printer->Print(variables_, + " ::google::protobuf::internal::WireFormatLite::Write$declared_type$NoTag(\n" + " this->$name$(i), output);\n"); + } else { + printer->Print(variables_, + " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n" + " $number$, this->$name$(i), output);\n"); + } + printer->Print("}\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { + if (descriptor_->options().packed()) { + // Write the tag and the size. + printer->Print(variables_, + "if (this->$name$_size() > 0) {\n" + " target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n" + " $number$,\n" + " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n" + " target);\n" + " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(\n" + " _$name$_cached_byte_size_, target);\n" + "}\n"); + } + printer->Print(variables_, + "for (int i = 0; i < this->$name$_size(); i++) {\n"); + if (descriptor_->options().packed()) { + printer->Print(variables_, + " target = ::google::protobuf::internal::WireFormatLite::\n" + " Write$declared_type$NoTagToArray(this->$name$(i), target);\n"); + } else { + printer->Print(variables_, + " target = ::google::protobuf::internal::WireFormatLite::\n" + " Write$declared_type$ToArray($number$, this->$name$(i), target);\n"); + } + printer->Print("}\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateByteSize(io::Printer* printer) const { + printer->Print(variables_, + "{\n" + " int data_size = 0;\n"); + printer->Indent(); + int fixed_size = FixedSize(descriptor_->type()); + if (fixed_size == -1) { + printer->Print(variables_, + "for (int i = 0; i < this->$name$_size(); i++) {\n" + " data_size += ::google::protobuf::internal::WireFormatLite::\n" + " $declared_type$Size(this->$name$(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "data_size = $fixed_size$ * this->$name$_size();\n"); + } + + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (data_size > 0) {\n" + " total_size += $tag_size$ +\n" + " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n" + "}\n" + "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" + "_$name$_cached_byte_size_ = data_size;\n" + "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" + "total_size += data_size;\n"); + } else { + printer->Print(variables_, + "total_size += $tag_size$ * this->$name$_size() + data_size;\n"); + } + printer->Outdent(); + printer->Print("}\n"); +} + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_primitive_field.h new file mode 100644 index 0000000..48249c4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_primitive_field.h @@ -0,0 +1,105 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +class PrimitiveFieldGenerator : public FieldGenerator { + public: + explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + ~PrimitiveFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GeneratePrivateMembers(io::Printer* printer) const; + void GenerateAccessorDeclarations(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateClearingCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateSwappingCode(io::Printer* printer) const; + void GenerateConstructorCode(io::Printer* printer) const; + void GenerateMergeFromCodedStream(io::Printer* printer) const; + void GenerateSerializeWithCachedSizes(io::Printer* printer) const; + void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; + void GenerateByteSize(io::Printer* printer) const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); +}; + +class RepeatedPrimitiveFieldGenerator : public FieldGenerator { + public: + explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + ~RepeatedPrimitiveFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GeneratePrivateMembers(io::Printer* printer) const; + void GenerateAccessorDeclarations(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateClearingCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateSwappingCode(io::Printer* printer) const; + void GenerateConstructorCode(io::Printer* printer) const; + void GenerateMergeFromCodedStream(io::Printer* printer) const; + void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const; + void GenerateSerializeWithCachedSizes(io::Printer* printer) const; + void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; + void GenerateByteSize(io::Printer* printer) const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_service.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_service.cc new file mode 100644 index 0000000..d20018e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_service.cc @@ -0,0 +1,334 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor) { + vars_["classname"] = descriptor_->name(); + vars_["full_name"] = descriptor_->full_name(); + if (options.dllexport_decl.empty()) { + vars_["dllexport"] = ""; + } else { + vars_["dllexport"] = options.dllexport_decl + " "; + } +} + +ServiceGenerator::~ServiceGenerator() {} + +void ServiceGenerator::GenerateDeclarations(io::Printer* printer) { + // Forward-declare the stub type. + printer->Print(vars_, + "class $classname$_Stub;\n" + "\n"); + + GenerateInterface(printer); + GenerateStubDefinition(printer); +} + +void ServiceGenerator::GenerateInterface(io::Printer* printer) { + printer->Print(vars_, + "class $dllexport$$classname$ : public ::google::protobuf::Service {\n" + " protected:\n" + " // This class should be treated as an abstract interface.\n" + " inline $classname$() {};\n" + " public:\n" + " virtual ~$classname$();\n"); + printer->Indent(); + + printer->Print(vars_, + "\n" + "typedef $classname$_Stub Stub;\n" + "\n" + "static const ::google::protobuf::ServiceDescriptor* descriptor();\n" + "\n"); + + GenerateMethodSignatures(VIRTUAL, printer); + + printer->Print( + "\n" + "// implements Service ----------------------------------------------\n" + "\n" + "const ::google::protobuf::ServiceDescriptor* GetDescriptor();\n" + "void CallMethod(const ::google::protobuf::MethodDescriptor* method,\n" + " ::google::protobuf::RpcController* controller,\n" + " const ::google::protobuf::Message* request,\n" + " ::google::protobuf::Message* response,\n" + " ::google::protobuf::Closure* done);\n" + "const ::google::protobuf::Message& GetRequestPrototype(\n" + " const ::google::protobuf::MethodDescriptor* method) const;\n" + "const ::google::protobuf::Message& GetResponsePrototype(\n" + " const ::google::protobuf::MethodDescriptor* method) const;\n"); + + printer->Outdent(); + printer->Print(vars_, + "\n" + " private:\n" + " GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n" + "};\n" + "\n"); +} + +void ServiceGenerator::GenerateStubDefinition(io::Printer* printer) { + printer->Print(vars_, + "class $dllexport$$classname$_Stub : public $classname$ {\n" + " public:\n"); + + printer->Indent(); + + printer->Print(vars_, + "$classname$_Stub(::google::protobuf::RpcChannel* channel);\n" + "$classname$_Stub(::google::protobuf::RpcChannel* channel,\n" + " ::google::protobuf::Service::ChannelOwnership ownership);\n" + "~$classname$_Stub();\n" + "\n" + "inline ::google::protobuf::RpcChannel* channel() { return channel_; }\n" + "\n" + "// implements $classname$ ------------------------------------------\n" + "\n"); + + GenerateMethodSignatures(NON_VIRTUAL, printer); + + printer->Outdent(); + printer->Print(vars_, + " private:\n" + " ::google::protobuf::RpcChannel* channel_;\n" + " bool owns_channel_;\n" + " GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$_Stub);\n" + "};\n" + "\n"); +} + +void ServiceGenerator::GenerateMethodSignatures( + VirtualOrNon virtual_or_non, io::Printer* printer) { + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + map sub_vars; + sub_vars["name"] = method->name(); + sub_vars["input_type"] = ClassName(method->input_type(), true); + sub_vars["output_type"] = ClassName(method->output_type(), true); + sub_vars["virtual"] = virtual_or_non == VIRTUAL ? "virtual " : ""; + + printer->Print(sub_vars, + "$virtual$void $name$(::google::protobuf::RpcController* controller,\n" + " const $input_type$* request,\n" + " $output_type$* response,\n" + " ::google::protobuf::Closure* done);\n"); + } +} + +// =================================================================== + +void ServiceGenerator::GenerateDescriptorInitializer( + io::Printer* printer, int index) { + map vars; + vars["classname"] = descriptor_->name(); + vars["index"] = SimpleItoa(index); + + printer->Print(vars, + "$classname$_descriptor_ = file->service($index$);\n"); +} + +// =================================================================== + +void ServiceGenerator::GenerateImplementation(io::Printer* printer) { + printer->Print(vars_, + "$classname$::~$classname$() {}\n" + "\n" + "const ::google::protobuf::ServiceDescriptor* $classname$::descriptor() {\n" + " protobuf_AssignDescriptorsOnce();\n" + " return $classname$_descriptor_;\n" + "}\n" + "\n" + "const ::google::protobuf::ServiceDescriptor* $classname$::GetDescriptor() {\n" + " protobuf_AssignDescriptorsOnce();\n" + " return $classname$_descriptor_;\n" + "}\n" + "\n"); + + // Generate methods of the interface. + GenerateNotImplementedMethods(printer); + GenerateCallMethod(printer); + GenerateGetPrototype(REQUEST, printer); + GenerateGetPrototype(RESPONSE, printer); + + // Generate stub implementation. + printer->Print(vars_, + "$classname$_Stub::$classname$_Stub(::google::protobuf::RpcChannel* channel)\n" + " : channel_(channel), owns_channel_(false) {}\n" + "$classname$_Stub::$classname$_Stub(\n" + " ::google::protobuf::RpcChannel* channel,\n" + " ::google::protobuf::Service::ChannelOwnership ownership)\n" + " : channel_(channel),\n" + " owns_channel_(ownership == ::google::protobuf::Service::STUB_OWNS_CHANNEL) {}\n" + "$classname$_Stub::~$classname$_Stub() {\n" + " if (owns_channel_) delete channel_;\n" + "}\n" + "\n"); + + GenerateStubMethods(printer); +} + +void ServiceGenerator::GenerateNotImplementedMethods(io::Printer* printer) { + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + map sub_vars; + sub_vars["classname"] = descriptor_->name(); + sub_vars["name"] = method->name(); + sub_vars["index"] = SimpleItoa(i); + sub_vars["input_type"] = ClassName(method->input_type(), true); + sub_vars["output_type"] = ClassName(method->output_type(), true); + + printer->Print(sub_vars, + "void $classname$::$name$(::google::protobuf::RpcController* controller,\n" + " const $input_type$*,\n" + " $output_type$*,\n" + " ::google::protobuf::Closure* done) {\n" + " controller->SetFailed(\"Method $name$() not implemented.\");\n" + " done->Run();\n" + "}\n" + "\n"); + } +} + +void ServiceGenerator::GenerateCallMethod(io::Printer* printer) { + printer->Print(vars_, + "void $classname$::CallMethod(const ::google::protobuf::MethodDescriptor* method,\n" + " ::google::protobuf::RpcController* controller,\n" + " const ::google::protobuf::Message* request,\n" + " ::google::protobuf::Message* response,\n" + " ::google::protobuf::Closure* done) {\n" + " GOOGLE_DCHECK_EQ(method->service(), $classname$_descriptor_);\n" + " switch(method->index()) {\n"); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + map sub_vars; + sub_vars["name"] = method->name(); + sub_vars["index"] = SimpleItoa(i); + sub_vars["input_type"] = ClassName(method->input_type(), true); + sub_vars["output_type"] = ClassName(method->output_type(), true); + + // Note: down_cast does not work here because it only works on pointers, + // not references. + printer->Print(sub_vars, + " case $index$:\n" + " $name$(controller,\n" + " ::google::protobuf::down_cast(request),\n" + " ::google::protobuf::down_cast< $output_type$*>(response),\n" + " done);\n" + " break;\n"); + } + + printer->Print(vars_, + " default:\n" + " GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n" + " break;\n" + " }\n" + "}\n" + "\n"); +} + +void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which, + io::Printer* printer) { + if (which == REQUEST) { + printer->Print(vars_, + "const ::google::protobuf::Message& $classname$::GetRequestPrototype(\n"); + } else { + printer->Print(vars_, + "const ::google::protobuf::Message& $classname$::GetResponsePrototype(\n"); + } + + printer->Print(vars_, + " const ::google::protobuf::MethodDescriptor* method) const {\n" + " GOOGLE_DCHECK_EQ(method->service(), descriptor());\n" + " switch(method->index()) {\n"); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + const Descriptor* type = + (which == REQUEST) ? method->input_type() : method->output_type(); + + map sub_vars; + sub_vars["index"] = SimpleItoa(i); + sub_vars["type"] = ClassName(type, true); + + printer->Print(sub_vars, + " case $index$:\n" + " return $type$::default_instance();\n"); + } + + printer->Print(vars_, + " default:\n" + " GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n" + " return *reinterpret_cast< ::google::protobuf::Message*>(NULL);\n" + " }\n" + "}\n" + "\n"); +} + +void ServiceGenerator::GenerateStubMethods(io::Printer* printer) { + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + map sub_vars; + sub_vars["classname"] = descriptor_->name(); + sub_vars["name"] = method->name(); + sub_vars["index"] = SimpleItoa(i); + sub_vars["input_type"] = ClassName(method->input_type(), true); + sub_vars["output_type"] = ClassName(method->output_type(), true); + + printer->Print(sub_vars, + "void $classname$_Stub::$name$(::google::protobuf::RpcController* controller,\n" + " const $input_type$* request,\n" + " $output_type$* response,\n" + " ::google::protobuf::Closure* done) {\n" + " channel_->CallMethod(descriptor()->method($index$),\n" + " controller, request, response, done);\n" + "}\n"); + } +} + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_service.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_service.h new file mode 100644 index 0000000..820f9f5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_service.h @@ -0,0 +1,119 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__ + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace cpp { + +class ServiceGenerator { + public: + // See generator.cc for the meaning of dllexport_decl. + explicit ServiceGenerator(const ServiceDescriptor* descriptor, + const Options& options); + ~ServiceGenerator(); + + // Header stuff. + + // Generate the class definitions for the service's interface and the + // stub implementation. + void GenerateDeclarations(io::Printer* printer); + + // Source file stuff. + + // Generate code that initializes the global variable storing the service's + // descriptor. + void GenerateDescriptorInitializer(io::Printer* printer, int index); + + // Generate implementations of everything declared by GenerateDeclarations(). + void GenerateImplementation(io::Printer* printer); + + private: + enum RequestOrResponse { REQUEST, RESPONSE }; + enum VirtualOrNon { VIRTUAL, NON_VIRTUAL }; + + // Header stuff. + + // Generate the service abstract interface. + void GenerateInterface(io::Printer* printer); + + // Generate the stub class definition. + void GenerateStubDefinition(io::Printer* printer); + + // Prints signatures for all methods in the + void GenerateMethodSignatures(VirtualOrNon virtual_or_non, + io::Printer* printer); + + // Source file stuff. + + // Generate the default implementations of the service methods, which + // produce a "not implemented" error. + void GenerateNotImplementedMethods(io::Printer* printer); + + // Generate the CallMethod() method of the service. + void GenerateCallMethod(io::Printer* printer); + + // Generate the Get{Request,Response}Prototype() methods. + void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer); + + // Generate the stub's implementations of the service methods. + void GenerateStubMethods(io::Printer* printer); + + const ServiceDescriptor* descriptor_; + map vars_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_string_field.cc new file mode 100644 index 0000000..9c0911a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -0,0 +1,491 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +namespace { + +void SetStringVariables(const FieldDescriptor* descriptor, + map* variables, + const Options& options) { + SetCommonFieldVariables(descriptor, variables, options); + (*variables)["default"] = DefaultValue(descriptor); + (*variables)["default_length"] = + SimpleItoa(descriptor->default_value_string().length()); + (*variables)["default_variable"] = descriptor->default_value_string().empty() + ? "&::google::protobuf::internal::kEmptyString" + : "_default_" + FieldName(descriptor) + "_"; + (*variables)["pointer_type"] = + descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char"; +} + +} // namespace + +// =================================================================== + +StringFieldGenerator:: +StringFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor) { + SetStringVariables(descriptor, &variables_, options); +} + +StringFieldGenerator::~StringFieldGenerator() {} + +void StringFieldGenerator:: +GeneratePrivateMembers(io::Printer* printer) const { + printer->Print(variables_, "::std::string* $name$_;\n"); + if (!descriptor_->default_value_string().empty()) { + printer->Print(variables_, "static ::std::string* $default_variable$;\n"); + } +} + +void StringFieldGenerator:: +GenerateAccessorDeclarations(io::Printer* printer) const { + // If we're using StringFieldGenerator for a field with a ctype, it's + // because that ctype isn't actually implemented. In particular, this is + // true of ctype=CORD and ctype=STRING_PIECE in the open source release. + // We aren't releasing Cord because it has too many Google-specific + // dependencies and we aren't releasing StringPiece because it's hardly + // useful outside of Google and because it would get confusing to have + // multiple instances of the StringPiece class in different libraries (PCRE + // already includes it for their C++ bindings, which came from Google). + // + // In any case, we make all the accessors private while still actually + // using a string to represent the field internally. This way, we can + // guarantee that if we do ever implement the ctype, it won't break any + // existing users who might be -- for whatever reason -- already using .proto + // files that applied the ctype. The field can still be accessed via the + // reflection interface since the reflection interface is independent of + // the string's underlying representation. + if (descriptor_->options().ctype() != FieldOptions::STRING) { + printer->Outdent(); + printer->Print( + " private:\n" + " // Hidden due to unknown ctype option.\n"); + printer->Indent(); + } + + printer->Print(variables_, + "inline const ::std::string& $name$() const$deprecation$;\n" + "inline void set_$name$(const ::std::string& value)$deprecation$;\n" + "inline void set_$name$(const char* value)$deprecation$;\n" + "inline void set_$name$(const $pointer_type$* value, size_t size)" + "$deprecation$;\n" + "inline ::std::string* mutable_$name$()$deprecation$;\n" + "inline ::std::string* release_$name$()$deprecation$;\n" + "inline void set_allocated_$name$(::std::string* $name$)$deprecation$;\n"); + + + if (descriptor_->options().ctype() != FieldOptions::STRING) { + printer->Outdent(); + printer->Print(" public:\n"); + printer->Indent(); + } +} + +void StringFieldGenerator:: +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + printer->Print(variables_, + "inline const ::std::string& $classname$::$name$() const {\n" + " return *$name$_;\n" + "}\n" + "inline void $classname$::set_$name$(const ::std::string& value) {\n" + " set_has_$name$();\n" + " if ($name$_ == $default_variable$) {\n" + " $name$_ = new ::std::string;\n" + " }\n" + " $name$_->assign(value);\n" + "}\n" + "inline void $classname$::set_$name$(const char* value) {\n" + " set_has_$name$();\n" + " if ($name$_ == $default_variable$) {\n" + " $name$_ = new ::std::string;\n" + " }\n" + " $name$_->assign(value);\n" + "}\n" + "inline " + "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n" + " set_has_$name$();\n" + " if ($name$_ == $default_variable$) {\n" + " $name$_ = new ::std::string;\n" + " }\n" + " $name$_->assign(reinterpret_cast(value), size);\n" + "}\n" + "inline ::std::string* $classname$::mutable_$name$() {\n" + " set_has_$name$();\n" + " if ($name$_ == $default_variable$) {\n"); + if (descriptor_->default_value_string().empty()) { + printer->Print(variables_, + " $name$_ = new ::std::string;\n"); + } else { + printer->Print(variables_, + " $name$_ = new ::std::string(*$default_variable$);\n"); + } + printer->Print(variables_, + " }\n" + " return $name$_;\n" + "}\n" + "inline ::std::string* $classname$::release_$name$() {\n" + " clear_has_$name$();\n" + " if ($name$_ == $default_variable$) {\n" + " return NULL;\n" + " } else {\n" + " ::std::string* temp = $name$_;\n" + " $name$_ = const_cast< ::std::string*>($default_variable$);\n" + " return temp;\n" + " }\n" + "}\n" + "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + " if ($name$_ != $default_variable$) {\n" + " delete $name$_;\n" + " }\n" + " if ($name$) {\n" + " set_has_$name$();\n" + " $name$_ = $name$;\n" + " } else {\n" + " clear_has_$name$();\n" + " $name$_ = const_cast< ::std::string*>($default_variable$);\n" + " }\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateNonInlineAccessorDefinitions(io::Printer* printer) const { + if (!descriptor_->default_value_string().empty()) { + // Initialized in GenerateDefaultInstanceAllocator. + printer->Print(variables_, + "::std::string* $classname$::$default_variable$ = NULL;\n"); + } +} + +void StringFieldGenerator:: +GenerateClearingCode(io::Printer* printer) const { + if (descriptor_->default_value_string().empty()) { + printer->Print(variables_, + "if ($name$_ != $default_variable$) {\n" + " $name$_->clear();\n" + "}\n"); + } else { + printer->Print(variables_, + "if ($name$_ != $default_variable$) {\n" + " $name$_->assign(*$default_variable$);\n" + "}\n"); + } +} + +void StringFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, "set_$name$(from.$name$());\n"); +} + +void StringFieldGenerator:: +GenerateSwappingCode(io::Printer* printer) const { + printer->Print(variables_, "std::swap($name$_, other->$name$_);\n"); +} + +void StringFieldGenerator:: +GenerateConstructorCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = const_cast< ::std::string*>($default_variable$);\n"); +} + +void StringFieldGenerator:: +GenerateDestructorCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($name$_ != $default_variable$) {\n" + " delete $name$_;\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateDefaultInstanceAllocator(io::Printer* printer) const { + if (!descriptor_->default_value_string().empty()) { + printer->Print(variables_, + "$classname$::$default_variable$ =\n" + " new ::std::string($default$, $default_length$);\n"); + } +} + +void StringFieldGenerator:: +GenerateShutdownCode(io::Printer* printer) const { + if (!descriptor_->default_value_string().empty()) { + printer->Print(variables_, + "delete $classname$::$default_variable$;\n"); + } +} + +void StringFieldGenerator:: +GenerateMergeFromCodedStream(io::Printer* printer) const { + printer->Print(variables_, + "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n" + " input, this->mutable_$name$()));\n"); + if (HasUtf8Verification(descriptor_->file()) && + descriptor_->type() == FieldDescriptor::TYPE_STRING) { + printer->Print(variables_, + "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n" + " this->$name$().data(), this->$name$().length(),\n" + " ::google::protobuf::internal::WireFormat::PARSE);\n"); + } +} + +void StringFieldGenerator:: +GenerateSerializeWithCachedSizes(io::Printer* printer) const { + if (HasUtf8Verification(descriptor_->file()) && + descriptor_->type() == FieldDescriptor::TYPE_STRING) { + printer->Print(variables_, + "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n" + " this->$name$().data(), this->$name$().length(),\n" + " ::google::protobuf::internal::WireFormat::SERIALIZE);\n"); + } + printer->Print(variables_, + "::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n" + " $number$, this->$name$(), output);\n"); +} + +void StringFieldGenerator:: +GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { + if (HasUtf8Verification(descriptor_->file()) && + descriptor_->type() == FieldDescriptor::TYPE_STRING) { + printer->Print(variables_, + "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n" + " this->$name$().data(), this->$name$().length(),\n" + " ::google::protobuf::internal::WireFormat::SERIALIZE);\n"); + } + printer->Print(variables_, + "target =\n" + " ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray(\n" + " $number$, this->$name$(), target);\n"); +} + +void StringFieldGenerator:: +GenerateByteSize(io::Printer* printer) const { + printer->Print(variables_, + "total_size += $tag_size$ +\n" + " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n" + " this->$name$());\n"); +} + +// =================================================================== + +RepeatedStringFieldGenerator:: +RepeatedStringFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor) { + SetStringVariables(descriptor, &variables_, options); +} + +RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {} + +void RepeatedStringFieldGenerator:: +GeneratePrivateMembers(io::Printer* printer) const { + printer->Print(variables_, + "::google::protobuf::RepeatedPtrField< ::std::string> $name$_;\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateAccessorDeclarations(io::Printer* printer) const { + // See comment above about unknown ctypes. + if (descriptor_->options().ctype() != FieldOptions::STRING) { + printer->Outdent(); + printer->Print( + " private:\n" + " // Hidden due to unknown ctype option.\n"); + printer->Indent(); + } + + printer->Print(variables_, + "inline const ::std::string& $name$(int index) const$deprecation$;\n" + "inline ::std::string* mutable_$name$(int index)$deprecation$;\n" + "inline void set_$name$(int index, const ::std::string& value)$deprecation$;\n" + "inline void set_$name$(int index, const char* value)$deprecation$;\n" + "inline " + "void set_$name$(int index, const $pointer_type$* value, size_t size)" + "$deprecation$;\n" + "inline ::std::string* add_$name$()$deprecation$;\n" + "inline void add_$name$(const ::std::string& value)$deprecation$;\n" + "inline void add_$name$(const char* value)$deprecation$;\n" + "inline void add_$name$(const $pointer_type$* value, size_t size)" + "$deprecation$;\n"); + + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const" + "$deprecation$;\n" + "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()" + "$deprecation$;\n"); + + if (descriptor_->options().ctype() != FieldOptions::STRING) { + printer->Outdent(); + printer->Print(" public:\n"); + printer->Indent(); + } +} + +void RepeatedStringFieldGenerator:: +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + printer->Print(variables_, + "inline const ::std::string& $classname$::$name$(int index) const {\n" + " return $name$_.$cppget$(index);\n" + "}\n" + "inline ::std::string* $classname$::mutable_$name$(int index) {\n" + " return $name$_.Mutable(index);\n" + "}\n" + "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n" + " $name$_.Mutable(index)->assign(value);\n" + "}\n" + "inline void $classname$::set_$name$(int index, const char* value) {\n" + " $name$_.Mutable(index)->assign(value);\n" + "}\n" + "inline void " + "$classname$::set_$name$" + "(int index, const $pointer_type$* value, size_t size) {\n" + " $name$_.Mutable(index)->assign(\n" + " reinterpret_cast(value), size);\n" + "}\n" + "inline ::std::string* $classname$::add_$name$() {\n" + " return $name$_.Add();\n" + "}\n" + "inline void $classname$::add_$name$(const ::std::string& value) {\n" + " $name$_.Add()->assign(value);\n" + "}\n" + "inline void $classname$::add_$name$(const char* value) {\n" + " $name$_.Add()->assign(value);\n" + "}\n" + "inline void " + "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n" + " $name$_.Add()->assign(reinterpret_cast(value), size);\n" + "}\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n" + "$classname$::$name$() const {\n" + " return $name$_;\n" + "}\n" + "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n" + "$classname$::mutable_$name$() {\n" + " return &$name$_;\n" + "}\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateClearingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.Clear();\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateSwappingCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateConstructorCode(io::Printer* printer) const { + // Not needed for repeated fields. +} + +void RepeatedStringFieldGenerator:: +GenerateMergeFromCodedStream(io::Printer* printer) const { + printer->Print(variables_, + "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n" + " input, this->add_$name$()));\n"); + if (HasUtf8Verification(descriptor_->file()) && + descriptor_->type() == FieldDescriptor::TYPE_STRING) { + printer->Print(variables_, + "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n" + " this->$name$(this->$name$_size() - 1).data(),\n" + " this->$name$(this->$name$_size() - 1).length(),\n" + " ::google::protobuf::internal::WireFormat::PARSE);\n"); + } +} + +void RepeatedStringFieldGenerator:: +GenerateSerializeWithCachedSizes(io::Printer* printer) const { + printer->Print(variables_, + "for (int i = 0; i < this->$name$_size(); i++) {\n"); + if (HasUtf8Verification(descriptor_->file()) && + descriptor_->type() == FieldDescriptor::TYPE_STRING) { + printer->Print(variables_, + "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n" + " this->$name$(i).data(), this->$name$(i).length(),\n" + " ::google::protobuf::internal::WireFormat::SERIALIZE);\n"); + } + printer->Print(variables_, + " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n" + " $number$, this->$name$(i), output);\n" + "}\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { + printer->Print(variables_, + "for (int i = 0; i < this->$name$_size(); i++) {\n"); + if (HasUtf8Verification(descriptor_->file()) && + descriptor_->type() == FieldDescriptor::TYPE_STRING) { + printer->Print(variables_, + " ::google::protobuf::internal::WireFormat::VerifyUTF8String(\n" + " this->$name$(i).data(), this->$name$(i).length(),\n" + " ::google::protobuf::internal::WireFormat::SERIALIZE);\n"); + } + printer->Print(variables_, + " target = ::google::protobuf::internal::WireFormatLite::\n" + " Write$declared_type$ToArray($number$, this->$name$(i), target);\n" + "}\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateByteSize(io::Printer* printer) const { + printer->Print(variables_, + "total_size += $tag_size$ * this->$name$_size();\n" + "for (int i = 0; i < this->$name$_size(); i++) {\n" + " total_size += ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n" + " this->$name$(i));\n" + "}\n"); +} + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_string_field.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_string_field.h new file mode 100644 index 0000000..3264134 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_string_field.h @@ -0,0 +1,108 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +class StringFieldGenerator : public FieldGenerator { + public: + explicit StringFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + ~StringFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GeneratePrivateMembers(io::Printer* printer) const; + void GenerateAccessorDeclarations(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateClearingCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateSwappingCode(io::Printer* printer) const; + void GenerateConstructorCode(io::Printer* printer) const; + void GenerateDestructorCode(io::Printer* printer) const; + void GenerateDefaultInstanceAllocator(io::Printer* printer) const; + void GenerateShutdownCode(io::Printer* printer) const; + void GenerateMergeFromCodedStream(io::Printer* printer) const; + void GenerateSerializeWithCachedSizes(io::Printer* printer) const; + void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; + void GenerateByteSize(io::Printer* printer) const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator); +}; + +class RepeatedStringFieldGenerator : public FieldGenerator { + public: + explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + ~RepeatedStringFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GeneratePrivateMembers(io::Printer* printer) const; + void GenerateAccessorDeclarations(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateClearingCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateSwappingCode(io::Printer* printer) const; + void GenerateConstructorCode(io::Printer* printer) const; + void GenerateMergeFromCodedStream(io::Printer* printer) const; + void GenerateSerializeWithCachedSizes(io::Printer* printer) const; + void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; + void GenerateByteSize(io::Printer* printer) const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto new file mode 100644 index 0000000..e14a818 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto @@ -0,0 +1,123 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file tests that various identifiers work as field and type names even +// though the same identifiers are used internally by the C++ code generator. + + +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +option cc_generic_services = true; // auto-added + +// We don't put this in a package within proto2 because we need to make sure +// that the generated code doesn't depend on being in the proto2 namespace. +package protobuf_unittest; + +// Test that fields can have names like "input" and "i" which are also used +// internally by the code generator for local variables. +message TestConflictingSymbolNames { + message BuildDescriptors {} + message TypeTraits {} + + optional int32 input = 1; + optional int32 output = 2; + optional string length = 3; + repeated int32 i = 4; + repeated string new_element = 5 [ctype=STRING_PIECE]; + optional int32 total_size = 6; + optional int32 tag = 7; + + enum TestEnum { FOO = 1; } + message Data1 { repeated int32 data = 1; } + message Data2 { repeated TestEnum data = 1; } + message Data3 { repeated string data = 1; } + message Data4 { repeated Data4 data = 1; } + message Data5 { repeated string data = 1 [ctype=STRING_PIECE]; } + message Data6 { repeated string data = 1 [ctype=CORD]; } + + optional int32 source = 8; + optional int32 value = 9; + optional int32 file = 10; + optional int32 from = 11; + optional int32 handle_uninterpreted = 12; + repeated int32 index = 13; + optional int32 controller = 14; + optional int32 already_here = 15; + + optional uint32 uint32 = 16; + optional uint64 uint64 = 17; + optional string string = 18; + optional int32 memset = 19; + optional int32 int32 = 20; + optional int64 int64 = 21; + + optional uint32 cached_size = 22; + optional uint32 extensions = 23; + optional uint32 bit = 24; + optional uint32 bits = 25; + optional uint32 offsets = 26; + optional uint32 reflection = 27; + + message Cord {} + optional string some_cord = 28 [ctype=CORD]; + + message StringPiece {} + optional string some_string_piece = 29 [ctype=STRING_PIECE]; + + // Some keywords. + optional uint32 int = 30; + optional uint32 friend = 31; + + // The generator used to #define a macro called "DO" inside the .cc file. + message DO {} + optional DO do = 32; + + // Some template parameter names for extensions. + optional int32 field_type = 33; + optional bool is_packed = 34; + + extensions 1000 to max; +} + +message TestConflictingSymbolNamesExtension { + extend TestConflictingSymbolNames { + repeated int32 repeated_int32_ext = 20423638 [packed=true]; + } +} + +message DummyMessage {} + +service TestConflictingMethodNames { + rpc Closure(DummyMessage) returns (DummyMessage); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_unittest.cc new file mode 100644 index 0000000..1eae29b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -0,0 +1,1354 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// To test the code generator, we actually use it to generate code for +// google/protobuf/unittest.proto, then test that. This means that we +// are actually testing the parser and other parts of the system at the same +// time, and that problems in the generator may show up as compile-time errors +// rather than unittest failures, which may be surprising. However, testing +// the output of the C++ generator directly would be very hard. We can't very +// well just check it against golden files since those files would have to be +// updated for any small change; such a test would be very brittle and probably +// not very helpful. What we really want to test is that the code compiles +// correctly and produces the interfaces we expect, which is why this test +// is written this way. + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. +namespace cpp_unittest { + +namespace protobuf_unittest = ::protobuf_unittest; + + +class MockErrorCollector : public MultiFileErrorCollector { + public: + MockErrorCollector() {} + ~MockErrorCollector() {} + + string text_; + + // implements ErrorCollector --------------------------------------- + void AddError(const string& filename, int line, int column, + const string& message) { + strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", + filename, line, column, message); + } +}; + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + +// Test that generated code has proper descriptors: +// Parse a descriptor directly (using google::protobuf::compiler::Importer) and +// compare it to the one that was produced by generated code. +TEST(GeneratedDescriptorTest, IdenticalDescriptors) { + const FileDescriptor* generated_descriptor = + unittest::TestAllTypes::descriptor()->file(); + + // Set up the Importer. + MockErrorCollector error_collector; + DiskSourceTree source_tree; + source_tree.MapPath("", TestSourceDir()); + Importer importer(&source_tree, &error_collector); + + // Import (parse) unittest.proto. + const FileDescriptor* parsed_descriptor = + importer.Import("google/protobuf/unittest.proto"); + EXPECT_EQ("", error_collector.text_); + ASSERT_TRUE(parsed_descriptor != NULL); + + // Test that descriptors are generated correctly by converting them to + // FileDescriptorProtos and comparing. + FileDescriptorProto generated_decsriptor_proto, parsed_descriptor_proto; + generated_descriptor->CopyTo(&generated_decsriptor_proto); + parsed_descriptor->CopyTo(&parsed_descriptor_proto); + + EXPECT_EQ(parsed_descriptor_proto.DebugString(), + generated_decsriptor_proto.DebugString()); +} + +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS + +// =================================================================== + +TEST(GeneratedMessageTest, Defaults) { + // Check that all default values are set correctly in the initial message. + unittest::TestAllTypes message; + + TestUtil::ExpectClear(message); + + // Messages should return pointers to default instances until first use. + // (This is not checked by ExpectClear() since it is not actually true after + // the fields have been set and then cleared.) + EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(), + &message.optionalgroup()); + EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), + &message.optional_nested_message()); + EXPECT_EQ(&unittest::ForeignMessage::default_instance(), + &message.optional_foreign_message()); + EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), + &message.optional_import_message()); +} + +TEST(GeneratedMessageTest, FloatingPointDefaults) { + const unittest::TestExtremeDefaultValues& extreme_default = + unittest::TestExtremeDefaultValues::default_instance(); + + EXPECT_EQ(0.0f, extreme_default.zero_float()); + EXPECT_EQ(1.0f, extreme_default.one_float()); + EXPECT_EQ(1.5f, extreme_default.small_float()); + EXPECT_EQ(-1.0f, extreme_default.negative_one_float()); + EXPECT_EQ(-1.5f, extreme_default.negative_float()); + EXPECT_EQ(2.0e8f, extreme_default.large_float()); + EXPECT_EQ(-8e-28f, extreme_default.small_negative_float()); + EXPECT_EQ(numeric_limits::infinity(), + extreme_default.inf_double()); + EXPECT_EQ(-numeric_limits::infinity(), + extreme_default.neg_inf_double()); + EXPECT_TRUE(extreme_default.nan_double() != extreme_default.nan_double()); + EXPECT_EQ(numeric_limits::infinity(), + extreme_default.inf_float()); + EXPECT_EQ(-numeric_limits::infinity(), + extreme_default.neg_inf_float()); + EXPECT_TRUE(extreme_default.nan_float() != extreme_default.nan_float()); +} + +TEST(GeneratedMessageTest, Trigraph) { + const unittest::TestExtremeDefaultValues& extreme_default = + unittest::TestExtremeDefaultValues::default_instance(); + + EXPECT_EQ("? ? ?? ?? ??? ?\?/ ?\?-", extreme_default.cpp_trigraph()); +} + +TEST(GeneratedMessageTest, ExtremeSmallIntegerDefault) { + const unittest::TestExtremeDefaultValues& extreme_default = + unittest::TestExtremeDefaultValues::default_instance(); + EXPECT_EQ(-0x80000000, kint32min); + EXPECT_EQ(GOOGLE_LONGLONG(-0x8000000000000000), kint64min); + EXPECT_EQ(kint32min, extreme_default.really_small_int32()); + EXPECT_EQ(kint64min, extreme_default.really_small_int64()); +} + +TEST(GeneratedMessageTest, Accessors) { + // Set every field to a unique value then go back and check all those + // values. + unittest::TestAllTypes message; + + TestUtil::SetAllFields(&message); + TestUtil::ExpectAllFieldsSet(message); + + TestUtil::ModifyRepeatedFields(&message); + TestUtil::ExpectRepeatedFieldsModified(message); +} + +TEST(GeneratedMessageTest, MutableStringDefault) { + // mutable_foo() for a string should return a string initialized to its + // default value. + unittest::TestAllTypes message; + + EXPECT_EQ("hello", *message.mutable_default_string()); + + // Note that the first time we call mutable_foo(), we get a newly-allocated + // string, but if we clear it and call it again, we get the same object again. + // We should verify that it has its default value in both cases. + message.set_default_string("blah"); + message.Clear(); + + EXPECT_EQ("hello", *message.mutable_default_string()); +} + +TEST(GeneratedMessageTest, StringDefaults) { + unittest::TestExtremeDefaultValues message; + // Check if '\000' can be used in default string value. + EXPECT_EQ(string("hel\000lo", 6), message.string_with_zero()); + EXPECT_EQ(string("wor\000ld", 6), message.bytes_with_zero()); +} + +TEST(GeneratedMessageTest, ReleaseString) { + // Check that release_foo() starts out NULL, and gives us a value + // that we can delete after it's been set. + unittest::TestAllTypes message; + + EXPECT_EQ(NULL, message.release_default_string()); + EXPECT_FALSE(message.has_default_string()); + EXPECT_EQ("hello", message.default_string()); + + message.set_default_string("blah"); + EXPECT_TRUE(message.has_default_string()); + string* str = message.release_default_string(); + EXPECT_FALSE(message.has_default_string()); + ASSERT_TRUE(str != NULL); + EXPECT_EQ("blah", *str); + delete str; + + EXPECT_EQ(NULL, message.release_default_string()); + EXPECT_FALSE(message.has_default_string()); + EXPECT_EQ("hello", message.default_string()); +} + +TEST(GeneratedMessageTest, ReleaseMessage) { + // Check that release_foo() starts out NULL, and gives us a value + // that we can delete after it's been set. + unittest::TestAllTypes message; + + EXPECT_EQ(NULL, message.release_optional_nested_message()); + EXPECT_FALSE(message.has_optional_nested_message()); + + message.mutable_optional_nested_message()->set_bb(1); + unittest::TestAllTypes::NestedMessage* nest = + message.release_optional_nested_message(); + EXPECT_FALSE(message.has_optional_nested_message()); + ASSERT_TRUE(nest != NULL); + EXPECT_EQ(1, nest->bb()); + delete nest; + + EXPECT_EQ(NULL, message.release_optional_nested_message()); + EXPECT_FALSE(message.has_optional_nested_message()); +} + +TEST(GeneratedMessageTest, SetAllocatedString) { + // Check that set_allocated_foo() works for strings. + unittest::TestAllTypes message; + + EXPECT_FALSE(message.has_optional_string()); + const string kHello("hello"); + message.set_optional_string(kHello); + EXPECT_TRUE(message.has_optional_string()); + + message.set_allocated_optional_string(NULL); + EXPECT_FALSE(message.has_optional_string()); + EXPECT_EQ("", message.optional_string()); + + message.set_allocated_optional_string(new string(kHello)); + EXPECT_TRUE(message.has_optional_string()); + EXPECT_EQ(kHello, message.optional_string()); +} + +TEST(GeneratedMessageTest, SetAllocatedMessage) { + // Check that set_allocated_foo() can be called in all cases. + unittest::TestAllTypes message; + + EXPECT_FALSE(message.has_optional_nested_message()); + + message.mutable_optional_nested_message()->set_bb(1); + EXPECT_TRUE(message.has_optional_nested_message()); + + message.set_allocated_optional_nested_message(NULL); + EXPECT_FALSE(message.has_optional_nested_message()); + EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), + &message.optional_nested_message()); + + message.mutable_optional_nested_message()->set_bb(1); + unittest::TestAllTypes::NestedMessage* nest = + message.release_optional_nested_message(); + ASSERT_TRUE(nest != NULL); + EXPECT_FALSE(message.has_optional_nested_message()); + + message.set_allocated_optional_nested_message(nest); + EXPECT_TRUE(message.has_optional_nested_message()); + EXPECT_EQ(1, message.optional_nested_message().bb()); +} + +TEST(GeneratedMessageTest, Clear) { + // Set every field to a unique value, clear the message, then check that + // it is cleared. + unittest::TestAllTypes message; + + TestUtil::SetAllFields(&message); + message.Clear(); + TestUtil::ExpectClear(message); + + // Unlike with the defaults test, we do NOT expect that requesting embedded + // messages will return a pointer to the default instance. Instead, they + // should return the objects that were created when mutable_blah() was + // called. + EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), + &message.optionalgroup()); + EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), + &message.optional_nested_message()); + EXPECT_NE(&unittest::ForeignMessage::default_instance(), + &message.optional_foreign_message()); + EXPECT_NE(&unittest_import::ImportMessage::default_instance(), + &message.optional_import_message()); +} + +TEST(GeneratedMessageTest, EmbeddedNullsInBytesCharStar) { + unittest::TestAllTypes message; + + const char* value = "\0lalala\0\0"; + message.set_optional_bytes(value, 9); + ASSERT_EQ(9, message.optional_bytes().size()); + EXPECT_EQ(0, memcmp(value, message.optional_bytes().data(), 9)); + + message.add_repeated_bytes(value, 9); + ASSERT_EQ(9, message.repeated_bytes(0).size()); + EXPECT_EQ(0, memcmp(value, message.repeated_bytes(0).data(), 9)); +} + +TEST(GeneratedMessageTest, ClearOneField) { + // Set every field to a unique value, then clear one value and insure that + // only that one value is cleared. + unittest::TestAllTypes message; + + TestUtil::SetAllFields(&message); + int64 original_value = message.optional_int64(); + + // Clear the field and make sure it shows up as cleared. + message.clear_optional_int64(); + EXPECT_FALSE(message.has_optional_int64()); + EXPECT_EQ(0, message.optional_int64()); + + // Other adjacent fields should not be cleared. + EXPECT_TRUE(message.has_optional_int32()); + EXPECT_TRUE(message.has_optional_uint32()); + + // Make sure if we set it again, then all fields are set. + message.set_optional_int64(original_value); + TestUtil::ExpectAllFieldsSet(message); +} + +TEST(GeneratedMessageTest, StringCharStarLength) { + // Verify that we can use a char*,length to set one of the string fields. + unittest::TestAllTypes message; + message.set_optional_string("abcdef", 3); + EXPECT_EQ("abc", message.optional_string()); + + // Verify that we can use a char*,length to add to a repeated string field. + message.add_repeated_string("abcdef", 3); + EXPECT_EQ(1, message.repeated_string_size()); + EXPECT_EQ("abc", message.repeated_string(0)); + + // Verify that we can use a char*,length to set a repeated string field. + message.set_repeated_string(0, "wxyz", 2); + EXPECT_EQ("wx", message.repeated_string(0)); +} + +TEST(GeneratedMessageTest, CopyFrom) { + unittest::TestAllTypes message1, message2; + + TestUtil::SetAllFields(&message1); + message2.CopyFrom(message1); + TestUtil::ExpectAllFieldsSet(message2); + + // Copying from self should be a no-op. + message2.CopyFrom(message2); + TestUtil::ExpectAllFieldsSet(message2); +} + +TEST(GeneratedMessageTest, SwapWithEmpty) { + unittest::TestAllTypes message1, message2; + TestUtil::SetAllFields(&message1); + + TestUtil::ExpectAllFieldsSet(message1); + TestUtil::ExpectClear(message2); + message1.Swap(&message2); + TestUtil::ExpectAllFieldsSet(message2); + TestUtil::ExpectClear(message1); +} + +TEST(GeneratedMessageTest, SwapWithSelf) { + unittest::TestAllTypes message; + TestUtil::SetAllFields(&message); + TestUtil::ExpectAllFieldsSet(message); + message.Swap(&message); + TestUtil::ExpectAllFieldsSet(message); +} + +TEST(GeneratedMessageTest, SwapWithOther) { + unittest::TestAllTypes message1, message2; + + message1.set_optional_int32(123); + message1.set_optional_string("abc"); + message1.mutable_optional_nested_message()->set_bb(1); + message1.set_optional_nested_enum(unittest::TestAllTypes::FOO); + message1.add_repeated_int32(1); + message1.add_repeated_int32(2); + message1.add_repeated_string("a"); + message1.add_repeated_string("b"); + message1.add_repeated_nested_message()->set_bb(7); + message1.add_repeated_nested_message()->set_bb(8); + message1.add_repeated_nested_enum(unittest::TestAllTypes::FOO); + message1.add_repeated_nested_enum(unittest::TestAllTypes::BAR); + + message2.set_optional_int32(456); + message2.set_optional_string("def"); + message2.mutable_optional_nested_message()->set_bb(2); + message2.set_optional_nested_enum(unittest::TestAllTypes::BAR); + message2.add_repeated_int32(3); + message2.add_repeated_string("c"); + message2.add_repeated_nested_message()->set_bb(9); + message2.add_repeated_nested_enum(unittest::TestAllTypes::BAZ); + + message1.Swap(&message2); + + EXPECT_EQ(456, message1.optional_int32()); + EXPECT_EQ("def", message1.optional_string()); + EXPECT_EQ(2, message1.optional_nested_message().bb()); + EXPECT_EQ(unittest::TestAllTypes::BAR, message1.optional_nested_enum()); + ASSERT_EQ(1, message1.repeated_int32_size()); + EXPECT_EQ(3, message1.repeated_int32(0)); + ASSERT_EQ(1, message1.repeated_string_size()); + EXPECT_EQ("c", message1.repeated_string(0)); + ASSERT_EQ(1, message1.repeated_nested_message_size()); + EXPECT_EQ(9, message1.repeated_nested_message(0).bb()); + ASSERT_EQ(1, message1.repeated_nested_enum_size()); + EXPECT_EQ(unittest::TestAllTypes::BAZ, message1.repeated_nested_enum(0)); + + EXPECT_EQ(123, message2.optional_int32()); + EXPECT_EQ("abc", message2.optional_string()); + EXPECT_EQ(1, message2.optional_nested_message().bb()); + EXPECT_EQ(unittest::TestAllTypes::FOO, message2.optional_nested_enum()); + ASSERT_EQ(2, message2.repeated_int32_size()); + EXPECT_EQ(1, message2.repeated_int32(0)); + EXPECT_EQ(2, message2.repeated_int32(1)); + ASSERT_EQ(2, message2.repeated_string_size()); + EXPECT_EQ("a", message2.repeated_string(0)); + EXPECT_EQ("b", message2.repeated_string(1)); + ASSERT_EQ(2, message2.repeated_nested_message_size()); + EXPECT_EQ(7, message2.repeated_nested_message(0).bb()); + EXPECT_EQ(8, message2.repeated_nested_message(1).bb()); + ASSERT_EQ(2, message2.repeated_nested_enum_size()); + EXPECT_EQ(unittest::TestAllTypes::FOO, message2.repeated_nested_enum(0)); + EXPECT_EQ(unittest::TestAllTypes::BAR, message2.repeated_nested_enum(1)); +} + +TEST(GeneratedMessageTest, CopyConstructor) { + unittest::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + + unittest::TestAllTypes message2(message1); + TestUtil::ExpectAllFieldsSet(message2); +} + +TEST(GeneratedMessageTest, CopyAssignmentOperator) { + unittest::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + + unittest::TestAllTypes message2; + message2 = message1; + TestUtil::ExpectAllFieldsSet(message2); + + // Make sure that self-assignment does something sane. + message2.operator=(message2); + TestUtil::ExpectAllFieldsSet(message2); +} + +#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \ + !defined(GOOGLE_PROTOBUF_NO_RTTI) +TEST(GeneratedMessageTest, UpcastCopyFrom) { + // Test the CopyFrom method that takes in the generic const Message& + // parameter. + unittest::TestAllTypes message1, message2; + + TestUtil::SetAllFields(&message1); + + const Message* source = implicit_cast(&message1); + message2.CopyFrom(*source); + + TestUtil::ExpectAllFieldsSet(message2); +} +#endif + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + +TEST(GeneratedMessageTest, DynamicMessageCopyFrom) { + // Test copying from a DynamicMessage, which must fall back to using + // reflection. + unittest::TestAllTypes message2; + + // Construct a new version of the dynamic message via the factory. + DynamicMessageFactory factory; + scoped_ptr message1; + message1.reset(factory.GetPrototype( + unittest::TestAllTypes::descriptor())->New()); + + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllTypes::descriptor()); + reflection_tester.SetAllFieldsViaReflection(message1.get()); + + message2.CopyFrom(*message1); + + TestUtil::ExpectAllFieldsSet(message2); +} + +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS + +TEST(GeneratedMessageTest, NonEmptyMergeFrom) { + // Test merging with a non-empty message. Code is a modified form + // of that found in google/protobuf/reflection_ops_unittest.cc. + unittest::TestAllTypes message1, message2; + + TestUtil::SetAllFields(&message1); + + // This field will test merging into an empty spot. + message2.set_optional_int32(message1.optional_int32()); + message1.clear_optional_int32(); + + // This tests overwriting. + message2.set_optional_string(message1.optional_string()); + message1.set_optional_string("something else"); + + // This tests concatenating. + message2.add_repeated_int32(message1.repeated_int32(1)); + int32 i = message1.repeated_int32(0); + message1.clear_repeated_int32(); + message1.add_repeated_int32(i); + + message1.MergeFrom(message2); + + TestUtil::ExpectAllFieldsSet(message1); +} + +#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \ + !defined(GOOGLE_PROTOBUF_NO_RTTI) +#ifdef PROTOBUF_HAS_DEATH_TEST + +TEST(GeneratedMessageTest, MergeFromSelf) { + unittest::TestAllTypes message; + EXPECT_DEATH(message.MergeFrom(message), "&from"); + EXPECT_DEATH(message.MergeFrom(implicit_cast(message)), + "&from"); +} + +#endif // PROTOBUF_HAS_DEATH_TEST +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS || !GOOGLE_PROTOBUF_NO_RTTI + +// Test the generated SerializeWithCachedSizesToArray(), +TEST(GeneratedMessageTest, SerializationToArray) { + unittest::TestAllTypes message1, message2; + string data; + TestUtil::SetAllFields(&message1); + int size = message1.ByteSize(); + data.resize(size); + uint8* start = reinterpret_cast(string_as_array(&data)); + uint8* end = message1.SerializeWithCachedSizesToArray(start); + EXPECT_EQ(size, end - start); + EXPECT_TRUE(message2.ParseFromString(data)); + TestUtil::ExpectAllFieldsSet(message2); + +} + +TEST(GeneratedMessageTest, PackedFieldsSerializationToArray) { + unittest::TestPackedTypes packed_message1, packed_message2; + string packed_data; + TestUtil::SetPackedFields(&packed_message1); + int packed_size = packed_message1.ByteSize(); + packed_data.resize(packed_size); + uint8* start = reinterpret_cast(string_as_array(&packed_data)); + uint8* end = packed_message1.SerializeWithCachedSizesToArray(start); + EXPECT_EQ(packed_size, end - start); + EXPECT_TRUE(packed_message2.ParseFromString(packed_data)); + TestUtil::ExpectPackedFieldsSet(packed_message2); +} + +// Test the generated SerializeWithCachedSizes() by forcing the buffer to write +// one byte at a time. +TEST(GeneratedMessageTest, SerializationToStream) { + unittest::TestAllTypes message1, message2; + TestUtil::SetAllFields(&message1); + int size = message1.ByteSize(); + string data; + data.resize(size); + { + // Allow the output stream to buffer only one byte at a time. + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message1.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + EXPECT_TRUE(message2.ParseFromString(data)); + TestUtil::ExpectAllFieldsSet(message2); + +} + +TEST(GeneratedMessageTest, PackedFieldsSerializationToStream) { + unittest::TestPackedTypes message1, message2; + TestUtil::SetPackedFields(&message1); + int size = message1.ByteSize(); + string data; + data.resize(size); + { + // Allow the output stream to buffer only one byte at a time. + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message1.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + EXPECT_TRUE(message2.ParseFromString(data)); + TestUtil::ExpectPackedFieldsSet(message2); +} + + +TEST(GeneratedMessageTest, Required) { + // Test that IsInitialized() returns false if required fields are missing. + unittest::TestRequired message; + + EXPECT_FALSE(message.IsInitialized()); + message.set_a(1); + EXPECT_FALSE(message.IsInitialized()); + message.set_b(2); + EXPECT_FALSE(message.IsInitialized()); + message.set_c(3); + EXPECT_TRUE(message.IsInitialized()); +} + +TEST(GeneratedMessageTest, RequiredForeign) { + // Test that IsInitialized() returns false if required fields in nested + // messages are missing. + unittest::TestRequiredForeign message; + + EXPECT_TRUE(message.IsInitialized()); + + message.mutable_optional_message(); + EXPECT_FALSE(message.IsInitialized()); + + message.mutable_optional_message()->set_a(1); + message.mutable_optional_message()->set_b(2); + message.mutable_optional_message()->set_c(3); + EXPECT_TRUE(message.IsInitialized()); + + message.add_repeated_message(); + EXPECT_FALSE(message.IsInitialized()); + + message.mutable_repeated_message(0)->set_a(1); + message.mutable_repeated_message(0)->set_b(2); + message.mutable_repeated_message(0)->set_c(3); + EXPECT_TRUE(message.IsInitialized()); +} + +TEST(GeneratedMessageTest, ForeignNested) { + // Test that TestAllTypes::NestedMessage can be embedded directly into + // another message. + unittest::TestForeignNested message; + + // If this compiles and runs without crashing, it must work. We have + // nothing more to test. + unittest::TestAllTypes::NestedMessage* nested = + message.mutable_foreign_nested(); + nested->set_bb(1); +} + +TEST(GeneratedMessageTest, ReallyLargeTagNumber) { + // Test that really large tag numbers don't break anything. + unittest::TestReallyLargeTagNumber message1, message2; + string data; + + // For the most part, if this compiles and runs then we're probably good. + // (The most likely cause for failure would be if something were attempting + // to allocate a lookup table of some sort using tag numbers as the index.) + // We'll try serializing just for fun. + message1.set_a(1234); + message1.set_bb(5678); + message1.SerializeToString(&data); + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(1234, message2.a()); + EXPECT_EQ(5678, message2.bb()); +} + +TEST(GeneratedMessageTest, MutualRecursion) { + // Test that mutually-recursive message types work. + unittest::TestMutualRecursionA message; + unittest::TestMutualRecursionA* nested = message.mutable_bb()->mutable_a(); + unittest::TestMutualRecursionA* nested2 = nested->mutable_bb()->mutable_a(); + + // Again, if the above compiles and runs, that's all we really have to + // test, but just for run we'll check that the system didn't somehow come + // up with a pointer loop... + EXPECT_NE(&message, nested); + EXPECT_NE(&message, nested2); + EXPECT_NE(nested, nested2); +} + +TEST(GeneratedMessageTest, CamelCaseFieldNames) { + // This test is mainly checking that the following compiles, which verifies + // that the field names were coerced to lower-case. + // + // Protocol buffers standard style is to use lowercase-with-underscores for + // field names. Some old proto1 .protos unfortunately used camel-case field + // names. In proto1, these names were forced to lower-case. So, we do the + // same thing in proto2. + + unittest::TestCamelCaseFieldNames message; + + message.set_primitivefield(2); + message.set_stringfield("foo"); + message.set_enumfield(unittest::FOREIGN_FOO); + message.mutable_messagefield()->set_c(6); + + message.add_repeatedprimitivefield(8); + message.add_repeatedstringfield("qux"); + message.add_repeatedenumfield(unittest::FOREIGN_BAR); + message.add_repeatedmessagefield()->set_c(15); + + EXPECT_EQ(2, message.primitivefield()); + EXPECT_EQ("foo", message.stringfield()); + EXPECT_EQ(unittest::FOREIGN_FOO, message.enumfield()); + EXPECT_EQ(6, message.messagefield().c()); + + EXPECT_EQ(8, message.repeatedprimitivefield(0)); + EXPECT_EQ("qux", message.repeatedstringfield(0)); + EXPECT_EQ(unittest::FOREIGN_BAR, message.repeatedenumfield(0)); + EXPECT_EQ(15, message.repeatedmessagefield(0).c()); +} + +TEST(GeneratedMessageTest, TestConflictingSymbolNames) { + // test_bad_identifiers.proto successfully compiled, then it works. The + // following is just a token usage to insure that the code is, in fact, + // being compiled and linked. + + protobuf_unittest::TestConflictingSymbolNames message; + message.set_uint32(1); + EXPECT_EQ(3, message.ByteSize()); + + message.set_friend_(5); + EXPECT_EQ(5, message.friend_()); + + // Instantiate extension template functions to test conflicting template + // parameter names. + typedef protobuf_unittest::TestConflictingSymbolNamesExtension ExtensionMessage; + message.AddExtension(ExtensionMessage::repeated_int32_ext, 123); + EXPECT_EQ(123, + message.GetExtension(ExtensionMessage::repeated_int32_ext, 0)); +} + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + +TEST(GeneratedMessageTest, TestOptimizedForSize) { + // We rely on the tests in reflection_ops_unittest and wire_format_unittest + // to really test that reflection-based methods work. Here we are mostly + // just making sure that TestOptimizedForSize actually builds and seems to + // function. + + protobuf_unittest::TestOptimizedForSize message, message2; + message.set_i(1); + message.mutable_msg()->set_c(2); + message2.CopyFrom(message); + EXPECT_EQ(1, message2.i()); + EXPECT_EQ(2, message2.msg().c()); +} + +TEST(GeneratedMessageTest, TestEmbedOptimizedForSize) { + // Verifies that something optimized for speed can contain something optimized + // for size. + + protobuf_unittest::TestEmbedOptimizedForSize message, message2; + message.mutable_optional_message()->set_i(1); + message.add_repeated_message()->mutable_msg()->set_c(2); + string data; + message.SerializeToString(&data); + ASSERT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(1, message2.optional_message().i()); + EXPECT_EQ(2, message2.repeated_message(0).msg().c()); +} + +TEST(GeneratedMessageTest, TestSpaceUsed) { + unittest::TestAllTypes message1; + // sizeof provides a lower bound on SpaceUsed(). + EXPECT_LE(sizeof(unittest::TestAllTypes), message1.SpaceUsed()); + const int empty_message_size = message1.SpaceUsed(); + + // Setting primitive types shouldn't affect the space used. + message1.set_optional_int32(123); + message1.set_optional_int64(12345); + message1.set_optional_uint32(123); + message1.set_optional_uint64(12345); + EXPECT_EQ(empty_message_size, message1.SpaceUsed()); + + // On some STL implementations, setting the string to a small value should + // only increase SpaceUsed() by the size of a string object, though this is + // not true everywhere. + message1.set_optional_string("abc"); + EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsed()); + + // Setting a string to a value larger than the string object itself should + // increase SpaceUsed(), because it cannot store the value internally. + message1.set_optional_string(string(sizeof(string) + 1, 'x')); + int min_expected_increase = message1.optional_string().capacity() + + sizeof(string); + EXPECT_LE(empty_message_size + min_expected_increase, + message1.SpaceUsed()); + + int previous_size = message1.SpaceUsed(); + // Adding an optional message should increase the size by the size of the + // nested message type. NestedMessage is simple enough (1 int field) that it + // is equal to sizeof(NestedMessage) + message1.mutable_optional_nested_message(); + ASSERT_EQ(sizeof(unittest::TestAllTypes::NestedMessage), + message1.optional_nested_message().SpaceUsed()); + EXPECT_EQ(previous_size + + sizeof(unittest::TestAllTypes::NestedMessage), + message1.SpaceUsed()); +} + +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS + + +TEST(GeneratedMessageTest, FieldConstantValues) { + unittest::TestRequired message; + EXPECT_EQ(unittest::TestAllTypes_NestedMessage::kBbFieldNumber, 1); + EXPECT_EQ(unittest::TestAllTypes::kOptionalInt32FieldNumber, 1); + EXPECT_EQ(unittest::TestAllTypes::kOptionalgroupFieldNumber, 16); + EXPECT_EQ(unittest::TestAllTypes::kOptionalNestedMessageFieldNumber, 18); + EXPECT_EQ(unittest::TestAllTypes::kOptionalNestedEnumFieldNumber, 21); + EXPECT_EQ(unittest::TestAllTypes::kRepeatedInt32FieldNumber, 31); + EXPECT_EQ(unittest::TestAllTypes::kRepeatedgroupFieldNumber, 46); + EXPECT_EQ(unittest::TestAllTypes::kRepeatedNestedMessageFieldNumber, 48); + EXPECT_EQ(unittest::TestAllTypes::kRepeatedNestedEnumFieldNumber, 51); +} + +TEST(GeneratedMessageTest, ExtensionConstantValues) { + EXPECT_EQ(unittest::TestRequired::kSingleFieldNumber, 1000); + EXPECT_EQ(unittest::TestRequired::kMultiFieldNumber, 1001); + EXPECT_EQ(unittest::kOptionalInt32ExtensionFieldNumber, 1); + EXPECT_EQ(unittest::kOptionalgroupExtensionFieldNumber, 16); + EXPECT_EQ(unittest::kOptionalNestedMessageExtensionFieldNumber, 18); + EXPECT_EQ(unittest::kOptionalNestedEnumExtensionFieldNumber, 21); + EXPECT_EQ(unittest::kRepeatedInt32ExtensionFieldNumber, 31); + EXPECT_EQ(unittest::kRepeatedgroupExtensionFieldNumber, 46); + EXPECT_EQ(unittest::kRepeatedNestedMessageExtensionFieldNumber, 48); + EXPECT_EQ(unittest::kRepeatedNestedEnumExtensionFieldNumber, 51); +} + +// =================================================================== + +TEST(GeneratedEnumTest, EnumValuesAsSwitchCases) { + // Test that our nested enum values can be used as switch cases. This test + // doesn't actually do anything, the proof that it works is that it + // compiles. + int i =0; + unittest::TestAllTypes::NestedEnum a = unittest::TestAllTypes::BAR; + switch (a) { + case unittest::TestAllTypes::FOO: + i = 1; + break; + case unittest::TestAllTypes::BAR: + i = 2; + break; + case unittest::TestAllTypes::BAZ: + i = 3; + break; + // no default case: We want to make sure the compiler recognizes that + // all cases are covered. (GCC warns if you do not cover all cases of + // an enum in a switch.) + } + + // Token check just for fun. + EXPECT_EQ(2, i); +} + +TEST(GeneratedEnumTest, IsValidValue) { + // Test enum IsValidValue. + EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(1)); + EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(2)); + EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(3)); + + EXPECT_FALSE(unittest::TestAllTypes::NestedEnum_IsValid(0)); + EXPECT_FALSE(unittest::TestAllTypes::NestedEnum_IsValid(4)); + + // Make sure it also works when there are dups. + EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(1)); + EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(2)); + EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(3)); + + EXPECT_FALSE(unittest::TestEnumWithDupValue_IsValid(0)); + EXPECT_FALSE(unittest::TestEnumWithDupValue_IsValid(4)); +} + +TEST(GeneratedEnumTest, MinAndMax) { + EXPECT_EQ(unittest::TestAllTypes::FOO, + unittest::TestAllTypes::NestedEnum_MIN); + EXPECT_EQ(unittest::TestAllTypes::BAZ, + unittest::TestAllTypes::NestedEnum_MAX); + EXPECT_EQ(4, unittest::TestAllTypes::NestedEnum_ARRAYSIZE); + + EXPECT_EQ(unittest::FOREIGN_FOO, unittest::ForeignEnum_MIN); + EXPECT_EQ(unittest::FOREIGN_BAZ, unittest::ForeignEnum_MAX); + EXPECT_EQ(7, unittest::ForeignEnum_ARRAYSIZE); + + EXPECT_EQ(1, unittest::TestEnumWithDupValue_MIN); + EXPECT_EQ(3, unittest::TestEnumWithDupValue_MAX); + EXPECT_EQ(4, unittest::TestEnumWithDupValue_ARRAYSIZE); + + EXPECT_EQ(unittest::SPARSE_E, unittest::TestSparseEnum_MIN); + EXPECT_EQ(unittest::SPARSE_C, unittest::TestSparseEnum_MAX); + EXPECT_EQ(12589235, unittest::TestSparseEnum_ARRAYSIZE); + + // Make sure we can take the address of _MIN, _MAX and _ARRAYSIZE. + void* null_pointer = 0; // NULL may be integer-type, not pointer-type. + EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MIN); + EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MAX); + EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_ARRAYSIZE); + + EXPECT_NE(null_pointer, &unittest::ForeignEnum_MIN); + EXPECT_NE(null_pointer, &unittest::ForeignEnum_MAX); + EXPECT_NE(null_pointer, &unittest::ForeignEnum_ARRAYSIZE); + + // Make sure we can use _MIN and _MAX as switch cases. + switch (unittest::SPARSE_A) { + case unittest::TestSparseEnum_MIN: + case unittest::TestSparseEnum_MAX: + break; + default: + break; + } +} + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + +TEST(GeneratedEnumTest, Name) { + // "Names" in the presence of dup values are a bit arbitrary. + EXPECT_EQ("FOO1", unittest::TestEnumWithDupValue_Name(unittest::FOO1)); + EXPECT_EQ("FOO1", unittest::TestEnumWithDupValue_Name(unittest::FOO2)); + + EXPECT_EQ("SPARSE_A", unittest::TestSparseEnum_Name(unittest::SPARSE_A)); + EXPECT_EQ("SPARSE_B", unittest::TestSparseEnum_Name(unittest::SPARSE_B)); + EXPECT_EQ("SPARSE_C", unittest::TestSparseEnum_Name(unittest::SPARSE_C)); + EXPECT_EQ("SPARSE_D", unittest::TestSparseEnum_Name(unittest::SPARSE_D)); + EXPECT_EQ("SPARSE_E", unittest::TestSparseEnum_Name(unittest::SPARSE_E)); + EXPECT_EQ("SPARSE_F", unittest::TestSparseEnum_Name(unittest::SPARSE_F)); + EXPECT_EQ("SPARSE_G", unittest::TestSparseEnum_Name(unittest::SPARSE_G)); +} + +TEST(GeneratedEnumTest, Parse) { + unittest::TestEnumWithDupValue dup_value = unittest::FOO1; + EXPECT_TRUE(unittest::TestEnumWithDupValue_Parse("FOO1", &dup_value)); + EXPECT_EQ(unittest::FOO1, dup_value); + EXPECT_TRUE(unittest::TestEnumWithDupValue_Parse("FOO2", &dup_value)); + EXPECT_EQ(unittest::FOO2, dup_value); + EXPECT_FALSE(unittest::TestEnumWithDupValue_Parse("FOO", &dup_value)); +} + +TEST(GeneratedEnumTest, GetEnumDescriptor) { + EXPECT_EQ(unittest::TestAllTypes::NestedEnum_descriptor(), + GetEnumDescriptor()); + EXPECT_EQ(unittest::ForeignEnum_descriptor(), + GetEnumDescriptor()); + EXPECT_EQ(unittest::TestEnumWithDupValue_descriptor(), + GetEnumDescriptor()); + EXPECT_EQ(unittest::TestSparseEnum_descriptor(), + GetEnumDescriptor()); +} + +#endif // PROTOBUF_TEST_NO_DESCRIPTORS + +// =================================================================== + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + +// Support code for testing services. +class GeneratedServiceTest : public testing::Test { + protected: + class MockTestService : public unittest::TestService { + public: + MockTestService() + : called_(false), + method_(""), + controller_(NULL), + request_(NULL), + response_(NULL), + done_(NULL) {} + + ~MockTestService() {} + + void Reset() { called_ = false; } + + // implements TestService ---------------------------------------- + + void Foo(RpcController* controller, + const unittest::FooRequest* request, + unittest::FooResponse* response, + Closure* done) { + ASSERT_FALSE(called_); + called_ = true; + method_ = "Foo"; + controller_ = controller; + request_ = request; + response_ = response; + done_ = done; + } + + void Bar(RpcController* controller, + const unittest::BarRequest* request, + unittest::BarResponse* response, + Closure* done) { + ASSERT_FALSE(called_); + called_ = true; + method_ = "Bar"; + controller_ = controller; + request_ = request; + response_ = response; + done_ = done; + } + + // --------------------------------------------------------------- + + bool called_; + string method_; + RpcController* controller_; + const Message* request_; + Message* response_; + Closure* done_; + }; + + class MockRpcChannel : public RpcChannel { + public: + MockRpcChannel() + : called_(false), + method_(NULL), + controller_(NULL), + request_(NULL), + response_(NULL), + done_(NULL), + destroyed_(NULL) {} + + ~MockRpcChannel() { + if (destroyed_ != NULL) *destroyed_ = true; + } + + void Reset() { called_ = false; } + + // implements TestService ---------------------------------------- + + void CallMethod(const MethodDescriptor* method, + RpcController* controller, + const Message* request, + Message* response, + Closure* done) { + ASSERT_FALSE(called_); + called_ = true; + method_ = method; + controller_ = controller; + request_ = request; + response_ = response; + done_ = done; + } + + // --------------------------------------------------------------- + + bool called_; + const MethodDescriptor* method_; + RpcController* controller_; + const Message* request_; + Message* response_; + Closure* done_; + bool* destroyed_; + }; + + class MockController : public RpcController { + public: + void Reset() { + ADD_FAILURE() << "Reset() not expected during this test."; + } + bool Failed() const { + ADD_FAILURE() << "Failed() not expected during this test."; + return false; + } + string ErrorText() const { + ADD_FAILURE() << "ErrorText() not expected during this test."; + return ""; + } + void StartCancel() { + ADD_FAILURE() << "StartCancel() not expected during this test."; + } + void SetFailed(const string& reason) { + ADD_FAILURE() << "SetFailed() not expected during this test."; + } + bool IsCanceled() const { + ADD_FAILURE() << "IsCanceled() not expected during this test."; + return false; + } + void NotifyOnCancel(Closure* callback) { + ADD_FAILURE() << "NotifyOnCancel() not expected during this test."; + } + }; + + GeneratedServiceTest() + : descriptor_(unittest::TestService::descriptor()), + foo_(descriptor_->FindMethodByName("Foo")), + bar_(descriptor_->FindMethodByName("Bar")), + stub_(&mock_channel_), + done_(NewPermanentCallback(&DoNothing)) {} + + virtual void SetUp() { + ASSERT_TRUE(foo_ != NULL); + ASSERT_TRUE(bar_ != NULL); + } + + const ServiceDescriptor* descriptor_; + const MethodDescriptor* foo_; + const MethodDescriptor* bar_; + + MockTestService mock_service_; + MockController mock_controller_; + + MockRpcChannel mock_channel_; + unittest::TestService::Stub stub_; + + // Just so we don't have to re-define these with every test. + unittest::FooRequest foo_request_; + unittest::FooResponse foo_response_; + unittest::BarRequest bar_request_; + unittest::BarResponse bar_response_; + scoped_ptr done_; +}; + +TEST_F(GeneratedServiceTest, GetDescriptor) { + // Test that GetDescriptor() works. + + EXPECT_EQ(descriptor_, mock_service_.GetDescriptor()); +} + +TEST_F(GeneratedServiceTest, GetChannel) { + EXPECT_EQ(&mock_channel_, stub_.channel()); +} + +TEST_F(GeneratedServiceTest, OwnsChannel) { + MockRpcChannel* channel = new MockRpcChannel; + bool destroyed = false; + channel->destroyed_ = &destroyed; + + { + unittest::TestService::Stub owning_stub(channel, + Service::STUB_OWNS_CHANNEL); + EXPECT_FALSE(destroyed); + } + + EXPECT_TRUE(destroyed); +} + +TEST_F(GeneratedServiceTest, CallMethod) { + // Test that CallMethod() works. + + // Call Foo() via CallMethod(). + mock_service_.CallMethod(foo_, &mock_controller_, + &foo_request_, &foo_response_, done_.get()); + + ASSERT_TRUE(mock_service_.called_); + + EXPECT_EQ("Foo" , mock_service_.method_ ); + EXPECT_EQ(&mock_controller_, mock_service_.controller_); + EXPECT_EQ(&foo_request_ , mock_service_.request_ ); + EXPECT_EQ(&foo_response_ , mock_service_.response_ ); + EXPECT_EQ(done_.get() , mock_service_.done_ ); + + // Try again, but call Bar() instead. + mock_service_.Reset(); + mock_service_.CallMethod(bar_, &mock_controller_, + &bar_request_, &bar_response_, done_.get()); + + ASSERT_TRUE(mock_service_.called_); + EXPECT_EQ("Bar", mock_service_.method_); +} + +TEST_F(GeneratedServiceTest, CallMethodTypeFailure) { + // Verify death if we call Foo() with Bar's message types. + +#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet + EXPECT_DEBUG_DEATH( + mock_service_.CallMethod(foo_, &mock_controller_, + &foo_request_, &bar_response_, done_.get()), + "dynamic_cast"); + + mock_service_.Reset(); + EXPECT_DEBUG_DEATH( + mock_service_.CallMethod(foo_, &mock_controller_, + &bar_request_, &foo_response_, done_.get()), + "dynamic_cast"); +#endif // PROTOBUF_HAS_DEATH_TEST +} + +TEST_F(GeneratedServiceTest, GetPrototypes) { + // Test Get{Request,Response}Prototype() methods. + + EXPECT_EQ(&unittest::FooRequest::default_instance(), + &mock_service_.GetRequestPrototype(foo_)); + EXPECT_EQ(&unittest::BarRequest::default_instance(), + &mock_service_.GetRequestPrototype(bar_)); + + EXPECT_EQ(&unittest::FooResponse::default_instance(), + &mock_service_.GetResponsePrototype(foo_)); + EXPECT_EQ(&unittest::BarResponse::default_instance(), + &mock_service_.GetResponsePrototype(bar_)); +} + +TEST_F(GeneratedServiceTest, Stub) { + // Test that the stub class works. + + // Call Foo() via the stub. + stub_.Foo(&mock_controller_, &foo_request_, &foo_response_, done_.get()); + + ASSERT_TRUE(mock_channel_.called_); + + EXPECT_EQ(foo_ , mock_channel_.method_ ); + EXPECT_EQ(&mock_controller_, mock_channel_.controller_); + EXPECT_EQ(&foo_request_ , mock_channel_.request_ ); + EXPECT_EQ(&foo_response_ , mock_channel_.response_ ); + EXPECT_EQ(done_.get() , mock_channel_.done_ ); + + // Call Bar() via the stub. + mock_channel_.Reset(); + stub_.Bar(&mock_controller_, &bar_request_, &bar_response_, done_.get()); + + ASSERT_TRUE(mock_channel_.called_); + EXPECT_EQ(bar_, mock_channel_.method_); +} + +TEST_F(GeneratedServiceTest, NotImplemented) { + // Test that failing to implement a method of a service causes it to fail + // with a "not implemented" error message. + + // A service which doesn't implement any methods. + class UnimplementedService : public unittest::TestService { + public: + UnimplementedService() {} + }; + + UnimplementedService unimplemented_service; + + // And a controller which expects to get a "not implemented" error. + class ExpectUnimplementedController : public MockController { + public: + ExpectUnimplementedController() : called_(false) {} + + void SetFailed(const string& reason) { + EXPECT_FALSE(called_); + called_ = true; + EXPECT_EQ("Method Foo() not implemented.", reason); + } + + bool called_; + }; + + ExpectUnimplementedController controller; + + // Call Foo. + unimplemented_service.Foo(&controller, &foo_request_, &foo_response_, + done_.get()); + + EXPECT_TRUE(controller.called_); +} + +} // namespace cpp_unittest +} // namespace cpp +} // namespace compiler + +namespace no_generic_services_test { + // Verify that no class called "TestService" was defined in + // unittest_no_generic_services.pb.h by defining a different type by the same + // name. If such a service was generated, this will not compile. + struct TestService { + int i; + }; +} + +namespace compiler { +namespace cpp { +namespace cpp_unittest { + +TEST_F(GeneratedServiceTest, NoGenericServices) { + // Verify that non-services in unittest_no_generic_services.proto were + // generated. + no_generic_services_test::TestMessage message; + message.set_a(1); + message.SetExtension(no_generic_services_test::test_extension, 123); + no_generic_services_test::TestEnum e = no_generic_services_test::FOO; + EXPECT_EQ(e, 1); + + // Verify that a ServiceDescriptor is generated for the service even if the + // class itself is not. + const FileDescriptor* file = + no_generic_services_test::TestMessage::descriptor()->file(); + + ASSERT_EQ(1, file->service_count()); + EXPECT_EQ("TestService", file->service(0)->name()); + ASSERT_EQ(1, file->service(0)->method_count()); + EXPECT_EQ("Foo", file->service(0)->method(0)->name()); +} + +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS + +// =================================================================== + +// This test must run last. It verifies that descriptors were or were not +// initialized depending on whether PROTOBUF_TEST_NO_DESCRIPTORS was defined. +// When this is defined, we skip all tests which are expected to trigger +// descriptor initialization. This verifies that everything else still works +// if descriptors are not initialized. +TEST(DescriptorInitializationTest, Initialized) { +#ifdef PROTOBUF_TEST_NO_DESCRIPTORS + bool should_have_descriptors = false; +#else + bool should_have_descriptors = true; +#endif + + EXPECT_EQ(should_have_descriptors, + DescriptorPool::generated_pool()->InternalIsFileLoaded( + "google/protobuf/unittest.proto")); +} + +} // namespace cpp_unittest + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_unittest.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_unittest.h new file mode 100644 index 0000000..a3a1d1b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/cpp/cpp_unittest.h @@ -0,0 +1,51 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This header declares the namespace google::protobuf::protobuf_unittest in order to expose +// any problems with the generated class names. We use this header to ensure +// unittest.cc will declare the namespace prior to other includes, while obeying +// normal include ordering. +// +// When generating a class name of "foo.Bar" we must ensure we prefix the class +// name with "::", in case the namespace google::protobuf::foo exists. We intentionally +// trigger that case here by declaring google::protobuf::protobuf_unittest. +// +// See ClassName in helpers.h for more details. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__ + +namespace google { +namespace protobuf { +namespace protobuf_unittest {} +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer.cc new file mode 100644 index 0000000..422f759 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer.cc @@ -0,0 +1,459 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifdef _MSC_VER +#include +#else +#include +#endif +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { + +#ifdef _WIN32 +#ifndef F_OK +#define F_OK 00 // not defined by MSVC for whatever reason +#endif +#include +#endif + +// Returns true if the text looks like a Windows-style absolute path, starting +// with a drive letter. Example: "C:\foo". TODO(kenton): Share this with +// copy in command_line_interface.cc? +static bool IsWindowsAbsolutePath(const string& text) { +#if defined(_WIN32) || defined(__CYGWIN__) + return text.size() >= 3 && text[1] == ':' && + isalpha(text[0]) && + (text[2] == '/' || text[2] == '\\') && + text.find_last_of(':') == 1; +#else + return false; +#endif +} + +MultiFileErrorCollector::~MultiFileErrorCollector() {} + +// This class serves two purposes: +// - It implements the ErrorCollector interface (used by Tokenizer and Parser) +// in terms of MultiFileErrorCollector, using a particular filename. +// - It lets us check if any errors have occurred. +class SourceTreeDescriptorDatabase::SingleFileErrorCollector + : public io::ErrorCollector { + public: + SingleFileErrorCollector(const string& filename, + MultiFileErrorCollector* multi_file_error_collector) + : filename_(filename), + multi_file_error_collector_(multi_file_error_collector), + had_errors_(false) {} + ~SingleFileErrorCollector() {} + + bool had_errors() { return had_errors_; } + + // implements ErrorCollector --------------------------------------- + void AddError(int line, int column, const string& message) { + if (multi_file_error_collector_ != NULL) { + multi_file_error_collector_->AddError(filename_, line, column, message); + } + had_errors_ = true; + } + + private: + string filename_; + MultiFileErrorCollector* multi_file_error_collector_; + bool had_errors_; +}; + +// =================================================================== + +SourceTreeDescriptorDatabase::SourceTreeDescriptorDatabase( + SourceTree* source_tree) + : source_tree_(source_tree), + error_collector_(NULL), + using_validation_error_collector_(false), + validation_error_collector_(this) {} + +SourceTreeDescriptorDatabase::~SourceTreeDescriptorDatabase() {} + +bool SourceTreeDescriptorDatabase::FindFileByName( + const string& filename, FileDescriptorProto* output) { + scoped_ptr input(source_tree_->Open(filename)); + if (input == NULL) { + if (error_collector_ != NULL) { + error_collector_->AddError(filename, -1, 0, "File not found."); + } + return false; + } + + // Set up the tokenizer and parser. + SingleFileErrorCollector file_error_collector(filename, error_collector_); + io::Tokenizer tokenizer(input.get(), &file_error_collector); + + Parser parser; + if (error_collector_ != NULL) { + parser.RecordErrorsTo(&file_error_collector); + } + if (using_validation_error_collector_) { + parser.RecordSourceLocationsTo(&source_locations_); + } + + // Parse it. + output->set_name(filename); + return parser.Parse(&tokenizer, output) && + !file_error_collector.had_errors(); +} + +bool SourceTreeDescriptorDatabase::FindFileContainingSymbol( + const string& symbol_name, FileDescriptorProto* output) { + return false; +} + +bool SourceTreeDescriptorDatabase::FindFileContainingExtension( + const string& containing_type, int field_number, + FileDescriptorProto* output) { + return false; +} + +// ------------------------------------------------------------------- + +SourceTreeDescriptorDatabase::ValidationErrorCollector:: +ValidationErrorCollector(SourceTreeDescriptorDatabase* owner) + : owner_(owner) {} + +SourceTreeDescriptorDatabase::ValidationErrorCollector:: +~ValidationErrorCollector() {} + +void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddError( + const string& filename, + const string& element_name, + const Message* descriptor, + ErrorLocation location, + const string& message) { + if (owner_->error_collector_ == NULL) return; + + int line, column; + owner_->source_locations_.Find(descriptor, location, &line, &column); + owner_->error_collector_->AddError(filename, line, column, message); +} + +// =================================================================== + +Importer::Importer(SourceTree* source_tree, + MultiFileErrorCollector* error_collector) + : database_(source_tree), + pool_(&database_, database_.GetValidationErrorCollector()) { + database_.RecordErrorsTo(error_collector); +} + +Importer::~Importer() {} + +const FileDescriptor* Importer::Import(const string& filename) { + return pool_.FindFileByName(filename); +} + +// =================================================================== + +SourceTree::~SourceTree() {} + +DiskSourceTree::DiskSourceTree() {} + +DiskSourceTree::~DiskSourceTree() {} + +static inline char LastChar(const string& str) { + return str[str.size() - 1]; +} + +// Given a path, returns an equivalent path with these changes: +// - On Windows, any backslashes are replaced with forward slashes. +// - Any instances of the directory "." are removed. +// - Any consecutive '/'s are collapsed into a single slash. +// Note that the resulting string may be empty. +// +// TODO(kenton): It would be nice to handle "..", e.g. so that we can figure +// out that "foo/bar.proto" is inside "baz/../foo". However, if baz is a +// symlink or doesn't exist, then things get complicated, and we can't +// actually determine this without investigating the filesystem, probably +// in non-portable ways. So, we punt. +// +// TODO(kenton): It would be nice to use realpath() here except that it +// resolves symbolic links. This could cause problems if people place +// symbolic links in their source tree. For example, if you executed: +// protoc --proto_path=foo foo/bar/baz.proto +// then if foo/bar is a symbolic link, foo/bar/baz.proto will canonicalize +// to a path which does not appear to be under foo, and thus the compiler +// will complain that baz.proto is not inside the --proto_path. +static string CanonicalizePath(string path) { +#ifdef _WIN32 + // The Win32 API accepts forward slashes as a path delimiter even though + // backslashes are standard. Let's avoid confusion and use only forward + // slashes. + if (HasPrefixString(path, "\\\\")) { + // Avoid converting two leading backslashes. + path = "\\\\" + StringReplace(path.substr(2), "\\", "/", true); + } else { + path = StringReplace(path, "\\", "/", true); + } +#endif + + vector parts; + vector canonical_parts; + SplitStringUsing(path, "/", &parts); // Note: Removes empty parts. + for (int i = 0; i < parts.size(); i++) { + if (parts[i] == ".") { + // Ignore. + } else { + canonical_parts.push_back(parts[i]); + } + } + string result = JoinStrings(canonical_parts, "/"); + if (!path.empty() && path[0] == '/') { + // Restore leading slash. + result = '/' + result; + } + if (!path.empty() && LastChar(path) == '/' && + !result.empty() && LastChar(result) != '/') { + // Restore trailing slash. + result += '/'; + } + return result; +} + +static inline bool ContainsParentReference(const string& path) { + return path == ".." || + HasPrefixString(path, "../") || + HasSuffixString(path, "/..") || + path.find("/../") != string::npos; +} + +// Maps a file from an old location to a new one. Typically, old_prefix is +// a virtual path and new_prefix is its corresponding disk path. Returns +// false if the filename did not start with old_prefix, otherwise replaces +// old_prefix with new_prefix and stores the result in *result. Examples: +// string result; +// assert(ApplyMapping("foo/bar", "", "baz", &result)); +// assert(result == "baz/foo/bar"); +// +// assert(ApplyMapping("foo/bar", "foo", "baz", &result)); +// assert(result == "baz/bar"); +// +// assert(ApplyMapping("foo", "foo", "bar", &result)); +// assert(result == "bar"); +// +// assert(!ApplyMapping("foo/bar", "baz", "qux", &result)); +// assert(!ApplyMapping("foo/bar", "baz", "qux", &result)); +// assert(!ApplyMapping("foobar", "foo", "baz", &result)); +static bool ApplyMapping(const string& filename, + const string& old_prefix, + const string& new_prefix, + string* result) { + if (old_prefix.empty()) { + // old_prefix matches any relative path. + if (ContainsParentReference(filename)) { + // We do not allow the file name to use "..". + return false; + } + if (HasPrefixString(filename, "/") || + IsWindowsAbsolutePath(filename)) { + // This is an absolute path, so it isn't matched by the empty string. + return false; + } + result->assign(new_prefix); + if (!result->empty()) result->push_back('/'); + result->append(filename); + return true; + } else if (HasPrefixString(filename, old_prefix)) { + // old_prefix is a prefix of the filename. Is it the whole filename? + if (filename.size() == old_prefix.size()) { + // Yep, it's an exact match. + *result = new_prefix; + return true; + } else { + // Not an exact match. Is the next character a '/'? Otherwise, + // this isn't actually a match at all. E.g. the prefix "foo/bar" + // does not match the filename "foo/barbaz". + int after_prefix_start = -1; + if (filename[old_prefix.size()] == '/') { + after_prefix_start = old_prefix.size() + 1; + } else if (filename[old_prefix.size() - 1] == '/') { + // old_prefix is never empty, and canonicalized paths never have + // consecutive '/' characters. + after_prefix_start = old_prefix.size(); + } + if (after_prefix_start != -1) { + // Yep. So the prefixes are directories and the filename is a file + // inside them. + string after_prefix = filename.substr(after_prefix_start); + if (ContainsParentReference(after_prefix)) { + // We do not allow the file name to use "..". + return false; + } + result->assign(new_prefix); + if (!result->empty()) result->push_back('/'); + result->append(after_prefix); + return true; + } + } + } + + return false; +} + +void DiskSourceTree::MapPath(const string& virtual_path, + const string& disk_path) { + mappings_.push_back(Mapping(virtual_path, CanonicalizePath(disk_path))); +} + +DiskSourceTree::DiskFileToVirtualFileResult +DiskSourceTree::DiskFileToVirtualFile( + const string& disk_file, + string* virtual_file, + string* shadowing_disk_file) { + int mapping_index = -1; + string canonical_disk_file = CanonicalizePath(disk_file); + + for (int i = 0; i < mappings_.size(); i++) { + // Apply the mapping in reverse. + if (ApplyMapping(canonical_disk_file, mappings_[i].disk_path, + mappings_[i].virtual_path, virtual_file)) { + // Success. + mapping_index = i; + break; + } + } + + if (mapping_index == -1) { + return NO_MAPPING; + } + + // Iterate through all mappings with higher precedence and verify that none + // of them map this file to some other existing file. + for (int i = 0; i < mapping_index; i++) { + if (ApplyMapping(*virtual_file, mappings_[i].virtual_path, + mappings_[i].disk_path, shadowing_disk_file)) { + if (access(shadowing_disk_file->c_str(), F_OK) >= 0) { + // File exists. + return SHADOWED; + } + } + } + shadowing_disk_file->clear(); + + // Verify that we can open the file. Note that this also has the side-effect + // of verifying that we are not canonicalizing away any non-existent + // directories. + scoped_ptr stream(OpenDiskFile(disk_file)); + if (stream == NULL) { + return CANNOT_OPEN; + } + + return SUCCESS; +} + +bool DiskSourceTree::VirtualFileToDiskFile(const string& virtual_file, + string* disk_file) { + scoped_ptr stream(OpenVirtualFile(virtual_file, + disk_file)); + return stream != NULL; +} + +io::ZeroCopyInputStream* DiskSourceTree::Open(const string& filename) { + return OpenVirtualFile(filename, NULL); +} + +io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile( + const string& virtual_file, + string* disk_file) { + if (virtual_file != CanonicalizePath(virtual_file) || + ContainsParentReference(virtual_file)) { + // We do not allow importing of paths containing things like ".." or + // consecutive slashes since the compiler expects files to be uniquely + // identified by file name. + return NULL; + } + + for (int i = 0; i < mappings_.size(); i++) { + string temp_disk_file; + if (ApplyMapping(virtual_file, mappings_[i].virtual_path, + mappings_[i].disk_path, &temp_disk_file)) { + io::ZeroCopyInputStream* stream = OpenDiskFile(temp_disk_file); + if (stream != NULL) { + if (disk_file != NULL) { + *disk_file = temp_disk_file; + } + return stream; + } + + if (errno == EACCES) { + // The file exists but is not readable. + // TODO(kenton): Find a way to report this more nicely. + GOOGLE_LOG(WARNING) << "Read access is denied for file: " << temp_disk_file; + return NULL; + } + } + } + + return NULL; +} + +io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( + const string& filename) { + int file_descriptor; + do { + file_descriptor = open(filename.c_str(), O_RDONLY); + } while (file_descriptor < 0 && errno == EINTR); + if (file_descriptor >= 0) { + io::FileInputStream* result = new io::FileInputStream(file_descriptor); + result->SetCloseOnDelete(true); + return result; + } else { + return NULL; + } +} + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer.h new file mode 100644 index 0000000..7a62fa0 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer.h @@ -0,0 +1,304 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file is the public interface to the .proto file parser. + +#ifndef GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__ +#define GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__ + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +namespace io { class ZeroCopyInputStream; } + +namespace compiler { + +// Defined in this file. +class Importer; +class MultiFileErrorCollector; +class SourceTree; +class DiskSourceTree; + +// TODO(kenton): Move all SourceTree stuff to a separate file? + +// An implementation of DescriptorDatabase which loads files from a SourceTree +// and parses them. +// +// Note: This class is not thread-safe since it maintains a table of source +// code locations for error reporting. However, when a DescriptorPool wraps +// a DescriptorDatabase, it uses mutex locking to make sure only one method +// of the database is called at a time, even if the DescriptorPool is used +// from multiple threads. Therefore, there is only a problem if you create +// multiple DescriptorPools wrapping the same SourceTreeDescriptorDatabase +// and use them from multiple threads. +// +// Note: This class does not implement FindFileContainingSymbol() or +// FindFileContainingExtension(); these will always return false. +class LIBPROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase { + public: + SourceTreeDescriptorDatabase(SourceTree* source_tree); + ~SourceTreeDescriptorDatabase(); + + // Instructs the SourceTreeDescriptorDatabase to report any parse errors + // to the given MultiFileErrorCollector. This should be called before + // parsing. error_collector must remain valid until either this method + // is called again or the SourceTreeDescriptorDatabase is destroyed. + void RecordErrorsTo(MultiFileErrorCollector* error_collector) { + error_collector_ = error_collector; + } + + // Gets a DescriptorPool::ErrorCollector which records errors to the + // MultiFileErrorCollector specified with RecordErrorsTo(). This collector + // has the ability to determine exact line and column numbers of errors + // from the information given to it by the DescriptorPool. + DescriptorPool::ErrorCollector* GetValidationErrorCollector() { + using_validation_error_collector_ = true; + return &validation_error_collector_; + } + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const string& filename, FileDescriptorProto* output); + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output); + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output); + + private: + class SingleFileErrorCollector; + + SourceTree* source_tree_; + MultiFileErrorCollector* error_collector_; + + class LIBPROTOBUF_EXPORT ValidationErrorCollector : public DescriptorPool::ErrorCollector { + public: + ValidationErrorCollector(SourceTreeDescriptorDatabase* owner); + ~ValidationErrorCollector(); + + // implements ErrorCollector --------------------------------------- + void AddError(const string& filename, + const string& element_name, + const Message* descriptor, + ErrorLocation location, + const string& message); + + private: + SourceTreeDescriptorDatabase* owner_; + }; + friend class ValidationErrorCollector; + + bool using_validation_error_collector_; + SourceLocationTable source_locations_; + ValidationErrorCollector validation_error_collector_; +}; + +// Simple interface for parsing .proto files. This wraps the process +// of opening the file, parsing it with a Parser, recursively parsing all its +// imports, and then cross-linking the results to produce a FileDescriptor. +// +// This is really just a thin wrapper around SourceTreeDescriptorDatabase. +// You may find that SourceTreeDescriptorDatabase is more flexible. +// +// TODO(kenton): I feel like this class is not well-named. +class LIBPROTOBUF_EXPORT Importer { + public: + Importer(SourceTree* source_tree, + MultiFileErrorCollector* error_collector); + ~Importer(); + + // Import the given file and build a FileDescriptor representing it. If + // the file is already in the DescriptorPool, the existing FileDescriptor + // will be returned. The FileDescriptor is property of the DescriptorPool, + // and will remain valid until it is destroyed. If any errors occur, they + // will be reported using the error collector and Import() will return NULL. + // + // A particular Importer object will only report errors for a particular + // file once. All future attempts to import the same file will return NULL + // without reporting any errors. The idea is that you might want to import + // a lot of files without seeing the same errors over and over again. If + // you want to see errors for the same files repeatedly, you can use a + // separate Importer object to import each one (but use the same + // DescriptorPool so that they can be cross-linked). + const FileDescriptor* Import(const string& filename); + + // The DescriptorPool in which all imported FileDescriptors and their + // contents are stored. + inline const DescriptorPool* pool() const { + return &pool_; + } + + private: + SourceTreeDescriptorDatabase database_; + DescriptorPool pool_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Importer); +}; + +// If the importer encounters problems while trying to import the proto files, +// it reports them to a MultiFileErrorCollector. +class LIBPROTOBUF_EXPORT MultiFileErrorCollector { + public: + inline MultiFileErrorCollector() {} + virtual ~MultiFileErrorCollector(); + + // Line and column numbers are zero-based. A line number of -1 indicates + // an error with the entire file (e.g. "not found"). + virtual void AddError(const string& filename, int line, int column, + const string& message) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultiFileErrorCollector); +}; + +// Abstract interface which represents a directory tree containing proto files. +// Used by the default implementation of Importer to resolve import statements +// Most users will probably want to use the DiskSourceTree implementation, +// below. +class LIBPROTOBUF_EXPORT SourceTree { + public: + inline SourceTree() {} + virtual ~SourceTree(); + + // Open the given file and return a stream that reads it, or NULL if not + // found. The caller takes ownership of the returned object. The filename + // must be a path relative to the root of the source tree and must not + // contain "." or ".." components. + virtual io::ZeroCopyInputStream* Open(const string& filename) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceTree); +}; + +// An implementation of SourceTree which loads files from locations on disk. +// Multiple mappings can be set up to map locations in the DiskSourceTree to +// locations in the physical filesystem. +class LIBPROTOBUF_EXPORT DiskSourceTree : public SourceTree { + public: + DiskSourceTree(); + ~DiskSourceTree(); + + // Map a path on disk to a location in the SourceTree. The path may be + // either a file or a directory. If it is a directory, the entire tree + // under it will be mapped to the given virtual location. To map a directory + // to the root of the source tree, pass an empty string for virtual_path. + // + // If multiple mapped paths apply when opening a file, they will be searched + // in order. For example, if you do: + // MapPath("bar", "foo/bar"); + // MapPath("", "baz"); + // and then you do: + // Open("bar/qux"); + // the DiskSourceTree will first try to open foo/bar/qux, then baz/bar/qux, + // returning the first one that opens successfuly. + // + // disk_path may be an absolute path or relative to the current directory, + // just like a path you'd pass to open(). + void MapPath(const string& virtual_path, const string& disk_path); + + // Return type for DiskFileToVirtualFile(). + enum DiskFileToVirtualFileResult { + SUCCESS, + SHADOWED, + CANNOT_OPEN, + NO_MAPPING + }; + + // Given a path to a file on disk, find a virtual path mapping to that + // file. The first mapping created with MapPath() whose disk_path contains + // the filename is used. However, that virtual path may not actually be + // usable to open the given file. Possible return values are: + // * SUCCESS: The mapping was found. *virtual_file is filled in so that + // calling Open(*virtual_file) will open the file named by disk_file. + // * SHADOWED: A mapping was found, but using Open() to open this virtual + // path will end up returning some different file. This is because some + // other mapping with a higher precedence also matches this virtual path + // and maps it to a different file that exists on disk. *virtual_file + // is filled in as it would be in the SUCCESS case. *shadowing_disk_file + // is filled in with the disk path of the file which would be opened if + // you were to call Open(*virtual_file). + // * CANNOT_OPEN: The mapping was found and was not shadowed, but the + // file specified cannot be opened. When this value is returned, + // errno will indicate the reason the file cannot be opened. *virtual_file + // will be set to the virtual path as in the SUCCESS case, even though + // it is not useful. + // * NO_MAPPING: Indicates that no mapping was found which contains this + // file. + DiskFileToVirtualFileResult + DiskFileToVirtualFile(const string& disk_file, + string* virtual_file, + string* shadowing_disk_file); + + // Given a virtual path, find the path to the file on disk. + // Return true and update disk_file with the on-disk path if the file exists. + // Return false and leave disk_file untouched if the file doesn't exist. + bool VirtualFileToDiskFile(const string& virtual_file, string* disk_file); + + // implements SourceTree ------------------------------------------- + io::ZeroCopyInputStream* Open(const string& filename); + + private: + struct Mapping { + string virtual_path; + string disk_path; + + inline Mapping(const string& virtual_path_param, + const string& disk_path_param) + : virtual_path(virtual_path_param), disk_path(disk_path_param) {} + }; + vector mappings_; + + // Like Open(), but returns the on-disk path in disk_file if disk_file is + // non-NULL and the file could be successfully opened. + io::ZeroCopyInputStream* OpenVirtualFile(const string& virtual_file, + string* disk_file); + + // Like Open() but given the actual on-disk path. + io::ZeroCopyInputStream* OpenDiskFile(const string& filename); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DiskSourceTree); +}; + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer_unittest.cc new file mode 100644 index 0000000..56fad56 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/importer_unittest.cc @@ -0,0 +1,600 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { + +namespace { + +#define EXPECT_SUBSTRING(needle, haystack) \ + EXPECT_PRED_FORMAT2(testing::IsSubstring, (needle), (haystack)) + +class MockErrorCollector : public MultiFileErrorCollector { + public: + MockErrorCollector() {} + ~MockErrorCollector() {} + + string text_; + + // implements ErrorCollector --------------------------------------- + void AddError(const string& filename, int line, int column, + const string& message) { + strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", + filename, line, column, message); + } +}; + +// ------------------------------------------------------------------- + +// A dummy implementation of SourceTree backed by a simple map. +class MockSourceTree : public SourceTree { + public: + MockSourceTree() {} + ~MockSourceTree() {} + + void AddFile(const string& name, const char* contents) { + files_[name] = contents; + } + + // implements SourceTree ------------------------------------------- + io::ZeroCopyInputStream* Open(const string& filename) { + const char* contents = FindPtrOrNull(files_, filename); + if (contents == NULL) { + return NULL; + } else { + return new io::ArrayInputStream(contents, strlen(contents)); + } + } + + private: + hash_map files_; +}; + +// =================================================================== + +class ImporterTest : public testing::Test { + protected: + ImporterTest() + : importer_(&source_tree_, &error_collector_) {} + + void AddFile(const string& filename, const char* text) { + source_tree_.AddFile(filename, text); + } + + // Return the collected error text + string error() const { return error_collector_.text_; } + + MockErrorCollector error_collector_; + MockSourceTree source_tree_; + Importer importer_; +}; + +TEST_F(ImporterTest, Import) { + // Test normal importing. + AddFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + const FileDescriptor* file = importer_.Import("foo.proto"); + EXPECT_EQ("", error_collector_.text_); + ASSERT_TRUE(file != NULL); + + ASSERT_EQ(1, file->message_type_count()); + EXPECT_EQ("Foo", file->message_type(0)->name()); + + // Importing again should return same object. + EXPECT_EQ(file, importer_.Import("foo.proto")); +} + +TEST_F(ImporterTest, ImportNested) { + // Test that importing a file which imports another file works. + AddFile("foo.proto", + "syntax = \"proto2\";\n" + "import \"bar.proto\";\n" + "message Foo {\n" + " optional Bar bar = 1;\n" + "}\n"); + AddFile("bar.proto", + "syntax = \"proto2\";\n" + "message Bar {}\n"); + + // Note that both files are actually parsed by the first call to Import() + // here, since foo.proto imports bar.proto. The second call just returns + // the same ProtoFile for bar.proto which was constructed while importing + // foo.proto. We test that this is the case below by checking that bar + // is among foo's dependencies (by pointer). + const FileDescriptor* foo = importer_.Import("foo.proto"); + const FileDescriptor* bar = importer_.Import("bar.proto"); + EXPECT_EQ("", error_collector_.text_); + ASSERT_TRUE(foo != NULL); + ASSERT_TRUE(bar != NULL); + + // Check that foo's dependency is the same object as bar. + ASSERT_EQ(1, foo->dependency_count()); + EXPECT_EQ(bar, foo->dependency(0)); + + // Check that foo properly cross-links bar. + ASSERT_EQ(1, foo->message_type_count()); + ASSERT_EQ(1, bar->message_type_count()); + ASSERT_EQ(1, foo->message_type(0)->field_count()); + ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, + foo->message_type(0)->field(0)->type()); + EXPECT_EQ(bar->message_type(0), + foo->message_type(0)->field(0)->message_type()); +} + +TEST_F(ImporterTest, FileNotFound) { + // Error: Parsing a file that doesn't exist. + EXPECT_TRUE(importer_.Import("foo.proto") == NULL); + EXPECT_EQ( + "foo.proto:-1:0: File not found.\n", + error_collector_.text_); +} + +TEST_F(ImporterTest, ImportNotFound) { + // Error: Importing a file that doesn't exist. + AddFile("foo.proto", + "syntax = \"proto2\";\n" + "import \"bar.proto\";\n"); + + EXPECT_TRUE(importer_.Import("foo.proto") == NULL); + EXPECT_EQ( + "bar.proto:-1:0: File not found.\n" + "foo.proto:-1:0: Import \"bar.proto\" was not found or had errors.\n", + error_collector_.text_); +} + +TEST_F(ImporterTest, RecursiveImport) { + // Error: Recursive import. + AddFile("recursive1.proto", + "syntax = \"proto2\";\n" + "import \"recursive2.proto\";\n"); + AddFile("recursive2.proto", + "syntax = \"proto2\";\n" + "import \"recursive1.proto\";\n"); + + EXPECT_TRUE(importer_.Import("recursive1.proto") == NULL); + EXPECT_EQ( + "recursive1.proto:-1:0: File recursively imports itself: recursive1.proto " + "-> recursive2.proto -> recursive1.proto\n" + "recursive2.proto:-1:0: Import \"recursive1.proto\" was not found " + "or had errors.\n" + "recursive1.proto:-1:0: Import \"recursive2.proto\" was not found " + "or had errors.\n", + error_collector_.text_); +} + +// TODO(sanjay): The MapField tests below more properly belong in +// descriptor_unittest, but are more convenient to test here. +TEST_F(ImporterTest, MapFieldValid) { + AddFile( + "map.proto", + "syntax = \"proto2\";\n" + "message Item {\n" + " required string key = 1;\n" + "}\n" + "message Map {\n" + " repeated Item items = 1 [experimental_map_key = \"key\"];\n" + "}\n" + ); + const FileDescriptor* file = importer_.Import("map.proto"); + ASSERT_TRUE(file != NULL) << error_collector_.text_; + EXPECT_EQ("", error_collector_.text_); + + // Check that Map::items points to Item::key + const Descriptor* item_type = file->FindMessageTypeByName("Item"); + ASSERT_TRUE(item_type != NULL); + const Descriptor* map_type = file->FindMessageTypeByName("Map"); + ASSERT_TRUE(map_type != NULL); + const FieldDescriptor* key_field = item_type->FindFieldByName("key"); + ASSERT_TRUE(key_field != NULL); + const FieldDescriptor* items_field = map_type->FindFieldByName("items"); + ASSERT_TRUE(items_field != NULL); + EXPECT_EQ(items_field->experimental_map_key(), key_field); +} + +TEST_F(ImporterTest, MapFieldNotRepeated) { + AddFile( + "map.proto", + "syntax = \"proto2\";\n" + "message Item {\n" + " required string key = 1;\n" + "}\n" + "message Map {\n" + " required Item items = 1 [experimental_map_key = \"key\"];\n" + "}\n" + ); + EXPECT_TRUE(importer_.Import("map.proto") == NULL); + EXPECT_SUBSTRING("only allowed for repeated fields", error()); +} + +TEST_F(ImporterTest, MapFieldNotMessageType) { + AddFile( + "map.proto", + "syntax = \"proto2\";\n" + "message Map {\n" + " repeated int32 items = 1 [experimental_map_key = \"key\"];\n" + "}\n" + ); + EXPECT_TRUE(importer_.Import("map.proto") == NULL); + EXPECT_SUBSTRING("only allowed for fields with a message type", error()); +} + +TEST_F(ImporterTest, MapFieldTypeNotFound) { + AddFile( + "map.proto", + "syntax = \"proto2\";\n" + "message Map {\n" + " repeated Unknown items = 1 [experimental_map_key = \"key\"];\n" + "}\n" + ); + EXPECT_TRUE(importer_.Import("map.proto") == NULL); + EXPECT_SUBSTRING("not defined", error()); +} + +TEST_F(ImporterTest, MapFieldKeyNotFound) { + AddFile( + "map.proto", + "syntax = \"proto2\";\n" + "message Item {\n" + " required string key = 1;\n" + "}\n" + "message Map {\n" + " repeated Item items = 1 [experimental_map_key = \"badkey\"];\n" + "}\n" + ); + EXPECT_TRUE(importer_.Import("map.proto") == NULL); + EXPECT_SUBSTRING("Could not find field", error()); +} + +TEST_F(ImporterTest, MapFieldKeyRepeated) { + AddFile( + "map.proto", + "syntax = \"proto2\";\n" + "message Item {\n" + " repeated string key = 1;\n" + "}\n" + "message Map {\n" + " repeated Item items = 1 [experimental_map_key = \"key\"];\n" + "}\n" + ); + EXPECT_TRUE(importer_.Import("map.proto") == NULL); + EXPECT_SUBSTRING("must not name a repeated field", error()); +} + +TEST_F(ImporterTest, MapFieldKeyNotScalar) { + AddFile( + "map.proto", + "syntax = \"proto2\";\n" + "message ItemKey { }\n" + "message Item {\n" + " required ItemKey key = 1;\n" + "}\n" + "message Map {\n" + " repeated Item items = 1 [experimental_map_key = \"key\"];\n" + "}\n" + ); + EXPECT_TRUE(importer_.Import("map.proto") == NULL); + EXPECT_SUBSTRING("must name a scalar or string", error()); +} + +// =================================================================== + +class DiskSourceTreeTest : public testing::Test { + protected: + virtual void SetUp() { + dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_1"); + dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_2"); + + for (int i = 0; i < dirnames_.size(); i++) { + if (File::Exists(dirnames_[i])) { + File::DeleteRecursively(dirnames_[i], NULL, NULL); + } + GOOGLE_CHECK(File::CreateDir(dirnames_[i].c_str(), DEFAULT_FILE_MODE)); + } + } + + virtual void TearDown() { + for (int i = 0; i < dirnames_.size(); i++) { + File::DeleteRecursively(dirnames_[i], NULL, NULL); + } + } + + void AddFile(const string& filename, const char* contents) { + File::WriteStringToFileOrDie(contents, filename); + } + + void AddSubdir(const string& dirname) { + GOOGLE_CHECK(File::CreateDir(dirname.c_str(), DEFAULT_FILE_MODE)); + } + + void ExpectFileContents(const string& filename, + const char* expected_contents) { + scoped_ptr input(source_tree_.Open(filename)); + + ASSERT_FALSE(input == NULL); + + // Read all the data from the file. + string file_contents; + const void* data; + int size; + while (input->Next(&data, &size)) { + file_contents.append(reinterpret_cast(data), size); + } + + EXPECT_EQ(expected_contents, file_contents); + } + + void ExpectFileNotFound(const string& filename) { + scoped_ptr input(source_tree_.Open(filename)); + EXPECT_TRUE(input == NULL); + } + + DiskSourceTree source_tree_; + + // Paths of two on-disk directories to use during the test. + vector dirnames_; +}; + +TEST_F(DiskSourceTreeTest, MapRoot) { + // Test opening a file in a directory that is mapped to the root of the + // source tree. + AddFile(dirnames_[0] + "/foo", "Hello World!"); + source_tree_.MapPath("", dirnames_[0]); + + ExpectFileContents("foo", "Hello World!"); + ExpectFileNotFound("bar"); +} + +TEST_F(DiskSourceTreeTest, MapDirectory) { + // Test opening a file in a directory that is mapped to somewhere other + // than the root of the source tree. + + AddFile(dirnames_[0] + "/foo", "Hello World!"); + source_tree_.MapPath("baz", dirnames_[0]); + + ExpectFileContents("baz/foo", "Hello World!"); + ExpectFileNotFound("baz/bar"); + ExpectFileNotFound("foo"); + ExpectFileNotFound("bar"); + + // Non-canonical file names should not work. + ExpectFileNotFound("baz//foo"); + ExpectFileNotFound("baz/../baz/foo"); + ExpectFileNotFound("baz/./foo"); + ExpectFileNotFound("baz/foo/"); +} + +TEST_F(DiskSourceTreeTest, NoParent) { + // Test that we cannot open files in a parent of a mapped directory. + + AddFile(dirnames_[0] + "/foo", "Hello World!"); + AddSubdir(dirnames_[0] + "/bar"); + AddFile(dirnames_[0] + "/bar/baz", "Blah."); + source_tree_.MapPath("", dirnames_[0] + "/bar"); + + ExpectFileContents("baz", "Blah."); + ExpectFileNotFound("../foo"); + ExpectFileNotFound("../bar/baz"); +} + +TEST_F(DiskSourceTreeTest, MapFile) { + // Test opening a file that is mapped directly into the source tree. + + AddFile(dirnames_[0] + "/foo", "Hello World!"); + source_tree_.MapPath("foo", dirnames_[0] + "/foo"); + + ExpectFileContents("foo", "Hello World!"); + ExpectFileNotFound("bar"); +} + +TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) { + // Test mapping and searching multiple directories. + + AddFile(dirnames_[0] + "/foo", "Hello World!"); + AddFile(dirnames_[1] + "/foo", "This file should be hidden."); + AddFile(dirnames_[1] + "/bar", "Goodbye World!"); + source_tree_.MapPath("", dirnames_[0]); + source_tree_.MapPath("", dirnames_[1]); + + ExpectFileContents("foo", "Hello World!"); + ExpectFileContents("bar", "Goodbye World!"); + ExpectFileNotFound("baz"); +} + +TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) { + // Test that directories are always searched in order, even when a latter + // directory is more-specific than a former one. + + // Create the "bar" directory so we can put a file in it. + ASSERT_TRUE(File::CreateDir((dirnames_[0] + "/bar").c_str(), + DEFAULT_FILE_MODE)); + + // Add files and map paths. + AddFile(dirnames_[0] + "/bar/foo", "Hello World!"); + AddFile(dirnames_[1] + "/foo", "This file should be hidden."); + source_tree_.MapPath("", dirnames_[0]); + source_tree_.MapPath("bar", dirnames_[1]); + + // Check. + ExpectFileContents("bar/foo", "Hello World!"); +} + +TEST_F(DiskSourceTreeTest, DiskFileToVirtualFile) { + // Test DiskFileToVirtualFile. + + AddFile(dirnames_[0] + "/foo", "Hello World!"); + AddFile(dirnames_[1] + "/foo", "This file should be hidden."); + source_tree_.MapPath("bar", dirnames_[0]); + source_tree_.MapPath("bar", dirnames_[1]); + + string virtual_file; + string shadowing_disk_file; + + EXPECT_EQ(DiskSourceTree::NO_MAPPING, + source_tree_.DiskFileToVirtualFile( + "/foo", &virtual_file, &shadowing_disk_file)); + + EXPECT_EQ(DiskSourceTree::SHADOWED, + source_tree_.DiskFileToVirtualFile( + dirnames_[1] + "/foo", &virtual_file, &shadowing_disk_file)); + EXPECT_EQ("bar/foo", virtual_file); + EXPECT_EQ(dirnames_[0] + "/foo", shadowing_disk_file); + + EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, + source_tree_.DiskFileToVirtualFile( + dirnames_[1] + "/baz", &virtual_file, &shadowing_disk_file)); + EXPECT_EQ("bar/baz", virtual_file); + + EXPECT_EQ(DiskSourceTree::SUCCESS, + source_tree_.DiskFileToVirtualFile( + dirnames_[0] + "/foo", &virtual_file, &shadowing_disk_file)); + EXPECT_EQ("bar/foo", virtual_file); +} + +TEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) { + // Test handling of "..", ".", etc. in DiskFileToVirtualFile(). + + source_tree_.MapPath("dir1", ".."); + source_tree_.MapPath("dir2", "../../foo"); + source_tree_.MapPath("dir3", "./foo/bar/."); + source_tree_.MapPath("dir4", "."); + source_tree_.MapPath("", "/qux"); + source_tree_.MapPath("dir5", "/quux/"); + + string virtual_file; + string shadowing_disk_file; + + // "../.." should not be considered to be under "..". + EXPECT_EQ(DiskSourceTree::NO_MAPPING, + source_tree_.DiskFileToVirtualFile( + "../../baz", &virtual_file, &shadowing_disk_file)); + + // "/foo" is not mapped (it should not be misintepreted as being under "."). + EXPECT_EQ(DiskSourceTree::NO_MAPPING, + source_tree_.DiskFileToVirtualFile( + "/foo", &virtual_file, &shadowing_disk_file)); + +#ifdef WIN32 + // "C:\foo" is not mapped (it should not be misintepreted as being under "."). + EXPECT_EQ(DiskSourceTree::NO_MAPPING, + source_tree_.DiskFileToVirtualFile( + "C:\\foo", &virtual_file, &shadowing_disk_file)); +#endif // WIN32 + + // But "../baz" should be. + EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, + source_tree_.DiskFileToVirtualFile( + "../baz", &virtual_file, &shadowing_disk_file)); + EXPECT_EQ("dir1/baz", virtual_file); + + // "../../foo/baz" is under "../../foo". + EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, + source_tree_.DiskFileToVirtualFile( + "../../foo/baz", &virtual_file, &shadowing_disk_file)); + EXPECT_EQ("dir2/baz", virtual_file); + + // "foo/./bar/baz" is under "./foo/bar/.". + EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, + source_tree_.DiskFileToVirtualFile( + "foo/bar/baz", &virtual_file, &shadowing_disk_file)); + EXPECT_EQ("dir3/baz", virtual_file); + + // "bar" is under ".". + EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, + source_tree_.DiskFileToVirtualFile( + "bar", &virtual_file, &shadowing_disk_file)); + EXPECT_EQ("dir4/bar", virtual_file); + + // "/qux/baz" is under "/qux". + EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, + source_tree_.DiskFileToVirtualFile( + "/qux/baz", &virtual_file, &shadowing_disk_file)); + EXPECT_EQ("baz", virtual_file); + + // "/quux/bar" is under "/quux". + EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, + source_tree_.DiskFileToVirtualFile( + "/quux/bar", &virtual_file, &shadowing_disk_file)); + EXPECT_EQ("dir5/bar", virtual_file); +} + +TEST_F(DiskSourceTreeTest, VirtualFileToDiskFile) { + // Test VirtualFileToDiskFile. + + AddFile(dirnames_[0] + "/foo", "Hello World!"); + AddFile(dirnames_[1] + "/foo", "This file should be hidden."); + AddFile(dirnames_[1] + "/quux", "This file should not be hidden."); + source_tree_.MapPath("bar", dirnames_[0]); + source_tree_.MapPath("bar", dirnames_[1]); + + // Existent files, shadowed and non-shadowed case. + string disk_file; + EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", &disk_file)); + EXPECT_EQ(dirnames_[0] + "/foo", disk_file); + EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/quux", &disk_file)); + EXPECT_EQ(dirnames_[1] + "/quux", disk_file); + + // Nonexistent file in existent directory and vice versa. + string not_touched = "not touched"; + EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("bar/baz", ¬_touched)); + EXPECT_EQ("not touched", not_touched); + EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", ¬_touched)); + EXPECT_EQ("not touched", not_touched); + + // Accept NULL as output parameter. + EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", NULL)); + EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", NULL)); +} + +} // namespace + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment.cc new file mode 100644 index 0000000..60b4f2a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment.cc @@ -0,0 +1,236 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +string EscapeJavadoc(const string& input) { + string result; + result.reserve(input.size() * 2); + + char prev = '*'; + + for (string::size_type i = 0; i < input.size(); i++) { + char c = input[i]; + switch (c) { + case '*': + // Avoid "/*". + if (prev == '/') { + result.append("*"); + } else { + result.push_back(c); + } + break; + case '/': + // Avoid "*/". + if (prev == '*') { + result.append("/"); + } else { + result.push_back(c); + } + break; + case '@': + // "{@" starts Javadoc markup. + if (prev == '{') { + result.append("@"); + } else { + result.push_back(c); + } + break; + case '<': + // Avoid interpretation as HTML. + result.append("<"); + break; + case '>': + // Avoid interpretation as HTML. + result.append(">"); + break; + case '&': + // Avoid interpretation as HTML. + result.append("&"); + break; + case '\\': + // Java interprets Unicode escape sequences anywhere! + result.append("\"); + break; + default: + result.push_back(c); + break; + } + + prev = c; + } + + return result; +} + +static void WriteDocCommentBodyForLocation( + io::Printer* printer, const SourceLocation& location) { + string comments = location.leading_comments.empty() ? + location.trailing_comments : location.leading_comments; + if (!comments.empty()) { + // TODO(kenton): Ideally we should parse the comment text as Markdown and + // write it back as HTML, but this requires a Markdown parser. For now + // we just use

 to get fixed-width text formatting.
+
+    // If the comment itself contains block comment start or end markers,
+    // HTML-escape them so that they don't accidentally close the doc comment.
+    comments = EscapeJavadoc(comments);
+
+    vector lines;
+    SplitStringAllowEmpty(comments, "\n", &lines);
+    while (!lines.empty() && lines.back().empty()) {
+      lines.pop_back();
+    }
+
+    printer->Print(
+        " *\n"
+        " * 
\n");
+    for (int i = 0; i < lines.size(); i++) {
+      // Most lines should start with a space.  Watch out for lines that start
+      // with a /, since putting that right after the leading asterisk will
+      // close the comment.
+      if (!lines[i].empty() && lines[i][0] == '/') {
+        printer->Print(" * $line$\n", "line", lines[i]);
+      } else {
+        printer->Print(" *$line$\n", "line", lines[i]);
+      }
+    }
+    printer->Print(" * 
\n"); + } +} + +template +static void WriteDocCommentBody( + io::Printer* printer, const DescriptorType* descriptor) { + SourceLocation location; + if (descriptor->GetSourceLocation(&location)) { + WriteDocCommentBodyForLocation(printer, location); + } +} + +static string FirstLineOf(const string& value) { + string result = value; + + string::size_type pos = result.find_first_of('\n'); + if (pos != string::npos) { + result.erase(pos); + } + + // If line ends in an opening brace, make it "{ ... }" so it looks nice. + if (!result.empty() && result[result.size() - 1] == '{') { + result.append(" ... }"); + } + + return result; +} + +void WriteMessageDocComment(io::Printer* printer, const Descriptor* message) { + printer->Print( + "/**\n" + " * Protobuf type {@code $fullname$}\n", + "fullname", EscapeJavadoc(message->full_name())); + WriteDocCommentBody(printer, message); + printer->Print(" */\n"); +} + +void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field) { + // In theory we should have slightly different comments for setters, getters, + // etc., but in practice everyone already knows the difference between these + // so it's redundant information. + + // We use the field declaration as the first line of the comment, e.g.: + // optional string foo = 5; + // This communicates a lot of information about the field in a small space. + // If the field is a group, the debug string might end with {. + printer->Print( + "/**\n" + " * $def$\n", + "def", EscapeJavadoc(FirstLineOf(field->DebugString()))); + WriteDocCommentBody(printer, field); + printer->Print(" */\n"); +} + +void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_) { + printer->Print( + "/**\n" + " * Protobuf enum {@code $fullname$}\n", + "fullname", EscapeJavadoc(enum_->full_name())); + WriteDocCommentBody(printer, enum_); + printer->Print(" */\n"); +} + +void WriteEnumValueDocComment(io::Printer* printer, + const EnumValueDescriptor* value) { + printer->Print( + "/**\n" + " * $def$\n", + "def", EscapeJavadoc(FirstLineOf(value->DebugString()))); + WriteDocCommentBody(printer, value); + printer->Print(" */\n"); +} + +void WriteServiceDocComment(io::Printer* printer, + const ServiceDescriptor* service) { + printer->Print( + "/**\n" + " * Protobuf service {@code $fullname$}\n", + "fullname", EscapeJavadoc(service->full_name())); + WriteDocCommentBody(printer, service); + printer->Print(" */\n"); +} + +void WriteMethodDocComment(io::Printer* printer, + const MethodDescriptor* method) { + printer->Print( + "/**\n" + " * $def$\n", + "def", EscapeJavadoc(FirstLineOf(method->DebugString()))); + WriteDocCommentBody(printer, method); + printer->Print(" */\n"); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment.h new file mode 100644 index 0000000..7244d9b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment.h @@ -0,0 +1,69 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__ + +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +void WriteMessageDocComment(io::Printer* printer, const Descriptor* message); +void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field); +void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_); +void WriteEnumValueDocComment(io::Printer* printer, + const EnumValueDescriptor* value); +void WriteServiceDocComment(io::Printer* printer, + const ServiceDescriptor* service); +void WriteMethodDocComment(io::Printer* printer, + const MethodDescriptor* method); + +// Exposed for testing only. +LIBPROTOC_EXPORT string EscapeJavadoc(const string& input); + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc new file mode 100644 index 0000000..28b6d8b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc @@ -0,0 +1,66 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include + +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +namespace { + +TEST(JavaDocCommentTest, Escaping) { + EXPECT_EQ("foo /* bar */ baz", EscapeJavadoc("foo /* bar */ baz")); + EXPECT_EQ("foo /*/ baz", EscapeJavadoc("foo /*/ baz")); + EXPECT_EQ("{@foo}", EscapeJavadoc("{@foo}")); + EXPECT_EQ("<i>&</i>", EscapeJavadoc("&")); + EXPECT_EQ("foo\u1234bar", EscapeJavadoc("foo\\u1234bar")); +} + +// TODO(kenton): It's hard to write a robust test of the doc comments -- we +// can only really compare the output against a golden value, which is a +// fairly tedious and fragile testing strategy. If we want to go that route, +// it probably makes sense to bite the bullet and write a test that compares +// the whole generated output for unittest.proto against a golden value, with +// a very simple script that can be run to regenerate it with the latest code. +// This would mean that updates to the golden file would have to be included +// in any change to the code generator, which would actually be fairly useful +// as it allows the reviewer to see clearly how the generated code is +// changing. + +} // namespace +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum.cc new file mode 100644 index 0000000..cfed815 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum.cc @@ -0,0 +1,271 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) + : descriptor_(descriptor) { + for (int i = 0; i < descriptor_->value_count(); i++) { + const EnumValueDescriptor* value = descriptor_->value(i); + const EnumValueDescriptor* canonical_value = + descriptor_->FindValueByNumber(value->number()); + + if (value == canonical_value) { + canonical_values_.push_back(value); + } else { + Alias alias; + alias.value = value; + alias.canonical_value = canonical_value; + aliases_.push_back(alias); + } + } +} + +EnumGenerator::~EnumGenerator() {} + +void EnumGenerator::Generate(io::Printer* printer) { + WriteEnumDocComment(printer, descriptor_); + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public enum $classname$\n" + " implements com.google.protobuf.ProtocolMessageEnum {\n", + "classname", descriptor_->name()); + } else { + printer->Print( + "public enum $classname$\n" + " implements com.google.protobuf.Internal.EnumLite {\n", + "classname", descriptor_->name()); + } + printer->Indent(); + + for (int i = 0; i < canonical_values_.size(); i++) { + map vars; + vars["name"] = canonical_values_[i]->name(); + vars["index"] = SimpleItoa(canonical_values_[i]->index()); + vars["number"] = SimpleItoa(canonical_values_[i]->number()); + WriteEnumValueDocComment(printer, canonical_values_[i]); + printer->Print(vars, + "$name$($index$, $number$),\n"); + } + + printer->Print( + ";\n" + "\n"); + + // ----------------------------------------------------------------- + + for (int i = 0; i < aliases_.size(); i++) { + map vars; + vars["classname"] = descriptor_->name(); + vars["name"] = aliases_[i].value->name(); + vars["canonical_name"] = aliases_[i].canonical_value->name(); + WriteEnumValueDocComment(printer, aliases_[i].value); + printer->Print(vars, + "public static final $classname$ $name$ = $canonical_name$;\n"); + } + + for (int i = 0; i < descriptor_->value_count(); i++) { + map vars; + vars["name"] = descriptor_->value(i)->name(); + vars["number"] = SimpleItoa(descriptor_->value(i)->number()); + WriteEnumValueDocComment(printer, descriptor_->value(i)); + printer->Print(vars, + "public static final int $name$_VALUE = $number$;\n"); + } + printer->Print("\n"); + + // ----------------------------------------------------------------- + + printer->Print( + "\n" + "public final int getNumber() { return value; }\n" + "\n" + "public static $classname$ valueOf(int value) {\n" + " switch (value) {\n", + "classname", descriptor_->name()); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < canonical_values_.size(); i++) { + printer->Print( + "case $number$: return $name$;\n", + "name", canonical_values_[i]->name(), + "number", SimpleItoa(canonical_values_[i]->number())); + } + + printer->Outdent(); + printer->Outdent(); + printer->Print( + " default: return null;\n" + " }\n" + "}\n" + "\n" + "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n" + " internalGetValueMap() {\n" + " return internalValueMap;\n" + "}\n" + "private static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n" + " internalValueMap =\n" + " new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n" + " public $classname$ findValueByNumber(int number) {\n" + " return $classname$.valueOf(number);\n" + " }\n" + " };\n" + "\n", + "classname", descriptor_->name()); + + // ----------------------------------------------------------------- + // Reflection + + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public final com.google.protobuf.Descriptors.EnumValueDescriptor\n" + " getValueDescriptor() {\n" + " return getDescriptor().getValues().get(index);\n" + "}\n" + "public final com.google.protobuf.Descriptors.EnumDescriptor\n" + " getDescriptorForType() {\n" + " return getDescriptor();\n" + "}\n" + "public static final com.google.protobuf.Descriptors.EnumDescriptor\n" + " getDescriptor() {\n"); + + // TODO(kenton): Cache statically? Note that we can't access descriptors + // at module init time because it wouldn't work with descriptor.proto, but + // we can cache the value the first time getDescriptor() is called. + if (descriptor_->containing_type() == NULL) { + printer->Print( + " return $file$.getDescriptor().getEnumTypes().get($index$);\n", + "file", ClassName(descriptor_->file()), + "index", SimpleItoa(descriptor_->index())); + } else { + printer->Print( + " return $parent$.getDescriptor().getEnumTypes().get($index$);\n", + "parent", ClassName(descriptor_->containing_type()), + "index", SimpleItoa(descriptor_->index())); + } + + printer->Print( + "}\n" + "\n" + "private static final $classname$[] VALUES = ", + "classname", descriptor_->name()); + + if (CanUseEnumValues()) { + // If the constants we are going to output are exactly the ones we + // have declared in the Java enum in the same order, then we can use + // the values() method that the Java compiler automatically generates + // for every enum. + printer->Print("values();\n"); + } else { + printer->Print( + "{\n" + " "); + for (int i = 0; i < descriptor_->value_count(); i++) { + printer->Print("$name$, ", + "name", descriptor_->value(i)->name()); + } + printer->Print( + "\n" + "};\n"); + } + + printer->Print( + "\n" + "public static $classname$ valueOf(\n" + " com.google.protobuf.Descriptors.EnumValueDescriptor desc) {\n" + " if (desc.getType() != getDescriptor()) {\n" + " throw new java.lang.IllegalArgumentException(\n" + " \"EnumValueDescriptor is not for this type.\");\n" + " }\n" + " return VALUES[desc.getIndex()];\n" + "}\n" + "\n", + "classname", descriptor_->name()); + + // index is only used for reflection; lite implementation does not need it + printer->Print("private final int index;\n"); + } + + // ----------------------------------------------------------------- + + printer->Print( + "private final int value;\n\n" + "private $classname$(int index, int value) {\n", + "classname", descriptor_->name()); + if (HasDescriptorMethods(descriptor_)) { + printer->Print(" this.index = index;\n"); + } + printer->Print( + " this.value = value;\n" + "}\n"); + + printer->Print( + "\n" + "// @@protoc_insertion_point(enum_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + + printer->Outdent(); + printer->Print("}\n\n"); +} + +bool EnumGenerator::CanUseEnumValues() { + if (canonical_values_.size() != descriptor_->value_count()) { + return false; + } + for (int i = 0; i < descriptor_->value_count(); i++) { + if (descriptor_->value(i)->name() != canonical_values_[i]->name()) { + return false; + } + } + return true; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum.h new file mode 100644 index 0000000..9a9e574 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum.h @@ -0,0 +1,86 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +class EnumGenerator { + public: + explicit EnumGenerator(const EnumDescriptor* descriptor); + ~EnumGenerator(); + + void Generate(io::Printer* printer); + + private: + const EnumDescriptor* descriptor_; + + // The proto language allows multiple enum constants to have the same numeric + // value. Java, however, does not allow multiple enum constants to be + // considered equivalent. We treat the first defined constant for any + // given numeric value as "canonical" and the rest as aliases of that + // canonical value. + vector canonical_values_; + + struct Alias { + const EnumValueDescriptor* value; + const EnumValueDescriptor* canonical_value; + }; + vector aliases_; + + bool CanUseEnumValues(); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum_field.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum_field.cc new file mode 100644 index 0000000..ec0b067 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum_field.cc @@ -0,0 +1,603 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { + +// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of +// repeat code between this and the other field types. +void SetEnumVariables(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + map* variables) { + (*variables)["name"] = + UnderscoresToCamelCase(descriptor); + (*variables)["capitalized_name"] = + UnderscoresToCapitalizedCamelCase(descriptor); + (*variables)["constant_name"] = FieldConstantName(descriptor); + (*variables)["number"] = SimpleItoa(descriptor->number()); + (*variables)["type"] = ClassName(descriptor->enum_type()); + (*variables)["default"] = DefaultValue(descriptor); + (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); + (*variables)["tag_size"] = SimpleItoa( + internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = descriptor->options().deprecated() + ? "@java.lang.Deprecated " : ""; + (*variables)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + (*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex); + + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex); + + // For repated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + // For repeated fields, one bit is used for whether the array is immutable + // in the parsing constructor. + (*variables)["get_mutable_bit_parser"] = + GenerateGetBitMutableLocal(builderBitIndex); + (*variables)["set_mutable_bit_parser"] = + GenerateSetBitMutableLocal(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +} // namespace + +// =================================================================== + +EnumFieldGenerator:: +EnumFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, &variables_); +} + +EnumFieldGenerator::~EnumFieldGenerator() {} + +int EnumFieldGenerator::GetNumBitsForMessage() const { + return 1; +} + +int EnumFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void EnumFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$();\n"); +} + +void EnumFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private $type$ $name$_;\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_;\n" + "}\n"); +} + +void EnumFieldGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + printer->Print(variables_, + "private $type$ $name$_ = $default$;\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " $set_has_field_bit_builder$;\n" + " $name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $clear_has_field_bit_builder$;\n" + " $name$_ = $default$;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); +} + +void EnumFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for enums +} + +void EnumFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void EnumFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $default$;\n" + "$clear_has_field_bit_builder$;\n"); +} + +void EnumFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " set$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); +} + +void EnumFieldGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); +} + +void EnumFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "int rawValue = input.readEnum();\n" + "$type$ value = $type$.valueOf(rawValue);\n"); + if (HasUnknownFields(descriptor_->containing_type())) { + printer->Print(variables_, + "if (value == null) {\n" + " unknownFields.mergeVarintField($number$, rawValue);\n" + "} else {\n"); + } else { + printer->Print(variables_, + "if (value != null) {\n"); + } + printer->Print(variables_, + " $set_has_field_bit_message$;\n" + " $name$_ = value;\n" + "}\n"); +} + +void EnumFieldGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + // noop for enums +} + +void EnumFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " output.writeEnum($number$, $name$_.getNumber());\n" + "}\n"); +} + +void EnumFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeEnumSize($number$, $name$_.getNumber());\n" + "}\n"); +} + +void EnumFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result &&\n" + " (get$capitalized_name$() == other.get$capitalized_name$());\n"); +} + +void EnumFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n" + "hash = (53 * hash) + hashEnum(get$capitalized_name$());\n"); +} + +string EnumFieldGenerator::GetBoxedType() const { + return ClassName(descriptor_->enum_type()); +} + +// =================================================================== + +RepeatedEnumFieldGenerator:: +RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, &variables_); +} + +RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} + +int RepeatedEnumFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedEnumFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedEnumFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$(int index);\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private java.util.List<$type$> $name$_;\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + + if (descriptor_->options().packed() && + HasGeneratedMethods(descriptor_->containing_type())) { + printer->Print(variables_, + "private int $name$MemoizedSerializedSize;\n"); + } +} + +void RepeatedEnumFieldGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + printer->Print(variables_, + // One field is the list and the other field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a refererence to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + "private java.util.List<$type$> $name$_ =\n" + " java.util.Collections.emptyList();\n" + + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = new java.util.ArrayList<$type$>($name$_);\n" + " $set_mutable_bit_builder$;\n" + " }\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + // Note: We return an unmodifiable list because otherwise the caller + // could hold on to the returned list and modify it after the message + // has been built, thus mutating the message which is supposed to be + // immutable. + "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + " return java.util.Collections.unmodifiableList($name$_);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder set$capitalized_name$(\n" + " int index, $type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder addAll$capitalized_name$(\n" + " java.lang.Iterable values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " super.addAll(values, $name$_);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $name$_ = java.util.Collections.emptyList();\n" + " $clear_mutable_bit_builder$;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for enums +} + +void RepeatedEnumFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = java.util.Collections.emptyList();\n" + "$clear_mutable_bit_builder$;\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + // The code below does two optimizations: + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. + printer->Print(variables_, + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + // The code below ensures that the result has an immutable list. If our + // list is immutable, we can just reuse it. If not, we make it immutable. + printer->Print(variables_, + "if ($get_mutable_bit_builder$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + // Read and store the enum + printer->Print(variables_, + "int rawValue = input.readEnum();\n" + "$type$ value = $type$.valueOf(rawValue);\n"); + if (HasUnknownFields(descriptor_->containing_type())) { + printer->Print(variables_, + "if (value == null) {\n" + " unknownFields.mergeVarintField($number$, rawValue);\n" + "} else {\n"); + } else { + printer->Print(variables_, + "if (value != null) {\n"); + } + printer->Print(variables_, + " if (!$get_mutable_bit_parser$) {\n" + " $name$_ = new java.util.ArrayList<$type$>();\n" + " $set_mutable_bit_parser$;\n" + " }\n" + " $name$_.add(value);\n" + "}\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateParsingCodeFromPacked(io::Printer* printer) const { + // Wrap GenerateParsingCode's contents with a while loop. + + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int oldLimit = input.pushLimit(length);\n" + "while(input.getBytesUntilLimit() > 0) {\n"); + printer->Indent(); + + GenerateParsingCode(printer); + + printer->Outdent(); + printer->Print(variables_, + "}\n" + "input.popLimit(oldLimit);\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_mutable_bit_parser$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + "}\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (get$capitalized_name$List().size() > 0) {\n" + " output.writeRawVarint32($tag$);\n" + " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + "}\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.writeEnumNoTag($name$_.get(i).getNumber());\n" + "}\n"); + } else { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.writeEnum($number$, $name$_.get(i).getNumber());\n" + "}\n"); + } +} + +void RepeatedEnumFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "{\n" + " int dataSize = 0;\n"); + printer->Indent(); + + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " dataSize += com.google.protobuf.CodedOutputStream\n" + " .computeEnumSizeNoTag($name$_.get(i).getNumber());\n" + "}\n"); + printer->Print( + "size += dataSize;\n"); + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (!get$capitalized_name$List().isEmpty()) {" + " size += $tag_size$;\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeRawVarint32Size(dataSize);\n" + "}"); + } else { + printer->Print(variables_, + "size += $tag_size$ * $name$_.size();\n"); + } + + // cache the data size for packed fields. + if (descriptor_->options().packed()) { + printer->Print(variables_, + "$name$MemoizedSerializedSize = dataSize;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List());\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + hashEnumList(get$capitalized_name$List());\n" + "}\n"); +} + +string RepeatedEnumFieldGenerator::GetBoxedType() const { + return ClassName(descriptor_->enum_type()); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum_field.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum_field.h new file mode 100644 index 0000000..90fae63 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_enum_field.h @@ -0,0 +1,123 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class EnumFieldGenerator : public FieldGenerator { + public: + explicit EnumFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); + ~EnumFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + const int messageBitIndex_; + const int builderBitIndex_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); +}; + +class RepeatedEnumFieldGenerator : public FieldGenerator { + public: + explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); + ~RepeatedEnumFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingCodeFromPacked(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + const int messageBitIndex_; + const int builderBitIndex_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_extension.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_extension.cc new file mode 100644 index 0000000..921fe65 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_extension.cc @@ -0,0 +1,218 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { + +const char* TypeName(FieldDescriptor::Type field_type) { + switch (field_type) { + case FieldDescriptor::TYPE_INT32 : return "INT32"; + case FieldDescriptor::TYPE_UINT32 : return "UINT32"; + case FieldDescriptor::TYPE_SINT32 : return "SINT32"; + case FieldDescriptor::TYPE_FIXED32 : return "FIXED32"; + case FieldDescriptor::TYPE_SFIXED32: return "SFIXED32"; + case FieldDescriptor::TYPE_INT64 : return "INT64"; + case FieldDescriptor::TYPE_UINT64 : return "UINT64"; + case FieldDescriptor::TYPE_SINT64 : return "SINT64"; + case FieldDescriptor::TYPE_FIXED64 : return "FIXED64"; + case FieldDescriptor::TYPE_SFIXED64: return "SFIXED64"; + case FieldDescriptor::TYPE_FLOAT : return "FLOAT"; + case FieldDescriptor::TYPE_DOUBLE : return "DOUBLE"; + case FieldDescriptor::TYPE_BOOL : return "BOOL"; + case FieldDescriptor::TYPE_STRING : return "STRING"; + case FieldDescriptor::TYPE_BYTES : return "BYTES"; + case FieldDescriptor::TYPE_ENUM : return "ENUM"; + case FieldDescriptor::TYPE_GROUP : return "GROUP"; + case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE"; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +} + +ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor) + : descriptor_(descriptor) { + if (descriptor_->extension_scope() != NULL) { + scope_ = ClassName(descriptor_->extension_scope()); + } else { + scope_ = ClassName(descriptor_->file()); + } +} + +ExtensionGenerator::~ExtensionGenerator() {} + +// Initializes the vars referenced in the generated code templates. +void InitTemplateVars(const FieldDescriptor* descriptor, + const string& scope, + map* vars_pointer) { + map &vars = *vars_pointer; + vars["scope"] = scope; + vars["name"] = UnderscoresToCamelCase(descriptor); + vars["containing_type"] = ClassName(descriptor->containing_type()); + vars["number"] = SimpleItoa(descriptor->number()); + vars["constant_name"] = FieldConstantName(descriptor); + vars["index"] = SimpleItoa(descriptor->index()); + vars["default"] = + descriptor->is_repeated() ? "" : DefaultValue(descriptor); + vars["type_constant"] = TypeName(GetType(descriptor)); + vars["packed"] = descriptor->options().packed() ? "true" : "false"; + vars["enum_map"] = "null"; + vars["prototype"] = "null"; + + JavaType java_type = GetJavaType(descriptor); + string singular_type; + switch (java_type) { + case JAVATYPE_MESSAGE: + singular_type = ClassName(descriptor->message_type()); + vars["prototype"] = singular_type + ".getDefaultInstance()"; + break; + case JAVATYPE_ENUM: + singular_type = ClassName(descriptor->enum_type()); + vars["enum_map"] = singular_type + ".internalGetValueMap()"; + break; + default: + singular_type = BoxedPrimitiveTypeName(java_type); + break; + } + vars["type"] = descriptor->is_repeated() ? + "java.util.List<" + singular_type + ">" : singular_type; + vars["singular_type"] = singular_type; +} + +void ExtensionGenerator::Generate(io::Printer* printer) { + map vars; + InitTemplateVars(descriptor_, scope_, &vars); + printer->Print(vars, + "public static final int $constant_name$ = $number$;\n"); + + WriteFieldDocComment(printer, descriptor_); + if (HasDescriptorMethods(descriptor_->file())) { + // Non-lite extensions + if (descriptor_->extension_scope() == NULL) { + // Non-nested + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessage\n" + " .newFileScopedGeneratedExtension(\n" + " $singular_type$.class,\n" + " $prototype$);\n"); + } else { + // Nested + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessage\n" + " .newMessageScopedGeneratedExtension(\n" + " $scope$.getDefaultInstance(),\n" + " $index$,\n" + " $singular_type$.class,\n" + " $prototype$);\n"); + } + } else { + // Lite extensions + if (descriptor_->is_repeated()) { + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n" + " .newRepeatedGeneratedExtension(\n" + " $containing_type$.getDefaultInstance(),\n" + " $prototype$,\n" + " $enum_map$,\n" + " $number$,\n" + " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n" + " $packed$);\n"); + } else { + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n" + " .newSingularGeneratedExtension(\n" + " $containing_type$.getDefaultInstance(),\n" + " $default$,\n" + " $prototype$,\n" + " $enum_map$,\n" + " $number$,\n" + " com.google.protobuf.WireFormat.FieldType.$type_constant$);\n"); + } + } +} + +void ExtensionGenerator::GenerateNonNestedInitializationCode( + io::Printer* printer) { + if (descriptor_->extension_scope() == NULL && + HasDescriptorMethods(descriptor_->file())) { + // Only applies to non-nested, non-lite extensions. + printer->Print( + "$name$.internalInit(descriptor.getExtensions().get($index$));\n", + "name", UnderscoresToCamelCase(descriptor_), + "index", SimpleItoa(descriptor_->index())); + } +} + +void ExtensionGenerator::GenerateRegistrationCode(io::Printer* printer) { + printer->Print( + "registry.add($scope$.$name$);\n", + "scope", scope_, + "name", UnderscoresToCamelCase(descriptor_)); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_extension.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_extension.h new file mode 100644 index 0000000..009ed9f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_extension.h @@ -0,0 +1,77 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__ + +#include + +#include + +namespace google { +namespace protobuf { + class FieldDescriptor; // descriptor.h + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +// Generates code for an extension, which may be within the scope of some +// message or may be at file scope. This is much simpler than FieldGenerator +// since extensions are just simple identifiers with interesting types. +class ExtensionGenerator { + public: + explicit ExtensionGenerator(const FieldDescriptor* descriptor); + ~ExtensionGenerator(); + + void Generate(io::Printer* printer); + void GenerateNonNestedInitializationCode(io::Printer* printer); + void GenerateRegistrationCode(io::Printer* printer); + + private: + const FieldDescriptor* descriptor_; + string scope_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_field.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_field.cc new file mode 100644 index 0000000..c7d433c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_field.cc @@ -0,0 +1,137 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +FieldGenerator::~FieldGenerator() {} + +void FieldGenerator::GenerateParsingCodeFromPacked(io::Printer* printer) const { + // Reaching here indicates a bug. Cases are: + // - This FieldGenerator should support packing, but this method should be + // overridden. + // - This FieldGenerator doesn't support packing, and this method should + // never have been called. + GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() " + << "called on field generator that does not support packing."; +} + +FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) + : descriptor_(descriptor), + field_generators_( + new scoped_ptr[descriptor->field_count()]), + extension_generators_( + new scoped_ptr[descriptor->extension_count()]) { + + // Construct all the FieldGenerators and assign them bit indices for their + // bit fields. + int messageBitIndex = 0; + int builderBitIndex = 0; + for (int i = 0; i < descriptor->field_count(); i++) { + FieldGenerator* generator = MakeGenerator(descriptor->field(i), + messageBitIndex, builderBitIndex); + field_generators_[i].reset(generator); + messageBitIndex += generator->GetNumBitsForMessage(); + builderBitIndex += generator->GetNumBitsForBuilder(); + } + for (int i = 0; i < descriptor->extension_count(); i++) { + FieldGenerator* generator = MakeGenerator(descriptor->extension(i), + messageBitIndex, builderBitIndex); + extension_generators_[i].reset(generator); + messageBitIndex += generator->GetNumBitsForMessage(); + builderBitIndex += generator->GetNumBitsForBuilder(); + } +} + +FieldGenerator* FieldGeneratorMap::MakeGenerator( + const FieldDescriptor* field, int messageBitIndex, int builderBitIndex) { + if (field->is_repeated()) { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + return new RepeatedMessageFieldGenerator( + field, messageBitIndex, builderBitIndex); + case JAVATYPE_ENUM: + return new RepeatedEnumFieldGenerator( + field, messageBitIndex, builderBitIndex); + case JAVATYPE_STRING: + return new RepeatedStringFieldGenerator( + field, messageBitIndex, builderBitIndex); + default: + return new RepeatedPrimitiveFieldGenerator( + field, messageBitIndex, builderBitIndex); + } + } else { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + return new MessageFieldGenerator( + field, messageBitIndex, builderBitIndex); + case JAVATYPE_ENUM: + return new EnumFieldGenerator( + field, messageBitIndex, builderBitIndex); + case JAVATYPE_STRING: + return new StringFieldGenerator( + field, messageBitIndex, builderBitIndex); + default: + return new PrimitiveFieldGenerator( + field, messageBitIndex, builderBitIndex); + } + } +} + +FieldGeneratorMap::~FieldGeneratorMap() {} + +const FieldGenerator& FieldGeneratorMap::get( + const FieldDescriptor* field) const { + GOOGLE_CHECK_EQ(field->containing_type(), descriptor_); + return *field_generators_[field->index()]; +} + +const FieldGenerator& FieldGeneratorMap::get_extension(int index) const { + return *extension_generators_[index]; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_field.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_field.h new file mode 100644 index 0000000..4dd0efd --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_field.h @@ -0,0 +1,109 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +class FieldGenerator { + public: + FieldGenerator() {} + virtual ~FieldGenerator(); + + virtual int GetNumBitsForMessage() const = 0; + virtual int GetNumBitsForBuilder() const = 0; + virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0; + virtual void GenerateMembers(io::Printer* printer) const = 0; + virtual void GenerateBuilderMembers(io::Printer* printer) const = 0; + virtual void GenerateInitializationCode(io::Printer* printer) const = 0; + virtual void GenerateBuilderClearCode(io::Printer* printer) const = 0; + virtual void GenerateMergingCode(io::Printer* printer) const = 0; + virtual void GenerateBuildingCode(io::Printer* printer) const = 0; + virtual void GenerateParsingCode(io::Printer* printer) const = 0; + virtual void GenerateParsingCodeFromPacked(io::Printer* printer) const; + virtual void GenerateParsingDoneCode(io::Printer* printer) const = 0; + virtual void GenerateSerializationCode(io::Printer* printer) const = 0; + virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; + virtual void GenerateFieldBuilderInitializationCode(io::Printer* printer) + const = 0; + + virtual void GenerateEqualsCode(io::Printer* printer) const = 0; + virtual void GenerateHashCode(io::Printer* printer) const = 0; + + virtual string GetBoxedType() const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); +}; + +// Convenience class which constructs FieldGenerators for a Descriptor. +class FieldGeneratorMap { + public: + explicit FieldGeneratorMap(const Descriptor* descriptor); + ~FieldGeneratorMap(); + + const FieldGenerator& get(const FieldDescriptor* field) const; + const FieldGenerator& get_extension(int index) const; + + private: + const Descriptor* descriptor_; + scoped_array > field_generators_; + scoped_array > extension_generators_; + + static FieldGenerator* MakeGenerator(const FieldDescriptor* field, + int messageBitIndex, int builderBitIndex); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_file.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_file.cc new file mode 100644 index 0000000..f43e550 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_file.cc @@ -0,0 +1,490 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { + + +// Recursively searches the given message to collect extensions. +// Returns true if all the extensions can be recognized. The extensions will be +// appended in to the extensions parameter. +// Returns false when there are unknown fields, in which case the data in the +// extensions output parameter is not reliable and should be discarded. +bool CollectExtensions(const Message& message, + vector* extensions) { + const Reflection* reflection = message.GetReflection(); + + // There are unknown fields that could be extensions, thus this call fails. + if (reflection->GetUnknownFields(message).field_count() > 0) return false; + + vector fields; + reflection->ListFields(message, &fields); + + for (int i = 0; i < fields.size(); i++) { + if (fields[i]->is_extension()) extensions->push_back(fields[i]); + + if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) { + if (fields[i]->is_repeated()) { + int size = reflection->FieldSize(message, fields[i]); + for (int j = 0; j < size; j++) { + const Message& sub_message = + reflection->GetRepeatedMessage(message, fields[i], j); + if (!CollectExtensions(sub_message, extensions)) return false; + } + } else { + const Message& sub_message = reflection->GetMessage(message, fields[i]); + if (!CollectExtensions(sub_message, extensions)) return false; + } + } + } + + return true; +} + +// Finds all extensions in the given message and its sub-messages. If the +// message contains unknown fields (which could be extensions), then those +// extensions are defined in alternate_pool. +// The message will be converted to a DynamicMessage backed by alternate_pool +// in order to handle this case. +void CollectExtensions(const FileDescriptorProto& file_proto, + const DescriptorPool& alternate_pool, + vector* extensions, + const string& file_data) { + if (!CollectExtensions(file_proto, extensions)) { + // There are unknown fields in the file_proto, which are probably + // extensions. We need to parse the data into a dynamic message based on the + // builder-pool to find out all extensions. + const Descriptor* file_proto_desc = alternate_pool.FindMessageTypeByName( + file_proto.GetDescriptor()->full_name()); + GOOGLE_CHECK(file_proto_desc) + << "Find unknown fields in FileDescriptorProto when building " + << file_proto.name() + << ". It's likely that those fields are custom options, however, " + "descriptor.proto is not in the transitive dependencies. " + "This normally should not happen. Please report a bug."; + DynamicMessageFactory factory; + scoped_ptr dynamic_file_proto( + factory.GetPrototype(file_proto_desc)->New()); + GOOGLE_CHECK(dynamic_file_proto.get() != NULL); + GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data)); + + // Collect the extensions again from the dynamic message. There should be no + // more unknown fields this time, i.e. all the custom options should be + // parsed as extensions now. + extensions->clear(); + GOOGLE_CHECK(CollectExtensions(*dynamic_file_proto, extensions)) + << "Find unknown fields in FileDescriptorProto when building " + << file_proto.name() + << ". It's likely that those fields are custom options, however, " + "those options cannot be recognized in the builder pool. " + "This normally should not happen. Please report a bug."; + } +} + + +} // namespace + +FileGenerator::FileGenerator(const FileDescriptor* file) + : file_(file), + java_package_(FileJavaPackage(file)), + classname_(FileClassName(file)) { +} + +FileGenerator::~FileGenerator() {} + +bool FileGenerator::Validate(string* error) { + // Check that no class name matches the file's class name. This is a common + // problem that leads to Java compile errors that can be hard to understand. + // It's especially bad when using the java_multiple_files, since we would + // end up overwriting the outer class with one of the inner ones. + + bool found_conflict = false; + for (int i = 0; i < file_->enum_type_count() && !found_conflict; i++) { + if (file_->enum_type(i)->name() == classname_) { + found_conflict = true; + } + } + for (int i = 0; i < file_->message_type_count() && !found_conflict; i++) { + if (file_->message_type(i)->name() == classname_) { + found_conflict = true; + } + } + for (int i = 0; i < file_->service_count() && !found_conflict; i++) { + if (file_->service(i)->name() == classname_) { + found_conflict = true; + } + } + + if (found_conflict) { + error->assign(file_->name()); + error->append( + ": Cannot generate Java output because the file's outer class name, \""); + error->append(classname_); + error->append( + "\", matches the name of one of the types declared inside it. " + "Please either rename the type or use the java_outer_classname " + "option to specify a different outer class name for the .proto file."); + return false; + } + + return true; +} + +void FileGenerator::Generate(io::Printer* printer) { + // We don't import anything because we refer to all classes by their + // fully-qualified names in the generated source. + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", file_->name()); + if (!java_package_.empty()) { + printer->Print( + "package $package$;\n" + "\n", + "package", java_package_); + } + printer->Print( + "public final class $classname$ {\n" + " private $classname$() {}\n", + "classname", classname_); + printer->Indent(); + + // ----------------------------------------------------------------- + + printer->Print( + "public static void registerAllExtensions(\n" + " com.google.protobuf.ExtensionRegistry$lite$ registry) {\n", + "lite", HasDescriptorMethods(file_) ? "" : "Lite"); + + printer->Indent(); + + for (int i = 0; i < file_->extension_count(); i++) { + ExtensionGenerator(file_->extension(i)).GenerateRegistrationCode(printer); + } + + for (int i = 0; i < file_->message_type_count(); i++) { + MessageGenerator(file_->message_type(i)) + .GenerateExtensionRegistrationCode(printer); + } + + printer->Outdent(); + printer->Print( + "}\n"); + + // ----------------------------------------------------------------- + + if (!file_->options().java_multiple_files()) { + for (int i = 0; i < file_->enum_type_count(); i++) { + EnumGenerator(file_->enum_type(i)).Generate(printer); + } + for (int i = 0; i < file_->message_type_count(); i++) { + MessageGenerator messageGenerator(file_->message_type(i)); + messageGenerator.GenerateInterface(printer); + messageGenerator.Generate(printer); + } + if (HasGenericServices(file_)) { + for (int i = 0; i < file_->service_count(); i++) { + ServiceGenerator(file_->service(i)).Generate(printer); + } + } + } + + // Extensions must be generated in the outer class since they are values, + // not classes. + for (int i = 0; i < file_->extension_count(); i++) { + ExtensionGenerator(file_->extension(i)).Generate(printer); + } + + // Static variables. + for (int i = 0; i < file_->message_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + MessageGenerator(file_->message_type(i)).GenerateStaticVariables(printer); + } + + printer->Print("\n"); + + if (HasDescriptorMethods(file_)) { + GenerateEmbeddedDescriptor(printer); + } else { + printer->Print( + "static {\n"); + printer->Indent(); + + for (int i = 0; i < file_->message_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + MessageGenerator(file_->message_type(i)) + .GenerateStaticVariableInitializers(printer); + } + + printer->Outdent(); + printer->Print( + "}\n"); + } + + printer->Print( + "\n" + "// @@protoc_insertion_point(outer_class_scope)\n"); + + printer->Outdent(); + printer->Print("}\n"); +} + +void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) { + // Embed the descriptor. We simply serialize the entire FileDescriptorProto + // and embed it as a string literal, which is parsed and built into real + // descriptors at initialization time. We unfortunately have to put it in + // a string literal, not a byte array, because apparently using a literal + // byte array causes the Java compiler to generate *instructions* to + // initialize each and every byte of the array, e.g. as if you typed: + // b[0] = 123; b[1] = 456; b[2] = 789; + // This makes huge bytecode files and can easily hit the compiler's internal + // code size limits (error "code to large"). String literals are apparently + // embedded raw, which is what we want. + FileDescriptorProto file_proto; + file_->CopyTo(&file_proto); + + string file_data; + file_proto.SerializeToString(&file_data); + + printer->Print( + "public static com.google.protobuf.Descriptors.FileDescriptor\n" + " getDescriptor() {\n" + " return descriptor;\n" + "}\n" + "private static com.google.protobuf.Descriptors.FileDescriptor\n" + " descriptor;\n" + "static {\n" + " java.lang.String[] descriptorData = {\n"); + printer->Indent(); + printer->Indent(); + + // Only write 40 bytes per line. + static const int kBytesPerLine = 40; + for (int i = 0; i < file_data.size(); i += kBytesPerLine) { + if (i > 0) { + // Every 400 lines, start a new string literal, in order to avoid the + // 64k length limit. + if (i % 400 == 0) { + printer->Print(",\n"); + } else { + printer->Print(" +\n"); + } + } + printer->Print("\"$data$\"", + "data", CEscape(file_data.substr(i, kBytesPerLine))); + } + + printer->Outdent(); + printer->Print("\n};\n"); + + // ----------------------------------------------------------------- + // Create the InternalDescriptorAssigner. + + printer->Print( + "com.google.protobuf.Descriptors.FileDescriptor." + "InternalDescriptorAssigner assigner =\n" + " new com.google.protobuf.Descriptors.FileDescriptor." + "InternalDescriptorAssigner() {\n" + " public com.google.protobuf.ExtensionRegistry assignDescriptors(\n" + " com.google.protobuf.Descriptors.FileDescriptor root) {\n" + " descriptor = root;\n"); + + printer->Indent(); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < file_->message_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + MessageGenerator(file_->message_type(i)) + .GenerateStaticVariableInitializers(printer); + } + for (int i = 0; i < file_->extension_count(); i++) { + // TODO(kenton): Reuse ExtensionGenerator objects? + ExtensionGenerator(file_->extension(i)) + .GenerateNonNestedInitializationCode(printer); + } + + // Proto compiler builds a DescriptorPool, which holds all the descriptors to + // generate, when processing the ".proto" files. We call this DescriptorPool + // the parsed pool (a.k.a. file_->pool()). + // + // Note that when users try to extend the (.*)DescriptorProto in their + // ".proto" files, it does not affect the pre-built FileDescriptorProto class + // in proto compiler. When we put the descriptor data in the file_proto, those + // extensions become unknown fields. + // + // Now we need to find out all the extension value to the (.*)DescriptorProto + // in the file_proto message, and prepare an ExtensionRegistry to return. + // + // To find those extensions, we need to parse the data into a dynamic message + // of the FileDescriptor based on the builder-pool, then we can use + // reflections to find all extension fields + vector extensions; + CollectExtensions(file_proto, *file_->pool(), &extensions, file_data); + + if (extensions.size() > 0) { + // Must construct an ExtensionRegistry containing all existing extensions + // and return it. + printer->Print( + "com.google.protobuf.ExtensionRegistry registry =\n" + " com.google.protobuf.ExtensionRegistry.newInstance();\n"); + for (int i = 0; i < extensions.size(); i++) { + ExtensionGenerator(extensions[i]).GenerateRegistrationCode(printer); + } + printer->Print( + "return registry;\n"); + } else { + printer->Print( + "return null;\n"); + } + + printer->Outdent(); + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + " };\n"); + + // ----------------------------------------------------------------- + // Invoke internalBuildGeneratedFileFrom() to build the file. + + printer->Print( + "com.google.protobuf.Descriptors.FileDescriptor\n" + " .internalBuildGeneratedFileFrom(descriptorData,\n" + " new com.google.protobuf.Descriptors.FileDescriptor[] {\n"); + + for (int i = 0; i < file_->dependency_count(); i++) { + if (ShouldIncludeDependency(file_->dependency(i))) { + printer->Print( + " $dependency$.getDescriptor(),\n", + "dependency", ClassName(file_->dependency(i))); + } + } + + printer->Print( + " }, assigner);\n"); + + printer->Outdent(); + printer->Print( + "}\n"); +} + +template +static void GenerateSibling(const string& package_dir, + const string& java_package, + const DescriptorClass* descriptor, + GeneratorContext* context, + vector* file_list, + const string& name_suffix, + void (GeneratorClass::*pfn)(io::Printer* printer)) { + string filename = package_dir + descriptor->name() + name_suffix + ".java"; + file_list->push_back(filename); + + scoped_ptr output(context->Open(filename)); + io::Printer printer(output.get(), '$'); + + printer.Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", descriptor->file()->name()); + if (!java_package.empty()) { + printer.Print( + "package $package$;\n" + "\n", + "package", java_package); + } + + GeneratorClass generator(descriptor); + (generator.*pfn)(&printer); +} + +void FileGenerator::GenerateSiblings(const string& package_dir, + GeneratorContext* context, + vector* file_list) { + if (file_->options().java_multiple_files()) { + for (int i = 0; i < file_->enum_type_count(); i++) { + GenerateSibling(package_dir, java_package_, + file_->enum_type(i), + context, file_list, "", + &EnumGenerator::Generate); + } + for (int i = 0; i < file_->message_type_count(); i++) { + GenerateSibling(package_dir, java_package_, + file_->message_type(i), + context, file_list, "OrBuilder", + &MessageGenerator::GenerateInterface); + GenerateSibling(package_dir, java_package_, + file_->message_type(i), + context, file_list, "", + &MessageGenerator::Generate); + } + if (HasGenericServices(file_)) { + for (int i = 0; i < file_->service_count(); i++) { + GenerateSibling(package_dir, java_package_, + file_->service(i), + context, file_list, "", + &ServiceGenerator::Generate); + } + } + } +} + +bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor) { + return true; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_file.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_file.h new file mode 100644 index 0000000..5991146 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_file.h @@ -0,0 +1,101 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { + class FileDescriptor; // descriptor.h + namespace io { + class Printer; // printer.h + } + namespace compiler { + class GeneratorContext; // code_generator.h + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +class FileGenerator { + public: + explicit FileGenerator(const FileDescriptor* file); + ~FileGenerator(); + + // Checks for problems that would otherwise lead to cryptic compile errors. + // Returns true if there are no problems, or writes an error description to + // the given string and returns false otherwise. + bool Validate(string* error); + + void Generate(io::Printer* printer); + + // If we aren't putting everything into one file, this will write all the + // files other than the outer file (i.e. one for each message, enum, and + // service type). + void GenerateSiblings(const string& package_dir, + GeneratorContext* generator_context, + vector* file_list); + + const string& java_package() { return java_package_; } + const string& classname() { return classname_; } + + + private: + // Returns whether the dependency should be included in the output file. + // Always returns true for opensource, but used internally at Google to help + // improve compatibility with version 1 of protocol buffers. + bool ShouldIncludeDependency(const FileDescriptor* descriptor); + + const FileDescriptor* file_; + string java_package_; + string classname_; + + + void GenerateEmbeddedDescriptor(io::Printer* printer); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_generator.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_generator.cc new file mode 100644 index 0000000..e6c79ab --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_generator.cc @@ -0,0 +1,128 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + + +JavaGenerator::JavaGenerator() {} +JavaGenerator::~JavaGenerator() {} + +bool JavaGenerator::Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const { + // ----------------------------------------------------------------- + // parse generator options + + // Name a file where we will write a list of generated file names, one + // per line. + string output_list_file; + + + vector > options; + ParseGeneratorParameter(parameter, &options); + + for (int i = 0; i < options.size(); i++) { + if (options[i].first == "output_list_file") { + output_list_file = options[i].second; + } else { + *error = "Unknown generator option: " + options[i].first; + return false; + } + } + + // ----------------------------------------------------------------- + + + if (file->options().optimize_for() == FileOptions::LITE_RUNTIME && + file->options().java_generate_equals_and_hash()) { + *error = "The \"java_generate_equals_and_hash\" option is incompatible " + "with \"optimize_for = LITE_RUNTIME\". You must optimize for " + "SPEED or CODE_SIZE if you want to use this option."; + return false; + } + + FileGenerator file_generator(file); + if (!file_generator.Validate(error)) { + return false; + } + + string package_dir = JavaPackageToDir(file_generator.java_package()); + + vector all_files; + + string java_filename = package_dir; + java_filename += file_generator.classname(); + java_filename += ".java"; + all_files.push_back(java_filename); + + // Generate main java file. + scoped_ptr output( + context->Open(java_filename)); + io::Printer printer(output.get(), '$'); + file_generator.Generate(&printer); + + // Generate sibling files. + file_generator.GenerateSiblings(package_dir, context, &all_files); + + // Generate output list if requested. + if (!output_list_file.empty()) { + // Generate output list. This is just a simple text file placed in a + // deterministic location which lists the .java files being generated. + scoped_ptr srclist_raw_output( + context->Open(output_list_file)); + io::Printer srclist_printer(srclist_raw_output.get(), '$'); + for (int i = 0; i < all_files.size(); i++) { + srclist_printer.Print("$filename$\n", "filename", all_files[i]); + } + } + + return true; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_generator.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_generator.h new file mode 100644 index 0000000..888b8d8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_generator.h @@ -0,0 +1,72 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Generates Java code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// CodeGenerator implementation which generates Java code. If you create your +// own protocol compiler binary and you want it to support Java output, you +// can do so by registering an instance of this CodeGenerator with the +// CommandLineInterface in your main() function. +class LIBPROTOC_EXPORT JavaGenerator : public CodeGenerator { + public: + JavaGenerator(); + ~JavaGenerator(); + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_helpers.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_helpers.cc new file mode 100644 index 0000000..cf241b8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_helpers.cc @@ -0,0 +1,500 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +const char kThickSeparator[] = + "// ===================================================================\n"; +const char kThinSeparator[] = + "// -------------------------------------------------------------------\n"; + +namespace { + +const char* kDefaultPackage = ""; + +const string& FieldName(const FieldDescriptor* field) { + // Groups are hacky: The name of the field is just the lower-cased name + // of the group type. In Java, though, we would like to retain the original + // capitalization of the type name. + if (GetType(field) == FieldDescriptor::TYPE_GROUP) { + return field->message_type()->name(); + } else { + return field->name(); + } +} + +string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) { + string result; + // Note: I distrust ctype.h due to locales. + for (int i = 0; i < input.size(); i++) { + if ('a' <= input[i] && input[i] <= 'z') { + if (cap_next_letter) { + result += input[i] + ('A' - 'a'); + } else { + result += input[i]; + } + cap_next_letter = false; + } else if ('A' <= input[i] && input[i] <= 'Z') { + if (i == 0 && !cap_next_letter) { + // Force first letter to lower-case unless explicitly told to + // capitalize it. + result += input[i] + ('a' - 'A'); + } else { + // Capital letters after the first are left as-is. + result += input[i]; + } + cap_next_letter = false; + } else if ('0' <= input[i] && input[i] <= '9') { + result += input[i]; + cap_next_letter = true; + } else { + cap_next_letter = true; + } + } + return result; +} + +} // namespace + +string UnderscoresToCamelCase(const FieldDescriptor* field) { + return UnderscoresToCamelCaseImpl(FieldName(field), false); +} + +string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) { + return UnderscoresToCamelCaseImpl(FieldName(field), true); +} + +string UnderscoresToCamelCase(const MethodDescriptor* method) { + return UnderscoresToCamelCaseImpl(method->name(), false); +} + +string StripProto(const string& filename) { + if (HasSuffixString(filename, ".protodevel")) { + return StripSuffixString(filename, ".protodevel"); + } else { + return StripSuffixString(filename, ".proto"); + } +} + +string FileClassName(const FileDescriptor* file) { + if (file->options().has_java_outer_classname()) { + return file->options().java_outer_classname(); + } else { + string basename; + string::size_type last_slash = file->name().find_last_of('/'); + if (last_slash == string::npos) { + basename = file->name(); + } else { + basename = file->name().substr(last_slash + 1); + } + return UnderscoresToCamelCaseImpl(StripProto(basename), true); + } +} + +string FileJavaPackage(const FileDescriptor* file) { + string result; + + if (file->options().has_java_package()) { + result = file->options().java_package(); + } else { + result = kDefaultPackage; + if (!file->package().empty()) { + if (!result.empty()) result += '.'; + result += file->package(); + } + } + + + return result; +} + +string JavaPackageToDir(string package_name) { + string package_dir = + StringReplace(package_name, ".", "/", true); + if (!package_dir.empty()) package_dir += "/"; + return package_dir; +} + +string ToJavaName(const string& full_name, const FileDescriptor* file) { + string result; + if (file->options().java_multiple_files()) { + result = FileJavaPackage(file); + } else { + result = ClassName(file); + } + if (!result.empty()) { + result += '.'; + } + if (file->package().empty()) { + result += full_name; + } else { + // Strip the proto package from full_name since we've replaced it with + // the Java package. + result += full_name.substr(file->package().size() + 1); + } + return result; +} + +string ClassName(const Descriptor* descriptor) { + return ToJavaName(descriptor->full_name(), descriptor->file()); +} + +string ClassName(const EnumDescriptor* descriptor) { + return ToJavaName(descriptor->full_name(), descriptor->file()); +} + +string ClassName(const ServiceDescriptor* descriptor) { + return ToJavaName(descriptor->full_name(), descriptor->file()); +} + +string ClassName(const FileDescriptor* descriptor) { + string result = FileJavaPackage(descriptor); + if (!result.empty()) result += '.'; + result += FileClassName(descriptor); + return result; +} + +string FieldConstantName(const FieldDescriptor *field) { + string name = field->name() + "_FIELD_NUMBER"; + UpperString(&name); + return name; +} + +FieldDescriptor::Type GetType(const FieldDescriptor* field) { + return field->type(); +} + +JavaType GetJavaType(const FieldDescriptor* field) { + switch (GetType(field)) { + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_SINT32: + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_SFIXED32: + return JAVATYPE_INT; + + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED64: + return JAVATYPE_LONG; + + case FieldDescriptor::TYPE_FLOAT: + return JAVATYPE_FLOAT; + + case FieldDescriptor::TYPE_DOUBLE: + return JAVATYPE_DOUBLE; + + case FieldDescriptor::TYPE_BOOL: + return JAVATYPE_BOOLEAN; + + case FieldDescriptor::TYPE_STRING: + return JAVATYPE_STRING; + + case FieldDescriptor::TYPE_BYTES: + return JAVATYPE_BYTES; + + case FieldDescriptor::TYPE_ENUM: + return JAVATYPE_ENUM; + + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + return JAVATYPE_MESSAGE; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return JAVATYPE_INT; +} + +const char* BoxedPrimitiveTypeName(JavaType type) { + switch (type) { + case JAVATYPE_INT : return "java.lang.Integer"; + case JAVATYPE_LONG : return "java.lang.Long"; + case JAVATYPE_FLOAT : return "java.lang.Float"; + case JAVATYPE_DOUBLE : return "java.lang.Double"; + case JAVATYPE_BOOLEAN: return "java.lang.Boolean"; + case JAVATYPE_STRING : return "java.lang.String"; + case JAVATYPE_BYTES : return "com.google.protobuf.ByteString"; + case JAVATYPE_ENUM : return NULL; + case JAVATYPE_MESSAGE: return NULL; + + // No default because we want the compiler to complain if any new + // JavaTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +bool AllAscii(const string& text) { + for (int i = 0; i < text.size(); i++) { + if ((text[i] & 0x80) != 0) { + return false; + } + } + return true; +} + +string DefaultValue(const FieldDescriptor* field) { + // Switch on CppType since we need to know which default_value_* method + // of FieldDescriptor to call. + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + return SimpleItoa(field->default_value_int32()); + case FieldDescriptor::CPPTYPE_UINT32: + // Need to print as a signed int since Java has no unsigned. + return SimpleItoa(static_cast(field->default_value_uint32())); + case FieldDescriptor::CPPTYPE_INT64: + return SimpleItoa(field->default_value_int64()) + "L"; + case FieldDescriptor::CPPTYPE_UINT64: + return SimpleItoa(static_cast(field->default_value_uint64())) + + "L"; + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value = field->default_value_double(); + if (value == numeric_limits::infinity()) { + return "Double.POSITIVE_INFINITY"; + } else if (value == -numeric_limits::infinity()) { + return "Double.NEGATIVE_INFINITY"; + } else if (value != value) { + return "Double.NaN"; + } else { + return SimpleDtoa(value) + "D"; + } + } + case FieldDescriptor::CPPTYPE_FLOAT: { + float value = field->default_value_float(); + if (value == numeric_limits::infinity()) { + return "Float.POSITIVE_INFINITY"; + } else if (value == -numeric_limits::infinity()) { + return "Float.NEGATIVE_INFINITY"; + } else if (value != value) { + return "Float.NaN"; + } else { + return SimpleFtoa(value) + "F"; + } + } + case FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool() ? "true" : "false"; + case FieldDescriptor::CPPTYPE_STRING: + if (GetType(field) == FieldDescriptor::TYPE_BYTES) { + if (field->has_default_value()) { + // See comments in Internal.java for gory details. + return strings::Substitute( + "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")", + CEscape(field->default_value_string())); + } else { + return "com.google.protobuf.ByteString.EMPTY"; + } + } else { + if (AllAscii(field->default_value_string())) { + // All chars are ASCII. In this case CEscape() works fine. + return "\"" + CEscape(field->default_value_string()) + "\""; + } else { + // See comments in Internal.java for gory details. + return strings::Substitute( + "com.google.protobuf.Internal.stringDefaultValue(\"$0\")", + CEscape(field->default_value_string())); + } + } + + case FieldDescriptor::CPPTYPE_ENUM: + return ClassName(field->enum_type()) + "." + + field->default_value_enum()->name(); + + case FieldDescriptor::CPPTYPE_MESSAGE: + return ClassName(field->message_type()) + ".getDefaultInstance()"; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return ""; +} + +bool IsDefaultValueJavaDefault(const FieldDescriptor* field) { + // Switch on CppType since we need to know which default_value_* method + // of FieldDescriptor to call. + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + return field->default_value_int32() == 0; + case FieldDescriptor::CPPTYPE_UINT32: + return field->default_value_uint32() == 0; + case FieldDescriptor::CPPTYPE_INT64: + return field->default_value_int64() == 0L; + case FieldDescriptor::CPPTYPE_UINT64: + return field->default_value_uint64() == 0L; + case FieldDescriptor::CPPTYPE_DOUBLE: + return field->default_value_double() == 0.0; + case FieldDescriptor::CPPTYPE_FLOAT: + return field->default_value_float() == 0.0; + case FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool() == false; + + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + return false; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return false; +} + +const char* bit_masks[] = { + "0x00000001", + "0x00000002", + "0x00000004", + "0x00000008", + "0x00000010", + "0x00000020", + "0x00000040", + "0x00000080", + + "0x00000100", + "0x00000200", + "0x00000400", + "0x00000800", + "0x00001000", + "0x00002000", + "0x00004000", + "0x00008000", + + "0x00010000", + "0x00020000", + "0x00040000", + "0x00080000", + "0x00100000", + "0x00200000", + "0x00400000", + "0x00800000", + + "0x01000000", + "0x02000000", + "0x04000000", + "0x08000000", + "0x10000000", + "0x20000000", + "0x40000000", + "0x80000000", +}; + +string GetBitFieldName(int index) { + string varName = "bitField"; + varName += SimpleItoa(index); + varName += "_"; + return varName; +} + +string GetBitFieldNameForBit(int bitIndex) { + return GetBitFieldName(bitIndex / 32); +} + +namespace { + +string GenerateGetBitInternal(const string& prefix, int bitIndex) { + string varName = prefix + GetBitFieldNameForBit(bitIndex); + int bitInVarIndex = bitIndex % 32; + + string mask = bit_masks[bitInVarIndex]; + string result = "((" + varName + " & " + mask + ") == " + mask + ")"; + return result; +} + +string GenerateSetBitInternal(const string& prefix, int bitIndex) { + string varName = prefix + GetBitFieldNameForBit(bitIndex); + int bitInVarIndex = bitIndex % 32; + + string mask = bit_masks[bitInVarIndex]; + string result = varName + " |= " + mask; + return result; +} + +} // namespace + +string GenerateGetBit(int bitIndex) { + return GenerateGetBitInternal("", bitIndex); +} + +string GenerateSetBit(int bitIndex) { + return GenerateSetBitInternal("", bitIndex); +} + +string GenerateClearBit(int bitIndex) { + string varName = GetBitFieldNameForBit(bitIndex); + int bitInVarIndex = bitIndex % 32; + + string mask = bit_masks[bitInVarIndex]; + string result = varName + " = (" + varName + " & ~" + mask + ")"; + return result; +} + +string GenerateGetBitFromLocal(int bitIndex) { + return GenerateGetBitInternal("from_", bitIndex); +} + +string GenerateSetBitToLocal(int bitIndex) { + return GenerateSetBitInternal("to_", bitIndex); +} + +string GenerateGetBitMutableLocal(int bitIndex) { + return GenerateGetBitInternal("mutable_", bitIndex); +} + +string GenerateSetBitMutableLocal(int bitIndex) { + return GenerateSetBitInternal("mutable_", bitIndex); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_helpers.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_helpers.h new file mode 100644 index 0000000..3937f06 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_helpers.h @@ -0,0 +1,220 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// Commonly-used separator comments. Thick is a line of '=', thin is a line +// of '-'. +extern const char kThickSeparator[]; +extern const char kThinSeparator[]; + +// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes +// "fooBarBaz" or "FooBarBaz", respectively. +string UnderscoresToCamelCase(const FieldDescriptor* field); +string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field); + +// Similar, but for method names. (Typically, this merely has the effect +// of lower-casing the first letter of the name.) +string UnderscoresToCamelCase(const MethodDescriptor* method); + +// Strips ".proto" or ".protodevel" from the end of a filename. +string StripProto(const string& filename); + +// Gets the unqualified class name for the file. Each .proto file becomes a +// single Java class, with all its contents nested in that class. +string FileClassName(const FileDescriptor* file); + +// Returns the file's Java package name. +string FileJavaPackage(const FileDescriptor* file); + +// Returns output directory for the given package name. +string JavaPackageToDir(string package_name); + +// Converts the given fully-qualified name in the proto namespace to its +// fully-qualified name in the Java namespace, given that it is in the given +// file. +string ToJavaName(const string& full_name, const FileDescriptor* file); + +// These return the fully-qualified class name corresponding to the given +// descriptor. +string ClassName(const Descriptor* descriptor); +string ClassName(const EnumDescriptor* descriptor); +string ClassName(const ServiceDescriptor* descriptor); +string ClassName(const FileDescriptor* descriptor); + +inline string ExtensionIdentifierName(const FieldDescriptor* descriptor) { + return ToJavaName(descriptor->full_name(), descriptor->file()); +} + +// Get the unqualified name that should be used for a field's field +// number constant. +string FieldConstantName(const FieldDescriptor *field); + +// Returns the type of the FieldDescriptor. +// This does nothing interesting for the open source release, but is used for +// hacks that improve compatability with version 1 protocol buffers at Google. +FieldDescriptor::Type GetType(const FieldDescriptor* field); + +enum JavaType { + JAVATYPE_INT, + JAVATYPE_LONG, + JAVATYPE_FLOAT, + JAVATYPE_DOUBLE, + JAVATYPE_BOOLEAN, + JAVATYPE_STRING, + JAVATYPE_BYTES, + JAVATYPE_ENUM, + JAVATYPE_MESSAGE +}; + +JavaType GetJavaType(const FieldDescriptor* field); + +// Get the fully-qualified class name for a boxed primitive type, e.g. +// "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message +// types. +const char* BoxedPrimitiveTypeName(JavaType type); + +string DefaultValue(const FieldDescriptor* field); +bool IsDefaultValueJavaDefault(const FieldDescriptor* field); + +// Does this message class keep track of unknown fields? +inline bool HasUnknownFields(const Descriptor* descriptor) { + return descriptor->file()->options().optimize_for() != + FileOptions::LITE_RUNTIME; +} + +// Does this message class have generated parsing, serialization, and other +// standard methods for which reflection-based fallback implementations exist? +inline bool HasGeneratedMethods(const Descriptor* descriptor) { + return descriptor->file()->options().optimize_for() != + FileOptions::CODE_SIZE; +} + +// Does this message have specialized equals() and hashCode() methods? +inline bool HasEqualsAndHashCode(const Descriptor* descriptor) { + return descriptor->file()->options().java_generate_equals_and_hash(); +} + +// Does this message class have descriptor and reflection methods? +inline bool HasDescriptorMethods(const Descriptor* descriptor) { + return descriptor->file()->options().optimize_for() != + FileOptions::LITE_RUNTIME; +} +inline bool HasDescriptorMethods(const EnumDescriptor* descriptor) { + return descriptor->file()->options().optimize_for() != + FileOptions::LITE_RUNTIME; +} +inline bool HasDescriptorMethods(const FileDescriptor* descriptor) { + return descriptor->options().optimize_for() != + FileOptions::LITE_RUNTIME; +} + +inline bool HasNestedBuilders(const Descriptor* descriptor) { + // The proto-lite version doesn't support nested builders. + return descriptor->file()->options().optimize_for() != + FileOptions::LITE_RUNTIME; +} + +// Should we generate generic services for this file? +inline bool HasGenericServices(const FileDescriptor *file) { + return file->service_count() > 0 && + file->options().optimize_for() != FileOptions::LITE_RUNTIME && + file->options().java_generic_services(); +} + + +// Methods for shared bitfields. + +// Gets the name of the shared bitfield for the given index. +string GetBitFieldName(int index); + +// Gets the name of the shared bitfield for the given bit index. +// Effectively, GetBitFieldName(bitIndex / 32) +string GetBitFieldNameForBit(int bitIndex); + +// Generates the java code for the expression that returns the boolean value +// of the bit of the shared bitfields for the given bit index. +// Example: "((bitField1_ & 0x04) == 0x04)" +string GenerateGetBit(int bitIndex); + +// Generates the java code for the expression that sets the bit of the shared +// bitfields for the given bit index. +// Example: "bitField1_ = (bitField1_ | 0x04)" +string GenerateSetBit(int bitIndex); + +// Generates the java code for the expression that clears the bit of the shared +// bitfields for the given bit index. +// Example: "bitField1_ = (bitField1_ & ~0x04)" +string GenerateClearBit(int bitIndex); + +// Does the same as GenerateGetBit but operates on the bit field on a local +// variable. This is used by the builder to copy the value in the builder to +// the message. +// Example: "((from_bitField1_ & 0x04) == 0x04)" +string GenerateGetBitFromLocal(int bitIndex); + +// Does the same as GenerateSetBit but operates on the bit field on a local +// variable. This is used by the builder to copy the value in the builder to +// the message. +// Example: "to_bitField1_ = (to_bitField1_ | 0x04)" +string GenerateSetBitToLocal(int bitIndex); + +// Does the same as GenerateGetBit but operates on the bit field on a local +// variable. This is used by the parsing constructor to record if a repeated +// field is mutable. +// Example: "((mutable_bitField1_ & 0x04) == 0x04)" +string GenerateGetBitMutableLocal(int bitIndex); + +// Does the same as GenerateSetBit but operates on the bit field on a local +// variable. This is used by the parsing constructor to record if a repeated +// field is mutable. +// Example: "mutable_bitField1_ = (mutable_bitField1_ | 0x04)" +string GenerateSetBitMutableLocal(int bitIndex); + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message.cc new file mode 100644 index 0000000..9322e24 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message.cc @@ -0,0 +1,1435 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { + +void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { + // Print the field's proto-syntax definition as a comment. We don't want to + // print group bodies so we cut off after the first line. + string def = field->DebugString(); + printer->Print("// $def$\n", + "def", def.substr(0, def.find_first_of('\n'))); +} + +struct FieldOrderingByNumber { + inline bool operator()(const FieldDescriptor* a, + const FieldDescriptor* b) const { + return a->number() < b->number(); + } +}; + +struct ExtensionRangeOrdering { + bool operator()(const Descriptor::ExtensionRange* a, + const Descriptor::ExtensionRange* b) const { + return a->start < b->start; + } +}; + +// Sort the fields of the given Descriptor by number into a new[]'d array +// and return it. +const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { + const FieldDescriptor** fields = + new const FieldDescriptor*[descriptor->field_count()]; + for (int i = 0; i < descriptor->field_count(); i++) { + fields[i] = descriptor->field(i); + } + sort(fields, fields + descriptor->field_count(), + FieldOrderingByNumber()); + return fields; +} + +// Get an identifier that uniquely identifies this type within the file. +// This is used to declare static variables related to this type at the +// outermost file scope. +string UniqueFileScopeIdentifier(const Descriptor* descriptor) { + return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); +} + +// Returns true if the message type has any required fields. If it doesn't, +// we can optimize out calls to its isInitialized() method. +// +// already_seen is used to avoid checking the same type multiple times +// (and also to protect against recursion). +static bool HasRequiredFields( + const Descriptor* type, + hash_set* already_seen) { + if (already_seen->count(type) > 0) { + // The type is already in cache. This means that either: + // a. The type has no required fields. + // b. We are in the midst of checking if the type has required fields, + // somewhere up the stack. In this case, we know that if the type + // has any required fields, they'll be found when we return to it, + // and the whole call to HasRequiredFields() will return true. + // Therefore, we don't have to check if this type has required fields + // here. + return false; + } + already_seen->insert(type); + + // If the type has extensions, an extension with message type could contain + // required fields, so we have to be conservative and assume such an + // extension exists. + if (type->extension_range_count() > 0) return true; + + for (int i = 0; i < type->field_count(); i++) { + const FieldDescriptor* field = type->field(i); + if (field->is_required()) { + return true; + } + if (GetJavaType(field) == JAVATYPE_MESSAGE) { + if (HasRequiredFields(field->message_type(), already_seen)) { + return true; + } + } + } + + return false; +} + +static bool HasRequiredFields(const Descriptor* type) { + hash_set already_seen; + return HasRequiredFields(type, &already_seen); +} + +} // namespace + +// =================================================================== + +MessageGenerator::MessageGenerator(const Descriptor* descriptor) + : descriptor_(descriptor), + field_generators_(descriptor) { +} + +MessageGenerator::~MessageGenerator() {} + +void MessageGenerator::GenerateStaticVariables(io::Printer* printer) { + if (HasDescriptorMethods(descriptor_)) { + // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is + // used in the construction of descriptors, we have a tricky bootstrapping + // problem. To help control static initialization order, we make sure all + // descriptors and other static data that depends on them are members of + // the outermost class in the file. This way, they will be initialized in + // a deterministic order. + + map vars; + vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); + vars["index"] = SimpleItoa(descriptor_->index()); + vars["classname"] = ClassName(descriptor_); + if (descriptor_->containing_type() != NULL) { + vars["parent"] = UniqueFileScopeIdentifier( + descriptor_->containing_type()); + } + if (descriptor_->file()->options().java_multiple_files()) { + // We can only make these package-private since the classes that use them + // are in separate files. + vars["private"] = ""; + } else { + vars["private"] = "private "; + } + + // The descriptor for this type. + printer->Print(vars, + "$private$static com.google.protobuf.Descriptors.Descriptor\n" + " internal_$identifier$_descriptor;\n"); + + // And the FieldAccessorTable. + printer->Print(vars, + "$private$static\n" + " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n" + " internal_$identifier$_fieldAccessorTable;\n"); + } + + // Generate static members for all nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + MessageGenerator(descriptor_->nested_type(i)) + .GenerateStaticVariables(printer); + } +} + +void MessageGenerator::GenerateStaticVariableInitializers( + io::Printer* printer) { + if (HasDescriptorMethods(descriptor_)) { + map vars; + vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); + vars["index"] = SimpleItoa(descriptor_->index()); + vars["classname"] = ClassName(descriptor_); + if (descriptor_->containing_type() != NULL) { + vars["parent"] = UniqueFileScopeIdentifier( + descriptor_->containing_type()); + } + + // The descriptor for this type. + if (descriptor_->containing_type() == NULL) { + printer->Print(vars, + "internal_$identifier$_descriptor =\n" + " getDescriptor().getMessageTypes().get($index$);\n"); + } else { + printer->Print(vars, + "internal_$identifier$_descriptor =\n" + " internal_$parent$_descriptor.getNestedTypes().get($index$);\n"); + } + + // And the FieldAccessorTable. + printer->Print(vars, + "internal_$identifier$_fieldAccessorTable = new\n" + " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n" + " internal_$identifier$_descriptor,\n" + " new java.lang.String[] { "); + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print( + "\"$field_name$\", ", + "field_name", + UnderscoresToCapitalizedCamelCase(descriptor_->field(i))); + } + printer->Print( + "});\n"); + } + + // Generate static member initializers for all nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + MessageGenerator(descriptor_->nested_type(i)) + .GenerateStaticVariableInitializers(printer); + } +} + +// =================================================================== + +void MessageGenerator::GenerateInterface(io::Printer* printer) { + if (descriptor_->extension_range_count() > 0) { + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public interface $classname$OrBuilder extends\n" + " com.google.protobuf.GeneratedMessage.\n" + " ExtendableMessageOrBuilder<$classname$> {\n", + "classname", descriptor_->name()); + } else { + printer->Print( + "public interface $classname$OrBuilder extends \n" + " com.google.protobuf.GeneratedMessageLite.\n" + " ExtendableMessageOrBuilder<$classname$> {\n", + "classname", descriptor_->name()); + } + } else { + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public interface $classname$OrBuilder\n" + " extends com.google.protobuf.MessageOrBuilder {\n", + "classname", descriptor_->name()); + } else { + printer->Print( + "public interface $classname$OrBuilder\n" + " extends com.google.protobuf.MessageLiteOrBuilder {\n", + "classname", descriptor_->name()); + } + } + + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("\n"); + PrintFieldComment(printer, descriptor_->field(i)); + field_generators_.get(descriptor_->field(i)) + .GenerateInterfaceMembers(printer); + } + printer->Outdent(); + + printer->Print("}\n"); +} + +// =================================================================== + +void MessageGenerator::Generate(io::Printer* printer) { + bool is_own_file = + descriptor_->containing_type() == NULL && + descriptor_->file()->options().java_multiple_files(); + + WriteMessageDocComment(printer, descriptor_); + + // The builder_type stores the super type name of the nested Builder class. + string builder_type; + if (descriptor_->extension_range_count() > 0) { + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public $static$ final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n" + " $classname$> implements $classname$OrBuilder {\n", + "static", is_own_file ? "" : "static", + "classname", descriptor_->name()); + builder_type = strings::Substitute( + "com.google.protobuf.GeneratedMessage.ExtendableBuilder<$0, ?>", + ClassName(descriptor_)); + } else { + printer->Print( + "public $static$ final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n" + " $classname$> implements $classname$OrBuilder {\n", + "static", is_own_file ? "" : "static", + "classname", descriptor_->name()); + builder_type = strings::Substitute( + "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>", + ClassName(descriptor_)); + } + } else { + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public $static$ final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessage\n" + " implements $classname$OrBuilder {\n", + "static", is_own_file ? "" : "static", + "classname", descriptor_->name()); + builder_type = "com.google.protobuf.GeneratedMessage.Builder"; + } else { + printer->Print( + "public $static$ final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessageLite\n" + " implements $classname$OrBuilder {\n", + "static", is_own_file ? "" : "static", + "classname", descriptor_->name()); + builder_type = "com.google.protobuf.GeneratedMessageLite.Builder"; + } + } + printer->Indent(); + // Using builder_type, instead of Builder, prevents the Builder class from + // being loaded into PermGen space when the default instance is created. + // This optimizes the PermGen space usage for clients that do not modify + // messages. + printer->Print( + "// Use $classname$.newBuilder() to construct.\n" + "private $classname$($buildertype$ builder) {\n" + " super(builder);\n" + "$set_unknown_fields$\n" + "}\n", + "classname", descriptor_->name(), + "buildertype", builder_type, + "set_unknown_fields", HasUnknownFields(descriptor_) + ? " this.unknownFields = builder.getUnknownFields();" : ""); + printer->Print( + // Used when constructing the default instance, which cannot be initialized + // immediately because it may cyclically refer to other default instances. + "private $classname$(boolean noInit) {$set_default_unknown_fields$}\n" + "\n" + "private static final $classname$ defaultInstance;\n" + "public static $classname$ getDefaultInstance() {\n" + " return defaultInstance;\n" + "}\n" + "\n" + "public $classname$ getDefaultInstanceForType() {\n" + " return defaultInstance;\n" + "}\n" + "\n", + "classname", descriptor_->name(), + "set_default_unknown_fields", HasUnknownFields(descriptor_) + ? " this.unknownFields =" + " com.google.protobuf.UnknownFieldSet.getDefaultInstance(); " : ""); + + if (HasUnknownFields(descriptor_)) { + printer->Print( + "private final com.google.protobuf.UnknownFieldSet unknownFields;\n" + "" + "@java.lang.Override\n" + "public final com.google.protobuf.UnknownFieldSet\n" + " getUnknownFields() {\n" + " return this.unknownFields;\n" + "}\n"); + } + + if (HasGeneratedMethods(descriptor_)) { + GenerateParsingConstructor(printer); + } + + GenerateDescriptorMethods(printer); + GenerateParser(printer); + + // Nested types + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + EnumGenerator(descriptor_->enum_type(i)).Generate(printer); + } + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + MessageGenerator messageGenerator(descriptor_->nested_type(i)); + messageGenerator.GenerateInterface(printer); + messageGenerator.Generate(printer); + } + + // Integers for bit fields. + int totalBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + totalBits += field_generators_.get(descriptor_->field(i)) + .GetNumBitsForMessage(); + } + int totalInts = (totalBits + 31) / 32; + for (int i = 0; i < totalInts; i++) { + printer->Print("private int $bit_field_name$;\n", + "bit_field_name", GetBitFieldName(i)); + } + + // Fields + for (int i = 0; i < descriptor_->field_count(); i++) { + PrintFieldComment(printer, descriptor_->field(i)); + printer->Print("public static final int $constant_name$ = $number$;\n", + "constant_name", FieldConstantName(descriptor_->field(i)), + "number", SimpleItoa(descriptor_->field(i)->number())); + field_generators_.get(descriptor_->field(i)).GenerateMembers(printer); + printer->Print("\n"); + } + + // Called by the constructor, except in the case of the default instance, + // in which case this is called by static init code later on. + printer->Print("private void initFields() {\n"); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateInitializationCode(printer); + } + printer->Outdent(); + printer->Print("}\n"); + + if (HasGeneratedMethods(descriptor_)) { + GenerateIsInitialized(printer, MEMOIZE); + GenerateMessageSerializationMethods(printer); + } + + if (HasEqualsAndHashCode(descriptor_)) { + GenerateEqualsAndHashCode(printer); + } + + GenerateParseFromMethods(printer); + GenerateBuilder(printer); + + // Carefully initialize the default instance in such a way that it doesn't + // conflict with other initialization. + printer->Print( + "\n" + "static {\n" + " defaultInstance = new $classname$(true);\n" + " defaultInstance.initFields();\n" + "}\n" + "\n" + "// @@protoc_insertion_point(class_scope:$full_name$)\n", + "classname", descriptor_->name(), + "full_name", descriptor_->full_name()); + + // Extensions must be declared after the defaultInstance is initialized + // because the defaultInstance is used by the extension to lazily retrieve + // the outer class's FileDescriptor. + for (int i = 0; i < descriptor_->extension_count(); i++) { + ExtensionGenerator(descriptor_->extension(i)).Generate(printer); + } + + printer->Outdent(); + printer->Print("}\n\n"); +} + + +// =================================================================== + +void MessageGenerator:: +GenerateMessageSerializationMethods(io::Printer* printer) { + scoped_array sorted_fields( + SortFieldsByNumber(descriptor_)); + + vector sorted_extensions; + for (int i = 0; i < descriptor_->extension_range_count(); ++i) { + sorted_extensions.push_back(descriptor_->extension_range(i)); + } + sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeOrdering()); + + printer->Print( + "public void writeTo(com.google.protobuf.CodedOutputStream output)\n" + " throws java.io.IOException {\n"); + printer->Indent(); + // writeTo(CodedOutputStream output) might be invoked without + // getSerializedSize() ever being called, but we need the memoized + // sizes in case this message has packed fields. Rather than emit checks for + // each packed field, just call getSerializedSize() up front for all messages. + // In most cases, getSerializedSize() will have already been called anyway by + // one of the wrapper writeTo() methods, making this call cheap. + printer->Print( + "getSerializedSize();\n"); + + if (descriptor_->extension_range_count() > 0) { + if (descriptor_->options().message_set_wire_format()) { + printer->Print( + "com.google.protobuf.GeneratedMessage$lite$\n" + " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n" + " newMessageSetExtensionWriter();\n", + "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite", + "classname", ClassName(descriptor_)); + } else { + printer->Print( + "com.google.protobuf.GeneratedMessage$lite$\n" + " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n" + " newExtensionWriter();\n", + "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite", + "classname", ClassName(descriptor_)); + } + } + + // Merge the fields and the extension ranges, both sorted by field number. + for (int i = 0, j = 0; + i < descriptor_->field_count() || j < sorted_extensions.size(); + ) { + if (i == descriptor_->field_count()) { + GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); + } else if (j == sorted_extensions.size()) { + GenerateSerializeOneField(printer, sorted_fields[i++]); + } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) { + GenerateSerializeOneField(printer, sorted_fields[i++]); + } else { + GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); + } + } + + if (HasUnknownFields(descriptor_)) { + if (descriptor_->options().message_set_wire_format()) { + printer->Print( + "getUnknownFields().writeAsMessageSetTo(output);\n"); + } else { + printer->Print( + "getUnknownFields().writeTo(output);\n"); + } + } + + printer->Outdent(); + printer->Print( + "}\n" + "\n" + "private int memoizedSerializedSize = -1;\n" + "public int getSerializedSize() {\n" + " int size = memoizedSerializedSize;\n" + " if (size != -1) return size;\n" + "\n" + " size = 0;\n"); + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); + } + + if (descriptor_->extension_range_count() > 0) { + if (descriptor_->options().message_set_wire_format()) { + printer->Print( + "size += extensionsSerializedSizeAsMessageSet();\n"); + } else { + printer->Print( + "size += extensionsSerializedSize();\n"); + } + } + + if (HasUnknownFields(descriptor_)) { + if (descriptor_->options().message_set_wire_format()) { + printer->Print( + "size += getUnknownFields().getSerializedSizeAsMessageSet();\n"); + } else { + printer->Print( + "size += getUnknownFields().getSerializedSize();\n"); + } + } + + printer->Outdent(); + printer->Print( + " memoizedSerializedSize = size;\n" + " return size;\n" + "}\n" + "\n"); + + printer->Print( + "private static final long serialVersionUID = 0L;\n" + "@java.lang.Override\n" + "protected java.lang.Object writeReplace()\n" + " throws java.io.ObjectStreamException {\n" + " return super.writeReplace();\n" + "}\n" + "\n"); +} + +void MessageGenerator:: +GenerateParseFromMethods(io::Printer* printer) { + // Note: These are separate from GenerateMessageSerializationMethods() + // because they need to be generated even for messages that are optimized + // for code size. + printer->Print( + "public static $classname$ parseFrom(\n" + " com.google.protobuf.ByteString data)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.ByteString data,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data, extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(byte[] data)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " byte[] data,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data, extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(java.io.InputStream input)\n" + " throws java.io.IOException {\n" + " return PARSER.parseFrom(input);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " java.io.InputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n" + " return PARSER.parseFrom(input, extensionRegistry);\n" + "}\n" + "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n" + " throws java.io.IOException {\n" + " return PARSER.parseDelimitedFrom(input);\n" + "}\n" + "public static $classname$ parseDelimitedFrom(\n" + " java.io.InputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n" + " return PARSER.parseDelimitedFrom(input, extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.CodedInputStream input)\n" + " throws java.io.IOException {\n" + " return PARSER.parseFrom(input);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n" + " return PARSER.parseFrom(input, extensionRegistry);\n" + "}\n" + "\n", + "classname", ClassName(descriptor_)); +} + +void MessageGenerator::GenerateSerializeOneField( + io::Printer* printer, const FieldDescriptor* field) { + field_generators_.get(field).GenerateSerializationCode(printer); +} + +void MessageGenerator::GenerateSerializeOneExtensionRange( + io::Printer* printer, const Descriptor::ExtensionRange* range) { + printer->Print( + "extensionWriter.writeUntil($end$, output);\n", + "end", SimpleItoa(range->end)); +} + +// =================================================================== + +void MessageGenerator::GenerateBuilder(io::Printer* printer) { + printer->Print( + "public static Builder newBuilder() { return Builder.create(); }\n" + "public Builder newBuilderForType() { return newBuilder(); }\n" + "public static Builder newBuilder($classname$ prototype) {\n" + " return newBuilder().mergeFrom(prototype);\n" + "}\n" + "public Builder toBuilder() { return newBuilder(this); }\n" + "\n", + "classname", ClassName(descriptor_)); + + if (HasNestedBuilders(descriptor_)) { + printer->Print( + "@java.lang.Override\n" + "protected Builder newBuilderForType(\n" + " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n" + " Builder builder = new Builder(parent);\n" + " return builder;\n" + "}\n"); + } + + WriteMessageDocComment(printer, descriptor_); + + if (descriptor_->extension_range_count() > 0) { + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public static final class Builder extends\n" + " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n" + " $classname$, Builder> implements $classname$OrBuilder {\n", + "classname", ClassName(descriptor_)); + } else { + printer->Print( + "public static final class Builder extends\n" + " com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n" + " $classname$, Builder> implements $classname$OrBuilder {\n", + "classname", ClassName(descriptor_)); + } + } else { + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public static final class Builder extends\n" + " com.google.protobuf.GeneratedMessage.Builder\n" + " implements $classname$OrBuilder {\n", + "classname", ClassName(descriptor_)); + } else { + printer->Print( + "public static final class Builder extends\n" + " com.google.protobuf.GeneratedMessageLite.Builder<\n" + " $classname$, Builder>\n" + " implements $classname$OrBuilder {\n", + "classname", ClassName(descriptor_)); + } + } + printer->Indent(); + + GenerateDescriptorMethods(printer); + GenerateCommonBuilderMethods(printer); + + if (HasGeneratedMethods(descriptor_)) { + GenerateIsInitialized(printer, DONT_MEMOIZE); + GenerateBuilderParsingMethods(printer); + } + + // Integers for bit fields. + int totalBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + totalBits += field_generators_.get(descriptor_->field(i)) + .GetNumBitsForBuilder(); + } + int totalInts = (totalBits + 31) / 32; + for (int i = 0; i < totalInts; i++) { + printer->Print("private int $bit_field_name$;\n", + "bit_field_name", GetBitFieldName(i)); + } + + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("\n"); + PrintFieldComment(printer, descriptor_->field(i)); + field_generators_.get(descriptor_->field(i)) + .GenerateBuilderMembers(printer); + } + + printer->Print( + "\n" + "// @@protoc_insertion_point(builder_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + + printer->Outdent(); + printer->Print("}\n"); +} + +void MessageGenerator::GenerateDescriptorMethods(io::Printer* printer) { + if (HasDescriptorMethods(descriptor_)) { + if (!descriptor_->options().no_standard_descriptor_accessor()) { + printer->Print( + "public static final com.google.protobuf.Descriptors.Descriptor\n" + " getDescriptor() {\n" + " return $fileclass$.internal_$identifier$_descriptor;\n" + "}\n" + "\n", + "fileclass", ClassName(descriptor_->file()), + "identifier", UniqueFileScopeIdentifier(descriptor_)); + } + printer->Print( + "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n" + " internalGetFieldAccessorTable() {\n" + " return $fileclass$.internal_$identifier$_fieldAccessorTable\n" + " .ensureFieldAccessorsInitialized(\n" + " $classname$.class, $classname$.Builder.class);\n" + "}\n" + "\n", + "classname", ClassName(descriptor_), + "fileclass", ClassName(descriptor_->file()), + "identifier", UniqueFileScopeIdentifier(descriptor_)); + } +} + +// =================================================================== + +void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { + printer->Print( + "// Construct using $classname$.newBuilder()\n" + "private Builder() {\n" + " maybeForceBuilderInitialization();\n" + "}\n" + "\n", + "classname", ClassName(descriptor_)); + + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "private Builder(\n" + " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n" + " super(parent);\n" + " maybeForceBuilderInitialization();\n" + "}\n", + "classname", ClassName(descriptor_)); + } + + + if (HasNestedBuilders(descriptor_)) { + printer->Print( + "private void maybeForceBuilderInitialization() {\n" + " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n"); + + printer->Indent(); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateFieldBuilderInitializationCode(printer); + } + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + "}\n"); + } else { + printer->Print( + "private void maybeForceBuilderInitialization() {\n" + "}\n"); + } + + printer->Print( + "private static Builder create() {\n" + " return new Builder();\n" + "}\n" + "\n" + "public Builder clear() {\n" + " super.clear();\n", + "classname", ClassName(descriptor_)); + + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateBuilderClearCode(printer); + } + + printer->Outdent(); + + printer->Print( + " return this;\n" + "}\n" + "\n" + "public Builder clone() {\n" + " return create().mergeFrom(buildPartial());\n" + "}\n" + "\n", + "classname", ClassName(descriptor_)); + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public com.google.protobuf.Descriptors.Descriptor\n" + " getDescriptorForType() {\n" + " return $fileclass$.internal_$identifier$_descriptor;\n" + "}\n" + "\n", + "fileclass", ClassName(descriptor_->file()), + "identifier", UniqueFileScopeIdentifier(descriptor_)); + } + printer->Print( + "public $classname$ getDefaultInstanceForType() {\n" + " return $classname$.getDefaultInstance();\n" + "}\n" + "\n", + "classname", ClassName(descriptor_)); + + // ----------------------------------------------------------------- + + printer->Print( + "public $classname$ build() {\n" + " $classname$ result = buildPartial();\n" + " if (!result.isInitialized()) {\n" + " throw newUninitializedMessageException(result);\n" + " }\n" + " return result;\n" + "}\n" + "\n" + "public $classname$ buildPartial() {\n" + " $classname$ result = new $classname$(this);\n", + "classname", ClassName(descriptor_)); + + printer->Indent(); + + // Local vars for from and to bit fields to avoid accessing the builder and + // message over and over for these fields. Seems to provide a slight + // perforamance improvement in micro benchmark and this is also what proto1 + // code does. + int totalBuilderBits = 0; + int totalMessageBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldGenerator& field = field_generators_.get(descriptor_->field(i)); + totalBuilderBits += field.GetNumBitsForBuilder(); + totalMessageBits += field.GetNumBitsForMessage(); + } + int totalBuilderInts = (totalBuilderBits + 31) / 32; + int totalMessageInts = (totalMessageBits + 31) / 32; + for (int i = 0; i < totalBuilderInts; i++) { + printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n", + "bit_field_name", GetBitFieldName(i)); + } + for (int i = 0; i < totalMessageInts; i++) { + printer->Print("int to_$bit_field_name$ = 0;\n", + "bit_field_name", GetBitFieldName(i)); + } + + // Output generation code for each field. + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer); + } + + // Copy the bit field results to the generated message + for (int i = 0; i < totalMessageInts; i++) { + printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n", + "bit_field_name", GetBitFieldName(i)); + } + + printer->Outdent(); + + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + " onBuilt();\n"); + } + + printer->Print( + " return result;\n" + "}\n" + "\n", + "classname", ClassName(descriptor_)); + + // ----------------------------------------------------------------- + + if (HasGeneratedMethods(descriptor_)) { + // MergeFrom(Message other) requires the ability to distinguish the other + // messages type by its descriptor. + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public Builder mergeFrom(com.google.protobuf.Message other) {\n" + " if (other instanceof $classname$) {\n" + " return mergeFrom(($classname$)other);\n" + " } else {\n" + " super.mergeFrom(other);\n" + " return this;\n" + " }\n" + "}\n" + "\n", + "classname", ClassName(descriptor_)); + } + + printer->Print( + "public Builder mergeFrom($classname$ other) {\n" + // Optimization: If other is the default instance, we know none of its + // fields are set so we can skip the merge. + " if (other == $classname$.getDefaultInstance()) return this;\n", + "classname", ClassName(descriptor_)); + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)).GenerateMergingCode(printer); + } + + printer->Outdent(); + + // if message type has extensions + if (descriptor_->extension_range_count() > 0) { + printer->Print( + " this.mergeExtensionFields(other);\n"); + } + + if (HasUnknownFields(descriptor_)) { + printer->Print( + " this.mergeUnknownFields(other.getUnknownFields());\n"); + } + + printer->Print( + " return this;\n" + "}\n" + "\n"); + } +} + +// =================================================================== + +void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { + printer->Print( + "public Builder mergeFrom(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n" + " $classname$ parsedMessage = null;\n" + " try {\n" + " parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n" + " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" + " parsedMessage = ($classname$) e.getUnfinishedMessage();\n" + " throw e;\n" + " } finally {\n" + " if (parsedMessage != null) {\n" + " mergeFrom(parsedMessage);\n" + " }\n" + " }\n" + " return this;\n" + "}\n", + "classname", ClassName(descriptor_)); +} + +// =================================================================== + +void MessageGenerator::GenerateIsInitialized( + io::Printer* printer, UseMemoization useMemoization) { + bool memoization = useMemoization == MEMOIZE; + if (memoization) { + // Memoizes whether the protocol buffer is fully initialized (has all + // required fields). -1 means not yet computed. 0 means false and 1 means + // true. + printer->Print( + "private byte memoizedIsInitialized = -1;\n"); + } + printer->Print( + "public final boolean isInitialized() {\n"); + printer->Indent(); + + if (memoization) { + printer->Print( + "byte isInitialized = memoizedIsInitialized;\n" + "if (isInitialized != -1) return isInitialized == 1;\n" + "\n"); + } + + // Check that all required fields in this message are set. + // TODO(kenton): We can optimize this when we switch to putting all the + // "has" fields into a single bitfield. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + if (field->is_required()) { + printer->Print( + "if (!has$name$()) {\n" + " $memoize$\n" + " return false;\n" + "}\n", + "name", UnderscoresToCapitalizedCamelCase(field), + "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); + } + } + + // Now check that all embedded messages are initialized. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (GetJavaType(field) == JAVATYPE_MESSAGE && + HasRequiredFields(field->message_type())) { + switch (field->label()) { + case FieldDescriptor::LABEL_REQUIRED: + printer->Print( + "if (!get$name$().isInitialized()) {\n" + " $memoize$\n" + " return false;\n" + "}\n", + "type", ClassName(field->message_type()), + "name", UnderscoresToCapitalizedCamelCase(field), + "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); + break; + case FieldDescriptor::LABEL_OPTIONAL: + printer->Print( + "if (has$name$()) {\n" + " if (!get$name$().isInitialized()) {\n" + " $memoize$\n" + " return false;\n" + " }\n" + "}\n", + "type", ClassName(field->message_type()), + "name", UnderscoresToCapitalizedCamelCase(field), + "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); + break; + case FieldDescriptor::LABEL_REPEATED: + printer->Print( + "for (int i = 0; i < get$name$Count(); i++) {\n" + " if (!get$name$(i).isInitialized()) {\n" + " $memoize$\n" + " return false;\n" + " }\n" + "}\n", + "type", ClassName(field->message_type()), + "name", UnderscoresToCapitalizedCamelCase(field), + "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); + break; + } + } + } + + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "if (!extensionsAreInitialized()) {\n" + " $memoize$\n" + " return false;\n" + "}\n", + "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); + } + + printer->Outdent(); + + if (memoization) { + printer->Print( + " memoizedIsInitialized = 1;\n"); + } + + printer->Print( + " return true;\n" + "}\n" + "\n"); +} + +// =================================================================== + +void MessageGenerator::GenerateEqualsAndHashCode(io::Printer* printer) { + printer->Print( + "@java.lang.Override\n" + "public boolean equals(final java.lang.Object obj) {\n"); + printer->Indent(); + printer->Print( + "if (obj == this) {\n" + " return true;\n" + "}\n" + "if (!(obj instanceof $classname$)) {\n" + " return super.equals(obj);\n" + "}\n" + "$classname$ other = ($classname$) obj;\n" + "\n", + "classname", ClassName(descriptor_)); + + printer->Print("boolean result = true;\n"); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (!field->is_repeated()) { + printer->Print( + "result = result && (has$name$() == other.has$name$());\n" + "if (has$name$()) {\n", + "name", UnderscoresToCapitalizedCamelCase(field)); + printer->Indent(); + } + field_generators_.get(field).GenerateEqualsCode(printer); + if (!field->is_repeated()) { + printer->Outdent(); + printer->Print( + "}\n"); + } + } + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "result = result &&\n" + " getUnknownFields().equals(other.getUnknownFields());\n"); + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "result = result &&\n" + " getExtensionFields().equals(other.getExtensionFields());\n"); + } + } + printer->Print( + "return result;\n"); + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + + printer->Print( + "private int memoizedHashCode = 0;\n"); + printer->Print( + "@java.lang.Override\n" + "public int hashCode() {\n"); + printer->Indent(); + printer->Print( + "if (memoizedHashCode != 0) {\n"); + printer->Indent(); + printer->Print( + "return memoizedHashCode;\n"); + printer->Outdent(); + printer->Print( + "}\n" + "int hash = 41;\n" + "hash = (19 * hash) + getDescriptorForType().hashCode();\n"); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (!field->is_repeated()) { + printer->Print( + "if (has$name$()) {\n", + "name", UnderscoresToCapitalizedCamelCase(field)); + printer->Indent(); + } + field_generators_.get(field).GenerateHashCode(printer); + if (!field->is_repeated()) { + printer->Outdent(); + printer->Print("}\n"); + } + } + if (HasDescriptorMethods(descriptor_)) { + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "hash = hashFields(hash, getExtensionFields());\n"); + } + } + printer->Print( + "hash = (29 * hash) + getUnknownFields().hashCode();\n" + "memoizedHashCode = hash;\n" + "return hash;\n"); + printer->Outdent(); + printer->Print( + "}\n" + "\n"); +} + +// =================================================================== + +void MessageGenerator::GenerateExtensionRegistrationCode(io::Printer* printer) { + for (int i = 0; i < descriptor_->extension_count(); i++) { + ExtensionGenerator(descriptor_->extension(i)) + .GenerateRegistrationCode(printer); + } + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + MessageGenerator(descriptor_->nested_type(i)) + .GenerateExtensionRegistrationCode(printer); + } +} + +// =================================================================== +void MessageGenerator::GenerateParsingConstructor(io::Printer* printer) { + scoped_array sorted_fields( + SortFieldsByNumber(descriptor_)); + + printer->Print( + "private $classname$(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n", + "classname", descriptor_->name()); + printer->Indent(); + + // Initialize all fields to default. + printer->Print( + "initFields();\n"); + + // Use builder bits to track mutable repeated fields. + int totalBuilderBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldGenerator& field = field_generators_.get(descriptor_->field(i)); + totalBuilderBits += field.GetNumBitsForBuilder(); + } + int totalBuilderInts = (totalBuilderBits + 31) / 32; + for (int i = 0; i < totalBuilderInts; i++) { + printer->Print("int mutable_$bit_field_name$ = 0;\n", + "bit_field_name", GetBitFieldName(i)); + } + + if (HasUnknownFields(descriptor_)) { + printer->Print( + "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n" + " com.google.protobuf.UnknownFieldSet.newBuilder();\n"); + } + + printer->Print( + "try {\n"); + printer->Indent(); + + printer->Print( + "boolean done = false;\n" + "while (!done) {\n"); + printer->Indent(); + + printer->Print( + "int tag = input.readTag();\n" + "switch (tag) {\n"); + printer->Indent(); + + printer->Print( + "case 0:\n" // zero signals EOF / limit reached + " done = true;\n" + " break;\n" + "default: {\n" + " if (!parseUnknownField(input,$unknown_fields$\n" + " extensionRegistry, tag)) {\n" + " done = true;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n", + "unknown_fields", HasUnknownFields(descriptor_) + ? " unknownFields," : ""); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = sorted_fields[i]; + uint32 tag = WireFormatLite::MakeTag(field->number(), + WireFormat::WireTypeForFieldType(field->type())); + + printer->Print( + "case $tag$: {\n", + "tag", SimpleItoa(tag)); + printer->Indent(); + + field_generators_.get(field).GenerateParsingCode(printer); + + printer->Outdent(); + printer->Print( + " break;\n" + "}\n"); + + if (field->is_packable()) { + // To make packed = true wire compatible, we generate parsing code from a + // packed version of this field regardless of field->options().packed(). + uint32 packed_tag = WireFormatLite::MakeTag(field->number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + printer->Print( + "case $tag$: {\n", + "tag", SimpleItoa(packed_tag)); + printer->Indent(); + + field_generators_.get(field).GenerateParsingCodeFromPacked(printer); + + printer->Outdent(); + printer->Print( + " break;\n" + "}\n"); + } + } + + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" // switch (tag) + "}\n"); // while (!done) + + printer->Outdent(); + printer->Print( + "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" + " throw e.setUnfinishedMessage(this);\n" + "} catch (java.io.IOException e) {\n" + " throw new com.google.protobuf.InvalidProtocolBufferException(\n" + " e.getMessage()).setUnfinishedMessage(this);\n" + "} finally {\n"); + printer->Indent(); + + // Make repeated field list immutable. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = sorted_fields[i]; + field_generators_.get(field).GenerateParsingDoneCode(printer); + } + + // Make unknown fields immutable. + if (HasUnknownFields(descriptor_)) { + printer->Print( + "this.unknownFields = unknownFields.build();\n"); + } + + // Make extensions immutable. + printer->Print( + "makeExtensionsImmutable();\n"); + + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" // finally + "}\n"); +} + +// =================================================================== +void MessageGenerator::GenerateParser(io::Printer* printer) { + printer->Print( + "public static com.google.protobuf.Parser<$classname$> PARSER =\n" + " new com.google.protobuf.AbstractParser<$classname$>() {\n", + "classname", descriptor_->name()); + printer->Indent(); + printer->Print( + "public $classname$ parsePartialFrom(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n", + "classname", descriptor_->name()); + if (HasGeneratedMethods(descriptor_)) { + printer->Print( + " return new $classname$(input, extensionRegistry);\n", + "classname", descriptor_->name()); + } else { + // When parsing constructor isn't generated, use builder to parse messages. + // Note, will fallback to use reflection based mergeFieldFrom() in + // AbstractMessage.Builder. + printer->Indent(); + printer->Print( + "Builder builder = newBuilder();\n" + "try {\n" + " builder.mergeFrom(input, extensionRegistry);\n" + "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" + " throw e.setUnfinishedMessage(builder.buildPartial());\n" + "} catch (java.io.IOException e) {\n" + " throw new com.google.protobuf.InvalidProtocolBufferException(\n" + " e.getMessage()).setUnfinishedMessage(builder.buildPartial());\n" + "}\n" + "return builder.buildPartial();\n"); + printer->Outdent(); + } + printer->Print( + "}\n"); + printer->Outdent(); + printer->Print( + "};\n" + "\n"); + + printer->Print( + "@java.lang.Override\n" + "public com.google.protobuf.Parser<$classname$> getParserForType() {\n" + " return PARSER;\n" + "}\n" + "\n", + "classname", descriptor_->name()); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message.h new file mode 100644 index 0000000..a30f020 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message.h @@ -0,0 +1,112 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +class MessageGenerator { + public: + explicit MessageGenerator(const Descriptor* descriptor); + ~MessageGenerator(); + + // All static variables have to be declared at the top-level of the file + // so that we can control initialization order, which is important for + // DescriptorProto bootstrapping to work. + void GenerateStaticVariables(io::Printer* printer); + + // Output code which initializes the static variables generated by + // GenerateStaticVariables(). + void GenerateStaticVariableInitializers(io::Printer* printer); + + // Generate the class itself. + void Generate(io::Printer* printer); + + // Generates the base interface that both the class and its builder implement + void GenerateInterface(io::Printer* printer); + + // Generate code to register all contained extensions with an + // ExtensionRegistry. + void GenerateExtensionRegistrationCode(io::Printer* printer); + + private: + enum UseMemoization { + MEMOIZE, + DONT_MEMOIZE + }; + + void GenerateMessageSerializationMethods(io::Printer* printer); + void GenerateParseFromMethods(io::Printer* printer); + void GenerateSerializeOneField(io::Printer* printer, + const FieldDescriptor* field); + void GenerateSerializeOneExtensionRange( + io::Printer* printer, const Descriptor::ExtensionRange* range); + + void GenerateBuilder(io::Printer* printer); + void GenerateCommonBuilderMethods(io::Printer* printer); + void GenerateDescriptorMethods(io::Printer* printer); + void GenerateBuilderParsingMethods(io::Printer* printer); + void GenerateIsInitialized(io::Printer* printer, + UseMemoization useMemoization); + void GenerateEqualsAndHashCode(io::Printer* printer); + + void GenerateParser(io::Printer* printer); + void GenerateParsingConstructor(io::Printer* printer); + + const Descriptor* descriptor_; + FieldGeneratorMap field_generators_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message_field.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message_field.cc new file mode 100644 index 0000000..b0b284f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message_field.cc @@ -0,0 +1,974 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { + +// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of +// repeat code between this and the other field types. +void SetMessageVariables(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + map* variables) { + (*variables)["name"] = + UnderscoresToCamelCase(descriptor); + (*variables)["capitalized_name"] = + UnderscoresToCapitalizedCamelCase(descriptor); + (*variables)["constant_name"] = FieldConstantName(descriptor); + (*variables)["number"] = SimpleItoa(descriptor->number()); + (*variables)["type"] = ClassName(descriptor->message_type()); + (*variables)["group_or_message"] = + (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? + "Group" : "Message"; + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = descriptor->options().deprecated() + ? "@java.lang.Deprecated " : ""; + (*variables)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + (*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex); + + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex); + + // For repated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + // For repeated fields, one bit is used for whether the array is immutable + // in the parsing constructor. + (*variables)["get_mutable_bit_parser"] = + GenerateGetBitMutableLocal(builderBitIndex); + (*variables)["set_mutable_bit_parser"] = + GenerateSetBitMutableLocal(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +} // namespace + +// =================================================================== + +MessageFieldGenerator:: +MessageFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); +} + +MessageFieldGenerator::~MessageFieldGenerator() {} + +int MessageFieldGenerator::GetNumBitsForMessage() const { + return 1; +} + +int MessageFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void MessageFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + // TODO(jonp): In the future, consider having a method specific to the + // interface so that builders can choose dynamically to either return a + // message or a nested builder, so that asking for the interface doesn't + // cause a message to ever be built. + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$();\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n"); + } +} + +void MessageFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private $type$ $name$_;\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_;\n" + "}\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + " return $name$_;\n" + "}\n"); + } +} + +void MessageFieldGenerator::PrintNestedBuilderCondition( + io::Printer* printer, + const char* regular_case, + const char* nested_builder_case) const { + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, "if ($name$Builder_ == null) {\n"); + printer->Indent(); + printer->Print(variables_, regular_case); + printer->Outdent(); + printer->Print("} else {\n"); + printer->Indent(); + printer->Print(variables_, nested_builder_case); + printer->Outdent(); + printer->Print("}\n"); + } else { + printer->Print(variables_, regular_case); + } +} + +void MessageFieldGenerator::PrintNestedBuilderFunction( + io::Printer* printer, + const char* method_prototype, + const char* regular_case, + const char* nested_builder_case, + const char* trailing_code) const { + printer->Print(variables_, method_prototype); + printer->Print(" {\n"); + printer->Indent(); + PrintNestedBuilderCondition(printer, regular_case, nested_builder_case); + if (trailing_code != NULL) { + printer->Print(variables_, trailing_code); + } + printer->Outdent(); + printer->Print("}\n"); +} + +void MessageFieldGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + // When using nested-builders, the code initially works just like the + // non-nested builder case. It only creates a nested builder lazily on + // demand and then forever delegates to it after creation. + + printer->Print(variables_, + // Used when the builder is null. + "private $type$ $name$_ = $type$.getDefaultInstance();\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, + // If this builder is non-null, it is used and the other fields are + // ignored. + "private com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" + "\n"); + } + + // The comments above the methods below are based on a hypothetical + // field of type "Field" called "Field". + + // boolean hasField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + + // Field getField() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public $type$ get$capitalized_name$()", + + "return $name$_;\n", + + "return $name$Builder_.getMessage();\n", + + NULL); + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder set$capitalized_name$($type$ value)", + + "if (value == null) {\n" + " throw new NullPointerException();\n" + "}\n" + "$name$_ = value;\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(value);\n", + + "$set_has_field_bit_builder$;\n" + "return this;\n"); + + // Field.Builder setField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder set$capitalized_name$(\n" + " $type$.Builder builderForValue)", + + "$name$_ = builderForValue.build();\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(builderForValue.build());\n", + + "$set_has_field_bit_builder$;\n" + "return this;\n"); + + // Field.Builder mergeField(Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder merge$capitalized_name$($type$ value)", + + "if ($get_has_field_bit_builder$ &&\n" + " $name$_ != $type$.getDefaultInstance()) {\n" + " $name$_ =\n" + " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n" + "} else {\n" + " $name$_ = value;\n" + "}\n" + "$on_changed$\n", + + "$name$Builder_.mergeFrom(value);\n", + + "$set_has_field_bit_builder$;\n" + "return this;\n"); + + // Field.Builder clearField() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder clear$capitalized_name$()", + + "$name$_ = $type$.getDefaultInstance();\n" + "$on_changed$\n", + + "$name$Builder_.clear();\n", + + "$clear_has_field_bit_builder$;\n" + "return this;\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n" + " $set_has_field_bit_builder$;\n" + " $on_changed$\n" + " return get$capitalized_name$FieldBuilder().getBuilder();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + " if ($name$Builder_ != null) {\n" + " return $name$Builder_.getMessageOrBuilder();\n" + " } else {\n" + " return $name$_;\n" + " }\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " get$capitalized_name$FieldBuilder() {\n" + " if ($name$Builder_ == null) {\n" + " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder>(\n" + " $name$_,\n" + " getParentForChildren(),\n" + " isClean());\n" + " $name$_ = null;\n" + " }\n" + " return $name$Builder_;\n" + "}\n"); + } +} + +void MessageFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + printer->Print(variables_, + "get$capitalized_name$FieldBuilder();\n"); +} + + +void MessageFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n"); +} + +void MessageFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + PrintNestedBuilderCondition(printer, + "$name$_ = $type$.getDefaultInstance();\n", + + "$name$Builder_.clear();\n"); + printer->Print(variables_, "$clear_has_field_bit_builder$;\n"); +} + +void MessageFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " merge$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); +} + +void MessageFieldGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n"); + + PrintNestedBuilderCondition(printer, + "result.$name$_ = $name$_;\n", + + "result.$name$_ = $name$Builder_.build();\n"); +} + +void MessageFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "$type$.Builder subBuilder = null;\n" + "if ($get_has_field_bit_message$) {\n" + " subBuilder = $name$_.toBuilder();\n" + "}\n"); + + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { + printer->Print(variables_, + "$name$_ = input.readGroup($number$, $type$.PARSER,\n" + " extensionRegistry);\n"); + } else { + printer->Print(variables_, + "$name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n"); + } + + printer->Print(variables_, + "if (subBuilder != null) {\n" + " subBuilder.mergeFrom($name$_);\n" + " $name$_ = subBuilder.buildPartial();\n" + "}\n"); + printer->Print(variables_, + "$set_has_field_bit_message$;\n"); +} + +void MessageFieldGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + // noop for messages. +} + +void MessageFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " output.write$group_or_message$($number$, $name$_);\n" + "}\n"); +} + +void MessageFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .compute$group_or_message$Size($number$, $name$_);\n" + "}\n"); +} + +void MessageFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$());\n"); +} + +void MessageFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n" + "hash = (53 * hash) + get$capitalized_name$().hashCode();\n"); +} + +string MessageFieldGenerator::GetBoxedType() const { + return ClassName(descriptor_->message_type()); +} + +// =================================================================== + +RepeatedMessageFieldGenerator:: +RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); +} + +RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} + +int RepeatedMessageFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedMessageFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedMessageFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + // TODO(jonp): In the future, consider having methods specific to the + // interface so that builders can choose dynamically to either return a + // message or a nested builder, so that asking for the interface doesn't + // cause a message to ever be built. + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.List<$type$> \n" + " get$capitalized_name$List();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$(int index);\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + if (HasNestedBuilders(descriptor_->containing_type())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.List \n" + " get$capitalized_name$OrBuilderList();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n" + " int index);\n"); + } +} + +void RepeatedMessageFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private java.util.List<$type$> $name$_;\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List \n" + " get$capitalized_name$OrBuilderList() {\n" + " return $name$_;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" + " int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + +} + +void RepeatedMessageFieldGenerator::PrintNestedBuilderCondition( + io::Printer* printer, + const char* regular_case, + const char* nested_builder_case) const { + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, "if ($name$Builder_ == null) {\n"); + printer->Indent(); + printer->Print(variables_, regular_case); + printer->Outdent(); + printer->Print("} else {\n"); + printer->Indent(); + printer->Print(variables_, nested_builder_case); + printer->Outdent(); + printer->Print("}\n"); + } else { + printer->Print(variables_, regular_case); + } +} + +void RepeatedMessageFieldGenerator::PrintNestedBuilderFunction( + io::Printer* printer, + const char* method_prototype, + const char* regular_case, + const char* nested_builder_case, + const char* trailing_code) const { + printer->Print(variables_, method_prototype); + printer->Print(" {\n"); + printer->Indent(); + PrintNestedBuilderCondition(printer, regular_case, nested_builder_case); + if (trailing_code != NULL) { + printer->Print(variables_, trailing_code); + } + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + // When using nested-builders, the code initially works just like the + // non-nested builder case. It only creates a nested builder lazily on + // demand and then forever delegates to it after creation. + + printer->Print(variables_, + // Used when the builder is null. + // One field is the list and the other field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a refererence to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + "private java.util.List<$type$> $name$_ =\n" + " java.util.Collections.emptyList();\n" + + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = new java.util.ArrayList<$type$>($name$_);\n" + " $set_mutable_bit_builder$;\n" + " }\n" + "}\n" + "\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, + // If this builder is non-null, it is used and the other fields are + // ignored. + "private com.google.protobuf.RepeatedFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n" + "\n"); + } + + // The comments above the methods below are based on a hypothetical + // repeated field of type "Field" called "RepeatedField". + + // List getRepeatedFieldList() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public java.util.List<$type$> get$capitalized_name$List()", + + "return java.util.Collections.unmodifiableList($name$_);\n", + "return $name$Builder_.getMessageList();\n", + + NULL); + + // int getRepeatedFieldCount() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public int get$capitalized_name$Count()", + + "return $name$_.size();\n", + "return $name$Builder_.getCount();\n", + + NULL); + + // Field getRepeatedField(int index) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public $type$ get$capitalized_name$(int index)", + + "return $name$_.get(index);\n", + + "return $name$Builder_.getMessage(index);\n", + + NULL); + + // Builder setRepeatedField(int index, Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder set$capitalized_name$(\n" + " int index, $type$ value)", + "if (value == null) {\n" + " throw new NullPointerException();\n" + "}\n" + "ensure$capitalized_name$IsMutable();\n" + "$name$_.set(index, value);\n" + "$on_changed$\n", + "$name$Builder_.setMessage(index, value);\n", + "return this;\n"); + + // Builder setRepeatedField(int index, Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder set$capitalized_name$(\n" + " int index, $type$.Builder builderForValue)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.set(index, builderForValue.build());\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(index, builderForValue.build());\n", + + "return this;\n"); + + // Builder addRepeatedField(Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder add$capitalized_name$($type$ value)", + + "if (value == null) {\n" + " throw new NullPointerException();\n" + "}\n" + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(value);\n" + + "$on_changed$\n", + + "$name$Builder_.addMessage(value);\n", + + "return this;\n"); + + // Builder addRepeatedField(int index, Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder add$capitalized_name$(\n" + " int index, $type$ value)", + + "if (value == null) {\n" + " throw new NullPointerException();\n" + "}\n" + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(index, value);\n" + "$on_changed$\n", + + "$name$Builder_.addMessage(index, value);\n", + + "return this;\n"); + + // Builder addRepeatedField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder add$capitalized_name$(\n" + " $type$.Builder builderForValue)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(builderForValue.build());\n" + "$on_changed$\n", + + "$name$Builder_.addMessage(builderForValue.build());\n", + + "return this;\n"); + + // Builder addRepeatedField(int index, Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder add$capitalized_name$(\n" + " int index, $type$.Builder builderForValue)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(index, builderForValue.build());\n" + "$on_changed$\n", + + "$name$Builder_.addMessage(index, builderForValue.build());\n", + + "return this;\n"); + + // Builder addAllRepeatedField(Iterable values) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder addAll$capitalized_name$(\n" + " java.lang.Iterable values)", + + "ensure$capitalized_name$IsMutable();\n" + "super.addAll(values, $name$_);\n" + "$on_changed$\n", + + "$name$Builder_.addAllMessages(values);\n", + + "return this;\n"); + + // Builder clearAllRepeatedField() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder clear$capitalized_name$()", + + "$name$_ = java.util.Collections.emptyList();\n" + "$clear_mutable_bit_builder$;\n" + "$on_changed$\n", + + "$name$Builder_.clear();\n", + + "return this;\n"); + + // Builder removeRepeatedField(int index) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder remove$capitalized_name$(int index)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.remove(index);\n" + "$on_changed$\n", + + "$name$Builder_.remove(index);\n", + + "return this;\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n" + " int index) {\n" + " return get$capitalized_name$FieldBuilder().getBuilder(index);\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" + " int index) {\n" + " if ($name$Builder_ == null) {\n" + " return $name$_.get(index);" + " } else {\n" + " return $name$Builder_.getMessageOrBuilder(index);\n" + " }\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List \n" + " get$capitalized_name$OrBuilderList() {\n" + " if ($name$Builder_ != null) {\n" + " return $name$Builder_.getMessageOrBuilderList();\n" + " } else {\n" + " return java.util.Collections.unmodifiableList($name$_);\n" + " }\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n" + " return get$capitalized_name$FieldBuilder().addBuilder(\n" + " $type$.getDefaultInstance());\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n" + " int index) {\n" + " return get$capitalized_name$FieldBuilder().addBuilder(\n" + " index, $type$.getDefaultInstance());\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<$type$.Builder> \n" + " get$capitalized_name$BuilderList() {\n" + " return get$capitalized_name$FieldBuilder().getBuilderList();\n" + "}\n" + "private com.google.protobuf.RepeatedFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " get$capitalized_name$FieldBuilder() {\n" + " if ($name$Builder_ == null) {\n" + " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder>(\n" + " $name$_,\n" + " $get_mutable_bit_builder$,\n" + " getParentForChildren(),\n" + " isClean());\n" + " $name$_ = null;\n" + " }\n" + " return $name$Builder_;\n" + "}\n"); + } +} + +void RepeatedMessageFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + printer->Print(variables_, + "get$capitalized_name$FieldBuilder();\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + PrintNestedBuilderCondition(printer, + "$name$_ = java.util.Collections.emptyList();\n" + "$clear_mutable_bit_builder$;\n", + + "$name$Builder_.clear();\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + // The code below does two optimizations (non-nested builder case): + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. + PrintNestedBuilderCondition(printer, + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n", + + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$Builder_.isEmpty()) {\n" + " $name$Builder_.dispose();\n" + " $name$Builder_ = null;\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " $name$Builder_ = \n" + " com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?\n" + " get$capitalized_name$FieldBuilder() : null;\n" + " } else {\n" + " $name$Builder_.addAllMessages(other.$name$_);\n" + " }\n" + "}\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + // The code below (non-nested builder case) ensures that the result has an + // immutable list. If our list is immutable, we can just reuse it. If not, + // we make it immutable. + PrintNestedBuilderCondition(printer, + "if ($get_mutable_bit_builder$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n", + + "result.$name$_ = $name$Builder_.build();\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (!$get_mutable_bit_parser$) {\n" + " $name$_ = new java.util.ArrayList<$type$>();\n" + " $set_mutable_bit_parser$;\n" + "}\n"); + + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { + printer->Print(variables_, + "$name$_.add(input.readGroup($number$, $type$.PARSER,\n" + " extensionRegistry));\n"); + } else { + printer->Print(variables_, + "$name$_.add(input.readMessage($type$.PARSER, extensionRegistry));\n"); + } +} + +void RepeatedMessageFieldGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_mutable_bit_parser$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + "}\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$group_or_message$($number$, $name$_.get(i));\n" + "}\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .compute$group_or_message$Size($number$, $name$_.get(i));\n" + "}\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List());\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n" + "}\n"); +} + +string RepeatedMessageFieldGenerator::GetBoxedType() const { + return ClassName(descriptor_->message_type()); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message_field.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message_field.h new file mode 100644 index 0000000..5c8078a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_message_field.h @@ -0,0 +1,136 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class MessageFieldGenerator : public FieldGenerator { + public: + explicit MessageFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); + ~MessageFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + const int messageBitIndex_; + const int builderBitIndex_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); + + void PrintNestedBuilderCondition(io::Printer* printer, + const char* regular_case, const char* nested_builder_case) const; + void PrintNestedBuilderFunction(io::Printer* printer, + const char* method_prototype, const char* regular_case, + const char* nested_builder_case, + const char* trailing_code) const; +}; + +class RepeatedMessageFieldGenerator : public FieldGenerator { + public: + explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); + ~RepeatedMessageFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + const int messageBitIndex_; + const int builderBitIndex_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); + + void PrintNestedBuilderCondition(io::Printer* printer, + const char* regular_case, const char* nested_builder_case) const; + void PrintNestedBuilderFunction(io::Printer* printer, + const char* method_prototype, const char* regular_case, + const char* nested_builder_case, + const char* trailing_code) const; +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_plugin_unittest.cc new file mode 100644 index 0000000..ccc94c9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_plugin_unittest.cc @@ -0,0 +1,122 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// TODO(kenton): Share code with the versions of this test in other languages? +// It seemed like parameterizing it would add more complexity than it is +// worth. + +#include +#include +#include +#include + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +namespace { + +class TestGenerator : public CodeGenerator { + public: + TestGenerator() {} + ~TestGenerator() {} + + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const { + string filename = "Test.java"; + TryInsert(filename, "outer_class_scope", context); + TryInsert(filename, "class_scope:foo.Bar", context); + TryInsert(filename, "class_scope:foo.Bar.Baz", context); + TryInsert(filename, "builder_scope:foo.Bar", context); + TryInsert(filename, "builder_scope:foo.Bar.Baz", context); + TryInsert(filename, "enum_scope:foo.Qux", context); + return true; + } + + void TryInsert(const string& filename, const string& insertion_point, + GeneratorContext* context) const { + scoped_ptr output( + context->OpenForInsert(filename, insertion_point)); + io::Printer printer(output.get(), '$'); + printer.Print("// inserted $name$\n", "name", insertion_point); + } +}; + +// This test verifies that all the expected insertion points exist. It does +// not verify that they are correctly-placed; that would require actually +// compiling the output which is a bit more than I care to do for this test. +TEST(JavaPluginTest, PluginTest) { + File::WriteStringToFileOrDie( + "syntax = \"proto2\";\n" + "package foo;\n" + "option java_package = \"\";\n" + "option java_outer_classname = \"Test\";\n" + "message Bar {\n" + " message Baz {}\n" + "}\n" + "enum Qux { BLAH = 1; }\n", + TestTempDir() + "/test.proto"); + + google::protobuf::compiler::CommandLineInterface cli; + cli.SetInputsAreProtoPathRelative(true); + + JavaGenerator java_generator; + TestGenerator test_generator; + cli.RegisterGenerator("--java_out", &java_generator, ""); + cli.RegisterGenerator("--test_out", &test_generator, ""); + + string proto_path = "-I" + TestTempDir(); + string java_out = "--java_out=" + TestTempDir(); + string test_out = "--test_out=" + TestTempDir(); + + const char* argv[] = { + "protoc", + proto_path.c_str(), + java_out.c_str(), + test_out.c_str(), + "test.proto" + }; + + EXPECT_EQ(0, cli.Run(5, argv)); +} + +} // namespace +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_primitive_field.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_primitive_field.cc new file mode 100644 index 0000000..0140e23 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -0,0 +1,787 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { + +const char* PrimitiveTypeName(JavaType type) { + switch (type) { + case JAVATYPE_INT : return "int"; + case JAVATYPE_LONG : return "long"; + case JAVATYPE_FLOAT : return "float"; + case JAVATYPE_DOUBLE : return "double"; + case JAVATYPE_BOOLEAN: return "boolean"; + case JAVATYPE_STRING : return "java.lang.String"; + case JAVATYPE_BYTES : return "com.google.protobuf.ByteString"; + case JAVATYPE_ENUM : return NULL; + case JAVATYPE_MESSAGE: return NULL; + + // No default because we want the compiler to complain if any new + // JavaTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +bool IsReferenceType(JavaType type) { + switch (type) { + case JAVATYPE_INT : return false; + case JAVATYPE_LONG : return false; + case JAVATYPE_FLOAT : return false; + case JAVATYPE_DOUBLE : return false; + case JAVATYPE_BOOLEAN: return false; + case JAVATYPE_STRING : return true; + case JAVATYPE_BYTES : return true; + case JAVATYPE_ENUM : return true; + case JAVATYPE_MESSAGE: return true; + + // No default because we want the compiler to complain if any new + // JavaTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return false; +} + +const char* GetCapitalizedType(const FieldDescriptor* field) { + switch (GetType(field)) { + case FieldDescriptor::TYPE_INT32 : return "Int32" ; + case FieldDescriptor::TYPE_UINT32 : return "UInt32" ; + case FieldDescriptor::TYPE_SINT32 : return "SInt32" ; + case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ; + case FieldDescriptor::TYPE_SFIXED32: return "SFixed32"; + case FieldDescriptor::TYPE_INT64 : return "Int64" ; + case FieldDescriptor::TYPE_UINT64 : return "UInt64" ; + case FieldDescriptor::TYPE_SINT64 : return "SInt64" ; + case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ; + case FieldDescriptor::TYPE_SFIXED64: return "SFixed64"; + case FieldDescriptor::TYPE_FLOAT : return "Float" ; + case FieldDescriptor::TYPE_DOUBLE : return "Double" ; + case FieldDescriptor::TYPE_BOOL : return "Bool" ; + case FieldDescriptor::TYPE_STRING : return "String" ; + case FieldDescriptor::TYPE_BYTES : return "Bytes" ; + case FieldDescriptor::TYPE_ENUM : return "Enum" ; + case FieldDescriptor::TYPE_GROUP : return "Group" ; + case FieldDescriptor::TYPE_MESSAGE : return "Message" ; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +// For encodings with fixed sizes, returns that size in bytes. Otherwise +// returns -1. +int FixedSize(FieldDescriptor::Type type) { + switch (type) { + case FieldDescriptor::TYPE_INT32 : return -1; + case FieldDescriptor::TYPE_INT64 : return -1; + case FieldDescriptor::TYPE_UINT32 : return -1; + case FieldDescriptor::TYPE_UINT64 : return -1; + case FieldDescriptor::TYPE_SINT32 : return -1; + case FieldDescriptor::TYPE_SINT64 : return -1; + case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size; + case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size; + case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size; + case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size; + case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize; + case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize; + + case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize; + case FieldDescriptor::TYPE_ENUM : return -1; + + case FieldDescriptor::TYPE_STRING : return -1; + case FieldDescriptor::TYPE_BYTES : return -1; + case FieldDescriptor::TYPE_GROUP : return -1; + case FieldDescriptor::TYPE_MESSAGE : return -1; + + // No default because we want the compiler to complain if any new + // types are added. + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return -1; +} + +void SetPrimitiveVariables(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + map* variables) { + (*variables)["name"] = + UnderscoresToCamelCase(descriptor); + (*variables)["capitalized_name"] = + UnderscoresToCapitalizedCamelCase(descriptor); + (*variables)["constant_name"] = FieldConstantName(descriptor); + (*variables)["number"] = SimpleItoa(descriptor->number()); + (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor)); + (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor)); + (*variables)["field_type"] = (*variables)["type"]; + (*variables)["field_list_type"] = "java.util.List<" + + (*variables)["boxed_type"] + ">"; + (*variables)["empty_list"] = "java.util.Collections.emptyList()"; + (*variables)["default"] = DefaultValue(descriptor); + (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ? + "" : ("= " + DefaultValue(descriptor)); + (*variables)["capitalized_type"] = GetCapitalizedType(descriptor); + (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); + (*variables)["tag_size"] = SimpleItoa( + WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + if (IsReferenceType(GetJavaType(descriptor))) { + (*variables)["null_check"] = + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n"; + } else { + (*variables)["null_check"] = ""; + } + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = descriptor->options().deprecated() + ? "@java.lang.Deprecated " : ""; + int fixed_size = FixedSize(GetType(descriptor)); + if (fixed_size != -1) { + (*variables)["fixed_size"] = SimpleItoa(fixed_size); + } + (*variables)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + (*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex); + + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex); + + // For repated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + // For repeated fields, one bit is used for whether the array is immutable + // in the parsing constructor. + (*variables)["get_mutable_bit_parser"] = + GenerateGetBitMutableLocal(builderBitIndex); + (*variables)["set_mutable_bit_parser"] = + GenerateSetBitMutableLocal(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +} // namespace + +// =================================================================== + +PrimitiveFieldGenerator:: +PrimitiveFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); +} + +PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} + +int PrimitiveFieldGenerator::GetNumBitsForMessage() const { + return 1; +} + +int PrimitiveFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void PrimitiveFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$();\n"); +} + +void PrimitiveFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private $field_type$ $name$_;\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_;\n" + "}\n"); +} + +void PrimitiveFieldGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + printer->Print(variables_, + "private $field_type$ $name$_ $default_init$;\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$null_check$" + " $set_has_field_bit_builder$;\n" + " $name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $clear_has_field_bit_builder$;\n"); + JavaType type = GetJavaType(descriptor_); + if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) { + // The default value is not a simple literal so we want to avoid executing + // it multiple times. Instead, get the default out of the default instance. + printer->Print(variables_, + " $name$_ = getDefaultInstance().get$capitalized_name$();\n"); + } else { + printer->Print(variables_, + " $name$_ = $default$;\n"); + } + printer->Print(variables_, + " $on_changed$\n" + " return this;\n" + "}\n"); +} + +void PrimitiveFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void PrimitiveFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void PrimitiveFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $default$;\n" + "$clear_has_field_bit_builder$;\n"); +} + +void PrimitiveFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " set$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); +} + +void PrimitiveFieldGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); +} + +void PrimitiveFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "$set_has_field_bit_message$;\n" + "$name$_ = input.read$capitalized_type$();\n"); +} + +void PrimitiveFieldGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + // noop for primitives. +} + +void PrimitiveFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " output.write$capitalized_type$($number$, $name$_);\n" + "}\n"); +} + +void PrimitiveFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .compute$capitalized_type$Size($number$, $name$_);\n" + "}\n"); +} + +void PrimitiveFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + switch (GetJavaType(descriptor_)) { + case JAVATYPE_INT: + case JAVATYPE_LONG: + case JAVATYPE_BOOLEAN: + printer->Print(variables_, + "result = result && (get$capitalized_name$()\n" + " == other.get$capitalized_name$());\n"); + break; + + case JAVATYPE_FLOAT: + printer->Print(variables_, + "result = result && (Float.floatToIntBits(get$capitalized_name$())" + " == Float.floatToIntBits(other.get$capitalized_name$()));\n"); + break; + + case JAVATYPE_DOUBLE: + printer->Print(variables_, + "result = result && (Double.doubleToLongBits(get$capitalized_name$())" + " == Double.doubleToLongBits(other.get$capitalized_name$()));\n"); + break; + + case JAVATYPE_STRING: + case JAVATYPE_BYTES: + printer->Print(variables_, + "result = result && get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$());\n"); + break; + + case JAVATYPE_ENUM: + case JAVATYPE_MESSAGE: + default: + GOOGLE_LOG(FATAL) << "Can't get here."; + break; + } +} + +void PrimitiveFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n"); + switch (GetJavaType(descriptor_)) { + case JAVATYPE_INT: + printer->Print(variables_, + "hash = (53 * hash) + get$capitalized_name$();\n"); + break; + + case JAVATYPE_LONG: + printer->Print(variables_, + "hash = (53 * hash) + hashLong(get$capitalized_name$());\n"); + break; + + case JAVATYPE_BOOLEAN: + printer->Print(variables_, + "hash = (53 * hash) + hashBoolean(get$capitalized_name$());\n"); + break; + + case JAVATYPE_FLOAT: + printer->Print(variables_, + "hash = (53 * hash) + Float.floatToIntBits(\n" + " get$capitalized_name$());\n"); + break; + + case JAVATYPE_DOUBLE: + printer->Print(variables_, + "hash = (53 * hash) + hashLong(\n" + " Double.doubleToLongBits(get$capitalized_name$()));\n"); + break; + + case JAVATYPE_STRING: + case JAVATYPE_BYTES: + printer->Print(variables_, + "hash = (53 * hash) + get$capitalized_name$().hashCode();\n"); + break; + + case JAVATYPE_ENUM: + case JAVATYPE_MESSAGE: + default: + GOOGLE_LOG(FATAL) << "Can't get here."; + break; + } +} + +string PrimitiveFieldGenerator::GetBoxedType() const { + return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); +} + +// =================================================================== + +RepeatedPrimitiveFieldGenerator:: +RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); +} + +RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} + +int RepeatedPrimitiveFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedPrimitiveFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$(int index);\n"); +} + + +void RepeatedPrimitiveFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private $field_list_type$ $name$_;\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<$boxed_type$>\n" + " get$capitalized_name$List() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + + if (descriptor_->options().packed() && + HasGeneratedMethods(descriptor_->containing_type())) { + printer->Print(variables_, + "private int $name$MemoizedSerializedSize = -1;\n"); + } +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + // One field is the list and the bit field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a refererence to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + printer->Print(variables_, + "private $field_list_type$ $name$_ = $empty_list$;\n"); + + printer->Print(variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = new java.util.ArrayList<$boxed_type$>($name$_);\n" + " $set_mutable_bit_builder$;\n" + " }\n" + "}\n"); + + // Note: We return an unmodifiable list because otherwise the caller + // could hold on to the returned list and modify it after the message + // has been built, thus mutating the message which is supposed to be + // immutable. + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<$boxed_type$>\n" + " get$capitalized_name$List() {\n" + " return java.util.Collections.unmodifiableList($name$_);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder set$capitalized_name$(\n" + " int index, $type$ value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder addAll$capitalized_name$(\n" + " java.lang.Iterable values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " super.addAll(values, $name$_);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $name$_ = $empty_list$;\n" + " $clear_mutable_bit_builder$;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $empty_list$;\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $empty_list$;\n" + "$clear_mutable_bit_builder$;\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + // The code below does two optimizations: + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. + printer->Print(variables_, + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + // The code below ensures that the result has an immutable list. If our + // list is immutable, we can just reuse it. If not, we make it immutable. + printer->Print(variables_, + "if ($get_mutable_bit_builder$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (!$get_mutable_bit_parser$) {\n" + " $name$_ = new java.util.ArrayList<$boxed_type$>();\n" + " $set_mutable_bit_parser$;\n" + "}\n" + "$name$_.add(input.read$capitalized_type$());\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateParsingCodeFromPacked(io::Printer* printer) const { + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int limit = input.pushLimit(length);\n" + "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n" + " $name$_ = new java.util.ArrayList<$boxed_type$>();\n" + " $set_mutable_bit_parser$;\n" + "}\n" + "while (input.getBytesUntilLimit() > 0) {\n" + " $name$_.add(input.read$capitalized_type$());\n" + "}\n" + "input.popLimit(limit);\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_mutable_bit_parser$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + "}\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (get$capitalized_name$List().size() > 0) {\n" + " output.writeRawVarint32($tag$);\n" + " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + "}\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$capitalized_type$NoTag($name$_.get(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$capitalized_type$($number$, $name$_.get(i));\n" + "}\n"); + } +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "{\n" + " int dataSize = 0;\n"); + printer->Indent(); + + if (FixedSize(GetType(descriptor_)) == -1) { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " dataSize += com.google.protobuf.CodedOutputStream\n" + " .compute$capitalized_type$SizeNoTag($name$_.get(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n"); + } + + printer->Print( + "size += dataSize;\n"); + + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (!get$capitalized_name$List().isEmpty()) {\n" + " size += $tag_size$;\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeInt32SizeNoTag(dataSize);\n" + "}\n"); + } else { + printer->Print(variables_, + "size += $tag_size$ * get$capitalized_name$List().size();\n"); + } + + // cache the data size for packed fields. + if (descriptor_->options().packed()) { + printer->Print(variables_, + "$name$MemoizedSerializedSize = dataSize;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List());\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n" + "}\n"); +} + +string RepeatedPrimitiveFieldGenerator::GetBoxedType() const { + return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_primitive_field.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_primitive_field.h new file mode 100644 index 0000000..1b5b6d9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_primitive_field.h @@ -0,0 +1,123 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class PrimitiveFieldGenerator : public FieldGenerator { + public: + explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); + ~PrimitiveFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + const int messageBitIndex_; + const int builderBitIndex_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); +}; + +class RepeatedPrimitiveFieldGenerator : public FieldGenerator { + public: + explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); + ~RepeatedPrimitiveFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingCodeFromPacked(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + const int messageBitIndex_; + const int builderBitIndex_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_service.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_service.cc new file mode 100644 index 0000000..bcd8035 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_service.cc @@ -0,0 +1,453 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor) + : descriptor_(descriptor) {} + +ServiceGenerator::~ServiceGenerator() {} + +void ServiceGenerator::Generate(io::Printer* printer) { + bool is_own_file = descriptor_->file()->options().java_multiple_files(); + WriteServiceDocComment(printer, descriptor_); + printer->Print( + "public $static$ abstract class $classname$\n" + " implements com.google.protobuf.Service {\n", + "static", is_own_file ? "" : "static", + "classname", descriptor_->name()); + printer->Indent(); + + printer->Print( + "protected $classname$() {}\n\n", + "classname", descriptor_->name()); + + GenerateInterface(printer); + + GenerateNewReflectiveServiceMethod(printer); + GenerateNewReflectiveBlockingServiceMethod(printer); + + GenerateAbstractMethods(printer); + + // Generate getDescriptor() and getDescriptorForType(). + printer->Print( + "public static final\n" + " com.google.protobuf.Descriptors.ServiceDescriptor\n" + " getDescriptor() {\n" + " return $file$.getDescriptor().getServices().get($index$);\n" + "}\n", + "file", ClassName(descriptor_->file()), + "index", SimpleItoa(descriptor_->index())); + GenerateGetDescriptorForType(printer); + + // Generate more stuff. + GenerateCallMethod(printer); + GenerateGetPrototype(REQUEST, printer); + GenerateGetPrototype(RESPONSE, printer); + GenerateStub(printer); + GenerateBlockingStub(printer); + + // Add an insertion point. + printer->Print( + "\n" + "// @@protoc_insertion_point(class_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + + printer->Outdent(); + printer->Print("}\n\n"); +} + +void ServiceGenerator::GenerateGetDescriptorForType(io::Printer* printer) { + printer->Print( + "public final com.google.protobuf.Descriptors.ServiceDescriptor\n" + " getDescriptorForType() {\n" + " return getDescriptor();\n" + "}\n"); +} + +void ServiceGenerator::GenerateInterface(io::Printer* printer) { + printer->Print("public interface Interface {\n"); + printer->Indent(); + GenerateAbstractMethods(printer); + printer->Outdent(); + printer->Print("}\n\n"); +} + +void ServiceGenerator::GenerateNewReflectiveServiceMethod( + io::Printer* printer) { + printer->Print( + "public static com.google.protobuf.Service newReflectiveService(\n" + " final Interface impl) {\n" + " return new $classname$() {\n", + "classname", descriptor_->name()); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + printer->Print("@java.lang.Override\n"); + GenerateMethodSignature(printer, method, IS_CONCRETE); + printer->Print( + " {\n" + " impl.$method$(controller, request, done);\n" + "}\n\n", + "method", UnderscoresToCamelCase(method)); + } + + printer->Outdent(); + printer->Print("};\n"); + printer->Outdent(); + printer->Print("}\n\n"); +} + +void ServiceGenerator::GenerateNewReflectiveBlockingServiceMethod( + io::Printer* printer) { + printer->Print( + "public static com.google.protobuf.BlockingService\n" + " newReflectiveBlockingService(final BlockingInterface impl) {\n" + " return new com.google.protobuf.BlockingService() {\n"); + printer->Indent(); + printer->Indent(); + + GenerateGetDescriptorForType(printer); + + GenerateCallBlockingMethod(printer); + GenerateGetPrototype(REQUEST, printer); + GenerateGetPrototype(RESPONSE, printer); + + printer->Outdent(); + printer->Print("};\n"); + printer->Outdent(); + printer->Print("}\n\n"); +} + +void ServiceGenerator::GenerateAbstractMethods(io::Printer* printer) { + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + WriteMethodDocComment(printer, method); + GenerateMethodSignature(printer, method, IS_ABSTRACT); + printer->Print(";\n\n"); + } +} + +void ServiceGenerator::GenerateCallMethod(io::Printer* printer) { + printer->Print( + "\n" + "public final void callMethod(\n" + " com.google.protobuf.Descriptors.MethodDescriptor method,\n" + " com.google.protobuf.RpcController controller,\n" + " com.google.protobuf.Message request,\n" + " com.google.protobuf.RpcCallback<\n" + " com.google.protobuf.Message> done) {\n" + " if (method.getService() != getDescriptor()) {\n" + " throw new java.lang.IllegalArgumentException(\n" + " \"Service.callMethod() given method descriptor for wrong \" +\n" + " \"service type.\");\n" + " }\n" + " switch(method.getIndex()) {\n"); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + map vars; + vars["index"] = SimpleItoa(i); + vars["method"] = UnderscoresToCamelCase(method); + vars["input"] = ClassName(method->input_type()); + vars["output"] = ClassName(method->output_type()); + printer->Print(vars, + "case $index$:\n" + " this.$method$(controller, ($input$)request,\n" + " com.google.protobuf.RpcUtil.<$output$>specializeCallback(\n" + " done));\n" + " return;\n"); + } + + printer->Print( + "default:\n" + " throw new java.lang.AssertionError(\"Can't get here.\");\n"); + + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + "}\n" + "\n"); +} + +void ServiceGenerator::GenerateCallBlockingMethod(io::Printer* printer) { + printer->Print( + "\n" + "public final com.google.protobuf.Message callBlockingMethod(\n" + " com.google.protobuf.Descriptors.MethodDescriptor method,\n" + " com.google.protobuf.RpcController controller,\n" + " com.google.protobuf.Message request)\n" + " throws com.google.protobuf.ServiceException {\n" + " if (method.getService() != getDescriptor()) {\n" + " throw new java.lang.IllegalArgumentException(\n" + " \"Service.callBlockingMethod() given method descriptor for \" +\n" + " \"wrong service type.\");\n" + " }\n" + " switch(method.getIndex()) {\n"); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + map vars; + vars["index"] = SimpleItoa(i); + vars["method"] = UnderscoresToCamelCase(method); + vars["input"] = ClassName(method->input_type()); + vars["output"] = ClassName(method->output_type()); + printer->Print(vars, + "case $index$:\n" + " return impl.$method$(controller, ($input$)request);\n"); + } + + printer->Print( + "default:\n" + " throw new java.lang.AssertionError(\"Can't get here.\");\n"); + + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + "}\n" + "\n"); +} + +void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which, + io::Printer* printer) { + /* + * TODO(cpovirk): The exception message says "Service.foo" when it may be + * "BlockingService.foo." Consider fixing. + */ + printer->Print( + "public final com.google.protobuf.Message\n" + " get$request_or_response$Prototype(\n" + " com.google.protobuf.Descriptors.MethodDescriptor method) {\n" + " if (method.getService() != getDescriptor()) {\n" + " throw new java.lang.IllegalArgumentException(\n" + " \"Service.get$request_or_response$Prototype() given method \" +\n" + " \"descriptor for wrong service type.\");\n" + " }\n" + " switch(method.getIndex()) {\n", + "request_or_response", (which == REQUEST) ? "Request" : "Response"); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + map vars; + vars["index"] = SimpleItoa(i); + vars["type"] = ClassName( + (which == REQUEST) ? method->input_type() : method->output_type()); + printer->Print(vars, + "case $index$:\n" + " return $type$.getDefaultInstance();\n"); + } + + printer->Print( + "default:\n" + " throw new java.lang.AssertionError(\"Can't get here.\");\n"); + + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + "}\n" + "\n"); +} + +void ServiceGenerator::GenerateStub(io::Printer* printer) { + printer->Print( + "public static Stub newStub(\n" + " com.google.protobuf.RpcChannel channel) {\n" + " return new Stub(channel);\n" + "}\n" + "\n" + "public static final class Stub extends $classname$ implements Interface {" + "\n", + "classname", ClassName(descriptor_)); + printer->Indent(); + + printer->Print( + "private Stub(com.google.protobuf.RpcChannel channel) {\n" + " this.channel = channel;\n" + "}\n" + "\n" + "private final com.google.protobuf.RpcChannel channel;\n" + "\n" + "public com.google.protobuf.RpcChannel getChannel() {\n" + " return channel;\n" + "}\n"); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + printer->Print("\n"); + GenerateMethodSignature(printer, method, IS_CONCRETE); + printer->Print(" {\n"); + printer->Indent(); + + map vars; + vars["index"] = SimpleItoa(i); + vars["output"] = ClassName(method->output_type()); + printer->Print(vars, + "channel.callMethod(\n" + " getDescriptor().getMethods().get($index$),\n" + " controller,\n" + " request,\n" + " $output$.getDefaultInstance(),\n" + " com.google.protobuf.RpcUtil.generalizeCallback(\n" + " done,\n" + " $output$.class,\n" + " $output$.getDefaultInstance()));\n"); + + printer->Outdent(); + printer->Print("}\n"); + } + + printer->Outdent(); + printer->Print( + "}\n" + "\n"); +} + +void ServiceGenerator::GenerateBlockingStub(io::Printer* printer) { + printer->Print( + "public static BlockingInterface newBlockingStub(\n" + " com.google.protobuf.BlockingRpcChannel channel) {\n" + " return new BlockingStub(channel);\n" + "}\n" + "\n"); + + printer->Print( + "public interface BlockingInterface {"); + printer->Indent(); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + GenerateBlockingMethodSignature(printer, method); + printer->Print(";\n"); + } + + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + + printer->Print( + "private static final class BlockingStub implements BlockingInterface {\n"); + printer->Indent(); + + printer->Print( + "private BlockingStub(com.google.protobuf.BlockingRpcChannel channel) {\n" + " this.channel = channel;\n" + "}\n" + "\n" + "private final com.google.protobuf.BlockingRpcChannel channel;\n"); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + GenerateBlockingMethodSignature(printer, method); + printer->Print(" {\n"); + printer->Indent(); + + map vars; + vars["index"] = SimpleItoa(i); + vars["output"] = ClassName(method->output_type()); + printer->Print(vars, + "return ($output$) channel.callBlockingMethod(\n" + " getDescriptor().getMethods().get($index$),\n" + " controller,\n" + " request,\n" + " $output$.getDefaultInstance());\n"); + + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void ServiceGenerator::GenerateMethodSignature(io::Printer* printer, + const MethodDescriptor* method, + IsAbstract is_abstract) { + map vars; + vars["name"] = UnderscoresToCamelCase(method); + vars["input"] = ClassName(method->input_type()); + vars["output"] = ClassName(method->output_type()); + vars["abstract"] = (is_abstract == IS_ABSTRACT) ? "abstract" : ""; + printer->Print(vars, + "public $abstract$ void $name$(\n" + " com.google.protobuf.RpcController controller,\n" + " $input$ request,\n" + " com.google.protobuf.RpcCallback<$output$> done)"); +} + +void ServiceGenerator::GenerateBlockingMethodSignature( + io::Printer* printer, + const MethodDescriptor* method) { + map vars; + vars["method"] = UnderscoresToCamelCase(method); + vars["input"] = ClassName(method->input_type()); + vars["output"] = ClassName(method->output_type()); + printer->Print(vars, + "\n" + "public $output$ $method$(\n" + " com.google.protobuf.RpcController controller,\n" + " $input$ request)\n" + " throws com.google.protobuf.ServiceException"); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_service.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_service.h new file mode 100644 index 0000000..e07eebf --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_service.h @@ -0,0 +1,113 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__ + +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +class ServiceGenerator { + public: + explicit ServiceGenerator(const ServiceDescriptor* descriptor); + ~ServiceGenerator(); + + void Generate(io::Printer* printer); + + private: + + // Generate the getDescriptorForType() method. + void GenerateGetDescriptorForType(io::Printer* printer); + + // Generate a Java interface for the service. + void GenerateInterface(io::Printer* printer); + + // Generate newReflectiveService() method. + void GenerateNewReflectiveServiceMethod(io::Printer* printer); + + // Generate newReflectiveBlockingService() method. + void GenerateNewReflectiveBlockingServiceMethod(io::Printer* printer); + + // Generate abstract method declarations for all methods. + void GenerateAbstractMethods(io::Printer* printer); + + // Generate the implementation of Service.callMethod(). + void GenerateCallMethod(io::Printer* printer); + + // Generate the implementation of BlockingService.callBlockingMethod(). + void GenerateCallBlockingMethod(io::Printer* printer); + + // Generate the implementations of Service.get{Request,Response}Prototype(). + enum RequestOrResponse { REQUEST, RESPONSE }; + void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer); + + // Generate a stub implementation of the service. + void GenerateStub(io::Printer* printer); + + // Generate a method signature, possibly abstract, without body or trailing + // semicolon. + enum IsAbstract { IS_ABSTRACT, IS_CONCRETE }; + void GenerateMethodSignature(io::Printer* printer, + const MethodDescriptor* method, + IsAbstract is_abstract); + + // Generate a blocking stub interface and implementation of the service. + void GenerateBlockingStub(io::Printer* printer); + + // Generate the method signature for one method of a blocking stub. + void GenerateBlockingMethodSignature(io::Printer* printer, + const MethodDescriptor* method); + + const ServiceDescriptor* descriptor_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +#endif // NET_PROTO2_COMPILER_JAVA_SERVICE_H__ +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_string_field.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_string_field.cc new file mode 100644 index 0000000..4815663 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_string_field.cc @@ -0,0 +1,726 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Author: jonp@google.com (Jon Perlow) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { + +void SetPrimitiveVariables(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + map* variables) { + (*variables)["name"] = + UnderscoresToCamelCase(descriptor); + (*variables)["capitalized_name"] = + UnderscoresToCapitalizedCamelCase(descriptor); + (*variables)["constant_name"] = FieldConstantName(descriptor); + (*variables)["number"] = SimpleItoa(descriptor->number()); + (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY"; + + (*variables)["default"] = DefaultValue(descriptor); + (*variables)["default_init"] = ("= " + DefaultValue(descriptor)); + (*variables)["capitalized_type"] = "String"; + (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); + (*variables)["tag_size"] = SimpleItoa( + WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + (*variables)["null_check"] = + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n"; + + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = descriptor->options().deprecated() + ? "@java.lang.Deprecated " : ""; + (*variables)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + (*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex); + + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex); + + // For repated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + // For repeated fields, one bit is used for whether the array is immutable + // in the parsing constructor. + (*variables)["get_mutable_bit_parser"] = + GenerateGetBitMutableLocal(builderBitIndex); + (*variables)["set_mutable_bit_parser"] = + GenerateSetBitMutableLocal(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +} // namespace + +// =================================================================== + +StringFieldGenerator:: +StringFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); +} + +StringFieldGenerator::~StringFieldGenerator() {} + +int StringFieldGenerator::GetNumBitsForMessage() const { + return 1; +} + +int StringFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +// A note about how strings are handled. This code used to just store a String +// in the Message. This had two issues: +// +// 1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded +// strings, but rather fields that were raw bytes incorrectly marked +// as strings in the proto file. This is common because in the proto1 +// syntax, string was the way to indicate bytes and C++ engineers can +// easily make this mistake without affecting the C++ API. By converting to +// strings immediately, some java code might corrupt these byte arrays as +// it passes through a java server even if the field was never accessed by +// application code. +// +// 2. There's a performance hit to converting between bytes and strings and +// it many cases, the field is never even read by the application code. This +// avoids unnecessary conversions in the common use cases. +// +// So now, the field for String is maintained as an Object reference which can +// either store a String or a ByteString. The code uses an instanceof check +// to see which one it has and converts to the other one if needed. It remembers +// the last value requested (in a thread safe manner) as this is most likely +// the one needed next. The thread safety is such that if two threads both +// convert the field because the changes made by each thread were not visible to +// the other, they may cause a conversion to happen more times than would +// otherwise be necessary. This was deemed better than adding synchronization +// overhead. It will not cause any corruption issues or affect the behavior of +// the API. The instanceof check is also highly optimized in the JVM and we +// decided it was better to reduce the memory overhead by not having two +// separate fields but rather use dynamic type checking. +// +// For single fields, the logic for this is done inside the generated code. For +// repeated fields, the logic is done in LazyStringArrayList and +// UnmodifiableLazyStringList. +void StringFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.lang.String get$capitalized_name$();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes();\n"); +} + +void StringFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private java.lang.Object $name$_;\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.lang.String get$capitalized_name$() {\n" + " java.lang.Object ref = $name$_;\n" + " if (ref instanceof java.lang.String) {\n" + " return (java.lang.String) ref;\n" + " } else {\n" + " com.google.protobuf.ByteString bs = \n" + " (com.google.protobuf.ByteString) ref;\n" + " java.lang.String s = bs.toStringUtf8();\n" + " if (bs.isValidUtf8()) {\n" + " $name$_ = s;\n" + " }\n" + " return s;\n" + " }\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes() {\n" + " java.lang.Object ref = $name$_;\n" + " if (ref instanceof java.lang.String) {\n" + " com.google.protobuf.ByteString b = \n" + " com.google.protobuf.ByteString.copyFromUtf8(\n" + " (java.lang.String) ref);\n" + " $name$_ = b;\n" + " return b;\n" + " } else {\n" + " return (com.google.protobuf.ByteString) ref;\n" + " }\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + printer->Print(variables_, + "private java.lang.Object $name$_ $default_init$;\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.lang.String get$capitalized_name$() {\n" + " java.lang.Object ref = $name$_;\n" + " if (!(ref instanceof java.lang.String)) {\n" + " java.lang.String s = ((com.google.protobuf.ByteString) ref)\n" + " .toStringUtf8();\n" + " $name$_ = s;\n" + " return s;\n" + " } else {\n" + " return (java.lang.String) ref;\n" + " }\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes() {\n" + " java.lang.Object ref = $name$_;\n" + " if (ref instanceof String) {\n" + " com.google.protobuf.ByteString b = \n" + " com.google.protobuf.ByteString.copyFromUtf8(\n" + " (java.lang.String) ref);\n" + " $name$_ = b;\n" + " return b;\n" + " } else {\n" + " return (com.google.protobuf.ByteString) ref;\n" + " }\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder set$capitalized_name$(\n" + " java.lang.String value) {\n" + "$null_check$" + " $set_has_field_bit_builder$;\n" + " $name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $clear_has_field_bit_builder$;\n"); + // The default value is not a simple literal so we want to avoid executing + // it multiple times. Instead, get the default out of the default instance. + printer->Print(variables_, + " $name$_ = getDefaultInstance().get$capitalized_name$();\n"); + printer->Print(variables_, + " $on_changed$\n" + " return this;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder set$capitalized_name$Bytes(\n" + " com.google.protobuf.ByteString value) {\n" + "$null_check$" + " $set_has_field_bit_builder$;\n" + " $name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void StringFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void StringFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $default$;\n" + "$clear_has_field_bit_builder$;\n"); +} + +void StringFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + // Allow a slight breach of abstraction here in order to avoid forcing + // all string fields to Strings when copying fields from a Message. + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " $set_has_field_bit_builder$;\n" + " $name$_ = other.$name$_;\n" + " $on_changed$\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); +} + +void StringFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "$set_has_field_bit_message$;\n" + "$name$_ = input.readBytes();\n"); +} + +void StringFieldGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + // noop for strings. +} + +void StringFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " output.writeBytes($number$, get$capitalized_name$Bytes());\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeBytesSize($number$, get$capitalized_name$Bytes());\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$());\n"); +} + +void StringFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n"); + printer->Print(variables_, + "hash = (53 * hash) + get$capitalized_name$().hashCode();\n"); +} + +string StringFieldGenerator::GetBoxedType() const { + return "java.lang.String"; +} + + +// =================================================================== + +RepeatedStringFieldGenerator:: +RepeatedStringFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); +} + +RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {} + +int RepeatedStringFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedStringFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedStringFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.List\n" + "get$capitalized_name$List();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.lang.String get$capitalized_name$(int index);\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes(int index);\n"); +} + + +void RepeatedStringFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private com.google.protobuf.LazyStringList $name$_;\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List\n" + " get$capitalized_name$List() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes(int index) {\n" + " return $name$_.getByteString(index);\n" + "}\n"); + + if (descriptor_->options().packed() && + HasGeneratedMethods(descriptor_->containing_type())) { + printer->Print(variables_, + "private int $name$MemoizedSerializedSize = -1;\n"); + } +} + +void RepeatedStringFieldGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + // One field is the list and the bit field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a refererence to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + printer->Print(variables_, + "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n"); + + printer->Print(variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n" + " $set_mutable_bit_builder$;\n" + " }\n" + "}\n"); + + // Note: We return an unmodifiable list because otherwise the caller + // could hold on to the returned list and modify it after the message + // has been built, thus mutating the message which is supposed to be + // immutable. + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List\n" + " get$capitalized_name$List() {\n" + " return java.util.Collections.unmodifiableList($name$_);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes(int index) {\n" + " return $name$_.getByteString(index);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder set$capitalized_name$(\n" + " int index, java.lang.String value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder add$capitalized_name$(\n" + " java.lang.String value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder addAll$capitalized_name$(\n" + " java.lang.Iterable values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " super.addAll(values, $name$_);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $name$_ = $empty_list$;\n" + " $clear_mutable_bit_builder$;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder add$capitalized_name$Bytes(\n" + " com.google.protobuf.ByteString value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void RepeatedStringFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $empty_list$;\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $empty_list$;\n" + "$clear_mutable_bit_builder$;\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + // The code below does two optimizations: + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. + printer->Print(variables_, + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + // The code below ensures that the result has an immutable list. If our + // list is immutable, we can just reuse it. If not, we make it immutable. + + printer->Print(variables_, + "if ($get_mutable_bit_builder$) {\n" + " $name$_ = new com.google.protobuf.UnmodifiableLazyStringList(\n" + " $name$_);\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (!$get_mutable_bit_parser$) {\n" + " $name$_ = new com.google.protobuf.LazyStringArrayList();\n" + " $set_mutable_bit_parser$;\n" + "}\n" + "$name$_.add(input.readBytes());\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateParsingCodeFromPacked(io::Printer* printer) const { + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int limit = input.pushLimit(length);\n" + "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n" + " $name$_ = new com.google.protobuf.LazyStringArrayList();\n" + " $set_mutable_bit_parser$;\n" + "}\n" + "while (input.getBytesUntilLimit() > 0) {\n" + " $name$.add(input.read$capitalized_type$());\n" + "}\n" + "input.popLimit(limit);\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_mutable_bit_parser$) {\n" + " $name$_ = new com.google.protobuf.UnmodifiableLazyStringList($name$_);\n" + "}\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (get$capitalized_name$List().size() > 0) {\n" + " output.writeRawVarint32($tag$);\n" + " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + "}\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$capitalized_type$NoTag($name$_.get(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.writeBytes($number$, $name$_.getByteString(i));\n" + "}\n"); + } +} + +void RepeatedStringFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "{\n" + " int dataSize = 0;\n"); + printer->Indent(); + + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " dataSize += com.google.protobuf.CodedOutputStream\n" + " .computeBytesSizeNoTag($name$_.getByteString(i));\n" + "}\n"); + + printer->Print( + "size += dataSize;\n"); + + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (!get$capitalized_name$List().isEmpty()) {\n" + " size += $tag_size$;\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeInt32SizeNoTag(dataSize);\n" + "}\n"); + } else { + printer->Print(variables_, + "size += $tag_size$ * get$capitalized_name$List().size();\n"); + } + + // cache the data size for packed fields. + if (descriptor_->options().packed()) { + printer->Print(variables_, + "$name$MemoizedSerializedSize = dataSize;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List());\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n" + "}\n"); +} + +string RepeatedStringFieldGenerator::GetBoxedType() const { + return "String"; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_string_field.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_string_field.h new file mode 100644 index 0000000..4f7532f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/java/java_string_field.h @@ -0,0 +1,122 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Author: jonp@google.com (Jon Perlow) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class StringFieldGenerator : public FieldGenerator { + public: + explicit StringFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); + ~StringFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + const int messageBitIndex_; + const int builderBitIndex_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator); +}; + +class RepeatedStringFieldGenerator : public FieldGenerator { + public: + explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); + ~RepeatedStringFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingCodeFromPacked(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map variables_; + const int messageBitIndex_; + const int builderBitIndex_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/main.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/main.cc new file mode 100644 index 0000000..1afc5d6 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/main.cc @@ -0,0 +1,61 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include +#include +#include +#include + + +int main(int argc, char* argv[]) { + + google::protobuf::compiler::CommandLineInterface cli; + cli.AllowPlugins("protoc-"); + + // Proto2 C++ + google::protobuf::compiler::cpp::CppGenerator cpp_generator; + cli.RegisterGenerator("--cpp_out", "--cpp_opt", &cpp_generator, + "Generate C++ header and source."); + + // Proto2 Java + google::protobuf::compiler::java::JavaGenerator java_generator; + cli.RegisterGenerator("--java_out", &java_generator, + "Generate Java source file."); + + + // Proto2 Python + google::protobuf::compiler::python::Generator py_generator; + cli.RegisterGenerator("--python_out", &py_generator, + "Generate Python source file."); + + return cli.Run(argc, argv); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/mock_code_generator.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/mock_code_generator.cc new file mode 100644 index 0000000..0e35ed1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/mock_code_generator.cc @@ -0,0 +1,241 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { + +// Returns the list of the names of files in all_files in the form of a +// comma-separated string. +string CommaSeparatedList(const vector all_files) { + vector names; + for (int i = 0; i < all_files.size(); i++) { + names.push_back(all_files[i]->name()); + } + return JoinStrings(names, ","); +} + +static const char* kFirstInsertionPointName = "first_mock_insertion_point"; +static const char* kSecondInsertionPointName = "second_mock_insertion_point"; +static const char* kFirstInsertionPoint = + "# @@protoc_insertion_point(first_mock_insertion_point) is here\n"; +static const char* kSecondInsertionPoint = + " # @@protoc_insertion_point(second_mock_insertion_point) is here\n"; + +MockCodeGenerator::MockCodeGenerator(const string& name) + : name_(name) {} + +MockCodeGenerator::~MockCodeGenerator() {} + +void MockCodeGenerator::ExpectGenerated( + const string& name, + const string& parameter, + const string& insertions, + const string& file, + const string& first_message_name, + const string& first_parsed_file_name, + const string& output_directory) { + string content; + ASSERT_TRUE(File::ReadFileToString( + output_directory + "/" + GetOutputFileName(name, file), &content)); + + vector lines; + SplitStringUsing(content, "\n", &lines); + + while (!lines.empty() && lines.back().empty()) { + lines.pop_back(); + } + for (int i = 0; i < lines.size(); i++) { + lines[i] += "\n"; + } + + vector insertion_list; + if (!insertions.empty()) { + SplitStringUsing(insertions, ",", &insertion_list); + } + + ASSERT_EQ(lines.size(), 3 + insertion_list.size() * 2); + EXPECT_EQ(GetOutputFileContent(name, parameter, file, + first_parsed_file_name, first_message_name), + lines[0]); + + EXPECT_EQ(kFirstInsertionPoint, lines[1 + insertion_list.size()]); + EXPECT_EQ(kSecondInsertionPoint, lines[2 + insertion_list.size() * 2]); + + for (int i = 0; i < insertion_list.size(); i++) { + EXPECT_EQ(GetOutputFileContent(insertion_list[i], "first_insert", + file, file, first_message_name), + lines[1 + i]); + // Second insertion point is indented, so the inserted text should + // automatically be indented too. + EXPECT_EQ(" " + GetOutputFileContent(insertion_list[i], "second_insert", + file, file, first_message_name), + lines[2 + insertion_list.size() + i]); + } +} + +bool MockCodeGenerator::Generate( + const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const { + for (int i = 0; i < file->message_type_count(); i++) { + if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) { + string command = StripPrefixString(file->message_type(i)->name(), + "MockCodeGenerator_"); + if (command == "Error") { + *error = "Saw message type MockCodeGenerator_Error."; + return false; + } else if (command == "Exit") { + cerr << "Saw message type MockCodeGenerator_Exit." << endl; + exit(123); + } else if (command == "Abort") { + cerr << "Saw message type MockCodeGenerator_Abort." << endl; + abort(); + } else if (command == "HasSourceCodeInfo") { + FileDescriptorProto file_descriptor_proto; + file->CopySourceCodeInfoTo(&file_descriptor_proto); + bool has_source_code_info = + file_descriptor_proto.has_source_code_info() && + file_descriptor_proto.source_code_info().location_size() > 0; + cerr << "Saw message type MockCodeGenerator_HasSourceCodeInfo: " + << has_source_code_info << "." << endl; + abort(); + } else { + GOOGLE_LOG(FATAL) << "Unknown MockCodeGenerator command: " << command; + } + } + } + + if (HasPrefixString(parameter, "insert=")) { + vector insert_into; + SplitStringUsing(StripPrefixString(parameter, "insert="), + ",", &insert_into); + + for (int i = 0; i < insert_into.size(); i++) { + { + scoped_ptr output( + context->OpenForInsert( + GetOutputFileName(insert_into[i], file), + kFirstInsertionPointName)); + io::Printer printer(output.get(), '$'); + printer.PrintRaw(GetOutputFileContent(name_, "first_insert", + file, context)); + if (printer.failed()) { + *error = "MockCodeGenerator detected write error."; + return false; + } + } + + { + scoped_ptr output( + context->OpenForInsert( + GetOutputFileName(insert_into[i], file), + kSecondInsertionPointName)); + io::Printer printer(output.get(), '$'); + printer.PrintRaw(GetOutputFileContent(name_, "second_insert", + file, context)); + if (printer.failed()) { + *error = "MockCodeGenerator detected write error."; + return false; + } + } + } + } else { + scoped_ptr output( + context->Open(GetOutputFileName(name_, file))); + + io::Printer printer(output.get(), '$'); + printer.PrintRaw(GetOutputFileContent(name_, parameter, + file, context)); + printer.PrintRaw(kFirstInsertionPoint); + printer.PrintRaw(kSecondInsertionPoint); + + if (printer.failed()) { + *error = "MockCodeGenerator detected write error."; + return false; + } + } + + return true; +} + +string MockCodeGenerator::GetOutputFileName(const string& generator_name, + const FileDescriptor* file) { + return GetOutputFileName(generator_name, file->name()); +} + +string MockCodeGenerator::GetOutputFileName(const string& generator_name, + const string& file) { + return file + ".MockCodeGenerator." + generator_name; +} + +string MockCodeGenerator::GetOutputFileContent( + const string& generator_name, + const string& parameter, + const FileDescriptor* file, + GeneratorContext *context) { + vector all_files; + context->ListParsedFiles(&all_files); + return GetOutputFileContent( + generator_name, parameter, file->name(), + CommaSeparatedList(all_files), + file->message_type_count() > 0 ? + file->message_type(0)->name() : "(none)"); +} + +string MockCodeGenerator::GetOutputFileContent( + const string& generator_name, + const string& parameter, + const string& file, + const string& parsed_file_list, + const string& first_message_name) { + return strings::Substitute("$0: $1, $2, $3, $4\n", + generator_name, parameter, file, + first_message_name, parsed_file_list); +} + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/mock_code_generator.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/mock_code_generator.h new file mode 100644 index 0000000..506fd20 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/mock_code_generator.h @@ -0,0 +1,117 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#ifndef GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { + +// A mock CodeGenerator, used by command_line_interface_unittest. This is in +// its own file so that it can be used both directly and as a plugin. +// +// Generate() produces some output which can be checked by ExpectCalled(). The +// generator can run in a different process (e.g. a plugin). +// +// If the parameter is "insert=NAMES", the MockCodeGenerator will insert lines +// into the files generated by other MockCodeGenerators instead of creating +// its own file. NAMES is a comma-separated list of the names of those other +// MockCodeGenerators. +// +// MockCodeGenerator will also modify its behavior slightly if the input file +// contains a message type with one of the following names: +// MockCodeGenerator_Error: Causes Generate() to return false and set the +// error message to "Saw message type MockCodeGenerator_Error." +// MockCodeGenerator_Exit: Generate() prints "Saw message type +// MockCodeGenerator_Exit." to stderr and then calls exit(123). +// MockCodeGenerator_Abort: Generate() prints "Saw message type +// MockCodeGenerator_Abort." to stderr and then calls abort(). +// MockCodeGenerator_HasSourceCodeInfo: Causes Generate() to abort after +// printing "Saw message type MockCodeGenerator_HasSourceCodeInfo: FOO." to +// stderr, where FOO is "1" if the supplied FileDescriptorProto has source +// code info, and "0" otherwise. +class MockCodeGenerator : public CodeGenerator { + public: + MockCodeGenerator(const string& name); + virtual ~MockCodeGenerator(); + + // Expect (via gTest) that a MockCodeGenerator with the given name was called + // with the given parameters by inspecting the output location. + // + // |insertions| is a comma-separated list of names of MockCodeGenerators which + // should have inserted lines into this file. + // |parsed_file_list| is a comma-separated list of names of the files + // that are being compiled together in this run. + static void ExpectGenerated(const string& name, + const string& parameter, + const string& insertions, + const string& file, + const string& first_message_name, + const string& parsed_file_list, + const string& output_directory); + + // Get the name of the file which would be written by the given generator. + static string GetOutputFileName(const string& generator_name, + const FileDescriptor* file); + static string GetOutputFileName(const string& generator_name, + const string& file); + + // implements CodeGenerator ---------------------------------------- + + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const; + + private: + string name_; + + static string GetOutputFileContent(const string& generator_name, + const string& parameter, + const FileDescriptor* file, + GeneratorContext *context); + static string GetOutputFileContent(const string& generator_name, + const string& parameter, + const string& file, + const string& parsed_file_list, + const string& first_message_name); +}; + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/package_info.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/package_info.h new file mode 100644 index 0000000..b897126 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/package_info.h @@ -0,0 +1,64 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file exists solely to document the google::protobuf::compiler namespace. +// It is not compiled into anything, but it may be read by an automated +// documentation generator. + +namespace google { + +namespace protobuf { + +// Implementation of the Protocol Buffer compiler. +// +// This package contains code for parsing .proto files and generating code +// based on them. There are two reasons you might be interested in this +// package: +// - You want to parse .proto files at runtime. In this case, you should +// look at importer.h. Since this functionality is widely useful, it is +// included in the libprotobuf base library; you do not have to link against +// libprotoc. +// - You want to write a custom protocol compiler which generates different +// kinds of code, e.g. code in a different language which is not supported +// by the official compiler. For this purpose, command_line_interface.h +// provides you with a complete compiler front-end, so all you need to do +// is write a custom implementation of CodeGenerator and a trivial main() +// function. You can even make your compiler support the official languages +// in addition to your own. Since this functionality is only useful to those +// writing custom compilers, it is in a separate library called "libprotoc" +// which you will have to link against. +namespace compiler {} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser.cc new file mode 100644 index 0000000..23aa01c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser.cc @@ -0,0 +1,1611 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Recursive descent FTW. + +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { + +using internal::WireFormat; + +namespace { + +typedef hash_map TypeNameMap; + +TypeNameMap MakeTypeNameTable() { + TypeNameMap result; + + result["double" ] = FieldDescriptorProto::TYPE_DOUBLE; + result["float" ] = FieldDescriptorProto::TYPE_FLOAT; + result["uint64" ] = FieldDescriptorProto::TYPE_UINT64; + result["fixed64" ] = FieldDescriptorProto::TYPE_FIXED64; + result["fixed32" ] = FieldDescriptorProto::TYPE_FIXED32; + result["bool" ] = FieldDescriptorProto::TYPE_BOOL; + result["string" ] = FieldDescriptorProto::TYPE_STRING; + result["group" ] = FieldDescriptorProto::TYPE_GROUP; + + result["bytes" ] = FieldDescriptorProto::TYPE_BYTES; + result["uint32" ] = FieldDescriptorProto::TYPE_UINT32; + result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32; + result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64; + result["int32" ] = FieldDescriptorProto::TYPE_INT32; + result["int64" ] = FieldDescriptorProto::TYPE_INT64; + result["sint32" ] = FieldDescriptorProto::TYPE_SINT32; + result["sint64" ] = FieldDescriptorProto::TYPE_SINT64; + + return result; +} + +const TypeNameMap kTypeNames = MakeTypeNameTable(); + +} // anonymous namespace + +// Makes code slightly more readable. The meaning of "DO(foo)" is +// "Execute foo and fail if it fails.", where failure is indicated by +// returning false. +#define DO(STATEMENT) if (STATEMENT) {} else return false + +// =================================================================== + +Parser::Parser() + : input_(NULL), + error_collector_(NULL), + source_location_table_(NULL), + had_errors_(false), + require_syntax_identifier_(false), + stop_after_syntax_identifier_(false) { +} + +Parser::~Parser() { +} + +// =================================================================== + +inline bool Parser::LookingAt(const char* text) { + return input_->current().text == text; +} + +inline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type) { + return input_->current().type == token_type; +} + +inline bool Parser::AtEnd() { + return LookingAtType(io::Tokenizer::TYPE_END); +} + +bool Parser::TryConsume(const char* text) { + if (LookingAt(text)) { + input_->Next(); + return true; + } else { + return false; + } +} + +bool Parser::Consume(const char* text, const char* error) { + if (TryConsume(text)) { + return true; + } else { + AddError(error); + return false; + } +} + +bool Parser::Consume(const char* text) { + if (TryConsume(text)) { + return true; + } else { + AddError("Expected \"" + string(text) + "\"."); + return false; + } +} + +bool Parser::ConsumeIdentifier(string* output, const char* error) { + if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + *output = input_->current().text; + input_->Next(); + return true; + } else { + AddError(error); + return false; + } +} + +bool Parser::ConsumeInteger(int* output, const char* error) { + if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + uint64 value = 0; + if (!io::Tokenizer::ParseInteger(input_->current().text, + kint32max, &value)) { + AddError("Integer out of range."); + // We still return true because we did, in fact, parse an integer. + } + *output = value; + input_->Next(); + return true; + } else { + AddError(error); + return false; + } +} + +bool Parser::ConsumeSignedInteger(int* output, const char* error) { + bool is_negative = false; + uint64 max_value = kint32max; + if (TryConsume("-")) { + is_negative = true; + max_value += 1; + } + uint64 value = 0; + DO(ConsumeInteger64(max_value, &value, error)); + if (is_negative) value *= -1; + *output = value; + return true; +} + +bool Parser::ConsumeInteger64(uint64 max_value, uint64* output, + const char* error) { + if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + if (!io::Tokenizer::ParseInteger(input_->current().text, max_value, + output)) { + AddError("Integer out of range."); + // We still return true because we did, in fact, parse an integer. + *output = 0; + } + input_->Next(); + return true; + } else { + AddError(error); + return false; + } +} + +bool Parser::ConsumeNumber(double* output, const char* error) { + if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { + *output = io::Tokenizer::ParseFloat(input_->current().text); + input_->Next(); + return true; + } else if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + // Also accept integers. + uint64 value = 0; + if (!io::Tokenizer::ParseInteger(input_->current().text, + kuint64max, &value)) { + AddError("Integer out of range."); + // We still return true because we did, in fact, parse a number. + } + *output = value; + input_->Next(); + return true; + } else if (LookingAt("inf")) { + *output = numeric_limits::infinity(); + input_->Next(); + return true; + } else if (LookingAt("nan")) { + *output = numeric_limits::quiet_NaN(); + input_->Next(); + return true; + } else { + AddError(error); + return false; + } +} + +bool Parser::ConsumeString(string* output, const char* error) { + if (LookingAtType(io::Tokenizer::TYPE_STRING)) { + io::Tokenizer::ParseString(input_->current().text, output); + input_->Next(); + // Allow C++ like concatenation of adjacent string tokens. + while (LookingAtType(io::Tokenizer::TYPE_STRING)) { + io::Tokenizer::ParseStringAppend(input_->current().text, output); + input_->Next(); + } + return true; + } else { + AddError(error); + return false; + } +} + +bool Parser::TryConsumeEndOfDeclaration(const char* text, + const LocationRecorder* location) { + if (LookingAt(text)) { + string leading, trailing; + input_->NextWithComments(&trailing, NULL, &leading); + + // Save the leading comments for next time, and recall the leading comments + // from last time. + leading.swap(upcoming_doc_comments_); + + if (location != NULL) { + location->AttachComments(&leading, &trailing); + } + return true; + } else { + return false; + } +} + +bool Parser::ConsumeEndOfDeclaration(const char* text, + const LocationRecorder* location) { + if (TryConsumeEndOfDeclaration(text, location)) { + return true; + } else { + AddError("Expected \"" + string(text) + "\"."); + return false; + } +} + +// ------------------------------------------------------------------- + +void Parser::AddError(int line, int column, const string& error) { + if (error_collector_ != NULL) { + error_collector_->AddError(line, column, error); + } + had_errors_ = true; +} + +void Parser::AddError(const string& error) { + AddError(input_->current().line, input_->current().column, error); +} + +// ------------------------------------------------------------------- + +Parser::LocationRecorder::LocationRecorder(Parser* parser) + : parser_(parser), + location_(parser_->source_code_info_->add_location()) { + location_->add_span(parser_->input_->current().line); + location_->add_span(parser_->input_->current().column); +} + +Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) { + Init(parent); +} + +Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent, + int path1) { + Init(parent); + AddPath(path1); +} + +Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent, + int path1, int path2) { + Init(parent); + AddPath(path1); + AddPath(path2); +} + +void Parser::LocationRecorder::Init(const LocationRecorder& parent) { + parser_ = parent.parser_; + location_ = parser_->source_code_info_->add_location(); + location_->mutable_path()->CopyFrom(parent.location_->path()); + + location_->add_span(parser_->input_->current().line); + location_->add_span(parser_->input_->current().column); +} + +Parser::LocationRecorder::~LocationRecorder() { + if (location_->span_size() <= 2) { + EndAt(parser_->input_->previous()); + } +} + +void Parser::LocationRecorder::AddPath(int path_component) { + location_->add_path(path_component); +} + +void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) { + location_->set_span(0, token.line); + location_->set_span(1, token.column); +} + +void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) { + if (token.line != location_->span(0)) { + location_->add_span(token.line); + } + location_->add_span(token.end_column); +} + +void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location) { + if (parser_->source_location_table_ != NULL) { + parser_->source_location_table_->Add( + descriptor, location, location_->span(0), location_->span(1)); + } +} + +void Parser::LocationRecorder::AttachComments( + string* leading, string* trailing) const { + GOOGLE_CHECK(!location_->has_leading_comments()); + GOOGLE_CHECK(!location_->has_trailing_comments()); + + if (!leading->empty()) { + location_->mutable_leading_comments()->swap(*leading); + } + if (!trailing->empty()) { + location_->mutable_trailing_comments()->swap(*trailing); + } +} + +// ------------------------------------------------------------------- + +void Parser::SkipStatement() { + while (true) { + if (AtEnd()) { + return; + } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { + if (TryConsumeEndOfDeclaration(";", NULL)) { + return; + } else if (TryConsume("{")) { + SkipRestOfBlock(); + return; + } else if (LookingAt("}")) { + return; + } + } + input_->Next(); + } +} + +void Parser::SkipRestOfBlock() { + while (true) { + if (AtEnd()) { + return; + } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { + if (TryConsumeEndOfDeclaration("}", NULL)) { + return; + } else if (TryConsume("{")) { + SkipRestOfBlock(); + } + } + input_->Next(); + } +} + +// =================================================================== + +bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { + input_ = input; + had_errors_ = false; + syntax_identifier_.clear(); + + // Note that |file| could be NULL at this point if + // stop_after_syntax_identifier_ is true. So, we conservatively allocate + // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto + // later on. + SourceCodeInfo source_code_info; + source_code_info_ = &source_code_info; + + if (LookingAtType(io::Tokenizer::TYPE_START)) { + // Advance to first token. + input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_); + } + + { + LocationRecorder root_location(this); + + if (require_syntax_identifier_ || LookingAt("syntax")) { + if (!ParseSyntaxIdentifier()) { + // Don't attempt to parse the file if we didn't recognize the syntax + // identifier. + return false; + } + } else if (!stop_after_syntax_identifier_) { + syntax_identifier_ = "proto2"; + } + + if (stop_after_syntax_identifier_) return !had_errors_; + + // Repeatedly parse statements until we reach the end of the file. + while (!AtEnd()) { + if (!ParseTopLevelStatement(file, root_location)) { + // This statement failed to parse. Skip it, but keep looping to parse + // other statements. + SkipStatement(); + + if (LookingAt("}")) { + AddError("Unmatched \"}\"."); + input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_); + } + } + } + } + + input_ = NULL; + source_code_info_ = NULL; + source_code_info.Swap(file->mutable_source_code_info()); + return !had_errors_; +} + +bool Parser::ParseSyntaxIdentifier() { + DO(Consume("syntax", "File must begin with 'syntax = \"proto2\";'.")); + DO(Consume("=")); + io::Tokenizer::Token syntax_token = input_->current(); + string syntax; + DO(ConsumeString(&syntax, "Expected syntax identifier.")); + DO(ConsumeEndOfDeclaration(";", NULL)); + + syntax_identifier_ = syntax; + + if (syntax != "proto2" && !stop_after_syntax_identifier_) { + AddError(syntax_token.line, syntax_token.column, + "Unrecognized syntax identifier \"" + syntax + "\". This parser " + "only recognizes \"proto2\"."); + return false; + } + + return true; +} + +bool Parser::ParseTopLevelStatement(FileDescriptorProto* file, + const LocationRecorder& root_location) { + if (TryConsumeEndOfDeclaration(";", NULL)) { + // empty statement; ignore + return true; + } else if (LookingAt("message")) { + LocationRecorder location(root_location, + FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size()); + return ParseMessageDefinition(file->add_message_type(), location); + } else if (LookingAt("enum")) { + LocationRecorder location(root_location, + FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size()); + return ParseEnumDefinition(file->add_enum_type(), location); + } else if (LookingAt("service")) { + LocationRecorder location(root_location, + FileDescriptorProto::kServiceFieldNumber, file->service_size()); + return ParseServiceDefinition(file->add_service(), location); + } else if (LookingAt("extend")) { + LocationRecorder location(root_location, + FileDescriptorProto::kExtensionFieldNumber); + return ParseExtend(file->mutable_extension(), + file->mutable_message_type(), + root_location, + FileDescriptorProto::kMessageTypeFieldNumber, + location); + } else if (LookingAt("import")) { + return ParseImport(file->mutable_dependency(), + file->mutable_public_dependency(), + file->mutable_weak_dependency(), + root_location); + } else if (LookingAt("package")) { + return ParsePackage(file, root_location); + } else if (LookingAt("option")) { + LocationRecorder location(root_location, + FileDescriptorProto::kOptionsFieldNumber); + return ParseOption(file->mutable_options(), location, OPTION_STATEMENT); + } else { + AddError("Expected top-level statement (e.g. \"message\")."); + return false; + } +} + +// ------------------------------------------------------------------- +// Messages + +bool Parser::ParseMessageDefinition(DescriptorProto* message, + const LocationRecorder& message_location) { + DO(Consume("message")); + { + LocationRecorder location(message_location, + DescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation( + message, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(message->mutable_name(), "Expected message name.")); + } + DO(ParseMessageBlock(message, message_location)); + return true; +} + +namespace { + +const int kMaxExtensionRangeSentinel = -1; + +bool IsMessageSetWireFormatMessage(const DescriptorProto& message) { + const MessageOptions& options = message.options(); + for (int i = 0; i < options.uninterpreted_option_size(); ++i) { + const UninterpretedOption& uninterpreted = options.uninterpreted_option(i); + if (uninterpreted.name_size() == 1 && + uninterpreted.name(0).name_part() == "message_set_wire_format" && + uninterpreted.identifier_value() == "true") { + return true; + } + } + return false; +} + +// Modifies any extension ranges that specified 'max' as the end of the +// extension range, and sets them to the type-specific maximum. The actual max +// tag number can only be determined after all options have been parsed. +void AdjustExtensionRangesWithMaxEndNumber(DescriptorProto* message) { + const bool is_message_set = IsMessageSetWireFormatMessage(*message); + const int max_extension_number = is_message_set ? + kint32max : + FieldDescriptor::kMaxNumber + 1; + for (int i = 0; i < message->extension_range_size(); ++i) { + if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) { + message->mutable_extension_range(i)->set_end(max_extension_number); + } + } +} + +} // namespace + +bool Parser::ParseMessageBlock(DescriptorProto* message, + const LocationRecorder& message_location) { + DO(ConsumeEndOfDeclaration("{", &message_location)); + + while (!TryConsumeEndOfDeclaration("}", NULL)) { + if (AtEnd()) { + AddError("Reached end of input in message definition (missing '}')."); + return false; + } + + if (!ParseMessageStatement(message, message_location)) { + // This statement failed to parse. Skip it, but keep looping to parse + // other statements. + SkipStatement(); + } + } + + if (message->extension_range_size() > 0) { + AdjustExtensionRangesWithMaxEndNumber(message); + } + return true; +} + +bool Parser::ParseMessageStatement(DescriptorProto* message, + const LocationRecorder& message_location) { + if (TryConsumeEndOfDeclaration(";", NULL)) { + // empty statement; ignore + return true; + } else if (LookingAt("message")) { + LocationRecorder location(message_location, + DescriptorProto::kNestedTypeFieldNumber, + message->nested_type_size()); + return ParseMessageDefinition(message->add_nested_type(), location); + } else if (LookingAt("enum")) { + LocationRecorder location(message_location, + DescriptorProto::kEnumTypeFieldNumber, + message->enum_type_size()); + return ParseEnumDefinition(message->add_enum_type(), location); + } else if (LookingAt("extensions")) { + LocationRecorder location(message_location, + DescriptorProto::kExtensionRangeFieldNumber); + return ParseExtensions(message, location); + } else if (LookingAt("extend")) { + LocationRecorder location(message_location, + DescriptorProto::kExtensionFieldNumber); + return ParseExtend(message->mutable_extension(), + message->mutable_nested_type(), + message_location, + DescriptorProto::kNestedTypeFieldNumber, + location); + } else if (LookingAt("option")) { + LocationRecorder location(message_location, + DescriptorProto::kOptionsFieldNumber); + return ParseOption(message->mutable_options(), location, OPTION_STATEMENT); + } else { + LocationRecorder location(message_location, + DescriptorProto::kFieldFieldNumber, + message->field_size()); + return ParseMessageField(message->add_field(), + message->mutable_nested_type(), + message_location, + DescriptorProto::kNestedTypeFieldNumber, + location); + } +} + +bool Parser::ParseMessageField(FieldDescriptorProto* field, + RepeatedPtrField* messages, + const LocationRecorder& parent_location, + int location_field_number_for_nested_type, + const LocationRecorder& field_location) { + // Parse label and type. + io::Tokenizer::Token label_token = input_->current(); + { + LocationRecorder location(field_location, + FieldDescriptorProto::kLabelFieldNumber); + FieldDescriptorProto::Label label; + DO(ParseLabel(&label)); + field->set_label(label); + } + + { + LocationRecorder location(field_location); // add path later + location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE); + + FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32; + string type_name; + DO(ParseType(&type, &type_name)); + if (type_name.empty()) { + location.AddPath(FieldDescriptorProto::kTypeFieldNumber); + field->set_type(type); + } else { + location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber); + field->set_type_name(type_name); + } + } + + // Parse name and '='. + io::Tokenizer::Token name_token = input_->current(); + { + LocationRecorder location(field_location, + FieldDescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(field->mutable_name(), "Expected field name.")); + } + DO(Consume("=", "Missing field number.")); + + // Parse field number. + { + LocationRecorder location(field_location, + FieldDescriptorProto::kNumberFieldNumber); + location.RecordLegacyLocation( + field, DescriptorPool::ErrorCollector::NUMBER); + int number; + DO(ConsumeInteger(&number, "Expected field number.")); + field->set_number(number); + } + + // Parse options. + DO(ParseFieldOptions(field, field_location)); + + // Deal with groups. + if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) { + // Awkward: Since a group declares both a message type and a field, we + // have to create overlapping locations. + LocationRecorder group_location(parent_location); + group_location.StartAt(label_token); + group_location.AddPath(location_field_number_for_nested_type); + group_location.AddPath(messages->size()); + + DescriptorProto* group = messages->Add(); + group->set_name(field->name()); + + // Record name location to match the field name's location. + { + LocationRecorder location(group_location, + DescriptorProto::kNameFieldNumber); + location.StartAt(name_token); + location.EndAt(name_token); + location.RecordLegacyLocation( + group, DescriptorPool::ErrorCollector::NAME); + } + + // The field's type_name also comes from the name. Confusing! + { + LocationRecorder location(field_location, + FieldDescriptorProto::kTypeNameFieldNumber); + location.StartAt(name_token); + location.EndAt(name_token); + } + + // As a hack for backwards-compatibility, we force the group name to start + // with a capital letter and lower-case the field name. New code should + // not use groups; it should use nested messages. + if (group->name()[0] < 'A' || 'Z' < group->name()[0]) { + AddError(name_token.line, name_token.column, + "Group names must start with a capital letter."); + } + LowerString(field->mutable_name()); + + field->set_type_name(group->name()); + if (LookingAt("{")) { + DO(ParseMessageBlock(group, group_location)); + } else { + AddError("Missing group body."); + return false; + } + } else { + DO(ConsumeEndOfDeclaration(";", &field_location)); + } + + return true; +} + +bool Parser::ParseFieldOptions(FieldDescriptorProto* field, + const LocationRecorder& field_location) { + if (!LookingAt("[")) return true; + + LocationRecorder location(field_location, + FieldDescriptorProto::kOptionsFieldNumber); + + DO(Consume("[")); + + // Parse field options. + do { + if (LookingAt("default")) { + // We intentionally pass field_location rather than location here, since + // the default value is not actually an option. + DO(ParseDefaultAssignment(field, field_location)); + } else { + DO(ParseOption(field->mutable_options(), location, OPTION_ASSIGNMENT)); + } + } while (TryConsume(",")); + + DO(Consume("]")); + return true; +} + +bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field, + const LocationRecorder& field_location) { + if (field->has_default_value()) { + AddError("Already set option \"default\"."); + field->clear_default_value(); + } + + DO(Consume("default")); + DO(Consume("=")); + + LocationRecorder location(field_location, + FieldDescriptorProto::kDefaultValueFieldNumber); + location.RecordLegacyLocation( + field, DescriptorPool::ErrorCollector::DEFAULT_VALUE); + string* default_value = field->mutable_default_value(); + + if (!field->has_type()) { + // The field has a type name, but we don't know if it is a message or an + // enum yet. Assume an enum for now. + DO(ConsumeIdentifier(default_value, "Expected identifier.")); + return true; + } + + switch (field->type()) { + case FieldDescriptorProto::TYPE_INT32: + case FieldDescriptorProto::TYPE_INT64: + case FieldDescriptorProto::TYPE_SINT32: + case FieldDescriptorProto::TYPE_SINT64: + case FieldDescriptorProto::TYPE_SFIXED32: + case FieldDescriptorProto::TYPE_SFIXED64: { + uint64 max_value = kint64max; + if (field->type() == FieldDescriptorProto::TYPE_INT32 || + field->type() == FieldDescriptorProto::TYPE_SINT32 || + field->type() == FieldDescriptorProto::TYPE_SFIXED32) { + max_value = kint32max; + } + + // These types can be negative. + if (TryConsume("-")) { + default_value->append("-"); + // Two's complement always has one more negative value than positive. + ++max_value; + } + // Parse the integer to verify that it is not out-of-range. + uint64 value; + DO(ConsumeInteger64(max_value, &value, "Expected integer.")); + // And stringify it again. + default_value->append(SimpleItoa(value)); + break; + } + + case FieldDescriptorProto::TYPE_UINT32: + case FieldDescriptorProto::TYPE_UINT64: + case FieldDescriptorProto::TYPE_FIXED32: + case FieldDescriptorProto::TYPE_FIXED64: { + uint64 max_value = kuint64max; + if (field->type() == FieldDescriptorProto::TYPE_UINT32 || + field->type() == FieldDescriptorProto::TYPE_FIXED32) { + max_value = kuint32max; + } + + // Numeric, not negative. + if (TryConsume("-")) { + AddError("Unsigned field can't have negative default value."); + } + // Parse the integer to verify that it is not out-of-range. + uint64 value; + DO(ConsumeInteger64(max_value, &value, "Expected integer.")); + // And stringify it again. + default_value->append(SimpleItoa(value)); + break; + } + + case FieldDescriptorProto::TYPE_FLOAT: + case FieldDescriptorProto::TYPE_DOUBLE: + // These types can be negative. + if (TryConsume("-")) { + default_value->append("-"); + } + // Parse the integer because we have to convert hex integers to decimal + // floats. + double value; + DO(ConsumeNumber(&value, "Expected number.")); + // And stringify it again. + default_value->append(SimpleDtoa(value)); + break; + + case FieldDescriptorProto::TYPE_BOOL: + if (TryConsume("true")) { + default_value->assign("true"); + } else if (TryConsume("false")) { + default_value->assign("false"); + } else { + AddError("Expected \"true\" or \"false\"."); + return false; + } + break; + + case FieldDescriptorProto::TYPE_STRING: + DO(ConsumeString(default_value, "Expected string.")); + break; + + case FieldDescriptorProto::TYPE_BYTES: + DO(ConsumeString(default_value, "Expected string.")); + *default_value = CEscape(*default_value); + break; + + case FieldDescriptorProto::TYPE_ENUM: + DO(ConsumeIdentifier(default_value, "Expected identifier.")); + break; + + case FieldDescriptorProto::TYPE_MESSAGE: + case FieldDescriptorProto::TYPE_GROUP: + AddError("Messages can't have default values."); + return false; + } + + return true; +} + +bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option, + const LocationRecorder& part_location) { + UninterpretedOption::NamePart* name = uninterpreted_option->add_name(); + string identifier; // We parse identifiers into this string. + if (LookingAt("(")) { // This is an extension. + DO(Consume("(")); + + { + LocationRecorder location( + part_location, UninterpretedOption::NamePart::kNamePartFieldNumber); + // An extension name consists of dot-separated identifiers, and may begin + // with a dot. + if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + DO(ConsumeIdentifier(&identifier, "Expected identifier.")); + name->mutable_name_part()->append(identifier); + } + while (LookingAt(".")) { + DO(Consume(".")); + name->mutable_name_part()->append("."); + DO(ConsumeIdentifier(&identifier, "Expected identifier.")); + name->mutable_name_part()->append(identifier); + } + } + + DO(Consume(")")); + name->set_is_extension(true); + } else { // This is a regular field. + LocationRecorder location( + part_location, UninterpretedOption::NamePart::kNamePartFieldNumber); + DO(ConsumeIdentifier(&identifier, "Expected identifier.")); + name->mutable_name_part()->append(identifier); + name->set_is_extension(false); + } + return true; +} + +bool Parser::ParseUninterpretedBlock(string* value) { + // Note that enclosing braces are not added to *value. + // We do NOT use ConsumeEndOfStatement for this brace because it's delimiting + // an expression, not a block of statements. + DO(Consume("{")); + int brace_depth = 1; + while (!AtEnd()) { + if (LookingAt("{")) { + brace_depth++; + } else if (LookingAt("}")) { + brace_depth--; + if (brace_depth == 0) { + input_->Next(); + return true; + } + } + // TODO(sanjay): Interpret line/column numbers to preserve formatting + if (!value->empty()) value->push_back(' '); + value->append(input_->current().text); + input_->Next(); + } + AddError("Unexpected end of stream while parsing aggregate value."); + return false; +} + +// We don't interpret the option here. Instead we store it in an +// UninterpretedOption, to be interpreted later. +bool Parser::ParseOption(Message* options, + const LocationRecorder& options_location, + OptionStyle style) { + // Create an entry in the uninterpreted_option field. + const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()-> + FindFieldByName("uninterpreted_option"); + GOOGLE_CHECK(uninterpreted_option_field != NULL) + << "No field named \"uninterpreted_option\" in the Options proto."; + + const Reflection* reflection = options->GetReflection(); + + LocationRecorder location( + options_location, uninterpreted_option_field->number(), + reflection->FieldSize(*options, uninterpreted_option_field)); + + if (style == OPTION_STATEMENT) { + DO(Consume("option")); + } + + UninterpretedOption* uninterpreted_option = down_cast( + options->GetReflection()->AddMessage(options, + uninterpreted_option_field)); + + // Parse dot-separated name. + { + LocationRecorder name_location(location, + UninterpretedOption::kNameFieldNumber); + name_location.RecordLegacyLocation( + uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME); + + { + LocationRecorder part_location(name_location, + uninterpreted_option->name_size()); + DO(ParseOptionNamePart(uninterpreted_option, part_location)); + } + + while (LookingAt(".")) { + DO(Consume(".")); + LocationRecorder part_location(name_location, + uninterpreted_option->name_size()); + DO(ParseOptionNamePart(uninterpreted_option, part_location)); + } + } + + DO(Consume("=")); + + { + LocationRecorder value_location(location); + value_location.RecordLegacyLocation( + uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE); + + // All values are a single token, except for negative numbers, which consist + // of a single '-' symbol, followed by a positive number. + bool is_negative = TryConsume("-"); + + switch (input_->current().type) { + case io::Tokenizer::TYPE_START: + GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read."; + return false; + + case io::Tokenizer::TYPE_END: + AddError("Unexpected end of stream while parsing option value."); + return false; + + case io::Tokenizer::TYPE_IDENTIFIER: { + value_location.AddPath( + UninterpretedOption::kIdentifierValueFieldNumber); + if (is_negative) { + AddError("Invalid '-' symbol before identifier."); + return false; + } + string value; + DO(ConsumeIdentifier(&value, "Expected identifier.")); + uninterpreted_option->set_identifier_value(value); + break; + } + + case io::Tokenizer::TYPE_INTEGER: { + uint64 value; + uint64 max_value = + is_negative ? static_cast(kint64max) + 1 : kuint64max; + DO(ConsumeInteger64(max_value, &value, "Expected integer.")); + if (is_negative) { + value_location.AddPath( + UninterpretedOption::kNegativeIntValueFieldNumber); + uninterpreted_option->set_negative_int_value( + -static_cast(value)); + } else { + value_location.AddPath( + UninterpretedOption::kPositiveIntValueFieldNumber); + uninterpreted_option->set_positive_int_value(value); + } + break; + } + + case io::Tokenizer::TYPE_FLOAT: { + value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber); + double value; + DO(ConsumeNumber(&value, "Expected number.")); + uninterpreted_option->set_double_value(is_negative ? -value : value); + break; + } + + case io::Tokenizer::TYPE_STRING: { + value_location.AddPath(UninterpretedOption::kStringValueFieldNumber); + if (is_negative) { + AddError("Invalid '-' symbol before string."); + return false; + } + string value; + DO(ConsumeString(&value, "Expected string.")); + uninterpreted_option->set_string_value(value); + break; + } + + case io::Tokenizer::TYPE_SYMBOL: + if (LookingAt("{")) { + value_location.AddPath( + UninterpretedOption::kAggregateValueFieldNumber); + DO(ParseUninterpretedBlock( + uninterpreted_option->mutable_aggregate_value())); + } else { + AddError("Expected option value."); + return false; + } + break; + } + } + + if (style == OPTION_STATEMENT) { + DO(ConsumeEndOfDeclaration(";", &location)); + } + + return true; +} + +bool Parser::ParseExtensions(DescriptorProto* message, + const LocationRecorder& extensions_location) { + // Parse the declaration. + DO(Consume("extensions")); + + do { + // Note that kExtensionRangeFieldNumber was already pushed by the parent. + LocationRecorder location(extensions_location, + message->extension_range_size()); + + DescriptorProto::ExtensionRange* range = message->add_extension_range(); + location.RecordLegacyLocation( + range, DescriptorPool::ErrorCollector::NUMBER); + + int start, end; + io::Tokenizer::Token start_token; + + { + LocationRecorder start_location( + location, DescriptorProto::ExtensionRange::kStartFieldNumber); + start_token = input_->current(); + DO(ConsumeInteger(&start, "Expected field number range.")); + } + + if (TryConsume("to")) { + LocationRecorder end_location( + location, DescriptorProto::ExtensionRange::kEndFieldNumber); + if (TryConsume("max")) { + // Set to the sentinel value - 1 since we increment the value below. + // The actual value of the end of the range should be set with + // AdjustExtensionRangesWithMaxEndNumber. + end = kMaxExtensionRangeSentinel - 1; + } else { + DO(ConsumeInteger(&end, "Expected integer.")); + } + } else { + LocationRecorder end_location( + location, DescriptorProto::ExtensionRange::kEndFieldNumber); + end_location.StartAt(start_token); + end_location.EndAt(start_token); + end = start; + } + + // Users like to specify inclusive ranges, but in code we like the end + // number to be exclusive. + ++end; + + range->set_start(start); + range->set_end(end); + } while (TryConsume(",")); + + DO(ConsumeEndOfDeclaration(";", &extensions_location)); + return true; +} + +bool Parser::ParseExtend(RepeatedPtrField* extensions, + RepeatedPtrField* messages, + const LocationRecorder& parent_location, + int location_field_number_for_nested_type, + const LocationRecorder& extend_location) { + DO(Consume("extend")); + + // Parse the extendee type. + io::Tokenizer::Token extendee_start = input_->current(); + string extendee; + DO(ParseUserDefinedType(&extendee)); + io::Tokenizer::Token extendee_end = input_->previous(); + + // Parse the block. + DO(ConsumeEndOfDeclaration("{", &extend_location)); + + bool is_first = true; + + do { + if (AtEnd()) { + AddError("Reached end of input in extend definition (missing '}')."); + return false; + } + + // Note that kExtensionFieldNumber was already pushed by the parent. + LocationRecorder location(extend_location, extensions->size()); + + FieldDescriptorProto* field = extensions->Add(); + + { + LocationRecorder extendee_location( + location, FieldDescriptorProto::kExtendeeFieldNumber); + extendee_location.StartAt(extendee_start); + extendee_location.EndAt(extendee_end); + + if (is_first) { + extendee_location.RecordLegacyLocation( + field, DescriptorPool::ErrorCollector::EXTENDEE); + is_first = false; + } + } + + field->set_extendee(extendee); + + if (!ParseMessageField(field, messages, parent_location, + location_field_number_for_nested_type, + location)) { + // This statement failed to parse. Skip it, but keep looping to parse + // other statements. + SkipStatement(); + } + } while (!TryConsumeEndOfDeclaration("}", NULL)); + + return true; +} + +// ------------------------------------------------------------------- +// Enums + +bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location) { + DO(Consume("enum")); + + { + LocationRecorder location(enum_location, + EnumDescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation( + enum_type, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name.")); + } + + DO(ParseEnumBlock(enum_type, enum_location)); + return true; +} + +bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location) { + DO(ConsumeEndOfDeclaration("{", &enum_location)); + + while (!TryConsumeEndOfDeclaration("}", NULL)) { + if (AtEnd()) { + AddError("Reached end of input in enum definition (missing '}')."); + return false; + } + + if (!ParseEnumStatement(enum_type, enum_location)) { + // This statement failed to parse. Skip it, but keep looping to parse + // other statements. + SkipStatement(); + } + } + + return true; +} + +bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location) { + if (TryConsumeEndOfDeclaration(";", NULL)) { + // empty statement; ignore + return true; + } else if (LookingAt("option")) { + LocationRecorder location(enum_location, + EnumDescriptorProto::kOptionsFieldNumber); + return ParseOption(enum_type->mutable_options(), location, + OPTION_STATEMENT); + } else { + LocationRecorder location(enum_location, + EnumDescriptorProto::kValueFieldNumber, enum_type->value_size()); + return ParseEnumConstant(enum_type->add_value(), location); + } +} + +bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value, + const LocationRecorder& enum_value_location) { + // Parse name. + { + LocationRecorder location(enum_value_location, + EnumValueDescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation( + enum_value, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(enum_value->mutable_name(), + "Expected enum constant name.")); + } + + DO(Consume("=", "Missing numeric value for enum constant.")); + + // Parse value. + { + LocationRecorder location( + enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber); + location.RecordLegacyLocation( + enum_value, DescriptorPool::ErrorCollector::NUMBER); + + int number; + DO(ConsumeSignedInteger(&number, "Expected integer.")); + enum_value->set_number(number); + } + + DO(ParseEnumConstantOptions(enum_value, enum_value_location)); + + DO(ConsumeEndOfDeclaration(";", &enum_value_location)); + + return true; +} + +bool Parser::ParseEnumConstantOptions( + EnumValueDescriptorProto* value, + const LocationRecorder& enum_value_location) { + if (!LookingAt("[")) return true; + + LocationRecorder location( + enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber); + + DO(Consume("[")); + + do { + DO(ParseOption(value->mutable_options(), location, OPTION_ASSIGNMENT)); + } while (TryConsume(",")); + + DO(Consume("]")); + return true; +} + +// ------------------------------------------------------------------- +// Services + +bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service, + const LocationRecorder& service_location) { + DO(Consume("service")); + + { + LocationRecorder location(service_location, + ServiceDescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation( + service, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(service->mutable_name(), "Expected service name.")); + } + + DO(ParseServiceBlock(service, service_location)); + return true; +} + +bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, + const LocationRecorder& service_location) { + DO(ConsumeEndOfDeclaration("{", &service_location)); + + while (!TryConsumeEndOfDeclaration("}", NULL)) { + if (AtEnd()) { + AddError("Reached end of input in service definition (missing '}')."); + return false; + } + + if (!ParseServiceStatement(service, service_location)) { + // This statement failed to parse. Skip it, but keep looping to parse + // other statements. + SkipStatement(); + } + } + + return true; +} + +bool Parser::ParseServiceStatement(ServiceDescriptorProto* service, + const LocationRecorder& service_location) { + if (TryConsumeEndOfDeclaration(";", NULL)) { + // empty statement; ignore + return true; + } else if (LookingAt("option")) { + LocationRecorder location( + service_location, ServiceDescriptorProto::kOptionsFieldNumber); + return ParseOption(service->mutable_options(), location, OPTION_STATEMENT); + } else { + LocationRecorder location(service_location, + ServiceDescriptorProto::kMethodFieldNumber, service->method_size()); + return ParseServiceMethod(service->add_method(), location); + } +} + +bool Parser::ParseServiceMethod(MethodDescriptorProto* method, + const LocationRecorder& method_location) { + DO(Consume("rpc")); + + { + LocationRecorder location(method_location, + MethodDescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation( + method, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(method->mutable_name(), "Expected method name.")); + } + + // Parse input type. + DO(Consume("(")); + { + LocationRecorder location(method_location, + MethodDescriptorProto::kInputTypeFieldNumber); + location.RecordLegacyLocation( + method, DescriptorPool::ErrorCollector::INPUT_TYPE); + DO(ParseUserDefinedType(method->mutable_input_type())); + } + DO(Consume(")")); + + // Parse output type. + DO(Consume("returns")); + DO(Consume("(")); + { + LocationRecorder location(method_location, + MethodDescriptorProto::kOutputTypeFieldNumber); + location.RecordLegacyLocation( + method, DescriptorPool::ErrorCollector::OUTPUT_TYPE); + DO(ParseUserDefinedType(method->mutable_output_type())); + } + DO(Consume(")")); + + if (LookingAt("{")) { + // Options! + DO(ParseOptions(method_location, + MethodDescriptorProto::kOptionsFieldNumber, + method->mutable_options())); + } else { + DO(ConsumeEndOfDeclaration(";", &method_location)); + } + + return true; +} + + +bool Parser::ParseOptions(const LocationRecorder& parent_location, + const int optionsFieldNumber, + Message* mutable_options) { + // Options! + ConsumeEndOfDeclaration("{", &parent_location); + while (!TryConsumeEndOfDeclaration("}", NULL)) { + if (AtEnd()) { + AddError("Reached end of input in method options (missing '}')."); + return false; + } + + if (TryConsumeEndOfDeclaration(";", NULL)) { + // empty statement; ignore + } else { + LocationRecorder location(parent_location, + optionsFieldNumber); + if (!ParseOption(mutable_options, location, OPTION_STATEMENT)) { + // This statement failed to parse. Skip it, but keep looping to + // parse other statements. + SkipStatement(); + } + } + } + + return true; +} + +// ------------------------------------------------------------------- + +bool Parser::ParseLabel(FieldDescriptorProto::Label* label) { + if (TryConsume("optional")) { + *label = FieldDescriptorProto::LABEL_OPTIONAL; + return true; + } else if (TryConsume("repeated")) { + *label = FieldDescriptorProto::LABEL_REPEATED; + return true; + } else if (TryConsume("required")) { + *label = FieldDescriptorProto::LABEL_REQUIRED; + return true; + } else { + AddError("Expected \"required\", \"optional\", or \"repeated\"."); + // We can actually reasonably recover here by just assuming the user + // forgot the label altogether. + *label = FieldDescriptorProto::LABEL_OPTIONAL; + return true; + } +} + +bool Parser::ParseType(FieldDescriptorProto::Type* type, + string* type_name) { + TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text); + if (iter != kTypeNames.end()) { + *type = iter->second; + input_->Next(); + } else { + DO(ParseUserDefinedType(type_name)); + } + return true; +} + +bool Parser::ParseUserDefinedType(string* type_name) { + type_name->clear(); + + TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text); + if (iter != kTypeNames.end()) { + // Note: The only place enum types are allowed is for field types, but + // if we are parsing a field type then we would not get here because + // primitives are allowed there as well. So this error message doesn't + // need to account for enums. + AddError("Expected message type."); + + // Pretend to accept this type so that we can go on parsing. + *type_name = input_->current().text; + input_->Next(); + return true; + } + + // A leading "." means the name is fully-qualified. + if (TryConsume(".")) type_name->append("."); + + // Consume the first part of the name. + string identifier; + DO(ConsumeIdentifier(&identifier, "Expected type name.")); + type_name->append(identifier); + + // Consume more parts. + while (TryConsume(".")) { + type_name->append("."); + DO(ConsumeIdentifier(&identifier, "Expected identifier.")); + type_name->append(identifier); + } + + return true; +} + +// =================================================================== + +bool Parser::ParsePackage(FileDescriptorProto* file, + const LocationRecorder& root_location) { + if (file->has_package()) { + AddError("Multiple package definitions."); + // Don't append the new package to the old one. Just replace it. Not + // that it really matters since this is an error anyway. + file->clear_package(); + } + + DO(Consume("package")); + + { + LocationRecorder location(root_location, + FileDescriptorProto::kPackageFieldNumber); + location.RecordLegacyLocation(file, DescriptorPool::ErrorCollector::NAME); + + while (true) { + string identifier; + DO(ConsumeIdentifier(&identifier, "Expected identifier.")); + file->mutable_package()->append(identifier); + if (!TryConsume(".")) break; + file->mutable_package()->append("."); + } + + location.EndAt(input_->previous()); + + DO(ConsumeEndOfDeclaration(";", &location)); + } + + return true; +} + +bool Parser::ParseImport(RepeatedPtrField* dependency, + RepeatedField* public_dependency, + RepeatedField* weak_dependency, + const LocationRecorder& root_location) { + DO(Consume("import")); + if (LookingAt("public")) { + LocationRecorder location( + root_location, FileDescriptorProto::kPublicDependencyFieldNumber, + public_dependency->size()); + DO(Consume("public")); + *public_dependency->Add() = dependency->size(); + } else if (LookingAt("weak")) { + LocationRecorder location( + root_location, FileDescriptorProto::kWeakDependencyFieldNumber, + weak_dependency->size()); + DO(Consume("weak")); + *weak_dependency->Add() = dependency->size(); + } + { + LocationRecorder location(root_location, + FileDescriptorProto::kDependencyFieldNumber, + dependency->size()); + DO(ConsumeString(dependency->Add(), + "Expected a string naming the file to import.")); + + location.EndAt(input_->previous()); + + DO(ConsumeEndOfDeclaration(";", &location)); + } + return true; +} + +// =================================================================== + +SourceLocationTable::SourceLocationTable() {} +SourceLocationTable::~SourceLocationTable() {} + +bool SourceLocationTable::Find( + const Message* descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + int* line, int* column) const { + const pair* result = + FindOrNull(location_map_, make_pair(descriptor, location)); + if (result == NULL) { + *line = -1; + *column = 0; + return false; + } else { + *line = result->first; + *column = result->second; + return true; + } +} + +void SourceLocationTable::Add( + const Message* descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + int line, int column) { + location_map_[make_pair(descriptor, location)] = make_pair(line, column); +} + +void SourceLocationTable::Clear() { + location_map_.clear(); +} + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser.h new file mode 100644 index 0000000..cfd3649 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser.h @@ -0,0 +1,477 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Implements parsing of .proto files to FileDescriptorProtos. + +#ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__ +#define GOOGLE_PROTOBUF_COMPILER_PARSER_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { class Message; } + +namespace protobuf { +namespace compiler { + +// Defined in this file. +class Parser; +class SourceLocationTable; + +// Implements parsing of protocol definitions (such as .proto files). +// +// Note that most users will be more interested in the Importer class. +// Parser is a lower-level class which simply converts a single .proto file +// to a FileDescriptorProto. It does not resolve import directives or perform +// many other kinds of validation needed to construct a complete +// FileDescriptor. +class LIBPROTOBUF_EXPORT Parser { + public: + Parser(); + ~Parser(); + + // Parse the entire input and construct a FileDescriptorProto representing + // it. Returns true if no errors occurred, false otherwise. + bool Parse(io::Tokenizer* input, FileDescriptorProto* file); + + // Optional fetaures: + + // DEPRECATED: New code should use the SourceCodeInfo embedded in the + // FileDescriptorProto. + // + // Requests that locations of certain definitions be recorded to the given + // SourceLocationTable while parsing. This can be used to look up exact line + // and column numbers for errors reported by DescriptorPool during validation. + // Set to NULL (the default) to discard source location information. + void RecordSourceLocationsTo(SourceLocationTable* location_table) { + source_location_table_ = location_table; + } + + // Requests that errors be recorded to the given ErrorCollector while + // parsing. Set to NULL (the default) to discard error messages. + void RecordErrorsTo(io::ErrorCollector* error_collector) { + error_collector_ = error_collector; + } + + // Returns the identifier used in the "syntax = " declaration, if one was + // seen during the last call to Parse(), or the empty string otherwise. + const string& GetSyntaxIdentifier() { return syntax_identifier_; } + + // If set true, input files will be required to begin with a syntax + // identifier. Otherwise, files may omit this. If a syntax identifier + // is provided, it must be 'syntax = "proto2";' and must appear at the + // top of this file regardless of whether or not it was required. + void SetRequireSyntaxIdentifier(bool value) { + require_syntax_identifier_ = value; + } + + // Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop + // parsing as soon as it has seen the syntax identifier, or lack thereof. + // This is useful for quickly identifying the syntax of the file without + // parsing the whole thing. If this is enabled, no error will be recorded + // if the syntax identifier is something other than "proto2" (since + // presumably the caller intends to deal with that), but other kinds of + // errors (e.g. parse errors) will still be reported. When this is enabled, + // you may pass a NULL FileDescriptorProto to Parse(). + void SetStopAfterSyntaxIdentifier(bool value) { + stop_after_syntax_identifier_ = value; + } + + private: + class LocationRecorder; + + // ================================================================= + // Error recovery helpers + + // Consume the rest of the current statement. This consumes tokens + // until it sees one of: + // ';' Consumes the token and returns. + // '{' Consumes the brace then calls SkipRestOfBlock(). + // '}' Returns without consuming. + // EOF Returns (can't consume). + // The Parser often calls SkipStatement() after encountering a syntax + // error. This allows it to go on parsing the following lines, allowing + // it to report more than just one error in the file. + void SkipStatement(); + + // Consume the rest of the current block, including nested blocks, + // ending after the closing '}' is encountered and consumed, or at EOF. + void SkipRestOfBlock(); + + // ----------------------------------------------------------------- + // Single-token consuming helpers + // + // These make parsing code more readable. + + // True if the current token is TYPE_END. + inline bool AtEnd(); + + // True if the next token matches the given text. + inline bool LookingAt(const char* text); + // True if the next token is of the given type. + inline bool LookingAtType(io::Tokenizer::TokenType token_type); + + // If the next token exactly matches the text given, consume it and return + // true. Otherwise, return false without logging an error. + bool TryConsume(const char* text); + + // These attempt to read some kind of token from the input. If successful, + // they return true. Otherwise they return false and add the given error + // to the error list. + + // Consume a token with the exact text given. + bool Consume(const char* text, const char* error); + // Same as above, but automatically generates the error "Expected \"text\".", + // where "text" is the expected token text. + bool Consume(const char* text); + // Consume a token of type IDENTIFIER and store its text in "output". + bool ConsumeIdentifier(string* output, const char* error); + // Consume an integer and store its value in "output". + bool ConsumeInteger(int* output, const char* error); + // Consume a signed integer and store its value in "output". + bool ConsumeSignedInteger(int* output, const char* error); + // Consume a 64-bit integer and store its value in "output". If the value + // is greater than max_value, an error will be reported. + bool ConsumeInteger64(uint64 max_value, uint64* output, const char* error); + // Consume a number and store its value in "output". This will accept + // tokens of either INTEGER or FLOAT type. + bool ConsumeNumber(double* output, const char* error); + // Consume a string literal and store its (unescaped) value in "output". + bool ConsumeString(string* output, const char* error); + + // Consume a token representing the end of the statement. Comments between + // this token and the next will be harvested for documentation. The given + // LocationRecorder should refer to the declaration that was just parsed; + // it will be populated with these comments. + // + // TODO(kenton): The LocationRecorder is const because historically locations + // have been passed around by const reference, for no particularly good + // reason. We should probably go through and change them all to mutable + // pointer to make this more intuitive. + bool TryConsumeEndOfDeclaration(const char* text, + const LocationRecorder* location); + bool ConsumeEndOfDeclaration(const char* text, + const LocationRecorder* location); + + // ----------------------------------------------------------------- + // Error logging helpers + + // Invokes error_collector_->AddError(), if error_collector_ is not NULL. + void AddError(int line, int column, const string& error); + + // Invokes error_collector_->AddError() with the line and column number + // of the current token. + void AddError(const string& error); + + // Records a location in the SourceCodeInfo.location table (see + // descriptor.proto). We use RAII to ensure that the start and end locations + // are recorded -- the constructor records the start location and the + // destructor records the end location. Since the parser is + // recursive-descent, this works out beautifully. + class LIBPROTOBUF_EXPORT LocationRecorder { + public: + // Construct the file's "root" location. + LocationRecorder(Parser* parser); + + // Construct a location that represents a declaration nested within the + // given parent. E.g. a field's location is nested within the location + // for a message type. The parent's path will be copied, so you should + // call AddPath() only to add the path components leading from the parent + // to the child (as opposed to leading from the root to the child). + LocationRecorder(const LocationRecorder& parent); + + // Convenience constructors that call AddPath() one or two times. + LocationRecorder(const LocationRecorder& parent, int path1); + LocationRecorder(const LocationRecorder& parent, int path1, int path2); + + ~LocationRecorder(); + + // Add a path component. See SourceCodeInfo.Location.path in + // descriptor.proto. + void AddPath(int path_component); + + // By default the location is considered to start at the current token at + // the time the LocationRecorder is created. StartAt() sets the start + // location to the given token instead. + void StartAt(const io::Tokenizer::Token& token); + + // By default the location is considered to end at the previous token at + // the time the LocationRecorder is destroyed. EndAt() sets the end + // location to the given token instead. + void EndAt(const io::Tokenizer::Token& token); + + // Records the start point of this location to the SourceLocationTable that + // was passed to RecordSourceLocationsTo(), if any. SourceLocationTable + // is an older way of keeping track of source locations which is still + // used in some places. + void RecordLegacyLocation(const Message* descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location); + + // Attaches leading and trailing comments to the location. The two strings + // will be swapped into place, so after this is called *leading and + // *trailing will be empty. + // + // TODO(kenton): See comment on TryConsumeEndOfDeclaration(), above, for + // why this is const. + void AttachComments(string* leading, string* trailing) const; + + private: + Parser* parser_; + SourceCodeInfo::Location* location_; + + void Init(const LocationRecorder& parent); + }; + + // ================================================================= + // Parsers for various language constructs + + // Parses the "syntax = \"proto2\";" line at the top of the file. Returns + // false if it failed to parse or if the syntax identifier was not + // recognized. + bool ParseSyntaxIdentifier(); + + // These methods parse various individual bits of code. They return + // false if they completely fail to parse the construct. In this case, + // it is probably necessary to skip the rest of the statement to recover. + // However, if these methods return true, it does NOT mean that there + // were no errors; only that there were no *syntax* errors. For instance, + // if a service method is defined using proper syntax but uses a primitive + // type as its input or output, ParseMethodField() still returns true + // and only reports the error by calling AddError(). In practice, this + // makes logic much simpler for the caller. + + // Parse a top-level message, enum, service, etc. + bool ParseTopLevelStatement(FileDescriptorProto* file, + const LocationRecorder& root_location); + + // Parse various language high-level language construrcts. + bool ParseMessageDefinition(DescriptorProto* message, + const LocationRecorder& message_location); + bool ParseEnumDefinition(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location); + bool ParseServiceDefinition(ServiceDescriptorProto* service, + const LocationRecorder& service_location); + bool ParsePackage(FileDescriptorProto* file, + const LocationRecorder& root_location); + bool ParseImport(RepeatedPtrField* dependency, + RepeatedField* public_dependency, + RepeatedField* weak_dependency, + const LocationRecorder& root_location); + bool ParseOption(Message* options, + const LocationRecorder& options_location); + + // These methods parse the contents of a message, enum, or service type and + // add them to the given object. They consume the entire block including + // the beginning and ending brace. + bool ParseMessageBlock(DescriptorProto* message, + const LocationRecorder& message_location); + bool ParseEnumBlock(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location); + bool ParseServiceBlock(ServiceDescriptorProto* service, + const LocationRecorder& service_location); + + // Parse one statement within a message, enum, or service block, inclunding + // final semicolon. + bool ParseMessageStatement(DescriptorProto* message, + const LocationRecorder& message_location); + bool ParseEnumStatement(EnumDescriptorProto* message, + const LocationRecorder& enum_location); + bool ParseServiceStatement(ServiceDescriptorProto* message, + const LocationRecorder& service_location); + + // Parse a field of a message. If the field is a group, its type will be + // added to "messages". + // + // parent_location and location_field_number_for_nested_type are needed when + // parsing groups -- we need to generate a nested message type within the + // parent and record its location accordingly. Since the parent could be + // either a FileDescriptorProto or a DescriptorProto, we must pass in the + // correct field number to use. + bool ParseMessageField(FieldDescriptorProto* field, + RepeatedPtrField* messages, + const LocationRecorder& parent_location, + int location_field_number_for_nested_type, + const LocationRecorder& field_location); + + // Parse an "extensions" declaration. + bool ParseExtensions(DescriptorProto* message, + const LocationRecorder& extensions_location); + + // Parse an "extend" declaration. (See also comments for + // ParseMessageField().) + bool ParseExtend(RepeatedPtrField* extensions, + RepeatedPtrField* messages, + const LocationRecorder& parent_location, + int location_field_number_for_nested_type, + const LocationRecorder& extend_location); + + // Parse a single enum value within an enum block. + bool ParseEnumConstant(EnumValueDescriptorProto* enum_value, + const LocationRecorder& enum_value_location); + + // Parse enum constant options, i.e. the list in square brackets at the end + // of the enum constant value definition. + bool ParseEnumConstantOptions(EnumValueDescriptorProto* value, + const LocationRecorder& enum_value_location); + + // Parse a single method within a service definition. + bool ParseServiceMethod(MethodDescriptorProto* method, + const LocationRecorder& method_location); + + + // Parse options of a single method or stream. + bool ParseOptions(const LocationRecorder& parent_location, + const int optionsFieldNumber, + Message* mutable_options); + + // Parse "required", "optional", or "repeated" and fill in "label" + // with the value. + bool ParseLabel(FieldDescriptorProto::Label* label); + + // Parse a type name and fill in "type" (if it is a primitive) or + // "type_name" (if it is not) with the type parsed. + bool ParseType(FieldDescriptorProto::Type* type, + string* type_name); + // Parse a user-defined type and fill in "type_name" with the name. + // If a primitive type is named, it is treated as an error. + bool ParseUserDefinedType(string* type_name); + + // Parses field options, i.e. the stuff in square brackets at the end + // of a field definition. Also parses default value. + bool ParseFieldOptions(FieldDescriptorProto* field, + const LocationRecorder& field_location); + + // Parse the "default" option. This needs special handling because its + // type is the field's type. + bool ParseDefaultAssignment(FieldDescriptorProto* field, + const LocationRecorder& field_location); + + enum OptionStyle { + OPTION_ASSIGNMENT, // just "name = value" + OPTION_STATEMENT // "option name = value;" + }; + + // Parse a single option name/value pair, e.g. "ctype = CORD". The name + // identifies a field of the given Message, and the value of that field + // is set to the parsed value. + bool ParseOption(Message* options, + const LocationRecorder& options_location, + OptionStyle style); + + // Parses a single part of a multipart option name. A multipart name consists + // of names separated by dots. Each name is either an identifier or a series + // of identifiers separated by dots and enclosed in parentheses. E.g., + // "foo.(bar.baz).qux". + bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option, + const LocationRecorder& part_location); + + // Parses a string surrounded by balanced braces. Strips off the outer + // braces and stores the enclosed string in *value. + // E.g., + // { foo } *value gets 'foo' + // { foo { bar: box } } *value gets 'foo { bar: box }' + // {} *value gets '' + // + // REQUIRES: LookingAt("{") + // When finished successfully, we are looking at the first token past + // the ending brace. + bool ParseUninterpretedBlock(string* value); + + // ================================================================= + + io::Tokenizer* input_; + io::ErrorCollector* error_collector_; + SourceCodeInfo* source_code_info_; + SourceLocationTable* source_location_table_; // legacy + bool had_errors_; + bool require_syntax_identifier_; + bool stop_after_syntax_identifier_; + string syntax_identifier_; + + // Leading doc comments for the next declaration. These are not complete + // yet; use ConsumeEndOfDeclaration() to get the complete comments. + string upcoming_doc_comments_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser); +}; + +// A table mapping (descriptor, ErrorLocation) pairs -- as reported by +// DescriptorPool when validating descriptors -- to line and column numbers +// within the original source code. +// +// This is semi-obsolete: FileDescriptorProto.source_code_info now contains +// far more complete information about source locations. However, as of this +// writing you still need to use SourceLocationTable when integrating with +// DescriptorPool. +class LIBPROTOBUF_EXPORT SourceLocationTable { + public: + SourceLocationTable(); + ~SourceLocationTable(); + + // Finds the precise location of the given error and fills in *line and + // *column with the line and column numbers. If not found, sets *line to + // -1 and *column to 0 (since line = -1 is used to mean "error has no exact + // location" in the ErrorCollector interface). Returns true if found, false + // otherwise. + bool Find(const Message* descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + int* line, int* column) const; + + // Adds a location to the table. + void Add(const Message* descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + int line, int column); + + // Clears the contents of the table. + void Clear(); + + private: + typedef map< + pair, + pair > LocationMap; + LocationMap location_map_; +}; + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_PARSER_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser_unittest.cc new file mode 100644 index 0000000..c61ac60 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/parser_unittest.cc @@ -0,0 +1,2374 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { + +namespace { + +class MockErrorCollector : public io::ErrorCollector { + public: + MockErrorCollector() {} + ~MockErrorCollector() {} + + string text_; + + // implements ErrorCollector --------------------------------------- + void AddError(int line, int column, const string& message) { + strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", + line, column, message); + } +}; + +class MockValidationErrorCollector : public DescriptorPool::ErrorCollector { + public: + MockValidationErrorCollector(const SourceLocationTable& source_locations, + io::ErrorCollector* wrapped_collector) + : source_locations_(source_locations), + wrapped_collector_(wrapped_collector) {} + ~MockValidationErrorCollector() {} + + // implements ErrorCollector --------------------------------------- + void AddError(const string& filename, + const string& element_name, + const Message* descriptor, + ErrorLocation location, + const string& message) { + int line, column; + source_locations_.Find(descriptor, location, &line, &column); + wrapped_collector_->AddError(line, column, message); + } + + private: + const SourceLocationTable& source_locations_; + io::ErrorCollector* wrapped_collector_; +}; + +class ParserTest : public testing::Test { + protected: + ParserTest() + : require_syntax_identifier_(false) {} + + // Set up the parser to parse the given text. + void SetupParser(const char* text) { + raw_input_.reset(new io::ArrayInputStream(text, strlen(text))); + input_.reset(new io::Tokenizer(raw_input_.get(), &error_collector_)); + parser_.reset(new Parser()); + parser_->RecordErrorsTo(&error_collector_); + parser_->SetRequireSyntaxIdentifier(require_syntax_identifier_); + } + + // Parse the input and expect that the resulting FileDescriptorProto matches + // the given output. The output is a FileDescriptorProto in protocol buffer + // text format. + void ExpectParsesTo(const char* input, const char* output) { + SetupParser(input); + FileDescriptorProto actual, expected; + + parser_->Parse(input_.get(), &actual); + EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); + ASSERT_EQ("", error_collector_.text_); + + // We don't cover SourceCodeInfo in these tests. + actual.clear_source_code_info(); + + // Parse the ASCII representation in order to canonicalize it. We could + // just compare directly to actual.DebugString(), but that would require + // that the caller precisely match the formatting that DebugString() + // produces. + ASSERT_TRUE(TextFormat::ParseFromString(output, &expected)); + + // Compare by comparing debug strings. + // TODO(kenton): Use differencer, once it is available. + EXPECT_EQ(expected.DebugString(), actual.DebugString()); + } + + // Parse the text and expect that the given errors are reported. + void ExpectHasErrors(const char* text, const char* expected_errors) { + ExpectHasEarlyExitErrors(text, expected_errors); + EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); + } + + // Same as above but does not expect that the parser parses the complete + // input. + void ExpectHasEarlyExitErrors(const char* text, const char* expected_errors) { + SetupParser(text); + FileDescriptorProto file; + parser_->Parse(input_.get(), &file); + EXPECT_EQ(expected_errors, error_collector_.text_); + } + + // Parse the text as a file and validate it (with a DescriptorPool), and + // expect that the validation step reports the given errors. + void ExpectHasValidationErrors(const char* text, + const char* expected_errors) { + SetupParser(text); + SourceLocationTable source_locations; + parser_->RecordSourceLocationsTo(&source_locations); + + FileDescriptorProto file; + file.set_name("foo.proto"); + parser_->Parse(input_.get(), &file); + EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); + ASSERT_EQ("", error_collector_.text_); + + MockValidationErrorCollector validation_error_collector( + source_locations, &error_collector_); + EXPECT_TRUE(pool_.BuildFileCollectingErrors( + file, &validation_error_collector) == NULL); + EXPECT_EQ(expected_errors, error_collector_.text_); + } + + MockErrorCollector error_collector_; + DescriptorPool pool_; + + scoped_ptr raw_input_; + scoped_ptr input_; + scoped_ptr parser_; + bool require_syntax_identifier_; +}; + +// =================================================================== + +TEST_F(ParserTest, StopAfterSyntaxIdentifier) { + SetupParser( + "// blah\n" + "syntax = \"foobar\";\n" + "this line will not be parsed\n"); + parser_->SetStopAfterSyntaxIdentifier(true); + EXPECT_TRUE(parser_->Parse(input_.get(), NULL)); + EXPECT_EQ("", error_collector_.text_); + EXPECT_EQ("foobar", parser_->GetSyntaxIdentifier()); +} + +TEST_F(ParserTest, StopAfterOmittedSyntaxIdentifier) { + SetupParser( + "// blah\n" + "this line will not be parsed\n"); + parser_->SetStopAfterSyntaxIdentifier(true); + EXPECT_TRUE(parser_->Parse(input_.get(), NULL)); + EXPECT_EQ("", error_collector_.text_); + EXPECT_EQ("", parser_->GetSyntaxIdentifier()); +} + +TEST_F(ParserTest, StopAfterSyntaxIdentifierWithErrors) { + SetupParser( + "// blah\n" + "syntax = error;\n"); + parser_->SetStopAfterSyntaxIdentifier(true); + EXPECT_FALSE(parser_->Parse(input_.get(), NULL)); + EXPECT_EQ("1:9: Expected syntax identifier.\n", error_collector_.text_); +} + +// =================================================================== + +typedef ParserTest ParseMessageTest; + +TEST_F(ParseMessageTest, SimpleMessage) { + ExpectParsesTo( + "message TestMessage {\n" + " required int32 foo = 1;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" + "}"); +} + +TEST_F(ParseMessageTest, ImplicitSyntaxIdentifier) { + require_syntax_identifier_ = false; + ExpectParsesTo( + "message TestMessage {\n" + " required int32 foo = 1;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" + "}"); + EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier()); +} + +TEST_F(ParseMessageTest, ExplicitSyntaxIdentifier) { + ExpectParsesTo( + "syntax = \"proto2\";\n" + "message TestMessage {\n" + " required int32 foo = 1;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" + "}"); + EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier()); +} + +TEST_F(ParseMessageTest, ExplicitRequiredSyntaxIdentifier) { + require_syntax_identifier_ = true; + ExpectParsesTo( + "syntax = \"proto2\";\n" + "message TestMessage {\n" + " required int32 foo = 1;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" + "}"); + EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier()); +} + +TEST_F(ParseMessageTest, SimpleFields) { + ExpectParsesTo( + "message TestMessage {\n" + " required int32 foo = 15;\n" + " optional int32 bar = 34;\n" + " repeated int32 baz = 3;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:15 }" + " field { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:34 }" + " field { name:\"baz\" label:LABEL_REPEATED type:TYPE_INT32 number:3 }" + "}"); +} + +TEST_F(ParseMessageTest, PrimitiveFieldTypes) { + ExpectParsesTo( + "message TestMessage {\n" + " required int32 foo = 1;\n" + " required int64 foo = 1;\n" + " required uint32 foo = 1;\n" + " required uint64 foo = 1;\n" + " required sint32 foo = 1;\n" + " required sint64 foo = 1;\n" + " required fixed32 foo = 1;\n" + " required fixed64 foo = 1;\n" + " required sfixed32 foo = 1;\n" + " required sfixed64 foo = 1;\n" + " required float foo = 1;\n" + " required double foo = 1;\n" + " required string foo = 1;\n" + " required bytes foo = 1;\n" + " required bool foo = 1;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT64 number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT32 number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT64 number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT32 number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT64 number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED32 number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED64 number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED32 number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED64 number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FLOAT number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_DOUBLE number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_STRING number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BYTES number:1 }" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BOOL number:1 }" + "}"); +} + +TEST_F(ParseMessageTest, FieldDefaults) { + ExpectParsesTo( + "message TestMessage {\n" + " required int32 foo = 1 [default= 1 ];\n" + " required int32 foo = 1 [default= -2 ];\n" + " required int64 foo = 1 [default= 3 ];\n" + " required int64 foo = 1 [default= -4 ];\n" + " required uint32 foo = 1 [default= 5 ];\n" + " required uint64 foo = 1 [default= 6 ];\n" + " required float foo = 1 [default= 7.5];\n" + " required float foo = 1 [default= -8.5];\n" + " required float foo = 1 [default= 9 ];\n" + " required double foo = 1 [default= 10.5];\n" + " required double foo = 1 [default=-11.5];\n" + " required double foo = 1 [default= 12 ];\n" + " required double foo = 1 [default= inf ];\n" + " required double foo = 1 [default=-inf ];\n" + " required double foo = 1 [default= nan ];\n" + " required string foo = 1 [default='13\\001'];\n" + " required string foo = 1 [default='a' \"b\" \n \"c\"];\n" + " required bytes foo = 1 [default='14\\002'];\n" + " required bytes foo = 1 [default='a' \"b\" \n 'c'];\n" + " required bool foo = 1 [default=true ];\n" + " required Foo foo = 1 [default=FOO ];\n" + + " required int32 foo = 1 [default= 0x7FFFFFFF];\n" + " required int32 foo = 1 [default=-0x80000000];\n" + " required uint32 foo = 1 [default= 0xFFFFFFFF];\n" + " required int64 foo = 1 [default= 0x7FFFFFFFFFFFFFFF];\n" + " required int64 foo = 1 [default=-0x8000000000000000];\n" + " required uint64 foo = 1 [default= 0xFFFFFFFFFFFFFFFF];\n" + " required double foo = 1 [default= 0xabcd];\n" + "}\n", + +#define ETC "name:\"foo\" label:LABEL_REQUIRED number:1" + "message_type {" + " name: \"TestMessage\"" + " field { type:TYPE_INT32 default_value:\"1\" "ETC" }" + " field { type:TYPE_INT32 default_value:\"-2\" "ETC" }" + " field { type:TYPE_INT64 default_value:\"3\" "ETC" }" + " field { type:TYPE_INT64 default_value:\"-4\" "ETC" }" + " field { type:TYPE_UINT32 default_value:\"5\" "ETC" }" + " field { type:TYPE_UINT64 default_value:\"6\" "ETC" }" + " field { type:TYPE_FLOAT default_value:\"7.5\" "ETC" }" + " field { type:TYPE_FLOAT default_value:\"-8.5\" "ETC" }" + " field { type:TYPE_FLOAT default_value:\"9\" "ETC" }" + " field { type:TYPE_DOUBLE default_value:\"10.5\" "ETC" }" + " field { type:TYPE_DOUBLE default_value:\"-11.5\" "ETC" }" + " field { type:TYPE_DOUBLE default_value:\"12\" "ETC" }" + " field { type:TYPE_DOUBLE default_value:\"inf\" "ETC" }" + " field { type:TYPE_DOUBLE default_value:\"-inf\" "ETC" }" + " field { type:TYPE_DOUBLE default_value:\"nan\" "ETC" }" + " field { type:TYPE_STRING default_value:\"13\\001\" "ETC" }" + " field { type:TYPE_STRING default_value:\"abc\" "ETC" }" + " field { type:TYPE_BYTES default_value:\"14\\\\002\" "ETC" }" + " field { type:TYPE_BYTES default_value:\"abc\" "ETC" }" + " field { type:TYPE_BOOL default_value:\"true\" "ETC" }" + " field { type_name:\"Foo\" default_value:\"FOO\" "ETC" }" + + " field { type:TYPE_INT32 default_value:\"2147483647\" "ETC" }" + " field { type:TYPE_INT32 default_value:\"-2147483648\" "ETC" }" + " field { type:TYPE_UINT32 default_value:\"4294967295\" "ETC" }" + " field { type:TYPE_INT64 default_value:\"9223372036854775807\" "ETC" }" + " field { type:TYPE_INT64 default_value:\"-9223372036854775808\" "ETC" }" + " field { type:TYPE_UINT64 default_value:\"18446744073709551615\" "ETC" }" + " field { type:TYPE_DOUBLE default_value:\"43981\" "ETC" }" + "}"); +#undef ETC +} + +TEST_F(ParseMessageTest, FieldOptions) { + ExpectParsesTo( + "message TestMessage {\n" + " optional string foo = 1\n" + " [ctype=CORD, (foo)=7, foo.(.bar.baz).qux.quux.(corge)=-33, \n" + " (quux)=\"x\040y\", (baz.qux)=hey];\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " field { name: \"foo\" label: LABEL_OPTIONAL type: TYPE_STRING number: 1" + " options { uninterpreted_option: { name { name_part: \"ctype\" " + " is_extension: false } " + " identifier_value: \"CORD\" }" + " uninterpreted_option: { name { name_part: \"foo\" " + " is_extension: true } " + " positive_int_value: 7 }" + " uninterpreted_option: { name { name_part: \"foo\" " + " is_extension: false } " + " name { name_part: \".bar.baz\"" + " is_extension: true } " + " name { name_part: \"qux\" " + " is_extension: false } " + " name { name_part: \"quux\" " + " is_extension: false } " + " name { name_part: \"corge\" " + " is_extension: true } " + " negative_int_value: -33 }" + " uninterpreted_option: { name { name_part: \"quux\" " + " is_extension: true } " + " string_value: \"x y\" }" + " uninterpreted_option: { name { name_part: \"baz.qux\" " + " is_extension: true } " + " identifier_value: \"hey\" }" + " }" + " }" + "}"); +} + +TEST_F(ParseMessageTest, Group) { + ExpectParsesTo( + "message TestMessage {\n" + " optional group TestGroup = 1 {};\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " nested_type { name: \"TestGroup\" }" + " field { name:\"testgroup\" label:LABEL_OPTIONAL number:1" + " type:TYPE_GROUP type_name: \"TestGroup\" }" + "}"); +} + +TEST_F(ParseMessageTest, NestedMessage) { + ExpectParsesTo( + "message TestMessage {\n" + " message Nested {}\n" + " optional Nested test_nested = 1;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " nested_type { name: \"Nested\" }" + " field { name:\"test_nested\" label:LABEL_OPTIONAL number:1" + " type_name: \"Nested\" }" + "}"); +} + +TEST_F(ParseMessageTest, NestedEnum) { + ExpectParsesTo( + "message TestMessage {\n" + " enum NestedEnum {}\n" + " optional NestedEnum test_enum = 1;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " enum_type { name: \"NestedEnum\" }" + " field { name:\"test_enum\" label:LABEL_OPTIONAL number:1" + " type_name: \"NestedEnum\" }" + "}"); +} + +TEST_F(ParseMessageTest, ExtensionRange) { + ExpectParsesTo( + "message TestMessage {\n" + " extensions 10 to 19;\n" + " extensions 30 to max;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " extension_range { start:10 end:20 }" + " extension_range { start:30 end:536870912 }" + "}"); +} + +TEST_F(ParseMessageTest, CompoundExtensionRange) { + ExpectParsesTo( + "message TestMessage {\n" + " extensions 2, 15, 9 to 11, 100 to max, 3;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " extension_range { start:2 end:3 }" + " extension_range { start:15 end:16 }" + " extension_range { start:9 end:12 }" + " extension_range { start:100 end:536870912 }" + " extension_range { start:3 end:4 }" + "}"); +} + +TEST_F(ParseMessageTest, LargerMaxForMessageSetWireFormatMessages) { + // Messages using the message_set_wire_format option can accept larger + // extension numbers, as the numbers are not encoded as int32 field values + // rather than tags. + ExpectParsesTo( + "message TestMessage {\n" + " extensions 4 to max;\n" + " option message_set_wire_format = true;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " extension_range { start:4 end: 0x7fffffff }" + " options {\n" + " uninterpreted_option { \n" + " name {\n" + " name_part: \"message_set_wire_format\"\n" + " is_extension: false\n" + " }\n" + " identifier_value: \"true\"\n" + " }\n" + " }\n" + "}"); +} + +TEST_F(ParseMessageTest, Extensions) { + ExpectParsesTo( + "extend Extendee1 { optional int32 foo = 12; }\n" + "extend Extendee2 { repeated TestMessage bar = 22; }\n", + + "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12" + " extendee: \"Extendee1\" } " + "extension { name:\"bar\" label:LABEL_REPEATED number:22" + " type_name:\"TestMessage\" extendee: \"Extendee2\" }"); +} + +TEST_F(ParseMessageTest, ExtensionsInMessageScope) { + ExpectParsesTo( + "message TestMessage {\n" + " extend Extendee1 { optional int32 foo = 12; }\n" + " extend Extendee2 { repeated TestMessage bar = 22; }\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12" + " extendee: \"Extendee1\" }" + " extension { name:\"bar\" label:LABEL_REPEATED number:22" + " type_name:\"TestMessage\" extendee: \"Extendee2\" }" + "}"); +} + +TEST_F(ParseMessageTest, MultipleExtensionsOneExtendee) { + ExpectParsesTo( + "extend Extendee1 {\n" + " optional int32 foo = 12;\n" + " repeated TestMessage bar = 22;\n" + "}\n", + + "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12" + " extendee: \"Extendee1\" } " + "extension { name:\"bar\" label:LABEL_REPEATED number:22" + " type_name:\"TestMessage\" extendee: \"Extendee1\" }"); +} + +// =================================================================== + +typedef ParserTest ParseEnumTest; + +TEST_F(ParseEnumTest, SimpleEnum) { + ExpectParsesTo( + "enum TestEnum {\n" + " FOO = 0;\n" + "}\n", + + "enum_type {" + " name: \"TestEnum\"" + " value { name:\"FOO\" number:0 }" + "}"); +} + +TEST_F(ParseEnumTest, Values) { + ExpectParsesTo( + "enum TestEnum {\n" + " FOO = 13;\n" + " BAR = -10;\n" + " BAZ = 500;\n" + " HEX_MAX = 0x7FFFFFFF;\n" + " HEX_MIN = -0x80000000;\n" + " INT_MAX = 2147483647;\n" + " INT_MIN = -2147483648;\n" + "}\n", + + "enum_type {" + " name: \"TestEnum\"" + " value { name:\"FOO\" number:13 }" + " value { name:\"BAR\" number:-10 }" + " value { name:\"BAZ\" number:500 }" + " value { name:\"HEX_MAX\" number:2147483647 }" + " value { name:\"HEX_MIN\" number:-2147483648 }" + " value { name:\"INT_MAX\" number:2147483647 }" + " value { name:\"INT_MIN\" number:-2147483648 }" + "}"); +} + +TEST_F(ParseEnumTest, ValueOptions) { + ExpectParsesTo( + "enum TestEnum {\n" + " FOO = 13;\n" + " BAR = -10 [ (something.text) = 'abc' ];\n" + " BAZ = 500 [ (something.text) = 'def', other = 1 ];\n" + "}\n", + + "enum_type {" + " name: \"TestEnum\"" + " value { name: \"FOO\" number: 13 }" + " value { name: \"BAR\" number: -10 " + " options { " + " uninterpreted_option { " + " name { name_part: \"something.text\" is_extension: true } " + " string_value: \"abc\" " + " } " + " } " + " } " + " value { name: \"BAZ\" number: 500 " + " options { " + " uninterpreted_option { " + " name { name_part: \"something.text\" is_extension: true } " + " string_value: \"def\" " + " } " + " uninterpreted_option { " + " name { name_part: \"other\" is_extension: false } " + " positive_int_value: 1 " + " } " + " } " + " } " + "}"); +} + +// =================================================================== + +typedef ParserTest ParseServiceTest; + +TEST_F(ParseServiceTest, SimpleService) { + ExpectParsesTo( + "service TestService {\n" + " rpc Foo(In) returns (Out);\n" + "}\n", + + "service {" + " name: \"TestService\"" + " method { name:\"Foo\" input_type:\"In\" output_type:\"Out\" }" + "}"); +} + +TEST_F(ParseServiceTest, MethodsAndStreams) { + ExpectParsesTo( + "service TestService {\n" + " rpc Foo(In1) returns (Out1);\n" + " rpc Bar(In2) returns (Out2);\n" + " rpc Baz(In3) returns (Out3);\n" + "}\n", + + "service {" + " name: \"TestService\"" + " method { name:\"Foo\" input_type:\"In1\" output_type:\"Out1\" }" + " method { name:\"Bar\" input_type:\"In2\" output_type:\"Out2\" }" + " method { name:\"Baz\" input_type:\"In3\" output_type:\"Out3\" }" + "}"); +} + +// =================================================================== +// imports and packages + +typedef ParserTest ParseMiscTest; + +TEST_F(ParseMiscTest, ParseImport) { + ExpectParsesTo( + "import \"foo/bar/baz.proto\";\n", + "dependency: \"foo/bar/baz.proto\""); +} + +TEST_F(ParseMiscTest, ParseMultipleImports) { + ExpectParsesTo( + "import \"foo.proto\";\n" + "import \"bar.proto\";\n" + "import \"baz.proto\";\n", + "dependency: \"foo.proto\"" + "dependency: \"bar.proto\"" + "dependency: \"baz.proto\""); +} + +TEST_F(ParseMiscTest, ParsePublicImports) { + ExpectParsesTo( + "import \"foo.proto\";\n" + "import public \"bar.proto\";\n" + "import \"baz.proto\";\n" + "import public \"qux.proto\";\n", + "dependency: \"foo.proto\"" + "dependency: \"bar.proto\"" + "dependency: \"baz.proto\"" + "dependency: \"qux.proto\"" + "public_dependency: 1 " + "public_dependency: 3 "); +} + +TEST_F(ParseMiscTest, ParsePackage) { + ExpectParsesTo( + "package foo.bar.baz;\n", + "package: \"foo.bar.baz\""); +} + +TEST_F(ParseMiscTest, ParsePackageWithSpaces) { + ExpectParsesTo( + "package foo . bar. \n" + " baz;\n", + "package: \"foo.bar.baz\""); +} + +// =================================================================== +// options + +TEST_F(ParseMiscTest, ParseFileOptions) { + ExpectParsesTo( + "option java_package = \"com.google.foo\";\n" + "option optimize_for = CODE_SIZE;", + + "options {" + "uninterpreted_option { name { name_part: \"java_package\" " + " is_extension: false }" + " string_value: \"com.google.foo\"} " + "uninterpreted_option { name { name_part: \"optimize_for\" " + " is_extension: false }" + " identifier_value: \"CODE_SIZE\" } " + "}"); +} + +// =================================================================== +// Error tests +// +// There are a very large number of possible errors that the parser could +// report, so it's infeasible to test every single one of them. Instead, +// we test each unique call to AddError() in parser.h. This does not mean +// we are testing every possible error that Parser can generate because +// each variant of the Consume() helper only counts as one unique call to +// AddError(). + +typedef ParserTest ParseErrorTest; + +TEST_F(ParseErrorTest, MissingSyntaxIdentifier) { + require_syntax_identifier_ = true; + ExpectHasEarlyExitErrors( + "message TestMessage {}", + "0:0: File must begin with 'syntax = \"proto2\";'.\n"); + EXPECT_EQ("", parser_->GetSyntaxIdentifier()); +} + +TEST_F(ParseErrorTest, UnknownSyntaxIdentifier) { + ExpectHasEarlyExitErrors( + "syntax = \"no_such_syntax\";", + "0:9: Unrecognized syntax identifier \"no_such_syntax\". This parser " + "only recognizes \"proto2\".\n"); + EXPECT_EQ("no_such_syntax", parser_->GetSyntaxIdentifier()); +} + +TEST_F(ParseErrorTest, SimpleSyntaxError) { + ExpectHasErrors( + "message TestMessage @#$ { blah }", + "0:20: Expected \"{\".\n"); + EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier()); +} + +TEST_F(ParseErrorTest, ExpectedTopLevel) { + ExpectHasErrors( + "blah;", + "0:0: Expected top-level statement (e.g. \"message\").\n"); +} + +TEST_F(ParseErrorTest, UnmatchedCloseBrace) { + // This used to cause an infinite loop. Doh. + ExpectHasErrors( + "}", + "0:0: Expected top-level statement (e.g. \"message\").\n" + "0:0: Unmatched \"}\".\n"); +} + +// ------------------------------------------------------------------- +// Message errors + +TEST_F(ParseErrorTest, MessageMissingName) { + ExpectHasErrors( + "message {}", + "0:8: Expected message name.\n"); +} + +TEST_F(ParseErrorTest, MessageMissingBody) { + ExpectHasErrors( + "message TestMessage;", + "0:19: Expected \"{\".\n"); +} + +TEST_F(ParseErrorTest, EofInMessage) { + ExpectHasErrors( + "message TestMessage {", + "0:21: Reached end of input in message definition (missing '}').\n"); +} + +TEST_F(ParseErrorTest, MissingFieldNumber) { + ExpectHasErrors( + "message TestMessage {\n" + " optional int32 foo;\n" + "}\n", + "1:20: Missing field number.\n"); +} + +TEST_F(ParseErrorTest, ExpectedFieldNumber) { + ExpectHasErrors( + "message TestMessage {\n" + " optional int32 foo = ;\n" + "}\n", + "1:23: Expected field number.\n"); +} + +TEST_F(ParseErrorTest, FieldNumberOutOfRange) { + ExpectHasErrors( + "message TestMessage {\n" + " optional int32 foo = 0x100000000;\n" + "}\n", + "1:23: Integer out of range.\n"); +} + +TEST_F(ParseErrorTest, MissingLabel) { + ExpectHasErrors( + "message TestMessage {\n" + " int32 foo = 1;\n" + "}\n", + "1:2: Expected \"required\", \"optional\", or \"repeated\".\n"); +} + +TEST_F(ParseErrorTest, ExpectedOptionName) { + ExpectHasErrors( + "message TestMessage {\n" + " optional uint32 foo = 1 [];\n" + "}\n", + "1:27: Expected identifier.\n"); +} + +TEST_F(ParseErrorTest, NonExtensionOptionNameBeginningWithDot) { + ExpectHasErrors( + "message TestMessage {\n" + " optional uint32 foo = 1 [.foo=1];\n" + "}\n", + "1:27: Expected identifier.\n"); +} + +TEST_F(ParseErrorTest, DefaultValueTypeMismatch) { + ExpectHasErrors( + "message TestMessage {\n" + " optional uint32 foo = 1 [default=true];\n" + "}\n", + "1:35: Expected integer.\n"); +} + +TEST_F(ParseErrorTest, DefaultValueNotBoolean) { + ExpectHasErrors( + "message TestMessage {\n" + " optional bool foo = 1 [default=blah];\n" + "}\n", + "1:33: Expected \"true\" or \"false\".\n"); +} + +TEST_F(ParseErrorTest, DefaultValueNotString) { + ExpectHasErrors( + "message TestMessage {\n" + " optional string foo = 1 [default=1];\n" + "}\n", + "1:35: Expected string.\n"); +} + +TEST_F(ParseErrorTest, DefaultValueUnsignedNegative) { + ExpectHasErrors( + "message TestMessage {\n" + " optional uint32 foo = 1 [default=-1];\n" + "}\n", + "1:36: Unsigned field can't have negative default value.\n"); +} + +TEST_F(ParseErrorTest, DefaultValueTooLarge) { + ExpectHasErrors( + "message TestMessage {\n" + " optional int32 foo = 1 [default= 0x80000000];\n" + " optional int32 foo = 1 [default=-0x80000001];\n" + " optional uint32 foo = 1 [default= 0x100000000];\n" + " optional int64 foo = 1 [default= 0x80000000000000000];\n" + " optional int64 foo = 1 [default=-0x80000000000000001];\n" + " optional uint64 foo = 1 [default= 0x100000000000000000];\n" + "}\n", + "1:36: Integer out of range.\n" + "2:36: Integer out of range.\n" + "3:36: Integer out of range.\n" + "4:36: Integer out of range.\n" + "5:36: Integer out of range.\n" + "6:36: Integer out of range.\n"); +} + +TEST_F(ParseErrorTest, EnumValueOutOfRange) { + ExpectHasErrors( + "enum TestEnum {\n" + " HEX_TOO_BIG = 0x80000000;\n" + " HEX_TOO_SMALL = -0x80000001;\n" + " INT_TOO_BIG = 2147483648;\n" + " INT_TOO_SMALL = -2147483649;\n" + "}\n", + "1:19: Integer out of range.\n" + "2:19: Integer out of range.\n" + "3:19: Integer out of range.\n" + "4:19: Integer out of range.\n"); +} + +TEST_F(ParseErrorTest, DefaultValueMissing) { + ExpectHasErrors( + "message TestMessage {\n" + " optional uint32 foo = 1 [default=];\n" + "}\n", + "1:35: Expected integer.\n"); +} + +TEST_F(ParseErrorTest, DefaultValueForGroup) { + ExpectHasErrors( + "message TestMessage {\n" + " optional group Foo = 1 [default=blah] {}\n" + "}\n", + "1:34: Messages can't have default values.\n"); +} + +TEST_F(ParseErrorTest, DuplicateDefaultValue) { + ExpectHasErrors( + "message TestMessage {\n" + " optional uint32 foo = 1 [default=1,default=2];\n" + "}\n", + "1:37: Already set option \"default\".\n"); +} + +TEST_F(ParseErrorTest, GroupNotCapitalized) { + ExpectHasErrors( + "message TestMessage {\n" + " optional group foo = 1 {}\n" + "}\n", + "1:17: Group names must start with a capital letter.\n"); +} + +TEST_F(ParseErrorTest, GroupMissingBody) { + ExpectHasErrors( + "message TestMessage {\n" + " optional group Foo = 1;\n" + "}\n", + "1:24: Missing group body.\n"); +} + +TEST_F(ParseErrorTest, ExtendingPrimitive) { + ExpectHasErrors( + "extend int32 { optional string foo = 4; }\n", + "0:7: Expected message type.\n"); +} + +TEST_F(ParseErrorTest, ErrorInExtension) { + ExpectHasErrors( + "message Foo { extensions 100 to 199; }\n" + "extend Foo { optional string foo; }\n", + "1:32: Missing field number.\n"); +} + +TEST_F(ParseErrorTest, MultipleParseErrors) { + // When a statement has a parse error, the parser should be able to continue + // parsing at the next statement. + ExpectHasErrors( + "message TestMessage {\n" + " optional int32 foo;\n" + " !invalid statement ending in a block { blah blah { blah } blah }\n" + " optional int32 bar = 3 {}\n" + "}\n", + "1:20: Missing field number.\n" + "2:2: Expected \"required\", \"optional\", or \"repeated\".\n" + "2:2: Expected type name.\n" + "3:25: Expected \";\".\n"); +} + +TEST_F(ParseErrorTest, EofInAggregateValue) { + ExpectHasErrors( + "option (fileopt) = { i:100\n", + "1:0: Unexpected end of stream while parsing aggregate value.\n"); +} + +// ------------------------------------------------------------------- +// Enum errors + +TEST_F(ParseErrorTest, EofInEnum) { + ExpectHasErrors( + "enum TestEnum {", + "0:15: Reached end of input in enum definition (missing '}').\n"); +} + +TEST_F(ParseErrorTest, EnumValueMissingNumber) { + ExpectHasErrors( + "enum TestEnum {\n" + " FOO;\n" + "}\n", + "1:5: Missing numeric value for enum constant.\n"); +} + +// ------------------------------------------------------------------- +// Service errors + +TEST_F(ParseErrorTest, EofInService) { + ExpectHasErrors( + "service TestService {", + "0:21: Reached end of input in service definition (missing '}').\n"); +} + +TEST_F(ParseErrorTest, ServiceMethodPrimitiveParams) { + ExpectHasErrors( + "service TestService {\n" + " rpc Foo(int32) returns (string);\n" + "}\n", + "1:10: Expected message type.\n" + "1:26: Expected message type.\n"); +} + + +TEST_F(ParseErrorTest, EofInMethodOptions) { + ExpectHasErrors( + "service TestService {\n" + " rpc Foo(Bar) returns(Bar) {", + "1:29: Reached end of input in method options (missing '}').\n" + "1:29: Reached end of input in service definition (missing '}').\n"); +} + + +TEST_F(ParseErrorTest, PrimitiveMethodInput) { + ExpectHasErrors( + "service TestService {\n" + " rpc Foo(int32) returns(Bar);\n" + "}\n", + "1:10: Expected message type.\n"); +} + + +TEST_F(ParseErrorTest, MethodOptionTypeError) { + // This used to cause an infinite loop. + ExpectHasErrors( + "message Baz {}\n" + "service Foo {\n" + " rpc Bar(Baz) returns(Baz) { option invalid syntax; }\n" + "}\n", + "2:45: Expected \"=\".\n"); +} + + +// ------------------------------------------------------------------- +// Import and package errors + +TEST_F(ParseErrorTest, ImportNotQuoted) { + ExpectHasErrors( + "import foo;\n", + "0:7: Expected a string naming the file to import.\n"); +} + +TEST_F(ParseErrorTest, MultiplePackagesInFile) { + ExpectHasErrors( + "package foo;\n" + "package bar;\n", + "1:0: Multiple package definitions.\n"); +} + +// =================================================================== +// Test that errors detected by DescriptorPool correctly report line and +// column numbers. We have one test for every call to RecordLocation() in +// parser.cc. + +typedef ParserTest ParserValidationErrorTest; + +TEST_F(ParserValidationErrorTest, PackageNameError) { + // Create another file which defines symbol "foo". + FileDescriptorProto other_file; + other_file.set_name("bar.proto"); + other_file.add_message_type()->set_name("foo"); + EXPECT_TRUE(pool_.BuildFile(other_file) != NULL); + + // Now try to define it as a package. + ExpectHasValidationErrors( + "package foo.bar;", + "0:8: \"foo\" is already defined (as something other than a package) " + "in file \"bar.proto\".\n"); +} + +TEST_F(ParserValidationErrorTest, MessageNameError) { + ExpectHasValidationErrors( + "message Foo {}\n" + "message Foo {}\n", + "1:8: \"Foo\" is already defined.\n"); +} + +TEST_F(ParserValidationErrorTest, FieldNameError) { + ExpectHasValidationErrors( + "message Foo {\n" + " optional int32 bar = 1;\n" + " optional int32 bar = 2;\n" + "}\n", + "2:17: \"bar\" is already defined in \"Foo\".\n"); +} + +TEST_F(ParserValidationErrorTest, FieldTypeError) { + ExpectHasValidationErrors( + "message Foo {\n" + " optional Baz bar = 1;\n" + "}\n", + "1:11: \"Baz\" is not defined.\n"); +} + +TEST_F(ParserValidationErrorTest, FieldNumberError) { + ExpectHasValidationErrors( + "message Foo {\n" + " optional int32 bar = 0;\n" + "}\n", + "1:23: Field numbers must be positive integers.\n"); +} + +TEST_F(ParserValidationErrorTest, FieldExtendeeError) { + ExpectHasValidationErrors( + "extend Baz { optional int32 bar = 1; }\n", + "0:7: \"Baz\" is not defined.\n"); +} + +TEST_F(ParserValidationErrorTest, FieldDefaultValueError) { + ExpectHasValidationErrors( + "enum Baz { QUX = 1; }\n" + "message Foo {\n" + " optional Baz bar = 1 [default=NO_SUCH_VALUE];\n" + "}\n", + "2:32: Enum type \"Baz\" has no value named \"NO_SUCH_VALUE\".\n"); +} + +TEST_F(ParserValidationErrorTest, FileOptionNameError) { + ExpectHasValidationErrors( + "option foo = 5;", + "0:7: Option \"foo\" unknown.\n"); +} + +TEST_F(ParserValidationErrorTest, FileOptionValueError) { + ExpectHasValidationErrors( + "option java_outer_classname = 5;", + "0:30: Value must be quoted string for string option " + "\"google.protobuf.FileOptions.java_outer_classname\".\n"); +} + +TEST_F(ParserValidationErrorTest, FieldOptionNameError) { + ExpectHasValidationErrors( + "message Foo {\n" + " optional bool bar = 1 [foo=1];\n" + "}\n", + "1:25: Option \"foo\" unknown.\n"); +} + +TEST_F(ParserValidationErrorTest, FieldOptionValueError) { + ExpectHasValidationErrors( + "message Foo {\n" + " optional int32 bar = 1 [ctype=1];\n" + "}\n", + "1:32: Value must be identifier for enum-valued option " + "\"google.protobuf.FieldOptions.ctype\".\n"); +} + +TEST_F(ParserValidationErrorTest, ExtensionRangeNumberError) { + ExpectHasValidationErrors( + "message Foo {\n" + " extensions 0;\n" + "}\n", + "1:13: Extension numbers must be positive integers.\n"); +} + +TEST_F(ParserValidationErrorTest, EnumNameError) { + ExpectHasValidationErrors( + "enum Foo {A = 1;}\n" + "enum Foo {B = 1;}\n", + "1:5: \"Foo\" is already defined.\n"); +} + +TEST_F(ParserValidationErrorTest, EnumValueNameError) { + ExpectHasValidationErrors( + "enum Foo {\n" + " BAR = 1;\n" + " BAR = 1;\n" + "}\n", + "2:2: \"BAR\" is already defined.\n"); +} + +TEST_F(ParserValidationErrorTest, ServiceNameError) { + ExpectHasValidationErrors( + "service Foo {}\n" + "service Foo {}\n", + "1:8: \"Foo\" is already defined.\n"); +} + +TEST_F(ParserValidationErrorTest, MethodNameError) { + ExpectHasValidationErrors( + "message Baz {}\n" + "service Foo {\n" + " rpc Bar(Baz) returns(Baz);\n" + " rpc Bar(Baz) returns(Baz);\n" + "}\n", + "3:6: \"Bar\" is already defined in \"Foo\".\n"); +} + + +TEST_F(ParserValidationErrorTest, MethodInputTypeError) { + ExpectHasValidationErrors( + "message Baz {}\n" + "service Foo {\n" + " rpc Bar(Qux) returns(Baz);\n" + "}\n", + "2:10: \"Qux\" is not defined.\n"); +} + + +TEST_F(ParserValidationErrorTest, MethodOutputTypeError) { + ExpectHasValidationErrors( + "message Baz {}\n" + "service Foo {\n" + " rpc Bar(Baz) returns(Qux);\n" + "}\n", + "2:23: \"Qux\" is not defined.\n"); +} + + +// =================================================================== +// Test that the output from FileDescriptor::DebugString() (and all other +// descriptor types) is parseable, and results in the same Descriptor +// definitions again afoter parsing (not, however, that the order of messages +// cannot be guaranteed to be the same) + +typedef ParserTest ParseDecriptorDebugTest; + +class CompareDescriptorNames { + public: + bool operator()(const DescriptorProto* left, const DescriptorProto* right) { + return left->name() < right->name(); + } +}; + +// Sorts nested DescriptorProtos of a DescriptoProto, by name. +void SortMessages(DescriptorProto *descriptor_proto) { + int size = descriptor_proto->nested_type_size(); + // recursively sort; we can't guarantee the order of nested messages either + for (int i = 0; i < size; ++i) { + SortMessages(descriptor_proto->mutable_nested_type(i)); + } + DescriptorProto **data = + descriptor_proto->mutable_nested_type()->mutable_data(); + sort(data, data + size, CompareDescriptorNames()); +} + +// Sorts DescriptorProtos belonging to a FileDescriptorProto, by name. +void SortMessages(FileDescriptorProto *file_descriptor_proto) { + int size = file_descriptor_proto->message_type_size(); + // recursively sort; we can't guarantee the order of nested messages either + for (int i = 0; i < size; ++i) { + SortMessages(file_descriptor_proto->mutable_message_type(i)); + } + DescriptorProto **data = + file_descriptor_proto->mutable_message_type()->mutable_data(); + sort(data, data + size, CompareDescriptorNames()); +} + +TEST_F(ParseDecriptorDebugTest, TestAllDescriptorTypes) { + const FileDescriptor* original_file = + protobuf_unittest::TestAllTypes::descriptor()->file(); + FileDescriptorProto expected; + original_file->CopyTo(&expected); + + // Get the DebugString of the unittest.proto FileDecriptor, which includes + // all other descriptor types + string debug_string = original_file->DebugString(); + + // Parse the debug string + SetupParser(debug_string.c_str()); + FileDescriptorProto parsed; + parser_->Parse(input_.get(), &parsed); + EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); + ASSERT_EQ("", error_collector_.text_); + + // We now have a FileDescriptorProto, but to compare with the expected we + // need to link to a FileDecriptor, then output back to a proto. We'll + // also need to give it the same name as the original. + parsed.set_name("google/protobuf/unittest.proto"); + // We need the imported dependency before we can build our parsed proto + const FileDescriptor* public_import = + protobuf_unittest_import::PublicImportMessage::descriptor()->file(); + FileDescriptorProto public_import_proto; + public_import->CopyTo(&public_import_proto); + ASSERT_TRUE(pool_.BuildFile(public_import_proto) != NULL); + const FileDescriptor* import = + protobuf_unittest_import::ImportMessage::descriptor()->file(); + FileDescriptorProto import_proto; + import->CopyTo(&import_proto); + ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL); + const FileDescriptor* actual = pool_.BuildFile(parsed); + parsed.Clear(); + actual->CopyTo(&parsed); + ASSERT_TRUE(actual != NULL); + + // The messages might be in different orders, making them hard to compare. + // So, sort the messages in the descriptor protos (including nested messages, + // recursively). + SortMessages(&expected); + SortMessages(&parsed); + + // I really wanted to use StringDiff here for the debug output on fail, + // but the strings are too long for it, and if I increase its max size, + // we get a memory allocation failure :( + EXPECT_EQ(expected.DebugString(), parsed.DebugString()); +} + +TEST_F(ParseDecriptorDebugTest, TestCustomOptions) { + const FileDescriptor* original_file = + protobuf_unittest::AggregateMessage::descriptor()->file(); + FileDescriptorProto expected; + original_file->CopyTo(&expected); + + string debug_string = original_file->DebugString(); + + // Parse the debug string + SetupParser(debug_string.c_str()); + FileDescriptorProto parsed; + parser_->Parse(input_.get(), &parsed); + EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); + ASSERT_EQ("", error_collector_.text_); + + // We now have a FileDescriptorProto, but to compare with the expected we + // need to link to a FileDecriptor, then output back to a proto. We'll + // also need to give it the same name as the original. + parsed.set_name(original_file->name()); + + // unittest_custom_options.proto depends on descriptor.proto. + const FileDescriptor* import = FileDescriptorProto::descriptor()->file(); + FileDescriptorProto import_proto; + import->CopyTo(&import_proto); + ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL); + const FileDescriptor* actual = pool_.BuildFile(parsed); + ASSERT_TRUE(actual != NULL); + parsed.Clear(); + actual->CopyTo(&parsed); + + // The messages might be in different orders, making them hard to compare. + // So, sort the messages in the descriptor protos (including nested messages, + // recursively). + SortMessages(&expected); + SortMessages(&parsed); + + EXPECT_EQ(expected.DebugString(), parsed.DebugString()); +} + +// =================================================================== +// SourceCodeInfo tests. + +// Follows a path -- as defined by SourceCodeInfo.Location.path -- from a +// message to a particular sub-field. +// * If the target is itself a message, sets *output_message to point at it, +// *output_field to NULL, and *output_index to -1. +// * Otherwise, if the target is an element of a repeated field, sets +// *output_message to the containing message, *output_field to the descriptor +// of the field, and *output_index to the index of the element. +// * Otherwise, the target is a field (possibly a repeated field, but not any +// one element). Sets *output_message to the containing message, +// *output_field to the descriptor of the field, and *output_index to -1. +// Returns true if the path was valid, false otherwise. A gTest failure is +// recorded before returning false. +bool FollowPath(const Message& root, + const int* path_begin, const int* path_end, + const Message** output_message, + const FieldDescriptor** output_field, + int* output_index) { + if (path_begin == path_end) { + // Path refers to this whole message. + *output_message = &root; + *output_field = NULL; + *output_index = -1; + return true; + } + + const Descriptor* descriptor = root.GetDescriptor(); + const Reflection* reflection = root.GetReflection(); + + const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin); + + if (field == NULL) { + ADD_FAILURE() << descriptor->name() << " has no field number: " + << *path_begin; + return false; + } + + ++path_begin; + + if (field->is_repeated()) { + if (path_begin == path_end) { + // Path refers to the whole repeated field. + *output_message = &root; + *output_field = field; + *output_index = -1; + return true; + } + + int index = *path_begin++; + int size = reflection->FieldSize(root, field); + + if (index >= size) { + ADD_FAILURE() << descriptor->name() << "." << field->name() + << " has size " << size << ", but path contained index: " + << index; + return false; + } + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + // Descend into child message. + const Message& child = reflection->GetRepeatedMessage(root, field, index); + return FollowPath(child, path_begin, path_end, + output_message, output_field, output_index); + } else if (path_begin == path_end) { + // Path refers to this element. + *output_message = &root; + *output_field = field; + *output_index = index; + return true; + } else { + ADD_FAILURE() << descriptor->name() << "." << field->name() + << " is not a message; cannot descend into it."; + return false; + } + } else { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + const Message& child = reflection->GetMessage(root, field); + return FollowPath(child, path_begin, path_end, + output_message, output_field, output_index); + } else if (path_begin == path_end) { + // Path refers to this field. + *output_message = &root; + *output_field = field; + *output_index = -1; + return true; + } else { + ADD_FAILURE() << descriptor->name() << "." << field->name() + << " is not a message; cannot descend into it."; + return false; + } + } +} + +// Check if two spans are equal. +bool CompareSpans(const RepeatedField& span1, + const RepeatedField& span2) { + if (span1.size() != span2.size()) return false; + for (int i = 0; i < span1.size(); i++) { + if (span1.Get(i) != span2.Get(i)) return false; + } + return true; +} + +// Test fixture for source info tests, which check that source locations are +// recorded correctly in FileDescriptorProto.source_code_info.location. +class SourceInfoTest : public ParserTest { + protected: + // The parsed file (initialized by Parse()). + FileDescriptorProto file_; + + // Parse the given text as a .proto file and populate the spans_ map with + // all the source location spans in its SourceCodeInfo table. + bool Parse(const char* text) { + ExtractMarkers(text); + SetupParser(text_without_markers_.c_str()); + if (!parser_->Parse(input_.get(), &file_)) { + return false; + } + + const SourceCodeInfo& source_info = file_.source_code_info(); + for (int i = 0; i < source_info.location_size(); i++) { + const SourceCodeInfo::Location& location = source_info.location(i); + const Message* descriptor_proto = NULL; + const FieldDescriptor* field = NULL; + int index = 0; + if (!FollowPath(file_, location.path().begin(), location.path().end(), + &descriptor_proto, &field, &index)) { + return false; + } + + spans_.insert(make_pair(SpanKey(*descriptor_proto, field, index), + &location)); + } + + return true; + } + + virtual void TearDown() { + EXPECT_TRUE(spans_.empty()) + << "Forgot to call HasSpan() for:\n" + << spans_.begin()->second->DebugString(); + } + + // ----------------------------------------------------------------- + // HasSpan() checks that the span of source code delimited by the given + // tags (comments) correspond via the SourceCodeInfo table to the given + // part of the FileDescriptorProto. (If unclear, look at the actual tests; + // it should quickly become obvious.) + + bool HasSpan(char start_marker, char end_marker, + const Message& descriptor_proto) { + return HasSpanWithComment( + start_marker, end_marker, descriptor_proto, NULL, -1, NULL, NULL); + } + + bool HasSpanWithComment(char start_marker, char end_marker, + const Message& descriptor_proto, + const char* expected_leading_comments, + const char* expected_trailing_comments) { + return HasSpanWithComment( + start_marker, end_marker, descriptor_proto, NULL, -1, + expected_leading_comments, expected_trailing_comments); + } + + bool HasSpan(char start_marker, char end_marker, + const Message& descriptor_proto, const string& field_name) { + return HasSpan(start_marker, end_marker, descriptor_proto, field_name, -1); + } + + bool HasSpan(char start_marker, char end_marker, + const Message& descriptor_proto, const string& field_name, + int index) { + return HasSpan(start_marker, end_marker, descriptor_proto, + field_name, index, NULL, NULL); + } + + bool HasSpan(char start_marker, char end_marker, + const Message& descriptor_proto, + const string& field_name, int index, + const char* expected_leading_comments, + const char* expected_trailing_comments) { + const FieldDescriptor* field = + descriptor_proto.GetDescriptor()->FindFieldByName(field_name); + if (field == NULL) { + ADD_FAILURE() << descriptor_proto.GetDescriptor()->name() + << " has no such field: " << field_name; + return false; + } + + return HasSpanWithComment( + start_marker, end_marker, descriptor_proto, field, index, + expected_leading_comments, expected_trailing_comments); + } + + bool HasSpan(const Message& descriptor_proto) { + return HasSpanWithComment( + '\0', '\0', descriptor_proto, NULL, -1, NULL, NULL); + } + + bool HasSpan(const Message& descriptor_proto, const string& field_name) { + return HasSpan('\0', '\0', descriptor_proto, field_name, -1); + } + + bool HasSpan(const Message& descriptor_proto, const string& field_name, + int index) { + return HasSpan('\0', '\0', descriptor_proto, field_name, index); + } + + bool HasSpanWithComment(char start_marker, char end_marker, + const Message& descriptor_proto, + const FieldDescriptor* field, int index, + const char* expected_leading_comments, + const char* expected_trailing_comments) { + pair range = + spans_.equal_range(SpanKey(descriptor_proto, field, index)); + + if (start_marker == '\0') { + if (range.first == range.second) { + return false; + } else { + spans_.erase(range.first); + return true; + } + } else { + pair start_pos = FindOrDie(markers_, start_marker); + pair end_pos = FindOrDie(markers_, end_marker); + + RepeatedField expected_span; + expected_span.Add(start_pos.first); + expected_span.Add(start_pos.second); + if (end_pos.first != start_pos.first) { + expected_span.Add(end_pos.first); + } + expected_span.Add(end_pos.second); + + for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) { + if (CompareSpans(expected_span, iter->second->span())) { + if (expected_leading_comments == NULL) { + EXPECT_FALSE(iter->second->has_leading_comments()); + } else { + EXPECT_TRUE(iter->second->has_leading_comments()); + EXPECT_EQ(expected_leading_comments, + iter->second->leading_comments()); + } + if (expected_trailing_comments == NULL) { + EXPECT_FALSE(iter->second->has_trailing_comments()); + } else { + EXPECT_TRUE(iter->second->has_trailing_comments()); + EXPECT_EQ(expected_trailing_comments, + iter->second->trailing_comments()); + } + + spans_.erase(iter); + return true; + } + } + + return false; + } + } + + private: + struct SpanKey { + const Message* descriptor_proto; + const FieldDescriptor* field; + int index; + + inline SpanKey() {} + inline SpanKey(const Message& descriptor_proto_param, + const FieldDescriptor* field_param, + int index_param) + : descriptor_proto(&descriptor_proto_param), field(field_param), + index(index_param) {} + + inline bool operator<(const SpanKey& other) const { + if (descriptor_proto < other.descriptor_proto) return true; + if (descriptor_proto > other.descriptor_proto) return false; + if (field < other.field) return true; + if (field > other.field) return false; + return index < other.index; + } + }; + + typedef multimap SpanMap; + SpanMap spans_; + map > markers_; + string text_without_markers_; + + void ExtractMarkers(const char* text) { + markers_.clear(); + text_without_markers_.clear(); + int line = 0; + int column = 0; + while (*text != '\0') { + if (*text == '$') { + ++text; + GOOGLE_CHECK_NE('\0', *text); + if (*text == '$') { + text_without_markers_ += '$'; + ++column; + } else { + markers_[*text] = make_pair(line, column); + ++text; + GOOGLE_CHECK_EQ('$', *text); + } + } else if (*text == '\n') { + ++line; + column = 0; + text_without_markers_ += *text; + } else { + text_without_markers_ += *text; + ++column; + } + ++text; + } + } +}; + +TEST_F(SourceInfoTest, BasicFileDecls) { + EXPECT_TRUE(Parse( + "$a$syntax = \"proto2\";\n" + "package $b$foo.bar$c$;\n" + "import $d$\"baz.proto\"$e$;\n" + "import $f$\"qux.proto\"$g$;$h$\n" + "\n" + "// comment ignored\n")); + + EXPECT_TRUE(HasSpan('a', 'h', file_)); + EXPECT_TRUE(HasSpan('b', 'c', file_, "package")); + EXPECT_TRUE(HasSpan('d', 'e', file_, "dependency", 0)); + EXPECT_TRUE(HasSpan('f', 'g', file_, "dependency", 1)); +} + +TEST_F(SourceInfoTest, Messages) { + EXPECT_TRUE(Parse( + "$a$message $b$Foo$c$ {}$d$\n" + "$e$message $f$Bar$g$ {}$h$\n")); + + EXPECT_TRUE(HasSpan('a', 'd', file_.message_type(0))); + EXPECT_TRUE(HasSpan('b', 'c', file_.message_type(0), "name")); + EXPECT_TRUE(HasSpan('e', 'h', file_.message_type(1))); + EXPECT_TRUE(HasSpan('f', 'g', file_.message_type(1), "name")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); +} + +TEST_F(SourceInfoTest, Fields) { + EXPECT_TRUE(Parse( + "message Foo {\n" + " $a$optional$b$ $c$int32$d$ $e$bar$f$ = $g$1$h$;$i$\n" + " $j$repeated$k$ $l$X.Y$m$ $n$baz$o$ = $p$2$q$;$r$\n" + "}\n")); + + const FieldDescriptorProto& field1 = file_.message_type(0).field(0); + const FieldDescriptorProto& field2 = file_.message_type(0).field(1); + + EXPECT_TRUE(HasSpan('a', 'i', field1)); + EXPECT_TRUE(HasSpan('a', 'b', field1, "label")); + EXPECT_TRUE(HasSpan('c', 'd', field1, "type")); + EXPECT_TRUE(HasSpan('e', 'f', field1, "name")); + EXPECT_TRUE(HasSpan('g', 'h', field1, "number")); + + EXPECT_TRUE(HasSpan('j', 'r', field2)); + EXPECT_TRUE(HasSpan('j', 'k', field2, "label")); + EXPECT_TRUE(HasSpan('l', 'm', field2, "type_name")); + EXPECT_TRUE(HasSpan('n', 'o', field2, "name")); + EXPECT_TRUE(HasSpan('p', 'q', field2, "number")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); +} + +TEST_F(SourceInfoTest, Extensions) { + EXPECT_TRUE(Parse( + "$a$extend $b$Foo$c$ {\n" + " $d$optional$e$ int32 bar = 1;$f$\n" + " $g$repeated$h$ X.Y baz = 2;$i$\n" + "}$j$\n" + "$k$extend $l$Bar$m$ {\n" + " $n$optional int32 qux = 1;$o$\n" + "}$p$\n")); + + const FieldDescriptorProto& field1 = file_.extension(0); + const FieldDescriptorProto& field2 = file_.extension(1); + const FieldDescriptorProto& field3 = file_.extension(2); + + EXPECT_TRUE(HasSpan('a', 'j', file_, "extension")); + EXPECT_TRUE(HasSpan('k', 'p', file_, "extension")); + + EXPECT_TRUE(HasSpan('d', 'f', field1)); + EXPECT_TRUE(HasSpan('d', 'e', field1, "label")); + EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee")); + + EXPECT_TRUE(HasSpan('g', 'i', field2)); + EXPECT_TRUE(HasSpan('g', 'h', field2, "label")); + EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee")); + + EXPECT_TRUE(HasSpan('n', 'o', field3)); + EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(field1, "type")); + EXPECT_TRUE(HasSpan(field1, "name")); + EXPECT_TRUE(HasSpan(field1, "number")); + EXPECT_TRUE(HasSpan(field2, "type_name")); + EXPECT_TRUE(HasSpan(field2, "name")); + EXPECT_TRUE(HasSpan(field2, "number")); + EXPECT_TRUE(HasSpan(field3, "label")); + EXPECT_TRUE(HasSpan(field3, "type")); + EXPECT_TRUE(HasSpan(field3, "name")); + EXPECT_TRUE(HasSpan(field3, "number")); +} + +TEST_F(SourceInfoTest, NestedExtensions) { + EXPECT_TRUE(Parse( + "message Message {\n" + " $a$extend $b$Foo$c$ {\n" + " $d$optional$e$ int32 bar = 1;$f$\n" + " $g$repeated$h$ X.Y baz = 2;$i$\n" + " }$j$\n" + " $k$extend $l$Bar$m$ {\n" + " $n$optional int32 qux = 1;$o$\n" + " }$p$\n" + "}\n")); + + const FieldDescriptorProto& field1 = file_.message_type(0).extension(0); + const FieldDescriptorProto& field2 = file_.message_type(0).extension(1); + const FieldDescriptorProto& field3 = file_.message_type(0).extension(2); + + EXPECT_TRUE(HasSpan('a', 'j', file_.message_type(0), "extension")); + EXPECT_TRUE(HasSpan('k', 'p', file_.message_type(0), "extension")); + + EXPECT_TRUE(HasSpan('d', 'f', field1)); + EXPECT_TRUE(HasSpan('d', 'e', field1, "label")); + EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee")); + + EXPECT_TRUE(HasSpan('g', 'i', field2)); + EXPECT_TRUE(HasSpan('g', 'h', field2, "label")); + EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee")); + + EXPECT_TRUE(HasSpan('n', 'o', field3)); + EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); + EXPECT_TRUE(HasSpan(field1, "type")); + EXPECT_TRUE(HasSpan(field1, "name")); + EXPECT_TRUE(HasSpan(field1, "number")); + EXPECT_TRUE(HasSpan(field2, "type_name")); + EXPECT_TRUE(HasSpan(field2, "name")); + EXPECT_TRUE(HasSpan(field2, "number")); + EXPECT_TRUE(HasSpan(field3, "label")); + EXPECT_TRUE(HasSpan(field3, "type")); + EXPECT_TRUE(HasSpan(field3, "name")); + EXPECT_TRUE(HasSpan(field3, "number")); +} + +TEST_F(SourceInfoTest, ExtensionRanges) { + EXPECT_TRUE(Parse( + "message Message {\n" + " $a$extensions $b$1$c$ to $d$4$e$, $f$6$g$;$h$\n" + " $i$extensions $j$8$k$ to $l$max$m$;$n$\n" + "}\n")); + + const DescriptorProto::ExtensionRange& range1 = + file_.message_type(0).extension_range(0); + const DescriptorProto::ExtensionRange& range2 = + file_.message_type(0).extension_range(1); + const DescriptorProto::ExtensionRange& range3 = + file_.message_type(0).extension_range(2); + + EXPECT_TRUE(HasSpan('a', 'h', file_.message_type(0), "extension_range")); + EXPECT_TRUE(HasSpan('i', 'n', file_.message_type(0), "extension_range")); + + EXPECT_TRUE(HasSpan('b', 'e', range1)); + EXPECT_TRUE(HasSpan('b', 'c', range1, "start")); + EXPECT_TRUE(HasSpan('d', 'e', range1, "end")); + + EXPECT_TRUE(HasSpan('f', 'g', range2)); + EXPECT_TRUE(HasSpan('f', 'g', range2, "start")); + EXPECT_TRUE(HasSpan('f', 'g', range2, "end")); + + EXPECT_TRUE(HasSpan('j', 'm', range3)); + EXPECT_TRUE(HasSpan('j', 'k', range3, "start")); + EXPECT_TRUE(HasSpan('l', 'm', range3, "end")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); +} + +TEST_F(SourceInfoTest, NestedMessages) { + EXPECT_TRUE(Parse( + "message Foo {\n" + " $a$message $b$Bar$c$ {\n" + " $d$message $e$Baz$f$ {}$g$\n" + " }$h$\n" + " $i$message $j$Qux$k$ {}$l$\n" + "}\n")); + + const DescriptorProto& bar = file_.message_type(0).nested_type(0); + const DescriptorProto& baz = bar.nested_type(0); + const DescriptorProto& qux = file_.message_type(0).nested_type(1); + + EXPECT_TRUE(HasSpan('a', 'h', bar)); + EXPECT_TRUE(HasSpan('b', 'c', bar, "name")); + EXPECT_TRUE(HasSpan('d', 'g', baz)); + EXPECT_TRUE(HasSpan('e', 'f', baz, "name")); + EXPECT_TRUE(HasSpan('i', 'l', qux)); + EXPECT_TRUE(HasSpan('j', 'k', qux, "name")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); +} + +TEST_F(SourceInfoTest, Groups) { + EXPECT_TRUE(Parse( + "message Foo {\n" + " message Bar {}\n" + " $a$optional$b$ $c$group$d$ $e$Baz$f$ = $g$1$h$ {\n" + " $i$message Qux {}$j$\n" + " }$k$\n" + "}\n")); + + const DescriptorProto& bar = file_.message_type(0).nested_type(0); + const DescriptorProto& baz = file_.message_type(0).nested_type(1); + const DescriptorProto& qux = baz.nested_type(0); + const FieldDescriptorProto& field = file_.message_type(0).field(0); + + EXPECT_TRUE(HasSpan('a', 'k', field)); + EXPECT_TRUE(HasSpan('a', 'b', field, "label")); + EXPECT_TRUE(HasSpan('c', 'd', field, "type")); + EXPECT_TRUE(HasSpan('e', 'f', field, "name")); + EXPECT_TRUE(HasSpan('e', 'f', field, "type_name")); + EXPECT_TRUE(HasSpan('g', 'h', field, "number")); + + EXPECT_TRUE(HasSpan('a', 'k', baz)); + EXPECT_TRUE(HasSpan('e', 'f', baz, "name")); + EXPECT_TRUE(HasSpan('i', 'j', qux)); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); + EXPECT_TRUE(HasSpan(bar)); + EXPECT_TRUE(HasSpan(bar, "name")); + EXPECT_TRUE(HasSpan(qux, "name")); +} + +TEST_F(SourceInfoTest, Enums) { + EXPECT_TRUE(Parse( + "$a$enum $b$Foo$c$ {}$d$\n" + "$e$enum $f$Bar$g$ {}$h$\n")); + + EXPECT_TRUE(HasSpan('a', 'd', file_.enum_type(0))); + EXPECT_TRUE(HasSpan('b', 'c', file_.enum_type(0), "name")); + EXPECT_TRUE(HasSpan('e', 'h', file_.enum_type(1))); + EXPECT_TRUE(HasSpan('f', 'g', file_.enum_type(1), "name")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); +} + +TEST_F(SourceInfoTest, EnumValues) { + EXPECT_TRUE(Parse( + "enum Foo {\n" + " $a$BAR$b$ = $c$1$d$;$e$\n" + " $f$BAZ$g$ = $h$2$i$;$j$\n" + "}")); + + const EnumValueDescriptorProto& bar = file_.enum_type(0).value(0); + const EnumValueDescriptorProto& baz = file_.enum_type(0).value(1); + + EXPECT_TRUE(HasSpan('a', 'e', bar)); + EXPECT_TRUE(HasSpan('a', 'b', bar, "name")); + EXPECT_TRUE(HasSpan('c', 'd', bar, "number")); + EXPECT_TRUE(HasSpan('f', 'j', baz)); + EXPECT_TRUE(HasSpan('f', 'g', baz, "name")); + EXPECT_TRUE(HasSpan('h', 'i', baz, "number")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.enum_type(0))); + EXPECT_TRUE(HasSpan(file_.enum_type(0), "name")); +} + +TEST_F(SourceInfoTest, NestedEnums) { + EXPECT_TRUE(Parse( + "message Foo {\n" + " $a$enum $b$Bar$c$ {}$d$\n" + " $e$enum $f$Baz$g$ {}$h$\n" + "}\n")); + + const EnumDescriptorProto& bar = file_.message_type(0).enum_type(0); + const EnumDescriptorProto& baz = file_.message_type(0).enum_type(1); + + EXPECT_TRUE(HasSpan('a', 'd', bar)); + EXPECT_TRUE(HasSpan('b', 'c', bar, "name")); + EXPECT_TRUE(HasSpan('e', 'h', baz)); + EXPECT_TRUE(HasSpan('f', 'g', baz, "name")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); +} + +TEST_F(SourceInfoTest, Services) { + EXPECT_TRUE(Parse( + "$a$service $b$Foo$c$ {}$d$\n" + "$e$service $f$Bar$g$ {}$h$\n")); + + EXPECT_TRUE(HasSpan('a', 'd', file_.service(0))); + EXPECT_TRUE(HasSpan('b', 'c', file_.service(0), "name")); + EXPECT_TRUE(HasSpan('e', 'h', file_.service(1))); + EXPECT_TRUE(HasSpan('f', 'g', file_.service(1), "name")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); +} + +TEST_F(SourceInfoTest, MethodsAndStreams) { + EXPECT_TRUE(Parse( + "service Foo {\n" + " $a$rpc $b$Bar$c$($d$X$e$) returns($f$Y$g$);$h$" + " $i$rpc $j$Baz$k$($l$Z$m$) returns($n$W$o$);$p$" + "}")); + + const MethodDescriptorProto& bar = file_.service(0).method(0); + const MethodDescriptorProto& baz = file_.service(0).method(1); + + EXPECT_TRUE(HasSpan('a', 'h', bar)); + EXPECT_TRUE(HasSpan('b', 'c', bar, "name")); + EXPECT_TRUE(HasSpan('d', 'e', bar, "input_type")); + EXPECT_TRUE(HasSpan('f', 'g', bar, "output_type")); + + EXPECT_TRUE(HasSpan('i', 'p', baz)); + EXPECT_TRUE(HasSpan('j', 'k', baz, "name")); + EXPECT_TRUE(HasSpan('l', 'm', baz, "input_type")); + EXPECT_TRUE(HasSpan('n', 'o', baz, "output_type")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.service(0))); + EXPECT_TRUE(HasSpan(file_.service(0), "name")); +} + +TEST_F(SourceInfoTest, Options) { + EXPECT_TRUE(Parse( + "$a$option $b$foo$c$.$d$($e$bar.baz$f$)$g$ = " + "$h$123$i$;$j$\n" + "$k$option qux = $l$-123$m$;$n$\n" + "$o$option corge = $p$abc$q$;$r$\n" + "$s$option grault = $t$'blah'$u$;$v$\n" + "$w$option garply = $x${ yadda yadda }$y$;$z$\n" + "$0$option waldo = $1$123.0$2$;$3$\n" + )); + + const UninterpretedOption& option1 = file_.options().uninterpreted_option(0); + const UninterpretedOption& option2 = file_.options().uninterpreted_option(1); + const UninterpretedOption& option3 = file_.options().uninterpreted_option(2); + const UninterpretedOption& option4 = file_.options().uninterpreted_option(3); + const UninterpretedOption& option5 = file_.options().uninterpreted_option(4); + const UninterpretedOption& option6 = file_.options().uninterpreted_option(5); + + EXPECT_TRUE(HasSpan('a', 'j', file_.options())); + EXPECT_TRUE(HasSpan('a', 'j', option1)); + EXPECT_TRUE(HasSpan('b', 'g', option1, "name")); + EXPECT_TRUE(HasSpan('b', 'c', option1.name(0))); + EXPECT_TRUE(HasSpan('b', 'c', option1.name(0), "name_part")); + EXPECT_TRUE(HasSpan('d', 'g', option1.name(1))); + EXPECT_TRUE(HasSpan('e', 'f', option1.name(1), "name_part")); + EXPECT_TRUE(HasSpan('h', 'i', option1, "positive_int_value")); + + EXPECT_TRUE(HasSpan('k', 'n', file_.options())); + EXPECT_TRUE(HasSpan('l', 'm', option2, "negative_int_value")); + + EXPECT_TRUE(HasSpan('o', 'r', file_.options())); + EXPECT_TRUE(HasSpan('p', 'q', option3, "identifier_value")); + + EXPECT_TRUE(HasSpan('s', 'v', file_.options())); + EXPECT_TRUE(HasSpan('t', 'u', option4, "string_value")); + + EXPECT_TRUE(HasSpan('w', 'z', file_.options())); + EXPECT_TRUE(HasSpan('x', 'y', option5, "aggregate_value")); + + EXPECT_TRUE(HasSpan('0', '3', file_.options())); + EXPECT_TRUE(HasSpan('1', '2', option6, "double_value")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(option2)); + EXPECT_TRUE(HasSpan(option3)); + EXPECT_TRUE(HasSpan(option4)); + EXPECT_TRUE(HasSpan(option5)); + EXPECT_TRUE(HasSpan(option6)); + EXPECT_TRUE(HasSpan(option2, "name")); + EXPECT_TRUE(HasSpan(option3, "name")); + EXPECT_TRUE(HasSpan(option4, "name")); + EXPECT_TRUE(HasSpan(option5, "name")); + EXPECT_TRUE(HasSpan(option6, "name")); + EXPECT_TRUE(HasSpan(option2.name(0))); + EXPECT_TRUE(HasSpan(option3.name(0))); + EXPECT_TRUE(HasSpan(option4.name(0))); + EXPECT_TRUE(HasSpan(option5.name(0))); + EXPECT_TRUE(HasSpan(option6.name(0))); + EXPECT_TRUE(HasSpan(option2.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option3.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option4.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option5.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option6.name(0), "name_part")); +} + +TEST_F(SourceInfoTest, ScopedOptions) { + EXPECT_TRUE(Parse( + "message Foo {\n" + " $a$option mopt = 1;$b$\n" + "}\n" + "enum Bar {\n" + " $c$option eopt = 1;$d$\n" + "}\n" + "service Baz {\n" + " $e$option sopt = 1;$f$\n" + " rpc M(X) returns(Y) {\n" + " $g$option mopt = 1;$h$\n" + " }\n" + "}\n")); + + EXPECT_TRUE(HasSpan('a', 'b', file_.message_type(0).options())); + EXPECT_TRUE(HasSpan('c', 'd', file_.enum_type(0).options())); + EXPECT_TRUE(HasSpan('e', 'f', file_.service(0).options())); + EXPECT_TRUE(HasSpan('g', 'h', file_.service(0).method(0).options())); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); + EXPECT_TRUE(HasSpan(file_.message_type(0).options() + .uninterpreted_option(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0).options() + .uninterpreted_option(0), "name")); + EXPECT_TRUE(HasSpan(file_.message_type(0).options() + .uninterpreted_option(0).name(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0).options() + .uninterpreted_option(0).name(0), "name_part")); + EXPECT_TRUE(HasSpan(file_.message_type(0).options() + .uninterpreted_option(0), "positive_int_value")); + EXPECT_TRUE(HasSpan(file_.enum_type(0))); + EXPECT_TRUE(HasSpan(file_.enum_type(0), "name")); + EXPECT_TRUE(HasSpan(file_.enum_type(0).options() + .uninterpreted_option(0))); + EXPECT_TRUE(HasSpan(file_.enum_type(0).options() + .uninterpreted_option(0), "name")); + EXPECT_TRUE(HasSpan(file_.enum_type(0).options() + .uninterpreted_option(0).name(0))); + EXPECT_TRUE(HasSpan(file_.enum_type(0).options() + .uninterpreted_option(0).name(0), "name_part")); + EXPECT_TRUE(HasSpan(file_.enum_type(0).options() + .uninterpreted_option(0), "positive_int_value")); + EXPECT_TRUE(HasSpan(file_.service(0))); + EXPECT_TRUE(HasSpan(file_.service(0), "name")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0))); + EXPECT_TRUE(HasSpan(file_.service(0).options() + .uninterpreted_option(0))); + EXPECT_TRUE(HasSpan(file_.service(0).options() + .uninterpreted_option(0), "name")); + EXPECT_TRUE(HasSpan(file_.service(0).options() + .uninterpreted_option(0).name(0))); + EXPECT_TRUE(HasSpan(file_.service(0).options() + .uninterpreted_option(0).name(0), "name_part")); + EXPECT_TRUE(HasSpan(file_.service(0).options() + .uninterpreted_option(0), "positive_int_value")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0), "name")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0), "input_type")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0), "output_type")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() + .uninterpreted_option(0))); + EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() + .uninterpreted_option(0), "name")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() + .uninterpreted_option(0).name(0))); + EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() + .uninterpreted_option(0).name(0), "name_part")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() + .uninterpreted_option(0), "positive_int_value")); +} + +TEST_F(SourceInfoTest, FieldOptions) { + // The actual "name = value" pairs are parsed by the same code as for + // top-level options so we won't re-test that -- just make sure that the + // syntax used for field options is understood. + EXPECT_TRUE(Parse( + "message Foo {" + " optional int32 bar = 1 " + "$a$[default=$b$123$c$,$d$opt1=123$e$," + "$f$opt2='hi'$g$]$h$;" + "}\n" + )); + + const FieldDescriptorProto& field = file_.message_type(0).field(0); + const UninterpretedOption& option1 = field.options().uninterpreted_option(0); + const UninterpretedOption& option2 = field.options().uninterpreted_option(1); + + EXPECT_TRUE(HasSpan('a', 'h', field.options())); + EXPECT_TRUE(HasSpan('b', 'c', field, "default_value")); + EXPECT_TRUE(HasSpan('d', 'e', option1)); + EXPECT_TRUE(HasSpan('f', 'g', option2)); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); + EXPECT_TRUE(HasSpan(field)); + EXPECT_TRUE(HasSpan(field, "label")); + EXPECT_TRUE(HasSpan(field, "type")); + EXPECT_TRUE(HasSpan(field, "name")); + EXPECT_TRUE(HasSpan(field, "number")); + EXPECT_TRUE(HasSpan(option1, "name")); + EXPECT_TRUE(HasSpan(option2, "name")); + EXPECT_TRUE(HasSpan(option1.name(0))); + EXPECT_TRUE(HasSpan(option2.name(0))); + EXPECT_TRUE(HasSpan(option1.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option2.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option1, "positive_int_value")); + EXPECT_TRUE(HasSpan(option2, "string_value")); +} + +TEST_F(SourceInfoTest, EnumValueOptions) { + // The actual "name = value" pairs are parsed by the same code as for + // top-level options so we won't re-test that -- just make sure that the + // syntax used for enum options is understood. + EXPECT_TRUE(Parse( + "enum Foo {" + " BAR = 1 $a$[$b$opt1=123$c$,$d$opt2='hi'$e$]$f$;" + "}\n" + )); + + const EnumValueDescriptorProto& value = file_.enum_type(0).value(0); + const UninterpretedOption& option1 = value.options().uninterpreted_option(0); + const UninterpretedOption& option2 = value.options().uninterpreted_option(1); + + EXPECT_TRUE(HasSpan('a', 'f', value.options())); + EXPECT_TRUE(HasSpan('b', 'c', option1)); + EXPECT_TRUE(HasSpan('d', 'e', option2)); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.enum_type(0))); + EXPECT_TRUE(HasSpan(file_.enum_type(0), "name")); + EXPECT_TRUE(HasSpan(value)); + EXPECT_TRUE(HasSpan(value, "name")); + EXPECT_TRUE(HasSpan(value, "number")); + EXPECT_TRUE(HasSpan(option1, "name")); + EXPECT_TRUE(HasSpan(option2, "name")); + EXPECT_TRUE(HasSpan(option1.name(0))); + EXPECT_TRUE(HasSpan(option2.name(0))); + EXPECT_TRUE(HasSpan(option1.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option2.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option1, "positive_int_value")); + EXPECT_TRUE(HasSpan(option2, "string_value")); +} + +TEST_F(SourceInfoTest, DocComments) { + EXPECT_TRUE(Parse( + "// Foo leading\n" + "// line 2\n" + "$a$message Foo {\n" + " // Foo trailing\n" + " // line 2\n" + "\n" + " // ignored\n" + "\n" + " // bar leading\n" + " $b$optional int32 bar = 1;$c$\n" + " // bar trailing\n" + "}$d$\n" + "// ignored\n" + )); + + const DescriptorProto& foo = file_.message_type(0); + const FieldDescriptorProto& bar = foo.field(0); + + EXPECT_TRUE(HasSpanWithComment('a', 'd', foo, + " Foo leading\n line 2\n", + " Foo trailing\n line 2\n")); + EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, + " bar leading\n", + " bar trailing\n")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(foo, "name")); + EXPECT_TRUE(HasSpan(bar, "label")); + EXPECT_TRUE(HasSpan(bar, "type")); + EXPECT_TRUE(HasSpan(bar, "name")); + EXPECT_TRUE(HasSpan(bar, "number")); +} + +TEST_F(SourceInfoTest, DocComments2) { + EXPECT_TRUE(Parse( + "// ignored\n" + "syntax = \"proto2\";\n" + "// Foo leading\n" + "// line 2\n" + "$a$message Foo {\n" + " /* Foo trailing\n" + " * line 2 */\n" + " // ignored\n" + " /* bar leading\n" + " */" + " $b$optional int32 bar = 1;$c$ // bar trailing\n" + " // ignored\n" + "}$d$\n" + "// ignored\n" + "\n" + "// option leading\n" + "$e$option baz = 123;$f$\n" + "// option trailing\n" + )); + + const DescriptorProto& foo = file_.message_type(0); + const FieldDescriptorProto& bar = foo.field(0); + const UninterpretedOption& baz = file_.options().uninterpreted_option(0); + + EXPECT_TRUE(HasSpanWithComment('a', 'd', foo, + " Foo leading\n line 2\n", + " Foo trailing\n line 2 ")); + EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, + " bar leading\n", + " bar trailing\n")); + EXPECT_TRUE(HasSpanWithComment('e', 'f', baz, + " option leading\n", + " option trailing\n")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(foo, "name")); + EXPECT_TRUE(HasSpan(bar, "label")); + EXPECT_TRUE(HasSpan(bar, "type")); + EXPECT_TRUE(HasSpan(bar, "name")); + EXPECT_TRUE(HasSpan(bar, "number")); + EXPECT_TRUE(HasSpan(file_.options())); + EXPECT_TRUE(HasSpan(baz, "name")); + EXPECT_TRUE(HasSpan(baz.name(0))); + EXPECT_TRUE(HasSpan(baz.name(0), "name_part")); + EXPECT_TRUE(HasSpan(baz, "positive_int_value")); +} + +TEST_F(SourceInfoTest, DocComments3) { + EXPECT_TRUE(Parse( + "$a$message Foo {\n" + " // bar leading\n" + " $b$optional int32 bar = 1 [(baz.qux) = {}];$c$\n" + " // bar trailing\n" + "}$d$\n" + "// ignored\n" + )); + + const DescriptorProto& foo = file_.message_type(0); + const FieldDescriptorProto& bar = foo.field(0); + + EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, + " bar leading\n", + " bar trailing\n")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(foo)); + EXPECT_TRUE(HasSpan(foo, "name")); + EXPECT_TRUE(HasSpan(bar, "label")); + EXPECT_TRUE(HasSpan(bar, "type")); + EXPECT_TRUE(HasSpan(bar, "name")); + EXPECT_TRUE(HasSpan(bar, "number")); + EXPECT_TRUE(HasSpan(bar.options())); + EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0))); + EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0), "name")); + EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0).name(0))); + EXPECT_TRUE(HasSpan( + bar.options().uninterpreted_option(0).name(0), "name_part")); + EXPECT_TRUE(HasSpan( + bar.options().uninterpreted_option(0), "aggregate_value")); +} + +// =================================================================== + +} // anonymous namespace + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.cc new file mode 100644 index 0000000..727f942 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.cc @@ -0,0 +1,163 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include + +#include +#include + +#ifdef _WIN32 +#include +#include +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif +#else +#include +#endif + +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace compiler { + +class GeneratorResponseContext : public GeneratorContext { + public: + GeneratorResponseContext(CodeGeneratorResponse* response, + const vector& parsed_files) + : response_(response), + parsed_files_(parsed_files) {} + virtual ~GeneratorResponseContext() {} + + // implements GeneratorContext -------------------------------------- + + virtual io::ZeroCopyOutputStream* Open(const string& filename) { + CodeGeneratorResponse::File* file = response_->add_file(); + file->set_name(filename); + return new io::StringOutputStream(file->mutable_content()); + } + + virtual io::ZeroCopyOutputStream* OpenForInsert( + const string& filename, const string& insertion_point) { + CodeGeneratorResponse::File* file = response_->add_file(); + file->set_name(filename); + file->set_insertion_point(insertion_point); + return new io::StringOutputStream(file->mutable_content()); + } + + void ListParsedFiles(vector* output) { + *output = parsed_files_; + } + + private: + CodeGeneratorResponse* response_; + const vector& parsed_files_; +}; + +int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { + + if (argc > 1) { + cerr << argv[0] << ": Unknown option: " << argv[1] << endl; + return 1; + } + +#ifdef _WIN32 + _setmode(STDIN_FILENO, _O_BINARY); + _setmode(STDOUT_FILENO, _O_BINARY); +#endif + + CodeGeneratorRequest request; + if (!request.ParseFromFileDescriptor(STDIN_FILENO)) { + cerr << argv[0] << ": protoc sent unparseable request to plugin." << endl; + return 1; + } + + DescriptorPool pool; + for (int i = 0; i < request.proto_file_size(); i++) { + const FileDescriptor* file = pool.BuildFile(request.proto_file(i)); + if (file == NULL) { + // BuildFile() already wrote an error message. + return 1; + } + } + + vector parsed_files; + for (int i = 0; i < request.file_to_generate_size(); i++) { + parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i))); + if (parsed_files.back() == NULL) { + cerr << argv[0] << ": protoc asked plugin to generate a file but " + "did not provide a descriptor for the file: " + << request.file_to_generate(i) << endl; + return 1; + } + } + + CodeGeneratorResponse response; + GeneratorResponseContext context(&response, parsed_files); + + for (int i = 0; i < parsed_files.size(); i++) { + const FileDescriptor* file = parsed_files[i]; + + string error; + bool succeeded = generator->Generate( + file, request.parameter(), &context, &error); + + if (!succeeded && error.empty()) { + error = "Code generator returned false but provided no error " + "description."; + } + if (!error.empty()) { + response.set_error(file->name() + ": " + error); + break; + } + } + + if (!response.SerializeToFileDescriptor(STDOUT_FILENO)) { + cerr << argv[0] << ": Error writing to stdout." << endl; + return 1; + } + + return 0; +} + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.h new file mode 100644 index 0000000..6fa2de1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.h @@ -0,0 +1,72 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// Front-end for protoc code generator plugins written in C++. +// +// To implement a protoc plugin in C++, simply write an implementation of +// CodeGenerator, then create a main() function like: +// int main(int argc, char* argv[]) { +// MyCodeGenerator generator; +// return google::protobuf::compiler::PluginMain(argc, argv, &generator); +// } +// You must link your plugin against libprotobuf and libprotoc. +// +// To get protoc to use the plugin, do one of the following: +// * Place the plugin binary somewhere in the PATH and give it the name +// "protoc-gen-NAME" (replacing "NAME" with the name of your plugin). If you +// then invoke protoc with the parameter --NAME_out=OUT_DIR (again, replace +// "NAME" with your plugin's name), protoc will invoke your plugin to generate +// the output, which will be placed in OUT_DIR. +// * Place the plugin binary anywhere, with any name, and pass the --plugin +// parameter to protoc to direct it to your plugin like so: +// protoc --plugin=protoc-gen-NAME=path/to/mybinary --NAME_out=OUT_DIR +// On Windows, make sure to include the .exe suffix: +// protoc --plugin=protoc-gen-NAME=path/to/mybinary.exe --NAME_out=OUT_DIR + +#ifndef GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__ +#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__ + +#include +namespace google { +namespace protobuf { +namespace compiler { + +class CodeGenerator; // code_generator.h + +// Implements main() for a protoc plugin exposing the given code generator. +LIBPROTOC_EXPORT int PluginMain(int argc, char* argv[], const CodeGenerator* generator); + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.pb.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.pb.cc new file mode 100644 index 0000000..ee14dcf --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.pb.cc @@ -0,0 +1,1090 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/compiler/plugin.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/compiler/plugin.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { +namespace compiler { + +namespace { + +const ::google::protobuf::Descriptor* CodeGeneratorRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + CodeGeneratorRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* CodeGeneratorResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + CodeGeneratorResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* CodeGeneratorResponse_File_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + CodeGeneratorResponse_File_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/compiler/plugin.proto"); + GOOGLE_CHECK(file != NULL); + CodeGeneratorRequest_descriptor_ = file->message_type(0); + static const int CodeGeneratorRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, file_to_generate_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, parameter_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, proto_file_), + }; + CodeGeneratorRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + CodeGeneratorRequest_descriptor_, + CodeGeneratorRequest::default_instance_, + CodeGeneratorRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(CodeGeneratorRequest)); + CodeGeneratorResponse_descriptor_ = file->message_type(1); + static const int CodeGeneratorResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, error_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, file_), + }; + CodeGeneratorResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + CodeGeneratorResponse_descriptor_, + CodeGeneratorResponse::default_instance_, + CodeGeneratorResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(CodeGeneratorResponse)); + CodeGeneratorResponse_File_descriptor_ = CodeGeneratorResponse_descriptor_->nested_type(0); + static const int CodeGeneratorResponse_File_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, insertion_point_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, content_), + }; + CodeGeneratorResponse_File_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + CodeGeneratorResponse_File_descriptor_, + CodeGeneratorResponse_File::default_instance_, + CodeGeneratorResponse_File_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(CodeGeneratorResponse_File)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + CodeGeneratorRequest_descriptor_, &CodeGeneratorRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + CodeGeneratorResponse_descriptor_, &CodeGeneratorResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + CodeGeneratorResponse_File_descriptor_, &CodeGeneratorResponse_File::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { + delete CodeGeneratorRequest::default_instance_; + delete CodeGeneratorRequest_reflection_; + delete CodeGeneratorResponse::default_instance_; + delete CodeGeneratorResponse_reflection_; + delete CodeGeneratorResponse_File::default_instance_; + delete CodeGeneratorResponse_File_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n%google/protobuf/compiler/plugin.proto\022" + "\030google.protobuf.compiler\032 google/protob" + "uf/descriptor.proto\"}\n\024CodeGeneratorRequ" + "est\022\030\n\020file_to_generate\030\001 \003(\t\022\021\n\tparamet" + "er\030\002 \001(\t\0228\n\nproto_file\030\017 \003(\0132$.google.pr" + "otobuf.FileDescriptorProto\"\252\001\n\025CodeGener" + "atorResponse\022\r\n\005error\030\001 \001(\t\022B\n\004file\030\017 \003(" + "\01324.google.protobuf.compiler.CodeGenerat" + "orResponse.File\032>\n\004File\022\014\n\004name\030\001 \001(\t\022\027\n" + "\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\tB" + ",\n\034com.google.protobuf.compilerB\014PluginP" + "rotos", 445); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes); + CodeGeneratorRequest::default_instance_ = new CodeGeneratorRequest(); + CodeGeneratorResponse::default_instance_ = new CodeGeneratorResponse(); + CodeGeneratorResponse_File::default_instance_ = new CodeGeneratorResponse_File(); + CodeGeneratorRequest::default_instance_->InitAsDefaultInstance(); + CodeGeneratorResponse::default_instance_->InitAsDefaultInstance(); + CodeGeneratorResponse_File::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto_; + +// =================================================================== + +#ifndef _MSC_VER +const int CodeGeneratorRequest::kFileToGenerateFieldNumber; +const int CodeGeneratorRequest::kParameterFieldNumber; +const int CodeGeneratorRequest::kProtoFileFieldNumber; +#endif // !_MSC_VER + +CodeGeneratorRequest::CodeGeneratorRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void CodeGeneratorRequest::InitAsDefaultInstance() { +} + +CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void CodeGeneratorRequest::SharedCtor() { + _cached_size_ = 0; + parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CodeGeneratorRequest::~CodeGeneratorRequest() { + SharedDtor(); +} + +void CodeGeneratorRequest::SharedDtor() { + if (parameter_ != &::google::protobuf::internal::kEmptyString) { + delete parameter_; + } + if (this != default_instance_) { + } +} + +void CodeGeneratorRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return CodeGeneratorRequest_descriptor_; +} + +const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + return *default_instance_; +} + +CodeGeneratorRequest* CodeGeneratorRequest::default_instance_ = NULL; + +CodeGeneratorRequest* CodeGeneratorRequest::New() const { + return new CodeGeneratorRequest; +} + +void CodeGeneratorRequest::Clear() { + if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { + if (has_parameter()) { + if (parameter_ != &::google::protobuf::internal::kEmptyString) { + parameter_->clear(); + } + } + } + file_to_generate_.Clear(); + proto_file_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool CodeGeneratorRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string file_to_generate = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_to_generate: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_file_to_generate())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_to_generate(this->file_to_generate_size() - 1).data(), + this->file_to_generate(this->file_to_generate_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_file_to_generate; + if (input->ExpectTag(18)) goto parse_parameter; + break; + } + + // optional string parameter = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_parameter: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_parameter())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->parameter().data(), this->parameter().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(122)) goto parse_proto_file; + break; + } + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + case 15: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_proto_file: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_proto_file())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(122)) goto parse_proto_file; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void CodeGeneratorRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated string file_to_generate = 1; + for (int i = 0; i < this->file_to_generate_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_to_generate(i).data(), this->file_to_generate(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_to_generate(i), output); + } + + // optional string parameter = 2; + if (has_parameter()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->parameter().data(), this->parameter().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->parameter(), output); + } + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + for (int i = 0; i < this->proto_file_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 15, this->proto_file(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* CodeGeneratorRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated string file_to_generate = 1; + for (int i = 0; i < this->file_to_generate_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_to_generate(i).data(), this->file_to_generate(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->file_to_generate(i), target); + } + + // optional string parameter = 2; + if (has_parameter()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->parameter().data(), this->parameter().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->parameter(), target); + } + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + for (int i = 0; i < this->proto_file_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 15, this->proto_file(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int CodeGeneratorRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { + // optional string parameter = 2; + if (has_parameter()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->parameter()); + } + + } + // repeated string file_to_generate = 1; + total_size += 1 * this->file_to_generate_size(); + for (int i = 0; i < this->file_to_generate_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_to_generate(i)); + } + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + total_size += 1 * this->proto_file_size(); + for (int i = 0; i < this->proto_file_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->proto_file(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const CodeGeneratorRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) { + GOOGLE_CHECK_NE(&from, this); + file_to_generate_.MergeFrom(from.file_to_generate_); + proto_file_.MergeFrom(from.proto_file_); + if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) { + if (from.has_parameter()) { + set_parameter(from.parameter()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void CodeGeneratorRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CodeGeneratorRequest::IsInitialized() const { + + for (int i = 0; i < proto_file_size(); i++) { + if (!this->proto_file(i).IsInitialized()) return false; + } + return true; +} + +void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) { + if (other != this) { + file_to_generate_.Swap(&other->file_to_generate_); + std::swap(parameter_, other->parameter_); + proto_file_.Swap(&other->proto_file_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = CodeGeneratorRequest_descriptor_; + metadata.reflection = CodeGeneratorRequest_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CodeGeneratorResponse_File::kNameFieldNumber; +const int CodeGeneratorResponse_File::kInsertionPointFieldNumber; +const int CodeGeneratorResponse_File::kContentFieldNumber; +#endif // !_MSC_VER + +CodeGeneratorResponse_File::CodeGeneratorResponse_File() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void CodeGeneratorResponse_File::InitAsDefaultInstance() { +} + +CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void CodeGeneratorResponse_File::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + content_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CodeGeneratorResponse_File::~CodeGeneratorResponse_File() { + SharedDtor(); +} + +void CodeGeneratorResponse_File::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (insertion_point_ != &::google::protobuf::internal::kEmptyString) { + delete insertion_point_; + } + if (content_ != &::google::protobuf::internal::kEmptyString) { + delete content_; + } + if (this != default_instance_) { + } +} + +void CodeGeneratorResponse_File::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() { + protobuf_AssignDescriptorsOnce(); + return CodeGeneratorResponse_File_descriptor_; +} + +const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + return *default_instance_; +} + +CodeGeneratorResponse_File* CodeGeneratorResponse_File::default_instance_ = NULL; + +CodeGeneratorResponse_File* CodeGeneratorResponse_File::New() const { + return new CodeGeneratorResponse_File; +} + +void CodeGeneratorResponse_File::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_insertion_point()) { + if (insertion_point_ != &::google::protobuf::internal::kEmptyString) { + insertion_point_->clear(); + } + } + if (has_content()) { + if (content_ != &::google::protobuf::internal::kEmptyString) { + content_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool CodeGeneratorResponse_File::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_insertion_point; + break; + } + + // optional string insertion_point = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_insertion_point: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_insertion_point())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->insertion_point().data(), this->insertion_point().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(122)) goto parse_content; + break; + } + + // optional string content = 15; + case 15: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_content: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_content())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->content().data(), this->content().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void CodeGeneratorResponse_File::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // optional string insertion_point = 2; + if (has_insertion_point()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->insertion_point().data(), this->insertion_point().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->insertion_point(), output); + } + + // optional string content = 15; + if (has_content()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->content().data(), this->content().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 15, this->content(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* CodeGeneratorResponse_File::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional string insertion_point = 2; + if (has_insertion_point()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->insertion_point().data(), this->insertion_point().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->insertion_point(), target); + } + + // optional string content = 15; + if (has_content()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->content().data(), this->content().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 15, this->content(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int CodeGeneratorResponse_File::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional string insertion_point = 2; + if (has_insertion_point()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->insertion_point()); + } + + // optional string content = 15; + if (has_content()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->content()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const CodeGeneratorResponse_File* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_insertion_point()) { + set_insertion_point(from.insertion_point()); + } + if (from.has_content()) { + set_content(from.content()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void CodeGeneratorResponse_File::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void CodeGeneratorResponse_File::CopyFrom(const CodeGeneratorResponse_File& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CodeGeneratorResponse_File::IsInitialized() const { + + return true; +} + +void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(insertion_point_, other->insertion_point_); + std::swap(content_, other->content_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = CodeGeneratorResponse_File_descriptor_; + metadata.reflection = CodeGeneratorResponse_File_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#ifndef _MSC_VER +const int CodeGeneratorResponse::kErrorFieldNumber; +const int CodeGeneratorResponse::kFileFieldNumber; +#endif // !_MSC_VER + +CodeGeneratorResponse::CodeGeneratorResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void CodeGeneratorResponse::InitAsDefaultInstance() { +} + +CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void CodeGeneratorResponse::SharedCtor() { + _cached_size_ = 0; + error_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CodeGeneratorResponse::~CodeGeneratorResponse() { + SharedDtor(); +} + +void CodeGeneratorResponse::SharedDtor() { + if (error_ != &::google::protobuf::internal::kEmptyString) { + delete error_; + } + if (this != default_instance_) { + } +} + +void CodeGeneratorResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return CodeGeneratorResponse_descriptor_; +} + +const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + return *default_instance_; +} + +CodeGeneratorResponse* CodeGeneratorResponse::default_instance_ = NULL; + +CodeGeneratorResponse* CodeGeneratorResponse::New() const { + return new CodeGeneratorResponse; +} + +void CodeGeneratorResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_error()) { + if (error_ != &::google::protobuf::internal::kEmptyString) { + error_->clear(); + } + } + } + file_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool CodeGeneratorResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string error = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_error())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->error().data(), this->error().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(122)) goto parse_file; + break; + } + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + case 15: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_file())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(122)) goto parse_file; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void CodeGeneratorResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string error = 1; + if (has_error()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->error().data(), this->error().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->error(), output); + } + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + for (int i = 0; i < this->file_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 15, this->file(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* CodeGeneratorResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string error = 1; + if (has_error()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->error().data(), this->error().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->error(), target); + } + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + for (int i = 0; i < this->file_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 15, this->file(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int CodeGeneratorResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string error = 1; + if (has_error()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->error()); + } + + } + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + total_size += 1 * this->file_size(); + for (int i = 0; i < this->file_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const CodeGeneratorResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) { + GOOGLE_CHECK_NE(&from, this); + file_.MergeFrom(from.file_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_error()) { + set_error(from.error()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void CodeGeneratorResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void CodeGeneratorResponse::CopyFrom(const CodeGeneratorResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CodeGeneratorResponse::IsInitialized() const { + + return true; +} + +void CodeGeneratorResponse::Swap(CodeGeneratorResponse* other) { + if (other != this) { + std::swap(error_, other->error_); + file_.Swap(&other->file_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = CodeGeneratorResponse_descriptor_; + metadata.reflection = CodeGeneratorResponse_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace compiler +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.pb.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.pb.h new file mode 100644 index 0000000..68cc21c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.pb.h @@ -0,0 +1,856 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/compiler/plugin.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include "google/protobuf/descriptor.pb.h" +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { +namespace compiler { + +// Internal implementation detail -- do not call these. +void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + +class CodeGeneratorRequest; +class CodeGeneratorResponse; +class CodeGeneratorResponse_File; + +// =================================================================== + +class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message { + public: + CodeGeneratorRequest(); + virtual ~CodeGeneratorRequest(); + + CodeGeneratorRequest(const CodeGeneratorRequest& from); + + inline CodeGeneratorRequest& operator=(const CodeGeneratorRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CodeGeneratorRequest& default_instance(); + + void Swap(CodeGeneratorRequest* other); + + // implements Message ---------------------------------------------- + + CodeGeneratorRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CodeGeneratorRequest& from); + void MergeFrom(const CodeGeneratorRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string file_to_generate = 1; + inline int file_to_generate_size() const; + inline void clear_file_to_generate(); + static const int kFileToGenerateFieldNumber = 1; + inline const ::std::string& file_to_generate(int index) const; + inline ::std::string* mutable_file_to_generate(int index); + inline void set_file_to_generate(int index, const ::std::string& value); + inline void set_file_to_generate(int index, const char* value); + inline void set_file_to_generate(int index, const char* value, size_t size); + inline ::std::string* add_file_to_generate(); + inline void add_file_to_generate(const ::std::string& value); + inline void add_file_to_generate(const char* value); + inline void add_file_to_generate(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_to_generate(); + + // optional string parameter = 2; + inline bool has_parameter() const; + inline void clear_parameter(); + static const int kParameterFieldNumber = 2; + inline const ::std::string& parameter() const; + inline void set_parameter(const ::std::string& value); + inline void set_parameter(const char* value); + inline void set_parameter(const char* value, size_t size); + inline ::std::string* mutable_parameter(); + inline ::std::string* release_parameter(); + inline void set_allocated_parameter(::std::string* parameter); + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + inline int proto_file_size() const; + inline void clear_proto_file(); + static const int kProtoFileFieldNumber = 15; + inline const ::google::protobuf::FileDescriptorProto& proto_file(int index) const; + inline ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index); + inline ::google::protobuf::FileDescriptorProto* add_proto_file(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& + proto_file() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* + mutable_proto_file(); + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) + private: + inline void set_has_parameter(); + inline void clear_has_parameter(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_; + ::std::string* parameter_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + + void InitAsDefaultInstance(); + static CodeGeneratorRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::Message { + public: + CodeGeneratorResponse_File(); + virtual ~CodeGeneratorResponse_File(); + + CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from); + + inline CodeGeneratorResponse_File& operator=(const CodeGeneratorResponse_File& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CodeGeneratorResponse_File& default_instance(); + + void Swap(CodeGeneratorResponse_File* other); + + // implements Message ---------------------------------------------- + + CodeGeneratorResponse_File* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CodeGeneratorResponse_File& from); + void MergeFrom(const CodeGeneratorResponse_File& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // optional string insertion_point = 2; + inline bool has_insertion_point() const; + inline void clear_insertion_point(); + static const int kInsertionPointFieldNumber = 2; + inline const ::std::string& insertion_point() const; + inline void set_insertion_point(const ::std::string& value); + inline void set_insertion_point(const char* value); + inline void set_insertion_point(const char* value, size_t size); + inline ::std::string* mutable_insertion_point(); + inline ::std::string* release_insertion_point(); + inline void set_allocated_insertion_point(::std::string* insertion_point); + + // optional string content = 15; + inline bool has_content() const; + inline void clear_content(); + static const int kContentFieldNumber = 15; + inline const ::std::string& content() const; + inline void set_content(const ::std::string& value); + inline void set_content(const char* value); + inline void set_content(const char* value, size_t size); + inline ::std::string* mutable_content(); + inline ::std::string* release_content(); + inline void set_allocated_content(::std::string* content); + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_insertion_point(); + inline void clear_has_insertion_point(); + inline void set_has_content(); + inline void clear_has_content(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::std::string* insertion_point_; + ::std::string* content_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + + void InitAsDefaultInstance(); + static CodeGeneratorResponse_File* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Message { + public: + CodeGeneratorResponse(); + virtual ~CodeGeneratorResponse(); + + CodeGeneratorResponse(const CodeGeneratorResponse& from); + + inline CodeGeneratorResponse& operator=(const CodeGeneratorResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CodeGeneratorResponse& default_instance(); + + void Swap(CodeGeneratorResponse* other); + + // implements Message ---------------------------------------------- + + CodeGeneratorResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CodeGeneratorResponse& from); + void MergeFrom(const CodeGeneratorResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef CodeGeneratorResponse_File File; + + // accessors ------------------------------------------------------- + + // optional string error = 1; + inline bool has_error() const; + inline void clear_error(); + static const int kErrorFieldNumber = 1; + inline const ::std::string& error() const; + inline void set_error(const ::std::string& value); + inline void set_error(const char* value); + inline void set_error(const char* value, size_t size); + inline ::std::string* mutable_error(); + inline ::std::string* release_error(); + inline void set_allocated_error(::std::string* error); + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + inline int file_size() const; + inline void clear_file(); + static const int kFileFieldNumber = 15; + inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const; + inline ::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index); + inline ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& + file() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* + mutable_file(); + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse) + private: + inline void set_has_error(); + inline void clear_has_error(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* error_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + + void InitAsDefaultInstance(); + static CodeGeneratorResponse* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// CodeGeneratorRequest + +// repeated string file_to_generate = 1; +inline int CodeGeneratorRequest::file_to_generate_size() const { + return file_to_generate_.size(); +} +inline void CodeGeneratorRequest::clear_file_to_generate() { + file_to_generate_.Clear(); +} +inline const ::std::string& CodeGeneratorRequest::file_to_generate(int index) const { + return file_to_generate_.Get(index); +} +inline ::std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) { + return file_to_generate_.Mutable(index); +} +inline void CodeGeneratorRequest::set_file_to_generate(int index, const ::std::string& value) { + file_to_generate_.Mutable(index)->assign(value); +} +inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) { + file_to_generate_.Mutable(index)->assign(value); +} +inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value, size_t size) { + file_to_generate_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* CodeGeneratorRequest::add_file_to_generate() { + return file_to_generate_.Add(); +} +inline void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) { + file_to_generate_.Add()->assign(value); +} +inline void CodeGeneratorRequest::add_file_to_generate(const char* value) { + file_to_generate_.Add()->assign(value); +} +inline void CodeGeneratorRequest::add_file_to_generate(const char* value, size_t size) { + file_to_generate_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +CodeGeneratorRequest::file_to_generate() const { + return file_to_generate_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +CodeGeneratorRequest::mutable_file_to_generate() { + return &file_to_generate_; +} + +// optional string parameter = 2; +inline bool CodeGeneratorRequest::has_parameter() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CodeGeneratorRequest::set_has_parameter() { + _has_bits_[0] |= 0x00000002u; +} +inline void CodeGeneratorRequest::clear_has_parameter() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CodeGeneratorRequest::clear_parameter() { + if (parameter_ != &::google::protobuf::internal::kEmptyString) { + parameter_->clear(); + } + clear_has_parameter(); +} +inline const ::std::string& CodeGeneratorRequest::parameter() const { + return *parameter_; +} +inline void CodeGeneratorRequest::set_parameter(const ::std::string& value) { + set_has_parameter(); + if (parameter_ == &::google::protobuf::internal::kEmptyString) { + parameter_ = new ::std::string; + } + parameter_->assign(value); +} +inline void CodeGeneratorRequest::set_parameter(const char* value) { + set_has_parameter(); + if (parameter_ == &::google::protobuf::internal::kEmptyString) { + parameter_ = new ::std::string; + } + parameter_->assign(value); +} +inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) { + set_has_parameter(); + if (parameter_ == &::google::protobuf::internal::kEmptyString) { + parameter_ = new ::std::string; + } + parameter_->assign(reinterpret_cast(value), size); +} +inline ::std::string* CodeGeneratorRequest::mutable_parameter() { + set_has_parameter(); + if (parameter_ == &::google::protobuf::internal::kEmptyString) { + parameter_ = new ::std::string; + } + return parameter_; +} +inline ::std::string* CodeGeneratorRequest::release_parameter() { + clear_has_parameter(); + if (parameter_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = parameter_; + parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void CodeGeneratorRequest::set_allocated_parameter(::std::string* parameter) { + if (parameter_ != &::google::protobuf::internal::kEmptyString) { + delete parameter_; + } + if (parameter) { + set_has_parameter(); + parameter_ = parameter; + } else { + clear_has_parameter(); + parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// repeated .google.protobuf.FileDescriptorProto proto_file = 15; +inline int CodeGeneratorRequest::proto_file_size() const { + return proto_file_.size(); +} +inline void CodeGeneratorRequest::clear_proto_file() { + proto_file_.Clear(); +} +inline const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const { + return proto_file_.Get(index); +} +inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) { + return proto_file_.Mutable(index); +} +inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() { + return proto_file_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& +CodeGeneratorRequest::proto_file() const { + return proto_file_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* +CodeGeneratorRequest::mutable_proto_file() { + return &proto_file_; +} + +// ------------------------------------------------------------------- + +// CodeGeneratorResponse_File + +// optional string name = 1; +inline bool CodeGeneratorResponse_File::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CodeGeneratorResponse_File::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void CodeGeneratorResponse_File::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CodeGeneratorResponse_File::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& CodeGeneratorResponse_File::name() const { + return *name_; +} +inline void CodeGeneratorResponse_File::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void CodeGeneratorResponse_File::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* CodeGeneratorResponse_File::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* CodeGeneratorResponse_File::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void CodeGeneratorResponse_File::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string insertion_point = 2; +inline bool CodeGeneratorResponse_File::has_insertion_point() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CodeGeneratorResponse_File::set_has_insertion_point() { + _has_bits_[0] |= 0x00000002u; +} +inline void CodeGeneratorResponse_File::clear_has_insertion_point() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CodeGeneratorResponse_File::clear_insertion_point() { + if (insertion_point_ != &::google::protobuf::internal::kEmptyString) { + insertion_point_->clear(); + } + clear_has_insertion_point(); +} +inline const ::std::string& CodeGeneratorResponse_File::insertion_point() const { + return *insertion_point_; +} +inline void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) { + set_has_insertion_point(); + if (insertion_point_ == &::google::protobuf::internal::kEmptyString) { + insertion_point_ = new ::std::string; + } + insertion_point_->assign(value); +} +inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) { + set_has_insertion_point(); + if (insertion_point_ == &::google::protobuf::internal::kEmptyString) { + insertion_point_ = new ::std::string; + } + insertion_point_->assign(value); +} +inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) { + set_has_insertion_point(); + if (insertion_point_ == &::google::protobuf::internal::kEmptyString) { + insertion_point_ = new ::std::string; + } + insertion_point_->assign(reinterpret_cast(value), size); +} +inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() { + set_has_insertion_point(); + if (insertion_point_ == &::google::protobuf::internal::kEmptyString) { + insertion_point_ = new ::std::string; + } + return insertion_point_; +} +inline ::std::string* CodeGeneratorResponse_File::release_insertion_point() { + clear_has_insertion_point(); + if (insertion_point_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = insertion_point_; + insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void CodeGeneratorResponse_File::set_allocated_insertion_point(::std::string* insertion_point) { + if (insertion_point_ != &::google::protobuf::internal::kEmptyString) { + delete insertion_point_; + } + if (insertion_point) { + set_has_insertion_point(); + insertion_point_ = insertion_point; + } else { + clear_has_insertion_point(); + insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string content = 15; +inline bool CodeGeneratorResponse_File::has_content() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CodeGeneratorResponse_File::set_has_content() { + _has_bits_[0] |= 0x00000004u; +} +inline void CodeGeneratorResponse_File::clear_has_content() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CodeGeneratorResponse_File::clear_content() { + if (content_ != &::google::protobuf::internal::kEmptyString) { + content_->clear(); + } + clear_has_content(); +} +inline const ::std::string& CodeGeneratorResponse_File::content() const { + return *content_; +} +inline void CodeGeneratorResponse_File::set_content(const ::std::string& value) { + set_has_content(); + if (content_ == &::google::protobuf::internal::kEmptyString) { + content_ = new ::std::string; + } + content_->assign(value); +} +inline void CodeGeneratorResponse_File::set_content(const char* value) { + set_has_content(); + if (content_ == &::google::protobuf::internal::kEmptyString) { + content_ = new ::std::string; + } + content_->assign(value); +} +inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) { + set_has_content(); + if (content_ == &::google::protobuf::internal::kEmptyString) { + content_ = new ::std::string; + } + content_->assign(reinterpret_cast(value), size); +} +inline ::std::string* CodeGeneratorResponse_File::mutable_content() { + set_has_content(); + if (content_ == &::google::protobuf::internal::kEmptyString) { + content_ = new ::std::string; + } + return content_; +} +inline ::std::string* CodeGeneratorResponse_File::release_content() { + clear_has_content(); + if (content_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = content_; + content_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void CodeGeneratorResponse_File::set_allocated_content(::std::string* content) { + if (content_ != &::google::protobuf::internal::kEmptyString) { + delete content_; + } + if (content) { + set_has_content(); + content_ = content; + } else { + clear_has_content(); + content_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// CodeGeneratorResponse + +// optional string error = 1; +inline bool CodeGeneratorResponse::has_error() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CodeGeneratorResponse::set_has_error() { + _has_bits_[0] |= 0x00000001u; +} +inline void CodeGeneratorResponse::clear_has_error() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CodeGeneratorResponse::clear_error() { + if (error_ != &::google::protobuf::internal::kEmptyString) { + error_->clear(); + } + clear_has_error(); +} +inline const ::std::string& CodeGeneratorResponse::error() const { + return *error_; +} +inline void CodeGeneratorResponse::set_error(const ::std::string& value) { + set_has_error(); + if (error_ == &::google::protobuf::internal::kEmptyString) { + error_ = new ::std::string; + } + error_->assign(value); +} +inline void CodeGeneratorResponse::set_error(const char* value) { + set_has_error(); + if (error_ == &::google::protobuf::internal::kEmptyString) { + error_ = new ::std::string; + } + error_->assign(value); +} +inline void CodeGeneratorResponse::set_error(const char* value, size_t size) { + set_has_error(); + if (error_ == &::google::protobuf::internal::kEmptyString) { + error_ = new ::std::string; + } + error_->assign(reinterpret_cast(value), size); +} +inline ::std::string* CodeGeneratorResponse::mutable_error() { + set_has_error(); + if (error_ == &::google::protobuf::internal::kEmptyString) { + error_ = new ::std::string; + } + return error_; +} +inline ::std::string* CodeGeneratorResponse::release_error() { + clear_has_error(); + if (error_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = error_; + error_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void CodeGeneratorResponse::set_allocated_error(::std::string* error) { + if (error_ != &::google::protobuf::internal::kEmptyString) { + delete error_; + } + if (error) { + set_has_error(); + error_ = error; + } else { + clear_has_error(); + error_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; +inline int CodeGeneratorResponse::file_size() const { + return file_.size(); +} +inline void CodeGeneratorResponse::clear_file() { + file_.Clear(); +} +inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const { + return file_.Get(index); +} +inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) { + return file_.Mutable(index); +} +inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() { + return file_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& +CodeGeneratorResponse::file() const { + return file_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* +CodeGeneratorResponse::mutable_file() { + return &file_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace compiler +} // namespace protobuf +} // namespace google + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.proto new file mode 100644 index 0000000..77b888f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/plugin.proto @@ -0,0 +1,147 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to +// change. +// +// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path. The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +package google.protobuf.compiler; +option java_package = "com.google.protobuf.compiler"; +option java_outer_classname = "PluginProtos"; + +import "google/protobuf/descriptor.proto"; + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + repeated string file_to_generate = 1; + + // The generator parameter passed on the command-line. + optional string parameter = 2; + + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + repeated FileDescriptorProto proto_file = 15; +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + optional string error = 1; + + // Represents a single generated file. + message File { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + optional string name = 1; + + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + optional string insertion_point = 2; + + // The file contents. + optional string content = 15; + } + repeated File file = 15; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_generator.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_generator.cc new file mode 100644 index 0000000..211ac70 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_generator.cc @@ -0,0 +1,1157 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: robinson@google.com (Will Robinson) +// +// This module outputs pure-Python protocol message classes that will +// largely be constructed at runtime via the metaclass in reflection.py. +// In other words, our job is basically to output a Python equivalent +// of the C++ *Descriptor objects, and fix up all circular references +// within these objects. +// +// Note that the runtime performance of protocol message classes created in +// this way is expected to be lousy. The plan is to create an alternate +// generator that outputs a Python/C extension module that lets +// performance-minded Python code leverage the fast C++ implementation +// directly. + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { + +namespace { + +// Returns a copy of |filename| with any trailing ".protodevel" or ".proto +// suffix stripped. +// TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc. +string StripProto(const string& filename) { + const char* suffix = HasSuffixString(filename, ".protodevel") + ? ".protodevel" : ".proto"; + return StripSuffixString(filename, suffix); +} + + +// Returns the Python module name expected for a given .proto filename. +string ModuleName(const string& filename) { + string basename = StripProto(filename); + StripString(&basename, "-", '_'); + StripString(&basename, "/", '.'); + return basename + "_pb2"; +} + + +// Returns the name of all containing types for descriptor, +// in order from outermost to innermost, followed by descriptor's +// own name. Each name is separated by |separator|. +template +string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, + const string& separator) { + string name = descriptor.name(); + for (const Descriptor* current = descriptor.containing_type(); + current != NULL; current = current->containing_type()) { + name = current->name() + separator + name; + } + return name; +} + + +// Name of the class attribute where we store the Python +// descriptor.Descriptor instance for the generated class. +// Must stay consistent with the _DESCRIPTOR_KEY constant +// in proto2/public/reflection.py. +const char kDescriptorKey[] = "DESCRIPTOR"; + + +// Does the file have top-level enums? +inline bool HasTopLevelEnums(const FileDescriptor *file) { + return file->enum_type_count() > 0; +} + + +// Should we generate generic services for this file? +inline bool HasGenericServices(const FileDescriptor *file) { + return file->service_count() > 0 && + file->options().py_generic_services(); +} + + +// Prints the common boilerplate needed at the top of every .py +// file output by this generator. +void PrintTopBoilerplate( + io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) { + // TODO(robinson): Allow parameterization of Python version? + printer->Print( + "# Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "# source: $filename$\n" + "\n", + "filename", file->name()); + if (HasTopLevelEnums(file)) { + printer->Print( + "from google.protobuf.internal import enum_type_wrapper\n"); + } + printer->Print( + "from google.protobuf import descriptor as _descriptor\n" + "from google.protobuf import message as _message\n" + "from google.protobuf import reflection as _reflection\n" + ); + if (HasGenericServices(file)) { + printer->Print( + "from google.protobuf import service as _service\n" + "from google.protobuf import service_reflection\n"); + } + + // Avoid circular imports if this module is descriptor_pb2. + if (!descriptor_proto) { + printer->Print( + "from google.protobuf import descriptor_pb2\n"); + } + printer->Print( + "# @@protoc_insertion_point(imports)\n"); + printer->Print("\n\n"); +} + + +// Returns a Python literal giving the default value for a field. +// If the field specifies no explicit default value, we'll return +// the default default value for the field type (zero for numbers, +// empty string for strings, empty list for repeated fields, and +// None for non-repeated, composite fields). +// +// TODO(robinson): Unify with code from +// //compiler/cpp/internal/primitive_field.cc +// //compiler/cpp/internal/enum_field.cc +// //compiler/cpp/internal/string_field.cc +string StringifyDefaultValue(const FieldDescriptor& field) { + if (field.is_repeated()) { + return "[]"; + } + + switch (field.cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + return SimpleItoa(field.default_value_int32()); + case FieldDescriptor::CPPTYPE_UINT32: + return SimpleItoa(field.default_value_uint32()); + case FieldDescriptor::CPPTYPE_INT64: + return SimpleItoa(field.default_value_int64()); + case FieldDescriptor::CPPTYPE_UINT64: + return SimpleItoa(field.default_value_uint64()); + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value = field.default_value_double(); + if (value == numeric_limits::infinity()) { + // Python pre-2.6 on Windows does not parse "inf" correctly. However, + // a numeric literal that is too big for a double will become infinity. + return "1e10000"; + } else if (value == -numeric_limits::infinity()) { + // See above. + return "-1e10000"; + } else if (value != value) { + // infinity * 0 = nan + return "(1e10000 * 0)"; + } else { + return SimpleDtoa(value); + } + } + case FieldDescriptor::CPPTYPE_FLOAT: { + float value = field.default_value_float(); + if (value == numeric_limits::infinity()) { + // Python pre-2.6 on Windows does not parse "inf" correctly. However, + // a numeric literal that is too big for a double will become infinity. + return "1e10000"; + } else if (value == -numeric_limits::infinity()) { + // See above. + return "-1e10000"; + } else if (value != value) { + // infinity - infinity = nan + return "(1e10000 * 0)"; + } else { + return SimpleFtoa(value); + } + } + case FieldDescriptor::CPPTYPE_BOOL: + return field.default_value_bool() ? "True" : "False"; + case FieldDescriptor::CPPTYPE_ENUM: + return SimpleItoa(field.default_value_enum()->number()); + case FieldDescriptor::CPPTYPE_STRING: + if (field.type() == FieldDescriptor::TYPE_STRING) { + return "unicode(\"" + CEscape(field.default_value_string()) + + "\", \"utf-8\")"; + } else { + return "\"" + CEscape(field.default_value_string()) + "\""; + } + case FieldDescriptor::CPPTYPE_MESSAGE: + return "None"; + } + // (We could add a default case above but then we wouldn't get the nice + // compiler warning when a new type is added.) + GOOGLE_LOG(FATAL) << "Not reached."; + return ""; +} + + + +} // namespace + + +Generator::Generator() : file_(NULL) { +} + +Generator::~Generator() { +} + +bool Generator::Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const { + + // Completely serialize all Generate() calls on this instance. The + // thread-safety constraints of the CodeGenerator interface aren't clear so + // just be as conservative as possible. It's easier to relax this later if + // we need to, but I doubt it will be an issue. + // TODO(kenton): The proper thing to do would be to allocate any state on + // the stack and use that, so that the Generator class itself does not need + // to have any mutable members. Then it is implicitly thread-safe. + MutexLock lock(&mutex_); + file_ = file; + string module_name = ModuleName(file->name()); + string filename = module_name; + StripString(&filename, ".", '/'); + filename += ".py"; + + FileDescriptorProto fdp; + file_->CopyTo(&fdp); + fdp.SerializeToString(&file_descriptor_serialized_); + + + scoped_ptr output(context->Open(filename)); + GOOGLE_CHECK(output.get()); + io::Printer printer(output.get(), '$'); + printer_ = &printer; + + PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto()); + PrintImports(); + PrintFileDescriptor(); + PrintTopLevelEnums(); + PrintTopLevelExtensions(); + PrintAllNestedEnumsInFile(); + PrintMessageDescriptors(); + FixForeignFieldsInDescriptors(); + PrintMessages(); + // We have to fix up the extensions after the message classes themselves, + // since they need to call static RegisterExtension() methods on these + // classes. + FixForeignFieldsInExtensions(); + // Descriptor options may have custom extensions. These custom options + // can only be successfully parsed after we register corresponding + // extensions. Therefore we parse all options again here to recognize + // custom options that may be unknown when we define the descriptors. + FixAllDescriptorOptions(); + if (HasGenericServices(file)) { + PrintServices(); + } + + printer.Print( + "# @@protoc_insertion_point(module_scope)\n"); + + return !printer.failed(); +} + +// Prints Python imports for all modules imported by |file|. +void Generator::PrintImports() const { + for (int i = 0; i < file_->dependency_count(); ++i) { + string module_name = ModuleName(file_->dependency(i)->name()); + printer_->Print("import $module$\n", "module", + module_name); + } + printer_->Print("\n"); + + // Print public imports. + for (int i = 0; i < file_->public_dependency_count(); ++i) { + string module_name = ModuleName(file_->public_dependency(i)->name()); + printer_->Print("from $module$ import *\n", "module", module_name); + } + printer_->Print("\n"); +} + +// Prints the single file descriptor for this file. +void Generator::PrintFileDescriptor() const { + map m; + m["descriptor_name"] = kDescriptorKey; + m["name"] = file_->name(); + m["package"] = file_->package(); + const char file_descriptor_template[] = + "$descriptor_name$ = _descriptor.FileDescriptor(\n" + " name='$name$',\n" + " package='$package$',\n"; + printer_->Print(m, file_descriptor_template); + printer_->Indent(); + printer_->Print( + "serialized_pb='$value$'", + "value", strings::CHexEscape(file_descriptor_serialized_)); + + // TODO(falk): Also print options and fix the message_type, enum_type, + // service and extension later in the generation. + + printer_->Outdent(); + printer_->Print(")\n"); + printer_->Print("\n"); +} + +// Prints descriptors and module-level constants for all top-level +// enums defined in |file|. +void Generator::PrintTopLevelEnums() const { + vector > top_level_enum_values; + for (int i = 0; i < file_->enum_type_count(); ++i) { + const EnumDescriptor& enum_descriptor = *file_->enum_type(i); + PrintEnum(enum_descriptor); + printer_->Print("$name$ = " + "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)", + "name", enum_descriptor.name(), + "descriptor_name", + ModuleLevelDescriptorName(enum_descriptor)); + printer_->Print("\n"); + + for (int j = 0; j < enum_descriptor.value_count(); ++j) { + const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j); + top_level_enum_values.push_back( + make_pair(value_descriptor.name(), value_descriptor.number())); + } + } + + for (int i = 0; i < top_level_enum_values.size(); ++i) { + printer_->Print("$name$ = $value$\n", + "name", top_level_enum_values[i].first, + "value", SimpleItoa(top_level_enum_values[i].second)); + } + printer_->Print("\n"); +} + +// Prints all enums contained in all message types in |file|. +void Generator::PrintAllNestedEnumsInFile() const { + for (int i = 0; i < file_->message_type_count(); ++i) { + PrintNestedEnums(*file_->message_type(i)); + } +} + +// Prints a Python statement assigning the appropriate module-level +// enum name to a Python EnumDescriptor object equivalent to +// enum_descriptor. +void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { + map m; + m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor); + m["name"] = enum_descriptor.name(); + m["full_name"] = enum_descriptor.full_name(); + m["file"] = kDescriptorKey; + const char enum_descriptor_template[] = + "$descriptor_name$ = _descriptor.EnumDescriptor(\n" + " name='$name$',\n" + " full_name='$full_name$',\n" + " filename=None,\n" + " file=$file$,\n" + " values=[\n"; + string options_string; + enum_descriptor.options().SerializeToString(&options_string); + printer_->Print(m, enum_descriptor_template); + printer_->Indent(); + printer_->Indent(); + for (int i = 0; i < enum_descriptor.value_count(); ++i) { + PrintEnumValueDescriptor(*enum_descriptor.value(i)); + printer_->Print(",\n"); + } + printer_->Outdent(); + printer_->Print("],\n"); + printer_->Print("containing_type=None,\n"); + printer_->Print("options=$options_value$,\n", + "options_value", + OptionsValue("EnumOptions", options_string)); + EnumDescriptorProto edp; + PrintSerializedPbInterval(enum_descriptor, edp); + printer_->Outdent(); + printer_->Print(")\n"); + printer_->Print("\n"); +} + +// Recursively prints enums in nested types within descriptor, then +// prints enums contained at the top level in descriptor. +void Generator::PrintNestedEnums(const Descriptor& descriptor) const { + for (int i = 0; i < descriptor.nested_type_count(); ++i) { + PrintNestedEnums(*descriptor.nested_type(i)); + } + + for (int i = 0; i < descriptor.enum_type_count(); ++i) { + PrintEnum(*descriptor.enum_type(i)); + } +} + +void Generator::PrintTopLevelExtensions() const { + const bool is_extension = true; + for (int i = 0; i < file_->extension_count(); ++i) { + const FieldDescriptor& extension_field = *file_->extension(i); + string constant_name = extension_field.name() + "_FIELD_NUMBER"; + UpperString(&constant_name); + printer_->Print("$constant_name$ = $number$\n", + "constant_name", constant_name, + "number", SimpleItoa(extension_field.number())); + printer_->Print("$name$ = ", "name", extension_field.name()); + PrintFieldDescriptor(extension_field, is_extension); + printer_->Print("\n"); + } + printer_->Print("\n"); +} + +// Prints Python equivalents of all Descriptors in |file|. +void Generator::PrintMessageDescriptors() const { + for (int i = 0; i < file_->message_type_count(); ++i) { + PrintDescriptor(*file_->message_type(i)); + printer_->Print("\n"); + } +} + +void Generator::PrintServices() const { + for (int i = 0; i < file_->service_count(); ++i) { + PrintServiceDescriptor(*file_->service(i)); + PrintServiceClass(*file_->service(i)); + PrintServiceStub(*file_->service(i)); + printer_->Print("\n"); + } +} + +void Generator::PrintServiceDescriptor( + const ServiceDescriptor& descriptor) const { + printer_->Print("\n"); + string service_name = ModuleLevelServiceDescriptorName(descriptor); + string options_string; + descriptor.options().SerializeToString(&options_string); + + printer_->Print( + "$service_name$ = _descriptor.ServiceDescriptor(\n", + "service_name", service_name); + printer_->Indent(); + map m; + m["name"] = descriptor.name(); + m["full_name"] = descriptor.full_name(); + m["file"] = kDescriptorKey; + m["index"] = SimpleItoa(descriptor.index()); + m["options_value"] = OptionsValue("ServiceOptions", options_string); + const char required_function_arguments[] = + "name='$name$',\n" + "full_name='$full_name$',\n" + "file=$file$,\n" + "index=$index$,\n" + "options=$options_value$,\n"; + printer_->Print(m, required_function_arguments); + + ServiceDescriptorProto sdp; + PrintSerializedPbInterval(descriptor, sdp); + + printer_->Print("methods=[\n"); + for (int i = 0; i < descriptor.method_count(); ++i) { + const MethodDescriptor* method = descriptor.method(i); + method->options().SerializeToString(&options_string); + + m.clear(); + m["name"] = method->name(); + m["full_name"] = method->full_name(); + m["index"] = SimpleItoa(method->index()); + m["serialized_options"] = CEscape(options_string); + m["input_type"] = ModuleLevelDescriptorName(*(method->input_type())); + m["output_type"] = ModuleLevelDescriptorName(*(method->output_type())); + m["options_value"] = OptionsValue("MethodOptions", options_string); + printer_->Print("_descriptor.MethodDescriptor(\n"); + printer_->Indent(); + printer_->Print( + m, + "name='$name$',\n" + "full_name='$full_name$',\n" + "index=$index$,\n" + "containing_service=None,\n" + "input_type=$input_type$,\n" + "output_type=$output_type$,\n" + "options=$options_value$,\n"); + printer_->Outdent(); + printer_->Print("),\n"); + } + + printer_->Outdent(); + printer_->Print("])\n\n"); +} + +void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const { + // Print the service. + printer_->Print("class $class_name$(_service.Service):\n", + "class_name", descriptor.name()); + printer_->Indent(); + printer_->Print( + "__metaclass__ = service_reflection.GeneratedServiceType\n" + "$descriptor_key$ = $descriptor_name$\n", + "descriptor_key", kDescriptorKey, + "descriptor_name", ModuleLevelServiceDescriptorName(descriptor)); + printer_->Outdent(); +} + +void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const { + // Print the service stub. + printer_->Print("class $class_name$_Stub($class_name$):\n", + "class_name", descriptor.name()); + printer_->Indent(); + printer_->Print( + "__metaclass__ = service_reflection.GeneratedServiceStubType\n" + "$descriptor_key$ = $descriptor_name$\n", + "descriptor_key", kDescriptorKey, + "descriptor_name", ModuleLevelServiceDescriptorName(descriptor)); + printer_->Outdent(); +} + +// Prints statement assigning ModuleLevelDescriptorName(message_descriptor) +// to a Python Descriptor object for message_descriptor. +// +// Mutually recursive with PrintNestedDescriptors(). +void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { + PrintNestedDescriptors(message_descriptor); + + printer_->Print("\n"); + printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n", + "descriptor_name", + ModuleLevelDescriptorName(message_descriptor)); + printer_->Indent(); + map m; + m["name"] = message_descriptor.name(); + m["full_name"] = message_descriptor.full_name(); + m["file"] = kDescriptorKey; + const char required_function_arguments[] = + "name='$name$',\n" + "full_name='$full_name$',\n" + "filename=None,\n" + "file=$file$,\n" + "containing_type=None,\n"; + printer_->Print(m, required_function_arguments); + PrintFieldsInDescriptor(message_descriptor); + PrintExtensionsInDescriptor(message_descriptor); + + // Nested types + printer_->Print("nested_types=["); + for (int i = 0; i < message_descriptor.nested_type_count(); ++i) { + const string nested_name = ModuleLevelDescriptorName( + *message_descriptor.nested_type(i)); + printer_->Print("$name$, ", "name", nested_name); + } + printer_->Print("],\n"); + + // Enum types + printer_->Print("enum_types=[\n"); + printer_->Indent(); + for (int i = 0; i < message_descriptor.enum_type_count(); ++i) { + const string descriptor_name = ModuleLevelDescriptorName( + *message_descriptor.enum_type(i)); + printer_->Print(descriptor_name.c_str()); + printer_->Print(",\n"); + } + printer_->Outdent(); + printer_->Print("],\n"); + string options_string; + message_descriptor.options().SerializeToString(&options_string); + printer_->Print( + "options=$options_value$,\n" + "is_extendable=$extendable$", + "options_value", OptionsValue("MessageOptions", options_string), + "extendable", message_descriptor.extension_range_count() > 0 ? + "True" : "False"); + printer_->Print(",\n"); + + // Extension ranges + printer_->Print("extension_ranges=["); + for (int i = 0; i < message_descriptor.extension_range_count(); ++i) { + const Descriptor::ExtensionRange* range = + message_descriptor.extension_range(i); + printer_->Print("($start$, $end$), ", + "start", SimpleItoa(range->start), + "end", SimpleItoa(range->end)); + } + printer_->Print("],\n"); + + // Serialization of proto + DescriptorProto edp; + PrintSerializedPbInterval(message_descriptor, edp); + + printer_->Outdent(); + printer_->Print(")\n"); +} + +// Prints Python Descriptor objects for all nested types contained in +// message_descriptor. +// +// Mutually recursive with PrintDescriptor(). +void Generator::PrintNestedDescriptors( + const Descriptor& containing_descriptor) const { + for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { + PrintDescriptor(*containing_descriptor.nested_type(i)); + } +} + +// Prints all messages in |file|. +void Generator::PrintMessages() const { + for (int i = 0; i < file_->message_type_count(); ++i) { + PrintMessage(*file_->message_type(i)); + printer_->Print("\n"); + } +} + +// Prints a Python class for the given message descriptor. We defer to the +// metaclass to do almost all of the work of actually creating a useful class. +// The purpose of this function and its many helper functions above is merely +// to output a Python version of the descriptors, which the metaclass in +// reflection.py will use to construct the meat of the class itself. +// +// Mutually recursive with PrintNestedMessages(). +void Generator::PrintMessage( + const Descriptor& message_descriptor) const { + printer_->Print("class $name$(_message.Message):\n", "name", + message_descriptor.name()); + printer_->Indent(); + printer_->Print("__metaclass__ = _reflection.GeneratedProtocolMessageType\n"); + PrintNestedMessages(message_descriptor); + map m; + m["descriptor_key"] = kDescriptorKey; + m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor); + printer_->Print(m, "$descriptor_key$ = $descriptor_name$\n"); + + printer_->Print( + "\n" + "# @@protoc_insertion_point(class_scope:$full_name$)\n", + "full_name", message_descriptor.full_name()); + + printer_->Outdent(); +} + +// Prints all nested messages within |containing_descriptor|. +// Mutually recursive with PrintMessage(). +void Generator::PrintNestedMessages( + const Descriptor& containing_descriptor) const { + for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { + printer_->Print("\n"); + PrintMessage(*containing_descriptor.nested_type(i)); + } +} + +// Recursively fixes foreign fields in all nested types in |descriptor|, then +// sets the message_type and enum_type of all message and enum fields to point +// to their respective descriptors. +// Args: +// descriptor: descriptor to print fields for. +// containing_descriptor: if descriptor is a nested type, this is its +// containing type, or NULL if this is a root/top-level type. +void Generator::FixForeignFieldsInDescriptor( + const Descriptor& descriptor, + const Descriptor* containing_descriptor) const { + for (int i = 0; i < descriptor.nested_type_count(); ++i) { + FixForeignFieldsInDescriptor(*descriptor.nested_type(i), &descriptor); + } + + for (int i = 0; i < descriptor.field_count(); ++i) { + const FieldDescriptor& field_descriptor = *descriptor.field(i); + FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name"); + } + + FixContainingTypeInDescriptor(descriptor, containing_descriptor); + for (int i = 0; i < descriptor.enum_type_count(); ++i) { + const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i); + FixContainingTypeInDescriptor(enum_descriptor, &descriptor); + } +} + +void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const { + map m; + m["descriptor_name"] = kDescriptorKey; + m["message_name"] = descriptor.name(); + m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor); + const char file_descriptor_template[] = + "$descriptor_name$.message_types_by_name['$message_name$'] = " + "$message_descriptor_name$\n"; + printer_->Print(m, file_descriptor_template); +} + +// Sets any necessary message_type and enum_type attributes +// for the Python version of |field|. +// +// containing_type may be NULL, in which case this is a module-level field. +// +// python_dict_name is the name of the Python dict where we should +// look the field up in the containing type. (e.g., fields_by_name +// or extensions_by_name). We ignore python_dict_name if containing_type +// is NULL. +void Generator::FixForeignFieldsInField(const Descriptor* containing_type, + const FieldDescriptor& field, + const string& python_dict_name) const { + const string field_referencing_expression = FieldReferencingExpression( + containing_type, field, python_dict_name); + map m; + m["field_ref"] = field_referencing_expression; + const Descriptor* foreign_message_type = field.message_type(); + if (foreign_message_type) { + m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type); + printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n"); + } + const EnumDescriptor* enum_type = field.enum_type(); + if (enum_type) { + m["enum_type"] = ModuleLevelDescriptorName(*enum_type); + printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n"); + } +} + +// Returns the module-level expression for the given FieldDescriptor. +// Only works for fields in the .proto file this Generator is generating for. +// +// containing_type may be NULL, in which case this is a module-level field. +// +// python_dict_name is the name of the Python dict where we should +// look the field up in the containing type. (e.g., fields_by_name +// or extensions_by_name). We ignore python_dict_name if containing_type +// is NULL. +string Generator::FieldReferencingExpression( + const Descriptor* containing_type, + const FieldDescriptor& field, + const string& python_dict_name) const { + // We should only ever be looking up fields in the current file. + // The only things we refer to from other files are message descriptors. + GOOGLE_CHECK_EQ(field.file(), file_) << field.file()->name() << " vs. " + << file_->name(); + if (!containing_type) { + return field.name(); + } + return strings::Substitute( + "$0.$1['$2']", + ModuleLevelDescriptorName(*containing_type), + python_dict_name, field.name()); +} + +// Prints containing_type for nested descriptors or enum descriptors. +template +void Generator::FixContainingTypeInDescriptor( + const DescriptorT& descriptor, + const Descriptor* containing_descriptor) const { + if (containing_descriptor != NULL) { + const string nested_name = ModuleLevelDescriptorName(descriptor); + const string parent_name = ModuleLevelDescriptorName( + *containing_descriptor); + printer_->Print( + "$nested_name$.containing_type = $parent_name$;\n", + "nested_name", nested_name, + "parent_name", parent_name); + } +} + +// Prints statements setting the message_type and enum_type fields in the +// Python descriptor objects we've already output in ths file. We must +// do this in a separate step due to circular references (otherwise, we'd +// just set everything in the initial assignment statements). +void Generator::FixForeignFieldsInDescriptors() const { + for (int i = 0; i < file_->message_type_count(); ++i) { + FixForeignFieldsInDescriptor(*file_->message_type(i), NULL); + } + for (int i = 0; i < file_->message_type_count(); ++i) { + AddMessageToFileDescriptor(*file_->message_type(i)); + } + printer_->Print("\n"); +} + +// We need to not only set any necessary message_type fields, but +// also need to call RegisterExtension() on each message we're +// extending. +void Generator::FixForeignFieldsInExtensions() const { + // Top-level extensions. + for (int i = 0; i < file_->extension_count(); ++i) { + FixForeignFieldsInExtension(*file_->extension(i)); + } + // Nested extensions. + for (int i = 0; i < file_->message_type_count(); ++i) { + FixForeignFieldsInNestedExtensions(*file_->message_type(i)); + } + printer_->Print("\n"); +} + +void Generator::FixForeignFieldsInExtension( + const FieldDescriptor& extension_field) const { + GOOGLE_CHECK(extension_field.is_extension()); + // extension_scope() will be NULL for top-level extensions, which is + // exactly what FixForeignFieldsInField() wants. + FixForeignFieldsInField(extension_field.extension_scope(), extension_field, + "extensions_by_name"); + + map m; + // Confusingly, for FieldDescriptors that happen to be extensions, + // containing_type() means "extended type." + // On the other hand, extension_scope() will give us what we normally + // mean by containing_type(). + m["extended_message_class"] = ModuleLevelMessageName( + *extension_field.containing_type()); + m["field"] = FieldReferencingExpression(extension_field.extension_scope(), + extension_field, + "extensions_by_name"); + printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n"); +} + +void Generator::FixForeignFieldsInNestedExtensions( + const Descriptor& descriptor) const { + // Recursively fix up extensions in all nested types. + for (int i = 0; i < descriptor.nested_type_count(); ++i) { + FixForeignFieldsInNestedExtensions(*descriptor.nested_type(i)); + } + // Fix up extensions directly contained within this type. + for (int i = 0; i < descriptor.extension_count(); ++i) { + FixForeignFieldsInExtension(*descriptor.extension(i)); + } +} + +// Returns a Python expression that instantiates a Python EnumValueDescriptor +// object for the given C++ descriptor. +void Generator::PrintEnumValueDescriptor( + const EnumValueDescriptor& descriptor) const { + // TODO(robinson): Fix up EnumValueDescriptor "type" fields. + // More circular references. ::sigh:: + string options_string; + descriptor.options().SerializeToString(&options_string); + map m; + m["name"] = descriptor.name(); + m["index"] = SimpleItoa(descriptor.index()); + m["number"] = SimpleItoa(descriptor.number()); + m["options"] = OptionsValue("EnumValueOptions", options_string); + printer_->Print( + m, + "_descriptor.EnumValueDescriptor(\n" + " name='$name$', index=$index$, number=$number$,\n" + " options=$options$,\n" + " type=None)"); +} + +// Returns a Python expression that calls descriptor._ParseOptions using +// the given descriptor class name and serialized options protobuf string. +string Generator::OptionsValue( + const string& class_name, const string& serialized_options) const { + if (serialized_options.length() == 0 || GeneratingDescriptorProto()) { + return "None"; + } else { + string full_class_name = "descriptor_pb2." + class_name; + return "_descriptor._ParseOptions(" + full_class_name + "(), '" + + CEscape(serialized_options)+ "')"; + } +} + +// Prints an expression for a Python FieldDescriptor for |field|. +void Generator::PrintFieldDescriptor( + const FieldDescriptor& field, bool is_extension) const { + string options_string; + field.options().SerializeToString(&options_string); + map m; + m["name"] = field.name(); + m["full_name"] = field.full_name(); + m["index"] = SimpleItoa(field.index()); + m["number"] = SimpleItoa(field.number()); + m["type"] = SimpleItoa(field.type()); + m["cpp_type"] = SimpleItoa(field.cpp_type()); + m["label"] = SimpleItoa(field.label()); + m["has_default_value"] = field.has_default_value() ? "True" : "False"; + m["default_value"] = StringifyDefaultValue(field); + m["is_extension"] = is_extension ? "True" : "False"; + m["options"] = OptionsValue("FieldOptions", options_string); + // We always set message_type and enum_type to None at this point, and then + // these fields in correctly after all referenced descriptors have been + // defined and/or imported (see FixForeignFieldsInDescriptors()). + const char field_descriptor_decl[] = + "_descriptor.FieldDescriptor(\n" + " name='$name$', full_name='$full_name$', index=$index$,\n" + " number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n" + " has_default_value=$has_default_value$, default_value=$default_value$,\n" + " message_type=None, enum_type=None, containing_type=None,\n" + " is_extension=$is_extension$, extension_scope=None,\n" + " options=$options$)"; + printer_->Print(m, field_descriptor_decl); +} + +// Helper for Print{Fields,Extensions}InDescriptor(). +void Generator::PrintFieldDescriptorsInDescriptor( + const Descriptor& message_descriptor, + bool is_extension, + const string& list_variable_name, + int (Descriptor::*CountFn)() const, + const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const { + printer_->Print("$list$=[\n", "list", list_variable_name); + printer_->Indent(); + for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) { + PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i), + is_extension); + printer_->Print(",\n"); + } + printer_->Outdent(); + printer_->Print("],\n"); +} + +// Prints a statement assigning "fields" to a list of Python FieldDescriptors, +// one for each field present in message_descriptor. +void Generator::PrintFieldsInDescriptor( + const Descriptor& message_descriptor) const { + const bool is_extension = false; + PrintFieldDescriptorsInDescriptor( + message_descriptor, is_extension, "fields", + &Descriptor::field_count, &Descriptor::field); +} + +// Prints a statement assigning "extensions" to a list of Python +// FieldDescriptors, one for each extension present in message_descriptor. +void Generator::PrintExtensionsInDescriptor( + const Descriptor& message_descriptor) const { + const bool is_extension = true; + PrintFieldDescriptorsInDescriptor( + message_descriptor, is_extension, "extensions", + &Descriptor::extension_count, &Descriptor::extension); +} + +bool Generator::GeneratingDescriptorProto() const { + return file_->name() == "google/protobuf/descriptor.proto"; +} + +// Returns the unique Python module-level identifier given to a descriptor. +// This name is module-qualified iff the given descriptor describes an +// entity that doesn't come from the current file. +template +string Generator::ModuleLevelDescriptorName( + const DescriptorT& descriptor) const { + // FIXME(robinson): + // We currently don't worry about collisions with underscores in the type + // names, so these would collide in nasty ways if found in the same file: + // OuterProto.ProtoA.ProtoB + // OuterProto_ProtoA.ProtoB # Underscore instead of period. + // As would these: + // OuterProto.ProtoA_.ProtoB + // OuterProto.ProtoA._ProtoB # Leading vs. trailing underscore. + // (Contrived, but certainly possible). + // + // The C++ implementation doesn't guard against this either. Leaving + // it for now... + string name = NamePrefixedWithNestedTypes(descriptor, "_"); + UpperString(&name); + // Module-private for now. Easy to make public later; almost impossible + // to make private later. + name = "_" + name; + // We now have the name relative to its own module. Also qualify with + // the module name iff this descriptor is from a different .proto file. + if (descriptor.file() != file_) { + name = ModuleName(descriptor.file()->name()) + "." + name; + } + return name; +} + +// Returns the name of the message class itself, not the descriptor. +// Like ModuleLevelDescriptorName(), module-qualifies the name iff +// the given descriptor describes an entity that doesn't come from +// the current file. +string Generator::ModuleLevelMessageName(const Descriptor& descriptor) const { + string name = NamePrefixedWithNestedTypes(descriptor, "."); + if (descriptor.file() != file_) { + name = ModuleName(descriptor.file()->name()) + "." + name; + } + return name; +} + +// Returns the unique Python module-level identifier given to a service +// descriptor. +string Generator::ModuleLevelServiceDescriptorName( + const ServiceDescriptor& descriptor) const { + string name = descriptor.name(); + UpperString(&name); + name = "_" + name; + if (descriptor.file() != file_) { + name = ModuleName(descriptor.file()->name()) + "." + name; + } + return name; +} + +// Prints standard constructor arguments serialized_start and serialized_end. +// Args: +// descriptor: The cpp descriptor to have a serialized reference. +// proto: A proto +// Example printer output: +// serialized_start=41, +// serialized_end=43, +// +template +void Generator::PrintSerializedPbInterval( + const DescriptorT& descriptor, DescriptorProtoT& proto) const { + descriptor.CopyTo(&proto); + string sp; + proto.SerializeToString(&sp); + int offset = file_descriptor_serialized_.find(sp); + GOOGLE_CHECK_GE(offset, 0); + + printer_->Print("serialized_start=$serialized_start$,\n" + "serialized_end=$serialized_end$,\n", + "serialized_start", SimpleItoa(offset), + "serialized_end", SimpleItoa(offset + sp.size())); +} + +namespace { +void PrintDescriptorOptionsFixingCode(const string& descriptor, + const string& options, + io::Printer* printer) { + // TODO(xiaofeng): I have added a method _SetOptions() to DescriptorBase + // in proto2 python runtime but it couldn't be used here because appengine + // uses a snapshot version of the library in which the new method is not + // yet present. After appengine has synced their runtime library, the code + // below should be cleaned up to use _SetOptions(). + printer->Print( + "$descriptor$.has_options = True\n" + "$descriptor$._options = $options$\n", + "descriptor", descriptor, "options", options); +} +} // namespace + +// Prints expressions that set the options field of all descriptors. +void Generator::FixAllDescriptorOptions() const { + // Prints an expression that sets the file descriptor's options. + string file_options = OptionsValue( + "FileOptions", file_->options().SerializeAsString()); + if (file_options != "None") { + PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_); + } + // Prints expressions that set the options for all top level enums. + for (int i = 0; i < file_->enum_type_count(); ++i) { + const EnumDescriptor& enum_descriptor = *file_->enum_type(i); + FixOptionsForEnum(enum_descriptor); + } + // Prints expressions that set the options for all top level extensions. + for (int i = 0; i < file_->extension_count(); ++i) { + const FieldDescriptor& field = *file_->extension(i); + FixOptionsForField(field); + } + // Prints expressions that set the options for all messages, nested enums, + // nested extensions and message fields. + for (int i = 0; i < file_->message_type_count(); ++i) { + FixOptionsForMessage(*file_->message_type(i)); + } +} + +// Prints expressions that set the options for an enum descriptor and its +// value descriptors. +void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { + string descriptor_name = ModuleLevelDescriptorName(enum_descriptor); + string enum_options = OptionsValue( + "EnumOptions", enum_descriptor.options().SerializeAsString()); + if (enum_options != "None") { + PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_); + } + for (int i = 0; i < enum_descriptor.value_count(); ++i) { + const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i); + string value_options = OptionsValue( + "EnumValueOptions", value_descriptor.options().SerializeAsString()); + if (value_options != "None") { + PrintDescriptorOptionsFixingCode( + StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(), + value_descriptor.name().c_str()), + value_options, printer_); + } + } +} + +// Prints expressions that set the options for field descriptors (including +// extensions). +void Generator::FixOptionsForField( + const FieldDescriptor& field) const { + string field_options = OptionsValue( + "FieldOptions", field.options().SerializeAsString()); + if (field_options != "None") { + string field_name; + if (field.is_extension()) { + if (field.extension_scope() == NULL) { + // Top level extensions. + field_name = field.name(); + } else { + field_name = FieldReferencingExpression( + field.extension_scope(), field, "extensions_by_name"); + } + } else { + field_name = FieldReferencingExpression( + field.containing_type(), field, "fields_by_name"); + } + PrintDescriptorOptionsFixingCode(field_name, field_options, printer_); + } +} + +// Prints expressions that set the options for a message and all its inner +// types (nested messages, nested enums, extensions, fields). +void Generator::FixOptionsForMessage(const Descriptor& descriptor) const { + // Nested messages. + for (int i = 0; i < descriptor.nested_type_count(); ++i) { + FixOptionsForMessage(*descriptor.nested_type(i)); + } + // Enums. + for (int i = 0; i < descriptor.enum_type_count(); ++i) { + FixOptionsForEnum(*descriptor.enum_type(i)); + } + // Fields. + for (int i = 0; i < descriptor.field_count(); ++i) { + const FieldDescriptor& field = *descriptor.field(i); + FixOptionsForField(field); + } + // Extensions. + for (int i = 0; i < descriptor.extension_count(); ++i) { + const FieldDescriptor& field = *descriptor.extension(i); + FixOptionsForField(field); + } + // Message option for this message. + string message_options = OptionsValue( + "MessageOptions", descriptor.options().SerializeAsString()); + if (message_options != "None") { + string descriptor_name = ModuleLevelDescriptorName(descriptor); + PrintDescriptorOptionsFixingCode(descriptor_name, + message_options, + printer_); + } +} + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_generator.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_generator.h new file mode 100644 index 0000000..a3f22ce --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_generator.h @@ -0,0 +1,161 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: robinson@google.com (Will Robinson) +// +// Generates Python code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ + +#include + +#include +#include + +namespace google { +namespace protobuf { + +class Descriptor; +class EnumDescriptor; +class EnumValueDescriptor; +class FieldDescriptor; +class ServiceDescriptor; + +namespace io { class Printer; } + +namespace compiler { +namespace python { + +// CodeGenerator implementation for generated Python protocol buffer classes. +// If you create your own protocol compiler binary and you want it to support +// Python output, you can do so by registering an instance of this +// CodeGenerator with the CommandLineInterface in your main() function. +class LIBPROTOC_EXPORT Generator : public CodeGenerator { + public: + Generator(); + virtual ~Generator(); + + // CodeGenerator methods. + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const; + + private: + void PrintImports() const; + void PrintFileDescriptor() const; + void PrintTopLevelEnums() const; + void PrintAllNestedEnumsInFile() const; + void PrintNestedEnums(const Descriptor& descriptor) const; + void PrintEnum(const EnumDescriptor& enum_descriptor) const; + + void PrintTopLevelExtensions() const; + + void PrintFieldDescriptor( + const FieldDescriptor& field, bool is_extension) const; + void PrintFieldDescriptorsInDescriptor( + const Descriptor& message_descriptor, + bool is_extension, + const string& list_variable_name, + int (Descriptor::*CountFn)() const, + const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const; + void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const; + void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const; + void PrintMessageDescriptors() const; + void PrintDescriptor(const Descriptor& message_descriptor) const; + void PrintNestedDescriptors(const Descriptor& containing_descriptor) const; + + void PrintMessages() const; + void PrintMessage(const Descriptor& message_descriptor) const; + void PrintNestedMessages(const Descriptor& containing_descriptor) const; + + void FixForeignFieldsInDescriptors() const; + void FixForeignFieldsInDescriptor( + const Descriptor& descriptor, + const Descriptor* containing_descriptor) const; + void FixForeignFieldsInField(const Descriptor* containing_type, + const FieldDescriptor& field, + const string& python_dict_name) const; + void AddMessageToFileDescriptor(const Descriptor& descriptor) const; + string FieldReferencingExpression(const Descriptor* containing_type, + const FieldDescriptor& field, + const string& python_dict_name) const; + template + void FixContainingTypeInDescriptor( + const DescriptorT& descriptor, + const Descriptor* containing_descriptor) const; + + void FixForeignFieldsInExtensions() const; + void FixForeignFieldsInExtension( + const FieldDescriptor& extension_field) const; + void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const; + + void PrintServices() const; + void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const; + void PrintServiceClass(const ServiceDescriptor& descriptor) const; + void PrintServiceStub(const ServiceDescriptor& descriptor) const; + + void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const; + string OptionsValue(const string& class_name, + const string& serialized_options) const; + bool GeneratingDescriptorProto() const; + + template + string ModuleLevelDescriptorName(const DescriptorT& descriptor) const; + string ModuleLevelMessageName(const Descriptor& descriptor) const; + string ModuleLevelServiceDescriptorName( + const ServiceDescriptor& descriptor) const; + + template + void PrintSerializedPbInterval( + const DescriptorT& descriptor, DescriptorProtoT& proto) const; + + void FixAllDescriptorOptions() const; + void FixOptionsForField(const FieldDescriptor& field) const; + void FixOptionsForEnum(const EnumDescriptor& descriptor) const; + void FixOptionsForMessage(const Descriptor& descriptor) const; + + // Very coarse-grained lock to ensure that Generate() is reentrant. + // Guards file_, printer_ and file_descriptor_serialized_. + mutable Mutex mutex_; + mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. + mutable string file_descriptor_serialized_; + mutable io::Printer* printer_; // Set in Generate(). Under mutex_. + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator); +}; + +} // namespace python +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_plugin_unittest.cc new file mode 100644 index 0000000..da619ad --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/python/python_plugin_unittest.cc @@ -0,0 +1,116 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// TODO(kenton): Share code with the versions of this test in other languages? +// It seemed like parameterizing it would add more complexity than it is +// worth. + +#include +#include +#include +#include + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { +namespace { + +class TestGenerator : public CodeGenerator { + public: + TestGenerator() {} + ~TestGenerator() {} + + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const { + TryInsert("test_pb2.py", "imports", context); + TryInsert("test_pb2.py", "module_scope", context); + TryInsert("test_pb2.py", "class_scope:foo.Bar", context); + TryInsert("test_pb2.py", "class_scope:foo.Bar.Baz", context); + return true; + } + + void TryInsert(const string& filename, const string& insertion_point, + GeneratorContext* context) const { + scoped_ptr output( + context->OpenForInsert(filename, insertion_point)); + io::Printer printer(output.get(), '$'); + printer.Print("// inserted $name$\n", "name", insertion_point); + } +}; + +// This test verifies that all the expected insertion points exist. It does +// not verify that they are correctly-placed; that would require actually +// compiling the output which is a bit more than I care to do for this test. +TEST(PythonPluginTest, PluginTest) { + File::WriteStringToFileOrDie( + "syntax = \"proto2\";\n" + "package foo;\n" + "message Bar {\n" + " message Baz {}\n" + "}\n", + TestTempDir() + "/test.proto"); + + google::protobuf::compiler::CommandLineInterface cli; + cli.SetInputsAreProtoPathRelative(true); + + python::Generator python_generator; + TestGenerator test_generator; + cli.RegisterGenerator("--python_out", &python_generator, ""); + cli.RegisterGenerator("--test_out", &test_generator, ""); + + string proto_path = "-I" + TestTempDir(); + string python_out = "--python_out=" + TestTempDir(); + string test_out = "--test_out=" + TestTempDir(); + + const char* argv[] = { + "protoc", + proto_path.c_str(), + python_out.c_str(), + test_out.c_str(), + "test.proto" + }; + + EXPECT_EQ(0, cli.Run(5, argv)); +} + +} // namespace +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/subprocess.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/subprocess.cc new file mode 100644 index 0000000..67da120 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/subprocess.cc @@ -0,0 +1,463 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include + +#include +#include + +#ifndef _WIN32 +#include +#include +#include +#include +#endif + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { + +#ifdef _WIN32 + +static void CloseHandleOrDie(HANDLE handle) { + if (!CloseHandle(handle)) { + GOOGLE_LOG(FATAL) << "CloseHandle: " + << Subprocess::Win32ErrorMessage(GetLastError()); + } +} + +Subprocess::Subprocess() + : process_start_error_(ERROR_SUCCESS), + child_handle_(NULL), child_stdin_(NULL), child_stdout_(NULL) {} + +Subprocess::~Subprocess() { + if (child_stdin_ != NULL) { + CloseHandleOrDie(child_stdin_); + } + if (child_stdout_ != NULL) { + CloseHandleOrDie(child_stdout_); + } +} + +void Subprocess::Start(const string& program, SearchMode search_mode) { + // Create the pipes. + HANDLE stdin_pipe_read; + HANDLE stdin_pipe_write; + HANDLE stdout_pipe_read; + HANDLE stdout_pipe_write; + + if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, NULL, 0)) { + GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError()); + } + if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, NULL, 0)) { + GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError()); + } + + // Make child side of the pipes inheritable. + if (!SetHandleInformation(stdin_pipe_read, + HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { + GOOGLE_LOG(FATAL) << "SetHandleInformation: " + << Win32ErrorMessage(GetLastError()); + } + if (!SetHandleInformation(stdout_pipe_write, + HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { + GOOGLE_LOG(FATAL) << "SetHandleInformation: " + << Win32ErrorMessage(GetLastError()); + } + + // Setup STARTUPINFO to redirect handles. + STARTUPINFOA startup_info; + ZeroMemory(&startup_info, sizeof(startup_info)); + startup_info.cb = sizeof(startup_info); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = stdin_pipe_read; + startup_info.hStdOutput = stdout_pipe_write; + startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); + + if (startup_info.hStdError == INVALID_HANDLE_VALUE) { + GOOGLE_LOG(FATAL) << "GetStdHandle: " + << Win32ErrorMessage(GetLastError()); + } + + // CreateProcess() mutates its second parameter. WTF? + char* name_copy = strdup(program.c_str()); + + // Create the process. + PROCESS_INFORMATION process_info; + + if (CreateProcessA((search_mode == SEARCH_PATH) ? NULL : program.c_str(), + (search_mode == SEARCH_PATH) ? name_copy : NULL, + NULL, // process security attributes + NULL, // thread security attributes + TRUE, // inherit handles? + 0, // obscure creation flags + NULL, // environment (inherit from parent) + NULL, // current directory (inherit from parent) + &startup_info, + &process_info)) { + child_handle_ = process_info.hProcess; + CloseHandleOrDie(process_info.hThread); + child_stdin_ = stdin_pipe_write; + child_stdout_ = stdout_pipe_read; + } else { + process_start_error_ = GetLastError(); + CloseHandleOrDie(stdin_pipe_write); + CloseHandleOrDie(stdout_pipe_read); + } + + CloseHandleOrDie(stdin_pipe_read); + CloseHandleOrDie(stdout_pipe_write); + free(name_copy); +} + +bool Subprocess::Communicate(const Message& input, Message* output, + string* error) { + if (process_start_error_ != ERROR_SUCCESS) { + *error = Win32ErrorMessage(process_start_error_); + return false; + } + + GOOGLE_CHECK(child_handle_ != NULL) << "Must call Start() first."; + + string input_data = input.SerializeAsString(); + string output_data; + + int input_pos = 0; + + while (child_stdout_ != NULL) { + HANDLE handles[2]; + int handle_count = 0; + + if (child_stdin_ != NULL) { + handles[handle_count++] = child_stdin_; + } + if (child_stdout_ != NULL) { + handles[handle_count++] = child_stdout_; + } + + DWORD wait_result = + WaitForMultipleObjects(handle_count, handles, FALSE, INFINITE); + + HANDLE signaled_handle; + if (wait_result >= WAIT_OBJECT_0 && + wait_result < WAIT_OBJECT_0 + handle_count) { + signaled_handle = handles[wait_result - WAIT_OBJECT_0]; + } else if (wait_result == WAIT_FAILED) { + GOOGLE_LOG(FATAL) << "WaitForMultipleObjects: " + << Win32ErrorMessage(GetLastError()); + } else { + GOOGLE_LOG(FATAL) << "WaitForMultipleObjects: Unexpected return code: " + << wait_result; + } + + if (signaled_handle == child_stdin_) { + DWORD n; + if (!WriteFile(child_stdin_, + input_data.data() + input_pos, + input_data.size() - input_pos, + &n, NULL)) { + // Child closed pipe. Presumably it will report an error later. + // Pretend we're done for now. + input_pos = input_data.size(); + } else { + input_pos += n; + } + + if (input_pos == input_data.size()) { + // We're done writing. Close. + CloseHandleOrDie(child_stdin_); + child_stdin_ = NULL; + } + } else if (signaled_handle == child_stdout_) { + char buffer[4096]; + DWORD n; + + if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, NULL)) { + // We're done reading. Close. + CloseHandleOrDie(child_stdout_); + child_stdout_ = NULL; + } else { + output_data.append(buffer, n); + } + } + } + + if (child_stdin_ != NULL) { + // Child did not finish reading input before it closed the output. + // Presumably it exited with an error. + CloseHandleOrDie(child_stdin_); + child_stdin_ = NULL; + } + + DWORD wait_result = WaitForSingleObject(child_handle_, INFINITE); + + if (wait_result == WAIT_FAILED) { + GOOGLE_LOG(FATAL) << "WaitForSingleObject: " + << Win32ErrorMessage(GetLastError()); + } else if (wait_result != WAIT_OBJECT_0) { + GOOGLE_LOG(FATAL) << "WaitForSingleObject: Unexpected return code: " + << wait_result; + } + + DWORD exit_code; + if (!GetExitCodeProcess(child_handle_, &exit_code)) { + GOOGLE_LOG(FATAL) << "GetExitCodeProcess: " + << Win32ErrorMessage(GetLastError()); + } + + CloseHandleOrDie(child_handle_); + child_handle_ = NULL; + + if (exit_code != 0) { + *error = strings::Substitute( + "Plugin failed with status code $0.", exit_code); + return false; + } + + if (!output->ParseFromString(output_data)) { + *error = "Plugin output is unparseable: " + CEscape(output_data); + return false; + } + + return true; +} + +string Subprocess::Win32ErrorMessage(DWORD error_code) { + char* message; + + // WTF? + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error_code, 0, + (LPTSTR)&message, // NOT A BUG! + 0, NULL); + + string result = message; + LocalFree(message); + return result; +} + +// =================================================================== + +#else // _WIN32 + +Subprocess::Subprocess() + : child_pid_(-1), child_stdin_(-1), child_stdout_(-1) {} + +Subprocess::~Subprocess() { + if (child_stdin_ != -1) { + close(child_stdin_); + } + if (child_stdout_ != -1) { + close(child_stdout_); + } +} + +void Subprocess::Start(const string& program, SearchMode search_mode) { + // Note that we assume that there are no other threads, thus we don't have to + // do crazy stuff like using socket pairs or avoiding libc locks. + + // [0] is read end, [1] is write end. + int stdin_pipe[2]; + int stdout_pipe[2]; + + GOOGLE_CHECK(pipe(stdin_pipe) != -1); + GOOGLE_CHECK(pipe(stdout_pipe) != -1); + + char* argv[2] = { strdup(program.c_str()), NULL }; + + child_pid_ = fork(); + if (child_pid_ == -1) { + GOOGLE_LOG(FATAL) << "fork: " << strerror(errno); + } else if (child_pid_ == 0) { + // We are the child. + dup2(stdin_pipe[0], STDIN_FILENO); + dup2(stdout_pipe[1], STDOUT_FILENO); + + close(stdin_pipe[0]); + close(stdin_pipe[1]); + close(stdout_pipe[0]); + close(stdout_pipe[1]); + + switch (search_mode) { + case SEARCH_PATH: + execvp(argv[0], argv); + break; + case EXACT_NAME: + execv(argv[0], argv); + break; + } + + // Write directly to STDERR_FILENO to avoid stdio code paths that may do + // stuff that is unsafe here. + int ignored; + ignored = write(STDERR_FILENO, argv[0], strlen(argv[0])); + const char* message = ": program not found or is not executable\n"; + ignored = write(STDERR_FILENO, message, strlen(message)); + (void) ignored; + + // Must use _exit() rather than exit() to avoid flushing output buffers + // that will also be flushed by the parent. + _exit(1); + } else { + free(argv[0]); + + close(stdin_pipe[0]); + close(stdout_pipe[1]); + + child_stdin_ = stdin_pipe[1]; + child_stdout_ = stdout_pipe[0]; + } +} + +bool Subprocess::Communicate(const Message& input, Message* output, + string* error) { + + GOOGLE_CHECK_NE(child_stdin_, -1) << "Must call Start() first."; + + // The "sighandler_t" typedef is GNU-specific, so define our own. + typedef void SignalHandler(int); + + // Make sure SIGPIPE is disabled so that if the child dies it doesn't kill us. + SignalHandler* old_pipe_handler = signal(SIGPIPE, SIG_IGN); + + string input_data = input.SerializeAsString(); + string output_data; + + int input_pos = 0; + int max_fd = max(child_stdin_, child_stdout_); + + while (child_stdout_ != -1) { + fd_set read_fds; + fd_set write_fds; + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + if (child_stdout_ != -1) { + FD_SET(child_stdout_, &read_fds); + } + if (child_stdin_ != -1) { + FD_SET(child_stdin_, &write_fds); + } + + if (select(max_fd + 1, &read_fds, &write_fds, NULL, NULL) < 0) { + if (errno == EINTR) { + // Interrupted by signal. Try again. + continue; + } else { + GOOGLE_LOG(FATAL) << "select: " << strerror(errno); + } + } + + if (child_stdin_ != -1 && FD_ISSET(child_stdin_, &write_fds)) { + int n = write(child_stdin_, input_data.data() + input_pos, + input_data.size() - input_pos); + if (n < 0) { + // Child closed pipe. Presumably it will report an error later. + // Pretend we're done for now. + input_pos = input_data.size(); + } else { + input_pos += n; + } + + if (input_pos == input_data.size()) { + // We're done writing. Close. + close(child_stdin_); + child_stdin_ = -1; + } + } + + if (child_stdout_ != -1 && FD_ISSET(child_stdout_, &read_fds)) { + char buffer[4096]; + int n = read(child_stdout_, buffer, sizeof(buffer)); + + if (n > 0) { + output_data.append(buffer, n); + } else { + // We're done reading. Close. + close(child_stdout_); + child_stdout_ = -1; + } + } + } + + if (child_stdin_ != -1) { + // Child did not finish reading input before it closed the output. + // Presumably it exited with an error. + close(child_stdin_); + child_stdin_ = -1; + } + + int status; + while (waitpid(child_pid_, &status, 0) == -1) { + if (errno != EINTR) { + GOOGLE_LOG(FATAL) << "waitpid: " << strerror(errno); + } + } + + // Restore SIGPIPE handling. + signal(SIGPIPE, old_pipe_handler); + + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) != 0) { + int error_code = WEXITSTATUS(status); + *error = strings::Substitute( + "Plugin failed with status code $0.", error_code); + return false; + } + } else if (WIFSIGNALED(status)) { + int signal = WTERMSIG(status); + *error = strings::Substitute( + "Plugin killed by signal $0.", signal); + return false; + } else { + *error = "Neither WEXITSTATUS nor WTERMSIG is true?"; + return false; + } + + if (!output->ParseFromString(output_data)) { + *error = "Plugin output is unparseable."; + return false; + } + + return true; +} + +#endif // !_WIN32 + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/subprocess.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/subprocess.h new file mode 100644 index 0000000..0056496 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/subprocess.h @@ -0,0 +1,108 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#ifndef GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__ +#define GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__ + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN // right... +#include +#else // _WIN32 +#include +#include +#endif // !_WIN32 +#include + +#include + + +namespace google { +namespace protobuf { + +class Message; + +namespace compiler { + +// Utility class for launching sub-processes. +class LIBPROTOC_EXPORT Subprocess { + public: + Subprocess(); + ~Subprocess(); + + enum SearchMode { + SEARCH_PATH, // Use PATH environment variable. + EXACT_NAME // Program is an exact file name; don't use the PATH. + }; + + // Start the subprocess. Currently we don't provide a way to specify + // arguments as protoc plugins don't have any. + void Start(const string& program, SearchMode search_mode); + + // Serialize the input message and pipe it to the subprocess's stdin, then + // close the pipe. Meanwhile, read from the subprocess's stdout and parse + // the data into *output. All this is done carefully to avoid deadlocks. + // Returns true if successful. On any sort of error, returns false and sets + // *error to a description of the problem. + bool Communicate(const Message& input, Message* output, string* error); + +#ifdef _WIN32 + // Given an error code, returns a human-readable error message. This is + // defined here so that CommandLineInterface can share it. + static string Win32ErrorMessage(DWORD error_code); +#endif + + private: +#ifdef _WIN32 + DWORD process_start_error_; + HANDLE child_handle_; + + // The file handles for our end of the child's pipes. We close each and + // set it to NULL when no longer needed. + HANDLE child_stdin_; + HANDLE child_stdout_; + +#else // _WIN32 + pid_t child_pid_; + + // The file descriptors for our end of the child's pipes. We close each and + // set it to -1 when no longer needed. + int child_stdin_; + int child_stdout_; + +#endif // !_WIN32 +}; + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/test_plugin.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/test_plugin.cc new file mode 100644 index 0000000..5cbbf3d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/test_plugin.cc @@ -0,0 +1,51 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// This is a dummy code generator plugin used by +// command_line_interface_unittest. + +#include +#include +#include +#include +#include + +int main(int argc, char* argv[]) { +#ifdef _MSC_VER + // Don't print a silly message or stick a modal dialog box in my face, + // please. + _set_abort_behavior(0, ~0); +#endif // !_MSC_VER + + google::protobuf::compiler::MockCodeGenerator generator("test_plugin"); + return google::protobuf::compiler::PluginMain(argc, argv, &generator); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_output_unittest.sh b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_output_unittest.sh new file mode 100755 index 0000000..3a02436 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_output_unittest.sh @@ -0,0 +1,91 @@ +#!/bin/sh +# +# Protocol Buffers - Google's data interchange format +# Copyright 2009 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Author: kenton@google.com (Kenton Varda) +# +# Test protoc's zip output mode. + +fail() { + echo "$@" >&2 + exit 1 +} + +TEST_TMPDIR=. +PROTOC=./protoc + +echo ' + syntax = "proto2"; + option java_multiple_files = true; + option java_package = "test.jar"; + option java_outer_classname = "Outer"; + message Foo {} + message Bar {} +' > $TEST_TMPDIR/testzip.proto + +$PROTOC \ + --cpp_out=$TEST_TMPDIR/testzip.zip --python_out=$TEST_TMPDIR/testzip.zip \ + --java_out=$TEST_TMPDIR/testzip.jar -I$TEST_TMPDIR testzip.proto \ + || fail 'protoc failed.' + +echo "Testing output to zip..." +if unzip -h > /dev/null; then + unzip -t $TEST_TMPDIR/testzip.zip > $TEST_TMPDIR/testzip.list || fail 'unzip failed.' + + grep 'testing: testzip\.pb\.cc *OK$' $TEST_TMPDIR/testzip.list > /dev/null \ + || fail 'testzip.pb.cc not found in output zip.' + grep 'testing: testzip\.pb\.h *OK$' $TEST_TMPDIR/testzip.list > /dev/null \ + || fail 'testzip.pb.h not found in output zip.' + grep 'testing: testzip_pb2\.py *OK$' $TEST_TMPDIR/testzip.list > /dev/null \ + || fail 'testzip_pb2.py not found in output zip.' + grep -i 'manifest' $TEST_TMPDIR/testzip.list > /dev/null \ + && fail 'Zip file contained manifest.' +else + echo "Warning: 'unzip' command not available. Skipping test." +fi + +echo "Testing output to jar..." +if jar c $TEST_TMPDIR/testzip.proto > /dev/null; then + jar tf $TEST_TMPDIR/testzip.jar > $TEST_TMPDIR/testzip.list || fail 'jar failed.' + + grep '^test/jar/Foo\.java$' $TEST_TMPDIR/testzip.list > /dev/null \ + || fail 'Foo.java not found in output jar.' + grep '^test/jar/Bar\.java$' $TEST_TMPDIR/testzip.list > /dev/null \ + || fail 'Bar.java not found in output jar.' + grep '^test/jar/Outer\.java$' $TEST_TMPDIR/testzip.list > /dev/null \ + || fail 'Outer.java not found in output jar.' + grep '^META-INF/MANIFEST\.MF$' $TEST_TMPDIR/testzip.list > /dev/null \ + || fail 'Manifest not found in output jar.' +else + echo "Warning: 'jar' command not available. Skipping test." +fi + +echo PASS diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_writer.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_writer.cc new file mode 100644 index 0000000..65d7352 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_writer.cc @@ -0,0 +1,218 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: ambrose@google.com (Ambrose Feinstein), +// kenton@google.com (Kenton Varda) +// +// Based on http://www.pkware.com/documents/casestudies/APPNOTE.TXT + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { + +static const uint32 kCRC32Table[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +static uint32 ComputeCRC32(const string &buf) { + uint32 x = ~0U; + for (int i = 0; i < buf.size(); ++i) { + unsigned char c = buf[i]; + x = kCRC32Table[(x ^ c) & 0xff] ^ (x >> 8); + } + return ~x; +} + +static void WriteShort(io::CodedOutputStream *out, uint16 val) { + uint8 p[2]; + p[0] = static_cast(val); + p[1] = static_cast(val >> 8); + out->WriteRaw(p, 2); +} + +ZipWriter::ZipWriter(io::ZeroCopyOutputStream* raw_output) + : raw_output_(raw_output) {} +ZipWriter::~ZipWriter() {} + +bool ZipWriter::Write(const string& filename, const string& contents) { + FileInfo info; + + info.name = filename; + uint16 filename_size = filename.size(); + info.offset = raw_output_->ByteCount(); + info.size = contents.size(); + info.crc32 = ComputeCRC32(contents); + + files_.push_back(info); + + // write file header + io::CodedOutputStream output(raw_output_); + output.WriteLittleEndian32(0x04034b50); // magic + WriteShort(&output, 10); // version needed to extract + WriteShort(&output, 0); // flags + WriteShort(&output, 0); // compression method: stored + WriteShort(&output, 0); // last modified time + WriteShort(&output, 0); // last modified date + output.WriteLittleEndian32(info.crc32); // crc-32 + output.WriteLittleEndian32(info.size); // compressed size + output.WriteLittleEndian32(info.size); // uncompressed size + WriteShort(&output, filename_size); // file name length + WriteShort(&output, 0); // extra field length + output.WriteString(filename); // file name + output.WriteString(contents); // file data + + return !output.HadError(); +} + +bool ZipWriter::WriteDirectory() { + uint16 num_entries = files_.size(); + uint32 dir_ofs = raw_output_->ByteCount(); + + // write central directory + io::CodedOutputStream output(raw_output_); + for (int i = 0; i < num_entries; ++i) { + const string &filename = files_[i].name; + uint16 filename_size = filename.size(); + uint32 crc32 = files_[i].crc32; + uint32 size = files_[i].size; + uint32 offset = files_[i].offset; + + output.WriteLittleEndian32(0x02014b50); // magic + WriteShort(&output, 10); // version made by + WriteShort(&output, 10); // version needed to extract + WriteShort(&output, 0); // flags + WriteShort(&output, 0); // compression method: stored + WriteShort(&output, 0); // last modified time + WriteShort(&output, 0); // last modified date + output.WriteLittleEndian32(crc32); // crc-32 + output.WriteLittleEndian32(size); // compressed size + output.WriteLittleEndian32(size); // uncompressed size + WriteShort(&output, filename_size); // file name length + WriteShort(&output, 0); // extra field length + WriteShort(&output, 0); // file comment length + WriteShort(&output, 0); // starting disk number + WriteShort(&output, 0); // internal file attributes + output.WriteLittleEndian32(0); // external file attributes + output.WriteLittleEndian32(offset); // local header offset + output.WriteString(filename); // file name + } + uint32 dir_len = output.ByteCount(); + + // write end of central directory marker + output.WriteLittleEndian32(0x06054b50); // magic + WriteShort(&output, 0); // disk number + WriteShort(&output, 0); // disk with start of central directory + WriteShort(&output, num_entries); // central directory entries (this disk) + WriteShort(&output, num_entries); // central directory entries (total) + output.WriteLittleEndian32(dir_len); // central directory byte size + output.WriteLittleEndian32(dir_ofs); // central directory offset + WriteShort(&output, 0); // comment length + + return output.HadError(); +} + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_writer.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_writer.h new file mode 100644 index 0000000..be73972 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/compiler/zip_writer.h @@ -0,0 +1,93 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { + +class ZipWriter { + public: + ZipWriter(io::ZeroCopyOutputStream* raw_output); + ~ZipWriter(); + + bool Write(const string& filename, const string& contents); + bool WriteDirectory(); + + private: + struct FileInfo { + string name; + uint32 offset; + uint32 size; + uint32 crc32; + }; + + io::ZeroCopyOutputStream* raw_output_; + vector files_; +}; + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.cc new file mode 100644 index 0000000..c941aac --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.cc @@ -0,0 +1,4949 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef PACKAGE // autoheader #defines this. :( + +namespace google { +namespace protobuf { + +const FieldDescriptor::CppType +FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = { + static_cast(0), // 0 is reserved for errors + + CPPTYPE_DOUBLE, // TYPE_DOUBLE + CPPTYPE_FLOAT, // TYPE_FLOAT + CPPTYPE_INT64, // TYPE_INT64 + CPPTYPE_UINT64, // TYPE_UINT64 + CPPTYPE_INT32, // TYPE_INT32 + CPPTYPE_UINT64, // TYPE_FIXED64 + CPPTYPE_UINT32, // TYPE_FIXED32 + CPPTYPE_BOOL, // TYPE_BOOL + CPPTYPE_STRING, // TYPE_STRING + CPPTYPE_MESSAGE, // TYPE_GROUP + CPPTYPE_MESSAGE, // TYPE_MESSAGE + CPPTYPE_STRING, // TYPE_BYTES + CPPTYPE_UINT32, // TYPE_UINT32 + CPPTYPE_ENUM, // TYPE_ENUM + CPPTYPE_INT32, // TYPE_SFIXED32 + CPPTYPE_INT64, // TYPE_SFIXED64 + CPPTYPE_INT32, // TYPE_SINT32 + CPPTYPE_INT64, // TYPE_SINT64 +}; + +const char * const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = { + "ERROR", // 0 is reserved for errors + + "double", // TYPE_DOUBLE + "float", // TYPE_FLOAT + "int64", // TYPE_INT64 + "uint64", // TYPE_UINT64 + "int32", // TYPE_INT32 + "fixed64", // TYPE_FIXED64 + "fixed32", // TYPE_FIXED32 + "bool", // TYPE_BOOL + "string", // TYPE_STRING + "group", // TYPE_GROUP + "message", // TYPE_MESSAGE + "bytes", // TYPE_BYTES + "uint32", // TYPE_UINT32 + "enum", // TYPE_ENUM + "sfixed32", // TYPE_SFIXED32 + "sfixed64", // TYPE_SFIXED64 + "sint32", // TYPE_SINT32 + "sint64", // TYPE_SINT64 +}; + +const char * const FieldDescriptor::kCppTypeToName[MAX_CPPTYPE + 1] = { + "ERROR", // 0 is reserved for errors + + "int32", // CPPTYPE_INT32 + "int64", // CPPTYPE_INT64 + "uint32", // CPPTYPE_UINT32 + "uint64", // CPPTYPE_UINT64 + "double", // CPPTYPE_DOUBLE + "float", // CPPTYPE_FLOAT + "bool", // CPPTYPE_BOOL + "enum", // CPPTYPE_ENUM + "string", // CPPTYPE_STRING + "message", // CPPTYPE_MESSAGE +}; + +const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = { + "ERROR", // 0 is reserved for errors + + "optional", // LABEL_OPTIONAL + "required", // LABEL_REQUIRED + "repeated", // LABEL_REPEATED +}; + +#ifndef _MSC_VER // MSVC doesn't need these and won't even accept them. +const int FieldDescriptor::kMaxNumber; +const int FieldDescriptor::kFirstReservedNumber; +const int FieldDescriptor::kLastReservedNumber; +#endif + +namespace { + +const string kEmptyString; + +string ToCamelCase(const string& input) { + bool capitalize_next = false; + string result; + result.reserve(input.size()); + + for (int i = 0; i < input.size(); i++) { + if (input[i] == '_') { + capitalize_next = true; + } else if (capitalize_next) { + // Note: I distrust ctype.h due to locales. + if ('a' <= input[i] && input[i] <= 'z') { + result.push_back(input[i] - 'a' + 'A'); + } else { + result.push_back(input[i]); + } + capitalize_next = false; + } else { + result.push_back(input[i]); + } + } + + // Lower-case the first letter. + if (!result.empty() && 'A' <= result[0] && result[0] <= 'Z') { + result[0] = result[0] - 'A' + 'a'; + } + + return result; +} + +// A DescriptorPool contains a bunch of hash_maps to implement the +// various Find*By*() methods. Since hashtable lookups are O(1), it's +// most efficient to construct a fixed set of large hash_maps used by +// all objects in the pool rather than construct one or more small +// hash_maps for each object. +// +// The keys to these hash_maps are (parent, name) or (parent, number) +// pairs. Unfortunately STL doesn't provide hash functions for pair<>, +// so we must invent our own. +// +// TODO(kenton): Use StringPiece rather than const char* in keys? It would +// be a lot cleaner but we'd just have to convert it back to const char* +// for the open source release. + +typedef pair PointerStringPair; + +struct PointerStringPairEqual { + inline bool operator()(const PointerStringPair& a, + const PointerStringPair& b) const { + return a.first == b.first && strcmp(a.second, b.second) == 0; + } +}; + +template +struct PointerIntegerPairHash { + size_t operator()(const PairType& p) const { + // FIXME(kenton): What is the best way to compute this hash? I have + // no idea! This seems a bit better than an XOR. + return reinterpret_cast(p.first) * ((1 << 16) - 1) + p.second; + } + + // Used only by MSVC and platforms where hash_map is not available. + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; + inline bool operator()(const PairType& a, const PairType& b) const { + return a.first < b.first || + (a.first == b.first && a.second < b.second); + } +}; + +typedef pair DescriptorIntPair; +typedef pair EnumIntPair; + +struct PointerStringPairHash { + size_t operator()(const PointerStringPair& p) const { + // FIXME(kenton): What is the best way to compute this hash? I have + // no idea! This seems a bit better than an XOR. + hash cstring_hash; + return reinterpret_cast(p.first) * ((1 << 16) - 1) + + cstring_hash(p.second); + } + + // Used only by MSVC and platforms where hash_map is not available. + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; + inline bool operator()(const PointerStringPair& a, + const PointerStringPair& b) const { + if (a.first < b.first) return true; + if (a.first > b.first) return false; + return strcmp(a.second, b.second) < 0; + } +}; + + +struct Symbol { + enum Type { + NULL_SYMBOL, MESSAGE, FIELD, ENUM, ENUM_VALUE, SERVICE, METHOD, + PACKAGE + }; + Type type; + union { + const Descriptor* descriptor; + const FieldDescriptor* field_descriptor; + const EnumDescriptor* enum_descriptor; + const EnumValueDescriptor* enum_value_descriptor; + const ServiceDescriptor* service_descriptor; + const MethodDescriptor* method_descriptor; + const FileDescriptor* package_file_descriptor; + }; + + inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; } + inline bool IsNull() const { return type == NULL_SYMBOL; } + inline bool IsType() const { + return type == MESSAGE || type == ENUM; + } + inline bool IsAggregate() const { + return type == MESSAGE || type == PACKAGE + || type == ENUM || type == SERVICE; + } + +#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \ + inline explicit Symbol(const TYPE* value) { \ + type = TYPE_CONSTANT; \ + this->FIELD = value; \ + } + + CONSTRUCTOR(Descriptor , MESSAGE , descriptor ) + CONSTRUCTOR(FieldDescriptor , FIELD , field_descriptor ) + CONSTRUCTOR(EnumDescriptor , ENUM , enum_descriptor ) + CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor ) + CONSTRUCTOR(ServiceDescriptor , SERVICE , service_descriptor ) + CONSTRUCTOR(MethodDescriptor , METHOD , method_descriptor ) + CONSTRUCTOR(FileDescriptor , PACKAGE , package_file_descriptor) +#undef CONSTRUCTOR + + const FileDescriptor* GetFile() const { + switch (type) { + case NULL_SYMBOL: return NULL; + case MESSAGE : return descriptor ->file(); + case FIELD : return field_descriptor ->file(); + case ENUM : return enum_descriptor ->file(); + case ENUM_VALUE : return enum_value_descriptor->type()->file(); + case SERVICE : return service_descriptor ->file(); + case METHOD : return method_descriptor ->service()->file(); + case PACKAGE : return package_file_descriptor; + } + return NULL; + } +}; + +const Symbol kNullSymbol; + +typedef hash_map, streq> + SymbolsByNameMap; +typedef hash_map + SymbolsByParentMap; +typedef hash_map, streq> + FilesByNameMap; +typedef hash_map + FieldsByNameMap; +typedef hash_map > + FieldsByNumberMap; +typedef hash_map > + EnumValuesByNumberMap; +// This is a map rather than a hash_map, since we use it to iterate +// through all the extensions that extend a given Descriptor, and an +// ordered data structure that implements lower_bound is convenient +// for that. +typedef map + ExtensionsGroupedByDescriptorMap; + +} // anonymous namespace + +// =================================================================== +// DescriptorPool::Tables + +class DescriptorPool::Tables { + public: + Tables(); + ~Tables(); + + // Record the current state of the tables to the stack of checkpoints. + // Each call to AddCheckpoint() must be paired with exactly one call to either + // ClearLastCheckpoint() or RollbackToLastCheckpoint(). + // + // This is used when building files, since some kinds of validation errors + // cannot be detected until the file's descriptors have already been added to + // the tables. + // + // This supports recursive checkpoints, since building a file may trigger + // recursive building of other files. Note that recursive checkpoints are not + // normally necessary; explicit dependencies are built prior to checkpointing. + // So although we recursively build transitive imports, there is at most one + // checkpoint in the stack during dependency building. + // + // Recursive checkpoints only arise during cross-linking of the descriptors. + // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and + // friends. If the pending file references an unknown symbol + // (e.g., it is not defined in the pending file's explicit dependencies), and + // the pool is using a fallback database, and that database contains a file + // defining that symbol, and that file has not yet been built by the pool, + // the pool builds the file during cross-linking, leading to another + // checkpoint. + void AddCheckpoint(); + + // Mark the last checkpoint as having cleared successfully, removing it from + // the stack. If the stack is empty, all pending symbols will be committed. + // + // Note that this does not guarantee that the symbols added since the last + // checkpoint won't be rolled back: if a checkpoint gets rolled back, + // everything past that point gets rolled back, including symbols added after + // checkpoints that were pushed onto the stack after it and marked as cleared. + void ClearLastCheckpoint(); + + // Roll back the Tables to the state of the checkpoint at the top of the + // stack, removing everything that was added after that point. + void RollbackToLastCheckpoint(); + + // The stack of files which are currently being built. Used to detect + // cyclic dependencies when loading files from a DescriptorDatabase. Not + // used when fallback_database_ == NULL. + vector pending_files_; + + // A set of files which we have tried to load from the fallback database + // and encountered errors. We will not attempt to load them again. + // Not used when fallback_database_ == NULL. + hash_set known_bad_files_; + + // The set of descriptors for which we've already loaded the full + // set of extensions numbers from fallback_database_. + hash_set extensions_loaded_from_db_; + + // ----------------------------------------------------------------- + // Finding items. + + // Find symbols. This returns a null Symbol (symbol.IsNull() is true) + // if not found. + inline Symbol FindSymbol(const string& key) const; + + // This implements the body of DescriptorPool::Find*ByName(). It should + // really be a private method of DescriptorPool, but that would require + // declaring Symbol in descriptor.h, which would drag all kinds of other + // stuff into the header. Yay C++. + Symbol FindByNameHelper( + const DescriptorPool* pool, const string& name) const; + + // These return NULL if not found. + inline const FileDescriptor* FindFile(const string& key) const; + inline const FieldDescriptor* FindExtension(const Descriptor* extendee, + int number); + inline void FindAllExtensions(const Descriptor* extendee, + vector* out) const; + + // ----------------------------------------------------------------- + // Adding items. + + // These add items to the corresponding tables. They return false if + // the key already exists in the table. For AddSymbol(), the string passed + // in must be one that was constructed using AllocateString(), as it will + // be used as a key in the symbols_by_name_ map without copying. + bool AddSymbol(const string& full_name, Symbol symbol); + bool AddFile(const FileDescriptor* file); + bool AddExtension(const FieldDescriptor* field); + + // ----------------------------------------------------------------- + // Allocating memory. + + // Allocate an object which will be reclaimed when the pool is + // destroyed. Note that the object's destructor will never be called, + // so its fields must be plain old data (primitive data types and + // pointers). All of the descriptor types are such objects. + template Type* Allocate(); + + // Allocate an array of objects which will be reclaimed when the + // pool in destroyed. Again, destructors are never called. + template Type* AllocateArray(int count); + + // Allocate a string which will be destroyed when the pool is destroyed. + // The string is initialized to the given value for convenience. + string* AllocateString(const string& value); + + // Allocate a protocol message object. Some older versions of GCC have + // trouble understanding explicit template instantiations in some cases, so + // in those cases we have to pass a dummy pointer of the right type as the + // parameter instead of specifying the type explicitly. + template Type* AllocateMessage(Type* dummy = NULL); + + // Allocate a FileDescriptorTables object. + FileDescriptorTables* AllocateFileTables(); + + private: + vector strings_; // All strings in the pool. + vector messages_; // All messages in the pool. + vector file_tables_; // All file tables in the pool. + vector allocations_; // All other memory allocated in the pool. + + SymbolsByNameMap symbols_by_name_; + FilesByNameMap files_by_name_; + ExtensionsGroupedByDescriptorMap extensions_; + + struct CheckPoint { + explicit CheckPoint(const Tables* tables) + : strings_before_checkpoint(tables->strings_.size()), + messages_before_checkpoint(tables->messages_.size()), + file_tables_before_checkpoint(tables->file_tables_.size()), + allocations_before_checkpoint(tables->allocations_.size()), + pending_symbols_before_checkpoint( + tables->symbols_after_checkpoint_.size()), + pending_files_before_checkpoint( + tables->files_after_checkpoint_.size()), + pending_extensions_before_checkpoint( + tables->extensions_after_checkpoint_.size()) { + } + int strings_before_checkpoint; + int messages_before_checkpoint; + int file_tables_before_checkpoint; + int allocations_before_checkpoint; + int pending_symbols_before_checkpoint; + int pending_files_before_checkpoint; + int pending_extensions_before_checkpoint; + }; + vector checkpoints_; + vector symbols_after_checkpoint_; + vector files_after_checkpoint_; + vector extensions_after_checkpoint_; + + // Allocate some bytes which will be reclaimed when the pool is + // destroyed. + void* AllocateBytes(int size); +}; + +// Contains tables specific to a particular file. These tables are not +// modified once the file has been constructed, so they need not be +// protected by a mutex. This makes operations that depend only on the +// contents of a single file -- e.g. Descriptor::FindFieldByName() -- +// lock-free. +// +// For historical reasons, the definitions of the methods of +// FileDescriptorTables and DescriptorPool::Tables are interleaved below. +// These used to be a single class. +class FileDescriptorTables { + public: + FileDescriptorTables(); + ~FileDescriptorTables(); + + // Empty table, used with placeholder files. + static const FileDescriptorTables kEmpty; + + // ----------------------------------------------------------------- + // Finding items. + + // Find symbols. These return a null Symbol (symbol.IsNull() is true) + // if not found. + inline Symbol FindNestedSymbol(const void* parent, + const string& name) const; + inline Symbol FindNestedSymbolOfType(const void* parent, + const string& name, + const Symbol::Type type) const; + + // These return NULL if not found. + inline const FieldDescriptor* FindFieldByNumber( + const Descriptor* parent, int number) const; + inline const FieldDescriptor* FindFieldByLowercaseName( + const void* parent, const string& lowercase_name) const; + inline const FieldDescriptor* FindFieldByCamelcaseName( + const void* parent, const string& camelcase_name) const; + inline const EnumValueDescriptor* FindEnumValueByNumber( + const EnumDescriptor* parent, int number) const; + + // ----------------------------------------------------------------- + // Adding items. + + // These add items to the corresponding tables. They return false if + // the key already exists in the table. For AddAliasUnderParent(), the + // string passed in must be one that was constructed using AllocateString(), + // as it will be used as a key in the symbols_by_parent_ map without copying. + bool AddAliasUnderParent(const void* parent, const string& name, + Symbol symbol); + bool AddFieldByNumber(const FieldDescriptor* field); + bool AddEnumValueByNumber(const EnumValueDescriptor* value); + + // Adds the field to the lowercase_name and camelcase_name maps. Never + // fails because we allow duplicates; the first field by the name wins. + void AddFieldByStylizedNames(const FieldDescriptor* field); + + private: + SymbolsByParentMap symbols_by_parent_; + FieldsByNameMap fields_by_lowercase_name_; + FieldsByNameMap fields_by_camelcase_name_; + FieldsByNumberMap fields_by_number_; // Not including extensions. + EnumValuesByNumberMap enum_values_by_number_; +}; + +DescriptorPool::Tables::Tables() + // Start some hash_map and hash_set objects with a small # of buckets + : known_bad_files_(3), + extensions_loaded_from_db_(3), + symbols_by_name_(3), + files_by_name_(3) {} + + +DescriptorPool::Tables::~Tables() { + GOOGLE_DCHECK(checkpoints_.empty()); + // Note that the deletion order is important, since the destructors of some + // messages may refer to objects in allocations_. + STLDeleteElements(&messages_); + for (int i = 0; i < allocations_.size(); i++) { + operator delete(allocations_[i]); + } + STLDeleteElements(&strings_); + STLDeleteElements(&file_tables_); +} + +FileDescriptorTables::FileDescriptorTables() + // Initialize all the hash tables to start out with a small # of buckets + : symbols_by_parent_(3), + fields_by_lowercase_name_(3), + fields_by_camelcase_name_(3), + fields_by_number_(3), + enum_values_by_number_(3) { +} + +FileDescriptorTables::~FileDescriptorTables() {} + +const FileDescriptorTables FileDescriptorTables::kEmpty; + +void DescriptorPool::Tables::AddCheckpoint() { + checkpoints_.push_back(CheckPoint(this)); +} + +void DescriptorPool::Tables::ClearLastCheckpoint() { + GOOGLE_DCHECK(!checkpoints_.empty()); + checkpoints_.pop_back(); + if (checkpoints_.empty()) { + // All checkpoints have been cleared: we can now commit all of the pending + // data. + symbols_after_checkpoint_.clear(); + files_after_checkpoint_.clear(); + extensions_after_checkpoint_.clear(); + } +} + +void DescriptorPool::Tables::RollbackToLastCheckpoint() { + GOOGLE_DCHECK(!checkpoints_.empty()); + const CheckPoint& checkpoint = checkpoints_.back(); + + for (int i = checkpoint.pending_symbols_before_checkpoint; + i < symbols_after_checkpoint_.size(); + i++) { + symbols_by_name_.erase(symbols_after_checkpoint_[i]); + } + for (int i = checkpoint.pending_files_before_checkpoint; + i < files_after_checkpoint_.size(); + i++) { + files_by_name_.erase(files_after_checkpoint_[i]); + } + for (int i = checkpoint.pending_extensions_before_checkpoint; + i < extensions_after_checkpoint_.size(); + i++) { + extensions_.erase(extensions_after_checkpoint_[i]); + } + + symbols_after_checkpoint_.resize( + checkpoint.pending_symbols_before_checkpoint); + files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint); + extensions_after_checkpoint_.resize( + checkpoint.pending_extensions_before_checkpoint); + + STLDeleteContainerPointers( + strings_.begin() + checkpoint.strings_before_checkpoint, strings_.end()); + STLDeleteContainerPointers( + messages_.begin() + checkpoint.messages_before_checkpoint, + messages_.end()); + STLDeleteContainerPointers( + file_tables_.begin() + checkpoint.file_tables_before_checkpoint, + file_tables_.end()); + for (int i = checkpoint.allocations_before_checkpoint; + i < allocations_.size(); + i++) { + operator delete(allocations_[i]); + } + + strings_.resize(checkpoint.strings_before_checkpoint); + messages_.resize(checkpoint.messages_before_checkpoint); + file_tables_.resize(checkpoint.file_tables_before_checkpoint); + allocations_.resize(checkpoint.allocations_before_checkpoint); + checkpoints_.pop_back(); +} + +// ------------------------------------------------------------------- + +inline Symbol DescriptorPool::Tables::FindSymbol(const string& key) const { + const Symbol* result = FindOrNull(symbols_by_name_, key.c_str()); + if (result == NULL) { + return kNullSymbol; + } else { + return *result; + } +} + +inline Symbol FileDescriptorTables::FindNestedSymbol( + const void* parent, const string& name) const { + const Symbol* result = + FindOrNull(symbols_by_parent_, PointerStringPair(parent, name.c_str())); + if (result == NULL) { + return kNullSymbol; + } else { + return *result; + } +} + +inline Symbol FileDescriptorTables::FindNestedSymbolOfType( + const void* parent, const string& name, const Symbol::Type type) const { + Symbol result = FindNestedSymbol(parent, name); + if (result.type != type) return kNullSymbol; + return result; +} + +Symbol DescriptorPool::Tables::FindByNameHelper( + const DescriptorPool* pool, const string& name) const { + MutexLockMaybe lock(pool->mutex_); + Symbol result = FindSymbol(name); + + if (result.IsNull() && pool->underlay_ != NULL) { + // Symbol not found; check the underlay. + result = + pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name); + } + + if (result.IsNull()) { + // Symbol still not found, so check fallback database. + if (pool->TryFindSymbolInFallbackDatabase(name)) { + result = FindSymbol(name); + } + } + + return result; +} + +inline const FileDescriptor* DescriptorPool::Tables::FindFile( + const string& key) const { + return FindPtrOrNull(files_by_name_, key.c_str()); +} + +inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber( + const Descriptor* parent, int number) const { + return FindPtrOrNull(fields_by_number_, make_pair(parent, number)); +} + +inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName( + const void* parent, const string& lowercase_name) const { + return FindPtrOrNull(fields_by_lowercase_name_, + PointerStringPair(parent, lowercase_name.c_str())); +} + +inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName( + const void* parent, const string& camelcase_name) const { + return FindPtrOrNull(fields_by_camelcase_name_, + PointerStringPair(parent, camelcase_name.c_str())); +} + +inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber( + const EnumDescriptor* parent, int number) const { + return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number)); +} + +inline const FieldDescriptor* DescriptorPool::Tables::FindExtension( + const Descriptor* extendee, int number) { + return FindPtrOrNull(extensions_, make_pair(extendee, number)); +} + +inline void DescriptorPool::Tables::FindAllExtensions( + const Descriptor* extendee, vector* out) const { + ExtensionsGroupedByDescriptorMap::const_iterator it = + extensions_.lower_bound(make_pair(extendee, 0)); + for (; it != extensions_.end() && it->first.first == extendee; ++it) { + out->push_back(it->second); + } +} + +// ------------------------------------------------------------------- + +bool DescriptorPool::Tables::AddSymbol( + const string& full_name, Symbol symbol) { + if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) { + symbols_after_checkpoint_.push_back(full_name.c_str()); + return true; + } else { + return false; + } +} + +bool FileDescriptorTables::AddAliasUnderParent( + const void* parent, const string& name, Symbol symbol) { + PointerStringPair by_parent_key(parent, name.c_str()); + return InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol); +} + +bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) { + if (InsertIfNotPresent(&files_by_name_, file->name().c_str(), file)) { + files_after_checkpoint_.push_back(file->name().c_str()); + return true; + } else { + return false; + } +} + +void FileDescriptorTables::AddFieldByStylizedNames( + const FieldDescriptor* field) { + const void* parent; + if (field->is_extension()) { + if (field->extension_scope() == NULL) { + parent = field->file(); + } else { + parent = field->extension_scope(); + } + } else { + parent = field->containing_type(); + } + + PointerStringPair lowercase_key(parent, field->lowercase_name().c_str()); + InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field); + + PointerStringPair camelcase_key(parent, field->camelcase_name().c_str()); + InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field); +} + +bool FileDescriptorTables::AddFieldByNumber(const FieldDescriptor* field) { + DescriptorIntPair key(field->containing_type(), field->number()); + return InsertIfNotPresent(&fields_by_number_, key, field); +} + +bool FileDescriptorTables::AddEnumValueByNumber( + const EnumValueDescriptor* value) { + EnumIntPair key(value->type(), value->number()); + return InsertIfNotPresent(&enum_values_by_number_, key, value); +} + +bool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) { + DescriptorIntPair key(field->containing_type(), field->number()); + if (InsertIfNotPresent(&extensions_, key, field)) { + extensions_after_checkpoint_.push_back(key); + return true; + } else { + return false; + } +} + +// ------------------------------------------------------------------- + +template +Type* DescriptorPool::Tables::Allocate() { + return reinterpret_cast(AllocateBytes(sizeof(Type))); +} + +template +Type* DescriptorPool::Tables::AllocateArray(int count) { + return reinterpret_cast(AllocateBytes(sizeof(Type) * count)); +} + +string* DescriptorPool::Tables::AllocateString(const string& value) { + string* result = new string(value); + strings_.push_back(result); + return result; +} + +template +Type* DescriptorPool::Tables::AllocateMessage(Type* dummy) { + Type* result = new Type; + messages_.push_back(result); + return result; +} + +FileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() { + FileDescriptorTables* result = new FileDescriptorTables; + file_tables_.push_back(result); + return result; +} + +void* DescriptorPool::Tables::AllocateBytes(int size) { + // TODO(kenton): Would it be worthwhile to implement this in some more + // sophisticated way? Probably not for the open source release, but for + // internal use we could easily plug in one of our existing memory pool + // allocators... + if (size == 0) return NULL; + + void* result = operator new(size); + allocations_.push_back(result); + return result; +} + +// =================================================================== +// DescriptorPool + +DescriptorPool::ErrorCollector::~ErrorCollector() {} + +DescriptorPool::DescriptorPool() + : mutex_(NULL), + fallback_database_(NULL), + default_error_collector_(NULL), + underlay_(NULL), + tables_(new Tables), + enforce_dependencies_(true), + allow_unknown_(false) {} + +DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database, + ErrorCollector* error_collector) + : mutex_(new Mutex), + fallback_database_(fallback_database), + default_error_collector_(error_collector), + underlay_(NULL), + tables_(new Tables), + enforce_dependencies_(true), + allow_unknown_(false) { +} + +DescriptorPool::DescriptorPool(const DescriptorPool* underlay) + : mutex_(NULL), + fallback_database_(NULL), + default_error_collector_(NULL), + underlay_(underlay), + tables_(new Tables), + enforce_dependencies_(true), + allow_unknown_(false) {} + +DescriptorPool::~DescriptorPool() { + if (mutex_ != NULL) delete mutex_; +} + +// DescriptorPool::BuildFile() defined later. +// DescriptorPool::BuildFileCollectingErrors() defined later. + +void DescriptorPool::InternalDontEnforceDependencies() { + enforce_dependencies_ = false; +} + +bool DescriptorPool::InternalIsFileLoaded(const string& filename) const { + MutexLockMaybe lock(mutex_); + return tables_->FindFile(filename) != NULL; +} + +// generated_pool ==================================================== + +namespace { + + +EncodedDescriptorDatabase* generated_database_ = NULL; +DescriptorPool* generated_pool_ = NULL; +GOOGLE_PROTOBUF_DECLARE_ONCE(generated_pool_init_); + +void DeleteGeneratedPool() { + delete generated_database_; + generated_database_ = NULL; + delete generated_pool_; + generated_pool_ = NULL; +} + +static void InitGeneratedPool() { + generated_database_ = new EncodedDescriptorDatabase; + generated_pool_ = new DescriptorPool(generated_database_); + + internal::OnShutdown(&DeleteGeneratedPool); +} + +inline void InitGeneratedPoolOnce() { + ::google::protobuf::GoogleOnceInit(&generated_pool_init_, &InitGeneratedPool); +} + +} // anonymous namespace + +const DescriptorPool* DescriptorPool::generated_pool() { + InitGeneratedPoolOnce(); + return generated_pool_; +} + +DescriptorPool* DescriptorPool::internal_generated_pool() { + InitGeneratedPoolOnce(); + return generated_pool_; +} + +void DescriptorPool::InternalAddGeneratedFile( + const void* encoded_file_descriptor, int size) { + // So, this function is called in the process of initializing the + // descriptors for generated proto classes. Each generated .pb.cc file + // has an internal procedure called AddDescriptors() which is called at + // process startup, and that function calls this one in order to register + // the raw bytes of the FileDescriptorProto representing the file. + // + // We do not actually construct the descriptor objects right away. We just + // hang on to the bytes until they are actually needed. We actually construct + // the descriptor the first time one of the following things happens: + // * Someone calls a method like descriptor(), GetDescriptor(), or + // GetReflection() on the generated types, which requires returning the + // descriptor or an object based on it. + // * Someone looks up the descriptor in DescriptorPool::generated_pool(). + // + // Once one of these happens, the DescriptorPool actually parses the + // FileDescriptorProto and generates a FileDescriptor (and all its children) + // based on it. + // + // Note that FileDescriptorProto is itself a generated protocol message. + // Therefore, when we parse one, we have to be very careful to avoid using + // any descriptor-based operations, since this might cause infinite recursion + // or deadlock. + InitGeneratedPoolOnce(); + GOOGLE_CHECK(generated_database_->Add(encoded_file_descriptor, size)); +} + + +// Find*By* methods ================================================== + +// TODO(kenton): There's a lot of repeated code here, but I'm not sure if +// there's any good way to factor it out. Think about this some time when +// there's nothing more important to do (read: never). + +const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const { + MutexLockMaybe lock(mutex_); + const FileDescriptor* result = tables_->FindFile(name); + if (result != NULL) return result; + if (underlay_ != NULL) { + result = underlay_->FindFileByName(name); + if (result != NULL) return result; + } + if (TryFindFileInFallbackDatabase(name)) { + result = tables_->FindFile(name); + if (result != NULL) return result; + } + return NULL; +} + +const FileDescriptor* DescriptorPool::FindFileContainingSymbol( + const string& symbol_name) const { + MutexLockMaybe lock(mutex_); + Symbol result = tables_->FindSymbol(symbol_name); + if (!result.IsNull()) return result.GetFile(); + if (underlay_ != NULL) { + const FileDescriptor* file_result = + underlay_->FindFileContainingSymbol(symbol_name); + if (file_result != NULL) return file_result; + } + if (TryFindSymbolInFallbackDatabase(symbol_name)) { + result = tables_->FindSymbol(symbol_name); + if (!result.IsNull()) return result.GetFile(); + } + return NULL; +} + +const Descriptor* DescriptorPool::FindMessageTypeByName( + const string& name) const { + Symbol result = tables_->FindByNameHelper(this, name); + return (result.type == Symbol::MESSAGE) ? result.descriptor : NULL; +} + +const FieldDescriptor* DescriptorPool::FindFieldByName( + const string& name) const { + Symbol result = tables_->FindByNameHelper(this, name); + if (result.type == Symbol::FIELD && + !result.field_descriptor->is_extension()) { + return result.field_descriptor; + } else { + return NULL; + } +} + +const FieldDescriptor* DescriptorPool::FindExtensionByName( + const string& name) const { + Symbol result = tables_->FindByNameHelper(this, name); + if (result.type == Symbol::FIELD && + result.field_descriptor->is_extension()) { + return result.field_descriptor; + } else { + return NULL; + } +} + +const EnumDescriptor* DescriptorPool::FindEnumTypeByName( + const string& name) const { + Symbol result = tables_->FindByNameHelper(this, name); + return (result.type == Symbol::ENUM) ? result.enum_descriptor : NULL; +} + +const EnumValueDescriptor* DescriptorPool::FindEnumValueByName( + const string& name) const { + Symbol result = tables_->FindByNameHelper(this, name); + return (result.type == Symbol::ENUM_VALUE) ? + result.enum_value_descriptor : NULL; +} + +const ServiceDescriptor* DescriptorPool::FindServiceByName( + const string& name) const { + Symbol result = tables_->FindByNameHelper(this, name); + return (result.type == Symbol::SERVICE) ? result.service_descriptor : NULL; +} + +const MethodDescriptor* DescriptorPool::FindMethodByName( + const string& name) const { + Symbol result = tables_->FindByNameHelper(this, name); + return (result.type == Symbol::METHOD) ? result.method_descriptor : NULL; +} + +const FieldDescriptor* DescriptorPool::FindExtensionByNumber( + const Descriptor* extendee, int number) const { + MutexLockMaybe lock(mutex_); + const FieldDescriptor* result = tables_->FindExtension(extendee, number); + if (result != NULL) { + return result; + } + if (underlay_ != NULL) { + result = underlay_->FindExtensionByNumber(extendee, number); + if (result != NULL) return result; + } + if (TryFindExtensionInFallbackDatabase(extendee, number)) { + result = tables_->FindExtension(extendee, number); + if (result != NULL) { + return result; + } + } + return NULL; +} + +void DescriptorPool::FindAllExtensions( + const Descriptor* extendee, vector* out) const { + MutexLockMaybe lock(mutex_); + + // Initialize tables_->extensions_ from the fallback database first + // (but do this only once per descriptor). + if (fallback_database_ != NULL && + tables_->extensions_loaded_from_db_.count(extendee) == 0) { + vector numbers; + if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(), + &numbers)) { + for (int i = 0; i < numbers.size(); ++i) { + int number = numbers[i]; + if (tables_->FindExtension(extendee, number) == NULL) { + TryFindExtensionInFallbackDatabase(extendee, number); + } + } + tables_->extensions_loaded_from_db_.insert(extendee); + } + } + + tables_->FindAllExtensions(extendee, out); + if (underlay_ != NULL) { + underlay_->FindAllExtensions(extendee, out); + } +} + +// ------------------------------------------------------------------- + +const FieldDescriptor* +Descriptor::FindFieldByNumber(int key) const { + const FieldDescriptor* result = + file()->tables_->FindFieldByNumber(this, key); + if (result == NULL || result->is_extension()) { + return NULL; + } else { + return result; + } +} + +const FieldDescriptor* +Descriptor::FindFieldByLowercaseName(const string& key) const { + const FieldDescriptor* result = + file()->tables_->FindFieldByLowercaseName(this, key); + if (result == NULL || result->is_extension()) { + return NULL; + } else { + return result; + } +} + +const FieldDescriptor* +Descriptor::FindFieldByCamelcaseName(const string& key) const { + const FieldDescriptor* result = + file()->tables_->FindFieldByCamelcaseName(this, key); + if (result == NULL || result->is_extension()) { + return NULL; + } else { + return result; + } +} + +const FieldDescriptor* +Descriptor::FindFieldByName(const string& key) const { + Symbol result = + file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); + if (!result.IsNull() && !result.field_descriptor->is_extension()) { + return result.field_descriptor; + } else { + return NULL; + } +} + +const FieldDescriptor* +Descriptor::FindExtensionByName(const string& key) const { + Symbol result = + file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); + if (!result.IsNull() && result.field_descriptor->is_extension()) { + return result.field_descriptor; + } else { + return NULL; + } +} + +const FieldDescriptor* +Descriptor::FindExtensionByLowercaseName(const string& key) const { + const FieldDescriptor* result = + file()->tables_->FindFieldByLowercaseName(this, key); + if (result == NULL || !result->is_extension()) { + return NULL; + } else { + return result; + } +} + +const FieldDescriptor* +Descriptor::FindExtensionByCamelcaseName(const string& key) const { + const FieldDescriptor* result = + file()->tables_->FindFieldByCamelcaseName(this, key); + if (result == NULL || !result->is_extension()) { + return NULL; + } else { + return result; + } +} + +const Descriptor* +Descriptor::FindNestedTypeByName(const string& key) const { + Symbol result = + file()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); + if (!result.IsNull()) { + return result.descriptor; + } else { + return NULL; + } +} + +const EnumDescriptor* +Descriptor::FindEnumTypeByName(const string& key) const { + Symbol result = + file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); + if (!result.IsNull()) { + return result.enum_descriptor; + } else { + return NULL; + } +} + +const EnumValueDescriptor* +Descriptor::FindEnumValueByName(const string& key) const { + Symbol result = + file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); + if (!result.IsNull()) { + return result.enum_value_descriptor; + } else { + return NULL; + } +} + +const EnumValueDescriptor* +EnumDescriptor::FindValueByName(const string& key) const { + Symbol result = + file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); + if (!result.IsNull()) { + return result.enum_value_descriptor; + } else { + return NULL; + } +} + +const EnumValueDescriptor* +EnumDescriptor::FindValueByNumber(int key) const { + return file()->tables_->FindEnumValueByNumber(this, key); +} + +const MethodDescriptor* +ServiceDescriptor::FindMethodByName(const string& key) const { + Symbol result = + file()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD); + if (!result.IsNull()) { + return result.method_descriptor; + } else { + return NULL; + } +} + +const Descriptor* +FileDescriptor::FindMessageTypeByName(const string& key) const { + Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); + if (!result.IsNull()) { + return result.descriptor; + } else { + return NULL; + } +} + +const EnumDescriptor* +FileDescriptor::FindEnumTypeByName(const string& key) const { + Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); + if (!result.IsNull()) { + return result.enum_descriptor; + } else { + return NULL; + } +} + +const EnumValueDescriptor* +FileDescriptor::FindEnumValueByName(const string& key) const { + Symbol result = + tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); + if (!result.IsNull()) { + return result.enum_value_descriptor; + } else { + return NULL; + } +} + +const ServiceDescriptor* +FileDescriptor::FindServiceByName(const string& key) const { + Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE); + if (!result.IsNull()) { + return result.service_descriptor; + } else { + return NULL; + } +} + +const FieldDescriptor* +FileDescriptor::FindExtensionByName(const string& key) const { + Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); + if (!result.IsNull() && result.field_descriptor->is_extension()) { + return result.field_descriptor; + } else { + return NULL; + } +} + +const FieldDescriptor* +FileDescriptor::FindExtensionByLowercaseName(const string& key) const { + const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key); + if (result == NULL || !result->is_extension()) { + return NULL; + } else { + return result; + } +} + +const FieldDescriptor* +FileDescriptor::FindExtensionByCamelcaseName(const string& key) const { + const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key); + if (result == NULL || !result->is_extension()) { + return NULL; + } else { + return result; + } +} + +bool Descriptor::IsExtensionNumber(int number) const { + // Linear search should be fine because we don't expect a message to have + // more than a couple extension ranges. + for (int i = 0; i < extension_range_count(); i++) { + if (number >= extension_range(i)->start && + number < extension_range(i)->end) { + return true; + } + } + return false; +} + +// ------------------------------------------------------------------- + +bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const { + if (fallback_database_ == NULL) return false; + + if (tables_->known_bad_files_.count(name) > 0) return false; + + FileDescriptorProto file_proto; + if (!fallback_database_->FindFileByName(name, &file_proto) || + BuildFileFromDatabase(file_proto) == NULL) { + tables_->known_bad_files_.insert(name); + return false; + } + + return true; +} + +bool DescriptorPool::IsSubSymbolOfBuiltType(const string& name) const { + string prefix = name; + for (;;) { + string::size_type dot_pos = prefix.find_last_of('.'); + if (dot_pos == string::npos) { + break; + } + prefix = prefix.substr(0, dot_pos); + Symbol symbol = tables_->FindSymbol(prefix); + // If the symbol type is anything other than PACKAGE, then its complete + // definition is already known. + if (!symbol.IsNull() && symbol.type != Symbol::PACKAGE) { + return true; + } + } + if (underlay_ != NULL) { + // Check to see if any prefix of this symbol exists in the underlay. + return underlay_->IsSubSymbolOfBuiltType(name); + } + return false; +} + +bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const { + if (fallback_database_ == NULL) return false; + + // We skip looking in the fallback database if the name is a sub-symbol of + // any descriptor that already exists in the descriptor pool (except for + // package descriptors). This is valid because all symbols except for + // packages are defined in a single file, so if the symbol exists then we + // should already have its definition. + // + // The other reason to do this is to support "overriding" type definitions + // by merging two databases that define the same type. (Yes, people do + // this.) The main difficulty with making this work is that + // FindFileContainingSymbol() is allowed to return both false positives + // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and false + // negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase). When two + // such databases are merged, looking up a non-existent sub-symbol of a type + // that already exists in the descriptor pool can result in an attempt to + // load multiple definitions of the same type. The check below avoids this. + if (IsSubSymbolOfBuiltType(name)) return false; + + FileDescriptorProto file_proto; + if (!fallback_database_->FindFileContainingSymbol(name, &file_proto)) { + return false; + } + + if (tables_->FindFile(file_proto.name()) != NULL) { + // We've already loaded this file, and it apparently doesn't contain the + // symbol we're looking for. Some DescriptorDatabases return false + // positives. + return false; + } + + if (BuildFileFromDatabase(file_proto) == NULL) { + return false; + } + + return true; +} + +bool DescriptorPool::TryFindExtensionInFallbackDatabase( + const Descriptor* containing_type, int field_number) const { + if (fallback_database_ == NULL) return false; + + FileDescriptorProto file_proto; + if (!fallback_database_->FindFileContainingExtension( + containing_type->full_name(), field_number, &file_proto)) { + return false; + } + + if (tables_->FindFile(file_proto.name()) != NULL) { + // We've already loaded this file, and it apparently doesn't contain the + // extension we're looking for. Some DescriptorDatabases return false + // positives. + return false; + } + + if (BuildFileFromDatabase(file_proto) == NULL) { + return false; + } + + return true; +} + +// =================================================================== + +string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const { + GOOGLE_CHECK(has_default_value()) << "No default value"; + switch (cpp_type()) { + case CPPTYPE_INT32: + return SimpleItoa(default_value_int32()); + break; + case CPPTYPE_INT64: + return SimpleItoa(default_value_int64()); + break; + case CPPTYPE_UINT32: + return SimpleItoa(default_value_uint32()); + break; + case CPPTYPE_UINT64: + return SimpleItoa(default_value_uint64()); + break; + case CPPTYPE_FLOAT: + return SimpleFtoa(default_value_float()); + break; + case CPPTYPE_DOUBLE: + return SimpleDtoa(default_value_double()); + break; + case CPPTYPE_BOOL: + return default_value_bool() ? "true" : "false"; + break; + case CPPTYPE_STRING: + if (quote_string_type) { + return "\"" + CEscape(default_value_string()) + "\""; + } else { + if (type() == TYPE_BYTES) { + return CEscape(default_value_string()); + } else { + return default_value_string(); + } + } + break; + case CPPTYPE_ENUM: + return default_value_enum()->name(); + break; + case CPPTYPE_MESSAGE: + GOOGLE_LOG(DFATAL) << "Messages can't have default values!"; + break; + } + GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string"; + return ""; +} + +// CopyTo methods ==================================================== + +void FileDescriptor::CopyTo(FileDescriptorProto* proto) const { + proto->set_name(name()); + if (!package().empty()) proto->set_package(package()); + + for (int i = 0; i < dependency_count(); i++) { + proto->add_dependency(dependency(i)->name()); + } + + for (int i = 0; i < public_dependency_count(); i++) { + proto->add_public_dependency(public_dependencies_[i]); + } + + for (int i = 0; i < weak_dependency_count(); i++) { + proto->add_weak_dependency(weak_dependencies_[i]); + } + + for (int i = 0; i < message_type_count(); i++) { + message_type(i)->CopyTo(proto->add_message_type()); + } + for (int i = 0; i < enum_type_count(); i++) { + enum_type(i)->CopyTo(proto->add_enum_type()); + } + for (int i = 0; i < service_count(); i++) { + service(i)->CopyTo(proto->add_service()); + } + for (int i = 0; i < extension_count(); i++) { + extension(i)->CopyTo(proto->add_extension()); + } + + if (&options() != &FileOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void FileDescriptor::CopySourceCodeInfoTo(FileDescriptorProto* proto) const { + if (source_code_info_ != &SourceCodeInfo::default_instance()) { + proto->mutable_source_code_info()->CopyFrom(*source_code_info_); + } +} + +void Descriptor::CopyTo(DescriptorProto* proto) const { + proto->set_name(name()); + + for (int i = 0; i < field_count(); i++) { + field(i)->CopyTo(proto->add_field()); + } + for (int i = 0; i < nested_type_count(); i++) { + nested_type(i)->CopyTo(proto->add_nested_type()); + } + for (int i = 0; i < enum_type_count(); i++) { + enum_type(i)->CopyTo(proto->add_enum_type()); + } + for (int i = 0; i < extension_range_count(); i++) { + DescriptorProto::ExtensionRange* range = proto->add_extension_range(); + range->set_start(extension_range(i)->start); + range->set_end(extension_range(i)->end); + } + for (int i = 0; i < extension_count(); i++) { + extension(i)->CopyTo(proto->add_extension()); + } + + if (&options() != &MessageOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const { + proto->set_name(name()); + proto->set_number(number()); + + // Some compilers do not allow static_cast directly between two enum types, + // so we must cast to int first. + proto->set_label(static_cast( + implicit_cast(label()))); + proto->set_type(static_cast( + implicit_cast(type()))); + + if (is_extension()) { + if (!containing_type()->is_unqualified_placeholder_) { + proto->set_extendee("."); + } + proto->mutable_extendee()->append(containing_type()->full_name()); + } + + if (cpp_type() == CPPTYPE_MESSAGE) { + if (message_type()->is_placeholder_) { + // We don't actually know if the type is a message type. It could be + // an enum. + proto->clear_type(); + } + + if (!message_type()->is_unqualified_placeholder_) { + proto->set_type_name("."); + } + proto->mutable_type_name()->append(message_type()->full_name()); + } else if (cpp_type() == CPPTYPE_ENUM) { + if (!enum_type()->is_unqualified_placeholder_) { + proto->set_type_name("."); + } + proto->mutable_type_name()->append(enum_type()->full_name()); + } + + if (has_default_value()) { + proto->set_default_value(DefaultValueAsString(false)); + } + + if (&options() != &FieldOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const { + proto->set_name(name()); + + for (int i = 0; i < value_count(); i++) { + value(i)->CopyTo(proto->add_value()); + } + + if (&options() != &EnumOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const { + proto->set_name(name()); + proto->set_number(number()); + + if (&options() != &EnumValueOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const { + proto->set_name(name()); + + for (int i = 0; i < method_count(); i++) { + method(i)->CopyTo(proto->add_method()); + } + + if (&options() != &ServiceOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const { + proto->set_name(name()); + + if (!input_type()->is_unqualified_placeholder_) { + proto->set_input_type("."); + } + proto->mutable_input_type()->append(input_type()->full_name()); + + if (!output_type()->is_unqualified_placeholder_) { + proto->set_output_type("."); + } + proto->mutable_output_type()->append(output_type()->full_name()); + + if (&options() != &MethodOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +// DebugString methods =============================================== + +namespace { + +// Used by each of the option formatters. +bool RetrieveOptions(int depth, + const Message &options, + vector *option_entries) { + option_entries->clear(); + const Reflection* reflection = options.GetReflection(); + vector fields; + reflection->ListFields(options, &fields); + for (int i = 0; i < fields.size(); i++) { + int count = 1; + bool repeated = false; + if (fields[i]->is_repeated()) { + count = reflection->FieldSize(options, fields[i]); + repeated = true; + } + for (int j = 0; j < count; j++) { + string fieldval; + if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + string tmp; + TextFormat::Printer printer; + printer.SetInitialIndentLevel(depth + 1); + printer.PrintFieldValueToString(options, fields[i], + repeated ? j : -1, &tmp); + fieldval.append("{\n"); + fieldval.append(tmp); + fieldval.append(depth * 2, ' '); + fieldval.append("}"); + } else { + TextFormat::PrintFieldValueToString(options, fields[i], + repeated ? j : -1, &fieldval); + } + string name; + if (fields[i]->is_extension()) { + name = "(." + fields[i]->full_name() + ")"; + } else { + name = fields[i]->name(); + } + option_entries->push_back(name + " = " + fieldval); + } + } + return !option_entries->empty(); +} + +// Formats options that all appear together in brackets. Does not include +// brackets. +bool FormatBracketedOptions(int depth, const Message &options, string *output) { + vector all_options; + if (RetrieveOptions(depth, options, &all_options)) { + output->append(JoinStrings(all_options, ", ")); + } + return !all_options.empty(); +} + +// Formats options one per line +bool FormatLineOptions(int depth, const Message &options, string *output) { + string prefix(depth * 2, ' '); + vector all_options; + if (RetrieveOptions(depth, options, &all_options)) { + for (int i = 0; i < all_options.size(); i++) { + strings::SubstituteAndAppend(output, "$0option $1;\n", + prefix, all_options[i]); + } + } + return !all_options.empty(); +} + +} // anonymous namespace + +string FileDescriptor::DebugString() const { + string contents = "syntax = \"proto2\";\n\n"; + + set public_dependencies; + set weak_dependencies; + public_dependencies.insert(public_dependencies_, + public_dependencies_ + public_dependency_count_); + weak_dependencies.insert(weak_dependencies_, + weak_dependencies_ + weak_dependency_count_); + + for (int i = 0; i < dependency_count(); i++) { + if (public_dependencies.count(i) > 0) { + strings::SubstituteAndAppend(&contents, "import public \"$0\";\n", + dependency(i)->name()); + } else if (weak_dependencies.count(i) > 0) { + strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n", + dependency(i)->name()); + } else { + strings::SubstituteAndAppend(&contents, "import \"$0\";\n", + dependency(i)->name()); + } + } + + if (!package().empty()) { + strings::SubstituteAndAppend(&contents, "package $0;\n\n", package()); + } + + if (FormatLineOptions(0, options(), &contents)) { + contents.append("\n"); // add some space if we had options + } + + for (int i = 0; i < enum_type_count(); i++) { + enum_type(i)->DebugString(0, &contents); + contents.append("\n"); + } + + // Find all the 'group' type extensions; we will not output their nested + // definitions (those will be done with their group field descriptor). + set groups; + for (int i = 0; i < extension_count(); i++) { + if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { + groups.insert(extension(i)->message_type()); + } + } + + for (int i = 0; i < message_type_count(); i++) { + if (groups.count(message_type(i)) == 0) { + strings::SubstituteAndAppend(&contents, "message $0", + message_type(i)->name()); + message_type(i)->DebugString(0, &contents); + contents.append("\n"); + } + } + + for (int i = 0; i < service_count(); i++) { + service(i)->DebugString(&contents); + contents.append("\n"); + } + + const Descriptor* containing_type = NULL; + for (int i = 0; i < extension_count(); i++) { + if (extension(i)->containing_type() != containing_type) { + if (i > 0) contents.append("}\n\n"); + containing_type = extension(i)->containing_type(); + strings::SubstituteAndAppend(&contents, "extend .$0 {\n", + containing_type->full_name()); + } + extension(i)->DebugString(1, &contents); + } + if (extension_count() > 0) contents.append("}\n\n"); + + return contents; +} + +string Descriptor::DebugString() const { + string contents; + strings::SubstituteAndAppend(&contents, "message $0", name()); + DebugString(0, &contents); + return contents; +} + +void Descriptor::DebugString(int depth, string *contents) const { + string prefix(depth * 2, ' '); + ++depth; + contents->append(" {\n"); + + FormatLineOptions(depth, options(), contents); + + // Find all the 'group' types for fields and extensions; we will not output + // their nested definitions (those will be done with their group field + // descriptor). + set groups; + for (int i = 0; i < field_count(); i++) { + if (field(i)->type() == FieldDescriptor::TYPE_GROUP) { + groups.insert(field(i)->message_type()); + } + } + for (int i = 0; i < extension_count(); i++) { + if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { + groups.insert(extension(i)->message_type()); + } + } + + for (int i = 0; i < nested_type_count(); i++) { + if (groups.count(nested_type(i)) == 0) { + strings::SubstituteAndAppend(contents, "$0 message $1", + prefix, nested_type(i)->name()); + nested_type(i)->DebugString(depth, contents); + } + } + for (int i = 0; i < enum_type_count(); i++) { + enum_type(i)->DebugString(depth, contents); + } + for (int i = 0; i < field_count(); i++) { + field(i)->DebugString(depth, contents); + } + + for (int i = 0; i < extension_range_count(); i++) { + strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n", + prefix, + extension_range(i)->start, + extension_range(i)->end - 1); + } + + // Group extensions by what they extend, so they can be printed out together. + const Descriptor* containing_type = NULL; + for (int i = 0; i < extension_count(); i++) { + if (extension(i)->containing_type() != containing_type) { + if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix); + containing_type = extension(i)->containing_type(); + strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n", + prefix, containing_type->full_name()); + } + extension(i)->DebugString(depth + 1, contents); + } + if (extension_count() > 0) + strings::SubstituteAndAppend(contents, "$0 }\n", prefix); + + strings::SubstituteAndAppend(contents, "$0}\n", prefix); +} + +string FieldDescriptor::DebugString() const { + string contents; + int depth = 0; + if (is_extension()) { + strings::SubstituteAndAppend(&contents, "extend .$0 {\n", + containing_type()->full_name()); + depth = 1; + } + DebugString(depth, &contents); + if (is_extension()) { + contents.append("}\n"); + } + return contents; +} + +void FieldDescriptor::DebugString(int depth, string *contents) const { + string prefix(depth * 2, ' '); + string field_type; + switch (type()) { + case TYPE_MESSAGE: + field_type = "." + message_type()->full_name(); + break; + case TYPE_ENUM: + field_type = "." + enum_type()->full_name(); + break; + default: + field_type = kTypeToName[type()]; + } + + strings::SubstituteAndAppend(contents, "$0$1 $2 $3 = $4", + prefix, + kLabelToName[label()], + field_type, + type() == TYPE_GROUP ? message_type()->name() : + name(), + number()); + + bool bracketed = false; + if (has_default_value()) { + bracketed = true; + strings::SubstituteAndAppend(contents, " [default = $0", + DefaultValueAsString(true)); + } + + string formatted_options; + if (FormatBracketedOptions(depth, options(), &formatted_options)) { + contents->append(bracketed ? ", " : " ["); + bracketed = true; + contents->append(formatted_options); + } + + if (bracketed) { + contents->append("]"); + } + + if (type() == TYPE_GROUP) { + message_type()->DebugString(depth, contents); + } else { + contents->append(";\n"); + } +} + +string EnumDescriptor::DebugString() const { + string contents; + DebugString(0, &contents); + return contents; +} + +void EnumDescriptor::DebugString(int depth, string *contents) const { + string prefix(depth * 2, ' '); + ++depth; + strings::SubstituteAndAppend(contents, "$0enum $1 {\n", + prefix, name()); + + FormatLineOptions(depth, options(), contents); + + for (int i = 0; i < value_count(); i++) { + value(i)->DebugString(depth, contents); + } + strings::SubstituteAndAppend(contents, "$0}\n", prefix); +} + +string EnumValueDescriptor::DebugString() const { + string contents; + DebugString(0, &contents); + return contents; +} + +void EnumValueDescriptor::DebugString(int depth, string *contents) const { + string prefix(depth * 2, ' '); + strings::SubstituteAndAppend(contents, "$0$1 = $2", + prefix, name(), number()); + + string formatted_options; + if (FormatBracketedOptions(depth, options(), &formatted_options)) { + strings::SubstituteAndAppend(contents, " [$0]", formatted_options); + } + contents->append(";\n"); +} + +string ServiceDescriptor::DebugString() const { + string contents; + DebugString(&contents); + return contents; +} + +void ServiceDescriptor::DebugString(string *contents) const { + strings::SubstituteAndAppend(contents, "service $0 {\n", name()); + + FormatLineOptions(1, options(), contents); + + for (int i = 0; i < method_count(); i++) { + method(i)->DebugString(1, contents); + } + + contents->append("}\n"); +} + +string MethodDescriptor::DebugString() const { + string contents; + DebugString(0, &contents); + return contents; +} + +void MethodDescriptor::DebugString(int depth, string *contents) const { + string prefix(depth * 2, ' '); + ++depth; + strings::SubstituteAndAppend(contents, "$0rpc $1(.$2) returns (.$3)", + prefix, name(), + input_type()->full_name(), + output_type()->full_name()); + + string formatted_options; + if (FormatLineOptions(depth, options(), &formatted_options)) { + strings::SubstituteAndAppend(contents, " {\n$0$1}\n", + formatted_options, prefix); + } else { + contents->append(";\n"); + } +} + + +// Location methods =============================================== + +static bool PathsEqual(const vector& x, const RepeatedField& y) { + if (x.size() != y.size()) return false; + for (int i = 0; i < x.size(); ++i) { + if (x[i] != y.Get(i)) return false; + } + return true; +} + +bool FileDescriptor::GetSourceLocation(const vector& path, + SourceLocation* out_location) const { + GOOGLE_CHECK_NOTNULL(out_location); + const SourceCodeInfo* info = source_code_info_; + for (int i = 0; info && i < info->location_size(); ++i) { + if (PathsEqual(path, info->location(i).path())) { + const RepeatedField& span = info->location(i).span(); + if (span.size() == 3 || span.size() == 4) { + out_location->start_line = span.Get(0); + out_location->start_column = span.Get(1); + out_location->end_line = span.Get(span.size() == 3 ? 0 : 2); + out_location->end_column = span.Get(span.size() - 1); + + out_location->leading_comments = info->location(i).leading_comments(); + out_location->trailing_comments = info->location(i).trailing_comments(); + return true; + } + } + } + return false; +} + +bool FieldDescriptor::is_packed() const { + return is_packable() && (options_ != NULL) && options_->packed(); +} + +bool Descriptor::GetSourceLocation(SourceLocation* out_location) const { + vector path; + GetLocationPath(&path); + return file()->GetSourceLocation(path, out_location); +} + +bool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const { + vector path; + GetLocationPath(&path); + return file()->GetSourceLocation(path, out_location); +} + +bool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const { + vector path; + GetLocationPath(&path); + return file()->GetSourceLocation(path, out_location); +} + +bool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const { + vector path; + GetLocationPath(&path); + return service()->file()->GetSourceLocation(path, out_location); +} + +bool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const { + vector path; + GetLocationPath(&path); + return file()->GetSourceLocation(path, out_location); +} + +bool EnumValueDescriptor::GetSourceLocation( + SourceLocation* out_location) const { + vector path; + GetLocationPath(&path); + return type()->file()->GetSourceLocation(path, out_location); +} + +void Descriptor::GetLocationPath(vector* output) const { + if (containing_type()) { + containing_type()->GetLocationPath(output); + output->push_back(DescriptorProto::kNestedTypeFieldNumber); + output->push_back(index()); + } else { + output->push_back(FileDescriptorProto::kMessageTypeFieldNumber); + output->push_back(index()); + } +} + +void FieldDescriptor::GetLocationPath(vector* output) const { + containing_type()->GetLocationPath(output); + output->push_back(DescriptorProto::kFieldFieldNumber); + output->push_back(index()); +} + +void EnumDescriptor::GetLocationPath(vector* output) const { + if (containing_type()) { + containing_type()->GetLocationPath(output); + output->push_back(DescriptorProto::kEnumTypeFieldNumber); + output->push_back(index()); + } else { + output->push_back(FileDescriptorProto::kEnumTypeFieldNumber); + output->push_back(index()); + } +} + +void EnumValueDescriptor::GetLocationPath(vector* output) const { + type()->GetLocationPath(output); + output->push_back(EnumDescriptorProto::kValueFieldNumber); + output->push_back(index()); +} + +void ServiceDescriptor::GetLocationPath(vector* output) const { + output->push_back(FileDescriptorProto::kServiceFieldNumber); + output->push_back(index()); +} + +void MethodDescriptor::GetLocationPath(vector* output) const { + service()->GetLocationPath(output); + output->push_back(ServiceDescriptorProto::kMethodFieldNumber); + output->push_back(index()); +} + +// =================================================================== + +namespace { + +// Represents an options message to interpret. Extension names in the option +// name are respolved relative to name_scope. element_name and orig_opt are +// used only for error reporting (since the parser records locations against +// pointers in the original options, not the mutable copy). The Message must be +// one of the Options messages in descriptor.proto. +struct OptionsToInterpret { + OptionsToInterpret(const string& ns, + const string& el, + const Message* orig_opt, + Message* opt) + : name_scope(ns), + element_name(el), + original_options(orig_opt), + options(opt) { + } + string name_scope; + string element_name; + const Message* original_options; + Message* options; +}; + +} // namespace + +class DescriptorBuilder { + public: + DescriptorBuilder(const DescriptorPool* pool, + DescriptorPool::Tables* tables, + DescriptorPool::ErrorCollector* error_collector); + ~DescriptorBuilder(); + + const FileDescriptor* BuildFile(const FileDescriptorProto& proto); + + private: + friend class OptionInterpreter; + + const DescriptorPool* pool_; + DescriptorPool::Tables* tables_; // for convenience + DescriptorPool::ErrorCollector* error_collector_; + + // As we build descriptors we store copies of the options messages in + // them. We put pointers to those copies in this vector, as we build, so we + // can later (after cross-linking) interpret those options. + vector options_to_interpret_; + + bool had_errors_; + string filename_; + FileDescriptor* file_; + FileDescriptorTables* file_tables_; + set dependencies_; + + // If LookupSymbol() finds a symbol that is in a file which is not a declared + // dependency of this file, it will fail, but will set + // possible_undeclared_dependency_ to point at that file. This is only used + // by AddNotDefinedError() to report a more useful error message. + // possible_undeclared_dependency_name_ is the name of the symbol that was + // actually found in possible_undeclared_dependency_, which may be a parent + // of the symbol actually looked for. + const FileDescriptor* possible_undeclared_dependency_; + string possible_undeclared_dependency_name_; + + void AddError(const string& element_name, + const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + const string& error); + + // Adds an error indicating that undefined_symbol was not defined. Must + // only be called after LookupSymbol() fails. + void AddNotDefinedError( + const string& element_name, + const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + const string& undefined_symbol); + + // Silly helper which determines if the given file is in the given package. + // I.e., either file->package() == package_name or file->package() is a + // nested package within package_name. + bool IsInPackage(const FileDescriptor* file, const string& package_name); + + // Helper function which finds all public dependencies of the given file, and + // stores the them in the dependencies_ set in the builder. + void RecordPublicDependencies(const FileDescriptor* file); + + // Like tables_->FindSymbol(), but additionally: + // - Search the pool's underlay if not found in tables_. + // - Insure that the resulting Symbol is from one of the file's declared + // dependencies. + Symbol FindSymbol(const string& name); + + // Like FindSymbol() but does not require that the symbol is in one of the + // file's declared dependencies. + Symbol FindSymbolNotEnforcingDeps(const string& name); + + // This implements the body of FindSymbolNotEnforcingDeps(). + Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool, + const string& name); + + // Like FindSymbol(), but looks up the name relative to some other symbol + // name. This first searches siblings of relative_to, then siblings of its + // parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes + // the following calls, returning the first non-null result: + // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"), + // FindSymbol("foo.bar"). If AllowUnknownDependencies() has been called + // on the DescriptorPool, this will generate a placeholder type if + // the name is not found (unless the name itself is malformed). The + // placeholder_type parameter indicates what kind of placeholder should be + // constructed in this case. The resolve_mode parameter determines whether + // any symbol is returned, or only symbols that are types. Note, however, + // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode, + // if it believes that's all it could refer to. The caller should always + // check that it receives the type of symbol it was expecting. + enum PlaceholderType { + PLACEHOLDER_MESSAGE, + PLACEHOLDER_ENUM, + PLACEHOLDER_EXTENDABLE_MESSAGE + }; + enum ResolveMode { + LOOKUP_ALL, LOOKUP_TYPES + }; + Symbol LookupSymbol(const string& name, const string& relative_to, + PlaceholderType placeholder_type = PLACEHOLDER_MESSAGE, + ResolveMode resolve_mode = LOOKUP_ALL); + + // Like LookupSymbol() but will not return a placeholder even if + // AllowUnknownDependencies() has been used. + Symbol LookupSymbolNoPlaceholder(const string& name, + const string& relative_to, + ResolveMode resolve_mode = LOOKUP_ALL); + + // Creates a placeholder type suitable for return from LookupSymbol(). May + // return kNullSymbol if the name is not a valid type name. + Symbol NewPlaceholder(const string& name, PlaceholderType placeholder_type); + + // Creates a placeholder file. Never returns NULL. This is used when an + // import is not found and AllowUnknownDependencies() is enabled. + const FileDescriptor* NewPlaceholderFile(const string& name); + + // Calls tables_->AddSymbol() and records an error if it fails. Returns + // true if successful or false if failed, though most callers can ignore + // the return value since an error has already been recorded. + bool AddSymbol(const string& full_name, + const void* parent, const string& name, + const Message& proto, Symbol symbol); + + // Like AddSymbol(), but succeeds if the symbol is already defined as long + // as the existing definition is also a package (because it's OK to define + // the same package in two different files). Also adds all parents of the + // packgae to the symbol table (e.g. AddPackage("foo.bar", ...) will add + // "foo.bar" and "foo" to the table). + void AddPackage(const string& name, const Message& proto, + const FileDescriptor* file); + + // Checks that the symbol name contains only alphanumeric characters and + // underscores. Records an error otherwise. + void ValidateSymbolName(const string& name, const string& full_name, + const Message& proto); + + // Like ValidateSymbolName(), but the name is allowed to contain periods and + // an error is indicated by returning false (not recording the error). + bool ValidateQualifiedName(const string& name); + + // Used by BUILD_ARRAY macro (below) to avoid having to have the type + // specified as a macro parameter. + template + inline void AllocateArray(int size, Type** output) { + *output = tables_->AllocateArray(size); + } + + // Allocates a copy of orig_options in tables_ and stores it in the + // descriptor. Remembers its uninterpreted options, to be interpreted + // later. DescriptorT must be one of the Descriptor messages from + // descriptor.proto. + template void AllocateOptions( + const typename DescriptorT::OptionsType& orig_options, + DescriptorT* descriptor); + // Specialization for FileOptions. + void AllocateOptions(const FileOptions& orig_options, + FileDescriptor* descriptor); + + // Implementation for AllocateOptions(). Don't call this directly. + template void AllocateOptionsImpl( + const string& name_scope, + const string& element_name, + const typename DescriptorT::OptionsType& orig_options, + DescriptorT* descriptor); + + // These methods all have the same signature for the sake of the BUILD_ARRAY + // macro, below. + void BuildMessage(const DescriptorProto& proto, + const Descriptor* parent, + Descriptor* result); + void BuildFieldOrExtension(const FieldDescriptorProto& proto, + const Descriptor* parent, + FieldDescriptor* result, + bool is_extension); + void BuildField(const FieldDescriptorProto& proto, + const Descriptor* parent, + FieldDescriptor* result) { + BuildFieldOrExtension(proto, parent, result, false); + } + void BuildExtension(const FieldDescriptorProto& proto, + const Descriptor* parent, + FieldDescriptor* result) { + BuildFieldOrExtension(proto, parent, result, true); + } + void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto, + const Descriptor* parent, + Descriptor::ExtensionRange* result); + void BuildEnum(const EnumDescriptorProto& proto, + const Descriptor* parent, + EnumDescriptor* result); + void BuildEnumValue(const EnumValueDescriptorProto& proto, + const EnumDescriptor* parent, + EnumValueDescriptor* result); + void BuildService(const ServiceDescriptorProto& proto, + const void* dummy, + ServiceDescriptor* result); + void BuildMethod(const MethodDescriptorProto& proto, + const ServiceDescriptor* parent, + MethodDescriptor* result); + + // Must be run only after building. + // + // NOTE: Options will not be available during cross-linking, as they + // have not yet been interpreted. Defer any handling of options to the + // Validate*Options methods. + void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto); + void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto); + void CrossLinkField(FieldDescriptor* field, + const FieldDescriptorProto& proto); + void CrossLinkEnum(EnumDescriptor* enum_type, + const EnumDescriptorProto& proto); + void CrossLinkEnumValue(EnumValueDescriptor* enum_value, + const EnumValueDescriptorProto& proto); + void CrossLinkService(ServiceDescriptor* service, + const ServiceDescriptorProto& proto); + void CrossLinkMethod(MethodDescriptor* method, + const MethodDescriptorProto& proto); + + // Must be run only after cross-linking. + void InterpretOptions(); + + // A helper class for interpreting options. + class OptionInterpreter { + public: + // Creates an interpreter that operates in the context of the pool of the + // specified builder, which must not be NULL. We don't take ownership of the + // builder. + explicit OptionInterpreter(DescriptorBuilder* builder); + + ~OptionInterpreter(); + + // Interprets the uninterpreted options in the specified Options message. + // On error, calls AddError() on the underlying builder and returns false. + // Otherwise returns true. + bool InterpretOptions(OptionsToInterpret* options_to_interpret); + + class AggregateOptionFinder; + + private: + // Interprets uninterpreted_option_ on the specified message, which + // must be the mutable copy of the original options message to which + // uninterpreted_option_ belongs. + bool InterpretSingleOption(Message* options); + + // Adds the uninterpreted_option to the given options message verbatim. + // Used when AllowUnknownDependencies() is in effect and we can't find + // the option's definition. + void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option, + Message* options); + + // A recursive helper function that drills into the intermediate fields + // in unknown_fields to check if field innermost_field is set on the + // innermost message. Returns false and sets an error if so. + bool ExamineIfOptionIsSet( + vector::const_iterator intermediate_fields_iter, + vector::const_iterator intermediate_fields_end, + const FieldDescriptor* innermost_field, const string& debug_msg_name, + const UnknownFieldSet& unknown_fields); + + // Validates the value for the option field of the currently interpreted + // option and then sets it on the unknown_field. + bool SetOptionValue(const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields); + + // Parses an aggregate value for a CPPTYPE_MESSAGE option and + // saves it into *unknown_fields. + bool SetAggregateOption(const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields); + + // Convenience functions to set an int field the right way, depending on + // its wire type (a single int CppType can represent multiple wire types). + void SetInt32(int number, int32 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + void SetInt64(int number, int64 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + void SetUInt32(int number, uint32 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + void SetUInt64(int number, uint64 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + + // A helper function that adds an error at the specified location of the + // option we're currently interpreting, and returns false. + bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location, + const string& msg) { + builder_->AddError(options_to_interpret_->element_name, + *uninterpreted_option_, location, msg); + return false; + } + + // A helper function that adds an error at the location of the option name + // and returns false. + bool AddNameError(const string& msg) { + return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg); + } + + // A helper function that adds an error at the location of the option name + // and returns false. + bool AddValueError(const string& msg) { + return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, msg); + } + + // We interpret against this builder's pool. Is never NULL. We don't own + // this pointer. + DescriptorBuilder* builder_; + + // The options we're currently interpreting, or NULL if we're not in a call + // to InterpretOptions. + const OptionsToInterpret* options_to_interpret_; + + // The option we're currently interpreting within options_to_interpret_, or + // NULL if we're not in a call to InterpretOptions(). This points to a + // submessage of the original option, not the mutable copy. Therefore we + // can use it to find locations recorded by the parser. + const UninterpretedOption* uninterpreted_option_; + + // Factory used to create the dynamic messages we need to parse + // any aggregate option values we encounter. + DynamicMessageFactory dynamic_factory_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter); + }; + + // Work-around for broken compilers: According to the C++ standard, + // OptionInterpreter should have access to the private members of any class + // which has declared DescriptorBuilder as a friend. Unfortunately some old + // versions of GCC and other compilers do not implement this correctly. So, + // we have to have these intermediate methods to provide access. We also + // redundantly declare OptionInterpreter a friend just to make things extra + // clear for these bad compilers. + friend class OptionInterpreter; + friend class OptionInterpreter::AggregateOptionFinder; + + static inline bool get_allow_unknown(const DescriptorPool* pool) { + return pool->allow_unknown_; + } + static inline bool get_is_placeholder(const Descriptor* descriptor) { + return descriptor->is_placeholder_; + } + static inline void assert_mutex_held(const DescriptorPool* pool) { + if (pool->mutex_ != NULL) { + pool->mutex_->AssertHeld(); + } + } + + // Must be run only after options have been interpreted. + // + // NOTE: Validation code must only reference the options in the mutable + // descriptors, which are the ones that have been interpreted. The const + // proto references are passed in only so they can be provided to calls to + // AddError(). Do not look at their options, which have not been interpreted. + void ValidateFileOptions(FileDescriptor* file, + const FileDescriptorProto& proto); + void ValidateMessageOptions(Descriptor* message, + const DescriptorProto& proto); + void ValidateFieldOptions(FieldDescriptor* field, + const FieldDescriptorProto& proto); + void ValidateEnumOptions(EnumDescriptor* enm, + const EnumDescriptorProto& proto); + void ValidateEnumValueOptions(EnumValueDescriptor* enum_value, + const EnumValueDescriptorProto& proto); + void ValidateServiceOptions(ServiceDescriptor* service, + const ServiceDescriptorProto& proto); + void ValidateMethodOptions(MethodDescriptor* method, + const MethodDescriptorProto& proto); + + void ValidateMapKey(FieldDescriptor* field, + const FieldDescriptorProto& proto); + +}; + +const FileDescriptor* DescriptorPool::BuildFile( + const FileDescriptorProto& proto) { + GOOGLE_CHECK(fallback_database_ == NULL) + << "Cannot call BuildFile on a DescriptorPool that uses a " + "DescriptorDatabase. You must instead find a way to get your file " + "into the underlying database."; + GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. + return DescriptorBuilder(this, tables_.get(), NULL).BuildFile(proto); +} + +const FileDescriptor* DescriptorPool::BuildFileCollectingErrors( + const FileDescriptorProto& proto, + ErrorCollector* error_collector) { + GOOGLE_CHECK(fallback_database_ == NULL) + << "Cannot call BuildFile on a DescriptorPool that uses a " + "DescriptorDatabase. You must instead find a way to get your file " + "into the underlying database."; + GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. + return DescriptorBuilder(this, tables_.get(), + error_collector).BuildFile(proto); +} + +const FileDescriptor* DescriptorPool::BuildFileFromDatabase( + const FileDescriptorProto& proto) const { + mutex_->AssertHeld(); + return DescriptorBuilder(this, tables_.get(), + default_error_collector_).BuildFile(proto); +} + +DescriptorBuilder::DescriptorBuilder( + const DescriptorPool* pool, + DescriptorPool::Tables* tables, + DescriptorPool::ErrorCollector* error_collector) + : pool_(pool), + tables_(tables), + error_collector_(error_collector), + had_errors_(false), + possible_undeclared_dependency_(NULL) {} + +DescriptorBuilder::~DescriptorBuilder() {} + +void DescriptorBuilder::AddError( + const string& element_name, + const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + const string& error) { + if (error_collector_ == NULL) { + if (!had_errors_) { + GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_ + << "\":"; + } + GOOGLE_LOG(ERROR) << " " << element_name << ": " << error; + } else { + error_collector_->AddError(filename_, element_name, + &descriptor, location, error); + } + had_errors_ = true; +} + +void DescriptorBuilder::AddNotDefinedError( + const string& element_name, + const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + const string& undefined_symbol) { + if (possible_undeclared_dependency_ == NULL) { + AddError(element_name, descriptor, location, + "\"" + undefined_symbol + "\" is not defined."); + } else { + AddError(element_name, descriptor, location, + "\"" + possible_undeclared_dependency_name_ + + "\" seems to be defined in \"" + + possible_undeclared_dependency_->name() + "\", which is not " + "imported by \"" + filename_ + "\". To use it here, please " + "add the necessary import."); + } +} + +bool DescriptorBuilder::IsInPackage(const FileDescriptor* file, + const string& package_name) { + return HasPrefixString(file->package(), package_name) && + (file->package().size() == package_name.size() || + file->package()[package_name.size()] == '.'); +} + +void DescriptorBuilder::RecordPublicDependencies(const FileDescriptor* file) { + if (file == NULL || !dependencies_.insert(file).second) return; + for (int i = 0; file != NULL && i < file->public_dependency_count(); i++) { + RecordPublicDependencies(file->public_dependency(i)); + } +} + +Symbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper( + const DescriptorPool* pool, const string& name) { + // If we are looking at an underlay, we must lock its mutex_, since we are + // accessing the underlay's tables_ directly. + MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_); + + Symbol result = pool->tables_->FindSymbol(name); + if (result.IsNull() && pool->underlay_ != NULL) { + // Symbol not found; check the underlay. + result = FindSymbolNotEnforcingDepsHelper(pool->underlay_, name); + } + + if (result.IsNull()) { + // In theory, we shouldn't need to check fallback_database_ because the + // symbol should be in one of its file's direct dependencies, and we have + // already loaded those by the time we get here. But we check anyway so + // that we can generate better error message when dependencies are missing + // (i.e., "missing dependency" rather than "type is not defined"). + if (pool->TryFindSymbolInFallbackDatabase(name)) { + result = pool->tables_->FindSymbol(name); + } + } + + return result; +} + +Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) { + return FindSymbolNotEnforcingDepsHelper(pool_, name); +} + +Symbol DescriptorBuilder::FindSymbol(const string& name) { + Symbol result = FindSymbolNotEnforcingDeps(name); + + if (result.IsNull()) return result; + + if (!pool_->enforce_dependencies_) { + // Hack for CompilerUpgrader. + return result; + } + + // Only find symbols which were defined in this file or one of its + // dependencies. + const FileDescriptor* file = result.GetFile(); + if (file == file_ || dependencies_.count(file) > 0) return result; + + if (result.type == Symbol::PACKAGE) { + // Arg, this is overcomplicated. The symbol is a package name. It could + // be that the package was defined in multiple files. result.GetFile() + // returns the first file we saw that used this package. We've determined + // that that file is not a direct dependency of the file we are currently + // building, but it could be that some other file which *is* a direct + // dependency also defines the same package. We can't really rule out this + // symbol unless none of the dependencies define it. + if (IsInPackage(file_, name)) return result; + for (set::const_iterator it = dependencies_.begin(); + it != dependencies_.end(); ++it) { + // Note: A dependency may be NULL if it was not found or had errors. + if (*it != NULL && IsInPackage(*it, name)) return result; + } + } + + possible_undeclared_dependency_ = file; + possible_undeclared_dependency_name_ = name; + return kNullSymbol; +} + +Symbol DescriptorBuilder::LookupSymbolNoPlaceholder( + const string& name, const string& relative_to, ResolveMode resolve_mode) { + possible_undeclared_dependency_ = NULL; + + if (name.size() > 0 && name[0] == '.') { + // Fully-qualified name. + return FindSymbol(name.substr(1)); + } + + // If name is something like "Foo.Bar.baz", and symbols named "Foo" are + // defined in multiple parent scopes, we only want to find "Bar.baz" in the + // innermost one. E.g., the following should produce an error: + // message Bar { message Baz {} } + // message Foo { + // message Bar { + // } + // optional Bar.Baz baz = 1; + // } + // So, we look for just "Foo" first, then look for "Bar.baz" within it if + // found. + string::size_type name_dot_pos = name.find_first_of('.'); + string first_part_of_name; + if (name_dot_pos == string::npos) { + first_part_of_name = name; + } else { + first_part_of_name = name.substr(0, name_dot_pos); + } + + string scope_to_try(relative_to); + + while (true) { + // Chop off the last component of the scope. + string::size_type dot_pos = scope_to_try.find_last_of('.'); + if (dot_pos == string::npos) { + return FindSymbol(name); + } else { + scope_to_try.erase(dot_pos); + } + + // Append ".first_part_of_name" and try to find. + string::size_type old_size = scope_to_try.size(); + scope_to_try.append(1, '.'); + scope_to_try.append(first_part_of_name); + Symbol result = FindSymbol(scope_to_try); + if (!result.IsNull()) { + if (first_part_of_name.size() < name.size()) { + // name is a compound symbol, of which we only found the first part. + // Now try to look up the rest of it. + if (result.IsAggregate()) { + scope_to_try.append(name, first_part_of_name.size(), + name.size() - first_part_of_name.size()); + return FindSymbol(scope_to_try); + } else { + // We found a symbol but it's not an aggregate. Continue the loop. + } + } else { + if (resolve_mode == LOOKUP_TYPES && !result.IsType()) { + // We found a symbol but it's not a type. Continue the loop. + } else { + return result; + } + } + } + + // Not found. Remove the name so we can try again. + scope_to_try.erase(old_size); + } +} + +Symbol DescriptorBuilder::LookupSymbol( + const string& name, const string& relative_to, + PlaceholderType placeholder_type, ResolveMode resolve_mode) { + Symbol result = LookupSymbolNoPlaceholder( + name, relative_to, resolve_mode); + if (result.IsNull() && pool_->allow_unknown_) { + // Not found, but AllowUnknownDependencies() is enabled. Return a + // placeholder instead. + result = NewPlaceholder(name, placeholder_type); + } + return result; +} + +Symbol DescriptorBuilder::NewPlaceholder(const string& name, + PlaceholderType placeholder_type) { + // Compute names. + const string* placeholder_full_name; + const string* placeholder_name; + const string* placeholder_package; + + if (!ValidateQualifiedName(name)) return kNullSymbol; + if (name[0] == '.') { + // Fully-qualified. + placeholder_full_name = tables_->AllocateString(name.substr(1)); + } else { + placeholder_full_name = tables_->AllocateString(name); + } + + string::size_type dotpos = placeholder_full_name->find_last_of('.'); + if (dotpos != string::npos) { + placeholder_package = tables_->AllocateString( + placeholder_full_name->substr(0, dotpos)); + placeholder_name = tables_->AllocateString( + placeholder_full_name->substr(dotpos + 1)); + } else { + placeholder_package = &kEmptyString; + placeholder_name = placeholder_full_name; + } + + // Create the placeholders. + FileDescriptor* placeholder_file = tables_->Allocate(); + memset(placeholder_file, 0, sizeof(*placeholder_file)); + + placeholder_file->source_code_info_ = &SourceCodeInfo::default_instance(); + + placeholder_file->name_ = + tables_->AllocateString(*placeholder_full_name + ".placeholder.proto"); + placeholder_file->package_ = placeholder_package; + placeholder_file->pool_ = pool_; + placeholder_file->options_ = &FileOptions::default_instance(); + placeholder_file->tables_ = &FileDescriptorTables::kEmpty; + // All other fields are zero or NULL. + + if (placeholder_type == PLACEHOLDER_ENUM) { + placeholder_file->enum_type_count_ = 1; + placeholder_file->enum_types_ = + tables_->AllocateArray(1); + + EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0]; + memset(placeholder_enum, 0, sizeof(*placeholder_enum)); + + placeholder_enum->full_name_ = placeholder_full_name; + placeholder_enum->name_ = placeholder_name; + placeholder_enum->file_ = placeholder_file; + placeholder_enum->options_ = &EnumOptions::default_instance(); + placeholder_enum->is_placeholder_ = true; + placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.'); + + // Enums must have at least one value. + placeholder_enum->value_count_ = 1; + placeholder_enum->values_ = tables_->AllocateArray(1); + + EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0]; + memset(placeholder_value, 0, sizeof(*placeholder_value)); + + placeholder_value->name_ = tables_->AllocateString("PLACEHOLDER_VALUE"); + // Note that enum value names are siblings of their type, not children. + placeholder_value->full_name_ = + placeholder_package->empty() ? placeholder_value->name_ : + tables_->AllocateString(*placeholder_package + ".PLACEHOLDER_VALUE"); + + placeholder_value->number_ = 0; + placeholder_value->type_ = placeholder_enum; + placeholder_value->options_ = &EnumValueOptions::default_instance(); + + return Symbol(placeholder_enum); + } else { + placeholder_file->message_type_count_ = 1; + placeholder_file->message_types_ = + tables_->AllocateArray(1); + + Descriptor* placeholder_message = &placeholder_file->message_types_[0]; + memset(placeholder_message, 0, sizeof(*placeholder_message)); + + placeholder_message->full_name_ = placeholder_full_name; + placeholder_message->name_ = placeholder_name; + placeholder_message->file_ = placeholder_file; + placeholder_message->options_ = &MessageOptions::default_instance(); + placeholder_message->is_placeholder_ = true; + placeholder_message->is_unqualified_placeholder_ = (name[0] != '.'); + + if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) { + placeholder_message->extension_range_count_ = 1; + placeholder_message->extension_ranges_ = + tables_->AllocateArray(1); + placeholder_message->extension_ranges_->start = 1; + // kMaxNumber + 1 because ExtensionRange::end is exclusive. + placeholder_message->extension_ranges_->end = + FieldDescriptor::kMaxNumber + 1; + } + + return Symbol(placeholder_message); + } +} + +const FileDescriptor* DescriptorBuilder::NewPlaceholderFile( + const string& name) { + FileDescriptor* placeholder = tables_->Allocate(); + memset(placeholder, 0, sizeof(*placeholder)); + + placeholder->name_ = tables_->AllocateString(name); + placeholder->package_ = &kEmptyString; + placeholder->pool_ = pool_; + placeholder->options_ = &FileOptions::default_instance(); + placeholder->tables_ = &FileDescriptorTables::kEmpty; + // All other fields are zero or NULL. + + return placeholder; +} + +bool DescriptorBuilder::AddSymbol( + const string& full_name, const void* parent, const string& name, + const Message& proto, Symbol symbol) { + // If the caller passed NULL for the parent, the symbol is at file scope. + // Use its file as the parent instead. + if (parent == NULL) parent = file_; + + if (tables_->AddSymbol(full_name, symbol)) { + if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) { + GOOGLE_LOG(DFATAL) << "\"" << full_name << "\" not previously defined in " + "symbols_by_name_, but was defined in symbols_by_parent_; " + "this shouldn't be possible."; + return false; + } + return true; + } else { + const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile(); + if (other_file == file_) { + string::size_type dot_pos = full_name.find_last_of('.'); + if (dot_pos == string::npos) { + AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + full_name + "\" is already defined."); + } else { + AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + full_name.substr(dot_pos + 1) + + "\" is already defined in \"" + + full_name.substr(0, dot_pos) + "\"."); + } + } else { + // Symbol seems to have been defined in a different file. + AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + full_name + "\" is already defined in file \"" + + other_file->name() + "\"."); + } + return false; + } +} + +void DescriptorBuilder::AddPackage( + const string& name, const Message& proto, const FileDescriptor* file) { + if (tables_->AddSymbol(name, Symbol(file))) { + // Success. Also add parent package, if any. + string::size_type dot_pos = name.find_last_of('.'); + if (dot_pos == string::npos) { + // No parents. + ValidateSymbolName(name, name, proto); + } else { + // Has parent. + string* parent_name = tables_->AllocateString(name.substr(0, dot_pos)); + AddPackage(*parent_name, proto, file); + ValidateSymbolName(name.substr(dot_pos + 1), name, proto); + } + } else { + Symbol existing_symbol = tables_->FindSymbol(name); + // It's OK to redefine a package. + if (existing_symbol.type != Symbol::PACKAGE) { + // Symbol seems to have been defined in a different file. + AddError(name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + name + "\" is already defined (as something other than " + "a package) in file \"" + existing_symbol.GetFile()->name() + + "\"."); + } + } +} + +void DescriptorBuilder::ValidateSymbolName( + const string& name, const string& full_name, const Message& proto) { + if (name.empty()) { + AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, + "Missing name."); + } else { + for (int i = 0; i < name.size(); i++) { + // I don't trust isalnum() due to locales. :( + if ((name[i] < 'a' || 'z' < name[i]) && + (name[i] < 'A' || 'Z' < name[i]) && + (name[i] < '0' || '9' < name[i]) && + (name[i] != '_')) { + AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + name + "\" is not a valid identifier."); + } + } + } +} + +bool DescriptorBuilder::ValidateQualifiedName(const string& name) { + bool last_was_period = false; + + for (int i = 0; i < name.size(); i++) { + // I don't trust isalnum() due to locales. :( + if (('a' <= name[i] && name[i] <= 'z') || + ('A' <= name[i] && name[i] <= 'Z') || + ('0' <= name[i] && name[i] <= '9') || + (name[i] == '_')) { + last_was_period = false; + } else if (name[i] == '.') { + if (last_was_period) return false; + last_was_period = true; + } else { + return false; + } + } + + return !name.empty() && !last_was_period; +} + +// ------------------------------------------------------------------- + +// This generic implementation is good for all descriptors except +// FileDescriptor. +template void DescriptorBuilder::AllocateOptions( + const typename DescriptorT::OptionsType& orig_options, + DescriptorT* descriptor) { + AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(), + orig_options, descriptor); +} + +// We specialize for FileDescriptor. +void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options, + FileDescriptor* descriptor) { + // We add the dummy token so that LookupSymbol does the right thing. + AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(), + orig_options, descriptor); +} + +template void DescriptorBuilder::AllocateOptionsImpl( + const string& name_scope, + const string& element_name, + const typename DescriptorT::OptionsType& orig_options, + DescriptorT* descriptor) { + // We need to use a dummy pointer to work around a bug in older versions of + // GCC. Otherwise, the following two lines could be replaced with: + // typename DescriptorT::OptionsType* options = + // tables_->AllocateMessage(); + typename DescriptorT::OptionsType* const dummy = NULL; + typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy); + // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti + // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the + // reflection based method, which requires the Descriptor. However, we are in + // the middle of building the descriptors, thus the deadlock. + options->ParseFromString(orig_options.SerializeAsString()); + descriptor->options_ = options; + + // Don't add to options_to_interpret_ unless there were uninterpreted + // options. This not only avoids unnecessary work, but prevents a + // bootstrapping problem when building descriptors for descriptor.proto. + // descriptor.proto does not contain any uninterpreted options, but + // attempting to interpret options anyway will cause + // OptionsType::GetDescriptor() to be called which may then deadlock since + // we're still trying to build it. + if (options->uninterpreted_option_size() > 0) { + options_to_interpret_.push_back( + OptionsToInterpret(name_scope, element_name, &orig_options, options)); + } +} + + +// A common pattern: We want to convert a repeated field in the descriptor +// to an array of values, calling some method to build each value. +#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \ + OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \ + AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \ + for (int i = 0; i < INPUT.NAME##_size(); i++) { \ + METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \ + } + +const FileDescriptor* DescriptorBuilder::BuildFile( + const FileDescriptorProto& proto) { + filename_ = proto.name(); + + // Check if the file already exists and is identical to the one being built. + // Note: This only works if the input is canonical -- that is, it + // fully-qualifies all type names, has no UninterpretedOptions, etc. + // This is fine, because this idempotency "feature" really only exists to + // accomodate one hack in the proto1->proto2 migration layer. + const FileDescriptor* existing_file = tables_->FindFile(filename_); + if (existing_file != NULL) { + // File already in pool. Compare the existing one to the input. + FileDescriptorProto existing_proto; + existing_file->CopyTo(&existing_proto); + if (existing_proto.SerializeAsString() == proto.SerializeAsString()) { + // They're identical. Return the existing descriptor. + return existing_file; + } + + // Not a match. The error will be detected and handled later. + } + + // Check to see if this file is already on the pending files list. + // TODO(kenton): Allow recursive imports? It may not work with some + // (most?) programming languages. E.g., in C++, a forward declaration + // of a type is not sufficient to allow it to be used even in a + // generated header file due to inlining. This could perhaps be + // worked around using tricks involving inserting #include statements + // mid-file, but that's pretty ugly, and I'm pretty sure there are + // some languages out there that do not allow recursive dependencies + // at all. + for (int i = 0; i < tables_->pending_files_.size(); i++) { + if (tables_->pending_files_[i] == proto.name()) { + string error_message("File recursively imports itself: "); + for (; i < tables_->pending_files_.size(); i++) { + error_message.append(tables_->pending_files_[i]); + error_message.append(" -> "); + } + error_message.append(proto.name()); + + AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, + error_message); + return NULL; + } + } + + // If we have a fallback_database_, attempt to load all dependencies now, + // before checkpointing tables_. This avoids confusion with recursive + // checkpoints. + if (pool_->fallback_database_ != NULL) { + tables_->pending_files_.push_back(proto.name()); + for (int i = 0; i < proto.dependency_size(); i++) { + if (tables_->FindFile(proto.dependency(i)) == NULL && + (pool_->underlay_ == NULL || + pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) { + // We don't care what this returns since we'll find out below anyway. + pool_->TryFindFileInFallbackDatabase(proto.dependency(i)); + } + } + tables_->pending_files_.pop_back(); + } + + // Checkpoint the tables so that we can roll back if something goes wrong. + tables_->AddCheckpoint(); + + FileDescriptor* result = tables_->Allocate(); + file_ = result; + + if (proto.has_source_code_info()) { + SourceCodeInfo *info = tables_->AllocateMessage(); + info->CopyFrom(proto.source_code_info()); + result->source_code_info_ = info; + } else { + result->source_code_info_ = &SourceCodeInfo::default_instance(); + } + + file_tables_ = tables_->AllocateFileTables(); + file_->tables_ = file_tables_; + + if (!proto.has_name()) { + AddError("", proto, DescriptorPool::ErrorCollector::OTHER, + "Missing field: FileDescriptorProto.name."); + } + + result->name_ = tables_->AllocateString(proto.name()); + if (proto.has_package()) { + result->package_ = tables_->AllocateString(proto.package()); + } else { + // We cannot rely on proto.package() returning a valid string if + // proto.has_package() is false, because we might be running at static + // initialization time, in which case default values have not yet been + // initialized. + result->package_ = tables_->AllocateString(""); + } + result->pool_ = pool_; + + // Add to tables. + if (!tables_->AddFile(result)) { + AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, + "A file with this name is already in the pool."); + // Bail out early so that if this is actually the exact same file, we + // don't end up reporting that every single symbol is already defined. + tables_->RollbackToLastCheckpoint(); + return NULL; + } + if (!result->package().empty()) { + AddPackage(result->package(), proto, result); + } + + // Make sure all dependencies are loaded. + set seen_dependencies; + result->dependency_count_ = proto.dependency_size(); + result->dependencies_ = + tables_->AllocateArray(proto.dependency_size()); + for (int i = 0; i < proto.dependency_size(); i++) { + if (!seen_dependencies.insert(proto.dependency(i)).second) { + AddError(proto.name(), proto, + DescriptorPool::ErrorCollector::OTHER, + "Import \"" + proto.dependency(i) + "\" was listed twice."); + } + + const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i)); + if (dependency == NULL && pool_->underlay_ != NULL) { + dependency = pool_->underlay_->FindFileByName(proto.dependency(i)); + } + + if (dependency == NULL) { + if (pool_->allow_unknown_) { + dependency = NewPlaceholderFile(proto.dependency(i)); + } else { + string message; + if (pool_->fallback_database_ == NULL) { + message = "Import \"" + proto.dependency(i) + + "\" has not been loaded."; + } else { + message = "Import \"" + proto.dependency(i) + + "\" was not found or had errors."; + } + AddError(proto.name(), proto, + DescriptorPool::ErrorCollector::OTHER, + message); + } + } + + result->dependencies_[i] = dependency; + } + + // Check public dependencies. + int public_dependency_count = 0; + result->public_dependencies_ = tables_->AllocateArray( + proto.public_dependency_size()); + for (int i = 0; i < proto.public_dependency_size(); i++) { + // Only put valid public dependency indexes. + int index = proto.public_dependency(i); + if (index >= 0 && index < proto.dependency_size()) { + result->public_dependencies_[public_dependency_count++] = index; + } else { + AddError(proto.name(), proto, + DescriptorPool::ErrorCollector::OTHER, + "Invalid public dependency index."); + } + } + result->public_dependency_count_ = public_dependency_count; + + // Build dependency set + dependencies_.clear(); + for (int i = 0; i < result->dependency_count(); i++) { + RecordPublicDependencies(result->dependency(i)); + } + + // Check weak dependencies. + int weak_dependency_count = 0; + result->weak_dependencies_ = tables_->AllocateArray( + proto.weak_dependency_size()); + for (int i = 0; i < proto.weak_dependency_size(); i++) { + int index = proto.weak_dependency(i); + if (index >= 0 && index < proto.dependency_size()) { + result->weak_dependencies_[weak_dependency_count++] = index; + } else { + AddError(proto.name(), proto, + DescriptorPool::ErrorCollector::OTHER, + "Invalid weak dependency index."); + } + } + result->weak_dependency_count_ = weak_dependency_count; + + // Convert children. + BUILD_ARRAY(proto, result, message_type, BuildMessage , NULL); + BUILD_ARRAY(proto, result, enum_type , BuildEnum , NULL); + BUILD_ARRAY(proto, result, service , BuildService , NULL); + BUILD_ARRAY(proto, result, extension , BuildExtension, NULL); + + // Copy options. + if (!proto.has_options()) { + result->options_ = NULL; // Will set to default_instance later. + } else { + AllocateOptions(proto.options(), result); + } + + // Note that the following steps must occur in exactly the specified order. + + // Cross-link. + CrossLinkFile(result, proto); + + // Interpret any remaining uninterpreted options gathered into + // options_to_interpret_ during descriptor building. Cross-linking has made + // extension options known, so all interpretations should now succeed. + if (!had_errors_) { + OptionInterpreter option_interpreter(this); + for (vector::iterator iter = + options_to_interpret_.begin(); + iter != options_to_interpret_.end(); ++iter) { + option_interpreter.InterpretOptions(&(*iter)); + } + options_to_interpret_.clear(); + } + + // Validate options. + if (!had_errors_) { + ValidateFileOptions(result, proto); + } + + if (had_errors_) { + tables_->RollbackToLastCheckpoint(); + return NULL; + } else { + tables_->ClearLastCheckpoint(); + return result; + } +} + +void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, + const Descriptor* parent, + Descriptor* result) { + const string& scope = (parent == NULL) ? + file_->package() : parent->full_name(); + string* full_name = tables_->AllocateString(scope); + if (!full_name->empty()) full_name->append(1, '.'); + full_name->append(proto.name()); + + ValidateSymbolName(proto.name(), *full_name, proto); + + result->name_ = tables_->AllocateString(proto.name()); + result->full_name_ = full_name; + result->file_ = file_; + result->containing_type_ = parent; + result->is_placeholder_ = false; + result->is_unqualified_placeholder_ = false; + + BUILD_ARRAY(proto, result, field , BuildField , result); + BUILD_ARRAY(proto, result, nested_type , BuildMessage , result); + BUILD_ARRAY(proto, result, enum_type , BuildEnum , result); + BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result); + BUILD_ARRAY(proto, result, extension , BuildExtension , result); + + // Copy options. + if (!proto.has_options()) { + result->options_ = NULL; // Will set to default_instance later. + } else { + AllocateOptions(proto.options(), result); + } + + AddSymbol(result->full_name(), parent, result->name(), + proto, Symbol(result)); + + // Check that no fields have numbers in extension ranges. + for (int i = 0; i < result->field_count(); i++) { + const FieldDescriptor* field = result->field(i); + for (int j = 0; j < result->extension_range_count(); j++) { + const Descriptor::ExtensionRange* range = result->extension_range(j); + if (range->start <= field->number() && field->number() < range->end) { + AddError(field->full_name(), proto.extension_range(j), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute( + "Extension range $0 to $1 includes field \"$2\" ($3).", + range->start, range->end - 1, + field->name(), field->number())); + } + } + } + + // Check that extension ranges don't overlap. + for (int i = 0; i < result->extension_range_count(); i++) { + const Descriptor::ExtensionRange* range1 = result->extension_range(i); + for (int j = i + 1; j < result->extension_range_count(); j++) { + const Descriptor::ExtensionRange* range2 = result->extension_range(j); + if (range1->end > range2->start && range2->end > range1->start) { + AddError(result->full_name(), proto.extension_range(j), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Extension range $0 to $1 overlaps with " + "already-defined range $2 to $3.", + range2->start, range2->end - 1, + range1->start, range1->end - 1)); + } + } + } +} + +void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, + const Descriptor* parent, + FieldDescriptor* result, + bool is_extension) { + const string& scope = (parent == NULL) ? + file_->package() : parent->full_name(); + string* full_name = tables_->AllocateString(scope); + if (!full_name->empty()) full_name->append(1, '.'); + full_name->append(proto.name()); + + ValidateSymbolName(proto.name(), *full_name, proto); + + result->name_ = tables_->AllocateString(proto.name()); + result->full_name_ = full_name; + result->file_ = file_; + result->number_ = proto.number(); + result->is_extension_ = is_extension; + + // If .proto files follow the style guide then the name should already be + // lower-cased. If that's the case we can just reuse the string we already + // allocated rather than allocate a new one. + string lowercase_name(proto.name()); + LowerString(&lowercase_name); + if (lowercase_name == proto.name()) { + result->lowercase_name_ = result->name_; + } else { + result->lowercase_name_ = tables_->AllocateString(lowercase_name); + } + + // Don't bother with the above optimization for camel-case names since + // .proto files that follow the guide shouldn't be using names in this + // format, so the optimization wouldn't help much. + result->camelcase_name_ = tables_->AllocateString(ToCamelCase(proto.name())); + + // Some compilers do not allow static_cast directly between two enum types, + // so we must cast to int first. + result->type_ = static_cast( + implicit_cast(proto.type())); + result->label_ = static_cast( + implicit_cast(proto.label())); + + // Some of these may be filled in when cross-linking. + result->containing_type_ = NULL; + result->extension_scope_ = NULL; + result->experimental_map_key_ = NULL; + result->message_type_ = NULL; + result->enum_type_ = NULL; + + result->has_default_value_ = proto.has_default_value(); + if (proto.has_default_value() && result->is_repeated()) { + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Repeated fields can't have default values."); + } + + if (proto.has_type()) { + if (proto.has_default_value()) { + char* end_pos = NULL; + switch (result->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + result->default_value_int32_ = + strtol(proto.default_value().c_str(), &end_pos, 0); + break; + case FieldDescriptor::CPPTYPE_INT64: + result->default_value_int64_ = + strto64(proto.default_value().c_str(), &end_pos, 0); + break; + case FieldDescriptor::CPPTYPE_UINT32: + result->default_value_uint32_ = + strtoul(proto.default_value().c_str(), &end_pos, 0); + break; + case FieldDescriptor::CPPTYPE_UINT64: + result->default_value_uint64_ = + strtou64(proto.default_value().c_str(), &end_pos, 0); + break; + case FieldDescriptor::CPPTYPE_FLOAT: + if (proto.default_value() == "inf") { + result->default_value_float_ = numeric_limits::infinity(); + } else if (proto.default_value() == "-inf") { + result->default_value_float_ = -numeric_limits::infinity(); + } else if (proto.default_value() == "nan") { + result->default_value_float_ = numeric_limits::quiet_NaN(); + } else { + result->default_value_float_ = + NoLocaleStrtod(proto.default_value().c_str(), &end_pos); + } + break; + case FieldDescriptor::CPPTYPE_DOUBLE: + if (proto.default_value() == "inf") { + result->default_value_double_ = numeric_limits::infinity(); + } else if (proto.default_value() == "-inf") { + result->default_value_double_ = -numeric_limits::infinity(); + } else if (proto.default_value() == "nan") { + result->default_value_double_ = numeric_limits::quiet_NaN(); + } else { + result->default_value_double_ = + NoLocaleStrtod(proto.default_value().c_str(), &end_pos); + } + break; + case FieldDescriptor::CPPTYPE_BOOL: + if (proto.default_value() == "true") { + result->default_value_bool_ = true; + } else if (proto.default_value() == "false") { + result->default_value_bool_ = false; + } else { + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Boolean default must be true or false."); + } + break; + case FieldDescriptor::CPPTYPE_ENUM: + // This will be filled in when cross-linking. + result->default_value_enum_ = NULL; + break; + case FieldDescriptor::CPPTYPE_STRING: + if (result->type() == FieldDescriptor::TYPE_BYTES) { + result->default_value_string_ = tables_->AllocateString( + UnescapeCEscapeString(proto.default_value())); + } else { + result->default_value_string_ = + tables_->AllocateString(proto.default_value()); + } + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Messages can't have default values."); + result->has_default_value_ = false; + break; + } + + if (end_pos != NULL) { + // end_pos is only set non-NULL by the parsers for numeric types, above. + // This checks that the default was non-empty and had no extra junk + // after the end of the number. + if (proto.default_value().empty() || *end_pos != '\0') { + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Couldn't parse default value."); + } + } + } else { + // No explicit default value + switch (result->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + result->default_value_int32_ = 0; + break; + case FieldDescriptor::CPPTYPE_INT64: + result->default_value_int64_ = 0; + break; + case FieldDescriptor::CPPTYPE_UINT32: + result->default_value_uint32_ = 0; + break; + case FieldDescriptor::CPPTYPE_UINT64: + result->default_value_uint64_ = 0; + break; + case FieldDescriptor::CPPTYPE_FLOAT: + result->default_value_float_ = 0.0f; + break; + case FieldDescriptor::CPPTYPE_DOUBLE: + result->default_value_double_ = 0.0; + break; + case FieldDescriptor::CPPTYPE_BOOL: + result->default_value_bool_ = false; + break; + case FieldDescriptor::CPPTYPE_ENUM: + // This will be filled in when cross-linking. + result->default_value_enum_ = NULL; + break; + case FieldDescriptor::CPPTYPE_STRING: + result->default_value_string_ = &kEmptyString; + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + break; + } + } + } + + if (result->number() <= 0) { + AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, + "Field numbers must be positive integers."); + } else if (!is_extension && result->number() > FieldDescriptor::kMaxNumber) { + // Only validate that the number is within the valid field range if it is + // not an extension. Since extension numbers are validated with the + // extendee's valid set of extension numbers, and those are in turn + // validated against the max allowed number, the check is unnecessary for + // extension fields. + // This avoids cross-linking issues that arise when attempting to check if + // the extendee is a message_set_wire_format message, which has a higher max + // on extension numbers. + AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Field numbers cannot be greater than $0.", + FieldDescriptor::kMaxNumber)); + } else if (result->number() >= FieldDescriptor::kFirstReservedNumber && + result->number() <= FieldDescriptor::kLastReservedNumber) { + AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute( + "Field numbers $0 through $1 are reserved for the protocol " + "buffer library implementation.", + FieldDescriptor::kFirstReservedNumber, + FieldDescriptor::kLastReservedNumber)); + } + + if (is_extension) { + if (!proto.has_extendee()) { + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + "FieldDescriptorProto.extendee not set for extension field."); + } + + result->extension_scope_ = parent; + } else { + if (proto.has_extendee()) { + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + "FieldDescriptorProto.extendee set for non-extension field."); + } + + result->containing_type_ = parent; + } + + // Copy options. + if (!proto.has_options()) { + result->options_ = NULL; // Will set to default_instance later. + } else { + AllocateOptions(proto.options(), result); + } + + AddSymbol(result->full_name(), parent, result->name(), + proto, Symbol(result)); +} + +void DescriptorBuilder::BuildExtensionRange( + const DescriptorProto::ExtensionRange& proto, + const Descriptor* parent, + Descriptor::ExtensionRange* result) { + result->start = proto.start(); + result->end = proto.end(); + if (result->start <= 0) { + AddError(parent->full_name(), proto, + DescriptorPool::ErrorCollector::NUMBER, + "Extension numbers must be positive integers."); + } + + // Checking of the upper bound of the extension range is deferred until after + // options interpreting. This allows messages with message_set_wire_format to + // have extensions beyond FieldDescriptor::kMaxNumber, since the extension + // numbers are actually used as int32s in the message_set_wire_format. + + if (result->start >= result->end) { + AddError(parent->full_name(), proto, + DescriptorPool::ErrorCollector::NUMBER, + "Extension range end number must be greater than start number."); + } +} + +void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, + const Descriptor* parent, + EnumDescriptor* result) { + const string& scope = (parent == NULL) ? + file_->package() : parent->full_name(); + string* full_name = tables_->AllocateString(scope); + if (!full_name->empty()) full_name->append(1, '.'); + full_name->append(proto.name()); + + ValidateSymbolName(proto.name(), *full_name, proto); + + result->name_ = tables_->AllocateString(proto.name()); + result->full_name_ = full_name; + result->file_ = file_; + result->containing_type_ = parent; + result->is_placeholder_ = false; + result->is_unqualified_placeholder_ = false; + + if (proto.value_size() == 0) { + // We cannot allow enums with no values because this would mean there + // would be no valid default value for fields of this type. + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::NAME, + "Enums must contain at least one value."); + } + + BUILD_ARRAY(proto, result, value, BuildEnumValue, result); + + // Copy options. + if (!proto.has_options()) { + result->options_ = NULL; // Will set to default_instance later. + } else { + AllocateOptions(proto.options(), result); + } + + AddSymbol(result->full_name(), parent, result->name(), + proto, Symbol(result)); +} + +void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto, + const EnumDescriptor* parent, + EnumValueDescriptor* result) { + result->name_ = tables_->AllocateString(proto.name()); + result->number_ = proto.number(); + result->type_ = parent; + + // Note: full_name for enum values is a sibling to the parent's name, not a + // child of it. + string* full_name = tables_->AllocateString(*parent->full_name_); + full_name->resize(full_name->size() - parent->name_->size()); + full_name->append(*result->name_); + result->full_name_ = full_name; + + ValidateSymbolName(proto.name(), *full_name, proto); + + // Copy options. + if (!proto.has_options()) { + result->options_ = NULL; // Will set to default_instance later. + } else { + AllocateOptions(proto.options(), result); + } + + // Again, enum values are weird because we makes them appear as siblings + // of the enum type instead of children of it. So, we use + // parent->containing_type() as the value's parent. + bool added_to_outer_scope = + AddSymbol(result->full_name(), parent->containing_type(), result->name(), + proto, Symbol(result)); + + // However, we also want to be able to search for values within a single + // enum type, so we add it as a child of the enum type itself, too. + // Note: This could fail, but if it does, the error has already been + // reported by the above AddSymbol() call, so we ignore the return code. + bool added_to_inner_scope = + file_tables_->AddAliasUnderParent(parent, result->name(), Symbol(result)); + + if (added_to_inner_scope && !added_to_outer_scope) { + // This value did not conflict with any values defined in the same enum, + // but it did conflict with some other symbol defined in the enum type's + // scope. Let's print an additional error to explain this. + string outer_scope; + if (parent->containing_type() == NULL) { + outer_scope = file_->package(); + } else { + outer_scope = parent->containing_type()->full_name(); + } + + if (outer_scope.empty()) { + outer_scope = "the global scope"; + } else { + outer_scope = "\"" + outer_scope + "\""; + } + + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::NAME, + "Note that enum values use C++ scoping rules, meaning that " + "enum values are siblings of their type, not children of it. " + "Therefore, \"" + result->name() + "\" must be unique within " + + outer_scope + ", not just within \"" + parent->name() + "\"."); + } + + // An enum is allowed to define two numbers that refer to the same value. + // FindValueByNumber() should return the first such value, so we simply + // ignore AddEnumValueByNumber()'s return code. + file_tables_->AddEnumValueByNumber(result); +} + +void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto, + const void* dummy, + ServiceDescriptor* result) { + string* full_name = tables_->AllocateString(file_->package()); + if (!full_name->empty()) full_name->append(1, '.'); + full_name->append(proto.name()); + + ValidateSymbolName(proto.name(), *full_name, proto); + + result->name_ = tables_->AllocateString(proto.name()); + result->full_name_ = full_name; + result->file_ = file_; + + BUILD_ARRAY(proto, result, method, BuildMethod, result); + + // Copy options. + if (!proto.has_options()) { + result->options_ = NULL; // Will set to default_instance later. + } else { + AllocateOptions(proto.options(), result); + } + + AddSymbol(result->full_name(), NULL, result->name(), + proto, Symbol(result)); +} + +void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto, + const ServiceDescriptor* parent, + MethodDescriptor* result) { + result->name_ = tables_->AllocateString(proto.name()); + result->service_ = parent; + + string* full_name = tables_->AllocateString(parent->full_name()); + full_name->append(1, '.'); + full_name->append(*result->name_); + result->full_name_ = full_name; + + ValidateSymbolName(proto.name(), *full_name, proto); + + // These will be filled in when cross-linking. + result->input_type_ = NULL; + result->output_type_ = NULL; + + // Copy options. + if (!proto.has_options()) { + result->options_ = NULL; // Will set to default_instance later. + } else { + AllocateOptions(proto.options(), result); + } + + AddSymbol(result->full_name(), parent, result->name(), + proto, Symbol(result)); +} + +#undef BUILD_ARRAY + +// ------------------------------------------------------------------- + +void DescriptorBuilder::CrossLinkFile( + FileDescriptor* file, const FileDescriptorProto& proto) { + if (file->options_ == NULL) { + file->options_ = &FileOptions::default_instance(); + } + + for (int i = 0; i < file->message_type_count(); i++) { + CrossLinkMessage(&file->message_types_[i], proto.message_type(i)); + } + + for (int i = 0; i < file->extension_count(); i++) { + CrossLinkField(&file->extensions_[i], proto.extension(i)); + } + + for (int i = 0; i < file->enum_type_count(); i++) { + CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i)); + } + + for (int i = 0; i < file->service_count(); i++) { + CrossLinkService(&file->services_[i], proto.service(i)); + } +} + +void DescriptorBuilder::CrossLinkMessage( + Descriptor* message, const DescriptorProto& proto) { + if (message->options_ == NULL) { + message->options_ = &MessageOptions::default_instance(); + } + + for (int i = 0; i < message->nested_type_count(); i++) { + CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i)); + } + + for (int i = 0; i < message->enum_type_count(); i++) { + CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i)); + } + + for (int i = 0; i < message->field_count(); i++) { + CrossLinkField(&message->fields_[i], proto.field(i)); + } + + for (int i = 0; i < message->extension_count(); i++) { + CrossLinkField(&message->extensions_[i], proto.extension(i)); + } +} + +void DescriptorBuilder::CrossLinkField( + FieldDescriptor* field, const FieldDescriptorProto& proto) { + if (field->options_ == NULL) { + field->options_ = &FieldOptions::default_instance(); + } + + if (proto.has_extendee()) { + Symbol extendee = LookupSymbol(proto.extendee(), field->full_name(), + PLACEHOLDER_EXTENDABLE_MESSAGE); + if (extendee.IsNull()) { + AddNotDefinedError(field->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + proto.extendee()); + return; + } else if (extendee.type != Symbol::MESSAGE) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + "\"" + proto.extendee() + "\" is not a message type."); + return; + } + field->containing_type_ = extendee.descriptor; + + if (!field->containing_type()->IsExtensionNumber(field->number())) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("\"$0\" does not declare $1 as an " + "extension number.", + field->containing_type()->full_name(), + field->number())); + } + } + + if (proto.has_type_name()) { + // Assume we are expecting a message type unless the proto contains some + // evidence that it expects an enum type. This only makes a difference if + // we end up creating a placeholder. + bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) || + proto.has_default_value(); + + Symbol type = + LookupSymbol(proto.type_name(), field->full_name(), + expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE, + LOOKUP_TYPES); + + if (type.IsNull()) { + AddNotDefinedError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + proto.type_name()); + return; + } + + if (!proto.has_type()) { + // Choose field type based on symbol. + if (type.type == Symbol::MESSAGE) { + field->type_ = FieldDescriptor::TYPE_MESSAGE; + } else if (type.type == Symbol::ENUM) { + field->type_ = FieldDescriptor::TYPE_ENUM; + } else { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "\"" + proto.type_name() + "\" is not a type."); + return; + } + } + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (type.type != Symbol::MESSAGE) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "\"" + proto.type_name() + "\" is not a message type."); + return; + } + field->message_type_ = type.descriptor; + + if (field->has_default_value()) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Messages can't have default values."); + } + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + if (type.type != Symbol::ENUM) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "\"" + proto.type_name() + "\" is not an enum type."); + return; + } + field->enum_type_ = type.enum_descriptor; + + if (field->enum_type()->is_placeholder_) { + // We can't look up default values for placeholder types. We'll have + // to just drop them. + field->has_default_value_ = false; + } + + if (field->has_default_value()) { + // We can't just use field->enum_type()->FindValueByName() here + // because that locks the pool's mutex, which we have already locked + // at this point. + Symbol default_value = + LookupSymbolNoPlaceholder(proto.default_value(), + field->enum_type()->full_name()); + + if (default_value.type == Symbol::ENUM_VALUE && + default_value.enum_value_descriptor->type() == field->enum_type()) { + field->default_value_enum_ = default_value.enum_value_descriptor; + } else { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Enum type \"" + field->enum_type()->full_name() + + "\" has no value named \"" + proto.default_value() + "\"."); + } + } else if (field->enum_type()->value_count() > 0) { + // All enums must have at least one value, or we would have reported + // an error elsewhere. We use the first defined value as the default + // if a default is not explicitly defined. + field->default_value_enum_ = field->enum_type()->value(0); + } + } else { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Field with primitive type has type_name."); + } + } else { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || + field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Field with message or enum type missing type_name."); + } + } + + // Add the field to the fields-by-number table. + // Note: We have to do this *after* cross-linking because extensions do not + // know their containing type until now. + if (!file_tables_->AddFieldByNumber(field)) { + const FieldDescriptor* conflicting_field = + file_tables_->FindFieldByNumber(field->containing_type(), + field->number()); + if (field->is_extension()) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Extension number $0 has already been used " + "in \"$1\" by extension \"$2\".", + field->number(), + field->containing_type()->full_name(), + conflicting_field->full_name())); + } else { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Field number $0 has already been used in " + "\"$1\" by field \"$2\".", + field->number(), + field->containing_type()->full_name(), + conflicting_field->name())); + } + } + + if (field->is_extension()) { + // No need for error checking: if the extension number collided, + // we've already been informed of it by the if() above. + tables_->AddExtension(field); + } + + // Add the field to the lowercase-name and camelcase-name tables. + file_tables_->AddFieldByStylizedNames(field); +} + +void DescriptorBuilder::CrossLinkEnum( + EnumDescriptor* enum_type, const EnumDescriptorProto& proto) { + if (enum_type->options_ == NULL) { + enum_type->options_ = &EnumOptions::default_instance(); + } + + for (int i = 0; i < enum_type->value_count(); i++) { + CrossLinkEnumValue(&enum_type->values_[i], proto.value(i)); + } +} + +void DescriptorBuilder::CrossLinkEnumValue( + EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) { + if (enum_value->options_ == NULL) { + enum_value->options_ = &EnumValueOptions::default_instance(); + } +} + +void DescriptorBuilder::CrossLinkService( + ServiceDescriptor* service, const ServiceDescriptorProto& proto) { + if (service->options_ == NULL) { + service->options_ = &ServiceOptions::default_instance(); + } + + for (int i = 0; i < service->method_count(); i++) { + CrossLinkMethod(&service->methods_[i], proto.method(i)); + } +} + +void DescriptorBuilder::CrossLinkMethod( + MethodDescriptor* method, const MethodDescriptorProto& proto) { + if (method->options_ == NULL) { + method->options_ = &MethodOptions::default_instance(); + } + + Symbol input_type = LookupSymbol(proto.input_type(), method->full_name()); + if (input_type.IsNull()) { + AddNotDefinedError(method->full_name(), proto, + DescriptorPool::ErrorCollector::INPUT_TYPE, + proto.input_type()); + } else if (input_type.type != Symbol::MESSAGE) { + AddError(method->full_name(), proto, + DescriptorPool::ErrorCollector::INPUT_TYPE, + "\"" + proto.input_type() + "\" is not a message type."); + } else { + method->input_type_ = input_type.descriptor; + } + + Symbol output_type = LookupSymbol(proto.output_type(), method->full_name()); + if (output_type.IsNull()) { + AddNotDefinedError(method->full_name(), proto, + DescriptorPool::ErrorCollector::OUTPUT_TYPE, + proto.output_type()); + } else if (output_type.type != Symbol::MESSAGE) { + AddError(method->full_name(), proto, + DescriptorPool::ErrorCollector::OUTPUT_TYPE, + "\"" + proto.output_type() + "\" is not a message type."); + } else { + method->output_type_ = output_type.descriptor; + } +} + +// ------------------------------------------------------------------- + +#define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type) \ + for (int i = 0; i < descriptor->array_name##_count(); ++i) { \ + Validate##type##Options(descriptor->array_name##s_ + i, \ + proto.array_name(i)); \ + } + +// Determine if the file uses optimize_for = LITE_RUNTIME, being careful to +// avoid problems that exist at init time. +static bool IsLite(const FileDescriptor* file) { + // TODO(kenton): I don't even remember how many of these conditions are + // actually possible. I'm just being super-safe. + return file != NULL && + &file->options() != NULL && + &file->options() != &FileOptions::default_instance() && + file->options().optimize_for() == FileOptions::LITE_RUNTIME; +} + +void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file, + const FileDescriptorProto& proto) { + VALIDATE_OPTIONS_FROM_ARRAY(file, message_type, Message); + VALIDATE_OPTIONS_FROM_ARRAY(file, enum_type, Enum); + VALIDATE_OPTIONS_FROM_ARRAY(file, service, Service); + VALIDATE_OPTIONS_FROM_ARRAY(file, extension, Field); + + // Lite files can only be imported by other Lite files. + if (!IsLite(file)) { + for (int i = 0; i < file->dependency_count(); i++) { + if (IsLite(file->dependency(i))) { + AddError( + file->name(), proto, + DescriptorPool::ErrorCollector::OTHER, + "Files that do not use optimize_for = LITE_RUNTIME cannot import " + "files which do use this option. This file is not lite, but it " + "imports \"" + file->dependency(i)->name() + "\" which is."); + break; + } + } + } +} + +void DescriptorBuilder::ValidateMessageOptions(Descriptor* message, + const DescriptorProto& proto) { + VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field); + VALIDATE_OPTIONS_FROM_ARRAY(message, nested_type, Message); + VALIDATE_OPTIONS_FROM_ARRAY(message, enum_type, Enum); + VALIDATE_OPTIONS_FROM_ARRAY(message, extension, Field); + + const int64 max_extension_range = + static_cast(message->options().message_set_wire_format() ? + kint32max : + FieldDescriptor::kMaxNumber); + for (int i = 0; i < message->extension_range_count(); ++i) { + if (message->extension_range(i)->end > max_extension_range + 1) { + AddError( + message->full_name(), proto.extension_range(i), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Extension numbers cannot be greater than $0.", + max_extension_range)); + } + } +} + +void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field, + const FieldDescriptorProto& proto) { + if (field->options().has_experimental_map_key()) { + ValidateMapKey(field, proto); + } + + // Only message type fields may be lazy. + if (field->options().lazy()) { + if (field->type() != FieldDescriptor::TYPE_MESSAGE) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "[lazy = true] can only be specified for submessage fields."); + } + } + + // Only repeated primitive fields may be packed. + if (field->options().packed() && !field->is_packable()) { + AddError( + field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "[packed = true] can only be specified for repeated primitive fields."); + } + + // Note: Default instance may not yet be initialized here, so we have to + // avoid reading from it. + if (field->containing_type_ != NULL && + &field->containing_type()->options() != + &MessageOptions::default_instance() && + field->containing_type()->options().message_set_wire_format()) { + if (field->is_extension()) { + if (!field->is_optional() || + field->type() != FieldDescriptor::TYPE_MESSAGE) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "Extensions of MessageSets must be optional messages."); + } + } else { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::NAME, + "MessageSets cannot have fields, only extensions."); + } + } + + // Lite extensions can only be of Lite types. + if (IsLite(field->file()) && + field->containing_type_ != NULL && + !IsLite(field->containing_type()->file())) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + "Extensions to non-lite types can only be declared in non-lite " + "files. Note that you cannot extend a non-lite type to contain " + "a lite type, but the reverse is allowed."); + } + +} + +void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm, + const EnumDescriptorProto& proto) { + VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue); + if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) { + map used_values; + for (int i = 0; i < enm->value_count(); ++i) { + const EnumValueDescriptor* enum_value = enm->value(i); + if (used_values.find(enum_value->number()) != used_values.end()) { + string error = + "\"" + enum_value->full_name() + + "\" uses the same enum value as \"" + + used_values[enum_value->number()] + "\". If this is intended, set " + "'option allow_alias = true;' to the enum definition."; + if (!enm->options().allow_alias()) { + // Generate error if duplicated enum values are explicitly disallowed. + AddError(enm->full_name(), proto, + DescriptorPool::ErrorCollector::NUMBER, + error); + } else { + // Generate warning if duplicated values are found but the option + // isn't set. + GOOGLE_LOG(ERROR) << error; + } + } else { + used_values[enum_value->number()] = enum_value->full_name(); + } + } + } +} + +void DescriptorBuilder::ValidateEnumValueOptions( + EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) { + // Nothing to do so far. +} +void DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service, + const ServiceDescriptorProto& proto) { + if (IsLite(service->file()) && + (service->file()->options().cc_generic_services() || + service->file()->options().java_generic_services())) { + AddError(service->full_name(), proto, + DescriptorPool::ErrorCollector::NAME, + "Files with optimize_for = LITE_RUNTIME cannot define services " + "unless you set both options cc_generic_services and " + "java_generic_sevices to false."); + } + + VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method); +} + +void DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* method, + const MethodDescriptorProto& proto) { + // Nothing to do so far. +} + +void DescriptorBuilder::ValidateMapKey(FieldDescriptor* field, + const FieldDescriptorProto& proto) { + if (!field->is_repeated()) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "map type is only allowed for repeated fields."); + return; + } + + if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "map type is only allowed for fields with a message type."); + return; + } + + const Descriptor* item_type = field->message_type(); + if (item_type == NULL) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Could not find field type."); + return; + } + + // Find the field in item_type named by "experimental_map_key" + const string& key_name = field->options().experimental_map_key(); + const Symbol key_symbol = LookupSymbol( + key_name, + // We append ".key_name" to the containing type's name since + // LookupSymbol() searches for peers of the supplied name, not + // children of the supplied name. + item_type->full_name() + "." + key_name); + + if (key_symbol.IsNull() || key_symbol.field_descriptor->is_extension()) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Could not find field named \"" + key_name + "\" in type \"" + + item_type->full_name() + "\"."); + return; + } + const FieldDescriptor* key_field = key_symbol.field_descriptor; + + if (key_field->is_repeated()) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "map_key must not name a repeated field."); + return; + } + + if (key_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "map key must name a scalar or string field."); + return; + } + + field->experimental_map_key_ = key_field; +} + + +#undef VALIDATE_OPTIONS_FROM_ARRAY + +// ------------------------------------------------------------------- + +DescriptorBuilder::OptionInterpreter::OptionInterpreter( + DescriptorBuilder* builder) : builder_(builder) { + GOOGLE_CHECK(builder_); +} + +DescriptorBuilder::OptionInterpreter::~OptionInterpreter() { +} + +bool DescriptorBuilder::OptionInterpreter::InterpretOptions( + OptionsToInterpret* options_to_interpret) { + // Note that these may be in different pools, so we can't use the same + // descriptor and reflection objects on both. + Message* options = options_to_interpret->options; + const Message* original_options = options_to_interpret->original_options; + + bool failed = false; + options_to_interpret_ = options_to_interpret; + + // Find the uninterpreted_option field in the mutable copy of the options + // and clear them, since we're about to interpret them. + const FieldDescriptor* uninterpreted_options_field = + options->GetDescriptor()->FindFieldByName("uninterpreted_option"); + GOOGLE_CHECK(uninterpreted_options_field != NULL) + << "No field named \"uninterpreted_option\" in the Options proto."; + options->GetReflection()->ClearField(options, uninterpreted_options_field); + + // Find the uninterpreted_option field in the original options. + const FieldDescriptor* original_uninterpreted_options_field = + original_options->GetDescriptor()-> + FindFieldByName("uninterpreted_option"); + GOOGLE_CHECK(original_uninterpreted_options_field != NULL) + << "No field named \"uninterpreted_option\" in the Options proto."; + + const int num_uninterpreted_options = original_options->GetReflection()-> + FieldSize(*original_options, original_uninterpreted_options_field); + for (int i = 0; i < num_uninterpreted_options; ++i) { + uninterpreted_option_ = down_cast( + &original_options->GetReflection()->GetRepeatedMessage( + *original_options, original_uninterpreted_options_field, i)); + if (!InterpretSingleOption(options)) { + // Error already added by InterpretSingleOption(). + failed = true; + break; + } + } + // Reset these, so we don't have any dangling pointers. + uninterpreted_option_ = NULL; + options_to_interpret_ = NULL; + + if (!failed) { + // InterpretSingleOption() added the interpreted options in the + // UnknownFieldSet, in case the option isn't yet known to us. Now we + // serialize the options message and deserialize it back. That way, any + // option fields that we do happen to know about will get moved from the + // UnknownFieldSet into the real fields, and thus be available right away. + // If they are not known, that's OK too. They will get reparsed into the + // UnknownFieldSet and wait there until the message is parsed by something + // that does know about the options. + string buf; + options->AppendToString(&buf); + GOOGLE_CHECK(options->ParseFromString(buf)) + << "Protocol message serialized itself in invalid fashion."; + } + + return !failed; +} + +bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption( + Message* options) { + // First do some basic validation. + if (uninterpreted_option_->name_size() == 0) { + // This should never happen unless the parser has gone seriously awry or + // someone has manually created the uninterpreted option badly. + return AddNameError("Option must have a name."); + } + if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") { + return AddNameError("Option must not use reserved name " + "\"uninterpreted_option\"."); + } + + const Descriptor* options_descriptor = NULL; + // Get the options message's descriptor from the builder's pool, so that we + // get the version that knows about any extension options declared in the + // file we're currently building. The descriptor should be there as long as + // the file we're building imported "google/protobuf/descriptors.proto". + + // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not + // DescriptorPool::FindMessageTypeByName() because we're already holding the + // pool's mutex, and the latter method locks it again. We don't use + // FindSymbol() because files that use custom options only need to depend on + // the file that defines the option, not descriptor.proto itself. + Symbol symbol = builder_->FindSymbolNotEnforcingDeps( + options->GetDescriptor()->full_name()); + if (!symbol.IsNull() && symbol.type == Symbol::MESSAGE) { + options_descriptor = symbol.descriptor; + } else { + // The options message's descriptor was not in the builder's pool, so use + // the standard version from the generated pool. We're not holding the + // generated pool's mutex, so we can search it the straightforward way. + options_descriptor = options->GetDescriptor(); + } + GOOGLE_CHECK(options_descriptor); + + // We iterate over the name parts to drill into the submessages until we find + // the leaf field for the option. As we drill down we remember the current + // submessage's descriptor in |descriptor| and the next field in that + // submessage in |field|. We also track the fields we're drilling down + // through in |intermediate_fields|. As we go, we reconstruct the full option + // name in |debug_msg_name|, for use in error messages. + const Descriptor* descriptor = options_descriptor; + const FieldDescriptor* field = NULL; + vector intermediate_fields; + string debug_msg_name = ""; + + for (int i = 0; i < uninterpreted_option_->name_size(); ++i) { + const string& name_part = uninterpreted_option_->name(i).name_part(); + if (debug_msg_name.size() > 0) { + debug_msg_name += "."; + } + if (uninterpreted_option_->name(i).is_extension()) { + debug_msg_name += "(" + name_part + ")"; + // Search for the extension's descriptor as an extension in the builder's + // pool. Note that we use DescriptorBuilder::LookupSymbol(), not + // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows + // relative lookups, and 2) because we're already holding the pool's + // mutex, and the latter method locks it again. + symbol = builder_->LookupSymbol(name_part, + options_to_interpret_->name_scope); + if (!symbol.IsNull() && symbol.type == Symbol::FIELD) { + field = symbol.field_descriptor; + } + // If we don't find the field then the field's descriptor was not in the + // builder's pool, but there's no point in looking in the generated + // pool. We require that you import the file that defines any extensions + // you use, so they must be present in the builder's pool. + } else { + debug_msg_name += name_part; + // Search for the field's descriptor as a regular field. + field = descriptor->FindFieldByName(name_part); + } + + if (field == NULL) { + if (get_allow_unknown(builder_->pool_)) { + // We can't find the option, but AllowUnknownDependencies() is enabled, + // so we will just leave it as uninterpreted. + AddWithoutInterpreting(*uninterpreted_option_, options); + return true; + } else { + return AddNameError("Option \"" + debug_msg_name + "\" unknown."); + } + } else if (field->containing_type() != descriptor) { + if (get_is_placeholder(field->containing_type())) { + // The field is an extension of a placeholder type, so we can't + // reliably verify whether it is a valid extension to use here (e.g. + // we don't know if it is an extension of the correct *Options message, + // or if it has a valid field number, etc.). Just leave it as + // uninterpreted instead. + AddWithoutInterpreting(*uninterpreted_option_, options); + return true; + } else { + // This can only happen if, due to some insane misconfiguration of the + // pools, we find the options message in one pool but the field in + // another. This would probably imply a hefty bug somewhere. + return AddNameError("Option field \"" + debug_msg_name + + "\" is not a field or extension of message \"" + + descriptor->name() + "\"."); + } + } else if (field->is_repeated()) { + return AddNameError("Option field \"" + debug_msg_name + + "\" is repeated. Repeated options are not " + "supported."); + } else if (i < uninterpreted_option_->name_size() - 1) { + if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { + return AddNameError("Option \"" + debug_msg_name + + "\" is an atomic type, not a message."); + } else { + // Drill down into the submessage. + intermediate_fields.push_back(field); + descriptor = field->message_type(); + } + } + } + + // We've found the leaf field. Now we use UnknownFieldSets to set its value + // on the options message. We do so because the message may not yet know + // about its extension fields, so we may not be able to set the fields + // directly. But the UnknownFieldSets will serialize to the same wire-format + // message, so reading that message back in once the extension fields are + // known will populate them correctly. + + // First see if the option is already set. + if (!ExamineIfOptionIsSet( + intermediate_fields.begin(), + intermediate_fields.end(), + field, debug_msg_name, + options->GetReflection()->GetUnknownFields(*options))) { + return false; // ExamineIfOptionIsSet() already added the error. + } + + + // First set the value on the UnknownFieldSet corresponding to the + // innermost message. + scoped_ptr unknown_fields(new UnknownFieldSet()); + if (!SetOptionValue(field, unknown_fields.get())) { + return false; // SetOptionValue() already added the error. + } + + // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all + // the intermediate messages. + for (vector::reverse_iterator iter = + intermediate_fields.rbegin(); + iter != intermediate_fields.rend(); ++iter) { + scoped_ptr parent_unknown_fields(new UnknownFieldSet()); + switch ((*iter)->type()) { + case FieldDescriptor::TYPE_MESSAGE: { + io::StringOutputStream outstr( + parent_unknown_fields->AddLengthDelimited((*iter)->number())); + io::CodedOutputStream out(&outstr); + internal::WireFormat::SerializeUnknownFields(*unknown_fields, &out); + GOOGLE_CHECK(!out.HadError()) + << "Unexpected failure while serializing option submessage " + << debug_msg_name << "\"."; + break; + } + + case FieldDescriptor::TYPE_GROUP: { + parent_unknown_fields->AddGroup((*iter)->number()) + ->MergeFrom(*unknown_fields); + break; + } + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " + << (*iter)->type(); + return false; + } + unknown_fields.reset(parent_unknown_fields.release()); + } + + // Now merge the UnknownFieldSet corresponding to the top-level message into + // the options message. + options->GetReflection()->MutableUnknownFields(options)->MergeFrom( + *unknown_fields); + + return true; +} + +void DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting( + const UninterpretedOption& uninterpreted_option, Message* options) { + const FieldDescriptor* field = + options->GetDescriptor()->FindFieldByName("uninterpreted_option"); + GOOGLE_CHECK(field != NULL); + + options->GetReflection()->AddMessage(options, field) + ->CopyFrom(uninterpreted_option); +} + +bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet( + vector::const_iterator intermediate_fields_iter, + vector::const_iterator intermediate_fields_end, + const FieldDescriptor* innermost_field, const string& debug_msg_name, + const UnknownFieldSet& unknown_fields) { + // We do linear searches of the UnknownFieldSet and its sub-groups. This + // should be fine since it's unlikely that any one options structure will + // contain more than a handful of options. + + if (intermediate_fields_iter == intermediate_fields_end) { + // We're at the innermost submessage. + for (int i = 0; i < unknown_fields.field_count(); i++) { + if (unknown_fields.field(i).number() == innermost_field->number()) { + return AddNameError("Option \"" + debug_msg_name + + "\" was already set."); + } + } + return true; + } + + for (int i = 0; i < unknown_fields.field_count(); i++) { + if (unknown_fields.field(i).number() == + (*intermediate_fields_iter)->number()) { + const UnknownField* unknown_field = &unknown_fields.field(i); + FieldDescriptor::Type type = (*intermediate_fields_iter)->type(); + // Recurse into the next submessage. + switch (type) { + case FieldDescriptor::TYPE_MESSAGE: + if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) { + UnknownFieldSet intermediate_unknown_fields; + if (intermediate_unknown_fields.ParseFromString( + unknown_field->length_delimited()) && + !ExamineIfOptionIsSet(intermediate_fields_iter + 1, + intermediate_fields_end, + innermost_field, debug_msg_name, + intermediate_unknown_fields)) { + return false; // Error already added. + } + } + break; + + case FieldDescriptor::TYPE_GROUP: + if (unknown_field->type() == UnknownField::TYPE_GROUP) { + if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1, + intermediate_fields_end, + innermost_field, debug_msg_name, + unknown_field->group())) { + return false; // Error already added. + } + } + break; + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type; + return false; + } + } + } + return true; +} + +bool DescriptorBuilder::OptionInterpreter::SetOptionValue( + const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields) { + // We switch on the CppType to validate. + switch (option_field->cpp_type()) { + + case FieldDescriptor::CPPTYPE_INT32: + if (uninterpreted_option_->has_positive_int_value()) { + if (uninterpreted_option_->positive_int_value() > + static_cast(kint32max)) { + return AddValueError("Value out of range for int32 option \"" + + option_field->full_name() + "\"."); + } else { + SetInt32(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } + } else if (uninterpreted_option_->has_negative_int_value()) { + if (uninterpreted_option_->negative_int_value() < + static_cast(kint32min)) { + return AddValueError("Value out of range for int32 option \"" + + option_field->full_name() + "\"."); + } else { + SetInt32(option_field->number(), + uninterpreted_option_->negative_int_value(), + option_field->type(), unknown_fields); + } + } else { + return AddValueError("Value must be integer for int32 option \"" + + option_field->full_name() + "\"."); + } + break; + + case FieldDescriptor::CPPTYPE_INT64: + if (uninterpreted_option_->has_positive_int_value()) { + if (uninterpreted_option_->positive_int_value() > + static_cast(kint64max)) { + return AddValueError("Value out of range for int64 option \"" + + option_field->full_name() + "\"."); + } else { + SetInt64(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } + } else if (uninterpreted_option_->has_negative_int_value()) { + SetInt64(option_field->number(), + uninterpreted_option_->negative_int_value(), + option_field->type(), unknown_fields); + } else { + return AddValueError("Value must be integer for int64 option \"" + + option_field->full_name() + "\"."); + } + break; + + case FieldDescriptor::CPPTYPE_UINT32: + if (uninterpreted_option_->has_positive_int_value()) { + if (uninterpreted_option_->positive_int_value() > kuint32max) { + return AddValueError("Value out of range for uint32 option \"" + + option_field->name() + "\"."); + } else { + SetUInt32(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } + } else { + return AddValueError("Value must be non-negative integer for uint32 " + "option \"" + option_field->full_name() + "\"."); + } + break; + + case FieldDescriptor::CPPTYPE_UINT64: + if (uninterpreted_option_->has_positive_int_value()) { + SetUInt64(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } else { + return AddValueError("Value must be non-negative integer for uint64 " + "option \"" + option_field->full_name() + "\"."); + } + break; + + case FieldDescriptor::CPPTYPE_FLOAT: { + float value; + if (uninterpreted_option_->has_double_value()) { + value = uninterpreted_option_->double_value(); + } else if (uninterpreted_option_->has_positive_int_value()) { + value = uninterpreted_option_->positive_int_value(); + } else if (uninterpreted_option_->has_negative_int_value()) { + value = uninterpreted_option_->negative_int_value(); + } else { + return AddValueError("Value must be number for float option \"" + + option_field->full_name() + "\"."); + } + unknown_fields->AddFixed32(option_field->number(), + google::protobuf::internal::WireFormatLite::EncodeFloat(value)); + break; + } + + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value; + if (uninterpreted_option_->has_double_value()) { + value = uninterpreted_option_->double_value(); + } else if (uninterpreted_option_->has_positive_int_value()) { + value = uninterpreted_option_->positive_int_value(); + } else if (uninterpreted_option_->has_negative_int_value()) { + value = uninterpreted_option_->negative_int_value(); + } else { + return AddValueError("Value must be number for double option \"" + + option_field->full_name() + "\"."); + } + unknown_fields->AddFixed64(option_field->number(), + google::protobuf::internal::WireFormatLite::EncodeDouble(value)); + break; + } + + case FieldDescriptor::CPPTYPE_BOOL: + uint64 value; + if (!uninterpreted_option_->has_identifier_value()) { + return AddValueError("Value must be identifier for boolean option " + "\"" + option_field->full_name() + "\"."); + } + if (uninterpreted_option_->identifier_value() == "true") { + value = 1; + } else if (uninterpreted_option_->identifier_value() == "false") { + value = 0; + } else { + return AddValueError("Value must be \"true\" or \"false\" for boolean " + "option \"" + option_field->full_name() + "\"."); + } + unknown_fields->AddVarint(option_field->number(), value); + break; + + case FieldDescriptor::CPPTYPE_ENUM: { + if (!uninterpreted_option_->has_identifier_value()) { + return AddValueError("Value must be identifier for enum-valued option " + "\"" + option_field->full_name() + "\"."); + } + const EnumDescriptor* enum_type = option_field->enum_type(); + const string& value_name = uninterpreted_option_->identifier_value(); + const EnumValueDescriptor* enum_value = NULL; + + if (enum_type->file()->pool() != DescriptorPool::generated_pool()) { + // Note that the enum value's fully-qualified name is a sibling of the + // enum's name, not a child of it. + string fully_qualified_name = enum_type->full_name(); + fully_qualified_name.resize(fully_qualified_name.size() - + enum_type->name().size()); + fully_qualified_name += value_name; + + // Search for the enum value's descriptor in the builder's pool. Note + // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not + // DescriptorPool::FindEnumValueByName() because we're already holding + // the pool's mutex, and the latter method locks it again. + Symbol symbol = + builder_->FindSymbolNotEnforcingDeps(fully_qualified_name); + if (!symbol.IsNull() && symbol.type == Symbol::ENUM_VALUE) { + if (symbol.enum_value_descriptor->type() != enum_type) { + return AddValueError("Enum type \"" + enum_type->full_name() + + "\" has no value named \"" + value_name + "\" for option \"" + + option_field->full_name() + + "\". This appears to be a value from a sibling type."); + } else { + enum_value = symbol.enum_value_descriptor; + } + } + } else { + // The enum type is in the generated pool, so we can search for the + // value there. + enum_value = enum_type->FindValueByName(value_name); + } + + if (enum_value == NULL) { + return AddValueError("Enum type \"" + + option_field->enum_type()->full_name() + + "\" has no value named \"" + value_name + "\" for " + "option \"" + option_field->full_name() + "\"."); + } else { + // Sign-extension is not a problem, since we cast directly from int32 to + // uint64, without first going through uint32. + unknown_fields->AddVarint(option_field->number(), + static_cast(static_cast(enum_value->number()))); + } + break; + } + + case FieldDescriptor::CPPTYPE_STRING: + if (!uninterpreted_option_->has_string_value()) { + return AddValueError("Value must be quoted string for string option " + "\"" + option_field->full_name() + "\"."); + } + // The string has already been unquoted and unescaped by the parser. + unknown_fields->AddLengthDelimited(option_field->number(), + uninterpreted_option_->string_value()); + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + if (!SetAggregateOption(option_field, unknown_fields)) { + return false; + } + break; + } + + return true; +} + +class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder + : public TextFormat::Finder { + public: + DescriptorBuilder* builder_; + + virtual const FieldDescriptor* FindExtension( + Message* message, const string& name) const { + assert_mutex_held(builder_->pool_); + const Descriptor* descriptor = message->GetDescriptor(); + Symbol result = builder_->LookupSymbolNoPlaceholder( + name, descriptor->full_name()); + if (result.type == Symbol::FIELD && + result.field_descriptor->is_extension()) { + return result.field_descriptor; + } else if (result.type == Symbol::MESSAGE && + descriptor->options().message_set_wire_format()) { + const Descriptor* foreign_type = result.descriptor; + // The text format allows MessageSet items to be specified using + // the type name, rather than the extension identifier. If the symbol + // lookup returned a Message, and the enclosing Message has + // message_set_wire_format = true, then return the message set + // extension, if one exists. + for (int i = 0; i < foreign_type->extension_count(); i++) { + const FieldDescriptor* extension = foreign_type->extension(i); + if (extension->containing_type() == descriptor && + extension->type() == FieldDescriptor::TYPE_MESSAGE && + extension->is_optional() && + extension->message_type() == foreign_type) { + // Found it. + return extension; + } + } + } + return NULL; + } +}; + +// A custom error collector to record any text-format parsing errors +namespace { +class AggregateErrorCollector : public io::ErrorCollector { + public: + string error_; + + virtual void AddError(int line, int column, const string& message) { + if (!error_.empty()) { + error_ += "; "; + } + error_ += message; + } + + virtual void AddWarning(int line, int column, const string& message) { + // Ignore warnings + } +}; +} + +// We construct a dynamic message of the type corresponding to +// option_field, parse the supplied text-format string into this +// message, and serialize the resulting message to produce the value. +bool DescriptorBuilder::OptionInterpreter::SetAggregateOption( + const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields) { + if (!uninterpreted_option_->has_aggregate_value()) { + return AddValueError("Option \"" + option_field->full_name() + + "\" is a message. To set the entire message, use " + "syntax like \"" + option_field->name() + + " = { }\". " + "To set fields within it, use " + "syntax like \"" + option_field->name() + + ".foo = value\"."); + } + + const Descriptor* type = option_field->message_type(); + scoped_ptr dynamic(dynamic_factory_.GetPrototype(type)->New()); + GOOGLE_CHECK(dynamic.get() != NULL) + << "Could not create an instance of " << option_field->DebugString(); + + AggregateErrorCollector collector; + AggregateOptionFinder finder; + finder.builder_ = builder_; + TextFormat::Parser parser; + parser.RecordErrorsTo(&collector); + parser.SetFinder(&finder); + if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(), + dynamic.get())) { + AddValueError("Error while parsing option value for \"" + + option_field->name() + "\": " + collector.error_); + return false; + } else { + string serial; + dynamic->SerializeToString(&serial); // Never fails + if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) { + unknown_fields->AddLengthDelimited(option_field->number(), serial); + } else { + GOOGLE_CHECK_EQ(option_field->type(), FieldDescriptor::TYPE_GROUP); + UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number()); + group->ParseFromString(serial); + } + return true; + } +} + +void DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value, + FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_INT32: + unknown_fields->AddVarint(number, + static_cast(static_cast(value))); + break; + + case FieldDescriptor::TYPE_SFIXED32: + unknown_fields->AddFixed32(number, static_cast(value)); + break; + + case FieldDescriptor::TYPE_SINT32: + unknown_fields->AddVarint(number, + google::protobuf::internal::WireFormatLite::ZigZagEncode32(value)); + break; + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type; + break; + } +} + +void DescriptorBuilder::OptionInterpreter::SetInt64(int number, int64 value, + FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_INT64: + unknown_fields->AddVarint(number, static_cast(value)); + break; + + case FieldDescriptor::TYPE_SFIXED64: + unknown_fields->AddFixed64(number, static_cast(value)); + break; + + case FieldDescriptor::TYPE_SINT64: + unknown_fields->AddVarint(number, + google::protobuf::internal::WireFormatLite::ZigZagEncode64(value)); + break; + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type; + break; + } +} + +void DescriptorBuilder::OptionInterpreter::SetUInt32(int number, uint32 value, + FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_UINT32: + unknown_fields->AddVarint(number, static_cast(value)); + break; + + case FieldDescriptor::TYPE_FIXED32: + unknown_fields->AddFixed32(number, static_cast(value)); + break; + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type; + break; + } +} + +void DescriptorBuilder::OptionInterpreter::SetUInt64(int number, uint64 value, + FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_UINT64: + unknown_fields->AddVarint(number, value); + break; + + case FieldDescriptor::TYPE_FIXED64: + unknown_fields->AddFixed64(number, value); + break; + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type; + break; + } +} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.h new file mode 100644 index 0000000..33e3af7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.h @@ -0,0 +1,1521 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains classes which describe a type of protocol message. +// You can use a message's descriptor to learn at runtime what fields +// it contains and what the types of those fields are. The Message +// interface also allows you to dynamically access and modify individual +// fields by passing the FieldDescriptor of the field you are interested +// in. +// +// Most users will not care about descriptors, because they will write +// code specific to certain protocol types and will simply use the classes +// generated by the protocol compiler directly. Advanced users who want +// to operate on arbitrary types (not known at compile time) may want to +// read descriptors in order to learn about the contents of a message. +// A very small number of users will want to construct their own +// Descriptors, either because they are implementing Message manually or +// because they are writing something like the protocol compiler. +// +// For an example of how you might use descriptors, see the code example +// at the top of message.h. + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__ +#define GOOGLE_PROTOBUF_DESCRIPTOR_H__ + +#include +#include +#include + +// TYPE_BOOL is defined in the MacOS's ConditionalMacros.h. +#ifdef TYPE_BOOL +#undef TYPE_BOOL +#endif // TYPE_BOOL + +namespace google { +namespace protobuf { + +// Defined in this file. +class Descriptor; +class FieldDescriptor; +class EnumDescriptor; +class EnumValueDescriptor; +class ServiceDescriptor; +class MethodDescriptor; +class FileDescriptor; +class DescriptorDatabase; +class DescriptorPool; + +// Defined in descriptor.proto +class DescriptorProto; +class FieldDescriptorProto; +class EnumDescriptorProto; +class EnumValueDescriptorProto; +class ServiceDescriptorProto; +class MethodDescriptorProto; +class FileDescriptorProto; +class MessageOptions; +class FieldOptions; +class EnumOptions; +class EnumValueOptions; +class ServiceOptions; +class MethodOptions; +class FileOptions; +class UninterpretedOption; +class SourceCodeInfo; + +// Defined in message.h +class Message; + +// Defined in descriptor.cc +class DescriptorBuilder; +class FileDescriptorTables; + +// Defined in unknown_field_set.h. +class UnknownField; + +// NB, all indices are zero-based. +struct SourceLocation { + int start_line; + int end_line; + int start_column; + int end_column; + + // Doc comments found at the source location. + // TODO(kenton): Maybe this struct should have been named SourceInfo or + // something instead. Oh well. + string leading_comments; + string trailing_comments; +}; + +// Describes a type of protocol message, or a particular group within a +// message. To obtain the Descriptor for a given message object, call +// Message::GetDescriptor(). Generated message classes also have a +// static method called descriptor() which returns the type's descriptor. +// Use DescriptorPool to construct your own descriptors. +class LIBPROTOBUF_EXPORT Descriptor { + public: + // The name of the message type, not including its scope. + const string& name() const; + + // The fully-qualified name of the message type, scope delimited by + // periods. For example, message type "Foo" which is declared in package + // "bar" has full name "bar.Foo". If a type "Baz" is nested within + // Foo, Baz's full_name is "bar.Foo.Baz". To get only the part that + // comes after the last '.', use name(). + const string& full_name() const; + + // Index of this descriptor within the file or containing type's message + // type array. + int index() const; + + // The .proto file in which this message type was defined. Never NULL. + const FileDescriptor* file() const; + + // If this Descriptor describes a nested type, this returns the type + // in which it is nested. Otherwise, returns NULL. + const Descriptor* containing_type() const; + + // Get options for this message type. These are specified in the .proto file + // by placing lines like "option foo = 1234;" in the message definition. + // Allowed options are defined by MessageOptions in + // google/protobuf/descriptor.proto, and any available extensions of that + // message. + const MessageOptions& options() const; + + // Write the contents of this Descriptor into the given DescriptorProto. + // The target DescriptorProto must be clear before calling this; if it + // isn't, the result may be garbage. + void CopyTo(DescriptorProto* proto) const; + + // Write the contents of this decriptor in a human-readable form. Output + // will be suitable for re-parsing. + string DebugString() const; + + // Field stuff ----------------------------------------------------- + + // The number of fields in this message type. + int field_count() const; + // Gets a field by index, where 0 <= index < field_count(). + // These are returned in the order they were defined in the .proto file. + const FieldDescriptor* field(int index) const; + + // Looks up a field by declared tag number. Returns NULL if no such field + // exists. + const FieldDescriptor* FindFieldByNumber(int number) const; + // Looks up a field by name. Returns NULL if no such field exists. + const FieldDescriptor* FindFieldByName(const string& name) const; + + // Looks up a field by lowercased name (as returned by lowercase_name()). + // This lookup may be ambiguous if multiple field names differ only by case, + // in which case the field returned is chosen arbitrarily from the matches. + const FieldDescriptor* FindFieldByLowercaseName( + const string& lowercase_name) const; + + // Looks up a field by camel-case name (as returned by camelcase_name()). + // This lookup may be ambiguous if multiple field names differ in a way that + // leads them to have identical camel-case names, in which case the field + // returned is chosen arbitrarily from the matches. + const FieldDescriptor* FindFieldByCamelcaseName( + const string& camelcase_name) const; + + // Nested type stuff ----------------------------------------------- + + // The number of nested types in this message type. + int nested_type_count() const; + // Gets a nested type by index, where 0 <= index < nested_type_count(). + // These are returned in the order they were defined in the .proto file. + const Descriptor* nested_type(int index) const; + + // Looks up a nested type by name. Returns NULL if no such nested type + // exists. + const Descriptor* FindNestedTypeByName(const string& name) const; + + // Enum stuff ------------------------------------------------------ + + // The number of enum types in this message type. + int enum_type_count() const; + // Gets an enum type by index, where 0 <= index < enum_type_count(). + // These are returned in the order they were defined in the .proto file. + const EnumDescriptor* enum_type(int index) const; + + // Looks up an enum type by name. Returns NULL if no such enum type exists. + const EnumDescriptor* FindEnumTypeByName(const string& name) const; + + // Looks up an enum value by name, among all enum types in this message. + // Returns NULL if no such value exists. + const EnumValueDescriptor* FindEnumValueByName(const string& name) const; + + // Extensions ------------------------------------------------------ + + // A range of field numbers which are designated for third-party + // extensions. + struct ExtensionRange { + int start; // inclusive + int end; // exclusive + }; + + // The number of extension ranges in this message type. + int extension_range_count() const; + // Gets an extension range by index, where 0 <= index < + // extension_range_count(). These are returned in the order they were defined + // in the .proto file. + const ExtensionRange* extension_range(int index) const; + + // Returns true if the number is in one of the extension ranges. + bool IsExtensionNumber(int number) const; + + // The number of extensions -- extending *other* messages -- that were + // defined nested within this message type's scope. + int extension_count() const; + // Get an extension by index, where 0 <= index < extension_count(). + // These are returned in the order they were defined in the .proto file. + const FieldDescriptor* extension(int index) const; + + // Looks up a named extension (which extends some *other* message type) + // defined within this message type's scope. + const FieldDescriptor* FindExtensionByName(const string& name) const; + + // Similar to FindFieldByLowercaseName(), but finds extensions defined within + // this message type's scope. + const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const; + + // Similar to FindFieldByCamelcaseName(), but finds extensions defined within + // this message type's scope. + const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this message declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef MessageOptions OptionsType; + + // Internal version of DebugString; controls the level of indenting for + // correct depth + void DebugString(int depth, string *contents) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(vector* output) const; + + const string* name_; + const string* full_name_; + const FileDescriptor* file_; + const Descriptor* containing_type_; + const MessageOptions* options_; + + // True if this is a placeholder for an unknown type. + bool is_placeholder_; + // True if this is a placeholder and the type name wasn't fully-qualified. + bool is_unqualified_placeholder_; + + int field_count_; + FieldDescriptor* fields_; + int nested_type_count_; + Descriptor* nested_types_; + int enum_type_count_; + EnumDescriptor* enum_types_; + int extension_range_count_; + ExtensionRange* extension_ranges_; + int extension_count_; + FieldDescriptor* extensions_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in descriptor.cc + // and update them to initialize the field. + + // Must be constructed using DescriptorPool. + Descriptor() {} + friend class DescriptorBuilder; + friend class EnumDescriptor; + friend class FieldDescriptor; + friend class MethodDescriptor; + friend class FileDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor); +}; + +// Describes a single field of a message. To get the descriptor for a given +// field, first get the Descriptor for the message in which it is defined, +// then call Descriptor::FindFieldByName(). To get a FieldDescriptor for +// an extension, do one of the following: +// - Get the Descriptor or FileDescriptor for its containing scope, then +// call Descriptor::FindExtensionByName() or +// FileDescriptor::FindExtensionByName(). +// - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber(). +// - Given a Reflection for a message object, call +// Reflection::FindKnownExtensionByName() or +// Reflection::FindKnownExtensionByNumber(). +// Use DescriptorPool to construct your own descriptors. +class LIBPROTOBUF_EXPORT FieldDescriptor { + public: + // Identifies a field type. 0 is reserved for errors. The order is weird + // for historical reasons. Types 12 and up are new in proto2. + enum Type { + TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire. + TYPE_FLOAT = 2, // float, exactly four bytes on the wire. + TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers + // take 10 bytes. Use TYPE_SINT64 if negative + // values are likely. + TYPE_UINT64 = 4, // uint64, varint on the wire. + TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers + // take 10 bytes. Use TYPE_SINT32 if negative + // values are likely. + TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire. + TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire. + TYPE_BOOL = 8, // bool, varint on the wire. + TYPE_STRING = 9, // UTF-8 text. + TYPE_GROUP = 10, // Tag-delimited message. Deprecated. + TYPE_MESSAGE = 11, // Length-delimited message. + + TYPE_BYTES = 12, // Arbitrary byte array. + TYPE_UINT32 = 13, // uint32, varint on the wire + TYPE_ENUM = 14, // Enum, varint on the wire + TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire + TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire + TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire + TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire + + MAX_TYPE = 18, // Constant useful for defining lookup tables + // indexed by Type. + }; + + // Specifies the C++ data type used to represent the field. There is a + // fixed mapping from Type to CppType where each Type maps to exactly one + // CppType. 0 is reserved for errors. + enum CppType { + CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 + CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 + CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32 + CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64 + CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE + CPPTYPE_FLOAT = 6, // TYPE_FLOAT + CPPTYPE_BOOL = 7, // TYPE_BOOL + CPPTYPE_ENUM = 8, // TYPE_ENUM + CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES + CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP + + MAX_CPPTYPE = 10, // Constant useful for defining lookup tables + // indexed by CppType. + }; + + // Identifies whether the field is optional, required, or repeated. 0 is + // reserved for errors. + enum Label { + LABEL_OPTIONAL = 1, // optional + LABEL_REQUIRED = 2, // required + LABEL_REPEATED = 3, // repeated + + MAX_LABEL = 3, // Constant useful for defining lookup tables + // indexed by Label. + }; + + // Valid field numbers are positive integers up to kMaxNumber. + static const int kMaxNumber = (1 << 29) - 1; + + // First field number reserved for the protocol buffer library implementation. + // Users may not declare fields that use reserved numbers. + static const int kFirstReservedNumber = 19000; + // Last field number reserved for the protocol buffer library implementation. + // Users may not declare fields that use reserved numbers. + static const int kLastReservedNumber = 19999; + + const string& name() const; // Name of this field within the message. + const string& full_name() const; // Fully-qualified name of the field. + const FileDescriptor* file() const;// File in which this field was defined. + bool is_extension() const; // Is this an extension field? + int number() const; // Declared tag number. + + // Same as name() except converted to lower-case. This (and especially the + // FindFieldByLowercaseName() method) can be useful when parsing formats + // which prefer to use lowercase naming style. (Although, technically + // field names should be lowercased anyway according to the protobuf style + // guide, so this only makes a difference when dealing with old .proto files + // which do not follow the guide.) + const string& lowercase_name() const; + + // Same as name() except converted to camel-case. In this conversion, any + // time an underscore appears in the name, it is removed and the next + // letter is capitalized. Furthermore, the first letter of the name is + // lower-cased. Examples: + // FooBar -> fooBar + // foo_bar -> fooBar + // fooBar -> fooBar + // This (and especially the FindFieldByCamelcaseName() method) can be useful + // when parsing formats which prefer to use camel-case naming style. + const string& camelcase_name() const; + + Type type() const; // Declared type of this field. + const char* type_name() const; // Name of the declared type. + CppType cpp_type() const; // C++ type of this field. + const char* cpp_type_name() const; // Name of the C++ type. + Label label() const; // optional/required/repeated + + bool is_required() const; // shorthand for label() == LABEL_REQUIRED + bool is_optional() const; // shorthand for label() == LABEL_OPTIONAL + bool is_repeated() const; // shorthand for label() == LABEL_REPEATED + bool is_packable() const; // shorthand for is_repeated() && + // IsTypePackable(type()) + bool is_packed() const; // shorthand for is_packable() && + // options().packed() + + // Index of this field within the message's field array, or the file or + // extension scope's extensions array. + int index() const; + + // Does this field have an explicitly-declared default value? + bool has_default_value() const; + + // Get the field default value if cpp_type() == CPPTYPE_INT32. If no + // explicit default was defined, the default is 0. + int32 default_value_int32() const; + // Get the field default value if cpp_type() == CPPTYPE_INT64. If no + // explicit default was defined, the default is 0. + int64 default_value_int64() const; + // Get the field default value if cpp_type() == CPPTYPE_UINT32. If no + // explicit default was defined, the default is 0. + uint32 default_value_uint32() const; + // Get the field default value if cpp_type() == CPPTYPE_UINT64. If no + // explicit default was defined, the default is 0. + uint64 default_value_uint64() const; + // Get the field default value if cpp_type() == CPPTYPE_FLOAT. If no + // explicit default was defined, the default is 0.0. + float default_value_float() const; + // Get the field default value if cpp_type() == CPPTYPE_DOUBLE. If no + // explicit default was defined, the default is 0.0. + double default_value_double() const; + // Get the field default value if cpp_type() == CPPTYPE_BOOL. If no + // explicit default was defined, the default is false. + bool default_value_bool() const; + // Get the field default value if cpp_type() == CPPTYPE_ENUM. If no + // explicit default was defined, the default is the first value defined + // in the enum type (all enum types are required to have at least one value). + // This never returns NULL. + const EnumValueDescriptor* default_value_enum() const; + // Get the field default value if cpp_type() == CPPTYPE_STRING. If no + // explicit default was defined, the default is the empty string. + const string& default_value_string() const; + + // The Descriptor for the message of which this is a field. For extensions, + // this is the extended type. Never NULL. + const Descriptor* containing_type() const; + + // An extension may be declared within the scope of another message. If this + // field is an extension (is_extension() is true), then extension_scope() + // returns that message, or NULL if the extension was declared at global + // scope. If this is not an extension, extension_scope() is undefined (may + // assert-fail). + const Descriptor* extension_scope() const; + + // If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the + // message or the group type. Otherwise, undefined. + const Descriptor* message_type() const; + // If type is TYPE_ENUM, returns a descriptor for the enum. Otherwise, + // undefined. + const EnumDescriptor* enum_type() const; + + // EXPERIMENTAL; DO NOT USE. + // If this field is a map field, experimental_map_key() is the field + // that is the key for this map. + // experimental_map_key()->containing_type() is the same as message_type(). + const FieldDescriptor* experimental_map_key() const; + + // Get the FieldOptions for this field. This includes things listed in + // square brackets after the field definition. E.g., the field: + // optional string text = 1 [ctype=CORD]; + // has the "ctype" option set. Allowed options are defined by FieldOptions + // in google/protobuf/descriptor.proto, and any available extensions of that + // message. + const FieldOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(FieldDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // Helper method to get the CppType for a particular Type. + static CppType TypeToCppType(Type type); + + // Return true iff [packed = true] is valid for fields of this type. + static inline bool IsTypePackable(Type field_type); + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this field declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef FieldOptions OptionsType; + + // See Descriptor::DebugString(). + void DebugString(int depth, string *contents) const; + + // formats the default value appropriately and returns it as a string. + // Must have a default value to call this. If quote_string_type is true, then + // types of CPPTYPE_STRING whill be surrounded by quotes and CEscaped. + string DefaultValueAsString(bool quote_string_type) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(vector* output) const; + + const string* name_; + const string* full_name_; + const string* lowercase_name_; + const string* camelcase_name_; + const FileDescriptor* file_; + int number_; + Type type_; + Label label_; + bool is_extension_; + const Descriptor* containing_type_; + const Descriptor* extension_scope_; + const Descriptor* message_type_; + const EnumDescriptor* enum_type_; + const FieldDescriptor* experimental_map_key_; + const FieldOptions* options_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in + // descriptor.cc and update them to initialize the field. + + bool has_default_value_; + union { + int32 default_value_int32_; + int64 default_value_int64_; + uint32 default_value_uint32_; + uint64 default_value_uint64_; + float default_value_float_; + double default_value_double_; + bool default_value_bool_; + + const EnumValueDescriptor* default_value_enum_; + const string* default_value_string_; + }; + + static const CppType kTypeToCppTypeMap[MAX_TYPE + 1]; + + static const char * const kTypeToName[MAX_TYPE + 1]; + + static const char * const kCppTypeToName[MAX_CPPTYPE + 1]; + + static const char * const kLabelToName[MAX_LABEL + 1]; + + // Must be constructed using DescriptorPool. + FieldDescriptor() {} + friend class DescriptorBuilder; + friend class FileDescriptor; + friend class Descriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor); +}; + +// Describes an enum type defined in a .proto file. To get the EnumDescriptor +// for a generated enum type, call TypeName_descriptor(). Use DescriptorPool +// to construct your own descriptors. +class LIBPROTOBUF_EXPORT EnumDescriptor { + public: + // The name of this enum type in the containing scope. + const string& name() const; + + // The fully-qualified name of the enum type, scope delimited by periods. + const string& full_name() const; + + // Index of this enum within the file or containing message's enum array. + int index() const; + + // The .proto file in which this enum type was defined. Never NULL. + const FileDescriptor* file() const; + + // The number of values for this EnumDescriptor. Guaranteed to be greater + // than zero. + int value_count() const; + // Gets a value by index, where 0 <= index < value_count(). + // These are returned in the order they were defined in the .proto file. + const EnumValueDescriptor* value(int index) const; + + // Looks up a value by name. Returns NULL if no such value exists. + const EnumValueDescriptor* FindValueByName(const string& name) const; + // Looks up a value by number. Returns NULL if no such value exists. If + // multiple values have this number, the first one defined is returned. + const EnumValueDescriptor* FindValueByNumber(int number) const; + + // If this enum type is nested in a message type, this is that message type. + // Otherwise, NULL. + const Descriptor* containing_type() const; + + // Get options for this enum type. These are specified in the .proto file by + // placing lines like "option foo = 1234;" in the enum definition. Allowed + // options are defined by EnumOptions in google/protobuf/descriptor.proto, + // and any available extensions of that message. + const EnumOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(EnumDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this enum declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef EnumOptions OptionsType; + + // See Descriptor::DebugString(). + void DebugString(int depth, string *contents) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(vector* output) const; + + const string* name_; + const string* full_name_; + const FileDescriptor* file_; + const Descriptor* containing_type_; + const EnumOptions* options_; + + // True if this is a placeholder for an unknown type. + bool is_placeholder_; + // True if this is a placeholder and the type name wasn't fully-qualified. + bool is_unqualified_placeholder_; + + int value_count_; + EnumValueDescriptor* values_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in + // descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + EnumDescriptor() {} + friend class DescriptorBuilder; + friend class Descriptor; + friend class FieldDescriptor; + friend class EnumValueDescriptor; + friend class FileDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor); +}; + +// Describes an individual enum constant of a particular type. To get the +// EnumValueDescriptor for a given enum value, first get the EnumDescriptor +// for its type, then use EnumDescriptor::FindValueByName() or +// EnumDescriptor::FindValueByNumber(). Use DescriptorPool to construct +// your own descriptors. +class LIBPROTOBUF_EXPORT EnumValueDescriptor { + public: + const string& name() const; // Name of this enum constant. + int index() const; // Index within the enums's Descriptor. + int number() const; // Numeric value of this enum constant. + + // The full_name of an enum value is a sibling symbol of the enum type. + // e.g. the full name of FieldDescriptorProto::TYPE_INT32 is actually + // "google.protobuf.FieldDescriptorProto.TYPE_INT32", NOT + // "google.protobuf.FieldDescriptorProto.Type.TYPE_INT32". This is to conform + // with C++ scoping rules for enums. + const string& full_name() const; + + // The type of this value. Never NULL. + const EnumDescriptor* type() const; + + // Get options for this enum value. These are specified in the .proto file + // by adding text like "[foo = 1234]" after an enum value definition. + // Allowed options are defined by EnumValueOptions in + // google/protobuf/descriptor.proto, and any available extensions of that + // message. + const EnumValueOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(EnumValueDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this enum value declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef EnumValueOptions OptionsType; + + // See Descriptor::DebugString(). + void DebugString(int depth, string *contents) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(vector* output) const; + + const string* name_; + const string* full_name_; + int number_; + const EnumDescriptor* type_; + const EnumValueOptions* options_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() + // in descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + EnumValueDescriptor() {} + friend class DescriptorBuilder; + friend class EnumDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor); +}; + +// Describes an RPC service. To get the ServiceDescriptor for a service, +// call Service::GetDescriptor(). Generated service classes also have a +// static method called descriptor() which returns the type's +// ServiceDescriptor. Use DescriptorPool to construct your own descriptors. +class LIBPROTOBUF_EXPORT ServiceDescriptor { + public: + // The name of the service, not including its containing scope. + const string& name() const; + // The fully-qualified name of the service, scope delimited by periods. + const string& full_name() const; + // Index of this service within the file's services array. + int index() const; + + // The .proto file in which this service was defined. Never NULL. + const FileDescriptor* file() const; + + // Get options for this service type. These are specified in the .proto file + // by placing lines like "option foo = 1234;" in the service definition. + // Allowed options are defined by ServiceOptions in + // google/protobuf/descriptor.proto, and any available extensions of that + // message. + const ServiceOptions& options() const; + + // The number of methods this service defines. + int method_count() const; + // Gets a MethodDescriptor by index, where 0 <= index < method_count(). + // These are returned in the order they were defined in the .proto file. + const MethodDescriptor* method(int index) const; + + // Look up a MethodDescriptor by name. + const MethodDescriptor* FindMethodByName(const string& name) const; + // See Descriptor::CopyTo(). + void CopyTo(ServiceDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this service declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef ServiceOptions OptionsType; + + // See Descriptor::DebugString(). + void DebugString(string *contents) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(vector* output) const; + + const string* name_; + const string* full_name_; + const FileDescriptor* file_; + const ServiceOptions* options_; + int method_count_; + MethodDescriptor* methods_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in + // descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + ServiceDescriptor() {} + friend class DescriptorBuilder; + friend class FileDescriptor; + friend class MethodDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceDescriptor); +}; + +// Describes an individual service method. To obtain a MethodDescriptor given +// a service, first get its ServiceDescriptor, then call +// ServiceDescriptor::FindMethodByName(). Use DescriptorPool to construct your +// own descriptors. +class LIBPROTOBUF_EXPORT MethodDescriptor { + public: + // Name of this method, not including containing scope. + const string& name() const; + // The fully-qualified name of the method, scope delimited by periods. + const string& full_name() const; + // Index within the service's Descriptor. + int index() const; + + // Gets the service to which this method belongs. Never NULL. + const ServiceDescriptor* service() const; + + // Gets the type of protocol message which this method accepts as input. + const Descriptor* input_type() const; + // Gets the type of protocol message which this message produces as output. + const Descriptor* output_type() const; + + // Get options for this method. These are specified in the .proto file by + // placing lines like "option foo = 1234;" in curly-braces after a method + // declaration. Allowed options are defined by MethodOptions in + // google/protobuf/descriptor.proto, and any available extensions of that + // message. + const MethodOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(MethodDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this method declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef MethodOptions OptionsType; + + // See Descriptor::DebugString(). + void DebugString(int depth, string *contents) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(vector* output) const; + + const string* name_; + const string* full_name_; + const ServiceDescriptor* service_; + const Descriptor* input_type_; + const Descriptor* output_type_; + const MethodOptions* options_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in + // descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + MethodDescriptor() {} + friend class DescriptorBuilder; + friend class ServiceDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MethodDescriptor); +}; + + +// Describes a whole .proto file. To get the FileDescriptor for a compiled-in +// file, get the descriptor for something defined in that file and call +// descriptor->file(). Use DescriptorPool to construct your own descriptors. +class LIBPROTOBUF_EXPORT FileDescriptor { + public: + // The filename, relative to the source tree. + // e.g. "google/protobuf/descriptor.proto" + const string& name() const; + + // The package, e.g. "google.protobuf.compiler". + const string& package() const; + + // The DescriptorPool in which this FileDescriptor and all its contents were + // allocated. Never NULL. + const DescriptorPool* pool() const; + + // The number of files imported by this one. + int dependency_count() const; + // Gets an imported file by index, where 0 <= index < dependency_count(). + // These are returned in the order they were defined in the .proto file. + const FileDescriptor* dependency(int index) const; + + // The number of files public imported by this one. + // The public dependency list is a subset of the dependency list. + int public_dependency_count() const; + // Gets a public imported file by index, where 0 <= index < + // public_dependency_count(). + // These are returned in the order they were defined in the .proto file. + const FileDescriptor* public_dependency(int index) const; + + // The number of files that are imported for weak fields. + // The weak dependency list is a subset of the dependency list. + int weak_dependency_count() const; + // Gets a weak imported file by index, where 0 <= index < + // weak_dependency_count(). + // These are returned in the order they were defined in the .proto file. + const FileDescriptor* weak_dependency(int index) const; + + // Number of top-level message types defined in this file. (This does not + // include nested types.) + int message_type_count() const; + // Gets a top-level message type, where 0 <= index < message_type_count(). + // These are returned in the order they were defined in the .proto file. + const Descriptor* message_type(int index) const; + + // Number of top-level enum types defined in this file. (This does not + // include nested types.) + int enum_type_count() const; + // Gets a top-level enum type, where 0 <= index < enum_type_count(). + // These are returned in the order they were defined in the .proto file. + const EnumDescriptor* enum_type(int index) const; + + // Number of services defined in this file. + int service_count() const; + // Gets a service, where 0 <= index < service_count(). + // These are returned in the order they were defined in the .proto file. + const ServiceDescriptor* service(int index) const; + + // Number of extensions defined at file scope. (This does not include + // extensions nested within message types.) + int extension_count() const; + // Gets an extension's descriptor, where 0 <= index < extension_count(). + // These are returned in the order they were defined in the .proto file. + const FieldDescriptor* extension(int index) const; + + // Get options for this file. These are specified in the .proto file by + // placing lines like "option foo = 1234;" at the top level, outside of any + // other definitions. Allowed options are defined by FileOptions in + // google/protobuf/descriptor.proto, and any available extensions of that + // message. + const FileOptions& options() const; + + // Find a top-level message type by name. Returns NULL if not found. + const Descriptor* FindMessageTypeByName(const string& name) const; + // Find a top-level enum type by name. Returns NULL if not found. + const EnumDescriptor* FindEnumTypeByName(const string& name) const; + // Find an enum value defined in any top-level enum by name. Returns NULL if + // not found. + const EnumValueDescriptor* FindEnumValueByName(const string& name) const; + // Find a service definition by name. Returns NULL if not found. + const ServiceDescriptor* FindServiceByName(const string& name) const; + // Find a top-level extension definition by name. Returns NULL if not found. + const FieldDescriptor* FindExtensionByName(const string& name) const; + // Similar to FindExtensionByName(), but searches by lowercased-name. See + // Descriptor::FindFieldByLowercaseName(). + const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const; + // Similar to FindExtensionByName(), but searches by camelcased-name. See + // Descriptor::FindFieldByCamelcaseName(). + const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const; + + // See Descriptor::CopyTo(). + // Notes: + // - This method does NOT copy source code information since it is relatively + // large and rarely needed. See CopySourceCodeInfoTo() below. + void CopyTo(FileDescriptorProto* proto) const; + // Write the source code information of this FileDescriptor into the given + // FileDescriptorProto. See CopyTo() above. + void CopySourceCodeInfoTo(FileDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + private: + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of the declaration or declaration-part denoted by |path|. + // Returns false and leaves |*out_location| unchanged iff location + // information was not available. (See SourceCodeInfo for + // description of path encoding.) + bool GetSourceLocation(const vector& path, + SourceLocation* out_location) const; + + typedef FileOptions OptionsType; + + const string* name_; + const string* package_; + const DescriptorPool* pool_; + int dependency_count_; + const FileDescriptor** dependencies_; + int public_dependency_count_; + int* public_dependencies_; + int weak_dependency_count_; + int* weak_dependencies_; + int message_type_count_; + Descriptor* message_types_; + int enum_type_count_; + EnumDescriptor* enum_types_; + int service_count_; + ServiceDescriptor* services_; + int extension_count_; + FieldDescriptor* extensions_; + const FileOptions* options_; + + const FileDescriptorTables* tables_; + const SourceCodeInfo* source_code_info_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in + // descriptor.cc and update them to initialize the field. + + FileDescriptor() {} + friend class DescriptorBuilder; + friend class Descriptor; + friend class FieldDescriptor; + friend class EnumDescriptor; + friend class EnumValueDescriptor; + friend class MethodDescriptor; + friend class ServiceDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor); +}; + +// =================================================================== + +// Used to construct descriptors. +// +// Normally you won't want to build your own descriptors. Message classes +// constructed by the protocol compiler will provide them for you. However, +// if you are implementing Message on your own, or if you are writing a +// program which can operate on totally arbitrary types and needs to load +// them from some sort of database, you might need to. +// +// Since Descriptors are composed of a whole lot of cross-linked bits of +// data that would be a pain to put together manually, the +// DescriptorPool class is provided to make the process easier. It can +// take a FileDescriptorProto (defined in descriptor.proto), validate it, +// and convert it to a set of nicely cross-linked Descriptors. +// +// DescriptorPool also helps with memory management. Descriptors are +// composed of many objects containing static data and pointers to each +// other. In all likelihood, when it comes time to delete this data, +// you'll want to delete it all at once. In fact, it is not uncommon to +// have a whole pool of descriptors all cross-linked with each other which +// you wish to delete all at once. This class represents such a pool, and +// handles the memory management for you. +// +// You can also search for descriptors within a DescriptorPool by name, and +// extensions by number. +class LIBPROTOBUF_EXPORT DescriptorPool { + public: + // Create a normal, empty DescriptorPool. + DescriptorPool(); + + // Constructs a DescriptorPool that, when it can't find something among the + // descriptors already in the pool, looks for it in the given + // DescriptorDatabase. + // Notes: + // - If a DescriptorPool is constructed this way, its BuildFile*() methods + // must not be called (they will assert-fail). The only way to populate + // the pool with descriptors is to call the Find*By*() methods. + // - The Find*By*() methods may block the calling thread if the + // DescriptorDatabase blocks. This in turn means that parsing messages + // may block if they need to look up extensions. + // - The Find*By*() methods will use mutexes for thread-safety, thus making + // them slower even when they don't have to fall back to the database. + // In fact, even the Find*By*() methods of descriptor objects owned by + // this pool will be slower, since they will have to obtain locks too. + // - An ErrorCollector may optionally be given to collect validation errors + // in files loaded from the database. If not given, errors will be printed + // to GOOGLE_LOG(ERROR). Remember that files are built on-demand, so this + // ErrorCollector may be called from any thread that calls one of the + // Find*By*() methods. + class ErrorCollector; + explicit DescriptorPool(DescriptorDatabase* fallback_database, + ErrorCollector* error_collector = NULL); + + ~DescriptorPool(); + + // Get a pointer to the generated pool. Generated protocol message classes + // which are compiled into the binary will allocate their descriptors in + // this pool. Do not add your own descriptors to this pool. + static const DescriptorPool* generated_pool(); + + // Find a FileDescriptor in the pool by file name. Returns NULL if not + // found. + const FileDescriptor* FindFileByName(const string& name) const; + + // Find the FileDescriptor in the pool which defines the given symbol. + // If any of the Find*ByName() methods below would succeed, then this is + // equivalent to calling that method and calling the result's file() method. + // Otherwise this returns NULL. + const FileDescriptor* FindFileContainingSymbol( + const string& symbol_name) const; + + // Looking up descriptors ------------------------------------------ + // These find descriptors by fully-qualified name. These will find both + // top-level descriptors and nested descriptors. They return NULL if not + // found. + + const Descriptor* FindMessageTypeByName(const string& name) const; + const FieldDescriptor* FindFieldByName(const string& name) const; + const FieldDescriptor* FindExtensionByName(const string& name) const; + const EnumDescriptor* FindEnumTypeByName(const string& name) const; + const EnumValueDescriptor* FindEnumValueByName(const string& name) const; + const ServiceDescriptor* FindServiceByName(const string& name) const; + const MethodDescriptor* FindMethodByName(const string& name) const; + + // Finds an extension of the given type by number. The extendee must be + // a member of this DescriptorPool or one of its underlays. + const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee, + int number) const; + + // Finds extensions of extendee. The extensions will be appended to + // out in an undefined order. Only extensions defined directly in + // this DescriptorPool or one of its underlays are guaranteed to be + // found: extensions defined in the fallback database might not be found + // depending on the database implementation. + void FindAllExtensions(const Descriptor* extendee, + vector* out) const; + + // Building descriptors -------------------------------------------- + + // When converting a FileDescriptorProto to a FileDescriptor, various + // errors might be detected in the input. The caller may handle these + // programmatically by implementing an ErrorCollector. + class LIBPROTOBUF_EXPORT ErrorCollector { + public: + inline ErrorCollector() {} + virtual ~ErrorCollector(); + + // These constants specify what exact part of the construct is broken. + // This is useful e.g. for mapping the error back to an exact location + // in a .proto file. + enum ErrorLocation { + NAME, // the symbol name, or the package name for files + NUMBER, // field or extension range number + TYPE, // field type + EXTENDEE, // field extendee + DEFAULT_VALUE, // field default value + INPUT_TYPE, // method input type + OUTPUT_TYPE, // method output type + OPTION_NAME, // name in assignment + OPTION_VALUE, // value in option assignment + OTHER // some other problem + }; + + // Reports an error in the FileDescriptorProto. + virtual void AddError( + const string& filename, // File name in which the error occurred. + const string& element_name, // Full name of the erroneous element. + const Message* descriptor, // Descriptor of the erroneous element. + ErrorLocation location, // One of the location constants, above. + const string& message // Human-readable error message. + ) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector); + }; + + // Convert the FileDescriptorProto to real descriptors and place them in + // this DescriptorPool. All dependencies of the file must already be in + // the pool. Returns the resulting FileDescriptor, or NULL if there were + // problems with the input (e.g. the message was invalid, or dependencies + // were missing). Details about the errors are written to GOOGLE_LOG(ERROR). + const FileDescriptor* BuildFile(const FileDescriptorProto& proto); + + // Same as BuildFile() except errors are sent to the given ErrorCollector. + const FileDescriptor* BuildFileCollectingErrors( + const FileDescriptorProto& proto, + ErrorCollector* error_collector); + + // By default, it is an error if a FileDescriptorProto contains references + // to types or other files that are not found in the DescriptorPool (or its + // backing DescriptorDatabase, if any). If you call + // AllowUnknownDependencies(), however, then unknown types and files + // will be replaced by placeholder descriptors. This can allow you to + // perform some useful operations with a .proto file even if you do not + // have access to other .proto files on which it depends. However, some + // heuristics must be used to fill in the gaps in information, and these + // can lead to descriptors which are inaccurate. For example, the + // DescriptorPool may be forced to guess whether an unknown type is a message + // or an enum, as well as what package it resides in. Furthermore, + // placeholder types will not be discoverable via FindMessageTypeByName() + // and similar methods, which could confuse some descriptor-based algorithms. + // Generally, the results of this option should only be relied upon for + // debugging purposes. + void AllowUnknownDependencies() { allow_unknown_ = true; } + + // Internal stuff -------------------------------------------------- + // These methods MUST NOT be called from outside the proto2 library. + // These methods may contain hidden pitfalls and may be removed in a + // future library version. + + // Create a DescriptorPool which is overlaid on top of some other pool. + // If you search for a descriptor in the overlay and it is not found, the + // underlay will be searched as a backup. If the underlay has its own + // underlay, that will be searched next, and so on. This also means that + // files built in the overlay will be cross-linked with the underlay's + // descriptors if necessary. The underlay remains property of the caller; + // it must remain valid for the lifetime of the newly-constructed pool. + // + // Example: Say you want to parse a .proto file at runtime in order to use + // its type with a DynamicMessage. Say this .proto file has dependencies, + // but you know that all the dependencies will be things that are already + // compiled into the binary. For ease of use, you'd like to load the types + // right out of generated_pool() rather than have to parse redundant copies + // of all these .protos and runtime. But, you don't want to add the parsed + // types directly into generated_pool(): this is not allowed, and would be + // bad design anyway. So, instead, you could use generated_pool() as an + // underlay for a new DescriptorPool in which you add only the new file. + // + // WARNING: Use of underlays can lead to many subtle gotchas. Instead, + // try to formulate what you want to do in terms of DescriptorDatabases. + explicit DescriptorPool(const DescriptorPool* underlay); + + // Called by generated classes at init time to add their descriptors to + // generated_pool. Do NOT call this in your own code! filename must be a + // permanent string (e.g. a string literal). + static void InternalAddGeneratedFile( + const void* encoded_file_descriptor, int size); + + + // For internal use only: Gets a non-const pointer to the generated pool. + // This is called at static-initialization time only, so thread-safety is + // not a concern. If both an underlay and a fallback database are present, + // the underlay takes precedence. + static DescriptorPool* internal_generated_pool(); + + // For internal use only: Changes the behavior of BuildFile() such that it + // allows the file to make reference to message types declared in other files + // which it did not officially declare as dependencies. + void InternalDontEnforceDependencies(); + + // For internal use only. + void internal_set_underlay(const DescriptorPool* underlay) { + underlay_ = underlay; + } + + // For internal (unit test) use only: Returns true if a FileDescriptor has + // been constructed for the given file, false otherwise. Useful for testing + // lazy descriptor initialization behavior. + bool InternalIsFileLoaded(const string& filename) const; + + private: + friend class Descriptor; + friend class FieldDescriptor; + friend class EnumDescriptor; + friend class ServiceDescriptor; + friend class FileDescriptor; + friend class DescriptorBuilder; + + // Return true if the given name is a sub-symbol of any non-package + // descriptor that already exists in the descriptor pool. (The full + // definition of such types is already known.) + bool IsSubSymbolOfBuiltType(const string& name) const; + + // Tries to find something in the fallback database and link in the + // corresponding proto file. Returns true if successful, in which case + // the caller should search for the thing again. These are declared + // const because they are called by (semantically) const methods. + bool TryFindFileInFallbackDatabase(const string& name) const; + bool TryFindSymbolInFallbackDatabase(const string& name) const; + bool TryFindExtensionInFallbackDatabase(const Descriptor* containing_type, + int field_number) const; + + // Like BuildFile() but called internally when the file has been loaded from + // fallback_database_. Declared const because it is called by (semantically) + // const methods. + const FileDescriptor* BuildFileFromDatabase( + const FileDescriptorProto& proto) const; + + // If fallback_database_ is NULL, this is NULL. Otherwise, this is a mutex + // which must be locked while accessing tables_. + Mutex* mutex_; + + // See constructor. + DescriptorDatabase* fallback_database_; + ErrorCollector* default_error_collector_; + const DescriptorPool* underlay_; + + // This class contains a lot of hash maps with complicated types that + // we'd like to keep out of the header. + class Tables; + scoped_ptr tables_; + + bool enforce_dependencies_; + bool allow_unknown_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool); +}; + +// inline methods ==================================================== + +// These macros makes this repetitive code more readable. +#define PROTOBUF_DEFINE_ACCESSOR(CLASS, FIELD, TYPE) \ + inline TYPE CLASS::FIELD() const { return FIELD##_; } + +// Strings fields are stored as pointers but returned as const references. +#define PROTOBUF_DEFINE_STRING_ACCESSOR(CLASS, FIELD) \ + inline const string& CLASS::FIELD() const { return *FIELD##_; } + +// Arrays take an index parameter, obviously. +#define PROTOBUF_DEFINE_ARRAY_ACCESSOR(CLASS, FIELD, TYPE) \ + inline TYPE CLASS::FIELD(int index) const { return FIELD##s_ + index; } + +#define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \ + inline const TYPE& CLASS::options() const { return *options_; } + +PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, full_name) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*) + +PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int) + +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, field, const FieldDescriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, nested_type, const Descriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, enum_type, const EnumDescriptor*) + +PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_range_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension_range, + const Descriptor::ExtensionRange*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension, + const FieldDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions) + +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name) +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, lowercase_name) +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, camelcase_name) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, type, FieldDescriptor::Type) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, extension_scope, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, message_type, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, enum_type, const EnumDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, experimental_map_key, + const FieldDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32 , int32 ) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64 , int64 ) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32, uint32) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64, uint64) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float , float ) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool , bool ) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_enum, + const EnumValueDescriptor*) +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string) + +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value, + const EnumValueDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions) + +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, full_name) +PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int) +PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions) + +PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, full_name) +PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method, + const MethodDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions) + +PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name) +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, input_type, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, output_type, const Descriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions) +PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, package) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, pool, const DescriptorPool*) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, dependency_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, public_dependency_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, weak_dependency_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions) + +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, enum_type, const EnumDescriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, service, + const ServiceDescriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension, + const FieldDescriptor*) + +#undef PROTOBUF_DEFINE_ACCESSOR +#undef PROTOBUF_DEFINE_STRING_ACCESSOR +#undef PROTOBUF_DEFINE_ARRAY_ACCESSOR + +// A few accessors differ from the macros... + +inline bool FieldDescriptor::is_required() const { + return label() == LABEL_REQUIRED; +} + +inline bool FieldDescriptor::is_optional() const { + return label() == LABEL_OPTIONAL; +} + +inline bool FieldDescriptor::is_repeated() const { + return label() == LABEL_REPEATED; +} + +inline bool FieldDescriptor::is_packable() const { + return is_repeated() && IsTypePackable(type()); +} + +// To save space, index() is computed by looking at the descriptor's position +// in the parent's array of children. +inline int FieldDescriptor::index() const { + if (!is_extension_) { + return this - containing_type_->fields_; + } else if (extension_scope_ != NULL) { + return this - extension_scope_->extensions_; + } else { + return this - file_->extensions_; + } +} + +inline int Descriptor::index() const { + if (containing_type_ == NULL) { + return this - file_->message_types_; + } else { + return this - containing_type_->nested_types_; + } +} + +inline int EnumDescriptor::index() const { + if (containing_type_ == NULL) { + return this - file_->enum_types_; + } else { + return this - containing_type_->enum_types_; + } +} + +inline int EnumValueDescriptor::index() const { + return this - type_->values_; +} + +inline int ServiceDescriptor::index() const { + return this - file_->services_; +} + +inline int MethodDescriptor::index() const { + return this - service_->methods_; +} + +inline const char* FieldDescriptor::type_name() const { + return kTypeToName[type_]; +} + +inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const { + return kTypeToCppTypeMap[type_]; +} + +inline const char* FieldDescriptor::cpp_type_name() const { + return kCppTypeToName[kTypeToCppTypeMap[type_]]; +} + +inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) { + return kTypeToCppTypeMap[type]; +} + +inline bool FieldDescriptor::IsTypePackable(Type field_type) { + return (field_type != FieldDescriptor::TYPE_STRING && + field_type != FieldDescriptor::TYPE_GROUP && + field_type != FieldDescriptor::TYPE_MESSAGE && + field_type != FieldDescriptor::TYPE_BYTES); +} + +inline const FileDescriptor* FileDescriptor::dependency(int index) const { + return dependencies_[index]; +} + +inline const FileDescriptor* FileDescriptor::public_dependency( + int index) const { + return dependencies_[public_dependencies_[index]]; +} + +inline const FileDescriptor* FileDescriptor::weak_dependency( + int index) const { + return dependencies_[weak_dependencies_[index]]; +} + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_DESCRIPTOR_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.pb.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.pb.cc new file mode 100644 index 0000000..65379f4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.pb.cc @@ -0,0 +1,8146 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/descriptor.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/descriptor.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +namespace { + +const ::google::protobuf::Descriptor* FileDescriptorSet_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FileDescriptorSet_reflection_ = NULL; +const ::google::protobuf::Descriptor* FileDescriptorProto_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FileDescriptorProto_reflection_ = NULL; +const ::google::protobuf::Descriptor* DescriptorProto_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + DescriptorProto_reflection_ = NULL; +const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + DescriptorProto_ExtensionRange_reflection_ = NULL; +const ::google::protobuf::Descriptor* FieldDescriptorProto_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FieldDescriptorProto_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor_ = NULL; +const ::google::protobuf::Descriptor* EnumDescriptorProto_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + EnumDescriptorProto_reflection_ = NULL; +const ::google::protobuf::Descriptor* EnumValueDescriptorProto_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + EnumValueDescriptorProto_reflection_ = NULL; +const ::google::protobuf::Descriptor* ServiceDescriptorProto_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ServiceDescriptorProto_reflection_ = NULL; +const ::google::protobuf::Descriptor* MethodDescriptorProto_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + MethodDescriptorProto_reflection_ = NULL; +const ::google::protobuf::Descriptor* FileOptions_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FileOptions_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor_ = NULL; +const ::google::protobuf::Descriptor* MessageOptions_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + MessageOptions_reflection_ = NULL; +const ::google::protobuf::Descriptor* FieldOptions_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FieldOptions_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL; +const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + EnumOptions_reflection_ = NULL; +const ::google::protobuf::Descriptor* EnumValueOptions_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + EnumValueOptions_reflection_ = NULL; +const ::google::protobuf::Descriptor* ServiceOptions_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ServiceOptions_reflection_ = NULL; +const ::google::protobuf::Descriptor* MethodOptions_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + MethodOptions_reflection_ = NULL; +const ::google::protobuf::Descriptor* UninterpretedOption_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + UninterpretedOption_reflection_ = NULL; +const ::google::protobuf::Descriptor* UninterpretedOption_NamePart_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + UninterpretedOption_NamePart_reflection_ = NULL; +const ::google::protobuf::Descriptor* SourceCodeInfo_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + SourceCodeInfo_reflection_ = NULL; +const ::google::protobuf::Descriptor* SourceCodeInfo_Location_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + SourceCodeInfo_Location_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/descriptor.proto"); + GOOGLE_CHECK(file != NULL); + FileDescriptorSet_descriptor_ = file->message_type(0); + static const int FileDescriptorSet_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, file_), + }; + FileDescriptorSet_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FileDescriptorSet_descriptor_, + FileDescriptorSet::default_instance_, + FileDescriptorSet_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FileDescriptorSet)); + FileDescriptorProto_descriptor_ = file->message_type(1); + static const int FileDescriptorProto_offsets_[11] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, public_dependency_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, weak_dependency_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, message_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, enum_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, service_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, extension_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, options_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, source_code_info_), + }; + FileDescriptorProto_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FileDescriptorProto_descriptor_, + FileDescriptorProto::default_instance_, + FileDescriptorProto_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FileDescriptorProto)); + DescriptorProto_descriptor_ = file->message_type(2); + static const int DescriptorProto_offsets_[7] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, field_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, nested_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, enum_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_range_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, options_), + }; + DescriptorProto_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + DescriptorProto_descriptor_, + DescriptorProto::default_instance_, + DescriptorProto_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(DescriptorProto)); + DescriptorProto_ExtensionRange_descriptor_ = DescriptorProto_descriptor_->nested_type(0); + static const int DescriptorProto_ExtensionRange_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_), + }; + DescriptorProto_ExtensionRange_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + DescriptorProto_ExtensionRange_descriptor_, + DescriptorProto_ExtensionRange::default_instance_, + DescriptorProto_ExtensionRange_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(DescriptorProto_ExtensionRange)); + FieldDescriptorProto_descriptor_ = file->message_type(3); + static const int FieldDescriptorProto_offsets_[8] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, label_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, extendee_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, default_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, options_), + }; + FieldDescriptorProto_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FieldDescriptorProto_descriptor_, + FieldDescriptorProto::default_instance_, + FieldDescriptorProto_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FieldDescriptorProto)); + FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0); + FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1); + EnumDescriptorProto_descriptor_ = file->message_type(4); + static const int EnumDescriptorProto_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, options_), + }; + EnumDescriptorProto_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + EnumDescriptorProto_descriptor_, + EnumDescriptorProto::default_instance_, + EnumDescriptorProto_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(EnumDescriptorProto)); + EnumValueDescriptorProto_descriptor_ = file->message_type(5); + static const int EnumValueDescriptorProto_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, options_), + }; + EnumValueDescriptorProto_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + EnumValueDescriptorProto_descriptor_, + EnumValueDescriptorProto::default_instance_, + EnumValueDescriptorProto_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(EnumValueDescriptorProto)); + ServiceDescriptorProto_descriptor_ = file->message_type(6); + static const int ServiceDescriptorProto_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, method_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, options_), + }; + ServiceDescriptorProto_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ServiceDescriptorProto_descriptor_, + ServiceDescriptorProto::default_instance_, + ServiceDescriptorProto_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ServiceDescriptorProto)); + MethodDescriptorProto_descriptor_ = file->message_type(7); + static const int MethodDescriptorProto_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, input_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, output_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, options_), + }; + MethodDescriptorProto_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + MethodDescriptorProto_descriptor_, + MethodDescriptorProto::default_instance_, + MethodDescriptorProto_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(MethodDescriptorProto)); + FileOptions_descriptor_ = file->message_type(8); + static const int FileOptions_offsets_[10] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generate_equals_and_hash_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, optimize_for_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, go_package_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_generic_services_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generic_services_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, py_generic_services_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_), + }; + FileOptions_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FileOptions_descriptor_, + FileOptions::default_instance_, + FileOptions_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _unknown_fields_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _extensions_), + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FileOptions)); + FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0); + MessageOptions_descriptor_ = file->message_type(9); + static const int MessageOptions_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, no_standard_descriptor_accessor_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, uninterpreted_option_), + }; + MessageOptions_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + MessageOptions_descriptor_, + MessageOptions::default_instance_, + MessageOptions_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _unknown_fields_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _extensions_), + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(MessageOptions)); + FieldOptions_descriptor_ = file->message_type(10); + static const int FieldOptions_offsets_[7] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, lazy_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, deprecated_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, experimental_map_key_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, weak_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, uninterpreted_option_), + }; + FieldOptions_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FieldOptions_descriptor_, + FieldOptions::default_instance_, + FieldOptions_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _unknown_fields_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _extensions_), + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FieldOptions)); + FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0); + EnumOptions_descriptor_ = file->message_type(11); + static const int EnumOptions_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, allow_alias_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, uninterpreted_option_), + }; + EnumOptions_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + EnumOptions_descriptor_, + EnumOptions::default_instance_, + EnumOptions_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _unknown_fields_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _extensions_), + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(EnumOptions)); + EnumValueOptions_descriptor_ = file->message_type(12); + static const int EnumValueOptions_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, uninterpreted_option_), + }; + EnumValueOptions_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + EnumValueOptions_descriptor_, + EnumValueOptions::default_instance_, + EnumValueOptions_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _unknown_fields_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _extensions_), + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(EnumValueOptions)); + ServiceOptions_descriptor_ = file->message_type(13); + static const int ServiceOptions_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, uninterpreted_option_), + }; + ServiceOptions_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ServiceOptions_descriptor_, + ServiceOptions::default_instance_, + ServiceOptions_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _unknown_fields_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _extensions_), + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ServiceOptions)); + MethodOptions_descriptor_ = file->message_type(14); + static const int MethodOptions_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, uninterpreted_option_), + }; + MethodOptions_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + MethodOptions_descriptor_, + MethodOptions::default_instance_, + MethodOptions_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _unknown_fields_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _extensions_), + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(MethodOptions)); + UninterpretedOption_descriptor_ = file->message_type(15); + static const int UninterpretedOption_offsets_[7] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, positive_int_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, negative_int_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, double_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, string_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, aggregate_value_), + }; + UninterpretedOption_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + UninterpretedOption_descriptor_, + UninterpretedOption::default_instance_, + UninterpretedOption_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(UninterpretedOption)); + UninterpretedOption_NamePart_descriptor_ = UninterpretedOption_descriptor_->nested_type(0); + static const int UninterpretedOption_NamePart_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, name_part_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, is_extension_), + }; + UninterpretedOption_NamePart_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + UninterpretedOption_NamePart_descriptor_, + UninterpretedOption_NamePart::default_instance_, + UninterpretedOption_NamePart_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(UninterpretedOption_NamePart)); + SourceCodeInfo_descriptor_ = file->message_type(16); + static const int SourceCodeInfo_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_), + }; + SourceCodeInfo_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + SourceCodeInfo_descriptor_, + SourceCodeInfo::default_instance_, + SourceCodeInfo_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(SourceCodeInfo)); + SourceCodeInfo_Location_descriptor_ = SourceCodeInfo_descriptor_->nested_type(0); + static const int SourceCodeInfo_Location_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, span_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, leading_comments_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, trailing_comments_), + }; + SourceCodeInfo_Location_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + SourceCodeInfo_Location_descriptor_, + SourceCodeInfo_Location::default_instance_, + SourceCodeInfo_Location_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(SourceCodeInfo_Location)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FileDescriptorSet_descriptor_, &FileDescriptorSet::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FileDescriptorProto_descriptor_, &FileDescriptorProto::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + DescriptorProto_descriptor_, &DescriptorProto::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + DescriptorProto_ExtensionRange_descriptor_, &DescriptorProto_ExtensionRange::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FieldDescriptorProto_descriptor_, &FieldDescriptorProto::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + EnumDescriptorProto_descriptor_, &EnumDescriptorProto::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + EnumValueDescriptorProto_descriptor_, &EnumValueDescriptorProto::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ServiceDescriptorProto_descriptor_, &ServiceDescriptorProto::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + MethodDescriptorProto_descriptor_, &MethodDescriptorProto::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FileOptions_descriptor_, &FileOptions::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + MessageOptions_descriptor_, &MessageOptions::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FieldOptions_descriptor_, &FieldOptions::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + EnumOptions_descriptor_, &EnumOptions::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + EnumValueOptions_descriptor_, &EnumValueOptions::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ServiceOptions_descriptor_, &ServiceOptions::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + MethodOptions_descriptor_, &MethodOptions::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + UninterpretedOption_descriptor_, &UninterpretedOption::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + UninterpretedOption_NamePart_descriptor_, &UninterpretedOption_NamePart::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + SourceCodeInfo_descriptor_, &SourceCodeInfo::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + SourceCodeInfo_Location_descriptor_, &SourceCodeInfo_Location::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() { + delete FileDescriptorSet::default_instance_; + delete FileDescriptorSet_reflection_; + delete FileDescriptorProto::default_instance_; + delete FileDescriptorProto_reflection_; + delete DescriptorProto::default_instance_; + delete DescriptorProto_reflection_; + delete DescriptorProto_ExtensionRange::default_instance_; + delete DescriptorProto_ExtensionRange_reflection_; + delete FieldDescriptorProto::default_instance_; + delete FieldDescriptorProto_reflection_; + delete EnumDescriptorProto::default_instance_; + delete EnumDescriptorProto_reflection_; + delete EnumValueDescriptorProto::default_instance_; + delete EnumValueDescriptorProto_reflection_; + delete ServiceDescriptorProto::default_instance_; + delete ServiceDescriptorProto_reflection_; + delete MethodDescriptorProto::default_instance_; + delete MethodDescriptorProto_reflection_; + delete FileOptions::default_instance_; + delete FileOptions_reflection_; + delete MessageOptions::default_instance_; + delete MessageOptions_reflection_; + delete FieldOptions::default_instance_; + delete FieldOptions_reflection_; + delete EnumOptions::default_instance_; + delete EnumOptions_reflection_; + delete EnumValueOptions::default_instance_; + delete EnumValueOptions_reflection_; + delete ServiceOptions::default_instance_; + delete ServiceOptions_reflection_; + delete MethodOptions::default_instance_; + delete MethodOptions_reflection_; + delete UninterpretedOption::default_instance_; + delete UninterpretedOption_reflection_; + delete UninterpretedOption_NamePart::default_instance_; + delete UninterpretedOption_NamePart_reflection_; + delete SourceCodeInfo::default_instance_; + delete SourceCodeInfo_reflection_; + delete SourceCodeInfo_Location::default_instance_; + delete SourceCodeInfo_Location_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n google/protobuf/descriptor.proto\022\017goog" + "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file" + "\030\001 \003(\0132$.google.protobuf.FileDescriptorP" + "roto\"\313\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001" + "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022" + "\031\n\021public_dependency\030\n \003(\005\022\027\n\017weak_depen" + "dency\030\013 \003(\005\0226\n\014message_type\030\004 \003(\0132 .goog" + "le.protobuf.DescriptorProto\0227\n\tenum_type" + "\030\005 \003(\0132$.google.protobuf.EnumDescriptorP" + "roto\0228\n\007service\030\006 \003(\0132\'.google.protobuf." + "ServiceDescriptorProto\0228\n\textension\030\007 \003(" + "\0132%.google.protobuf.FieldDescriptorProto" + "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File" + "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog" + "le.protobuf.SourceCodeInfo\"\251\003\n\017Descripto" + "rProto\022\014\n\004name\030\001 \001(\t\0224\n\005field\030\002 \003(\0132%.go" + "ogle.protobuf.FieldDescriptorProto\0228\n\tex" + "tension\030\006 \003(\0132%.google.protobuf.FieldDes" + "criptorProto\0225\n\013nested_type\030\003 \003(\0132 .goog" + "le.protobuf.DescriptorProto\0227\n\tenum_type" + "\030\004 \003(\0132$.google.protobuf.EnumDescriptorP" + "roto\022H\n\017extension_range\030\005 \003(\0132/.google.p" + "rotobuf.DescriptorProto.ExtensionRange\0220" + "\n\007options\030\007 \001(\0132\037.google.protobuf.Messag" + "eOptions\032,\n\016ExtensionRange\022\r\n\005start\030\001 \001(" + "\005\022\013\n\003end\030\002 \001(\005\"\224\005\n\024FieldDescriptorProto\022" + "\014\n\004name\030\001 \001(\t\022\016\n\006number\030\003 \001(\005\022:\n\005label\030\004" + " \001(\0162+.google.protobuf.FieldDescriptorPr" + "oto.Label\0228\n\004type\030\005 \001(\0162*.google.protobu" + "f.FieldDescriptorProto.Type\022\021\n\ttype_name" + "\030\006 \001(\t\022\020\n\010extendee\030\002 \001(\t\022\025\n\rdefault_valu" + "e\030\007 \001(\t\022.\n\007options\030\010 \001(\0132\035.google.protob" + "uf.FieldOptions\"\266\002\n\004Type\022\017\n\013TYPE_DOUBLE\020" + "\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYP" + "E_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED" + "64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n" + "\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_M" + "ESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020" + "\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rT" + "YPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_" + "SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n" + "\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPEATED\020\003\"\214\001" + "\n\023EnumDescriptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005v" + "alue\030\002 \003(\0132).google.protobuf.EnumValueDe" + "scriptorProto\022-\n\007options\030\003 \001(\0132\034.google." + "protobuf.EnumOptions\"l\n\030EnumValueDescrip" + "torProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222" + "\n\007options\030\003 \001(\0132!.google.protobuf.EnumVa" + "lueOptions\"\220\001\n\026ServiceDescriptorProto\022\014\n" + "\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.google.pro" + "tobuf.MethodDescriptorProto\0220\n\007options\030\003" + " \001(\0132\037.google.protobuf.ServiceOptions\"\177\n" + "\025MethodDescriptorProto\022\014\n\004name\030\001 \001(\t\022\022\n\n" + "input_type\030\002 \001(\t\022\023\n\013output_type\030\003 \001(\t\022/\n" + "\007options\030\004 \001(\0132\036.google.protobuf.MethodO" + "ptions\"\351\003\n\013FileOptions\022\024\n\014java_package\030\001" + " \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023ja" + "va_multiple_files\030\n \001(\010:\005false\022,\n\035java_g" + "enerate_equals_and_hash\030\024 \001(\010:\005false\022F\n\014" + "optimize_for\030\t \001(\0162).google.protobuf.Fil" + "eOptions.OptimizeMode:\005SPEED\022\022\n\ngo_packa" + "ge\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005f" + "alse\022$\n\025java_generic_services\030\021 \001(\010:\005fal" + "se\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022C" + "\n\024uninterpreted_option\030\347\007 \003(\0132$.google.p" + "rotobuf.UninterpretedOption\":\n\014OptimizeM" + "ode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RU" + "NTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270\001\n\016MessageOptions\022&\n" + "\027message_set_wire_format\030\001 \001(\010:\005false\022.\n" + "\037no_standard_descriptor_accessor\030\002 \001(\010:\005" + "false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g" + "oogle.protobuf.UninterpretedOption*\t\010\350\007\020" + "\200\200\200\200\002\"\276\002\n\014FieldOptions\022:\n\005ctype\030\001 \001(\0162#." + "google.protobuf.FieldOptions.CType:\006STRI" + "NG\022\016\n\006packed\030\002 \001(\010\022\023\n\004lazy\030\005 \001(\010:\005false\022" + "\031\n\ndeprecated\030\003 \001(\010:\005false\022\034\n\024experiment" + "al_map_key\030\t \001(\t\022\023\n\004weak\030\n \001(\010:\005false\022C\n" + "\024uninterpreted_option\030\347\007 \003(\0132$.google.pr" + "otobuf.UninterpretedOption\"/\n\005CType\022\n\n\006S" + "TRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002*\t\010\350\007" + "\020\200\200\200\200\002\"x\n\013EnumOptions\022\031\n\013allow_alias\030\002 \001" + "(\010:\004true\022C\n\024uninterpreted_option\030\347\007 \003(\0132" + "$.google.protobuf.UninterpretedOption*\t\010" + "\350\007\020\200\200\200\200\002\"b\n\020EnumValueOptions\022C\n\024uninterp" + "reted_option\030\347\007 \003(\0132$.google.protobuf.Un" + "interpretedOption*\t\010\350\007\020\200\200\200\200\002\"`\n\016ServiceO" + "ptions\022C\n\024uninterpreted_option\030\347\007 \003(\0132$." + "google.protobuf.UninterpretedOption*\t\010\350\007" + "\020\200\200\200\200\002\"_\n\rMethodOptions\022C\n\024uninterpreted" + "_option\030\347\007 \003(\0132$.google.protobuf.Uninter" + "pretedOption*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023Uninterprete" + "dOption\022;\n\004name\030\002 \003(\0132-.google.protobuf." + "UninterpretedOption.NamePart\022\030\n\020identifi" + "er_value\030\003 \001(\t\022\032\n\022positive_int_value\030\004 \001" + "(\004\022\032\n\022negative_int_value\030\005 \001(\003\022\024\n\014double" + "_value\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017ag" + "gregate_value\030\010 \001(\t\0323\n\010NamePart\022\021\n\tname_" + "part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\261\001\n\016Sou" + "rceCodeInfo\022:\n\010location\030\001 \003(\0132(.google.p" + "rotobuf.SourceCodeInfo.Location\032c\n\010Locat" + "ion\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022" + "\030\n\020leading_comments\030\003 \001(\t\022\031\n\021trailing_co" + "mments\030\004 \001(\tB)\n\023com.google.protobufB\020Des" + "criptorProtosH\001", 4135); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/descriptor.proto", &protobuf_RegisterTypes); + FileDescriptorSet::default_instance_ = new FileDescriptorSet(); + FileDescriptorProto::default_instance_ = new FileDescriptorProto(); + DescriptorProto::default_instance_ = new DescriptorProto(); + DescriptorProto_ExtensionRange::default_instance_ = new DescriptorProto_ExtensionRange(); + FieldDescriptorProto::default_instance_ = new FieldDescriptorProto(); + EnumDescriptorProto::default_instance_ = new EnumDescriptorProto(); + EnumValueDescriptorProto::default_instance_ = new EnumValueDescriptorProto(); + ServiceDescriptorProto::default_instance_ = new ServiceDescriptorProto(); + MethodDescriptorProto::default_instance_ = new MethodDescriptorProto(); + FileOptions::default_instance_ = new FileOptions(); + MessageOptions::default_instance_ = new MessageOptions(); + FieldOptions::default_instance_ = new FieldOptions(); + EnumOptions::default_instance_ = new EnumOptions(); + EnumValueOptions::default_instance_ = new EnumValueOptions(); + ServiceOptions::default_instance_ = new ServiceOptions(); + MethodOptions::default_instance_ = new MethodOptions(); + UninterpretedOption::default_instance_ = new UninterpretedOption(); + UninterpretedOption_NamePart::default_instance_ = new UninterpretedOption_NamePart(); + SourceCodeInfo::default_instance_ = new SourceCodeInfo(); + SourceCodeInfo_Location::default_instance_ = new SourceCodeInfo_Location(); + FileDescriptorSet::default_instance_->InitAsDefaultInstance(); + FileDescriptorProto::default_instance_->InitAsDefaultInstance(); + DescriptorProto::default_instance_->InitAsDefaultInstance(); + DescriptorProto_ExtensionRange::default_instance_->InitAsDefaultInstance(); + FieldDescriptorProto::default_instance_->InitAsDefaultInstance(); + EnumDescriptorProto::default_instance_->InitAsDefaultInstance(); + EnumValueDescriptorProto::default_instance_->InitAsDefaultInstance(); + ServiceDescriptorProto::default_instance_->InitAsDefaultInstance(); + MethodDescriptorProto::default_instance_->InitAsDefaultInstance(); + FileOptions::default_instance_->InitAsDefaultInstance(); + MessageOptions::default_instance_->InitAsDefaultInstance(); + FieldOptions::default_instance_->InitAsDefaultInstance(); + EnumOptions::default_instance_->InitAsDefaultInstance(); + EnumValueOptions::default_instance_->InitAsDefaultInstance(); + ServiceOptions::default_instance_->InitAsDefaultInstance(); + MethodOptions::default_instance_->InitAsDefaultInstance(); + UninterpretedOption::default_instance_->InitAsDefaultInstance(); + UninterpretedOption_NamePart::default_instance_->InitAsDefaultInstance(); + SourceCodeInfo::default_instance_->InitAsDefaultInstance(); + SourceCodeInfo_Location::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_; + +// =================================================================== + +#ifndef _MSC_VER +const int FileDescriptorSet::kFileFieldNumber; +#endif // !_MSC_VER + +FileDescriptorSet::FileDescriptorSet() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void FileDescriptorSet::InitAsDefaultInstance() { +} + +FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void FileDescriptorSet::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FileDescriptorSet::~FileDescriptorSet() { + SharedDtor(); +} + +void FileDescriptorSet::SharedDtor() { + if (this != default_instance_) { + } +} + +void FileDescriptorSet::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FileDescriptorSet_descriptor_; +} + +const FileDescriptorSet& FileDescriptorSet::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +FileDescriptorSet* FileDescriptorSet::default_instance_ = NULL; + +FileDescriptorSet* FileDescriptorSet::New() const { + return new FileDescriptorSet; +} + +void FileDescriptorSet::Clear() { + file_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FileDescriptorSet::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .google.protobuf.FileDescriptorProto file = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_file())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_file; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void FileDescriptorSet::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .google.protobuf.FileDescriptorProto file = 1; + for (int i = 0; i < this->file_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* FileDescriptorSet::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .google.protobuf.FileDescriptorProto file = 1; + for (int i = 0; i < this->file_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int FileDescriptorSet::ByteSize() const { + int total_size = 0; + + // repeated .google.protobuf.FileDescriptorProto file = 1; + total_size += 1 * this->file_size(); + for (int i = 0; i < this->file_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FileDescriptorSet* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) { + GOOGLE_CHECK_NE(&from, this); + file_.MergeFrom(from.file_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FileDescriptorSet::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FileDescriptorSet::IsInitialized() const { + + for (int i = 0; i < file_size(); i++) { + if (!this->file(i).IsInitialized()) return false; + } + return true; +} + +void FileDescriptorSet::Swap(FileDescriptorSet* other) { + if (other != this) { + file_.Swap(&other->file_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FileDescriptorSet_descriptor_; + metadata.reflection = FileDescriptorSet_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FileDescriptorProto::kNameFieldNumber; +const int FileDescriptorProto::kPackageFieldNumber; +const int FileDescriptorProto::kDependencyFieldNumber; +const int FileDescriptorProto::kPublicDependencyFieldNumber; +const int FileDescriptorProto::kWeakDependencyFieldNumber; +const int FileDescriptorProto::kMessageTypeFieldNumber; +const int FileDescriptorProto::kEnumTypeFieldNumber; +const int FileDescriptorProto::kServiceFieldNumber; +const int FileDescriptorProto::kExtensionFieldNumber; +const int FileDescriptorProto::kOptionsFieldNumber; +const int FileDescriptorProto::kSourceCodeInfoFieldNumber; +#endif // !_MSC_VER + +FileDescriptorProto::FileDescriptorProto() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void FileDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance()); + source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>(&::google::protobuf::SourceCodeInfo::default_instance()); +} + +FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void FileDescriptorProto::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + options_ = NULL; + source_code_info_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FileDescriptorProto::~FileDescriptorProto() { + SharedDtor(); +} + +void FileDescriptorProto::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (package_ != &::google::protobuf::internal::kEmptyString) { + delete package_; + } + if (this != default_instance_) { + delete options_; + delete source_code_info_; + } +} + +void FileDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FileDescriptorProto_descriptor_; +} + +const FileDescriptorProto& FileDescriptorProto::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +FileDescriptorProto* FileDescriptorProto::default_instance_ = NULL; + +FileDescriptorProto* FileDescriptorProto::New() const { + return new FileDescriptorProto; +} + +void FileDescriptorProto::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_package()) { + if (package_ != &::google::protobuf::internal::kEmptyString) { + package_->clear(); + } + } + } + if (_has_bits_[9 / 32] & (0xffu << (9 % 32))) { + if (has_options()) { + if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear(); + } + if (has_source_code_info()) { + if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear(); + } + } + dependency_.Clear(); + public_dependency_.Clear(); + weak_dependency_.Clear(); + message_type_.Clear(); + enum_type_.Clear(); + service_.Clear(); + extension_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FileDescriptorProto::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_package; + break; + } + + // optional string package = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_package: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_package())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->package().data(), this->package().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_dependency; + break; + } + + // repeated string dependency = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_dependency: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_dependency())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dependency(this->dependency_size() - 1).data(), + this->dependency(this->dependency_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_dependency; + if (input->ExpectTag(34)) goto parse_message_type; + break; + } + + // repeated .google.protobuf.DescriptorProto message_type = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_message_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_message_type())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_message_type; + if (input->ExpectTag(42)) goto parse_enum_type; + break; + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_enum_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_enum_type())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_enum_type; + if (input->ExpectTag(50)) goto parse_service; + break; + } + + // repeated .google.protobuf.ServiceDescriptorProto service = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_service: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_service())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(50)) goto parse_service; + if (input->ExpectTag(58)) goto parse_extension; + break; + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_extension: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_extension())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(58)) goto parse_extension; + if (input->ExpectTag(66)) goto parse_options; + break; + } + + // optional .google.protobuf.FileOptions options = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(74)) goto parse_source_code_info; + break; + } + + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + case 9: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_source_code_info: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_source_code_info())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(80)) goto parse_public_dependency; + break; + } + + // repeated int32 public_dependency = 10; + case 10: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_public_dependency: + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + 1, 80, input, this->mutable_public_dependency()))); + } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) + == ::google::protobuf::internal::WireFormatLite:: + WIRETYPE_LENGTH_DELIMITED) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, this->mutable_public_dependency()))); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(80)) goto parse_public_dependency; + if (input->ExpectTag(88)) goto parse_weak_dependency; + break; + } + + // repeated int32 weak_dependency = 11; + case 11: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_weak_dependency: + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + 1, 88, input, this->mutable_weak_dependency()))); + } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) + == ::google::protobuf::internal::WireFormatLite:: + WIRETYPE_LENGTH_DELIMITED) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, this->mutable_weak_dependency()))); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(88)) goto parse_weak_dependency; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void FileDescriptorProto::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // optional string package = 2; + if (has_package()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->package().data(), this->package().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->package(), output); + } + + // repeated string dependency = 3; + for (int i = 0; i < this->dependency_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dependency(i).data(), this->dependency(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->dependency(i), output); + } + + // repeated .google.protobuf.DescriptorProto message_type = 4; + for (int i = 0; i < this->message_type_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, this->message_type(i), output); + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; + for (int i = 0; i < this->enum_type_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 5, this->enum_type(i), output); + } + + // repeated .google.protobuf.ServiceDescriptorProto service = 6; + for (int i = 0; i < this->service_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 6, this->service(i), output); + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 7; + for (int i = 0; i < this->extension_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 7, this->extension(i), output); + } + + // optional .google.protobuf.FileOptions options = 8; + if (has_options()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 8, this->options(), output); + } + + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + if (has_source_code_info()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 9, this->source_code_info(), output); + } + + // repeated int32 public_dependency = 10; + for (int i = 0; i < this->public_dependency_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteInt32( + 10, this->public_dependency(i), output); + } + + // repeated int32 weak_dependency = 11; + for (int i = 0; i < this->weak_dependency_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteInt32( + 11, this->weak_dependency(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* FileDescriptorProto::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional string package = 2; + if (has_package()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->package().data(), this->package().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->package(), target); + } + + // repeated string dependency = 3; + for (int i = 0; i < this->dependency_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dependency(i).data(), this->dependency(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(3, this->dependency(i), target); + } + + // repeated .google.protobuf.DescriptorProto message_type = 4; + for (int i = 0; i < this->message_type_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->message_type(i), target); + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; + for (int i = 0; i < this->enum_type_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 5, this->enum_type(i), target); + } + + // repeated .google.protobuf.ServiceDescriptorProto service = 6; + for (int i = 0; i < this->service_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, this->service(i), target); + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 7; + for (int i = 0; i < this->extension_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 7, this->extension(i), target); + } + + // optional .google.protobuf.FileOptions options = 8; + if (has_options()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 8, this->options(), target); + } + + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + if (has_source_code_info()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 9, this->source_code_info(), target); + } + + // repeated int32 public_dependency = 10; + for (int i = 0; i < this->public_dependency_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32ToArray(10, this->public_dependency(i), target); + } + + // repeated int32 weak_dependency = 11; + for (int i = 0; i < this->weak_dependency_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32ToArray(11, this->weak_dependency(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int FileDescriptorProto::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional string package = 2; + if (has_package()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->package()); + } + + } + if (_has_bits_[9 / 32] & (0xffu << (9 % 32))) { + // optional .google.protobuf.FileOptions options = 8; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options()); + } + + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + if (has_source_code_info()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->source_code_info()); + } + + } + // repeated string dependency = 3; + total_size += 1 * this->dependency_size(); + for (int i = 0; i < this->dependency_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->dependency(i)); + } + + // repeated int32 public_dependency = 10; + { + int data_size = 0; + for (int i = 0; i < this->public_dependency_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + Int32Size(this->public_dependency(i)); + } + total_size += 1 * this->public_dependency_size() + data_size; + } + + // repeated int32 weak_dependency = 11; + { + int data_size = 0; + for (int i = 0; i < this->weak_dependency_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + Int32Size(this->weak_dependency(i)); + } + total_size += 1 * this->weak_dependency_size() + data_size; + } + + // repeated .google.protobuf.DescriptorProto message_type = 4; + total_size += 1 * this->message_type_size(); + for (int i = 0; i < this->message_type_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->message_type(i)); + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; + total_size += 1 * this->enum_type_size(); + for (int i = 0; i < this->enum_type_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->enum_type(i)); + } + + // repeated .google.protobuf.ServiceDescriptorProto service = 6; + total_size += 1 * this->service_size(); + for (int i = 0; i < this->service_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->service(i)); + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 7; + total_size += 1 * this->extension_size(); + for (int i = 0; i < this->extension_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->extension(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FileDescriptorProto* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) { + GOOGLE_CHECK_NE(&from, this); + dependency_.MergeFrom(from.dependency_); + public_dependency_.MergeFrom(from.public_dependency_); + weak_dependency_.MergeFrom(from.weak_dependency_); + message_type_.MergeFrom(from.message_type_); + enum_type_.MergeFrom(from.enum_type_); + service_.MergeFrom(from.service_); + extension_.MergeFrom(from.extension_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_package()) { + set_package(from.package()); + } + } + if (from._has_bits_[9 / 32] & (0xffu << (9 % 32))) { + if (from.has_options()) { + mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options()); + } + if (from.has_source_code_info()) { + mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom(from.source_code_info()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FileDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FileDescriptorProto::IsInitialized() const { + + for (int i = 0; i < message_type_size(); i++) { + if (!this->message_type(i).IsInitialized()) return false; + } + for (int i = 0; i < enum_type_size(); i++) { + if (!this->enum_type(i).IsInitialized()) return false; + } + for (int i = 0; i < service_size(); i++) { + if (!this->service(i).IsInitialized()) return false; + } + for (int i = 0; i < extension_size(); i++) { + if (!this->extension(i).IsInitialized()) return false; + } + if (has_options()) { + if (!this->options().IsInitialized()) return false; + } + return true; +} + +void FileDescriptorProto::Swap(FileDescriptorProto* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(package_, other->package_); + dependency_.Swap(&other->dependency_); + public_dependency_.Swap(&other->public_dependency_); + weak_dependency_.Swap(&other->weak_dependency_); + message_type_.Swap(&other->message_type_); + enum_type_.Swap(&other->enum_type_); + service_.Swap(&other->service_); + extension_.Swap(&other->extension_); + std::swap(options_, other->options_); + std::swap(source_code_info_, other->source_code_info_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FileDescriptorProto_descriptor_; + metadata.reflection = FileDescriptorProto_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int DescriptorProto_ExtensionRange::kStartFieldNumber; +const int DescriptorProto_ExtensionRange::kEndFieldNumber; +#endif // !_MSC_VER + +DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void DescriptorProto_ExtensionRange::InitAsDefaultInstance() { +} + +DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void DescriptorProto_ExtensionRange::SharedCtor() { + _cached_size_ = 0; + start_ = 0; + end_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() { + SharedDtor(); +} + +void DescriptorProto_ExtensionRange::SharedDtor() { + if (this != default_instance_) { + } +} + +void DescriptorProto_ExtensionRange::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() { + protobuf_AssignDescriptorsOnce(); + return DescriptorProto_ExtensionRange_descriptor_; +} + +const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::default_instance_ = NULL; + +DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::New() const { + return new DescriptorProto_ExtensionRange; +} + +void DescriptorProto_ExtensionRange::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + start_ = 0; + end_ = 0; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional int32 start = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &start_))); + set_has_start(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_end; + break; + } + + // optional int32 end = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_end: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &end_))); + set_has_end(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional int32 start = 1; + if (has_start()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output); + } + + // optional int32 end = 2; + if (has_end()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional int32 start = 1; + if (has_start()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target); + } + + // optional int32 end = 2; + if (has_end()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int DescriptorProto_ExtensionRange::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional int32 start = 1; + if (has_start()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->start()); + } + + // optional int32 end = 2; + if (has_end()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->end()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const DescriptorProto_ExtensionRange* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_start()) { + set_start(from.start()); + } + if (from.has_end()) { + set_end(from.end()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void DescriptorProto_ExtensionRange::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRange& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DescriptorProto_ExtensionRange::IsInitialized() const { + + return true; +} + +void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other) { + if (other != this) { + std::swap(start_, other->start_); + std::swap(end_, other->end_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = DescriptorProto_ExtensionRange_descriptor_; + metadata.reflection = DescriptorProto_ExtensionRange_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#ifndef _MSC_VER +const int DescriptorProto::kNameFieldNumber; +const int DescriptorProto::kFieldFieldNumber; +const int DescriptorProto::kExtensionFieldNumber; +const int DescriptorProto::kNestedTypeFieldNumber; +const int DescriptorProto::kEnumTypeFieldNumber; +const int DescriptorProto::kExtensionRangeFieldNumber; +const int DescriptorProto::kOptionsFieldNumber; +#endif // !_MSC_VER + +DescriptorProto::DescriptorProto() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void DescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::MessageOptions*>(&::google::protobuf::MessageOptions::default_instance()); +} + +DescriptorProto::DescriptorProto(const DescriptorProto& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void DescriptorProto::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + options_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +DescriptorProto::~DescriptorProto() { + SharedDtor(); +} + +void DescriptorProto::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + delete options_; + } +} + +void DescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* DescriptorProto::descriptor() { + protobuf_AssignDescriptorsOnce(); + return DescriptorProto_descriptor_; +} + +const DescriptorProto& DescriptorProto::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +DescriptorProto* DescriptorProto::default_instance_ = NULL; + +DescriptorProto* DescriptorProto::New() const { + return new DescriptorProto; +} + +void DescriptorProto::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_options()) { + if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear(); + } + } + field_.Clear(); + extension_.Clear(); + nested_type_.Clear(); + enum_type_.Clear(); + extension_range_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool DescriptorProto::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_field; + break; + } + + // repeated .google.protobuf.FieldDescriptorProto field = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_field: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_field())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_field; + if (input->ExpectTag(26)) goto parse_nested_type; + break; + } + + // repeated .google.protobuf.DescriptorProto nested_type = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_nested_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_nested_type())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_nested_type; + if (input->ExpectTag(34)) goto parse_enum_type; + break; + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_enum_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_enum_type())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_enum_type; + if (input->ExpectTag(42)) goto parse_extension_range; + break; + } + + // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_extension_range: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_extension_range())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_extension_range; + if (input->ExpectTag(50)) goto parse_extension; + break; + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_extension: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_extension())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(50)) goto parse_extension; + if (input->ExpectTag(58)) goto parse_options; + break; + } + + // optional .google.protobuf.MessageOptions options = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void DescriptorProto::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // repeated .google.protobuf.FieldDescriptorProto field = 2; + for (int i = 0; i < this->field_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->field(i), output); + } + + // repeated .google.protobuf.DescriptorProto nested_type = 3; + for (int i = 0; i < this->nested_type_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->nested_type(i), output); + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; + for (int i = 0; i < this->enum_type_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, this->enum_type(i), output); + } + + // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; + for (int i = 0; i < this->extension_range_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 5, this->extension_range(i), output); + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + for (int i = 0; i < this->extension_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 6, this->extension(i), output); + } + + // optional .google.protobuf.MessageOptions options = 7; + if (has_options()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 7, this->options(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* DescriptorProto::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // repeated .google.protobuf.FieldDescriptorProto field = 2; + for (int i = 0; i < this->field_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->field(i), target); + } + + // repeated .google.protobuf.DescriptorProto nested_type = 3; + for (int i = 0; i < this->nested_type_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->nested_type(i), target); + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; + for (int i = 0; i < this->enum_type_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->enum_type(i), target); + } + + // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; + for (int i = 0; i < this->extension_range_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 5, this->extension_range(i), target); + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + for (int i = 0; i < this->extension_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, this->extension(i), target); + } + + // optional .google.protobuf.MessageOptions options = 7; + if (has_options()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 7, this->options(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int DescriptorProto::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional .google.protobuf.MessageOptions options = 7; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options()); + } + + } + // repeated .google.protobuf.FieldDescriptorProto field = 2; + total_size += 1 * this->field_size(); + for (int i = 0; i < this->field_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->field(i)); + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + total_size += 1 * this->extension_size(); + for (int i = 0; i < this->extension_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->extension(i)); + } + + // repeated .google.protobuf.DescriptorProto nested_type = 3; + total_size += 1 * this->nested_type_size(); + for (int i = 0; i < this->nested_type_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->nested_type(i)); + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; + total_size += 1 * this->enum_type_size(); + for (int i = 0; i < this->enum_type_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->enum_type(i)); + } + + // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; + total_size += 1 * this->extension_range_size(); + for (int i = 0; i < this->extension_range_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->extension_range(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const DescriptorProto* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void DescriptorProto::MergeFrom(const DescriptorProto& from) { + GOOGLE_CHECK_NE(&from, this); + field_.MergeFrom(from.field_); + extension_.MergeFrom(from.extension_); + nested_type_.MergeFrom(from.nested_type_); + enum_type_.MergeFrom(from.enum_type_); + extension_range_.MergeFrom(from.extension_range_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_options()) { + mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void DescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void DescriptorProto::CopyFrom(const DescriptorProto& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DescriptorProto::IsInitialized() const { + + for (int i = 0; i < field_size(); i++) { + if (!this->field(i).IsInitialized()) return false; + } + for (int i = 0; i < extension_size(); i++) { + if (!this->extension(i).IsInitialized()) return false; + } + for (int i = 0; i < nested_type_size(); i++) { + if (!this->nested_type(i).IsInitialized()) return false; + } + for (int i = 0; i < enum_type_size(); i++) { + if (!this->enum_type(i).IsInitialized()) return false; + } + if (has_options()) { + if (!this->options().IsInitialized()) return false; + } + return true; +} + +void DescriptorProto::Swap(DescriptorProto* other) { + if (other != this) { + std::swap(name_, other->name_); + field_.Swap(&other->field_); + extension_.Swap(&other->extension_); + nested_type_.Swap(&other->nested_type_); + enum_type_.Swap(&other->enum_type_); + extension_range_.Swap(&other->extension_range_); + std::swap(options_, other->options_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata DescriptorProto::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = DescriptorProto_descriptor_; + metadata.reflection = DescriptorProto_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor() { + protobuf_AssignDescriptorsOnce(); + return FieldDescriptorProto_Type_descriptor_; +} +bool FieldDescriptorProto_Type_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32; +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64; +const FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN; +const FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX; +const int FieldDescriptorProto::Type_ARRAYSIZE; +#endif // _MSC_VER +const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() { + protobuf_AssignDescriptorsOnce(); + return FieldDescriptorProto_Label_descriptor_; +} +bool FieldDescriptorProto_Label_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL; +const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED; +const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED; +const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN; +const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX; +const int FieldDescriptorProto::Label_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int FieldDescriptorProto::kNameFieldNumber; +const int FieldDescriptorProto::kNumberFieldNumber; +const int FieldDescriptorProto::kLabelFieldNumber; +const int FieldDescriptorProto::kTypeFieldNumber; +const int FieldDescriptorProto::kTypeNameFieldNumber; +const int FieldDescriptorProto::kExtendeeFieldNumber; +const int FieldDescriptorProto::kDefaultValueFieldNumber; +const int FieldDescriptorProto::kOptionsFieldNumber; +#endif // !_MSC_VER + +FieldDescriptorProto::FieldDescriptorProto() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void FieldDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::FieldOptions*>(&::google::protobuf::FieldOptions::default_instance()); +} + +FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void FieldDescriptorProto::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + number_ = 0; + label_ = 1; + type_ = 1; + type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + options_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FieldDescriptorProto::~FieldDescriptorProto() { + SharedDtor(); +} + +void FieldDescriptorProto::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (type_name_ != &::google::protobuf::internal::kEmptyString) { + delete type_name_; + } + if (extendee_ != &::google::protobuf::internal::kEmptyString) { + delete extendee_; + } + if (default_value_ != &::google::protobuf::internal::kEmptyString) { + delete default_value_; + } + if (this != default_instance_) { + delete options_; + } +} + +void FieldDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FieldDescriptorProto_descriptor_; +} + +const FieldDescriptorProto& FieldDescriptorProto::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +FieldDescriptorProto* FieldDescriptorProto::default_instance_ = NULL; + +FieldDescriptorProto* FieldDescriptorProto::New() const { + return new FieldDescriptorProto; +} + +void FieldDescriptorProto::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + number_ = 0; + label_ = 1; + type_ = 1; + if (has_type_name()) { + if (type_name_ != &::google::protobuf::internal::kEmptyString) { + type_name_->clear(); + } + } + if (has_extendee()) { + if (extendee_ != &::google::protobuf::internal::kEmptyString) { + extendee_->clear(); + } + } + if (has_default_value()) { + if (default_value_ != &::google::protobuf::internal::kEmptyString) { + default_value_->clear(); + } + } + if (has_options()) { + if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FieldDescriptorProto::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_extendee; + break; + } + + // optional string extendee = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_extendee: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_extendee())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->extendee().data(), this->extendee().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(24)) goto parse_number; + break; + } + + // optional int32 number = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &number_))); + set_has_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(32)) goto parse_label; + break; + } + + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_label: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) { + set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value)); + } else { + mutable_unknown_fields()->AddVarint(4, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(40)) goto parse_type; + break; + } + + // optional .google.protobuf.FieldDescriptorProto.Type type = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_type: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) { + set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value)); + } else { + mutable_unknown_fields()->AddVarint(5, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(50)) goto parse_type_name; + break; + } + + // optional string type_name = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_type_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_type_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->type_name().data(), this->type_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(58)) goto parse_default_value; + break; + } + + // optional string default_value = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_default_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_default_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->default_value().data(), this->default_value().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(66)) goto parse_options; + break; + } + + // optional .google.protobuf.FieldOptions options = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void FieldDescriptorProto::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // optional string extendee = 2; + if (has_extendee()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->extendee().data(), this->extendee().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->extendee(), output); + } + + // optional int32 number = 3; + if (has_number()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output); + } + + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + if (has_label()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 4, this->label(), output); + } + + // optional .google.protobuf.FieldDescriptorProto.Type type = 5; + if (has_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 5, this->type(), output); + } + + // optional string type_name = 6; + if (has_type_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->type_name().data(), this->type_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 6, this->type_name(), output); + } + + // optional string default_value = 7; + if (has_default_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->default_value().data(), this->default_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 7, this->default_value(), output); + } + + // optional .google.protobuf.FieldOptions options = 8; + if (has_options()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 8, this->options(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* FieldDescriptorProto::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional string extendee = 2; + if (has_extendee()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->extendee().data(), this->extendee().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->extendee(), target); + } + + // optional int32 number = 3; + if (has_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target); + } + + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + if (has_label()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 4, this->label(), target); + } + + // optional .google.protobuf.FieldDescriptorProto.Type type = 5; + if (has_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 5, this->type(), target); + } + + // optional string type_name = 6; + if (has_type_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->type_name().data(), this->type_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 6, this->type_name(), target); + } + + // optional string default_value = 7; + if (has_default_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->default_value().data(), this->default_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 7, this->default_value(), target); + } + + // optional .google.protobuf.FieldOptions options = 8; + if (has_options()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 8, this->options(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int FieldDescriptorProto::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional int32 number = 3; + if (has_number()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->number()); + } + + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + if (has_label()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->label()); + } + + // optional .google.protobuf.FieldDescriptorProto.Type type = 5; + if (has_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); + } + + // optional string type_name = 6; + if (has_type_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->type_name()); + } + + // optional string extendee = 2; + if (has_extendee()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->extendee()); + } + + // optional string default_value = 7; + if (has_default_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->default_value()); + } + + // optional .google.protobuf.FieldOptions options = 8; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FieldDescriptorProto* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_number()) { + set_number(from.number()); + } + if (from.has_label()) { + set_label(from.label()); + } + if (from.has_type()) { + set_type(from.type()); + } + if (from.has_type_name()) { + set_type_name(from.type_name()); + } + if (from.has_extendee()) { + set_extendee(from.extendee()); + } + if (from.has_default_value()) { + set_default_value(from.default_value()); + } + if (from.has_options()) { + mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FieldDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FieldDescriptorProto::IsInitialized() const { + + if (has_options()) { + if (!this->options().IsInitialized()) return false; + } + return true; +} + +void FieldDescriptorProto::Swap(FieldDescriptorProto* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(number_, other->number_); + std::swap(label_, other->label_); + std::swap(type_, other->type_); + std::swap(type_name_, other->type_name_); + std::swap(extendee_, other->extendee_); + std::swap(default_value_, other->default_value_); + std::swap(options_, other->options_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FieldDescriptorProto_descriptor_; + metadata.reflection = FieldDescriptorProto_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int EnumDescriptorProto::kNameFieldNumber; +const int EnumDescriptorProto::kValueFieldNumber; +const int EnumDescriptorProto::kOptionsFieldNumber; +#endif // !_MSC_VER + +EnumDescriptorProto::EnumDescriptorProto() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void EnumDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::EnumOptions*>(&::google::protobuf::EnumOptions::default_instance()); +} + +EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void EnumDescriptorProto::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + options_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +EnumDescriptorProto::~EnumDescriptorProto() { + SharedDtor(); +} + +void EnumDescriptorProto::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + delete options_; + } +} + +void EnumDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() { + protobuf_AssignDescriptorsOnce(); + return EnumDescriptorProto_descriptor_; +} + +const EnumDescriptorProto& EnumDescriptorProto::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +EnumDescriptorProto* EnumDescriptorProto::default_instance_ = NULL; + +EnumDescriptorProto* EnumDescriptorProto::New() const { + return new EnumDescriptorProto; +} + +void EnumDescriptorProto::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_options()) { + if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear(); + } + } + value_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool EnumDescriptorProto::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_value; + break; + } + + // repeated .google.protobuf.EnumValueDescriptorProto value = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_value())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_value; + if (input->ExpectTag(26)) goto parse_options; + break; + } + + // optional .google.protobuf.EnumOptions options = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void EnumDescriptorProto::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // repeated .google.protobuf.EnumValueDescriptorProto value = 2; + for (int i = 0; i < this->value_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->value(i), output); + } + + // optional .google.protobuf.EnumOptions options = 3; + if (has_options()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->options(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* EnumDescriptorProto::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // repeated .google.protobuf.EnumValueDescriptorProto value = 2; + for (int i = 0; i < this->value_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->value(i), target); + } + + // optional .google.protobuf.EnumOptions options = 3; + if (has_options()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->options(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int EnumDescriptorProto::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional .google.protobuf.EnumOptions options = 3; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options()); + } + + } + // repeated .google.protobuf.EnumValueDescriptorProto value = 2; + total_size += 1 * this->value_size(); + for (int i = 0; i < this->value_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->value(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const EnumDescriptorProto* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) { + GOOGLE_CHECK_NE(&from, this); + value_.MergeFrom(from.value_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_options()) { + mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void EnumDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EnumDescriptorProto::IsInitialized() const { + + for (int i = 0; i < value_size(); i++) { + if (!this->value(i).IsInitialized()) return false; + } + if (has_options()) { + if (!this->options().IsInitialized()) return false; + } + return true; +} + +void EnumDescriptorProto::Swap(EnumDescriptorProto* other) { + if (other != this) { + std::swap(name_, other->name_); + value_.Swap(&other->value_); + std::swap(options_, other->options_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = EnumDescriptorProto_descriptor_; + metadata.reflection = EnumDescriptorProto_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int EnumValueDescriptorProto::kNameFieldNumber; +const int EnumValueDescriptorProto::kNumberFieldNumber; +const int EnumValueDescriptorProto::kOptionsFieldNumber; +#endif // !_MSC_VER + +EnumValueDescriptorProto::EnumValueDescriptorProto() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void EnumValueDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::EnumValueOptions*>(&::google::protobuf::EnumValueOptions::default_instance()); +} + +EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void EnumValueDescriptorProto::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + number_ = 0; + options_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +EnumValueDescriptorProto::~EnumValueDescriptorProto() { + SharedDtor(); +} + +void EnumValueDescriptorProto::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + delete options_; + } +} + +void EnumValueDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() { + protobuf_AssignDescriptorsOnce(); + return EnumValueDescriptorProto_descriptor_; +} + +const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +EnumValueDescriptorProto* EnumValueDescriptorProto::default_instance_ = NULL; + +EnumValueDescriptorProto* EnumValueDescriptorProto::New() const { + return new EnumValueDescriptorProto; +} + +void EnumValueDescriptorProto::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + number_ = 0; + if (has_options()) { + if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool EnumValueDescriptorProto::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_number; + break; + } + + // optional int32 number = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &number_))); + set_has_number(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_options; + break; + } + + // optional .google.protobuf.EnumValueOptions options = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void EnumValueDescriptorProto::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // optional int32 number = 2; + if (has_number()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output); + } + + // optional .google.protobuf.EnumValueOptions options = 3; + if (has_options()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->options(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* EnumValueDescriptorProto::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional int32 number = 2; + if (has_number()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target); + } + + // optional .google.protobuf.EnumValueOptions options = 3; + if (has_options()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->options(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int EnumValueDescriptorProto::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional int32 number = 2; + if (has_number()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->number()); + } + + // optional .google.protobuf.EnumValueOptions options = 3; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const EnumValueDescriptorProto* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_number()) { + set_number(from.number()); + } + if (from.has_options()) { + mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void EnumValueDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EnumValueDescriptorProto::IsInitialized() const { + + if (has_options()) { + if (!this->options().IsInitialized()) return false; + } + return true; +} + +void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(number_, other->number_); + std::swap(options_, other->options_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = EnumValueDescriptorProto_descriptor_; + metadata.reflection = EnumValueDescriptorProto_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ServiceDescriptorProto::kNameFieldNumber; +const int ServiceDescriptorProto::kMethodFieldNumber; +const int ServiceDescriptorProto::kOptionsFieldNumber; +#endif // !_MSC_VER + +ServiceDescriptorProto::ServiceDescriptorProto() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ServiceDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::ServiceOptions*>(&::google::protobuf::ServiceOptions::default_instance()); +} + +ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ServiceDescriptorProto::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + options_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ServiceDescriptorProto::~ServiceDescriptorProto() { + SharedDtor(); +} + +void ServiceDescriptorProto::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + delete options_; + } +} + +void ServiceDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServiceDescriptorProto_descriptor_; +} + +const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +ServiceDescriptorProto* ServiceDescriptorProto::default_instance_ = NULL; + +ServiceDescriptorProto* ServiceDescriptorProto::New() const { + return new ServiceDescriptorProto; +} + +void ServiceDescriptorProto::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_options()) { + if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear(); + } + } + method_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ServiceDescriptorProto::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_method; + break; + } + + // repeated .google.protobuf.MethodDescriptorProto method = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_method: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_method())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_method; + if (input->ExpectTag(26)) goto parse_options; + break; + } + + // optional .google.protobuf.ServiceOptions options = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ServiceDescriptorProto::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // repeated .google.protobuf.MethodDescriptorProto method = 2; + for (int i = 0; i < this->method_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->method(i), output); + } + + // optional .google.protobuf.ServiceOptions options = 3; + if (has_options()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->options(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ServiceDescriptorProto::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // repeated .google.protobuf.MethodDescriptorProto method = 2; + for (int i = 0; i < this->method_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->method(i), target); + } + + // optional .google.protobuf.ServiceOptions options = 3; + if (has_options()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->options(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ServiceDescriptorProto::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional .google.protobuf.ServiceOptions options = 3; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options()); + } + + } + // repeated .google.protobuf.MethodDescriptorProto method = 2; + total_size += 1 * this->method_size(); + for (int i = 0; i < this->method_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->method(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ServiceDescriptorProto* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) { + GOOGLE_CHECK_NE(&from, this); + method_.MergeFrom(from.method_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_options()) { + mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ServiceDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServiceDescriptorProto::IsInitialized() const { + + for (int i = 0; i < method_size(); i++) { + if (!this->method(i).IsInitialized()) return false; + } + if (has_options()) { + if (!this->options().IsInitialized()) return false; + } + return true; +} + +void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) { + if (other != this) { + std::swap(name_, other->name_); + method_.Swap(&other->method_); + std::swap(options_, other->options_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServiceDescriptorProto_descriptor_; + metadata.reflection = ServiceDescriptorProto_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int MethodDescriptorProto::kNameFieldNumber; +const int MethodDescriptorProto::kInputTypeFieldNumber; +const int MethodDescriptorProto::kOutputTypeFieldNumber; +const int MethodDescriptorProto::kOptionsFieldNumber; +#endif // !_MSC_VER + +MethodDescriptorProto::MethodDescriptorProto() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void MethodDescriptorProto::InitAsDefaultInstance() { + options_ = const_cast< ::google::protobuf::MethodOptions*>(&::google::protobuf::MethodOptions::default_instance()); +} + +MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void MethodDescriptorProto::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + options_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +MethodDescriptorProto::~MethodDescriptorProto() { + SharedDtor(); +} + +void MethodDescriptorProto::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (input_type_ != &::google::protobuf::internal::kEmptyString) { + delete input_type_; + } + if (output_type_ != &::google::protobuf::internal::kEmptyString) { + delete output_type_; + } + if (this != default_instance_) { + delete options_; + } +} + +void MethodDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() { + protobuf_AssignDescriptorsOnce(); + return MethodDescriptorProto_descriptor_; +} + +const MethodDescriptorProto& MethodDescriptorProto::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +MethodDescriptorProto* MethodDescriptorProto::default_instance_ = NULL; + +MethodDescriptorProto* MethodDescriptorProto::New() const { + return new MethodDescriptorProto; +} + +void MethodDescriptorProto::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_input_type()) { + if (input_type_ != &::google::protobuf::internal::kEmptyString) { + input_type_->clear(); + } + } + if (has_output_type()) { + if (output_type_ != &::google::protobuf::internal::kEmptyString) { + output_type_->clear(); + } + } + if (has_options()) { + if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool MethodDescriptorProto::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_input_type; + break; + } + + // optional string input_type = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_input_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_input_type())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->input_type().data(), this->input_type().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_output_type; + break; + } + + // optional string output_type = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_output_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_output_type())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->output_type().data(), this->output_type().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_options; + break; + } + + // optional .google.protobuf.MethodOptions options = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void MethodDescriptorProto::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // optional string input_type = 2; + if (has_input_type()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->input_type().data(), this->input_type().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->input_type(), output); + } + + // optional string output_type = 3; + if (has_output_type()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->output_type().data(), this->output_type().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->output_type(), output); + } + + // optional .google.protobuf.MethodOptions options = 4; + if (has_options()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, this->options(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* MethodDescriptorProto::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional string input_type = 2; + if (has_input_type()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->input_type().data(), this->input_type().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->input_type(), target); + } + + // optional string output_type = 3; + if (has_output_type()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->output_type().data(), this->output_type().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->output_type(), target); + } + + // optional .google.protobuf.MethodOptions options = 4; + if (has_options()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->options(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int MethodDescriptorProto::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional string input_type = 2; + if (has_input_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->input_type()); + } + + // optional string output_type = 3; + if (has_output_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->output_type()); + } + + // optional .google.protobuf.MethodOptions options = 4; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const MethodDescriptorProto* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_input_type()) { + set_input_type(from.input_type()); + } + if (from.has_output_type()) { + set_output_type(from.output_type()); + } + if (from.has_options()) { + mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void MethodDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MethodDescriptorProto::IsInitialized() const { + + if (has_options()) { + if (!this->options().IsInitialized()) return false; + } + return true; +} + +void MethodDescriptorProto::Swap(MethodDescriptorProto* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(input_type_, other->input_type_); + std::swap(output_type_, other->output_type_); + std::swap(options_, other->options_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = MethodDescriptorProto_descriptor_; + metadata.reflection = MethodDescriptorProto_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() { + protobuf_AssignDescriptorsOnce(); + return FileOptions_OptimizeMode_descriptor_; +} +bool FileOptions_OptimizeMode_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const FileOptions_OptimizeMode FileOptions::SPEED; +const FileOptions_OptimizeMode FileOptions::CODE_SIZE; +const FileOptions_OptimizeMode FileOptions::LITE_RUNTIME; +const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN; +const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX; +const int FileOptions::OptimizeMode_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int FileOptions::kJavaPackageFieldNumber; +const int FileOptions::kJavaOuterClassnameFieldNumber; +const int FileOptions::kJavaMultipleFilesFieldNumber; +const int FileOptions::kJavaGenerateEqualsAndHashFieldNumber; +const int FileOptions::kOptimizeForFieldNumber; +const int FileOptions::kGoPackageFieldNumber; +const int FileOptions::kCcGenericServicesFieldNumber; +const int FileOptions::kJavaGenericServicesFieldNumber; +const int FileOptions::kPyGenericServicesFieldNumber; +const int FileOptions::kUninterpretedOptionFieldNumber; +#endif // !_MSC_VER + +FileOptions::FileOptions() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void FileOptions::InitAsDefaultInstance() { +} + +FileOptions::FileOptions(const FileOptions& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void FileOptions::SharedCtor() { + _cached_size_ = 0; + java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + java_multiple_files_ = false; + java_generate_equals_and_hash_ = false; + optimize_for_ = 1; + go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + cc_generic_services_ = false; + java_generic_services_ = false; + py_generic_services_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FileOptions::~FileOptions() { + SharedDtor(); +} + +void FileOptions::SharedDtor() { + if (java_package_ != &::google::protobuf::internal::kEmptyString) { + delete java_package_; + } + if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) { + delete java_outer_classname_; + } + if (go_package_ != &::google::protobuf::internal::kEmptyString) { + delete go_package_; + } + if (this != default_instance_) { + } +} + +void FileOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FileOptions::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FileOptions_descriptor_; +} + +const FileOptions& FileOptions::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +FileOptions* FileOptions::default_instance_ = NULL; + +FileOptions* FileOptions::New() const { + return new FileOptions; +} + +void FileOptions::Clear() { + _extensions_.Clear(); + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_java_package()) { + if (java_package_ != &::google::protobuf::internal::kEmptyString) { + java_package_->clear(); + } + } + if (has_java_outer_classname()) { + if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) { + java_outer_classname_->clear(); + } + } + java_multiple_files_ = false; + java_generate_equals_and_hash_ = false; + optimize_for_ = 1; + if (has_go_package()) { + if (go_package_ != &::google::protobuf::internal::kEmptyString) { + go_package_->clear(); + } + } + cc_generic_services_ = false; + java_generic_services_ = false; + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + py_generic_services_ = false; + } + uninterpreted_option_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FileOptions::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string java_package = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_java_package())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_package().data(), this->java_package().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(66)) goto parse_java_outer_classname; + break; + } + + // optional string java_outer_classname = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_java_outer_classname: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_java_outer_classname())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_outer_classname().data(), this->java_outer_classname().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(72)) goto parse_optimize_for; + break; + } + + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; + case 9: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_optimize_for: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) { + set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value)); + } else { + mutable_unknown_fields()->AddVarint(9, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(80)) goto parse_java_multiple_files; + break; + } + + // optional bool java_multiple_files = 10 [default = false]; + case 10: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_java_multiple_files: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &java_multiple_files_))); + set_has_java_multiple_files(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(90)) goto parse_go_package; + break; + } + + // optional string go_package = 11; + case 11: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_go_package: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_go_package())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->go_package().data(), this->go_package().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(128)) goto parse_cc_generic_services; + break; + } + + // optional bool cc_generic_services = 16 [default = false]; + case 16: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_cc_generic_services: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &cc_generic_services_))); + set_has_cc_generic_services(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(136)) goto parse_java_generic_services; + break; + } + + // optional bool java_generic_services = 17 [default = false]; + case 17: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_java_generic_services: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &java_generic_services_))); + set_has_java_generic_services(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(144)) goto parse_py_generic_services; + break; + } + + // optional bool py_generic_services = 18 [default = false]; + case 18: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_py_generic_services: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &py_generic_services_))); + set_has_py_generic_services(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(160)) goto parse_java_generate_equals_and_hash; + break; + } + + // optional bool java_generate_equals_and_hash = 20 [default = false]; + case 20: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_java_generate_equals_and_hash: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &java_generate_equals_and_hash_))); + set_has_java_generate_equals_and_hash(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + break; + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + if ((8000u <= tag)) { + DO_(_extensions_.ParseField(tag, input, default_instance_, + mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void FileOptions::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string java_package = 1; + if (has_java_package()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_package().data(), this->java_package().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->java_package(), output); + } + + // optional string java_outer_classname = 8; + if (has_java_outer_classname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_outer_classname().data(), this->java_outer_classname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 8, this->java_outer_classname(), output); + } + + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; + if (has_optimize_for()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 9, this->optimize_for(), output); + } + + // optional bool java_multiple_files = 10 [default = false]; + if (has_java_multiple_files()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output); + } + + // optional string go_package = 11; + if (has_go_package()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->go_package().data(), this->go_package().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 11, this->go_package(), output); + } + + // optional bool cc_generic_services = 16 [default = false]; + if (has_cc_generic_services()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output); + } + + // optional bool java_generic_services = 17 [default = false]; + if (has_java_generic_services()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output); + } + + // optional bool py_generic_services = 18 [default = false]; + if (has_py_generic_services()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output); + } + + // optional bool java_generate_equals_and_hash = 20 [default = false]; + if (has_java_generate_equals_and_hash()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 999, this->uninterpreted_option(i), output); + } + + // Extension range [1000, 536870912) + _extensions_.SerializeWithCachedSizes( + 1000, 536870912, output); + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* FileOptions::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string java_package = 1; + if (has_java_package()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_package().data(), this->java_package().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->java_package(), target); + } + + // optional string java_outer_classname = 8; + if (has_java_outer_classname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_outer_classname().data(), this->java_outer_classname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 8, this->java_outer_classname(), target); + } + + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; + if (has_optimize_for()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 9, this->optimize_for(), target); + } + + // optional bool java_multiple_files = 10 [default = false]; + if (has_java_multiple_files()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target); + } + + // optional string go_package = 11; + if (has_go_package()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->go_package().data(), this->go_package().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 11, this->go_package(), target); + } + + // optional bool cc_generic_services = 16 [default = false]; + if (has_cc_generic_services()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target); + } + + // optional bool java_generic_services = 17 [default = false]; + if (has_java_generic_services()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target); + } + + // optional bool py_generic_services = 18 [default = false]; + if (has_py_generic_services()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target); + } + + // optional bool java_generate_equals_and_hash = 20 [default = false]; + if (has_java_generate_equals_and_hash()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); + } + + // Extension range [1000, 536870912) + target = _extensions_.SerializeWithCachedSizesToArray( + 1000, 536870912, target); + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int FileOptions::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string java_package = 1; + if (has_java_package()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->java_package()); + } + + // optional string java_outer_classname = 8; + if (has_java_outer_classname()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->java_outer_classname()); + } + + // optional bool java_multiple_files = 10 [default = false]; + if (has_java_multiple_files()) { + total_size += 1 + 1; + } + + // optional bool java_generate_equals_and_hash = 20 [default = false]; + if (has_java_generate_equals_and_hash()) { + total_size += 2 + 1; + } + + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; + if (has_optimize_for()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for()); + } + + // optional string go_package = 11; + if (has_go_package()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->go_package()); + } + + // optional bool cc_generic_services = 16 [default = false]; + if (has_cc_generic_services()) { + total_size += 2 + 1; + } + + // optional bool java_generic_services = 17 [default = false]; + if (has_java_generic_services()) { + total_size += 2 + 1; + } + + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // optional bool py_generic_services = 18 [default = false]; + if (has_py_generic_services()) { + total_size += 2 + 1; + } + + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2 * this->uninterpreted_option_size(); + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->uninterpreted_option(i)); + } + + total_size += _extensions_.ByteSize(); + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FileOptions::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FileOptions* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FileOptions::MergeFrom(const FileOptions& from) { + GOOGLE_CHECK_NE(&from, this); + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_java_package()) { + set_java_package(from.java_package()); + } + if (from.has_java_outer_classname()) { + set_java_outer_classname(from.java_outer_classname()); + } + if (from.has_java_multiple_files()) { + set_java_multiple_files(from.java_multiple_files()); + } + if (from.has_java_generate_equals_and_hash()) { + set_java_generate_equals_and_hash(from.java_generate_equals_and_hash()); + } + if (from.has_optimize_for()) { + set_optimize_for(from.optimize_for()); + } + if (from.has_go_package()) { + set_go_package(from.go_package()); + } + if (from.has_cc_generic_services()) { + set_cc_generic_services(from.cc_generic_services()); + } + if (from.has_java_generic_services()) { + set_java_generic_services(from.java_generic_services()); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_py_generic_services()) { + set_py_generic_services(from.py_generic_services()); + } + } + _extensions_.MergeFrom(from._extensions_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FileOptions::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FileOptions::CopyFrom(const FileOptions& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FileOptions::IsInitialized() const { + + for (int i = 0; i < uninterpreted_option_size(); i++) { + if (!this->uninterpreted_option(i).IsInitialized()) return false; + } + + if (!_extensions_.IsInitialized()) return false; return true; +} + +void FileOptions::Swap(FileOptions* other) { + if (other != this) { + std::swap(java_package_, other->java_package_); + std::swap(java_outer_classname_, other->java_outer_classname_); + std::swap(java_multiple_files_, other->java_multiple_files_); + std::swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_); + std::swap(optimize_for_, other->optimize_for_); + std::swap(go_package_, other->go_package_); + std::swap(cc_generic_services_, other->cc_generic_services_); + std::swap(java_generic_services_, other->java_generic_services_); + std::swap(py_generic_services_, other->py_generic_services_); + uninterpreted_option_.Swap(&other->uninterpreted_option_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); + } +} + +::google::protobuf::Metadata FileOptions::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FileOptions_descriptor_; + metadata.reflection = FileOptions_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int MessageOptions::kMessageSetWireFormatFieldNumber; +const int MessageOptions::kNoStandardDescriptorAccessorFieldNumber; +const int MessageOptions::kUninterpretedOptionFieldNumber; +#endif // !_MSC_VER + +MessageOptions::MessageOptions() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void MessageOptions::InitAsDefaultInstance() { +} + +MessageOptions::MessageOptions(const MessageOptions& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void MessageOptions::SharedCtor() { + _cached_size_ = 0; + message_set_wire_format_ = false; + no_standard_descriptor_accessor_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +MessageOptions::~MessageOptions() { + SharedDtor(); +} + +void MessageOptions::SharedDtor() { + if (this != default_instance_) { + } +} + +void MessageOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* MessageOptions::descriptor() { + protobuf_AssignDescriptorsOnce(); + return MessageOptions_descriptor_; +} + +const MessageOptions& MessageOptions::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +MessageOptions* MessageOptions::default_instance_ = NULL; + +MessageOptions* MessageOptions::New() const { + return new MessageOptions; +} + +void MessageOptions::Clear() { + _extensions_.Clear(); + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + message_set_wire_format_ = false; + no_standard_descriptor_accessor_ = false; + } + uninterpreted_option_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool MessageOptions::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional bool message_set_wire_format = 1 [default = false]; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &message_set_wire_format_))); + set_has_message_set_wire_format(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_no_standard_descriptor_accessor; + break; + } + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_no_standard_descriptor_accessor: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &no_standard_descriptor_accessor_))); + set_has_no_standard_descriptor_accessor(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + break; + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + if ((8000u <= tag)) { + DO_(_extensions_.ParseField(tag, input, default_instance_, + mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void MessageOptions::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional bool message_set_wire_format = 1 [default = false]; + if (has_message_set_wire_format()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output); + } + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + if (has_no_standard_descriptor_accessor()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 999, this->uninterpreted_option(i), output); + } + + // Extension range [1000, 536870912) + _extensions_.SerializeWithCachedSizes( + 1000, 536870912, output); + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* MessageOptions::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional bool message_set_wire_format = 1 [default = false]; + if (has_message_set_wire_format()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target); + } + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + if (has_no_standard_descriptor_accessor()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); + } + + // Extension range [1000, 536870912) + target = _extensions_.SerializeWithCachedSizesToArray( + 1000, 536870912, target); + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int MessageOptions::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional bool message_set_wire_format = 1 [default = false]; + if (has_message_set_wire_format()) { + total_size += 1 + 1; + } + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + if (has_no_standard_descriptor_accessor()) { + total_size += 1 + 1; + } + + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2 * this->uninterpreted_option_size(); + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->uninterpreted_option(i)); + } + + total_size += _extensions_.ByteSize(); + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const MessageOptions* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void MessageOptions::MergeFrom(const MessageOptions& from) { + GOOGLE_CHECK_NE(&from, this); + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_message_set_wire_format()) { + set_message_set_wire_format(from.message_set_wire_format()); + } + if (from.has_no_standard_descriptor_accessor()) { + set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor()); + } + } + _extensions_.MergeFrom(from._extensions_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void MessageOptions::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void MessageOptions::CopyFrom(const MessageOptions& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MessageOptions::IsInitialized() const { + + for (int i = 0; i < uninterpreted_option_size(); i++) { + if (!this->uninterpreted_option(i).IsInitialized()) return false; + } + + if (!_extensions_.IsInitialized()) return false; return true; +} + +void MessageOptions::Swap(MessageOptions* other) { + if (other != this) { + std::swap(message_set_wire_format_, other->message_set_wire_format_); + std::swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_); + uninterpreted_option_.Swap(&other->uninterpreted_option_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); + } +} + +::google::protobuf::Metadata MessageOptions::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = MessageOptions_descriptor_; + metadata.reflection = MessageOptions_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return FieldOptions_CType_descriptor_; +} +bool FieldOptions_CType_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const FieldOptions_CType FieldOptions::STRING; +const FieldOptions_CType FieldOptions::CORD; +const FieldOptions_CType FieldOptions::STRING_PIECE; +const FieldOptions_CType FieldOptions::CType_MIN; +const FieldOptions_CType FieldOptions::CType_MAX; +const int FieldOptions::CType_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int FieldOptions::kCtypeFieldNumber; +const int FieldOptions::kPackedFieldNumber; +const int FieldOptions::kLazyFieldNumber; +const int FieldOptions::kDeprecatedFieldNumber; +const int FieldOptions::kExperimentalMapKeyFieldNumber; +const int FieldOptions::kWeakFieldNumber; +const int FieldOptions::kUninterpretedOptionFieldNumber; +#endif // !_MSC_VER + +FieldOptions::FieldOptions() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void FieldOptions::InitAsDefaultInstance() { +} + +FieldOptions::FieldOptions(const FieldOptions& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void FieldOptions::SharedCtor() { + _cached_size_ = 0; + ctype_ = 0; + packed_ = false; + lazy_ = false; + deprecated_ = false; + experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + weak_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FieldOptions::~FieldOptions() { + SharedDtor(); +} + +void FieldOptions::SharedDtor() { + if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) { + delete experimental_map_key_; + } + if (this != default_instance_) { + } +} + +void FieldOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FieldOptions::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FieldOptions_descriptor_; +} + +const FieldOptions& FieldOptions::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +FieldOptions* FieldOptions::default_instance_ = NULL; + +FieldOptions* FieldOptions::New() const { + return new FieldOptions; +} + +void FieldOptions::Clear() { + _extensions_.Clear(); + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + ctype_ = 0; + packed_ = false; + lazy_ = false; + deprecated_ = false; + if (has_experimental_map_key()) { + if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) { + experimental_map_key_->clear(); + } + } + weak_ = false; + } + uninterpreted_option_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FieldOptions::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::google::protobuf::FieldOptions_CType_IsValid(value)) { + set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_packed; + break; + } + + // optional bool packed = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_packed: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &packed_))); + set_has_packed(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(24)) goto parse_deprecated; + break; + } + + // optional bool deprecated = 3 [default = false]; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_deprecated: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &deprecated_))); + set_has_deprecated(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(40)) goto parse_lazy; + break; + } + + // optional bool lazy = 5 [default = false]; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_lazy: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &lazy_))); + set_has_lazy(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(74)) goto parse_experimental_map_key; + break; + } + + // optional string experimental_map_key = 9; + case 9: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_experimental_map_key: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_experimental_map_key())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->experimental_map_key().data(), this->experimental_map_key().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(80)) goto parse_weak; + break; + } + + // optional bool weak = 10 [default = false]; + case 10: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_weak: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &weak_))); + set_has_weak(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + break; + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + if ((8000u <= tag)) { + DO_(_extensions_.ParseField(tag, input, default_instance_, + mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void FieldOptions::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; + if (has_ctype()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->ctype(), output); + } + + // optional bool packed = 2; + if (has_packed()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output); + } + + // optional bool deprecated = 3 [default = false]; + if (has_deprecated()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output); + } + + // optional bool lazy = 5 [default = false]; + if (has_lazy()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->lazy(), output); + } + + // optional string experimental_map_key = 9; + if (has_experimental_map_key()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->experimental_map_key().data(), this->experimental_map_key().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 9, this->experimental_map_key(), output); + } + + // optional bool weak = 10 [default = false]; + if (has_weak()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->weak(), output); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 999, this->uninterpreted_option(i), output); + } + + // Extension range [1000, 536870912) + _extensions_.SerializeWithCachedSizes( + 1000, 536870912, output); + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; + if (has_ctype()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->ctype(), target); + } + + // optional bool packed = 2; + if (has_packed()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target); + } + + // optional bool deprecated = 3 [default = false]; + if (has_deprecated()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target); + } + + // optional bool lazy = 5 [default = false]; + if (has_lazy()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->lazy(), target); + } + + // optional string experimental_map_key = 9; + if (has_experimental_map_key()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->experimental_map_key().data(), this->experimental_map_key().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 9, this->experimental_map_key(), target); + } + + // optional bool weak = 10 [default = false]; + if (has_weak()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->weak(), target); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); + } + + // Extension range [1000, 536870912) + target = _extensions_.SerializeWithCachedSizesToArray( + 1000, 536870912, target); + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int FieldOptions::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; + if (has_ctype()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype()); + } + + // optional bool packed = 2; + if (has_packed()) { + total_size += 1 + 1; + } + + // optional bool lazy = 5 [default = false]; + if (has_lazy()) { + total_size += 1 + 1; + } + + // optional bool deprecated = 3 [default = false]; + if (has_deprecated()) { + total_size += 1 + 1; + } + + // optional string experimental_map_key = 9; + if (has_experimental_map_key()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->experimental_map_key()); + } + + // optional bool weak = 10 [default = false]; + if (has_weak()) { + total_size += 1 + 1; + } + + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2 * this->uninterpreted_option_size(); + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->uninterpreted_option(i)); + } + + total_size += _extensions_.ByteSize(); + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FieldOptions* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FieldOptions::MergeFrom(const FieldOptions& from) { + GOOGLE_CHECK_NE(&from, this); + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_ctype()) { + set_ctype(from.ctype()); + } + if (from.has_packed()) { + set_packed(from.packed()); + } + if (from.has_lazy()) { + set_lazy(from.lazy()); + } + if (from.has_deprecated()) { + set_deprecated(from.deprecated()); + } + if (from.has_experimental_map_key()) { + set_experimental_map_key(from.experimental_map_key()); + } + if (from.has_weak()) { + set_weak(from.weak()); + } + } + _extensions_.MergeFrom(from._extensions_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FieldOptions::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FieldOptions::CopyFrom(const FieldOptions& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FieldOptions::IsInitialized() const { + + for (int i = 0; i < uninterpreted_option_size(); i++) { + if (!this->uninterpreted_option(i).IsInitialized()) return false; + } + + if (!_extensions_.IsInitialized()) return false; return true; +} + +void FieldOptions::Swap(FieldOptions* other) { + if (other != this) { + std::swap(ctype_, other->ctype_); + std::swap(packed_, other->packed_); + std::swap(lazy_, other->lazy_); + std::swap(deprecated_, other->deprecated_); + std::swap(experimental_map_key_, other->experimental_map_key_); + std::swap(weak_, other->weak_); + uninterpreted_option_.Swap(&other->uninterpreted_option_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); + } +} + +::google::protobuf::Metadata FieldOptions::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FieldOptions_descriptor_; + metadata.reflection = FieldOptions_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int EnumOptions::kAllowAliasFieldNumber; +const int EnumOptions::kUninterpretedOptionFieldNumber; +#endif // !_MSC_VER + +EnumOptions::EnumOptions() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void EnumOptions::InitAsDefaultInstance() { +} + +EnumOptions::EnumOptions(const EnumOptions& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void EnumOptions::SharedCtor() { + _cached_size_ = 0; + allow_alias_ = true; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +EnumOptions::~EnumOptions() { + SharedDtor(); +} + +void EnumOptions::SharedDtor() { + if (this != default_instance_) { + } +} + +void EnumOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* EnumOptions::descriptor() { + protobuf_AssignDescriptorsOnce(); + return EnumOptions_descriptor_; +} + +const EnumOptions& EnumOptions::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +EnumOptions* EnumOptions::default_instance_ = NULL; + +EnumOptions* EnumOptions::New() const { + return new EnumOptions; +} + +void EnumOptions::Clear() { + _extensions_.Clear(); + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + allow_alias_ = true; + } + uninterpreted_option_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool EnumOptions::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional bool allow_alias = 2 [default = true]; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &allow_alias_))); + set_has_allow_alias(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + break; + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + if ((8000u <= tag)) { + DO_(_extensions_.ParseField(tag, input, default_instance_, + mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void EnumOptions::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional bool allow_alias = 2 [default = true]; + if (has_allow_alias()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->allow_alias(), output); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 999, this->uninterpreted_option(i), output); + } + + // Extension range [1000, 536870912) + _extensions_.SerializeWithCachedSizes( + 1000, 536870912, output); + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* EnumOptions::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional bool allow_alias = 2 [default = true]; + if (has_allow_alias()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->allow_alias(), target); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); + } + + // Extension range [1000, 536870912) + target = _extensions_.SerializeWithCachedSizesToArray( + 1000, 536870912, target); + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int EnumOptions::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional bool allow_alias = 2 [default = true]; + if (has_allow_alias()) { + total_size += 1 + 1; + } + + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2 * this->uninterpreted_option_size(); + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->uninterpreted_option(i)); + } + + total_size += _extensions_.ByteSize(); + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const EnumOptions* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void EnumOptions::MergeFrom(const EnumOptions& from) { + GOOGLE_CHECK_NE(&from, this); + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_allow_alias()) { + set_allow_alias(from.allow_alias()); + } + } + _extensions_.MergeFrom(from._extensions_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void EnumOptions::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void EnumOptions::CopyFrom(const EnumOptions& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EnumOptions::IsInitialized() const { + + for (int i = 0; i < uninterpreted_option_size(); i++) { + if (!this->uninterpreted_option(i).IsInitialized()) return false; + } + + if (!_extensions_.IsInitialized()) return false; return true; +} + +void EnumOptions::Swap(EnumOptions* other) { + if (other != this) { + std::swap(allow_alias_, other->allow_alias_); + uninterpreted_option_.Swap(&other->uninterpreted_option_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); + } +} + +::google::protobuf::Metadata EnumOptions::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = EnumOptions_descriptor_; + metadata.reflection = EnumOptions_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int EnumValueOptions::kUninterpretedOptionFieldNumber; +#endif // !_MSC_VER + +EnumValueOptions::EnumValueOptions() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void EnumValueOptions::InitAsDefaultInstance() { +} + +EnumValueOptions::EnumValueOptions(const EnumValueOptions& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void EnumValueOptions::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +EnumValueOptions::~EnumValueOptions() { + SharedDtor(); +} + +void EnumValueOptions::SharedDtor() { + if (this != default_instance_) { + } +} + +void EnumValueOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() { + protobuf_AssignDescriptorsOnce(); + return EnumValueOptions_descriptor_; +} + +const EnumValueOptions& EnumValueOptions::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +EnumValueOptions* EnumValueOptions::default_instance_ = NULL; + +EnumValueOptions* EnumValueOptions::New() const { + return new EnumValueOptions; +} + +void EnumValueOptions::Clear() { + _extensions_.Clear(); + uninterpreted_option_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool EnumValueOptions::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + if ((8000u <= tag)) { + DO_(_extensions_.ParseField(tag, input, default_instance_, + mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void EnumValueOptions::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 999, this->uninterpreted_option(i), output); + } + + // Extension range [1000, 536870912) + _extensions_.SerializeWithCachedSizes( + 1000, 536870912, output); + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* EnumValueOptions::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); + } + + // Extension range [1000, 536870912) + target = _extensions_.SerializeWithCachedSizesToArray( + 1000, 536870912, target); + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int EnumValueOptions::ByteSize() const { + int total_size = 0; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2 * this->uninterpreted_option_size(); + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->uninterpreted_option(i)); + } + + total_size += _extensions_.ByteSize(); + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const EnumValueOptions* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void EnumValueOptions::MergeFrom(const EnumValueOptions& from) { + GOOGLE_CHECK_NE(&from, this); + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + _extensions_.MergeFrom(from._extensions_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void EnumValueOptions::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void EnumValueOptions::CopyFrom(const EnumValueOptions& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EnumValueOptions::IsInitialized() const { + + for (int i = 0; i < uninterpreted_option_size(); i++) { + if (!this->uninterpreted_option(i).IsInitialized()) return false; + } + + if (!_extensions_.IsInitialized()) return false; return true; +} + +void EnumValueOptions::Swap(EnumValueOptions* other) { + if (other != this) { + uninterpreted_option_.Swap(&other->uninterpreted_option_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); + } +} + +::google::protobuf::Metadata EnumValueOptions::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = EnumValueOptions_descriptor_; + metadata.reflection = EnumValueOptions_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ServiceOptions::kUninterpretedOptionFieldNumber; +#endif // !_MSC_VER + +ServiceOptions::ServiceOptions() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ServiceOptions::InitAsDefaultInstance() { +} + +ServiceOptions::ServiceOptions(const ServiceOptions& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ServiceOptions::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ServiceOptions::~ServiceOptions() { + SharedDtor(); +} + +void ServiceOptions::SharedDtor() { + if (this != default_instance_) { + } +} + +void ServiceOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ServiceOptions::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ServiceOptions_descriptor_; +} + +const ServiceOptions& ServiceOptions::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +ServiceOptions* ServiceOptions::default_instance_ = NULL; + +ServiceOptions* ServiceOptions::New() const { + return new ServiceOptions; +} + +void ServiceOptions::Clear() { + _extensions_.Clear(); + uninterpreted_option_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ServiceOptions::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + if ((8000u <= tag)) { + DO_(_extensions_.ParseField(tag, input, default_instance_, + mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ServiceOptions::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 999, this->uninterpreted_option(i), output); + } + + // Extension range [1000, 536870912) + _extensions_.SerializeWithCachedSizes( + 1000, 536870912, output); + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ServiceOptions::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); + } + + // Extension range [1000, 536870912) + target = _extensions_.SerializeWithCachedSizesToArray( + 1000, 536870912, target); + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ServiceOptions::ByteSize() const { + int total_size = 0; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2 * this->uninterpreted_option_size(); + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->uninterpreted_option(i)); + } + + total_size += _extensions_.ByteSize(); + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ServiceOptions* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ServiceOptions::MergeFrom(const ServiceOptions& from) { + GOOGLE_CHECK_NE(&from, this); + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + _extensions_.MergeFrom(from._extensions_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ServiceOptions::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ServiceOptions::CopyFrom(const ServiceOptions& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServiceOptions::IsInitialized() const { + + for (int i = 0; i < uninterpreted_option_size(); i++) { + if (!this->uninterpreted_option(i).IsInitialized()) return false; + } + + if (!_extensions_.IsInitialized()) return false; return true; +} + +void ServiceOptions::Swap(ServiceOptions* other) { + if (other != this) { + uninterpreted_option_.Swap(&other->uninterpreted_option_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); + } +} + +::google::protobuf::Metadata ServiceOptions::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ServiceOptions_descriptor_; + metadata.reflection = ServiceOptions_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int MethodOptions::kUninterpretedOptionFieldNumber; +#endif // !_MSC_VER + +MethodOptions::MethodOptions() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void MethodOptions::InitAsDefaultInstance() { +} + +MethodOptions::MethodOptions(const MethodOptions& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void MethodOptions::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +MethodOptions::~MethodOptions() { + SharedDtor(); +} + +void MethodOptions::SharedDtor() { + if (this != default_instance_) { + } +} + +void MethodOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* MethodOptions::descriptor() { + protobuf_AssignDescriptorsOnce(); + return MethodOptions_descriptor_; +} + +const MethodOptions& MethodOptions::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +MethodOptions* MethodOptions::default_instance_ = NULL; + +MethodOptions* MethodOptions::New() const { + return new MethodOptions; +} + +void MethodOptions::Clear() { + _extensions_.Clear(); + uninterpreted_option_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool MethodOptions::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + if ((8000u <= tag)) { + DO_(_extensions_.ParseField(tag, input, default_instance_, + mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void MethodOptions::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 999, this->uninterpreted_option(i), output); + } + + // Extension range [1000, 536870912) + _extensions_.SerializeWithCachedSizes( + 1000, 536870912, output); + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* MethodOptions::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(i), target); + } + + // Extension range [1000, 536870912) + target = _extensions_.SerializeWithCachedSizesToArray( + 1000, 536870912, target); + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int MethodOptions::ByteSize() const { + int total_size = 0; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2 * this->uninterpreted_option_size(); + for (int i = 0; i < this->uninterpreted_option_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->uninterpreted_option(i)); + } + + total_size += _extensions_.ByteSize(); + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const MethodOptions* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void MethodOptions::MergeFrom(const MethodOptions& from) { + GOOGLE_CHECK_NE(&from, this); + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + _extensions_.MergeFrom(from._extensions_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void MethodOptions::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void MethodOptions::CopyFrom(const MethodOptions& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MethodOptions::IsInitialized() const { + + for (int i = 0; i < uninterpreted_option_size(); i++) { + if (!this->uninterpreted_option(i).IsInitialized()) return false; + } + + if (!_extensions_.IsInitialized()) return false; return true; +} + +void MethodOptions::Swap(MethodOptions* other) { + if (other != this) { + uninterpreted_option_.Swap(&other->uninterpreted_option_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); + } +} + +::google::protobuf::Metadata MethodOptions::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = MethodOptions_descriptor_; + metadata.reflection = MethodOptions_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int UninterpretedOption_NamePart::kNamePartFieldNumber; +const int UninterpretedOption_NamePart::kIsExtensionFieldNumber; +#endif // !_MSC_VER + +UninterpretedOption_NamePart::UninterpretedOption_NamePart() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void UninterpretedOption_NamePart::InitAsDefaultInstance() { +} + +UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void UninterpretedOption_NamePart::SharedCtor() { + _cached_size_ = 0; + name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + is_extension_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +UninterpretedOption_NamePart::~UninterpretedOption_NamePart() { + SharedDtor(); +} + +void UninterpretedOption_NamePart::SharedDtor() { + if (name_part_ != &::google::protobuf::internal::kEmptyString) { + delete name_part_; + } + if (this != default_instance_) { + } +} + +void UninterpretedOption_NamePart::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor() { + protobuf_AssignDescriptorsOnce(); + return UninterpretedOption_NamePart_descriptor_; +} + +const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +UninterpretedOption_NamePart* UninterpretedOption_NamePart::default_instance_ = NULL; + +UninterpretedOption_NamePart* UninterpretedOption_NamePart::New() const { + return new UninterpretedOption_NamePart; +} + +void UninterpretedOption_NamePart::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name_part()) { + if (name_part_ != &::google::protobuf::internal::kEmptyString) { + name_part_->clear(); + } + } + is_extension_ = false; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool UninterpretedOption_NamePart::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string name_part = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name_part())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name_part().data(), this->name_part().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_is_extension; + break; + } + + // required bool is_extension = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_is_extension: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &is_extension_))); + set_has_is_extension(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void UninterpretedOption_NamePart::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string name_part = 1; + if (has_name_part()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name_part().data(), this->name_part().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name_part(), output); + } + + // required bool is_extension = 2; + if (has_is_extension()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* UninterpretedOption_NamePart::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string name_part = 1; + if (has_name_part()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name_part().data(), this->name_part().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name_part(), target); + } + + // required bool is_extension = 2; + if (has_is_extension()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int UninterpretedOption_NamePart::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string name_part = 1; + if (has_name_part()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name_part()); + } + + // required bool is_extension = 2; + if (has_is_extension()) { + total_size += 1 + 1; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const UninterpretedOption_NamePart* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name_part()) { + set_name_part(from.name_part()); + } + if (from.has_is_extension()) { + set_is_extension(from.is_extension()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void UninterpretedOption_NamePart::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool UninterpretedOption_NamePart::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) { + if (other != this) { + std::swap(name_part_, other->name_part_); + std::swap(is_extension_, other->is_extension_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = UninterpretedOption_NamePart_descriptor_; + metadata.reflection = UninterpretedOption_NamePart_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#ifndef _MSC_VER +const int UninterpretedOption::kNameFieldNumber; +const int UninterpretedOption::kIdentifierValueFieldNumber; +const int UninterpretedOption::kPositiveIntValueFieldNumber; +const int UninterpretedOption::kNegativeIntValueFieldNumber; +const int UninterpretedOption::kDoubleValueFieldNumber; +const int UninterpretedOption::kStringValueFieldNumber; +const int UninterpretedOption::kAggregateValueFieldNumber; +#endif // !_MSC_VER + +UninterpretedOption::UninterpretedOption() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void UninterpretedOption::InitAsDefaultInstance() { +} + +UninterpretedOption::UninterpretedOption(const UninterpretedOption& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void UninterpretedOption::SharedCtor() { + _cached_size_ = 0; + identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + positive_int_value_ = GOOGLE_ULONGLONG(0); + negative_int_value_ = GOOGLE_LONGLONG(0); + double_value_ = 0; + string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +UninterpretedOption::~UninterpretedOption() { + SharedDtor(); +} + +void UninterpretedOption::SharedDtor() { + if (identifier_value_ != &::google::protobuf::internal::kEmptyString) { + delete identifier_value_; + } + if (string_value_ != &::google::protobuf::internal::kEmptyString) { + delete string_value_; + } + if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) { + delete aggregate_value_; + } + if (this != default_instance_) { + } +} + +void UninterpretedOption::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() { + protobuf_AssignDescriptorsOnce(); + return UninterpretedOption_descriptor_; +} + +const UninterpretedOption& UninterpretedOption::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +UninterpretedOption* UninterpretedOption::default_instance_ = NULL; + +UninterpretedOption* UninterpretedOption::New() const { + return new UninterpretedOption; +} + +void UninterpretedOption::Clear() { + if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { + if (has_identifier_value()) { + if (identifier_value_ != &::google::protobuf::internal::kEmptyString) { + identifier_value_->clear(); + } + } + positive_int_value_ = GOOGLE_ULONGLONG(0); + negative_int_value_ = GOOGLE_LONGLONG(0); + double_value_ = 0; + if (has_string_value()) { + if (string_value_ != &::google::protobuf::internal::kEmptyString) { + string_value_->clear(); + } + } + if (has_aggregate_value()) { + if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) { + aggregate_value_->clear(); + } + } + } + name_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool UninterpretedOption::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_name())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_name; + if (input->ExpectTag(26)) goto parse_identifier_value; + break; + } + + // optional string identifier_value = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_identifier_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_identifier_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->identifier_value().data(), this->identifier_value().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(32)) goto parse_positive_int_value; + break; + } + + // optional uint64 positive_int_value = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_positive_int_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &positive_int_value_))); + set_has_positive_int_value(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(40)) goto parse_negative_int_value; + break; + } + + // optional int64 negative_int_value = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_negative_int_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &negative_int_value_))); + set_has_negative_int_value(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(49)) goto parse_double_value; + break; + } + + // optional double double_value = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_double_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &double_value_))); + set_has_double_value(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(58)) goto parse_string_value; + break; + } + + // optional bytes string_value = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_string_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_string_value())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(66)) goto parse_aggregate_value; + break; + } + + // optional string aggregate_value = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_aggregate_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_aggregate_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->aggregate_value().data(), this->aggregate_value().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void UninterpretedOption::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; + for (int i = 0; i < this->name_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->name(i), output); + } + + // optional string identifier_value = 3; + if (has_identifier_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->identifier_value().data(), this->identifier_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->identifier_value(), output); + } + + // optional uint64 positive_int_value = 4; + if (has_positive_int_value()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output); + } + + // optional int64 negative_int_value = 5; + if (has_negative_int_value()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output); + } + + // optional double double_value = 6; + if (has_double_value()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output); + } + + // optional bytes string_value = 7; + if (has_string_value()) { + ::google::protobuf::internal::WireFormatLite::WriteBytes( + 7, this->string_value(), output); + } + + // optional string aggregate_value = 8; + if (has_aggregate_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->aggregate_value().data(), this->aggregate_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 8, this->aggregate_value(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* UninterpretedOption::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; + for (int i = 0; i < this->name_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->name(i), target); + } + + // optional string identifier_value = 3; + if (has_identifier_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->identifier_value().data(), this->identifier_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->identifier_value(), target); + } + + // optional uint64 positive_int_value = 4; + if (has_positive_int_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target); + } + + // optional int64 negative_int_value = 5; + if (has_negative_int_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target); + } + + // optional double double_value = 6; + if (has_double_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target); + } + + // optional bytes string_value = 7; + if (has_string_value()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 7, this->string_value(), target); + } + + // optional string aggregate_value = 8; + if (has_aggregate_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->aggregate_value().data(), this->aggregate_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 8, this->aggregate_value(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int UninterpretedOption::ByteSize() const { + int total_size = 0; + + if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { + // optional string identifier_value = 3; + if (has_identifier_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->identifier_value()); + } + + // optional uint64 positive_int_value = 4; + if (has_positive_int_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->positive_int_value()); + } + + // optional int64 negative_int_value = 5; + if (has_negative_int_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->negative_int_value()); + } + + // optional double double_value = 6; + if (has_double_value()) { + total_size += 1 + 8; + } + + // optional bytes string_value = 7; + if (has_string_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->string_value()); + } + + // optional string aggregate_value = 8; + if (has_aggregate_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->aggregate_value()); + } + + } + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; + total_size += 1 * this->name_size(); + for (int i = 0; i < this->name_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->name(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const UninterpretedOption* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void UninterpretedOption::MergeFrom(const UninterpretedOption& from) { + GOOGLE_CHECK_NE(&from, this); + name_.MergeFrom(from.name_); + if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) { + if (from.has_identifier_value()) { + set_identifier_value(from.identifier_value()); + } + if (from.has_positive_int_value()) { + set_positive_int_value(from.positive_int_value()); + } + if (from.has_negative_int_value()) { + set_negative_int_value(from.negative_int_value()); + } + if (from.has_double_value()) { + set_double_value(from.double_value()); + } + if (from.has_string_value()) { + set_string_value(from.string_value()); + } + if (from.has_aggregate_value()) { + set_aggregate_value(from.aggregate_value()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void UninterpretedOption::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void UninterpretedOption::CopyFrom(const UninterpretedOption& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool UninterpretedOption::IsInitialized() const { + + for (int i = 0; i < name_size(); i++) { + if (!this->name(i).IsInitialized()) return false; + } + return true; +} + +void UninterpretedOption::Swap(UninterpretedOption* other) { + if (other != this) { + name_.Swap(&other->name_); + std::swap(identifier_value_, other->identifier_value_); + std::swap(positive_int_value_, other->positive_int_value_); + std::swap(negative_int_value_, other->negative_int_value_); + std::swap(double_value_, other->double_value_); + std::swap(string_value_, other->string_value_); + std::swap(aggregate_value_, other->aggregate_value_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata UninterpretedOption::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = UninterpretedOption_descriptor_; + metadata.reflection = UninterpretedOption_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int SourceCodeInfo_Location::kPathFieldNumber; +const int SourceCodeInfo_Location::kSpanFieldNumber; +const int SourceCodeInfo_Location::kLeadingCommentsFieldNumber; +const int SourceCodeInfo_Location::kTrailingCommentsFieldNumber; +#endif // !_MSC_VER + +SourceCodeInfo_Location::SourceCodeInfo_Location() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void SourceCodeInfo_Location::InitAsDefaultInstance() { +} + +SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void SourceCodeInfo_Location::SharedCtor() { + _cached_size_ = 0; + leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +SourceCodeInfo_Location::~SourceCodeInfo_Location() { + SharedDtor(); +} + +void SourceCodeInfo_Location::SharedDtor() { + if (leading_comments_ != &::google::protobuf::internal::kEmptyString) { + delete leading_comments_; + } + if (trailing_comments_ != &::google::protobuf::internal::kEmptyString) { + delete trailing_comments_; + } + if (this != default_instance_) { + } +} + +void SourceCodeInfo_Location::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() { + protobuf_AssignDescriptorsOnce(); + return SourceCodeInfo_Location_descriptor_; +} + +const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +SourceCodeInfo_Location* SourceCodeInfo_Location::default_instance_ = NULL; + +SourceCodeInfo_Location* SourceCodeInfo_Location::New() const { + return new SourceCodeInfo_Location; +} + +void SourceCodeInfo_Location::Clear() { + if (_has_bits_[2 / 32] & (0xffu << (2 % 32))) { + if (has_leading_comments()) { + if (leading_comments_ != &::google::protobuf::internal::kEmptyString) { + leading_comments_->clear(); + } + } + if (has_trailing_comments()) { + if (trailing_comments_ != &::google::protobuf::internal::kEmptyString) { + trailing_comments_->clear(); + } + } + } + path_.Clear(); + span_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool SourceCodeInfo_Location::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated int32 path = 1 [packed = true]; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, this->mutable_path()))); + } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) + == ::google::protobuf::internal::WireFormatLite:: + WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + 1, 10, input, this->mutable_path()))); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_span; + break; + } + + // repeated int32 span = 2 [packed = true]; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_span: + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, this->mutable_span()))); + } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) + == ::google::protobuf::internal::WireFormatLite:: + WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + 1, 18, input, this->mutable_span()))); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_leading_comments; + break; + } + + // optional string leading_comments = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_leading_comments: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_leading_comments())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->leading_comments().data(), this->leading_comments().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_trailing_comments; + break; + } + + // optional string trailing_comments = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_trailing_comments: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_trailing_comments())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->trailing_comments().data(), this->trailing_comments().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void SourceCodeInfo_Location::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated int32 path = 1 [packed = true]; + if (this->path_size() > 0) { + ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(_path_cached_byte_size_); + } + for (int i = 0; i < this->path_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag( + this->path(i), output); + } + + // repeated int32 span = 2 [packed = true]; + if (this->span_size() > 0) { + ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(_span_cached_byte_size_); + } + for (int i = 0; i < this->span_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag( + this->span(i), output); + } + + // optional string leading_comments = 3; + if (has_leading_comments()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->leading_comments().data(), this->leading_comments().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->leading_comments(), output); + } + + // optional string trailing_comments = 4; + if (has_trailing_comments()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->trailing_comments().data(), this->trailing_comments().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->trailing_comments(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* SourceCodeInfo_Location::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated int32 path = 1 [packed = true]; + if (this->path_size() > 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray( + 1, + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + target); + target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( + _path_cached_byte_size_, target); + } + for (int i = 0; i < this->path_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32NoTagToArray(this->path(i), target); + } + + // repeated int32 span = 2 [packed = true]; + if (this->span_size() > 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray( + 2, + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + target); + target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( + _span_cached_byte_size_, target); + } + for (int i = 0; i < this->span_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32NoTagToArray(this->span(i), target); + } + + // optional string leading_comments = 3; + if (has_leading_comments()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->leading_comments().data(), this->leading_comments().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->leading_comments(), target); + } + + // optional string trailing_comments = 4; + if (has_trailing_comments()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->trailing_comments().data(), this->trailing_comments().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->trailing_comments(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int SourceCodeInfo_Location::ByteSize() const { + int total_size = 0; + + if (_has_bits_[2 / 32] & (0xffu << (2 % 32))) { + // optional string leading_comments = 3; + if (has_leading_comments()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->leading_comments()); + } + + // optional string trailing_comments = 4; + if (has_trailing_comments()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->trailing_comments()); + } + + } + // repeated int32 path = 1 [packed = true]; + { + int data_size = 0; + for (int i = 0; i < this->path_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + Int32Size(this->path(i)); + } + if (data_size > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size(data_size); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _path_cached_byte_size_ = data_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + total_size += data_size; + } + + // repeated int32 span = 2 [packed = true]; + { + int data_size = 0; + for (int i = 0; i < this->span_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + Int32Size(this->span(i)); + } + if (data_size > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size(data_size); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _span_cached_byte_size_ = data_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + total_size += data_size; + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const SourceCodeInfo_Location* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) { + GOOGLE_CHECK_NE(&from, this); + path_.MergeFrom(from.path_); + span_.MergeFrom(from.span_); + if (from._has_bits_[2 / 32] & (0xffu << (2 % 32))) { + if (from.has_leading_comments()) { + set_leading_comments(from.leading_comments()); + } + if (from.has_trailing_comments()) { + set_trailing_comments(from.trailing_comments()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void SourceCodeInfo_Location::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SourceCodeInfo_Location::IsInitialized() const { + + return true; +} + +void SourceCodeInfo_Location::Swap(SourceCodeInfo_Location* other) { + if (other != this) { + path_.Swap(&other->path_); + span_.Swap(&other->span_); + std::swap(leading_comments_, other->leading_comments_); + std::swap(trailing_comments_, other->trailing_comments_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = SourceCodeInfo_Location_descriptor_; + metadata.reflection = SourceCodeInfo_Location_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#ifndef _MSC_VER +const int SourceCodeInfo::kLocationFieldNumber; +#endif // !_MSC_VER + +SourceCodeInfo::SourceCodeInfo() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void SourceCodeInfo::InitAsDefaultInstance() { +} + +SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void SourceCodeInfo::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +SourceCodeInfo::~SourceCodeInfo() { + SharedDtor(); +} + +void SourceCodeInfo::SharedDtor() { + if (this != default_instance_) { + } +} + +void SourceCodeInfo::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() { + protobuf_AssignDescriptorsOnce(); + return SourceCodeInfo_descriptor_; +} + +const SourceCodeInfo& SourceCodeInfo::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +SourceCodeInfo* SourceCodeInfo::default_instance_ = NULL; + +SourceCodeInfo* SourceCodeInfo::New() const { + return new SourceCodeInfo; +} + +void SourceCodeInfo::Clear() { + location_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool SourceCodeInfo::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_location: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_location())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_location; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void SourceCodeInfo::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + for (int i = 0; i < this->location_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->location(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* SourceCodeInfo::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + for (int i = 0; i < this->location_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->location(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int SourceCodeInfo::ByteSize() const { + int total_size = 0; + + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + total_size += 1 * this->location_size(); + for (int i = 0; i < this->location_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->location(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const SourceCodeInfo* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) { + GOOGLE_CHECK_NE(&from, this); + location_.MergeFrom(from.location_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void SourceCodeInfo::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SourceCodeInfo::IsInitialized() const { + + return true; +} + +void SourceCodeInfo::Swap(SourceCodeInfo* other) { + if (other != this) { + location_.Swap(&other->location_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = SourceCodeInfo_descriptor_; + metadata.reflection = SourceCodeInfo_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.pb.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.pb.h new file mode 100644 index 0000000..07cf807 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.pb.h @@ -0,0 +1,5992 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/descriptor.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + +class FileDescriptorSet; +class FileDescriptorProto; +class DescriptorProto; +class DescriptorProto_ExtensionRange; +class FieldDescriptorProto; +class EnumDescriptorProto; +class EnumValueDescriptorProto; +class ServiceDescriptorProto; +class MethodDescriptorProto; +class FileOptions; +class MessageOptions; +class FieldOptions; +class EnumOptions; +class EnumValueOptions; +class ServiceOptions; +class MethodOptions; +class UninterpretedOption; +class UninterpretedOption_NamePart; +class SourceCodeInfo; +class SourceCodeInfo_Location; + +enum FieldDescriptorProto_Type { + FieldDescriptorProto_Type_TYPE_DOUBLE = 1, + FieldDescriptorProto_Type_TYPE_FLOAT = 2, + FieldDescriptorProto_Type_TYPE_INT64 = 3, + FieldDescriptorProto_Type_TYPE_UINT64 = 4, + FieldDescriptorProto_Type_TYPE_INT32 = 5, + FieldDescriptorProto_Type_TYPE_FIXED64 = 6, + FieldDescriptorProto_Type_TYPE_FIXED32 = 7, + FieldDescriptorProto_Type_TYPE_BOOL = 8, + FieldDescriptorProto_Type_TYPE_STRING = 9, + FieldDescriptorProto_Type_TYPE_GROUP = 10, + FieldDescriptorProto_Type_TYPE_MESSAGE = 11, + FieldDescriptorProto_Type_TYPE_BYTES = 12, + FieldDescriptorProto_Type_TYPE_UINT32 = 13, + FieldDescriptorProto_Type_TYPE_ENUM = 14, + FieldDescriptorProto_Type_TYPE_SFIXED32 = 15, + FieldDescriptorProto_Type_TYPE_SFIXED64 = 16, + FieldDescriptorProto_Type_TYPE_SINT32 = 17, + FieldDescriptorProto_Type_TYPE_SINT64 = 18 +}; +LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value); +const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE; +const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64; +const int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor(); +inline const ::std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value) { + return ::google::protobuf::internal::NameOfEnum( + FieldDescriptorProto_Type_descriptor(), value); +} +inline bool FieldDescriptorProto_Type_Parse( + const ::std::string& name, FieldDescriptorProto_Type* value) { + return ::google::protobuf::internal::ParseNamedEnum( + FieldDescriptorProto_Type_descriptor(), name, value); +} +enum FieldDescriptorProto_Label { + FieldDescriptorProto_Label_LABEL_OPTIONAL = 1, + FieldDescriptorProto_Label_LABEL_REQUIRED = 2, + FieldDescriptorProto_Label_LABEL_REPEATED = 3 +}; +LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value); +const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL; +const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED; +const int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor(); +inline const ::std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value) { + return ::google::protobuf::internal::NameOfEnum( + FieldDescriptorProto_Label_descriptor(), value); +} +inline bool FieldDescriptorProto_Label_Parse( + const ::std::string& name, FieldDescriptorProto_Label* value) { + return ::google::protobuf::internal::ParseNamedEnum( + FieldDescriptorProto_Label_descriptor(), name, value); +} +enum FileOptions_OptimizeMode { + FileOptions_OptimizeMode_SPEED = 1, + FileOptions_OptimizeMode_CODE_SIZE = 2, + FileOptions_OptimizeMode_LITE_RUNTIME = 3 +}; +LIBPROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value); +const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED; +const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME; +const int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor(); +inline const ::std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value) { + return ::google::protobuf::internal::NameOfEnum( + FileOptions_OptimizeMode_descriptor(), value); +} +inline bool FileOptions_OptimizeMode_Parse( + const ::std::string& name, FileOptions_OptimizeMode* value) { + return ::google::protobuf::internal::ParseNamedEnum( + FileOptions_OptimizeMode_descriptor(), name, value); +} +enum FieldOptions_CType { + FieldOptions_CType_STRING = 0, + FieldOptions_CType_CORD = 1, + FieldOptions_CType_STRING_PIECE = 2 +}; +LIBPROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value); +const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING; +const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE; +const int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor(); +inline const ::std::string& FieldOptions_CType_Name(FieldOptions_CType value) { + return ::google::protobuf::internal::NameOfEnum( + FieldOptions_CType_descriptor(), value); +} +inline bool FieldOptions_CType_Parse( + const ::std::string& name, FieldOptions_CType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + FieldOptions_CType_descriptor(), name, value); +} +// =================================================================== + +class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message { + public: + FileDescriptorSet(); + virtual ~FileDescriptorSet(); + + FileDescriptorSet(const FileDescriptorSet& from); + + inline FileDescriptorSet& operator=(const FileDescriptorSet& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FileDescriptorSet& default_instance(); + + void Swap(FileDescriptorSet* other); + + // implements Message ---------------------------------------------- + + FileDescriptorSet* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FileDescriptorSet& from); + void MergeFrom(const FileDescriptorSet& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.FileDescriptorProto file = 1; + inline int file_size() const; + inline void clear_file(); + static const int kFileFieldNumber = 1; + inline const ::google::protobuf::FileDescriptorProto& file(int index) const; + inline ::google::protobuf::FileDescriptorProto* mutable_file(int index); + inline ::google::protobuf::FileDescriptorProto* add_file(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& + file() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* + mutable_file(); + + // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static FileDescriptorSet* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message { + public: + FileDescriptorProto(); + virtual ~FileDescriptorProto(); + + FileDescriptorProto(const FileDescriptorProto& from); + + inline FileDescriptorProto& operator=(const FileDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FileDescriptorProto& default_instance(); + + void Swap(FileDescriptorProto* other); + + // implements Message ---------------------------------------------- + + FileDescriptorProto* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FileDescriptorProto& from); + void MergeFrom(const FileDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // optional string package = 2; + inline bool has_package() const; + inline void clear_package(); + static const int kPackageFieldNumber = 2; + inline const ::std::string& package() const; + inline void set_package(const ::std::string& value); + inline void set_package(const char* value); + inline void set_package(const char* value, size_t size); + inline ::std::string* mutable_package(); + inline ::std::string* release_package(); + inline void set_allocated_package(::std::string* package); + + // repeated string dependency = 3; + inline int dependency_size() const; + inline void clear_dependency(); + static const int kDependencyFieldNumber = 3; + inline const ::std::string& dependency(int index) const; + inline ::std::string* mutable_dependency(int index); + inline void set_dependency(int index, const ::std::string& value); + inline void set_dependency(int index, const char* value); + inline void set_dependency(int index, const char* value, size_t size); + inline ::std::string* add_dependency(); + inline void add_dependency(const ::std::string& value); + inline void add_dependency(const char* value); + inline void add_dependency(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency(); + + // repeated int32 public_dependency = 10; + inline int public_dependency_size() const; + inline void clear_public_dependency(); + static const int kPublicDependencyFieldNumber = 10; + inline ::google::protobuf::int32 public_dependency(int index) const; + inline void set_public_dependency(int index, ::google::protobuf::int32 value); + inline void add_public_dependency(::google::protobuf::int32 value); + inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + public_dependency() const; + inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_public_dependency(); + + // repeated int32 weak_dependency = 11; + inline int weak_dependency_size() const; + inline void clear_weak_dependency(); + static const int kWeakDependencyFieldNumber = 11; + inline ::google::protobuf::int32 weak_dependency(int index) const; + inline void set_weak_dependency(int index, ::google::protobuf::int32 value); + inline void add_weak_dependency(::google::protobuf::int32 value); + inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + weak_dependency() const; + inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_weak_dependency(); + + // repeated .google.protobuf.DescriptorProto message_type = 4; + inline int message_type_size() const; + inline void clear_message_type(); + static const int kMessageTypeFieldNumber = 4; + inline const ::google::protobuf::DescriptorProto& message_type(int index) const; + inline ::google::protobuf::DescriptorProto* mutable_message_type(int index); + inline ::google::protobuf::DescriptorProto* add_message_type(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& + message_type() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* + mutable_message_type(); + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; + inline int enum_type_size() const; + inline void clear_enum_type(); + static const int kEnumTypeFieldNumber = 5; + inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; + inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); + inline ::google::protobuf::EnumDescriptorProto* add_enum_type(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& + enum_type() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* + mutable_enum_type(); + + // repeated .google.protobuf.ServiceDescriptorProto service = 6; + inline int service_size() const; + inline void clear_service(); + static const int kServiceFieldNumber = 6; + inline const ::google::protobuf::ServiceDescriptorProto& service(int index) const; + inline ::google::protobuf::ServiceDescriptorProto* mutable_service(int index); + inline ::google::protobuf::ServiceDescriptorProto* add_service(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& + service() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* + mutable_service(); + + // repeated .google.protobuf.FieldDescriptorProto extension = 7; + inline int extension_size() const; + inline void clear_extension(); + static const int kExtensionFieldNumber = 7; + inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const; + inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); + inline ::google::protobuf::FieldDescriptorProto* add_extension(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& + extension() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* + mutable_extension(); + + // optional .google.protobuf.FileOptions options = 8; + inline bool has_options() const; + inline void clear_options(); + static const int kOptionsFieldNumber = 8; + inline const ::google::protobuf::FileOptions& options() const; + inline ::google::protobuf::FileOptions* mutable_options(); + inline ::google::protobuf::FileOptions* release_options(); + inline void set_allocated_options(::google::protobuf::FileOptions* options); + + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + inline bool has_source_code_info() const; + inline void clear_source_code_info(); + static const int kSourceCodeInfoFieldNumber = 9; + inline const ::google::protobuf::SourceCodeInfo& source_code_info() const; + inline ::google::protobuf::SourceCodeInfo* mutable_source_code_info(); + inline ::google::protobuf::SourceCodeInfo* release_source_code_info(); + inline void set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info); + + // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_package(); + inline void clear_has_package(); + inline void set_has_options(); + inline void clear_has_options(); + inline void set_has_source_code_info(); + inline void clear_has_source_code_info(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::std::string* package_; + ::google::protobuf::RepeatedPtrField< ::std::string> dependency_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > public_dependency_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > weak_dependency_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_; + ::google::protobuf::FileOptions* options_; + ::google::protobuf::SourceCodeInfo* source_code_info_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(11 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static FileDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::protobuf::Message { + public: + DescriptorProto_ExtensionRange(); + virtual ~DescriptorProto_ExtensionRange(); + + DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from); + + inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const DescriptorProto_ExtensionRange& default_instance(); + + void Swap(DescriptorProto_ExtensionRange* other); + + // implements Message ---------------------------------------------- + + DescriptorProto_ExtensionRange* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DescriptorProto_ExtensionRange& from); + void MergeFrom(const DescriptorProto_ExtensionRange& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 start = 1; + inline bool has_start() const; + inline void clear_start(); + static const int kStartFieldNumber = 1; + inline ::google::protobuf::int32 start() const; + inline void set_start(::google::protobuf::int32 value); + + // optional int32 end = 2; + inline bool has_end() const; + inline void clear_end(); + static const int kEndFieldNumber = 2; + inline ::google::protobuf::int32 end() const; + inline void set_end(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange) + private: + inline void set_has_start(); + inline void clear_has_start(); + inline void set_has_end(); + inline void clear_has_end(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::int32 start_; + ::google::protobuf::int32 end_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static DescriptorProto_ExtensionRange* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { + public: + DescriptorProto(); + virtual ~DescriptorProto(); + + DescriptorProto(const DescriptorProto& from); + + inline DescriptorProto& operator=(const DescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const DescriptorProto& default_instance(); + + void Swap(DescriptorProto* other); + + // implements Message ---------------------------------------------- + + DescriptorProto* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DescriptorProto& from); + void MergeFrom(const DescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef DescriptorProto_ExtensionRange ExtensionRange; + + // accessors ------------------------------------------------------- + + // optional string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.FieldDescriptorProto field = 2; + inline int field_size() const; + inline void clear_field(); + static const int kFieldFieldNumber = 2; + inline const ::google::protobuf::FieldDescriptorProto& field(int index) const; + inline ::google::protobuf::FieldDescriptorProto* mutable_field(int index); + inline ::google::protobuf::FieldDescriptorProto* add_field(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& + field() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* + mutable_field(); + + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + inline int extension_size() const; + inline void clear_extension(); + static const int kExtensionFieldNumber = 6; + inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const; + inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); + inline ::google::protobuf::FieldDescriptorProto* add_extension(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& + extension() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* + mutable_extension(); + + // repeated .google.protobuf.DescriptorProto nested_type = 3; + inline int nested_type_size() const; + inline void clear_nested_type(); + static const int kNestedTypeFieldNumber = 3; + inline const ::google::protobuf::DescriptorProto& nested_type(int index) const; + inline ::google::protobuf::DescriptorProto* mutable_nested_type(int index); + inline ::google::protobuf::DescriptorProto* add_nested_type(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& + nested_type() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* + mutable_nested_type(); + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; + inline int enum_type_size() const; + inline void clear_enum_type(); + static const int kEnumTypeFieldNumber = 4; + inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; + inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); + inline ::google::protobuf::EnumDescriptorProto* add_enum_type(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& + enum_type() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* + mutable_enum_type(); + + // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; + inline int extension_range_size() const; + inline void clear_extension_range(); + static const int kExtensionRangeFieldNumber = 5; + inline const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const; + inline ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index); + inline ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& + extension_range() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* + mutable_extension_range(); + + // optional .google.protobuf.MessageOptions options = 7; + inline bool has_options() const; + inline void clear_options(); + static const int kOptionsFieldNumber = 7; + inline const ::google::protobuf::MessageOptions& options() const; + inline ::google::protobuf::MessageOptions* mutable_options(); + inline ::google::protobuf::MessageOptions* release_options(); + inline void set_allocated_options(::google::protobuf::MessageOptions* options); + + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_; + ::google::protobuf::MessageOptions* options_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static DescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Message { + public: + FieldDescriptorProto(); + virtual ~FieldDescriptorProto(); + + FieldDescriptorProto(const FieldDescriptorProto& from); + + inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FieldDescriptorProto& default_instance(); + + void Swap(FieldDescriptorProto* other); + + // implements Message ---------------------------------------------- + + FieldDescriptorProto* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FieldDescriptorProto& from); + void MergeFrom(const FieldDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef FieldDescriptorProto_Type Type; + static const Type TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE; + static const Type TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT; + static const Type TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64; + static const Type TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64; + static const Type TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32; + static const Type TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64; + static const Type TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32; + static const Type TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL; + static const Type TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING; + static const Type TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP; + static const Type TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE; + static const Type TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES; + static const Type TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32; + static const Type TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM; + static const Type TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32; + static const Type TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64; + static const Type TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32; + static const Type TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64; + static inline bool Type_IsValid(int value) { + return FieldDescriptorProto_Type_IsValid(value); + } + static const Type Type_MIN = + FieldDescriptorProto_Type_Type_MIN; + static const Type Type_MAX = + FieldDescriptorProto_Type_Type_MAX; + static const int Type_ARRAYSIZE = + FieldDescriptorProto_Type_Type_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Type_descriptor() { + return FieldDescriptorProto_Type_descriptor(); + } + static inline const ::std::string& Type_Name(Type value) { + return FieldDescriptorProto_Type_Name(value); + } + static inline bool Type_Parse(const ::std::string& name, + Type* value) { + return FieldDescriptorProto_Type_Parse(name, value); + } + + typedef FieldDescriptorProto_Label Label; + static const Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL; + static const Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED; + static const Label LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED; + static inline bool Label_IsValid(int value) { + return FieldDescriptorProto_Label_IsValid(value); + } + static const Label Label_MIN = + FieldDescriptorProto_Label_Label_MIN; + static const Label Label_MAX = + FieldDescriptorProto_Label_Label_MAX; + static const int Label_ARRAYSIZE = + FieldDescriptorProto_Label_Label_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Label_descriptor() { + return FieldDescriptorProto_Label_descriptor(); + } + static inline const ::std::string& Label_Name(Label value) { + return FieldDescriptorProto_Label_Name(value); + } + static inline bool Label_Parse(const ::std::string& name, + Label* value) { + return FieldDescriptorProto_Label_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // optional int32 number = 3; + inline bool has_number() const; + inline void clear_number(); + static const int kNumberFieldNumber = 3; + inline ::google::protobuf::int32 number() const; + inline void set_number(::google::protobuf::int32 value); + + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + inline bool has_label() const; + inline void clear_label(); + static const int kLabelFieldNumber = 4; + inline ::google::protobuf::FieldDescriptorProto_Label label() const; + inline void set_label(::google::protobuf::FieldDescriptorProto_Label value); + + // optional .google.protobuf.FieldDescriptorProto.Type type = 5; + inline bool has_type() const; + inline void clear_type(); + static const int kTypeFieldNumber = 5; + inline ::google::protobuf::FieldDescriptorProto_Type type() const; + inline void set_type(::google::protobuf::FieldDescriptorProto_Type value); + + // optional string type_name = 6; + inline bool has_type_name() const; + inline void clear_type_name(); + static const int kTypeNameFieldNumber = 6; + inline const ::std::string& type_name() const; + inline void set_type_name(const ::std::string& value); + inline void set_type_name(const char* value); + inline void set_type_name(const char* value, size_t size); + inline ::std::string* mutable_type_name(); + inline ::std::string* release_type_name(); + inline void set_allocated_type_name(::std::string* type_name); + + // optional string extendee = 2; + inline bool has_extendee() const; + inline void clear_extendee(); + static const int kExtendeeFieldNumber = 2; + inline const ::std::string& extendee() const; + inline void set_extendee(const ::std::string& value); + inline void set_extendee(const char* value); + inline void set_extendee(const char* value, size_t size); + inline ::std::string* mutable_extendee(); + inline ::std::string* release_extendee(); + inline void set_allocated_extendee(::std::string* extendee); + + // optional string default_value = 7; + inline bool has_default_value() const; + inline void clear_default_value(); + static const int kDefaultValueFieldNumber = 7; + inline const ::std::string& default_value() const; + inline void set_default_value(const ::std::string& value); + inline void set_default_value(const char* value); + inline void set_default_value(const char* value, size_t size); + inline ::std::string* mutable_default_value(); + inline ::std::string* release_default_value(); + inline void set_allocated_default_value(::std::string* default_value); + + // optional .google.protobuf.FieldOptions options = 8; + inline bool has_options() const; + inline void clear_options(); + static const int kOptionsFieldNumber = 8; + inline const ::google::protobuf::FieldOptions& options() const; + inline ::google::protobuf::FieldOptions* mutable_options(); + inline ::google::protobuf::FieldOptions* release_options(); + inline void set_allocated_options(::google::protobuf::FieldOptions* options); + + // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_number(); + inline void clear_has_number(); + inline void set_has_label(); + inline void clear_has_label(); + inline void set_has_type(); + inline void clear_has_type(); + inline void set_has_type_name(); + inline void clear_has_type_name(); + inline void set_has_extendee(); + inline void clear_has_extendee(); + inline void set_has_default_value(); + inline void clear_has_default_value(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::google::protobuf::int32 number_; + int label_; + ::std::string* type_name_; + ::std::string* extendee_; + ::std::string* default_value_; + ::google::protobuf::FieldOptions* options_; + int type_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static FieldDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Message { + public: + EnumDescriptorProto(); + virtual ~EnumDescriptorProto(); + + EnumDescriptorProto(const EnumDescriptorProto& from); + + inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EnumDescriptorProto& default_instance(); + + void Swap(EnumDescriptorProto* other); + + // implements Message ---------------------------------------------- + + EnumDescriptorProto* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EnumDescriptorProto& from); + void MergeFrom(const EnumDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.EnumValueDescriptorProto value = 2; + inline int value_size() const; + inline void clear_value(); + static const int kValueFieldNumber = 2; + inline const ::google::protobuf::EnumValueDescriptorProto& value(int index) const; + inline ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index); + inline ::google::protobuf::EnumValueDescriptorProto* add_value(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& + value() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* + mutable_value(); + + // optional .google.protobuf.EnumOptions options = 3; + inline bool has_options() const; + inline void clear_options(); + static const int kOptionsFieldNumber = 3; + inline const ::google::protobuf::EnumOptions& options() const; + inline ::google::protobuf::EnumOptions* mutable_options(); + inline ::google::protobuf::EnumOptions* release_options(); + inline void set_allocated_options(::google::protobuf::EnumOptions* options); + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_; + ::google::protobuf::EnumOptions* options_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static EnumDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::Message { + public: + EnumValueDescriptorProto(); + virtual ~EnumValueDescriptorProto(); + + EnumValueDescriptorProto(const EnumValueDescriptorProto& from); + + inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EnumValueDescriptorProto& default_instance(); + + void Swap(EnumValueDescriptorProto* other); + + // implements Message ---------------------------------------------- + + EnumValueDescriptorProto* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EnumValueDescriptorProto& from); + void MergeFrom(const EnumValueDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // optional int32 number = 2; + inline bool has_number() const; + inline void clear_number(); + static const int kNumberFieldNumber = 2; + inline ::google::protobuf::int32 number() const; + inline void set_number(::google::protobuf::int32 value); + + // optional .google.protobuf.EnumValueOptions options = 3; + inline bool has_options() const; + inline void clear_options(); + static const int kOptionsFieldNumber = 3; + inline const ::google::protobuf::EnumValueOptions& options() const; + inline ::google::protobuf::EnumValueOptions* mutable_options(); + inline ::google::protobuf::EnumValueOptions* release_options(); + inline void set_allocated_options(::google::protobuf::EnumValueOptions* options); + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_number(); + inline void clear_has_number(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::google::protobuf::EnumValueOptions* options_; + ::google::protobuf::int32 number_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static EnumValueDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Message { + public: + ServiceDescriptorProto(); + virtual ~ServiceDescriptorProto(); + + ServiceDescriptorProto(const ServiceDescriptorProto& from); + + inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServiceDescriptorProto& default_instance(); + + void Swap(ServiceDescriptorProto* other); + + // implements Message ---------------------------------------------- + + ServiceDescriptorProto* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServiceDescriptorProto& from); + void MergeFrom(const ServiceDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.MethodDescriptorProto method = 2; + inline int method_size() const; + inline void clear_method(); + static const int kMethodFieldNumber = 2; + inline const ::google::protobuf::MethodDescriptorProto& method(int index) const; + inline ::google::protobuf::MethodDescriptorProto* mutable_method(int index); + inline ::google::protobuf::MethodDescriptorProto* add_method(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& + method() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* + mutable_method(); + + // optional .google.protobuf.ServiceOptions options = 3; + inline bool has_options() const; + inline void clear_options(); + static const int kOptionsFieldNumber = 3; + inline const ::google::protobuf::ServiceOptions& options() const; + inline ::google::protobuf::ServiceOptions* mutable_options(); + inline ::google::protobuf::ServiceOptions* release_options(); + inline void set_allocated_options(::google::protobuf::ServiceOptions* options); + + // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_; + ::google::protobuf::ServiceOptions* options_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static ServiceDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Message { + public: + MethodDescriptorProto(); + virtual ~MethodDescriptorProto(); + + MethodDescriptorProto(const MethodDescriptorProto& from); + + inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MethodDescriptorProto& default_instance(); + + void Swap(MethodDescriptorProto* other); + + // implements Message ---------------------------------------------- + + MethodDescriptorProto* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MethodDescriptorProto& from); + void MergeFrom(const MethodDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + inline void set_allocated_name(::std::string* name); + + // optional string input_type = 2; + inline bool has_input_type() const; + inline void clear_input_type(); + static const int kInputTypeFieldNumber = 2; + inline const ::std::string& input_type() const; + inline void set_input_type(const ::std::string& value); + inline void set_input_type(const char* value); + inline void set_input_type(const char* value, size_t size); + inline ::std::string* mutable_input_type(); + inline ::std::string* release_input_type(); + inline void set_allocated_input_type(::std::string* input_type); + + // optional string output_type = 3; + inline bool has_output_type() const; + inline void clear_output_type(); + static const int kOutputTypeFieldNumber = 3; + inline const ::std::string& output_type() const; + inline void set_output_type(const ::std::string& value); + inline void set_output_type(const char* value); + inline void set_output_type(const char* value, size_t size); + inline ::std::string* mutable_output_type(); + inline ::std::string* release_output_type(); + inline void set_allocated_output_type(::std::string* output_type); + + // optional .google.protobuf.MethodOptions options = 4; + inline bool has_options() const; + inline void clear_options(); + static const int kOptionsFieldNumber = 4; + inline const ::google::protobuf::MethodOptions& options() const; + inline ::google::protobuf::MethodOptions* mutable_options(); + inline ::google::protobuf::MethodOptions* release_options(); + inline void set_allocated_options(::google::protobuf::MethodOptions* options); + + // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_input_type(); + inline void clear_has_input_type(); + inline void set_has_output_type(); + inline void clear_has_output_type(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::std::string* input_type_; + ::std::string* output_type_; + ::google::protobuf::MethodOptions* options_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static MethodDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { + public: + FileOptions(); + virtual ~FileOptions(); + + FileOptions(const FileOptions& from); + + inline FileOptions& operator=(const FileOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FileOptions& default_instance(); + + void Swap(FileOptions* other); + + // implements Message ---------------------------------------------- + + FileOptions* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FileOptions& from); + void MergeFrom(const FileOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef FileOptions_OptimizeMode OptimizeMode; + static const OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED; + static const OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE; + static const OptimizeMode LITE_RUNTIME = FileOptions_OptimizeMode_LITE_RUNTIME; + static inline bool OptimizeMode_IsValid(int value) { + return FileOptions_OptimizeMode_IsValid(value); + } + static const OptimizeMode OptimizeMode_MIN = + FileOptions_OptimizeMode_OptimizeMode_MIN; + static const OptimizeMode OptimizeMode_MAX = + FileOptions_OptimizeMode_OptimizeMode_MAX; + static const int OptimizeMode_ARRAYSIZE = + FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + OptimizeMode_descriptor() { + return FileOptions_OptimizeMode_descriptor(); + } + static inline const ::std::string& OptimizeMode_Name(OptimizeMode value) { + return FileOptions_OptimizeMode_Name(value); + } + static inline bool OptimizeMode_Parse(const ::std::string& name, + OptimizeMode* value) { + return FileOptions_OptimizeMode_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional string java_package = 1; + inline bool has_java_package() const; + inline void clear_java_package(); + static const int kJavaPackageFieldNumber = 1; + inline const ::std::string& java_package() const; + inline void set_java_package(const ::std::string& value); + inline void set_java_package(const char* value); + inline void set_java_package(const char* value, size_t size); + inline ::std::string* mutable_java_package(); + inline ::std::string* release_java_package(); + inline void set_allocated_java_package(::std::string* java_package); + + // optional string java_outer_classname = 8; + inline bool has_java_outer_classname() const; + inline void clear_java_outer_classname(); + static const int kJavaOuterClassnameFieldNumber = 8; + inline const ::std::string& java_outer_classname() const; + inline void set_java_outer_classname(const ::std::string& value); + inline void set_java_outer_classname(const char* value); + inline void set_java_outer_classname(const char* value, size_t size); + inline ::std::string* mutable_java_outer_classname(); + inline ::std::string* release_java_outer_classname(); + inline void set_allocated_java_outer_classname(::std::string* java_outer_classname); + + // optional bool java_multiple_files = 10 [default = false]; + inline bool has_java_multiple_files() const; + inline void clear_java_multiple_files(); + static const int kJavaMultipleFilesFieldNumber = 10; + inline bool java_multiple_files() const; + inline void set_java_multiple_files(bool value); + + // optional bool java_generate_equals_and_hash = 20 [default = false]; + inline bool has_java_generate_equals_and_hash() const; + inline void clear_java_generate_equals_and_hash(); + static const int kJavaGenerateEqualsAndHashFieldNumber = 20; + inline bool java_generate_equals_and_hash() const; + inline void set_java_generate_equals_and_hash(bool value); + + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; + inline bool has_optimize_for() const; + inline void clear_optimize_for(); + static const int kOptimizeForFieldNumber = 9; + inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const; + inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value); + + // optional string go_package = 11; + inline bool has_go_package() const; + inline void clear_go_package(); + static const int kGoPackageFieldNumber = 11; + inline const ::std::string& go_package() const; + inline void set_go_package(const ::std::string& value); + inline void set_go_package(const char* value); + inline void set_go_package(const char* value, size_t size); + inline ::std::string* mutable_go_package(); + inline ::std::string* release_go_package(); + inline void set_allocated_go_package(::std::string* go_package); + + // optional bool cc_generic_services = 16 [default = false]; + inline bool has_cc_generic_services() const; + inline void clear_cc_generic_services(); + static const int kCcGenericServicesFieldNumber = 16; + inline bool cc_generic_services() const; + inline void set_cc_generic_services(bool value); + + // optional bool java_generic_services = 17 [default = false]; + inline bool has_java_generic_services() const; + inline void clear_java_generic_services(); + static const int kJavaGenericServicesFieldNumber = 17; + inline bool java_generic_services() const; + inline void set_java_generic_services(bool value); + + // optional bool py_generic_services = 18 [default = false]; + inline bool has_py_generic_services() const; + inline void clear_py_generic_services(); + static const int kPyGenericServicesFieldNumber = 18; + inline bool py_generic_services() const; + inline void set_py_generic_services(bool value); + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + inline int uninterpreted_option_size() const; + inline void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions) + private: + inline void set_has_java_package(); + inline void clear_has_java_package(); + inline void set_has_java_outer_classname(); + inline void clear_has_java_outer_classname(); + inline void set_has_java_multiple_files(); + inline void clear_has_java_multiple_files(); + inline void set_has_java_generate_equals_and_hash(); + inline void clear_has_java_generate_equals_and_hash(); + inline void set_has_optimize_for(); + inline void clear_has_optimize_for(); + inline void set_has_go_package(); + inline void clear_has_go_package(); + inline void set_has_cc_generic_services(); + inline void clear_has_cc_generic_services(); + inline void set_has_java_generic_services(); + inline void clear_has_java_generic_services(); + inline void set_has_py_generic_services(); + inline void clear_has_py_generic_services(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* java_package_; + ::std::string* java_outer_classname_; + int optimize_for_; + bool java_multiple_files_; + bool java_generate_equals_and_hash_; + bool cc_generic_services_; + bool java_generic_services_; + ::std::string* go_package_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + bool py_generic_services_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(10 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static FileOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { + public: + MessageOptions(); + virtual ~MessageOptions(); + + MessageOptions(const MessageOptions& from); + + inline MessageOptions& operator=(const MessageOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MessageOptions& default_instance(); + + void Swap(MessageOptions* other); + + // implements Message ---------------------------------------------- + + MessageOptions* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MessageOptions& from); + void MergeFrom(const MessageOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool message_set_wire_format = 1 [default = false]; + inline bool has_message_set_wire_format() const; + inline void clear_message_set_wire_format(); + static const int kMessageSetWireFormatFieldNumber = 1; + inline bool message_set_wire_format() const; + inline void set_message_set_wire_format(bool value); + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + inline bool has_no_standard_descriptor_accessor() const; + inline void clear_no_standard_descriptor_accessor(); + static const int kNoStandardDescriptorAccessorFieldNumber = 2; + inline bool no_standard_descriptor_accessor() const; + inline void set_no_standard_descriptor_accessor(bool value); + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + inline int uninterpreted_option_size() const; + inline void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions) + private: + inline void set_has_message_set_wire_format(); + inline void clear_has_message_set_wire_format(); + inline void set_has_no_standard_descriptor_accessor(); + inline void clear_has_no_standard_descriptor_accessor(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + bool message_set_wire_format_; + bool no_standard_descriptor_accessor_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static MessageOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { + public: + FieldOptions(); + virtual ~FieldOptions(); + + FieldOptions(const FieldOptions& from); + + inline FieldOptions& operator=(const FieldOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FieldOptions& default_instance(); + + void Swap(FieldOptions* other); + + // implements Message ---------------------------------------------- + + FieldOptions* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FieldOptions& from); + void MergeFrom(const FieldOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef FieldOptions_CType CType; + static const CType STRING = FieldOptions_CType_STRING; + static const CType CORD = FieldOptions_CType_CORD; + static const CType STRING_PIECE = FieldOptions_CType_STRING_PIECE; + static inline bool CType_IsValid(int value) { + return FieldOptions_CType_IsValid(value); + } + static const CType CType_MIN = + FieldOptions_CType_CType_MIN; + static const CType CType_MAX = + FieldOptions_CType_CType_MAX; + static const int CType_ARRAYSIZE = + FieldOptions_CType_CType_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + CType_descriptor() { + return FieldOptions_CType_descriptor(); + } + static inline const ::std::string& CType_Name(CType value) { + return FieldOptions_CType_Name(value); + } + static inline bool CType_Parse(const ::std::string& name, + CType* value) { + return FieldOptions_CType_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; + inline bool has_ctype() const; + inline void clear_ctype(); + static const int kCtypeFieldNumber = 1; + inline ::google::protobuf::FieldOptions_CType ctype() const; + inline void set_ctype(::google::protobuf::FieldOptions_CType value); + + // optional bool packed = 2; + inline bool has_packed() const; + inline void clear_packed(); + static const int kPackedFieldNumber = 2; + inline bool packed() const; + inline void set_packed(bool value); + + // optional bool lazy = 5 [default = false]; + inline bool has_lazy() const; + inline void clear_lazy(); + static const int kLazyFieldNumber = 5; + inline bool lazy() const; + inline void set_lazy(bool value); + + // optional bool deprecated = 3 [default = false]; + inline bool has_deprecated() const; + inline void clear_deprecated(); + static const int kDeprecatedFieldNumber = 3; + inline bool deprecated() const; + inline void set_deprecated(bool value); + + // optional string experimental_map_key = 9; + inline bool has_experimental_map_key() const; + inline void clear_experimental_map_key(); + static const int kExperimentalMapKeyFieldNumber = 9; + inline const ::std::string& experimental_map_key() const; + inline void set_experimental_map_key(const ::std::string& value); + inline void set_experimental_map_key(const char* value); + inline void set_experimental_map_key(const char* value, size_t size); + inline ::std::string* mutable_experimental_map_key(); + inline ::std::string* release_experimental_map_key(); + inline void set_allocated_experimental_map_key(::std::string* experimental_map_key); + + // optional bool weak = 10 [default = false]; + inline bool has_weak() const; + inline void clear_weak(); + static const int kWeakFieldNumber = 10; + inline bool weak() const; + inline void set_weak(bool value); + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + inline int uninterpreted_option_size() const; + inline void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions) + private: + inline void set_has_ctype(); + inline void clear_has_ctype(); + inline void set_has_packed(); + inline void clear_has_packed(); + inline void set_has_lazy(); + inline void clear_has_lazy(); + inline void set_has_deprecated(); + inline void clear_has_deprecated(); + inline void set_has_experimental_map_key(); + inline void clear_has_experimental_map_key(); + inline void set_has_weak(); + inline void clear_has_weak(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + int ctype_; + bool packed_; + bool lazy_; + bool deprecated_; + bool weak_; + ::std::string* experimental_map_key_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static FieldOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { + public: + EnumOptions(); + virtual ~EnumOptions(); + + EnumOptions(const EnumOptions& from); + + inline EnumOptions& operator=(const EnumOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EnumOptions& default_instance(); + + void Swap(EnumOptions* other); + + // implements Message ---------------------------------------------- + + EnumOptions* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EnumOptions& from); + void MergeFrom(const EnumOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool allow_alias = 2 [default = true]; + inline bool has_allow_alias() const; + inline void clear_allow_alias(); + static const int kAllowAliasFieldNumber = 2; + inline bool allow_alias() const; + inline void set_allow_alias(bool value); + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + inline int uninterpreted_option_size() const; + inline void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions) + private: + inline void set_has_allow_alias(); + inline void clear_has_allow_alias(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + bool allow_alias_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static EnumOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { + public: + EnumValueOptions(); + virtual ~EnumValueOptions(); + + EnumValueOptions(const EnumValueOptions& from); + + inline EnumValueOptions& operator=(const EnumValueOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EnumValueOptions& default_instance(); + + void Swap(EnumValueOptions* other); + + // implements Message ---------------------------------------------- + + EnumValueOptions* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EnumValueOptions& from); + void MergeFrom(const EnumValueOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + inline int uninterpreted_option_size() const; + inline void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions) + private: + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static EnumValueOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { + public: + ServiceOptions(); + virtual ~ServiceOptions(); + + ServiceOptions(const ServiceOptions& from); + + inline ServiceOptions& operator=(const ServiceOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServiceOptions& default_instance(); + + void Swap(ServiceOptions* other); + + // implements Message ---------------------------------------------- + + ServiceOptions* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServiceOptions& from); + void MergeFrom(const ServiceOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + inline int uninterpreted_option_size() const; + inline void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions) + private: + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static ServiceOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { + public: + MethodOptions(); + virtual ~MethodOptions(); + + MethodOptions(const MethodOptions& from); + + inline MethodOptions& operator=(const MethodOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MethodOptions& default_instance(); + + void Swap(MethodOptions* other); + + // implements Message ---------------------------------------------- + + MethodOptions* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MethodOptions& from); + void MergeFrom(const MethodOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + inline int uninterpreted_option_size() const; + inline void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions) + private: + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static MethodOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobuf::Message { + public: + UninterpretedOption_NamePart(); + virtual ~UninterpretedOption_NamePart(); + + UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from); + + inline UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const UninterpretedOption_NamePart& default_instance(); + + void Swap(UninterpretedOption_NamePart* other); + + // implements Message ---------------------------------------------- + + UninterpretedOption_NamePart* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const UninterpretedOption_NamePart& from); + void MergeFrom(const UninterpretedOption_NamePart& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string name_part = 1; + inline bool has_name_part() const; + inline void clear_name_part(); + static const int kNamePartFieldNumber = 1; + inline const ::std::string& name_part() const; + inline void set_name_part(const ::std::string& value); + inline void set_name_part(const char* value); + inline void set_name_part(const char* value, size_t size); + inline ::std::string* mutable_name_part(); + inline ::std::string* release_name_part(); + inline void set_allocated_name_part(::std::string* name_part); + + // required bool is_extension = 2; + inline bool has_is_extension() const; + inline void clear_is_extension(); + static const int kIsExtensionFieldNumber = 2; + inline bool is_extension() const; + inline void set_is_extension(bool value); + + // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart) + private: + inline void set_has_name_part(); + inline void clear_has_name_part(); + inline void set_has_is_extension(); + inline void clear_has_is_extension(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_part_; + bool is_extension_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static UninterpretedOption_NamePart* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Message { + public: + UninterpretedOption(); + virtual ~UninterpretedOption(); + + UninterpretedOption(const UninterpretedOption& from); + + inline UninterpretedOption& operator=(const UninterpretedOption& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const UninterpretedOption& default_instance(); + + void Swap(UninterpretedOption* other); + + // implements Message ---------------------------------------------- + + UninterpretedOption* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const UninterpretedOption& from); + void MergeFrom(const UninterpretedOption& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef UninterpretedOption_NamePart NamePart; + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; + inline int name_size() const; + inline void clear_name(); + static const int kNameFieldNumber = 2; + inline const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const; + inline ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index); + inline ::google::protobuf::UninterpretedOption_NamePart* add_name(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >& + name() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >* + mutable_name(); + + // optional string identifier_value = 3; + inline bool has_identifier_value() const; + inline void clear_identifier_value(); + static const int kIdentifierValueFieldNumber = 3; + inline const ::std::string& identifier_value() const; + inline void set_identifier_value(const ::std::string& value); + inline void set_identifier_value(const char* value); + inline void set_identifier_value(const char* value, size_t size); + inline ::std::string* mutable_identifier_value(); + inline ::std::string* release_identifier_value(); + inline void set_allocated_identifier_value(::std::string* identifier_value); + + // optional uint64 positive_int_value = 4; + inline bool has_positive_int_value() const; + inline void clear_positive_int_value(); + static const int kPositiveIntValueFieldNumber = 4; + inline ::google::protobuf::uint64 positive_int_value() const; + inline void set_positive_int_value(::google::protobuf::uint64 value); + + // optional int64 negative_int_value = 5; + inline bool has_negative_int_value() const; + inline void clear_negative_int_value(); + static const int kNegativeIntValueFieldNumber = 5; + inline ::google::protobuf::int64 negative_int_value() const; + inline void set_negative_int_value(::google::protobuf::int64 value); + + // optional double double_value = 6; + inline bool has_double_value() const; + inline void clear_double_value(); + static const int kDoubleValueFieldNumber = 6; + inline double double_value() const; + inline void set_double_value(double value); + + // optional bytes string_value = 7; + inline bool has_string_value() const; + inline void clear_string_value(); + static const int kStringValueFieldNumber = 7; + inline const ::std::string& string_value() const; + inline void set_string_value(const ::std::string& value); + inline void set_string_value(const char* value); + inline void set_string_value(const void* value, size_t size); + inline ::std::string* mutable_string_value(); + inline ::std::string* release_string_value(); + inline void set_allocated_string_value(::std::string* string_value); + + // optional string aggregate_value = 8; + inline bool has_aggregate_value() const; + inline void clear_aggregate_value(); + static const int kAggregateValueFieldNumber = 8; + inline const ::std::string& aggregate_value() const; + inline void set_aggregate_value(const ::std::string& value); + inline void set_aggregate_value(const char* value); + inline void set_aggregate_value(const char* value, size_t size); + inline ::std::string* mutable_aggregate_value(); + inline ::std::string* release_aggregate_value(); + inline void set_allocated_aggregate_value(::std::string* aggregate_value); + + // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption) + private: + inline void set_has_identifier_value(); + inline void clear_has_identifier_value(); + inline void set_has_positive_int_value(); + inline void clear_has_positive_int_value(); + inline void set_has_negative_int_value(); + inline void clear_has_negative_int_value(); + inline void set_has_double_value(); + inline void clear_has_double_value(); + inline void set_has_string_value(); + inline void clear_has_string_value(); + inline void set_has_aggregate_value(); + inline void clear_has_aggregate_value(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_; + ::std::string* identifier_value_; + ::google::protobuf::uint64 positive_int_value_; + ::google::protobuf::int64 negative_int_value_; + double double_value_; + ::std::string* string_value_; + ::std::string* aggregate_value_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static UninterpretedOption* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message { + public: + SourceCodeInfo_Location(); + virtual ~SourceCodeInfo_Location(); + + SourceCodeInfo_Location(const SourceCodeInfo_Location& from); + + inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SourceCodeInfo_Location& default_instance(); + + void Swap(SourceCodeInfo_Location* other); + + // implements Message ---------------------------------------------- + + SourceCodeInfo_Location* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SourceCodeInfo_Location& from); + void MergeFrom(const SourceCodeInfo_Location& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated int32 path = 1 [packed = true]; + inline int path_size() const; + inline void clear_path(); + static const int kPathFieldNumber = 1; + inline ::google::protobuf::int32 path(int index) const; + inline void set_path(int index, ::google::protobuf::int32 value); + inline void add_path(::google::protobuf::int32 value); + inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + path() const; + inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_path(); + + // repeated int32 span = 2 [packed = true]; + inline int span_size() const; + inline void clear_span(); + static const int kSpanFieldNumber = 2; + inline ::google::protobuf::int32 span(int index) const; + inline void set_span(int index, ::google::protobuf::int32 value); + inline void add_span(::google::protobuf::int32 value); + inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + span() const; + inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_span(); + + // optional string leading_comments = 3; + inline bool has_leading_comments() const; + inline void clear_leading_comments(); + static const int kLeadingCommentsFieldNumber = 3; + inline const ::std::string& leading_comments() const; + inline void set_leading_comments(const ::std::string& value); + inline void set_leading_comments(const char* value); + inline void set_leading_comments(const char* value, size_t size); + inline ::std::string* mutable_leading_comments(); + inline ::std::string* release_leading_comments(); + inline void set_allocated_leading_comments(::std::string* leading_comments); + + // optional string trailing_comments = 4; + inline bool has_trailing_comments() const; + inline void clear_trailing_comments(); + static const int kTrailingCommentsFieldNumber = 4; + inline const ::std::string& trailing_comments() const; + inline void set_trailing_comments(const ::std::string& value); + inline void set_trailing_comments(const char* value); + inline void set_trailing_comments(const char* value, size_t size); + inline ::std::string* mutable_trailing_comments(); + inline ::std::string* release_trailing_comments(); + inline void set_allocated_trailing_comments(::std::string* trailing_comments); + + // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location) + private: + inline void set_has_leading_comments(); + inline void clear_has_leading_comments(); + inline void set_has_trailing_comments(); + inline void clear_has_trailing_comments(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_; + mutable int _path_cached_byte_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > span_; + mutable int _span_cached_byte_size_; + ::std::string* leading_comments_; + ::std::string* trailing_comments_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static SourceCodeInfo_Location* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message { + public: + SourceCodeInfo(); + virtual ~SourceCodeInfo(); + + SourceCodeInfo(const SourceCodeInfo& from); + + inline SourceCodeInfo& operator=(const SourceCodeInfo& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SourceCodeInfo& default_instance(); + + void Swap(SourceCodeInfo* other); + + // implements Message ---------------------------------------------- + + SourceCodeInfo* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SourceCodeInfo& from); + void MergeFrom(const SourceCodeInfo& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef SourceCodeInfo_Location Location; + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + inline int location_size() const; + inline void clear_location(); + static const int kLocationFieldNumber = 1; + inline const ::google::protobuf::SourceCodeInfo_Location& location(int index) const; + inline ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index); + inline ::google::protobuf::SourceCodeInfo_Location* add_location(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >& + location() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >* + mutable_location(); + + // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static SourceCodeInfo* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// FileDescriptorSet + +// repeated .google.protobuf.FileDescriptorProto file = 1; +inline int FileDescriptorSet::file_size() const { + return file_.size(); +} +inline void FileDescriptorSet::clear_file() { + file_.Clear(); +} +inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const { + return file_.Get(index); +} +inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) { + return file_.Mutable(index); +} +inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() { + return file_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& +FileDescriptorSet::file() const { + return file_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* +FileDescriptorSet::mutable_file() { + return &file_; +} + +// ------------------------------------------------------------------- + +// FileDescriptorProto + +// optional string name = 1; +inline bool FileDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FileDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void FileDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FileDescriptorProto::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& FileDescriptorProto::name() const { + return *name_; +} +inline void FileDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void FileDescriptorProto::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void FileDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* FileDescriptorProto::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* FileDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void FileDescriptorProto::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string package = 2; +inline bool FileDescriptorProto::has_package() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FileDescriptorProto::set_has_package() { + _has_bits_[0] |= 0x00000002u; +} +inline void FileDescriptorProto::clear_has_package() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FileDescriptorProto::clear_package() { + if (package_ != &::google::protobuf::internal::kEmptyString) { + package_->clear(); + } + clear_has_package(); +} +inline const ::std::string& FileDescriptorProto::package() const { + return *package_; +} +inline void FileDescriptorProto::set_package(const ::std::string& value) { + set_has_package(); + if (package_ == &::google::protobuf::internal::kEmptyString) { + package_ = new ::std::string; + } + package_->assign(value); +} +inline void FileDescriptorProto::set_package(const char* value) { + set_has_package(); + if (package_ == &::google::protobuf::internal::kEmptyString) { + package_ = new ::std::string; + } + package_->assign(value); +} +inline void FileDescriptorProto::set_package(const char* value, size_t size) { + set_has_package(); + if (package_ == &::google::protobuf::internal::kEmptyString) { + package_ = new ::std::string; + } + package_->assign(reinterpret_cast(value), size); +} +inline ::std::string* FileDescriptorProto::mutable_package() { + set_has_package(); + if (package_ == &::google::protobuf::internal::kEmptyString) { + package_ = new ::std::string; + } + return package_; +} +inline ::std::string* FileDescriptorProto::release_package() { + clear_has_package(); + if (package_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = package_; + package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void FileDescriptorProto::set_allocated_package(::std::string* package) { + if (package_ != &::google::protobuf::internal::kEmptyString) { + delete package_; + } + if (package) { + set_has_package(); + package_ = package; + } else { + clear_has_package(); + package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// repeated string dependency = 3; +inline int FileDescriptorProto::dependency_size() const { + return dependency_.size(); +} +inline void FileDescriptorProto::clear_dependency() { + dependency_.Clear(); +} +inline const ::std::string& FileDescriptorProto::dependency(int index) const { + return dependency_.Get(index); +} +inline ::std::string* FileDescriptorProto::mutable_dependency(int index) { + return dependency_.Mutable(index); +} +inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) { + dependency_.Mutable(index)->assign(value); +} +inline void FileDescriptorProto::set_dependency(int index, const char* value) { + dependency_.Mutable(index)->assign(value); +} +inline void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) { + dependency_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* FileDescriptorProto::add_dependency() { + return dependency_.Add(); +} +inline void FileDescriptorProto::add_dependency(const ::std::string& value) { + dependency_.Add()->assign(value); +} +inline void FileDescriptorProto::add_dependency(const char* value) { + dependency_.Add()->assign(value); +} +inline void FileDescriptorProto::add_dependency(const char* value, size_t size) { + dependency_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +FileDescriptorProto::dependency() const { + return dependency_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +FileDescriptorProto::mutable_dependency() { + return &dependency_; +} + +// repeated int32 public_dependency = 10; +inline int FileDescriptorProto::public_dependency_size() const { + return public_dependency_.size(); +} +inline void FileDescriptorProto::clear_public_dependency() { + public_dependency_.Clear(); +} +inline ::google::protobuf::int32 FileDescriptorProto::public_dependency(int index) const { + return public_dependency_.Get(index); +} +inline void FileDescriptorProto::set_public_dependency(int index, ::google::protobuf::int32 value) { + public_dependency_.Set(index, value); +} +inline void FileDescriptorProto::add_public_dependency(::google::protobuf::int32 value) { + public_dependency_.Add(value); +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +FileDescriptorProto::public_dependency() const { + return public_dependency_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +FileDescriptorProto::mutable_public_dependency() { + return &public_dependency_; +} + +// repeated int32 weak_dependency = 11; +inline int FileDescriptorProto::weak_dependency_size() const { + return weak_dependency_.size(); +} +inline void FileDescriptorProto::clear_weak_dependency() { + weak_dependency_.Clear(); +} +inline ::google::protobuf::int32 FileDescriptorProto::weak_dependency(int index) const { + return weak_dependency_.Get(index); +} +inline void FileDescriptorProto::set_weak_dependency(int index, ::google::protobuf::int32 value) { + weak_dependency_.Set(index, value); +} +inline void FileDescriptorProto::add_weak_dependency(::google::protobuf::int32 value) { + weak_dependency_.Add(value); +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +FileDescriptorProto::weak_dependency() const { + return weak_dependency_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +FileDescriptorProto::mutable_weak_dependency() { + return &weak_dependency_; +} + +// repeated .google.protobuf.DescriptorProto message_type = 4; +inline int FileDescriptorProto::message_type_size() const { + return message_type_.size(); +} +inline void FileDescriptorProto::clear_message_type() { + message_type_.Clear(); +} +inline const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const { + return message_type_.Get(index); +} +inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) { + return message_type_.Mutable(index); +} +inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() { + return message_type_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& +FileDescriptorProto::message_type() const { + return message_type_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* +FileDescriptorProto::mutable_message_type() { + return &message_type_; +} + +// repeated .google.protobuf.EnumDescriptorProto enum_type = 5; +inline int FileDescriptorProto::enum_type_size() const { + return enum_type_.size(); +} +inline void FileDescriptorProto::clear_enum_type() { + enum_type_.Clear(); +} +inline const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const { + return enum_type_.Get(index); +} +inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) { + return enum_type_.Mutable(index); +} +inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() { + return enum_type_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& +FileDescriptorProto::enum_type() const { + return enum_type_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* +FileDescriptorProto::mutable_enum_type() { + return &enum_type_; +} + +// repeated .google.protobuf.ServiceDescriptorProto service = 6; +inline int FileDescriptorProto::service_size() const { + return service_.size(); +} +inline void FileDescriptorProto::clear_service() { + service_.Clear(); +} +inline const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const { + return service_.Get(index); +} +inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) { + return service_.Mutable(index); +} +inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() { + return service_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& +FileDescriptorProto::service() const { + return service_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* +FileDescriptorProto::mutable_service() { + return &service_; +} + +// repeated .google.protobuf.FieldDescriptorProto extension = 7; +inline int FileDescriptorProto::extension_size() const { + return extension_.size(); +} +inline void FileDescriptorProto::clear_extension() { + extension_.Clear(); +} +inline const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const { + return extension_.Get(index); +} +inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) { + return extension_.Mutable(index); +} +inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() { + return extension_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& +FileDescriptorProto::extension() const { + return extension_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* +FileDescriptorProto::mutable_extension() { + return &extension_; +} + +// optional .google.protobuf.FileOptions options = 8; +inline bool FileDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void FileDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000200u; +} +inline void FileDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000200u; +} +inline void FileDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const { + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) options_ = new ::google::protobuf::FileOptions; + return options_; +} +inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::FileOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void FileDescriptorProto::set_allocated_options(::google::protobuf::FileOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } +} + +// optional .google.protobuf.SourceCodeInfo source_code_info = 9; +inline bool FileDescriptorProto::has_source_code_info() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void FileDescriptorProto::set_has_source_code_info() { + _has_bits_[0] |= 0x00000400u; +} +inline void FileDescriptorProto::clear_has_source_code_info() { + _has_bits_[0] &= ~0x00000400u; +} +inline void FileDescriptorProto::clear_source_code_info() { + if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear(); + clear_has_source_code_info(); +} +inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const { + return source_code_info_ != NULL ? *source_code_info_ : *default_instance_->source_code_info_; +} +inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() { + set_has_source_code_info(); + if (source_code_info_ == NULL) source_code_info_ = new ::google::protobuf::SourceCodeInfo; + return source_code_info_; +} +inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() { + clear_has_source_code_info(); + ::google::protobuf::SourceCodeInfo* temp = source_code_info_; + source_code_info_ = NULL; + return temp; +} +inline void FileDescriptorProto::set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info) { + delete source_code_info_; + source_code_info_ = source_code_info; + if (source_code_info) { + set_has_source_code_info(); + } else { + clear_has_source_code_info(); + } +} + +// ------------------------------------------------------------------- + +// DescriptorProto_ExtensionRange + +// optional int32 start = 1; +inline bool DescriptorProto_ExtensionRange::has_start() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DescriptorProto_ExtensionRange::set_has_start() { + _has_bits_[0] |= 0x00000001u; +} +inline void DescriptorProto_ExtensionRange::clear_has_start() { + _has_bits_[0] &= ~0x00000001u; +} +inline void DescriptorProto_ExtensionRange::clear_start() { + start_ = 0; + clear_has_start(); +} +inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const { + return start_; +} +inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) { + set_has_start(); + start_ = value; +} + +// optional int32 end = 2; +inline bool DescriptorProto_ExtensionRange::has_end() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void DescriptorProto_ExtensionRange::set_has_end() { + _has_bits_[0] |= 0x00000002u; +} +inline void DescriptorProto_ExtensionRange::clear_has_end() { + _has_bits_[0] &= ~0x00000002u; +} +inline void DescriptorProto_ExtensionRange::clear_end() { + end_ = 0; + clear_has_end(); +} +inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const { + return end_; +} +inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) { + set_has_end(); + end_ = value; +} + +// ------------------------------------------------------------------- + +// DescriptorProto + +// optional string name = 1; +inline bool DescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void DescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void DescriptorProto::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& DescriptorProto::name() const { + return *name_; +} +inline void DescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void DescriptorProto::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void DescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* DescriptorProto::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* DescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void DescriptorProto::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// repeated .google.protobuf.FieldDescriptorProto field = 2; +inline int DescriptorProto::field_size() const { + return field_.size(); +} +inline void DescriptorProto::clear_field() { + field_.Clear(); +} +inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const { + return field_.Get(index); +} +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) { + return field_.Mutable(index); +} +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() { + return field_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& +DescriptorProto::field() const { + return field_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* +DescriptorProto::mutable_field() { + return &field_; +} + +// repeated .google.protobuf.FieldDescriptorProto extension = 6; +inline int DescriptorProto::extension_size() const { + return extension_.size(); +} +inline void DescriptorProto::clear_extension() { + extension_.Clear(); +} +inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const { + return extension_.Get(index); +} +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) { + return extension_.Mutable(index); +} +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() { + return extension_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& +DescriptorProto::extension() const { + return extension_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* +DescriptorProto::mutable_extension() { + return &extension_; +} + +// repeated .google.protobuf.DescriptorProto nested_type = 3; +inline int DescriptorProto::nested_type_size() const { + return nested_type_.size(); +} +inline void DescriptorProto::clear_nested_type() { + nested_type_.Clear(); +} +inline const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const { + return nested_type_.Get(index); +} +inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) { + return nested_type_.Mutable(index); +} +inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() { + return nested_type_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& +DescriptorProto::nested_type() const { + return nested_type_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* +DescriptorProto::mutable_nested_type() { + return &nested_type_; +} + +// repeated .google.protobuf.EnumDescriptorProto enum_type = 4; +inline int DescriptorProto::enum_type_size() const { + return enum_type_.size(); +} +inline void DescriptorProto::clear_enum_type() { + enum_type_.Clear(); +} +inline const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const { + return enum_type_.Get(index); +} +inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) { + return enum_type_.Mutable(index); +} +inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() { + return enum_type_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& +DescriptorProto::enum_type() const { + return enum_type_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* +DescriptorProto::mutable_enum_type() { + return &enum_type_; +} + +// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; +inline int DescriptorProto::extension_range_size() const { + return extension_range_.size(); +} +inline void DescriptorProto::clear_extension_range() { + extension_range_.Clear(); +} +inline const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const { + return extension_range_.Get(index); +} +inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) { + return extension_range_.Mutable(index); +} +inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() { + return extension_range_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& +DescriptorProto::extension_range() const { + return extension_range_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* +DescriptorProto::mutable_extension_range() { + return &extension_range_; +} + +// optional .google.protobuf.MessageOptions options = 7; +inline bool DescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void DescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000040u; +} +inline void DescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000040u; +} +inline void DescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const { + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) options_ = new ::google::protobuf::MessageOptions; + return options_; +} +inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::MessageOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void DescriptorProto::set_allocated_options(::google::protobuf::MessageOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } +} + +// ------------------------------------------------------------------- + +// FieldDescriptorProto + +// optional string name = 1; +inline bool FieldDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FieldDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void FieldDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FieldDescriptorProto::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& FieldDescriptorProto::name() const { + return *name_; +} +inline void FieldDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void FieldDescriptorProto::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void FieldDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* FieldDescriptorProto::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* FieldDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void FieldDescriptorProto::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional int32 number = 3; +inline bool FieldDescriptorProto::has_number() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FieldDescriptorProto::set_has_number() { + _has_bits_[0] |= 0x00000002u; +} +inline void FieldDescriptorProto::clear_has_number() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FieldDescriptorProto::clear_number() { + number_ = 0; + clear_has_number(); +} +inline ::google::protobuf::int32 FieldDescriptorProto::number() const { + return number_; +} +inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) { + set_has_number(); + number_ = value; +} + +// optional .google.protobuf.FieldDescriptorProto.Label label = 4; +inline bool FieldDescriptorProto::has_label() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FieldDescriptorProto::set_has_label() { + _has_bits_[0] |= 0x00000004u; +} +inline void FieldDescriptorProto::clear_has_label() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FieldDescriptorProto::clear_label() { + label_ = 1; + clear_has_label(); +} +inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const { + return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_); +} +inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) { + assert(::google::protobuf::FieldDescriptorProto_Label_IsValid(value)); + set_has_label(); + label_ = value; +} + +// optional .google.protobuf.FieldDescriptorProto.Type type = 5; +inline bool FieldDescriptorProto::has_type() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FieldDescriptorProto::set_has_type() { + _has_bits_[0] |= 0x00000008u; +} +inline void FieldDescriptorProto::clear_has_type() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FieldDescriptorProto::clear_type() { + type_ = 1; + clear_has_type(); +} +inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const { + return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_); +} +inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) { + assert(::google::protobuf::FieldDescriptorProto_Type_IsValid(value)); + set_has_type(); + type_ = value; +} + +// optional string type_name = 6; +inline bool FieldDescriptorProto::has_type_name() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FieldDescriptorProto::set_has_type_name() { + _has_bits_[0] |= 0x00000010u; +} +inline void FieldDescriptorProto::clear_has_type_name() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FieldDescriptorProto::clear_type_name() { + if (type_name_ != &::google::protobuf::internal::kEmptyString) { + type_name_->clear(); + } + clear_has_type_name(); +} +inline const ::std::string& FieldDescriptorProto::type_name() const { + return *type_name_; +} +inline void FieldDescriptorProto::set_type_name(const ::std::string& value) { + set_has_type_name(); + if (type_name_ == &::google::protobuf::internal::kEmptyString) { + type_name_ = new ::std::string; + } + type_name_->assign(value); +} +inline void FieldDescriptorProto::set_type_name(const char* value) { + set_has_type_name(); + if (type_name_ == &::google::protobuf::internal::kEmptyString) { + type_name_ = new ::std::string; + } + type_name_->assign(value); +} +inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) { + set_has_type_name(); + if (type_name_ == &::google::protobuf::internal::kEmptyString) { + type_name_ = new ::std::string; + } + type_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* FieldDescriptorProto::mutable_type_name() { + set_has_type_name(); + if (type_name_ == &::google::protobuf::internal::kEmptyString) { + type_name_ = new ::std::string; + } + return type_name_; +} +inline ::std::string* FieldDescriptorProto::release_type_name() { + clear_has_type_name(); + if (type_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = type_name_; + type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void FieldDescriptorProto::set_allocated_type_name(::std::string* type_name) { + if (type_name_ != &::google::protobuf::internal::kEmptyString) { + delete type_name_; + } + if (type_name) { + set_has_type_name(); + type_name_ = type_name; + } else { + clear_has_type_name(); + type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string extendee = 2; +inline bool FieldDescriptorProto::has_extendee() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FieldDescriptorProto::set_has_extendee() { + _has_bits_[0] |= 0x00000020u; +} +inline void FieldDescriptorProto::clear_has_extendee() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FieldDescriptorProto::clear_extendee() { + if (extendee_ != &::google::protobuf::internal::kEmptyString) { + extendee_->clear(); + } + clear_has_extendee(); +} +inline const ::std::string& FieldDescriptorProto::extendee() const { + return *extendee_; +} +inline void FieldDescriptorProto::set_extendee(const ::std::string& value) { + set_has_extendee(); + if (extendee_ == &::google::protobuf::internal::kEmptyString) { + extendee_ = new ::std::string; + } + extendee_->assign(value); +} +inline void FieldDescriptorProto::set_extendee(const char* value) { + set_has_extendee(); + if (extendee_ == &::google::protobuf::internal::kEmptyString) { + extendee_ = new ::std::string; + } + extendee_->assign(value); +} +inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) { + set_has_extendee(); + if (extendee_ == &::google::protobuf::internal::kEmptyString) { + extendee_ = new ::std::string; + } + extendee_->assign(reinterpret_cast(value), size); +} +inline ::std::string* FieldDescriptorProto::mutable_extendee() { + set_has_extendee(); + if (extendee_ == &::google::protobuf::internal::kEmptyString) { + extendee_ = new ::std::string; + } + return extendee_; +} +inline ::std::string* FieldDescriptorProto::release_extendee() { + clear_has_extendee(); + if (extendee_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = extendee_; + extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void FieldDescriptorProto::set_allocated_extendee(::std::string* extendee) { + if (extendee_ != &::google::protobuf::internal::kEmptyString) { + delete extendee_; + } + if (extendee) { + set_has_extendee(); + extendee_ = extendee; + } else { + clear_has_extendee(); + extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string default_value = 7; +inline bool FieldDescriptorProto::has_default_value() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void FieldDescriptorProto::set_has_default_value() { + _has_bits_[0] |= 0x00000040u; +} +inline void FieldDescriptorProto::clear_has_default_value() { + _has_bits_[0] &= ~0x00000040u; +} +inline void FieldDescriptorProto::clear_default_value() { + if (default_value_ != &::google::protobuf::internal::kEmptyString) { + default_value_->clear(); + } + clear_has_default_value(); +} +inline const ::std::string& FieldDescriptorProto::default_value() const { + return *default_value_; +} +inline void FieldDescriptorProto::set_default_value(const ::std::string& value) { + set_has_default_value(); + if (default_value_ == &::google::protobuf::internal::kEmptyString) { + default_value_ = new ::std::string; + } + default_value_->assign(value); +} +inline void FieldDescriptorProto::set_default_value(const char* value) { + set_has_default_value(); + if (default_value_ == &::google::protobuf::internal::kEmptyString) { + default_value_ = new ::std::string; + } + default_value_->assign(value); +} +inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) { + set_has_default_value(); + if (default_value_ == &::google::protobuf::internal::kEmptyString) { + default_value_ = new ::std::string; + } + default_value_->assign(reinterpret_cast(value), size); +} +inline ::std::string* FieldDescriptorProto::mutable_default_value() { + set_has_default_value(); + if (default_value_ == &::google::protobuf::internal::kEmptyString) { + default_value_ = new ::std::string; + } + return default_value_; +} +inline ::std::string* FieldDescriptorProto::release_default_value() { + clear_has_default_value(); + if (default_value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = default_value_; + default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void FieldDescriptorProto::set_allocated_default_value(::std::string* default_value) { + if (default_value_ != &::google::protobuf::internal::kEmptyString) { + delete default_value_; + } + if (default_value) { + set_has_default_value(); + default_value_ = default_value; + } else { + clear_has_default_value(); + default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional .google.protobuf.FieldOptions options = 8; +inline bool FieldDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void FieldDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000080u; +} +inline void FieldDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000080u; +} +inline void FieldDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const { + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) options_ = new ::google::protobuf::FieldOptions; + return options_; +} +inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::FieldOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } +} + +// ------------------------------------------------------------------- + +// EnumDescriptorProto + +// optional string name = 1; +inline bool EnumDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void EnumDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void EnumDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void EnumDescriptorProto::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& EnumDescriptorProto::name() const { + return *name_; +} +inline void EnumDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void EnumDescriptorProto::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void EnumDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* EnumDescriptorProto::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* EnumDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void EnumDescriptorProto::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// repeated .google.protobuf.EnumValueDescriptorProto value = 2; +inline int EnumDescriptorProto::value_size() const { + return value_.size(); +} +inline void EnumDescriptorProto::clear_value() { + value_.Clear(); +} +inline const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const { + return value_.Get(index); +} +inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) { + return value_.Mutable(index); +} +inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() { + return value_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& +EnumDescriptorProto::value() const { + return value_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* +EnumDescriptorProto::mutable_value() { + return &value_; +} + +// optional .google.protobuf.EnumOptions options = 3; +inline bool EnumDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void EnumDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000004u; +} +inline void EnumDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000004u; +} +inline void EnumDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const { + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) options_ = new ::google::protobuf::EnumOptions; + return options_; +} +inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::EnumOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } +} + +// ------------------------------------------------------------------- + +// EnumValueDescriptorProto + +// optional string name = 1; +inline bool EnumValueDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void EnumValueDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void EnumValueDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void EnumValueDescriptorProto::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& EnumValueDescriptorProto::name() const { + return *name_; +} +inline void EnumValueDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void EnumValueDescriptorProto::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* EnumValueDescriptorProto::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* EnumValueDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void EnumValueDescriptorProto::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional int32 number = 2; +inline bool EnumValueDescriptorProto::has_number() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void EnumValueDescriptorProto::set_has_number() { + _has_bits_[0] |= 0x00000002u; +} +inline void EnumValueDescriptorProto::clear_has_number() { + _has_bits_[0] &= ~0x00000002u; +} +inline void EnumValueDescriptorProto::clear_number() { + number_ = 0; + clear_has_number(); +} +inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const { + return number_; +} +inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) { + set_has_number(); + number_ = value; +} + +// optional .google.protobuf.EnumValueOptions options = 3; +inline bool EnumValueDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void EnumValueDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000004u; +} +inline void EnumValueDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000004u; +} +inline void EnumValueDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const { + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) options_ = new ::google::protobuf::EnumValueOptions; + return options_; +} +inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::EnumValueOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void EnumValueDescriptorProto::set_allocated_options(::google::protobuf::EnumValueOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } +} + +// ------------------------------------------------------------------- + +// ServiceDescriptorProto + +// optional string name = 1; +inline bool ServiceDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ServiceDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void ServiceDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ServiceDescriptorProto::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& ServiceDescriptorProto::name() const { + return *name_; +} +inline void ServiceDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void ServiceDescriptorProto::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void ServiceDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* ServiceDescriptorProto::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* ServiceDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void ServiceDescriptorProto::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// repeated .google.protobuf.MethodDescriptorProto method = 2; +inline int ServiceDescriptorProto::method_size() const { + return method_.size(); +} +inline void ServiceDescriptorProto::clear_method() { + method_.Clear(); +} +inline const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const { + return method_.Get(index); +} +inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) { + return method_.Mutable(index); +} +inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() { + return method_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& +ServiceDescriptorProto::method() const { + return method_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* +ServiceDescriptorProto::mutable_method() { + return &method_; +} + +// optional .google.protobuf.ServiceOptions options = 3; +inline bool ServiceDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ServiceDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000004u; +} +inline void ServiceDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000004u; +} +inline void ServiceDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const { + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) options_ = new ::google::protobuf::ServiceOptions; + return options_; +} +inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::ServiceOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void ServiceDescriptorProto::set_allocated_options(::google::protobuf::ServiceOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } +} + +// ------------------------------------------------------------------- + +// MethodDescriptorProto + +// optional string name = 1; +inline bool MethodDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MethodDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void MethodDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MethodDescriptorProto::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& MethodDescriptorProto::name() const { + return *name_; +} +inline void MethodDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void MethodDescriptorProto::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void MethodDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* MethodDescriptorProto::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* MethodDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void MethodDescriptorProto::set_allocated_name(::std::string* name) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (name) { + set_has_name(); + name_ = name; + } else { + clear_has_name(); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string input_type = 2; +inline bool MethodDescriptorProto::has_input_type() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MethodDescriptorProto::set_has_input_type() { + _has_bits_[0] |= 0x00000002u; +} +inline void MethodDescriptorProto::clear_has_input_type() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MethodDescriptorProto::clear_input_type() { + if (input_type_ != &::google::protobuf::internal::kEmptyString) { + input_type_->clear(); + } + clear_has_input_type(); +} +inline const ::std::string& MethodDescriptorProto::input_type() const { + return *input_type_; +} +inline void MethodDescriptorProto::set_input_type(const ::std::string& value) { + set_has_input_type(); + if (input_type_ == &::google::protobuf::internal::kEmptyString) { + input_type_ = new ::std::string; + } + input_type_->assign(value); +} +inline void MethodDescriptorProto::set_input_type(const char* value) { + set_has_input_type(); + if (input_type_ == &::google::protobuf::internal::kEmptyString) { + input_type_ = new ::std::string; + } + input_type_->assign(value); +} +inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) { + set_has_input_type(); + if (input_type_ == &::google::protobuf::internal::kEmptyString) { + input_type_ = new ::std::string; + } + input_type_->assign(reinterpret_cast(value), size); +} +inline ::std::string* MethodDescriptorProto::mutable_input_type() { + set_has_input_type(); + if (input_type_ == &::google::protobuf::internal::kEmptyString) { + input_type_ = new ::std::string; + } + return input_type_; +} +inline ::std::string* MethodDescriptorProto::release_input_type() { + clear_has_input_type(); + if (input_type_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = input_type_; + input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void MethodDescriptorProto::set_allocated_input_type(::std::string* input_type) { + if (input_type_ != &::google::protobuf::internal::kEmptyString) { + delete input_type_; + } + if (input_type) { + set_has_input_type(); + input_type_ = input_type; + } else { + clear_has_input_type(); + input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string output_type = 3; +inline bool MethodDescriptorProto::has_output_type() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MethodDescriptorProto::set_has_output_type() { + _has_bits_[0] |= 0x00000004u; +} +inline void MethodDescriptorProto::clear_has_output_type() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MethodDescriptorProto::clear_output_type() { + if (output_type_ != &::google::protobuf::internal::kEmptyString) { + output_type_->clear(); + } + clear_has_output_type(); +} +inline const ::std::string& MethodDescriptorProto::output_type() const { + return *output_type_; +} +inline void MethodDescriptorProto::set_output_type(const ::std::string& value) { + set_has_output_type(); + if (output_type_ == &::google::protobuf::internal::kEmptyString) { + output_type_ = new ::std::string; + } + output_type_->assign(value); +} +inline void MethodDescriptorProto::set_output_type(const char* value) { + set_has_output_type(); + if (output_type_ == &::google::protobuf::internal::kEmptyString) { + output_type_ = new ::std::string; + } + output_type_->assign(value); +} +inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) { + set_has_output_type(); + if (output_type_ == &::google::protobuf::internal::kEmptyString) { + output_type_ = new ::std::string; + } + output_type_->assign(reinterpret_cast(value), size); +} +inline ::std::string* MethodDescriptorProto::mutable_output_type() { + set_has_output_type(); + if (output_type_ == &::google::protobuf::internal::kEmptyString) { + output_type_ = new ::std::string; + } + return output_type_; +} +inline ::std::string* MethodDescriptorProto::release_output_type() { + clear_has_output_type(); + if (output_type_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = output_type_; + output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void MethodDescriptorProto::set_allocated_output_type(::std::string* output_type) { + if (output_type_ != &::google::protobuf::internal::kEmptyString) { + delete output_type_; + } + if (output_type) { + set_has_output_type(); + output_type_ = output_type; + } else { + clear_has_output_type(); + output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional .google.protobuf.MethodOptions options = 4; +inline bool MethodDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void MethodDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000008u; +} +inline void MethodDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000008u; +} +inline void MethodDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const { + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) options_ = new ::google::protobuf::MethodOptions; + return options_; +} +inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::MethodOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void MethodDescriptorProto::set_allocated_options(::google::protobuf::MethodOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } +} + +// ------------------------------------------------------------------- + +// FileOptions + +// optional string java_package = 1; +inline bool FileOptions::has_java_package() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FileOptions::set_has_java_package() { + _has_bits_[0] |= 0x00000001u; +} +inline void FileOptions::clear_has_java_package() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FileOptions::clear_java_package() { + if (java_package_ != &::google::protobuf::internal::kEmptyString) { + java_package_->clear(); + } + clear_has_java_package(); +} +inline const ::std::string& FileOptions::java_package() const { + return *java_package_; +} +inline void FileOptions::set_java_package(const ::std::string& value) { + set_has_java_package(); + if (java_package_ == &::google::protobuf::internal::kEmptyString) { + java_package_ = new ::std::string; + } + java_package_->assign(value); +} +inline void FileOptions::set_java_package(const char* value) { + set_has_java_package(); + if (java_package_ == &::google::protobuf::internal::kEmptyString) { + java_package_ = new ::std::string; + } + java_package_->assign(value); +} +inline void FileOptions::set_java_package(const char* value, size_t size) { + set_has_java_package(); + if (java_package_ == &::google::protobuf::internal::kEmptyString) { + java_package_ = new ::std::string; + } + java_package_->assign(reinterpret_cast(value), size); +} +inline ::std::string* FileOptions::mutable_java_package() { + set_has_java_package(); + if (java_package_ == &::google::protobuf::internal::kEmptyString) { + java_package_ = new ::std::string; + } + return java_package_; +} +inline ::std::string* FileOptions::release_java_package() { + clear_has_java_package(); + if (java_package_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = java_package_; + java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void FileOptions::set_allocated_java_package(::std::string* java_package) { + if (java_package_ != &::google::protobuf::internal::kEmptyString) { + delete java_package_; + } + if (java_package) { + set_has_java_package(); + java_package_ = java_package; + } else { + clear_has_java_package(); + java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string java_outer_classname = 8; +inline bool FileOptions::has_java_outer_classname() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FileOptions::set_has_java_outer_classname() { + _has_bits_[0] |= 0x00000002u; +} +inline void FileOptions::clear_has_java_outer_classname() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FileOptions::clear_java_outer_classname() { + if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) { + java_outer_classname_->clear(); + } + clear_has_java_outer_classname(); +} +inline const ::std::string& FileOptions::java_outer_classname() const { + return *java_outer_classname_; +} +inline void FileOptions::set_java_outer_classname(const ::std::string& value) { + set_has_java_outer_classname(); + if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) { + java_outer_classname_ = new ::std::string; + } + java_outer_classname_->assign(value); +} +inline void FileOptions::set_java_outer_classname(const char* value) { + set_has_java_outer_classname(); + if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) { + java_outer_classname_ = new ::std::string; + } + java_outer_classname_->assign(value); +} +inline void FileOptions::set_java_outer_classname(const char* value, size_t size) { + set_has_java_outer_classname(); + if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) { + java_outer_classname_ = new ::std::string; + } + java_outer_classname_->assign(reinterpret_cast(value), size); +} +inline ::std::string* FileOptions::mutable_java_outer_classname() { + set_has_java_outer_classname(); + if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) { + java_outer_classname_ = new ::std::string; + } + return java_outer_classname_; +} +inline ::std::string* FileOptions::release_java_outer_classname() { + clear_has_java_outer_classname(); + if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = java_outer_classname_; + java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void FileOptions::set_allocated_java_outer_classname(::std::string* java_outer_classname) { + if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) { + delete java_outer_classname_; + } + if (java_outer_classname) { + set_has_java_outer_classname(); + java_outer_classname_ = java_outer_classname; + } else { + clear_has_java_outer_classname(); + java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional bool java_multiple_files = 10 [default = false]; +inline bool FileOptions::has_java_multiple_files() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FileOptions::set_has_java_multiple_files() { + _has_bits_[0] |= 0x00000004u; +} +inline void FileOptions::clear_has_java_multiple_files() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FileOptions::clear_java_multiple_files() { + java_multiple_files_ = false; + clear_has_java_multiple_files(); +} +inline bool FileOptions::java_multiple_files() const { + return java_multiple_files_; +} +inline void FileOptions::set_java_multiple_files(bool value) { + set_has_java_multiple_files(); + java_multiple_files_ = value; +} + +// optional bool java_generate_equals_and_hash = 20 [default = false]; +inline bool FileOptions::has_java_generate_equals_and_hash() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FileOptions::set_has_java_generate_equals_and_hash() { + _has_bits_[0] |= 0x00000008u; +} +inline void FileOptions::clear_has_java_generate_equals_and_hash() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FileOptions::clear_java_generate_equals_and_hash() { + java_generate_equals_and_hash_ = false; + clear_has_java_generate_equals_and_hash(); +} +inline bool FileOptions::java_generate_equals_and_hash() const { + return java_generate_equals_and_hash_; +} +inline void FileOptions::set_java_generate_equals_and_hash(bool value) { + set_has_java_generate_equals_and_hash(); + java_generate_equals_and_hash_ = value; +} + +// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; +inline bool FileOptions::has_optimize_for() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FileOptions::set_has_optimize_for() { + _has_bits_[0] |= 0x00000010u; +} +inline void FileOptions::clear_has_optimize_for() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FileOptions::clear_optimize_for() { + optimize_for_ = 1; + clear_has_optimize_for(); +} +inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const { + return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_); +} +inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) { + assert(::google::protobuf::FileOptions_OptimizeMode_IsValid(value)); + set_has_optimize_for(); + optimize_for_ = value; +} + +// optional string go_package = 11; +inline bool FileOptions::has_go_package() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FileOptions::set_has_go_package() { + _has_bits_[0] |= 0x00000020u; +} +inline void FileOptions::clear_has_go_package() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FileOptions::clear_go_package() { + if (go_package_ != &::google::protobuf::internal::kEmptyString) { + go_package_->clear(); + } + clear_has_go_package(); +} +inline const ::std::string& FileOptions::go_package() const { + return *go_package_; +} +inline void FileOptions::set_go_package(const ::std::string& value) { + set_has_go_package(); + if (go_package_ == &::google::protobuf::internal::kEmptyString) { + go_package_ = new ::std::string; + } + go_package_->assign(value); +} +inline void FileOptions::set_go_package(const char* value) { + set_has_go_package(); + if (go_package_ == &::google::protobuf::internal::kEmptyString) { + go_package_ = new ::std::string; + } + go_package_->assign(value); +} +inline void FileOptions::set_go_package(const char* value, size_t size) { + set_has_go_package(); + if (go_package_ == &::google::protobuf::internal::kEmptyString) { + go_package_ = new ::std::string; + } + go_package_->assign(reinterpret_cast(value), size); +} +inline ::std::string* FileOptions::mutable_go_package() { + set_has_go_package(); + if (go_package_ == &::google::protobuf::internal::kEmptyString) { + go_package_ = new ::std::string; + } + return go_package_; +} +inline ::std::string* FileOptions::release_go_package() { + clear_has_go_package(); + if (go_package_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = go_package_; + go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void FileOptions::set_allocated_go_package(::std::string* go_package) { + if (go_package_ != &::google::protobuf::internal::kEmptyString) { + delete go_package_; + } + if (go_package) { + set_has_go_package(); + go_package_ = go_package; + } else { + clear_has_go_package(); + go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional bool cc_generic_services = 16 [default = false]; +inline bool FileOptions::has_cc_generic_services() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void FileOptions::set_has_cc_generic_services() { + _has_bits_[0] |= 0x00000040u; +} +inline void FileOptions::clear_has_cc_generic_services() { + _has_bits_[0] &= ~0x00000040u; +} +inline void FileOptions::clear_cc_generic_services() { + cc_generic_services_ = false; + clear_has_cc_generic_services(); +} +inline bool FileOptions::cc_generic_services() const { + return cc_generic_services_; +} +inline void FileOptions::set_cc_generic_services(bool value) { + set_has_cc_generic_services(); + cc_generic_services_ = value; +} + +// optional bool java_generic_services = 17 [default = false]; +inline bool FileOptions::has_java_generic_services() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void FileOptions::set_has_java_generic_services() { + _has_bits_[0] |= 0x00000080u; +} +inline void FileOptions::clear_has_java_generic_services() { + _has_bits_[0] &= ~0x00000080u; +} +inline void FileOptions::clear_java_generic_services() { + java_generic_services_ = false; + clear_has_java_generic_services(); +} +inline bool FileOptions::java_generic_services() const { + return java_generic_services_; +} +inline void FileOptions::set_java_generic_services(bool value) { + set_has_java_generic_services(); + java_generic_services_ = value; +} + +// optional bool py_generic_services = 18 [default = false]; +inline bool FileOptions::has_py_generic_services() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void FileOptions::set_has_py_generic_services() { + _has_bits_[0] |= 0x00000100u; +} +inline void FileOptions::clear_has_py_generic_services() { + _has_bits_[0] &= ~0x00000100u; +} +inline void FileOptions::clear_py_generic_services() { + py_generic_services_ = false; + clear_has_py_generic_services(); +} +inline bool FileOptions::py_generic_services() const { + return py_generic_services_; +} +inline void FileOptions::set_py_generic_services(bool value) { + set_has_py_generic_services(); + py_generic_services_ = value; +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int FileOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void FileOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) { + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +FileOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +FileOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// MessageOptions + +// optional bool message_set_wire_format = 1 [default = false]; +inline bool MessageOptions::has_message_set_wire_format() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MessageOptions::set_has_message_set_wire_format() { + _has_bits_[0] |= 0x00000001u; +} +inline void MessageOptions::clear_has_message_set_wire_format() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MessageOptions::clear_message_set_wire_format() { + message_set_wire_format_ = false; + clear_has_message_set_wire_format(); +} +inline bool MessageOptions::message_set_wire_format() const { + return message_set_wire_format_; +} +inline void MessageOptions::set_message_set_wire_format(bool value) { + set_has_message_set_wire_format(); + message_set_wire_format_ = value; +} + +// optional bool no_standard_descriptor_accessor = 2 [default = false]; +inline bool MessageOptions::has_no_standard_descriptor_accessor() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MessageOptions::set_has_no_standard_descriptor_accessor() { + _has_bits_[0] |= 0x00000002u; +} +inline void MessageOptions::clear_has_no_standard_descriptor_accessor() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MessageOptions::clear_no_standard_descriptor_accessor() { + no_standard_descriptor_accessor_ = false; + clear_has_no_standard_descriptor_accessor(); +} +inline bool MessageOptions::no_standard_descriptor_accessor() const { + return no_standard_descriptor_accessor_; +} +inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) { + set_has_no_standard_descriptor_accessor(); + no_standard_descriptor_accessor_ = value; +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int MessageOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void MessageOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) { + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +MessageOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +MessageOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// FieldOptions + +// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; +inline bool FieldOptions::has_ctype() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FieldOptions::set_has_ctype() { + _has_bits_[0] |= 0x00000001u; +} +inline void FieldOptions::clear_has_ctype() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FieldOptions::clear_ctype() { + ctype_ = 0; + clear_has_ctype(); +} +inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const { + return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_); +} +inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) { + assert(::google::protobuf::FieldOptions_CType_IsValid(value)); + set_has_ctype(); + ctype_ = value; +} + +// optional bool packed = 2; +inline bool FieldOptions::has_packed() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FieldOptions::set_has_packed() { + _has_bits_[0] |= 0x00000002u; +} +inline void FieldOptions::clear_has_packed() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FieldOptions::clear_packed() { + packed_ = false; + clear_has_packed(); +} +inline bool FieldOptions::packed() const { + return packed_; +} +inline void FieldOptions::set_packed(bool value) { + set_has_packed(); + packed_ = value; +} + +// optional bool lazy = 5 [default = false]; +inline bool FieldOptions::has_lazy() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FieldOptions::set_has_lazy() { + _has_bits_[0] |= 0x00000004u; +} +inline void FieldOptions::clear_has_lazy() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FieldOptions::clear_lazy() { + lazy_ = false; + clear_has_lazy(); +} +inline bool FieldOptions::lazy() const { + return lazy_; +} +inline void FieldOptions::set_lazy(bool value) { + set_has_lazy(); + lazy_ = value; +} + +// optional bool deprecated = 3 [default = false]; +inline bool FieldOptions::has_deprecated() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FieldOptions::set_has_deprecated() { + _has_bits_[0] |= 0x00000008u; +} +inline void FieldOptions::clear_has_deprecated() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FieldOptions::clear_deprecated() { + deprecated_ = false; + clear_has_deprecated(); +} +inline bool FieldOptions::deprecated() const { + return deprecated_; +} +inline void FieldOptions::set_deprecated(bool value) { + set_has_deprecated(); + deprecated_ = value; +} + +// optional string experimental_map_key = 9; +inline bool FieldOptions::has_experimental_map_key() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FieldOptions::set_has_experimental_map_key() { + _has_bits_[0] |= 0x00000010u; +} +inline void FieldOptions::clear_has_experimental_map_key() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FieldOptions::clear_experimental_map_key() { + if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) { + experimental_map_key_->clear(); + } + clear_has_experimental_map_key(); +} +inline const ::std::string& FieldOptions::experimental_map_key() const { + return *experimental_map_key_; +} +inline void FieldOptions::set_experimental_map_key(const ::std::string& value) { + set_has_experimental_map_key(); + if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) { + experimental_map_key_ = new ::std::string; + } + experimental_map_key_->assign(value); +} +inline void FieldOptions::set_experimental_map_key(const char* value) { + set_has_experimental_map_key(); + if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) { + experimental_map_key_ = new ::std::string; + } + experimental_map_key_->assign(value); +} +inline void FieldOptions::set_experimental_map_key(const char* value, size_t size) { + set_has_experimental_map_key(); + if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) { + experimental_map_key_ = new ::std::string; + } + experimental_map_key_->assign(reinterpret_cast(value), size); +} +inline ::std::string* FieldOptions::mutable_experimental_map_key() { + set_has_experimental_map_key(); + if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) { + experimental_map_key_ = new ::std::string; + } + return experimental_map_key_; +} +inline ::std::string* FieldOptions::release_experimental_map_key() { + clear_has_experimental_map_key(); + if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = experimental_map_key_; + experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void FieldOptions::set_allocated_experimental_map_key(::std::string* experimental_map_key) { + if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) { + delete experimental_map_key_; + } + if (experimental_map_key) { + set_has_experimental_map_key(); + experimental_map_key_ = experimental_map_key; + } else { + clear_has_experimental_map_key(); + experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional bool weak = 10 [default = false]; +inline bool FieldOptions::has_weak() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FieldOptions::set_has_weak() { + _has_bits_[0] |= 0x00000020u; +} +inline void FieldOptions::clear_has_weak() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FieldOptions::clear_weak() { + weak_ = false; + clear_has_weak(); +} +inline bool FieldOptions::weak() const { + return weak_; +} +inline void FieldOptions::set_weak(bool value) { + set_has_weak(); + weak_ = value; +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int FieldOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void FieldOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) { + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +FieldOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +FieldOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// EnumOptions + +// optional bool allow_alias = 2 [default = true]; +inline bool EnumOptions::has_allow_alias() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void EnumOptions::set_has_allow_alias() { + _has_bits_[0] |= 0x00000001u; +} +inline void EnumOptions::clear_has_allow_alias() { + _has_bits_[0] &= ~0x00000001u; +} +inline void EnumOptions::clear_allow_alias() { + allow_alias_ = true; + clear_has_allow_alias(); +} +inline bool EnumOptions::allow_alias() const { + return allow_alias_; +} +inline void EnumOptions::set_allow_alias(bool value) { + set_has_allow_alias(); + allow_alias_ = value; +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int EnumOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void EnumOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) { + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +EnumOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +EnumOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// EnumValueOptions + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int EnumValueOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void EnumValueOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) { + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +EnumValueOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +EnumValueOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// ServiceOptions + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int ServiceOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void ServiceOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) { + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +ServiceOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +ServiceOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// MethodOptions + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int MethodOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void MethodOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) { + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +MethodOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +MethodOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// UninterpretedOption_NamePart + +// required string name_part = 1; +inline bool UninterpretedOption_NamePart::has_name_part() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void UninterpretedOption_NamePart::set_has_name_part() { + _has_bits_[0] |= 0x00000001u; +} +inline void UninterpretedOption_NamePart::clear_has_name_part() { + _has_bits_[0] &= ~0x00000001u; +} +inline void UninterpretedOption_NamePart::clear_name_part() { + if (name_part_ != &::google::protobuf::internal::kEmptyString) { + name_part_->clear(); + } + clear_has_name_part(); +} +inline const ::std::string& UninterpretedOption_NamePart::name_part() const { + return *name_part_; +} +inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) { + set_has_name_part(); + if (name_part_ == &::google::protobuf::internal::kEmptyString) { + name_part_ = new ::std::string; + } + name_part_->assign(value); +} +inline void UninterpretedOption_NamePart::set_name_part(const char* value) { + set_has_name_part(); + if (name_part_ == &::google::protobuf::internal::kEmptyString) { + name_part_ = new ::std::string; + } + name_part_->assign(value); +} +inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) { + set_has_name_part(); + if (name_part_ == &::google::protobuf::internal::kEmptyString) { + name_part_ = new ::std::string; + } + name_part_->assign(reinterpret_cast(value), size); +} +inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() { + set_has_name_part(); + if (name_part_ == &::google::protobuf::internal::kEmptyString) { + name_part_ = new ::std::string; + } + return name_part_; +} +inline ::std::string* UninterpretedOption_NamePart::release_name_part() { + clear_has_name_part(); + if (name_part_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_part_; + name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void UninterpretedOption_NamePart::set_allocated_name_part(::std::string* name_part) { + if (name_part_ != &::google::protobuf::internal::kEmptyString) { + delete name_part_; + } + if (name_part) { + set_has_name_part(); + name_part_ = name_part; + } else { + clear_has_name_part(); + name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// required bool is_extension = 2; +inline bool UninterpretedOption_NamePart::has_is_extension() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void UninterpretedOption_NamePart::set_has_is_extension() { + _has_bits_[0] |= 0x00000002u; +} +inline void UninterpretedOption_NamePart::clear_has_is_extension() { + _has_bits_[0] &= ~0x00000002u; +} +inline void UninterpretedOption_NamePart::clear_is_extension() { + is_extension_ = false; + clear_has_is_extension(); +} +inline bool UninterpretedOption_NamePart::is_extension() const { + return is_extension_; +} +inline void UninterpretedOption_NamePart::set_is_extension(bool value) { + set_has_is_extension(); + is_extension_ = value; +} + +// ------------------------------------------------------------------- + +// UninterpretedOption + +// repeated .google.protobuf.UninterpretedOption.NamePart name = 2; +inline int UninterpretedOption::name_size() const { + return name_.size(); +} +inline void UninterpretedOption::clear_name() { + name_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const { + return name_.Get(index); +} +inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) { + return name_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() { + return name_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >& +UninterpretedOption::name() const { + return name_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >* +UninterpretedOption::mutable_name() { + return &name_; +} + +// optional string identifier_value = 3; +inline bool UninterpretedOption::has_identifier_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void UninterpretedOption::set_has_identifier_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void UninterpretedOption::clear_has_identifier_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void UninterpretedOption::clear_identifier_value() { + if (identifier_value_ != &::google::protobuf::internal::kEmptyString) { + identifier_value_->clear(); + } + clear_has_identifier_value(); +} +inline const ::std::string& UninterpretedOption::identifier_value() const { + return *identifier_value_; +} +inline void UninterpretedOption::set_identifier_value(const ::std::string& value) { + set_has_identifier_value(); + if (identifier_value_ == &::google::protobuf::internal::kEmptyString) { + identifier_value_ = new ::std::string; + } + identifier_value_->assign(value); +} +inline void UninterpretedOption::set_identifier_value(const char* value) { + set_has_identifier_value(); + if (identifier_value_ == &::google::protobuf::internal::kEmptyString) { + identifier_value_ = new ::std::string; + } + identifier_value_->assign(value); +} +inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) { + set_has_identifier_value(); + if (identifier_value_ == &::google::protobuf::internal::kEmptyString) { + identifier_value_ = new ::std::string; + } + identifier_value_->assign(reinterpret_cast(value), size); +} +inline ::std::string* UninterpretedOption::mutable_identifier_value() { + set_has_identifier_value(); + if (identifier_value_ == &::google::protobuf::internal::kEmptyString) { + identifier_value_ = new ::std::string; + } + return identifier_value_; +} +inline ::std::string* UninterpretedOption::release_identifier_value() { + clear_has_identifier_value(); + if (identifier_value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = identifier_value_; + identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void UninterpretedOption::set_allocated_identifier_value(::std::string* identifier_value) { + if (identifier_value_ != &::google::protobuf::internal::kEmptyString) { + delete identifier_value_; + } + if (identifier_value) { + set_has_identifier_value(); + identifier_value_ = identifier_value; + } else { + clear_has_identifier_value(); + identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional uint64 positive_int_value = 4; +inline bool UninterpretedOption::has_positive_int_value() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void UninterpretedOption::set_has_positive_int_value() { + _has_bits_[0] |= 0x00000004u; +} +inline void UninterpretedOption::clear_has_positive_int_value() { + _has_bits_[0] &= ~0x00000004u; +} +inline void UninterpretedOption::clear_positive_int_value() { + positive_int_value_ = GOOGLE_ULONGLONG(0); + clear_has_positive_int_value(); +} +inline ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const { + return positive_int_value_; +} +inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) { + set_has_positive_int_value(); + positive_int_value_ = value; +} + +// optional int64 negative_int_value = 5; +inline bool UninterpretedOption::has_negative_int_value() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void UninterpretedOption::set_has_negative_int_value() { + _has_bits_[0] |= 0x00000008u; +} +inline void UninterpretedOption::clear_has_negative_int_value() { + _has_bits_[0] &= ~0x00000008u; +} +inline void UninterpretedOption::clear_negative_int_value() { + negative_int_value_ = GOOGLE_LONGLONG(0); + clear_has_negative_int_value(); +} +inline ::google::protobuf::int64 UninterpretedOption::negative_int_value() const { + return negative_int_value_; +} +inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) { + set_has_negative_int_value(); + negative_int_value_ = value; +} + +// optional double double_value = 6; +inline bool UninterpretedOption::has_double_value() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void UninterpretedOption::set_has_double_value() { + _has_bits_[0] |= 0x00000010u; +} +inline void UninterpretedOption::clear_has_double_value() { + _has_bits_[0] &= ~0x00000010u; +} +inline void UninterpretedOption::clear_double_value() { + double_value_ = 0; + clear_has_double_value(); +} +inline double UninterpretedOption::double_value() const { + return double_value_; +} +inline void UninterpretedOption::set_double_value(double value) { + set_has_double_value(); + double_value_ = value; +} + +// optional bytes string_value = 7; +inline bool UninterpretedOption::has_string_value() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void UninterpretedOption::set_has_string_value() { + _has_bits_[0] |= 0x00000020u; +} +inline void UninterpretedOption::clear_has_string_value() { + _has_bits_[0] &= ~0x00000020u; +} +inline void UninterpretedOption::clear_string_value() { + if (string_value_ != &::google::protobuf::internal::kEmptyString) { + string_value_->clear(); + } + clear_has_string_value(); +} +inline const ::std::string& UninterpretedOption::string_value() const { + return *string_value_; +} +inline void UninterpretedOption::set_string_value(const ::std::string& value) { + set_has_string_value(); + if (string_value_ == &::google::protobuf::internal::kEmptyString) { + string_value_ = new ::std::string; + } + string_value_->assign(value); +} +inline void UninterpretedOption::set_string_value(const char* value) { + set_has_string_value(); + if (string_value_ == &::google::protobuf::internal::kEmptyString) { + string_value_ = new ::std::string; + } + string_value_->assign(value); +} +inline void UninterpretedOption::set_string_value(const void* value, size_t size) { + set_has_string_value(); + if (string_value_ == &::google::protobuf::internal::kEmptyString) { + string_value_ = new ::std::string; + } + string_value_->assign(reinterpret_cast(value), size); +} +inline ::std::string* UninterpretedOption::mutable_string_value() { + set_has_string_value(); + if (string_value_ == &::google::protobuf::internal::kEmptyString) { + string_value_ = new ::std::string; + } + return string_value_; +} +inline ::std::string* UninterpretedOption::release_string_value() { + clear_has_string_value(); + if (string_value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = string_value_; + string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void UninterpretedOption::set_allocated_string_value(::std::string* string_value) { + if (string_value_ != &::google::protobuf::internal::kEmptyString) { + delete string_value_; + } + if (string_value) { + set_has_string_value(); + string_value_ = string_value; + } else { + clear_has_string_value(); + string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string aggregate_value = 8; +inline bool UninterpretedOption::has_aggregate_value() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void UninterpretedOption::set_has_aggregate_value() { + _has_bits_[0] |= 0x00000040u; +} +inline void UninterpretedOption::clear_has_aggregate_value() { + _has_bits_[0] &= ~0x00000040u; +} +inline void UninterpretedOption::clear_aggregate_value() { + if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) { + aggregate_value_->clear(); + } + clear_has_aggregate_value(); +} +inline const ::std::string& UninterpretedOption::aggregate_value() const { + return *aggregate_value_; +} +inline void UninterpretedOption::set_aggregate_value(const ::std::string& value) { + set_has_aggregate_value(); + if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) { + aggregate_value_ = new ::std::string; + } + aggregate_value_->assign(value); +} +inline void UninterpretedOption::set_aggregate_value(const char* value) { + set_has_aggregate_value(); + if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) { + aggregate_value_ = new ::std::string; + } + aggregate_value_->assign(value); +} +inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) { + set_has_aggregate_value(); + if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) { + aggregate_value_ = new ::std::string; + } + aggregate_value_->assign(reinterpret_cast(value), size); +} +inline ::std::string* UninterpretedOption::mutable_aggregate_value() { + set_has_aggregate_value(); + if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) { + aggregate_value_ = new ::std::string; + } + return aggregate_value_; +} +inline ::std::string* UninterpretedOption::release_aggregate_value() { + clear_has_aggregate_value(); + if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = aggregate_value_; + aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void UninterpretedOption::set_allocated_aggregate_value(::std::string* aggregate_value) { + if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) { + delete aggregate_value_; + } + if (aggregate_value) { + set_has_aggregate_value(); + aggregate_value_ = aggregate_value; + } else { + clear_has_aggregate_value(); + aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// SourceCodeInfo_Location + +// repeated int32 path = 1 [packed = true]; +inline int SourceCodeInfo_Location::path_size() const { + return path_.size(); +} +inline void SourceCodeInfo_Location::clear_path() { + path_.Clear(); +} +inline ::google::protobuf::int32 SourceCodeInfo_Location::path(int index) const { + return path_.Get(index); +} +inline void SourceCodeInfo_Location::set_path(int index, ::google::protobuf::int32 value) { + path_.Set(index, value); +} +inline void SourceCodeInfo_Location::add_path(::google::protobuf::int32 value) { + path_.Add(value); +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +SourceCodeInfo_Location::path() const { + return path_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +SourceCodeInfo_Location::mutable_path() { + return &path_; +} + +// repeated int32 span = 2 [packed = true]; +inline int SourceCodeInfo_Location::span_size() const { + return span_.size(); +} +inline void SourceCodeInfo_Location::clear_span() { + span_.Clear(); +} +inline ::google::protobuf::int32 SourceCodeInfo_Location::span(int index) const { + return span_.Get(index); +} +inline void SourceCodeInfo_Location::set_span(int index, ::google::protobuf::int32 value) { + span_.Set(index, value); +} +inline void SourceCodeInfo_Location::add_span(::google::protobuf::int32 value) { + span_.Add(value); +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +SourceCodeInfo_Location::span() const { + return span_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +SourceCodeInfo_Location::mutable_span() { + return &span_; +} + +// optional string leading_comments = 3; +inline bool SourceCodeInfo_Location::has_leading_comments() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void SourceCodeInfo_Location::set_has_leading_comments() { + _has_bits_[0] |= 0x00000004u; +} +inline void SourceCodeInfo_Location::clear_has_leading_comments() { + _has_bits_[0] &= ~0x00000004u; +} +inline void SourceCodeInfo_Location::clear_leading_comments() { + if (leading_comments_ != &::google::protobuf::internal::kEmptyString) { + leading_comments_->clear(); + } + clear_has_leading_comments(); +} +inline const ::std::string& SourceCodeInfo_Location::leading_comments() const { + return *leading_comments_; +} +inline void SourceCodeInfo_Location::set_leading_comments(const ::std::string& value) { + set_has_leading_comments(); + if (leading_comments_ == &::google::protobuf::internal::kEmptyString) { + leading_comments_ = new ::std::string; + } + leading_comments_->assign(value); +} +inline void SourceCodeInfo_Location::set_leading_comments(const char* value) { + set_has_leading_comments(); + if (leading_comments_ == &::google::protobuf::internal::kEmptyString) { + leading_comments_ = new ::std::string; + } + leading_comments_->assign(value); +} +inline void SourceCodeInfo_Location::set_leading_comments(const char* value, size_t size) { + set_has_leading_comments(); + if (leading_comments_ == &::google::protobuf::internal::kEmptyString) { + leading_comments_ = new ::std::string; + } + leading_comments_->assign(reinterpret_cast(value), size); +} +inline ::std::string* SourceCodeInfo_Location::mutable_leading_comments() { + set_has_leading_comments(); + if (leading_comments_ == &::google::protobuf::internal::kEmptyString) { + leading_comments_ = new ::std::string; + } + return leading_comments_; +} +inline ::std::string* SourceCodeInfo_Location::release_leading_comments() { + clear_has_leading_comments(); + if (leading_comments_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = leading_comments_; + leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void SourceCodeInfo_Location::set_allocated_leading_comments(::std::string* leading_comments) { + if (leading_comments_ != &::google::protobuf::internal::kEmptyString) { + delete leading_comments_; + } + if (leading_comments) { + set_has_leading_comments(); + leading_comments_ = leading_comments; + } else { + clear_has_leading_comments(); + leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string trailing_comments = 4; +inline bool SourceCodeInfo_Location::has_trailing_comments() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void SourceCodeInfo_Location::set_has_trailing_comments() { + _has_bits_[0] |= 0x00000008u; +} +inline void SourceCodeInfo_Location::clear_has_trailing_comments() { + _has_bits_[0] &= ~0x00000008u; +} +inline void SourceCodeInfo_Location::clear_trailing_comments() { + if (trailing_comments_ != &::google::protobuf::internal::kEmptyString) { + trailing_comments_->clear(); + } + clear_has_trailing_comments(); +} +inline const ::std::string& SourceCodeInfo_Location::trailing_comments() const { + return *trailing_comments_; +} +inline void SourceCodeInfo_Location::set_trailing_comments(const ::std::string& value) { + set_has_trailing_comments(); + if (trailing_comments_ == &::google::protobuf::internal::kEmptyString) { + trailing_comments_ = new ::std::string; + } + trailing_comments_->assign(value); +} +inline void SourceCodeInfo_Location::set_trailing_comments(const char* value) { + set_has_trailing_comments(); + if (trailing_comments_ == &::google::protobuf::internal::kEmptyString) { + trailing_comments_ = new ::std::string; + } + trailing_comments_->assign(value); +} +inline void SourceCodeInfo_Location::set_trailing_comments(const char* value, size_t size) { + set_has_trailing_comments(); + if (trailing_comments_ == &::google::protobuf::internal::kEmptyString) { + trailing_comments_ = new ::std::string; + } + trailing_comments_->assign(reinterpret_cast(value), size); +} +inline ::std::string* SourceCodeInfo_Location::mutable_trailing_comments() { + set_has_trailing_comments(); + if (trailing_comments_ == &::google::protobuf::internal::kEmptyString) { + trailing_comments_ = new ::std::string; + } + return trailing_comments_; +} +inline ::std::string* SourceCodeInfo_Location::release_trailing_comments() { + clear_has_trailing_comments(); + if (trailing_comments_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = trailing_comments_; + trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void SourceCodeInfo_Location::set_allocated_trailing_comments(::std::string* trailing_comments) { + if (trailing_comments_ != &::google::protobuf::internal::kEmptyString) { + delete trailing_comments_; + } + if (trailing_comments) { + set_has_trailing_comments(); + trailing_comments_ = trailing_comments; + } else { + clear_has_trailing_comments(); + trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// ------------------------------------------------------------------- + +// SourceCodeInfo + +// repeated .google.protobuf.SourceCodeInfo.Location location = 1; +inline int SourceCodeInfo::location_size() const { + return location_.size(); +} +inline void SourceCodeInfo::clear_location() { + location_.Clear(); +} +inline const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const { + return location_.Get(index); +} +inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) { + return location_.Mutable(index); +} +inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() { + return location_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >& +SourceCodeInfo::location() const { + return location_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >* +SourceCodeInfo::mutable_location() { + return &location_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Type>() { + return ::google::protobuf::FieldDescriptorProto_Type_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Label>() { + return ::google::protobuf::FieldDescriptorProto_Label_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FileOptions_OptimizeMode>() { + return ::google::protobuf::FileOptions_OptimizeMode_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_CType>() { + return ::google::protobuf::FieldOptions_CType_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.proto new file mode 100644 index 0000000..a785f79 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor.proto @@ -0,0 +1,620 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + + + +package google.protobuf; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field whithout harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; + optional int32 end = 2; + } + repeated ExtensionRange extension_range = 5; + + optional MessageOptions options = 7; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + TYPE_GROUP = 10; // Tag-delimited aggregate. + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + }; + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REQUIRED = 2; + LABEL_REPEATED = 3; + // TODO(sanjay): Should we add LABEL_MAP? + }; + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be either TYPE_ENUM or TYPE_MESSAGE. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + optional string default_value = 7; + + optional FieldOptions options = 8; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; +} + + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Object-C plugin) and your porject website (if available) -- there's no need +// to explain how you intend to use them. Usually you only need one extension +// number. You can declare multiple options with only one extension number by +// putting them in a sub-message. See the Custom Options section of the docs +// for examples: +// http://code.google.com/apis/protocolbuffers/docs/proto.html#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + + // If set, all the classes from the .proto file are wrapped in a single + // outer class with the given name. This applies to both Proto1 + // (equivalent to the old "--one_java_file" option) and Proto2 (where + // a .proto always translates to a single class, but you may want to + // explicitly choose the class name). + optional string java_outer_classname = 8; + + // If set true, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the outer class + // named by java_outer_classname. However, the outer class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [default=false]; + + // If set true, then the Java code generator will generate equals() and + // hashCode() methods for all messages defined in the .proto file. This is + // purely a speed optimization, as the AbstractMessage base class includes + // reflection-based implementations of these methods. + optional bool java_generate_equals_and_hash = 20 [default=false]; + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default=SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. There is no default. + optional string go_package = 11; + + + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of proto2. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default=false]; + optional bool java_generic_services = 17 [default=false]; + optional bool py_generic_services = 18 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default=false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + optional CType ctype = 1 [default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. + optional bool packed = 2; + + + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outher message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + optional bool lazy = 5 [default=false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default=false]; + + // EXPERIMENTAL. DO NOT USE. + // For "map" fields, the name of the field in the enclosed type that + // is the key for this map. For example, suppose we have: + // message Item { + // required string name = 1; + // required string value = 2; + // } + // message Config { + // repeated Item items = 1 [experimental_map_key="name"]; + // } + // In this situation, the map key for Item will be set to "name". + // TODO: Fully-implement this, then remove the "experimental_" prefix. + optional string experimental_map_key = 9; + + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to false to disallow mapping different tag names to a same + // value. + optional bool allow_alias = 2 [default=true]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // 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". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendent. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed=true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed=true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + optional string leading_comments = 3; + optional string trailing_comments = 4; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database.cc new file mode 100644 index 0000000..35e459d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database.cc @@ -0,0 +1,541 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +DescriptorDatabase::~DescriptorDatabase() {} + +// =================================================================== + +template +bool SimpleDescriptorDatabase::DescriptorIndex::AddFile( + const FileDescriptorProto& file, + Value value) { + if (!InsertIfNotPresent(&by_name_, file.name(), value)) { + GOOGLE_LOG(ERROR) << "File already exists in database: " << file.name(); + return false; + } + + // We must be careful here -- calling file.package() if file.has_package() is + // false could access an uninitialized static-storage variable if we are being + // run at startup time. + string path = file.has_package() ? file.package() : string(); + if (!path.empty()) path += '.'; + + for (int i = 0; i < file.message_type_size(); i++) { + if (!AddSymbol(path + file.message_type(i).name(), value)) return false; + if (!AddNestedExtensions(file.message_type(i), value)) return false; + } + for (int i = 0; i < file.enum_type_size(); i++) { + if (!AddSymbol(path + file.enum_type(i).name(), value)) return false; + } + for (int i = 0; i < file.extension_size(); i++) { + if (!AddSymbol(path + file.extension(i).name(), value)) return false; + if (!AddExtension(file.extension(i), value)) return false; + } + for (int i = 0; i < file.service_size(); i++) { + if (!AddSymbol(path + file.service(i).name(), value)) return false; + } + + return true; +} + +template +bool SimpleDescriptorDatabase::DescriptorIndex::AddSymbol( + const string& name, Value value) { + // We need to make sure not to violate our map invariant. + + // If the symbol name is invalid it could break our lookup algorithm (which + // relies on the fact that '.' sorts before all other characters that are + // valid in symbol names). + if (!ValidateSymbolName(name)) { + GOOGLE_LOG(ERROR) << "Invalid symbol name: " << name; + return false; + } + + // Try to look up the symbol to make sure a super-symbol doesn't already + // exist. + typename map::iterator iter = FindLastLessOrEqual(name); + + if (iter == by_symbol_.end()) { + // Apparently the map is currently empty. Just insert and be done with it. + by_symbol_.insert(typename map::value_type(name, value)); + return true; + } + + if (IsSubSymbol(iter->first, name)) { + GOOGLE_LOG(ERROR) << "Symbol name \"" << name << "\" conflicts with the existing " + "symbol \"" << iter->first << "\"."; + return false; + } + + // OK, that worked. Now we have to make sure that no symbol in the map is + // a sub-symbol of the one we are inserting. The only symbol which could + // be so is the first symbol that is greater than the new symbol. Since + // |iter| points at the last symbol that is less than or equal, we just have + // to increment it. + ++iter; + + if (iter != by_symbol_.end() && IsSubSymbol(name, iter->first)) { + GOOGLE_LOG(ERROR) << "Symbol name \"" << name << "\" conflicts with the existing " + "symbol \"" << iter->first << "\"."; + return false; + } + + // OK, no conflicts. + + // Insert the new symbol using the iterator as a hint, the new entry will + // appear immediately before the one the iterator is pointing at. + by_symbol_.insert(iter, typename map::value_type(name, value)); + + return true; +} + +template +bool SimpleDescriptorDatabase::DescriptorIndex::AddNestedExtensions( + const DescriptorProto& message_type, + Value value) { + for (int i = 0; i < message_type.nested_type_size(); i++) { + if (!AddNestedExtensions(message_type.nested_type(i), value)) return false; + } + for (int i = 0; i < message_type.extension_size(); i++) { + if (!AddExtension(message_type.extension(i), value)) return false; + } + return true; +} + +template +bool SimpleDescriptorDatabase::DescriptorIndex::AddExtension( + const FieldDescriptorProto& field, + Value value) { + if (!field.extendee().empty() && field.extendee()[0] == '.') { + // The extension is fully-qualified. We can use it as a lookup key in + // the by_symbol_ table. + if (!InsertIfNotPresent(&by_extension_, + make_pair(field.extendee().substr(1), + field.number()), + value)) { + GOOGLE_LOG(ERROR) << "Extension conflicts with extension already in database: " + "extend " << field.extendee() << " { " + << field.name() << " = " << field.number() << " }"; + return false; + } + } else { + // Not fully-qualified. We can't really do anything here, unfortunately. + // We don't consider this an error, though, because the descriptor is + // valid. + } + return true; +} + +template +Value SimpleDescriptorDatabase::DescriptorIndex::FindFile( + const string& filename) { + return FindWithDefault(by_name_, filename, Value()); +} + +template +Value SimpleDescriptorDatabase::DescriptorIndex::FindSymbol( + const string& name) { + typename map::iterator iter = FindLastLessOrEqual(name); + + return (iter != by_symbol_.end() && IsSubSymbol(iter->first, name)) ? + iter->second : Value(); +} + +template +Value SimpleDescriptorDatabase::DescriptorIndex::FindExtension( + const string& containing_type, + int field_number) { + return FindWithDefault(by_extension_, + make_pair(containing_type, field_number), + Value()); +} + +template +bool SimpleDescriptorDatabase::DescriptorIndex::FindAllExtensionNumbers( + const string& containing_type, + vector* output) { + typename map, Value >::const_iterator it = + by_extension_.lower_bound(make_pair(containing_type, 0)); + bool success = false; + + for (; it != by_extension_.end() && it->first.first == containing_type; + ++it) { + output->push_back(it->first.second); + success = true; + } + + return success; +} + +template +typename map::iterator +SimpleDescriptorDatabase::DescriptorIndex::FindLastLessOrEqual( + const string& name) { + // Find the last key in the map which sorts less than or equal to the + // symbol name. Since upper_bound() returns the *first* key that sorts + // *greater* than the input, we want the element immediately before that. + typename map::iterator iter = by_symbol_.upper_bound(name); + if (iter != by_symbol_.begin()) --iter; + return iter; +} + +template +bool SimpleDescriptorDatabase::DescriptorIndex::IsSubSymbol( + const string& sub_symbol, const string& super_symbol) { + return sub_symbol == super_symbol || + (HasPrefixString(super_symbol, sub_symbol) && + super_symbol[sub_symbol.size()] == '.'); +} + +template +bool SimpleDescriptorDatabase::DescriptorIndex::ValidateSymbolName( + const string& name) { + for (int i = 0; i < name.size(); i++) { + // I don't trust ctype.h due to locales. :( + if (name[i] != '.' && name[i] != '_' && + (name[i] < '0' || name[i] > '9') && + (name[i] < 'A' || name[i] > 'Z') && + (name[i] < 'a' || name[i] > 'z')) { + return false; + } + } + return true; +} + +// ------------------------------------------------------------------- + +SimpleDescriptorDatabase::SimpleDescriptorDatabase() {} +SimpleDescriptorDatabase::~SimpleDescriptorDatabase() { + STLDeleteElements(&files_to_delete_); +} + +bool SimpleDescriptorDatabase::Add(const FileDescriptorProto& file) { + FileDescriptorProto* new_file = new FileDescriptorProto; + new_file->CopyFrom(file); + return AddAndOwn(new_file); +} + +bool SimpleDescriptorDatabase::AddAndOwn(const FileDescriptorProto* file) { + files_to_delete_.push_back(file); + return index_.AddFile(*file, file); +} + +bool SimpleDescriptorDatabase::FindFileByName( + const string& filename, + FileDescriptorProto* output) { + return MaybeCopy(index_.FindFile(filename), output); +} + +bool SimpleDescriptorDatabase::FindFileContainingSymbol( + const string& symbol_name, + FileDescriptorProto* output) { + return MaybeCopy(index_.FindSymbol(symbol_name), output); +} + +bool SimpleDescriptorDatabase::FindFileContainingExtension( + const string& containing_type, + int field_number, + FileDescriptorProto* output) { + return MaybeCopy(index_.FindExtension(containing_type, field_number), output); +} + +bool SimpleDescriptorDatabase::FindAllExtensionNumbers( + const string& extendee_type, + vector* output) { + return index_.FindAllExtensionNumbers(extendee_type, output); +} + +bool SimpleDescriptorDatabase::MaybeCopy(const FileDescriptorProto* file, + FileDescriptorProto* output) { + if (file == NULL) return false; + output->CopyFrom(*file); + return true; +} + +// ------------------------------------------------------------------- + +EncodedDescriptorDatabase::EncodedDescriptorDatabase() {} +EncodedDescriptorDatabase::~EncodedDescriptorDatabase() { + for (int i = 0; i < files_to_delete_.size(); i++) { + operator delete(files_to_delete_[i]); + } +} + +bool EncodedDescriptorDatabase::Add( + const void* encoded_file_descriptor, int size) { + FileDescriptorProto file; + if (file.ParseFromArray(encoded_file_descriptor, size)) { + return index_.AddFile(file, make_pair(encoded_file_descriptor, size)); + } else { + GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to " + "EncodedDescriptorDatabase::Add()."; + return false; + } +} + +bool EncodedDescriptorDatabase::AddCopy( + const void* encoded_file_descriptor, int size) { + void* copy = operator new(size); + memcpy(copy, encoded_file_descriptor, size); + files_to_delete_.push_back(copy); + return Add(copy, size); +} + +bool EncodedDescriptorDatabase::FindFileByName( + const string& filename, + FileDescriptorProto* output) { + return MaybeParse(index_.FindFile(filename), output); +} + +bool EncodedDescriptorDatabase::FindFileContainingSymbol( + const string& symbol_name, + FileDescriptorProto* output) { + return MaybeParse(index_.FindSymbol(symbol_name), output); +} + +bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol( + const string& symbol_name, + string* output) { + pair encoded_file = index_.FindSymbol(symbol_name); + if (encoded_file.first == NULL) return false; + + // Optimization: The name should be the first field in the encoded message. + // Try to just read it directly. + io::CodedInputStream input(reinterpret_cast(encoded_file.first), + encoded_file.second); + + const uint32 kNameTag = internal::WireFormatLite::MakeTag( + FileDescriptorProto::kNameFieldNumber, + internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + + if (input.ReadTag() == kNameTag) { + // Success! + return internal::WireFormatLite::ReadString(&input, output); + } else { + // Slow path. Parse whole message. + FileDescriptorProto file_proto; + if (!file_proto.ParseFromArray(encoded_file.first, encoded_file.second)) { + return false; + } + *output = file_proto.name(); + return true; + } +} + +bool EncodedDescriptorDatabase::FindFileContainingExtension( + const string& containing_type, + int field_number, + FileDescriptorProto* output) { + return MaybeParse(index_.FindExtension(containing_type, field_number), + output); +} + +bool EncodedDescriptorDatabase::FindAllExtensionNumbers( + const string& extendee_type, + vector* output) { + return index_.FindAllExtensionNumbers(extendee_type, output); +} + +bool EncodedDescriptorDatabase::MaybeParse( + pair encoded_file, + FileDescriptorProto* output) { + if (encoded_file.first == NULL) return false; + return output->ParseFromArray(encoded_file.first, encoded_file.second); +} + +// =================================================================== + +DescriptorPoolDatabase::DescriptorPoolDatabase(const DescriptorPool& pool) + : pool_(pool) {} +DescriptorPoolDatabase::~DescriptorPoolDatabase() {} + +bool DescriptorPoolDatabase::FindFileByName( + const string& filename, + FileDescriptorProto* output) { + const FileDescriptor* file = pool_.FindFileByName(filename); + if (file == NULL) return false; + output->Clear(); + file->CopyTo(output); + return true; +} + +bool DescriptorPoolDatabase::FindFileContainingSymbol( + const string& symbol_name, + FileDescriptorProto* output) { + const FileDescriptor* file = pool_.FindFileContainingSymbol(symbol_name); + if (file == NULL) return false; + output->Clear(); + file->CopyTo(output); + return true; +} + +bool DescriptorPoolDatabase::FindFileContainingExtension( + const string& containing_type, + int field_number, + FileDescriptorProto* output) { + const Descriptor* extendee = pool_.FindMessageTypeByName(containing_type); + if (extendee == NULL) return false; + + const FieldDescriptor* extension = + pool_.FindExtensionByNumber(extendee, field_number); + if (extension == NULL) return false; + + output->Clear(); + extension->file()->CopyTo(output); + return true; +} + +bool DescriptorPoolDatabase::FindAllExtensionNumbers( + const string& extendee_type, + vector* output) { + const Descriptor* extendee = pool_.FindMessageTypeByName(extendee_type); + if (extendee == NULL) return false; + + vector extensions; + pool_.FindAllExtensions(extendee, &extensions); + + for (int i = 0; i < extensions.size(); ++i) { + output->push_back(extensions[i]->number()); + } + + return true; +} + +// =================================================================== + +MergedDescriptorDatabase::MergedDescriptorDatabase( + DescriptorDatabase* source1, + DescriptorDatabase* source2) { + sources_.push_back(source1); + sources_.push_back(source2); +} +MergedDescriptorDatabase::MergedDescriptorDatabase( + const vector& sources) + : sources_(sources) {} +MergedDescriptorDatabase::~MergedDescriptorDatabase() {} + +bool MergedDescriptorDatabase::FindFileByName( + const string& filename, + FileDescriptorProto* output) { + for (int i = 0; i < sources_.size(); i++) { + if (sources_[i]->FindFileByName(filename, output)) { + return true; + } + } + return false; +} + +bool MergedDescriptorDatabase::FindFileContainingSymbol( + const string& symbol_name, + FileDescriptorProto* output) { + for (int i = 0; i < sources_.size(); i++) { + if (sources_[i]->FindFileContainingSymbol(symbol_name, output)) { + // The symbol was found in source i. However, if one of the previous + // sources defines a file with the same name (which presumably doesn't + // contain the symbol, since it wasn't found in that source), then we + // must hide it from the caller. + FileDescriptorProto temp; + for (int j = 0; j < i; j++) { + if (sources_[j]->FindFileByName(output->name(), &temp)) { + // Found conflicting file in a previous source. + return false; + } + } + return true; + } + } + return false; +} + +bool MergedDescriptorDatabase::FindFileContainingExtension( + const string& containing_type, + int field_number, + FileDescriptorProto* output) { + for (int i = 0; i < sources_.size(); i++) { + if (sources_[i]->FindFileContainingExtension( + containing_type, field_number, output)) { + // The symbol was found in source i. However, if one of the previous + // sources defines a file with the same name (which presumably doesn't + // contain the symbol, since it wasn't found in that source), then we + // must hide it from the caller. + FileDescriptorProto temp; + for (int j = 0; j < i; j++) { + if (sources_[j]->FindFileByName(output->name(), &temp)) { + // Found conflicting file in a previous source. + return false; + } + } + return true; + } + } + return false; +} + +bool MergedDescriptorDatabase::FindAllExtensionNumbers( + const string& extendee_type, + vector* output) { + set merged_results; + vector results; + bool success = false; + + for (int i = 0; i < sources_.size(); i++) { + if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) { + copy(results.begin(), results.end(), + insert_iterator >(merged_results, merged_results.begin())); + success = true; + } + results.clear(); + } + + copy(merged_results.begin(), merged_results.end(), + insert_iterator >(*output, output->end())); + + return success; +} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database.h new file mode 100644 index 0000000..2ccb145 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database.h @@ -0,0 +1,367 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Interface for manipulating databases of descriptors. + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ +#define GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +// Defined in this file. +class DescriptorDatabase; +class SimpleDescriptorDatabase; +class EncodedDescriptorDatabase; +class DescriptorPoolDatabase; +class MergedDescriptorDatabase; + +// Abstract interface for a database of descriptors. +// +// This is useful if you want to create a DescriptorPool which loads +// descriptors on-demand from some sort of large database. If the database +// is large, it may be inefficient to enumerate every .proto file inside it +// calling DescriptorPool::BuildFile() for each one. Instead, a DescriptorPool +// can be created which wraps a DescriptorDatabase and only builds particular +// descriptors when they are needed. +class LIBPROTOBUF_EXPORT DescriptorDatabase { + public: + inline DescriptorDatabase() {} + virtual ~DescriptorDatabase(); + + // Find a file by file name. Fills in in *output and returns true if found. + // Otherwise, returns false, leaving the contents of *output undefined. + virtual bool FindFileByName(const string& filename, + FileDescriptorProto* output) = 0; + + // Find the file that declares the given fully-qualified symbol name. + // If found, fills in *output and returns true, otherwise returns false + // and leaves *output undefined. + virtual bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output) = 0; + + // Find the file which defines an extension extending the given message type + // with the given field number. If found, fills in *output and returns true, + // otherwise returns false and leaves *output undefined. containing_type + // must be a fully-qualified type name. + virtual bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output) = 0; + + // Finds the tag numbers used by all known extensions of + // extendee_type, and appends them to output in an undefined + // order. This method is best-effort: it's not guaranteed that the + // database will find all extensions, and it's not guaranteed that + // FindFileContainingExtension will return true on all of the found + // numbers. Returns true if the search was successful, otherwise + // returns false and leaves output unchanged. + // + // This method has a default implementation that always returns + // false. + virtual bool FindAllExtensionNumbers(const string& extendee_type, + vector* output) { + return false; + } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase); +}; + +// A DescriptorDatabase into which you can insert files manually. +// +// FindFileContainingSymbol() is fully-implemented. When you add a file, its +// symbols will be indexed for this purpose. Note that the implementation +// may return false positives, but only if it isn't possible for the symbol +// to be defined in any other file. In particular, if a file defines a symbol +// "Foo", then searching for "Foo.[anything]" will match that file. This way, +// the database does not need to aggressively index all children of a symbol. +// +// FindFileContainingExtension() is mostly-implemented. It works if and only +// if the original FieldDescriptorProto defining the extension has a +// fully-qualified type name in its "extendee" field (i.e. starts with a '.'). +// If the extendee is a relative name, SimpleDescriptorDatabase will not +// attempt to resolve the type, so it will not know what type the extension is +// extending. Therefore, calling FindFileContainingExtension() with the +// extension's containing type will never actually find that extension. Note +// that this is an unlikely problem, as all FileDescriptorProtos created by the +// protocol compiler (as well as ones created by calling +// FileDescriptor::CopyTo()) will always use fully-qualified names for all +// types. You only need to worry if you are constructing FileDescriptorProtos +// yourself, or are calling compiler::Parser directly. +class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { + public: + SimpleDescriptorDatabase(); + ~SimpleDescriptorDatabase(); + + // Adds the FileDescriptorProto to the database, making a copy. The object + // can be deleted after Add() returns. Returns false if the file conflicted + // with a file already in the database, in which case an error will have + // been written to GOOGLE_LOG(ERROR). + bool Add(const FileDescriptorProto& file); + + // Adds the FileDescriptorProto to the database and takes ownership of it. + bool AddAndOwn(const FileDescriptorProto* file); + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const string& filename, + FileDescriptorProto* output); + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output); + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output); + bool FindAllExtensionNumbers(const string& extendee_type, + vector* output); + + private: + // So that it can use DescriptorIndex. + friend class EncodedDescriptorDatabase; + + // An index mapping file names, symbol names, and extension numbers to + // some sort of values. + template + class DescriptorIndex { + public: + // Helpers to recursively add particular descriptors and all their contents + // to the index. + bool AddFile(const FileDescriptorProto& file, + Value value); + bool AddSymbol(const string& name, Value value); + bool AddNestedExtensions(const DescriptorProto& message_type, + Value value); + bool AddExtension(const FieldDescriptorProto& field, + Value value); + + Value FindFile(const string& filename); + Value FindSymbol(const string& name); + Value FindExtension(const string& containing_type, int field_number); + bool FindAllExtensionNumbers(const string& containing_type, + vector* output); + + private: + map by_name_; + map by_symbol_; + map, Value> by_extension_; + + // Invariant: The by_symbol_ map does not contain any symbols which are + // prefixes of other symbols in the map. For example, "foo.bar" is a + // prefix of "foo.bar.baz" (but is not a prefix of "foo.barbaz"). + // + // This invariant is important because it means that given a symbol name, + // we can find a key in the map which is a prefix of the symbol in O(lg n) + // time, and we know that there is at most one such key. + // + // The prefix lookup algorithm works like so: + // 1) Find the last key in the map which is less than or equal to the + // search key. + // 2) If the found key is a prefix of the search key, then return it. + // Otherwise, there is no match. + // + // I am sure this algorithm has been described elsewhere, but since I + // wasn't able to find it quickly I will instead prove that it works + // myself. The key to the algorithm is that if a match exists, step (1) + // will find it. Proof: + // 1) Define the "search key" to be the key we are looking for, the "found + // key" to be the key found in step (1), and the "match key" to be the + // key which actually matches the serach key (i.e. the key we're trying + // to find). + // 2) The found key must be less than or equal to the search key by + // definition. + // 3) The match key must also be less than or equal to the search key + // (because it is a prefix). + // 4) The match key cannot be greater than the found key, because if it + // were, then step (1) of the algorithm would have returned the match + // key instead (since it finds the *greatest* key which is less than or + // equal to the search key). + // 5) Therefore, the found key must be between the match key and the search + // key, inclusive. + // 6) Since the search key must be a sub-symbol of the match key, if it is + // not equal to the match key, then search_key[match_key.size()] must + // be '.'. + // 7) Since '.' sorts before any other character that is valid in a symbol + // name, then if the found key is not equal to the match key, then + // found_key[match_key.size()] must also be '.', because any other value + // would make it sort after the search key. + // 8) Therefore, if the found key is not equal to the match key, then the + // found key must be a sub-symbol of the match key. However, this would + // contradict our map invariant which says that no symbol in the map is + // a sub-symbol of any other. + // 9) Therefore, the found key must match the match key. + // + // The above proof assumes the match key exists. In the case that the + // match key does not exist, then step (1) will return some other symbol. + // That symbol cannot be a super-symbol of the search key since if it were, + // then it would be a match, and we're assuming the match key doesn't exist. + // Therefore, step 2 will correctly return no match. + + // Find the last entry in the by_symbol_ map whose key is less than or + // equal to the given name. + typename map::iterator FindLastLessOrEqual( + const string& name); + + // True if either the arguments are equal or super_symbol identifies a + // parent symbol of sub_symbol (e.g. "foo.bar" is a parent of + // "foo.bar.baz", but not a parent of "foo.barbaz"). + bool IsSubSymbol(const string& sub_symbol, const string& super_symbol); + + // Returns true if and only if all characters in the name are alphanumerics, + // underscores, or periods. + bool ValidateSymbolName(const string& name); + }; + + + DescriptorIndex index_; + vector files_to_delete_; + + // If file is non-NULL, copy it into *output and return true, otherwise + // return false. + bool MaybeCopy(const FileDescriptorProto* file, + FileDescriptorProto* output); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleDescriptorDatabase); +}; + +// Very similar to SimpleDescriptorDatabase, but stores all the descriptors +// as raw bytes and generally tries to use as little memory as possible. +// +// The same caveats regarding FindFileContainingExtension() apply as with +// SimpleDescriptorDatabase. +class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase { + public: + EncodedDescriptorDatabase(); + ~EncodedDescriptorDatabase(); + + // Adds the FileDescriptorProto to the database. The descriptor is provided + // in encoded form. The database does not make a copy of the bytes, nor + // does it take ownership; it's up to the caller to make sure the bytes + // remain valid for the life of the database. Returns false and logs an error + // if the bytes are not a valid FileDescriptorProto or if the file conflicted + // with a file already in the database. + bool Add(const void* encoded_file_descriptor, int size); + + // Like Add(), but makes a copy of the data, so that the caller does not + // need to keep it around. + bool AddCopy(const void* encoded_file_descriptor, int size); + + // Like FindFileContainingSymbol but returns only the name of the file. + bool FindNameOfFileContainingSymbol(const string& symbol_name, + string* output); + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const string& filename, + FileDescriptorProto* output); + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output); + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output); + bool FindAllExtensionNumbers(const string& extendee_type, + vector* output); + + private: + SimpleDescriptorDatabase::DescriptorIndex > index_; + vector files_to_delete_; + + // If encoded_file.first is non-NULL, parse the data into *output and return + // true, otherwise return false. + bool MaybeParse(pair encoded_file, + FileDescriptorProto* output); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EncodedDescriptorDatabase); +}; + +// A DescriptorDatabase that fetches files from a given pool. +class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase { + public: + DescriptorPoolDatabase(const DescriptorPool& pool); + ~DescriptorPoolDatabase(); + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const string& filename, + FileDescriptorProto* output); + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output); + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output); + bool FindAllExtensionNumbers(const string& extendee_type, + vector* output); + + private: + const DescriptorPool& pool_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPoolDatabase); +}; + +// A DescriptorDatabase that wraps two or more others. It first searches the +// first database and, if that fails, tries the second, and so on. +class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase { + public: + // Merge just two databases. The sources remain property of the caller. + MergedDescriptorDatabase(DescriptorDatabase* source1, + DescriptorDatabase* source2); + // Merge more than two databases. The sources remain property of the caller. + // The vector may be deleted after the constructor returns but the + // DescriptorDatabases need to stick around. + MergedDescriptorDatabase(const vector& sources); + ~MergedDescriptorDatabase(); + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const string& filename, + FileDescriptorProto* output); + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output); + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output); + // Merges the results of calling all databases. Returns true iff any + // of the databases returned true. + bool FindAllExtensionNumbers(const string& extendee_type, + vector* output); + + private: + vector sources_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database_unittest.cc new file mode 100644 index 0000000..ac72ddc --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_database_unittest.cc @@ -0,0 +1,748 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file makes extensive use of RFC 3092. :) + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace { + +static void AddToDatabase(SimpleDescriptorDatabase* database, + const char* file_text) { + FileDescriptorProto file_proto; + EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); + database->Add(file_proto); +} + +static void ExpectContainsType(const FileDescriptorProto& proto, + const string& type_name) { + for (int i = 0; i < proto.message_type_size(); i++) { + if (proto.message_type(i).name() == type_name) return; + } + ADD_FAILURE() << "\"" << proto.name() + << "\" did not contain expected type \"" + << type_name << "\"."; +} + +// =================================================================== + +#if GTEST_HAS_PARAM_TEST + +// SimpleDescriptorDatabase, EncodedDescriptorDatabase, and +// DescriptorPoolDatabase call for very similar tests. Instead of writing +// three nearly-identical sets of tests, we use parameterized tests to apply +// the same code to all three. + +// The parameterized test runs against a DescriptarDatabaseTestCase. We have +// implementations for each of the three classes we want to test. +class DescriptorDatabaseTestCase { + public: + virtual ~DescriptorDatabaseTestCase() {} + + virtual DescriptorDatabase* GetDatabase() = 0; + virtual bool AddToDatabase(const FileDescriptorProto& file) = 0; +}; + +// Factory function type. +typedef DescriptorDatabaseTestCase* DescriptorDatabaseTestCaseFactory(); + +// Specialization for SimpleDescriptorDatabase. +class SimpleDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase { + public: + static DescriptorDatabaseTestCase* New() { + return new SimpleDescriptorDatabaseTestCase; + } + + virtual ~SimpleDescriptorDatabaseTestCase() {} + + virtual DescriptorDatabase* GetDatabase() { + return &database_; + } + virtual bool AddToDatabase(const FileDescriptorProto& file) { + return database_.Add(file); + } + + private: + SimpleDescriptorDatabase database_; +}; + +// Specialization for EncodedDescriptorDatabase. +class EncodedDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase { + public: + static DescriptorDatabaseTestCase* New() { + return new EncodedDescriptorDatabaseTestCase; + } + + virtual ~EncodedDescriptorDatabaseTestCase() {} + + virtual DescriptorDatabase* GetDatabase() { + return &database_; + } + virtual bool AddToDatabase(const FileDescriptorProto& file) { + string data; + file.SerializeToString(&data); + return database_.AddCopy(data.data(), data.size()); + } + + private: + EncodedDescriptorDatabase database_; +}; + +// Specialization for DescriptorPoolDatabase. +class DescriptorPoolDatabaseTestCase : public DescriptorDatabaseTestCase { + public: + static DescriptorDatabaseTestCase* New() { + return new EncodedDescriptorDatabaseTestCase; + } + + DescriptorPoolDatabaseTestCase() : database_(pool_) {} + virtual ~DescriptorPoolDatabaseTestCase() {} + + virtual DescriptorDatabase* GetDatabase() { + return &database_; + } + virtual bool AddToDatabase(const FileDescriptorProto& file) { + return pool_.BuildFile(file); + } + + private: + DescriptorPool pool_; + DescriptorPoolDatabase database_; +}; + +// ------------------------------------------------------------------- + +class DescriptorDatabaseTest + : public testing::TestWithParam { + protected: + virtual void SetUp() { + test_case_.reset(GetParam()()); + database_ = test_case_->GetDatabase(); + } + + void AddToDatabase(const char* file_descriptor_text) { + FileDescriptorProto file_proto; + EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto)); + EXPECT_TRUE(test_case_->AddToDatabase(file_proto)); + } + + void AddToDatabaseWithError(const char* file_descriptor_text) { + FileDescriptorProto file_proto; + EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto)); + EXPECT_FALSE(test_case_->AddToDatabase(file_proto)); + } + + scoped_ptr test_case_; + DescriptorDatabase* database_; +}; + +TEST_P(DescriptorDatabaseTest, FindFileByName) { + AddToDatabase( + "name: \"foo.proto\" " + "message_type { name:\"Foo\" }"); + AddToDatabase( + "name: \"bar.proto\" " + "message_type { name:\"Bar\" }"); + + { + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileByName("foo.proto", &file)); + EXPECT_EQ("foo.proto", file.name()); + ExpectContainsType(file, "Foo"); + } + + { + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileByName("bar.proto", &file)); + EXPECT_EQ("bar.proto", file.name()); + ExpectContainsType(file, "Bar"); + } + + { + // Fails to find undefined files. + FileDescriptorProto file; + EXPECT_FALSE(database_->FindFileByName("baz.proto", &file)); + } +} + +TEST_P(DescriptorDatabaseTest, FindFileContainingSymbol) { + AddToDatabase( + "name: \"foo.proto\" " + "message_type { " + " name: \"Foo\" " + " field { name:\"qux\" }" + " nested_type { name: \"Grault\" } " + " enum_type { name: \"Garply\" } " + "} " + "enum_type { " + " name: \"Waldo\" " + " value { name:\"FRED\" } " + "} " + "extension { name: \"plugh\" } " + "service { " + " name: \"Xyzzy\" " + " method { name: \"Thud\" } " + "}" + ); + AddToDatabase( + "name: \"bar.proto\" " + "package: \"corge\" " + "message_type { name: \"Bar\" }"); + + { + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingSymbol("Foo", &file)); + EXPECT_EQ("foo.proto", file.name()); + } + + { + // Can find fields. + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.qux", &file)); + EXPECT_EQ("foo.proto", file.name()); + } + + { + // Can find nested types. + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.Grault", &file)); + EXPECT_EQ("foo.proto", file.name()); + } + + { + // Can find nested enums. + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.Garply", &file)); + EXPECT_EQ("foo.proto", file.name()); + } + + { + // Can find enum types. + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingSymbol("Waldo", &file)); + EXPECT_EQ("foo.proto", file.name()); + } + + { + // Can find enum values. + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingSymbol("Waldo.FRED", &file)); + EXPECT_EQ("foo.proto", file.name()); + } + + { + // Can find extensions. + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingSymbol("plugh", &file)); + EXPECT_EQ("foo.proto", file.name()); + } + + { + // Can find services. + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingSymbol("Xyzzy", &file)); + EXPECT_EQ("foo.proto", file.name()); + } + + { + // Can find methods. + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingSymbol("Xyzzy.Thud", &file)); + EXPECT_EQ("foo.proto", file.name()); + } + + { + // Can find things in packages. + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingSymbol("corge.Bar", &file)); + EXPECT_EQ("bar.proto", file.name()); + } + + { + // Fails to find undefined symbols. + FileDescriptorProto file; + EXPECT_FALSE(database_->FindFileContainingSymbol("Baz", &file)); + } + + { + // Names must be fully-qualified. + FileDescriptorProto file; + EXPECT_FALSE(database_->FindFileContainingSymbol("Bar", &file)); + } +} + +TEST_P(DescriptorDatabaseTest, FindFileContainingExtension) { + AddToDatabase( + "name: \"foo.proto\" " + "message_type { " + " name: \"Foo\" " + " extension_range { start: 1 end: 1000 } " + " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 " + " extendee: \".Foo\" }" + "}"); + AddToDatabase( + "name: \"bar.proto\" " + "package: \"corge\" " + "dependency: \"foo.proto\" " + "message_type { " + " name: \"Bar\" " + " extension_range { start: 1 end: 1000 } " + "} " + "extension { name:\"grault\" extendee: \".Foo\" number:32 } " + "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } " + "extension { name:\"waldo\" extendee: \"Bar\" number:56 } "); + + { + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingExtension("Foo", 5, &file)); + EXPECT_EQ("foo.proto", file.name()); + } + + { + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingExtension("Foo", 32, &file)); + EXPECT_EQ("bar.proto", file.name()); + } + + { + // Can find extensions for qualified type names. + FileDescriptorProto file; + EXPECT_TRUE(database_->FindFileContainingExtension("corge.Bar", 70, &file)); + EXPECT_EQ("bar.proto", file.name()); + } + + { + // Can't find extensions whose extendee was not fully-qualified in the + // FileDescriptorProto. + FileDescriptorProto file; + EXPECT_FALSE(database_->FindFileContainingExtension("Bar", 56, &file)); + EXPECT_FALSE( + database_->FindFileContainingExtension("corge.Bar", 56, &file)); + } + + { + // Can't find non-existent extension numbers. + FileDescriptorProto file; + EXPECT_FALSE(database_->FindFileContainingExtension("Foo", 12, &file)); + } + + { + // Can't find extensions for non-existent types. + FileDescriptorProto file; + EXPECT_FALSE( + database_->FindFileContainingExtension("NoSuchType", 5, &file)); + } + + { + // Can't find extensions for unqualified type names. + FileDescriptorProto file; + EXPECT_FALSE(database_->FindFileContainingExtension("Bar", 70, &file)); + } +} + +TEST_P(DescriptorDatabaseTest, FindAllExtensionNumbers) { + AddToDatabase( + "name: \"foo.proto\" " + "message_type { " + " name: \"Foo\" " + " extension_range { start: 1 end: 1000 } " + " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 " + " extendee: \".Foo\" }" + "}"); + AddToDatabase( + "name: \"bar.proto\" " + "package: \"corge\" " + "dependency: \"foo.proto\" " + "message_type { " + " name: \"Bar\" " + " extension_range { start: 1 end: 1000 } " + "} " + "extension { name:\"grault\" extendee: \".Foo\" number:32 } " + "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } " + "extension { name:\"waldo\" extendee: \"Bar\" number:56 } "); + + { + vector numbers; + EXPECT_TRUE(database_->FindAllExtensionNumbers("Foo", &numbers)); + ASSERT_EQ(2, numbers.size()); + sort(numbers.begin(), numbers.end()); + EXPECT_EQ(5, numbers[0]); + EXPECT_EQ(32, numbers[1]); + } + + { + vector numbers; + EXPECT_TRUE(database_->FindAllExtensionNumbers("corge.Bar", &numbers)); + // Note: won't find extension 56 due to the name not being fully qualified. + ASSERT_EQ(1, numbers.size()); + EXPECT_EQ(70, numbers[0]); + } + + { + // Can't find extensions for non-existent types. + vector numbers; + EXPECT_FALSE(database_->FindAllExtensionNumbers("NoSuchType", &numbers)); + } + + { + // Can't find extensions for unqualified types. + vector numbers; + EXPECT_FALSE(database_->FindAllExtensionNumbers("Bar", &numbers)); + } +} + +TEST_P(DescriptorDatabaseTest, ConflictingFileError) { + AddToDatabase( + "name: \"foo.proto\" " + "message_type { " + " name: \"Foo\" " + "}"); + AddToDatabaseWithError( + "name: \"foo.proto\" " + "message_type { " + " name: \"Bar\" " + "}"); +} + +TEST_P(DescriptorDatabaseTest, ConflictingTypeError) { + AddToDatabase( + "name: \"foo.proto\" " + "message_type { " + " name: \"Foo\" " + "}"); + AddToDatabaseWithError( + "name: \"bar.proto\" " + "message_type { " + " name: \"Foo\" " + "}"); +} + +TEST_P(DescriptorDatabaseTest, ConflictingExtensionError) { + AddToDatabase( + "name: \"foo.proto\" " + "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 " + " extendee: \".Foo\" }"); + AddToDatabaseWithError( + "name: \"bar.proto\" " + "extension { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 " + " extendee: \".Foo\" }"); +} + +INSTANTIATE_TEST_CASE_P(Simple, DescriptorDatabaseTest, + testing::Values(&SimpleDescriptorDatabaseTestCase::New)); +INSTANTIATE_TEST_CASE_P(MemoryConserving, DescriptorDatabaseTest, + testing::Values(&EncodedDescriptorDatabaseTestCase::New)); +INSTANTIATE_TEST_CASE_P(Pool, DescriptorDatabaseTest, + testing::Values(&DescriptorPoolDatabaseTestCase::New)); + +#endif // GTEST_HAS_PARAM_TEST + +TEST(EncodedDescriptorDatabaseExtraTest, FindNameOfFileContainingSymbol) { + // Create two files, one of which is in two parts. + FileDescriptorProto file1, file2a, file2b; + file1.set_name("foo.proto"); + file1.set_package("foo"); + file1.add_message_type()->set_name("Foo"); + file2a.set_name("bar.proto"); + file2b.set_package("bar"); + file2b.add_message_type()->set_name("Bar"); + + // Normal serialization allows our optimization to kick in. + string data1 = file1.SerializeAsString(); + + // Force out-of-order serialization to test slow path. + string data2 = file2b.SerializeAsString() + file2a.SerializeAsString(); + + // Create EncodedDescriptorDatabase containing both files. + EncodedDescriptorDatabase db; + db.Add(data1.data(), data1.size()); + db.Add(data2.data(), data2.size()); + + // Test! + string filename; + EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo", &filename)); + EXPECT_EQ("foo.proto", filename); + EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo.Blah", &filename)); + EXPECT_EQ("foo.proto", filename); + EXPECT_TRUE(db.FindNameOfFileContainingSymbol("bar.Bar", &filename)); + EXPECT_EQ("bar.proto", filename); + EXPECT_FALSE(db.FindNameOfFileContainingSymbol("foo", &filename)); + EXPECT_FALSE(db.FindNameOfFileContainingSymbol("bar", &filename)); + EXPECT_FALSE(db.FindNameOfFileContainingSymbol("baz.Baz", &filename)); +} + +// =================================================================== + +class MergedDescriptorDatabaseTest : public testing::Test { + protected: + MergedDescriptorDatabaseTest() + : forward_merged_(&database1_, &database2_), + reverse_merged_(&database2_, &database1_) {} + + virtual void SetUp() { + AddToDatabase(&database1_, + "name: \"foo.proto\" " + "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } " + "extension { name:\"foo_ext\" extendee: \".Foo\" number:3 " + " label:LABEL_OPTIONAL type:TYPE_INT32 } "); + AddToDatabase(&database2_, + "name: \"bar.proto\" " + "message_type { name:\"Bar\" extension_range { start: 1 end: 100 } } " + "extension { name:\"bar_ext\" extendee: \".Bar\" number:5 " + " label:LABEL_OPTIONAL type:TYPE_INT32 } "); + + // baz.proto exists in both pools, with different definitions. + AddToDatabase(&database1_, + "name: \"baz.proto\" " + "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } " + "message_type { name:\"FromPool1\" } " + "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 " + " label:LABEL_OPTIONAL type:TYPE_INT32 } " + "extension { name:\"database1_only_ext\" extendee: \".Baz\" number:13 " + " label:LABEL_OPTIONAL type:TYPE_INT32 } "); + AddToDatabase(&database2_, + "name: \"baz.proto\" " + "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } " + "message_type { name:\"FromPool2\" } " + "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 " + " label:LABEL_OPTIONAL type:TYPE_INT32 } "); + } + + SimpleDescriptorDatabase database1_; + SimpleDescriptorDatabase database2_; + + MergedDescriptorDatabase forward_merged_; + MergedDescriptorDatabase reverse_merged_; +}; + +TEST_F(MergedDescriptorDatabaseTest, FindFileByName) { + { + // Can find file that is only in database1_. + FileDescriptorProto file; + EXPECT_TRUE(forward_merged_.FindFileByName("foo.proto", &file)); + EXPECT_EQ("foo.proto", file.name()); + ExpectContainsType(file, "Foo"); + } + + { + // Can find file that is only in database2_. + FileDescriptorProto file; + EXPECT_TRUE(forward_merged_.FindFileByName("bar.proto", &file)); + EXPECT_EQ("bar.proto", file.name()); + ExpectContainsType(file, "Bar"); + } + + { + // In forward_merged_, database1_'s baz.proto takes precedence. + FileDescriptorProto file; + EXPECT_TRUE(forward_merged_.FindFileByName("baz.proto", &file)); + EXPECT_EQ("baz.proto", file.name()); + ExpectContainsType(file, "FromPool1"); + } + + { + // In reverse_merged_, database2_'s baz.proto takes precedence. + FileDescriptorProto file; + EXPECT_TRUE(reverse_merged_.FindFileByName("baz.proto", &file)); + EXPECT_EQ("baz.proto", file.name()); + ExpectContainsType(file, "FromPool2"); + } + + { + // Can't find non-existent file. + FileDescriptorProto file; + EXPECT_FALSE(forward_merged_.FindFileByName("no_such.proto", &file)); + } +} + +TEST_F(MergedDescriptorDatabaseTest, FindFileContainingSymbol) { + { + // Can find file that is only in database1_. + FileDescriptorProto file; + EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Foo", &file)); + EXPECT_EQ("foo.proto", file.name()); + ExpectContainsType(file, "Foo"); + } + + { + // Can find file that is only in database2_. + FileDescriptorProto file; + EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Bar", &file)); + EXPECT_EQ("bar.proto", file.name()); + ExpectContainsType(file, "Bar"); + } + + { + // In forward_merged_, database1_'s baz.proto takes precedence. + FileDescriptorProto file; + EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Baz", &file)); + EXPECT_EQ("baz.proto", file.name()); + ExpectContainsType(file, "FromPool1"); + } + + { + // In reverse_merged_, database2_'s baz.proto takes precedence. + FileDescriptorProto file; + EXPECT_TRUE(reverse_merged_.FindFileContainingSymbol("Baz", &file)); + EXPECT_EQ("baz.proto", file.name()); + ExpectContainsType(file, "FromPool2"); + } + + { + // FromPool1 only shows up in forward_merged_ because it is masked by + // database2_'s baz.proto in reverse_merged_. + FileDescriptorProto file; + EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("FromPool1", &file)); + EXPECT_FALSE(reverse_merged_.FindFileContainingSymbol("FromPool1", &file)); + } + + { + // Can't find non-existent symbol. + FileDescriptorProto file; + EXPECT_FALSE( + forward_merged_.FindFileContainingSymbol("NoSuchType", &file)); + } +} + +TEST_F(MergedDescriptorDatabaseTest, FindFileContainingExtension) { + { + // Can find file that is only in database1_. + FileDescriptorProto file; + EXPECT_TRUE( + forward_merged_.FindFileContainingExtension("Foo", 3, &file)); + EXPECT_EQ("foo.proto", file.name()); + ExpectContainsType(file, "Foo"); + } + + { + // Can find file that is only in database2_. + FileDescriptorProto file; + EXPECT_TRUE( + forward_merged_.FindFileContainingExtension("Bar", 5, &file)); + EXPECT_EQ("bar.proto", file.name()); + ExpectContainsType(file, "Bar"); + } + + { + // In forward_merged_, database1_'s baz.proto takes precedence. + FileDescriptorProto file; + EXPECT_TRUE( + forward_merged_.FindFileContainingExtension("Baz", 12, &file)); + EXPECT_EQ("baz.proto", file.name()); + ExpectContainsType(file, "FromPool1"); + } + + { + // In reverse_merged_, database2_'s baz.proto takes precedence. + FileDescriptorProto file; + EXPECT_TRUE( + reverse_merged_.FindFileContainingExtension("Baz", 12, &file)); + EXPECT_EQ("baz.proto", file.name()); + ExpectContainsType(file, "FromPool2"); + } + + { + // Baz's extension 13 only shows up in forward_merged_ because it is + // masked by database2_'s baz.proto in reverse_merged_. + FileDescriptorProto file; + EXPECT_TRUE(forward_merged_.FindFileContainingExtension("Baz", 13, &file)); + EXPECT_FALSE(reverse_merged_.FindFileContainingExtension("Baz", 13, &file)); + } + + { + // Can't find non-existent extension. + FileDescriptorProto file; + EXPECT_FALSE( + forward_merged_.FindFileContainingExtension("Foo", 6, &file)); + } +} + +TEST_F(MergedDescriptorDatabaseTest, FindAllExtensionNumbers) { + { + // Message only has extension in database1_ + vector numbers; + EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Foo", &numbers)); + ASSERT_EQ(1, numbers.size()); + EXPECT_EQ(3, numbers[0]); + } + + { + // Message only has extension in database2_ + vector numbers; + EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Bar", &numbers)); + ASSERT_EQ(1, numbers.size()); + EXPECT_EQ(5, numbers[0]); + } + + { + // Merge results from the two databases. + vector numbers; + EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Baz", &numbers)); + ASSERT_EQ(2, numbers.size()); + sort(numbers.begin(), numbers.end()); + EXPECT_EQ(12, numbers[0]); + EXPECT_EQ(13, numbers[1]); + } + + { + vector numbers; + EXPECT_TRUE(reverse_merged_.FindAllExtensionNumbers("Baz", &numbers)); + ASSERT_EQ(2, numbers.size()); + sort(numbers.begin(), numbers.end()); + EXPECT_EQ(12, numbers[0]); + EXPECT_EQ(13, numbers[1]); + } + + { + // Can't find extensions for a non-existent message. + vector numbers; + EXPECT_FALSE(reverse_merged_.FindAllExtensionNumbers("Blah", &numbers)); + } +} + +} // anonymous namespace +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_unittest.cc new file mode 100644 index 0000000..86e6a49 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/descriptor_unittest.cc @@ -0,0 +1,4656 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file makes extensive use of RFC 3092. :) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace google { +namespace protobuf { + +// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. +namespace descriptor_unittest { + +// Some helpers to make assembling descriptors faster. +DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) { + DescriptorProto* result = file->add_message_type(); + result->set_name(name); + return result; +} + +DescriptorProto* AddNestedMessage(DescriptorProto* parent, const string& name) { + DescriptorProto* result = parent->add_nested_type(); + result->set_name(name); + return result; +} + +EnumDescriptorProto* AddEnum(FileDescriptorProto* file, const string& name) { + EnumDescriptorProto* result = file->add_enum_type(); + result->set_name(name); + return result; +} + +EnumDescriptorProto* AddNestedEnum(DescriptorProto* parent, + const string& name) { + EnumDescriptorProto* result = parent->add_enum_type(); + result->set_name(name); + return result; +} + +ServiceDescriptorProto* AddService(FileDescriptorProto* file, + const string& name) { + ServiceDescriptorProto* result = file->add_service(); + result->set_name(name); + return result; +} + +FieldDescriptorProto* AddField(DescriptorProto* parent, + const string& name, int number, + FieldDescriptorProto::Label label, + FieldDescriptorProto::Type type) { + FieldDescriptorProto* result = parent->add_field(); + result->set_name(name); + result->set_number(number); + result->set_label(label); + result->set_type(type); + return result; +} + +FieldDescriptorProto* AddExtension(FileDescriptorProto* file, + const string& extendee, + const string& name, int number, + FieldDescriptorProto::Label label, + FieldDescriptorProto::Type type) { + FieldDescriptorProto* result = file->add_extension(); + result->set_name(name); + result->set_number(number); + result->set_label(label); + result->set_type(type); + result->set_extendee(extendee); + return result; +} + +FieldDescriptorProto* AddNestedExtension(DescriptorProto* parent, + const string& extendee, + const string& name, int number, + FieldDescriptorProto::Label label, + FieldDescriptorProto::Type type) { + FieldDescriptorProto* result = parent->add_extension(); + result->set_name(name); + result->set_number(number); + result->set_label(label); + result->set_type(type); + result->set_extendee(extendee); + return result; +} + +DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent, + int start, int end) { + DescriptorProto::ExtensionRange* result = parent->add_extension_range(); + result->set_start(start); + result->set_end(end); + return result; +} + +EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto, + const string& name, int number) { + EnumValueDescriptorProto* result = enum_proto->add_value(); + result->set_name(name); + result->set_number(number); + return result; +} + +MethodDescriptorProto* AddMethod(ServiceDescriptorProto* service, + const string& name, + const string& input_type, + const string& output_type) { + MethodDescriptorProto* result = service->add_method(); + result->set_name(name); + result->set_input_type(input_type); + result->set_output_type(output_type); + return result; +} + +// Empty enums technically aren't allowed. We need to insert a dummy value +// into them. +void AddEmptyEnum(FileDescriptorProto* file, const string& name) { + AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1); +} + +// =================================================================== + +// Test simple files. +class FileDescriptorTest : public testing::Test { + protected: + virtual void SetUp() { + // Build descriptors for the following definitions: + // + // // in "foo.proto" + // message FooMessage { extensions 1; } + // enum FooEnum {FOO_ENUM_VALUE = 1;} + // service FooService {} + // extend FooMessage { optional int32 foo_extension = 1; } + // + // // in "bar.proto" + // package bar_package; + // message BarMessage { extensions 1; } + // enum BarEnum {BAR_ENUM_VALUE = 1;} + // service BarService {} + // extend BarMessage { optional int32 bar_extension = 1; } + // + // Also, we have an empty file "baz.proto". This file's purpose is to + // make sure that even though it has the same package as foo.proto, + // searching it for members of foo.proto won't work. + + FileDescriptorProto foo_file; + foo_file.set_name("foo.proto"); + AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2); + AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1); + AddService(&foo_file, "FooService"); + AddExtension(&foo_file, "FooMessage", "foo_extension", 1, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + + FileDescriptorProto bar_file; + bar_file.set_name("bar.proto"); + bar_file.set_package("bar_package"); + bar_file.add_dependency("foo.proto"); + AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2); + AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1); + AddService(&bar_file, "BarService"); + AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + + FileDescriptorProto baz_file; + baz_file.set_name("baz.proto"); + + // Build the descriptors and get the pointers. + foo_file_ = pool_.BuildFile(foo_file); + ASSERT_TRUE(foo_file_ != NULL); + + bar_file_ = pool_.BuildFile(bar_file); + ASSERT_TRUE(bar_file_ != NULL); + + baz_file_ = pool_.BuildFile(baz_file); + ASSERT_TRUE(baz_file_ != NULL); + + ASSERT_EQ(1, foo_file_->message_type_count()); + foo_message_ = foo_file_->message_type(0); + ASSERT_EQ(1, foo_file_->enum_type_count()); + foo_enum_ = foo_file_->enum_type(0); + ASSERT_EQ(1, foo_enum_->value_count()); + foo_enum_value_ = foo_enum_->value(0); + ASSERT_EQ(1, foo_file_->service_count()); + foo_service_ = foo_file_->service(0); + ASSERT_EQ(1, foo_file_->extension_count()); + foo_extension_ = foo_file_->extension(0); + + ASSERT_EQ(1, bar_file_->message_type_count()); + bar_message_ = bar_file_->message_type(0); + ASSERT_EQ(1, bar_file_->enum_type_count()); + bar_enum_ = bar_file_->enum_type(0); + ASSERT_EQ(1, bar_enum_->value_count()); + bar_enum_value_ = bar_enum_->value(0); + ASSERT_EQ(1, bar_file_->service_count()); + bar_service_ = bar_file_->service(0); + ASSERT_EQ(1, bar_file_->extension_count()); + bar_extension_ = bar_file_->extension(0); + } + + DescriptorPool pool_; + + const FileDescriptor* foo_file_; + const FileDescriptor* bar_file_; + const FileDescriptor* baz_file_; + + const Descriptor* foo_message_; + const EnumDescriptor* foo_enum_; + const EnumValueDescriptor* foo_enum_value_; + const ServiceDescriptor* foo_service_; + const FieldDescriptor* foo_extension_; + + const Descriptor* bar_message_; + const EnumDescriptor* bar_enum_; + const EnumValueDescriptor* bar_enum_value_; + const ServiceDescriptor* bar_service_; + const FieldDescriptor* bar_extension_; +}; + +TEST_F(FileDescriptorTest, Name) { + EXPECT_EQ("foo.proto", foo_file_->name()); + EXPECT_EQ("bar.proto", bar_file_->name()); + EXPECT_EQ("baz.proto", baz_file_->name()); +} + +TEST_F(FileDescriptorTest, Package) { + EXPECT_EQ("", foo_file_->package()); + EXPECT_EQ("bar_package", bar_file_->package()); +} + +TEST_F(FileDescriptorTest, Dependencies) { + EXPECT_EQ(0, foo_file_->dependency_count()); + EXPECT_EQ(1, bar_file_->dependency_count()); + EXPECT_EQ(foo_file_, bar_file_->dependency(0)); +} + +TEST_F(FileDescriptorTest, FindMessageTypeByName) { + EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage")); + EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage")); + + EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == NULL); + EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == NULL); + EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == NULL); + + EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == NULL); + EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == NULL); +} + +TEST_F(FileDescriptorTest, FindEnumTypeByName) { + EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum")); + EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum")); + + EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == NULL); + EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == NULL); + EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == NULL); + + EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == NULL); + EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == NULL); +} + +TEST_F(FileDescriptorTest, FindEnumValueByName) { + EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE")); + EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE")); + + EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == NULL); + EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL); + EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL); + + EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == NULL); + EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == NULL); +} + +TEST_F(FileDescriptorTest, FindServiceByName) { + EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService")); + EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService")); + + EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == NULL); + EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == NULL); + EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == NULL); + + EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == NULL); + EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == NULL); +} + +TEST_F(FileDescriptorTest, FindExtensionByName) { + EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension")); + EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension")); + + EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == NULL); + EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == NULL); + EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == NULL); + + EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == NULL); + EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == NULL); +} + +TEST_F(FileDescriptorTest, FindExtensionByNumber) { + EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1)); + EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1)); + + EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == NULL); +} + +TEST_F(FileDescriptorTest, BuildAgain) { + // Test that if te call BuildFile again on the same input we get the same + // FileDescriptor back. + FileDescriptorProto file; + foo_file_->CopyTo(&file); + EXPECT_EQ(foo_file_, pool_.BuildFile(file)); + + // But if we change the file then it won't work. + file.set_package("some.other.package"); + EXPECT_TRUE(pool_.BuildFile(file) == NULL); +} + +// =================================================================== + +// Test simple flat messages and fields. +class DescriptorTest : public testing::Test { + protected: + virtual void SetUp() { + // Build descriptors for the following definitions: + // + // // in "foo.proto" + // message TestForeign {} + // enum TestEnum {} + // + // message TestMessage { + // required string foo = 1; + // optional TestEnum bar = 6; + // repeated TestForeign baz = 500000000; + // optional group qux = 15 {} + // } + // + // // in "bar.proto" + // package corge.grault; + // message TestMessage2 { + // required string foo = 1; + // required string bar = 2; + // required string quux = 6; + // } + // + // We cheat and use TestForeign as the type for qux rather than create + // an actual nested type. + // + // Since all primitive types (including string) use the same building + // code, there's no need to test each one individually. + // + // TestMessage2 is primarily here to test FindFieldByName and friends. + // All messages created from the same DescriptorPool share the same lookup + // table, so we need to insure that they don't interfere. + + FileDescriptorProto foo_file; + foo_file.set_name("foo.proto"); + AddMessage(&foo_file, "TestForeign"); + AddEmptyEnum(&foo_file, "TestEnum"); + + DescriptorProto* message = AddMessage(&foo_file, "TestMessage"); + AddField(message, "foo", 1, + FieldDescriptorProto::LABEL_REQUIRED, + FieldDescriptorProto::TYPE_STRING); + AddField(message, "bar", 6, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_ENUM) + ->set_type_name("TestEnum"); + AddField(message, "baz", 500000000, + FieldDescriptorProto::LABEL_REPEATED, + FieldDescriptorProto::TYPE_MESSAGE) + ->set_type_name("TestForeign"); + AddField(message, "qux", 15, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_GROUP) + ->set_type_name("TestForeign"); + + FileDescriptorProto bar_file; + bar_file.set_name("bar.proto"); + bar_file.set_package("corge.grault"); + + DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2"); + AddField(message2, "foo", 1, + FieldDescriptorProto::LABEL_REQUIRED, + FieldDescriptorProto::TYPE_STRING); + AddField(message2, "bar", 2, + FieldDescriptorProto::LABEL_REQUIRED, + FieldDescriptorProto::TYPE_STRING); + AddField(message2, "quux", 6, + FieldDescriptorProto::LABEL_REQUIRED, + FieldDescriptorProto::TYPE_STRING); + + // Build the descriptors and get the pointers. + foo_file_ = pool_.BuildFile(foo_file); + ASSERT_TRUE(foo_file_ != NULL); + + bar_file_ = pool_.BuildFile(bar_file); + ASSERT_TRUE(bar_file_ != NULL); + + ASSERT_EQ(1, foo_file_->enum_type_count()); + enum_ = foo_file_->enum_type(0); + + ASSERT_EQ(2, foo_file_->message_type_count()); + foreign_ = foo_file_->message_type(0); + message_ = foo_file_->message_type(1); + + ASSERT_EQ(4, message_->field_count()); + foo_ = message_->field(0); + bar_ = message_->field(1); + baz_ = message_->field(2); + qux_ = message_->field(3); + + ASSERT_EQ(1, bar_file_->message_type_count()); + message2_ = bar_file_->message_type(0); + + ASSERT_EQ(3, message2_->field_count()); + foo2_ = message2_->field(0); + bar2_ = message2_->field(1); + quux2_ = message2_->field(2); + } + + DescriptorPool pool_; + + const FileDescriptor* foo_file_; + const FileDescriptor* bar_file_; + + const Descriptor* message_; + const Descriptor* message2_; + const Descriptor* foreign_; + const EnumDescriptor* enum_; + + const FieldDescriptor* foo_; + const FieldDescriptor* bar_; + const FieldDescriptor* baz_; + const FieldDescriptor* qux_; + + const FieldDescriptor* foo2_; + const FieldDescriptor* bar2_; + const FieldDescriptor* quux2_; +}; + +TEST_F(DescriptorTest, Name) { + EXPECT_EQ("TestMessage", message_->name()); + EXPECT_EQ("TestMessage", message_->full_name()); + EXPECT_EQ(foo_file_, message_->file()); + + EXPECT_EQ("TestMessage2", message2_->name()); + EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name()); + EXPECT_EQ(bar_file_, message2_->file()); +} + +TEST_F(DescriptorTest, ContainingType) { + EXPECT_TRUE(message_->containing_type() == NULL); + EXPECT_TRUE(message2_->containing_type() == NULL); +} + +TEST_F(DescriptorTest, FieldsByIndex) { + ASSERT_EQ(4, message_->field_count()); + EXPECT_EQ(foo_, message_->field(0)); + EXPECT_EQ(bar_, message_->field(1)); + EXPECT_EQ(baz_, message_->field(2)); + EXPECT_EQ(qux_, message_->field(3)); +} + +TEST_F(DescriptorTest, FindFieldByName) { + // All messages in the same DescriptorPool share a single lookup table for + // fields. So, in addition to testing that FindFieldByName finds the fields + // of the message, we need to test that it does *not* find the fields of + // *other* messages. + + EXPECT_EQ(foo_, message_->FindFieldByName("foo")); + EXPECT_EQ(bar_, message_->FindFieldByName("bar")); + EXPECT_EQ(baz_, message_->FindFieldByName("baz")); + EXPECT_EQ(qux_, message_->FindFieldByName("qux")); + EXPECT_TRUE(message_->FindFieldByName("no_such_field") == NULL); + EXPECT_TRUE(message_->FindFieldByName("quux") == NULL); + + EXPECT_EQ(foo2_ , message2_->FindFieldByName("foo" )); + EXPECT_EQ(bar2_ , message2_->FindFieldByName("bar" )); + EXPECT_EQ(quux2_, message2_->FindFieldByName("quux")); + EXPECT_TRUE(message2_->FindFieldByName("baz") == NULL); + EXPECT_TRUE(message2_->FindFieldByName("qux") == NULL); +} + +TEST_F(DescriptorTest, FindFieldByNumber) { + EXPECT_EQ(foo_, message_->FindFieldByNumber(1)); + EXPECT_EQ(bar_, message_->FindFieldByNumber(6)); + EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000)); + EXPECT_EQ(qux_, message_->FindFieldByNumber(15)); + EXPECT_TRUE(message_->FindFieldByNumber(837592) == NULL); + EXPECT_TRUE(message_->FindFieldByNumber(2) == NULL); + + EXPECT_EQ(foo2_ , message2_->FindFieldByNumber(1)); + EXPECT_EQ(bar2_ , message2_->FindFieldByNumber(2)); + EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6)); + EXPECT_TRUE(message2_->FindFieldByNumber(15) == NULL); + EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == NULL); +} + +TEST_F(DescriptorTest, FieldName) { + EXPECT_EQ("foo", foo_->name()); + EXPECT_EQ("bar", bar_->name()); + EXPECT_EQ("baz", baz_->name()); + EXPECT_EQ("qux", qux_->name()); +} + +TEST_F(DescriptorTest, FieldFullName) { + EXPECT_EQ("TestMessage.foo", foo_->full_name()); + EXPECT_EQ("TestMessage.bar", bar_->full_name()); + EXPECT_EQ("TestMessage.baz", baz_->full_name()); + EXPECT_EQ("TestMessage.qux", qux_->full_name()); + + EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name()); + EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name()); + EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name()); +} + +TEST_F(DescriptorTest, FieldFile) { + EXPECT_EQ(foo_file_, foo_->file()); + EXPECT_EQ(foo_file_, bar_->file()); + EXPECT_EQ(foo_file_, baz_->file()); + EXPECT_EQ(foo_file_, qux_->file()); + + EXPECT_EQ(bar_file_, foo2_->file()); + EXPECT_EQ(bar_file_, bar2_->file()); + EXPECT_EQ(bar_file_, quux2_->file()); +} + +TEST_F(DescriptorTest, FieldIndex) { + EXPECT_EQ(0, foo_->index()); + EXPECT_EQ(1, bar_->index()); + EXPECT_EQ(2, baz_->index()); + EXPECT_EQ(3, qux_->index()); +} + +TEST_F(DescriptorTest, FieldNumber) { + EXPECT_EQ( 1, foo_->number()); + EXPECT_EQ( 6, bar_->number()); + EXPECT_EQ(500000000, baz_->number()); + EXPECT_EQ( 15, qux_->number()); +} + +TEST_F(DescriptorTest, FieldType) { + EXPECT_EQ(FieldDescriptor::TYPE_STRING , foo_->type()); + EXPECT_EQ(FieldDescriptor::TYPE_ENUM , bar_->type()); + EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_->type()); + EXPECT_EQ(FieldDescriptor::TYPE_GROUP , qux_->type()); +} + +TEST_F(DescriptorTest, FieldLabel) { + EXPECT_EQ(FieldDescriptor::LABEL_REQUIRED, foo_->label()); + EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->label()); + EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, baz_->label()); + EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, qux_->label()); + + EXPECT_TRUE (foo_->is_required()); + EXPECT_FALSE(foo_->is_optional()); + EXPECT_FALSE(foo_->is_repeated()); + + EXPECT_FALSE(bar_->is_required()); + EXPECT_TRUE (bar_->is_optional()); + EXPECT_FALSE(bar_->is_repeated()); + + EXPECT_FALSE(baz_->is_required()); + EXPECT_FALSE(baz_->is_optional()); + EXPECT_TRUE (baz_->is_repeated()); +} + +TEST_F(DescriptorTest, FieldHasDefault) { + EXPECT_FALSE(foo_->has_default_value()); + EXPECT_FALSE(bar_->has_default_value()); + EXPECT_FALSE(baz_->has_default_value()); + EXPECT_FALSE(qux_->has_default_value()); +} + +TEST_F(DescriptorTest, FieldContainingType) { + EXPECT_EQ(message_, foo_->containing_type()); + EXPECT_EQ(message_, bar_->containing_type()); + EXPECT_EQ(message_, baz_->containing_type()); + EXPECT_EQ(message_, qux_->containing_type()); + + EXPECT_EQ(message2_, foo2_ ->containing_type()); + EXPECT_EQ(message2_, bar2_ ->containing_type()); + EXPECT_EQ(message2_, quux2_->containing_type()); +} + +TEST_F(DescriptorTest, FieldMessageType) { + EXPECT_TRUE(foo_->message_type() == NULL); + EXPECT_TRUE(bar_->message_type() == NULL); + + EXPECT_EQ(foreign_, baz_->message_type()); + EXPECT_EQ(foreign_, qux_->message_type()); +} + +TEST_F(DescriptorTest, FieldEnumType) { + EXPECT_TRUE(foo_->enum_type() == NULL); + EXPECT_TRUE(baz_->enum_type() == NULL); + EXPECT_TRUE(qux_->enum_type() == NULL); + + EXPECT_EQ(enum_, bar_->enum_type()); +} + +// =================================================================== + +class StylizedFieldNamesTest : public testing::Test { + protected: + void SetUp() { + FileDescriptorProto file; + file.set_name("foo.proto"); + + AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000); + + DescriptorProto* message = AddMessage(&file, "TestMessage"); + AddField(message, "foo_foo", 1, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddField(message, "FooBar", 2, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddField(message, "fooBaz", 3, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddField(message, "fooFoo", 4, // Camel-case conflict with foo_foo. + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddField(message, "foobar", 5, // Lower-case conflict with FooBar. + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + + AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddNestedExtension(message, "ExtendableMessage", "BarBar", 2, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddNestedExtension(message, "ExtendableMessage", "barFoo", 4, // Conflict + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddNestedExtension(message, "ExtendableMessage", "barbar", 5, // Conflict + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + + AddExtension(&file, "ExtendableMessage", "baz_foo", 11, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddExtension(&file, "ExtendableMessage", "BazBar", 12, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddExtension(&file, "ExtendableMessage", "BazBaz", 13, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddExtension(&file, "ExtendableMessage", "bazFoo", 14, // Conflict + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddExtension(&file, "ExtendableMessage", "bazbar", 15, // Conflict + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + + file_ = pool_.BuildFile(file); + ASSERT_TRUE(file_ != NULL); + ASSERT_EQ(2, file_->message_type_count()); + message_ = file_->message_type(1); + ASSERT_EQ("TestMessage", message_->name()); + ASSERT_EQ(5, message_->field_count()); + ASSERT_EQ(5, message_->extension_count()); + ASSERT_EQ(5, file_->extension_count()); + } + + DescriptorPool pool_; + const FileDescriptor* file_; + const Descriptor* message_; +}; + +TEST_F(StylizedFieldNamesTest, LowercaseName) { + EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name()); + EXPECT_EQ("foobar" , message_->field(1)->lowercase_name()); + EXPECT_EQ("foobaz" , message_->field(2)->lowercase_name()); + EXPECT_EQ("foofoo" , message_->field(3)->lowercase_name()); + EXPECT_EQ("foobar" , message_->field(4)->lowercase_name()); + + EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name()); + EXPECT_EQ("barbar" , message_->extension(1)->lowercase_name()); + EXPECT_EQ("barbaz" , message_->extension(2)->lowercase_name()); + EXPECT_EQ("barfoo" , message_->extension(3)->lowercase_name()); + EXPECT_EQ("barbar" , message_->extension(4)->lowercase_name()); + + EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name()); + EXPECT_EQ("bazbar" , file_->extension(1)->lowercase_name()); + EXPECT_EQ("bazbaz" , file_->extension(2)->lowercase_name()); + EXPECT_EQ("bazfoo" , file_->extension(3)->lowercase_name()); + EXPECT_EQ("bazbar" , file_->extension(4)->lowercase_name()); +} + +TEST_F(StylizedFieldNamesTest, CamelcaseName) { + EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name()); + EXPECT_EQ("fooBar", message_->field(1)->camelcase_name()); + EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name()); + EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name()); + EXPECT_EQ("foobar", message_->field(4)->camelcase_name()); + + EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name()); + EXPECT_EQ("barBar", message_->extension(1)->camelcase_name()); + EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name()); + EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name()); + EXPECT_EQ("barbar", message_->extension(4)->camelcase_name()); + + EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name()); + EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name()); + EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name()); + EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name()); + EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name()); +} + +TEST_F(StylizedFieldNamesTest, FindByLowercaseName) { + EXPECT_EQ(message_->field(0), + message_->FindFieldByLowercaseName("foo_foo")); + EXPECT_EQ(message_->field(1), + message_->FindFieldByLowercaseName("foobar")); + EXPECT_EQ(message_->field(2), + message_->FindFieldByLowercaseName("foobaz")); + EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == NULL); + EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == NULL); + EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == NULL); + EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == NULL); + + EXPECT_EQ(message_->extension(0), + message_->FindExtensionByLowercaseName("bar_foo")); + EXPECT_EQ(message_->extension(1), + message_->FindExtensionByLowercaseName("barbar")); + EXPECT_EQ(message_->extension(2), + message_->FindExtensionByLowercaseName("barbaz")); + EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == NULL); + EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == NULL); + EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == NULL); + EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == NULL); + + EXPECT_EQ(file_->extension(0), + file_->FindExtensionByLowercaseName("baz_foo")); + EXPECT_EQ(file_->extension(1), + file_->FindExtensionByLowercaseName("bazbar")); + EXPECT_EQ(file_->extension(2), + file_->FindExtensionByLowercaseName("bazbaz")); + EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == NULL); + EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == NULL); + EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == NULL); +} + +TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) { + EXPECT_EQ(message_->field(0), + message_->FindFieldByCamelcaseName("fooFoo")); + EXPECT_EQ(message_->field(1), + message_->FindFieldByCamelcaseName("fooBar")); + EXPECT_EQ(message_->field(2), + message_->FindFieldByCamelcaseName("fooBaz")); + EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == NULL); + EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == NULL); + EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == NULL); + EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == NULL); + + EXPECT_EQ(message_->extension(0), + message_->FindExtensionByCamelcaseName("barFoo")); + EXPECT_EQ(message_->extension(1), + message_->FindExtensionByCamelcaseName("barBar")); + EXPECT_EQ(message_->extension(2), + message_->FindExtensionByCamelcaseName("barBaz")); + EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == NULL); + EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == NULL); + EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == NULL); + EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == NULL); + + EXPECT_EQ(file_->extension(0), + file_->FindExtensionByCamelcaseName("bazFoo")); + EXPECT_EQ(file_->extension(1), + file_->FindExtensionByCamelcaseName("bazBar")); + EXPECT_EQ(file_->extension(2), + file_->FindExtensionByCamelcaseName("bazBaz")); + EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == NULL); + EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == NULL); + EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == NULL); +} + +// =================================================================== + +// Test enum descriptors. +class EnumDescriptorTest : public testing::Test { + protected: + virtual void SetUp() { + // Build descriptors for the following definitions: + // + // // in "foo.proto" + // enum TestEnum { + // FOO = 1; + // BAR = 2; + // } + // + // // in "bar.proto" + // package corge.grault; + // enum TestEnum2 { + // FOO = 1; + // BAZ = 3; + // } + // + // TestEnum2 is primarily here to test FindValueByName and friends. + // All enums created from the same DescriptorPool share the same lookup + // table, so we need to insure that they don't interfere. + + // TestEnum + FileDescriptorProto foo_file; + foo_file.set_name("foo.proto"); + + EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum"); + AddEnumValue(enum_proto, "FOO", 1); + AddEnumValue(enum_proto, "BAR", 2); + + // TestEnum2 + FileDescriptorProto bar_file; + bar_file.set_name("bar.proto"); + bar_file.set_package("corge.grault"); + + EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2"); + AddEnumValue(enum2_proto, "FOO", 1); + AddEnumValue(enum2_proto, "BAZ", 3); + + // Build the descriptors and get the pointers. + foo_file_ = pool_.BuildFile(foo_file); + ASSERT_TRUE(foo_file_ != NULL); + + bar_file_ = pool_.BuildFile(bar_file); + ASSERT_TRUE(bar_file_ != NULL); + + ASSERT_EQ(1, foo_file_->enum_type_count()); + enum_ = foo_file_->enum_type(0); + + ASSERT_EQ(2, enum_->value_count()); + foo_ = enum_->value(0); + bar_ = enum_->value(1); + + ASSERT_EQ(1, bar_file_->enum_type_count()); + enum2_ = bar_file_->enum_type(0); + + ASSERT_EQ(2, enum2_->value_count()); + foo2_ = enum2_->value(0); + baz2_ = enum2_->value(1); + } + + DescriptorPool pool_; + + const FileDescriptor* foo_file_; + const FileDescriptor* bar_file_; + + const EnumDescriptor* enum_; + const EnumDescriptor* enum2_; + + const EnumValueDescriptor* foo_; + const EnumValueDescriptor* bar_; + + const EnumValueDescriptor* foo2_; + const EnumValueDescriptor* baz2_; +}; + +TEST_F(EnumDescriptorTest, Name) { + EXPECT_EQ("TestEnum", enum_->name()); + EXPECT_EQ("TestEnum", enum_->full_name()); + EXPECT_EQ(foo_file_, enum_->file()); + + EXPECT_EQ("TestEnum2", enum2_->name()); + EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name()); + EXPECT_EQ(bar_file_, enum2_->file()); +} + +TEST_F(EnumDescriptorTest, ContainingType) { + EXPECT_TRUE(enum_->containing_type() == NULL); + EXPECT_TRUE(enum2_->containing_type() == NULL); +} + +TEST_F(EnumDescriptorTest, ValuesByIndex) { + ASSERT_EQ(2, enum_->value_count()); + EXPECT_EQ(foo_, enum_->value(0)); + EXPECT_EQ(bar_, enum_->value(1)); +} + +TEST_F(EnumDescriptorTest, FindValueByName) { + EXPECT_EQ(foo_ , enum_ ->FindValueByName("FOO")); + EXPECT_EQ(bar_ , enum_ ->FindValueByName("BAR")); + EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO")); + EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ")); + + EXPECT_TRUE(enum_ ->FindValueByName("NO_SUCH_VALUE") == NULL); + EXPECT_TRUE(enum_ ->FindValueByName("BAZ" ) == NULL); + EXPECT_TRUE(enum2_->FindValueByName("BAR" ) == NULL); +} + +TEST_F(EnumDescriptorTest, FindValueByNumber) { + EXPECT_EQ(foo_ , enum_ ->FindValueByNumber(1)); + EXPECT_EQ(bar_ , enum_ ->FindValueByNumber(2)); + EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1)); + EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3)); + + EXPECT_TRUE(enum_ ->FindValueByNumber(416) == NULL); + EXPECT_TRUE(enum_ ->FindValueByNumber(3) == NULL); + EXPECT_TRUE(enum2_->FindValueByNumber(2) == NULL); +} + +TEST_F(EnumDescriptorTest, ValueName) { + EXPECT_EQ("FOO", foo_->name()); + EXPECT_EQ("BAR", bar_->name()); +} + +TEST_F(EnumDescriptorTest, ValueFullName) { + EXPECT_EQ("FOO", foo_->full_name()); + EXPECT_EQ("BAR", bar_->full_name()); + EXPECT_EQ("corge.grault.FOO", foo2_->full_name()); + EXPECT_EQ("corge.grault.BAZ", baz2_->full_name()); +} + +TEST_F(EnumDescriptorTest, ValueIndex) { + EXPECT_EQ(0, foo_->index()); + EXPECT_EQ(1, bar_->index()); +} + +TEST_F(EnumDescriptorTest, ValueNumber) { + EXPECT_EQ(1, foo_->number()); + EXPECT_EQ(2, bar_->number()); +} + +TEST_F(EnumDescriptorTest, ValueType) { + EXPECT_EQ(enum_ , foo_ ->type()); + EXPECT_EQ(enum_ , bar_ ->type()); + EXPECT_EQ(enum2_, foo2_->type()); + EXPECT_EQ(enum2_, baz2_->type()); +} + +// =================================================================== + +// Test service descriptors. +class ServiceDescriptorTest : public testing::Test { + protected: + virtual void SetUp() { + // Build descriptors for the following messages and service: + // // in "foo.proto" + // message FooRequest {} + // message FooResponse {} + // message BarRequest {} + // message BarResponse {} + // message BazRequest {} + // message BazResponse {} + // + // service TestService { + // rpc Foo(FooRequest) returns (FooResponse); + // rpc Bar(BarRequest) returns (BarResponse); + // } + // + // // in "bar.proto" + // package corge.grault + // service TestService2 { + // rpc Foo(FooRequest) returns (FooResponse); + // rpc Baz(BazRequest) returns (BazResponse); + // } + + FileDescriptorProto foo_file; + foo_file.set_name("foo.proto"); + + AddMessage(&foo_file, "FooRequest"); + AddMessage(&foo_file, "FooResponse"); + AddMessage(&foo_file, "BarRequest"); + AddMessage(&foo_file, "BarResponse"); + AddMessage(&foo_file, "BazRequest"); + AddMessage(&foo_file, "BazResponse"); + + ServiceDescriptorProto* service = AddService(&foo_file, "TestService"); + AddMethod(service, "Foo", "FooRequest", "FooResponse"); + AddMethod(service, "Bar", "BarRequest", "BarResponse"); + + FileDescriptorProto bar_file; + bar_file.set_name("bar.proto"); + bar_file.set_package("corge.grault"); + bar_file.add_dependency("foo.proto"); + + ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2"); + AddMethod(service2, "Foo", "FooRequest", "FooResponse"); + AddMethod(service2, "Baz", "BazRequest", "BazResponse"); + + // Build the descriptors and get the pointers. + foo_file_ = pool_.BuildFile(foo_file); + ASSERT_TRUE(foo_file_ != NULL); + + bar_file_ = pool_.BuildFile(bar_file); + ASSERT_TRUE(bar_file_ != NULL); + + ASSERT_EQ(6, foo_file_->message_type_count()); + foo_request_ = foo_file_->message_type(0); + foo_response_ = foo_file_->message_type(1); + bar_request_ = foo_file_->message_type(2); + bar_response_ = foo_file_->message_type(3); + baz_request_ = foo_file_->message_type(4); + baz_response_ = foo_file_->message_type(5); + + ASSERT_EQ(1, foo_file_->service_count()); + service_ = foo_file_->service(0); + + ASSERT_EQ(2, service_->method_count()); + foo_ = service_->method(0); + bar_ = service_->method(1); + + ASSERT_EQ(1, bar_file_->service_count()); + service2_ = bar_file_->service(0); + + ASSERT_EQ(2, service2_->method_count()); + foo2_ = service2_->method(0); + baz2_ = service2_->method(1); + } + + DescriptorPool pool_; + + const FileDescriptor* foo_file_; + const FileDescriptor* bar_file_; + + const Descriptor* foo_request_; + const Descriptor* foo_response_; + const Descriptor* bar_request_; + const Descriptor* bar_response_; + const Descriptor* baz_request_; + const Descriptor* baz_response_; + + const ServiceDescriptor* service_; + const ServiceDescriptor* service2_; + + const MethodDescriptor* foo_; + const MethodDescriptor* bar_; + + const MethodDescriptor* foo2_; + const MethodDescriptor* baz2_; +}; + +TEST_F(ServiceDescriptorTest, Name) { + EXPECT_EQ("TestService", service_->name()); + EXPECT_EQ("TestService", service_->full_name()); + EXPECT_EQ(foo_file_, service_->file()); + + EXPECT_EQ("TestService2", service2_->name()); + EXPECT_EQ("corge.grault.TestService2", service2_->full_name()); + EXPECT_EQ(bar_file_, service2_->file()); +} + +TEST_F(ServiceDescriptorTest, MethodsByIndex) { + ASSERT_EQ(2, service_->method_count()); + EXPECT_EQ(foo_, service_->method(0)); + EXPECT_EQ(bar_, service_->method(1)); +} + +TEST_F(ServiceDescriptorTest, FindMethodByName) { + EXPECT_EQ(foo_ , service_ ->FindMethodByName("Foo")); + EXPECT_EQ(bar_ , service_ ->FindMethodByName("Bar")); + EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo")); + EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz")); + + EXPECT_TRUE(service_ ->FindMethodByName("NoSuchMethod") == NULL); + EXPECT_TRUE(service_ ->FindMethodByName("Baz" ) == NULL); + EXPECT_TRUE(service2_->FindMethodByName("Bar" ) == NULL); +} + +TEST_F(ServiceDescriptorTest, MethodName) { + EXPECT_EQ("Foo", foo_->name()); + EXPECT_EQ("Bar", bar_->name()); +} + +TEST_F(ServiceDescriptorTest, MethodFullName) { + EXPECT_EQ("TestService.Foo", foo_->full_name()); + EXPECT_EQ("TestService.Bar", bar_->full_name()); + EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name()); + EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name()); +} + +TEST_F(ServiceDescriptorTest, MethodIndex) { + EXPECT_EQ(0, foo_->index()); + EXPECT_EQ(1, bar_->index()); +} + +TEST_F(ServiceDescriptorTest, MethodParent) { + EXPECT_EQ(service_, foo_->service()); + EXPECT_EQ(service_, bar_->service()); +} + +TEST_F(ServiceDescriptorTest, MethodInputType) { + EXPECT_EQ(foo_request_, foo_->input_type()); + EXPECT_EQ(bar_request_, bar_->input_type()); +} + +TEST_F(ServiceDescriptorTest, MethodOutputType) { + EXPECT_EQ(foo_response_, foo_->output_type()); + EXPECT_EQ(bar_response_, bar_->output_type()); +} + +// =================================================================== + +// Test nested types. +class NestedDescriptorTest : public testing::Test { + protected: + virtual void SetUp() { + // Build descriptors for the following definitions: + // + // // in "foo.proto" + // message TestMessage { + // message Foo {} + // message Bar {} + // enum Baz { A = 1; } + // enum Qux { B = 1; } + // } + // + // // in "bar.proto" + // package corge.grault; + // message TestMessage2 { + // message Foo {} + // message Baz {} + // enum Qux { A = 1; } + // enum Quux { C = 1; } + // } + // + // TestMessage2 is primarily here to test FindNestedTypeByName and friends. + // All messages created from the same DescriptorPool share the same lookup + // table, so we need to insure that they don't interfere. + // + // We add enum values to the enums in order to test searching for enum + // values across a message's scope. + + FileDescriptorProto foo_file; + foo_file.set_name("foo.proto"); + + DescriptorProto* message = AddMessage(&foo_file, "TestMessage"); + AddNestedMessage(message, "Foo"); + AddNestedMessage(message, "Bar"); + EnumDescriptorProto* baz = AddNestedEnum(message, "Baz"); + AddEnumValue(baz, "A", 1); + EnumDescriptorProto* qux = AddNestedEnum(message, "Qux"); + AddEnumValue(qux, "B", 1); + + FileDescriptorProto bar_file; + bar_file.set_name("bar.proto"); + bar_file.set_package("corge.grault"); + + DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2"); + AddNestedMessage(message2, "Foo"); + AddNestedMessage(message2, "Baz"); + EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux"); + AddEnumValue(qux2, "A", 1); + EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux"); + AddEnumValue(quux2, "C", 1); + + // Build the descriptors and get the pointers. + foo_file_ = pool_.BuildFile(foo_file); + ASSERT_TRUE(foo_file_ != NULL); + + bar_file_ = pool_.BuildFile(bar_file); + ASSERT_TRUE(bar_file_ != NULL); + + ASSERT_EQ(1, foo_file_->message_type_count()); + message_ = foo_file_->message_type(0); + + ASSERT_EQ(2, message_->nested_type_count()); + foo_ = message_->nested_type(0); + bar_ = message_->nested_type(1); + + ASSERT_EQ(2, message_->enum_type_count()); + baz_ = message_->enum_type(0); + qux_ = message_->enum_type(1); + + ASSERT_EQ(1, baz_->value_count()); + a_ = baz_->value(0); + ASSERT_EQ(1, qux_->value_count()); + b_ = qux_->value(0); + + ASSERT_EQ(1, bar_file_->message_type_count()); + message2_ = bar_file_->message_type(0); + + ASSERT_EQ(2, message2_->nested_type_count()); + foo2_ = message2_->nested_type(0); + baz2_ = message2_->nested_type(1); + + ASSERT_EQ(2, message2_->enum_type_count()); + qux2_ = message2_->enum_type(0); + quux2_ = message2_->enum_type(1); + + ASSERT_EQ(1, qux2_->value_count()); + a2_ = qux2_->value(0); + ASSERT_EQ(1, quux2_->value_count()); + c2_ = quux2_->value(0); + } + + DescriptorPool pool_; + + const FileDescriptor* foo_file_; + const FileDescriptor* bar_file_; + + const Descriptor* message_; + const Descriptor* message2_; + + const Descriptor* foo_; + const Descriptor* bar_; + const EnumDescriptor* baz_; + const EnumDescriptor* qux_; + const EnumValueDescriptor* a_; + const EnumValueDescriptor* b_; + + const Descriptor* foo2_; + const Descriptor* baz2_; + const EnumDescriptor* qux2_; + const EnumDescriptor* quux2_; + const EnumValueDescriptor* a2_; + const EnumValueDescriptor* c2_; +}; + +TEST_F(NestedDescriptorTest, MessageName) { + EXPECT_EQ("Foo", foo_ ->name()); + EXPECT_EQ("Bar", bar_ ->name()); + EXPECT_EQ("Foo", foo2_->name()); + EXPECT_EQ("Baz", baz2_->name()); + + EXPECT_EQ("TestMessage.Foo", foo_->full_name()); + EXPECT_EQ("TestMessage.Bar", bar_->full_name()); + EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name()); + EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name()); +} + +TEST_F(NestedDescriptorTest, MessageContainingType) { + EXPECT_EQ(message_ , foo_ ->containing_type()); + EXPECT_EQ(message_ , bar_ ->containing_type()); + EXPECT_EQ(message2_, foo2_->containing_type()); + EXPECT_EQ(message2_, baz2_->containing_type()); +} + +TEST_F(NestedDescriptorTest, NestedMessagesByIndex) { + ASSERT_EQ(2, message_->nested_type_count()); + EXPECT_EQ(foo_, message_->nested_type(0)); + EXPECT_EQ(bar_, message_->nested_type(1)); +} + +TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) { + EXPECT_TRUE(message_->FindFieldByName("Foo") == NULL); + EXPECT_TRUE(message_->FindFieldByName("Qux") == NULL); + EXPECT_TRUE(message_->FindExtensionByName("Foo") == NULL); + EXPECT_TRUE(message_->FindExtensionByName("Qux") == NULL); +} + +TEST_F(NestedDescriptorTest, FindNestedTypeByName) { + EXPECT_EQ(foo_ , message_ ->FindNestedTypeByName("Foo")); + EXPECT_EQ(bar_ , message_ ->FindNestedTypeByName("Bar")); + EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo")); + EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz")); + + EXPECT_TRUE(message_ ->FindNestedTypeByName("NoSuchType") == NULL); + EXPECT_TRUE(message_ ->FindNestedTypeByName("Baz" ) == NULL); + EXPECT_TRUE(message2_->FindNestedTypeByName("Bar" ) == NULL); + + EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == NULL); +} + +TEST_F(NestedDescriptorTest, EnumName) { + EXPECT_EQ("Baz" , baz_ ->name()); + EXPECT_EQ("Qux" , qux_ ->name()); + EXPECT_EQ("Qux" , qux2_->name()); + EXPECT_EQ("Quux", quux2_->name()); + + EXPECT_EQ("TestMessage.Baz", baz_->full_name()); + EXPECT_EQ("TestMessage.Qux", qux_->full_name()); + EXPECT_EQ("corge.grault.TestMessage2.Qux" , qux2_ ->full_name()); + EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name()); +} + +TEST_F(NestedDescriptorTest, EnumContainingType) { + EXPECT_EQ(message_ , baz_ ->containing_type()); + EXPECT_EQ(message_ , qux_ ->containing_type()); + EXPECT_EQ(message2_, qux2_ ->containing_type()); + EXPECT_EQ(message2_, quux2_->containing_type()); +} + +TEST_F(NestedDescriptorTest, NestedEnumsByIndex) { + ASSERT_EQ(2, message_->nested_type_count()); + EXPECT_EQ(foo_, message_->nested_type(0)); + EXPECT_EQ(bar_, message_->nested_type(1)); +} + +TEST_F(NestedDescriptorTest, FindEnumTypeByName) { + EXPECT_EQ(baz_ , message_ ->FindEnumTypeByName("Baz" )); + EXPECT_EQ(qux_ , message_ ->FindEnumTypeByName("Qux" )); + EXPECT_EQ(qux2_ , message2_->FindEnumTypeByName("Qux" )); + EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux")); + + EXPECT_TRUE(message_ ->FindEnumTypeByName("NoSuchType") == NULL); + EXPECT_TRUE(message_ ->FindEnumTypeByName("Quux" ) == NULL); + EXPECT_TRUE(message2_->FindEnumTypeByName("Baz" ) == NULL); + + EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == NULL); +} + +TEST_F(NestedDescriptorTest, FindEnumValueByName) { + EXPECT_EQ(a_ , message_ ->FindEnumValueByName("A")); + EXPECT_EQ(b_ , message_ ->FindEnumValueByName("B")); + EXPECT_EQ(a2_, message2_->FindEnumValueByName("A")); + EXPECT_EQ(c2_, message2_->FindEnumValueByName("C")); + + EXPECT_TRUE(message_ ->FindEnumValueByName("NO_SUCH_VALUE") == NULL); + EXPECT_TRUE(message_ ->FindEnumValueByName("C" ) == NULL); + EXPECT_TRUE(message2_->FindEnumValueByName("B" ) == NULL); + + EXPECT_TRUE(message_->FindEnumValueByName("Foo") == NULL); +} + +// =================================================================== + +// Test extensions. +class ExtensionDescriptorTest : public testing::Test { + protected: + virtual void SetUp() { + // Build descriptors for the following definitions: + // + // enum Baz {} + // message Qux {} + // + // message Foo { + // extensions 10 to 19; + // extensions 30 to 39; + // } + // extends Foo with optional int32 foo_int32 = 10; + // extends Foo with repeated TestEnum foo_enum = 19; + // message Bar { + // extends Foo with optional Qux foo_message = 30; + // // (using Qux as the group type) + // extends Foo with repeated group foo_group = 39; + // } + + FileDescriptorProto foo_file; + foo_file.set_name("foo.proto"); + + AddEmptyEnum(&foo_file, "Baz"); + AddMessage(&foo_file, "Qux"); + + DescriptorProto* foo = AddMessage(&foo_file, "Foo"); + AddExtensionRange(foo, 10, 20); + AddExtensionRange(foo, 30, 40); + + AddExtension(&foo_file, "Foo", "foo_int32", 10, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + AddExtension(&foo_file, "Foo", "foo_enum", 19, + FieldDescriptorProto::LABEL_REPEATED, + FieldDescriptorProto::TYPE_ENUM) + ->set_type_name("Baz"); + + DescriptorProto* bar = AddMessage(&foo_file, "Bar"); + AddNestedExtension(bar, "Foo", "foo_message", 30, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_MESSAGE) + ->set_type_name("Qux"); + AddNestedExtension(bar, "Foo", "foo_group", 39, + FieldDescriptorProto::LABEL_REPEATED, + FieldDescriptorProto::TYPE_GROUP) + ->set_type_name("Qux"); + + // Build the descriptors and get the pointers. + foo_file_ = pool_.BuildFile(foo_file); + ASSERT_TRUE(foo_file_ != NULL); + + ASSERT_EQ(1, foo_file_->enum_type_count()); + baz_ = foo_file_->enum_type(0); + + ASSERT_EQ(3, foo_file_->message_type_count()); + qux_ = foo_file_->message_type(0); + foo_ = foo_file_->message_type(1); + bar_ = foo_file_->message_type(2); + } + + DescriptorPool pool_; + + const FileDescriptor* foo_file_; + + const Descriptor* foo_; + const Descriptor* bar_; + const EnumDescriptor* baz_; + const Descriptor* qux_; +}; + +TEST_F(ExtensionDescriptorTest, ExtensionRanges) { + EXPECT_EQ(0, bar_->extension_range_count()); + ASSERT_EQ(2, foo_->extension_range_count()); + + EXPECT_EQ(10, foo_->extension_range(0)->start); + EXPECT_EQ(30, foo_->extension_range(1)->start); + + EXPECT_EQ(20, foo_->extension_range(0)->end); + EXPECT_EQ(40, foo_->extension_range(1)->end); +}; + +TEST_F(ExtensionDescriptorTest, Extensions) { + EXPECT_EQ(0, foo_->extension_count()); + ASSERT_EQ(2, foo_file_->extension_count()); + ASSERT_EQ(2, bar_->extension_count()); + + EXPECT_TRUE(foo_file_->extension(0)->is_extension()); + EXPECT_TRUE(foo_file_->extension(1)->is_extension()); + EXPECT_TRUE(bar_->extension(0)->is_extension()); + EXPECT_TRUE(bar_->extension(1)->is_extension()); + + EXPECT_EQ("foo_int32" , foo_file_->extension(0)->name()); + EXPECT_EQ("foo_enum" , foo_file_->extension(1)->name()); + EXPECT_EQ("foo_message", bar_->extension(0)->name()); + EXPECT_EQ("foo_group" , bar_->extension(1)->name()); + + EXPECT_EQ(10, foo_file_->extension(0)->number()); + EXPECT_EQ(19, foo_file_->extension(1)->number()); + EXPECT_EQ(30, bar_->extension(0)->number()); + EXPECT_EQ(39, bar_->extension(1)->number()); + + EXPECT_EQ(FieldDescriptor::TYPE_INT32 , foo_file_->extension(0)->type()); + EXPECT_EQ(FieldDescriptor::TYPE_ENUM , foo_file_->extension(1)->type()); + EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type()); + EXPECT_EQ(FieldDescriptor::TYPE_GROUP , bar_->extension(1)->type()); + + EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type()); + EXPECT_EQ(qux_, bar_->extension(0)->message_type()); + EXPECT_EQ(qux_, bar_->extension(1)->message_type()); + + EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label()); + EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label()); + EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label()); + EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label()); + + EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type()); + EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type()); + EXPECT_EQ(foo_, bar_->extension(0)->containing_type()); + EXPECT_EQ(foo_, bar_->extension(1)->containing_type()); + + EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == NULL); + EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == NULL); + EXPECT_EQ(bar_, bar_->extension(0)->extension_scope()); + EXPECT_EQ(bar_, bar_->extension(1)->extension_scope()); +}; + +TEST_F(ExtensionDescriptorTest, IsExtensionNumber) { + EXPECT_FALSE(foo_->IsExtensionNumber( 9)); + EXPECT_TRUE (foo_->IsExtensionNumber(10)); + EXPECT_TRUE (foo_->IsExtensionNumber(19)); + EXPECT_FALSE(foo_->IsExtensionNumber(20)); + EXPECT_FALSE(foo_->IsExtensionNumber(29)); + EXPECT_TRUE (foo_->IsExtensionNumber(30)); + EXPECT_TRUE (foo_->IsExtensionNumber(39)); + EXPECT_FALSE(foo_->IsExtensionNumber(40)); +} + +TEST_F(ExtensionDescriptorTest, FindExtensionByName) { + // Note that FileDescriptor::FindExtensionByName() is tested by + // FileDescriptorTest. + ASSERT_EQ(2, bar_->extension_count()); + + EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message")); + EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group" )); + + EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL); + EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL); + EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL); +} + +TEST_F(ExtensionDescriptorTest, FindAllExtensions) { + vector extensions; + pool_.FindAllExtensions(foo_, &extensions); + ASSERT_EQ(4, extensions.size()); + EXPECT_EQ(10, extensions[0]->number()); + EXPECT_EQ(19, extensions[1]->number()); + EXPECT_EQ(30, extensions[2]->number()); + EXPECT_EQ(39, extensions[3]->number()); +} + +// =================================================================== + +class MiscTest : public testing::Test { + protected: + // Function which makes a field descriptor of the given type. + const FieldDescriptor* GetFieldDescriptorOfType(FieldDescriptor::Type type) { + FileDescriptorProto file_proto; + file_proto.set_name("foo.proto"); + AddEmptyEnum(&file_proto, "DummyEnum"); + + DescriptorProto* message = AddMessage(&file_proto, "TestMessage"); + FieldDescriptorProto* field = + AddField(message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL, + static_cast(static_cast(type))); + + if (type == FieldDescriptor::TYPE_MESSAGE || + type == FieldDescriptor::TYPE_GROUP) { + field->set_type_name("TestMessage"); + } else if (type == FieldDescriptor::TYPE_ENUM) { + field->set_type_name("DummyEnum"); + } + + // Build the descriptors and get the pointers. + pool_.reset(new DescriptorPool()); + const FileDescriptor* file = pool_->BuildFile(file_proto); + + if (file != NULL && + file->message_type_count() == 1 && + file->message_type(0)->field_count() == 1) { + return file->message_type(0)->field(0); + } else { + return NULL; + } + } + + const char* GetTypeNameForFieldType(FieldDescriptor::Type type) { + const FieldDescriptor* field = GetFieldDescriptorOfType(type); + return field != NULL ? field->type_name() : ""; + } + + FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) { + const FieldDescriptor* field = GetFieldDescriptorOfType(type); + return field != NULL ? field->cpp_type() : + static_cast(0); + } + + const char* GetCppTypeNameForFieldType(FieldDescriptor::Type type) { + const FieldDescriptor* field = GetFieldDescriptorOfType(type); + return field != NULL ? field->cpp_type_name() : ""; + } + + scoped_ptr pool_; +}; + +TEST_F(MiscTest, TypeNames) { + // Test that correct type names are returned. + + typedef FieldDescriptor FD; // avoid ugly line wrapping + + EXPECT_STREQ("double" , GetTypeNameForFieldType(FD::TYPE_DOUBLE )); + EXPECT_STREQ("float" , GetTypeNameForFieldType(FD::TYPE_FLOAT )); + EXPECT_STREQ("int64" , GetTypeNameForFieldType(FD::TYPE_INT64 )); + EXPECT_STREQ("uint64" , GetTypeNameForFieldType(FD::TYPE_UINT64 )); + EXPECT_STREQ("int32" , GetTypeNameForFieldType(FD::TYPE_INT32 )); + EXPECT_STREQ("fixed64" , GetTypeNameForFieldType(FD::TYPE_FIXED64 )); + EXPECT_STREQ("fixed32" , GetTypeNameForFieldType(FD::TYPE_FIXED32 )); + EXPECT_STREQ("bool" , GetTypeNameForFieldType(FD::TYPE_BOOL )); + EXPECT_STREQ("string" , GetTypeNameForFieldType(FD::TYPE_STRING )); + EXPECT_STREQ("group" , GetTypeNameForFieldType(FD::TYPE_GROUP )); + EXPECT_STREQ("message" , GetTypeNameForFieldType(FD::TYPE_MESSAGE )); + EXPECT_STREQ("bytes" , GetTypeNameForFieldType(FD::TYPE_BYTES )); + EXPECT_STREQ("uint32" , GetTypeNameForFieldType(FD::TYPE_UINT32 )); + EXPECT_STREQ("enum" , GetTypeNameForFieldType(FD::TYPE_ENUM )); + EXPECT_STREQ("sfixed32", GetTypeNameForFieldType(FD::TYPE_SFIXED32)); + EXPECT_STREQ("sfixed64", GetTypeNameForFieldType(FD::TYPE_SFIXED64)); + EXPECT_STREQ("sint32" , GetTypeNameForFieldType(FD::TYPE_SINT32 )); + EXPECT_STREQ("sint64" , GetTypeNameForFieldType(FD::TYPE_SINT64 )); +} + +TEST_F(MiscTest, CppTypes) { + // Test that CPP types are assigned correctly. + + typedef FieldDescriptor FD; // avoid ugly line wrapping + + EXPECT_EQ(FD::CPPTYPE_DOUBLE , GetCppTypeForFieldType(FD::TYPE_DOUBLE )); + EXPECT_EQ(FD::CPPTYPE_FLOAT , GetCppTypeForFieldType(FD::TYPE_FLOAT )); + EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_INT64 )); + EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_UINT64 )); + EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_INT32 )); + EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_FIXED64 )); + EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_FIXED32 )); + EXPECT_EQ(FD::CPPTYPE_BOOL , GetCppTypeForFieldType(FD::TYPE_BOOL )); + EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_STRING )); + EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP )); + EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE )); + EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_BYTES )); + EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_UINT32 )); + EXPECT_EQ(FD::CPPTYPE_ENUM , GetCppTypeForFieldType(FD::TYPE_ENUM )); + EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_SFIXED32)); + EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SFIXED64)); + EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_SINT32 )); + EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SINT64 )); +} + +TEST_F(MiscTest, CppTypeNames) { + // Test that correct CPP type names are returned. + + typedef FieldDescriptor FD; // avoid ugly line wrapping + + EXPECT_STREQ("double" , GetCppTypeNameForFieldType(FD::TYPE_DOUBLE )); + EXPECT_STREQ("float" , GetCppTypeNameForFieldType(FD::TYPE_FLOAT )); + EXPECT_STREQ("int64" , GetCppTypeNameForFieldType(FD::TYPE_INT64 )); + EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_UINT64 )); + EXPECT_STREQ("int32" , GetCppTypeNameForFieldType(FD::TYPE_INT32 )); + EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_FIXED64 )); + EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_FIXED32 )); + EXPECT_STREQ("bool" , GetCppTypeNameForFieldType(FD::TYPE_BOOL )); + EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_STRING )); + EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_GROUP )); + EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_MESSAGE )); + EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_BYTES )); + EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_UINT32 )); + EXPECT_STREQ("enum" , GetCppTypeNameForFieldType(FD::TYPE_ENUM )); + EXPECT_STREQ("int32" , GetCppTypeNameForFieldType(FD::TYPE_SFIXED32)); + EXPECT_STREQ("int64" , GetCppTypeNameForFieldType(FD::TYPE_SFIXED64)); + EXPECT_STREQ("int32" , GetCppTypeNameForFieldType(FD::TYPE_SINT32 )); + EXPECT_STREQ("int64" , GetCppTypeNameForFieldType(FD::TYPE_SINT64 )); +} + +TEST_F(MiscTest, DefaultValues) { + // Test that setting default values works. + FileDescriptorProto file_proto; + file_proto.set_name("foo.proto"); + + EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum"); + AddEnumValue(enum_type_proto, "A", 1); + AddEnumValue(enum_type_proto, "B", 2); + + DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage"); + + typedef FieldDescriptorProto FD; // avoid ugly line wrapping + const FD::Label label = FD::LABEL_OPTIONAL; + + // Create fields of every CPP type with default values. + AddField(message_proto, "int32" , 1, label, FD::TYPE_INT32 ) + ->set_default_value("-1"); + AddField(message_proto, "int64" , 2, label, FD::TYPE_INT64 ) + ->set_default_value("-1000000000000"); + AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32) + ->set_default_value("42"); + AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64) + ->set_default_value("2000000000000"); + AddField(message_proto, "float" , 5, label, FD::TYPE_FLOAT ) + ->set_default_value("4.5"); + AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE) + ->set_default_value("10e100"); + AddField(message_proto, "bool" , 7, label, FD::TYPE_BOOL ) + ->set_default_value("true"); + AddField(message_proto, "string", 8, label, FD::TYPE_STRING) + ->set_default_value("hello"); + AddField(message_proto, "data" , 9, label, FD::TYPE_BYTES ) + ->set_default_value("\\001\\002\\003"); + + FieldDescriptorProto* enum_field = + AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM); + enum_field->set_type_name("DummyEnum"); + enum_field->set_default_value("B"); + + // Strings are allowed to have empty defaults. (At one point, due to + // a bug, empty defaults for strings were rejected. Oops.) + AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING) + ->set_default_value(""); + + // Add a second set of fields with implicit defalut values. + AddField(message_proto, "implicit_int32" , 21, label, FD::TYPE_INT32 ); + AddField(message_proto, "implicit_int64" , 22, label, FD::TYPE_INT64 ); + AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32); + AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64); + AddField(message_proto, "implicit_float" , 25, label, FD::TYPE_FLOAT ); + AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE); + AddField(message_proto, "implicit_bool" , 27, label, FD::TYPE_BOOL ); + AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING); + AddField(message_proto, "implicit_data" , 29, label, FD::TYPE_BYTES ); + AddField(message_proto, "implicit_enum" , 30, label, FD::TYPE_ENUM) + ->set_type_name("DummyEnum"); + + // Build it. + DescriptorPool pool; + const FileDescriptor* file = pool.BuildFile(file_proto); + ASSERT_TRUE(file != NULL); + + ASSERT_EQ(1, file->enum_type_count()); + const EnumDescriptor* enum_type = file->enum_type(0); + ASSERT_EQ(2, enum_type->value_count()); + const EnumValueDescriptor* enum_value_a = enum_type->value(0); + const EnumValueDescriptor* enum_value_b = enum_type->value(1); + + ASSERT_EQ(1, file->message_type_count()); + const Descriptor* message = file->message_type(0); + + ASSERT_EQ(21, message->field_count()); + + // Check the default values. + ASSERT_TRUE(message->field(0)->has_default_value()); + ASSERT_TRUE(message->field(1)->has_default_value()); + ASSERT_TRUE(message->field(2)->has_default_value()); + ASSERT_TRUE(message->field(3)->has_default_value()); + ASSERT_TRUE(message->field(4)->has_default_value()); + ASSERT_TRUE(message->field(5)->has_default_value()); + ASSERT_TRUE(message->field(6)->has_default_value()); + ASSERT_TRUE(message->field(7)->has_default_value()); + ASSERT_TRUE(message->field(8)->has_default_value()); + ASSERT_TRUE(message->field(9)->has_default_value()); + ASSERT_TRUE(message->field(10)->has_default_value()); + + EXPECT_EQ(-1 , message->field(0)->default_value_int32 ()); + EXPECT_EQ(-GOOGLE_ULONGLONG(1000000000000), + message->field(1)->default_value_int64 ()); + EXPECT_EQ(42 , message->field(2)->default_value_uint32()); + EXPECT_EQ(GOOGLE_ULONGLONG(2000000000000), + message->field(3)->default_value_uint64()); + EXPECT_EQ(4.5 , message->field(4)->default_value_float ()); + EXPECT_EQ(10e100 , message->field(5)->default_value_double()); + EXPECT_TRUE( message->field(6)->default_value_bool ()); + EXPECT_EQ("hello" , message->field(7)->default_value_string()); + EXPECT_EQ("\001\002\003" , message->field(8)->default_value_string()); + EXPECT_EQ(enum_value_b , message->field(9)->default_value_enum ()); + EXPECT_EQ("" , message->field(10)->default_value_string()); + + ASSERT_FALSE(message->field(11)->has_default_value()); + ASSERT_FALSE(message->field(12)->has_default_value()); + ASSERT_FALSE(message->field(13)->has_default_value()); + ASSERT_FALSE(message->field(14)->has_default_value()); + ASSERT_FALSE(message->field(15)->has_default_value()); + ASSERT_FALSE(message->field(16)->has_default_value()); + ASSERT_FALSE(message->field(17)->has_default_value()); + ASSERT_FALSE(message->field(18)->has_default_value()); + ASSERT_FALSE(message->field(19)->has_default_value()); + ASSERT_FALSE(message->field(20)->has_default_value()); + + EXPECT_EQ(0 , message->field(11)->default_value_int32 ()); + EXPECT_EQ(0 , message->field(12)->default_value_int64 ()); + EXPECT_EQ(0 , message->field(13)->default_value_uint32()); + EXPECT_EQ(0 , message->field(14)->default_value_uint64()); + EXPECT_EQ(0.0f , message->field(15)->default_value_float ()); + EXPECT_EQ(0.0 , message->field(16)->default_value_double()); + EXPECT_FALSE( message->field(17)->default_value_bool ()); + EXPECT_EQ("" , message->field(18)->default_value_string()); + EXPECT_EQ("" , message->field(19)->default_value_string()); + EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum()); +} + +TEST_F(MiscTest, FieldOptions) { + // Try setting field options. + + FileDescriptorProto file_proto; + file_proto.set_name("foo.proto"); + + DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage"); + AddField(message_proto, "foo", 1, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + FieldDescriptorProto* bar_proto = + AddField(message_proto, "bar", 2, + FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); + + FieldOptions* options = bar_proto->mutable_options(); + options->set_ctype(FieldOptions::CORD); + + // Build the descriptors and get the pointers. + DescriptorPool pool; + const FileDescriptor* file = pool.BuildFile(file_proto); + ASSERT_TRUE(file != NULL); + + ASSERT_EQ(1, file->message_type_count()); + const Descriptor* message = file->message_type(0); + + ASSERT_EQ(2, message->field_count()); + const FieldDescriptor* foo = message->field(0); + const FieldDescriptor* bar = message->field(1); + + // "foo" had no options set, so it should return the default options. + EXPECT_EQ(&FieldOptions::default_instance(), &foo->options()); + + // "bar" had options set. + EXPECT_NE(&FieldOptions::default_instance(), options); + EXPECT_TRUE(bar->options().has_ctype()); + EXPECT_EQ(FieldOptions::CORD, bar->options().ctype()); +} + +// =================================================================== +enum DescriptorPoolMode { + NO_DATABASE, + FALLBACK_DATABASE +}; + +class AllowUnknownDependenciesTest + : public testing::TestWithParam { + protected: + DescriptorPoolMode mode() { + return GetParam(); + } + + virtual void SetUp() { + FileDescriptorProto foo_proto, bar_proto; + + switch (mode()) { + case NO_DATABASE: + pool_.reset(new DescriptorPool); + break; + case FALLBACK_DATABASE: + pool_.reset(new DescriptorPool(&db_)); + break; + } + + pool_->AllowUnknownDependencies(); + + ASSERT_TRUE(TextFormat::ParseFromString( + "name: 'foo.proto'" + "dependency: 'bar.proto'" + "dependency: 'baz.proto'" + "message_type {" + " name: 'Foo'" + " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }" + " field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }" + " field { name:'qux' number:3 label:LABEL_OPTIONAL" + " type_name: '.corge.Qux'" + " type: TYPE_ENUM" + " options {" + " uninterpreted_option {" + " name {" + " name_part: 'grault'" + " is_extension: true" + " }" + " positive_int_value: 1234" + " }" + " }" + " }" + "}", + &foo_proto)); + ASSERT_TRUE(TextFormat::ParseFromString( + "name: 'bar.proto'" + "message_type { name: 'Bar' }", + &bar_proto)); + + // Collect pointers to stuff. + bar_file_ = BuildFile(bar_proto); + ASSERT_TRUE(bar_file_ != NULL); + + ASSERT_EQ(1, bar_file_->message_type_count()); + bar_type_ = bar_file_->message_type(0); + + foo_file_ = BuildFile(foo_proto); + ASSERT_TRUE(foo_file_ != NULL); + + ASSERT_EQ(1, foo_file_->message_type_count()); + foo_type_ = foo_file_->message_type(0); + + ASSERT_EQ(3, foo_type_->field_count()); + bar_field_ = foo_type_->field(0); + baz_field_ = foo_type_->field(1); + qux_field_ = foo_type_->field(2); + } + + const FileDescriptor* BuildFile(const FileDescriptorProto& proto) { + switch (mode()) { + case NO_DATABASE: + return pool_->BuildFile(proto); + break; + case FALLBACK_DATABASE: { + EXPECT_TRUE(db_.Add(proto)); + return pool_->FindFileByName(proto.name()); + } + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; + } + + const FileDescriptor* bar_file_; + const Descriptor* bar_type_; + const FileDescriptor* foo_file_; + const Descriptor* foo_type_; + const FieldDescriptor* bar_field_; + const FieldDescriptor* baz_field_; + const FieldDescriptor* qux_field_; + + SimpleDescriptorDatabase db_; // used if in FALLBACK_DATABASE mode. + scoped_ptr pool_; +}; + +TEST_P(AllowUnknownDependenciesTest, PlaceholderFile) { + ASSERT_EQ(2, foo_file_->dependency_count()); + EXPECT_EQ(bar_file_, foo_file_->dependency(0)); + + const FileDescriptor* baz_file = foo_file_->dependency(1); + EXPECT_EQ("baz.proto", baz_file->name()); + EXPECT_EQ(0, baz_file->message_type_count()); + + // Placeholder files should not be findable. + EXPECT_EQ(bar_file_, pool_->FindFileByName(bar_file_->name())); + EXPECT_TRUE(pool_->FindFileByName(baz_file->name()) == NULL); +} + +TEST_P(AllowUnknownDependenciesTest, PlaceholderTypes) { + ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type()); + EXPECT_EQ(bar_type_, bar_field_->message_type()); + + ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type()); + const Descriptor* baz_type = baz_field_->message_type(); + EXPECT_EQ("Baz", baz_type->name()); + EXPECT_EQ("Baz", baz_type->full_name()); + EXPECT_EQ("Baz.placeholder.proto", baz_type->file()->name()); + EXPECT_EQ(0, baz_type->extension_range_count()); + + ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type()); + const EnumDescriptor* qux_type = qux_field_->enum_type(); + EXPECT_EQ("Qux", qux_type->name()); + EXPECT_EQ("corge.Qux", qux_type->full_name()); + EXPECT_EQ("corge.Qux.placeholder.proto", qux_type->file()->name()); + + // Placeholder types should not be findable. + EXPECT_EQ(bar_type_, pool_->FindMessageTypeByName(bar_type_->full_name())); + EXPECT_TRUE(pool_->FindMessageTypeByName(baz_type->full_name()) == NULL); + EXPECT_TRUE(pool_->FindEnumTypeByName(qux_type->full_name()) == NULL); +} + +TEST_P(AllowUnknownDependenciesTest, CopyTo) { + // FieldDescriptor::CopyTo() should write non-fully-qualified type names + // for placeholder types which were not originally fully-qualified. + FieldDescriptorProto proto; + + // Bar is not a placeholder, so it is fully-qualified. + bar_field_->CopyTo(&proto); + EXPECT_EQ(".Bar", proto.type_name()); + EXPECT_EQ(FieldDescriptorProto::TYPE_MESSAGE, proto.type()); + + // Baz is an unqualified placeholder. + proto.Clear(); + baz_field_->CopyTo(&proto); + EXPECT_EQ("Baz", proto.type_name()); + EXPECT_FALSE(proto.has_type()); + + // Qux is a fully-qualified placeholder. + proto.Clear(); + qux_field_->CopyTo(&proto); + EXPECT_EQ(".corge.Qux", proto.type_name()); + EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type()); +} + +TEST_P(AllowUnknownDependenciesTest, CustomOptions) { + // Qux should still have the uninterpreted option attached. + ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size()); + const UninterpretedOption& option = + qux_field_->options().uninterpreted_option(0); + ASSERT_EQ(1, option.name_size()); + EXPECT_EQ("grault", option.name(0).name_part()); +} + +TEST_P(AllowUnknownDependenciesTest, UnknownExtendee) { + // Test that we can extend an unknown type. This is slightly tricky because + // it means that the placeholder type must have an extension range. + + FileDescriptorProto extension_proto; + + ASSERT_TRUE(TextFormat::ParseFromString( + "name: 'extension.proto'" + "extension { extendee: 'UnknownType' name:'some_extension' number:123" + " label:LABEL_OPTIONAL type:TYPE_INT32 }", + &extension_proto)); + const FileDescriptor* file = BuildFile(extension_proto); + + ASSERT_TRUE(file != NULL); + + ASSERT_EQ(1, file->extension_count()); + const Descriptor* extendee = file->extension(0)->containing_type(); + EXPECT_EQ("UnknownType", extendee->name()); + ASSERT_EQ(1, extendee->extension_range_count()); + EXPECT_EQ(1, extendee->extension_range(0)->start); + EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end); +} + +TEST_P(AllowUnknownDependenciesTest, CustomOption) { + // Test that we can use a custom option without having parsed + // descriptor.proto. + + FileDescriptorProto option_proto; + + ASSERT_TRUE(TextFormat::ParseFromString( + "name: \"unknown_custom_options.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { " + " extendee: \"google.protobuf.FileOptions\" " + " name: \"some_option\" " + " number: 123456 " + " label: LABEL_OPTIONAL " + " type: TYPE_INT32 " + "} " + "options { " + " uninterpreted_option { " + " name { " + " name_part: \"some_option\" " + " is_extension: true " + " } " + " positive_int_value: 1234 " + " } " + " uninterpreted_option { " + " name { " + " name_part: \"unknown_option\" " + " is_extension: true " + " } " + " positive_int_value: 1234 " + " } " + " uninterpreted_option { " + " name { " + " name_part: \"optimize_for\" " + " is_extension: false " + " } " + " identifier_value: \"SPEED\" " + " } " + "}", + &option_proto)); + + const FileDescriptor* file = BuildFile(option_proto); + ASSERT_TRUE(file != NULL); + + // Verify that no extension options were set, but they were left as + // uninterpreted_options. + vector fields; + file->options().GetReflection()->ListFields(file->options(), &fields); + ASSERT_EQ(2, fields.size()); + EXPECT_TRUE(file->options().has_optimize_for()); + EXPECT_EQ(2, file->options().uninterpreted_option_size()); +} + +TEST_P(AllowUnknownDependenciesTest, + UndeclaredDependencyTriggersBuildOfDependency) { + // Crazy case: suppose foo.proto refers to a symbol without declaring the + // dependency that finds it. In the event that the pool is backed by a + // DescriptorDatabase, the pool will attempt to find the symbol in the + // database. If successful, it will build the undeclared dependency to verify + // that the file does indeed contain the symbol. If that file fails to build, + // then its descriptors must be rolled back. However, we still want foo.proto + // to build successfully, since we are allowing unknown dependencies. + + FileDescriptorProto undeclared_dep_proto; + // We make this file fail to build by giving it two fields with tag 1. + ASSERT_TRUE(TextFormat::ParseFromString( + "name: \"invalid_file_as_undeclared_dep.proto\" " + "package: \"undeclared\" " + "message_type: { " + " name: \"Quux\" " + " field { " + " name:'qux' number:1 label:LABEL_OPTIONAL type: TYPE_INT32 " + " }" + " field { " + " name:'quux' number:1 label:LABEL_OPTIONAL type: TYPE_INT64 " + " }" + "}", + &undeclared_dep_proto)); + // We can't use the BuildFile() helper because we don't actually want to build + // it into the descriptor pool in the fallback database case: it just needs to + // be sitting in the database so that it gets built during the building of + // test.proto below. + switch (mode()) { + case NO_DATABASE: { + ASSERT_TRUE(pool_->BuildFile(undeclared_dep_proto) == NULL); + break; + } + case FALLBACK_DATABASE: { + ASSERT_TRUE(db_.Add(undeclared_dep_proto)); + } + } + + FileDescriptorProto test_proto; + ASSERT_TRUE(TextFormat::ParseFromString( + "name: \"test.proto\" " + "message_type: { " + " name: \"Corge\" " + " field { " + " name:'quux' number:1 label: LABEL_OPTIONAL " + " type_name:'undeclared.Quux' type: TYPE_MESSAGE " + " }" + "}", + &test_proto)); + + const FileDescriptor* file = BuildFile(test_proto); + ASSERT_TRUE(file != NULL); + GOOGLE_LOG(INFO) << file->DebugString(); + + EXPECT_EQ(0, file->dependency_count()); + ASSERT_EQ(1, file->message_type_count()); + const Descriptor* corge_desc = file->message_type(0); + ASSERT_EQ("Corge", corge_desc->name()); + ASSERT_EQ(1, corge_desc->field_count()); + + const FieldDescriptor* quux_field = corge_desc->field(0); + ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, quux_field->type()); + ASSERT_EQ("Quux", quux_field->message_type()->name()); + ASSERT_EQ("undeclared.Quux", quux_field->message_type()->full_name()); + EXPECT_EQ("undeclared.Quux.placeholder.proto", + quux_field->message_type()->file()->name()); + // The place holder type should not be findable. + ASSERT_TRUE(pool_->FindMessageTypeByName("undeclared.Quux") == NULL); +} + +INSTANTIATE_TEST_CASE_P(DatabaseSource, + AllowUnknownDependenciesTest, + testing::Values(NO_DATABASE, FALLBACK_DATABASE)); + +// =================================================================== + +TEST(CustomOptions, OptionLocations) { + const Descriptor* message = + protobuf_unittest::TestMessageWithCustomOptions::descriptor(); + const FileDescriptor* file = message->file(); + const FieldDescriptor* field = message->FindFieldByName("field1"); + const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum"); + // TODO(benjy): Support EnumValue options, once the compiler does. + const ServiceDescriptor* service = + file->FindServiceByName("TestServiceWithCustomOptions"); + const MethodDescriptor* method = service->FindMethodByName("Foo"); + + EXPECT_EQ(GOOGLE_LONGLONG(9876543210), + file->options().GetExtension(protobuf_unittest::file_opt1)); + EXPECT_EQ(-56, + message->options().GetExtension(protobuf_unittest::message_opt1)); + EXPECT_EQ(GOOGLE_LONGLONG(8765432109), + field->options().GetExtension(protobuf_unittest::field_opt1)); + EXPECT_EQ(42, // Check that we get the default for an option we don't set. + field->options().GetExtension(protobuf_unittest::field_opt2)); + EXPECT_EQ(-789, + enm->options().GetExtension(protobuf_unittest::enum_opt1)); + EXPECT_EQ(123, + enm->value(1)->options().GetExtension( + protobuf_unittest::enum_value_opt1)); + EXPECT_EQ(GOOGLE_LONGLONG(-9876543210), + service->options().GetExtension(protobuf_unittest::service_opt1)); + EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2, + method->options().GetExtension(protobuf_unittest::method_opt1)); + + // See that the regular options went through unscathed. + EXPECT_TRUE(message->options().has_message_set_wire_format()); + EXPECT_EQ(FieldOptions::CORD, field->options().ctype()); +} + +TEST(CustomOptions, OptionTypes) { + const MessageOptions* options = NULL; + + options = + &protobuf_unittest::CustomOptionMinIntegerValues::descriptor()->options(); + EXPECT_FALSE( options->GetExtension(protobuf_unittest::bool_opt)); + EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt)); + EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt)); + EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::uint32_opt)); + EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::uint64_opt)); + EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sint32_opt)); + EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sint64_opt)); + EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::fixed32_opt)); + EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::fixed64_opt)); + EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sfixed32_opt)); + EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sfixed64_opt)); + + options = + &protobuf_unittest::CustomOptionMaxIntegerValues::descriptor()->options(); + EXPECT_TRUE( options->GetExtension(protobuf_unittest::bool_opt)); + EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::int32_opt)); + EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::int64_opt)); + EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt)); + EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::uint64_opt)); + EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sint32_opt)); + EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sint64_opt)); + EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::fixed32_opt)); + EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::fixed64_opt)); + EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sfixed32_opt)); + EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sfixed64_opt)); + + options = + &protobuf_unittest::CustomOptionOtherValues::descriptor()->options(); + EXPECT_EQ(-100, options->GetExtension(protobuf_unittest::int32_opt)); + EXPECT_FLOAT_EQ(12.3456789, + options->GetExtension(protobuf_unittest::float_opt)); + EXPECT_DOUBLE_EQ(1.234567890123456789, + options->GetExtension(protobuf_unittest::double_opt)); + EXPECT_EQ("Hello, \"World\"", + options->GetExtension(protobuf_unittest::string_opt)); + + EXPECT_EQ(string("Hello\0World", 11), + options->GetExtension(protobuf_unittest::bytes_opt)); + + EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2, + options->GetExtension(protobuf_unittest::enum_opt)); + + options = + &protobuf_unittest::SettingRealsFromPositiveInts::descriptor()->options(); + EXPECT_FLOAT_EQ(12, options->GetExtension(protobuf_unittest::float_opt)); + EXPECT_DOUBLE_EQ(154, options->GetExtension(protobuf_unittest::double_opt)); + + options = + &protobuf_unittest::SettingRealsFromNegativeInts::descriptor()->options(); + EXPECT_FLOAT_EQ(-12, options->GetExtension(protobuf_unittest::float_opt)); + EXPECT_DOUBLE_EQ(-154, options->GetExtension(protobuf_unittest::double_opt)); +} + +TEST(CustomOptions, ComplexExtensionOptions) { + const MessageOptions* options = + &protobuf_unittest::VariousComplexOptions::descriptor()->options(); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1). + GetExtension(protobuf_unittest::quux), 324); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1). + GetExtension(protobuf_unittest::corge).qux(), 876); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2). + GetExtension(protobuf_unittest::grault), 654); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(), + 743); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar(). + GetExtension(protobuf_unittest::quux), 1999); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar(). + GetExtension(protobuf_unittest::corge).qux(), 2008); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2). + GetExtension(protobuf_unittest::garply).foo(), 741); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2). + GetExtension(protobuf_unittest::garply). + GetExtension(protobuf_unittest::quux), 1998); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2). + GetExtension(protobuf_unittest::garply). + GetExtension(protobuf_unittest::corge).qux(), 2121); + EXPECT_EQ(options->GetExtension( + protobuf_unittest::ComplexOptionType2::ComplexOptionType4::complex_opt4). + waldo(), 1971); + EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2). + fred().waldo(), 321); + EXPECT_EQ(9, options->GetExtension(protobuf_unittest::complex_opt3).qux()); + EXPECT_EQ(22, options->GetExtension(protobuf_unittest::complex_opt3). + complexoptiontype5().plugh()); + EXPECT_EQ(24, options->GetExtension(protobuf_unittest::complexopt6).xyzzy()); +} + +TEST(CustomOptions, OptionsFromOtherFile) { + // Test that to use a custom option, we only need to import the file + // defining the option; we do not also have to import descriptor.proto. + DescriptorPool pool; + + FileDescriptorProto file_proto; + FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); + ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); + + protobuf_unittest::TestMessageWithCustomOptions::descriptor() + ->file()->CopyTo(&file_proto); + ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); + + ASSERT_TRUE(TextFormat::ParseFromString( + "name: \"custom_options_import.proto\" " + "package: \"protobuf_unittest\" " + "dependency: \"google/protobuf/unittest_custom_options.proto\" " + "options { " + " uninterpreted_option { " + " name { " + " name_part: \"file_opt1\" " + " is_extension: true " + " } " + " positive_int_value: 1234 " + " } " + // Test a non-extension option too. (At one point this failed due to a + // bug.) + " uninterpreted_option { " + " name { " + " name_part: \"java_package\" " + " is_extension: false " + " } " + " string_value: \"foo\" " + " } " + // Test that enum-typed options still work too. (At one point this also + // failed due to a bug.) + " uninterpreted_option { " + " name { " + " name_part: \"optimize_for\" " + " is_extension: false " + " } " + " identifier_value: \"SPEED\" " + " } " + "}" + , + &file_proto)); + + const FileDescriptor* file = pool.BuildFile(file_proto); + ASSERT_TRUE(file != NULL); + EXPECT_EQ(1234, file->options().GetExtension(protobuf_unittest::file_opt1)); + EXPECT_TRUE(file->options().has_java_package()); + EXPECT_EQ("foo", file->options().java_package()); + EXPECT_TRUE(file->options().has_optimize_for()); + EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for()); +} + +TEST(CustomOptions, MessageOptionThreeFieldsSet) { + // This tests a bug which previously existed in custom options parsing. The + // bug occurred when you defined a custom option with message type and then + // set three fields of that option on a single definition (see the example + // below). The bug is a bit hard to explain, so check the change history if + // you want to know more. + DescriptorPool pool; + + FileDescriptorProto file_proto; + FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); + ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); + + protobuf_unittest::TestMessageWithCustomOptions::descriptor() + ->file()->CopyTo(&file_proto); + ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); + + // The following represents the definition: + // + // import "google/protobuf/unittest_custom_options.proto" + // package protobuf_unittest; + // message Foo { + // option (complex_opt1).foo = 1234; + // option (complex_opt1).foo2 = 1234; + // option (complex_opt1).foo3 = 1234; + // } + ASSERT_TRUE(TextFormat::ParseFromString( + "name: \"custom_options_import.proto\" " + "package: \"protobuf_unittest\" " + "dependency: \"google/protobuf/unittest_custom_options.proto\" " + "message_type { " + " name: \"Foo\" " + " options { " + " uninterpreted_option { " + " name { " + " name_part: \"complex_opt1\" " + " is_extension: true " + " } " + " name { " + " name_part: \"foo\" " + " is_extension: false " + " } " + " positive_int_value: 1234 " + " } " + " uninterpreted_option { " + " name { " + " name_part: \"complex_opt1\" " + " is_extension: true " + " } " + " name { " + " name_part: \"foo2\" " + " is_extension: false " + " } " + " positive_int_value: 1234 " + " } " + " uninterpreted_option { " + " name { " + " name_part: \"complex_opt1\" " + " is_extension: true " + " } " + " name { " + " name_part: \"foo3\" " + " is_extension: false " + " } " + " positive_int_value: 1234 " + " } " + " } " + "}", + &file_proto)); + + const FileDescriptor* file = pool.BuildFile(file_proto); + ASSERT_TRUE(file != NULL); + ASSERT_EQ(1, file->message_type_count()); + + const MessageOptions& options = file->message_type(0)->options(); + EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo()); +} + +// Check that aggregate options were parsed and saved correctly in +// the appropriate descriptors. +TEST(CustomOptions, AggregateOptions) { + const Descriptor* msg = protobuf_unittest::AggregateMessage::descriptor(); + const FileDescriptor* file = msg->file(); + const FieldDescriptor* field = msg->FindFieldByName("fieldname"); + const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum"); + const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE"); + const ServiceDescriptor* service = file->FindServiceByName( + "AggregateService"); + const MethodDescriptor* method = service->FindMethodByName("Method"); + + // Tests for the different types of data embedded in fileopt + const protobuf_unittest::Aggregate& file_options = + file->options().GetExtension(protobuf_unittest::fileopt); + EXPECT_EQ(100, file_options.i()); + EXPECT_EQ("FileAnnotation", file_options.s()); + EXPECT_EQ("NestedFileAnnotation", file_options.sub().s()); + EXPECT_EQ("FileExtensionAnnotation", + file_options.file().GetExtension(protobuf_unittest::fileopt).s()); + EXPECT_EQ("EmbeddedMessageSetElement", + file_options.mset().GetExtension( + protobuf_unittest::AggregateMessageSetElement + ::message_set_extension).s()); + + // Simple tests for all the other types of annotations + EXPECT_EQ("MessageAnnotation", + msg->options().GetExtension(protobuf_unittest::msgopt).s()); + EXPECT_EQ("FieldAnnotation", + field->options().GetExtension(protobuf_unittest::fieldopt).s()); + EXPECT_EQ("EnumAnnotation", + enumd->options().GetExtension(protobuf_unittest::enumopt).s()); + EXPECT_EQ("EnumValueAnnotation", + enumv->options().GetExtension(protobuf_unittest::enumvalopt).s()); + EXPECT_EQ("ServiceAnnotation", + service->options().GetExtension(protobuf_unittest::serviceopt).s()); + EXPECT_EQ("MethodAnnotation", + method->options().GetExtension(protobuf_unittest::methodopt).s()); +} + +// =================================================================== + +// The tests below trigger every unique call to AddError() in descriptor.cc, +// in the order in which they appear in that file. I'm using TextFormat here +// to specify the input descriptors because building them using code would +// be too bulky. + +class MockErrorCollector : public DescriptorPool::ErrorCollector { + public: + MockErrorCollector() {} + ~MockErrorCollector() {} + + string text_; + + // implements ErrorCollector --------------------------------------- + void AddError(const string& filename, + const string& element_name, const Message* descriptor, + ErrorLocation location, const string& message) { + const char* location_name = NULL; + switch (location) { + case NAME : location_name = "NAME" ; break; + case NUMBER : location_name = "NUMBER" ; break; + case TYPE : location_name = "TYPE" ; break; + case EXTENDEE : location_name = "EXTENDEE" ; break; + case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break; + case OPTION_NAME : location_name = "OPTION_NAME" ; break; + case OPTION_VALUE : location_name = "OPTION_VALUE" ; break; + case INPUT_TYPE : location_name = "INPUT_TYPE" ; break; + case OUTPUT_TYPE : location_name = "OUTPUT_TYPE" ; break; + case OTHER : location_name = "OTHER" ; break; + } + + strings::SubstituteAndAppend( + &text_, "$0: $1: $2: $3\n", + filename, element_name, location_name, message); + } +}; + +class ValidationErrorTest : public testing::Test { + protected: + // Parse file_text as a FileDescriptorProto in text format and add it + // to the DescriptorPool. Expect no errors. + void BuildFile(const string& file_text) { + FileDescriptorProto file_proto; + ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); + ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL); + } + + // Parse file_text as a FileDescriptorProto in text format and add it + // to the DescriptorPool. Expect errors to be produced which match the + // given error text. + void BuildFileWithErrors(const string& file_text, + const string& expected_errors) { + FileDescriptorProto file_proto; + ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); + + MockErrorCollector error_collector; + EXPECT_TRUE( + pool_.BuildFileCollectingErrors(file_proto, &error_collector) == NULL); + EXPECT_EQ(expected_errors, error_collector.text_); + } + + // Builds some already-parsed file in our test pool. + void BuildFileInTestPool(const FileDescriptor* file) { + FileDescriptorProto file_proto; + file->CopyTo(&file_proto); + ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL); + } + + // Build descriptor.proto in our test pool. This allows us to extend it in + // the test pool, so we can test custom options. + void BuildDescriptorMessagesInTestPool() { + BuildFileInTestPool(DescriptorProto::descriptor()->file()); + } + + DescriptorPool pool_; +}; + +TEST_F(ValidationErrorTest, AlreadyDefined) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { name: \"Foo\" }" + "message_type { name: \"Foo\" }", + + "foo.proto: Foo: NAME: \"Foo\" is already defined.\n"); +} + +TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "package: \"foo.bar\" " + "message_type { name: \"Foo\" }" + "message_type { name: \"Foo\" }", + + "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in " + "\"foo.bar\".\n"); +} + +TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) { + BuildFile( + "name: \"foo.proto\" " + "message_type { name: \"Foo\" }"); + + BuildFileWithErrors( + "name: \"bar.proto\" " + "message_type { name: \"Foo\" }", + + "bar.proto: Foo: NAME: \"Foo\" is already defined in file " + "\"foo.proto\".\n"); +} + +TEST_F(ValidationErrorTest, PackageAlreadyDefined) { + BuildFile( + "name: \"foo.proto\" " + "message_type { name: \"foo\" }"); + BuildFileWithErrors( + "name: \"bar.proto\" " + "package: \"foo.bar\"", + + "bar.proto: foo: NAME: \"foo\" is already defined (as something other " + "than a package) in file \"foo.proto\".\n"); +} + +TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } " + "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ", + + "foo.proto: FOO: NAME: \"FOO\" is already defined.\n" + "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, " + "meaning that enum values are siblings of their type, not children of " + "it. Therefore, \"FOO\" must be unique within the global scope, not " + "just within \"Bar\".\n"); +} + +TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "package: \"pkg\" " + "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } " + "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ", + + "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n" + "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, " + "meaning that enum values are siblings of their type, not children of " + "it. Therefore, \"FOO\" must be unique within \"pkg\", not just within " + "\"Bar\".\n"); +} + +TEST_F(ValidationErrorTest, MissingName) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { }", + + "foo.proto: : NAME: Missing name.\n"); +} + +TEST_F(ValidationErrorTest, InvalidName) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { name: \"$\" }", + + "foo.proto: $: NAME: \"$\" is not a valid identifier.\n"); +} + +TEST_F(ValidationErrorTest, InvalidPackageName) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "package: \"foo.$\"", + + "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n"); +} + +TEST_F(ValidationErrorTest, MissingFileName) { + BuildFileWithErrors( + "", + + ": : OTHER: Missing field: FileDescriptorProto.name.\n"); +} + +TEST_F(ValidationErrorTest, DupeDependency) { + BuildFile("name: \"foo.proto\""); + BuildFileWithErrors( + "name: \"bar.proto\" " + "dependency: \"foo.proto\" " + "dependency: \"foo.proto\" ", + + "bar.proto: bar.proto: OTHER: Import \"foo.proto\" was listed twice.\n"); +} + +TEST_F(ValidationErrorTest, UnknownDependency) { + BuildFileWithErrors( + "name: \"bar.proto\" " + "dependency: \"foo.proto\" ", + + "bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n"); +} + +TEST_F(ValidationErrorTest, InvalidPublicDependencyIndex) { + BuildFile("name: \"foo.proto\""); + BuildFileWithErrors( + "name: \"bar.proto\" " + "dependency: \"foo.proto\" " + "public_dependency: 1", + "bar.proto: bar.proto: OTHER: Invalid public dependency index.\n"); +} + +TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) { + // Used to crash: If we depend on a non-existent file and then refer to a + // package defined in a file that we didn't import, and that package is + // nested within a parent package which this file is also in, and we don't + // include that parent package in the name (i.e. we do a relative lookup)... + // Yes, really. + BuildFile( + "name: 'foo.proto' " + "package: 'outer.foo' "); + BuildFileWithErrors( + "name: 'bar.proto' " + "dependency: 'baz.proto' " + "package: 'outer.bar' " + "message_type { " + " name: 'Bar' " + " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }" + "}", + + "bar.proto: bar.proto: OTHER: Import \"baz.proto\" has not been loaded.\n" + "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined in " + "\"foo.proto\", which is not imported by \"bar.proto\". To use it here, " + "please add the necessary import.\n"); +} + +TEST_F(ValidationErrorTest, DupeFile) { + BuildFile( + "name: \"foo.proto\" " + "message_type { name: \"Foo\" }"); + // Note: We should *not* get redundant errors about "Foo" already being + // defined. + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { name: \"Foo\" } " + // Add another type so that the files aren't identical (in which case there + // would be no error). + "enum_type { name: \"Bar\" }", + + "foo.proto: foo.proto: OTHER: A file with this name is already in the " + "pool.\n"); +} + +TEST_F(ValidationErrorTest, FieldInExtensionRange) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 }" + " field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 }" + " field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 }" + " field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 }" + " extension_range { start: 10 end: 20 }" + "}", + + "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field " + "\"bar\" (10).\n" + "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field " + "\"baz\" (19).\n"); +} + +TEST_F(ValidationErrorTest, OverlappingExtensionRanges) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " extension_range { start: 10 end: 20 }" + " extension_range { start: 20 end: 30 }" + " extension_range { start: 19 end: 21 }" + "}", + + "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with " + "already-defined range 10 to 19.\n" + "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with " + "already-defined range 20 to 29.\n"); +} + +TEST_F(ValidationErrorTest, InvalidDefaults) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + + // Invalid number. + " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32" + " default_value: \"abc\" }" + + // Empty default value. + " field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32" + " default_value: \"\" }" + + // Invalid boolean. + " field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL" + " default_value: \"abc\" }" + + // Messages can't have defaults. + " field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: TYPE_MESSAGE" + " default_value: \"abc\" type_name: \"Foo\" }" + + // Same thing, but we don't know that this field has message type until + // we look up the type name. + " field { name: \"quux\" number: 5 label: LABEL_OPTIONAL" + " default_value: \"abc\" type_name: \"Foo\" }" + + // Repeateds can't have defaults. + " field { name: \"corge\" number: 6 label: LABEL_REPEATED type: TYPE_INT32" + " default_value: \"1\" }" + "}", + + "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value.\n" + "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value.\n" + "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or " + "false.\n" + "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n" + "foo.proto: Foo.corge: DEFAULT_VALUE: Repeated fields can't have default " + "values.\n" + // This ends up being reported later because the error is detected at + // cross-linking time. + "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default " + "values.\n"); +} + +TEST_F(ValidationErrorTest, NegativeFieldNumber) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 }" + "}", + + "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n"); +} + +TEST_F(ValidationErrorTest, HugeFieldNumber) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name: \"foo\" number: 0x70000000 " + " label:LABEL_OPTIONAL type:TYPE_INT32 }" + "}", + + "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than " + "536870911.\n"); +} + +TEST_F(ValidationErrorTest, ReservedFieldNumber) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL type:TYPE_INT32 }" + " field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL type:TYPE_INT32 }" + " field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL type:TYPE_INT32 }" + " field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL type:TYPE_INT32 }" + "}", + + "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are " + "reserved for the protocol buffer library implementation.\n" + "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are " + "reserved for the protocol buffer library implementation.\n"); +} + +TEST_F(ValidationErrorTest, ExtensionMissingExtendee) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL" + " type_name: \"Foo\" }" + "}", + + "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for " + "extension field.\n"); +} + +TEST_F(ValidationErrorTest, NonExtensionWithExtendee) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Bar\"" + " extension_range { start: 1 end: 2 }" + "}" + "message_type {" + " name: \"Foo\"" + " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL" + " type_name: \"Foo\" extendee: \"Bar\" }" + "}", + + "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for " + "non-extension field.\n"); +} + +TEST_F(ValidationErrorTest, FieldNumberConflict) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }" + " field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }" + "}", + + "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in " + "\"Foo\" by field \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, BadMessageSetExtensionType) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"MessageSet\"" + " options { message_set_wire_format: true }" + " extension_range { start: 4 end: 5 }" + "}" + "message_type {" + " name: \"Foo\"" + " extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32" + " extendee: \"MessageSet\" }" + "}", + + "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional " + "messages.\n"); +} + +TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"MessageSet\"" + " options { message_set_wire_format: true }" + " extension_range { start: 4 end: 5 }" + "}" + "message_type {" + " name: \"Foo\"" + " extension { name:\"foo\" number:4 label:LABEL_REPEATED type:TYPE_MESSAGE" + " type_name: \"Foo\" extendee: \"MessageSet\" }" + "}", + + "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional " + "messages.\n"); +} + +TEST_F(ValidationErrorTest, FieldInMessageSet) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " options { message_set_wire_format: true }" + " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }" + "}", + + "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only " + "extensions.\n"); +} + +TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " extension_range { start: -10 end: -1 }" + "}", + + "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n"); +} + +TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " extension_range { start: 1 end: 0x70000000 }" + "}", + + "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than " + "536870911.\n"); +} + +TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " extension_range { start: 10 end: 10 }" + " extension_range { start: 10 end: 5 }" + "}", + + "foo.proto: Foo: NUMBER: Extension range end number must be greater than " + "start number.\n" + "foo.proto: Foo: NUMBER: Extension range end number must be greater than " + "start number.\n"); +} + +TEST_F(ValidationErrorTest, EmptyEnum) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "enum_type { name: \"Foo\" }" + // Also use the empty enum in a message to make sure there are no crashes + // during validation (possible if the code attempts to derive a default + // value for the field). + "message_type {" + " name: \"Bar\"" + " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type_name:\"Foo\" }" + " field { name: \"bar\" number: 2 label:LABEL_OPTIONAL type_name:\"Foo\" " + " default_value: \"NO_SUCH_VALUE\" }" + "}", + + "foo.proto: Foo: NAME: Enums must contain at least one value.\n" + "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named " + "\"NO_SUCH_VALUE\".\n"); +} + +TEST_F(ValidationErrorTest, UndefinedExtendee) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" + " extendee: \"Bar\" }" + "}", + + "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n"); +} + +TEST_F(ValidationErrorTest, NonMessageExtendee) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }" + "message_type {" + " name: \"Foo\"" + " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" + " extendee: \"Bar\" }" + "}", + + "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n"); +} + +TEST_F(ValidationErrorTest, NotAnExtensionNumber) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Bar\"" + "}" + "message_type {" + " name: \"Foo\"" + " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" + " extendee: \"Bar\" }" + "}", + + "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension " + "number.\n"); +} + +TEST_F(ValidationErrorTest, UndefinedFieldType) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" + "}", + + "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n"); +} + +TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) { + BuildFile( + "name: \"bar.proto\" " + "message_type { name: \"Bar\" } "); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" + "}", + "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", " + "which is not imported by \"foo.proto\". To use it here, please add the " + "necessary import.\n"); +} + +TEST_F(ValidationErrorTest, FieldTypeDefinedInIndirectDependency) { + // Test for hidden dependencies. + // + // // bar.proto + // message Bar{} + // + // // forward.proto + // import "bar.proto" + // + // // foo.proto + // import "forward.proto" + // message Foo { + // optional Bar foo = 1; // Error, needs to import bar.proto explicitly. + // } + // + BuildFile( + "name: \"bar.proto\" " + "message_type { name: \"Bar\" }"); + + BuildFile( + "name: \"forward.proto\"" + "dependency: \"bar.proto\""); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"forward.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" + "}", + "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", " + "which is not imported by \"foo.proto\". To use it here, please add the " + "necessary import.\n"); +} + +TEST_F(ValidationErrorTest, FieldTypeDefinedInPublicDependency) { + // Test for public dependencies. + // + // // bar.proto + // message Bar{} + // + // // forward.proto + // import public "bar.proto" + // + // // foo.proto + // import "forward.proto" + // message Foo { + // optional Bar foo = 1; // Correct. "bar.proto" is public imported into + // // forward.proto, so when "foo.proto" imports + // // "forward.proto", it imports "bar.proto" too. + // } + // + BuildFile( + "name: \"bar.proto\" " + "message_type { name: \"Bar\" }"); + + BuildFile( + "name: \"forward.proto\"" + "dependency: \"bar.proto\" " + "public_dependency: 0"); + + BuildFile( + "name: \"foo.proto\" " + "dependency: \"forward.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" + "}"); +} + +TEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) { + // Test for public dependencies. + // + // // bar.proto + // message Bar{} + // + // // forward.proto + // import public "bar.proto" + // + // // forward2.proto + // import public "forward.proto" + // + // // foo.proto + // import "forward2.proto" + // message Foo { + // optional Bar foo = 1; // Correct, public imports are transitive. + // } + // + BuildFile( + "name: \"bar.proto\" " + "message_type { name: \"Bar\" }"); + + BuildFile( + "name: \"forward.proto\"" + "dependency: \"bar.proto\" " + "public_dependency: 0"); + + BuildFile( + "name: \"forward2.proto\"" + "dependency: \"forward.proto\" " + "public_dependency: 0"); + + BuildFile( + "name: \"foo.proto\" " + "dependency: \"forward2.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" + "}"); +} + +TEST_F(ValidationErrorTest, + FieldTypeDefinedInPrivateDependencyOfPublicDependency) { + // Test for public dependencies. + // + // // bar.proto + // message Bar{} + // + // // forward.proto + // import "bar.proto" + // + // // forward2.proto + // import public "forward.proto" + // + // // foo.proto + // import "forward2.proto" + // message Foo { + // optional Bar foo = 1; // Error, the "bar.proto" is not public imported + // // into "forward.proto", so will not be imported + // // into either "forward2.proto" or "foo.proto". + // } + // + BuildFile( + "name: \"bar.proto\" " + "message_type { name: \"Bar\" }"); + + BuildFile( + "name: \"forward.proto\"" + "dependency: \"bar.proto\""); + + BuildFile( + "name: \"forward2.proto\"" + "dependency: \"forward.proto\" " + "public_dependency: 0"); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"forward2.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" + "}", + "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", " + "which is not imported by \"foo.proto\". To use it here, please add the " + "necessary import.\n"); +} + + +TEST_F(ValidationErrorTest, SearchMostLocalFirst) { + // The following should produce an error that Bar.Baz is not defined: + // message Bar { message Baz {} } + // message Foo { + // message Bar { + // // Placing "message Baz{}" here, or removing Foo.Bar altogether, + // // would fix the error. + // } + // optional Bar.Baz baz = 1; + // } + // An one point the lookup code incorrectly did not produce an error in this + // case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first, + // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually + // refer to the inner Bar, not the outer one. + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Bar\"" + " nested_type { name: \"Baz\" }" + "}" + "message_type {" + " name: \"Foo\"" + " nested_type { name: \"Bar\" }" + " field { name:\"baz\" number:1 label:LABEL_OPTIONAL" + " type_name:\"Bar.Baz\" }" + "}", + + "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is not defined.\n"); +} + +TEST_F(ValidationErrorTest, SearchMostLocalFirst2) { + // This test would find the most local "Bar" first, and does, but + // proceeds to find the outer one because the inner one's not an + // aggregate. + BuildFile( + "name: \"foo.proto\" " + "message_type {" + " name: \"Bar\"" + " nested_type { name: \"Baz\" }" + "}" + "message_type {" + " name: \"Foo\"" + " field { name: \"Bar\" number:1 type:TYPE_BYTES } " + " field { name:\"baz\" number:2 label:LABEL_OPTIONAL" + " type_name:\"Bar.Baz\" }" + "}"); +} + +TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) { + // Imagine we have the following: + // + // foo.proto: + // package foo.bar; + // bar.proto: + // package foo.bar; + // import "foo.proto"; + // message Bar {} + // baz.proto: + // package foo; + // import "bar.proto" + // message Baz { optional bar.Bar qux = 1; } + // + // When validating baz.proto, we will look up "bar.Bar". As part of this + // lookup, we first lookup "bar" then try to find "Bar" within it. "bar" + // should resolve to "foo.bar". Note, though, that "foo.bar" was originally + // defined in foo.proto, which is not a direct dependency of baz.proto. The + // implementation of FindSymbol() normally only returns symbols in direct + // dependencies, not indirect ones. This test insures that this does not + // prevent it from finding "foo.bar". + + BuildFile( + "name: \"foo.proto\" " + "package: \"foo.bar\" "); + BuildFile( + "name: \"bar.proto\" " + "package: \"foo.bar\" " + "dependency: \"foo.proto\" " + "message_type { name: \"Bar\" }"); + BuildFile( + "name: \"baz.proto\" " + "package: \"foo\" " + "dependency: \"bar.proto\" " + "message_type { " + " name: \"Baz\" " + " field { name:\"qux\" number:1 label:LABEL_OPTIONAL " + " type_name:\"bar.Bar\" }" + "}"); +} + +TEST_F(ValidationErrorTest, FieldTypeNotAType) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL " + " type_name:\".Foo.bar\" }" + " field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" + "}", + + "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n"); +} + +TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " nested_type {" + " name: \"Bar\"" + " field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" + " }" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL " + " type_name:\"Bar.Baz\" }" + "}", + "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n"); +} + +TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) { + BuildFile( + "name: \"foo.proto\" " + "message_type {" + " name: \"Bar\"" + "}" + "message_type {" + " name: \"Foo\"" + " field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" + "}"); +} + +TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { name: \"Bar\" } " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM" + " type_name:\"Bar\" }" + "}", + + "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n"); +} + +TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE" + " type_name:\"Bar\" }" + "}", + + "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n"); +} + +TEST_F(ValidationErrorTest, BadEnumDefaultValue) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\"" + " default_value:\"NO_SUCH_VALUE\" }" + "}", + + "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named " + "\"NO_SUCH_VALUE\".\n"); +} + +TEST_F(ValidationErrorTest, PrimitiveWithTypeName) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" + " type_name:\"Foo\" }" + "}", + + "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n"); +} + +TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"Foo\"" + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }" + "}", + + "foo.proto: Foo.foo: TYPE: Field with message or enum type missing " + "type_name.\n"); +} + +TEST_F(ValidationErrorTest, InputTypeNotDefined) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { name: \"Foo\" } " + "service {" + " name: \"TestService\"" + " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }" + "}", + + "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n" + ); +} + +TEST_F(ValidationErrorTest, InputTypeNotAMessage) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { name: \"Foo\" } " + "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " + "service {" + " name: \"TestService\"" + " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }" + "}", + + "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n" + ); +} + +TEST_F(ValidationErrorTest, OutputTypeNotDefined) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { name: \"Foo\" } " + "service {" + " name: \"TestService\"" + " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }" + "}", + + "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n" + ); +} + +TEST_F(ValidationErrorTest, OutputTypeNotAMessage) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { name: \"Foo\" } " + "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " + "service {" + " name: \"TestService\"" + " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }" + "}", + + "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n" + ); +} + + +TEST_F(ValidationErrorTest, IllegalPackedField) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {\n" + " name: \"Foo\"" + " field { name:\"packed_string\" number:1 label:LABEL_REPEATED " + " type:TYPE_STRING " + " options { uninterpreted_option {" + " name { name_part: \"packed\" is_extension: false }" + " identifier_value: \"true\" }}}\n" + " field { name:\"packed_message\" number:3 label:LABEL_REPEATED " + " type_name: \"Foo\"" + " options { uninterpreted_option {" + " name { name_part: \"packed\" is_extension: false }" + " identifier_value: \"true\" }}}\n" + " field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL " + " type:TYPE_INT32 " + " options { uninterpreted_option {" + " name { name_part: \"packed\" is_extension: false }" + " identifier_value: \"true\" }}}\n" + "}", + + "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be " + "specified for repeated primitive fields.\n" + "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be " + "specified for repeated primitive fields.\n" + "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be " + "specified for repeated primitive fields.\n" + ); +} + +TEST_F(ValidationErrorTest, OptionWrongType) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { " + " name: \"TestMessage\" " + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING " + " options { uninterpreted_option { name { name_part: \"ctype\" " + " is_extension: false }" + " positive_int_value: 1 }" + " }" + " }" + "}\n", + + "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for " + "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n"); +} + +TEST_F(ValidationErrorTest, OptionExtendsAtomicType) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { " + " name: \"TestMessage\" " + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING " + " options { uninterpreted_option { name { name_part: \"ctype\" " + " is_extension: false }" + " name { name_part: \"foo\" " + " is_extension: true }" + " positive_int_value: 1 }" + " }" + " }" + "}\n", + + "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an " + "atomic type, not a message.\n"); +} + +TEST_F(ValidationErrorTest, DupOption) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { " + " name: \"TestMessage\" " + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 " + " options { uninterpreted_option { name { name_part: \"ctype\" " + " is_extension: false }" + " identifier_value: \"CORD\" }" + " uninterpreted_option { name { name_part: \"ctype\" " + " is_extension: false }" + " identifier_value: \"CORD\" }" + " }" + " }" + "}\n", + + "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was " + "already set.\n"); +} + +TEST_F(ValidationErrorTest, InvalidOptionName) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type { " + " name: \"TestMessage\" " + " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL " + " options { uninterpreted_option { " + " name { name_part: \"uninterpreted_option\" " + " is_extension: false }" + " positive_int_value: 1 " + " }" + " }" + " }" + "}\n", + + "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use " + "reserved name \"uninterpreted_option\".\n"); +} + +TEST_F(ValidationErrorTest, RepeatedOption) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_REPEATED " + " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " double_value: 1.2 } }", + + "foo.proto: foo.proto: OPTION_NAME: Option field \"(foo)\" is repeated. " + "Repeated options are not supported.\n"); +} + +TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }" + "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }", + + "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used " + "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n"); +} + +TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " positive_int_value: 0x80000000 } " + "}", + + "foo.proto: foo.proto: OPTION_VALUE: Value out of range " + "for int32 option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " negative_int_value: -0x80000001 } " + "}", + + "foo.proto: foo.proto: OPTION_VALUE: Value out of range " + "for int32 option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " string_value: \"5\" } }", + + "foo.proto: foo.proto: OPTION_VALUE: Value must be integer " + "for int32 option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " positive_int_value: 0x8000000000000000 } " + "}", + + "foo.proto: foo.proto: OPTION_VALUE: Value out of range " + "for int64 option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " identifier_value: \"5\" } }", + + "foo.proto: foo.proto: OPTION_VALUE: Value must be integer " + "for int64 option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " positive_int_value: 0x100000000 } }", + + "foo.proto: foo.proto: OPTION_VALUE: Value out of range " + "for uint32 option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " double_value: -5.6 } }", + + "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer " + "for uint32 option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " negative_int_value: -5 } }", + + "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer " + "for uint64 option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " string_value: \"bar\" } }", + + "foo.proto: foo.proto: OPTION_VALUE: Value must be number " + "for float option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " string_value: \"bar\" } }", + + "foo.proto: foo.proto: OPTION_VALUE: Value must be number " + "for double option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " identifier_value: \"bar\" } }", + + "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" " + "for boolean option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } " + " value { name: \"BAZ\" number: 2 } }" + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_ENUM type_name: \"FooEnum\" " + " extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " string_value: \"QUUX\" } }", + + "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for " + "enum-valued option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } " + " value { name: \"BAZ\" number: 2 } }" + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_ENUM type_name: \"FooEnum\" " + " extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " identifier_value: \"QUUX\" } }", + + "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value " + "named \"QUUX\" for option \"foo\".\n"); +} + +TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } " + " value { name: \"BAZ\" number: 2 } }" + "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } " + " value { name: \"QUUX\" number: 2 } }" + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_ENUM type_name: \"FooEnum1\" " + " extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " identifier_value: \"QUUX\" } }", + + "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value " + "named \"QUUX\" for option \"foo\". This appears to be a value from a " + "sibling type.\n"); +} + +TEST_F(ValidationErrorTest, StringOptionValueIsNotString) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " identifier_value: \"QUUX\" } }", + + "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string for " + "string option \"foo\".\n"); +} + +// Helper function for tests that check for aggregate value parsing +// errors. The "value" argument is embedded inside the +// "uninterpreted_option" portion of the result. +static string EmbedAggregateValue(const char* value) { + return strings::Substitute( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "message_type { name: \"Foo\" } " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_MESSAGE type_name: \"Foo\" " + " extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " $0 } }", + value); +} + +TEST_F(ValidationErrorTest, AggregateValueNotFound) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + EmbedAggregateValue("string_value: \"\""), + "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. " + "To set the entire message, use syntax like " + "\"foo = { }\". To set fields within it, use " + "syntax like \"foo.foo = value\".\n"); +} + +TEST_F(ValidationErrorTest, AggregateValueParseError) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + EmbedAggregateValue("aggregate_value: \"1+2\""), + "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " + "value for \"foo\": Expected identifier.\n"); +} + +TEST_F(ValidationErrorTest, AggregateValueUnknownFields) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + EmbedAggregateValue("aggregate_value: \"x:100\""), + "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " + "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n"); +} + +TEST_F(ValidationErrorTest, NotLiteImportsLite) { + BuildFile( + "name: \"bar.proto\" " + "options { optimize_for: LITE_RUNTIME } "); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"bar.proto\" ", + + "foo.proto: foo.proto: OTHER: Files that do not use optimize_for = " + "LITE_RUNTIME cannot import files which do use this option. This file " + "is not lite, but it imports \"bar.proto\" which is.\n"); +} + +TEST_F(ValidationErrorTest, LiteExtendsNotLite) { + BuildFile( + "name: \"bar.proto\" " + "message_type: {" + " name: \"Bar\"" + " extension_range { start: 1 end: 1000 }" + "}"); + + BuildFileWithErrors( + "name: \"foo.proto\" " + "dependency: \"bar.proto\" " + "options { optimize_for: LITE_RUNTIME } " + "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL " + " type: TYPE_INT32 extendee: \"Bar\" }", + + "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be " + "declared in non-lite files. Note that you cannot extend a non-lite " + "type to contain a lite type, but the reverse is allowed.\n"); +} + +TEST_F(ValidationErrorTest, NoLiteServices) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "options {" + " optimize_for: LITE_RUNTIME" + " cc_generic_services: true" + " java_generic_services: true" + "} " + "service { name: \"Foo\" }", + + "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot " + "define services unless you set both options cc_generic_services and " + "java_generic_sevices to false.\n"); + + BuildFile( + "name: \"bar.proto\" " + "options {" + " optimize_for: LITE_RUNTIME" + " cc_generic_services: false" + " java_generic_services: false" + "} " + "service { name: \"Bar\" }"); +} + +TEST_F(ValidationErrorTest, RollbackAfterError) { + // Build a file which contains every kind of construct but references an + // undefined type. All these constructs will be added to the symbol table + // before the undefined type error is noticed. The DescriptorPool will then + // have to roll everything back. + BuildFileWithErrors( + "name: \"foo.proto\" " + "message_type {" + " name: \"TestMessage\"" + " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }" + "} " + "enum_type {" + " name: \"TestEnum\"" + " value { name:\"BAR\" number:1 }" + "} " + "service {" + " name: \"TestService\"" + " method {" + " name: \"Baz\"" + " input_type: \"NoSuchType\"" // error + " output_type: \"TestMessage\"" + " }" + "}", + + "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n" + ); + + // Make sure that if we build the same file again with the error fixed, + // it works. If the above rollback was incomplete, then some symbols will + // be left defined, and this second attempt will fail since it tries to + // re-define the same symbols. + BuildFile( + "name: \"foo.proto\" " + "message_type {" + " name: \"TestMessage\"" + " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }" + "} " + "enum_type {" + " name: \"TestEnum\"" + " value { name:\"BAR\" number:1 }" + "} " + "service {" + " name: \"TestService\"" + " method { name:\"Baz\"" + " input_type:\"TestMessage\"" + " output_type:\"TestMessage\" }" + "}"); +} + +TEST_F(ValidationErrorTest, ErrorsReportedToLogError) { + // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is + // provided. + + FileDescriptorProto file_proto; + ASSERT_TRUE(TextFormat::ParseFromString( + "name: \"foo.proto\" " + "message_type { name: \"Foo\" } " + "message_type { name: \"Foo\" } ", + &file_proto)); + + vector errors; + + { + ScopedMemoryLog log; + EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL); + errors = log.GetMessages(ERROR); + } + + ASSERT_EQ(2, errors.size()); + + EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]); + EXPECT_EQ(" Foo: \"Foo\" is already defined.", errors[1]); +} + +TEST_F(ValidationErrorTest, DisallowEnumAlias) { + BuildFileWithErrors( + "name: \"foo.proto\" " + "enum_type {" + " name: \"Bar\"" + " value { name:\"ENUM_A\" number:0 }" + " value { name:\"ENUM_B\" number:0 }" + " options { allow_alias: false }" + "}", + "foo.proto: Bar: NUMBER: " + "\"ENUM_B\" uses the same enum value as \"ENUM_A\". " + "If this is intended, set 'option allow_alias = true;' to the enum " + "definition.\n"); +} + +// =================================================================== +// DescriptorDatabase + +static void AddToDatabase(SimpleDescriptorDatabase* database, + const char* file_text) { + FileDescriptorProto file_proto; + EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); + database->Add(file_proto); +} + +class DatabaseBackedPoolTest : public testing::Test { + protected: + DatabaseBackedPoolTest() {} + + SimpleDescriptorDatabase database_; + + virtual void SetUp() { + AddToDatabase(&database_, + "name: 'foo.proto' " + "message_type { name:'Foo' extension_range { start: 1 end: 100 } } " + "enum_type { name:'TestEnum' value { name:'DUMMY' number:0 } } " + "service { name:'TestService' } "); + AddToDatabase(&database_, + "name: 'bar.proto' " + "dependency: 'foo.proto' " + "message_type { name:'Bar' } " + "extension { name:'foo_ext' extendee: '.Foo' number:5 " + " label:LABEL_OPTIONAL type:TYPE_INT32 } "); + // Baz has an undeclared dependency on Foo. + AddToDatabase(&database_, + "name: 'baz.proto' " + "message_type { " + " name:'Baz' " + " field { name:'foo' number:1 label:LABEL_OPTIONAL type_name:'Foo' } " + "}"); + } + + // We can't inject a file containing errors into a DescriptorPool, so we + // need an actual mock DescriptorDatabase to test errors. + class ErrorDescriptorDatabase : public DescriptorDatabase { + public: + ErrorDescriptorDatabase() {} + ~ErrorDescriptorDatabase() {} + + // implements DescriptorDatabase --------------------------------- + bool FindFileByName(const string& filename, + FileDescriptorProto* output) { + // error.proto and error2.proto cyclically import each other. + if (filename == "error.proto") { + output->Clear(); + output->set_name("error.proto"); + output->add_dependency("error2.proto"); + return true; + } else if (filename == "error2.proto") { + output->Clear(); + output->set_name("error2.proto"); + output->add_dependency("error.proto"); + return true; + } else { + return false; + } + } + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output) { + return false; + } + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output) { + return false; + } + }; + + // A DescriptorDatabase that counts how many times each method has been + // called and forwards to some other DescriptorDatabase. + class CallCountingDatabase : public DescriptorDatabase { + public: + CallCountingDatabase(DescriptorDatabase* wrapped_db) + : wrapped_db_(wrapped_db) { + Clear(); + } + ~CallCountingDatabase() {} + + DescriptorDatabase* wrapped_db_; + + int call_count_; + + void Clear() { + call_count_ = 0; + } + + // implements DescriptorDatabase --------------------------------- + bool FindFileByName(const string& filename, + FileDescriptorProto* output) { + ++call_count_; + return wrapped_db_->FindFileByName(filename, output); + } + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output) { + ++call_count_; + return wrapped_db_->FindFileContainingSymbol(symbol_name, output); + } + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output) { + ++call_count_; + return wrapped_db_->FindFileContainingExtension( + containing_type, field_number, output); + } + }; + + // A DescriptorDatabase which falsely always returns foo.proto when searching + // for any symbol or extension number. This shouldn't cause the + // DescriptorPool to reload foo.proto if it is already loaded. + class FalsePositiveDatabase : public DescriptorDatabase { + public: + FalsePositiveDatabase(DescriptorDatabase* wrapped_db) + : wrapped_db_(wrapped_db) {} + ~FalsePositiveDatabase() {} + + DescriptorDatabase* wrapped_db_; + + // implements DescriptorDatabase --------------------------------- + bool FindFileByName(const string& filename, + FileDescriptorProto* output) { + return wrapped_db_->FindFileByName(filename, output); + } + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output) { + return FindFileByName("foo.proto", output); + } + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output) { + return FindFileByName("foo.proto", output); + } + }; +}; + +TEST_F(DatabaseBackedPoolTest, FindFileByName) { + DescriptorPool pool(&database_); + + const FileDescriptor* foo = pool.FindFileByName("foo.proto"); + ASSERT_TRUE(foo != NULL); + EXPECT_EQ("foo.proto", foo->name()); + ASSERT_EQ(1, foo->message_type_count()); + EXPECT_EQ("Foo", foo->message_type(0)->name()); + + EXPECT_EQ(foo, pool.FindFileByName("foo.proto")); + + EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == NULL); +} + +TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) { + DescriptorPool pool(&database_); + + const FileDescriptor* foo = pool.FindFileByName("foo.proto"); + ASSERT_TRUE(foo != NULL); + EXPECT_EQ("foo.proto", foo->name()); + ASSERT_EQ(1, foo->message_type_count()); + EXPECT_EQ("Foo", foo->message_type(0)->name()); + + const FileDescriptor* bar = pool.FindFileByName("bar.proto"); + ASSERT_TRUE(bar != NULL); + EXPECT_EQ("bar.proto", bar->name()); + ASSERT_EQ(1, bar->message_type_count()); + EXPECT_EQ("Bar", bar->message_type(0)->name()); + + ASSERT_EQ(1, bar->dependency_count()); + EXPECT_EQ(foo, bar->dependency(0)); +} + +TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) { + DescriptorPool pool(&database_); + + const FileDescriptor* bar = pool.FindFileByName("bar.proto"); + ASSERT_TRUE(bar != NULL); + EXPECT_EQ("bar.proto", bar->name()); + ASSERT_EQ(1, bar->message_type_count()); + ASSERT_EQ("Bar", bar->message_type(0)->name()); + + const FileDescriptor* foo = pool.FindFileByName("foo.proto"); + ASSERT_TRUE(foo != NULL); + EXPECT_EQ("foo.proto", foo->name()); + ASSERT_EQ(1, foo->message_type_count()); + ASSERT_EQ("Foo", foo->message_type(0)->name()); + + ASSERT_EQ(1, bar->dependency_count()); + EXPECT_EQ(foo, bar->dependency(0)); +} + +TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) { + DescriptorPool pool(&database_); + + const FileDescriptor* file = pool.FindFileContainingSymbol("Foo"); + ASSERT_TRUE(file != NULL); + EXPECT_EQ("foo.proto", file->name()); + EXPECT_EQ(file, pool.FindFileByName("foo.proto")); + + EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == NULL); +} + +TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) { + DescriptorPool pool(&database_); + + const Descriptor* type = pool.FindMessageTypeByName("Foo"); + ASSERT_TRUE(type != NULL); + EXPECT_EQ("Foo", type->name()); + EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto")); + + EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == NULL); +} + +TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) { + DescriptorPool pool(&database_); + + const Descriptor* foo = pool.FindMessageTypeByName("Foo"); + ASSERT_TRUE(foo != NULL); + + const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5); + ASSERT_TRUE(extension != NULL); + EXPECT_EQ("foo_ext", extension->name()); + EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto")); + + EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == NULL); +} + +TEST_F(DatabaseBackedPoolTest, FindAllExtensions) { + DescriptorPool pool(&database_); + + const Descriptor* foo = pool.FindMessageTypeByName("Foo"); + + for (int i = 0; i < 2; ++i) { + // Repeat the lookup twice, to check that we get consistent + // results despite the fallback database lookup mutating the pool. + vector extensions; + pool.FindAllExtensions(foo, &extensions); + ASSERT_EQ(1, extensions.size()); + EXPECT_EQ(5, extensions[0]->number()); + } +} + +TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) { + ErrorDescriptorDatabase error_database; + DescriptorPool pool(&error_database); + + vector errors; + + { + ScopedMemoryLog log; + EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); + errors = log.GetMessages(ERROR); + } + + EXPECT_FALSE(errors.empty()); +} + +TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) { + ErrorDescriptorDatabase error_database; + MockErrorCollector error_collector; + DescriptorPool pool(&error_database, &error_collector); + + EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); + EXPECT_EQ( + "error.proto: error.proto: OTHER: File recursively imports itself: " + "error.proto -> error2.proto -> error.proto\n" + "error2.proto: error2.proto: OTHER: Import \"error.proto\" was not " + "found or had errors.\n" + "error.proto: error.proto: OTHER: Import \"error2.proto\" was not " + "found or had errors.\n", + error_collector.text_); +} + +TEST_F(DatabaseBackedPoolTest, UndeclaredDependencyOnUnbuiltType) { + // Check that we find and report undeclared dependencies on types that exist + // in the descriptor database but that have not not been built yet. + MockErrorCollector error_collector; + DescriptorPool pool(&database_, &error_collector); + EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL); + EXPECT_EQ( + "baz.proto: Baz.foo: TYPE: \"Foo\" seems to be defined in \"foo.proto\", " + "which is not imported by \"baz.proto\". To use it here, please add " + "the necessary import.\n", + error_collector.text_); +} + +TEST_F(DatabaseBackedPoolTest, RollbackAfterError) { + // Make sure that all traces of bad types are removed from the pool. This used + // to be b/4529436, due to the fact that a symbol resolution failure could + // potentially cause another file to be recursively built, which would trigger + // a checkpoint _past_ possibly invalid symbols. + // Baz is defined in the database, but the file is invalid because it is + // missing a necessary import. + DescriptorPool pool(&database_); + EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL); + // Make sure that searching again for the file or the type fails. + EXPECT_TRUE(pool.FindFileByName("baz.proto") == NULL); + EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL); +} + +TEST_F(DatabaseBackedPoolTest, UnittestProto) { + // Try to load all of unittest.proto from a DescriptorDatabase. This should + // thoroughly test all paths through DescriptorBuilder to insure that there + // are no deadlocking problems when pool_->mutex_ is non-NULL. + const FileDescriptor* original_file = + protobuf_unittest::TestAllTypes::descriptor()->file(); + + DescriptorPoolDatabase database(*DescriptorPool::generated_pool()); + DescriptorPool pool(&database); + const FileDescriptor* file_from_database = + pool.FindFileByName(original_file->name()); + + ASSERT_TRUE(file_from_database != NULL); + + FileDescriptorProto original_file_proto; + original_file->CopyTo(&original_file_proto); + + FileDescriptorProto file_from_database_proto; + file_from_database->CopyTo(&file_from_database_proto); + + EXPECT_EQ(original_file_proto.DebugString(), + file_from_database_proto.DebugString()); +} + +TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) { + // Searching for a child of an existing descriptor should never fall back + // to the DescriptorDatabase even if it isn't found, because we know all + // children are already loaded. + CallCountingDatabase call_counter(&database_); + DescriptorPool pool(&call_counter); + + const FileDescriptor* file = pool.FindFileByName("foo.proto"); + ASSERT_TRUE(file != NULL); + const Descriptor* foo = pool.FindMessageTypeByName("Foo"); + ASSERT_TRUE(foo != NULL); + const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum"); + ASSERT_TRUE(test_enum != NULL); + const ServiceDescriptor* test_service = pool.FindServiceByName("TestService"); + ASSERT_TRUE(test_service != NULL); + + EXPECT_NE(0, call_counter.call_count_); + call_counter.Clear(); + + EXPECT_TRUE(foo->FindFieldByName("no_such_field") == NULL); + EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == NULL); + EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == NULL); + EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == NULL); + EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == NULL); + EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == NULL); + EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == NULL); + + EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == NULL); + EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == NULL); + EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == NULL); + EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == NULL); + EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == NULL); + + EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no.such.field") == NULL); + EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no_such_field") == NULL); + EXPECT_TRUE(pool.FindMessageTypeByName("Foo.NoSuchMessageType") == NULL); + EXPECT_TRUE(pool.FindFieldByName("Foo.no_such_field") == NULL); + EXPECT_TRUE(pool.FindExtensionByName("Foo.no_such_extension") == NULL); + EXPECT_TRUE(pool.FindEnumTypeByName("Foo.NoSuchEnumType") == NULL); + EXPECT_TRUE(pool.FindEnumValueByName("Foo.NO_SUCH_VALUE") == NULL); + EXPECT_TRUE(pool.FindMethodByName("TestService.NoSuchMethod") == NULL); + + EXPECT_EQ(0, call_counter.call_count_); +} + +TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) { + // If FindFileContainingSymbol() or FindFileContainingExtension() return a + // file that is already in the DescriptorPool, it should not attempt to + // reload the file. + FalsePositiveDatabase false_positive_database(&database_); + MockErrorCollector error_collector; + DescriptorPool pool(&false_positive_database, &error_collector); + + // First make sure foo.proto is loaded. + const Descriptor* foo = pool.FindMessageTypeByName("Foo"); + ASSERT_TRUE(foo != NULL); + + // Try inducing false positives. + EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == NULL); + EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == NULL); + + // No errors should have been reported. (If foo.proto was incorrectly + // loaded multiple times, errors would have been reported.) + EXPECT_EQ("", error_collector.text_); +} + +TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) { + ErrorDescriptorDatabase error_database; + MockErrorCollector error_collector; + DescriptorPool pool(&error_database, &error_collector); + + EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); + error_collector.text_.clear(); + EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); + EXPECT_EQ("", error_collector.text_); +} + +TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) { + // If a lookup finds a symbol of the wrong type (e.g. we pass a type name + // to FindFieldByName()), we should fail fast, without checking the fallback + // database. + CallCountingDatabase call_counter(&database_); + DescriptorPool pool(&call_counter); + + const FileDescriptor* file = pool.FindFileByName("foo.proto"); + ASSERT_TRUE(file != NULL); + const Descriptor* foo = pool.FindMessageTypeByName("Foo"); + ASSERT_TRUE(foo != NULL); + const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum"); + ASSERT_TRUE(test_enum != NULL); + + EXPECT_NE(0, call_counter.call_count_); + call_counter.Clear(); + + EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == NULL); + EXPECT_TRUE(pool.FindFieldByName("Foo") == NULL); + EXPECT_TRUE(pool.FindExtensionByName("Foo") == NULL); + EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == NULL); + EXPECT_TRUE(pool.FindEnumValueByName("Foo") == NULL); + EXPECT_TRUE(pool.FindServiceByName("Foo") == NULL); + EXPECT_TRUE(pool.FindMethodByName("Foo") == NULL); + + EXPECT_EQ(0, call_counter.call_count_); +} + +// =================================================================== + +class AbortingErrorCollector : public DescriptorPool::ErrorCollector { + public: + AbortingErrorCollector() {} + + virtual void AddError( + const string &filename, + const string &element_name, + const Message *message, + ErrorLocation location, + const string &error_message) { + GOOGLE_LOG(FATAL) << "AddError() called unexpectedly: " << filename << ": " + << error_message; + } + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AbortingErrorCollector); +}; + +// A source tree containing only one file. +class SingletonSourceTree : public compiler::SourceTree { + public: + SingletonSourceTree(const string& filename, const string& contents) + : filename_(filename), contents_(contents) {} + + virtual io::ZeroCopyInputStream* Open(const string& filename) { + return filename == filename_ ? + new io::ArrayInputStream(contents_.data(), contents_.size()) : NULL; + } + + private: + const string filename_; + const string contents_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SingletonSourceTree); +}; + +const char *const kSourceLocationTestInput = + "syntax = \"proto2\";\n" + "message A {\n" + " optional int32 a = 1;\n" + " message B {\n" + " required double b = 1;\n" + " }\n" + "}\n" + "enum Indecision {\n" + " YES = 1;\n" + " NO = 2;\n" + " MAYBE = 3;\n" + "}\n" + "service S {\n" + " rpc Method(A) returns (A.B);\n" + // Put an empty line here to make the source location range match. + "\n" + "}\n"; + +class SourceLocationTest : public testing::Test { + public: + SourceLocationTest() + : source_tree_("/test/test.proto", kSourceLocationTestInput), + db_(&source_tree_), + pool_(&db_, &collector_) {} + + static string PrintSourceLocation(const SourceLocation &loc) { + return strings::Substitute("$0:$1-$2:$3", + 1 + loc.start_line, + 1 + loc.start_column, + 1 + loc.end_line, + 1 + loc.end_column); + } + + private: + AbortingErrorCollector collector_; + SingletonSourceTree source_tree_; + compiler::SourceTreeDescriptorDatabase db_; + + protected: + DescriptorPool pool_; +}; + +// TODO(adonovan): implement support for option fields and for +// subparts of declarations. + +TEST_F(SourceLocationTest, GetSourceLocation) { + SourceLocation loc; + + const FileDescriptor *file_desc = + GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto")); + + const Descriptor *a_desc = file_desc->FindMessageTypeByName("A"); + EXPECT_TRUE(a_desc->GetSourceLocation(&loc)); + EXPECT_EQ("2:1-7:2", PrintSourceLocation(loc)); + + const Descriptor *a_b_desc = a_desc->FindNestedTypeByName("B"); + EXPECT_TRUE(a_b_desc->GetSourceLocation(&loc)); + EXPECT_EQ("4:3-6:4", PrintSourceLocation(loc)); + + const EnumDescriptor *e_desc = file_desc->FindEnumTypeByName("Indecision"); + EXPECT_TRUE(e_desc->GetSourceLocation(&loc)); + EXPECT_EQ("8:1-12:2", PrintSourceLocation(loc)); + + const EnumValueDescriptor *yes_desc = e_desc->FindValueByName("YES"); + EXPECT_TRUE(yes_desc->GetSourceLocation(&loc)); + EXPECT_EQ("9:3-9:13", PrintSourceLocation(loc)); + + const ServiceDescriptor *s_desc = file_desc->FindServiceByName("S"); + EXPECT_TRUE(s_desc->GetSourceLocation(&loc)); + EXPECT_EQ("13:1-16:2", PrintSourceLocation(loc)); + + const MethodDescriptor *m_desc = s_desc->FindMethodByName("Method"); + EXPECT_TRUE(m_desc->GetSourceLocation(&loc)); + EXPECT_EQ("14:3-14:31", PrintSourceLocation(loc)); + +} + +// Missing SourceCodeInfo doesn't cause crash: +TEST_F(SourceLocationTest, GetSourceLocation_MissingSourceCodeInfo) { + SourceLocation loc; + + const FileDescriptor *file_desc = + GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto")); + + FileDescriptorProto proto; + file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo. + EXPECT_FALSE(proto.has_source_code_info()); + + DescriptorPool bad1_pool(&pool_); + const FileDescriptor* bad1_file_desc = + GOOGLE_CHECK_NOTNULL(bad1_pool.BuildFile(proto)); + const Descriptor *bad1_a_desc = bad1_file_desc->FindMessageTypeByName("A"); + EXPECT_FALSE(bad1_a_desc->GetSourceLocation(&loc)); +} + +// Corrupt SourceCodeInfo doesn't cause crash: +TEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) { + SourceLocation loc; + + const FileDescriptor *file_desc = + GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto")); + + FileDescriptorProto proto; + file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo. + EXPECT_FALSE(proto.has_source_code_info()); + SourceCodeInfo_Location *loc_msg = + proto.mutable_source_code_info()->add_location(); + loc_msg->add_path(1); + loc_msg->add_path(2); + loc_msg->add_path(3); + loc_msg->add_span(4); + loc_msg->add_span(5); + loc_msg->add_span(6); + + DescriptorPool bad2_pool(&pool_); + const FileDescriptor* bad2_file_desc = + GOOGLE_CHECK_NOTNULL(bad2_pool.BuildFile(proto)); + const Descriptor *bad2_a_desc = bad2_file_desc->FindMessageTypeByName("A"); + EXPECT_FALSE(bad2_a_desc->GetSourceLocation(&loc)); +} + +// =================================================================== + +const char* const kCopySourceCodeInfoToTestInput = + "syntax = \"proto2\";\n" + "message Foo {}\n"; + +// Required since source code information is not preserved by +// FileDescriptorTest. +class CopySourceCodeInfoToTest : public testing::Test { + public: + CopySourceCodeInfoToTest() + : source_tree_("/test/test.proto", kCopySourceCodeInfoToTestInput), + db_(&source_tree_), + pool_(&db_, &collector_) {} + + private: + AbortingErrorCollector collector_; + SingletonSourceTree source_tree_; + compiler::SourceTreeDescriptorDatabase db_; + + protected: + DescriptorPool pool_; +}; + +TEST_F(CopySourceCodeInfoToTest, CopyTo_DoesNotCopySourceCodeInfo) { + const FileDescriptor* file_desc = + GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto")); + FileDescriptorProto file_desc_proto; + ASSERT_FALSE(file_desc_proto.has_source_code_info()); + + file_desc->CopyTo(&file_desc_proto); + EXPECT_FALSE(file_desc_proto.has_source_code_info()); +} + +TEST_F(CopySourceCodeInfoToTest, CopySourceCodeInfoTo) { + const FileDescriptor* file_desc = + GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto")); + FileDescriptorProto file_desc_proto; + ASSERT_FALSE(file_desc_proto.has_source_code_info()); + + file_desc->CopySourceCodeInfoTo(&file_desc_proto); + const SourceCodeInfo& info = file_desc_proto.source_code_info(); + ASSERT_EQ(3, info.location_size()); + // Get the Foo message location + const SourceCodeInfo_Location& foo_location = info.location(1); + ASSERT_EQ(2, foo_location.path_size()); + EXPECT_EQ(FileDescriptorProto::kMessageTypeFieldNumber, foo_location.path(0)); + EXPECT_EQ(0, foo_location.path(1)); // Foo is the first message defined + ASSERT_EQ(3, foo_location.span_size()); // Foo spans one line + EXPECT_EQ(1, foo_location.span(0)); // Foo is declared on line 1 + EXPECT_EQ(0, foo_location.span(1)); // Foo starts at column 0 + EXPECT_EQ(14, foo_location.span(2)); // Foo ends on column 14 +} + +// =================================================================== + + +} // namespace descriptor_unittest +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message.cc new file mode 100644 index 0000000..09bec54 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message.cc @@ -0,0 +1,571 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// DynamicMessage is implemented by constructing a data structure which +// has roughly the same memory layout as a generated message would have. +// Then, we use GeneratedMessageReflection to implement our reflection +// interface. All the other operations we need to implement (e.g. +// parsing, copying, etc.) are already implemented in terms of +// Reflection, so the rest is easy. +// +// The up side of this strategy is that it's very efficient. We don't +// need to use hash_maps or generic representations of fields. The +// down side is that this is a low-level memory management hack which +// can be tricky to get right. +// +// As mentioned in the header, we only expose a DynamicMessageFactory +// publicly, not the DynamicMessage class itself. This is because +// GenericMessageReflection wants to have a pointer to a "default" +// copy of the class, with all fields initialized to their default +// values. We only want to construct one of these per message type, +// so DynamicMessageFactory stores a cache of default messages for +// each type it sees (each unique Descriptor pointer). The code +// refers to the "default" copy of the class as the "prototype". +// +// Note on memory allocation: This module often calls "operator new()" +// to allocate untyped memory, rather than calling something like +// "new uint8[]". This is because "operator new()" means "Give me some +// space which I can use as I please." while "new uint8[]" means "Give +// me an array of 8-bit integers.". In practice, the later may return +// a pointer that is not aligned correctly for general use. I believe +// Item 8 of "More Effective C++" discusses this in more detail, though +// I don't have the book on me right now so I'm not sure. + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +using internal::WireFormat; +using internal::ExtensionSet; +using internal::GeneratedMessageReflection; + + +// =================================================================== +// Some helper tables and functions... + +namespace { + +// Compute the byte size of the in-memory representation of the field. +int FieldSpaceUsed(const FieldDescriptor* field) { + typedef FieldDescriptor FD; // avoid line wrapping + if (field->label() == FD::LABEL_REPEATED) { + switch (field->cpp_type()) { + case FD::CPPTYPE_INT32 : return sizeof(RepeatedField); + case FD::CPPTYPE_INT64 : return sizeof(RepeatedField); + case FD::CPPTYPE_UINT32 : return sizeof(RepeatedField); + case FD::CPPTYPE_UINT64 : return sizeof(RepeatedField); + case FD::CPPTYPE_DOUBLE : return sizeof(RepeatedField); + case FD::CPPTYPE_FLOAT : return sizeof(RepeatedField); + case FD::CPPTYPE_BOOL : return sizeof(RepeatedField); + case FD::CPPTYPE_ENUM : return sizeof(RepeatedField); + case FD::CPPTYPE_MESSAGE: return sizeof(RepeatedPtrField); + + case FD::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return sizeof(RepeatedPtrField); + } + break; + } + } else { + switch (field->cpp_type()) { + case FD::CPPTYPE_INT32 : return sizeof(int32 ); + case FD::CPPTYPE_INT64 : return sizeof(int64 ); + case FD::CPPTYPE_UINT32 : return sizeof(uint32 ); + case FD::CPPTYPE_UINT64 : return sizeof(uint64 ); + case FD::CPPTYPE_DOUBLE : return sizeof(double ); + case FD::CPPTYPE_FLOAT : return sizeof(float ); + case FD::CPPTYPE_BOOL : return sizeof(bool ); + case FD::CPPTYPE_ENUM : return sizeof(int ); + + case FD::CPPTYPE_MESSAGE: + return sizeof(Message*); + + case FD::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return sizeof(string*); + } + break; + } + } + + GOOGLE_LOG(DFATAL) << "Can't get here."; + return 0; +} + +inline int DivideRoundingUp(int i, int j) { + return (i + (j - 1)) / j; +} + +static const int kSafeAlignment = sizeof(uint64); + +inline int AlignTo(int offset, int alignment) { + return DivideRoundingUp(offset, alignment) * alignment; +} + +// Rounds the given byte offset up to the next offset aligned such that any +// type may be stored at it. +inline int AlignOffset(int offset) { + return AlignTo(offset, kSafeAlignment); +} + +#define bitsizeof(T) (sizeof(T) * 8) + +} // namespace + +// =================================================================== + +class DynamicMessage : public Message { + public: + struct TypeInfo { + int size; + int has_bits_offset; + int unknown_fields_offset; + int extensions_offset; + + // Not owned by the TypeInfo. + DynamicMessageFactory* factory; // The factory that created this object. + const DescriptorPool* pool; // The factory's DescriptorPool. + const Descriptor* type; // Type of this DynamicMessage. + + // Warning: The order in which the following pointers are defined is + // important (the prototype must be deleted *before* the offsets). + scoped_array offsets; + scoped_ptr reflection; + // Don't use a scoped_ptr to hold the prototype: the destructor for + // DynamicMessage needs to know whether it is the prototype, and does so by + // looking back at this field. This would assume details about the + // implementation of scoped_ptr. + const DynamicMessage* prototype; + + TypeInfo() : prototype(NULL) {} + + ~TypeInfo() { + delete prototype; + } + }; + + DynamicMessage(const TypeInfo* type_info); + ~DynamicMessage(); + + // Called on the prototype after construction to initialize message fields. + void CrossLinkPrototypes(); + + // implements Message ---------------------------------------------- + + Message* New() const; + + int GetCachedSize() const; + void SetCachedSize(int size) const; + + Metadata GetMetadata() const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage); + + inline bool is_prototype() const { + return type_info_->prototype == this || + // If type_info_->prototype is NULL, then we must be constructing + // the prototype now, which means we must be the prototype. + type_info_->prototype == NULL; + } + + inline void* OffsetToPointer(int offset) { + return reinterpret_cast(this) + offset; + } + inline const void* OffsetToPointer(int offset) const { + return reinterpret_cast(this) + offset; + } + + const TypeInfo* type_info_; + + // TODO(kenton): Make this an atomic when C++ supports it. + mutable int cached_byte_size_; +}; + +DynamicMessage::DynamicMessage(const TypeInfo* type_info) + : type_info_(type_info), + cached_byte_size_(0) { + // We need to call constructors for various fields manually and set + // default values where appropriate. We use placement new to call + // constructors. If you haven't heard of placement new, I suggest Googling + // it now. We use placement new even for primitive types that don't have + // constructors for consistency. (In theory, placement new should be used + // any time you are trying to convert untyped memory to typed memory, though + // in practice that's not strictly necessary for types that don't have a + // constructor.) + + const Descriptor* descriptor = type_info_->type; + + new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet; + + if (type_info_->extensions_offset != -1) { + new(OffsetToPointer(type_info_->extensions_offset)) ExtensionSet; + } + + for (int i = 0; i < descriptor->field_count(); i++) { + const FieldDescriptor* field = descriptor->field(i); + void* field_ptr = OffsetToPointer(type_info_->offsets[i]); + switch (field->cpp_type()) { +#define HANDLE_TYPE(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + if (!field->is_repeated()) { \ + new(field_ptr) TYPE(field->default_value_##TYPE()); \ + } else { \ + new(field_ptr) RepeatedField(); \ + } \ + break; + + HANDLE_TYPE(INT32 , int32 ); + HANDLE_TYPE(INT64 , int64 ); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT , float ); + HANDLE_TYPE(BOOL , bool ); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_ENUM: + if (!field->is_repeated()) { + new(field_ptr) int(field->default_value_enum()->number()); + } else { + new(field_ptr) RepeatedField(); + } + break; + + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + if (!field->is_repeated()) { + if (is_prototype()) { + new(field_ptr) const string*(&field->default_value_string()); + } else { + string* default_value = + *reinterpret_cast( + type_info_->prototype->OffsetToPointer( + type_info_->offsets[i])); + new(field_ptr) string*(default_value); + } + } else { + new(field_ptr) RepeatedPtrField(); + } + break; + } + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: { + if (!field->is_repeated()) { + new(field_ptr) Message*(NULL); + } else { + new(field_ptr) RepeatedPtrField(); + } + break; + } + } + } +} + +DynamicMessage::~DynamicMessage() { + const Descriptor* descriptor = type_info_->type; + + reinterpret_cast( + OffsetToPointer(type_info_->unknown_fields_offset))->~UnknownFieldSet(); + + if (type_info_->extensions_offset != -1) { + reinterpret_cast( + OffsetToPointer(type_info_->extensions_offset))->~ExtensionSet(); + } + + // We need to manually run the destructors for repeated fields and strings, + // just as we ran their constructors in the the DynamicMessage constructor. + // Additionally, if any singular embedded messages have been allocated, we + // need to delete them, UNLESS we are the prototype message of this type, + // in which case any embedded messages are other prototypes and shouldn't + // be touched. + for (int i = 0; i < descriptor->field_count(); i++) { + const FieldDescriptor* field = descriptor->field(i); + void* field_ptr = OffsetToPointer(type_info_->offsets[i]); + + if (field->is_repeated()) { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + reinterpret_cast*>(field_ptr) \ + ->~RepeatedField(); \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + reinterpret_cast*>(field_ptr) + ->~RepeatedPtrField(); + break; + } + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + reinterpret_cast*>(field_ptr) + ->~RepeatedPtrField(); + break; + } + + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + string* ptr = *reinterpret_cast(field_ptr); + if (ptr != &field->default_value_string()) { + delete ptr; + } + break; + } + } + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (!is_prototype()) { + Message* message = *reinterpret_cast(field_ptr); + if (message != NULL) { + delete message; + } + } + } + } +} + +void DynamicMessage::CrossLinkPrototypes() { + // This should only be called on the prototype message. + GOOGLE_CHECK(is_prototype()); + + DynamicMessageFactory* factory = type_info_->factory; + const Descriptor* descriptor = type_info_->type; + + // Cross-link default messages. + for (int i = 0; i < descriptor->field_count(); i++) { + const FieldDescriptor* field = descriptor->field(i); + void* field_ptr = OffsetToPointer(type_info_->offsets[i]); + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + !field->is_repeated()) { + // For fields with message types, we need to cross-link with the + // prototype for the field's type. + // For singular fields, the field is just a pointer which should + // point to the prototype. + *reinterpret_cast(field_ptr) = + factory->GetPrototypeNoLock(field->message_type()); + } + } +} + +Message* DynamicMessage::New() const { + void* new_base = operator new(type_info_->size); + memset(new_base, 0, type_info_->size); + return new(new_base) DynamicMessage(type_info_); +} + +int DynamicMessage::GetCachedSize() const { + return cached_byte_size_; +} + +void DynamicMessage::SetCachedSize(int size) const { + // This is theoretically not thread-compatible, but in practice it works + // because if multiple threads write this simultaneously, they will be + // writing the exact same value. + cached_byte_size_ = size; +} + +Metadata DynamicMessage::GetMetadata() const { + Metadata metadata; + metadata.descriptor = type_info_->type; + metadata.reflection = type_info_->reflection.get(); + return metadata; +} + +// =================================================================== + +struct DynamicMessageFactory::PrototypeMap { + typedef hash_map Map; + Map map_; +}; + +DynamicMessageFactory::DynamicMessageFactory() + : pool_(NULL), delegate_to_generated_factory_(false), + prototypes_(new PrototypeMap) { +} + +DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool) + : pool_(pool), delegate_to_generated_factory_(false), + prototypes_(new PrototypeMap) { +} + +DynamicMessageFactory::~DynamicMessageFactory() { + for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin(); + iter != prototypes_->map_.end(); ++iter) { + delete iter->second; + } +} + +const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) { + MutexLock lock(&prototypes_mutex_); + return GetPrototypeNoLock(type); +} + +const Message* DynamicMessageFactory::GetPrototypeNoLock( + const Descriptor* type) { + if (delegate_to_generated_factory_ && + type->file()->pool() == DescriptorPool::generated_pool()) { + return MessageFactory::generated_factory()->GetPrototype(type); + } + + const DynamicMessage::TypeInfo** target = &prototypes_->map_[type]; + if (*target != NULL) { + // Already exists. + return (*target)->prototype; + } + + DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo; + *target = type_info; + + type_info->type = type; + type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_; + type_info->factory = this; + + // We need to construct all the structures passed to + // GeneratedMessageReflection's constructor. This includes: + // - A block of memory that contains space for all the message's fields. + // - An array of integers indicating the byte offset of each field within + // this block. + // - A big bitfield containing a bit for each field indicating whether + // or not that field is set. + + // Compute size and offsets. + int* offsets = new int[type->field_count()]; + type_info->offsets.reset(offsets); + + // Decide all field offsets by packing in order. + // We place the DynamicMessage object itself at the beginning of the allocated + // space. + int size = sizeof(DynamicMessage); + size = AlignOffset(size); + + // Next the has_bits, which is an array of uint32s. + type_info->has_bits_offset = size; + int has_bits_array_size = + DivideRoundingUp(type->field_count(), bitsizeof(uint32)); + size += has_bits_array_size * sizeof(uint32); + size = AlignOffset(size); + + // The ExtensionSet, if any. + if (type->extension_range_count() > 0) { + type_info->extensions_offset = size; + size += sizeof(ExtensionSet); + size = AlignOffset(size); + } else { + // No extensions. + type_info->extensions_offset = -1; + } + + // All the fields. + for (int i = 0; i < type->field_count(); i++) { + // Make sure field is aligned to avoid bus errors. + int field_size = FieldSpaceUsed(type->field(i)); + size = AlignTo(size, min(kSafeAlignment, field_size)); + offsets[i] = size; + size += field_size; + } + + // Add the UnknownFieldSet to the end. + size = AlignOffset(size); + type_info->unknown_fields_offset = size; + size += sizeof(UnknownFieldSet); + + // Align the final size to make sure no clever allocators think that + // alignment is not necessary. + size = AlignOffset(size); + type_info->size = size; + + // Allocate the prototype. + void* base = operator new(size); + memset(base, 0, size); + DynamicMessage* prototype = new(base) DynamicMessage(type_info); + type_info->prototype = prototype; + + // Construct the reflection object. + type_info->reflection.reset( + new GeneratedMessageReflection( + type_info->type, + type_info->prototype, + type_info->offsets.get(), + type_info->has_bits_offset, + type_info->unknown_fields_offset, + type_info->extensions_offset, + type_info->pool, + this, + type_info->size)); + + // Cross link prototypes. + prototype->CrossLinkPrototypes(); + + return prototype; +} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message.h new file mode 100644 index 0000000..b3d1e5d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message.h @@ -0,0 +1,136 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Defines an implementation of Message which can emulate types which are not +// known at compile-time. + +#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ +#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ + +#include +#include + +namespace google { +namespace protobuf { + +// Defined in other files. +class Descriptor; // descriptor.h +class DescriptorPool; // descriptor.h + +// Constructs implementations of Message which can emulate types which are not +// known at compile-time. +// +// Sometimes you want to be able to manipulate protocol types that you don't +// know about at compile time. It would be nice to be able to construct +// a Message object which implements the message type given by any arbitrary +// Descriptor. DynamicMessage provides this. +// +// As it turns out, a DynamicMessage needs to construct extra +// information about its type in order to operate. Most of this information +// can be shared between all DynamicMessages of the same type. But, caching +// this information in some sort of global map would be a bad idea, since +// the cached information for a particular descriptor could outlive the +// descriptor itself. To avoid this problem, DynamicMessageFactory +// encapsulates this "cache". All DynamicMessages of the same type created +// from the same factory will share the same support data. Any Descriptors +// used with a particular factory must outlive the factory. +class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory { + public: + // Construct a DynamicMessageFactory that will search for extensions in + // the DescriptorPool in which the extendee is defined. + DynamicMessageFactory(); + + // Construct a DynamicMessageFactory that will search for extensions in + // the given DescriptorPool. + // + // DEPRECATED: Use CodedInputStream::SetExtensionRegistry() to tell the + // parser to look for extensions in an alternate pool. However, note that + // this is almost never what you want to do. Almost all users should use + // the zero-arg constructor. + DynamicMessageFactory(const DescriptorPool* pool); + + ~DynamicMessageFactory(); + + // Call this to tell the DynamicMessageFactory that if it is given a + // Descriptor d for which: + // d->file()->pool() == DescriptorPool::generated_pool(), + // then it should delegate to MessageFactory::generated_factory() instead + // of constructing a dynamic implementation of the message. In theory there + // is no down side to doing this, so it may become the default in the future. + void SetDelegateToGeneratedFactory(bool enable) { + delegate_to_generated_factory_ = enable; + } + + // implements MessageFactory --------------------------------------- + + // Given a Descriptor, constructs the default (prototype) Message of that + // type. You can then call that message's New() method to construct a + // mutable message of that type. + // + // Calling this method twice with the same Descriptor returns the same + // object. The returned object remains property of the factory and will + // be destroyed when the factory is destroyed. Also, any objects created + // by calling the prototype's New() method share some data with the + // prototype, so these must be destroyed before the DynamicMessageFactory + // is destroyed. + // + // The given descriptor must outlive the returned message, and hence must + // outlive the DynamicMessageFactory. + // + // The method is thread-safe. + const Message* GetPrototype(const Descriptor* type); + + private: + const DescriptorPool* pool_; + bool delegate_to_generated_factory_; + + // This struct just contains a hash_map. We can't #include from + // this header due to hacks needed for hash_map portability in the open source + // release. Namely, stubs/hash.h, which defines hash_map portably, is not a + // public header (for good reason), but dynamic_message.h is, and public + // headers may only #include other public headers. + struct PrototypeMap; + scoped_ptr prototypes_; + mutable Mutex prototypes_mutex_; + + friend class DynamicMessage; + const Message* GetPrototypeNoLock(const Descriptor* type); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message_unittest.cc new file mode 100644 index 0000000..e461597 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/dynamic_message_unittest.cc @@ -0,0 +1,166 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Since the reflection interface for DynamicMessage is implemented by +// GenericMessageReflection, the only thing we really have to test is +// that DynamicMessage correctly sets up the information that +// GenericMessageReflection needs to use. So, we focus on that in this +// test. Other tests, such as generic_message_reflection_unittest and +// reflection_ops_unittest, cover the rest of the functionality used by +// DynamicMessage. + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace google { +namespace protobuf { + +class DynamicMessageTest : public testing::Test { + protected: + DescriptorPool pool_; + DynamicMessageFactory factory_; + const Descriptor* descriptor_; + const Message* prototype_; + const Descriptor* extensions_descriptor_; + const Message* extensions_prototype_; + const Descriptor* packed_descriptor_; + const Message* packed_prototype_; + + DynamicMessageTest(): factory_(&pool_) {} + + virtual void SetUp() { + // We want to make sure that DynamicMessage works (particularly with + // extensions) even if we use descriptors that are *not* from compiled-in + // types, so we make copies of the descriptors for unittest.proto and + // unittest_import.proto. + FileDescriptorProto unittest_file; + FileDescriptorProto unittest_import_file; + FileDescriptorProto unittest_import_public_file; + + unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file); + unittest_import::ImportMessage::descriptor()->file()->CopyTo( + &unittest_import_file); + unittest_import::PublicImportMessage::descriptor()->file()->CopyTo( + &unittest_import_public_file); + + ASSERT_TRUE(pool_.BuildFile(unittest_import_public_file) != NULL); + ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != NULL); + ASSERT_TRUE(pool_.BuildFile(unittest_file) != NULL); + + descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes"); + ASSERT_TRUE(descriptor_ != NULL); + prototype_ = factory_.GetPrototype(descriptor_); + + extensions_descriptor_ = + pool_.FindMessageTypeByName("protobuf_unittest.TestAllExtensions"); + ASSERT_TRUE(extensions_descriptor_ != NULL); + extensions_prototype_ = factory_.GetPrototype(extensions_descriptor_); + + packed_descriptor_ = + pool_.FindMessageTypeByName("protobuf_unittest.TestPackedTypes"); + ASSERT_TRUE(packed_descriptor_ != NULL); + packed_prototype_ = factory_.GetPrototype(packed_descriptor_); + } +}; + +TEST_F(DynamicMessageTest, Descriptor) { + // Check that the descriptor on the DynamicMessage matches the descriptor + // passed to GetPrototype(). + EXPECT_EQ(prototype_->GetDescriptor(), descriptor_); +} + +TEST_F(DynamicMessageTest, OnePrototype) { + // Check that requesting the same prototype twice produces the same object. + EXPECT_EQ(prototype_, factory_.GetPrototype(descriptor_)); +} + +TEST_F(DynamicMessageTest, Defaults) { + // Check that all default values are set correctly in the initial message. + TestUtil::ReflectionTester reflection_tester(descriptor_); + reflection_tester.ExpectClearViaReflection(*prototype_); +} + +TEST_F(DynamicMessageTest, IndependentOffsets) { + // Check that all fields have independent offsets by setting each + // one to a unique value then checking that they all still have those + // unique values (i.e. they don't stomp each other). + scoped_ptr message(prototype_->New()); + TestUtil::ReflectionTester reflection_tester(descriptor_); + + reflection_tester.SetAllFieldsViaReflection(message.get()); + reflection_tester.ExpectAllFieldsSetViaReflection(*message); +} + +TEST_F(DynamicMessageTest, Extensions) { + // Check that extensions work. + scoped_ptr message(extensions_prototype_->New()); + TestUtil::ReflectionTester reflection_tester(extensions_descriptor_); + + reflection_tester.SetAllFieldsViaReflection(message.get()); + reflection_tester.ExpectAllFieldsSetViaReflection(*message); +} + +TEST_F(DynamicMessageTest, PackedFields) { + // Check that packed fields work properly. + scoped_ptr message(packed_prototype_->New()); + TestUtil::ReflectionTester reflection_tester(packed_descriptor_); + + reflection_tester.SetPackedFieldsViaReflection(message.get()); + reflection_tester.ExpectPackedFieldsSetViaReflection(*message); +} + +TEST_F(DynamicMessageTest, SpaceUsed) { + // Test that SpaceUsed() works properly + + // Since we share the implementation with generated messages, we don't need + // to test very much here. Just make sure it appears to be working. + + scoped_ptr message(prototype_->New()); + TestUtil::ReflectionTester reflection_tester(descriptor_); + + int initial_space_used = message->SpaceUsed(); + + reflection_tester.SetAllFieldsViaReflection(message.get()); + EXPECT_LT(initial_space_used, message->SpaceUsed()); +} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set.cc new file mode 100644 index 0000000..2cbba8f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set.cc @@ -0,0 +1,1461 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +namespace { + +inline WireFormatLite::FieldType real_type(FieldType type) { + GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE); + return static_cast(type); +} + +inline WireFormatLite::CppType cpp_type(FieldType type) { + return WireFormatLite::FieldTypeToCppType(real_type(type)); +} + +// Registry stuff. +typedef hash_map, + ExtensionInfo> ExtensionRegistry; +ExtensionRegistry* registry_ = NULL; +GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_); + +void DeleteRegistry() { + delete registry_; + registry_ = NULL; +} + +void InitRegistry() { + registry_ = new ExtensionRegistry; + OnShutdown(&DeleteRegistry); +} + +// This function is only called at startup, so there is no need for thread- +// safety. +void Register(const MessageLite* containing_type, + int number, ExtensionInfo info) { + ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry); + + if (!InsertIfNotPresent(registry_, make_pair(containing_type, number), + info)) { + GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \"" + << containing_type->GetTypeName() + << "\", field number " << number << "."; + } +} + +const ExtensionInfo* FindRegisteredExtension( + const MessageLite* containing_type, int number) { + return (registry_ == NULL) ? NULL : + FindOrNull(*registry_, make_pair(containing_type, number)); +} + +} // namespace + +ExtensionFinder::~ExtensionFinder() {} + +bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) { + const ExtensionInfo* extension = + FindRegisteredExtension(containing_type_, number); + if (extension == NULL) { + return false; + } else { + *output = *extension; + return true; + } +} + +void ExtensionSet::RegisterExtension(const MessageLite* containing_type, + int number, FieldType type, + bool is_repeated, bool is_packed) { + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM); + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE); + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP); + ExtensionInfo info(type, is_repeated, is_packed); + Register(containing_type, number, info); +} + +static bool CallNoArgValidityFunc(const void* arg, int number) { + // Note: Must use C-style cast here rather than reinterpret_cast because + // the C++ standard at one point did not allow casts between function and + // data pointers and some compilers enforce this for C++-style casts. No + // compiler enforces it for C-style casts since lots of C-style code has + // relied on these kinds of casts for a long time, despite being + // technically undefined. See: + // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195 + // Also note: Some compilers do not allow function pointers to be "const". + // Which makes sense, I suppose, because it's meaningless. + return ((EnumValidityFunc*)arg)(number); +} + +void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type, + int number, FieldType type, + bool is_repeated, bool is_packed, + EnumValidityFunc* is_valid) { + GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM); + ExtensionInfo info(type, is_repeated, is_packed); + info.enum_validity_check.func = CallNoArgValidityFunc; + // See comment in CallNoArgValidityFunc() about why we use a c-style cast. + info.enum_validity_check.arg = (void*)is_valid; + Register(containing_type, number, info); +} + +void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type, + int number, FieldType type, + bool is_repeated, bool is_packed, + const MessageLite* prototype) { + GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE || + type == WireFormatLite::TYPE_GROUP); + ExtensionInfo info(type, is_repeated, is_packed); + info.message_prototype = prototype; + Register(containing_type, number, info); +} + + +// =================================================================== +// Constructors and basic methods. + +ExtensionSet::ExtensionSet() {} + +ExtensionSet::~ExtensionSet() { + for (map::iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + iter->second.Free(); + } +} + +// Defined in extension_set_heavy.cc. +// void ExtensionSet::AppendToList(const Descriptor* containing_type, +// const DescriptorPool* pool, +// vector* output) const + +bool ExtensionSet::Has(int number) const { + map::const_iterator iter = extensions_.find(number); + if (iter == extensions_.end()) return false; + GOOGLE_DCHECK(!iter->second.is_repeated); + return !iter->second.is_cleared; +} + +int ExtensionSet::NumExtensions() const { + int result = 0; + for (map::const_iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + if (!iter->second.is_cleared) { + ++result; + } + } + return result; +} + +int ExtensionSet::ExtensionSize(int number) const { + map::const_iterator iter = extensions_.find(number); + if (iter == extensions_.end()) return false; + return iter->second.GetSize(); +} + +FieldType ExtensionSet::ExtensionType(int number) const { + map::const_iterator iter = extensions_.find(number); + if (iter == extensions_.end()) { + GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). "; + return 0; + } + if (iter->second.is_cleared) { + GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). "; + } + return iter->second.type; +} + +void ExtensionSet::ClearExtension(int number) { + map::iterator iter = extensions_.find(number); + if (iter == extensions_.end()) return; + iter->second.Clear(); +} + +// =================================================================== +// Field accessors + +namespace { + +enum Cardinality { + REPEATED, + OPTIONAL +}; + +} // namespace + +#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ + GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \ + GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE) + +// ------------------------------------------------------------------- +// Primitives + +#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \ + \ +LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \ + LOWERCASE default_value) const { \ + map::const_iterator iter = extensions_.find(number); \ + if (iter == extensions_.end() || iter->second.is_cleared) { \ + return default_value; \ + } else { \ + GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \ + return iter->second.LOWERCASE##_value; \ + } \ +} \ + \ +void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \ + LOWERCASE value, \ + const FieldDescriptor* descriptor) { \ + Extension* extension; \ + if (MaybeNewExtension(number, descriptor, &extension)) { \ + extension->type = type; \ + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ + extension->is_repeated = false; \ + } else { \ + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \ + } \ + extension->is_cleared = false; \ + extension->LOWERCASE##_value = value; \ +} \ + \ +LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \ + map::const_iterator iter = extensions_.find(number); \ + GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ + GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \ + return iter->second.repeated_##LOWERCASE##_value->Get(index); \ +} \ + \ +void ExtensionSet::SetRepeated##CAMELCASE( \ + int number, int index, LOWERCASE value) { \ + map::iterator iter = extensions_.find(number); \ + GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ + GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \ + iter->second.repeated_##LOWERCASE##_value->Set(index, value); \ +} \ + \ +void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \ + bool packed, LOWERCASE value, \ + const FieldDescriptor* descriptor) { \ + Extension* extension; \ + if (MaybeNewExtension(number, descriptor, &extension)) { \ + extension->type = type; \ + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ + extension->is_repeated = true; \ + extension->is_packed = packed; \ + extension->repeated_##LOWERCASE##_value = new RepeatedField(); \ + } else { \ + GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \ + GOOGLE_DCHECK_EQ(extension->is_packed, packed); \ + } \ + extension->repeated_##LOWERCASE##_value->Add(value); \ +} + +PRIMITIVE_ACCESSORS( INT32, int32, Int32) +PRIMITIVE_ACCESSORS( INT64, int64, Int64) +PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32) +PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64) +PRIMITIVE_ACCESSORS( FLOAT, float, Float) +PRIMITIVE_ACCESSORS(DOUBLE, double, Double) +PRIMITIVE_ACCESSORS( BOOL, bool, Bool) + +#undef PRIMITIVE_ACCESSORS + +void* ExtensionSet::MutableRawRepeatedField(int number) { + // We assume that all the RepeatedField<>* pointers have the same + // size and alignment within the anonymous union in Extension. + map::const_iterator iter = extensions_.find(number); + GOOGLE_CHECK(iter != extensions_.end()) << "no extension numbered " << number; + return iter->second.repeated_int32_value; +} + +// ------------------------------------------------------------------- +// Enums + +int ExtensionSet::GetEnum(int number, int default_value) const { + map::const_iterator iter = extensions_.find(number); + if (iter == extensions_.end() || iter->second.is_cleared) { + // Not present. Return the default value. + return default_value; + } else { + GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM); + return iter->second.enum_value; + } +} + +void ExtensionSet::SetEnum(int number, FieldType type, int value, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); + extension->is_repeated = false; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM); + } + extension->is_cleared = false; + extension->enum_value = value; +} + +int ExtensionSet::GetRepeatedEnum(int number, int index) const { + map::const_iterator iter = extensions_.find(number); + GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM); + return iter->second.repeated_enum_value->Get(index); +} + +void ExtensionSet::SetRepeatedEnum(int number, int index, int value) { + map::iterator iter = extensions_.find(number); + GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM); + iter->second.repeated_enum_value->Set(index, value); +} + +void ExtensionSet::AddEnum(int number, FieldType type, + bool packed, int value, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); + extension->is_repeated = true; + extension->is_packed = packed; + extension->repeated_enum_value = new RepeatedField(); + } else { + GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM); + GOOGLE_DCHECK_EQ(extension->is_packed, packed); + } + extension->repeated_enum_value->Add(value); +} + +// ------------------------------------------------------------------- +// Strings + +const string& ExtensionSet::GetString(int number, + const string& default_value) const { + map::const_iterator iter = extensions_.find(number); + if (iter == extensions_.end() || iter->second.is_cleared) { + // Not present. Return the default value. + return default_value; + } else { + GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING); + return *iter->second.string_value; + } +} + +string* ExtensionSet::MutableString(int number, FieldType type, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); + extension->is_repeated = false; + extension->string_value = new string; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING); + } + extension->is_cleared = false; + return extension->string_value; +} + +const string& ExtensionSet::GetRepeatedString(int number, int index) const { + map::const_iterator iter = extensions_.find(number); + GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING); + return iter->second.repeated_string_value->Get(index); +} + +string* ExtensionSet::MutableRepeatedString(int number, int index) { + map::iterator iter = extensions_.find(number); + GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING); + return iter->second.repeated_string_value->Mutable(index); +} + +string* ExtensionSet::AddString(int number, FieldType type, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); + extension->is_repeated = true; + extension->is_packed = false; + extension->repeated_string_value = new RepeatedPtrField(); + } else { + GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING); + } + return extension->repeated_string_value->Add(); +} + +// ------------------------------------------------------------------- +// Messages + +const MessageLite& ExtensionSet::GetMessage( + int number, const MessageLite& default_value) const { + map::const_iterator iter = extensions_.find(number); + if (iter == extensions_.end()) { + // Not present. Return the default value. + return default_value; + } else { + GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); + if (iter->second.is_lazy) { + return iter->second.lazymessage_value->GetMessage(default_value); + } else { + return *iter->second.message_value; + } + } +} + +// Defined in extension_set_heavy.cc. +// const MessageLite& ExtensionSet::GetMessage(int number, +// const Descriptor* message_type, +// MessageFactory* factory) const + +MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, + const MessageLite& prototype, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); + extension->is_repeated = false; + extension->is_lazy = false; + extension->message_value = prototype.New(); + extension->is_cleared = false; + return extension->message_value; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); + extension->is_cleared = false; + if (extension->is_lazy) { + return extension->lazymessage_value->MutableMessage(prototype); + } else { + return extension->message_value; + } + } +} + +// Defined in extension_set_heavy.cc. +// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, +// const Descriptor* message_type, +// MessageFactory* factory) + +void ExtensionSet::SetAllocatedMessage(int number, FieldType type, + const FieldDescriptor* descriptor, + MessageLite* message) { + if (message == NULL) { + ClearExtension(number); + return; + } + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); + extension->is_repeated = false; + extension->is_lazy = false; + extension->message_value = message; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); + if (extension->is_lazy) { + extension->lazymessage_value->SetAllocatedMessage(message); + } else { + delete extension->message_value; + extension->message_value = message; + } + } + extension->is_cleared = false; +} + +MessageLite* ExtensionSet::ReleaseMessage(int number, + const MessageLite& prototype) { + map::iterator iter = extensions_.find(number); + if (iter == extensions_.end()) { + // Not present. Return NULL. + return NULL; + } else { + GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); + MessageLite* ret = NULL; + if (iter->second.is_lazy) { + ret = iter->second.lazymessage_value->ReleaseMessage(prototype); + delete iter->second.lazymessage_value; + } else { + ret = iter->second.message_value; + } + extensions_.erase(number); + return ret; + } +} + +// Defined in extension_set_heavy.cc. +// MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor, +// MessageFactory* factory); + +const MessageLite& ExtensionSet::GetRepeatedMessage( + int number, int index) const { + map::const_iterator iter = extensions_.find(number); + GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); + return iter->second.repeated_message_value->Get(index); +} + +MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) { + map::iterator iter = extensions_.find(number); + GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); + return iter->second.repeated_message_value->Mutable(index); +} + +MessageLite* ExtensionSet::AddMessage(int number, FieldType type, + const MessageLite& prototype, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); + extension->is_repeated = true; + extension->repeated_message_value = + new RepeatedPtrField(); + } else { + GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); + } + + // RepeatedPtrField does not know how to Add() since it cannot + // allocate an abstract object, so we have to be tricky. + MessageLite* result = extension->repeated_message_value + ->AddFromCleared >(); + if (result == NULL) { + result = prototype.New(); + extension->repeated_message_value->AddAllocated(result); + } + return result; +} + +// Defined in extension_set_heavy.cc. +// MessageLite* ExtensionSet::AddMessage(int number, FieldType type, +// const Descriptor* message_type, +// MessageFactory* factory) + +#undef GOOGLE_DCHECK_TYPE + +void ExtensionSet::RemoveLast(int number) { + map::iterator iter = extensions_.find(number); + GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; + + Extension* extension = &iter->second; + GOOGLE_DCHECK(extension->is_repeated); + + switch(cpp_type(extension->type)) { + case WireFormatLite::CPPTYPE_INT32: + extension->repeated_int32_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_INT64: + extension->repeated_int64_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_UINT32: + extension->repeated_uint32_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_UINT64: + extension->repeated_uint64_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_FLOAT: + extension->repeated_float_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_DOUBLE: + extension->repeated_double_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_BOOL: + extension->repeated_bool_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_ENUM: + extension->repeated_enum_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_STRING: + extension->repeated_string_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_MESSAGE: + extension->repeated_message_value->RemoveLast(); + break; + } +} + +MessageLite* ExtensionSet::ReleaseLast(int number) { + map::iterator iter = extensions_.find(number); + GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; + + Extension* extension = &iter->second; + GOOGLE_DCHECK(extension->is_repeated); + GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE); + return extension->repeated_message_value->ReleaseLast(); +} + +void ExtensionSet::SwapElements(int number, int index1, int index2) { + map::iterator iter = extensions_.find(number); + GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; + + Extension* extension = &iter->second; + GOOGLE_DCHECK(extension->is_repeated); + + switch(cpp_type(extension->type)) { + case WireFormatLite::CPPTYPE_INT32: + extension->repeated_int32_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_INT64: + extension->repeated_int64_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_UINT32: + extension->repeated_uint32_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_UINT64: + extension->repeated_uint64_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_FLOAT: + extension->repeated_float_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_DOUBLE: + extension->repeated_double_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_BOOL: + extension->repeated_bool_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_ENUM: + extension->repeated_enum_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_STRING: + extension->repeated_string_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_MESSAGE: + extension->repeated_message_value->SwapElements(index1, index2); + break; + } +} + +// =================================================================== + +void ExtensionSet::Clear() { + for (map::iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + iter->second.Clear(); + } +} + +void ExtensionSet::MergeFrom(const ExtensionSet& other) { + for (map::const_iterator iter = other.extensions_.begin(); + iter != other.extensions_.end(); ++iter) { + const Extension& other_extension = iter->second; + + if (other_extension.is_repeated) { + Extension* extension; + bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor, + &extension); + if (is_new) { + // Extension did not already exist in set. + extension->type = other_extension.type; + extension->is_packed = other_extension.is_packed; + extension->is_repeated = true; + } else { + GOOGLE_DCHECK_EQ(extension->type, other_extension.type); + GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed); + GOOGLE_DCHECK(extension->is_repeated); + } + + switch (cpp_type(other_extension.type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ + if (is_new) { \ + extension->repeated_##LOWERCASE##_value = \ + new REPEATED_TYPE; \ + } \ + extension->repeated_##LOWERCASE##_value->MergeFrom( \ + *other_extension.repeated_##LOWERCASE##_value); \ + break; + + HANDLE_TYPE( INT32, int32, RepeatedField < int32>); + HANDLE_TYPE( INT64, int64, RepeatedField < int64>); + HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>); + HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>); + HANDLE_TYPE( FLOAT, float, RepeatedField < float>); + HANDLE_TYPE( DOUBLE, double, RepeatedField < double>); + HANDLE_TYPE( BOOL, bool, RepeatedField < bool>); + HANDLE_TYPE( ENUM, enum, RepeatedField < int>); + HANDLE_TYPE( STRING, string, RepeatedPtrField< string>); +#undef HANDLE_TYPE + + case WireFormatLite::CPPTYPE_MESSAGE: + if (is_new) { + extension->repeated_message_value = + new RepeatedPtrField(); + } + // We can't call RepeatedPtrField::MergeFrom() because + // it would attempt to allocate new objects. + RepeatedPtrField* other_repeated_message = + other_extension.repeated_message_value; + for (int i = 0; i < other_repeated_message->size(); i++) { + const MessageLite& other_message = other_repeated_message->Get(i); + MessageLite* target = extension->repeated_message_value + ->AddFromCleared >(); + if (target == NULL) { + target = other_message.New(); + extension->repeated_message_value->AddAllocated(target); + } + target->CheckTypeAndMergeFrom(other_message); + } + break; + } + } else { + if (!other_extension.is_cleared) { + switch (cpp_type(other_extension.type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ + Set##CAMELCASE(iter->first, other_extension.type, \ + other_extension.LOWERCASE##_value, \ + other_extension.descriptor); \ + break; + + HANDLE_TYPE( INT32, int32, Int32); + HANDLE_TYPE( INT64, int64, Int64); + HANDLE_TYPE(UINT32, uint32, UInt32); + HANDLE_TYPE(UINT64, uint64, UInt64); + HANDLE_TYPE( FLOAT, float, Float); + HANDLE_TYPE(DOUBLE, double, Double); + HANDLE_TYPE( BOOL, bool, Bool); + HANDLE_TYPE( ENUM, enum, Enum); +#undef HANDLE_TYPE + case WireFormatLite::CPPTYPE_STRING: + SetString(iter->first, other_extension.type, + *other_extension.string_value, + other_extension.descriptor); + break; + case WireFormatLite::CPPTYPE_MESSAGE: { + Extension* extension; + bool is_new = MaybeNewExtension(iter->first, + other_extension.descriptor, + &extension); + if (is_new) { + extension->type = other_extension.type; + extension->is_packed = other_extension.is_packed; + extension->is_repeated = false; + if (other_extension.is_lazy) { + extension->is_lazy = true; + extension->lazymessage_value = + other_extension.lazymessage_value->New(); + extension->lazymessage_value->MergeFrom( + *other_extension.lazymessage_value); + } else { + extension->is_lazy = false; + extension->message_value = + other_extension.message_value->New(); + extension->message_value->CheckTypeAndMergeFrom( + *other_extension.message_value); + } + } else { + GOOGLE_DCHECK_EQ(extension->type, other_extension.type); + GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed); + GOOGLE_DCHECK(!extension->is_repeated); + if (other_extension.is_lazy) { + if (extension->is_lazy) { + extension->lazymessage_value->MergeFrom( + *other_extension.lazymessage_value); + } else { + extension->message_value->CheckTypeAndMergeFrom( + other_extension.lazymessage_value->GetMessage( + *extension->message_value)); + } + } else { + if (extension->is_lazy) { + extension->lazymessage_value->MutableMessage( + *other_extension.message_value)->CheckTypeAndMergeFrom( + *other_extension.message_value); + } else { + extension->message_value->CheckTypeAndMergeFrom( + *other_extension.message_value); + } + } + } + extension->is_cleared = false; + break; + } + } + } + } + } +} + +void ExtensionSet::Swap(ExtensionSet* x) { + extensions_.swap(x->extensions_); +} + +bool ExtensionSet::IsInitialized() const { + // Extensions are never required. However, we need to check that all + // embedded messages are initialized. + for (map::const_iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + const Extension& extension = iter->second; + if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) { + if (extension.is_repeated) { + for (int i = 0; i < extension.repeated_message_value->size(); i++) { + if (!extension.repeated_message_value->Get(i).IsInitialized()) { + return false; + } + } + } else { + if (!extension.is_cleared) { + if (extension.is_lazy) { + if (!extension.lazymessage_value->IsInitialized()) return false; + } else { + if (!extension.message_value->IsInitialized()) return false; + } + } + } + } + } + + return true; +} + +bool ExtensionSet::FindExtensionInfoFromTag( + uint32 tag, ExtensionFinder* extension_finder, + int* field_number, ExtensionInfo* extension) { + *field_number = WireFormatLite::GetTagFieldNumber(tag); + WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); + + bool is_unknown; + if (!extension_finder->Find(*field_number, extension)) { + is_unknown = true; + } else if (extension->is_packed) { + is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + } else { + WireFormatLite::WireType expected_wire_type = + WireFormatLite::WireTypeForFieldType(real_type(extension->type)); + is_unknown = (wire_type != expected_wire_type); + } + return !is_unknown; +} + +bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper) { + int number; + ExtensionInfo extension; + if (!FindExtensionInfoFromTag(tag, extension_finder, &number, &extension)) { + return field_skipper->SkipField(input, tag); + } else { + return ParseFieldWithExtensionInfo(number, extension, input, field_skipper); + } +} + +bool ExtensionSet::ParseFieldWithExtensionInfo( + int number, const ExtensionInfo& extension, + io::CodedInputStream* input, + FieldSkipper* field_skipper) { + if (extension.is_packed) { + uint32 size; + if (!input->ReadVarint32(&size)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(size); + + switch (extension.type) { +#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + while (input->BytesUntilLimit() > 0) { \ + CPP_LOWERCASE value; \ + if (!WireFormatLite::ReadPrimitive< \ + CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \ + input, &value)) return false; \ + Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ + true, value, extension.descriptor); \ + } \ + break + + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, Int32, int32); + HANDLE_TYPE( SINT64, Int64, int64); + HANDLE_TYPE( FIXED32, UInt32, uint32); + HANDLE_TYPE( FIXED64, UInt64, uint64); + HANDLE_TYPE(SFIXED32, Int32, int32); + HANDLE_TYPE(SFIXED64, Int64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); +#undef HANDLE_TYPE + + case WireFormatLite::TYPE_ENUM: + while (input->BytesUntilLimit() > 0) { + int value; + if (!WireFormatLite::ReadPrimitive( + input, &value)) return false; + if (extension.enum_validity_check.func( + extension.enum_validity_check.arg, value)) { + AddEnum(number, WireFormatLite::TYPE_ENUM, true, value, + extension.descriptor); + } + } + break; + + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; + break; + } + + input->PopLimit(limit); + } else { + switch (extension.type) { +#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: { \ + CPP_LOWERCASE value; \ + if (!WireFormatLite::ReadPrimitive< \ + CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \ + input, &value)) return false; \ + if (extension.is_repeated) { \ + Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ + false, value, extension.descriptor); \ + } else { \ + Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \ + extension.descriptor); \ + } \ + } break + + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, Int32, int32); + HANDLE_TYPE( SINT64, Int64, int64); + HANDLE_TYPE( FIXED32, UInt32, uint32); + HANDLE_TYPE( FIXED64, UInt64, uint64); + HANDLE_TYPE(SFIXED32, Int32, int32); + HANDLE_TYPE(SFIXED64, Int64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); +#undef HANDLE_TYPE + + case WireFormatLite::TYPE_ENUM: { + int value; + if (!WireFormatLite::ReadPrimitive( + input, &value)) return false; + + if (!extension.enum_validity_check.func( + extension.enum_validity_check.arg, value)) { + // Invalid value. Treat as unknown. + field_skipper->SkipUnknownEnum(number, value); + } else if (extension.is_repeated) { + AddEnum(number, WireFormatLite::TYPE_ENUM, false, value, + extension.descriptor); + } else { + SetEnum(number, WireFormatLite::TYPE_ENUM, value, + extension.descriptor); + } + break; + } + + case WireFormatLite::TYPE_STRING: { + string* value = extension.is_repeated ? + AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) : + MutableString(number, WireFormatLite::TYPE_STRING, + extension.descriptor); + if (!WireFormatLite::ReadString(input, value)) return false; + break; + } + + case WireFormatLite::TYPE_BYTES: { + string* value = extension.is_repeated ? + AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) : + MutableString(number, WireFormatLite::TYPE_BYTES, + extension.descriptor); + if (!WireFormatLite::ReadBytes(input, value)) return false; + break; + } + + case WireFormatLite::TYPE_GROUP: { + MessageLite* value = extension.is_repeated ? + AddMessage(number, WireFormatLite::TYPE_GROUP, + *extension.message_prototype, extension.descriptor) : + MutableMessage(number, WireFormatLite::TYPE_GROUP, + *extension.message_prototype, extension.descriptor); + if (!WireFormatLite::ReadGroup(number, input, value)) return false; + break; + } + + case WireFormatLite::TYPE_MESSAGE: { + MessageLite* value = extension.is_repeated ? + AddMessage(number, WireFormatLite::TYPE_MESSAGE, + *extension.message_prototype, extension.descriptor) : + MutableMessage(number, WireFormatLite::TYPE_MESSAGE, + *extension.message_prototype, extension.descriptor); + if (!WireFormatLite::ReadMessage(input, value)) return false; + break; + } + } + } + + return true; +} + +bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, + const MessageLite* containing_type) { + FieldSkipper skipper; + GeneratedExtensionFinder finder(containing_type); + return ParseField(tag, input, &finder, &skipper); +} + +// Defined in extension_set_heavy.cc. +// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, +// const MessageLite* containing_type, +// UnknownFieldSet* unknown_fields) + +// Defined in extension_set_heavy.cc. +// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, +// const MessageLite* containing_type, +// UnknownFieldSet* unknown_fields); + +void ExtensionSet::SerializeWithCachedSizes( + int start_field_number, int end_field_number, + io::CodedOutputStream* output) const { + map::const_iterator iter; + for (iter = extensions_.lower_bound(start_field_number); + iter != extensions_.end() && iter->first < end_field_number; + ++iter) { + iter->second.SerializeFieldWithCachedSizes(iter->first, output); + } +} + +int ExtensionSet::ByteSize() const { + int total_size = 0; + + for (map::const_iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + total_size += iter->second.ByteSize(iter->first); + } + + return total_size; +} + +// Defined in extension_set_heavy.cc. +// int ExtensionSet::SpaceUsedExcludingSelf() const + +bool ExtensionSet::MaybeNewExtension(int number, + const FieldDescriptor* descriptor, + Extension** result) { + pair::iterator, bool> insert_result = + extensions_.insert(make_pair(number, Extension())); + *result = &insert_result.first->second; + (*result)->descriptor = descriptor; + return insert_result.second; +} + +// =================================================================== +// Methods of ExtensionSet::Extension + +void ExtensionSet::Extension::Clear() { + if (is_repeated) { + switch (cpp_type(type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ + repeated_##LOWERCASE##_value->Clear(); \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE( UINT32, uint32); + HANDLE_TYPE( UINT64, uint64); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( DOUBLE, double); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, enum); + HANDLE_TYPE( STRING, string); + HANDLE_TYPE(MESSAGE, message); +#undef HANDLE_TYPE + } + } else { + if (!is_cleared) { + switch (cpp_type(type)) { + case WireFormatLite::CPPTYPE_STRING: + string_value->clear(); + break; + case WireFormatLite::CPPTYPE_MESSAGE: + if (is_lazy) { + lazymessage_value->Clear(); + } else { + message_value->Clear(); + } + break; + default: + // No need to do anything. Get*() will return the default value + // as long as is_cleared is true and Set*() will overwrite the + // previous value. + break; + } + + is_cleared = true; + } + } +} + +void ExtensionSet::Extension::SerializeFieldWithCachedSizes( + int number, + io::CodedOutputStream* output) const { + if (is_repeated) { + if (is_packed) { + if (cached_size == 0) return; + + WireFormatLite::WriteTag(number, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(cached_size); + + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + WireFormatLite::Write##CAMELCASE##NoTag( \ + repeated_##LOWERCASE##_value->Get(i), output); \ + } \ + break + + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, SInt32, int32); + HANDLE_TYPE( SINT64, SInt64, int64); + HANDLE_TYPE( FIXED32, Fixed32, uint32); + HANDLE_TYPE( FIXED64, Fixed64, uint64); + HANDLE_TYPE(SFIXED32, SFixed32, int32); + HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); + HANDLE_TYPE( ENUM, Enum, enum); +#undef HANDLE_TYPE + + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; + break; + } + } else { + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + WireFormatLite::Write##CAMELCASE(number, \ + repeated_##LOWERCASE##_value->Get(i), output); \ + } \ + break + + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, SInt32, int32); + HANDLE_TYPE( SINT64, SInt64, int64); + HANDLE_TYPE( FIXED32, Fixed32, uint32); + HANDLE_TYPE( FIXED64, Fixed64, uint64); + HANDLE_TYPE(SFIXED32, SFixed32, int32); + HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); + HANDLE_TYPE( STRING, String, string); + HANDLE_TYPE( BYTES, Bytes, string); + HANDLE_TYPE( ENUM, Enum, enum); + HANDLE_TYPE( GROUP, Group, message); + HANDLE_TYPE( MESSAGE, Message, message); +#undef HANDLE_TYPE + } + } + } else if (!is_cleared) { + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + WireFormatLite::Write##CAMELCASE(number, VALUE, output); \ + break + + HANDLE_TYPE( INT32, Int32, int32_value); + HANDLE_TYPE( INT64, Int64, int64_value); + HANDLE_TYPE( UINT32, UInt32, uint32_value); + HANDLE_TYPE( UINT64, UInt64, uint64_value); + HANDLE_TYPE( SINT32, SInt32, int32_value); + HANDLE_TYPE( SINT64, SInt64, int64_value); + HANDLE_TYPE( FIXED32, Fixed32, uint32_value); + HANDLE_TYPE( FIXED64, Fixed64, uint64_value); + HANDLE_TYPE(SFIXED32, SFixed32, int32_value); + HANDLE_TYPE(SFIXED64, SFixed64, int64_value); + HANDLE_TYPE( FLOAT, Float, float_value); + HANDLE_TYPE( DOUBLE, Double, double_value); + HANDLE_TYPE( BOOL, Bool, bool_value); + HANDLE_TYPE( STRING, String, *string_value); + HANDLE_TYPE( BYTES, Bytes, *string_value); + HANDLE_TYPE( ENUM, Enum, enum_value); + HANDLE_TYPE( GROUP, Group, *message_value); +#undef HANDLE_TYPE + case WireFormatLite::TYPE_MESSAGE: + if (is_lazy) { + lazymessage_value->WriteMessage(number, output); + } else { + WireFormatLite::WriteMessage(number, *message_value, output); + } + break; + } + } +} + +int ExtensionSet::Extension::ByteSize(int number) const { + int result = 0; + + if (is_repeated) { + if (is_packed) { + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + result += WireFormatLite::CAMELCASE##Size( \ + repeated_##LOWERCASE##_value->Get(i)); \ + } \ + break + + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, SInt32, int32); + HANDLE_TYPE( SINT64, SInt64, int64); + HANDLE_TYPE( ENUM, Enum, enum); +#undef HANDLE_TYPE + + // Stuff with fixed size. +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::k##CAMELCASE##Size * \ + repeated_##LOWERCASE##_value->size(); \ + break + HANDLE_TYPE( FIXED32, Fixed32, uint32); + HANDLE_TYPE( FIXED64, Fixed64, uint64); + HANDLE_TYPE(SFIXED32, SFixed32, int32); + HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); +#undef HANDLE_TYPE + + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; + break; + } + + cached_size = result; + if (result > 0) { + result += io::CodedOutputStream::VarintSize32(result); + result += io::CodedOutputStream::VarintSize32( + WireFormatLite::MakeTag(number, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); + } + } else { + int tag_size = WireFormatLite::TagSize(number, real_type(type)); + + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += tag_size * repeated_##LOWERCASE##_value->size(); \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + result += WireFormatLite::CAMELCASE##Size( \ + repeated_##LOWERCASE##_value->Get(i)); \ + } \ + break + + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, SInt32, int32); + HANDLE_TYPE( SINT64, SInt64, int64); + HANDLE_TYPE( STRING, String, string); + HANDLE_TYPE( BYTES, Bytes, string); + HANDLE_TYPE( ENUM, Enum, enum); + HANDLE_TYPE( GROUP, Group, message); + HANDLE_TYPE( MESSAGE, Message, message); +#undef HANDLE_TYPE + + // Stuff with fixed size. +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \ + repeated_##LOWERCASE##_value->size(); \ + break + HANDLE_TYPE( FIXED32, Fixed32, uint32); + HANDLE_TYPE( FIXED64, Fixed64, uint64); + HANDLE_TYPE(SFIXED32, SFixed32, int32); + HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); +#undef HANDLE_TYPE + } + } + } else if (!is_cleared) { + result += WireFormatLite::TagSize(number, real_type(type)); + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \ + break + + HANDLE_TYPE( INT32, Int32, int32_value); + HANDLE_TYPE( INT64, Int64, int64_value); + HANDLE_TYPE( UINT32, UInt32, uint32_value); + HANDLE_TYPE( UINT64, UInt64, uint64_value); + HANDLE_TYPE( SINT32, SInt32, int32_value); + HANDLE_TYPE( SINT64, SInt64, int64_value); + HANDLE_TYPE( STRING, String, *string_value); + HANDLE_TYPE( BYTES, Bytes, *string_value); + HANDLE_TYPE( ENUM, Enum, enum_value); + HANDLE_TYPE( GROUP, Group, *message_value); +#undef HANDLE_TYPE + case WireFormatLite::TYPE_MESSAGE: { + if (is_lazy) { + int size = lazymessage_value->ByteSize(); + result += io::CodedOutputStream::VarintSize32(size) + size; + } else { + result += WireFormatLite::MessageSize(*message_value); + } + break; + } + + // Stuff with fixed size. +#define HANDLE_TYPE(UPPERCASE, CAMELCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::k##CAMELCASE##Size; \ + break + HANDLE_TYPE( FIXED32, Fixed32); + HANDLE_TYPE( FIXED64, Fixed64); + HANDLE_TYPE(SFIXED32, SFixed32); + HANDLE_TYPE(SFIXED64, SFixed64); + HANDLE_TYPE( FLOAT, Float); + HANDLE_TYPE( DOUBLE, Double); + HANDLE_TYPE( BOOL, Bool); +#undef HANDLE_TYPE + } + } + + return result; +} + +int ExtensionSet::Extension::GetSize() const { + GOOGLE_DCHECK(is_repeated); + switch (cpp_type(type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ + return repeated_##LOWERCASE##_value->size() + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE( UINT32, uint32); + HANDLE_TYPE( UINT64, uint64); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( DOUBLE, double); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, enum); + HANDLE_TYPE( STRING, string); + HANDLE_TYPE(MESSAGE, message); +#undef HANDLE_TYPE + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return 0; +} + +void ExtensionSet::Extension::Free() { + if (is_repeated) { + switch (cpp_type(type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ + delete repeated_##LOWERCASE##_value; \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE( UINT32, uint32); + HANDLE_TYPE( UINT64, uint64); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( DOUBLE, double); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, enum); + HANDLE_TYPE( STRING, string); + HANDLE_TYPE(MESSAGE, message); +#undef HANDLE_TYPE + } + } else { + switch (cpp_type(type)) { + case WireFormatLite::CPPTYPE_STRING: + delete string_value; + break; + case WireFormatLite::CPPTYPE_MESSAGE: + if (is_lazy) { + delete lazymessage_value; + } else { + delete message_value; + } + break; + default: + break; + } + } +} + +// Defined in extension_set_heavy.cc. +// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set.h new file mode 100644 index 0000000..df8f1f3 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set.h @@ -0,0 +1,1007 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__ +#define GOOGLE_PROTOBUF_EXTENSION_SET_H__ + +#include +#include +#include +#include + + +#include + +namespace google { + +namespace protobuf { + class Descriptor; // descriptor.h + class FieldDescriptor; // descriptor.h + class DescriptorPool; // descriptor.h + class MessageLite; // message_lite.h + class Message; // message.h + class MessageFactory; // message.h + class UnknownFieldSet; // unknown_field_set.h + namespace io { + class CodedInputStream; // coded_stream.h + class CodedOutputStream; // coded_stream.h + } + namespace internal { + class FieldSkipper; // wire_format_lite.h + class RepeatedPtrFieldBase; // repeated_field.h + } + template class RepeatedField; // repeated_field.h + template class RepeatedPtrField; // repeated_field.h +} + +namespace protobuf { +namespace internal { + +// Used to store values of type WireFormatLite::FieldType without having to +// #include wire_format_lite.h. Also, ensures that we use only one byte to +// store these values, which is important to keep the layout of +// ExtensionSet::Extension small. +typedef uint8 FieldType; + +// A function which, given an integer value, returns true if the number +// matches one of the defined values for the corresponding enum type. This +// is used with RegisterEnumExtension, below. +typedef bool EnumValidityFunc(int number); + +// Version of the above which takes an argument. This is needed to deal with +// extensions that are not compiled in. +typedef bool EnumValidityFuncWithArg(const void* arg, int number); + +// Information about a registered extension. +struct ExtensionInfo { + inline ExtensionInfo() {} + inline ExtensionInfo(FieldType type_param, bool isrepeated, bool ispacked) + : type(type_param), is_repeated(isrepeated), is_packed(ispacked), + descriptor(NULL) {} + + FieldType type; + bool is_repeated; + bool is_packed; + + struct EnumValidityCheck { + EnumValidityFuncWithArg* func; + const void* arg; + }; + + union { + EnumValidityCheck enum_validity_check; + const MessageLite* message_prototype; + }; + + // The descriptor for this extension, if one exists and is known. May be + // NULL. Must not be NULL if the descriptor for the extension does not + // live in the same pool as the descriptor for the containing type. + const FieldDescriptor* descriptor; +}; + +// Abstract interface for an object which looks up extension definitions. Used +// when parsing. +class LIBPROTOBUF_EXPORT ExtensionFinder { + public: + virtual ~ExtensionFinder(); + + // Find the extension with the given containing type and number. + virtual bool Find(int number, ExtensionInfo* output) = 0; +}; + +// Implementation of ExtensionFinder which finds extensions defined in .proto +// files which have been compiled into the binary. +class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder { + public: + GeneratedExtensionFinder(const MessageLite* containing_type) + : containing_type_(containing_type) {} + virtual ~GeneratedExtensionFinder() {} + + // Returns true and fills in *output if found, otherwise returns false. + virtual bool Find(int number, ExtensionInfo* output); + + private: + const MessageLite* containing_type_; +}; + +// Note: extension_set_heavy.cc defines DescriptorPoolExtensionFinder for +// finding extensions from a DescriptorPool. + +// This is an internal helper class intended for use within the protocol buffer +// library and generated classes. Clients should not use it directly. Instead, +// use the generated accessors such as GetExtension() of the class being +// extended. +// +// This class manages extensions for a protocol message object. The +// message's HasExtension(), GetExtension(), MutableExtension(), and +// ClearExtension() methods are just thin wrappers around the embedded +// ExtensionSet. When parsing, if a tag number is encountered which is +// inside one of the message type's extension ranges, the tag is passed +// off to the ExtensionSet for parsing. Etc. +class LIBPROTOBUF_EXPORT ExtensionSet { + public: + ExtensionSet(); + ~ExtensionSet(); + + // These are called at startup by protocol-compiler-generated code to + // register known extensions. The registrations are used by ParseField() + // to look up extensions for parsed field numbers. Note that dynamic parsing + // does not use ParseField(); only protocol-compiler-generated parsing + // methods do. + static void RegisterExtension(const MessageLite* containing_type, + int number, FieldType type, + bool is_repeated, bool is_packed); + static void RegisterEnumExtension(const MessageLite* containing_type, + int number, FieldType type, + bool is_repeated, bool is_packed, + EnumValidityFunc* is_valid); + static void RegisterMessageExtension(const MessageLite* containing_type, + int number, FieldType type, + bool is_repeated, bool is_packed, + const MessageLite* prototype); + + // ================================================================= + + // Add all fields which are currently present to the given vector. This + // is useful to implement Reflection::ListFields(). + void AppendToList(const Descriptor* containing_type, + const DescriptorPool* pool, + vector* output) const; + + // ================================================================= + // Accessors + // + // Generated message classes include type-safe templated wrappers around + // these methods. Generally you should use those rather than call these + // directly, unless you are doing low-level memory management. + // + // When calling any of these accessors, the extension number requested + // MUST exist in the DescriptorPool provided to the constructor. Otheriwse, + // the method will fail an assert. Normally, though, you would not call + // these directly; you would either call the generated accessors of your + // message class (e.g. GetExtension()) or you would call the accessors + // of the reflection interface. In both cases, it is impossible to + // trigger this assert failure: the generated accessors only accept + // linked-in extension types as parameters, while the Reflection interface + // requires you to provide the FieldDescriptor describing the extension. + // + // When calling any of these accessors, a protocol-compiler-generated + // implementation of the extension corresponding to the number MUST + // be linked in, and the FieldDescriptor used to refer to it MUST be + // the one generated by that linked-in code. Otherwise, the method will + // die on an assert failure. The message objects returned by the message + // accessors are guaranteed to be of the correct linked-in type. + // + // These methods pretty much match Reflection except that: + // - They're not virtual. + // - They identify fields by number rather than FieldDescriptors. + // - They identify enum values using integers rather than descriptors. + // - Strings provide Mutable() in addition to Set() accessors. + + bool Has(int number) const; + int ExtensionSize(int number) const; // Size of a repeated extension. + int NumExtensions() const; // The number of extensions + FieldType ExtensionType(int number) const; + void ClearExtension(int number); + + // singular fields ------------------------------------------------- + + int32 GetInt32 (int number, int32 default_value) const; + int64 GetInt64 (int number, int64 default_value) const; + uint32 GetUInt32(int number, uint32 default_value) const; + uint64 GetUInt64(int number, uint64 default_value) const; + float GetFloat (int number, float default_value) const; + double GetDouble(int number, double default_value) const; + bool GetBool (int number, bool default_value) const; + int GetEnum (int number, int default_value) const; + const string & GetString (int number, const string& default_value) const; + const MessageLite& GetMessage(int number, + const MessageLite& default_value) const; + const MessageLite& GetMessage(int number, const Descriptor* message_type, + MessageFactory* factory) const; + + // |descriptor| may be NULL so long as it is known that the descriptor for + // the extension lives in the same pool as the descriptor for the containing + // type. +#define desc const FieldDescriptor* descriptor // avoid line wrapping + void SetInt32 (int number, FieldType type, int32 value, desc); + void SetInt64 (int number, FieldType type, int64 value, desc); + void SetUInt32(int number, FieldType type, uint32 value, desc); + void SetUInt64(int number, FieldType type, uint64 value, desc); + void SetFloat (int number, FieldType type, float value, desc); + void SetDouble(int number, FieldType type, double value, desc); + void SetBool (int number, FieldType type, bool value, desc); + void SetEnum (int number, FieldType type, int value, desc); + void SetString(int number, FieldType type, const string& value, desc); + string * MutableString (int number, FieldType type, desc); + MessageLite* MutableMessage(int number, FieldType type, + const MessageLite& prototype, desc); + MessageLite* MutableMessage(const FieldDescriptor* decsriptor, + MessageFactory* factory); + // Adds the given message to the ExtensionSet, taking ownership of the + // message object. Existing message with the same number will be deleted. + // If "message" is NULL, this is equivalent to "ClearExtension(number)". + void SetAllocatedMessage(int number, FieldType type, + const FieldDescriptor* descriptor, + MessageLite* message); + MessageLite* ReleaseMessage(int number, const MessageLite& prototype); + MessageLite* ReleaseMessage(const FieldDescriptor* descriptor, + MessageFactory* factory); +#undef desc + + // repeated fields ------------------------------------------------- + + void* MutableRawRepeatedField(int number); + + int32 GetRepeatedInt32 (int number, int index) const; + int64 GetRepeatedInt64 (int number, int index) const; + uint32 GetRepeatedUInt32(int number, int index) const; + uint64 GetRepeatedUInt64(int number, int index) const; + float GetRepeatedFloat (int number, int index) const; + double GetRepeatedDouble(int number, int index) const; + bool GetRepeatedBool (int number, int index) const; + int GetRepeatedEnum (int number, int index) const; + const string & GetRepeatedString (int number, int index) const; + const MessageLite& GetRepeatedMessage(int number, int index) const; + + void SetRepeatedInt32 (int number, int index, int32 value); + void SetRepeatedInt64 (int number, int index, int64 value); + void SetRepeatedUInt32(int number, int index, uint32 value); + void SetRepeatedUInt64(int number, int index, uint64 value); + void SetRepeatedFloat (int number, int index, float value); + void SetRepeatedDouble(int number, int index, double value); + void SetRepeatedBool (int number, int index, bool value); + void SetRepeatedEnum (int number, int index, int value); + void SetRepeatedString(int number, int index, const string& value); + string * MutableRepeatedString (int number, int index); + MessageLite* MutableRepeatedMessage(int number, int index); + +#define desc const FieldDescriptor* descriptor // avoid line wrapping + void AddInt32 (int number, FieldType type, bool packed, int32 value, desc); + void AddInt64 (int number, FieldType type, bool packed, int64 value, desc); + void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc); + void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc); + void AddFloat (int number, FieldType type, bool packed, float value, desc); + void AddDouble(int number, FieldType type, bool packed, double value, desc); + void AddBool (int number, FieldType type, bool packed, bool value, desc); + void AddEnum (int number, FieldType type, bool packed, int value, desc); + void AddString(int number, FieldType type, const string& value, desc); + string * AddString (int number, FieldType type, desc); + MessageLite* AddMessage(int number, FieldType type, + const MessageLite& prototype, desc); + MessageLite* AddMessage(const FieldDescriptor* descriptor, + MessageFactory* factory); +#undef desc + + void RemoveLast(int number); + MessageLite* ReleaseLast(int number); + void SwapElements(int number, int index1, int index2); + + // ----------------------------------------------------------------- + // TODO(kenton): Hardcore memory management accessors + + // ================================================================= + // convenience methods for implementing methods of Message + // + // These could all be implemented in terms of the other methods of this + // class, but providing them here helps keep the generated code size down. + + void Clear(); + void MergeFrom(const ExtensionSet& other); + void Swap(ExtensionSet* other); + bool IsInitialized() const; + + // Parses a single extension from the input. The input should start out + // positioned immediately after the tag. + bool ParseField(uint32 tag, io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper); + + // Specific versions for lite or full messages (constructs the appropriate + // FieldSkipper automatically). |containing_type| is the default + // instance for the containing message; it is used only to look up the + // extension by number. See RegisterExtension(), above. Unlike the other + // methods of ExtensionSet, this only works for generated message types -- + // it looks up extensions registered using RegisterExtension(). + bool ParseField(uint32 tag, io::CodedInputStream* input, + const MessageLite* containing_type); + bool ParseField(uint32 tag, io::CodedInputStream* input, + const Message* containing_type, + UnknownFieldSet* unknown_fields); + + // Parse an entire message in MessageSet format. Such messages have no + // fields, only extensions. + bool ParseMessageSet(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper); + + // Specific versions for lite or full messages (constructs the appropriate + // FieldSkipper automatically). + bool ParseMessageSet(io::CodedInputStream* input, + const MessageLite* containing_type); + bool ParseMessageSet(io::CodedInputStream* input, + const Message* containing_type, + UnknownFieldSet* unknown_fields); + + // Write all extension fields with field numbers in the range + // [start_field_number, end_field_number) + // to the output stream, using the cached sizes computed when ByteSize() was + // last called. Note that the range bounds are inclusive-exclusive. + void SerializeWithCachedSizes(int start_field_number, + int end_field_number, + io::CodedOutputStream* output) const; + + // Same as SerializeWithCachedSizes, but without any bounds checking. + // The caller must ensure that target has sufficient capacity for the + // serialized extensions. + // + // Returns a pointer past the last written byte. + uint8* SerializeWithCachedSizesToArray(int start_field_number, + int end_field_number, + uint8* target) const; + + // Like above but serializes in MessageSet format. + void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const; + uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const; + + // Returns the total serialized size of all the extensions. + int ByteSize() const; + + // Like ByteSize() but uses MessageSet format. + int MessageSetByteSize() const; + + // Returns (an estimate of) the total number of bytes used for storing the + // extensions in memory, excluding sizeof(*this). If the ExtensionSet is + // for a lite message (and thus possibly contains lite messages), the results + // are undefined (might work, might crash, might corrupt data, might not even + // be linked in). It's up to the protocol compiler to avoid calling this on + // such ExtensionSets (easy enough since lite messages don't implement + // SpaceUsed()). + int SpaceUsedExcludingSelf() const; + + private: + + // Interface of a lazily parsed singular message extension. + class LIBPROTOBUF_EXPORT LazyMessageExtension { + public: + LazyMessageExtension() {} + virtual ~LazyMessageExtension() {} + + virtual LazyMessageExtension* New() const = 0; + virtual const MessageLite& GetMessage( + const MessageLite& prototype) const = 0; + virtual MessageLite* MutableMessage(const MessageLite& prototype) = 0; + virtual void SetAllocatedMessage(MessageLite *message) = 0; + virtual MessageLite* ReleaseMessage(const MessageLite& prototype) = 0; + + virtual bool IsInitialized() const = 0; + virtual int ByteSize() const = 0; + virtual int SpaceUsed() const = 0; + + virtual void MergeFrom(const LazyMessageExtension& other) = 0; + virtual void Clear() = 0; + + virtual bool ReadMessage(const MessageLite& prototype, + io::CodedInputStream* input) = 0; + virtual void WriteMessage(int number, + io::CodedOutputStream* output) const = 0; + virtual uint8* WriteMessageToArray(int number, uint8* target) const = 0; + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension); + }; + struct Extension { + // The order of these fields packs Extension into 24 bytes when using 8 + // byte alignment. Consider this when adding or removing fields here. + union { + int32 int32_value; + int64 int64_value; + uint32 uint32_value; + uint64 uint64_value; + float float_value; + double double_value; + bool bool_value; + int enum_value; + string* string_value; + MessageLite* message_value; + LazyMessageExtension* lazymessage_value; + + RepeatedField * repeated_int32_value; + RepeatedField * repeated_int64_value; + RepeatedField * repeated_uint32_value; + RepeatedField * repeated_uint64_value; + RepeatedField * repeated_float_value; + RepeatedField * repeated_double_value; + RepeatedField * repeated_bool_value; + RepeatedField * repeated_enum_value; + RepeatedPtrField* repeated_string_value; + RepeatedPtrField* repeated_message_value; + }; + + FieldType type; + bool is_repeated; + + // For singular types, indicates if the extension is "cleared". This + // happens when an extension is set and then later cleared by the caller. + // We want to keep the Extension object around for reuse, so instead of + // removing it from the map, we just set is_cleared = true. This has no + // meaning for repeated types; for those, the size of the RepeatedField + // simply becomes zero when cleared. + bool is_cleared : 4; + + // For singular message types, indicates whether lazy parsing is enabled + // for this extension. This field is only valid when type == TYPE_MESSAGE + // and !is_repeated because we only support lazy parsing for singular + // message types currently. If is_lazy = true, the extension is stored in + // lazymessage_value. Otherwise, the extension will be message_value. + bool is_lazy : 4; + + // For repeated types, this indicates if the [packed=true] option is set. + bool is_packed; + + // For packed fields, the size of the packed data is recorded here when + // ByteSize() is called then used during serialization. + // TODO(kenton): Use atomic when C++ supports it. + mutable int cached_size; + + // The descriptor for this extension, if one exists and is known. May be + // NULL. Must not be NULL if the descriptor for the extension does not + // live in the same pool as the descriptor for the containing type. + const FieldDescriptor* descriptor; + + // Some helper methods for operations on a single Extension. + void SerializeFieldWithCachedSizes( + int number, + io::CodedOutputStream* output) const; + uint8* SerializeFieldWithCachedSizesToArray( + int number, + uint8* target) const; + void SerializeMessageSetItemWithCachedSizes( + int number, + io::CodedOutputStream* output) const; + uint8* SerializeMessageSetItemWithCachedSizesToArray( + int number, + uint8* target) const; + int ByteSize(int number) const; + int MessageSetItemByteSize(int number) const; + void Clear(); + int GetSize() const; + void Free(); + int SpaceUsedExcludingSelf() const; + }; + + + // Returns true and fills field_number and extension if extension is found. + bool FindExtensionInfoFromTag(uint32 tag, ExtensionFinder* extension_finder, + int* field_number, ExtensionInfo* extension); + + // Parses a single extension from the input. The input should start out + // positioned immediately after the wire tag. This method is called in + // ParseField() after field number is extracted from the wire tag and + // ExtensionInfo is found by the field number. + bool ParseFieldWithExtensionInfo(int field_number, + const ExtensionInfo& extension, + io::CodedInputStream* input, + FieldSkipper* field_skipper); + + // Like ParseField(), but this method may parse singular message extensions + // lazily depending on the value of FLAGS_eagerly_parse_message_sets. + bool ParseFieldMaybeLazily(uint32 tag, io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper); + + // Gets the extension with the given number, creating it if it does not + // already exist. Returns true if the extension did not already exist. + bool MaybeNewExtension(int number, const FieldDescriptor* descriptor, + Extension** result); + + // Parse a single MessageSet item -- called just after the item group start + // tag has been read. + bool ParseMessageSetItem(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper); + + + // Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This + // friendship should automatically extend to ExtensionSet::Extension, but + // unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this + // correctly. So, we must provide helpers for calling methods of that + // class. + + // Defined in extension_set_heavy.cc. + static inline int RepeatedMessage_SpaceUsedExcludingSelf( + RepeatedPtrFieldBase* field); + + // The Extension struct is small enough to be passed by value, so we use it + // directly as the value type in the map rather than use pointers. We use + // a map rather than hash_map here because we expect most ExtensionSets will + // only contain a small number of extensions whereas hash_map is optimized + // for 100 elements or more. Also, we want AppendToList() to order fields + // by field number. + std::map extensions_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet); +}; + +// These are just for convenience... +inline void ExtensionSet::SetString(int number, FieldType type, + const string& value, + const FieldDescriptor* descriptor) { + MutableString(number, type, descriptor)->assign(value); +} +inline void ExtensionSet::SetRepeatedString(int number, int index, + const string& value) { + MutableRepeatedString(number, index)->assign(value); +} +inline void ExtensionSet::AddString(int number, FieldType type, + const string& value, + const FieldDescriptor* descriptor) { + AddString(number, type, descriptor)->assign(value); +} + +// =================================================================== +// Glue for generated extension accessors + +// ------------------------------------------------------------------- +// Template magic + +// First we have a set of classes representing "type traits" for different +// field types. A type traits class knows how to implement basic accessors +// for extensions of a particular type given an ExtensionSet. The signature +// for a type traits class looks like this: +// +// class TypeTraits { +// public: +// typedef ? ConstType; +// typedef ? MutableType; +// +// static inline ConstType Get(int number, const ExtensionSet& set); +// static inline void Set(int number, ConstType value, ExtensionSet* set); +// static inline MutableType Mutable(int number, ExtensionSet* set); +// +// // Variants for repeated fields. +// static inline ConstType Get(int number, const ExtensionSet& set, +// int index); +// static inline void Set(int number, int index, +// ConstType value, ExtensionSet* set); +// static inline MutableType Mutable(int number, int index, +// ExtensionSet* set); +// static inline void Add(int number, ConstType value, ExtensionSet* set); +// static inline MutableType Add(int number, ExtensionSet* set); +// }; +// +// Not all of these methods make sense for all field types. For example, the +// "Mutable" methods only make sense for strings and messages, and the +// repeated methods only make sense for repeated types. So, each type +// traits class implements only the set of methods from this signature that it +// actually supports. This will cause a compiler error if the user tries to +// access an extension using a method that doesn't make sense for its type. +// For example, if "foo" is an extension of type "optional int32", then if you +// try to write code like: +// my_message.MutableExtension(foo) +// you will get a compile error because PrimitiveTypeTraits does not +// have a "Mutable()" method. + +// ------------------------------------------------------------------- +// PrimitiveTypeTraits + +// Since the ExtensionSet has different methods for each primitive type, +// we must explicitly define the methods of the type traits class for each +// known type. +template +class PrimitiveTypeTraits { + public: + typedef Type ConstType; + + static inline ConstType Get(int number, const ExtensionSet& set, + ConstType default_value); + static inline void Set(int number, FieldType field_type, + ConstType value, ExtensionSet* set); +}; + +template +class RepeatedPrimitiveTypeTraits { + public: + typedef Type ConstType; + + static inline Type Get(int number, const ExtensionSet& set, int index); + static inline void Set(int number, int index, Type value, ExtensionSet* set); + static inline void Add(int number, FieldType field_type, + bool is_packed, Type value, ExtensionSet* set); +}; + +#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD) \ +template<> inline TYPE PrimitiveTypeTraits::Get( \ + int number, const ExtensionSet& set, TYPE default_value) { \ + return set.Get##METHOD(number, default_value); \ +} \ +template<> inline void PrimitiveTypeTraits::Set( \ + int number, FieldType field_type, TYPE value, ExtensionSet* set) { \ + set->Set##METHOD(number, field_type, value, NULL); \ +} \ + \ +template<> inline TYPE RepeatedPrimitiveTypeTraits::Get( \ + int number, const ExtensionSet& set, int index) { \ + return set.GetRepeated##METHOD(number, index); \ +} \ +template<> inline void RepeatedPrimitiveTypeTraits::Set( \ + int number, int index, TYPE value, ExtensionSet* set) { \ + set->SetRepeated##METHOD(number, index, value); \ +} \ +template<> inline void RepeatedPrimitiveTypeTraits::Add( \ + int number, FieldType field_type, bool is_packed, \ + TYPE value, ExtensionSet* set) { \ + set->Add##METHOD(number, field_type, is_packed, value, NULL); \ +} + +PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32, Int32) +PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64, Int64) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64) +PROTOBUF_DEFINE_PRIMITIVE_TYPE( float, Float) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double) +PROTOBUF_DEFINE_PRIMITIVE_TYPE( bool, Bool) + +#undef PROTOBUF_DEFINE_PRIMITIVE_TYPE + +// ------------------------------------------------------------------- +// StringTypeTraits + +// Strings support both Set() and Mutable(). +class LIBPROTOBUF_EXPORT StringTypeTraits { + public: + typedef const string& ConstType; + typedef string* MutableType; + + static inline const string& Get(int number, const ExtensionSet& set, + ConstType default_value) { + return set.GetString(number, default_value); + } + static inline void Set(int number, FieldType field_type, + const string& value, ExtensionSet* set) { + set->SetString(number, field_type, value, NULL); + } + static inline string* Mutable(int number, FieldType field_type, + ExtensionSet* set) { + return set->MutableString(number, field_type, NULL); + } +}; + +class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits { + public: + typedef const string& ConstType; + typedef string* MutableType; + + static inline const string& Get(int number, const ExtensionSet& set, + int index) { + return set.GetRepeatedString(number, index); + } + static inline void Set(int number, int index, + const string& value, ExtensionSet* set) { + set->SetRepeatedString(number, index, value); + } + static inline string* Mutable(int number, int index, ExtensionSet* set) { + return set->MutableRepeatedString(number, index); + } + static inline void Add(int number, FieldType field_type, + bool /*is_packed*/, const string& value, + ExtensionSet* set) { + set->AddString(number, field_type, value, NULL); + } + static inline string* Add(int number, FieldType field_type, + ExtensionSet* set) { + return set->AddString(number, field_type, NULL); + } +}; + +// ------------------------------------------------------------------- +// EnumTypeTraits + +// ExtensionSet represents enums using integers internally, so we have to +// static_cast around. +template +class EnumTypeTraits { + public: + typedef Type ConstType; + + static inline ConstType Get(int number, const ExtensionSet& set, + ConstType default_value) { + return static_cast(set.GetEnum(number, default_value)); + } + static inline void Set(int number, FieldType field_type, + ConstType value, ExtensionSet* set) { + GOOGLE_DCHECK(IsValid(value)); + set->SetEnum(number, field_type, value, NULL); + } +}; + +template +class RepeatedEnumTypeTraits { + public: + typedef Type ConstType; + + static inline ConstType Get(int number, const ExtensionSet& set, int index) { + return static_cast(set.GetRepeatedEnum(number, index)); + } + static inline void Set(int number, int index, + ConstType value, ExtensionSet* set) { + GOOGLE_DCHECK(IsValid(value)); + set->SetRepeatedEnum(number, index, value); + } + static inline void Add(int number, FieldType field_type, + bool is_packed, ConstType value, ExtensionSet* set) { + GOOGLE_DCHECK(IsValid(value)); + set->AddEnum(number, field_type, is_packed, value, NULL); + } +}; + +// ------------------------------------------------------------------- +// MessageTypeTraits + +// ExtensionSet guarantees that when manipulating extensions with message +// types, the implementation used will be the compiled-in class representing +// that type. So, we can static_cast down to the exact type we expect. +template +class MessageTypeTraits { + public: + typedef const Type& ConstType; + typedef Type* MutableType; + + static inline ConstType Get(int number, const ExtensionSet& set, + ConstType default_value) { + return static_cast( + set.GetMessage(number, default_value)); + } + static inline MutableType Mutable(int number, FieldType field_type, + ExtensionSet* set) { + return static_cast( + set->MutableMessage(number, field_type, Type::default_instance(), NULL)); + } + static inline void SetAllocated(int number, FieldType field_type, + MutableType message, ExtensionSet* set) { + set->SetAllocatedMessage(number, field_type, NULL, message); + } + static inline MutableType Release(int number, FieldType field_type, + ExtensionSet* set) { + return static_cast(set->ReleaseMessage( + number, Type::default_instance())); + } +}; + +template +class RepeatedMessageTypeTraits { + public: + typedef const Type& ConstType; + typedef Type* MutableType; + + static inline ConstType Get(int number, const ExtensionSet& set, int index) { + return static_cast(set.GetRepeatedMessage(number, index)); + } + static inline MutableType Mutable(int number, int index, ExtensionSet* set) { + return static_cast(set->MutableRepeatedMessage(number, index)); + } + static inline MutableType Add(int number, FieldType field_type, + ExtensionSet* set) { + return static_cast( + set->AddMessage(number, field_type, Type::default_instance(), NULL)); + } +}; + +// ------------------------------------------------------------------- +// ExtensionIdentifier + +// This is the type of actual extension objects. E.g. if you have: +// extends Foo with optional int32 bar = 1234; +// then "bar" will be defined in C++ as: +// ExtensionIdentifier, 1, false> bar(1234); +// +// Note that we could, in theory, supply the field number as a template +// parameter, and thus make an instance of ExtensionIdentifier have no +// actual contents. However, if we did that, then using at extension +// identifier would not necessarily cause the compiler to output any sort +// of reference to any simple defined in the extension's .pb.o file. Some +// linkers will actually drop object files that are not explicitly referenced, +// but that would be bad because it would cause this extension to not be +// registered at static initialization, and therefore using it would crash. + +template +class ExtensionIdentifier { + public: + typedef TypeTraitsType TypeTraits; + typedef ExtendeeType Extendee; + + ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value) + : number_(number), default_value_(default_value) {} + inline int number() const { return number_; } + typename TypeTraits::ConstType default_value() const { + return default_value_; + } + + private: + const int number_; + typename TypeTraits::ConstType default_value_; +}; + +// ------------------------------------------------------------------- +// Generated accessors + +// This macro should be expanded in the context of a generated type which +// has extensions. +// +// We use "_proto_TypeTraits" as a type name below because "TypeTraits" +// causes problems if the class has a nested message or enum type with that +// name and "_TypeTraits" is technically reserved for the C++ library since +// it starts with an underscore followed by a capital letter. +// +// For similar reason, we use "_field_type" and "_is_packed" as parameter names +// below, so that "field_type" and "is_packed" can be used as field names. +#define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME) \ + /* Has, Size, Clear */ \ + template \ + inline bool HasExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \ + return _extensions_.Has(id.number()); \ + } \ + \ + template \ + inline void ClearExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ + _extensions_.ClearExtension(id.number()); \ + } \ + \ + template \ + inline int ExtensionSize( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \ + return _extensions_.ExtensionSize(id.number()); \ + } \ + \ + /* Singular accessors */ \ + template \ + inline typename _proto_TypeTraits::ConstType GetExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \ + return _proto_TypeTraits::Get(id.number(), _extensions_, \ + id.default_value()); \ + } \ + \ + template \ + inline typename _proto_TypeTraits::MutableType MutableExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ + return _proto_TypeTraits::Mutable(id.number(), _field_type, \ + &_extensions_); \ + } \ + \ + template \ + inline void SetExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + typename _proto_TypeTraits::ConstType value) { \ + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); \ + } \ + \ + template \ + inline void SetAllocatedExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + typename _proto_TypeTraits::MutableType value) { \ + _proto_TypeTraits::SetAllocated(id.number(), _field_type, \ + value, &_extensions_); \ + } \ + template \ + inline typename _proto_TypeTraits::MutableType ReleaseExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ + return _proto_TypeTraits::Release(id.number(), _field_type, \ + &_extensions_); \ + } \ + \ + /* Repeated accessors */ \ + template \ + inline typename _proto_TypeTraits::ConstType GetExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + int index) const { \ + return _proto_TypeTraits::Get(id.number(), _extensions_, index); \ + } \ + \ + template \ + inline typename _proto_TypeTraits::MutableType MutableExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + int index) { \ + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); \ + } \ + \ + template \ + inline void SetExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + int index, typename _proto_TypeTraits::ConstType value) { \ + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); \ + } \ + \ + template \ + inline typename _proto_TypeTraits::MutableType AddExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ + return _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); \ + } \ + \ + template \ + inline void AddExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + typename _proto_TypeTraits::ConstType value) { \ + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, \ + value, &_extensions_); \ + } + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_EXTENSION_SET_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set_heavy.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set_heavy.cc new file mode 100644 index 0000000..483d705 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set_heavy.cc @@ -0,0 +1,711 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Contains methods defined in extension_set.h which cannot be part of the +// lite library because they use descriptors or reflection. + +#include +#include +#include +#include +#include +#include +#include + +namespace google { + +namespace protobuf { +namespace internal { + + +// Implementation of ExtensionFinder which finds extensions in a given +// DescriptorPool, using the given MessageFactory to construct sub-objects. +// This class is implemented in extension_set_heavy.cc. +class DescriptorPoolExtensionFinder : public ExtensionFinder { + public: + DescriptorPoolExtensionFinder(const DescriptorPool* pool, + MessageFactory* factory, + const Descriptor* containing_type) + : pool_(pool), factory_(factory), containing_type_(containing_type) {} + virtual ~DescriptorPoolExtensionFinder() {} + + virtual bool Find(int number, ExtensionInfo* output); + + private: + const DescriptorPool* pool_; + MessageFactory* factory_; + const Descriptor* containing_type_; +}; + +void ExtensionSet::AppendToList(const Descriptor* containing_type, + const DescriptorPool* pool, + vector* output) const { + for (map::const_iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + bool has = false; + if (iter->second.is_repeated) { + has = iter->second.GetSize() > 0; + } else { + has = !iter->second.is_cleared; + } + + if (has) { + // TODO(kenton): Looking up each field by number is somewhat unfortunate. + // Is there a better way? The problem is that descriptors are lazily- + // initialized, so they might not even be constructed until + // AppendToList() is called. + + if (iter->second.descriptor == NULL) { + output->push_back(pool->FindExtensionByNumber( + containing_type, iter->first)); + } else { + output->push_back(iter->second.descriptor); + } + } + } +} + +inline FieldDescriptor::Type real_type(FieldType type) { + GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE); + return static_cast(type); +} + +inline FieldDescriptor::CppType cpp_type(FieldType type) { + return FieldDescriptor::TypeToCppType( + static_cast(type)); +} + +inline WireFormatLite::FieldType field_type(FieldType type) { + GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE); + return static_cast(type); +} + +#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ + GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \ + : FieldDescriptor::LABEL_OPTIONAL, \ + FieldDescriptor::LABEL_##LABEL); \ + GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE) + +const MessageLite& ExtensionSet::GetMessage(int number, + const Descriptor* message_type, + MessageFactory* factory) const { + map::const_iterator iter = extensions_.find(number); + if (iter == extensions_.end() || iter->second.is_cleared) { + // Not present. Return the default value. + return *factory->GetPrototype(message_type); + } else { + GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); + if (iter->second.is_lazy) { + return iter->second.lazymessage_value->GetMessage( + *factory->GetPrototype(message_type)); + } else { + return *iter->second.message_value; + } + } +} + +MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor, + MessageFactory* factory) { + Extension* extension; + if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) { + extension->type = descriptor->type(); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); + extension->is_repeated = false; + extension->is_packed = false; + const MessageLite* prototype = + factory->GetPrototype(descriptor->message_type()); + extension->is_lazy = false; + extension->message_value = prototype->New(); + extension->is_cleared = false; + return extension->message_value; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); + extension->is_cleared = false; + if (extension->is_lazy) { + return extension->lazymessage_value->MutableMessage( + *factory->GetPrototype(descriptor->message_type())); + } else { + return extension->message_value; + } + } +} + +MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor, + MessageFactory* factory) { + map::iterator iter = extensions_.find(descriptor->number()); + if (iter == extensions_.end()) { + // Not present. Return NULL. + return NULL; + } else { + GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); + MessageLite* ret = NULL; + if (iter->second.is_lazy) { + ret = iter->second.lazymessage_value->ReleaseMessage( + *factory->GetPrototype(descriptor->message_type())); + delete iter->second.lazymessage_value; + } else { + ret = iter->second.message_value; + } + extensions_.erase(descriptor->number()); + return ret; + } +} + +MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor, + MessageFactory* factory) { + Extension* extension; + if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) { + extension->type = descriptor->type(); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); + extension->is_repeated = true; + extension->repeated_message_value = + new RepeatedPtrField(); + } else { + GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); + } + + // RepeatedPtrField does not know how to Add() since it cannot + // allocate an abstract object, so we have to be tricky. + MessageLite* result = extension->repeated_message_value + ->AddFromCleared >(); + if (result == NULL) { + const MessageLite* prototype; + if (extension->repeated_message_value->size() == 0) { + prototype = factory->GetPrototype(descriptor->message_type()); + GOOGLE_CHECK(prototype != NULL); + } else { + prototype = &extension->repeated_message_value->Get(0); + } + result = prototype->New(); + extension->repeated_message_value->AddAllocated(result); + } + return result; +} + +static bool ValidateEnumUsingDescriptor(const void* arg, int number) { + return reinterpret_cast(arg) + ->FindValueByNumber(number) != NULL; +} + +bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) { + const FieldDescriptor* extension = + pool_->FindExtensionByNumber(containing_type_, number); + if (extension == NULL) { + return false; + } else { + output->type = extension->type(); + output->is_repeated = extension->is_repeated(); + output->is_packed = extension->options().packed(); + output->descriptor = extension; + if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + output->message_prototype = + factory_->GetPrototype(extension->message_type()); + GOOGLE_CHECK(output->message_prototype != NULL) + << "Extension factory's GetPrototype() returned NULL for extension: " + << extension->full_name(); + } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + output->enum_validity_check.func = ValidateEnumUsingDescriptor; + output->enum_validity_check.arg = extension->enum_type(); + } + + return true; + } +} + +bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, + const Message* containing_type, + UnknownFieldSet* unknown_fields) { + UnknownFieldSetFieldSkipper skipper(unknown_fields); + if (input->GetExtensionPool() == NULL) { + GeneratedExtensionFinder finder(containing_type); + return ParseField(tag, input, &finder, &skipper); + } else { + DescriptorPoolExtensionFinder finder(input->GetExtensionPool(), + input->GetExtensionFactory(), + containing_type->GetDescriptor()); + return ParseField(tag, input, &finder, &skipper); + } +} + +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, + const Message* containing_type, + UnknownFieldSet* unknown_fields) { + UnknownFieldSetFieldSkipper skipper(unknown_fields); + if (input->GetExtensionPool() == NULL) { + GeneratedExtensionFinder finder(containing_type); + return ParseMessageSet(input, &finder, &skipper); + } else { + DescriptorPoolExtensionFinder finder(input->GetExtensionPool(), + input->GetExtensionFactory(), + containing_type->GetDescriptor()); + return ParseMessageSet(input, &finder, &skipper); + } +} + +int ExtensionSet::SpaceUsedExcludingSelf() const { + int total_size = + extensions_.size() * sizeof(map::value_type); + for (map::const_iterator iter = extensions_.begin(), + end = extensions_.end(); + iter != end; + ++iter) { + total_size += iter->second.SpaceUsedExcludingSelf(); + } + return total_size; +} + +inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf( + RepeatedPtrFieldBase* field) { + return field->SpaceUsedExcludingSelf >(); +} + +int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { + int total_size = 0; + if (is_repeated) { + switch (cpp_type(type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + total_size += sizeof(*repeated_##LOWERCASE##_value) + \ + repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE( UINT32, uint32); + HANDLE_TYPE( UINT64, uint64); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( DOUBLE, double); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, enum); + HANDLE_TYPE( STRING, string); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_MESSAGE: + // repeated_message_value is actually a RepeatedPtrField, + // but MessageLite has no SpaceUsed(), so we must directly call + // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type + // handler. + total_size += sizeof(*repeated_message_value) + + RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value); + break; + } + } else { + switch (cpp_type(type)) { + case FieldDescriptor::CPPTYPE_STRING: + total_size += sizeof(*string_value) + + StringSpaceUsedExcludingSelf(*string_value); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + if (is_lazy) { + total_size += lazymessage_value->SpaceUsed(); + } else { + total_size += down_cast(message_value)->SpaceUsed(); + } + break; + default: + // No extra storage costs for primitive types. + break; + } + } + return total_size; +} + +// The Serialize*ToArray methods are only needed in the heavy library, as +// the lite library only generates SerializeWithCachedSizes. +uint8* ExtensionSet::SerializeWithCachedSizesToArray( + int start_field_number, int end_field_number, + uint8* target) const { + map::const_iterator iter; + for (iter = extensions_.lower_bound(start_field_number); + iter != extensions_.end() && iter->first < end_field_number; + ++iter) { + target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first, + target); + } + return target; +} + +uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray( + uint8* target) const { + map::const_iterator iter; + for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) { + target = iter->second.SerializeMessageSetItemWithCachedSizesToArray( + iter->first, target); + } + return target; +} + +uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray( + int number, uint8* target) const { + if (is_repeated) { + if (is_packed) { + if (cached_size == 0) return target; + + target = WireFormatLite::WriteTagToArray(number, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target); + target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target); + + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case FieldDescriptor::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + target = WireFormatLite::Write##CAMELCASE##NoTagToArray( \ + repeated_##LOWERCASE##_value->Get(i), target); \ + } \ + break + + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, SInt32, int32); + HANDLE_TYPE( SINT64, SInt64, int64); + HANDLE_TYPE( FIXED32, Fixed32, uint32); + HANDLE_TYPE( FIXED64, Fixed64, uint64); + HANDLE_TYPE(SFIXED32, SFixed32, int32); + HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); + HANDLE_TYPE( ENUM, Enum, enum); +#undef HANDLE_TYPE + + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; + break; + } + } else { + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case FieldDescriptor::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + target = WireFormatLite::Write##CAMELCASE##ToArray(number, \ + repeated_##LOWERCASE##_value->Get(i), target); \ + } \ + break + + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, SInt32, int32); + HANDLE_TYPE( SINT64, SInt64, int64); + HANDLE_TYPE( FIXED32, Fixed32, uint32); + HANDLE_TYPE( FIXED64, Fixed64, uint64); + HANDLE_TYPE(SFIXED32, SFixed32, int32); + HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); + HANDLE_TYPE( STRING, String, string); + HANDLE_TYPE( BYTES, Bytes, string); + HANDLE_TYPE( ENUM, Enum, enum); + HANDLE_TYPE( GROUP, Group, message); + HANDLE_TYPE( MESSAGE, Message, message); +#undef HANDLE_TYPE + } + } + } else if (!is_cleared) { + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \ + case FieldDescriptor::TYPE_##UPPERCASE: \ + target = WireFormatLite::Write##CAMELCASE##ToArray( \ + number, VALUE, target); \ + break + + HANDLE_TYPE( INT32, Int32, int32_value); + HANDLE_TYPE( INT64, Int64, int64_value); + HANDLE_TYPE( UINT32, UInt32, uint32_value); + HANDLE_TYPE( UINT64, UInt64, uint64_value); + HANDLE_TYPE( SINT32, SInt32, int32_value); + HANDLE_TYPE( SINT64, SInt64, int64_value); + HANDLE_TYPE( FIXED32, Fixed32, uint32_value); + HANDLE_TYPE( FIXED64, Fixed64, uint64_value); + HANDLE_TYPE(SFIXED32, SFixed32, int32_value); + HANDLE_TYPE(SFIXED64, SFixed64, int64_value); + HANDLE_TYPE( FLOAT, Float, float_value); + HANDLE_TYPE( DOUBLE, Double, double_value); + HANDLE_TYPE( BOOL, Bool, bool_value); + HANDLE_TYPE( STRING, String, *string_value); + HANDLE_TYPE( BYTES, Bytes, *string_value); + HANDLE_TYPE( ENUM, Enum, enum_value); + HANDLE_TYPE( GROUP, Group, *message_value); +#undef HANDLE_TYPE + case FieldDescriptor::TYPE_MESSAGE: + if (is_lazy) { + target = lazymessage_value->WriteMessageToArray(number, target); + } else { + target = WireFormatLite::WriteMessageToArray( + number, *message_value, target); + } + break; + } + } + return target; +} + +uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray( + int number, + uint8* target) const { + if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { + // Not a valid MessageSet extension, but serialize it the normal way. + GOOGLE_LOG(WARNING) << "Invalid message set extension."; + return SerializeFieldWithCachedSizesToArray(number, target); + } + + if (is_cleared) return target; + + // Start group. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemStartTag, target); + // Write type ID. + target = WireFormatLite::WriteUInt32ToArray( + WireFormatLite::kMessageSetTypeIdNumber, number, target); + // Write message. + if (is_lazy) { + target = lazymessage_value->WriteMessageToArray( + WireFormatLite::kMessageSetMessageNumber, target); + } else { + target = WireFormatLite::WriteMessageToArray( + WireFormatLite::kMessageSetMessageNumber, *message_value, target); + } + // End group. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemEndTag, target); + return target; +} + + +bool ExtensionSet::ParseFieldMaybeLazily( + uint32 tag, io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper) { + return ParseField(tag, input, extension_finder, field_skipper); +} + +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper) { + while (true) { + uint32 tag = input->ReadTag(); + switch (tag) { + case 0: + return true; + case WireFormatLite::kMessageSetItemStartTag: + if (!ParseMessageSetItem(input, extension_finder, field_skipper)) { + return false; + } + break; + default: + if (!ParseField(tag, input, extension_finder, field_skipper)) { + return false; + } + break; + } + } +} + +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, + const MessageLite* containing_type) { + FieldSkipper skipper; + GeneratedExtensionFinder finder(containing_type); + return ParseMessageSet(input, &finder, &skipper); +} + +bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper) { + // TODO(kenton): It would be nice to share code between this and + // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the + // differences would be hard to factor out. + + // This method parses a group which should contain two fields: + // required int32 type_id = 2; + // required data message = 3; + + // Once we see a type_id, we'll construct a fake tag for this extension + // which is the tag it would have had under the proto2 extensions wire + // format. + uint32 fake_tag = 0; + + // If we see message data before the type_id, we'll append it to this so + // we can parse it later. + string message_data; + + while (true) { + uint32 tag = input->ReadTag(); + if (tag == 0) return false; + + switch (tag) { + case WireFormatLite::kMessageSetTypeIdTag: { + uint32 type_id; + if (!input->ReadVarint32(&type_id)) return false; + fake_tag = WireFormatLite::MakeTag(type_id, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + + if (!message_data.empty()) { + // We saw some message data before the type_id. Have to parse it + // now. + io::CodedInputStream sub_input( + reinterpret_cast(message_data.data()), + message_data.size()); + if (!ParseFieldMaybeLazily(fake_tag, &sub_input, + extension_finder, field_skipper)) { + return false; + } + message_data.clear(); + } + + break; + } + + case WireFormatLite::kMessageSetMessageTag: { + if (fake_tag == 0) { + // We haven't seen a type_id yet. Append this data to message_data. + string temp; + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->ReadString(&temp, length)) return false; + io::StringOutputStream output_stream(&message_data); + io::CodedOutputStream coded_output(&output_stream); + coded_output.WriteVarint32(length); + coded_output.WriteString(temp); + } else { + // Already saw type_id, so we can parse this directly. + if (!ParseFieldMaybeLazily(fake_tag, input, + extension_finder, field_skipper)) { + return false; + } + } + + break; + } + + case WireFormatLite::kMessageSetItemEndTag: { + return true; + } + + default: { + if (!field_skipper->SkipField(input, tag)) return false; + } + } + } +} + +void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes( + int number, + io::CodedOutputStream* output) const { + if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { + // Not a valid MessageSet extension, but serialize it the normal way. + SerializeFieldWithCachedSizes(number, output); + return; + } + + if (is_cleared) return; + + // Start group. + output->WriteTag(WireFormatLite::kMessageSetItemStartTag); + + // Write type ID. + WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber, + number, + output); + // Write message. + if (is_lazy) { + lazymessage_value->WriteMessage( + WireFormatLite::kMessageSetMessageNumber, output); + } else { + WireFormatLite::WriteMessageMaybeToArray( + WireFormatLite::kMessageSetMessageNumber, + *message_value, + output); + } + + // End group. + output->WriteTag(WireFormatLite::kMessageSetItemEndTag); +} + +int ExtensionSet::Extension::MessageSetItemByteSize(int number) const { + if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { + // Not a valid MessageSet extension, but compute the byte size for it the + // normal way. + return ByteSize(number); + } + + if (is_cleared) return 0; + + int our_size = WireFormatLite::kMessageSetItemTagsSize; + + // type_id + our_size += io::CodedOutputStream::VarintSize32(number); + + // message + int message_size = 0; + if (is_lazy) { + message_size = lazymessage_value->ByteSize(); + } else { + message_size = message_value->ByteSize(); + } + + our_size += io::CodedOutputStream::VarintSize32(message_size); + our_size += message_size; + + return our_size; +} + +void ExtensionSet::SerializeMessageSetWithCachedSizes( + io::CodedOutputStream* output) const { + map::const_iterator iter; + for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) { + iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output); + } +} + +int ExtensionSet::MessageSetByteSize() const { + int total_size = 0; + + for (map::const_iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + total_size += iter->second.MessageSetItemByteSize(iter->first); + } + + return total_size; +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set_unittest.cc new file mode 100644 index 0000000..559de6e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/extension_set_unittest.cc @@ -0,0 +1,726 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace google { + +namespace protobuf { +namespace internal { +namespace { + +// This test closely mirrors google/protobuf/compiler/cpp/unittest.cc +// except that it uses extensions rather than regular fields. + +TEST(ExtensionSetTest, Defaults) { + // Check that all default values are set correctly in the initial message. + unittest::TestAllExtensions message; + + TestUtil::ExpectExtensionsClear(message); + + // Messages should return pointers to default instances until first use. + // (This is not checked by ExpectClear() since it is not actually true after + // the fields have been set and then cleared.) + EXPECT_EQ(&unittest::OptionalGroup_extension::default_instance(), + &message.GetExtension(unittest::optionalgroup_extension)); + EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), + &message.GetExtension(unittest::optional_nested_message_extension)); + EXPECT_EQ(&unittest::ForeignMessage::default_instance(), + &message.GetExtension( + unittest::optional_foreign_message_extension)); + EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), + &message.GetExtension(unittest::optional_import_message_extension)); +} + +TEST(ExtensionSetTest, Accessors) { + // Set every field to a unique value then go back and check all those + // values. + unittest::TestAllExtensions message; + + TestUtil::SetAllExtensions(&message); + TestUtil::ExpectAllExtensionsSet(message); + + TestUtil::ModifyRepeatedExtensions(&message); + TestUtil::ExpectRepeatedExtensionsModified(message); +} + +TEST(ExtensionSetTest, Clear) { + // Set every field to a unique value, clear the message, then check that + // it is cleared. + unittest::TestAllExtensions message; + + TestUtil::SetAllExtensions(&message); + message.Clear(); + TestUtil::ExpectExtensionsClear(message); + + // Unlike with the defaults test, we do NOT expect that requesting embedded + // messages will return a pointer to the default instance. Instead, they + // should return the objects that were created when mutable_blah() was + // called. + EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(), + &message.GetExtension(unittest::optionalgroup_extension)); + EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), + &message.GetExtension(unittest::optional_nested_message_extension)); + EXPECT_NE(&unittest::ForeignMessage::default_instance(), + &message.GetExtension( + unittest::optional_foreign_message_extension)); + EXPECT_NE(&unittest_import::ImportMessage::default_instance(), + &message.GetExtension(unittest::optional_import_message_extension)); + + // Make sure setting stuff again after clearing works. (This takes slightly + // different code paths since the objects are reused.) + TestUtil::SetAllExtensions(&message); + TestUtil::ExpectAllExtensionsSet(message); +} + +TEST(ExtensionSetTest, ClearOneField) { + // Set every field to a unique value, then clear one value and insure that + // only that one value is cleared. + unittest::TestAllExtensions message; + + TestUtil::SetAllExtensions(&message); + int64 original_value = + message.GetExtension(unittest::optional_int64_extension); + + // Clear the field and make sure it shows up as cleared. + message.ClearExtension(unittest::optional_int64_extension); + EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension)); + EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension)); + + // Other adjacent fields should not be cleared. + EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension)); + EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension)); + + // Make sure if we set it again, then all fields are set. + message.SetExtension(unittest::optional_int64_extension, original_value); + TestUtil::ExpectAllExtensionsSet(message); +} + +TEST(ExtensionSetTest, SetAllocatedExtensin) { + unittest::TestAllExtensions message; + EXPECT_FALSE(message.HasExtension( + unittest::optional_foreign_message_extension)); + // Add a extension using SetAllocatedExtension + unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage(); + message.SetAllocatedExtension(unittest::optional_foreign_message_extension, + foreign_message); + EXPECT_TRUE(message.HasExtension( + unittest::optional_foreign_message_extension)); + EXPECT_EQ(foreign_message, + message.MutableExtension( + unittest::optional_foreign_message_extension)); + EXPECT_EQ(foreign_message, + &message.GetExtension( + unittest::optional_foreign_message_extension)); + + // SetAllocatedExtension should delete the previously existing extension. + // (We reply on unittest to check memory leaks for this case) + message.SetAllocatedExtension(unittest::optional_foreign_message_extension, + new unittest::ForeignMessage()); + + // SetAllocatedExtension with a NULL parameter is equivalent to ClearExtenion. + message.SetAllocatedExtension(unittest::optional_foreign_message_extension, + NULL); + EXPECT_FALSE(message.HasExtension( + unittest::optional_foreign_message_extension)); +} + +TEST(ExtensionSetTest, ReleaseExtension) { + unittest::TestMessageSet message; + EXPECT_FALSE(message.HasExtension( + unittest::TestMessageSetExtension1::message_set_extension)); + // Add a extension using SetAllocatedExtension + unittest::TestMessageSetExtension1* extension = + new unittest::TestMessageSetExtension1(); + message.SetAllocatedExtension( + unittest::TestMessageSetExtension1::message_set_extension, + extension); + EXPECT_TRUE(message.HasExtension( + unittest::TestMessageSetExtension1::message_set_extension)); + // Release the extension using ReleaseExtension + unittest::TestMessageSetExtension1* released_extension = + message.ReleaseExtension( + unittest::TestMessageSetExtension1::message_set_extension); + EXPECT_EQ(extension, released_extension); + EXPECT_FALSE(message.HasExtension( + unittest::TestMessageSetExtension1::message_set_extension)); + // ReleaseExtension will return the underlying object even after + // ClearExtension is called. + message.SetAllocatedExtension( + unittest::TestMessageSetExtension1::message_set_extension, + extension); + message.ClearExtension( + unittest::TestMessageSetExtension1::message_set_extension); + released_extension = message.ReleaseExtension( + unittest::TestMessageSetExtension1::message_set_extension); + EXPECT_TRUE(released_extension != NULL); + delete released_extension; +} + + +TEST(ExtensionSetTest, CopyFrom) { + unittest::TestAllExtensions message1, message2; + + TestUtil::SetAllExtensions(&message1); + message2.CopyFrom(message1); + TestUtil::ExpectAllExtensionsSet(message2); + message2.CopyFrom(message1); // exercise copy when fields already exist + TestUtil::ExpectAllExtensionsSet(message2); +} + +TEST(ExtensioSetTest, CopyFromPacked) { + unittest::TestPackedExtensions message1, message2; + + TestUtil::SetPackedExtensions(&message1); + message2.CopyFrom(message1); + TestUtil::ExpectPackedExtensionsSet(message2); + message2.CopyFrom(message1); // exercise copy when fields already exist + TestUtil::ExpectPackedExtensionsSet(message2); +} + +TEST(ExtensionSetTest, CopyFromUpcasted) { + unittest::TestAllExtensions message1, message2; + const Message& upcasted_message = message1; + + TestUtil::SetAllExtensions(&message1); + message2.CopyFrom(upcasted_message); + TestUtil::ExpectAllExtensionsSet(message2); + // exercise copy when fields already exist + message2.CopyFrom(upcasted_message); + TestUtil::ExpectAllExtensionsSet(message2); +} + +TEST(ExtensionSetTest, SwapWithEmpty) { + unittest::TestAllExtensions message1, message2; + TestUtil::SetAllExtensions(&message1); + + TestUtil::ExpectAllExtensionsSet(message1); + TestUtil::ExpectExtensionsClear(message2); + message1.Swap(&message2); + TestUtil::ExpectAllExtensionsSet(message2); + TestUtil::ExpectExtensionsClear(message1); +} + +TEST(ExtensionSetTest, SwapWithSelf) { + unittest::TestAllExtensions message; + TestUtil::SetAllExtensions(&message); + + TestUtil::ExpectAllExtensionsSet(message); + message.Swap(&message); + TestUtil::ExpectAllExtensionsSet(message); +} + +TEST(ExtensionSetTest, SerializationToArray) { + // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire + // compatibility of extensions. + // + // This checks serialization to a flat array by explicitly reserving space in + // the string and calling the generated message's + // SerializeWithCachedSizesToArray. + unittest::TestAllExtensions source; + unittest::TestAllTypes destination; + TestUtil::SetAllExtensions(&source); + int size = source.ByteSize(); + string data; + data.resize(size); + uint8* target = reinterpret_cast(string_as_array(&data)); + uint8* end = source.SerializeWithCachedSizesToArray(target); + EXPECT_EQ(size, end - target); + EXPECT_TRUE(destination.ParseFromString(data)); + TestUtil::ExpectAllFieldsSet(destination); +} + +TEST(ExtensionSetTest, SerializationToStream) { + // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire + // compatibility of extensions. + // + // This checks serialization to an output stream by creating an array output + // stream that can only buffer 1 byte at a time - this prevents the message + // from ever jumping to the fast path, ensuring that serialization happens via + // the CodedOutputStream. + unittest::TestAllExtensions source; + unittest::TestAllTypes destination; + TestUtil::SetAllExtensions(&source); + int size = source.ByteSize(); + string data; + data.resize(size); + { + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + source.SerializeWithCachedSizes(&output_stream); + ASSERT_FALSE(output_stream.HadError()); + } + EXPECT_TRUE(destination.ParseFromString(data)); + TestUtil::ExpectAllFieldsSet(destination); +} + +TEST(ExtensionSetTest, PackedSerializationToArray) { + // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure + // wire compatibility of extensions. + // + // This checks serialization to a flat array by explicitly reserving space in + // the string and calling the generated message's + // SerializeWithCachedSizesToArray. + unittest::TestPackedExtensions source; + unittest::TestPackedTypes destination; + TestUtil::SetPackedExtensions(&source); + int size = source.ByteSize(); + string data; + data.resize(size); + uint8* target = reinterpret_cast(string_as_array(&data)); + uint8* end = source.SerializeWithCachedSizesToArray(target); + EXPECT_EQ(size, end - target); + EXPECT_TRUE(destination.ParseFromString(data)); + TestUtil::ExpectPackedFieldsSet(destination); +} + +TEST(ExtensionSetTest, PackedSerializationToStream) { + // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure + // wire compatibility of extensions. + // + // This checks serialization to an output stream by creating an array output + // stream that can only buffer 1 byte at a time - this prevents the message + // from ever jumping to the fast path, ensuring that serialization happens via + // the CodedOutputStream. + unittest::TestPackedExtensions source; + unittest::TestPackedTypes destination; + TestUtil::SetPackedExtensions(&source); + int size = source.ByteSize(); + string data; + data.resize(size); + { + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + source.SerializeWithCachedSizes(&output_stream); + ASSERT_FALSE(output_stream.HadError()); + } + EXPECT_TRUE(destination.ParseFromString(data)); + TestUtil::ExpectPackedFieldsSet(destination); +} + +TEST(ExtensionSetTest, Parsing) { + // Serialize as TestAllTypes and parse as TestAllExtensions. + unittest::TestAllTypes source; + unittest::TestAllExtensions destination; + string data; + + TestUtil::SetAllFields(&source); + source.SerializeToString(&data); + EXPECT_TRUE(destination.ParseFromString(data)); + TestUtil::ExpectAllExtensionsSet(destination); +} + +TEST(ExtensionSetTest, PackedParsing) { + // Serialize as TestPackedTypes and parse as TestPackedExtensions. + unittest::TestPackedTypes source; + unittest::TestPackedExtensions destination; + string data; + + TestUtil::SetPackedFields(&source); + source.SerializeToString(&data); + EXPECT_TRUE(destination.ParseFromString(data)); + TestUtil::ExpectPackedExtensionsSet(destination); +} + +TEST(ExtensionSetTest, IsInitialized) { + // Test that IsInitialized() returns false if required fields in nested + // extensions are missing. + unittest::TestAllExtensions message; + + EXPECT_TRUE(message.IsInitialized()); + + message.MutableExtension(unittest::TestRequired::single); + EXPECT_FALSE(message.IsInitialized()); + + message.MutableExtension(unittest::TestRequired::single)->set_a(1); + EXPECT_FALSE(message.IsInitialized()); + message.MutableExtension(unittest::TestRequired::single)->set_b(2); + EXPECT_FALSE(message.IsInitialized()); + message.MutableExtension(unittest::TestRequired::single)->set_c(3); + EXPECT_TRUE(message.IsInitialized()); + + message.AddExtension(unittest::TestRequired::multi); + EXPECT_FALSE(message.IsInitialized()); + + message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1); + EXPECT_FALSE(message.IsInitialized()); + message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2); + EXPECT_FALSE(message.IsInitialized()); + message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3); + EXPECT_TRUE(message.IsInitialized()); +} + +TEST(ExtensionSetTest, MutableString) { + // Test the mutable string accessors. + unittest::TestAllExtensions message; + + message.MutableExtension(unittest::optional_string_extension)->assign("foo"); + EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension)); + EXPECT_EQ("foo", message.GetExtension(unittest::optional_string_extension)); + + message.AddExtension(unittest::repeated_string_extension)->assign("bar"); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension)); + EXPECT_EQ("bar", + message.GetExtension(unittest::repeated_string_extension, 0)); +} + +TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { + // Scalar primitive extensions should increase the extension set size by a + // minimum of the size of the primitive type. +#define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value) \ + do { \ + unittest::TestAllExtensions message; \ + const int base_size = message.SpaceUsed(); \ + message.SetExtension(unittest::optional_##type##_extension, value); \ + int min_expected_size = base_size + \ + sizeof(message.GetExtension(unittest::optional_##type##_extension)); \ + EXPECT_LE(min_expected_size, message.SpaceUsed()); \ + } while (0) + + TEST_SCALAR_EXTENSIONS_SPACE_USED(int32 , 101); + TEST_SCALAR_EXTENSIONS_SPACE_USED(int64 , 102); + TEST_SCALAR_EXTENSIONS_SPACE_USED(uint32 , 103); + TEST_SCALAR_EXTENSIONS_SPACE_USED(uint64 , 104); + TEST_SCALAR_EXTENSIONS_SPACE_USED(sint32 , 105); + TEST_SCALAR_EXTENSIONS_SPACE_USED(sint64 , 106); + TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed32 , 107); + TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed64 , 108); + TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed32, 109); + TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed64, 110); + TEST_SCALAR_EXTENSIONS_SPACE_USED(float , 111); + TEST_SCALAR_EXTENSIONS_SPACE_USED(double , 112); + TEST_SCALAR_EXTENSIONS_SPACE_USED(bool , true); +#undef TEST_SCALAR_EXTENSIONS_SPACE_USED + { + unittest::TestAllExtensions message; + const int base_size = message.SpaceUsed(); + message.SetExtension(unittest::optional_nested_enum_extension, + unittest::TestAllTypes::FOO); + int min_expected_size = base_size + + sizeof(message.GetExtension(unittest::optional_nested_enum_extension)); + EXPECT_LE(min_expected_size, message.SpaceUsed()); + } + { + // Strings may cause extra allocations depending on their length; ensure + // that gets included as well. + unittest::TestAllExtensions message; + const int base_size = message.SpaceUsed(); + const string s("this is a fairly large string that will cause some " + "allocation in order to store it in the extension"); + message.SetExtension(unittest::optional_string_extension, s); + int min_expected_size = base_size + s.length(); + EXPECT_LE(min_expected_size, message.SpaceUsed()); + } + { + // Messages also have additional allocation that need to be counted. + unittest::TestAllExtensions message; + const int base_size = message.SpaceUsed(); + unittest::ForeignMessage foreign; + foreign.set_c(42); + message.MutableExtension(unittest::optional_foreign_message_extension)-> + CopyFrom(foreign); + int min_expected_size = base_size + foreign.SpaceUsed(); + EXPECT_LE(min_expected_size, message.SpaceUsed()); + } + + // Repeated primitive extensions will increase space used by at least a + // RepeatedField, and will cause additional allocations when the array + // gets too big for the initial space. + // This macro: + // - Adds a value to the repeated extension, then clears it, establishing + // the base size. + // - Adds a small number of values, testing that it doesn't increase the + // SpaceUsed() + // - Adds a large number of values (requiring allocation in the repeated + // field), and ensures that that allocation is included in SpaceUsed() +#define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value) \ + do { \ + unittest::TestAllExtensions message; \ + const int base_size = message.SpaceUsed(); \ + int min_expected_size = sizeof(RepeatedField) + base_size; \ + message.AddExtension(unittest::repeated_##type##_extension, value); \ + message.ClearExtension(unittest::repeated_##type##_extension); \ + const int empty_repeated_field_size = message.SpaceUsed(); \ + EXPECT_LE(min_expected_size, empty_repeated_field_size) << #type; \ + message.AddExtension(unittest::repeated_##type##_extension, value); \ + message.AddExtension(unittest::repeated_##type##_extension, value); \ + EXPECT_EQ(empty_repeated_field_size, message.SpaceUsed()) << #type; \ + message.ClearExtension(unittest::repeated_##type##_extension); \ + for (int i = 0; i < 16; ++i) { \ + message.AddExtension(unittest::repeated_##type##_extension, value); \ + } \ + int expected_size = sizeof(cpptype) * (16 - \ + kMinRepeatedFieldAllocationSize) + empty_repeated_field_size; \ + EXPECT_EQ(expected_size, message.SpaceUsed()) << #type; \ + } while (0) + + TEST_REPEATED_EXTENSIONS_SPACE_USED(int32 , int32 , 101); + TEST_REPEATED_EXTENSIONS_SPACE_USED(int64 , int64 , 102); + TEST_REPEATED_EXTENSIONS_SPACE_USED(uint32 , uint32, 103); + TEST_REPEATED_EXTENSIONS_SPACE_USED(uint64 , uint64, 104); + TEST_REPEATED_EXTENSIONS_SPACE_USED(sint32 , int32 , 105); + TEST_REPEATED_EXTENSIONS_SPACE_USED(sint64 , int64 , 106); + TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed32 , uint32, 107); + TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed64 , uint64, 108); + TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed32, int32 , 109); + TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed64, int64 , 110); + TEST_REPEATED_EXTENSIONS_SPACE_USED(float , float , 111); + TEST_REPEATED_EXTENSIONS_SPACE_USED(double , double, 112); + TEST_REPEATED_EXTENSIONS_SPACE_USED(bool , bool , true); + TEST_REPEATED_EXTENSIONS_SPACE_USED(nested_enum, int, + unittest::TestAllTypes::FOO); +#undef TEST_REPEATED_EXTENSIONS_SPACE_USED + // Repeated strings + { + unittest::TestAllExtensions message; + const int base_size = message.SpaceUsed(); + int min_expected_size = sizeof(RepeatedPtrField) + base_size; + const string value(256, 'x'); + // Once items are allocated, they may stick around even when cleared so + // without the hardcore memory management accessors there isn't a notion of + // the empty repeated field memory usage as there is with primitive types. + for (int i = 0; i < 16; ++i) { + message.AddExtension(unittest::repeated_string_extension, value); + } + min_expected_size += (sizeof(value) + value.size()) * + (16 - kMinRepeatedFieldAllocationSize); + EXPECT_LE(min_expected_size, message.SpaceUsed()); + } + // Repeated messages + { + unittest::TestAllExtensions message; + const int base_size = message.SpaceUsed(); + int min_expected_size = sizeof(RepeatedPtrField) + + base_size; + unittest::ForeignMessage prototype; + prototype.set_c(2); + for (int i = 0; i < 16; ++i) { + message.AddExtension(unittest::repeated_foreign_message_extension)-> + CopyFrom(prototype); + } + min_expected_size += + (16 - kMinRepeatedFieldAllocationSize) * prototype.SpaceUsed(); + EXPECT_LE(min_expected_size, message.SpaceUsed()); + } +} + +#ifdef PROTOBUF_HAS_DEATH_TEST + +TEST(ExtensionSetTest, InvalidEnumDeath) { + unittest::TestAllExtensions message; + EXPECT_DEBUG_DEATH( + message.SetExtension(unittest::optional_foreign_enum_extension, + static_cast(53)), + "IsValid"); +} + +#endif // PROTOBUF_HAS_DEATH_TEST + +TEST(ExtensionSetTest, DynamicExtensions) { + // Test adding a dynamic extension to a compiled-in message object. + + FileDescriptorProto dynamic_proto; + dynamic_proto.set_name("dynamic_extensions_test.proto"); + dynamic_proto.add_dependency( + unittest::TestAllExtensions::descriptor()->file()->name()); + dynamic_proto.set_package("dynamic_extensions"); + + // Copy the fields and nested types from TestDynamicExtensions into our new + // proto, converting the fields into extensions. + const Descriptor* template_descriptor = + unittest::TestDynamicExtensions::descriptor(); + DescriptorProto template_descriptor_proto; + template_descriptor->CopyTo(&template_descriptor_proto); + dynamic_proto.mutable_message_type()->MergeFrom( + template_descriptor_proto.nested_type()); + dynamic_proto.mutable_enum_type()->MergeFrom( + template_descriptor_proto.enum_type()); + dynamic_proto.mutable_extension()->MergeFrom( + template_descriptor_proto.field()); + + // For each extension that we added... + for (int i = 0; i < dynamic_proto.extension_size(); i++) { + // Set its extendee to TestAllExtensions. + FieldDescriptorProto* extension = dynamic_proto.mutable_extension(i); + extension->set_extendee( + unittest::TestAllExtensions::descriptor()->full_name()); + + // If the field refers to one of the types nested in TestDynamicExtensions, + // make it refer to the type in our dynamic proto instead. + string prefix = "." + template_descriptor->full_name() + "."; + if (extension->has_type_name()) { + string* type_name = extension->mutable_type_name(); + if (HasPrefixString(*type_name, prefix)) { + type_name->replace(0, prefix.size(), ".dynamic_extensions."); + } + } + } + + // Now build the file, using the generated pool as an underlay. + DescriptorPool dynamic_pool(DescriptorPool::generated_pool()); + const FileDescriptor* file = dynamic_pool.BuildFile(dynamic_proto); + ASSERT_TRUE(file != NULL); + DynamicMessageFactory dynamic_factory(&dynamic_pool); + dynamic_factory.SetDelegateToGeneratedFactory(true); + + // Construct a message that we can parse with the extensions we defined. + // Since the extensions were based off of the fields of TestDynamicExtensions, + // we can use that message to create this test message. + string data; + { + unittest::TestDynamicExtensions message; + message.set_scalar_extension(123); + message.set_enum_extension(unittest::FOREIGN_BAR); + message.set_dynamic_enum_extension( + unittest::TestDynamicExtensions::DYNAMIC_BAZ); + message.mutable_message_extension()->set_c(456); + message.mutable_dynamic_message_extension()->set_dynamic_field(789); + message.add_repeated_extension("foo"); + message.add_repeated_extension("bar"); + message.add_packed_extension(12); + message.add_packed_extension(-34); + message.add_packed_extension(56); + message.add_packed_extension(-78); + + // Also add some unknown fields. + + // An unknown enum value (for a known field). + message.mutable_unknown_fields()->AddVarint( + unittest::TestDynamicExtensions::kDynamicEnumExtensionFieldNumber, + 12345); + // A regular unknown field. + message.mutable_unknown_fields()->AddLengthDelimited(54321, "unknown"); + + message.SerializeToString(&data); + } + + // Now we can parse this using our dynamic extension definitions... + unittest::TestAllExtensions message; + { + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory); + ASSERT_TRUE(message.ParseFromCodedStream(&input)); + ASSERT_TRUE(input.ConsumedEntireMessage()); + } + + // Can we print it? + EXPECT_EQ( + "[dynamic_extensions.scalar_extension]: 123\n" + "[dynamic_extensions.enum_extension]: FOREIGN_BAR\n" + "[dynamic_extensions.dynamic_enum_extension]: DYNAMIC_BAZ\n" + "[dynamic_extensions.message_extension] {\n" + " c: 456\n" + "}\n" + "[dynamic_extensions.dynamic_message_extension] {\n" + " dynamic_field: 789\n" + "}\n" + "[dynamic_extensions.repeated_extension]: \"foo\"\n" + "[dynamic_extensions.repeated_extension]: \"bar\"\n" + "[dynamic_extensions.packed_extension]: 12\n" + "[dynamic_extensions.packed_extension]: -34\n" + "[dynamic_extensions.packed_extension]: 56\n" + "[dynamic_extensions.packed_extension]: -78\n" + "2002: 12345\n" + "54321: \"unknown\"\n", + message.DebugString()); + + // Can we serialize it? + // (Don't use EXPECT_EQ because we don't want to dump raw binary data to the + // terminal on failure.) + EXPECT_TRUE(message.SerializeAsString() == data); + + // What if we parse using the reflection-based parser? + { + unittest::TestAllExtensions message2; + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory); + ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message2)); + ASSERT_TRUE(input.ConsumedEntireMessage()); + EXPECT_EQ(message.DebugString(), message2.DebugString()); + } + + // Are the embedded generated types actually using the generated objects? + { + const FieldDescriptor* message_extension = + file->FindExtensionByName("message_extension"); + ASSERT_TRUE(message_extension != NULL); + const Message& sub_message = + message.GetReflection()->GetMessage(message, message_extension); + const unittest::ForeignMessage* typed_sub_message = +#ifdef GOOGLE_PROTOBUF_NO_RTTI + static_cast(&sub_message); +#else + dynamic_cast(&sub_message); +#endif + ASSERT_TRUE(typed_sub_message != NULL); + EXPECT_EQ(456, typed_sub_message->c()); + } + + // What does GetMessage() return for the embedded dynamic type if it isn't + // present? + { + const FieldDescriptor* dynamic_message_extension = + file->FindExtensionByName("dynamic_message_extension"); + ASSERT_TRUE(dynamic_message_extension != NULL); + const Message& parent = unittest::TestAllExtensions::default_instance(); + const Message& sub_message = + parent.GetReflection()->GetMessage(parent, dynamic_message_extension, + &dynamic_factory); + const Message* prototype = + dynamic_factory.GetPrototype(dynamic_message_extension->message_type()); + EXPECT_EQ(prototype, &sub_message); + } +} + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_enum_reflection.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_enum_reflection.h new file mode 100644 index 0000000..a09a540 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_enum_reflection.h @@ -0,0 +1,85 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jasonh@google.com (Jason Hsueh) +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. +// It provides reflection support for generated enums, and is included in +// generated .pb.h files and should have minimal dependencies. The methods are +// implemented in generated_message_reflection.cc. + +#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ +#define GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ + +#include + +namespace google { +namespace protobuf { + class EnumDescriptor; +} // namespace protobuf + +namespace protobuf { + +// Returns the EnumDescriptor for enum type E, which must be a +// proto-declared enum type. Code generated by the protocol compiler +// will include specializations of this template for each enum type declared. +template +const EnumDescriptor* GetEnumDescriptor(); + +namespace internal { + +// Helper for EnumType_Parse functions: try to parse the string 'name' as an +// enum name of the given type, returning true and filling in value on success, +// or returning false and leaving value unchanged on failure. +LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor, + const string& name, + int* value); + +template +bool ParseNamedEnum(const EnumDescriptor* descriptor, + const string& name, + EnumType* value) { + int tmp; + if (!ParseNamedEnum(descriptor, name, &tmp)) return false; + *value = static_cast(tmp); + return true; +} + +// Just a wrapper around printing the name of a value. The main point of this +// function is not to be inlined, so that you can do this without including +// descriptor.h. +LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value); + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection.cc new file mode 100644 index 0000000..f4d0851 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection.cc @@ -0,0 +1,1293 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +int StringSpaceUsedExcludingSelf(const string& str) { + const void* start = &str; + const void* end = &str + 1; + + if (start <= str.data() && str.data() <= end) { + // The string's data is stored inside the string object itself. + return 0; + } else { + return str.capacity(); + } +} + +bool ParseNamedEnum(const EnumDescriptor* descriptor, + const string& name, + int* value) { + const EnumValueDescriptor* d = descriptor->FindValueByName(name); + if (d == NULL) return false; + *value = d->number(); + return true; +} + +const string& NameOfEnum(const EnumDescriptor* descriptor, int value) { + const EnumValueDescriptor* d = descriptor->FindValueByNumber(value); + return (d == NULL ? kEmptyString : d->name()); +} + +// =================================================================== +// Helpers for reporting usage errors (e.g. trying to use GetInt32() on +// a string field). + +namespace { + +void ReportReflectionUsageError( + const Descriptor* descriptor, const FieldDescriptor* field, + const char* method, const char* description) { + GOOGLE_LOG(FATAL) + << "Protocol Buffer reflection usage error:\n" + " Method : google::protobuf::Reflection::" << method << "\n" + " Message type: " << descriptor->full_name() << "\n" + " Field : " << field->full_name() << "\n" + " Problem : " << description; +} + +const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = { + "INVALID_CPPTYPE", + "CPPTYPE_INT32", + "CPPTYPE_INT64", + "CPPTYPE_UINT32", + "CPPTYPE_UINT64", + "CPPTYPE_DOUBLE", + "CPPTYPE_FLOAT", + "CPPTYPE_BOOL", + "CPPTYPE_ENUM", + "CPPTYPE_STRING", + "CPPTYPE_MESSAGE" +}; + +static void ReportReflectionUsageTypeError( + const Descriptor* descriptor, const FieldDescriptor* field, + const char* method, + FieldDescriptor::CppType expected_type) { + GOOGLE_LOG(FATAL) + << "Protocol Buffer reflection usage error:\n" + " Method : google::protobuf::Reflection::" << method << "\n" + " Message type: " << descriptor->full_name() << "\n" + " Field : " << field->full_name() << "\n" + " Problem : Field is not the right type for this message:\n" + " Expected : " << cpptype_names_[expected_type] << "\n" + " Field type: " << cpptype_names_[field->cpp_type()]; +} + +static void ReportReflectionUsageEnumTypeError( + const Descriptor* descriptor, const FieldDescriptor* field, + const char* method, const EnumValueDescriptor* value) { + GOOGLE_LOG(FATAL) + << "Protocol Buffer reflection usage error:\n" + " Method : google::protobuf::Reflection::" << method << "\n" + " Message type: " << descriptor->full_name() << "\n" + " Field : " << field->full_name() << "\n" + " Problem : Enum value did not match field type:\n" + " Expected : " << field->enum_type()->full_name() << "\n" + " Actual : " << value->full_name(); +} + +#define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \ + if (!(CONDITION)) \ + ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION) +#define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \ + USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION) +#define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \ + USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION) + +#define USAGE_CHECK_TYPE(METHOD, CPPTYPE) \ + if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \ + ReportReflectionUsageTypeError(descriptor_, field, #METHOD, \ + FieldDescriptor::CPPTYPE_##CPPTYPE) + +#define USAGE_CHECK_ENUM_VALUE(METHOD) \ + if (value->type() != field->enum_type()) \ + ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value) + +#define USAGE_CHECK_MESSAGE_TYPE(METHOD) \ + USAGE_CHECK_EQ(field->containing_type(), descriptor_, \ + METHOD, "Field does not match message type."); +#define USAGE_CHECK_SINGULAR(METHOD) \ + USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \ + "Field is repeated; the method requires a singular field.") +#define USAGE_CHECK_REPEATED(METHOD) \ + USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \ + "Field is singular; the method requires a repeated field.") + +#define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \ + USAGE_CHECK_MESSAGE_TYPE(METHOD); \ + USAGE_CHECK_##LABEL(METHOD); \ + USAGE_CHECK_TYPE(METHOD, CPPTYPE) + +} // namespace + +// =================================================================== + +GeneratedMessageReflection::GeneratedMessageReflection( + const Descriptor* descriptor, + const Message* default_instance, + const int offsets[], + int has_bits_offset, + int unknown_fields_offset, + int extensions_offset, + const DescriptorPool* descriptor_pool, + MessageFactory* factory, + int object_size) + : descriptor_ (descriptor), + default_instance_ (default_instance), + offsets_ (offsets), + has_bits_offset_ (has_bits_offset), + unknown_fields_offset_(unknown_fields_offset), + extensions_offset_(extensions_offset), + object_size_ (object_size), + descriptor_pool_ ((descriptor_pool == NULL) ? + DescriptorPool::generated_pool() : + descriptor_pool), + message_factory_ (factory) { +} + +GeneratedMessageReflection::~GeneratedMessageReflection() {} + +const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields( + const Message& message) const { + const void* ptr = reinterpret_cast(&message) + + unknown_fields_offset_; + return *reinterpret_cast(ptr); +} +UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields( + Message* message) const { + void* ptr = reinterpret_cast(message) + unknown_fields_offset_; + return reinterpret_cast(ptr); +} + +int GeneratedMessageReflection::SpaceUsed(const Message& message) const { + // object_size_ already includes the in-memory representation of each field + // in the message, so we only need to account for additional memory used by + // the fields. + int total_size = object_size_; + + total_size += GetUnknownFields(message).SpaceUsedExcludingSelf(); + + if (extensions_offset_ != -1) { + total_size += GetExtensionSet(message).SpaceUsedExcludingSelf(); + } + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + if (field->is_repeated()) { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + total_size += GetRaw >(message, field) \ + .SpaceUsedExcludingSelf(); \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + total_size += GetRaw >(message, field) + .SpaceUsedExcludingSelf(); + break; + } + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + // We don't know which subclass of RepeatedPtrFieldBase the type is, + // so we use RepeatedPtrFieldBase directly. + total_size += + GetRaw(message, field) + .SpaceUsedExcludingSelf >(); + break; + } + } else { + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32 : + case FieldDescriptor::CPPTYPE_INT64 : + case FieldDescriptor::CPPTYPE_UINT32: + case FieldDescriptor::CPPTYPE_UINT64: + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT : + case FieldDescriptor::CPPTYPE_BOOL : + case FieldDescriptor::CPPTYPE_ENUM : + // Field is inline, so we've already counted it. + break; + + case FieldDescriptor::CPPTYPE_STRING: { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + const string* ptr = GetField(message, field); + + // Initially, the string points to the default value stored in + // the prototype. Only count the string if it has been changed + // from the default value. + const string* default_ptr = DefaultRaw(field); + + if (ptr != default_ptr) { + // string fields are represented by just a pointer, so also + // include sizeof(string) as well. + total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr); + } + break; + } + } + break; + } + + case FieldDescriptor::CPPTYPE_MESSAGE: + if (&message == default_instance_) { + // For singular fields, the prototype just stores a pointer to the + // external type's prototype, so there is no extra memory usage. + } else { + const Message* sub_message = GetRaw(message, field); + if (sub_message != NULL) { + total_size += sub_message->SpaceUsed(); + } + } + break; + } + } + } + + return total_size; +} + +void GeneratedMessageReflection::Swap( + Message* message1, + Message* message2) const { + if (message1 == message2) return; + + // TODO(kenton): Other Reflection methods should probably check this too. + GOOGLE_CHECK_EQ(message1->GetReflection(), this) + << "First argument to Swap() (of type \"" + << message1->GetDescriptor()->full_name() + << "\") is not compatible with this reflection object (which is for type \"" + << descriptor_->full_name() + << "\"). Note that the exact same class is required; not just the same " + "descriptor."; + GOOGLE_CHECK_EQ(message2->GetReflection(), this) + << "Second argument to Swap() (of type \"" + << message2->GetDescriptor()->full_name() + << "\") is not compatible with this reflection object (which is for type \"" + << descriptor_->full_name() + << "\"). Note that the exact same class is required; not just the same " + "descriptor."; + + uint32* has_bits1 = MutableHasBits(message1); + uint32* has_bits2 = MutableHasBits(message2); + int has_bits_size = (descriptor_->field_count() + 31) / 32; + + for (int i = 0; i < has_bits_size; i++) { + std::swap(has_bits1[i], has_bits2[i]); + } + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->is_repeated()) { + switch (field->cpp_type()) { +#define SWAP_ARRAYS(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + MutableRaw >(message1, field)->Swap( \ + MutableRaw >(message2, field)); \ + break; + + SWAP_ARRAYS(INT32 , int32 ); + SWAP_ARRAYS(INT64 , int64 ); + SWAP_ARRAYS(UINT32, uint32); + SWAP_ARRAYS(UINT64, uint64); + SWAP_ARRAYS(FLOAT , float ); + SWAP_ARRAYS(DOUBLE, double); + SWAP_ARRAYS(BOOL , bool ); + SWAP_ARRAYS(ENUM , int ); +#undef SWAP_ARRAYS + + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + MutableRaw(message1, field)->Swap( + MutableRaw(message2, field)); + break; + + default: + GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); + } + } else { + switch (field->cpp_type()) { +#define SWAP_VALUES(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + std::swap(*MutableRaw(message1, field), \ + *MutableRaw(message2, field)); \ + break; + + SWAP_VALUES(INT32 , int32 ); + SWAP_VALUES(INT64 , int64 ); + SWAP_VALUES(UINT32, uint32); + SWAP_VALUES(UINT64, uint64); + SWAP_VALUES(FLOAT , float ); + SWAP_VALUES(DOUBLE, double); + SWAP_VALUES(BOOL , bool ); + SWAP_VALUES(ENUM , int ); +#undef SWAP_VALUES + case FieldDescriptor::CPPTYPE_MESSAGE: + std::swap(*MutableRaw(message1, field), + *MutableRaw(message2, field)); + break; + + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + std::swap(*MutableRaw(message1, field), + *MutableRaw(message2, field)); + break; + } + break; + + default: + GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); + } + } + } + + if (extensions_offset_ != -1) { + MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2)); + } + + MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2)); +} + +// ------------------------------------------------------------------- + +bool GeneratedMessageReflection::HasField(const Message& message, + const FieldDescriptor* field) const { + USAGE_CHECK_MESSAGE_TYPE(HasField); + USAGE_CHECK_SINGULAR(HasField); + + if (field->is_extension()) { + return GetExtensionSet(message).Has(field->number()); + } else { + return HasBit(message, field); + } +} + +int GeneratedMessageReflection::FieldSize(const Message& message, + const FieldDescriptor* field) const { + USAGE_CHECK_MESSAGE_TYPE(FieldSize); + USAGE_CHECK_REPEATED(FieldSize); + + if (field->is_extension()) { + return GetExtensionSet(message).ExtensionSize(field->number()); + } else { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + return GetRaw >(message, field).size() + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + return GetRaw(message, field).size(); + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return 0; + } +} + +void GeneratedMessageReflection::ClearField( + Message* message, const FieldDescriptor* field) const { + USAGE_CHECK_MESSAGE_TYPE(ClearField); + + if (field->is_extension()) { + MutableExtensionSet(message)->ClearExtension(field->number()); + } else if (!field->is_repeated()) { + if (HasBit(*message, field)) { + ClearBit(message, field); + + // We need to set the field back to its default value. + switch (field->cpp_type()) { +#define CLEAR_TYPE(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + *MutableRaw(message, field) = \ + field->default_value_##TYPE(); \ + break; + + CLEAR_TYPE(INT32 , int32 ); + CLEAR_TYPE(INT64 , int64 ); + CLEAR_TYPE(UINT32, uint32); + CLEAR_TYPE(UINT64, uint64); + CLEAR_TYPE(FLOAT , float ); + CLEAR_TYPE(DOUBLE, double); + CLEAR_TYPE(BOOL , bool ); +#undef CLEAR_TYPE + + case FieldDescriptor::CPPTYPE_ENUM: + *MutableRaw(message, field) = + field->default_value_enum()->number(); + break; + + case FieldDescriptor::CPPTYPE_STRING: { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + const string* default_ptr = DefaultRaw(field); + string** value = MutableRaw(message, field); + if (*value != default_ptr) { + if (field->has_default_value()) { + (*value)->assign(field->default_value_string()); + } else { + (*value)->clear(); + } + } + break; + } + break; + } + + case FieldDescriptor::CPPTYPE_MESSAGE: + (*MutableRaw(message, field))->Clear(); + break; + } + } + } else { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + MutableRaw >(message, field)->Clear(); \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + MutableRaw >(message, field)->Clear(); + break; + } + break; + } + + case FieldDescriptor::CPPTYPE_MESSAGE: { + // We don't know which subclass of RepeatedPtrFieldBase the type is, + // so we use RepeatedPtrFieldBase directly. + MutableRaw(message, field) + ->Clear >(); + break; + } + } + } +} + +void GeneratedMessageReflection::RemoveLast( + Message* message, + const FieldDescriptor* field) const { + USAGE_CHECK_MESSAGE_TYPE(RemoveLast); + USAGE_CHECK_REPEATED(RemoveLast); + + if (field->is_extension()) { + MutableExtensionSet(message)->RemoveLast(field->number()); + } else { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + MutableRaw >(message, field)->RemoveLast(); \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + MutableRaw >(message, field)->RemoveLast(); + break; + } + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + MutableRaw(message, field) + ->RemoveLast >(); + break; + } + } +} + +Message* GeneratedMessageReflection::ReleaseLast( + Message* message, + const FieldDescriptor* field) const { + USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE); + + if (field->is_extension()) { + return static_cast( + MutableExtensionSet(message)->ReleaseLast(field->number())); + } else { + return MutableRaw(message, field) + ->ReleaseLast >(); + } +} + +void GeneratedMessageReflection::SwapElements( + Message* message, + const FieldDescriptor* field, + int index1, + int index2) const { + USAGE_CHECK_MESSAGE_TYPE(Swap); + USAGE_CHECK_REPEATED(Swap); + + if (field->is_extension()) { + MutableExtensionSet(message)->SwapElements(field->number(), index1, index2); + } else { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE : \ + MutableRaw >(message, field) \ + ->SwapElements(index1, index2); \ + break + + HANDLE_TYPE( INT32, int32); + HANDLE_TYPE( INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE( FLOAT, float); + HANDLE_TYPE( BOOL, bool); + HANDLE_TYPE( ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + MutableRaw(message, field) + ->SwapElements(index1, index2); + break; + } + } +} + +namespace { +// Comparison functor for sorting FieldDescriptors by field number. +struct FieldNumberSorter { + bool operator()(const FieldDescriptor* left, + const FieldDescriptor* right) const { + return left->number() < right->number(); + } +}; +} // namespace + +void GeneratedMessageReflection::ListFields( + const Message& message, + vector* output) const { + output->clear(); + + // Optimization: The default instance never has any fields set. + if (&message == default_instance_) return; + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->is_repeated()) { + if (FieldSize(message, field) > 0) { + output->push_back(field); + } + } else { + if (HasBit(message, field)) { + output->push_back(field); + } + } + } + + if (extensions_offset_ != -1) { + GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_, + output); + } + + // ListFields() must sort output by field number. + sort(output->begin(), output->end(), FieldNumberSorter()); +} + +// ------------------------------------------------------------------- + +#undef DEFINE_PRIMITIVE_ACCESSORS +#define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE) \ + PASSTYPE GeneratedMessageReflection::Get##TYPENAME( \ + const Message& message, const FieldDescriptor* field) const { \ + USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE); \ + if (field->is_extension()) { \ + return GetExtensionSet(message).Get##TYPENAME( \ + field->number(), field->default_value_##PASSTYPE()); \ + } else { \ + return GetField(message, field); \ + } \ + } \ + \ + void GeneratedMessageReflection::Set##TYPENAME( \ + Message* message, const FieldDescriptor* field, \ + PASSTYPE value) const { \ + USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \ + if (field->is_extension()) { \ + return MutableExtensionSet(message)->Set##TYPENAME( \ + field->number(), field->type(), value, field); \ + } else { \ + SetField(message, field, value); \ + } \ + } \ + \ + PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME( \ + const Message& message, \ + const FieldDescriptor* field, int index) const { \ + USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE); \ + if (field->is_extension()) { \ + return GetExtensionSet(message).GetRepeated##TYPENAME( \ + field->number(), index); \ + } else { \ + return GetRepeatedField(message, field, index); \ + } \ + } \ + \ + void GeneratedMessageReflection::SetRepeated##TYPENAME( \ + Message* message, const FieldDescriptor* field, \ + int index, PASSTYPE value) const { \ + USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE); \ + if (field->is_extension()) { \ + MutableExtensionSet(message)->SetRepeated##TYPENAME( \ + field->number(), index, value); \ + } else { \ + SetRepeatedField(message, field, index, value); \ + } \ + } \ + \ + void GeneratedMessageReflection::Add##TYPENAME( \ + Message* message, const FieldDescriptor* field, \ + PASSTYPE value) const { \ + USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \ + if (field->is_extension()) { \ + MutableExtensionSet(message)->Add##TYPENAME( \ + field->number(), field->type(), field->options().packed(), value, \ + field); \ + } else { \ + AddField(message, field, value); \ + } \ + } + +DEFINE_PRIMITIVE_ACCESSORS(Int32 , int32 , int32 , INT32 ) +DEFINE_PRIMITIVE_ACCESSORS(Int64 , int64 , int64 , INT64 ) +DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32) +DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64) +DEFINE_PRIMITIVE_ACCESSORS(Float , float , float , FLOAT ) +DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE) +DEFINE_PRIMITIVE_ACCESSORS(Bool , bool , bool , BOOL ) +#undef DEFINE_PRIMITIVE_ACCESSORS + +// ------------------------------------------------------------------- + +string GeneratedMessageReflection::GetString( + const Message& message, const FieldDescriptor* field) const { + USAGE_CHECK_ALL(GetString, SINGULAR, STRING); + if (field->is_extension()) { + return GetExtensionSet(message).GetString(field->number(), + field->default_value_string()); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return *GetField(message, field); + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return kEmptyString; // Make compiler happy. + } +} + +const string& GeneratedMessageReflection::GetStringReference( + const Message& message, + const FieldDescriptor* field, string* scratch) const { + USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING); + if (field->is_extension()) { + return GetExtensionSet(message).GetString(field->number(), + field->default_value_string()); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return *GetField(message, field); + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return kEmptyString; // Make compiler happy. + } +} + + +void GeneratedMessageReflection::SetString( + Message* message, const FieldDescriptor* field, + const string& value) const { + USAGE_CHECK_ALL(SetString, SINGULAR, STRING); + if (field->is_extension()) { + return MutableExtensionSet(message)->SetString(field->number(), + field->type(), value, field); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + string** ptr = MutableField(message, field); + if (*ptr == DefaultRaw(field)) { + *ptr = new string(value); + } else { + (*ptr)->assign(value); + } + break; + } + } + } +} + + +string GeneratedMessageReflection::GetRepeatedString( + const Message& message, const FieldDescriptor* field, int index) const { + USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING); + if (field->is_extension()) { + return GetExtensionSet(message).GetRepeatedString(field->number(), index); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return GetRepeatedPtrField(message, field, index); + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return kEmptyString; // Make compiler happy. + } +} + +const string& GeneratedMessageReflection::GetRepeatedStringReference( + const Message& message, const FieldDescriptor* field, + int index, string* scratch) const { + USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING); + if (field->is_extension()) { + return GetExtensionSet(message).GetRepeatedString(field->number(), index); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return GetRepeatedPtrField(message, field, index); + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return kEmptyString; // Make compiler happy. + } +} + + +void GeneratedMessageReflection::SetRepeatedString( + Message* message, const FieldDescriptor* field, + int index, const string& value) const { + USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING); + if (field->is_extension()) { + MutableExtensionSet(message)->SetRepeatedString( + field->number(), index, value); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + *MutableRepeatedField(message, field, index) = value; + break; + } + } +} + + +void GeneratedMessageReflection::AddString( + Message* message, const FieldDescriptor* field, + const string& value) const { + USAGE_CHECK_ALL(AddString, REPEATED, STRING); + if (field->is_extension()) { + MutableExtensionSet(message)->AddString(field->number(), + field->type(), value, field); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + *AddField(message, field) = value; + break; + } + } +} + + +// ------------------------------------------------------------------- + +const EnumValueDescriptor* GeneratedMessageReflection::GetEnum( + const Message& message, const FieldDescriptor* field) const { + USAGE_CHECK_ALL(GetEnum, SINGULAR, ENUM); + + int value; + if (field->is_extension()) { + value = GetExtensionSet(message).GetEnum( + field->number(), field->default_value_enum()->number()); + } else { + value = GetField(message, field); + } + const EnumValueDescriptor* result = + field->enum_type()->FindValueByNumber(value); + GOOGLE_CHECK(result != NULL) << "Value " << value << " is not valid for field " + << field->full_name() << " of type " + << field->enum_type()->full_name() << "."; + return result; +} + +void GeneratedMessageReflection::SetEnum( + Message* message, const FieldDescriptor* field, + const EnumValueDescriptor* value) const { + USAGE_CHECK_ALL(SetEnum, SINGULAR, ENUM); + USAGE_CHECK_ENUM_VALUE(SetEnum); + + if (field->is_extension()) { + MutableExtensionSet(message)->SetEnum(field->number(), field->type(), + value->number(), field); + } else { + SetField(message, field, value->number()); + } +} + +const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum( + const Message& message, const FieldDescriptor* field, int index) const { + USAGE_CHECK_ALL(GetRepeatedEnum, REPEATED, ENUM); + + int value; + if (field->is_extension()) { + value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index); + } else { + value = GetRepeatedField(message, field, index); + } + const EnumValueDescriptor* result = + field->enum_type()->FindValueByNumber(value); + GOOGLE_CHECK(result != NULL) << "Value " << value << " is not valid for field " + << field->full_name() << " of type " + << field->enum_type()->full_name() << "."; + return result; +} + +void GeneratedMessageReflection::SetRepeatedEnum( + Message* message, + const FieldDescriptor* field, int index, + const EnumValueDescriptor* value) const { + USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM); + USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum); + + if (field->is_extension()) { + MutableExtensionSet(message)->SetRepeatedEnum( + field->number(), index, value->number()); + } else { + SetRepeatedField(message, field, index, value->number()); + } +} + +void GeneratedMessageReflection::AddEnum( + Message* message, const FieldDescriptor* field, + const EnumValueDescriptor* value) const { + USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM); + USAGE_CHECK_ENUM_VALUE(AddEnum); + + if (field->is_extension()) { + MutableExtensionSet(message)->AddEnum(field->number(), field->type(), + field->options().packed(), + value->number(), field); + } else { + AddField(message, field, value->number()); + } +} + +// ------------------------------------------------------------------- + +const Message& GeneratedMessageReflection::GetMessage( + const Message& message, const FieldDescriptor* field, + MessageFactory* factory) const { + USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE); + + if (factory == NULL) factory = message_factory_; + + if (field->is_extension()) { + return static_cast( + GetExtensionSet(message).GetMessage( + field->number(), field->message_type(), factory)); + } else { + const Message* result; + result = GetRaw(message, field); + if (result == NULL) { + result = DefaultRaw(field); + } + return *result; + } +} + +Message* GeneratedMessageReflection::MutableMessage( + Message* message, const FieldDescriptor* field, + MessageFactory* factory) const { + USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE); + + if (factory == NULL) factory = message_factory_; + + if (field->is_extension()) { + return static_cast( + MutableExtensionSet(message)->MutableMessage(field, factory)); + } else { + Message* result; + Message** result_holder = MutableField(message, field); + if (*result_holder == NULL) { + const Message* default_message = DefaultRaw(field); + *result_holder = default_message->New(); + } + result = *result_holder; + return result; + } +} + +Message* GeneratedMessageReflection::ReleaseMessage( + Message* message, + const FieldDescriptor* field, + MessageFactory* factory) const { + USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE); + + if (factory == NULL) factory = message_factory_; + + if (field->is_extension()) { + return static_cast( + MutableExtensionSet(message)->ReleaseMessage(field, factory)); + } else { + ClearBit(message, field); + Message** result = MutableRaw(message, field); + Message* ret = *result; + *result = NULL; + return ret; + } +} + +const Message& GeneratedMessageReflection::GetRepeatedMessage( + const Message& message, const FieldDescriptor* field, int index) const { + USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE); + + if (field->is_extension()) { + return static_cast( + GetExtensionSet(message).GetRepeatedMessage(field->number(), index)); + } else { + return GetRaw(message, field) + .Get >(index); + } +} + +Message* GeneratedMessageReflection::MutableRepeatedMessage( + Message* message, const FieldDescriptor* field, int index) const { + USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE); + + if (field->is_extension()) { + return static_cast( + MutableExtensionSet(message)->MutableRepeatedMessage( + field->number(), index)); + } else { + return MutableRaw(message, field) + ->Mutable >(index); + } +} + +Message* GeneratedMessageReflection::AddMessage( + Message* message, const FieldDescriptor* field, + MessageFactory* factory) const { + USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE); + + if (factory == NULL) factory = message_factory_; + + if (field->is_extension()) { + return static_cast( + MutableExtensionSet(message)->AddMessage(field, factory)); + } else { + // We can't use AddField() because RepeatedPtrFieldBase doesn't + // know how to allocate one. + RepeatedPtrFieldBase* repeated = + MutableRaw(message, field); + Message* result = repeated->AddFromCleared >(); + if (result == NULL) { + // We must allocate a new object. + const Message* prototype; + if (repeated->size() == 0) { + prototype = factory->GetPrototype(field->message_type()); + } else { + prototype = &repeated->Get >(0); + } + result = prototype->New(); + repeated->AddAllocated >(result); + } + return result; + } +} + +void* GeneratedMessageReflection::MutableRawRepeatedField( + Message* message, const FieldDescriptor* field, + FieldDescriptor::CppType cpptype, + int ctype, const Descriptor* desc) const { + USAGE_CHECK_REPEATED("MutableRawRepeatedField"); + if (field->cpp_type() != cpptype) + ReportReflectionUsageTypeError(descriptor_, + field, "MutableRawRepeatedField", cpptype); + if (ctype >= 0) + GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch"; + if (desc != NULL) + GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type"; + if (field->is_extension()) + return MutableExtensionSet(message)->MutableRawRepeatedField( + field->number()); + else + return reinterpret_cast(message) + offsets_[field->index()]; +} + +// ----------------------------------------------------------------------------- + +const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName( + const string& name) const { + if (extensions_offset_ == -1) return NULL; + + const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name); + if (result != NULL && result->containing_type() == descriptor_) { + return result; + } + + if (descriptor_->options().message_set_wire_format()) { + // MessageSet extensions may be identified by type name. + const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name); + if (type != NULL) { + // Look for a matching extension in the foreign type's scope. + for (int i = 0; i < type->extension_count(); i++) { + const FieldDescriptor* extension = type->extension(i); + if (extension->containing_type() == descriptor_ && + extension->type() == FieldDescriptor::TYPE_MESSAGE && + extension->is_optional() && + extension->message_type() == type) { + // Found it. + return extension; + } + } + } + } + + return NULL; +} + +const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber( + int number) const { + if (extensions_offset_ == -1) return NULL; + return descriptor_pool_->FindExtensionByNumber(descriptor_, number); +} + +// =================================================================== +// Some private helpers. + +// These simple template accessors obtain pointers (or references) to +// the given field. +template +inline const Type& GeneratedMessageReflection::GetRaw( + const Message& message, const FieldDescriptor* field) const { + const void* ptr = reinterpret_cast(&message) + + offsets_[field->index()]; + return *reinterpret_cast(ptr); +} + +template +inline Type* GeneratedMessageReflection::MutableRaw( + Message* message, const FieldDescriptor* field) const { + void* ptr = reinterpret_cast(message) + offsets_[field->index()]; + return reinterpret_cast(ptr); +} + +template +inline const Type& GeneratedMessageReflection::DefaultRaw( + const FieldDescriptor* field) const { + const void* ptr = reinterpret_cast(default_instance_) + + offsets_[field->index()]; + return *reinterpret_cast(ptr); +} + +inline const uint32* GeneratedMessageReflection::GetHasBits( + const Message& message) const { + const void* ptr = reinterpret_cast(&message) + has_bits_offset_; + return reinterpret_cast(ptr); +} +inline uint32* GeneratedMessageReflection::MutableHasBits( + Message* message) const { + void* ptr = reinterpret_cast(message) + has_bits_offset_; + return reinterpret_cast(ptr); +} + +inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet( + const Message& message) const { + GOOGLE_DCHECK_NE(extensions_offset_, -1); + const void* ptr = reinterpret_cast(&message) + + extensions_offset_; + return *reinterpret_cast(ptr); +} +inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet( + Message* message) const { + GOOGLE_DCHECK_NE(extensions_offset_, -1); + void* ptr = reinterpret_cast(message) + extensions_offset_; + return reinterpret_cast(ptr); +} + +// Simple accessors for manipulating has_bits_. +inline bool GeneratedMessageReflection::HasBit( + const Message& message, const FieldDescriptor* field) const { + return GetHasBits(message)[field->index() / 32] & + (1 << (field->index() % 32)); +} + +inline void GeneratedMessageReflection::SetBit( + Message* message, const FieldDescriptor* field) const { + MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32)); +} + +inline void GeneratedMessageReflection::ClearBit( + Message* message, const FieldDescriptor* field) const { + MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32)); +} + +// Template implementations of basic accessors. Inline because each +// template instance is only called from one location. These are +// used for all types except messages. +template +inline const Type& GeneratedMessageReflection::GetField( + const Message& message, const FieldDescriptor* field) const { + return GetRaw(message, field); +} + +template +inline void GeneratedMessageReflection::SetField( + Message* message, const FieldDescriptor* field, const Type& value) const { + *MutableRaw(message, field) = value; + SetBit(message, field); +} + +template +inline Type* GeneratedMessageReflection::MutableField( + Message* message, const FieldDescriptor* field) const { + SetBit(message, field); + return MutableRaw(message, field); +} + +template +inline const Type& GeneratedMessageReflection::GetRepeatedField( + const Message& message, const FieldDescriptor* field, int index) const { + return GetRaw >(message, field).Get(index); +} + +template +inline const Type& GeneratedMessageReflection::GetRepeatedPtrField( + const Message& message, const FieldDescriptor* field, int index) const { + return GetRaw >(message, field).Get(index); +} + +template +inline void GeneratedMessageReflection::SetRepeatedField( + Message* message, const FieldDescriptor* field, + int index, Type value) const { + MutableRaw >(message, field)->Set(index, value); +} + +template +inline Type* GeneratedMessageReflection::MutableRepeatedField( + Message* message, const FieldDescriptor* field, int index) const { + RepeatedPtrField* repeated = + MutableRaw >(message, field); + return repeated->Mutable(index); +} + +template +inline void GeneratedMessageReflection::AddField( + Message* message, const FieldDescriptor* field, const Type& value) const { + MutableRaw >(message, field)->Add(value); +} + +template +inline Type* GeneratedMessageReflection::AddField( + Message* message, const FieldDescriptor* field) const { + RepeatedPtrField* repeated = + MutableRaw >(message, field); + return repeated->Add(); +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection.h new file mode 100644 index 0000000..c1c142f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection.h @@ -0,0 +1,419 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ + +#include +#include +#include +// TODO(jasonh): Remove this once the compiler change to directly include this +// is released to components. +#include +#include +#include + + +namespace google { +namespace upb { +namespace google_opensource { +class GMR_Handlers; +} // namespace google_opensource +} // namespace upb + +namespace protobuf { + class DescriptorPool; +} + +namespace protobuf { +namespace internal { + +// Defined in this file. +class GeneratedMessageReflection; + +// Defined in other files. +class ExtensionSet; // extension_set.h + +// THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use +// by generated code. This class is just a big hack that reduces code +// size. +// +// A GeneratedMessageReflection is an implementation of Reflection +// which expects all fields to be backed by simple variables located in +// memory. The locations are given using a base pointer and a set of +// offsets. +// +// It is required that the user represents fields of each type in a standard +// way, so that GeneratedMessageReflection can cast the void* pointer to +// the appropriate type. For primitive fields and string fields, each field +// should be represented using the obvious C++ primitive type. Enums and +// Messages are different: +// - Singular Message fields are stored as a pointer to a Message. These +// should start out NULL, except for in the default instance where they +// should start out pointing to other default instances. +// - Enum fields are stored as an int. This int must always contain +// a valid value, such that EnumDescriptor::FindValueByNumber() would +// not return NULL. +// - Repeated fields are stored as RepeatedFields or RepeatedPtrFields +// of whatever type the individual field would be. Strings and +// Messages use RepeatedPtrFields while everything else uses +// RepeatedFields. +class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { + public: + // Constructs a GeneratedMessageReflection. + // Parameters: + // descriptor: The descriptor for the message type being implemented. + // default_instance: The default instance of the message. This is only + // used to obtain pointers to default instances of embedded + // messages, which GetMessage() will return if the particular + // sub-message has not been initialized yet. (Thus, all + // embedded message fields *must* have non-NULL pointers + // in the default instance.) + // offsets: An array of ints giving the byte offsets, relative to + // the start of the message object, of each field. These can + // be computed at compile time using the + // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined + // below. + // has_bits_offset: Offset in the message of an array of uint32s of size + // descriptor->field_count()/32, rounded up. This is a + // bitfield where each bit indicates whether or not the + // corresponding field of the message has been initialized. + // The bit for field index i is obtained by the expression: + // has_bits[i / 32] & (1 << (i % 32)) + // unknown_fields_offset: Offset in the message of the UnknownFieldSet for + // the message. + // extensions_offset: Offset in the message of the ExtensionSet for the + // message, or -1 if the message type has no extension + // ranges. + // pool: DescriptorPool to search for extension definitions. Only + // used by FindKnownExtensionByName() and + // FindKnownExtensionByNumber(). + // factory: MessageFactory to use to construct extension messages. + // object_size: The size of a message object of this type, as measured + // by sizeof(). + GeneratedMessageReflection(const Descriptor* descriptor, + const Message* default_instance, + const int offsets[], + int has_bits_offset, + int unknown_fields_offset, + int extensions_offset, + const DescriptorPool* pool, + MessageFactory* factory, + int object_size); + ~GeneratedMessageReflection(); + + // implements Reflection ------------------------------------------- + + const UnknownFieldSet& GetUnknownFields(const Message& message) const; + UnknownFieldSet* MutableUnknownFields(Message* message) const; + + int SpaceUsed(const Message& message) const; + + bool HasField(const Message& message, const FieldDescriptor* field) const; + int FieldSize(const Message& message, const FieldDescriptor* field) const; + void ClearField(Message* message, const FieldDescriptor* field) const; + void RemoveLast(Message* message, const FieldDescriptor* field) const; + Message* ReleaseLast(Message* message, const FieldDescriptor* field) const; + void Swap(Message* message1, Message* message2) const; + void SwapElements(Message* message, const FieldDescriptor* field, + int index1, int index2) const; + void ListFields(const Message& message, + vector* output) const; + + int32 GetInt32 (const Message& message, + const FieldDescriptor* field) const; + int64 GetInt64 (const Message& message, + const FieldDescriptor* field) const; + uint32 GetUInt32(const Message& message, + const FieldDescriptor* field) const; + uint64 GetUInt64(const Message& message, + const FieldDescriptor* field) const; + float GetFloat (const Message& message, + const FieldDescriptor* field) const; + double GetDouble(const Message& message, + const FieldDescriptor* field) const; + bool GetBool (const Message& message, + const FieldDescriptor* field) const; + string GetString(const Message& message, + const FieldDescriptor* field) const; + const string& GetStringReference(const Message& message, + const FieldDescriptor* field, + string* scratch) const; + const EnumValueDescriptor* GetEnum(const Message& message, + const FieldDescriptor* field) const; + const Message& GetMessage(const Message& message, + const FieldDescriptor* field, + MessageFactory* factory = NULL) const; + + void SetInt32 (Message* message, + const FieldDescriptor* field, int32 value) const; + void SetInt64 (Message* message, + const FieldDescriptor* field, int64 value) const; + void SetUInt32(Message* message, + const FieldDescriptor* field, uint32 value) const; + void SetUInt64(Message* message, + const FieldDescriptor* field, uint64 value) const; + void SetFloat (Message* message, + const FieldDescriptor* field, float value) const; + void SetDouble(Message* message, + const FieldDescriptor* field, double value) const; + void SetBool (Message* message, + const FieldDescriptor* field, bool value) const; + void SetString(Message* message, + const FieldDescriptor* field, + const string& value) const; + void SetEnum (Message* message, const FieldDescriptor* field, + const EnumValueDescriptor* value) const; + Message* MutableMessage(Message* message, const FieldDescriptor* field, + MessageFactory* factory = NULL) const; + Message* ReleaseMessage(Message* message, const FieldDescriptor* field, + MessageFactory* factory = NULL) const; + + int32 GetRepeatedInt32 (const Message& message, + const FieldDescriptor* field, int index) const; + int64 GetRepeatedInt64 (const Message& message, + const FieldDescriptor* field, int index) const; + uint32 GetRepeatedUInt32(const Message& message, + const FieldDescriptor* field, int index) const; + uint64 GetRepeatedUInt64(const Message& message, + const FieldDescriptor* field, int index) const; + float GetRepeatedFloat (const Message& message, + const FieldDescriptor* field, int index) const; + double GetRepeatedDouble(const Message& message, + const FieldDescriptor* field, int index) const; + bool GetRepeatedBool (const Message& message, + const FieldDescriptor* field, int index) const; + string GetRepeatedString(const Message& message, + const FieldDescriptor* field, int index) const; + const string& GetRepeatedStringReference(const Message& message, + const FieldDescriptor* field, + int index, string* scratch) const; + const EnumValueDescriptor* GetRepeatedEnum(const Message& message, + const FieldDescriptor* field, + int index) const; + const Message& GetRepeatedMessage(const Message& message, + const FieldDescriptor* field, + int index) const; + + // Set the value of a field. + void SetRepeatedInt32 (Message* message, + const FieldDescriptor* field, int index, int32 value) const; + void SetRepeatedInt64 (Message* message, + const FieldDescriptor* field, int index, int64 value) const; + void SetRepeatedUInt32(Message* message, + const FieldDescriptor* field, int index, uint32 value) const; + void SetRepeatedUInt64(Message* message, + const FieldDescriptor* field, int index, uint64 value) const; + void SetRepeatedFloat (Message* message, + const FieldDescriptor* field, int index, float value) const; + void SetRepeatedDouble(Message* message, + const FieldDescriptor* field, int index, double value) const; + void SetRepeatedBool (Message* message, + const FieldDescriptor* field, int index, bool value) const; + void SetRepeatedString(Message* message, + const FieldDescriptor* field, int index, + const string& value) const; + void SetRepeatedEnum(Message* message, const FieldDescriptor* field, + int index, const EnumValueDescriptor* value) const; + // Get a mutable pointer to a field with a message type. + Message* MutableRepeatedMessage(Message* message, + const FieldDescriptor* field, + int index) const; + + void AddInt32 (Message* message, + const FieldDescriptor* field, int32 value) const; + void AddInt64 (Message* message, + const FieldDescriptor* field, int64 value) const; + void AddUInt32(Message* message, + const FieldDescriptor* field, uint32 value) const; + void AddUInt64(Message* message, + const FieldDescriptor* field, uint64 value) const; + void AddFloat (Message* message, + const FieldDescriptor* field, float value) const; + void AddDouble(Message* message, + const FieldDescriptor* field, double value) const; + void AddBool (Message* message, + const FieldDescriptor* field, bool value) const; + void AddString(Message* message, + const FieldDescriptor* field, const string& value) const; + void AddEnum(Message* message, + const FieldDescriptor* field, + const EnumValueDescriptor* value) const; + Message* AddMessage(Message* message, const FieldDescriptor* field, + MessageFactory* factory = NULL) const; + + const FieldDescriptor* FindKnownExtensionByName(const string& name) const; + const FieldDescriptor* FindKnownExtensionByNumber(int number) const; + + protected: + virtual void* MutableRawRepeatedField( + Message* message, const FieldDescriptor* field, FieldDescriptor::CppType, + int ctype, const Descriptor* desc) const; + + private: + friend class GeneratedMessage; + + // To parse directly into a proto2 generated class, the class GMR_Handlers + // needs access to member offsets and hasbits. + friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers; + + const Descriptor* descriptor_; + const Message* default_instance_; + const int* offsets_; + + int has_bits_offset_; + int unknown_fields_offset_; + int extensions_offset_; + int object_size_; + + const DescriptorPool* descriptor_pool_; + MessageFactory* message_factory_; + + template + inline const Type& GetRaw(const Message& message, + const FieldDescriptor* field) const; + template + inline Type* MutableRaw(Message* message, + const FieldDescriptor* field) const; + template + inline const Type& DefaultRaw(const FieldDescriptor* field) const; + + inline const uint32* GetHasBits(const Message& message) const; + inline uint32* MutableHasBits(Message* message) const; + inline const ExtensionSet& GetExtensionSet(const Message& message) const; + inline ExtensionSet* MutableExtensionSet(Message* message) const; + + inline bool HasBit(const Message& message, + const FieldDescriptor* field) const; + inline void SetBit(Message* message, + const FieldDescriptor* field) const; + inline void ClearBit(Message* message, + const FieldDescriptor* field) const; + + template + inline const Type& GetField(const Message& message, + const FieldDescriptor* field) const; + template + inline void SetField(Message* message, + const FieldDescriptor* field, const Type& value) const; + template + inline Type* MutableField(Message* message, + const FieldDescriptor* field) const; + template + inline const Type& GetRepeatedField(const Message& message, + const FieldDescriptor* field, + int index) const; + template + inline const Type& GetRepeatedPtrField(const Message& message, + const FieldDescriptor* field, + int index) const; + template + inline void SetRepeatedField(Message* message, + const FieldDescriptor* field, int index, + Type value) const; + template + inline Type* MutableRepeatedField(Message* message, + const FieldDescriptor* field, + int index) const; + template + inline void AddField(Message* message, + const FieldDescriptor* field, const Type& value) const; + template + inline Type* AddField(Message* message, + const FieldDescriptor* field) const; + + int GetExtensionNumberOrDie(const Descriptor* type) const; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection); +}; + +// Returns the offset of the given field within the given aggregate type. +// This is equivalent to the ANSI C offsetof() macro. However, according +// to the C++ standard, offsetof() only works on POD types, and GCC +// enforces this requirement with a warning. In practice, this rule is +// unnecessarily strict; there is probably no compiler or platform on +// which the offsets of the direct fields of a class are non-constant. +// Fields inherited from superclasses *can* have non-constant offsets, +// but that's not what this macro will be used for. +// +// Note that we calculate relative to the pointer value 16 here since if we +// just use zero, GCC complains about dereferencing a NULL pointer. We +// choose 16 rather than some other number just in case the compiler would +// be confused by an unaligned pointer. +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ + static_cast( \ + reinterpret_cast( \ + &reinterpret_cast(16)->FIELD) - \ + reinterpret_cast(16)) + +// There are some places in proto2 where dynamic_cast would be useful as an +// optimization. For example, take Message::MergeFrom(const Message& other). +// For a given generated message FooMessage, we generate these two methods: +// void MergeFrom(const FooMessage& other); +// void MergeFrom(const Message& other); +// The former method can be implemented directly in terms of FooMessage's +// inline accessors, but the latter method must work with the reflection +// interface. However, if the parameter to the latter method is actually of +// type FooMessage, then we'd like to be able to just call the other method +// as an optimization. So, we use dynamic_cast to check this. +// +// That said, dynamic_cast requires RTTI, which many people like to disable +// for performance and code size reasons. When RTTI is not available, we +// still need to produce correct results. So, in this case we have to fall +// back to using reflection, which is what we would have done anyway if the +// objects were not of the exact same class. +// +// dynamic_cast_if_available() implements this logic. If RTTI is +// enabled, it does a dynamic_cast. If RTTI is disabled, it just returns +// NULL. +// +// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI. +// On MSVC, this should be detected automatically. +template +inline To dynamic_cast_if_available(From from) { +#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI)) + return NULL; +#else + return dynamic_cast(from); +#endif +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection_unittest.cc new file mode 100644 index 0000000..39aa55f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_reflection_unittest.cc @@ -0,0 +1,484 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// To test GeneratedMessageReflection, we actually let the protocol compiler +// generate a full protocol message implementation and then test its +// reflection interface. This is much easier and more maintainable than +// trying to create our own Message class for GeneratedMessageReflection +// to wrap. +// +// The tests here closely mirror some of the tests in +// compiler/cpp/unittest, except using the reflection interface +// rather than generated accessors. + +#include +#include +#include +#include + +#include +#include +#include + +namespace google { +namespace protobuf { + +namespace { + +// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. +const FieldDescriptor* F(const string& name) { + const FieldDescriptor* result = + unittest::TestAllTypes::descriptor()->FindFieldByName(name); + GOOGLE_CHECK(result != NULL); + return result; +} + +TEST(GeneratedMessageReflectionTest, Defaults) { + // Check that all default values are set correctly in the initial message. + unittest::TestAllTypes message; + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllTypes::descriptor()); + + reflection_tester.ExpectClearViaReflection(message); + + const Reflection* reflection = message.GetReflection(); + + // Messages should return pointers to default instances until first use. + // (This is not checked by ExpectClear() since it is not actually true after + // the fields have been set and then cleared.) + EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(), + &reflection->GetMessage(message, F("optionalgroup"))); + EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), + &reflection->GetMessage(message, F("optional_nested_message"))); + EXPECT_EQ(&unittest::ForeignMessage::default_instance(), + &reflection->GetMessage(message, F("optional_foreign_message"))); + EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), + &reflection->GetMessage(message, F("optional_import_message"))); +} + +TEST(GeneratedMessageReflectionTest, Accessors) { + // Set every field to a unique value then go back and check all those + // values. + unittest::TestAllTypes message; + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllTypes::descriptor()); + + reflection_tester.SetAllFieldsViaReflection(&message); + TestUtil::ExpectAllFieldsSet(message); + reflection_tester.ExpectAllFieldsSetViaReflection(message); + + reflection_tester.ModifyRepeatedFieldsViaReflection(&message); + TestUtil::ExpectRepeatedFieldsModified(message); +} + +TEST(GeneratedMessageReflectionTest, GetStringReference) { + // Test that GetStringReference() returns the underlying string when it is + // a normal string field. + unittest::TestAllTypes message; + message.set_optional_string("foo"); + message.add_repeated_string("foo"); + + const Reflection* reflection = message.GetReflection(); + string scratch; + + EXPECT_EQ(&message.optional_string(), + &reflection->GetStringReference(message, F("optional_string"), &scratch)) + << "For simple string fields, GetStringReference() should return a " + "reference to the underlying string."; + EXPECT_EQ(&message.repeated_string(0), + &reflection->GetRepeatedStringReference(message, F("repeated_string"), + 0, &scratch)) + << "For simple string fields, GetRepeatedStringReference() should return " + "a reference to the underlying string."; +} + + +TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) { + // Check that after setting all fields and then clearing, getting an + // embedded message does NOT return the default instance. + unittest::TestAllTypes message; + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllTypes::descriptor()); + + TestUtil::SetAllFields(&message); + message.Clear(); + + const Reflection* reflection = message.GetReflection(); + + EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), + &reflection->GetMessage(message, F("optionalgroup"))); + EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), + &reflection->GetMessage(message, F("optional_nested_message"))); + EXPECT_NE(&unittest::ForeignMessage::default_instance(), + &reflection->GetMessage(message, F("optional_foreign_message"))); + EXPECT_NE(&unittest_import::ImportMessage::default_instance(), + &reflection->GetMessage(message, F("optional_import_message"))); +} + + +TEST(GeneratedMessageReflectionTest, Swap) { + unittest::TestAllTypes message1; + unittest::TestAllTypes message2; + + TestUtil::SetAllFields(&message1); + + const Reflection* reflection = message1.GetReflection(); + reflection->Swap(&message1, &message2); + + TestUtil::ExpectClear(message1); + TestUtil::ExpectAllFieldsSet(message2); +} + +TEST(GeneratedMessageReflectionTest, SwapWithBothSet) { + unittest::TestAllTypes message1; + unittest::TestAllTypes message2; + + TestUtil::SetAllFields(&message1); + TestUtil::SetAllFields(&message2); + TestUtil::ModifyRepeatedFields(&message2); + + const Reflection* reflection = message1.GetReflection(); + reflection->Swap(&message1, &message2); + + TestUtil::ExpectRepeatedFieldsModified(message1); + TestUtil::ExpectAllFieldsSet(message2); + + message1.set_optional_int32(532819); + + reflection->Swap(&message1, &message2); + + EXPECT_EQ(532819, message2.optional_int32()); +} + +TEST(GeneratedMessageReflectionTest, SwapExtensions) { + unittest::TestAllExtensions message1; + unittest::TestAllExtensions message2; + + TestUtil::SetAllExtensions(&message1); + + const Reflection* reflection = message1.GetReflection(); + reflection->Swap(&message1, &message2); + + TestUtil::ExpectExtensionsClear(message1); + TestUtil::ExpectAllExtensionsSet(message2); +} + +TEST(GeneratedMessageReflectionTest, SwapUnknown) { + unittest::TestEmptyMessage message1, message2; + + message1.mutable_unknown_fields()->AddVarint(1234, 1); + + EXPECT_EQ(1, message1.unknown_fields().field_count()); + EXPECT_EQ(0, message2.unknown_fields().field_count()); + const Reflection* reflection = message1.GetReflection(); + reflection->Swap(&message1, &message2); + EXPECT_EQ(0, message1.unknown_fields().field_count()); + EXPECT_EQ(1, message2.unknown_fields().field_count()); +} + +TEST(GeneratedMessageReflectionTest, RemoveLast) { + unittest::TestAllTypes message; + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllTypes::descriptor()); + + TestUtil::SetAllFields(&message); + + reflection_tester.RemoveLastRepeatedsViaReflection(&message); + + TestUtil::ExpectLastRepeatedsRemoved(message); +} + +TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) { + unittest::TestAllExtensions message; + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllExtensions::descriptor()); + + TestUtil::SetAllExtensions(&message); + + reflection_tester.RemoveLastRepeatedsViaReflection(&message); + + TestUtil::ExpectLastRepeatedExtensionsRemoved(message); +} + +TEST(GeneratedMessageReflectionTest, ReleaseLast) { + unittest::TestAllTypes message; + const Descriptor* descriptor = message.GetDescriptor(); + TestUtil::ReflectionTester reflection_tester(descriptor); + + TestUtil::SetAllFields(&message); + + reflection_tester.ReleaseLastRepeatedsViaReflection(&message, false); + + TestUtil::ExpectLastRepeatedsReleased(message); + + // Now test that we actually release the right message. + message.Clear(); + TestUtil::SetAllFields(&message); + ASSERT_EQ(2, message.repeated_foreign_message_size()); + const protobuf_unittest::ForeignMessage* expected = + message.mutable_repeated_foreign_message(1); + scoped_ptr released(message.GetReflection()->ReleaseLast( + &message, descriptor->FindFieldByName("repeated_foreign_message"))); + EXPECT_EQ(expected, released.get()); +} + +TEST(GeneratedMessageReflectionTest, ReleaseLastExtensions) { + unittest::TestAllExtensions message; + const Descriptor* descriptor = message.GetDescriptor(); + TestUtil::ReflectionTester reflection_tester(descriptor); + + TestUtil::SetAllExtensions(&message); + + reflection_tester.ReleaseLastRepeatedsViaReflection(&message, true); + + TestUtil::ExpectLastRepeatedExtensionsReleased(message); + + // Now test that we actually release the right message. + message.Clear(); + TestUtil::SetAllExtensions(&message); + ASSERT_EQ(2, message.ExtensionSize( + unittest::repeated_foreign_message_extension)); + const protobuf_unittest::ForeignMessage* expected = message.MutableExtension( + unittest::repeated_foreign_message_extension, 1); + scoped_ptr released(message.GetReflection()->ReleaseLast( + &message, descriptor->file()->FindExtensionByName( + "repeated_foreign_message_extension"))); + EXPECT_EQ(expected, released.get()); + +} + +TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) { + unittest::TestAllTypes message; + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllTypes::descriptor()); + + TestUtil::SetAllFields(&message); + + // Swap and test that fields are all swapped. + reflection_tester.SwapRepeatedsViaReflection(&message); + TestUtil::ExpectRepeatedsSwapped(message); + + // Swap back and test that fields are all back to original values. + reflection_tester.SwapRepeatedsViaReflection(&message); + TestUtil::ExpectAllFieldsSet(message); +} + +TEST(GeneratedMessageReflectionTest, SwapRepeatedElementsExtension) { + unittest::TestAllExtensions message; + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllExtensions::descriptor()); + + TestUtil::SetAllExtensions(&message); + + // Swap and test that fields are all swapped. + reflection_tester.SwapRepeatedsViaReflection(&message); + TestUtil::ExpectRepeatedExtensionsSwapped(message); + + // Swap back and test that fields are all back to original values. + reflection_tester.SwapRepeatedsViaReflection(&message); + TestUtil::ExpectAllExtensionsSet(message); +} + +TEST(GeneratedMessageReflectionTest, Extensions) { + // Set every extension to a unique value then go back and check all those + // values. + unittest::TestAllExtensions message; + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllExtensions::descriptor()); + + reflection_tester.SetAllFieldsViaReflection(&message); + TestUtil::ExpectAllExtensionsSet(message); + reflection_tester.ExpectAllFieldsSetViaReflection(message); + + reflection_tester.ModifyRepeatedFieldsViaReflection(&message); + TestUtil::ExpectRepeatedExtensionsModified(message); +} + +TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) { + const Reflection* reflection = + unittest::TestAllExtensions::default_instance().GetReflection(); + + const FieldDescriptor* extension1 = + unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( + "optional_int32_extension"); + const FieldDescriptor* extension2 = + unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( + "repeated_string_extension"); + + EXPECT_EQ(extension1, + reflection->FindKnownExtensionByNumber(extension1->number())); + EXPECT_EQ(extension2, + reflection->FindKnownExtensionByNumber(extension2->number())); + + // Non-existent extension. + EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == NULL); + + // Extensions of TestAllExtensions should not show up as extensions of + // other types. + EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> + FindKnownExtensionByNumber(extension1->number()) == NULL); +} + +TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) { + const Reflection* reflection = + unittest::TestAllExtensions::default_instance().GetReflection(); + + const FieldDescriptor* extension1 = + unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( + "optional_int32_extension"); + const FieldDescriptor* extension2 = + unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( + "repeated_string_extension"); + + EXPECT_EQ(extension1, + reflection->FindKnownExtensionByName(extension1->full_name())); + EXPECT_EQ(extension2, + reflection->FindKnownExtensionByName(extension2->full_name())); + + // Non-existent extension. + EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == NULL); + + // Extensions of TestAllExtensions should not show up as extensions of + // other types. + EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> + FindKnownExtensionByName(extension1->full_name()) == NULL); +} + +TEST(GeneratedMessageReflectionTest, ReleaseMessageTest) { + unittest::TestAllTypes message; + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllTypes::descriptor()); + + // When nothing is set, we expect all released messages to be NULL. + reflection_tester.ExpectMessagesReleasedViaReflection( + &message, TestUtil::ReflectionTester::IS_NULL); + + // After fields are set we should get non-NULL releases. + reflection_tester.SetAllFieldsViaReflection(&message); + reflection_tester.ExpectMessagesReleasedViaReflection( + &message, TestUtil::ReflectionTester::NOT_NULL); + + // After Clear() we may or may not get a message from ReleaseMessage(). + // This is implementation specific. + reflection_tester.SetAllFieldsViaReflection(&message); + message.Clear(); + reflection_tester.ExpectMessagesReleasedViaReflection( + &message, TestUtil::ReflectionTester::CAN_BE_NULL); + + // Test a different code path for setting after releasing. + TestUtil::SetAllFields(&message); + TestUtil::ExpectAllFieldsSet(message); +} + +TEST(GeneratedMessageReflectionTest, ReleaseExtensionMessageTest) { + unittest::TestAllExtensions message; + TestUtil::ReflectionTester reflection_tester( + unittest::TestAllExtensions::descriptor()); + + // When nothing is set, we expect all released messages to be NULL. + reflection_tester.ExpectMessagesReleasedViaReflection( + &message, TestUtil::ReflectionTester::IS_NULL); + + // After fields are set we should get non-NULL releases. + reflection_tester.SetAllFieldsViaReflection(&message); + reflection_tester.ExpectMessagesReleasedViaReflection( + &message, TestUtil::ReflectionTester::NOT_NULL); + + // After Clear() we may or may not get a message from ReleaseMessage(). + // This is implementation specific. + reflection_tester.SetAllFieldsViaReflection(&message); + message.Clear(); + reflection_tester.ExpectMessagesReleasedViaReflection( + &message, TestUtil::ReflectionTester::CAN_BE_NULL); + + // Test a different code path for setting after releasing. + TestUtil::SetAllExtensions(&message); + TestUtil::ExpectAllExtensionsSet(message); +} + +#ifdef PROTOBUF_HAS_DEATH_TEST + +TEST(GeneratedMessageReflectionTest, UsageErrors) { + unittest::TestAllTypes message; + const Reflection* reflection = message.GetReflection(); + const Descriptor* descriptor = message.GetDescriptor(); + +#define f(NAME) descriptor->FindFieldByName(NAME) + + // Testing every single failure mode would be too much work. Let's just + // check a few. + EXPECT_DEATH( + reflection->GetInt32( + message, descriptor->FindFieldByName("optional_int64")), + "Protocol Buffer reflection usage error:\n" + " Method : google::protobuf::Reflection::GetInt32\n" + " Message type: protobuf_unittest\\.TestAllTypes\n" + " Field : protobuf_unittest\\.TestAllTypes\\.optional_int64\n" + " Problem : Field is not the right type for this message:\n" + " Expected : CPPTYPE_INT32\n" + " Field type: CPPTYPE_INT64"); + EXPECT_DEATH( + reflection->GetInt32( + message, descriptor->FindFieldByName("repeated_int32")), + "Protocol Buffer reflection usage error:\n" + " Method : google::protobuf::Reflection::GetInt32\n" + " Message type: protobuf_unittest.TestAllTypes\n" + " Field : protobuf_unittest.TestAllTypes.repeated_int32\n" + " Problem : Field is repeated; the method requires a singular field."); + EXPECT_DEATH( + reflection->GetInt32( + message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), + "Protocol Buffer reflection usage error:\n" + " Method : google::protobuf::Reflection::GetInt32\n" + " Message type: protobuf_unittest.TestAllTypes\n" + " Field : protobuf_unittest.ForeignMessage.c\n" + " Problem : Field does not match message type."); + EXPECT_DEATH( + reflection->HasField( + message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), + "Protocol Buffer reflection usage error:\n" + " Method : google::protobuf::Reflection::HasField\n" + " Message type: protobuf_unittest.TestAllTypes\n" + " Field : protobuf_unittest.ForeignMessage.c\n" + " Problem : Field does not match message type."); + +#undef f +} + +#endif // PROTOBUF_HAS_DEATH_TEST + + +} // namespace +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_util.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_util.cc new file mode 100644 index 0000000..ac32150 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_util.cc @@ -0,0 +1,54 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include + +namespace google { +namespace protobuf { +namespace internal { + +double Infinity() { + return std::numeric_limits::infinity(); +} +double NaN() { + return std::numeric_limits::quiet_NaN(); +} + +const ::std::string kEmptyString; + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_util.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_util.h new file mode 100644 index 0000000..b2fb8f0 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/generated_message_util.h @@ -0,0 +1,77 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains miscellaneous helper code used by generated code -- +// including lite types -- but which should not be used directly by users. + +#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ + +#include + +#include +namespace google { +namespace protobuf { +namespace internal { + +// Annotation for the compiler to emit a deprecation message if a field marked +// with option 'deprecated=true' is used in the code, or for other things in +// generated code which are deprecated. +// +// For internal use in the pb.cc files, deprecation warnings are suppressed +// there. +#undef DEPRECATED_PROTOBUF_FIELD +#define PROTOBUF_DEPRECATED + + +// Constants for special floating point values. +LIBPROTOBUF_EXPORT double Infinity(); +LIBPROTOBUF_EXPORT double NaN(); + +// Constant used for empty default strings. +LIBPROTOBUF_EXPORT extern const ::std::string kEmptyString; + +// Defined in generated_message_reflection.cc -- not actually part of the lite +// library. +// +// TODO(jasonh): The various callers get this declaration from a variety of +// places: probably in most cases repeated_field.h. Clean these up so they all +// get the declaration from this file. +LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str); + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream.cc new file mode 100644 index 0000000..36add8c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream.cc @@ -0,0 +1,857 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This implementation is heavily optimized to make reads and writes +// of small values (especially varints) as fast as possible. In +// particular, we optimize for the common case that a read or a write +// will not cross the end of the buffer, since we can avoid a lot +// of branching in this case. + +#include +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace io { + +namespace { + +static const int kMaxVarintBytes = 10; +static const int kMaxVarint32Bytes = 5; + + +inline bool NextNonEmpty(ZeroCopyInputStream* input, + const void** data, int* size) { + bool success; + do { + success = input->Next(data, size); + } while (success && *size == 0); + return success; +} + +} // namespace + +// CodedInputStream ================================================== + +CodedInputStream::~CodedInputStream() { + if (input_ != NULL) { + BackUpInputToCurrentPosition(); + } + + if (total_bytes_warning_threshold_ == -2) { + GOOGLE_LOG(WARNING) << "The total number of bytes read was " << total_bytes_read_; + } +} + +// Static. +int CodedInputStream::default_recursion_limit_ = 100; + + +void CodedInputStream::BackUpInputToCurrentPosition() { + int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_; + if (backup_bytes > 0) { + input_->BackUp(backup_bytes); + + // total_bytes_read_ doesn't include overflow_bytes_. + total_bytes_read_ -= BufferSize() + buffer_size_after_limit_; + buffer_end_ = buffer_; + buffer_size_after_limit_ = 0; + overflow_bytes_ = 0; + } +} + +inline void CodedInputStream::RecomputeBufferLimits() { + buffer_end_ += buffer_size_after_limit_; + int closest_limit = min(current_limit_, total_bytes_limit_); + if (closest_limit < total_bytes_read_) { + // The limit position is in the current buffer. We must adjust + // the buffer size accordingly. + buffer_size_after_limit_ = total_bytes_read_ - closest_limit; + buffer_end_ -= buffer_size_after_limit_; + } else { + buffer_size_after_limit_ = 0; + } +} + +CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) { + // Current position relative to the beginning of the stream. + int current_position = CurrentPosition(); + + Limit old_limit = current_limit_; + + // security: byte_limit is possibly evil, so check for negative values + // and overflow. + if (byte_limit >= 0 && + byte_limit <= INT_MAX - current_position) { + current_limit_ = current_position + byte_limit; + } else { + // Negative or overflow. + current_limit_ = INT_MAX; + } + + // We need to enforce all limits, not just the new one, so if the previous + // limit was before the new requested limit, we continue to enforce the + // previous limit. + current_limit_ = min(current_limit_, old_limit); + + RecomputeBufferLimits(); + return old_limit; +} + +void CodedInputStream::PopLimit(Limit limit) { + // The limit passed in is actually the *old* limit, which we returned from + // PushLimit(). + current_limit_ = limit; + RecomputeBufferLimits(); + + // We may no longer be at a legitimate message end. ReadTag() needs to be + // called again to find out. + legitimate_message_end_ = false; +} + +int CodedInputStream::BytesUntilLimit() const { + if (current_limit_ == INT_MAX) return -1; + int current_position = CurrentPosition(); + + return current_limit_ - current_position; +} + +void CodedInputStream::SetTotalBytesLimit( + int total_bytes_limit, int warning_threshold) { + // Make sure the limit isn't already past, since this could confuse other + // code. + int current_position = CurrentPosition(); + total_bytes_limit_ = max(current_position, total_bytes_limit); + if (warning_threshold >= 0) { + total_bytes_warning_threshold_ = warning_threshold; + } else { + // warning_threshold is negative + total_bytes_warning_threshold_ = -1; + } + RecomputeBufferLimits(); +} + +void CodedInputStream::PrintTotalBytesLimitError() { + GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too " + "big (more than " << total_bytes_limit_ + << " bytes). To increase the limit (or to disable these " + "warnings), see CodedInputStream::SetTotalBytesLimit() " + "in google/protobuf/io/coded_stream.h."; +} + +bool CodedInputStream::Skip(int count) { + if (count < 0) return false; // security: count is often user-supplied + + const int original_buffer_size = BufferSize(); + + if (count <= original_buffer_size) { + // Just skipping within the current buffer. Easy. + Advance(count); + return true; + } + + if (buffer_size_after_limit_ > 0) { + // We hit a limit inside this buffer. Advance to the limit and fail. + Advance(original_buffer_size); + return false; + } + + count -= original_buffer_size; + buffer_ = NULL; + buffer_end_ = buffer_; + + // Make sure this skip doesn't try to skip past the current limit. + int closest_limit = min(current_limit_, total_bytes_limit_); + int bytes_until_limit = closest_limit - total_bytes_read_; + if (bytes_until_limit < count) { + // We hit the limit. Skip up to it then fail. + if (bytes_until_limit > 0) { + total_bytes_read_ = closest_limit; + input_->Skip(bytes_until_limit); + } + return false; + } + + total_bytes_read_ += count; + return input_->Skip(count); +} + +bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) { + if (BufferSize() == 0 && !Refresh()) return false; + + *data = buffer_; + *size = BufferSize(); + return true; +} + +bool CodedInputStream::ReadRaw(void* buffer, int size) { + int current_buffer_size; + while ((current_buffer_size = BufferSize()) < size) { + // Reading past end of buffer. Copy what we have, then refresh. + memcpy(buffer, buffer_, current_buffer_size); + buffer = reinterpret_cast(buffer) + current_buffer_size; + size -= current_buffer_size; + Advance(current_buffer_size); + if (!Refresh()) return false; + } + + memcpy(buffer, buffer_, size); + Advance(size); + + return true; +} + +bool CodedInputStream::ReadString(string* buffer, int size) { + if (size < 0) return false; // security: size is often user-supplied + return InternalReadStringInline(buffer, size); +} + +bool CodedInputStream::ReadStringFallback(string* buffer, int size) { + if (!buffer->empty()) { + buffer->clear(); + } + + int current_buffer_size; + while ((current_buffer_size = BufferSize()) < size) { + // Some STL implementations "helpfully" crash on buffer->append(NULL, 0). + if (current_buffer_size != 0) { + // Note: string1.append(string2) is O(string2.size()) (as opposed to + // O(string1.size() + string2.size()), which would be bad). + buffer->append(reinterpret_cast(buffer_), + current_buffer_size); + } + size -= current_buffer_size; + Advance(current_buffer_size); + if (!Refresh()) return false; + } + + buffer->append(reinterpret_cast(buffer_), size); + Advance(size); + + return true; +} + + +bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) { + uint8 bytes[sizeof(*value)]; + + const uint8* ptr; + if (BufferSize() >= sizeof(*value)) { + // Fast path: Enough bytes in the buffer to read directly. + ptr = buffer_; + Advance(sizeof(*value)); + } else { + // Slow path: Had to read past the end of the buffer. + if (!ReadRaw(bytes, sizeof(*value))) return false; + ptr = bytes; + } + ReadLittleEndian32FromArray(ptr, value); + return true; +} + +bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) { + uint8 bytes[sizeof(*value)]; + + const uint8* ptr; + if (BufferSize() >= sizeof(*value)) { + // Fast path: Enough bytes in the buffer to read directly. + ptr = buffer_; + Advance(sizeof(*value)); + } else { + // Slow path: Had to read past the end of the buffer. + if (!ReadRaw(bytes, sizeof(*value))) return false; + ptr = bytes; + } + ReadLittleEndian64FromArray(ptr, value); + return true; +} + +namespace { + +inline const uint8* ReadVarint32FromArray( + const uint8* buffer, uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; +inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) { + // Fast path: We have enough bytes left in the buffer to guarantee that + // this read won't cross the end, so we can skip the checks. + const uint8* ptr = buffer; + uint32 b; + uint32 result; + + b = *(ptr++); result = (b & 0x7F) ; if (!(b & 0x80)) goto done; + b = *(ptr++); result |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; + b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; + b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; + b = *(ptr++); result |= b << 28; if (!(b & 0x80)) goto done; + + // If the input is larger than 32 bits, we still need to read it all + // and discard the high-order bits. + for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) { + b = *(ptr++); if (!(b & 0x80)) goto done; + } + + // We have overrun the maximum size of a varint (10 bytes). Assume + // the data is corrupt. + return NULL; + + done: + *value = result; + return ptr; +} + +} // namespace + +bool CodedInputStream::ReadVarint32Slow(uint32* value) { + uint64 result; + // Directly invoke ReadVarint64Fallback, since we already tried to optimize + // for one-byte varints. + if (!ReadVarint64Fallback(&result)) return false; + *value = (uint32)result; + return true; +} + +bool CodedInputStream::ReadVarint32Fallback(uint32* value) { + if (BufferSize() >= kMaxVarintBytes || + // Optimization: If the varint ends at exactly the end of the buffer, + // we can detect that and still use the fast path. + (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { + const uint8* end = ReadVarint32FromArray(buffer_, value); + if (end == NULL) return false; + buffer_ = end; + return true; + } else { + // Really slow case: we will incur the cost of an extra function call here, + // but moving this out of line reduces the size of this function, which + // improves the common case. In micro benchmarks, this is worth about 10-15% + return ReadVarint32Slow(value); + } +} + +uint32 CodedInputStream::ReadTagSlow() { + if (buffer_ == buffer_end_) { + // Call refresh. + if (!Refresh()) { + // Refresh failed. Make sure that it failed due to EOF, not because + // we hit total_bytes_limit_, which, unlike normal limits, is not a + // valid place to end a message. + int current_position = total_bytes_read_ - buffer_size_after_limit_; + if (current_position >= total_bytes_limit_) { + // Hit total_bytes_limit_. But if we also hit the normal limit, + // we're still OK. + legitimate_message_end_ = current_limit_ == total_bytes_limit_; + } else { + legitimate_message_end_ = true; + } + return 0; + } + } + + // For the slow path, just do a 64-bit read. Try to optimize for one-byte tags + // again, since we have now refreshed the buffer. + uint64 result = 0; + if (!ReadVarint64(&result)) return 0; + return static_cast(result); +} + +uint32 CodedInputStream::ReadTagFallback() { + const int buf_size = BufferSize(); + if (buf_size >= kMaxVarintBytes || + // Optimization: If the varint ends at exactly the end of the buffer, + // we can detect that and still use the fast path. + (buf_size > 0 && !(buffer_end_[-1] & 0x80))) { + uint32 tag; + const uint8* end = ReadVarint32FromArray(buffer_, &tag); + if (end == NULL) { + return 0; + } + buffer_ = end; + return tag; + } else { + // We are commonly at a limit when attempting to read tags. Try to quickly + // detect this case without making another function call. + if ((buf_size == 0) && + ((buffer_size_after_limit_ > 0) || + (total_bytes_read_ == current_limit_)) && + // Make sure that the limit we hit is not total_bytes_limit_, since + // in that case we still need to call Refresh() so that it prints an + // error. + total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) { + // We hit a byte limit. + legitimate_message_end_ = true; + return 0; + } + return ReadTagSlow(); + } +} + +bool CodedInputStream::ReadVarint64Slow(uint64* value) { + // Slow path: This read might cross the end of the buffer, so we + // need to check and refresh the buffer if and when it does. + + uint64 result = 0; + int count = 0; + uint32 b; + + do { + if (count == kMaxVarintBytes) return false; + while (buffer_ == buffer_end_) { + if (!Refresh()) return false; + } + b = *buffer_; + result |= static_cast(b & 0x7F) << (7 * count); + Advance(1); + ++count; + } while (b & 0x80); + + *value = result; + return true; +} + +bool CodedInputStream::ReadVarint64Fallback(uint64* value) { + if (BufferSize() >= kMaxVarintBytes || + // Optimization: If the varint ends at exactly the end of the buffer, + // we can detect that and still use the fast path. + (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { + // Fast path: We have enough bytes left in the buffer to guarantee that + // this read won't cross the end, so we can skip the checks. + + const uint8* ptr = buffer_; + uint32 b; + + // Splitting into 32-bit pieces gives better performance on 32-bit + // processors. + uint32 part0 = 0, part1 = 0, part2 = 0; + + b = *(ptr++); part0 = (b & 0x7F) ; if (!(b & 0x80)) goto done; + b = *(ptr++); part0 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; + b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; + b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; + b = *(ptr++); part1 = (b & 0x7F) ; if (!(b & 0x80)) goto done; + b = *(ptr++); part1 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; + b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; + b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; + b = *(ptr++); part2 = (b & 0x7F) ; if (!(b & 0x80)) goto done; + b = *(ptr++); part2 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; + + // We have overrun the maximum size of a varint (10 bytes). The data + // must be corrupt. + return false; + + done: + Advance(ptr - buffer_); + *value = (static_cast(part0) ) | + (static_cast(part1) << 28) | + (static_cast(part2) << 56); + return true; + } else { + return ReadVarint64Slow(value); + } +} + +bool CodedInputStream::Refresh() { + GOOGLE_DCHECK_EQ(0, BufferSize()); + + if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 || + total_bytes_read_ == current_limit_) { + // We've hit a limit. Stop. + int current_position = total_bytes_read_ - buffer_size_after_limit_; + + if (current_position >= total_bytes_limit_ && + total_bytes_limit_ != current_limit_) { + // Hit total_bytes_limit_. + PrintTotalBytesLimitError(); + } + + return false; + } + + if (total_bytes_warning_threshold_ >= 0 && + total_bytes_read_ >= total_bytes_warning_threshold_) { + GOOGLE_LOG(WARNING) << "Reading dangerously large protocol message. If the " + "message turns out to be larger than " + << total_bytes_limit_ << " bytes, parsing will be halted " + "for security reasons. To increase the limit (or to " + "disable these warnings), see " + "CodedInputStream::SetTotalBytesLimit() in " + "google/protobuf/io/coded_stream.h."; + + // Don't warn again for this stream, and print total size at the end. + total_bytes_warning_threshold_ = -2; + } + + const void* void_buffer; + int buffer_size; + if (NextNonEmpty(input_, &void_buffer, &buffer_size)) { + buffer_ = reinterpret_cast(void_buffer); + buffer_end_ = buffer_ + buffer_size; + GOOGLE_CHECK_GE(buffer_size, 0); + + if (total_bytes_read_ <= INT_MAX - buffer_size) { + total_bytes_read_ += buffer_size; + } else { + // Overflow. Reset buffer_end_ to not include the bytes beyond INT_MAX. + // We can't get that far anyway, because total_bytes_limit_ is guaranteed + // to be less than it. We need to keep track of the number of bytes + // we discarded, though, so that we can call input_->BackUp() to back + // up over them on destruction. + + // The following line is equivalent to: + // overflow_bytes_ = total_bytes_read_ + buffer_size - INT_MAX; + // except that it avoids overflows. Signed integer overflow has + // undefined results according to the C standard. + overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size); + buffer_end_ -= overflow_bytes_; + total_bytes_read_ = INT_MAX; + } + + RecomputeBufferLimits(); + return true; + } else { + buffer_ = NULL; + buffer_end_ = NULL; + return false; + } +} + +// CodedOutputStream ================================================= + +CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output) + : output_(output), + buffer_(NULL), + buffer_size_(0), + total_bytes_(0), + had_error_(false) { + // Eagerly Refresh() so buffer space is immediately available. + Refresh(); + // The Refresh() may have failed. If the client doesn't write any data, + // though, don't consider this an error. If the client does write data, then + // another Refresh() will be attempted and it will set the error once again. + had_error_ = false; +} + +CodedOutputStream::~CodedOutputStream() { + if (buffer_size_ > 0) { + output_->BackUp(buffer_size_); + } +} + +bool CodedOutputStream::Skip(int count) { + if (count < 0) return false; + + while (count > buffer_size_) { + count -= buffer_size_; + if (!Refresh()) return false; + } + + Advance(count); + return true; +} + +bool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) { + if (buffer_size_ == 0 && !Refresh()) return false; + + *data = buffer_; + *size = buffer_size_; + return true; +} + +void CodedOutputStream::WriteRaw(const void* data, int size) { + while (buffer_size_ < size) { + memcpy(buffer_, data, buffer_size_); + size -= buffer_size_; + data = reinterpret_cast(data) + buffer_size_; + if (!Refresh()) return; + } + + memcpy(buffer_, data, size); + Advance(size); +} + +uint8* CodedOutputStream::WriteRawToArray( + const void* data, int size, uint8* target) { + memcpy(target, data, size); + return target + size; +} + + +void CodedOutputStream::WriteLittleEndian32(uint32 value) { + uint8 bytes[sizeof(value)]; + + bool use_fast = buffer_size_ >= sizeof(value); + uint8* ptr = use_fast ? buffer_ : bytes; + + WriteLittleEndian32ToArray(value, ptr); + + if (use_fast) { + Advance(sizeof(value)); + } else { + WriteRaw(bytes, sizeof(value)); + } +} + +void CodedOutputStream::WriteLittleEndian64(uint64 value) { + uint8 bytes[sizeof(value)]; + + bool use_fast = buffer_size_ >= sizeof(value); + uint8* ptr = use_fast ? buffer_ : bytes; + + WriteLittleEndian64ToArray(value, ptr); + + if (use_fast) { + Advance(sizeof(value)); + } else { + WriteRaw(bytes, sizeof(value)); + } +} + +inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline( + uint32 value, uint8* target) { + target[0] = static_cast(value | 0x80); + if (value >= (1 << 7)) { + target[1] = static_cast((value >> 7) | 0x80); + if (value >= (1 << 14)) { + target[2] = static_cast((value >> 14) | 0x80); + if (value >= (1 << 21)) { + target[3] = static_cast((value >> 21) | 0x80); + if (value >= (1 << 28)) { + target[4] = static_cast(value >> 28); + return target + 5; + } else { + target[3] &= 0x7F; + return target + 4; + } + } else { + target[2] &= 0x7F; + return target + 3; + } + } else { + target[1] &= 0x7F; + return target + 2; + } + } else { + target[0] &= 0x7F; + return target + 1; + } +} + +void CodedOutputStream::WriteVarint32(uint32 value) { + if (buffer_size_ >= kMaxVarint32Bytes) { + // Fast path: We have enough bytes left in the buffer to guarantee that + // this write won't cross the end, so we can skip the checks. + uint8* target = buffer_; + uint8* end = WriteVarint32FallbackToArrayInline(value, target); + int size = end - target; + Advance(size); + } else { + // Slow path: This write might cross the end of the buffer, so we + // compose the bytes first then use WriteRaw(). + uint8 bytes[kMaxVarint32Bytes]; + int size = 0; + while (value > 0x7F) { + bytes[size++] = (static_cast(value) & 0x7F) | 0x80; + value >>= 7; + } + bytes[size++] = static_cast(value) & 0x7F; + WriteRaw(bytes, size); + } +} + +uint8* CodedOutputStream::WriteVarint32FallbackToArray( + uint32 value, uint8* target) { + return WriteVarint32FallbackToArrayInline(value, target); +} + +inline uint8* CodedOutputStream::WriteVarint64ToArrayInline( + uint64 value, uint8* target) { + // Splitting into 32-bit pieces gives better performance on 32-bit + // processors. + uint32 part0 = static_cast(value ); + uint32 part1 = static_cast(value >> 28); + uint32 part2 = static_cast(value >> 56); + + int size; + + // Here we can't really optimize for small numbers, since the value is + // split into three parts. Cheking for numbers < 128, for instance, + // would require three comparisons, since you'd have to make sure part1 + // and part2 are zero. However, if the caller is using 64-bit integers, + // it is likely that they expect the numbers to often be very large, so + // we probably don't want to optimize for small numbers anyway. Thus, + // we end up with a hardcoded binary search tree... + if (part2 == 0) { + if (part1 == 0) { + if (part0 < (1 << 14)) { + if (part0 < (1 << 7)) { + size = 1; goto size1; + } else { + size = 2; goto size2; + } + } else { + if (part0 < (1 << 21)) { + size = 3; goto size3; + } else { + size = 4; goto size4; + } + } + } else { + if (part1 < (1 << 14)) { + if (part1 < (1 << 7)) { + size = 5; goto size5; + } else { + size = 6; goto size6; + } + } else { + if (part1 < (1 << 21)) { + size = 7; goto size7; + } else { + size = 8; goto size8; + } + } + } + } else { + if (part2 < (1 << 7)) { + size = 9; goto size9; + } else { + size = 10; goto size10; + } + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + + size10: target[9] = static_cast((part2 >> 7) | 0x80); + size9 : target[8] = static_cast((part2 ) | 0x80); + size8 : target[7] = static_cast((part1 >> 21) | 0x80); + size7 : target[6] = static_cast((part1 >> 14) | 0x80); + size6 : target[5] = static_cast((part1 >> 7) | 0x80); + size5 : target[4] = static_cast((part1 ) | 0x80); + size4 : target[3] = static_cast((part0 >> 21) | 0x80); + size3 : target[2] = static_cast((part0 >> 14) | 0x80); + size2 : target[1] = static_cast((part0 >> 7) | 0x80); + size1 : target[0] = static_cast((part0 ) | 0x80); + + target[size-1] &= 0x7F; + return target + size; +} + +void CodedOutputStream::WriteVarint64(uint64 value) { + if (buffer_size_ >= kMaxVarintBytes) { + // Fast path: We have enough bytes left in the buffer to guarantee that + // this write won't cross the end, so we can skip the checks. + uint8* target = buffer_; + + uint8* end = WriteVarint64ToArrayInline(value, target); + int size = end - target; + Advance(size); + } else { + // Slow path: This write might cross the end of the buffer, so we + // compose the bytes first then use WriteRaw(). + uint8 bytes[kMaxVarintBytes]; + int size = 0; + while (value > 0x7F) { + bytes[size++] = (static_cast(value) & 0x7F) | 0x80; + value >>= 7; + } + bytes[size++] = static_cast(value) & 0x7F; + WriteRaw(bytes, size); + } +} + +uint8* CodedOutputStream::WriteVarint64ToArray( + uint64 value, uint8* target) { + return WriteVarint64ToArrayInline(value, target); +} + +bool CodedOutputStream::Refresh() { + void* void_buffer; + if (output_->Next(&void_buffer, &buffer_size_)) { + buffer_ = reinterpret_cast(void_buffer); + total_bytes_ += buffer_size_; + return true; + } else { + buffer_ = NULL; + buffer_size_ = 0; + had_error_ = true; + return false; + } +} + +int CodedOutputStream::VarintSize32Fallback(uint32 value) { + if (value < (1 << 7)) { + return 1; + } else if (value < (1 << 14)) { + return 2; + } else if (value < (1 << 21)) { + return 3; + } else if (value < (1 << 28)) { + return 4; + } else { + return 5; + } +} + +int CodedOutputStream::VarintSize64(uint64 value) { + if (value < (1ull << 35)) { + if (value < (1ull << 7)) { + return 1; + } else if (value < (1ull << 14)) { + return 2; + } else if (value < (1ull << 21)) { + return 3; + } else if (value < (1ull << 28)) { + return 4; + } else { + return 5; + } + } else { + if (value < (1ull << 42)) { + return 6; + } else if (value < (1ull << 49)) { + return 7; + } else if (value < (1ull << 56)) { + return 8; + } else if (value < (1ull << 63)) { + return 9; + } else { + return 10; + } + } +} + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream.h new file mode 100644 index 0000000..66cbee0 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream.h @@ -0,0 +1,1136 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains the CodedInputStream and CodedOutputStream classes, +// which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively, +// and allow you to read or write individual pieces of data in various +// formats. In particular, these implement the varint encoding for +// integers, a simple variable-length encoding in which smaller numbers +// take fewer bytes. +// +// Typically these classes will only be used internally by the protocol +// buffer library in order to encode and decode protocol buffers. Clients +// of the library only need to know about this class if they wish to write +// custom message parsing or serialization procedures. +// +// CodedOutputStream example: +// // Write some data to "myfile". First we write a 4-byte "magic number" +// // to identify the file type, then write a length-delimited string. The +// // string is composed of a varint giving the length followed by the raw +// // bytes. +// int fd = open("myfile", O_WRONLY); +// ZeroCopyOutputStream* raw_output = new FileOutputStream(fd); +// CodedOutputStream* coded_output = new CodedOutputStream(raw_output); +// +// int magic_number = 1234; +// char text[] = "Hello world!"; +// coded_output->WriteLittleEndian32(magic_number); +// coded_output->WriteVarint32(strlen(text)); +// coded_output->WriteRaw(text, strlen(text)); +// +// delete coded_output; +// delete raw_output; +// close(fd); +// +// CodedInputStream example: +// // Read a file created by the above code. +// int fd = open("myfile", O_RDONLY); +// ZeroCopyInputStream* raw_input = new FileInputStream(fd); +// CodedInputStream coded_input = new CodedInputStream(raw_input); +// +// coded_input->ReadLittleEndian32(&magic_number); +// if (magic_number != 1234) { +// cerr << "File not in expected format." << endl; +// return; +// } +// +// uint32 size; +// coded_input->ReadVarint32(&size); +// +// char* text = new char[size + 1]; +// coded_input->ReadRaw(buffer, size); +// text[size] = '\0'; +// +// delete coded_input; +// delete raw_input; +// close(fd); +// +// cout << "Text is: " << text << endl; +// delete [] text; +// +// For those who are interested, varint encoding is defined as follows: +// +// The encoding operates on unsigned integers of up to 64 bits in length. +// Each byte of the encoded value has the format: +// * bits 0-6: Seven bits of the number being encoded. +// * bit 7: Zero if this is the last byte in the encoding (in which +// case all remaining bits of the number are zero) or 1 if +// more bytes follow. +// The first byte contains the least-significant 7 bits of the number, the +// second byte (if present) contains the next-least-significant 7 bits, +// and so on. So, the binary number 1011000101011 would be encoded in two +// bytes as "10101011 00101100". +// +// In theory, varint could be used to encode integers of any length. +// However, for practicality we set a limit at 64 bits. The maximum encoded +// length of a number is thus 10 bytes. + +#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ +#define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ + +#include +#ifdef _MSC_VER + #if defined(_M_IX86) && \ + !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) + #define PROTOBUF_LITTLE_ENDIAN 1 + #endif + #if _MSC_VER >= 1300 + // If MSVC has "/RTCc" set, it will complain about truncating casts at + // runtime. This file contains some intentional truncating casts. + #pragma runtime_checks("c", off) + #endif +#else + #include // __BYTE_ORDER + #if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN && \ + !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) + #define PROTOBUF_LITTLE_ENDIAN 1 + #endif +#endif +#include + + +namespace google { +namespace protobuf { + +class DescriptorPool; +class MessageFactory; + +namespace io { + +// Defined in this file. +class CodedInputStream; +class CodedOutputStream; + +// Defined in other files. +class ZeroCopyInputStream; // zero_copy_stream.h +class ZeroCopyOutputStream; // zero_copy_stream.h + +// Class which reads and decodes binary data which is composed of varint- +// encoded integers and fixed-width pieces. Wraps a ZeroCopyInputStream. +// Most users will not need to deal with CodedInputStream. +// +// Most methods of CodedInputStream that return a bool return false if an +// underlying I/O error occurs or if the data is malformed. Once such a +// failure occurs, the CodedInputStream is broken and is no longer useful. +class LIBPROTOBUF_EXPORT CodedInputStream { + public: + // Create a CodedInputStream that reads from the given ZeroCopyInputStream. + explicit CodedInputStream(ZeroCopyInputStream* input); + + // Create a CodedInputStream that reads from the given flat array. This is + // faster than using an ArrayInputStream. PushLimit(size) is implied by + // this constructor. + explicit CodedInputStream(const uint8* buffer, int size); + + // Destroy the CodedInputStream and position the underlying + // ZeroCopyInputStream at the first unread byte. If an error occurred while + // reading (causing a method to return false), then the exact position of + // the input stream may be anywhere between the last value that was read + // successfully and the stream's byte limit. + ~CodedInputStream(); + + // Return true if this CodedInputStream reads from a flat array instead of + // a ZeroCopyInputStream. + inline bool IsFlat() const; + + // Skips a number of bytes. Returns false if an underlying read error + // occurs. + bool Skip(int count); + + // Sets *data to point directly at the unread part of the CodedInputStream's + // underlying buffer, and *size to the size of that buffer, but does not + // advance the stream's current position. This will always either produce + // a non-empty buffer or return false. If the caller consumes any of + // this data, it should then call Skip() to skip over the consumed bytes. + // This may be useful for implementing external fast parsing routines for + // types of data not covered by the CodedInputStream interface. + bool GetDirectBufferPointer(const void** data, int* size); + + // Like GetDirectBufferPointer, but this method is inlined, and does not + // attempt to Refresh() if the buffer is currently empty. + inline void GetDirectBufferPointerInline(const void** data, + int* size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + + // Read raw bytes, copying them into the given buffer. + bool ReadRaw(void* buffer, int size); + + // Like ReadRaw, but reads into a string. + // + // Implementation Note: ReadString() grows the string gradually as it + // reads in the data, rather than allocating the entire requested size + // upfront. This prevents denial-of-service attacks in which a client + // could claim that a string is going to be MAX_INT bytes long in order to + // crash the server because it can't allocate this much space at once. + bool ReadString(string* buffer, int size); + // Like the above, with inlined optimizations. This should only be used + // by the protobuf implementation. + inline bool InternalReadStringInline(string* buffer, + int size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + + + // Read a 32-bit little-endian integer. + bool ReadLittleEndian32(uint32* value); + // Read a 64-bit little-endian integer. + bool ReadLittleEndian64(uint64* value); + + // These methods read from an externally provided buffer. The caller is + // responsible for ensuring that the buffer has sufficient space. + // Read a 32-bit little-endian integer. + static const uint8* ReadLittleEndian32FromArray(const uint8* buffer, + uint32* value); + // Read a 64-bit little-endian integer. + static const uint8* ReadLittleEndian64FromArray(const uint8* buffer, + uint64* value); + + // Read an unsigned integer with Varint encoding, truncating to 32 bits. + // Reading a 32-bit value is equivalent to reading a 64-bit one and casting + // it to uint32, but may be more efficient. + bool ReadVarint32(uint32* value); + // Read an unsigned integer with Varint encoding. + bool ReadVarint64(uint64* value); + + // Read a tag. This calls ReadVarint32() and returns the result, or returns + // zero (which is not a valid tag) if ReadVarint32() fails. Also, it updates + // the last tag value, which can be checked with LastTagWas(). + // Always inline because this is only called in once place per parse loop + // but it is called for every iteration of said loop, so it should be fast. + // GCC doesn't want to inline this by default. + uint32 ReadTag() GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + + // Usually returns true if calling ReadVarint32() now would produce the given + // value. Will always return false if ReadVarint32() would not return the + // given value. If ExpectTag() returns true, it also advances past + // the varint. For best performance, use a compile-time constant as the + // parameter. + // Always inline because this collapses to a small number of instructions + // when given a constant parameter, but GCC doesn't want to inline by default. + bool ExpectTag(uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + + // Like above, except this reads from the specified buffer. The caller is + // responsible for ensuring that the buffer is large enough to read a varint + // of the expected size. For best performance, use a compile-time constant as + // the expected tag parameter. + // + // Returns a pointer beyond the expected tag if it was found, or NULL if it + // was not. + static const uint8* ExpectTagFromArray( + const uint8* buffer, + uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + + // Usually returns true if no more bytes can be read. Always returns false + // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent + // call to LastTagWas() will act as if ReadTag() had been called and returned + // zero, and ConsumedEntireMessage() will return true. + bool ExpectAtEnd(); + + // If the last call to ReadTag() returned the given value, returns true. + // Otherwise, returns false; + // + // This is needed because parsers for some types of embedded messages + // (with field type TYPE_GROUP) don't actually know that they've reached the + // end of a message until they see an ENDGROUP tag, which was actually part + // of the enclosing message. The enclosing message would like to check that + // tag to make sure it had the right number, so it calls LastTagWas() on + // return from the embedded parser to check. + bool LastTagWas(uint32 expected); + + // When parsing message (but NOT a group), this method must be called + // immediately after MergeFromCodedStream() returns (if it returns true) + // to further verify that the message ended in a legitimate way. For + // example, this verifies that parsing did not end on an end-group tag. + // It also checks for some cases where, due to optimizations, + // MergeFromCodedStream() can incorrectly return true. + bool ConsumedEntireMessage(); + + // Limits ---------------------------------------------------------- + // Limits are used when parsing length-delimited embedded messages. + // After the message's length is read, PushLimit() is used to prevent + // the CodedInputStream from reading beyond that length. Once the + // embedded message has been parsed, PopLimit() is called to undo the + // limit. + + // Opaque type used with PushLimit() and PopLimit(). Do not modify + // values of this type yourself. The only reason that this isn't a + // struct with private internals is for efficiency. + typedef int Limit; + + // Places a limit on the number of bytes that the stream may read, + // starting from the current position. Once the stream hits this limit, + // it will act like the end of the input has been reached until PopLimit() + // is called. + // + // As the names imply, the stream conceptually has a stack of limits. The + // shortest limit on the stack is always enforced, even if it is not the + // top limit. + // + // The value returned by PushLimit() is opaque to the caller, and must + // be passed unchanged to the corresponding call to PopLimit(). + Limit PushLimit(int byte_limit); + + // Pops the last limit pushed by PushLimit(). The input must be the value + // returned by that call to PushLimit(). + void PopLimit(Limit limit); + + // Returns the number of bytes left until the nearest limit on the + // stack is hit, or -1 if no limits are in place. + int BytesUntilLimit() const; + + // Returns current position relative to the beginning of the input stream. + int CurrentPosition() const; + + // Total Bytes Limit ----------------------------------------------- + // To prevent malicious users from sending excessively large messages + // and causing integer overflows or memory exhaustion, CodedInputStream + // imposes a hard limit on the total number of bytes it will read. + + // Sets the maximum number of bytes that this CodedInputStream will read + // before refusing to continue. To prevent integer overflows in the + // protocol buffers implementation, as well as to prevent servers from + // allocating enormous amounts of memory to hold parsed messages, the + // maximum message length should be limited to the shortest length that + // will not harm usability. The theoretical shortest message that could + // cause integer overflows is 512MB. The default limit is 64MB. Apps + // should set shorter limits if possible. If warning_threshold is not -1, + // a warning will be printed to stderr after warning_threshold bytes are + // read. For backwards compatibility all negative values get squached to -1, + // as other negative values might have special internal meanings. + // An error will always be printed to stderr if the limit is reached. + // + // This is unrelated to PushLimit()/PopLimit(). + // + // Hint: If you are reading this because your program is printing a + // warning about dangerously large protocol messages, you may be + // confused about what to do next. The best option is to change your + // design such that excessively large messages are not necessary. + // For example, try to design file formats to consist of many small + // messages rather than a single large one. If this is infeasible, + // you will need to increase the limit. Chances are, though, that + // your code never constructs a CodedInputStream on which the limit + // can be set. You probably parse messages by calling things like + // Message::ParseFromString(). In this case, you will need to change + // your code to instead construct some sort of ZeroCopyInputStream + // (e.g. an ArrayInputStream), construct a CodedInputStream around + // that, then call Message::ParseFromCodedStream() instead. Then + // you can adjust the limit. Yes, it's more work, but you're doing + // something unusual. + void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold); + + // Recursion Limit ------------------------------------------------- + // To prevent corrupt or malicious messages from causing stack overflows, + // we must keep track of the depth of recursion when parsing embedded + // messages and groups. CodedInputStream keeps track of this because it + // is the only object that is passed down the stack during parsing. + + // Sets the maximum recursion depth. The default is 100. + void SetRecursionLimit(int limit); + + + // Increments the current recursion depth. Returns true if the depth is + // under the limit, false if it has gone over. + bool IncrementRecursionDepth(); + + // Decrements the recursion depth. + void DecrementRecursionDepth(); + + // Extension Registry ---------------------------------------------- + // ADVANCED USAGE: 99.9% of people can ignore this section. + // + // By default, when parsing extensions, the parser looks for extension + // definitions in the pool which owns the outer message's Descriptor. + // However, you may call SetExtensionRegistry() to provide an alternative + // pool instead. This makes it possible, for example, to parse a message + // using a generated class, but represent some extensions using + // DynamicMessage. + + // Set the pool used to look up extensions. Most users do not need to call + // this as the correct pool will be chosen automatically. + // + // WARNING: It is very easy to misuse this. Carefully read the requirements + // below. Do not use this unless you are sure you need it. Almost no one + // does. + // + // Let's say you are parsing a message into message object m, and you want + // to take advantage of SetExtensionRegistry(). You must follow these + // requirements: + // + // The given DescriptorPool must contain m->GetDescriptor(). It is not + // sufficient for it to simply contain a descriptor that has the same name + // and content -- it must be the *exact object*. In other words: + // assert(pool->FindMessageTypeByName(m->GetDescriptor()->full_name()) == + // m->GetDescriptor()); + // There are two ways to satisfy this requirement: + // 1) Use m->GetDescriptor()->pool() as the pool. This is generally useless + // because this is the pool that would be used anyway if you didn't call + // SetExtensionRegistry() at all. + // 2) Use a DescriptorPool which has m->GetDescriptor()->pool() as an + // "underlay". Read the documentation for DescriptorPool for more + // information about underlays. + // + // You must also provide a MessageFactory. This factory will be used to + // construct Message objects representing extensions. The factory's + // GetPrototype() MUST return non-NULL for any Descriptor which can be found + // through the provided pool. + // + // If the provided factory might return instances of protocol-compiler- + // generated (i.e. compiled-in) types, or if the outer message object m is + // a generated type, then the given factory MUST have this property: If + // GetPrototype() is given a Descriptor which resides in + // DescriptorPool::generated_pool(), the factory MUST return the same + // prototype which MessageFactory::generated_factory() would return. That + // is, given a descriptor for a generated type, the factory must return an + // instance of the generated class (NOT DynamicMessage). However, when + // given a descriptor for a type that is NOT in generated_pool, the factory + // is free to return any implementation. + // + // The reason for this requirement is that generated sub-objects may be + // accessed via the standard (non-reflection) extension accessor methods, + // and these methods will down-cast the object to the generated class type. + // If the object is not actually of that type, the results would be undefined. + // On the other hand, if an extension is not compiled in, then there is no + // way the code could end up accessing it via the standard accessors -- the + // only way to access the extension is via reflection. When using reflection, + // DynamicMessage and generated messages are indistinguishable, so it's fine + // if these objects are represented using DynamicMessage. + // + // Using DynamicMessageFactory on which you have called + // SetDelegateToGeneratedFactory(true) should be sufficient to satisfy the + // above requirement. + // + // If either pool or factory is NULL, both must be NULL. + // + // Note that this feature is ignored when parsing "lite" messages as they do + // not have descriptors. + void SetExtensionRegistry(const DescriptorPool* pool, + MessageFactory* factory); + + // Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool + // has been provided. + const DescriptorPool* GetExtensionPool(); + + // Get the MessageFactory set via SetExtensionRegistry(), or NULL if no + // factory has been provided. + MessageFactory* GetExtensionFactory(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream); + + ZeroCopyInputStream* input_; + const uint8* buffer_; + const uint8* buffer_end_; // pointer to the end of the buffer. + int total_bytes_read_; // total bytes read from input_, including + // the current buffer + + // If total_bytes_read_ surpasses INT_MAX, we record the extra bytes here + // so that we can BackUp() on destruction. + int overflow_bytes_; + + // LastTagWas() stuff. + uint32 last_tag_; // result of last ReadTag(). + + // This is set true by ReadTag{Fallback/Slow}() if it is called when exactly + // at EOF, or by ExpectAtEnd() when it returns true. This happens when we + // reach the end of a message and attempt to read another tag. + bool legitimate_message_end_; + + // See EnableAliasing(). + bool aliasing_enabled_; + + // Limits + Limit current_limit_; // if position = -1, no limit is applied + + // For simplicity, if the current buffer crosses a limit (either a normal + // limit created by PushLimit() or the total bytes limit), buffer_size_ + // only tracks the number of bytes before that limit. This field + // contains the number of bytes after it. Note that this implies that if + // buffer_size_ == 0 and buffer_size_after_limit_ > 0, we know we've + // hit a limit. However, if both are zero, it doesn't necessarily mean + // we aren't at a limit -- the buffer may have ended exactly at the limit. + int buffer_size_after_limit_; + + // Maximum number of bytes to read, period. This is unrelated to + // current_limit_. Set using SetTotalBytesLimit(). + int total_bytes_limit_; + + // If positive/0: Limit for bytes read after which a warning due to size + // should be logged. + // If -1: Printing of warning disabled. Can be set by client. + // If -2: Internal: Limit has been reached, print full size when destructing. + int total_bytes_warning_threshold_; + + // Current recursion depth, controlled by IncrementRecursionDepth() and + // DecrementRecursionDepth(). + int recursion_depth_; + // Recursion depth limit, set by SetRecursionLimit(). + int recursion_limit_; + + // See SetExtensionRegistry(). + const DescriptorPool* extension_pool_; + MessageFactory* extension_factory_; + + // Private member functions. + + // Advance the buffer by a given number of bytes. + void Advance(int amount); + + // Back up input_ to the current buffer position. + void BackUpInputToCurrentPosition(); + + // Recomputes the value of buffer_size_after_limit_. Must be called after + // current_limit_ or total_bytes_limit_ changes. + void RecomputeBufferLimits(); + + // Writes an error message saying that we hit total_bytes_limit_. + void PrintTotalBytesLimitError(); + + // Called when the buffer runs out to request more data. Implies an + // Advance(BufferSize()). + bool Refresh(); + + // When parsing varints, we optimize for the common case of small values, and + // then optimize for the case when the varint fits within the current buffer + // piece. The Fallback method is used when we can't use the one-byte + // optimization. The Slow method is yet another fallback when the buffer is + // not large enough. Making the slow path out-of-line speeds up the common + // case by 10-15%. The slow path is fairly uncommon: it only triggers when a + // message crosses multiple buffers. + bool ReadVarint32Fallback(uint32* value); + bool ReadVarint64Fallback(uint64* value); + bool ReadVarint32Slow(uint32* value); + bool ReadVarint64Slow(uint64* value); + bool ReadLittleEndian32Fallback(uint32* value); + bool ReadLittleEndian64Fallback(uint64* value); + // Fallback/slow methods for reading tags. These do not update last_tag_, + // but will set legitimate_message_end_ if we are at the end of the input + // stream. + uint32 ReadTagFallback(); + uint32 ReadTagSlow(); + bool ReadStringFallback(string* buffer, int size); + + // Return the size of the buffer. + int BufferSize() const; + + static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB + + static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB + + static int default_recursion_limit_; // 100 by default. +}; + +// Class which encodes and writes binary data which is composed of varint- +// encoded integers and fixed-width pieces. Wraps a ZeroCopyOutputStream. +// Most users will not need to deal with CodedOutputStream. +// +// Most methods of CodedOutputStream which return a bool return false if an +// underlying I/O error occurs. Once such a failure occurs, the +// CodedOutputStream is broken and is no longer useful. The Write* methods do +// not return the stream status, but will invalidate the stream if an error +// occurs. The client can probe HadError() to determine the status. +// +// Note that every method of CodedOutputStream which writes some data has +// a corresponding static "ToArray" version. These versions write directly +// to the provided buffer, returning a pointer past the last written byte. +// They require that the buffer has sufficient capacity for the encoded data. +// This allows an optimization where we check if an output stream has enough +// space for an entire message before we start writing and, if there is, we +// call only the ToArray methods to avoid doing bound checks for each +// individual value. +// i.e., in the example above: +// +// CodedOutputStream coded_output = new CodedOutputStream(raw_output); +// int magic_number = 1234; +// char text[] = "Hello world!"; +// +// int coded_size = sizeof(magic_number) + +// CodedOutputStream::VarintSize32(strlen(text)) + +// strlen(text); +// +// uint8* buffer = +// coded_output->GetDirectBufferForNBytesAndAdvance(coded_size); +// if (buffer != NULL) { +// // The output stream has enough space in the buffer: write directly to +// // the array. +// buffer = CodedOutputStream::WriteLittleEndian32ToArray(magic_number, +// buffer); +// buffer = CodedOutputStream::WriteVarint32ToArray(strlen(text), buffer); +// buffer = CodedOutputStream::WriteRawToArray(text, strlen(text), buffer); +// } else { +// // Make bound-checked writes, which will ask the underlying stream for +// // more space as needed. +// coded_output->WriteLittleEndian32(magic_number); +// coded_output->WriteVarint32(strlen(text)); +// coded_output->WriteRaw(text, strlen(text)); +// } +// +// delete coded_output; +class LIBPROTOBUF_EXPORT CodedOutputStream { + public: + // Create an CodedOutputStream that writes to the given ZeroCopyOutputStream. + explicit CodedOutputStream(ZeroCopyOutputStream* output); + + // Destroy the CodedOutputStream and position the underlying + // ZeroCopyOutputStream immediately after the last byte written. + ~CodedOutputStream(); + + // Skips a number of bytes, leaving the bytes unmodified in the underlying + // buffer. Returns false if an underlying write error occurs. This is + // mainly useful with GetDirectBufferPointer(). + bool Skip(int count); + + // Sets *data to point directly at the unwritten part of the + // CodedOutputStream's underlying buffer, and *size to the size of that + // buffer, but does not advance the stream's current position. This will + // always either produce a non-empty buffer or return false. If the caller + // writes any data to this buffer, it should then call Skip() to skip over + // the consumed bytes. This may be useful for implementing external fast + // serialization routines for types of data not covered by the + // CodedOutputStream interface. + bool GetDirectBufferPointer(void** data, int* size); + + // If there are at least "size" bytes available in the current buffer, + // returns a pointer directly into the buffer and advances over these bytes. + // The caller may then write directly into this buffer (e.g. using the + // *ToArray static methods) rather than go through CodedOutputStream. If + // there are not enough bytes available, returns NULL. The return pointer is + // invalidated as soon as any other non-const method of CodedOutputStream + // is called. + inline uint8* GetDirectBufferForNBytesAndAdvance(int size); + + // Write raw bytes, copying them from the given buffer. + void WriteRaw(const void* buffer, int size); + // Like WriteRaw() but writing directly to the target array. + // This is _not_ inlined, as the compiler often optimizes memcpy into inline + // copy loops. Since this gets called by every field with string or bytes + // type, inlining may lead to a significant amount of code bloat, with only a + // minor performance gain. + static uint8* WriteRawToArray(const void* buffer, int size, uint8* target); + + // Equivalent to WriteRaw(str.data(), str.size()). + void WriteString(const string& str); + // Like WriteString() but writing directly to the target array. + static uint8* WriteStringToArray(const string& str, uint8* target); + + + // Write a 32-bit little-endian integer. + void WriteLittleEndian32(uint32 value); + // Like WriteLittleEndian32() but writing directly to the target array. + static uint8* WriteLittleEndian32ToArray(uint32 value, uint8* target); + // Write a 64-bit little-endian integer. + void WriteLittleEndian64(uint64 value); + // Like WriteLittleEndian64() but writing directly to the target array. + static uint8* WriteLittleEndian64ToArray(uint64 value, uint8* target); + + // Write an unsigned integer with Varint encoding. Writing a 32-bit value + // is equivalent to casting it to uint64 and writing it as a 64-bit value, + // but may be more efficient. + void WriteVarint32(uint32 value); + // Like WriteVarint32() but writing directly to the target array. + static uint8* WriteVarint32ToArray(uint32 value, uint8* target); + // Write an unsigned integer with Varint encoding. + void WriteVarint64(uint64 value); + // Like WriteVarint64() but writing directly to the target array. + static uint8* WriteVarint64ToArray(uint64 value, uint8* target); + + // Equivalent to WriteVarint32() except when the value is negative, + // in which case it must be sign-extended to a full 10 bytes. + void WriteVarint32SignExtended(int32 value); + // Like WriteVarint32SignExtended() but writing directly to the target array. + static uint8* WriteVarint32SignExtendedToArray(int32 value, uint8* target); + + // This is identical to WriteVarint32(), but optimized for writing tags. + // In particular, if the input is a compile-time constant, this method + // compiles down to a couple instructions. + // Always inline because otherwise the aformentioned optimization can't work, + // but GCC by default doesn't want to inline this. + void WriteTag(uint32 value); + // Like WriteTag() but writing directly to the target array. + static uint8* WriteTagToArray( + uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + + // Returns the number of bytes needed to encode the given value as a varint. + static int VarintSize32(uint32 value); + // Returns the number of bytes needed to encode the given value as a varint. + static int VarintSize64(uint64 value); + + // If negative, 10 bytes. Otheriwse, same as VarintSize32(). + static int VarintSize32SignExtended(int32 value); + + // Compile-time equivalent of VarintSize32(). + template + struct StaticVarintSize32 { + static const int value = + (Value < (1 << 7)) + ? 1 + : (Value < (1 << 14)) + ? 2 + : (Value < (1 << 21)) + ? 3 + : (Value < (1 << 28)) + ? 4 + : 5; + }; + + // Returns the total number of bytes written since this object was created. + inline int ByteCount() const; + + // Returns true if there was an underlying I/O error since this object was + // created. + bool HadError() const { return had_error_; } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream); + + ZeroCopyOutputStream* output_; + uint8* buffer_; + int buffer_size_; + int total_bytes_; // Sum of sizes of all buffers seen so far. + bool had_error_; // Whether an error occurred during output. + + // Advance the buffer by a given number of bytes. + void Advance(int amount); + + // Called when the buffer runs out to request more data. Implies an + // Advance(buffer_size_). + bool Refresh(); + + static uint8* WriteVarint32FallbackToArray(uint32 value, uint8* target); + + // Always-inlined versions of WriteVarint* functions so that code can be + // reused, while still controlling size. For instance, WriteVarint32ToArray() + // should not directly call this: since it is inlined itself, doing so + // would greatly increase the size of generated code. Instead, it should call + // WriteVarint32FallbackToArray. Meanwhile, WriteVarint32() is already + // out-of-line, so it should just invoke this directly to avoid any extra + // function call overhead. + static uint8* WriteVarint32FallbackToArrayInline( + uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + static uint8* WriteVarint64ToArrayInline( + uint64 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + + static int VarintSize32Fallback(uint32 value); +}; + +// inline methods ==================================================== +// The vast majority of varints are only one byte. These inline +// methods optimize for that case. + +inline bool CodedInputStream::ReadVarint32(uint32* value) { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { + *value = *buffer_; + Advance(1); + return true; + } else { + return ReadVarint32Fallback(value); + } +} + +inline bool CodedInputStream::ReadVarint64(uint64* value) { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { + *value = *buffer_; + Advance(1); + return true; + } else { + return ReadVarint64Fallback(value); + } +} + +// static +inline const uint8* CodedInputStream::ReadLittleEndian32FromArray( + const uint8* buffer, + uint32* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(value, buffer, sizeof(*value)); + return buffer + sizeof(*value); +#else + *value = (static_cast(buffer[0]) ) | + (static_cast(buffer[1]) << 8) | + (static_cast(buffer[2]) << 16) | + (static_cast(buffer[3]) << 24); + return buffer + sizeof(*value); +#endif +} +// static +inline const uint8* CodedInputStream::ReadLittleEndian64FromArray( + const uint8* buffer, + uint64* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(value, buffer, sizeof(*value)); + return buffer + sizeof(*value); +#else + uint32 part0 = (static_cast(buffer[0]) ) | + (static_cast(buffer[1]) << 8) | + (static_cast(buffer[2]) << 16) | + (static_cast(buffer[3]) << 24); + uint32 part1 = (static_cast(buffer[4]) ) | + (static_cast(buffer[5]) << 8) | + (static_cast(buffer[6]) << 16) | + (static_cast(buffer[7]) << 24); + *value = static_cast(part0) | + (static_cast(part1) << 32); + return buffer + sizeof(*value); +#endif +} + +inline bool CodedInputStream::ReadLittleEndian32(uint32* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast(sizeof(*value)))) { + memcpy(value, buffer_, sizeof(*value)); + Advance(sizeof(*value)); + return true; + } else { + return ReadLittleEndian32Fallback(value); + } +#else + return ReadLittleEndian32Fallback(value); +#endif +} + +inline bool CodedInputStream::ReadLittleEndian64(uint64* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast(sizeof(*value)))) { + memcpy(value, buffer_, sizeof(*value)); + Advance(sizeof(*value)); + return true; + } else { + return ReadLittleEndian64Fallback(value); + } +#else + return ReadLittleEndian64Fallback(value); +#endif +} + +inline uint32 CodedInputStream::ReadTag() { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] < 0x80) { + last_tag_ = buffer_[0]; + Advance(1); + return last_tag_; + } else { + last_tag_ = ReadTagFallback(); + return last_tag_; + } +} + +inline bool CodedInputStream::LastTagWas(uint32 expected) { + return last_tag_ == expected; +} + +inline bool CodedInputStream::ConsumedEntireMessage() { + return legitimate_message_end_; +} + +inline bool CodedInputStream::ExpectTag(uint32 expected) { + if (expected < (1 << 7)) { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] == expected) { + Advance(1); + return true; + } else { + return false; + } + } else if (expected < (1 << 14)) { + if (GOOGLE_PREDICT_TRUE(BufferSize() >= 2) && + buffer_[0] == static_cast(expected | 0x80) && + buffer_[1] == static_cast(expected >> 7)) { + Advance(2); + return true; + } else { + return false; + } + } else { + // Don't bother optimizing for larger values. + return false; + } +} + +inline const uint8* CodedInputStream::ExpectTagFromArray( + const uint8* buffer, uint32 expected) { + if (expected < (1 << 7)) { + if (buffer[0] == expected) { + return buffer + 1; + } + } else if (expected < (1 << 14)) { + if (buffer[0] == static_cast(expected | 0x80) && + buffer[1] == static_cast(expected >> 7)) { + return buffer + 2; + } + } + return NULL; +} + +inline void CodedInputStream::GetDirectBufferPointerInline(const void** data, + int* size) { + *data = buffer_; + *size = buffer_end_ - buffer_; +} + +inline bool CodedInputStream::ExpectAtEnd() { + // If we are at a limit we know no more bytes can be read. Otherwise, it's + // hard to say without calling Refresh(), and we'd rather not do that. + + if (buffer_ == buffer_end_ && + ((buffer_size_after_limit_ != 0) || + (total_bytes_read_ == current_limit_))) { + last_tag_ = 0; // Pretend we called ReadTag()... + legitimate_message_end_ = true; // ... and it hit EOF. + return true; + } else { + return false; + } +} + +inline int CodedInputStream::CurrentPosition() const { + return total_bytes_read_ - (BufferSize() + buffer_size_after_limit_); +} + +inline uint8* CodedOutputStream::GetDirectBufferForNBytesAndAdvance(int size) { + if (buffer_size_ < size) { + return NULL; + } else { + uint8* result = buffer_; + Advance(size); + return result; + } +} + +inline uint8* CodedOutputStream::WriteVarint32ToArray(uint32 value, + uint8* target) { + if (value < 0x80) { + *target = value; + return target + 1; + } else { + return WriteVarint32FallbackToArray(value, target); + } +} + +inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) { + if (value < 0) { + WriteVarint64(static_cast(value)); + } else { + WriteVarint32(static_cast(value)); + } +} + +inline uint8* CodedOutputStream::WriteVarint32SignExtendedToArray( + int32 value, uint8* target) { + if (value < 0) { + return WriteVarint64ToArray(static_cast(value), target); + } else { + return WriteVarint32ToArray(static_cast(value), target); + } +} + +inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value, + uint8* target) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(target, &value, sizeof(value)); +#else + target[0] = static_cast(value); + target[1] = static_cast(value >> 8); + target[2] = static_cast(value >> 16); + target[3] = static_cast(value >> 24); +#endif + return target + sizeof(value); +} + +inline uint8* CodedOutputStream::WriteLittleEndian64ToArray(uint64 value, + uint8* target) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(target, &value, sizeof(value)); +#else + uint32 part0 = static_cast(value); + uint32 part1 = static_cast(value >> 32); + + target[0] = static_cast(part0); + target[1] = static_cast(part0 >> 8); + target[2] = static_cast(part0 >> 16); + target[3] = static_cast(part0 >> 24); + target[4] = static_cast(part1); + target[5] = static_cast(part1 >> 8); + target[6] = static_cast(part1 >> 16); + target[7] = static_cast(part1 >> 24); +#endif + return target + sizeof(value); +} + +inline void CodedOutputStream::WriteTag(uint32 value) { + WriteVarint32(value); +} + +inline uint8* CodedOutputStream::WriteTagToArray( + uint32 value, uint8* target) { + if (value < (1 << 7)) { + target[0] = value; + return target + 1; + } else if (value < (1 << 14)) { + target[0] = static_cast(value | 0x80); + target[1] = static_cast(value >> 7); + return target + 2; + } else { + return WriteVarint32FallbackToArray(value, target); + } +} + +inline int CodedOutputStream::VarintSize32(uint32 value) { + if (value < (1 << 7)) { + return 1; + } else { + return VarintSize32Fallback(value); + } +} + +inline int CodedOutputStream::VarintSize32SignExtended(int32 value) { + if (value < 0) { + return 10; // TODO(kenton): Make this a symbolic constant. + } else { + return VarintSize32(static_cast(value)); + } +} + +inline void CodedOutputStream::WriteString(const string& str) { + WriteRaw(str.data(), static_cast(str.size())); +} + +inline uint8* CodedOutputStream::WriteStringToArray( + const string& str, uint8* target) { + return WriteRawToArray(str.data(), static_cast(str.size()), target); +} + +inline int CodedOutputStream::ByteCount() const { + return total_bytes_ - buffer_size_; +} + +inline void CodedInputStream::Advance(int amount) { + buffer_ += amount; +} + +inline void CodedOutputStream::Advance(int amount) { + buffer_ += amount; + buffer_size_ -= amount; +} + +inline void CodedInputStream::SetRecursionLimit(int limit) { + recursion_limit_ = limit; +} + +inline bool CodedInputStream::IncrementRecursionDepth() { + ++recursion_depth_; + return recursion_depth_ <= recursion_limit_; +} + +inline void CodedInputStream::DecrementRecursionDepth() { + if (recursion_depth_ > 0) --recursion_depth_; +} + +inline void CodedInputStream::SetExtensionRegistry(const DescriptorPool* pool, + MessageFactory* factory) { + extension_pool_ = pool; + extension_factory_ = factory; +} + +inline const DescriptorPool* CodedInputStream::GetExtensionPool() { + return extension_pool_; +} + +inline MessageFactory* CodedInputStream::GetExtensionFactory() { + return extension_factory_; +} + +inline int CodedInputStream::BufferSize() const { + return buffer_end_ - buffer_; +} + +inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) + : input_(input), + buffer_(NULL), + buffer_end_(NULL), + total_bytes_read_(0), + overflow_bytes_(0), + last_tag_(0), + legitimate_message_end_(false), + aliasing_enabled_(false), + current_limit_(kint32max), + buffer_size_after_limit_(0), + total_bytes_limit_(kDefaultTotalBytesLimit), + total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), + recursion_depth_(0), + recursion_limit_(default_recursion_limit_), + extension_pool_(NULL), + extension_factory_(NULL) { + // Eagerly Refresh() so buffer space is immediately available. + Refresh(); +} + +inline CodedInputStream::CodedInputStream(const uint8* buffer, int size) + : input_(NULL), + buffer_(buffer), + buffer_end_(buffer + size), + total_bytes_read_(size), + overflow_bytes_(0), + last_tag_(0), + legitimate_message_end_(false), + aliasing_enabled_(false), + current_limit_(size), + buffer_size_after_limit_(0), + total_bytes_limit_(kDefaultTotalBytesLimit), + total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), + recursion_depth_(0), + recursion_limit_(default_recursion_limit_), + extension_pool_(NULL), + extension_factory_(NULL) { + // Note that setting current_limit_ == size is important to prevent some + // code paths from trying to access input_ and segfaulting. +} + +inline bool CodedInputStream::IsFlat() const { + return input_ == NULL; +} + +} // namespace io +} // namespace protobuf + + +#if defined(_MSC_VER) && _MSC_VER >= 1300 + #pragma runtime_checks("c", restore) +#endif // _MSC_VER + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream_inl.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream_inl.h new file mode 100644 index 0000000..144f44f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream_inl.h @@ -0,0 +1,68 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jasonh@google.com (Jason Hsueh) +// +// Implements methods of coded_stream.h that need to be inlined for performance +// reasons, but should not be defined in a public header. + +#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__ +#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { + +inline bool CodedInputStream::InternalReadStringInline(string* buffer, + int size) { + if (size < 0) return false; // security: size is often user-supplied + + if (BufferSize() >= size) { + STLStringResizeUninitialized(buffer, size); + // When buffer is empty, string_as_array(buffer) will return NULL but memcpy + // requires non-NULL pointers even when size is 0. Hench this check. + if (size > 0) { + memcpy(string_as_array(buffer), buffer_, size); + Advance(size); + } + return true; + } + + return ReadStringFallback(buffer, size); +} + +} // namespace io +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream_unittest.cc new file mode 100644 index 0000000..2daab19 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/coded_stream_unittest.cc @@ -0,0 +1,1191 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains tests and benchmarks. + +#include + +#include + +#include + +#include +#include +#include +#include + + +// This declares an unsigned long long integer literal in a portable way. +// (The original macro is way too big and ruins my formatting.) +#undef ULL +#define ULL(x) GOOGLE_ULONGLONG(x) + +namespace google { +namespace protobuf { +namespace io { +namespace { + +// =================================================================== +// Data-Driven Test Infrastructure + +// TEST_1D and TEST_2D are macros I'd eventually like to see added to +// gTest. These macros can be used to declare tests which should be +// run multiple times, once for each item in some input array. TEST_1D +// tests all cases in a single input array. TEST_2D tests all +// combinations of cases from two arrays. The arrays must be statically +// defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example: +// +// int kCases[] = {1, 2, 3, 4} +// TEST_1D(MyFixture, MyTest, kCases) { +// EXPECT_GT(kCases_case, 0); +// } +// +// This test iterates through the numbers 1, 2, 3, and 4 and tests that +// they are all grater than zero. In case of failure, the exact case +// which failed will be printed. The case type must be printable using +// ostream::operator<<. + +// TODO(kenton): gTest now supports "parameterized tests" which would be +// a better way to accomplish this. Rewrite when time permits. + +#define TEST_1D(FIXTURE, NAME, CASES) \ + class FIXTURE##_##NAME##_DD : public FIXTURE { \ + protected: \ + template \ + void DoSingleCase(const CaseType& CASES##_case); \ + }; \ + \ + TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ + for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \ + SCOPED_TRACE(testing::Message() \ + << #CASES " case #" << i << ": " << CASES[i]); \ + DoSingleCase(CASES[i]); \ + } \ + } \ + \ + template \ + void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case) + +#define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \ + class FIXTURE##_##NAME##_DD : public FIXTURE { \ + protected: \ + template \ + void DoSingleCase(const CaseType1& CASES1##_case, \ + const CaseType2& CASES2##_case); \ + }; \ + \ + TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ + for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \ + for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \ + SCOPED_TRACE(testing::Message() \ + << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \ + << #CASES2 " case #" << j << ": " << CASES2[j]); \ + DoSingleCase(CASES1[i], CASES2[j]); \ + } \ + } \ + } \ + \ + template \ + void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \ + const CaseType2& CASES2##_case) + +// =================================================================== + +class CodedStreamTest : public testing::Test { + protected: + // Helper method used by tests for bytes warning. See implementation comment + // for further information. + static void SetupTotalBytesLimitWarningTest( + int total_bytes_limit, int warning_threshold, + vector* out_errors, vector* out_warnings); + + // Buffer used during most of the tests. This assumes tests run sequentially. + static const int kBufferSize = 1024 * 64; + static uint8 buffer_[kBufferSize]; +}; + +uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize]; + +// We test each operation over a variety of block sizes to insure that +// we test cases where reads or writes cross buffer boundaries, cases +// where they don't, and cases where there is so much buffer left that +// we can use special optimized paths that don't worry about bounds +// checks. +const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024}; + +// ------------------------------------------------------------------- +// Varint tests. + +struct VarintCase { + uint8 bytes[10]; // Encoded bytes. + int size; // Encoded size, in bytes. + uint64 value; // Parsed value. +}; + +inline std::ostream& operator<<(std::ostream& os, const VarintCase& c) { + return os << c.value; +} + +VarintCase kVarintCases[] = { + // 32-bit values + {{0x00} , 1, 0}, + {{0x01} , 1, 1}, + {{0x7f} , 1, 127}, + {{0xa2, 0x74}, 2, (0x22 << 0) | (0x74 << 7)}, // 14882 + {{0xbe, 0xf7, 0x92, 0x84, 0x0b}, 5, // 2961488830 + (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | + (ULL(0x0b) << 28)}, + + // 64-bit + {{0xbe, 0xf7, 0x92, 0x84, 0x1b}, 5, // 7256456126 + (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | + (ULL(0x1b) << 28)}, + {{0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49}, 8, // 41256202580718336 + (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) | + (ULL(0x43) << 28) | (ULL(0x49) << 35) | (ULL(0x24) << 42) | + (ULL(0x49) << 49)}, + // 11964378330978735131 + {{0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01}, 10, + (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) | + (ULL(0x3b) << 28) | (ULL(0x56) << 35) | (ULL(0x00) << 42) | + (ULL(0x05) << 49) | (ULL(0x26) << 56) | (ULL(0x01) << 63)}, +}; + +TEST_2D(CodedStreamTest, ReadVarint32, kVarintCases, kBlockSizes) { + memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedInputStream coded_input(&input); + + uint32 value; + EXPECT_TRUE(coded_input.ReadVarint32(&value)); + EXPECT_EQ(static_cast(kVarintCases_case.value), value); + } + + EXPECT_EQ(kVarintCases_case.size, input.ByteCount()); +} + +TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) { + memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedInputStream coded_input(&input); + + uint32 expected_value = static_cast(kVarintCases_case.value); + EXPECT_EQ(expected_value, coded_input.ReadTag()); + + EXPECT_TRUE(coded_input.LastTagWas(expected_value)); + EXPECT_FALSE(coded_input.LastTagWas(expected_value + 1)); + } + + EXPECT_EQ(kVarintCases_case.size, input.ByteCount()); +} + +// This is the regression test that verifies that there is no issues +// with the empty input buffers handling. +TEST_F(CodedStreamTest, EmptyInputBeforeEos) { + class In : public ZeroCopyInputStream { + public: + In() : count_(0) {} + private: + virtual bool Next(const void** data, int* size) { + *data = NULL; + *size = 0; + return count_++ < 2; + } + virtual void BackUp(int count) { + GOOGLE_LOG(FATAL) << "Tests never call this."; + } + virtual bool Skip(int count) { + GOOGLE_LOG(FATAL) << "Tests never call this."; + return false; + } + virtual int64 ByteCount() const { return 0; } + int count_; + } in; + CodedInputStream input(&in); + input.ReadTag(); + EXPECT_TRUE(input.ConsumedEntireMessage()); +} + +TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) { + // Leave one byte at the beginning of the buffer so we can read it + // to force the first buffer to be loaded. + buffer_[0] = '\0'; + memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size); + ArrayInputStream input(buffer_, sizeof(buffer_)); + + { + CodedInputStream coded_input(&input); + + // Read one byte to force coded_input.Refill() to be called. Otherwise, + // ExpectTag() will return a false negative. + uint8 dummy; + coded_input.ReadRaw(&dummy, 1); + EXPECT_EQ((uint)'\0', (uint)dummy); + + uint32 expected_value = static_cast(kVarintCases_case.value); + + // ExpectTag() produces false negatives for large values. + if (kVarintCases_case.size <= 2) { + EXPECT_FALSE(coded_input.ExpectTag(expected_value + 1)); + EXPECT_TRUE(coded_input.ExpectTag(expected_value)); + } else { + EXPECT_FALSE(coded_input.ExpectTag(expected_value)); + } + } + + if (kVarintCases_case.size <= 2) { + EXPECT_EQ(kVarintCases_case.size + 1, input.ByteCount()); + } else { + EXPECT_EQ(1, input.ByteCount()); + } +} + +TEST_1D(CodedStreamTest, ExpectTagFromArray, kVarintCases) { + memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); + + const uint32 expected_value = static_cast(kVarintCases_case.value); + + // If the expectation succeeds, it should return a pointer past the tag. + if (kVarintCases_case.size <= 2) { + EXPECT_TRUE(NULL == + CodedInputStream::ExpectTagFromArray(buffer_, + expected_value + 1)); + EXPECT_TRUE(buffer_ + kVarintCases_case.size == + CodedInputStream::ExpectTagFromArray(buffer_, expected_value)); + } else { + EXPECT_TRUE(NULL == + CodedInputStream::ExpectTagFromArray(buffer_, expected_value)); + } +} + +TEST_2D(CodedStreamTest, ReadVarint64, kVarintCases, kBlockSizes) { + memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedInputStream coded_input(&input); + + uint64 value; + EXPECT_TRUE(coded_input.ReadVarint64(&value)); + EXPECT_EQ(kVarintCases_case.value, value); + } + + EXPECT_EQ(kVarintCases_case.size, input.ByteCount()); +} + +TEST_2D(CodedStreamTest, WriteVarint32, kVarintCases, kBlockSizes) { + if (kVarintCases_case.value > ULL(0x00000000FFFFFFFF)) { + // Skip this test for the 64-bit values. + return; + } + + ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedOutputStream coded_output(&output); + + coded_output.WriteVarint32(static_cast(kVarintCases_case.value)); + EXPECT_FALSE(coded_output.HadError()); + + EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount()); + } + + EXPECT_EQ(kVarintCases_case.size, output.ByteCount()); + EXPECT_EQ(0, + memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size)); +} + +TEST_2D(CodedStreamTest, WriteVarint64, kVarintCases, kBlockSizes) { + ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedOutputStream coded_output(&output); + + coded_output.WriteVarint64(kVarintCases_case.value); + EXPECT_FALSE(coded_output.HadError()); + + EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount()); + } + + EXPECT_EQ(kVarintCases_case.size, output.ByteCount()); + EXPECT_EQ(0, + memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size)); +} + +// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error: +// "sorry, unimplemented: `method_call_expr' not supported by dump_expr" +#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) + +int32 kSignExtendedVarintCases[] = { + 0, 1, -1, 1237894, -37895138 +}; + +TEST_2D(CodedStreamTest, WriteVarint32SignExtended, + kSignExtendedVarintCases, kBlockSizes) { + ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedOutputStream coded_output(&output); + + coded_output.WriteVarint32SignExtended(kSignExtendedVarintCases_case); + EXPECT_FALSE(coded_output.HadError()); + + if (kSignExtendedVarintCases_case < 0) { + EXPECT_EQ(10, coded_output.ByteCount()); + } else { + EXPECT_LE(coded_output.ByteCount(), 5); + } + } + + if (kSignExtendedVarintCases_case < 0) { + EXPECT_EQ(10, output.ByteCount()); + } else { + EXPECT_LE(output.ByteCount(), 5); + } + + // Read value back in as a varint64 and insure it matches. + ArrayInputStream input(buffer_, sizeof(buffer_)); + + { + CodedInputStream coded_input(&input); + + uint64 value; + EXPECT_TRUE(coded_input.ReadVarint64(&value)); + + EXPECT_EQ(kSignExtendedVarintCases_case, static_cast(value)); + } + + EXPECT_EQ(output.ByteCount(), input.ByteCount()); +} + +#endif + + +// ------------------------------------------------------------------- +// Varint failure test. + +struct VarintErrorCase { + uint8 bytes[12]; + int size; + bool can_parse; +}; + +inline std::ostream& operator<<(std::ostream& os, const VarintErrorCase& c) { + return os << "size " << c.size; +} + +const VarintErrorCase kVarintErrorCases[] = { + // Control case. (Insures that there isn't something else wrong that + // makes parsing always fail.) + {{0x00}, 1, true}, + + // No input data. + {{}, 0, false}, + + // Input ends unexpectedly. + {{0xf0, 0xab}, 2, false}, + + // Input ends unexpectedly after 32 bits. + {{0xf0, 0xab, 0xc9, 0x9a, 0xf8, 0xb2}, 6, false}, + + // Longer than 10 bytes. + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}, + 11, false}, +}; + +TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) { + memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); + ArrayInputStream input(buffer_, kVarintErrorCases_case.size, + kBlockSizes_case); + CodedInputStream coded_input(&input); + + uint32 value; + EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value)); +} + +TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) { + memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); + ArrayInputStream input(buffer_, kVarintErrorCases_case.size, + kBlockSizes_case); + CodedInputStream coded_input(&input); + + uint64 value; + EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value)); +} + +// ------------------------------------------------------------------- +// VarintSize + +struct VarintSizeCase { + uint64 value; + int size; +}; + +inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) { + return os << c.value; +} + +VarintSizeCase kVarintSizeCases[] = { + {0u, 1}, + {1u, 1}, + {127u, 1}, + {128u, 2}, + {758923u, 3}, + {4000000000u, 5}, + {ULL(41256202580718336), 8}, + {ULL(11964378330978735131), 10}, +}; + +TEST_1D(CodedStreamTest, VarintSize32, kVarintSizeCases) { + if (kVarintSizeCases_case.value > 0xffffffffu) { + // Skip 64-bit values. + return; + } + + EXPECT_EQ(kVarintSizeCases_case.size, + CodedOutputStream::VarintSize32( + static_cast(kVarintSizeCases_case.value))); +} + +TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) { + EXPECT_EQ(kVarintSizeCases_case.size, + CodedOutputStream::VarintSize64(kVarintSizeCases_case.value)); +} + +// ------------------------------------------------------------------- +// Fixed-size int tests + +struct Fixed32Case { + uint8 bytes[sizeof(uint32)]; // Encoded bytes. + uint32 value; // Parsed value. +}; + +struct Fixed64Case { + uint8 bytes[sizeof(uint64)]; // Encoded bytes. + uint64 value; // Parsed value. +}; + +inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) { + return os << "0x" << hex << c.value << dec; +} + +inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) { + return os << "0x" << hex << c.value << dec; +} + +Fixed32Case kFixed32Cases[] = { + {{0xef, 0xcd, 0xab, 0x90}, 0x90abcdefu}, + {{0x12, 0x34, 0x56, 0x78}, 0x78563412u}, +}; + +Fixed64Case kFixed64Cases[] = { + {{0xef, 0xcd, 0xab, 0x90, 0x12, 0x34, 0x56, 0x78}, ULL(0x7856341290abcdef)}, + {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, ULL(0x8877665544332211)}, +}; + +TEST_2D(CodedStreamTest, ReadLittleEndian32, kFixed32Cases, kBlockSizes) { + memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes)); + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedInputStream coded_input(&input); + + uint32 value; + EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); + EXPECT_EQ(kFixed32Cases_case.value, value); + } + + EXPECT_EQ(sizeof(uint32), input.ByteCount()); +} + +TEST_2D(CodedStreamTest, ReadLittleEndian64, kFixed64Cases, kBlockSizes) { + memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes)); + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedInputStream coded_input(&input); + + uint64 value; + EXPECT_TRUE(coded_input.ReadLittleEndian64(&value)); + EXPECT_EQ(kFixed64Cases_case.value, value); + } + + EXPECT_EQ(sizeof(uint64), input.ByteCount()); +} + +TEST_2D(CodedStreamTest, WriteLittleEndian32, kFixed32Cases, kBlockSizes) { + ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedOutputStream coded_output(&output); + + coded_output.WriteLittleEndian32(kFixed32Cases_case.value); + EXPECT_FALSE(coded_output.HadError()); + + EXPECT_EQ(sizeof(uint32), coded_output.ByteCount()); + } + + EXPECT_EQ(sizeof(uint32), output.ByteCount()); + EXPECT_EQ(0, memcmp(buffer_, kFixed32Cases_case.bytes, sizeof(uint32))); +} + +TEST_2D(CodedStreamTest, WriteLittleEndian64, kFixed64Cases, kBlockSizes) { + ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedOutputStream coded_output(&output); + + coded_output.WriteLittleEndian64(kFixed64Cases_case.value); + EXPECT_FALSE(coded_output.HadError()); + + EXPECT_EQ(sizeof(uint64), coded_output.ByteCount()); + } + + EXPECT_EQ(sizeof(uint64), output.ByteCount()); + EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64))); +} + +// Tests using the static methods to read fixed-size values from raw arrays. + +TEST_1D(CodedStreamTest, ReadLittleEndian32FromArray, kFixed32Cases) { + memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes)); + + uint32 value; + const uint8* end = CodedInputStream::ReadLittleEndian32FromArray( + buffer_, &value); + EXPECT_EQ(kFixed32Cases_case.value, value); + EXPECT_TRUE(end == buffer_ + sizeof(value)); +} + +TEST_1D(CodedStreamTest, ReadLittleEndian64FromArray, kFixed64Cases) { + memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes)); + + uint64 value; + const uint8* end = CodedInputStream::ReadLittleEndian64FromArray( + buffer_, &value); + EXPECT_EQ(kFixed64Cases_case.value, value); + EXPECT_TRUE(end == buffer_ + sizeof(value)); +} + +// ------------------------------------------------------------------- +// Raw reads and writes + +const char kRawBytes[] = "Some bytes which will be written and read raw."; + +TEST_1D(CodedStreamTest, ReadRaw, kBlockSizes) { + memcpy(buffer_, kRawBytes, sizeof(kRawBytes)); + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + char read_buffer[sizeof(kRawBytes)]; + + { + CodedInputStream coded_input(&input); + + EXPECT_TRUE(coded_input.ReadRaw(read_buffer, sizeof(kRawBytes))); + EXPECT_EQ(0, memcmp(kRawBytes, read_buffer, sizeof(kRawBytes))); + } + + EXPECT_EQ(sizeof(kRawBytes), input.ByteCount()); +} + +TEST_1D(CodedStreamTest, WriteRaw, kBlockSizes) { + ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedOutputStream coded_output(&output); + + coded_output.WriteRaw(kRawBytes, sizeof(kRawBytes)); + EXPECT_FALSE(coded_output.HadError()); + + EXPECT_EQ(sizeof(kRawBytes), coded_output.ByteCount()); + } + + EXPECT_EQ(sizeof(kRawBytes), output.ByteCount()); + EXPECT_EQ(0, memcmp(buffer_, kRawBytes, sizeof(kRawBytes))); +} + +TEST_1D(CodedStreamTest, ReadString, kBlockSizes) { + memcpy(buffer_, kRawBytes, sizeof(kRawBytes)); + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedInputStream coded_input(&input); + + string str; + EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes))); + EXPECT_EQ(kRawBytes, str); + } + + EXPECT_EQ(strlen(kRawBytes), input.ByteCount()); +} + +// Check to make sure ReadString doesn't crash on impossibly large strings. +TEST_1D(CodedStreamTest, ReadStringImpossiblyLarge, kBlockSizes) { + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedInputStream coded_input(&input); + + string str; + // Try to read a gigabyte. + EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30)); + } +} + +TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnStack) { + // Same test as above, except directly use a buffer. This used to cause + // crashes while the above did not. + uint8 buffer[8]; + CodedInputStream coded_input(buffer, 8); + string str; + EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30)); +} + +TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnHeap) { + scoped_array buffer(new uint8[8]); + CodedInputStream coded_input(buffer.get(), 8); + string str; + EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30)); +} + + +// ------------------------------------------------------------------- +// Skip + +const char kSkipTestBytes[] = + ""; +const char kSkipOutputTestBytes[] = + "---------------------------------"; + +TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) { + memcpy(buffer_, kSkipTestBytes, sizeof(kSkipTestBytes)); + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedInputStream coded_input(&input); + + string str; + EXPECT_TRUE(coded_input.ReadString(&str, strlen(""))); + EXPECT_EQ("", str); + EXPECT_TRUE(coded_input.Skip(strlen(""))); + EXPECT_TRUE(coded_input.ReadString(&str, strlen(""))); + EXPECT_EQ("", str); + } + + EXPECT_EQ(strlen(kSkipTestBytes), input.ByteCount()); +} + +// ------------------------------------------------------------------- +// GetDirectBufferPointer + +TEST_F(CodedStreamTest, GetDirectBufferPointerInput) { + ArrayInputStream input(buffer_, sizeof(buffer_), 8); + CodedInputStream coded_input(&input); + + const void* ptr; + int size; + + EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size)); + EXPECT_EQ(buffer_, ptr); + EXPECT_EQ(8, size); + + // Peeking again should return the same pointer. + EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size)); + EXPECT_EQ(buffer_, ptr); + EXPECT_EQ(8, size); + + // Skip forward in the same buffer then peek again. + EXPECT_TRUE(coded_input.Skip(3)); + EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size)); + EXPECT_EQ(buffer_ + 3, ptr); + EXPECT_EQ(5, size); + + // Skip to end of buffer and peek -- should get next buffer. + EXPECT_TRUE(coded_input.Skip(5)); + EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size)); + EXPECT_EQ(buffer_ + 8, ptr); + EXPECT_EQ(8, size); +} + +TEST_F(CodedStreamTest, GetDirectBufferPointerInlineInput) { + ArrayInputStream input(buffer_, sizeof(buffer_), 8); + CodedInputStream coded_input(&input); + + const void* ptr; + int size; + + coded_input.GetDirectBufferPointerInline(&ptr, &size); + EXPECT_EQ(buffer_, ptr); + EXPECT_EQ(8, size); + + // Peeking again should return the same pointer. + coded_input.GetDirectBufferPointerInline(&ptr, &size); + EXPECT_EQ(buffer_, ptr); + EXPECT_EQ(8, size); + + // Skip forward in the same buffer then peek again. + EXPECT_TRUE(coded_input.Skip(3)); + coded_input.GetDirectBufferPointerInline(&ptr, &size); + EXPECT_EQ(buffer_ + 3, ptr); + EXPECT_EQ(5, size); + + // Skip to end of buffer and peek -- should return false and provide an empty + // buffer. It does not try to Refresh(). + EXPECT_TRUE(coded_input.Skip(5)); + coded_input.GetDirectBufferPointerInline(&ptr, &size); + EXPECT_EQ(buffer_ + 8, ptr); + EXPECT_EQ(0, size); +} + +TEST_F(CodedStreamTest, GetDirectBufferPointerOutput) { + ArrayOutputStream output(buffer_, sizeof(buffer_), 8); + CodedOutputStream coded_output(&output); + + void* ptr; + int size; + + EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size)); + EXPECT_EQ(buffer_, ptr); + EXPECT_EQ(8, size); + + // Peeking again should return the same pointer. + EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size)); + EXPECT_EQ(buffer_, ptr); + EXPECT_EQ(8, size); + + // Skip forward in the same buffer then peek again. + EXPECT_TRUE(coded_output.Skip(3)); + EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size)); + EXPECT_EQ(buffer_ + 3, ptr); + EXPECT_EQ(5, size); + + // Skip to end of buffer and peek -- should get next buffer. + EXPECT_TRUE(coded_output.Skip(5)); + EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size)); + EXPECT_EQ(buffer_ + 8, ptr); + EXPECT_EQ(8, size); + + // Skip over multiple buffers. + EXPECT_TRUE(coded_output.Skip(22)); + EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size)); + EXPECT_EQ(buffer_ + 30, ptr); + EXPECT_EQ(2, size); +} + +// ------------------------------------------------------------------- +// Limits + +TEST_1D(CodedStreamTest, BasicLimit, kBlockSizes) { + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedInputStream coded_input(&input); + + EXPECT_EQ(-1, coded_input.BytesUntilLimit()); + CodedInputStream::Limit limit = coded_input.PushLimit(8); + + // Read until we hit the limit. + uint32 value; + EXPECT_EQ(8, coded_input.BytesUntilLimit()); + EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); + EXPECT_EQ(4, coded_input.BytesUntilLimit()); + EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); + EXPECT_EQ(0, coded_input.BytesUntilLimit()); + EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); + EXPECT_EQ(0, coded_input.BytesUntilLimit()); + + coded_input.PopLimit(limit); + + EXPECT_EQ(-1, coded_input.BytesUntilLimit()); + EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); + } + + EXPECT_EQ(12, input.ByteCount()); +} + +// Test what happens when we push two limits where the second (top) one is +// shorter. +TEST_1D(CodedStreamTest, SmallLimitOnTopOfBigLimit, kBlockSizes) { + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedInputStream coded_input(&input); + + EXPECT_EQ(-1, coded_input.BytesUntilLimit()); + CodedInputStream::Limit limit1 = coded_input.PushLimit(8); + EXPECT_EQ(8, coded_input.BytesUntilLimit()); + CodedInputStream::Limit limit2 = coded_input.PushLimit(4); + + uint32 value; + + // Read until we hit limit2, the top and shortest limit. + EXPECT_EQ(4, coded_input.BytesUntilLimit()); + EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); + EXPECT_EQ(0, coded_input.BytesUntilLimit()); + EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); + EXPECT_EQ(0, coded_input.BytesUntilLimit()); + + coded_input.PopLimit(limit2); + + // Read until we hit limit1. + EXPECT_EQ(4, coded_input.BytesUntilLimit()); + EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); + EXPECT_EQ(0, coded_input.BytesUntilLimit()); + EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); + EXPECT_EQ(0, coded_input.BytesUntilLimit()); + + coded_input.PopLimit(limit1); + + // No more limits. + EXPECT_EQ(-1, coded_input.BytesUntilLimit()); + EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); + } + + EXPECT_EQ(12, input.ByteCount()); +} + +// Test what happens when we push two limits where the second (top) one is +// longer. In this case, the top limit is shortened to match the previous +// limit. +TEST_1D(CodedStreamTest, BigLimitOnTopOfSmallLimit, kBlockSizes) { + ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); + + { + CodedInputStream coded_input(&input); + + EXPECT_EQ(-1, coded_input.BytesUntilLimit()); + CodedInputStream::Limit limit1 = coded_input.PushLimit(4); + EXPECT_EQ(4, coded_input.BytesUntilLimit()); + CodedInputStream::Limit limit2 = coded_input.PushLimit(8); + + uint32 value; + + // Read until we hit limit2. Except, wait! limit1 is shorter, so + // we end up hitting that first, despite having 4 bytes to go on + // limit2. + EXPECT_EQ(4, coded_input.BytesUntilLimit()); + EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); + EXPECT_EQ(0, coded_input.BytesUntilLimit()); + EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); + EXPECT_EQ(0, coded_input.BytesUntilLimit()); + + coded_input.PopLimit(limit2); + + // OK, popped limit2, now limit1 is on top, which we've already hit. + EXPECT_EQ(0, coded_input.BytesUntilLimit()); + EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); + EXPECT_EQ(0, coded_input.BytesUntilLimit()); + + coded_input.PopLimit(limit1); + + // No more limits. + EXPECT_EQ(-1, coded_input.BytesUntilLimit()); + EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); + } + + EXPECT_EQ(8, input.ByteCount()); +} + +TEST_F(CodedStreamTest, ExpectAtEnd) { + // Test ExpectAtEnd(), which is based on limits. + ArrayInputStream input(buffer_, sizeof(buffer_)); + CodedInputStream coded_input(&input); + + EXPECT_FALSE(coded_input.ExpectAtEnd()); + + CodedInputStream::Limit limit = coded_input.PushLimit(4); + + uint32 value; + EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); + EXPECT_TRUE(coded_input.ExpectAtEnd()); + + coded_input.PopLimit(limit); + EXPECT_FALSE(coded_input.ExpectAtEnd()); +} + +TEST_F(CodedStreamTest, NegativeLimit) { + // Check what happens when we push a negative limit. + ArrayInputStream input(buffer_, sizeof(buffer_)); + CodedInputStream coded_input(&input); + + CodedInputStream::Limit limit = coded_input.PushLimit(-1234); + // BytesUntilLimit() returns -1 to mean "no limit", which actually means + // "the limit is INT_MAX relative to the beginning of the stream". + EXPECT_EQ(-1, coded_input.BytesUntilLimit()); + coded_input.PopLimit(limit); +} + +TEST_F(CodedStreamTest, NegativeLimitAfterReading) { + // Check what happens when we push a negative limit. + ArrayInputStream input(buffer_, sizeof(buffer_)); + CodedInputStream coded_input(&input); + ASSERT_TRUE(coded_input.Skip(128)); + + CodedInputStream::Limit limit = coded_input.PushLimit(-64); + // BytesUntilLimit() returns -1 to mean "no limit", which actually means + // "the limit is INT_MAX relative to the beginning of the stream". + EXPECT_EQ(-1, coded_input.BytesUntilLimit()); + coded_input.PopLimit(limit); +} + +TEST_F(CodedStreamTest, OverflowLimit) { + // Check what happens when we push a limit large enough that its absolute + // position is more than 2GB into the stream. + ArrayInputStream input(buffer_, sizeof(buffer_)); + CodedInputStream coded_input(&input); + ASSERT_TRUE(coded_input.Skip(128)); + + CodedInputStream::Limit limit = coded_input.PushLimit(INT_MAX); + // BytesUntilLimit() returns -1 to mean "no limit", which actually means + // "the limit is INT_MAX relative to the beginning of the stream". + EXPECT_EQ(-1, coded_input.BytesUntilLimit()); + coded_input.PopLimit(limit); +} + +TEST_F(CodedStreamTest, TotalBytesLimit) { + ArrayInputStream input(buffer_, sizeof(buffer_)); + CodedInputStream coded_input(&input); + coded_input.SetTotalBytesLimit(16, -1); + + string str; + EXPECT_TRUE(coded_input.ReadString(&str, 16)); + + vector errors; + + { + ScopedMemoryLog error_log; + EXPECT_FALSE(coded_input.ReadString(&str, 1)); + errors = error_log.GetMessages(ERROR); + } + + ASSERT_EQ(1, errors.size()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, + "A protocol message was rejected because it was too big", errors[0]); + + coded_input.SetTotalBytesLimit(32, -1); + EXPECT_TRUE(coded_input.ReadString(&str, 16)); +} + +TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) { + // total_bytes_limit_ is not a valid place for a message to end. + + ArrayInputStream input(buffer_, sizeof(buffer_)); + CodedInputStream coded_input(&input); + + // Set both total_bytes_limit and a regular limit at 16 bytes. + coded_input.SetTotalBytesLimit(16, -1); + CodedInputStream::Limit limit = coded_input.PushLimit(16); + + // Read 16 bytes. + string str; + EXPECT_TRUE(coded_input.ReadString(&str, 16)); + + // Read a tag. Should fail, but report being a valid endpoint since it's + // a regular limit. + EXPECT_EQ(0, coded_input.ReadTag()); + EXPECT_TRUE(coded_input.ConsumedEntireMessage()); + + // Pop the limit. + coded_input.PopLimit(limit); + + // Read a tag. Should fail, and report *not* being a valid endpoint, since + // this time we're hitting the total bytes limit. + EXPECT_EQ(0, coded_input.ReadTag()); + EXPECT_FALSE(coded_input.ConsumedEntireMessage()); +} + +// This method is used by the tests below. +// It constructs a CodedInputStream with the given limits and tries to read 2KiB +// of data from it. Then it returns the logged errors and warnings in the given +// vectors. +void CodedStreamTest::SetupTotalBytesLimitWarningTest( + int total_bytes_limit, int warning_threshold, + vector* out_errors, vector* out_warnings) { + ArrayInputStream raw_input(buffer_, sizeof(buffer_), 128); + + ScopedMemoryLog scoped_log; + { + CodedInputStream input(&raw_input); + input.SetTotalBytesLimit(total_bytes_limit, warning_threshold); + string str; + EXPECT_TRUE(input.ReadString(&str, 2048)); + } + + *out_errors = scoped_log.GetMessages(ERROR); + *out_warnings = scoped_log.GetMessages(WARNING); +} + +TEST_F(CodedStreamTest, TotalBytesLimitWarning) { + vector errors; + vector warnings; + SetupTotalBytesLimitWarningTest(10240, 1024, &errors, &warnings); + + EXPECT_EQ(0, errors.size()); + + ASSERT_EQ(2, warnings.size()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, + "Reading dangerously large protocol message. If the message turns out to " + "be larger than 10240 bytes, parsing will be halted for security reasons.", + warnings[0]); + EXPECT_PRED_FORMAT2(testing::IsSubstring, + "The total number of bytes read was 2048", + warnings[1]); +} + +TEST_F(CodedStreamTest, TotalBytesLimitWarningDisabled) { + vector errors; + vector warnings; + + // Test with -1 + SetupTotalBytesLimitWarningTest(10240, -1, &errors, &warnings); + EXPECT_EQ(0, errors.size()); + EXPECT_EQ(0, warnings.size()); + + // Test again with -2, expecting the same result + SetupTotalBytesLimitWarningTest(10240, -2, &errors, &warnings); + EXPECT_EQ(0, errors.size()); + EXPECT_EQ(0, warnings.size()); +} + + +TEST_F(CodedStreamTest, RecursionLimit) { + ArrayInputStream input(buffer_, sizeof(buffer_)); + CodedInputStream coded_input(&input); + coded_input.SetRecursionLimit(4); + + // This is way too much testing for a counter. + EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1 + EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2 + EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3 + EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4 + EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5 + EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6 + coded_input.DecrementRecursionDepth(); // 5 + EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6 + coded_input.DecrementRecursionDepth(); // 5 + coded_input.DecrementRecursionDepth(); // 4 + coded_input.DecrementRecursionDepth(); // 3 + EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4 + EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5 + coded_input.DecrementRecursionDepth(); // 4 + coded_input.DecrementRecursionDepth(); // 3 + coded_input.DecrementRecursionDepth(); // 2 + coded_input.DecrementRecursionDepth(); // 1 + coded_input.DecrementRecursionDepth(); // 0 + coded_input.DecrementRecursionDepth(); // 0 + coded_input.DecrementRecursionDepth(); // 0 + EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1 + EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2 + EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3 + EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4 + EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5 + + coded_input.SetRecursionLimit(6); + EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 6 + EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 7 +} + + +class ReallyBigInputStream : public ZeroCopyInputStream { + public: + ReallyBigInputStream() : backup_amount_(0), buffer_count_(0) {} + ~ReallyBigInputStream() {} + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size) { + // We only expect BackUp() to be called at the end. + EXPECT_EQ(0, backup_amount_); + + switch (buffer_count_++) { + case 0: + *data = buffer_; + *size = sizeof(buffer_); + return true; + case 1: + // Return an enormously large buffer that, when combined with the 1k + // returned already, should overflow the total_bytes_read_ counter in + // CodedInputStream. Note that we'll only read the first 1024 bytes + // of this buffer so it's OK that we have it point at buffer_. + *data = buffer_; + *size = INT_MAX; + return true; + default: + return false; + } + } + + void BackUp(int count) { + backup_amount_ = count; + } + + bool Skip(int count) { GOOGLE_LOG(FATAL) << "Not implemented."; return false; } + int64 ByteCount() const { GOOGLE_LOG(FATAL) << "Not implemented."; return 0; } + + int backup_amount_; + + private: + char buffer_[1024]; + int64 buffer_count_; +}; + +TEST_F(CodedStreamTest, InputOver2G) { + // CodedInputStream should gracefully handle input over 2G and call + // input.BackUp() with the correct number of bytes on destruction. + ReallyBigInputStream input; + + vector errors; + + { + ScopedMemoryLog error_log; + CodedInputStream coded_input(&input); + string str; + EXPECT_TRUE(coded_input.ReadString(&str, 512)); + EXPECT_TRUE(coded_input.ReadString(&str, 1024)); + errors = error_log.GetMessages(ERROR); + } + + EXPECT_EQ(INT_MAX - 512, input.backup_amount_); + EXPECT_EQ(0, errors.size()); +} + +// =================================================================== + + +} // namespace +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream.cc new file mode 100644 index 0000000..fe1f331 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream.cc @@ -0,0 +1,326 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: brianolson@google.com (Brian Olson) +// +// This file contains the implementation of classes GzipInputStream and +// GzipOutputStream. + +#include "config.h" + +#if HAVE_ZLIB +#include + +#include + +namespace google { +namespace protobuf { +namespace io { + +static const int kDefaultBufferSize = 65536; + +GzipInputStream::GzipInputStream( + ZeroCopyInputStream* sub_stream, Format format, int buffer_size) + : format_(format), sub_stream_(sub_stream), zerror_(Z_OK) { + zcontext_.zalloc = Z_NULL; + zcontext_.zfree = Z_NULL; + zcontext_.opaque = Z_NULL; + zcontext_.total_out = 0; + zcontext_.next_in = NULL; + zcontext_.avail_in = 0; + zcontext_.total_in = 0; + zcontext_.msg = NULL; + if (buffer_size == -1) { + output_buffer_length_ = kDefaultBufferSize; + } else { + output_buffer_length_ = buffer_size; + } + output_buffer_ = operator new(output_buffer_length_); + GOOGLE_CHECK(output_buffer_ != NULL); + zcontext_.next_out = static_cast(output_buffer_); + zcontext_.avail_out = output_buffer_length_; + output_position_ = output_buffer_; +} +GzipInputStream::~GzipInputStream() { + operator delete(output_buffer_); + zerror_ = inflateEnd(&zcontext_); +} + +static inline int internalInflateInit2( + z_stream* zcontext, GzipInputStream::Format format) { + int windowBitsFormat = 0; + switch (format) { + case GzipInputStream::GZIP: windowBitsFormat = 16; break; + case GzipInputStream::AUTO: windowBitsFormat = 32; break; + case GzipInputStream::ZLIB: windowBitsFormat = 0; break; + } + return inflateInit2(zcontext, /* windowBits */15 | windowBitsFormat); +} + +int GzipInputStream::Inflate(int flush) { + if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) { + // previous inflate filled output buffer. don't change input params yet. + } else if (zcontext_.avail_in == 0) { + const void* in; + int in_size; + bool first = zcontext_.next_in == NULL; + bool ok = sub_stream_->Next(&in, &in_size); + if (!ok) { + zcontext_.next_out = NULL; + zcontext_.avail_out = 0; + return Z_STREAM_END; + } + zcontext_.next_in = static_cast(const_cast(in)); + zcontext_.avail_in = in_size; + if (first) { + int error = internalInflateInit2(&zcontext_, format_); + if (error != Z_OK) { + return error; + } + } + } + zcontext_.next_out = static_cast(output_buffer_); + zcontext_.avail_out = output_buffer_length_; + output_position_ = output_buffer_; + int error = inflate(&zcontext_, flush); + return error; +} + +void GzipInputStream::DoNextOutput(const void** data, int* size) { + *data = output_position_; + *size = ((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_); + output_position_ = zcontext_.next_out; +} + +// implements ZeroCopyInputStream ---------------------------------- +bool GzipInputStream::Next(const void** data, int* size) { + bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) + || (zerror_ == Z_BUF_ERROR); + if ((!ok) || (zcontext_.next_out == NULL)) { + return false; + } + if (zcontext_.next_out != output_position_) { + DoNextOutput(data, size); + return true; + } + if (zerror_ == Z_STREAM_END) { + if (zcontext_.next_out != NULL) { + // sub_stream_ may have concatenated streams to follow + zerror_ = inflateEnd(&zcontext_); + if (zerror_ != Z_OK) { + return false; + } + zerror_ = internalInflateInit2(&zcontext_, format_); + if (zerror_ != Z_OK) { + return false; + } + } else { + *data = NULL; + *size = 0; + return false; + } + } + zerror_ = Inflate(Z_NO_FLUSH); + if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) { + // The underlying stream's Next returned false inside Inflate. + return false; + } + ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) + || (zerror_ == Z_BUF_ERROR); + if (!ok) { + return false; + } + DoNextOutput(data, size); + return true; +} +void GzipInputStream::BackUp(int count) { + output_position_ = reinterpret_cast( + reinterpret_cast(output_position_) - count); +} +bool GzipInputStream::Skip(int count) { + const void* data; + int size; + bool ok = Next(&data, &size); + while (ok && (size < count)) { + count -= size; + ok = Next(&data, &size); + } + if (size > count) { + BackUp(size - count); + } + return ok; +} +int64 GzipInputStream::ByteCount() const { + return zcontext_.total_out + + (((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_)); +} + +// ========================================================================= + +GzipOutputStream::Options::Options() + : format(GZIP), + buffer_size(kDefaultBufferSize), + compression_level(Z_DEFAULT_COMPRESSION), + compression_strategy(Z_DEFAULT_STRATEGY) {} + +GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream) { + Init(sub_stream, Options()); +} + +GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream, + const Options& options) { + Init(sub_stream, options); +} + +void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream, + const Options& options) { + sub_stream_ = sub_stream; + sub_data_ = NULL; + sub_data_size_ = 0; + + input_buffer_length_ = options.buffer_size; + input_buffer_ = operator new(input_buffer_length_); + GOOGLE_CHECK(input_buffer_ != NULL); + + zcontext_.zalloc = Z_NULL; + zcontext_.zfree = Z_NULL; + zcontext_.opaque = Z_NULL; + zcontext_.next_out = NULL; + zcontext_.avail_out = 0; + zcontext_.total_out = 0; + zcontext_.next_in = NULL; + zcontext_.avail_in = 0; + zcontext_.total_in = 0; + zcontext_.msg = NULL; + // default to GZIP format + int windowBitsFormat = 16; + if (options.format == ZLIB) { + windowBitsFormat = 0; + } + zerror_ = deflateInit2( + &zcontext_, + options.compression_level, + Z_DEFLATED, + /* windowBits */15 | windowBitsFormat, + /* memLevel (default) */8, + options.compression_strategy); +} + +GzipOutputStream::~GzipOutputStream() { + Close(); + if (input_buffer_ != NULL) { + operator delete(input_buffer_); + } +} + +// private +int GzipOutputStream::Deflate(int flush) { + int error = Z_OK; + do { + if ((sub_data_ == NULL) || (zcontext_.avail_out == 0)) { + bool ok = sub_stream_->Next(&sub_data_, &sub_data_size_); + if (!ok) { + sub_data_ = NULL; + sub_data_size_ = 0; + return Z_BUF_ERROR; + } + GOOGLE_CHECK_GT(sub_data_size_, 0); + zcontext_.next_out = static_cast(sub_data_); + zcontext_.avail_out = sub_data_size_; + } + error = deflate(&zcontext_, flush); + } while (error == Z_OK && zcontext_.avail_out == 0); + if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) { + // Notify lower layer of data. + sub_stream_->BackUp(zcontext_.avail_out); + // We don't own the buffer anymore. + sub_data_ = NULL; + sub_data_size_ = 0; + } + return error; +} + +// implements ZeroCopyOutputStream --------------------------------- +bool GzipOutputStream::Next(void** data, int* size) { + if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) { + return false; + } + if (zcontext_.avail_in != 0) { + zerror_ = Deflate(Z_NO_FLUSH); + if (zerror_ != Z_OK) { + return false; + } + } + if (zcontext_.avail_in == 0) { + // all input was consumed. reset the buffer. + zcontext_.next_in = static_cast(input_buffer_); + zcontext_.avail_in = input_buffer_length_; + *data = input_buffer_; + *size = input_buffer_length_; + } else { + // The loop in Deflate should consume all avail_in + GOOGLE_LOG(DFATAL) << "Deflate left bytes unconsumed"; + } + return true; +} +void GzipOutputStream::BackUp(int count) { + GOOGLE_CHECK_GE(zcontext_.avail_in, count); + zcontext_.avail_in -= count; +} +int64 GzipOutputStream::ByteCount() const { + return zcontext_.total_in + zcontext_.avail_in; +} + +bool GzipOutputStream::Flush() { + zerror_ = Deflate(Z_FULL_FLUSH); + // Return true if the flush succeeded or if it was a no-op. + return (zerror_ == Z_OK) || + (zerror_ == Z_BUF_ERROR && zcontext_.avail_in == 0 && + zcontext_.avail_out != 0); +} + +bool GzipOutputStream::Close() { + if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) { + return false; + } + do { + zerror_ = Deflate(Z_FINISH); + } while (zerror_ == Z_OK); + zerror_ = deflateEnd(&zcontext_); + bool ok = zerror_ == Z_OK; + zerror_ = Z_STREAM_END; + return ok; +} + +} // namespace io +} // namespace protobuf +} // namespace google + +#endif // HAVE_ZLIB diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream.h new file mode 100644 index 0000000..365e9ea --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream.h @@ -0,0 +1,209 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: brianolson@google.com (Brian Olson) +// +// This file contains the definition for classes GzipInputStream and +// GzipOutputStream. +// +// GzipInputStream decompresses data from an underlying +// ZeroCopyInputStream and provides the decompressed data as a +// ZeroCopyInputStream. +// +// GzipOutputStream is an ZeroCopyOutputStream that compresses data to +// an underlying ZeroCopyOutputStream. + +#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ +#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ + +#include + +#include +#include + +namespace google { +namespace protobuf { +namespace io { + +// A ZeroCopyInputStream that reads compressed data through zlib +class LIBPROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream { + public: + // Format key for constructor + enum Format { + // zlib will autodetect gzip header or deflate stream + AUTO = 0, + + // GZIP streams have some extra header data for file attributes. + GZIP = 1, + + // Simpler zlib stream format. + ZLIB = 2, + }; + + // buffer_size and format may be -1 for default of 64kB and GZIP format + explicit GzipInputStream( + ZeroCopyInputStream* sub_stream, + Format format = AUTO, + int buffer_size = -1); + virtual ~GzipInputStream(); + + // Return last error message or NULL if no error. + inline const char* ZlibErrorMessage() const { + return zcontext_.msg; + } + inline int ZlibErrorCode() const { + return zerror_; + } + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + private: + Format format_; + + ZeroCopyInputStream* sub_stream_; + + z_stream zcontext_; + int zerror_; + + void* output_buffer_; + void* output_position_; + size_t output_buffer_length_; + + int Inflate(int flush); + void DoNextOutput(const void** data, int* size); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream); +}; + + +class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream { + public: + // Format key for constructor + enum Format { + // GZIP streams have some extra header data for file attributes. + GZIP = 1, + + // Simpler zlib stream format. + ZLIB = 2, + }; + + struct LIBPROTOBUF_EXPORT Options { + // Defaults to GZIP. + Format format; + + // What size buffer to use internally. Defaults to 64kB. + int buffer_size; + + // A number between 0 and 9, where 0 is no compression and 9 is best + // compression. Defaults to Z_DEFAULT_COMPRESSION (see zlib.h). + int compression_level; + + // Defaults to Z_DEFAULT_STRATEGY. Can also be set to Z_FILTERED, + // Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in + // zlib.h for definitions of these constants. + int compression_strategy; + + Options(); // Initializes with default values. + }; + + // Create a GzipOutputStream with default options. + explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream); + + // Create a GzipOutputStream with the given options. + GzipOutputStream( + ZeroCopyOutputStream* sub_stream, + const Options& options); + + virtual ~GzipOutputStream(); + + // Return last error message or NULL if no error. + inline const char* ZlibErrorMessage() const { + return zcontext_.msg; + } + inline int ZlibErrorCode() const { + return zerror_; + } + + // Flushes data written so far to zipped data in the underlying stream. + // It is the caller's responsibility to flush the underlying stream if + // necessary. + // Compression may be less efficient stopping and starting around flushes. + // Returns true if no error. + // + // Please ensure that block size is > 6. Here is an excerpt from the zlib + // doc that explains why: + // + // In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out + // is greater than six to avoid repeated flush markers due to + // avail_out == 0 on return. + bool Flush(); + + // Writes out all data and closes the gzip stream. + // It is the caller's responsibility to close the underlying stream if + // necessary. + // Returns true if no error. + bool Close(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + ZeroCopyOutputStream* sub_stream_; + // Result from calling Next() on sub_stream_ + void* sub_data_; + int sub_data_size_; + + z_stream zcontext_; + int zerror_; + void* input_buffer_; + size_t input_buffer_length_; + + // Shared constructor code. + void Init(ZeroCopyOutputStream* sub_stream, const Options& options); + + // Do some compression. + // Takes zlib flush mode. + // Returns zlib error code. + int Deflate(int flush); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream); +}; + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream_unittest.sh b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream_unittest.sh new file mode 100755 index 0000000..6e8a094 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/gzip_stream_unittest.sh @@ -0,0 +1,44 @@ +#!/bin/sh -x +# +# Protocol Buffers - Google's data interchange format +# Copyright 2009 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Author: brianolson@google.com (Brian Olson) +# +# Test compatibility between command line gzip/gunzip binaries and +# ZeroCopyStream versions. + +TESTFILE=Makefile + +(./zcgzip < ${TESTFILE} | gunzip | cmp - ${TESTFILE}) && \ +(gzip < ${TESTFILE} | ./zcgunzip | cmp - ${TESTFILE}) + +# Result of "(cmd) && (cmd)" implicitly becomes result of this script +# and thus the test. diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/package_info.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/package_info.h new file mode 100644 index 0000000..7a7a4e7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/package_info.h @@ -0,0 +1,54 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file exists solely to document the google::protobuf::io namespace. +// It is not compiled into anything, but it may be read by an automated +// documentation generator. + +namespace google { + +namespace protobuf { + +// Auxiliary classes used for I/O. +// +// The Protocol Buffer library uses the classes in this package to deal with +// I/O and encoding/decoding raw bytes. Most users will not need to +// deal with this package. However, users who want to adapt the system to +// work with their own I/O abstractions -- e.g., to allow Protocol Buffers +// to be read from a different kind of input stream without the need for a +// temporary buffer -- should take a closer look. +namespace io {} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer.cc new file mode 100644 index 0000000..d2bf3f5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer.cc @@ -0,0 +1,198 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { + +Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter) + : variable_delimiter_(variable_delimiter), + output_(output), + buffer_(NULL), + buffer_size_(0), + at_start_of_line_(true), + failed_(false) { +} + +Printer::~Printer() { + // Only BackUp() if we have called Next() at least once and never failed. + if (buffer_size_ > 0 && !failed_) { + output_->BackUp(buffer_size_); + } +} + +void Printer::Print(const map& variables, const char* text) { + int size = strlen(text); + int pos = 0; // The number of bytes we've written so far. + + for (int i = 0; i < size; i++) { + if (text[i] == '\n') { + // Saw newline. If there is more text, we may need to insert an indent + // here. So, write what we have so far, including the '\n'. + WriteRaw(text + pos, i - pos + 1); + pos = i + 1; + + // Setting this true will cause the next WriteRaw() to insert an indent + // first. + at_start_of_line_ = true; + + } else if (text[i] == variable_delimiter_) { + // Saw the start of a variable name. + + // Write what we have so far. + WriteRaw(text + pos, i - pos); + pos = i + 1; + + // Find closing delimiter. + const char* end = strchr(text + pos, variable_delimiter_); + if (end == NULL) { + GOOGLE_LOG(DFATAL) << " Unclosed variable name."; + end = text + pos; + } + int endpos = end - text; + + string varname(text + pos, endpos - pos); + if (varname.empty()) { + // Two delimiters in a row reduce to a literal delimiter character. + WriteRaw(&variable_delimiter_, 1); + } else { + // Replace with the variable's value. + map::const_iterator iter = variables.find(varname); + if (iter == variables.end()) { + GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname; + } else { + WriteRaw(iter->second.data(), iter->second.size()); + } + } + + // Advance past this variable. + i = endpos; + pos = endpos + 1; + } + } + + // Write the rest. + WriteRaw(text + pos, size - pos); +} + +void Printer::Print(const char* text) { + static map empty; + Print(empty, text); +} + +void Printer::Print(const char* text, + const char* variable, const string& value) { + map vars; + vars[variable] = value; + Print(vars, text); +} + +void Printer::Print(const char* text, + const char* variable1, const string& value1, + const char* variable2, const string& value2) { + map vars; + vars[variable1] = value1; + vars[variable2] = value2; + Print(vars, text); +} + +void Printer::Print(const char* text, + const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3) { + map vars; + vars[variable1] = value1; + vars[variable2] = value2; + vars[variable3] = value3; + Print(vars, text); +} + +void Printer::Indent() { + indent_ += " "; +} + +void Printer::Outdent() { + if (indent_.empty()) { + GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; + return; + } + + indent_.resize(indent_.size() - 2); +} + +void Printer::PrintRaw(const string& data) { + WriteRaw(data.data(), data.size()); +} + +void Printer::PrintRaw(const char* data) { + if (failed_) return; + WriteRaw(data, strlen(data)); +} + +void Printer::WriteRaw(const char* data, int size) { + if (failed_) return; + if (size == 0) return; + + if (at_start_of_line_ && (size > 0) && (data[0] != '\n')) { + // Insert an indent. + at_start_of_line_ = false; + WriteRaw(indent_.data(), indent_.size()); + if (failed_) return; + } + + while (size > buffer_size_) { + // Data exceeds space in the buffer. Copy what we can and request a + // new buffer. + memcpy(buffer_, data, buffer_size_); + data += buffer_size_; + size -= buffer_size_; + void* void_buffer; + failed_ = !output_->Next(&void_buffer, &buffer_size_); + if (failed_) return; + buffer_ = reinterpret_cast(void_buffer); + } + + // Buffer is big enough to receive the data; copy it. + memcpy(buffer_, data, size); + buffer_ += size; + buffer_size_ -= size; +} + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer.h new file mode 100644 index 0000000..5be4854 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer.h @@ -0,0 +1,136 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Utility class for writing text to a ZeroCopyOutputStream. + +#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__ +#define GOOGLE_PROTOBUF_IO_PRINTER_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { + +class ZeroCopyOutputStream; // zero_copy_stream.h + +// This simple utility class assists in code generation. It basically +// allows the caller to define a set of variables and then output some +// text with variable substitutions. Example usage: +// +// Printer printer(output, '$'); +// map vars; +// vars["name"] = "Bob"; +// printer.Print(vars, "My name is $name$."); +// +// The above writes "My name is Bob." to the output stream. +// +// Printer aggressively enforces correct usage, crashing (with assert failures) +// in the case of undefined variables in debug builds. This helps greatly in +// debugging code which uses it. +class LIBPROTOBUF_EXPORT Printer { + public: + // Create a printer that writes text to the given output stream. Use the + // given character as the delimiter for variables. + Printer(ZeroCopyOutputStream* output, char variable_delimiter); + ~Printer(); + + // Print some text after applying variable substitutions. If a particular + // variable in the text is not defined, this will crash. Variables to be + // substituted are identified by their names surrounded by delimiter + // characters (as given to the constructor). The variable bindings are + // defined by the given map. + void Print(const map& variables, const char* text); + + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable, const string& value); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3); + // TODO(kenton): Overloaded versions with more variables? Three seems + // to be enough. + + // Indent text by two spaces. After calling Indent(), two spaces will be + // inserted at the beginning of each line of text. Indent() may be called + // multiple times to produce deeper indents. + void Indent(); + + // Reduces the current indent level by two spaces, or crashes if the indent + // level is zero. + void Outdent(); + + // Write a string to the output buffer. + // This method does not look for newlines to add indentation. + void PrintRaw(const string& data); + + // Write a zero-delimited string to output buffer. + // This method does not look for newlines to add indentation. + void PrintRaw(const char* data); + + // Write some bytes to the output buffer. + // This method does not look for newlines to add indentation. + void WriteRaw(const char* data, int size); + + // True if any write to the underlying stream failed. (We don't just + // crash in this case because this is an I/O failure, not a programming + // error.) + bool failed() const { return failed_; } + + private: + const char variable_delimiter_; + + ZeroCopyOutputStream* const output_; + char* buffer_; + int buffer_size_; + + string indent_; + bool at_start_of_line_; + bool failed_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer); +}; + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_PRINTER_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer_unittest.cc new file mode 100644 index 0000000..c9b3035 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/printer_unittest.cc @@ -0,0 +1,285 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include +#include + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { +namespace { + +// Each test repeats over several block sizes in order to test both cases +// where particular writes cross a buffer boundary and cases where they do +// not. + +TEST(Printer, EmptyPrinter) { + char buffer[8192]; + const int block_size = 100; + ArrayOutputStream output(buffer, GOOGLE_ARRAYSIZE(buffer), block_size); + Printer printer(&output, '\0'); + EXPECT_TRUE(!printer.failed()); +} + +TEST(Printer, BasicPrinting) { + char buffer[8192]; + + for (int block_size = 1; block_size < 512; block_size *= 2) { + ArrayOutputStream output(buffer, sizeof(buffer), block_size); + + { + Printer printer(&output, '\0'); + + printer.Print("Hello World!"); + printer.Print(" This is the same line.\n"); + printer.Print("But this is a new one.\nAnd this is another one."); + + EXPECT_FALSE(printer.failed()); + } + + buffer[output.ByteCount()] = '\0'; + + EXPECT_STREQ("Hello World! This is the same line.\n" + "But this is a new one.\n" + "And this is another one.", + buffer); + } +} + +TEST(Printer, WriteRaw) { + char buffer[8192]; + + for (int block_size = 1; block_size < 512; block_size *= 2) { + ArrayOutputStream output(buffer, sizeof(buffer), block_size); + + { + string string_obj = "From an object\n"; + Printer printer(&output, '$'); + printer.WriteRaw("Hello World!", 12); + printer.PrintRaw(" This is the same line.\n"); + printer.PrintRaw("But this is a new one.\nAnd this is another one."); + printer.WriteRaw("\n", 1); + printer.PrintRaw(string_obj); + EXPECT_FALSE(printer.failed()); + } + + buffer[output.ByteCount()] = '\0'; + + EXPECT_STREQ("Hello World! This is the same line.\n" + "But this is a new one.\n" + "And this is another one." + "\n" + "From an object\n", + buffer); + } +} + +TEST(Printer, VariableSubstitution) { + char buffer[8192]; + + for (int block_size = 1; block_size < 512; block_size *= 2) { + ArrayOutputStream output(buffer, sizeof(buffer), block_size); + + { + Printer printer(&output, '$'); + map vars; + + vars["foo"] = "World"; + vars["bar"] = "$foo$"; + vars["abcdefg"] = "1234"; + + printer.Print(vars, "Hello $foo$!\nbar = $bar$\n"); + printer.PrintRaw("RawBit\n"); + printer.Print(vars, "$abcdefg$\nA literal dollar sign: $$"); + + vars["foo"] = "blah"; + printer.Print(vars, "\nNow foo = $foo$."); + + EXPECT_FALSE(printer.failed()); + } + + buffer[output.ByteCount()] = '\0'; + + EXPECT_STREQ("Hello World!\n" + "bar = $foo$\n" + "RawBit\n" + "1234\n" + "A literal dollar sign: $\n" + "Now foo = blah.", + buffer); + } +} + +TEST(Printer, InlineVariableSubstitution) { + char buffer[8192]; + + ArrayOutputStream output(buffer, sizeof(buffer)); + + { + Printer printer(&output, '$'); + printer.Print("Hello $foo$!\n", "foo", "World"); + printer.PrintRaw("RawBit\n"); + printer.Print("$foo$ $bar$\n", "foo", "one", "bar", "two"); + EXPECT_FALSE(printer.failed()); + } + + buffer[output.ByteCount()] = '\0'; + + EXPECT_STREQ("Hello World!\n" + "RawBit\n" + "one two\n", + buffer); +} + +TEST(Printer, Indenting) { + char buffer[8192]; + + for (int block_size = 1; block_size < 512; block_size *= 2) { + ArrayOutputStream output(buffer, sizeof(buffer), block_size); + + { + Printer printer(&output, '$'); + map vars; + + vars["newline"] = "\n"; + + printer.Print("This is not indented.\n"); + printer.Indent(); + printer.Print("This is indented\nAnd so is this\n"); + printer.Outdent(); + printer.Print("But this is not."); + printer.Indent(); + printer.Print(" And this is still the same line.\n" + "But this is indented.\n"); + printer.PrintRaw("RawBit has indent at start\n"); + printer.PrintRaw("but not after a raw newline\n"); + printer.Print(vars, "Note that a newline in a variable will break " + "indenting, as we see$newline$here.\n"); + printer.Indent(); + printer.Print("And this"); + printer.Outdent(); + printer.Outdent(); + printer.Print(" is double-indented\nBack to normal."); + + EXPECT_FALSE(printer.failed()); + } + + buffer[output.ByteCount()] = '\0'; + + EXPECT_STREQ( + "This is not indented.\n" + " This is indented\n" + " And so is this\n" + "But this is not. And this is still the same line.\n" + " But this is indented.\n" + " RawBit has indent at start\n" + "but not after a raw newline\n" + "Note that a newline in a variable will break indenting, as we see\n" + "here.\n" + " And this is double-indented\n" + "Back to normal.", + buffer); + } +} + +// Death tests do not work on Windows as of yet. +#ifdef PROTOBUF_HAS_DEATH_TEST +TEST(Printer, Death) { + char buffer[8192]; + + ArrayOutputStream output(buffer, sizeof(buffer)); + Printer printer(&output, '$'); + + EXPECT_DEBUG_DEATH(printer.Print("$nosuchvar$"), "Undefined variable"); + EXPECT_DEBUG_DEATH(printer.Print("$unclosed"), "Unclosed variable name"); + EXPECT_DEBUG_DEATH(printer.Outdent(), "without matching Indent"); +} +#endif // PROTOBUF__HAS_DEATH_TEST + +TEST(Printer, WriteFailurePartial) { + char buffer[17]; + + ArrayOutputStream output(buffer, sizeof(buffer)); + Printer printer(&output, '$'); + + // Print 16 bytes to almost fill the buffer (should not fail). + printer.Print("0123456789abcdef"); + EXPECT_FALSE(printer.failed()); + + // Try to print 2 chars. Only one fits. + printer.Print("<>"); + EXPECT_TRUE(printer.failed()); + + // Anything else should fail too. + printer.Print(" "); + EXPECT_TRUE(printer.failed()); + printer.Print("blah"); + EXPECT_TRUE(printer.failed()); + + // Buffer should contain the first 17 bytes written. + EXPECT_EQ("0123456789abcdef<", string(buffer, sizeof(buffer))); +} + +TEST(Printer, WriteFailureExact) { + char buffer[16]; + + ArrayOutputStream output(buffer, sizeof(buffer)); + Printer printer(&output, '$'); + + // Print 16 bytes to fill the buffer exactly (should not fail). + printer.Print("0123456789abcdef"); + EXPECT_FALSE(printer.failed()); + + // Try to print one more byte (should fail). + printer.Print(" "); + EXPECT_TRUE(printer.failed()); + + // Should not crash + printer.Print("blah"); + EXPECT_TRUE(printer.failed()); + + // Buffer should contain the first 16 bytes written. + EXPECT_EQ("0123456789abcdef", string(buffer, sizeof(buffer))); +} + +} // namespace +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer.cc new file mode 100644 index 0000000..a022b71 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer.cc @@ -0,0 +1,1091 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Here we have a hand-written lexer. At first you might ask yourself, +// "Hand-written text processing? Is Kenton crazy?!" Well, first of all, +// yes I am crazy, but that's beside the point. There are actually reasons +// why I ended up writing this this way. +// +// The traditional approach to lexing is to use lex to generate a lexer for +// you. Unfortunately, lex's output is ridiculously ugly and difficult to +// integrate cleanly with C++ code, especially abstract code or code meant +// as a library. Better parser-generators exist but would add dependencies +// which most users won't already have, which we'd like to avoid. (GNU flex +// has a C++ output option, but it's still ridiculously ugly, non-abstract, +// and not library-friendly.) +// +// The next approach that any good software engineer should look at is to +// use regular expressions. And, indeed, I did. I have code which +// implements this same class using regular expressions. It's about 200 +// lines shorter. However: +// - Rather than error messages telling you "This string has an invalid +// escape sequence at line 5, column 45", you get error messages like +// "Parse error on line 5". Giving more precise errors requires adding +// a lot of code that ends up basically as complex as the hand-coded +// version anyway. +// - The regular expression to match a string literal looks like this: +// kString = new RE("(\"([^\"\\\\]|" // non-escaped +// "\\\\[abfnrtv?\"'\\\\0-7]|" // normal escape +// "\\\\x[0-9a-fA-F])*\"|" // hex escape +// "\'([^\'\\\\]|" // Also support single-quotes. +// "\\\\[abfnrtv?\"'\\\\0-7]|" +// "\\\\x[0-9a-fA-F])*\')"); +// Verifying the correctness of this line noise is actually harder than +// verifying the correctness of ConsumeString(), defined below. I'm not +// even confident that the above is correct, after staring at it for some +// time. +// - PCRE is fast, but there's still more overhead involved than the code +// below. +// - Sadly, regular expressions are not part of the C standard library, so +// using them would require depending on some other library. For the +// open source release, this could be really annoying. Nobody likes +// downloading one piece of software just to find that they need to +// download something else to make it work, and in all likelihood +// people downloading Protocol Buffers will already be doing so just +// to make something else work. We could include a copy of PCRE with +// our code, but that obligates us to keep it up-to-date and just seems +// like a big waste just to save 200 lines of code. +// +// On a similar but unrelated note, I'm even scared to use ctype.h. +// Apparently functions like isalpha() are locale-dependent. So, if we used +// that, then if this code is being called from some program that doesn't +// have its locale set to "C", it would behave strangely. We can't just set +// the locale to "C" ourselves since we might break the calling program that +// way, particularly if it is multi-threaded. WTF? Someone please let me +// (Kenton) know if I'm missing something here... +// +// I'd love to hear about other alternatives, though, as this code isn't +// exactly pretty. + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { +namespace { + +// As mentioned above, I don't trust ctype.h due to the presence of "locales". +// So, I have written replacement functions here. Someone please smack me if +// this is a bad idea or if there is some way around this. +// +// These "character classes" are designed to be used in template methods. +// For instance, Tokenizer::ConsumeZeroOrMore() will eat +// whitespace. + +// Note: No class is allowed to contain '\0', since this is used to mark end- +// of-input and is handled specially. + +#define CHARACTER_CLASS(NAME, EXPRESSION) \ + class NAME { \ + public: \ + static inline bool InClass(char c) { \ + return EXPRESSION; \ + } \ + } + +CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' || + c == '\r' || c == '\v' || c == '\f'); +CHARACTER_CLASS(WhitespaceNoNewline, c == ' ' || c == '\t' || + c == '\r' || c == '\v' || c == '\f'); + +CHARACTER_CLASS(Unprintable, c < ' ' && c > '\0'); + +CHARACTER_CLASS(Digit, '0' <= c && c <= '9'); +CHARACTER_CLASS(OctalDigit, '0' <= c && c <= '7'); +CHARACTER_CLASS(HexDigit, ('0' <= c && c <= '9') || + ('a' <= c && c <= 'f') || + ('A' <= c && c <= 'F')); + +CHARACTER_CLASS(Letter, ('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + (c == '_')); + +CHARACTER_CLASS(Alphanumeric, ('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + ('0' <= c && c <= '9') || + (c == '_')); + +CHARACTER_CLASS(Escape, c == 'a' || c == 'b' || c == 'f' || c == 'n' || + c == 'r' || c == 't' || c == 'v' || c == '\\' || + c == '?' || c == '\'' || c == '\"'); + +#undef CHARACTER_CLASS + +// Given a char, interpret it as a numeric digit and return its value. +// This supports any number base up to 36. +inline int DigitValue(char digit) { + if ('0' <= digit && digit <= '9') return digit - '0'; + if ('a' <= digit && digit <= 'z') return digit - 'a' + 10; + if ('A' <= digit && digit <= 'Z') return digit - 'A' + 10; + return -1; +} + +// Inline because it's only used in one place. +inline char TranslateEscape(char c) { + switch (c) { + case 'a': return '\a'; + case 'b': return '\b'; + case 'f': return '\f'; + case 'n': return '\n'; + case 'r': return '\r'; + case 't': return '\t'; + case 'v': return '\v'; + case '\\': return '\\'; + case '?': return '\?'; // Trigraphs = :( + case '\'': return '\''; + case '"': return '\"'; + + // We expect escape sequences to have been validated separately. + default: return '?'; + } +} + +} // anonymous namespace + +ErrorCollector::~ErrorCollector() {} + +// =================================================================== + +Tokenizer::Tokenizer(ZeroCopyInputStream* input, + ErrorCollector* error_collector) + : input_(input), + error_collector_(error_collector), + buffer_(NULL), + buffer_size_(0), + buffer_pos_(0), + read_error_(false), + line_(0), + column_(0), + record_target_(NULL), + record_start_(-1), + allow_f_after_float_(false), + comment_style_(CPP_COMMENT_STYLE) { + + current_.line = 0; + current_.column = 0; + current_.end_column = 0; + current_.type = TYPE_START; + + Refresh(); +} + +Tokenizer::~Tokenizer() { + // If we had any buffer left unread, return it to the underlying stream + // so that someone else can read it. + if (buffer_size_ > buffer_pos_) { + input_->BackUp(buffer_size_ - buffer_pos_); + } +} + +// ------------------------------------------------------------------- +// Internal helpers. + +void Tokenizer::NextChar() { + // Update our line and column counters based on the character being + // consumed. + if (current_char_ == '\n') { + ++line_; + column_ = 0; + } else if (current_char_ == '\t') { + column_ += kTabWidth - column_ % kTabWidth; + } else { + ++column_; + } + + // Advance to the next character. + ++buffer_pos_; + if (buffer_pos_ < buffer_size_) { + current_char_ = buffer_[buffer_pos_]; + } else { + Refresh(); + } +} + +void Tokenizer::Refresh() { + if (read_error_) { + current_char_ = '\0'; + return; + } + + // If we're in a token, append the rest of the buffer to it. + if (record_target_ != NULL && record_start_ < buffer_size_) { + record_target_->append(buffer_ + record_start_, buffer_size_ - record_start_); + record_start_ = 0; + } + + const void* data = NULL; + buffer_ = NULL; + buffer_pos_ = 0; + do { + if (!input_->Next(&data, &buffer_size_)) { + // end of stream (or read error) + buffer_size_ = 0; + read_error_ = true; + current_char_ = '\0'; + return; + } + } while (buffer_size_ == 0); + + buffer_ = static_cast(data); + + current_char_ = buffer_[0]; +} + +inline void Tokenizer::RecordTo(string* target) { + record_target_ = target; + record_start_ = buffer_pos_; +} + +inline void Tokenizer::StopRecording() { + // Note: The if() is necessary because some STL implementations crash when + // you call string::append(NULL, 0), presumably because they are trying to + // be helpful by detecting the NULL pointer, even though there's nothing + // wrong with reading zero bytes from NULL. + if (buffer_pos_ != record_start_) { + record_target_->append(buffer_ + record_start_, buffer_pos_ - record_start_); + } + record_target_ = NULL; + record_start_ = -1; +} + +inline void Tokenizer::StartToken() { + current_.type = TYPE_START; // Just for the sake of initializing it. + current_.text.clear(); + current_.line = line_; + current_.column = column_; + RecordTo(¤t_.text); +} + +inline void Tokenizer::EndToken() { + StopRecording(); + current_.end_column = column_; +} + +// ------------------------------------------------------------------- +// Helper methods that consume characters. + +template +inline bool Tokenizer::LookingAt() { + return CharacterClass::InClass(current_char_); +} + +template +inline bool Tokenizer::TryConsumeOne() { + if (CharacterClass::InClass(current_char_)) { + NextChar(); + return true; + } else { + return false; + } +} + +inline bool Tokenizer::TryConsume(char c) { + if (current_char_ == c) { + NextChar(); + return true; + } else { + return false; + } +} + +template +inline void Tokenizer::ConsumeZeroOrMore() { + while (CharacterClass::InClass(current_char_)) { + NextChar(); + } +} + +template +inline void Tokenizer::ConsumeOneOrMore(const char* error) { + if (!CharacterClass::InClass(current_char_)) { + AddError(error); + } else { + do { + NextChar(); + } while (CharacterClass::InClass(current_char_)); + } +} + +// ------------------------------------------------------------------- +// Methods that read whole patterns matching certain kinds of tokens +// or comments. + +void Tokenizer::ConsumeString(char delimiter) { + while (true) { + switch (current_char_) { + case '\0': + case '\n': { + AddError("String literals cannot cross line boundaries."); + return; + } + + case '\\': { + // An escape sequence. + NextChar(); + if (TryConsumeOne()) { + // Valid escape sequence. + } else if (TryConsumeOne()) { + // Possibly followed by two more octal digits, but these will + // just be consumed by the main loop anyway so we don't need + // to do so explicitly here. + } else if (TryConsume('x') || TryConsume('X')) { + if (!TryConsumeOne()) { + AddError("Expected hex digits for escape sequence."); + } + // Possibly followed by another hex digit, but again we don't care. + } else if (TryConsume('u')) { + if (!TryConsumeOne() || + !TryConsumeOne() || + !TryConsumeOne() || + !TryConsumeOne()) { + AddError("Expected four hex digits for \\u escape sequence."); + } + } else if (TryConsume('U')) { + // We expect 8 hex digits; but only the range up to 0x10ffff is + // legal. + if (!TryConsume('0') || + !TryConsume('0') || + !(TryConsume('0') || TryConsume('1')) || + !TryConsumeOne() || + !TryConsumeOne() || + !TryConsumeOne() || + !TryConsumeOne() || + !TryConsumeOne()) { + AddError("Expected eight hex digits up to 10ffff for \\U escape " + "sequence"); + } + } else { + AddError("Invalid escape sequence in string literal."); + } + break; + } + + default: { + if (current_char_ == delimiter) { + NextChar(); + return; + } + NextChar(); + break; + } + } + } +} + +Tokenizer::TokenType Tokenizer::ConsumeNumber(bool started_with_zero, + bool started_with_dot) { + bool is_float = false; + + if (started_with_zero && (TryConsume('x') || TryConsume('X'))) { + // A hex number (started with "0x"). + ConsumeOneOrMore("\"0x\" must be followed by hex digits."); + + } else if (started_with_zero && LookingAt()) { + // An octal number (had a leading zero). + ConsumeZeroOrMore(); + if (LookingAt()) { + AddError("Numbers starting with leading zero must be in octal."); + ConsumeZeroOrMore(); + } + + } else { + // A decimal number. + if (started_with_dot) { + is_float = true; + ConsumeZeroOrMore(); + } else { + ConsumeZeroOrMore(); + + if (TryConsume('.')) { + is_float = true; + ConsumeZeroOrMore(); + } + } + + if (TryConsume('e') || TryConsume('E')) { + is_float = true; + TryConsume('-') || TryConsume('+'); + ConsumeOneOrMore("\"e\" must be followed by exponent."); + } + + if (allow_f_after_float_ && (TryConsume('f') || TryConsume('F'))) { + is_float = true; + } + } + + if (LookingAt()) { + AddError("Need space between number and identifier."); + } else if (current_char_ == '.') { + if (is_float) { + AddError( + "Already saw decimal point or exponent; can't have another one."); + } else { + AddError("Hex and octal numbers must be integers."); + } + } + + return is_float ? TYPE_FLOAT : TYPE_INTEGER; +} + +void Tokenizer::ConsumeLineComment(string* content) { + if (content != NULL) RecordTo(content); + + while (current_char_ != '\0' && current_char_ != '\n') { + NextChar(); + } + TryConsume('\n'); + + if (content != NULL) StopRecording(); +} + +void Tokenizer::ConsumeBlockComment(string* content) { + int start_line = line_; + int start_column = column_ - 2; + + if (content != NULL) RecordTo(content); + + while (true) { + while (current_char_ != '\0' && + current_char_ != '*' && + current_char_ != '/' && + current_char_ != '\n') { + NextChar(); + } + + if (TryConsume('\n')) { + if (content != NULL) StopRecording(); + + // Consume leading whitespace and asterisk; + ConsumeZeroOrMore(); + if (TryConsume('*')) { + if (TryConsume('/')) { + // End of comment. + break; + } + } + + if (content != NULL) RecordTo(content); + } else if (TryConsume('*') && TryConsume('/')) { + // End of comment. + if (content != NULL) { + StopRecording(); + // Strip trailing "*/". + content->erase(content->size() - 2); + } + break; + } else if (TryConsume('/') && current_char_ == '*') { + // Note: We didn't consume the '*' because if there is a '/' after it + // we want to interpret that as the end of the comment. + AddError( + "\"/*\" inside block comment. Block comments cannot be nested."); + } else if (current_char_ == '\0') { + AddError("End-of-file inside block comment."); + error_collector_->AddError( + start_line, start_column, " Comment started here."); + if (content != NULL) StopRecording(); + break; + } + } +} + +Tokenizer::NextCommentStatus Tokenizer::TryConsumeCommentStart() { + if (comment_style_ == CPP_COMMENT_STYLE && TryConsume('/')) { + if (TryConsume('/')) { + return LINE_COMMENT; + } else if (TryConsume('*')) { + return BLOCK_COMMENT; + } else { + // Oops, it was just a slash. Return it. + current_.type = TYPE_SYMBOL; + current_.text = "/"; + current_.line = line_; + current_.column = column_ - 1; + current_.end_column = column_; + return SLASH_NOT_COMMENT; + } + } else if (comment_style_ == SH_COMMENT_STYLE && TryConsume('#')) { + return LINE_COMMENT; + } else { + return NO_COMMENT; + } +} + +// ------------------------------------------------------------------- + +bool Tokenizer::Next() { + previous_ = current_; + + while (!read_error_) { + ConsumeZeroOrMore(); + + switch (TryConsumeCommentStart()) { + case LINE_COMMENT: + ConsumeLineComment(NULL); + continue; + case BLOCK_COMMENT: + ConsumeBlockComment(NULL); + continue; + case SLASH_NOT_COMMENT: + return true; + case NO_COMMENT: + break; + } + + // Check for EOF before continuing. + if (read_error_) break; + + if (LookingAt() || current_char_ == '\0') { + AddError("Invalid control characters encountered in text."); + NextChar(); + // Skip more unprintable characters, too. But, remember that '\0' is + // also what current_char_ is set to after EOF / read error. We have + // to be careful not to go into an infinite loop of trying to consume + // it, so make sure to check read_error_ explicitly before consuming + // '\0'. + while (TryConsumeOne() || + (!read_error_ && TryConsume('\0'))) { + // Ignore. + } + + } else { + // Reading some sort of token. + StartToken(); + + if (TryConsumeOne()) { + ConsumeZeroOrMore(); + current_.type = TYPE_IDENTIFIER; + } else if (TryConsume('0')) { + current_.type = ConsumeNumber(true, false); + } else if (TryConsume('.')) { + // This could be the beginning of a floating-point number, or it could + // just be a '.' symbol. + + if (TryConsumeOne()) { + // It's a floating-point number. + if (previous_.type == TYPE_IDENTIFIER && + current_.line == previous_.line && + current_.column == previous_.end_column) { + // We don't accept syntax like "blah.123". + error_collector_->AddError(line_, column_ - 2, + "Need space between identifier and decimal point."); + } + current_.type = ConsumeNumber(false, true); + } else { + current_.type = TYPE_SYMBOL; + } + } else if (TryConsumeOne()) { + current_.type = ConsumeNumber(false, false); + } else if (TryConsume('\"')) { + ConsumeString('\"'); + current_.type = TYPE_STRING; + } else if (TryConsume('\'')) { + ConsumeString('\''); + current_.type = TYPE_STRING; + } else { + NextChar(); + current_.type = TYPE_SYMBOL; + } + + EndToken(); + return true; + } + } + + // EOF + current_.type = TYPE_END; + current_.text.clear(); + current_.line = line_; + current_.column = column_; + current_.end_column = column_; + return false; +} + +namespace { + +// Helper class for collecting comments and putting them in the right places. +// +// This basically just buffers the most recent comment until it can be decided +// exactly where that comment should be placed. When Flush() is called, the +// current comment goes into either prev_trailing_comments or detached_comments. +// When the CommentCollector is destroyed, the last buffered comment goes into +// next_leading_comments. +class CommentCollector { + public: + CommentCollector(string* prev_trailing_comments, + vector* detached_comments, + string* next_leading_comments) + : prev_trailing_comments_(prev_trailing_comments), + detached_comments_(detached_comments), + next_leading_comments_(next_leading_comments), + has_comment_(false), + is_line_comment_(false), + can_attach_to_prev_(true) { + if (prev_trailing_comments != NULL) prev_trailing_comments->clear(); + if (detached_comments != NULL) detached_comments->clear(); + if (next_leading_comments != NULL) next_leading_comments->clear(); + } + + ~CommentCollector() { + // Whatever is in the buffer is a leading comment. + if (next_leading_comments_ != NULL && has_comment_) { + comment_buffer_.swap(*next_leading_comments_); + } + } + + // About to read a line comment. Get the comment buffer pointer in order to + // read into it. + string* GetBufferForLineComment() { + // We want to combine with previous line comments, but not block comments. + if (has_comment_ && !is_line_comment_) { + Flush(); + } + has_comment_ = true; + is_line_comment_ = true; + return &comment_buffer_; + } + + // About to read a block comment. Get the comment buffer pointer in order to + // read into it. + string* GetBufferForBlockComment() { + if (has_comment_) { + Flush(); + } + has_comment_ = true; + is_line_comment_ = false; + return &comment_buffer_; + } + + void ClearBuffer() { + comment_buffer_.clear(); + has_comment_ = false; + } + + // Called once we know that the comment buffer is complete and is *not* + // connected to the next token. + void Flush() { + if (has_comment_) { + if (can_attach_to_prev_) { + if (prev_trailing_comments_ != NULL) { + prev_trailing_comments_->append(comment_buffer_); + } + can_attach_to_prev_ = false; + } else { + if (detached_comments_ != NULL) { + detached_comments_->push_back(comment_buffer_); + } + } + ClearBuffer(); + } + } + + void DetachFromPrev() { + can_attach_to_prev_ = false; + } + + private: + string* prev_trailing_comments_; + vector* detached_comments_; + string* next_leading_comments_; + + string comment_buffer_; + + // True if any comments were read into comment_buffer_. This can be true even + // if comment_buffer_ is empty, namely if the comment was "/**/". + bool has_comment_; + + // Is the comment in the comment buffer a line comment? + bool is_line_comment_; + + // Is it still possible that we could be reading a comment attached to the + // previous token? + bool can_attach_to_prev_; +}; + +} // namespace + +bool Tokenizer::NextWithComments(string* prev_trailing_comments, + vector* detached_comments, + string* next_leading_comments) { + CommentCollector collector(prev_trailing_comments, detached_comments, + next_leading_comments); + + if (current_.type == TYPE_START) { + collector.DetachFromPrev(); + } else { + // A comment appearing on the same line must be attached to the previous + // declaration. + ConsumeZeroOrMore(); + switch (TryConsumeCommentStart()) { + case LINE_COMMENT: + ConsumeLineComment(collector.GetBufferForLineComment()); + + // Don't allow comments on subsequent lines to be attached to a trailing + // comment. + collector.Flush(); + break; + case BLOCK_COMMENT: + ConsumeBlockComment(collector.GetBufferForBlockComment()); + + ConsumeZeroOrMore(); + if (!TryConsume('\n')) { + // Oops, the next token is on the same line. If we recorded a comment + // we really have no idea which token it should be attached to. + collector.ClearBuffer(); + return Next(); + } + + // Don't allow comments on subsequent lines to be attached to a trailing + // comment. + collector.Flush(); + break; + case SLASH_NOT_COMMENT: + return true; + case NO_COMMENT: + if (!TryConsume('\n')) { + // The next token is on the same line. There are no comments. + return Next(); + } + break; + } + } + + // OK, we are now on the line *after* the previous token. + while (true) { + ConsumeZeroOrMore(); + + switch (TryConsumeCommentStart()) { + case LINE_COMMENT: + ConsumeLineComment(collector.GetBufferForLineComment()); + break; + case BLOCK_COMMENT: + ConsumeBlockComment(collector.GetBufferForBlockComment()); + + // Consume the rest of the line so that we don't interpret it as a + // blank line the next time around the loop. + ConsumeZeroOrMore(); + TryConsume('\n'); + break; + case SLASH_NOT_COMMENT: + return true; + case NO_COMMENT: + if (TryConsume('\n')) { + // Completely blank line. + collector.Flush(); + collector.DetachFromPrev(); + } else { + bool result = Next(); + if (!result || + current_.text == "}" || + current_.text == "]" || + current_.text == ")") { + // It looks like we're at the end of a scope. In this case it + // makes no sense to attach a comment to the following token. + collector.Flush(); + } + return result; + } + break; + } + } +} + +// ------------------------------------------------------------------- +// Token-parsing helpers. Remember that these don't need to report +// errors since any errors should already have been reported while +// tokenizing. Also, these can assume that whatever text they +// are given is text that the tokenizer actually parsed as a token +// of the given type. + +bool Tokenizer::ParseInteger(const string& text, uint64 max_value, + uint64* output) { + // Sadly, we can't just use strtoul() since it is only 32-bit and strtoull() + // is non-standard. I hate the C standard library. :( + +// return strtoull(text.c_str(), NULL, 0); + + const char* ptr = text.c_str(); + int base = 10; + if (ptr[0] == '0') { + if (ptr[1] == 'x' || ptr[1] == 'X') { + // This is hex. + base = 16; + ptr += 2; + } else { + // This is octal. + base = 8; + } + } + + uint64 result = 0; + for (; *ptr != '\0'; ptr++) { + int digit = DigitValue(*ptr); + GOOGLE_LOG_IF(DFATAL, digit < 0 || digit >= base) + << " Tokenizer::ParseInteger() passed text that could not have been" + " tokenized as an integer: " << CEscape(text); + if (digit > max_value || result > (max_value - digit) / base) { + // Overflow. + return false; + } + result = result * base + digit; + } + + *output = result; + return true; +} + +double Tokenizer::ParseFloat(const string& text) { + const char* start = text.c_str(); + char* end; + double result = NoLocaleStrtod(start, &end); + + // "1e" is not a valid float, but if the tokenizer reads it, it will + // report an error but still return it as a valid token. We need to + // accept anything the tokenizer could possibly return, error or not. + if (*end == 'e' || *end == 'E') { + ++end; + if (*end == '-' || *end == '+') ++end; + } + + // If the Tokenizer had allow_f_after_float_ enabled, the float may be + // suffixed with the letter 'f'. + if (*end == 'f' || *end == 'F') { + ++end; + } + + GOOGLE_LOG_IF(DFATAL, end - start != text.size() || *start == '-') + << " Tokenizer::ParseFloat() passed text that could not have been" + " tokenized as a float: " << CEscape(text); + return result; +} + +// Helper to append a Unicode code point to a string as UTF8, without bringing +// in any external dependencies. +static void AppendUTF8(uint32 code_point, string* output) { + uint32 tmp = 0; + int len = 0; + if (code_point <= 0x7f) { + tmp = code_point; + len = 1; + } else if (code_point <= 0x07ff) { + tmp = 0x0000c080 | + ((code_point & 0x07c0) << 2) | + (code_point & 0x003f); + len = 2; + } else if (code_point <= 0xffff) { + tmp = 0x00e08080 | + ((code_point & 0xf000) << 4) | + ((code_point & 0x0fc0) << 2) | + (code_point & 0x003f); + len = 3; + } else if (code_point <= 0x1fffff) { + tmp = 0xf0808080 | + ((code_point & 0x1c0000) << 6) | + ((code_point & 0x03f000) << 4) | + ((code_point & 0x000fc0) << 2) | + (code_point & 0x003f); + len = 4; + } else { + // UTF-16 is only defined for code points up to 0x10FFFF, and UTF-8 is + // normally only defined up to there as well. + StringAppendF(output, "\\U%08x", code_point); + return; + } + tmp = ghtonl(tmp); + output->append(reinterpret_cast(&tmp) + sizeof(tmp) - len, len); +} + +// Try to read hex digits from ptr, and stuff the numeric result into +// *result. Returns true if that many digits were successfully consumed. +static bool ReadHexDigits(const char* ptr, int len, uint32* result) { + *result = 0; + if (len == 0) return false; + for (const char* end = ptr + len; ptr < end; ++ptr) { + if (*ptr == '\0') return false; + *result = (*result << 4) + DigitValue(*ptr); + } + return true; +} + +// Handling UTF-16 surrogate pairs. UTF-16 encodes code points in the range +// 0x10000...0x10ffff as a pair of numbers, a head surrogate followed by a trail +// surrogate. These numbers are in a reserved range of Unicode code points, so +// if we encounter such a pair we know how to parse it and convert it into a +// single code point. +static const uint32 kMinHeadSurrogate = 0xd800; +static const uint32 kMaxHeadSurrogate = 0xdc00; +static const uint32 kMinTrailSurrogate = 0xdc00; +static const uint32 kMaxTrailSurrogate = 0xe000; + +static inline bool IsHeadSurrogate(uint32 code_point) { + return (code_point >= kMinHeadSurrogate) && (code_point < kMaxHeadSurrogate); +} + +static inline bool IsTrailSurrogate(uint32 code_point) { + return (code_point >= kMinTrailSurrogate) && + (code_point < kMaxTrailSurrogate); +} + +// Combine a head and trail surrogate into a single Unicode code point. +static uint32 AssembleUTF16(uint32 head_surrogate, uint32 trail_surrogate) { + GOOGLE_DCHECK(IsHeadSurrogate(head_surrogate)); + GOOGLE_DCHECK(IsTrailSurrogate(trail_surrogate)); + return 0x10000 + (((head_surrogate - kMinHeadSurrogate) << 10) | + (trail_surrogate - kMinTrailSurrogate)); +} + +// Convert the escape sequence parameter to a number of expected hex digits. +static inline int UnicodeLength(char key) { + if (key == 'u') return 4; + if (key == 'U') return 8; + return 0; +} + +// Given a pointer to the 'u' or 'U' starting a Unicode escape sequence, attempt +// to parse that sequence. On success, returns a pointer to the first char +// beyond that sequence, and fills in *code_point. On failure, returns ptr +// itself. +static const char* FetchUnicodePoint(const char* ptr, uint32* code_point) { + const char* p = ptr; + // Fetch the code point. + const int len = UnicodeLength(*p++); + if (!ReadHexDigits(p, len, code_point)) + return ptr; + p += len; + + // Check if the code point we read is a "head surrogate." If so, then we + // expect it to be immediately followed by another code point which is a valid + // "trail surrogate," and together they form a UTF-16 pair which decodes into + // a single Unicode point. Trail surrogates may only use \u, not \U. + if (IsHeadSurrogate(*code_point) && *p == '\\' && *(p + 1) == 'u') { + uint32 trail_surrogate; + if (ReadHexDigits(p + 2, 4, &trail_surrogate) && + IsTrailSurrogate(trail_surrogate)) { + *code_point = AssembleUTF16(*code_point, trail_surrogate); + p += 6; + } + // If this failed, then we just emit the head surrogate as a code point. + // It's bogus, but so is the string. + } + + return p; +} + +// The text string must begin and end with single or double quote +// characters. +void Tokenizer::ParseStringAppend(const string& text, string* output) { + // Reminder: text[0] is always a quote character. (If text is + // empty, it's invalid, so we'll just return). + const size_t text_size = text.size(); + if (text_size == 0) { + GOOGLE_LOG(DFATAL) + << " Tokenizer::ParseStringAppend() passed text that could not" + " have been tokenized as a string: " << CEscape(text); + return; + } + + // Reserve room for new string. The branch is necessary because if + // there is already space available the reserve() call might + // downsize the output. + const size_t new_len = text_size + output->size(); + if (new_len > output->capacity()) { + output->reserve(new_len); + } + + // Loop through the string copying characters to "output" and + // interpreting escape sequences. Note that any invalid escape + // sequences or other errors were already reported while tokenizing. + // In this case we do not need to produce valid results. + for (const char* ptr = text.c_str() + 1; *ptr != '\0'; ptr++) { + if (*ptr == '\\' && ptr[1] != '\0') { + // An escape sequence. + ++ptr; + + if (OctalDigit::InClass(*ptr)) { + // An octal escape. May one, two, or three digits. + int code = DigitValue(*ptr); + if (OctalDigit::InClass(ptr[1])) { + ++ptr; + code = code * 8 + DigitValue(*ptr); + } + if (OctalDigit::InClass(ptr[1])) { + ++ptr; + code = code * 8 + DigitValue(*ptr); + } + output->push_back(static_cast(code)); + + } else if (*ptr == 'x') { + // A hex escape. May zero, one, or two digits. (The zero case + // will have been caught as an error earlier.) + int code = 0; + if (HexDigit::InClass(ptr[1])) { + ++ptr; + code = DigitValue(*ptr); + } + if (HexDigit::InClass(ptr[1])) { + ++ptr; + code = code * 16 + DigitValue(*ptr); + } + output->push_back(static_cast(code)); + + } else if (*ptr == 'u' || *ptr == 'U') { + uint32 unicode; + const char* end = FetchUnicodePoint(ptr, &unicode); + if (end == ptr) { + // Failure: Just dump out what we saw, don't try to parse it. + output->push_back(*ptr); + } else { + AppendUTF8(unicode, output); + ptr = end - 1; // Because we're about to ++ptr. + } + } else { + // Some other escape code. + output->push_back(TranslateEscape(*ptr)); + } + + } else if (*ptr == text[0] && ptr[1] == '\0') { + // Ignore final quote matching the starting quote. + } else { + output->push_back(*ptr); + } + } +} + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer.h new file mode 100644 index 0000000..d85b82f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer.h @@ -0,0 +1,384 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Class for parsing tokenized text from a ZeroCopyInputStream. + +#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__ +#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { + +class ZeroCopyInputStream; // zero_copy_stream.h + +// Defined in this file. +class ErrorCollector; +class Tokenizer; + +// Abstract interface for an object which collects the errors that occur +// during parsing. A typical implementation might simply print the errors +// to stdout. +class LIBPROTOBUF_EXPORT ErrorCollector { + public: + inline ErrorCollector() {} + virtual ~ErrorCollector(); + + // Indicates that there was an error in the input at the given line and + // column numbers. The numbers are zero-based, so you may want to add + // 1 to each before printing them. + virtual void AddError(int line, int column, const string& message) = 0; + + // Indicates that there was a warning in the input at the given line and + // column numbers. The numbers are zero-based, so you may want to add + // 1 to each before printing them. + virtual void AddWarning(int line, int column, const string& message) { } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector); +}; + +// This class converts a stream of raw text into a stream of tokens for +// the protocol definition parser to parse. The tokens recognized are +// similar to those that make up the C language; see the TokenType enum for +// precise descriptions. Whitespace and comments are skipped. By default, +// C- and C++-style comments are recognized, but other styles can be used by +// calling set_comment_style(). +class LIBPROTOBUF_EXPORT Tokenizer { + public: + // Construct a Tokenizer that reads and tokenizes text from the given + // input stream and writes errors to the given error_collector. + // The caller keeps ownership of input and error_collector. + Tokenizer(ZeroCopyInputStream* input, ErrorCollector* error_collector); + ~Tokenizer(); + + enum TokenType { + TYPE_START, // Next() has not yet been called. + TYPE_END, // End of input reached. "text" is empty. + + TYPE_IDENTIFIER, // A sequence of letters, digits, and underscores, not + // starting with a digit. It is an error for a number + // to be followed by an identifier with no space in + // between. + TYPE_INTEGER, // A sequence of digits representing an integer. Normally + // the digits are decimal, but a prefix of "0x" indicates + // a hex number and a leading zero indicates octal, just + // like with C numeric literals. A leading negative sign + // is NOT included in the token; it's up to the parser to + // interpret the unary minus operator on its own. + TYPE_FLOAT, // A floating point literal, with a fractional part and/or + // an exponent. Always in decimal. Again, never + // negative. + TYPE_STRING, // A quoted sequence of escaped characters. Either single + // or double quotes can be used, but they must match. + // A string literal cannot cross a line break. + TYPE_SYMBOL, // Any other printable character, like '!' or '+'. + // Symbols are always a single character, so "!+$%" is + // four tokens. + }; + + // Structure representing a token read from the token stream. + struct Token { + TokenType type; + string text; // The exact text of the token as it appeared in + // the input. e.g. tokens of TYPE_STRING will still + // be escaped and in quotes. + + // "line" and "column" specify the position of the first character of + // the token within the input stream. They are zero-based. + int line; + int column; + int end_column; + }; + + // Get the current token. This is updated when Next() is called. Before + // the first call to Next(), current() has type TYPE_START and no contents. + const Token& current(); + + // Return the previous token -- i.e. what current() returned before the + // previous call to Next(). + const Token& previous(); + + // Advance to the next token. Returns false if the end of the input is + // reached. + bool Next(); + + // Like Next(), but also collects comments which appear between the previous + // and next tokens. + // + // Comments which appear to be attached to the previous token are stored + // in *prev_tailing_comments. Comments which appear to be attached to the + // next token are stored in *next_leading_comments. Comments appearing in + // between which do not appear to be attached to either will be added to + // detached_comments. Any of these parameters can be NULL to simply discard + // the comments. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // Only the comment content is returned; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk will + // be stripped from the beginning of each line other than the first. Newlines + // are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment. This is not attached to qux or corge + // // because there are blank lines separating it from both. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + bool NextWithComments(string* prev_trailing_comments, + vector* detached_comments, + string* next_leading_comments); + + // Parse helpers --------------------------------------------------- + + // Parses a TYPE_FLOAT token. This never fails, so long as the text actually + // comes from a TYPE_FLOAT token parsed by Tokenizer. If it doesn't, the + // result is undefined (possibly an assert failure). + static double ParseFloat(const string& text); + + // Parses a TYPE_STRING token. This never fails, so long as the text actually + // comes from a TYPE_STRING token parsed by Tokenizer. If it doesn't, the + // result is undefined (possibly an assert failure). + static void ParseString(const string& text, string* output); + + // Identical to ParseString, but appends to output. + static void ParseStringAppend(const string& text, string* output); + + // Parses a TYPE_INTEGER token. Returns false if the result would be + // greater than max_value. Otherwise, returns true and sets *output to the + // result. If the text is not from a Token of type TYPE_INTEGER originally + // parsed by a Tokenizer, the result is undefined (possibly an assert + // failure). + static bool ParseInteger(const string& text, uint64 max_value, + uint64* output); + + // Options --------------------------------------------------------- + + // Set true to allow floats to be suffixed with the letter 'f'. Tokens + // which would otherwise be integers but which have the 'f' suffix will be + // forced to be interpreted as floats. For all other purposes, the 'f' is + // ignored. + void set_allow_f_after_float(bool value) { allow_f_after_float_ = value; } + + // Valid values for set_comment_style(). + enum CommentStyle { + // Line comments begin with "//", block comments are delimited by "/*" and + // "*/". + CPP_COMMENT_STYLE, + // Line comments begin with "#". No way to write block comments. + SH_COMMENT_STYLE + }; + + // Sets the comment style. + void set_comment_style(CommentStyle style) { comment_style_ = style; } + + // ----------------------------------------------------------------- + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer); + + Token current_; // Returned by current(). + Token previous_; // Returned by previous(). + + ZeroCopyInputStream* input_; + ErrorCollector* error_collector_; + + char current_char_; // == buffer_[buffer_pos_], updated by NextChar(). + const char* buffer_; // Current buffer returned from input_. + int buffer_size_; // Size of buffer_. + int buffer_pos_; // Current position within the buffer. + bool read_error_; // Did we previously encounter a read error? + + // Line and column number of current_char_ within the whole input stream. + int line_; + int column_; + + // String to which text should be appended as we advance through it. + // Call RecordTo(&str) to start recording and StopRecording() to stop. + // E.g. StartToken() calls RecordTo(¤t_.text). record_start_ is the + // position within the current buffer where recording started. + string* record_target_; + int record_start_; + + // Options. + bool allow_f_after_float_; + CommentStyle comment_style_; + + // Since we count columns we need to interpret tabs somehow. We'll take + // the standard 8-character definition for lack of any way to do better. + static const int kTabWidth = 8; + + // ----------------------------------------------------------------- + // Helper methods. + + // Consume this character and advance to the next one. + void NextChar(); + + // Read a new buffer from the input. + void Refresh(); + + inline void RecordTo(string* target); + inline void StopRecording(); + + // Called when the current character is the first character of a new + // token (not including whitespace or comments). + inline void StartToken(); + // Called when the current character is the first character after the + // end of the last token. After this returns, current_.text will + // contain all text consumed since StartToken() was called. + inline void EndToken(); + + // Convenience method to add an error at the current line and column. + void AddError(const string& message) { + error_collector_->AddError(line_, column_, message); + } + + // ----------------------------------------------------------------- + // The following four methods are used to consume tokens of specific + // types. They are actually used to consume all characters *after* + // the first, since the calling function consumes the first character + // in order to decide what kind of token is being read. + + // Read and consume a string, ending when the given delimiter is + // consumed. + void ConsumeString(char delimiter); + + // Read and consume a number, returning TYPE_FLOAT or TYPE_INTEGER + // depending on what was read. This needs to know if the first + // character was a zero in order to correctly recognize hex and octal + // numbers. + // It also needs to know if the first characted was a . to parse floating + // point correctly. + TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot); + + // Consume the rest of a line. + void ConsumeLineComment(string* content); + // Consume until "*/". + void ConsumeBlockComment(string* content); + + enum NextCommentStatus { + // Started a line comment. + LINE_COMMENT, + + // Started a block comment. + BLOCK_COMMENT, + + // Consumed a slash, then realized it wasn't a comment. current_ has + // been filled in with a slash token. The caller should return it. + SLASH_NOT_COMMENT, + + // We do not appear to be starting a comment here. + NO_COMMENT + }; + + // If we're at the start of a new comment, consume it and return what kind + // of comment it is. + NextCommentStatus TryConsumeCommentStart(); + + // ----------------------------------------------------------------- + // These helper methods make the parsing code more readable. The + // "character classes" refered to are defined at the top of the .cc file. + // Basically it is a C++ class with one method: + // static bool InClass(char c); + // The method returns true if c is a member of this "class", like "Letter" + // or "Digit". + + // Returns true if the current character is of the given character + // class, but does not consume anything. + template + inline bool LookingAt(); + + // If the current character is in the given class, consume it and return + // true. Otherwise return false. + // e.g. TryConsumeOne() + template + inline bool TryConsumeOne(); + + // Like above, but try to consume the specific character indicated. + inline bool TryConsume(char c); + + // Consume zero or more of the given character class. + template + inline void ConsumeZeroOrMore(); + + // Consume one or more of the given character class or log the given + // error message. + // e.g. ConsumeOneOrMore("Expected digits."); + template + inline void ConsumeOneOrMore(const char* error); +}; + +// inline methods ==================================================== +inline const Tokenizer::Token& Tokenizer::current() { + return current_; +} + +inline const Tokenizer::Token& Tokenizer::previous() { + return previous_; +} + +inline void Tokenizer::ParseString(const string& text, string* output) { + output->clear(); + ParseStringAppend(text, output); +} + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_TOKENIZER_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer_unittest.cc new file mode 100644 index 0000000..dbb5be4 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/tokenizer_unittest.cc @@ -0,0 +1,1001 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { +namespace { + +// =================================================================== +// Data-Driven Test Infrastructure + +// TODO(kenton): This is copied from coded_stream_unittest. This is +// temporary until these fetaures are integrated into gTest itself. + +// TEST_1D and TEST_2D are macros I'd eventually like to see added to +// gTest. These macros can be used to declare tests which should be +// run multiple times, once for each item in some input array. TEST_1D +// tests all cases in a single input array. TEST_2D tests all +// combinations of cases from two arrays. The arrays must be statically +// defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example: +// +// int kCases[] = {1, 2, 3, 4} +// TEST_1D(MyFixture, MyTest, kCases) { +// EXPECT_GT(kCases_case, 0); +// } +// +// This test iterates through the numbers 1, 2, 3, and 4 and tests that +// they are all grater than zero. In case of failure, the exact case +// which failed will be printed. The case type must be printable using +// ostream::operator<<. + +#define TEST_1D(FIXTURE, NAME, CASES) \ + class FIXTURE##_##NAME##_DD : public FIXTURE { \ + protected: \ + template \ + void DoSingleCase(const CaseType& CASES##_case); \ + }; \ + \ + TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ + for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \ + SCOPED_TRACE(testing::Message() \ + << #CASES " case #" << i << ": " << CASES[i]); \ + DoSingleCase(CASES[i]); \ + } \ + } \ + \ + template \ + void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case) + +#define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \ + class FIXTURE##_##NAME##_DD : public FIXTURE { \ + protected: \ + template \ + void DoSingleCase(const CaseType1& CASES1##_case, \ + const CaseType2& CASES2##_case); \ + }; \ + \ + TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ + for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \ + for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \ + SCOPED_TRACE(testing::Message() \ + << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \ + << #CASES2 " case #" << j << ": " << CASES2[j]); \ + DoSingleCase(CASES1[i], CASES2[j]); \ + } \ + } \ + } \ + \ + template \ + void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \ + const CaseType2& CASES2##_case) + +// ------------------------------------------------------------------- + +// An input stream that is basically like an ArrayInputStream but sometimes +// returns empty buffers, just to throw us off. +class TestInputStream : public ZeroCopyInputStream { + public: + TestInputStream(const void* data, int size, int block_size) + : array_stream_(data, size, block_size), counter_(0) {} + ~TestInputStream() {} + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size) { + // We'll return empty buffers starting with the first buffer, and every + // 3 and 5 buffers after that. + if (counter_ % 3 == 0 || counter_ % 5 == 0) { + *data = NULL; + *size = 0; + ++counter_; + return true; + } else { + ++counter_; + return array_stream_.Next(data, size); + } + } + + void BackUp(int count) { return array_stream_.BackUp(count); } + bool Skip(int count) { return array_stream_.Skip(count); } + int64 ByteCount() const { return array_stream_.ByteCount(); } + + private: + ArrayInputStream array_stream_; + int counter_; +}; + +// ------------------------------------------------------------------- + +// An error collector which simply concatenates all its errors into a big +// block of text which can be checked. +class TestErrorCollector : public ErrorCollector { + public: + TestErrorCollector() {} + ~TestErrorCollector() {} + + string text_; + + // implements ErrorCollector --------------------------------------- + void AddError(int line, int column, const string& message) { + strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", + line, column, message); + } +}; + +// ------------------------------------------------------------------- + +// We test each operation over a variety of block sizes to insure that +// we test cases where reads cross buffer boundaries as well as cases +// where they don't. This is sort of a brute-force approach to this, +// but it's easy to write and easy to understand. +const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024}; + +class TokenizerTest : public testing::Test { + protected: + // For easy testing. + uint64 ParseInteger(const string& text) { + uint64 result; + EXPECT_TRUE(Tokenizer::ParseInteger(text, kuint64max, &result)); + return result; + } +}; + +// =================================================================== + +// These tests causes gcc 3.3.5 (and earlier?) to give the cryptic error: +// "sorry, unimplemented: `method_call_expr' not supported by dump_expr" +#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) + +// In each test case, the entire input text should parse as a single token +// of the given type. +struct SimpleTokenCase { + string input; + Tokenizer::TokenType type; +}; + +inline ostream& operator<<(ostream& out, + const SimpleTokenCase& test_case) { + return out << CEscape(test_case.input); +} + +SimpleTokenCase kSimpleTokenCases[] = { + // Test identifiers. + { "hello", Tokenizer::TYPE_IDENTIFIER }, + + // Test integers. + { "123", Tokenizer::TYPE_INTEGER }, + { "0xab6", Tokenizer::TYPE_INTEGER }, + { "0XAB6", Tokenizer::TYPE_INTEGER }, + { "0X1234567", Tokenizer::TYPE_INTEGER }, + { "0x89abcdef", Tokenizer::TYPE_INTEGER }, + { "0x89ABCDEF", Tokenizer::TYPE_INTEGER }, + { "01234567", Tokenizer::TYPE_INTEGER }, + + // Test floats. + { "123.45", Tokenizer::TYPE_FLOAT }, + { "1.", Tokenizer::TYPE_FLOAT }, + { "1e3", Tokenizer::TYPE_FLOAT }, + { "1E3", Tokenizer::TYPE_FLOAT }, + { "1e-3", Tokenizer::TYPE_FLOAT }, + { "1e+3", Tokenizer::TYPE_FLOAT }, + { "1.e3", Tokenizer::TYPE_FLOAT }, + { "1.2e3", Tokenizer::TYPE_FLOAT }, + { ".1", Tokenizer::TYPE_FLOAT }, + { ".1e3", Tokenizer::TYPE_FLOAT }, + { ".1e-3", Tokenizer::TYPE_FLOAT }, + { ".1e+3", Tokenizer::TYPE_FLOAT }, + + // Test strings. + { "'hello'", Tokenizer::TYPE_STRING }, + { "\"foo\"", Tokenizer::TYPE_STRING }, + { "'a\"b'", Tokenizer::TYPE_STRING }, + { "\"a'b\"", Tokenizer::TYPE_STRING }, + { "'a\\'b'", Tokenizer::TYPE_STRING }, + { "\"a\\\"b\"", Tokenizer::TYPE_STRING }, + { "'\\xf'", Tokenizer::TYPE_STRING }, + { "'\\0'", Tokenizer::TYPE_STRING }, + + // Test symbols. + { "+", Tokenizer::TYPE_SYMBOL }, + { ".", Tokenizer::TYPE_SYMBOL }, +}; + +TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) { + // Set up the tokenizer. + TestInputStream input(kSimpleTokenCases_case.input.data(), + kSimpleTokenCases_case.input.size(), + kBlockSizes_case); + TestErrorCollector error_collector; + Tokenizer tokenizer(&input, &error_collector); + + // Before Next() is called, the initial token should always be TYPE_START. + EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type); + EXPECT_EQ("", tokenizer.current().text); + EXPECT_EQ(0, tokenizer.current().line); + EXPECT_EQ(0, tokenizer.current().column); + EXPECT_EQ(0, tokenizer.current().end_column); + + // Parse the token. + ASSERT_TRUE(tokenizer.Next()); + + // Check that it has the right type. + EXPECT_EQ(kSimpleTokenCases_case.type, tokenizer.current().type); + // Check that it contains the complete input text. + EXPECT_EQ(kSimpleTokenCases_case.input, tokenizer.current().text); + // Check that it is located at the beginning of the input + EXPECT_EQ(0, tokenizer.current().line); + EXPECT_EQ(0, tokenizer.current().column); + EXPECT_EQ(kSimpleTokenCases_case.input.size(), + tokenizer.current().end_column); + + // There should be no more input. + EXPECT_FALSE(tokenizer.Next()); + + // After Next() returns false, the token should have type TYPE_END. + EXPECT_EQ(Tokenizer::TYPE_END, tokenizer.current().type); + EXPECT_EQ("", tokenizer.current().text); + EXPECT_EQ(0, tokenizer.current().line); + EXPECT_EQ(kSimpleTokenCases_case.input.size(), tokenizer.current().column); + EXPECT_EQ(kSimpleTokenCases_case.input.size(), + tokenizer.current().end_column); + + // There should be no errors. + EXPECT_TRUE(error_collector.text_.empty()); +} + +TEST_1D(TokenizerTest, FloatSuffix, kBlockSizes) { + // Test the "allow_f_after_float" option. + + // Set up the tokenizer. + const char* text = "1f 2.5f 6e3f 7F"; + TestInputStream input(text, strlen(text), kBlockSizes_case); + TestErrorCollector error_collector; + Tokenizer tokenizer(&input, &error_collector); + tokenizer.set_allow_f_after_float(true); + + // Advance through tokens and check that they are parsed as expected. + ASSERT_TRUE(tokenizer.Next()); + EXPECT_EQ(tokenizer.current().text, "1f"); + EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); + ASSERT_TRUE(tokenizer.Next()); + EXPECT_EQ(tokenizer.current().text, "2.5f"); + EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); + ASSERT_TRUE(tokenizer.Next()); + EXPECT_EQ(tokenizer.current().text, "6e3f"); + EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); + ASSERT_TRUE(tokenizer.Next()); + EXPECT_EQ(tokenizer.current().text, "7F"); + EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); + + // There should be no more input. + EXPECT_FALSE(tokenizer.Next()); + // There should be no errors. + EXPECT_TRUE(error_collector.text_.empty()); +} + +#endif + +// ------------------------------------------------------------------- + +// In each case, the input is parsed to produce a list of tokens. The +// last token in "output" must have type TYPE_END. +struct MultiTokenCase { + string input; + Tokenizer::Token output[10]; // The compiler wants a constant array + // size for initialization to work. There + // is no reason this can't be increased if + // needed. +}; + +inline ostream& operator<<(ostream& out, + const MultiTokenCase& test_case) { + return out << CEscape(test_case.input); +} + +MultiTokenCase kMultiTokenCases[] = { + // Test empty input. + { "", { + { Tokenizer::TYPE_END , "" , 0, 0 }, + }}, + + // Test all token types at the same time. + { "foo 1 1.2 + 'bar'", { + { Tokenizer::TYPE_IDENTIFIER, "foo" , 0, 0, 3 }, + { Tokenizer::TYPE_INTEGER , "1" , 0, 4, 5 }, + { Tokenizer::TYPE_FLOAT , "1.2" , 0, 6, 9 }, + { Tokenizer::TYPE_SYMBOL , "+" , 0, 10, 11 }, + { Tokenizer::TYPE_STRING , "'bar'", 0, 12, 17 }, + { Tokenizer::TYPE_END , "" , 0, 17, 17 }, + }}, + + // Test that consecutive symbols are parsed as separate tokens. + { "!@+%", { + { Tokenizer::TYPE_SYMBOL , "!" , 0, 0, 1 }, + { Tokenizer::TYPE_SYMBOL , "@" , 0, 1, 2 }, + { Tokenizer::TYPE_SYMBOL , "+" , 0, 2, 3 }, + { Tokenizer::TYPE_SYMBOL , "%" , 0, 3, 4 }, + { Tokenizer::TYPE_END , "" , 0, 4, 4 }, + }}, + + // Test that newlines affect line numbers correctly. + { "foo bar\nrab oof", { + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 4, 7 }, + { Tokenizer::TYPE_IDENTIFIER, "rab", 1, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "oof", 1, 4, 7 }, + { Tokenizer::TYPE_END , "" , 1, 7, 7 }, + }}, + + // Test that tabs affect column numbers correctly. + { "foo\tbar \tbaz", { + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 8, 11 }, + { Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16, 19 }, + { Tokenizer::TYPE_END , "" , 0, 19, 19 }, + }}, + + // Test that tabs in string literals affect column numbers correctly. + { "\"foo\tbar\" baz", { + { Tokenizer::TYPE_STRING , "\"foo\tbar\"", 0, 0, 12 }, + { Tokenizer::TYPE_IDENTIFIER, "baz" , 0, 13, 16 }, + { Tokenizer::TYPE_END , "" , 0, 16, 16 }, + }}, + + // Test that line comments are ignored. + { "foo // This is a comment\n" + "bar // This is another comment", { + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 0, 3 }, + { Tokenizer::TYPE_END , "" , 1, 30, 30 }, + }}, + + // Test that block comments are ignored. + { "foo /* This is a block comment */ bar", { + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34, 37 }, + { Tokenizer::TYPE_END , "" , 0, 37, 37 }, + }}, + + // Test that sh-style comments are not ignored by default. + { "foo # bar\n" + "baz", { + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_SYMBOL , "#" , 0, 4, 5 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6, 9 }, + { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0, 3 }, + { Tokenizer::TYPE_END , "" , 1, 3, 3 }, + }}, + + // Bytes with the high-order bit set should not be seen as control characters. + { "\300", { + { Tokenizer::TYPE_SYMBOL, "\300", 0, 0, 1 }, + { Tokenizer::TYPE_END , "" , 0, 1, 1 }, + }}, + + // Test all whitespace chars + { "foo\n\t\r\v\fbar", { + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11, 14 }, + { Tokenizer::TYPE_END , "" , 1, 14, 14 }, + }}, +}; + +TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) { + // Set up the tokenizer. + TestInputStream input(kMultiTokenCases_case.input.data(), + kMultiTokenCases_case.input.size(), + kBlockSizes_case); + TestErrorCollector error_collector; + Tokenizer tokenizer(&input, &error_collector); + + // Before Next() is called, the initial token should always be TYPE_START. + EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type); + EXPECT_EQ("", tokenizer.current().text); + EXPECT_EQ(0, tokenizer.current().line); + EXPECT_EQ(0, tokenizer.current().column); + EXPECT_EQ(0, tokenizer.current().end_column); + + // Loop through all expected tokens. + int i = 0; + Tokenizer::Token token; + do { + token = kMultiTokenCases_case.output[i++]; + + SCOPED_TRACE(testing::Message() << "Token #" << i << ": " << token.text); + + Tokenizer::Token previous = tokenizer.current(); + + // Next() should only return false when it hits the end token. + if (token.type != Tokenizer::TYPE_END) { + ASSERT_TRUE(tokenizer.Next()); + } else { + ASSERT_FALSE(tokenizer.Next()); + } + + // Check that the previous token is set correctly. + EXPECT_EQ(previous.type, tokenizer.previous().type); + EXPECT_EQ(previous.text, tokenizer.previous().text); + EXPECT_EQ(previous.line, tokenizer.previous().line); + EXPECT_EQ(previous.column, tokenizer.previous().column); + EXPECT_EQ(previous.end_column, tokenizer.previous().end_column); + + // Check that the token matches the expected one. + EXPECT_EQ(token.type, tokenizer.current().type); + EXPECT_EQ(token.text, tokenizer.current().text); + EXPECT_EQ(token.line, tokenizer.current().line); + EXPECT_EQ(token.column, tokenizer.current().column); + EXPECT_EQ(token.end_column, tokenizer.current().end_column); + + } while (token.type != Tokenizer::TYPE_END); + + // There should be no errors. + EXPECT_TRUE(error_collector.text_.empty()); +} + +// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error: +// "sorry, unimplemented: `method_call_expr' not supported by dump_expr" +#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) + +TEST_1D(TokenizerTest, ShCommentStyle, kBlockSizes) { + // Test the "comment_style" option. + + const char* text = "foo # bar\n" + "baz // qux\n" + "corge /* grault */\n" + "garply"; + const char* const kTokens[] = {"foo", // "# bar" is ignored + "baz", "/", "/", "qux", + "corge", "/", "*", "grault", "*", "/", + "garply"}; + + // Set up the tokenizer. + TestInputStream input(text, strlen(text), kBlockSizes_case); + TestErrorCollector error_collector; + Tokenizer tokenizer(&input, &error_collector); + tokenizer.set_comment_style(Tokenizer::SH_COMMENT_STYLE); + + // Advance through tokens and check that they are parsed as expected. + for (int i = 0; i < GOOGLE_ARRAYSIZE(kTokens); i++) { + EXPECT_TRUE(tokenizer.Next()); + EXPECT_EQ(tokenizer.current().text, kTokens[i]); + } + + // There should be no more input. + EXPECT_FALSE(tokenizer.Next()); + // There should be no errors. + EXPECT_TRUE(error_collector.text_.empty()); +} + +#endif + +// ------------------------------------------------------------------- + +// In each case, the input is expected to have two tokens named "prev" and +// "next" with comments in between. +struct DocCommentCase { + string input; + + const char* prev_trailing_comments; + const char* detached_comments[10]; + const char* next_leading_comments; +}; + +inline ostream& operator<<(ostream& out, + const DocCommentCase& test_case) { + return out << CEscape(test_case.input); +} + +DocCommentCase kDocCommentCases[] = { + { + "prev next", + + "", + {}, + "" + }, + + { + "prev /* ignored */ next", + + "", + {}, + "" + }, + + { + "prev // trailing comment\n" + "next", + + " trailing comment\n", + {}, + "" + }, + + { + "prev\n" + "// leading comment\n" + "// line 2\n" + "next", + + "", + {}, + " leading comment\n" + " line 2\n" + }, + + { + "prev\n" + "// trailing comment\n" + "// line 2\n" + "\n" + "next", + + " trailing comment\n" + " line 2\n", + {}, + "" + }, + + { + "prev // trailing comment\n" + "// leading comment\n" + "// line 2\n" + "next", + + " trailing comment\n", + {}, + " leading comment\n" + " line 2\n" + }, + + { + "prev /* trailing block comment */\n" + "/* leading block comment\n" + " * line 2\n" + " * line 3 */" + "next", + + " trailing block comment ", + {}, + " leading block comment\n" + " line 2\n" + " line 3 " + }, + + { + "prev\n" + "/* trailing block comment\n" + " * line 2\n" + " * line 3\n" + " */\n" + "/* leading block comment\n" + " * line 2\n" + " * line 3 */" + "next", + + " trailing block comment\n" + " line 2\n" + " line 3\n", + {}, + " leading block comment\n" + " line 2\n" + " line 3 " + }, + + { + "prev\n" + "// trailing comment\n" + "\n" + "// detached comment\n" + "// line 2\n" + "\n" + "// second detached comment\n" + "/* third detached comment\n" + " * line 2 */\n" + "// leading comment\n" + "next", + + " trailing comment\n", + { + " detached comment\n" + " line 2\n", + " second detached comment\n", + " third detached comment\n" + " line 2 " + }, + " leading comment\n" + }, + + { + "prev /**/\n" + "\n" + "// detached comment\n" + "\n" + "// leading comment\n" + "next", + + "", + { + " detached comment\n" + }, + " leading comment\n" + }, + + { + "prev /**/\n" + "// leading comment\n" + "next", + + "", + {}, + " leading comment\n" + }, + }; + +TEST_2D(TokenizerTest, DocComments, kDocCommentCases, kBlockSizes) { + // Set up the tokenizer. + TestInputStream input(kDocCommentCases_case.input.data(), + kDocCommentCases_case.input.size(), + kBlockSizes_case); + TestErrorCollector error_collector; + Tokenizer tokenizer(&input, &error_collector); + + // Set up a second tokenizer where we'll pass all NULLs to NextWithComments(). + TestInputStream input2(kDocCommentCases_case.input.data(), + kDocCommentCases_case.input.size(), + kBlockSizes_case); + Tokenizer tokenizer2(&input2, &error_collector); + + tokenizer.Next(); + tokenizer2.Next(); + + EXPECT_EQ("prev", tokenizer.current().text); + EXPECT_EQ("prev", tokenizer2.current().text); + + string prev_trailing_comments; + vector detached_comments; + string next_leading_comments; + tokenizer.NextWithComments(&prev_trailing_comments, &detached_comments, + &next_leading_comments); + tokenizer2.NextWithComments(NULL, NULL, NULL); + EXPECT_EQ("next", tokenizer.current().text); + EXPECT_EQ("next", tokenizer2.current().text); + + EXPECT_EQ(kDocCommentCases_case.prev_trailing_comments, + prev_trailing_comments); + + for (int i = 0; i < detached_comments.size(); i++) { + ASSERT_LT(i, GOOGLE_ARRAYSIZE(kDocCommentCases)); + ASSERT_TRUE(kDocCommentCases_case.detached_comments[i] != NULL); + EXPECT_EQ(kDocCommentCases_case.detached_comments[i], + detached_comments[i]); + } + + // Verify that we matched all the detached comments. + EXPECT_EQ(NULL, + kDocCommentCases_case.detached_comments[detached_comments.size()]); + + EXPECT_EQ(kDocCommentCases_case.next_leading_comments, + next_leading_comments); +} + +// ------------------------------------------------------------------- + +// Test parse helpers. It's not really worth setting up a full data-driven +// test here. +TEST_F(TokenizerTest, ParseInteger) { + EXPECT_EQ(0, ParseInteger("0")); + EXPECT_EQ(123, ParseInteger("123")); + EXPECT_EQ(0xabcdef12u, ParseInteger("0xabcdef12")); + EXPECT_EQ(0xabcdef12u, ParseInteger("0xABCDEF12")); + EXPECT_EQ(kuint64max, ParseInteger("0xFFFFFFFFFFFFFFFF")); + EXPECT_EQ(01234567, ParseInteger("01234567")); + EXPECT_EQ(0X123, ParseInteger("0X123")); + + // Test invalid integers that may still be tokenized as integers. + EXPECT_EQ(0, ParseInteger("0x")); + + uint64 i; +#ifdef PROTOBUF_HASDEATH_TEST // death tests do not work on Windows yet + // Test invalid integers that will never be tokenized as integers. + EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("zxy", kuint64max, &i), + "passed text that could not have been tokenized as an integer"); + EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("1.2", kuint64max, &i), + "passed text that could not have been tokenized as an integer"); + EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("08", kuint64max, &i), + "passed text that could not have been tokenized as an integer"); + EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("0xg", kuint64max, &i), + "passed text that could not have been tokenized as an integer"); + EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("-1", kuint64max, &i), + "passed text that could not have been tokenized as an integer"); +#endif // PROTOBUF_HASDEATH_TEST + + // Test overflows. + EXPECT_TRUE (Tokenizer::ParseInteger("0", 0, &i)); + EXPECT_FALSE(Tokenizer::ParseInteger("1", 0, &i)); + EXPECT_TRUE (Tokenizer::ParseInteger("1", 1, &i)); + EXPECT_TRUE (Tokenizer::ParseInteger("12345", 12345, &i)); + EXPECT_FALSE(Tokenizer::ParseInteger("12346", 12345, &i)); + EXPECT_TRUE (Tokenizer::ParseInteger("0xFFFFFFFFFFFFFFFF" , kuint64max, &i)); + EXPECT_FALSE(Tokenizer::ParseInteger("0x10000000000000000", kuint64max, &i)); +} + +TEST_F(TokenizerTest, ParseFloat) { + EXPECT_DOUBLE_EQ(1 , Tokenizer::ParseFloat("1.")); + EXPECT_DOUBLE_EQ(1e3 , Tokenizer::ParseFloat("1e3")); + EXPECT_DOUBLE_EQ(1e3 , Tokenizer::ParseFloat("1E3")); + EXPECT_DOUBLE_EQ(1.5e3, Tokenizer::ParseFloat("1.5e3")); + EXPECT_DOUBLE_EQ(.1 , Tokenizer::ParseFloat(".1")); + EXPECT_DOUBLE_EQ(.25 , Tokenizer::ParseFloat(".25")); + EXPECT_DOUBLE_EQ(.1e3 , Tokenizer::ParseFloat(".1e3")); + EXPECT_DOUBLE_EQ(.25e3, Tokenizer::ParseFloat(".25e3")); + EXPECT_DOUBLE_EQ(.1e+3, Tokenizer::ParseFloat(".1e+3")); + EXPECT_DOUBLE_EQ(.1e-3, Tokenizer::ParseFloat(".1e-3")); + EXPECT_DOUBLE_EQ(5 , Tokenizer::ParseFloat("5")); + EXPECT_DOUBLE_EQ(6e-12, Tokenizer::ParseFloat("6e-12")); + EXPECT_DOUBLE_EQ(1.2 , Tokenizer::ParseFloat("1.2")); + EXPECT_DOUBLE_EQ(1.e2 , Tokenizer::ParseFloat("1.e2")); + + // Test invalid integers that may still be tokenized as integers. + EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e")); + EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e-")); + EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.e")); + + // Test 'f' suffix. + EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1f")); + EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.0f")); + EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1F")); + + // These should parse successfully even though they are out of range. + // Overflows become infinity and underflows become zero. + EXPECT_EQ( 0.0, Tokenizer::ParseFloat("1e-9999999999999999999999999999")); + EXPECT_EQ(HUGE_VAL, Tokenizer::ParseFloat("1e+9999999999999999999999999999")); + +#ifdef PROTOBUF_HASDEATH_TEST // death tests do not work on Windows yet + // Test invalid integers that will never be tokenized as integers. + EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("zxy"), + "passed text that could not have been tokenized as a float"); + EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("1-e0"), + "passed text that could not have been tokenized as a float"); + EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("-1.0"), + "passed text that could not have been tokenized as a float"); +#endif // PROTOBUF_HASDEATH_TEST +} + +TEST_F(TokenizerTest, ParseString) { + string output; + Tokenizer::ParseString("'hello'", &output); + EXPECT_EQ("hello", output); + Tokenizer::ParseString("\"blah\\nblah2\"", &output); + EXPECT_EQ("blah\nblah2", output); + Tokenizer::ParseString("'\\1x\\1\\123\\739\\52\\334n\\3'", &output); + EXPECT_EQ("\1x\1\123\739\52\334n\3", output); + Tokenizer::ParseString("'\\x20\\x4'", &output); + EXPECT_EQ("\x20\x4", output); + + // Test invalid strings that may still be tokenized as strings. + Tokenizer::ParseString("\"\\a\\l\\v\\t", &output); // \l is invalid + EXPECT_EQ("\a?\v\t", output); + Tokenizer::ParseString("'", &output); + EXPECT_EQ("", output); + Tokenizer::ParseString("'\\", &output); + EXPECT_EQ("\\", output); + + // Experiment with Unicode escapes. Here are one-, two- and three-byte Unicode + // characters. + Tokenizer::ParseString("'\\u0024\\u00a2\\u20ac\\U00024b62XX'", &output); + EXPECT_EQ("$¢€𤭢XX", output); + // Same thing encoded using UTF16. + Tokenizer::ParseString("'\\u0024\\u00a2\\u20ac\\ud852\\udf62XX'", &output); + EXPECT_EQ("$¢€𤭢XX", output); + // Here's some broken UTF16; there's a head surrogate with no tail surrogate. + // We just output this as if it were UTF8; it's not a defined code point, but + // it has a defined encoding. + Tokenizer::ParseString("'\\ud852XX'", &output); + EXPECT_EQ("\xed\xa1\x92XX", output); + // Malformed escape: Demons may fly out of the nose. + Tokenizer::ParseString("\\u0", &output); + EXPECT_EQ("u0", output); + + // Test invalid strings that will never be tokenized as strings. +#ifdef PROTOBUF_HASDEATH_TEST // death tests do not work on Windows yet + EXPECT_DEBUG_DEATH(Tokenizer::ParseString("", &output), + "passed text that could not have been tokenized as a string"); +#endif // PROTOBUF_HASDEATH_TEST +} + +TEST_F(TokenizerTest, ParseStringAppend) { + // Check that ParseString and ParseStringAppend differ. + string output("stuff+"); + Tokenizer::ParseStringAppend("'hello'", &output); + EXPECT_EQ("stuff+hello", output); + Tokenizer::ParseString("'hello'", &output); + EXPECT_EQ("hello", output); +} + +// ------------------------------------------------------------------- + +// Each case parses some input text, ignoring the tokens produced, and +// checks that the error output matches what is expected. +struct ErrorCase { + string input; + bool recoverable; // True if the tokenizer should be able to recover and + // parse more tokens after seeing this error. Cases + // for which this is true must end with "foo" as + // the last token, which the test will check for. + const char* errors; +}; + +inline ostream& operator<<(ostream& out, + const ErrorCase& test_case) { + return out << CEscape(test_case.input); +} + +ErrorCase kErrorCases[] = { + // String errors. + { "'\\l' foo", true, + "0:2: Invalid escape sequence in string literal.\n" }, + { "'\\x' foo", true, + "0:3: Expected hex digits for escape sequence.\n" }, + { "'foo", false, + "0:4: String literals cannot cross line boundaries.\n" }, + { "'bar\nfoo", true, + "0:4: String literals cannot cross line boundaries.\n" }, + { "'\\u01' foo", true, + "0:5: Expected four hex digits for \\u escape sequence.\n" }, + { "'\\u01' foo", true, + "0:5: Expected four hex digits for \\u escape sequence.\n" }, + { "'\\uXYZ' foo", true, + "0:3: Expected four hex digits for \\u escape sequence.\n" }, + + // Integer errors. + { "123foo", true, + "0:3: Need space between number and identifier.\n" }, + + // Hex/octal errors. + { "0x foo", true, + "0:2: \"0x\" must be followed by hex digits.\n" }, + { "0541823 foo", true, + "0:4: Numbers starting with leading zero must be in octal.\n" }, + { "0x123z foo", true, + "0:5: Need space between number and identifier.\n" }, + { "0x123.4 foo", true, + "0:5: Hex and octal numbers must be integers.\n" }, + { "0123.4 foo", true, + "0:4: Hex and octal numbers must be integers.\n" }, + + // Float errors. + { "1e foo", true, + "0:2: \"e\" must be followed by exponent.\n" }, + { "1e- foo", true, + "0:3: \"e\" must be followed by exponent.\n" }, + { "1.2.3 foo", true, + "0:3: Already saw decimal point or exponent; can't have another one.\n" }, + { "1e2.3 foo", true, + "0:3: Already saw decimal point or exponent; can't have another one.\n" }, + { "a.1 foo", true, + "0:1: Need space between identifier and decimal point.\n" }, + // allow_f_after_float not enabled, so this should be an error. + { "1.0f foo", true, + "0:3: Need space between number and identifier.\n" }, + + // Block comment errors. + { "/*", false, + "0:2: End-of-file inside block comment.\n" + "0:0: Comment started here.\n"}, + { "/*/*/ foo", true, + "0:3: \"/*\" inside block comment. Block comments cannot be nested.\n"}, + + // Control characters. Multiple consecutive control characters should only + // produce one error. + { "\b foo", true, + "0:0: Invalid control characters encountered in text.\n" }, + { "\b\b foo", true, + "0:0: Invalid control characters encountered in text.\n" }, + + // Check that control characters at end of input don't result in an + // infinite loop. + { "\b", false, + "0:0: Invalid control characters encountered in text.\n" }, + + // Check recovery from '\0'. We have to explicitly specify the length of + // these strings because otherwise the string constructor will just call + // strlen() which will see the first '\0' and think that is the end of the + // string. + { string("\0foo", 4), true, + "0:0: Invalid control characters encountered in text.\n" }, + { string("\0\0foo", 5), true, + "0:0: Invalid control characters encountered in text.\n" }, +}; + +TEST_2D(TokenizerTest, Errors, kErrorCases, kBlockSizes) { + // Set up the tokenizer. + TestInputStream input(kErrorCases_case.input.data(), + kErrorCases_case.input.size(), + kBlockSizes_case); + TestErrorCollector error_collector; + Tokenizer tokenizer(&input, &error_collector); + + // Ignore all input, except remember if the last token was "foo". + bool last_was_foo = false; + while (tokenizer.Next()) { + last_was_foo = tokenizer.current().text == "foo"; + } + + // Check that the errors match what was expected. + EXPECT_EQ(kErrorCases_case.errors, error_collector.text_); + + // If the error was recoverable, make sure we saw "foo" after it. + if (kErrorCases_case.recoverable) { + EXPECT_TRUE(last_was_foo); + } +} + +// ------------------------------------------------------------------- + +TEST_1D(TokenizerTest, BackUpOnDestruction, kBlockSizes) { + string text = "foo bar"; + TestInputStream input(text.data(), text.size(), kBlockSizes_case); + + // Create a tokenizer, read one token, then destroy it. + { + TestErrorCollector error_collector; + Tokenizer tokenizer(&input, &error_collector); + + tokenizer.Next(); + } + + // Only "foo" should have been read. + EXPECT_EQ(strlen("foo"), input.ByteCount()); +} + + +} // namespace +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream.cc new file mode 100644 index 0000000..dad6ff1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream.cc @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + + +namespace google { +namespace protobuf { +namespace io { + +ZeroCopyInputStream::~ZeroCopyInputStream() {} +ZeroCopyOutputStream::~ZeroCopyOutputStream() {} + + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream.h new file mode 100644 index 0000000..db5326f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream.h @@ -0,0 +1,238 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains the ZeroCopyInputStream and ZeroCopyOutputStream +// interfaces, which represent abstract I/O streams to and from which +// protocol buffers can be read and written. For a few simple +// implementations of these interfaces, see zero_copy_stream_impl.h. +// +// These interfaces are different from classic I/O streams in that they +// try to minimize the amount of data copying that needs to be done. +// To accomplish this, responsibility for allocating buffers is moved to +// the stream object, rather than being the responsibility of the caller. +// So, the stream can return a buffer which actually points directly into +// the final data structure where the bytes are to be stored, and the caller +// can interact directly with that buffer, eliminating an intermediate copy +// operation. +// +// As an example, consider the common case in which you are reading bytes +// from an array that is already in memory (or perhaps an mmap()ed file). +// With classic I/O streams, you would do something like: +// char buffer[BUFFER_SIZE]; +// input->Read(buffer, BUFFER_SIZE); +// DoSomething(buffer, BUFFER_SIZE); +// Then, the stream basically just calls memcpy() to copy the data from +// the array into your buffer. With a ZeroCopyInputStream, you would do +// this instead: +// const void* buffer; +// int size; +// input->Next(&buffer, &size); +// DoSomething(buffer, size); +// Here, no copy is performed. The input stream returns a pointer directly +// into the backing array, and the caller ends up reading directly from it. +// +// If you want to be able to read the old-fashion way, you can create +// a CodedInputStream or CodedOutputStream wrapping these objects and use +// their ReadRaw()/WriteRaw() methods. These will, of course, add a copy +// step, but Coded*Stream will handle buffering so at least it will be +// reasonably efficient. +// +// ZeroCopyInputStream example: +// // Read in a file and print its contents to stdout. +// int fd = open("myfile", O_RDONLY); +// ZeroCopyInputStream* input = new FileInputStream(fd); +// +// const void* buffer; +// int size; +// while (input->Next(&buffer, &size)) { +// cout.write(buffer, size); +// } +// +// delete input; +// close(fd); +// +// ZeroCopyOutputStream example: +// // Copy the contents of "infile" to "outfile", using plain read() for +// // "infile" but a ZeroCopyOutputStream for "outfile". +// int infd = open("infile", O_RDONLY); +// int outfd = open("outfile", O_WRONLY); +// ZeroCopyOutputStream* output = new FileOutputStream(outfd); +// +// void* buffer; +// int size; +// while (output->Next(&buffer, &size)) { +// int bytes = read(infd, buffer, size); +// if (bytes < size) { +// // Reached EOF. +// output->BackUp(size - bytes); +// break; +// } +// } +// +// delete output; +// close(infd); +// close(outfd); + +#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ +#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ + +#include +#include + +namespace google { + +namespace protobuf { +namespace io { + +// Defined in this file. +class ZeroCopyInputStream; +class ZeroCopyOutputStream; + +// Abstract interface similar to an input stream but designed to minimize +// copying. +class LIBPROTOBUF_EXPORT ZeroCopyInputStream { + public: + inline ZeroCopyInputStream() {} + virtual ~ZeroCopyInputStream(); + + // Obtains a chunk of data from the stream. + // + // Preconditions: + // * "size" and "data" are not NULL. + // + // Postconditions: + // * If the returned value is false, there is no more data to return or + // an error occurred. All errors are permanent. + // * Otherwise, "size" points to the actual number of bytes read and "data" + // points to a pointer to a buffer containing these bytes. + // * Ownership of this buffer remains with the stream, and the buffer + // remains valid only until some other method of the stream is called + // or the stream is destroyed. + // * It is legal for the returned buffer to have zero size, as long + // as repeatedly calling Next() eventually yields a buffer with non-zero + // size. + virtual bool Next(const void** data, int* size) = 0; + + // Backs up a number of bytes, so that the next call to Next() returns + // data again that was already returned by the last call to Next(). This + // is useful when writing procedures that are only supposed to read up + // to a certain point in the input, then return. If Next() returns a + // buffer that goes beyond what you wanted to read, you can use BackUp() + // to return to the point where you intended to finish. + // + // Preconditions: + // * The last method called must have been Next(). + // * count must be less than or equal to the size of the last buffer + // returned by Next(). + // + // Postconditions: + // * The last "count" bytes of the last buffer returned by Next() will be + // pushed back into the stream. Subsequent calls to Next() will return + // the same data again before producing new data. + virtual void BackUp(int count) = 0; + + // Skips a number of bytes. Returns false if the end of the stream is + // reached or some input error occurred. In the end-of-stream case, the + // stream is advanced to the end of the stream (so ByteCount() will return + // the total size of the stream). + virtual bool Skip(int count) = 0; + + // Returns the total number of bytes read since this object was created. + virtual int64 ByteCount() const = 0; + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream); +}; + +// Abstract interface similar to an output stream but designed to minimize +// copying. +class LIBPROTOBUF_EXPORT ZeroCopyOutputStream { + public: + inline ZeroCopyOutputStream() {} + virtual ~ZeroCopyOutputStream(); + + // Obtains a buffer into which data can be written. Any data written + // into this buffer will eventually (maybe instantly, maybe later on) + // be written to the output. + // + // Preconditions: + // * "size" and "data" are not NULL. + // + // Postconditions: + // * If the returned value is false, an error occurred. All errors are + // permanent. + // * Otherwise, "size" points to the actual number of bytes in the buffer + // and "data" points to the buffer. + // * Ownership of this buffer remains with the stream, and the buffer + // remains valid only until some other method of the stream is called + // or the stream is destroyed. + // * Any data which the caller stores in this buffer will eventually be + // written to the output (unless BackUp() is called). + // * It is legal for the returned buffer to have zero size, as long + // as repeatedly calling Next() eventually yields a buffer with non-zero + // size. + virtual bool Next(void** data, int* size) = 0; + + // Backs up a number of bytes, so that the end of the last buffer returned + // by Next() is not actually written. This is needed when you finish + // writing all the data you want to write, but the last buffer was bigger + // than you needed. You don't want to write a bunch of garbage after the + // end of your data, so you use BackUp() to back up. + // + // Preconditions: + // * The last method called must have been Next(). + // * count must be less than or equal to the size of the last buffer + // returned by Next(). + // * The caller must not have written anything to the last "count" bytes + // of that buffer. + // + // Postconditions: + // * The last "count" bytes of the last buffer returned by Next() will be + // ignored. + virtual void BackUp(int count) = 0; + + // Returns the total number of bytes written since this object was created. + virtual int64 ByteCount() const = 0; + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream); +}; + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl.cc new file mode 100644 index 0000000..9fcbb62 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl.cc @@ -0,0 +1,471 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifdef _MSC_VER +#include +#else +#include +#include +#include +#include +#endif +#include +#include +#include + +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace io { + +#ifdef _WIN32 +// Win32 lseek is broken: If invoked on a non-seekable file descriptor, its +// return value is undefined. We re-define it to always produce an error. +#define lseek(fd, offset, origin) ((off_t)-1) +#endif + +namespace { + +// EINTR sucks. +int close_no_eintr(int fd) { + int result; + do { + result = close(fd); + } while (result < 0 && errno == EINTR); + return result; +} + +} // namespace + + +// =================================================================== + +FileInputStream::FileInputStream(int file_descriptor, int block_size) + : copying_input_(file_descriptor), + impl_(©ing_input_, block_size) { +} + +FileInputStream::~FileInputStream() {} + +bool FileInputStream::Close() { + return copying_input_.Close(); +} + +bool FileInputStream::Next(const void** data, int* size) { + return impl_.Next(data, size); +} + +void FileInputStream::BackUp(int count) { + impl_.BackUp(count); +} + +bool FileInputStream::Skip(int count) { + return impl_.Skip(count); +} + +int64 FileInputStream::ByteCount() const { + return impl_.ByteCount(); +} + +FileInputStream::CopyingFileInputStream::CopyingFileInputStream( + int file_descriptor) + : file_(file_descriptor), + close_on_delete_(false), + is_closed_(false), + errno_(0), + previous_seek_failed_(false) { +} + +FileInputStream::CopyingFileInputStream::~CopyingFileInputStream() { + if (close_on_delete_) { + if (!Close()) { + GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_); + } + } +} + +bool FileInputStream::CopyingFileInputStream::Close() { + GOOGLE_CHECK(!is_closed_); + + is_closed_ = true; + if (close_no_eintr(file_) != 0) { + // The docs on close() do not specify whether a file descriptor is still + // open after close() fails with EIO. However, the glibc source code + // seems to indicate that it is not. + errno_ = errno; + return false; + } + + return true; +} + +int FileInputStream::CopyingFileInputStream::Read(void* buffer, int size) { + GOOGLE_CHECK(!is_closed_); + + int result; + do { + result = read(file_, buffer, size); + } while (result < 0 && errno == EINTR); + + if (result < 0) { + // Read error (not EOF). + errno_ = errno; + } + + return result; +} + +int FileInputStream::CopyingFileInputStream::Skip(int count) { + GOOGLE_CHECK(!is_closed_); + + if (!previous_seek_failed_ && + lseek(file_, count, SEEK_CUR) != (off_t)-1) { + // Seek succeeded. + return count; + } else { + // Failed to seek. + + // Note to self: Don't seek again. This file descriptor doesn't + // support it. + previous_seek_failed_ = true; + + // Use the default implementation. + return CopyingInputStream::Skip(count); + } +} + +// =================================================================== + +FileOutputStream::FileOutputStream(int file_descriptor, int block_size) + : copying_output_(file_descriptor), + impl_(©ing_output_, block_size) { +} + +FileOutputStream::~FileOutputStream() { + impl_.Flush(); +} + +bool FileOutputStream::Close() { + bool flush_succeeded = impl_.Flush(); + return copying_output_.Close() && flush_succeeded; +} + +bool FileOutputStream::Flush() { + return impl_.Flush(); +} + +bool FileOutputStream::Next(void** data, int* size) { + return impl_.Next(data, size); +} + +void FileOutputStream::BackUp(int count) { + impl_.BackUp(count); +} + +int64 FileOutputStream::ByteCount() const { + return impl_.ByteCount(); +} + +FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream( + int file_descriptor) + : file_(file_descriptor), + close_on_delete_(false), + is_closed_(false), + errno_(0) { +} + +FileOutputStream::CopyingFileOutputStream::~CopyingFileOutputStream() { + if (close_on_delete_) { + if (!Close()) { + GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_); + } + } +} + +bool FileOutputStream::CopyingFileOutputStream::Close() { + GOOGLE_CHECK(!is_closed_); + + is_closed_ = true; + if (close_no_eintr(file_) != 0) { + // The docs on close() do not specify whether a file descriptor is still + // open after close() fails with EIO. However, the glibc source code + // seems to indicate that it is not. + errno_ = errno; + return false; + } + + return true; +} + +bool FileOutputStream::CopyingFileOutputStream::Write( + const void* buffer, int size) { + GOOGLE_CHECK(!is_closed_); + int total_written = 0; + + const uint8* buffer_base = reinterpret_cast(buffer); + + while (total_written < size) { + int bytes; + do { + bytes = write(file_, buffer_base + total_written, size - total_written); + } while (bytes < 0 && errno == EINTR); + + if (bytes <= 0) { + // Write error. + + // FIXME(kenton): According to the man page, if write() returns zero, + // there was no error; write() simply did not write anything. It's + // unclear under what circumstances this might happen, but presumably + // errno won't be set in this case. I am confused as to how such an + // event should be handled. For now I'm treating it as an error, since + // retrying seems like it could lead to an infinite loop. I suspect + // this never actually happens anyway. + + if (bytes < 0) { + errno_ = errno; + } + return false; + } + total_written += bytes; + } + + return true; +} + +// =================================================================== + +IstreamInputStream::IstreamInputStream(istream* input, int block_size) + : copying_input_(input), + impl_(©ing_input_, block_size) { +} + +IstreamInputStream::~IstreamInputStream() {} + +bool IstreamInputStream::Next(const void** data, int* size) { + return impl_.Next(data, size); +} + +void IstreamInputStream::BackUp(int count) { + impl_.BackUp(count); +} + +bool IstreamInputStream::Skip(int count) { + return impl_.Skip(count); +} + +int64 IstreamInputStream::ByteCount() const { + return impl_.ByteCount(); +} + +IstreamInputStream::CopyingIstreamInputStream::CopyingIstreamInputStream( + istream* input) + : input_(input) { +} + +IstreamInputStream::CopyingIstreamInputStream::~CopyingIstreamInputStream() {} + +int IstreamInputStream::CopyingIstreamInputStream::Read( + void* buffer, int size) { + input_->read(reinterpret_cast(buffer), size); + int result = input_->gcount(); + if (result == 0 && input_->fail() && !input_->eof()) { + return -1; + } + return result; +} + +// =================================================================== + +OstreamOutputStream::OstreamOutputStream(ostream* output, int block_size) + : copying_output_(output), + impl_(©ing_output_, block_size) { +} + +OstreamOutputStream::~OstreamOutputStream() { + impl_.Flush(); +} + +bool OstreamOutputStream::Next(void** data, int* size) { + return impl_.Next(data, size); +} + +void OstreamOutputStream::BackUp(int count) { + impl_.BackUp(count); +} + +int64 OstreamOutputStream::ByteCount() const { + return impl_.ByteCount(); +} + +OstreamOutputStream::CopyingOstreamOutputStream::CopyingOstreamOutputStream( + ostream* output) + : output_(output) { +} + +OstreamOutputStream::CopyingOstreamOutputStream::~CopyingOstreamOutputStream() { +} + +bool OstreamOutputStream::CopyingOstreamOutputStream::Write( + const void* buffer, int size) { + output_->write(reinterpret_cast(buffer), size); + return output_->good(); +} + +// =================================================================== + +ConcatenatingInputStream::ConcatenatingInputStream( + ZeroCopyInputStream* const streams[], int count) + : streams_(streams), stream_count_(count), bytes_retired_(0) { +} + +ConcatenatingInputStream::~ConcatenatingInputStream() { +} + +bool ConcatenatingInputStream::Next(const void** data, int* size) { + while (stream_count_ > 0) { + if (streams_[0]->Next(data, size)) return true; + + // That stream is done. Advance to the next one. + bytes_retired_ += streams_[0]->ByteCount(); + ++streams_; + --stream_count_; + } + + // No more streams. + return false; +} + +void ConcatenatingInputStream::BackUp(int count) { + if (stream_count_ > 0) { + streams_[0]->BackUp(count); + } else { + GOOGLE_LOG(DFATAL) << "Can't BackUp() after failed Next()."; + } +} + +bool ConcatenatingInputStream::Skip(int count) { + while (stream_count_ > 0) { + // Assume that ByteCount() can be used to find out how much we actually + // skipped when Skip() fails. + int64 target_byte_count = streams_[0]->ByteCount() + count; + if (streams_[0]->Skip(count)) return true; + + // Hit the end of the stream. Figure out how many more bytes we still have + // to skip. + int64 final_byte_count = streams_[0]->ByteCount(); + GOOGLE_DCHECK_LT(final_byte_count, target_byte_count); + count = target_byte_count - final_byte_count; + + // That stream is done. Advance to the next one. + bytes_retired_ += final_byte_count; + ++streams_; + --stream_count_; + } + + return false; +} + +int64 ConcatenatingInputStream::ByteCount() const { + if (stream_count_ == 0) { + return bytes_retired_; + } else { + return bytes_retired_ + streams_[0]->ByteCount(); + } +} + + +// =================================================================== + +LimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input, + int64 limit) + : input_(input), limit_(limit) {} + +LimitingInputStream::~LimitingInputStream() { + // If we overshot the limit, back up. + if (limit_ < 0) input_->BackUp(-limit_); +} + +bool LimitingInputStream::Next(const void** data, int* size) { + if (limit_ <= 0) return false; + if (!input_->Next(data, size)) return false; + + limit_ -= *size; + if (limit_ < 0) { + // We overshot the limit. Reduce *size to hide the rest of the buffer. + *size += limit_; + } + return true; +} + +void LimitingInputStream::BackUp(int count) { + if (limit_ < 0) { + input_->BackUp(count - limit_); + limit_ = count; + } else { + input_->BackUp(count); + limit_ += count; + } +} + +bool LimitingInputStream::Skip(int count) { + if (count > limit_) { + if (limit_ < 0) return false; + input_->Skip(limit_); + limit_ = 0; + return false; + } else { + if (!input_->Skip(count)) return false; + limit_ -= count; + return true; + } +} + +int64 LimitingInputStream::ByteCount() const { + if (limit_ < 0) { + return input_->ByteCount() + limit_; + } else { + return input_->ByteCount(); + } +} + + +// =================================================================== + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl.h new file mode 100644 index 0000000..9fedb00 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl.h @@ -0,0 +1,357 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains common implementations of the interfaces defined in +// zero_copy_stream.h which are only included in the full (non-lite) +// protobuf library. These implementations include Unix file descriptors +// and C++ iostreams. See also: zero_copy_stream_impl_lite.h + +#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ +#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ + +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace io { + + +// =================================================================== + +// A ZeroCopyInputStream which reads from a file descriptor. +// +// FileInputStream is preferred over using an ifstream with IstreamInputStream. +// The latter will introduce an extra layer of buffering, harming performance. +// Also, it's conceivable that FileInputStream could someday be enhanced +// to use zero-copy file descriptors on OSs which support them. +class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream { + public: + // Creates a stream that reads from the given Unix file descriptor. + // If a block_size is given, it specifies the number of bytes that + // should be read and returned with each call to Next(). Otherwise, + // a reasonable default is used. + explicit FileInputStream(int file_descriptor, int block_size = -1); + ~FileInputStream(); + + // Flushes any buffers and closes the underlying file. Returns false if + // an error occurs during the process; use GetErrno() to examine the error. + // Even if an error occurs, the file descriptor is closed when this returns. + bool Close(); + + // By default, the file descriptor is not closed when the stream is + // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: + // This leaves no way for the caller to detect if close() fails. If + // detecting close() errors is important to you, you should arrange + // to close the descriptor yourself. + void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); } + + // If an I/O error has occurred on this file descriptor, this is the + // errno from that error. Otherwise, this is zero. Once an error + // occurs, the stream is broken and all subsequent operations will + // fail. + int GetErrno() { return copying_input_.GetErrno(); } + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + private: + class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream { + public: + CopyingFileInputStream(int file_descriptor); + ~CopyingFileInputStream(); + + bool Close(); + void SetCloseOnDelete(bool value) { close_on_delete_ = value; } + int GetErrno() { return errno_; } + + // implements CopyingInputStream --------------------------------- + int Read(void* buffer, int size); + int Skip(int count); + + private: + // The file descriptor. + const int file_; + bool close_on_delete_; + bool is_closed_; + + // The errno of the I/O error, if one has occurred. Otherwise, zero. + int errno_; + + // Did we try to seek once and fail? If so, we assume this file descriptor + // doesn't support seeking and won't try again. + bool previous_seek_failed_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream); + }; + + CopyingFileInputStream copying_input_; + CopyingInputStreamAdaptor impl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream which writes to a file descriptor. +// +// FileOutputStream is preferred over using an ofstream with +// OstreamOutputStream. The latter will introduce an extra layer of buffering, +// harming performance. Also, it's conceivable that FileOutputStream could +// someday be enhanced to use zero-copy file descriptors on OSs which +// support them. +class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { + public: + // Creates a stream that writes to the given Unix file descriptor. + // If a block_size is given, it specifies the size of the buffers + // that should be returned by Next(). Otherwise, a reasonable default + // is used. + explicit FileOutputStream(int file_descriptor, int block_size = -1); + ~FileOutputStream(); + + // Flushes any buffers and closes the underlying file. Returns false if + // an error occurs during the process; use GetErrno() to examine the error. + // Even if an error occurs, the file descriptor is closed when this returns. + bool Close(); + + // Flushes FileOutputStream's buffers but does not close the + // underlying file. No special measures are taken to ensure that + // underlying operating system file object is synchronized to disk. + bool Flush(); + + // By default, the file descriptor is not closed when the stream is + // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: + // This leaves no way for the caller to detect if close() fails. If + // detecting close() errors is important to you, you should arrange + // to close the descriptor yourself. + void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); } + + // If an I/O error has occurred on this file descriptor, this is the + // errno from that error. Otherwise, this is zero. Once an error + // occurs, the stream is broken and all subsequent operations will + // fail. + int GetErrno() { return copying_output_.GetErrno(); } + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream { + public: + CopyingFileOutputStream(int file_descriptor); + ~CopyingFileOutputStream(); + + bool Close(); + void SetCloseOnDelete(bool value) { close_on_delete_ = value; } + int GetErrno() { return errno_; } + + // implements CopyingOutputStream -------------------------------- + bool Write(const void* buffer, int size); + + private: + // The file descriptor. + const int file_; + bool close_on_delete_; + bool is_closed_; + + // The errno of the I/O error, if one has occurred. Otherwise, zero. + int errno_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream); + }; + + CopyingFileOutputStream copying_output_; + CopyingOutputStreamAdaptor impl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream); +}; + +// =================================================================== + +// A ZeroCopyInputStream which reads from a C++ istream. +// +// Note that for reading files (or anything represented by a file descriptor), +// FileInputStream is more efficient. +class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream { + public: + // Creates a stream that reads from the given C++ istream. + // If a block_size is given, it specifies the number of bytes that + // should be read and returned with each call to Next(). Otherwise, + // a reasonable default is used. + explicit IstreamInputStream(istream* stream, int block_size = -1); + ~IstreamInputStream(); + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + private: + class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream { + public: + CopyingIstreamInputStream(istream* input); + ~CopyingIstreamInputStream(); + + // implements CopyingInputStream --------------------------------- + int Read(void* buffer, int size); + // (We use the default implementation of Skip().) + + private: + // The stream. + istream* input_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream); + }; + + CopyingIstreamInputStream copying_input_; + CopyingInputStreamAdaptor impl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream which writes to a C++ ostream. +// +// Note that for writing files (or anything represented by a file descriptor), +// FileOutputStream is more efficient. +class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream { + public: + // Creates a stream that writes to the given C++ ostream. + // If a block_size is given, it specifies the size of the buffers + // that should be returned by Next(). Otherwise, a reasonable default + // is used. + explicit OstreamOutputStream(ostream* stream, int block_size = -1); + ~OstreamOutputStream(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream { + public: + CopyingOstreamOutputStream(ostream* output); + ~CopyingOstreamOutputStream(); + + // implements CopyingOutputStream -------------------------------- + bool Write(const void* buffer, int size); + + private: + // The stream. + ostream* output_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream); + }; + + CopyingOstreamOutputStream copying_output_; + CopyingOutputStreamAdaptor impl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream); +}; + +// =================================================================== + +// A ZeroCopyInputStream which reads from several other streams in sequence. +// ConcatenatingInputStream is unable to distinguish between end-of-stream +// and read errors in the underlying streams, so it assumes any errors mean +// end-of-stream. So, if the underlying streams fail for any other reason, +// ConcatenatingInputStream may do odd things. It is suggested that you do +// not use ConcatenatingInputStream on streams that might produce read errors +// other than end-of-stream. +class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream { + public: + // All streams passed in as well as the array itself must remain valid + // until the ConcatenatingInputStream is destroyed. + ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count); + ~ConcatenatingInputStream(); + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + + private: + // As streams are retired, streams_ is incremented and count_ is + // decremented. + ZeroCopyInputStream* const* streams_; + int stream_count_; + int64 bytes_retired_; // Bytes read from previous streams. + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream); +}; + +// =================================================================== + +// A ZeroCopyInputStream which wraps some other stream and limits it to +// a particular byte count. +class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream { + public: + LimitingInputStream(ZeroCopyInputStream* input, int64 limit); + ~LimitingInputStream(); + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + + private: + ZeroCopyInputStream* input_; + int64 limit_; // Decreases as we go, becomes negative if we overshoot. + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream); +}; + +// =================================================================== + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl_lite.cc new file mode 100644 index 0000000..f552e1f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl_lite.cc @@ -0,0 +1,393 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { + +namespace { + +// Default block size for Copying{In,Out}putStreamAdaptor. +static const int kDefaultBlockSize = 8192; + +} // namespace + +// =================================================================== + +ArrayInputStream::ArrayInputStream(const void* data, int size, + int block_size) + : data_(reinterpret_cast(data)), + size_(size), + block_size_(block_size > 0 ? block_size : size), + position_(0), + last_returned_size_(0) { +} + +ArrayInputStream::~ArrayInputStream() { +} + +bool ArrayInputStream::Next(const void** data, int* size) { + if (position_ < size_) { + last_returned_size_ = min(block_size_, size_ - position_); + *data = data_ + position_; + *size = last_returned_size_; + position_ += last_returned_size_; + return true; + } else { + // We're at the end of the array. + last_returned_size_ = 0; // Don't let caller back up. + return false; + } +} + +void ArrayInputStream::BackUp(int count) { + GOOGLE_CHECK_GT(last_returned_size_, 0) + << "BackUp() can only be called after a successful Next()."; + GOOGLE_CHECK_LE(count, last_returned_size_); + GOOGLE_CHECK_GE(count, 0); + position_ -= count; + last_returned_size_ = 0; // Don't let caller back up further. +} + +bool ArrayInputStream::Skip(int count) { + GOOGLE_CHECK_GE(count, 0); + last_returned_size_ = 0; // Don't let caller back up. + if (count > size_ - position_) { + position_ = size_; + return false; + } else { + position_ += count; + return true; + } +} + +int64 ArrayInputStream::ByteCount() const { + return position_; +} + + +// =================================================================== + +ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size) + : data_(reinterpret_cast(data)), + size_(size), + block_size_(block_size > 0 ? block_size : size), + position_(0), + last_returned_size_(0) { +} + +ArrayOutputStream::~ArrayOutputStream() { +} + +bool ArrayOutputStream::Next(void** data, int* size) { + if (position_ < size_) { + last_returned_size_ = min(block_size_, size_ - position_); + *data = data_ + position_; + *size = last_returned_size_; + position_ += last_returned_size_; + return true; + } else { + // We're at the end of the array. + last_returned_size_ = 0; // Don't let caller back up. + return false; + } +} + +void ArrayOutputStream::BackUp(int count) { + GOOGLE_CHECK_GT(last_returned_size_, 0) + << "BackUp() can only be called after a successful Next()."; + GOOGLE_CHECK_LE(count, last_returned_size_); + GOOGLE_CHECK_GE(count, 0); + position_ -= count; + last_returned_size_ = 0; // Don't let caller back up further. +} + +int64 ArrayOutputStream::ByteCount() const { + return position_; +} + +// =================================================================== + +StringOutputStream::StringOutputStream(string* target) + : target_(target) { +} + +StringOutputStream::~StringOutputStream() { +} + +bool StringOutputStream::Next(void** data, int* size) { + int old_size = target_->size(); + + // Grow the string. + if (old_size < target_->capacity()) { + // Resize the string to match its capacity, since we can get away + // without a memory allocation this way. + STLStringResizeUninitialized(target_, target_->capacity()); + } else { + // Size has reached capacity, so double the size. Also make sure + // that the new size is at least kMinimumSize. + STLStringResizeUninitialized( + target_, + max(old_size * 2, + kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness. + } + + *data = string_as_array(target_) + old_size; + *size = target_->size() - old_size; + return true; +} + +void StringOutputStream::BackUp(int count) { + GOOGLE_CHECK_GE(count, 0); + GOOGLE_CHECK_LE(count, target_->size()); + target_->resize(target_->size() - count); +} + +int64 StringOutputStream::ByteCount() const { + return target_->size(); +} + +// =================================================================== + +CopyingInputStream::~CopyingInputStream() {} + +int CopyingInputStream::Skip(int count) { + char junk[4096]; + int skipped = 0; + while (skipped < count) { + int bytes = Read(junk, min(count - skipped, + implicit_cast(sizeof(junk)))); + if (bytes <= 0) { + // EOF or read error. + return skipped; + } + skipped += bytes; + } + return skipped; +} + +CopyingInputStreamAdaptor::CopyingInputStreamAdaptor( + CopyingInputStream* copying_stream, int block_size) + : copying_stream_(copying_stream), + owns_copying_stream_(false), + failed_(false), + position_(0), + buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), + buffer_used_(0), + backup_bytes_(0) { +} + +CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() { + if (owns_copying_stream_) { + delete copying_stream_; + } +} + +bool CopyingInputStreamAdaptor::Next(const void** data, int* size) { + if (failed_) { + // Already failed on a previous read. + return false; + } + + AllocateBufferIfNeeded(); + + if (backup_bytes_ > 0) { + // We have data left over from a previous BackUp(), so just return that. + *data = buffer_.get() + buffer_used_ - backup_bytes_; + *size = backup_bytes_; + backup_bytes_ = 0; + return true; + } + + // Read new data into the buffer. + buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_); + if (buffer_used_ <= 0) { + // EOF or read error. We don't need the buffer anymore. + if (buffer_used_ < 0) { + // Read error (not EOF). + failed_ = true; + } + FreeBuffer(); + return false; + } + position_ += buffer_used_; + + *size = buffer_used_; + *data = buffer_.get(); + return true; +} + +void CopyingInputStreamAdaptor::BackUp(int count) { + GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL) + << " BackUp() can only be called after Next()."; + GOOGLE_CHECK_LE(count, buffer_used_) + << " Can't back up over more bytes than were returned by the last call" + " to Next()."; + GOOGLE_CHECK_GE(count, 0) + << " Parameter to BackUp() can't be negative."; + + backup_bytes_ = count; +} + +bool CopyingInputStreamAdaptor::Skip(int count) { + GOOGLE_CHECK_GE(count, 0); + + if (failed_) { + // Already failed on a previous read. + return false; + } + + // First skip any bytes left over from a previous BackUp(). + if (backup_bytes_ >= count) { + // We have more data left over than we're trying to skip. Just chop it. + backup_bytes_ -= count; + return true; + } + + count -= backup_bytes_; + backup_bytes_ = 0; + + int skipped = copying_stream_->Skip(count); + position_ += skipped; + return skipped == count; +} + +int64 CopyingInputStreamAdaptor::ByteCount() const { + return position_ - backup_bytes_; +} + +void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() { + if (buffer_.get() == NULL) { + buffer_.reset(new uint8[buffer_size_]); + } +} + +void CopyingInputStreamAdaptor::FreeBuffer() { + GOOGLE_CHECK_EQ(backup_bytes_, 0); + buffer_used_ = 0; + buffer_.reset(); +} + +// =================================================================== + +CopyingOutputStream::~CopyingOutputStream() {} + +CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor( + CopyingOutputStream* copying_stream, int block_size) + : copying_stream_(copying_stream), + owns_copying_stream_(false), + failed_(false), + position_(0), + buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), + buffer_used_(0) { +} + +CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() { + WriteBuffer(); + if (owns_copying_stream_) { + delete copying_stream_; + } +} + +bool CopyingOutputStreamAdaptor::Flush() { + return WriteBuffer(); +} + +bool CopyingOutputStreamAdaptor::Next(void** data, int* size) { + if (buffer_used_ == buffer_size_) { + if (!WriteBuffer()) return false; + } + + AllocateBufferIfNeeded(); + + *data = buffer_.get() + buffer_used_; + *size = buffer_size_ - buffer_used_; + buffer_used_ = buffer_size_; + return true; +} + +void CopyingOutputStreamAdaptor::BackUp(int count) { + GOOGLE_CHECK_GE(count, 0); + GOOGLE_CHECK_EQ(buffer_used_, buffer_size_) + << " BackUp() can only be called after Next()."; + GOOGLE_CHECK_LE(count, buffer_used_) + << " Can't back up over more bytes than were returned by the last call" + " to Next()."; + + buffer_used_ -= count; +} + +int64 CopyingOutputStreamAdaptor::ByteCount() const { + return position_ + buffer_used_; +} + +bool CopyingOutputStreamAdaptor::WriteBuffer() { + if (failed_) { + // Already failed on a previous write. + return false; + } + + if (buffer_used_ == 0) return true; + + if (copying_stream_->Write(buffer_.get(), buffer_used_)) { + position_ += buffer_used_; + buffer_used_ = 0; + return true; + } else { + failed_ = true; + FreeBuffer(); + return false; + } +} + +void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() { + if (buffer_ == NULL) { + buffer_.reset(new uint8[buffer_size_]); + } +} + +void CopyingOutputStreamAdaptor::FreeBuffer() { + buffer_used_ = 0; + buffer_.reset(); +} + +// =================================================================== + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl_lite.h new file mode 100644 index 0000000..153f543 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_impl_lite.h @@ -0,0 +1,340 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains common implementations of the interfaces defined in +// zero_copy_stream.h which are included in the "lite" protobuf library. +// These implementations cover I/O on raw arrays and strings, as well as +// adaptors which make it easy to implement streams based on traditional +// streams. Of course, many users will probably want to write their own +// implementations of these interfaces specific to the particular I/O +// abstractions they prefer to use, but these should cover the most common +// cases. + +#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ +#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ + +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace io { + +// =================================================================== + +// A ZeroCopyInputStream backed by an in-memory array of bytes. +class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream { + public: + // Create an InputStream that returns the bytes pointed to by "data". + // "data" remains the property of the caller but must remain valid until + // the stream is destroyed. If a block_size is given, calls to Next() + // will return data blocks no larger than the given size. Otherwise, the + // first call to Next() returns the entire array. block_size is mainly + // useful for testing; in production you would probably never want to set + // it. + ArrayInputStream(const void* data, int size, int block_size = -1); + ~ArrayInputStream(); + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + + private: + const uint8* const data_; // The byte array. + const int size_; // Total size of the array. + const int block_size_; // How many bytes to return at a time. + + int position_; + int last_returned_size_; // How many bytes we returned last time Next() + // was called (used for error checking only). + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream backed by an in-memory array of bytes. +class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream { + public: + // Create an OutputStream that writes to the bytes pointed to by "data". + // "data" remains the property of the caller but must remain valid until + // the stream is destroyed. If a block_size is given, calls to Next() + // will return data blocks no larger than the given size. Otherwise, the + // first call to Next() returns the entire array. block_size is mainly + // useful for testing; in production you would probably never want to set + // it. + ArrayOutputStream(void* data, int size, int block_size = -1); + ~ArrayOutputStream(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + uint8* const data_; // The byte array. + const int size_; // Total size of the array. + const int block_size_; // How many bytes to return at a time. + + int position_; + int last_returned_size_; // How many bytes we returned last time Next() + // was called (used for error checking only). + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream which appends bytes to a string. +class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream { + public: + // Create a StringOutputStream which appends bytes to the given string. + // The string remains property of the caller, but it MUST NOT be accessed + // in any way until the stream is destroyed. + // + // Hint: If you call target->reserve(n) before creating the stream, + // the first call to Next() will return at least n bytes of buffer + // space. + explicit StringOutputStream(string* target); + ~StringOutputStream(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + static const int kMinimumSize = 16; + + string* target_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream); +}; + +// Note: There is no StringInputStream. Instead, just create an +// ArrayInputStream as follows: +// ArrayInputStream input(str.data(), str.size()); + +// =================================================================== + +// A generic traditional input stream interface. +// +// Lots of traditional input streams (e.g. file descriptors, C stdio +// streams, and C++ iostreams) expose an interface where every read +// involves copying bytes into a buffer. If you want to take such an +// interface and make a ZeroCopyInputStream based on it, simply implement +// CopyingInputStream and then use CopyingInputStreamAdaptor. +// +// CopyingInputStream implementations should avoid buffering if possible. +// CopyingInputStreamAdaptor does its own buffering and will read data +// in large blocks. +class LIBPROTOBUF_EXPORT CopyingInputStream { + public: + virtual ~CopyingInputStream(); + + // Reads up to "size" bytes into the given buffer. Returns the number of + // bytes read. Read() waits until at least one byte is available, or + // returns zero if no bytes will ever become available (EOF), or -1 if a + // permanent read error occurred. + virtual int Read(void* buffer, int size) = 0; + + // Skips the next "count" bytes of input. Returns the number of bytes + // actually skipped. This will always be exactly equal to "count" unless + // EOF was reached or a permanent read error occurred. + // + // The default implementation just repeatedly calls Read() into a scratch + // buffer. + virtual int Skip(int count); +}; + +// A ZeroCopyInputStream which reads from a CopyingInputStream. This is +// useful for implementing ZeroCopyInputStreams that read from traditional +// streams. Note that this class is not really zero-copy. +// +// If you want to read from file descriptors or C++ istreams, this is +// already implemented for you: use FileInputStream or IstreamInputStream +// respectively. +class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream { + public: + // Creates a stream that reads from the given CopyingInputStream. + // If a block_size is given, it specifies the number of bytes that + // should be read and returned with each call to Next(). Otherwise, + // a reasonable default is used. The caller retains ownership of + // copying_stream unless SetOwnsCopyingStream(true) is called. + explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream, + int block_size = -1); + ~CopyingInputStreamAdaptor(); + + // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to + // delete the underlying CopyingInputStream when it is destroyed. + void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + private: + // Insures that buffer_ is not NULL. + void AllocateBufferIfNeeded(); + // Frees the buffer and resets buffer_used_. + void FreeBuffer(); + + // The underlying copying stream. + CopyingInputStream* copying_stream_; + bool owns_copying_stream_; + + // True if we have seen a permenant error from the underlying stream. + bool failed_; + + // The current position of copying_stream_, relative to the point where + // we started reading. + int64 position_; + + // Data is read into this buffer. It may be NULL if no buffer is currently + // in use. Otherwise, it points to an array of size buffer_size_. + scoped_array buffer_; + const int buffer_size_; + + // Number of valid bytes currently in the buffer (i.e. the size last + // returned by Next()). 0 <= buffer_used_ <= buffer_size_. + int buffer_used_; + + // Number of bytes in the buffer which were backed up over by a call to + // BackUp(). These need to be returned again. + // 0 <= backup_bytes_ <= buffer_used_ + int backup_bytes_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor); +}; + +// =================================================================== + +// A generic traditional output stream interface. +// +// Lots of traditional output streams (e.g. file descriptors, C stdio +// streams, and C++ iostreams) expose an interface where every write +// involves copying bytes from a buffer. If you want to take such an +// interface and make a ZeroCopyOutputStream based on it, simply implement +// CopyingOutputStream and then use CopyingOutputStreamAdaptor. +// +// CopyingOutputStream implementations should avoid buffering if possible. +// CopyingOutputStreamAdaptor does its own buffering and will write data +// in large blocks. +class LIBPROTOBUF_EXPORT CopyingOutputStream { + public: + virtual ~CopyingOutputStream(); + + // Writes "size" bytes from the given buffer to the output. Returns true + // if successful, false on a write error. + virtual bool Write(const void* buffer, int size) = 0; +}; + +// A ZeroCopyOutputStream which writes to a CopyingOutputStream. This is +// useful for implementing ZeroCopyOutputStreams that write to traditional +// streams. Note that this class is not really zero-copy. +// +// If you want to write to file descriptors or C++ ostreams, this is +// already implemented for you: use FileOutputStream or OstreamOutputStream +// respectively. +class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream { + public: + // Creates a stream that writes to the given Unix file descriptor. + // If a block_size is given, it specifies the size of the buffers + // that should be returned by Next(). Otherwise, a reasonable default + // is used. + explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream, + int block_size = -1); + ~CopyingOutputStreamAdaptor(); + + // Writes all pending data to the underlying stream. Returns false if a + // write error occurred on the underlying stream. (The underlying + // stream itself is not necessarily flushed.) + bool Flush(); + + // Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to + // delete the underlying CopyingOutputStream when it is destroyed. + void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + // Write the current buffer, if it is present. + bool WriteBuffer(); + // Insures that buffer_ is not NULL. + void AllocateBufferIfNeeded(); + // Frees the buffer. + void FreeBuffer(); + + // The underlying copying stream. + CopyingOutputStream* copying_stream_; + bool owns_copying_stream_; + + // True if we have seen a permenant error from the underlying stream. + bool failed_; + + // The current position of copying_stream_, relative to the point where + // we started writing. + int64 position_; + + // Data is written from this buffer. It may be NULL if no buffer is + // currently in use. Otherwise, it points to an array of size buffer_size_. + scoped_array buffer_; + const int buffer_size_; + + // Number of valid bytes currently in the buffer (i.e. the size last + // returned by Next()). When BackUp() is called, we just reduce this. + // 0 <= buffer_used_ <= buffer_size_. + int buffer_used_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor); +}; + +// =================================================================== + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_unittest.cc new file mode 100644 index 0000000..6f155df --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/io/zero_copy_stream_unittest.cc @@ -0,0 +1,944 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Testing strategy: For each type of I/O (array, string, file, etc.) we +// create an output stream and write some data to it, then create a +// corresponding input stream to read the same data back and expect it to +// match. When the data is written, it is written in several small chunks +// of varying sizes, with a BackUp() after each chunk. It is read back +// similarly, but with chunks separated at different points. The whole +// process is run with a variety of block sizes for both the input and +// the output. +// +// TODO(kenton): Rewrite this test to bring it up to the standards of all +// the other proto2 tests. May want to wait for gTest to implement +// "parametized tests" so that one set of tests can be used on all the +// implementations. + +#include "config.h" + +#ifdef _MSC_VER +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include + +#include +#include + +#if HAVE_ZLIB +#include +#endif + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { +namespace { + +#ifdef _WIN32 +#define pipe(fds) _pipe(fds, 4096, O_BINARY) +#endif + +#ifndef O_BINARY +#ifdef _O_BINARY +#define O_BINARY _O_BINARY +#else +#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. +#endif +#endif + +class IoTest : public testing::Test { + protected: + // Test helpers. + + // Helper to write an array of data to an output stream. + bool WriteToOutput(ZeroCopyOutputStream* output, const void* data, int size); + // Helper to read a fixed-length array of data from an input stream. + int ReadFromInput(ZeroCopyInputStream* input, void* data, int size); + // Write a string to the output stream. + void WriteString(ZeroCopyOutputStream* output, const string& str); + // Read a number of bytes equal to the size of the given string and checks + // that it matches the string. + void ReadString(ZeroCopyInputStream* input, const string& str); + // Writes some text to the output stream in a particular order. Returns + // the number of bytes written, incase the caller needs that to set up an + // input stream. + int WriteStuff(ZeroCopyOutputStream* output); + // Reads text from an input stream and expects it to match what + // WriteStuff() writes. + void ReadStuff(ZeroCopyInputStream* input); + + // Similar to WriteStuff, but performs more sophisticated testing. + int WriteStuffLarge(ZeroCopyOutputStream* output); + // Reads and tests a stream that should have been written to + // via WriteStuffLarge(). + void ReadStuffLarge(ZeroCopyInputStream* input); + +#if HAVE_ZLIB + string Compress(const string& data, const GzipOutputStream::Options& options); + string Uncompress(const string& data); +#endif + + static const int kBlockSizes[]; + static const int kBlockSizeCount; +}; + +const int IoTest::kBlockSizes[] = {-1, 1, 2, 5, 7, 10, 23, 64}; +const int IoTest::kBlockSizeCount = GOOGLE_ARRAYSIZE(IoTest::kBlockSizes); + +bool IoTest::WriteToOutput(ZeroCopyOutputStream* output, + const void* data, int size) { + const uint8* in = reinterpret_cast(data); + int in_size = size; + + void* out; + int out_size; + + while (true) { + if (!output->Next(&out, &out_size)) { + return false; + } + EXPECT_GT(out_size, 0); + + if (in_size <= out_size) { + memcpy(out, in, in_size); + output->BackUp(out_size - in_size); + return true; + } + + memcpy(out, in, out_size); + in += out_size; + in_size -= out_size; + } +} + +#define MAX_REPEATED_ZEROS 100 + +int IoTest::ReadFromInput(ZeroCopyInputStream* input, void* data, int size) { + uint8* out = reinterpret_cast(data); + int out_size = size; + + const void* in; + int in_size = 0; + + int repeated_zeros = 0; + + while (true) { + if (!input->Next(&in, &in_size)) { + return size - out_size; + } + EXPECT_GT(in_size, -1); + if (in_size == 0) { + repeated_zeros++; + } else { + repeated_zeros = 0; + } + EXPECT_LT(repeated_zeros, MAX_REPEATED_ZEROS); + + if (out_size <= in_size) { + memcpy(out, in, out_size); + if (in_size > out_size) { + input->BackUp(in_size - out_size); + } + return size; // Copied all of it. + } + + memcpy(out, in, in_size); + out += in_size; + out_size -= in_size; + } +} + +void IoTest::WriteString(ZeroCopyOutputStream* output, const string& str) { + EXPECT_TRUE(WriteToOutput(output, str.c_str(), str.size())); +} + +void IoTest::ReadString(ZeroCopyInputStream* input, const string& str) { + scoped_array buffer(new char[str.size() + 1]); + buffer[str.size()] = '\0'; + EXPECT_EQ(ReadFromInput(input, buffer.get(), str.size()), str.size()); + EXPECT_STREQ(str.c_str(), buffer.get()); +} + +int IoTest::WriteStuff(ZeroCopyOutputStream* output) { + WriteString(output, "Hello world!\n"); + WriteString(output, "Some te"); + WriteString(output, "xt. Blah blah."); + WriteString(output, "abcdefg"); + WriteString(output, "01234567890123456789"); + WriteString(output, "foobar"); + + EXPECT_EQ(output->ByteCount(), 68); + + int result = output->ByteCount(); + return result; +} + +// Reads text from an input stream and expects it to match what WriteStuff() +// writes. +void IoTest::ReadStuff(ZeroCopyInputStream* input) { + ReadString(input, "Hello world!\n"); + ReadString(input, "Some text. "); + ReadString(input, "Blah "); + ReadString(input, "blah."); + ReadString(input, "abcdefg"); + EXPECT_TRUE(input->Skip(20)); + ReadString(input, "foo"); + ReadString(input, "bar"); + + EXPECT_EQ(input->ByteCount(), 68); + + uint8 byte; + EXPECT_EQ(ReadFromInput(input, &byte, 1), 0); +} + +int IoTest::WriteStuffLarge(ZeroCopyOutputStream* output) { + WriteString(output, "Hello world!\n"); + WriteString(output, "Some te"); + WriteString(output, "xt. Blah blah."); + WriteString(output, string(100000, 'x')); // A very long string + WriteString(output, string(100000, 'y')); // A very long string + WriteString(output, "01234567890123456789"); + + EXPECT_EQ(output->ByteCount(), 200055); + + int result = output->ByteCount(); + return result; +} + +// Reads text from an input stream and expects it to match what WriteStuff() +// writes. +void IoTest::ReadStuffLarge(ZeroCopyInputStream* input) { + ReadString(input, "Hello world!\nSome text. "); + EXPECT_TRUE(input->Skip(5)); + ReadString(input, "blah."); + EXPECT_TRUE(input->Skip(100000 - 10)); + ReadString(input, string(10, 'x') + string(100000 - 20000, 'y')); + EXPECT_TRUE(input->Skip(20000 - 10)); + ReadString(input, "yyyyyyyyyy01234567890123456789"); + + EXPECT_EQ(input->ByteCount(), 200055); + + uint8 byte; + EXPECT_EQ(ReadFromInput(input, &byte, 1), 0); +} + +// =================================================================== + +TEST_F(IoTest, ArrayIo) { + const int kBufferSize = 256; + uint8 buffer[kBufferSize]; + + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + int size; + { + ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); + size = WriteStuff(&output); + } + { + ArrayInputStream input(buffer, size, kBlockSizes[j]); + ReadStuff(&input); + } + } + } +} + +TEST_F(IoTest, TwoSessionWrite) { + // Test that two concatenated write sessions read correctly + + static const char* strA = "0123456789"; + static const char* strB = "WhirledPeas"; + const int kBufferSize = 2*1024; + uint8* buffer = new uint8[kBufferSize]; + char* temp_buffer = new char[40]; + + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + ArrayOutputStream* output = + new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]); + CodedOutputStream* coded_output = new CodedOutputStream(output); + coded_output->WriteVarint32(strlen(strA)); + coded_output->WriteRaw(strA, strlen(strA)); + delete coded_output; // flush + int64 pos = output->ByteCount(); + delete output; + output = new ArrayOutputStream( + buffer + pos, kBufferSize - pos, kBlockSizes[i]); + coded_output = new CodedOutputStream(output); + coded_output->WriteVarint32(strlen(strB)); + coded_output->WriteRaw(strB, strlen(strB)); + delete coded_output; // flush + int64 size = pos + output->ByteCount(); + delete output; + + ArrayInputStream* input = + new ArrayInputStream(buffer, size, kBlockSizes[j]); + CodedInputStream* coded_input = new CodedInputStream(input); + uint32 insize; + EXPECT_TRUE(coded_input->ReadVarint32(&insize)); + EXPECT_EQ(strlen(strA), insize); + EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); + EXPECT_EQ(0, memcmp(temp_buffer, strA, insize)); + + EXPECT_TRUE(coded_input->ReadVarint32(&insize)); + EXPECT_EQ(strlen(strB), insize); + EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); + EXPECT_EQ(0, memcmp(temp_buffer, strB, insize)); + + delete coded_input; + delete input; + } + } + + delete [] temp_buffer; + delete [] buffer; +} + +#if HAVE_ZLIB +TEST_F(IoTest, GzipIo) { + const int kBufferSize = 2*1024; + uint8* buffer = new uint8[kBufferSize]; + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + for (int z = 0; z < kBlockSizeCount; z++) { + int gzip_buffer_size = kBlockSizes[z]; + int size; + { + ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); + GzipOutputStream::Options options; + options.format = GzipOutputStream::GZIP; + if (gzip_buffer_size != -1) { + options.buffer_size = gzip_buffer_size; + } + GzipOutputStream gzout(&output, options); + WriteStuff(&gzout); + gzout.Close(); + size = output.ByteCount(); + } + { + ArrayInputStream input(buffer, size, kBlockSizes[j]); + GzipInputStream gzin( + &input, GzipInputStream::GZIP, gzip_buffer_size); + ReadStuff(&gzin); + } + } + } + } + delete [] buffer; +} + +TEST_F(IoTest, GzipIoWithFlush) { + const int kBufferSize = 2*1024; + uint8* buffer = new uint8[kBufferSize]; + // We start with i = 4 as we want a block size > 6. With block size <= 6 + // Flush() fills up the entire 2K buffer with flush markers and the test + // fails. See documentation for Flush() for more detail. + for (int i = 4; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + for (int z = 0; z < kBlockSizeCount; z++) { + int gzip_buffer_size = kBlockSizes[z]; + int size; + { + ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); + GzipOutputStream::Options options; + options.format = GzipOutputStream::GZIP; + if (gzip_buffer_size != -1) { + options.buffer_size = gzip_buffer_size; + } + GzipOutputStream gzout(&output, options); + WriteStuff(&gzout); + EXPECT_TRUE(gzout.Flush()); + gzout.Close(); + size = output.ByteCount(); + } + { + ArrayInputStream input(buffer, size, kBlockSizes[j]); + GzipInputStream gzin( + &input, GzipInputStream::GZIP, gzip_buffer_size); + ReadStuff(&gzin); + } + } + } + } + delete [] buffer; +} + +TEST_F(IoTest, GzipIoContiguousFlushes) { + const int kBufferSize = 2*1024; + uint8* buffer = new uint8[kBufferSize]; + + int block_size = kBlockSizes[4]; + int gzip_buffer_size = block_size; + int size; + + ArrayOutputStream output(buffer, kBufferSize, block_size); + GzipOutputStream::Options options; + options.format = GzipOutputStream::GZIP; + if (gzip_buffer_size != -1) { + options.buffer_size = gzip_buffer_size; + } + GzipOutputStream gzout(&output, options); + WriteStuff(&gzout); + EXPECT_TRUE(gzout.Flush()); + EXPECT_TRUE(gzout.Flush()); + gzout.Close(); + size = output.ByteCount(); + + ArrayInputStream input(buffer, size, block_size); + GzipInputStream gzin( + &input, GzipInputStream::GZIP, gzip_buffer_size); + ReadStuff(&gzin); + + delete [] buffer; +} + +TEST_F(IoTest, GzipIoReadAfterFlush) { + const int kBufferSize = 2*1024; + uint8* buffer = new uint8[kBufferSize]; + + int block_size = kBlockSizes[4]; + int gzip_buffer_size = block_size; + int size; + ArrayOutputStream output(buffer, kBufferSize, block_size); + GzipOutputStream::Options options; + options.format = GzipOutputStream::GZIP; + if (gzip_buffer_size != -1) { + options.buffer_size = gzip_buffer_size; + } + + GzipOutputStream gzout(&output, options); + WriteStuff(&gzout); + EXPECT_TRUE(gzout.Flush()); + size = output.ByteCount(); + + ArrayInputStream input(buffer, size, block_size); + GzipInputStream gzin( + &input, GzipInputStream::GZIP, gzip_buffer_size); + ReadStuff(&gzin); + + gzout.Close(); + + delete [] buffer; +} + +TEST_F(IoTest, ZlibIo) { + const int kBufferSize = 2*1024; + uint8* buffer = new uint8[kBufferSize]; + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + for (int z = 0; z < kBlockSizeCount; z++) { + int gzip_buffer_size = kBlockSizes[z]; + int size; + { + ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); + GzipOutputStream::Options options; + options.format = GzipOutputStream::ZLIB; + if (gzip_buffer_size != -1) { + options.buffer_size = gzip_buffer_size; + } + GzipOutputStream gzout(&output, options); + WriteStuff(&gzout); + gzout.Close(); + size = output.ByteCount(); + } + { + ArrayInputStream input(buffer, size, kBlockSizes[j]); + GzipInputStream gzin( + &input, GzipInputStream::ZLIB, gzip_buffer_size); + ReadStuff(&gzin); + } + } + } + } + delete [] buffer; +} + +TEST_F(IoTest, ZlibIoInputAutodetect) { + const int kBufferSize = 2*1024; + uint8* buffer = new uint8[kBufferSize]; + int size; + { + ArrayOutputStream output(buffer, kBufferSize); + GzipOutputStream::Options options; + options.format = GzipOutputStream::ZLIB; + GzipOutputStream gzout(&output, options); + WriteStuff(&gzout); + gzout.Close(); + size = output.ByteCount(); + } + { + ArrayInputStream input(buffer, size); + GzipInputStream gzin(&input, GzipInputStream::AUTO); + ReadStuff(&gzin); + } + { + ArrayOutputStream output(buffer, kBufferSize); + GzipOutputStream::Options options; + options.format = GzipOutputStream::GZIP; + GzipOutputStream gzout(&output, options); + WriteStuff(&gzout); + gzout.Close(); + size = output.ByteCount(); + } + { + ArrayInputStream input(buffer, size); + GzipInputStream gzin(&input, GzipInputStream::AUTO); + ReadStuff(&gzin); + } + delete [] buffer; +} + +string IoTest::Compress(const string& data, + const GzipOutputStream::Options& options) { + string result; + { + StringOutputStream output(&result); + GzipOutputStream gzout(&output, options); + WriteToOutput(&gzout, data.data(), data.size()); + } + return result; +} + +string IoTest::Uncompress(const string& data) { + string result; + { + ArrayInputStream input(data.data(), data.size()); + GzipInputStream gzin(&input); + const void* buffer; + int size; + while (gzin.Next(&buffer, &size)) { + result.append(reinterpret_cast(buffer), size); + } + } + return result; +} + +TEST_F(IoTest, CompressionOptions) { + // Some ad-hoc testing of compression options. + + string golden; + File::ReadFileToStringOrDie( + TestSourceDir() + "/google/protobuf/testdata/golden_message", + &golden); + + GzipOutputStream::Options options; + string gzip_compressed = Compress(golden, options); + + options.compression_level = 0; + string not_compressed = Compress(golden, options); + + // Try zlib compression for fun. + options = GzipOutputStream::Options(); + options.format = GzipOutputStream::ZLIB; + string zlib_compressed = Compress(golden, options); + + // Uncompressed should be bigger than the original since it should have some + // sort of header. + EXPECT_GT(not_compressed.size(), golden.size()); + + // Higher compression levels should result in smaller sizes. + EXPECT_LT(zlib_compressed.size(), not_compressed.size()); + + // ZLIB format should differ from GZIP format. + EXPECT_TRUE(zlib_compressed != gzip_compressed); + + // Everything should decompress correctly. + EXPECT_TRUE(Uncompress(not_compressed) == golden); + EXPECT_TRUE(Uncompress(gzip_compressed) == golden); + EXPECT_TRUE(Uncompress(zlib_compressed) == golden); +} + +TEST_F(IoTest, TwoSessionWriteGzip) { + // Test that two concatenated gzip streams can be read correctly + + static const char* strA = "0123456789"; + static const char* strB = "QuickBrownFox"; + const int kBufferSize = 2*1024; + uint8* buffer = new uint8[kBufferSize]; + char* temp_buffer = new char[40]; + + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + ArrayOutputStream* output = + new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]); + GzipOutputStream* gzout = new GzipOutputStream(output); + CodedOutputStream* coded_output = new CodedOutputStream(gzout); + int32 outlen = strlen(strA) + 1; + coded_output->WriteVarint32(outlen); + coded_output->WriteRaw(strA, outlen); + delete coded_output; // flush + delete gzout; // flush + int64 pos = output->ByteCount(); + delete output; + output = new ArrayOutputStream( + buffer + pos, kBufferSize - pos, kBlockSizes[i]); + gzout = new GzipOutputStream(output); + coded_output = new CodedOutputStream(gzout); + outlen = strlen(strB) + 1; + coded_output->WriteVarint32(outlen); + coded_output->WriteRaw(strB, outlen); + delete coded_output; // flush + delete gzout; // flush + int64 size = pos + output->ByteCount(); + delete output; + + ArrayInputStream* input = + new ArrayInputStream(buffer, size, kBlockSizes[j]); + GzipInputStream* gzin = new GzipInputStream(input); + CodedInputStream* coded_input = new CodedInputStream(gzin); + uint32 insize; + EXPECT_TRUE(coded_input->ReadVarint32(&insize)); + EXPECT_EQ(strlen(strA) + 1, insize); + EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); + EXPECT_EQ(0, memcmp(temp_buffer, strA, insize)) + << "strA=" << strA << " in=" << temp_buffer; + + EXPECT_TRUE(coded_input->ReadVarint32(&insize)); + EXPECT_EQ(strlen(strB) + 1, insize); + EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); + EXPECT_EQ(0, memcmp(temp_buffer, strB, insize)) + << " out_block_size=" << kBlockSizes[i] + << " in_block_size=" << kBlockSizes[j] + << " pos=" << pos + << " size=" << size + << " strB=" << strB << " in=" << temp_buffer; + + delete coded_input; + delete gzin; + delete input; + } + } + + delete [] temp_buffer; + delete [] buffer; +} +#endif + +// There is no string input, only string output. Also, it doesn't support +// explicit block sizes. So, we'll only run one test and we'll use +// ArrayInput to read back the results. +TEST_F(IoTest, StringIo) { + string str; + { + StringOutputStream output(&str); + WriteStuff(&output); + } + { + ArrayInputStream input(str.data(), str.size()); + ReadStuff(&input); + } +} + + +// To test files, we create a temporary file, write, read, truncate, repeat. +TEST_F(IoTest, FileIo) { + string filename = TestTempDir() + "/zero_copy_stream_test_file"; + + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + // Make a temporary file. + int file = + open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777); + ASSERT_GE(file, 0); + + { + FileOutputStream output(file, kBlockSizes[i]); + WriteStuff(&output); + EXPECT_EQ(0, output.GetErrno()); + } + + // Rewind. + ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1); + + { + FileInputStream input(file, kBlockSizes[j]); + ReadStuff(&input); + EXPECT_EQ(0, input.GetErrno()); + } + + close(file); + } + } +} + +#if HAVE_ZLIB +TEST_F(IoTest, GzipFileIo) { + string filename = TestTempDir() + "/zero_copy_stream_test_file"; + + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + // Make a temporary file. + int file = + open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777); + ASSERT_GE(file, 0); + { + FileOutputStream output(file, kBlockSizes[i]); + GzipOutputStream gzout(&output); + WriteStuffLarge(&gzout); + gzout.Close(); + output.Flush(); + EXPECT_EQ(0, output.GetErrno()); + } + + // Rewind. + ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1); + + { + FileInputStream input(file, kBlockSizes[j]); + GzipInputStream gzin(&input); + ReadStuffLarge(&gzin); + EXPECT_EQ(0, input.GetErrno()); + } + + close(file); + } + } +} +#endif + +// MSVC raises various debugging exceptions if we try to use a file +// descriptor of -1, defeating our tests below. This class will disable +// these debug assertions while in scope. +class MsvcDebugDisabler { + public: +#if defined(_MSC_VER) && _MSC_VER >= 1400 + MsvcDebugDisabler() { + old_handler_ = _set_invalid_parameter_handler(MyHandler); + old_mode_ = _CrtSetReportMode(_CRT_ASSERT, 0); + } + ~MsvcDebugDisabler() { + old_handler_ = _set_invalid_parameter_handler(old_handler_); + old_mode_ = _CrtSetReportMode(_CRT_ASSERT, old_mode_); + } + + static void MyHandler(const wchar_t *expr, + const wchar_t *func, + const wchar_t *file, + unsigned int line, + uintptr_t pReserved) { + // do nothing + } + + _invalid_parameter_handler old_handler_; + int old_mode_; +#else + // Dummy constructor and destructor to ensure that GCC doesn't complain + // that debug_disabler is an unused variable. + MsvcDebugDisabler() {} + ~MsvcDebugDisabler() {} +#endif +}; + +// Test that FileInputStreams report errors correctly. +TEST_F(IoTest, FileReadError) { + MsvcDebugDisabler debug_disabler; + + // -1 = invalid file descriptor. + FileInputStream input(-1); + + const void* buffer; + int size; + EXPECT_FALSE(input.Next(&buffer, &size)); + EXPECT_EQ(EBADF, input.GetErrno()); +} + +// Test that FileOutputStreams report errors correctly. +TEST_F(IoTest, FileWriteError) { + MsvcDebugDisabler debug_disabler; + + // -1 = invalid file descriptor. + FileOutputStream input(-1); + + void* buffer; + int size; + + // The first call to Next() succeeds because it doesn't have anything to + // write yet. + EXPECT_TRUE(input.Next(&buffer, &size)); + + // Second call fails. + EXPECT_FALSE(input.Next(&buffer, &size)); + + EXPECT_EQ(EBADF, input.GetErrno()); +} + +// Pipes are not seekable, so File{Input,Output}Stream ends up doing some +// different things to handle them. We'll test by writing to a pipe and +// reading back from it. +TEST_F(IoTest, PipeIo) { + int files[2]; + + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + // Need to create a new pipe each time because ReadStuff() expects + // to see EOF at the end. + ASSERT_EQ(pipe(files), 0); + + { + FileOutputStream output(files[1], kBlockSizes[i]); + WriteStuff(&output); + EXPECT_EQ(0, output.GetErrno()); + } + close(files[1]); // Send EOF. + + { + FileInputStream input(files[0], kBlockSizes[j]); + ReadStuff(&input); + EXPECT_EQ(0, input.GetErrno()); + } + close(files[0]); + } + } +} + +// Test using C++ iostreams. +TEST_F(IoTest, IostreamIo) { + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + { + stringstream stream; + + { + OstreamOutputStream output(&stream, kBlockSizes[i]); + WriteStuff(&output); + EXPECT_FALSE(stream.fail()); + } + + { + IstreamInputStream input(&stream, kBlockSizes[j]); + ReadStuff(&input); + EXPECT_TRUE(stream.eof()); + } + } + + { + stringstream stream; + + { + OstreamOutputStream output(&stream, kBlockSizes[i]); + WriteStuffLarge(&output); + EXPECT_FALSE(stream.fail()); + } + + { + IstreamInputStream input(&stream, kBlockSizes[j]); + ReadStuffLarge(&input); + EXPECT_TRUE(stream.eof()); + } + } + } + } +} + +// To test ConcatenatingInputStream, we create several ArrayInputStreams +// covering a buffer and then concatenate them. +TEST_F(IoTest, ConcatenatingInputStream) { + const int kBufferSize = 256; + uint8 buffer[kBufferSize]; + + // Fill the buffer. + ArrayOutputStream output(buffer, kBufferSize); + WriteStuff(&output); + + // Now split it up into multiple streams of varying sizes. + ASSERT_EQ(68, output.ByteCount()); // Test depends on this. + ArrayInputStream input1(buffer , 12); + ArrayInputStream input2(buffer + 12, 7); + ArrayInputStream input3(buffer + 19, 6); + ArrayInputStream input4(buffer + 25, 15); + ArrayInputStream input5(buffer + 40, 0); + // Note: We want to make sure we have a stream boundary somewhere between + // bytes 42 and 62, which is the range that it Skip()ed by ReadStuff(). This + // tests that a bug that existed in the original code for Skip() is fixed. + ArrayInputStream input6(buffer + 40, 10); + ArrayInputStream input7(buffer + 50, 18); // Total = 68 bytes. + + ZeroCopyInputStream* streams[] = + {&input1, &input2, &input3, &input4, &input5, &input6, &input7}; + + // Create the concatenating stream and read. + ConcatenatingInputStream input(streams, GOOGLE_ARRAYSIZE(streams)); + ReadStuff(&input); +} + +// To test LimitingInputStream, we write our golden text to a buffer, then +// create an ArrayInputStream that contains the whole buffer (not just the +// bytes written), then use a LimitingInputStream to limit it just to the +// bytes written. +TEST_F(IoTest, LimitingInputStream) { + const int kBufferSize = 256; + uint8 buffer[kBufferSize]; + + // Fill the buffer. + ArrayOutputStream output(buffer, kBufferSize); + WriteStuff(&output); + + // Set up input. + ArrayInputStream array_input(buffer, kBufferSize); + LimitingInputStream input(&array_input, output.ByteCount()); + + ReadStuff(&input); +} + +// Check that a zero-size array doesn't confuse the code. +TEST(ZeroSizeArray, Input) { + ArrayInputStream input(NULL, 0); + const void* data; + int size; + EXPECT_FALSE(input.Next(&data, &size)); +} + +TEST(ZeroSizeArray, Output) { + ArrayOutputStream output(NULL, 0); + void* data; + int size; + EXPECT_FALSE(output.Next(&data, &size)); +} + +} // namespace +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/lite_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/lite_unittest.cc new file mode 100644 index 0000000..7a0a57b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/lite_unittest.cc @@ -0,0 +1,185 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include +#include + +#include +#include +#include + +using namespace std; + +namespace { +// Helper methods to test parsing merge behavior. +void ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite& message) { + GOOGLE_CHECK(message.optional_int32() == 3); + GOOGLE_CHECK(message.optional_int64() == 2); + GOOGLE_CHECK(message.optional_string() == "hello"); +} + +void AssignParsingMergeMessages( + google::protobuf::unittest::TestAllTypesLite* msg1, + google::protobuf::unittest::TestAllTypesLite* msg2, + google::protobuf::unittest::TestAllTypesLite* msg3) { + msg1->set_optional_int32(1); + msg2->set_optional_int64(2); + msg3->set_optional_int32(3); + msg3->set_optional_string("hello"); +} + +} // namespace + +int main(int argc, char* argv[]) { + string data, packed_data; + + { + protobuf_unittest::TestAllTypesLite message, message2, message3; + google::protobuf::TestUtilLite::ExpectClear(message); + google::protobuf::TestUtilLite::SetAllFields(&message); + message2.CopyFrom(message); + data = message.SerializeAsString(); + message3.ParseFromString(data); + google::protobuf::TestUtilLite::ExpectAllFieldsSet(message); + google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2); + google::protobuf::TestUtilLite::ExpectAllFieldsSet(message3); + google::protobuf::TestUtilLite::ModifyRepeatedFields(&message); + google::protobuf::TestUtilLite::ExpectRepeatedFieldsModified(message); + message.Clear(); + google::protobuf::TestUtilLite::ExpectClear(message); + } + + { + protobuf_unittest::TestAllExtensionsLite message, message2, message3; + google::protobuf::TestUtilLite::ExpectExtensionsClear(message); + google::protobuf::TestUtilLite::SetAllExtensions(&message); + message2.CopyFrom(message); + string extensions_data = message.SerializeAsString(); + GOOGLE_CHECK(extensions_data == data); + message3.ParseFromString(extensions_data); + google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message); + google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2); + google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message3); + google::protobuf::TestUtilLite::ModifyRepeatedExtensions(&message); + google::protobuf::TestUtilLite::ExpectRepeatedExtensionsModified(message); + message.Clear(); + google::protobuf::TestUtilLite::ExpectExtensionsClear(message); + } + + { + protobuf_unittest::TestPackedTypesLite message, message2, message3; + google::protobuf::TestUtilLite::ExpectPackedClear(message); + google::protobuf::TestUtilLite::SetPackedFields(&message); + message2.CopyFrom(message); + packed_data = message.SerializeAsString(); + message3.ParseFromString(packed_data); + google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message); + google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2); + google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message3); + google::protobuf::TestUtilLite::ModifyPackedFields(&message); + google::protobuf::TestUtilLite::ExpectPackedFieldsModified(message); + message.Clear(); + google::protobuf::TestUtilLite::ExpectPackedClear(message); + } + + { + protobuf_unittest::TestPackedExtensionsLite message, message2, message3; + google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); + google::protobuf::TestUtilLite::SetPackedExtensions(&message); + message2.CopyFrom(message); + string packed_extensions_data = message.SerializeAsString(); + GOOGLE_CHECK(packed_extensions_data == packed_data); + message3.ParseFromString(packed_extensions_data); + google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message); + google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2); + google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message3); + google::protobuf::TestUtilLite::ModifyPackedExtensions(&message); + google::protobuf::TestUtilLite::ExpectPackedExtensionsModified(message); + message.Clear(); + google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); + } + + { + // Test that if an optional or required message/group field appears multiple + // times in the input, they need to be merged. + google::protobuf::unittest::TestParsingMergeLite::RepeatedFieldsGenerator generator; + google::protobuf::unittest::TestAllTypesLite* msg1; + google::protobuf::unittest::TestAllTypesLite* msg2; + google::protobuf::unittest::TestAllTypesLite* msg3; + +#define ASSIGN_REPEATED_FIELD(FIELD) \ + msg1 = generator.add_##FIELD(); \ + msg2 = generator.add_##FIELD(); \ + msg3 = generator.add_##FIELD(); \ + AssignParsingMergeMessages(msg1, msg2, msg3) + + ASSIGN_REPEATED_FIELD(field1); + ASSIGN_REPEATED_FIELD(field2); + ASSIGN_REPEATED_FIELD(field3); + ASSIGN_REPEATED_FIELD(ext1); + ASSIGN_REPEATED_FIELD(ext2); + +#undef ASSIGN_REPEATED_FIELD +#define ASSIGN_REPEATED_GROUP(FIELD) \ + msg1 = generator.add_##FIELD()->mutable_field1(); \ + msg2 = generator.add_##FIELD()->mutable_field1(); \ + msg3 = generator.add_##FIELD()->mutable_field1(); \ + AssignParsingMergeMessages(msg1, msg2, msg3) + + ASSIGN_REPEATED_GROUP(group1); + ASSIGN_REPEATED_GROUP(group2); + +#undef ASSIGN_REPEATED_GROUP + + string buffer; + generator.SerializeToString(&buffer); + google::protobuf::unittest::TestParsingMergeLite parsing_merge; + parsing_merge.ParseFromString(buffer); + + // Required and optional fields should be merged. + ExpectMessageMerged(parsing_merge.required_all_types()); + ExpectMessageMerged(parsing_merge.optional_all_types()); + ExpectMessageMerged( + parsing_merge.optionalgroup().optional_group_all_types()); + ExpectMessageMerged(parsing_merge.GetExtension( + google::protobuf::unittest::TestParsingMergeLite::optional_ext)); + + // Repeated fields should not be merged. + GOOGLE_CHECK(parsing_merge.repeated_all_types_size() == 3); + GOOGLE_CHECK(parsing_merge.repeatedgroup_size() == 3); + GOOGLE_CHECK(parsing_merge.ExtensionSize( + google::protobuf::unittest::TestParsingMergeLite::repeated_ext) == 3); + } + + cout << "PASS" << endl; + return 0; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message.cc new file mode 100644 index 0000000..ab7efa9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message.cc @@ -0,0 +1,358 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +using internal::WireFormat; +using internal::ReflectionOps; + +Message::~Message() {} + +void Message::MergeFrom(const Message& from) { + const Descriptor* descriptor = GetDescriptor(); + GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor) + << ": Tried to merge from a message with a different type. " + "to: " << descriptor->full_name() << ", " + "from:" << from.GetDescriptor()->full_name(); + ReflectionOps::Merge(from, this); +} + +void Message::CheckTypeAndMergeFrom(const MessageLite& other) { + MergeFrom(*down_cast(&other)); +} + +void Message::CopyFrom(const Message& from) { + const Descriptor* descriptor = GetDescriptor(); + GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor) + << ": Tried to copy from a message with a different type." + "to: " << descriptor->full_name() << ", " + "from:" << from.GetDescriptor()->full_name(); + ReflectionOps::Copy(from, this); +} + +string Message::GetTypeName() const { + return GetDescriptor()->full_name(); +} + +void Message::Clear() { + ReflectionOps::Clear(this); +} + +bool Message::IsInitialized() const { + return ReflectionOps::IsInitialized(*this); +} + +void Message::FindInitializationErrors(vector* errors) const { + return ReflectionOps::FindInitializationErrors(*this, "", errors); +} + +string Message::InitializationErrorString() const { + vector errors; + FindInitializationErrors(&errors); + return JoinStrings(errors, ", "); +} + +void Message::CheckInitialized() const { + GOOGLE_CHECK(IsInitialized()) + << "Message of type \"" << GetDescriptor()->full_name() + << "\" is missing required fields: " << InitializationErrorString(); +} + +void Message::DiscardUnknownFields() { + return ReflectionOps::DiscardUnknownFields(this); +} + +bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) { + return WireFormat::ParseAndMergePartial(input, this); +} + +bool Message::ParseFromFileDescriptor(int file_descriptor) { + io::FileInputStream input(file_descriptor); + return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0; +} + +bool Message::ParsePartialFromFileDescriptor(int file_descriptor) { + io::FileInputStream input(file_descriptor); + return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0; +} + +bool Message::ParseFromIstream(istream* input) { + io::IstreamInputStream zero_copy_input(input); + return ParseFromZeroCopyStream(&zero_copy_input) && input->eof(); +} + +bool Message::ParsePartialFromIstream(istream* input) { + io::IstreamInputStream zero_copy_input(input); + return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof(); +} + + +void Message::SerializeWithCachedSizes( + io::CodedOutputStream* output) const { + WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output); +} + +int Message::ByteSize() const { + int size = WireFormat::ByteSize(*this); + SetCachedSize(size); + return size; +} + +void Message::SetCachedSize(int size) const { + GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name() + << "\" implements neither SetCachedSize() nor ByteSize(). " + "Must implement one or the other."; +} + +int Message::SpaceUsed() const { + return GetReflection()->SpaceUsed(*this); +} + +bool Message::SerializeToFileDescriptor(int file_descriptor) const { + io::FileOutputStream output(file_descriptor); + return SerializeToZeroCopyStream(&output); +} + +bool Message::SerializePartialToFileDescriptor(int file_descriptor) const { + io::FileOutputStream output(file_descriptor); + return SerializePartialToZeroCopyStream(&output); +} + +bool Message::SerializeToOstream(ostream* output) const { + { + io::OstreamOutputStream zero_copy_output(output); + if (!SerializeToZeroCopyStream(&zero_copy_output)) return false; + } + return output->good(); +} + +bool Message::SerializePartialToOstream(ostream* output) const { + io::OstreamOutputStream zero_copy_output(output); + return SerializePartialToZeroCopyStream(&zero_copy_output); +} + + +// ============================================================================= +// Reflection and associated Template Specializations + +Reflection::~Reflection() {} + +#define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE) \ +template<> \ +const RepeatedField& Reflection::GetRepeatedField( \ + const Message& message, const FieldDescriptor* field) const { \ + return *static_cast* >( \ + MutableRawRepeatedField(const_cast(&message), \ + field, CPPTYPE, CTYPE, NULL)); \ +} \ + \ +template<> \ +RepeatedField* Reflection::MutableRepeatedField( \ + Message* message, const FieldDescriptor* field) const { \ + return static_cast* >( \ + MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \ +} + +HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1); +HANDLE_TYPE(int64, FieldDescriptor::CPPTYPE_INT64, -1); +HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1); +HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1); +HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1); +HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1); +HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1); + + +#undef HANDLE_TYPE + +void* Reflection::MutableRawRepeatedString( + Message* message, const FieldDescriptor* field, bool is_string) const { + return MutableRawRepeatedField(message, field, + FieldDescriptor::CPPTYPE_STRING, FieldOptions::STRING, NULL); +} + + +// ============================================================================= +// MessageFactory + +MessageFactory::~MessageFactory() {} + +namespace { + +class GeneratedMessageFactory : public MessageFactory { + public: + GeneratedMessageFactory(); + ~GeneratedMessageFactory(); + + static GeneratedMessageFactory* singleton(); + + typedef void RegistrationFunc(const string&); + void RegisterFile(const char* file, RegistrationFunc* registration_func); + void RegisterType(const Descriptor* descriptor, const Message* prototype); + + // implements MessageFactory --------------------------------------- + const Message* GetPrototype(const Descriptor* type); + + private: + // Only written at static init time, so does not require locking. + hash_map, streq> file_map_; + + // Initialized lazily, so requires locking. + Mutex mutex_; + hash_map type_map_; +}; + +GeneratedMessageFactory* generated_message_factory_ = NULL; +GOOGLE_PROTOBUF_DECLARE_ONCE(generated_message_factory_once_init_); + +void ShutdownGeneratedMessageFactory() { + delete generated_message_factory_; +} + +void InitGeneratedMessageFactory() { + generated_message_factory_ = new GeneratedMessageFactory; + internal::OnShutdown(&ShutdownGeneratedMessageFactory); +} + +GeneratedMessageFactory::GeneratedMessageFactory() {} +GeneratedMessageFactory::~GeneratedMessageFactory() {} + +GeneratedMessageFactory* GeneratedMessageFactory::singleton() { + ::google::protobuf::GoogleOnceInit(&generated_message_factory_once_init_, + &InitGeneratedMessageFactory); + return generated_message_factory_; +} + +void GeneratedMessageFactory::RegisterFile( + const char* file, RegistrationFunc* registration_func) { + if (!InsertIfNotPresent(&file_map_, file, registration_func)) { + GOOGLE_LOG(FATAL) << "File is already registered: " << file; + } +} + +void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor, + const Message* prototype) { + GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool()) + << "Tried to register a non-generated type with the generated " + "type registry."; + + // This should only be called as a result of calling a file registration + // function during GetPrototype(), in which case we already have locked + // the mutex. + mutex_.AssertHeld(); + if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) { + GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name(); + } +} + + +const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) { + { + ReaderMutexLock lock(&mutex_); + const Message* result = FindPtrOrNull(type_map_, type); + if (result != NULL) return result; + } + + // If the type is not in the generated pool, then we can't possibly handle + // it. + if (type->file()->pool() != DescriptorPool::generated_pool()) return NULL; + + // Apparently the file hasn't been registered yet. Let's do that now. + RegistrationFunc* registration_func = + FindPtrOrNull(file_map_, type->file()->name().c_str()); + if (registration_func == NULL) { + GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't " + "registered: " << type->file()->name(); + return NULL; + } + + WriterMutexLock lock(&mutex_); + + // Check if another thread preempted us. + const Message* result = FindPtrOrNull(type_map_, type); + if (result == NULL) { + // Nope. OK, register everything. + registration_func(type->file()->name()); + // Should be here now. + result = FindPtrOrNull(type_map_, type); + } + + if (result == NULL) { + GOOGLE_LOG(DFATAL) << "Type appears to be in generated pool but wasn't " + << "registered: " << type->full_name(); + } + + return result; +} + +} // namespace + +MessageFactory* MessageFactory::generated_factory() { + return GeneratedMessageFactory::singleton(); +} + +void MessageFactory::InternalRegisterGeneratedFile( + const char* filename, void (*register_messages)(const string&)) { + GeneratedMessageFactory::singleton()->RegisterFile(filename, + register_messages); +} + +void MessageFactory::InternalRegisterGeneratedMessage( + const Descriptor* descriptor, const Message* prototype) { + GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype); +} + + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message.h new file mode 100644 index 0000000..0f90bc1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message.h @@ -0,0 +1,837 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Defines Message, the abstract interface implemented by non-lite +// protocol message objects. Although it's possible to implement this +// interface manually, most users will use the protocol compiler to +// generate implementations. +// +// Example usage: +// +// Say you have a message defined as: +// +// message Foo { +// optional string text = 1; +// repeated int32 numbers = 2; +// } +// +// Then, if you used the protocol compiler to generate a class from the above +// definition, you could use it like so: +// +// string data; // Will store a serialized version of the message. +// +// { +// // Create a message and serialize it. +// Foo foo; +// foo.set_text("Hello World!"); +// foo.add_numbers(1); +// foo.add_numbers(5); +// foo.add_numbers(42); +// +// foo.SerializeToString(&data); +// } +// +// { +// // Parse the serialized message and check that it contains the +// // correct data. +// Foo foo; +// foo.ParseFromString(data); +// +// assert(foo.text() == "Hello World!"); +// assert(foo.numbers_size() == 3); +// assert(foo.numbers(0) == 1); +// assert(foo.numbers(1) == 5); +// assert(foo.numbers(2) == 42); +// } +// +// { +// // Same as the last block, but do it dynamically via the Message +// // reflection interface. +// Message* foo = new Foo; +// const Descriptor* descriptor = foo->GetDescriptor(); +// +// // Get the descriptors for the fields we're interested in and verify +// // their types. +// const FieldDescriptor* text_field = descriptor->FindFieldByName("text"); +// assert(text_field != NULL); +// assert(text_field->type() == FieldDescriptor::TYPE_STRING); +// assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL); +// const FieldDescriptor* numbers_field = descriptor-> +// FindFieldByName("numbers"); +// assert(numbers_field != NULL); +// assert(numbers_field->type() == FieldDescriptor::TYPE_INT32); +// assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED); +// +// // Parse the message. +// foo->ParseFromString(data); +// +// // Use the reflection interface to examine the contents. +// const Reflection* reflection = foo->GetReflection(); +// assert(reflection->GetString(foo, text_field) == "Hello World!"); +// assert(reflection->FieldSize(foo, numbers_field) == 3); +// assert(reflection->GetRepeatedInt32(foo, numbers_field, 0) == 1); +// assert(reflection->GetRepeatedInt32(foo, numbers_field, 1) == 5); +// assert(reflection->GetRepeatedInt32(foo, numbers_field, 2) == 42); +// +// delete foo; +// } + +#ifndef GOOGLE_PROTOBUF_MESSAGE_H__ +#define GOOGLE_PROTOBUF_MESSAGE_H__ + +#include +#include + +#ifdef __DECCXX +// HP C++'s iosfwd doesn't work. +#include +#else +#include +#endif + +#include + +#include +#include + + +namespace google { +namespace protobuf { + +// Defined in this file. +class Message; +class Reflection; +class MessageFactory; + +// Defined in other files. +class UnknownFieldSet; // unknown_field_set.h +namespace io { + class ZeroCopyInputStream; // zero_copy_stream.h + class ZeroCopyOutputStream; // zero_copy_stream.h + class CodedInputStream; // coded_stream.h + class CodedOutputStream; // coded_stream.h +} + + +template +class RepeatedField; // repeated_field.h + +template +class RepeatedPtrField; // repeated_field.h + +// A container to hold message metadata. +struct Metadata { + const Descriptor* descriptor; + const Reflection* reflection; +}; + +// Abstract interface for protocol messages. +// +// See also MessageLite, which contains most every-day operations. Message +// adds descriptors and reflection on top of that. +// +// The methods of this class that are virtual but not pure-virtual have +// default implementations based on reflection. Message classes which are +// optimized for speed will want to override these with faster implementations, +// but classes optimized for code size may be happy with keeping them. See +// the optimize_for option in descriptor.proto. +class LIBPROTOBUF_EXPORT Message : public MessageLite { + public: + inline Message() {} + virtual ~Message(); + + // Basic Operations ------------------------------------------------ + + // Construct a new instance of the same type. Ownership is passed to the + // caller. (This is also defined in MessageLite, but is defined again here + // for return-type covariance.) + virtual Message* New() const = 0; + + // Make this message into a copy of the given message. The given message + // must have the same descriptor, but need not necessarily be the same class. + // By default this is just implemented as "Clear(); MergeFrom(from);". + virtual void CopyFrom(const Message& from); + + // Merge the fields from the given message into this message. Singular + // fields will be overwritten, except for embedded messages which will + // be merged. Repeated fields will be concatenated. The given message + // must be of the same type as this message (i.e. the exact same class). + virtual void MergeFrom(const Message& from); + + // Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with + // a nice error message. + void CheckInitialized() const; + + // Slowly build a list of all required fields that are not set. + // This is much, much slower than IsInitialized() as it is implemented + // purely via reflection. Generally, you should not call this unless you + // have already determined that an error exists by calling IsInitialized(). + void FindInitializationErrors(vector* errors) const; + + // Like FindInitializationErrors, but joins all the strings, delimited by + // commas, and returns them. + string InitializationErrorString() const; + + // Clears all unknown fields from this message and all embedded messages. + // Normally, if unknown tag numbers are encountered when parsing a message, + // the tag and value are stored in the message's UnknownFieldSet and + // then written back out when the message is serialized. This allows servers + // which simply route messages to other servers to pass through messages + // that have new field definitions which they don't yet know about. However, + // this behavior can have security implications. To avoid it, call this + // method after parsing. + // + // See Reflection::GetUnknownFields() for more on unknown fields. + virtual void DiscardUnknownFields(); + + // Computes (an estimate of) the total number of bytes currently used for + // storing the message in memory. The default implementation calls the + // Reflection object's SpaceUsed() method. + virtual int SpaceUsed() const; + + // Debugging & Testing---------------------------------------------- + + // Generates a human readable form of this message, useful for debugging + // and other purposes. + string DebugString() const; + // Like DebugString(), but with less whitespace. + string ShortDebugString() const; + // Like DebugString(), but do not escape UTF-8 byte sequences. + string Utf8DebugString() const; + // Convenience function useful in GDB. Prints DebugString() to stdout. + void PrintDebugString() const; + + // Heavy I/O ------------------------------------------------------- + // Additional parsing and serialization methods not implemented by + // MessageLite because they are not supported by the lite library. + + // Parse a protocol buffer from a file descriptor. If successful, the entire + // input will be consumed. + bool ParseFromFileDescriptor(int file_descriptor); + // Like ParseFromFileDescriptor(), but accepts messages that are missing + // required fields. + bool ParsePartialFromFileDescriptor(int file_descriptor); + // Parse a protocol buffer from a C++ istream. If successful, the entire + // input will be consumed. + bool ParseFromIstream(istream* input); + // Like ParseFromIstream(), but accepts messages that are missing + // required fields. + bool ParsePartialFromIstream(istream* input); + + // Serialize the message and write it to the given file descriptor. All + // required fields must be set. + bool SerializeToFileDescriptor(int file_descriptor) const; + // Like SerializeToFileDescriptor(), but allows missing required fields. + bool SerializePartialToFileDescriptor(int file_descriptor) const; + // Serialize the message and write it to the given C++ ostream. All + // required fields must be set. + bool SerializeToOstream(ostream* output) const; + // Like SerializeToOstream(), but allows missing required fields. + bool SerializePartialToOstream(ostream* output) const; + + + // Reflection-based methods ---------------------------------------- + // These methods are pure-virtual in MessageLite, but Message provides + // reflection-based default implementations. + + virtual string GetTypeName() const; + virtual void Clear(); + virtual bool IsInitialized() const; + virtual void CheckTypeAndMergeFrom(const MessageLite& other); + virtual bool MergePartialFromCodedStream(io::CodedInputStream* input); + virtual int ByteSize() const; + virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const; + + private: + // This is called only by the default implementation of ByteSize(), to + // update the cached size. If you override ByteSize(), you do not need + // to override this. If you do not override ByteSize(), you MUST override + // this; the default implementation will crash. + // + // The method is private because subclasses should never call it; only + // override it. Yes, C++ lets you do that. Crazy, huh? + virtual void SetCachedSize(int size) const; + + public: + + // Introspection --------------------------------------------------- + + // Typedef for backwards-compatibility. + typedef google::protobuf::Reflection Reflection; + + // Get a Descriptor for this message's type. This describes what + // fields the message contains, the types of those fields, etc. + const Descriptor* GetDescriptor() const { return GetMetadata().descriptor; } + + // Get the Reflection interface for this Message, which can be used to + // read and modify the fields of the Message dynamically (in other words, + // without knowing the message type at compile time). This object remains + // property of the Message. + // + // This method remains virtual in case a subclass does not implement + // reflection and wants to override the default behavior. + virtual const Reflection* GetReflection() const { + return GetMetadata().reflection; + } + + protected: + // Get a struct containing the metadata for the Message. Most subclasses only + // need to implement this method, rather than the GetDescriptor() and + // GetReflection() wrappers. + virtual Metadata GetMetadata() const = 0; + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); +}; + +// This interface contains methods that can be used to dynamically access +// and modify the fields of a protocol message. Their semantics are +// similar to the accessors the protocol compiler generates. +// +// To get the Reflection for a given Message, call Message::GetReflection(). +// +// This interface is separate from Message only for efficiency reasons; +// the vast majority of implementations of Message will share the same +// implementation of Reflection (GeneratedMessageReflection, +// defined in generated_message.h), and all Messages of a particular class +// should share the same Reflection object (though you should not rely on +// the latter fact). +// +// There are several ways that these methods can be used incorrectly. For +// example, any of the following conditions will lead to undefined +// results (probably assertion failures): +// - The FieldDescriptor is not a field of this message type. +// - The method called is not appropriate for the field's type. For +// each field type in FieldDescriptor::TYPE_*, there is only one +// Get*() method, one Set*() method, and one Add*() method that is +// valid for that type. It should be obvious which (except maybe +// for TYPE_BYTES, which are represented using strings in C++). +// - A Get*() or Set*() method for singular fields is called on a repeated +// field. +// - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated +// field. +// - The Message object passed to any method is not of the right type for +// this Reflection object (i.e. message.GetReflection() != reflection). +// +// You might wonder why there is not any abstract representation for a field +// of arbitrary type. E.g., why isn't there just a "GetField()" method that +// returns "const Field&", where "Field" is some class with accessors like +// "GetInt32Value()". The problem is that someone would have to deal with +// allocating these Field objects. For generated message classes, having to +// allocate space for an additional object to wrap every field would at least +// double the message's memory footprint, probably worse. Allocating the +// objects on-demand, on the other hand, would be expensive and prone to +// memory leaks. So, instead we ended up with this flat interface. +// +// TODO(kenton): Create a utility class which callers can use to read and +// write fields from a Reflection without paying attention to the type. +class LIBPROTOBUF_EXPORT Reflection { + public: + inline Reflection() {} + virtual ~Reflection(); + + // Get the UnknownFieldSet for the message. This contains fields which + // were seen when the Message was parsed but were not recognized according + // to the Message's definition. + virtual const UnknownFieldSet& GetUnknownFields( + const Message& message) const = 0; + // Get a mutable pointer to the UnknownFieldSet for the message. This + // contains fields which were seen when the Message was parsed but were not + // recognized according to the Message's definition. + virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0; + + // Estimate the amount of memory used by the message object. + virtual int SpaceUsed(const Message& message) const = 0; + + // Check if the given non-repeated field is set. + virtual bool HasField(const Message& message, + const FieldDescriptor* field) const = 0; + + // Get the number of elements of a repeated field. + virtual int FieldSize(const Message& message, + const FieldDescriptor* field) const = 0; + + // Clear the value of a field, so that HasField() returns false or + // FieldSize() returns zero. + virtual void ClearField(Message* message, + const FieldDescriptor* field) const = 0; + + // Removes the last element of a repeated field. + // We don't provide a way to remove any element other than the last + // because it invites inefficient use, such as O(n^2) filtering loops + // that should have been O(n). If you want to remove an element other + // than the last, the best way to do it is to re-arrange the elements + // (using Swap()) so that the one you want removed is at the end, then + // call RemoveLast(). + virtual void RemoveLast(Message* message, + const FieldDescriptor* field) const = 0; + // Removes the last element of a repeated message field, and returns the + // pointer to the caller. Caller takes ownership of the returned pointer. + virtual Message* ReleaseLast(Message* message, + const FieldDescriptor* field) const = 0; + + // Swap the complete contents of two messages. + virtual void Swap(Message* message1, Message* message2) const = 0; + + // Swap two elements of a repeated field. + virtual void SwapElements(Message* message, + const FieldDescriptor* field, + int index1, + int index2) const = 0; + + // List all fields of the message which are currently set. This includes + // extensions. Singular fields will only be listed if HasField(field) would + // return true and repeated fields will only be listed if FieldSize(field) + // would return non-zero. Fields (both normal fields and extension fields) + // will be listed ordered by field number. + virtual void ListFields(const Message& message, + vector* output) const = 0; + + // Singular field getters ------------------------------------------ + // These get the value of a non-repeated field. They return the default + // value for fields that aren't set. + + virtual int32 GetInt32 (const Message& message, + const FieldDescriptor* field) const = 0; + virtual int64 GetInt64 (const Message& message, + const FieldDescriptor* field) const = 0; + virtual uint32 GetUInt32(const Message& message, + const FieldDescriptor* field) const = 0; + virtual uint64 GetUInt64(const Message& message, + const FieldDescriptor* field) const = 0; + virtual float GetFloat (const Message& message, + const FieldDescriptor* field) const = 0; + virtual double GetDouble(const Message& message, + const FieldDescriptor* field) const = 0; + virtual bool GetBool (const Message& message, + const FieldDescriptor* field) const = 0; + virtual string GetString(const Message& message, + const FieldDescriptor* field) const = 0; + virtual const EnumValueDescriptor* GetEnum( + const Message& message, const FieldDescriptor* field) const = 0; + // See MutableMessage() for the meaning of the "factory" parameter. + virtual const Message& GetMessage(const Message& message, + const FieldDescriptor* field, + MessageFactory* factory = NULL) const = 0; + + // Get a string value without copying, if possible. + // + // GetString() necessarily returns a copy of the string. This can be + // inefficient when the string is already stored in a string object in the + // underlying message. GetStringReference() will return a reference to the + // underlying string in this case. Otherwise, it will copy the string into + // *scratch and return that. + // + // Note: It is perfectly reasonable and useful to write code like: + // str = reflection->GetStringReference(field, &str); + // This line would ensure that only one copy of the string is made + // regardless of the field's underlying representation. When initializing + // a newly-constructed string, though, it's just as fast and more readable + // to use code like: + // string str = reflection->GetString(field); + virtual const string& GetStringReference(const Message& message, + const FieldDescriptor* field, + string* scratch) const = 0; + + + // Singular field mutators ----------------------------------------- + // These mutate the value of a non-repeated field. + + virtual void SetInt32 (Message* message, + const FieldDescriptor* field, int32 value) const = 0; + virtual void SetInt64 (Message* message, + const FieldDescriptor* field, int64 value) const = 0; + virtual void SetUInt32(Message* message, + const FieldDescriptor* field, uint32 value) const = 0; + virtual void SetUInt64(Message* message, + const FieldDescriptor* field, uint64 value) const = 0; + virtual void SetFloat (Message* message, + const FieldDescriptor* field, float value) const = 0; + virtual void SetDouble(Message* message, + const FieldDescriptor* field, double value) const = 0; + virtual void SetBool (Message* message, + const FieldDescriptor* field, bool value) const = 0; + virtual void SetString(Message* message, + const FieldDescriptor* field, + const string& value) const = 0; + virtual void SetEnum (Message* message, + const FieldDescriptor* field, + const EnumValueDescriptor* value) const = 0; + // Get a mutable pointer to a field with a message type. If a MessageFactory + // is provided, it will be used to construct instances of the sub-message; + // otherwise, the default factory is used. If the field is an extension that + // does not live in the same pool as the containing message's descriptor (e.g. + // it lives in an overlay pool), then a MessageFactory must be provided. + // If you have no idea what that meant, then you probably don't need to worry + // about it (don't provide a MessageFactory). WARNING: If the + // FieldDescriptor is for a compiled-in extension, then + // factory->GetPrototype(field->message_type() MUST return an instance of the + // compiled-in class for this type, NOT DynamicMessage. + virtual Message* MutableMessage(Message* message, + const FieldDescriptor* field, + MessageFactory* factory = NULL) const = 0; + // Releases the message specified by 'field' and returns the pointer, + // ReleaseMessage() will return the message the message object if it exists. + // Otherwise, it may or may not return NULL. In any case, if the return value + // is non-NULL, the caller takes ownership of the pointer. + // If the field existed (HasField() is true), then the returned pointer will + // be the same as the pointer returned by MutableMessage(). + // This function has the same effect as ClearField(). + virtual Message* ReleaseMessage(Message* message, + const FieldDescriptor* field, + MessageFactory* factory = NULL) const = 0; + + + // Repeated field getters ------------------------------------------ + // These get the value of one element of a repeated field. + + virtual int32 GetRepeatedInt32 (const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual int64 GetRepeatedInt64 (const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual uint32 GetRepeatedUInt32(const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual uint64 GetRepeatedUInt64(const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual float GetRepeatedFloat (const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual double GetRepeatedDouble(const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual bool GetRepeatedBool (const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual string GetRepeatedString(const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual const EnumValueDescriptor* GetRepeatedEnum( + const Message& message, + const FieldDescriptor* field, int index) const = 0; + virtual const Message& GetRepeatedMessage( + const Message& message, + const FieldDescriptor* field, int index) const = 0; + + // See GetStringReference(), above. + virtual const string& GetRepeatedStringReference( + const Message& message, const FieldDescriptor* field, + int index, string* scratch) const = 0; + + + // Repeated field mutators ----------------------------------------- + // These mutate the value of one element of a repeated field. + + virtual void SetRepeatedInt32 (Message* message, + const FieldDescriptor* field, + int index, int32 value) const = 0; + virtual void SetRepeatedInt64 (Message* message, + const FieldDescriptor* field, + int index, int64 value) const = 0; + virtual void SetRepeatedUInt32(Message* message, + const FieldDescriptor* field, + int index, uint32 value) const = 0; + virtual void SetRepeatedUInt64(Message* message, + const FieldDescriptor* field, + int index, uint64 value) const = 0; + virtual void SetRepeatedFloat (Message* message, + const FieldDescriptor* field, + int index, float value) const = 0; + virtual void SetRepeatedDouble(Message* message, + const FieldDescriptor* field, + int index, double value) const = 0; + virtual void SetRepeatedBool (Message* message, + const FieldDescriptor* field, + int index, bool value) const = 0; + virtual void SetRepeatedString(Message* message, + const FieldDescriptor* field, + int index, const string& value) const = 0; + virtual void SetRepeatedEnum(Message* message, + const FieldDescriptor* field, int index, + const EnumValueDescriptor* value) const = 0; + // Get a mutable pointer to an element of a repeated field with a message + // type. + virtual Message* MutableRepeatedMessage( + Message* message, const FieldDescriptor* field, int index) const = 0; + + + // Repeated field adders ------------------------------------------- + // These add an element to a repeated field. + + virtual void AddInt32 (Message* message, + const FieldDescriptor* field, int32 value) const = 0; + virtual void AddInt64 (Message* message, + const FieldDescriptor* field, int64 value) const = 0; + virtual void AddUInt32(Message* message, + const FieldDescriptor* field, uint32 value) const = 0; + virtual void AddUInt64(Message* message, + const FieldDescriptor* field, uint64 value) const = 0; + virtual void AddFloat (Message* message, + const FieldDescriptor* field, float value) const = 0; + virtual void AddDouble(Message* message, + const FieldDescriptor* field, double value) const = 0; + virtual void AddBool (Message* message, + const FieldDescriptor* field, bool value) const = 0; + virtual void AddString(Message* message, + const FieldDescriptor* field, + const string& value) const = 0; + virtual void AddEnum (Message* message, + const FieldDescriptor* field, + const EnumValueDescriptor* value) const = 0; + // See MutableMessage() for comments on the "factory" parameter. + virtual Message* AddMessage(Message* message, + const FieldDescriptor* field, + MessageFactory* factory = NULL) const = 0; + + + // Repeated field accessors ------------------------------------------------- + // The methods above, e.g. GetRepeatedInt32(msg, fd, index), provide singular + // access to the data in a RepeatedField. The methods below provide aggregate + // access by exposing the RepeatedField object itself with the Message. + // Applying these templates to inappropriate types will lead to an undefined + // reference at link time (e.g. GetRepeatedField<***double>), or possibly a + // template matching error at compile time (e.g. GetRepeatedPtrField). + // + // Usage example: my_doubs = refl->GetRepeatedField(msg, fd); + + // for T = Cord and all protobuf scalar types except enums. + template + const RepeatedField& GetRepeatedField( + const Message&, const FieldDescriptor*) const; + + // for T = Cord and all protobuf scalar types except enums. + template + RepeatedField* MutableRepeatedField( + Message*, const FieldDescriptor*) const; + + // for T = string, google::protobuf::internal::StringPieceField + // google::protobuf::Message & descendants. + template + const RepeatedPtrField& GetRepeatedPtrField( + const Message&, const FieldDescriptor*) const; + + // for T = string, google::protobuf::internal::StringPieceField + // google::protobuf::Message & descendants. + template + RepeatedPtrField* MutableRepeatedPtrField( + Message*, const FieldDescriptor*) const; + + // Extensions ---------------------------------------------------------------- + + // Try to find an extension of this message type by fully-qualified field + // name. Returns NULL if no extension is known for this name or number. + virtual const FieldDescriptor* FindKnownExtensionByName( + const string& name) const = 0; + + // Try to find an extension of this message type by field number. + // Returns NULL if no extension is known for this name or number. + virtual const FieldDescriptor* FindKnownExtensionByNumber( + int number) const = 0; + + // --------------------------------------------------------------------------- + + protected: + // Obtain a pointer to a Repeated Field Structure and do some type checking: + // on field->cpp_type(), + // on field->field_option().ctype() (if ctype >= 0) + // of field->message_type() (if message_type != NULL). + // We use 1 routine rather than 4 (const vs mutable) x (scalar vs pointer). + virtual void* MutableRawRepeatedField( + Message* message, const FieldDescriptor* field, FieldDescriptor::CppType, + int ctype, const Descriptor* message_type) const = 0; + + private: + // Special version for specialized implementations of string. We can't call + // MutableRawRepeatedField directly here because we don't have access to + // FieldOptions::* which are defined in descriptor.pb.h. Including that + // file here is not possible because it would cause a circular include cycle. + void* MutableRawRepeatedString( + Message* message, const FieldDescriptor* field, bool is_string) const; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection); +}; + +// Abstract interface for a factory for message objects. +class LIBPROTOBUF_EXPORT MessageFactory { + public: + inline MessageFactory() {} + virtual ~MessageFactory(); + + // Given a Descriptor, gets or constructs the default (prototype) Message + // of that type. You can then call that message's New() method to construct + // a mutable message of that type. + // + // Calling this method twice with the same Descriptor returns the same + // object. The returned object remains property of the factory. Also, any + // objects created by calling the prototype's New() method share some data + // with the prototype, so these must be destoyed before the MessageFactory + // is destroyed. + // + // The given descriptor must outlive the returned message, and hence must + // outlive the MessageFactory. + // + // Some implementations do not support all types. GetPrototype() will + // return NULL if the descriptor passed in is not supported. + // + // This method may or may not be thread-safe depending on the implementation. + // Each implementation should document its own degree thread-safety. + virtual const Message* GetPrototype(const Descriptor* type) = 0; + + // Gets a MessageFactory which supports all generated, compiled-in messages. + // In other words, for any compiled-in type FooMessage, the following is true: + // MessageFactory::generated_factory()->GetPrototype( + // FooMessage::descriptor()) == FooMessage::default_instance() + // This factory supports all types which are found in + // DescriptorPool::generated_pool(). If given a descriptor from any other + // pool, GetPrototype() will return NULL. (You can also check if a + // descriptor is for a generated message by checking if + // descriptor->file()->pool() == DescriptorPool::generated_pool().) + // + // This factory is 100% thread-safe; calling GetPrototype() does not modify + // any shared data. + // + // This factory is a singleton. The caller must not delete the object. + static MessageFactory* generated_factory(); + + // For internal use only: Registers a .proto file at static initialization + // time, to be placed in generated_factory. The first time GetPrototype() + // is called with a descriptor from this file, |register_messages| will be + // called, with the file name as the parameter. It must call + // InternalRegisterGeneratedMessage() (below) to register each message type + // in the file. This strange mechanism is necessary because descriptors are + // built lazily, so we can't register types by their descriptor until we + // know that the descriptor exists. |filename| must be a permanent string. + static void InternalRegisterGeneratedFile( + const char* filename, void (*register_messages)(const string&)); + + // For internal use only: Registers a message type. Called only by the + // functions which are registered with InternalRegisterGeneratedFile(), + // above. + static void InternalRegisterGeneratedMessage(const Descriptor* descriptor, + const Message* prototype); + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory); +}; + +#define DECLARE_GET_REPEATED_FIELD(TYPE) \ +template<> \ +LIBPROTOBUF_EXPORT \ +const RepeatedField& Reflection::GetRepeatedField( \ + const Message& message, const FieldDescriptor* field) const; \ + \ +template<> \ +LIBPROTOBUF_EXPORT \ +RepeatedField* Reflection::MutableRepeatedField( \ + Message* message, const FieldDescriptor* field) const; + +DECLARE_GET_REPEATED_FIELD(int32) +DECLARE_GET_REPEATED_FIELD(int64) +DECLARE_GET_REPEATED_FIELD(uint32) +DECLARE_GET_REPEATED_FIELD(uint64) +DECLARE_GET_REPEATED_FIELD(float) +DECLARE_GET_REPEATED_FIELD(double) +DECLARE_GET_REPEATED_FIELD(bool) + +#undef DECLARE_GET_REPEATED_FIELD + +// ============================================================================= +// Implementation details for {Get,Mutable}RawRepeatedPtrField. We provide +// specializations for , and and handle +// everything else with the default template which will match any type having +// a method with signature "static const google::protobuf::Descriptor* descriptor()". +// Such a type presumably is a descendant of google::protobuf::Message. + +template<> +inline const RepeatedPtrField& Reflection::GetRepeatedPtrField( + const Message& message, const FieldDescriptor* field) const { + return *static_cast* >( + MutableRawRepeatedString(const_cast(&message), field, true)); +} + +template<> +inline RepeatedPtrField* Reflection::MutableRepeatedPtrField( + Message* message, const FieldDescriptor* field) const { + return static_cast* >( + MutableRawRepeatedString(message, field, true)); +} + + +// ----- + +template<> +inline const RepeatedPtrField& Reflection::GetRepeatedPtrField( + const Message& message, const FieldDescriptor* field) const { + return *static_cast* >( + MutableRawRepeatedField(const_cast(&message), field, + FieldDescriptor::CPPTYPE_MESSAGE, -1, + NULL)); +} + +template<> +inline RepeatedPtrField* Reflection::MutableRepeatedPtrField( + Message* message, const FieldDescriptor* field) const { + return static_cast* >( + MutableRawRepeatedField(message, field, + FieldDescriptor::CPPTYPE_MESSAGE, -1, + NULL)); +} + +template +inline const RepeatedPtrField& Reflection::GetRepeatedPtrField( + const Message& message, const FieldDescriptor* field) const { + return *static_cast* >( + MutableRawRepeatedField(const_cast(&message), field, + FieldDescriptor::CPPTYPE_MESSAGE, -1, + PB::default_instance().GetDescriptor())); +} + +template +inline RepeatedPtrField* Reflection::MutableRepeatedPtrField( + Message* message, const FieldDescriptor* field) const { + return static_cast* >( + MutableRawRepeatedField(message, field, + FieldDescriptor::CPPTYPE_MESSAGE, -1, + PB::default_instance().GetDescriptor())); +} + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_MESSAGE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_lite.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_lite.cc new file mode 100644 index 0000000..49dbe6e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_lite.cc @@ -0,0 +1,334 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Authors: wink@google.com (Wink Saville), +// kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +MessageLite::~MessageLite() {} + +string MessageLite::InitializationErrorString() const { + return "(cannot determine missing fields for lite message)"; +} + +namespace { + +// When serializing, we first compute the byte size, then serialize the message. +// If serialization produces a different number of bytes than expected, we +// call this function, which crashes. The problem could be due to a bug in the +// protobuf implementation but is more likely caused by concurrent modification +// of the message. This function attempts to distinguish between the two and +// provide a useful error message. +void ByteSizeConsistencyError(int byte_size_before_serialization, + int byte_size_after_serialization, + int bytes_produced_by_serialization) { + GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization) + << "Protocol message was modified concurrently during serialization."; + GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization) + << "Byte size calculation and serialization were inconsistent. This " + "may indicate a bug in protocol buffers or it may be caused by " + "concurrent modification of the message."; + GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal."; +} + +string InitializationErrorMessage(const char* action, + const MessageLite& message) { + // Note: We want to avoid depending on strutil in the lite library, otherwise + // we'd use: + // + // return strings::Substitute( + // "Can't $0 message of type \"$1\" because it is missing required " + // "fields: $2", + // action, message.GetTypeName(), + // message.InitializationErrorString()); + + string result; + result += "Can't "; + result += action; + result += " message of type \""; + result += message.GetTypeName(); + result += "\" because it is missing required fields: "; + result += message.InitializationErrorString(); + return result; +} + +// Several of the Parse methods below just do one thing and then call another +// method. In a naive implementation, we might have ParseFromString() call +// ParseFromArray() which would call ParseFromZeroCopyStream() which would call +// ParseFromCodedStream() which would call MergeFromCodedStream() which would +// call MergePartialFromCodedStream(). However, when parsing very small +// messages, every function call introduces significant overhead. To avoid +// this without reproducing code, we use these forced-inline helpers. +// +// Note: GCC only allows GOOGLE_ATTRIBUTE_ALWAYS_INLINE on declarations, not +// definitions. +inline bool InlineMergeFromCodedStream(io::CodedInputStream* input, + MessageLite* message) + GOOGLE_ATTRIBUTE_ALWAYS_INLINE; +inline bool InlineParseFromCodedStream(io::CodedInputStream* input, + MessageLite* message) + GOOGLE_ATTRIBUTE_ALWAYS_INLINE; +inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input, + MessageLite* message) + GOOGLE_ATTRIBUTE_ALWAYS_INLINE; +inline bool InlineParseFromArray(const void* data, int size, + MessageLite* message) + GOOGLE_ATTRIBUTE_ALWAYS_INLINE; +inline bool InlineParsePartialFromArray(const void* data, int size, + MessageLite* message) + GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + +bool InlineMergeFromCodedStream(io::CodedInputStream* input, + MessageLite* message) { + if (!message->MergePartialFromCodedStream(input)) return false; + if (!message->IsInitialized()) { + GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message); + return false; + } + return true; +} + +bool InlineParseFromCodedStream(io::CodedInputStream* input, + MessageLite* message) { + message->Clear(); + return InlineMergeFromCodedStream(input, message); +} + +bool InlineParsePartialFromCodedStream(io::CodedInputStream* input, + MessageLite* message) { + message->Clear(); + return message->MergePartialFromCodedStream(input); +} + +bool InlineParseFromArray(const void* data, int size, MessageLite* message) { + io::CodedInputStream input(reinterpret_cast(data), size); + return InlineParseFromCodedStream(&input, message) && + input.ConsumedEntireMessage(); +} + +bool InlineParsePartialFromArray(const void* data, int size, + MessageLite* message) { + io::CodedInputStream input(reinterpret_cast(data), size); + return InlineParsePartialFromCodedStream(&input, message) && + input.ConsumedEntireMessage(); +} + +} // namespace + +bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) { + return InlineMergeFromCodedStream(input, this); +} + +bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) { + return InlineParseFromCodedStream(input, this); +} + +bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) { + return InlineParsePartialFromCodedStream(input, this); +} + +bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { + io::CodedInputStream decoder(input); + return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage(); +} + +bool MessageLite::ParsePartialFromZeroCopyStream( + io::ZeroCopyInputStream* input) { + io::CodedInputStream decoder(input); + return ParsePartialFromCodedStream(&decoder) && + decoder.ConsumedEntireMessage(); +} + +bool MessageLite::ParseFromBoundedZeroCopyStream( + io::ZeroCopyInputStream* input, int size) { + io::CodedInputStream decoder(input); + decoder.PushLimit(size); + return ParseFromCodedStream(&decoder) && + decoder.ConsumedEntireMessage() && + decoder.BytesUntilLimit() == 0; +} + +bool MessageLite::ParsePartialFromBoundedZeroCopyStream( + io::ZeroCopyInputStream* input, int size) { + io::CodedInputStream decoder(input); + decoder.PushLimit(size); + return ParsePartialFromCodedStream(&decoder) && + decoder.ConsumedEntireMessage() && + decoder.BytesUntilLimit() == 0; +} + +bool MessageLite::ParseFromString(const string& data) { + return InlineParseFromArray(data.data(), data.size(), this); +} + +bool MessageLite::ParsePartialFromString(const string& data) { + return InlineParsePartialFromArray(data.data(), data.size(), this); +} + +bool MessageLite::ParseFromArray(const void* data, int size) { + return InlineParseFromArray(data, size, this); +} + +bool MessageLite::ParsePartialFromArray(const void* data, int size) { + return InlineParsePartialFromArray(data, size, this); +} + + +// =================================================================== + +uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const { + // We only optimize this when using optimize_for = SPEED. In other cases + // we just use the CodedOutputStream path. + int size = GetCachedSize(); + io::ArrayOutputStream out(target, size); + io::CodedOutputStream coded_out(&out); + SerializeWithCachedSizes(&coded_out); + GOOGLE_CHECK(!coded_out.HadError()); + return target + size; +} + +bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const { + GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); + return SerializePartialToCodedStream(output); +} + +bool MessageLite::SerializePartialToCodedStream( + io::CodedOutputStream* output) const { + const int size = ByteSize(); // Force size to be cached. + uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size); + if (buffer != NULL) { + uint8* end = SerializeWithCachedSizesToArray(buffer); + if (end - buffer != size) { + ByteSizeConsistencyError(size, ByteSize(), end - buffer); + } + return true; + } else { + int original_byte_count = output->ByteCount(); + SerializeWithCachedSizes(output); + if (output->HadError()) { + return false; + } + int final_byte_count = output->ByteCount(); + + if (final_byte_count - original_byte_count != size) { + ByteSizeConsistencyError(size, ByteSize(), + final_byte_count - original_byte_count); + } + + return true; + } +} + +bool MessageLite::SerializeToZeroCopyStream( + io::ZeroCopyOutputStream* output) const { + io::CodedOutputStream encoder(output); + return SerializeToCodedStream(&encoder); +} + +bool MessageLite::SerializePartialToZeroCopyStream( + io::ZeroCopyOutputStream* output) const { + io::CodedOutputStream encoder(output); + return SerializePartialToCodedStream(&encoder); +} + +bool MessageLite::AppendToString(string* output) const { + GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); + return AppendPartialToString(output); +} + +bool MessageLite::AppendPartialToString(string* output) const { + int old_size = output->size(); + int byte_size = ByteSize(); + STLStringResizeUninitialized(output, old_size + byte_size); + uint8* start = reinterpret_cast(string_as_array(output) + old_size); + uint8* end = SerializeWithCachedSizesToArray(start); + if (end - start != byte_size) { + ByteSizeConsistencyError(byte_size, ByteSize(), end - start); + } + return true; +} + +bool MessageLite::SerializeToString(string* output) const { + output->clear(); + return AppendToString(output); +} + +bool MessageLite::SerializePartialToString(string* output) const { + output->clear(); + return AppendPartialToString(output); +} + +bool MessageLite::SerializeToArray(void* data, int size) const { + GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); + return SerializePartialToArray(data, size); +} + +bool MessageLite::SerializePartialToArray(void* data, int size) const { + int byte_size = ByteSize(); + if (size < byte_size) return false; + uint8* start = reinterpret_cast(data); + uint8* end = SerializeWithCachedSizesToArray(start); + if (end - start != byte_size) { + ByteSizeConsistencyError(byte_size, ByteSize(), end - start); + } + return true; +} + +string MessageLite::SerializeAsString() const { + // If the compiler implements the (Named) Return Value Optimization, + // the local variable 'result' will not actually reside on the stack + // of this function, but will be overlaid with the object that the + // caller supplied for the return value to be constructed in. + string output; + if (!AppendToString(&output)) + output.clear(); + return output; +} + +string MessageLite::SerializePartialAsString() const { + string output; + if (!AppendPartialToString(&output)) + output.clear(); + return output; +} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_lite.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_lite.h new file mode 100644 index 0000000..1ec3068 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_lite.h @@ -0,0 +1,246 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Authors: wink@google.com (Wink Saville), +// kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Defines MessageLite, the abstract interface implemented by all (lite +// and non-lite) protocol message objects. + +#ifndef GOOGLE_PROTOBUF_MESSAGE_LITE_H__ +#define GOOGLE_PROTOBUF_MESSAGE_LITE_H__ + +#include + +namespace google { +namespace protobuf { + +namespace io { + class CodedInputStream; + class CodedOutputStream; + class ZeroCopyInputStream; + class ZeroCopyOutputStream; +} + +// Interface to light weight protocol messages. +// +// This interface is implemented by all protocol message objects. Non-lite +// messages additionally implement the Message interface, which is a +// subclass of MessageLite. Use MessageLite instead when you only need +// the subset of features which it supports -- namely, nothing that uses +// descriptors or reflection. You can instruct the protocol compiler +// to generate classes which implement only MessageLite, not the full +// Message interface, by adding the following line to the .proto file: +// +// option optimize_for = LITE_RUNTIME; +// +// This is particularly useful on resource-constrained systems where +// the full protocol buffers runtime library is too big. +// +// Note that on non-constrained systems (e.g. servers) when you need +// to link in lots of protocol definitions, a better way to reduce +// total code footprint is to use optimize_for = CODE_SIZE. This +// will make the generated code smaller while still supporting all the +// same features (at the expense of speed). optimize_for = LITE_RUNTIME +// is best when you only have a small number of message types linked +// into your binary, in which case the size of the protocol buffers +// runtime itself is the biggest problem. +class LIBPROTOBUF_EXPORT MessageLite { + public: + inline MessageLite() {} + virtual ~MessageLite(); + + // Basic Operations ------------------------------------------------ + + // Get the name of this message type, e.g. "foo.bar.BazProto". + virtual string GetTypeName() const = 0; + + // Construct a new instance of the same type. Ownership is passed to the + // caller. + virtual MessageLite* New() const = 0; + + // Clear all fields of the message and set them to their default values. + // Clear() avoids freeing memory, assuming that any memory allocated + // to hold parts of the message will be needed again to hold the next + // message. If you actually want to free the memory used by a Message, + // you must delete it. + virtual void Clear() = 0; + + // Quickly check if all required fields have values set. + virtual bool IsInitialized() const = 0; + + // This is not implemented for Lite messages -- it just returns "(cannot + // determine missing fields for lite message)". However, it is implemented + // for full messages. See message.h. + virtual string InitializationErrorString() const; + + // If |other| is the exact same class as this, calls MergeFrom(). Otherwise, + // results are undefined (probably crash). + virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0; + + // Parsing --------------------------------------------------------- + // Methods for parsing in protocol buffer format. Most of these are + // just simple wrappers around MergeFromCodedStream(). + + // Fill the message with a protocol buffer parsed from the given input + // stream. Returns false on a read error or if the input is in the + // wrong format. + bool ParseFromCodedStream(io::CodedInputStream* input); + // Like ParseFromCodedStream(), but accepts messages that are missing + // required fields. + bool ParsePartialFromCodedStream(io::CodedInputStream* input); + // Read a protocol buffer from the given zero-copy input stream. If + // successful, the entire input will be consumed. + bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); + // Like ParseFromZeroCopyStream(), but accepts messages that are missing + // required fields. + bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input); + // Read a protocol buffer from the given zero-copy input stream, expecting + // the message to be exactly "size" bytes long. If successful, exactly + // this many bytes will have been consumed from the input. + bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); + // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are + // missing required fields. + bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, + int size); + // Parse a protocol buffer contained in a string. + bool ParseFromString(const string& data); + // Like ParseFromString(), but accepts messages that are missing + // required fields. + bool ParsePartialFromString(const string& data); + // Parse a protocol buffer contained in an array of bytes. + bool ParseFromArray(const void* data, int size); + // Like ParseFromArray(), but accepts messages that are missing + // required fields. + bool ParsePartialFromArray(const void* data, int size); + + + // Reads a protocol buffer from the stream and merges it into this + // Message. Singular fields read from the input overwrite what is + // already in the Message and repeated fields are appended to those + // already present. + // + // It is the responsibility of the caller to call input->LastTagWas() + // (for groups) or input->ConsumedEntireMessage() (for non-groups) after + // this returns to verify that the message's end was delimited correctly. + // + // ParsefromCodedStream() is implemented as Clear() followed by + // MergeFromCodedStream(). + bool MergeFromCodedStream(io::CodedInputStream* input); + + // Like MergeFromCodedStream(), but succeeds even if required fields are + // missing in the input. + // + // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream() + // followed by IsInitialized(). + virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) = 0; + + + // Serialization --------------------------------------------------- + // Methods for serializing in protocol buffer format. Most of these + // are just simple wrappers around ByteSize() and SerializeWithCachedSizes(). + + // Write a protocol buffer of this message to the given output. Returns + // false on a write error. If the message is missing required fields, + // this may GOOGLE_CHECK-fail. + bool SerializeToCodedStream(io::CodedOutputStream* output) const; + // Like SerializeToCodedStream(), but allows missing required fields. + bool SerializePartialToCodedStream(io::CodedOutputStream* output) const; + // Write the message to the given zero-copy output stream. All required + // fields must be set. + bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const; + // Like SerializeToZeroCopyStream(), but allows missing required fields. + bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const; + // Serialize the message and store it in the given string. All required + // fields must be set. + bool SerializeToString(string* output) const; + // Like SerializeToString(), but allows missing required fields. + bool SerializePartialToString(string* output) const; + // Serialize the message and store it in the given byte array. All required + // fields must be set. + bool SerializeToArray(void* data, int size) const; + // Like SerializeToArray(), but allows missing required fields. + bool SerializePartialToArray(void* data, int size) const; + + // Make a string encoding the message. Is equivalent to calling + // SerializeToString() on a string and using that. Returns the empty + // string if SerializeToString() would have returned an error. + // Note: If you intend to generate many such strings, you may + // reduce heap fragmentation by instead re-using the same string + // object with calls to SerializeToString(). + string SerializeAsString() const; + // Like SerializeAsString(), but allows missing required fields. + string SerializePartialAsString() const; + + // Like SerializeToString(), but appends to the data to the string's existing + // contents. All required fields must be set. + bool AppendToString(string* output) const; + // Like AppendToString(), but allows missing required fields. + bool AppendPartialToString(string* output) const; + + // Computes the serialized size of the message. This recursively calls + // ByteSize() on all embedded messages. If a subclass does not override + // this, it MUST override SetCachedSize(). + virtual int ByteSize() const = 0; + + // Serializes the message without recomputing the size. The message must + // not have changed since the last call to ByteSize(); if it has, the results + // are undefined. + virtual void SerializeWithCachedSizes( + io::CodedOutputStream* output) const = 0; + + // Like SerializeWithCachedSizes, but writes directly to *target, returning + // a pointer to the byte immediately after the last byte written. "target" + // must point at a byte array of at least ByteSize() bytes. + virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const; + + // Returns the result of the last call to ByteSize(). An embedded message's + // size is needed both to serialize it (because embedded messages are + // length-delimited) and to compute the outer message's size. Caching + // the size avoids computing it multiple times. + // + // ByteSize() does not automatically use the cached size when available + // because this would require invalidating it every time the message was + // modified, which would be too hard and expensive. (E.g. if a deeply-nested + // sub-message is changed, all of its parents' cached sizes would need to be + // invalidated, which is too much work for an otherwise inlined setter + // method.) + virtual int GetCachedSize() const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_MESSAGE_LITE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_unittest.cc new file mode 100644 index 0000000..a1449c7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/message_unittest.cc @@ -0,0 +1,354 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include +#include +#include +#ifdef _MSC_VER +#include +#else +#include +#endif +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace google { +namespace protobuf { + +#ifndef O_BINARY +#ifdef _O_BINARY +#define O_BINARY _O_BINARY +#else +#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. +#endif +#endif + +TEST(MessageTest, SerializeHelpers) { + // TODO(kenton): Test more helpers? They're all two-liners so it seems + // like a waste of time. + + protobuf_unittest::TestAllTypes message; + TestUtil::SetAllFields(&message); + stringstream stream; + + string str1("foo"); + string str2("bar"); + + EXPECT_TRUE(message.SerializeToString(&str1)); + EXPECT_TRUE(message.AppendToString(&str2)); + EXPECT_TRUE(message.SerializeToOstream(&stream)); + + EXPECT_EQ(str1.size() + 3, str2.size()); + EXPECT_EQ("bar", str2.substr(0, 3)); + // Don't use EXPECT_EQ because we don't want to dump raw binary data to + // stdout. + EXPECT_TRUE(str2.substr(3) == str1); + + // GCC gives some sort of error if we try to just do stream.str() == str1. + string temp = stream.str(); + EXPECT_TRUE(temp == str1); + + EXPECT_TRUE(message.SerializeAsString() == str1); + +} + +TEST(MessageTest, SerializeToBrokenOstream) { + ofstream out; + protobuf_unittest::TestAllTypes message; + message.set_optional_int32(123); + + EXPECT_FALSE(message.SerializeToOstream(&out)); +} + +TEST(MessageTest, ParseFromFileDescriptor) { + string filename = TestSourceDir() + + "/google/protobuf/testdata/golden_message"; + int file = open(filename.c_str(), O_RDONLY | O_BINARY); + + unittest::TestAllTypes message; + EXPECT_TRUE(message.ParseFromFileDescriptor(file)); + TestUtil::ExpectAllFieldsSet(message); + + EXPECT_GE(close(file), 0); +} + +TEST(MessageTest, ParsePackedFromFileDescriptor) { + string filename = + TestSourceDir() + + "/google/protobuf/testdata/golden_packed_fields_message"; + int file = open(filename.c_str(), O_RDONLY | O_BINARY); + + unittest::TestPackedTypes message; + EXPECT_TRUE(message.ParseFromFileDescriptor(file)); + TestUtil::ExpectPackedFieldsSet(message); + + EXPECT_GE(close(file), 0); +} + +TEST(MessageTest, ParseHelpers) { + // TODO(kenton): Test more helpers? They're all two-liners so it seems + // like a waste of time. + string data; + + { + // Set up. + protobuf_unittest::TestAllTypes message; + TestUtil::SetAllFields(&message); + message.SerializeToString(&data); + } + + { + // Test ParseFromString. + protobuf_unittest::TestAllTypes message; + EXPECT_TRUE(message.ParseFromString(data)); + TestUtil::ExpectAllFieldsSet(message); + } + + { + // Test ParseFromIstream. + protobuf_unittest::TestAllTypes message; + stringstream stream(data); + EXPECT_TRUE(message.ParseFromIstream(&stream)); + EXPECT_TRUE(stream.eof()); + TestUtil::ExpectAllFieldsSet(message); + } + + { + // Test ParseFromBoundedZeroCopyStream. + string data_with_junk(data); + data_with_junk.append("some junk on the end"); + io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size()); + protobuf_unittest::TestAllTypes message; + EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size())); + TestUtil::ExpectAllFieldsSet(message); + } + + { + // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if + // EOF is reached before the expected number of bytes. + io::ArrayInputStream stream(data.data(), data.size()); + protobuf_unittest::TestAllTypes message; + EXPECT_FALSE( + message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1)); + } +} + +TEST(MessageTest, ParseFailsIfNotInitialized) { + unittest::TestRequired message; + vector errors; + + { + ScopedMemoryLog log; + EXPECT_FALSE(message.ParseFromString("")); + errors = log.GetMessages(ERROR); + } + + ASSERT_EQ(1, errors.size()); + EXPECT_EQ("Can't parse message of type \"protobuf_unittest.TestRequired\" " + "because it is missing required fields: a, b, c", + errors[0]); +} + +TEST(MessageTest, BypassInitializationCheckOnParse) { + unittest::TestRequired message; + io::ArrayInputStream raw_input(NULL, 0); + io::CodedInputStream input(&raw_input); + EXPECT_TRUE(message.MergePartialFromCodedStream(&input)); +} + +TEST(MessageTest, InitializationErrorString) { + unittest::TestRequired message; + EXPECT_EQ("a, b, c", message.InitializationErrorString()); +} + +#ifdef PROTOBUF_HAS_DEATH_TEST + +TEST(MessageTest, SerializeFailsIfNotInitialized) { + unittest::TestRequired message; + string data; + EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)), + "Can't serialize message of type \"protobuf_unittest.TestRequired\" because " + "it is missing required fields: a, b, c"); +} + +TEST(MessageTest, CheckInitialized) { + unittest::TestRequired message; + EXPECT_DEATH(message.CheckInitialized(), + "Message of type \"protobuf_unittest.TestRequired\" is missing required " + "fields: a, b, c"); +} + +#endif // PROTOBUF_HAS_DEATH_TEST + +TEST(MessageTest, BypassInitializationCheckOnSerialize) { + unittest::TestRequired message; + io::ArrayOutputStream raw_output(NULL, 0); + io::CodedOutputStream output(&raw_output); + EXPECT_TRUE(message.SerializePartialToCodedStream(&output)); +} + +TEST(MessageTest, FindInitializationErrors) { + unittest::TestRequired message; + vector errors; + message.FindInitializationErrors(&errors); + ASSERT_EQ(3, errors.size()); + EXPECT_EQ("a", errors[0]); + EXPECT_EQ("b", errors[1]); + EXPECT_EQ("c", errors[2]); +} + +TEST(MessageTest, ParseFailsOnInvalidMessageEnd) { + unittest::TestAllTypes message; + + // Control case. + EXPECT_TRUE(message.ParseFromArray("", 0)); + + // The byte is a valid varint, but not a valid tag (zero). + EXPECT_FALSE(message.ParseFromArray("\0", 1)); + + // The byte is a malformed varint. + EXPECT_FALSE(message.ParseFromArray("\200", 1)); + + // The byte is an endgroup tag, but we aren't parsing a group. + EXPECT_FALSE(message.ParseFromArray("\014", 1)); +} + +namespace { + +void ExpectMessageMerged(const unittest::TestAllTypes& message) { + EXPECT_EQ(3, message.optional_int32()); + EXPECT_EQ(2, message.optional_int64()); + EXPECT_EQ("hello", message.optional_string()); +} + +void AssignParsingMergeMessages( + unittest::TestAllTypes* msg1, + unittest::TestAllTypes* msg2, + unittest::TestAllTypes* msg3) { + msg1->set_optional_int32(1); + msg2->set_optional_int64(2); + msg3->set_optional_int32(3); + msg3->set_optional_string("hello"); +} + +} // namespace + +// Test that if an optional or required message/group field appears multiple +// times in the input, they need to be merged. +TEST(MessageTest, ParsingMerge) { + unittest::TestParsingMerge::RepeatedFieldsGenerator generator; + unittest::TestAllTypes* msg1; + unittest::TestAllTypes* msg2; + unittest::TestAllTypes* msg3; + +#define ASSIGN_REPEATED_FIELD(FIELD) \ + msg1 = generator.add_##FIELD(); \ + msg2 = generator.add_##FIELD(); \ + msg3 = generator.add_##FIELD(); \ + AssignParsingMergeMessages(msg1, msg2, msg3) + + ASSIGN_REPEATED_FIELD(field1); + ASSIGN_REPEATED_FIELD(field2); + ASSIGN_REPEATED_FIELD(field3); + ASSIGN_REPEATED_FIELD(ext1); + ASSIGN_REPEATED_FIELD(ext2); + +#undef ASSIGN_REPEATED_FIELD +#define ASSIGN_REPEATED_GROUP(FIELD) \ + msg1 = generator.add_##FIELD()->mutable_field1(); \ + msg2 = generator.add_##FIELD()->mutable_field1(); \ + msg3 = generator.add_##FIELD()->mutable_field1(); \ + AssignParsingMergeMessages(msg1, msg2, msg3) + + ASSIGN_REPEATED_GROUP(group1); + ASSIGN_REPEATED_GROUP(group2); + +#undef ASSIGN_REPEATED_GROUP + + string buffer; + generator.SerializeToString(&buffer); + unittest::TestParsingMerge parsing_merge; + parsing_merge.ParseFromString(buffer); + + // Required and optional fields should be merged. + ExpectMessageMerged(parsing_merge.required_all_types()); + ExpectMessageMerged(parsing_merge.optional_all_types()); + ExpectMessageMerged( + parsing_merge.optionalgroup().optional_group_all_types()); + ExpectMessageMerged( + parsing_merge.GetExtension(unittest::TestParsingMerge::optional_ext)); + + // Repeated fields should not be merged. + EXPECT_EQ(3, parsing_merge.repeated_all_types_size()); + EXPECT_EQ(3, parsing_merge.repeatedgroup_size()); + EXPECT_EQ(3, parsing_merge.ExtensionSize( + unittest::TestParsingMerge::repeated_ext)); +} + +TEST(MessageFactoryTest, GeneratedFactoryLookup) { + EXPECT_EQ( + MessageFactory::generated_factory()->GetPrototype( + protobuf_unittest::TestAllTypes::descriptor()), + &protobuf_unittest::TestAllTypes::default_instance()); +} + +TEST(MessageFactoryTest, GeneratedFactoryUnknownType) { + // Construct a new descriptor. + DescriptorPool pool; + FileDescriptorProto file; + file.set_name("foo.proto"); + file.add_message_type()->set_name("Foo"); + const Descriptor* descriptor = pool.BuildFile(file)->message_type(0); + + // Trying to construct it should return NULL. + EXPECT_TRUE( + MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL); +} + + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/package_info.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/package_info.h new file mode 100644 index 0000000..60cd399 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/package_info.h @@ -0,0 +1,64 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file exists solely to document the google::protobuf namespace. +// It is not compiled into anything, but it may be read by an automated +// documentation generator. + +namespace google { + +// Core components of the Protocol Buffers runtime library. +// +// The files in this package represent the core of the Protocol Buffer +// system. All of them are part of the libprotobuf library. +// +// A note on thread-safety: +// +// Thread-safety in the Protocol Buffer library follows a simple rule: +// unless explicitly noted otherwise, it is always safe to use an object +// from multiple threads simultaneously as long as the object is declared +// const in all threads (or, it is only used in ways that would be allowed +// if it were declared const). However, if an object is accessed in one +// thread in a way that would not be allowed if it were const, then it is +// not safe to access that object in any other thread simultaneously. +// +// Put simply, read-only access to an object can happen in multiple threads +// simultaneously, but write access can only happen in a single thread at +// a time. +// +// The implementation does contain some "const" methods which actually modify +// the object behind the scenes -- e.g., to cache results -- but in these cases +// mutex locking is used to make the access thread-safe. +namespace protobuf {} +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops.cc new file mode 100644 index 0000000..f00997c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops.cc @@ -0,0 +1,267 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +void ReflectionOps::Copy(const Message& from, Message* to) { + if (&from == to) return; + Clear(to); + Merge(from, to); +} + +void ReflectionOps::Merge(const Message& from, Message* to) { + GOOGLE_CHECK_NE(&from, to); + + const Descriptor* descriptor = from.GetDescriptor(); + GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor) + << "Tried to merge messages of different types."; + + const Reflection* from_reflection = from.GetReflection(); + const Reflection* to_reflection = to->GetReflection(); + + vector fields; + from_reflection->ListFields(from, &fields); + for (int i = 0; i < fields.size(); i++) { + const FieldDescriptor* field = fields[i]; + + if (field->is_repeated()) { + int count = from_reflection->FieldSize(from, field); + for (int j = 0; j < count; j++) { + switch (field->cpp_type()) { +#define HANDLE_TYPE(CPPTYPE, METHOD) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + to_reflection->Add##METHOD(to, field, \ + from_reflection->GetRepeated##METHOD(from, field, j)); \ + break; + + HANDLE_TYPE(INT32 , Int32 ); + HANDLE_TYPE(INT64 , Int64 ); + HANDLE_TYPE(UINT32, UInt32); + HANDLE_TYPE(UINT64, UInt64); + HANDLE_TYPE(FLOAT , Float ); + HANDLE_TYPE(DOUBLE, Double); + HANDLE_TYPE(BOOL , Bool ); + HANDLE_TYPE(STRING, String); + HANDLE_TYPE(ENUM , Enum ); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_MESSAGE: + to_reflection->AddMessage(to, field)->MergeFrom( + from_reflection->GetRepeatedMessage(from, field, j)); + break; + } + } + } else { + switch (field->cpp_type()) { +#define HANDLE_TYPE(CPPTYPE, METHOD) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + to_reflection->Set##METHOD(to, field, \ + from_reflection->Get##METHOD(from, field)); \ + break; + + HANDLE_TYPE(INT32 , Int32 ); + HANDLE_TYPE(INT64 , Int64 ); + HANDLE_TYPE(UINT32, UInt32); + HANDLE_TYPE(UINT64, UInt64); + HANDLE_TYPE(FLOAT , Float ); + HANDLE_TYPE(DOUBLE, Double); + HANDLE_TYPE(BOOL , Bool ); + HANDLE_TYPE(STRING, String); + HANDLE_TYPE(ENUM , Enum ); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_MESSAGE: + to_reflection->MutableMessage(to, field)->MergeFrom( + from_reflection->GetMessage(from, field)); + break; + } + } + } + + to_reflection->MutableUnknownFields(to)->MergeFrom( + from_reflection->GetUnknownFields(from)); +} + +void ReflectionOps::Clear(Message* message) { + const Reflection* reflection = message->GetReflection(); + + vector fields; + reflection->ListFields(*message, &fields); + for (int i = 0; i < fields.size(); i++) { + reflection->ClearField(message, fields[i]); + } + + reflection->MutableUnknownFields(message)->Clear(); +} + +bool ReflectionOps::IsInitialized(const Message& message) { + const Descriptor* descriptor = message.GetDescriptor(); + const Reflection* reflection = message.GetReflection(); + + // Check required fields of this message. + for (int i = 0; i < descriptor->field_count(); i++) { + if (descriptor->field(i)->is_required()) { + if (!reflection->HasField(message, descriptor->field(i))) { + return false; + } + } + } + + // Check that sub-messages are initialized. + vector fields; + reflection->ListFields(message, &fields); + for (int i = 0; i < fields.size(); i++) { + const FieldDescriptor* field = fields[i]; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + + if (field->is_repeated()) { + int size = reflection->FieldSize(message, field); + + for (int j = 0; j < size; j++) { + if (!reflection->GetRepeatedMessage(message, field, j) + .IsInitialized()) { + return false; + } + } + } else { + if (!reflection->GetMessage(message, field).IsInitialized()) { + return false; + } + } + } + } + + return true; +} + +void ReflectionOps::DiscardUnknownFields(Message* message) { + const Reflection* reflection = message->GetReflection(); + + reflection->MutableUnknownFields(message)->Clear(); + + vector fields; + reflection->ListFields(*message, &fields); + for (int i = 0; i < fields.size(); i++) { + const FieldDescriptor* field = fields[i]; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (field->is_repeated()) { + int size = reflection->FieldSize(*message, field); + for (int j = 0; j < size; j++) { + reflection->MutableRepeatedMessage(message, field, j) + ->DiscardUnknownFields(); + } + } else { + reflection->MutableMessage(message, field)->DiscardUnknownFields(); + } + } + } +} + +static string SubMessagePrefix(const string& prefix, + const FieldDescriptor* field, + int index) { + string result(prefix); + if (field->is_extension()) { + result.append("("); + result.append(field->full_name()); + result.append(")"); + } else { + result.append(field->name()); + } + if (index != -1) { + result.append("["); + result.append(SimpleItoa(index)); + result.append("]"); + } + result.append("."); + return result; +} + +void ReflectionOps::FindInitializationErrors( + const Message& message, + const string& prefix, + vector* errors) { + const Descriptor* descriptor = message.GetDescriptor(); + const Reflection* reflection = message.GetReflection(); + + // Check required fields of this message. + for (int i = 0; i < descriptor->field_count(); i++) { + if (descriptor->field(i)->is_required()) { + if (!reflection->HasField(message, descriptor->field(i))) { + errors->push_back(prefix + descriptor->field(i)->name()); + } + } + } + + // Check sub-messages. + vector fields; + reflection->ListFields(message, &fields); + for (int i = 0; i < fields.size(); i++) { + const FieldDescriptor* field = fields[i]; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + + if (field->is_repeated()) { + int size = reflection->FieldSize(message, field); + + for (int j = 0; j < size; j++) { + const Message& sub_message = + reflection->GetRepeatedMessage(message, field, j); + FindInitializationErrors(sub_message, + SubMessagePrefix(prefix, field, j), + errors); + } + } else { + const Message& sub_message = reflection->GetMessage(message, field); + FindInitializationErrors(sub_message, + SubMessagePrefix(prefix, field, -1), + errors); + } + } + } +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops.h new file mode 100644 index 0000000..60165c2 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops.h @@ -0,0 +1,81 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_REFLECTION_OPS_H__ +#define GOOGLE_PROTOBUF_REFLECTION_OPS_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +// Basic operations that can be performed using reflection. +// These can be used as a cheap way to implement the corresponding +// methods of the Message interface, though they are likely to be +// slower than implementations tailored for the specific message type. +// +// This class should stay limited to operations needed to implement +// the Message interface. +// +// This class is really a namespace that contains only static methods. +class LIBPROTOBUF_EXPORT ReflectionOps { + public: + static void Copy(const Message& from, Message* to); + static void Merge(const Message& from, Message* to); + static void Clear(Message* message); + static bool IsInitialized(const Message& message); + static void DiscardUnknownFields(Message* message); + + // Finds all unset required fields in the message and adds their full + // paths (e.g. "foo.bar[5].baz") to *names. "prefix" will be attached to + // the front of each name. + static void FindInitializationErrors(const Message& message, + const string& prefix, + vector* errors); + + private: + // All methods are static. No need to construct. + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionOps); +}; + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_REFLECTION_OPS_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops_unittest.cc new file mode 100644 index 0000000..29229b5 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/reflection_ops_unittest.cc @@ -0,0 +1,405 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { +namespace { + +TEST(ReflectionOpsTest, SanityCheck) { + unittest::TestAllTypes message; + + TestUtil::SetAllFields(&message); + TestUtil::ExpectAllFieldsSet(message); +} + +TEST(ReflectionOpsTest, Copy) { + unittest::TestAllTypes message, message2; + + TestUtil::SetAllFields(&message); + + ReflectionOps::Copy(message, &message2); + + TestUtil::ExpectAllFieldsSet(message2); + + // Copying from self should be a no-op. + ReflectionOps::Copy(message2, &message2); + TestUtil::ExpectAllFieldsSet(message2); +} + +TEST(ReflectionOpsTest, CopyExtensions) { + unittest::TestAllExtensions message, message2; + + TestUtil::SetAllExtensions(&message); + + ReflectionOps::Copy(message, &message2); + + TestUtil::ExpectAllExtensionsSet(message2); +} + +TEST(ReflectionOpsTest, Merge) { + // Note: Copy is implemented in terms of Merge() so technically the Copy + // test already tested most of this. + + unittest::TestAllTypes message, message2; + + TestUtil::SetAllFields(&message); + + // This field will test merging into an empty spot. + message2.set_optional_int32(message.optional_int32()); + message.clear_optional_int32(); + + // This tests overwriting. + message2.set_optional_string(message.optional_string()); + message.set_optional_string("something else"); + + // This tests concatenating. + message2.add_repeated_int32(message.repeated_int32(1)); + int32 i = message.repeated_int32(0); + message.clear_repeated_int32(); + message.add_repeated_int32(i); + + ReflectionOps::Merge(message2, &message); + + TestUtil::ExpectAllFieldsSet(message); +} + +TEST(ReflectionOpsTest, MergeExtensions) { + // Note: Copy is implemented in terms of Merge() so technically the Copy + // test already tested most of this. + + unittest::TestAllExtensions message, message2; + + TestUtil::SetAllExtensions(&message); + + // This field will test merging into an empty spot. + message2.SetExtension(unittest::optional_int32_extension, + message.GetExtension(unittest::optional_int32_extension)); + message.ClearExtension(unittest::optional_int32_extension); + + // This tests overwriting. + message2.SetExtension(unittest::optional_string_extension, + message.GetExtension(unittest::optional_string_extension)); + message.SetExtension(unittest::optional_string_extension, "something else"); + + // This tests concatenating. + message2.AddExtension(unittest::repeated_int32_extension, + message.GetExtension(unittest::repeated_int32_extension, 1)); + int32 i = message.GetExtension(unittest::repeated_int32_extension, 0); + message.ClearExtension(unittest::repeated_int32_extension); + message.AddExtension(unittest::repeated_int32_extension, i); + + ReflectionOps::Merge(message2, &message); + + TestUtil::ExpectAllExtensionsSet(message); +} + +TEST(ReflectionOpsTest, MergeUnknown) { + // Test that the messages' UnknownFieldSets are correctly merged. + unittest::TestEmptyMessage message1, message2; + message1.mutable_unknown_fields()->AddVarint(1234, 1); + message2.mutable_unknown_fields()->AddVarint(1234, 2); + + ReflectionOps::Merge(message2, &message1); + + ASSERT_EQ(2, message1.unknown_fields().field_count()); + ASSERT_EQ(UnknownField::TYPE_VARINT, + message1.unknown_fields().field(0).type()); + EXPECT_EQ(1, message1.unknown_fields().field(0).varint()); + ASSERT_EQ(UnknownField::TYPE_VARINT, + message1.unknown_fields().field(1).type()); + EXPECT_EQ(2, message1.unknown_fields().field(1).varint()); +} + +#ifdef PROTOBUF_HAS_DEATH_TEST + +TEST(ReflectionOpsTest, MergeFromSelf) { + // Note: Copy is implemented in terms of Merge() so technically the Copy + // test already tested most of this. + + unittest::TestAllTypes message; + + EXPECT_DEATH( + ReflectionOps::Merge(message, &message), + "&from"); +} + +#endif // PROTOBUF_HAS_DEATH_TEST + +TEST(ReflectionOpsTest, Clear) { + unittest::TestAllTypes message; + + TestUtil::SetAllFields(&message); + + ReflectionOps::Clear(&message); + + TestUtil::ExpectClear(message); + + // Check that getting embedded messages returns the objects created during + // SetAllFields() rather than default instances. + EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), + &message.optionalgroup()); + EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), + &message.optional_nested_message()); + EXPECT_NE(&unittest::ForeignMessage::default_instance(), + &message.optional_foreign_message()); + EXPECT_NE(&unittest_import::ImportMessage::default_instance(), + &message.optional_import_message()); +} + +TEST(ReflectionOpsTest, ClearExtensions) { + unittest::TestAllExtensions message; + + TestUtil::SetAllExtensions(&message); + + ReflectionOps::Clear(&message); + + TestUtil::ExpectExtensionsClear(message); + + // Check that getting embedded messages returns the objects created during + // SetAllExtensions() rather than default instances. + EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(), + &message.GetExtension(unittest::optionalgroup_extension)); + EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), + &message.GetExtension(unittest::optional_nested_message_extension)); + EXPECT_NE(&unittest::ForeignMessage::default_instance(), + &message.GetExtension( + unittest::optional_foreign_message_extension)); + EXPECT_NE(&unittest_import::ImportMessage::default_instance(), + &message.GetExtension(unittest::optional_import_message_extension)); +} + +TEST(ReflectionOpsTest, ClearUnknown) { + // Test that the message's UnknownFieldSet is correctly cleared. + unittest::TestEmptyMessage message; + message.mutable_unknown_fields()->AddVarint(1234, 1); + + ReflectionOps::Clear(&message); + + EXPECT_EQ(0, message.unknown_fields().field_count()); +} + +TEST(ReflectionOpsTest, DiscardUnknownFields) { + unittest::TestAllTypes message; + TestUtil::SetAllFields(&message); + + // Set some unknown fields in message. + message.mutable_unknown_fields() + ->AddVarint(123456, 654321); + message.mutable_optional_nested_message() + ->mutable_unknown_fields() + ->AddVarint(123456, 654321); + message.mutable_repeated_nested_message(0) + ->mutable_unknown_fields() + ->AddVarint(123456, 654321); + + EXPECT_EQ(1, message.unknown_fields().field_count()); + EXPECT_EQ(1, message.optional_nested_message() + .unknown_fields().field_count()); + EXPECT_EQ(1, message.repeated_nested_message(0) + .unknown_fields().field_count()); + + // Discard them. + ReflectionOps::DiscardUnknownFields(&message); + TestUtil::ExpectAllFieldsSet(message); + + EXPECT_EQ(0, message.unknown_fields().field_count()); + EXPECT_EQ(0, message.optional_nested_message() + .unknown_fields().field_count()); + EXPECT_EQ(0, message.repeated_nested_message(0) + .unknown_fields().field_count()); +} + +TEST(ReflectionOpsTest, DiscardUnknownExtensions) { + unittest::TestAllExtensions message; + TestUtil::SetAllExtensions(&message); + + // Set some unknown fields. + message.mutable_unknown_fields() + ->AddVarint(123456, 654321); + message.MutableExtension(unittest::optional_nested_message_extension) + ->mutable_unknown_fields() + ->AddVarint(123456, 654321); + message.MutableExtension(unittest::repeated_nested_message_extension, 0) + ->mutable_unknown_fields() + ->AddVarint(123456, 654321); + + EXPECT_EQ(1, message.unknown_fields().field_count()); + EXPECT_EQ(1, + message.GetExtension(unittest::optional_nested_message_extension) + .unknown_fields().field_count()); + EXPECT_EQ(1, + message.GetExtension(unittest::repeated_nested_message_extension, 0) + .unknown_fields().field_count()); + + // Discard them. + ReflectionOps::DiscardUnknownFields(&message); + TestUtil::ExpectAllExtensionsSet(message); + + EXPECT_EQ(0, message.unknown_fields().field_count()); + EXPECT_EQ(0, + message.GetExtension(unittest::optional_nested_message_extension) + .unknown_fields().field_count()); + EXPECT_EQ(0, + message.GetExtension(unittest::repeated_nested_message_extension, 0) + .unknown_fields().field_count()); +} + +TEST(ReflectionOpsTest, IsInitialized) { + unittest::TestRequired message; + + EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + message.set_a(1); + EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + message.set_b(2); + EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + message.set_c(3); + EXPECT_TRUE(ReflectionOps::IsInitialized(message)); +} + +TEST(ReflectionOpsTest, ForeignIsInitialized) { + unittest::TestRequiredForeign message; + + // Starts out initialized because the foreign message is itself an optional + // field. + EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + + // Once we create that field, the message is no longer initialized. + message.mutable_optional_message(); + EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + + // Initialize it. Now we're initialized. + message.mutable_optional_message()->set_a(1); + message.mutable_optional_message()->set_b(2); + message.mutable_optional_message()->set_c(3); + EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + + // Add a repeated version of the message. No longer initialized. + unittest::TestRequired* sub_message = message.add_repeated_message(); + EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + + // Initialize that repeated version. + sub_message->set_a(1); + sub_message->set_b(2); + sub_message->set_c(3); + EXPECT_TRUE(ReflectionOps::IsInitialized(message)); +} + +TEST(ReflectionOpsTest, ExtensionIsInitialized) { + unittest::TestAllExtensions message; + + // Starts out initialized because the foreign message is itself an optional + // field. + EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + + // Once we create that field, the message is no longer initialized. + message.MutableExtension(unittest::TestRequired::single); + EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + + // Initialize it. Now we're initialized. + message.MutableExtension(unittest::TestRequired::single)->set_a(1); + message.MutableExtension(unittest::TestRequired::single)->set_b(2); + message.MutableExtension(unittest::TestRequired::single)->set_c(3); + EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + + // Add a repeated version of the message. No longer initialized. + message.AddExtension(unittest::TestRequired::multi); + EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + + // Initialize that repeated version. + message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1); + message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2); + message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3); + EXPECT_TRUE(ReflectionOps::IsInitialized(message)); +} + +static string FindInitializationErrors(const Message& message) { + vector errors; + ReflectionOps::FindInitializationErrors(message, "", &errors); + return JoinStrings(errors, ","); +} + +TEST(ReflectionOpsTest, FindInitializationErrors) { + unittest::TestRequired message; + EXPECT_EQ("a,b,c", FindInitializationErrors(message)); +} + +TEST(ReflectionOpsTest, FindForeignInitializationErrors) { + unittest::TestRequiredForeign message; + message.mutable_optional_message(); + message.add_repeated_message(); + message.add_repeated_message(); + EXPECT_EQ("optional_message.a," + "optional_message.b," + "optional_message.c," + "repeated_message[0].a," + "repeated_message[0].b," + "repeated_message[0].c," + "repeated_message[1].a," + "repeated_message[1].b," + "repeated_message[1].c", + FindInitializationErrors(message)); +} + +TEST(ReflectionOpsTest, FindExtensionInitializationErrors) { + unittest::TestAllExtensions message; + message.MutableExtension(unittest::TestRequired::single); + message.AddExtension(unittest::TestRequired::multi); + message.AddExtension(unittest::TestRequired::multi); + EXPECT_EQ("(protobuf_unittest.TestRequired.single).a," + "(protobuf_unittest.TestRequired.single).b," + "(protobuf_unittest.TestRequired.single).c," + "(protobuf_unittest.TestRequired.multi)[0].a," + "(protobuf_unittest.TestRequired.multi)[0].b," + "(protobuf_unittest.TestRequired.multi)[0].c," + "(protobuf_unittest.TestRequired.multi)[1].a," + "(protobuf_unittest.TestRequired.multi)[1].b," + "(protobuf_unittest.TestRequired.multi)[1].c", + FindInitializationErrors(message)); +} + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field.cc new file mode 100644 index 0000000..2c1f74c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field.cc @@ -0,0 +1,87 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include +#include + +namespace google { +namespace protobuf { + +namespace internal { + +void RepeatedPtrFieldBase::Reserve(int new_size) { + if (total_size_ >= new_size) return; + + void** old_elements = elements_; + total_size_ = max(kMinRepeatedFieldAllocationSize, + max(total_size_ * 2, new_size)); + elements_ = new void*[total_size_]; + if (old_elements != NULL) { + memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0])); + delete [] old_elements; + } +} + +void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) { + if (this == other) return; + void** swap_elements = elements_; + int swap_current_size = current_size_; + int swap_allocated_size = allocated_size_; + int swap_total_size = total_size_; + + elements_ = other->elements_; + current_size_ = other->current_size_; + allocated_size_ = other->allocated_size_; + total_size_ = other->total_size_; + + other->elements_ = swap_elements; + other->current_size_ = swap_current_size; + other->allocated_size_ = swap_allocated_size; + other->total_size_ = swap_total_size; +} + +string* StringTypeHandlerBase::New() { + return new string; +} +void StringTypeHandlerBase::Delete(string* value) { + delete value; +} + +} // namespace internal + + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field.h new file mode 100644 index 0000000..570d4b7 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field.h @@ -0,0 +1,1519 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// RepeatedField and RepeatedPtrField are used by generated protocol message +// classes to manipulate repeated fields. These classes are very similar to +// STL's vector, but include a number of optimizations found to be useful +// specifically in the case of Protocol Buffers. RepeatedPtrField is +// particularly different from STL vector as it manages ownership of the +// pointers that it contains. +// +// Typically, clients should not need to access RepeatedField objects directly, +// but should instead use the accessor functions generated automatically by the +// protocol compiler. + +#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__ +#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__ + +#include +#include +#include +#include +#include +#include +#include + +namespace google { + +namespace upb { +namespace google_opensource { +class GMR_Handlers; +} // namespace google_opensource +} // namespace upb + +namespace protobuf { + +class Message; + +namespace internal { + +static const int kMinRepeatedFieldAllocationSize = 4; + +// A utility function for logging that doesn't need any template types. +void LogIndexOutOfBounds(int index, int size); +} // namespace internal + + +// RepeatedField is used to represent repeated fields of a primitive type (in +// other words, everything except strings and nested Messages). Most users will +// not ever use a RepeatedField directly; they will use the get-by-index, +// set-by-index, and add accessors that are generated for all repeated fields. +template +class RepeatedField { + public: + RepeatedField(); + RepeatedField(const RepeatedField& other); + template + RepeatedField(Iter begin, const Iter& end); + ~RepeatedField(); + + RepeatedField& operator=(const RepeatedField& other); + + int size() const; + + const Element& Get(int index) const; + Element* Mutable(int index); + void Set(int index, const Element& value); + void Add(const Element& value); + Element* Add(); + // Remove the last element in the array. + void RemoveLast(); + + // Extract elements with indices in "[start .. start+num-1]". + // Copy them into "elements[0 .. num-1]" if "elements" is not NULL. + // Caution: implementation also moves elements with indices [start+num ..]. + // Calling this routine inside a loop can cause quadratic behavior. + void ExtractSubrange(int start, int num, Element* elements); + + void Clear(); + void MergeFrom(const RepeatedField& other); + void CopyFrom(const RepeatedField& other); + + // Reserve space to expand the field to at least the given size. If the + // array is grown, it will always be at least doubled in size. + void Reserve(int new_size); + + // Resize the RepeatedField to a new, smaller size. This is O(1). + void Truncate(int new_size); + + void AddAlreadyReserved(const Element& value); + Element* AddAlreadyReserved(); + int Capacity() const; + + // Gets the underlying array. This pointer is possibly invalidated by + // any add or remove operation. + Element* mutable_data(); + const Element* data() const; + + // Swap entire contents with "other". + void Swap(RepeatedField* other); + + // Swap two elements. + void SwapElements(int index1, int index2); + + // STL-like iterator support + typedef Element* iterator; + typedef const Element* const_iterator; + typedef Element value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef int size_type; + typedef ptrdiff_t difference_type; + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + // Reverse iterator support + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + reverse_iterator rbegin() { + return reverse_iterator(end()); + } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { + return reverse_iterator(begin()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + // Returns the number of bytes used by the repeated field, excluding + // sizeof(*this) + int SpaceUsedExcludingSelf() const; + + private: + static const int kInitialSize = 0; + + Element* elements_; + int current_size_; + int total_size_; + + // Move the contents of |from| into |to|, possibly clobbering |from| in the + // process. For primitive types this is just a memcpy(), but it could be + // specialized for non-primitive types to, say, swap each element instead. + void MoveArray(Element to[], Element from[], int size); + + // Copy the elements of |from| into |to|. + void CopyArray(Element to[], const Element from[], int size); +}; + +namespace internal { +template class RepeatedPtrIterator; +template class RepeatedPtrOverPtrsIterator; +} // namespace internal + +namespace internal { + +// This is a helper template to copy an array of elements effeciently when they +// have a trivial copy constructor, and correctly otherwise. This really +// shouldn't be necessary, but our compiler doesn't optimize std::copy very +// effectively. +template ::value> +struct ElementCopier { + void operator()(Element to[], const Element from[], int array_size); +}; + +} // namespace internal + +namespace internal { + +// This is the common base class for RepeatedPtrFields. It deals only in void* +// pointers. Users should not use this interface directly. +// +// The methods of this interface correspond to the methods of RepeatedPtrField, +// but may have a template argument called TypeHandler. Its signature is: +// class TypeHandler { +// public: +// typedef MyType Type; +// static Type* New(); +// static void Delete(Type*); +// static void Clear(Type*); +// static void Merge(const Type& from, Type* to); +// +// // Only needs to be implemented if SpaceUsedExcludingSelf() is called. +// static int SpaceUsed(const Type&); +// }; +class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { + protected: + // The reflection implementation needs to call protected methods directly, + // reinterpreting pointers as being to Message instead of a specific Message + // subclass. + friend class GeneratedMessageReflection; + + // ExtensionSet stores repeated message extensions as + // RepeatedPtrField, but non-lite ExtensionSets need to + // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf() + // reinterpreting MessageLite as Message. ExtensionSet also needs to make + // use of AddFromCleared(), which is not part of the public interface. + friend class ExtensionSet; + + // To parse directly into a proto2 generated class, the upb class GMR_Handlers + // needs to be able to modify a RepeatedPtrFieldBase directly. + friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers; + + RepeatedPtrFieldBase(); + + // Must be called from destructor. + template + void Destroy(); + + int size() const; + + template + const typename TypeHandler::Type& Get(int index) const; + template + typename TypeHandler::Type* Mutable(int index); + template + typename TypeHandler::Type* Add(); + template + void RemoveLast(); + template + void Clear(); + template + void MergeFrom(const RepeatedPtrFieldBase& other); + template + void CopyFrom(const RepeatedPtrFieldBase& other); + + void CloseGap(int start, int num) { + // Close up a gap of "num" elements starting at offset "start". + for (int i = start + num; i < allocated_size_; ++i) + elements_[i - num] = elements_[i]; + current_size_ -= num; + allocated_size_ -= num; + } + + void Reserve(int new_size); + + int Capacity() const; + + // Used for constructing iterators. + void* const* raw_data() const; + void** raw_mutable_data() const; + + template + typename TypeHandler::Type** mutable_data(); + template + const typename TypeHandler::Type* const* data() const; + + void Swap(RepeatedPtrFieldBase* other); + + void SwapElements(int index1, int index2); + + template + int SpaceUsedExcludingSelf() const; + + + // Advanced memory management -------------------------------------- + + // Like Add(), but if there are no cleared objects to use, returns NULL. + template + typename TypeHandler::Type* AddFromCleared(); + + template + void AddAllocated(typename TypeHandler::Type* value); + template + typename TypeHandler::Type* ReleaseLast(); + + int ClearedCount() const; + template + void AddCleared(typename TypeHandler::Type* value); + template + typename TypeHandler::Type* ReleaseCleared(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase); + + static const int kInitialSize = 0; + + void** elements_; + int current_size_; + int allocated_size_; + int total_size_; + + template + static inline typename TypeHandler::Type* cast(void* element) { + return reinterpret_cast(element); + } + template + static inline const typename TypeHandler::Type* cast(const void* element) { + return reinterpret_cast(element); + } +}; + +template +class GenericTypeHandler { + public: + typedef GenericType Type; + static GenericType* New() { return new GenericType; } + static void Delete(GenericType* value) { delete value; } + static void Clear(GenericType* value) { value->Clear(); } + static void Merge(const GenericType& from, GenericType* to) { + to->MergeFrom(from); + } + static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); } + static const Type& default_instance() { return Type::default_instance(); } +}; + +template <> +inline void GenericTypeHandler::Merge( + const MessageLite& from, MessageLite* to) { + to->CheckTypeAndMergeFrom(from); +} + +template <> +inline const MessageLite& GenericTypeHandler::default_instance() { + // Yes, the behavior of the code is undefined, but this function is only + // called when we're already deep into the world of undefined, because the + // caller called Get(index) out of bounds. + MessageLite* null = NULL; + return *null; +} + +template <> +inline const Message& GenericTypeHandler::default_instance() { + // Yes, the behavior of the code is undefined, but this function is only + // called when we're already deep into the world of undefined, because the + // caller called Get(index) out of bounds. + Message* null = NULL; + return *null; +} + + +// HACK: If a class is declared as DLL-exported in MSVC, it insists on +// generating copies of all its methods -- even inline ones -- to include +// in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which +// isn't in the lite library, therefore the lite library cannot link if +// StringTypeHandler is exported. So, we factor out StringTypeHandlerBase, +// export that, then make StringTypeHandler be a subclass which is NOT +// exported. +// TODO(kenton): There has to be a better way. +class LIBPROTOBUF_EXPORT StringTypeHandlerBase { + public: + typedef string Type; + static string* New(); + static void Delete(string* value); + static void Clear(string* value) { value->clear(); } + static void Merge(const string& from, string* to) { *to = from; } + static const Type& default_instance() { + return ::google::protobuf::internal::kEmptyString; + } +}; + +class StringTypeHandler : public StringTypeHandlerBase { + public: + static int SpaceUsed(const string& value) { + return sizeof(value) + StringSpaceUsedExcludingSelf(value); + } +}; + + +} // namespace internal + +// RepeatedPtrField is like RepeatedField, but used for repeated strings or +// Messages. +template +class RepeatedPtrField : public internal::RepeatedPtrFieldBase { + public: + RepeatedPtrField(); + RepeatedPtrField(const RepeatedPtrField& other); + template + RepeatedPtrField(Iter begin, const Iter& end); + ~RepeatedPtrField(); + + RepeatedPtrField& operator=(const RepeatedPtrField& other); + + int size() const; + + const Element& Get(int index) const; + Element* Mutable(int index); + Element* Add(); + + // Remove the last element in the array. + // Ownership of the element is retained by the array. + void RemoveLast(); + + // Delete elements with indices in the range [start .. start+num-1]. + // Caution: implementation moves all elements with indices [start+num .. ]. + // Calling this routine inside a loop can cause quadratic behavior. + void DeleteSubrange(int start, int num); + + void Clear(); + void MergeFrom(const RepeatedPtrField& other); + void CopyFrom(const RepeatedPtrField& other); + + // Reserve space to expand the field to at least the given size. This only + // resizes the pointer array; it doesn't allocate any objects. If the + // array is grown, it will always be at least doubled in size. + void Reserve(int new_size); + + int Capacity() const; + + // Gets the underlying array. This pointer is possibly invalidated by + // any add or remove operation. + Element** mutable_data(); + const Element* const* data() const; + + // Swap entire contents with "other". + void Swap(RepeatedPtrField* other); + + // Swap two elements. + void SwapElements(int index1, int index2); + + // STL-like iterator support + typedef internal::RepeatedPtrIterator iterator; + typedef internal::RepeatedPtrIterator const_iterator; + typedef Element value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef int size_type; + typedef ptrdiff_t difference_type; + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + // Reverse iterator support + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + reverse_iterator rbegin() { + return reverse_iterator(end()); + } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { + return reverse_iterator(begin()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + // Custom STL-like iterator that iterates over and returns the underlying + // pointers to Element rather than Element itself. + typedef internal::RepeatedPtrOverPtrsIterator + pointer_iterator; + typedef internal::RepeatedPtrOverPtrsIterator + const_pointer_iterator; + pointer_iterator pointer_begin(); + const_pointer_iterator pointer_begin() const; + pointer_iterator pointer_end(); + const_pointer_iterator pointer_end() const; + + // Returns (an estimate of) the number of bytes used by the repeated field, + // excluding sizeof(*this). + int SpaceUsedExcludingSelf() const; + + // Advanced memory management -------------------------------------- + // When hardcore memory management becomes necessary -- as it sometimes + // does here at Google -- the following methods may be useful. + + // Add an already-allocated object, passing ownership to the + // RepeatedPtrField. + void AddAllocated(Element* value); + // Remove the last element and return it, passing ownership to the caller. + // Requires: size() > 0 + Element* ReleaseLast(); + + // Extract elements with indices in the range "[start .. start+num-1]". + // The caller assumes ownership of the extracted elements and is responsible + // for deleting them when they are no longer needed. + // If "elements" is non-NULL, then pointers to the extracted elements + // are stored in "elements[0 .. num-1]" for the convenience of the caller. + // If "elements" is NULL, then the caller must use some other mechanism + // to perform any further operations (like deletion) on these elements. + // Caution: implementation also moves elements with indices [start+num ..]. + // Calling this routine inside a loop can cause quadratic behavior. + void ExtractSubrange(int start, int num, Element** elements); + + // When elements are removed by calls to RemoveLast() or Clear(), they + // are not actually freed. Instead, they are cleared and kept so that + // they can be reused later. This can save lots of CPU time when + // repeatedly reusing a protocol message for similar purposes. + // + // Hardcore programs may choose to manipulate these cleared objects + // to better optimize memory management using the following routines. + + // Get the number of cleared objects that are currently being kept + // around for reuse. + int ClearedCount() const; + // Add an element to the pool of cleared objects, passing ownership to + // the RepeatedPtrField. The element must be cleared prior to calling + // this method. + void AddCleared(Element* value); + // Remove a single element from the cleared pool and return it, passing + // ownership to the caller. The element is guaranteed to be cleared. + // Requires: ClearedCount() > 0 + Element* ReleaseCleared(); + + protected: + // Note: RepeatedPtrField SHOULD NOT be subclassed by users. We only + // subclass it in one place as a hack for compatibility with proto1. The + // subclass needs to know about TypeHandler in order to call protected + // methods on RepeatedPtrFieldBase. + class TypeHandler; + +}; + +// implementation ==================================================== + +template +inline RepeatedField::RepeatedField() + : elements_(NULL), + current_size_(0), + total_size_(kInitialSize) { +} + +template +inline RepeatedField::RepeatedField(const RepeatedField& other) + : elements_(NULL), + current_size_(0), + total_size_(kInitialSize) { + CopyFrom(other); +} + +template +template +inline RepeatedField::RepeatedField(Iter begin, const Iter& end) + : elements_(NULL), + current_size_(0), + total_size_(kInitialSize) { + for (; begin != end; ++begin) { + Add(*begin); + } +} + +template +RepeatedField::~RepeatedField() { + delete [] elements_; +} + +template +inline RepeatedField& +RepeatedField::operator=(const RepeatedField& other) { + if (this != &other) + CopyFrom(other); + return *this; +} + +template +inline int RepeatedField::size() const { + return current_size_; +} + +template +inline int RepeatedField::Capacity() const { + return total_size_; +} + +template +inline void RepeatedField::AddAlreadyReserved(const Element& value) { + GOOGLE_DCHECK_LT(size(), Capacity()); + elements_[current_size_++] = value; +} + +template +inline Element* RepeatedField::AddAlreadyReserved() { + GOOGLE_DCHECK_LT(size(), Capacity()); + return &elements_[current_size_++]; +} + +template +inline const Element& RepeatedField::Get(int index) const { + GOOGLE_DCHECK_LT(index, size()); + return elements_[index]; +} + +template +inline Element* RepeatedField::Mutable(int index) { + GOOGLE_DCHECK_LT(index, size()); + return elements_ + index; +} + +template +inline void RepeatedField::Set(int index, const Element& value) { + GOOGLE_DCHECK_LT(index, size()); + elements_[index] = value; +} + +template +inline void RepeatedField::Add(const Element& value) { + if (current_size_ == total_size_) Reserve(total_size_ + 1); + elements_[current_size_++] = value; +} + +template +inline Element* RepeatedField::Add() { + if (current_size_ == total_size_) Reserve(total_size_ + 1); + return &elements_[current_size_++]; +} + +template +inline void RepeatedField::RemoveLast() { + GOOGLE_DCHECK_GT(current_size_, 0); + --current_size_; +} + +template +void RepeatedField::ExtractSubrange( + int start, int num, Element* elements) { + GOOGLE_DCHECK_GE(start, 0); + GOOGLE_DCHECK_GE(num, 0); + GOOGLE_DCHECK_LE(start + num, this->size()); + + // Save the values of the removed elements if requested. + if (elements != NULL) { + for (int i = 0; i < num; ++i) + elements[i] = this->Get(i + start); + } + + // Slide remaining elements down to fill the gap. + if (num > 0) { + for (int i = start + num; i < this->size(); ++i) + this->Set(i - num, this->Get(i)); + this->Truncate(this->size() - num); + } +} + +template +inline void RepeatedField::Clear() { + current_size_ = 0; +} + +template +inline void RepeatedField::MergeFrom(const RepeatedField& other) { + if (other.current_size_ != 0) { + Reserve(current_size_ + other.current_size_); + CopyArray(elements_ + current_size_, other.elements_, other.current_size_); + current_size_ += other.current_size_; + } +} + +template +inline void RepeatedField::CopyFrom(const RepeatedField& other) { + Clear(); + MergeFrom(other); +} + +template +inline Element* RepeatedField::mutable_data() { + return elements_; +} + +template +inline const Element* RepeatedField::data() const { + return elements_; +} + + +template +void RepeatedField::Swap(RepeatedField* other) { + if (this == other) return; + Element* swap_elements = elements_; + int swap_current_size = current_size_; + int swap_total_size = total_size_; + + elements_ = other->elements_; + current_size_ = other->current_size_; + total_size_ = other->total_size_; + + other->elements_ = swap_elements; + other->current_size_ = swap_current_size; + other->total_size_ = swap_total_size; +} + +template +void RepeatedField::SwapElements(int index1, int index2) { + std::swap(elements_[index1], elements_[index2]); +} + +template +inline typename RepeatedField::iterator +RepeatedField::begin() { + return elements_; +} +template +inline typename RepeatedField::const_iterator +RepeatedField::begin() const { + return elements_; +} +template +inline typename RepeatedField::iterator +RepeatedField::end() { + return elements_ + current_size_; +} +template +inline typename RepeatedField::const_iterator +RepeatedField::end() const { + return elements_ + current_size_; +} + +template +inline int RepeatedField::SpaceUsedExcludingSelf() const { + return (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0; +} + +// Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant +// amount of code bloat. +template +void RepeatedField::Reserve(int new_size) { + if (total_size_ >= new_size) return; + + Element* old_elements = elements_; + total_size_ = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize, + max(total_size_ * 2, new_size)); + elements_ = new Element[total_size_]; + if (old_elements != NULL) { + MoveArray(elements_, old_elements, current_size_); + delete [] old_elements; + } +} + +template +inline void RepeatedField::Truncate(int new_size) { + GOOGLE_DCHECK_LE(new_size, current_size_); + current_size_ = new_size; +} + +template +inline void RepeatedField::MoveArray( + Element to[], Element from[], int array_size) { + CopyArray(to, from, array_size); +} + +template +inline void RepeatedField::CopyArray( + Element to[], const Element from[], int array_size) { + internal::ElementCopier()(to, from, array_size); +} + +namespace internal { + +template +void ElementCopier::operator()( + Element to[], const Element from[], int array_size) { + std::copy(from, from + array_size, to); +} + +template +struct ElementCopier { + void operator()(Element to[], const Element from[], int array_size) { + memcpy(to, from, array_size * sizeof(Element)); + } +}; + +} // namespace internal + + +// ------------------------------------------------------------------- + +namespace internal { + +inline RepeatedPtrFieldBase::RepeatedPtrFieldBase() + : elements_(NULL), + current_size_(0), + allocated_size_(0), + total_size_(kInitialSize) { +} + +template +void RepeatedPtrFieldBase::Destroy() { + for (int i = 0; i < allocated_size_; i++) { + TypeHandler::Delete(cast(elements_[i])); + } + delete [] elements_; +} + +inline int RepeatedPtrFieldBase::size() const { + return current_size_; +} + +template +inline const typename TypeHandler::Type& +RepeatedPtrFieldBase::Get(int index) const { + GOOGLE_DCHECK_LT(index, size()); + return *cast(elements_[index]); +} + + +template +inline typename TypeHandler::Type* +RepeatedPtrFieldBase::Mutable(int index) { + GOOGLE_DCHECK_LT(index, size()); + return cast(elements_[index]); +} + +template +inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() { + if (current_size_ < allocated_size_) { + return cast(elements_[current_size_++]); + } + if (allocated_size_ == total_size_) Reserve(total_size_ + 1); + ++allocated_size_; + typename TypeHandler::Type* result = TypeHandler::New(); + elements_[current_size_++] = result; + return result; +} + +template +inline void RepeatedPtrFieldBase::RemoveLast() { + GOOGLE_DCHECK_GT(current_size_, 0); + TypeHandler::Clear(cast(elements_[--current_size_])); +} + +template +void RepeatedPtrFieldBase::Clear() { + for (int i = 0; i < current_size_; i++) { + TypeHandler::Clear(cast(elements_[i])); + } + current_size_ = 0; +} + +template +inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) { + Reserve(current_size_ + other.current_size_); + for (int i = 0; i < other.current_size_; i++) { + TypeHandler::Merge(other.template Get(i), Add()); + } +} + +template +inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) { + RepeatedPtrFieldBase::Clear(); + RepeatedPtrFieldBase::MergeFrom(other); +} + +inline int RepeatedPtrFieldBase::Capacity() const { + return total_size_; +} + +inline void* const* RepeatedPtrFieldBase::raw_data() const { + return elements_; +} + +inline void** RepeatedPtrFieldBase::raw_mutable_data() const { + return elements_; +} + +template +inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() { + // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this + // method entirely. + return reinterpret_cast(elements_); +} + +template +inline const typename TypeHandler::Type* const* +RepeatedPtrFieldBase::data() const { + // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this + // method entirely. + return reinterpret_cast(elements_); +} + +inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) { + std::swap(elements_[index1], elements_[index2]); +} + +template +inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const { + int allocated_bytes = + (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0; + for (int i = 0; i < allocated_size_; ++i) { + allocated_bytes += TypeHandler::SpaceUsed(*cast(elements_[i])); + } + return allocated_bytes; +} + +template +inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() { + if (current_size_ < allocated_size_) { + return cast(elements_[current_size_++]); + } else { + return NULL; + } +} + +template +void RepeatedPtrFieldBase::AddAllocated( + typename TypeHandler::Type* value) { + // Make room for the new pointer. + if (current_size_ == total_size_) { + // The array is completely full with no cleared objects, so grow it. + Reserve(total_size_ + 1); + ++allocated_size_; + } else if (allocated_size_ == total_size_) { + // There is no more space in the pointer array because it contains some + // cleared objects awaiting reuse. We don't want to grow the array in this + // case because otherwise a loop calling AddAllocated() followed by Clear() + // would leak memory. + TypeHandler::Delete(cast(elements_[current_size_])); + } else if (current_size_ < allocated_size_) { + // We have some cleared objects. We don't care about their order, so we + // can just move the first one to the end to make space. + elements_[allocated_size_] = elements_[current_size_]; + ++allocated_size_; + } else { + // There are no cleared objects. + ++allocated_size_; + } + + elements_[current_size_++] = value; +} + +template +inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() { + GOOGLE_DCHECK_GT(current_size_, 0); + typename TypeHandler::Type* result = + cast(elements_[--current_size_]); + --allocated_size_; + if (current_size_ < allocated_size_) { + // There are cleared elements on the end; replace the removed element + // with the last allocated element. + elements_[current_size_] = elements_[allocated_size_]; + } + return result; +} + +inline int RepeatedPtrFieldBase::ClearedCount() const { + return allocated_size_ - current_size_; +} + +template +inline void RepeatedPtrFieldBase::AddCleared( + typename TypeHandler::Type* value) { + if (allocated_size_ == total_size_) Reserve(total_size_ + 1); + elements_[allocated_size_++] = value; +} + +template +inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() { + GOOGLE_DCHECK_GT(allocated_size_, current_size_); + return cast(elements_[--allocated_size_]); +} + +} // namespace internal + +// ------------------------------------------------------------------- + +template +class RepeatedPtrField::TypeHandler + : public internal::GenericTypeHandler { +}; + +template <> +class RepeatedPtrField::TypeHandler + : public internal::StringTypeHandler { +}; + + +template +inline RepeatedPtrField::RepeatedPtrField() {} + +template +inline RepeatedPtrField::RepeatedPtrField( + const RepeatedPtrField& other) { + CopyFrom(other); +} + +template +template +inline RepeatedPtrField::RepeatedPtrField( + Iter begin, const Iter& end) { + for (; begin != end; ++begin) { + *Add() = *begin; + } +} + +template +RepeatedPtrField::~RepeatedPtrField() { + Destroy(); +} + +template +inline RepeatedPtrField& RepeatedPtrField::operator=( + const RepeatedPtrField& other) { + if (this != &other) + CopyFrom(other); + return *this; +} + +template +inline int RepeatedPtrField::size() const { + return RepeatedPtrFieldBase::size(); +} + +template +inline const Element& RepeatedPtrField::Get(int index) const { + return RepeatedPtrFieldBase::Get(index); +} + + +template +inline Element* RepeatedPtrField::Mutable(int index) { + return RepeatedPtrFieldBase::Mutable(index); +} + +template +inline Element* RepeatedPtrField::Add() { + return RepeatedPtrFieldBase::Add(); +} + +template +inline void RepeatedPtrField::RemoveLast() { + RepeatedPtrFieldBase::RemoveLast(); +} + +template +inline void RepeatedPtrField::DeleteSubrange(int start, int num) { + GOOGLE_DCHECK_GE(start, 0); + GOOGLE_DCHECK_GE(num, 0); + GOOGLE_DCHECK_LE(start + num, size()); + for (int i = 0; i < num; ++i) + delete RepeatedPtrFieldBase::Mutable(start + i); + ExtractSubrange(start, num, NULL); +} + +template +inline void RepeatedPtrField::ExtractSubrange( + int start, int num, Element** elements) { + GOOGLE_DCHECK_GE(start, 0); + GOOGLE_DCHECK_GE(num, 0); + GOOGLE_DCHECK_LE(start + num, size()); + + if (num > 0) { + // Save the values of the removed elements if requested. + if (elements != NULL) { + for (int i = 0; i < num; ++i) + elements[i] = RepeatedPtrFieldBase::Mutable(i + start); + } + CloseGap(start, num); + } +} + +template +inline void RepeatedPtrField::Clear() { + RepeatedPtrFieldBase::Clear(); +} + +template +inline void RepeatedPtrField::MergeFrom( + const RepeatedPtrField& other) { + RepeatedPtrFieldBase::MergeFrom(other); +} + +template +inline void RepeatedPtrField::CopyFrom( + const RepeatedPtrField& other) { + RepeatedPtrFieldBase::CopyFrom(other); +} + +template +inline Element** RepeatedPtrField::mutable_data() { + return RepeatedPtrFieldBase::mutable_data(); +} + +template +inline const Element* const* RepeatedPtrField::data() const { + return RepeatedPtrFieldBase::data(); +} + +template +void RepeatedPtrField::Swap(RepeatedPtrField* other) { + RepeatedPtrFieldBase::Swap(other); +} + +template +void RepeatedPtrField::SwapElements(int index1, int index2) { + RepeatedPtrFieldBase::SwapElements(index1, index2); +} + +template +inline int RepeatedPtrField::SpaceUsedExcludingSelf() const { + return RepeatedPtrFieldBase::SpaceUsedExcludingSelf(); +} + +template +inline void RepeatedPtrField::AddAllocated(Element* value) { + RepeatedPtrFieldBase::AddAllocated(value); +} + +template +inline Element* RepeatedPtrField::ReleaseLast() { + return RepeatedPtrFieldBase::ReleaseLast(); +} + + +template +inline int RepeatedPtrField::ClearedCount() const { + return RepeatedPtrFieldBase::ClearedCount(); +} + +template +inline void RepeatedPtrField::AddCleared(Element* value) { + return RepeatedPtrFieldBase::AddCleared(value); +} + +template +inline Element* RepeatedPtrField::ReleaseCleared() { + return RepeatedPtrFieldBase::ReleaseCleared(); +} + +template +inline void RepeatedPtrField::Reserve(int new_size) { + return RepeatedPtrFieldBase::Reserve(new_size); +} + +template +inline int RepeatedPtrField::Capacity() const { + return RepeatedPtrFieldBase::Capacity(); +} + +// ------------------------------------------------------------------- + +namespace internal { + +// STL-like iterator implementation for RepeatedPtrField. You should not +// refer to this class directly; use RepeatedPtrField::iterator instead. +// +// The iterator for RepeatedPtrField, RepeatedPtrIterator, is +// very similar to iterator_ptr in util/gtl/iterator_adaptors.h, +// but adds random-access operators and is modified to wrap a void** base +// iterator (since RepeatedPtrField stores its array as a void* array and +// casting void** to T** would violate C++ aliasing rules). +// +// This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin +// (jyasskin@google.com). +template +class RepeatedPtrIterator + : public std::iterator< + std::random_access_iterator_tag, Element> { + public: + typedef RepeatedPtrIterator iterator; + typedef std::iterator< + std::random_access_iterator_tag, Element> superclass; + + // Let the compiler know that these are type names, so we don't have to + // write "typename" in front of them everywhere. + typedef typename superclass::reference reference; + typedef typename superclass::pointer pointer; + typedef typename superclass::difference_type difference_type; + + RepeatedPtrIterator() : it_(NULL) {} + explicit RepeatedPtrIterator(void* const* it) : it_(it) {} + + // Allow "upcasting" from RepeatedPtrIterator to + // RepeatedPtrIterator. + template + RepeatedPtrIterator(const RepeatedPtrIterator& other) + : it_(other.it_) { + // Force a compiler error if the other type is not convertible to ours. + if (false) { + implicit_cast(0); + } + } + + // dereferenceable + reference operator*() const { return *reinterpret_cast(*it_); } + pointer operator->() const { return &(operator*()); } + + // {inc,dec}rementable + iterator& operator++() { ++it_; return *this; } + iterator operator++(int) { return iterator(it_++); } + iterator& operator--() { --it_; return *this; } + iterator operator--(int) { return iterator(it_--); } + + // equality_comparable + bool operator==(const iterator& x) const { return it_ == x.it_; } + bool operator!=(const iterator& x) const { return it_ != x.it_; } + + // less_than_comparable + bool operator<(const iterator& x) const { return it_ < x.it_; } + bool operator<=(const iterator& x) const { return it_ <= x.it_; } + bool operator>(const iterator& x) const { return it_ > x.it_; } + bool operator>=(const iterator& x) const { return it_ >= x.it_; } + + // addable, subtractable + iterator& operator+=(difference_type d) { + it_ += d; + return *this; + } + friend iterator operator+(iterator it, difference_type d) { + it += d; + return it; + } + friend iterator operator+(difference_type d, iterator it) { + it += d; + return it; + } + iterator& operator-=(difference_type d) { + it_ -= d; + return *this; + } + friend iterator operator-(iterator it, difference_type d) { + it -= d; + return it; + } + + // indexable + reference operator[](difference_type d) const { return *(*this + d); } + + // random access iterator + difference_type operator-(const iterator& x) const { return it_ - x.it_; } + + private: + template + friend class RepeatedPtrIterator; + + // The internal iterator. + void* const* it_; +}; + +// Provide an iterator that operates on pointers to the underlying objects +// rather than the objects themselves as RepeatedPtrIterator does. +// Consider using this when working with stl algorithms that change +// the array. +// The VoidPtr template parameter holds the type-agnostic pointer value +// referenced by the iterator. It should either be "void *" for a mutable +// iterator, or "const void *" for a constant iterator. +template +class RepeatedPtrOverPtrsIterator + : public std::iterator { + public: + typedef RepeatedPtrOverPtrsIterator iterator; + typedef std::iterator< + std::random_access_iterator_tag, Element*> superclass; + + // Let the compiler know that these are type names, so we don't have to + // write "typename" in front of them everywhere. + typedef typename superclass::reference reference; + typedef typename superclass::pointer pointer; + typedef typename superclass::difference_type difference_type; + + RepeatedPtrOverPtrsIterator() : it_(NULL) {} + explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {} + + // dereferenceable + reference operator*() const { return *reinterpret_cast(it_); } + pointer operator->() const { return &(operator*()); } + + // {inc,dec}rementable + iterator& operator++() { ++it_; return *this; } + iterator operator++(int) { return iterator(it_++); } + iterator& operator--() { --it_; return *this; } + iterator operator--(int) { return iterator(it_--); } + + // equality_comparable + bool operator==(const iterator& x) const { return it_ == x.it_; } + bool operator!=(const iterator& x) const { return it_ != x.it_; } + + // less_than_comparable + bool operator<(const iterator& x) const { return it_ < x.it_; } + bool operator<=(const iterator& x) const { return it_ <= x.it_; } + bool operator>(const iterator& x) const { return it_ > x.it_; } + bool operator>=(const iterator& x) const { return it_ >= x.it_; } + + // addable, subtractable + iterator& operator+=(difference_type d) { + it_ += d; + return *this; + } + friend iterator operator+(iterator it, difference_type d) { + it += d; + return it; + } + friend iterator operator+(difference_type d, iterator it) { + it += d; + return it; + } + iterator& operator-=(difference_type d) { + it_ -= d; + return *this; + } + friend iterator operator-(iterator it, difference_type d) { + it -= d; + return it; + } + + // indexable + reference operator[](difference_type d) const { return *(*this + d); } + + // random access iterator + difference_type operator-(const iterator& x) const { return it_ - x.it_; } + + private: + template + friend class RepeatedPtrIterator; + + // The internal iterator. + VoidPtr* it_; +}; + +} // namespace internal + +template +inline typename RepeatedPtrField::iterator +RepeatedPtrField::begin() { + return iterator(raw_data()); +} +template +inline typename RepeatedPtrField::const_iterator +RepeatedPtrField::begin() const { + return iterator(raw_data()); +} +template +inline typename RepeatedPtrField::iterator +RepeatedPtrField::end() { + return iterator(raw_data() + size()); +} +template +inline typename RepeatedPtrField::const_iterator +RepeatedPtrField::end() const { + return iterator(raw_data() + size()); +} + +template +inline typename RepeatedPtrField::pointer_iterator +RepeatedPtrField::pointer_begin() { + return pointer_iterator(raw_mutable_data()); +} +template +inline typename RepeatedPtrField::const_pointer_iterator +RepeatedPtrField::pointer_begin() const { + return const_pointer_iterator(const_cast(raw_mutable_data())); +} +template +inline typename RepeatedPtrField::pointer_iterator +RepeatedPtrField::pointer_end() { + return pointer_iterator(raw_mutable_data() + size()); +} +template +inline typename RepeatedPtrField::const_pointer_iterator +RepeatedPtrField::pointer_end() const { + return const_pointer_iterator( + const_cast(raw_mutable_data() + size())); +} + + +// Iterators and helper functions that follow the spirit of the STL +// std::back_insert_iterator and std::back_inserter but are tailor-made +// for RepeatedField and RepatedPtrField. Typical usage would be: +// +// std::copy(some_sequence.begin(), some_sequence.end(), +// google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence())); +// +// Ported by johannes from util/gtl/proto-array-iterators.h + +namespace internal { +// A back inserter for RepeatedField objects. +template class RepeatedFieldBackInsertIterator + : public std::iterator { + public: + explicit RepeatedFieldBackInsertIterator( + RepeatedField* const mutable_field) + : field_(mutable_field) { + } + RepeatedFieldBackInsertIterator& operator=(const T& value) { + field_->Add(value); + return *this; + } + RepeatedFieldBackInsertIterator& operator*() { + return *this; + } + RepeatedFieldBackInsertIterator& operator++() { + return *this; + } + RepeatedFieldBackInsertIterator& operator++(int /* unused */) { + return *this; + } + + private: + RepeatedField* field_; +}; + +// A back inserter for RepeatedPtrField objects. +template class RepeatedPtrFieldBackInsertIterator + : public std::iterator { + public: + RepeatedPtrFieldBackInsertIterator( + RepeatedPtrField* const mutable_field) + : field_(mutable_field) { + } + RepeatedPtrFieldBackInsertIterator& operator=(const T& value) { + *field_->Add() = value; + return *this; + } + RepeatedPtrFieldBackInsertIterator& operator=( + const T* const ptr_to_value) { + *field_->Add() = *ptr_to_value; + return *this; + } + RepeatedPtrFieldBackInsertIterator& operator*() { + return *this; + } + RepeatedPtrFieldBackInsertIterator& operator++() { + return *this; + } + RepeatedPtrFieldBackInsertIterator& operator++(int /* unused */) { + return *this; + } + + private: + RepeatedPtrField* field_; +}; + +// A back inserter for RepeatedPtrFields that inserts by transfering ownership +// of a pointer. +template class AllocatedRepeatedPtrFieldBackInsertIterator + : public std::iterator { + public: + explicit AllocatedRepeatedPtrFieldBackInsertIterator( + RepeatedPtrField* const mutable_field) + : field_(mutable_field) { + } + AllocatedRepeatedPtrFieldBackInsertIterator& operator=( + T* const ptr_to_value) { + field_->AddAllocated(ptr_to_value); + return *this; + } + AllocatedRepeatedPtrFieldBackInsertIterator& operator*() { + return *this; + } + AllocatedRepeatedPtrFieldBackInsertIterator& operator++() { + return *this; + } + AllocatedRepeatedPtrFieldBackInsertIterator& operator++( + int /* unused */) { + return *this; + } + + private: + RepeatedPtrField* field_; +}; +} // namespace internal + +// Provides a back insert iterator for RepeatedField instances, +// similar to std::back_inserter(). +template internal::RepeatedFieldBackInsertIterator +RepeatedFieldBackInserter(RepeatedField* const mutable_field) { + return internal::RepeatedFieldBackInsertIterator(mutable_field); +} + +// Provides a back insert iterator for RepeatedPtrField instances, +// similar to std::back_inserter(). +template internal::RepeatedPtrFieldBackInsertIterator +RepeatedPtrFieldBackInserter(RepeatedPtrField* const mutable_field) { + return internal::RepeatedPtrFieldBackInsertIterator(mutable_field); +} + +// Special back insert iterator for RepeatedPtrField instances, just in +// case someone wants to write generic template code that can access both +// RepeatedFields and RepeatedPtrFields using a common name. +template internal::RepeatedPtrFieldBackInsertIterator +RepeatedFieldBackInserter(RepeatedPtrField* const mutable_field) { + return internal::RepeatedPtrFieldBackInsertIterator(mutable_field); +} + +// Provides a back insert iterator for RepeatedPtrField instances +// similar to std::back_inserter() which transfers the ownership while +// copying elements. +template internal::AllocatedRepeatedPtrFieldBackInsertIterator +AllocatedRepeatedPtrFieldBackInserter( + RepeatedPtrField* const mutable_field) { + return internal::AllocatedRepeatedPtrFieldBackInsertIterator( + mutable_field); +} + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field_reflection_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field_reflection_unittest.cc new file mode 100644 index 0000000..a40162d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field_reflection_unittest.cc @@ -0,0 +1,195 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: tgs@google.com (Tom Szymanski) +// +// Test reflection methods for aggregate access to Repeated[Ptr]Fields. +// This test proto2 methods on a proto2 layout. + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +using unittest::ForeignMessage; +using unittest::TestAllTypes; +using unittest::TestAllExtensions; + +namespace { + +static int Func(int i, int j) { + return i * j; +} + +static string StrFunc(int i, int j) { + string str; + SStringPrintf(&str, "%d", Func(i, 4)); + return str; +} + + +TEST(RepeatedFieldReflectionTest, RegularFields) { + TestAllTypes message; + const Reflection* refl = message.GetReflection(); + const Descriptor* desc = message.GetDescriptor(); + + for (int i = 0; i < 10; ++i) { + message.add_repeated_int32(Func(i, 1)); + message.add_repeated_double(Func(i, 2)); + message.add_repeated_string(StrFunc(i, 5)); + message.add_repeated_foreign_message()->set_c(Func(i, 6)); + } + + // Get FieldDescriptors for all the fields of interest. + const FieldDescriptor* fd_repeated_int32 = + desc->FindFieldByName("repeated_int32"); + const FieldDescriptor* fd_repeated_double = + desc->FindFieldByName("repeated_double"); + const FieldDescriptor* fd_repeated_string = + desc->FindFieldByName("repeated_string"); + const FieldDescriptor* fd_repeated_foreign_message = + desc->FindFieldByName("repeated_foreign_message"); + + // Get RepeatedField objects for all fields of interest. + const RepeatedField& rf_int32 = + refl->GetRepeatedField(message, fd_repeated_int32); + const RepeatedField& rf_double = + refl->GetRepeatedField(message, fd_repeated_double); + + // Get mutable RepeatedField objects for all fields of interest. + RepeatedField* mrf_int32 = + refl->MutableRepeatedField(&message, fd_repeated_int32); + RepeatedField* mrf_double = + refl->MutableRepeatedField(&message, fd_repeated_double); + + // Get RepeatedPtrField objects for all fields of interest. + const RepeatedPtrField& rpf_string = + refl->GetRepeatedPtrField(message, fd_repeated_string); + const RepeatedPtrField& rpf_foreign_message = + refl->GetRepeatedPtrField( + message, fd_repeated_foreign_message); + const RepeatedPtrField& rpf_message = + refl->GetRepeatedPtrField( + message, fd_repeated_foreign_message); + + // Get mutable RepeatedPtrField objects for all fields of interest. + RepeatedPtrField* mrpf_string = + refl->MutableRepeatedPtrField(&message, fd_repeated_string); + RepeatedPtrField* mrpf_foreign_message = + refl->MutableRepeatedPtrField( + &message, fd_repeated_foreign_message); + RepeatedPtrField* mrpf_message = + refl->MutableRepeatedPtrField( + &message, fd_repeated_foreign_message); + + // Make sure we can do get and sets through the Repeated[Ptr]Field objects. + for (int i = 0; i < 10; ++i) { + // Check gets through const objects. + EXPECT_EQ(rf_int32.Get(i), Func(i, 1)); + EXPECT_EQ(rf_double.Get(i), Func(i, 2)); + EXPECT_EQ(rpf_string.Get(i), StrFunc(i, 5)); + EXPECT_EQ(rpf_foreign_message.Get(i).c(), Func(i, 6)); + EXPECT_EQ(down_cast(&rpf_message.Get(i))->c(), + Func(i, 6)); + + // Check gets through mutable objects. + EXPECT_EQ(mrf_int32->Get(i), Func(i, 1)); + EXPECT_EQ(mrf_double->Get(i), Func(i, 2)); + EXPECT_EQ(mrpf_string->Get(i), StrFunc(i, 5)); + EXPECT_EQ(mrpf_foreign_message->Get(i).c(), Func(i, 6)); + EXPECT_EQ(down_cast(&mrpf_message->Get(i))->c(), + Func(i, 6)); + + // Check sets through mutable objects. + mrf_int32->Set(i, Func(i, -1)); + mrf_double->Set(i, Func(i, -2)); + mrpf_string->Mutable(i)->assign(StrFunc(i, -5)); + mrpf_foreign_message->Mutable(i)->set_c(Func(i, -6)); + EXPECT_EQ(message.repeated_int32(i), Func(i, -1)); + EXPECT_EQ(message.repeated_double(i), Func(i, -2)); + EXPECT_EQ(message.repeated_string(i), StrFunc(i, -5)); + EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, -6)); + down_cast(mrpf_message->Mutable(i))->set_c(Func(i, 7)); + EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7)); + } + +#ifdef PROTOBUF_HAS_DEATH_TEST + // Make sure types are checked correctly at runtime. + const FieldDescriptor* fd_optional_int32 = + desc->FindFieldByName("optional_int32"); + EXPECT_DEATH(refl->GetRepeatedField( + message, fd_optional_int32), "requires a repeated field"); + EXPECT_DEATH(refl->GetRepeatedField( + message, fd_repeated_int32), "not the right type"); + EXPECT_DEATH(refl->GetRepeatedPtrField( + message, fd_repeated_foreign_message), "wrong submessage type"); +#endif // PROTOBUF_HAS_DEATH_TEST +} + + + + +TEST(RepeatedFieldReflectionTest, ExtensionFields) { + TestAllExtensions extended_message; + const Reflection* refl = extended_message.GetReflection(); + const Descriptor* desc = extended_message.GetDescriptor(); + + for (int i = 0; i < 10; ++i) { + extended_message.AddExtension( + unittest::repeated_int64_extension, Func(i, 1)); + } + + const FieldDescriptor* fd_repeated_int64_extension = + desc->file()->FindExtensionByName("repeated_int64_extension"); + GOOGLE_CHECK(fd_repeated_int64_extension != NULL); + + const RepeatedField& rf_int64_extension = + refl->GetRepeatedField(extended_message, + fd_repeated_int64_extension); + + RepeatedField* mrf_int64_extension = + refl->MutableRepeatedField(&extended_message, + fd_repeated_int64_extension); + + for (int i = 0; i < 10; ++i) { + EXPECT_EQ(Func(i, 1), rf_int64_extension.Get(i)); + mrf_int64_extension->Set(i, Func(i, -1)); + EXPECT_EQ(Func(i, -1), + extended_message.GetExtension(unittest::repeated_int64_extension, i)); + } +} + +} // namespace +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field_unittest.cc new file mode 100644 index 0000000..257701e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/repeated_field_unittest.cc @@ -0,0 +1,1357 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// TODO(kenton): Improve this unittest to bring it up to the standards of +// other proto2 unittests. + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace google { +using protobuf_unittest::TestAllTypes; + +namespace protobuf { +namespace { + +// Test operations on a small RepeatedField. +TEST(RepeatedField, Small) { + RepeatedField field; + + EXPECT_EQ(field.size(), 0); + + field.Add(5); + + EXPECT_EQ(field.size(), 1); + EXPECT_EQ(field.Get(0), 5); + + field.Add(42); + + EXPECT_EQ(field.size(), 2); + EXPECT_EQ(field.Get(0), 5); + EXPECT_EQ(field.Get(1), 42); + + field.Set(1, 23); + + EXPECT_EQ(field.size(), 2); + EXPECT_EQ(field.Get(0), 5); + EXPECT_EQ(field.Get(1), 23); + + field.RemoveLast(); + + EXPECT_EQ(field.size(), 1); + EXPECT_EQ(field.Get(0), 5); + + field.Clear(); + + EXPECT_EQ(field.size(), 0); + int expected_usage = 4 * sizeof(int); + EXPECT_EQ(field.SpaceUsedExcludingSelf(), expected_usage); +} + + +// Test operations on a RepeatedField which is large enough to allocate a +// separate array. +TEST(RepeatedField, Large) { + RepeatedField field; + + for (int i = 0; i < 16; i++) { + field.Add(i * i); + } + + EXPECT_EQ(field.size(), 16); + + for (int i = 0; i < 16; i++) { + EXPECT_EQ(field.Get(i), i * i); + } + + int expected_usage = 16 * sizeof(int); + EXPECT_GE(field.SpaceUsedExcludingSelf(), expected_usage); +} + +// Test swapping between various types of RepeatedFields. +TEST(RepeatedField, SwapSmallSmall) { + RepeatedField field1; + RepeatedField field2; + + field1.Add(5); + field1.Add(42); + + field1.Swap(&field2); + + EXPECT_EQ(field1.size(), 0); + EXPECT_EQ(field2.size(), 2); + EXPECT_EQ(field2.Get(0), 5); + EXPECT_EQ(field2.Get(1), 42); +} + +TEST(RepeatedField, SwapLargeSmall) { + RepeatedField field1; + RepeatedField field2; + + for (int i = 0; i < 16; i++) { + field1.Add(i * i); + } + field2.Add(5); + field2.Add(42); + field1.Swap(&field2); + + EXPECT_EQ(field1.size(), 2); + EXPECT_EQ(field1.Get(0), 5); + EXPECT_EQ(field1.Get(1), 42); + EXPECT_EQ(field2.size(), 16); + for (int i = 0; i < 16; i++) { + EXPECT_EQ(field2.Get(i), i * i); + } +} + +TEST(RepeatedField, SwapLargeLarge) { + RepeatedField field1; + RepeatedField field2; + + field1.Add(5); + field1.Add(42); + for (int i = 0; i < 16; i++) { + field1.Add(i); + field2.Add(i * i); + } + field2.Swap(&field1); + + EXPECT_EQ(field1.size(), 16); + for (int i = 0; i < 16; i++) { + EXPECT_EQ(field1.Get(i), i * i); + } + EXPECT_EQ(field2.size(), 18); + EXPECT_EQ(field2.Get(0), 5); + EXPECT_EQ(field2.Get(1), 42); + for (int i = 2; i < 18; i++) { + EXPECT_EQ(field2.Get(i), i - 2); + } +} + +// Determines how much space was reserved by the given field by adding elements +// to it until it re-allocates its space. +static int ReservedSpace(RepeatedField* field) { + const int* ptr = field->data(); + do { + field->Add(0); + } while (field->data() == ptr); + + return field->size() - 1; +} + +TEST(RepeatedField, ReserveMoreThanDouble) { + // Reserve more than double the previous space in the field and expect the + // field to reserve exactly the amount specified. + RepeatedField field; + field.Reserve(20); + + EXPECT_EQ(20, ReservedSpace(&field)); +} + +TEST(RepeatedField, ReserveLessThanDouble) { + // Reserve less than double the previous space in the field and expect the + // field to grow by double instead. + RepeatedField field; + field.Reserve(20); + field.Reserve(30); + + EXPECT_EQ(40, ReservedSpace(&field)); +} + +TEST(RepeatedField, ReserveLessThanExisting) { + // Reserve less than the previous space in the field and expect the + // field to not re-allocate at all. + RepeatedField field; + field.Reserve(20); + const int* previous_ptr = field.data(); + field.Reserve(10); + + EXPECT_EQ(previous_ptr, field.data()); + EXPECT_EQ(20, ReservedSpace(&field)); +} + +TEST(RepeatedField, MergeFrom) { + RepeatedField source, destination; + source.Add(4); + source.Add(5); + destination.Add(1); + destination.Add(2); + destination.Add(3); + + destination.MergeFrom(source); + + ASSERT_EQ(5, destination.size()); + EXPECT_EQ(1, destination.Get(0)); + EXPECT_EQ(2, destination.Get(1)); + EXPECT_EQ(3, destination.Get(2)); + EXPECT_EQ(4, destination.Get(3)); + EXPECT_EQ(5, destination.Get(4)); +} + +TEST(RepeatedField, CopyFrom) { + RepeatedField source, destination; + source.Add(4); + source.Add(5); + destination.Add(1); + destination.Add(2); + destination.Add(3); + + destination.CopyFrom(source); + + ASSERT_EQ(2, destination.size()); + EXPECT_EQ(4, destination.Get(0)); + EXPECT_EQ(5, destination.Get(1)); +} + +TEST(RepeatedField, CopyConstruct) { + RepeatedField source; + source.Add(1); + source.Add(2); + + RepeatedField destination(source); + + ASSERT_EQ(2, destination.size()); + EXPECT_EQ(1, destination.Get(0)); + EXPECT_EQ(2, destination.Get(1)); +} + +TEST(RepeatedField, IteratorConstruct) { + vector values; + values.push_back(1); + values.push_back(2); + + RepeatedField field(values.begin(), values.end()); + ASSERT_EQ(values.size(), field.size()); + EXPECT_EQ(values[0], field.Get(0)); + EXPECT_EQ(values[1], field.Get(1)); + + RepeatedField other(field.begin(), field.end()); + ASSERT_EQ(values.size(), other.size()); + EXPECT_EQ(values[0], other.Get(0)); + EXPECT_EQ(values[1], other.Get(1)); +} + +TEST(RepeatedField, CopyAssign) { + RepeatedField source, destination; + source.Add(4); + source.Add(5); + destination.Add(1); + destination.Add(2); + destination.Add(3); + + destination = source; + + ASSERT_EQ(2, destination.size()); + EXPECT_EQ(4, destination.Get(0)); + EXPECT_EQ(5, destination.Get(1)); +} + +TEST(RepeatedField, SelfAssign) { + // Verify that assignment to self does not destroy data. + RepeatedField source, *p; + p = &source; + source.Add(7); + source.Add(8); + + *p = source; + + ASSERT_EQ(2, source.size()); + EXPECT_EQ(7, source.Get(0)); + EXPECT_EQ(8, source.Get(1)); +} + +TEST(RepeatedField, MutableDataIsMutable) { + RepeatedField field; + field.Add(1); + EXPECT_EQ(1, field.Get(0)); + // The fact that this line compiles would be enough, but we'll check the + // value anyway. + *field.mutable_data() = 2; + EXPECT_EQ(2, field.Get(0)); +} + +TEST(RepeatedField, Truncate) { + RepeatedField field; + + field.Add(12); + field.Add(34); + field.Add(56); + field.Add(78); + EXPECT_EQ(4, field.size()); + + field.Truncate(3); + EXPECT_EQ(3, field.size()); + + field.Add(90); + EXPECT_EQ(4, field.size()); + EXPECT_EQ(90, field.Get(3)); + + // Truncations that don't change the size are allowed, but growing is not + // allowed. + field.Truncate(field.size()); +#ifdef PROTOBUF_HAS_DEATH_TEST + EXPECT_DEBUG_DEATH(field.Truncate(field.size() + 1), "new_size"); +#endif +} + + +TEST(RepeatedField, ExtractSubrange) { + // Exhaustively test every subrange in arrays of all sizes from 0 through 9. + for (int sz = 0; sz < 10; ++sz) { + for (int num = 0; num <= sz; ++num) { + for (int start = 0; start < sz - num; ++start) { + // Create RepeatedField with sz elements having values 0 through sz-1. + RepeatedField field; + for (int i = 0; i < sz; ++i) + field.Add(i); + EXPECT_EQ(field.size(), sz); + + // Create a catcher array and call ExtractSubrange. + int32 catcher[10]; + for (int i = 0; i < 10; ++i) + catcher[i] = -1; + field.ExtractSubrange(start, num, catcher); + + // Does the resulting array have the right size? + EXPECT_EQ(field.size(), sz - num); + + // Were the removed elements extracted into the catcher array? + for (int i = 0; i < num; ++i) + EXPECT_EQ(catcher[i], start + i); + EXPECT_EQ(catcher[num], -1); + + // Does the resulting array contain the right values? + for (int i = 0; i < start; ++i) + EXPECT_EQ(field.Get(i), i); + for (int i = start; i < field.size(); ++i) + EXPECT_EQ(field.Get(i), i + num); + } + } + } +} + +// =================================================================== +// RepeatedPtrField tests. These pretty much just mirror the RepeatedField +// tests above. + +TEST(RepeatedPtrField, Small) { + RepeatedPtrField field; + + EXPECT_EQ(field.size(), 0); + + field.Add()->assign("foo"); + + EXPECT_EQ(field.size(), 1); + EXPECT_EQ(field.Get(0), "foo"); + + field.Add()->assign("bar"); + + EXPECT_EQ(field.size(), 2); + EXPECT_EQ(field.Get(0), "foo"); + EXPECT_EQ(field.Get(1), "bar"); + + field.Mutable(1)->assign("baz"); + + EXPECT_EQ(field.size(), 2); + EXPECT_EQ(field.Get(0), "foo"); + EXPECT_EQ(field.Get(1), "baz"); + + field.RemoveLast(); + + EXPECT_EQ(field.size(), 1); + EXPECT_EQ(field.Get(0), "foo"); + + field.Clear(); + + EXPECT_EQ(field.size(), 0); +} + + +TEST(RepeatedPtrField, Large) { + RepeatedPtrField field; + + for (int i = 0; i < 16; i++) { + *field.Add() += 'a' + i; + } + + EXPECT_EQ(field.size(), 16); + + for (int i = 0; i < 16; i++) { + EXPECT_EQ(field.Get(i).size(), 1); + EXPECT_EQ(field.Get(i)[0], 'a' + i); + } + + int min_expected_usage = 16 * sizeof(string); + EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage); +} + +TEST(RepeatedPtrField, SwapSmallSmall) { + RepeatedPtrField field1; + RepeatedPtrField field2; + + field1.Add()->assign("foo"); + field1.Add()->assign("bar"); + field1.Swap(&field2); + + EXPECT_EQ(field1.size(), 0); + EXPECT_EQ(field2.size(), 2); + EXPECT_EQ(field2.Get(0), "foo"); + EXPECT_EQ(field2.Get(1), "bar"); +} + +TEST(RepeatedPtrField, SwapLargeSmall) { + RepeatedPtrField field1; + RepeatedPtrField field2; + + field2.Add()->assign("foo"); + field2.Add()->assign("bar"); + for (int i = 0; i < 16; i++) { + *field1.Add() += 'a' + i; + } + field1.Swap(&field2); + + EXPECT_EQ(field1.size(), 2); + EXPECT_EQ(field1.Get(0), "foo"); + EXPECT_EQ(field1.Get(1), "bar"); + EXPECT_EQ(field2.size(), 16); + for (int i = 0; i < 16; i++) { + EXPECT_EQ(field2.Get(i).size(), 1); + EXPECT_EQ(field2.Get(i)[0], 'a' + i); + } +} + +TEST(RepeatedPtrField, SwapLargeLarge) { + RepeatedPtrField field1; + RepeatedPtrField field2; + + field1.Add()->assign("foo"); + field1.Add()->assign("bar"); + for (int i = 0; i < 16; i++) { + *field1.Add() += 'A' + i; + *field2.Add() += 'a' + i; + } + field2.Swap(&field1); + + EXPECT_EQ(field1.size(), 16); + for (int i = 0; i < 16; i++) { + EXPECT_EQ(field1.Get(i).size(), 1); + EXPECT_EQ(field1.Get(i)[0], 'a' + i); + } + EXPECT_EQ(field2.size(), 18); + EXPECT_EQ(field2.Get(0), "foo"); + EXPECT_EQ(field2.Get(1), "bar"); + for (int i = 2; i < 18; i++) { + EXPECT_EQ(field2.Get(i).size(), 1); + EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2); + } +} + +static int ReservedSpace(RepeatedPtrField* field) { + const string* const* ptr = field->data(); + do { + field->Add(); + } while (field->data() == ptr); + + return field->size() - 1; +} + +TEST(RepeatedPtrField, ReserveMoreThanDouble) { + RepeatedPtrField field; + field.Reserve(20); + + EXPECT_EQ(20, ReservedSpace(&field)); +} + +TEST(RepeatedPtrField, ReserveLessThanDouble) { + RepeatedPtrField field; + field.Reserve(20); + field.Reserve(30); + + EXPECT_EQ(40, ReservedSpace(&field)); +} + +TEST(RepeatedPtrField, ReserveLessThanExisting) { + RepeatedPtrField field; + field.Reserve(20); + const string* const* previous_ptr = field.data(); + field.Reserve(10); + + EXPECT_EQ(previous_ptr, field.data()); + EXPECT_EQ(20, ReservedSpace(&field)); +} + +TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) { + // Check that a bug is fixed: An earlier implementation of Reserve() + // failed to copy pointers to allocated-but-cleared objects, possibly + // leading to segfaults. + RepeatedPtrField field; + string* first = field.Add(); + field.RemoveLast(); + + field.Reserve(20); + EXPECT_EQ(first, field.Add()); +} + +// Clearing elements is tricky with RepeatedPtrFields since the memory for +// the elements is retained and reused. +TEST(RepeatedPtrField, ClearedElements) { + RepeatedPtrField field; + + string* original = field.Add(); + *original = "foo"; + + EXPECT_EQ(field.ClearedCount(), 0); + + field.RemoveLast(); + EXPECT_TRUE(original->empty()); + EXPECT_EQ(field.ClearedCount(), 1); + + EXPECT_EQ(field.Add(), original); // Should return same string for reuse. + + EXPECT_EQ(field.ReleaseLast(), original); // We take ownership. + EXPECT_EQ(field.ClearedCount(), 0); + + EXPECT_NE(field.Add(), original); // Should NOT return the same string. + EXPECT_EQ(field.ClearedCount(), 0); + + field.AddAllocated(original); // Give ownership back. + EXPECT_EQ(field.ClearedCount(), 0); + EXPECT_EQ(field.Mutable(1), original); + + field.Clear(); + EXPECT_EQ(field.ClearedCount(), 2); + EXPECT_EQ(field.ReleaseCleared(), original); // Take ownership again. + EXPECT_EQ(field.ClearedCount(), 1); + EXPECT_NE(field.Add(), original); + EXPECT_EQ(field.ClearedCount(), 0); + EXPECT_NE(field.Add(), original); + EXPECT_EQ(field.ClearedCount(), 0); + + field.AddCleared(original); // Give ownership back, but as a cleared object. + EXPECT_EQ(field.ClearedCount(), 1); + EXPECT_EQ(field.Add(), original); + EXPECT_EQ(field.ClearedCount(), 0); +} + +// Test all code paths in AddAllocated(). +TEST(RepeatedPtrField, AddAlocated) { + RepeatedPtrField field; + while (field.size() < field.Capacity()) { + field.Add()->assign("filler"); + } + + int index = field.size(); + + // First branch: Field is at capacity with no cleared objects. + string* foo = new string("foo"); + field.AddAllocated(foo); + EXPECT_EQ(index + 1, field.size()); + EXPECT_EQ(0, field.ClearedCount()); + EXPECT_EQ(foo, &field.Get(index)); + + // Last branch: Field is not at capacity and there are no cleared objects. + string* bar = new string("bar"); + field.AddAllocated(bar); + ++index; + EXPECT_EQ(index + 1, field.size()); + EXPECT_EQ(0, field.ClearedCount()); + EXPECT_EQ(bar, &field.Get(index)); + + // Third branch: Field is not at capacity and there are no cleared objects. + field.RemoveLast(); + string* baz = new string("baz"); + field.AddAllocated(baz); + EXPECT_EQ(index + 1, field.size()); + EXPECT_EQ(1, field.ClearedCount()); + EXPECT_EQ(baz, &field.Get(index)); + + // Second branch: Field is at capacity but has some cleared objects. + while (field.size() < field.Capacity()) { + field.Add()->assign("filler2"); + } + field.RemoveLast(); + index = field.size(); + string* qux = new string("qux"); + field.AddAllocated(qux); + EXPECT_EQ(index + 1, field.size()); + // We should have discarded the cleared object. + EXPECT_EQ(0, field.ClearedCount()); + EXPECT_EQ(qux, &field.Get(index)); +} + +TEST(RepeatedPtrField, MergeFrom) { + RepeatedPtrField source, destination; + source.Add()->assign("4"); + source.Add()->assign("5"); + destination.Add()->assign("1"); + destination.Add()->assign("2"); + destination.Add()->assign("3"); + + destination.MergeFrom(source); + + ASSERT_EQ(5, destination.size()); + EXPECT_EQ("1", destination.Get(0)); + EXPECT_EQ("2", destination.Get(1)); + EXPECT_EQ("3", destination.Get(2)); + EXPECT_EQ("4", destination.Get(3)); + EXPECT_EQ("5", destination.Get(4)); +} + +TEST(RepeatedPtrField, CopyFrom) { + RepeatedPtrField source, destination; + source.Add()->assign("4"); + source.Add()->assign("5"); + destination.Add()->assign("1"); + destination.Add()->assign("2"); + destination.Add()->assign("3"); + + destination.CopyFrom(source); + + ASSERT_EQ(2, destination.size()); + EXPECT_EQ("4", destination.Get(0)); + EXPECT_EQ("5", destination.Get(1)); +} + +TEST(RepeatedPtrField, CopyConstruct) { + RepeatedPtrField source; + source.Add()->assign("1"); + source.Add()->assign("2"); + + RepeatedPtrField destination(source); + + ASSERT_EQ(2, destination.size()); + EXPECT_EQ("1", destination.Get(0)); + EXPECT_EQ("2", destination.Get(1)); +} + +TEST(RepeatedPtrField, IteratorConstruct_String) { + vector values; + values.push_back("1"); + values.push_back("2"); + + RepeatedPtrField field(values.begin(), values.end()); + ASSERT_EQ(values.size(), field.size()); + EXPECT_EQ(values[0], field.Get(0)); + EXPECT_EQ(values[1], field.Get(1)); + + RepeatedPtrField other(field.begin(), field.end()); + ASSERT_EQ(values.size(), other.size()); + EXPECT_EQ(values[0], other.Get(0)); + EXPECT_EQ(values[1], other.Get(1)); +} + +TEST(RepeatedPtrField, IteratorConstruct_Proto) { + typedef TestAllTypes::NestedMessage Nested; + vector values; + values.push_back(Nested()); + values.back().set_bb(1); + values.push_back(Nested()); + values.back().set_bb(2); + + RepeatedPtrField field(values.begin(), values.end()); + ASSERT_EQ(values.size(), field.size()); + EXPECT_EQ(values[0].bb(), field.Get(0).bb()); + EXPECT_EQ(values[1].bb(), field.Get(1).bb()); + + RepeatedPtrField other(field.begin(), field.end()); + ASSERT_EQ(values.size(), other.size()); + EXPECT_EQ(values[0].bb(), other.Get(0).bb()); + EXPECT_EQ(values[1].bb(), other.Get(1).bb()); +} + +TEST(RepeatedPtrField, CopyAssign) { + RepeatedPtrField source, destination; + source.Add()->assign("4"); + source.Add()->assign("5"); + destination.Add()->assign("1"); + destination.Add()->assign("2"); + destination.Add()->assign("3"); + + destination = source; + + ASSERT_EQ(2, destination.size()); + EXPECT_EQ("4", destination.Get(0)); + EXPECT_EQ("5", destination.Get(1)); +} + +TEST(RepeatedPtrField, SelfAssign) { + // Verify that assignment to self does not destroy data. + RepeatedPtrField source, *p; + p = &source; + source.Add()->assign("7"); + source.Add()->assign("8"); + + *p = source; + + ASSERT_EQ(2, source.size()); + EXPECT_EQ("7", source.Get(0)); + EXPECT_EQ("8", source.Get(1)); +} + +TEST(RepeatedPtrField, MutableDataIsMutable) { + RepeatedPtrField field; + *field.Add() = "1"; + EXPECT_EQ("1", field.Get(0)); + // The fact that this line compiles would be enough, but we'll check the + // value anyway. + string** data = field.mutable_data(); + **data = "2"; + EXPECT_EQ("2", field.Get(0)); +} + +TEST(RepeatedPtrField, ExtractSubrange) { + // Exhaustively test every subrange in arrays of all sizes from 0 through 9 + // with 0 through 3 cleared elements at the end. + for (int sz = 0; sz < 10; ++sz) { + for (int num = 0; num <= sz; ++num) { + for (int start = 0; start < sz - num; ++start) { + for (int extra = 0; extra < 4; ++extra) { + vector subject; + + // Create an array with "sz" elements and "extra" cleared elements. + RepeatedPtrField field; + for (int i = 0; i < sz + extra; ++i) { + subject.push_back(new string()); + field.AddAllocated(subject[i]); + } + EXPECT_EQ(field.size(), sz + extra); + for (int i = 0; i < extra; ++i) + field.RemoveLast(); + EXPECT_EQ(field.size(), sz); + EXPECT_EQ(field.ClearedCount(), extra); + + // Create a catcher array and call ExtractSubrange. + string* catcher[10]; + for (int i = 0; i < 10; ++i) + catcher[i] = NULL; + field.ExtractSubrange(start, num, catcher); + + // Does the resulting array have the right size? + EXPECT_EQ(field.size(), sz - num); + + // Were the removed elements extracted into the catcher array? + for (int i = 0; i < num; ++i) + EXPECT_EQ(catcher[i], subject[start + i]); + EXPECT_EQ(NULL, catcher[num]); + + // Does the resulting array contain the right values? + for (int i = 0; i < start; ++i) + EXPECT_EQ(field.Mutable(i), subject[i]); + for (int i = start; i < field.size(); ++i) + EXPECT_EQ(field.Mutable(i), subject[i + num]); + + // Reinstate the cleared elements. + EXPECT_EQ(field.ClearedCount(), extra); + for (int i = 0; i < extra; ++i) + field.Add(); + EXPECT_EQ(field.ClearedCount(), 0); + EXPECT_EQ(field.size(), sz - num + extra); + + // Make sure the extra elements are all there (in some order). + for (int i = sz; i < sz + extra; ++i) { + int count = 0; + for (int j = sz; j < sz + extra; ++j) { + if (field.Mutable(j - num) == subject[i]) + count += 1; + } + EXPECT_EQ(count, 1); + } + + // Release the caught elements. + for (int i = 0; i < num; ++i) + delete catcher[i]; + } + } + } + } +} + +TEST(RepeatedPtrField, DeleteSubrange) { + // DeleteSubrange is a trivial extension of ExtendSubrange. +} + +// =================================================================== + +// Iterator tests stolen from net/proto/proto-array_unittest. +class RepeatedFieldIteratorTest : public testing::Test { + protected: + virtual void SetUp() { + for (int i = 0; i < 3; ++i) { + proto_array_.Add(i); + } + } + + RepeatedField proto_array_; +}; + +TEST_F(RepeatedFieldIteratorTest, Convertible) { + RepeatedField::iterator iter = proto_array_.begin(); + RepeatedField::const_iterator c_iter = iter; + RepeatedField::value_type value = *c_iter; + EXPECT_EQ(0, value); +} + +TEST_F(RepeatedFieldIteratorTest, MutableIteration) { + RepeatedField::iterator iter = proto_array_.begin(); + EXPECT_EQ(0, *iter); + ++iter; + EXPECT_EQ(1, *iter++); + EXPECT_EQ(2, *iter); + ++iter; + EXPECT_TRUE(proto_array_.end() == iter); + + EXPECT_EQ(2, *(proto_array_.end() - 1)); +} + +TEST_F(RepeatedFieldIteratorTest, ConstIteration) { + const RepeatedField& const_proto_array = proto_array_; + RepeatedField::const_iterator iter = const_proto_array.begin(); + EXPECT_EQ(0, *iter); + ++iter; + EXPECT_EQ(1, *iter++); + EXPECT_EQ(2, *iter); + ++iter; + EXPECT_TRUE(proto_array_.end() == iter); + EXPECT_EQ(2, *(proto_array_.end() - 1)); +} + +TEST_F(RepeatedFieldIteratorTest, Mutation) { + RepeatedField::iterator iter = proto_array_.begin(); + *iter = 7; + EXPECT_EQ(7, proto_array_.Get(0)); +} + +// ------------------------------------------------------------------- + +class RepeatedPtrFieldIteratorTest : public testing::Test { + protected: + virtual void SetUp() { + proto_array_.Add()->assign("foo"); + proto_array_.Add()->assign("bar"); + proto_array_.Add()->assign("baz"); + } + + RepeatedPtrField proto_array_; +}; + +TEST_F(RepeatedPtrFieldIteratorTest, Convertible) { + RepeatedPtrField::iterator iter = proto_array_.begin(); + RepeatedPtrField::const_iterator c_iter = iter; + RepeatedPtrField::value_type value = *c_iter; + EXPECT_EQ("foo", value); +} + +TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) { + RepeatedPtrField::iterator iter = proto_array_.begin(); + EXPECT_EQ("foo", *iter); + ++iter; + EXPECT_EQ("bar", *(iter++)); + EXPECT_EQ("baz", *iter); + ++iter; + EXPECT_TRUE(proto_array_.end() == iter); + EXPECT_EQ("baz", *(--proto_array_.end())); +} + +TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) { + const RepeatedPtrField& const_proto_array = proto_array_; + RepeatedPtrField::const_iterator iter = const_proto_array.begin(); + EXPECT_EQ("foo", *iter); + ++iter; + EXPECT_EQ("bar", *(iter++)); + EXPECT_EQ("baz", *iter); + ++iter; + EXPECT_TRUE(const_proto_array.end() == iter); + EXPECT_EQ("baz", *(--const_proto_array.end())); +} + +TEST_F(RepeatedPtrFieldIteratorTest, MutableReverseIteration) { + RepeatedPtrField::reverse_iterator iter = proto_array_.rbegin(); + EXPECT_EQ("baz", *iter); + ++iter; + EXPECT_EQ("bar", *(iter++)); + EXPECT_EQ("foo", *iter); + ++iter; + EXPECT_TRUE(proto_array_.rend() == iter); + EXPECT_EQ("foo", *(--proto_array_.rend())); +} + +TEST_F(RepeatedPtrFieldIteratorTest, ConstReverseIteration) { + const RepeatedPtrField& const_proto_array = proto_array_; + RepeatedPtrField::const_reverse_iterator iter + = const_proto_array.rbegin(); + EXPECT_EQ("baz", *iter); + ++iter; + EXPECT_EQ("bar", *(iter++)); + EXPECT_EQ("foo", *iter); + ++iter; + EXPECT_TRUE(const_proto_array.rend() == iter); + EXPECT_EQ("foo", *(--const_proto_array.rend())); +} + +TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) { + RepeatedPtrField::iterator iter = proto_array_.begin(); + RepeatedPtrField::iterator iter2 = iter; + ++iter2; + ++iter2; + EXPECT_TRUE(iter + 2 == iter2); + EXPECT_TRUE(iter == iter2 - 2); + EXPECT_EQ("baz", iter[2]); + EXPECT_EQ("baz", *(iter + 2)); + EXPECT_EQ(3, proto_array_.end() - proto_array_.begin()); +} + +TEST_F(RepeatedPtrFieldIteratorTest, Comparable) { + RepeatedPtrField::const_iterator iter = proto_array_.begin(); + RepeatedPtrField::const_iterator iter2 = iter + 1; + EXPECT_TRUE(iter == iter); + EXPECT_TRUE(iter != iter2); + EXPECT_TRUE(iter < iter2); + EXPECT_TRUE(iter <= iter2); + EXPECT_TRUE(iter <= iter); + EXPECT_TRUE(iter2 > iter); + EXPECT_TRUE(iter2 >= iter); + EXPECT_TRUE(iter >= iter); +} + +// Uninitialized iterator does not point to any of the RepeatedPtrField. +TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) { + RepeatedPtrField::iterator iter; + EXPECT_TRUE(iter != proto_array_.begin()); + EXPECT_TRUE(iter != proto_array_.begin() + 1); + EXPECT_TRUE(iter != proto_array_.begin() + 2); + EXPECT_TRUE(iter != proto_array_.begin() + 3); + EXPECT_TRUE(iter != proto_array_.end()); +} + +TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) { + proto_array_.Clear(); + proto_array_.Add()->assign("a"); + proto_array_.Add()->assign("c"); + proto_array_.Add()->assign("d"); + proto_array_.Add()->assign("n"); + proto_array_.Add()->assign("p"); + proto_array_.Add()->assign("x"); + proto_array_.Add()->assign("y"); + + string v = "f"; + RepeatedPtrField::const_iterator it = + lower_bound(proto_array_.begin(), proto_array_.end(), v); + + EXPECT_EQ(*it, "n"); + EXPECT_TRUE(it == proto_array_.begin() + 3); +} + +TEST_F(RepeatedPtrFieldIteratorTest, Mutation) { + RepeatedPtrField::iterator iter = proto_array_.begin(); + *iter = "qux"; + EXPECT_EQ("qux", proto_array_.Get(0)); +} + +// ------------------------------------------------------------------- + +class RepeatedPtrFieldPtrsIteratorTest : public testing::Test { + protected: + virtual void SetUp() { + proto_array_.Add()->assign("foo"); + proto_array_.Add()->assign("bar"); + proto_array_.Add()->assign("baz"); + const_proto_array_ = &proto_array_; + } + + RepeatedPtrField proto_array_; + const RepeatedPtrField* const_proto_array_; +}; + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) { + RepeatedPtrField::pointer_iterator iter = + proto_array_.pointer_begin(); + (void) iter; +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertibleConstPtr) { + RepeatedPtrField::const_pointer_iterator iter = + const_proto_array_->pointer_begin(); + (void) iter; +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) { + RepeatedPtrField::pointer_iterator iter = + proto_array_.pointer_begin(); + EXPECT_EQ("foo", **iter); + ++iter; + EXPECT_EQ("bar", **(iter++)); + EXPECT_EQ("baz", **iter); + ++iter; + EXPECT_TRUE(proto_array_.pointer_end() == iter); + EXPECT_EQ("baz", **(--proto_array_.pointer_end())); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutableConstPtrIteration) { + RepeatedPtrField::const_pointer_iterator iter = + const_proto_array_->pointer_begin(); + EXPECT_EQ("foo", **iter); + ++iter; + EXPECT_EQ("bar", **(iter++)); + EXPECT_EQ("baz", **iter); + ++iter; + EXPECT_TRUE(const_proto_array_->pointer_end() == iter); + EXPECT_EQ("baz", **(--const_proto_array_->pointer_end())); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) { + RepeatedPtrField::pointer_iterator iter = + proto_array_.pointer_begin(); + RepeatedPtrField::pointer_iterator iter2 = iter; + ++iter2; + ++iter2; + EXPECT_TRUE(iter + 2 == iter2); + EXPECT_TRUE(iter == iter2 - 2); + EXPECT_EQ("baz", *iter[2]); + EXPECT_EQ("baz", **(iter + 2)); + EXPECT_EQ(3, proto_array_.end() - proto_array_.begin()); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomConstPtrAccess) { + RepeatedPtrField::const_pointer_iterator iter = + const_proto_array_->pointer_begin(); + RepeatedPtrField::const_pointer_iterator iter2 = iter; + ++iter2; + ++iter2; + EXPECT_TRUE(iter + 2 == iter2); + EXPECT_TRUE(iter == iter2 - 2); + EXPECT_EQ("baz", *iter[2]); + EXPECT_EQ("baz", **(iter + 2)); + EXPECT_EQ(3, const_proto_array_->end() - const_proto_array_->begin()); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) { + RepeatedPtrField::pointer_iterator iter = + proto_array_.pointer_begin(); + RepeatedPtrField::pointer_iterator iter2 = iter + 1; + EXPECT_TRUE(iter == iter); + EXPECT_TRUE(iter != iter2); + EXPECT_TRUE(iter < iter2); + EXPECT_TRUE(iter <= iter2); + EXPECT_TRUE(iter <= iter); + EXPECT_TRUE(iter2 > iter); + EXPECT_TRUE(iter2 >= iter); + EXPECT_TRUE(iter >= iter); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparableConstPtr) { + RepeatedPtrField::const_pointer_iterator iter = + const_proto_array_->pointer_begin(); + RepeatedPtrField::const_pointer_iterator iter2 = iter + 1; + EXPECT_TRUE(iter == iter); + EXPECT_TRUE(iter != iter2); + EXPECT_TRUE(iter < iter2); + EXPECT_TRUE(iter <= iter2); + EXPECT_TRUE(iter <= iter); + EXPECT_TRUE(iter2 > iter); + EXPECT_TRUE(iter2 >= iter); + EXPECT_TRUE(iter >= iter); +} + +// Uninitialized iterator does not point to any of the RepeatedPtrOverPtrs. +// Dereferencing an uninitialized iterator crashes the process. +TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) { + RepeatedPtrField::pointer_iterator iter; + EXPECT_TRUE(iter != proto_array_.pointer_begin()); + EXPECT_TRUE(iter != proto_array_.pointer_begin() + 1); + EXPECT_TRUE(iter != proto_array_.pointer_begin() + 2); + EXPECT_TRUE(iter != proto_array_.pointer_begin() + 3); + EXPECT_TRUE(iter != proto_array_.pointer_end()); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedConstPtrIterator) { + RepeatedPtrField::const_pointer_iterator iter; + EXPECT_TRUE(iter != const_proto_array_->pointer_begin()); + EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 1); + EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 2); + EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 3); + EXPECT_TRUE(iter != const_proto_array_->pointer_end()); +} + +// This comparison functor is required by the tests for RepeatedPtrOverPtrs. +// They operate on strings and need to compare strings as strings in +// any stl algorithm, even though the iterator returns a pointer to a string +// - i.e. *iter has type string*. +struct StringLessThan { + bool operator()(const string* z, const string& y) { + return *z < y; + } + bool operator()(const string* z, const string* y) { + return *z < *y; + } +}; + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) { + proto_array_.Clear(); + proto_array_.Add()->assign("a"); + proto_array_.Add()->assign("c"); + proto_array_.Add()->assign("d"); + proto_array_.Add()->assign("n"); + proto_array_.Add()->assign("p"); + proto_array_.Add()->assign("x"); + proto_array_.Add()->assign("y"); + + { + string v = "f"; + RepeatedPtrField::pointer_iterator it = + lower_bound(proto_array_.pointer_begin(), proto_array_.pointer_end(), + &v, StringLessThan()); + + GOOGLE_CHECK(*it != NULL); + + EXPECT_EQ(**it, "n"); + EXPECT_TRUE(it == proto_array_.pointer_begin() + 3); + } + { + string v = "f"; + RepeatedPtrField::const_pointer_iterator it = + lower_bound(const_proto_array_->pointer_begin(), + const_proto_array_->pointer_end(), + &v, StringLessThan()); + + GOOGLE_CHECK(*it != NULL); + + EXPECT_EQ(**it, "n"); + EXPECT_TRUE(it == const_proto_array_->pointer_begin() + 3); + } +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) { + RepeatedPtrField::pointer_iterator iter = + proto_array_.pointer_begin(); + **iter = "qux"; + EXPECT_EQ("qux", proto_array_.Get(0)); + + EXPECT_EQ("bar", proto_array_.Get(1)); + EXPECT_EQ("baz", proto_array_.Get(2)); + ++iter; + delete *iter; + *iter = new string("a"); + ++iter; + delete *iter; + *iter = new string("b"); + EXPECT_EQ("a", proto_array_.Get(1)); + EXPECT_EQ("b", proto_array_.Get(2)); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, Sort) { + proto_array_.Add()->assign("c"); + proto_array_.Add()->assign("d"); + proto_array_.Add()->assign("n"); + proto_array_.Add()->assign("p"); + proto_array_.Add()->assign("a"); + proto_array_.Add()->assign("y"); + proto_array_.Add()->assign("x"); + EXPECT_EQ("foo", proto_array_.Get(0)); + EXPECT_EQ("n", proto_array_.Get(5)); + EXPECT_EQ("x", proto_array_.Get(9)); + sort(proto_array_.pointer_begin(), + proto_array_.pointer_end(), + StringLessThan()); + EXPECT_EQ("a", proto_array_.Get(0)); + EXPECT_EQ("baz", proto_array_.Get(2)); + EXPECT_EQ("y", proto_array_.Get(9)); +} + + +// ----------------------------------------------------------------------------- +// Unit-tests for the insert iterators +// google::protobuf::RepeatedFieldBackInserter, +// google::protobuf::AllocatedRepeatedPtrFieldBackInserter +// Ported from util/gtl/proto-array-iterators_unittest. + +class RepeatedFieldInsertionIteratorsTest : public testing::Test { + protected: + std::list halves; + std::list fibonacci; + std::vector words; + typedef TestAllTypes::NestedMessage Nested; + Nested nesteds[2]; + std::vector nested_ptrs; + TestAllTypes protobuffer; + + virtual void SetUp() { + fibonacci.push_back(1); + fibonacci.push_back(1); + fibonacci.push_back(2); + fibonacci.push_back(3); + fibonacci.push_back(5); + fibonacci.push_back(8); + std::copy(fibonacci.begin(), fibonacci.end(), + RepeatedFieldBackInserter(protobuffer.mutable_repeated_int32())); + + halves.push_back(1.0); + halves.push_back(0.5); + halves.push_back(0.25); + halves.push_back(0.125); + halves.push_back(0.0625); + std::copy(halves.begin(), halves.end(), + RepeatedFieldBackInserter(protobuffer.mutable_repeated_double())); + + words.push_back("Able"); + words.push_back("was"); + words.push_back("I"); + words.push_back("ere"); + words.push_back("I"); + words.push_back("saw"); + words.push_back("Elba"); + std::copy(words.begin(), words.end(), + RepeatedFieldBackInserter(protobuffer.mutable_repeated_string())); + + nesteds[0].set_bb(17); + nesteds[1].set_bb(4711); + std::copy(&nesteds[0], &nesteds[2], + RepeatedFieldBackInserter( + protobuffer.mutable_repeated_nested_message())); + + nested_ptrs.push_back(new Nested); + nested_ptrs.back()->set_bb(170); + nested_ptrs.push_back(new Nested); + nested_ptrs.back()->set_bb(47110); + std::copy(nested_ptrs.begin(), nested_ptrs.end(), + RepeatedFieldBackInserter( + protobuffer.mutable_repeated_nested_message())); + + } + + virtual void TearDown() { + STLDeleteContainerPointers(nested_ptrs.begin(), nested_ptrs.end()); + } +}; + +TEST_F(RepeatedFieldInsertionIteratorsTest, Fibonacci) { + EXPECT_TRUE(std::equal(fibonacci.begin(), + fibonacci.end(), + protobuffer.repeated_int32().begin())); + EXPECT_TRUE(std::equal(protobuffer.repeated_int32().begin(), + protobuffer.repeated_int32().end(), + fibonacci.begin())); +} + +TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) { + EXPECT_TRUE(std::equal(halves.begin(), + halves.end(), + protobuffer.repeated_double().begin())); + EXPECT_TRUE(std::equal(protobuffer.repeated_double().begin(), + protobuffer.repeated_double().end(), + halves.begin())); +} + +TEST_F(RepeatedFieldInsertionIteratorsTest, Words) { + ASSERT_EQ(words.size(), protobuffer.repeated_string_size()); + for (int i = 0; i < words.size(); ++i) + EXPECT_EQ(words.at(i), protobuffer.repeated_string(i)); +} + +TEST_F(RepeatedFieldInsertionIteratorsTest, Words2) { + words.clear(); + words.push_back("sing"); + words.push_back("a"); + words.push_back("song"); + words.push_back("of"); + words.push_back("six"); + words.push_back("pence"); + protobuffer.mutable_repeated_string()->Clear(); + std::copy(words.begin(), words.end(), RepeatedPtrFieldBackInserter( + protobuffer.mutable_repeated_string())); + ASSERT_EQ(words.size(), protobuffer.repeated_string_size()); + for (int i = 0; i < words.size(); ++i) + EXPECT_EQ(words.at(i), protobuffer.repeated_string(i)); +} + +TEST_F(RepeatedFieldInsertionIteratorsTest, Nesteds) { + ASSERT_EQ(protobuffer.repeated_nested_message_size(), 4); + EXPECT_EQ(protobuffer.repeated_nested_message(0).bb(), 17); + EXPECT_EQ(protobuffer.repeated_nested_message(1).bb(), 4711); + EXPECT_EQ(protobuffer.repeated_nested_message(2).bb(), 170); + EXPECT_EQ(protobuffer.repeated_nested_message(3).bb(), 47110); +} + +TEST_F(RepeatedFieldInsertionIteratorsTest, + AllocatedRepeatedPtrFieldWithStringIntData) { + vector data; + TestAllTypes goldenproto; + for (int i = 0; i < 10; ++i) { + Nested* new_data = new Nested; + new_data->set_bb(i); + data.push_back(new_data); + + new_data = goldenproto.add_repeated_nested_message(); + new_data->set_bb(i); + } + TestAllTypes testproto; + copy(data.begin(), data.end(), + AllocatedRepeatedPtrFieldBackInserter( + testproto.mutable_repeated_nested_message())); + EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); +} + +TEST_F(RepeatedFieldInsertionIteratorsTest, + AllocatedRepeatedPtrFieldWithString) { + vector data; + TestAllTypes goldenproto; + for (int i = 0; i < 10; ++i) { + string* new_data = new string; + *new_data = "name-" + SimpleItoa(i); + data.push_back(new_data); + + new_data = goldenproto.add_repeated_string(); + *new_data = "name-" + SimpleItoa(i); + } + TestAllTypes testproto; + copy(data.begin(), data.end(), + AllocatedRepeatedPtrFieldBackInserter( + testproto.mutable_repeated_string())); + EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); +} + +} // namespace + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/service.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/service.cc new file mode 100644 index 0000000..caf968c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/service.cc @@ -0,0 +1,46 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +namespace google { +namespace protobuf { + +Service::~Service() {} +RpcChannel::~RpcChannel() {} +RpcController::~RpcController() {} + +} // namespace protobuf + +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/service.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/service.h new file mode 100644 index 0000000..a6a7d16 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/service.h @@ -0,0 +1,291 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// DEPRECATED: This module declares the abstract interfaces underlying proto2 +// RPC services. These are intented to be independent of any particular RPC +// implementation, so that proto2 services can be used on top of a variety +// of implementations. Starting with version 2.3.0, RPC implementations should +// not try to build on these, but should instead provide code generator plugins +// which generate code specific to the particular RPC implementation. This way +// the generated code can be more appropriate for the implementation in use +// and can avoid unnecessary layers of indirection. +// +// +// When you use the protocol compiler to compile a service definition, it +// generates two classes: An abstract interface for the service (with +// methods matching the service definition) and a "stub" implementation. +// A stub is just a type-safe wrapper around an RpcChannel which emulates a +// local implementation of the service. +// +// For example, the service definition: +// service MyService { +// rpc Foo(MyRequest) returns(MyResponse); +// } +// will generate abstract interface "MyService" and class "MyService::Stub". +// You could implement a MyService as follows: +// class MyServiceImpl : public MyService { +// public: +// MyServiceImpl() {} +// ~MyServiceImpl() {} +// +// // implements MyService --------------------------------------- +// +// void Foo(google::protobuf::RpcController* controller, +// const MyRequest* request, +// MyResponse* response, +// Closure* done) { +// // ... read request and fill in response ... +// done->Run(); +// } +// }; +// You would then register an instance of MyServiceImpl with your RPC server +// implementation. (How to do that depends on the implementation.) +// +// To call a remote MyServiceImpl, first you need an RpcChannel connected to it. +// How to construct a channel depends, again, on your RPC implementation. +// Here we use a hypothentical "MyRpcChannel" as an example: +// MyRpcChannel channel("rpc:hostname:1234/myservice"); +// MyRpcController controller; +// MyServiceImpl::Stub stub(&channel); +// FooRequest request; +// FooRespnose response; +// +// // ... fill in request ... +// +// stub.Foo(&controller, request, &response, NewCallback(HandleResponse)); +// +// On Thread-Safety: +// +// Different RPC implementations may make different guarantees about what +// threads they may run callbacks on, and what threads the application is +// allowed to use to call the RPC system. Portable software should be ready +// for callbacks to be called on any thread, but should not try to call the +// RPC system from any thread except for the ones on which it received the +// callbacks. Realistically, though, simple software will probably want to +// use a single-threaded RPC system while high-end software will want to +// use multiple threads. RPC implementations should provide multiple +// choices. + +#ifndef GOOGLE_PROTOBUF_SERVICE_H__ +#define GOOGLE_PROTOBUF_SERVICE_H__ + +#include +#include + +namespace google { +namespace protobuf { + +// Defined in this file. +class Service; +class RpcController; +class RpcChannel; + +// Defined in other files. +class Descriptor; // descriptor.h +class ServiceDescriptor; // descriptor.h +class MethodDescriptor; // descriptor.h +class Message; // message.h + +// Abstract base interface for protocol-buffer-based RPC services. Services +// themselves are abstract interfaces (implemented either by servers or as +// stubs), but they subclass this base interface. The methods of this +// interface can be used to call the methods of the Service without knowing +// its exact type at compile time (analogous to Reflection). +class LIBPROTOBUF_EXPORT Service { + public: + inline Service() {} + virtual ~Service(); + + // When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second + // parameter to the constructor to tell it to delete its RpcChannel when + // destroyed. + enum ChannelOwnership { + STUB_OWNS_CHANNEL, + STUB_DOESNT_OWN_CHANNEL + }; + + // Get the ServiceDescriptor describing this service and its methods. + virtual const ServiceDescriptor* GetDescriptor() = 0; + + // Call a method of the service specified by MethodDescriptor. This is + // normally implemented as a simple switch() that calls the standard + // definitions of the service's methods. + // + // Preconditions: + // * method->service() == GetDescriptor() + // * request and response are of the exact same classes as the objects + // returned by GetRequestPrototype(method) and + // GetResponsePrototype(method). + // * After the call has started, the request must not be modified and the + // response must not be accessed at all until "done" is called. + // * "controller" is of the correct type for the RPC implementation being + // used by this Service. For stubs, the "correct type" depends on the + // RpcChannel which the stub is using. Server-side Service + // implementations are expected to accept whatever type of RpcController + // the server-side RPC implementation uses. + // + // Postconditions: + // * "done" will be called when the method is complete. This may be + // before CallMethod() returns or it may be at some point in the future. + // * If the RPC succeeded, "response" contains the response returned by + // the server. + // * If the RPC failed, "response"'s contents are undefined. The + // RpcController can be queried to determine if an error occurred and + // possibly to get more information about the error. + virtual void CallMethod(const MethodDescriptor* method, + RpcController* controller, + const Message* request, + Message* response, + Closure* done) = 0; + + // CallMethod() requires that the request and response passed in are of a + // particular subclass of Message. GetRequestPrototype() and + // GetResponsePrototype() get the default instances of these required types. + // You can then call Message::New() on these instances to construct mutable + // objects which you can then pass to CallMethod(). + // + // Example: + // const MethodDescriptor* method = + // service->GetDescriptor()->FindMethodByName("Foo"); + // Message* request = stub->GetRequestPrototype (method)->New(); + // Message* response = stub->GetResponsePrototype(method)->New(); + // request->ParseFromString(input); + // service->CallMethod(method, *request, response, callback); + virtual const Message& GetRequestPrototype( + const MethodDescriptor* method) const = 0; + virtual const Message& GetResponsePrototype( + const MethodDescriptor* method) const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Service); +}; + +// An RpcController mediates a single method call. The primary purpose of +// the controller is to provide a way to manipulate settings specific to the +// RPC implementation and to find out about RPC-level errors. +// +// The methods provided by the RpcController interface are intended to be a +// "least common denominator" set of features which we expect all +// implementations to support. Specific implementations may provide more +// advanced features (e.g. deadline propagation). +class LIBPROTOBUF_EXPORT RpcController { + public: + inline RpcController() {} + virtual ~RpcController(); + + // Client-side methods --------------------------------------------- + // These calls may be made from the client side only. Their results + // are undefined on the server side (may crash). + + // Resets the RpcController to its initial state so that it may be reused in + // a new call. Must not be called while an RPC is in progress. + virtual void Reset() = 0; + + // After a call has finished, returns true if the call failed. The possible + // reasons for failure depend on the RPC implementation. Failed() must not + // be called before a call has finished. If Failed() returns true, the + // contents of the response message are undefined. + virtual bool Failed() const = 0; + + // If Failed() is true, returns a human-readable description of the error. + virtual string ErrorText() const = 0; + + // Advises the RPC system that the caller desires that the RPC call be + // canceled. The RPC system may cancel it immediately, may wait awhile and + // then cancel it, or may not even cancel the call at all. If the call is + // canceled, the "done" callback will still be called and the RpcController + // will indicate that the call failed at that time. + virtual void StartCancel() = 0; + + // Server-side methods --------------------------------------------- + // These calls may be made from the server side only. Their results + // are undefined on the client side (may crash). + + // Causes Failed() to return true on the client side. "reason" will be + // incorporated into the message returned by ErrorText(). If you find + // you need to return machine-readable information about failures, you + // should incorporate it into your response protocol buffer and should + // NOT call SetFailed(). + virtual void SetFailed(const string& reason) = 0; + + // If true, indicates that the client canceled the RPC, so the server may + // as well give up on replying to it. The server should still call the + // final "done" callback. + virtual bool IsCanceled() const = 0; + + // Asks that the given callback be called when the RPC is canceled. The + // callback will always be called exactly once. If the RPC completes without + // being canceled, the callback will be called after completion. If the RPC + // has already been canceled when NotifyOnCancel() is called, the callback + // will be called immediately. + // + // NotifyOnCancel() must be called no more than once per request. + virtual void NotifyOnCancel(Closure* callback) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcController); +}; + +// Abstract interface for an RPC channel. An RpcChannel represents a +// communication line to a Service which can be used to call that Service's +// methods. The Service may be running on another machine. Normally, you +// should not call an RpcChannel directly, but instead construct a stub Service +// wrapping it. Example: +// RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234"); +// MyService* service = new MyService::Stub(channel); +// service->MyMethod(request, &response, callback); +class LIBPROTOBUF_EXPORT RpcChannel { + public: + inline RpcChannel() {} + virtual ~RpcChannel(); + + // Call the given method of the remote service. The signature of this + // procedure looks the same as Service::CallMethod(), but the requirements + // are less strict in one important way: the request and response objects + // need not be of any specific class as long as their descriptors are + // method->input_type() and method->output_type(). + virtual void CallMethod(const MethodDescriptor* method, + RpcController* controller, + const Message* request, + Message* response, + Closure* done) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcChannel); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_SERVICE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops.h new file mode 100644 index 0000000..b8581fa --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops.h @@ -0,0 +1,206 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// The routines exported by this module are subtle. If you use them, even if +// you get the code right, it will depend on careful reasoning about atomicity +// and memory ordering; it will be less readable, and harder to maintain. If +// you plan to use these routines, you should have a good reason, such as solid +// evidence that performance would otherwise suffer, or there being no +// alternative. You should assume only properties explicitly guaranteed by the +// specifications in this file. You are almost certainly _not_ writing code +// just for the x86; if you assume x86 semantics, x86 hardware bugs and +// implementations on other archtectures will cause your code to break. If you +// do not know what you are doing, avoid these routines, and use a Mutex. +// +// It is incorrect to make direct assignments to/from an atomic variable. +// You should use one of the Load or Store routines. The NoBarrier +// versions are provided when no barriers are needed: +// NoBarrier_Store() +// NoBarrier_Load() +// Although there are currently no compiler enforcement, you are encouraged +// to use these. + +// This header and the implementations for each platform (located in +// atomicops_internals_*) must be kept in sync with the upstream code (V8). + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_H_ + +// Don't include this file for people not concerned about thread safety. +#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY + +#include + +namespace google { +namespace protobuf { +namespace internal { + +typedef int32 Atomic32; +#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT +// We need to be able to go between Atomic64 and AtomicWord implicitly. This +// means Atomic64 and AtomicWord should be the same type on 64-bit. +#if defined(GOOGLE_PROTOBUF_OS_NACL) +// NaCl's intptr_t is not actually 64-bits on 64-bit! +// http://code.google.com/p/nativeclient/issues/detail?id=1162 +typedef int64 Atomic64; +#else +typedef intptr_t Atomic64; +#endif +#endif + +// Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or +// Atomic64 routines below, depending on your architecture. +typedef intptr_t AtomicWord; + +// Atomically execute: +// result = *ptr; +// if (*ptr == old_value) +// *ptr = new_value; +// return result; +// +// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value". +// Always return the old value of "*ptr" +// +// This routine implies no memory barriers. +Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value); + +// Atomically store new_value into *ptr, returning the previous value held in +// *ptr. This routine implies no memory barriers. +Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value); + +// Atomically increment *ptr by "increment". Returns the new value of +// *ptr with the increment applied. This routine implies no memory barriers. +Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment); + +Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment); + +// These following lower-level operations are typically useful only to people +// implementing higher-level synchronization operations like spinlocks, +// mutexes, and condition-variables. They combine CompareAndSwap(), a load, or +// a store with appropriate memory-ordering instructions. "Acquire" operations +// ensure that no later memory access can be reordered ahead of the operation. +// "Release" operations ensure that no previous memory access can be reordered +// after the operation. "Barrier" operations have both "Acquire" and "Release" +// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory +// access. +Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value); +Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value); + +void MemoryBarrier(); +void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value); +void Acquire_Store(volatile Atomic32* ptr, Atomic32 value); +void Release_Store(volatile Atomic32* ptr, Atomic32 value); + +Atomic32 NoBarrier_Load(volatile const Atomic32* ptr); +Atomic32 Acquire_Load(volatile const Atomic32* ptr); +Atomic32 Release_Load(volatile const Atomic32* ptr); + +// 64-bit atomic operations (only available on 64-bit processors). +#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT +Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value); +Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value); +Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); +Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); + +Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value); +Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value); +void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value); +void Acquire_Store(volatile Atomic64* ptr, Atomic64 value); +void Release_Store(volatile Atomic64* ptr, Atomic64 value); +Atomic64 NoBarrier_Load(volatile const Atomic64* ptr); +Atomic64 Acquire_Load(volatile const Atomic64* ptr); +Atomic64 Release_Load(volatile const Atomic64* ptr); +#endif // GOOGLE_PROTOBUF_ARCH_64_BIT + +} // namespace internal +} // namespace protobuf +} // namespace google + +// Include our platform specific implementation. +#define GOOGLE_PROTOBUF_ATOMICOPS_ERROR \ +#error "Atomic operations are not supported on your platform" + +// MSVC. +#if defined(_MSC_VER) +#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64) +#include +#else +GOOGLE_PROTOBUF_ATOMICOPS_ERROR +#endif + +// Apple. +#elif defined(GOOGLE_PROTOBUF_OS_APPLE) +#include + +// GCC. +#elif defined(__GNUC__) +#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64) +#include +#elif defined(GOOGLE_PROTOBUF_ARCH_ARM) +#include +#elif defined(GOOGLE_PROTOBUF_ARCH_ARM_QNX) +#include +#elif defined(GOOGLE_PROTOBUF_ARCH_MIPS) +#include +#elif defined(__pnacl__) +#include +#else +GOOGLE_PROTOBUF_ATOMICOPS_ERROR +#endif + +// Unknown. +#else +GOOGLE_PROTOBUF_ATOMICOPS_ERROR +#endif + +// On some platforms we need additional declarations to make AtomicWord +// compatible with our other Atomic* types. +#if defined(GOOGLE_PROTOBUF_OS_APPLE) +#include +#endif + +#undef GOOGLE_PROTOBUF_ATOMICOPS_ERROR + +#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h new file mode 100644 index 0000000..1f4dedc --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h @@ -0,0 +1,151 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. +// +// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_ + +namespace google { +namespace protobuf { +namespace internal { + +// 0xffff0fc0 is the hard coded address of a function provided by +// the kernel which implements an atomic compare-exchange. On older +// ARM architecture revisions (pre-v6) this may be implemented using +// a syscall. This address is stable, and in active use (hard coded) +// by at least glibc-2.7 and the Android C library. +typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value, + Atomic32 new_value, + volatile Atomic32* ptr); +LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) = + (LinuxKernelCmpxchgFunc) 0xffff0fc0; + +typedef void (*LinuxKernelMemoryBarrierFunc)(void); +LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) = + (LinuxKernelMemoryBarrierFunc) 0xffff0fa0; + + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev_value = *ptr; + do { + if (!pLinuxKernelCmpxchg(old_value, new_value, + const_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + Atomic32 old_value; + do { + old_value = *ptr; + } while (pLinuxKernelCmpxchg(old_value, new_value, + const_cast(ptr))); + return old_value; +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return Barrier_AtomicIncrement(ptr, increment); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + for (;;) { + // Atomic exchange the old value with an incremented one. + Atomic32 old_value = *ptr; + Atomic32 new_value = old_value + increment; + if (pLinuxKernelCmpxchg(old_value, new_value, + const_cast(ptr)) == 0) { + // The exchange took place as expected. + return new_value; + } + // Otherwise, *ptr changed mid-loop and we need to retry. + } +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void MemoryBarrier() { + pLinuxKernelMemoryBarrier(); +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h new file mode 100644 index 0000000..f050769 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h @@ -0,0 +1,146 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_ + +// For _smp_cmpxchg() +#include + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 QNXCmpxchg(Atomic32 old_value, + Atomic32 new_value, + volatile Atomic32* ptr) { + return static_cast( + _smp_cmpxchg((volatile unsigned *)ptr, + (unsigned)old_value, + (unsigned)new_value)); +} + + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev_value = *ptr; + do { + if (!QNXCmpxchg(old_value, new_value, + const_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + Atomic32 old_value; + do { + old_value = *ptr; + } while (QNXCmpxchg(old_value, new_value, + const_cast(ptr))); + return old_value; +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return Barrier_AtomicIncrement(ptr, increment); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + for (;;) { + // Atomic exchange the old value with an incremented one. + Atomic32 old_value = *ptr; + Atomic32 new_value = old_value + increment; + if (QNXCmpxchg(old_value, new_value, + const_cast(ptr)) == 0) { + // The exchange took place as expected. + return new_value; + } + // Otherwise, *ptr changed mid-loop and we need to retry. + } +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void MemoryBarrier() { + __sync_synchronize(); +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h new file mode 100644 index 0000000..e9d8679 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h @@ -0,0 +1,122 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ + +// AtomicWord is a synonym for intptr_t, and Atomic32 is a synonym for int32, +// which in turn means int. On some LP32 platforms, intptr_t is an int, but +// on others, it's a long. When AtomicWord and Atomic32 are based on different +// fundamental types, their pointers are incompatible. +// +// This file defines function overloads to allow both AtomicWord and Atomic32 +// data to be used with this interface. +// +// On LP64 platforms, AtomicWord and Atomic64 are both always long, +// so this problem doesn't occur. + +#if !defined(GOOGLE_PROTOBUF_ARCH_64_BIT) + +namespace google { +namespace protobuf { +namespace internal { + +inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr, + AtomicWord old_value, + AtomicWord new_value) { + return NoBarrier_CompareAndSwap( + reinterpret_cast(ptr), old_value, new_value); +} + +inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr, + AtomicWord new_value) { + return NoBarrier_AtomicExchange( + reinterpret_cast(ptr), new_value); +} + +inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr, + AtomicWord increment) { + return NoBarrier_AtomicIncrement( + reinterpret_cast(ptr), increment); +} + +inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr, + AtomicWord increment) { + return Barrier_AtomicIncrement( + reinterpret_cast(ptr), increment); +} + +inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr, + AtomicWord old_value, + AtomicWord new_value) { + return Acquire_CompareAndSwap( + reinterpret_cast(ptr), old_value, new_value); +} + +inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr, + AtomicWord old_value, + AtomicWord new_value) { + return Release_CompareAndSwap( + reinterpret_cast(ptr), old_value, new_value); +} + +inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) { + NoBarrier_Store(reinterpret_cast(ptr), value); +} + +inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) { + return Acquire_Store(reinterpret_cast(ptr), value); +} + +inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) { + return Release_Store(reinterpret_cast(ptr), value); +} + +inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) { + return NoBarrier_Load(reinterpret_cast(ptr)); +} + +inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) { + return Acquire_Load(reinterpret_cast(ptr)); +} + +inline AtomicWord Release_Load(volatile const AtomicWord* ptr) { + return Release_Load(reinterpret_cast(ptr)); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // !defined(GOOGLE_PROTOBUF_ARCH_64_BIT) + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_macosx.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_macosx.h new file mode 100644 index 0000000..f9b7581 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_macosx.h @@ -0,0 +1,225 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_ + +#include + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev_value; + do { + if (OSAtomicCompareAndSwap32(old_value, new_value, + const_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + Atomic32 old_value; + do { + old_value = *ptr; + } while (!OSAtomicCompareAndSwap32(old_value, new_value, + const_cast(ptr))); + return old_value; +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return OSAtomicAdd32(increment, const_cast(ptr)); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return OSAtomicAdd32Barrier(increment, const_cast(ptr)); +} + +inline void MemoryBarrier() { + OSMemoryBarrier(); +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev_value; + do { + if (OSAtomicCompareAndSwap32Barrier(old_value, new_value, + const_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return Acquire_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +#ifdef __LP64__ + +// 64-bit implementation on 64-bit platform + +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 prev_value; + do { + if (OSAtomicCompareAndSwap64(old_value, new_value, + reinterpret_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + Atomic64 old_value; + do { + old_value = *ptr; + } while (!OSAtomicCompareAndSwap64(old_value, new_value, + reinterpret_cast(ptr))); + return old_value; +} + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return OSAtomicAdd64(increment, reinterpret_cast(ptr)); +} + +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return OSAtomicAdd64Barrier(increment, + reinterpret_cast(ptr)); +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 prev_value; + do { + if (OSAtomicCompareAndSwap64Barrier( + old_value, new_value, reinterpret_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + // The lib kern interface does not distinguish between + // Acquire and Release memory barriers; they are equivalent. + return Acquire_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return *ptr; +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + Atomic64 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + MemoryBarrier(); + return *ptr; +} + +#endif // defined(__LP64__) + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h new file mode 100644 index 0000000..dc46851 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h @@ -0,0 +1,187 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_ + +#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory") + +namespace google { +namespace protobuf { +namespace internal { + +// Atomically execute: +// result = *ptr; +// if (*ptr == old_value) +// *ptr = new_value; +// return result; +// +// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value". +// Always return the old value of "*ptr" +// +// This routine implies no memory barriers. +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev, tmp; + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + "1:\n" + "ll %0, %5\n" // prev = *ptr + "bne %0, %3, 2f\n" // if (prev != old_value) goto 2 + "move %2, %4\n" // tmp = new_value + "sc %2, %1\n" // *ptr = tmp (with atomic check) + "beqz %2, 1b\n" // start again on atomic error + "nop\n" // delay slot nop + "2:\n" + ".set pop\n" + : "=&r" (prev), "=m" (*ptr), "=&r" (tmp) + : "Ir" (old_value), "r" (new_value), "m" (*ptr) + : "memory"); + return prev; +} + +// Atomically store new_value into *ptr, returning the previous value held in +// *ptr. This routine implies no memory barriers. +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + Atomic32 temp, old; + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + "1:\n" + "ll %1, %2\n" // old = *ptr + "move %0, %3\n" // temp = new_value + "sc %0, %2\n" // *ptr = temp (with atomic check) + "beqz %0, 1b\n" // start again on atomic error + "nop\n" // delay slot nop + ".set pop\n" + : "=&r" (temp), "=&r" (old), "=m" (*ptr) + : "r" (new_value), "m" (*ptr) + : "memory"); + + return old; +} + +// Atomically increment *ptr by "increment". Returns the new value of +// *ptr with the increment applied. This routine implies no memory barriers. +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + Atomic32 temp, temp2; + + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + "1:\n" + "ll %0, %2\n" // temp = *ptr + "addu %1, %0, %3\n" // temp2 = temp + increment + "sc %1, %2\n" // *ptr = temp2 (with atomic check) + "beqz %1, 1b\n" // start again on atomic error + "addu %1, %0, %3\n" // temp2 = temp + increment + ".set pop\n" + : "=&r" (temp), "=&r" (temp2), "=m" (*ptr) + : "Ir" (increment), "m" (*ptr) + : "memory"); + // temp2 now holds the final value. + return temp2; +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + ATOMICOPS_COMPILER_BARRIER(); + Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment); + ATOMICOPS_COMPILER_BARRIER(); + return res; +} + +// "Acquire" operations +// ensure that no later memory access can be reordered ahead of the operation. +// "Release" operations ensure that no previous memory access can be reordered +// after the operation. "Barrier" operations have both "Acquire" and "Release" +// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory +// access. +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + ATOMICOPS_COMPILER_BARRIER(); + Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + ATOMICOPS_COMPILER_BARRIER(); + return res; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + ATOMICOPS_COMPILER_BARRIER(); + Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + ATOMICOPS_COMPILER_BARRIER(); + return res; +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void MemoryBarrier() { + __asm__ __volatile__("sync" : : : "memory"); +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#undef ATOMICOPS_COMPILER_BARRIER + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_pnacl.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_pnacl.h new file mode 100644 index 0000000..04a91a8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_pnacl.h @@ -0,0 +1,73 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_ + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return __sync_val_compare_and_swap(ptr, old_value, new_value); +} + +inline void MemoryBarrier() { + __sync_synchronize(); +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + MemoryBarrier(); + return ret; +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; + MemoryBarrier(); + return value; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc new file mode 100644 index 0000000..0774872 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc @@ -0,0 +1,137 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This module gets enough CPU information to optimize the +// atomicops module on x86. + +#include + +#include + +// This file only makes sense with atomicops_internals_x86_gcc.h -- it +// depends on structs that are defined in that file. If atomicops.h +// doesn't sub-include that file, then we aren't needed, and shouldn't +// try to do anything. +#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_ + +// Inline cpuid instruction. In PIC compilations, %ebx contains the address +// of the global offset table. To avoid breaking such executables, this code +// must preserve that register's value across cpuid instructions. +#if defined(__i386__) +#define cpuid(a, b, c, d, inp) \ + asm("mov %%ebx, %%edi\n" \ + "cpuid\n" \ + "xchg %%edi, %%ebx\n" \ + : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp)) +#elif defined(__x86_64__) +#define cpuid(a, b, c, d, inp) \ + asm("mov %%rbx, %%rdi\n" \ + "cpuid\n" \ + "xchg %%rdi, %%rbx\n" \ + : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp)) +#endif + +#if defined(cpuid) // initialize the struct only on x86 + +namespace google { +namespace protobuf { +namespace internal { + +// Set the flags so that code will run correctly and conservatively, so even +// if we haven't been initialized yet, we're probably single threaded, and our +// default values should hopefully be pretty safe. +struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = { + false, // bug can't exist before process spawns multiple threads + false, // no SSE2 +}; + +namespace { + +// Initialize the AtomicOps_Internalx86CPUFeatures struct. +void AtomicOps_Internalx86CPUFeaturesInit() { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + + // Get vendor string (issue CPUID with eax = 0) + cpuid(eax, ebx, ecx, edx, 0); + char vendor[13]; + memcpy(vendor, &ebx, 4); + memcpy(vendor + 4, &edx, 4); + memcpy(vendor + 8, &ecx, 4); + vendor[12] = 0; + + // get feature flags in ecx/edx, and family/model in eax + cpuid(eax, ebx, ecx, edx, 1); + + int family = (eax >> 8) & 0xf; // family and model fields + int model = (eax >> 4) & 0xf; + if (family == 0xf) { // use extended family and model fields + family += (eax >> 20) & 0xff; + model += ((eax >> 16) & 0xf) << 4; + } + + // Opteron Rev E has a bug in which on very rare occasions a locked + // instruction doesn't act as a read-acquire barrier if followed by a + // non-locked read-modify-write instruction. Rev F has this bug in + // pre-release versions, but not in versions released to customers, + // so we test only for Rev E, which is family 15, model 32..63 inclusive. + if (strcmp(vendor, "AuthenticAMD") == 0 && // AMD + family == 15 && + 32 <= model && model <= 63) { + AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true; + } else { + AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false; + } + + // edx bit 26 is SSE2 which we use to tell use whether we can use mfence + AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1); +} + +class AtomicOpsx86Initializer { + public: + AtomicOpsx86Initializer() { + AtomicOps_Internalx86CPUFeaturesInit(); + } +}; + +// A global to get use initialized on startup via static initialization :/ +AtomicOpsx86Initializer g_initer; + +} // namespace + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // __i386__ + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h new file mode 100644 index 0000000..5324dfb --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h @@ -0,0 +1,293 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_ + +namespace google { +namespace protobuf { +namespace internal { + +// This struct is not part of the public API of this module; clients may not +// use it. +// Features of this x86. Values may not be correct before main() is run, +// but are set conservatively. +struct AtomicOps_x86CPUFeatureStruct { + bool has_amd_lock_mb_bug; // Processor has AMD memory-barrier bug; do lfence + // after acquire compare-and-swap. + bool has_sse2; // Processor has SSE2. +}; +extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures; + +#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory") + +// 32-bit low-level operations on any platform. + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev; + __asm__ __volatile__("lock; cmpxchgl %1,%2" + : "=a" (prev) + : "q" (new_value), "m" (*ptr), "0" (old_value) + : "memory"); + return prev; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + __asm__ __volatile__("xchgl %1,%0" // The lock prefix is implicit for xchg. + : "=r" (new_value) + : "m" (*ptr), "0" (new_value) + : "memory"); + return new_value; // Now it's the previous value. +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + Atomic32 temp = increment; + __asm__ __volatile__("lock; xaddl %0,%1" + : "+r" (temp), "+m" (*ptr) + : : "memory"); + // temp now holds the old value of *ptr + return temp + increment; +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + Atomic32 temp = increment; + __asm__ __volatile__("lock; xaddl %0,%1" + : "+r" (temp), "+m" (*ptr) + : : "memory"); + // temp now holds the old value of *ptr + if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { + __asm__ __volatile__("lfence" : : : "memory"); + } + return temp + increment; +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { + __asm__ __volatile__("lfence" : : : "memory"); + } + return x; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +#if defined(__x86_64__) + +// 64-bit implementations of memory barrier can be simpler, because it +// "mfence" is guaranteed to exist. +inline void MemoryBarrier() { + __asm__ __volatile__("mfence" : : : "memory"); +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +#else + +inline void MemoryBarrier() { + if (AtomicOps_Internalx86CPUFeatures.has_sse2) { + __asm__ __volatile__("mfence" : : : "memory"); + } else { // mfence is faster but not present on PIII + Atomic32 x = 0; + NoBarrier_AtomicExchange(&x, 0); // acts as a barrier on PIII + } +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + if (AtomicOps_Internalx86CPUFeatures.has_sse2) { + *ptr = value; + __asm__ __volatile__("mfence" : : : "memory"); + } else { + NoBarrier_AtomicExchange(ptr, value); + // acts as a barrier on PIII + } +} +#endif + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + ATOMICOPS_COMPILER_BARRIER(); + *ptr = value; // An x86 store acts as a release barrier. + // See comments in Atomic64 version of Release_Store(), below. +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; // An x86 load acts as a acquire barrier. + // See comments in Atomic64 version of Release_Store(), below. + ATOMICOPS_COMPILER_BARRIER(); + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +#if defined(__x86_64__) + +// 64-bit low-level operations on 64-bit platform. + +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 prev; + __asm__ __volatile__("lock; cmpxchgq %1,%2" + : "=a" (prev) + : "q" (new_value), "m" (*ptr), "0" (old_value) + : "memory"); + return prev; +} + +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + __asm__ __volatile__("xchgq %1,%0" // The lock prefix is implicit for xchg. + : "=r" (new_value) + : "m" (*ptr), "0" (new_value) + : "memory"); + return new_value; // Now it's the previous value. +} + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + Atomic64 temp = increment; + __asm__ __volatile__("lock; xaddq %0,%1" + : "+r" (temp), "+m" (*ptr) + : : "memory"); + // temp now contains the previous value of *ptr + return temp + increment; +} + +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + Atomic64 temp = increment; + __asm__ __volatile__("lock; xaddq %0,%1" + : "+r" (temp), "+m" (*ptr) + : : "memory"); + // temp now contains the previous value of *ptr + if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { + __asm__ __volatile__("lfence" : : : "memory"); + } + return temp + increment; +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + ATOMICOPS_COMPILER_BARRIER(); + + *ptr = value; // An x86 store acts as a release barrier + // for current AMD/Intel chips as of Jan 2008. + // See also Acquire_Load(), below. + + // When new chips come out, check: + // IA-32 Intel Architecture Software Developer's Manual, Volume 3: + // System Programming Guide, Chatper 7: Multiple-processor management, + // Section 7.2, Memory Ordering. + // Last seen at: + // http://developer.intel.com/design/pentium4/manuals/index_new.htm + // + // x86 stores/loads fail to act as barriers for a few instructions (clflush + // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are + // not generated by the compiler, and are rare. Users of these instructions + // need to know about cache behaviour in any case since all of these involve + // either flushing cache lines or non-temporal cache hints. +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return *ptr; +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + Atomic64 value = *ptr; // An x86 load acts as a acquire barrier, + // for current AMD/Intel chips as of Jan 2008. + // See also Release_Store(), above. + ATOMICOPS_COMPILER_BARRIER(); + return value; +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + MemoryBarrier(); + return *ptr; +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { + __asm__ __volatile__("lfence" : : : "memory"); + } + return x; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +#endif // defined(__x86_64__) + +} // namespace internal +} // namespace protobuf +} // namespace google + +#undef ATOMICOPS_COMPILER_BARRIER + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc new file mode 100644 index 0000000..0b35979 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc @@ -0,0 +1,112 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// The compilation of extension_set.cc fails when windows.h is included. +// Therefore we move the code depending on windows.h to this separate cc file. + +// Don't compile this file for people not concerned about thread safety. +#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY + +#include + +#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_ + +#include + +namespace google { +namespace protobuf { +namespace internal { + +inline void MemoryBarrier() { + // We use MemoryBarrier from WinNT.h + ::MemoryBarrier(); +} + +Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + LONG result = InterlockedCompareExchange( + reinterpret_cast(ptr), + static_cast(new_value), + static_cast(old_value)); + return static_cast(result); +} + +Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + LONG result = InterlockedExchange( + reinterpret_cast(ptr), + static_cast(new_value)); + return static_cast(result); +} + +Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return InterlockedExchangeAdd( + reinterpret_cast(ptr), + static_cast(increment)) + increment; +} + +#if defined(_WIN64) + +// 64-bit low-level operations on 64-bit platform. + +Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + PVOID result = InterlockedCompareExchangePointer( + reinterpret_cast(ptr), + reinterpret_cast(new_value), reinterpret_cast(old_value)); + return reinterpret_cast(result); +} + +Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + PVOID result = InterlockedExchangePointer( + reinterpret_cast(ptr), + reinterpret_cast(new_value)); + return reinterpret_cast(result); +} + +Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return InterlockedExchangeAdd64( + reinterpret_cast(ptr), + static_cast(increment)) + increment; +} + +#endif // defined(_WIN64) + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_ +#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h new file mode 100644 index 0000000..6f9869d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h @@ -0,0 +1,150 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_ + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return Barrier_AtomicIncrement(ptr, increment); +} + +#if !(defined(_MSC_VER) && _MSC_VER >= 1400) +#error "We require at least vs2005 for MemoryBarrier" +#endif + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + NoBarrier_AtomicExchange(ptr, value); + // acts as a barrier in this implementation +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; // works w/o barrier for current Intel chips as of June 2005 + // See comments in Atomic64 version of Release_Store() below. +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +#if defined(_WIN64) + +// 64-bit low-level operations on 64-bit platform. + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return Barrier_AtomicIncrement(ptr, increment); +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + NoBarrier_AtomicExchange(ptr, value); + // acts as a barrier in this implementation +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; // works w/o barrier for current Intel chips as of June 2005 + + // When new chips come out, check: + // IA-32 Intel Architecture Software Developer's Manual, Volume 3: + // System Programming Guide, Chatper 7: Multiple-processor management, + // Section 7.2, Memory Ordering. + // Last seen at: + // http://developer.intel.com/design/pentium4/manuals/index_new.htm +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return *ptr; +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + Atomic64 value = *ptr; + return value; +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + MemoryBarrier(); + return *ptr; +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +#endif // defined(_WIN64) + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common.cc new file mode 100644 index 0000000..e604502 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common.cc @@ -0,0 +1,395 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include +#include +#include +#include +#include + +#include "config.h" + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN // We only need minimal includes +#include +#define snprintf _snprintf // see comment in strutil.cc +#elif defined(HAVE_PTHREAD) +#include +#else +#error "No suitable threading library available." +#endif + +namespace google { +namespace protobuf { + +namespace internal { + +void VerifyVersion(int headerVersion, + int minLibraryVersion, + const char* filename) { + if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) { + // Library is too old for headers. + GOOGLE_LOG(FATAL) + << "This program requires version " << VersionString(minLibraryVersion) + << " of the Protocol Buffer runtime library, but the installed version " + "is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ". Please update " + "your library. If you compiled the program yourself, make sure that " + "your headers are from the same version of Protocol Buffers as your " + "link-time library. (Version verification failed in \"" + << filename << "\".)"; + } + if (headerVersion < kMinHeaderVersionForLibrary) { + // Headers are too old for library. + GOOGLE_LOG(FATAL) + << "This program was compiled against version " + << VersionString(headerVersion) << " of the Protocol Buffer runtime " + "library, which is not compatible with the installed version (" + << VersionString(GOOGLE_PROTOBUF_VERSION) << "). Contact the program " + "author for an update. If you compiled the program yourself, make " + "sure that your headers are from the same version of Protocol Buffers " + "as your link-time library. (Version verification failed in \"" + << filename << "\".)"; + } +} + +string VersionString(int version) { + int major = version / 1000000; + int minor = (version / 1000) % 1000; + int micro = version % 1000; + + // 128 bytes should always be enough, but we use snprintf() anyway to be + // safe. + char buffer[128]; + snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro); + + // Guard against broken MSVC snprintf(). + buffer[sizeof(buffer)-1] = '\0'; + + return buffer; +} + +} // namespace internal + +// =================================================================== +// emulates google3/base/logging.cc + +namespace internal { + +void DefaultLogHandler(LogLevel level, const char* filename, int line, + const string& message) { + static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" }; + + // We use fprintf() instead of cerr because we want this to work at static + // initialization time. + fprintf(stderr, "[libprotobuf %s %s:%d] %s\n", + level_names[level], filename, line, message.c_str()); + fflush(stderr); // Needed on MSVC. +} + +void NullLogHandler(LogLevel level, const char* filename, int line, + const string& message) { + // Nothing. +} + +static LogHandler* log_handler_ = &DefaultLogHandler; +static int log_silencer_count_ = 0; + +static Mutex* log_silencer_count_mutex_ = NULL; +GOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_); + +void DeleteLogSilencerCount() { + delete log_silencer_count_mutex_; + log_silencer_count_mutex_ = NULL; +} +void InitLogSilencerCount() { + log_silencer_count_mutex_ = new Mutex; + OnShutdown(&DeleteLogSilencerCount); +} +void InitLogSilencerCountOnce() { + GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount); +} + +LogMessage& LogMessage::operator<<(const string& value) { + message_ += value; + return *this; +} + +LogMessage& LogMessage::operator<<(const char* value) { + message_ += value; + return *this; +} + +// Since this is just for logging, we don't care if the current locale changes +// the results -- in fact, we probably prefer that. So we use snprintf() +// instead of Simple*toa(). +#undef DECLARE_STREAM_OPERATOR +#define DECLARE_STREAM_OPERATOR(TYPE, FORMAT) \ + LogMessage& LogMessage::operator<<(TYPE value) { \ + /* 128 bytes should be big enough for any of the primitive */ \ + /* values which we print with this, but well use snprintf() */ \ + /* anyway to be extra safe. */ \ + char buffer[128]; \ + snprintf(buffer, sizeof(buffer), FORMAT, value); \ + /* Guard against broken MSVC snprintf(). */ \ + buffer[sizeof(buffer)-1] = '\0'; \ + message_ += buffer; \ + return *this; \ + } + +DECLARE_STREAM_OPERATOR(char , "%c" ) +DECLARE_STREAM_OPERATOR(int , "%d" ) +DECLARE_STREAM_OPERATOR(uint , "%u" ) +DECLARE_STREAM_OPERATOR(long , "%ld") +DECLARE_STREAM_OPERATOR(unsigned long, "%lu") +DECLARE_STREAM_OPERATOR(double , "%g" ) +#undef DECLARE_STREAM_OPERATOR + +LogMessage::LogMessage(LogLevel level, const char* filename, int line) + : level_(level), filename_(filename), line_(line) {} +LogMessage::~LogMessage() {} + +void LogMessage::Finish() { + bool suppress = false; + + if (level_ != LOGLEVEL_FATAL) { + InitLogSilencerCountOnce(); + MutexLock lock(log_silencer_count_mutex_); + suppress = log_silencer_count_ > 0; + } + + if (!suppress) { + log_handler_(level_, filename_, line_, message_); + } + + if (level_ == LOGLEVEL_FATAL) { +#if PROTOBUF_USE_EXCEPTIONS + throw FatalException(filename_, line_, message_); +#else + abort(); +#endif + } +} + +void LogFinisher::operator=(LogMessage& other) { + other.Finish(); +} + +} // namespace internal + +LogHandler* SetLogHandler(LogHandler* new_func) { + LogHandler* old = internal::log_handler_; + if (old == &internal::NullLogHandler) { + old = NULL; + } + if (new_func == NULL) { + internal::log_handler_ = &internal::NullLogHandler; + } else { + internal::log_handler_ = new_func; + } + return old; +} + +LogSilencer::LogSilencer() { + internal::InitLogSilencerCountOnce(); + MutexLock lock(internal::log_silencer_count_mutex_); + ++internal::log_silencer_count_; +}; + +LogSilencer::~LogSilencer() { + internal::InitLogSilencerCountOnce(); + MutexLock lock(internal::log_silencer_count_mutex_); + --internal::log_silencer_count_; +}; + +// =================================================================== +// emulates google3/base/callback.cc + +Closure::~Closure() {} + +namespace internal { FunctionClosure0::~FunctionClosure0() {} } + +void DoNothing() {} + +// =================================================================== +// emulates google3/base/mutex.cc + +#ifdef _WIN32 + +struct Mutex::Internal { + CRITICAL_SECTION mutex; +#ifndef NDEBUG + // Used only to implement AssertHeld(). + DWORD thread_id; +#endif +}; + +Mutex::Mutex() + : mInternal(new Internal) { + InitializeCriticalSection(&mInternal->mutex); +} + +Mutex::~Mutex() { + DeleteCriticalSection(&mInternal->mutex); + delete mInternal; +} + +void Mutex::Lock() { + EnterCriticalSection(&mInternal->mutex); +#ifndef NDEBUG + mInternal->thread_id = GetCurrentThreadId(); +#endif +} + +void Mutex::Unlock() { +#ifndef NDEBUG + mInternal->thread_id = 0; +#endif + LeaveCriticalSection(&mInternal->mutex); +} + +void Mutex::AssertHeld() { +#ifndef NDEBUG + GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId()); +#endif +} + +#elif defined(HAVE_PTHREAD) + +struct Mutex::Internal { + pthread_mutex_t mutex; +}; + +Mutex::Mutex() + : mInternal(new Internal) { + pthread_mutex_init(&mInternal->mutex, NULL); +} + +Mutex::~Mutex() { + pthread_mutex_destroy(&mInternal->mutex); + delete mInternal; +} + +void Mutex::Lock() { + int result = pthread_mutex_lock(&mInternal->mutex); + if (result != 0) { + GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result); + } +} + +void Mutex::Unlock() { + int result = pthread_mutex_unlock(&mInternal->mutex); + if (result != 0) { + GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result); + } +} + +void Mutex::AssertHeld() { + // pthreads dosn't provide a way to check which thread holds the mutex. + // TODO(kenton): Maybe keep track of locking thread ID like with WIN32? +} + +#endif + +// =================================================================== +// emulates google3/util/endian/endian.h +// +// TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in +// google/protobuf/io/coded_stream.h and therefore can not be used here. +// Maybe move that macro definition here in the furture. +uint32 ghtonl(uint32 x) { + union { + uint32 result; + uint8 result_array[4]; + }; + result_array[0] = static_cast(x >> 24); + result_array[1] = static_cast((x >> 16) & 0xFF); + result_array[2] = static_cast((x >> 8) & 0xFF); + result_array[3] = static_cast(x & 0xFF); + return result; +} + +// =================================================================== +// Shutdown support. + +namespace internal { + +typedef void OnShutdownFunc(); +vector* shutdown_functions = NULL; +Mutex* shutdown_functions_mutex = NULL; +GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init); + +void InitShutdownFunctions() { + shutdown_functions = new vector; + shutdown_functions_mutex = new Mutex; +} + +inline void InitShutdownFunctionsOnce() { + GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions); +} + +void OnShutdown(void (*func)()) { + InitShutdownFunctionsOnce(); + MutexLock lock(shutdown_functions_mutex); + shutdown_functions->push_back(func); +} + +} // namespace internal + +void ShutdownProtobufLibrary() { + internal::InitShutdownFunctionsOnce(); + + // We don't need to lock shutdown_functions_mutex because it's up to the + // caller to make sure that no one is using the library before this is + // called. + + // Make it safe to call this multiple times. + if (internal::shutdown_functions == NULL) return; + + for (int i = 0; i < internal::shutdown_functions->size(); i++) { + internal::shutdown_functions->at(i)(); + } + delete internal::shutdown_functions; + internal::shutdown_functions = NULL; + delete internal::shutdown_functions_mutex; + internal::shutdown_functions_mutex = NULL; +} + +#if PROTOBUF_USE_EXCEPTIONS +FatalException::~FatalException() throw() {} + +const char* FatalException::what() const throw() { + return message_.c_str(); +} +#endif + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common.h new file mode 100644 index 0000000..f287ddf --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common.h @@ -0,0 +1,1223 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) and others +// +// Contains basic types and utilities used by the rest of the library. + +#ifndef GOOGLE_PROTOBUF_COMMON_H__ +#define GOOGLE_PROTOBUF_COMMON_H__ + +#include +#include +#include +#include +#include +#if defined(__osf__) +// Tru64 lacks stdint.h, but has inttypes.h which defines a superset of +// what stdint.h would define. +#include +#elif !defined(_MSC_VER) +#include +#endif + +#ifndef PROTOBUF_USE_EXCEPTIONS +#if defined(_MSC_VER) && defined(_CPPUNWIND) + #define PROTOBUF_USE_EXCEPTIONS 1 +#elif defined(__EXCEPTIONS) + #define PROTOBUF_USE_EXCEPTIONS 1 +#else + #define PROTOBUF_USE_EXCEPTIONS 0 +#endif +#endif + +#if PROTOBUF_USE_EXCEPTIONS +#include +#endif + +#if defined(_WIN32) && defined(GetMessage) +// Allow GetMessage to be used as a valid method name in protobuf classes. +// windows.h defines GetMessage() as a macro. Let's re-define it as an inline +// function. The inline function should be equivalent for C++ users. +inline BOOL GetMessage_Win32( + LPMSG lpMsg, HWND hWnd, + UINT wMsgFilterMin, UINT wMsgFilterMax) { + return GetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); +} +#undef GetMessage +inline BOOL GetMessage( + LPMSG lpMsg, HWND hWnd, + UINT wMsgFilterMin, UINT wMsgFilterMax) { + return GetMessage_Win32(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); +} +#endif + + +namespace std {} + +namespace google { +namespace protobuf { + +#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS +#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +#if defined(_MSC_VER) && defined(PROTOBUF_USE_DLLS) + #ifdef LIBPROTOBUF_EXPORTS + #define LIBPROTOBUF_EXPORT __declspec(dllexport) + #else + #define LIBPROTOBUF_EXPORT __declspec(dllimport) + #endif + #ifdef LIBPROTOC_EXPORTS + #define LIBPROTOC_EXPORT __declspec(dllexport) + #else + #define LIBPROTOC_EXPORT __declspec(dllimport) + #endif +#else + #define LIBPROTOBUF_EXPORT + #define LIBPROTOC_EXPORT +#endif + +namespace internal { + +// Some of these constants are macros rather than const ints so that they can +// be used in #if directives. + +// The current version, represented as a single integer to make comparison +// easier: major * 10^6 + minor * 10^3 + micro +#define GOOGLE_PROTOBUF_VERSION 2005000 + +// The minimum library version which works with the current version of the +// headers. +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2005000 + +// The minimum header version which works with the current version of +// the library. This constant should only be used by protoc's C++ code +// generator. +static const int kMinHeaderVersionForLibrary = 2005000; + +// The minimum protoc version which works with the current version of the +// headers. +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2005000 + +// The minimum header version which works with the current version of +// protoc. This constant should only be used in VerifyVersion(). +static const int kMinHeaderVersionForProtoc = 2005000; + +// Verifies that the headers and libraries are compatible. Use the macro +// below to call this. +void LIBPROTOBUF_EXPORT VerifyVersion(int headerVersion, int minLibraryVersion, + const char* filename); + +// Converts a numeric version number to a string. +std::string LIBPROTOBUF_EXPORT VersionString(int version); + +} // namespace internal + +// Place this macro in your main() function (or somewhere before you attempt +// to use the protobuf library) to verify that the version you link against +// matches the headers you compiled against. If a version mismatch is +// detected, the process will abort. +#define GOOGLE_PROTOBUF_VERIFY_VERSION \ + ::google::protobuf::internal::VerifyVersion( \ + GOOGLE_PROTOBUF_VERSION, GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION, \ + __FILE__) + +// =================================================================== +// from google3/base/port.h + +typedef unsigned int uint; + +#ifdef _MSC_VER +typedef __int8 int8; +typedef __int16 int16; +typedef __int32 int32; +typedef __int64 int64; + +typedef unsigned __int8 uint8; +typedef unsigned __int16 uint16; +typedef unsigned __int32 uint32; +typedef unsigned __int64 uint64; +#else +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef int64_t int64; + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; +#endif + +// long long macros to be used because gcc and vc++ use different suffixes, +// and different size specifiers in format strings +#undef GOOGLE_LONGLONG +#undef GOOGLE_ULONGLONG +#undef GOOGLE_LL_FORMAT + +#ifdef _MSC_VER +#define GOOGLE_LONGLONG(x) x##I64 +#define GOOGLE_ULONGLONG(x) x##UI64 +#define GOOGLE_LL_FORMAT "I64" // As in printf("%I64d", ...) +#else +#define GOOGLE_LONGLONG(x) x##LL +#define GOOGLE_ULONGLONG(x) x##ULL +#define GOOGLE_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also. +#endif + +static const int32 kint32max = 0x7FFFFFFF; +static const int32 kint32min = -kint32max - 1; +static const int64 kint64max = GOOGLE_LONGLONG(0x7FFFFFFFFFFFFFFF); +static const int64 kint64min = -kint64max - 1; +static const uint32 kuint32max = 0xFFFFFFFFu; +static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); + +// ------------------------------------------------------------------- +// Annotations: Some parts of the code have been annotated in ways that might +// be useful to some compilers or tools, but are not supported universally. +// You can #define these annotations yourself if the default implementation +// is not right for you. + +#ifndef GOOGLE_ATTRIBUTE_ALWAYS_INLINE +#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +// For functions we want to force inline. +// Introduced in gcc 3.1. +#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) +#else +// Other compilers will have to figure it out for themselves. +#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE +#endif +#endif + +#ifndef GOOGLE_ATTRIBUTE_DEPRECATED +#ifdef __GNUC__ +// If the method/variable/type is used anywhere, produce a warning. +#define GOOGLE_ATTRIBUTE_DEPRECATED __attribute__((deprecated)) +#else +#define GOOGLE_ATTRIBUTE_DEPRECATED +#endif +#endif + +#ifndef GOOGLE_PREDICT_TRUE +#ifdef __GNUC__ +// Provided at least since GCC 3.0. +#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#else +#define GOOGLE_PREDICT_TRUE +#endif +#endif + +// Delimits a block of code which may write to memory which is simultaneously +// written by other threads, but which has been determined to be thread-safe +// (e.g. because it is an idempotent write). +#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN +#define GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN() +#endif +#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_END +#define GOOGLE_SAFE_CONCURRENT_WRITES_END() +#endif + +// =================================================================== +// from google3/base/basictypes.h + +// The GOOGLE_ARRAYSIZE(arr) macro returns the # of elements in an array arr. +// The expression is a compile-time constant, and therefore can be +// used in defining new arrays, for example. +// +// GOOGLE_ARRAYSIZE catches a few type errors. If you see a compiler error +// +// "warning: division by zero in ..." +// +// when using GOOGLE_ARRAYSIZE, you are (wrongfully) giving it a pointer. +// You should only use GOOGLE_ARRAYSIZE on statically allocated arrays. +// +// The following comments are on the implementation details, and can +// be ignored by the users. +// +// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in +// the array) and sizeof(*(arr)) (the # of bytes in one array +// element). If the former is divisible by the latter, perhaps arr is +// indeed an array, in which case the division result is the # of +// elements in the array. Otherwise, arr cannot possibly be an array, +// and we generate a compiler error to prevent the code from +// compiling. +// +// Since the size of bool is implementation-defined, we need to cast +// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final +// result has type size_t. +// +// This macro is not perfect as it wrongfully accepts certain +// pointers, namely where the pointer size is divisible by the pointee +// size. Since all our code has to go through a 32-bit compiler, +// where a pointer is 4 bytes, this means all pointers to a type whose +// size is 3 or greater than 4 will be (righteously) rejected. +// +// Kudos to Jorg Brown for this simple and elegant implementation. + +#undef GOOGLE_ARRAYSIZE +#define GOOGLE_ARRAYSIZE(a) \ + ((sizeof(a) / sizeof(*(a))) / \ + static_cast(!(sizeof(a) % sizeof(*(a))))) + +namespace internal { + +// Use implicit_cast as a safe version of static_cast or const_cast +// for upcasting in the type hierarchy (i.e. casting a pointer to Foo +// to a pointer to SuperclassOfFoo or casting a pointer to Foo to +// a const pointer to Foo). +// When you use implicit_cast, the compiler checks that the cast is safe. +// Such explicit implicit_casts are necessary in surprisingly many +// situations where C++ demands an exact type match instead of an +// argument type convertable to a target type. +// +// The From type can be inferred, so the preferred syntax for using +// implicit_cast is the same as for static_cast etc.: +// +// implicit_cast(expr) +// +// implicit_cast would have been part of the C++ standard library, +// but the proposal was submitted too late. It will probably make +// its way into the language in the future. +template +inline To implicit_cast(From const &f) { + return f; +} + +// When you upcast (that is, cast a pointer from type Foo to type +// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts +// always succeed. When you downcast (that is, cast a pointer from +// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because +// how do you know the pointer is really of type SubclassOfFoo? It +// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, +// when you downcast, you should use this macro. In debug mode, we +// use dynamic_cast<> to double-check the downcast is legal (we die +// if it's not). In normal mode, we do the efficient static_cast<> +// instead. Thus, it's important to test in debug mode to make sure +// the cast is legal! +// This is the only place in the code we should use dynamic_cast<>. +// In particular, you SHOULDN'T be using dynamic_cast<> in order to +// do RTTI (eg code like this: +// if (dynamic_cast(foo)) HandleASubclass1Object(foo); +// if (dynamic_cast(foo)) HandleASubclass2Object(foo); +// You should design the code some other way not to need this. + +template // use like this: down_cast(foo); +inline To down_cast(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) { + implicit_cast(0); + } + +#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI) + assert(f == NULL || dynamic_cast(f) != NULL); // RTTI: debug mode only! +#endif + return static_cast(f); +} + +} // namespace internal + +// We made these internal so that they would show up as such in the docs, +// but we don't want to stick "internal::" in front of them everywhere. +using internal::implicit_cast; +using internal::down_cast; + +// The COMPILE_ASSERT macro can be used to verify that a compile time +// expression is true. For example, you could use it to verify the +// size of a static array: +// +// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, +// content_type_names_incorrect_size); +// +// or to make sure a struct is smaller than a certain size: +// +// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); +// +// The second argument to the macro is the name of the variable. If +// the expression is false, most compilers will issue a warning/error +// containing the name of the variable. + +namespace internal { + +template +struct CompileAssert { +}; + +} // namespace internal + +#undef GOOGLE_COMPILE_ASSERT +#define GOOGLE_COMPILE_ASSERT(expr, msg) \ + typedef ::google::protobuf::internal::CompileAssert<(bool(expr))> \ + msg[bool(expr) ? 1 : -1] + + +// Implementation details of COMPILE_ASSERT: +// +// - COMPILE_ASSERT works by defining an array type that has -1 +// elements (and thus is invalid) when the expression is false. +// +// - The simpler definition +// +// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] +// +// does not work, as gcc supports variable-length arrays whose sizes +// are determined at run-time (this is gcc's extension and not part +// of the C++ standard). As a result, gcc fails to reject the +// following code with the simple definition: +// +// int foo; +// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is +// // not a compile-time constant. +// +// - By using the type CompileAssert<(bool(expr))>, we ensures that +// expr is a compile-time constant. (Template arguments must be +// determined at compile-time.) +// +// - The outter parentheses in CompileAssert<(bool(expr))> are necessary +// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written +// +// CompileAssert +// +// instead, these compilers will refuse to compile +// +// COMPILE_ASSERT(5 > 0, some_message); +// +// (They seem to think the ">" in "5 > 0" marks the end of the +// template argument list.) +// +// - The array size is (bool(expr) ? 1 : -1), instead of simply +// +// ((expr) ? 1 : -1). +// +// This is to avoid running into a bug in MS VC 7.1, which +// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. + +// =================================================================== +// from google3/base/scoped_ptr.h + +namespace internal { + +// This is an implementation designed to match the anticipated future TR2 +// implementation of the scoped_ptr class, and its closely-related brethren, +// scoped_array, scoped_ptr_malloc, and make_scoped_ptr. + +template class scoped_ptr; +template class scoped_array; + +// A scoped_ptr is like a T*, except that the destructor of scoped_ptr +// automatically deletes the pointer it holds (if any). +// That is, scoped_ptr owns the T object that it points to. +// Like a T*, a scoped_ptr may hold either NULL or a pointer to a T object. +// +// The size of a scoped_ptr is small: +// sizeof(scoped_ptr) == sizeof(C*) +template +class scoped_ptr { + public: + + // The element type + typedef C element_type; + + // Constructor. Defaults to intializing with NULL. + // There is no way to create an uninitialized scoped_ptr. + // The input parameter must be allocated with new. + explicit scoped_ptr(C* p = NULL) : ptr_(p) { } + + // Destructor. If there is a C object, delete it. + // We don't need to test ptr_ == NULL because C++ does that for us. + ~scoped_ptr() { + enum { type_must_be_complete = sizeof(C) }; + delete ptr_; + } + + // Reset. Deletes the current owned object, if any. + // Then takes ownership of a new object, if given. + // this->reset(this->get()) works. + void reset(C* p = NULL) { + if (p != ptr_) { + enum { type_must_be_complete = sizeof(C) }; + delete ptr_; + ptr_ = p; + } + } + + // Accessors to get the owned object. + // operator* and operator-> will assert() if there is no current object. + C& operator*() const { + assert(ptr_ != NULL); + return *ptr_; + } + C* operator->() const { + assert(ptr_ != NULL); + return ptr_; + } + C* get() const { return ptr_; } + + // Comparison operators. + // These return whether two scoped_ptr refer to the same object, not just to + // two different but equal objects. + bool operator==(C* p) const { return ptr_ == p; } + bool operator!=(C* p) const { return ptr_ != p; } + + // Swap two scoped pointers. + void swap(scoped_ptr& p2) { + C* tmp = ptr_; + ptr_ = p2.ptr_; + p2.ptr_ = tmp; + } + + // Release a pointer. + // The return value is the current pointer held by this object. + // If this object holds a NULL pointer, the return value is NULL. + // After this operation, this object will hold a NULL pointer, + // and will not own the object any more. + C* release() { + C* retVal = ptr_; + ptr_ = NULL; + return retVal; + } + + private: + C* ptr_; + + // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't + // make sense, and if C2 == C, it still doesn't make sense because you should + // never have the same object owned by two different scoped_ptrs. + template bool operator==(scoped_ptr const& p2) const; + template bool operator!=(scoped_ptr const& p2) const; + + // Disallow evil constructors + scoped_ptr(const scoped_ptr&); + void operator=(const scoped_ptr&); +}; + +// scoped_array is like scoped_ptr, except that the caller must allocate +// with new [] and the destructor deletes objects with delete []. +// +// As with scoped_ptr, a scoped_array either points to an object +// or is NULL. A scoped_array owns the object that it points to. +// +// Size: sizeof(scoped_array) == sizeof(C*) +template +class scoped_array { + public: + + // The element type + typedef C element_type; + + // Constructor. Defaults to intializing with NULL. + // There is no way to create an uninitialized scoped_array. + // The input parameter must be allocated with new []. + explicit scoped_array(C* p = NULL) : array_(p) { } + + // Destructor. If there is a C object, delete it. + // We don't need to test ptr_ == NULL because C++ does that for us. + ~scoped_array() { + enum { type_must_be_complete = sizeof(C) }; + delete[] array_; + } + + // Reset. Deletes the current owned object, if any. + // Then takes ownership of a new object, if given. + // this->reset(this->get()) works. + void reset(C* p = NULL) { + if (p != array_) { + enum { type_must_be_complete = sizeof(C) }; + delete[] array_; + array_ = p; + } + } + + // Get one element of the current object. + // Will assert() if there is no current object, or index i is negative. + C& operator[](std::ptrdiff_t i) const { + assert(i >= 0); + assert(array_ != NULL); + return array_[i]; + } + + // Get a pointer to the zeroth element of the current object. + // If there is no current object, return NULL. + C* get() const { + return array_; + } + + // Comparison operators. + // These return whether two scoped_array refer to the same object, not just to + // two different but equal objects. + bool operator==(C* p) const { return array_ == p; } + bool operator!=(C* p) const { return array_ != p; } + + // Swap two scoped arrays. + void swap(scoped_array& p2) { + C* tmp = array_; + array_ = p2.array_; + p2.array_ = tmp; + } + + // Release an array. + // The return value is the current pointer held by this object. + // If this object holds a NULL pointer, the return value is NULL. + // After this operation, this object will hold a NULL pointer, + // and will not own the object any more. + C* release() { + C* retVal = array_; + array_ = NULL; + return retVal; + } + + private: + C* array_; + + // Forbid comparison of different scoped_array types. + template bool operator==(scoped_array const& p2) const; + template bool operator!=(scoped_array const& p2) const; + + // Disallow evil constructors + scoped_array(const scoped_array&); + void operator=(const scoped_array&); +}; + +} // namespace internal + +// We made these internal so that they would show up as such in the docs, +// but we don't want to stick "internal::" in front of them everywhere. +using internal::scoped_ptr; +using internal::scoped_array; + +// =================================================================== +// emulates google3/base/logging.h + +enum LogLevel { + LOGLEVEL_INFO, // Informational. This is never actually used by + // libprotobuf. + LOGLEVEL_WARNING, // Warns about issues that, although not technically a + // problem now, could cause problems in the future. For + // example, a // warning will be printed when parsing a + // message that is near the message size limit. + LOGLEVEL_ERROR, // An error occurred which should never happen during + // normal use. + LOGLEVEL_FATAL, // An error occurred from which the library cannot + // recover. This usually indicates a programming error + // in the code which calls the library, especially when + // compiled in debug mode. + +#ifdef NDEBUG + LOGLEVEL_DFATAL = LOGLEVEL_ERROR +#else + LOGLEVEL_DFATAL = LOGLEVEL_FATAL +#endif +}; + +namespace internal { + +class LogFinisher; + +class LIBPROTOBUF_EXPORT LogMessage { + public: + LogMessage(LogLevel level, const char* filename, int line); + ~LogMessage(); + + LogMessage& operator<<(const std::string& value); + LogMessage& operator<<(const char* value); + LogMessage& operator<<(char value); + LogMessage& operator<<(int value); + LogMessage& operator<<(uint value); + LogMessage& operator<<(long value); + LogMessage& operator<<(unsigned long value); + LogMessage& operator<<(double value); + + private: + friend class LogFinisher; + void Finish(); + + LogLevel level_; + const char* filename_; + int line_; + std::string message_; +}; + +// Used to make the entire "LOG(BLAH) << etc." expression have a void return +// type and print a newline after each message. +class LIBPROTOBUF_EXPORT LogFinisher { + public: + void operator=(LogMessage& other); +}; + +} // namespace internal + +// Undef everything in case we're being mixed with some other Google library +// which already defined them itself. Presumably all Google libraries will +// support the same syntax for these so it should not be a big deal if they +// end up using our definitions instead. +#undef GOOGLE_LOG +#undef GOOGLE_LOG_IF + +#undef GOOGLE_CHECK +#undef GOOGLE_CHECK_EQ +#undef GOOGLE_CHECK_NE +#undef GOOGLE_CHECK_LT +#undef GOOGLE_CHECK_LE +#undef GOOGLE_CHECK_GT +#undef GOOGLE_CHECK_GE +#undef GOOGLE_CHECK_NOTNULL + +#undef GOOGLE_DLOG +#undef GOOGLE_DCHECK +#undef GOOGLE_DCHECK_EQ +#undef GOOGLE_DCHECK_NE +#undef GOOGLE_DCHECK_LT +#undef GOOGLE_DCHECK_LE +#undef GOOGLE_DCHECK_GT +#undef GOOGLE_DCHECK_GE + +#define GOOGLE_LOG(LEVEL) \ + ::google::protobuf::internal::LogFinisher() = \ + ::google::protobuf::internal::LogMessage( \ + ::google::protobuf::LOGLEVEL_##LEVEL, __FILE__, __LINE__) +#define GOOGLE_LOG_IF(LEVEL, CONDITION) \ + !(CONDITION) ? (void)0 : GOOGLE_LOG(LEVEL) + +#define GOOGLE_CHECK(EXPRESSION) \ + GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": " +#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK((A) == (B)) +#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK((A) != (B)) +#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK((A) < (B)) +#define GOOGLE_CHECK_LE(A, B) GOOGLE_CHECK((A) <= (B)) +#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK((A) > (B)) +#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK((A) >= (B)) + +namespace internal { +template +T* CheckNotNull(const char *file, int line, const char *name, T* val) { + if (val == NULL) { + GOOGLE_LOG(FATAL) << name; + } + return val; +} +} // namespace internal +#define GOOGLE_CHECK_NOTNULL(A) \ + internal::CheckNotNull(__FILE__, __LINE__, "'" #A "' must not be NULL", (A)) + +#ifdef NDEBUG + +#define GOOGLE_DLOG GOOGLE_LOG_IF(INFO, false) + +#define GOOGLE_DCHECK(EXPRESSION) while(false) GOOGLE_CHECK(EXPRESSION) +#define GOOGLE_DCHECK_EQ(A, B) GOOGLE_DCHECK((A) == (B)) +#define GOOGLE_DCHECK_NE(A, B) GOOGLE_DCHECK((A) != (B)) +#define GOOGLE_DCHECK_LT(A, B) GOOGLE_DCHECK((A) < (B)) +#define GOOGLE_DCHECK_LE(A, B) GOOGLE_DCHECK((A) <= (B)) +#define GOOGLE_DCHECK_GT(A, B) GOOGLE_DCHECK((A) > (B)) +#define GOOGLE_DCHECK_GE(A, B) GOOGLE_DCHECK((A) >= (B)) + +#else // NDEBUG + +#define GOOGLE_DLOG GOOGLE_LOG + +#define GOOGLE_DCHECK GOOGLE_CHECK +#define GOOGLE_DCHECK_EQ GOOGLE_CHECK_EQ +#define GOOGLE_DCHECK_NE GOOGLE_CHECK_NE +#define GOOGLE_DCHECK_LT GOOGLE_CHECK_LT +#define GOOGLE_DCHECK_LE GOOGLE_CHECK_LE +#define GOOGLE_DCHECK_GT GOOGLE_CHECK_GT +#define GOOGLE_DCHECK_GE GOOGLE_CHECK_GE + +#endif // !NDEBUG + +typedef void LogHandler(LogLevel level, const char* filename, int line, + const std::string& message); + +// The protobuf library sometimes writes warning and error messages to +// stderr. These messages are primarily useful for developers, but may +// also help end users figure out a problem. If you would prefer that +// these messages be sent somewhere other than stderr, call SetLogHandler() +// to set your own handler. This returns the old handler. Set the handler +// to NULL to ignore log messages (but see also LogSilencer, below). +// +// Obviously, SetLogHandler is not thread-safe. You should only call it +// at initialization time, and probably not from library code. If you +// simply want to suppress log messages temporarily (e.g. because you +// have some code that tends to trigger them frequently and you know +// the warnings are not important to you), use the LogSilencer class +// below. +LIBPROTOBUF_EXPORT LogHandler* SetLogHandler(LogHandler* new_func); + +// Create a LogSilencer if you want to temporarily suppress all log +// messages. As long as any LogSilencer objects exist, non-fatal +// log messages will be discarded (the current LogHandler will *not* +// be called). Constructing a LogSilencer is thread-safe. You may +// accidentally suppress log messages occurring in another thread, but +// since messages are generally for debugging purposes only, this isn't +// a big deal. If you want to intercept log messages, use SetLogHandler(). +class LIBPROTOBUF_EXPORT LogSilencer { + public: + LogSilencer(); + ~LogSilencer(); +}; + +// =================================================================== +// emulates google3/base/callback.h + +// Abstract interface for a callback. When calling an RPC, you must provide +// a Closure to call when the procedure completes. See the Service interface +// in service.h. +// +// To automatically construct a Closure which calls a particular function or +// method with a particular set of parameters, use the NewCallback() function. +// Example: +// void FooDone(const FooResponse* response) { +// ... +// } +// +// void CallFoo() { +// ... +// // When done, call FooDone() and pass it a pointer to the response. +// Closure* callback = NewCallback(&FooDone, response); +// // Make the call. +// service->Foo(controller, request, response, callback); +// } +// +// Example that calls a method: +// class Handler { +// public: +// ... +// +// void FooDone(const FooResponse* response) { +// ... +// } +// +// void CallFoo() { +// ... +// // When done, call FooDone() and pass it a pointer to the response. +// Closure* callback = NewCallback(this, &Handler::FooDone, response); +// // Make the call. +// service->Foo(controller, request, response, callback); +// } +// }; +// +// Currently NewCallback() supports binding zero, one, or two arguments. +// +// Callbacks created with NewCallback() automatically delete themselves when +// executed. They should be used when a callback is to be called exactly +// once (usually the case with RPC callbacks). If a callback may be called +// a different number of times (including zero), create it with +// NewPermanentCallback() instead. You are then responsible for deleting the +// callback (using the "delete" keyword as normal). +// +// Note that NewCallback() is a bit touchy regarding argument types. Generally, +// the values you provide for the parameter bindings must exactly match the +// types accepted by the callback function. For example: +// void Foo(string s); +// NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string +// NewCallback(&Foo, string("foo")); // WORKS +// Also note that the arguments cannot be references: +// void Foo(const string& s); +// string my_str; +// NewCallback(&Foo, my_str); // WON'T WORK: Can't use referecnes. +// However, correctly-typed pointers will work just fine. +class LIBPROTOBUF_EXPORT Closure { + public: + Closure() {} + virtual ~Closure(); + + virtual void Run() = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure); +}; + +namespace internal { + +class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure { + public: + typedef void (*FunctionType)(); + + FunctionClosure0(FunctionType function, bool self_deleting) + : function_(function), self_deleting_(self_deleting) {} + ~FunctionClosure0(); + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; +}; + +template +class MethodClosure0 : public Closure { + public: + typedef void (Class::*MethodType)(); + + MethodClosure0(Class* object, MethodType method, bool self_deleting) + : object_(object), method_(method), self_deleting_(self_deleting) {} + ~MethodClosure0() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; +}; + +template +class FunctionClosure1 : public Closure { + public: + typedef void (*FunctionType)(Arg1 arg1); + + FunctionClosure1(FunctionType function, bool self_deleting, + Arg1 arg1) + : function_(function), self_deleting_(self_deleting), + arg1_(arg1) {} + ~FunctionClosure1() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(arg1_); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; + Arg1 arg1_; +}; + +template +class MethodClosure1 : public Closure { + public: + typedef void (Class::*MethodType)(Arg1 arg1); + + MethodClosure1(Class* object, MethodType method, bool self_deleting, + Arg1 arg1) + : object_(object), method_(method), self_deleting_(self_deleting), + arg1_(arg1) {} + ~MethodClosure1() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(arg1_); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; + Arg1 arg1_; +}; + +template +class FunctionClosure2 : public Closure { + public: + typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2); + + FunctionClosure2(FunctionType function, bool self_deleting, + Arg1 arg1, Arg2 arg2) + : function_(function), self_deleting_(self_deleting), + arg1_(arg1), arg2_(arg2) {} + ~FunctionClosure2() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(arg1_, arg2_); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; + Arg1 arg1_; + Arg2 arg2_; +}; + +template +class MethodClosure2 : public Closure { + public: + typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2); + + MethodClosure2(Class* object, MethodType method, bool self_deleting, + Arg1 arg1, Arg2 arg2) + : object_(object), method_(method), self_deleting_(self_deleting), + arg1_(arg1), arg2_(arg2) {} + ~MethodClosure2() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(arg1_, arg2_); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; + Arg1 arg1_; + Arg2 arg2_; +}; + +} // namespace internal + +// See Closure. +inline Closure* NewCallback(void (*function)()) { + return new internal::FunctionClosure0(function, true); +} + +// See Closure. +inline Closure* NewPermanentCallback(void (*function)()) { + return new internal::FunctionClosure0(function, false); +} + +// See Closure. +template +inline Closure* NewCallback(Class* object, void (Class::*method)()) { + return new internal::MethodClosure0(object, method, true); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) { + return new internal::MethodClosure0(object, method, false); +} + +// See Closure. +template +inline Closure* NewCallback(void (*function)(Arg1), + Arg1 arg1) { + return new internal::FunctionClosure1(function, true, arg1); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(void (*function)(Arg1), + Arg1 arg1) { + return new internal::FunctionClosure1(function, false, arg1); +} + +// See Closure. +template +inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1), + Arg1 arg1) { + return new internal::MethodClosure1(object, method, true, arg1); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1), + Arg1 arg1) { + return new internal::MethodClosure1(object, method, false, arg1); +} + +// See Closure. +template +inline Closure* NewCallback(void (*function)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::FunctionClosure2( + function, true, arg1, arg2); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::FunctionClosure2( + function, false, arg1, arg2); +} + +// See Closure. +template +inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::MethodClosure2( + object, method, true, arg1, arg2); +} + +// See Closure. +template +inline Closure* NewPermanentCallback( + Class* object, void (Class::*method)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::MethodClosure2( + object, method, false, arg1, arg2); +} + +// A function which does nothing. Useful for creating no-op callbacks, e.g.: +// Closure* nothing = NewCallback(&DoNothing); +void LIBPROTOBUF_EXPORT DoNothing(); + +// =================================================================== +// emulates google3/base/mutex.h + +namespace internal { + +// A Mutex is a non-reentrant (aka non-recursive) mutex. At most one thread T +// may hold a mutex at a given time. If T attempts to Lock() the same Mutex +// while holding it, T will deadlock. +class LIBPROTOBUF_EXPORT Mutex { + public: + // Create a Mutex that is not held by anybody. + Mutex(); + + // Destructor + ~Mutex(); + + // Block if necessary until this Mutex is free, then acquire it exclusively. + void Lock(); + + // Release this Mutex. Caller must hold it exclusively. + void Unlock(); + + // Crash if this Mutex is not held exclusively by this thread. + // May fail to crash when it should; will never crash when it should not. + void AssertHeld(); + + private: + struct Internal; + Internal* mInternal; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex); +}; + +// MutexLock(mu) acquires mu when constructed and releases it when destroyed. +class LIBPROTOBUF_EXPORT MutexLock { + public: + explicit MutexLock(Mutex *mu) : mu_(mu) { this->mu_->Lock(); } + ~MutexLock() { this->mu_->Unlock(); } + private: + Mutex *const mu_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock); +}; + +// TODO(kenton): Implement these? Hard to implement portably. +typedef MutexLock ReaderMutexLock; +typedef MutexLock WriterMutexLock; + +// MutexLockMaybe is like MutexLock, but is a no-op when mu is NULL. +class LIBPROTOBUF_EXPORT MutexLockMaybe { + public: + explicit MutexLockMaybe(Mutex *mu) : + mu_(mu) { if (this->mu_ != NULL) { this->mu_->Lock(); } } + ~MutexLockMaybe() { if (this->mu_ != NULL) { this->mu_->Unlock(); } } + private: + Mutex *const mu_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe); +}; + +} // namespace internal + +// We made these internal so that they would show up as such in the docs, +// but we don't want to stick "internal::" in front of them everywhere. +using internal::Mutex; +using internal::MutexLock; +using internal::ReaderMutexLock; +using internal::WriterMutexLock; +using internal::MutexLockMaybe; + +// =================================================================== +// from google3/util/utf8/public/unilib.h + +namespace internal { + +// Checks if the buffer contains structurally-valid UTF-8. Implemented in +// structurally_valid.cc. +LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len); + +} // namespace internal + +// =================================================================== +// from google3/util/endian/endian.h +LIBPROTOBUF_EXPORT uint32 ghtonl(uint32 x); + +// =================================================================== +// Shutdown support. + +// Shut down the entire protocol buffers library, deleting all static-duration +// objects allocated by the library or by generated .pb.cc files. +// +// There are two reasons you might want to call this: +// * You use a draconian definition of "memory leak" in which you expect +// every single malloc() to have a corresponding free(), even for objects +// which live until program exit. +// * You are writing a dynamically-loaded library which needs to clean up +// after itself when the library is unloaded. +// +// It is safe to call this multiple times. However, it is not safe to use +// any other part of the protocol buffers library after +// ShutdownProtobufLibrary() has been called. +LIBPROTOBUF_EXPORT void ShutdownProtobufLibrary(); + +namespace internal { + +// Register a function to be called when ShutdownProtocolBuffers() is called. +LIBPROTOBUF_EXPORT void OnShutdown(void (*func)()); + +} // namespace internal + +#if PROTOBUF_USE_EXCEPTIONS +class FatalException : public std::exception { + public: + FatalException(const char* filename, int line, const std::string& message) + : filename_(filename), line_(line), message_(message) {} + virtual ~FatalException() throw(); + + virtual const char* what() const throw(); + + const char* filename() const { return filename_; } + int line() const { return line_; } + const std::string& message() const { return message_; } + + private: + const char* filename_; + const int line_; + const std::string message_; +}; +#endif + +// This is at the end of the file instead of the beginning to work around a bug +// in some versions of MSVC. +using namespace std; // Don't do this at home, kids. + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMMON_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common_unittest.cc new file mode 100644 index 0000000..43cd6d0 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/common_unittest.cc @@ -0,0 +1,357 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include +#include +#include +#include + +#include +#include + +#include "config.h" + +namespace google { +namespace protobuf { +namespace { + +// TODO(kenton): More tests. + +#ifdef PACKAGE_VERSION // only defined when using automake, not MSVC + +TEST(VersionTest, VersionMatchesConfig) { + // Verify that the version string specified in config.h matches the one + // in common.h. The config.h version is a string which may have a suffix + // like "beta" or "rc1", so we remove that. + string version = PACKAGE_VERSION; + int pos = 0; + while (pos < version.size() && + (ascii_isdigit(version[pos]) || version[pos] == '.')) { + ++pos; + } + version.erase(pos); + + EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION)); +} + +#endif // PACKAGE_VERSION + +TEST(CommonTest, IntMinMaxConstants) { + // kint32min was declared incorrectly in the first release of protobufs. + // Ugh. + EXPECT_LT(kint32min, kint32max); + EXPECT_EQ(static_cast(kint32min), static_cast(kint32max) + 1); + EXPECT_LT(kint64min, kint64max); + EXPECT_EQ(static_cast(kint64min), static_cast(kint64max) + 1); + EXPECT_EQ(0, kuint32max + 1); + EXPECT_EQ(0, kuint64max + 1); +} + +vector captured_messages_; + +void CaptureLog(LogLevel level, const char* filename, int line, + const string& message) { + captured_messages_.push_back( + strings::Substitute("$0 $1:$2: $3", + implicit_cast(level), filename, line, message)); +} + +TEST(LoggingTest, DefaultLogging) { + CaptureTestStderr(); + int line = __LINE__; + GOOGLE_LOG(INFO ) << "A message."; + GOOGLE_LOG(WARNING) << "A warning."; + GOOGLE_LOG(ERROR ) << "An error."; + + string text = GetCapturedTestStderr(); + EXPECT_EQ( + "[libprotobuf INFO "__FILE__":" + SimpleItoa(line + 1) + "] A message.\n" + "[libprotobuf WARNING "__FILE__":" + SimpleItoa(line + 2) + "] A warning.\n" + "[libprotobuf ERROR "__FILE__":" + SimpleItoa(line + 3) + "] An error.\n", + text); +} + +TEST(LoggingTest, NullLogging) { + LogHandler* old_handler = SetLogHandler(NULL); + + CaptureTestStderr(); + GOOGLE_LOG(INFO ) << "A message."; + GOOGLE_LOG(WARNING) << "A warning."; + GOOGLE_LOG(ERROR ) << "An error."; + + EXPECT_TRUE(SetLogHandler(old_handler) == NULL); + + string text = GetCapturedTestStderr(); + EXPECT_EQ("", text); +} + +TEST(LoggingTest, CaptureLogging) { + captured_messages_.clear(); + + LogHandler* old_handler = SetLogHandler(&CaptureLog); + + int start_line = __LINE__; + GOOGLE_LOG(ERROR) << "An error."; + GOOGLE_LOG(WARNING) << "A warning."; + + EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog); + + ASSERT_EQ(2, captured_messages_.size()); + EXPECT_EQ( + "2 "__FILE__":" + SimpleItoa(start_line + 1) + ": An error.", + captured_messages_[0]); + EXPECT_EQ( + "1 "__FILE__":" + SimpleItoa(start_line + 2) + ": A warning.", + captured_messages_[1]); +} + +TEST(LoggingTest, SilenceLogging) { + captured_messages_.clear(); + + LogHandler* old_handler = SetLogHandler(&CaptureLog); + + int line1 = __LINE__; GOOGLE_LOG(INFO) << "Visible1"; + LogSilencer* silencer1 = new LogSilencer; + GOOGLE_LOG(INFO) << "Not visible."; + LogSilencer* silencer2 = new LogSilencer; + GOOGLE_LOG(INFO) << "Not visible."; + delete silencer1; + GOOGLE_LOG(INFO) << "Not visible."; + delete silencer2; + int line2 = __LINE__; GOOGLE_LOG(INFO) << "Visible2"; + + EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog); + + ASSERT_EQ(2, captured_messages_.size()); + EXPECT_EQ( + "0 "__FILE__":" + SimpleItoa(line1) + ": Visible1", + captured_messages_[0]); + EXPECT_EQ( + "0 "__FILE__":" + SimpleItoa(line2) + ": Visible2", + captured_messages_[1]); +} + +class ClosureTest : public testing::Test { + public: + void SetA123Method() { a_ = 123; } + static void SetA123Function() { current_instance_->a_ = 123; } + + void SetAMethod(int a) { a_ = a; } + void SetCMethod(string c) { c_ = c; } + + static void SetAFunction(int a) { current_instance_->a_ = a; } + static void SetCFunction(string c) { current_instance_->c_ = c; } + + void SetABMethod(int a, const char* b) { a_ = a; b_ = b; } + static void SetABFunction(int a, const char* b) { + current_instance_->a_ = a; + current_instance_->b_ = b; + } + + virtual void SetUp() { + current_instance_ = this; + a_ = 0; + b_ = NULL; + c_.clear(); + permanent_closure_ = NULL; + } + + void DeleteClosureInCallback() { + delete permanent_closure_; + } + + int a_; + const char* b_; + string c_; + Closure* permanent_closure_; + + static ClosureTest* current_instance_; +}; + +ClosureTest* ClosureTest::current_instance_ = NULL; + +TEST_F(ClosureTest, TestClosureFunction0) { + Closure* closure = NewCallback(&SetA123Function); + EXPECT_NE(123, a_); + closure->Run(); + EXPECT_EQ(123, a_); +} + +TEST_F(ClosureTest, TestClosureMethod0) { + Closure* closure = NewCallback(current_instance_, + &ClosureTest::SetA123Method); + EXPECT_NE(123, a_); + closure->Run(); + EXPECT_EQ(123, a_); +} + +TEST_F(ClosureTest, TestClosureFunction1) { + Closure* closure = NewCallback(&SetAFunction, 456); + EXPECT_NE(456, a_); + closure->Run(); + EXPECT_EQ(456, a_); +} + +TEST_F(ClosureTest, TestClosureMethod1) { + Closure* closure = NewCallback(current_instance_, + &ClosureTest::SetAMethod, 456); + EXPECT_NE(456, a_); + closure->Run(); + EXPECT_EQ(456, a_); +} + +TEST_F(ClosureTest, TestClosureFunction1String) { + Closure* closure = NewCallback(&SetCFunction, string("test")); + EXPECT_NE("test", c_); + closure->Run(); + EXPECT_EQ("test", c_); +} + +TEST_F(ClosureTest, TestClosureMethod1String) { + Closure* closure = NewCallback(current_instance_, + &ClosureTest::SetCMethod, string("test")); + EXPECT_NE("test", c_); + closure->Run(); + EXPECT_EQ("test", c_); +} + +TEST_F(ClosureTest, TestClosureFunction2) { + const char* cstr = "hello"; + Closure* closure = NewCallback(&SetABFunction, 789, cstr); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); +} + +TEST_F(ClosureTest, TestClosureMethod2) { + const char* cstr = "hello"; + Closure* closure = NewCallback(current_instance_, + &ClosureTest::SetABMethod, 789, cstr); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); +} + +// Repeat all of the above with NewPermanentCallback() + +TEST_F(ClosureTest, TestPermanentClosureFunction0) { + Closure* closure = NewPermanentCallback(&SetA123Function); + EXPECT_NE(123, a_); + closure->Run(); + EXPECT_EQ(123, a_); + a_ = 0; + closure->Run(); + EXPECT_EQ(123, a_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureMethod0) { + Closure* closure = NewPermanentCallback(current_instance_, + &ClosureTest::SetA123Method); + EXPECT_NE(123, a_); + closure->Run(); + EXPECT_EQ(123, a_); + a_ = 0; + closure->Run(); + EXPECT_EQ(123, a_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureFunction1) { + Closure* closure = NewPermanentCallback(&SetAFunction, 456); + EXPECT_NE(456, a_); + closure->Run(); + EXPECT_EQ(456, a_); + a_ = 0; + closure->Run(); + EXPECT_EQ(456, a_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureMethod1) { + Closure* closure = NewPermanentCallback(current_instance_, + &ClosureTest::SetAMethod, 456); + EXPECT_NE(456, a_); + closure->Run(); + EXPECT_EQ(456, a_); + a_ = 0; + closure->Run(); + EXPECT_EQ(456, a_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureFunction2) { + const char* cstr = "hello"; + Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + a_ = 0; + b_ = NULL; + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureMethod2) { + const char* cstr = "hello"; + Closure* closure = NewPermanentCallback(current_instance_, + &ClosureTest::SetABMethod, 789, cstr); + EXPECT_NE(789, a_); + EXPECT_NE(cstr, b_); + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + a_ = 0; + b_ = NULL; + closure->Run(); + EXPECT_EQ(789, a_); + EXPECT_EQ(cstr, b_); + delete closure; +} + +TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) { + permanent_closure_ = NewPermanentCallback((ClosureTest*) this, + &ClosureTest::DeleteClosureInCallback); + permanent_closure_->Run(); +} + +} // anonymous namespace +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/hash.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/hash.h new file mode 100644 index 0000000..f7d1071 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/hash.h @@ -0,0 +1,232 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// Deals with the fact that hash_map is not defined everywhere. + +#ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__ +#define GOOGLE_PROTOBUF_STUBS_HASH_H__ + +#include +#include +#include "config.h" + +#if defined(HAVE_HASH_MAP) && defined(HAVE_HASH_SET) +#include HASH_MAP_H +#include HASH_SET_H +#else +#define MISSING_HASH +#include +#include +#endif + +namespace google { +namespace protobuf { + +#ifdef MISSING_HASH + +// This system doesn't have hash_map or hash_set. Emulate them using map and +// set. + +// Make hash be the same as less. Note that everywhere where custom +// hash functions are defined in the protobuf code, they are also defined such +// that they can be used as "less" functions, which is required by MSVC anyway. +template +struct hash { + // Dummy, just to make derivative hash functions compile. + int operator()(const Key& key) { + GOOGLE_LOG(FATAL) << "Should never be called."; + return 0; + } + + inline bool operator()(const Key& a, const Key& b) const { + return a < b; + } +}; + +// Make sure char* is compared by value. +template <> +struct hash { + // Dummy, just to make derivative hash functions compile. + int operator()(const char* key) { + GOOGLE_LOG(FATAL) << "Should never be called."; + return 0; + } + + inline bool operator()(const char* a, const char* b) const { + return strcmp(a, b) < 0; + } +}; + +template , + typename EqualKey = int > +class hash_map : public std::map { + public: + hash_map(int = 0) {} +}; + +template , + typename EqualKey = int > +class hash_set : public std::set { + public: + hash_set(int = 0) {} +}; + +#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION) + +template +struct hash : public HASH_NAMESPACE::hash_compare { +}; + +// MSVC's hash_compare hashes based on the string contents but +// compares based on the string pointer. WTF? +class CstringLess { + public: + inline bool operator()(const char* a, const char* b) const { + return strcmp(a, b) < 0; + } +}; + +template <> +struct hash + : public HASH_NAMESPACE::hash_compare { +}; + +template , + typename EqualKey = int > +class hash_map : public HASH_NAMESPACE::hash_map< + Key, Data, HashFcn> { + public: + hash_map(int = 0) {} +}; + +template , + typename EqualKey = int > +class hash_set : public HASH_NAMESPACE::hash_set< + Key, HashFcn> { + public: + hash_set(int = 0) {} +}; + +#else + +template +struct hash : public HASH_NAMESPACE::hash { +}; + +template +struct hash { + inline size_t operator()(const Key* key) const { + return reinterpret_cast(key); + } +}; + +// Unlike the old SGI version, the TR1 "hash" does not special-case char*. So, +// we go ahead and provide our own implementation. +template <> +struct hash { + inline size_t operator()(const char* str) const { + size_t result = 0; + for (; *str != '\0'; str++) { + result = 5 * result + *str; + } + return result; + } +}; + +template , + typename EqualKey = std::equal_to > +class hash_map : public HASH_NAMESPACE::HASH_MAP_CLASS< + Key, Data, HashFcn, EqualKey> { + public: + hash_map(int = 0) {} +}; + +template , + typename EqualKey = std::equal_to > +class hash_set : public HASH_NAMESPACE::HASH_SET_CLASS< + Key, HashFcn, EqualKey> { + public: + hash_set(int = 0) {} +}; + +#endif + +template <> +struct hash { + inline size_t operator()(const string& key) const { + return hash()(key.c_str()); + } + + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; + inline size_t operator()(const string& a, const string& b) const { + return a < b; + } +}; + +template +struct hash > { + inline size_t operator()(const pair& key) const { + size_t first_hash = hash()(key.first); + size_t second_hash = hash()(key.second); + + // FIXME(kenton): What is the best way to compute this hash? I have + // no idea! This seems a bit better than an XOR. + return first_hash * ((1 << 16) - 1) + second_hash; + } + + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; + inline size_t operator()(const pair& a, + const pair& b) const { + return a < b; + } +}; + +// Used by GCC/SGI STL only. (Why isn't this provided by the standard +// library? :( ) +struct streq { + inline bool operator()(const char* a, const char* b) const { + return strcmp(a, b) == 0; + } +}; + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_HASH_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/map-util.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/map-util.h new file mode 100644 index 0000000..775848b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/map-util.h @@ -0,0 +1,143 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// from google3/util/gtl/map-util.h +// Author: Anton Carver + +#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ +#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ + +#include + +namespace google { +namespace protobuf { + +// Perform a lookup in a map or hash_map. +// If the key is present in the map then the value associated with that +// key is returned, otherwise the value passed as a default is returned. +template +const typename Collection::value_type::second_type& +FindWithDefault(const Collection& collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& value) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return value; + } + return it->second; +} + +// Perform a lookup in a map or hash_map. +// If the key is present a const pointer to the associated value is returned, +// otherwise a NULL pointer is returned. +template +const typename Collection::value_type::second_type* +FindOrNull(const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return 0; + } + return &it->second; +} + +// Perform a lookup in a map or hash_map, assuming that the key exists. +// Crash if it does not. +// +// This is intended as a replacement for operator[] as an rvalue (for reading) +// when the key is guaranteed to exist. +// +// operator[] is discouraged for several reasons: +// * It has a side-effect of inserting missing keys +// * It is not thread-safe (even when it is not inserting, it can still +// choose to resize the underlying storage) +// * It invalidates iterators (when it chooses to resize) +// * It default constructs a value object even if it doesn't need to +// +// This version assumes the key is printable, and includes it in the fatal log +// message. +template +const typename Collection::value_type::second_type& +FindOrDie(const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + GOOGLE_CHECK(it != collection.end()) << "Map key not found: " << key; + return it->second; +} + +// Perform a lookup in a map or hash_map whose values are pointers. +// If the key is present a const pointer to the associated value is returned, +// otherwise a NULL pointer is returned. +// This function does not distinguish between a missing key and a key mapped +// to a NULL value. +template +const typename Collection::value_type::second_type +FindPtrOrNull(const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return 0; + } + return it->second; +} + +// Change the value associated with a particular key in a map or hash_map. +// If the key is not present in the map the key and value are inserted, +// otherwise the value is updated to be a copy of the value provided. +// True indicates that an insert took place, false indicates an update. +template +bool InsertOrUpdate(Collection * const collection, + const Key& key, const Value& value) { + pair ret = + collection->insert(typename Collection::value_type(key, value)); + if (!ret.second) { + // update + ret.first->second = value; + return false; + } + return true; +} + +// Insert a new key and value into a map or hash_map. +// If the key is not present in the map the key and value are +// inserted, otherwise nothing happens. True indicates that an insert +// took place, false indicates the key was already present. +template +bool InsertIfNotPresent(Collection * const collection, + const Key& key, const Value& value) { + pair ret = + collection->insert(typename Collection::value_type(key, value)); + return ret.second; +} + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once.cc new file mode 100644 index 0000000..1e24b85 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once.cc @@ -0,0 +1,99 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// emulates google3/base/once.h +// +// This header is intended to be included only by internal .cc files and +// generated .pb.cc files. Users should not use this directly. + +#include + +#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include + +namespace google { +namespace protobuf { + +namespace { + +void SchedYield() { +#ifdef _WIN32 + Sleep(0); +#else // POSIX + sched_yield(); +#endif +} + +} // namespace + +void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure) { + internal::AtomicWord state = internal::Acquire_Load(once); + // Fast path. The provided closure was already executed. + if (state == ONCE_STATE_DONE) { + return; + } + // The closure execution did not complete yet. The once object can be in one + // of the two following states: + // - UNINITIALIZED: We are the first thread calling this function. + // - EXECUTING_CLOSURE: Another thread is already executing the closure. + // + // First, try to change the state from UNINITIALIZED to EXECUTING_CLOSURE + // atomically. + state = internal::Acquire_CompareAndSwap( + once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_CLOSURE); + if (state == ONCE_STATE_UNINITIALIZED) { + // We are the first thread to call this function, so we have to call the + // closure. + closure->Run(); + internal::Release_Store(once, ONCE_STATE_DONE); + } else { + // Another thread has already started executing the closure. We need to + // wait until it completes the initialization. + while (state == ONCE_STATE_EXECUTING_CLOSURE) { + // Note that futex() could be used here on Linux as an improvement. + SchedYield(); + state = internal::Acquire_Load(once); + } + } +} + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once.h new file mode 100644 index 0000000..7fbc117 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once.h @@ -0,0 +1,148 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// emulates google3/base/once.h +// +// This header is intended to be included only by internal .cc files and +// generated .pb.cc files. Users should not use this directly. +// +// This is basically a portable version of pthread_once(). +// +// This header declares: +// * A type called ProtobufOnceType. +// * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type +// ProtobufOnceType. This is the only legal way to declare such a variable. +// The macro may only be used at the global scope (you cannot create local or +// class member variables of this type). +// * A function GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()). +// This function, when invoked multiple times given the same ProtobufOnceType +// object, will invoke init_func on the first call only, and will make sure +// none of the calls return before that first call to init_func has finished. +// * The user can provide a parameter which GoogleOnceInit() forwards to the +// user-provided function when it is called. Usage example: +// int a = 10; +// GoogleOnceInit(&my_once, &MyFunctionExpectingIntArgument, &a); +// * This implementation guarantees that ProtobufOnceType is a POD (i.e. no +// static initializer generated). +// +// This implements a way to perform lazy initialization. It's more efficient +// than using mutexes as no lock is needed if initialization has already +// happened. +// +// Example usage: +// void Init(); +// GOOGLE_PROTOBUF_DECLARE_ONCE(once_init); +// +// // Calls Init() exactly once. +// void InitOnce() { +// GoogleOnceInit(&once_init, &Init); +// } +// +// Note that if GoogleOnceInit() is called before main() has begun, it must +// only be called by the thread that will eventually call main() -- that is, +// the thread that performs dynamic initialization. In general this is a safe +// assumption since people don't usually construct threads before main() starts, +// but it is technically not guaranteed. Unfortunately, Win32 provides no way +// whatsoever to statically-initialize its synchronization primitives, so our +// only choice is to assume that dynamic initialization is single-threaded. + +#ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__ +#define GOOGLE_PROTOBUF_STUBS_ONCE_H__ + +#include +#include + +namespace google { +namespace protobuf { + +#ifdef GOOGLE_PROTOBUF_NO_THREAD_SAFETY + +typedef bool ProtobufOnceType; + +#define GOOGLE_PROTOBUF_ONCE_INIT false + +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { + if (!*once) { + *once = true; + init_func(); + } +} + +template +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg), + Arg arg) { + if (!*once) { + *once = true; + init_func(arg); + } +} + +#else + +enum { + ONCE_STATE_UNINITIALIZED = 0, + ONCE_STATE_EXECUTING_CLOSURE = 1, + ONCE_STATE_DONE = 2 +}; + +typedef internal::AtomicWord ProtobufOnceType; + +#define GOOGLE_PROTOBUF_ONCE_INIT ::google::protobuf::ONCE_STATE_UNINITIALIZED + +LIBPROTOBUF_EXPORT +void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure); + +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { + if (internal::Acquire_Load(once) != ONCE_STATE_DONE) { + internal::FunctionClosure0 func(init_func, false); + GoogleOnceInitImpl(once, &func); + } +} + +template +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg*), + Arg* arg) { + if (internal::Acquire_Load(once) != ONCE_STATE_DONE) { + internal::FunctionClosure1 func(init_func, false, arg); + GoogleOnceInitImpl(once, &func); + } +} + +#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY + +#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ + ::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_ONCE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once_unittest.cc new file mode 100644 index 0000000..b8f86a0 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/once_unittest.cc @@ -0,0 +1,253 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#ifdef _WIN32 +#include +#else +#include +#include +#endif + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace { + +class OnceInitTest : public testing::Test { + protected: + void SetUp() { + state_ = INIT_NOT_STARTED; + current_test_ = this; + } + + // Since ProtobufOnceType is only allowed to be allocated in static storage, + // each test must use a different pair of ProtobufOnceType objects which it + // must declare itself. + void SetOnces(ProtobufOnceType* once, ProtobufOnceType* recursive_once) { + once_ = once; + recursive_once_ = recursive_once; + } + + void InitOnce() { + GoogleOnceInit(once_, &InitStatic); + } + void InitRecursiveOnce() { + GoogleOnceInit(recursive_once_, &InitRecursiveStatic); + } + + void BlockInit() { init_blocker_.Lock(); } + void UnblockInit() { init_blocker_.Unlock(); } + + class TestThread { + public: + TestThread(Closure* callback) + : done_(false), joined_(false), callback_(callback) { +#ifdef _WIN32 + thread_ = CreateThread(NULL, 0, &Start, this, 0, NULL); +#else + pthread_create(&thread_, NULL, &Start, this); +#endif + } + ~TestThread() { + if (!joined_) Join(); + } + + bool IsDone() { + MutexLock lock(&done_mutex_); + return done_; + } + void Join() { + joined_ = true; +#ifdef _WIN32 + WaitForSingleObject(thread_, INFINITE); + CloseHandle(thread_); +#else + pthread_join(thread_, NULL); +#endif + } + + private: +#ifdef _WIN32 + HANDLE thread_; +#else + pthread_t thread_; +#endif + + Mutex done_mutex_; + bool done_; + bool joined_; + Closure* callback_; + +#ifdef _WIN32 + static DWORD WINAPI Start(LPVOID arg) { +#else + static void* Start(void* arg) { +#endif + reinterpret_cast(arg)->Run(); + return 0; + } + + void Run() { + callback_->Run(); + MutexLock lock(&done_mutex_); + done_ = true; + } + }; + + TestThread* RunInitOnceInNewThread() { + return new TestThread(NewCallback(this, &OnceInitTest::InitOnce)); + } + TestThread* RunInitRecursiveOnceInNewThread() { + return new TestThread(NewCallback(this, &OnceInitTest::InitRecursiveOnce)); + } + + enum State { + INIT_NOT_STARTED, + INIT_STARTED, + INIT_DONE + }; + State CurrentState() { + MutexLock lock(&mutex_); + return state_; + } + + void WaitABit() { +#ifdef _WIN32 + Sleep(1000); +#else + sleep(1); +#endif + } + + private: + Mutex mutex_; + Mutex init_blocker_; + State state_; + ProtobufOnceType* once_; + ProtobufOnceType* recursive_once_; + + void Init() { + MutexLock lock(&mutex_); + EXPECT_EQ(INIT_NOT_STARTED, state_); + state_ = INIT_STARTED; + mutex_.Unlock(); + init_blocker_.Lock(); + init_blocker_.Unlock(); + mutex_.Lock(); + state_ = INIT_DONE; + } + + static OnceInitTest* current_test_; + static void InitStatic() { current_test_->Init(); } + static void InitRecursiveStatic() { current_test_->InitOnce(); } +}; + +OnceInitTest* OnceInitTest::current_test_ = NULL; + +GOOGLE_PROTOBUF_DECLARE_ONCE(simple_once); + +TEST_F(OnceInitTest, Simple) { + SetOnces(&simple_once, NULL); + + EXPECT_EQ(INIT_NOT_STARTED, CurrentState()); + InitOnce(); + EXPECT_EQ(INIT_DONE, CurrentState()); + + // Calling again has no effect. + InitOnce(); + EXPECT_EQ(INIT_DONE, CurrentState()); +} + +GOOGLE_PROTOBUF_DECLARE_ONCE(recursive_once1); +GOOGLE_PROTOBUF_DECLARE_ONCE(recursive_once2); + +TEST_F(OnceInitTest, Recursive) { + SetOnces(&recursive_once1, &recursive_once2); + + EXPECT_EQ(INIT_NOT_STARTED, CurrentState()); + InitRecursiveOnce(); + EXPECT_EQ(INIT_DONE, CurrentState()); +} + +GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_once); + +TEST_F(OnceInitTest, MultipleThreads) { + SetOnces(&multiple_threads_once, NULL); + + scoped_ptr threads[4]; + EXPECT_EQ(INIT_NOT_STARTED, CurrentState()); + for (int i = 0; i < 4; i++) { + threads[i].reset(RunInitOnceInNewThread()); + } + for (int i = 0; i < 4; i++) { + threads[i]->Join(); + } + EXPECT_EQ(INIT_DONE, CurrentState()); +} + +GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_blocked_once1); +GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_blocked_once2); + +TEST_F(OnceInitTest, MultipleThreadsBlocked) { + SetOnces(&multiple_threads_blocked_once1, &multiple_threads_blocked_once2); + + scoped_ptr threads[8]; + EXPECT_EQ(INIT_NOT_STARTED, CurrentState()); + + BlockInit(); + for (int i = 0; i < 4; i++) { + threads[i].reset(RunInitOnceInNewThread()); + } + for (int i = 4; i < 8; i++) { + threads[i].reset(RunInitRecursiveOnceInNewThread()); + } + + WaitABit(); + + // We should now have one thread blocked inside Init(), four blocked waiting + // for Init() to complete, and three blocked waiting for InitRecursive() to + // complete. + EXPECT_EQ(INIT_STARTED, CurrentState()); + UnblockInit(); + + for (int i = 0; i < 8; i++) { + threads[i]->Join(); + } + EXPECT_EQ(INIT_DONE, CurrentState()); +} + +} // anonymous namespace +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/platform_macros.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/platform_macros.h new file mode 100644 index 0000000..b1df60e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/platform_macros.h @@ -0,0 +1,70 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ +#define GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ + +#include + +// Processor architecture detection. For more info on what's defined, see: +// http://msdn.microsoft.com/en-us/library/b0084kay.aspx +// http://www.agner.org/optimize/calling_conventions.pdf +// or with gcc, run: "echo | gcc -E -dM -" +#if defined(_M_X64) || defined(__x86_64__) +#define GOOGLE_PROTOBUF_ARCH_X64 1 +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#elif defined(_M_IX86) || defined(__i386__) +#define GOOGLE_PROTOBUF_ARCH_IA32 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(__QNX__) +#define GOOGLE_PROTOBUF_ARCH_ARM_QNX 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(__ARMEL__) +#define GOOGLE_PROTOBUF_ARCH_ARM 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(__MIPSEL__) +#define GOOGLE_PROTOBUF_ARCH_MIPS 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(__pnacl__) +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(__ppc__) +#define GOOGLE_PROTOBUF_ARCH_PPC 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#else +#error Host architecture was not detected as supported by protobuf +#endif + +#if defined(__APPLE__) +#define GOOGLE_PROTOBUF_OS_APPLE +#elif defined(__native_client__) +#define GOOGLE_PROTOBUF_OS_NACL +#endif + +#endif // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stl_util.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stl_util.h new file mode 100644 index 0000000..9021dad --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stl_util.h @@ -0,0 +1,121 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// from google3/util/gtl/stl_util.h + +#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__ +#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__ + +#include + +namespace google { +namespace protobuf { + +// STLDeleteContainerPointers() +// For a range within a container of pointers, calls delete +// (non-array version) on these pointers. +// NOTE: for these three functions, we could just implement a DeleteObject +// functor and then call for_each() on the range and functor, but this +// requires us to pull in all of algorithm.h, which seems expensive. +// For hash_[multi]set, it is important that this deletes behind the iterator +// because the hash_set may call the hash function on the iterator when it is +// advanced, which could result in the hash function trying to deference a +// stale pointer. +template +void STLDeleteContainerPointers(ForwardIterator begin, + ForwardIterator end) { + while (begin != end) { + ForwardIterator temp = begin; + ++begin; + delete *temp; + } +} + +// Inside Google, this function implements a horrible, disgusting hack in which +// we reach into the string's private implementation and resize it without +// initializing the new bytes. In some cases doing this can significantly +// improve performance. However, since it's totally non-portable it has no +// place in open source code. Feel free to fill this function in with your +// own disgusting hack if you want the perf boost. +inline void STLStringResizeUninitialized(string* s, size_t new_size) { + s->resize(new_size); +} + +// Return a mutable char* pointing to a string's internal buffer, +// which may not be null-terminated. Writing through this pointer will +// modify the string. +// +// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the +// next call to a string method that invalidates iterators. +// +// As of 2006-04, there is no standard-blessed way of getting a +// mutable reference to a string's internal buffer. However, issue 530 +// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530) +// proposes this as the method. According to Matt Austern, this should +// already work on all current implementations. +inline char* string_as_array(string* str) { + // DO NOT USE const_cast(str->data())! See the unittest for why. + return str->empty() ? NULL : &*str->begin(); +} + +// STLDeleteElements() deletes all the elements in an STL container and clears +// the container. This function is suitable for use with a vector, set, +// hash_set, or any other STL container which defines sensible begin(), end(), +// and clear() methods. +// +// If container is NULL, this function is a no-op. +// +// As an alternative to calling STLDeleteElements() directly, consider +// ElementDeleter (defined below), which ensures that your container's elements +// are deleted when the ElementDeleter goes out of scope. +template +void STLDeleteElements(T *container) { + if (!container) return; + STLDeleteContainerPointers(container->begin(), container->end()); + container->clear(); +} + +// Given an STL container consisting of (key, value) pairs, STLDeleteValues +// deletes all the "value" components and clears the container. Does nothing +// in the case it's given a NULL pointer. + +template +void STLDeleteValues(T *v) { + if (!v) return; + for (typename T::iterator i = v->begin(); i != v->end(); ++i) { + delete i->second; + } + v->clear(); +} + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf.cc new file mode 100644 index 0000000..4a5b858 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf.cc @@ -0,0 +1,175 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// from google3/base/stringprintf.cc + +#include + +#include +#include // For va_list and related operations +#include // MSVC requires this for _vsnprintf +#include +#include +#include + +namespace google { +namespace protobuf { + +#ifdef _MSC_VER +enum { IS_COMPILER_MSVC = 1 }; +#ifndef va_copy +// Define va_copy for MSVC. This is a hack, assuming va_list is simply a +// pointer into the stack and is safe to copy. +#define va_copy(dest, src) ((dest) = (src)) +#endif +#else +enum { IS_COMPILER_MSVC = 0 }; +#endif + +void StringAppendV(string* dst, const char* format, va_list ap) { + // First try with a small fixed size buffer + static const int kSpaceLength = 1024; + char space[kSpaceLength]; + + // It's possible for methods that use a va_list to invalidate + // the data in it upon use. The fix is to make a copy + // of the structure before using it and use that copy instead. + va_list backup_ap; + va_copy(backup_ap, ap); + int result = vsnprintf(space, kSpaceLength, format, backup_ap); + va_end(backup_ap); + + if (result < kSpaceLength) { + if (result >= 0) { + // Normal case -- everything fit. + dst->append(space, result); + return; + } + + if (IS_COMPILER_MSVC) { + // Error or MSVC running out of space. MSVC 8.0 and higher + // can be asked about space needed with the special idiom below: + va_copy(backup_ap, ap); + result = vsnprintf(NULL, 0, format, backup_ap); + va_end(backup_ap); + } + + if (result < 0) { + // Just an error. + return; + } + } + + // Increase the buffer size to the size requested by vsnprintf, + // plus one for the closing \0. + int length = result+1; + char* buf = new char[length]; + + // Restore the va_list before we use it again + va_copy(backup_ap, ap); + result = vsnprintf(buf, length, format, backup_ap); + va_end(backup_ap); + + if (result >= 0 && result < length) { + // It fit + dst->append(buf, result); + } + delete[] buf; +} + + +string StringPrintf(const char* format, ...) { + va_list ap; + va_start(ap, format); + string result; + StringAppendV(&result, format, ap); + va_end(ap); + return result; +} + +const string& SStringPrintf(string* dst, const char* format, ...) { + va_list ap; + va_start(ap, format); + dst->clear(); + StringAppendV(dst, format, ap); + va_end(ap); + return *dst; +} + +void StringAppendF(string* dst, const char* format, ...) { + va_list ap; + va_start(ap, format); + StringAppendV(dst, format, ap); + va_end(ap); +} + +// Max arguments supported by StringPrintVector +const int kStringPrintfVectorMaxArgs = 32; + +// An empty block of zero for filler arguments. This is const so that if +// printf tries to write to it (via %n) then the program gets a SIGSEGV +// and we can fix the problem or protect against an attack. +static const char string_printf_empty_block[256] = { '\0' }; + +string StringPrintfVector(const char* format, const vector& v) { + GOOGLE_CHECK_LE(v.size(), kStringPrintfVectorMaxArgs) + << "StringPrintfVector currently only supports up to " + << kStringPrintfVectorMaxArgs << " arguments. " + << "Feel free to add support for more if you need it."; + + // Add filler arguments so that bogus format+args have a harder time + // crashing the program, corrupting the program (%n), + // or displaying random chunks of memory to users. + + const char* cstr[kStringPrintfVectorMaxArgs]; + for (int i = 0; i < v.size(); ++i) { + cstr[i] = v[i].c_str(); + } + for (int i = v.size(); i < GOOGLE_ARRAYSIZE(cstr); ++i) { + cstr[i] = &string_printf_empty_block[0]; + } + + // I do not know any way to pass kStringPrintfVectorMaxArgs arguments, + // or any way to build a va_list by hand, or any API for printf + // that accepts an array of arguments. The best I can do is stick + // this COMPILE_ASSERT right next to the actual statement. + + GOOGLE_COMPILE_ASSERT(kStringPrintfVectorMaxArgs == 32, arg_count_mismatch); + return StringPrintf(format, + cstr[0], cstr[1], cstr[2], cstr[3], cstr[4], + cstr[5], cstr[6], cstr[7], cstr[8], cstr[9], + cstr[10], cstr[11], cstr[12], cstr[13], cstr[14], + cstr[15], cstr[16], cstr[17], cstr[18], cstr[19], + cstr[20], cstr[21], cstr[22], cstr[23], cstr[24], + cstr[25], cstr[26], cstr[27], cstr[28], cstr[29], + cstr[30], cstr[31]); +} +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf.h new file mode 100644 index 0000000..4a03e5f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf.h @@ -0,0 +1,76 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// from google3/base/stringprintf.h +// +// Printf variants that place their output in a C++ string. +// +// Usage: +// string result = StringPrintf("%d %s\n", 10, "hello"); +// SStringPrintf(&result, "%d %s\n", 10, "hello"); +// StringAppendF(&result, "%d %s\n", 20, "there"); + +#ifndef GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H +#define GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H + +#include +#include +#include + +#include + +namespace google { +namespace protobuf { + +// Return a C++ string +LIBPROTOBUF_EXPORT extern string StringPrintf(const char* format, ...); + +// Store result into a supplied string and return it +LIBPROTOBUF_EXPORT extern const string& SStringPrintf(string* dst, const char* format, ...); + +// Append result to a supplied string +LIBPROTOBUF_EXPORT extern void StringAppendF(string* dst, const char* format, ...); + +// Lower-level routine that takes a va_list and appends to a specified +// string. All other routines are just convenience wrappers around it. +LIBPROTOBUF_EXPORT extern void StringAppendV(string* dst, const char* format, va_list ap); + +// The max arguments supported by StringPrintfVector +LIBPROTOBUF_EXPORT extern const int kStringPrintfVectorMaxArgs; + +// You can use this version when all your arguments are strings, but +// you don't know how many arguments you'll have at compile time. +// StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs +LIBPROTOBUF_EXPORT extern string StringPrintfVector(const char* format, const vector& v); + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf_unittest.cc new file mode 100644 index 0000000..de5ce59 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/stringprintf_unittest.cc @@ -0,0 +1,152 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// from google3/base/stringprintf_unittest.cc + +#include + +#include +#include + +#include +#include + +namespace google { +namespace protobuf { +namespace { + +TEST(StringPrintfTest, Empty) { +#if 0 + // gcc 2.95.3, gcc 4.1.0, and gcc 4.2.2 all warn about this: + // warning: zero-length printf format string. + // so we do not allow them in google3. + EXPECT_EQ("", StringPrintf("")); +#endif + EXPECT_EQ("", StringPrintf("%s", string().c_str())); + EXPECT_EQ("", StringPrintf("%s", "")); +} + +TEST(StringPrintfTest, Misc) { +// MSVC and mingw does not support $ format specifier. +#if !defined(_MSC_VER) && !defined(__MINGW32__) + EXPECT_EQ("123hello w", StringPrintf("%3$d%2$s %1$c", 'w', "hello", 123)); +#endif // !_MSC_VER +} + +TEST(StringAppendFTest, Empty) { + string value("Hello"); + const char* empty = ""; + StringAppendF(&value, "%s", empty); + EXPECT_EQ("Hello", value); +} + +TEST(StringAppendFTest, EmptyString) { + string value("Hello"); + StringAppendF(&value, "%s", ""); + EXPECT_EQ("Hello", value); +} + +TEST(StringAppendFTest, String) { + string value("Hello"); + StringAppendF(&value, " %s", "World"); + EXPECT_EQ("Hello World", value); +} + +TEST(StringAppendFTest, Int) { + string value("Hello"); + StringAppendF(&value, " %d", 123); + EXPECT_EQ("Hello 123", value); +} + +TEST(StringPrintfTest, Multibyte) { + // If we are in multibyte mode and feed invalid multibyte sequence, + // StringPrintf should return an empty string instead of running + // out of memory while trying to determine destination buffer size. + // see b/4194543. + + char* old_locale = setlocale(LC_CTYPE, NULL); + // Push locale with multibyte mode + setlocale(LC_CTYPE, "en_US.utf8"); + + const char kInvalidCodePoint[] = "\375\067s"; + string value = StringPrintf("%.*s", 3, kInvalidCodePoint); + + // In some versions of glibc (e.g. eglibc-2.11.1, aka GRTEv2), snprintf + // returns error given an invalid codepoint. Other versions + // (e.g. eglibc-2.15, aka pre-GRTEv3) emit the codepoint verbatim. + // We test that the output is one of the above. + EXPECT_TRUE(value.empty() || value == kInvalidCodePoint); + + // Repeat with longer string, to make sure that the dynamically + // allocated path in StringAppendV is handled correctly. + int n = 2048; + char* buf = new char[n+1]; + memset(buf, ' ', n-3); + memcpy(buf + n - 3, kInvalidCodePoint, 4); + value = StringPrintf("%.*s", n, buf); + // See GRTEv2 vs. GRTEv3 comment above. + EXPECT_TRUE(value.empty() || value == buf); + delete[] buf; + + setlocale(LC_CTYPE, old_locale); +} + +TEST(StringPrintfTest, NoMultibyte) { + // No multibyte handling, but the string contains funny chars. + char* old_locale = setlocale(LC_CTYPE, NULL); + setlocale(LC_CTYPE, "POSIX"); + string value = StringPrintf("%.*s", 3, "\375\067s"); + setlocale(LC_CTYPE, old_locale); + EXPECT_EQ("\375\067s", value); +} + +TEST(StringPrintfTest, DontOverwriteErrno) { + // Check that errno isn't overwritten unless we're printing + // something significantly larger than what people are normally + // printing in their badly written PLOG() statements. + errno = ECHILD; + string value = StringPrintf("Hello, %s!", "World"); + EXPECT_EQ(ECHILD, errno); +} + +TEST(StringPrintfTest, LargeBuf) { + // Check that the large buffer is handled correctly. + int n = 2048; + char* buf = new char[n+1]; + memset(buf, ' ', n); + buf[n] = 0; + string value = StringPrintf("%s", buf); + EXPECT_EQ(buf, value); + delete[] buf; +} + +} // anonymous namespace +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/structurally_valid.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/structurally_valid.cc new file mode 100644 index 0000000..0f6afe6 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/structurally_valid.cc @@ -0,0 +1,536 @@ +// Copyright 2005-2008 Google Inc. All Rights Reserved. +// Author: jrm@google.com (Jim Meehan) + +#include + +namespace google { +namespace protobuf { +namespace internal { + +// These four-byte entries compactly encode how many bytes 0..255 to delete +// in making a string replacement, how many bytes to add 0..255, and the offset +// 0..64k-1 of the replacement string in remap_string. +struct RemapEntry { + uint8 delete_bytes; + uint8 add_bytes; + uint16 bytes_offset; +}; + +// Exit type codes for state tables. All but the first get stuffed into +// signed one-byte entries. The first is only generated by executable code. +// To distinguish from next-state entries, these must be contiguous and +// all <= kExitNone +typedef enum { + kExitDstSpaceFull = 239, + kExitIllegalStructure, // 240 + kExitOK, // 241 + kExitReject, // ... + kExitReplace1, + kExitReplace2, + kExitReplace3, + kExitReplace21, + kExitReplace31, + kExitReplace32, + kExitReplaceOffset1, + kExitReplaceOffset2, + kExitReplace1S0, + kExitSpecial, + kExitDoAgain, + kExitRejectAlt, + kExitNone // 255 +} ExitReason; + + +// This struct represents one entire state table. The three initialized byte +// areas are state_table, remap_base, and remap_string. state0 and state0_size +// give the byte offset and length within state_table of the initial state -- +// table lookups are expected to start and end in this state, but for +// truncated UTF-8 strings, may end in a different state. These allow a quick +// test for that condition. entry_shift is 8 for tables subscripted by a full +// byte value and 6 for space-optimized tables subscripted by only six +// significant bits in UTF-8 continuation bytes. +typedef struct { + const uint32 state0; + const uint32 state0_size; + const uint32 total_size; + const int max_expand; + const int entry_shift; + const int bytes_per_entry; + const uint32 losub; + const uint32 hiadd; + const uint8* state_table; + const RemapEntry* remap_base; + const uint8* remap_string; + const uint8* fast_state; +} UTF8StateMachineObj; + +typedef UTF8StateMachineObj UTF8ScanObj; + +#define X__ (kExitIllegalStructure) +#define RJ_ (kExitReject) +#define S1_ (kExitReplace1) +#define S2_ (kExitReplace2) +#define S3_ (kExitReplace3) +#define S21 (kExitReplace21) +#define S31 (kExitReplace31) +#define S32 (kExitReplace32) +#define T1_ (kExitReplaceOffset1) +#define T2_ (kExitReplaceOffset2) +#define S11 (kExitReplace1S0) +#define SP_ (kExitSpecial) +#define D__ (kExitDoAgain) +#define RJA (kExitRejectAlt) + +// Entire table has 9 state blocks of 256 entries each +static const unsigned int utf8acceptnonsurrogates_STATE0 = 0; // state[0] +static const unsigned int utf8acceptnonsurrogates_STATE0_SIZE = 256; // =[1] +static const unsigned int utf8acceptnonsurrogates_TOTAL_SIZE = 2304; +static const unsigned int utf8acceptnonsurrogates_MAX_EXPAND_X4 = 0; +static const unsigned int utf8acceptnonsurrogates_SHIFT = 8; +static const unsigned int utf8acceptnonsurrogates_BYTES = 1; +static const unsigned int utf8acceptnonsurrogates_LOSUB = 0x20202020; +static const unsigned int utf8acceptnonsurrogates_HIADD = 0x00000000; + +static const uint8 utf8acceptnonsurrogates[] = { +// state[0] 0x000000 Byte 1 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 3, + 4, 5, 5, 5, 6, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[1] 0x000080 Byte 2 of 2 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[2] 0x000000 Byte 2 of 3 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[3] 0x001000 Byte 2 of 3 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[4] 0x000000 Byte 2 of 4 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[5] 0x040000 Byte 2 of 4 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[6] 0x100000 Byte 2 of 4 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[7] 0x00d000 Byte 2 of 3 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[8] 0x00d800 Byte 3 of 3 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +}; + +// Remap base[0] = (del, add, string_offset) +static const RemapEntry utf8acceptnonsurrogates_remap_base[] = { +{0, 0, 0} }; + +// Remap string[0] +static const unsigned char utf8acceptnonsurrogates_remap_string[] = { +0 }; + +static const unsigned char utf8acceptnonsurrogates_fast[256] = { +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const UTF8ScanObj utf8acceptnonsurrogates_obj = { + utf8acceptnonsurrogates_STATE0, + utf8acceptnonsurrogates_STATE0_SIZE, + utf8acceptnonsurrogates_TOTAL_SIZE, + utf8acceptnonsurrogates_MAX_EXPAND_X4, + utf8acceptnonsurrogates_SHIFT, + utf8acceptnonsurrogates_BYTES, + utf8acceptnonsurrogates_LOSUB, + utf8acceptnonsurrogates_HIADD, + utf8acceptnonsurrogates, + utf8acceptnonsurrogates_remap_base, + utf8acceptnonsurrogates_remap_string, + utf8acceptnonsurrogates_fast +}; + + +#undef X__ +#undef RJ_ +#undef S1_ +#undef S2_ +#undef S3_ +#undef S21 +#undef S31 +#undef S32 +#undef T1_ +#undef T2_ +#undef S11 +#undef SP_ +#undef D__ +#undef RJA + +// Return true if current Tbl pointer is within state0 range +// Note that unsigned compare checks both ends of range simultaneously +static inline bool InStateZero(const UTF8ScanObj* st, const uint8* Tbl) { + const uint8* Tbl0 = &st->state_table[st->state0]; + return (static_cast(Tbl - Tbl0) < st->state0_size); +} + +// Scan a UTF-8 string based on state table. +// Always scan complete UTF-8 characters +// Set number of bytes scanned. Return reason for exiting +int UTF8GenericScan(const UTF8ScanObj* st, + const char * str, + int str_length, + int* bytes_consumed) { + *bytes_consumed = 0; + if (str_length == 0) return kExitOK; + + int eshift = st->entry_shift; + const uint8* isrc = reinterpret_cast(str); + const uint8* src = isrc; + const uint8* srclimit = isrc + str_length; + const uint8* srclimit8 = srclimit - 7; + const uint8* Tbl_0 = &st->state_table[st->state0]; + + DoAgain: + // Do state-table scan + int e = 0; + uint8 c; + const uint8* Tbl2 = &st->fast_state[0]; + const uint32 losub = st->losub; + const uint32 hiadd = st->hiadd; + // Check initial few bytes one at a time until 8-byte aligned + //---------------------------- + while ((((uintptr_t)src & 0x07) != 0) && + (src < srclimit) && + Tbl2[src[0]] == 0) { + src++; + } + if (((uintptr_t)src & 0x07) == 0) { + // Do fast for groups of 8 identity bytes. + // This covers a lot of 7-bit ASCII ~8x faster then the 1-byte loop, + // including slowing slightly on cr/lf/ht + //---------------------------- + while (src < srclimit8) { + uint32 s0123 = (reinterpret_cast(src))[0]; + uint32 s4567 = (reinterpret_cast(src))[1]; + src += 8; + // This is a fast range check for all bytes in [lowsub..0x80-hiadd) + uint32 temp = (s0123 - losub) | (s0123 + hiadd) | + (s4567 - losub) | (s4567 + hiadd); + if ((temp & 0x80808080) != 0) { + // We typically end up here on cr/lf/ht; src was incremented + int e0123 = (Tbl2[src[-8]] | Tbl2[src[-7]]) | + (Tbl2[src[-6]] | Tbl2[src[-5]]); + if (e0123 != 0) { + src -= 8; + break; + } // Exit on Non-interchange + e0123 = (Tbl2[src[-4]] | Tbl2[src[-3]]) | + (Tbl2[src[-2]] | Tbl2[src[-1]]); + if (e0123 != 0) { + src -= 4; + break; + } // Exit on Non-interchange + // Else OK, go around again + } + } + } + //---------------------------- + + // Byte-at-a-time scan + //---------------------------- + const uint8* Tbl = Tbl_0; + while (src < srclimit) { + c = *src; + e = Tbl[c]; + src++; + if (e >= kExitIllegalStructure) {break;} + Tbl = &Tbl_0[e << eshift]; + } + //---------------------------- + + + // Exit posibilities: + // Some exit code, !state0, back up over last char + // Some exit code, state0, back up one byte exactly + // source consumed, !state0, back up over partial char + // source consumed, state0, exit OK + // For illegal byte in state0, avoid backup up over PREVIOUS char + // For truncated last char, back up to beginning of it + + if (e >= kExitIllegalStructure) { + // Back up over exactly one byte of rejected/illegal UTF-8 character + src--; + // Back up more if needed + if (!InStateZero(st, Tbl)) { + do { + src--; + } while ((src > isrc) && ((src[0] & 0xc0) == 0x80)); + } + } else if (!InStateZero(st, Tbl)) { + // Back up over truncated UTF-8 character + e = kExitIllegalStructure; + do { + src--; + } while ((src > isrc) && ((src[0] & 0xc0) == 0x80)); + } else { + // Normal termination, source fully consumed + e = kExitOK; + } + + if (e == kExitDoAgain) { + // Loop back up to the fast scan + goto DoAgain; + } + + *bytes_consumed = src - isrc; + return e; +} + +int UTF8GenericScanFastAscii(const UTF8ScanObj* st, + const char * str, + int str_length, + int* bytes_consumed) { + *bytes_consumed = 0; + if (str_length == 0) return kExitOK; + + const uint8* isrc = reinterpret_cast(str); + const uint8* src = isrc; + const uint8* srclimit = isrc + str_length; + const uint8* srclimit8 = srclimit - 7; + int n; + int rest_consumed; + int exit_reason; + do { + // Check initial few bytes one at a time until 8-byte aligned + while ((((uintptr_t)src & 0x07) != 0) && + (src < srclimit) && (src[0] < 0x80)) { + src++; + } + if (((uintptr_t)src & 0x07) == 0) { + while ((src < srclimit8) && + (((reinterpret_cast(src)[0] | + reinterpret_cast(src)[1]) & 0x80808080) == 0)) { + src += 8; + } + } + while ((src < srclimit) && (src[0] < 0x80)) { + src++; + } + // Run state table on the rest + n = src - isrc; + exit_reason = UTF8GenericScan(st, str + n, str_length - n, &rest_consumed); + src += rest_consumed; + } while ( exit_reason == kExitDoAgain ); + + *bytes_consumed = src - isrc; + return exit_reason; +} + +// Hack: On some compilers the static tables are initialized at startup. +// We can't use them until they are initialized. However, some Protocol +// Buffer parsing happens at static init time and may try to validate +// UTF-8 strings. Since UTF-8 validation is only used for debugging +// anyway, we simply always return success if initialization hasn't +// occurred yet. +namespace { + +bool module_initialized_ = false; + +struct InitDetector { + InitDetector() { + module_initialized_ = true; + } +}; +InitDetector init_detector; + +} // namespace + +bool IsStructurallyValidUTF8(const char* buf, int len) { + if (!module_initialized_) return true; + + int bytes_consumed = 0; + UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj, + buf, len, &bytes_consumed); + return (bytes_consumed == len); +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/structurally_valid_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/structurally_valid_unittest.cc new file mode 100644 index 0000000..9088888 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/structurally_valid_unittest.cc @@ -0,0 +1,40 @@ +// Copyright 2008 Google Inc. All Rights Reserved. +// Author: xpeng@google.com (Peter Peng) + +#include +#include + +namespace google { +namespace protobuf { +namespace internal { +namespace { + +TEST(StructurallyValidTest, ValidUTF8String) { + // On GCC, this string can be written as: + // "abcd 1234 - \u2014\u2013\u2212" + // MSVC seems to interpret \u differently. + string valid_str("abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789"); + EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data(), + valid_str.size())); + // Additional check for pointer alignment + for (int i = 1; i < 8; ++i) { + EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data() + i, + valid_str.size() - i)); + } +} + +TEST(StructurallyValidTest, InvalidUTF8String) { + const string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789"); + EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data(), + invalid_str.size())); + // Additional check for pointer alignment + for (int i = 1; i < 8; ++i) { + EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data() + i, + invalid_str.size() - i)); + } +} + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil.cc new file mode 100644 index 0000000..917b3e9 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil.cc @@ -0,0 +1,1211 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// from google3/strings/strutil.cc + +#include +#include +#include // FLT_DIG and DBL_DIG +#include +#include +#include +#include + +#ifdef _WIN32 +// MSVC has only _snprintf, not snprintf. +// +// MinGW has both snprintf and _snprintf, but they appear to be different +// functions. The former is buggy. When invoked like so: +// char buffer[32]; +// snprintf(buffer, 32, "%.*g\n", FLT_DIG, 1.23e10f); +// it prints "1.23000e+10". This is plainly wrong: %g should never print +// trailing zeros after the decimal point. For some reason this bug only +// occurs with some input values, not all. In any case, _snprintf does the +// right thing, so we use it. +#define snprintf _snprintf +#endif + +namespace google { +namespace protobuf { + +inline bool IsNaN(double value) { + // NaN is never equal to anything, even itself. + return value != value; +} + +// These are defined as macros on some platforms. #undef them so that we can +// redefine them. +#undef isxdigit +#undef isprint + +// The definitions of these in ctype.h change based on locale. Since our +// string manipulation is all in relation to the protocol buffer and C++ +// languages, we always want to use the C locale. So, we re-define these +// exactly as we want them. +inline bool isxdigit(char c) { + return ('0' <= c && c <= '9') || + ('a' <= c && c <= 'f') || + ('A' <= c && c <= 'F'); +} + +inline bool isprint(char c) { + return c >= 0x20 && c <= 0x7E; +} + +// ---------------------------------------------------------------------- +// StripString +// Replaces any occurrence of the character 'remove' (or the characters +// in 'remove') with the character 'replacewith'. +// ---------------------------------------------------------------------- +void StripString(string* s, const char* remove, char replacewith) { + const char * str_start = s->c_str(); + const char * str = str_start; + for (str = strpbrk(str, remove); + str != NULL; + str = strpbrk(str + 1, remove)) { + (*s)[str - str_start] = replacewith; + } +} + +// ---------------------------------------------------------------------- +// StringReplace() +// Replace the "old" pattern with the "new" pattern in a string, +// and append the result to "res". If replace_all is false, +// it only replaces the first instance of "old." +// ---------------------------------------------------------------------- + +void StringReplace(const string& s, const string& oldsub, + const string& newsub, bool replace_all, + string* res) { + if (oldsub.empty()) { + res->append(s); // if empty, append the given string. + return; + } + + string::size_type start_pos = 0; + string::size_type pos; + do { + pos = s.find(oldsub, start_pos); + if (pos == string::npos) { + break; + } + res->append(s, start_pos, pos - start_pos); + res->append(newsub); + start_pos = pos + oldsub.size(); // start searching again after the "old" + } while (replace_all); + res->append(s, start_pos, s.length() - start_pos); +} + +// ---------------------------------------------------------------------- +// StringReplace() +// Give me a string and two patterns "old" and "new", and I replace +// the first instance of "old" in the string with "new", if it +// exists. If "global" is true; call this repeatedly until it +// fails. RETURN a new string, regardless of whether the replacement +// happened or not. +// ---------------------------------------------------------------------- + +string StringReplace(const string& s, const string& oldsub, + const string& newsub, bool replace_all) { + string ret; + StringReplace(s, oldsub, newsub, replace_all, &ret); + return ret; +} + +// ---------------------------------------------------------------------- +// SplitStringUsing() +// Split a string using a character delimiter. Append the components +// to 'result'. +// +// Note: For multi-character delimiters, this routine will split on *ANY* of +// the characters in the string, not the entire string as a single delimiter. +// ---------------------------------------------------------------------- +template +static inline +void SplitStringToIteratorUsing(const string& full, + const char* delim, + ITR& result) { + // Optimize the common case where delim is a single character. + if (delim[0] != '\0' && delim[1] == '\0') { + char c = delim[0]; + const char* p = full.data(); + const char* end = p + full.size(); + while (p != end) { + if (*p == c) { + ++p; + } else { + const char* start = p; + while (++p != end && *p != c); + *result++ = string(start, p - start); + } + } + return; + } + + string::size_type begin_index, end_index; + begin_index = full.find_first_not_of(delim); + while (begin_index != string::npos) { + end_index = full.find_first_of(delim, begin_index); + if (end_index == string::npos) { + *result++ = full.substr(begin_index); + return; + } + *result++ = full.substr(begin_index, (end_index - begin_index)); + begin_index = full.find_first_not_of(delim, end_index); + } +} + +void SplitStringUsing(const string& full, + const char* delim, + vector* result) { + back_insert_iterator< vector > it(*result); + SplitStringToIteratorUsing(full, delim, it); +} + +// Split a string using a character delimiter. Append the components +// to 'result'. If there are consecutive delimiters, this function +// will return corresponding empty strings. The string is split into +// at most the specified number of pieces greedily. This means that the +// last piece may possibly be split further. To split into as many pieces +// as possible, specify 0 as the number of pieces. +// +// If "full" is the empty string, yields an empty string as the only value. +// +// If "pieces" is negative for some reason, it returns the whole string +// ---------------------------------------------------------------------- +template +static inline +void SplitStringToIteratorAllowEmpty(const StringType& full, + const char* delim, + int pieces, + ITR& result) { + string::size_type begin_index, end_index; + begin_index = 0; + + for (int i = 0; (i < pieces-1) || (pieces == 0); i++) { + end_index = full.find_first_of(delim, begin_index); + if (end_index == string::npos) { + *result++ = full.substr(begin_index); + return; + } + *result++ = full.substr(begin_index, (end_index - begin_index)); + begin_index = end_index + 1; + } + *result++ = full.substr(begin_index); +} + +void SplitStringAllowEmpty(const string& full, const char* delim, + vector* result) { + back_insert_iterator > it(*result); + SplitStringToIteratorAllowEmpty(full, delim, 0, it); +} + +// ---------------------------------------------------------------------- +// JoinStrings() +// This merges a vector of string components with delim inserted +// as separaters between components. +// +// ---------------------------------------------------------------------- +template +static void JoinStringsIterator(const ITERATOR& start, + const ITERATOR& end, + const char* delim, + string* result) { + GOOGLE_CHECK(result != NULL); + result->clear(); + int delim_length = strlen(delim); + + // Precompute resulting length so we can reserve() memory in one shot. + int length = 0; + for (ITERATOR iter = start; iter != end; ++iter) { + if (iter != start) { + length += delim_length; + } + length += iter->size(); + } + result->reserve(length); + + // Now combine everything. + for (ITERATOR iter = start; iter != end; ++iter) { + if (iter != start) { + result->append(delim, delim_length); + } + result->append(iter->data(), iter->size()); + } +} + +void JoinStrings(const vector& components, + const char* delim, + string * result) { + JoinStringsIterator(components.begin(), components.end(), delim, result); +} + +// ---------------------------------------------------------------------- +// UnescapeCEscapeSequences() +// This does all the unescaping that C does: \ooo, \r, \n, etc +// Returns length of resulting string. +// The implementation of \x parses any positive number of hex digits, +// but it is an error if the value requires more than 8 bits, and the +// result is truncated to 8 bits. +// +// The second call stores its errors in a supplied string vector. +// If the string vector pointer is NULL, it reports the errors with LOG(). +// ---------------------------------------------------------------------- + +#define IS_OCTAL_DIGIT(c) (((c) >= '0') && ((c) <= '7')) + +inline int hex_digit_to_int(char c) { + /* Assume ASCII. */ + assert('0' == 0x30 && 'A' == 0x41 && 'a' == 0x61); + assert(isxdigit(c)); + int x = static_cast(c); + if (x > '9') { + x += 9; + } + return x & 0xf; +} + +// Protocol buffers doesn't ever care about errors, but I don't want to remove +// the code. +#define LOG_STRING(LEVEL, VECTOR) GOOGLE_LOG_IF(LEVEL, false) + +int UnescapeCEscapeSequences(const char* source, char* dest) { + return UnescapeCEscapeSequences(source, dest, NULL); +} + +int UnescapeCEscapeSequences(const char* source, char* dest, + vector *errors) { + GOOGLE_DCHECK(errors == NULL) << "Error reporting not implemented."; + + char* d = dest; + const char* p = source; + + // Small optimization for case where source = dest and there's no escaping + while ( p == d && *p != '\0' && *p != '\\' ) + p++, d++; + + while (*p != '\0') { + if (*p != '\\') { + *d++ = *p++; + } else { + switch ( *++p ) { // skip past the '\\' + case '\0': + LOG_STRING(ERROR, errors) << "String cannot end with \\"; + *d = '\0'; + return d - dest; // we're done with p + case 'a': *d++ = '\a'; break; + case 'b': *d++ = '\b'; break; + case 'f': *d++ = '\f'; break; + case 'n': *d++ = '\n'; break; + case 'r': *d++ = '\r'; break; + case 't': *d++ = '\t'; break; + case 'v': *d++ = '\v'; break; + case '\\': *d++ = '\\'; break; + case '?': *d++ = '\?'; break; // \? Who knew? + case '\'': *d++ = '\''; break; + case '"': *d++ = '\"'; break; + case '0': case '1': case '2': case '3': // octal digit: 1 to 3 digits + case '4': case '5': case '6': case '7': { + char ch = *p - '0'; + if ( IS_OCTAL_DIGIT(p[1]) ) + ch = ch * 8 + *++p - '0'; + if ( IS_OCTAL_DIGIT(p[1]) ) // safe (and easy) to do this twice + ch = ch * 8 + *++p - '0'; // now points at last digit + *d++ = ch; + break; + } + case 'x': case 'X': { + if (!isxdigit(p[1])) { + if (p[1] == '\0') { + LOG_STRING(ERROR, errors) << "String cannot end with \\x"; + } else { + LOG_STRING(ERROR, errors) << + "\\x cannot be followed by non-hex digit: \\" << *p << p[1]; + } + break; + } + unsigned int ch = 0; + const char *hex_start = p; + while (isxdigit(p[1])) // arbitrarily many hex digits + ch = (ch << 4) + hex_digit_to_int(*++p); + if (ch > 0xFF) + LOG_STRING(ERROR, errors) << "Value of " << + "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits"; + *d++ = ch; + break; + } +#if 0 // TODO(kenton): Support \u and \U? Requires runetochar(). + case 'u': { + // \uhhhh => convert 4 hex digits to UTF-8 + char32 rune = 0; + const char *hex_start = p; + for (int i = 0; i < 4; ++i) { + if (isxdigit(p[1])) { // Look one char ahead. + rune = (rune << 4) + hex_digit_to_int(*++p); // Advance p. + } else { + LOG_STRING(ERROR, errors) + << "\\u must be followed by 4 hex digits: \\" + << string(hex_start, p+1-hex_start); + break; + } + } + d += runetochar(d, &rune); + break; + } + case 'U': { + // \Uhhhhhhhh => convert 8 hex digits to UTF-8 + char32 rune = 0; + const char *hex_start = p; + for (int i = 0; i < 8; ++i) { + if (isxdigit(p[1])) { // Look one char ahead. + // Don't change rune until we're sure this + // is within the Unicode limit, but do advance p. + char32 newrune = (rune << 4) + hex_digit_to_int(*++p); + if (newrune > 0x10FFFF) { + LOG_STRING(ERROR, errors) + << "Value of \\" + << string(hex_start, p + 1 - hex_start) + << " exceeds Unicode limit (0x10FFFF)"; + break; + } else { + rune = newrune; + } + } else { + LOG_STRING(ERROR, errors) + << "\\U must be followed by 8 hex digits: \\" + << string(hex_start, p+1-hex_start); + break; + } + } + d += runetochar(d, &rune); + break; + } +#endif + default: + LOG_STRING(ERROR, errors) << "Unknown escape sequence: \\" << *p; + } + p++; // read past letter we escaped + } + } + *d = '\0'; + return d - dest; +} + +// ---------------------------------------------------------------------- +// UnescapeCEscapeString() +// This does the same thing as UnescapeCEscapeSequences, but creates +// a new string. The caller does not need to worry about allocating +// a dest buffer. This should be used for non performance critical +// tasks such as printing debug messages. It is safe for src and dest +// to be the same. +// +// The second call stores its errors in a supplied string vector. +// If the string vector pointer is NULL, it reports the errors with LOG(). +// +// In the first and second calls, the length of dest is returned. In the +// the third call, the new string is returned. +// ---------------------------------------------------------------------- +int UnescapeCEscapeString(const string& src, string* dest) { + return UnescapeCEscapeString(src, dest, NULL); +} + +int UnescapeCEscapeString(const string& src, string* dest, + vector *errors) { + scoped_array unescaped(new char[src.size() + 1]); + int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors); + GOOGLE_CHECK(dest); + dest->assign(unescaped.get(), len); + return len; +} + +string UnescapeCEscapeString(const string& src) { + scoped_array unescaped(new char[src.size() + 1]); + int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), NULL); + return string(unescaped.get(), len); +} + +// ---------------------------------------------------------------------- +// CEscapeString() +// CHexEscapeString() +// Copies 'src' to 'dest', escaping dangerous characters using +// C-style escape sequences. This is very useful for preparing query +// flags. 'src' and 'dest' should not overlap. The 'Hex' version uses +// hexadecimal rather than octal sequences. +// Returns the number of bytes written to 'dest' (not including the \0) +// or -1 if there was insufficient space. +// +// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. +// ---------------------------------------------------------------------- +int CEscapeInternal(const char* src, int src_len, char* dest, + int dest_len, bool use_hex, bool utf8_safe) { + const char* src_end = src + src_len; + int used = 0; + bool last_hex_escape = false; // true if last output char was \xNN + + for (; src < src_end; src++) { + if (dest_len - used < 2) // Need space for two letter escape + return -1; + + bool is_hex_escape = false; + switch (*src) { + case '\n': dest[used++] = '\\'; dest[used++] = 'n'; break; + case '\r': dest[used++] = '\\'; dest[used++] = 'r'; break; + case '\t': dest[used++] = '\\'; dest[used++] = 't'; break; + case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break; + case '\'': dest[used++] = '\\'; dest[used++] = '\''; break; + case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break; + default: + // Note that if we emit \xNN and the src character after that is a hex + // digit then that digit must be escaped too to prevent it being + // interpreted as part of the character code by C. + if ((!utf8_safe || static_cast(*src) < 0x80) && + (!isprint(*src) || + (last_hex_escape && isxdigit(*src)))) { + if (dest_len - used < 4) // need space for 4 letter escape + return -1; + sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"), + static_cast(*src)); + is_hex_escape = use_hex; + used += 4; + } else { + dest[used++] = *src; break; + } + } + last_hex_escape = is_hex_escape; + } + + if (dest_len - used < 1) // make sure that there is room for \0 + return -1; + + dest[used] = '\0'; // doesn't count towards return value though + return used; +} + +int CEscapeString(const char* src, int src_len, char* dest, int dest_len) { + return CEscapeInternal(src, src_len, dest, dest_len, false, false); +} + +// ---------------------------------------------------------------------- +// CEscape() +// CHexEscape() +// Copies 'src' to result, escaping dangerous characters using +// C-style escape sequences. This is very useful for preparing query +// flags. 'src' and 'dest' should not overlap. The 'Hex' version +// hexadecimal rather than octal sequences. +// +// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. +// ---------------------------------------------------------------------- +string CEscape(const string& src) { + const int dest_length = src.size() * 4 + 1; // Maximum possible expansion + scoped_array dest(new char[dest_length]); + const int len = CEscapeInternal(src.data(), src.size(), + dest.get(), dest_length, false, false); + GOOGLE_DCHECK_GE(len, 0); + return string(dest.get(), len); +} + +namespace strings { + +string Utf8SafeCEscape(const string& src) { + const int dest_length = src.size() * 4 + 1; // Maximum possible expansion + scoped_array dest(new char[dest_length]); + const int len = CEscapeInternal(src.data(), src.size(), + dest.get(), dest_length, false, true); + GOOGLE_DCHECK_GE(len, 0); + return string(dest.get(), len); +} + +string CHexEscape(const string& src) { + const int dest_length = src.size() * 4 + 1; // Maximum possible expansion + scoped_array dest(new char[dest_length]); + const int len = CEscapeInternal(src.data(), src.size(), + dest.get(), dest_length, true, false); + GOOGLE_DCHECK_GE(len, 0); + return string(dest.get(), len); +} + +} // namespace strings + +// ---------------------------------------------------------------------- +// strto32_adaptor() +// strtou32_adaptor() +// Implementation of strto[u]l replacements that have identical +// overflow and underflow characteristics for both ILP-32 and LP-64 +// platforms, including errno preservation in error-free calls. +// ---------------------------------------------------------------------- + +int32 strto32_adaptor(const char *nptr, char **endptr, int base) { + const int saved_errno = errno; + errno = 0; + const long result = strtol(nptr, endptr, base); + if (errno == ERANGE && result == LONG_MIN) { + return kint32min; + } else if (errno == ERANGE && result == LONG_MAX) { + return kint32max; + } else if (errno == 0 && result < kint32min) { + errno = ERANGE; + return kint32min; + } else if (errno == 0 && result > kint32max) { + errno = ERANGE; + return kint32max; + } + if (errno == 0) + errno = saved_errno; + return static_cast(result); +} + +uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) { + const int saved_errno = errno; + errno = 0; + const unsigned long result = strtoul(nptr, endptr, base); + if (errno == ERANGE && result == ULONG_MAX) { + return kuint32max; + } else if (errno == 0 && result > kuint32max) { + errno = ERANGE; + return kuint32max; + } + if (errno == 0) + errno = saved_errno; + return static_cast(result); +} + +// ---------------------------------------------------------------------- +// FastIntToBuffer() +// FastInt64ToBuffer() +// FastHexToBuffer() +// FastHex64ToBuffer() +// FastHex32ToBuffer() +// ---------------------------------------------------------------------- + +// Offset into buffer where FastInt64ToBuffer places the end of string +// null character. Also used by FastInt64ToBufferLeft. +static const int kFastInt64ToBufferOffset = 21; + +char *FastInt64ToBuffer(int64 i, char* buffer) { + // We could collapse the positive and negative sections, but that + // would be slightly slower for positive numbers... + // 22 bytes is enough to store -2**64, -18446744073709551616. + char* p = buffer + kFastInt64ToBufferOffset; + *p-- = '\0'; + if (i >= 0) { + do { + *p-- = '0' + i % 10; + i /= 10; + } while (i > 0); + return p + 1; + } else { + // On different platforms, % and / have different behaviors for + // negative numbers, so we need to jump through hoops to make sure + // we don't divide negative numbers. + if (i > -10) { + i = -i; + *p-- = '0' + i; + *p = '-'; + return p; + } else { + // Make sure we aren't at MIN_INT, in which case we can't say i = -i + i = i + 10; + i = -i; + *p-- = '0' + i % 10; + // Undo what we did a moment ago + i = i / 10 + 1; + do { + *p-- = '0' + i % 10; + i /= 10; + } while (i > 0); + *p = '-'; + return p; + } + } +} + +// Offset into buffer where FastInt32ToBuffer places the end of string +// null character. Also used by FastInt32ToBufferLeft +static const int kFastInt32ToBufferOffset = 11; + +// Yes, this is a duplicate of FastInt64ToBuffer. But, we need this for the +// compiler to generate 32 bit arithmetic instructions. It's much faster, at +// least with 32 bit binaries. +char *FastInt32ToBuffer(int32 i, char* buffer) { + // We could collapse the positive and negative sections, but that + // would be slightly slower for positive numbers... + // 12 bytes is enough to store -2**32, -4294967296. + char* p = buffer + kFastInt32ToBufferOffset; + *p-- = '\0'; + if (i >= 0) { + do { + *p-- = '0' + i % 10; + i /= 10; + } while (i > 0); + return p + 1; + } else { + // On different platforms, % and / have different behaviors for + // negative numbers, so we need to jump through hoops to make sure + // we don't divide negative numbers. + if (i > -10) { + i = -i; + *p-- = '0' + i; + *p = '-'; + return p; + } else { + // Make sure we aren't at MIN_INT, in which case we can't say i = -i + i = i + 10; + i = -i; + *p-- = '0' + i % 10; + // Undo what we did a moment ago + i = i / 10 + 1; + do { + *p-- = '0' + i % 10; + i /= 10; + } while (i > 0); + *p = '-'; + return p; + } + } +} + +char *FastHexToBuffer(int i, char* buffer) { + GOOGLE_CHECK(i >= 0) << "FastHexToBuffer() wants non-negative integers, not " << i; + + static const char *hexdigits = "0123456789abcdef"; + char *p = buffer + 21; + *p-- = '\0'; + do { + *p-- = hexdigits[i & 15]; // mod by 16 + i >>= 4; // divide by 16 + } while (i > 0); + return p + 1; +} + +char *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) { + static const char *hexdigits = "0123456789abcdef"; + buffer[num_byte] = '\0'; + for (int i = num_byte - 1; i >= 0; i--) { +#ifdef _M_X64 + // MSVC x64 platform has a bug optimizing the uint32(value) in the #else + // block. Given that the uint32 cast was to improve performance on 32-bit + // platforms, we use 64-bit '&' directly. + buffer[i] = hexdigits[value & 0xf]; +#else + buffer[i] = hexdigits[uint32(value) & 0xf]; +#endif + value >>= 4; + } + return buffer; +} + +char *FastHex64ToBuffer(uint64 value, char* buffer) { + return InternalFastHexToBuffer(value, buffer, 16); +} + +char *FastHex32ToBuffer(uint32 value, char* buffer) { + return InternalFastHexToBuffer(value, buffer, 8); +} + +static inline char* PlaceNum(char* p, int num, char prev_sep) { + *p-- = '0' + num % 10; + *p-- = '0' + num / 10; + *p-- = prev_sep; + return p; +} + +// ---------------------------------------------------------------------- +// FastInt32ToBufferLeft() +// FastUInt32ToBufferLeft() +// FastInt64ToBufferLeft() +// FastUInt64ToBufferLeft() +// +// Like the Fast*ToBuffer() functions above, these are intended for speed. +// Unlike the Fast*ToBuffer() functions, however, these functions write +// their output to the beginning of the buffer (hence the name, as the +// output is left-aligned). The caller is responsible for ensuring that +// the buffer has enough space to hold the output. +// +// Returns a pointer to the end of the string (i.e. the null character +// terminating the string). +// ---------------------------------------------------------------------- + +static const char two_ASCII_digits[100][2] = { + {'0','0'}, {'0','1'}, {'0','2'}, {'0','3'}, {'0','4'}, + {'0','5'}, {'0','6'}, {'0','7'}, {'0','8'}, {'0','9'}, + {'1','0'}, {'1','1'}, {'1','2'}, {'1','3'}, {'1','4'}, + {'1','5'}, {'1','6'}, {'1','7'}, {'1','8'}, {'1','9'}, + {'2','0'}, {'2','1'}, {'2','2'}, {'2','3'}, {'2','4'}, + {'2','5'}, {'2','6'}, {'2','7'}, {'2','8'}, {'2','9'}, + {'3','0'}, {'3','1'}, {'3','2'}, {'3','3'}, {'3','4'}, + {'3','5'}, {'3','6'}, {'3','7'}, {'3','8'}, {'3','9'}, + {'4','0'}, {'4','1'}, {'4','2'}, {'4','3'}, {'4','4'}, + {'4','5'}, {'4','6'}, {'4','7'}, {'4','8'}, {'4','9'}, + {'5','0'}, {'5','1'}, {'5','2'}, {'5','3'}, {'5','4'}, + {'5','5'}, {'5','6'}, {'5','7'}, {'5','8'}, {'5','9'}, + {'6','0'}, {'6','1'}, {'6','2'}, {'6','3'}, {'6','4'}, + {'6','5'}, {'6','6'}, {'6','7'}, {'6','8'}, {'6','9'}, + {'7','0'}, {'7','1'}, {'7','2'}, {'7','3'}, {'7','4'}, + {'7','5'}, {'7','6'}, {'7','7'}, {'7','8'}, {'7','9'}, + {'8','0'}, {'8','1'}, {'8','2'}, {'8','3'}, {'8','4'}, + {'8','5'}, {'8','6'}, {'8','7'}, {'8','8'}, {'8','9'}, + {'9','0'}, {'9','1'}, {'9','2'}, {'9','3'}, {'9','4'}, + {'9','5'}, {'9','6'}, {'9','7'}, {'9','8'}, {'9','9'} +}; + +char* FastUInt32ToBufferLeft(uint32 u, char* buffer) { + int digits; + const char *ASCII_digits = NULL; + // The idea of this implementation is to trim the number of divides to as few + // as possible by using multiplication and subtraction rather than mod (%), + // and by outputting two digits at a time rather than one. + // The huge-number case is first, in the hopes that the compiler will output + // that case in one branch-free block of code, and only output conditional + // branches into it from below. + if (u >= 1000000000) { // >= 1,000,000,000 + digits = u / 100000000; // 100,000,000 + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; +sublt100_000_000: + u -= digits * 100000000; // 100,000,000 +lt100_000_000: + digits = u / 1000000; // 1,000,000 + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; +sublt1_000_000: + u -= digits * 1000000; // 1,000,000 +lt1_000_000: + digits = u / 10000; // 10,000 + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; +sublt10_000: + u -= digits * 10000; // 10,000 +lt10_000: + digits = u / 100; + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; +sublt100: + u -= digits * 100; +lt100: + digits = u; + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; +done: + *buffer = 0; + return buffer; + } + + if (u < 100) { + digits = u; + if (u >= 10) goto lt100; + *buffer++ = '0' + digits; + goto done; + } + if (u < 10000) { // 10,000 + if (u >= 1000) goto lt10_000; + digits = u / 100; + *buffer++ = '0' + digits; + goto sublt100; + } + if (u < 1000000) { // 1,000,000 + if (u >= 100000) goto lt1_000_000; + digits = u / 10000; // 10,000 + *buffer++ = '0' + digits; + goto sublt10_000; + } + if (u < 100000000) { // 100,000,000 + if (u >= 10000000) goto lt100_000_000; + digits = u / 1000000; // 1,000,000 + *buffer++ = '0' + digits; + goto sublt1_000_000; + } + // we already know that u < 1,000,000,000 + digits = u / 100000000; // 100,000,000 + *buffer++ = '0' + digits; + goto sublt100_000_000; +} + +char* FastInt32ToBufferLeft(int32 i, char* buffer) { + uint32 u = i; + if (i < 0) { + *buffer++ = '-'; + u = -i; + } + return FastUInt32ToBufferLeft(u, buffer); +} + +char* FastUInt64ToBufferLeft(uint64 u64, char* buffer) { + int digits; + const char *ASCII_digits = NULL; + + uint32 u = static_cast(u64); + if (u == u64) return FastUInt32ToBufferLeft(u, buffer); + + uint64 top_11_digits = u64 / 1000000000; + buffer = FastUInt64ToBufferLeft(top_11_digits, buffer); + u = u64 - (top_11_digits * 1000000000); + + digits = u / 10000000; // 10,000,000 + GOOGLE_DCHECK_LT(digits, 100); + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; + u -= digits * 10000000; // 10,000,000 + digits = u / 100000; // 100,000 + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; + u -= digits * 100000; // 100,000 + digits = u / 1000; // 1,000 + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; + u -= digits * 1000; // 1,000 + digits = u / 10; + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; + u -= digits * 10; + digits = u; + *buffer++ = '0' + digits; + *buffer = 0; + return buffer; +} + +char* FastInt64ToBufferLeft(int64 i, char* buffer) { + uint64 u = i; + if (i < 0) { + *buffer++ = '-'; + u = -i; + } + return FastUInt64ToBufferLeft(u, buffer); +} + +// ---------------------------------------------------------------------- +// SimpleItoa() +// Description: converts an integer to a string. +// +// Return value: string +// ---------------------------------------------------------------------- + +string SimpleItoa(int i) { + char buffer[kFastToBufferSize]; + return (sizeof(i) == 4) ? + FastInt32ToBuffer(i, buffer) : + FastInt64ToBuffer(i, buffer); +} + +string SimpleItoa(unsigned int i) { + char buffer[kFastToBufferSize]; + return string(buffer, (sizeof(i) == 4) ? + FastUInt32ToBufferLeft(i, buffer) : + FastUInt64ToBufferLeft(i, buffer)); +} + +string SimpleItoa(long i) { + char buffer[kFastToBufferSize]; + return (sizeof(i) == 4) ? + FastInt32ToBuffer(i, buffer) : + FastInt64ToBuffer(i, buffer); +} + +string SimpleItoa(unsigned long i) { + char buffer[kFastToBufferSize]; + return string(buffer, (sizeof(i) == 4) ? + FastUInt32ToBufferLeft(i, buffer) : + FastUInt64ToBufferLeft(i, buffer)); +} + +string SimpleItoa(long long i) { + char buffer[kFastToBufferSize]; + return (sizeof(i) == 4) ? + FastInt32ToBuffer(i, buffer) : + FastInt64ToBuffer(i, buffer); +} + +string SimpleItoa(unsigned long long i) { + char buffer[kFastToBufferSize]; + return string(buffer, (sizeof(i) == 4) ? + FastUInt32ToBufferLeft(i, buffer) : + FastUInt64ToBufferLeft(i, buffer)); +} + +// ---------------------------------------------------------------------- +// SimpleDtoa() +// SimpleFtoa() +// DoubleToBuffer() +// FloatToBuffer() +// We want to print the value without losing precision, but we also do +// not want to print more digits than necessary. This turns out to be +// trickier than it sounds. Numbers like 0.2 cannot be represented +// exactly in binary. If we print 0.2 with a very large precision, +// e.g. "%.50g", we get "0.2000000000000000111022302462515654042363167". +// On the other hand, if we set the precision too low, we lose +// significant digits when printing numbers that actually need them. +// It turns out there is no precision value that does the right thing +// for all numbers. +// +// Our strategy is to first try printing with a precision that is never +// over-precise, then parse the result with strtod() to see if it +// matches. If not, we print again with a precision that will always +// give a precise result, but may use more digits than necessary. +// +// An arguably better strategy would be to use the algorithm described +// in "How to Print Floating-Point Numbers Accurately" by Steele & +// White, e.g. as implemented by David M. Gay's dtoa(). It turns out, +// however, that the following implementation is about as fast as +// DMG's code. Furthermore, DMG's code locks mutexes, which means it +// will not scale well on multi-core machines. DMG's code is slightly +// more accurate (in that it will never use more digits than +// necessary), but this is probably irrelevant for most users. +// +// Rob Pike and Ken Thompson also have an implementation of dtoa() in +// third_party/fmt/fltfmt.cc. Their implementation is similar to this +// one in that it makes guesses and then uses strtod() to check them. +// Their implementation is faster because they use their own code to +// generate the digits in the first place rather than use snprintf(), +// thus avoiding format string parsing overhead. However, this makes +// it considerably more complicated than the following implementation, +// and it is embedded in a larger library. If speed turns out to be +// an issue, we could re-implement this in terms of their +// implementation. +// ---------------------------------------------------------------------- + +string SimpleDtoa(double value) { + char buffer[kDoubleToBufferSize]; + return DoubleToBuffer(value, buffer); +} + +string SimpleFtoa(float value) { + char buffer[kFloatToBufferSize]; + return FloatToBuffer(value, buffer); +} + +static inline bool IsValidFloatChar(char c) { + return ('0' <= c && c <= '9') || + c == 'e' || c == 'E' || + c == '+' || c == '-'; +} + +void DelocalizeRadix(char* buffer) { + // Fast check: if the buffer has a normal decimal point, assume no + // translation is needed. + if (strchr(buffer, '.') != NULL) return; + + // Find the first unknown character. + while (IsValidFloatChar(*buffer)) ++buffer; + + if (*buffer == '\0') { + // No radix character found. + return; + } + + // We are now pointing at the locale-specific radix character. Replace it + // with '.'. + *buffer = '.'; + ++buffer; + + if (!IsValidFloatChar(*buffer) && *buffer != '\0') { + // It appears the radix was a multi-byte character. We need to remove the + // extra bytes. + char* target = buffer; + do { ++buffer; } while (!IsValidFloatChar(*buffer) && *buffer != '\0'); + memmove(target, buffer, strlen(buffer) + 1); + } +} + +char* DoubleToBuffer(double value, char* buffer) { + // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all + // platforms these days. Just in case some system exists where DBL_DIG + // is significantly larger -- and risks overflowing our buffer -- we have + // this assert. + GOOGLE_COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big); + + if (value == numeric_limits::infinity()) { + strcpy(buffer, "inf"); + return buffer; + } else if (value == -numeric_limits::infinity()) { + strcpy(buffer, "-inf"); + return buffer; + } else if (IsNaN(value)) { + strcpy(buffer, "nan"); + return buffer; + } + + int snprintf_result = + snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value); + + // The snprintf should never overflow because the buffer is significantly + // larger than the precision we asked for. + GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); + + // We need to make parsed_value volatile in order to force the compiler to + // write it out to the stack. Otherwise, it may keep the value in a + // register, and if it does that, it may keep it as a long double instead + // of a double. This long double may have extra bits that make it compare + // unequal to "value" even though it would be exactly equal if it were + // truncated to a double. + volatile double parsed_value = strtod(buffer, NULL); + if (parsed_value != value) { + int snprintf_result = + snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG+2, value); + + // Should never overflow; see above. + GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); + } + + DelocalizeRadix(buffer); + return buffer; +} + +bool safe_strtof(const char* str, float* value) { + char* endptr; + errno = 0; // errno only gets set on errors +#if defined(_WIN32) || defined (__hpux) // has no strtof() + *value = strtod(str, &endptr); +#else + *value = strtof(str, &endptr); +#endif + return *str != 0 && *endptr == 0 && errno == 0; +} + +char* FloatToBuffer(float value, char* buffer) { + // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all + // platforms these days. Just in case some system exists where FLT_DIG + // is significantly larger -- and risks overflowing our buffer -- we have + // this assert. + GOOGLE_COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big); + + if (value == numeric_limits::infinity()) { + strcpy(buffer, "inf"); + return buffer; + } else if (value == -numeric_limits::infinity()) { + strcpy(buffer, "-inf"); + return buffer; + } else if (IsNaN(value)) { + strcpy(buffer, "nan"); + return buffer; + } + + int snprintf_result = + snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value); + + // The snprintf should never overflow because the buffer is significantly + // larger than the precision we asked for. + GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); + + float parsed_value; + if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) { + int snprintf_result = + snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+2, value); + + // Should never overflow; see above. + GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); + } + + DelocalizeRadix(buffer); + return buffer; +} + +// ---------------------------------------------------------------------- +// NoLocaleStrtod() +// This code will make you cry. +// ---------------------------------------------------------------------- + +// Returns a string identical to *input except that the character pointed to +// by radix_pos (which should be '.') is replaced with the locale-specific +// radix character. +string LocalizeRadix(const char* input, const char* radix_pos) { + // Determine the locale-specific radix character by calling sprintf() to + // print the number 1.5, then stripping off the digits. As far as I can + // tell, this is the only portable, thread-safe way to get the C library + // to divuldge the locale's radix character. No, localeconv() is NOT + // thread-safe. + char temp[16]; + int size = sprintf(temp, "%.1f", 1.5); + GOOGLE_CHECK_EQ(temp[0], '1'); + GOOGLE_CHECK_EQ(temp[size-1], '5'); + GOOGLE_CHECK_LE(size, 6); + + // Now replace the '.' in the input with it. + string result; + result.reserve(strlen(input) + size - 3); + result.append(input, radix_pos); + result.append(temp + 1, size - 2); + result.append(radix_pos + 1); + return result; +} + +double NoLocaleStrtod(const char* text, char** original_endptr) { + // We cannot simply set the locale to "C" temporarily with setlocale() + // as this is not thread-safe. Instead, we try to parse in the current + // locale first. If parsing stops at a '.' character, then this is a + // pretty good hint that we're actually in some other locale in which + // '.' is not the radix character. + + char* temp_endptr; + double result = strtod(text, &temp_endptr); + if (original_endptr != NULL) *original_endptr = temp_endptr; + if (*temp_endptr != '.') return result; + + // Parsing halted on a '.'. Perhaps we're in a different locale? Let's + // try to replace the '.' with a locale-specific radix character and + // try again. + string localized = LocalizeRadix(text, temp_endptr); + const char* localized_cstr = localized.c_str(); + char* localized_endptr; + result = strtod(localized_cstr, &localized_endptr); + if ((localized_endptr - localized_cstr) > + (temp_endptr - text)) { + // This attempt got further, so replacing the decimal must have helped. + // Update original_endptr to point at the right location. + if (original_endptr != NULL) { + // size_diff is non-zero if the localized radix has multiple bytes. + int size_diff = localized.size() - strlen(text); + // const_cast is necessary to match the strtod() interface. + *original_endptr = const_cast( + text + (localized_endptr - localized_cstr - size_diff)); + } + } + + return result; +} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil.h new file mode 100644 index 0000000..a401c63 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil.h @@ -0,0 +1,467 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// from google3/strings/strutil.h + +#ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ +#define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { + +#ifdef _MSC_VER +#define strtoll _strtoi64 +#define strtoull _strtoui64 +#elif defined(__DECCXX) && defined(__osf__) +// HP C++ on Tru64 does not have strtoll, but strtol is already 64-bit. +#define strtoll strtol +#define strtoull strtoul +#endif + +// ---------------------------------------------------------------------- +// ascii_isalnum() +// Check if an ASCII character is alphanumeric. We can't use ctype's +// isalnum() because it is affected by locale. This function is applied +// to identifiers in the protocol buffer language, not to natural-language +// strings, so locale should not be taken into account. +// ascii_isdigit() +// Like above, but only accepts digits. +// ---------------------------------------------------------------------- + +inline bool ascii_isalnum(char c) { + return ('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + ('0' <= c && c <= '9'); +} + +inline bool ascii_isdigit(char c) { + return ('0' <= c && c <= '9'); +} + +// ---------------------------------------------------------------------- +// HasPrefixString() +// Check if a string begins with a given prefix. +// StripPrefixString() +// Given a string and a putative prefix, returns the string minus the +// prefix string if the prefix matches, otherwise the original +// string. +// ---------------------------------------------------------------------- +inline bool HasPrefixString(const string& str, + const string& prefix) { + return str.size() >= prefix.size() && + str.compare(0, prefix.size(), prefix) == 0; +} + +inline string StripPrefixString(const string& str, const string& prefix) { + if (HasPrefixString(str, prefix)) { + return str.substr(prefix.size()); + } else { + return str; + } +} + +// ---------------------------------------------------------------------- +// HasSuffixString() +// Return true if str ends in suffix. +// StripSuffixString() +// Given a string and a putative suffix, returns the string minus the +// suffix string if the suffix matches, otherwise the original +// string. +// ---------------------------------------------------------------------- +inline bool HasSuffixString(const string& str, + const string& suffix) { + return str.size() >= suffix.size() && + str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; +} + +inline string StripSuffixString(const string& str, const string& suffix) { + if (HasSuffixString(str, suffix)) { + return str.substr(0, str.size() - suffix.size()); + } else { + return str; + } +} + +// ---------------------------------------------------------------------- +// StripString +// Replaces any occurrence of the character 'remove' (or the characters +// in 'remove') with the character 'replacewith'. +// Good for keeping html characters or protocol characters (\t) out +// of places where they might cause a problem. +// ---------------------------------------------------------------------- +LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove, + char replacewith); + +// ---------------------------------------------------------------------- +// LowerString() +// UpperString() +// Convert the characters in "s" to lowercase or uppercase. ASCII-only: +// these functions intentionally ignore locale because they are applied to +// identifiers used in the Protocol Buffer language, not to natural-language +// strings. +// ---------------------------------------------------------------------- + +inline void LowerString(string * s) { + string::iterator end = s->end(); + for (string::iterator i = s->begin(); i != end; ++i) { + // tolower() changes based on locale. We don't want this! + if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A'; + } +} + +inline void UpperString(string * s) { + string::iterator end = s->end(); + for (string::iterator i = s->begin(); i != end; ++i) { + // toupper() changes based on locale. We don't want this! + if ('a' <= *i && *i <= 'z') *i += 'A' - 'a'; + } +} + +// ---------------------------------------------------------------------- +// StringReplace() +// Give me a string and two patterns "old" and "new", and I replace +// the first instance of "old" in the string with "new", if it +// exists. RETURN a new string, regardless of whether the replacement +// happened or not. +// ---------------------------------------------------------------------- + +LIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub, + const string& newsub, bool replace_all); + +// ---------------------------------------------------------------------- +// SplitStringUsing() +// Split a string using a character delimiter. Append the components +// to 'result'. If there are consecutive delimiters, this function skips +// over all of them. +// ---------------------------------------------------------------------- +LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim, + vector* res); + +// Split a string using one or more byte delimiters, presented +// as a nul-terminated c string. Append the components to 'result'. +// If there are consecutive delimiters, this function will return +// corresponding empty strings. If you want to drop the empty +// strings, try SplitStringUsing(). +// +// If "full" is the empty string, yields an empty string as the only value. +// ---------------------------------------------------------------------- +LIBPROTOBUF_EXPORT void SplitStringAllowEmpty(const string& full, + const char* delim, + vector* result); + +// ---------------------------------------------------------------------- +// JoinStrings() +// These methods concatenate a vector of strings into a C++ string, using +// the C-string "delim" as a separator between components. There are two +// flavors of the function, one flavor returns the concatenated string, +// another takes a pointer to the target string. In the latter case the +// target string is cleared and overwritten. +// ---------------------------------------------------------------------- +LIBPROTOBUF_EXPORT void JoinStrings(const vector& components, + const char* delim, string* result); + +inline string JoinStrings(const vector& components, + const char* delim) { + string result; + JoinStrings(components, delim, &result); + return result; +} + +// ---------------------------------------------------------------------- +// UnescapeCEscapeSequences() +// Copies "source" to "dest", rewriting C-style escape sequences +// -- '\n', '\r', '\\', '\ooo', etc -- to their ASCII +// equivalents. "dest" must be sufficiently large to hold all +// the characters in the rewritten string (i.e. at least as large +// as strlen(source) + 1 should be safe, since the replacements +// are always shorter than the original escaped sequences). It's +// safe for source and dest to be the same. RETURNS the length +// of dest. +// +// It allows hex sequences \xhh, or generally \xhhhhh with an +// arbitrary number of hex digits, but all of them together must +// specify a value of a single byte (e.g. \x0045 is equivalent +// to \x45, and \x1234 is erroneous). +// +// It also allows escape sequences of the form \uhhhh (exactly four +// hex digits, upper or lower case) or \Uhhhhhhhh (exactly eight +// hex digits, upper or lower case) to specify a Unicode code +// point. The dest array will contain the UTF8-encoded version of +// that code-point (e.g., if source contains \u2019, then dest will +// contain the three bytes 0xE2, 0x80, and 0x99). +// +// Errors: In the first form of the call, errors are reported with +// LOG(ERROR). The same is true for the second form of the call if +// the pointer to the string vector is NULL; otherwise, error +// messages are stored in the vector. In either case, the effect on +// the dest array is not defined, but rest of the source will be +// processed. +// ---------------------------------------------------------------------- + +LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest); +LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, + vector *errors); + +// ---------------------------------------------------------------------- +// UnescapeCEscapeString() +// This does the same thing as UnescapeCEscapeSequences, but creates +// a new string. The caller does not need to worry about allocating +// a dest buffer. This should be used for non performance critical +// tasks such as printing debug messages. It is safe for src and dest +// to be the same. +// +// The second call stores its errors in a supplied string vector. +// If the string vector pointer is NULL, it reports the errors with LOG(). +// +// In the first and second calls, the length of dest is returned. In the +// the third call, the new string is returned. +// ---------------------------------------------------------------------- + +LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest); +LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest, + vector *errors); +LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src); + +// ---------------------------------------------------------------------- +// CEscapeString() +// Copies 'src' to 'dest', escaping dangerous characters using +// C-style escape sequences. This is very useful for preparing query +// flags. 'src' and 'dest' should not overlap. +// Returns the number of bytes written to 'dest' (not including the \0) +// or -1 if there was insufficient space. +// +// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. +// ---------------------------------------------------------------------- +LIBPROTOBUF_EXPORT int CEscapeString(const char* src, int src_len, + char* dest, int dest_len); + +// ---------------------------------------------------------------------- +// CEscape() +// More convenient form of CEscapeString: returns result as a "string". +// This version is slower than CEscapeString() because it does more +// allocation. However, it is much more convenient to use in +// non-speed-critical code like logging messages etc. +// ---------------------------------------------------------------------- +LIBPROTOBUF_EXPORT string CEscape(const string& src); + +namespace strings { +// Like CEscape() but does not escape bytes with the upper bit set. +LIBPROTOBUF_EXPORT string Utf8SafeCEscape(const string& src); + +// Like CEscape() but uses hex (\x) escapes instead of octals. +LIBPROTOBUF_EXPORT string CHexEscape(const string& src); +} // namespace strings + +// ---------------------------------------------------------------------- +// strto32() +// strtou32() +// strto64() +// strtou64() +// Architecture-neutral plug compatible replacements for strtol() and +// strtoul(). Long's have different lengths on ILP-32 and LP-64 +// platforms, so using these is safer, from the point of view of +// overflow behavior, than using the standard libc functions. +// ---------------------------------------------------------------------- +LIBPROTOBUF_EXPORT int32 strto32_adaptor(const char *nptr, char **endptr, + int base); +LIBPROTOBUF_EXPORT uint32 strtou32_adaptor(const char *nptr, char **endptr, + int base); + +inline int32 strto32(const char *nptr, char **endptr, int base) { + if (sizeof(int32) == sizeof(long)) + return strtol(nptr, endptr, base); + else + return strto32_adaptor(nptr, endptr, base); +} + +inline uint32 strtou32(const char *nptr, char **endptr, int base) { + if (sizeof(uint32) == sizeof(unsigned long)) + return strtoul(nptr, endptr, base); + else + return strtou32_adaptor(nptr, endptr, base); +} + +// For now, long long is 64-bit on all the platforms we care about, so these +// functions can simply pass the call to strto[u]ll. +inline int64 strto64(const char *nptr, char **endptr, int base) { + GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long), + sizeof_int64_is_not_sizeof_long_long); + return strtoll(nptr, endptr, base); +} + +inline uint64 strtou64(const char *nptr, char **endptr, int base) { + GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long), + sizeof_uint64_is_not_sizeof_long_long); + return strtoull(nptr, endptr, base); +} + +// ---------------------------------------------------------------------- +// FastIntToBuffer() +// FastHexToBuffer() +// FastHex64ToBuffer() +// FastHex32ToBuffer() +// FastTimeToBuffer() +// These are intended for speed. FastIntToBuffer() assumes the +// integer is non-negative. FastHexToBuffer() puts output in +// hex rather than decimal. FastTimeToBuffer() puts the output +// into RFC822 format. +// +// FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format, +// padded to exactly 16 bytes (plus one byte for '\0') +// +// FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format, +// padded to exactly 8 bytes (plus one byte for '\0') +// +// All functions take the output buffer as an arg. +// They all return a pointer to the beginning of the output, +// which may not be the beginning of the input buffer. +// ---------------------------------------------------------------------- + +// Suggested buffer size for FastToBuffer functions. Also works with +// DoubleToBuffer() and FloatToBuffer(). +static const int kFastToBufferSize = 32; + +LIBPROTOBUF_EXPORT char* FastInt32ToBuffer(int32 i, char* buffer); +LIBPROTOBUF_EXPORT char* FastInt64ToBuffer(int64 i, char* buffer); +char* FastUInt32ToBuffer(uint32 i, char* buffer); // inline below +char* FastUInt64ToBuffer(uint64 i, char* buffer); // inline below +LIBPROTOBUF_EXPORT char* FastHexToBuffer(int i, char* buffer); +LIBPROTOBUF_EXPORT char* FastHex64ToBuffer(uint64 i, char* buffer); +LIBPROTOBUF_EXPORT char* FastHex32ToBuffer(uint32 i, char* buffer); + +// at least 22 bytes long +inline char* FastIntToBuffer(int i, char* buffer) { + return (sizeof(i) == 4 ? + FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer)); +} +inline char* FastUIntToBuffer(unsigned int i, char* buffer) { + return (sizeof(i) == 4 ? + FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer)); +} +inline char* FastLongToBuffer(long i, char* buffer) { + return (sizeof(i) == 4 ? + FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer)); +} +inline char* FastULongToBuffer(unsigned long i, char* buffer) { + return (sizeof(i) == 4 ? + FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer)); +} + +// ---------------------------------------------------------------------- +// FastInt32ToBufferLeft() +// FastUInt32ToBufferLeft() +// FastInt64ToBufferLeft() +// FastUInt64ToBufferLeft() +// +// Like the Fast*ToBuffer() functions above, these are intended for speed. +// Unlike the Fast*ToBuffer() functions, however, these functions write +// their output to the beginning of the buffer (hence the name, as the +// output is left-aligned). The caller is responsible for ensuring that +// the buffer has enough space to hold the output. +// +// Returns a pointer to the end of the string (i.e. the null character +// terminating the string). +// ---------------------------------------------------------------------- + +LIBPROTOBUF_EXPORT char* FastInt32ToBufferLeft(int32 i, char* buffer); +LIBPROTOBUF_EXPORT char* FastUInt32ToBufferLeft(uint32 i, char* buffer); +LIBPROTOBUF_EXPORT char* FastInt64ToBufferLeft(int64 i, char* buffer); +LIBPROTOBUF_EXPORT char* FastUInt64ToBufferLeft(uint64 i, char* buffer); + +// Just define these in terms of the above. +inline char* FastUInt32ToBuffer(uint32 i, char* buffer) { + FastUInt32ToBufferLeft(i, buffer); + return buffer; +} +inline char* FastUInt64ToBuffer(uint64 i, char* buffer) { + FastUInt64ToBufferLeft(i, buffer); + return buffer; +} + +// ---------------------------------------------------------------------- +// SimpleItoa() +// Description: converts an integer to a string. +// +// Return value: string +// ---------------------------------------------------------------------- +LIBPROTOBUF_EXPORT string SimpleItoa(int i); +LIBPROTOBUF_EXPORT string SimpleItoa(unsigned int i); +LIBPROTOBUF_EXPORT string SimpleItoa(long i); +LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long i); +LIBPROTOBUF_EXPORT string SimpleItoa(long long i); +LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long long i); + +// ---------------------------------------------------------------------- +// SimpleDtoa() +// SimpleFtoa() +// DoubleToBuffer() +// FloatToBuffer() +// Description: converts a double or float to a string which, if +// passed to NoLocaleStrtod(), will produce the exact same original double +// (except in case of NaN; all NaNs are considered the same value). +// We try to keep the string short but it's not guaranteed to be as +// short as possible. +// +// DoubleToBuffer() and FloatToBuffer() write the text to the given +// buffer and return it. The buffer must be at least +// kDoubleToBufferSize bytes for doubles and kFloatToBufferSize +// bytes for floats. kFastToBufferSize is also guaranteed to be large +// enough to hold either. +// +// Return value: string +// ---------------------------------------------------------------------- +LIBPROTOBUF_EXPORT string SimpleDtoa(double value); +LIBPROTOBUF_EXPORT string SimpleFtoa(float value); + +LIBPROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer); +LIBPROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer); + +// In practice, doubles should never need more than 24 bytes and floats +// should never need more than 14 (including null terminators), but we +// overestimate to be safe. +static const int kDoubleToBufferSize = 32; +static const int kFloatToBufferSize = 24; + +// ---------------------------------------------------------------------- +// NoLocaleStrtod() +// Exactly like strtod(), except it always behaves as if in the "C" +// locale (i.e. decimal points must be '.'s). +// ---------------------------------------------------------------------- + +LIBPROTOBUF_EXPORT double NoLocaleStrtod(const char* text, char** endptr); + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil_unittest.cc new file mode 100644 index 0000000..b9c9253 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/strutil_unittest.cc @@ -0,0 +1,83 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace { + +// TODO(kenton): Copy strutil tests from google3? + +TEST(StringUtilityTest, ImmuneToLocales) { + // Remember the old locale. + char* old_locale_cstr = setlocale(LC_NUMERIC, NULL); + ASSERT_TRUE(old_locale_cstr != NULL); + string old_locale = old_locale_cstr; + + // Set the locale to "C". + ASSERT_TRUE(setlocale(LC_NUMERIC, "C") != NULL); + + EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL)); + EXPECT_EQ("1.5", SimpleDtoa(1.5)); + EXPECT_EQ("1.5", SimpleFtoa(1.5)); + + // Verify that the endptr is set correctly even if not all text was parsed. + const char* text = "1.5f"; + char* endptr; + EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr)); + EXPECT_EQ(3, endptr - text); + + if (setlocale(LC_NUMERIC, "es_ES") == NULL && + setlocale(LC_NUMERIC, "es_ES.utf8") == NULL) { + // Some systems may not have the desired locale available. + GOOGLE_LOG(WARNING) + << "Couldn't set locale to es_ES. Skipping this test."; + } else { + EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL)); + EXPECT_EQ("1.5", SimpleDtoa(1.5)); + EXPECT_EQ("1.5", SimpleFtoa(1.5)); + EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr)); + EXPECT_EQ(3, endptr - text); + } + + // Return to original locale. + setlocale(LC_NUMERIC, old_locale.c_str()); +} + +} // anonymous namespace +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/substitute.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/substitute.cc new file mode 100644 index 0000000..259245b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/substitute.cc @@ -0,0 +1,134 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace strings { + +using internal::SubstituteArg; + +// Returns the number of args in arg_array which were passed explicitly +// to Substitute(). +static int CountSubstituteArgs(const SubstituteArg* const* args_array) { + int count = 0; + while (args_array[count] != NULL && args_array[count]->size() != -1) { + ++count; + } + return count; +} + +string Substitute( + const char* format, + const SubstituteArg& arg0, const SubstituteArg& arg1, + const SubstituteArg& arg2, const SubstituteArg& arg3, + const SubstituteArg& arg4, const SubstituteArg& arg5, + const SubstituteArg& arg6, const SubstituteArg& arg7, + const SubstituteArg& arg8, const SubstituteArg& arg9) { + string result; + SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4, + arg5, arg6, arg7, arg8, arg9); + return result; +} + +void SubstituteAndAppend( + string* output, const char* format, + const SubstituteArg& arg0, const SubstituteArg& arg1, + const SubstituteArg& arg2, const SubstituteArg& arg3, + const SubstituteArg& arg4, const SubstituteArg& arg5, + const SubstituteArg& arg6, const SubstituteArg& arg7, + const SubstituteArg& arg8, const SubstituteArg& arg9) { + const SubstituteArg* const args_array[] = { + &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, NULL + }; + + // Determine total size needed. + int size = 0; + for (int i = 0; format[i] != '\0'; i++) { + if (format[i] == '$') { + if (ascii_isdigit(format[i+1])) { + int index = format[i+1] - '0'; + if (args_array[index]->size() == -1) { + GOOGLE_LOG(DFATAL) + << "strings::Substitute format string invalid: asked for \"$" + << index << "\", but only " << CountSubstituteArgs(args_array) + << " args were given. Full format string was: \"" + << CEscape(format) << "\"."; + return; + } + size += args_array[index]->size(); + ++i; // Skip next char. + } else if (format[i+1] == '$') { + ++size; + ++i; // Skip next char. + } else { + GOOGLE_LOG(DFATAL) + << "Invalid strings::Substitute() format string: \"" + << CEscape(format) << "\"."; + return; + } + } else { + ++size; + } + } + + if (size == 0) return; + + // Build the string. + int original_size = output->size(); + STLStringResizeUninitialized(output, original_size + size); + char* target = string_as_array(output) + original_size; + for (int i = 0; format[i] != '\0'; i++) { + if (format[i] == '$') { + if (ascii_isdigit(format[i+1])) { + const SubstituteArg* src = args_array[format[i+1] - '0']; + memcpy(target, src->data(), src->size()); + target += src->size(); + ++i; // Skip next char. + } else if (format[i+1] == '$') { + *target++ = '$'; + ++i; // Skip next char. + } + } else { + *target++ = format[i]; + } + } + + GOOGLE_DCHECK_EQ(target - output->data(), output->size()); +} + +} // namespace strings +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/substitute.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/substitute.h new file mode 100644 index 0000000..2581793 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/substitute.h @@ -0,0 +1,170 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// from google3/strings/substitute.h + +#include +#include +#include + +#ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ +#define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ + +namespace google { +namespace protobuf { +namespace strings { + +// ---------------------------------------------------------------------- +// strings::Substitute() +// strings::SubstituteAndAppend() +// Kind of like StringPrintf, but different. +// +// Example: +// string GetMessage(string first_name, string last_name, int age) { +// return strings::Substitute("My name is $0 $1 and I am $2 years old.", +// first_name, last_name, age); +// } +// +// Differences from StringPrintf: +// * The format string does not identify the types of arguments. +// Instead, the magic of C++ deals with this for us. See below +// for a list of accepted types. +// * Substitutions in the format string are identified by a '$' +// followed by a digit. So, you can use arguments out-of-order and +// use the same argument multiple times. +// * It's much faster than StringPrintf. +// +// Supported types: +// * Strings (const char*, const string&) +// * Note that this means you do not have to add .c_str() to all of +// your strings. In fact, you shouldn't; it will be slower. +// * int32, int64, uint32, uint64: Formatted using SimpleItoa(). +// * float, double: Formatted using SimpleFtoa() and SimpleDtoa(). +// * bool: Printed as "true" or "false". +// +// SubstituteAndAppend() is like Substitute() but appends the result to +// *output. Example: +// +// string str; +// strings::SubstituteAndAppend(&str, +// "My name is $0 $1 and I am $2 years old.", +// first_name, last_name, age); +// +// Substitute() is significantly faster than StringPrintf(). For very +// large strings, it may be orders of magnitude faster. +// ---------------------------------------------------------------------- + +namespace internal { // Implementation details. + +class SubstituteArg { + public: + inline SubstituteArg(const char* value) + : text_(value), size_(strlen(text_)) {} + inline SubstituteArg(const string& value) + : text_(value.data()), size_(value.size()) {} + + // Indicates that no argument was given. + inline explicit SubstituteArg() + : text_(NULL), size_(-1) {} + + // Primitives + // We don't overload for signed and unsigned char because if people are + // explicitly declaring their chars as signed or unsigned then they are + // probably actually using them as 8-bit integers and would probably + // prefer an integer representation. But, we don't really know. So, we + // make the caller decide what to do. + inline SubstituteArg(char value) + : text_(scratch_), size_(1) { scratch_[0] = value; } + inline SubstituteArg(short value) + : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(unsigned short value) + : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(int value) + : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(unsigned int value) + : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(long value) + : text_(FastLongToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(unsigned long value) + : text_(FastULongToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(long long value) + : text_(FastInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(unsigned long long value) + : text_(FastUInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(float value) + : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(double value) + : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(bool value) + : text_(value ? "true" : "false"), size_(strlen(text_)) {} + + inline const char* data() const { return text_; } + inline int size() const { return size_; } + + private: + const char* text_; + int size_; + char scratch_[kFastToBufferSize]; +}; + +} // namespace internal + +LIBPROTOBUF_EXPORT string Substitute( + const char* format, + const internal::SubstituteArg& arg0 = internal::SubstituteArg(), + const internal::SubstituteArg& arg1 = internal::SubstituteArg(), + const internal::SubstituteArg& arg2 = internal::SubstituteArg(), + const internal::SubstituteArg& arg3 = internal::SubstituteArg(), + const internal::SubstituteArg& arg4 = internal::SubstituteArg(), + const internal::SubstituteArg& arg5 = internal::SubstituteArg(), + const internal::SubstituteArg& arg6 = internal::SubstituteArg(), + const internal::SubstituteArg& arg7 = internal::SubstituteArg(), + const internal::SubstituteArg& arg8 = internal::SubstituteArg(), + const internal::SubstituteArg& arg9 = internal::SubstituteArg()); + +LIBPROTOBUF_EXPORT void SubstituteAndAppend( + string* output, const char* format, + const internal::SubstituteArg& arg0 = internal::SubstituteArg(), + const internal::SubstituteArg& arg1 = internal::SubstituteArg(), + const internal::SubstituteArg& arg2 = internal::SubstituteArg(), + const internal::SubstituteArg& arg3 = internal::SubstituteArg(), + const internal::SubstituteArg& arg4 = internal::SubstituteArg(), + const internal::SubstituteArg& arg5 = internal::SubstituteArg(), + const internal::SubstituteArg& arg6 = internal::SubstituteArg(), + const internal::SubstituteArg& arg7 = internal::SubstituteArg(), + const internal::SubstituteArg& arg8 = internal::SubstituteArg(), + const internal::SubstituteArg& arg9 = internal::SubstituteArg()); + +} // namespace strings +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/template_util.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/template_util.h new file mode 100644 index 0000000..4f30ffa --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/template_util.h @@ -0,0 +1,138 @@ +// Copyright 2005 Google Inc. +// All rights reserved. +// +// 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. + +// ---- +// Author: lar@google.com (Laramie Leavitt) +// +// Template metaprogramming utility functions. +// +// This code is compiled directly on many platforms, including client +// platforms like Windows, Mac, and embedded systems. Before making +// any changes here, make sure that you're not breaking any platforms. +// +// +// The names choosen here reflect those used in tr1 and the boost::mpl +// library, there are similar operations used in the Loki library as +// well. I prefer the boost names for 2 reasons: +// 1. I think that portions of the Boost libraries are more likely to +// be included in the c++ standard. +// 2. It is not impossible that some of the boost libraries will be +// included in our own build in the future. +// Both of these outcomes means that we may be able to directly replace +// some of these with boost equivalents. +// +#ifndef GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ +#define GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ + +namespace google { +namespace protobuf { +namespace internal { + +// Types small_ and big_ are guaranteed such that sizeof(small_) < +// sizeof(big_) +typedef char small_; + +struct big_ { + char dummy[2]; +}; + +// Identity metafunction. +template +struct identity_ { + typedef T type; +}; + +// integral_constant, defined in tr1, is a wrapper for an integer +// value. We don't really need this generality; we could get away +// with hardcoding the integer type to bool. We use the fully +// general integer_constant for compatibility with tr1. + +template +struct integral_constant { + static const T value = v; + typedef T value_type; + typedef integral_constant type; +}; + +template const T integral_constant::value; + + +// Abbreviations: true_type and false_type are structs that represent boolean +// true and false values. Also define the boost::mpl versions of those names, +// true_ and false_. +typedef integral_constant true_type; +typedef integral_constant false_type; +typedef true_type true_; +typedef false_type false_; + +// if_ is a templatized conditional statement. +// if_ is a compile time evaluation of cond. +// if_<>::type contains A if cond is true, B otherwise. +template +struct if_{ + typedef A type; +}; + +template +struct if_ { + typedef B type; +}; + + +// type_equals_ is a template type comparator, similar to Loki IsSameType. +// type_equals_::value is true iff "A" is the same type as "B". +// +// New code should prefer base::is_same, defined in base/type_traits.h. +// It is functionally identical, but is_same is the standard spelling. +template +struct type_equals_ : public false_ { +}; + +template +struct type_equals_ : public true_ { +}; + +// and_ is a template && operator. +// and_::value evaluates "A::value && B::value". +template +struct and_ : public integral_constant { +}; + +// or_ is a template || operator. +// or_::value evaluates "A::value || B::value". +template +struct or_ : public integral_constant { +}; + + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/template_util_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/template_util_unittest.cc new file mode 100644 index 0000000..b1745e2 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/template_util_unittest.cc @@ -0,0 +1,130 @@ +// Copyright 2005 Google Inc. +// All rights reserved. +// +// 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. + +// ---- +// Author: lar@google.com (Laramie Leavitt) +// +// These tests are really compile time tests. +// If you try to step through this in a debugger +// you will not see any evaluations, merely that +// value is assigned true or false sequentially. + +#include + +#include +#include + +namespace GOOGLE_NAMESPACE = google::protobuf::internal; + +namespace google { +namespace protobuf { +namespace internal { +namespace { + +TEST(TemplateUtilTest, TestSize) { + EXPECT_GT(sizeof(GOOGLE_NAMESPACE::big_), sizeof(GOOGLE_NAMESPACE::small_)); +} + +TEST(TemplateUtilTest, TestIntegralConstants) { + // test the built-in types. + EXPECT_TRUE(true_type::value); + EXPECT_FALSE(false_type::value); + + typedef integral_constant one_type; + EXPECT_EQ(1, one_type::value); +} + +TEST(TemplateUtilTest, TestTemplateIf) { + typedef if_::type if_true; + EXPECT_TRUE(if_true::value); + + typedef if_::type if_false; + EXPECT_FALSE(if_false::value); +} + +TEST(TemplateUtilTest, TestTemplateTypeEquals) { + // Check that the TemplateTypeEquals works correctly. + bool value = false; + + // Test the same type is true. + value = type_equals_::value; + EXPECT_TRUE(value); + + // Test different types are false. + value = type_equals_::value; + EXPECT_FALSE(value); + + // Test type aliasing. + typedef const int foo; + value = type_equals_::value; + EXPECT_TRUE(value); +} + +TEST(TemplateUtilTest, TestTemplateAndOr) { + // Check that the TemplateTypeEquals works correctly. + bool value = false; + + // Yes && Yes == true. + value = and_::value; + EXPECT_TRUE(value); + // Yes && No == false. + value = and_::value; + EXPECT_FALSE(value); + // No && Yes == false. + value = and_::value; + EXPECT_FALSE(value); + // No && No == false. + value = and_::value; + EXPECT_FALSE(value); + + // Yes || Yes == true. + value = or_::value; + EXPECT_TRUE(value); + // Yes || No == true. + value = or_::value; + EXPECT_TRUE(value); + // No || Yes == true. + value = or_::value; + EXPECT_TRUE(value); + // No || No == false. + value = or_::value; + EXPECT_FALSE(value); +} + +TEST(TemplateUtilTest, TestIdentity) { + EXPECT_TRUE( + (type_equals_::type, int>::value)); + EXPECT_TRUE( + (type_equals_::type, void>::value)); +} + +} // anonymous namespace +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/type_traits.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/type_traits.h new file mode 100644 index 0000000..e41f5e6 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/type_traits.h @@ -0,0 +1,336 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// 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. + +// ---- +// Author: Matt Austern +// +// This code is compiled directly on many platforms, including client +// platforms like Windows, Mac, and embedded systems. Before making +// any changes here, make sure that you're not breaking any platforms. +// +// Define a small subset of tr1 type traits. The traits we define are: +// is_integral +// is_floating_point +// is_pointer +// is_enum +// is_reference +// is_pod +// has_trivial_constructor +// has_trivial_copy +// has_trivial_assign +// has_trivial_destructor +// remove_const +// remove_volatile +// remove_cv +// remove_reference +// add_reference +// remove_pointer +// is_same +// is_convertible +// We can add more type traits as required. + +#ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_ +#define GOOGLE_PROTOBUF_TYPE_TRAITS_H_ + +#include // For pair + +#include // For true_type and false_type + +namespace google { +namespace protobuf { +namespace internal { + +template struct is_integral; +template struct is_floating_point; +template struct is_pointer; +// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least) +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +// is_enum uses is_convertible, which is not available on MSVC. +template struct is_enum; +#endif +template struct is_reference; +template struct is_pod; +template struct has_trivial_constructor; +template struct has_trivial_copy; +template struct has_trivial_assign; +template struct has_trivial_destructor; +template struct remove_const; +template struct remove_volatile; +template struct remove_cv; +template struct remove_reference; +template struct add_reference; +template struct remove_pointer; +template struct is_same; +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +template struct is_convertible; +#endif + +// is_integral is false except for the built-in integer types. A +// cv-qualified type is integral if and only if the underlying type is. +template struct is_integral : false_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +#if defined(_MSC_VER) +// wchar_t is not by default a distinct type from unsigned short in +// Microsoft C. +// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx +template<> struct is_integral<__wchar_t> : true_type { }; +#else +template<> struct is_integral : true_type { }; +#endif +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +#ifdef HAVE_LONG_LONG +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +#endif +template struct is_integral : is_integral { }; +template struct is_integral : is_integral { }; +template struct is_integral : is_integral { }; + +// is_floating_point is false except for the built-in floating-point types. +// A cv-qualified type is integral if and only if the underlying type is. +template struct is_floating_point : false_type { }; +template<> struct is_floating_point : true_type { }; +template<> struct is_floating_point : true_type { }; +template<> struct is_floating_point : true_type { }; +template struct is_floating_point + : is_floating_point { }; +template struct is_floating_point + : is_floating_point { }; +template struct is_floating_point + : is_floating_point { }; + +// is_pointer is false except for pointer types. A cv-qualified type (e.g. +// "int* const", as opposed to "int const*") is cv-qualified if and only if +// the underlying type is. +template struct is_pointer : false_type { }; +template struct is_pointer : true_type { }; +template struct is_pointer : is_pointer { }; +template struct is_pointer : is_pointer { }; +template struct is_pointer : is_pointer { }; + +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) + +namespace internal { + +template struct is_class_or_union { + template static small_ tester(void (U::*)()); + template static big_ tester(...); + static const bool value = sizeof(tester(0)) == sizeof(small_); +}; + +// is_convertible chokes if the first argument is an array. That's why +// we use add_reference here. +template struct is_enum_impl + : is_convertible::type, int> { }; + +template struct is_enum_impl : false_type { }; + +} // namespace internal + +// Specified by TR1 [4.5.1] primary type categories. + +// Implementation note: +// +// Each type is either void, integral, floating point, array, pointer, +// reference, member object pointer, member function pointer, enum, +// union or class. Out of these, only integral, floating point, reference, +// class and enum types are potentially convertible to int. Therefore, +// if a type is not a reference, integral, floating point or class and +// is convertible to int, it's a enum. Adding cv-qualification to a type +// does not change whether it's an enum. +// +// Is-convertible-to-int check is done only if all other checks pass, +// because it can't be used with some types (e.g. void or classes with +// inaccessible conversion operators). +template struct is_enum + : internal::is_enum_impl< + is_same::value || + is_integral::value || + is_floating_point::value || + is_reference::value || + internal::is_class_or_union::value, + T> { }; + +template struct is_enum : is_enum { }; +template struct is_enum : is_enum { }; +template struct is_enum : is_enum { }; + +#endif + +// is_reference is false except for reference types. +template struct is_reference : false_type {}; +template struct is_reference : true_type {}; + + +// We can't get is_pod right without compiler help, so fail conservatively. +// We will assume it's false except for arithmetic types, enumerations, +// pointers and cv-qualified versions thereof. Note that std::pair +// is not a POD even if T and U are PODs. +template struct is_pod + : integral_constant::value || + is_floating_point::value || +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) + // is_enum is not available on MSVC. + is_enum::value || +#endif + is_pointer::value)> { }; +template struct is_pod : is_pod { }; +template struct is_pod : is_pod { }; +template struct is_pod : is_pod { }; + + +// We can't get has_trivial_constructor right without compiler help, so +// fail conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial +// constructors. (3) array of a type with a trivial constructor. +// (4) const versions thereof. +template struct has_trivial_constructor : is_pod { }; +template struct has_trivial_constructor > + : integral_constant::value && + has_trivial_constructor::value)> { }; +template struct has_trivial_constructor + : has_trivial_constructor { }; +template struct has_trivial_constructor + : has_trivial_constructor { }; + +// We can't get has_trivial_copy right without compiler help, so fail +// conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial copy +// constructors. (3) array of a type with a trivial copy constructor. +// (4) const versions thereof. +template struct has_trivial_copy : is_pod { }; +template struct has_trivial_copy > + : integral_constant::value && + has_trivial_copy::value)> { }; +template struct has_trivial_copy + : has_trivial_copy { }; +template struct has_trivial_copy : has_trivial_copy { }; + +// We can't get has_trivial_assign right without compiler help, so fail +// conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial copy +// constructors. (3) array of a type with a trivial assign constructor. +template struct has_trivial_assign : is_pod { }; +template struct has_trivial_assign > + : integral_constant::value && + has_trivial_assign::value)> { }; +template struct has_trivial_assign + : has_trivial_assign { }; + +// We can't get has_trivial_destructor right without compiler help, so +// fail conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial +// destructors. (3) array of a type with a trivial destructor. +// (4) const versions thereof. +template struct has_trivial_destructor : is_pod { }; +template struct has_trivial_destructor > + : integral_constant::value && + has_trivial_destructor::value)> { }; +template struct has_trivial_destructor + : has_trivial_destructor { }; +template struct has_trivial_destructor + : has_trivial_destructor { }; + +// Specified by TR1 [4.7.1] +template struct remove_const { typedef T type; }; +template struct remove_const { typedef T type; }; +template struct remove_volatile { typedef T type; }; +template struct remove_volatile { typedef T type; }; +template struct remove_cv { + typedef typename remove_const::type>::type type; +}; + + +// Specified by TR1 [4.7.2] Reference modifications. +template struct remove_reference { typedef T type; }; +template struct remove_reference { typedef T type; }; + +template struct add_reference { typedef T& type; }; +template struct add_reference { typedef T& type; }; + +// Specified by TR1 [4.7.4] Pointer modifications. +template struct remove_pointer { typedef T type; }; +template struct remove_pointer { typedef T type; }; +template struct remove_pointer { typedef T type; }; +template struct remove_pointer { typedef T type; }; +template struct remove_pointer { + typedef T type; }; + +// Specified by TR1 [4.6] Relationships between types +template struct is_same : public false_type { }; +template struct is_same : public true_type { }; + +// Specified by TR1 [4.6] Relationships between types +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +namespace internal { + +// This class is an implementation detail for is_convertible, and you +// don't need to know how it works to use is_convertible. For those +// who care: we declare two different functions, one whose argument is +// of type To and one with a variadic argument list. We give them +// return types of different size, so we can use sizeof to trick the +// compiler into telling us which function it would have chosen if we +// had called it with an argument of type From. See Alexandrescu's +// _Modern C++ Design_ for more details on this sort of trick. + +template +struct ConvertHelper { + static small_ Test(To); + static big_ Test(...); + static From Create(); +}; +} // namespace internal + +// Inherits from true_type if From is convertible to To, false_type otherwise. +template +struct is_convertible + : integral_constant::Test( + internal::ConvertHelper::Create())) + == sizeof(small_)> { +}; +#endif + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_TYPE_TRAITS_H_ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/type_traits_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/type_traits_unittest.cc new file mode 100644 index 0000000..7a8cbfb --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/stubs/type_traits_unittest.cc @@ -0,0 +1,628 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// 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. + +// ---- +// Author: Matt Austern + +#include + +#include // for exit() +#include +#include +#include + +#include +#include + +typedef int int32; +typedef long int64; + +using std::string; +using std::vector; +using std::pair; + + +// This assertion produces errors like "error: invalid use of +// incomplete type 'struct ::AssertTypesEq'" +// when it fails. +template struct AssertTypesEq; +template struct AssertTypesEq {}; +#define COMPILE_ASSERT_TYPES_EQ(T, U) static_cast(AssertTypesEq()) + +// A user-defined POD type. +struct A { + int n_; +}; + +// A user-defined non-POD type with a trivial copy constructor. +class B { + public: + explicit B(int n) : n_(n) { } + private: + int n_; +}; + +// Another user-defined non-POD type with a trivial copy constructor. +// We will explicitly declare C to have a trivial copy constructor +// by specializing has_trivial_copy. +class C { + public: + explicit C(int n) : n_(n) { } + private: + int n_; +}; + +namespace google { +namespace protobuf { +namespace internal { +template<> struct has_trivial_copy : true_type { }; +} // namespace internal +} // namespace protobuf +} // namespace google + +// Another user-defined non-POD type with a trivial assignment operator. +// We will explicitly declare C to have a trivial assignment operator +// by specializing has_trivial_assign. +class D { + public: + explicit D(int n) : n_(n) { } + private: + int n_; +}; + +namespace google { +namespace protobuf { +namespace internal { +template<> struct has_trivial_assign : true_type { }; +} // namespace internal +} // namespace protobuf +} // namespace google + +// Another user-defined non-POD type with a trivial constructor. +// We will explicitly declare E to have a trivial constructor +// by specializing has_trivial_constructor. +class E { + public: + int n_; +}; + +namespace google { +namespace protobuf { +namespace internal { +template<> struct has_trivial_constructor : true_type { }; +} // namespace internal +} // namespace protobuf +} // namespace google + +// Another user-defined non-POD type with a trivial destructor. +// We will explicitly declare E to have a trivial destructor +// by specializing has_trivial_destructor. +class F { + public: + explicit F(int n) : n_(n) { } + private: + int n_; +}; + +namespace google { +namespace protobuf { +namespace internal { +template<> struct has_trivial_destructor : true_type { }; +} // namespace internal +} // namespace protobuf +} // namespace google + +enum G {}; + +union H {}; + +class I { + public: + operator int() const; +}; + +class J { + private: + operator int() const; +}; + +namespace google { +namespace protobuf { +namespace internal { +namespace { + +// A base class and a derived class that inherits from it, used for +// testing conversion type traits. +class Base { + public: + virtual ~Base() { } +}; + +class Derived : public Base { +}; + +TEST(TypeTraitsTest, TestIsInteger) { + // Verify that is_integral is true for all integer types. + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + + // Verify that is_integral is false for a few non-integer types. + EXPECT_FALSE(is_integral::value); + EXPECT_FALSE(is_integral::value); + EXPECT_FALSE(is_integral::value); + EXPECT_FALSE(is_integral::value); + EXPECT_FALSE(is_integral::value); + EXPECT_FALSE((is_integral >::value)); + + // Verify that cv-qualified integral types are still integral, and + // cv-qualified non-integral types are still non-integral. + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + EXPECT_TRUE(is_integral::value); + EXPECT_FALSE(is_integral::value); + EXPECT_FALSE(is_integral::value); + EXPECT_FALSE(is_integral::value); +} + +TEST(TypeTraitsTest, TestIsFloating) { + // Verify that is_floating_point is true for all floating-point types. + EXPECT_TRUE(is_floating_point::value); + EXPECT_TRUE(is_floating_point::value); + EXPECT_TRUE(is_floating_point::value); + + // Verify that is_floating_point is false for a few non-float types. + EXPECT_FALSE(is_floating_point::value); + EXPECT_FALSE(is_floating_point::value); + EXPECT_FALSE(is_floating_point::value); + EXPECT_FALSE(is_floating_point::value); + EXPECT_FALSE(is_floating_point::value); + EXPECT_FALSE((is_floating_point >::value)); + + // Verify that cv-qualified floating point types are still floating, and + // cv-qualified non-floating types are still non-floating. + EXPECT_TRUE(is_floating_point::value); + EXPECT_TRUE(is_floating_point::value); + EXPECT_TRUE(is_floating_point::value); + EXPECT_FALSE(is_floating_point::value); + EXPECT_FALSE(is_floating_point::value); + EXPECT_FALSE(is_floating_point::value); +} + +TEST(TypeTraitsTest, TestIsPointer) { + // Verify that is_pointer is true for some pointer types. + EXPECT_TRUE(is_pointer::value); + EXPECT_TRUE(is_pointer::value); + EXPECT_TRUE(is_pointer::value); + EXPECT_TRUE(is_pointer::value); + EXPECT_TRUE(is_pointer::value); + + // Verify that is_pointer is false for some non-pointer types. + EXPECT_FALSE(is_pointer::value); + EXPECT_FALSE(is_pointer::value); + EXPECT_FALSE(is_pointer::value); + EXPECT_FALSE(is_pointer >::value); + EXPECT_FALSE(is_pointer::value); + + // A function pointer is a pointer, but a function type, or a function + // reference type, is not. + EXPECT_TRUE(is_pointer::value); + EXPECT_FALSE(is_pointer::value); + EXPECT_FALSE(is_pointer::value); + + // Verify that is_pointer is true for some cv-qualified pointer types, + // and false for some cv-qualified non-pointer types. + EXPECT_TRUE(is_pointer::value); + EXPECT_TRUE(is_pointer::value); + EXPECT_TRUE(is_pointer::value); + EXPECT_FALSE(is_pointer::value); + EXPECT_FALSE(is_pointer >::value); + EXPECT_FALSE(is_pointer::value); +} + +TEST(TypeTraitsTest, TestIsEnum) { +// is_enum isn't supported on MSVC or gcc 3.x +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) + // Verify that is_enum is true for enum types. + EXPECT_TRUE(is_enum::value); + EXPECT_TRUE(is_enum::value); + EXPECT_TRUE(is_enum::value); + EXPECT_TRUE(is_enum::value); + + // Verify that is_enum is false for a few non-enum types. + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); + EXPECT_FALSE(is_enum::value); +#endif +} + +TEST(TypeTraitsTest, TestIsReference) { + // Verifies that is_reference is true for all reference types. + typedef float& RefFloat; + EXPECT_TRUE(is_reference::value); + EXPECT_TRUE(is_reference::value); + EXPECT_TRUE(is_reference::value); + EXPECT_TRUE(is_reference::value); + EXPECT_TRUE(is_reference::value); + EXPECT_TRUE(is_reference::value); + EXPECT_TRUE(is_reference::value); + EXPECT_TRUE(is_reference::value); + + + // Verifies that is_reference is false for all non-reference types. + EXPECT_FALSE(is_reference::value); + EXPECT_FALSE(is_reference::value); + EXPECT_FALSE(is_reference::value); + EXPECT_FALSE(is_reference::value); + EXPECT_FALSE(is_reference::value); + EXPECT_FALSE(is_reference::value); + EXPECT_FALSE(is_reference::value); +} + +TEST(TypeTraitsTest, TestAddReference) { + COMPILE_ASSERT_TYPES_EQ(int&, add_reference::type); + COMPILE_ASSERT_TYPES_EQ(const int&, add_reference::type); + COMPILE_ASSERT_TYPES_EQ(volatile int&, + add_reference::type); + COMPILE_ASSERT_TYPES_EQ(const volatile int&, + add_reference::type); + COMPILE_ASSERT_TYPES_EQ(int&, add_reference::type); + COMPILE_ASSERT_TYPES_EQ(const int&, add_reference::type); + COMPILE_ASSERT_TYPES_EQ(volatile int&, + add_reference::type); + COMPILE_ASSERT_TYPES_EQ(const volatile int&, + add_reference::type); +} + +TEST(TypeTraitsTest, TestIsPod) { + // Verify that arithmetic types and pointers are marked as PODs. + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); + EXPECT_TRUE(is_pod::value); +#endif + + // Verify that some non-POD types are not marked as PODs. + EXPECT_FALSE(is_pod::value); + EXPECT_FALSE(is_pod::value); + EXPECT_FALSE((is_pod >::value)); + EXPECT_FALSE(is_pod::value); + EXPECT_FALSE(is_pod::value); + EXPECT_FALSE(is_pod::value); + EXPECT_FALSE(is_pod::value); + EXPECT_FALSE(is_pod::value); + EXPECT_FALSE(is_pod::value); +} + +TEST(TypeTraitsTest, TestHasTrivialConstructor) { + // Verify that arithmetic types and pointers have trivial constructors. + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + EXPECT_TRUE(has_trivial_constructor::value); + + // Verify that pairs and arrays of such types have trivial + // constructors. + typedef int int10[10]; + EXPECT_TRUE((has_trivial_constructor >::value)); + EXPECT_TRUE(has_trivial_constructor::value); + + // Verify that pairs of types without trivial constructors + // are not marked as trivial. + EXPECT_FALSE((has_trivial_constructor >::value)); + EXPECT_FALSE((has_trivial_constructor >::value)); + + // Verify that types without trivial constructors are + // correctly marked as such. + EXPECT_FALSE(has_trivial_constructor::value); + EXPECT_FALSE(has_trivial_constructor >::value); + + // Verify that E, which we have declared to have a trivial + // constructor, is correctly marked as such. + EXPECT_TRUE(has_trivial_constructor::value); +} + +TEST(TypeTraitsTest, TestHasTrivialCopy) { + // Verify that arithmetic types and pointers have trivial copy + // constructors. + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + EXPECT_TRUE(has_trivial_copy::value); + + // Verify that pairs and arrays of such types have trivial + // copy constructors. + typedef int int10[10]; + EXPECT_TRUE((has_trivial_copy >::value)); + EXPECT_TRUE(has_trivial_copy::value); + + // Verify that pairs of types without trivial copy constructors + // are not marked as trivial. + EXPECT_FALSE((has_trivial_copy >::value)); + EXPECT_FALSE((has_trivial_copy >::value)); + + // Verify that types without trivial copy constructors are + // correctly marked as such. + EXPECT_FALSE(has_trivial_copy::value); + EXPECT_FALSE(has_trivial_copy >::value); + + // Verify that C, which we have declared to have a trivial + // copy constructor, is correctly marked as such. + EXPECT_TRUE(has_trivial_copy::value); +} + +TEST(TypeTraitsTest, TestHasTrivialAssign) { + // Verify that arithmetic types and pointers have trivial assignment + // operators. + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + EXPECT_TRUE(has_trivial_assign::value); + + // Verify that pairs and arrays of such types have trivial + // assignment operators. + typedef int int10[10]; + EXPECT_TRUE((has_trivial_assign >::value)); + EXPECT_TRUE(has_trivial_assign::value); + + // Verify that pairs of types without trivial assignment operators + // are not marked as trivial. + EXPECT_FALSE((has_trivial_assign >::value)); + EXPECT_FALSE((has_trivial_assign >::value)); + + // Verify that types without trivial assignment operators are + // correctly marked as such. + EXPECT_FALSE(has_trivial_assign::value); + EXPECT_FALSE(has_trivial_assign >::value); + + // Verify that D, which we have declared to have a trivial + // assignment operator, is correctly marked as such. + EXPECT_TRUE(has_trivial_assign::value); +} + +TEST(TypeTraitsTest, TestHasTrivialDestructor) { + // Verify that arithmetic types and pointers have trivial destructors. + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + EXPECT_TRUE(has_trivial_destructor::value); + + // Verify that pairs and arrays of such types have trivial + // destructors. + typedef int int10[10]; + EXPECT_TRUE((has_trivial_destructor >::value)); + EXPECT_TRUE(has_trivial_destructor::value); + + // Verify that pairs of types without trivial destructors + // are not marked as trivial. + EXPECT_FALSE((has_trivial_destructor >::value)); + EXPECT_FALSE((has_trivial_destructor >::value)); + + // Verify that types without trivial destructors are + // correctly marked as such. + EXPECT_FALSE(has_trivial_destructor::value); + EXPECT_FALSE(has_trivial_destructor >::value); + + // Verify that F, which we have declared to have a trivial + // destructor, is correctly marked as such. + EXPECT_TRUE(has_trivial_destructor::value); +} + +// Tests remove_pointer. +TEST(TypeTraitsTest, TestRemovePointer) { + COMPILE_ASSERT_TYPES_EQ(int, remove_pointer::type); + COMPILE_ASSERT_TYPES_EQ(int, remove_pointer::type); + COMPILE_ASSERT_TYPES_EQ(const int, remove_pointer::type); + COMPILE_ASSERT_TYPES_EQ(int, remove_pointer::type); + COMPILE_ASSERT_TYPES_EQ(int, remove_pointer::type); +} + +TEST(TypeTraitsTest, TestRemoveConst) { + COMPILE_ASSERT_TYPES_EQ(int, remove_const::type); + COMPILE_ASSERT_TYPES_EQ(int, remove_const::type); + COMPILE_ASSERT_TYPES_EQ(int *, remove_const::type); + // TR1 examples. + COMPILE_ASSERT_TYPES_EQ(const int *, remove_const::type); + COMPILE_ASSERT_TYPES_EQ(volatile int, + remove_const::type); +} + +TEST(TypeTraitsTest, TestRemoveVolatile) { + COMPILE_ASSERT_TYPES_EQ(int, remove_volatile::type); + COMPILE_ASSERT_TYPES_EQ(int, remove_volatile::type); + COMPILE_ASSERT_TYPES_EQ(int *, remove_volatile::type); + // TR1 examples. + COMPILE_ASSERT_TYPES_EQ(volatile int *, + remove_volatile::type); + COMPILE_ASSERT_TYPES_EQ(const int, + remove_volatile::type); +} + +TEST(TypeTraitsTest, TestRemoveCV) { + COMPILE_ASSERT_TYPES_EQ(int, remove_cv::type); + COMPILE_ASSERT_TYPES_EQ(int, remove_cv::type); + COMPILE_ASSERT_TYPES_EQ(int, remove_cv::type); + COMPILE_ASSERT_TYPES_EQ(int *, remove_cv::type); + // TR1 examples. + COMPILE_ASSERT_TYPES_EQ(const volatile int *, + remove_cv::type); + COMPILE_ASSERT_TYPES_EQ(int, + remove_cv::type); +} + +TEST(TypeTraitsTest, TestRemoveReference) { + COMPILE_ASSERT_TYPES_EQ(int, remove_reference::type); + COMPILE_ASSERT_TYPES_EQ(int, remove_reference::type); + COMPILE_ASSERT_TYPES_EQ(const int, remove_reference::type); + COMPILE_ASSERT_TYPES_EQ(int*, remove_reference::type); +} + +TEST(TypeTraitsTest, TestIsSame) { + EXPECT_TRUE((is_same::value)); + EXPECT_FALSE((is_same::value)); + EXPECT_FALSE((is_same::value)); + EXPECT_FALSE((is_same::value)); + + EXPECT_TRUE((is_same::value)); + EXPECT_FALSE((is_same::value)); + EXPECT_FALSE((is_same::value)); + + EXPECT_TRUE((is_same::value)); + EXPECT_TRUE((is_same::value)); + EXPECT_FALSE((is_same::value)); + EXPECT_FALSE((is_same::value)); + EXPECT_FALSE((is_same::value)); + EXPECT_FALSE((is_same::value)); + + EXPECT_TRUE((is_same::value)); + EXPECT_TRUE((is_same::value)); + EXPECT_FALSE((is_same::value)); + EXPECT_FALSE((is_same::value)); +} + +TEST(TypeTraitsTest, TestConvertible) { +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) + EXPECT_TRUE((is_convertible::value)); + EXPECT_TRUE((is_convertible::value)); + EXPECT_TRUE((is_convertible::value)); + + EXPECT_TRUE((is_convertible::value)); + EXPECT_FALSE((is_convertible::value)); + + EXPECT_TRUE((is_convertible::value)); + EXPECT_FALSE((is_convertible::value)); + EXPECT_TRUE((is_convertible::value)); + EXPECT_FALSE((is_convertible::value)); +#endif +} + +} // anonymous namespace +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util.cc new file mode 100644 index 0000000..a9666fe --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util.cc @@ -0,0 +1,3047 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifdef _WIN32 +// Verify that #including windows.h does not break anything (e.g. because +// windows.h #defines GetMessage() as a macro). +#include +#endif + +#include +#include +#include + +#include +#include +#include + +namespace google { +namespace protobuf { + +void TestUtil::SetAllFields(unittest::TestAllTypes* message) { + SetOptionalFields(message); + AddRepeatedFields1(message); + AddRepeatedFields2(message); + SetDefaultFields(message); +} + +void TestUtil::SetOptionalFields(unittest::TestAllTypes* message) { + message->set_optional_int32 (101); + message->set_optional_int64 (102); + message->set_optional_uint32 (103); + message->set_optional_uint64 (104); + message->set_optional_sint32 (105); + message->set_optional_sint64 (106); + message->set_optional_fixed32 (107); + message->set_optional_fixed64 (108); + message->set_optional_sfixed32(109); + message->set_optional_sfixed64(110); + message->set_optional_float (111); + message->set_optional_double (112); + message->set_optional_bool (true); + message->set_optional_string ("115"); + message->set_optional_bytes ("116"); + + message->mutable_optionalgroup ()->set_a(117); + message->mutable_optional_nested_message ()->set_bb(118); + message->mutable_optional_foreign_message ()->set_c(119); + message->mutable_optional_import_message ()->set_d(120); + message->mutable_optional_public_import_message()->set_e(126); + message->mutable_optional_lazy_message ()->set_bb(127); + + message->set_optional_nested_enum (unittest::TestAllTypes::BAZ); + message->set_optional_foreign_enum(unittest::FOREIGN_BAZ ); + message->set_optional_import_enum (unittest_import::IMPORT_BAZ); + + // StringPiece and Cord fields are only accessible via reflection in the + // open source release; see comments in compiler/cpp/string_field.cc. +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + message->GetReflection()->SetString( + message, + message->GetDescriptor()->FindFieldByName("optional_string_piece"), + "124"); + message->GetReflection()->SetString( + message, + message->GetDescriptor()->FindFieldByName("optional_cord"), + "125"); +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS +} + +// ------------------------------------------------------------------- + +void TestUtil::AddRepeatedFields1(unittest::TestAllTypes* message) { + message->add_repeated_int32 (201); + message->add_repeated_int64 (202); + message->add_repeated_uint32 (203); + message->add_repeated_uint64 (204); + message->add_repeated_sint32 (205); + message->add_repeated_sint64 (206); + message->add_repeated_fixed32 (207); + message->add_repeated_fixed64 (208); + message->add_repeated_sfixed32(209); + message->add_repeated_sfixed64(210); + message->add_repeated_float (211); + message->add_repeated_double (212); + message->add_repeated_bool (true); + message->add_repeated_string ("215"); + message->add_repeated_bytes ("216"); + + message->add_repeatedgroup ()->set_a(217); + message->add_repeated_nested_message ()->set_bb(218); + message->add_repeated_foreign_message()->set_c(219); + message->add_repeated_import_message ()->set_d(220); + message->add_repeated_lazy_message ()->set_bb(227); + + message->add_repeated_nested_enum (unittest::TestAllTypes::BAR); + message->add_repeated_foreign_enum(unittest::FOREIGN_BAR ); + message->add_repeated_import_enum (unittest_import::IMPORT_BAR); + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + message->GetReflection()->AddString( + message, + message->GetDescriptor()->FindFieldByName("repeated_string_piece"), + "224"); + message->GetReflection()->AddString( + message, + message->GetDescriptor()->FindFieldByName("repeated_cord"), + "225"); +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS +} + +void TestUtil::AddRepeatedFields2(unittest::TestAllTypes* message) { + // Add a second one of each field. + message->add_repeated_int32 (301); + message->add_repeated_int64 (302); + message->add_repeated_uint32 (303); + message->add_repeated_uint64 (304); + message->add_repeated_sint32 (305); + message->add_repeated_sint64 (306); + message->add_repeated_fixed32 (307); + message->add_repeated_fixed64 (308); + message->add_repeated_sfixed32(309); + message->add_repeated_sfixed64(310); + message->add_repeated_float (311); + message->add_repeated_double (312); + message->add_repeated_bool (false); + message->add_repeated_string ("315"); + message->add_repeated_bytes ("316"); + + message->add_repeatedgroup ()->set_a(317); + message->add_repeated_nested_message ()->set_bb(318); + message->add_repeated_foreign_message()->set_c(319); + message->add_repeated_import_message ()->set_d(320); + message->add_repeated_lazy_message ()->set_bb(327); + + message->add_repeated_nested_enum (unittest::TestAllTypes::BAZ); + message->add_repeated_foreign_enum(unittest::FOREIGN_BAZ ); + message->add_repeated_import_enum (unittest_import::IMPORT_BAZ); + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + message->GetReflection()->AddString( + message, + message->GetDescriptor()->FindFieldByName("repeated_string_piece"), + "324"); + message->GetReflection()->AddString( + message, + message->GetDescriptor()->FindFieldByName("repeated_cord"), + "325"); +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS +} + +// ------------------------------------------------------------------- + +void TestUtil::SetDefaultFields(unittest::TestAllTypes* message) { + message->set_default_int32 (401); + message->set_default_int64 (402); + message->set_default_uint32 (403); + message->set_default_uint64 (404); + message->set_default_sint32 (405); + message->set_default_sint64 (406); + message->set_default_fixed32 (407); + message->set_default_fixed64 (408); + message->set_default_sfixed32(409); + message->set_default_sfixed64(410); + message->set_default_float (411); + message->set_default_double (412); + message->set_default_bool (false); + message->set_default_string ("415"); + message->set_default_bytes ("416"); + + message->set_default_nested_enum (unittest::TestAllTypes::FOO); + message->set_default_foreign_enum(unittest::FOREIGN_FOO ); + message->set_default_import_enum (unittest_import::IMPORT_FOO); + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + message->GetReflection()->SetString( + message, + message->GetDescriptor()->FindFieldByName("default_string_piece"), + "424"); + message->GetReflection()->SetString( + message, + message->GetDescriptor()->FindFieldByName("default_cord"), + "425"); +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS +} + +// ------------------------------------------------------------------- + +void TestUtil::ModifyRepeatedFields(unittest::TestAllTypes* message) { + message->set_repeated_int32 (1, 501); + message->set_repeated_int64 (1, 502); + message->set_repeated_uint32 (1, 503); + message->set_repeated_uint64 (1, 504); + message->set_repeated_sint32 (1, 505); + message->set_repeated_sint64 (1, 506); + message->set_repeated_fixed32 (1, 507); + message->set_repeated_fixed64 (1, 508); + message->set_repeated_sfixed32(1, 509); + message->set_repeated_sfixed64(1, 510); + message->set_repeated_float (1, 511); + message->set_repeated_double (1, 512); + message->set_repeated_bool (1, true); + message->set_repeated_string (1, "515"); + message->set_repeated_bytes (1, "516"); + + message->mutable_repeatedgroup (1)->set_a(517); + message->mutable_repeated_nested_message (1)->set_bb(518); + message->mutable_repeated_foreign_message(1)->set_c(519); + message->mutable_repeated_import_message (1)->set_d(520); + message->mutable_repeated_lazy_message (1)->set_bb(527); + + message->set_repeated_nested_enum (1, unittest::TestAllTypes::FOO); + message->set_repeated_foreign_enum(1, unittest::FOREIGN_FOO ); + message->set_repeated_import_enum (1, unittest_import::IMPORT_FOO); + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + message->GetReflection()->SetRepeatedString( + message, + message->GetDescriptor()->FindFieldByName("repeated_string_piece"), + 1, "524"); + message->GetReflection()->SetRepeatedString( + message, + message->GetDescriptor()->FindFieldByName("repeated_cord"), + 1, "525"); +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) { + EXPECT_TRUE(message.has_optional_int32 ()); + EXPECT_TRUE(message.has_optional_int64 ()); + EXPECT_TRUE(message.has_optional_uint32 ()); + EXPECT_TRUE(message.has_optional_uint64 ()); + EXPECT_TRUE(message.has_optional_sint32 ()); + EXPECT_TRUE(message.has_optional_sint64 ()); + EXPECT_TRUE(message.has_optional_fixed32 ()); + EXPECT_TRUE(message.has_optional_fixed64 ()); + EXPECT_TRUE(message.has_optional_sfixed32()); + EXPECT_TRUE(message.has_optional_sfixed64()); + EXPECT_TRUE(message.has_optional_float ()); + EXPECT_TRUE(message.has_optional_double ()); + EXPECT_TRUE(message.has_optional_bool ()); + EXPECT_TRUE(message.has_optional_string ()); + EXPECT_TRUE(message.has_optional_bytes ()); + + EXPECT_TRUE(message.has_optionalgroup ()); + EXPECT_TRUE(message.has_optional_nested_message ()); + EXPECT_TRUE(message.has_optional_foreign_message ()); + EXPECT_TRUE(message.has_optional_import_message ()); + EXPECT_TRUE(message.has_optional_public_import_message()); + EXPECT_TRUE(message.has_optional_lazy_message ()); + + EXPECT_TRUE(message.optionalgroup ().has_a()); + EXPECT_TRUE(message.optional_nested_message ().has_bb()); + EXPECT_TRUE(message.optional_foreign_message ().has_c()); + EXPECT_TRUE(message.optional_import_message ().has_d()); + EXPECT_TRUE(message.optional_public_import_message().has_e()); + EXPECT_TRUE(message.optional_lazy_message ().has_bb()); + + EXPECT_TRUE(message.has_optional_nested_enum ()); + EXPECT_TRUE(message.has_optional_foreign_enum()); + EXPECT_TRUE(message.has_optional_import_enum ()); + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + EXPECT_TRUE(message.has_optional_string_piece()); + EXPECT_TRUE(message.has_optional_cord()); +#endif + + EXPECT_EQ(101 , message.optional_int32 ()); + EXPECT_EQ(102 , message.optional_int64 ()); + EXPECT_EQ(103 , message.optional_uint32 ()); + EXPECT_EQ(104 , message.optional_uint64 ()); + EXPECT_EQ(105 , message.optional_sint32 ()); + EXPECT_EQ(106 , message.optional_sint64 ()); + EXPECT_EQ(107 , message.optional_fixed32 ()); + EXPECT_EQ(108 , message.optional_fixed64 ()); + EXPECT_EQ(109 , message.optional_sfixed32()); + EXPECT_EQ(110 , message.optional_sfixed64()); + EXPECT_EQ(111 , message.optional_float ()); + EXPECT_EQ(112 , message.optional_double ()); + EXPECT_TRUE( message.optional_bool ()); + EXPECT_EQ("115", message.optional_string ()); + EXPECT_EQ("116", message.optional_bytes ()); + + EXPECT_EQ(117, message.optionalgroup ().a()); + EXPECT_EQ(118, message.optional_nested_message ().bb()); + EXPECT_EQ(119, message.optional_foreign_message ().c()); + EXPECT_EQ(120, message.optional_import_message ().d()); + EXPECT_EQ(126, message.optional_public_import_message ().e()); + EXPECT_EQ(127, message.optional_lazy_message ().bb()); + + EXPECT_EQ(unittest::TestAllTypes::BAZ, message.optional_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_BAZ , message.optional_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_BAZ, message.optional_import_enum ()); + + + // ----------------------------------------------------------------- + + ASSERT_EQ(2, message.repeated_int32_size ()); + ASSERT_EQ(2, message.repeated_int64_size ()); + ASSERT_EQ(2, message.repeated_uint32_size ()); + ASSERT_EQ(2, message.repeated_uint64_size ()); + ASSERT_EQ(2, message.repeated_sint32_size ()); + ASSERT_EQ(2, message.repeated_sint64_size ()); + ASSERT_EQ(2, message.repeated_fixed32_size ()); + ASSERT_EQ(2, message.repeated_fixed64_size ()); + ASSERT_EQ(2, message.repeated_sfixed32_size()); + ASSERT_EQ(2, message.repeated_sfixed64_size()); + ASSERT_EQ(2, message.repeated_float_size ()); + ASSERT_EQ(2, message.repeated_double_size ()); + ASSERT_EQ(2, message.repeated_bool_size ()); + ASSERT_EQ(2, message.repeated_string_size ()); + ASSERT_EQ(2, message.repeated_bytes_size ()); + + ASSERT_EQ(2, message.repeatedgroup_size ()); + ASSERT_EQ(2, message.repeated_nested_message_size ()); + ASSERT_EQ(2, message.repeated_foreign_message_size()); + ASSERT_EQ(2, message.repeated_import_message_size ()); + ASSERT_EQ(2, message.repeated_lazy_message_size ()); + ASSERT_EQ(2, message.repeated_nested_enum_size ()); + ASSERT_EQ(2, message.repeated_foreign_enum_size ()); + ASSERT_EQ(2, message.repeated_import_enum_size ()); + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + ASSERT_EQ(2, message.repeated_string_piece_size()); + ASSERT_EQ(2, message.repeated_cord_size()); +#endif + + EXPECT_EQ(201 , message.repeated_int32 (0)); + EXPECT_EQ(202 , message.repeated_int64 (0)); + EXPECT_EQ(203 , message.repeated_uint32 (0)); + EXPECT_EQ(204 , message.repeated_uint64 (0)); + EXPECT_EQ(205 , message.repeated_sint32 (0)); + EXPECT_EQ(206 , message.repeated_sint64 (0)); + EXPECT_EQ(207 , message.repeated_fixed32 (0)); + EXPECT_EQ(208 , message.repeated_fixed64 (0)); + EXPECT_EQ(209 , message.repeated_sfixed32(0)); + EXPECT_EQ(210 , message.repeated_sfixed64(0)); + EXPECT_EQ(211 , message.repeated_float (0)); + EXPECT_EQ(212 , message.repeated_double (0)); + EXPECT_TRUE( message.repeated_bool (0)); + EXPECT_EQ("215", message.repeated_string (0)); + EXPECT_EQ("216", message.repeated_bytes (0)); + + EXPECT_EQ(217, message.repeatedgroup (0).a()); + EXPECT_EQ(218, message.repeated_nested_message (0).bb()); + EXPECT_EQ(219, message.repeated_foreign_message(0).c()); + EXPECT_EQ(220, message.repeated_import_message (0).d()); + EXPECT_EQ(227, message.repeated_lazy_message (0).bb()); + + + EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0)); + EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0)); + EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0)); + + EXPECT_EQ(301 , message.repeated_int32 (1)); + EXPECT_EQ(302 , message.repeated_int64 (1)); + EXPECT_EQ(303 , message.repeated_uint32 (1)); + EXPECT_EQ(304 , message.repeated_uint64 (1)); + EXPECT_EQ(305 , message.repeated_sint32 (1)); + EXPECT_EQ(306 , message.repeated_sint64 (1)); + EXPECT_EQ(307 , message.repeated_fixed32 (1)); + EXPECT_EQ(308 , message.repeated_fixed64 (1)); + EXPECT_EQ(309 , message.repeated_sfixed32(1)); + EXPECT_EQ(310 , message.repeated_sfixed64(1)); + EXPECT_EQ(311 , message.repeated_float (1)); + EXPECT_EQ(312 , message.repeated_double (1)); + EXPECT_FALSE( message.repeated_bool (1)); + EXPECT_EQ("315", message.repeated_string (1)); + EXPECT_EQ("316", message.repeated_bytes (1)); + + EXPECT_EQ(317, message.repeatedgroup (1).a()); + EXPECT_EQ(318, message.repeated_nested_message (1).bb()); + EXPECT_EQ(319, message.repeated_foreign_message(1).c()); + EXPECT_EQ(320, message.repeated_import_message (1).d()); + EXPECT_EQ(327, message.repeated_lazy_message (1).bb()); + + EXPECT_EQ(unittest::TestAllTypes::BAZ, message.repeated_nested_enum (1)); + EXPECT_EQ(unittest::FOREIGN_BAZ , message.repeated_foreign_enum(1)); + EXPECT_EQ(unittest_import::IMPORT_BAZ, message.repeated_import_enum (1)); + + + // ----------------------------------------------------------------- + + EXPECT_TRUE(message.has_default_int32 ()); + EXPECT_TRUE(message.has_default_int64 ()); + EXPECT_TRUE(message.has_default_uint32 ()); + EXPECT_TRUE(message.has_default_uint64 ()); + EXPECT_TRUE(message.has_default_sint32 ()); + EXPECT_TRUE(message.has_default_sint64 ()); + EXPECT_TRUE(message.has_default_fixed32 ()); + EXPECT_TRUE(message.has_default_fixed64 ()); + EXPECT_TRUE(message.has_default_sfixed32()); + EXPECT_TRUE(message.has_default_sfixed64()); + EXPECT_TRUE(message.has_default_float ()); + EXPECT_TRUE(message.has_default_double ()); + EXPECT_TRUE(message.has_default_bool ()); + EXPECT_TRUE(message.has_default_string ()); + EXPECT_TRUE(message.has_default_bytes ()); + + EXPECT_TRUE(message.has_default_nested_enum ()); + EXPECT_TRUE(message.has_default_foreign_enum()); + EXPECT_TRUE(message.has_default_import_enum ()); + + + EXPECT_EQ(401 , message.default_int32 ()); + EXPECT_EQ(402 , message.default_int64 ()); + EXPECT_EQ(403 , message.default_uint32 ()); + EXPECT_EQ(404 , message.default_uint64 ()); + EXPECT_EQ(405 , message.default_sint32 ()); + EXPECT_EQ(406 , message.default_sint64 ()); + EXPECT_EQ(407 , message.default_fixed32 ()); + EXPECT_EQ(408 , message.default_fixed64 ()); + EXPECT_EQ(409 , message.default_sfixed32()); + EXPECT_EQ(410 , message.default_sfixed64()); + EXPECT_EQ(411 , message.default_float ()); + EXPECT_EQ(412 , message.default_double ()); + EXPECT_FALSE( message.default_bool ()); + EXPECT_EQ("415", message.default_string ()); + EXPECT_EQ("416", message.default_bytes ()); + + EXPECT_EQ(unittest::TestAllTypes::FOO, message.default_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_FOO , message.default_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_FOO, message.default_import_enum ()); + +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectClear(const unittest::TestAllTypes& message) { + // has_blah() should initially be false for all optional fields. + EXPECT_FALSE(message.has_optional_int32 ()); + EXPECT_FALSE(message.has_optional_int64 ()); + EXPECT_FALSE(message.has_optional_uint32 ()); + EXPECT_FALSE(message.has_optional_uint64 ()); + EXPECT_FALSE(message.has_optional_sint32 ()); + EXPECT_FALSE(message.has_optional_sint64 ()); + EXPECT_FALSE(message.has_optional_fixed32 ()); + EXPECT_FALSE(message.has_optional_fixed64 ()); + EXPECT_FALSE(message.has_optional_sfixed32()); + EXPECT_FALSE(message.has_optional_sfixed64()); + EXPECT_FALSE(message.has_optional_float ()); + EXPECT_FALSE(message.has_optional_double ()); + EXPECT_FALSE(message.has_optional_bool ()); + EXPECT_FALSE(message.has_optional_string ()); + EXPECT_FALSE(message.has_optional_bytes ()); + + EXPECT_FALSE(message.has_optionalgroup ()); + EXPECT_FALSE(message.has_optional_nested_message ()); + EXPECT_FALSE(message.has_optional_foreign_message ()); + EXPECT_FALSE(message.has_optional_import_message ()); + EXPECT_FALSE(message.has_optional_public_import_message()); + EXPECT_FALSE(message.has_optional_lazy_message ()); + + EXPECT_FALSE(message.has_optional_nested_enum ()); + EXPECT_FALSE(message.has_optional_foreign_enum()); + EXPECT_FALSE(message.has_optional_import_enum ()); + + EXPECT_FALSE(message.has_optional_string_piece()); + EXPECT_FALSE(message.has_optional_cord()); + + // Optional fields without defaults are set to zero or something like it. + EXPECT_EQ(0 , message.optional_int32 ()); + EXPECT_EQ(0 , message.optional_int64 ()); + EXPECT_EQ(0 , message.optional_uint32 ()); + EXPECT_EQ(0 , message.optional_uint64 ()); + EXPECT_EQ(0 , message.optional_sint32 ()); + EXPECT_EQ(0 , message.optional_sint64 ()); + EXPECT_EQ(0 , message.optional_fixed32 ()); + EXPECT_EQ(0 , message.optional_fixed64 ()); + EXPECT_EQ(0 , message.optional_sfixed32()); + EXPECT_EQ(0 , message.optional_sfixed64()); + EXPECT_EQ(0 , message.optional_float ()); + EXPECT_EQ(0 , message.optional_double ()); + EXPECT_FALSE( message.optional_bool ()); + EXPECT_EQ("" , message.optional_string ()); + EXPECT_EQ("" , message.optional_bytes ()); + + // Embedded messages should also be clear. + EXPECT_FALSE(message.optionalgroup ().has_a()); + EXPECT_FALSE(message.optional_nested_message ().has_bb()); + EXPECT_FALSE(message.optional_foreign_message ().has_c()); + EXPECT_FALSE(message.optional_import_message ().has_d()); + EXPECT_FALSE(message.optional_public_import_message().has_e()); + EXPECT_FALSE(message.optional_lazy_message ().has_bb()); + + EXPECT_EQ(0, message.optionalgroup ().a()); + EXPECT_EQ(0, message.optional_nested_message ().bb()); + EXPECT_EQ(0, message.optional_foreign_message ().c()); + EXPECT_EQ(0, message.optional_import_message ().d()); + EXPECT_EQ(0, message.optional_public_import_message().e()); + EXPECT_EQ(0, message.optional_lazy_message ().bb()); + + // Enums without defaults are set to the first value in the enum. + EXPECT_EQ(unittest::TestAllTypes::FOO, message.optional_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_FOO , message.optional_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_FOO, message.optional_import_enum ()); + + + // Repeated fields are empty. + EXPECT_EQ(0, message.repeated_int32_size ()); + EXPECT_EQ(0, message.repeated_int64_size ()); + EXPECT_EQ(0, message.repeated_uint32_size ()); + EXPECT_EQ(0, message.repeated_uint64_size ()); + EXPECT_EQ(0, message.repeated_sint32_size ()); + EXPECT_EQ(0, message.repeated_sint64_size ()); + EXPECT_EQ(0, message.repeated_fixed32_size ()); + EXPECT_EQ(0, message.repeated_fixed64_size ()); + EXPECT_EQ(0, message.repeated_sfixed32_size()); + EXPECT_EQ(0, message.repeated_sfixed64_size()); + EXPECT_EQ(0, message.repeated_float_size ()); + EXPECT_EQ(0, message.repeated_double_size ()); + EXPECT_EQ(0, message.repeated_bool_size ()); + EXPECT_EQ(0, message.repeated_string_size ()); + EXPECT_EQ(0, message.repeated_bytes_size ()); + + EXPECT_EQ(0, message.repeatedgroup_size ()); + EXPECT_EQ(0, message.repeated_nested_message_size ()); + EXPECT_EQ(0, message.repeated_foreign_message_size()); + EXPECT_EQ(0, message.repeated_import_message_size ()); + EXPECT_EQ(0, message.repeated_lazy_message_size ()); + EXPECT_EQ(0, message.repeated_nested_enum_size ()); + EXPECT_EQ(0, message.repeated_foreign_enum_size ()); + EXPECT_EQ(0, message.repeated_import_enum_size ()); + + EXPECT_EQ(0, message.repeated_string_piece_size()); + EXPECT_EQ(0, message.repeated_cord_size()); + + // has_blah() should also be false for all default fields. + EXPECT_FALSE(message.has_default_int32 ()); + EXPECT_FALSE(message.has_default_int64 ()); + EXPECT_FALSE(message.has_default_uint32 ()); + EXPECT_FALSE(message.has_default_uint64 ()); + EXPECT_FALSE(message.has_default_sint32 ()); + EXPECT_FALSE(message.has_default_sint64 ()); + EXPECT_FALSE(message.has_default_fixed32 ()); + EXPECT_FALSE(message.has_default_fixed64 ()); + EXPECT_FALSE(message.has_default_sfixed32()); + EXPECT_FALSE(message.has_default_sfixed64()); + EXPECT_FALSE(message.has_default_float ()); + EXPECT_FALSE(message.has_default_double ()); + EXPECT_FALSE(message.has_default_bool ()); + EXPECT_FALSE(message.has_default_string ()); + EXPECT_FALSE(message.has_default_bytes ()); + + EXPECT_FALSE(message.has_default_nested_enum ()); + EXPECT_FALSE(message.has_default_foreign_enum()); + EXPECT_FALSE(message.has_default_import_enum ()); + + + // Fields with defaults have their default values (duh). + EXPECT_EQ( 41 , message.default_int32 ()); + EXPECT_EQ( 42 , message.default_int64 ()); + EXPECT_EQ( 43 , message.default_uint32 ()); + EXPECT_EQ( 44 , message.default_uint64 ()); + EXPECT_EQ(-45 , message.default_sint32 ()); + EXPECT_EQ( 46 , message.default_sint64 ()); + EXPECT_EQ( 47 , message.default_fixed32 ()); + EXPECT_EQ( 48 , message.default_fixed64 ()); + EXPECT_EQ( 49 , message.default_sfixed32()); + EXPECT_EQ(-50 , message.default_sfixed64()); + EXPECT_EQ( 51.5 , message.default_float ()); + EXPECT_EQ( 52e3 , message.default_double ()); + EXPECT_TRUE( message.default_bool ()); + EXPECT_EQ("hello", message.default_string ()); + EXPECT_EQ("world", message.default_bytes ()); + + EXPECT_EQ(unittest::TestAllTypes::BAR, message.default_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_BAR , message.default_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_BAR, message.default_import_enum ()); + +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectRepeatedFieldsModified( + const unittest::TestAllTypes& message) { + // ModifyRepeatedFields only sets the second repeated element of each + // field. In addition to verifying this, we also verify that the first + // element and size were *not* modified. + ASSERT_EQ(2, message.repeated_int32_size ()); + ASSERT_EQ(2, message.repeated_int64_size ()); + ASSERT_EQ(2, message.repeated_uint32_size ()); + ASSERT_EQ(2, message.repeated_uint64_size ()); + ASSERT_EQ(2, message.repeated_sint32_size ()); + ASSERT_EQ(2, message.repeated_sint64_size ()); + ASSERT_EQ(2, message.repeated_fixed32_size ()); + ASSERT_EQ(2, message.repeated_fixed64_size ()); + ASSERT_EQ(2, message.repeated_sfixed32_size()); + ASSERT_EQ(2, message.repeated_sfixed64_size()); + ASSERT_EQ(2, message.repeated_float_size ()); + ASSERT_EQ(2, message.repeated_double_size ()); + ASSERT_EQ(2, message.repeated_bool_size ()); + ASSERT_EQ(2, message.repeated_string_size ()); + ASSERT_EQ(2, message.repeated_bytes_size ()); + + ASSERT_EQ(2, message.repeatedgroup_size ()); + ASSERT_EQ(2, message.repeated_nested_message_size ()); + ASSERT_EQ(2, message.repeated_foreign_message_size()); + ASSERT_EQ(2, message.repeated_import_message_size ()); + ASSERT_EQ(2, message.repeated_lazy_message_size ()); + ASSERT_EQ(2, message.repeated_nested_enum_size ()); + ASSERT_EQ(2, message.repeated_foreign_enum_size ()); + ASSERT_EQ(2, message.repeated_import_enum_size ()); + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + ASSERT_EQ(2, message.repeated_string_piece_size()); + ASSERT_EQ(2, message.repeated_cord_size()); +#endif + + EXPECT_EQ(201 , message.repeated_int32 (0)); + EXPECT_EQ(202 , message.repeated_int64 (0)); + EXPECT_EQ(203 , message.repeated_uint32 (0)); + EXPECT_EQ(204 , message.repeated_uint64 (0)); + EXPECT_EQ(205 , message.repeated_sint32 (0)); + EXPECT_EQ(206 , message.repeated_sint64 (0)); + EXPECT_EQ(207 , message.repeated_fixed32 (0)); + EXPECT_EQ(208 , message.repeated_fixed64 (0)); + EXPECT_EQ(209 , message.repeated_sfixed32(0)); + EXPECT_EQ(210 , message.repeated_sfixed64(0)); + EXPECT_EQ(211 , message.repeated_float (0)); + EXPECT_EQ(212 , message.repeated_double (0)); + EXPECT_TRUE( message.repeated_bool (0)); + EXPECT_EQ("215", message.repeated_string (0)); + EXPECT_EQ("216", message.repeated_bytes (0)); + + EXPECT_EQ(217, message.repeatedgroup (0).a()); + EXPECT_EQ(218, message.repeated_nested_message (0).bb()); + EXPECT_EQ(219, message.repeated_foreign_message(0).c()); + EXPECT_EQ(220, message.repeated_import_message (0).d()); + EXPECT_EQ(227, message.repeated_lazy_message (0).bb()); + + EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0)); + EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0)); + EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0)); + + + // Actually verify the second (modified) elements now. + EXPECT_EQ(501 , message.repeated_int32 (1)); + EXPECT_EQ(502 , message.repeated_int64 (1)); + EXPECT_EQ(503 , message.repeated_uint32 (1)); + EXPECT_EQ(504 , message.repeated_uint64 (1)); + EXPECT_EQ(505 , message.repeated_sint32 (1)); + EXPECT_EQ(506 , message.repeated_sint64 (1)); + EXPECT_EQ(507 , message.repeated_fixed32 (1)); + EXPECT_EQ(508 , message.repeated_fixed64 (1)); + EXPECT_EQ(509 , message.repeated_sfixed32(1)); + EXPECT_EQ(510 , message.repeated_sfixed64(1)); + EXPECT_EQ(511 , message.repeated_float (1)); + EXPECT_EQ(512 , message.repeated_double (1)); + EXPECT_TRUE( message.repeated_bool (1)); + EXPECT_EQ("515", message.repeated_string (1)); + EXPECT_EQ("516", message.repeated_bytes (1)); + + EXPECT_EQ(517, message.repeatedgroup (1).a()); + EXPECT_EQ(518, message.repeated_nested_message (1).bb()); + EXPECT_EQ(519, message.repeated_foreign_message(1).c()); + EXPECT_EQ(520, message.repeated_import_message (1).d()); + EXPECT_EQ(527, message.repeated_lazy_message (1).bb()); + + EXPECT_EQ(unittest::TestAllTypes::FOO, message.repeated_nested_enum (1)); + EXPECT_EQ(unittest::FOREIGN_FOO , message.repeated_foreign_enum(1)); + EXPECT_EQ(unittest_import::IMPORT_FOO, message.repeated_import_enum (1)); + +} + +// ------------------------------------------------------------------- + +void TestUtil::SetPackedFields(unittest::TestPackedTypes* message) { + message->add_packed_int32 (601); + message->add_packed_int64 (602); + message->add_packed_uint32 (603); + message->add_packed_uint64 (604); + message->add_packed_sint32 (605); + message->add_packed_sint64 (606); + message->add_packed_fixed32 (607); + message->add_packed_fixed64 (608); + message->add_packed_sfixed32(609); + message->add_packed_sfixed64(610); + message->add_packed_float (611); + message->add_packed_double (612); + message->add_packed_bool (true); + message->add_packed_enum (unittest::FOREIGN_BAR); + // add a second one of each field + message->add_packed_int32 (701); + message->add_packed_int64 (702); + message->add_packed_uint32 (703); + message->add_packed_uint64 (704); + message->add_packed_sint32 (705); + message->add_packed_sint64 (706); + message->add_packed_fixed32 (707); + message->add_packed_fixed64 (708); + message->add_packed_sfixed32(709); + message->add_packed_sfixed64(710); + message->add_packed_float (711); + message->add_packed_double (712); + message->add_packed_bool (false); + message->add_packed_enum (unittest::FOREIGN_BAZ); +} + +void TestUtil::SetUnpackedFields(unittest::TestUnpackedTypes* message) { + // The values applied here must match those of SetPackedFields. + + message->add_unpacked_int32 (601); + message->add_unpacked_int64 (602); + message->add_unpacked_uint32 (603); + message->add_unpacked_uint64 (604); + message->add_unpacked_sint32 (605); + message->add_unpacked_sint64 (606); + message->add_unpacked_fixed32 (607); + message->add_unpacked_fixed64 (608); + message->add_unpacked_sfixed32(609); + message->add_unpacked_sfixed64(610); + message->add_unpacked_float (611); + message->add_unpacked_double (612); + message->add_unpacked_bool (true); + message->add_unpacked_enum (unittest::FOREIGN_BAR); + // add a second one of each field + message->add_unpacked_int32 (701); + message->add_unpacked_int64 (702); + message->add_unpacked_uint32 (703); + message->add_unpacked_uint64 (704); + message->add_unpacked_sint32 (705); + message->add_unpacked_sint64 (706); + message->add_unpacked_fixed32 (707); + message->add_unpacked_fixed64 (708); + message->add_unpacked_sfixed32(709); + message->add_unpacked_sfixed64(710); + message->add_unpacked_float (711); + message->add_unpacked_double (712); + message->add_unpacked_bool (false); + message->add_unpacked_enum (unittest::FOREIGN_BAZ); +} + +// ------------------------------------------------------------------- + +void TestUtil::ModifyPackedFields(unittest::TestPackedTypes* message) { + message->set_packed_int32 (1, 801); + message->set_packed_int64 (1, 802); + message->set_packed_uint32 (1, 803); + message->set_packed_uint64 (1, 804); + message->set_packed_sint32 (1, 805); + message->set_packed_sint64 (1, 806); + message->set_packed_fixed32 (1, 807); + message->set_packed_fixed64 (1, 808); + message->set_packed_sfixed32(1, 809); + message->set_packed_sfixed64(1, 810); + message->set_packed_float (1, 811); + message->set_packed_double (1, 812); + message->set_packed_bool (1, true); + message->set_packed_enum (1, unittest::FOREIGN_FOO); +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectPackedFieldsSet(const unittest::TestPackedTypes& message) { + ASSERT_EQ(2, message.packed_int32_size ()); + ASSERT_EQ(2, message.packed_int64_size ()); + ASSERT_EQ(2, message.packed_uint32_size ()); + ASSERT_EQ(2, message.packed_uint64_size ()); + ASSERT_EQ(2, message.packed_sint32_size ()); + ASSERT_EQ(2, message.packed_sint64_size ()); + ASSERT_EQ(2, message.packed_fixed32_size ()); + ASSERT_EQ(2, message.packed_fixed64_size ()); + ASSERT_EQ(2, message.packed_sfixed32_size()); + ASSERT_EQ(2, message.packed_sfixed64_size()); + ASSERT_EQ(2, message.packed_float_size ()); + ASSERT_EQ(2, message.packed_double_size ()); + ASSERT_EQ(2, message.packed_bool_size ()); + ASSERT_EQ(2, message.packed_enum_size ()); + + EXPECT_EQ(601 , message.packed_int32 (0)); + EXPECT_EQ(602 , message.packed_int64 (0)); + EXPECT_EQ(603 , message.packed_uint32 (0)); + EXPECT_EQ(604 , message.packed_uint64 (0)); + EXPECT_EQ(605 , message.packed_sint32 (0)); + EXPECT_EQ(606 , message.packed_sint64 (0)); + EXPECT_EQ(607 , message.packed_fixed32 (0)); + EXPECT_EQ(608 , message.packed_fixed64 (0)); + EXPECT_EQ(609 , message.packed_sfixed32(0)); + EXPECT_EQ(610 , message.packed_sfixed64(0)); + EXPECT_EQ(611 , message.packed_float (0)); + EXPECT_EQ(612 , message.packed_double (0)); + EXPECT_TRUE( message.packed_bool (0)); + EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0)); + + EXPECT_EQ(701 , message.packed_int32 (1)); + EXPECT_EQ(702 , message.packed_int64 (1)); + EXPECT_EQ(703 , message.packed_uint32 (1)); + EXPECT_EQ(704 , message.packed_uint64 (1)); + EXPECT_EQ(705 , message.packed_sint32 (1)); + EXPECT_EQ(706 , message.packed_sint64 (1)); + EXPECT_EQ(707 , message.packed_fixed32 (1)); + EXPECT_EQ(708 , message.packed_fixed64 (1)); + EXPECT_EQ(709 , message.packed_sfixed32(1)); + EXPECT_EQ(710 , message.packed_sfixed64(1)); + EXPECT_EQ(711 , message.packed_float (1)); + EXPECT_EQ(712 , message.packed_double (1)); + EXPECT_FALSE( message.packed_bool (1)); + EXPECT_EQ(unittest::FOREIGN_BAZ, message.packed_enum(1)); +} + +void TestUtil::ExpectUnpackedFieldsSet( + const unittest::TestUnpackedTypes& message) { + // The values expected here must match those of ExpectPackedFieldsSet. + + ASSERT_EQ(2, message.unpacked_int32_size ()); + ASSERT_EQ(2, message.unpacked_int64_size ()); + ASSERT_EQ(2, message.unpacked_uint32_size ()); + ASSERT_EQ(2, message.unpacked_uint64_size ()); + ASSERT_EQ(2, message.unpacked_sint32_size ()); + ASSERT_EQ(2, message.unpacked_sint64_size ()); + ASSERT_EQ(2, message.unpacked_fixed32_size ()); + ASSERT_EQ(2, message.unpacked_fixed64_size ()); + ASSERT_EQ(2, message.unpacked_sfixed32_size()); + ASSERT_EQ(2, message.unpacked_sfixed64_size()); + ASSERT_EQ(2, message.unpacked_float_size ()); + ASSERT_EQ(2, message.unpacked_double_size ()); + ASSERT_EQ(2, message.unpacked_bool_size ()); + ASSERT_EQ(2, message.unpacked_enum_size ()); + + EXPECT_EQ(601 , message.unpacked_int32 (0)); + EXPECT_EQ(602 , message.unpacked_int64 (0)); + EXPECT_EQ(603 , message.unpacked_uint32 (0)); + EXPECT_EQ(604 , message.unpacked_uint64 (0)); + EXPECT_EQ(605 , message.unpacked_sint32 (0)); + EXPECT_EQ(606 , message.unpacked_sint64 (0)); + EXPECT_EQ(607 , message.unpacked_fixed32 (0)); + EXPECT_EQ(608 , message.unpacked_fixed64 (0)); + EXPECT_EQ(609 , message.unpacked_sfixed32(0)); + EXPECT_EQ(610 , message.unpacked_sfixed64(0)); + EXPECT_EQ(611 , message.unpacked_float (0)); + EXPECT_EQ(612 , message.unpacked_double (0)); + EXPECT_TRUE( message.unpacked_bool (0)); + EXPECT_EQ(unittest::FOREIGN_BAR, message.unpacked_enum(0)); + + EXPECT_EQ(701 , message.unpacked_int32 (1)); + EXPECT_EQ(702 , message.unpacked_int64 (1)); + EXPECT_EQ(703 , message.unpacked_uint32 (1)); + EXPECT_EQ(704 , message.unpacked_uint64 (1)); + EXPECT_EQ(705 , message.unpacked_sint32 (1)); + EXPECT_EQ(706 , message.unpacked_sint64 (1)); + EXPECT_EQ(707 , message.unpacked_fixed32 (1)); + EXPECT_EQ(708 , message.unpacked_fixed64 (1)); + EXPECT_EQ(709 , message.unpacked_sfixed32(1)); + EXPECT_EQ(710 , message.unpacked_sfixed64(1)); + EXPECT_EQ(711 , message.unpacked_float (1)); + EXPECT_EQ(712 , message.unpacked_double (1)); + EXPECT_FALSE( message.unpacked_bool (1)); + EXPECT_EQ(unittest::FOREIGN_BAZ, message.unpacked_enum(1)); +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectPackedClear( + const unittest::TestPackedTypes& message) { + // Packed repeated fields are empty. + EXPECT_EQ(0, message.packed_int32_size ()); + EXPECT_EQ(0, message.packed_int64_size ()); + EXPECT_EQ(0, message.packed_uint32_size ()); + EXPECT_EQ(0, message.packed_uint64_size ()); + EXPECT_EQ(0, message.packed_sint32_size ()); + EXPECT_EQ(0, message.packed_sint64_size ()); + EXPECT_EQ(0, message.packed_fixed32_size ()); + EXPECT_EQ(0, message.packed_fixed64_size ()); + EXPECT_EQ(0, message.packed_sfixed32_size()); + EXPECT_EQ(0, message.packed_sfixed64_size()); + EXPECT_EQ(0, message.packed_float_size ()); + EXPECT_EQ(0, message.packed_double_size ()); + EXPECT_EQ(0, message.packed_bool_size ()); + EXPECT_EQ(0, message.packed_enum_size ()); +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectPackedFieldsModified( + const unittest::TestPackedTypes& message) { + // Do the same for packed repeated fields. + ASSERT_EQ(2, message.packed_int32_size ()); + ASSERT_EQ(2, message.packed_int64_size ()); + ASSERT_EQ(2, message.packed_uint32_size ()); + ASSERT_EQ(2, message.packed_uint64_size ()); + ASSERT_EQ(2, message.packed_sint32_size ()); + ASSERT_EQ(2, message.packed_sint64_size ()); + ASSERT_EQ(2, message.packed_fixed32_size ()); + ASSERT_EQ(2, message.packed_fixed64_size ()); + ASSERT_EQ(2, message.packed_sfixed32_size()); + ASSERT_EQ(2, message.packed_sfixed64_size()); + ASSERT_EQ(2, message.packed_float_size ()); + ASSERT_EQ(2, message.packed_double_size ()); + ASSERT_EQ(2, message.packed_bool_size ()); + ASSERT_EQ(2, message.packed_enum_size ()); + + EXPECT_EQ(601 , message.packed_int32 (0)); + EXPECT_EQ(602 , message.packed_int64 (0)); + EXPECT_EQ(603 , message.packed_uint32 (0)); + EXPECT_EQ(604 , message.packed_uint64 (0)); + EXPECT_EQ(605 , message.packed_sint32 (0)); + EXPECT_EQ(606 , message.packed_sint64 (0)); + EXPECT_EQ(607 , message.packed_fixed32 (0)); + EXPECT_EQ(608 , message.packed_fixed64 (0)); + EXPECT_EQ(609 , message.packed_sfixed32(0)); + EXPECT_EQ(610 , message.packed_sfixed64(0)); + EXPECT_EQ(611 , message.packed_float (0)); + EXPECT_EQ(612 , message.packed_double (0)); + EXPECT_TRUE( message.packed_bool (0)); + EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0)); + // Actually verify the second (modified) elements now. + EXPECT_EQ(801 , message.packed_int32 (1)); + EXPECT_EQ(802 , message.packed_int64 (1)); + EXPECT_EQ(803 , message.packed_uint32 (1)); + EXPECT_EQ(804 , message.packed_uint64 (1)); + EXPECT_EQ(805 , message.packed_sint32 (1)); + EXPECT_EQ(806 , message.packed_sint64 (1)); + EXPECT_EQ(807 , message.packed_fixed32 (1)); + EXPECT_EQ(808 , message.packed_fixed64 (1)); + EXPECT_EQ(809 , message.packed_sfixed32(1)); + EXPECT_EQ(810 , message.packed_sfixed64(1)); + EXPECT_EQ(811 , message.packed_float (1)); + EXPECT_EQ(812 , message.packed_double (1)); + EXPECT_TRUE( message.packed_bool (1)); + EXPECT_EQ(unittest::FOREIGN_FOO, message.packed_enum(1)); +} + +// =================================================================== +// Extensions +// +// All this code is exactly equivalent to the above code except that it's +// manipulating extension fields instead of normal ones. +// +// I gave up on the 80-char limit here. Sorry. + +void TestUtil::SetAllExtensions(unittest::TestAllExtensions* message) { + message->SetExtension(unittest::optional_int32_extension , 101); + message->SetExtension(unittest::optional_int64_extension , 102); + message->SetExtension(unittest::optional_uint32_extension , 103); + message->SetExtension(unittest::optional_uint64_extension , 104); + message->SetExtension(unittest::optional_sint32_extension , 105); + message->SetExtension(unittest::optional_sint64_extension , 106); + message->SetExtension(unittest::optional_fixed32_extension , 107); + message->SetExtension(unittest::optional_fixed64_extension , 108); + message->SetExtension(unittest::optional_sfixed32_extension, 109); + message->SetExtension(unittest::optional_sfixed64_extension, 110); + message->SetExtension(unittest::optional_float_extension , 111); + message->SetExtension(unittest::optional_double_extension , 112); + message->SetExtension(unittest::optional_bool_extension , true); + message->SetExtension(unittest::optional_string_extension , "115"); + message->SetExtension(unittest::optional_bytes_extension , "116"); + + message->MutableExtension(unittest::optionalgroup_extension )->set_a(117); + message->MutableExtension(unittest::optional_nested_message_extension )->set_bb(118); + message->MutableExtension(unittest::optional_foreign_message_extension)->set_c(119); + message->MutableExtension(unittest::optional_import_message_extension )->set_d(120); + + message->SetExtension(unittest::optional_nested_enum_extension , unittest::TestAllTypes::BAZ); + message->SetExtension(unittest::optional_foreign_enum_extension, unittest::FOREIGN_BAZ ); + message->SetExtension(unittest::optional_import_enum_extension , unittest_import::IMPORT_BAZ); + + message->SetExtension(unittest::optional_string_piece_extension, "124"); + message->SetExtension(unittest::optional_cord_extension, "125"); + + message->MutableExtension(unittest::optional_public_import_message_extension)->set_e(126); + message->MutableExtension(unittest::optional_lazy_message_extension)->set_bb(127); + + // ----------------------------------------------------------------- + + message->AddExtension(unittest::repeated_int32_extension , 201); + message->AddExtension(unittest::repeated_int64_extension , 202); + message->AddExtension(unittest::repeated_uint32_extension , 203); + message->AddExtension(unittest::repeated_uint64_extension , 204); + message->AddExtension(unittest::repeated_sint32_extension , 205); + message->AddExtension(unittest::repeated_sint64_extension , 206); + message->AddExtension(unittest::repeated_fixed32_extension , 207); + message->AddExtension(unittest::repeated_fixed64_extension , 208); + message->AddExtension(unittest::repeated_sfixed32_extension, 209); + message->AddExtension(unittest::repeated_sfixed64_extension, 210); + message->AddExtension(unittest::repeated_float_extension , 211); + message->AddExtension(unittest::repeated_double_extension , 212); + message->AddExtension(unittest::repeated_bool_extension , true); + message->AddExtension(unittest::repeated_string_extension , "215"); + message->AddExtension(unittest::repeated_bytes_extension , "216"); + + message->AddExtension(unittest::repeatedgroup_extension )->set_a(217); + message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(218); + message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(219); + message->AddExtension(unittest::repeated_import_message_extension )->set_d(220); + message->AddExtension(unittest::repeated_lazy_message_extension )->set_bb(227); + + message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAR); + message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAR ); + message->AddExtension(unittest::repeated_import_enum_extension , unittest_import::IMPORT_BAR); + + message->AddExtension(unittest::repeated_string_piece_extension, "224"); + message->AddExtension(unittest::repeated_cord_extension, "225"); + + // Add a second one of each field. + message->AddExtension(unittest::repeated_int32_extension , 301); + message->AddExtension(unittest::repeated_int64_extension , 302); + message->AddExtension(unittest::repeated_uint32_extension , 303); + message->AddExtension(unittest::repeated_uint64_extension , 304); + message->AddExtension(unittest::repeated_sint32_extension , 305); + message->AddExtension(unittest::repeated_sint64_extension , 306); + message->AddExtension(unittest::repeated_fixed32_extension , 307); + message->AddExtension(unittest::repeated_fixed64_extension , 308); + message->AddExtension(unittest::repeated_sfixed32_extension, 309); + message->AddExtension(unittest::repeated_sfixed64_extension, 310); + message->AddExtension(unittest::repeated_float_extension , 311); + message->AddExtension(unittest::repeated_double_extension , 312); + message->AddExtension(unittest::repeated_bool_extension , false); + message->AddExtension(unittest::repeated_string_extension , "315"); + message->AddExtension(unittest::repeated_bytes_extension , "316"); + + message->AddExtension(unittest::repeatedgroup_extension )->set_a(317); + message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(318); + message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(319); + message->AddExtension(unittest::repeated_import_message_extension )->set_d(320); + message->AddExtension(unittest::repeated_lazy_message_extension )->set_bb(327); + + message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAZ); + message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAZ ); + message->AddExtension(unittest::repeated_import_enum_extension , unittest_import::IMPORT_BAZ); + + message->AddExtension(unittest::repeated_string_piece_extension, "324"); + message->AddExtension(unittest::repeated_cord_extension, "325"); + + // ----------------------------------------------------------------- + + message->SetExtension(unittest::default_int32_extension , 401); + message->SetExtension(unittest::default_int64_extension , 402); + message->SetExtension(unittest::default_uint32_extension , 403); + message->SetExtension(unittest::default_uint64_extension , 404); + message->SetExtension(unittest::default_sint32_extension , 405); + message->SetExtension(unittest::default_sint64_extension , 406); + message->SetExtension(unittest::default_fixed32_extension , 407); + message->SetExtension(unittest::default_fixed64_extension , 408); + message->SetExtension(unittest::default_sfixed32_extension, 409); + message->SetExtension(unittest::default_sfixed64_extension, 410); + message->SetExtension(unittest::default_float_extension , 411); + message->SetExtension(unittest::default_double_extension , 412); + message->SetExtension(unittest::default_bool_extension , false); + message->SetExtension(unittest::default_string_extension , "415"); + message->SetExtension(unittest::default_bytes_extension , "416"); + + message->SetExtension(unittest::default_nested_enum_extension , unittest::TestAllTypes::FOO); + message->SetExtension(unittest::default_foreign_enum_extension, unittest::FOREIGN_FOO ); + message->SetExtension(unittest::default_import_enum_extension , unittest_import::IMPORT_FOO); + + message->SetExtension(unittest::default_string_piece_extension, "424"); + message->SetExtension(unittest::default_cord_extension, "425"); +} + +// ------------------------------------------------------------------- + +void TestUtil::SetAllFieldsAndExtensions( + unittest::TestFieldOrderings* message) { + GOOGLE_CHECK(message); + message->set_my_int(1); + message->set_my_string("foo"); + message->set_my_float(1.0); + message->SetExtension(unittest::my_extension_int, 23); + message->SetExtension(unittest::my_extension_string, "bar"); +} + +// ------------------------------------------------------------------- + +void TestUtil::ModifyRepeatedExtensions(unittest::TestAllExtensions* message) { + message->SetExtension(unittest::repeated_int32_extension , 1, 501); + message->SetExtension(unittest::repeated_int64_extension , 1, 502); + message->SetExtension(unittest::repeated_uint32_extension , 1, 503); + message->SetExtension(unittest::repeated_uint64_extension , 1, 504); + message->SetExtension(unittest::repeated_sint32_extension , 1, 505); + message->SetExtension(unittest::repeated_sint64_extension , 1, 506); + message->SetExtension(unittest::repeated_fixed32_extension , 1, 507); + message->SetExtension(unittest::repeated_fixed64_extension , 1, 508); + message->SetExtension(unittest::repeated_sfixed32_extension, 1, 509); + message->SetExtension(unittest::repeated_sfixed64_extension, 1, 510); + message->SetExtension(unittest::repeated_float_extension , 1, 511); + message->SetExtension(unittest::repeated_double_extension , 1, 512); + message->SetExtension(unittest::repeated_bool_extension , 1, true); + message->SetExtension(unittest::repeated_string_extension , 1, "515"); + message->SetExtension(unittest::repeated_bytes_extension , 1, "516"); + + message->MutableExtension(unittest::repeatedgroup_extension , 1)->set_a(517); + message->MutableExtension(unittest::repeated_nested_message_extension , 1)->set_bb(518); + message->MutableExtension(unittest::repeated_foreign_message_extension, 1)->set_c(519); + message->MutableExtension(unittest::repeated_import_message_extension , 1)->set_d(520); + message->MutableExtension(unittest::repeated_lazy_message_extension , 1)->set_bb(527); + + message->SetExtension(unittest::repeated_nested_enum_extension , 1, unittest::TestAllTypes::FOO); + message->SetExtension(unittest::repeated_foreign_enum_extension, 1, unittest::FOREIGN_FOO ); + message->SetExtension(unittest::repeated_import_enum_extension , 1, unittest_import::IMPORT_FOO); + + message->SetExtension(unittest::repeated_string_piece_extension, 1, "524"); + message->SetExtension(unittest::repeated_cord_extension, 1, "525"); +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectAllExtensionsSet( + const unittest::TestAllExtensions& message) { + EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_int64_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_uint64_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_sint32_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_sint64_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_fixed32_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_fixed64_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed32_extension)); + EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed64_extension)); + EXPECT_TRUE(message.HasExtension(unittest::optional_float_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_double_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_bool_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension )); + + EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_public_import_message_extension)); + EXPECT_TRUE(message.HasExtension(unittest::optional_lazy_message_extension )); + + EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension ).has_a()); + EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb()); + EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension ).has_c()); + EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension ).has_d()); + EXPECT_TRUE(message.GetExtension(unittest::optional_public_import_message_extension).has_e()); + EXPECT_TRUE(message.GetExtension(unittest::optional_lazy_message_extension ).has_bb()); + + EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension )); + EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension)); + EXPECT_TRUE(message.HasExtension(unittest::optional_import_enum_extension )); + + EXPECT_TRUE(message.HasExtension(unittest::optional_string_piece_extension)); + EXPECT_TRUE(message.HasExtension(unittest::optional_cord_extension)); + + EXPECT_EQ(101 , message.GetExtension(unittest::optional_int32_extension )); + EXPECT_EQ(102 , message.GetExtension(unittest::optional_int64_extension )); + EXPECT_EQ(103 , message.GetExtension(unittest::optional_uint32_extension )); + EXPECT_EQ(104 , message.GetExtension(unittest::optional_uint64_extension )); + EXPECT_EQ(105 , message.GetExtension(unittest::optional_sint32_extension )); + EXPECT_EQ(106 , message.GetExtension(unittest::optional_sint64_extension )); + EXPECT_EQ(107 , message.GetExtension(unittest::optional_fixed32_extension )); + EXPECT_EQ(108 , message.GetExtension(unittest::optional_fixed64_extension )); + EXPECT_EQ(109 , message.GetExtension(unittest::optional_sfixed32_extension)); + EXPECT_EQ(110 , message.GetExtension(unittest::optional_sfixed64_extension)); + EXPECT_EQ(111 , message.GetExtension(unittest::optional_float_extension )); + EXPECT_EQ(112 , message.GetExtension(unittest::optional_double_extension )); + EXPECT_TRUE( message.GetExtension(unittest::optional_bool_extension )); + EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension )); + EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension )); + + EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension ).a()); + EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension ).bb()); + EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension).c()); + EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension ).d()); + + EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::optional_nested_enum_extension )); + EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::optional_foreign_enum_extension)); + EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::optional_import_enum_extension )); + + EXPECT_EQ("124", message.GetExtension(unittest::optional_string_piece_extension)); + EXPECT_EQ("125", message.GetExtension(unittest::optional_cord_extension)); + EXPECT_EQ(126, message.GetExtension(unittest::optional_public_import_message_extension ).e()); + EXPECT_EQ(127, message.GetExtension(unittest::optional_lazy_message_extension).bb()); + + // ----------------------------------------------------------------- + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension )); + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension )); + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension)); + + EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 0)); + EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 0)); + EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 0)); + EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 0)); + EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 0)); + EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 0)); + EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 0)); + EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 0)); + EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 0)); + EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0)); + EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0)); + EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0)); + EXPECT_TRUE( message.GetExtension(unittest::repeated_bool_extension , 0)); + EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0)); + EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0)); + + EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a()); + EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb()); + EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c()); + EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d()); + EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension , 0).bb()); + + EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0)); + EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0)); + EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0)); + + EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0)); + EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0)); + + EXPECT_EQ(301 , message.GetExtension(unittest::repeated_int32_extension , 1)); + EXPECT_EQ(302 , message.GetExtension(unittest::repeated_int64_extension , 1)); + EXPECT_EQ(303 , message.GetExtension(unittest::repeated_uint32_extension , 1)); + EXPECT_EQ(304 , message.GetExtension(unittest::repeated_uint64_extension , 1)); + EXPECT_EQ(305 , message.GetExtension(unittest::repeated_sint32_extension , 1)); + EXPECT_EQ(306 , message.GetExtension(unittest::repeated_sint64_extension , 1)); + EXPECT_EQ(307 , message.GetExtension(unittest::repeated_fixed32_extension , 1)); + EXPECT_EQ(308 , message.GetExtension(unittest::repeated_fixed64_extension , 1)); + EXPECT_EQ(309 , message.GetExtension(unittest::repeated_sfixed32_extension, 1)); + EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension, 1)); + EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension , 1)); + EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension , 1)); + EXPECT_FALSE( message.GetExtension(unittest::repeated_bool_extension , 1)); + EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension , 1)); + EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension , 1)); + + EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension , 1).a()); + EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb()); + EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c()); + EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension , 1).d()); + EXPECT_EQ(327, message.GetExtension(unittest::repeated_lazy_message_extension , 1).bb()); + + EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::repeated_nested_enum_extension , 1)); + EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension, 1)); + EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::repeated_import_enum_extension , 1)); + + EXPECT_EQ("324", message.GetExtension(unittest::repeated_string_piece_extension, 1)); + EXPECT_EQ("325", message.GetExtension(unittest::repeated_cord_extension, 1)); + + // ----------------------------------------------------------------- + + EXPECT_TRUE(message.HasExtension(unittest::default_int32_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_int64_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_uint32_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_uint64_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_sint32_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_sint64_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_fixed32_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_fixed64_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_sfixed32_extension)); + EXPECT_TRUE(message.HasExtension(unittest::default_sfixed64_extension)); + EXPECT_TRUE(message.HasExtension(unittest::default_float_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_double_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_bool_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_string_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_bytes_extension )); + + EXPECT_TRUE(message.HasExtension(unittest::default_nested_enum_extension )); + EXPECT_TRUE(message.HasExtension(unittest::default_foreign_enum_extension)); + EXPECT_TRUE(message.HasExtension(unittest::default_import_enum_extension )); + + EXPECT_TRUE(message.HasExtension(unittest::default_string_piece_extension)); + EXPECT_TRUE(message.HasExtension(unittest::default_cord_extension)); + + EXPECT_EQ(401 , message.GetExtension(unittest::default_int32_extension )); + EXPECT_EQ(402 , message.GetExtension(unittest::default_int64_extension )); + EXPECT_EQ(403 , message.GetExtension(unittest::default_uint32_extension )); + EXPECT_EQ(404 , message.GetExtension(unittest::default_uint64_extension )); + EXPECT_EQ(405 , message.GetExtension(unittest::default_sint32_extension )); + EXPECT_EQ(406 , message.GetExtension(unittest::default_sint64_extension )); + EXPECT_EQ(407 , message.GetExtension(unittest::default_fixed32_extension )); + EXPECT_EQ(408 , message.GetExtension(unittest::default_fixed64_extension )); + EXPECT_EQ(409 , message.GetExtension(unittest::default_sfixed32_extension)); + EXPECT_EQ(410 , message.GetExtension(unittest::default_sfixed64_extension)); + EXPECT_EQ(411 , message.GetExtension(unittest::default_float_extension )); + EXPECT_EQ(412 , message.GetExtension(unittest::default_double_extension )); + EXPECT_FALSE( message.GetExtension(unittest::default_bool_extension )); + EXPECT_EQ("415", message.GetExtension(unittest::default_string_extension )); + EXPECT_EQ("416", message.GetExtension(unittest::default_bytes_extension )); + + EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::default_nested_enum_extension )); + EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::default_foreign_enum_extension)); + EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::default_import_enum_extension )); + + EXPECT_EQ("424", message.GetExtension(unittest::default_string_piece_extension)); + EXPECT_EQ("425", message.GetExtension(unittest::default_cord_extension)); +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectExtensionsClear( + const unittest::TestAllExtensions& message) { + string serialized; + ASSERT_TRUE(message.SerializeToString(&serialized)); + EXPECT_EQ("", serialized); + EXPECT_EQ(0, message.ByteSize()); + + // has_blah() should initially be false for all optional fields. + EXPECT_FALSE(message.HasExtension(unittest::optional_int32_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_uint32_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_uint64_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_sint32_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_sint64_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_fixed32_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_fixed64_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed32_extension)); + EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed64_extension)); + EXPECT_FALSE(message.HasExtension(unittest::optional_float_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_double_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_bool_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension )); + + EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_public_import_message_extension)); + EXPECT_FALSE(message.HasExtension(unittest::optional_lazy_message_extension )); + + EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension )); + EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension)); + EXPECT_FALSE(message.HasExtension(unittest::optional_import_enum_extension )); + + EXPECT_FALSE(message.HasExtension(unittest::optional_string_piece_extension)); + EXPECT_FALSE(message.HasExtension(unittest::optional_cord_extension)); + + // Optional fields without defaults are set to zero or something like it. + EXPECT_EQ(0 , message.GetExtension(unittest::optional_int32_extension )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_int64_extension )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint32_extension )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint64_extension )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint32_extension )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint64_extension )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed32_extension )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed64_extension )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed32_extension)); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed64_extension)); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_float_extension )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_double_extension )); + EXPECT_FALSE( message.GetExtension(unittest::optional_bool_extension )); + EXPECT_EQ("" , message.GetExtension(unittest::optional_string_extension )); + EXPECT_EQ("" , message.GetExtension(unittest::optional_bytes_extension )); + + // Embedded messages should also be clear. + EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension ).has_a()); + EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb()); + EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension ).has_c()); + EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension ).has_d()); + EXPECT_FALSE(message.GetExtension(unittest::optional_public_import_message_extension).has_e()); + EXPECT_FALSE(message.GetExtension(unittest::optional_lazy_message_extension ).has_bb()); + + EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension ).a()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension ).bb()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension ).c()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension ).d()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_public_import_message_extension).e()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_lazy_message_extension ).bb()); + + // Enums without defaults are set to the first value in the enum. + EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::optional_nested_enum_extension )); + EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::optional_foreign_enum_extension)); + EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::optional_import_enum_extension )); + + EXPECT_EQ("", message.GetExtension(unittest::optional_string_piece_extension)); + EXPECT_EQ("", message.GetExtension(unittest::optional_cord_extension)); + + // Repeated fields are empty. + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int32_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int64_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint32_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint64_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint32_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint64_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed32_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed64_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed32_extension)); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed64_extension)); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_float_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_double_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bool_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bytes_extension )); + + EXPECT_EQ(0, message.ExtensionSize(unittest::repeatedgroup_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension)); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_lazy_message_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension )); + + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_piece_extension)); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_cord_extension)); + + // has_blah() should also be false for all default fields. + EXPECT_FALSE(message.HasExtension(unittest::default_int32_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_int64_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_uint32_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_uint64_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_sint32_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_sint64_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_fixed32_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_fixed64_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_sfixed32_extension)); + EXPECT_FALSE(message.HasExtension(unittest::default_sfixed64_extension)); + EXPECT_FALSE(message.HasExtension(unittest::default_float_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_double_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_bool_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_string_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_bytes_extension )); + + EXPECT_FALSE(message.HasExtension(unittest::default_nested_enum_extension )); + EXPECT_FALSE(message.HasExtension(unittest::default_foreign_enum_extension)); + EXPECT_FALSE(message.HasExtension(unittest::default_import_enum_extension )); + + EXPECT_FALSE(message.HasExtension(unittest::default_string_piece_extension)); + EXPECT_FALSE(message.HasExtension(unittest::default_cord_extension)); + + // Fields with defaults have their default values (duh). + EXPECT_EQ( 41 , message.GetExtension(unittest::default_int32_extension )); + EXPECT_EQ( 42 , message.GetExtension(unittest::default_int64_extension )); + EXPECT_EQ( 43 , message.GetExtension(unittest::default_uint32_extension )); + EXPECT_EQ( 44 , message.GetExtension(unittest::default_uint64_extension )); + EXPECT_EQ(-45 , message.GetExtension(unittest::default_sint32_extension )); + EXPECT_EQ( 46 , message.GetExtension(unittest::default_sint64_extension )); + EXPECT_EQ( 47 , message.GetExtension(unittest::default_fixed32_extension )); + EXPECT_EQ( 48 , message.GetExtension(unittest::default_fixed64_extension )); + EXPECT_EQ( 49 , message.GetExtension(unittest::default_sfixed32_extension)); + EXPECT_EQ(-50 , message.GetExtension(unittest::default_sfixed64_extension)); + EXPECT_EQ( 51.5 , message.GetExtension(unittest::default_float_extension )); + EXPECT_EQ( 52e3 , message.GetExtension(unittest::default_double_extension )); + EXPECT_TRUE( message.GetExtension(unittest::default_bool_extension )); + EXPECT_EQ("hello", message.GetExtension(unittest::default_string_extension )); + EXPECT_EQ("world", message.GetExtension(unittest::default_bytes_extension )); + + EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::default_nested_enum_extension )); + EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::default_foreign_enum_extension)); + EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::default_import_enum_extension )); + + EXPECT_EQ("abc", message.GetExtension(unittest::default_string_piece_extension)); + EXPECT_EQ("123", message.GetExtension(unittest::default_cord_extension)); +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectRepeatedExtensionsModified( + const unittest::TestAllExtensions& message) { + // ModifyRepeatedFields only sets the second repeated element of each + // field. In addition to verifying this, we also verify that the first + // element and size were *not* modified. + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension )); + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension )); + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension)); + + EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 0)); + EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 0)); + EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 0)); + EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 0)); + EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 0)); + EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 0)); + EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 0)); + EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 0)); + EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 0)); + EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0)); + EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0)); + EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0)); + EXPECT_TRUE( message.GetExtension(unittest::repeated_bool_extension , 0)); + EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0)); + EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0)); + + EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a()); + EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb()); + EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c()); + EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d()); + EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension , 0).bb()); + + EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0)); + EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0)); + EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0)); + + EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0)); + EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0)); + + // Actually verify the second (modified) elements now. + EXPECT_EQ(501 , message.GetExtension(unittest::repeated_int32_extension , 1)); + EXPECT_EQ(502 , message.GetExtension(unittest::repeated_int64_extension , 1)); + EXPECT_EQ(503 , message.GetExtension(unittest::repeated_uint32_extension , 1)); + EXPECT_EQ(504 , message.GetExtension(unittest::repeated_uint64_extension , 1)); + EXPECT_EQ(505 , message.GetExtension(unittest::repeated_sint32_extension , 1)); + EXPECT_EQ(506 , message.GetExtension(unittest::repeated_sint64_extension , 1)); + EXPECT_EQ(507 , message.GetExtension(unittest::repeated_fixed32_extension , 1)); + EXPECT_EQ(508 , message.GetExtension(unittest::repeated_fixed64_extension , 1)); + EXPECT_EQ(509 , message.GetExtension(unittest::repeated_sfixed32_extension, 1)); + EXPECT_EQ(510 , message.GetExtension(unittest::repeated_sfixed64_extension, 1)); + EXPECT_EQ(511 , message.GetExtension(unittest::repeated_float_extension , 1)); + EXPECT_EQ(512 , message.GetExtension(unittest::repeated_double_extension , 1)); + EXPECT_TRUE( message.GetExtension(unittest::repeated_bool_extension , 1)); + EXPECT_EQ("515", message.GetExtension(unittest::repeated_string_extension , 1)); + EXPECT_EQ("516", message.GetExtension(unittest::repeated_bytes_extension , 1)); + + EXPECT_EQ(517, message.GetExtension(unittest::repeatedgroup_extension , 1).a()); + EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb()); + EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c()); + EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension , 1).d()); + EXPECT_EQ(527, message.GetExtension(unittest::repeated_lazy_message_extension , 1).bb()); + + EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::repeated_nested_enum_extension , 1)); + EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::repeated_foreign_enum_extension, 1)); + EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::repeated_import_enum_extension , 1)); + + EXPECT_EQ("524", message.GetExtension(unittest::repeated_string_piece_extension, 1)); + EXPECT_EQ("525", message.GetExtension(unittest::repeated_cord_extension, 1)); +} + +// ------------------------------------------------------------------- + +void TestUtil::SetPackedExtensions(unittest::TestPackedExtensions* message) { + message->AddExtension(unittest::packed_int32_extension , 601); + message->AddExtension(unittest::packed_int64_extension , 602); + message->AddExtension(unittest::packed_uint32_extension , 603); + message->AddExtension(unittest::packed_uint64_extension , 604); + message->AddExtension(unittest::packed_sint32_extension , 605); + message->AddExtension(unittest::packed_sint64_extension , 606); + message->AddExtension(unittest::packed_fixed32_extension , 607); + message->AddExtension(unittest::packed_fixed64_extension , 608); + message->AddExtension(unittest::packed_sfixed32_extension, 609); + message->AddExtension(unittest::packed_sfixed64_extension, 610); + message->AddExtension(unittest::packed_float_extension , 611); + message->AddExtension(unittest::packed_double_extension , 612); + message->AddExtension(unittest::packed_bool_extension , true); + message->AddExtension(unittest::packed_enum_extension, unittest::FOREIGN_BAR); + // add a second one of each field + message->AddExtension(unittest::packed_int32_extension , 701); + message->AddExtension(unittest::packed_int64_extension , 702); + message->AddExtension(unittest::packed_uint32_extension , 703); + message->AddExtension(unittest::packed_uint64_extension , 704); + message->AddExtension(unittest::packed_sint32_extension , 705); + message->AddExtension(unittest::packed_sint64_extension , 706); + message->AddExtension(unittest::packed_fixed32_extension , 707); + message->AddExtension(unittest::packed_fixed64_extension , 708); + message->AddExtension(unittest::packed_sfixed32_extension, 709); + message->AddExtension(unittest::packed_sfixed64_extension, 710); + message->AddExtension(unittest::packed_float_extension , 711); + message->AddExtension(unittest::packed_double_extension , 712); + message->AddExtension(unittest::packed_bool_extension , false); + message->AddExtension(unittest::packed_enum_extension, unittest::FOREIGN_BAZ); +} + +// ------------------------------------------------------------------- + +void TestUtil::ModifyPackedExtensions(unittest::TestPackedExtensions* message) { + message->SetExtension(unittest::packed_int32_extension , 1, 801); + message->SetExtension(unittest::packed_int64_extension , 1, 802); + message->SetExtension(unittest::packed_uint32_extension , 1, 803); + message->SetExtension(unittest::packed_uint64_extension , 1, 804); + message->SetExtension(unittest::packed_sint32_extension , 1, 805); + message->SetExtension(unittest::packed_sint64_extension , 1, 806); + message->SetExtension(unittest::packed_fixed32_extension , 1, 807); + message->SetExtension(unittest::packed_fixed64_extension , 1, 808); + message->SetExtension(unittest::packed_sfixed32_extension, 1, 809); + message->SetExtension(unittest::packed_sfixed64_extension, 1, 810); + message->SetExtension(unittest::packed_float_extension , 1, 811); + message->SetExtension(unittest::packed_double_extension , 1, 812); + message->SetExtension(unittest::packed_bool_extension , 1, true); + message->SetExtension(unittest::packed_enum_extension , 1, + unittest::FOREIGN_FOO); +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectPackedExtensionsSet( + const unittest::TestPackedExtensions& message) { + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension )); + + EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension , 0)); + EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension , 0)); + EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension , 0)); + EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension , 0)); + EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension , 0)); + EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension , 0)); + EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension , 0)); + EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension , 0)); + EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension, 0)); + EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension, 0)); + EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension , 0)); + EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension , 0)); + EXPECT_TRUE( message.GetExtension(unittest::packed_bool_extension , 0)); + EXPECT_EQ(unittest::FOREIGN_BAR, + message.GetExtension(unittest::packed_enum_extension, 0)); + EXPECT_EQ(701 , message.GetExtension(unittest::packed_int32_extension , 1)); + EXPECT_EQ(702 , message.GetExtension(unittest::packed_int64_extension , 1)); + EXPECT_EQ(703 , message.GetExtension(unittest::packed_uint32_extension , 1)); + EXPECT_EQ(704 , message.GetExtension(unittest::packed_uint64_extension , 1)); + EXPECT_EQ(705 , message.GetExtension(unittest::packed_sint32_extension , 1)); + EXPECT_EQ(706 , message.GetExtension(unittest::packed_sint64_extension , 1)); + EXPECT_EQ(707 , message.GetExtension(unittest::packed_fixed32_extension , 1)); + EXPECT_EQ(708 , message.GetExtension(unittest::packed_fixed64_extension , 1)); + EXPECT_EQ(709 , message.GetExtension(unittest::packed_sfixed32_extension, 1)); + EXPECT_EQ(710 , message.GetExtension(unittest::packed_sfixed64_extension, 1)); + EXPECT_EQ(711 , message.GetExtension(unittest::packed_float_extension , 1)); + EXPECT_EQ(712 , message.GetExtension(unittest::packed_double_extension , 1)); + EXPECT_FALSE( message.GetExtension(unittest::packed_bool_extension , 1)); + EXPECT_EQ(unittest::FOREIGN_BAZ, + message.GetExtension(unittest::packed_enum_extension, 1)); +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectPackedExtensionsClear( + const unittest::TestPackedExtensions& message) { + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int32_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int64_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint32_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint64_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint32_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint64_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed32_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed64_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed32_extension)); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed64_extension)); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_float_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_double_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_bool_extension )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_enum_extension )); +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectPackedExtensionsModified( + const unittest::TestPackedExtensions& message) { + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension )); + EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension , 0)); + EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension , 0)); + EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension , 0)); + EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension , 0)); + EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension , 0)); + EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension , 0)); + EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension , 0)); + EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension , 0)); + EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension, 0)); + EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension, 0)); + EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension , 0)); + EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension , 0)); + EXPECT_TRUE( message.GetExtension(unittest::packed_bool_extension , 0)); + EXPECT_EQ(unittest::FOREIGN_BAR, + message.GetExtension(unittest::packed_enum_extension, 0)); + + // Actually verify the second (modified) elements now. + EXPECT_EQ(801 , message.GetExtension(unittest::packed_int32_extension , 1)); + EXPECT_EQ(802 , message.GetExtension(unittest::packed_int64_extension , 1)); + EXPECT_EQ(803 , message.GetExtension(unittest::packed_uint32_extension , 1)); + EXPECT_EQ(804 , message.GetExtension(unittest::packed_uint64_extension , 1)); + EXPECT_EQ(805 , message.GetExtension(unittest::packed_sint32_extension , 1)); + EXPECT_EQ(806 , message.GetExtension(unittest::packed_sint64_extension , 1)); + EXPECT_EQ(807 , message.GetExtension(unittest::packed_fixed32_extension , 1)); + EXPECT_EQ(808 , message.GetExtension(unittest::packed_fixed64_extension , 1)); + EXPECT_EQ(809 , message.GetExtension(unittest::packed_sfixed32_extension, 1)); + EXPECT_EQ(810 , message.GetExtension(unittest::packed_sfixed64_extension, 1)); + EXPECT_EQ(811 , message.GetExtension(unittest::packed_float_extension , 1)); + EXPECT_EQ(812 , message.GetExtension(unittest::packed_double_extension , 1)); + EXPECT_TRUE( message.GetExtension(unittest::packed_bool_extension , 1)); + EXPECT_EQ(unittest::FOREIGN_FOO, + message.GetExtension(unittest::packed_enum_extension, 1)); +} + +// ------------------------------------------------------------------- + +void TestUtil::ExpectAllFieldsAndExtensionsInOrder(const string& serialized) { + // We set each field individually, serialize separately, and concatenate all + // the strings in canonical order to determine the expected serialization. + string expected; + unittest::TestFieldOrderings message; + message.set_my_int(1); // Field 1. + message.AppendToString(&expected); + message.Clear(); + message.SetExtension(unittest::my_extension_int, 23); // Field 5. + message.AppendToString(&expected); + message.Clear(); + message.set_my_string("foo"); // Field 11. + message.AppendToString(&expected); + message.Clear(); + message.SetExtension(unittest::my_extension_string, "bar"); // Field 50. + message.AppendToString(&expected); + message.Clear(); + message.set_my_float(1.0); // Field 101. + message.AppendToString(&expected); + message.Clear(); + + // We don't EXPECT_EQ() since we don't want to print raw bytes to stdout. + EXPECT_TRUE(serialized == expected); +} + +void TestUtil::ExpectLastRepeatedsRemoved( + const unittest::TestAllTypes& message) { + ASSERT_EQ(1, message.repeated_int32_size ()); + ASSERT_EQ(1, message.repeated_int64_size ()); + ASSERT_EQ(1, message.repeated_uint32_size ()); + ASSERT_EQ(1, message.repeated_uint64_size ()); + ASSERT_EQ(1, message.repeated_sint32_size ()); + ASSERT_EQ(1, message.repeated_sint64_size ()); + ASSERT_EQ(1, message.repeated_fixed32_size ()); + ASSERT_EQ(1, message.repeated_fixed64_size ()); + ASSERT_EQ(1, message.repeated_sfixed32_size()); + ASSERT_EQ(1, message.repeated_sfixed64_size()); + ASSERT_EQ(1, message.repeated_float_size ()); + ASSERT_EQ(1, message.repeated_double_size ()); + ASSERT_EQ(1, message.repeated_bool_size ()); + ASSERT_EQ(1, message.repeated_string_size ()); + ASSERT_EQ(1, message.repeated_bytes_size ()); + + ASSERT_EQ(1, message.repeatedgroup_size ()); + ASSERT_EQ(1, message.repeated_nested_message_size ()); + ASSERT_EQ(1, message.repeated_foreign_message_size()); + ASSERT_EQ(1, message.repeated_import_message_size ()); + ASSERT_EQ(1, message.repeated_import_message_size ()); + ASSERT_EQ(1, message.repeated_nested_enum_size ()); + ASSERT_EQ(1, message.repeated_foreign_enum_size ()); + ASSERT_EQ(1, message.repeated_import_enum_size ()); + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + ASSERT_EQ(1, message.repeated_string_piece_size()); + ASSERT_EQ(1, message.repeated_cord_size()); +#endif + + // Test that the remaining element is the correct one. + EXPECT_EQ(201 , message.repeated_int32 (0)); + EXPECT_EQ(202 , message.repeated_int64 (0)); + EXPECT_EQ(203 , message.repeated_uint32 (0)); + EXPECT_EQ(204 , message.repeated_uint64 (0)); + EXPECT_EQ(205 , message.repeated_sint32 (0)); + EXPECT_EQ(206 , message.repeated_sint64 (0)); + EXPECT_EQ(207 , message.repeated_fixed32 (0)); + EXPECT_EQ(208 , message.repeated_fixed64 (0)); + EXPECT_EQ(209 , message.repeated_sfixed32(0)); + EXPECT_EQ(210 , message.repeated_sfixed64(0)); + EXPECT_EQ(211 , message.repeated_float (0)); + EXPECT_EQ(212 , message.repeated_double (0)); + EXPECT_TRUE( message.repeated_bool (0)); + EXPECT_EQ("215", message.repeated_string (0)); + EXPECT_EQ("216", message.repeated_bytes (0)); + + EXPECT_EQ(217, message.repeatedgroup (0).a()); + EXPECT_EQ(218, message.repeated_nested_message (0).bb()); + EXPECT_EQ(219, message.repeated_foreign_message(0).c()); + EXPECT_EQ(220, message.repeated_import_message (0).d()); + EXPECT_EQ(220, message.repeated_import_message (0).d()); + + EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0)); + EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0)); + EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0)); +} + +void TestUtil::ExpectLastRepeatedExtensionsRemoved( + const unittest::TestAllExtensions& message) { + + // Test that one element was removed. + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_int32_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_int64_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_uint32_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_uint64_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sint32_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sint64_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_fixed32_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_fixed64_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sfixed32_extension)); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sfixed64_extension)); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_float_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_double_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_bool_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_bytes_extension )); + + ASSERT_EQ(1, message.ExtensionSize(unittest::repeatedgroup_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_message_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_message_extension)); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_message_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_lazy_message_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_enum_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_enum_extension )); + + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_piece_extension)); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_cord_extension)); + + // Test that the remaining element is the correct one. + EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 0)); + EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 0)); + EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 0)); + EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 0)); + EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 0)); + EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 0)); + EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 0)); + EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 0)); + EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 0)); + EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0)); + EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0)); + EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0)); + EXPECT_TRUE( message.GetExtension(unittest::repeated_bool_extension , 0)); + EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0)); + EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0)); + + EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a()); + EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb()); + EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c()); + EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d()); + EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension , 0).bb()); + + EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0)); + EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0)); + EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0)); + + EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0)); + EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0)); +} + +void TestUtil::ExpectLastRepeatedsReleased( + const unittest::TestAllTypes& message) { + ASSERT_EQ(1, message.repeatedgroup_size ()); + ASSERT_EQ(1, message.repeated_nested_message_size ()); + ASSERT_EQ(1, message.repeated_foreign_message_size()); + ASSERT_EQ(1, message.repeated_import_message_size ()); + ASSERT_EQ(1, message.repeated_import_message_size ()); + + EXPECT_EQ(217, message.repeatedgroup (0).a()); + EXPECT_EQ(218, message.repeated_nested_message (0).bb()); + EXPECT_EQ(219, message.repeated_foreign_message(0).c()); + EXPECT_EQ(220, message.repeated_import_message (0).d()); + EXPECT_EQ(220, message.repeated_import_message (0).d()); +} + +void TestUtil::ExpectLastRepeatedExtensionsReleased( + const unittest::TestAllExtensions& message) { + ASSERT_EQ(1, message.ExtensionSize(unittest::repeatedgroup_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_message_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_message_extension)); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_message_extension )); + ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_lazy_message_extension )); + + EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a()); + EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb()); + EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c()); + EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d()); + EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension , 0).bb()); +} + +void TestUtil::ExpectRepeatedsSwapped( + const unittest::TestAllTypes& message) { + ASSERT_EQ(2, message.repeated_int32_size ()); + ASSERT_EQ(2, message.repeated_int64_size ()); + ASSERT_EQ(2, message.repeated_uint32_size ()); + ASSERT_EQ(2, message.repeated_uint64_size ()); + ASSERT_EQ(2, message.repeated_sint32_size ()); + ASSERT_EQ(2, message.repeated_sint64_size ()); + ASSERT_EQ(2, message.repeated_fixed32_size ()); + ASSERT_EQ(2, message.repeated_fixed64_size ()); + ASSERT_EQ(2, message.repeated_sfixed32_size()); + ASSERT_EQ(2, message.repeated_sfixed64_size()); + ASSERT_EQ(2, message.repeated_float_size ()); + ASSERT_EQ(2, message.repeated_double_size ()); + ASSERT_EQ(2, message.repeated_bool_size ()); + ASSERT_EQ(2, message.repeated_string_size ()); + ASSERT_EQ(2, message.repeated_bytes_size ()); + + ASSERT_EQ(2, message.repeatedgroup_size ()); + ASSERT_EQ(2, message.repeated_nested_message_size ()); + ASSERT_EQ(2, message.repeated_foreign_message_size()); + ASSERT_EQ(2, message.repeated_import_message_size ()); + ASSERT_EQ(2, message.repeated_import_message_size ()); + ASSERT_EQ(2, message.repeated_nested_enum_size ()); + ASSERT_EQ(2, message.repeated_foreign_enum_size ()); + ASSERT_EQ(2, message.repeated_import_enum_size ()); + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + ASSERT_EQ(2, message.repeated_string_piece_size()); + ASSERT_EQ(2, message.repeated_cord_size()); +#endif + + // Test that the first element and second element are flipped. + EXPECT_EQ(201 , message.repeated_int32 (1)); + EXPECT_EQ(202 , message.repeated_int64 (1)); + EXPECT_EQ(203 , message.repeated_uint32 (1)); + EXPECT_EQ(204 , message.repeated_uint64 (1)); + EXPECT_EQ(205 , message.repeated_sint32 (1)); + EXPECT_EQ(206 , message.repeated_sint64 (1)); + EXPECT_EQ(207 , message.repeated_fixed32 (1)); + EXPECT_EQ(208 , message.repeated_fixed64 (1)); + EXPECT_EQ(209 , message.repeated_sfixed32(1)); + EXPECT_EQ(210 , message.repeated_sfixed64(1)); + EXPECT_EQ(211 , message.repeated_float (1)); + EXPECT_EQ(212 , message.repeated_double (1)); + EXPECT_TRUE( message.repeated_bool (1)); + EXPECT_EQ("215", message.repeated_string (1)); + EXPECT_EQ("216", message.repeated_bytes (1)); + + EXPECT_EQ(217, message.repeatedgroup (1).a()); + EXPECT_EQ(218, message.repeated_nested_message (1).bb()); + EXPECT_EQ(219, message.repeated_foreign_message(1).c()); + EXPECT_EQ(220, message.repeated_import_message (1).d()); + EXPECT_EQ(220, message.repeated_import_message (1).d()); + + EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (1)); + EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(1)); + EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (1)); + + EXPECT_EQ(301 , message.repeated_int32 (0)); + EXPECT_EQ(302 , message.repeated_int64 (0)); + EXPECT_EQ(303 , message.repeated_uint32 (0)); + EXPECT_EQ(304 , message.repeated_uint64 (0)); + EXPECT_EQ(305 , message.repeated_sint32 (0)); + EXPECT_EQ(306 , message.repeated_sint64 (0)); + EXPECT_EQ(307 , message.repeated_fixed32 (0)); + EXPECT_EQ(308 , message.repeated_fixed64 (0)); + EXPECT_EQ(309 , message.repeated_sfixed32(0)); + EXPECT_EQ(310 , message.repeated_sfixed64(0)); + EXPECT_EQ(311 , message.repeated_float (0)); + EXPECT_EQ(312 , message.repeated_double (0)); + EXPECT_FALSE( message.repeated_bool (0)); + EXPECT_EQ("315", message.repeated_string (0)); + EXPECT_EQ("316", message.repeated_bytes (0)); + + EXPECT_EQ(317, message.repeatedgroup (0).a()); + EXPECT_EQ(318, message.repeated_nested_message (0).bb()); + EXPECT_EQ(319, message.repeated_foreign_message(0).c()); + EXPECT_EQ(320, message.repeated_import_message (0).d()); + EXPECT_EQ(320, message.repeated_import_message (0).d()); + + EXPECT_EQ(unittest::TestAllTypes::BAZ, message.repeated_nested_enum (0)); + EXPECT_EQ(unittest::FOREIGN_BAZ , message.repeated_foreign_enum(0)); + EXPECT_EQ(unittest_import::IMPORT_BAZ, message.repeated_import_enum (0)); +} + +void TestUtil::ExpectRepeatedExtensionsSwapped( + const unittest::TestAllExtensions& message) { + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension )); + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension )); + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension)); + + EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 1)); + EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 1)); + EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 1)); + EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 1)); + EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 1)); + EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 1)); + EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 1)); + EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 1)); + EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 1)); + EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 1)); + EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 1)); + EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 1)); + EXPECT_TRUE( message.GetExtension(unittest::repeated_bool_extension , 1)); + EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 1)); + EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 1)); + + EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 1).a()); + EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb()); + EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c()); + EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 1).d()); + EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension , 1).bb()); + + EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 1)); + EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 1)); + EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 1)); + + EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 1)); + EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 1)); + + EXPECT_EQ(301 , message.GetExtension(unittest::repeated_int32_extension , 0)); + EXPECT_EQ(302 , message.GetExtension(unittest::repeated_int64_extension , 0)); + EXPECT_EQ(303 , message.GetExtension(unittest::repeated_uint32_extension , 0)); + EXPECT_EQ(304 , message.GetExtension(unittest::repeated_uint64_extension , 0)); + EXPECT_EQ(305 , message.GetExtension(unittest::repeated_sint32_extension , 0)); + EXPECT_EQ(306 , message.GetExtension(unittest::repeated_sint64_extension , 0)); + EXPECT_EQ(307 , message.GetExtension(unittest::repeated_fixed32_extension , 0)); + EXPECT_EQ(308 , message.GetExtension(unittest::repeated_fixed64_extension , 0)); + EXPECT_EQ(309 , message.GetExtension(unittest::repeated_sfixed32_extension, 0)); + EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension, 0)); + EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension , 0)); + EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension , 0)); + EXPECT_FALSE( message.GetExtension(unittest::repeated_bool_extension , 0)); + EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension , 0)); + EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension , 0)); + + EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension , 0).a()); + EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb()); + EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c()); + EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension , 0).d()); + EXPECT_EQ(327, message.GetExtension(unittest::repeated_lazy_message_extension , 0).bb()); + + EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::repeated_nested_enum_extension , 0)); + EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension, 0)); + EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::repeated_import_enum_extension , 0)); + + EXPECT_EQ("324", message.GetExtension(unittest::repeated_string_piece_extension, 0)); + EXPECT_EQ("325", message.GetExtension(unittest::repeated_cord_extension, 0)); +} + +// =================================================================== + +TestUtil::ReflectionTester::ReflectionTester( + const Descriptor* base_descriptor) + : base_descriptor_(base_descriptor) { + + const DescriptorPool* pool = base_descriptor->file()->pool(); + + nested_b_ = + pool->FindFieldByName("protobuf_unittest.TestAllTypes.NestedMessage.bb"); + foreign_c_ = + pool->FindFieldByName("protobuf_unittest.ForeignMessage.c"); + import_d_ = + pool->FindFieldByName("protobuf_unittest_import.ImportMessage.d"); + import_e_ = + pool->FindFieldByName("protobuf_unittest_import.PublicImportMessage.e"); + nested_foo_ = + pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.FOO"); + nested_bar_ = + pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.BAR"); + nested_baz_ = + pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.BAZ"); + foreign_foo_ = + pool->FindEnumValueByName("protobuf_unittest.FOREIGN_FOO"); + foreign_bar_ = + pool->FindEnumValueByName("protobuf_unittest.FOREIGN_BAR"); + foreign_baz_ = + pool->FindEnumValueByName("protobuf_unittest.FOREIGN_BAZ"); + import_foo_ = + pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_FOO"); + import_bar_ = + pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_BAR"); + import_baz_ = + pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_BAZ"); + + if (base_descriptor_->name() == "TestAllExtensions") { + group_a_ = + pool->FindFieldByName("protobuf_unittest.OptionalGroup_extension.a"); + repeated_group_a_ = + pool->FindFieldByName("protobuf_unittest.RepeatedGroup_extension.a"); + } else { + group_a_ = + pool->FindFieldByName("protobuf_unittest.TestAllTypes.OptionalGroup.a"); + repeated_group_a_ = + pool->FindFieldByName("protobuf_unittest.TestAllTypes.RepeatedGroup.a"); + } + + EXPECT_TRUE(group_a_ != NULL); + EXPECT_TRUE(repeated_group_a_ != NULL); + EXPECT_TRUE(nested_b_ != NULL); + EXPECT_TRUE(foreign_c_ != NULL); + EXPECT_TRUE(import_d_ != NULL); + EXPECT_TRUE(import_e_ != NULL); + EXPECT_TRUE(nested_foo_ != NULL); + EXPECT_TRUE(nested_bar_ != NULL); + EXPECT_TRUE(nested_baz_ != NULL); + EXPECT_TRUE(foreign_foo_ != NULL); + EXPECT_TRUE(foreign_bar_ != NULL); + EXPECT_TRUE(foreign_baz_ != NULL); + EXPECT_TRUE(import_foo_ != NULL); + EXPECT_TRUE(import_bar_ != NULL); + EXPECT_TRUE(import_baz_ != NULL); +} + +// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. +const FieldDescriptor* TestUtil::ReflectionTester::F(const string& name) { + const FieldDescriptor* result = NULL; + if (base_descriptor_->name() == "TestAllExtensions" || + base_descriptor_->name() == "TestPackedExtensions") { + result = base_descriptor_->file()->FindExtensionByName(name + "_extension"); + } else { + result = base_descriptor_->FindFieldByName(name); + } + GOOGLE_CHECK(result != NULL); + return result; +} + +// ------------------------------------------------------------------- + +void TestUtil::ReflectionTester::SetAllFieldsViaReflection(Message* message) { + const Reflection* reflection = message->GetReflection(); + Message* sub_message; + + reflection->SetInt32 (message, F("optional_int32" ), 101); + reflection->SetInt64 (message, F("optional_int64" ), 102); + reflection->SetUInt32(message, F("optional_uint32" ), 103); + reflection->SetUInt64(message, F("optional_uint64" ), 104); + reflection->SetInt32 (message, F("optional_sint32" ), 105); + reflection->SetInt64 (message, F("optional_sint64" ), 106); + reflection->SetUInt32(message, F("optional_fixed32" ), 107); + reflection->SetUInt64(message, F("optional_fixed64" ), 108); + reflection->SetInt32 (message, F("optional_sfixed32"), 109); + reflection->SetInt64 (message, F("optional_sfixed64"), 110); + reflection->SetFloat (message, F("optional_float" ), 111); + reflection->SetDouble(message, F("optional_double" ), 112); + reflection->SetBool (message, F("optional_bool" ), true); + reflection->SetString(message, F("optional_string" ), "115"); + reflection->SetString(message, F("optional_bytes" ), "116"); + + sub_message = reflection->MutableMessage(message, F("optionalgroup")); + sub_message->GetReflection()->SetInt32(sub_message, group_a_, 117); + sub_message = reflection->MutableMessage(message, F("optional_nested_message")); + sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 118); + sub_message = reflection->MutableMessage(message, F("optional_foreign_message")); + sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 119); + sub_message = reflection->MutableMessage(message, F("optional_import_message")); + sub_message->GetReflection()->SetInt32(sub_message, import_d_, 120); + + reflection->SetEnum(message, F("optional_nested_enum" ), nested_baz_); + reflection->SetEnum(message, F("optional_foreign_enum"), foreign_baz_); + reflection->SetEnum(message, F("optional_import_enum" ), import_baz_); + + reflection->SetString(message, F("optional_string_piece"), "124"); + reflection->SetString(message, F("optional_cord"), "125"); + + sub_message = reflection->MutableMessage(message, F("optional_public_import_message")); + sub_message->GetReflection()->SetInt32(sub_message, import_e_, 126); + + sub_message = reflection->MutableMessage(message, F("optional_lazy_message")); + sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 127); + + // ----------------------------------------------------------------- + + reflection->AddInt32 (message, F("repeated_int32" ), 201); + reflection->AddInt64 (message, F("repeated_int64" ), 202); + reflection->AddUInt32(message, F("repeated_uint32" ), 203); + reflection->AddUInt64(message, F("repeated_uint64" ), 204); + reflection->AddInt32 (message, F("repeated_sint32" ), 205); + reflection->AddInt64 (message, F("repeated_sint64" ), 206); + reflection->AddUInt32(message, F("repeated_fixed32" ), 207); + reflection->AddUInt64(message, F("repeated_fixed64" ), 208); + reflection->AddInt32 (message, F("repeated_sfixed32"), 209); + reflection->AddInt64 (message, F("repeated_sfixed64"), 210); + reflection->AddFloat (message, F("repeated_float" ), 211); + reflection->AddDouble(message, F("repeated_double" ), 212); + reflection->AddBool (message, F("repeated_bool" ), true); + reflection->AddString(message, F("repeated_string" ), "215"); + reflection->AddString(message, F("repeated_bytes" ), "216"); + + sub_message = reflection->AddMessage(message, F("repeatedgroup")); + sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 217); + sub_message = reflection->AddMessage(message, F("repeated_nested_message")); + sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 218); + sub_message = reflection->AddMessage(message, F("repeated_foreign_message")); + sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 219); + sub_message = reflection->AddMessage(message, F("repeated_import_message")); + sub_message->GetReflection()->SetInt32(sub_message, import_d_, 220); + sub_message = reflection->AddMessage(message, F("repeated_lazy_message")); + sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 227); + + reflection->AddEnum(message, F("repeated_nested_enum" ), nested_bar_); + reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_bar_); + reflection->AddEnum(message, F("repeated_import_enum" ), import_bar_); + + reflection->AddString(message, F("repeated_string_piece"), "224"); + reflection->AddString(message, F("repeated_cord"), "225"); + + // Add a second one of each field. + reflection->AddInt32 (message, F("repeated_int32" ), 301); + reflection->AddInt64 (message, F("repeated_int64" ), 302); + reflection->AddUInt32(message, F("repeated_uint32" ), 303); + reflection->AddUInt64(message, F("repeated_uint64" ), 304); + reflection->AddInt32 (message, F("repeated_sint32" ), 305); + reflection->AddInt64 (message, F("repeated_sint64" ), 306); + reflection->AddUInt32(message, F("repeated_fixed32" ), 307); + reflection->AddUInt64(message, F("repeated_fixed64" ), 308); + reflection->AddInt32 (message, F("repeated_sfixed32"), 309); + reflection->AddInt64 (message, F("repeated_sfixed64"), 310); + reflection->AddFloat (message, F("repeated_float" ), 311); + reflection->AddDouble(message, F("repeated_double" ), 312); + reflection->AddBool (message, F("repeated_bool" ), false); + reflection->AddString(message, F("repeated_string" ), "315"); + reflection->AddString(message, F("repeated_bytes" ), "316"); + + sub_message = reflection->AddMessage(message, F("repeatedgroup")); + sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 317); + sub_message = reflection->AddMessage(message, F("repeated_nested_message")); + sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 318); + sub_message = reflection->AddMessage(message, F("repeated_foreign_message")); + sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 319); + sub_message = reflection->AddMessage(message, F("repeated_import_message")); + sub_message->GetReflection()->SetInt32(sub_message, import_d_, 320); + sub_message = reflection->AddMessage(message, F("repeated_lazy_message")); + sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 327); + + reflection->AddEnum(message, F("repeated_nested_enum" ), nested_baz_); + reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_baz_); + reflection->AddEnum(message, F("repeated_import_enum" ), import_baz_); + + reflection->AddString(message, F("repeated_string_piece"), "324"); + reflection->AddString(message, F("repeated_cord"), "325"); + + // ----------------------------------------------------------------- + + reflection->SetInt32 (message, F("default_int32" ), 401); + reflection->SetInt64 (message, F("default_int64" ), 402); + reflection->SetUInt32(message, F("default_uint32" ), 403); + reflection->SetUInt64(message, F("default_uint64" ), 404); + reflection->SetInt32 (message, F("default_sint32" ), 405); + reflection->SetInt64 (message, F("default_sint64" ), 406); + reflection->SetUInt32(message, F("default_fixed32" ), 407); + reflection->SetUInt64(message, F("default_fixed64" ), 408); + reflection->SetInt32 (message, F("default_sfixed32"), 409); + reflection->SetInt64 (message, F("default_sfixed64"), 410); + reflection->SetFloat (message, F("default_float" ), 411); + reflection->SetDouble(message, F("default_double" ), 412); + reflection->SetBool (message, F("default_bool" ), false); + reflection->SetString(message, F("default_string" ), "415"); + reflection->SetString(message, F("default_bytes" ), "416"); + + reflection->SetEnum(message, F("default_nested_enum" ), nested_foo_); + reflection->SetEnum(message, F("default_foreign_enum"), foreign_foo_); + reflection->SetEnum(message, F("default_import_enum" ), import_foo_); + + reflection->SetString(message, F("default_string_piece"), "424"); + reflection->SetString(message, F("default_cord"), "425"); +} + +void TestUtil::ReflectionTester::SetPackedFieldsViaReflection( + Message* message) { + const Reflection* reflection = message->GetReflection(); + reflection->AddInt32 (message, F("packed_int32" ), 601); + reflection->AddInt64 (message, F("packed_int64" ), 602); + reflection->AddUInt32(message, F("packed_uint32" ), 603); + reflection->AddUInt64(message, F("packed_uint64" ), 604); + reflection->AddInt32 (message, F("packed_sint32" ), 605); + reflection->AddInt64 (message, F("packed_sint64" ), 606); + reflection->AddUInt32(message, F("packed_fixed32" ), 607); + reflection->AddUInt64(message, F("packed_fixed64" ), 608); + reflection->AddInt32 (message, F("packed_sfixed32"), 609); + reflection->AddInt64 (message, F("packed_sfixed64"), 610); + reflection->AddFloat (message, F("packed_float" ), 611); + reflection->AddDouble(message, F("packed_double" ), 612); + reflection->AddBool (message, F("packed_bool" ), true); + reflection->AddEnum (message, F("packed_enum" ), foreign_bar_); + + reflection->AddInt32 (message, F("packed_int32" ), 701); + reflection->AddInt64 (message, F("packed_int64" ), 702); + reflection->AddUInt32(message, F("packed_uint32" ), 703); + reflection->AddUInt64(message, F("packed_uint64" ), 704); + reflection->AddInt32 (message, F("packed_sint32" ), 705); + reflection->AddInt64 (message, F("packed_sint64" ), 706); + reflection->AddUInt32(message, F("packed_fixed32" ), 707); + reflection->AddUInt64(message, F("packed_fixed64" ), 708); + reflection->AddInt32 (message, F("packed_sfixed32"), 709); + reflection->AddInt64 (message, F("packed_sfixed64"), 710); + reflection->AddFloat (message, F("packed_float" ), 711); + reflection->AddDouble(message, F("packed_double" ), 712); + reflection->AddBool (message, F("packed_bool" ), false); + reflection->AddEnum (message, F("packed_enum" ), foreign_baz_); +} + +// ------------------------------------------------------------------- + +void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection( + const Message& message) { + // We have to split this into three function otherwise it creates a stack + // frame so large that it triggers a warning. + ExpectAllFieldsSetViaReflection1(message); + ExpectAllFieldsSetViaReflection2(message); + ExpectAllFieldsSetViaReflection3(message); +} + +void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection1( + const Message& message) { + const Reflection* reflection = message.GetReflection(); + string scratch; + const Message* sub_message; + + EXPECT_TRUE(reflection->HasField(message, F("optional_int32" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_int64" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_uint32" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_uint64" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_sint32" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_sint64" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_fixed32" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_fixed64" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed32"))); + EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed64"))); + EXPECT_TRUE(reflection->HasField(message, F("optional_float" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_double" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_bool" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_string" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_bytes" ))); + + EXPECT_TRUE(reflection->HasField(message, F("optionalgroup" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_nested_message" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_message" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_import_message" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_public_import_message"))); + EXPECT_TRUE(reflection->HasField(message, F("optional_lazy_message" ))); + + sub_message = &reflection->GetMessage(message, F("optionalgroup")); + EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, group_a_)); + sub_message = &reflection->GetMessage(message, F("optional_nested_message")); + EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, nested_b_)); + sub_message = &reflection->GetMessage(message, F("optional_foreign_message")); + EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_)); + sub_message = &reflection->GetMessage(message, F("optional_import_message")); + EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_d_)); + sub_message = &reflection->GetMessage(message, F("optional_public_import_message")); + EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_e_)); + sub_message = &reflection->GetMessage(message, F("optional_lazy_message")); + EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, nested_b_)); + + EXPECT_TRUE(reflection->HasField(message, F("optional_nested_enum" ))); + EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_enum"))); + EXPECT_TRUE(reflection->HasField(message, F("optional_import_enum" ))); + + EXPECT_TRUE(reflection->HasField(message, F("optional_string_piece"))); + EXPECT_TRUE(reflection->HasField(message, F("optional_cord"))); + + EXPECT_EQ(101 , reflection->GetInt32 (message, F("optional_int32" ))); + EXPECT_EQ(102 , reflection->GetInt64 (message, F("optional_int64" ))); + EXPECT_EQ(103 , reflection->GetUInt32(message, F("optional_uint32" ))); + EXPECT_EQ(104 , reflection->GetUInt64(message, F("optional_uint64" ))); + EXPECT_EQ(105 , reflection->GetInt32 (message, F("optional_sint32" ))); + EXPECT_EQ(106 , reflection->GetInt64 (message, F("optional_sint64" ))); + EXPECT_EQ(107 , reflection->GetUInt32(message, F("optional_fixed32" ))); + EXPECT_EQ(108 , reflection->GetUInt64(message, F("optional_fixed64" ))); + EXPECT_EQ(109 , reflection->GetInt32 (message, F("optional_sfixed32"))); + EXPECT_EQ(110 , reflection->GetInt64 (message, F("optional_sfixed64"))); + EXPECT_EQ(111 , reflection->GetFloat (message, F("optional_float" ))); + EXPECT_EQ(112 , reflection->GetDouble(message, F("optional_double" ))); + EXPECT_TRUE( reflection->GetBool (message, F("optional_bool" ))); + EXPECT_EQ("115", reflection->GetString(message, F("optional_string" ))); + EXPECT_EQ("116", reflection->GetString(message, F("optional_bytes" ))); + + EXPECT_EQ("115", reflection->GetStringReference(message, F("optional_string"), &scratch)); + EXPECT_EQ("116", reflection->GetStringReference(message, F("optional_bytes" ), &scratch)); + + sub_message = &reflection->GetMessage(message, F("optionalgroup")); + EXPECT_EQ(117, sub_message->GetReflection()->GetInt32(*sub_message, group_a_)); + sub_message = &reflection->GetMessage(message, F("optional_nested_message")); + EXPECT_EQ(118, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); + sub_message = &reflection->GetMessage(message, F("optional_foreign_message")); + EXPECT_EQ(119, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); + sub_message = &reflection->GetMessage(message, F("optional_import_message")); + EXPECT_EQ(120, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); + sub_message = &reflection->GetMessage(message, F("optional_public_import_message")); + EXPECT_EQ(126, sub_message->GetReflection()->GetInt32(*sub_message, import_e_)); + sub_message = &reflection->GetMessage(message, F("optional_lazy_message")); + EXPECT_EQ(127, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); + + EXPECT_EQ( nested_baz_, reflection->GetEnum(message, F("optional_nested_enum" ))); + EXPECT_EQ(foreign_baz_, reflection->GetEnum(message, F("optional_foreign_enum"))); + EXPECT_EQ( import_baz_, reflection->GetEnum(message, F("optional_import_enum" ))); + + EXPECT_EQ("124", reflection->GetString(message, F("optional_string_piece"))); + EXPECT_EQ("124", reflection->GetStringReference(message, F("optional_string_piece"), &scratch)); + + EXPECT_EQ("125", reflection->GetString(message, F("optional_cord"))); + EXPECT_EQ("125", reflection->GetStringReference(message, F("optional_cord"), &scratch)); + +} + +void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection2( + const Message& message) { + const Reflection* reflection = message.GetReflection(); + string scratch; + const Message* sub_message; + + // ----------------------------------------------------------------- + + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int32" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int64" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint32" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint64" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint32" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint64" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed32" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed64" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed32"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed64"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_float" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_double" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bool" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bytes" ))); + + ASSERT_EQ(2, reflection->FieldSize(message, F("repeatedgroup" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_message" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_message"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_message" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_lazy_message" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_enum" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_enum" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_enum" ))); + + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string_piece"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_cord"))); + + EXPECT_EQ(201 , reflection->GetRepeatedInt32 (message, F("repeated_int32" ), 0)); + EXPECT_EQ(202 , reflection->GetRepeatedInt64 (message, F("repeated_int64" ), 0)); + EXPECT_EQ(203 , reflection->GetRepeatedUInt32(message, F("repeated_uint32" ), 0)); + EXPECT_EQ(204 , reflection->GetRepeatedUInt64(message, F("repeated_uint64" ), 0)); + EXPECT_EQ(205 , reflection->GetRepeatedInt32 (message, F("repeated_sint32" ), 0)); + EXPECT_EQ(206 , reflection->GetRepeatedInt64 (message, F("repeated_sint64" ), 0)); + EXPECT_EQ(207 , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 0)); + EXPECT_EQ(208 , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 0)); + EXPECT_EQ(209 , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 0)); + EXPECT_EQ(210 , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 0)); + EXPECT_EQ(211 , reflection->GetRepeatedFloat (message, F("repeated_float" ), 0)); + EXPECT_EQ(212 , reflection->GetRepeatedDouble(message, F("repeated_double" ), 0)); + EXPECT_TRUE( reflection->GetRepeatedBool (message, F("repeated_bool" ), 0)); + EXPECT_EQ("215", reflection->GetRepeatedString(message, F("repeated_string" ), 0)); + EXPECT_EQ("216", reflection->GetRepeatedString(message, F("repeated_bytes" ), 0)); + + EXPECT_EQ("215", reflection->GetRepeatedStringReference(message, F("repeated_string"), 0, &scratch)); + EXPECT_EQ("216", reflection->GetRepeatedStringReference(message, F("repeated_bytes"), 0, &scratch)); + + sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 0); + EXPECT_EQ(217, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_)); + sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 0); + EXPECT_EQ(218, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); + sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 0); + EXPECT_EQ(219, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); + sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 0); + EXPECT_EQ(220, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); + sub_message = &reflection->GetRepeatedMessage(message, F("repeated_lazy_message"), 0); + EXPECT_EQ(227, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); + + EXPECT_EQ( nested_bar_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),0)); + EXPECT_EQ(foreign_bar_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),0)); + EXPECT_EQ( import_bar_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),0)); + + EXPECT_EQ("224", reflection->GetRepeatedString(message, F("repeated_string_piece"), 0)); + EXPECT_EQ("224", reflection->GetRepeatedStringReference( + message, F("repeated_string_piece"), 0, &scratch)); + + EXPECT_EQ("225", reflection->GetRepeatedString(message, F("repeated_cord"), 0)); + EXPECT_EQ("225", reflection->GetRepeatedStringReference( + message, F("repeated_cord"), 0, &scratch)); + + EXPECT_EQ(301 , reflection->GetRepeatedInt32 (message, F("repeated_int32" ), 1)); + EXPECT_EQ(302 , reflection->GetRepeatedInt64 (message, F("repeated_int64" ), 1)); + EXPECT_EQ(303 , reflection->GetRepeatedUInt32(message, F("repeated_uint32" ), 1)); + EXPECT_EQ(304 , reflection->GetRepeatedUInt64(message, F("repeated_uint64" ), 1)); + EXPECT_EQ(305 , reflection->GetRepeatedInt32 (message, F("repeated_sint32" ), 1)); + EXPECT_EQ(306 , reflection->GetRepeatedInt64 (message, F("repeated_sint64" ), 1)); + EXPECT_EQ(307 , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 1)); + EXPECT_EQ(308 , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 1)); + EXPECT_EQ(309 , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 1)); + EXPECT_EQ(310 , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 1)); + EXPECT_EQ(311 , reflection->GetRepeatedFloat (message, F("repeated_float" ), 1)); + EXPECT_EQ(312 , reflection->GetRepeatedDouble(message, F("repeated_double" ), 1)); + EXPECT_FALSE( reflection->GetRepeatedBool (message, F("repeated_bool" ), 1)); + EXPECT_EQ("315", reflection->GetRepeatedString(message, F("repeated_string" ), 1)); + EXPECT_EQ("316", reflection->GetRepeatedString(message, F("repeated_bytes" ), 1)); + + EXPECT_EQ("315", reflection->GetRepeatedStringReference(message, F("repeated_string"), + 1, &scratch)); + EXPECT_EQ("316", reflection->GetRepeatedStringReference(message, F("repeated_bytes"), + 1, &scratch)); + + sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 1); + EXPECT_EQ(317, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_)); + sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 1); + EXPECT_EQ(318, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); + sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 1); + EXPECT_EQ(319, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); + sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 1); + EXPECT_EQ(320, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); + sub_message = &reflection->GetRepeatedMessage(message, F("repeated_lazy_message"), 1); + EXPECT_EQ(327, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); + + EXPECT_EQ( nested_baz_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),1)); + EXPECT_EQ(foreign_baz_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),1)); + EXPECT_EQ( import_baz_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),1)); + + EXPECT_EQ("324", reflection->GetRepeatedString(message, F("repeated_string_piece"), 1)); + EXPECT_EQ("324", reflection->GetRepeatedStringReference( + message, F("repeated_string_piece"), 1, &scratch)); + + EXPECT_EQ("325", reflection->GetRepeatedString(message, F("repeated_cord"), 1)); + EXPECT_EQ("325", reflection->GetRepeatedStringReference( + message, F("repeated_cord"), 1, &scratch)); +} + +void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection3( + const Message& message) { + const Reflection* reflection = message.GetReflection(); + string scratch; + + // ----------------------------------------------------------------- + + EXPECT_TRUE(reflection->HasField(message, F("default_int32" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_int64" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_uint32" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_uint64" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_sint32" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_sint64" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_fixed32" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_fixed64" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_sfixed32"))); + EXPECT_TRUE(reflection->HasField(message, F("default_sfixed64"))); + EXPECT_TRUE(reflection->HasField(message, F("default_float" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_double" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_bool" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_string" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_bytes" ))); + + EXPECT_TRUE(reflection->HasField(message, F("default_nested_enum" ))); + EXPECT_TRUE(reflection->HasField(message, F("default_foreign_enum"))); + EXPECT_TRUE(reflection->HasField(message, F("default_import_enum" ))); + + EXPECT_TRUE(reflection->HasField(message, F("default_string_piece"))); + EXPECT_TRUE(reflection->HasField(message, F("default_cord"))); + + EXPECT_EQ(401 , reflection->GetInt32 (message, F("default_int32" ))); + EXPECT_EQ(402 , reflection->GetInt64 (message, F("default_int64" ))); + EXPECT_EQ(403 , reflection->GetUInt32(message, F("default_uint32" ))); + EXPECT_EQ(404 , reflection->GetUInt64(message, F("default_uint64" ))); + EXPECT_EQ(405 , reflection->GetInt32 (message, F("default_sint32" ))); + EXPECT_EQ(406 , reflection->GetInt64 (message, F("default_sint64" ))); + EXPECT_EQ(407 , reflection->GetUInt32(message, F("default_fixed32" ))); + EXPECT_EQ(408 , reflection->GetUInt64(message, F("default_fixed64" ))); + EXPECT_EQ(409 , reflection->GetInt32 (message, F("default_sfixed32"))); + EXPECT_EQ(410 , reflection->GetInt64 (message, F("default_sfixed64"))); + EXPECT_EQ(411 , reflection->GetFloat (message, F("default_float" ))); + EXPECT_EQ(412 , reflection->GetDouble(message, F("default_double" ))); + EXPECT_FALSE( reflection->GetBool (message, F("default_bool" ))); + EXPECT_EQ("415", reflection->GetString(message, F("default_string" ))); + EXPECT_EQ("416", reflection->GetString(message, F("default_bytes" ))); + + EXPECT_EQ("415", reflection->GetStringReference(message, F("default_string"), &scratch)); + EXPECT_EQ("416", reflection->GetStringReference(message, F("default_bytes" ), &scratch)); + + EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("default_nested_enum" ))); + EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("default_foreign_enum"))); + EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("default_import_enum" ))); + + EXPECT_EQ("424", reflection->GetString(message, F("default_string_piece"))); + EXPECT_EQ("424", reflection->GetStringReference(message, F("default_string_piece"), + &scratch)); + + EXPECT_EQ("425", reflection->GetString(message, F("default_cord"))); + EXPECT_EQ("425", reflection->GetStringReference(message, F("default_cord"), &scratch)); +} + +void TestUtil::ReflectionTester::ExpectPackedFieldsSetViaReflection( + const Message& message) { + const Reflection* reflection = message.GetReflection(); + + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int32" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int64" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint32" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint64" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint32" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint64" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed32" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed64" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed32"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed64"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_float" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_double" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_bool" ))); + ASSERT_EQ(2, reflection->FieldSize(message, F("packed_enum" ))); + + EXPECT_EQ(601 , reflection->GetRepeatedInt32 (message, F("packed_int32" ), 0)); + EXPECT_EQ(602 , reflection->GetRepeatedInt64 (message, F("packed_int64" ), 0)); + EXPECT_EQ(603 , reflection->GetRepeatedUInt32(message, F("packed_uint32" ), 0)); + EXPECT_EQ(604 , reflection->GetRepeatedUInt64(message, F("packed_uint64" ), 0)); + EXPECT_EQ(605 , reflection->GetRepeatedInt32 (message, F("packed_sint32" ), 0)); + EXPECT_EQ(606 , reflection->GetRepeatedInt64 (message, F("packed_sint64" ), 0)); + EXPECT_EQ(607 , reflection->GetRepeatedUInt32(message, F("packed_fixed32" ), 0)); + EXPECT_EQ(608 , reflection->GetRepeatedUInt64(message, F("packed_fixed64" ), 0)); + EXPECT_EQ(609 , reflection->GetRepeatedInt32 (message, F("packed_sfixed32"), 0)); + EXPECT_EQ(610 , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 0)); + EXPECT_EQ(611 , reflection->GetRepeatedFloat (message, F("packed_float" ), 0)); + EXPECT_EQ(612 , reflection->GetRepeatedDouble(message, F("packed_double" ), 0)); + EXPECT_TRUE( reflection->GetRepeatedBool (message, F("packed_bool" ), 0)); + EXPECT_EQ(foreign_bar_, + reflection->GetRepeatedEnum(message, F("packed_enum"), 0)); + + EXPECT_EQ(701 , reflection->GetRepeatedInt32 (message, F("packed_int32" ), 1)); + EXPECT_EQ(702 , reflection->GetRepeatedInt64 (message, F("packed_int64" ), 1)); + EXPECT_EQ(703 , reflection->GetRepeatedUInt32(message, F("packed_uint32" ), 1)); + EXPECT_EQ(704 , reflection->GetRepeatedUInt64(message, F("packed_uint64" ), 1)); + EXPECT_EQ(705 , reflection->GetRepeatedInt32 (message, F("packed_sint32" ), 1)); + EXPECT_EQ(706 , reflection->GetRepeatedInt64 (message, F("packed_sint64" ), 1)); + EXPECT_EQ(707 , reflection->GetRepeatedUInt32(message, F("packed_fixed32" ), 1)); + EXPECT_EQ(708 , reflection->GetRepeatedUInt64(message, F("packed_fixed64" ), 1)); + EXPECT_EQ(709 , reflection->GetRepeatedInt32 (message, F("packed_sfixed32"), 1)); + EXPECT_EQ(710 , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 1)); + EXPECT_EQ(711 , reflection->GetRepeatedFloat (message, F("packed_float" ), 1)); + EXPECT_EQ(712 , reflection->GetRepeatedDouble(message, F("packed_double" ), 1)); + EXPECT_FALSE( reflection->GetRepeatedBool (message, F("packed_bool" ), 1)); + EXPECT_EQ(foreign_baz_, + reflection->GetRepeatedEnum(message, F("packed_enum"), 1)); +} + +// ------------------------------------------------------------------- + +void TestUtil::ReflectionTester::ExpectClearViaReflection( + const Message& message) { + const Reflection* reflection = message.GetReflection(); + string scratch; + const Message* sub_message; + + // has_blah() should initially be false for all optional fields. + EXPECT_FALSE(reflection->HasField(message, F("optional_int32" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_int64" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_uint32" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_uint64" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_sint32" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_sint64" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_fixed32" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_fixed64" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed32"))); + EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed64"))); + EXPECT_FALSE(reflection->HasField(message, F("optional_float" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_double" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_bool" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_string" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_bytes" ))); + + EXPECT_FALSE(reflection->HasField(message, F("optionalgroup" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_nested_message" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_message"))); + EXPECT_FALSE(reflection->HasField(message, F("optional_import_message" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_public_import_message"))); + EXPECT_FALSE(reflection->HasField(message, F("optional_lazy_message"))); + + EXPECT_FALSE(reflection->HasField(message, F("optional_nested_enum" ))); + EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_enum"))); + EXPECT_FALSE(reflection->HasField(message, F("optional_import_enum" ))); + + EXPECT_FALSE(reflection->HasField(message, F("optional_string_piece"))); + EXPECT_FALSE(reflection->HasField(message, F("optional_cord"))); + + // Optional fields without defaults are set to zero or something like it. + EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_int32" ))); + EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_int64" ))); + EXPECT_EQ(0 , reflection->GetUInt32(message, F("optional_uint32" ))); + EXPECT_EQ(0 , reflection->GetUInt64(message, F("optional_uint64" ))); + EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_sint32" ))); + EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_sint64" ))); + EXPECT_EQ(0 , reflection->GetUInt32(message, F("optional_fixed32" ))); + EXPECT_EQ(0 , reflection->GetUInt64(message, F("optional_fixed64" ))); + EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_sfixed32"))); + EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_sfixed64"))); + EXPECT_EQ(0 , reflection->GetFloat (message, F("optional_float" ))); + EXPECT_EQ(0 , reflection->GetDouble(message, F("optional_double" ))); + EXPECT_FALSE( reflection->GetBool (message, F("optional_bool" ))); + EXPECT_EQ("" , reflection->GetString(message, F("optional_string" ))); + EXPECT_EQ("" , reflection->GetString(message, F("optional_bytes" ))); + + EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string"), &scratch)); + EXPECT_EQ("", reflection->GetStringReference(message, F("optional_bytes" ), &scratch)); + + // Embedded messages should also be clear. + sub_message = &reflection->GetMessage(message, F("optionalgroup")); + EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, group_a_)); + EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, group_a_)); + sub_message = &reflection->GetMessage(message, F("optional_nested_message")); + EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, nested_b_)); + EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); + sub_message = &reflection->GetMessage(message, F("optional_foreign_message")); + EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_)); + EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); + sub_message = &reflection->GetMessage(message, F("optional_import_message")); + EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_d_)); + EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); + sub_message = &reflection->GetMessage(message, F("optional_public_import_message")); + EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_e_)); + EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_e_)); + sub_message = &reflection->GetMessage(message, F("optional_lazy_message")); + EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, nested_b_)); + EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); + + // Enums without defaults are set to the first value in the enum. + EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("optional_nested_enum" ))); + EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("optional_foreign_enum"))); + EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("optional_import_enum" ))); + + EXPECT_EQ("", reflection->GetString(message, F("optional_string_piece"))); + EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string_piece"), &scratch)); + + EXPECT_EQ("", reflection->GetString(message, F("optional_cord"))); + EXPECT_EQ("", reflection->GetStringReference(message, F("optional_cord"), &scratch)); + + // Repeated fields are empty. + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int32" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int64" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint32" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint64" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint32" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint64" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed32" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed64" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed32"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed64"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_float" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_double" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bool" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bytes" ))); + + EXPECT_EQ(0, reflection->FieldSize(message, F("repeatedgroup" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_message" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_message"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_message" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_lazy_message" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_enum" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_enum" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_enum" ))); + + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string_piece"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_cord"))); + + // has_blah() should also be false for all default fields. + EXPECT_FALSE(reflection->HasField(message, F("default_int32" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_int64" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_uint32" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_uint64" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_sint32" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_sint64" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_fixed32" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_fixed64" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_sfixed32"))); + EXPECT_FALSE(reflection->HasField(message, F("default_sfixed64"))); + EXPECT_FALSE(reflection->HasField(message, F("default_float" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_double" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_bool" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_string" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_bytes" ))); + + EXPECT_FALSE(reflection->HasField(message, F("default_nested_enum" ))); + EXPECT_FALSE(reflection->HasField(message, F("default_foreign_enum"))); + EXPECT_FALSE(reflection->HasField(message, F("default_import_enum" ))); + + EXPECT_FALSE(reflection->HasField(message, F("default_string_piece"))); + EXPECT_FALSE(reflection->HasField(message, F("default_cord"))); + + // Fields with defaults have their default values (duh). + EXPECT_EQ( 41 , reflection->GetInt32 (message, F("default_int32" ))); + EXPECT_EQ( 42 , reflection->GetInt64 (message, F("default_int64" ))); + EXPECT_EQ( 43 , reflection->GetUInt32(message, F("default_uint32" ))); + EXPECT_EQ( 44 , reflection->GetUInt64(message, F("default_uint64" ))); + EXPECT_EQ(-45 , reflection->GetInt32 (message, F("default_sint32" ))); + EXPECT_EQ( 46 , reflection->GetInt64 (message, F("default_sint64" ))); + EXPECT_EQ( 47 , reflection->GetUInt32(message, F("default_fixed32" ))); + EXPECT_EQ( 48 , reflection->GetUInt64(message, F("default_fixed64" ))); + EXPECT_EQ( 49 , reflection->GetInt32 (message, F("default_sfixed32"))); + EXPECT_EQ(-50 , reflection->GetInt64 (message, F("default_sfixed64"))); + EXPECT_EQ( 51.5 , reflection->GetFloat (message, F("default_float" ))); + EXPECT_EQ( 52e3 , reflection->GetDouble(message, F("default_double" ))); + EXPECT_TRUE( reflection->GetBool (message, F("default_bool" ))); + EXPECT_EQ("hello", reflection->GetString(message, F("default_string" ))); + EXPECT_EQ("world", reflection->GetString(message, F("default_bytes" ))); + + EXPECT_EQ("hello", reflection->GetStringReference(message, F("default_string"), &scratch)); + EXPECT_EQ("world", reflection->GetStringReference(message, F("default_bytes" ), &scratch)); + + EXPECT_EQ( nested_bar_, reflection->GetEnum(message, F("default_nested_enum" ))); + EXPECT_EQ(foreign_bar_, reflection->GetEnum(message, F("default_foreign_enum"))); + EXPECT_EQ( import_bar_, reflection->GetEnum(message, F("default_import_enum" ))); + + EXPECT_EQ("abc", reflection->GetString(message, F("default_string_piece"))); + EXPECT_EQ("abc", reflection->GetStringReference(message, F("default_string_piece"), &scratch)); + + EXPECT_EQ("123", reflection->GetString(message, F("default_cord"))); + EXPECT_EQ("123", reflection->GetStringReference(message, F("default_cord"), &scratch)); +} + +void TestUtil::ReflectionTester::ExpectPackedClearViaReflection( + const Message& message) { + const Reflection* reflection = message.GetReflection(); + + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int32" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int64" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint32" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint64" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint32" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint64" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed32" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed64" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed32"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed64"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_float" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_double" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_bool" ))); + EXPECT_EQ(0, reflection->FieldSize(message, F("packed_enum" ))); +} + +// ------------------------------------------------------------------- + +void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection( + Message* message) { + const Reflection* reflection = message->GetReflection(); + Message* sub_message; + + reflection->SetRepeatedInt32 (message, F("repeated_int32" ), 1, 501); + reflection->SetRepeatedInt64 (message, F("repeated_int64" ), 1, 502); + reflection->SetRepeatedUInt32(message, F("repeated_uint32" ), 1, 503); + reflection->SetRepeatedUInt64(message, F("repeated_uint64" ), 1, 504); + reflection->SetRepeatedInt32 (message, F("repeated_sint32" ), 1, 505); + reflection->SetRepeatedInt64 (message, F("repeated_sint64" ), 1, 506); + reflection->SetRepeatedUInt32(message, F("repeated_fixed32" ), 1, 507); + reflection->SetRepeatedUInt64(message, F("repeated_fixed64" ), 1, 508); + reflection->SetRepeatedInt32 (message, F("repeated_sfixed32"), 1, 509); + reflection->SetRepeatedInt64 (message, F("repeated_sfixed64"), 1, 510); + reflection->SetRepeatedFloat (message, F("repeated_float" ), 1, 511); + reflection->SetRepeatedDouble(message, F("repeated_double" ), 1, 512); + reflection->SetRepeatedBool (message, F("repeated_bool" ), 1, true); + reflection->SetRepeatedString(message, F("repeated_string" ), 1, "515"); + reflection->SetRepeatedString(message, F("repeated_bytes" ), 1, "516"); + + sub_message = reflection->MutableRepeatedMessage(message, F("repeatedgroup"), 1); + sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 517); + sub_message = reflection->MutableRepeatedMessage(message, F("repeated_nested_message"), 1); + sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 518); + sub_message = reflection->MutableRepeatedMessage(message, F("repeated_foreign_message"), 1); + sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 519); + sub_message = reflection->MutableRepeatedMessage(message, F("repeated_import_message"), 1); + sub_message->GetReflection()->SetInt32(sub_message, import_d_, 520); + sub_message = reflection->MutableRepeatedMessage(message, F("repeated_lazy_message"), 1); + sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 527); + + reflection->SetRepeatedEnum(message, F("repeated_nested_enum" ), 1, nested_foo_); + reflection->SetRepeatedEnum(message, F("repeated_foreign_enum"), 1, foreign_foo_); + reflection->SetRepeatedEnum(message, F("repeated_import_enum" ), 1, import_foo_); + + reflection->SetRepeatedString(message, F("repeated_string_piece"), 1, "524"); + reflection->SetRepeatedString(message, F("repeated_cord"), 1, "525"); +} + +void TestUtil::ReflectionTester::ModifyPackedFieldsViaReflection( + Message* message) { + const Reflection* reflection = message->GetReflection(); + reflection->SetRepeatedInt32 (message, F("packed_int32" ), 1, 801); + reflection->SetRepeatedInt64 (message, F("packed_int64" ), 1, 802); + reflection->SetRepeatedUInt32(message, F("packed_uint32" ), 1, 803); + reflection->SetRepeatedUInt64(message, F("packed_uint64" ), 1, 804); + reflection->SetRepeatedInt32 (message, F("packed_sint32" ), 1, 805); + reflection->SetRepeatedInt64 (message, F("packed_sint64" ), 1, 806); + reflection->SetRepeatedUInt32(message, F("packed_fixed32" ), 1, 807); + reflection->SetRepeatedUInt64(message, F("packed_fixed64" ), 1, 808); + reflection->SetRepeatedInt32 (message, F("packed_sfixed32"), 1, 809); + reflection->SetRepeatedInt64 (message, F("packed_sfixed64"), 1, 810); + reflection->SetRepeatedFloat (message, F("packed_float" ), 1, 811); + reflection->SetRepeatedDouble(message, F("packed_double" ), 1, 812); + reflection->SetRepeatedBool (message, F("packed_bool" ), 1, true); + reflection->SetRepeatedEnum (message, F("packed_enum" ), 1, foreign_foo_); +} + +void TestUtil::ReflectionTester::RemoveLastRepeatedsViaReflection( + Message* message) { + const Reflection* reflection = message->GetReflection(); + + vector output; + reflection->ListFields(*message, &output); + for (int i=0; iis_repeated()) continue; + + reflection->RemoveLast(message, field); + } +} + +void TestUtil::ReflectionTester::ReleaseLastRepeatedsViaReflection( + Message* message, bool expect_extensions_notnull) { + const Reflection* reflection = message->GetReflection(); + + vector output; + reflection->ListFields(*message, &output); + for (int i=0; iis_repeated()) continue; + if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue; + + Message* released = reflection->ReleaseLast(message, field); + if (!field->is_extension() || expect_extensions_notnull) { + ASSERT_TRUE(released != NULL) << "ReleaseLast returned NULL for: " + << field->name(); + } + delete released; + } +} + +void TestUtil::ReflectionTester::SwapRepeatedsViaReflection(Message* message) { + const Reflection* reflection = message->GetReflection(); + + vector output; + reflection->ListFields(*message, &output); + for (int i=0; iis_repeated()) continue; + + reflection->SwapElements(message, field, 0, 1); + } +} + +void TestUtil::ReflectionTester::ExpectMessagesReleasedViaReflection( + Message* message, + TestUtil::ReflectionTester::MessageReleaseState expected_release_state) { + const Reflection* reflection = message->GetReflection(); + + static const char* fields[] = { + "optionalgroup", + "optional_nested_message", + "optional_foreign_message", + "optional_import_message", + }; + for (int i = 0; i < GOOGLE_ARRAYSIZE(fields); i++) { + const Message& sub_message = reflection->GetMessage(*message, F(fields[i])); + Message* released = reflection->ReleaseMessage(message, F(fields[i])); + switch (expected_release_state) { + case IS_NULL: + EXPECT_TRUE(released == NULL); + break; + case NOT_NULL: + EXPECT_TRUE(released != NULL); + EXPECT_EQ(&sub_message, released); + break; + case CAN_BE_NULL: + break; + } + delete released; + EXPECT_FALSE(reflection->HasField(*message, F(fields[i]))); + } +} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util.h new file mode 100644 index 0000000..4551957 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util.h @@ -0,0 +1,193 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_TEST_UTIL_H__ +#define GOOGLE_PROTOBUF_TEST_UTIL_H__ + +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +namespace unittest = ::protobuf_unittest; +namespace unittest_import = protobuf_unittest_import; + +class TestUtil { + public: + // Set every field in the message to a unique value. + static void SetAllFields(unittest::TestAllTypes* message); + static void SetOptionalFields(unittest::TestAllTypes* message); + static void AddRepeatedFields1(unittest::TestAllTypes* message); + static void AddRepeatedFields2(unittest::TestAllTypes* message); + static void SetDefaultFields(unittest::TestAllTypes* message); + static void SetAllExtensions(unittest::TestAllExtensions* message); + static void SetAllFieldsAndExtensions(unittest::TestFieldOrderings* message); + static void SetPackedFields(unittest::TestPackedTypes* message); + static void SetPackedExtensions(unittest::TestPackedExtensions* message); + static void SetUnpackedFields(unittest::TestUnpackedTypes* message); + + // Use the repeated versions of the set_*() accessors to modify all the + // repeated fields of the messsage (which should already have been + // initialized with Set*Fields()). Set*Fields() itself only tests + // the add_*() accessors. + static void ModifyRepeatedFields(unittest::TestAllTypes* message); + static void ModifyRepeatedExtensions(unittest::TestAllExtensions* message); + static void ModifyPackedFields(unittest::TestPackedTypes* message); + static void ModifyPackedExtensions(unittest::TestPackedExtensions* message); + + // Check that all fields have the values that they should have after + // Set*Fields() is called. + static void ExpectAllFieldsSet(const unittest::TestAllTypes& message); + static void ExpectAllExtensionsSet( + const unittest::TestAllExtensions& message); + static void ExpectPackedFieldsSet(const unittest::TestPackedTypes& message); + static void ExpectPackedExtensionsSet( + const unittest::TestPackedExtensions& message); + static void ExpectUnpackedFieldsSet( + const unittest::TestUnpackedTypes& message); + + // Expect that the message is modified as would be expected from + // Modify*Fields(). + static void ExpectRepeatedFieldsModified( + const unittest::TestAllTypes& message); + static void ExpectRepeatedExtensionsModified( + const unittest::TestAllExtensions& message); + static void ExpectPackedFieldsModified( + const unittest::TestPackedTypes& message); + static void ExpectPackedExtensionsModified( + const unittest::TestPackedExtensions& message); + + // Check that all fields have their default values. + static void ExpectClear(const unittest::TestAllTypes& message); + static void ExpectExtensionsClear(const unittest::TestAllExtensions& message); + static void ExpectPackedClear(const unittest::TestPackedTypes& message); + static void ExpectPackedExtensionsClear( + const unittest::TestPackedExtensions& message); + + // Check that the passed-in serialization is the canonical serialization we + // expect for a TestFieldOrderings message filled in by + // SetAllFieldsAndExtensions(). + static void ExpectAllFieldsAndExtensionsInOrder(const string& serialized); + + // Check that all repeated fields have had their last elements removed. + static void ExpectLastRepeatedsRemoved( + const unittest::TestAllTypes& message); + static void ExpectLastRepeatedExtensionsRemoved( + const unittest::TestAllExtensions& message); + static void ExpectLastRepeatedsReleased( + const unittest::TestAllTypes& message); + static void ExpectLastRepeatedExtensionsReleased( + const unittest::TestAllExtensions& message); + + // Check that all repeated fields have had their first and last elements + // swapped. + static void ExpectRepeatedsSwapped(const unittest::TestAllTypes& message); + static void ExpectRepeatedExtensionsSwapped( + const unittest::TestAllExtensions& message); + + // Like above, but use the reflection interface. + class ReflectionTester { + public: + // base_descriptor must be a descriptor for TestAllTypes or + // TestAllExtensions. In the former case, ReflectionTester fetches from + // it the FieldDescriptors needed to use the reflection interface. In + // the latter case, ReflectionTester searches for extension fields in + // its file. + explicit ReflectionTester(const Descriptor* base_descriptor); + + void SetAllFieldsViaReflection(Message* message); + void ModifyRepeatedFieldsViaReflection(Message* message); + void ExpectAllFieldsSetViaReflection(const Message& message); + void ExpectClearViaReflection(const Message& message); + + void SetPackedFieldsViaReflection(Message* message); + void ModifyPackedFieldsViaReflection(Message* message); + void ExpectPackedFieldsSetViaReflection(const Message& message); + void ExpectPackedClearViaReflection(const Message& message); + + void RemoveLastRepeatedsViaReflection(Message* message); + void ReleaseLastRepeatedsViaReflection( + Message* message, bool expect_extensions_notnull); + void SwapRepeatedsViaReflection(Message* message); + + enum MessageReleaseState { + IS_NULL, + CAN_BE_NULL, + NOT_NULL, + }; + void ExpectMessagesReleasedViaReflection( + Message* message, MessageReleaseState expected_release_state); + + private: + const FieldDescriptor* F(const string& name); + + const Descriptor* base_descriptor_; + + const FieldDescriptor* group_a_; + const FieldDescriptor* repeated_group_a_; + const FieldDescriptor* nested_b_; + const FieldDescriptor* foreign_c_; + const FieldDescriptor* import_d_; + const FieldDescriptor* import_e_; + + const EnumValueDescriptor* nested_foo_; + const EnumValueDescriptor* nested_bar_; + const EnumValueDescriptor* nested_baz_; + const EnumValueDescriptor* foreign_foo_; + const EnumValueDescriptor* foreign_bar_; + const EnumValueDescriptor* foreign_baz_; + const EnumValueDescriptor* import_foo_; + const EnumValueDescriptor* import_bar_; + const EnumValueDescriptor* import_baz_; + + // We have to split this into three function otherwise it creates a stack + // frame so large that it triggers a warning. + void ExpectAllFieldsSetViaReflection1(const Message& message); + void ExpectAllFieldsSetViaReflection2(const Message& message); + void ExpectAllFieldsSetViaReflection3(const Message& message); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionTester); + }; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtil); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_TEST_UTIL_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util_lite.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util_lite.cc new file mode 100644 index 0000000..9099292 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util_lite.cc @@ -0,0 +1,1548 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include + + +#define EXPECT_TRUE GOOGLE_CHECK +#define ASSERT_TRUE GOOGLE_CHECK +#define EXPECT_FALSE(COND) GOOGLE_CHECK(!(COND)) +#define EXPECT_EQ GOOGLE_CHECK_EQ +#define ASSERT_EQ GOOGLE_CHECK_EQ + +namespace google { +namespace protobuf { + +void TestUtilLite::SetAllFields(unittest::TestAllTypesLite* message) { + message->set_optional_int32 (101); + message->set_optional_int64 (102); + message->set_optional_uint32 (103); + message->set_optional_uint64 (104); + message->set_optional_sint32 (105); + message->set_optional_sint64 (106); + message->set_optional_fixed32 (107); + message->set_optional_fixed64 (108); + message->set_optional_sfixed32(109); + message->set_optional_sfixed64(110); + message->set_optional_float (111); + message->set_optional_double (112); + message->set_optional_bool (true); + message->set_optional_string ("115"); + message->set_optional_bytes ("116"); + + message->mutable_optionalgroup ()->set_a(117); + message->mutable_optional_nested_message ()->set_bb(118); + message->mutable_optional_foreign_message ()->set_c(119); + message->mutable_optional_import_message ()->set_d(120); + message->mutable_optional_public_import_message()->set_e(126); + message->mutable_optional_lazy_message ()->set_bb(127); + + message->set_optional_nested_enum (unittest::TestAllTypesLite::BAZ ); + message->set_optional_foreign_enum(unittest::FOREIGN_LITE_BAZ ); + message->set_optional_import_enum (unittest_import::IMPORT_LITE_BAZ); + + + // ----------------------------------------------------------------- + + message->add_repeated_int32 (201); + message->add_repeated_int64 (202); + message->add_repeated_uint32 (203); + message->add_repeated_uint64 (204); + message->add_repeated_sint32 (205); + message->add_repeated_sint64 (206); + message->add_repeated_fixed32 (207); + message->add_repeated_fixed64 (208); + message->add_repeated_sfixed32(209); + message->add_repeated_sfixed64(210); + message->add_repeated_float (211); + message->add_repeated_double (212); + message->add_repeated_bool (true); + message->add_repeated_string ("215"); + message->add_repeated_bytes ("216"); + + message->add_repeatedgroup ()->set_a(217); + message->add_repeated_nested_message ()->set_bb(218); + message->add_repeated_foreign_message()->set_c(219); + message->add_repeated_import_message ()->set_d(220); + message->add_repeated_lazy_message ()->set_bb(227); + + message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAR ); + message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAR ); + message->add_repeated_import_enum (unittest_import::IMPORT_LITE_BAR); + + + // Add a second one of each field. + message->add_repeated_int32 (301); + message->add_repeated_int64 (302); + message->add_repeated_uint32 (303); + message->add_repeated_uint64 (304); + message->add_repeated_sint32 (305); + message->add_repeated_sint64 (306); + message->add_repeated_fixed32 (307); + message->add_repeated_fixed64 (308); + message->add_repeated_sfixed32(309); + message->add_repeated_sfixed64(310); + message->add_repeated_float (311); + message->add_repeated_double (312); + message->add_repeated_bool (false); + message->add_repeated_string ("315"); + message->add_repeated_bytes ("316"); + + message->add_repeatedgroup ()->set_a(317); + message->add_repeated_nested_message ()->set_bb(318); + message->add_repeated_foreign_message()->set_c(319); + message->add_repeated_import_message ()->set_d(320); + message->add_repeated_lazy_message ()->set_bb(327); + + message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAZ ); + message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAZ ); + message->add_repeated_import_enum (unittest_import::IMPORT_LITE_BAZ); + + + // ----------------------------------------------------------------- + + message->set_default_int32 (401); + message->set_default_int64 (402); + message->set_default_uint32 (403); + message->set_default_uint64 (404); + message->set_default_sint32 (405); + message->set_default_sint64 (406); + message->set_default_fixed32 (407); + message->set_default_fixed64 (408); + message->set_default_sfixed32(409); + message->set_default_sfixed64(410); + message->set_default_float (411); + message->set_default_double (412); + message->set_default_bool (false); + message->set_default_string ("415"); + message->set_default_bytes ("416"); + + message->set_default_nested_enum (unittest::TestAllTypesLite::FOO ); + message->set_default_foreign_enum(unittest::FOREIGN_LITE_FOO ); + message->set_default_import_enum (unittest_import::IMPORT_LITE_FOO); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ModifyRepeatedFields(unittest::TestAllTypesLite* message) { + message->set_repeated_int32 (1, 501); + message->set_repeated_int64 (1, 502); + message->set_repeated_uint32 (1, 503); + message->set_repeated_uint64 (1, 504); + message->set_repeated_sint32 (1, 505); + message->set_repeated_sint64 (1, 506); + message->set_repeated_fixed32 (1, 507); + message->set_repeated_fixed64 (1, 508); + message->set_repeated_sfixed32(1, 509); + message->set_repeated_sfixed64(1, 510); + message->set_repeated_float (1, 511); + message->set_repeated_double (1, 512); + message->set_repeated_bool (1, true); + message->set_repeated_string (1, "515"); + message->set_repeated_bytes (1, "516"); + + message->mutable_repeatedgroup (1)->set_a(517); + message->mutable_repeated_nested_message (1)->set_bb(518); + message->mutable_repeated_foreign_message(1)->set_c(519); + message->mutable_repeated_import_message (1)->set_d(520); + message->mutable_repeated_lazy_message (1)->set_bb(527); + + message->set_repeated_nested_enum (1, unittest::TestAllTypesLite::FOO ); + message->set_repeated_foreign_enum(1, unittest::FOREIGN_LITE_FOO ); + message->set_repeated_import_enum (1, unittest_import::IMPORT_LITE_FOO); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectAllFieldsSet( + const unittest::TestAllTypesLite& message) { + EXPECT_TRUE(message.has_optional_int32 ()); + EXPECT_TRUE(message.has_optional_int64 ()); + EXPECT_TRUE(message.has_optional_uint32 ()); + EXPECT_TRUE(message.has_optional_uint64 ()); + EXPECT_TRUE(message.has_optional_sint32 ()); + EXPECT_TRUE(message.has_optional_sint64 ()); + EXPECT_TRUE(message.has_optional_fixed32 ()); + EXPECT_TRUE(message.has_optional_fixed64 ()); + EXPECT_TRUE(message.has_optional_sfixed32()); + EXPECT_TRUE(message.has_optional_sfixed64()); + EXPECT_TRUE(message.has_optional_float ()); + EXPECT_TRUE(message.has_optional_double ()); + EXPECT_TRUE(message.has_optional_bool ()); + EXPECT_TRUE(message.has_optional_string ()); + EXPECT_TRUE(message.has_optional_bytes ()); + + EXPECT_TRUE(message.has_optionalgroup ()); + EXPECT_TRUE(message.has_optional_nested_message ()); + EXPECT_TRUE(message.has_optional_foreign_message ()); + EXPECT_TRUE(message.has_optional_import_message ()); + EXPECT_TRUE(message.has_optional_public_import_message()); + EXPECT_TRUE(message.has_optional_lazy_message ()); + + EXPECT_TRUE(message.optionalgroup ().has_a()); + EXPECT_TRUE(message.optional_nested_message ().has_bb()); + EXPECT_TRUE(message.optional_foreign_message ().has_c()); + EXPECT_TRUE(message.optional_import_message ().has_d()); + EXPECT_TRUE(message.optional_public_import_message().has_e()); + EXPECT_TRUE(message.optional_lazy_message ().has_bb()); + + EXPECT_TRUE(message.has_optional_nested_enum ()); + EXPECT_TRUE(message.has_optional_foreign_enum()); + EXPECT_TRUE(message.has_optional_import_enum ()); + + + EXPECT_EQ(101 , message.optional_int32 ()); + EXPECT_EQ(102 , message.optional_int64 ()); + EXPECT_EQ(103 , message.optional_uint32 ()); + EXPECT_EQ(104 , message.optional_uint64 ()); + EXPECT_EQ(105 , message.optional_sint32 ()); + EXPECT_EQ(106 , message.optional_sint64 ()); + EXPECT_EQ(107 , message.optional_fixed32 ()); + EXPECT_EQ(108 , message.optional_fixed64 ()); + EXPECT_EQ(109 , message.optional_sfixed32()); + EXPECT_EQ(110 , message.optional_sfixed64()); + EXPECT_EQ(111 , message.optional_float ()); + EXPECT_EQ(112 , message.optional_double ()); + EXPECT_EQ(true , message.optional_bool ()); + EXPECT_EQ("115", message.optional_string ()); + EXPECT_EQ("116", message.optional_bytes ()); + + EXPECT_EQ(117, message.optionalgroup ().a()); + EXPECT_EQ(118, message.optional_nested_message ().bb()); + EXPECT_EQ(119, message.optional_foreign_message ().c()); + EXPECT_EQ(120, message.optional_import_message ().d()); + EXPECT_EQ(126, message.optional_public_import_message().e()); + EXPECT_EQ(127, message.optional_lazy_message ().bb()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.optional_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.optional_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.optional_import_enum ()); + + + // ----------------------------------------------------------------- + + ASSERT_EQ(2, message.repeated_int32_size ()); + ASSERT_EQ(2, message.repeated_int64_size ()); + ASSERT_EQ(2, message.repeated_uint32_size ()); + ASSERT_EQ(2, message.repeated_uint64_size ()); + ASSERT_EQ(2, message.repeated_sint32_size ()); + ASSERT_EQ(2, message.repeated_sint64_size ()); + ASSERT_EQ(2, message.repeated_fixed32_size ()); + ASSERT_EQ(2, message.repeated_fixed64_size ()); + ASSERT_EQ(2, message.repeated_sfixed32_size()); + ASSERT_EQ(2, message.repeated_sfixed64_size()); + ASSERT_EQ(2, message.repeated_float_size ()); + ASSERT_EQ(2, message.repeated_double_size ()); + ASSERT_EQ(2, message.repeated_bool_size ()); + ASSERT_EQ(2, message.repeated_string_size ()); + ASSERT_EQ(2, message.repeated_bytes_size ()); + + ASSERT_EQ(2, message.repeatedgroup_size ()); + ASSERT_EQ(2, message.repeated_nested_message_size ()); + ASSERT_EQ(2, message.repeated_foreign_message_size()); + ASSERT_EQ(2, message.repeated_import_message_size ()); + ASSERT_EQ(2, message.repeated_lazy_message_size ()); + ASSERT_EQ(2, message.repeated_nested_enum_size ()); + ASSERT_EQ(2, message.repeated_foreign_enum_size ()); + ASSERT_EQ(2, message.repeated_import_enum_size ()); + + + EXPECT_EQ(201 , message.repeated_int32 (0)); + EXPECT_EQ(202 , message.repeated_int64 (0)); + EXPECT_EQ(203 , message.repeated_uint32 (0)); + EXPECT_EQ(204 , message.repeated_uint64 (0)); + EXPECT_EQ(205 , message.repeated_sint32 (0)); + EXPECT_EQ(206 , message.repeated_sint64 (0)); + EXPECT_EQ(207 , message.repeated_fixed32 (0)); + EXPECT_EQ(208 , message.repeated_fixed64 (0)); + EXPECT_EQ(209 , message.repeated_sfixed32(0)); + EXPECT_EQ(210 , message.repeated_sfixed64(0)); + EXPECT_EQ(211 , message.repeated_float (0)); + EXPECT_EQ(212 , message.repeated_double (0)); + EXPECT_EQ(true , message.repeated_bool (0)); + EXPECT_EQ("215", message.repeated_string (0)); + EXPECT_EQ("216", message.repeated_bytes (0)); + + EXPECT_EQ(217, message.repeatedgroup (0).a()); + EXPECT_EQ(218, message.repeated_nested_message (0).bb()); + EXPECT_EQ(219, message.repeated_foreign_message(0).c()); + EXPECT_EQ(220, message.repeated_import_message (0).d()); + EXPECT_EQ(227, message.repeated_lazy_message (0).bb()); + + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.repeated_foreign_enum(0)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.repeated_import_enum (0)); + + EXPECT_EQ(301 , message.repeated_int32 (1)); + EXPECT_EQ(302 , message.repeated_int64 (1)); + EXPECT_EQ(303 , message.repeated_uint32 (1)); + EXPECT_EQ(304 , message.repeated_uint64 (1)); + EXPECT_EQ(305 , message.repeated_sint32 (1)); + EXPECT_EQ(306 , message.repeated_sint64 (1)); + EXPECT_EQ(307 , message.repeated_fixed32 (1)); + EXPECT_EQ(308 , message.repeated_fixed64 (1)); + EXPECT_EQ(309 , message.repeated_sfixed32(1)); + EXPECT_EQ(310 , message.repeated_sfixed64(1)); + EXPECT_EQ(311 , message.repeated_float (1)); + EXPECT_EQ(312 , message.repeated_double (1)); + EXPECT_EQ(false, message.repeated_bool (1)); + EXPECT_EQ("315", message.repeated_string (1)); + EXPECT_EQ("316", message.repeated_bytes (1)); + + EXPECT_EQ(317, message.repeatedgroup (1).a()); + EXPECT_EQ(318, message.repeated_nested_message (1).bb()); + EXPECT_EQ(319, message.repeated_foreign_message(1).c()); + EXPECT_EQ(320, message.repeated_import_message (1).d()); + EXPECT_EQ(327, message.repeated_lazy_message (1).bb()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.repeated_nested_enum (1)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.repeated_foreign_enum(1)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.repeated_import_enum (1)); + + + // ----------------------------------------------------------------- + + EXPECT_TRUE(message.has_default_int32 ()); + EXPECT_TRUE(message.has_default_int64 ()); + EXPECT_TRUE(message.has_default_uint32 ()); + EXPECT_TRUE(message.has_default_uint64 ()); + EXPECT_TRUE(message.has_default_sint32 ()); + EXPECT_TRUE(message.has_default_sint64 ()); + EXPECT_TRUE(message.has_default_fixed32 ()); + EXPECT_TRUE(message.has_default_fixed64 ()); + EXPECT_TRUE(message.has_default_sfixed32()); + EXPECT_TRUE(message.has_default_sfixed64()); + EXPECT_TRUE(message.has_default_float ()); + EXPECT_TRUE(message.has_default_double ()); + EXPECT_TRUE(message.has_default_bool ()); + EXPECT_TRUE(message.has_default_string ()); + EXPECT_TRUE(message.has_default_bytes ()); + + EXPECT_TRUE(message.has_default_nested_enum ()); + EXPECT_TRUE(message.has_default_foreign_enum()); + EXPECT_TRUE(message.has_default_import_enum ()); + + + EXPECT_EQ(401 , message.default_int32 ()); + EXPECT_EQ(402 , message.default_int64 ()); + EXPECT_EQ(403 , message.default_uint32 ()); + EXPECT_EQ(404 , message.default_uint64 ()); + EXPECT_EQ(405 , message.default_sint32 ()); + EXPECT_EQ(406 , message.default_sint64 ()); + EXPECT_EQ(407 , message.default_fixed32 ()); + EXPECT_EQ(408 , message.default_fixed64 ()); + EXPECT_EQ(409 , message.default_sfixed32()); + EXPECT_EQ(410 , message.default_sfixed64()); + EXPECT_EQ(411 , message.default_float ()); + EXPECT_EQ(412 , message.default_double ()); + EXPECT_EQ(false, message.default_bool ()); + EXPECT_EQ("415", message.default_string ()); + EXPECT_EQ("416", message.default_bytes ()); + + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.default_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.default_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.default_import_enum ()); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectClear(const unittest::TestAllTypesLite& message) { + // has_blah() should initially be false for all optional fields. + EXPECT_FALSE(message.has_optional_int32 ()); + EXPECT_FALSE(message.has_optional_int64 ()); + EXPECT_FALSE(message.has_optional_uint32 ()); + EXPECT_FALSE(message.has_optional_uint64 ()); + EXPECT_FALSE(message.has_optional_sint32 ()); + EXPECT_FALSE(message.has_optional_sint64 ()); + EXPECT_FALSE(message.has_optional_fixed32 ()); + EXPECT_FALSE(message.has_optional_fixed64 ()); + EXPECT_FALSE(message.has_optional_sfixed32()); + EXPECT_FALSE(message.has_optional_sfixed64()); + EXPECT_FALSE(message.has_optional_float ()); + EXPECT_FALSE(message.has_optional_double ()); + EXPECT_FALSE(message.has_optional_bool ()); + EXPECT_FALSE(message.has_optional_string ()); + EXPECT_FALSE(message.has_optional_bytes ()); + + EXPECT_FALSE(message.has_optionalgroup ()); + EXPECT_FALSE(message.has_optional_nested_message ()); + EXPECT_FALSE(message.has_optional_foreign_message ()); + EXPECT_FALSE(message.has_optional_import_message ()); + EXPECT_FALSE(message.has_optional_public_import_message()); + EXPECT_FALSE(message.has_optional_lazy_message ()); + + EXPECT_FALSE(message.has_optional_nested_enum ()); + EXPECT_FALSE(message.has_optional_foreign_enum()); + EXPECT_FALSE(message.has_optional_import_enum ()); + + + // Optional fields without defaults are set to zero or something like it. + EXPECT_EQ(0 , message.optional_int32 ()); + EXPECT_EQ(0 , message.optional_int64 ()); + EXPECT_EQ(0 , message.optional_uint32 ()); + EXPECT_EQ(0 , message.optional_uint64 ()); + EXPECT_EQ(0 , message.optional_sint32 ()); + EXPECT_EQ(0 , message.optional_sint64 ()); + EXPECT_EQ(0 , message.optional_fixed32 ()); + EXPECT_EQ(0 , message.optional_fixed64 ()); + EXPECT_EQ(0 , message.optional_sfixed32()); + EXPECT_EQ(0 , message.optional_sfixed64()); + EXPECT_EQ(0 , message.optional_float ()); + EXPECT_EQ(0 , message.optional_double ()); + EXPECT_EQ(false, message.optional_bool ()); + EXPECT_EQ("" , message.optional_string ()); + EXPECT_EQ("" , message.optional_bytes ()); + + // Embedded messages should also be clear. + EXPECT_FALSE(message.optionalgroup ().has_a()); + EXPECT_FALSE(message.optional_nested_message ().has_bb()); + EXPECT_FALSE(message.optional_foreign_message ().has_c()); + EXPECT_FALSE(message.optional_import_message ().has_d()); + EXPECT_FALSE(message.optional_public_import_message().has_e()); + EXPECT_FALSE(message.optional_lazy_message ().has_bb()); + + EXPECT_EQ(0, message.optionalgroup ().a()); + EXPECT_EQ(0, message.optional_nested_message ().bb()); + EXPECT_EQ(0, message.optional_foreign_message().c()); + EXPECT_EQ(0, message.optional_import_message ().d()); + + // Enums without defaults are set to the first value in the enum. + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.optional_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.optional_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.optional_import_enum ()); + + + // Repeated fields are empty. + EXPECT_EQ(0, message.repeated_int32_size ()); + EXPECT_EQ(0, message.repeated_int64_size ()); + EXPECT_EQ(0, message.repeated_uint32_size ()); + EXPECT_EQ(0, message.repeated_uint64_size ()); + EXPECT_EQ(0, message.repeated_sint32_size ()); + EXPECT_EQ(0, message.repeated_sint64_size ()); + EXPECT_EQ(0, message.repeated_fixed32_size ()); + EXPECT_EQ(0, message.repeated_fixed64_size ()); + EXPECT_EQ(0, message.repeated_sfixed32_size()); + EXPECT_EQ(0, message.repeated_sfixed64_size()); + EXPECT_EQ(0, message.repeated_float_size ()); + EXPECT_EQ(0, message.repeated_double_size ()); + EXPECT_EQ(0, message.repeated_bool_size ()); + EXPECT_EQ(0, message.repeated_string_size ()); + EXPECT_EQ(0, message.repeated_bytes_size ()); + + EXPECT_EQ(0, message.repeatedgroup_size ()); + EXPECT_EQ(0, message.repeated_nested_message_size ()); + EXPECT_EQ(0, message.repeated_foreign_message_size()); + EXPECT_EQ(0, message.repeated_import_message_size ()); + EXPECT_EQ(0, message.repeated_lazy_message_size ()); + EXPECT_EQ(0, message.repeated_nested_enum_size ()); + EXPECT_EQ(0, message.repeated_foreign_enum_size ()); + EXPECT_EQ(0, message.repeated_import_enum_size ()); + + + // has_blah() should also be false for all default fields. + EXPECT_FALSE(message.has_default_int32 ()); + EXPECT_FALSE(message.has_default_int64 ()); + EXPECT_FALSE(message.has_default_uint32 ()); + EXPECT_FALSE(message.has_default_uint64 ()); + EXPECT_FALSE(message.has_default_sint32 ()); + EXPECT_FALSE(message.has_default_sint64 ()); + EXPECT_FALSE(message.has_default_fixed32 ()); + EXPECT_FALSE(message.has_default_fixed64 ()); + EXPECT_FALSE(message.has_default_sfixed32()); + EXPECT_FALSE(message.has_default_sfixed64()); + EXPECT_FALSE(message.has_default_float ()); + EXPECT_FALSE(message.has_default_double ()); + EXPECT_FALSE(message.has_default_bool ()); + EXPECT_FALSE(message.has_default_string ()); + EXPECT_FALSE(message.has_default_bytes ()); + + EXPECT_FALSE(message.has_default_nested_enum ()); + EXPECT_FALSE(message.has_default_foreign_enum()); + EXPECT_FALSE(message.has_default_import_enum ()); + + + // Fields with defaults have their default values (duh). + EXPECT_EQ( 41 , message.default_int32 ()); + EXPECT_EQ( 42 , message.default_int64 ()); + EXPECT_EQ( 43 , message.default_uint32 ()); + EXPECT_EQ( 44 , message.default_uint64 ()); + EXPECT_EQ(-45 , message.default_sint32 ()); + EXPECT_EQ( 46 , message.default_sint64 ()); + EXPECT_EQ( 47 , message.default_fixed32 ()); + EXPECT_EQ( 48 , message.default_fixed64 ()); + EXPECT_EQ( 49 , message.default_sfixed32()); + EXPECT_EQ(-50 , message.default_sfixed64()); + EXPECT_EQ( 51.5 , message.default_float ()); + EXPECT_EQ( 52e3 , message.default_double ()); + EXPECT_EQ(true , message.default_bool ()); + EXPECT_EQ("hello", message.default_string ()); + EXPECT_EQ("world", message.default_bytes ()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.default_nested_enum ()); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.default_foreign_enum()); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.default_import_enum ()); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectRepeatedFieldsModified( + const unittest::TestAllTypesLite& message) { + // ModifyRepeatedFields only sets the second repeated element of each + // field. In addition to verifying this, we also verify that the first + // element and size were *not* modified. + ASSERT_EQ(2, message.repeated_int32_size ()); + ASSERT_EQ(2, message.repeated_int64_size ()); + ASSERT_EQ(2, message.repeated_uint32_size ()); + ASSERT_EQ(2, message.repeated_uint64_size ()); + ASSERT_EQ(2, message.repeated_sint32_size ()); + ASSERT_EQ(2, message.repeated_sint64_size ()); + ASSERT_EQ(2, message.repeated_fixed32_size ()); + ASSERT_EQ(2, message.repeated_fixed64_size ()); + ASSERT_EQ(2, message.repeated_sfixed32_size()); + ASSERT_EQ(2, message.repeated_sfixed64_size()); + ASSERT_EQ(2, message.repeated_float_size ()); + ASSERT_EQ(2, message.repeated_double_size ()); + ASSERT_EQ(2, message.repeated_bool_size ()); + ASSERT_EQ(2, message.repeated_string_size ()); + ASSERT_EQ(2, message.repeated_bytes_size ()); + + ASSERT_EQ(2, message.repeatedgroup_size ()); + ASSERT_EQ(2, message.repeated_nested_message_size ()); + ASSERT_EQ(2, message.repeated_foreign_message_size()); + ASSERT_EQ(2, message.repeated_import_message_size ()); + ASSERT_EQ(2, message.repeated_lazy_message_size ()); + ASSERT_EQ(2, message.repeated_nested_enum_size ()); + ASSERT_EQ(2, message.repeated_foreign_enum_size ()); + ASSERT_EQ(2, message.repeated_import_enum_size ()); + + + EXPECT_EQ(201 , message.repeated_int32 (0)); + EXPECT_EQ(202 , message.repeated_int64 (0)); + EXPECT_EQ(203 , message.repeated_uint32 (0)); + EXPECT_EQ(204 , message.repeated_uint64 (0)); + EXPECT_EQ(205 , message.repeated_sint32 (0)); + EXPECT_EQ(206 , message.repeated_sint64 (0)); + EXPECT_EQ(207 , message.repeated_fixed32 (0)); + EXPECT_EQ(208 , message.repeated_fixed64 (0)); + EXPECT_EQ(209 , message.repeated_sfixed32(0)); + EXPECT_EQ(210 , message.repeated_sfixed64(0)); + EXPECT_EQ(211 , message.repeated_float (0)); + EXPECT_EQ(212 , message.repeated_double (0)); + EXPECT_EQ(true , message.repeated_bool (0)); + EXPECT_EQ("215", message.repeated_string (0)); + EXPECT_EQ("216", message.repeated_bytes (0)); + + EXPECT_EQ(217, message.repeatedgroup (0).a()); + EXPECT_EQ(218, message.repeated_nested_message (0).bb()); + EXPECT_EQ(219, message.repeated_foreign_message(0).c()); + EXPECT_EQ(220, message.repeated_import_message (0).d()); + EXPECT_EQ(227, message.repeated_lazy_message (0).bb()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.repeated_foreign_enum(0)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.repeated_import_enum (0)); + + + // Actually verify the second (modified) elements now. + EXPECT_EQ(501 , message.repeated_int32 (1)); + EXPECT_EQ(502 , message.repeated_int64 (1)); + EXPECT_EQ(503 , message.repeated_uint32 (1)); + EXPECT_EQ(504 , message.repeated_uint64 (1)); + EXPECT_EQ(505 , message.repeated_sint32 (1)); + EXPECT_EQ(506 , message.repeated_sint64 (1)); + EXPECT_EQ(507 , message.repeated_fixed32 (1)); + EXPECT_EQ(508 , message.repeated_fixed64 (1)); + EXPECT_EQ(509 , message.repeated_sfixed32(1)); + EXPECT_EQ(510 , message.repeated_sfixed64(1)); + EXPECT_EQ(511 , message.repeated_float (1)); + EXPECT_EQ(512 , message.repeated_double (1)); + EXPECT_EQ(true , message.repeated_bool (1)); + EXPECT_EQ("515", message.repeated_string (1)); + EXPECT_EQ("516", message.repeated_bytes (1)); + + EXPECT_EQ(517, message.repeatedgroup (1).a()); + EXPECT_EQ(518, message.repeated_nested_message (1).bb()); + EXPECT_EQ(519, message.repeated_foreign_message(1).c()); + EXPECT_EQ(520, message.repeated_import_message (1).d()); + EXPECT_EQ(527, message.repeated_lazy_message (1).bb()); + + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.repeated_nested_enum (1)); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.repeated_foreign_enum(1)); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.repeated_import_enum (1)); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::SetPackedFields(unittest::TestPackedTypesLite* message) { + message->add_packed_int32 (601); + message->add_packed_int64 (602); + message->add_packed_uint32 (603); + message->add_packed_uint64 (604); + message->add_packed_sint32 (605); + message->add_packed_sint64 (606); + message->add_packed_fixed32 (607); + message->add_packed_fixed64 (608); + message->add_packed_sfixed32(609); + message->add_packed_sfixed64(610); + message->add_packed_float (611); + message->add_packed_double (612); + message->add_packed_bool (true); + message->add_packed_enum (unittest::FOREIGN_LITE_BAR); + // add a second one of each field + message->add_packed_int32 (701); + message->add_packed_int64 (702); + message->add_packed_uint32 (703); + message->add_packed_uint64 (704); + message->add_packed_sint32 (705); + message->add_packed_sint64 (706); + message->add_packed_fixed32 (707); + message->add_packed_fixed64 (708); + message->add_packed_sfixed32(709); + message->add_packed_sfixed64(710); + message->add_packed_float (711); + message->add_packed_double (712); + message->add_packed_bool (false); + message->add_packed_enum (unittest::FOREIGN_LITE_BAZ); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ModifyPackedFields(unittest::TestPackedTypesLite* message) { + message->set_packed_int32 (1, 801); + message->set_packed_int64 (1, 802); + message->set_packed_uint32 (1, 803); + message->set_packed_uint64 (1, 804); + message->set_packed_sint32 (1, 805); + message->set_packed_sint64 (1, 806); + message->set_packed_fixed32 (1, 807); + message->set_packed_fixed64 (1, 808); + message->set_packed_sfixed32(1, 809); + message->set_packed_sfixed64(1, 810); + message->set_packed_float (1, 811); + message->set_packed_double (1, 812); + message->set_packed_bool (1, true); + message->set_packed_enum (1, unittest::FOREIGN_LITE_FOO); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedFieldsSet( + const unittest::TestPackedTypesLite& message) { + ASSERT_EQ(2, message.packed_int32_size ()); + ASSERT_EQ(2, message.packed_int64_size ()); + ASSERT_EQ(2, message.packed_uint32_size ()); + ASSERT_EQ(2, message.packed_uint64_size ()); + ASSERT_EQ(2, message.packed_sint32_size ()); + ASSERT_EQ(2, message.packed_sint64_size ()); + ASSERT_EQ(2, message.packed_fixed32_size ()); + ASSERT_EQ(2, message.packed_fixed64_size ()); + ASSERT_EQ(2, message.packed_sfixed32_size()); + ASSERT_EQ(2, message.packed_sfixed64_size()); + ASSERT_EQ(2, message.packed_float_size ()); + ASSERT_EQ(2, message.packed_double_size ()); + ASSERT_EQ(2, message.packed_bool_size ()); + ASSERT_EQ(2, message.packed_enum_size ()); + + EXPECT_EQ(601 , message.packed_int32 (0)); + EXPECT_EQ(602 , message.packed_int64 (0)); + EXPECT_EQ(603 , message.packed_uint32 (0)); + EXPECT_EQ(604 , message.packed_uint64 (0)); + EXPECT_EQ(605 , message.packed_sint32 (0)); + EXPECT_EQ(606 , message.packed_sint64 (0)); + EXPECT_EQ(607 , message.packed_fixed32 (0)); + EXPECT_EQ(608 , message.packed_fixed64 (0)); + EXPECT_EQ(609 , message.packed_sfixed32(0)); + EXPECT_EQ(610 , message.packed_sfixed64(0)); + EXPECT_EQ(611 , message.packed_float (0)); + EXPECT_EQ(612 , message.packed_double (0)); + EXPECT_EQ(true , message.packed_bool (0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0)); + + EXPECT_EQ(701 , message.packed_int32 (1)); + EXPECT_EQ(702 , message.packed_int64 (1)); + EXPECT_EQ(703 , message.packed_uint32 (1)); + EXPECT_EQ(704 , message.packed_uint64 (1)); + EXPECT_EQ(705 , message.packed_sint32 (1)); + EXPECT_EQ(706 , message.packed_sint64 (1)); + EXPECT_EQ(707 , message.packed_fixed32 (1)); + EXPECT_EQ(708 , message.packed_fixed64 (1)); + EXPECT_EQ(709 , message.packed_sfixed32(1)); + EXPECT_EQ(710 , message.packed_sfixed64(1)); + EXPECT_EQ(711 , message.packed_float (1)); + EXPECT_EQ(712 , message.packed_double (1)); + EXPECT_EQ(false, message.packed_bool (1)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ, message.packed_enum(1)); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedClear( + const unittest::TestPackedTypesLite& message) { + // Packed repeated fields are empty. + EXPECT_EQ(0, message.packed_int32_size ()); + EXPECT_EQ(0, message.packed_int64_size ()); + EXPECT_EQ(0, message.packed_uint32_size ()); + EXPECT_EQ(0, message.packed_uint64_size ()); + EXPECT_EQ(0, message.packed_sint32_size ()); + EXPECT_EQ(0, message.packed_sint64_size ()); + EXPECT_EQ(0, message.packed_fixed32_size ()); + EXPECT_EQ(0, message.packed_fixed64_size ()); + EXPECT_EQ(0, message.packed_sfixed32_size()); + EXPECT_EQ(0, message.packed_sfixed64_size()); + EXPECT_EQ(0, message.packed_float_size ()); + EXPECT_EQ(0, message.packed_double_size ()); + EXPECT_EQ(0, message.packed_bool_size ()); + EXPECT_EQ(0, message.packed_enum_size ()); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedFieldsModified( + const unittest::TestPackedTypesLite& message) { + // Do the same for packed repeated fields. + ASSERT_EQ(2, message.packed_int32_size ()); + ASSERT_EQ(2, message.packed_int64_size ()); + ASSERT_EQ(2, message.packed_uint32_size ()); + ASSERT_EQ(2, message.packed_uint64_size ()); + ASSERT_EQ(2, message.packed_sint32_size ()); + ASSERT_EQ(2, message.packed_sint64_size ()); + ASSERT_EQ(2, message.packed_fixed32_size ()); + ASSERT_EQ(2, message.packed_fixed64_size ()); + ASSERT_EQ(2, message.packed_sfixed32_size()); + ASSERT_EQ(2, message.packed_sfixed64_size()); + ASSERT_EQ(2, message.packed_float_size ()); + ASSERT_EQ(2, message.packed_double_size ()); + ASSERT_EQ(2, message.packed_bool_size ()); + ASSERT_EQ(2, message.packed_enum_size ()); + + EXPECT_EQ(601 , message.packed_int32 (0)); + EXPECT_EQ(602 , message.packed_int64 (0)); + EXPECT_EQ(603 , message.packed_uint32 (0)); + EXPECT_EQ(604 , message.packed_uint64 (0)); + EXPECT_EQ(605 , message.packed_sint32 (0)); + EXPECT_EQ(606 , message.packed_sint64 (0)); + EXPECT_EQ(607 , message.packed_fixed32 (0)); + EXPECT_EQ(608 , message.packed_fixed64 (0)); + EXPECT_EQ(609 , message.packed_sfixed32(0)); + EXPECT_EQ(610 , message.packed_sfixed64(0)); + EXPECT_EQ(611 , message.packed_float (0)); + EXPECT_EQ(612 , message.packed_double (0)); + EXPECT_EQ(true , message.packed_bool (0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0)); + // Actually verify the second (modified) elements now. + EXPECT_EQ(801 , message.packed_int32 (1)); + EXPECT_EQ(802 , message.packed_int64 (1)); + EXPECT_EQ(803 , message.packed_uint32 (1)); + EXPECT_EQ(804 , message.packed_uint64 (1)); + EXPECT_EQ(805 , message.packed_sint32 (1)); + EXPECT_EQ(806 , message.packed_sint64 (1)); + EXPECT_EQ(807 , message.packed_fixed32 (1)); + EXPECT_EQ(808 , message.packed_fixed64 (1)); + EXPECT_EQ(809 , message.packed_sfixed32(1)); + EXPECT_EQ(810 , message.packed_sfixed64(1)); + EXPECT_EQ(811 , message.packed_float (1)); + EXPECT_EQ(812 , message.packed_double (1)); + EXPECT_EQ(true , message.packed_bool (1)); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO, message.packed_enum(1)); +} + +// =================================================================== +// Extensions +// +// All this code is exactly equivalent to the above code except that it's +// manipulating extension fields instead of normal ones. +// +// I gave up on the 80-char limit here. Sorry. + +void TestUtilLite::SetAllExtensions(unittest::TestAllExtensionsLite* message) { + message->SetExtension(unittest::optional_int32_extension_lite , 101); + message->SetExtension(unittest::optional_int64_extension_lite , 102); + message->SetExtension(unittest::optional_uint32_extension_lite , 103); + message->SetExtension(unittest::optional_uint64_extension_lite , 104); + message->SetExtension(unittest::optional_sint32_extension_lite , 105); + message->SetExtension(unittest::optional_sint64_extension_lite , 106); + message->SetExtension(unittest::optional_fixed32_extension_lite , 107); + message->SetExtension(unittest::optional_fixed64_extension_lite , 108); + message->SetExtension(unittest::optional_sfixed32_extension_lite, 109); + message->SetExtension(unittest::optional_sfixed64_extension_lite, 110); + message->SetExtension(unittest::optional_float_extension_lite , 111); + message->SetExtension(unittest::optional_double_extension_lite , 112); + message->SetExtension(unittest::optional_bool_extension_lite , true); + message->SetExtension(unittest::optional_string_extension_lite , "115"); + message->SetExtension(unittest::optional_bytes_extension_lite , "116"); + + message->MutableExtension(unittest::optionalgroup_extension_lite )->set_a(117); + message->MutableExtension(unittest::optional_nested_message_extension_lite )->set_bb(118); + message->MutableExtension(unittest::optional_foreign_message_extension_lite )->set_c(119); + message->MutableExtension(unittest::optional_import_message_extension_lite )->set_d(120); + message->MutableExtension(unittest::optional_public_import_message_extension_lite)->set_e(126); + message->MutableExtension(unittest::optional_lazy_message_extension_lite )->set_bb(127); + + message->SetExtension(unittest::optional_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ ); + message->SetExtension(unittest::optional_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ ); + message->SetExtension(unittest::optional_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAZ); + + + // ----------------------------------------------------------------- + + message->AddExtension(unittest::repeated_int32_extension_lite , 201); + message->AddExtension(unittest::repeated_int64_extension_lite , 202); + message->AddExtension(unittest::repeated_uint32_extension_lite , 203); + message->AddExtension(unittest::repeated_uint64_extension_lite , 204); + message->AddExtension(unittest::repeated_sint32_extension_lite , 205); + message->AddExtension(unittest::repeated_sint64_extension_lite , 206); + message->AddExtension(unittest::repeated_fixed32_extension_lite , 207); + message->AddExtension(unittest::repeated_fixed64_extension_lite , 208); + message->AddExtension(unittest::repeated_sfixed32_extension_lite, 209); + message->AddExtension(unittest::repeated_sfixed64_extension_lite, 210); + message->AddExtension(unittest::repeated_float_extension_lite , 211); + message->AddExtension(unittest::repeated_double_extension_lite , 212); + message->AddExtension(unittest::repeated_bool_extension_lite , true); + message->AddExtension(unittest::repeated_string_extension_lite , "215"); + message->AddExtension(unittest::repeated_bytes_extension_lite , "216"); + + message->AddExtension(unittest::repeatedgroup_extension_lite )->set_a(217); + message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(218); + message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(219); + message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(220); + message->AddExtension(unittest::repeated_lazy_message_extension_lite )->set_bb(227); + + message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAR ); + message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAR ); + message->AddExtension(unittest::repeated_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAR); + + + // Add a second one of each field. + message->AddExtension(unittest::repeated_int32_extension_lite , 301); + message->AddExtension(unittest::repeated_int64_extension_lite , 302); + message->AddExtension(unittest::repeated_uint32_extension_lite , 303); + message->AddExtension(unittest::repeated_uint64_extension_lite , 304); + message->AddExtension(unittest::repeated_sint32_extension_lite , 305); + message->AddExtension(unittest::repeated_sint64_extension_lite , 306); + message->AddExtension(unittest::repeated_fixed32_extension_lite , 307); + message->AddExtension(unittest::repeated_fixed64_extension_lite , 308); + message->AddExtension(unittest::repeated_sfixed32_extension_lite, 309); + message->AddExtension(unittest::repeated_sfixed64_extension_lite, 310); + message->AddExtension(unittest::repeated_float_extension_lite , 311); + message->AddExtension(unittest::repeated_double_extension_lite , 312); + message->AddExtension(unittest::repeated_bool_extension_lite , false); + message->AddExtension(unittest::repeated_string_extension_lite , "315"); + message->AddExtension(unittest::repeated_bytes_extension_lite , "316"); + + message->AddExtension(unittest::repeatedgroup_extension_lite )->set_a(317); + message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(318); + message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(319); + message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(320); + message->AddExtension(unittest::repeated_lazy_message_extension_lite )->set_bb(327); + + message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ ); + message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ ); + message->AddExtension(unittest::repeated_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAZ); + + + // ----------------------------------------------------------------- + + message->SetExtension(unittest::default_int32_extension_lite , 401); + message->SetExtension(unittest::default_int64_extension_lite , 402); + message->SetExtension(unittest::default_uint32_extension_lite , 403); + message->SetExtension(unittest::default_uint64_extension_lite , 404); + message->SetExtension(unittest::default_sint32_extension_lite , 405); + message->SetExtension(unittest::default_sint64_extension_lite , 406); + message->SetExtension(unittest::default_fixed32_extension_lite , 407); + message->SetExtension(unittest::default_fixed64_extension_lite , 408); + message->SetExtension(unittest::default_sfixed32_extension_lite, 409); + message->SetExtension(unittest::default_sfixed64_extension_lite, 410); + message->SetExtension(unittest::default_float_extension_lite , 411); + message->SetExtension(unittest::default_double_extension_lite , 412); + message->SetExtension(unittest::default_bool_extension_lite , false); + message->SetExtension(unittest::default_string_extension_lite , "415"); + message->SetExtension(unittest::default_bytes_extension_lite , "416"); + + message->SetExtension(unittest::default_nested_enum_extension_lite , unittest::TestAllTypesLite::FOO ); + message->SetExtension(unittest::default_foreign_enum_extension_lite, unittest::FOREIGN_LITE_FOO ); + message->SetExtension(unittest::default_import_enum_extension_lite , unittest_import::IMPORT_LITE_FOO); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ModifyRepeatedExtensions( + unittest::TestAllExtensionsLite* message) { + message->SetExtension(unittest::repeated_int32_extension_lite , 1, 501); + message->SetExtension(unittest::repeated_int64_extension_lite , 1, 502); + message->SetExtension(unittest::repeated_uint32_extension_lite , 1, 503); + message->SetExtension(unittest::repeated_uint64_extension_lite , 1, 504); + message->SetExtension(unittest::repeated_sint32_extension_lite , 1, 505); + message->SetExtension(unittest::repeated_sint64_extension_lite , 1, 506); + message->SetExtension(unittest::repeated_fixed32_extension_lite , 1, 507); + message->SetExtension(unittest::repeated_fixed64_extension_lite , 1, 508); + message->SetExtension(unittest::repeated_sfixed32_extension_lite, 1, 509); + message->SetExtension(unittest::repeated_sfixed64_extension_lite, 1, 510); + message->SetExtension(unittest::repeated_float_extension_lite , 1, 511); + message->SetExtension(unittest::repeated_double_extension_lite , 1, 512); + message->SetExtension(unittest::repeated_bool_extension_lite , 1, true); + message->SetExtension(unittest::repeated_string_extension_lite , 1, "515"); + message->SetExtension(unittest::repeated_bytes_extension_lite , 1, "516"); + + message->MutableExtension(unittest::repeatedgroup_extension_lite , 1)->set_a(517); + message->MutableExtension(unittest::repeated_nested_message_extension_lite , 1)->set_bb(518); + message->MutableExtension(unittest::repeated_foreign_message_extension_lite, 1)->set_c(519); + message->MutableExtension(unittest::repeated_import_message_extension_lite , 1)->set_d(520); + message->MutableExtension(unittest::repeated_lazy_message_extension_lite , 1)->set_bb(527); + + message->SetExtension(unittest::repeated_nested_enum_extension_lite , 1, unittest::TestAllTypesLite::FOO ); + message->SetExtension(unittest::repeated_foreign_enum_extension_lite, 1, unittest::FOREIGN_LITE_FOO ); + message->SetExtension(unittest::repeated_import_enum_extension_lite , 1, unittest_import::IMPORT_LITE_FOO); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectAllExtensionsSet( + const unittest::TestAllExtensionsLite& message) { + EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_int64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_uint64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_sint32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_sint64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_fixed32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_fixed64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed32_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed64_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::optional_float_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_double_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_bool_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension_lite )); + + EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_public_import_message_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::optional_lazy_message_extension_lite )); + + EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a()); + EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb()); + EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension_lite ).has_c()); + EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d()); + EXPECT_TRUE(message.GetExtension(unittest::optional_public_import_message_extension_lite).has_e()); + EXPECT_TRUE(message.GetExtension(unittest::optional_lazy_message_extension_lite ).has_bb()); + + EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::optional_import_enum_extension_lite )); + + + EXPECT_EQ(101 , message.GetExtension(unittest::optional_int32_extension_lite )); + EXPECT_EQ(102 , message.GetExtension(unittest::optional_int64_extension_lite )); + EXPECT_EQ(103 , message.GetExtension(unittest::optional_uint32_extension_lite )); + EXPECT_EQ(104 , message.GetExtension(unittest::optional_uint64_extension_lite )); + EXPECT_EQ(105 , message.GetExtension(unittest::optional_sint32_extension_lite )); + EXPECT_EQ(106 , message.GetExtension(unittest::optional_sint64_extension_lite )); + EXPECT_EQ(107 , message.GetExtension(unittest::optional_fixed32_extension_lite )); + EXPECT_EQ(108 , message.GetExtension(unittest::optional_fixed64_extension_lite )); + EXPECT_EQ(109 , message.GetExtension(unittest::optional_sfixed32_extension_lite)); + EXPECT_EQ(110 , message.GetExtension(unittest::optional_sfixed64_extension_lite)); + EXPECT_EQ(111 , message.GetExtension(unittest::optional_float_extension_lite )); + EXPECT_EQ(112 , message.GetExtension(unittest::optional_double_extension_lite )); + EXPECT_EQ(true , message.GetExtension(unittest::optional_bool_extension_lite )); + EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension_lite )); + EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension_lite )); + + EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension_lite ).a()); + EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb()); + EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension_lite ).c()); + EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension_lite ).d()); + EXPECT_EQ(126, message.GetExtension(unittest::optional_public_import_message_extension_lite).e()); + EXPECT_EQ(127, message.GetExtension(unittest::optional_lazy_message_extension_lite ).bb()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::optional_nested_enum_extension_lite )); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.GetExtension(unittest::optional_foreign_enum_extension_lite)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.GetExtension(unittest::optional_import_enum_extension_lite )); + + + // ----------------------------------------------------------------- + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite )); + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite )); + + + EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension_lite , 0)); + EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension_lite , 0)); + EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension_lite , 0)); + EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension_lite , 0)); + EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension_lite , 0)); + EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension_lite , 0)); + EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 0)); + EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 0)); + EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0)); + EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0)); + EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension_lite , 0)); + EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension_lite , 0)); + EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 0)); + EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension_lite , 0)); + EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension_lite , 0)); + + EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension_lite , 0).a()); + EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb()); + EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c()); + EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d()); + EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension_lite , 0).bb()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::repeated_import_enum_extension_lite , 0)); + + + EXPECT_EQ(301 , message.GetExtension(unittest::repeated_int32_extension_lite , 1)); + EXPECT_EQ(302 , message.GetExtension(unittest::repeated_int64_extension_lite , 1)); + EXPECT_EQ(303 , message.GetExtension(unittest::repeated_uint32_extension_lite , 1)); + EXPECT_EQ(304 , message.GetExtension(unittest::repeated_uint64_extension_lite , 1)); + EXPECT_EQ(305 , message.GetExtension(unittest::repeated_sint32_extension_lite , 1)); + EXPECT_EQ(306 , message.GetExtension(unittest::repeated_sint64_extension_lite , 1)); + EXPECT_EQ(307 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 1)); + EXPECT_EQ(308 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 1)); + EXPECT_EQ(309 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1)); + EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1)); + EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension_lite , 1)); + EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension_lite , 1)); + EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension_lite , 1)); + EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension_lite , 1)); + EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension_lite , 1)); + + EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension_lite , 1).a()); + EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb()); + EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c()); + EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d()); + EXPECT_EQ(327, message.GetExtension(unittest::repeated_lazy_message_extension_lite , 1).bb()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.GetExtension(unittest::repeated_import_enum_extension_lite , 1)); + + + // ----------------------------------------------------------------- + + EXPECT_TRUE(message.HasExtension(unittest::default_int32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_int64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_uint32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_uint64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_sint32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_sint64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_fixed32_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_fixed64_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_sfixed32_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::default_sfixed64_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::default_float_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_double_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_bool_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_string_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_bytes_extension_lite )); + + EXPECT_TRUE(message.HasExtension(unittest::default_nested_enum_extension_lite )); + EXPECT_TRUE(message.HasExtension(unittest::default_foreign_enum_extension_lite)); + EXPECT_TRUE(message.HasExtension(unittest::default_import_enum_extension_lite )); + + + EXPECT_EQ(401 , message.GetExtension(unittest::default_int32_extension_lite )); + EXPECT_EQ(402 , message.GetExtension(unittest::default_int64_extension_lite )); + EXPECT_EQ(403 , message.GetExtension(unittest::default_uint32_extension_lite )); + EXPECT_EQ(404 , message.GetExtension(unittest::default_uint64_extension_lite )); + EXPECT_EQ(405 , message.GetExtension(unittest::default_sint32_extension_lite )); + EXPECT_EQ(406 , message.GetExtension(unittest::default_sint64_extension_lite )); + EXPECT_EQ(407 , message.GetExtension(unittest::default_fixed32_extension_lite )); + EXPECT_EQ(408 , message.GetExtension(unittest::default_fixed64_extension_lite )); + EXPECT_EQ(409 , message.GetExtension(unittest::default_sfixed32_extension_lite)); + EXPECT_EQ(410 , message.GetExtension(unittest::default_sfixed64_extension_lite)); + EXPECT_EQ(411 , message.GetExtension(unittest::default_float_extension_lite )); + EXPECT_EQ(412 , message.GetExtension(unittest::default_double_extension_lite )); + EXPECT_EQ(false, message.GetExtension(unittest::default_bool_extension_lite )); + EXPECT_EQ("415", message.GetExtension(unittest::default_string_extension_lite )); + EXPECT_EQ("416", message.GetExtension(unittest::default_bytes_extension_lite )); + + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::default_nested_enum_extension_lite )); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::default_foreign_enum_extension_lite)); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::default_import_enum_extension_lite )); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectExtensionsClear( + const unittest::TestAllExtensionsLite& message) { + string serialized; + ASSERT_TRUE(message.SerializeToString(&serialized)); + EXPECT_EQ("", serialized); + EXPECT_EQ(0, message.ByteSize()); + + // has_blah() should initially be false for all optional fields. + EXPECT_FALSE(message.HasExtension(unittest::optional_int32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_uint32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_uint64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_sint32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_sint64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_fixed32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_fixed64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed32_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed64_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::optional_float_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_double_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_bool_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension_lite )); + + EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_public_import_message_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::optional_lazy_message_extension_lite )); + + EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::optional_import_enum_extension_lite )); + + + // Optional fields without defaults are set to zero or something like it. + EXPECT_EQ(0 , message.GetExtension(unittest::optional_int32_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_int64_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint32_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint64_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint32_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint64_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed32_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed64_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed32_extension_lite)); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed64_extension_lite)); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_float_extension_lite )); + EXPECT_EQ(0 , message.GetExtension(unittest::optional_double_extension_lite )); + EXPECT_EQ(false, message.GetExtension(unittest::optional_bool_extension_lite )); + EXPECT_EQ("" , message.GetExtension(unittest::optional_string_extension_lite )); + EXPECT_EQ("" , message.GetExtension(unittest::optional_bytes_extension_lite )); + + // Embedded messages should also be clear. + EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a()); + EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb()); + EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension_lite ).has_c()); + EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d()); + EXPECT_FALSE(message.GetExtension(unittest::optional_public_import_message_extension_lite).has_e()); + EXPECT_FALSE(message.GetExtension(unittest::optional_lazy_message_extension_lite ).has_bb()); + + EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension_lite ).a()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension_lite ).c()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension_lite ).d()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_public_import_message_extension_lite).e()); + EXPECT_EQ(0, message.GetExtension(unittest::optional_lazy_message_extension_lite ).bb()); + + // Enums without defaults are set to the first value in the enum. + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::optional_nested_enum_extension_lite )); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::optional_foreign_enum_extension_lite)); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::optional_import_enum_extension_lite )); + + + // Repeated fields are empty. + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite)); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite)); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_float_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_double_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bool_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bytes_extension_lite )); + + EXPECT_EQ(0, message.ExtensionSize(unittest::repeatedgroup_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite)); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension_lite )); + + + // has_blah() should also be false for all default fields. + EXPECT_FALSE(message.HasExtension(unittest::default_int32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_int64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_uint32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_uint64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_sint32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_sint64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_fixed32_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_fixed64_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_sfixed32_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::default_sfixed64_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::default_float_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_double_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_bool_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_string_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_bytes_extension_lite )); + + EXPECT_FALSE(message.HasExtension(unittest::default_nested_enum_extension_lite )); + EXPECT_FALSE(message.HasExtension(unittest::default_foreign_enum_extension_lite)); + EXPECT_FALSE(message.HasExtension(unittest::default_import_enum_extension_lite )); + + + // Fields with defaults have their default values (duh). + EXPECT_EQ( 41 , message.GetExtension(unittest::default_int32_extension_lite )); + EXPECT_EQ( 42 , message.GetExtension(unittest::default_int64_extension_lite )); + EXPECT_EQ( 43 , message.GetExtension(unittest::default_uint32_extension_lite )); + EXPECT_EQ( 44 , message.GetExtension(unittest::default_uint64_extension_lite )); + EXPECT_EQ(-45 , message.GetExtension(unittest::default_sint32_extension_lite )); + EXPECT_EQ( 46 , message.GetExtension(unittest::default_sint64_extension_lite )); + EXPECT_EQ( 47 , message.GetExtension(unittest::default_fixed32_extension_lite )); + EXPECT_EQ( 48 , message.GetExtension(unittest::default_fixed64_extension_lite )); + EXPECT_EQ( 49 , message.GetExtension(unittest::default_sfixed32_extension_lite)); + EXPECT_EQ(-50 , message.GetExtension(unittest::default_sfixed64_extension_lite)); + EXPECT_EQ( 51.5 , message.GetExtension(unittest::default_float_extension_lite )); + EXPECT_EQ( 52e3 , message.GetExtension(unittest::default_double_extension_lite )); + EXPECT_EQ(true , message.GetExtension(unittest::default_bool_extension_lite )); + EXPECT_EQ("hello", message.GetExtension(unittest::default_string_extension_lite )); + EXPECT_EQ("world", message.GetExtension(unittest::default_bytes_extension_lite )); + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::default_nested_enum_extension_lite )); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::default_foreign_enum_extension_lite)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::default_import_enum_extension_lite )); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectRepeatedExtensionsModified( + const unittest::TestAllExtensionsLite& message) { + // ModifyRepeatedFields only sets the second repeated element of each + // field. In addition to verifying this, we also verify that the first + // element and size were *not* modified. + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite )); + + ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite )); + + + EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension_lite , 0)); + EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension_lite , 0)); + EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension_lite , 0)); + EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension_lite , 0)); + EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension_lite , 0)); + EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension_lite , 0)); + EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 0)); + EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 0)); + EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0)); + EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0)); + EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension_lite , 0)); + EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension_lite , 0)); + EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 0)); + EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension_lite , 0)); + EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension_lite , 0)); + + EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension_lite , 0).a()); + EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb()); + EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c()); + EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d()); + EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension_lite , 0).bb()); + + EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0)); + EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::repeated_import_enum_extension_lite , 0)); + + + // Actually verify the second (modified) elements now. + EXPECT_EQ(501 , message.GetExtension(unittest::repeated_int32_extension_lite , 1)); + EXPECT_EQ(502 , message.GetExtension(unittest::repeated_int64_extension_lite , 1)); + EXPECT_EQ(503 , message.GetExtension(unittest::repeated_uint32_extension_lite , 1)); + EXPECT_EQ(504 , message.GetExtension(unittest::repeated_uint64_extension_lite , 1)); + EXPECT_EQ(505 , message.GetExtension(unittest::repeated_sint32_extension_lite , 1)); + EXPECT_EQ(506 , message.GetExtension(unittest::repeated_sint64_extension_lite , 1)); + EXPECT_EQ(507 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 1)); + EXPECT_EQ(508 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 1)); + EXPECT_EQ(509 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1)); + EXPECT_EQ(510 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1)); + EXPECT_EQ(511 , message.GetExtension(unittest::repeated_float_extension_lite , 1)); + EXPECT_EQ(512 , message.GetExtension(unittest::repeated_double_extension_lite , 1)); + EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 1)); + EXPECT_EQ("515", message.GetExtension(unittest::repeated_string_extension_lite , 1)); + EXPECT_EQ("516", message.GetExtension(unittest::repeated_bytes_extension_lite , 1)); + + EXPECT_EQ(517, message.GetExtension(unittest::repeatedgroup_extension_lite , 1).a()); + EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb()); + EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c()); + EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d()); + EXPECT_EQ(527, message.GetExtension(unittest::repeated_lazy_message_extension_lite , 1).bb()); + + EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1)); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1)); + EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::repeated_import_enum_extension_lite , 1)); + +} + +// ------------------------------------------------------------------- + +void TestUtilLite::SetPackedExtensions( + unittest::TestPackedExtensionsLite* message) { + message->AddExtension(unittest::packed_int32_extension_lite , 601); + message->AddExtension(unittest::packed_int64_extension_lite , 602); + message->AddExtension(unittest::packed_uint32_extension_lite , 603); + message->AddExtension(unittest::packed_uint64_extension_lite , 604); + message->AddExtension(unittest::packed_sint32_extension_lite , 605); + message->AddExtension(unittest::packed_sint64_extension_lite , 606); + message->AddExtension(unittest::packed_fixed32_extension_lite , 607); + message->AddExtension(unittest::packed_fixed64_extension_lite , 608); + message->AddExtension(unittest::packed_sfixed32_extension_lite, 609); + message->AddExtension(unittest::packed_sfixed64_extension_lite, 610); + message->AddExtension(unittest::packed_float_extension_lite , 611); + message->AddExtension(unittest::packed_double_extension_lite , 612); + message->AddExtension(unittest::packed_bool_extension_lite , true); + message->AddExtension(unittest::packed_enum_extension_lite, unittest::FOREIGN_LITE_BAR); + // add a second one of each field + message->AddExtension(unittest::packed_int32_extension_lite , 701); + message->AddExtension(unittest::packed_int64_extension_lite , 702); + message->AddExtension(unittest::packed_uint32_extension_lite , 703); + message->AddExtension(unittest::packed_uint64_extension_lite , 704); + message->AddExtension(unittest::packed_sint32_extension_lite , 705); + message->AddExtension(unittest::packed_sint64_extension_lite , 706); + message->AddExtension(unittest::packed_fixed32_extension_lite , 707); + message->AddExtension(unittest::packed_fixed64_extension_lite , 708); + message->AddExtension(unittest::packed_sfixed32_extension_lite, 709); + message->AddExtension(unittest::packed_sfixed64_extension_lite, 710); + message->AddExtension(unittest::packed_float_extension_lite , 711); + message->AddExtension(unittest::packed_double_extension_lite , 712); + message->AddExtension(unittest::packed_bool_extension_lite , false); + message->AddExtension(unittest::packed_enum_extension_lite, unittest::FOREIGN_LITE_BAZ); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ModifyPackedExtensions( + unittest::TestPackedExtensionsLite* message) { + message->SetExtension(unittest::packed_int32_extension_lite , 1, 801); + message->SetExtension(unittest::packed_int64_extension_lite , 1, 802); + message->SetExtension(unittest::packed_uint32_extension_lite , 1, 803); + message->SetExtension(unittest::packed_uint64_extension_lite , 1, 804); + message->SetExtension(unittest::packed_sint32_extension_lite , 1, 805); + message->SetExtension(unittest::packed_sint64_extension_lite , 1, 806); + message->SetExtension(unittest::packed_fixed32_extension_lite , 1, 807); + message->SetExtension(unittest::packed_fixed64_extension_lite , 1, 808); + message->SetExtension(unittest::packed_sfixed32_extension_lite, 1, 809); + message->SetExtension(unittest::packed_sfixed64_extension_lite, 1, 810); + message->SetExtension(unittest::packed_float_extension_lite , 1, 811); + message->SetExtension(unittest::packed_double_extension_lite , 1, 812); + message->SetExtension(unittest::packed_bool_extension_lite , 1, true); + message->SetExtension(unittest::packed_enum_extension_lite , 1, + unittest::FOREIGN_LITE_FOO); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedExtensionsSet( + const unittest::TestPackedExtensionsLite& message) { + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite )); + + EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension_lite , 0)); + EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension_lite , 0)); + EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension_lite , 0)); + EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension_lite , 0)); + EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension_lite , 0)); + EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension_lite , 0)); + EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension_lite , 0)); + EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension_lite , 0)); + EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 0)); + EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 0)); + EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension_lite , 0)); + EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension_lite , 0)); + EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR, + message.GetExtension(unittest::packed_enum_extension_lite, 0)); + EXPECT_EQ(701 , message.GetExtension(unittest::packed_int32_extension_lite , 1)); + EXPECT_EQ(702 , message.GetExtension(unittest::packed_int64_extension_lite , 1)); + EXPECT_EQ(703 , message.GetExtension(unittest::packed_uint32_extension_lite , 1)); + EXPECT_EQ(704 , message.GetExtension(unittest::packed_uint64_extension_lite , 1)); + EXPECT_EQ(705 , message.GetExtension(unittest::packed_sint32_extension_lite , 1)); + EXPECT_EQ(706 , message.GetExtension(unittest::packed_sint64_extension_lite , 1)); + EXPECT_EQ(707 , message.GetExtension(unittest::packed_fixed32_extension_lite , 1)); + EXPECT_EQ(708 , message.GetExtension(unittest::packed_fixed64_extension_lite , 1)); + EXPECT_EQ(709 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 1)); + EXPECT_EQ(710 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 1)); + EXPECT_EQ(711 , message.GetExtension(unittest::packed_float_extension_lite , 1)); + EXPECT_EQ(712 , message.GetExtension(unittest::packed_double_extension_lite , 1)); + EXPECT_EQ(false, message.GetExtension(unittest::packed_bool_extension_lite , 1)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAZ, + message.GetExtension(unittest::packed_enum_extension_lite, 1)); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedExtensionsClear( + const unittest::TestPackedExtensionsLite& message) { + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed32_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed64_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed32_extension_lite)); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed64_extension_lite)); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_float_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_double_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_bool_extension_lite )); + EXPECT_EQ(0, message.ExtensionSize(unittest::packed_enum_extension_lite )); +} + +// ------------------------------------------------------------------- + +void TestUtilLite::ExpectPackedExtensionsModified( + const unittest::TestPackedExtensionsLite& message) { + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite)); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite )); + ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite )); + EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension_lite , 0)); + EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension_lite , 0)); + EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension_lite , 0)); + EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension_lite , 0)); + EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension_lite , 0)); + EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension_lite , 0)); + EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension_lite , 0)); + EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension_lite , 0)); + EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 0)); + EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 0)); + EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension_lite , 0)); + EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension_lite , 0)); + EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 0)); + EXPECT_EQ(unittest::FOREIGN_LITE_BAR, + message.GetExtension(unittest::packed_enum_extension_lite, 0)); + + // Actually verify the second (modified) elements now. + EXPECT_EQ(801 , message.GetExtension(unittest::packed_int32_extension_lite , 1)); + EXPECT_EQ(802 , message.GetExtension(unittest::packed_int64_extension_lite , 1)); + EXPECT_EQ(803 , message.GetExtension(unittest::packed_uint32_extension_lite , 1)); + EXPECT_EQ(804 , message.GetExtension(unittest::packed_uint64_extension_lite , 1)); + EXPECT_EQ(805 , message.GetExtension(unittest::packed_sint32_extension_lite , 1)); + EXPECT_EQ(806 , message.GetExtension(unittest::packed_sint64_extension_lite , 1)); + EXPECT_EQ(807 , message.GetExtension(unittest::packed_fixed32_extension_lite , 1)); + EXPECT_EQ(808 , message.GetExtension(unittest::packed_fixed64_extension_lite , 1)); + EXPECT_EQ(809 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 1)); + EXPECT_EQ(810 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 1)); + EXPECT_EQ(811 , message.GetExtension(unittest::packed_float_extension_lite , 1)); + EXPECT_EQ(812 , message.GetExtension(unittest::packed_double_extension_lite , 1)); + EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 1)); + EXPECT_EQ(unittest::FOREIGN_LITE_FOO, + message.GetExtension(unittest::packed_enum_extension_lite, 1)); +} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util_lite.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util_lite.h new file mode 100644 index 0000000..ca35aaa --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/test_util_lite.h @@ -0,0 +1,101 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__ +#define GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__ + +#include + +namespace google { +namespace protobuf { + +namespace unittest = protobuf_unittest; +namespace unittest_import = protobuf_unittest_import; + +class TestUtilLite { + public: + // Set every field in the message to a unique value. + static void SetAllFields(unittest::TestAllTypesLite* message); + static void SetAllExtensions(unittest::TestAllExtensionsLite* message); + static void SetPackedFields(unittest::TestPackedTypesLite* message); + static void SetPackedExtensions(unittest::TestPackedExtensionsLite* message); + + // Use the repeated versions of the set_*() accessors to modify all the + // repeated fields of the messsage (which should already have been + // initialized with Set*Fields()). Set*Fields() itself only tests + // the add_*() accessors. + static void ModifyRepeatedFields(unittest::TestAllTypesLite* message); + static void ModifyRepeatedExtensions( + unittest::TestAllExtensionsLite* message); + static void ModifyPackedFields(unittest::TestPackedTypesLite* message); + static void ModifyPackedExtensions( + unittest::TestPackedExtensionsLite* message); + + // Check that all fields have the values that they should have after + // Set*Fields() is called. + static void ExpectAllFieldsSet(const unittest::TestAllTypesLite& message); + static void ExpectAllExtensionsSet( + const unittest::TestAllExtensionsLite& message); + static void ExpectPackedFieldsSet( + const unittest::TestPackedTypesLite& message); + static void ExpectPackedExtensionsSet( + const unittest::TestPackedExtensionsLite& message); + + // Expect that the message is modified as would be expected from + // Modify*Fields(). + static void ExpectRepeatedFieldsModified( + const unittest::TestAllTypesLite& message); + static void ExpectRepeatedExtensionsModified( + const unittest::TestAllExtensionsLite& message); + static void ExpectPackedFieldsModified( + const unittest::TestPackedTypesLite& message); + static void ExpectPackedExtensionsModified( + const unittest::TestPackedExtensionsLite& message); + + // Check that all fields have their default values. + static void ExpectClear(const unittest::TestAllTypesLite& message); + static void ExpectExtensionsClear( + const unittest::TestAllExtensionsLite& message); + static void ExpectPackedClear(const unittest::TestPackedTypesLite& message); + static void ExpectPackedExtensionsClear( + const unittest::TestPackedExtensionsLite& message); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtilLite); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/golden_message b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/golden_message new file mode 100644 index 0000000000000000000000000000000000000000..4dd62cd3bbd87cbdcdb765e1ae69f6a673287806 GIT binary patch literal 509 zcmXxfJxo(k6bJBo{^!0@HbzE9N8iVNn@ORwgK?FCfse??06~EPUeMvisa6vnMU%qR z5DS!vkd&_ltq`DLfNB`f!7!P~(9v^iJ$d=v|9R&o@168u*HHIx&&Y#1J-nnxqe`jX zF~Qd3apB2CD=XEn)J@;OzvfwHgeKW_&72UvqL`*%Q=X81Q4n6P2{R?)ElTZB=Mk~% z1vRUw%VfSGEHvp0HK~jUHHxr-7+)#ICUQ8T9JY|4zzJ@35g)jSpSp}Q`F0sTDOJIF z`==@hq_kmqkvZKU>mJ^S-^jX;y!f502S`{RF0xbPREg6i?%Zbfyg>B5VAp0N z`ktxD{U2mK#xH)$zd6rMe#eo1&#_)l<@Bf2N4+GQtm>q_PgyTZs^~(yuWA*YW)F31 fvxC{pXRYd*1J^XHVeC-O(TUTs=5XKz>sIp@DQ$T4 literal 0 HcmV?d00001 diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/golden_packed_fields_message b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/golden_packed_fields_message new file mode 100644 index 0000000000000000000000000000000000000000..ee28d388305508b7a5dbe784e3c6bf4204c52122 GIT binary patch literal 142 zcmcb_%5sxsFY7Hq1gdU SJG41$Vq;=t*u}=g$_4<-G94WN literal 0 HcmV?d00001 diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/text_format_unittest_data.txt b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/text_format_unittest_data.txt new file mode 100644 index 0000000..bbe5882 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/text_format_unittest_data.txt @@ -0,0 +1,128 @@ +optional_int32: 101 +optional_int64: 102 +optional_uint32: 103 +optional_uint64: 104 +optional_sint32: 105 +optional_sint64: 106 +optional_fixed32: 107 +optional_fixed64: 108 +optional_sfixed32: 109 +optional_sfixed64: 110 +optional_float: 111 +optional_double: 112 +optional_bool: true +optional_string: "115" +optional_bytes: "116" +OptionalGroup { + a: 117 +} +optional_nested_message { + bb: 118 +} +optional_foreign_message { + c: 119 +} +optional_import_message { + d: 120 +} +optional_nested_enum: BAZ +optional_foreign_enum: FOREIGN_BAZ +optional_import_enum: IMPORT_BAZ +optional_string_piece: "124" +optional_cord: "125" +optional_public_import_message { + e: 126 +} +optional_lazy_message { + bb: 127 +} +repeated_int32: 201 +repeated_int32: 301 +repeated_int64: 202 +repeated_int64: 302 +repeated_uint32: 203 +repeated_uint32: 303 +repeated_uint64: 204 +repeated_uint64: 304 +repeated_sint32: 205 +repeated_sint32: 305 +repeated_sint64: 206 +repeated_sint64: 306 +repeated_fixed32: 207 +repeated_fixed32: 307 +repeated_fixed64: 208 +repeated_fixed64: 308 +repeated_sfixed32: 209 +repeated_sfixed32: 309 +repeated_sfixed64: 210 +repeated_sfixed64: 310 +repeated_float: 211 +repeated_float: 311 +repeated_double: 212 +repeated_double: 312 +repeated_bool: true +repeated_bool: false +repeated_string: "215" +repeated_string: "315" +repeated_bytes: "216" +repeated_bytes: "316" +RepeatedGroup { + a: 217 +} +RepeatedGroup { + a: 317 +} +repeated_nested_message { + bb: 218 +} +repeated_nested_message { + bb: 318 +} +repeated_foreign_message { + c: 219 +} +repeated_foreign_message { + c: 319 +} +repeated_import_message { + d: 220 +} +repeated_import_message { + d: 320 +} +repeated_nested_enum: BAR +repeated_nested_enum: BAZ +repeated_foreign_enum: FOREIGN_BAR +repeated_foreign_enum: FOREIGN_BAZ +repeated_import_enum: IMPORT_BAR +repeated_import_enum: IMPORT_BAZ +repeated_string_piece: "224" +repeated_string_piece: "324" +repeated_cord: "225" +repeated_cord: "325" +repeated_lazy_message { + bb: 227 +} +repeated_lazy_message { + bb: 327 +} +default_int32: 401 +default_int64: 402 +default_uint32: 403 +default_uint64: 404 +default_sint32: 405 +default_sint64: 406 +default_fixed32: 407 +default_fixed64: 408 +default_sfixed32: 409 +default_sfixed64: 410 +default_float: 411 +default_double: 412 +default_bool: false +default_string: "415" +default_bytes: "416" +default_nested_enum: FOO +default_foreign_enum: FOREIGN_FOO +default_import_enum: IMPORT_FOO +default_string_piece: "424" +default_cord: "425" diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt new file mode 100644 index 0000000..0a217f0 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt @@ -0,0 +1,128 @@ +[protobuf_unittest.optional_int32_extension]: 101 +[protobuf_unittest.optional_int64_extension]: 102 +[protobuf_unittest.optional_uint32_extension]: 103 +[protobuf_unittest.optional_uint64_extension]: 104 +[protobuf_unittest.optional_sint32_extension]: 105 +[protobuf_unittest.optional_sint64_extension]: 106 +[protobuf_unittest.optional_fixed32_extension]: 107 +[protobuf_unittest.optional_fixed64_extension]: 108 +[protobuf_unittest.optional_sfixed32_extension]: 109 +[protobuf_unittest.optional_sfixed64_extension]: 110 +[protobuf_unittest.optional_float_extension]: 111 +[protobuf_unittest.optional_double_extension]: 112 +[protobuf_unittest.optional_bool_extension]: true +[protobuf_unittest.optional_string_extension]: "115" +[protobuf_unittest.optional_bytes_extension]: "116" +[protobuf_unittest.optionalgroup_extension] { + a: 117 +} +[protobuf_unittest.optional_nested_message_extension] { + bb: 118 +} +[protobuf_unittest.optional_foreign_message_extension] { + c: 119 +} +[protobuf_unittest.optional_import_message_extension] { + d: 120 +} +[protobuf_unittest.optional_nested_enum_extension]: BAZ +[protobuf_unittest.optional_foreign_enum_extension]: FOREIGN_BAZ +[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ +[protobuf_unittest.optional_string_piece_extension]: "124" +[protobuf_unittest.optional_cord_extension]: "125" +[protobuf_unittest.optional_public_import_message_extension] { + e: 126 +} +[protobuf_unittest.optional_lazy_message_extension] { + bb: 127 +} +[protobuf_unittest.repeated_int32_extension]: 201 +[protobuf_unittest.repeated_int32_extension]: 301 +[protobuf_unittest.repeated_int64_extension]: 202 +[protobuf_unittest.repeated_int64_extension]: 302 +[protobuf_unittest.repeated_uint32_extension]: 203 +[protobuf_unittest.repeated_uint32_extension]: 303 +[protobuf_unittest.repeated_uint64_extension]: 204 +[protobuf_unittest.repeated_uint64_extension]: 304 +[protobuf_unittest.repeated_sint32_extension]: 205 +[protobuf_unittest.repeated_sint32_extension]: 305 +[protobuf_unittest.repeated_sint64_extension]: 206 +[protobuf_unittest.repeated_sint64_extension]: 306 +[protobuf_unittest.repeated_fixed32_extension]: 207 +[protobuf_unittest.repeated_fixed32_extension]: 307 +[protobuf_unittest.repeated_fixed64_extension]: 208 +[protobuf_unittest.repeated_fixed64_extension]: 308 +[protobuf_unittest.repeated_sfixed32_extension]: 209 +[protobuf_unittest.repeated_sfixed32_extension]: 309 +[protobuf_unittest.repeated_sfixed64_extension]: 210 +[protobuf_unittest.repeated_sfixed64_extension]: 310 +[protobuf_unittest.repeated_float_extension]: 211 +[protobuf_unittest.repeated_float_extension]: 311 +[protobuf_unittest.repeated_double_extension]: 212 +[protobuf_unittest.repeated_double_extension]: 312 +[protobuf_unittest.repeated_bool_extension]: true +[protobuf_unittest.repeated_bool_extension]: false +[protobuf_unittest.repeated_string_extension]: "215" +[protobuf_unittest.repeated_string_extension]: "315" +[protobuf_unittest.repeated_bytes_extension]: "216" +[protobuf_unittest.repeated_bytes_extension]: "316" +[protobuf_unittest.repeatedgroup_extension] { + a: 217 +} +[protobuf_unittest.repeatedgroup_extension] { + a: 317 +} +[protobuf_unittest.repeated_nested_message_extension] { + bb: 218 +} +[protobuf_unittest.repeated_nested_message_extension] { + bb: 318 +} +[protobuf_unittest.repeated_foreign_message_extension] { + c: 219 +} +[protobuf_unittest.repeated_foreign_message_extension] { + c: 319 +} +[protobuf_unittest.repeated_import_message_extension] { + d: 220 +} +[protobuf_unittest.repeated_import_message_extension] { + d: 320 +} +[protobuf_unittest.repeated_nested_enum_extension]: BAR +[protobuf_unittest.repeated_nested_enum_extension]: BAZ +[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAR +[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAZ +[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAR +[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAZ +[protobuf_unittest.repeated_string_piece_extension]: "224" +[protobuf_unittest.repeated_string_piece_extension]: "324" +[protobuf_unittest.repeated_cord_extension]: "225" +[protobuf_unittest.repeated_cord_extension]: "325" +[protobuf_unittest.repeated_lazy_message_extension] { + bb: 227 +} +[protobuf_unittest.repeated_lazy_message_extension] { + bb: 327 +} +[protobuf_unittest.default_int32_extension]: 401 +[protobuf_unittest.default_int64_extension]: 402 +[protobuf_unittest.default_uint32_extension]: 403 +[protobuf_unittest.default_uint64_extension]: 404 +[protobuf_unittest.default_sint32_extension]: 405 +[protobuf_unittest.default_sint64_extension]: 406 +[protobuf_unittest.default_fixed32_extension]: 407 +[protobuf_unittest.default_fixed64_extension]: 408 +[protobuf_unittest.default_sfixed32_extension]: 409 +[protobuf_unittest.default_sfixed64_extension]: 410 +[protobuf_unittest.default_float_extension]: 411 +[protobuf_unittest.default_double_extension]: 412 +[protobuf_unittest.default_bool_extension]: false +[protobuf_unittest.default_string_extension]: "415" +[protobuf_unittest.default_bytes_extension]: "416" +[protobuf_unittest.default_nested_enum_extension]: FOO +[protobuf_unittest.default_foreign_enum_extension]: FOREIGN_FOO +[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO +[protobuf_unittest.default_string_piece_extension]: "424" +[protobuf_unittest.default_cord_extension]: "425" diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/file.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/file.cc new file mode 100644 index 0000000..e224781 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/file.cc @@ -0,0 +1,176 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// emulates google3/file/base/file.cc + +#include +#include +#include +#include +#ifdef _MSC_VER +#define WIN32_LEAN_AND_MEAN // yeah, right +#include // Find*File(). :( +#include +#include +#else +#include +#include +#endif +#include + +namespace google { +namespace protobuf { + +#ifdef _WIN32 +#define mkdir(name, mode) mkdir(name) +// Windows doesn't have symbolic links. +#define lstat stat +#ifndef F_OK +#define F_OK 00 // not defined by MSVC for whatever reason +#endif +#endif + +bool File::Exists(const string& name) { + return access(name.c_str(), F_OK) == 0; +} + +bool File::ReadFileToString(const string& name, string* output) { + char buffer[1024]; + FILE* file = fopen(name.c_str(), "rb"); + if (file == NULL) return false; + + while (true) { + size_t n = fread(buffer, 1, sizeof(buffer), file); + if (n <= 0) break; + output->append(buffer, n); + } + + int error = ferror(file); + if (fclose(file) != 0) return false; + return error == 0; +} + +void File::ReadFileToStringOrDie(const string& name, string* output) { + GOOGLE_CHECK(ReadFileToString(name, output)) << "Could not read: " << name; +} + +void File::WriteStringToFileOrDie(const string& contents, const string& name) { + FILE* file = fopen(name.c_str(), "wb"); + GOOGLE_CHECK(file != NULL) + << "fopen(" << name << ", \"wb\"): " << strerror(errno); + GOOGLE_CHECK_EQ(fwrite(contents.data(), 1, contents.size(), file), + contents.size()) + << "fwrite(" << name << "): " << strerror(errno); + GOOGLE_CHECK(fclose(file) == 0) + << "fclose(" << name << "): " << strerror(errno); +} + +bool File::CreateDir(const string& name, int mode) { + return mkdir(name.c_str(), mode) == 0; +} + +bool File::RecursivelyCreateDir(const string& path, int mode) { + if (CreateDir(path, mode)) return true; + + if (Exists(path)) return false; + + // Try creating the parent. + string::size_type slashpos = path.find_last_of('/'); + if (slashpos == string::npos) { + // No parent given. + return false; + } + + return RecursivelyCreateDir(path.substr(0, slashpos), mode) && + CreateDir(path, mode); +} + +void File::DeleteRecursively(const string& name, + void* dummy1, void* dummy2) { + // We don't care too much about error checking here since this is only used + // in tests to delete temporary directories that are under /tmp anyway. + +#ifdef _MSC_VER + // This interface is so weird. + WIN32_FIND_DATA find_data; + HANDLE find_handle = FindFirstFile((name + "/*").c_str(), &find_data); + if (find_handle == INVALID_HANDLE_VALUE) { + // Just delete it, whatever it is. + DeleteFile(name.c_str()); + RemoveDirectory(name.c_str()); + return; + } + + do { + string entry_name = find_data.cFileName; + if (entry_name != "." && entry_name != "..") { + string path = name + "/" + entry_name; + if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + DeleteRecursively(path, NULL, NULL); + RemoveDirectory(path.c_str()); + } else { + DeleteFile(path.c_str()); + } + } + } while(FindNextFile(find_handle, &find_data)); + FindClose(find_handle); + + RemoveDirectory(name.c_str()); +#else + // Use opendir()! Yay! + // lstat = Don't follow symbolic links. + struct stat stats; + if (lstat(name.c_str(), &stats) != 0) return; + + if (S_ISDIR(stats.st_mode)) { + DIR* dir = opendir(name.c_str()); + if (dir != NULL) { + while (true) { + struct dirent* entry = readdir(dir); + if (entry == NULL) break; + string entry_name = entry->d_name; + if (entry_name != "." && entry_name != "..") { + DeleteRecursively(name + "/" + entry_name, NULL, NULL); + } + } + } + + closedir(dir); + rmdir(name.c_str()); + + } else if (S_ISREG(stats.st_mode)) { + remove(name.c_str()); + } +#endif +} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/file.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/file.h new file mode 100644 index 0000000..a6b1c76 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/file.h @@ -0,0 +1,83 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// emulates google3/file/base/file.h + +#ifndef GOOGLE_PROTOBUF_TESTING_FILE_H__ +#define GOOGLE_PROTOBUF_TESTING_FILE_H__ + +#include + +namespace google { +namespace protobuf { + +const int DEFAULT_FILE_MODE = 0777; + +// Protocol buffer code only uses a couple static methods of File, and only +// in tests. +class File { + public: + // Check if the file exists. + static bool Exists(const string& name); + + // Read an entire file to a string. Return true if successful, false + // otherwise. + static bool ReadFileToString(const string& name, string* output); + + // Same as above, but crash on failure. + static void ReadFileToStringOrDie(const string& name, string* output); + + // Create a file and write a string to it. + static void WriteStringToFileOrDie(const string& contents, + const string& name); + + // Create a directory. + static bool CreateDir(const string& name, int mode); + + // Create a directory and all parent directories if necessary. + static bool RecursivelyCreateDir(const string& path, int mode); + + // If "name" is a file, we delete it. If it is a directory, we + // call DeleteRecursively() for each file or directory (other than + // dot and double-dot) within it, and then delete the directory itself. + // The "dummy" parameters have a meaning in the original version of this + // method but they are not used anywhere in protocol buffers. + static void DeleteRecursively(const string& name, + void* dummy1, void* dummy2); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(File); +}; + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_TESTING_FILE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/googletest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/googletest.cc new file mode 100644 index 0000000..a8da6b1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/googletest.cc @@ -0,0 +1,255 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// emulates google3/testing/base/public/googletest.cc + +#include +#include +#include +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#include +#else +#include +#endif +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +#ifdef _WIN32 +#define mkdir(name, mode) mkdir(name) +#endif + +#ifndef O_BINARY +#ifdef _O_BINARY +#define O_BINARY _O_BINARY +#else +#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. +#endif +#endif + +string TestSourceDir() { +#ifdef _MSC_VER + // Look for the "src" directory. + string prefix = "."; + + while (!File::Exists(prefix + "/src/google/protobuf")) { + if (!File::Exists(prefix)) { + GOOGLE_LOG(FATAL) + << "Could not find protobuf source code. Please run tests from " + "somewhere within the protobuf source package."; + } + prefix += "/.."; + } + return prefix + "/src"; +#else + // automake sets the "srcdir" environment variable. + char* result = getenv("srcdir"); + if (result == NULL) { + // Otherwise, the test must be run from the source directory. + return "."; + } else { + return result; + } +#endif +} + +namespace { + +string GetTemporaryDirectoryName() { + // tmpnam() is generally not considered safe but we're only using it for + // testing. We cannot use tmpfile() or mkstemp() since we're creating a + // directory. + char b[L_tmpnam + 1]; // HPUX multithread return 0 if s is 0 + string result = tmpnam(b); +#ifdef _WIN32 + // On Win32, tmpnam() returns a file prefixed with '\', but which is supposed + // to be used in the current working directory. WTF? + if (HasPrefixString(result, "\\")) { + result.erase(0, 1); + } +#endif // _WIN32 + return result; +} + +// Creates a temporary directory on demand and deletes it when the process +// quits. +class TempDirDeleter { + public: + TempDirDeleter() {} + ~TempDirDeleter() { + if (!name_.empty()) { + File::DeleteRecursively(name_, NULL, NULL); + } + } + + string GetTempDir() { + if (name_.empty()) { + name_ = GetTemporaryDirectoryName(); + GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno); + + // Stick a file in the directory that tells people what this is, in case + // we abort and don't get a chance to delete it. + File::WriteStringToFileOrDie("", name_ + "/TEMP_DIR_FOR_PROTOBUF_TESTS"); + } + return name_; + } + + private: + string name_; +}; + +TempDirDeleter temp_dir_deleter_; + +} // namespace + +string TestTempDir() { + return temp_dir_deleter_.GetTempDir(); +} + +// TODO(kenton): Share duplicated code below. Too busy/lazy for now. + +static string stdout_capture_filename_; +static string stderr_capture_filename_; +static int original_stdout_ = -1; +static int original_stderr_ = -1; + +void CaptureTestStdout() { + GOOGLE_CHECK_EQ(original_stdout_, -1) << "Already capturing."; + + stdout_capture_filename_ = TestTempDir() + "/captured_stdout"; + + int fd = open(stdout_capture_filename_.c_str(), + O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777); + GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno); + + original_stdout_ = dup(1); + close(1); + dup2(fd, 1); + close(fd); +} + +void CaptureTestStderr() { + GOOGLE_CHECK_EQ(original_stderr_, -1) << "Already capturing."; + + stderr_capture_filename_ = TestTempDir() + "/captured_stderr"; + + int fd = open(stderr_capture_filename_.c_str(), + O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777); + GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno); + + original_stderr_ = dup(2); + close(2); + dup2(fd, 2); + close(fd); +} + +string GetCapturedTestStdout() { + GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing."; + + close(1); + dup2(original_stdout_, 1); + original_stdout_ = -1; + + string result; + File::ReadFileToStringOrDie(stdout_capture_filename_, &result); + + remove(stdout_capture_filename_.c_str()); + + return result; +} + +string GetCapturedTestStderr() { + GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing."; + + close(2); + dup2(original_stderr_, 2); + original_stderr_ = -1; + + string result; + File::ReadFileToStringOrDie(stderr_capture_filename_, &result); + + remove(stderr_capture_filename_.c_str()); + + return result; +} + +ScopedMemoryLog* ScopedMemoryLog::active_log_ = NULL; + +ScopedMemoryLog::ScopedMemoryLog() { + GOOGLE_CHECK(active_log_ == NULL); + active_log_ = this; + old_handler_ = SetLogHandler(&HandleLog); +} + +ScopedMemoryLog::~ScopedMemoryLog() { + SetLogHandler(old_handler_); + active_log_ = NULL; +} + +const vector& ScopedMemoryLog::GetMessages(LogLevel level) { + GOOGLE_CHECK(level == ERROR || + level == WARNING); + return messages_[level]; +} + +void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, + int line, const string& message) { + GOOGLE_CHECK(active_log_ != NULL); + if (level == ERROR || level == WARNING) { + active_log_->messages_[level].push_back(message); + } +} + +namespace { + +// Force shutdown at process exit so that we can test for memory leaks. To +// actually check for leaks, I suggest using the heap checker included with +// google-perftools. Set it to "draconian" mode to ensure that every last +// call to malloc() has a corresponding free(). +struct ForceShutdown { + ~ForceShutdown() { + ShutdownProtobufLibrary(); + } +} force_shutdown; + +} // namespace + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/googletest.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/googletest.h new file mode 100644 index 0000000..003be10 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/googletest.h @@ -0,0 +1,102 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// emulates google3/testing/base/public/googletest.h + +#ifndef GOOGLE_PROTOBUF_GOOGLETEST_H__ +#define GOOGLE_PROTOBUF_GOOGLETEST_H__ + +#include +#include +#include + +// Disable death tests if we use exceptions in CHECK(). +#if !PROTOBUF_USE_EXCEPTIONS && defined(GTEST_HAS_DEATH_TEST) +#define PROTOBUF_HAS_DEATH_TEST +#endif + +namespace google { +namespace protobuf { + +// When running unittests, get the directory containing the source code. +string TestSourceDir(); + +// When running unittests, get a directory where temporary files may be +// placed. +string TestTempDir(); + +// Capture all text written to stdout or stderr. +void CaptureTestStdout(); +void CaptureTestStderr(); + +// Stop capturing stdout or stderr and return the text captured. +string GetCapturedTestStdout(); +string GetCapturedTestStderr(); + +// For use with ScopedMemoryLog::GetMessages(). Inside Google the LogLevel +// constants don't have the LOGLEVEL_ prefix, so the code that used +// ScopedMemoryLog refers to LOGLEVEL_ERROR as just ERROR. +#undef ERROR // defend against promiscuous windows.h +static const LogLevel ERROR = LOGLEVEL_ERROR; +static const LogLevel WARNING = LOGLEVEL_WARNING; + +// Receives copies of all LOG(ERROR) messages while in scope. Sample usage: +// { +// ScopedMemoryLog log; // constructor registers object as a log sink +// SomeRoutineThatMayLogMessages(); +// const vector& warnings = log.GetMessages(ERROR); +// } // destructor unregisters object as a log sink +// This is a dummy implementation which covers only what is used by protocol +// buffer unit tests. +class ScopedMemoryLog { + public: + ScopedMemoryLog(); + virtual ~ScopedMemoryLog(); + + // Fetches all messages with the given severity level. + const vector& GetMessages(LogLevel error); + + private: + map > messages_; + LogHandler* old_handler_; + + static void HandleLog(LogLevel level, const char* filename, int line, + const string& message); + + static ScopedMemoryLog* active_log_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedMemoryLog); +}; + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_GOOGLETEST_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/zcgunzip.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/zcgunzip.cc new file mode 100644 index 0000000..a619785 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/zcgunzip.cc @@ -0,0 +1,73 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2009 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: brianolson@google.com (Brian Olson) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Test program to verify that GzipInputStream is compatible with command line +// gunzip or java.util.zip.GzipInputStream +// +// Reads gzip stream on standard input and writes decompressed data to standard +// output. + +#include "config.h" + +#include +#include +#include +#include + +#include +#include + +using google::protobuf::io::FileInputStream; +using google::protobuf::io::GzipInputStream; + +int main(int argc, const char** argv) { + FileInputStream fin(STDIN_FILENO); + GzipInputStream in(&fin); + + while (true) { + const void* inptr; + int inlen; + bool ok; + ok = in.Next(&inptr, &inlen); + if (!ok) { + break; + } + if (inlen > 0) { + int err = write(STDOUT_FILENO, inptr, inlen); + assert(err == inlen); + } + } + + return 0; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/zcgzip.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/zcgzip.cc new file mode 100644 index 0000000..9133275 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/testing/zcgzip.cc @@ -0,0 +1,79 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2009 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: brianolson@google.com (Brian Olson) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Test program to verify that GzipOutputStream is compatible with command line +// gzip or java.util.zip.GzipOutputStream +// +// Reads data on standard input and writes compressed gzip stream to standard +// output. + +#include "config.h" + +#include +#include +#include + +#include +#include + +using google::protobuf::io::FileOutputStream; +using google::protobuf::io::GzipOutputStream; + +int main(int argc, const char** argv) { + FileOutputStream fout(STDOUT_FILENO); + GzipOutputStream out(&fout); + int readlen; + + while (true) { + void* outptr; + int outlen; + bool ok; + do { + ok = out.Next(&outptr, &outlen); + if (!ok) { + break; + } + } while (outlen <= 0); + readlen = read(STDIN_FILENO, outptr, outlen); + if (readlen <= 0) { + out.BackUp(outlen); + break; + } + if (readlen < outlen) { + out.BackUp(outlen - readlen); + } + } + + return 0; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format.cc new file mode 100644 index 0000000..cabb99e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format.cc @@ -0,0 +1,1521 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jschorr@google.com (Joseph Schorr) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +string Message::DebugString() const { + string debug_string; + + TextFormat::PrintToString(*this, &debug_string); + + return debug_string; +} + +string Message::ShortDebugString() const { + string debug_string; + + TextFormat::Printer printer; + printer.SetSingleLineMode(true); + + printer.PrintToString(*this, &debug_string); + // Single line mode currently might have an extra space at the end. + if (debug_string.size() > 0 && + debug_string[debug_string.size() - 1] == ' ') { + debug_string.resize(debug_string.size() - 1); + } + + return debug_string; +} + +string Message::Utf8DebugString() const { + string debug_string; + + TextFormat::Printer printer; + printer.SetUseUtf8StringEscaping(true); + + printer.PrintToString(*this, &debug_string); + + return debug_string; +} + +void Message::PrintDebugString() const { + printf("%s", DebugString().c_str()); +} + + +// =========================================================================== +// Implementation of the parse information tree class. +TextFormat::ParseInfoTree::ParseInfoTree() { } + +TextFormat::ParseInfoTree::~ParseInfoTree() { + // Remove any nested information trees, as they are owned by this tree. + for (NestedMap::iterator it = nested_.begin(); it != nested_.end(); ++it) { + STLDeleteElements(&(it->second)); + } +} + +void TextFormat::ParseInfoTree::RecordLocation( + const FieldDescriptor* field, + TextFormat::ParseLocation location) { + locations_[field].push_back(location); +} + +TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested( + const FieldDescriptor* field) { + // Owned by us in the map. + TextFormat::ParseInfoTree* instance = new TextFormat::ParseInfoTree(); + vector* trees = &nested_[field]; + GOOGLE_CHECK(trees); + trees->push_back(instance); + return instance; +} + +void CheckFieldIndex(const FieldDescriptor* field, int index) { + if (field == NULL) { return; } + + if (field->is_repeated() && index == -1) { + GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. " + << "Field: " << field->name(); + } else if (!field->is_repeated() && index != -1) { + GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields." + << "Field: " << field->name(); + } +} + +TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation( + const FieldDescriptor* field, int index) const { + CheckFieldIndex(field, index); + if (index == -1) { index = 0; } + + const vector* locations = + FindOrNull(locations_, field); + if (locations == NULL || index >= locations->size()) { + return TextFormat::ParseLocation(); + } + + return (*locations)[index]; +} + +TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested( + const FieldDescriptor* field, int index) const { + CheckFieldIndex(field, index); + if (index == -1) { index = 0; } + + const vector* trees = FindOrNull(nested_, field); + if (trees == NULL || index >= trees->size()) { + return NULL; + } + + return (*trees)[index]; +} + + +// =========================================================================== +// Internal class for parsing an ASCII representation of a Protocol Message. +// This class makes use of the Protocol Message compiler's tokenizer found +// in //google/protobuf/io/tokenizer.h. Note that class's Parse +// method is *not* thread-safe and should only be used in a single thread at +// a time. + +// Makes code slightly more readable. The meaning of "DO(foo)" is +// "Execute foo and fail if it fails.", where failure is indicated by +// returning false. Borrowed from parser.cc (Thanks Kenton!). +#define DO(STATEMENT) if (STATEMENT) {} else return false + +class TextFormat::Parser::ParserImpl { + public: + + // Determines if repeated values for a non-repeated field are + // permitted, e.g., the string "foo: 1 foo: 2" for a + // required/optional field named "foo". + enum SingularOverwritePolicy { + ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained + FORBID_SINGULAR_OVERWRITES = 1, // an error is issued + }; + + ParserImpl(const Descriptor* root_message_type, + io::ZeroCopyInputStream* input_stream, + io::ErrorCollector* error_collector, + TextFormat::Finder* finder, + ParseInfoTree* parse_info_tree, + SingularOverwritePolicy singular_overwrite_policy, + bool allow_unknown_field) + : error_collector_(error_collector), + finder_(finder), + parse_info_tree_(parse_info_tree), + tokenizer_error_collector_(this), + tokenizer_(input_stream, &tokenizer_error_collector_), + root_message_type_(root_message_type), + singular_overwrite_policy_(singular_overwrite_policy), + allow_unknown_field_(allow_unknown_field), + had_errors_(false) { + // For backwards-compatibility with proto1, we need to allow the 'f' suffix + // for floats. + tokenizer_.set_allow_f_after_float(true); + + // '#' starts a comment. + tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE); + + // Consume the starting token. + tokenizer_.Next(); + } + ~ParserImpl() { } + + // Parses the ASCII representation specified in input and saves the + // information into the output pointer (a Message). Returns + // false if an error occurs (an error will also be logged to + // GOOGLE_LOG(ERROR)). + bool Parse(Message* output) { + // Consume fields until we cannot do so anymore. + while(true) { + if (LookingAtType(io::Tokenizer::TYPE_END)) { + return !had_errors_; + } + + DO(ConsumeField(output)); + } + } + + bool ParseField(const FieldDescriptor* field, Message* output) { + bool suc; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + suc = ConsumeFieldMessage(output, output->GetReflection(), field); + } else { + suc = ConsumeFieldValue(output, output->GetReflection(), field); + } + return suc && LookingAtType(io::Tokenizer::TYPE_END); + } + + void ReportError(int line, int col, const string& message) { + had_errors_ = true; + if (error_collector_ == NULL) { + if (line >= 0) { + GOOGLE_LOG(ERROR) << "Error parsing text-format " + << root_message_type_->full_name() + << ": " << (line + 1) << ":" + << (col + 1) << ": " << message; + } else { + GOOGLE_LOG(ERROR) << "Error parsing text-format " + << root_message_type_->full_name() + << ": " << message; + } + } else { + error_collector_->AddError(line, col, message); + } + } + + void ReportWarning(int line, int col, const string& message) { + if (error_collector_ == NULL) { + if (line >= 0) { + GOOGLE_LOG(WARNING) << "Warning parsing text-format " + << root_message_type_->full_name() + << ": " << (line + 1) << ":" + << (col + 1) << ": " << message; + } else { + GOOGLE_LOG(WARNING) << "Warning parsing text-format " + << root_message_type_->full_name() + << ": " << message; + } + } else { + error_collector_->AddWarning(line, col, message); + } + } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl); + + // Reports an error with the given message with information indicating + // the position (as derived from the current token). + void ReportError(const string& message) { + ReportError(tokenizer_.current().line, tokenizer_.current().column, + message); + } + + // Reports a warning with the given message with information indicating + // the position (as derived from the current token). + void ReportWarning(const string& message) { + ReportWarning(tokenizer_.current().line, tokenizer_.current().column, + message); + } + + // Consumes the specified message with the given starting delimeter. + // This method checks to see that the end delimeter at the conclusion of + // the consumption matches the starting delimeter passed in here. + bool ConsumeMessage(Message* message, const string delimeter) { + while (!LookingAt(">") && !LookingAt("}")) { + DO(ConsumeField(message)); + } + + // Confirm that we have a valid ending delimeter. + DO(Consume(delimeter)); + + return true; + } + + // Consumes the current field (as returned by the tokenizer) on the + // passed in message. + bool ConsumeField(Message* message) { + const Reflection* reflection = message->GetReflection(); + const Descriptor* descriptor = message->GetDescriptor(); + + string field_name; + + const FieldDescriptor* field = NULL; + int start_line = tokenizer_.current().line; + int start_column = tokenizer_.current().column; + + if (TryConsume("[")) { + // Extension. + DO(ConsumeIdentifier(&field_name)); + while (TryConsume(".")) { + string part; + DO(ConsumeIdentifier(&part)); + field_name += "."; + field_name += part; + } + DO(Consume("]")); + + field = (finder_ != NULL + ? finder_->FindExtension(message, field_name) + : reflection->FindKnownExtensionByName(field_name)); + + if (field == NULL) { + if (!allow_unknown_field_) { + ReportError("Extension \"" + field_name + "\" is not defined or " + "is not an extension of \"" + + descriptor->full_name() + "\"."); + return false; + } else { + ReportWarning("Extension \"" + field_name + "\" is not defined or " + "is not an extension of \"" + + descriptor->full_name() + "\"."); + } + } + } else { + DO(ConsumeIdentifier(&field_name)); + + field = descriptor->FindFieldByName(field_name); + // Group names are expected to be capitalized as they appear in the + // .proto file, which actually matches their type names, not their field + // names. + if (field == NULL) { + string lower_field_name = field_name; + LowerString(&lower_field_name); + field = descriptor->FindFieldByName(lower_field_name); + // If the case-insensitive match worked but the field is NOT a group, + if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) { + field = NULL; + } + } + // Again, special-case group names as described above. + if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP + && field->message_type()->name() != field_name) { + field = NULL; + } + + if (field == NULL) { + if (!allow_unknown_field_) { + ReportError("Message type \"" + descriptor->full_name() + + "\" has no field named \"" + field_name + "\"."); + return false; + } else { + ReportWarning("Message type \"" + descriptor->full_name() + + "\" has no field named \"" + field_name + "\"."); + } + } + } + + // Skips unknown field. + if (field == NULL) { + GOOGLE_CHECK(allow_unknown_field_); + // Try to guess the type of this field. + // If this field is not a message, there should be a ":" between the + // field name and the field value and also the field value should not + // start with "{" or "<" which indicates the begining of a message body. + // If there is no ":" or there is a "{" or "<" after ":", this field has + // to be a message or the input is ill-formed. + if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) { + return SkipFieldValue(); + } else { + return SkipFieldMessage(); + } + } + + // Fail if the field is not repeated and it has already been specified. + if ((singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) && + !field->is_repeated() && reflection->HasField(*message, field)) { + ReportError("Non-repeated field \"" + field_name + + "\" is specified multiple times."); + return false; + } + + // Perform special handling for embedded message types. + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + // ':' is optional here. + TryConsume(":"); + DO(ConsumeFieldMessage(message, reflection, field)); + } else { + DO(Consume(":")); + if (field->is_repeated() && TryConsume("[")) { + // Short repeated format, e.g. "foo: [1, 2, 3]" + while (true) { + DO(ConsumeFieldValue(message, reflection, field)); + if (TryConsume("]")) { + break; + } + DO(Consume(",")); + } + } else { + DO(ConsumeFieldValue(message, reflection, field)); + } + } + + // For historical reasons, fields may optionally be separated by commas or + // semicolons. + TryConsume(";") || TryConsume(","); + + if (field->options().deprecated()) { + ReportWarning("text format contains deprecated field \"" + + field_name + "\""); + } + + // If a parse info tree exists, add the location for the parsed + // field. + if (parse_info_tree_ != NULL) { + RecordLocation(parse_info_tree_, field, + ParseLocation(start_line, start_column)); + } + + return true; + } + + // Skips the next field including the field's name and value. + bool SkipField() { + string field_name; + if (TryConsume("[")) { + // Extension name. + DO(ConsumeIdentifier(&field_name)); + while (TryConsume(".")) { + string part; + DO(ConsumeIdentifier(&part)); + field_name += "."; + field_name += part; + } + DO(Consume("]")); + } else { + DO(ConsumeIdentifier(&field_name)); + } + + // Try to guess the type of this field. + // If this field is not a message, there should be a ":" between the + // field name and the field value and also the field value should not + // start with "{" or "<" which indicates the begining of a message body. + // If there is no ":" or there is a "{" or "<" after ":", this field has + // to be a message or the input is ill-formed. + if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) { + DO(SkipFieldValue()); + } else { + DO(SkipFieldMessage()); + } + // For historical reasons, fields may optionally be separated by commas or + // semicolons. + TryConsume(";") || TryConsume(","); + return true; + } + + bool ConsumeFieldMessage(Message* message, + const Reflection* reflection, + const FieldDescriptor* field) { + + // If the parse information tree is not NULL, create a nested one + // for the nested message. + ParseInfoTree* parent = parse_info_tree_; + if (parent != NULL) { + parse_info_tree_ = CreateNested(parent, field); + } + + string delimeter; + if (TryConsume("<")) { + delimeter = ">"; + } else { + DO(Consume("{")); + delimeter = "}"; + } + + if (field->is_repeated()) { + DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter)); + } else { + DO(ConsumeMessage(reflection->MutableMessage(message, field), + delimeter)); + } + + // Reset the parse information tree. + parse_info_tree_ = parent; + return true; + } + + // Skips the whole body of a message including the begining delimeter and + // the ending delimeter. + bool SkipFieldMessage() { + string delimeter; + if (TryConsume("<")) { + delimeter = ">"; + } else { + DO(Consume("{")); + delimeter = "}"; + } + while (!LookingAt(">") && !LookingAt("}")) { + DO(SkipField()); + } + DO(Consume(delimeter)); + return true; + } + + bool ConsumeFieldValue(Message* message, + const Reflection* reflection, + const FieldDescriptor* field) { + +// Define an easy to use macro for setting fields. This macro checks +// to see if the field is repeated (in which case we need to use the Add +// methods or not (in which case we need to use the Set methods). +#define SET_FIELD(CPPTYPE, VALUE) \ + if (field->is_repeated()) { \ + reflection->Add##CPPTYPE(message, field, VALUE); \ + } else { \ + reflection->Set##CPPTYPE(message, field, VALUE); \ + } \ + + switch(field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: { + int64 value; + DO(ConsumeSignedInteger(&value, kint32max)); + SET_FIELD(Int32, static_cast(value)); + break; + } + + case FieldDescriptor::CPPTYPE_UINT32: { + uint64 value; + DO(ConsumeUnsignedInteger(&value, kuint32max)); + SET_FIELD(UInt32, static_cast(value)); + break; + } + + case FieldDescriptor::CPPTYPE_INT64: { + int64 value; + DO(ConsumeSignedInteger(&value, kint64max)); + SET_FIELD(Int64, value); + break; + } + + case FieldDescriptor::CPPTYPE_UINT64: { + uint64 value; + DO(ConsumeUnsignedInteger(&value, kuint64max)); + SET_FIELD(UInt64, value); + break; + } + + case FieldDescriptor::CPPTYPE_FLOAT: { + double value; + DO(ConsumeDouble(&value)); + SET_FIELD(Float, static_cast(value)); + break; + } + + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value; + DO(ConsumeDouble(&value)); + SET_FIELD(Double, value); + break; + } + + case FieldDescriptor::CPPTYPE_STRING: { + string value; + DO(ConsumeString(&value)); + SET_FIELD(String, value); + break; + } + + case FieldDescriptor::CPPTYPE_BOOL: { + if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + uint64 value; + DO(ConsumeUnsignedInteger(&value, 1)); + SET_FIELD(Bool, value); + } else { + string value; + DO(ConsumeIdentifier(&value)); + if (value == "true" || value == "t") { + SET_FIELD(Bool, true); + } else if (value == "false" || value == "f") { + SET_FIELD(Bool, false); + } else { + ReportError("Invalid value for boolean field \"" + field->name() + + "\". Value: \"" + value + "\"."); + return false; + } + } + break; + } + + case FieldDescriptor::CPPTYPE_ENUM: { + string value; + const EnumDescriptor* enum_type = field->enum_type(); + const EnumValueDescriptor* enum_value = NULL; + + if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + DO(ConsumeIdentifier(&value)); + // Find the enumeration value. + enum_value = enum_type->FindValueByName(value); + + } else if (LookingAt("-") || + LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + int64 int_value; + DO(ConsumeSignedInteger(&int_value, kint32max)); + value = SimpleItoa(int_value); // for error reporting + enum_value = enum_type->FindValueByNumber(int_value); + } else { + ReportError("Expected integer or identifier."); + return false; + } + + if (enum_value == NULL) { + ReportError("Unknown enumeration value of \"" + value + "\" for " + "field \"" + field->name() + "\"."); + return false; + } + + SET_FIELD(Enum, enum_value); + break; + } + + case FieldDescriptor::CPPTYPE_MESSAGE: { + // We should never get here. Put here instead of a default + // so that if new types are added, we get a nice compiler warning. + GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE"; + break; + } + } +#undef SET_FIELD + return true; + } + + bool SkipFieldValue() { + if (LookingAtType(io::Tokenizer::TYPE_STRING)) { + while (LookingAtType(io::Tokenizer::TYPE_STRING)) { + tokenizer_.Next(); + } + return true; + } + // Possible field values other than string: + // 12345 => TYPE_INTEGER + // -12345 => TYPE_SYMBOL + TYPE_INTEGER + // 1.2345 => TYPE_FLOAT + // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT + // inf => TYPE_IDENTIFIER + // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER + // TYPE_INTEGER => TYPE_IDENTIFIER + // Divides them into two group, one with TYPE_SYMBOL + // and the other without: + // Group one: + // 12345 => TYPE_INTEGER + // 1.2345 => TYPE_FLOAT + // inf => TYPE_IDENTIFIER + // TYPE_INTEGER => TYPE_IDENTIFIER + // Group two: + // -12345 => TYPE_SYMBOL + TYPE_INTEGER + // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT + // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER + // As we can see, the field value consists of an optional '-' and one of + // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER. + bool has_minus = TryConsume("-"); + if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) && + !LookingAtType(io::Tokenizer::TYPE_FLOAT) && + !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + return false; + } + // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field + // value while other combinations all generate valid values. + // We check if the value of this combination is valid here. + // TYPE_IDENTIFIER after a '-' should be one of the float values listed + // below: + // inf, inff, infinity, nan + if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + string text = tokenizer_.current().text; + LowerString(&text); + if (text != "inf" && + text != "infinity" && + text != "nan") { + ReportError("Invalid float number: " + text); + return false; + } + } + tokenizer_.Next(); + return true; + } + + // Returns true if the current token's text is equal to that specified. + bool LookingAt(const string& text) { + return tokenizer_.current().text == text; + } + + // Returns true if the current token's type is equal to that specified. + bool LookingAtType(io::Tokenizer::TokenType token_type) { + return tokenizer_.current().type == token_type; + } + + // Consumes an identifier and saves its value in the identifier parameter. + // Returns false if the token is not of type IDENTFIER. + bool ConsumeIdentifier(string* identifier) { + if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + ReportError("Expected identifier."); + return false; + } + + *identifier = tokenizer_.current().text; + + tokenizer_.Next(); + return true; + } + + // Consumes a string and saves its value in the text parameter. + // Returns false if the token is not of type STRING. + bool ConsumeString(string* text) { + if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { + ReportError("Expected string."); + return false; + } + + text->clear(); + while (LookingAtType(io::Tokenizer::TYPE_STRING)) { + io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text); + + tokenizer_.Next(); + } + + return true; + } + + // Consumes a uint64 and saves its value in the value parameter. + // Returns false if the token is not of type INTEGER. + bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) { + if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + ReportError("Expected integer."); + return false; + } + + if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, + max_value, value)) { + ReportError("Integer out of range."); + return false; + } + + tokenizer_.Next(); + return true; + } + + // Consumes an int64 and saves its value in the value parameter. + // Note that since the tokenizer does not support negative numbers, + // we actually may consume an additional token (for the minus sign) in this + // method. Returns false if the token is not an integer + // (signed or otherwise). + bool ConsumeSignedInteger(int64* value, uint64 max_value) { + bool negative = false; + + if (TryConsume("-")) { + negative = true; + // Two's complement always allows one more negative integer than + // positive. + ++max_value; + } + + uint64 unsigned_value; + + DO(ConsumeUnsignedInteger(&unsigned_value, max_value)); + + *value = static_cast(unsigned_value); + + if (negative) { + *value = -*value; + } + + return true; + } + + // Consumes a double and saves its value in the value parameter. + // Note that since the tokenizer does not support negative numbers, + // we actually may consume an additional token (for the minus sign) in this + // method. Returns false if the token is not a double + // (signed or otherwise). + bool ConsumeDouble(double* value) { + bool negative = false; + + if (TryConsume("-")) { + negative = true; + } + + // A double can actually be an integer, according to the tokenizer. + // Therefore, we must check both cases here. + if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + // We have found an integer value for the double. + uint64 integer_value; + DO(ConsumeUnsignedInteger(&integer_value, kuint64max)); + + *value = static_cast(integer_value); + } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { + // We have found a float value for the double. + *value = io::Tokenizer::ParseFloat(tokenizer_.current().text); + + // Mark the current token as consumed. + tokenizer_.Next(); + } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + string text = tokenizer_.current().text; + LowerString(&text); + if (text == "inf" || + text == "infinity") { + *value = std::numeric_limits::infinity(); + tokenizer_.Next(); + } else if (text == "nan") { + *value = std::numeric_limits::quiet_NaN(); + tokenizer_.Next(); + } else { + ReportError("Expected double."); + return false; + } + } else { + ReportError("Expected double."); + return false; + } + + if (negative) { + *value = -*value; + } + + return true; + } + + // Consumes a token and confirms that it matches that specified in the + // value parameter. Returns false if the token found does not match that + // which was specified. + bool Consume(const string& value) { + const string& current_value = tokenizer_.current().text; + + if (current_value != value) { + ReportError("Expected \"" + value + "\", found \"" + current_value + + "\"."); + return false; + } + + tokenizer_.Next(); + + return true; + } + + // Attempts to consume the supplied value. Returns false if a the + // token found does not match the value specified. + bool TryConsume(const string& value) { + if (tokenizer_.current().text == value) { + tokenizer_.Next(); + return true; + } else { + return false; + } + } + + // An internal instance of the Tokenizer's error collector, used to + // collect any base-level parse errors and feed them to the ParserImpl. + class ParserErrorCollector : public io::ErrorCollector { + public: + explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) : + parser_(parser) { } + + virtual ~ParserErrorCollector() { }; + + virtual void AddError(int line, int column, const string& message) { + parser_->ReportError(line, column, message); + } + + virtual void AddWarning(int line, int column, const string& message) { + parser_->ReportWarning(line, column, message); + } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector); + TextFormat::Parser::ParserImpl* parser_; + }; + + io::ErrorCollector* error_collector_; + TextFormat::Finder* finder_; + ParseInfoTree* parse_info_tree_; + ParserErrorCollector tokenizer_error_collector_; + io::Tokenizer tokenizer_; + const Descriptor* root_message_type_; + SingularOverwritePolicy singular_overwrite_policy_; + bool allow_unknown_field_; + bool had_errors_; +}; + +#undef DO + +// =========================================================================== +// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted +// from the Printer found in //google/protobuf/io/printer.h +class TextFormat::Printer::TextGenerator { + public: + explicit TextGenerator(io::ZeroCopyOutputStream* output, + int initial_indent_level) + : output_(output), + buffer_(NULL), + buffer_size_(0), + at_start_of_line_(true), + failed_(false), + indent_(""), + initial_indent_level_(initial_indent_level) { + indent_.resize(initial_indent_level_ * 2, ' '); + } + + ~TextGenerator() { + // Only BackUp() if we're sure we've successfully called Next() at least + // once. + if (!failed_ && buffer_size_ > 0) { + output_->BackUp(buffer_size_); + } + } + + // Indent text by two spaces. After calling Indent(), two spaces will be + // inserted at the beginning of each line of text. Indent() may be called + // multiple times to produce deeper indents. + void Indent() { + indent_ += " "; + } + + // Reduces the current indent level by two spaces, or crashes if the indent + // level is zero. + void Outdent() { + if (indent_.empty() || + indent_.size() < initial_indent_level_ * 2) { + GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; + return; + } + + indent_.resize(indent_.size() - 2); + } + + // Print text to the output stream. + void Print(const string& str) { + Print(str.data(), str.size()); + } + + // Print text to the output stream. + void Print(const char* text) { + Print(text, strlen(text)); + } + + // Print text to the output stream. + void Print(const char* text, int size) { + int pos = 0; // The number of bytes we've written so far. + + for (int i = 0; i < size; i++) { + if (text[i] == '\n') { + // Saw newline. If there is more text, we may need to insert an indent + // here. So, write what we have so far, including the '\n'. + Write(text + pos, i - pos + 1); + pos = i + 1; + + // Setting this true will cause the next Write() to insert an indent + // first. + at_start_of_line_ = true; + } + } + + // Write the rest. + Write(text + pos, size - pos); + } + + // True if any write to the underlying stream failed. (We don't just + // crash in this case because this is an I/O failure, not a programming + // error.) + bool failed() const { return failed_; } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator); + + void Write(const char* data, int size) { + if (failed_) return; + if (size == 0) return; + + if (at_start_of_line_) { + // Insert an indent. + at_start_of_line_ = false; + Write(indent_.data(), indent_.size()); + if (failed_) return; + } + + while (size > buffer_size_) { + // Data exceeds space in the buffer. Copy what we can and request a + // new buffer. + memcpy(buffer_, data, buffer_size_); + data += buffer_size_; + size -= buffer_size_; + void* void_buffer; + failed_ = !output_->Next(&void_buffer, &buffer_size_); + if (failed_) return; + buffer_ = reinterpret_cast(void_buffer); + } + + // Buffer is big enough to receive the data; copy it. + memcpy(buffer_, data, size); + buffer_ += size; + buffer_size_ -= size; + } + + io::ZeroCopyOutputStream* const output_; + char* buffer_; + int buffer_size_; + bool at_start_of_line_; + bool failed_; + + string indent_; + int initial_indent_level_; +}; + +// =========================================================================== + +TextFormat::Finder::~Finder() { +} + +TextFormat::Parser::Parser() + : error_collector_(NULL), + finder_(NULL), + parse_info_tree_(NULL), + allow_partial_(false), + allow_unknown_field_(false) { +} + +TextFormat::Parser::~Parser() {} + +bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, + Message* output) { + output->Clear(); + ParserImpl parser(output->GetDescriptor(), input, error_collector_, + finder_, parse_info_tree_, + ParserImpl::FORBID_SINGULAR_OVERWRITES, + allow_unknown_field_); + return MergeUsingImpl(input, output, &parser); +} + +bool TextFormat::Parser::ParseFromString(const string& input, + Message* output) { + io::ArrayInputStream input_stream(input.data(), input.size()); + return Parse(&input_stream, output); +} + +bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, + Message* output) { + ParserImpl parser(output->GetDescriptor(), input, error_collector_, + finder_, parse_info_tree_, + ParserImpl::ALLOW_SINGULAR_OVERWRITES, + allow_unknown_field_); + return MergeUsingImpl(input, output, &parser); +} + +bool TextFormat::Parser::MergeFromString(const string& input, + Message* output) { + io::ArrayInputStream input_stream(input.data(), input.size()); + return Merge(&input_stream, output); +} + +bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input, + Message* output, + ParserImpl* parser_impl) { + if (!parser_impl->Parse(output)) return false; + if (!allow_partial_ && !output->IsInitialized()) { + vector missing_fields; + output->FindInitializationErrors(&missing_fields); + parser_impl->ReportError(-1, 0, "Message missing required fields: " + + JoinStrings(missing_fields, ", ")); + return false; + } + return true; +} + +bool TextFormat::Parser::ParseFieldValueFromString( + const string& input, + const FieldDescriptor* field, + Message* output) { + io::ArrayInputStream input_stream(input.data(), input.size()); + ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_, + finder_, parse_info_tree_, + ParserImpl::ALLOW_SINGULAR_OVERWRITES, + allow_unknown_field_); + return parser.ParseField(field, output); +} + +/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, + Message* output) { + return Parser().Parse(input, output); +} + +/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input, + Message* output) { + return Parser().Merge(input, output); +} + +/* static */ bool TextFormat::ParseFromString(const string& input, + Message* output) { + return Parser().ParseFromString(input, output); +} + +/* static */ bool TextFormat::MergeFromString(const string& input, + Message* output) { + return Parser().MergeFromString(input, output); +} + +// =========================================================================== + +TextFormat::Printer::Printer() + : initial_indent_level_(0), + single_line_mode_(false), + use_short_repeated_primitives_(false), + utf8_string_escaping_(false) {} + +TextFormat::Printer::~Printer() {} + +bool TextFormat::Printer::PrintToString(const Message& message, + string* output) const { + GOOGLE_DCHECK(output) << "output specified is NULL"; + + output->clear(); + io::StringOutputStream output_stream(output); + + bool result = Print(message, &output_stream); + + return result; +} + +bool TextFormat::Printer::PrintUnknownFieldsToString( + const UnknownFieldSet& unknown_fields, + string* output) const { + GOOGLE_DCHECK(output) << "output specified is NULL"; + + output->clear(); + io::StringOutputStream output_stream(output); + return PrintUnknownFields(unknown_fields, &output_stream); +} + +bool TextFormat::Printer::Print(const Message& message, + io::ZeroCopyOutputStream* output) const { + TextGenerator generator(output, initial_indent_level_); + + Print(message, generator); + + // Output false if the generator failed internally. + return !generator.failed(); +} + +bool TextFormat::Printer::PrintUnknownFields( + const UnknownFieldSet& unknown_fields, + io::ZeroCopyOutputStream* output) const { + TextGenerator generator(output, initial_indent_level_); + + PrintUnknownFields(unknown_fields, generator); + + // Output false if the generator failed internally. + return !generator.failed(); +} + +void TextFormat::Printer::Print(const Message& message, + TextGenerator& generator) const { + const Reflection* reflection = message.GetReflection(); + vector fields; + reflection->ListFields(message, &fields); + for (int i = 0; i < fields.size(); i++) { + PrintField(message, reflection, fields[i], generator); + } + PrintUnknownFields(reflection->GetUnknownFields(message), generator); +} + +void TextFormat::Printer::PrintFieldValueToString( + const Message& message, + const FieldDescriptor* field, + int index, + string* output) const { + + GOOGLE_DCHECK(output) << "output specified is NULL"; + + output->clear(); + io::StringOutputStream output_stream(output); + TextGenerator generator(&output_stream, initial_indent_level_); + + PrintFieldValue(message, message.GetReflection(), field, index, generator); +} + +void TextFormat::Printer::PrintField(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) const { + if (use_short_repeated_primitives_ && + field->is_repeated() && + field->cpp_type() != FieldDescriptor::CPPTYPE_STRING && + field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { + PrintShortRepeatedField(message, reflection, field, generator); + return; + } + + int count = 0; + + if (field->is_repeated()) { + count = reflection->FieldSize(message, field); + } else if (reflection->HasField(message, field)) { + count = 1; + } + + for (int j = 0; j < count; ++j) { + PrintFieldName(message, reflection, field, generator); + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (single_line_mode_) { + generator.Print(" { "); + } else { + generator.Print(" {\n"); + generator.Indent(); + } + } else { + generator.Print(": "); + } + + // Write the field value. + int field_index = j; + if (!field->is_repeated()) { + field_index = -1; + } + + PrintFieldValue(message, reflection, field, field_index, generator); + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (single_line_mode_) { + generator.Print("} "); + } else { + generator.Outdent(); + generator.Print("}\n"); + } + } else { + if (single_line_mode_) { + generator.Print(" "); + } else { + generator.Print("\n"); + } + } + } +} + +void TextFormat::Printer::PrintShortRepeatedField( + const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) const { + // Print primitive repeated field in short form. + PrintFieldName(message, reflection, field, generator); + + int size = reflection->FieldSize(message, field); + generator.Print(": ["); + for (int i = 0; i < size; i++) { + if (i > 0) generator.Print(", "); + PrintFieldValue(message, reflection, field, i, generator); + } + if (single_line_mode_) { + generator.Print("] "); + } else { + generator.Print("]\n"); + } +} + +void TextFormat::Printer::PrintFieldName(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) const { + if (field->is_extension()) { + generator.Print("["); + // We special-case MessageSet elements for compatibility with proto1. + if (field->containing_type()->options().message_set_wire_format() + && field->type() == FieldDescriptor::TYPE_MESSAGE + && field->is_optional() + && field->extension_scope() == field->message_type()) { + generator.Print(field->message_type()->full_name()); + } else { + generator.Print(field->full_name()); + } + generator.Print("]"); + } else { + if (field->type() == FieldDescriptor::TYPE_GROUP) { + // Groups must be serialized with their original capitalization. + generator.Print(field->message_type()->name()); + } else { + generator.Print(field->name()); + } + } +} + +void TextFormat::Printer::PrintFieldValue( + const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + int index, + TextGenerator& generator) const { + GOOGLE_DCHECK(field->is_repeated() || (index == -1)) + << "Index must be -1 for non-repeated fields"; + + switch (field->cpp_type()) { +#define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + generator.Print(TO_STRING(field->is_repeated() ? \ + reflection->GetRepeated##METHOD(message, field, index) : \ + reflection->Get##METHOD(message, field))); \ + break; \ + + OUTPUT_FIELD( INT32, Int32, SimpleItoa); + OUTPUT_FIELD( INT64, Int64, SimpleItoa); + OUTPUT_FIELD(UINT32, UInt32, SimpleItoa); + OUTPUT_FIELD(UINT64, UInt64, SimpleItoa); + OUTPUT_FIELD( FLOAT, Float, SimpleFtoa); + OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa); +#undef OUTPUT_FIELD + + case FieldDescriptor::CPPTYPE_STRING: { + string scratch; + const string& value = field->is_repeated() ? + reflection->GetRepeatedStringReference( + message, field, index, &scratch) : + reflection->GetStringReference(message, field, &scratch); + + generator.Print("\""); + if (utf8_string_escaping_) { + generator.Print(strings::Utf8SafeCEscape(value)); + } else { + generator.Print(CEscape(value)); + } + generator.Print("\""); + + break; + } + + case FieldDescriptor::CPPTYPE_BOOL: + if (field->is_repeated()) { + generator.Print(reflection->GetRepeatedBool(message, field, index) + ? "true" : "false"); + } else { + generator.Print(reflection->GetBool(message, field) + ? "true" : "false"); + } + break; + + case FieldDescriptor::CPPTYPE_ENUM: + generator.Print(field->is_repeated() ? + reflection->GetRepeatedEnum(message, field, index)->name() : + reflection->GetEnum(message, field)->name()); + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + Print(field->is_repeated() ? + reflection->GetRepeatedMessage(message, field, index) : + reflection->GetMessage(message, field), + generator); + break; + } +} + +/* static */ bool TextFormat::Print(const Message& message, + io::ZeroCopyOutputStream* output) { + return Printer().Print(message, output); +} + +/* static */ bool TextFormat::PrintUnknownFields( + const UnknownFieldSet& unknown_fields, + io::ZeroCopyOutputStream* output) { + return Printer().PrintUnknownFields(unknown_fields, output); +} + +/* static */ bool TextFormat::PrintToString( + const Message& message, string* output) { + return Printer().PrintToString(message, output); +} + +/* static */ bool TextFormat::PrintUnknownFieldsToString( + const UnknownFieldSet& unknown_fields, string* output) { + return Printer().PrintUnknownFieldsToString(unknown_fields, output); +} + +/* static */ void TextFormat::PrintFieldValueToString( + const Message& message, + const FieldDescriptor* field, + int index, + string* output) { + return Printer().PrintFieldValueToString(message, field, index, output); +} + +/* static */ bool TextFormat::ParseFieldValueFromString( + const string& input, + const FieldDescriptor* field, + Message* message) { + return Parser().ParseFieldValueFromString(input, field, message); +} + +// Prints an integer as hex with a fixed number of digits dependent on the +// integer type. +template +static string PaddedHex(IntType value) { + string result; + result.reserve(sizeof(value) * 2); + for (int i = sizeof(value) * 2 - 1; i >= 0; i--) { + result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F)); + } + return result; +} + +void TextFormat::Printer::PrintUnknownFields( + const UnknownFieldSet& unknown_fields, TextGenerator& generator) const { + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + string field_number = SimpleItoa(field.number()); + + switch (field.type()) { + case UnknownField::TYPE_VARINT: + generator.Print(field_number); + generator.Print(": "); + generator.Print(SimpleItoa(field.varint())); + if (single_line_mode_) { + generator.Print(" "); + } else { + generator.Print("\n"); + } + break; + case UnknownField::TYPE_FIXED32: { + generator.Print(field_number); + generator.Print(": 0x"); + char buffer[kFastToBufferSize]; + generator.Print(FastHex32ToBuffer(field.fixed32(), buffer)); + if (single_line_mode_) { + generator.Print(" "); + } else { + generator.Print("\n"); + } + break; + } + case UnknownField::TYPE_FIXED64: { + generator.Print(field_number); + generator.Print(": 0x"); + char buffer[kFastToBufferSize]; + generator.Print(FastHex64ToBuffer(field.fixed64(), buffer)); + if (single_line_mode_) { + generator.Print(" "); + } else { + generator.Print("\n"); + } + break; + } + case UnknownField::TYPE_LENGTH_DELIMITED: { + generator.Print(field_number); + const string& value = field.length_delimited(); + UnknownFieldSet embedded_unknown_fields; + if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) { + // This field is parseable as a Message. + // So it is probably an embedded message. + if (single_line_mode_) { + generator.Print(" { "); + } else { + generator.Print(" {\n"); + generator.Indent(); + } + PrintUnknownFields(embedded_unknown_fields, generator); + if (single_line_mode_) { + generator.Print("} "); + } else { + generator.Outdent(); + generator.Print("}\n"); + } + } else { + // This field is not parseable as a Message. + // So it is probably just a plain string. + generator.Print(": \""); + generator.Print(CEscape(value)); + generator.Print("\""); + if (single_line_mode_) { + generator.Print(" "); + } else { + generator.Print("\n"); + } + } + break; + } + case UnknownField::TYPE_GROUP: + generator.Print(field_number); + if (single_line_mode_) { + generator.Print(" { "); + } else { + generator.Print(" {\n"); + generator.Indent(); + } + PrintUnknownFields(field.group(), generator); + if (single_line_mode_) { + generator.Print("} "); + } else { + generator.Outdent(); + generator.Print("}\n"); + } + break; + } + } +} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format.h new file mode 100644 index 0000000..01f3ffb --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format.h @@ -0,0 +1,369 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jschorr@google.com (Joseph Schorr) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Utilities for printing and parsing protocol messages in a human-readable, +// text-based format. + +#ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__ +#define GOOGLE_PROTOBUF_TEXT_FORMAT_H__ + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +namespace io { + class ErrorCollector; // tokenizer.h +} + +// This class implements protocol buffer text format. Printing and parsing +// protocol messages in text format is useful for debugging and human editing +// of messages. +// +// This class is really a namespace that contains only static methods. +class LIBPROTOBUF_EXPORT TextFormat { + public: + // Outputs a textual representation of the given message to the given + // output stream. + static bool Print(const Message& message, io::ZeroCopyOutputStream* output); + + // Print the fields in an UnknownFieldSet. They are printed by tag number + // only. Embedded messages are heuristically identified by attempting to + // parse them. + static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, + io::ZeroCopyOutputStream* output); + + // Like Print(), but outputs directly to a string. + static bool PrintToString(const Message& message, string* output); + + // Like PrintUnknownFields(), but outputs directly to a string. + static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, + string* output); + + // Outputs a textual representation of the value of the field supplied on + // the message supplied. For non-repeated fields, an index of -1 must + // be supplied. Note that this method will print the default value for a + // field if it is not set. + static void PrintFieldValueToString(const Message& message, + const FieldDescriptor* field, + int index, + string* output); + + // Class for those users which require more fine-grained control over how + // a protobuffer message is printed out. + class LIBPROTOBUF_EXPORT Printer { + public: + Printer(); + ~Printer(); + + // Like TextFormat::Print + bool Print(const Message& message, io::ZeroCopyOutputStream* output) const; + // Like TextFormat::PrintUnknownFields + bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, + io::ZeroCopyOutputStream* output) const; + // Like TextFormat::PrintToString + bool PrintToString(const Message& message, string* output) const; + // Like TextFormat::PrintUnknownFieldsToString + bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, + string* output) const; + // Like TextFormat::PrintFieldValueToString + void PrintFieldValueToString(const Message& message, + const FieldDescriptor* field, + int index, + string* output) const; + + // Adjust the initial indent level of all output. Each indent level is + // equal to two spaces. + void SetInitialIndentLevel(int indent_level) { + initial_indent_level_ = indent_level; + } + + // If printing in single line mode, then the entire message will be output + // on a single line with no line breaks. + void SetSingleLineMode(bool single_line_mode) { + single_line_mode_ = single_line_mode; + } + + // Set true to print repeated primitives in a format like: + // field_name: [1, 2, 3, 4] + // instead of printing each value on its own line. Short format applies + // only to primitive values -- i.e. everything except strings and + // sub-messages/groups. + void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) { + use_short_repeated_primitives_ = use_short_repeated_primitives; + } + + // Set true to output UTF-8 instead of ASCII. The only difference + // is that bytes >= 0x80 in string fields will not be escaped, + // because they are assumed to be part of UTF-8 multi-byte + // sequences. + void SetUseUtf8StringEscaping(bool as_utf8) { + utf8_string_escaping_ = as_utf8; + } + + private: + // Forward declaration of an internal class used to print the text + // output to the OutputStream (see text_format.cc for implementation). + class TextGenerator; + + // Internal Print method, used for writing to the OutputStream via + // the TextGenerator class. + void Print(const Message& message, + TextGenerator& generator) const; + + // Print a single field. + void PrintField(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) const; + + // Print a repeated primitive field in short form. + void PrintShortRepeatedField(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) const; + + // Print the name of a field -- i.e. everything that comes before the + // ':' for a single name/value pair. + void PrintFieldName(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) const; + + // Outputs a textual representation of the value of the field supplied on + // the message supplied or the default value if not set. + void PrintFieldValue(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + int index, + TextGenerator& generator) const; + + // Print the fields in an UnknownFieldSet. They are printed by tag number + // only. Embedded messages are heuristically identified by attempting to + // parse them. + void PrintUnknownFields(const UnknownFieldSet& unknown_fields, + TextGenerator& generator) const; + + int initial_indent_level_; + + bool single_line_mode_; + + bool use_short_repeated_primitives_; + + bool utf8_string_escaping_; + }; + + // Parses a text-format protocol message from the given input stream to + // the given message object. This function parses the format written + // by Print(). + static bool Parse(io::ZeroCopyInputStream* input, Message* output); + // Like Parse(), but reads directly from a string. + static bool ParseFromString(const string& input, Message* output); + + // Like Parse(), but the data is merged into the given message, as if + // using Message::MergeFrom(). + static bool Merge(io::ZeroCopyInputStream* input, Message* output); + // Like Merge(), but reads directly from a string. + static bool MergeFromString(const string& input, Message* output); + + // Parse the given text as a single field value and store it into the + // given field of the given message. If the field is a repeated field, + // the new value will be added to the end + static bool ParseFieldValueFromString(const string& input, + const FieldDescriptor* field, + Message* message); + + // Interface that TextFormat::Parser can use to find extensions. + // This class may be extended in the future to find more information + // like fields, etc. + class LIBPROTOBUF_EXPORT Finder { + public: + virtual ~Finder(); + + // Try to find an extension of *message by fully-qualified field + // name. Returns NULL if no extension is known for this name or number. + virtual const FieldDescriptor* FindExtension( + Message* message, + const string& name) const = 0; + }; + + // A location in the parsed text. + struct ParseLocation { + int line; + int column; + + ParseLocation() : line(-1), column(-1) {} + ParseLocation(int line_param, int column_param) + : line(line_param), column(column_param) {} + }; + + // Data structure which is populated with the locations of each field + // value parsed from the text. + class LIBPROTOBUF_EXPORT ParseInfoTree { + public: + ParseInfoTree(); + ~ParseInfoTree(); + + // Returns the parse location for index-th value of the field in the parsed + // text. If none exists, returns a location with line = -1. Index should be + // -1 for not-repeated fields. + ParseLocation GetLocation(const FieldDescriptor* field, int index) const; + + // Returns the parse info tree for the given field, which must be a message + // type. The nested information tree is owned by the root tree and will be + // deleted when it is deleted. + ParseInfoTree* GetTreeForNested(const FieldDescriptor* field, + int index) const; + + private: + // Allow the text format parser to record information into the tree. + friend class TextFormat; + + // Records the starting location of a single value for a field. + void RecordLocation(const FieldDescriptor* field, ParseLocation location); + + // Create and records a nested tree for a nested message field. + ParseInfoTree* CreateNested(const FieldDescriptor* field); + + // Defines the map from the index-th field descriptor to its parse location. + typedef map > LocationMap; + + // Defines the map from the index-th field descriptor to the nested parse + // info tree. + typedef map > NestedMap; + + LocationMap locations_; + NestedMap nested_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParseInfoTree); + }; + + // For more control over parsing, use this class. + class LIBPROTOBUF_EXPORT Parser { + public: + Parser(); + ~Parser(); + + // Like TextFormat::Parse(). + bool Parse(io::ZeroCopyInputStream* input, Message* output); + // Like TextFormat::ParseFromString(). + bool ParseFromString(const string& input, Message* output); + // Like TextFormat::Merge(). + bool Merge(io::ZeroCopyInputStream* input, Message* output); + // Like TextFormat::MergeFromString(). + bool MergeFromString(const string& input, Message* output); + + // Set where to report parse errors. If NULL (the default), errors will + // be printed to stderr. + void RecordErrorsTo(io::ErrorCollector* error_collector) { + error_collector_ = error_collector; + } + + // Set how parser finds extensions. If NULL (the default), the + // parser will use the standard Reflection object associated with + // the message being parsed. + void SetFinder(Finder* finder) { + finder_ = finder; + } + + // Sets where location information about the parse will be written. If NULL + // (the default), then no location will be written. + void WriteLocationsTo(ParseInfoTree* tree) { + parse_info_tree_ = tree; + } + + // Normally parsing fails if, after parsing, output->IsInitialized() + // returns false. Call AllowPartialMessage(true) to skip this check. + void AllowPartialMessage(bool allow) { + allow_partial_ = allow; + } + + // Like TextFormat::ParseFieldValueFromString + bool ParseFieldValueFromString(const string& input, + const FieldDescriptor* field, + Message* output); + + + private: + // Forward declaration of an internal class used to parse text + // representations (see text_format.cc for implementation). + class ParserImpl; + + // Like TextFormat::Merge(). The provided implementation is used + // to do the parsing. + bool MergeUsingImpl(io::ZeroCopyInputStream* input, + Message* output, + ParserImpl* parser_impl); + + io::ErrorCollector* error_collector_; + Finder* finder_; + ParseInfoTree* parse_info_tree_; + bool allow_partial_; + bool allow_unknown_field_; + }; + + private: + // Hack: ParseInfoTree declares TextFormat as a friend which should extend + // the friendship to TextFormat::Parser::ParserImpl, but unfortunately some + // old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide + // helpers for ParserImpl to call methods of ParseInfoTree. + static inline void RecordLocation(ParseInfoTree* info_tree, + const FieldDescriptor* field, + ParseLocation location); + static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree, + const FieldDescriptor* field); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat); +}; + +inline void TextFormat::RecordLocation(ParseInfoTree* info_tree, + const FieldDescriptor* field, + ParseLocation location) { + info_tree->RecordLocation(field, location); +} + +inline TextFormat::ParseInfoTree* TextFormat::CreateNested( + ParseInfoTree* info_tree, const FieldDescriptor* field) { + return info_tree->CreateNested(field); +} + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_TEXT_FORMAT_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format_unittest.cc new file mode 100644 index 0000000..304fb84 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/text_format_unittest.cc @@ -0,0 +1,1248 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jschorr@google.com (Joseph Schorr) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. +namespace text_format_unittest { + +inline bool IsNaN(double value) { + // NaN is never equal to anything, even itself. + return value != value; +} + +// A basic string with different escapable characters for testing. +const string kEscapeTestString = + "\"A string with ' characters \n and \r newlines and \t tabs and \001 " + "slashes \\ and multiple spaces"; + +// A representation of the above string with all the characters escaped. +const string kEscapeTestStringEscaped = + "\"\\\"A string with \\' characters \\n and \\r newlines " + "and \\t tabs and \\001 slashes \\\\ and multiple spaces\""; + +class TextFormatTest : public testing::Test { + public: + static void SetUpTestCase() { + File::ReadFileToStringOrDie( + TestSourceDir() + + "/google/protobuf/testdata/text_format_unittest_data.txt", + &static_proto_debug_string_); + } + + TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {} + + protected: + // Debug string read from text_format_unittest_data.txt. + const string proto_debug_string_; + unittest::TestAllTypes proto_; + + private: + static string static_proto_debug_string_; +}; +string TextFormatTest::static_proto_debug_string_; + +class TextFormatExtensionsTest : public testing::Test { + public: + static void SetUpTestCase() { + File::ReadFileToStringOrDie( + TestSourceDir() + + "/google/protobuf/testdata/" + "text_format_unittest_extensions_data.txt", + &static_proto_debug_string_); + } + + TextFormatExtensionsTest() + : proto_debug_string_(static_proto_debug_string_) {} + + protected: + // Debug string read from text_format_unittest_data.txt. + const string proto_debug_string_; + unittest::TestAllExtensions proto_; + + private: + static string static_proto_debug_string_; +}; +string TextFormatExtensionsTest::static_proto_debug_string_; + + +TEST_F(TextFormatTest, Basic) { + TestUtil::SetAllFields(&proto_); + EXPECT_EQ(proto_debug_string_, proto_.DebugString()); +} + +TEST_F(TextFormatExtensionsTest, Extensions) { + TestUtil::SetAllExtensions(&proto_); + EXPECT_EQ(proto_debug_string_, proto_.DebugString()); +} + +TEST_F(TextFormatTest, ShortDebugString) { + proto_.set_optional_int32(1); + proto_.set_optional_string("hello"); + proto_.mutable_optional_nested_message()->set_bb(2); + proto_.mutable_optional_foreign_message(); + + EXPECT_EQ("optional_int32: 1 optional_string: \"hello\" " + "optional_nested_message { bb: 2 } " + "optional_foreign_message { }", + proto_.ShortDebugString()); +} + +TEST_F(TextFormatTest, ShortPrimitiveRepeateds) { + proto_.set_optional_int32(123); + proto_.add_repeated_int32(456); + proto_.add_repeated_int32(789); + proto_.add_repeated_string("foo"); + proto_.add_repeated_string("bar"); + proto_.add_repeated_nested_message()->set_bb(2); + proto_.add_repeated_nested_message()->set_bb(3); + proto_.add_repeated_nested_enum(unittest::TestAllTypes::FOO); + proto_.add_repeated_nested_enum(unittest::TestAllTypes::BAR); + + TextFormat::Printer printer; + printer.SetUseShortRepeatedPrimitives(true); + string text; + printer.PrintToString(proto_, &text); + + EXPECT_EQ("optional_int32: 123\n" + "repeated_int32: [456, 789]\n" + "repeated_string: \"foo\"\n" + "repeated_string: \"bar\"\n" + "repeated_nested_message {\n bb: 2\n}\n" + "repeated_nested_message {\n bb: 3\n}\n" + "repeated_nested_enum: [FOO, BAR]\n", + text); + + // Try in single-line mode. + printer.SetSingleLineMode(true); + printer.PrintToString(proto_, &text); + + EXPECT_EQ("optional_int32: 123 " + "repeated_int32: [456, 789] " + "repeated_string: \"foo\" " + "repeated_string: \"bar\" " + "repeated_nested_message { bb: 2 } " + "repeated_nested_message { bb: 3 } " + "repeated_nested_enum: [FOO, BAR] ", + text); +} + + +TEST_F(TextFormatTest, StringEscape) { + // Set the string value to test. + proto_.set_optional_string(kEscapeTestString); + + // Get the DebugString from the proto. + string debug_string = proto_.DebugString(); + string utf8_debug_string = proto_.Utf8DebugString(); + + // Hardcode a correct value to test against. + string correct_string = "optional_string: " + + kEscapeTestStringEscaped + + "\n"; + + // Compare. + EXPECT_EQ(correct_string, debug_string); + // UTF-8 string is the same as non-UTF-8 because + // the protocol buffer contains no UTF-8 text. + EXPECT_EQ(correct_string, utf8_debug_string); + + string expected_short_debug_string = "optional_string: " + + kEscapeTestStringEscaped; + EXPECT_EQ(expected_short_debug_string, proto_.ShortDebugString()); +} + +TEST_F(TextFormatTest, Utf8DebugString) { + // Set the string value to test. + proto_.set_optional_string("\350\260\267\346\255\214"); + + // Get the DebugString from the proto. + string debug_string = proto_.DebugString(); + string utf8_debug_string = proto_.Utf8DebugString(); + + // Hardcode a correct value to test against. + string correct_utf8_string = "optional_string: " + "\"\350\260\267\346\255\214\"" + "\n"; + string correct_string = "optional_string: " + "\"\\350\\260\\267\\346\\255\\214\"" + "\n"; + + // Compare. + EXPECT_EQ(correct_utf8_string, utf8_debug_string); + EXPECT_EQ(correct_string, debug_string); +} + +TEST_F(TextFormatTest, PrintUnknownFields) { + // Test printing of unknown fields in a message. + + unittest::TestEmptyMessage message; + UnknownFieldSet* unknown_fields = message.mutable_unknown_fields(); + + unknown_fields->AddVarint(5, 1); + unknown_fields->AddFixed32(5, 2); + unknown_fields->AddFixed64(5, 3); + unknown_fields->AddLengthDelimited(5, "4"); + unknown_fields->AddGroup(5)->AddVarint(10, 5); + + unknown_fields->AddVarint(8, 1); + unknown_fields->AddVarint(8, 2); + unknown_fields->AddVarint(8, 3); + + EXPECT_EQ( + "5: 1\n" + "5: 0x00000002\n" + "5: 0x0000000000000003\n" + "5: \"4\"\n" + "5 {\n" + " 10: 5\n" + "}\n" + "8: 1\n" + "8: 2\n" + "8: 3\n", + message.DebugString()); +} + +TEST_F(TextFormatTest, PrintUnknownMessage) { + // Test heuristic printing of messages in an UnknownFieldSet. + + protobuf_unittest::TestAllTypes message; + + // Cases which should not be interpreted as sub-messages. + + // 'a' is a valid FIXED64 tag, so for the string to be parseable as a message + // it should be followed by 8 bytes. Since this string only has two + // subsequent bytes, it should be treated as a string. + message.add_repeated_string("abc"); + + // 'd' happens to be a valid ENDGROUP tag. So, + // UnknownFieldSet::MergeFromCodedStream() will successfully parse "def", but + // the ConsumedEntireMessage() check should fail. + message.add_repeated_string("def"); + + // A zero-length string should never be interpreted as a message even though + // it is technically valid as one. + message.add_repeated_string(""); + + // Case which should be interpreted as a sub-message. + + // An actual nested message with content should always be interpreted as a + // nested message. + message.add_repeated_nested_message()->set_bb(123); + + string data; + message.SerializeToString(&data); + + string text; + UnknownFieldSet unknown_fields; + EXPECT_TRUE(unknown_fields.ParseFromString(data)); + EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text)); + EXPECT_EQ( + "44: \"abc\"\n" + "44: \"def\"\n" + "44: \"\"\n" + "48 {\n" + " 1: 123\n" + "}\n", + text); +} + +TEST_F(TextFormatTest, PrintMessageWithIndent) { + // Test adding an initial indent to printing. + + protobuf_unittest::TestAllTypes message; + + message.add_repeated_string("abc"); + message.add_repeated_string("def"); + message.add_repeated_nested_message()->set_bb(123); + + string text; + TextFormat::Printer printer; + printer.SetInitialIndentLevel(1); + EXPECT_TRUE(printer.PrintToString(message, &text)); + EXPECT_EQ( + " repeated_string: \"abc\"\n" + " repeated_string: \"def\"\n" + " repeated_nested_message {\n" + " bb: 123\n" + " }\n", + text); +} + +TEST_F(TextFormatTest, PrintMessageSingleLine) { + // Test printing a message on a single line. + + protobuf_unittest::TestAllTypes message; + + message.add_repeated_string("abc"); + message.add_repeated_string("def"); + message.add_repeated_nested_message()->set_bb(123); + + string text; + TextFormat::Printer printer; + printer.SetInitialIndentLevel(1); + printer.SetSingleLineMode(true); + EXPECT_TRUE(printer.PrintToString(message, &text)); + EXPECT_EQ( + " repeated_string: \"abc\" repeated_string: \"def\" " + "repeated_nested_message { bb: 123 } ", + text); +} + +TEST_F(TextFormatTest, PrintBufferTooSmall) { + // Test printing a message to a buffer that is too small. + + protobuf_unittest::TestAllTypes message; + + message.add_repeated_string("abc"); + message.add_repeated_string("def"); + + char buffer[1] = ""; + io::ArrayOutputStream output_stream(buffer, 1); + EXPECT_FALSE(TextFormat::Print(message, &output_stream)); + EXPECT_EQ(buffer[0], 'r'); + EXPECT_EQ(output_stream.ByteCount(), 1); +} + +TEST_F(TextFormatTest, ParseBasic) { + io::ArrayInputStream input_stream(proto_debug_string_.data(), + proto_debug_string_.size()); + TextFormat::Parse(&input_stream, &proto_); + TestUtil::ExpectAllFieldsSet(proto_); +} + +TEST_F(TextFormatExtensionsTest, ParseExtensions) { + io::ArrayInputStream input_stream(proto_debug_string_.data(), + proto_debug_string_.size()); + TextFormat::Parse(&input_stream, &proto_); + TestUtil::ExpectAllExtensionsSet(proto_); +} + +TEST_F(TextFormatTest, ParseEnumFieldFromNumber) { + // Create a parse string with a numerical value for an enum field. + string parse_string = strings::Substitute("optional_nested_enum: $0", + unittest::TestAllTypes::BAZ); + EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto_)); + EXPECT_TRUE(proto_.has_optional_nested_enum()); + EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.optional_nested_enum()); +} + +TEST_F(TextFormatTest, ParseEnumFieldFromNegativeNumber) { + ASSERT_LT(unittest::SPARSE_E, 0); + string parse_string = strings::Substitute("sparse_enum: $0", + unittest::SPARSE_E); + unittest::SparseEnumMessage proto; + EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto)); + EXPECT_TRUE(proto.has_sparse_enum()); + EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum()); +} + +TEST_F(TextFormatTest, ParseStringEscape) { + // Create a parse string with escpaed characters in it. + string parse_string = "optional_string: " + + kEscapeTestStringEscaped + + "\n"; + + io::ArrayInputStream input_stream(parse_string.data(), + parse_string.size()); + TextFormat::Parse(&input_stream, &proto_); + + // Compare. + EXPECT_EQ(kEscapeTestString, proto_.optional_string()); +} + +TEST_F(TextFormatTest, ParseConcatenatedString) { + // Create a parse string with multiple parts on one line. + string parse_string = "optional_string: \"foo\" \"bar\"\n"; + + io::ArrayInputStream input_stream1(parse_string.data(), + parse_string.size()); + TextFormat::Parse(&input_stream1, &proto_); + + // Compare. + EXPECT_EQ("foobar", proto_.optional_string()); + + // Create a parse string with multiple parts on seperate lines. + parse_string = "optional_string: \"foo\"\n" + "\"bar\"\n"; + + io::ArrayInputStream input_stream2(parse_string.data(), + parse_string.size()); + TextFormat::Parse(&input_stream2, &proto_); + + // Compare. + EXPECT_EQ("foobar", proto_.optional_string()); +} + +TEST_F(TextFormatTest, ParseFloatWithSuffix) { + // Test that we can parse a floating-point value with 'f' appended to the + // end. This is needed for backwards-compatibility with proto1. + + // Have it parse a float with the 'f' suffix. + string parse_string = "optional_float: 1.0f\n"; + + io::ArrayInputStream input_stream(parse_string.data(), + parse_string.size()); + + TextFormat::Parse(&input_stream, &proto_); + + // Compare. + EXPECT_EQ(1.0, proto_.optional_float()); +} + +TEST_F(TextFormatTest, ParseShortRepeatedForm) { + string parse_string = + // Mixed short-form and long-form are simply concatenated. + "repeated_int32: 1\n" + "repeated_int32: [456, 789]\n" + "repeated_nested_enum: [ FOO ,BAR, # comment\n" + " 3]\n" + // Note that while the printer won't print repeated strings in short-form, + // the parser will accept them. + "repeated_string: [ \"foo\", 'bar' ]\n"; + + ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_)); + + ASSERT_EQ(3, proto_.repeated_int32_size()); + EXPECT_EQ(1, proto_.repeated_int32(0)); + EXPECT_EQ(456, proto_.repeated_int32(1)); + EXPECT_EQ(789, proto_.repeated_int32(2)); + + ASSERT_EQ(3, proto_.repeated_nested_enum_size()); + EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0)); + EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1)); + EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2)); + + ASSERT_EQ(2, proto_.repeated_string_size()); + EXPECT_EQ("foo", proto_.repeated_string(0)); + EXPECT_EQ("bar", proto_.repeated_string(1)); +} + +TEST_F(TextFormatTest, Comments) { + // Test that comments are ignored. + + string parse_string = "optional_int32: 1 # a comment\n" + "optional_int64: 2 # another comment"; + + io::ArrayInputStream input_stream(parse_string.data(), + parse_string.size()); + + TextFormat::Parse(&input_stream, &proto_); + + // Compare. + EXPECT_EQ(1, proto_.optional_int32()); + EXPECT_EQ(2, proto_.optional_int64()); +} + +TEST_F(TextFormatTest, OptionalColon) { + // Test that we can place a ':' after the field name of a nested message, + // even though we don't have to. + + string parse_string = "optional_nested_message: { bb: 1}\n"; + + io::ArrayInputStream input_stream(parse_string.data(), + parse_string.size()); + + TextFormat::Parse(&input_stream, &proto_); + + // Compare. + EXPECT_TRUE(proto_.has_optional_nested_message()); + EXPECT_EQ(1, proto_.optional_nested_message().bb()); +} + +// Some platforms (e.g. Windows) insist on padding the exponent to three +// digits when one or two would be just fine. +static string RemoveRedundantZeros(string text) { + text = StringReplace(text, "e+0", "e+", true); + text = StringReplace(text, "e-0", "e-", true); + return text; +} + +TEST_F(TextFormatTest, PrintExotic) { + unittest::TestAllTypes message; + + // Note: In C, a negative integer literal is actually the unary negation + // operator being applied to a positive integer literal, and + // 9223372036854775808 is outside the range of int64. However, it is not + // outside the range of uint64. Confusingly, this means that everything + // works if we make the literal unsigned, even though we are negating it. + message.add_repeated_int64(-GOOGLE_ULONGLONG(9223372036854775808)); + message.add_repeated_uint64(GOOGLE_ULONGLONG(18446744073709551615)); + message.add_repeated_double(123.456); + message.add_repeated_double(1.23e21); + message.add_repeated_double(1.23e-18); + message.add_repeated_double(std::numeric_limits::infinity()); + message.add_repeated_double(-std::numeric_limits::infinity()); + message.add_repeated_double(std::numeric_limits::quiet_NaN()); + message.add_repeated_string(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12)); + + // Fun story: We used to use 1.23e22 instead of 1.23e21 above, but this + // seemed to trigger an odd case on MinGW/GCC 3.4.5 where GCC's parsing of + // the value differed from strtod()'s parsing. That is to say, the + // following assertion fails on MinGW: + // assert(1.23e22 == strtod("1.23e22", NULL)); + // As a result, SimpleDtoa() would print the value as + // "1.2300000000000001e+22" to make sure strtod() produce the exact same + // result. Our goal is to test runtime parsing, not compile-time parsing, + // so this wasn't our problem. It was found that using 1.23e21 did not + // have this problem, so we switched to that instead. + + EXPECT_EQ( + "repeated_int64: -9223372036854775808\n" + "repeated_uint64: 18446744073709551615\n" + "repeated_double: 123.456\n" + "repeated_double: 1.23e+21\n" + "repeated_double: 1.23e-18\n" + "repeated_double: inf\n" + "repeated_double: -inf\n" + "repeated_double: nan\n" + "repeated_string: \"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\'\\\"\"\n", + RemoveRedundantZeros(message.DebugString())); +} + +TEST_F(TextFormatTest, PrintFloatPrecision) { + unittest::TestAllTypes message; + + message.add_repeated_float(1.2); + message.add_repeated_float(1.23); + message.add_repeated_float(1.234); + message.add_repeated_float(1.2345); + message.add_repeated_float(1.23456); + message.add_repeated_float(1.2e10); + message.add_repeated_float(1.23e10); + message.add_repeated_float(1.234e10); + message.add_repeated_float(1.2345e10); + message.add_repeated_float(1.23456e10); + message.add_repeated_double(1.2); + message.add_repeated_double(1.23); + message.add_repeated_double(1.234); + message.add_repeated_double(1.2345); + message.add_repeated_double(1.23456); + message.add_repeated_double(1.234567); + message.add_repeated_double(1.2345678); + message.add_repeated_double(1.23456789); + message.add_repeated_double(1.234567898); + message.add_repeated_double(1.2345678987); + message.add_repeated_double(1.23456789876); + message.add_repeated_double(1.234567898765); + message.add_repeated_double(1.2345678987654); + message.add_repeated_double(1.23456789876543); + message.add_repeated_double(1.2e100); + message.add_repeated_double(1.23e100); + message.add_repeated_double(1.234e100); + message.add_repeated_double(1.2345e100); + message.add_repeated_double(1.23456e100); + message.add_repeated_double(1.234567e100); + message.add_repeated_double(1.2345678e100); + message.add_repeated_double(1.23456789e100); + message.add_repeated_double(1.234567898e100); + message.add_repeated_double(1.2345678987e100); + message.add_repeated_double(1.23456789876e100); + message.add_repeated_double(1.234567898765e100); + message.add_repeated_double(1.2345678987654e100); + message.add_repeated_double(1.23456789876543e100); + + EXPECT_EQ( + "repeated_float: 1.2\n" + "repeated_float: 1.23\n" + "repeated_float: 1.234\n" + "repeated_float: 1.2345\n" + "repeated_float: 1.23456\n" + "repeated_float: 1.2e+10\n" + "repeated_float: 1.23e+10\n" + "repeated_float: 1.234e+10\n" + "repeated_float: 1.2345e+10\n" + "repeated_float: 1.23456e+10\n" + "repeated_double: 1.2\n" + "repeated_double: 1.23\n" + "repeated_double: 1.234\n" + "repeated_double: 1.2345\n" + "repeated_double: 1.23456\n" + "repeated_double: 1.234567\n" + "repeated_double: 1.2345678\n" + "repeated_double: 1.23456789\n" + "repeated_double: 1.234567898\n" + "repeated_double: 1.2345678987\n" + "repeated_double: 1.23456789876\n" + "repeated_double: 1.234567898765\n" + "repeated_double: 1.2345678987654\n" + "repeated_double: 1.23456789876543\n" + "repeated_double: 1.2e+100\n" + "repeated_double: 1.23e+100\n" + "repeated_double: 1.234e+100\n" + "repeated_double: 1.2345e+100\n" + "repeated_double: 1.23456e+100\n" + "repeated_double: 1.234567e+100\n" + "repeated_double: 1.2345678e+100\n" + "repeated_double: 1.23456789e+100\n" + "repeated_double: 1.234567898e+100\n" + "repeated_double: 1.2345678987e+100\n" + "repeated_double: 1.23456789876e+100\n" + "repeated_double: 1.234567898765e+100\n" + "repeated_double: 1.2345678987654e+100\n" + "repeated_double: 1.23456789876543e+100\n", + RemoveRedundantZeros(message.DebugString())); +} + + +TEST_F(TextFormatTest, AllowPartial) { + unittest::TestRequired message; + TextFormat::Parser parser; + parser.AllowPartialMessage(true); + EXPECT_TRUE(parser.ParseFromString("a: 1", &message)); + EXPECT_EQ(1, message.a()); + EXPECT_FALSE(message.has_b()); + EXPECT_FALSE(message.has_c()); +} + +TEST_F(TextFormatTest, ParseExotic) { + unittest::TestAllTypes message; + ASSERT_TRUE(TextFormat::ParseFromString( + "repeated_int32: -1\n" + "repeated_int32: -2147483648\n" + "repeated_int64: -1\n" + "repeated_int64: -9223372036854775808\n" + "repeated_uint32: 4294967295\n" + "repeated_uint32: 2147483648\n" + "repeated_uint64: 18446744073709551615\n" + "repeated_uint64: 9223372036854775808\n" + "repeated_double: 123.0\n" + "repeated_double: 123.5\n" + "repeated_double: 0.125\n" + "repeated_double: 1.23E17\n" + "repeated_double: 1.235E+22\n" + "repeated_double: 1.235e-18\n" + "repeated_double: 123.456789\n" + "repeated_double: inf\n" + "repeated_double: Infinity\n" + "repeated_double: -inf\n" + "repeated_double: -Infinity\n" + "repeated_double: nan\n" + "repeated_double: NaN\n" + "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\"\n", + &message)); + + ASSERT_EQ(2, message.repeated_int32_size()); + EXPECT_EQ(-1, message.repeated_int32(0)); + // Note: In C, a negative integer literal is actually the unary negation + // operator being applied to a positive integer literal, and 2147483648 is + // outside the range of int32. However, it is not outside the range of + // uint32. Confusingly, this means that everything works if we make the + // literal unsigned, even though we are negating it. + EXPECT_EQ(-2147483648u, message.repeated_int32(1)); + + ASSERT_EQ(2, message.repeated_int64_size()); + EXPECT_EQ(-1, message.repeated_int64(0)); + // Note: In C, a negative integer literal is actually the unary negation + // operator being applied to a positive integer literal, and + // 9223372036854775808 is outside the range of int64. However, it is not + // outside the range of uint64. Confusingly, this means that everything + // works if we make the literal unsigned, even though we are negating it. + EXPECT_EQ(-GOOGLE_ULONGLONG(9223372036854775808), message.repeated_int64(1)); + + ASSERT_EQ(2, message.repeated_uint32_size()); + EXPECT_EQ(4294967295u, message.repeated_uint32(0)); + EXPECT_EQ(2147483648u, message.repeated_uint32(1)); + + ASSERT_EQ(2, message.repeated_uint64_size()); + EXPECT_EQ(GOOGLE_ULONGLONG(18446744073709551615), message.repeated_uint64(0)); + EXPECT_EQ(GOOGLE_ULONGLONG(9223372036854775808), message.repeated_uint64(1)); + + ASSERT_EQ(13, message.repeated_double_size()); + EXPECT_EQ(123.0 , message.repeated_double(0)); + EXPECT_EQ(123.5 , message.repeated_double(1)); + EXPECT_EQ(0.125 , message.repeated_double(2)); + EXPECT_EQ(1.23E17 , message.repeated_double(3)); + EXPECT_EQ(1.235E22 , message.repeated_double(4)); + EXPECT_EQ(1.235E-18 , message.repeated_double(5)); + EXPECT_EQ(123.456789, message.repeated_double(6)); + EXPECT_EQ(message.repeated_double(7), numeric_limits::infinity()); + EXPECT_EQ(message.repeated_double(8), numeric_limits::infinity()); + EXPECT_EQ(message.repeated_double(9), -numeric_limits::infinity()); + EXPECT_EQ(message.repeated_double(10), -numeric_limits::infinity()); + EXPECT_TRUE(IsNaN(message.repeated_double(11))); + EXPECT_TRUE(IsNaN(message.repeated_double(12))); + + // Note: Since these string literals have \0's in them, we must explicitly + // pass their sizes to string's constructor. + ASSERT_EQ(1, message.repeated_string_size()); + EXPECT_EQ(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12), + message.repeated_string(0)); +} + +class TextFormatParserTest : public testing::Test { + protected: + void ExpectFailure(const string& input, const string& message, int line, + int col) { + scoped_ptr proto(new unittest::TestAllTypes); + ExpectFailure(input, message, line, col, proto.get()); + } + + void ExpectFailure(const string& input, const string& message, int line, + int col, Message* proto) { + ExpectMessage(input, message, line, col, proto, false); + } + + void ExpectMessage(const string& input, const string& message, int line, + int col, Message* proto, bool expected_result) { + TextFormat::Parser parser; + MockErrorCollector error_collector; + parser.RecordErrorsTo(&error_collector); + EXPECT_EQ(parser.ParseFromString(input, proto), expected_result); + EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n", + error_collector.text_); + } + + void ExpectSuccessAndTree(const string& input, Message* proto, + TextFormat::ParseInfoTree* info_tree) { + TextFormat::Parser parser; + MockErrorCollector error_collector; + parser.RecordErrorsTo(&error_collector); + parser.WriteLocationsTo(info_tree); + + EXPECT_TRUE(parser.ParseFromString(input, proto)); + } + + void ExpectLocation(TextFormat::ParseInfoTree* tree, + const Descriptor* d, const string& field_name, + int index, int line, int column) { + TextFormat::ParseLocation location = tree->GetLocation( + d->FindFieldByName(field_name), index); + EXPECT_EQ(line, location.line); + EXPECT_EQ(column, location.column); + } + + // An error collector which simply concatenates all its errors into a big + // block of text which can be checked. + class MockErrorCollector : public io::ErrorCollector { + public: + MockErrorCollector() {} + ~MockErrorCollector() {} + + string text_; + + // implements ErrorCollector ------------------------------------- + void AddError(int line, int column, const string& message) { + strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", + line + 1, column + 1, message); + } + + void AddWarning(int line, int column, const string& message) { + AddError(line, column, "WARNING:" + message); + } + }; +}; + +TEST_F(TextFormatParserTest, ParseInfoTreeBuilding) { + scoped_ptr message(new unittest::TestAllTypes); + const Descriptor* d = message->GetDescriptor(); + + string stringData = + "optional_int32: 1\n" + "optional_int64: 2\n" + " optional_double: 2.4\n" + "repeated_int32: 5\n" + "repeated_int32: 10\n" + "optional_nested_message <\n" + " bb: 78\n" + ">\n" + "repeated_nested_message <\n" + " bb: 79\n" + ">\n" + "repeated_nested_message <\n" + " bb: 80\n" + ">"; + + + TextFormat::ParseInfoTree tree; + ExpectSuccessAndTree(stringData, message.get(), &tree); + + // Verify that the tree has the correct positions. + ExpectLocation(&tree, d, "optional_int32", -1, 0, 0); + ExpectLocation(&tree, d, "optional_int64", -1, 1, 0); + ExpectLocation(&tree, d, "optional_double", -1, 2, 2); + + ExpectLocation(&tree, d, "repeated_int32", 0, 3, 0); + ExpectLocation(&tree, d, "repeated_int32", 1, 4, 0); + + ExpectLocation(&tree, d, "optional_nested_message", -1, 5, 0); + ExpectLocation(&tree, d, "repeated_nested_message", 0, 8, 0); + ExpectLocation(&tree, d, "repeated_nested_message", 1, 11, 0); + + // Check for fields not set. For an invalid field, the location returned + // should be -1, -1. + ExpectLocation(&tree, d, "repeated_int64", 0, -1, -1); + ExpectLocation(&tree, d, "repeated_int32", 6, -1, -1); + ExpectLocation(&tree, d, "some_unknown_field", -1, -1, -1); + + // Verify inside the nested message. + const FieldDescriptor* nested_field = + d->FindFieldByName("optional_nested_message"); + + TextFormat::ParseInfoTree* nested_tree = + tree.GetTreeForNested(nested_field, -1); + ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 6, 2); + + // Verify inside another nested message. + nested_field = d->FindFieldByName("repeated_nested_message"); + nested_tree = tree.GetTreeForNested(nested_field, 0); + ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 9, 2); + + nested_tree = tree.GetTreeForNested(nested_field, 1); + ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 12, 2); + + // Verify a NULL tree for an unknown nested field. + TextFormat::ParseInfoTree* unknown_nested_tree = + tree.GetTreeForNested(nested_field, 2); + + EXPECT_EQ(NULL, unknown_nested_tree); +} + +TEST_F(TextFormatParserTest, ParseFieldValueFromString) { + scoped_ptr message(new unittest::TestAllTypes); + const Descriptor* d = message->GetDescriptor(); + +#define EXPECT_FIELD(name, value, valuestring) \ + EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ + valuestring, d->FindFieldByName("optional_" #name), message.get())); \ + EXPECT_EQ(value, message->optional_##name()); \ + EXPECT_TRUE(message->has_optional_##name()); + +#define EXPECT_BOOL_FIELD(name, value, valuestring) \ + EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ + valuestring, d->FindFieldByName("optional_" #name), message.get())); \ + EXPECT_TRUE(message->optional_##name() == value); \ + EXPECT_TRUE(message->has_optional_##name()); + +#define EXPECT_FLOAT_FIELD(name, value, valuestring) \ + EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ + valuestring, d->FindFieldByName("optional_" #name), message.get())); \ + EXPECT_FLOAT_EQ(value, message->optional_##name()); \ + EXPECT_TRUE(message->has_optional_##name()); + +#define EXPECT_DOUBLE_FIELD(name, value, valuestring) \ + EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ + valuestring, d->FindFieldByName("optional_" #name), message.get())); \ + EXPECT_DOUBLE_EQ(value, message->optional_##name()); \ + EXPECT_TRUE(message->has_optional_##name()); + +#define EXPECT_INVALID(name, valuestring) \ + EXPECT_FALSE(TextFormat::ParseFieldValueFromString( \ + valuestring, d->FindFieldByName("optional_" #name), message.get())); + + // int32 + EXPECT_FIELD(int32, 1, "1"); + EXPECT_FIELD(int32, -1, "-1"); + EXPECT_FIELD(int32, 0x1234, "0x1234"); + EXPECT_INVALID(int32, "a"); + EXPECT_INVALID(int32, "999999999999999999999999999999999999"); + EXPECT_INVALID(int32, "1,2"); + + // int64 + EXPECT_FIELD(int64, 1, "1"); + EXPECT_FIELD(int64, -1, "-1"); + EXPECT_FIELD(int64, 0x1234567812345678LL, "0x1234567812345678"); + EXPECT_INVALID(int64, "a"); + EXPECT_INVALID(int64, "999999999999999999999999999999999999"); + EXPECT_INVALID(int64, "1,2"); + + // uint64 + EXPECT_FIELD(uint64, 1, "1"); + EXPECT_FIELD(uint64, 0xf234567812345678ULL, "0xf234567812345678"); + EXPECT_INVALID(uint64, "-1"); + EXPECT_INVALID(uint64, "a"); + EXPECT_INVALID(uint64, "999999999999999999999999999999999999"); + EXPECT_INVALID(uint64, "1,2"); + + // fixed32 + EXPECT_FIELD(fixed32, 1, "1"); + EXPECT_FIELD(fixed32, 0x12345678, "0x12345678"); + EXPECT_INVALID(fixed32, "-1"); + EXPECT_INVALID(fixed32, "a"); + EXPECT_INVALID(fixed32, "999999999999999999999999999999999999"); + EXPECT_INVALID(fixed32, "1,2"); + + // fixed64 + EXPECT_FIELD(fixed64, 1, "1"); + EXPECT_FIELD(fixed64, 0x1234567812345678ULL, "0x1234567812345678"); + EXPECT_INVALID(fixed64, "-1"); + EXPECT_INVALID(fixed64, "a"); + EXPECT_INVALID(fixed64, "999999999999999999999999999999999999"); + EXPECT_INVALID(fixed64, "1,2"); + + // bool + EXPECT_BOOL_FIELD(bool, true, "true"); + EXPECT_BOOL_FIELD(bool, false, "false"); + EXPECT_BOOL_FIELD(bool, true, "1"); + EXPECT_BOOL_FIELD(bool, true, "t"); + EXPECT_BOOL_FIELD(bool, false, "0"); + EXPECT_BOOL_FIELD(bool, false, "f"); + EXPECT_INVALID(bool, "2"); + EXPECT_INVALID(bool, "-0"); + EXPECT_INVALID(bool, "on"); + EXPECT_INVALID(bool, "a"); + EXPECT_INVALID(bool, "True"); + + // float + EXPECT_FIELD(float, 1, "1"); + EXPECT_FLOAT_FIELD(float, 1.5, "1.5"); + EXPECT_FLOAT_FIELD(float, 1.5e3, "1.5e3"); + EXPECT_FLOAT_FIELD(float, -4.55, "-4.55"); + EXPECT_INVALID(float, "a"); + EXPECT_INVALID(float, "1,2"); + + // double + EXPECT_FIELD(double, 1, "1"); + EXPECT_FIELD(double, -1, "-1"); + EXPECT_DOUBLE_FIELD(double, 2.3, "2.3"); + EXPECT_DOUBLE_FIELD(double, 3e5, "3e5"); + EXPECT_INVALID(double, "a"); + EXPECT_INVALID(double, "1,2"); + + // string + EXPECT_FIELD(string, "hello", "\"hello\""); + EXPECT_FIELD(string, "-1.87", "'-1.87'"); + EXPECT_INVALID(string, "hello"); // without quote for value + + // enum + EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR"); + EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ, + SimpleItoa(unittest::TestAllTypes::BAZ)); + EXPECT_INVALID(nested_enum, "FOOBAR"); + + // message + EXPECT_TRUE(TextFormat::ParseFieldValueFromString( + "", d->FindFieldByName("optional_nested_message"), message.get())); + EXPECT_EQ(12, message->optional_nested_message().bb()); \ + EXPECT_TRUE(message->has_optional_nested_message()); + EXPECT_INVALID(nested_message, "any"); + +#undef EXPECT_FIELD +#undef EXPECT_BOOL_FIELD +#undef EXPECT_FLOAT_FIELD +#undef EXPECT_DOUBLE_FIELD +#undef EXPECT_INVALID +} + + +TEST_F(TextFormatParserTest, InvalidToken) { + ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.", + 2, 1); + + ExpectFailure("optional_bool: true!\n", "Expected identifier.", 1, 20); + ExpectFailure("\"some string\"", "Expected identifier.", 1, 1); +} + +TEST_F(TextFormatParserTest, InvalidFieldName) { + ExpectFailure( + "invalid_field: somevalue\n", + "Message type \"protobuf_unittest.TestAllTypes\" has no field named " + "\"invalid_field\".", + 1, 14); +} + +TEST_F(TextFormatParserTest, InvalidCapitalization) { + // We require that group names be exactly as they appear in the .proto. + ExpectFailure( + "optionalgroup {\na: 15\n}\n", + "Message type \"protobuf_unittest.TestAllTypes\" has no field named " + "\"optionalgroup\".", + 1, 15); + ExpectFailure( + "OPTIONALgroup {\na: 15\n}\n", + "Message type \"protobuf_unittest.TestAllTypes\" has no field named " + "\"OPTIONALgroup\".", + 1, 15); + ExpectFailure( + "Optional_Double: 10.0\n", + "Message type \"protobuf_unittest.TestAllTypes\" has no field named " + "\"Optional_Double\".", + 1, 16); +} + +TEST_F(TextFormatParserTest, InvalidFieldValues) { + // Invalid values for a double/float field. + ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18); + ExpectFailure("optional_double: true\n", "Expected double.", 1, 18); + ExpectFailure("optional_double: !\n", "Expected double.", 1, 18); + ExpectFailure("optional_double {\n \n}\n", "Expected \":\", found \"{\".", + 1, 17); + + // Invalid values for a signed integer field. + ExpectFailure("optional_int32: \"hello\"\n", "Expected integer.", 1, 17); + ExpectFailure("optional_int32: true\n", "Expected integer.", 1, 17); + ExpectFailure("optional_int32: 4.5\n", "Expected integer.", 1, 17); + ExpectFailure("optional_int32: !\n", "Expected integer.", 1, 17); + ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".", + 1, 16); + ExpectFailure("optional_int32: 0x80000000\n", + "Integer out of range.", 1, 17); + ExpectFailure("optional_int64: 0x8000000000000000\n", + "Integer out of range.", 1, 17); + ExpectFailure("optional_int32: -0x80000001\n", + "Integer out of range.", 1, 18); + ExpectFailure("optional_int64: -0x8000000000000001\n", + "Integer out of range.", 1, 18); + + // Invalid values for an unsigned integer field. + ExpectFailure("optional_uint64: \"hello\"\n", "Expected integer.", 1, 18); + ExpectFailure("optional_uint64: true\n", "Expected integer.", 1, 18); + ExpectFailure("optional_uint64: 4.5\n", "Expected integer.", 1, 18); + ExpectFailure("optional_uint64: -5\n", "Expected integer.", 1, 18); + ExpectFailure("optional_uint64: !\n", "Expected integer.", 1, 18); + ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".", + 1, 17); + ExpectFailure("optional_uint32: 0x100000000\n", + "Integer out of range.", 1, 18); + ExpectFailure("optional_uint64: 0x10000000000000000\n", + "Integer out of range.", 1, 18); + + // Invalid values for a boolean field. + ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16); + ExpectFailure("optional_bool: 5\n", "Integer out of range.", 1, 16); + ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16); + ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16); + + ExpectFailure( + "optional_bool: meh\n", + "Invalid value for boolean field \"optional_bool\". Value: \"meh\".", + 2, 1); + + ExpectFailure("optional_bool {\n \n}\n", "Expected \":\", found \"{\".", + 1, 15); + + // Invalid values for a string field. + ExpectFailure("optional_string: true\n", "Expected string.", 1, 18); + ExpectFailure("optional_string: 5\n", "Expected string.", 1, 18); + ExpectFailure("optional_string: -7.5\n", "Expected string.", 1, 18); + ExpectFailure("optional_string: !\n", "Expected string.", 1, 18); + ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".", + 1, 17); + + // Invalid values for an enumeration field. + ExpectFailure("optional_nested_enum: \"hello\"\n", + "Expected integer or identifier.", 1, 23); + + // Valid token, but enum value is not defined. + ExpectFailure("optional_nested_enum: 5\n", + "Unknown enumeration value of \"5\" for field " + "\"optional_nested_enum\".", 2, 1); + // We consume the negative sign, so the error position starts one character + // later. + ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer.", 1, 24); + ExpectFailure("optional_nested_enum: !\n", + "Expected integer or identifier.", 1, 23); + + ExpectFailure( + "optional_nested_enum: grah\n", + "Unknown enumeration value of \"grah\" for field " + "\"optional_nested_enum\".", 2, 1); + + ExpectFailure( + "optional_nested_enum {\n \n}\n", + "Expected \":\", found \"{\".", 1, 22); +} + +TEST_F(TextFormatParserTest, MessageDelimeters) { + // Non-matching delimeters. + ExpectFailure("OptionalGroup <\n \n}\n", "Expected \">\", found \"}\".", + 3, 1); + + // Invalid delimeters. + ExpectFailure("OptionalGroup [\n \n]\n", "Expected \"{\", found \"[\".", + 1, 15); + + // Unending message. + ExpectFailure("optional_nested_message {\n \nbb: 118\n", + "Expected identifier.", + 4, 1); +} + +TEST_F(TextFormatParserTest, UnknownExtension) { + // Non-matching delimeters. + ExpectFailure("[blahblah]: 123", + "Extension \"blahblah\" is not defined or is not an " + "extension of \"protobuf_unittest.TestAllTypes\".", + 1, 11); +} + +TEST_F(TextFormatParserTest, MissingRequired) { + unittest::TestRequired message; + ExpectFailure("a: 1", + "Message missing required fields: b, c", + 0, 1, &message); +} + +TEST_F(TextFormatParserTest, ParseDuplicateRequired) { + unittest::TestRequired message; + ExpectFailure("a: 1 b: 2 c: 3 a: 1", + "Non-repeated field \"a\" is specified multiple times.", + 1, 17, &message); +} + +TEST_F(TextFormatParserTest, ParseDuplicateOptional) { + unittest::ForeignMessage message; + ExpectFailure("c: 1 c: 2", + "Non-repeated field \"c\" is specified multiple times.", + 1, 7, &message); +} + +TEST_F(TextFormatParserTest, MergeDuplicateRequired) { + unittest::TestRequired message; + TextFormat::Parser parser; + EXPECT_TRUE(parser.MergeFromString("a: 1 b: 2 c: 3 a: 4", &message)); + EXPECT_EQ(4, message.a()); +} + +TEST_F(TextFormatParserTest, MergeDuplicateOptional) { + unittest::ForeignMessage message; + TextFormat::Parser parser; + EXPECT_TRUE(parser.MergeFromString("c: 1 c: 2", &message)); + EXPECT_EQ(2, message.c()); +} + +TEST_F(TextFormatParserTest, ExplicitDelimiters) { + unittest::TestRequired message; + EXPECT_TRUE(TextFormat::ParseFromString("a:1,b:2;c:3", &message)); + EXPECT_EQ(1, message.a()); + EXPECT_EQ(2, message.b()); + EXPECT_EQ(3, message.c()); +} + +TEST_F(TextFormatParserTest, PrintErrorsToStderr) { + vector errors; + + { + ScopedMemoryLog log; + unittest::TestAllTypes proto; + EXPECT_FALSE(TextFormat::ParseFromString("no_such_field: 1", &proto)); + errors = log.GetMessages(ERROR); + } + + ASSERT_EQ(1, errors.size()); + EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: " + "1:14: Message type \"protobuf_unittest.TestAllTypes\" has no field " + "named \"no_such_field\".", + errors[0]); +} + +TEST_F(TextFormatParserTest, FailsOnTokenizationError) { + vector errors; + + { + ScopedMemoryLog log; + unittest::TestAllTypes proto; + EXPECT_FALSE(TextFormat::ParseFromString("\020", &proto)); + errors = log.GetMessages(ERROR); + } + + ASSERT_EQ(1, errors.size()); + EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: " + "1:1: Invalid control characters encountered in text.", + errors[0]); +} + +TEST_F(TextFormatParserTest, ParseDeprecatedField) { + unittest::TestDeprecatedFields message; + ExpectMessage("deprecated_int32: 42", + "WARNING:text format contains deprecated field " + "\"deprecated_int32\"", 1, 21, &message, true); +} + +class TextFormatMessageSetTest : public testing::Test { + protected: + static const char proto_debug_string_[]; +}; +const char TextFormatMessageSetTest::proto_debug_string_[] = +"message_set {\n" +" [protobuf_unittest.TestMessageSetExtension1] {\n" +" i: 23\n" +" }\n" +" [protobuf_unittest.TestMessageSetExtension2] {\n" +" str: \"foo\"\n" +" }\n" +"}\n"; + + +TEST_F(TextFormatMessageSetTest, Serialize) { + protobuf_unittest::TestMessageSetContainer proto; + protobuf_unittest::TestMessageSetExtension1* item_a = + proto.mutable_message_set()->MutableExtension( + protobuf_unittest::TestMessageSetExtension1::message_set_extension); + item_a->set_i(23); + protobuf_unittest::TestMessageSetExtension2* item_b = + proto.mutable_message_set()->MutableExtension( + protobuf_unittest::TestMessageSetExtension2::message_set_extension); + item_b->set_str("foo"); + EXPECT_EQ(proto_debug_string_, proto.DebugString()); +} + +TEST_F(TextFormatMessageSetTest, Deserialize) { + protobuf_unittest::TestMessageSetContainer proto; + ASSERT_TRUE(TextFormat::ParseFromString(proto_debug_string_, &proto)); + EXPECT_EQ(23, proto.message_set().GetExtension( + protobuf_unittest::TestMessageSetExtension1::message_set_extension).i()); + EXPECT_EQ("foo", proto.message_set().GetExtension( + protobuf_unittest::TestMessageSetExtension2::message_set_extension).str()); + + // Ensure that these are the only entries present. + vector descriptors; + proto.message_set().GetReflection()->ListFields( + proto.message_set(), &descriptors); + EXPECT_EQ(2, descriptors.size()); +} + + +} // namespace text_format_unittest +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest.proto new file mode 100644 index 0000000..6eb2d86 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest.proto @@ -0,0 +1,719 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// A proto file we will use for unit testing. + + +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +option cc_generic_services = true; // auto-added +option java_generic_services = true; // auto-added +option py_generic_services = true; // auto-added + +import "google/protobuf/unittest_import.proto"; + +// We don't put this in a package within proto2 because we need to make sure +// that the generated code doesn't depend on being in the proto2 namespace. +// In test_util.h we do "using namespace unittest = protobuf_unittest". +package protobuf_unittest; + +// Protos optimized for SPEED use a strict superset of the generated code +// of equivalent ones optimized for CODE_SIZE, so we should optimize all our +// tests for speed unless explicitly testing code size optimization. +option optimize_for = SPEED; + +option java_outer_classname = "UnittestProto"; + +// This proto includes every type of field in both singular and repeated +// forms. +message TestAllTypes { + message NestedMessage { + // The field name "b" fails to compile in proto1 because it conflicts with + // a local variable named "b" in one of the generated methods. Doh. + // This file needs to compile in proto1 to test backwards-compatibility. + optional int32 bb = 1; + } + + enum NestedEnum { + FOO = 1; + BAR = 2; + BAZ = 3; + } + + // Singular + optional int32 optional_int32 = 1; + optional int64 optional_int64 = 2; + optional uint32 optional_uint32 = 3; + optional uint64 optional_uint64 = 4; + optional sint32 optional_sint32 = 5; + optional sint64 optional_sint64 = 6; + optional fixed32 optional_fixed32 = 7; + optional fixed64 optional_fixed64 = 8; + optional sfixed32 optional_sfixed32 = 9; + optional sfixed64 optional_sfixed64 = 10; + optional float optional_float = 11; + optional double optional_double = 12; + optional bool optional_bool = 13; + optional string optional_string = 14; + optional bytes optional_bytes = 15; + + optional group OptionalGroup = 16 { + optional int32 a = 17; + } + + optional NestedMessage optional_nested_message = 18; + optional ForeignMessage optional_foreign_message = 19; + optional protobuf_unittest_import.ImportMessage optional_import_message = 20; + + optional NestedEnum optional_nested_enum = 21; + optional ForeignEnum optional_foreign_enum = 22; + optional protobuf_unittest_import.ImportEnum optional_import_enum = 23; + + optional string optional_string_piece = 24 [ctype=STRING_PIECE]; + optional string optional_cord = 25 [ctype=CORD]; + + // Defined in unittest_import_public.proto + optional protobuf_unittest_import.PublicImportMessage + optional_public_import_message = 26; + + optional NestedMessage optional_lazy_message = 27 [lazy=true]; + + // Repeated + repeated int32 repeated_int32 = 31; + repeated int64 repeated_int64 = 32; + repeated uint32 repeated_uint32 = 33; + repeated uint64 repeated_uint64 = 34; + repeated sint32 repeated_sint32 = 35; + repeated sint64 repeated_sint64 = 36; + repeated fixed32 repeated_fixed32 = 37; + repeated fixed64 repeated_fixed64 = 38; + repeated sfixed32 repeated_sfixed32 = 39; + repeated sfixed64 repeated_sfixed64 = 40; + repeated float repeated_float = 41; + repeated double repeated_double = 42; + repeated bool repeated_bool = 43; + repeated string repeated_string = 44; + repeated bytes repeated_bytes = 45; + + repeated group RepeatedGroup = 46 { + optional int32 a = 47; + } + + repeated NestedMessage repeated_nested_message = 48; + repeated ForeignMessage repeated_foreign_message = 49; + repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; + + repeated NestedEnum repeated_nested_enum = 51; + repeated ForeignEnum repeated_foreign_enum = 52; + repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; + + repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; + repeated string repeated_cord = 55 [ctype=CORD]; + + repeated NestedMessage repeated_lazy_message = 57 [lazy=true]; + + // Singular with defaults + optional int32 default_int32 = 61 [default = 41 ]; + optional int64 default_int64 = 62 [default = 42 ]; + optional uint32 default_uint32 = 63 [default = 43 ]; + optional uint64 default_uint64 = 64 [default = 44 ]; + optional sint32 default_sint32 = 65 [default = -45 ]; + optional sint64 default_sint64 = 66 [default = 46 ]; + optional fixed32 default_fixed32 = 67 [default = 47 ]; + optional fixed64 default_fixed64 = 68 [default = 48 ]; + optional sfixed32 default_sfixed32 = 69 [default = 49 ]; + optional sfixed64 default_sfixed64 = 70 [default = -50 ]; + optional float default_float = 71 [default = 51.5 ]; + optional double default_double = 72 [default = 52e3 ]; + optional bool default_bool = 73 [default = true ]; + optional string default_string = 74 [default = "hello"]; + optional bytes default_bytes = 75 [default = "world"]; + + optional NestedEnum default_nested_enum = 81 [default = BAR ]; + optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR]; + optional protobuf_unittest_import.ImportEnum + default_import_enum = 83 [default = IMPORT_BAR]; + + optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"]; + optional string default_cord = 85 [ctype=CORD,default="123"]; +} + +message TestDeprecatedFields { + optional int32 deprecated_int32 = 1 [deprecated=true]; +} + +// Define these after TestAllTypes to make sure the compiler can handle +// that. +message ForeignMessage { + optional int32 c = 1; +} + +enum ForeignEnum { + FOREIGN_FOO = 4; + FOREIGN_BAR = 5; + FOREIGN_BAZ = 6; +} + +message TestAllExtensions { + extensions 1 to max; +} + +extend TestAllExtensions { + // Singular + optional int32 optional_int32_extension = 1; + optional int64 optional_int64_extension = 2; + optional uint32 optional_uint32_extension = 3; + optional uint64 optional_uint64_extension = 4; + optional sint32 optional_sint32_extension = 5; + optional sint64 optional_sint64_extension = 6; + optional fixed32 optional_fixed32_extension = 7; + optional fixed64 optional_fixed64_extension = 8; + optional sfixed32 optional_sfixed32_extension = 9; + optional sfixed64 optional_sfixed64_extension = 10; + optional float optional_float_extension = 11; + optional double optional_double_extension = 12; + optional bool optional_bool_extension = 13; + optional string optional_string_extension = 14; + optional bytes optional_bytes_extension = 15; + + optional group OptionalGroup_extension = 16 { + optional int32 a = 17; + } + + optional TestAllTypes.NestedMessage optional_nested_message_extension = 18; + optional ForeignMessage optional_foreign_message_extension = 19; + optional protobuf_unittest_import.ImportMessage + optional_import_message_extension = 20; + + optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21; + optional ForeignEnum optional_foreign_enum_extension = 22; + optional protobuf_unittest_import.ImportEnum + optional_import_enum_extension = 23; + + optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE]; + optional string optional_cord_extension = 25 [ctype=CORD]; + + optional protobuf_unittest_import.PublicImportMessage + optional_public_import_message_extension = 26; + + optional TestAllTypes.NestedMessage + optional_lazy_message_extension = 27 [lazy=true]; + + // Repeated + repeated int32 repeated_int32_extension = 31; + repeated int64 repeated_int64_extension = 32; + repeated uint32 repeated_uint32_extension = 33; + repeated uint64 repeated_uint64_extension = 34; + repeated sint32 repeated_sint32_extension = 35; + repeated sint64 repeated_sint64_extension = 36; + repeated fixed32 repeated_fixed32_extension = 37; + repeated fixed64 repeated_fixed64_extension = 38; + repeated sfixed32 repeated_sfixed32_extension = 39; + repeated sfixed64 repeated_sfixed64_extension = 40; + repeated float repeated_float_extension = 41; + repeated double repeated_double_extension = 42; + repeated bool repeated_bool_extension = 43; + repeated string repeated_string_extension = 44; + repeated bytes repeated_bytes_extension = 45; + + repeated group RepeatedGroup_extension = 46 { + optional int32 a = 47; + } + + repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48; + repeated ForeignMessage repeated_foreign_message_extension = 49; + repeated protobuf_unittest_import.ImportMessage + repeated_import_message_extension = 50; + + repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51; + repeated ForeignEnum repeated_foreign_enum_extension = 52; + repeated protobuf_unittest_import.ImportEnum + repeated_import_enum_extension = 53; + + repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE]; + repeated string repeated_cord_extension = 55 [ctype=CORD]; + + repeated TestAllTypes.NestedMessage + repeated_lazy_message_extension = 57 [lazy=true]; + + // Singular with defaults + optional int32 default_int32_extension = 61 [default = 41 ]; + optional int64 default_int64_extension = 62 [default = 42 ]; + optional uint32 default_uint32_extension = 63 [default = 43 ]; + optional uint64 default_uint64_extension = 64 [default = 44 ]; + optional sint32 default_sint32_extension = 65 [default = -45 ]; + optional sint64 default_sint64_extension = 66 [default = 46 ]; + optional fixed32 default_fixed32_extension = 67 [default = 47 ]; + optional fixed64 default_fixed64_extension = 68 [default = 48 ]; + optional sfixed32 default_sfixed32_extension = 69 [default = 49 ]; + optional sfixed64 default_sfixed64_extension = 70 [default = -50 ]; + optional float default_float_extension = 71 [default = 51.5 ]; + optional double default_double_extension = 72 [default = 52e3 ]; + optional bool default_bool_extension = 73 [default = true ]; + optional string default_string_extension = 74 [default = "hello"]; + optional bytes default_bytes_extension = 75 [default = "world"]; + + optional TestAllTypes.NestedEnum + default_nested_enum_extension = 81 [default = BAR]; + optional ForeignEnum + default_foreign_enum_extension = 82 [default = FOREIGN_BAR]; + optional protobuf_unittest_import.ImportEnum + default_import_enum_extension = 83 [default = IMPORT_BAR]; + + optional string default_string_piece_extension = 84 [ctype=STRING_PIECE, + default="abc"]; + optional string default_cord_extension = 85 [ctype=CORD, default="123"]; +} + +message TestNestedExtension { + extend TestAllExtensions { + // Check for bug where string extensions declared in tested scope did not + // compile. + optional string test = 1002 [default="test"]; + } +} + +// We have separate messages for testing required fields because it's +// annoying to have to fill in required fields in TestProto in order to +// do anything with it. Note that we don't need to test every type of +// required filed because the code output is basically identical to +// optional fields for all types. +message TestRequired { + required int32 a = 1; + optional int32 dummy2 = 2; + required int32 b = 3; + + extend TestAllExtensions { + optional TestRequired single = 1000; + repeated TestRequired multi = 1001; + } + + // Pad the field count to 32 so that we can test that IsInitialized() + // properly checks multiple elements of has_bits_. + optional int32 dummy4 = 4; + optional int32 dummy5 = 5; + optional int32 dummy6 = 6; + optional int32 dummy7 = 7; + optional int32 dummy8 = 8; + optional int32 dummy9 = 9; + optional int32 dummy10 = 10; + optional int32 dummy11 = 11; + optional int32 dummy12 = 12; + optional int32 dummy13 = 13; + optional int32 dummy14 = 14; + optional int32 dummy15 = 15; + optional int32 dummy16 = 16; + optional int32 dummy17 = 17; + optional int32 dummy18 = 18; + optional int32 dummy19 = 19; + optional int32 dummy20 = 20; + optional int32 dummy21 = 21; + optional int32 dummy22 = 22; + optional int32 dummy23 = 23; + optional int32 dummy24 = 24; + optional int32 dummy25 = 25; + optional int32 dummy26 = 26; + optional int32 dummy27 = 27; + optional int32 dummy28 = 28; + optional int32 dummy29 = 29; + optional int32 dummy30 = 30; + optional int32 dummy31 = 31; + optional int32 dummy32 = 32; + + required int32 c = 33; +} + +message TestRequiredForeign { + optional TestRequired optional_message = 1; + repeated TestRequired repeated_message = 2; + optional int32 dummy = 3; +} + +// Test that we can use NestedMessage from outside TestAllTypes. +message TestForeignNested { + optional TestAllTypes.NestedMessage foreign_nested = 1; +} + +// TestEmptyMessage is used to test unknown field support. +message TestEmptyMessage { +} + +// Like above, but declare all field numbers as potential extensions. No +// actual extensions should ever be defined for this type. +message TestEmptyMessageWithExtensions { + extensions 1 to max; +} + +message TestMultipleExtensionRanges { + extensions 42; + extensions 4143 to 4243; + extensions 65536 to max; +} + +// Test that really large tag numbers don't break anything. +message TestReallyLargeTagNumber { + // The largest possible tag number is 2^28 - 1, since the wire format uses + // three bits to communicate wire type. + optional int32 a = 1; + optional int32 bb = 268435455; +} + +message TestRecursiveMessage { + optional TestRecursiveMessage a = 1; + optional int32 i = 2; +} + +// Test that mutual recursion works. +message TestMutualRecursionA { + optional TestMutualRecursionB bb = 1; +} + +message TestMutualRecursionB { + optional TestMutualRecursionA a = 1; + optional int32 optional_int32 = 2; +} + +// Test that groups have disjoint field numbers from their siblings and +// parents. This is NOT possible in proto1; only proto2. When attempting +// to compile with proto1, this will emit an error; so we only include it +// in protobuf_unittest_proto. +message TestDupFieldNumber { // NO_PROTO1 + optional int32 a = 1; // NO_PROTO1 + optional group Foo = 2 { optional int32 a = 1; } // NO_PROTO1 + optional group Bar = 3 { optional int32 a = 1; } // NO_PROTO1 +} // NO_PROTO1 + +// Additional messages for testing lazy fields. +message TestEagerMessage { + optional TestAllTypes sub_message = 1 [lazy=false]; +} +message TestLazyMessage { + optional TestAllTypes sub_message = 1 [lazy=true]; +} + +// Needed for a Python test. +message TestNestedMessageHasBits { + message NestedMessage { + repeated int32 nestedmessage_repeated_int32 = 1; + repeated ForeignMessage nestedmessage_repeated_foreignmessage = 2; + } + optional NestedMessage optional_nested_message = 1; +} + + +// Test an enum that has multiple values with the same number. +enum TestEnumWithDupValue { + option allow_alias = true; + FOO1 = 1; + BAR1 = 2; + BAZ = 3; + FOO2 = 1; + BAR2 = 2; +} + +// Test an enum with large, unordered values. +enum TestSparseEnum { + SPARSE_A = 123; + SPARSE_B = 62374; + SPARSE_C = 12589234; + SPARSE_D = -15; + SPARSE_E = -53452; + SPARSE_F = 0; + SPARSE_G = 2; +} + +// Test message with CamelCase field names. This violates Protocol Buffer +// standard style. +message TestCamelCaseFieldNames { + optional int32 PrimitiveField = 1; + optional string StringField = 2; + optional ForeignEnum EnumField = 3; + optional ForeignMessage MessageField = 4; + optional string StringPieceField = 5 [ctype=STRING_PIECE]; + optional string CordField = 6 [ctype=CORD]; + + repeated int32 RepeatedPrimitiveField = 7; + repeated string RepeatedStringField = 8; + repeated ForeignEnum RepeatedEnumField = 9; + repeated ForeignMessage RepeatedMessageField = 10; + repeated string RepeatedStringPieceField = 11 [ctype=STRING_PIECE]; + repeated string RepeatedCordField = 12 [ctype=CORD]; +} + + +// We list fields out of order, to ensure that we're using field number and not +// field index to determine serialization order. +message TestFieldOrderings { + optional string my_string = 11; + extensions 2 to 10; + optional int64 my_int = 1; + extensions 12 to 100; + optional float my_float = 101; +} + + +extend TestFieldOrderings { + optional string my_extension_string = 50; + optional int32 my_extension_int = 5; +} + + +message TestExtremeDefaultValues { + optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"]; + optional uint32 large_uint32 = 2 [default = 0xFFFFFFFF]; + optional uint64 large_uint64 = 3 [default = 0xFFFFFFFFFFFFFFFF]; + optional int32 small_int32 = 4 [default = -0x7FFFFFFF]; + optional int64 small_int64 = 5 [default = -0x7FFFFFFFFFFFFFFF]; + optional int32 really_small_int32 = 21 [default = -0x80000000]; + optional int64 really_small_int64 = 22 [default = -0x8000000000000000]; + + // The default value here is UTF-8 for "\u1234". (We could also just type + // the UTF-8 text directly into this text file rather than escape it, but + // lots of people use editors that would be confused by this.) + optional string utf8_string = 6 [default = "\341\210\264"]; + + // Tests for single-precision floating-point values. + optional float zero_float = 7 [default = 0]; + optional float one_float = 8 [default = 1]; + optional float small_float = 9 [default = 1.5]; + optional float negative_one_float = 10 [default = -1]; + optional float negative_float = 11 [default = -1.5]; + // Using exponents + optional float large_float = 12 [default = 2E8]; + optional float small_negative_float = 13 [default = -8e-28]; + + // Text for nonfinite floating-point values. + optional double inf_double = 14 [default = inf]; + optional double neg_inf_double = 15 [default = -inf]; + optional double nan_double = 16 [default = nan]; + optional float inf_float = 17 [default = inf]; + optional float neg_inf_float = 18 [default = -inf]; + optional float nan_float = 19 [default = nan]; + + // Tests for C++ trigraphs. + // Trigraphs should be escaped in C++ generated files, but they should not be + // escaped for other languages. + // Note that in .proto file, "\?" is a valid way to escape ? in string + // literals. + optional string cpp_trigraph = 20 [default = "? \? ?? \?? \??? ??/ ?\?-"]; + + // String defaults containing the character '\000' + optional string string_with_zero = 23 [default = "hel\000lo"]; + optional bytes bytes_with_zero = 24 [default = "wor\000ld"]; + optional string string_piece_with_zero = 25 [ctype=STRING_PIECE, + default="ab\000c"]; + optional string cord_with_zero = 26 [ctype=CORD, + default="12\0003"]; +} + +message SparseEnumMessage { + optional TestSparseEnum sparse_enum = 1; +} + +// Test String and Bytes: string is for valid UTF-8 strings +message OneString { + optional string data = 1; +} + +message MoreString { + repeated string data = 1; +} + +message OneBytes { + optional bytes data = 1; +} + +message MoreBytes { + repeated bytes data = 1; +} + + +// Test messages for packed fields + +message TestPackedTypes { + repeated int32 packed_int32 = 90 [packed = true]; + repeated int64 packed_int64 = 91 [packed = true]; + repeated uint32 packed_uint32 = 92 [packed = true]; + repeated uint64 packed_uint64 = 93 [packed = true]; + repeated sint32 packed_sint32 = 94 [packed = true]; + repeated sint64 packed_sint64 = 95 [packed = true]; + repeated fixed32 packed_fixed32 = 96 [packed = true]; + repeated fixed64 packed_fixed64 = 97 [packed = true]; + repeated sfixed32 packed_sfixed32 = 98 [packed = true]; + repeated sfixed64 packed_sfixed64 = 99 [packed = true]; + repeated float packed_float = 100 [packed = true]; + repeated double packed_double = 101 [packed = true]; + repeated bool packed_bool = 102 [packed = true]; + repeated ForeignEnum packed_enum = 103 [packed = true]; +} + +// A message with the same fields as TestPackedTypes, but without packing. Used +// to test packed <-> unpacked wire compatibility. +message TestUnpackedTypes { + repeated int32 unpacked_int32 = 90 [packed = false]; + repeated int64 unpacked_int64 = 91 [packed = false]; + repeated uint32 unpacked_uint32 = 92 [packed = false]; + repeated uint64 unpacked_uint64 = 93 [packed = false]; + repeated sint32 unpacked_sint32 = 94 [packed = false]; + repeated sint64 unpacked_sint64 = 95 [packed = false]; + repeated fixed32 unpacked_fixed32 = 96 [packed = false]; + repeated fixed64 unpacked_fixed64 = 97 [packed = false]; + repeated sfixed32 unpacked_sfixed32 = 98 [packed = false]; + repeated sfixed64 unpacked_sfixed64 = 99 [packed = false]; + repeated float unpacked_float = 100 [packed = false]; + repeated double unpacked_double = 101 [packed = false]; + repeated bool unpacked_bool = 102 [packed = false]; + repeated ForeignEnum unpacked_enum = 103 [packed = false]; +} + +message TestPackedExtensions { + extensions 1 to max; +} + +extend TestPackedExtensions { + repeated int32 packed_int32_extension = 90 [packed = true]; + repeated int64 packed_int64_extension = 91 [packed = true]; + repeated uint32 packed_uint32_extension = 92 [packed = true]; + repeated uint64 packed_uint64_extension = 93 [packed = true]; + repeated sint32 packed_sint32_extension = 94 [packed = true]; + repeated sint64 packed_sint64_extension = 95 [packed = true]; + repeated fixed32 packed_fixed32_extension = 96 [packed = true]; + repeated fixed64 packed_fixed64_extension = 97 [packed = true]; + repeated sfixed32 packed_sfixed32_extension = 98 [packed = true]; + repeated sfixed64 packed_sfixed64_extension = 99 [packed = true]; + repeated float packed_float_extension = 100 [packed = true]; + repeated double packed_double_extension = 101 [packed = true]; + repeated bool packed_bool_extension = 102 [packed = true]; + repeated ForeignEnum packed_enum_extension = 103 [packed = true]; +} + +// Used by ExtensionSetTest/DynamicExtensions. The test actually builds +// a set of extensions to TestAllExtensions dynamically, based on the fields +// of this message type. +message TestDynamicExtensions { + enum DynamicEnumType { + DYNAMIC_FOO = 2200; + DYNAMIC_BAR = 2201; + DYNAMIC_BAZ = 2202; + } + message DynamicMessageType { + optional int32 dynamic_field = 2100; + } + + optional fixed32 scalar_extension = 2000; + optional ForeignEnum enum_extension = 2001; + optional DynamicEnumType dynamic_enum_extension = 2002; + + optional ForeignMessage message_extension = 2003; + optional DynamicMessageType dynamic_message_extension = 2004; + + repeated string repeated_extension = 2005; + repeated sint32 packed_extension = 2006 [packed = true]; +} + +message TestRepeatedScalarDifferentTagSizes { + // Parsing repeated fixed size values used to fail. This message needs to be + // used in order to get a tag of the right size; all of the repeated fields + // in TestAllTypes didn't trigger the check. + repeated fixed32 repeated_fixed32 = 12; + // Check for a varint type, just for good measure. + repeated int32 repeated_int32 = 13; + + // These have two-byte tags. + repeated fixed64 repeated_fixed64 = 2046; + repeated int64 repeated_int64 = 2047; + + // Three byte tags. + repeated float repeated_float = 262142; + repeated uint64 repeated_uint64 = 262143; +} + +// Test that if an optional or required message/group field appears multiple +// times in the input, they need to be merged. +message TestParsingMerge { + // RepeatedFieldsGenerator defines matching field types as TestParsingMerge, + // except that all fields are repeated. In the tests, we will serialize the + // RepeatedFieldsGenerator to bytes, and parse the bytes to TestParsingMerge. + // Repeated fields in RepeatedFieldsGenerator are expected to be merged into + // the corresponding required/optional fields in TestParsingMerge. + message RepeatedFieldsGenerator { + repeated TestAllTypes field1 = 1; + repeated TestAllTypes field2 = 2; + repeated TestAllTypes field3 = 3; + repeated group Group1 = 10 { + optional TestAllTypes field1 = 11; + } + repeated group Group2 = 20 { + optional TestAllTypes field1 = 21; + } + repeated TestAllTypes ext1 = 1000; + repeated TestAllTypes ext2 = 1001; + } + required TestAllTypes required_all_types = 1; + optional TestAllTypes optional_all_types = 2; + repeated TestAllTypes repeated_all_types = 3; + optional group OptionalGroup = 10 { + optional TestAllTypes optional_group_all_types = 11; + } + repeated group RepeatedGroup = 20 { + optional TestAllTypes repeated_group_all_types = 21; + } + extensions 1000 to max; + extend TestParsingMerge { + optional TestAllTypes optional_ext = 1000; + repeated TestAllTypes repeated_ext = 1001; + } +} + +message TestCommentInjectionMessage { + // */ <- This should not close the generated doc comment + optional string a = 1 [default="*/ <- Neither should this."]; +} + + +// Test that RPC services work. +message FooRequest {} +message FooResponse {} + +message FooClientMessage {} +message FooServerMessage{} + +service TestService { + rpc Foo(FooRequest) returns (FooResponse); + rpc Bar(BarRequest) returns (BarResponse); +} + + +message BarRequest {} +message BarResponse {} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_custom_options.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_custom_options.proto new file mode 100644 index 0000000..e591d29 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_custom_options.proto @@ -0,0 +1,387 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: benjy@google.com (Benjy Weinberger) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// A proto file used to test the "custom options" feature of proto2. + + +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +option cc_generic_services = true; // auto-added +option java_generic_services = true; // auto-added +option py_generic_services = true; + +// A custom file option (defined below). +option (file_opt1) = 9876543210; + +import "google/protobuf/descriptor.proto"; + +// We don't put this in a package within proto2 because we need to make sure +// that the generated code doesn't depend on being in the proto2 namespace. +package protobuf_unittest; + + +// Some simple test custom options of various types. + +extend google.protobuf.FileOptions { + optional uint64 file_opt1 = 7736974; +} + +extend google.protobuf.MessageOptions { + optional int32 message_opt1 = 7739036; +} + +extend google.protobuf.FieldOptions { + optional fixed64 field_opt1 = 7740936; + // This is useful for testing that we correctly register default values for + // extension options. + optional int32 field_opt2 = 7753913 [default=42]; +} + +extend google.protobuf.EnumOptions { + optional sfixed32 enum_opt1 = 7753576; +} + +extend google.protobuf.EnumValueOptions { + optional int32 enum_value_opt1 = 1560678; +} + +extend google.protobuf.ServiceOptions { + optional sint64 service_opt1 = 7887650; +} + +enum MethodOpt1 { + METHODOPT1_VAL1 = 1; + METHODOPT1_VAL2 = 2; +} + +extend google.protobuf.MethodOptions { + optional MethodOpt1 method_opt1 = 7890860; +} + +// A test message with custom options at all possible locations (and also some +// regular options, to make sure they interact nicely). +message TestMessageWithCustomOptions { + option message_set_wire_format = false; + + option (message_opt1) = -56; + + optional string field1 = 1 [ctype=CORD, + (field_opt1)=8765432109]; + + enum AnEnum { + option (enum_opt1) = -789; + + ANENUM_VAL1 = 1; + ANENUM_VAL2 = 2 [(enum_value_opt1) = 123]; + } +} + + +// A test RPC service with custom options at all possible locations (and also +// some regular options, to make sure they interact nicely). +message CustomOptionFooRequest { +} + +message CustomOptionFooResponse { +} + +message CustomOptionFooClientMessage { +} + +message CustomOptionFooServerMessage { +} + +service TestServiceWithCustomOptions { + option (service_opt1) = -9876543210; + + rpc Foo(CustomOptionFooRequest) returns (CustomOptionFooResponse) { + option (method_opt1) = METHODOPT1_VAL2; + } +} + + + +// Options of every possible field type, so we can test them all exhaustively. + +message DummyMessageContainingEnum { + enum TestEnumType { + TEST_OPTION_ENUM_TYPE1 = 22; + TEST_OPTION_ENUM_TYPE2 = -23; + } +} + +message DummyMessageInvalidAsOptionType { +} + +extend google.protobuf.MessageOptions { + optional bool bool_opt = 7706090; + optional int32 int32_opt = 7705709; + optional int64 int64_opt = 7705542; + optional uint32 uint32_opt = 7704880; + optional uint64 uint64_opt = 7702367; + optional sint32 sint32_opt = 7701568; + optional sint64 sint64_opt = 7700863; + optional fixed32 fixed32_opt = 7700307; + optional fixed64 fixed64_opt = 7700194; + optional sfixed32 sfixed32_opt = 7698645; + optional sfixed64 sfixed64_opt = 7685475; + optional float float_opt = 7675390; + optional double double_opt = 7673293; + optional string string_opt = 7673285; + optional bytes bytes_opt = 7673238; + optional DummyMessageContainingEnum.TestEnumType enum_opt = 7673233; + optional DummyMessageInvalidAsOptionType message_type_opt = 7665967; +} + +message CustomOptionMinIntegerValues { + option (bool_opt) = false; + option (int32_opt) = -0x80000000; + option (int64_opt) = -0x8000000000000000; + option (uint32_opt) = 0; + option (uint64_opt) = 0; + option (sint32_opt) = -0x80000000; + option (sint64_opt) = -0x8000000000000000; + option (fixed32_opt) = 0; + option (fixed64_opt) = 0; + option (sfixed32_opt) = -0x80000000; + option (sfixed64_opt) = -0x8000000000000000; +} + +message CustomOptionMaxIntegerValues { + option (bool_opt) = true; + option (int32_opt) = 0x7FFFFFFF; + option (int64_opt) = 0x7FFFFFFFFFFFFFFF; + option (uint32_opt) = 0xFFFFFFFF; + option (uint64_opt) = 0xFFFFFFFFFFFFFFFF; + option (sint32_opt) = 0x7FFFFFFF; + option (sint64_opt) = 0x7FFFFFFFFFFFFFFF; + option (fixed32_opt) = 0xFFFFFFFF; + option (fixed64_opt) = 0xFFFFFFFFFFFFFFFF; + option (sfixed32_opt) = 0x7FFFFFFF; + option (sfixed64_opt) = 0x7FFFFFFFFFFFFFFF; +} + +message CustomOptionOtherValues { + option (int32_opt) = -100; // To test sign-extension. + option (float_opt) = 12.3456789; + option (double_opt) = 1.234567890123456789; + option (string_opt) = "Hello, \"World\""; + option (bytes_opt) = "Hello\0World"; + option (enum_opt) = TEST_OPTION_ENUM_TYPE2; +} + +message SettingRealsFromPositiveInts { + option (float_opt) = 12; + option (double_opt) = 154; +} + +message SettingRealsFromNegativeInts { + option (float_opt) = -12; + option (double_opt) = -154; +} + +// Options of complex message types, themselves combined and extended in +// various ways. + +message ComplexOptionType1 { + optional int32 foo = 1; + optional int32 foo2 = 2; + optional int32 foo3 = 3; + + extensions 100 to max; +} + +message ComplexOptionType2 { + optional ComplexOptionType1 bar = 1; + optional int32 baz = 2; + + message ComplexOptionType4 { + optional int32 waldo = 1; + + extend google.protobuf.MessageOptions { + optional ComplexOptionType4 complex_opt4 = 7633546; + } + } + + optional ComplexOptionType4 fred = 3; + + extensions 100 to max; +} + +message ComplexOptionType3 { + optional int32 qux = 1; + + optional group ComplexOptionType5 = 2 { + optional int32 plugh = 3; + } +} + +extend ComplexOptionType1 { + optional int32 quux = 7663707; + optional ComplexOptionType3 corge = 7663442; +} + +extend ComplexOptionType2 { + optional int32 grault = 7650927; + optional ComplexOptionType1 garply = 7649992; +} + +extend google.protobuf.MessageOptions { + optional protobuf_unittest.ComplexOptionType1 complex_opt1 = 7646756; + optional ComplexOptionType2 complex_opt2 = 7636949; + optional ComplexOptionType3 complex_opt3 = 7636463; + optional group ComplexOpt6 = 7595468 { + optional int32 xyzzy = 7593951; + } +} + +// Note that we try various different ways of naming the same extension. +message VariousComplexOptions { + option (.protobuf_unittest.complex_opt1).foo = 42; + option (protobuf_unittest.complex_opt1).(.protobuf_unittest.quux) = 324; + option (.protobuf_unittest.complex_opt1).(protobuf_unittest.corge).qux = 876; + option (complex_opt2).baz = 987; + option (complex_opt2).(grault) = 654; + option (complex_opt2).bar.foo = 743; + option (complex_opt2).bar.(quux) = 1999; + option (complex_opt2).bar.(protobuf_unittest.corge).qux = 2008; + option (complex_opt2).(garply).foo = 741; + option (complex_opt2).(garply).(.protobuf_unittest.quux) = 1998; + option (complex_opt2).(protobuf_unittest.garply).(corge).qux = 2121; + option (ComplexOptionType2.ComplexOptionType4.complex_opt4).waldo = 1971; + option (complex_opt2).fred.waldo = 321; + option (protobuf_unittest.complex_opt3).qux = 9; + option (complex_opt3).complexoptiontype5.plugh = 22; + option (complexopt6).xyzzy = 24; +} + +// ------------------------------------------------------ +// Definitions for testing aggregate option parsing. +// See descriptor_unittest.cc. + +message AggregateMessageSet { + option message_set_wire_format = true; + extensions 4 to max; +} + +message AggregateMessageSetElement { + extend AggregateMessageSet { + optional AggregateMessageSetElement message_set_extension = 15447542; + } + optional string s = 1; +} + +// A helper type used to test aggregate option parsing +message Aggregate { + optional int32 i = 1; + optional string s = 2; + + // A nested object + optional Aggregate sub = 3; + + // To test the parsing of extensions inside aggregate values + optional google.protobuf.FileOptions file = 4; + extend google.protobuf.FileOptions { + optional Aggregate nested = 15476903; + } + + // An embedded message set + optional AggregateMessageSet mset = 5; +} + +// Allow Aggregate to be used as an option at all possible locations +// in the .proto grammer. +extend google.protobuf.FileOptions { optional Aggregate fileopt = 15478479; } +extend google.protobuf.MessageOptions { optional Aggregate msgopt = 15480088; } +extend google.protobuf.FieldOptions { optional Aggregate fieldopt = 15481374; } +extend google.protobuf.EnumOptions { optional Aggregate enumopt = 15483218; } +extend google.protobuf.EnumValueOptions { optional Aggregate enumvalopt = 15486921; } +extend google.protobuf.ServiceOptions { optional Aggregate serviceopt = 15497145; } +extend google.protobuf.MethodOptions { optional Aggregate methodopt = 15512713; } + +// Try using AggregateOption at different points in the proto grammar +option (fileopt) = { + s: 'FileAnnotation' + // Also test the handling of comments + /* of both types */ i: 100 + + sub { s: 'NestedFileAnnotation' } + + // Include a google.protobuf.FileOptions and recursively extend it with + // another fileopt. + file { + [protobuf_unittest.fileopt] { + s:'FileExtensionAnnotation' + } + } + + // A message set inside an option value + mset { + [protobuf_unittest.AggregateMessageSetElement.message_set_extension] { + s: 'EmbeddedMessageSetElement' + } + } +}; + +message AggregateMessage { + option (msgopt) = { i:101 s:'MessageAnnotation' }; + optional int32 fieldname = 1 [(fieldopt) = { s:'FieldAnnotation' }]; +} + +service AggregateService { + option (serviceopt) = { s:'ServiceAnnotation' }; + rpc Method (AggregateMessage) returns (AggregateMessage) { + option (methodopt) = { s:'MethodAnnotation' }; + } +} + +enum AggregateEnum { + option (enumopt) = { s:'EnumAnnotation' }; + VALUE = 1 [(enumvalopt) = { s:'EnumValueAnnotation' }]; +} + +// Test custom options for nested type. +message NestedOptionType { + message NestedMessage { + option (message_opt1) = 1001; + optional int32 nested_field = 1 [(field_opt1) = 1002]; + } + enum NestedEnum { + option (enum_opt1) = 1003; + NESTED_ENUM_VALUE = 1 [(enum_value_opt1) = 1004]; + } + extend google.protobuf.FileOptions { + optional int32 nested_extension = 7912573 [(field_opt2) = 1005]; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_embed_optimize_for.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_embed_optimize_for.proto new file mode 100644 index 0000000..fa17625 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_embed_optimize_for.proto @@ -0,0 +1,50 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// A proto file which imports a proto file that uses optimize_for = CODE_SIZE. + +import "google/protobuf/unittest_optimize_for.proto"; + +package protobuf_unittest; + +// We optimize for speed here, but we are importing a proto that is optimized +// for code size. +option optimize_for = SPEED; + +message TestEmbedOptimizedForSize { + // Test that embedding a message which has optimize_for = CODE_SIZE into + // one optimized for speed works. + optional TestOptimizedForSize optional_message = 1; + repeated TestOptimizedForSize repeated_message = 2; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_empty.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_empty.proto new file mode 100644 index 0000000..ab12d1f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_empty.proto @@ -0,0 +1,37 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file intentionally left blank. (At one point this wouldn't compile +// correctly.) + diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_enormous_descriptor.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_enormous_descriptor.proto new file mode 100644 index 0000000..bc0b7c1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_enormous_descriptor.proto @@ -0,0 +1,1046 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// A proto file that has an extremely large descriptor. Used to test that +// descriptors over 64k don't break the string literal length limit in Java. + + +package google.protobuf; +option java_package = "com.google.protobuf"; + +// Avoid generating insanely long methods. +option optimize_for = CODE_SIZE; + +message TestEnormousDescriptor { + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1 = 1 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_2 = 2 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_3 = 3 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_4 = 4 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_5 = 5 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_6 = 6 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_7 = 7 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_8 = 8 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_9 = 9 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_10 = 10 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_11 = 11 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_12 = 12 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_13 = 13 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_14 = 14 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_15 = 15 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_16 = 16 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_17 = 17 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_18 = 18 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_19 = 19 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_20 = 20 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_21 = 21 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_22 = 22 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_23 = 23 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_24 = 24 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_25 = 25 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_26 = 26 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_27 = 27 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_28 = 28 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_29 = 29 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_30 = 30 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_31 = 31 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_32 = 32 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_33 = 33 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_34 = 34 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_35 = 35 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_36 = 36 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_37 = 37 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_38 = 38 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_39 = 39 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_40 = 40 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_41 = 41 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_42 = 42 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_43 = 43 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_44 = 44 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_45 = 45 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_46 = 46 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_47 = 47 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_48 = 48 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_49 = 49 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_50 = 50 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_51 = 51 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_52 = 52 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_53 = 53 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_54 = 54 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_55 = 55 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_56 = 56 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_57 = 57 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_58 = 58 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_59 = 59 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_60 = 60 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_61 = 61 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_62 = 62 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_63 = 63 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_64 = 64 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_65 = 65 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_66 = 66 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_67 = 67 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_68 = 68 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_69 = 69 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_70 = 70 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_71 = 71 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_72 = 72 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_73 = 73 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_74 = 74 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_75 = 75 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_76 = 76 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_77 = 77 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_78 = 78 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_79 = 79 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_80 = 80 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_81 = 81 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_82 = 82 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_83 = 83 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_84 = 84 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_85 = 85 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_86 = 86 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_87 = 87 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_88 = 88 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_89 = 89 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_90 = 90 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_91 = 91 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_92 = 92 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_93 = 93 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_94 = 94 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_95 = 95 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_96 = 96 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_97 = 97 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_98 = 98 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_99 = 99 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_100 = 100 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_101 = 101 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_102 = 102 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_103 = 103 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_104 = 104 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_105 = 105 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_106 = 106 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_107 = 107 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_108 = 108 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_109 = 109 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_110 = 110 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_111 = 111 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_112 = 112 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_113 = 113 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_114 = 114 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_115 = 115 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_116 = 116 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_117 = 117 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_118 = 118 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_119 = 119 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_120 = 120 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_121 = 121 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_122 = 122 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_123 = 123 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_124 = 124 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_125 = 125 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_126 = 126 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_127 = 127 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_128 = 128 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_129 = 129 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_130 = 130 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_131 = 131 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_132 = 132 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_133 = 133 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_134 = 134 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_135 = 135 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_136 = 136 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_137 = 137 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_138 = 138 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_139 = 139 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_140 = 140 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_141 = 141 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_142 = 142 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_143 = 143 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_144 = 144 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_145 = 145 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_146 = 146 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_147 = 147 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_148 = 148 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_149 = 149 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_150 = 150 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_151 = 151 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_152 = 152 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_153 = 153 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_154 = 154 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_155 = 155 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_156 = 156 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_157 = 157 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_158 = 158 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_159 = 159 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_160 = 160 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_161 = 161 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_162 = 162 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_163 = 163 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_164 = 164 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_165 = 165 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_166 = 166 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_167 = 167 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_168 = 168 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_169 = 169 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_170 = 170 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_171 = 171 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_172 = 172 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_173 = 173 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_174 = 174 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_175 = 175 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_176 = 176 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_177 = 177 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_178 = 178 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_179 = 179 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_180 = 180 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_181 = 181 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_182 = 182 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_183 = 183 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_184 = 184 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_185 = 185 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_186 = 186 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_187 = 187 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_188 = 188 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_189 = 189 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_190 = 190 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_191 = 191 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_192 = 192 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_193 = 193 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_194 = 194 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_195 = 195 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_196 = 196 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_197 = 197 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_198 = 198 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_199 = 199 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_200 = 200 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_201 = 201 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_202 = 202 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_203 = 203 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_204 = 204 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_205 = 205 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_206 = 206 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_207 = 207 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_208 = 208 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_209 = 209 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_210 = 210 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_211 = 211 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_212 = 212 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_213 = 213 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_214 = 214 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_215 = 215 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_216 = 216 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_217 = 217 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_218 = 218 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_219 = 219 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_220 = 220 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_221 = 221 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_222 = 222 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_223 = 223 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_224 = 224 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_225 = 225 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_226 = 226 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_227 = 227 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_228 = 228 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_229 = 229 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_230 = 230 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_231 = 231 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_232 = 232 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_233 = 233 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_234 = 234 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_235 = 235 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_236 = 236 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_237 = 237 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_238 = 238 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_239 = 239 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_240 = 240 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_241 = 241 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_242 = 242 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_243 = 243 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_244 = 244 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_245 = 245 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_246 = 246 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_247 = 247 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_248 = 248 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_249 = 249 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_250 = 250 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_251 = 251 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_252 = 252 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_253 = 253 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_254 = 254 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_255 = 255 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_256 = 256 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_257 = 257 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_258 = 258 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_259 = 259 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_260 = 260 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_261 = 261 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_262 = 262 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_263 = 263 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_264 = 264 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_265 = 265 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_266 = 266 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_267 = 267 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_268 = 268 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_269 = 269 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_270 = 270 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_271 = 271 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_272 = 272 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_273 = 273 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_274 = 274 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_275 = 275 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_276 = 276 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_277 = 277 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_278 = 278 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_279 = 279 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_280 = 280 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_281 = 281 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_282 = 282 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_283 = 283 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_284 = 284 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_285 = 285 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_286 = 286 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_287 = 287 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_288 = 288 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_289 = 289 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_290 = 290 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_291 = 291 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_292 = 292 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_293 = 293 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_294 = 294 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_295 = 295 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_296 = 296 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_297 = 297 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_298 = 298 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_299 = 299 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_300 = 300 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_301 = 301 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_302 = 302 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_303 = 303 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_304 = 304 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_305 = 305 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_306 = 306 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_307 = 307 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_308 = 308 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_309 = 309 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_310 = 310 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_311 = 311 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_312 = 312 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_313 = 313 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_314 = 314 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_315 = 315 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_316 = 316 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_317 = 317 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_318 = 318 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_319 = 319 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_320 = 320 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_321 = 321 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_322 = 322 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_323 = 323 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_324 = 324 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_325 = 325 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_326 = 326 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_327 = 327 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_328 = 328 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_329 = 329 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_330 = 330 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_331 = 331 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_332 = 332 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_333 = 333 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_334 = 334 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_335 = 335 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_336 = 336 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_337 = 337 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_338 = 338 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_339 = 339 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_340 = 340 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_341 = 341 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_342 = 342 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_343 = 343 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_344 = 344 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_345 = 345 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_346 = 346 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_347 = 347 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_348 = 348 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_349 = 349 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_350 = 350 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_351 = 351 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_352 = 352 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_353 = 353 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_354 = 354 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_355 = 355 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_356 = 356 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_357 = 357 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_358 = 358 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_359 = 359 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_360 = 360 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_361 = 361 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_362 = 362 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_363 = 363 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_364 = 364 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_365 = 365 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_366 = 366 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_367 = 367 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_368 = 368 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_369 = 369 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_370 = 370 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_371 = 371 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_372 = 372 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_373 = 373 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_374 = 374 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_375 = 375 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_376 = 376 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_377 = 377 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_378 = 378 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_379 = 379 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_380 = 380 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_381 = 381 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_382 = 382 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_383 = 383 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_384 = 384 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_385 = 385 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_386 = 386 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_387 = 387 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_388 = 388 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_389 = 389 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_390 = 390 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_391 = 391 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_392 = 392 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_393 = 393 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_394 = 394 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_395 = 395 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_396 = 396 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_397 = 397 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_398 = 398 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_399 = 399 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_400 = 400 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_401 = 401 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_402 = 402 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_403 = 403 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_404 = 404 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_405 = 405 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_406 = 406 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_407 = 407 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_408 = 408 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_409 = 409 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_410 = 410 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_411 = 411 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_412 = 412 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_413 = 413 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_414 = 414 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_415 = 415 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_416 = 416 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_417 = 417 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_418 = 418 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_419 = 419 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_420 = 420 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_421 = 421 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_422 = 422 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_423 = 423 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_424 = 424 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_425 = 425 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_426 = 426 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_427 = 427 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_428 = 428 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_429 = 429 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_430 = 430 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_431 = 431 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_432 = 432 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_433 = 433 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_434 = 434 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_435 = 435 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_436 = 436 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_437 = 437 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_438 = 438 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_439 = 439 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_440 = 440 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_441 = 441 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_442 = 442 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_443 = 443 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_444 = 444 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_445 = 445 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_446 = 446 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_447 = 447 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_448 = 448 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_449 = 449 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_450 = 450 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_451 = 451 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_452 = 452 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_453 = 453 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_454 = 454 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_455 = 455 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_456 = 456 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_457 = 457 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_458 = 458 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_459 = 459 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_460 = 460 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_461 = 461 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_462 = 462 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_463 = 463 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_464 = 464 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_465 = 465 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_466 = 466 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_467 = 467 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_468 = 468 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_469 = 469 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_470 = 470 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_471 = 471 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_472 = 472 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_473 = 473 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_474 = 474 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_475 = 475 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_476 = 476 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_477 = 477 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_478 = 478 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_479 = 479 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_480 = 480 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_481 = 481 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_482 = 482 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_483 = 483 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_484 = 484 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_485 = 485 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_486 = 486 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_487 = 487 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_488 = 488 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_489 = 489 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_490 = 490 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_491 = 491 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_492 = 492 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_493 = 493 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_494 = 494 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_495 = 495 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_496 = 496 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_497 = 497 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_498 = 498 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_499 = 499 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_500 = 500 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_501 = 501 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_502 = 502 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_503 = 503 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_504 = 504 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_505 = 505 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_506 = 506 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_507 = 507 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_508 = 508 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_509 = 509 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_510 = 510 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_511 = 511 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_512 = 512 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_513 = 513 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_514 = 514 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_515 = 515 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_516 = 516 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_517 = 517 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_518 = 518 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_519 = 519 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_520 = 520 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_521 = 521 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_522 = 522 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_523 = 523 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_524 = 524 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_525 = 525 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_526 = 526 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_527 = 527 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_528 = 528 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_529 = 529 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_530 = 530 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_531 = 531 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_532 = 532 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_533 = 533 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_534 = 534 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_535 = 535 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_536 = 536 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_537 = 537 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_538 = 538 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_539 = 539 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_540 = 540 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_541 = 541 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_542 = 542 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_543 = 543 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_544 = 544 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_545 = 545 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_546 = 546 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_547 = 547 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_548 = 548 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_549 = 549 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_550 = 550 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_551 = 551 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_552 = 552 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_553 = 553 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_554 = 554 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_555 = 555 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_556 = 556 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_557 = 557 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_558 = 558 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_559 = 559 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_560 = 560 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_561 = 561 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_562 = 562 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_563 = 563 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_564 = 564 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_565 = 565 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_566 = 566 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_567 = 567 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_568 = 568 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_569 = 569 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_570 = 570 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_571 = 571 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_572 = 572 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_573 = 573 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_574 = 574 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_575 = 575 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_576 = 576 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_577 = 577 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_578 = 578 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_579 = 579 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_580 = 580 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_581 = 581 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_582 = 582 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_583 = 583 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_584 = 584 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_585 = 585 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_586 = 586 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_587 = 587 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_588 = 588 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_589 = 589 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_590 = 590 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_591 = 591 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_592 = 592 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_593 = 593 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_594 = 594 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_595 = 595 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_596 = 596 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_597 = 597 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_598 = 598 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_599 = 599 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_600 = 600 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_601 = 601 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_602 = 602 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_603 = 603 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_604 = 604 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_605 = 605 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_606 = 606 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_607 = 607 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_608 = 608 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_609 = 609 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_610 = 610 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_611 = 611 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_612 = 612 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_613 = 613 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_614 = 614 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_615 = 615 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_616 = 616 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_617 = 617 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_618 = 618 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_619 = 619 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_620 = 620 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_621 = 621 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_622 = 622 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_623 = 623 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_624 = 624 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_625 = 625 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_626 = 626 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_627 = 627 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_628 = 628 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_629 = 629 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_630 = 630 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_631 = 631 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_632 = 632 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_633 = 633 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_634 = 634 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_635 = 635 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_636 = 636 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_637 = 637 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_638 = 638 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_639 = 639 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_640 = 640 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_641 = 641 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_642 = 642 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_643 = 643 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_644 = 644 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_645 = 645 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_646 = 646 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_647 = 647 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_648 = 648 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_649 = 649 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_650 = 650 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_651 = 651 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_652 = 652 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_653 = 653 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_654 = 654 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_655 = 655 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_656 = 656 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_657 = 657 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_658 = 658 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_659 = 659 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_660 = 660 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_661 = 661 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_662 = 662 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_663 = 663 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_664 = 664 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_665 = 665 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_666 = 666 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_667 = 667 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_668 = 668 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_669 = 669 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_670 = 670 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_671 = 671 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_672 = 672 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_673 = 673 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_674 = 674 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_675 = 675 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_676 = 676 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_677 = 677 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_678 = 678 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_679 = 679 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_680 = 680 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_681 = 681 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_682 = 682 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_683 = 683 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_684 = 684 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_685 = 685 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_686 = 686 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_687 = 687 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_688 = 688 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_689 = 689 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_690 = 690 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_691 = 691 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_692 = 692 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_693 = 693 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_694 = 694 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_695 = 695 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_696 = 696 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_697 = 697 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_698 = 698 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_699 = 699 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_700 = 700 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_701 = 701 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_702 = 702 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_703 = 703 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_704 = 704 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_705 = 705 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_706 = 706 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_707 = 707 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_708 = 708 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_709 = 709 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_710 = 710 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_711 = 711 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_712 = 712 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_713 = 713 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_714 = 714 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_715 = 715 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_716 = 716 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_717 = 717 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_718 = 718 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_719 = 719 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_720 = 720 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_721 = 721 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_722 = 722 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_723 = 723 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_724 = 724 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_725 = 725 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_726 = 726 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_727 = 727 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_728 = 728 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_729 = 729 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_730 = 730 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_731 = 731 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_732 = 732 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_733 = 733 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_734 = 734 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_735 = 735 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_736 = 736 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_737 = 737 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_738 = 738 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_739 = 739 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_740 = 740 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_741 = 741 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_742 = 742 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_743 = 743 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_744 = 744 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_745 = 745 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_746 = 746 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_747 = 747 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_748 = 748 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_749 = 749 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_750 = 750 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_751 = 751 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_752 = 752 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_753 = 753 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_754 = 754 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_755 = 755 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_756 = 756 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_757 = 757 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_758 = 758 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_759 = 759 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_760 = 760 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_761 = 761 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_762 = 762 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_763 = 763 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_764 = 764 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_765 = 765 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_766 = 766 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_767 = 767 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_768 = 768 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_769 = 769 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_770 = 770 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_771 = 771 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_772 = 772 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_773 = 773 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_774 = 774 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_775 = 775 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_776 = 776 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_777 = 777 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_778 = 778 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_779 = 779 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_780 = 780 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_781 = 781 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_782 = 782 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_783 = 783 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_784 = 784 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_785 = 785 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_786 = 786 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_787 = 787 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_788 = 788 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_789 = 789 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_790 = 790 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_791 = 791 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_792 = 792 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_793 = 793 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_794 = 794 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_795 = 795 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_796 = 796 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_797 = 797 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_798 = 798 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_799 = 799 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_800 = 800 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_801 = 801 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_802 = 802 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_803 = 803 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_804 = 804 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_805 = 805 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_806 = 806 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_807 = 807 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_808 = 808 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_809 = 809 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_810 = 810 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_811 = 811 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_812 = 812 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_813 = 813 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_814 = 814 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_815 = 815 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_816 = 816 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_817 = 817 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_818 = 818 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_819 = 819 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_820 = 820 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_821 = 821 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_822 = 822 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_823 = 823 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_824 = 824 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_825 = 825 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_826 = 826 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_827 = 827 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_828 = 828 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_829 = 829 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_830 = 830 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_831 = 831 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_832 = 832 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_833 = 833 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_834 = 834 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_835 = 835 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_836 = 836 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_837 = 837 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_838 = 838 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_839 = 839 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_840 = 840 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_841 = 841 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_842 = 842 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_843 = 843 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_844 = 844 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_845 = 845 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_846 = 846 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_847 = 847 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_848 = 848 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_849 = 849 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_850 = 850 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_851 = 851 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_852 = 852 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_853 = 853 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_854 = 854 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_855 = 855 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_856 = 856 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_857 = 857 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_858 = 858 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_859 = 859 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_860 = 860 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_861 = 861 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_862 = 862 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_863 = 863 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_864 = 864 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_865 = 865 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_866 = 866 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_867 = 867 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_868 = 868 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_869 = 869 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_870 = 870 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_871 = 871 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_872 = 872 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_873 = 873 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_874 = 874 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_875 = 875 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_876 = 876 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_877 = 877 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_878 = 878 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_879 = 879 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_880 = 880 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_881 = 881 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_882 = 882 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_883 = 883 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_884 = 884 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_885 = 885 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_886 = 886 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_887 = 887 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_888 = 888 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_889 = 889 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_890 = 890 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_891 = 891 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_892 = 892 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_893 = 893 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_894 = 894 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_895 = 895 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_896 = 896 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_897 = 897 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_898 = 898 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_899 = 899 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_900 = 900 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_901 = 901 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_902 = 902 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_903 = 903 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_904 = 904 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_905 = 905 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_906 = 906 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_907 = 907 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_908 = 908 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_909 = 909 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_910 = 910 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_911 = 911 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_912 = 912 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_913 = 913 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_914 = 914 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_915 = 915 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_916 = 916 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_917 = 917 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_918 = 918 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_919 = 919 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_920 = 920 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_921 = 921 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_922 = 922 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_923 = 923 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_924 = 924 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_925 = 925 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_926 = 926 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_927 = 927 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_928 = 928 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_929 = 929 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_930 = 930 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_931 = 931 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_932 = 932 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_933 = 933 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_934 = 934 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_935 = 935 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_936 = 936 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_937 = 937 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_938 = 938 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_939 = 939 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_940 = 940 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_941 = 941 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_942 = 942 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_943 = 943 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_944 = 944 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_945 = 945 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_946 = 946 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_947 = 947 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_948 = 948 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_949 = 949 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_950 = 950 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_951 = 951 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_952 = 952 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_953 = 953 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_954 = 954 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_955 = 955 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_956 = 956 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_957 = 957 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_958 = 958 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_959 = 959 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_960 = 960 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_961 = 961 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_962 = 962 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_963 = 963 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_964 = 964 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_965 = 965 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_966 = 966 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_967 = 967 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_968 = 968 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_969 = 969 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_970 = 970 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_971 = 971 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_972 = 972 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_973 = 973 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_974 = 974 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_975 = 975 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_976 = 976 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_977 = 977 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_978 = 978 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_979 = 979 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_980 = 980 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_981 = 981 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_982 = 982 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_983 = 983 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_984 = 984 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_985 = 985 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_986 = 986 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_987 = 987 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_988 = 988 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_989 = 989 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_990 = 990 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_991 = 991 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_992 = 992 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_993 = 993 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_994 = 994 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_995 = 995 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_996 = 996 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_997 = 997 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_998 = 998 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_999 = 999 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; + optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000 = 1000 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import.proto new file mode 100644 index 0000000..c115b11 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import.proto @@ -0,0 +1,64 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// A proto file which is imported by unittest.proto to test importing. + + +// We don't put this in a package within proto2 because we need to make sure +// that the generated code doesn't depend on being in the proto2 namespace. +// In test_util.h we do +// "using namespace unittest_import = protobuf_unittest_import". +package protobuf_unittest_import; + +option optimize_for = SPEED; + +// Excercise the java_package option. +option java_package = "com.google.protobuf.test"; + +// Do not set a java_outer_classname here to verify that Proto2 works without +// one. + +// Test public import +import public "google/protobuf/unittest_import_public.proto"; + +message ImportMessage { + optional int32 d = 1; +} + +enum ImportEnum { + IMPORT_FOO = 7; + IMPORT_BAR = 8; + IMPORT_BAZ = 9; +} + diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_lite.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_lite.proto new file mode 100644 index 0000000..81b117f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_lite.proto @@ -0,0 +1,51 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// This is like unittest_import.proto but with optimize_for = LITE_RUNTIME. + +package protobuf_unittest_import; + +option optimize_for = LITE_RUNTIME; + +option java_package = "com.google.protobuf"; + +import public "google/protobuf/unittest_import_public_lite.proto"; + +message ImportMessageLite { + optional int32 d = 1; +} + +enum ImportEnumLite { + IMPORT_LITE_FOO = 7; + IMPORT_LITE_BAR = 8; + IMPORT_LITE_BAZ = 9; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_public.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_public.proto new file mode 100644 index 0000000..ea5d1b1 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_public.proto @@ -0,0 +1,40 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: liujisi@google.com (Pherl Liu) + + +package protobuf_unittest_import; + +option java_package = "com.google.protobuf.test"; + +message PublicImportMessage { + optional int32 e = 1; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_public_lite.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_public_lite.proto new file mode 100644 index 0000000..d077563 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_import_public_lite.proto @@ -0,0 +1,42 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: liujisi@google.com (Pherl Liu) + + +package protobuf_unittest_import; + +option optimize_for = LITE_RUNTIME; + +option java_package = "com.google.protobuf"; + +message PublicImportMessageLite { + optional int32 e = 1; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_lite.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_lite.proto new file mode 100644 index 0000000..a1764aa --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_lite.proto @@ -0,0 +1,360 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// This is like unittest.proto but with optimize_for = LITE_RUNTIME. + +package protobuf_unittest; + +import "google/protobuf/unittest_import_lite.proto"; + +option optimize_for = LITE_RUNTIME; + +option java_package = "com.google.protobuf"; + +// Same as TestAllTypes but with the lite runtime. +message TestAllTypesLite { + message NestedMessage { + optional int32 bb = 1; + } + + enum NestedEnum { + FOO = 1; + BAR = 2; + BAZ = 3; + } + + // Singular + optional int32 optional_int32 = 1; + optional int64 optional_int64 = 2; + optional uint32 optional_uint32 = 3; + optional uint64 optional_uint64 = 4; + optional sint32 optional_sint32 = 5; + optional sint64 optional_sint64 = 6; + optional fixed32 optional_fixed32 = 7; + optional fixed64 optional_fixed64 = 8; + optional sfixed32 optional_sfixed32 = 9; + optional sfixed64 optional_sfixed64 = 10; + optional float optional_float = 11; + optional double optional_double = 12; + optional bool optional_bool = 13; + optional string optional_string = 14; + optional bytes optional_bytes = 15; + + optional group OptionalGroup = 16 { + optional int32 a = 17; + } + + optional NestedMessage optional_nested_message = 18; + optional ForeignMessageLite optional_foreign_message = 19; + optional protobuf_unittest_import.ImportMessageLite + optional_import_message = 20; + + optional NestedEnum optional_nested_enum = 21; + optional ForeignEnumLite optional_foreign_enum = 22; + optional protobuf_unittest_import.ImportEnumLite optional_import_enum = 23; + + optional string optional_string_piece = 24 [ctype=STRING_PIECE]; + optional string optional_cord = 25 [ctype=CORD]; + + // Defined in unittest_import_public.proto + optional protobuf_unittest_import.PublicImportMessageLite + optional_public_import_message = 26; + + optional NestedMessage optional_lazy_message = 27 [lazy=true]; + + // Repeated + repeated int32 repeated_int32 = 31; + repeated int64 repeated_int64 = 32; + repeated uint32 repeated_uint32 = 33; + repeated uint64 repeated_uint64 = 34; + repeated sint32 repeated_sint32 = 35; + repeated sint64 repeated_sint64 = 36; + repeated fixed32 repeated_fixed32 = 37; + repeated fixed64 repeated_fixed64 = 38; + repeated sfixed32 repeated_sfixed32 = 39; + repeated sfixed64 repeated_sfixed64 = 40; + repeated float repeated_float = 41; + repeated double repeated_double = 42; + repeated bool repeated_bool = 43; + repeated string repeated_string = 44; + repeated bytes repeated_bytes = 45; + + repeated group RepeatedGroup = 46 { + optional int32 a = 47; + } + + repeated NestedMessage repeated_nested_message = 48; + repeated ForeignMessageLite repeated_foreign_message = 49; + repeated protobuf_unittest_import.ImportMessageLite + repeated_import_message = 50; + + repeated NestedEnum repeated_nested_enum = 51; + repeated ForeignEnumLite repeated_foreign_enum = 52; + repeated protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53; + + repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; + repeated string repeated_cord = 55 [ctype=CORD]; + + repeated NestedMessage repeated_lazy_message = 57 [lazy=true]; + + // Singular with defaults + optional int32 default_int32 = 61 [default = 41 ]; + optional int64 default_int64 = 62 [default = 42 ]; + optional uint32 default_uint32 = 63 [default = 43 ]; + optional uint64 default_uint64 = 64 [default = 44 ]; + optional sint32 default_sint32 = 65 [default = -45 ]; + optional sint64 default_sint64 = 66 [default = 46 ]; + optional fixed32 default_fixed32 = 67 [default = 47 ]; + optional fixed64 default_fixed64 = 68 [default = 48 ]; + optional sfixed32 default_sfixed32 = 69 [default = 49 ]; + optional sfixed64 default_sfixed64 = 70 [default = -50 ]; + optional float default_float = 71 [default = 51.5 ]; + optional double default_double = 72 [default = 52e3 ]; + optional bool default_bool = 73 [default = true ]; + optional string default_string = 74 [default = "hello"]; + optional bytes default_bytes = 75 [default = "world"]; + + optional NestedEnum default_nested_enum = 81 [default = BAR]; + optional ForeignEnumLite default_foreign_enum = 82 + [default = FOREIGN_LITE_BAR]; + optional protobuf_unittest_import.ImportEnumLite + default_import_enum = 83 [default = IMPORT_LITE_BAR]; + + optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"]; + optional string default_cord = 85 [ctype=CORD,default="123"]; +} + +message ForeignMessageLite { + optional int32 c = 1; +} + +enum ForeignEnumLite { + FOREIGN_LITE_FOO = 4; + FOREIGN_LITE_BAR = 5; + FOREIGN_LITE_BAZ = 6; +} + +message TestPackedTypesLite { + repeated int32 packed_int32 = 90 [packed = true]; + repeated int64 packed_int64 = 91 [packed = true]; + repeated uint32 packed_uint32 = 92 [packed = true]; + repeated uint64 packed_uint64 = 93 [packed = true]; + repeated sint32 packed_sint32 = 94 [packed = true]; + repeated sint64 packed_sint64 = 95 [packed = true]; + repeated fixed32 packed_fixed32 = 96 [packed = true]; + repeated fixed64 packed_fixed64 = 97 [packed = true]; + repeated sfixed32 packed_sfixed32 = 98 [packed = true]; + repeated sfixed64 packed_sfixed64 = 99 [packed = true]; + repeated float packed_float = 100 [packed = true]; + repeated double packed_double = 101 [packed = true]; + repeated bool packed_bool = 102 [packed = true]; + repeated ForeignEnumLite packed_enum = 103 [packed = true]; +} + +message TestAllExtensionsLite { + extensions 1 to max; +} + +extend TestAllExtensionsLite { + // Singular + optional int32 optional_int32_extension_lite = 1; + optional int64 optional_int64_extension_lite = 2; + optional uint32 optional_uint32_extension_lite = 3; + optional uint64 optional_uint64_extension_lite = 4; + optional sint32 optional_sint32_extension_lite = 5; + optional sint64 optional_sint64_extension_lite = 6; + optional fixed32 optional_fixed32_extension_lite = 7; + optional fixed64 optional_fixed64_extension_lite = 8; + optional sfixed32 optional_sfixed32_extension_lite = 9; + optional sfixed64 optional_sfixed64_extension_lite = 10; + optional float optional_float_extension_lite = 11; + optional double optional_double_extension_lite = 12; + optional bool optional_bool_extension_lite = 13; + optional string optional_string_extension_lite = 14; + optional bytes optional_bytes_extension_lite = 15; + + optional group OptionalGroup_extension_lite = 16 { + optional int32 a = 17; + } + + optional TestAllTypesLite.NestedMessage optional_nested_message_extension_lite + = 18; + optional ForeignMessageLite optional_foreign_message_extension_lite = 19; + optional protobuf_unittest_import.ImportMessageLite + optional_import_message_extension_lite = 20; + + optional TestAllTypesLite.NestedEnum optional_nested_enum_extension_lite = 21; + optional ForeignEnumLite optional_foreign_enum_extension_lite = 22; + optional protobuf_unittest_import.ImportEnumLite + optional_import_enum_extension_lite = 23; + + optional string optional_string_piece_extension_lite = 24 + [ctype=STRING_PIECE]; + optional string optional_cord_extension_lite = 25 [ctype=CORD]; + + optional protobuf_unittest_import.PublicImportMessageLite + optional_public_import_message_extension_lite = 26; + + optional TestAllTypesLite.NestedMessage + optional_lazy_message_extension_lite = 27 [lazy=true]; + + // Repeated + repeated int32 repeated_int32_extension_lite = 31; + repeated int64 repeated_int64_extension_lite = 32; + repeated uint32 repeated_uint32_extension_lite = 33; + repeated uint64 repeated_uint64_extension_lite = 34; + repeated sint32 repeated_sint32_extension_lite = 35; + repeated sint64 repeated_sint64_extension_lite = 36; + repeated fixed32 repeated_fixed32_extension_lite = 37; + repeated fixed64 repeated_fixed64_extension_lite = 38; + repeated sfixed32 repeated_sfixed32_extension_lite = 39; + repeated sfixed64 repeated_sfixed64_extension_lite = 40; + repeated float repeated_float_extension_lite = 41; + repeated double repeated_double_extension_lite = 42; + repeated bool repeated_bool_extension_lite = 43; + repeated string repeated_string_extension_lite = 44; + repeated bytes repeated_bytes_extension_lite = 45; + + repeated group RepeatedGroup_extension_lite = 46 { + optional int32 a = 47; + } + + repeated TestAllTypesLite.NestedMessage repeated_nested_message_extension_lite + = 48; + repeated ForeignMessageLite repeated_foreign_message_extension_lite = 49; + repeated protobuf_unittest_import.ImportMessageLite + repeated_import_message_extension_lite = 50; + + repeated TestAllTypesLite.NestedEnum repeated_nested_enum_extension_lite = 51; + repeated ForeignEnumLite repeated_foreign_enum_extension_lite = 52; + repeated protobuf_unittest_import.ImportEnumLite + repeated_import_enum_extension_lite = 53; + + repeated string repeated_string_piece_extension_lite = 54 + [ctype=STRING_PIECE]; + repeated string repeated_cord_extension_lite = 55 [ctype=CORD]; + + repeated TestAllTypesLite.NestedMessage + repeated_lazy_message_extension_lite = 57 [lazy=true]; + + // Singular with defaults + optional int32 default_int32_extension_lite = 61 [default = 41 ]; + optional int64 default_int64_extension_lite = 62 [default = 42 ]; + optional uint32 default_uint32_extension_lite = 63 [default = 43 ]; + optional uint64 default_uint64_extension_lite = 64 [default = 44 ]; + optional sint32 default_sint32_extension_lite = 65 [default = -45 ]; + optional sint64 default_sint64_extension_lite = 66 [default = 46 ]; + optional fixed32 default_fixed32_extension_lite = 67 [default = 47 ]; + optional fixed64 default_fixed64_extension_lite = 68 [default = 48 ]; + optional sfixed32 default_sfixed32_extension_lite = 69 [default = 49 ]; + optional sfixed64 default_sfixed64_extension_lite = 70 [default = -50 ]; + optional float default_float_extension_lite = 71 [default = 51.5 ]; + optional double default_double_extension_lite = 72 [default = 52e3 ]; + optional bool default_bool_extension_lite = 73 [default = true ]; + optional string default_string_extension_lite = 74 [default = "hello"]; + optional bytes default_bytes_extension_lite = 75 [default = "world"]; + + optional TestAllTypesLite.NestedEnum + default_nested_enum_extension_lite = 81 [default = BAR]; + optional ForeignEnumLite + default_foreign_enum_extension_lite = 82 [default = FOREIGN_LITE_BAR]; + optional protobuf_unittest_import.ImportEnumLite + default_import_enum_extension_lite = 83 [default = IMPORT_LITE_BAR]; + + optional string default_string_piece_extension_lite = 84 [ctype=STRING_PIECE, + default="abc"]; + optional string default_cord_extension_lite = 85 [ctype=CORD, default="123"]; +} + +message TestPackedExtensionsLite { + extensions 1 to max; +} + +extend TestPackedExtensionsLite { + repeated int32 packed_int32_extension_lite = 90 [packed = true]; + repeated int64 packed_int64_extension_lite = 91 [packed = true]; + repeated uint32 packed_uint32_extension_lite = 92 [packed = true]; + repeated uint64 packed_uint64_extension_lite = 93 [packed = true]; + repeated sint32 packed_sint32_extension_lite = 94 [packed = true]; + repeated sint64 packed_sint64_extension_lite = 95 [packed = true]; + repeated fixed32 packed_fixed32_extension_lite = 96 [packed = true]; + repeated fixed64 packed_fixed64_extension_lite = 97 [packed = true]; + repeated sfixed32 packed_sfixed32_extension_lite = 98 [packed = true]; + repeated sfixed64 packed_sfixed64_extension_lite = 99 [packed = true]; + repeated float packed_float_extension_lite = 100 [packed = true]; + repeated double packed_double_extension_lite = 101 [packed = true]; + repeated bool packed_bool_extension_lite = 102 [packed = true]; + repeated ForeignEnumLite packed_enum_extension_lite = 103 [packed = true]; +} + +message TestNestedExtensionLite { + extend TestAllExtensionsLite { + optional int32 nested_extension = 12345; + } +} + +// Test that deprecated fields work. We only verify that they compile (at one +// point this failed). +message TestDeprecatedLite { + optional int32 deprecated_field = 1 [deprecated = true]; +} + +// See the comments of the same type in unittest.proto. +message TestParsingMergeLite { + message RepeatedFieldsGenerator { + repeated TestAllTypesLite field1 = 1; + repeated TestAllTypesLite field2 = 2; + repeated TestAllTypesLite field3 = 3; + repeated group Group1 = 10 { + optional TestAllTypesLite field1 = 11; + } + repeated group Group2 = 20 { + optional TestAllTypesLite field1 = 21; + } + repeated TestAllTypesLite ext1 = 1000; + repeated TestAllTypesLite ext2 = 1001; + } + required TestAllTypesLite required_all_types = 1; + optional TestAllTypesLite optional_all_types = 2; + repeated TestAllTypesLite repeated_all_types = 3; + optional group OptionalGroup = 10 { + optional TestAllTypesLite optional_group_all_types = 11; + } + repeated group RepeatedGroup = 20 { + optional TestAllTypesLite repeated_group_all_types = 21; + } + extensions 1000 to max; + extend TestParsingMergeLite { + optional TestAllTypesLite optional_ext = 1000; + repeated TestAllTypesLite repeated_ext = 1001; + } +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_lite_imports_nonlite.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_lite_imports_nonlite.proto new file mode 100644 index 0000000..d52cb8c --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_lite_imports_nonlite.proto @@ -0,0 +1,43 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// Tests that a "lite" message can import a regular message. + +package protobuf_unittest; + +import "google/protobuf/unittest.proto"; + +option optimize_for = LITE_RUNTIME; + +message TestLiteImportsNonlite { + optional TestAllTypes message = 1; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_mset.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_mset.proto new file mode 100644 index 0000000..3497f09 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_mset.proto @@ -0,0 +1,72 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains messages for testing message_set_wire_format. + +package protobuf_unittest; + +option optimize_for = SPEED; + +// A message with message_set_wire_format. +message TestMessageSet { + option message_set_wire_format = true; + extensions 4 to max; +} + +message TestMessageSetContainer { + optional TestMessageSet message_set = 1; +} + +message TestMessageSetExtension1 { + extend TestMessageSet { + optional TestMessageSetExtension1 message_set_extension = 1545008; + } + optional int32 i = 15; +} + +message TestMessageSetExtension2 { + extend TestMessageSet { + optional TestMessageSetExtension2 message_set_extension = 1547769; + } + optional string str = 25; +} + +// MessageSet wire format is equivalent to this. +message RawMessageSet { + repeated group Item = 1 { + required int32 type_id = 2; + required bytes message = 3; + } +} + diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_no_generic_services.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_no_generic_services.proto new file mode 100644 index 0000000..cffb412 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_no_generic_services.proto @@ -0,0 +1,52 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +package google.protobuf.no_generic_services_test; + +// *_generic_services are false by default. + +message TestMessage { + optional int32 a = 1; + extensions 1000 to max; +} + +enum TestEnum { + FOO = 1; +} + +extend TestMessage { + optional int32 test_extension = 1000; +} + +service TestService { + rpc Foo(TestMessage) returns(TestMessage); +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_optimize_for.proto b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_optimize_for.proto new file mode 100644 index 0000000..feecbef --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unittest_optimize_for.proto @@ -0,0 +1,61 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// A proto file which uses optimize_for = CODE_SIZE. + +import "google/protobuf/unittest.proto"; + +package protobuf_unittest; + +option optimize_for = CODE_SIZE; + +message TestOptimizedForSize { + optional int32 i = 1; + optional ForeignMessage msg = 19; + + extensions 1000 to max; + + extend TestOptimizedForSize { + optional int32 test_extension = 1234; + optional TestRequiredOptimizedForSize test_extension2 = 1235; + } +} + +message TestRequiredOptimizedForSize { + required int32 x = 1; +} + +message TestOptionalOptimizedForSize { + optional TestRequiredOptimizedForSize o = 1; +} diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set.cc new file mode 100644 index 0000000..841433d --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set.cc @@ -0,0 +1,266 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +UnknownFieldSet::UnknownFieldSet() + : fields_(NULL) {} + +UnknownFieldSet::~UnknownFieldSet() { + Clear(); + delete fields_; +} + +void UnknownFieldSet::ClearFallback() { + GOOGLE_DCHECK(fields_ != NULL); + for (int i = 0; i < fields_->size(); i++) { + (*fields_)[i].Delete(); + } + fields_->clear(); +} + +void UnknownFieldSet::ClearAndFreeMemory() { + if (fields_ != NULL) { + Clear(); + delete fields_; + fields_ = NULL; + } +} + +void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) { + for (int i = 0; i < other.field_count(); i++) { + AddField(other.field(i)); + } +} + +int UnknownFieldSet::SpaceUsedExcludingSelf() const { + if (fields_ == NULL) return 0; + + int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size(); + for (int i = 0; i < fields_->size(); i++) { + const UnknownField& field = (*fields_)[i]; + switch (field.type()) { + case UnknownField::TYPE_LENGTH_DELIMITED: + total_size += sizeof(*field.length_delimited_.string_value_) + + internal::StringSpaceUsedExcludingSelf( + *field.length_delimited_.string_value_); + break; + case UnknownField::TYPE_GROUP: + total_size += field.group_->SpaceUsed(); + break; + default: + break; + } + } + return total_size; +} + +int UnknownFieldSet::SpaceUsed() const { + return sizeof(*this) + SpaceUsedExcludingSelf(); +} + +void UnknownFieldSet::AddVarint(int number, uint64 value) { + if (fields_ == NULL) fields_ = new vector; + UnknownField field; + field.number_ = number; + field.type_ = UnknownField::TYPE_VARINT; + field.varint_ = value; + fields_->push_back(field); +} + +void UnknownFieldSet::AddFixed32(int number, uint32 value) { + if (fields_ == NULL) fields_ = new vector; + UnknownField field; + field.number_ = number; + field.type_ = UnknownField::TYPE_FIXED32; + field.fixed32_ = value; + fields_->push_back(field); +} + +void UnknownFieldSet::AddFixed64(int number, uint64 value) { + if (fields_ == NULL) fields_ = new vector; + UnknownField field; + field.number_ = number; + field.type_ = UnknownField::TYPE_FIXED64; + field.fixed64_ = value; + fields_->push_back(field); +} + +string* UnknownFieldSet::AddLengthDelimited(int number) { + if (fields_ == NULL) fields_ = new vector; + UnknownField field; + field.number_ = number; + field.type_ = UnknownField::TYPE_LENGTH_DELIMITED; + field.length_delimited_.string_value_ = new string; + fields_->push_back(field); + return field.length_delimited_.string_value_; +} + + +UnknownFieldSet* UnknownFieldSet::AddGroup(int number) { + if (fields_ == NULL) fields_ = new vector; + UnknownField field; + field.number_ = number; + field.type_ = UnknownField::TYPE_GROUP; + field.group_ = new UnknownFieldSet; + fields_->push_back(field); + return field.group_; +} + +void UnknownFieldSet::AddField(const UnknownField& field) { + if (fields_ == NULL) fields_ = new vector; + fields_->push_back(field); + fields_->back().DeepCopy(); +} + +void UnknownFieldSet::DeleteSubrange(int start, int num) { + GOOGLE_DCHECK(fields_ != NULL); + // Delete the specified fields. + for (int i = 0; i < num; ++i) { + (*fields_)[i + start].Delete(); + } + // Slide down the remaining fields. + for (int i = start + num; i < fields_->size(); ++i) { + (*fields_)[i - num] = (*fields_)[i]; + } + // Pop off the # of deleted fields. + for (int i = 0; i < num; ++i) { + fields_->pop_back(); + } +} + +void UnknownFieldSet::DeleteByNumber(int number) { + if (fields_ == NULL) return; + int left = 0; // The number of fields left after deletion. + for (int i = 0; i < fields_->size(); ++i) { + UnknownField* field = &(*fields_)[i]; + if (field->number() == number) { + field->Delete(); + } else { + if (i != left) { + (*fields_)[left] = (*fields_)[i]; + } + ++left; + } + } + fields_->resize(left); +} + +bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) { + + UnknownFieldSet other; + if (internal::WireFormat::SkipMessage(input, &other) && + input->ConsumedEntireMessage()) { + MergeFrom(other); + return true; + } else { + return false; + } +} + +bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) { + Clear(); + return MergeFromCodedStream(input); +} + +bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { + io::CodedInputStream coded_input(input); + return ParseFromCodedStream(&coded_input) && + coded_input.ConsumedEntireMessage(); +} + +bool UnknownFieldSet::ParseFromArray(const void* data, int size) { + io::ArrayInputStream input(data, size); + return ParseFromZeroCopyStream(&input); +} + +void UnknownField::Delete() { + switch (type()) { + case UnknownField::TYPE_LENGTH_DELIMITED: + delete length_delimited_.string_value_; + break; + case UnknownField::TYPE_GROUP: + delete group_; + break; + default: + break; + } +} + +void UnknownField::DeepCopy() { + switch (type()) { + case UnknownField::TYPE_LENGTH_DELIMITED: + length_delimited_.string_value_ = new string( + *length_delimited_.string_value_); + break; + case UnknownField::TYPE_GROUP: { + UnknownFieldSet* group = new UnknownFieldSet; + group->MergeFrom(*group_); + group_ = group; + break; + } + default: + break; + } +} + + +void UnknownField::SerializeLengthDelimitedNoTag( + io::CodedOutputStream* output) const { + GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type_); + const string& data = *length_delimited_.string_value_; + output->WriteVarint32(data.size()); + output->WriteString(data); +} + +uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const { + GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type_); + const string& data = *length_delimited_.string_value_; + target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target); + target = io::CodedOutputStream::WriteStringToArray(data, target); + return target; +} + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set.h new file mode 100644 index 0000000..825bba8 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set.h @@ -0,0 +1,311 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Contains classes used to keep track of unrecognized fields seen while +// parsing a protocol message. + +#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ +#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ + +#include +#include +#include +#include +// TODO(jasonh): some people seem to rely on protobufs to include this for them! + +namespace google { +namespace protobuf { + namespace io { + class CodedInputStream; // coded_stream.h + class CodedOutputStream; // coded_stream.h + class ZeroCopyInputStream; // zero_copy_stream.h + } + namespace internal { + class WireFormat; // wire_format.h + class UnknownFieldSetFieldSkipperUsingCord; + // extension_set_heavy.cc + } + +class Message; // message.h +class UnknownField; // below + +// An UnknownFieldSet contains fields that were encountered while parsing a +// message but were not defined by its type. Keeping track of these can be +// useful, especially in that they may be written if the message is serialized +// again without being cleared in between. This means that software which +// simply receives messages and forwards them to other servers does not need +// to be updated every time a new field is added to the message definition. +// +// To get the UnknownFieldSet attached to any message, call +// Reflection::GetUnknownFields(). +// +// This class is necessarily tied to the protocol buffer wire format, unlike +// the Reflection interface which is independent of any serialization scheme. +class LIBPROTOBUF_EXPORT UnknownFieldSet { + public: + UnknownFieldSet(); + ~UnknownFieldSet(); + + // Remove all fields. + inline void Clear(); + + // Remove all fields and deallocate internal data objects + void ClearAndFreeMemory(); + + // Is this set empty? + inline bool empty() const; + + // Merge the contents of some other UnknownFieldSet with this one. + void MergeFrom(const UnknownFieldSet& other); + + // Swaps the contents of some other UnknownFieldSet with this one. + inline void Swap(UnknownFieldSet* x); + + // Computes (an estimate of) the total number of bytes currently used for + // storing the unknown fields in memory. Does NOT include + // sizeof(*this) in the calculation. + int SpaceUsedExcludingSelf() const; + + // Version of SpaceUsed() including sizeof(*this). + int SpaceUsed() const; + + // Returns the number of fields present in the UnknownFieldSet. + inline int field_count() const; + // Get a field in the set, where 0 <= index < field_count(). The fields + // appear in the order in which they were added. + inline const UnknownField& field(int index) const; + // Get a mutable pointer to a field in the set, where + // 0 <= index < field_count(). The fields appear in the order in which + // they were added. + inline UnknownField* mutable_field(int index); + + // Adding fields --------------------------------------------------- + + void AddVarint(int number, uint64 value); + void AddFixed32(int number, uint32 value); + void AddFixed64(int number, uint64 value); + void AddLengthDelimited(int number, const string& value); + string* AddLengthDelimited(int number); + UnknownFieldSet* AddGroup(int number); + + // Adds an unknown field from another set. + void AddField(const UnknownField& field); + + // Delete fields with indices in the range [start .. start+num-1]. + // Caution: implementation moves all fields with indices [start+num .. ]. + void DeleteSubrange(int start, int num); + + // Delete all fields with a specific field number. The order of left fields + // is preserved. + // Caution: implementation moves all fields after the first deleted field. + void DeleteByNumber(int number); + + // Parsing helpers ------------------------------------------------- + // These work exactly like the similarly-named methods of Message. + + bool MergeFromCodedStream(io::CodedInputStream* input); + bool ParseFromCodedStream(io::CodedInputStream* input); + bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); + bool ParseFromArray(const void* data, int size); + inline bool ParseFromString(const string& data) { + return ParseFromArray(data.data(), data.size()); + } + + private: + + void ClearFallback(); + + vector* fields_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet); +}; + +// Represents one field in an UnknownFieldSet. +class LIBPROTOBUF_EXPORT UnknownField { + public: + enum Type { + TYPE_VARINT, + TYPE_FIXED32, + TYPE_FIXED64, + TYPE_LENGTH_DELIMITED, + TYPE_GROUP + }; + + // The field's tag number, as seen on the wire. + inline int number() const; + + // The field type. + inline Type type() const; + + // Accessors ------------------------------------------------------- + // Each method works only for UnknownFields of the corresponding type. + + inline uint64 varint() const; + inline uint32 fixed32() const; + inline uint64 fixed64() const; + inline const string& length_delimited() const; + inline const UnknownFieldSet& group() const; + + inline void set_varint(uint64 value); + inline void set_fixed32(uint32 value); + inline void set_fixed64(uint64 value); + inline void set_length_delimited(const string& value); + inline string* mutable_length_delimited(); + inline UnknownFieldSet* mutable_group(); + + // Serialization API. + // These methods can take advantage of the underlying implementation and may + // archieve a better performance than using getters to retrieve the data and + // do the serialization yourself. + void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const; + uint8* SerializeLengthDelimitedNoTagToArray(uint8* target) const; + + inline int GetLengthDelimitedSize() const; + + private: + friend class UnknownFieldSet; + + // If this UnknownField contains a pointer, delete it. + void Delete(); + + // Make a deep copy of any pointers in this UnknownField. + void DeepCopy(); + + + unsigned int number_ : 29; + unsigned int type_ : 3; + union { + uint64 varint_; + uint32 fixed32_; + uint64 fixed64_; + mutable union { + string* string_value_; + } length_delimited_; + UnknownFieldSet* group_; + }; +}; + +// =================================================================== +// inline implementations + +inline void UnknownFieldSet::Clear() { + if (fields_ != NULL) { + ClearFallback(); + } +} + +inline bool UnknownFieldSet::empty() const { + return fields_ == NULL || fields_->empty(); +} + +inline void UnknownFieldSet::Swap(UnknownFieldSet* x) { + std::swap(fields_, x->fields_); +} + +inline int UnknownFieldSet::field_count() const { + return (fields_ == NULL) ? 0 : fields_->size(); +} +inline const UnknownField& UnknownFieldSet::field(int index) const { + return (*fields_)[index]; +} +inline UnknownField* UnknownFieldSet::mutable_field(int index) { + return &(*fields_)[index]; +} + +inline void UnknownFieldSet::AddLengthDelimited( + int number, const string& value) { + AddLengthDelimited(number)->assign(value); +} + + +inline int UnknownField::number() const { return number_; } +inline UnknownField::Type UnknownField::type() const { + return static_cast(type_); +} + +inline uint64 UnknownField::varint () const { + assert(type_ == TYPE_VARINT); + return varint_; +} +inline uint32 UnknownField::fixed32() const { + assert(type_ == TYPE_FIXED32); + return fixed32_; +} +inline uint64 UnknownField::fixed64() const { + assert(type_ == TYPE_FIXED64); + return fixed64_; +} +inline const string& UnknownField::length_delimited() const { + assert(type_ == TYPE_LENGTH_DELIMITED); + return *length_delimited_.string_value_; +} +inline const UnknownFieldSet& UnknownField::group() const { + assert(type_ == TYPE_GROUP); + return *group_; +} + +inline void UnknownField::set_varint(uint64 value) { + assert(type_ == TYPE_VARINT); + varint_ = value; +} +inline void UnknownField::set_fixed32(uint32 value) { + assert(type_ == TYPE_FIXED32); + fixed32_ = value; +} +inline void UnknownField::set_fixed64(uint64 value) { + assert(type_ == TYPE_FIXED64); + fixed64_ = value; +} +inline void UnknownField::set_length_delimited(const string& value) { + assert(type_ == TYPE_LENGTH_DELIMITED); + length_delimited_.string_value_->assign(value); +} +inline string* UnknownField::mutable_length_delimited() { + assert(type_ == TYPE_LENGTH_DELIMITED); + return length_delimited_.string_value_; +} +inline UnknownFieldSet* UnknownField::mutable_group() { + assert(type_ == TYPE_GROUP); + return group_; +} + +inline int UnknownField::GetLengthDelimitedSize() const { + GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type_); + return length_delimited_.string_value_->size(); +} + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set_unittest.cc new file mode 100644 index 0000000..c6b8769 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/unknown_field_set_unittest.cc @@ -0,0 +1,594 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This test is testing a lot more than just the UnknownFieldSet class. It +// tests handling of unknown fields throughout the system. + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +using internal::WireFormat; + +class UnknownFieldSetTest : public testing::Test { + protected: + virtual void SetUp() { + descriptor_ = unittest::TestAllTypes::descriptor(); + TestUtil::SetAllFields(&all_fields_); + all_fields_.SerializeToString(&all_fields_data_); + ASSERT_TRUE(empty_message_.ParseFromString(all_fields_data_)); + unknown_fields_ = empty_message_.mutable_unknown_fields(); + } + + const UnknownField* GetField(const string& name) { + const FieldDescriptor* field = descriptor_->FindFieldByName(name); + if (field == NULL) return NULL; + for (int i = 0; i < unknown_fields_->field_count(); i++) { + if (unknown_fields_->field(i).number() == field->number()) { + return &unknown_fields_->field(i); + } + } + return NULL; + } + + // Constructs a protocol buffer which contains fields with all the same + // numbers as all_fields_data_ except that each field is some other wire + // type. + string GetBizarroData() { + unittest::TestEmptyMessage bizarro_message; + UnknownFieldSet* bizarro_unknown_fields = + bizarro_message.mutable_unknown_fields(); + for (int i = 0; i < unknown_fields_->field_count(); i++) { + const UnknownField& unknown_field = unknown_fields_->field(i); + if (unknown_field.type() == UnknownField::TYPE_VARINT) { + bizarro_unknown_fields->AddFixed32(unknown_field.number(), 1); + } else { + bizarro_unknown_fields->AddVarint(unknown_field.number(), 1); + } + } + + string data; + EXPECT_TRUE(bizarro_message.SerializeToString(&data)); + return data; + } + + const Descriptor* descriptor_; + unittest::TestAllTypes all_fields_; + string all_fields_data_; + + // An empty message that has been parsed from all_fields_data_. So, it has + // unknown fields of every type. + unittest::TestEmptyMessage empty_message_; + UnknownFieldSet* unknown_fields_; +}; + +namespace { + +TEST_F(UnknownFieldSetTest, AllFieldsPresent) { + // All fields of TestAllTypes should be present, in numeric order (because + // that's the order we parsed them in). Fields that are not valid field + // numbers of TestAllTypes should NOT be present. + + int pos = 0; + + for (int i = 0; i < 1000; i++) { + const FieldDescriptor* field = descriptor_->FindFieldByNumber(i); + if (field != NULL) { + ASSERT_LT(pos, unknown_fields_->field_count()); + EXPECT_EQ(i, unknown_fields_->field(pos++).number()); + if (field->is_repeated()) { + // Should have a second instance. + ASSERT_LT(pos, unknown_fields_->field_count()); + EXPECT_EQ(i, unknown_fields_->field(pos++).number()); + } + } + } + EXPECT_EQ(unknown_fields_->field_count(), pos); +} + +TEST_F(UnknownFieldSetTest, Varint) { + const UnknownField* field = GetField("optional_int32"); + ASSERT_TRUE(field != NULL); + + ASSERT_EQ(UnknownField::TYPE_VARINT, field->type()); + EXPECT_EQ(all_fields_.optional_int32(), field->varint()); +} + +TEST_F(UnknownFieldSetTest, Fixed32) { + const UnknownField* field = GetField("optional_fixed32"); + ASSERT_TRUE(field != NULL); + + ASSERT_EQ(UnknownField::TYPE_FIXED32, field->type()); + EXPECT_EQ(all_fields_.optional_fixed32(), field->fixed32()); +} + +TEST_F(UnknownFieldSetTest, Fixed64) { + const UnknownField* field = GetField("optional_fixed64"); + ASSERT_TRUE(field != NULL); + + ASSERT_EQ(UnknownField::TYPE_FIXED64, field->type()); + EXPECT_EQ(all_fields_.optional_fixed64(), field->fixed64()); +} + +TEST_F(UnknownFieldSetTest, LengthDelimited) { + const UnknownField* field = GetField("optional_string"); + ASSERT_TRUE(field != NULL); + + ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED, field->type()); + EXPECT_EQ(all_fields_.optional_string(), field->length_delimited()); +} + +TEST_F(UnknownFieldSetTest, Group) { + const UnknownField* field = GetField("optionalgroup"); + ASSERT_TRUE(field != NULL); + + ASSERT_EQ(UnknownField::TYPE_GROUP, field->type()); + ASSERT_EQ(1, field->group().field_count()); + + const UnknownField& nested_field = field->group().field(0); + const FieldDescriptor* nested_field_descriptor = + unittest::TestAllTypes::OptionalGroup::descriptor()->FindFieldByName("a"); + ASSERT_TRUE(nested_field_descriptor != NULL); + + EXPECT_EQ(nested_field_descriptor->number(), nested_field.number()); + ASSERT_EQ(UnknownField::TYPE_VARINT, nested_field.type()); + EXPECT_EQ(all_fields_.optionalgroup().a(), nested_field.varint()); +} + +TEST_F(UnknownFieldSetTest, SerializeFastAndSlowAreEquivalent) { + int size = WireFormat::ComputeUnknownFieldsSize( + empty_message_.unknown_fields()); + string slow_buffer; + string fast_buffer; + slow_buffer.resize(size); + fast_buffer.resize(size); + + uint8* target = reinterpret_cast(string_as_array(&fast_buffer)); + uint8* result = WireFormat::SerializeUnknownFieldsToArray( + empty_message_.unknown_fields(), target); + EXPECT_EQ(size, result - target); + + { + io::ArrayOutputStream raw_stream(string_as_array(&slow_buffer), size, 1); + io::CodedOutputStream output_stream(&raw_stream); + WireFormat::SerializeUnknownFields(empty_message_.unknown_fields(), + &output_stream); + ASSERT_FALSE(output_stream.HadError()); + } + EXPECT_TRUE(fast_buffer == slow_buffer); +} + +TEST_F(UnknownFieldSetTest, Serialize) { + // Check that serializing the UnknownFieldSet produces the original data + // again. + + string data; + empty_message_.SerializeToString(&data); + + // Don't use EXPECT_EQ because we don't want to dump raw binary data to + // stdout. + EXPECT_TRUE(data == all_fields_data_); +} + +TEST_F(UnknownFieldSetTest, ParseViaReflection) { + // Make sure fields are properly parsed to the UnknownFieldSet when parsing + // via reflection. + + unittest::TestEmptyMessage message; + io::ArrayInputStream raw_input(all_fields_data_.data(), + all_fields_data_.size()); + io::CodedInputStream input(&raw_input); + ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message)); + + EXPECT_EQ(message.DebugString(), empty_message_.DebugString()); +} + +TEST_F(UnknownFieldSetTest, SerializeViaReflection) { + // Make sure fields are properly written from the UnknownFieldSet when + // serializing via reflection. + + string data; + + { + io::StringOutputStream raw_output(&data); + io::CodedOutputStream output(&raw_output); + int size = WireFormat::ByteSize(empty_message_); + WireFormat::SerializeWithCachedSizes(empty_message_, size, &output); + ASSERT_FALSE(output.HadError()); + } + + // Don't use EXPECT_EQ because we don't want to dump raw binary data to + // stdout. + EXPECT_TRUE(data == all_fields_data_); +} + +TEST_F(UnknownFieldSetTest, CopyFrom) { + unittest::TestEmptyMessage message; + + message.CopyFrom(empty_message_); + + EXPECT_EQ(empty_message_.DebugString(), message.DebugString()); +} + +TEST_F(UnknownFieldSetTest, Swap) { + unittest::TestEmptyMessage other_message; + ASSERT_TRUE(other_message.ParseFromString(GetBizarroData())); + + EXPECT_GT(empty_message_.unknown_fields().field_count(), 0); + EXPECT_GT(other_message.unknown_fields().field_count(), 0); + const string debug_string = empty_message_.DebugString(); + const string other_debug_string = other_message.DebugString(); + EXPECT_NE(debug_string, other_debug_string); + + empty_message_.Swap(&other_message); + EXPECT_EQ(debug_string, other_message.DebugString()); + EXPECT_EQ(other_debug_string, empty_message_.DebugString()); +} + +TEST_F(UnknownFieldSetTest, SwapWithSelf) { + const string debug_string = empty_message_.DebugString(); + EXPECT_GT(empty_message_.unknown_fields().field_count(), 0); + + empty_message_.Swap(&empty_message_); + EXPECT_GT(empty_message_.unknown_fields().field_count(), 0); + EXPECT_EQ(debug_string, empty_message_.DebugString()); +} + +TEST_F(UnknownFieldSetTest, MergeFrom) { + unittest::TestEmptyMessage source, destination; + + destination.mutable_unknown_fields()->AddVarint(1, 1); + destination.mutable_unknown_fields()->AddVarint(3, 2); + source.mutable_unknown_fields()->AddVarint(2, 3); + source.mutable_unknown_fields()->AddVarint(3, 4); + + destination.MergeFrom(source); + + EXPECT_EQ( + // Note: The ordering of fields here depends on the ordering of adds + // and merging, above. + "1: 1\n" + "3: 2\n" + "2: 3\n" + "3: 4\n", + destination.DebugString()); +} + + +TEST_F(UnknownFieldSetTest, Clear) { + // Clear the set. + empty_message_.Clear(); + EXPECT_EQ(0, unknown_fields_->field_count()); +} + +TEST_F(UnknownFieldSetTest, ClearAndFreeMemory) { + EXPECT_GT(unknown_fields_->field_count(), 0); + unknown_fields_->ClearAndFreeMemory(); + EXPECT_EQ(0, unknown_fields_->field_count()); + unknown_fields_->AddVarint(123456, 654321); + EXPECT_EQ(1, unknown_fields_->field_count()); +} + +TEST_F(UnknownFieldSetTest, ParseKnownAndUnknown) { + // Test mixing known and unknown fields when parsing. + + unittest::TestEmptyMessage source; + source.mutable_unknown_fields()->AddVarint(123456, 654321); + string data; + ASSERT_TRUE(source.SerializeToString(&data)); + + unittest::TestAllTypes destination; + ASSERT_TRUE(destination.ParseFromString(all_fields_data_ + data)); + + TestUtil::ExpectAllFieldsSet(destination); + ASSERT_EQ(1, destination.unknown_fields().field_count()); + ASSERT_EQ(UnknownField::TYPE_VARINT, + destination.unknown_fields().field(0).type()); + EXPECT_EQ(654321, destination.unknown_fields().field(0).varint()); +} + +TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknown) { + // Test that fields of the wrong wire type are treated like unknown fields + // when parsing. + + unittest::TestAllTypes all_types_message; + unittest::TestEmptyMessage empty_message; + string bizarro_data = GetBizarroData(); + ASSERT_TRUE(all_types_message.ParseFromString(bizarro_data)); + ASSERT_TRUE(empty_message.ParseFromString(bizarro_data)); + + // All fields should have been interpreted as unknown, so the debug strings + // should be the same. + EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString()); +} + +TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknownViaReflection) { + // Same as WrongTypeTreatedAsUnknown but via the reflection interface. + + unittest::TestAllTypes all_types_message; + unittest::TestEmptyMessage empty_message; + string bizarro_data = GetBizarroData(); + io::ArrayInputStream raw_input(bizarro_data.data(), bizarro_data.size()); + io::CodedInputStream input(&raw_input); + ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &all_types_message)); + ASSERT_TRUE(empty_message.ParseFromString(bizarro_data)); + + EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString()); +} + +TEST_F(UnknownFieldSetTest, UnknownExtensions) { + // Make sure fields are properly parsed to the UnknownFieldSet even when + // they are declared as extension numbers. + + unittest::TestEmptyMessageWithExtensions message; + ASSERT_TRUE(message.ParseFromString(all_fields_data_)); + + EXPECT_EQ(message.DebugString(), empty_message_.DebugString()); +} + +TEST_F(UnknownFieldSetTest, UnknownExtensionsReflection) { + // Same as UnknownExtensions except parsing via reflection. + + unittest::TestEmptyMessageWithExtensions message; + io::ArrayInputStream raw_input(all_fields_data_.data(), + all_fields_data_.size()); + io::CodedInputStream input(&raw_input); + ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message)); + + EXPECT_EQ(message.DebugString(), empty_message_.DebugString()); +} + +TEST_F(UnknownFieldSetTest, WrongExtensionTypeTreatedAsUnknown) { + // Test that fields of the wrong wire type are treated like unknown fields + // when parsing extensions. + + unittest::TestAllExtensions all_extensions_message; + unittest::TestEmptyMessage empty_message; + string bizarro_data = GetBizarroData(); + ASSERT_TRUE(all_extensions_message.ParseFromString(bizarro_data)); + ASSERT_TRUE(empty_message.ParseFromString(bizarro_data)); + + // All fields should have been interpreted as unknown, so the debug strings + // should be the same. + EXPECT_EQ(empty_message.DebugString(), all_extensions_message.DebugString()); +} + +TEST_F(UnknownFieldSetTest, UnknownEnumValue) { + using unittest::TestAllTypes; + using unittest::TestAllExtensions; + using unittest::TestEmptyMessage; + + const FieldDescriptor* singular_field = + TestAllTypes::descriptor()->FindFieldByName("optional_nested_enum"); + const FieldDescriptor* repeated_field = + TestAllTypes::descriptor()->FindFieldByName("repeated_nested_enum"); + ASSERT_TRUE(singular_field != NULL); + ASSERT_TRUE(repeated_field != NULL); + + string data; + + { + TestEmptyMessage empty_message; + UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields(); + unknown_fields->AddVarint(singular_field->number(), TestAllTypes::BAR); + unknown_fields->AddVarint(singular_field->number(), 5); // not valid + unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::FOO); + unknown_fields->AddVarint(repeated_field->number(), 4); // not valid + unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::BAZ); + unknown_fields->AddVarint(repeated_field->number(), 6); // not valid + empty_message.SerializeToString(&data); + } + + { + TestAllTypes message; + ASSERT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(TestAllTypes::BAR, message.optional_nested_enum()); + ASSERT_EQ(2, message.repeated_nested_enum_size()); + EXPECT_EQ(TestAllTypes::FOO, message.repeated_nested_enum(0)); + EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(1)); + + const UnknownFieldSet& unknown_fields = message.unknown_fields(); + ASSERT_EQ(3, unknown_fields.field_count()); + + EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number()); + ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type()); + EXPECT_EQ(5, unknown_fields.field(0).varint()); + + EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number()); + ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type()); + EXPECT_EQ(4, unknown_fields.field(1).varint()); + + EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number()); + ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type()); + EXPECT_EQ(6, unknown_fields.field(2).varint()); + } + + { + using unittest::optional_nested_enum_extension; + using unittest::repeated_nested_enum_extension; + + TestAllExtensions message; + ASSERT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(TestAllTypes::BAR, + message.GetExtension(optional_nested_enum_extension)); + ASSERT_EQ(2, message.ExtensionSize(repeated_nested_enum_extension)); + EXPECT_EQ(TestAllTypes::FOO, + message.GetExtension(repeated_nested_enum_extension, 0)); + EXPECT_EQ(TestAllTypes::BAZ, + message.GetExtension(repeated_nested_enum_extension, 1)); + + const UnknownFieldSet& unknown_fields = message.unknown_fields(); + ASSERT_EQ(3, unknown_fields.field_count()); + + EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number()); + ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type()); + EXPECT_EQ(5, unknown_fields.field(0).varint()); + + EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number()); + ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type()); + EXPECT_EQ(4, unknown_fields.field(1).varint()); + + EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number()); + ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type()); + EXPECT_EQ(6, unknown_fields.field(2).varint()); + } +} + +TEST_F(UnknownFieldSetTest, SpaceUsed) { + unittest::TestEmptyMessage empty_message; + + // Make sure an unknown field set has zero space used until a field is + // actually added. + int base_size = empty_message.SpaceUsed(); + UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields(); + EXPECT_EQ(base_size, empty_message.SpaceUsed()); + + // Make sure each thing we add to the set increases the SpaceUsed(). + unknown_fields->AddVarint(1, 0); + EXPECT_LT(base_size, empty_message.SpaceUsed()); + base_size = empty_message.SpaceUsed(); + + string* str = unknown_fields->AddLengthDelimited(1); + EXPECT_LT(base_size, empty_message.SpaceUsed()); + base_size = empty_message.SpaceUsed(); + + str->assign(sizeof(string) + 1, 'x'); + EXPECT_LT(base_size, empty_message.SpaceUsed()); + base_size = empty_message.SpaceUsed(); + + UnknownFieldSet* group = unknown_fields->AddGroup(1); + EXPECT_LT(base_size, empty_message.SpaceUsed()); + base_size = empty_message.SpaceUsed(); + + group->AddVarint(1, 0); + EXPECT_LT(base_size, empty_message.SpaceUsed()); +} + + +TEST_F(UnknownFieldSetTest, Empty) { + UnknownFieldSet unknown_fields; + EXPECT_TRUE(unknown_fields.empty()); + unknown_fields.AddVarint(6, 123); + EXPECT_FALSE(unknown_fields.empty()); + unknown_fields.Clear(); + EXPECT_TRUE(unknown_fields.empty()); +} + +TEST_F(UnknownFieldSetTest, DeleteSubrange) { + // Exhaustively test the deletion of every possible subrange in arrays of all + // sizes from 0 through 9. + for (int size = 0; size < 10; ++size) { + for (int num = 0; num <= size; ++num) { + for (int start = 0; start < size - num; ++start) { + // Create a set with "size" fields. + UnknownFieldSet unknown; + for (int i = 0; i < size; ++i) { + unknown.AddFixed32(i, i); + } + // Delete the specified subrange. + unknown.DeleteSubrange(start, num); + // Make sure the resulting field values are still correct. + EXPECT_EQ(size - num, unknown.field_count()); + for (int i = 0; i < unknown.field_count(); ++i) { + if (i < start) { + EXPECT_EQ(i, unknown.field(i).fixed32()); + } else { + EXPECT_EQ(i + num, unknown.field(i).fixed32()); + } + } + } + } + } +} + +void CheckDeleteByNumber(const vector& field_numbers, int deleted_number, + const vector& expected_field_nubmers) { + UnknownFieldSet unknown_fields; + for (int i = 0; i < field_numbers.size(); ++i) { + unknown_fields.AddFixed32(field_numbers[i], i); + } + unknown_fields.DeleteByNumber(deleted_number); + ASSERT_EQ(expected_field_nubmers.size(), unknown_fields.field_count()); + for (int i = 0; i < expected_field_nubmers.size(); ++i) { + EXPECT_EQ(expected_field_nubmers[i], + unknown_fields.field(i).number()); + } +} + +#define MAKE_VECTOR(x) vector(x, x + GOOGLE_ARRAYSIZE(x)) +TEST_F(UnknownFieldSetTest, DeleteByNumber) { + CheckDeleteByNumber(vector(), 1, vector()); + static const int kTestFieldNumbers1[] = {1, 2, 3}; + static const int kFieldNumberToDelete1 = 1; + static const int kExpectedFieldNumbers1[] = {2, 3}; + CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers1), kFieldNumberToDelete1, + MAKE_VECTOR(kExpectedFieldNumbers1)); + static const int kTestFieldNumbers2[] = {1, 2, 3}; + static const int kFieldNumberToDelete2 = 2; + static const int kExpectedFieldNumbers2[] = {1, 3}; + CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers2), kFieldNumberToDelete2, + MAKE_VECTOR(kExpectedFieldNumbers2)); + static const int kTestFieldNumbers3[] = {1, 2, 3}; + static const int kFieldNumberToDelete3 = 3; + static const int kExpectedFieldNumbers3[] = {1, 2}; + CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers3), kFieldNumberToDelete3, + MAKE_VECTOR(kExpectedFieldNumbers3)); + static const int kTestFieldNumbers4[] = {1, 2, 1, 4, 1}; + static const int kFieldNumberToDelete4 = 1; + static const int kExpectedFieldNumbers4[] = {2, 4}; + CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers4), kFieldNumberToDelete4, + MAKE_VECTOR(kExpectedFieldNumbers4)); + static const int kTestFieldNumbers5[] = {1, 2, 3, 4, 5}; + static const int kFieldNumberToDelete5 = 6; + static const int kExpectedFieldNumbers5[] = {1, 2, 3, 4, 5}; + CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers5), kFieldNumberToDelete5, + MAKE_VECTOR(kExpectedFieldNumbers5)); +} +#undef MAKE_VECTOR +} // namespace + +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format.cc new file mode 100644 index 0000000..ead763b --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format.cc @@ -0,0 +1,1063 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + + +namespace google { +namespace protobuf { +namespace internal { + +namespace { + +// This function turns out to be convenient when using some macros later. +inline int GetEnumNumber(const EnumValueDescriptor* descriptor) { + return descriptor->number(); +} + +} // anonymous namespace + +// =================================================================== + +bool UnknownFieldSetFieldSkipper::SkipField( + io::CodedInputStream* input, uint32 tag) { + return WireFormat::SkipField(input, tag, unknown_fields_); +} + +bool UnknownFieldSetFieldSkipper::SkipMessage(io::CodedInputStream* input) { + return WireFormat::SkipMessage(input, unknown_fields_); +} + +void UnknownFieldSetFieldSkipper::SkipUnknownEnum( + int field_number, int value) { + unknown_fields_->AddVarint(field_number, value); +} + +bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, + UnknownFieldSet* unknown_fields) { + int number = WireFormatLite::GetTagFieldNumber(tag); + + switch (WireFormatLite::GetTagWireType(tag)) { + case WireFormatLite::WIRETYPE_VARINT: { + uint64 value; + if (!input->ReadVarint64(&value)) return false; + if (unknown_fields != NULL) unknown_fields->AddVarint(number, value); + return true; + } + case WireFormatLite::WIRETYPE_FIXED64: { + uint64 value; + if (!input->ReadLittleEndian64(&value)) return false; + if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value); + return true; + } + case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (unknown_fields == NULL) { + if (!input->Skip(length)) return false; + } else { + if (!input->ReadString(unknown_fields->AddLengthDelimited(number), + length)) { + return false; + } + } + return true; + } + case WireFormatLite::WIRETYPE_START_GROUP: { + if (!input->IncrementRecursionDepth()) return false; + if (!SkipMessage(input, (unknown_fields == NULL) ? + NULL : unknown_fields->AddGroup(number))) { + return false; + } + input->DecrementRecursionDepth(); + // Check that the ending tag matched the starting tag. + if (!input->LastTagWas(WireFormatLite::MakeTag( + WireFormatLite::GetTagFieldNumber(tag), + WireFormatLite::WIRETYPE_END_GROUP))) { + return false; + } + return true; + } + case WireFormatLite::WIRETYPE_END_GROUP: { + return false; + } + case WireFormatLite::WIRETYPE_FIXED32: { + uint32 value; + if (!input->ReadLittleEndian32(&value)) return false; + if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value); + return true; + } + default: { + return false; + } + } +} + +bool WireFormat::SkipMessage(io::CodedInputStream* input, + UnknownFieldSet* unknown_fields) { + while(true) { + uint32 tag = input->ReadTag(); + if (tag == 0) { + // End of input. This is a valid place to end, so return true. + return true; + } + + WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); + + if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { + // Must be the end of the message. + return true; + } + + if (!SkipField(input, tag, unknown_fields)) return false; + } +} + +void WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields, + io::CodedOutputStream* output) { + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + switch (field.type()) { + case UnknownField::TYPE_VARINT: + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_VARINT)); + output->WriteVarint64(field.varint()); + break; + case UnknownField::TYPE_FIXED32: + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_FIXED32)); + output->WriteLittleEndian32(field.fixed32()); + break; + case UnknownField::TYPE_FIXED64: + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_FIXED64)); + output->WriteLittleEndian64(field.fixed64()); + break; + case UnknownField::TYPE_LENGTH_DELIMITED: + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); + output->WriteVarint32(field.length_delimited().size()); + output->WriteString(field.length_delimited()); + break; + case UnknownField::TYPE_GROUP: + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_START_GROUP)); + SerializeUnknownFields(field.group(), output); + output->WriteVarint32(WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_END_GROUP)); + break; + } + } +} + +uint8* WireFormat::SerializeUnknownFieldsToArray( + const UnknownFieldSet& unknown_fields, + uint8* target) { + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + + switch (field.type()) { + case UnknownField::TYPE_VARINT: + target = WireFormatLite::WriteInt64ToArray( + field.number(), field.varint(), target); + break; + case UnknownField::TYPE_FIXED32: + target = WireFormatLite::WriteFixed32ToArray( + field.number(), field.fixed32(), target); + break; + case UnknownField::TYPE_FIXED64: + target = WireFormatLite::WriteFixed64ToArray( + field.number(), field.fixed64(), target); + break; + case UnknownField::TYPE_LENGTH_DELIMITED: + target = WireFormatLite::WriteBytesToArray( + field.number(), field.length_delimited(), target); + break; + case UnknownField::TYPE_GROUP: + target = WireFormatLite::WriteTagToArray( + field.number(), WireFormatLite::WIRETYPE_START_GROUP, target); + target = SerializeUnknownFieldsToArray(field.group(), target); + target = WireFormatLite::WriteTagToArray( + field.number(), WireFormatLite::WIRETYPE_END_GROUP, target); + break; + } + } + return target; +} + +void WireFormat::SerializeUnknownMessageSetItems( + const UnknownFieldSet& unknown_fields, + io::CodedOutputStream* output) { + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + // The only unknown fields that are allowed to exist in a MessageSet are + // messages, which are length-delimited. + if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { + // Start group. + output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag); + + // Write type ID. + output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag); + output->WriteVarint32(field.number()); + + // Write message. + output->WriteVarint32(WireFormatLite::kMessageSetMessageTag); + field.SerializeLengthDelimitedNoTag(output); + + // End group. + output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag); + } + } +} + +uint8* WireFormat::SerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, + uint8* target) { + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + + // The only unknown fields that are allowed to exist in a MessageSet are + // messages, which are length-delimited. + if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { + // Start group. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemStartTag, target); + + // Write type ID. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetTypeIdTag, target); + target = io::CodedOutputStream::WriteVarint32ToArray( + field.number(), target); + + // Write message. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetMessageTag, target); + target = field.SerializeLengthDelimitedNoTagToArray(target); + + // End group. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemEndTag, target); + } + } + + return target; +} + +int WireFormat::ComputeUnknownFieldsSize( + const UnknownFieldSet& unknown_fields) { + int size = 0; + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + + switch (field.type()) { + case UnknownField::TYPE_VARINT: + size += io::CodedOutputStream::VarintSize32( + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_VARINT)); + size += io::CodedOutputStream::VarintSize64(field.varint()); + break; + case UnknownField::TYPE_FIXED32: + size += io::CodedOutputStream::VarintSize32( + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_FIXED32)); + size += sizeof(int32); + break; + case UnknownField::TYPE_FIXED64: + size += io::CodedOutputStream::VarintSize32( + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_FIXED64)); + size += sizeof(int64); + break; + case UnknownField::TYPE_LENGTH_DELIMITED: + size += io::CodedOutputStream::VarintSize32( + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); + size += io::CodedOutputStream::VarintSize32( + field.length_delimited().size()); + size += field.length_delimited().size(); + break; + case UnknownField::TYPE_GROUP: + size += io::CodedOutputStream::VarintSize32( + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_START_GROUP)); + size += ComputeUnknownFieldsSize(field.group()); + size += io::CodedOutputStream::VarintSize32( + WireFormatLite::MakeTag(field.number(), + WireFormatLite::WIRETYPE_END_GROUP)); + break; + } + } + + return size; +} + +int WireFormat::ComputeUnknownMessageSetItemsSize( + const UnknownFieldSet& unknown_fields) { + int size = 0; + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + + // The only unknown fields that are allowed to exist in a MessageSet are + // messages, which are length-delimited. + if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { + size += WireFormatLite::kMessageSetItemTagsSize; + size += io::CodedOutputStream::VarintSize32(field.number()); + + int field_size = field.GetLengthDelimitedSize(); + size += io::CodedOutputStream::VarintSize32(field_size); + size += field_size; + } + } + + return size; +} + +// =================================================================== + +bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input, + Message* message) { + const Descriptor* descriptor = message->GetDescriptor(); + const Reflection* message_reflection = message->GetReflection(); + + while(true) { + uint32 tag = input->ReadTag(); + if (tag == 0) { + // End of input. This is a valid place to end, so return true. + return true; + } + + if (WireFormatLite::GetTagWireType(tag) == + WireFormatLite::WIRETYPE_END_GROUP) { + // Must be the end of the message. + return true; + } + + const FieldDescriptor* field = NULL; + + if (descriptor != NULL) { + int field_number = WireFormatLite::GetTagFieldNumber(tag); + field = descriptor->FindFieldByNumber(field_number); + + // If that failed, check if the field is an extension. + if (field == NULL && descriptor->IsExtensionNumber(field_number)) { + if (input->GetExtensionPool() == NULL) { + field = message_reflection->FindKnownExtensionByNumber(field_number); + } else { + field = input->GetExtensionPool() + ->FindExtensionByNumber(descriptor, field_number); + } + } + + // If that failed, but we're a MessageSet, and this is the tag for a + // MessageSet item, then parse that. + if (field == NULL && + descriptor->options().message_set_wire_format() && + tag == WireFormatLite::kMessageSetItemStartTag) { + if (!ParseAndMergeMessageSetItem(input, message)) { + return false; + } + continue; // Skip ParseAndMergeField(); already taken care of. + } + } + + if (!ParseAndMergeField(tag, field, message, input)) { + return false; + } + } +} + +bool WireFormat::ParseAndMergeField( + uint32 tag, + const FieldDescriptor* field, // May be NULL for unknown + Message* message, + io::CodedInputStream* input) { + const Reflection* message_reflection = message->GetReflection(); + + enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format; + + if (field == NULL) { + value_format = UNKNOWN; + } else if (WireFormatLite::GetTagWireType(tag) == + WireTypeForFieldType(field->type())) { + value_format = NORMAL_FORMAT; + } else if (field->is_packable() && + WireFormatLite::GetTagWireType(tag) == + WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + value_format = PACKED_FORMAT; + } else { + // We don't recognize this field. Either the field number is unknown + // or the wire type doesn't match. Put it in our unknown field set. + value_format = UNKNOWN; + } + + if (value_format == UNKNOWN) { + return SkipField(input, tag, + message_reflection->MutableUnknownFields(message)); + } else if (value_format == PACKED_FORMAT) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + + switch (field->type()) { +#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + while (input->BytesUntilLimit() > 0) { \ + CPPTYPE value; \ + if (!WireFormatLite::ReadPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \ + return false; \ + message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ + } \ + break; \ + } + + HANDLE_PACKED_TYPE( INT32, int32, Int32) + HANDLE_PACKED_TYPE( INT64, int64, Int64) + HANDLE_PACKED_TYPE(SINT32, int32, Int32) + HANDLE_PACKED_TYPE(SINT64, int64, Int64) + HANDLE_PACKED_TYPE(UINT32, uint32, UInt32) + HANDLE_PACKED_TYPE(UINT64, uint64, UInt64) + + HANDLE_PACKED_TYPE( FIXED32, uint32, UInt32) + HANDLE_PACKED_TYPE( FIXED64, uint64, UInt64) + HANDLE_PACKED_TYPE(SFIXED32, int32, Int32) + HANDLE_PACKED_TYPE(SFIXED64, int64, Int64) + + HANDLE_PACKED_TYPE(FLOAT , float , Float ) + HANDLE_PACKED_TYPE(DOUBLE, double, Double) + + HANDLE_PACKED_TYPE(BOOL, bool, Bool) +#undef HANDLE_PACKED_TYPE + + case FieldDescriptor::TYPE_ENUM: { + while (input->BytesUntilLimit() > 0) { + int value; + if (!WireFormatLite::ReadPrimitive( + input, &value)) return false; + const EnumValueDescriptor* enum_value = + field->enum_type()->FindValueByNumber(value); + if (enum_value != NULL) { + message_reflection->AddEnum(message, field, enum_value); + } + } + + break; + } + + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_BYTES: + // Can't have packed fields of these types: these should be caught by + // the protocol compiler. + return false; + break; + } + + input->PopLimit(limit); + } else { + // Non-packed value (value_format == NORMAL_FORMAT) + switch (field->type()) { +#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + CPPTYPE value; \ + if (!WireFormatLite::ReadPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \ + return false; \ + if (field->is_repeated()) { \ + message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ + } else { \ + message_reflection->Set##CPPTYPE_METHOD(message, field, value); \ + } \ + break; \ + } + + HANDLE_TYPE( INT32, int32, Int32) + HANDLE_TYPE( INT64, int64, Int64) + HANDLE_TYPE(SINT32, int32, Int32) + HANDLE_TYPE(SINT64, int64, Int64) + HANDLE_TYPE(UINT32, uint32, UInt32) + HANDLE_TYPE(UINT64, uint64, UInt64) + + HANDLE_TYPE( FIXED32, uint32, UInt32) + HANDLE_TYPE( FIXED64, uint64, UInt64) + HANDLE_TYPE(SFIXED32, int32, Int32) + HANDLE_TYPE(SFIXED64, int64, Int64) + + HANDLE_TYPE(FLOAT , float , Float ) + HANDLE_TYPE(DOUBLE, double, Double) + + HANDLE_TYPE(BOOL, bool, Bool) +#undef HANDLE_TYPE + + case FieldDescriptor::TYPE_ENUM: { + int value; + if (!WireFormatLite::ReadPrimitive( + input, &value)) return false; + const EnumValueDescriptor* enum_value = + field->enum_type()->FindValueByNumber(value); + if (enum_value != NULL) { + if (field->is_repeated()) { + message_reflection->AddEnum(message, field, enum_value); + } else { + message_reflection->SetEnum(message, field, enum_value); + } + } else { + // The enum value is not one of the known values. Add it to the + // UnknownFieldSet. + int64 sign_extended_value = static_cast(value); + message_reflection->MutableUnknownFields(message) + ->AddVarint(WireFormatLite::GetTagFieldNumber(tag), + sign_extended_value); + } + break; + } + + // Handle strings separately so that we can optimize the ctype=CORD case. + case FieldDescriptor::TYPE_STRING: { + string value; + if (!WireFormatLite::ReadString(input, &value)) return false; + VerifyUTF8String(value.data(), value.length(), PARSE); + if (field->is_repeated()) { + message_reflection->AddString(message, field, value); + } else { + message_reflection->SetString(message, field, value); + } + break; + } + + case FieldDescriptor::TYPE_BYTES: { + string value; + if (!WireFormatLite::ReadBytes(input, &value)) return false; + if (field->is_repeated()) { + message_reflection->AddString(message, field, value); + } else { + message_reflection->SetString(message, field, value); + } + break; + } + + case FieldDescriptor::TYPE_GROUP: { + Message* sub_message; + if (field->is_repeated()) { + sub_message = message_reflection->AddMessage( + message, field, input->GetExtensionFactory()); + } else { + sub_message = message_reflection->MutableMessage( + message, field, input->GetExtensionFactory()); + } + + if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag), + input, sub_message)) + return false; + break; + } + + case FieldDescriptor::TYPE_MESSAGE: { + Message* sub_message; + if (field->is_repeated()) { + sub_message = message_reflection->AddMessage( + message, field, input->GetExtensionFactory()); + } else { + sub_message = message_reflection->MutableMessage( + message, field, input->GetExtensionFactory()); + } + + if (!WireFormatLite::ReadMessage(input, sub_message)) return false; + break; + } + } + } + + return true; +} + +bool WireFormat::ParseAndMergeMessageSetItem( + io::CodedInputStream* input, + Message* message) { + const Reflection* message_reflection = message->GetReflection(); + + // This method parses a group which should contain two fields: + // required int32 type_id = 2; + // required data message = 3; + + // Once we see a type_id, we'll construct a fake tag for this extension + // which is the tag it would have had under the proto2 extensions wire + // format. + uint32 fake_tag = 0; + + // Once we see a type_id, we'll look up the FieldDescriptor for the + // extension. + const FieldDescriptor* field = NULL; + + // If we see message data before the type_id, we'll append it to this so + // we can parse it later. + string message_data; + + while (true) { + uint32 tag = input->ReadTag(); + if (tag == 0) return false; + + switch (tag) { + case WireFormatLite::kMessageSetTypeIdTag: { + uint32 type_id; + if (!input->ReadVarint32(&type_id)) return false; + fake_tag = WireFormatLite::MakeTag( + type_id, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + field = message_reflection->FindKnownExtensionByNumber(type_id); + + if (!message_data.empty()) { + // We saw some message data before the type_id. Have to parse it + // now. + io::ArrayInputStream raw_input(message_data.data(), + message_data.size()); + io::CodedInputStream sub_input(&raw_input); + if (!ParseAndMergeField(fake_tag, field, message, + &sub_input)) { + return false; + } + message_data.clear(); + } + + break; + } + + case WireFormatLite::kMessageSetMessageTag: { + if (fake_tag == 0) { + // We haven't seen a type_id yet. Append this data to message_data. + string temp; + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->ReadString(&temp, length)) return false; + io::StringOutputStream output_stream(&message_data); + io::CodedOutputStream coded_output(&output_stream); + coded_output.WriteVarint32(length); + coded_output.WriteString(temp); + } else { + // Already saw type_id, so we can parse this directly. + if (!ParseAndMergeField(fake_tag, field, message, input)) { + return false; + } + } + + break; + } + + case WireFormatLite::kMessageSetItemEndTag: { + return true; + } + + default: { + if (!SkipField(input, tag, NULL)) return false; + } + } + } +} + +// =================================================================== + +void WireFormat::SerializeWithCachedSizes( + const Message& message, + int size, io::CodedOutputStream* output) { + const Descriptor* descriptor = message.GetDescriptor(); + const Reflection* message_reflection = message.GetReflection(); + int expected_endpoint = output->ByteCount() + size; + + vector fields; + message_reflection->ListFields(message, &fields); + for (int i = 0; i < fields.size(); i++) { + SerializeFieldWithCachedSizes(fields[i], message, output); + } + + if (descriptor->options().message_set_wire_format()) { + SerializeUnknownMessageSetItems( + message_reflection->GetUnknownFields(message), output); + } else { + SerializeUnknownFields( + message_reflection->GetUnknownFields(message), output); + } + + GOOGLE_CHECK_EQ(output->ByteCount(), expected_endpoint) + << ": Protocol message serialized to a size different from what was " + "originally expected. Perhaps it was modified by another thread " + "during serialization?"; +} + +void WireFormat::SerializeFieldWithCachedSizes( + const FieldDescriptor* field, + const Message& message, + io::CodedOutputStream* output) { + const Reflection* message_reflection = message.GetReflection(); + + if (field->is_extension() && + field->containing_type()->options().message_set_wire_format() && + field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + !field->is_repeated()) { + SerializeMessageSetItemWithCachedSizes(field, message, output); + return; + } + + int count = 0; + + if (field->is_repeated()) { + count = message_reflection->FieldSize(message, field); + } else if (message_reflection->HasField(message, field)) { + count = 1; + } + + const bool is_packed = field->options().packed(); + if (is_packed && count > 0) { + WireFormatLite::WriteTag(field->number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); + const int data_size = FieldDataOnlyByteSize(field, message); + output->WriteVarint32(data_size); + } + + for (int j = 0; j < count; j++) { + switch (field->type()) { +#define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + const CPPTYPE value = field->is_repeated() ? \ + message_reflection->GetRepeated##CPPTYPE_METHOD( \ + message, field, j) : \ + message_reflection->Get##CPPTYPE_METHOD( \ + message, field); \ + if (is_packed) { \ + WireFormatLite::Write##TYPE_METHOD##NoTag(value, output); \ + } else { \ + WireFormatLite::Write##TYPE_METHOD(field->number(), value, output); \ + } \ + break; \ + } + + HANDLE_PRIMITIVE_TYPE( INT32, int32, Int32, Int32) + HANDLE_PRIMITIVE_TYPE( INT64, int64, Int64, Int64) + HANDLE_PRIMITIVE_TYPE(SINT32, int32, SInt32, Int32) + HANDLE_PRIMITIVE_TYPE(SINT64, int64, SInt64, Int64) + HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32) + HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64) + + HANDLE_PRIMITIVE_TYPE( FIXED32, uint32, Fixed32, UInt32) + HANDLE_PRIMITIVE_TYPE( FIXED64, uint64, Fixed64, UInt64) + HANDLE_PRIMITIVE_TYPE(SFIXED32, int32, SFixed32, Int32) + HANDLE_PRIMITIVE_TYPE(SFIXED64, int64, SFixed64, Int64) + + HANDLE_PRIMITIVE_TYPE(FLOAT , float , Float , Float ) + HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double) + + HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool) +#undef HANDLE_PRIMITIVE_TYPE + +#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: \ + WireFormatLite::Write##TYPE_METHOD( \ + field->number(), \ + field->is_repeated() ? \ + message_reflection->GetRepeated##CPPTYPE_METHOD( \ + message, field, j) : \ + message_reflection->Get##CPPTYPE_METHOD(message, field), \ + output); \ + break; + + HANDLE_TYPE(GROUP , Group , Message) + HANDLE_TYPE(MESSAGE, Message, Message) +#undef HANDLE_TYPE + + case FieldDescriptor::TYPE_ENUM: { + const EnumValueDescriptor* value = field->is_repeated() ? + message_reflection->GetRepeatedEnum(message, field, j) : + message_reflection->GetEnum(message, field); + if (is_packed) { + WireFormatLite::WriteEnumNoTag(value->number(), output); + } else { + WireFormatLite::WriteEnum(field->number(), value->number(), output); + } + break; + } + + // Handle strings separately so that we can get string references + // instead of copying. + case FieldDescriptor::TYPE_STRING: { + string scratch; + const string& value = field->is_repeated() ? + message_reflection->GetRepeatedStringReference( + message, field, j, &scratch) : + message_reflection->GetStringReference(message, field, &scratch); + VerifyUTF8String(value.data(), value.length(), SERIALIZE); + WireFormatLite::WriteString(field->number(), value, output); + break; + } + + case FieldDescriptor::TYPE_BYTES: { + string scratch; + const string& value = field->is_repeated() ? + message_reflection->GetRepeatedStringReference( + message, field, j, &scratch) : + message_reflection->GetStringReference(message, field, &scratch); + WireFormatLite::WriteBytes(field->number(), value, output); + break; + } + } + } +} + +void WireFormat::SerializeMessageSetItemWithCachedSizes( + const FieldDescriptor* field, + const Message& message, + io::CodedOutputStream* output) { + const Reflection* message_reflection = message.GetReflection(); + + // Start group. + output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag); + + // Write type ID. + output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag); + output->WriteVarint32(field->number()); + + // Write message. + output->WriteVarint32(WireFormatLite::kMessageSetMessageTag); + + const Message& sub_message = message_reflection->GetMessage(message, field); + output->WriteVarint32(sub_message.GetCachedSize()); + sub_message.SerializeWithCachedSizes(output); + + // End group. + output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag); +} + +// =================================================================== + +int WireFormat::ByteSize(const Message& message) { + const Descriptor* descriptor = message.GetDescriptor(); + const Reflection* message_reflection = message.GetReflection(); + + int our_size = 0; + + vector fields; + message_reflection->ListFields(message, &fields); + for (int i = 0; i < fields.size(); i++) { + our_size += FieldByteSize(fields[i], message); + } + + if (descriptor->options().message_set_wire_format()) { + our_size += ComputeUnknownMessageSetItemsSize( + message_reflection->GetUnknownFields(message)); + } else { + our_size += ComputeUnknownFieldsSize( + message_reflection->GetUnknownFields(message)); + } + + return our_size; +} + +int WireFormat::FieldByteSize( + const FieldDescriptor* field, + const Message& message) { + const Reflection* message_reflection = message.GetReflection(); + + if (field->is_extension() && + field->containing_type()->options().message_set_wire_format() && + field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + !field->is_repeated()) { + return MessageSetItemByteSize(field, message); + } + + int count = 0; + if (field->is_repeated()) { + count = message_reflection->FieldSize(message, field); + } else if (message_reflection->HasField(message, field)) { + count = 1; + } + + const int data_size = FieldDataOnlyByteSize(field, message); + int our_size = data_size; + if (field->options().packed()) { + if (data_size > 0) { + // Packed fields get serialized like a string, not their native type. + // Technically this doesn't really matter; the size only changes if it's + // a GROUP + our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING); + our_size += io::CodedOutputStream::VarintSize32(data_size); + } + } else { + our_size += count * TagSize(field->number(), field->type()); + } + return our_size; +} + +int WireFormat::FieldDataOnlyByteSize( + const FieldDescriptor* field, + const Message& message) { + const Reflection* message_reflection = message.GetReflection(); + + int count = 0; + if (field->is_repeated()) { + count = message_reflection->FieldSize(message, field); + } else if (message_reflection->HasField(message, field)) { + count = 1; + } + + int data_size = 0; + switch (field->type()) { +#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: \ + if (field->is_repeated()) { \ + for (int j = 0; j < count; j++) { \ + data_size += WireFormatLite::TYPE_METHOD##Size( \ + message_reflection->GetRepeated##CPPTYPE_METHOD( \ + message, field, j)); \ + } \ + } else { \ + data_size += WireFormatLite::TYPE_METHOD##Size( \ + message_reflection->Get##CPPTYPE_METHOD(message, field)); \ + } \ + break; + +#define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: \ + data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \ + break; + + HANDLE_TYPE( INT32, Int32, Int32) + HANDLE_TYPE( INT64, Int64, Int64) + HANDLE_TYPE(SINT32, SInt32, Int32) + HANDLE_TYPE(SINT64, SInt64, Int64) + HANDLE_TYPE(UINT32, UInt32, UInt32) + HANDLE_TYPE(UINT64, UInt64, UInt64) + + HANDLE_FIXED_TYPE( FIXED32, Fixed32) + HANDLE_FIXED_TYPE( FIXED64, Fixed64) + HANDLE_FIXED_TYPE(SFIXED32, SFixed32) + HANDLE_FIXED_TYPE(SFIXED64, SFixed64) + + HANDLE_FIXED_TYPE(FLOAT , Float ) + HANDLE_FIXED_TYPE(DOUBLE, Double) + + HANDLE_FIXED_TYPE(BOOL, Bool) + + HANDLE_TYPE(GROUP , Group , Message) + HANDLE_TYPE(MESSAGE, Message, Message) +#undef HANDLE_TYPE +#undef HANDLE_FIXED_TYPE + + case FieldDescriptor::TYPE_ENUM: { + if (field->is_repeated()) { + for (int j = 0; j < count; j++) { + data_size += WireFormatLite::EnumSize( + message_reflection->GetRepeatedEnum(message, field, j)->number()); + } + } else { + data_size += WireFormatLite::EnumSize( + message_reflection->GetEnum(message, field)->number()); + } + break; + } + + // Handle strings separately so that we can get string references + // instead of copying. + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_BYTES: { + for (int j = 0; j < count; j++) { + string scratch; + const string& value = field->is_repeated() ? + message_reflection->GetRepeatedStringReference( + message, field, j, &scratch) : + message_reflection->GetStringReference(message, field, &scratch); + data_size += WireFormatLite::StringSize(value); + } + break; + } + } + return data_size; +} + +int WireFormat::MessageSetItemByteSize( + const FieldDescriptor* field, + const Message& message) { + const Reflection* message_reflection = message.GetReflection(); + + int our_size = WireFormatLite::kMessageSetItemTagsSize; + + // type_id + our_size += io::CodedOutputStream::VarintSize32(field->number()); + + // message + const Message& sub_message = message_reflection->GetMessage(message, field); + int message_size = sub_message.ByteSize(); + + our_size += io::CodedOutputStream::VarintSize32(message_size); + our_size += message_size; + + return our_size; +} + +void WireFormat::VerifyUTF8StringFallback(const char* data, + int size, + Operation op) { + if (!IsStructurallyValidUTF8(data, size)) { + const char* operation_str = NULL; + switch (op) { + case PARSE: + operation_str = "parsing"; + break; + case SERIALIZE: + operation_str = "serializing"; + break; + // no default case: have the compiler warn if a case is not covered. + } + GOOGLE_LOG(ERROR) << "String field contains invalid UTF-8 data when " + << operation_str + << " a protocol buffer. Use the 'bytes' type if you intend to " + "send raw bytes."; + } +} + + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format.h new file mode 100644 index 0000000..6cc9002 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format.h @@ -0,0 +1,308 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// atenasio@google.com (Chris Atenasio) (ZigZag transform) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_H__ +#define GOOGLE_PROTOBUF_WIRE_FORMAT_H__ + +#include +#include +#include +#include +#include +#include + +// Do UTF-8 validation on string type in Debug build only +#ifndef NDEBUG +#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED +#endif + +namespace google { +namespace protobuf { + namespace io { + class CodedInputStream; // coded_stream.h + class CodedOutputStream; // coded_stream.h + } + class UnknownFieldSet; // unknown_field_set.h +} + +namespace protobuf { +namespace internal { + +// This class is for internal use by the protocol buffer library and by +// protocol-complier-generated message classes. It must not be called +// directly by clients. +// +// This class contains code for implementing the binary protocol buffer +// wire format via reflection. The WireFormatLite class implements the +// non-reflection based routines. +// +// This class is really a namespace that contains only static methods +class LIBPROTOBUF_EXPORT WireFormat { + public: + + // Given a field return its WireType + static inline WireFormatLite::WireType WireTypeForField( + const FieldDescriptor* field); + + // Given a FieldSescriptor::Type return its WireType + static inline WireFormatLite::WireType WireTypeForFieldType( + FieldDescriptor::Type type); + + // Compute the byte size of a tag. For groups, this includes both the start + // and end tags. + static inline int TagSize(int field_number, FieldDescriptor::Type type); + + // These procedures can be used to implement the methods of Message which + // handle parsing and serialization of the protocol buffer wire format + // using only the Reflection interface. When you ask the protocol + // compiler to optimize for code size rather than speed, it will implement + // those methods in terms of these procedures. Of course, these are much + // slower than the specialized implementations which the protocol compiler + // generates when told to optimize for speed. + + // Read a message in protocol buffer wire format. + // + // This procedure reads either to the end of the input stream or through + // a WIRETYPE_END_GROUP tag ending the message, whichever comes first. + // It returns false if the input is invalid. + // + // Required fields are NOT checked by this method. You must call + // IsInitialized() on the resulting message yourself. + static bool ParseAndMergePartial(io::CodedInputStream* input, + Message* message); + + // Serialize a message in protocol buffer wire format. + // + // Any embedded messages within the message must have their correct sizes + // cached. However, the top-level message need not; its size is passed as + // a parameter to this procedure. + // + // These return false iff the underlying stream returns a write error. + static void SerializeWithCachedSizes( + const Message& message, + int size, io::CodedOutputStream* output); + + // Implements Message::ByteSize() via reflection. WARNING: The result + // of this method is *not* cached anywhere. However, all embedded messages + // will have their ByteSize() methods called, so their sizes will be cached. + // Therefore, calling this method is sufficient to allow you to call + // WireFormat::SerializeWithCachedSizes() on the same object. + static int ByteSize(const Message& message); + + // ----------------------------------------------------------------- + // Helpers for dealing with unknown fields + + // Skips a field value of the given WireType. The input should start + // positioned immediately after the tag. If unknown_fields is non-NULL, + // the contents of the field will be added to it. + static bool SkipField(io::CodedInputStream* input, uint32 tag, + UnknownFieldSet* unknown_fields); + + // Reads and ignores a message from the input. If unknown_fields is non-NULL, + // the contents will be added to it. + static bool SkipMessage(io::CodedInputStream* input, + UnknownFieldSet* unknown_fields); + + // Write the contents of an UnknownFieldSet to the output. + static void SerializeUnknownFields(const UnknownFieldSet& unknown_fields, + io::CodedOutputStream* output); + // Same as above, except writing directly to the provided buffer. + // Requires that the buffer have sufficient capacity for + // ComputeUnknownFieldsSize(unknown_fields). + // + // Returns a pointer past the last written byte. + static uint8* SerializeUnknownFieldsToArray( + const UnknownFieldSet& unknown_fields, + uint8* target); + + // Same thing except for messages that have the message_set_wire_format + // option. + static void SerializeUnknownMessageSetItems( + const UnknownFieldSet& unknown_fields, + io::CodedOutputStream* output); + // Same as above, except writing directly to the provided buffer. + // Requires that the buffer have sufficient capacity for + // ComputeUnknownMessageSetItemsSize(unknown_fields). + // + // Returns a pointer past the last written byte. + static uint8* SerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, + uint8* target); + + // Compute the size of the UnknownFieldSet on the wire. + static int ComputeUnknownFieldsSize(const UnknownFieldSet& unknown_fields); + + // Same thing except for messages that have the message_set_wire_format + // option. + static int ComputeUnknownMessageSetItemsSize( + const UnknownFieldSet& unknown_fields); + + + // Helper functions for encoding and decoding tags. (Inlined below and in + // _inl.h) + // + // This is different from MakeTag(field->number(), field->type()) in the case + // of packed repeated fields. + static uint32 MakeTag(const FieldDescriptor* field); + + // Parse a single field. The input should start out positioned immidately + // after the tag. + static bool ParseAndMergeField( + uint32 tag, + const FieldDescriptor* field, // May be NULL for unknown + Message* message, + io::CodedInputStream* input); + + // Serialize a single field. + static void SerializeFieldWithCachedSizes( + const FieldDescriptor* field, // Cannot be NULL + const Message& message, + io::CodedOutputStream* output); + + // Compute size of a single field. If the field is a message type, this + // will call ByteSize() for the embedded message, insuring that it caches + // its size. + static int FieldByteSize( + const FieldDescriptor* field, // Cannot be NULL + const Message& message); + + // Parse/serialize a MessageSet::Item group. Used with messages that use + // opion message_set_wire_format = true. + static bool ParseAndMergeMessageSetItem( + io::CodedInputStream* input, + Message* message); + static void SerializeMessageSetItemWithCachedSizes( + const FieldDescriptor* field, + const Message& message, + io::CodedOutputStream* output); + static int MessageSetItemByteSize( + const FieldDescriptor* field, + const Message& message); + + // Computes the byte size of a field, excluding tags. For packed fields, it + // only includes the size of the raw data, and not the size of the total + // length, but for other length-delimited types, the size of the length is + // included. + static int FieldDataOnlyByteSize( + const FieldDescriptor* field, // Cannot be NULL + const Message& message); + + enum Operation { + PARSE, + SERIALIZE, + }; + + // Verifies that a string field is valid UTF8, logging an error if not. + static void VerifyUTF8String(const char* data, int size, Operation op); + + private: + // Verifies that a string field is valid UTF8, logging an error if not. + static void VerifyUTF8StringFallback( + const char* data, + int size, + Operation op); + + + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat); +}; + +// Subclass of FieldSkipper which saves skipped fields to an UnknownFieldSet. +class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper { + public: + UnknownFieldSetFieldSkipper(UnknownFieldSet* unknown_fields) + : unknown_fields_(unknown_fields) {} + virtual ~UnknownFieldSetFieldSkipper() {} + + // implements FieldSkipper ----------------------------------------- + virtual bool SkipField(io::CodedInputStream* input, uint32 tag); + virtual bool SkipMessage(io::CodedInputStream* input); + virtual void SkipUnknownEnum(int field_number, int value); + + protected: + UnknownFieldSet* unknown_fields_; +}; + +// inline methods ==================================================== + +inline WireFormatLite::WireType WireFormat::WireTypeForField( + const FieldDescriptor* field) { + if (field->options().packed()) { + return WireFormatLite::WIRETYPE_LENGTH_DELIMITED; + } else { + return WireTypeForFieldType(field->type()); + } +} + +inline WireFormatLite::WireType WireFormat::WireTypeForFieldType( + FieldDescriptor::Type type) { + // Some compilers don't like enum -> enum casts, so we implicit_cast to + // int first. + return WireFormatLite::WireTypeForFieldType( + static_cast( + implicit_cast(type))); +} + +inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) { + return WireFormatLite::MakeTag(field->number(), WireTypeForField(field)); +} + +inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) { + // Some compilers don't like enum -> enum casts, so we implicit_cast to + // int first. + return WireFormatLite::TagSize(field_number, + static_cast( + implicit_cast(type))); +} + +inline void WireFormat::VerifyUTF8String(const char* data, int size, + WireFormat::Operation op) { +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + WireFormat::VerifyUTF8StringFallback(data, size, op); +#else + // Avoid the compiler warning about unsued variables. + (void)data; (void)size; (void)op; +#endif +} + + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite.cc new file mode 100644 index 0000000..738fc42 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite.cc @@ -0,0 +1,361 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +#ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC + // requires them. +const int WireFormatLite::kMessageSetItemStartTag; +const int WireFormatLite::kMessageSetItemEndTag; +const int WireFormatLite::kMessageSetTypeIdTag; +const int WireFormatLite::kMessageSetMessageTag; + +#endif + +const int WireFormatLite::kMessageSetItemTagsSize = + io::CodedOutputStream::StaticVarintSize32::value + + io::CodedOutputStream::StaticVarintSize32::value + + io::CodedOutputStream::StaticVarintSize32::value + + io::CodedOutputStream::StaticVarintSize32::value; + +const WireFormatLite::CppType +WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = { + static_cast(0), // 0 is reserved for errors + + CPPTYPE_DOUBLE, // TYPE_DOUBLE + CPPTYPE_FLOAT, // TYPE_FLOAT + CPPTYPE_INT64, // TYPE_INT64 + CPPTYPE_UINT64, // TYPE_UINT64 + CPPTYPE_INT32, // TYPE_INT32 + CPPTYPE_UINT64, // TYPE_FIXED64 + CPPTYPE_UINT32, // TYPE_FIXED32 + CPPTYPE_BOOL, // TYPE_BOOL + CPPTYPE_STRING, // TYPE_STRING + CPPTYPE_MESSAGE, // TYPE_GROUP + CPPTYPE_MESSAGE, // TYPE_MESSAGE + CPPTYPE_STRING, // TYPE_BYTES + CPPTYPE_UINT32, // TYPE_UINT32 + CPPTYPE_ENUM, // TYPE_ENUM + CPPTYPE_INT32, // TYPE_SFIXED32 + CPPTYPE_INT64, // TYPE_SFIXED64 + CPPTYPE_INT32, // TYPE_SINT32 + CPPTYPE_INT64, // TYPE_SINT64 +}; + +const WireFormatLite::WireType +WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = { + static_cast(-1), // invalid + WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE + WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT + WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64 + WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64 + WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32 + WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64 + WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32 + WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING + WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES + WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32 + WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM + WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32 + WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64 + WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32 + WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64 +}; + +bool WireFormatLite::SkipField( + io::CodedInputStream* input, uint32 tag) { + switch (WireFormatLite::GetTagWireType(tag)) { + case WireFormatLite::WIRETYPE_VARINT: { + uint64 value; + if (!input->ReadVarint64(&value)) return false; + return true; + } + case WireFormatLite::WIRETYPE_FIXED64: { + uint64 value; + if (!input->ReadLittleEndian64(&value)) return false; + return true; + } + case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->Skip(length)) return false; + return true; + } + case WireFormatLite::WIRETYPE_START_GROUP: { + if (!input->IncrementRecursionDepth()) return false; + if (!SkipMessage(input)) return false; + input->DecrementRecursionDepth(); + // Check that the ending tag matched the starting tag. + if (!input->LastTagWas(WireFormatLite::MakeTag( + WireFormatLite::GetTagFieldNumber(tag), + WireFormatLite::WIRETYPE_END_GROUP))) { + return false; + } + return true; + } + case WireFormatLite::WIRETYPE_END_GROUP: { + return false; + } + case WireFormatLite::WIRETYPE_FIXED32: { + uint32 value; + if (!input->ReadLittleEndian32(&value)) return false; + return true; + } + default: { + return false; + } + } +} + +bool WireFormatLite::SkipMessage(io::CodedInputStream* input) { + while(true) { + uint32 tag = input->ReadTag(); + if (tag == 0) { + // End of input. This is a valid place to end, so return true. + return true; + } + + WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); + + if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { + // Must be the end of the message. + return true; + } + + if (!SkipField(input, tag)) return false; + } +} + +bool FieldSkipper::SkipField( + io::CodedInputStream* input, uint32 tag) { + return WireFormatLite::SkipField(input, tag); +} + +bool FieldSkipper::SkipMessage(io::CodedInputStream* input) { + return WireFormatLite::SkipMessage(input); +} + +void FieldSkipper::SkipUnknownEnum( + int field_number, int value) { + // Nothing. +} + +bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input, + bool (*is_valid)(int), + RepeatedField* values) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + int value; + if (!google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, WireFormatLite::TYPE_ENUM>(input, &value)) { + return false; + } + if (is_valid(value)) { + values->Add(value); + } + } + input->PopLimit(limit); + return true; +} + +void WireFormatLite::WriteInt32(int field_number, int32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteInt32NoTag(value, output); +} +void WireFormatLite::WriteInt64(int field_number, int64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteInt64NoTag(value, output); +} +void WireFormatLite::WriteUInt32(int field_number, uint32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteUInt32NoTag(value, output); +} +void WireFormatLite::WriteUInt64(int field_number, uint64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteUInt64NoTag(value, output); +} +void WireFormatLite::WriteSInt32(int field_number, int32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteSInt32NoTag(value, output); +} +void WireFormatLite::WriteSInt64(int field_number, int64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteSInt64NoTag(value, output); +} +void WireFormatLite::WriteFixed32(int field_number, uint32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteFixed32NoTag(value, output); +} +void WireFormatLite::WriteFixed64(int field_number, uint64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteFixed64NoTag(value, output); +} +void WireFormatLite::WriteSFixed32(int field_number, int32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteSFixed32NoTag(value, output); +} +void WireFormatLite::WriteSFixed64(int field_number, int64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteSFixed64NoTag(value, output); +} +void WireFormatLite::WriteFloat(int field_number, float value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteFloatNoTag(value, output); +} +void WireFormatLite::WriteDouble(int field_number, double value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteDoubleNoTag(value, output); +} +void WireFormatLite::WriteBool(int field_number, bool value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteBoolNoTag(value, output); +} +void WireFormatLite::WriteEnum(int field_number, int value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteEnumNoTag(value, output); +} + +void WireFormatLite::WriteString(int field_number, const string& value, + io::CodedOutputStream* output) { + // String is for UTF-8 text only + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + GOOGLE_CHECK(value.size() <= kint32max); + output->WriteVarint32(value.size()); + output->WriteString(value); +} +void WireFormatLite::WriteBytes(int field_number, const string& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + GOOGLE_CHECK(value.size() <= kint32max); + output->WriteVarint32(value.size()); + output->WriteString(value); +} + + +void WireFormatLite::WriteGroup(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_START_GROUP, output); + value.SerializeWithCachedSizes(output); + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} + +void WireFormatLite::WriteMessage(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + const int size = value.GetCachedSize(); + output->WriteVarint32(size); + value.SerializeWithCachedSizes(output); +} + +void WireFormatLite::WriteGroupMaybeToArray(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_START_GROUP, output); + const int size = value.GetCachedSize(); + uint8* target = output->GetDirectBufferForNBytesAndAdvance(size); + if (target != NULL) { + uint8* end = value.SerializeWithCachedSizesToArray(target); + GOOGLE_DCHECK_EQ(end - target, size); + } else { + value.SerializeWithCachedSizes(output); + } + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} + +void WireFormatLite::WriteMessageMaybeToArray(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + const int size = value.GetCachedSize(); + output->WriteVarint32(size); + uint8* target = output->GetDirectBufferForNBytesAndAdvance(size); + if (target != NULL) { + uint8* end = value.SerializeWithCachedSizesToArray(target); + GOOGLE_DCHECK_EQ(end - target, size); + } else { + value.SerializeWithCachedSizes(output); + } +} + +bool WireFormatLite::ReadString(io::CodedInputStream* input, + string* value) { + // String is for UTF-8 text only + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->InternalReadStringInline(value, length)) return false; + return true; +} +bool WireFormatLite::ReadBytes(io::CodedInputStream* input, + string* value) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + return input->InternalReadStringInline(value, length); +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite.h new file mode 100644 index 0000000..cb4fc91 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite.h @@ -0,0 +1,622 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// atenasio@google.com (Chris Atenasio) (ZigZag transform) +// wink@google.com (Wink Saville) (refactored from wire_format.h) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ +#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ + +#include +#include +#include +#include // for CodedOutputStream::Varint32Size + +namespace google { + +namespace protobuf { + template class RepeatedField; // repeated_field.h +} + +namespace protobuf { +namespace internal { + +class StringPieceField; + +// This class is for internal use by the protocol buffer library and by +// protocol-complier-generated message classes. It must not be called +// directly by clients. +// +// This class contains helpers for implementing the binary protocol buffer +// wire format without the need for reflection. Use WireFormat when using +// reflection. +// +// This class is really a namespace that contains only static methods. +class LIBPROTOBUF_EXPORT WireFormatLite { + public: + + // ----------------------------------------------------------------- + // Helper constants and functions related to the format. These are + // mostly meant for internal and generated code to use. + + // The wire format is composed of a sequence of tag/value pairs, each + // of which contains the value of one field (or one element of a repeated + // field). Each tag is encoded as a varint. The lower bits of the tag + // identify its wire type, which specifies the format of the data to follow. + // The rest of the bits contain the field number. Each type of field (as + // declared by FieldDescriptor::Type, in descriptor.h) maps to one of + // these wire types. Immediately following each tag is the field's value, + // encoded in the format specified by the wire type. Because the tag + // identifies the encoding of this data, it is possible to skip + // unrecognized fields for forwards compatibility. + + enum WireType { + WIRETYPE_VARINT = 0, + WIRETYPE_FIXED64 = 1, + WIRETYPE_LENGTH_DELIMITED = 2, + WIRETYPE_START_GROUP = 3, + WIRETYPE_END_GROUP = 4, + WIRETYPE_FIXED32 = 5, + }; + + // Lite alternative to FieldDescriptor::Type. Must be kept in sync. + enum FieldType { + TYPE_DOUBLE = 1, + TYPE_FLOAT = 2, + TYPE_INT64 = 3, + TYPE_UINT64 = 4, + TYPE_INT32 = 5, + TYPE_FIXED64 = 6, + TYPE_FIXED32 = 7, + TYPE_BOOL = 8, + TYPE_STRING = 9, + TYPE_GROUP = 10, + TYPE_MESSAGE = 11, + TYPE_BYTES = 12, + TYPE_UINT32 = 13, + TYPE_ENUM = 14, + TYPE_SFIXED32 = 15, + TYPE_SFIXED64 = 16, + TYPE_SINT32 = 17, + TYPE_SINT64 = 18, + MAX_FIELD_TYPE = 18, + }; + + // Lite alternative to FieldDescriptor::CppType. Must be kept in sync. + enum CppType { + CPPTYPE_INT32 = 1, + CPPTYPE_INT64 = 2, + CPPTYPE_UINT32 = 3, + CPPTYPE_UINT64 = 4, + CPPTYPE_DOUBLE = 5, + CPPTYPE_FLOAT = 6, + CPPTYPE_BOOL = 7, + CPPTYPE_ENUM = 8, + CPPTYPE_STRING = 9, + CPPTYPE_MESSAGE = 10, + MAX_CPPTYPE = 10, + }; + + // Helper method to get the CppType for a particular Type. + static CppType FieldTypeToCppType(FieldType type); + + // Given a FieldSescriptor::Type return its WireType + static inline WireFormatLite::WireType WireTypeForFieldType( + WireFormatLite::FieldType type) { + return kWireTypeForFieldType[type]; + } + + // Number of bits in a tag which identify the wire type. + static const int kTagTypeBits = 3; + // Mask for those bits. + static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1; + + // Helper functions for encoding and decoding tags. (Inlined below and in + // _inl.h) + // + // This is different from MakeTag(field->number(), field->type()) in the case + // of packed repeated fields. + static uint32 MakeTag(int field_number, WireType type); + static WireType GetTagWireType(uint32 tag); + static int GetTagFieldNumber(uint32 tag); + + // Compute the byte size of a tag. For groups, this includes both the start + // and end tags. + static inline int TagSize(int field_number, WireFormatLite::FieldType type); + + // Skips a field value with the given tag. The input should start + // positioned immediately after the tag. Skipped values are simply discarded, + // not recorded anywhere. See WireFormat::SkipField() for a version that + // records to an UnknownFieldSet. + static bool SkipField(io::CodedInputStream* input, uint32 tag); + + // Reads and ignores a message from the input. Skipped values are simply + // discarded, not recorded anywhere. See WireFormat::SkipMessage() for a + // version that records to an UnknownFieldSet. + static bool SkipMessage(io::CodedInputStream* input); + +// This macro does the same thing as WireFormatLite::MakeTag(), but the +// result is usable as a compile-time constant, which makes it usable +// as a switch case or a template input. WireFormatLite::MakeTag() is more +// type-safe, though, so prefer it if possible. +#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \ + static_cast( \ + ((FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \ + | (TYPE)) + + // These are the tags for the old MessageSet format, which was defined as: + // message MessageSet { + // repeated group Item = 1 { + // required int32 type_id = 2; + // required string message = 3; + // } + // } + static const int kMessageSetItemNumber = 1; + static const int kMessageSetTypeIdNumber = 2; + static const int kMessageSetMessageNumber = 3; + static const int kMessageSetItemStartTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, + WireFormatLite::WIRETYPE_START_GROUP); + static const int kMessageSetItemEndTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, + WireFormatLite::WIRETYPE_END_GROUP); + static const int kMessageSetTypeIdTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber, + WireFormatLite::WIRETYPE_VARINT); + static const int kMessageSetMessageTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + + // Byte size of all tags of a MessageSet::Item combined. + static const int kMessageSetItemTagsSize; + + // Helper functions for converting between floats/doubles and IEEE-754 + // uint32s/uint64s so that they can be written. (Assumes your platform + // uses IEEE-754 floats.) + static uint32 EncodeFloat(float value); + static float DecodeFloat(uint32 value); + static uint64 EncodeDouble(double value); + static double DecodeDouble(uint64 value); + + // Helper functions for mapping signed integers to unsigned integers in + // such a way that numbers with small magnitudes will encode to smaller + // varints. If you simply static_cast a negative number to an unsigned + // number and varint-encode it, it will always take 10 bytes, defeating + // the purpose of varint. So, for the "sint32" and "sint64" field types, + // we ZigZag-encode the values. + static uint32 ZigZagEncode32(int32 n); + static int32 ZigZagDecode32(uint32 n); + static uint64 ZigZagEncode64(int64 n); + static int64 ZigZagDecode64(uint64 n); + + // ================================================================= + // Methods for reading/writing individual field. The implementations + // of these methods are defined in wire_format_lite_inl.h; you must #include + // that file to use these. + +// Avoid ugly line wrapping +#define input io::CodedInputStream* input +#define output io::CodedOutputStream* output +#define field_number int field_number +#define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE + + // Read fields, not including tags. The assumption is that you already + // read the tag to determine what field to read. + + // For primitive fields, we just use a templatized routine parameterized by + // the represented type and the FieldType. These are specialized with the + // appropriate definition for each declared type. + template + static inline bool ReadPrimitive(input, CType* value) INL; + + // Reads repeated primitive values, with optimizations for repeats. + // tag_size and tag should both be compile-time constants provided by the + // protocol compiler. + template + static inline bool ReadRepeatedPrimitive(int tag_size, + uint32 tag, + input, + RepeatedField* value) INL; + + // Identical to ReadRepeatedPrimitive, except will not inline the + // implementation. + template + static bool ReadRepeatedPrimitiveNoInline(int tag_size, + uint32 tag, + input, + RepeatedField* value); + + // Reads a primitive value directly from the provided buffer. It returns a + // pointer past the segment of data that was read. + // + // This is only implemented for the types with fixed wire size, e.g. + // float, double, and the (s)fixed* types. + template + static inline const uint8* ReadPrimitiveFromArray(const uint8* buffer, + CType* value) INL; + + // Reads a primitive packed field. + // + // This is only implemented for packable types. + template + static inline bool ReadPackedPrimitive(input, + RepeatedField* value) INL; + + // Identical to ReadPackedPrimitive, except will not inline the + // implementation. + template + static bool ReadPackedPrimitiveNoInline(input, RepeatedField* value); + + // Read a packed enum field. Values for which is_valid() returns false are + // dropped. + static bool ReadPackedEnumNoInline(input, + bool (*is_valid)(int), + RepeatedField* value); + + static bool ReadString(input, string* value); + static bool ReadBytes (input, string* value); + + static inline bool ReadGroup (field_number, input, MessageLite* value); + static inline bool ReadMessage(input, MessageLite* value); + + // Like above, but de-virtualize the call to MergePartialFromCodedStream(). + // The pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override MergePartialFromCodedStream()). + template + static inline bool ReadGroupNoVirtual(field_number, input, + MessageType* value); + template + static inline bool ReadMessageNoVirtual(input, MessageType* value); + + // Write a tag. The Write*() functions typically include the tag, so + // normally there's no need to call this unless using the Write*NoTag() + // variants. + static inline void WriteTag(field_number, WireType type, output) INL; + + // Write fields, without tags. + static inline void WriteInt32NoTag (int32 value, output) INL; + static inline void WriteInt64NoTag (int64 value, output) INL; + static inline void WriteUInt32NoTag (uint32 value, output) INL; + static inline void WriteUInt64NoTag (uint64 value, output) INL; + static inline void WriteSInt32NoTag (int32 value, output) INL; + static inline void WriteSInt64NoTag (int64 value, output) INL; + static inline void WriteFixed32NoTag (uint32 value, output) INL; + static inline void WriteFixed64NoTag (uint64 value, output) INL; + static inline void WriteSFixed32NoTag(int32 value, output) INL; + static inline void WriteSFixed64NoTag(int64 value, output) INL; + static inline void WriteFloatNoTag (float value, output) INL; + static inline void WriteDoubleNoTag (double value, output) INL; + static inline void WriteBoolNoTag (bool value, output) INL; + static inline void WriteEnumNoTag (int value, output) INL; + + // Write fields, including tags. + static void WriteInt32 (field_number, int32 value, output); + static void WriteInt64 (field_number, int64 value, output); + static void WriteUInt32 (field_number, uint32 value, output); + static void WriteUInt64 (field_number, uint64 value, output); + static void WriteSInt32 (field_number, int32 value, output); + static void WriteSInt64 (field_number, int64 value, output); + static void WriteFixed32 (field_number, uint32 value, output); + static void WriteFixed64 (field_number, uint64 value, output); + static void WriteSFixed32(field_number, int32 value, output); + static void WriteSFixed64(field_number, int64 value, output); + static void WriteFloat (field_number, float value, output); + static void WriteDouble (field_number, double value, output); + static void WriteBool (field_number, bool value, output); + static void WriteEnum (field_number, int value, output); + + static void WriteString(field_number, const string& value, output); + static void WriteBytes (field_number, const string& value, output); + + static void WriteGroup( + field_number, const MessageLite& value, output); + static void WriteMessage( + field_number, const MessageLite& value, output); + // Like above, but these will check if the output stream has enough + // space to write directly to a flat array. + static void WriteGroupMaybeToArray( + field_number, const MessageLite& value, output); + static void WriteMessageMaybeToArray( + field_number, const MessageLite& value, output); + + // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override SerializeWithCachedSizes()). + template + static inline void WriteGroupNoVirtual( + field_number, const MessageType& value, output); + template + static inline void WriteMessageNoVirtual( + field_number, const MessageType& value, output); + +#undef output +#define output uint8* target + + // Like above, but use only *ToArray methods of CodedOutputStream. + static inline uint8* WriteTagToArray(field_number, WireType type, output) INL; + + // Write fields, without tags. + static inline uint8* WriteInt32NoTagToArray (int32 value, output) INL; + static inline uint8* WriteInt64NoTagToArray (int64 value, output) INL; + static inline uint8* WriteUInt32NoTagToArray (uint32 value, output) INL; + static inline uint8* WriteUInt64NoTagToArray (uint64 value, output) INL; + static inline uint8* WriteSInt32NoTagToArray (int32 value, output) INL; + static inline uint8* WriteSInt64NoTagToArray (int64 value, output) INL; + static inline uint8* WriteFixed32NoTagToArray (uint32 value, output) INL; + static inline uint8* WriteFixed64NoTagToArray (uint64 value, output) INL; + static inline uint8* WriteSFixed32NoTagToArray(int32 value, output) INL; + static inline uint8* WriteSFixed64NoTagToArray(int64 value, output) INL; + static inline uint8* WriteFloatNoTagToArray (float value, output) INL; + static inline uint8* WriteDoubleNoTagToArray (double value, output) INL; + static inline uint8* WriteBoolNoTagToArray (bool value, output) INL; + static inline uint8* WriteEnumNoTagToArray (int value, output) INL; + + // Write fields, including tags. + static inline uint8* WriteInt32ToArray( + field_number, int32 value, output) INL; + static inline uint8* WriteInt64ToArray( + field_number, int64 value, output) INL; + static inline uint8* WriteUInt32ToArray( + field_number, uint32 value, output) INL; + static inline uint8* WriteUInt64ToArray( + field_number, uint64 value, output) INL; + static inline uint8* WriteSInt32ToArray( + field_number, int32 value, output) INL; + static inline uint8* WriteSInt64ToArray( + field_number, int64 value, output) INL; + static inline uint8* WriteFixed32ToArray( + field_number, uint32 value, output) INL; + static inline uint8* WriteFixed64ToArray( + field_number, uint64 value, output) INL; + static inline uint8* WriteSFixed32ToArray( + field_number, int32 value, output) INL; + static inline uint8* WriteSFixed64ToArray( + field_number, int64 value, output) INL; + static inline uint8* WriteFloatToArray( + field_number, float value, output) INL; + static inline uint8* WriteDoubleToArray( + field_number, double value, output) INL; + static inline uint8* WriteBoolToArray( + field_number, bool value, output) INL; + static inline uint8* WriteEnumToArray( + field_number, int value, output) INL; + + static inline uint8* WriteStringToArray( + field_number, const string& value, output) INL; + static inline uint8* WriteBytesToArray( + field_number, const string& value, output) INL; + + static inline uint8* WriteGroupToArray( + field_number, const MessageLite& value, output) INL; + static inline uint8* WriteMessageToArray( + field_number, const MessageLite& value, output) INL; + + // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override SerializeWithCachedSizes()). + template + static inline uint8* WriteGroupNoVirtualToArray( + field_number, const MessageType& value, output) INL; + template + static inline uint8* WriteMessageNoVirtualToArray( + field_number, const MessageType& value, output) INL; + +#undef output +#undef input +#undef INL + +#undef field_number + + // Compute the byte size of a field. The XxSize() functions do NOT include + // the tag, so you must also call TagSize(). (This is because, for repeated + // fields, you should only call TagSize() once and multiply it by the element + // count, but you may have to call XxSize() for each individual element.) + static inline int Int32Size ( int32 value); + static inline int Int64Size ( int64 value); + static inline int UInt32Size (uint32 value); + static inline int UInt64Size (uint64 value); + static inline int SInt32Size ( int32 value); + static inline int SInt64Size ( int64 value); + static inline int EnumSize ( int value); + + // These types always have the same size. + static const int kFixed32Size = 4; + static const int kFixed64Size = 8; + static const int kSFixed32Size = 4; + static const int kSFixed64Size = 8; + static const int kFloatSize = 4; + static const int kDoubleSize = 8; + static const int kBoolSize = 1; + + static inline int StringSize(const string& value); + static inline int BytesSize (const string& value); + + static inline int GroupSize (const MessageLite& value); + static inline int MessageSize(const MessageLite& value); + + // Like above, but de-virtualize the call to ByteSize(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override ByteSize()). + template + static inline int GroupSizeNoVirtual (const MessageType& value); + template + static inline int MessageSizeNoVirtual(const MessageType& value); + + // Given the length of data, calculate the byte size of the data on the + // wire if we encode the data as a length delimited field. + static inline int LengthDelimitedSize(int length); + + private: + // A helper method for the repeated primitive reader. This method has + // optimizations for primitive types that have fixed size on the wire, and + // can be read using potentially faster paths. + template + static inline bool ReadRepeatedFixedSizePrimitive( + int tag_size, + uint32 tag, + google::protobuf::io::CodedInputStream* input, + RepeatedField* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + + static const CppType kFieldTypeToCppTypeMap[]; + static const WireFormatLite::WireType kWireTypeForFieldType[]; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite); +}; + +// A class which deals with unknown values. The default implementation just +// discards them. WireFormat defines a subclass which writes to an +// UnknownFieldSet. This class is used by ExtensionSet::ParseField(), since +// ExtensionSet is part of the lite library but UnknownFieldSet is not. +class LIBPROTOBUF_EXPORT FieldSkipper { + public: + FieldSkipper() {} + virtual ~FieldSkipper() {} + + // Skip a field whose tag has already been consumed. + virtual bool SkipField(io::CodedInputStream* input, uint32 tag); + + // Skip an entire message or group, up to an end-group tag (which is consumed) + // or end-of-stream. + virtual bool SkipMessage(io::CodedInputStream* input); + + // Deal with an already-parsed unrecognized enum value. The default + // implementation does nothing, but the UnknownFieldSet-based implementation + // saves it as an unknown varint. + virtual void SkipUnknownEnum(int field_number, int value); +}; + +// inline methods ==================================================== + +inline WireFormatLite::CppType +WireFormatLite::FieldTypeToCppType(FieldType type) { + return kFieldTypeToCppTypeMap[type]; +} + +inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) { + return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type); +} + +inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) { + return static_cast(tag & kTagTypeMask); +} + +inline int WireFormatLite::GetTagFieldNumber(uint32 tag) { + return static_cast(tag >> kTagTypeBits); +} + +inline int WireFormatLite::TagSize(int field_number, + WireFormatLite::FieldType type) { + int result = io::CodedOutputStream::VarintSize32( + field_number << kTagTypeBits); + if (type == TYPE_GROUP) { + // Groups have both a start and an end tag. + return result * 2; + } else { + return result; + } +} + +inline uint32 WireFormatLite::EncodeFloat(float value) { + union {float f; uint32 i;}; + f = value; + return i; +} + +inline float WireFormatLite::DecodeFloat(uint32 value) { + union {float f; uint32 i;}; + i = value; + return f; +} + +inline uint64 WireFormatLite::EncodeDouble(double value) { + union {double f; uint64 i;}; + f = value; + return i; +} + +inline double WireFormatLite::DecodeDouble(uint64 value) { + union {double f; uint64 i;}; + i = value; + return f; +} + +// ZigZag Transform: Encodes signed integers so that they can be +// effectively used with varint encoding. +// +// varint operates on unsigned integers, encoding smaller numbers into +// fewer bytes. If you try to use it on a signed integer, it will treat +// this number as a very large unsigned integer, which means that even +// small signed numbers like -1 will take the maximum number of bytes +// (10) to encode. ZigZagEncode() maps signed integers to unsigned +// in such a way that those with a small absolute value will have smaller +// encoded values, making them appropriate for encoding using varint. +// +// int32 -> uint32 +// ------------------------- +// 0 -> 0 +// -1 -> 1 +// 1 -> 2 +// -2 -> 3 +// ... -> ... +// 2147483647 -> 4294967294 +// -2147483648 -> 4294967295 +// +// >> encode >> +// << decode << + +inline uint32 WireFormatLite::ZigZagEncode32(int32 n) { + // Note: the right-shift must be arithmetic + return (n << 1) ^ (n >> 31); +} + +inline int32 WireFormatLite::ZigZagDecode32(uint32 n) { + return (n >> 1) ^ -static_cast(n & 1); +} + +inline uint64 WireFormatLite::ZigZagEncode64(int64 n) { + // Note: the right-shift must be arithmetic + return (n << 1) ^ (n >> 63); +} + +inline int64 WireFormatLite::ZigZagDecode64(uint64 n) { + return (n >> 1) ^ -static_cast(n & 1); +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite_inl.h b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite_inl.h new file mode 100644 index 0000000..641cc92 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_lite_inl.h @@ -0,0 +1,776 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// wink@google.com (Wink Saville) (refactored from wire_format.h) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ +#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ + +#include +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace internal { + +// Implementation details of ReadPrimitive. + +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int32* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = static_cast(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int64* value) { + uint64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = static_cast(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + uint32* value) { + return input->ReadVarint32(value); +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + uint64* value) { + return input->ReadVarint64(value); +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int32* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = ZigZagDecode32(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int64* value) { + uint64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = ZigZagDecode64(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + uint32* value) { + return input->ReadLittleEndian32(value); +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + uint64* value) { + return input->ReadLittleEndian64(value); +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int32* value) { + uint32 temp; + if (!input->ReadLittleEndian32(&temp)) return false; + *value = static_cast(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int64* value) { + uint64 temp; + if (!input->ReadLittleEndian64(&temp)) return false; + *value = static_cast(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + float* value) { + uint32 temp; + if (!input->ReadLittleEndian32(&temp)) return false; + *value = DecodeFloat(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + double* value) { + uint64 temp; + if (!input->ReadLittleEndian64(&temp)) return false; + *value = DecodeDouble(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + bool* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = temp != 0; + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = static_cast(temp); + return true; +} + +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + uint32, WireFormatLite::TYPE_FIXED32>( + const uint8* buffer, + uint32* value) { + return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value); +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + uint64, WireFormatLite::TYPE_FIXED64>( + const uint8* buffer, + uint64* value) { + return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value); +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + int32, WireFormatLite::TYPE_SFIXED32>( + const uint8* buffer, + int32* value) { + uint32 temp; + buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); + *value = static_cast(temp); + return buffer; +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + int64, WireFormatLite::TYPE_SFIXED64>( + const uint8* buffer, + int64* value) { + uint64 temp; + buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); + *value = static_cast(temp); + return buffer; +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + float, WireFormatLite::TYPE_FLOAT>( + const uint8* buffer, + float* value) { + uint32 temp; + buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); + *value = DecodeFloat(temp); + return buffer; +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + double, WireFormatLite::TYPE_DOUBLE>( + const uint8* buffer, + double* value) { + uint64 temp; + buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); + *value = DecodeDouble(temp); + return buffer; +} + +template +inline bool WireFormatLite::ReadRepeatedPrimitive(int, // tag_size, unused. + uint32 tag, + io::CodedInputStream* input, + RepeatedField* values) { + CType value; + if (!ReadPrimitive(input, &value)) return false; + values->Add(value); + int elements_already_reserved = values->Capacity() - values->size(); + while (elements_already_reserved > 0 && input->ExpectTag(tag)) { + if (!ReadPrimitive(input, &value)) return false; + values->AddAlreadyReserved(value); + elements_already_reserved--; + } + return true; +} + +template +inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive( + int tag_size, + uint32 tag, + io::CodedInputStream* input, + RepeatedField* values) { + GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size); + CType value; + if (!ReadPrimitive(input, &value)) + return false; + values->Add(value); + + // For fixed size values, repeated values can be read more quickly by + // reading directly from a raw array. + // + // We can get a tight loop by only reading as many elements as can be + // added to the RepeatedField without having to do any resizing. Additionally, + // we only try to read as many elements as are available from the current + // buffer space. Doing so avoids having to perform boundary checks when + // reading the value: the maximum number of elements that can be read is + // known outside of the loop. + const void* void_pointer; + int size; + input->GetDirectBufferPointerInline(&void_pointer, &size); + if (size > 0) { + const uint8* buffer = reinterpret_cast(void_pointer); + // The number of bytes each type occupies on the wire. + const int per_value_size = tag_size + sizeof(value); + + int elements_available = min(values->Capacity() - values->size(), + size / per_value_size); + int num_read = 0; + while (num_read < elements_available && + (buffer = io::CodedInputStream::ExpectTagFromArray( + buffer, tag)) != NULL) { + buffer = ReadPrimitiveFromArray(buffer, &value); + values->AddAlreadyReserved(value); + ++num_read; + } + const int read_bytes = num_read * per_value_size; + if (read_bytes > 0) { + input->Skip(read_bytes); + } + } + return true; +} + +// Specializations of ReadRepeatedPrimitive for the fixed size types, which use +// the optimized code path. +#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ +template <> \ +inline bool WireFormatLite::ReadRepeatedPrimitive< \ + CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ + int tag_size, \ + uint32 tag, \ + io::CodedInputStream* input, \ + RepeatedField* values) { \ + return ReadRepeatedFixedSizePrimitive< \ + CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ + tag_size, tag, input, values); \ +} + +READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) + +#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE + +template +bool WireFormatLite::ReadRepeatedPrimitiveNoInline( + int tag_size, + uint32 tag, + io::CodedInputStream* input, + RepeatedField* value) { + return ReadRepeatedPrimitive( + tag_size, tag, input, value); +} + +template +inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input, + RepeatedField* values) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + CType value; + if (!ReadPrimitive(input, &value)) return false; + values->Add(value); + } + input->PopLimit(limit); + return true; +} + +template +bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input, + RepeatedField* values) { + return ReadPackedPrimitive(input, values); +} + + +inline bool WireFormatLite::ReadGroup(int field_number, + io::CodedInputStream* input, + MessageLite* value) { + if (!input->IncrementRecursionDepth()) return false; + if (!value->MergePartialFromCodedStream(input)) return false; + input->DecrementRecursionDepth(); + // Make sure the last thing read was an end tag for this group. + if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { + return false; + } + return true; +} +inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, + MessageLite* value) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->IncrementRecursionDepth()) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + if (!value->MergePartialFromCodedStream(input)) return false; + // Make sure that parsing stopped when the limit was hit, not at an endgroup + // tag. + if (!input->ConsumedEntireMessage()) return false; + input->PopLimit(limit); + input->DecrementRecursionDepth(); + return true; +} + +// We name the template parameter something long and extremely unlikely to occur +// elsewhere because a *qualified* member access expression designed to avoid +// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the +// name of the qualifying class to be looked up both in the context of the full +// expression (finding the template parameter) and in the context of the object +// whose member we are accessing. This could potentially find a nested type +// within that object. The standard goes on to require these names to refer to +// the same entity, which this collision would violate. The lack of a safe way +// to avoid this collision appears to be a defect in the standard, but until it +// is corrected, we choose the name to avoid accidental collisions. +template +inline bool WireFormatLite::ReadGroupNoVirtual( + int field_number, io::CodedInputStream* input, + MessageType_WorkAroundCppLookupDefect* value) { + if (!input->IncrementRecursionDepth()) return false; + if (!value-> + MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) + return false; + input->DecrementRecursionDepth(); + // Make sure the last thing read was an end tag for this group. + if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { + return false; + } + return true; +} +template +inline bool WireFormatLite::ReadMessageNoVirtual( + io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->IncrementRecursionDepth()) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + if (!value-> + MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) + return false; + // Make sure that parsing stopped when the limit was hit, not at an endgroup + // tag. + if (!input->ConsumedEntireMessage()) return false; + input->PopLimit(limit); + input->DecrementRecursionDepth(); + return true; +} + +// =================================================================== + +inline void WireFormatLite::WriteTag(int field_number, WireType type, + io::CodedOutputStream* output) { + output->WriteTag(MakeTag(field_number, type)); +} + +inline void WireFormatLite::WriteInt32NoTag(int32 value, + io::CodedOutputStream* output) { + output->WriteVarint32SignExtended(value); +} +inline void WireFormatLite::WriteInt64NoTag(int64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(static_cast(value)); +} +inline void WireFormatLite::WriteUInt32NoTag(uint32 value, + io::CodedOutputStream* output) { + output->WriteVarint32(value); +} +inline void WireFormatLite::WriteUInt64NoTag(uint64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(value); +} +inline void WireFormatLite::WriteSInt32NoTag(int32 value, + io::CodedOutputStream* output) { + output->WriteVarint32(ZigZagEncode32(value)); +} +inline void WireFormatLite::WriteSInt64NoTag(int64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(ZigZagEncode64(value)); +} +inline void WireFormatLite::WriteFixed32NoTag(uint32 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(value); +} +inline void WireFormatLite::WriteFixed64NoTag(uint64 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(value); +} +inline void WireFormatLite::WriteSFixed32NoTag(int32 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(static_cast(value)); +} +inline void WireFormatLite::WriteSFixed64NoTag(int64 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(static_cast(value)); +} +inline void WireFormatLite::WriteFloatNoTag(float value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(EncodeFloat(value)); +} +inline void WireFormatLite::WriteDoubleNoTag(double value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(EncodeDouble(value)); +} +inline void WireFormatLite::WriteBoolNoTag(bool value, + io::CodedOutputStream* output) { + output->WriteVarint32(value ? 1 : 0); +} +inline void WireFormatLite::WriteEnumNoTag(int value, + io::CodedOutputStream* output) { + output->WriteVarint32SignExtended(value); +} + +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template +inline void WireFormatLite::WriteGroupNoVirtual( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_START_GROUP, output); + value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} +template +inline void WireFormatLite::WriteMessageNoVirtual( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32( + value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()); + value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); +} + +// =================================================================== + +inline uint8* WireFormatLite::WriteTagToArray(int field_number, + WireType type, + uint8* target) { + return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type), + target); +} + +inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); +} +inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint64ToArray( + static_cast(value), target); +} +inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32ToArray(value, target); +} +inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint64ToArray(value, target); +} +inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value), + target); +} +inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value), + target); +} +inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target); +} +inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target); +} +inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray( + static_cast(value), target); +} +inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray( + static_cast(value), target); +} +inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value), + target); +} +inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value), + target); +} +inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target); +} +inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); +} + +inline uint8* WireFormatLite::WriteInt32ToArray(int field_number, + int32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteInt32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteInt64ToArray(int field_number, + int64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteInt64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number, + uint32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteUInt32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number, + uint64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteUInt64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number, + int32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteSInt32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number, + int64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteSInt64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number, + uint32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteFixed32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number, + uint64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteFixed64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number, + int32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteSFixed32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number, + int64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteSFixed64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteFloatToArray(int field_number, + float value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteFloatNoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteDoubleToArray(int field_number, + double value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteDoubleNoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteBoolToArray(int field_number, + bool value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteBoolNoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteEnumToArray(int field_number, + int value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteEnumNoTagToArray(value, target); +} + +inline uint8* WireFormatLite::WriteStringToArray(int field_number, + const string& value, + uint8* target) { + // String is for UTF-8 text only + // WARNING: In wire_format.cc, both strings and bytes are handled by + // WriteString() to avoid code duplication. If the implementations become + // different, you will need to update that usage. + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); + return io::CodedOutputStream::WriteStringToArray(value, target); +} +inline uint8* WireFormatLite::WriteBytesToArray(int field_number, + const string& value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target); + return io::CodedOutputStream::WriteStringToArray(value, target); +} + + +inline uint8* WireFormatLite::WriteGroupToArray(int field_number, + const MessageLite& value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); + target = value.SerializeWithCachedSizesToArray(target); + return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); +} +inline uint8* WireFormatLite::WriteMessageToArray(int field_number, + const MessageLite& value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray( + value.GetCachedSize(), target); + return value.SerializeWithCachedSizesToArray(target); +} + +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template +inline uint8* WireFormatLite::WriteGroupNoVirtualToArray( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); + target = value.MessageType_WorkAroundCppLookupDefect + ::SerializeWithCachedSizesToArray(target); + return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); +} +template +inline uint8* WireFormatLite::WriteMessageNoVirtualToArray( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray( + value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target); + return value.MessageType_WorkAroundCppLookupDefect + ::SerializeWithCachedSizesToArray(target); +} + +// =================================================================== + +inline int WireFormatLite::Int32Size(int32 value) { + return io::CodedOutputStream::VarintSize32SignExtended(value); +} +inline int WireFormatLite::Int64Size(int64 value) { + return io::CodedOutputStream::VarintSize64(static_cast(value)); +} +inline int WireFormatLite::UInt32Size(uint32 value) { + return io::CodedOutputStream::VarintSize32(value); +} +inline int WireFormatLite::UInt64Size(uint64 value) { + return io::CodedOutputStream::VarintSize64(value); +} +inline int WireFormatLite::SInt32Size(int32 value) { + return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); +} +inline int WireFormatLite::SInt64Size(int64 value) { + return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); +} +inline int WireFormatLite::EnumSize(int value) { + return io::CodedOutputStream::VarintSize32SignExtended(value); +} + +inline int WireFormatLite::StringSize(const string& value) { + return io::CodedOutputStream::VarintSize32(value.size()) + + value.size(); +} +inline int WireFormatLite::BytesSize(const string& value) { + return io::CodedOutputStream::VarintSize32(value.size()) + + value.size(); +} + + +inline int WireFormatLite::GroupSize(const MessageLite& value) { + return value.ByteSize(); +} +inline int WireFormatLite::MessageSize(const MessageLite& value) { + return LengthDelimitedSize(value.ByteSize()); +} + +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template +inline int WireFormatLite::GroupSizeNoVirtual( + const MessageType_WorkAroundCppLookupDefect& value) { + return value.MessageType_WorkAroundCppLookupDefect::ByteSize(); +} +template +inline int WireFormatLite::MessageSizeNoVirtual( + const MessageType_WorkAroundCppLookupDefect& value) { + return LengthDelimitedSize( + value.MessageType_WorkAroundCppLookupDefect::ByteSize()); +} + +inline int WireFormatLite::LengthDelimitedSize(int length) { + return io::CodedOutputStream::VarintSize32(length) + length; +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ diff --git a/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_unittest.cc b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_unittest.cc new file mode 100644 index 0000000..9822828 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/google/protobuf/wire_format_unittest.cc @@ -0,0 +1,978 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { +namespace { + +TEST(WireFormatTest, EnumsInSync) { + // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match + // FieldDescriptor::Type and FieldDescriptor::CppType. + + EXPECT_EQ(implicit_cast(FieldDescriptor::MAX_TYPE), + implicit_cast(WireFormatLite::MAX_FIELD_TYPE)); + EXPECT_EQ(implicit_cast(FieldDescriptor::MAX_CPPTYPE), + implicit_cast(WireFormatLite::MAX_CPPTYPE)); + + for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) { + EXPECT_EQ( + implicit_cast(FieldDescriptor::TypeToCppType( + static_cast(i))), + implicit_cast(WireFormatLite::FieldTypeToCppType( + static_cast(i)))); + } +} + +TEST(WireFormatTest, MaxFieldNumber) { + // Make sure the max field number constant is accurate. + EXPECT_EQ((1 << (32 - WireFormatLite::kTagTypeBits)) - 1, + FieldDescriptor::kMaxNumber); +} + +TEST(WireFormatTest, Parse) { + unittest::TestAllTypes source, dest; + string data; + + // Serialize using the generated code. + TestUtil::SetAllFields(&source); + source.SerializeToString(&data); + + // Parse using WireFormat. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectAllFieldsSet(dest); +} + +TEST(WireFormatTest, ParseExtensions) { + unittest::TestAllExtensions source, dest; + string data; + + // Serialize using the generated code. + TestUtil::SetAllExtensions(&source); + source.SerializeToString(&data); + + // Parse using WireFormat. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectAllExtensionsSet(dest); +} + +TEST(WireFormatTest, ParsePacked) { + unittest::TestPackedTypes source, dest; + string data; + + // Serialize using the generated code. + TestUtil::SetPackedFields(&source); + source.SerializeToString(&data); + + // Parse using WireFormat. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectPackedFieldsSet(dest); +} + +TEST(WireFormatTest, ParsePackedFromUnpacked) { + // Serialize using the generated code. + unittest::TestUnpackedTypes source; + TestUtil::SetUnpackedFields(&source); + string data = source.SerializeAsString(); + + // Parse using WireFormat. + unittest::TestPackedTypes dest; + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectPackedFieldsSet(dest); +} + +TEST(WireFormatTest, ParseUnpackedFromPacked) { + // Serialize using the generated code. + unittest::TestPackedTypes source; + TestUtil::SetPackedFields(&source); + string data = source.SerializeAsString(); + + // Parse using WireFormat. + unittest::TestUnpackedTypes dest; + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectUnpackedFieldsSet(dest); +} + +TEST(WireFormatTest, ParsePackedExtensions) { + unittest::TestPackedExtensions source, dest; + string data; + + // Serialize using the generated code. + TestUtil::SetPackedExtensions(&source); + source.SerializeToString(&data); + + // Parse using WireFormat. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectPackedExtensionsSet(dest); +} + +TEST(WireFormatTest, ByteSize) { + unittest::TestAllTypes message; + TestUtil::SetAllFields(&message); + + EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message)); + message.Clear(); + EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, WireFormat::ByteSize(message)); +} + +TEST(WireFormatTest, ByteSizeExtensions) { + unittest::TestAllExtensions message; + TestUtil::SetAllExtensions(&message); + + EXPECT_EQ(message.ByteSize(), + WireFormat::ByteSize(message)); + message.Clear(); + EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, WireFormat::ByteSize(message)); +} + +TEST(WireFormatTest, ByteSizePacked) { + unittest::TestPackedTypes message; + TestUtil::SetPackedFields(&message); + + EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message)); + message.Clear(); + EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, WireFormat::ByteSize(message)); +} + +TEST(WireFormatTest, ByteSizePackedExtensions) { + unittest::TestPackedExtensions message; + TestUtil::SetPackedExtensions(&message); + + EXPECT_EQ(message.ByteSize(), + WireFormat::ByteSize(message)); + message.Clear(); + EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, WireFormat::ByteSize(message)); +} + +TEST(WireFormatTest, Serialize) { + unittest::TestAllTypes message; + string generated_data; + string dynamic_data; + + TestUtil::SetAllFields(&message); + int size = message.ByteSize(); + + // Serialize using the generated code. + { + io::StringOutputStream raw_output(&generated_data); + io::CodedOutputStream output(&raw_output); + message.SerializeWithCachedSizes(&output); + ASSERT_FALSE(output.HadError()); + } + + // Serialize using WireFormat. + { + io::StringOutputStream raw_output(&dynamic_data); + io::CodedOutputStream output(&raw_output); + WireFormat::SerializeWithCachedSizes(message, size, &output); + ASSERT_FALSE(output.HadError()); + } + + // Should be the same. + // Don't use EXPECT_EQ here because we're comparing raw binary data and + // we really don't want it dumped to stdout on failure. + EXPECT_TRUE(dynamic_data == generated_data); +} + +TEST(WireFormatTest, SerializeExtensions) { + unittest::TestAllExtensions message; + string generated_data; + string dynamic_data; + + TestUtil::SetAllExtensions(&message); + int size = message.ByteSize(); + + // Serialize using the generated code. + { + io::StringOutputStream raw_output(&generated_data); + io::CodedOutputStream output(&raw_output); + message.SerializeWithCachedSizes(&output); + ASSERT_FALSE(output.HadError()); + } + + // Serialize using WireFormat. + { + io::StringOutputStream raw_output(&dynamic_data); + io::CodedOutputStream output(&raw_output); + WireFormat::SerializeWithCachedSizes(message, size, &output); + ASSERT_FALSE(output.HadError()); + } + + // Should be the same. + // Don't use EXPECT_EQ here because we're comparing raw binary data and + // we really don't want it dumped to stdout on failure. + EXPECT_TRUE(dynamic_data == generated_data); +} + +TEST(WireFormatTest, SerializeFieldsAndExtensions) { + unittest::TestFieldOrderings message; + string generated_data; + string dynamic_data; + + TestUtil::SetAllFieldsAndExtensions(&message); + int size = message.ByteSize(); + + // Serialize using the generated code. + { + io::StringOutputStream raw_output(&generated_data); + io::CodedOutputStream output(&raw_output); + message.SerializeWithCachedSizes(&output); + ASSERT_FALSE(output.HadError()); + } + + // Serialize using WireFormat. + { + io::StringOutputStream raw_output(&dynamic_data); + io::CodedOutputStream output(&raw_output); + WireFormat::SerializeWithCachedSizes(message, size, &output); + ASSERT_FALSE(output.HadError()); + } + + // Should be the same. + // Don't use EXPECT_EQ here because we're comparing raw binary data and + // we really don't want it dumped to stdout on failure. + EXPECT_TRUE(dynamic_data == generated_data); + + // Should output in canonical order. + TestUtil::ExpectAllFieldsAndExtensionsInOrder(dynamic_data); + TestUtil::ExpectAllFieldsAndExtensionsInOrder(generated_data); +} + +TEST(WireFormatTest, ParseMultipleExtensionRanges) { + // Make sure we can parse a message that contains multiple extensions ranges. + unittest::TestFieldOrderings source; + string data; + + TestUtil::SetAllFieldsAndExtensions(&source); + source.SerializeToString(&data); + + { + unittest::TestFieldOrderings dest; + EXPECT_TRUE(dest.ParseFromString(data)); + EXPECT_EQ(source.DebugString(), dest.DebugString()); + } + + // Also test using reflection-based parsing. + { + unittest::TestFieldOrderings dest; + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream coded_input(&raw_input); + EXPECT_TRUE(WireFormat::ParseAndMergePartial(&coded_input, &dest)); + EXPECT_EQ(source.DebugString(), dest.DebugString()); + } +} + +const int kUnknownTypeId = 1550055; + +TEST(WireFormatTest, SerializeMessageSet) { + // Set up a TestMessageSet with two known messages and an unknown one. + unittest::TestMessageSet message_set; + message_set.MutableExtension( + unittest::TestMessageSetExtension1::message_set_extension)->set_i(123); + message_set.MutableExtension( + unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo"); + message_set.mutable_unknown_fields()->AddLengthDelimited( + kUnknownTypeId, "bar"); + + string data; + ASSERT_TRUE(message_set.SerializeToString(&data)); + + // Parse back using RawMessageSet and check the contents. + unittest::RawMessageSet raw; + ASSERT_TRUE(raw.ParseFromString(data)); + + EXPECT_EQ(0, raw.unknown_fields().field_count()); + + ASSERT_EQ(3, raw.item_size()); + EXPECT_EQ( + unittest::TestMessageSetExtension1::descriptor()->extension(0)->number(), + raw.item(0).type_id()); + EXPECT_EQ( + unittest::TestMessageSetExtension2::descriptor()->extension(0)->number(), + raw.item(1).type_id()); + EXPECT_EQ(kUnknownTypeId, raw.item(2).type_id()); + + unittest::TestMessageSetExtension1 message1; + EXPECT_TRUE(message1.ParseFromString(raw.item(0).message())); + EXPECT_EQ(123, message1.i()); + + unittest::TestMessageSetExtension2 message2; + EXPECT_TRUE(message2.ParseFromString(raw.item(1).message())); + EXPECT_EQ("foo", message2.str()); + + EXPECT_EQ("bar", raw.item(2).message()); +} + +TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) { + // Serialize a MessageSet to a stream and to a flat array using generated + // code, and also using WireFormat, and check that the results are equal. + // Set up a TestMessageSet with two known messages and an unknown one, as + // above. + + unittest::TestMessageSet message_set; + message_set.MutableExtension( + unittest::TestMessageSetExtension1::message_set_extension)->set_i(123); + message_set.MutableExtension( + unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo"); + message_set.mutable_unknown_fields()->AddLengthDelimited( + kUnknownTypeId, "bar"); + + int size = message_set.ByteSize(); + EXPECT_EQ(size, message_set.GetCachedSize()); + ASSERT_EQ(size, WireFormat::ByteSize(message_set)); + + string flat_data; + string stream_data; + string dynamic_data; + flat_data.resize(size); + stream_data.resize(size); + + // Serialize to flat array + { + uint8* target = reinterpret_cast(string_as_array(&flat_data)); + uint8* end = message_set.SerializeWithCachedSizesToArray(target); + EXPECT_EQ(size, end - target); + } + + // Serialize to buffer + { + io::ArrayOutputStream array_stream(string_as_array(&stream_data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message_set.SerializeWithCachedSizes(&output_stream); + ASSERT_FALSE(output_stream.HadError()); + } + + // Serialize to buffer with WireFormat. + { + io::StringOutputStream string_stream(&dynamic_data); + io::CodedOutputStream output_stream(&string_stream); + WireFormat::SerializeWithCachedSizes(message_set, size, &output_stream); + ASSERT_FALSE(output_stream.HadError()); + } + + EXPECT_TRUE(flat_data == stream_data); + EXPECT_TRUE(flat_data == dynamic_data); +} + +TEST(WireFormatTest, ParseMessageSet) { + // Set up a RawMessageSet with two known messages and an unknown one. + unittest::RawMessageSet raw; + + { + unittest::RawMessageSet::Item* item = raw.add_item(); + item->set_type_id( + unittest::TestMessageSetExtension1::descriptor()->extension(0)->number()); + unittest::TestMessageSetExtension1 message; + message.set_i(123); + message.SerializeToString(item->mutable_message()); + } + + { + unittest::RawMessageSet::Item* item = raw.add_item(); + item->set_type_id( + unittest::TestMessageSetExtension2::descriptor()->extension(0)->number()); + unittest::TestMessageSetExtension2 message; + message.set_str("foo"); + message.SerializeToString(item->mutable_message()); + } + + { + unittest::RawMessageSet::Item* item = raw.add_item(); + item->set_type_id(kUnknownTypeId); + item->set_message("bar"); + } + + string data; + ASSERT_TRUE(raw.SerializeToString(&data)); + + // Parse as a TestMessageSet and check the contents. + unittest::TestMessageSet message_set; + ASSERT_TRUE(message_set.ParseFromString(data)); + + EXPECT_EQ(123, message_set.GetExtension( + unittest::TestMessageSetExtension1::message_set_extension).i()); + EXPECT_EQ("foo", message_set.GetExtension( + unittest::TestMessageSetExtension2::message_set_extension).str()); + + ASSERT_EQ(1, message_set.unknown_fields().field_count()); + ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED, + message_set.unknown_fields().field(0).type()); + EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited()); + + // Also parse using WireFormat. + unittest::TestMessageSet dynamic_message_set; + io::CodedInputStream input(reinterpret_cast(data.data()), + data.size()); + ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set)); + EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString()); +} + +TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) { + string data; + { + unittest::TestMessageSetExtension1 message; + message.set_i(123); + // Build a MessageSet manually with its message content put before its + // type_id. + io::StringOutputStream output_stream(&data); + io::CodedOutputStream coded_output(&output_stream); + coded_output.WriteTag(WireFormatLite::kMessageSetItemStartTag); + // Write the message content first. + WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + &coded_output); + coded_output.WriteVarint32(message.ByteSize()); + message.SerializeWithCachedSizes(&coded_output); + // Write the type id. + uint32 type_id = message.GetDescriptor()->extension(0)->number(); + WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber, + type_id, &coded_output); + coded_output.WriteTag(WireFormatLite::kMessageSetItemEndTag); + } + { + unittest::TestMessageSet message_set; + ASSERT_TRUE(message_set.ParseFromString(data)); + + EXPECT_EQ(123, message_set.GetExtension( + unittest::TestMessageSetExtension1::message_set_extension).i()); + } + { + // Test parse the message via Reflection. + unittest::TestMessageSet message_set; + io::CodedInputStream input( + reinterpret_cast(data.data()), data.size()); + EXPECT_TRUE(WireFormat::ParseAndMergePartial(&input, &message_set)); + EXPECT_TRUE(input.ConsumedEntireMessage()); + + EXPECT_EQ(123, message_set.GetExtension( + unittest::TestMessageSetExtension1::message_set_extension).i()); + } +} + +TEST(WireFormatTest, ParseBrokenMessageSet) { + unittest::TestMessageSet message_set; + string input("goodbye"); // Invalid wire format data. + EXPECT_FALSE(message_set.ParseFromString(input)); +} + +TEST(WireFormatTest, RecursionLimit) { + unittest::TestRecursiveMessage message; + message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1); + string data; + message.SerializeToString(&data); + + { + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetRecursionLimit(4); + unittest::TestRecursiveMessage message2; + EXPECT_TRUE(message2.ParseFromCodedStream(&input)); + } + + { + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetRecursionLimit(3); + unittest::TestRecursiveMessage message2; + EXPECT_FALSE(message2.ParseFromCodedStream(&input)); + } +} + +TEST(WireFormatTest, UnknownFieldRecursionLimit) { + unittest::TestEmptyMessage message; + message.mutable_unknown_fields() + ->AddGroup(1234) + ->AddGroup(1234) + ->AddGroup(1234) + ->AddGroup(1234) + ->AddVarint(1234, 123); + string data; + message.SerializeToString(&data); + + { + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetRecursionLimit(4); + unittest::TestEmptyMessage message2; + EXPECT_TRUE(message2.ParseFromCodedStream(&input)); + } + + { + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetRecursionLimit(3); + unittest::TestEmptyMessage message2; + EXPECT_FALSE(message2.ParseFromCodedStream(&input)); + } +} + +TEST(WireFormatTest, ZigZag) { +// avoid line-wrapping +#define LL(x) GOOGLE_LONGLONG(x) +#define ULL(x) GOOGLE_ULONGLONG(x) +#define ZigZagEncode32(x) WireFormatLite::ZigZagEncode32(x) +#define ZigZagDecode32(x) WireFormatLite::ZigZagDecode32(x) +#define ZigZagEncode64(x) WireFormatLite::ZigZagEncode64(x) +#define ZigZagDecode64(x) WireFormatLite::ZigZagDecode64(x) + + EXPECT_EQ(0u, ZigZagEncode32( 0)); + EXPECT_EQ(1u, ZigZagEncode32(-1)); + EXPECT_EQ(2u, ZigZagEncode32( 1)); + EXPECT_EQ(3u, ZigZagEncode32(-2)); + EXPECT_EQ(0x7FFFFFFEu, ZigZagEncode32(0x3FFFFFFF)); + EXPECT_EQ(0x7FFFFFFFu, ZigZagEncode32(0xC0000000)); + EXPECT_EQ(0xFFFFFFFEu, ZigZagEncode32(0x7FFFFFFF)); + EXPECT_EQ(0xFFFFFFFFu, ZigZagEncode32(0x80000000)); + + EXPECT_EQ( 0, ZigZagDecode32(0u)); + EXPECT_EQ(-1, ZigZagDecode32(1u)); + EXPECT_EQ( 1, ZigZagDecode32(2u)); + EXPECT_EQ(-2, ZigZagDecode32(3u)); + EXPECT_EQ(0x3FFFFFFF, ZigZagDecode32(0x7FFFFFFEu)); + EXPECT_EQ(0xC0000000, ZigZagDecode32(0x7FFFFFFFu)); + EXPECT_EQ(0x7FFFFFFF, ZigZagDecode32(0xFFFFFFFEu)); + EXPECT_EQ(0x80000000, ZigZagDecode32(0xFFFFFFFFu)); + + EXPECT_EQ(0u, ZigZagEncode64( 0)); + EXPECT_EQ(1u, ZigZagEncode64(-1)); + EXPECT_EQ(2u, ZigZagEncode64( 1)); + EXPECT_EQ(3u, ZigZagEncode64(-2)); + EXPECT_EQ(ULL(0x000000007FFFFFFE), ZigZagEncode64(LL(0x000000003FFFFFFF))); + EXPECT_EQ(ULL(0x000000007FFFFFFF), ZigZagEncode64(LL(0xFFFFFFFFC0000000))); + EXPECT_EQ(ULL(0x00000000FFFFFFFE), ZigZagEncode64(LL(0x000000007FFFFFFF))); + EXPECT_EQ(ULL(0x00000000FFFFFFFF), ZigZagEncode64(LL(0xFFFFFFFF80000000))); + EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFE), ZigZagEncode64(LL(0x7FFFFFFFFFFFFFFF))); + EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFF), ZigZagEncode64(LL(0x8000000000000000))); + + EXPECT_EQ( 0, ZigZagDecode64(0u)); + EXPECT_EQ(-1, ZigZagDecode64(1u)); + EXPECT_EQ( 1, ZigZagDecode64(2u)); + EXPECT_EQ(-2, ZigZagDecode64(3u)); + EXPECT_EQ(LL(0x000000003FFFFFFF), ZigZagDecode64(ULL(0x000000007FFFFFFE))); + EXPECT_EQ(LL(0xFFFFFFFFC0000000), ZigZagDecode64(ULL(0x000000007FFFFFFF))); + EXPECT_EQ(LL(0x000000007FFFFFFF), ZigZagDecode64(ULL(0x00000000FFFFFFFE))); + EXPECT_EQ(LL(0xFFFFFFFF80000000), ZigZagDecode64(ULL(0x00000000FFFFFFFF))); + EXPECT_EQ(LL(0x7FFFFFFFFFFFFFFF), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFE))); + EXPECT_EQ(LL(0x8000000000000000), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFF))); + + // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1) + // were chosen semi-randomly via keyboard bashing. + EXPECT_EQ( 0, ZigZagDecode32(ZigZagEncode32( 0))); + EXPECT_EQ( 1, ZigZagDecode32(ZigZagEncode32( 1))); + EXPECT_EQ( -1, ZigZagDecode32(ZigZagEncode32( -1))); + EXPECT_EQ(14927, ZigZagDecode32(ZigZagEncode32(14927))); + EXPECT_EQ(-3612, ZigZagDecode32(ZigZagEncode32(-3612))); + + EXPECT_EQ( 0, ZigZagDecode64(ZigZagEncode64( 0))); + EXPECT_EQ( 1, ZigZagDecode64(ZigZagEncode64( 1))); + EXPECT_EQ( -1, ZigZagDecode64(ZigZagEncode64( -1))); + EXPECT_EQ(14927, ZigZagDecode64(ZigZagEncode64(14927))); + EXPECT_EQ(-3612, ZigZagDecode64(ZigZagEncode64(-3612))); + + EXPECT_EQ(LL(856912304801416), ZigZagDecode64(ZigZagEncode64( + LL(856912304801416)))); + EXPECT_EQ(LL(-75123905439571256), ZigZagDecode64(ZigZagEncode64( + LL(-75123905439571256)))); +} + +TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) { + // At one point checks would trigger when parsing repeated fixed scalar + // fields. + protobuf_unittest::TestRepeatedScalarDifferentTagSizes msg1, msg2; + for (int i = 0; i < 100; ++i) { + msg1.add_repeated_fixed32(i); + msg1.add_repeated_int32(i); + msg1.add_repeated_fixed64(i); + msg1.add_repeated_int64(i); + msg1.add_repeated_float(i); + msg1.add_repeated_uint64(i); + } + + // Make sure that we have a variety of tag sizes. + const google::protobuf::Descriptor* desc = msg1.GetDescriptor(); + const google::protobuf::FieldDescriptor* field; + field = desc->FindFieldByName("repeated_fixed32"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_int32"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_fixed64"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_int64"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_float"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_uint64"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type())); + + EXPECT_TRUE(msg2.ParseFromString(msg1.SerializeAsString())); + EXPECT_EQ(msg1.DebugString(), msg2.DebugString()); +} + +class WireFormatInvalidInputTest : public testing::Test { + protected: + // Make a serialized TestAllTypes in which the field optional_nested_message + // contains exactly the given bytes, which may be invalid. + string MakeInvalidEmbeddedMessage(const char* bytes, int size) { + const FieldDescriptor* field = + unittest::TestAllTypes::descriptor()->FindFieldByName( + "optional_nested_message"); + GOOGLE_CHECK(field != NULL); + + string result; + + { + io::StringOutputStream raw_output(&result); + io::CodedOutputStream output(&raw_output); + + WireFormatLite::WriteBytes(field->number(), string(bytes, size), &output); + } + + return result; + } + + // Make a serialized TestAllTypes in which the field optionalgroup + // contains exactly the given bytes -- which may be invalid -- and + // possibly no end tag. + string MakeInvalidGroup(const char* bytes, int size, bool include_end_tag) { + const FieldDescriptor* field = + unittest::TestAllTypes::descriptor()->FindFieldByName( + "optionalgroup"); + GOOGLE_CHECK(field != NULL); + + string result; + + { + io::StringOutputStream raw_output(&result); + io::CodedOutputStream output(&raw_output); + + output.WriteVarint32(WireFormat::MakeTag(field)); + output.WriteString(string(bytes, size)); + if (include_end_tag) { + output.WriteVarint32(WireFormatLite::MakeTag( + field->number(), WireFormatLite::WIRETYPE_END_GROUP)); + } + } + + return result; + } +}; + +TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) { + unittest::TestAllTypes message; + + // Control case. + EXPECT_TRUE(message.ParseFromString(MakeInvalidEmbeddedMessage("", 0))); + + // The byte is a valid varint, but not a valid tag (zero). + EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\0", 1))); + + // The byte is a malformed varint. + EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\200", 1))); + + // The byte is an endgroup tag, but we aren't parsing a group. + EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\014", 1))); + + // The byte is a valid varint but not a valid tag (bad wire type). + EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1))); +} + +TEST_F(WireFormatInvalidInputTest, InvalidGroup) { + unittest::TestAllTypes message; + + // Control case. + EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true))); + + // Missing end tag. Groups cannot end at EOF. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false))); + + // The byte is a valid varint, but not a valid tag (zero). + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false))); + + // The byte is a malformed varint. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false))); + + // The byte is an endgroup tag, but not the right one for this group. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false))); + + // The byte is a valid varint but not a valid tag (bad wire type). + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true))); +} + +TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) { + // Use TestEmptyMessage so that the group made by MakeInvalidGroup will not + // be a known tag number. + unittest::TestEmptyMessage message; + + // Control case. + EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true))); + + // Missing end tag. Groups cannot end at EOF. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false))); + + // The byte is a valid varint, but not a valid tag (zero). + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false))); + + // The byte is a malformed varint. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false))); + + // The byte is an endgroup tag, but not the right one for this group. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false))); + + // The byte is a valid varint but not a valid tag (bad wire type). + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true))); +} + +TEST_F(WireFormatInvalidInputTest, InvalidStringInUnknownGroup) { + // Test a bug fix: SkipMessage should fail if the message contains a string + // whose length would extend beyond the message end. + + unittest::TestAllTypes message; + message.set_optional_string("foo foo foo foo"); + string data; + message.SerializeToString(&data); + + // Chop some bytes off the end. + data.resize(data.size() - 4); + + // Try to skip it. Note that the bug was only present when parsing to an + // UnknownFieldSet. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream coded_input(&raw_input); + UnknownFieldSet unknown_fields; + EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields)); +} + +// Test differences between string and bytes. +// Value of a string type must be valid UTF-8 string. When UTF-8 +// validation is enabled (GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED): +// WriteInvalidUTF8String: see error message. +// ReadInvalidUTF8String: see error message. +// WriteValidUTF8String: fine. +// ReadValidUTF8String: fine. +// WriteAnyBytes: fine. +// ReadAnyBytes: fine. +const char * kInvalidUTF8String = "Invalid UTF-8: \xA0\xB0\xC0\xD0"; +// This used to be "Valid UTF-8: \x01\x02\u8C37\u6B4C", but MSVC seems to +// interpret \u differently from GCC. +const char * kValidUTF8String = "Valid UTF-8: \x01\x02\350\260\267\346\255\214"; + +template +bool WriteMessage(const char *value, T *message, string *wire_buffer) { + message->set_data(value); + wire_buffer->clear(); + message->AppendToString(wire_buffer); + return (wire_buffer->size() > 0); +} + +template +bool ReadMessage(const string &wire_buffer, T *message) { + return message->ParseFromArray(wire_buffer.data(), wire_buffer.size()); +} + +bool StartsWith(const string& s, const string& prefix) { + return s.substr(0, prefix.length()) == prefix; +} + +TEST(Utf8ValidationTest, WriteInvalidUTF8String) { + string wire_buffer; + protobuf_unittest::OneString input; + vector errors; + { + ScopedMemoryLog log; + WriteMessage(kInvalidUTF8String, &input, &wire_buffer); + errors = log.GetMessages(ERROR); + } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + ASSERT_EQ(1, errors.size()); + EXPECT_TRUE(StartsWith(errors[0], + "String field contains invalid UTF-8 data when " + "serializing a protocol buffer. Use the " + "'bytes' type if you intend to send raw bytes.")); +#else + ASSERT_EQ(0, errors.size()); +#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED +} + +TEST(Utf8ValidationTest, ReadInvalidUTF8String) { + string wire_buffer; + protobuf_unittest::OneString input; + WriteMessage(kInvalidUTF8String, &input, &wire_buffer); + protobuf_unittest::OneString output; + vector errors; + { + ScopedMemoryLog log; + ReadMessage(wire_buffer, &output); + errors = log.GetMessages(ERROR); + } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + ASSERT_EQ(1, errors.size()); + EXPECT_TRUE(StartsWith(errors[0], + "String field contains invalid UTF-8 data when " + "parsing a protocol buffer. Use the " + "'bytes' type if you intend to send raw bytes.")); + +#else + ASSERT_EQ(0, errors.size()); +#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED +} + +TEST(Utf8ValidationTest, WriteValidUTF8String) { + string wire_buffer; + protobuf_unittest::OneString input; + vector errors; + { + ScopedMemoryLog log; + WriteMessage(kValidUTF8String, &input, &wire_buffer); + errors = log.GetMessages(ERROR); + } + ASSERT_EQ(0, errors.size()); +} + +TEST(Utf8ValidationTest, ReadValidUTF8String) { + string wire_buffer; + protobuf_unittest::OneString input; + WriteMessage(kValidUTF8String, &input, &wire_buffer); + protobuf_unittest::OneString output; + vector errors; + { + ScopedMemoryLog log; + ReadMessage(wire_buffer, &output); + errors = log.GetMessages(ERROR); + } + ASSERT_EQ(0, errors.size()); + EXPECT_EQ(input.data(), output.data()); +} + +// Bytes: anything can pass as bytes, use invalid UTF-8 string to test +TEST(Utf8ValidationTest, WriteArbitraryBytes) { + string wire_buffer; + protobuf_unittest::OneBytes input; + vector errors; + { + ScopedMemoryLog log; + WriteMessage(kInvalidUTF8String, &input, &wire_buffer); + errors = log.GetMessages(ERROR); + } + ASSERT_EQ(0, errors.size()); +} + +TEST(Utf8ValidationTest, ReadArbitraryBytes) { + string wire_buffer; + protobuf_unittest::OneBytes input; + WriteMessage(kInvalidUTF8String, &input, &wire_buffer); + protobuf_unittest::OneBytes output; + vector errors; + { + ScopedMemoryLog log; + ReadMessage(wire_buffer, &output); + errors = log.GetMessages(ERROR); + } + ASSERT_EQ(0, errors.size()); + EXPECT_EQ(input.data(), output.data()); +} + +TEST(Utf8ValidationTest, ParseRepeatedString) { + protobuf_unittest::MoreBytes input; + input.add_data(kValidUTF8String); + input.add_data(kInvalidUTF8String); + input.add_data(kInvalidUTF8String); + string wire_buffer = input.SerializeAsString(); + + protobuf_unittest::MoreString output; + vector errors; + { + ScopedMemoryLog log; + ReadMessage(wire_buffer, &output); + errors = log.GetMessages(ERROR); + } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + ASSERT_EQ(2, errors.size()); +#else + ASSERT_EQ(0, errors.size()); +#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + EXPECT_EQ(wire_buffer, output.SerializeAsString()); +} + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/cpp/thirdparty/protobuf-2.5.0/src/solaris/libstdc++.la b/cpp/thirdparty/protobuf-2.5.0/src/solaris/libstdc++.la new file mode 100644 index 0000000..3edf425 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/src/solaris/libstdc++.la @@ -0,0 +1,51 @@ +# libstdc++.la - a libtool library file +# Generated by ltmain.sh - GNU libtool 1.4a-GCC3.0 (1.641.2.256 2001/05/28 20:09:07 with GCC-local changes) +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# --- +# NOTE: This file lives in /usr/sfw/lib on Solaris 10. Unfortunately, +# due to an apparent bug in the Solaris 10 6/06 release, +# /usr/sfw/lib/libstdc++.la is empty. Below is the correct content, +# according to +# http://forum.java.sun.com/thread.jspa?threadID=5073150 +# By passing LDFLAGS='-Lsrc/solaris' to configure, make will pick up +# this copy of the file rather than the empty copy in /usr/sfw/lib. +# +# Also see +# http://www.technicalarticles.org/index.php/Compiling_MySQL_5.0_on_Solaris_10 +# +# Note: this is for 32-bit systems. If you have a 64-bit system, +# uncomment the appropriate dependency_libs line below. +# ---- + +# The name that we can dlopen(3). +dlname='libstdc++.so.6' + +# Names of this library. +library_names='libstdc++.so.6.0.3 libstdc++.so.6 libstdc++.so' + +# The name of the static archive. +old_library='libstdc++.a' + +# Libraries that this one depends upon. +# 32-bit version: +dependency_libs='-lc -lm -L/usr/sfw/lib -lgcc_s' +# 64-bit version: +#dependency_libs='-L/lib/64 -lc -lm -L/usr/sfw/lib/64 -lgcc_s' + +# Version information for libstdc++. +current=6 +age=0 +revision=3 + +# Is this an already installed library? +installed=yes + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/usr/sfw/lib' diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/config.h b/cpp/thirdparty/protobuf-2.5.0/vsprojects/config.h new file mode 100644 index 0000000..2c64450 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/config.h @@ -0,0 +1,29 @@ +/* protobuf config.h for MSVC. On other platforms, this is generated + * automatically by autoheader / autoconf / configure. */ + +/* the location of */ +#define HASH_MAP_H + +/* the namespace of hash_map/hash_set */ +// Apparently Microsoft decided to move hash_map *back* to the std namespace +// in MSVC 2010: +// http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx +// TODO(kenton): Use unordered_map instead, which is available in MSVC 2010. +#if _MSC_VER < 1310 || _MSC_VER >= 1600 +#define HASH_NAMESPACE std +#else +#define HASH_NAMESPACE stdext +#endif + +/* the location of */ +#define HASH_SET_H + +/* define if the compiler has hash_map */ +#define HAVE_HASH_MAP 1 + +/* define if the compiler has hash_set */ +#define HAVE_HASH_SET 1 + +/* define if you want to use zlib. See readme.txt for additional + * requirements. */ +// #define HAVE_ZLIB 1 diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/convert2008to2005.sh b/cpp/thirdparty/protobuf-2.5.0/vsprojects/convert2008to2005.sh new file mode 100755 index 0000000..60eccaf --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/convert2008to2005.sh @@ -0,0 +1,20 @@ +#! /bin/sh -e + +# This script downgrades MSVC 2008 projects to MSVC 2005 projects, allowing +# people with MSVC 2005 to open them. Otherwise, MSVC 2005 simply refuses to +# open projects created with 2008. We run this as part of our release process. +# If you obtained the code direct from version control and you want to use +# MSVC 2005, you may have to run this manually. (Hint: Use Cygwin or MSYS.) + +for file in *.sln; do + echo "downgrading $file..." + sed -i -re 's/Format Version 10.00/Format Version 9.00/g; + s/Visual Studio 2008/Visual Studio 2005/g;' $file +done + +for file in *.vcproj; do + echo "downgrading $file..." + sed -i -re 's/Version="9.00"/Version="8.00"/g;' $file +done + +# Yes, really, that's it. diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/extract_includes.bat b/cpp/thirdparty/protobuf-2.5.0/vsprojects/extract_includes.bat new file mode 100755 index 0000000..2ddcddb --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/extract_includes.bat @@ -0,0 +1,49 @@ +md include +md include\google +md include\google\protobuf +md include\google\protobuf\stubs +md include\google\protobuf\io +md include\google\protobuf\compiler +md include\google\protobuf\compiler\cpp +md include\google\protobuf\compiler\java +md include\google\protobuf\compiler\python +copy ..\src\google\protobuf\stubs\atomicops.h include\google\protobuf\stubs\atomicops.h +copy ..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h include\google\protobuf\stubs\atomicops_internals_x86_msvc.h +copy ..\src\google\protobuf\stubs\common.h include\google\protobuf\stubs\common.h +copy ..\src\google\protobuf\stubs\once.h include\google\protobuf\stubs\once.h +copy ..\src\google\protobuf\stubs\platform_macros.h include\google\protobuf\stubs\platform_macros.h +copy ..\src\google\protobuf\stubs\template_util.h include\google\protobuf\stubs\template_util.h +copy ..\src\google\protobuf\stubs\type_traits.h include\google\protobuf\stubs\type_traits.h +copy ..\src\google\protobuf\descriptor.h include\google\protobuf\descriptor.h +copy ..\src\google\protobuf\descriptor.pb.h include\google\protobuf\descriptor.pb.h +copy ..\src\google\protobuf\descriptor_database.h include\google\protobuf\descriptor_database.h +copy ..\src\google\protobuf\dynamic_message.h include\google\protobuf\dynamic_message.h +copy ..\src\google\protobuf\extension_set.h include\google\protobuf\extension_set.h +copy ..\src\google\protobuf\generated_enum_reflection.h include\google\protobuf\generated_enum_reflection.h +copy ..\src\google\protobuf\generated_message_util.h include\google\protobuf\generated_message_util.h +copy ..\src\google\protobuf\generated_message_reflection.h include\google\protobuf\generated_message_reflection.h +copy ..\src\google\protobuf\message.h include\google\protobuf\message.h +copy ..\src\google\protobuf\message_lite.h include\google\protobuf\message_lite.h +copy ..\src\google\protobuf\reflection_ops.h include\google\protobuf\reflection_ops.h +copy ..\src\google\protobuf\repeated_field.h include\google\protobuf\repeated_field.h +copy ..\src\google\protobuf\service.h include\google\protobuf\service.h +copy ..\src\google\protobuf\text_format.h include\google\protobuf\text_format.h +copy ..\src\google\protobuf\unknown_field_set.h include\google\protobuf\unknown_field_set.h +copy ..\src\google\protobuf\wire_format.h include\google\protobuf\wire_format.h +copy ..\src\google\protobuf\wire_format_lite.h include\google\protobuf\wire_format_lite.h +copy ..\src\google\protobuf\wire_format_lite_inl.h include\google\protobuf\wire_format_lite_inl.h +copy ..\src\google\protobuf\io\coded_stream.h include\google\protobuf\io\coded_stream.h +copy ..\src\google\protobuf\io\gzip_stream.h include\google\protobuf\io\gzip_stream.h +copy ..\src\google\protobuf\io\printer.h include\google\protobuf\io\printer.h +copy ..\src\google\protobuf\io\tokenizer.h include\google\protobuf\io\tokenizer.h +copy ..\src\google\protobuf\io\zero_copy_stream.h include\google\protobuf\io\zero_copy_stream.h +copy ..\src\google\protobuf\io\zero_copy_stream_impl.h include\google\protobuf\io\zero_copy_stream_impl.h +copy ..\src\google\protobuf\io\zero_copy_stream_impl_lite.h include\google\protobuf\io\zero_copy_stream_impl_lite.h +copy ..\src\google\protobuf\compiler\code_generator.h include\google\protobuf\compiler\code_generator.h +copy ..\src\google\protobuf\compiler\command_line_interface.h include\google\protobuf\compiler\command_line_interface.h +copy ..\src\google\protobuf\compiler\importer.h include\google\protobuf\compiler\importer.h +copy ..\src\google\protobuf\compiler\parser.h include\google\protobuf\compiler\parser.h +copy ..\src\google\protobuf\compiler\cpp\cpp_generator.h include\google\protobuf\compiler\cpp\cpp_generator.h +copy ..\src\google\protobuf\compiler\java\java_generator.h include\google\protobuf\compiler\java\java_generator.h +copy ..\src\google\protobuf\compiler\python\python_generator.h include\google\protobuf\compiler\python\python_generator.h +copy ..\src\google\protobuf\compiler\plugin.h include\google\protobuf\compiler\plugin.h diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotobuf-lite.vcproj b/cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotobuf-lite.vcproj new file mode 100644 index 0000000..3023684 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotobuf-lite.vcproj @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotobuf.vcproj b/cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotobuf.vcproj new file mode 100644 index 0000000..0546d8e --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotobuf.vcproj @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotoc.vcproj b/cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotoc.vcproj new file mode 100644 index 0000000..bda0d28 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/libprotoc.vcproj @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/lite-test.vcproj b/cpp/thirdparty/protobuf-2.5.0/vsprojects/lite-test.vcproj new file mode 100644 index 0000000..2b20532 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/lite-test.vcproj @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/protobuf.sln b/cpp/thirdparty/protobuf-2.5.0/vsprojects/protobuf.sln new file mode 100644 index 0000000..a359c28 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/protobuf.sln @@ -0,0 +1,92 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf", "libprotobuf.vcproj", "{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotoc", "libprotoc.vcproj", "{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}" + ProjectSection(ProjectDependencies) = postProject + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "protoc", "protoc.vcproj", "{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}" + ProjectSection(ProjectDependencies) = postProject + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcproj", "{4DF72760-C055-40A5-A77E-30A17E2AC2DB}" + ProjectSection(ProjectDependencies) = postProject + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} + {3AF54C8A-10BF-4332-9147-F68ED9862032} = {3AF54C8A-10BF-4332-9147-F68ED9862032} + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32} = {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32} + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "..\gtest\msvc\gtest.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "..\gtest\msvc\gtest_main.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf-lite", "libprotobuf-lite.vcproj", "{49EA010D-706F-4BE2-A397-77854B72A040}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lite-test", "lite-test.vcproj", "{12015ACE-42BE-4952-A5A0-44A9A46908E2}" + ProjectSection(ProjectDependencies) = postProject + {49EA010D-706F-4BE2-A397-77854B72A040} = {49EA010D-706F-4BE2-A397-77854B72A040} + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_plugin", "test_plugin.vcproj", "{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}" + ProjectSection(ProjectDependencies) = postProject + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.ActiveCfg = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.Build.0 = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.ActiveCfg = Release|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.Build.0 = Release|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.ActiveCfg = Debug|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.Build.0 = Debug|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.ActiveCfg = Release|Win32 + {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.Build.0 = Release|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.ActiveCfg = Debug|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.Build.0 = Debug|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.ActiveCfg = Release|Win32 + {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.Build.0 = Release|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.ActiveCfg = Debug|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.Build.0 = Debug|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.ActiveCfg = Release|Win32 + {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.Build.0 = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.Build.0 = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.ActiveCfg = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.Build.0 = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.ActiveCfg = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.Build.0 = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.ActiveCfg = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.Build.0 = Release|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.ActiveCfg = Debug|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.Build.0 = Debug|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.ActiveCfg = Release|Win32 + {49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.Build.0 = Release|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.ActiveCfg = Debug|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.Build.0 = Debug|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.ActiveCfg = Release|Win32 + {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.Build.0 = Release|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.ActiveCfg = Debug|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.Build.0 = Debug|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.ActiveCfg = Release|Win32 + {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/protoc.vcproj b/cpp/thirdparty/protobuf-2.5.0/vsprojects/protoc.vcproj new file mode 100644 index 0000000..68bb66f --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/protoc.vcproj @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/readme.txt b/cpp/thirdparty/protobuf-2.5.0/vsprojects/readme.txt new file mode 100644 index 0000000..288345a --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/readme.txt @@ -0,0 +1,114 @@ +This directory contains project files for compiling Protocol Buffers using +MSVC. This is not the recommended way to do Protocol Buffer development -- +we prefer to develop under a Unix-like environment -- but it may be more +accessible to those who primarily work with MSVC. + +Compiling and Installing +======================== + +1) Open protobuf.sln in Microsoft Visual Studio. +2) Choose "Debug" or "Release" configuration as desired.* +3) From the Build menu, choose "Build Solution". Wait for compiling to finish. +4) From a command shell, run tests.exe and lite-test.exe and check that all + tests pass. +5) Run extract_includes.bat to copy all the public headers into a separate + "include" directory (under the top-level package directory). +6) Copy the contents of the include directory to wherever you want to put + headers. +7) Copy protoc.exe wherever you put build tools (probably somewhere in your + PATH). +8) Copy libprotobuf.lib, libprotobuf-lite.lib, and libprotoc.lib wherever you + put libraries. + +* To avoid conflicts between the MSVC debug and release runtime libraries, when + compiling a debug build of your application, you may need to link against a + debug build of libprotobuf.lib. Similarly, release builds should link against + release libs. + +DLLs vs. static linking +======================= + +Static linking is now the default for the Protocol Buffer libraries. Due to +issues with Win32's use of a separate heap for each DLL, as well as binary +compatibility issues between different versions of MSVC's STL library, it is +recommended that you use static linkage only. However, it is possible to +build libprotobuf and libprotoc as DLLs if you really want. To do this, +do the following: + + 1) Open protobuf.sln in MSVC. + 2) For each of the projects libprotobuf, libprotobuf-lite, and libprotoc, do + the following: + 2a) Right-click the project and choose "properties". + 2b) From the side bar, choose "General", under "Configuration Properties". + 2c) Change the "Configuration Type" to "Dynamic Library (.dll)". + 2d) From the side bar, choose "Preprocessor", under "C/C++". + 2e) Add PROTOBUF_USE_DLLS to the list of preprocessor defines. + 3) When compiling your project, make sure to #define PROTOBUF_USE_DLLS. + +When distributing your software to end users, we strongly recommend that you +do NOT install libprotobuf.dll or libprotoc.dll to any shared location. +Instead, keep these libraries next to your binaries, in your application's +own install directory. C++ makes it very difficult to maintain binary +compatibility between releases, so it is likely that future versions of these +libraries will *not* be usable as drop-in replacements. + +If your project is itself a DLL intended for use by third-party software, we +recommend that you do NOT expose protocol buffer objects in your library's +public interface, and that you statically link protocol buffers into your +library. + +ZLib support +============ + +If you want to include GzipInputStream and GzipOutputStream +(google/protobuf/io/gzip_stream.h) in libprotoc, you will need to do a few +additional steps: + +1) Obtain a copy of the zlib library. The pre-compiled DLL at zlib.net works. +2) Make sure zlib's two headers are in your include path and that the .lib file + is in your library path. You could place all three files directly into the + vsproject directory to compile libprotobuf, but they need to be visible to + your own project as well, so you should probably just put them into the + VC shared icnlude and library directories. +3) Right-click on the "tests" project and choose "properties". Navigate the + sidebar to "Configuration Properties" -> "Linker" -> "Input". +4) Under "Additional Dependencies", add the name of the zlib .lib file (e.g. + zdll.lib). Make sure to update both the Debug and Release configurations. +5) If you are compiling libprotobuf and libprotoc as DLLs (see previous + section), repeat steps 2 and 3 for the libprotobuf and libprotoc projects. + If you are compiling them as static libraries, then you will need to link + against the zlib library directly from your own app. +6) Edit config.h (in the vsprojects directory) and un-comment the line that + #defines HAVE_ZLIB. (Or, alternatively, define this macro via the project + settings.) + +Notes on Compiler Warnings +========================== + +The following warnings have been disabled while building the protobuf libraries +and compiler. You may have to disable some of them in your own project as +well, or live with them. + +C4018 - 'expression' : signed/unsigned mismatch +C4146 - unary minus operator applied to unsigned type, result still unsigned +C4244 - Conversion from 'type1' to 'type2', possible loss of data. +C4251 - 'identifier' : class 'type' needs to have dll-interface to be used by + clients of class 'type2' +C4267 - Conversion from 'size_t' to 'type', possible loss of data. +C4305 - 'identifier' : truncation from 'type1' to 'type2' +C4355 - 'this' : used in base member initializer list +C4800 - 'type' : forcing value to bool 'true' or 'false' (performance warning) +C4996 - 'function': was declared deprecated + +C4251 is of particular note, if you are compiling the Protocol Buffer library +as a DLL (see previous section). The protocol buffer library uses templates in +its public interfaces. MSVC does not provide any reasonable way to export +template classes from a DLL. However, in practice, it appears that exporting +templates is not necessary anyway. Since the complete definition of any +template is available in the header files, anyone importing the DLL will just +end up compiling instances of the templates into their own binary. The +Protocol Buffer implementation does not rely on static template members being +unique, so there should be no problem with this, but MSVC prints warning +nevertheless. So, we disable it. Unfortunately, this warning will also be +produced when compiling code which merely uses protocol buffers, meaning you +may have to disable it in your code too. diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/test_plugin.vcproj b/cpp/thirdparty/protobuf-2.5.0/vsprojects/test_plugin.vcproj new file mode 100755 index 0000000..9bfbc54 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/test_plugin.vcproj @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/thirdparty/protobuf-2.5.0/vsprojects/tests.vcproj b/cpp/thirdparty/protobuf-2.5.0/vsprojects/tests.vcproj new file mode 100644 index 0000000..fa5c234 --- /dev/null +++ b/cpp/thirdparty/protobuf-2.5.0/vsprojects/tests.vcproj @@ -0,0 +1,681 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/valgrind.supp b/cpp/valgrind.supp new file mode 100644 index 0000000..21f169f --- /dev/null +++ b/cpp/valgrind.supp @@ -0,0 +1,328 @@ +{ + getpwnam_r + Memcheck:Leak + fun:malloc + ... + fun:__nss_lookup_function + ... + fun:getpwnam_r@@GLIBC_* +} +{ + getpwnam_r static mem + Memcheck:Leak + fun:malloc + fun:nss_parse_service_list + fun:__nss_database_lookup + ... + fun:getpwnam_r@@GLIBC_* +} +{ + getpwuid_r + Memcheck:Leak + fun:malloc + ... + fun:__nss_lookup_function + ... + fun:getpwuid_r@@GLIBC_* +} +{ + getpwuid_r static mem + Memcheck:Leak + fun:malloc + fun:nss_parse_service_list + fun:__nss_database_lookup + ... + fun:getpwuid_r@@GLIBC_* +} +{ + getgrgid_r + Memcheck:Leak + fun:malloc + ... + fun:__nss_lookup_function + ... + fun:getgrgid_r@@GLIBC_* +} +{ + getgrgid_r static mem + Memcheck:Leak + fun:malloc + fun:nss_parse_service_list + fun:__nss_database_lookup + ... + fun:getgrgid_r@@GLIBC_* +} +{ + getgrnam_r + Memcheck:Leak + fun:malloc + ... + fun:__nss_lookup_function + ... + fun:getgrnam_r@@GLIBC_* +} +{ + getgrnam_r + Memcheck:Leak + fun:malloc + fun:nss_parse_service_list + fun:__nss_database_lookup + ... + fun:getgrnam_r@@GLIBC_* +} +{ + gethostbyname2_r + Memcheck:Leak + fun:malloc + fun:_dl_scope_free + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:do_dlopen + fun:_dl_catch_error + fun:__libc_dlopen_mode + fun:__nss_lookup_function + fun:__nss_lookup + fun:gethostbyname2_r@@GLIBC_* +} +{ + boost_thread_TLS? + Memcheck:Leak + fun:malloc + fun:_ZN5boost6detail25get_once_per_thread_epochEv + fun:* + fun:_ZN5boost6detail23get_current_thread_dataEv + fun:_ZN5boost11this_thread6get_idEv +} +{ + boost_thread_TLS? + Memcheck:Leak + fun:_Znwm + fun:_ZN5boost12_GLOBAL__N_125make_external_thread_dataEv + fun:_ZN5boost11this_thread6get_idEv +} +{ + boost_thread_TLS? + Memcheck:Leak + fun:_Znwm + obj:*libboost_thread* + fun:_ZN5boost11this_thread6get_idEv +} +{ + missing_openssl_compressionmethods_free_in_boost + Memcheck:Leak + fun:malloc + fun:CRYPTO_malloc + ... + fun:SSL_COMP_get_compression_methods + fun:SSL_library_init + fun:_ZN5boost4asio3ssl6detail12openssl_initILb1EE7do_initC1Ev + fun:_ZN5boost4asio3ssl6detail12openssl_initILb1EE7do_init8instanceEv + fun:_ZN5boost4asio3ssl6detail12openssl_initILb1EEC1Ev +} +{ + missing_openssl_compressionmethods_free_in_boost (1.49) + Memcheck:Leak + fun:malloc + fun:CRYPTO_malloc + ... + fun:SSL_COMP_get_compression_methods + fun:SSL_library_init + fun:_ZN5boost4asio3ssl6detail17openssl_init_base7do_initC1Ev + fun:_ZN5boost4asio3ssl6detail17openssl_init_base8instanceEv + fun:_ZN5boost4asio3ssl6detail12openssl_initILb1EEC1Ev +} +{ + pthread_cancel_init leak #1 + Memcheck:Leak + fun:malloc + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:do_dlopen + fun:_dl_catch_error + ... + fun:__libc_dlopen_mode + fun:pthread_cancel_init + fun:pthread_cancel + fun:fuse_session_loop_mt +} +{ + boost::thread_specific_ptr leak + Memcheck:Leak + fun:_Znwm + ... + fun:_ZN5boost6detail16add_new_tss_nodeEPKvNS_10shared_ptrINS0_20tss_cleanup_functionEEEPv + fun:_ZN5boost6detail12set_tss_dataEPKvNS_10shared_ptrINS0_20tss_cleanup_functionEEEPvb + fun:_ZN5boost19thread_specific_ptrIiED1Ev +} +{ + boost::thread_specific_ptr leak + Memcheck:Leak + fun:malloc + fun:_ZN5boost6detail25get_once_per_thread_epochEv + fun:* + fun:_ZN5boost6detail23get_current_thread_dataEv + fun:_ZN5boost6detail13find_tss_dataEPKv + fun:_ZN5boost6detail12get_tss_dataEPKv + fun:_ZNK5boost19thread_specific_ptrIiE3getEv + fun:_ZN5boost19thread_specific_ptrIiE5resetEPi +} +{ + boost::thread_specific_ptr leak + Memcheck:Leak + fun:_Znwm + ... + fun:_ZN5boost6detail16add_new_tss_nodeEPKvNS_10shared_ptrINS0_20tss_cleanup_functionEEEPv + fun:_ZN5boost6detail12set_tss_dataEPKvNS_10shared_ptrINS0_20tss_cleanup_functionEEEPvb + fun:_ZN5boost19thread_specific_ptrIiED1Ev +} +{ + boost::detail::get_current_thread_data() leak + Memcheck:Leak + fun:malloc + fun:_ZN5boost6detail25get_once_per_thread_epochEv + fun:* + fun:_ZN5boost6detail23get_current_thread_dataEv + fun:_ZN5boost6detail20interruption_checker* + fun:_ZN5boost18condition_variable4waitERNS_11unique_lockINS_5mutexEEE +} +{ + boost::thread join leak + Memcheck:Leak + fun:malloc + fun:_ZN5boost6detail25get_once_per_thread_epochEv + fun:* + fun:_ZN5boost6detail23get_current_thread_dataEv + fun:_ZN5boost6thread4joinEv +} +{ + boost::thread exit leak + Memcheck:Leak + fun:malloc + fun:_ZN5boost6detail25get_once_per_thread_epochEv + fun:* + fun:_ZN5boost6detail23get_current_thread_dataEv + fun:_ZN5boost6detail13find_tss_dataEPKv + fun:_ZN5boost6detail12set_tss_dataEPKvNS_10shared_ptrINS0_20tss_cleanup_functionEEEPvb + fun:_ZN5boost19thread_specific_ptrIiED1Ev + fun:exit +} +{ + OpenSSL static memory? + Memcheck:Leak + fun:malloc + fun:CRYPTO_malloc + ... + obj:/lib/libcrypto.so.0.9.8 + ... +} +{ + OpenSSL static memory? + Memcheck:Leak + fun:realloc + fun:CRYPTO_realloc + ... + obj:/lib/libcrypto.so.0.9.8 + ... +} +{ + realpath static memory? + Memcheck:Leak + fun:malloc + fun:realpath@@GLIBC_* + fun:main +} +{ + occurs when fusermount -u is run while fuse gets started + Memcheck:Leak + fun:calloc + fun:fuse_fs_new +} +{ + boost static ssl init leak? + Memcheck:Leak + ... + fun:_ZN5boost4asio3ssl6detail12openssl_initILb1EEC1Ev + ... +} +{ + unknown leak when interrupting a mount.xtreemfs retrying to mount a volume + Memcheck:Leak + fun:malloc + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error + fun:_dl_open + fun:do_dlopen + fun:_dl_catch_error + fun:dlerror_run + fun:__libc_dlopen_mode + fun:__nss_lookup_function + obj:* + obj:* +} +{ + getaddrinfo causes invalid free of noai6ai_cached + Memcheck:Free + fun:free + fun:__libc_freeres + fun:_vgnU_freeres + fun:__run_exit_handlers + fun:exit + fun:(below main) +} +{ + missing length field initialization in x509 encoding/decoding functions, see http://rt.openssl.org/Ticket/Display.html?id=2400 + Memcheck:Cond + fun:ASN1_STRING_set + fun:ASN1_mbstring_ncopy + fun:ASN1_mbstring_copy + fun:ASN1_STRING_to_UTF8 + obj:/lib*/libcrypto.so.1.0.0 + obj:/lib*/libcrypto.so.1.0.0 + fun:ASN1_item_ex_d2i + obj:/lib*/libcrypto.so.1.0.0 + obj:/lib*/libcrypto.so.1.0.0 + fun:ASN1_item_ex_d2i + obj:/lib*/libcrypto.so.1.0.0 + obj:/lib*/libcrypto.so.1.0.0 +} +{ + Bad request parsing on some OpenSSL versions when using SSLv3 + Memcheck:Cond + ... + fun:ssl3_read_bytes + obj:/lib*/libssl.so.1.0.0 +} +{ + object caching for ipv6 addresses in glibc + Memcheck:Leak + fun:malloc + fun:make_request + fun:__check_pf +} +{ + floating point formatting in glibc + Memcheck:Addr1 + fun:__printf_fp + fun:vfprintf + fun:vsnprintf +} +{ + floating point formatting in glibc + Memcheck:Addr4 + fun:__printf_fp + fun:vfprintf + fun:vsnprintf +} +{ + floating point formatting in glibc + Memcheck:Addr8 + ... + fun:__printf_fp + fun:vfprintf + fun:vsnprintf +} diff --git a/etc/init.d/generate_initd_scripts.sh b/etc/init.d/generate_initd_scripts.sh new file mode 100755 index 0000000..f30c46f --- /dev/null +++ b/etc/init.d/generate_initd_scripts.sh @@ -0,0 +1,37 @@ +#!/bin/bash -e + +# This script generates the /etc/init.d/xtreemfs-{dir,mrc,osd} scripts +# based on the file 'xtreemfs-service.template'. + + +# Settings +services=( "dir" "mrc" "osd" ) +long_service_names=( "Directory Service" "Metadata and Replica Catalog" "Object Storage Device" ) + +template_file="xtreemfs-service.template" + +# Create files +script_directory=$(dirname "$0") + +for i in $(seq 0 $((${#services[@]} - 1))) +do + service=${services[$i]} + short_service_name_lowercase=$service + short_service_name_uppercase=$(echo $service | tr [[:lower:]] [[:upper:]]) + long_service_name=${long_service_names[$i]} + if [ "$service" = "dir" ] + then + should_start="\$null" + else + should_start="xtreemfs-dir" + fi + + initd_file="${script_directory}/xtreemfs-${service}" + cp "${script_directory}/${template_file}" "$initd_file" + chmod a+x "$initd_file" + + sed -i -e "s|@SHORT_SERVICE_NAME@|${short_service_name_uppercase}|g" "$initd_file" + sed -i -e "s|@SHORT_SERVICE_NAME_LOWERCASE@|${short_service_name_lowercase}|g" "$initd_file" + sed -i -e "s|@LONG_SERVICE_NAME@|${long_service_name}|g" "$initd_file" + sed -i -e "s|@SHOULD_START@|${should_start}|g" "$initd_file" +done \ No newline at end of file diff --git a/etc/init.d/xtreemfs-service.template b/etc/init.d/xtreemfs-service.template new file mode 100644 index 0000000..e8d9faf --- /dev/null +++ b/etc/init.d/xtreemfs-service.template @@ -0,0 +1,161 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: xtreemfs-@SHORT_SERVICE_NAME_LOWERCASE@ +# Required-Start: $network $remote_fs +# Required-Stop: $network $remote_fs +# Should-Start: @SHOULD_START@ +# Should-Stop: $null +# Default-Start: 3 5 +# Default-Stop: 0 1 2 6 +# Short-Description: XtreemFS @SHORT_SERVICE_NAME@ +# Description: XtreemFS @LONG_SERVICE_NAME@ (@SHORT_SERVICE_NAME@). http://www.xtreemfs.org/ +### END INIT INFO + +# Source function library. +if [ -e /lib/lsb/init-functions ]; then + . /lib/lsb/init-functions +else + . /etc/init.d/functions +fi + +XTREEMFS_USER=xtreemfs + +PID=/var/run/xtreemfs_@SHORT_SERVICE_NAME_LOWERCASE@.pid + +CONFIG=/etc/xos/xtreemfs/@SHORT_SERVICE_NAME_LOWERCASE@config.properties + +LOG=/var/log/xtreemfs/@SHORT_SERVICE_NAME_LOWERCASE@.log + +if [ -z $JAVA_HOME ]; then + export JAVA_HOME=/usr +fi +JAVA_CALL="$JAVA_HOME/bin/java -ea -cp /usr/share/java/XtreemFS.jar:/usr/share/java/BabuDB.jar:/usr/share/java/Flease.jar:/usr/share/java/protobuf-java-2.5.0.jar:/usr/share/java/Foundation.jar:/usr/share/java/jdmkrt.jar:/usr/share/java/jdmktk.jar:/usr/share/java/commons-codec-1.3.jar" + +# For SELinux we need to use 'runuser' not 'su' +if [ -x "/sbin/runuser" ]; then + SU="/sbin/runuser" +else + SU="/bin/su" +fi + +pre_check() { + exists=`grep -c $XTREEMFS_USER /etc/passwd` + if [ $exists -eq 0 ]; then + echo "User $XTREEMFS_USER does not exist. Create it first." + exit 1 + fi + log_directory=`dirname $LOG` + if [ ! -e $log_directory ]; then + echo "Directory for logfiles $log_directory does not exist. Create it first." + exit 1 + fi +} + +start() { + if [ -f $PID ]; then + PROCPID=`cat $PID` + if [ -e /proc/$PROCPID ];then + echo "XtreemFS @LONG_SERVICE_NAME@ (@SHORT_SERVICE_NAME@) already started" + return 0 + else + echo -n "Previous XtreemFS @LONG_SERVICE_NAME@ (@SHORT_SERVICE_NAME@) was not shutdown correctly (PID $PROCPID). " + fi + fi + + pre_check + + echo >> $LOG + date >> $LOG + echo -e "Starting XtreemFS @LONG_SERVICE_NAME@ (@SHORT_SERVICE_NAME@)...\n\n" >> $LOG + + echo -n "Starting XtreemFS @LONG_SERVICE_NAME@ (@SHORT_SERVICE_NAME@)..." + $SU -s /bin/bash $XTREEMFS_USER -c "$JAVA_CALL org.xtreemfs.@SHORT_SERVICE_NAME_LOWERCASE@.@SHORT_SERVICE_NAME@ $CONFIG" >> $LOG 2>&1 & + PROCPID=$! + echo $PROCPID > $PID + sleep 1s + + if [ -e /proc/$PROCPID ]; then + echo "success" + else + echo "failed" + return 1 + fi + + return 0 +} + +stop() { + result=0 + if [ -f $PID ]; then + echo -n "Stopping XtreemFS @LONG_SERVICE_NAME@ (@SHORT_SERVICE_NAME@)..." + killproc -p $PID $SU + result=$? + if [ $result -eq 0 ]; then + rm -f $PID + echo "success" + else + echo "failed" + fi + else + echo "XtreemFS @LONG_SERVICE_NAME@ (@SHORT_SERVICE_NAME@) is not running" + fi + + return $result +} + +status() { + if [ -f $PID ]; then + PROCPID=`cat $PID` + if [ ! -e /proc/$PROCPID ]; then + echo "XtreemFS @LONG_SERVICE_NAME@ (@SHORT_SERVICE_NAME@) has crashed" + return 1 + else + echo "XtreemFS @LONG_SERVICE_NAME@ (@SHORT_SERVICE_NAME@) is running" + return 0 + fi + else + echo "XtreemFS @LONG_SERVICE_NAME@ (@SHORT_SERVICE_NAME@) is not running" + return 3 + fi +} + +# See how we were called. +case "$1" in + start) + start + result=$? + ;; + stop) + stop + result=$? + ;; + status) + status + result=$? + ;; + reload) + result=0 + ;; + restart) + stop && sleep 1 && start + result=$? + ;; + try-restart) + ## Stop the service and if this succeeds (i.e. the + ## service was running before), start it again. + $0 status >/dev/null + if [ $? -eq 0 ]; then + $0 restart + result=$? + else + result=0 + fi + ;; + *) + echo -e "Usage: $0 {start|stop|restart|reload|status|try-restart}\n" + result=1 + ;; +esac + +exit $result diff --git a/etc/xos/xtreemfs/datacentermap.example b/etc/xos/xtreemfs/datacentermap.example new file mode 100644 index 0000000..f4528d6 --- /dev/null +++ b/etc/xos/xtreemfs/datacentermap.example @@ -0,0 +1,7 @@ +datacenters=A,B,C +distance.A-B=10 +distance.A-C=100 +distance.B-C=50 +A.addresses=192.168.1.1,192.168.2.0/24 +B.addresses=192.168.1.2,192.168.3.0/24 +C.addresses=192.168.1.3,192.168.4.0/24,192.168.10.10 diff --git a/etc/xos/xtreemfs/default_dir b/etc/xos/xtreemfs/default_dir new file mode 100644 index 0000000..698859d --- /dev/null +++ b/etc/xos/xtreemfs/default_dir @@ -0,0 +1,9 @@ +# This configuration file is only used by maintenance tools like xtfs_chstatus, +# xtfs_cleanup_osd, xtfs_remove_osd and xtfs_scrub if a DIR server is not +# explicitely set at the command line. +# +# Do *not* use this file to tell MRC and OSD which DIR to contact. +# Edit the corresponding configuration files mrcconfig.properties +# and osdconfig.properties instead. +dir_service.host = localhost +dir_service.port = 32638 diff --git a/etc/xos/xtreemfs/dirconfig.properties b/etc/xos/xtreemfs/dirconfig.properties new file mode 100644 index 0000000..1c6e020 --- /dev/null +++ b/etc/xos/xtreemfs/dirconfig.properties @@ -0,0 +1,154 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +#debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 32638 + +# port for the status page (HTTP server) +http_port = 30638 + +# optional address for network device ("any" if not specified) +# listen.address = 127.0.0.1 + +# specify whether SSL is required +ssl.enabled = false + +# server credentials for SSL handshakes +ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/ds.p12 +ssl.service_creds.pw = passphrase +ssl.service_creds.container = pkcs12 +#ssl.trust_manager = org.xtreemfs.auth.plugin.SSLX509TrustManager + +# trusted certificates for SSL handshakes +ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks +ssl.trusted_certs.pw = jks_passphrase +ssl.trusted_certs.container = jks + +# Enables the Grid SSL mode. This mode uses SSL only for user authentication +# and sends all data via an unencrypted TCP connection. +#ssl.grid_ssl = false + +# time to wait for the directory service to become available on start-up +# before aborting +#startup.wait_for_dir = 30 + +# administrator password for privileged operations +#admin_password = passphrase + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +#monitoring = true + +#monitoring.email.program = /usr/sbin/sendmail + +#monitoring.email.sender = XtreemFS DIR + +#monitoring.email.receiver = + +#monitoring.max_warnings = 1 + +# If you want to monitor your XtreemFS installation through SNMP +# uncomment the following lines. You have to set snmp.enabled = true +# and provide a listen port and optional a address. Also optional +# is a path to an aclfile which controls which hosts can access the +# monitoring information via SNMP. +#snmp.enabled = true +#snmp.address = localhost +#snmp.port = 34638 +#snmp.aclfile = /etc/xos/xtreemfs/snmp.acl + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /var/lib/xtreemfs/dir/database + +# directory in which the database logs are stored +babudb.logDir = /var/lib/xtreemfs/dir/db-log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 200 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +# maximum number of key-value pairs per block +#babudb.maxNumRecordsPerBlock = 16 + +# maximum size for a babudb on-disk index file +#babudb.maxBlockFileSize = 52428800 + +# Uncomment this line if you want to enable the DIR replication. The path points +# to the database replication configuration. Place here the hostnames of all replicas. +#babudb.plugin.0 = /etc/xos/xtreemfs/server-repl-plugin/dir.properties + diff --git a/etc/xos/xtreemfs/mrcconfig.properties b/etc/xos/xtreemfs/mrcconfig.properties new file mode 100644 index 0000000..6ba1fdc --- /dev/null +++ b/etc/xos/xtreemfs/mrcconfig.properties @@ -0,0 +1,190 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +#debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 32636 + +# port for the status page (HTTP server) +http_port = 30636 + +# optional address for network device, "any" if not specified +# listen.address = 127.0.0.1 + +# optinal host name that is used to register the service at the DIR +# hostname = foo.bar.com + +# interval for querying the Directory Service for new OSDs (in s) +osd_check_interval = 10 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 32638 +# If you run a replicated DIR, you also have to set the addresses of the additional DIR replicas here: +#dir_service1.host = second-DIR-replica +#dir_service1.port = 32638 +#dir_service2.host = third-DIR-replica +#dir_service2.port = 32638 + +# specify whether access time stamps are updated +no_atime = true + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = false + +# server credentials for SSL handshakes +ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/mrc.p12 +ssl.service_creds.pw = passphrase +ssl.service_creds.container = pkcs12 +#ssl.trust_manager = org.xtreemfs.auth.plugin.SSLX509TrustManager + +# trusted certificates for SSL handshakes +ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks +ssl.trusted_certs.pw = jks_passphrase +ssl.trusted_certs.container = jks + +# Enables the Grid SSL mode. This mode uses SSL only for user authentication +# and sends all data via an unencrypted TCP connection. +#ssl.grid_ssl = false + +# Authentication providers are used to retrieve the user identities +# from the client or from certificate. +# The default provider is org.xtreemfs.common.auth.NullAuthProvider, which just +# takes the information provided by the client. The name of a pluggable +# provider can be used here. +authentication_provider = org.xtreemfs.common.auth.NullAuthProvider + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. So far, pluggable +# policies have to inherit from either org.xtreemfs.mrc.ac.FileAccessPolicy, +# org.xtreemfs.mrc.osdstatus.OSDSelectionPolicy, +# org.xtreemfs.common.auth.AuthenticationProvider, or javax.ssl.TrustManager. +# Policies identified by policy IDs (OSDSelectionPolicy and FileAccessPolicy) +# require a public static long field called POLICY_ID that assigns the policy +# a unique number. +policy_dir = /etc/xos/xtreemfs/policies + +# Shared secret between the MRC and all OSDs. +# The secret is used by the MRC to sign capabilities, i.e. security tokens for +# data access at OSDs. In turn, an OSD uses the secret to verify that the +# capability has been issued by the MRC. The shared secret will be replaced by +# a public key infrastructure in future releases. +capability_secret = secretPassphrase + +# validity time span for capabilities in seconds +#capability_timeout = 600 + +# administrator password for privileged operations +#admin_password = passphrase + +# If you want to monitor your XtreemFS installation through SNMP +# uncomment the following lines. You have to set snmp.enabled = true +# and provide a listen port and optional a address. Also optional +# is a path to an aclfile which controls which hosts can access the +# monitoring information via SNMP. +#snmp.enabled = true +#snmp.address = localhost +#snmp.port = 34636 +#snmp.aclfile = /etc/xos/xtreemfs/snmp.acl + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /var/lib/xtreemfs/mrc/database + +# directory in which the database logs are stored +babudb.logDir = /var/lib/xtreemfs/mrc/db-log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = ASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 0 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +# maximum number of key-value pairs per block +#babudb.maxNumRecordsPerBlock = 16 + +# maximum size for a babudb on-disk index file +#babudb.maxBlockFileSize = 52428800 + +# Uncomment this line if you want to enable the MRC replication. The path points +# to the database replication configuration. Place here the hostnames of all replicas. +# +# Please note, if you replicate the MRC you have to change the option +# "babudb.sync" in this file from ASYNC to a synchronous one e.g., FDATASYNC. +#babudb.plugin.0 = /etc/xos/xtreemfs/server-repl-plugin/mrc.properties + diff --git a/etc/xos/xtreemfs/osdconfig.properties b/etc/xos/xtreemfs/osdconfig.properties new file mode 100644 index 0000000..ac91b9e --- /dev/null +++ b/etc/xos/xtreemfs/osdconfig.properties @@ -0,0 +1,130 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +#debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 32640 + +# port for the status page (HTTP server) +http_port = 30640 + +# optional address for network device, "any" if not specified +# listen.address = 127.0.0.1 + +# optinal host name that is used to register the service at the DIR +# hostname = foo.bar.com + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 32638 +# If you run a replicated DIR, you also have to set the addresses of the additional DIR replicas here: +#dir_service1.host = second-DIR-replica +#dir_service1.port = 32638 +#dir_service2.host = third-DIR-replica +#dir_service2.port = 32638 + +# directory containing XtreemFS file content +object_dir = /var/lib/xtreemfs/objs/ + +# Number of storage threads. Increase it to improve concurrency in case of multiple open files. +# Set it to a value >1 only if the underlying device can cope with concurrency, e.g. an SSD. +#storage_threads = 1 + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = false + +# server credentials for SSL handshakes +ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12 +ssl.service_creds.pw = passphrase +ssl.service_creds.container = pkcs12 +#ssl.trust_manager = org.xtreemfs.auth.plugin.SSLX509TrustManager + +# trusted certificates for SSL handshakes +ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks +ssl.trusted_certs.pw = jks_passphrase +ssl.trusted_certs.container = jks + +# Enables the Grid SSL mode. This mode uses SSL only for user authentication +# and sends all data via an unencrypted TCP connection. +#ssl.grid_ssl = false + +# send and receive buffer sizes of sockets +#socket.send_buffer_size = 262144 +#socket.recv_buffer_size = 262144 + +report_free_space = true + +# specify whether internal OSD checksums are required +# if the flag is set to true, the OSD will calculate checksums for +# newly created objects, which will be checked when the object is read +checksums.enabled = false + +# algorithm used for checksum calculation +# by default, Adler32, CRC32, MD5 and SHA-1 are supported +checksums.algorithm = Adler32 + +# Shared secret between the MRC and all OSDs. +# The secret is used by the MRC to sign capabilities, i.e. security tokens for +# data access at OSDs. In turn, an OSD uses the secret to verify that the +# capability has been issued by the MRC. The shared secret will be replaced by +# a public key infrastructure in future releases. +capability_secret = secretPassphrase + +# administrator password for privileged operations +#admin_password = passphrase + +# time to wait for the directory service to become available on start-up +# before aborting +#startup.wait_for_dir = 30 + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# If you want to monitor your XtreemFS installation through SNMP +# uncomment the following lines. You have to set snmp.enabled = true +# and provide a listen port and optional a address. Also optional +# is a path to an aclfile which controls which hosts can access the +# monitoring information via SNMP. +#snmp.enabled = true +#snmp.address = localhost +#snmp.port = 34640 +#snmp.aclfile = /etc/xos/xtreemfs/snmp.acl + + +# Optional user-definied script to determine the health status of the OSD. +# The health status will be used in the default OSD selection policy to +# exclude OSDs with FAILED or WARNING health status. +# See the xtreemfs user guide for more information. +#health_check = /usr/share/xtreemfs/osd_health_check.sh + diff --git a/etc/xos/xtreemfs/snmp.acl b/etc/xos/xtreemfs/snmp.acl new file mode 100644 index 0000000..831a461 --- /dev/null +++ b/etc/xos/xtreemfs/snmp.acl @@ -0,0 +1,38 @@ +# @(#)file jdmk.acl +# @(#)author Sun Microsystems, Inc. +# @(#)version 1.11 +# @(#)lastedit 04/04/07 +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + +# access: can take only "read-only" or "read-write" values +# +# managers can be : +# - hostname: hubble +# - ip v4 and v6 addresses: 123.456.789.12 , fe80::a00:20ff:fe9b:ea82 +# - subnet mask: 123!255!255!255 (its an IPO address where "." are replaced +# by "!"). This way of expressing the subnet is deprecated, use the prefix +# notation. +# - ip v4 and v6 netmask prefix notation : +# 123.456.789.12/24, fe80::a00:20ff:fe9b:ea82/64 + +acl = { + { + communities = public + access = read-only + managers = localhost + } + { + communities = private + access = read-write + managers = localhost + } +} + +trap = { + { + trap-community = public + hosts = localhost + } +} diff --git a/interface/Makefile b/interface/Makefile new file mode 100644 index 0000000..249e021 --- /dev/null +++ b/interface/Makefile @@ -0,0 +1,57 @@ +PROTOC=../cpp/thirdparty/protobuf-2.5.0/src/protoc +BASE_DIR=$(shell pwd) +INCLUDE_DIR=include/ +PROTOBUF_INCLUDE=../cpp/thirdparty/protobuf-2.5.0/src + +PBRPC_PLUGIN=../bin/protoc-gen-pbrpc +PBRPCCPP_PLUGIN=../bin/protoc-gen-pbrpccpp + +TARGET_DIR_JAVA_FOUNDATION=../java/foundation/src/ +GENERATED_DIR_JAVA_FOUNDATION=$(TARGET_DIR_JAVA_FOUNDATION)org/xtreemfs/foundation/pbrpc/generatedinterfaces/ + +TARGET_DIR_JAVA_PBRPCGEN=../java/pbrpcgen/src/ +GENERATED_DIR_JAVA_PBRPCGEN=$(TARGET_DIR_JAVA_PBRPCGEN)org/xtreemfs/foundation/pbrpc/generatedinterfaces/ + +TARGET_DIR_JAVA_SERVERS=../java/servers/src/ +GENERATED_DIR_JAVA_SERVERS=$(TARGET_DIR_JAVA_SERVERS)org/xtreemfs/pbrpc/generatedinterfaces/ + +TARGET_DIR_CPP_CLIENT=../cpp/generated/ +TARGET_DIR_H_CLIENT=../client/include/generated/ + + +PROTOS_FOUNDATION=$(wildcard pbrpc/*.proto) include/PBRPC.proto +PROTOS_SERVERS=$(wildcard xtreemfs/*.proto) include/Common.proto + +.PHONY: foundation_clean pbrpcgen_clean servers_clean + +all: cpp servers foundation + +cpp: + $(PROTOC) -I$(PROTOBUF_INCLUDE) -I. -I$(@D)/pbrpc/ $(PROTOS_FOUNDATION) --cpp_out=$(TARGET_DIR_CPP_CLIENT) + + $(PROTOC) include/Common.proto --cpp_out=$(TARGET_DIR_CPP_CLIENT) + $(PROTOC) -I$(PROTOBUF_INCLUDE) -I. -I$(@D)/xtreemfs/ $(PROTOS_SERVERS) --cpp_out=$(TARGET_DIR_CPP_CLIENT) + $(PROTOC) --plugin=$(PBRPCCPP_PLUGIN) -I$(PROTOBUF_INCLUDE) -I. -I$(@D)/xtreemfs/ $(PROTOS_SERVERS) --pbrpccpp_out=$(TARGET_DIR_CPP_CLIENT) + $(PROTOC) --plugin=$(PBRPCCPP_PLUGIN) -I$(PROTOBUF_INCLUDE) -I. -I$(@D)/pbrpc/ $(PROTOS_FOUNDATION) --pbrpccpp_out=$(TARGET_DIR_CPP_CLIENT) + + +servers: + $(PROTOC) include/Common.proto --java_out=$(TARGET_DIR_JAVA_SERVERS) + $(PROTOC) -I$(PROTOBUF_INCLUDE) -I. -I$(@D)/xtreemfs/ $(PROTOS_SERVERS) --java_out=$(TARGET_DIR_JAVA_SERVERS) + $(PROTOC) --plugin=$(PBRPC_PLUGIN) -I$(PROTOBUF_INCLUDE) -I. -I$(@D)/xtreemfs/ $(PROTOS_SERVERS) --pbrpc_out=$(TARGET_DIR_JAVA_SERVERS) + +servers_clean: + @rm -r $(GENERATED_DIR_JAVA_SERVERS)*.java + +foundation: pbrpc/*.proto + $(PROTOC) -I$(PROTOBUF_INCLUDE) -I. -I$(@D)/pbrpc/ $(PROTOS_FOUNDATION) --java_out=$(TARGET_DIR_JAVA_FOUNDATION) + $(PROTOC) --plugin=$(PBRPC_PLUGIN) -I$(PROTOBUF_INCLUDE) -I. -I$(@D)/pbrpc/ $(PROTOS_FOUNDATION) --pbrpc_out=$(TARGET_DIR_JAVA_FOUNDATION) + +foundation_clean: + @rm -r $(GENERATED_DIR_JAVA_FOUNDATION)*.java + +pbrpcgen: include/PBRPC.proto + $(PROTOC) -I$(PROTOBUF_INCLUDE) -Iinclude/ $< --java_out=$(TARGET_DIR_JAVA_PBRPCGEN) + +pbrpcgen_clean: + @rm -r $(GENERATED_DIR_JAVA_PBRPCGEN)*.java diff --git a/interface/include/Common.proto b/interface/include/Common.proto new file mode 100644 index 0000000..57446b7 --- /dev/null +++ b/interface/include/Common.proto @@ -0,0 +1,44 @@ +// +// Copyright (c) 2009-2011, Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// +// All rights reserved. +// +// 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 the Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// 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 HOLDER 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. +// +// AUTHORS: Bjoern Kolbeck (ZIB) +// + +option java_package="org.xtreemfs.pbrpc.generatedinterfaces"; +package xtreemfs.pbrpc; + +// Dummy message for requests without parameters. +// The RPC implementation sends an empty message block. +message emptyRequest { +} + +// Dummy message for responses without content. +// The RPC implementation sends an empty message block. +message emptyResponse { +} diff --git a/interface/include/PBRPC.proto b/interface/include/PBRPC.proto new file mode 100644 index 0000000..9988d77 --- /dev/null +++ b/interface/include/PBRPC.proto @@ -0,0 +1,49 @@ +// +// Copyright (c) 2009-2011, Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// +// All rights reserved. +// +// 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 the Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// 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 HOLDER 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. +// +// AUTHORS: Bjoern Kolbeck (ZIB) +// + + +option java_package="org.xtreemfs.foundation.pbrpc.generatedinterfaces"; +package xtreemfs.pbrpc; +import "google/protobuf/descriptor.proto"; + +// Ids used by the protoc for the PBRPC specific options. +// data_in/out signals that a method can take raw data as input or produces +// raw data as output. +extend google.protobuf.MethodOptions { + optional fixed32 proc_id = 50001; + optional bool data_in = 50004; + optional bool data_out = 50003; +} + +extend google.protobuf.ServiceOptions { + optional fixed32 interface_id = 50002; +} diff --git a/interface/pbrpc/Ping.proto b/interface/pbrpc/Ping.proto new file mode 100644 index 0000000..eae201c --- /dev/null +++ b/interface/pbrpc/Ping.proto @@ -0,0 +1,77 @@ +// +// Copyright (c) 2009-2011, Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// +// All rights reserved. +// +// 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 the Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// 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 HOLDER 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. +// +// AUTHORS: Bjoern Kolbeck (ZIB) +// + +// Simple ping-pong RPCs for testing. + +option java_package="org.xtreemfs.foundation.pbrpc.generatedinterfaces"; +package xtreemfs.pbrpc; +import "include/PBRPC.proto"; + +message PingRequest{ + required string text = 1; + required bool sendError = 2; +} + +message PingResponse { + + message PingResult { + required string text = 1; + } + + message PingError { + required string errorMessage = 1; + } + + optional PingResult result = 1; + optional PingError error = 2; +} + +message Ping_emptyRequest { +} + +message Ping_emptyResponse { +} + + +service PingService { + option(interface_id)=1; + + rpc doPing(PingRequest) returns(PingResponse) { + option(proc_id)=1; + option(data_in)=true; + }; + rpc emptyPing(Ping_emptyRequest) returns(Ping_emptyResponse) { + option(proc_id)=2; + } +} + + diff --git a/interface/pbrpc/RPC.proto b/interface/pbrpc/RPC.proto new file mode 100644 index 0000000..e830136 --- /dev/null +++ b/interface/pbrpc/RPC.proto @@ -0,0 +1,167 @@ +// +// Copyright (c) 2009-2011, Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// +// All rights reserved. +// +// 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 the Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// 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 HOLDER 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. +// +// AUTHORS: Bjoern Kolbeck (ZIB) +// + +// Header for RPC protocol. + +option java_package="org.xtreemfs.foundation.pbrpc.generatedinterfaces"; +package xtreemfs.pbrpc; + +// Encodes the type of the RPC message sent. +enum MessageType { + // RPC request to execute method. + RPC_REQUEST = 0; + // RPC response after successful execution of method. + RPC_RESPONSE_SUCCESS = 1; + // RPC response when execution of a method failed, including POSIX errors. + RPC_RESPONSE_ERROR = 2; +} + +// Authentication type provided for request. +enum AuthType { + // No authentication. + AUTH_NONE = 0; + // Plain text admin password authentication. + AUTH_PASSWORD = 1; +} + +// File system user credentials for executing an operation. +// Might be ignored by some operations. +message UserCredentials { + // Globally unique user ID (GUID). + required string username = 1; + // List of one or more globally unique group IDs (GGID). + repeated string groups = 2; +} + +// Admin password if AuthType AUTH_PASSWORD. +message AuthPassword { + required string password = 1; +} + +// RPC Authentication information. +message Auth { + // Selected authentication type. + required AuthType auth_type = 1; + // Optional data, depends on auth_type selected. + optional AuthPassword auth_passwd = 3; + optional bytes auth_data = 2; +} + +// Error types. +enum ErrorType { + // Requested interface_id not implemented by server. + INVALID_INTERFACE_ID = 1; + // Requested procedure_id not implemented by serevr. + INVALID_PROC_ID = 2; + // Server cannot parse the RPC request. + GARBAGE_ARGS = 3; + // Authentication failed, access denied. + AUTH_FAILED = 4; + // Unspecific internal server error that caused the RPC to fail. + INTERNAL_SERVER_ERROR = 5; + // POSIX errno error (not necessarily a failure), e.g. ENOENT. + // POSIXErrno contains details that can be passed to an application. + ERRNO = 6; + // Server redirects to another server implementing the same interface. + REDIRECT = 7; + // Request failed, due to an invalid view (i.e. an outdated xlocset). + INVALID_VIEW = 8; + // Generic IO_ERROR to be used by the RPC implementation. + IO_ERROR = 100; +} + +// Additional error code which can be passed to applications. +// See errno.h for details. Values are equivalent to Linux +// values, but are different for other unix platforms such as +// Mac OS X and Solaris! +enum POSIXErrno { + POSIX_ERROR_NONE = 9999; + POSIX_ERROR_EPERM = 1; + POSIX_ERROR_ENOENT = 2; + POSIX_ERROR_EINTR = 4; + POSIX_ERROR_EIO = 5; + POSIX_ERROR_EAGAIN = 11; + POSIX_ERROR_EACCES = 13; + POSIX_ERROR_EEXIST = 17; + POSIX_ERROR_EXDEV = 18; + POSIX_ERROR_ENODEV = 19; + POSIX_ERROR_ENOTDIR = 20; + POSIX_ERROR_EISDIR = 21; + POSIX_ERROR_EINVAL = 22; + POSIX_ERROR_ENOSPC = 28; + POSIX_ERROR_ENOTEMPTY = 39; + POSIX_ERROR_ENODATA = 61; +} + +// RPC header message sent in the first request fragment. +message RPCHeader { + + // Header data for requests, i.e. message_type is RPC_REQUEST. + message RequestHeader { + // Interface id of the requested method. + required fixed32 interface_id = 1; + // Procedure id of the requested method. + required fixed32 proc_id = 2; + // File system user credentials for the operation. + required UserCredentials user_creds = 3; + // Authentication details. + required Auth auth_data = 4; + } + + // Header data for error responses, i.e. message_type is RPC_ERROR_RESPONSE. + message ErrorResponse { + // Error type details. + required ErrorType error_type = 1; + // Optional POSIX errno. + optional POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + // Optional human readable error message in English (not localized!). + optional string error_message = 3; + // Optional debug information that only makes sense to developers such + // as stack traces. + optional string debug_info = 4; + // Optional UUID of the server to use instead. Required when error_type is REDIRECT. + optional string redirect_to_server_uuid = 5; + } + + // A unique id to identify the request. The response sent back by the server will have + // the same call_id. + // The call_id must be unqiue per TCP connection. In addition, clients should start + // with a value based e.g. on time to avoid problems after a client restart. + required fixed32 call_id = 1; + // Type of this RPC message (Request, Response). + required MessageType message_type = 2; + + // Optional request_header, required if message_type is RPC_REQUEST. + optional RequestHeader request_header = 3; + // Optional error_response, required if message_type is RPC_ERROR_RESPONSE. + optional ErrorResponse error_response = 4; +} diff --git a/interface/xtreemfs/DIR.proto b/interface/xtreemfs/DIR.proto new file mode 100644 index 0000000..ae2d80e --- /dev/null +++ b/interface/xtreemfs/DIR.proto @@ -0,0 +1,281 @@ +// +// Copyright (c) 2009-2011, Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// +// All rights reserved. +// +// 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 the Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// 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 HOLDER 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. +// +// AUTHORS: Bjoern Kolbeck (ZIB), Jan Stender (ZIB) +// + +option java_package="org.xtreemfs.pbrpc.generatedinterfaces"; +package xtreemfs.pbrpc; +import "include/PBRPC.proto"; +import "include/Common.proto"; +import "xtreemfs/GlobalTypes.proto"; + +// For each server UUID, at least one address mapping must exist. +// Each record maps a UUID to one FQDN or IP address and port. +message AddressMapping { + // UUID being mapped. + required string uuid = 1; + // Version of this record. + required fixed64 version = 2; + // Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values. + required string protocol = 3; + // FQDN or IP address of the server. + required string address = 4; + // TCP/UDP port number. + required fixed32 port = 5; + // Matching network. There has to exist exactly one default address + // accessible from any network for which this is set to "*". + required string match_network = 6; + // Time to live in seconds before the + // entry should be evicted from caches. + required fixed32 ttl_s = 7; + // URI, obsolete. + required string uri = 8; +} + +// Set of mappings for a UUID. +message AddressMappingSet { + repeated AddressMapping mappings = 1; +} + +// DIR service address, used for auto discovery. +message DirService { + required string address = 1; + required fixed32 port = 2; + required string protocol = 3; + required fixed32 interface_version = 4; +} + +// Key/Value pairs for a service. +message ServiceDataMap { + repeated KeyValuePair data = 1; +} + +enum ServiceType { + // Returns a list of all service types. + SERVICE_TYPE_MIXED = 0; + SERVICE_TYPE_MRC = 1; + SERVICE_TYPE_OSD = 2; + SERVICE_TYPE_VOLUME = 3; + SERVICE_TYPE_DIR = 4; +} + +enum ServiceStatus { + // Service is available. + SERVICE_STATUS_AVAIL = 0; + // Service (OSD) will be removed, new files are + // not allocated to this OSD. + SERVICE_STATUS_TO_BE_REMOVED = 1; + // Service was removed permanently, data is lost. + SERVICE_STATUS_REMOVED = 2; +} + +// Service data in DIR. +message Service { + required ServiceType type = 1; + // Service uuid, e.g. volume UUID. + required string uuid = 2; + // Version of this record, assigned by the DIR on write. + required fixed64 version = 3; + // Service name, e.g. volume name. + required string name = 4; + // Timestamp of last update in global XtreemFS time, assigned + // by the DIR on write. + required fixed64 last_updated_s = 5; + // Service details including service state. + required ServiceDataMap data = 6; +} + +message ServiceSet { + repeated Service services = 1; +} + +// Service configuration stored in the DIR. +message Configuration { + // Service UUID. + required string uuid = 1; + // Configuration options. + repeated KeyValuePair parameter = 2; + // Version of this record, assigned by the DIR on write. + required fixed64 version = 3; +} + + +message addressMappingGetRequest { + // UUID of the service for which mapping should be returned. + required string uuid = 1; +} + +message addressMappingGetResponse { + // List of matching mappings, might be empty. + optional AddressMappingSet result = 1; +} + +message addressMappingSetResponse { + // New version number assigned to the address mapping + // by the DIR. + optional fixed64 new_version = 1; +} + +message globalTimeSGetResponse { + // Global XtreemFS time in seconds. + required fixed64 time_in_seconds = 1; +} + +message serviceDeregisterRequest { + // UUID of the service that should be dregistered. + required string uuid = 1; +} + +message serviceGetByNameRequest { + // Service name to search for. + required string name = 1; +} + +message serviceGetByUUIDRequest { + // UUID to search for. + required string name = 1; +} + +message serviceGetByTypeRequest { + // Service types to search for. + required ServiceType type = 1; +} + +message serviceRegisterRequest { + // Service data to be registered. + // Old data for the service with the same UUID is + // overwritten. + required Service service = 1; +} + +message serviceRegisterResponse { + // New version assigned to the service record by the DIR. + required fixed64 new_version = 1; +} + +message configurationGetRequest { + // UUID of the servic for which the configuration is requested. + required string uuid = 1; +} + +message configurationSetResponse { + // New version assigned to the configuration record by the DIR. + optional fixed64 new_version = 1; +} + +// Due to a name clash with "message DIRService", the former service +// "DIRService" had to be renamed to another name, now "DirectoryService". +// See http://code.google.com/p/xtreemfs/issues/detail?id=248 for more info. +service DirectoryService { + + option(interface_id)=10001; + + // Returns the address mappings for a UUID stored on the DIR. + rpc xtreemfs_address_mappings_get(addressMappingGetRequest) returns(AddressMappingSet) { + option(proc_id)=1; + }; + // Removes all address mappings for a UUID. + rpc xtreemfs_address_mappings_remove(addressMappingGetRequest) returns(emptyResponse) { + option(proc_id)=2; + }; + // Sets (updates or adds) the address mappings for a UUID. All records must have the same + // UUID and the same version. The version must be the latest returned by the DIR, otherwise + // the DIR will return an error. + rpc xtreemfs_address_mappings_set(AddressMappingSet) returns(addressMappingSetResponse) { + option(proc_id)=3; + }; + + // DIR discovery requests are sent via UDP. DIRs in the same net answer with a + // DirService response. + rpc xtreemfs_discover_dir(emptyRequest) returns(DirService) { + option(proc_id)=4; + }; + + // Returns the global XtreemFS time in seconds since Unix epoch. + rpc xtreemfs_global_time_s_get(emptyRequest) returns(globalTimeSGetResponse) { + option(proc_id)=5; + }; + + // Deregisters a service (deletes the service record). + rpc xtreemfs_service_deregister(serviceDeregisterRequest) returns(emptyResponse) { + option(proc_id)=6; + }; + + // Returns a list of services with a matching name. + rpc xtreemfs_service_get_by_name(serviceGetByNameRequest) returns(ServiceSet) { + option(proc_id)=7; + }; + + // Returns a list of services with a matching type. Use MIXED to get all types. + rpc xtreemfs_service_get_by_type(serviceGetByTypeRequest) returns(ServiceSet) { + option(proc_id)=8; + }; + + // Returns a list of services with a matching UUID. + rpc xtreemfs_service_get_by_uuid(serviceGetByUUIDRequest) returns(ServiceSet) { + option(proc_id)=9; + }; + + // Sets the status of the service with UUID to offline. + rpc xtreemfs_service_offline(serviceGetByUUIDRequest) returns(emptyResponse) { + option(proc_id)=10; + }; + + // Registers (or updates) a service record. Version should be 0 for new records and the + // previous version returned by the DIR for updates. + rpc xtreemfs_service_register(serviceRegisterRequest) returns(serviceRegisterResponse) { + option(proc_id)=11; + }; + + // Triggers a BabuDB database snapshot. + rpc xtreemfs_checkpoint(emptyRequest) returns(emptyResponse) { + option(proc_id)=20; + }; + + // Shuts the service down, requires AUTH_PASSWORD. + rpc xtreemfs_shutdown(emptyRequest) returns(emptyResponse) { + option(proc_id)=21; + }; + + // Returns the configuration for the service with UUID. + rpc xtreemfs_configuration_get(configurationGetRequest) returns(Configuration) { + option(proc_id)=22; + }; + + // Updates the configuration for the service. + rpc xtreemfs_configuration_set(Configuration) returns(configurationSetResponse) { + option(proc_id)=23; + }; + + // Send a client's vivaldi coordinates to th DIR. + rpc xtreemfs_vivaldi_client_update(VivaldiCoordinates) returns(emptyResponse) { + option(proc_id)=24; + }; +} diff --git a/interface/xtreemfs/GlobalTypes.proto b/interface/xtreemfs/GlobalTypes.proto new file mode 100644 index 0000000..b759fb7 --- /dev/null +++ b/interface/xtreemfs/GlobalTypes.proto @@ -0,0 +1,288 @@ +// +// Copyright (c) 2009-2011, Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// +// All rights reserved. +// +// 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 the Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// 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 HOLDER 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. +// +// AUTHORS: Bjoern Kolbeck (ZIB), Jan Stender (ZIB) +// + +option java_package="org.xtreemfs.pbrpc.generatedinterfaces"; +package xtreemfs.pbrpc; +import "include/PBRPC.proto"; +import "include/Common.proto"; + +// Access control policy for a volume. +enum AccessControlPolicyType { + // No access control. + ACCESS_CONTROL_POLICY_NULL = 1; + // Regular POSIX permission and ACL-based access control. + ACCESS_CONTROL_POLICY_POSIX = 2; + // Permissions per volume (instead of per directory), + // faster since hierarchical evaluation is skipped. + ACCESS_CONTROL_POLICY_VOLUME = 3; +} + +// Values for OSD (and Replica) selection policies. +enum OSDSelectionPolicyType { + // Default filter. + OSD_SELECTION_POLICY_FILTER_DEFAULT = 1000; + // Filter based on the domain name (FQDN) of OSDs. + OSD_SELECTION_POLICY_FILTER_FQDN = 1001; + // Filter based on the UUID of OSDs. + OSD_SELECTION_POLICY_FILTER_UUID = 1002; + // Groups OSDs according to their location in the + // datacenter map. + OSD_SELECTION_POLICY_GROUP_DCMAP = 2000; + // Groups OSDs accroding to their domain names. + OSD_SELECTION_POLICY_GROUP_FQDN = 2001; + // Sorts the OSDs by distance from client calculated + // using the datacenter map. + OSD_SELECTION_POLICY_SORT_DCMAP = 3000; + // Sorts the OSDs by longest postfix match of the FQDN + // of OSD and client. + OSD_SELECTION_POLICY_SORT_FQDN = 3001; + // Random order. + OSD_SELECTION_POLICY_SORT_RANDOM = 3002; + // Sorts the OSDs by proximity of vivalid network + // coordinates of the client. + OSD_SELECTION_POLICY_SORT_VIVALDI = 3003; + // Sorts the OSDs in a round robin manner for + // multiple OSDs per host. + OSD_SELECTION_POLICY_SORT_HOST_ROUND_ROBIN = 3004; + // Sortes the OSDs by their UUID. + OSD_SELECTION_POLICY_SORT_UUID = 3998; + // Reverse given list. Used only internally by unit tests. + OSD_SELECTION_POLICY_SORT_REVERSE = 3999; +} + +enum ReplicaSelectionPolicyType { + REPLICA_SELECTION_POLICY_SIMPLE = 1; +} + +// Configuration for file data snapshots. +enum SnapConfig { + // Indicates that snapshots are disabled. + SNAP_CONFIG_SNAPS_DISABLED = 0; + // Indicates access to the current version of a file. + SNAP_CONFIG_ACCESS_CURRENT = 1; + // Indicates access to a snapshot of a file. + SNAP_CONFIG_ACCESS_SNAP = 2; +} + +// File size update data sent by OSDs. +message NewFileSize { + // New file size in bytes. + required fixed64 size_in_bytes = 1; + // Truncate epoch to sort file size updates. + required fixed32 truncate_epoch = 2; +} + +enum StripingPolicyType { + // Default striping policy (round-robin distribution). + STRIPING_POLICY_RAID0 = 0; + // Erasure code striping policy (. + STRIPING_POLICY_ERASURECODE = 1; +} + +message StripingPolicy { + // Type (by default STRIPING_POLICY_RAID0). + required StripingPolicyType type = 1; + // Size of a single chunk (object) in *kB*! + // The name of the field is wrong: This is not the total size of the stripe. + // Instead, the total size of a stripe in XtreemFS is: stripe_size * (width + parity_width) + required fixed32 stripe_size = 2; + // Number of OSDs to distribute data chunks on. + required fixed32 width = 3; + // Number of OSDs to distribute parity chunks on. + optional fixed32 parity_width = 4; +} + +// Details for a file replica. +message Replica { + // UUIDs of OSDs to store objects on. + // Length of this list must be equal to width + // in striping_policy! + repeated string osd_uuids = 1; + // Flags to control replication, e.g. transfer strategy. + required fixed32 replication_flags = 2; + // Striping policy for this replica. + required StripingPolicy striping_policy = 3; +} + +// List of replicas for a file. +message Replicas { + repeated Replica replicas = 1; +} + +// The LeaseState for a Replica. +enum LeaseState { + // The replica's update policy is not using lease. + NONE = 0; + // The replica is the the primary. + PRIMARY = 1; + // The replica is a backup (and an active primary exists). + BACKUP = 2; + // The replica is not active (currently no lease exists). + IDLE = 3; +} + +// The XCap is the authorization token that allows a +// client to execute operations on an OSD. It is created +// by the MRC on open and must be renewed by the client +// *before* it times out. +// The XCap is signed and must not be modified by a client. +message XCap { + // Access mode (see SYSTEM_V_FCNTL for allowed values). + required fixed32 access_mode = 1; + // IP address of the client that owns this XCap. + required string client_identity = 2; + // Number of seconds this XCap is valid. + required fixed64 expire_time_s = 3; + // Timestamp in global synchronized XtreemFS time when + // the XCap expires. + required fixed32 expire_timeout_s = 4; + // FileID for which this XCap is valid. + required string file_id = 5; + // True, if the file should be replicated when + // closed (read-only replication). + required bool replicate_on_close = 6; + // MRC server signature, based on various fields of the XCap. + required string server_signature = 7; + // Current truncate_epoch for the file, required by OSDs. + required fixed32 truncate_epoch = 8; + // Snapshot configuration for the file, required by OSDs. + required SnapConfig snap_config = 9; + // If a snapshot of the file is being accessed, this timestamp + // indicates which version (snapshot) of the file should be used + // on the OSD. + required fixed64 snap_timestamp = 10; +} + +// Locations of a file, i.e. the list of replicas including the OSDs that hold +// the file data. +message XLocSet { + // Used by the read-only replication to properly handle + // holes in sparse files and EOF. + required fixed64 read_only_file_size = 1; + // List of actual file replicas. + repeated Replica replicas = 2; + // Update policy to use for the file, + // see org.xtreemfs.common.ReplicaUpdatePolicies for values. + required string replica_update_policy = 3; + // Monotonically increasing version number of a file's XLocSet. + // Used to identify clients with outdates XLocSets. + required fixed32 version = 4; +} + +// Information required by OSDs for all file operations. +message FileCredentials { + required XCap xcap = 1; + required XLocSet xlocs = 2; +} + +message FileCredentialsSet { + optional FileCredentials file_credentials = 1; +} + +// Network coordinates to estimate the latency. +message VivaldiCoordinates { + required double x_coordinate = 1; + required double y_coordinate = 2; + required double local_error = 3; +} + +// Response returned by OSD write and truncate operations. +// This information is stored by the client and must be +// relayed to the MRC in regular intervals or when the file +// is fsynced or closed. +// In addition, the client must use this information locally +// for open files to provide processes with an accurate +// file size. +// Clients only need to store and relay the most recent OSDWriteResponse. +// These are sorted first by truncate_epoch and then by size_in_bytes, both ascending. +message OSDWriteResponse { + // Current file size in bytes. + optional fixed64 size_in_bytes = 1; + // Truncate epoch. + optional fixed32 truncate_epoch = 2; +} + +// TCP ports used by the services. +// HTTP ports are used for the status pages. +enum PORTS { + DIR_HTTP_PORT_DEFAULT = 30638; + DIR_PBRPC_PORT_DEFAULT = 32638; + MRC_HTTP_PORT_DEFAULT = 30636; + MRC_PBRPC_PORT_DEFAULT = 32636; + OSD_HTTP_PORT_DEFAULT = 30640; + OSD_PBRPC_PORT_DEFAULT = 32640; +} + +// Renew interval for clients. +enum CONSTANTS { + XCAP_RENEW_INTERVAL_IN_MIN = 1; +} + +// Flags for open command and access mode. +// Values are Linux, might be different for other platforms! +enum SYSTEM_V_FCNTL { + SYSTEM_V_FCNTL_H_O_RDONLY = 0x0000; + SYSTEM_V_FCNTL_H_O_WRONLY = 0x0001; + SYSTEM_V_FCNTL_H_O_RDWR = 0x0002; + SYSTEM_V_FCNTL_H_O_APPEND = 0x0008; + SYSTEM_V_FCNTL_H_O_CREAT = 0x0100; + SYSTEM_V_FCNTL_H_O_TRUNC = 0x0200; + SYSTEM_V_FCNTL_H_O_EXCL = 0x0400; + SYSTEM_V_FCNTL_H_O_SYNC = 0x0010; + SYSTEM_V_FCNTL_H_S_IFREG = 0x8000; + SYSTEM_V_FCNTL_H_S_IFDIR = 0x4000; + SYSTEM_V_FCNTL_H_S_IFLNK = 0xA000; + SYSTEM_V_FCNTL_H_S_IFIFO = 0x1000; +} + +// Flags for replication, multiple flags can be +// OR'ed. +enum REPL_FLAG { + REPL_FLAG_FULL_REPLICA = 1; + REPL_FLAG_IS_COMPLETE = 2; + REPL_FLAG_STRATEGY_RANDOM = 4; + REPL_FLAG_STRATEGY_RAREST_FIRST = 8; + REPL_FLAG_STRATEGY_SEQUENTIAL = 16; + REPL_FLAG_STRATEGY_SEQUENTIAL_PREFETCHING = 32; +} + +// Simple key/value pair. Protobuf doesn't provide a map type. +message KeyValuePair { + required string key = 1; + required string value = 2; +} + +enum SERVICES { + DIR = 1; + MRC = 2; + OSD = 3; +} diff --git a/interface/xtreemfs/MRC.proto b/interface/xtreemfs/MRC.proto new file mode 100644 index 0000000..aa00738 --- /dev/null +++ b/interface/xtreemfs/MRC.proto @@ -0,0 +1,823 @@ +// +// Copyright (c) 2009-2011, Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// +// All rights reserved. +// +// 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 the Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// 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 HOLDER 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. +// +// AUTHORS: Bjoern Kolbeck (ZIB), Jan Stender (ZIB) +// + +option java_package="org.xtreemfs.pbrpc.generatedinterfaces"; +package xtreemfs.pbrpc; +import "include/PBRPC.proto"; +import "include/Common.proto"; +import "xtreemfs/GlobalTypes.proto"; + +// information about a single file or directory; relevant for the 'stat' call +message Stat { + + // POSIX attributes + + // device number; represented by a hash of the volume id + required fixed64 dev = 1; + // inode number; represented by the file ID + required fixed64 ino = 2; + // POSIX access mode + required fixed32 mode = 3; + // hardlink count + required fixed32 nlink = 4; + // owning user ID + required string user_id = 5; + // owning group ID + required string group_id = 6; + // file size + required fixed64 size = 7; + // atime (access time) in nanoseconds since 1970 + required fixed64 atime_ns = 8; + // mtime (data modification time) in nanoseconds since 1970 + required fixed64 mtime_ns = 9; + // ctime (inode change time) in nanoseconds since 1970 + required fixed64 ctime_ns = 10; + // block size; represented by the stripe size + required fixed32 blksize = 11; + + // XtreemFS-specific attributes + + // identification tag for the stat object + optional fixed64 etag = 12; + // truncate epoch + required fixed32 truncate_epoch = 13; + // Win32-specific attributes + optional fixed32 attributes = 14; +} + +// single directory entry; relevant for the 'readdir' call +message DirectoryEntry { + // file or subdirectory name + required string name = 1; + // stat buffer containing the associated stat information + // Can have 0 or 1 Stats on a readdir for names only + optional Stat stbuf = 2; +} + +// list of directory entries; relevant for the 'readdir' call +message DirectoryEntries { + repeated DirectoryEntry entries = 1; +} + +// extended attribute of a file or directory +message XAttr { + // attribute name + required string name = 1; + // attribute value; can be empty on a 'listxattr' call for names only + optional string value = 2; + // redundant field of "value" which also accepts binary values (needed + // for storing the value of "system.posix_acl_access", + // added after version 1.3.1) + // If both value and value_bytes are present, value_bytes will always + // be preferred. For backward compability "value" always has to be set, + // even if "value_bytes" is available. + optional bytes value_bytes_string = 3; +} + +// information about a volume; relevant for the 'xtfs_mkvol' call +message Volume { + // access control policy to be assigned to the volume + required AccessControlPolicyType access_control_policy = 1; + // default striping policy to be assigned to the volume + required StripingPolicy default_striping_policy = 2; + // volume ID + required string id = 3; + // initial access mode for the root directory + required fixed32 mode = 4; + // volume name + required string name = 5; + // owning group ID of the volume (i.e. volume's root directory) + required string owner_group_id = 6; + // owning user ID of the volume (i.e. volume's root directory) + required string owner_user_id = 7; + // optional configuration attributes for the volume + repeated KeyValuePair attrs = 8; + // optional volume quota + optional fixed64 quota = 9; +} + +// a list of volumes; relevant for the 'xtfs_lsvol' call +message Volumes { + repeated Volume volumes = 1; +} + +// information about a file system (i.e. mounted volume) +message StatVFS { + + // POSIX attributes + + // size of a block in bytes + required fixed32 bsize = 1; + // number of available blocks in the file system for non-privileged users + required fixed64 bavail = 2; + // number of free blocks in the file system + optional fixed64 bfree = 13; + // total number of blocks in file system + required fixed64 blocks = 3; + // volume id + required string fsid = 4; + // maximum filename length + required fixed32 namemax = 5; + + // XtreemFS-specific attributes + + // access control policy of the volume + required AccessControlPolicyType access_control_policy = 6; + // default striping policy of the volume + required StripingPolicy default_striping_policy = 7; + // identification tag for the statVFS object + required fixed64 etag = 8; + // access mode of the volume's root directory + required fixed32 mode = 9; + // volume name + required string name = 10; + // owning group ID of the volume (i.e. volume's root directory) + required string owner_group_id = 11; + // owning user ID of the volume (i.e. volume's root directory) + required string owner_user_id = 12; +} + +// flags for setattr request +enum Setattrs { + SETATTR_MODE = 1; + SETATTR_UID = 2; + SETATTR_GID = 4; + SETATTR_SIZE = 8; + SETATTR_ATIME = 16; + SETATTR_MTIME = 32; + SETATTR_CTIME = 64; + SETATTR_ATTRIBUTES = 128; +} + +//messages for requests + +// sets file attriubtes of an open file +message fsetattrRequest { + // a buffer containing the attributes to update + required Stat stbuf = 1; + // a bitmap of Setattrs indicating which attributes to update + required fixed32 to_set = 2; + // the capability returned by the MRC when the file was opened + required XCap cap = 3; +} + +// requests attributes of a file or directory +message getattrRequest { + // the volume name + required string volume_name = 1; + // the path to the file or directory, relative to the volume root + required string path = 2; + // an identification tag indicating the last known version of the attributes + required fixed64 known_etag = 3; +} + +// returns attributes of a file or directory +message getattrResponse { + optional Stat stbuf = 1; +} + + +// requests extended attributes of a file or directory +message getxattrRequest { + // the volume name + required string volume_name = 1; + // the path to the file or directory, relative to the volume root + required string path = 2; + // the name of the attribute to retrieve + required string name = 3; +} + +// returns an attribute value of a file or directory +message getxattrResponse { + required string value = 1; + // see XAttr message for explanation. + optional bytes value_bytes_string = 2; +} + +// creates a new hardlink to an existing file +message linkRequest { + // the volume name + required string volume_name = 1; + // the path to the file to which the link is supposed to be created, + // relative to the volume root + required string target_path = 2; + // the path to the new link, relative to the volume root + required string link_path = 3; +} + +// requests a list of extended attributes of a file or directory +message listxattrRequest { + // the volume name + required string volume_name = 1; + // the path to the file or directory, relative to the volume root + required string path = 2; + // a flag indicating that no attribute values are supposed to be returned + required bool names_only = 3; +} + +// returns a list of extended attributes of a file or directory +message listxattrResponse { + repeated XAttr xattrs = 1; +} + +// creates a new directory +message mkdirRequest { + // the volume name + required string volume_name = 1; + // the path to the file or directory, relative to the volume root + required string path = 2; + // the initial access mode of the newly created directory + required fixed32 mode = 3; +} + +// opens a file and requests file credentials +message openRequest { + // the volume name + required string volume_name = 1; + // the path to the file, relative to the volume root + required string path = 2; + // a bitmap open flags, as defined in the specification of the POSIX + // 'open' call, e.g. O_RDWR, O_RDONLY, O_CREAT, O_EXCL, O_TRUNC ... + required fixed32 flags = 3; + // the initial access mode for a file created w/ O_CREAT + required fixed32 mode = 4; + // the initial set of Win32-specific attributes + required fixed32 attributes = 5; + // optional set of Vivaldi cooridnates of the client, which can be + // used to order the list of replicas + optional VivaldiCoordinates coordinates = 6; +} + +// returns a set of file credentials +message openResponse { + // the file credentials + required FileCredentials creds = 1; + // the server timestamp in seconds since 1970 to which the file + // timestamps were updated + required fixed32 timestamp_s = 2; +} + +// requests the content of a directory +message readdirRequest { + // the volume name + required string volume_name = 1; + // the path to the directory, relative to the volume root + required string path = 2; + // an identification tag indicating the last known version of the directory + // content + required fixed64 known_etag = 3; + // the maximum number of directory entries to return + required fixed32 limit_directory_entries_count = 4; + // a flag indicating that only names of nested files and directories are + // supposed to be returned, no attributes + required bool names_only = 5; + // the number of directory entries that have been returned already by + // previous calls + required fixed64 seen_directory_entries_count = 6; +} + +// requests the target path of a symbolic link +message readlinkRequest { + // the volume name + required string volume_name = 1; + // the path to the symbolic link, relative to the volume root + required string path = 2; +} + +// returns the target path of a symbolic link +message readlinkResponse { + repeated string link_target_path = 1; +} + +// removes an extended attribute from a file or directory +message removexattrRequest { + // the volume name + required string volume_name = 1; + // the path to the file or directory, relative to the volume root + required string path = 2; + // the name of the attribute to remove + required string name = 3; +} + +// changes the path name of a file or directory +message renameRequest { + // the volume name + required string volume_name = 1; + // the pathname to the file or directory to change + required string source_path = 2; + // the new path name for the file or directory + required string target_path = 3; +} + +// returns the result of a rename operation +message renameResponse { + // the server timestamp in seconds since 1970 to which the file and + // directory timestamps were updated + required fixed32 timestamp_s = 1; + // an optional set of file credentials that may contain a capabiltiy + // for the deletion of the previous file at the given target path + optional FileCredentials creds = 2; +} + +// deletes an empty directory +message rmdirRequest { + // the volume name + required string volume_name = 1; + // the path to the directory to delete + required string path = 2; +} + +// changes attributes of a file or directory +message setattrRequest { + // the volume name + required string volume_name = 1; + // the path to the file or directory, relative to the volume root + required string path = 2; + // a buffer containing the attributes to update + required Stat stbuf = 3; + // a bitmap of Setattrs indicating which attributes to update + required fixed32 to_set = 4; +} + +// flags for setxattr request +enum XATTR_FLAGS { + XATTR_FLAGS_CREATE = 1; + XATTR_FLAGS_REPLACE = 2; +} + +// sets an extended attribute of a file or directory +message setxattrRequest { + // the volume name + required string volume_name = 1; + // the path to the file or directory, relative to the volume root + required string path = 2; + // the name of the extended attribute to set + required string name = 3; + // the (new) value for the extended attribute to set + required string value = 4; + // (new) value in bytes, see XAttr for explanation. + optional bytes value_bytes_string = 6; + // flags indicating whether the attribute is supposed to be created or + // replaced (see XATTR_FLAGS) + required fixed32 flags = 5; +} + +// requests information about a mounted volume +message statvfsRequest { + // the volume name + required string volume_name = 1; + // an identification tag indicating the last known version of the directory + // content + required fixed64 known_etag = 5; +} + +// creates a symbolic link to a file +message symlinkRequest { + // the volume name + required string volume_name = 1; + // the path to the file to which the link is supposed to be created, + // relative to the volume root + required string target_path = 2; + // the path to the new link, relative to the volume root + required string link_path = 3; +} + +// deletes a file or directory +message unlinkRequest { + // the volume name + required string volume_name = 1; + // the path to the file or directory, relative to the volume root + required string path = 2; +} + +// returns the result of an unlink operation +message unlinkResponse { + // the server timestamp in seconds since 1970 to which the file and + // directory timestamps were updated + required fixed32 timestamp_s = 1; + // an optional set of file credentials that may contain a capabiltiy + // for the deletion of the previous file at the given target path + optional FileCredentials creds = 2; +} + +// flags for the 'access' call +enum ACCESS_FLAGS { + ACCESS_FLAGS_F_OK = 0; // existence + ACCESS_FLAGS_X_OK = 1; // execute permission + ACCESS_FLAGS_W_OK = 2; // write permission + ACCESS_FLAGS_R_OK = 4; // read permission +} + +// checks whether access is granted to a file or directory +message accessRequest { + // the volume name + required string volume_name = 1; + // the path to the file or directory, relative to the volume root + required string path = 2; + // the flags for which the access is supposed to be checked; + // see ACCESS_FLAGS + required fixed32 flags = 3; +} + +message xtreemfs_check_file_existsRequest { + required string volume_id = 1; + repeated string file_ids = 2; + required string osd_uuid = 3; +} + +message xtreemfs_check_file_existsResponse { + required bool volume_exists = 1; + + enum FILE_STATE { + DELETED=0; + REGISTERED=1; + ABANDONED=2; + } + repeated FILE_STATE file_states = 2 [packed=true]; +} + +// dumps or restores the MRC database +message xtreemfs_dump_restore_databaseRequest { + // the path to the dump file on the MRC host + required string dump_file = 1; +} + +// requests the list of suitable OSDs for new replicas of a file +message xtreemfs_get_suitable_osdsRequest { + // the file ID + optional string file_id = 1; + // or path and volume_name to file. + optional string path = 3; + optional string volume_name = 4; + // the number of OSDs required in a valid group + // ignored by filtering and sorting policies + required fixed32 num_osds = 2; +} + +// returns a list of suitable OSDs +message xtreemfs_get_suitable_osdsResponse { + repeated string osd_uuids = 1; +} + +message timestampResponse { + required fixed32 timestamp_s = 1; +} + +message stringMessage { + required string a_string = 1; +} + +message xtreemfs_listdirRequest { + required string path = 1; +} + +message xtreemfs_listdirResponse { + repeated string names = 1; +} + +// adds a replica to a file +message xtreemfs_replica_addRequest { + // the file ID + optional string file_id = 1; + // or path and volume_name to file. + optional string path = 3; + optional string volume_name = 4; + // the replica to add + required Replica new_replica = 2; +} + +// requests a list of all replicas of a file (deprecated) +message xtreemfs_replica_listRequest { + // the file ID + optional string file_id = 1; + // or path and volume_name to file. + optional string path = 2; + optional string volume_name = 3; +} + +// requests the xLocSet of a file +message xtreemfs_get_xlocsetRequest { + // the file ID + optional string file_id = 1; + // or path and volume_name to file + optional string path = 2; + optional string volume_name = 3; + // or a valid XCap. + optional XCap xcap = 4; +} + +// removes a replica from a file +message xtreemfs_replica_removeRequest { + // the file ID + optional string file_id = 1; + // or path and volume_name to file. + optional string path = 3; + optional string volume_name = 4; + // the UUID of the head OSD of the replica to remove + required string osd_uuid = 2; +} + +// restores a file w/ orphaned file content by creating a new metadata object +message xtreemfs_restore_fileRequest { + // the path to the restored file + required string file_path = 1; + // the file ID + required string file_id = 2; + // the file size + required fixed64 file_size = 3; + // the UUID of the OSD with the orphaned file content + required string osd_uuid = 4; + // the stripe size of the file + required fixed32 stripe_size = 5; +} + +// deletes a volume +message xtreemfs_rmvolRequest { + // the name of the volume to delete + required string volume_name = 1; +} + +// updates the size of an open file +message xtreemfs_update_file_sizeRequest { + // the capability that was returned when opening the file + required XCap xcap = 1; + // the OSDWriteResponse received from an OSD that contains the new file size + required OSDWriteResponse osd_write_response = 2; + // a flag indicating that the file is supposed to be closed + optional bool close_file = 3; + // the client's Vivaldi coordinates (e.g. used for creating replicas at + // specific locations when the file is closed) + optional VivaldiCoordinates coordinates = 4; +} + +// sets the replica update policy of a file by ID +message xtreemfs_set_replica_update_policyRequest { + // the file ID + required string file_id = 1; + // the new replica update policy + required string update_policy = 2; +} + +// returns the old replica update policy when setting a new one +message xtreemfs_set_replica_update_policyResponse { + // the old replica update policy + required string old_update_policy = 1; +} + +// sets the read-only flag of a file by ID +message xtreemfs_set_read_only_xattrRequest { + // the file ID + required string file_id = 1; + // the read-only flag to set + required bool value = 2; +} + +message xtreemfs_set_read_only_xattrResponse { + required bool was_set = 1; +} + +message xtreemfs_get_file_credentialsRequest{ + required string file_id = 1; +} + +service MRCService { + + option(interface_id)=20001; + + // POSIX/FUSE operations ---------------------------------------- + + // sets attributes of an open file + rpc fsetattr(fsetattrRequest) returns(emptyResponse) { + option(proc_id)=2; + }; + + // truncates an open file + rpc ftruncate(XCap) returns(XCap) { + option(proc_id)=3; + }; + + // returns attributes of a file or directory + rpc getattr(getattrRequest) returns(getattrResponse) { + option(proc_id)=4; + }; + + // returns an extended attribute of a file or directory + rpc getxattr(getxattrRequest) returns(getxattrResponse) { + option(proc_id)=5; + }; + + // creates a hardlink to a file + rpc link(linkRequest) returns(timestampResponse) { + option(proc_id)=6; + }; + + // returns the list of extended attributes of a file or directory + rpc listxattr(listxattrRequest) returns(listxattrResponse) { + option(proc_id)=7; + }; + + // creates a new directory + rpc mkdir(mkdirRequest) returns(timestampResponse) { + option(proc_id)=8; + }; + + // opens an existing file to obtain file credentials + rpc open(openRequest) returns(openResponse) { + option(proc_id)=9; + }; + + // returns a list of all nested files and directories in a directory + rpc readdir(readdirRequest) returns(DirectoryEntries) { + option(proc_id)=10; + }; + + // returns the target path of a symbolic link + rpc readlink(readlinkRequest) returns(readlinkResponse) { + option(proc_id)=11; + }; + + // removes an extended attribute from a file or directory + rpc removexattr(removexattrRequest) returns(timestampResponse) { + option(proc_id)=12; + }; + + // renames a file or directory + rpc rename(renameRequest) returns(renameResponse) { + option(proc_id)=13; + }; + + // removes an empty directory + rpc rmdir(rmdirRequest) returns(timestampResponse) { + option(proc_id)=14; + }; + + // sets attributes of a file or directory + rpc setattr(setattrRequest) returns(timestampResponse) { + option(proc_id)=15; + }; + + // sets an extended attribute of a file or directory + rpc setxattr(setxattrRequest) returns(timestampResponse) { + option(proc_id)=16; + }; + + // returns information about a mounted volume + rpc statvfs(statvfsRequest) returns(StatVFS) { + option(proc_id)=17; + }; + + // creates a symbolic link to a file or directory + rpc symlink(symlinkRequest) returns(timestampResponse) { + option(proc_id)=18; + }; + + // removes a link to a file and removes the file if no more links exist + rpc unlink(unlinkRequest) returns(unlinkResponse) { + option(proc_id)=19; + }; + + // checks access to a file or directory + rpc access(accessRequest) returns(emptyResponse) { + option(proc_id)=20; + }; + + //-- XtreemFS specific operations ------------------------------------- + + // enforces a database checkpoint on the MRC + rpc xtreemfs_checkpoint(emptyRequest) returns(emptyResponse) { + option(proc_id)=30; + }; + + // checks if a certain set of files exist + rpc xtreemfs_check_file_exists(xtreemfs_check_file_existsRequest) returns(xtreemfs_check_file_existsResponse) { + option(proc_id)=31; + }; + + // dumps the MRC database to a dump file on the MRC host + rpc xtreemfs_dump_database(xtreemfs_dump_restore_databaseRequest) returns(emptyResponse) { + option(proc_id)=32; + }; + + // returns the list of suitable OSDs for replicas of a given file + rpc xtreemfs_get_suitable_osds(xtreemfs_get_suitable_osdsRequest) returns(xtreemfs_get_suitable_osdsResponse) { + option(proc_id)=33; + }; + + // call for internal debugging purposes + rpc xtreemfs_internal_debug(stringMessage) returns(stringMessage) { + option(proc_id)=34; + }; + + + rpc xtreemfs_listdir(xtreemfs_listdirRequest) returns(xtreemfs_listdirResponse) { + option(proc_id)=35; + }; + + // returns a list of all volumes on the MRC + rpc xtreemfs_lsvol(emptyRequest) returns(Volumes) { + option(proc_id)=36; + }; + + // creates a new volume + rpc xtreemfs_mkvol(Volume) returns(emptyResponse) { + option(proc_id)=47; + }; + + // renews an existing capability to extend the validity period + rpc xtreemfs_renew_capability(XCap) returns(XCap) { + option(proc_id)=37; + }; + + rpc xtreemfs_replication_to_master(emptyRequest) returns(emptyResponse) { + option(proc_id)=38; + }; + + // adds a replica to a file + rpc xtreemfs_replica_add(xtreemfs_replica_addRequest) returns(emptyResponse) { + option(proc_id)=39; + }; + + // lists all replicas of a file (deprecated) + rpc xtreemfs_replica_list(xtreemfs_replica_listRequest) returns(Replicas) { + option(proc_id)=40; + }; + + // removes a replica from a file + rpc xtreemfs_replica_remove(xtreemfs_replica_removeRequest) returns(FileCredentials) { + option(proc_id)=41; + }; + + // restores the MRC database from a dump file on the MRC host + rpc xtreemfs_restore_database(xtreemfs_dump_restore_databaseRequest) returns(emptyResponse) { + option(proc_id)=42; + }; + + // restores a file on the MRC for which orphaned objects exist on an OSD + rpc xtreemfs_restore_file(xtreemfs_restore_fileRequest) returns(emptyResponse) { + option(proc_id)=43; + }; + + // deletes a volume + rpc xtreemfs_rmvol(xtreemfs_rmvolRequest) returns(emptyResponse) { + option(proc_id)=44; + }; + + // terminates the MRC + rpc xtreemfs_shutdown(emptyRequest) returns(emptyResponse) { + option(proc_id)=45; + }; + + // updates the size of a file and indicates that a file was closed + rpc xtreemfs_update_file_size(xtreemfs_update_file_sizeRequest) returns(timestampResponse) { + option(proc_id)=46; + }; + + // sets the replica update policy on a file identified by a file ID (privileged users only!) + rpc xtreemfs_set_replica_update_policy(xtreemfs_set_replica_update_policyRequest) returns(xtreemfs_set_replica_update_policyResponse) { + option(proc_id)=48; + }; + + // sets the read-only attribute on a file identified by a file ID (privileged users only!) + rpc xtreemfs_set_read_only_xattr(xtreemfs_set_read_only_xattrRequest) returns(xtreemfs_set_read_only_xattrResponse) { + option(proc_id)=49; + }; + + // returns a set of file credentials (capability + XLocList) for a file identified by a file ID (privileged users only!) + rpc xtreemfs_get_file_credentials(xtreemfs_get_file_credentialsRequest) returns(FileCredentials) { + option(proc_id)=50; + }; + + // Returns the current xLocSet for the specified file. + rpc xtreemfs_get_xlocset(xtreemfs_get_xlocsetRequest) returns(XLocSet) { + option(proc_id)=51; + }; +} diff --git a/interface/xtreemfs/OSD.proto b/interface/xtreemfs/OSD.proto new file mode 100644 index 0000000..c8d896e --- /dev/null +++ b/interface/xtreemfs/OSD.proto @@ -0,0 +1,582 @@ +// +// Copyright (c) 2009-2011, Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// +// All rights reserved. +// +// 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 the Konrad-Zuse-Zentrum fuer Informationstechnik Berlin +// 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 HOLDER 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. +// +// AUTHORS: Bjoern Kolbeck (ZIB), Jan Stender (ZIB) +// + +option java_package="org.xtreemfs.pbrpc.generatedinterfaces"; +package xtreemfs.pbrpc; +import "include/PBRPC.proto"; +import "include/Common.proto"; +import "xtreemfs/GlobalTypes.proto"; + +// Message sent between OSDs when the size of a striped file changes. +// Optimization to reduce communication between servers for sparse files +// and to handle EOF. +message InternalGmax { + required fixed64 epoch = 1; + required fixed64 file_size = 2; + required fixed64 last_object_id = 3; +} + +// POSIX file lock. +message Lock { + // Process ID, must be unique per client, + // i.e. client_pid+uuid must be globally unique. + required fixed32 client_pid = 1; + // UUID for client, can be temporary. + required string client_uuid = 2; + // Length of byte range for the lock. + required fixed64 length = 3; + // Offset of the locked byte range. + required fixed64 offset = 4; + // If true, lock is exclusive. + required bool exclusive = 5; +} + +// Contains details on object data which is now sent in +// the data fragment of the RPC protocol. +message ObjectData { + // Data checksum (Adler32), if checksums are enabled. + required fixed32 checksum = 1; + // True, if the checksum doesn't match the data on the OSD. + required bool invalid_checksum_on_osd = 2; + // Number of zeros the client must append to data before delivering + // data to an application (for sparse files). + // When returned by the xtreemfs_check_object method + // it stores the total number of bytes(data + sparse data) + required fixed32 zero_padding = 3; +} + +// List of objects which an OSD has stored locally. +// Used by the read-only replication to optimize +// fetching of missing objects. +message ObjectList { + // serialized data type + required bytes set = 1; + required fixed32 stripe_width = 2; + required fixed32 first_ = 3; +} + +// Version information for an object. +// Used to generate a mapping from object_number +// to object_version. Used by the read-write replication. +message ObjectVersion { + required fixed64 object_number = 1; + required fixed64 object_version = 2; +} + +// Entry for the truncate log required by the read-write +// replication. For each truncate, a version number is +// assigned and a record is appended to the truncate log. +message TruncateRecord { + required fixed64 version = 1; + required fixed64 last_object_number = 2; +} + +message TruncateLog { + repeated TruncateRecord records = 1; +} + +// Version of the latest XLocSet a Replica has beeen part of +// and a flag indicating if the Replica is currently participating +// in a XLocSetChange +message XLocSetVersionState { + required fixed32 version = 1; + required bool invalidated = 2; + optional fixed64 modified_time = 3; +} + +// Full status of a replica. Used by the read-write +// replication during Replica Reset. +message ReplicaStatus { + // Current truncate epoch. + required fixed64 truncate_epoch = 1; + // Local file size. + required fixed64 file_size = 2; + // Last object version stored locally. + required fixed64 max_obj_version = 3; + // Primary epoch number (aka Master Epoch). + required fixed32 primary_epoch = 4; + // List of objects and their version. + repeated ObjectVersion objectVersions = 5; + // Truncate log. + required TruncateLog truncate_log = 6; +} + +// Mapping from object_number/version to OSDs that have +// a copy of this object. Used by the rw-replication. +message ObjectVersionMapping { + required fixed64 object_number = 1; + required fixed64 object_version = 2; + repeated string osd_uuids = 3; +} + +// Correct replica state sent by the Primary to all +// backups. After receiving this information, backups +// will bring themselves to the authoritative state by +// fetching missing data and deleting outdated objects. +message AuthoritativeReplicaState { + required fixed64 truncate_epoch = 1; + required fixed64 max_obj_version = 4; + repeated ObjectVersionMapping objectVersions = 2; + required TruncateLog truncate_log = 3; +} + +// Response sent by an OSD when reading objects for +// the ro/rw replication. +message InternalReadLocalResponse { + required ObjectData data = 1; + // List of objects the OSD has. + repeated ObjectList object_set = 2; +} + +message readRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + // Object number starting at 0. + required fixed64 object_number = 3; + // Version, currently ignored. + required fixed64 object_version = 4; + // Offset within the object. + required fixed32 offset = 5; + // Length of data to be read, must be <= stripe_size - offset. + required fixed32 length = 6; +} + +message truncateRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + // New file size in bytes. + required fixed64 new_file_size = 3; +} + +message unlink_osd_Request { + required FileCredentials file_credentials = 1; + required string file_id = 2; +} + +message writeRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + // Object number starting at 0. + required fixed64 object_number = 3; + // Version, currently ignored. + required fixed64 object_version = 4; + // Offset within the object. + required fixed32 offset = 5; + // Timeout of the client lease, if set. + // Reserved for client-side-caching, currently not used. + required fixed64 lease_timeout = 6; + // Only the checksum of ObjectData is used. + required ObjectData object_data = 7; +} + +// Internal message sent between OSDs of a striped file. +// Transmitted via UDP. +message xtreemfs_broadcast_gmaxRequest{ + required string file_id = 1; + required fixed64 truncate_epoch = 2; + required fixed64 last_object = 3; + required fixed64 file_size = 4; +} + +message xtreemfs_check_objectRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + required fixed64 object_number = 3; + required fixed64 object_version = 4; +} + +message xtreemfs_cleanup_get_resultsResponse { + // Human readable English status and error messages. + repeated string results = 1; +} + +message xtreemfs_cleanup_is_runningResponse { + required bool is_running = 1; +} + +message xtreemfs_cleanup_startRequest { + // If true, objects for deleted files are deleted as well. + required bool remove_zombies = 1; + // If true, files for which the MRC cannot be contacted or + // where no volume DIR entry exists are deleted. + required bool remove_unavail_volume = 2; + // If true, objects are not deleted but moved to lost and found. + required bool lost_and_found = 3; + // Delete metadata of deleted or abandoned files. + required bool delete_metadata = 4; + // Time in seconds to wait after the last view update before + // deleting metadata. + required fixed32 metadata_timeout = 5; +} + +message xtreemfs_cleanup_statusResponse { + required string status = 1; +} + +message xtreemfs_rwr_fetchRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + required fixed64 object_number = 3; + required fixed64 object_version = 4; +} + +message xtreemfs_repair_objectRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + required fixed64 object_number = 3; + required fixed64 object_version = 4; +} + +message xtreemfs_rwr_flease_msgRequest { + // The actual flease message is sent in data. + required string sender_hostname = 1; + required fixed32 sender_port = 2; +} + +message xtreemfs_rwr_set_primary_epochRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + required fixed32 primary_epoch = 3; +} + +message xtreemfs_rwr_statusRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + // Maximum local object version stored on an OSD. + required fixed64 max_local_obj_version = 3; +} + +message xtreemfs_rwr_truncateRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + required fixed64 new_file_size = 3; + required fixed64 object_version = 4; +} + +message xtreemfs_rwr_updateRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + required fixed64 new_file_size = 3; + required fixed64 object_number = 7; + required fixed64 object_version = 4; + required fixed32 offset = 5; + required ObjectData obj = 6; +} + +message xtreemfs_internal_get_gmaxRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; +} + +message xtreemfs_internal_get_file_sizeRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; +} + +message xtreemfs_internal_get_file_sizeResponse { + // File size in bytes (as seen by local OSD). + required fixed64 file_size = 1; +} + +message xtreemfs_internal_read_localRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + required fixed64 object_number = 3; + required fixed64 object_version = 4; + required fixed32 offset = 5; + required fixed32 length = 6; + required bool attach_object_list = 7; + repeated ObjectList required_objects = 8; +} + +message xtreemfs_internal_get_object_setRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; +} + +message xtreemfs_internal_get_fileid_listResponse { + repeated string file_ids = 1; +} +message lockRequest { + required FileCredentials file_credentials = 1; + required Lock lock_request = 2; +} + +message xtreemfs_pingMesssage { + required VivaldiCoordinates coordinates = 1; + required bool request_response = 2; +} + +message xtreemfs_rwr_auth_stateRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + required AuthoritativeReplicaState state = 3; +} + +message xtreemfs_rwr_reset_completeRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; + required fixed32 primary_epoch = 3; +} + +message xtreemfs_xloc_set_invalidateRequest { + required FileCredentials file_credentials = 1; + required string file_id = 2; +} + +message xtreemfs_xloc_set_invalidateResponse { + required LeaseState lease_state = 1; + optional ReplicaStatus replica_status = 2; +} + +// Status of OSD health test +enum OSDHealthResult { + OSD_HEALTH_RESULT_PASSED = 0; + OSD_HEALTH_RESULT_WARNING = 1; + OSD_HEALTH_RESULT_FAILED = 2; + // Status is not available, + // i.e. the test is disabled or an error occurred + OSD_HEALTH_RESULT_NOT_AVAIL = 3; +} + +service OSDService { + + option(interface_id)=30001; + + // POSIX/FUSE operations ---------------------------------------- + // See POSIX for details. + + // Client read operation with POSIX semantics. + // In case of EOF, read returns less data than requested. + rpc read(readRequest) returns(ObjectData) { + option(proc_id)=10; + option(data_out)=true; + }; + + // Truncates a file. + // OSDWriteResponse may contain new file size, if it changed. + // The OSDWriteResponse should be sent to the MRC immediately. + rpc truncate(truncateRequest) returns(OSDWriteResponse) { + option(proc_id)=11; + }; + + // Deletes the objects of a file. + rpc unlink(unlink_osd_Request) returns(emptyResponse) { + option(proc_id)=12; + }; + + // Client write operation. + // If an OSDWriteResponse with a new file size is returned, + // it can be cached by the client and relayed to the MRC + // at a later point. + // However, the cached file size must be considered + // when a local process stats the file. + // If a fsync or close is truncated, the file size must first + // be written to the MRC *before* the call returns. + rpc write(writeRequest) returns(OSDWriteResponse) { + option(proc_id)=13; + option(data_in)=true; + }; + + // XtreemFS specific ops ---------------------------------------- + + // Sent only via UDP. After a write to a striped file that modifies the file size, + // an OSD will sent this hint to all other OSDs in the stripe. + // These hints are used to handle EOF and holes in sparse files correctly. + // However, they are not necessary for correct operations. + rpc xtreemfs_broadcast_gmax(xtreemfs_broadcast_gmaxRequest) returns(emptyResponse) { + option(proc_id)=20; + }; + + // The OSD reads the object from the local disk, and if enabled calculates and + // compares the checksum. + rpc xtreemfs_check_object(xtreemfs_check_objectRequest) returns(ObjectData) { + option(proc_id)=21; + }; + + // Returns the messages produces by the OSD cleanup process. Requires AUTH_PASSWORD. + rpc xtreemfs_cleanup_get_results(emptyRequest) returns(xtreemfs_cleanup_get_resultsResponse) { + option(proc_id)=30; + }; + + // Checks if the OSD cleanup process is running. Requires AUTH_PASSWORD. + rpc xtreemfs_cleanup_is_running(emptyRequest) returns(xtreemfs_cleanup_is_runningResponse) { + option(proc_id)=31; + }; + + // Starts the OSD cleanup process (removes orphaned objects). Requires AUTH_PASSWORD. + rpc xtreemfs_cleanup_start(xtreemfs_cleanup_startRequest) returns(emptyResponse) { + option(proc_id)=32; + }; + + // Returns a short status message of the cleanup process. + // Can be used for (G)UIs to report progress. Requires AUTH_PASSWORD. + rpc xtreemfs_cleanup_status(emptyRequest) returns(xtreemfs_cleanup_statusResponse) { + option(proc_id)=33; + }; + + // Stops the OSD cleanup process. Requires AUTH_PASSWORD. + rpc xtreemfs_cleanup_stop(emptyRequest) returns(emptyResponse) { + option(proc_id)=34; + }; + + // Removes superflous object versions. + // Part of the experimental snapshots implementation. + rpc xtreemfs_cleanup_versions_start(emptyRequest) returns(emptyResponse) { + option(proc_id)=35; + }; + + // Triggers the OSD to fetch an Object form another Replica. + rpc xtreemfs_repair_object(xtreemfs_repair_objectRequest) returns(emptyResponse) { + option(proc_id)=36; + }; + + // Reads a specific object version from the OSD. Used by the read-write replication. + rpc xtreemfs_rwr_fetch(xtreemfs_rwr_fetchRequest) returns(ObjectData) { + option(proc_id)=73; + }; + + // Wrapper for flease messages. Flease is used for primary election + // in the rw-replication. + rpc xtreemfs_rwr_flease_msg(xtreemfs_rwr_flease_msgRequest) returns(emptyResponse) { + option(proc_id)=71; + option(data_in)=true; + }; + + // No-op used to inform an OSD that the replica set changed. + rpc xtreemfs_rwr_notify(FileCredentials) returns(emptyResponse) { + option(proc_id)=75; + } + + // Stores the primary epoch on the OSD. + rpc xtreemfs_rwr_set_primary_epoch(xtreemfs_rwr_set_primary_epochRequest) returns(ObjectData) { + option(proc_id)=78; + }; + + // Returns the replica status for a file on the local OSD. + rpc xtreemfs_rwr_status(xtreemfs_rwr_statusRequest) returns(ReplicaStatus) { + option(proc_id)=76; + }; + + // Executes the truncate on the backup replicas. + // A version number must have been assigned by the primary. + rpc xtreemfs_rwr_truncate(xtreemfs_rwr_truncateRequest) returns(emptyResponse) { + option(proc_id)=74; + }; + + // Executes the write on the backup replicas. + // A version number must have been assigned by the primary. + rpc xtreemfs_rwr_update(xtreemfs_rwr_updateRequest) returns(emptyResponse) { + option(proc_id)=72; + option(data_in)=true; + }; + + // Sets the authoritative state on a backup OSD. + // Only primaries can send this operation. + rpc xtreemfs_rwr_auth_state(xtreemfs_rwr_auth_stateRequest) returns(emptyResponse) { + option(proc_id)=79; + }; + + // Informs the primary that a backup has completed the RESET. + rpc xtreemfs_rwr_reset_complete(xtreemfs_rwr_reset_completeRequest) returns(emptyResponse) { + option(proc_id)=80; + }; + + // Returns the local file size information on an OSD. + // Used to determine the real file size of a striped file. + rpc xtreemfs_internal_get_gmax(xtreemfs_internal_get_gmaxRequest) returns(InternalGmax) { + option(proc_id)=40; + }; + + // Truncate operation sent by the head OSD to the other stripes. + // Only for striped files. + rpc xtreemfs_internal_truncate(truncateRequest) returns(OSDWriteResponse) { + option(proc_id)=41; + }; + + // Returns the file size. + rpc xtreemfs_internal_get_file_size(xtreemfs_internal_get_file_sizeRequest) returns(xtreemfs_internal_get_file_sizeResponse) { + option(proc_id)=42; + }; + + // Reads an object from a remote OSD, used by the ronly-replication. + rpc xtreemfs_internal_read_local(xtreemfs_internal_read_localRequest) returns(InternalReadLocalResponse) { + option(proc_id)=43; + }; + + // Returns the list of objects that an OSD has stored for a file. + rpc xtreemfs_internal_get_object_set(xtreemfs_internal_get_object_setRequest) returns(ObjectList) { + option(proc_id)=44; + }; + + // Returns a list of file ids stored on the OSD. + rpc xtreemfs_internal_get_fileid_list(emptyRequest) returns(xtreemfs_internal_get_fileid_listResponse) { + option(proc_id)=45; + } + + // Acquires a file lock. See POSIX fcntl locks. + rpc xtreemfs_lock_acquire(lockRequest) returns(Lock) { + option(proc_id)=50; + }; + + // Checks a file lock. See POSIX fcntl locks. + rpc xtreemfs_lock_check(lockRequest) returns(Lock) { + option(proc_id)=51; + }; + + // Releases a file lock. See POSIX fcntl locks. + rpc xtreemfs_lock_release(lockRequest) returns(emptyResponse) { + option(proc_id)=52; + }; + + // Simple RPC ping. + rpc xtreemfs_ping(xtreemfs_pingMesssage) returns(xtreemfs_pingMesssage) { + option(proc_id)=60; + }; + + // Shuts the OSD down. Requires AUTH_PASSWORD. + rpc xtreemfs_shutdown(emptyRequest) returns(emptyResponse) { + option(proc_id)=70; + }; + + // Invalidate the replicas location set. + rpc xtreemfs_xloc_set_invalidate(xtreemfs_xloc_set_invalidateRequest) returns(xtreemfs_xloc_set_invalidateResponse) { + option(proc_id)=81; + }; + + // Sets the authoritative state on a replica during an xLocSet change. + // This operation invalidets replicas not yet invalidated and does not require + // a valid view. + rpc xtreemfs_rwr_auth_state_invalidated(xtreemfs_rwr_auth_stateRequest) returns(emptyResponse) { + option(proc_id)=82; + }; +} diff --git a/java/flease/build-1.6.5.xml b/java/flease/build-1.6.5.xml new file mode 100644 index 0000000..fe9bf3a --- /dev/null +++ b/java/flease/build-1.6.5.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + Builds, tests, and runs the project Flease. + + + + diff --git a/java/flease/build.xml b/java/flease/build.xml new file mode 100644 index 0000000..b69101e --- /dev/null +++ b/java/flease/build.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + Builds, tests, and runs the project Flease. + + + + diff --git a/java/flease/eclipse-project/.classpath b/java/flease/eclipse-project/.classpath new file mode 100644 index 0000000..242f08e --- /dev/null +++ b/java/flease/eclipse-project/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/java/flease/eclipse-project/.project b/java/flease/eclipse-project/.project new file mode 100644 index 0000000..372a047 --- /dev/null +++ b/java/flease/eclipse-project/.project @@ -0,0 +1,18 @@ + + + xtreemfs_flease + + + xtreemfs_foundation + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/java/flease/manifest.mf b/java/flease/manifest.mf new file mode 100644 index 0000000..328e8e5 --- /dev/null +++ b/java/flease/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/java/flease/nbproject/build-impl-1.6.5.xml b/java/flease/nbproject/build-impl-1.6.5.xml new file mode 100644 index 0000000..3a1ab62 --- /dev/null +++ b/java/flease/nbproject/build-impl-1.6.5.xml @@ -0,0 +1,892 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/flease/nbproject/build-impl.xml b/java/flease/nbproject/build-impl.xml new file mode 100644 index 0000000..acc75ed --- /dev/null +++ b/java/flease/nbproject/build-impl.xml @@ -0,0 +1,1054 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/flease/nbproject/genfiles.properties b/java/flease/nbproject/genfiles.properties new file mode 100644 index 0000000..b812a41 --- /dev/null +++ b/java/flease/nbproject/genfiles.properties @@ -0,0 +1,11 @@ +build.xml.data.CRC32=3d699ec7 +build.xml.script.CRC32=d8a5a904 +build.xml.stylesheet.CRC32=958a1d3e@1.26.2.45 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=d06e30bd +nbproject/build-impl.xml.script.CRC32=318c6c3f +nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45 +nbproject/profiler-build-impl.xml.data.CRC32=3d699ec7 +nbproject/profiler-build-impl.xml.script.CRC32=abda56ed +nbproject/profiler-build-impl.xml.stylesheet.CRC32=42cb6bcf@1.6.1 diff --git a/java/flease/nbproject/private/config.properties b/java/flease/nbproject/private/config.properties new file mode 100644 index 0000000..e69de29 diff --git a/java/flease/nbproject/private/private.properties b/java/flease/nbproject/private/private.properties new file mode 100644 index 0000000..ba93c2b --- /dev/null +++ b/java/flease/nbproject/private/private.properties @@ -0,0 +1,6 @@ +compile.on.save=true +do.depend=false +do.jar=true +javac.debug=true +javadoc.preview=true +user.properties.file=/home/kleineweber/.netbeans/7.0/build.properties diff --git a/java/flease/nbproject/private/private.xml b/java/flease/nbproject/private/private.xml new file mode 100644 index 0000000..e571abf --- /dev/null +++ b/java/flease/nbproject/private/private.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/java/flease/nbproject/private/profiler/configurations.xml b/java/flease/nbproject/private/profiler/configurations.xml new file mode 100644 index 0000000..692945a --- /dev/null +++ b/java/flease/nbproject/private/profiler/configurations.xml @@ -0,0 +1,141 @@ + + + +1000 +false +profiler.simple.filter +false + + +8 +true + +false +false +0 +0 +false +2 +true +false +false + +profiler.simple.filter +1 +32 +1 +false +3 +true +true +3 +10 +1 +true +New CPU Analysis +false +1 +true +Quick filter... +10 +0 +false +0 +profiler.simple.filter +0 +false +true + + + +1 + + +false +false +false +true +false +false +32 +Quick filter... +0 +false +0 +0 + +profiler.simple.filter +10 +0 +true +true +Profile all classes +true +10 +true + +1000 +0 +true +1000 +0 +profiler.simple.filter +false +10 +Analyze Performance + +1 +0 + +0 +false +profiler.simple.filter +true +Quick filter... +false +false +false +0 + + +false +0 +32 + +0 +32 +0 +profiler.simple.filter +Analyze Memory +2 +false +Profile all classes +0 +0 +10 +profiler.simple.filter +true +1 +true +false +10 + +false +10 +false +true +false +true +false +Quick filter... +0 +false +false + +false +8 +Monitor Application +1000 +true +true + diff --git a/java/flease/nbproject/profiler-build-impl.xml b/java/flease/nbproject/profiler-build-impl.xml new file mode 100644 index 0000000..7c8995d --- /dev/null +++ b/java/flease/nbproject/profiler-build-impl.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/flease/nbproject/project.properties b/java/flease/nbproject/project.properties new file mode 100644 index 0000000..0c6fd61 --- /dev/null +++ b/java/flease/nbproject/project.properties @@ -0,0 +1,73 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +application.title=Flease +application.vendor=bjko +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Flease.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +includes=** +jar.compress=false +javac.classpath=\ + ${reference.XtreemFS-foundation.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.6 +javac.target=1.6 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit_4.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class= +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +project.XtreemFS-foundation=../foundation +reference.XtreemFS-foundation.jar=${project.XtreemFS-foundation}/dist/Foundation.jar +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs=-ea +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/java/flease/nbproject/project.xml b/java/flease/nbproject/project.xml new file mode 100644 index 0000000..48b1ff4 --- /dev/null +++ b/java/flease/nbproject/project.xml @@ -0,0 +1,24 @@ + + org.netbeans.modules.java.j2seproject + + + Flease + + + + + + + + + + XtreemFS-foundation + jar + + jar + clean + jar + + + + diff --git a/java/flease/nbproject/protobuf-build.cfg.xml b/java/flease/nbproject/protobuf-build.cfg.xml new file mode 100644 index 0000000..fe07f64 --- /dev/null +++ b/java/flease/nbproject/protobuf-build.cfg.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/java/flease/nbproject/protobuf-build.xml b/java/flease/nbproject/protobuf-build.xml new file mode 100644 index 0000000..4bd0450 --- /dev/null +++ b/java/flease/nbproject/protobuf-build.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/flease/src/org/xtreemfs/foundation/flease/Flease.java b/java/flease/src/org/xtreemfs/foundation/flease/Flease.java new file mode 100644 index 0000000..024af34 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/Flease.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; + +/** + * Object represents a lease. + * @author bjko + */ +public class Flease { + + public static final Flease EMPTY_LEASE = new Flease(null,null, 0,FleaseMessage.IGNORE_MASTER_EPOCH); + + private final ASCIIString leaseHolder; + private final long leaseTimeout_ms; + private final ASCIIString cellId; + private final long masterEpochNumber; + + + public Flease(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long masterEpochNumber) { + this.cellId = cellId; + this.leaseHolder = leaseHolder; + this.leaseTimeout_ms = leaseTimeout_ms; + this.masterEpochNumber = masterEpochNumber; + } + + /** + * @return the leaseHolder + */ + public ASCIIString getLeaseHolder() { + return leaseHolder; + } + + /** + * @return the leaseTimeout_ms + */ + public long getLeaseTimeout_ms() { + return leaseTimeout_ms; + } + + public boolean isValid() { + return (TimeSync.getGlobalTime() < leaseTimeout_ms); + } + + public boolean isEmptyLease() { + return leaseTimeout_ms == 0; + } + + public boolean equals(Object other) { + try { + Flease o = (Flease) other; + + boolean sameTo = o.leaseTimeout_ms == this.leaseTimeout_ms; + return isSameLeaseHolder(o) && sameTo; + + } catch (ClassCastException ex) { + return false; + } + } + + public boolean isSameLeaseHolder(Flease o) { + return (o.leaseHolder == this.leaseHolder) || + (o.leaseHolder != null) && (this.leaseHolder != null) && (o.leaseHolder.equals(this.leaseHolder)); + } + + /** + * @return the cellId + */ + ASCIIString getCellId() { + return cellId; + } + + public String toString() { + return (cellId == null ? "" : cellId.toString())+": "+ + (leaseHolder == null ? "null" : leaseHolder.toString())+"/"+ + leaseTimeout_ms; + } + + /** + * @return the masterEpochNumber + */ + public long getMasterEpochNumber() { + return masterEpochNumber; + } +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/FleaseConfig.java b/java/flease/src/org/xtreemfs/foundation/flease/FleaseConfig.java new file mode 100644 index 0000000..02564f7 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/FleaseConfig.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease; + +import java.net.InetSocketAddress; +import org.xtreemfs.foundation.buffer.ASCIIString; + +/** + * + * @author bjko + */ +public class FleaseConfig { + + /** + * maximum lease timeout used in the system + */ + private final int maxLeaseTimeout_ms; + + /** + * maximum clock drift allowed + */ + private final int dmax_ms; + + + /** + * used to discard old messages + */ + private final int messageTimeout_ms; + + /** + * time the proposer waits for an answer + */ + private final int roundTimeout_ms; + + private final int cellTimeout_ms; + + private final int restartWait_ms; + + private final int senderId; + + private final InetSocketAddress endpoint; + + private final ASCIIString identity; + + private final int maxRetries; + + private final boolean sendLearnMessages; + + private final int toNotification_ms; + + private final boolean debugPrintMessages; + + public FleaseConfig(int leaseTimeout_ms, int dmax_ms, + int messageTimeout_ms, InetSocketAddress endpoint, + String identity, int maxRetries) { + this(leaseTimeout_ms,dmax_ms,messageTimeout_ms,endpoint,identity,maxRetries,true,0); + } + + public FleaseConfig(int leaseTimeout_ms, int dmax_ms, + int messageTimeout_ms, InetSocketAddress endpoint, + String identity, int maxRetries, boolean sendLearnMessages, + int toNotification_ms) { + this(leaseTimeout_ms, dmax_ms, messageTimeout_ms, endpoint, identity, maxRetries, sendLearnMessages, toNotification_ms, false); + } + + public FleaseConfig(int leaseTimeout_ms, int dmax_ms, + int messageTimeout_ms, InetSocketAddress endpoint, + String identity, int maxRetries, boolean sendLearnMessages, + int toNotification_ms, boolean debugPrintMessages) { + + this.maxLeaseTimeout_ms = leaseTimeout_ms; + this.dmax_ms = dmax_ms; + this.messageTimeout_ms = messageTimeout_ms; + this.cellTimeout_ms = maxLeaseTimeout_ms*2; + this.roundTimeout_ms = messageTimeout_ms*2; + + this.restartWait_ms = maxLeaseTimeout_ms+dmax_ms*2+messageTimeout_ms; + + this.endpoint = endpoint; + this.senderId = identity.hashCode(); + + checkValidConfiguration(); + this.identity = new ASCIIString(identity); + this.maxRetries = maxRetries; + + this.sendLearnMessages = sendLearnMessages; + this.toNotification_ms = toNotification_ms; + this.debugPrintMessages = debugPrintMessages; + + } + + public void checkValidConfiguration() { + + if (maxLeaseTimeout_ms < dmax_ms*2) { + throw new IllegalArgumentException("maxLeaseTimeout_ms must be at least twice as long as dmax_ms but should be much bigger"); + } + + if (maxLeaseTimeout_ms < dmax_ms*2+roundTimeout_ms*2) { + throw new IllegalArgumentException("maxLeaseTimeout_ms must be at least as long as dmax_ms*2+4*message_timeout but should be much bigger"); + } + } + + /** + * @return the leaseTimeout_ms + */ + public int getMaxLeaseTimeout() { + return maxLeaseTimeout_ms; + } + + /** + * @return the dmax_ms + */ + public int getDMax() { + return dmax_ms; + } + + /** + * @return the maxPxWait_ms + */ + public int getMessageTimeout() { + return messageTimeout_ms; + } + + /** + * @return the cellTimeout_ms + */ + public int getCellTimeout() { + return cellTimeout_ms; + } + + /** + * @return the restartWait_ms + */ + public int getRestartWait() { + return restartWait_ms; + } + + /** + * @return the senderId + */ + public int getSenderId() { + return senderId; + } + + /** + * @return the endpoint + */ + public InetSocketAddress getEndpoint() { + return endpoint; + } + + public ASCIIString getIdentity() { + return identity; + } + + public int getRoundTimeout() { + return roundTimeout_ms; + } + + public int getMaxRetries() { + return maxRetries; + } + + /** + * @return the sendLearnMessages + */ + public boolean isSendLearnMessages() { + return sendLearnMessages; + } + + /** + * @return the toNotification_ms + */ + public int getToNotification_ms() { + return toNotification_ms; + } + + /** + * @return the debugPrintMessages + */ + public boolean isDebugPrintMessages() { + return debugPrintMessages; + } + + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/FleaseFuture.java b/java/flease/src/org/xtreemfs/foundation/flease/FleaseFuture.java new file mode 100644 index 0000000..84f4da9 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/FleaseFuture.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease; + +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.proposer.FleaseException; +import org.xtreemfs.foundation.flease.proposer.FleaseListener; + +/** + * + * @author bjko + */ +public class FleaseFuture implements FleaseListener { + + private volatile Flease result; + + private volatile FleaseException error; + + FleaseFuture() { + result = null; + } + + public Flease get() throws FleaseException,InterruptedException { + + synchronized (this) { + if ((result == null) && (error == null)) + this.wait(); + + if (error != null) + throw error; + + return result; + } + + } + public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long masterEpochNumber) { + synchronized (this) { + result = new Flease(cellId,leaseHolder,leaseTimeout_ms,masterEpochNumber); + this.notifyAll(); + } + } + + public void proposalFailed(ASCIIString cellId, Throwable cause) { + synchronized (this) { + if (cause instanceof FleaseException) { + error = (FleaseException) cause; + } else { + error = new FleaseException(cause.getMessage(), cause); + } + this.notifyAll(); + } + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/FleaseMessageSenderInterface.java b/java/flease/src/org/xtreemfs/foundation/flease/FleaseMessageSenderInterface.java new file mode 100644 index 0000000..344c290 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/FleaseMessageSenderInterface.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease; + +import java.io.IOException; +import java.net.InetSocketAddress; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; + +/** + * + * @author bjko + */ +public interface FleaseMessageSenderInterface { + + public void sendMessage(FleaseMessage message, InetSocketAddress recipient); + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/FleaseStage.java b/java/flease/src/org/xtreemfs/foundation/flease/FleaseStage.java new file mode 100644 index 0000000..850ec04 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/FleaseStage.java @@ -0,0 +1,691 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.acceptor.FleaseAcceptor; +import org.xtreemfs.foundation.flease.acceptor.FleaseAcceptorCell; +import org.xtreemfs.foundation.flease.acceptor.LearnEventListener; +import org.xtreemfs.foundation.flease.comm.FleaseCommunicationInterface; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.flease.proposer.FleaseException; +import org.xtreemfs.foundation.flease.proposer.FleaseListener; +import org.xtreemfs.foundation.flease.proposer.FleaseLocalQueueInterface; +import org.xtreemfs.foundation.flease.proposer.FleaseProposer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * + * @author bjko + */ +public class FleaseStage extends LifeCycleThread implements LearnEventListener, FleaseLocalQueueInterface { + + public static final String FLEASE_VERSION = "0.2.4 (trunk)"; + + public static final int TIMER_INTERVAL_IN_MS = 50; + + public static final boolean ENABLE_TIMEOUT_EVENTS = true; + + public static final boolean DISABLE_RENEW_FOR_TESTING = false; + + public static final boolean COLLECT_STATISTICS = false; + + private final FleaseProposer proposer; + + private final FleaseAcceptor acceptor; + + private final PriorityQueue timers; + + private final PriorityQueue leaseTimeouts; + + private final LinkedBlockingQueue messages; + + private volatile boolean quit; + + private long lastTimerRun; + + private final FleaseConfig config; + + private final FleaseMessageSenderInterface sender; + + public static final int MAX_BATCH_SIZE = 20; + + private final FleaseStatusListener leaseListener; + + private final AtomicReference> durRequests, durMsgs, durTimers; + + private final AtomicInteger inRequests, inMsgs, inTimers, outMsgs; + + private final FleaseStats statThr; + + private final MasterEpochHandlerInterface meHandler; + + /** + * Creates a new instance of Flease. + * @param config flease configuration used for all cells and leases. + * @param lockfileDir a lockfile for this flease instance is created in this directory. + * @param sender interface to send flease messages to other flease nodes. + * @param ignoreLockForTesting should only be used by unit tests. + * @param viewListener not used at the moment, can be null. + * @param leaseListener listener is notified when the lease changes for any open cell. + * @param meHandler handler for storing/retrieving master epochs, can be null. + * @throws IOException + */ + public FleaseStage(FleaseConfig config, String lockfileDir, + final FleaseMessageSenderInterface sender, boolean ignoreLockForTesting, + final FleaseViewChangeListenerInterface viewListener, final FleaseStatusListener leaseListener, + final MasterEpochHandlerInterface meHandler) throws IOException { + super("FleaseSt"); + assert (sender != null); + assert(leaseListener != null); + + timers = new PriorityQueue(); + messages = new LinkedBlockingQueue(); + quit = false; + this.config = config; + this.leaseListener = leaseListener; + this.meHandler = meHandler; + + acceptor = new FleaseAcceptor(this, config, lockfileDir, ignoreLockForTesting); + proposer = new FleaseProposer(config, acceptor, new FleaseCommunicationInterface() { + + public void sendMessage(FleaseMessage msg, InetSocketAddress receiver) throws IOException { + sender.sendMessage(msg, receiver); + } + + public void requestTimer(FleaseMessage msg, long timestamp) { + createTimer(msg, timestamp); + } + }, leaseListener, this, this,meHandler); + acceptor.setViewChangeListener(viewListener); + proposer.setViewChangeListener(viewListener); + this.sender = sender; + + leaseTimeouts = new PriorityQueue(1000, new Comparator() { + + public int compare(Flease o1, Flease o2) { + return (int) (o1.getLeaseTimeout_ms() - o2.getLeaseTimeout_ms()); + } + }); + if (COLLECT_STATISTICS) { + durRequests = new AtomicReference(new LinkedList()); + durTimers = new AtomicReference(new LinkedList()); + durMsgs = new AtomicReference(new LinkedList()); + inRequests = new AtomicInteger(); + inTimers = new AtomicInteger(); + inMsgs = new AtomicInteger(); + outMsgs = new AtomicInteger(); + statThr = new FleaseStats(this, lockfileDir+"/flease.stats"); + } else { + durRequests = null; + durTimers = null; + durMsgs = null; + outMsgs = null; + inRequests = null; + inTimers = null; + inMsgs = null; + statThr = null; + } + } + + public ASCIIString getIdentity() { + return config.getIdentity(); + } + + @Deprecated + public FleaseFuture openCell(ASCIIString cellId, List acceptors, boolean requestMasterEpoch) { + return openCell(cellId, acceptors, requestMasterEpoch, 0); + } + + /** + * Opens a cell. The leaseListener will be notified of all lease events for this cell. The local flease + * instance will try to acquire the lease. + * + * @param cellId + * unique ID of the cell to open. + * @param acceptors + * list of remote flease instances, do not include local flease instance. + * @param requestMasterEpoch + * if true, a master epoch will be requested when the local instance is lease owner. + * @param viewId + * the current view id to open the cell with. + * @return + */ + public FleaseFuture openCell(ASCIIString cellId, List acceptors, boolean requestMasterEpoch, + int viewId) { + FleaseFuture f = new FleaseFuture(); + Request rq = new Request(Request.RequestType.OPEN_CELL_REQUEST); + rq.cellId = cellId; + rq.acceptors = acceptors; + rq.listener = f; + rq.requestME = requestMasterEpoch; + rq.viewId = viewId; + + if (COLLECT_STATISTICS) + inRequests.incrementAndGet(); + + this.messages.add(rq); + return f; + } + + public void batchOpenCells(ASCIIString[] cellIds, List[] acceptors, boolean requestMasterEpoch) { + + List batch = new ArrayList(cellIds.length); + for (int i =0; i < cellIds.length; i++) { + Request rq = new Request(Request.RequestType.OPEN_CELL_REQUEST); + rq.cellId = cellIds[i]; + rq.acceptors = acceptors[i]; + rq.listener = null; + rq.requestME = requestMasterEpoch; + batch.add(rq); + } + + for (int i = 0; i < batch.size(); i += MAX_BATCH_SIZE) { + int endIndex = i+MAX_BATCH_SIZE; + if (endIndex > batch.size()-1) + endIndex = batch.size(); + List sublist = batch.subList(i, endIndex); + + if (COLLECT_STATISTICS) + inRequests.addAndGet(sublist.size()); + + this.messages.addAll(sublist); + } + + } + + /** + * Closes a cell which must be open. If the local instance is the current lease owner, + * the lease will not be renewed. + * @param cellId + * @param returnLease if true, the lease will immediately be released. + * @return + */ + public FleaseFuture closeCell(ASCIIString cellId, boolean returnLease) { + // TODO(bjko): return lease, check if not_owner event is triggered. + FleaseFuture f = new FleaseFuture(); + Request rq = new Request(Request.RequestType.CLOSE_CELL_REQUEST); + rq.cellId = cellId; + rq.listener = f; + + if (COLLECT_STATISTICS) + inRequests.incrementAndGet(); + + this.messages.add(rq); + return f; + } + + public void setViewId(ASCIIString cellId, int viewId, FleaseListener listener) { + Request rq = new Request(Request.RequestType.SET_VIEW); + rq.cellId = cellId; + rq.viewId = viewId; + rq.listener = listener; + + if (COLLECT_STATISTICS) + inRequests.incrementAndGet(); + + this.messages.add(rq); + } + + public Map getLocalState() throws InterruptedException { + final Request rq = new Request(Request.RequestType.GET_STATE); + final Map[] map = new Map[1]; + rq.cback = new FleaseStateCallback() { + + public void localStateResult(Map state) { + synchronized (rq) { + map[0] = state; + rq.notifyAll(); + } + } + }; + this.messages.add(rq); + synchronized (rq) { + if (map[0] == null) { + rq.wait(); + } + return map[0]; + } + } + + public void receiveMessage(FleaseMessage msg) { + assert (msg.getSender() != null); + + if (COLLECT_STATISTICS) + inMsgs.incrementAndGet(); + + this.messages.add(msg); + } + + public FleaseMessage _test_get_local_lease_state(ASCIIString cellId) { + return acceptor.getLocalLeaseInformation(cellId); + } + + public String _dump_acceptor_state(ASCIIString cellId) { + FleaseAcceptorCell cell = acceptor.cells.get(cellId); + if (cell == null) { + return cellId + ": does not exist"; + } else { + return cellId + ": " + cell.toString(); + } + + } + + public void learnedEvent(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long masterEpochNumber) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"learned event: "+leaseHolder+"/"+leaseTimeout_ms); + } + Flease newFlease = new Flease(cellId, leaseHolder, leaseTimeout_ms, masterEpochNumber); + Flease oldFlease = proposer.updatePrevLeaseForCell(cellId, newFlease); + if (oldFlease != null) { + if (oldFlease.isValid()) { + if (!oldFlease.isSameLeaseHolder(newFlease)) { + Logging.logMessage( + Logging.LEVEL_DEBUG, + Category.replication, + this, + "New lease replaced old lease which is still valid according to this OSD's clocks. Make sure all OSD clocks are synchronized. New Lease: %s Old Lease: %s", + newFlease, oldFlease); + } + } + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"lease state change: %s %s %d",cellId,leaseHolder,leaseTimeout_ms); + } + leaseListener.statusChanged(cellId, newFlease); + if (ENABLE_TIMEOUT_EVENTS) { + leaseTimeouts.remove(oldFlease); + leaseTimeouts.add(newFlease); + } + } + } + + @Override + public void run() { + + if (COLLECT_STATISTICS) + statThr.start(); + + Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this, "Flease (version %s) ready", FLEASE_VERSION); + + notifyStarted(); + + // interval to check the OFT + + long nextTimerRunInMS = TIMER_INTERVAL_IN_MS; + lastTimerRun = 0; + + List rqList = new ArrayList(1000); + + while (!quit) { + try { + final Object tmp = messages.poll(nextTimerRunInMS, TimeUnit.MILLISECONDS); + + if (quit) { + break; + } + + if ((tmp == null) || + (TimeSync.getLocalSystemTime() >= lastTimerRun + nextTimerRunInMS)) { + if (ENABLE_TIMEOUT_EVENTS) { + //nextTimerRunInMS = + checkTimers(); + checkLeaseTimeouts(); + } else { + nextTimerRunInMS = checkTimers(); + } + lastTimerRun = TimeSync.getLocalSystemTime(); + } + if (tmp == null) { + continue; + } + + rqList.add(tmp); + messages.drainTo(rqList, 25); + /*final int numItems = messages.poll(rqList, 25, nextTimerRunInMS); + if ((numItems == 0) || + (TimeSync.getLocalSystemTime() >= lastTimerRun+nextTimerRunInMS)) { + nextTimerRunInMS = checkTimers(); + lastTimerRun = TimeSync.getLocalSystemTime(); + } + if (numItems == 0) + continue;*/ + + while (!rqList.isEmpty()) { + + final Object request = rqList.remove(rqList.size() - 1); + + long rqStart; + if (COLLECT_STATISTICS) { + rqStart = System.nanoTime(); + } + if (request instanceof FleaseMessage) { + final FleaseMessage msg = (FleaseMessage) request; + + if (msg.isInternalEvent()) { + //should never happen! + Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this, "received internal event: %s", msg); + } else if (msg.isAcceptorMessage()) { + final FleaseMessage response = acceptor.processMessage(msg); + if (response != null) { + if (msg.getMasterEpochNumber() == FleaseMessage.REQUEST_MASTER_EPOCH + && response.getMsgType() == FleaseMessage.MsgType.MSG_PREPARE_ACK) { + // Respond with the current master epoch. + if (meHandler != null) { + MasterEpochHandlerInterface.Continuation cont = new MasterEpochHandlerInterface.Continuation() { + @Override + public void processingFinished() { + sender.sendMessage(response, msg.getSender()); + } + }; + meHandler.sendMasterEpoch(response, cont); + } else { + Logging.logMessage(Logging.LEVEL_ERROR, this, + "MASTER EPOCH WAS REQUESTED, BUT NO MASTER EPOCH HANDLER DEFINED!!!"); + sender.sendMessage(response, msg.getSender()); + } + } else if (msg.getMasterEpochNumber() != FleaseMessage.IGNORE_MASTER_EPOCH + && response.getMsgType() == FleaseMessage.MsgType.MSG_ACCEPT_ACK) { + // Write the current master epoch to disk. + if (meHandler != null) { + MasterEpochHandlerInterface.Continuation cont = new MasterEpochHandlerInterface.Continuation() { + @Override + public void processingFinished() { + sender.sendMessage(response, msg.getSender()); + } + }; + meHandler.storeMasterEpoch(response, cont); + } + } else { + sender.sendMessage(response, msg.getSender()); + } + } + } else { + proposer.processMessage(msg); + } + if (COLLECT_STATISTICS) { + long rqEnd = System.nanoTime(); + durMsgs.get().add(Integer.valueOf((int)(rqEnd-rqStart))); + outMsgs.incrementAndGet(); + } + } else { + Request rq = (Request) request; + switch (rq.type) { + case OPEN_CELL_REQUEST: { + assert (rq.acceptors != null); + try { + proposer.openCell(rq.cellId, rq.acceptors, rq.requestME, rq.viewId); + acceptor.setViewId(rq.cellId, rq.viewId); + if (rq.listener != null) + rq.listener.proposalResult(rq.cellId, null, 0, FleaseMessage.IGNORE_MASTER_EPOCH); + } catch (FleaseException ex) { + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + leaseListener.leaseFailed(rq.cellId, ex); + } + break; + } + case CLOSE_CELL_REQUEST: { + proposer.closeCell(rq.cellId); + rq.listener.proposalResult(rq.cellId, null, 0, FleaseMessage.IGNORE_MASTER_EPOCH); + break; + } + case HANDOVER_LEASE: { + try { + Flease prevLease = proposer.updatePrevLeaseForCell(rq.cellId, Flease.EMPTY_LEASE); + if (prevLease != null) { + //cancel the lease + leaseTimeouts.remove(prevLease); + } + proposer.handoverLease(rq.cellId, rq.newLeaseOwner); + } catch (FleaseException ex) { + rq.listener.proposalFailed(rq.cellId, ex); + } + break; + } + case SET_VIEW: { + proposer.setViewId(rq.cellId, rq.viewId); + acceptor.setViewId(rq.cellId, rq.viewId); + rq.listener.proposalResult(rq.cellId, null, 0, FleaseMessage.IGNORE_MASTER_EPOCH); + break; + } + case GET_STATE: { + try { + rq.cback.localStateResult(acceptor.localState()); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + if (COLLECT_STATISTICS) { + long rqEnd = System.nanoTime(); + durRequests.get().add(Integer.valueOf((int)(rqEnd-rqStart))); + } + } + + } + if (DISABLE_RENEW_FOR_TESTING) { + Thread.sleep(0, 2); + } + + } catch (InterruptedException ex) { + if (quit) { + break; + } + } catch (Throwable ex) { + notifyCrashed(ex); + break; + } + } + + acceptor.shutdown(); + notifyStopped(); + Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this, "Flease stopped", FLEASE_VERSION); + } + + public void shutdown() { + if (COLLECT_STATISTICS) + statThr.shutdown(); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "received shutdown call..."); + quit = true; + this.interrupt(); + } + + private int checkTimers() throws Throwable { + final long now = TimeSync.getLocalSystemTime(); + + TimerEntry e = timers.peek(); + if (e == null) { + return TIMER_INTERVAL_IN_MS; + } + if (e.getScheduledTime() <= now + TIMER_INTERVAL_IN_MS) { + //execute timer + + do { + e = timers.poll(); + + long rqStart; + if (COLLECT_STATISTICS) { + rqStart = System.nanoTime(); + inTimers.incrementAndGet(); + } + if (e.getScheduledTime() < now) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "event sent after deadline: %s", e.message); + } + e.getMessage().setSendTimestamp(TimeSync.getGlobalTime()); + proposer.processMessage(e.getMessage()); + + if (COLLECT_STATISTICS) { + long rqEnd = System.nanoTime(); + durTimers.get().add(Integer.valueOf((int)(rqEnd-rqStart))); + } + + e = timers.peek(); + if (e == null) { + return TIMER_INTERVAL_IN_MS; + } + } while (e.getScheduledTime() <= now + TIMER_INTERVAL_IN_MS); + + return (int) (e.getScheduledTime() - now); + } else { + //tell how long we have to wait + return (int) (e.getScheduledTime() - now); + } + } + + private void checkLeaseTimeouts() { + final long now = TimeSync.getGlobalTime(); + final long deadline = now + TIMER_INTERVAL_IN_MS + TimeSync.getLocalRenewInterval()+config.getToNotification_ms(); + + Flease f = leaseTimeouts.peek(); + if (f == null) + return; + if (f.getLeaseTimeout_ms() <= deadline) { + //execute timer + do { + f = leaseTimeouts.poll(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"lease state change: %s timed out (old lease: %s)",f.getCellId(),f.toString()); + } + proposer.updatePrevLeaseForCell(f.getCellId(), f.EMPTY_LEASE); + leaseListener.statusChanged(f.getCellId(), Flease.EMPTY_LEASE); + //create restart event + FleaseMessage restartEvt = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART); + restartEvt.setCellId(f.getCellId()); + restartEvt.setProposalNo(proposer.getCurrentBallotNo(f.getCellId())); + createTimer(restartEvt, TimeSync.getLocalSystemTime() + config.getDMax()); + + f = leaseTimeouts.peek(); + if (f == null) { + return; + } + } while (f.getLeaseTimeout_ms() <= deadline); + } + } + + protected void createTimer(FleaseMessage msg, long timestamp) { + msg.validateMessage(); + TimerEntry e = new TimerEntry(timestamp, msg); + timers.add(e); + } + + int getInRequests() { + return this.inRequests.getAndSet(0); + } + + int getInMessages() { + return this.inMsgs.getAndSet(0); + } + + int getOutMessages() { + return this.outMsgs.getAndSet(0); + } + + int getInTimers() { + return this.inTimers.getAndSet(0); + } + + List getRequestDurations() { + return durRequests.getAndSet(new LinkedList()); + } + + List getMessageDurations() { + return durMsgs.getAndSet(new LinkedList()); + } + + List getTimersDurations() { + return durTimers.getAndSet(new LinkedList()); + } + + @Override + public void enqueueMessage(FleaseMessage message) { + messages.add(message); + } + + private final static class TimerEntry implements Comparable { + + private final long scheduledTime; + + private final FleaseMessage message; + + public TimerEntry(long scheduledTime, FleaseMessage message) { + this.scheduledTime = scheduledTime; + this.message = message; + } + + /** + * @return the scheduledTime + */ + public long getScheduledTime() { + return scheduledTime; + } + + public FleaseMessage getMessage() { + return this.message; + } + + public int compareTo(Object o) { + TimerEntry e2 = (TimerEntry) o; + return (int) (this.scheduledTime - e2.scheduledTime); + } + } + + private final static class Request { + + public boolean autoRenew; + public boolean requestME; + + public enum RequestType { + + OPEN_CELL_REQUEST, + CLOSE_CELL_REQUEST, + GET_LEASE_REQUEST, + RETURN_LEASE_REQUEST, + HANDOVER_LEASE, + GET_STATE, + SET_VIEW + + }; + public final RequestType type; + + public ASCIIString cellId; + + public ASCIIString newLeaseOwner; //< for handover only! + + public List acceptors; + + public FleaseListener listener; + + public int viewId; + + public FleaseStateCallback cback; + + public Request(RequestType type) { + this.type = type; + } + } + + private static interface FleaseStateCallback { + + public void localStateResult(Map state); + } +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/FleaseStats.java b/java/flease/src/org/xtreemfs/foundation/flease/FleaseStats.java new file mode 100644 index 0000000..13baf52 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/FleaseStats.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Collections; +import java.util.List; +import org.xtreemfs.foundation.flease.comm.tcp.TCPFleaseCommunicator; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * + * @author bjko + */ +public class FleaseStats extends Thread { + + public static final int INTERVAL_IN_MS = 1000; + + private volatile boolean quit; + + private final FleaseStage st; + + private final PrintWriter out; + + public FleaseStats(FleaseStage st, String logfile) throws IOException { + super("FStats"); + this.st = st; + this.quit = false; + try { + out = new PrintWriter(logfile); + } catch (IOException ex) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this,"cannot write to %s, due to %s",logfile,ex.toString()); + ex.printStackTrace(); + throw ex; + } + } + + public void shutdown() { + quit = true; + this.interrupt(); + } + + public void run() { + long t = 0; + Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this,"collecting statistics"); + do { + try { + try { + sleep(INTERVAL_IN_MS); + } catch (InterruptedException ex) { + Logging.logMessage(Logging.LEVEL_INFO, this,"interrupted"); + break; + } + t += INTERVAL_IN_MS; + int inRq = st.getInRequests(); + int inMsgs = st.getInMessages(); + int outMsgs = st.getOutMessages(); + int inTimers = st.getInTimers(); + + int tcpOut = TCPFleaseCommunicator.instance.getNumOut(); + int tcpIn = TCPFleaseCommunicator.instance.getNumIn(); + List durRq = st.getRequestDurations(); + List durMsgs = st.getMessageDurations(); + List durTimers = st.getTimersDurations(); + + printValues(inRq, durRq,t,"R"); + printValues(inMsgs, durMsgs,t,"M"); + printValues2(inMsgs, outMsgs,t,"m"); + printValues2(tcpIn, tcpOut,t,"x"); + printValues(inTimers, durTimers,t,"T"); + } catch (Throwable thr) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this,thr.toString()); + } + + } while (!quit); + out.close(); + Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this,"done"); + } + + void printValues(int numRq, List durations, long t, String type) { + int p95_out = getP95(durations); + + double outPerInterval = ((double)INTERVAL_IN_MS)/( ((double)p95_out) / 1e6); + double rho = ((double)numRq)/outPerInterval; + if (p95_out == 0) { + outPerInterval = 0; + rho = 0; + } + + out.format("%10d %s %10.2f %10.2f %10.2f\n", t,type,(double)numRq,outPerInterval,rho); + } + + void printValues2(int numRq, int numOut, long t, String type) { + + double rho = ((double)numRq)/((double)numOut); + if (numOut == 0) { + rho = 0; + } + + out.format("%10d %s %10.2f %10.2f %10.2f\n", t,type,(double)numRq,(double)numOut,rho); + } + + int getP95(List items) { + + if (items.size() == 0) + return 0; + if (items.size() == 1) + return items.get(0); + + Collections.sort(items); + + int rank = ((int)Math.round(0.95*items.size()))-1; + return items.get(rank); + + } +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/FleaseStatusListener.java b/java/flease/src/org/xtreemfs/foundation/flease/FleaseStatusListener.java new file mode 100644 index 0000000..c1bce28 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/FleaseStatusListener.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease; + +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.proposer.FleaseException; + +/** + * + * @author bjko + */ +public interface FleaseStatusListener { + + public void statusChanged(ASCIIString cellId, Flease lease); + + public void leaseFailed(ASCIIString cellId, FleaseException error); + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/FleaseViewChangeListenerInterface.java b/java/flease/src/org/xtreemfs/foundation/flease/FleaseViewChangeListenerInterface.java new file mode 100644 index 0000000..88580ce --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/FleaseViewChangeListenerInterface.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease; + +import org.xtreemfs.foundation.buffer.ASCIIString; + + +/** + * The view change listener is called whenever flease + * (proposor or acceptor) see a new viewId > current viewId + * @author bjko + */ +public interface FleaseViewChangeListenerInterface { + + public void viewIdChangeEvent(ASCIIString cellId, int viewId); + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/MasterEpochHandlerInterface.java b/java/flease/src/org/xtreemfs/foundation/flease/MasterEpochHandlerInterface.java new file mode 100644 index 0000000..b135684 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/MasterEpochHandlerInterface.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease; + +import org.xtreemfs.foundation.flease.comm.FleaseMessage; + +/** + * + * @author bjko + */ +public interface MasterEpochHandlerInterface { + + public void sendMasterEpoch(FleaseMessage response, Continuation callback); + + public void storeMasterEpoch(FleaseMessage request, Continuation callback); + + public static interface Continuation { + void processingFinished(); + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/SimpleMasterEpochHandler.java b/java/flease/src/org/xtreemfs/foundation/flease/SimpleMasterEpochHandler.java new file mode 100644 index 0000000..920bb74 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/SimpleMasterEpochHandler.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease; + +import java.io.File; +import java.io.RandomAccessFile; +import java.nio.channels.FileChannel; +import java.util.concurrent.LinkedBlockingQueue; +import org.xtreemfs.foundation.LRUCache; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.logging.Logging; + +/** + * + * @author bjko + */ +public class SimpleMasterEpochHandler extends LifeCycleThread implements MasterEpochHandlerInterface { + public static final int MAX_EPOCH_CACHE_SIZE = 10000; + + + private final LinkedBlockingQueue requests; + + private final LRUCache epochs; + + private final String directory; + + public SimpleMasterEpochHandler(String directory) { + super("SimpleMEHandler"); + requests = new LinkedBlockingQueue(); + epochs = new LRUCache(MAX_EPOCH_CACHE_SIZE); + this.directory = directory; + } + + @Override + public void run() { + try { + notifyStarted(); + do { + Request rq = requests.take(); + + switch (rq.type) { + case SEND: { + try { + Long epoch = epochs.get(rq.message.getCellId()); + if (epoch == null) { + + File f = new File(getFileName(rq.message.getCellId())); + if (f.exists()) { + RandomAccessFile raf = new RandomAccessFile(f, "r"); + epoch = raf.readLong(); + raf.close(); + } else { + epoch = 0l; + } + epochs.put(rq.message.getCellId(),epoch); + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.all, this, "sent %d", epoch); + } + rq.message.setMasterEpochNumber(epoch); + } catch (Exception ex) { + rq.message.setMasterEpochNumber(-1); + } finally { + try { + rq.callback.processingFinished(); + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + break; + } + case STORE: { + try { + File f = new File(getFileName(rq.message.getCellId())); + RandomAccessFile raf = new RandomAccessFile(f, "rw"); + raf.writeLong(rq.message.getMasterEpochNumber()); + raf.getFD().sync(); + raf.close(); + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.all, this, "stored %d", + rq.message.getMasterEpochNumber()); + epochs.put(rq.message.getCellId(),rq.message.getMasterEpochNumber()); + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + try { + rq.callback.processingFinished(); + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + break; + } + } + + } while (!interrupted()); + } catch (InterruptedException ex) { + } catch (Throwable ex) { + notifyCrashed(ex); + } + notifyStopped(); + } + + private String getFileName(ASCIIString cellId) { + return directory + cellId.toString() + ".me"; + } + + @Override + public void shutdown() { + this.interrupt(); + } + + @Override + public void sendMasterEpoch(FleaseMessage response, Continuation callback) { + Request rq = new Request(); + rq.callback = callback; + rq.message = response; + rq.type = Request.RequestType.SEND; + requests.add(rq); + } + + @Override + public void storeMasterEpoch(FleaseMessage request, Continuation callback) { + Request rq = new Request(); + rq.callback = callback; + rq.message = request; + rq.type = Request.RequestType.STORE; + requests.add(rq); + } + + private final static class Request { + FleaseMessage message; + Continuation callback; + String fileName; + enum RequestType { + SEND, STORE; + }; + RequestType type; + } + + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/UDPFleaseCommunicator.java b/java/flease/src/org/xtreemfs/foundation/flease/UDPFleaseCommunicator.java new file mode 100644 index 0000000..15ae341 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/UDPFleaseCommunicator.java @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.channels.ClosedByInterruptException; +import java.nio.channels.DatagramChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicBoolean; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * + * @author bjko + */ +public class UDPFleaseCommunicator extends LifeCycleThread implements FleaseMessageSenderInterface { + + private final FleaseStage stage; + + private final int port; + + private DatagramChannel channel; + + private Selector selector; + + private volatile boolean quit; + + private final AtomicBoolean sendMode; + + private final LinkedBlockingQueue q; + + private static final int MAX_UDP_SIZE = 16*1024; + + private long numTx,numRx; + + public UDPFleaseCommunicator(FleaseConfig config, String lockfileDir, + boolean ignoreLockForTesting, + final FleaseViewChangeListenerInterface viewListener) throws Exception { + super("FlUDPCom"); + stage = new FleaseStage(config, lockfileDir, this, ignoreLockForTesting, viewListener, null, null); + port = config.getEndpoint().getPort(); + q = new LinkedBlockingQueue(); + sendMode = new AtomicBoolean(false); + numTx = 0; + numRx = 0; + } + + public FleaseStage getStage() { + return stage; + } + + + public void sendMessage(FleaseMessage message, InetSocketAddress recipient) { + FleaseMessage m = message.clone(); + m.setSender(recipient); + send(m); + } + + /** + * sends a UDPRequest. + * + * @attention Overwrites the first byte of rq.data with the message type. + */ + public void send(FleaseMessage rq) { + q.add(rq); + + if (q.size() == 1) { + //System.out.println("wakeup!"); + selector.wakeup(); + } + } + + public void shutdown() { + quit = true; + interrupt(); + } + + @Override + public void run() { + + long numRxCycles = 0; + long durAllRx = 0; + long maxPkgCycle = 0; + long avgPkgCycle = 0; + + try { + + + selector = Selector.open(); + + channel = DatagramChannel.open(); + channel.socket().bind(new InetSocketAddress(port)); + channel.socket().setReceiveBufferSize(1024*1024*1024); + channel.socket().setSendBufferSize(1024*1024*1024); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,"sendbuffer size: "+channel.socket().getSendBufferSize()); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this,"recv size: "+channel.socket().getReceiveBufferSize()); + channel.configureBlocking(false); + channel.register(selector, SelectionKey.OP_READ); + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, "UDP socket on port %d ready", + port); + + stage.start(); + stage.waitForStartup(); + + + notifyStarted(); + + + + + boolean isRdOnly = true; + + List sendList = new ArrayList(5000); + ReusableBuffer data = BufferPool.allocate(MAX_UDP_SIZE); + + while (!quit) { + + if (q.size() == 0) { + if (!isRdOnly) { + channel.keyFor(selector).interestOps(SelectionKey.OP_READ); + //System.out.println("read only"); + isRdOnly = true; + } + } else { + if (isRdOnly) { + channel.keyFor(selector).interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE); + //System.out.println("read write"); + isRdOnly = false; + } + } + + int numKeys = selector.select(); + + if (q.size() == 0) { + if (!isRdOnly) { + channel.keyFor(selector).interestOps(SelectionKey.OP_READ); + //System.out.println("read only"); + isRdOnly = true; + } + } else { + if (isRdOnly) { + channel.keyFor(selector).interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE); + //System.out.println("read write"); + isRdOnly = false; + } + } + + if (numKeys == 0) + continue; + + if (q.size() > 10000) { + System.out.println("QS!!!!! " + q.size()); + System.out.println("is readOnly: " + isRdOnly); + } + + // fetch events + Set keys = selector.selectedKeys(); + Iterator iter = keys.iterator(); + + // process all events + while (iter.hasNext()) { + + SelectionKey key = iter.next(); + + // remove key from the list + iter.remove(); + + if (key.isWritable()) { + q.drainTo(sendList,50); + //System.out.println("sent: "+queue.size()); + while (!sendList.isEmpty()) { + FleaseMessage r = sendList.remove(sendList.size()-1); + if (r == null) + break; + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "sent packet to %s", r.getSender().toString()); + data.clear(); + r.serialize(data); + data.flip(); + int sent = channel.send(data.getBuffer(), r.getSender()); + if (sent == 0) { + System.out.println("cannot send anymore!"); + q.addAll(sendList); + sendList.clear(); + break; + } + numTx++; + } + } + if (key.isReadable()) { + InetSocketAddress sender = null; + + int numRxInCycle = 0; + do { + data.clear(); + sender = (InetSocketAddress) channel.receive(data.getBuffer()); + if (sender == null) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "read key for empty read"); + break; + } else { + numRxInCycle++; + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "read data from %s", sender.toString()); + + try { + //unpack flease message + data.flip(); + FleaseMessage m = new FleaseMessage(data); + m.setSender(sender); + numRx++; + stage.receiveMessage(m); + } catch (Throwable ex) { + ex.printStackTrace(); + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "received invalid UPD message: "+ex); + } + } + } while (sender != null); + numRxCycles++; + avgPkgCycle += numRxInCycle; + if (numRxInCycle > maxPkgCycle) + maxPkgCycle = numRxInCycle; + } + } + + } + + stage.shutdown(); + + selector.close(); + channel.close(); + + } catch (ClosedByInterruptException ex) { + // ignore + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } catch (Throwable th) { + notifyCrashed(th); + return; + } + + + Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this,"num packets tranferred: %d tx %d rx",numTx,numRx); + Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this,"numRxCycles %d, maxPkgPerCycle %d, avg/Cycle %d",numRxCycles,maxPkgCycle,avgPkgCycle/numRxCycles); + + notifyStopped(); + } +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptor.java b/java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptor.java new file mode 100644 index 0000000..3bd152e --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptor.java @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.acceptor; + +import java.io.File; +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.FleaseConfig; +import org.xtreemfs.foundation.flease.FleaseViewChangeListenerInterface; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.flease.comm.ProposalNumber; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * Acceptor for MultiPaXos Lease negotiation (MPXLN). + * This version has no persistent state. + * + * @author bjko + */ +public class FleaseAcceptor { + + /** + * Instances of the Multipaxos + */ + public final Map cells; + + /** + * filename to use for storing state permanantly + */ + public static final String LOCKFILE_NAME = "flease_lock."; + + /** + * lockfile full path + */ + private final String lockfile; + + private final long waitUntilTimestamp_ms; + + /** + * set to true to quit + */ + public boolean quit; + + private final FleaseConfig config; + + private FleaseViewChangeListenerInterface viewListener; + + private final LearnEventListener evtListener; + + + + /** + * Creates a new instance of PxAcceptor + * + * @param port + * port to listen on + * @param debug + */ + public FleaseAcceptor(LearnEventListener evtListener, FleaseConfig localConfig, String lockfileDir, boolean ignoreLockFileForTesting) + throws IOException { + this.config = localConfig; + + cells = new HashMap(); + + quit = false; + + lockfile = lockfileDir+"/"+LOCKFILE_NAME+config.getIdentity().hashCode(); + + this.evtListener = evtListener; + + File lock = new File(lockfile); + if (lock.exists() && !ignoreLockFileForTesting) { + /*waitUntilTimestamp_ms = TimeSync.getLocalSystemTime()+TimeSync.getLocalRenewInterval()+ + config.getRestartWait();*/ + waitUntilTimestamp_ms = System.currentTimeMillis() + config.getRestartWait(); + Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this,"restarted after crash (lock file %s exists). acceptor will ignore all messages for %d ms (recovery period until %s)", + lockfile,config.getRestartWait(),(new Date(waitUntilTimestamp_ms)).toString()); + + } else { + waitUntilTimestamp_ms = 0; + if (ignoreLockFileForTesting) + lock.delete(); + if (!lock.createNewFile()) + throw new IOException("Lock file exists!"); + } + + } + + public void setViewChangeListener(FleaseViewChangeListenerInterface listener) { + viewListener = listener; + } + + public void setViewId(ASCIIString cellId, int viewId) { + FleaseAcceptorCell cell = getCell(cellId); + + // Set the viewId or invalidate the cell if the VIEW_ID_INVALIDATED is passed. + if (viewId == FleaseMessage.VIEW_ID_INVALIDATED) { + cell.invalidateView(); + } else { + cell.setViewId(viewId); + } + } + + private FleaseAcceptorCell getCell(FleaseMessage msg) { + assert (msg != null); + return getCell(msg.getCellId()); + } + + private FleaseAcceptorCell getCell(ASCIIString cellId) { + FleaseAcceptorCell cc = cells.get(cellId); + if (cc == null) { + cc = new FleaseAcceptorCell(); + cells.put(cellId,cc); + } else { + if ((cc.lastAccess+config.getCellTimeout()) < System.currentTimeMillis()) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A GCed cell "+cellId); + // Cell is outdated and GCed. + + // Create a new cell and transfer the previous view. + FleaseAcceptorCell tmp = new FleaseAcceptorCell(); + tmp.setViewId(cc.getViewId()); + if (cc.isViewInvalidated()) { + tmp.invalidateView(); + } + + cells.put(cellId, tmp); + cc = tmp; + } + } + /*if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG,this,"using cell "+cellId);*/ + cc.touch(); + return cc; + } + + /** + * Handles paxos prepare messages + * + * @param msg + * the incomming message + * @return a response message + */ + public FleaseMessage handlePREPARE(FleaseMessage msg) { + + final FleaseAcceptorCell cc = getCell(msg); + cc.touch(); + + if ((cc.getPrepared() != null) && (cc.getPrepared().after(msg))) { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + final String preped = (cc.getPrepared() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getPrepared().getProposalNo().toString(); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A prepare NACK p:"+preped+" is after "+msg.getProposalNo()+""); + } + FleaseMessage reject = new FleaseMessage( + FleaseMessage.MsgType.MSG_PREPARE_NACK,msg); + reject.setPrevProposalNo(cc.getPrepared().getProposalNo()); + reject.setLeaseHolder(null); + reject.setLeaseTimeout(0); + reject.setSendTimestamp(TimeSync.getGlobalTime()); + return reject; + } else { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + final String preped = (cc.getPrepared() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getPrepared().getProposalNo().toString(); + final String acced = (cc.getAccepted() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getAccepted().getProposalNo()+"="+cc.getAccepted().getLeaseHolder()+"/"+cc.getAccepted().getLeaseTimeout(); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A prepare ACK p:"+preped+" -> "+msg.getProposalNo()+" a:"+acced); + } + // lastPrepared = msg; + cc.setPrepared(msg); + // FIXME:Persistently write to disk + FleaseMessage response = new FleaseMessage( + FleaseMessage.MsgType.MSG_PREPARE_ACK,msg); + + if (cc.getAccepted() != null) { + + response.setPrevProposalNo(cc.getAccepted().getProposalNo()); + response.setLeaseHolder(cc.getAccepted().getLeaseHolder()); + assert(response.getLeaseHolder() != null); + response.setLeaseTimeout(cc.getAccepted() + .getLeaseTimeout()); + } + response.setSendTimestamp(TimeSync.getGlobalTime()); + return response; + + + } + } + + /** + * Handles paxos accept (vote) messages. + * + * @param msg + * incomming message + * @return a response message or null + */ + public FleaseMessage handleACCEPT(FleaseMessage msg) { + + final FleaseAcceptorCell cc = getCell(msg); + + cc.touch(); + if ((cc.getPrepared() != null) && (cc.getPrepared().after(msg))) { + // reject the request + if (Logging.isDebug() && config.isDebugPrintMessages()) { + final String preped = (cc.getPrepared() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getPrepared().getProposalNo().toString(); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A accept NACK p:"+preped+" is after "+msg.getProposalNo()+""); + } + FleaseMessage tmp = new FleaseMessage( + FleaseMessage.MsgType.MSG_ACCEPT_NACK,msg); + tmp.setSendTimestamp(TimeSync.getGlobalTime()); + tmp.setLeaseHolder(null); + tmp.setLeaseTimeout(0); + tmp.setPrevProposalNo(cc.getPrepared().getProposalNo()); + return tmp; + } else { + // okay accept it + if (Logging.isDebug() && config.isDebugPrintMessages()) { + final String preped = (cc.getPrepared() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getPrepared().getProposalNo().toString(); + final String acced = (cc.getAccepted() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getAccepted().getProposalNo()+"="+cc.getAccepted().getLeaseHolder()+"/"+cc.getAccepted().getLeaseTimeout(); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A accept ACK p:"+preped+" a: "+acced+" -> "+msg.getProposalNo()+"="+msg.getLeaseHolder()+"/"+msg.getLeaseTimeout()); + } + assert(msg.getLeaseHolder() != null); + cc.setAccepted(msg); + cc.setPrepared(msg); + + + FleaseMessage tmp = new FleaseMessage( + FleaseMessage.MsgType.MSG_ACCEPT_ACK,msg); + tmp.setSendTimestamp(TimeSync.getGlobalTime()); + return tmp; + + } + } + + /** + * Handles paxos learn messages. Removes oudated instances and updates + * maxLearnedInstId accordingly + * + * @param msg + * incomming message + */ + public void handleLEARN(FleaseMessage msg) { + final FleaseAcceptorCell cc = getCell(msg); + + cc.touch(); + if ((cc.getPrepared() != null) && (cc.getPrepared().after(msg)) + || (cc.getAccepted() != null) && (cc.getAccepted().after(msg))) { + if (Logging.isDebug() && config.isDebugPrintMessages()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A ignore outdated LEARN message "+msg.getProposalNo()); + } else { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + final String preped = (cc.getPrepared() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getPrepared().getProposalNo().toString(); + final String acced = (cc.getAccepted() == null) ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString() : cc.getAccepted().getProposalNo()+"="+cc.getAccepted().getLeaseHolder()+"/"+cc.getAccepted().getLeaseTimeout(); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication,this,"A learn p:"+preped+" a: "+acced+" -> "+msg.getProposalNo()+"="+msg.getLeaseHolder()+"/"+msg.getLeaseTimeout()); + } + + cc.setAccepted(msg); + cc.setPrepared(msg); + cc.setLatestLearn(msg); + evtListener.learnedEvent(msg.getCellId(), msg.getLeaseHolder(), msg.getLeaseTimeout(), msg.getMasterEpochNumber()); + } + + } + + /** + * Handles requests for lease information. Returns current lease + * holder+timeout or the current instance id. + * + * @param msg + * incomming message + * @return a response message + */ + public FleaseMessage getLocalLeaseInformation(ASCIIString cellId) { + FleaseAcceptorCell cc = getCell(cellId); + return cc.getLatestLearn(); + } + + public Map localState() { + Map state = new HashMap(); + + for (ASCIIString cellId : cells.keySet()) { + FleaseAcceptorCell cell = cells.get(cellId); + FleaseMessage lrn = null; + if (cell.isLearned()) + lrn = cell.getAccepted(); + state.put(cellId, lrn); + } + + return state; + } + + + /** + * main loop + */ + public FleaseMessage processMessage(FleaseMessage msg) { + + assert(!quit); + + /*if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG,this,"received %s",msg.toString());*/ + + final long now = TimeSync.getLocalSystemTime(); + if (msg.getSendTimestamp()+config.getMessageTimeout() < TimeSync.getGlobalTime()) { + //old message, ignore + if (Logging.isDebug() && config.isDebugPrintMessages()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"A outdated message discarded: %s",msg.toString()); + return null; + } + if (this.waitUntilTimestamp_ms >= now) { + if (Logging.isDebug() && config.isDebugPrintMessages()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"A message discarded, acceptor is still in recovery period"); + return null; + } + + + + assert(msg.getCellId() != null); + final FleaseAcceptorCell cc = getCell(msg.getCellId()); + + if (cc.getViewId() < msg.getViewId()) { + // If the local view is lower than the delivered one, the view listener has to be informed to update + // the local view. But the request can still be answered. + viewListener.viewIdChangeEvent(msg.getCellId(), msg.getViewId()); + + } else if (cc.getViewId() > msg.getViewId() || (cc.getViewId() == msg.getViewId() && cc.isViewInvalidated())) { + // If the request is from an older view, or the a view that has been invalidated on this + // AcceptorCell, the request has to be aborted. + FleaseMessage response = new FleaseMessage(FleaseMessage.MsgType.MSG_WRONG_VIEW, msg); + response.setViewId(cc.getViewId()); + return response; + } + + FleaseMessage response = null; + if (msg.getMsgType() == FleaseMessage.MsgType.MSG_PREPARE) + response = handlePREPARE(msg); + else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_ACCEPT) + response = handleACCEPT(msg); + else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_LEARN) + handleLEARN(msg); + /*else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_GET_LEASE) + response = handleGETLEASE(msg); + else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_RENEW_LEASE) + response = handleRENEWINSTANCE(msg);*/ + else + Logging.logMessage(Logging.LEVEL_ERROR, Category.replication,this,"A invalid message type received: %s",msg.toString()); + + /*if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG,this,"response %s",(response != null) ? response.toString() : "");*/ + + return response; + } + + /*private void notifyLeaseListener(FleaseAcceptorCell cell, ASCIIString leaseHolder, long leaseTimeout) { + if (leaseListener != null) { + final ASCIIString prevLeaseHolder = cell.getPrevLeaseHolder(); + if ( ( (((prevLeaseHolder == null) || (leaseHolder == null)) && (prevLeaseHolder != leaseHolder)) || + (!prevLeaseHolder.equals(leaseHolder)) ) || (leaseTimeout != cell.getPrevLeaseTimeout())) { + leaseListener.statusChanged(cell.getCellId(), leaseHolder,leaseTimeout); + cell.setPrevLeaseHolder(leaseHolder); + cell.setPrevLeaseTimeout(leaseTimeout); + } + } + }*/ + + /** + * string representation + * + * @return a string + */ + public String toString() { + return "Acceptor @ " + config.getIdentity(); + } + + // only for testing! + /*public String getLocalLeaseInfo(String cellId) { + + synchronized (cells) { + FleaseAcceptorCell cc = getCell(cellId); + FleaseInstance currentL = cc.getInstances().get(cc.getMaxLearnedInstanceId()); + if (currentL != null) { + // there is an instance + if (currentL.getAccepted().getLeaseTimeout() > (System + .currentTimeMillis() / 1000) + - config.getDMax()) { + return currentL.getAccepted().getLeaseHolder(); + } else { + return null; + } + } + return null; + } + + }*/ + + public void shutdown() { + this.quit = true; + File f = new File(lockfile); + f.delete(); + } + + + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptorCell.java b/java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptorCell.java new file mode 100644 index 0000000..e766a99 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptorCell.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.acceptor; + +import java.io.Serializable; +import java.util.concurrent.atomic.AtomicReference; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; + +/** + * A coordination cell is used to separate concurrent lease nogitiations + * for individual objects (e.g. volumes on the MRC). + * @author bjko + */ +public class FleaseAcceptorCell implements Serializable { + + FleaseMessage prepared; + + FleaseMessage accepted; + + AtomicReference latestLearn; + + + /** timestamp for last access **/ + public long lastAccess; + + private int viewId; + + private boolean viewInvalidated = false; + + /** + * Creates a new instance of CoordinationCell + */ + public FleaseAcceptorCell() { + prepared = null; + accepted = null; + lastAccess = TimeSync.getLocalSystemTime(); + latestLearn = new AtomicReference(); + } + + public FleaseMessage getLatestLearn() { + return latestLearn.get(); + } + + public void setLatestLearn(FleaseMessage msg) { + assert(msg.getMsgType() == FleaseMessage.MsgType.MSG_LEARN); + latestLearn.set(msg); + } + + /** + * Getter for property lastPrep. + * @return Value of property lastPrep. + */ + public FleaseMessage getPrepared() { + return this.prepared; + } + + /** + * Setter for property lastPrep. + * @param lastPrep New value of property lastPrep. + */ + public void setPrepared(FleaseMessage prepared) { + this.prepared = prepared; + } + + /** + * Getter for property accepted. + * @return Value of property accepted. + */ + public FleaseMessage getAccepted() { + return this.accepted; + } + + /** + * Setter for property accepted. + * @param accepted New value of property accepted. + */ + public void setAccepted(FleaseMessage accepted) { + assert(accepted.getLeaseHolder() != null); + assert(accepted.getLeaseTimeout() > 0); + this.accepted = accepted; + } + + public boolean isLearned() { + return latestLearn.get() != null; + } + + public void touch() { + this.lastAccess = System.currentTimeMillis(); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + + sb.append("\t"); + sb.append("prep "); + sb.append(getPrepared()); + sb.append("\n"); + sb.append("\t"); + sb.append("accept "); + sb.append(getAccepted()); + sb.append("\n"); + sb.append("\t"); + sb.append("isLrnd "); + sb.append(isLearned()); + sb.append("\n"); + + return sb.toString(); + } + + /** + * @return The most recently set viewId. + */ + public int getViewId() { + return viewId; + } + + /** + * Set the acceptors viewId and clears the viewInvalidated flag. + * + * @param viewId + * The viewId to set. + */ + public void setViewId(int viewId) { + this.viewId = viewId; + this.viewInvalidated = false; + } + + /** + * @return true if this view is invalidated. + */ + public boolean isViewInvalidated() { + return viewInvalidated; + } + + /** + * Invalidate the current view. + */ + public void invalidateView() { + viewInvalidated = true; + } +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseInstance.java b/java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseInstance.java new file mode 100644 index 0000000..487dbac --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/acceptor/FleaseInstance.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.acceptor; + +import java.io.Serializable; + +import org.xtreemfs.foundation.flease.comm.FleaseMessage; + +/** + * + * @author bjko + */ +public class FleaseInstance implements Serializable { + + /** Creates a new instance of PxInstance */ + public FleaseInstance() { + learned = false; + timeout = 0; + prepared = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE); + accepted = null; + + } + + /** + * Holds value of property learned. + */ + private boolean learned; + + /** + * Getter for property learned. + * @return Value of property learned. + */ + public boolean isLearned() { + return this.learned; + } + + /** + * Setter for property learned. + * @param learned New value of property learned. + */ + public void setLearned(boolean learned) { + this.learned = learned; + } + + /** + * Holds value of property timeout. + */ + private long timeout; + + /** + * Getter for property timeout. + * @return Value of property timeout. + */ + public long getTimeout() { + return this.timeout; + } + + /** + * Setter for property timeout. + * @param timeout New value of property timeout. + */ + public void setTimeout(long timeout) { + this.timeout = timeout; + } + + /** + * Holds value of property prepared. + */ + private FleaseMessage prepared; + + /** + * Getter for property lastPrep. + * @return Value of property lastPrep. + */ + public FleaseMessage getPrepared() { + return this.prepared; + } + + /** + * Setter for property lastPrep. + * @param lastPrep New value of property lastPrep. + */ + public void setPrepared(FleaseMessage prepared) { + this.prepared = prepared; + } + + /** + * Holds value of property accepted. + */ + private FleaseMessage accepted; + + /** + * Getter for property accepted. + * @return Value of property accepted. + */ + public FleaseMessage getAccepted() { + return this.accepted; + } + + /** + * Setter for property accepted. + * @param accepted New value of property accepted. + */ + public void setAccepted(FleaseMessage accepted) { + assert(accepted.getLeaseHolder() != null); + assert(accepted.getLeaseTimeout() > 0); + this.accepted = accepted; + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/acceptor/LearnEventListener.java b/java/flease/src/org/xtreemfs/foundation/flease/acceptor/LearnEventListener.java new file mode 100644 index 0000000..4f2fdf0 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/acceptor/LearnEventListener.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.acceptor; + +import org.xtreemfs.foundation.buffer.ASCIIString; + + +/** + * + * @author bjko + */ +public interface LearnEventListener { + + public void learnedEvent(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long masterEpochNumber); + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/comm/FleaseCommunicationInterface.java b/java/flease/src/org/xtreemfs/foundation/flease/comm/FleaseCommunicationInterface.java new file mode 100644 index 0000000..79662ea --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/comm/FleaseCommunicationInterface.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.comm; + +import java.io.IOException; +import java.net.InetSocketAddress; + +/** + * + * @author bjko + */ +public interface FleaseCommunicationInterface { + + public void sendMessage(FleaseMessage msg, InetSocketAddress receiver) throws IOException; + + public void requestTimer(FleaseMessage msg, long timestamp); + + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/comm/FleaseMessage.java b/java/flease/src/org/xtreemfs/foundation/flease/comm/FleaseMessage.java new file mode 100644 index 0000000..8292fe2 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/comm/FleaseMessage.java @@ -0,0 +1,460 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.comm; + +import java.io.Serializable; +import java.net.InetSocketAddress; +import java.util.Date; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.flease.FleaseConfig; + +/** + * A message for multipaxos lease negotiation. + * @author bjko + */ +public class FleaseMessage implements Serializable, Cloneable { + + /** + * Message types + */ + public static enum MsgType { + /** + * paxos prepare message + */ + MSG_PREPARE, + /** + * acknowledgment for prepare + */ + MSG_PREPARE_ACK, + /** + * reject of prepare + */ + MSG_PREPARE_NACK, + /** + * paxos vote message + */ + MSG_ACCEPT, + /** + * acceptance of vote (voted) + */ + MSG_ACCEPT_ACK, + /** + * reject of vote message + */ + MSG_ACCEPT_NACK, + /** + * paxos learn message + */ + MSG_LEARN, + /** + * for future use (volontary lease return by master, revocation) + */ + MSG_LEASE_RETURN, + + /** + * internal timeout event during prepare (timer) + */ + EVENT_TIMEOUT_PREPARE, + + /** + * internal timeout event during prepare (timer) + */ + EVENT_TIMEOUT_ACCEPT, + + /** + * internal restart event (timer) + */ + EVENT_RESTART, + + /** + * event to renew the lease + */ + EVENT_RENEW, + + /** + * message (response) indicating that the viewId has changed + */ + MSG_WRONG_VIEW + + }; + + private static final long serialVersionUID = 3187504351237849866L; + + public static final int VIEW_ID_INVALIDATED = -1; + + public static final long IGNORE_MASTER_EPOCH = -1; + + public static final long REQUEST_MASTER_EPOCH = 0; + + /** + * message type + * @see MsgType + */ + private final MsgType msgType; + + /** + * cellId this message belongs to + */ + private ASCIIString cellId; + + /** + * proposal number for this message + */ + private ProposalNumber proposalNo; + + + /** + * timestamp when the message was sent to discard messages arriving after + * timeout+dmax. + */ + private long sendTimestamp; + + /** + * the socket address of the current lease holder + * part of the proposal value + * @attention necessary for correct operation of leases negotiation + */ + private ASCIIString leaseHolder; + + /** + * (absolute) timestamp of lease timeout in ms since epoch + * part of the proposal value + * @attention necessary for correct operation of leases negotiation + */ + private long leaseTimeout; + + private ProposalNumber prevProposalNo; + + + private InetSocketAddress address; + + private int viewId; + + private long masterEpochNumber; + + + /** + * Creates a new instance of PxMessage + * @param msgType message type + */ + public FleaseMessage(MsgType msgType) { + this.msgType = msgType; + this.proposalNo = ProposalNumber.EMPTY_PROPOSAL_NUMBER; + this.prevProposalNo = ProposalNumber.EMPTY_PROPOSAL_NUMBER; + this.masterEpochNumber = IGNORE_MASTER_EPOCH; + } + + /** + * Creates a new instance of PxMessage + * @param msgType message type + * @param template a message to take instanceId and cellId from + */ + public FleaseMessage(MsgType msgType, FleaseMessage template) { + this.msgType = msgType; + this.proposalNo = template.proposalNo; + this.cellId = template.cellId; + this.leaseHolder = template.leaseHolder; + this.leaseTimeout = template.leaseTimeout; + this.prevProposalNo = template.prevProposalNo; + this.viewId = template.viewId; + this.masterEpochNumber = template.masterEpochNumber; + } + + public FleaseMessage(FleaseMessage other) { + this.msgType = other.msgType; + this.address = other.address; + this.proposalNo = other.proposalNo; + this.cellId = other.cellId; + this.leaseHolder = other.leaseHolder; + this.leaseTimeout = other.leaseTimeout; + this.sendTimestamp = other.sendTimestamp; + this.prevProposalNo = other.prevProposalNo; + this.viewId = other.viewId; + this.masterEpochNumber = other.masterEpochNumber; + } + + public void validateMessage() { + assert(msgType != null); + assert(proposalNo != null); + assert(cellId != null); + } + + /** + * @return the prevAcceptedBallotNo + */ + public ProposalNumber getPrevProposalNo() { + return prevProposalNo; + } + + /** + * @param prevAcceptedBallotNo the prevAcceptedBallotNo to set + */ + public void setPrevProposalNo(ProposalNumber prevAcceptedBallotNo) { + this.prevProposalNo = prevAcceptedBallotNo; + } + + /** + * @return the viewId + */ + public int getViewId() { + return viewId; + } + + /** + * @param viewId the viewId to set + */ + public void setViewId(int viewId) { + this.viewId = viewId; + } + + /** + * @return the masterEpochNumber + */ + public long getMasterEpochNumber() { + return masterEpochNumber; + } + + /** + * @param masterEpochNumber the masterEpochNumber to set + */ + public void setMasterEpochNumber(long masterEpochNumber) { + this.masterEpochNumber = masterEpochNumber; + } + + + + /** + * Getter for property proposalNo. + * @return Value of property proposalNo. + */ + public ProposalNumber getProposalNo() { + return this.proposalNo; + } + + /** + * Setter for property proposalNo. + * @param proposalNo New value of property proposalNo. + */ + public void setProposalNo(ProposalNumber proposalNo) { + this.proposalNo = proposalNo; + } + + /** + * Getter for property msgType. + * @return Value of property msgType. + */ + public MsgType getMsgType() { + return this.msgType; + } + + /** + * Setter for property msgType. + * @param msgType New value of property msgType. + */ + /*public void setMsgType(MsgType msgType) { + this.msgType = msgType; + }*/ + + /** + * Getter for property leaseHolder. + * @return Value of property leaseHolder. + */ + public ASCIIString getLeaseHolder() { + return this.leaseHolder; + } + + /** + * Setter for property leaseHolder. + * @param leaseHolder New value of property leaseHolder. + */ + public void setLeaseHolder(ASCIIString leaseHolder) { + this.leaseHolder = leaseHolder; + } + + /** + * Getter for property leaseTimeout. + * @return Value of property leaseTimeout. + */ + public long getLeaseTimeout() { + return this.leaseTimeout; + } + + /** + * Setter for property leaseTimeout. + * @param leaseTimeout New value of property leaseTimeout. + */ + public void setLeaseTimeout(long leaseTimeout) { + this.leaseTimeout = leaseTimeout; + } + + /** + * Getter for property cellId. + * @return Value of property cellId. + */ + public ASCIIString getCellId() { + return this.cellId; + } + + /** + * Setter for property cellId. + * @param cellId New value of property cellId. + */ + public void setCellId(ASCIIString cellId) { + this.cellId = cellId; + } + + /** + * @return the sendTimestamp + */ + public long getSendTimestamp() { + return sendTimestamp; + } + + /** + * @param sendTimestamp the sendTimestamp to set + */ + public void setSendTimestamp(long sendTimestamp) { + this.sendTimestamp = sendTimestamp; + } + + /** + * @return the sender + */ + public InetSocketAddress getSender() { + return address; + } + + /** + * @param sender the sender to set + */ + public void setSender(InetSocketAddress sender) { + this.address = sender; + } + + /** + * checks if this message is before other + * @param other another message + * @return true if this message is before other + */ + public boolean before(FleaseMessage other) { + return proposalNo.before(other.proposalNo); + } + + /** + * checks if this message is after other + * @param other another message + * @return true if this message is after (i.e. >) other + */ + public boolean after(FleaseMessage other) { + return proposalNo.after(other.proposalNo); + } + + /** + * checks if both messages have the same message id. + * @param other another message + * @return true if both messages have the same message id + */ + public boolean sameMsgId(FleaseMessage other) { + return proposalNo.sameNumber(other.proposalNo); + } + + /** + * toString + * @return a string representation of the message + */ + @Override + public String toString() { + assert(this.msgType != null); + return String.format("FleaseMessage ( type=%s cell=%s v=%d b=%s lease=%s/%d(%s) prevb=%s ts=%d(%s) addr=%s mepoch=%d)", + this.msgType.toString(),this.cellId,this.viewId,this.proposalNo,this.leaseHolder, + this.leaseTimeout,new Date(this.leaseTimeout),this.prevProposalNo,this.sendTimestamp,new Date(this.sendTimestamp), + (address != null) ? address.toString() : "n/a", this.masterEpochNumber); + } + + public boolean isInternalEvent() { + return msgType == MsgType.EVENT_RESTART || + msgType == MsgType.EVENT_TIMEOUT_ACCEPT || + msgType == MsgType.EVENT_TIMEOUT_PREPARE; + } + + public boolean isAcceptorMessage() { + return msgType == MsgType.MSG_ACCEPT || + msgType == MsgType.MSG_LEARN || + msgType == MsgType.MSG_PREPARE || + msgType == MsgType.MSG_LEASE_RETURN; + } + + public boolean isProposerMessage() { + return msgType == MsgType.MSG_ACCEPT_ACK || + msgType == MsgType.MSG_ACCEPT_NACK || + msgType == MsgType.MSG_PREPARE_ACK || + msgType == MsgType.MSG_PREPARE_NACK; + } + + public int getSize() { + return 1+cellId.getSerializedSize()+ + (leaseHolder == null ? 4 : leaseHolder.getSerializedSize())+ + 8+8+8+8+8+8+4+8; + } + + public void serialize(ReusableBuffer buffer) { + assert(buffer != null); + buffer.put((byte)this.msgType.ordinal()); + cellId.marshall(buffer); + proposalNo.serialize(buffer); + prevProposalNo.serialize(buffer); + buffer.putLong(this.getSendTimestamp()); + buffer.putLong(this.leaseTimeout); + if (leaseHolder != null) + this.leaseHolder.marshall(buffer); + else + buffer.putInt(0); + buffer.putInt(this.viewId); + buffer.putLong(this.masterEpochNumber); + } + + public FleaseMessage(ReusableBuffer buffer) { + assert(buffer != null); + this.msgType = MsgType.values()[buffer.get()]; + this.cellId = ASCIIString.unmarshall(buffer); + this.proposalNo = new ProposalNumber(buffer); + this.prevProposalNo = new ProposalNumber(buffer); + this.setSendTimestamp(buffer.getLong()); + this.leaseTimeout = buffer.getLong(); + this.leaseHolder = ASCIIString.unmarshall(buffer); + this.viewId = buffer.getInt(); + this.masterEpochNumber = buffer.getLong(); + } + + public boolean hasTimedOut(FleaseConfig cfg, long currentGlobalTimeout) { + assert(this.leaseTimeout > 0); + assert(this.leaseHolder != null); + return (this.leaseTimeout+cfg.getDMax() < currentGlobalTimeout); + } + + public boolean hasNotTimedOut(FleaseConfig cfg, long currentGlobalTimeout) { + assert(this.leaseTimeout > 0); + assert(this.leaseHolder != null); + return (this.leaseTimeout-cfg.getDMax() > currentGlobalTimeout); + } + + @Override + public FleaseMessage clone() { + FleaseMessage myClone = new FleaseMessage(this); + myClone.address = this.address; + myClone.cellId = this.cellId; + myClone.leaseHolder = this.leaseHolder; + myClone.leaseTimeout = this.leaseTimeout; + myClone.prevProposalNo = this.prevProposalNo; + myClone.proposalNo = this.proposalNo; + myClone.sendTimestamp = this.sendTimestamp; + myClone.viewId = this.viewId; + myClone.masterEpochNumber = this.masterEpochNumber; + return myClone; + } +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/comm/ProposalNumber.java b/java/flease/src/org/xtreemfs/foundation/flease/comm/ProposalNumber.java new file mode 100644 index 0000000..9b45eb2 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/comm/ProposalNumber.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.comm; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; + + +/** + * + * @author bjko + */ +public class ProposalNumber implements Cloneable { + + private final long proposalNo; + private final long senderId; + + public static final ProposalNumber EMPTY_PROPOSAL_NUMBER = new ProposalNumber(0, 0); + + public ProposalNumber(long proposalNo, long senderId) { + this.proposalNo = proposalNo; + this.senderId = senderId; + } + + public ProposalNumber(ReusableBuffer buffer) { + this.proposalNo = buffer.getLong(); + this.senderId = buffer.getLong(); + } + + /** + * checks if this message is before other + * @param other another message + * @return true if this message is before other + */ + public boolean before(ProposalNumber other) { + if (this.proposalNo < other.proposalNo) { + return true; + } else if (this.proposalNo > other.proposalNo) { + return false; + } else { + return (this.senderId < other.senderId); + } + } + + /** + * checks if this message is after other + * @param other another message + * @return true if this message is after (i.e. >) other + */ + public boolean after(ProposalNumber other) { + if (this.proposalNo > other.proposalNo) { + return true; + } else if (this.proposalNo < other.proposalNo) { + return false; + } else { + return (this.senderId > other.senderId); + } + } + + public boolean sameNumber(ProposalNumber other) { + return (senderId == other.senderId)&& (proposalNo == other.proposalNo); + } + + public boolean isEmpty() { + if (this == EMPTY_PROPOSAL_NUMBER) + return true; + return this.sameNumber(EMPTY_PROPOSAL_NUMBER); + } + + public void serialize(ReusableBuffer buffer) { + buffer.putLong(this.proposalNo); + buffer.putLong(this.senderId); + + } + + /** + * @return the proposalNo + */ + public long getProposalNo() { + return proposalNo; + } + + /** + * @return the senderId + */ + public long getSenderId() { + return senderId; + } + + public String toString() { + return "("+proposalNo+";"+senderId+")"; + } + + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/EchoClient.java b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/EchoClient.java new file mode 100644 index 0000000..fd02bc4 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/EchoClient.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.comm.tcp; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.concurrent.atomic.AtomicBoolean; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; + +/** + * + * @author bjko + */ +public class EchoClient { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + // TODO code application logic here + + Logging.start(Logging.LEVEL_DEBUG); + TimeSync ts = TimeSync.initializeLocal(50); + + try { + ts.waitForStartup(); + + TCPClient com = new TCPClient(3334,null, new NIOServer() { + + public void onAccept(NIOConnection connection) { + onConnect(connection); + } + + public void onConnect(NIOConnection connection) { + System.out.println("connected to "+connection.getEndpoint()); + connection.read(BufferPool.allocate(1024)); + connection.setContext(new AtomicBoolean(false)); + } + + public void onRead(NIOConnection connection, ReusableBuffer buffer) { + System.out.println("read from "+connection); + buffer.flip(); + byte[] data = new byte[buffer.remaining()]; + buffer.get(data); + String contents = new String(data); + BufferPool.free(buffer); + connection.read(BufferPool.allocate(1024)); + System.out.println(">> "+contents); + } + + public void onClose(NIOConnection connection) { + System.out.println("connection from "+connection.getEndpoint()+" closed "); + } + + public void onWriteFailed(IOException exception, Object context) { + System.out.println("could not write, context: "+context); + } + + public void onConnectFailed(InetSocketAddress endpoint, IOException exception, Object context) { + System.out.println("could not connect to: "+endpoint+", context: "+context); + } + }); + com.start(); + com.waitForStartup(); + + ReusableBuffer data = ReusableBuffer.wrap("Hello world!\n".getBytes()); + com.write(new InetSocketAddress("localhost", 3333), data, "Yagg"); + + Thread.sleep(100); + + data = ReusableBuffer.wrap("Hello world!\n".getBytes()); + com.write(new InetSocketAddress("localhost", 3333), data, "Yagga"); + + Thread.sleep(30000); + + data = ReusableBuffer.wrap("YaggaYagga!\n".getBytes()); + com.write(new InetSocketAddress("localhost", 3333), data, null); + + Thread.sleep(2000); + com.shutdown(); + ts.close(); + + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(1); + } + + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/EchoServer.java b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/EchoServer.java new file mode 100644 index 0000000..6dcaa3a --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/EchoServer.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.comm.tcp; + +import java.io.IOException; +import java.net.InetSocketAddress; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; + + +/** + * + * @author bjko + */ +public class EchoServer implements NIOServer { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + // TODO code application logic here + + try { + Logging.start(Logging.LEVEL_DEBUG); + TimeSync.initializeLocal(50); + + EchoServer s = new EchoServer(); + TCPCommunicator srv = new TCPCommunicator(s, 3333, null); + srv.start(); + srv.waitForStartup(); + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(1); + } + } + + public EchoServer() { + + } + + public void onAccept(NIOConnection connection) { + //ignore + System.out.println("connected: "+connection); + connection.read(BufferPool.allocate(1024)); + } + + public void onConnect(NIOConnection connection) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void onRead(NIOConnection connection, ReusableBuffer buffer) { + boolean done = false; + System.out.println("do read: "+connection); + for (int i = 0; i < buffer.position(); i++) { + if (buffer.get(i) == '\n') { + done = true; + break; + } + } + if (done || !buffer.hasRemaining()) { + buffer.flip(); + byte[] data = new byte[buffer.remaining()]; + buffer.get(data); + String contents = new String(data); + if (contents.startsWith("quit")) { + try { + connection.close(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } else { + //we have a full line + System.out.println("new buffer: "+connection); + buffer.clear(); + + if (contents.startsWith("stats")) { + contents = BufferPool.getStatus(); + } else { + contents = "you said: "+contents; + } + buffer.put(contents.getBytes()); + buffer.flip(); + connection.write(buffer,null); + connection.read(BufferPool.allocate(1024)); + } + } + } + + public void onClose(NIOConnection connection) { + System.out.println("disconnected: "+connection); + } + + public void onWriteFailed(IOException exception, Object context) { + System.out.println("an error occurred: "+exception); + } + + public void onConnectFailed(InetSocketAddress endpoint, IOException exception, Object context) { + //ignore + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/NIOConnection.java b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/NIOConnection.java new file mode 100644 index 0000000..99dee91 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/NIOConnection.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.comm.tcp; + +import java.net.InetSocketAddress; +import org.xtreemfs.foundation.buffer.ReusableBuffer; + +/** + * + * @author bjko + */ +public class NIOConnection { + + private TCPConnection connection; + + private Object context; + + public NIOConnection(TCPConnection connection) { + this.connection = connection; + } + + public void setContext(Object context) { + this.context = context; + } + + public Object getContext() { + return context; + } + + /** + * READ MUST ONLY BE USED FROM A NIOServer callback! + * @param buffer + */ + public void read(ReusableBuffer buffer) { + connection.setReceiveBuffer(buffer); + } + + /** + * Write is thread safe + * @param buffer + */ + public void write(ReusableBuffer buffer, Object context) { + connection.getServer().write(connection, buffer, context); + //FIXME:wakeup selector, change interest set + } + + public void close() { + connection.getServer().closeConnection(connection); + } + + public InetSocketAddress getEndpoint() { + return connection.getEndpoint(); + } + + public String toString() { + return "TCP connection (from "+connection.getChannel().socket().getRemoteSocketAddress()+" to local server @ "+connection.getServer().getPort()+")"; + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/NIOServer.java b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/NIOServer.java new file mode 100644 index 0000000..98fe391 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/NIOServer.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease.comm.tcp; + +import java.io.IOException; +import java.net.InetSocketAddress; +import org.xtreemfs.foundation.buffer.ReusableBuffer; + +/** + * + * @author bjko + */ +public interface NIOServer { + + /** + * called upon incoming connections. + * @param connection + */ + public void onAccept(NIOConnection connection); + + /** + * called when a connection was established + * make sure to issue the first write + * @param connection + */ + public void onConnect(NIOConnection connection); + + /** + * called when new data is available + * @param connection + * @param buffer + */ + public void onRead(NIOConnection connection, ReusableBuffer buffer); + + /** + * called when a connection is closed + * @param connection + */ + public void onClose(NIOConnection connection); + + + public void onWriteFailed(IOException exception, Object context); + + public void onConnectFailed(InetSocketAddress endpoint, IOException exception, Object context); + +} \ No newline at end of file diff --git a/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPClient.java b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPClient.java new file mode 100644 index 0000000..99a0f5a --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPClient.java @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease.comm.tcp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; +import java.util.Timer; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.xtreemfs.foundation.LifeCycleListener; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; + +/** + * + * @author bjko + */ +public class TCPClient { + + private static final long MAX_WAITTIME_MS = 1000 * 60 * 10; + + final Map connections; + + final ReadWriteLock conLock; + + final TCPCommunicator server; + + final NIOServer implementation; + + final Timer closeTimer; + + public TCPClient(int port, InetAddress bindAddr, final NIOServer implementation) throws IOException { + conLock = new ReentrantReadWriteLock(); + connections = new HashMap(); + this.implementation = implementation; + NIOServer impl = new NIOServer() { + + public void onAccept(NIOConnection connection) { + final InetSocketAddress endpt = connection.getEndpoint(); + try { + conLock.writeLock().lock(); + ClientConnection cc = connections.get(endpt); + if (cc == null) { + cc = new ClientConnection(); + cc.setConnection(connection); + cc.connectSucces(); + connections.put(endpt,cc); + } + } finally { + conLock.writeLock().unlock(); + } + implementation.onAccept(connection); + } + + public void onConnect(NIOConnection connection) { + final InetSocketAddress endpt = connection.getEndpoint(); + try { + conLock.writeLock().lock(); + ClientConnection cc = connections.get(endpt); + if (cc != null) + cc.connectSucces(); + else { + Logging.logMessage(Logging.LEVEL_ERROR, this,"connect for unknown connection: "+connection); + connection.close(); + } + } finally { + conLock.writeLock().unlock(); + } + implementation.onConnect(connection); + } + + public void onRead(NIOConnection connection, ReusableBuffer buffer) { + implementation.onRead(connection, buffer); + } + + public void onClose(NIOConnection connection) { + final InetSocketAddress endpt = connection.getEndpoint(); + try { + conLock.writeLock().lock(); + connections.remove(endpt); + } finally { + conLock.writeLock().unlock(); + } + implementation.onClose(connection); + } + + public void onWriteFailed(IOException exception, Object context) { + implementation.onWriteFailed(exception, context); + } + + public void onConnectFailed(InetSocketAddress endpoint, IOException exception, Object context) { + System.out.println("connect failed for: "+endpoint); + try { + conLock.readLock().lock(); + ClientConnection cc = connections.get(endpoint); + if (cc != null) { + synchronized (cc) { + cc.connectFailed(); + cc.setConnection(null); + } + } + } finally { + conLock.readLock().unlock(); + } + implementation.onConnectFailed(endpoint,exception,context); + } + }; + + server = new TCPCommunicator(impl, port, bindAddr); + + closeTimer = new Timer(); + /*closeTimer.scheduleAtFixedRate(new TimerTask() { + + @Override + public void run() { + final long now = TimeSync.getLocalSystemTime(); + try { + conLock.writeLock().lock(); + for (Entry e : connections.entrySet()) { + if (e.getValue().lastConnectAttempt_ms) + + } + } finally { + conLock.writeLock().unlock(); + } + } + }, CON_TIMEOUT, CON_TIMEOUT); + */ + + } + + public void write(InetSocketAddress remote, ReusableBuffer data, Object context) { + ClientConnection client = null; + try { + conLock.readLock().lock(); + client = connections.get(remote); + } finally { + conLock.readLock().unlock(); + } + if (client == null) { + try { + conLock.writeLock().lock(); + client = connections.get(remote); + if (client == null) { + client = new ClientConnection(); + connections.put(remote, client); + } + } finally { + conLock.writeLock().unlock(); + } + } + synchronized (client) { + try { + if (!client.isConnected()) { + if (client.canReconnect()) { + NIOConnection con = server.connect(remote,null); + client.setConnection(con); + } else { + implementation.onWriteFailed(new IOException("cannot connect to server, blocked due to reconnect timeout"), context); + return; + } + } + } catch (IOException ex) { + implementation.onWriteFailed(ex, context); + return; + } + assert(client.getConnection() != null); + client.getConnection().write(data, context); + } + + + } + + public void start() { + server.start(); + } + + public void waitForStartup() throws Exception { + server.waitForStartup(); + } + + public void shutdown() { + server.shutdown(); + closeTimer.cancel(); + } + + public void waitForShutdown() throws Exception { + server.waitForShutdown(); + } + + public void setLifeCycleListener(LifeCycleListener l) { + server.setLifeCycleListener(l); + } + + public int getSendQueueSize() { + return server.getSendQueueSize(); + } + + private static class ClientConnection { + + NIOConnection connection; + + long lastConnectAttempt_ms; + + long waitTime_ms; + + public ClientConnection() { + lastConnectAttempt_ms = 0; + waitTime_ms = 1000; + } + + public NIOConnection getConnection() { + return connection; + } + + public void setConnection(NIOConnection connection) { + this.connection = connection; + } + + public boolean canReconnect() { + return (lastConnectAttempt_ms + waitTime_ms < TimeSync.getLocalSystemTime()); + } + + public boolean isConnected() { + return (connection != null); + } + + public void connectSucces() { + waitTime_ms = 1000; + lastConnectAttempt_ms = 0; + } + + public void connectFailed() { + lastConnectAttempt_ms = TimeSync.getLocalSystemTime(); + waitTime_ms = waitTime_ms * 2; + if (waitTime_ms > MAX_WAITTIME_MS) { + waitTime_ms = MAX_WAITTIME_MS; + } + } + } +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPCommunicator.java b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPCommunicator.java new file mode 100644 index 0000000..c037211 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPCommunicator.java @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease.comm.tcp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.flease.comm.tcp.TCPConnection.SendRequest; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * + * @author bjko + */ +public class TCPCommunicator extends LifeCycleThread { + + private final int port; + + /** + * the server socket + */ + private final ServerSocketChannel socket; + + /** + * Selector for server socket + */ + private final Selector selector; + + private final NIOServer implementation; + + private final List connections; + + private final Queue pendingCons; + + private final AtomicInteger sendQueueSize; + + /** + * + * @param implementation + * @param port, 0 to disable server mode + * @param bindAddr + * @throws IOException + */ + public TCPCommunicator(NIOServer implementation, int port, InetAddress bindAddr) throws IOException { + super("TCPcom@" + port); + + this.port = port; + this.implementation = implementation; + this.connections = new LinkedList(); + this.pendingCons = new ConcurrentLinkedQueue(); + sendQueueSize = new AtomicInteger(); + + // open server socket + if (port == 0) { + socket = null; + } else { + socket = ServerSocketChannel.open(); + socket.configureBlocking(false); + socket.socket().setReceiveBufferSize(256 * 1024); + socket.socket().setReuseAddress(true); + socket.socket().bind( + bindAddr == null ? new InetSocketAddress(port) : new InetSocketAddress(bindAddr, port)); + } + + // create a selector and register socket + selector = Selector.open(); + if (socket != null) + socket.register(selector, SelectionKey.OP_ACCEPT); + } + + /** + * Stop the server and close all connections. + */ + public void shutdown() { + this.interrupt(); + } + + /** + * sends a response. + * + * @param request + * the request + */ + public void write(TCPConnection connection, ReusableBuffer buffer, Object context) { + assert (buffer != null); + synchronized (connection) { + if (connection.getChannel().isConnected()) { + if (connection.sendQueueIsEmpty()) { + try { + int bytesWritten = connection.getChannel().write(buffer.getBuffer()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"directly wrote %d bytes to %s",bytesWritten,connection.getChannel().socket().getRemoteSocketAddress().toString()); + } + if (bytesWritten < 0) { + if (context != null) + implementation.onWriteFailed(new IOException("remote party closed connection while writing"), context); + abortConnection(connection,new IOException("remote party closed connection while writing")); + return; + } + if (!buffer.hasRemaining()) { + //we are done + BufferPool.free(buffer); + return; + } + } catch (ClosedChannelException ex) { + if (context != null) + implementation.onWriteFailed(ex, context); + abortConnection(connection,ex); + } catch (IOException ex) { + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this,ex); + if (context != null) + implementation.onWriteFailed(ex, context); + abortConnection(connection,ex); + } + } + + synchronized (connection) { + boolean isEmpty = connection.sendQueueIsEmpty(); + if (isEmpty) { + try { + SelectionKey key = connection.getChannel().keyFor(selector); + if (key != null) { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + } + } catch (CancelledKeyException ex) { + } + } + } + + sendQueueSize.incrementAndGet(); + connection.addToSendQueue(new TCPConnection.SendRequest(buffer, context)); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"enqueued write to %s",connection.getEndpoint()); + } + selector.wakeup(); + } else { + // ignore and free bufers + if (connection.getChannel().isConnectionPending()) { + sendQueueSize.incrementAndGet(); + connection.addToSendQueue(new TCPConnection.SendRequest(buffer, context)); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"enqueued write to %s",connection.getEndpoint()); + } + } else { + BufferPool.free(buffer); + if (context != null) + implementation.onWriteFailed(new IOException("Connection already closed"), context); + } + } + } + } + + public void run() { + notifyStarted(); + + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, "TCP Server @%d ready", port); + } + + try { + while (!isInterrupted()) { + // try to select events... + try { + final int numKeys = selector.select(); + if (!pendingCons.isEmpty()) { + while (true) { + TCPConnection con = pendingCons.poll(); + if (con == null) { + break; + } + try { + assert(con.getChannel() != null); + con.getChannel().register(selector, + SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE | SelectionKey.OP_READ, con); + } catch (ClosedChannelException ex) { + abortConnection(con,ex); + } + } + } + if (numKeys == 0) { + continue; + } + } catch (CancelledKeyException ex) { + // who cares + } catch (IOException ex) { + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "Exception while selecting: %s", ex.toString()); + continue; + } + + // fetch events + Set keys = selector.selectedKeys(); + Iterator iter = keys.iterator(); + + // process all events + while (iter.hasNext()) { + SelectionKey key = iter.next(); + + // remove key from the list + iter.remove(); + try { + + if (key.isAcceptable()) { + acceptConnection(key); + } + if (key.isConnectable()) { + connectConnection(key); + } + if (key.isReadable()) { + readConnection(key); + } + if (key.isWritable()) { + writeConnection(key); + } + } catch (CancelledKeyException ex) { + // nobody cares... + continue; + } + } + } + + for (TCPConnection con : connections) { + try { + con.close(implementation,new IOException("server shutdown")); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + // close socket + selector.close(); + if (socket != null) + socket.close(); + + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "TCP Server @%d shutdown complete", port); + } + + notifyStopped(); + } catch (Throwable thr) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this, "TPC Server @%d CRASHED!", port); + notifyCrashed(thr); + } + } + + private void connectConnection(SelectionKey key) { + final TCPConnection con = (TCPConnection) key.attachment(); + final SocketChannel channel = con.getChannel(); + + try { + if (channel.isConnectionPending()) { + channel.finishConnect(); + } + synchronized (con) { + if (con.getSendBuffer() != null) { + key.interestOps(SelectionKey.OP_WRITE | SelectionKey.OP_READ); + } else { + key.interestOps(SelectionKey.OP_READ); + } + } + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connected from %s to %s", con + .getChannel().socket().getLocalSocketAddress().toString(), channel.socket().getRemoteSocketAddress() + .toString()); + } + implementation.onConnect(con.getNIOConnection()); + } catch (IOException ex) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this,ex); + } + implementation.onConnectFailed(con.getEndpoint(), ex, con.getNIOConnection().getContext()); + con.close(implementation,ex); + } + + } + + public NIOConnection connect(InetSocketAddress server, Object context) throws IOException { + TCPConnection con = openConnection(server,context); + return con.getNIOConnection(); + } + + private TCPConnection openConnection(InetSocketAddress server, Object context) throws IOException { + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connect to %s", server + .toString()); + } + SocketChannel channel = null; + TCPConnection con = null; + try { + channel = SocketChannel.open(); + channel.configureBlocking(false); + //channel.socket().setTcpNoDelay(true); + channel.socket().setReceiveBufferSize(256 * 1024); + channel.connect(server); + con = new TCPConnection(channel, this, server); + con.getNIOConnection().setContext(context); + pendingCons.add(con); + selector.wakeup(); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connection established"); + return con; + } catch (IOException ex) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "cannot contact server %s", + server); + } + if (con != null) + con.close(implementation, ex); + throw ex; + } + + + } + + + /** + * accept a new incomming connection + * + * @param key + * the acceptable key + */ + private void acceptConnection(SelectionKey key) { + SocketChannel client = null; + TCPConnection connection = null; + // FIXME: Better exception handling! + + try { + // accept connection + client = socket.accept(); + connection = new TCPConnection(client,this,(InetSocketAddress)client.socket().getRemoteSocketAddress()); + + // and configure it to be non blocking + // IMPORTANT! + client.configureBlocking(false); + client.register(selector, SelectionKey.OP_READ, connection); + //client.socket().setTcpNoDelay(true); + + //numConnections.incrementAndGet(); + + connections.add(connection); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connect from client at %s", + client.socket().getRemoteSocketAddress().toString()); + } + implementation.onAccept(connection.getNIOConnection()); + + } catch (ClosedChannelException ex) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "cannot establish connection: %s", ex.toString()); + } + } catch (IOException ex) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "cannot establish connection: %s", ex.toString()); + } + } + } + + + /** + * read data from a readable connection + * + * @param key + * a readable key + */ + private void readConnection(SelectionKey key) { + final TCPConnection con = (TCPConnection) key.attachment(); + final SocketChannel channel = con.getChannel(); + + try { + + while (true) { + final ReusableBuffer readBuf = con.getReceiveBuffer(); + if (readBuf == null) + return; + final int numBytesRead = channel.read(readBuf.getBuffer()); + if (numBytesRead == -1) { + // connection closed + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "client closed connection (EOF): %s", channel.socket() + .getRemoteSocketAddress().toString()); + } + abortConnection(con,new IOException("remote end closed connection while reading data")); + return; + } else if (numBytesRead == 0) { + return; + } + implementation.onRead(con.getNIOConnection(), readBuf); + } + } catch (ClosedChannelException ex) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "connection to %s closed by remote peer", con.getChannel().socket() + .getRemoteSocketAddress().toString()); + } + abortConnection(con,ex); + } catch (IOException ex) { + // simply close the connection + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + } + abortConnection(con,ex); + } + } + + /** + * write data to a writeable connection + * + * @param key + * the writable key + */ + private void writeConnection(SelectionKey key) { + final TCPConnection con = (TCPConnection) key.attachment(); + final SocketChannel channel = con.getChannel(); + + SendRequest srq = null; + try { + + while (true) { + srq = con.getSendBuffer(); + if (srq == null) { + synchronized (con) { + srq = con.getSendBuffer(); + if (srq == null) { + // no more responses, stop writing... + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + return; + } + } + } + // send data + final long numBytesWritten = channel.write(srq.getData().getBuffer()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"wrote %d bytes to %s",numBytesWritten,channel.socket().getRemoteSocketAddress().toString()); + } + if (numBytesWritten == -1) { + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "client closed connection (EOF): %s", channel.socket().getRemoteSocketAddress().toString()); + } + // connection closed + + abortConnection(con, new IOException("remote end closed connection while writing data")); + return; + } + if (srq.getData().hasRemaining()) { + // not enough data... + break; + } + // finished sending fragment + // clean up :-) request finished + + BufferPool.free(srq.getData()); + sendQueueSize.decrementAndGet(); + con.nextSendBuffer(); + + } + } catch (ClosedChannelException ex) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "connection to %s closed by remote peer", con.getChannel().socket().getRemoteSocketAddress().toString()); + } + abortConnection(con,ex); + } catch (IOException ex) { + // simply close the connection + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + } + abortConnection(con,ex); + } + } + + public int getSendQueueSize() { + return sendQueueSize.get(); + } + + void closeConnection(TCPConnection con) { + if (con.isClosed()) + return; + con.setClosed(); + final SocketChannel channel = con.getChannel(); + + // remove the connection from the selector and close socket + try { + synchronized (connections) { + connections.remove(con); + } + final SelectionKey key = channel.keyFor(selector); + if (key != null) + key.cancel(); + con.close(null,null); + } catch (Exception ex) { + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "closing connection to %s", channel + .socket().getRemoteSocketAddress().toString()); + } + } + + void abortConnection(TCPConnection con, IOException exception) { + if (con.isClosed()) + return; + con.setClosed(); + final SocketChannel channel = con.getChannel(); + + // remove the connection from the selector and close socket + try { + synchronized (connections) { + connections.remove(con); + } + final SelectionKey key = channel.keyFor(selector); + if (key != null) + key.cancel(); + con.close(implementation,exception); + } catch (Exception ex) { + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "closing connection to %s", channel + .socket().getRemoteSocketAddress().toString()); + } + implementation.onClose(con.getNIOConnection()); + } + + int getPort() { + return this.port; + } +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPConnection.java b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPConnection.java new file mode 100644 index 0000000..99b04ac --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPConnection.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease.comm.tcp; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.channels.SocketChannel; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicBoolean; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; + +/** + * + * @author bjko + */ +public class TCPConnection { + + private SocketChannel channel; + + private Queue sendQueue; + + private ReusableBuffer receiveBuffer; + + private final NIOConnection nioCon; + + private final TCPCommunicator myServer; + + private final AtomicBoolean closed; + + private final InetSocketAddress endpoint; + + public TCPConnection(SocketChannel channel, TCPCommunicator myServer, InetSocketAddress endpoint) { + this.channel = channel; + sendQueue = new ConcurrentLinkedQueue(); + nioCon = new NIOConnection(this); + this.myServer = myServer; + closed = new AtomicBoolean(false); + this.endpoint = endpoint; + } + + + public TCPCommunicator getServer() { + return myServer; + } + + public NIOConnection getNIOConnection() { + return nioCon; + } + + public SocketChannel getChannel() { + return channel; + } + + public InetSocketAddress getEndpoint() { + return this.endpoint; + } + + public SendRequest getSendBuffer() { + return sendQueue.peek(); + } + + public void nextSendBuffer() { + sendQueue.poll(); + } + + public void addToSendQueue(SendRequest buffer) { + sendQueue.add(buffer); + } + + public boolean sendQueueIsEmpty() { + return sendQueue.isEmpty(); + } + + public ReusableBuffer getReceiveBuffer() { + return receiveBuffer; + } + + public void setReceiveBuffer(ReusableBuffer buffer) { + receiveBuffer = buffer; + } + + public boolean isClosed() { + return closed.get(); + } + + public void setClosed() { + closed.set(true); + } + + public void close(NIOServer implementation, IOException error) { + try { + BufferPool.free(receiveBuffer); + channel.close(); + } catch (IOException ex) { + //ignore + } finally { + for (SendRequest rq : sendQueue) { + BufferPool.free(rq.data); + } + if (implementation != null) { + for (SendRequest rq : sendQueue) { + if (rq.getContext() != null) + implementation.onWriteFailed(error, rq.getContext()); + } + } + } + } + + public static class SendRequest { + private final ReusableBuffer data; + private final Object context; + + public SendRequest(ReusableBuffer data, Object context) { + this.data = data; + this.context = context; + } + + /** + * @return the data + */ + public ReusableBuffer getData() { + return data; + } + + /** + * @return the context + */ + public Object getContext() { + return context; + } + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPFleaseCommunicator.java b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPFleaseCommunicator.java new file mode 100644 index 0000000..16af69d --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/comm/tcp/TCPFleaseCommunicator.java @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease.comm.tcp; + +import org.xtreemfs.foundation.flease.*; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteOrder; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import org.xtreemfs.foundation.LifeCycleListener; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.logging.Logging; + +/** + * + * @author bjko + */ +public class TCPFleaseCommunicator implements FleaseMessageSenderInterface { + + private final FleaseStage stage; + + private final int port; + + private TCPClient comm; + + private volatile boolean quit; + + private final AtomicBoolean sendMode; + + private final LinkedBlockingQueue q; + + private static final int MAX_UDP_SIZE = 16*1024; + + private long numTx,numRx; + + public static TCPFleaseCommunicator instance; + + private AtomicInteger numIn, numOut; + + public TCPFleaseCommunicator(FleaseConfig config, String lockfileDir, + boolean ignoreLockForTesting, + final FleaseViewChangeListenerInterface viewListener, FleaseStatusListener fsl, MasterEpochHandlerInterface meHandler) throws Exception { + stage = new FleaseStage(config, lockfileDir, this, ignoreLockForTesting, viewListener,fsl,meHandler); + port = config.getEndpoint().getPort(); + q = new LinkedBlockingQueue(); + sendMode = new AtomicBoolean(false); + numTx = 0; + numRx = 0; + numIn = new AtomicInteger(); + numOut = new AtomicInteger(); + instance = this; //only for testing! + comm = new TCPClient(port, null, new NIOServer() { + + public void onAccept(NIOConnection connection) { + ReusableBuffer hdr = BufferPool.allocate(4); + hdr.getBuffer().order(ByteOrder.LITTLE_ENDIAN); + ReusableBuffer bdy = BufferPool.allocate(2048); + bdy.getBuffer().order(ByteOrder.LITTLE_ENDIAN); + Connection c = new Connection(hdr, bdy); + connection.setContext(c); + connection.read(hdr); + } + + public void onConnect(NIOConnection connection) { + onAccept(connection); + } + + public void onRead(NIOConnection connection, ReusableBuffer buffer) { + Connection c = (Connection) connection.getContext(); + try { + if (c.readingHdr) { + if (buffer.hasRemaining()) { + connection.read(buffer); + } else { + buffer.flip(); + c.readingHdr = false; + int size = buffer.getInt(); + if ((size <= 0) || (size > 2048)) { + Logging.logMessage(Logging.LEVEL_ERROR, this,"warining: invalid fragment size: %d",size); + connection.close(); + return; + } + buffer.clear(); + c.data.limit(size); + connection.read(c.data); + } + } else { + if (buffer.hasRemaining()) { + connection.read(buffer); + } else { + buffer.flip(); + FleaseMessage m = new FleaseMessage(buffer); + m.setSender(connection.getEndpoint()); + buffer.clear(); + c.readingHdr = true; + connection.read(c.header); + stage.receiveMessage(m); + } + } + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this,ex); + Logging.logMessage(Logging.LEVEL_ERROR, this,buffer.toString()); + connection.close(); + } + + } + + public void onClose(NIOConnection connection) { + Connection c = (Connection) connection.getContext(); + if (c.readingHdr) + BufferPool.free(c.data); + else + BufferPool.free(c.header); + + } + + public void onWriteFailed(IOException exception, Object context) { + Logging.logMessage(Logging.LEVEL_ERROR, this,"write failed: "+context); + } + + public void onConnectFailed(InetSocketAddress endpoint, IOException exception, Object context) { + Logging.logMessage(Logging.LEVEL_ERROR, this,"could not connect to: "+endpoint); + } + }); + + /*Timer t = new Timer(true); + t.scheduleAtFixedRate(new TimerTask() { + + long maxQsize = 0; + long sum = 0; + long numSamples = 0; + int cnt = 0; + + @Override + public void run() { + long size = comm.getSendQueueSize(); + sum = sum+size; + numSamples++; + if (size > maxQsize) + maxQsize = size; + cnt++; + if (cnt == 10) { + System.out.println("avg: "+(sum/numSamples)+" max: "+maxQsize); + cnt = 0; + } + } + }, 10, 1000);*/ + } + + public FleaseStage getStage() { + return stage; + } + + + public void sendMessage(FleaseMessage message, InetSocketAddress recipient) { + FleaseMessage m = message.clone(); + m.setSender(recipient); + send(m); + + if (FleaseStage.COLLECT_STATISTICS) + numOut.incrementAndGet(); + } + + /** + * sends a UDPRequest. + * + * @attention Overwrites the first byte of rq.data with the message type. + */ + public void send(FleaseMessage rq) { + if (FleaseStage.COLLECT_STATISTICS) + numIn.incrementAndGet(); + + final int size = rq.getSize(); + ReusableBuffer data = BufferPool.allocate(size+4); + data.getBuffer().order(ByteOrder.LITTLE_ENDIAN); + data.putInt(size); + rq.serialize(data); + data.getBuffer().order(ByteOrder.BIG_ENDIAN); + data.flip(); + if (data.remaining() != size+4) + throw new IllegalStateException("data is wrong: "+data); + comm.write(rq.getSender(), data, null); + } + + public void start() throws Exception { + comm.start(); + comm.waitForStartup(); + stage.start(); + stage.waitForStartup(); + } + + public void shutdown() throws Exception { + stage.shutdown(); + stage.waitForShutdown(); + comm.shutdown(); + comm.waitForShutdown(); + } + + public void setLifeCycleListener(LifeCycleListener l) { + comm.setLifeCycleListener(l); + stage.setLifeCycleListener(l); + } + + public int getNumIn() { + return numIn.getAndSet(0); + } + + public int getNumOut() { + return numOut.getAndSet(0); + } + + private static class Connection { + public ReusableBuffer header; + public ReusableBuffer data; + public boolean readingHdr; + + public Connection(ReusableBuffer header, ReusableBuffer data) { + this.header = header; + this.data = data; + readingHdr = true; + } + + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/proposer/CellAction.java b/java/flease/src/org/xtreemfs/foundation/flease/proposer/CellAction.java new file mode 100644 index 0000000..bb6e76b --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/proposer/CellAction.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2012 by Bjoern Kolbeck. + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.proposer; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * Stores a single action for traces. + * @author bjko + */ +public class CellAction { + + private final ActionName actionName; + private final String message; + + public static enum ActionName { + PROPOSER_SET_VIEWID, + PROPOSER_CELL_OPENED, + PROPOSER_CELL_CLOSED, + PROPOSER_ACQUIRE_LEASE, + PROPOSER_RETURNED_LOCAL_LEASE, + PROPOSER_START_RENEW, + PROPOSER_RENEW_CANCELLED, + PROPOSER_RENEW_FAILED_NO_LEASE, + PROPOSER_RENEW_FAILED_LEASE_TO, + PROPOSER_RENEW_FAILED_LEASE_NOT_ENOUGH_TIME, + PROPOSER_RENEW_FAILED_NOT_OWNER, + PROPOSER_HANDOVER_LEASE, + PROPOSER_RESTART_EVENT, + PROPOSER_RENEW_EVENT, + PROPOSER_INTERNAL_ERROR_CELL_RESET, + PROPOSER_SET_BALLOT_NO, + PROPOSER_REQUEST_MASTER_EPOCH, + PROPOSER_WAIT_FOR_ACK, + PROPOSER_PREPARE_START, + PROPOSER_PREPARE_PROCESS_RESPONSE, + PROPOSER_PREPARE_TIMEOUT, + PROPOSER_VIEW_OUTDATED, + PROPOSER_PREPARE_OVERRULED, + PROPOSER_PREPARE_SUCCESS, + PROPOSER_PREPARE_EMPTY, + PROPOSER_PREPARE_PRIOR_VALUE, + PROPOSER_PREPARE_IMPLICIT_RENEW, + PROPOSER_PREPARE_MAX_MASTER_EPOCH, + PROPOSER_ACCEPT_START, + PROPOSER_ACCEPT_PROCESS_RESPONSE, + PROPOSER_ACCEPT_TIMEOUT, + PROPOSER_ACCEPT_OVERRULED, + PROPOSER_LEARN_START, + PROPOSER_LEARN_TIMED_OUT, + PROPOSER_SCHEDULED_RENEW, + PROPOSER_LEARN_LEASE_IN_GRACE_PERIOD, + PROPOSER_CANCELLED, + PROPOSER_CANCEL_LEASE_FAILED, + PROPOSER_CANCEL_SCHEDULE_RESTART, + PROPOSER_RECEIVED_OUT_OF_SYNC_MSG, + PROPOSER_RENEW_LEASE, + PROPOSER_RENEW_FAILED_NO_LOCAL_LEASE_INFO, + PROPOSER_SCHEDULED_RESTART, + PROPOSER_SCHEDULED_TIMEOUT, + PROPOSER_PREPARE_FAILED, + PROPOSER_PREPARE_LEASE_TO, + PROPOSER_ACCEPT_FAILED, + PROPOSER_ACCEPT_SUCCESS, + } + + public static class CellActionList implements Iterable { + public static final int MAX_ACTIONS_IN_LIST = 50; + List actions; + + public CellActionList() { + actions = new LinkedList(); + } + + public void addAction(ActionName actionName) { + addAction(actionName, null); + } + + public void addAction(ActionName actionName, String message) { + actions.add(new CellAction(actionName, message)); + if (actions.size() > MAX_ACTIONS_IN_LIST) { + actions.remove(0); + } + } + + @Override + public Iterator iterator() { + return actions.iterator(); + } + + @Override + public String toString() { + StringBuilder text = new StringBuilder(); + text.append("actions:["); + Iterator iter = iterator(); + while (iter.hasNext()) { + CellAction action = iter.next(); + text.append(action); + if (iter.hasNext()) { + text.append(", "); + } + } + text.append("]"); + return text.toString(); + } + + } + + public CellAction(ActionName actionName) { + this.actionName = actionName; + this.message = null; + } + + public CellAction(ActionName actionName, String message) { + this.actionName = actionName; + this.message = message; + } + + public String toString() { + return actionName + (message != null + ? " (" + message +")" + : ""); + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseException.java b/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseException.java new file mode 100644 index 0000000..1b93a18 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseException.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.proposer; + +/** + * + * @author bjko + */ +public class FleaseException extends Exception { + + private String fleaseCellDebugString = null; + + public FleaseException(String message) { + super(message); + } + + public FleaseException(String message, Throwable cause) { + super(message, cause); + } + + public void addFleaseCellDebugString(String fleaseCellDebugString) { + this.fleaseCellDebugString = fleaseCellDebugString; + } + + public String getFleaseCellDebugString() { + return fleaseCellDebugString; + } +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseListener.java b/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseListener.java new file mode 100644 index 0000000..c50dd53 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseListener.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.proposer; + +import org.xtreemfs.foundation.buffer.ASCIIString; + +/** + * + * @author bjko + */ +public interface FleaseListener { + + public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long masterEpochNumber); + + public void proposalFailed(ASCIIString cellId, Throwable cause); + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseLocalQueueInterface.java b/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseLocalQueueInterface.java new file mode 100644 index 0000000..5ec9b50 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseLocalQueueInterface.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.proposer; + +import org.xtreemfs.foundation.flease.comm.FleaseMessage; + +/** + * + * @author bjko + */ +public interface FleaseLocalQueueInterface { + + public void enqueueMessage(FleaseMessage message); + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseProposer.java b/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseProposer.java new file mode 100644 index 0000000..8ce97a0 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseProposer.java @@ -0,0 +1,1197 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.proposer; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.Flease; +import org.xtreemfs.foundation.flease.FleaseConfig; +import org.xtreemfs.foundation.flease.FleaseStage; +import org.xtreemfs.foundation.flease.FleaseStatusListener; +import org.xtreemfs.foundation.flease.FleaseViewChangeListenerInterface; +import org.xtreemfs.foundation.flease.MasterEpochHandlerInterface; +import org.xtreemfs.foundation.flease.acceptor.FleaseAcceptor; +import org.xtreemfs.foundation.flease.acceptor.LearnEventListener; +import org.xtreemfs.foundation.flease.comm.FleaseCommunicationInterface; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.flease.comm.FleaseMessage.MsgType; +import org.xtreemfs.foundation.flease.comm.ProposalNumber; +import org.xtreemfs.foundation.flease.proposer.CellAction.ActionName; +import org.xtreemfs.foundation.flease.proposer.FleaseProposerCell.State; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * + * @author bjko + */ +public class FleaseProposer { + + final Map cells; + + final FleaseConfig config; + + final FleaseAcceptor localAcceptor; + + final FleaseCommunicationInterface comm; + + //private long lastBallotNo; + + private FleaseViewChangeListenerInterface viewListener; + + private final FleaseStatusListener leaseListener; + + private final LearnEventListener evListener; + + private final FleaseLocalQueueInterface localQueue; + + private final MasterEpochHandlerInterface meHandler; + + public FleaseProposer( + FleaseConfig config, + FleaseAcceptor localAcceptor, + FleaseCommunicationInterface comm, + FleaseStatusListener leaseListener, + LearnEventListener evListener, + FleaseLocalQueueInterface localQueue, + MasterEpochHandlerInterface meHandler) { + cells = new HashMap(100000); + this.config = config; + this.localAcceptor = localAcceptor; + this.comm = comm; + assert(leaseListener != null); + this.leaseListener = leaseListener; + this.evListener = evListener; + this.localQueue = localQueue; + this.meHandler = meHandler; + assert ((meHandler == null) || (meHandler != null) && (localQueue != null)); + } + + public void setViewChangeListener(FleaseViewChangeListenerInterface listener) { + viewListener = listener; + } + + public void setViewId(ASCIIString cellId, int viewId) { + FleaseProposerCell cell = cells.get(cellId); + + // Set the view only if the cell is already open. New cells have to be opened with a viewId @see FleaseStage.openCell() + if (cell != null) { + cell.setViewId(viewId); + cell.addAction(ActionName.PROPOSER_SET_VIEWID, Integer.toString(viewId)); + } + } + + public Flease updatePrevLeaseForCell(ASCIIString cellId, Flease lease) { + FleaseProposerCell cell = cells.get(cellId); + if (cell == null) { + return null; + } + final Flease prevLease = cell.getPrevLease(); + if (!prevLease.equals(lease)) { + cell.setPrevLease(lease); + return prevLease; + } + return null; + } + + public ProposalNumber getCurrentBallotNo(ASCIIString cellId) { + FleaseProposerCell cell = cells.get(cellId); + if (cell == null) { + return ProposalNumber.EMPTY_PROPOSAL_NUMBER; + } + return cell.getBallotNo(); + } + + public void openCell( + ASCIIString cellId, + List acceptors, + boolean requestMasterEpoch, + int viewId) throws FleaseException { + FleaseProposerCell cell = cells.get(cellId); + if (cell == null) { + cell = new FleaseProposerCell(cellId, acceptors, config.getSenderId()); + cell.setCellState(State.IDLE); + cell.setRequestMasteEpoch(requestMasterEpoch); + cell.setViewId(viewId); + cells.put(cellId, cell); + cell.addAction(ActionName.PROPOSER_CELL_OPENED); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_WARN, + Category.replication, + this, + "P created new cellId %s", + cellId); + } + acquireLease(cell); + } else { + throw new FleaseException("cell already opened"); + } + } + + public void closeCell(ASCIIString cellId) { + FleaseProposerCell cell = cells.remove(cellId); + if (cell != null) { + cell.addAction(ActionName.PROPOSER_CELL_CLOSED); + } + } + + private void acquireLease(FleaseProposerCell cell) throws FleaseException { + cell.addAction(ActionName.PROPOSER_ACQUIRE_LEASE); + final ASCIIString cellId = cell.getCellId(); + //check local results + FleaseMessage localInfo = localAcceptor.getLocalLeaseInformation(cellId); + if ((localInfo != null) && (localInfo.hasNotTimedOut(config, TimeSync.getGlobalTime()))) { + //we can safely return the learned values + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P request served from local state: %s", + cellId); + } + cell.addAction(ActionName.PROPOSER_RETURNED_LOCAL_LEASE); + evListener.learnedEvent(localInfo.getCellId(), + localInfo.getLeaseHolder(), + localInfo.getLeaseTimeout(), + localInfo.getMasterEpochNumber()); + return; + } + + if (cell.getCellState() == State.IDLE) { + //can safely start the proposal + cell.setNumFailures(0); + cell.setHandoverTo(null); + startPrepare(cell,config.getIdentity()); + } else { + cell.addAction(ActionName.PROPOSER_ACQUIRE_LEASE, "not idle"); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_WARN, + Logging.Category.replication, + this, + "P cellId %s is not idle, ignoring acquireLease", + cellId); + } + } + } + + public void renewLease(ASCIIString cellId) throws FleaseException { + FleaseProposerCell cell = cells.get(cellId); + if (cell == null) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Category.replication, + this, + "P ignore renew for closed/unknown cell %s", cellId); + } + return; + } + cell.addAction(ActionName.PROPOSER_RENEW_LEASE); + //fixme + + if (cell.isHandoverInProgress()) { + Logging.logMessage(Logging.LEVEL_INFO, + this, + "handover in progress for cell %s, renew canceled", + cell.getCellId()); + return; + } + + //check local state + FleaseMessage localInfo = localAcceptor.getLocalLeaseInformation(cellId); + + if (localInfo == null) { + cell.addAction(ActionName.PROPOSER_RENEW_FAILED_NO_LOCAL_LEASE_INFO); + throw new FleaseException("cannot renew lease, no local lease information!"); + } + if (!localInfo.getLeaseHolder().equals(config.getIdentity())) { + cell.addAction(ActionName.PROPOSER_RENEW_FAILED_NOT_OWNER); + throw new FleaseException("cannot renew lease, not lease owner (owner is " + + localInfo.getLeaseHolder() + ")!"); + } + if (localInfo.hasTimedOut(config, TimeSync.getGlobalTime())) { + cell.addAction(ActionName.PROPOSER_RENEW_FAILED_LEASE_TO); + throw new FleaseException("cannot renew lease, lease already timed out! " + + (localInfo.getLeaseTimeout() - config.getDMax()) + + " < " + TimeSync.getGlobalTime()); + } + //make sure there is enough time before timeout + if (localInfo.getLeaseTimeout() - config.getDMax() + < TimeSync.getGlobalTime() + config.getRoundTimeout() * 2) { + cell.addAction(ActionName.PROPOSER_RENEW_FAILED_LEASE_NOT_ENOUGH_TIME); + throw new FleaseException("cannot renew lease, not enough time left for renew! " + + (localInfo.getLeaseTimeout() - config.getDMax()) + + " < " + + (TimeSync.getGlobalTime() + config.getRoundTimeout() * 2)); + } + + //no need for a new master epoch upon renew! + cell.setRequestMasteEpoch(false); + + //we can safely set the instance no +1 + //ONLY ALLOWED DURING RENEW! + + startPrepare(cell,config.getIdentity()); + } + + public void handoverLease(ASCIIString cellId, ASCIIString newOwner) throws FleaseException { + // TODO(bjko): Change to return lease. + FleaseProposerCell cell = cells.get(cellId); + if (cell == null) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Category.replication, + this, + "P ignore renew for closed/unknown cell %s", + cellId); + } + return; + } + cell.addAction(ActionName.PROPOSER_HANDOVER_LEASE); + //fixme + + //check local state + FleaseMessage localInfo = localAcceptor.getLocalLeaseInformation(cellId); + + if (localInfo == null) { + throw new FleaseException("cannot handover lease, no local lease information!"); + } + if (!localInfo.getLeaseHolder().equals(config.getIdentity())) { + throw new FleaseException("cannot handover lease, not lease owner (owner is " + + localInfo.getLeaseHolder() + ")!"); + } + //make sure there is enough time before timeout + if (localInfo.getLeaseTimeout() - config.getDMax() + < TimeSync.getGlobalTime() + config.getRoundTimeout() * 2) { + throw new FleaseException("cannot handover lease, not enough time left for renew! " + + (localInfo.getLeaseTimeout() - config.getDMax()) + + " < " + + (TimeSync.getGlobalTime() + config.getRoundTimeout() * 2)); + } + //we can safely set the instance no +1 + //ONLY ALLOWED DURING RENEW! + + cell.setHandoverTo(newOwner); + if (cell.getCellState() == State.IDLE) { + //set state to unknown + evListener.learnedEvent(localInfo.getCellId(), + null, + 0, + FleaseMessage.IGNORE_MASTER_EPOCH); + startPrepare(cell,newOwner); + } + } + + public void processMessage(FleaseMessage msg) throws Exception { + //get the cell + FleaseProposerCell cell = cells.get(msg.getCellId()); + if (cell == null) { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P drop message for unknown cellId %s from %s", + msg.getCellId(), + msg.getSender()); + } + return; + } + + try { + //reject anything if viewID < own viewID or if own viewId is -1 + //ignore if viewId > own viewID but notify listener + final int myViewId = cell.getViewId(); + if (myViewId == FleaseMessage.VIEW_ID_INVALIDATED) { + //just ignore things + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Category.replication, + this, + "P drop message because of INVALIDATED local view for cell %s", + cell.getCellId()); + } + return; + } + + if (myViewId > msg.getViewId()) { + //drop + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Category.replication, + this, + "P drop message because of outdated remote view for cell %s: " + + "local view %d, remote %d", + cell.getCellId(), + myViewId, + msg.getViewId()); + } + return; + } + + //events + switch (cell.getCellState()) { + case IDLE: { + if (msg.getMsgType() == FleaseMessage.MsgType.EVENT_RESTART) { + cell.addAction(ActionName.PROPOSER_RESTART_EVENT); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P restart event: %s", + msg.toString()); + } + startPrepare(cell,config.getIdentity()); + } else if (msg.getMsgType() == FleaseMessage.MsgType.EVENT_RENEW) { + cell.addAction(ActionName.PROPOSER_RENEW_EVENT); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P renew event: %s", + msg.toString()); + } + try { + renewLease(cell.getCellId()); + } catch (FleaseException ex) { + cell.addAction(ActionName.PROPOSER_INTERNAL_ERROR_CELL_RESET, + ex.toString()); + Logging.logMessage(Logging.LEVEL_ERROR, + this, + "P renew failed for cell %s: %s", + cell.getCellId(), + ex.toString()); + // Reset cell. + cell.setCellState(State.IDLE); + cell.setMessageSent(null); + cell.setBallotNo(new ProposalNumber(cell.getBallotNo().getProposalNo() + 1, + cell.getBallotNo().getSenderId())); + cell.getResponses().clear(); + cell.setNumFailures(0); + // Schedule restart. + final int wait_ms = (int) config.getDMax() + config.getMaxLeaseTimeout(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P cannot renew cell %s, scheduled restart in %d ms", + cell.getCellId(), wait_ms); + } + cell.addAction(ActionName.PROPOSER_SCHEDULED_RESTART); + FleaseMessage timer = new FleaseMessage(MsgType.EVENT_RESTART); + timer.setCellId(cell.getCellId()); + timer.setProposalNo(cell.getBallotNo()); + comm.requestTimer(timer, TimeSync.getLocalSystemTime() + wait_ms); + } + } else { + //ignore everything else + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P droped message in state IDLE: %s", + msg.toString()); + } + } + break; + } + case WAIT_FOR_PREP_ACK: { + processPrepareResponse(cell, msg); + break; + } + case WAIT_FOR_ACCEPT_ACK: { + processAcceptResponse(cell, msg); + break; + } + } + } catch (Throwable throwable) { + Logging.logMessage(Logging.LEVEL_ERROR, + Category.replication, + this, + "Exception in proposer: %s, cell %s", + throwable, + cell); + throw new Exception(throwable); + } + } + + protected void startPrepare(FleaseProposerCell cell, ASCIIString leaseHolder) { + cell.addAction(ActionName.PROPOSER_PREPARE_START); + assertState(cell.getCellState() == State.IDLE, cell); + + if (cell.getLastPrepareTimestamp_ms() + config.getMaxLeaseTimeout() + < TimeSync.getLocalSystemTime()) { + //timed out, set new ballot number + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Category.replication, + this, + "P reset cell id %s due to timeout", + cell.getCellId()); + } + cell.setBallotNo(new ProposalNumber(TimeSync.getGlobalTime(), config.getSenderId())); + cell.addAction(ActionName.PROPOSER_SET_BALLOT_NO, cell.getBallotNo().toString()); + } + + //propose myself + cell.getResponses().clear(); + cell.touch(); + + //assert (lastBallotNo < cell.getBallotNo().getProposalNo()) : ("lastBallotNo="+lastBallotNo+", cell="+cell.getBallotNo().getProposalNo()); + assertState(cell.getBallotNo() != null, cell); + assertState(cell.getBallotNo().getSenderId() == config.getSenderId(), cell); + + //lastBallotNo = cell.getBallotNo().getProposalNo(); + + final int numRemoteAcc = cell.getNumAcceptors(); + FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE); + msg.setCellId(cell.getCellId()); + msg.setProposalNo(cell.getBallotNo()); + msg.setLeaseHolder(leaseHolder); + msg.setLeaseTimeout(TimeSync.getGlobalTime() + config.getMaxLeaseTimeout()); + msg.setSendTimestamp(TimeSync.getGlobalTime()); + msg.setSender(null); + msg.setViewId(cell.getViewId()); + if (cell.isRequestMasteEpoch()) { + msg.setMasterEpochNumber(FleaseMessage.REQUEST_MASTER_EPOCH); + cell.addAction(ActionName.PROPOSER_REQUEST_MASTER_EPOCH); + } + cell.setMessageSent(msg); + + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.replication, this, + "P start PREPARE: %s", + msg.toString()); + } + + for (int i = 0; i < numRemoteAcc; i++) { + try { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.replication, this, + "P send prepare to: %s", + cell.getAcceptors().get(i)); + } + Thread.yield(); + comm.sendMessage(msg, cell.getAcceptors().get(i)); + } catch (IOException ex) { + //cancel(cell, ex, 0); + } + } + + FleaseMessage timer = new FleaseMessage(MsgType.EVENT_TIMEOUT_PREPARE); + timer.setCellId(cell.getCellId()); + timer.setProposalNo(cell.getBallotNo()); + timer.validateMessage(); + comm.requestTimer(timer, TimeSync.getLocalSystemTime() + config.getRoundTimeout()); + cell.addAction(ActionName.PROPOSER_SCHEDULED_TIMEOUT); + + assertState(cell.getMessageSent() != null, cell); + assertState(cell.getMessageSent().getProposalNo() != null, cell); + cell.setCellState(State.WAIT_FOR_PREP_ACK); + + final FleaseMessage localResponse = localAcceptor.handlePREPARE(msg); + if (localResponse != null) { + if (meHandler != null + && cell.isRequestMasteEpoch() + && localResponse.getMsgType() == FleaseMessage.MsgType.MSG_PREPARE_ACK) { + meHandler.sendMasterEpoch(localResponse, + new MasterEpochHandlerInterface.Continuation() { + @Override + public void processingFinished() { + localQueue.enqueueMessage(localResponse); + } + }); + } else { + processPrepareResponse(cell, localResponse); + } + } + + } + + protected void processPrepareResponse(FleaseProposerCell cell, FleaseMessage msg) { + cell.addAction(ActionName.PROPOSER_PREPARE_PROCESS_RESPONSE); + assertState(cell.getCellState() == State.WAIT_FOR_PREP_ACK, cell); + assertState(cell.getMessageSent() != null, cell); + + if (msg.getMsgType() != MsgType.MSG_PREPARE_ACK + && msg.getMsgType() != MsgType.MSG_PREPARE_NACK + && msg.getMsgType() != MsgType.MSG_WRONG_VIEW + && msg.getMsgType() != MsgType.EVENT_TIMEOUT_PREPARE) { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P ignore message (UNEXPECTED MESSAGE TYPE %s): %s", + msg.getMsgType(), + msg.toString()); + } + return; + } + + if (msg.getSendTimestamp() + config.getMessageTimeout() < TimeSync.getGlobalTime()) { + //drop outdated message + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P ignore message (too old): %s", + msg.toString()); + } + return; + } + + final long currentTime = TimeSync.getGlobalTime(); + if (msg.getSendTimestamp() > currentTime + config.getDMax()) { + cell.addAction(ActionName.PROPOSER_RECEIVED_OUT_OF_SYNC_MSG, + msg.getSendTimestamp() + + " > " + + currentTime + + "+" + + config.getDMax()); + //drop outdated message + Logging.logMessage(Logging.LEVEL_WARN, + Logging.Category.replication, + this, + "RECEIVED MESSAGE WITH TIMESTAMP TOO FAR IN THE FUTURE (likely cause: " + + "clocks aren't in sync). SYSTEM IS NOT IN A SAFE STATE. Msg TS %d > current Time %d + dMax %d. FleaseMessage Details: %s", + msg.getSendTimestamp(), + currentTime, + config.getDMax(), + msg.toString()); + cell.addAction(ActionName.PROPOSER_PREPARE_FAILED); + cancel(cell, + new FleaseException("System is not in sync (clock sync drift exceeded)!"), 0); + return; + } + + if (msg.before(cell.getMessageSent())) { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P ignore message (before my request): %s", + msg.toString()); + } + return; + } + + if (msg.getMsgType() == MsgType.EVENT_TIMEOUT_PREPARE) { + cell.addAction(ActionName.PROPOSER_PREPARE_TIMEOUT); + //not enough responses :( abort or re-try + cancel(cell, new FleaseException("did not receive enough responses for PREPARE"), 0); + return; + } + + final List responses = cell.getResponses(); + responses.add(msg); + if (cell.majorityAvail()) { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P majority responded for proposal %s: %d", + cell.getBallotNo(), + responses.size()); + } + //analyze responses + ProposalNumber maxBallot = ProposalNumber.EMPTY_PROPOSAL_NUMBER; + FleaseMessage prevAccepted = new FleaseMessage(MsgType.MSG_ACCEPT); + int maxViewId = 0; + for (FleaseMessage resp : responses) { + switch (resp.getMsgType()) { + + case MSG_WRONG_VIEW: { + if (resp.getViewId() > maxViewId) { + maxViewId = resp.getViewId(); + } + break; + } + + case MSG_PREPARE_ACK: { + //check for previously accepted proposals + if (!resp.getPrevProposalNo().isEmpty()) { + if (prevAccepted == null + || resp.getPrevProposalNo().after( + prevAccepted.getPrevProposalNo())) { + prevAccepted = resp; + } + } + break; + } + + case MSG_PREPARE_NACK: { + if (resp.getPrevProposalNo().after(maxBallot)) { + maxBallot = resp.getPrevProposalNo(); + } + break; + } + + } + } + + if (maxViewId > cell.getViewId()) { + cell.addAction(ActionName.PROPOSER_VIEW_OUTDATED, + maxViewId + "!=" + cell.getViewId()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P prepare failed due to outdated view local=%d max=%", + cell.getViewId(), + maxViewId); + } + viewListener.viewIdChangeEvent(cell.getCellId(), maxViewId); + cell.addAction(ActionName.PROPOSER_PREPARE_FAILED); + cancel(cell, new FleaseException("local viewId is outdated"), 0); + return; + } + + if (!maxBallot.isEmpty()) { + cell.addAction(ActionName.PROPOSER_PREPARE_OVERRULED); + cell.setBallotNo(new ProposalNumber( + maxBallot.getProposalNo() + (int) (Math.random() * 10) + 1, + cell.getBallotNo().getSenderId())); + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P prepare OVERRULED by %s, restart with ballot number: %s", + maxBallot.getProposalNo(), + cell.getBallotNo()); + } + //request a timer event for restart + cancel(cell, + new FleaseException("local proposal was overruled by remote proposal"), 0); + return; + } + + if (!prevAccepted.getProposalNo().isEmpty()) { + //change our values for accept + + //check prev accepted value + if (prevAccepted.hasNotTimedOut(config, TimeSync.getGlobalTime())) { + //we must use the previous value + //except for renew instances + if (prevAccepted.getLeaseHolder().equals(config.getIdentity())) { + //renew! + assertState( + cell.getMessageSent().getLeaseHolder().equals(config.getIdentity()) + || cell.isHandoverInProgress(), + cell); + assertState( + cell.getMessageSent().getLeaseTimeout() >= + prevAccepted.getLeaseTimeout(), + cell); + cell.addAction(ActionName.PROPOSER_PREPARE_IMPLICIT_RENEW); + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P prepare ACK processing with my proposal (renew): " + + "prev=%s/%d %s", + prevAccepted.getLeaseHolder(), + prevAccepted.getLeaseTimeout(), + prevAccepted.getPrevProposalNo()); + } + } else { + //use other value + cell.addAction(ActionName.PROPOSER_PREPARE_PRIOR_VALUE); + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P prepare ACK processing with prior proposal (still valid): " + + "prev=%s/%d %s", + prevAccepted.getLeaseHolder(), + prevAccepted.getLeaseTimeout(), + prevAccepted.getPrevProposalNo()); + } + cell.getMessageSent().setLeaseHolder(prevAccepted.getLeaseHolder()); + cell.getMessageSent().setLeaseTimeout(prevAccepted.getLeaseTimeout()); + } + } else { + if (prevAccepted.hasTimedOut(config, TimeSync.getGlobalTime())) { + cell.addAction(ActionName.PROPOSER_PREPARE_LEASE_TO); + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P prepare ACK processing with my proposal " + + "(old lease has timed out): prev=%s/%d %s", + prevAccepted.getLeaseHolder(), + prevAccepted.getLeaseTimeout(), + prevAccepted.getPrevProposalNo()); + } + } else { + //unknown state of the lease, must use prev value + cell.addAction(ActionName.PROPOSER_PREPARE_PRIOR_VALUE); + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P processing with prior proposal (old lease is in GP): " + + "%s/%d %s", + prevAccepted.getLeaseHolder(), + prevAccepted.getLeaseTimeout(), + prevAccepted.getPrevProposalNo()); + } + cell.getMessageSent().setLeaseHolder(prevAccepted.getLeaseHolder()); + cell.getMessageSent().setLeaseTimeout(prevAccepted.getLeaseTimeout()); + } + } + } else { + cell.addAction(ActionName.PROPOSER_PREPARE_EMPTY); + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P processing with no prior proposal"); + } + } + + //master epoch + if (cell.isRequestMasteEpoch()) { + long maxMasterEpoch = -1; + for (FleaseMessage resp : responses) { + if (resp.getMsgType() == FleaseMessage.MsgType.MSG_PREPARE_ACK) { + if (resp.getMasterEpochNumber() > maxMasterEpoch) { + maxMasterEpoch = resp.getMasterEpochNumber(); + } + } + } + assert(maxMasterEpoch > -1) : "no valid master epoch sent: "+maxMasterEpoch; + cell.setMasterEpochNumber(maxMasterEpoch+1); + cell.addAction(ActionName.PROPOSER_PREPARE_MAX_MASTER_EPOCH, + Long.toString(maxMasterEpoch)); + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P using masterEpoch %s", + maxMasterEpoch+1); + } + } + + responses.clear(); + + cell.addAction(ActionName.PROPOSER_PREPARE_SUCCESS); + startAccept(cell); + } + } + + public void startAccept(FleaseProposerCell cell) { + cell.addAction(ActionName.PROPOSER_ACCEPT_START); + cell.setCellState(State.WAIT_FOR_ACCEPT_ACK); + + final int numRemoteAcc = cell.getNumAcceptors(); + + FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.MSG_ACCEPT); + msg.setCellId(cell.getCellId()); + msg.setProposalNo(cell.getBallotNo()); + msg.setLeaseHolder(cell.getMessageSent().getLeaseHolder()); + msg.setLeaseTimeout(cell.getMessageSent().getLeaseTimeout()); + msg.setSendTimestamp(TimeSync.getGlobalTime()); + msg.setSender(null); + msg.setViewId(cell.getViewId()); + if (cell.isRequestMasteEpoch()) + msg.setMasterEpochNumber(cell.getMasterEpochNumber()); + cell.setMessageSent(msg); + + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.replication, this, + "P start ACCEPT: %s", + msg.toString()); + } + + for (int i = 0; i < numRemoteAcc; i++) { + try { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.replication, this, + "P send accept to: %s", + cell.getAcceptors().get(i)); + } + Thread.yield(); + comm.sendMessage(msg, cell.getAcceptors().get(i)); + } catch (IOException ex) { + //cancel(cell, ex, 0); + } + } + + cell.addAction(ActionName.PROPOSER_SCHEDULED_TIMEOUT); + FleaseMessage timer = new FleaseMessage(MsgType.EVENT_TIMEOUT_ACCEPT); + timer.setCellId(cell.getCellId()); + timer.setProposalNo(cell.getBallotNo()); + timer.validateMessage(); + comm.requestTimer(timer, TimeSync.getLocalSystemTime() + config.getRoundTimeout()); + + final FleaseMessage localResponse = localAcceptor.handleACCEPT(msg); + if (localResponse != null) { + if (meHandler != null + && cell.isRequestMasteEpoch() + && localResponse.getMsgType() == FleaseMessage.MsgType.MSG_ACCEPT_ACK) { + meHandler.storeMasterEpoch(localResponse, + new MasterEpochHandlerInterface.Continuation() { + @Override + public void processingFinished() { + localQueue.enqueueMessage(localResponse); + } + }); + } else { + processAcceptResponse(cell, localResponse); + } + } + + } + + protected void processAcceptResponse(FleaseProposerCell cell, FleaseMessage msg) { + cell.addAction(ActionName.PROPOSER_ACCEPT_PROCESS_RESPONSE); + assertState(cell.getCellState() == State.WAIT_FOR_ACCEPT_ACK, cell); + assertState(cell.getMessageSent() != null, cell); + + if (msg.getSendTimestamp() + config.getMessageTimeout() < TimeSync.getGlobalTime()) { + //drop outdated message + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P ignore message (too old): %s", + msg.toString()); + } + return; + } + + if (msg.getSendTimestamp() > TimeSync.getGlobalTime() + config.getDMax()) { + //drop outdated message + cell.addAction(ActionName.PROPOSER_RECEIVED_OUT_OF_SYNC_MSG, + msg.getSendTimestamp() + + " > " + + TimeSync.getGlobalTime() + + "+" + + config.getDMax()); + Logging.logMessage(Logging.LEVEL_WARN, + Logging.Category.replication, + this, + "RECEIVED MESSAGE WITH TIMESTAMP TOO FAR IN THE FUTURE " + + "(likely cause: clocks aren't in sync). " + + "SYSTEM IS NOT IN A SAFE STATE: %s", + msg.toString()); + cell.addAction(ActionName.PROPOSER_ACCEPT_FAILED); + cancel(cell, + new FleaseException("System is not in sync (clock sync drift exceeded)!"), 0); + return; + } + + if (msg.getMsgType() != MsgType.MSG_ACCEPT_ACK + && msg.getMsgType() != MsgType.MSG_ACCEPT_NACK + && msg.getMsgType() != MsgType.MSG_WRONG_VIEW + && msg.getMsgType() != MsgType.EVENT_TIMEOUT_ACCEPT) { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P ignore message (unexpected message type): %s", + msg.toString()); + } + return; + } + + if (msg.before(cell.getMessageSent())) { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P ignore message (before my request): %s", + msg.toString()); + } + return; + } + + if (msg.getMsgType() == MsgType.EVENT_TIMEOUT_ACCEPT) { + //not enough responses :( abort or re-try + cell.addAction(ActionName.PROPOSER_ACCEPT_TIMEOUT); + cancel(cell, new FleaseException("did not receive enough responses for ACCEPT"), 0); + return; + } + + final List responses = cell.getResponses(); + responses.add(msg); + if (cell.majorityAvail()) { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P majority responded for proposal %s: %d", + cell.getBallotNo(), responses.size()); + } + //analyze responses + int maxViewId = 0; + ProposalNumber maxBallot = ProposalNumber.EMPTY_PROPOSAL_NUMBER; + for (FleaseMessage resp : responses) { + if (resp.getViewId() > maxViewId) { + maxViewId = resp.getViewId(); + } else if (resp.getMsgType() == MsgType.MSG_ACCEPT_NACK) { + maxBallot = resp.getPrevProposalNo(); + } + } + + if (maxViewId > cell.getViewId()) { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P accept failed due to outdated view local=%d max=%", + cell.getViewId(), + maxViewId); + } + viewListener.viewIdChangeEvent(cell.getCellId(), maxViewId); + cancel(cell, new FleaseException("local viewId is outdated"), 0); + return; + } + + //take action + if (!maxBallot.isEmpty()) { + cell.addAction(ActionName.PROPOSER_ACCEPT_OVERRULED); + cell.setBallotNo(new ProposalNumber( + maxBallot.getProposalNo() + (int) (Math.random() * 10) + 1, + cell.getBallotNo().getSenderId())); + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P accept OVERRULED by %s, restart with ballot number: %s", + maxBallot.getProposalNo(), cell.getBallotNo()); + } + //request a timer event for restart + cancel(cell, + new FleaseException("proposal was overruled by remote proposal " + +"during ACCEPT"), + 0); + return; + } + + responses.clear(); + + cell.addAction(ActionName.PROPOSER_ACCEPT_SUCCESS); + learn(cell); + } + } + + public void learn(FleaseProposerCell cell) { + cell.addAction(ActionName.PROPOSER_LEARN_START); + cell.setCellState(State.IDLE); + + final int numRemoteAcc = cell.getNumAcceptors(); + FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.MSG_LEARN); + msg.setCellId(cell.getCellId()); + msg.setProposalNo(cell.getBallotNo()); + msg.setLeaseHolder(cell.getMessageSent().getLeaseHolder()); + msg.setLeaseTimeout(cell.getMessageSent().getLeaseTimeout()); + msg.setSendTimestamp(TimeSync.getGlobalTime()); + msg.setSender(null); + msg.setViewId(cell.getViewId()); + if (cell.isRequestMasteEpoch()) { + assertState(cell.getMasterEpochNumber() > -1, cell); + msg.setMasterEpochNumber(cell.getMasterEpochNumber()); + } + cell.setMessageSent(msg); + + + //check the result... + //if the lease is already outdated, we can immediately retry + //if thg lease is in the grace period, we have to trigger a timer + + if (msg.hasTimedOut(config, TimeSync.getGlobalTime())) { + //timed out + //retry + cell.addAction(ActionName.PROPOSER_LEARN_TIMED_OUT); + cell.setBallotNo(new ProposalNumber( + cell.getBallotNo().getProposalNo() + 1, + cell.getBallotNo().getSenderId())); + + startPrepare(cell,cell.getMessageSent().getLeaseHolder()); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.replication, this, + "P finished round, lease has timed out, restart prepare: %s", + msg.toString()); + } + + } else if (msg.hasNotTimedOut(config, TimeSync.getGlobalTime())) { + //lease is valid, do learn step + + cell.setBallotNo(new ProposalNumber( + cell.getBallotNo().getProposalNo() + 1, + cell.getBallotNo().getSenderId())); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P finished round, lease is valid: %s", + msg.toString()); + } + + //only here does a learn make sense + if (config.isSendLearnMessages()) { + if (Logging.isDebug() && config.isDebugPrintMessages()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P start LEARN: %s", + msg.toString()); + } + + for (int i = 0; i < numRemoteAcc; i++) { + try { + comm.sendMessage(msg, cell.getAcceptors().get(i)); + } catch (IOException ex) { + //ignore them here + } + } + } + + //FIXME: local message + //msgs[numRemoteAcc] = new FleaseMessage(msg); + //msgs[numRemoteAcc].setSender(null); + localAcceptor.handleLEARN(msg); + + if (!FleaseStage.DISABLE_RENEW_FOR_TESTING + && cell.getMessageSent().getLeaseHolder().equals(config.getIdentity())) { + //renew after half of the time + //FIXE: could be relaxed + final long renewTime = + cell.getMessageSent().getLeaseTimeout() - config.getRoundTimeout() * 4; + if (TimeSync.getGlobalTime() < renewTime) { + cell.addAction(ActionName.PROPOSER_SCHEDULED_RENEW); + final FleaseMessage timer = new FleaseMessage(MsgType.EVENT_RENEW); + timer.setCellId(cell.getCellId()); + timer.setProposalNo(cell.getBallotNo()); + + comm.requestTimer(timer, globalToLocalTime(renewTime)); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "scheduled renew for %s at %d", + cell.getCellId(), + globalToLocalTime(renewTime)); + } + } else { + cell.addAction(ActionName.PROPOSER_LEARN_TIMED_OUT); + cell.addAction(ActionName.PROPOSER_SCHEDULED_RESTART); + final int wait_ms = (int) + (msg.getLeaseTimeout() - TimeSync.getGlobalTime() + config.getDMax()); + Logging.logMessage(Logging.LEVEL_WARN, + Logging.Category.replication, + this, + "too late to schedule renew for cell %s, restart in %d ms " + + "(now=%d, renew=%d)", + cell.getCellId(), + wait_ms, + TimeSync.getGlobalTime(), + renewTime); + //schedule a retry instead + cancel(cell, + new FleaseException("too late for renew, re-start after lease " + + "has timed out in " + + wait_ms + + "ms"), + wait_ms); + } + } + + } else { + //grace period + cell.addAction(ActionName.PROPOSER_LEARN_LEASE_IN_GRACE_PERIOD); + cell.addAction(ActionName.PROPOSER_SCHEDULED_RESTART); + final int wait_ms = (int) + (msg.getLeaseTimeout() - TimeSync.getGlobalTime() + config.getDMax()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Logging.Category.replication, + this, + "P finished round, lease is in grace period, " + + "scheduled restart in %d ms: %s", + wait_ms, + msg.toString()); + } + cancel(cell, new FleaseException("current lease not yet timed out"), wait_ms); + } + } + + public long globalToLocalTime(long globalTime) { + return globalTime-TimeSync.getInstance().getDrift(); + } + + public void cancel(FleaseProposerCell cell, Throwable reason, long retryAfter_ms) { + cell.addAction(ActionName.PROPOSER_CANCELLED); + int numFailures = cell.getNumFailures() + 1; + cell.setNumFailures(numFailures); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + Category.replication, + this, + "P proposal failed for cell %s: %s", + cell.getCellId(), + reason); + } + cell.setCellState(State.IDLE); + cell.setMessageSent(null); + cell.setBallotNo(new ProposalNumber( + cell.getBallotNo().getProposalNo() + 1, + cell.getBallotNo().getSenderId())); + cell.getResponses().clear(); + + if (numFailures > config.getMaxRetries()) { + cell.addAction(ActionName.PROPOSER_CANCEL_LEASE_FAILED); + FleaseException error; + try { + error = (FleaseException) reason; + error.addFleaseCellDebugString(cell.toString()); + } catch (ClassCastException ex) { + error = new FleaseException("internal flease error", reason); + } + leaseListener.leaseFailed(cell.getCellId(), error); + //full lease timeout wait here... + cell.setNumFailures(0); + + cell.addAction(ActionName.PROPOSER_SCHEDULED_RESTART); + FleaseMessage timer = new FleaseMessage(MsgType.EVENT_RESTART); + timer.setCellId(cell.getCellId()); + timer.setProposalNo(cell.getBallotNo()); + + comm.requestTimer(timer, TimeSync.getLocalSystemTime() + config.getMaxLeaseTimeout()); + + } else { + cell.addAction(ActionName.PROPOSER_SCHEDULED_RESTART); + FleaseMessage timer = new FleaseMessage(MsgType.EVENT_RESTART); + final int retryTmp = (int) + (retryAfter_ms > 0 ? retryAfter_ms : 50 + (int) (Math.random() * 100)); + timer.setCellId(cell.getCellId()); + timer.setProposalNo(cell.getBallotNo()); + + comm.requestTimer(timer, TimeSync.getLocalSystemTime() + retryTmp); + + } + } + + private void assertState(boolean assertion, FleaseProposerCell cell) { + if (assertion == false) { + Logging.logMessage(Logging.LEVEL_ERROR, + Logging.Category.replication, + this, + "Invalid state detected. State: %s", + cell); + throw new AssertionError("Invalid state in cell " + + (cell != null ? cell.getCellId() : "NULL")); + } + } +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseProposerCell.java b/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseProposerCell.java new file mode 100644 index 0000000..a9bf54e --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/proposer/FleaseProposerCell.java @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.foundation.flease.proposer; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.Flease; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.flease.comm.ProposalNumber; +import org.xtreemfs.foundation.flease.proposer.CellAction.ActionName; +import org.xtreemfs.foundation.flease.proposer.CellAction.CellActionList; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * + * @author bjko + */ +public class FleaseProposerCell { + + /** + * @return the responses + */ + public List getResponses() { + return responses; + } + + /** + * @return the messageSent + */ + public FleaseMessage getMessageSent() { + return messageSent; + } + + /** + * @param messageSent the messageSent to set + */ + public void setMessageSent(FleaseMessage messageSent) { + this.messageSent = messageSent; + } + + /** + * @return the lastPrepateTimestamp_ms + */ + public long getLastPrepareTimestamp_ms() { + return lastPrepateTimestamp_ms; + } + + public void setViewId(int viewId) { + this.viewId = viewId; + } + + public int getViewId() { + return this.viewId; + } + + public boolean isHandoverInProgress() { + return handoverTo != null; + } + + /** + * @return the prevLease + */ + public Flease getPrevLease() { + return prevLease; + } + + /** + * @param prevLease the prevLease to set + */ + public void setPrevLease(Flease prevLease) { + this.prevLease = prevLease; + } + + /** + * @return the markedClose + */ + public boolean isMarkedClose() { + return markedClose; + } + + /** + * @param markedClose the markedClose to set + */ + public void setMarkedClose(boolean markedClose) { + this.markedClose = markedClose; + } + + /** + * @return the requestMasteEpoch + */ + public boolean isRequestMasteEpoch() { + return requestMasteEpoch; + } + + /** + * @param requestMasteEpoch the requestMasteEpoch to set + */ + public void setRequestMasteEpoch(boolean requestMasteEpoch) { + this.requestMasteEpoch = requestMasteEpoch; + } + + /** + * @return the masterEpochNumber + */ + public long getMasterEpochNumber() { + return masterEpochNumber; + } + + /** + * @param masterEpochNumber the masterEpochNumber to set + */ + public void setMasterEpochNumber(long masterEpochNumber) { + this.masterEpochNumber = masterEpochNumber; + } + + public static enum State { + IDLE, + WAIT_FOR_PREP_ACK, + WAIT_FOR_ACCEPT_ACK, + }; + + private final ASCIIString cellId; + + private ProposalNumber ballotNo; + + private List acceptors; + + private final List listeners; + + private final List responses; + + private State cellState; + + private int numFailures; + + private final int majority; + + private long lastPrepateTimestamp_ms; + + private int viewId; + + private Flease prevLease; + + private boolean markedClose; + + private ASCIIString handoverTo; + + private boolean requestMasteEpoch; + + private long masterEpochNumber; + + private final CellActionList actions; + + /** + * the value to use for prepare, accept and learn + * might be != than the local host, if the proposer + * must use a previously accepted value + */ + private FleaseMessage messageSent; + + FleaseProposerCell(ASCIIString cellId, List acceptors, long senderId) { + this.actions = new CellActionList(); + this.cellId = cellId; + this.acceptors = acceptors; + this.responses = new ArrayList(acceptors.size()+1); + this.listeners = new ArrayList(5); + this.ballotNo = new ProposalNumber(TimeSync.getGlobalTime(),senderId); + this.majority = (int) Math.floor((acceptors.size()+1.0)/ 2.0) + 1; + this.prevLease = Flease.EMPTY_LEASE; + this.markedClose = false; + this.handoverTo = null; + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"opened new cell id %s with majority = %d ",cellId,majority); + } + } + + public void addAction(ActionName actionName) { + actions.addAction(actionName); + } + + public void addAction(ActionName actionName, String message) { + actions.addAction(actionName, message); + } + + public boolean majorityAvail() { + return responses.size() >= this.majority; + } + + /** + * @return the cellId + */ + public ASCIIString getCellId() { + return cellId; + } + + /** + * @return the ballotNo + */ + public ProposalNumber getBallotNo() { + return ballotNo; + } + + /** + * @param ballotNo the ballotNo to set + */ + public void setBallotNo(ProposalNumber ballotNo) { + this.ballotNo = ballotNo; + } + + /** + * @return the acceptors + */ + public List getAcceptors() { + return acceptors; + } + + /** + * @param acceptors the acceptors to set + */ + public void setAcceptors(List acceptors) { + this.acceptors = acceptors; + } + + /** + * @return the cellState + */ + public State getCellState() { + return cellState; + } + + /** + * @param cellState the cellState to set + */ + public void setCellState(State cellState) { + this.cellState = cellState; + } + + /** + * @return the listeners + */ + public List getListeners() { + return listeners; + } + + public int getNumAcceptors() { + return acceptors.size(); + } + + /** + * @return the numFailures + */ + public int getNumFailures() { + return numFailures; + } + + /** + * @param numFailures the numFailures to set + */ + public void setNumFailures(int numFailures) { + this.numFailures = numFailures; + } + + public void touch() { + this.lastPrepateTimestamp_ms = TimeSync.getLocalSystemTime(); + } + + /** + * @return the handoverTo + */ + public ASCIIString getHandoverTo() { + return handoverTo; + } + + /** + * @param handoverTo the handoverTo to set + */ + public void setHandoverTo(ASCIIString handoverTo) { + this.handoverTo = handoverTo; + } + + @Override + public String toString() { + StringBuilder text = new StringBuilder(); + text.append(getClass().getSimpleName()); + text.append(":{"); + text.append(" cellId:"); + text.append(cellId); + text.append(" ballotNo:"); + text.append(ballotNo); + text.append(" numAcceptors:"); + text.append(acceptors != null ? acceptors.size() : "null"); + text.append(" numResponses:"); + text.append(responses != null ? responses.size() : "null"); + text.append(" cellState:"); + text.append(cellState); + text.append(" numFail:"); + text.append(numFailures); + text.append(" majority:"); + text.append(majority); + text.append(" lastPTSP:"); + text.append(lastPrepateTimestamp_ms); + text.append(" viewId:"); + text.append(viewId); + text.append(" prevL:"); + text.append(prevLease != null ? prevLease : "none"); + text.append(" markedClose:"); + text.append(markedClose); + text.append(" rqME:"); + text.append(requestMasteEpoch); + text.append(" msgSent:"); + text.append(messageSent); + text.append(" responses:"); + for (FleaseMessage r : responses) { + text.append(r); + text.append(","); + } + text.append(" actions:"); + text.append(actions); + text.append("}"); + return text.toString(); + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/sim/Communicator.java b/java/flease/src/org/xtreemfs/foundation/flease/sim/Communicator.java new file mode 100644 index 0000000..917e891 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/sim/Communicator.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease.sim; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.flease.FleaseStage; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.logging.Logging; + +/** + * A tool to simulate package loss, temporary host disconnects and message delay. + * @author bjko + */ +public class Communicator extends LifeCycleThread { + + /** + * the connected UDPSimSockets + */ + protected final Map ports; + + /** + * sockets which are currently blocked (i.e. simulated network outage) + */ + protected final Map blockedPorts; + + /** + * the packet loss in percent (0..100) + */ + private int pkgLossPct; + + /** + * if true the thread will quit operation + */ + private boolean quit; + + /** + * debug output is generated if set to true + */ + private boolean debug; + + /** + * queue with packets to be delivered to sockets + */ + private final LinkedBlockingQueue sendQ; + + /** + * singleton + */ + private static volatile Communicator theInstance; + + + /** + * thread for delayed delivery and blocking ports + */ + private DelayedDelivery dd; + private int minDelay; + private int maxDelay; + + /** + * percent of packets to be delayed + */ + private int pctDelay; + + /** + * if set to true, ports are blocked unsymmetric (i.e. receive but cannot send) + */ + private boolean halfLink; + + /** + * Creates a new instance of UDPSim + * @param pkgLossPct packet loss in percent + * @param minDelay minimum delay of a delayed packet + * @param maxDelay maximum delay of a delayed packet + * @param pctDelay percentage of packets to be delayed + * @param halfLink if set to true, ports are blocked unsymmetric (i.e. receive but cannot send) + * @param pHostUnavail probability (0..1) that a host becomes unavailable + * @param pHostRecovery probability that a host is recovered. This value is multiplied by the + * number of rounds that the host is already unavailable. + * @param debug if set to true extensive debug output is generated + */ + public Communicator(int pkgLossPct, int minDelay, int maxDelay, int pctDelay, + boolean halfLink, double pHostUnavail, double pHostRecovery, + boolean debug) { + + super("UDP-Sim"); + + this.ports = new ConcurrentHashMap(); + this.blockedPorts = new ConcurrentHashMap(); + this.pkgLossPct = pkgLossPct; + this.quit = false; + this.debug = debug; + this.sendQ = new LinkedBlockingQueue(); + this.dd = new DelayedDelivery(sendQ,blockedPorts,ports, + pHostUnavail,pHostRecovery, + debug); + dd.start(); + this.minDelay = minDelay; + this.maxDelay = maxDelay; + this.pctDelay = pctDelay; + + this.halfLink = halfLink; + + + theInstance = this; + + } + + /** + * opens a port and delivers messages into the queue + * @param port port number to open + * @param q the queue to receive messages + * @return true if the port was opened succesfully, false if the port is already in use + */ + public boolean openPort(int port, FleaseStage stage) { + if (ports.get(port) != null) + return false; + + ports.put(port,stage); + return true; + } + + /** + * Opens a free port + * @param q the queue to receive messages + * @return treu if successful, false if there is no free port available + */ + public int openPort(FleaseStage stage) { + int tries = 0; + while (tries < 5) { + int rport = (int)(Math.random()*65000.0)+1; + if (ports.get(rport) == null) { + ports.put(rport,stage); + return rport; + } + tries++; + } + return -1; + } + + /** + * closes the port + * @param port port number to close + */ + public void closePort(int port) { + ports.remove(port); + } + + /** + * sends a datagram packet from + * @param port sending port number + * @param dp packet to send + */ + public synchronized void send(int port, FleaseMessage msg) { + Packet p = new Packet(msg,port); + sendQ.add(p); + } + + /** + * main loop + */ + public void run() { + try { + InetAddress ia = InetAddress.getLocalHost(); + + notifyStarted(); + while (!quit) { + try { + Packet p = sendQ.take(); + + FleaseStage rec = ports.get(p.recipientPort); + + if (rec == null) + continue; + + if (blockedPorts.containsKey(p.msg.getSender().getPort())) { + if (debug) + Logging.logMessage(Logging.LEVEL_DEBUG,this,"msg dropped, port blocked "+p.msg.getSender().getPort()); + continue; + } + + if (blockedPorts.containsKey(p.recipientPort)) { + if (debug) + Logging.logMessage(Logging.LEVEL_DEBUG,this,"msg dropped, port blocked "+p.recipientPort); + continue; + } + + if (!dropPacket() || p.requeued) { + + int delay = delayPacket(); + if ((delay > 0) && !p.requeued) { + if (debug) + Logging.logMessage(Logging.LEVEL_DEBUG,this,"msg delayed "+delay+"ms "+p.recipientPort+" -> "+p.msg.getSender().getPort()); + dd.add(p,delay); + } else { + + //p.msg.setSender(new InetSocketAddress(ia, p.recipientPort)); + try { + rec.receiveMessage(p.msg); + } catch (IllegalStateException e) { + //just drop it + } + } + } else { + if (debug) + Logging.logMessage(Logging.LEVEL_DEBUG,this,"msg lost "+p.recipientPort+" -> "+p.msg.getSender().getPort()); + } + + + + } catch (InterruptedException ex) { + Logging.logError(Logging.LEVEL_ERROR,this,ex); + } + } + + } catch (UnknownHostException ex) { + Logging.logError(Logging.LEVEL_ERROR,this,ex); + } + + notifyStopped(); + } + + /** + * decides if a message should be dropped. + * @return true, if the packet is to be dropped + */ + private boolean dropPacket() { + int rv = (int)(Math.random()*100.0); + return (rv < this.pkgLossPct); + } + + + + /** + * singleton + * @return null, if not initialized, the instance otherwise + */ + public static Communicator getInstance() { + return theInstance; + } + + /** + * kills the thread and the delayed delivery thread + */ + public void shutdown() { + + try { + this.quit = true; + this.interrupt(); + dd.shutdown(); + + dd.waitForShutdown(); + waitForShutdown(); + } catch (Exception exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + } + } + + /** + * decides if and how long a packet is delayed + * @return delay in ms + */ + private int delayPacket() { + if (pctDelay == 0) + return 0; + int rv = (int)(Math.random()*100.0); + if (rv < this.pctDelay) { + return (int)(Math.random()*((double)maxDelay-minDelay))+minDelay; + } else { + return 0; + } + } + + /** + * Packet information + */ + protected static class Packet { + /** + * the datagram that is being sent + */ + public FleaseMessage msg; + /** + * originating prot number + */ + public int recipientPort; + /** + * set to true if it was requeued after delay (i.e. must not be dropped, delayed...) + */ + public boolean requeued; + /** + * creates a new packet + * @param dp datagram packet + * @param port originating port + */ + public Packet(FleaseMessage msg, int port) { + this.msg = msg; + this.recipientPort = port; + this.requeued = false; + } + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/sim/DelayedDelivery.java b/java/flease/src/org/xtreemfs/foundation/flease/sim/DelayedDelivery.java new file mode 100644 index 0000000..259b2d0 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/sim/DelayedDelivery.java @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease.sim; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.concurrent.LinkedBlockingQueue; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.flease.FleaseStage; +import org.xtreemfs.foundation.logging.Logging; + +/** + * Thread to deliver delayed packets and to set availability status of hosts. + * @author bjko + */ +public class DelayedDelivery extends LifeCycleThread { + + /** + * queued packets for delayed delivery + */ + private final LinkedList packets; + + /** + * sending queue + */ + private final LinkedBlockingQueue targetQ; + + /** + * minimum delay in ms + */ + private int minDelay; + + /** + * maximum delay in ms + */ + private int maxDelay; + + /** + * if set to true the thread shuts down + */ + private boolean quit; + + /** + * time to wait between two invocations in ms + */ + private static final int WAIT_TIME = 50; + + /** + * list of blocked ports (unavailable hosts) + */ + private final Map blockedPorts; + + /** + * all ports + */ + private final Map ports; + + /** + * probability of unavailable host + */ + private double pHostUnavail; + + /** + * probability of host recovery + */ + private double pHostRecovery; + + /** + * number of rounds (i.e. WAIT_TIME) to wait between checks for host availability + */ + private final static int HOSTWAIT_MULTIPLIER = 10; + + /** + * if set to true debug output is generated + */ + private boolean debug; + + /** + * Creates a new instance of UDPDelayedDelivery + * @param targetQ queue to use for delivering delayed packets + * @param blockedPorts list of blocked ports (unavail hosts) + * @param ports list of all hosts + * @param pHostUnavail probability of unavailable host + * @param pHostRecovery probability of host recovery + * @param debug if set to true debug output is generated + */ + public DelayedDelivery(LinkedBlockingQueue targetQ, + Map blockedPorts, + Map ports, + double pHostUnavail, double pHostRecovery, boolean debug) { + + super("UDP-Delivery"); + + this.packets = new LinkedList(); + this.targetQ = targetQ; + /*this.minDelay = minDelay; + this.maxDelay = maxDelay;*/ + + this.pHostUnavail = pHostUnavail; + this.pHostRecovery = pHostRecovery; + + this.blockedPorts = blockedPorts; + this.ports = ports; + + this.quit = false; + this.debug = debug; + } + + /** + * adds a packet for delyed delivery + * @param p packet to send + * @param delay delay in ms + */ + public void add(Communicator.Packet p, int delay) { + synchronized (packets) { + DelayPacket dp = new DelayPacket(); + dp.packet = p; + dp.waited = 0; + dp.delay = delay; + packets.add(dp); + } + } + + /** + * main loop + */ + public void run() { + + notifyStarted(); + + int hostwait = 0; + while (!quit) { + synchronized (packets) { + Iterator iter = packets.iterator(); + while (iter.hasNext()) { + DelayPacket dp = iter.next(); + try { + dp.waited += WAIT_TIME; + if (dp.waited >= dp.delay) { + dp.packet.requeued = true; + iter.remove(); + targetQ.add(dp.packet); + } + } catch (IllegalStateException ex) { + } + } + } + //check only every 10*WAIT_TIME + hostwait++; + if (hostwait == HOSTWAIT_MULTIPLIER) { + + //check if hosts should become available again... + Iterator iter = blockedPorts.keySet().iterator(); + while (iter.hasNext()) { + int portNo = iter.next(); + int round = blockedPorts.get(portNo); + if (Math.random() < this.pHostRecovery*round) { + + iter.remove(); + if (debug) + Logging.logMessage(Logging.LEVEL_DEBUG,this,"unblocked "+portNo); + } else { + blockedPorts.put(portNo,round+1); + } + } + + //make hosts unavailable + if (blockedPorts.size() < ports.size()) { + if (Math.random() < this.pHostUnavail) { + //get a random host to make unavailable + Integer[] keys = ports.keySet().toArray(new Integer[0]); + int rand = (int)(Math.random()*(double)(keys.length)); + blockedPorts.put(keys[rand],1); + if (debug) + Logging.logMessage(Logging.LEVEL_DEBUG,this,"blocked "+keys[rand]); + } + } + + hostwait = 0; + + } + + synchronized (this) { + try { + this.wait(WAIT_TIME); + } catch (InterruptedException ex) { + } + } + + } + + notifyStopped(); + } + + /** + * shuts down the thread + */ + public void shutdown() { + this.quit = true; + this.interrupt(); + } + + /** + * information on packet to be delayed + */ + protected static class DelayPacket { + /** + * packet to send + */ + Communicator.Packet packet; + int delay; + /** + * time already waited + */ + int waited; + } + +} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/sim/FleaseMultiSim.java b/java/flease/src/org/xtreemfs/foundation/flease/sim/FleaseMultiSim.java new file mode 100644 index 0000000..1e26a08 --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/sim/FleaseMultiSim.java @@ -0,0 +1,231 @@ +///* +// * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin +// * +// * Licensed under the BSD License, see LICENSE file for details. +// * +// */ +// +//package org.xtreemfs.foundation.flease.sim; +// +//import java.net.InetSocketAddress; +//import java.util.ArrayList; +//import java.util.Iterator; +//import java.util.List; +//import java.util.Map; +//import java.util.concurrent.Semaphore; +//import java.util.concurrent.TimeUnit; +//import org.xtreemfs.common.TimeSync; +//import org.xtreemfs.common.buffer.ASCIIString; +//import org.xtreemfs.common.logging.Logging; +//import org.xtreemfs.common.logging.Logging.Category; +//import org.xtreemfs.foundation.LifeCycleListener; +//import org.xtreemfs.foundation.flease.FleaseConfig; +//import org.xtreemfs.foundation.flease.FleaseMessageSenderInterface; +//import org.xtreemfs.foundation.flease.FleaseStage; +//import org.xtreemfs.foundation.flease.FleaseViewChangeListenerInterface; +//import org.xtreemfs.foundation.flease.comm.FleaseMessage; +//import org.xtreemfs.foundation.flease.proposer.FleaseListener; +// +///** +// * Simulator for testing +// * @author bjko +// */ +//public class FleaseMultiSim { +// +// //private void +// +// /** +// * @param args the command line arguments +// */ +// public static void main(String[] args) { +// try { +// +// final boolean DEBUG_COMM_MSGS = false; +// +// final int dmax = 500; +// final int leaseTimeout = 10000; +// +// final int numHosts = 10; +// final int numConcurrentProposers = 10; +// final FleaseStage[] stages = new FleaseStage[numHosts]; +// +// Logging.start(Logging.LEVEL_DEBUG, Category.all); +// TimeSync.initializeLocal(10000, 50); +// +// final Communicator com = new Communicator(10, 10, 2000, 5, true, 0.05, 0.05, DEBUG_COMM_MSGS); +// com.start(); +// +// List allPorts = new ArrayList(numHosts); +// List[] acceptors = new List[numHosts]; +// +// for (int i = 0; i < numHosts; i++) { +// final int portNo = 1024+i; +// FleaseConfig cfg = new FleaseConfig(leaseTimeout, dmax, 500, new InetSocketAddress(portNo), "localhost:"+(1024+i),5); +// stages[i] = new FleaseStage(cfg, "/tmp/xtreemfs-test", new FleaseMessageSenderInterface() { +// +// public void sendMessage(FleaseMessage message, InetSocketAddress recipient) { +// assert(message != null); +// if (DEBUG_COMM_MSGS) +// Logging.logMessage(Logging.LEVEL_DEBUG, this,"received message for delivery to port %d: %s",recipient.getPort(),message.toString()); +// message.setSender(new InetSocketAddress("localhost", portNo)); +// com.send(recipient.getPort(), message); +// } +// }, true, new FleaseViewChangeListenerInterface() { +// +// public void viewIdChangeEvent(ASCIIString cellId, int viewId) { +// //ignore +// } +// },null); +// stages[i].setLifeCycleListener(new LifeCycleListener() { +// +// public void startupPerformed() { +// } +// +// public void shutdownPerformed() { +// } +// +// public void crashPerformed(Throwable cause) { +// cause.printStackTrace(); +// System.exit(100); +// } +// }); +// stages[i].start(); +// allPorts.add(new InetSocketAddress("localhost", 1024+i)); +// com.openPort(1024+i, stages[i]); +// } +// +// for (int i = 0; i < numHosts; i++) { +// final int portNo = 1024+i; +// acceptors[i] = new ArrayList(numHosts-1); +// for (InetSocketAddress ia : allPorts) { +// if (ia.getPort() != portNo) +// acceptors[i].add(ia); +// } +// stages[i].openCell(new ASCIIString("testcell"), acceptors[i],true); +// } +// +// //do something +// +// do { +// final List results = new ArrayList(numHosts); +// final Semaphore s = new Semaphore(0); +// +// +// final List hostNumbers = new ArrayList(numHosts); +// for (int i = 0; i < numHosts; i++) +// hostNumbers.add(i); +// +// while (hostNumbers.size()+numConcurrentProposers > numHosts) { +// final int tmp = (int)(Math.random()*hostNumbers.size()); +// final int host = hostNumbers.remove((int)tmp); +// stages[host].getLease(new ASCIIString("testcell"), new FleaseListener() { +// +// public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms) { +// final ASCIIString id = stages[host].getIdentity(); +// synchronized (results) { +// LInfo i = new LInfo(); +// i.host = id; +// i.owner = leaseHolder; +// i.to = leaseTimeout_ms; +// results.add(i); +// } +// s.release(); +// System.out.println("host: "+id+". lease result: "+leaseHolder+"/"+leaseTimeout_ms); +// } +// +// public void proposalFailed(ASCIIString cellId, Throwable cause) { +// final ASCIIString id = stages[host].getIdentity(); +// System.out.println("host: "+id+". lease failed: "+cause); +// s.release(); +// } +// }); +// } +// System.out.println("all started"); +// +// if (!s.tryAcquire(numConcurrentProposers, 30000, TimeUnit.MILLISECONDS)) { +// throw new RuntimeException("timed out waiting for semaphore"); +// } +// +// System.out.println("all results available"); +// final long now = TimeSync.getGlobalTime(); +// +// //first: remove all leases which are timed out +// Iterator iter = results.iterator(); +// while (iter.hasNext()) { +// LInfo i = iter.next(); +// if (i.to+dmax < now) { +// iter.remove(); +// } +// } +// +// //now check all the values +// ASCIIString owner = null; +// LInfo other = null; +// boolean violated = false; +// for (LInfo i : results) { +// if (owner == null) { +// owner = i.owner; +// other = i; +// } else { +// if (!owner.equals(i.owner)) { +// com.shutdown(); +// Map traces = Thread.getAllStackTraces(); +// System.out.println("INVARIANT VIOLATED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); +// System.out.println("\n\n"); +// System.out.println(i.host+" has : "+i.owner+"/"+i.to); +// System.out.println(other.host+" has : "+other.owner+"/"+other.to); +// +// for (int j = 0; j < numHosts; j++) { +// System.out.println(stages[j]._dump_acceptor_state(new ASCIIString("testcell"))); +// } +// +// System.out.println(""); +// for (Thread t : traces.keySet()) { +// System.out.println("Thread: "+t.getName()); +// final StackTraceElement[] e = traces.get(t); +// for (StackTraceElement elem : e) { +// System.out.println(elem.toString()); +// } +// } +// System.exit(2); +// } +// } +// } +// +// +// //make sure that cells also time out some times (requires a wait > 2*lease_timeout) +// final int waitTime = (int)(Math.random()*(leaseTimeout*2+2000+dmax)); +// System.out.println("waiting for "+waitTime+"ms"); +// Thread.sleep(waitTime); +// } while (true); +// /* +// for (int i = 0; i < numHosts; i++) { +// stages[i].shutdown(); +// } +// com.shutdown(); +// */ +// +// } catch (Exception ex) { +// ex.printStackTrace(); +// Map traces = Thread.getAllStackTraces(); +// System.out.println(""); +// for (Thread t : traces.keySet()) { +// System.out.println("Thread: "+t.getName()); +// final StackTraceElement[] e = traces.get(t); +// for (StackTraceElement elem : e) { +// System.out.println(elem.toString()); +// } +// } +// System.exit(1); +// } +// +// } +// +// public static final class LInfo { +// ASCIIString host; +// ASCIIString owner; +// long to; +// +// } +// +//} diff --git a/java/flease/src/org/xtreemfs/foundation/flease/sim/FleaseSim.java b/java/flease/src/org/xtreemfs/foundation/flease/sim/FleaseSim.java new file mode 100644 index 0000000..4bd154b --- /dev/null +++ b/java/flease/src/org/xtreemfs/foundation/flease/sim/FleaseSim.java @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease.sim; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import org.xtreemfs.foundation.LifeCycleListener; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.Flease; +import org.xtreemfs.foundation.flease.FleaseConfig; +import org.xtreemfs.foundation.flease.FleaseMessageSenderInterface; +import org.xtreemfs.foundation.flease.FleaseStage; +import org.xtreemfs.foundation.flease.FleaseStatusListener; +import org.xtreemfs.foundation.flease.FleaseViewChangeListenerInterface; +import org.xtreemfs.foundation.flease.MasterEpochHandlerInterface; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.flease.proposer.FleaseException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * Simulator for testing + * @author bjko + */ +public class FleaseSim { + + //private void + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + try { + + final boolean DEBUG_COMM_MSGS = false; + + final int dmax = 500; + final int leaseTimeout = 5000; + + final int numHosts = 10; + final FleaseStage[] stages = new FleaseStage[numHosts]; + + final boolean useME = true; + + Logging.start(Logging.LEVEL_DEBUG, Category.all); + TimeSync.initializeLocal(50); + + final Communicator com = new Communicator(10, 100, 30000, 5, true, 0.2, 0.05, DEBUG_COMM_MSGS); + com.start(); + + List allPorts = new ArrayList(numHosts); + List[] acceptors = new List[numHosts]; + MasterEpochHandlerInterface[] meHandlers = new MasterEpochHandlerInterface[numHosts]; + final AtomicReference[] leaseStates = new AtomicReference[numHosts]; + + for (int i = 0; i < numHosts; i++) { + final int portNo = 1024+i; + final int myI = i; + FleaseConfig cfg = new FleaseConfig(leaseTimeout, dmax, 500, new InetSocketAddress(portNo), "localhost:"+(1024+i),5, true, 0, true); + leaseStates[i] = new AtomicReference(Flease.EMPTY_LEASE); + + if (useME) { + meHandlers[i] = new MasterEpochHandlerInterface() { + long me = 0; + + public long getMasterEpoch() { + return me; + } + + @Override + public void sendMasterEpoch(FleaseMessage response, Continuation callback) { + response.setMasterEpochNumber(me); + callback.processingFinished(); + } + + @Override + public void storeMasterEpoch(FleaseMessage request, Continuation callback) { + me = request.getMasterEpochNumber(); + callback.processingFinished(); + } + }; + } + + + stages[i] = new FleaseStage(cfg, "/tmp/xtreemfs-test", new FleaseMessageSenderInterface() { + + public void sendMessage(FleaseMessage message, InetSocketAddress recipient) { + assert(message != null); + if (DEBUG_COMM_MSGS) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"received message for delivery to port %d: %s",recipient.getPort(),message.toString()); + message.setSender(new InetSocketAddress("localhost", portNo)); + com.send(recipient.getPort(), message); + } + }, true, new FleaseViewChangeListenerInterface() { + + public void viewIdChangeEvent(ASCIIString cellId, int viewId) { + } + },new FleaseStatusListener() { + + public void statusChanged(ASCIIString cellId, Flease lease) { + + synchronized (leaseStates) { + leaseStates[myI].set(lease); + } + System.out.println("state change for "+portNo+": "+lease.getLeaseHolder()+"/"+lease.getLeaseTimeout_ms()); + } + + public void leaseFailed(ASCIIString cellId, FleaseException error) { + System.out.println("lease failed: "+error); + synchronized (leaseStates) { + leaseStates[myI].set(Flease.EMPTY_LEASE); + } + //restart my cell + } + },meHandlers[i]); + stages[i].setLifeCycleListener(new LifeCycleListener() { + + public void startupPerformed() { + } + + public void shutdownPerformed() { + } + + public void crashPerformed(Throwable cause) { + cause.printStackTrace(); + System.exit(100); + } + }); + stages[i].start(); + allPorts.add(new InetSocketAddress("localhost", 1024+i)); + com.openPort(1024+i, stages[i]); + } + + for (int i = 0; i < numHosts; i++) { + final int portNo = 1024+i; + acceptors[i] = new ArrayList(numHosts-1); + for (InetSocketAddress ia : allPorts) { + if (ia.getPort() != portNo) + acceptors[i].add(ia); + } + stages[i].openCell(new ASCIIString("testcell"), acceptors[i],false); + } + + //do something + + do { + final AtomicBoolean sync = new AtomicBoolean(); + final AtomicReference ref = new AtomicReference(); + + Thread.sleep(100); + System.out.print("checking local states: "); + ASCIIString leaseHolder = null; + int leaseInstanceId = 0; + + + + synchronized (leaseStates) { + for (int i = 0; i < numHosts; i++) { + if (!leaseStates[i].get().isEmptyLease()) { + if (leaseHolder == null) { + leaseHolder = leaseStates[i].get().getLeaseHolder(); + } else { + if (!leaseHolder.equals(leaseStates[i].get().getLeaseHolder())) { + com.shutdown(); + System.out.println("INVARIANT VIOLATED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + System.out.println("\n\n"); + System.out.println("got lease for: "+leaseHolder); + System.out.println("but host "+i+" learned "+leaseStates[i].get().getLeaseHolder()); + + for (int j = 0; j < numHosts; j++) { + System.out.println(stages[j]._dump_acceptor_state(new ASCIIString("testcell"))); + System.out.println("signalled result: "+leaseStates[j].get()); + System.out.println(" valid: "+leaseStates[j].get().isValid()); + } + System.exit(2); + } else { + System.out.print("+"); + } + } + } else { + System.out.print("o"); + } + } + } + + System.out.println(""); + + final int host = (int)(Math.random()*numHosts); + stages[host].closeCell(new ASCIIString("testcell"), false); + + + //make sure that cells also time out some times (requires a wait > 2*lease_timeout) + final int waitTime = (int)(Math.random()*(leaseTimeout*2+1000)); + System.out.println("waiting for "+waitTime+"ms"); + Thread.sleep(waitTime); + stages[host].openCell(new ASCIIString("testcell"), acceptors[host],false); + } while (true); + + /* + for (int i = 0; i < numHosts; i++) { + stages[i].shutdown(); + } + com.shutdown(); + */ + + + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(1); + } + + } + +} diff --git a/java/flease/test/org/xtreemfs/foundation/flease/FleaseStageTest.java b/java/flease/test/org/xtreemfs/foundation/flease/FleaseStageTest.java new file mode 100644 index 0000000..98b5d3d --- /dev/null +++ b/java/flease/test/org/xtreemfs/foundation/flease/FleaseStageTest.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.File; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.flease.proposer.FleaseException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.FSUtils; + +/** + * + * @author bjko + */ +public class FleaseStageTest { + + private static FleaseConfig cfg; + private static File testDir; + + @BeforeClass + public static void setUpClass() { + Logging.start(Logging.LEVEL_WARN, Category.all); + TimeSync.initializeLocal(50); + + cfg = new FleaseConfig(10000, 500, 500, new InetSocketAddress(12345), "localhost:12345",5); + testDir = new File("/tmp/xtreemfs-test/"); + } + + @Before + public void setUp() throws Exception { + FSUtils.delTree(testDir); + testDir.mkdirs(); + } + + @After + public void tearDown() throws Exception { + } + + /** + * Test of createTimer method, of class FleaseStage. + */ + @Test + public void testOpenAndGetLease() throws Exception { + final ASCIIString CELL_ID = new ASCIIString("testcell"); + + final AtomicReference result = new AtomicReference(); + + FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() { + + @Override + public void sendMessage(FleaseMessage message, InetSocketAddress recipient) { + //ignore me + } + }, true, new FleaseViewChangeListenerInterface() { + + @Override + public void viewIdChangeEvent(ASCIIString cellId, int viewId) { + } + },new FleaseStatusListener() { + + @Override + public void statusChanged(ASCIIString cellId, Flease lease) { + // System.out.println("state change: "+cellId+" owner="+lease.getLeaseHolder()); + synchronized (result) { + result.set(new Flease(cellId, lease.getLeaseHolder(), lease.getLeaseTimeout_ms(),lease.getMasterEpochNumber())); + result.notify(); + } + } + + @Override + public void leaseFailed(ASCIIString cellId, FleaseException error) { + fail(error.toString()); + } + }, null); + + FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART); + msg.setCellId(CELL_ID); + + fs.start(); + fs.waitForStartup(); + + fs.openCell(CELL_ID, new ArrayList(),false); + + synchronized(result) { + if (result.get() == null) + result.wait(1000); + if (result.get() == null) + fail("timeout!"); + } + + assertEquals(result.get().getLeaseHolder(),cfg.getIdentity()); + + FleaseFuture f = fs.closeCell(CELL_ID, false); + f.get(); + + Thread.sleep(12000); + + result.set(null); + + fs.openCell(CELL_ID, new ArrayList(), false); + + synchronized(result) { + if (result.get() == null) + result.wait(1000); + if (result.get() == null) + fail("timeout!"); + } + + assertEquals(result.get().getLeaseHolder(),cfg.getIdentity()); + + fs.shutdown(); + fs.waitForShutdown(); + + } + + + /** + * Test of createTimer method, of class FleaseStage. + */ + @Test + public void testGetState() throws Exception { + FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() { + + @Override + public void sendMessage(FleaseMessage message, InetSocketAddress recipient) { + //ignore me + } + }, true, new FleaseViewChangeListenerInterface() { + + @Override + public void viewIdChangeEvent(ASCIIString cellId, int viewId) { + } + },new FleaseStatusListener() { + + @Override + public void statusChanged(ASCIIString cellId, Flease lease) { + } + + @Override + public void leaseFailed(ASCIIString cellId, FleaseException error) { + fail(error.toString()); + } + }, null); + + FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART); + msg.setCellId(new ASCIIString("testcell")); + + fs.start(); + fs.waitForStartup(); + + FleaseFuture f = fs.openCell(new ASCIIString("testcell"), new ArrayList(), false); + final AtomicBoolean done = new AtomicBoolean(false); + f.get(); + + Thread.sleep(100); + + + Map m = fs.getLocalState(); + + // for (ASCIIString cellId : m.keySet()) { + // System.out.println("cell "+cellId+" "+m.get(cellId)); + // } + + fs.shutdown(); + fs.waitForShutdown(); + + } + + /** + * Test of createTimer method, of class FleaseStage. + */ + @Test + public void testCreateTimer() throws Exception { + FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() { + + @Override + public void sendMessage(FleaseMessage messages, InetSocketAddress recipient) { + //ignore me + } + }, true, new FleaseViewChangeListenerInterface() { + + @Override + public void viewIdChangeEvent(ASCIIString cellId, int viewId) { + } + },new FleaseStatusListener() { + + @Override + public void statusChanged(ASCIIString cellId, Flease lease) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void leaseFailed(ASCIIString cellId, FleaseException error) { + throw new UnsupportedOperationException("Not supported yet."); + } + }, null); + + FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART); + msg.setCellId(new ASCIIString("testcell")); + + fs.start(); + fs.waitForStartup(); + fs.createTimer(msg, TimeSync.getLocalSystemTime()+20); + Thread.sleep(100); + fs.shutdown(); + fs.waitForShutdown(); + + } + +} diff --git a/java/flease/test/org/xtreemfs/foundation/flease/MasterEpochTest.java b/java/flease/test/org/xtreemfs/foundation/flease/MasterEpochTest.java new file mode 100644 index 0000000..4c3231a --- /dev/null +++ b/java/flease/test/org/xtreemfs/foundation/flease/MasterEpochTest.java @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.File; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicReference; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.flease.proposer.FleaseException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.FSUtils; + +/** + * + * @author bjko + */ +public class MasterEpochTest { + + private static FleaseConfig cfg; + private static File testDir; + + @BeforeClass + public static void setUpClass() { + Logging.start(Logging.LEVEL_WARN, Category.all); + TimeSync.initializeLocal(50); + + cfg = new FleaseConfig(10000, 500, 500, new InetSocketAddress(12345), "localhost:12345",5, true, 0, true); + testDir = new File("/tmp/xtreemfs-test/"); + } + + @Before + public void setUp() throws Exception { + FSUtils.delTree(testDir); + testDir.mkdirs(); + } + + @After + public void tearDown() throws Exception { + } + + /** + * Test of createTimer method, of class FleaseStage. + */ + @Test + public void testOpenAndGetLease() throws Exception { + final ASCIIString CELL_ID = new ASCIIString("testcell"); + + final AtomicReference result = new AtomicReference(); + + FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() { + + @Override + public void sendMessage(FleaseMessage message, InetSocketAddress recipient) { + //ignore me + } + }, true, new FleaseViewChangeListenerInterface() { + + @Override + public void viewIdChangeEvent(ASCIIString cellId, int viewId) { + } + },new FleaseStatusListener() { + + @Override + public void statusChanged(ASCIIString cellId, Flease lease) { + // System.out.println("state change: "+cellId+" owner="+lease.getLeaseHolder()); + synchronized (result) { + result.set(new Flease(cellId, lease.getLeaseHolder(), lease.getLeaseTimeout_ms(),lease.getMasterEpochNumber())); + result.notify(); + } + } + + @Override + public void leaseFailed(ASCIIString cellId, FleaseException error) { + fail(error.toString()); + } + }, new MasterEpochHandlerInterface() { + + long masterEpochNum = 0; + + @Override + public void sendMasterEpoch(FleaseMessage response, Continuation callback) { + // System.out.println("sending: "+masterEpochNum); + response.setMasterEpochNumber(masterEpochNum); + callback.processingFinished(); + } + + @Override + public void storeMasterEpoch(FleaseMessage request, Continuation callback) { + masterEpochNum = request.getMasterEpochNumber(); + // System.out.println("storing: "+masterEpochNum); + callback.processingFinished(); + } + }); + + FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART); + msg.setCellId(CELL_ID); + + fs.start(); + fs.waitForStartup(); + + fs.openCell(CELL_ID, new ArrayList(),true); + + synchronized(result) { + if (result.get() == null) + result.wait(1000); + if (result.get() == null) + fail("timeout!"); + } + + assertEquals(result.get().getLeaseHolder(),cfg.getIdentity()); + assertEquals(result.get().getMasterEpochNumber(),1); + + FleaseFuture f = fs.closeCell(CELL_ID, false); + f.get(); + + Thread.sleep(12000); + + result.set(null); + + fs.openCell(CELL_ID, new ArrayList(), true); + + synchronized(result) { + if (result.get() == null) + result.wait(1000); + if (result.get() == null) + fail("timeout!"); + } + + assertEquals(result.get().getLeaseHolder(),cfg.getIdentity()); + assertEquals(result.get().getMasterEpochNumber(),2); + + fs.shutdown(); + fs.waitForShutdown(); + + } + + + /** + * Test of createTimer method, of class FleaseStage. + */ + @Test + public void testSimpleMasterEpochHandler() throws Exception { + final ASCIIString CELL_ID = new ASCIIString("testcell"); + + final AtomicReference result = new AtomicReference(); + + SimpleMasterEpochHandler meHandler = new SimpleMasterEpochHandler("/tmp/xtreemfs-test/"); + meHandler.start(); + meHandler.waitForStartup(); + + FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() { + + @Override + public void sendMessage(FleaseMessage message, InetSocketAddress recipient) { + //ignore me + } + }, true, new FleaseViewChangeListenerInterface() { + + @Override + public void viewIdChangeEvent(ASCIIString cellId, int viewId) { + } + },new FleaseStatusListener() { + + @Override + public void statusChanged(ASCIIString cellId, Flease lease) { + // System.out.println("state change: "+cellId+" owner="+lease.getLeaseHolder()); + synchronized (result) { + result.set(new Flease(cellId, lease.getLeaseHolder(), lease.getLeaseTimeout_ms(),lease.getMasterEpochNumber())); + result.notify(); + } + } + + @Override + public void leaseFailed(ASCIIString cellId, FleaseException error) { + fail(error.toString()); + } + }, meHandler); + + FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART); + msg.setCellId(CELL_ID); + + fs.start(); + fs.waitForStartup(); + + fs.openCell(CELL_ID, new ArrayList(),true); + + synchronized(result) { + if (result.get() == null) + result.wait(1000); + if (result.get() == null) + fail("timeout!"); + } + + assertEquals(result.get().getLeaseHolder(),cfg.getIdentity()); + assertEquals(1, result.get().getMasterEpochNumber()); + + FleaseFuture f = fs.closeCell(CELL_ID, false); + f.get(); + + fs.shutdown(); + fs.waitForShutdown(); + meHandler.shutdown(); + meHandler.waitForShutdown(); + + Thread.sleep(12000); + + //restart + meHandler = new SimpleMasterEpochHandler("/tmp/xtreemfs-test/"); + meHandler.start(); + meHandler.waitForStartup(); + + fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() { + + @Override + public void sendMessage(FleaseMessage message, InetSocketAddress recipient) { + //ignore me + } + }, true, new FleaseViewChangeListenerInterface() { + + @Override + public void viewIdChangeEvent(ASCIIString cellId, int viewId) { + } + },new FleaseStatusListener() { + + @Override + public void statusChanged(ASCIIString cellId, Flease lease) { + // System.out.println("state change: "+cellId+" owner="+lease.getLeaseHolder()); + synchronized (result) { + result.set(new Flease(cellId, lease.getLeaseHolder(), lease.getLeaseTimeout_ms(),lease.getMasterEpochNumber())); + result.notify(); + } + } + + @Override + public void leaseFailed(ASCIIString cellId, FleaseException error) { + fail(error.toString()); + } + }, meHandler); + + fs.start(); + fs.waitForStartup(); + + result.set(null); + + fs.openCell(CELL_ID, new ArrayList(), true); + + synchronized(result) { + if (result.get() == null) + result.wait(1000); + if (result.get() == null) + fail("timeout!"); + } + + assertEquals(result.get().getLeaseHolder(),cfg.getIdentity()); + assertEquals(result.get().getMasterEpochNumber(),2); + + fs.shutdown(); + fs.waitForShutdown(); + + } + + +} diff --git a/java/flease/test/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptorTest.java b/java/flease/test/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptorTest.java new file mode 100644 index 0000000..e020503 --- /dev/null +++ b/java/flease/test/org/xtreemfs/foundation/flease/acceptor/FleaseAcceptorTest.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease.acceptor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.io.File; +import java.net.InetSocketAddress; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.FleaseConfig; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.flease.comm.FleaseMessage.MsgType; +import org.xtreemfs.foundation.flease.comm.ProposalNumber; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.FSUtils; + +/** + * + * @author bjko + */ +public class FleaseAcceptorTest { + + private FleaseAcceptor acceptor; + private final static ASCIIString TESTCELL = new ASCIIString("testcell"); + + private static FleaseConfig cfg; + private static File testDir; + + @BeforeClass + public static void setUpClass() { + testDir = new File("/tmp/xtreemfs-test/"); + FSUtils.delTree(testDir); + testDir.mkdirs(); + Logging.start(Logging.LEVEL_WARN, Category.all); + TimeSync.initializeLocal(50); + + cfg = new FleaseConfig(10000, 500, 500, new InetSocketAddress(12345), "localhost:12345",1); + } + + @Before + public void setUp() throws Exception { + acceptor = new FleaseAcceptor(new LearnEventListener() { + + @Override + public void learnedEvent(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long me) { + } + }, cfg, "/tmp/xtreemfs-test/", true); + } + + @After + public void tearDown() throws Exception { + acceptor.shutdown(); + } + + @Test + public void testPrepAccLearn() { + + FleaseMessage prep = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE); + prep.setCellId(TESTCELL); + prep.setProposalNo(new ProposalNumber(1, 1)); + prep.setSendTimestamp(TimeSync.getLocalSystemTime()); + prep.setLeaseTimeout(TimeSync.getLocalSystemTime()+10000); + prep.setLeaseHolder(new ASCIIString("me")); + + FleaseMessage response = acceptor.processMessage(prep); + assertEquals(MsgType.MSG_PREPARE_ACK,response.getMsgType()); + + prep = new FleaseMessage(MsgType.MSG_ACCEPT,prep); + prep.setSendTimestamp(TimeSync.getLocalSystemTime()); + + response = acceptor.processMessage(prep); + assertEquals(MsgType.MSG_ACCEPT_ACK,response.getMsgType()); + + prep = new FleaseMessage(MsgType.MSG_LEARN,prep); + prep.setSendTimestamp(TimeSync.getLocalSystemTime()); + response = acceptor.processMessage(prep); + assertNull(response); + + } + + @Test + public void testConcurrentProposal() { + + FleaseMessage prep1 = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE); + prep1.setCellId(TESTCELL); + prep1.setProposalNo(new ProposalNumber(1, 1)); + prep1.setSendTimestamp(TimeSync.getLocalSystemTime()); + prep1.setLeaseTimeout(TimeSync.getLocalSystemTime()+10000); + prep1.setLeaseHolder(new ASCIIString("me1")); + + FleaseMessage prep2 = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE); + prep2.setCellId(TESTCELL); + prep2.setProposalNo(new ProposalNumber(1, 2)); + prep2.setSendTimestamp(TimeSync.getLocalSystemTime()); + prep2.setLeaseTimeout(TimeSync.getLocalSystemTime()+10000); + prep2.setLeaseHolder(new ASCIIString("me2")); + + FleaseMessage response = acceptor.processMessage(prep1); + assertEquals(MsgType.MSG_PREPARE_ACK,response.getMsgType()); + + response = acceptor.processMessage(prep2); + assertEquals(MsgType.MSG_PREPARE_ACK,response.getMsgType()); + + prep1 = new FleaseMessage(MsgType.MSG_ACCEPT,prep1); + prep1.setSendTimestamp(TimeSync.getLocalSystemTime()); + + response = acceptor.processMessage(prep1); + assertEquals(MsgType.MSG_ACCEPT_NACK,response.getMsgType()); + + } + + @Test + public void testGetLease() { + + + FleaseMessage prep2 = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE); + prep2.setCellId(TESTCELL); + prep2.setProposalNo(new ProposalNumber(1, 2)); + prep2.setSendTimestamp(TimeSync.getLocalSystemTime()); + prep2.setLeaseTimeout(TimeSync.getLocalSystemTime()+10000); + prep2.setLeaseHolder(new ASCIIString("me2")); + + + FleaseMessage response = acceptor.processMessage(prep2); + assertEquals(MsgType.MSG_PREPARE_ACK,response.getMsgType()); + + prep2 = new FleaseMessage(MsgType.MSG_ACCEPT,prep2); + prep2.setSendTimestamp(TimeSync.getLocalSystemTime()); + response = acceptor.processMessage(prep2); + assertEquals(MsgType.MSG_ACCEPT_ACK,response.getMsgType()); + + FleaseMessage lease = acceptor.getLocalLeaseInformation(TESTCELL); + assertNull(lease); + + prep2 = new FleaseMessage(MsgType.MSG_LEARN,prep2); + prep2.setSendTimestamp(TimeSync.getLocalSystemTime()); + response = acceptor.processMessage(prep2); + assertNull(response); + + lease = acceptor.getLocalLeaseInformation(TESTCELL); + assertNotNull(lease); + assertEquals(new ASCIIString("me2"),lease.getLeaseHolder()); + + + + } + + + +} diff --git a/java/flease/test/org/xtreemfs/foundation/flease/comm/FleaseMessageTest.java b/java/flease/test/org/xtreemfs/foundation/flease/comm/FleaseMessageTest.java new file mode 100644 index 0000000..616f3c7 --- /dev/null +++ b/java/flease/test/org/xtreemfs/foundation/flease/comm/FleaseMessageTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease.comm; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import static org.junit.Assert.*; + +/** + * + * @author bjko + */ +public class FleaseMessageTest { + + public FleaseMessageTest() { + } + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + @Test + public void testSerialization() throws Exception { + FleaseMessage m1 = new FleaseMessage(FleaseMessage.MsgType.MSG_LEARN); + m1.setCellId(new ASCIIString("testcell")); + m1.setLeaseHolder(new ASCIIString("yagga")); + m1.setLeaseTimeout(123456789l); + m1.setPrevProposalNo(new ProposalNumber(12, 178743687)); + m1.setProposalNo(new ProposalNumber(15, 736456)); + m1.setSendTimestamp(49789834); + m1.setViewId(55685); + m1.setMasterEpochNumber(52455115211l); + + final int size = m1.getSize(); + ReusableBuffer rb = BufferPool.allocate(size); + + m1.serialize(rb); + + + rb.flip(); + + FleaseMessage m2 = new FleaseMessage(rb); + + assertEquals(m1.getCellId(),m2.getCellId()); + assertEquals(m1.getLeaseHolder(),m2.getLeaseHolder()); + assertEquals(m1.getLeaseTimeout(),m2.getLeaseTimeout()); + assertEquals(m1.getMsgType(),m2.getMsgType()); + assertEquals(m1.getPrevProposalNo().getProposalNo(),m2.getPrevProposalNo().getProposalNo()); + assertEquals(m1.getPrevProposalNo().getSenderId(),m2.getPrevProposalNo().getSenderId()); + assertEquals(m1.getProposalNo().getProposalNo(),m2.getProposalNo().getProposalNo()); + assertEquals(m1.getProposalNo().getSenderId(),m2.getProposalNo().getSenderId()); + assertEquals(m1.getSendTimestamp(),m2.getSendTimestamp()); + assertEquals(m1.getViewId(),m2.getViewId()); + assertEquals(m1.getMasterEpochNumber(),m2.getMasterEpochNumber()); + } + +} \ No newline at end of file diff --git a/java/flease/test/org/xtreemfs/foundation/flease/proposer/FleaseProposerTest.java b/java/flease/test/org/xtreemfs/foundation/flease/proposer/FleaseProposerTest.java new file mode 100644 index 0000000..846250f --- /dev/null +++ b/java/flease/test/org/xtreemfs/foundation/flease/proposer/FleaseProposerTest.java @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.flease.proposer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.Flease; +import org.xtreemfs.foundation.flease.FleaseConfig; +import org.xtreemfs.foundation.flease.FleaseStatusListener; +import org.xtreemfs.foundation.flease.acceptor.FleaseAcceptor; +import org.xtreemfs.foundation.flease.acceptor.LearnEventListener; +import org.xtreemfs.foundation.flease.comm.FleaseCommunicationInterface; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.FSUtils; + +/** + * + * @author bjko + */ +public class FleaseProposerTest { + + private FleaseAcceptor acceptor; + private FleaseProposer proposer; + private final static ASCIIString TESTCELL = new ASCIIString("testcell"); + + private static FleaseConfig cfg; + private static File testDir; + + private static AtomicReference result; + + @BeforeClass + public static void setUpClass() throws Exception { + testDir = new File("/tmp/xtreemfs-test/"); + FSUtils.delTree(testDir); + testDir.mkdirs(); + + result = new AtomicReference(); + Logging.start(Logging.LEVEL_WARN, Category.all); + TimeSync.initializeLocal(50); + + cfg = new FleaseConfig(10000, 500, 500, new InetSocketAddress(12345), "localhost:12345",5); + } + + @Before + public void setUp() throws Exception { + acceptor = new FleaseAcceptor(new LearnEventListener() { + + @Override + public void learnedEvent(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long me) { + } + }, cfg, "/tmp/xtreemfs-test/", true); + proposer = new FleaseProposer(cfg, acceptor, new FleaseCommunicationInterface() { + + @Override + public void sendMessage(FleaseMessage msg, InetSocketAddress receiver) throws IOException { + } + + @Override + public void requestTimer(FleaseMessage msg, long timestamp) { + if (msg.getMsgType() == FleaseMessage.MsgType.EVENT_RESTART) { + long wait = timestamp - TimeSync.getLocalSystemTime(); + try { + Thread.sleep(wait); + } catch (InterruptedException ex) { + Logger.getLogger(FleaseProposerTest.class.getName()).log(Level.SEVERE, null, ex); + } + try { + proposer.processMessage(msg); + } catch (Exception ex) { + fail(ex.toString()); + } + } + } + }, new FleaseStatusListener() { + + @Override + public void statusChanged(ASCIIString cellId, Flease lease) { + // System.out.println("result: "+lease.getLeaseHolder()); + synchronized (result) { + result.set(new Flease(cellId, lease.getLeaseHolder(), lease.getLeaseTimeout_ms(),lease.getMasterEpochNumber())); + result.notify(); + } + } + + @Override + public void leaseFailed(ASCIIString cellId, FleaseException error) { + // System.out.println("failed: "+error); + fail(error.toString()); + } + }, new LearnEventListener() { + + @Override + public void learnedEvent(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, long me) { + throw new UnsupportedOperationException("Not supported yet."); + } + },null,null); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetLease() throws Exception { + + proposer.openCell(TESTCELL, new ArrayList(), false, 0); + + Thread.sleep(100); + + FleaseProposerCell cell = proposer.cells.get(TESTCELL); + + assertEquals(TESTCELL,cell.getMessageSent().getCellId()); + assertEquals(cfg.getIdentity(),cell.getMessageSent().getLeaseHolder()); + assertTrue(cell.getMessageSent().getLeaseTimeout() > TimeSync.getGlobalTime()); + + + } + + /*public void testHandoverLease() throws Exception { + + proposer.openCell(TESTCELL, new ArrayList(),false); + + + Thread.sleep(100); + + FleaseProposerCell cell = proposer.cells.get(TESTCELL); + + assertEquals(TESTCELL,cell.getMessageSent().getCellId()); + assertEquals(cfg.getIdentity(),cell.getMessageSent().getLeaseHolder()); + assertTrue(cell.getMessageSent().getLeaseTimeout() > TimeSync.getGlobalTime()); + + final ASCIIString HANDOVER = new ASCIIString("HANDOVER"); + + proposer.handoverLease(TESTCELL, HANDOVER); + + Thread.sleep(100); + + cell = proposer.cells.get(TESTCELL); + + assertEquals(TESTCELL,cell.getMessageSent().getCellId()); + assertEquals(HANDOVER,cell.getMessageSent().getLeaseHolder()); + assertTrue(cell.getMessageSent().getLeaseTimeout() > TimeSync.getGlobalTime()); + + + }*/ + + +// public void testPriorProposal() throws Exception { +// +// final ASCIIString otherId = new ASCIIString("YAGGAYAGGA"); +// final AtomicBoolean finished = new AtomicBoolean(false); +// +// //initialize the acceptor +// FleaseMessage tmp = new FleaseMessage(FleaseMessage.MsgType.MSG_ACCEPT); +// tmp.setCellId(TESTCELL); +// tmp.setProposalNo(new ProposalNumber(10, 123456)); +// tmp.setLeaseHolder(otherId); +// tmp.setLeaseTimeout(TimeSync.getGlobalTime()-20000); +// tmp.setSendTimestamp(TimeSync.getGlobalTime()); +// acceptor.processMessage(tmp); +// +// tmp.setCellId(TESTCELL); +// tmp.setProposalNo(new ProposalNumber(10, 123456)); +// tmp.setLeaseTimeout(TimeSync.getGlobalTime()+10000); +// tmp.setSendTimestamp(TimeSync.getGlobalTime()); +// acceptor.processMessage(tmp); +// +// proposer.openCell(TESTCELL, new ArrayList(),false); +// +// System.out.println("start acquire lease..."); +// proposer.acquireLease(TESTCELL, new FleaseListener() { +// +// public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms) { +// System.out.println("got lease!"); +// assertEquals(TESTCELL,cellId); +// assertEquals(otherId,leaseHolder); +// finished.set(true); +// } +// +// public void proposalFailed(ASCIIString cellId, Throwable cause) { +// System.out.println("failed!"); +// fail(cause.toString()); +// } +// }); +// +// +// } +// +// +// public void testPriorProposal2() throws Exception { +// +// final ASCIIString otherId = new ASCIIString("YAGGAYAGGA"); +// final AtomicBoolean finished = new AtomicBoolean(false); +// +// //initialize the acceptor +// FleaseMessage tmp = new FleaseMessage(FleaseMessage.MsgType.MSG_LEARN); +// tmp.setCellId(TESTCELL); +// tmp.setProposalNo(new ProposalNumber(10, 123456)); +// tmp.setLeaseHolder(otherId); +// tmp.setLeaseTimeout(TimeSync.getGlobalTime()+10000); +// tmp.setSendTimestamp(TimeSync.getGlobalTime()); +// acceptor.processMessage(tmp); +// +// tmp.setCellId(TESTCELL); +// tmp.setProposalNo(new ProposalNumber(10, 123456)); +// tmp.setLeaseTimeout(TimeSync.getGlobalTime()+10000); +// tmp.setSendTimestamp(TimeSync.getGlobalTime()); +// acceptor.processMessage(tmp); +// +// proposer.openCell(TESTCELL, new ArrayList(),false); +// +// System.out.println("start acquire lease..."); +// proposer.acquireLease(TESTCELL, new FleaseListener() { +// +// public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms) { +// System.out.println("got lease!"); +// assertEquals(TESTCELL,cellId); +// assertEquals(otherId,leaseHolder); +// finished.set(true); +// } +// +// public void proposalFailed(ASCIIString cellId, Throwable cause) { +// System.out.println("failed!"); +// fail(cause.toString()); +// } +// }); +// +// +// } +// +// public void testValidLease() throws Exception { +// +// final ASCIIString otherId = new ASCIIString("YAGGAYAGGA"); +// final AtomicBoolean finished = new AtomicBoolean(false); +// +// //initialize the acceptor +// FleaseMessage tmp = new FleaseMessage(FleaseMessage.MsgType.MSG_LEARN); +// tmp.setCellId(TESTCELL); +// tmp.setProposalNo(new ProposalNumber(10, 123456)); +// tmp.setLeaseHolder(otherId); +// tmp.setLeaseTimeout(TimeSync.getGlobalTime()+10000); +// tmp.setSendTimestamp(TimeSync.getGlobalTime()); +// acceptor.processMessage(tmp); +// +// proposer.openCell(TESTCELL, new ArrayList(),false); +// +// System.out.println("start acquire lease..."); +// proposer.acquireLease(TESTCELL, new FleaseListener() { +// +// public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms) { +// System.out.println("got lease!"); +// assertEquals(TESTCELL,cellId); +// assertEquals(otherId,leaseHolder); +// finished.set(true); +// } +// +// public void proposalFailed(ASCIIString cellId, Throwable cause) { +// System.out.println("failed!"); +// fail(cause.toString()); +// } +// }); +// } +// +// public void testLeaseInGP() throws Exception { +// +// System.out.println("TEST testLeaseInGP"); +// +// final ASCIIString otherId = new ASCIIString("YAGGAYAGGA"); +// final AtomicBoolean finished = new AtomicBoolean(false); +// +// //initialize the acceptor +// FleaseMessage tmp = new FleaseMessage(FleaseMessage.MsgType.MSG_LEARN); +// tmp.setCellId(TESTCELL); +// tmp.setProposalNo(new ProposalNumber(10, 123456)); +// tmp.setLeaseHolder(otherId); +// tmp.setLeaseTimeout(TimeSync.getGlobalTime()+100); +// tmp.setSendTimestamp(TimeSync.getGlobalTime()); +// acceptor.processMessage(tmp); +// +// proposer.openCell(TESTCELL, new ArrayList(),false); +// +// System.out.println("start acquire lease..."); +// proposer.acquireLease(TESTCELL, new FleaseListener() { +// +// public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms) { +// System.out.println("got lease!"); +// assertEquals(TESTCELL,cellId); +// assertEquals(cfg.getIdentity(),leaseHolder); +// finished.set(true); +// } +// +// public void proposalFailed(ASCIIString cellId, Throwable cause) { +// System.out.println("failed!"); +// fail(cause.toString()); +// } +// }); +// +// +// } + + + + + +} diff --git a/java/foundation/build-1.6.5.xml b/java/foundation/build-1.6.5.xml new file mode 100644 index 0000000..ddf49ef --- /dev/null +++ b/java/foundation/build-1.6.5.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + Builds, tests, and runs the project Foundation as part of the XtreemFS project. + + + + diff --git a/java/foundation/build-before-profiler.xml b/java/foundation/build-before-profiler.xml new file mode 100644 index 0000000..da1b387 --- /dev/null +++ b/java/foundation/build-before-profiler.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project Foundation as part of the XtreemFS project. + + + diff --git a/java/foundation/build.xml b/java/foundation/build.xml new file mode 100644 index 0000000..1e864f6 --- /dev/null +++ b/java/foundation/build.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + Builds, tests, and runs the project Foundation as part of the XtreemFS project. + + + + + + + Creating PBRPC.jar. + + + + + + + diff --git a/java/foundation/eclipse-project/.classpath b/java/foundation/eclipse-project/.classpath new file mode 100644 index 0000000..7ee5d18 --- /dev/null +++ b/java/foundation/eclipse-project/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/java/foundation/eclipse-project/.project b/java/foundation/eclipse-project/.project new file mode 100644 index 0000000..1447dce --- /dev/null +++ b/java/foundation/eclipse-project/.project @@ -0,0 +1,17 @@ + + + xtreemfs_foundation + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/java/foundation/nbproject/build-impl-1.6.5.xml b/java/foundation/nbproject/build-impl-1.6.5.xml new file mode 100644 index 0000000..8ba3c05 --- /dev/null +++ b/java/foundation/nbproject/build-impl-1.6.5.xml @@ -0,0 +1,682 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + diff --git a/java/foundation/nbproject/build-impl.xml b/java/foundation/nbproject/build-impl.xml new file mode 100644 index 0000000..b66e0b7 --- /dev/null +++ b/java/foundation/nbproject/build-impl.xml @@ -0,0 +1,687 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + diff --git a/java/foundation/nbproject/genfiles.properties b/java/foundation/nbproject/genfiles.properties new file mode 100644 index 0000000..5749302 --- /dev/null +++ b/java/foundation/nbproject/genfiles.properties @@ -0,0 +1,11 @@ +build.xml.data.CRC32=4a9eff70 +build.xml.script.CRC32=ce2ddeb0 +build.xml.stylesheet.CRC32=958a1d3e +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=beaaf17a +nbproject/build-impl.xml.script.CRC32=3e4625c6 +nbproject/build-impl.xml.stylesheet.CRC32=78c6a6ee@1.38.1.45 +nbproject/profiler-build-impl.xml.data.CRC32=4a9eff70 +nbproject/profiler-build-impl.xml.script.CRC32=abda56ed +nbproject/profiler-build-impl.xml.stylesheet.CRC32=42cb6bcf diff --git a/java/foundation/nbproject/profiler-build-impl.xml b/java/foundation/nbproject/profiler-build-impl.xml new file mode 100644 index 0000000..7c8995d --- /dev/null +++ b/java/foundation/nbproject/profiler-build-impl.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/foundation/nbproject/project.properties b/java/foundation/nbproject/project.properties new file mode 100644 index 0000000..e72205a --- /dev/null +++ b/java/foundation/nbproject/project.properties @@ -0,0 +1,82 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +application.args= +application.title=Foundation +application.vendor=flangner +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Foundation.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.bcprov-jdk16-139.jar=lib/bcprov-jdk16-139.jar +file.reference.cdaclient.jar=lib/cdaclient.jar +file.reference.junit-4.11.jar=../lib/test/junit-4.11.jar +file.reference.config.jar=lib/config.jar +file.reference.je-3.2.13.jar=lib/je-3.2.13.jar +file.reference.protobuf-java-2.5.0.jar=../lib/protobuf-java-2.5.0.jar +file.reference.xbean.jar=lib/xbean.jar +file.reference.commons-codec-1.3.jar=../lib/commons-codec-1.3.jar +includes=** +jar.compress=true +javac.classpath=\ + ${file.reference.commons-codec-1.3.jar}:\ + ${file.reference.protobuf-java-2.5.0.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.6 +javac.target=1.6 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit_4.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding= +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +jnlp.codebase.type=local +jnlp.enabled=false +jnlp.offline-allowed=false +jnlp.signed=false +main.class= +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs=-ea +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +src.dir=src +test.src.dir=test diff --git a/java/foundation/nbproject/project.xml b/java/foundation/nbproject/project.xml new file mode 100644 index 0000000..489d87e --- /dev/null +++ b/java/foundation/nbproject/project.xml @@ -0,0 +1,22 @@ + + + org.netbeans.modules.java.j2seproject + + + + + + + + XtreemFS-foundation + 1.6.5 + + + + + + + + + + diff --git a/java/foundation/src/org/xtreemfs/foundation/ClientLease.java b/java/foundation/src/org/xtreemfs/foundation/ClientLease.java new file mode 100644 index 0000000..62710a5 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/ClientLease.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2010 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation; + +/** + * + * @author bjko + */ +public final class ClientLease implements Cloneable { + + /** + * Default time span for the client lease validity. + * Must be smaller than a intra-OSD lease, if replication is + * active! + */ + public static final long LEASE_VALIDITY = 15000; + + /** + * Indicates that a lease spans to EOF "append lease". + * a lease from 0 to -1 spans the whole file, even if data is appended. + */ + public static final long TO_EOF = -1; + + /** + * timestamp when the lease expires + */ + private long firstObject; + /** + * last object the lease is valid for + */ + private long lastObject; + + /** + * UUID of the client owning the lease + */ + private String clientId; + + /** + * timestamp when the lease expires (in seconds since 01/01/70) + * must be XtreemFS global time! + */ + private long expires; + + + /** + * fileId this lease was issued for + */ + private final String fileId; + + /** + * sequenceNo, used to generate unique leaseId = fileId+"/"+sequenceNo + */ + private long sequenceNo; + + /** + * lease type/operation + */ + private String operation; + + public static final String EXCLUSIVE_LEASE = "w"; + + + public ClientLease(final String fileId) { + this.fileId = fileId; + } + + + /** + * Checks if two leases have conflicting (i.e. overlapping ranges) + * @param other other lease for the same file + * @return true, if there is an overlap in the ranges + */ + public boolean isConflicting(ClientLease other) { + //checks + if ( ((this.lastObject < other.firstObject) && (this.lastObject != TO_EOF)) || + ((other.lastObject < this.firstObject) && (other.lastObject != TO_EOF)) ) { + return false; + } else { + return true; + } + } + + @Override + public ClientLease clone() { + ClientLease l = new ClientLease(this.fileId); + l.clientId = this.clientId; + l.expires = this.expires; + l.firstObject = this.firstObject; + l.lastObject = this.lastObject; + l.operation = this.operation; + l.sequenceNo = this.sequenceNo; + return l; + } + + public long getFirstObject() { + return firstObject; + } + + public void setFirstObject(long firstObject) { + this.firstObject = firstObject; + } + + public long getLastObject() { + return lastObject; + } + + public void setLastObject(long lastObject) { + this.lastObject = lastObject; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public long getExpires() { + return expires; + } + + public void setExpires(long expires) { + this.expires = expires; + } + + public String getFileId() { + return fileId; + } + + public long getSequenceNo() { + return sequenceNo; + } + + public void setSequenceNo(long sequenceNo) { + this.sequenceNo = sequenceNo; + } + + public String getOperation() { + return operation; + } + + public void setOperation(String operation) { + this.operation = operation; + } + + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/CrashReporter.java b/java/foundation/src/org/xtreemfs/foundation/CrashReporter.java new file mode 100644 index 0000000..54920a6 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/CrashReporter.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2010 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation; + +import java.util.Map; + +/** + * + * @author bjko + */ +public class CrashReporter { + + public static void reportXtreemFSCrash(String report) { + /*try { + URL u = new URL("http://www.xtreemfs.org/dump/dump.php?srv=server"); + HttpURLConnection con = (HttpURLConnection) u.openConnection(); + con.setRequestMethod("PUT"); + con.setDoOutput(true); + con.connect(); + OutputStream os = con.getOutputStream(); + os.write(report.getBytes()); + os.flush(); + os.close(); + + InputStream is = con.getInputStream(); + is.available(); + is.close(); + } catch (Throwable th) { + System.out.println("cannot send crash report: "+th); + }*/ + } + + public static String createCrashReport(String service, String version, Throwable cause) { + try { + StringBuilder report = new StringBuilder(); + report.append("----------------------------------------------------------------\n"); + report.append("We are sorry, but your "+service+" has crashed. To report this bug\n"); + report.append("please go to http://www.xtreemfs.org and file an issue and attach\n"); + report.append("this crash report.\n\n"); + report.append("service: "); + report.append(service); + report.append(" version: "); + report.append(version); + report.append("\n"); + report.append("JVM version: "); + report.append(System.getProperty("java.version")); + report.append(" "); + report.append(System.getProperty("java.vendor")); + report.append(" on "); + report.append(System.getProperty("os.name")); + report.append(" "); + report.append(System.getProperty("os.version")); + report.append("\n"); + report.append("exception: "); + report.append(cause.toString()); + report.append("\n"); + for (StackTraceElement elem : cause.getStackTrace()) { + report.append(elem.toString()); + report.append("\n"); + } + if (cause.getCause() != null) { + report.append("\nroot cause: "); + report.append(cause.getCause()); + report.append("\n"); + for (StackTraceElement elem : cause.getCause().getStackTrace()) { + report.append(elem.toString()); + report.append("\n"); + } + } + reportThreadStates(report); + + report.append("----------------------------------------------------------------\n"); + return report.toString(); + } catch (Exception ex) { + ex.printStackTrace(); + return "Could not write crash report for: "+service+","+version+","+cause+" due to "+ex; + } + } + + /** Logs the stack trace of each thread into {@code report}. */ + public static void reportThreadStates(StringBuilder report) { + report.append("\n--- THREAD STATES ---\n"); + final Map traces = Thread.getAllStackTraces(); + for (Thread t : traces.keySet()) { + report.append("thread: "); + report.append(t.getName()); + report.append("\n"); + for (StackTraceElement e : traces.get(t)) { + report.append(e.toString()); + report.append("\n"); + } + report.append("\n"); + } + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/LRUCache.java b/java/foundation/src/org/xtreemfs/foundation/LRUCache.java new file mode 100644 index 0000000..29e936d --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/LRUCache.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008-2010 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * This class implements a LRU cache + * + * @author jmalo + */ +public class LRUCache extends LinkedHashMap { + private static final long serialVersionUID = -4673214355284364245L; + private int maximumSize; + + /** Creates a new instance of LRUCache */ + public LRUCache(int size) { + super(size, (float)0.75, true); + + maximumSize = size; + } + + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > maximumSize; + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/LifeCycleListener.java b/java/foundation/src/org/xtreemfs/foundation/LifeCycleListener.java new file mode 100644 index 0000000..a91914a --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/LifeCycleListener.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2010 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation; + +/** + * Notifies a process of a life cycle event. + * + * @author stender + * + */ +public interface LifeCycleListener { + + public void startupPerformed(); + + public void shutdownPerformed(); + + public void crashPerformed(Throwable cause); + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/LifeCycleThread.java b/java/foundation/src/org/xtreemfs/foundation/LifeCycleThread.java new file mode 100644 index 0000000..8e8bcde --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/LifeCycleThread.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2008-2010 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * A base class for threads representing a life cycle. It offers methods for + * blocking other threads until a certain life cycle event has occurred. It + * currently supports two life cycle-related events: startup and shutdown. + * + * @author stender + * + */ +public class LifeCycleThread extends Thread { + + private final Object startLock; + + private final Object stopLock; + + private boolean started; + + private boolean stopped; + + private Exception exc; + + private LifeCycleListener listener; + + public LifeCycleThread(String name) { + super(name); + startLock = new Object(); + stopLock = new Object(); + } + + /** + * This method should be invoked by subclasses when the startup procedure + * has been completed. + */ + protected void notifyStarted() { + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, "Thread %s started", Thread + .currentThread().getName()); + + synchronized (startLock) { + started = true; + startLock.notifyAll(); + if (listener != null) + listener.startupPerformed(); + } + } + + /** + * This method should be invoked by subclasses when the shutdown procedure + * has been completed. + */ + protected void notifyStopped() { + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, "Thread %s terminated", Thread + .currentThread().getName()); + + synchronized (stopLock) { + stopped = true; + stopLock.notifyAll(); + if (listener != null) + listener.shutdownPerformed(); + } + } + + /** + * This method should be invoked by subclasses when the thread has crashed. + */ + protected void notifyCrashed(Throwable exc) { + + Logging.logMessage(Logging.LEVEL_CRIT, this, "service ***CRASHED***, shutting down"); + Logging.logError(Logging.LEVEL_CRIT, this, exc); + + synchronized (startLock) { + this.exc = exc instanceof Exception ? (Exception) exc : new Exception(exc); + started = true; + startLock.notifyAll(); + } + + synchronized (stopLock) { + this.exc = exc instanceof Exception ? (Exception) exc : new Exception(exc); + stopped = true; + stopLock.notifyAll(); + } + + if (listener != null) + listener.crashPerformed(exc); + } + + /** + * Synchronously waits for a notification indicating that the startup + * procedure has been completed. + * + * @throws Exception + * if an error occurred during the startup procedure + */ + public void waitForStartup() throws Exception { + synchronized (startLock) { + + while (!started) + startLock.wait(); + + if (exc != null && listener == null) + throw exc; + } + } + + /** + * Synchronously waits for a notification indicating that the shutdown + * procedure has been completed. + * + * @throws Exception + * if an error occurred during the shutdown procedure + */ + public void waitForShutdown() throws Exception { + synchronized (stopLock) { + + if (!started) + return; + while (!stopped) + try { + stopLock.wait(); + } catch (InterruptedException e) { + // In case this thread executes notifyCrashed(), he will + // probably interrupt itself. However, this should not + // interfere with the notifyCrashed() procedure and + // therefore we swallow this exception. + if (listener == null) { + throw e; + } + } + + if (exc != null && listener == null) + throw exc; + } + } + + /** + * Terminates the thread. This method should be overridden in subclasses. + * @throws Exception if an error occurred + */ + public void shutdown() throws Exception { + } + + /** + * Sets a listener waiting for life cycle events. + * + * @param listener + * the listener + */ + public void setLifeCycleListener(LifeCycleListener listener) { + this.listener = listener; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/SSLOptions.java b/java/foundation/src/org/xtreemfs/foundation/SSLOptions.java new file mode 100644 index 0000000..4a76bf4 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/SSLOptions.java @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender, Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation; + +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.Security; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; + +/** + * Encapsulates the SSLOptions for the connections of pinky and speedy + * + * @author clorenz + */ +public class SSLOptions { + /** + * a Java JKS Keystore + */ + public final static String JKS_CONTAINER = "JKS"; + + /** + * a PKCS12 Keystore + */ + public final static String PKCS12_CONTAINER = "PKCS12"; + + /** + * Default SSL/TLS Protocol to use when no or an invalid protocol was specified + */ + public final static String DEFAULT_SSL_PROTOCOL = "TLS"; + + /** + * file with the private key and the public cert for the server + */ + private final InputStream serverCredentialFile; + + /** + * file with trusted public certs + */ + private final InputStream trustedCertificatesFile; + + /** + * passphrase of the server credential file + */ + private final char[] serverCredentialFilePassphrase; + + /** + * passphrase of the trusted certificates file + */ + private final char[] trustedCertificatesFilePassphrase; + + /** + * using symmetric encryption or only authenticating via certs + */ + private boolean authenticationWithoutEncryption; + + /** + * file format of the server credential file + */ + private final String serverCredentialFileContainer; + + /** + * file format of the trusted certificates file + */ + private final String trustedCertificatesFileContainer; + + /** + * knows the used certs and more + */ + private final SSLContext sslContext; + + private final boolean useFakeSSLMode; + + public SSLOptions(InputStream serverCredentialFile, String serverCredentialFilePassphrase, + String serverCredentialFileContainer, InputStream trustedCertificatesFile, + String trustedCertificatesFilePassphrase, String trustedCertificatesFileContainer, + boolean authenticationWithoutEncryption, boolean useFakeSSLMode, String sslProtocolString, + TrustManager trustManager) throws IOException { + + this.serverCredentialFile = serverCredentialFile; + this.trustedCertificatesFile = trustedCertificatesFile; + + if (serverCredentialFilePassphrase != null) + this.serverCredentialFilePassphrase = serverCredentialFilePassphrase.toCharArray(); + else + this.serverCredentialFilePassphrase = null; + + if (trustedCertificatesFilePassphrase != null) + this.trustedCertificatesFilePassphrase = trustedCertificatesFilePassphrase.toCharArray(); + else + this.trustedCertificatesFilePassphrase = null; + + this.serverCredentialFileContainer = serverCredentialFileContainer; + this.trustedCertificatesFileContainer = trustedCertificatesFileContainer; + + this.authenticationWithoutEncryption = authenticationWithoutEncryption; + + this.useFakeSSLMode = useFakeSSLMode; + + sslContext = createSSLContext(sslProtocolStringToProtocol(sslProtocolString), trustManager); + } + + /** + * Create/initialize the SSLContext with key material + * + * @param trustManager + * the trust manager for the SSL context (may be + * null) + * @return the created and initialized SSLContext + * @throws IOException + */ + private SSLContext createSSLContext(String sslProtocol, TrustManager trustManager) throws IOException { + SSLContext sslContext = null; + try { + // First initialize the key and trust material. + KeyStore ksKeys = KeyStore.getInstance(serverCredentialFileContainer); + ksKeys.load(serverCredentialFile, serverCredentialFilePassphrase); + + // KeyManager's decide which key material to use. + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ksKeys, serverCredentialFilePassphrase); + + // There are quite a few issues with the OpenJDK PKCS11 provider in combination with NSS, + // so remove it no matter what the OpenJDK version is. + if ("OpenJDK Runtime Environment".equals(System.getProperty("java.runtime.name"))) { + try { + Security.removeProvider("SunPKCS11-NSS"); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Successfully removed faulty security provider 'SunPKCS11-NSS'."); + } + } catch(SecurityException e) { + Logging.logMessage(Logging.LEVEL_WARN, this, + "Could not remove security provider 'SunPKCS11-NSS'. This might cause TLS connections to time out. " + + "Known to affect multiple OpenJDK / NSS version combinations."); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "%s:\n%s", e.getMessage(), OutputUtils.stackTraceToString(e)); + } + } + } + + // Re-enable disabled algorithms if the user requests it. + final String defaultDisabledAlgorithms = Security.getProperty("jdk.tls.disabledAlgorithms"); + removeDisabledEntailedProtocolSupportForProtocol(sslProtocol); + + try { + sslContext = SSLContext.getInstance(sslProtocol); + } catch (NoSuchAlgorithmException e) { + Logging.logMessage(Logging.LEVEL_WARN, this, "Unsupported algorithm '%s', defaulting to '%s'.", + sslProtocol, DEFAULT_SSL_PROTOCOL); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "%s:\n%s", e.getMessage(), OutputUtils.stackTraceToString(e)); + } + + // Reset disabled algorithms because the context could not be created. + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Trying to reset disabled algorithms."); + } + try { + Security.setProperty("jdk.tls.disabledAlgorithms", defaultDisabledAlgorithms); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Successfully reset disabled algorithms."); + } + } catch (SecurityException e1) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Could not reset disabled algorithms: %s", OutputUtils.stackTraceToString(e1)); + } + } + + // Setup everything anew for the default SSL protocol. + removeDisabledEntailedProtocolSupportForProtocol(DEFAULT_SSL_PROTOCOL); + sslContext = SSLContext.getInstance(DEFAULT_SSL_PROTOCOL); + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Disabling the following algorithms: %s", Security.getProperty("jdk.tls.disabledAlgorithms")); + } + + if (trustManager != null) { + // if a user-defined trust manager is set ... + trustManager.init(trustedCertificatesFileContainer, trustedCertificatesFile, + trustedCertificatesFilePassphrase); + sslContext.init(kmf.getKeyManagers(), new TrustManager[] { trustManager }, null); + } else if (trustedCertificatesFileContainer.equals("none")) { + TrustManager[] myTMs = new TrustManager[] { new NoAuthTrustStore() }; + sslContext.init(kmf.getKeyManagers(), myTMs, null); + } else { + + // TrustManager's decide whether to allow connections. + KeyStore ksTrust = null; + if (trustedCertificatesFileContainer.equals("none")) { + ksTrust = KeyStore.getInstance(KeyStore.getDefaultType()); + } else { + ksTrust = KeyStore.getInstance(trustedCertificatesFileContainer); + ksTrust.load(trustedCertificatesFile, trustedCertificatesFilePassphrase); + } + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ksTrust); + + sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + } + } catch (UnrecoverableKeyException e) { + e.printStackTrace(); + } catch (KeyManagementException e) { + e.printStackTrace(); + } catch (KeyStoreException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (CertificateException e) { + e.printStackTrace(); + } + return sslContext; + } + + public boolean isAuthenticationWithoutEncryption() { + return this.authenticationWithoutEncryption; + } + + public void setAuthenticationWithoutEncryption(boolean authenticationWithoutEncryption) { + this.authenticationWithoutEncryption = authenticationWithoutEncryption; + } + + public InputStream getServerCredentialFile() { + return this.serverCredentialFile; + } + + public String getServerCredentialFileContainer() { + return this.serverCredentialFileContainer; + } + + public String getServerCredentialFilePassphrase() { + return this.serverCredentialFilePassphrase.toString(); + } + + public InputStream getTrustedCertificatesFile() { + return this.trustedCertificatesFile; + } + + public String getTrustedCertificatesFileContainer() { + return this.trustedCertificatesFileContainer; + } + + public String getTrustedCertificatesFilePassphrase() { + return this.trustedCertificatesFilePassphrase.toString(); + } + + public SSLContext getSSLContext() { + return this.sslContext; + } + + public boolean isFakeSSLMode() { + return this.useFakeSSLMode; + } + + public String getSSLProtocol() { + return sslContext.getProtocol(); + } + + public boolean isSSLEngineProtocolSupported(String sslEngineProtocol) { + // Protocol names in JDK 5, 6: SSLv2Hello, SSLv3, TLSv1 + // Additionally in JDK 7, 8: TLSv1.2 + // TLSv1.1 seems to depend on the vendor + String sslProtocol = getSSLProtocol(); + if ("SSLv3".equals(sslProtocol)) { + return "SSLv3".equals(sslEngineProtocol); + } else if ("TLS".equals(sslProtocol)) { + return "SSLv3".equals(sslEngineProtocol) || + "TLSv1".equals(sslEngineProtocol) || + "TLSv1.1".equals(sslEngineProtocol) || + "TLSv1.2".equals(sslEngineProtocol); + } else if ("TLSv1".equals(sslProtocol)) { + return "TLSv1".equals(sslEngineProtocol); + } else if ("TLSv1.1".equals(sslProtocol)) { + return "TLSv1.1".equals(sslEngineProtocol); + } else if ("TLSv1.2".equals(sslProtocol)) { + return "TLSv1.2".equals(sslEngineProtocol); + } else { + return false; + } + } + + private String sslProtocolStringToProtocol(String sslProtocolString) { + // SSL Context Protocol Strings: + // JDK 6: SSL, SSLv2, SSLv3, TLS, TLSv1 + // additionally in JDK 7: TLSv1.2 + // TLSv1.1 seems to depend on the vendor + if ("sslv3".equals(sslProtocolString)) { + return "SSLv3"; + } else if ("ssltls".equals(sslProtocolString)) { + return "TLS"; + } else if ("tlsv1".equals(sslProtocolString)) { + return "TLSv1"; + } else if ("tlsv11".equals(sslProtocolString)) { + return "TLSv1.1"; + } else if ("tlsv12".equals(sslProtocolString)) { + return "TLSv1.2"; + } else { + if (sslProtocolString != null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "Unknown SSL Context Protocol: '%s', defaulting to '%s'.", + sslProtocolString, DEFAULT_SSL_PROTOCOL); + } + return DEFAULT_SSL_PROTOCOL; + } + } + + /** + * Removes all protocols that should be supported when using {@code sslProtocol} from the disabled + * algorithms list that is set as system default, e.g. in /usr/lib/jvm/default-java/jre/lib/security/java.security. + * + * @param sslProtocol + */ + private void removeDisabledEntailedProtocolSupportForProtocol(String sslProtocol) { + if (Security.getProperty("jdk.tls.disabledAlgorithms") == null) { + return; // no disabled algorithms, everything is allowed by default + } + + String[] entailedSupportedProtocols = new String[] {}; + if ("SSLv3".equals(sslProtocol)) { + entailedSupportedProtocols = new String[] { "SSLv3" }; + } else if ("TLS".equals(sslProtocol)) { + entailedSupportedProtocols = new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" }; + } else if ("TLSv1".equals(sslProtocol)) { + entailedSupportedProtocols = new String[] { "TLSv1" }; + } else if ("TLSv1.1".equals(sslProtocol)) { + entailedSupportedProtocols = new String[] { "TLSv1.1" }; + } else if ("TLSv1.2".equals(sslProtocol)) { + entailedSupportedProtocols = new String[] { "TLSv1.2" }; + } + + // For each protocol whose support is entailed by the requested protocol, + // remove it from the disabled algorithms list if possible. + for (String supportedSSLProtocol : entailedSupportedProtocols) { + if (Security.getProperty("jdk.tls.disabledAlgorithms").contains(supportedSSLProtocol)) { + Logging.logMessage(Logging.LEVEL_WARN, this, + "Algorithm '%s' is disabled in your java.security configuration file (see key 'jdk.tls.disabledAlgorithms'). " + + "Trying to enable algorithm '%s' manually as specified in your configuration file (see key 'ssl.protocol'). " + + "Consider using a newer SSL/TLS algorithm for your setup, " + + "as algorithm '%s' has been disabled by default because of security issues.", + supportedSSLProtocol, supportedSSLProtocol, supportedSSLProtocol); + try { + Security.setProperty("jdk.tls.disabledAlgorithms", + Security.getProperty("jdk.tls.disabledAlgorithms").replace(supportedSSLProtocol, "").replace(" ", "")); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Successfully removed algorithm '%s' from disabled algorithms.", + supportedSSLProtocol); + } + } catch (SecurityException e) { + Logging.logMessage(Logging.LEVEL_WARN, this, "Could not remove algorithm '%s' from disabled algorithm. " + + "This might cause SSL Handshake exceptions. For SSLv3 this is known to affect all JDKs fixing issue CVE-2014-3566.", + supportedSSLProtocol); + } + } + } + } + + private static class NoAuthTrustStore implements TrustManager, X509TrustManager { + + @Override + public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { + // ignore + } + + @Override + public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { + // ignore + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[] {}; + } + + @Override + public void init(String trustedCertificatesFileContainer, InputStream trustedCertificatesFile, + char[] trustedCertificatesFilePassphrase) { + // ignore + } + + } + + public static interface TrustManager extends javax.net.ssl.TrustManager { + public void init(String trustedCertificatesFileContainer, InputStream trustedCertificatesFile, + char[] trustedCertificatesFilePassphrase); + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/TimeServerClient.java b/java/foundation/src/org/xtreemfs/foundation/TimeServerClient.java new file mode 100644 index 0000000..5fcb2a8 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/TimeServerClient.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010 by Felix Langner, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation; + +import java.net.InetSocketAddress; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; + + +/** + * Provides methods to synchronize with a XtreemFS TimeServer, usually provided + * by a DIR service. + * + * @author flangner + * @since 03/01/2010 + */ + +public interface TimeServerClient { + + /** + * Requests the global time at the given server. + * + * @param server - if null, the default will be used. + * @return a {@link RPCResponse} future for an UNIX time-stamp. + */ + public long xtreemfs_global_time_get(InetSocketAddress server); +} \ No newline at end of file diff --git a/java/foundation/src/org/xtreemfs/foundation/TimeSync.java b/java/foundation/src/org/xtreemfs/foundation/TimeSync.java new file mode 100644 index 0000000..a300af5 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/TimeSync.java @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2008-2010 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.InetSocketAddress; + +import java.net.Socket; +import java.util.Calendar; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * A class that offers a local time w/ adjustable granularity and a global time + * based on the time reported by the DIR. Global time is adjusted periodically. + * This class should be used to minimize the number of calls to + * System.currentTimeMillis which is a costly system call on Linux. Moreover it + * offers a system-global time. + * + * @author bjko + */ +public final class TimeSync extends LifeCycleThread { + + public enum ExtSyncSource { + XTREEMFS_DIR, GPSD, LOCAL_CLOCK + }; + + /** + * The maximum round trip time for a clock synchronization message between + * the TimeSync and the DIR. If the round trip time of a + * synchronization message exceeds this value, the message will be ignored. + */ + private static final int MAX_RTT = 1000; + + /** + * A client used to synchronize clocks + */ + private TimeServerClient timeServerClient; + + /** + * interval in ms to wait between to synchronizations. + */ + private volatile int timeSyncInterval; + + /** + * interval between updates of the local system clock. + * + * If it's set to 0, the local renew by the thread is disabled and the time + * is read from the system on demand. + */ + private volatile int localTimeRenew; + + private volatile ExtSyncSource syncSource; + + private InetSocketAddress gpsdAddr; + + /** + * local sys time as of last update + */ + private volatile long localSysTime; + + /** + * drift between local clock and global time as of last resync() operation. + */ + private volatile long currentDrift; + + /** + * set to true to stop thread + */ + private volatile boolean quit; + + /** + * timestamp of last resync operation + */ + private volatile long lastSuccessfulSync; + + /** + * Timestamp of the last resync attempt. + * + * @note No need to specify it as volatile since it's only used by run(). + */ + private long lastSyncAttempt; + + private volatile int syncRTT; + + private volatile boolean syncSuccess; + + private static TimeSync theInstance; + + private final Pattern gpsdDatePattern; + + private Socket gpsdSocket; + + /** + * Creates a new instance of TimeSync + * + * @dir a directory server to use for synchronizing clocks, can be null for + * test setups only + */ + private TimeSync(ExtSyncSource source, TimeServerClient dir, InetSocketAddress gpsd, int timeSyncInterval, int localTimeRenew) { + super("TSync Thr"); + setDaemon(true); + this.syncSuccess = false; + this.gpsdDatePattern = Pattern.compile("GPSD,D=(....)-(..)-(..)T(..):(..):(..)\\.(.+)Z"); + + init(source, dir, gpsd, timeSyncInterval, localTimeRenew); + } + + /** + * Initializes the TimeSync with new parameters. + * + * @param source + * @param dir + * @param gpsd + * @param timeSyncInterval + * @param localTimeRenew + */ + public synchronized void init(ExtSyncSource source, TimeServerClient dir, InetSocketAddress gpsd, int timeSyncInterval, int localTimeRenew) { + this.localTimeRenew = localTimeRenew; + this.timeSyncInterval = timeSyncInterval; + this.timeServerClient = dir; + this.syncSource = source; + this.gpsdAddr = gpsd; + + if (this.timeServerClient != null && this.timeSyncInterval != 0 && this.localTimeRenew != 0) { + this.localTimeRenew = 0; + Logging.logMessage(Logging.LEVEL_DEBUG, this, + "Disabled the periodic local time renew (set local_clock_renewal to 0)" + + " and using always the current system time as base since the time will be corrected by synchronizing with the DIR service."); + } + + if (source == ExtSyncSource.GPSD) { + try { + if (gpsdSocket != null) + gpsdSocket.close(); + + gpsdSocket = new Socket(); + gpsdSocket.setSoTimeout(2000); + gpsdSocket.setTcpNoDelay(true); + gpsdSocket.connect(gpsdAddr,2000); + } catch (IOException ex) { + Logging.logMessage(Logging.LEVEL_ERROR, this,"cannot connect to GPSd: "+ex); + gpsdSocket = null; + } + } + } + + /** + * main loop + */ + @Override + public void run() { + TimeSync.theInstance = this; + notifyStarted(); + String tsStatus; + if (localTimeRenew == 0) { + tsStatus = "using the local clock"; + } else { + tsStatus = "using the local clock (precision is " + this.localTimeRenew + " ms)"; + } + if (this.timeServerClient != null && timeSyncInterval != 0) { + tsStatus += " and remote sync every " + this.timeSyncInterval + " ms"; + } + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, "TimeSync is running %s", tsStatus); + while (!quit) { + // Renew cached local time. + final long previousLocalSysTime = localSysTime; + localSysTime = System.currentTimeMillis(); + if (localTimeRenew > 0 && previousLocalSysTime != 0) { + final long timeBetweenUpdates = Math.abs(localSysTime - previousLocalSysTime); + if (timeBetweenUpdates > 4 * localTimeRenew) { + Logging.logMessage(Logging.LEVEL_WARN, this, + "The granularity of the renewed local time could not be guaranteed" + + " since it took longer to retrieve the latest local time (%d ms) than configured (local_clock_renewal = %d)." + + " Maybe the system is under high I/O load and therefore scheduling threads takes longer than usual?", + timeBetweenUpdates, + localTimeRenew); + } + } + + // Remote sync time. + if (timeSyncInterval != 0 && localSysTime - lastSyncAttempt > timeSyncInterval) { + resync(); + } + if (!quit) { + // + try { + // If local refresh was disabled, use timeSyncInterval as sleep time. + long sleepTimeMs = localTimeRenew != 0 ? localTimeRenew : timeSyncInterval; + if (sleepTimeMs == 0) { + // If there is no need to run this thread at all, let it sleep for 10 minutes. + sleepTimeMs = 600000; + } + TimeSync.sleep(sleepTimeMs); + } catch (InterruptedException ex) { + break; + } + } + + } + + notifyStopped(); + syncSuccess = false; + theInstance = null; + } + + /** + * Initializes the time synchronizer. Note that only the first invocation of + * this method has an effect, any further invocations will be ignored. + * + * @param dir + * @param timeSyncInterval + * @param localTimeRenew + * @param dirAuthStr + */ + public static TimeSync initialize(TimeServerClient dir, int timeSyncInterval, int localTimeRenew) throws Exception { + + if (theInstance != null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.lifecycle, null, "time sync already running", + new Object[0]); + return theInstance; + } + + TimeSync s = new TimeSync(ExtSyncSource.XTREEMFS_DIR, dir, null, timeSyncInterval, localTimeRenew); + s.start(); + s.waitForStartup(); + return s; + } + + public static TimeSync initializeLocal(int localTimeRenew) { + if (theInstance != null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.lifecycle, null, "time sync already running", + new Object[0]); + return theInstance; + } + + TimeSync s = new TimeSync(ExtSyncSource.LOCAL_CLOCK, null, null, 0, localTimeRenew); + s.start(); + return s; + } + + public static TimeSync initializeGPSD(InetSocketAddress gpsd, int timeSyncInterval, int localTimeRenew) { + if (theInstance != null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.lifecycle, null, "time sync already running", + new Object[0]); + return theInstance; + } + + TimeSync s = new TimeSync(ExtSyncSource.GPSD, null, gpsd, timeSyncInterval, localTimeRenew); + s.start(); + return s; + } + + public void close() { + shutdown(); + try { + waitForShutdown(); + } catch (Exception e) { + Logging.logError(Logging.LEVEL_ERROR, null, e); + } + } + + /** + * stop the thread + */ + public void shutdown() { + quit = true; + this.interrupt(); + if (gpsdSocket != null) { + try { + gpsdSocket.close(); + } catch (IOException ex) { + } + } + } + + /** + * returns the current value of the local system time variable. Has a + * resolution of localTimeRenew ms. + */ + public static long getLocalSystemTime() { + TimeSync ts = getInstance(); + if (ts.localTimeRenew == 0 || ts.localSysTime == 0) { + return System.currentTimeMillis(); + } else { + return ts.localSysTime; + } + } + + /** + * returns the current value of the local system time adjusted to global + * time. Has a resolution of localTimeRenew ms. + */ + public static long getGlobalTime() { + TimeSync ts = getInstance(); + if (ts.localTimeRenew == 0 || ts.localSysTime == 0) { + return System.currentTimeMillis() + ts.currentDrift; + } else { + return ts.localSysTime + ts.currentDrift; + } + } + + public static long getLocalRenewInterval() { + return getInstance().localTimeRenew; + } + + public static int getTimeSyncInterval() { + return getInstance().timeSyncInterval; + } + + public static int getSyncRTT() { + return getInstance().syncRTT; + } + + public static boolean lastSyncWasSuccessful() { + return getInstance().syncSuccess; + } + + + /** + * + * @return the timestamp (local time) when the drift + * was successfully calculated + */ + public static long getLastSuccessfulSyncTimestamp() { + return getInstance().lastSuccessfulSync; + } + /** + * returns the current clock drift. + */ + public long getDrift() { + return this.currentDrift; + } + + /** + * resynchronizes with the global time obtained from the DIR + */ + @SuppressWarnings("deprecation") + private void resync() { + switch (syncSource) { + case LOCAL_CLOCK : return; + case XTREEMFS_DIR : { + try { + long tStart = System.currentTimeMillis(); + lastSyncAttempt = tStart; + long oldDrift = currentDrift; + long globalTime = timeServerClient.xtreemfs_global_time_get(null); + if (globalTime <= 0) { + //error + return; + } + + long tEnd = System.currentTimeMillis(); + // add half a roundtrip to estimate the delay + syncRTT = (int)(tEnd - tStart); + + if (syncRTT > MAX_RTT) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "Ignored time synchronization message because DIR took too long to respond (%d ms)", + syncRTT); + syncSuccess = false; + return; + } + + globalTime += syncRTT / 2; + syncSuccess = true; + + currentDrift = globalTime - tEnd; + lastSuccessfulSync = tEnd; + + if (Math.abs(oldDrift - currentDrift) > 5000 && oldDrift != 0) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, + "STRANGE DRIFT CHANGE from %d to %d", oldDrift, currentDrift); + } + + } catch (Exception ex) { + syncSuccess = false; + ex.printStackTrace(); + } + break; + } + case GPSD : { + try { + + BufferedReader br = new BufferedReader(new InputStreamReader(gpsdSocket.getInputStream())); + OutputStream os = gpsdSocket.getOutputStream(); + long tStart = System.currentTimeMillis(); + lastSyncAttempt = tStart; + + os.write(new byte[]{'d','\n'}); + os.flush(); + + long oldDrift = currentDrift; + String response = br.readLine(); + long tEnd = System.currentTimeMillis(); + + + Matcher m = gpsdDatePattern.matcher(response); + Calendar c = Calendar.getInstance(); + if (m.matches()) { + c.set(Calendar.YEAR, Integer.parseInt(m.group(1))); + c.set(Calendar.MONTH, Integer.parseInt(m.group(2))-1); + c.set(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(3))); + c.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(4))); + c.set(Calendar.MINUTE, Integer.parseInt(m.group(5))); + c.set(Calendar.SECOND, Integer.parseInt(m.group(6))); + //c.set(Calendar.MILLISECOND, Integer.parseInt(m.group(7))*10); + } else { + Logging.logMessage(Logging.LEVEL_WARN, this,"cannot parse GPSd response: %s",response); + syncSuccess = false; + return; + } + + long globalTime = c.getTimeInMillis(); + Date d = new Date(globalTime); + Logging.logMessage(Logging.LEVEL_DEBUG, this,"global GPSd time: %d (%d:%d:%d)",c.getTimeInMillis(),d.getHours(), + d.getMinutes(),d.getSeconds()); + + // add half a roundtrip to estimate the delay + syncRTT = (int)(tEnd - tStart); + Logging.logMessage(Logging.LEVEL_DEBUG, this,"sync RTT: %d ms",syncRTT); + globalTime += syncRTT / 2; + syncSuccess = true; + + currentDrift = globalTime - tEnd; + lastSuccessfulSync = tEnd; + + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "resync success, drift: %d ms", Math.abs(oldDrift-currentDrift)); + + if (Math.abs(oldDrift - currentDrift) > 5000 && oldDrift != 0) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, + "STRANGE DRIFT CHANGE from %d to %d", oldDrift, currentDrift); + } + } catch (Exception ex) { + syncSuccess = false; + ex.printStackTrace(); + } + } + } + } + + public static TimeSync getInstance() { + if (theInstance == null) + throw new RuntimeException("TimeSync not initialized!"); + return theInstance; + } + + public static boolean isInitialized() { + return theInstance != null; + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/VersionManagement.java b/java/foundation/src/org/xtreemfs/foundation/VersionManagement.java new file mode 100644 index 0000000..0a9901d --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/VersionManagement.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2008-2010 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation; + +/** + * This class is meant to maintain version numbers for different components used + * in XtreemFS, in order to be able to detect possible incompatibilities between + * different versions. + * + * When a new version of the protocol, database, etc. has been implemented, the + * corresponding version number should be replaced. XtreemFS will rely on this + * class to find out what the current version numbers are. + * + */ +public class VersionManagement { + + public static final String RELEASE_VERSION = "1.5.1 (Wonderful Waffles)"; + + private static final long mrcDataVersion = 10; + + private static final long osdDataVersion = 1; + + private static final long foundationVersion = 2; + + public static long getMrcDataVersion() { + return mrcDataVersion; + } + + public static long getOsdDataVersion() { + return osdDataVersion; + } + + public static long getFoundationVersion() { + return foundationVersion; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/buffer/ASCIIString.java b/java/foundation/src/org/xtreemfs/foundation/buffer/ASCIIString.java new file mode 100644 index 0000000..775dd2c --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/buffer/ASCIIString.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2010 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.buffer; + +import java.io.Serializable; + +/** + * + * @author bjko + */ +public final class ASCIIString implements Serializable { + private static final long serialVersionUID = 4633232360908659139L; + + private byte[] data; + + private int hash; + + protected ASCIIString() { + + } + + /** + * Creates a new instance of ASCIIString + */ + public ASCIIString(String str) { + this.data = str.getBytes(); + } + + /** + * Creates a new instance of ASCIIString + */ + protected ASCIIString(byte[] data) { + this.data = data; + } + + public String toString() { + return new String(data); + } + + public char charAt(int index) { + + return (char)data[index]; + } + + public boolean equals(Object o) { + if (o == null) return false; + try { + ASCIIString other = (ASCIIString)o; + + if (other.length() != this.length()) + return false; + + for (int i = 0; i < data.length; i++) { + if (data[i] != other.data[i]) + return false; + } + return true; + } catch (ClassCastException ex) { + return false; + } + } + + public void marshall(ReusableBuffer target) { + target.putInt(data.length); + target.put(data); + + } + + public static ASCIIString unmarshall(ReusableBuffer target) { + + int length = target.getInt(); + if (length < 0) + return null; + byte[] tmp = new byte[length]; + + target.get(tmp); + + return new ASCIIString(tmp); + } + + public int hashCode() { + int h = hash; + if (h == 0) { + + for (int i = 0; i < data.length; i++) { + h = 31*h + data[i]; + } + hash = h; + } + return h; + } + + public int length() { + return data.length; + } + + public int getSerializedSize() { + return length()+Integer.SIZE/8; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/buffer/BufferPool.java b/java/foundation/src/org/xtreemfs/foundation/buffer/BufferPool.java new file mode 100644 index 0000000..5d6964c --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/buffer/BufferPool.java @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.buffer; + +import java.nio.ByteBuffer; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/** + * A concurrent pool for buffer recycling. + * + * @author bjko + */ +public final class BufferPool { + + /** + * size of buffers for each class. + */ + public static final int[] BUFF_SIZES = { 8192, 65536, 131072, 524288, + 2097152 }; + + /** + * max pool size for each class + */ + public static final int[] MAX_POOL_SIZES = { 2000, 200, 100, 10, 5 }; + + /** + * queues to store buffers in + */ + private final ConcurrentLinkedQueue[] pools; + + /** + * pool sizes to avoid counting elements on each access + */ + private final AtomicInteger[] poolSizes; + + /** + * stats for num requests and creates of buffers per class + */ + private final AtomicLong[] requests, creates, deletes; + + /** + * singleton pattern. + */ + private static final BufferPool instance = new BufferPool(); + + /** + * if true all allocate/free operations record the stack trace. Useful to + * find memory leaks but slow. + */ + protected static boolean recordStackTraces = false; + + /** + * Creates a new instance of BufferPool + */ + @SuppressWarnings("unchecked") + private BufferPool() { + + pools = new ConcurrentLinkedQueue[BUFF_SIZES.length]; + + creates = new AtomicLong[BUFF_SIZES.length]; + for (int i = 0; i < creates.length; i++) { + creates[i] = new AtomicLong(); + } + + requests = new AtomicLong[BUFF_SIZES.length + 1]; + deletes = new AtomicLong[BUFF_SIZES.length + 1]; + for (int i = 0; i < BUFF_SIZES.length + 1; i++) { + requests[i] = new AtomicLong(); + deletes[i] = new AtomicLong(); + } + + poolSizes = new AtomicInteger[BUFF_SIZES.length]; + for (int i = 0; i < BUFF_SIZES.length; i++) { + pools[i] = new ConcurrentLinkedQueue(); + poolSizes[i] = new AtomicInteger(0); + } + } + + /** + * Get a new buffer. The Buffer is taken from the pool or created if none is + * available or the size exceedes the largest class. + * + * @param size + * the buffer's size in bytes + * @return a buffer of requested size + * @throws OutOfMemoryError + * if a buffer cannot be allocated + */ + public static ReusableBuffer allocate(int size) { + ReusableBuffer tmp = instance.getNewBuffer(size); + assert (tmp.refCount.get() == 1): "newly allocated buffer has invalid reference count: " + tmp.refCount.get(); + + if (recordStackTraces) { + tmp.allocStack = "\n"; + for (StackTraceElement elem : new Exception().getStackTrace()) + tmp.allocStack += elem.toString() + "\n"; + } + return tmp; + } + + /** + * Returns a buffer to the pool, if the buffer is reusable. Other buffers + * are ignored. + * + * @param buf + * the buffer to return + */ + public static void free(ReusableBuffer buf) { + if (buf != null) { + instance.returnBuffer(buf); + } + } + + /** + * Returns a buffer which has at least size bytes. + * + * @attention The returned buffer can be larger than requested! + */ + private ReusableBuffer getNewBuffer(int size) { + + try { + + // if there is a pooled buffer with sufficient capacity ... + for (int i = 0; i < BUFF_SIZES.length; i++) { + + if (size <= BUFF_SIZES[i]) { + + ByteBuffer buf = pools[i].poll(); + + // if no free buffer is available in the pool ... + if (buf == null) { + + // ... create + // - a direct buffer if the pool is not full yet, + // - a non-direct buffer if the pool is full + // + // Thus, the first MAX_POOL_SIZES[i] buffers will be + // pooled, whereas any additional buffers will be + // allocated on demand and freed by the garbage + // collector. + + buf = creates[i].get() < MAX_POOL_SIZES[i] ? ByteBuffer.allocateDirect(BUFF_SIZES[i]) + : ByteBuffer.allocate(BUFF_SIZES[i]); + creates[i].incrementAndGet(); + } + + // otherwise, decrement the pool size to indicate that the + // pooled buffer was handed out to the application + else { + poolSizes[i].decrementAndGet(); + } + + requests[i].incrementAndGet(); + return new ReusableBuffer(buf, size); + + } + + } + + // ... otherwise, create an unpooled buffer + requests[BUFF_SIZES.length].incrementAndGet(); + + ByteBuffer buf = ByteBuffer.allocate(size); + return new ReusableBuffer(buf, size); + + } catch (OutOfMemoryError ex) { + System.out.println(getStatus()); + throw ex; + } + } + + private void returnBuffer(ReusableBuffer buffer) { + returnBuffer(buffer, false); + } + + /** + * return a buffer to the pool + */ + private void returnBuffer(ReusableBuffer buffer, boolean callFromView) { + + if (!buffer.isReusable()) + return; + + if (buffer.viewParent != null) { + + // view buffer + if (recordStackTraces) { + + if (buffer.freeStack == null) + buffer.freeStack = ""; + buffer.freeStack += "\n"; + + StackTraceElement[] stackTrace = new Exception().getStackTrace(); + for (int i = 0; i < stackTrace.length; i++) + buffer.freeStack += stackTrace[i].toString() + "\n"; + } + + assert (!buffer.returned) : "buffer was already released: " + buffer.freeStack; + buffer.returned = true; + returnBuffer(buffer.viewParent, true); + + } else { + + assert (!buffer.returned || callFromView) : "buffer was already released: " + buffer.freeStack; + + if (recordStackTraces) { + + if (buffer.freeStack == null) + buffer.freeStack = ""; + buffer.freeStack += "\n"; + + StackTraceElement[] stackTrace = new Exception().getStackTrace(); + for (int i = 0; i < stackTrace.length; i++) + buffer.freeStack += stackTrace[i].toString() + "\n"; + } + + if (!callFromView) { + buffer.returned = true; + } + + if (buffer.refCount.getAndDecrement() > 1) { + return; + } + + ByteBuffer buf = buffer.getParent(); + buf.clear(); + + // determine the pool to which the buffer is supposed to be + // returned + // ... + for (int i = 0; i < BUFF_SIZES.length; i++) { + + if (buf.capacity() == BUFF_SIZES[i]) { + + // return direct buffers to the pool + if (buf.isDirect()) { + + poolSizes[i].incrementAndGet(); + pools[i].add(buf); + + // since only direct buffers will be returned to the + // pool, which have been counted on allocation, there is + // no need to check the pool size here + + return; + } + + // if the buffer is non-direct, increment the delete counter + // and implicitly make the buffer subject to garbage + // collection + else { + deletes[i].incrementAndGet(); + return; + } + + } + + } + + assert (!buf.isDirect()) : "encountered direct buffer that does not fit in any of the pools (size=" + + buf.capacity() + "): " + buffer.freeStack; + + // if the buffer did not fit in any of the pools, + // increment the delete counter for the unpooled buffers + deletes[deletes.length - 1].incrementAndGet(); + + } + } + + /** + * Get the current pool size for a specific buffer size. + * + * @throws IllegalArgumentException + * when bufferSize is not in the pool + */ + public static int getPoolSize(int bufferSize) { + for (int i = 0; i < BUFF_SIZES.length; i++) { + if (BUFF_SIZES[i] == bufferSize) { + return instance.poolSizes[i].get(); + } + } + throw new IllegalArgumentException("Specified buffer size is not pooled. Check BufferPool configuration."); + } + + /** + * Returns a textual representation of the pool status. + * + * @return a textual representation of the pool status. + */ + public static String getStatus() { + + String str = ""; + for (int i = 0; i < BUFF_SIZES.length; i++) { + str += String.format( + "%8d: poolSize = %5d numRequests = %8d creates = %8d deletes = %8d\n", + BUFF_SIZES[i], instance.poolSizes[i].get(), instance.requests[i].get(), instance.creates[i] + .get(), instance.deletes[i].get()); + } + str += String.format("unpooled (> %8d) numRequests = creates = %8d deletes = %8d", + BUFF_SIZES[BUFF_SIZES.length - 1], instance.requests[instance.requests.length - 1].get(), + instance.deletes[instance.deletes.length - 1].get()); + return str; + } + + /** + * Specifies whether stack traces shall be recorded when allocating and + * freeing buffers. Since recording stack traces leads to some overhead, it + * should only be enabled for debugging purposes. + * + * @param record + */ + public static void enableStackTraceRecording(boolean record) { + recordStackTraces = record; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/buffer/ReusableBuffer.java b/java/foundation/src/org/xtreemfs/foundation/buffer/ReusableBuffer.java new file mode 100644 index 0000000..a36f22d --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/buffer/ReusableBuffer.java @@ -0,0 +1,724 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.buffer; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.util.concurrent.atomic.AtomicInteger; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * + * @author bjko + */ +public final class ReusableBuffer { + + private static final Charset ENC_UTF8 = Charset.forName("utf-8"); + + /** + * A view buffer of parentBuffer with the requested size. For non-reusable + * buffers this is the buffer itself + */ + private ByteBuffer buffer; + + /** + * A parent buffer which is returned to the pool + */ + private final ByteBuffer parentBuffer; + + /** + * True if the buffer can be returned to the pool + */ + private final boolean reusable; + + /** + * set to true after a buffer was returned to the pool + */ + protected volatile boolean returned; + + /** + * size (as requested), might be smaller than parentBuffer size but is + * always equal to the (view) buffer size. + */ + private int size; + + protected ReusableBuffer viewParent; + + protected String freeStack, allocStack; + + /** + * reference count + */ + AtomicInteger refCount; + + /** + * Creates a new instance of ReusableBuffer. A view buffer of size is created. + * + * @param buffer + * the parent buffer + * @param size + * the requested size + */ + protected ReusableBuffer(ByteBuffer buffer, int size) { + buffer.position(0); + buffer.limit(size); + this.buffer = buffer.slice(); + this.parentBuffer = buffer; + this.size = size; + this.reusable = true; + this.refCount = new AtomicInteger(1); + returned = false; + viewParent = null; + } + + /** + * A wrapper for a non-reusable buffer. The buffer is not used by the pool + * when returned. + */ + public ReusableBuffer(ByteBuffer nonManaged) { + this.buffer = nonManaged; + this.size = buffer.limit(); + this.reusable = false; + this.parentBuffer = null; + returned = false; + this.refCount = new AtomicInteger(1); + viewParent = null; + } + + /** + * Creates a non-reusable buffer around a byte array. Uses the + * ByteBuffer.wrap method. + * + * @param data + * the byte arry containing the data + * @return + */ + public static ReusableBuffer wrap(byte[] data) { + return new ReusableBuffer(ByteBuffer.wrap(data)); + } + + public static ReusableBuffer wrap(byte[] data, int offset, int length) { + assert (offset >= 0); + assert (length >= 0); + if (offset + length > data.length) + throw new IllegalArgumentException("offset+length > buffer size (" + offset + "+" + length + + " > " + data.length); + ByteBuffer tmp = ByteBuffer.wrap(data); + tmp.position(offset); + tmp.limit(offset + length); + return new ReusableBuffer(tmp.slice()); + } + + /** + * Creates a new view buffer. This view buffer shares the same data (i.e. + * backing byte buffer) but has independent position, limit etc. + */ + public ReusableBuffer createViewBuffer() { + + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + + if (this.viewParent == null) { + + if (parentBuffer == null) { + // wraped buffers + ReusableBuffer view = new ReusableBuffer(this.buffer.slice()); + view.viewParent = this; + + return view; + + } else { + // regular buffer + ReusableBuffer view = new ReusableBuffer(this.parentBuffer, this.size); + view.viewParent = this; + this.refCount.incrementAndGet(); + + if (BufferPool.recordStackTraces) { + view.allocStack = "\n"; + StackTraceElement[] stackTrace = new Exception().getStackTrace(); + for (int i = 0; i < stackTrace.length; i++) + view.allocStack += stackTrace[i].toString() + (i < stackTrace.length - 1 ? "\n" : ""); + } + + return view; + } + + } else { + + if (parentBuffer == null) { + // wraped buffers + ReusableBuffer view = new ReusableBuffer(this.buffer.slice()); + view.viewParent = this.viewParent; + + return view; + + } else { + // regular buffer: use the parent to create a view buffer + ReusableBuffer view = new ReusableBuffer(this.buffer, this.size); + view.viewParent = this.viewParent; + this.viewParent.refCount.incrementAndGet(); + + if (BufferPool.recordStackTraces) { + view.allocStack = "\n"; + StackTraceElement[] stackTrace = new Exception().getStackTrace(); + for (int i = 0; i < stackTrace.length; i++) + view.allocStack += stackTrace[i].toString() + (i < stackTrace.length - 1 ? "\n" : ""); + } + + return view; + } + } + } + + /** + * @see java.nio.Buffer#capacity + */ + public int capacity() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return this.size; + } + + /** + * May be higher than {@link #capacity()} if the parent buffer is from the {@link BufferPool} which may + * have returned a larger buffer. + */ + public int capacityUnderlying() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return parentBuffer != null ? parentBuffer.capacity() : this.size; + } + + /** + * @see java.nio.ByteBuffer#hasArray + */ + public boolean hasArray() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.hasArray(); + } + + /** + * Returns the byte array of the buffer, creating a copy if the buffer is + * not backed by an array + * + * @return a byte array with a copy of the data + */ + public byte[] array() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + byte[] array = null; + + if (this.hasArray() && (this.viewParent == null)) { + array = buffer.array(); + } else { + array = new byte[this.limit()]; + final int oldPos = this.position(); + this.position(0); + this.get(array); + this.position(oldPos); + } + + return array; + } + + /** + * @see java.nio.Buffer#flip + */ + public void flip() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.flip(); + } + + /** + * @see java.nio.Buffer#compact + */ + public void compact() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.compact(); + } + + /** + * @see java.nio.Buffer#limit(int) + */ + public void limit(int l) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.limit(l); + } + + /** + * @see java.nio.Buffer#limit() + */ + public int limit() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.limit(); + } + + /** + * @see java.nio.Buffer#position(int) + */ + public void position(int p) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.position(p); + } + + /** + * @see java.nio.Buffer#position() + */ + public int position() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.position(); + } + + /** + * @see java.nio.Buffer#hasRemaining + */ + public boolean hasRemaining() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.hasRemaining(); + } + + /** + * Returns the view buffer encapsulated by this ReusableBuffer. + * + * @return the view buffer + */ + public ByteBuffer getBuffer() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return this.buffer; + } + + /** + * Returns true, if this buffer is re-usable and can be returned to the + * pool. + * + * @return true, if this buffer is re-usable + */ + public boolean isReusable() { + // assert(!returned) : + // "Buffer was already freed and cannot be used anymore"+this.freeStack; + return this.reusable; + } + + /** + * Returns the parent buffer. + * + * @return the parent buffer + */ + protected ByteBuffer getParent() { + return this.parentBuffer; + } + + /** + * @see java.nio.ByteBuffer#get() + */ + public byte get() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.get(); + } + + public byte get(int index) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.get(index); + } + + /** + * @see java.nio.ByteBuffer#get(byte[]) + */ + public ReusableBuffer get(byte[] dst) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.get(dst); + return this; + } + + /** + * @see java.nio.ByteBuffer#get(byte[], int offset, int length) + */ + public ReusableBuffer get(byte[] dst, int offset, int length) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.get(dst, offset, length); + return this; + } + + /** + * @see java.nio.ByteBuffer#put(byte) + */ + public ReusableBuffer put(byte b) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.put(b); + return this; + } + + /** + * @see java.nio.ByteBuffer#put(byte[]) + */ + public ReusableBuffer put(byte[] src) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.put(src); + return this; + } + + /** + * @see java.nio.ByteBuffer#put(byte[],int,int) + */ + public ReusableBuffer put(byte[] src, int offset, int len) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.put(src, offset, len); + return this; + } + + /** + * @see java.nio.ByteBuffer#put(ByteBuffer) + */ + public ReusableBuffer put(ByteBuffer src) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.put(src); + return this; + } + + /** + * Writes the content of src into this buffer. + * + * @param src + * the buffer to read from + * @return this ReusableBuffer after reading + * @see java.nio.ByteBuffer#put(ByteBuffer) + */ + public ReusableBuffer put(ReusableBuffer src) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.put(src.buffer); + return this; + } + + /** + * @see java.nio.ByteBuffer#getInt + */ + public int getInt() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.getInt(); + } + + /** + * @see java.nio.ByteBuffer#putInt(int) + */ + public ReusableBuffer putInt(int i) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.putInt(i); + return this; + } + + public long getLong() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.getLong(); + } + + public ReusableBuffer putLong(long l) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.putLong(l); + return this; + } + + public double getDouble() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.getDouble(); + } + + public ReusableBuffer putDouble(double d) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.putDouble(d); + return this; + } + + public String getString() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + int length = buffer.getInt(); + if (length > 0) { + byte[] bytes = new byte[length]; + buffer.get(bytes); + return new String(bytes, ENC_UTF8); + } else if (length == 0) { + return ""; + } else { + return null; + } + } + + public ReusableBuffer putString(String str) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + if (str != null) { + byte[] bytes = str.getBytes(ENC_UTF8); + buffer.putInt(bytes.length); + buffer.put(bytes); + } else { + buffer.putInt(-1); + } + return this; + } + + public ReusableBuffer putShortString(String str) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + assert (str.length() <= Short.MAX_VALUE); + if (str != null) { + byte[] bytes = str.getBytes(ENC_UTF8); + buffer.putShort((short) bytes.length); + buffer.put(bytes); + } else { + buffer.putInt(-1); + } + return this; + } + + public ASCIIString getBufferBackedASCIIString() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return ASCIIString.unmarshall(this); + } + + public ReusableBuffer putBufferBackedASCIIString(ASCIIString str) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + if (str != null) { + str.marshall(this); + } else { + buffer.putInt(-1); + } + return this; + } + + public ReusableBuffer putShort(short s) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.putShort(s); + return this; + } + + public short getShort() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.getShort(); + } + + /** + * @see java.nio.ByteBuffer#isDirect + */ + public boolean isDirect() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.isDirect(); + } + + /** + * @see java.nio.Buffer#remaining + */ + public int remaining() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.remaining(); + } + + /** + * @see java.nio.Buffer#clear + */ + public void clear() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.clear(); + } + + public byte[] getData() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + byte[] array = new byte[this.limit()]; + this.position(0); + this.get(array); + return array; + } + + public void shrink(int newSize) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + if (newSize > size) { + throw new IllegalArgumentException("new size must not be larger than old size"); + } + this.size = newSize; + int oldPos = buffer.position(); + if (oldPos > newSize) + oldPos = 0; + + // save parent position and limit + ByteBuffer originalBuffer; + if (parentBuffer != null) { + originalBuffer = parentBuffer; + } else { + originalBuffer = buffer; + } + int position = originalBuffer.position(); + int limit = originalBuffer.limit(); + + originalBuffer.position(0); + originalBuffer.limit(newSize); + this.buffer = originalBuffer.slice(); + buffer.position(oldPos); + + // restore parent position and limit + originalBuffer.position(position); + originalBuffer.limit(limit); + } + + /* + * Increases the capacity of this buffer. Returns false if {@code newSize} is bigger than the capacity of + * the underlying buffer. + * + * The underlying buffer can be a reusable buffer (parentBuffer != 0) or non-reusable buffer (viewParent + * != 0). + */ + public boolean enlarge(int newSize) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + if (newSize == this.size) { + return true; + } + if (parentBuffer == null && viewParent == null) { + return false; + } + ByteBuffer underlyingBuffer = parentBuffer != null ? parentBuffer : viewParent.getBuffer(); + if (newSize > underlyingBuffer.capacity()) { + return false; + } else { + this.size = newSize; + int oldPos = buffer.position(); + if (oldPos > newSize) + oldPos = 0; + + // save parent position and limit + int position = underlyingBuffer.position(); + int limit = underlyingBuffer.limit(); + + underlyingBuffer.position(0); + underlyingBuffer.limit(newSize); + this.buffer = underlyingBuffer.slice(); + buffer.position(oldPos); + + // restore parent position and limit + underlyingBuffer.position(position); + underlyingBuffer.limit(limit); + + return true; + } + } + + /* + * Sets the new range of the buffer starting from {@code offset} going for {@code length} bytes. + * + * The new position of the buffer will be 0 and the size/capacity will equal {@code length}. + */ + public void range(int offset, int length) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + + // useless call! + if ((offset == 0) && (length == this.size)) + return; + + if (offset >= size) { + throw new IllegalArgumentException("offset must be < size. offset=" + offset + " size=" + size); + } + if (offset + length > size) { + throw new IllegalArgumentException("offset+length must be <= size. size=" + size + " offset=" + + offset + " length=" + length); + } + + this.size = length; + + // save parent position and limit + ByteBuffer originalBuffer; + if (parentBuffer != null) { + originalBuffer = parentBuffer; + } else { + originalBuffer = buffer; + } + int position = originalBuffer.position(); + int limit = originalBuffer.limit(); + + // ensure that the subsequent 'position' does not fail + if (offset > limit) + originalBuffer.limit(offset); + + originalBuffer.position(offset); + originalBuffer.limit(offset + length); + this.buffer = originalBuffer.slice(); + assert (this.buffer.capacity() == length); + + // restore parent position and limit + originalBuffer.position(position); + originalBuffer.limit(limit); + } + + public ReusableBuffer putBoolean(boolean bool) { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + buffer.put(bool ? (byte) 1 : (byte) 0); + return this; + } + + public boolean getBoolean() { + assert (!returned) : "Buffer was already freed and cannot be used anymore" + this.freeStack; + return buffer.get() == 1; + } + + public int getRefCount() { + if (this.viewParent == null) { + return this.refCount.get(); + } else { + return this.viewParent.refCount.get(); + } + } + + @Override + protected void finalize() { + + if (!returned && reusable) { + + Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, + "buffer was finalized but not freed before! buffer = %s, refCount=%d", this.toString(), getRefCount()); + + if (allocStack != null) { + + Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "stacktrace: %s", allocStack); + if (this.viewParent != null) + Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "parent stacktrace: %s", + viewParent.allocStack); + } + + if (freeStack != null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "freed at: %s", freeStack); + } else if (viewParent != null && viewParent.freeStack != null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "freed at: %s", viewParent.freeStack); + } + + if (Logging.isDebug()) { + + byte[] data = new byte[(this.capacity() > 128) ? 128 : this.capacity()]; + this.position(0); + this.limit(this.capacity()); + this.get(data); + String content = new String(data); + + Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "content: %s", content); + + if (this.viewParent != null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "view parent: %s", + this.viewParent.toString()); + Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "ref count: %d", + this.viewParent.refCount.get()); + } else { + Logging.logMessage(Logging.LEVEL_WARN, Category.buffer, this, "ref count: %d", + this.refCount.get()); + } + + } + + BufferPool.free(this); + + } + + } + + @Override + public String toString() { + return "ReusableBuffer( capacity=" + this.capacity() + " limit=" + this.limit() + " position=" + + this.position() + ")"; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumAlgorithm.java b/java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumAlgorithm.java new file mode 100644 index 0000000..d590a78 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumAlgorithm.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.checksums; + +import java.nio.ByteBuffer; + +/** + * An interface which must be implemented by checksum algorithms for XtreemFS. + * + * 19.08.2008 + * + * @author clorenz + */ +public interface ChecksumAlgorithm extends Cloneable { + /** + * Returns a string that identifies the algorithm, independent of + * implementation details. + * + * @return name of algorithm + */ + public String getName(); + + /** + * Returns checksum value (as Hex-String) and resets the Algorithm. + * + * @return checksum + */ + public long getValue(); + + /** + * Resets checksum to initial value. + * + * @return + */ + public void reset(); + + /** + * Updates checksum with specified data. + * + * @param data + */ + public void update(ByteBuffer data); + + /** + * returns a new instance of the checksum algorithm + * + * @return + */ + public ChecksumAlgorithm clone(); +} diff --git a/java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumFactory.java b/java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumFactory.java new file mode 100644 index 0000000..2cb4418 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumFactory.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.checksums; + +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.concurrent.ConcurrentLinkedQueue; + +/** + * A Factory for getting checksum algorithms from checksum provider. Implemented + * as a Singleton. + * + * 19.08.2008 + * + * @author clorenz + */ +public class ChecksumFactory { + /** + * amount of cached instances/algorithm + */ + private static int MAX_CACHE_SIZE = 20; + + private static ChecksumFactory self; + + /** + * Contains all available checksum algorithms (only one instance). + */ + private HashMap algorithms; + + /** + * Contains all known checksum provider + */ + private HashMap knownProvider; + + /** + * Contains cached instances for all available checksum algorithms. + */ + private HashMap> pool; + + /** + * creates a new ChecksumFactory + */ + private ChecksumFactory() { + super(); + this.algorithms = new HashMap(); + this.pool = new HashMap>(); + this.knownProvider = new HashMap(); + } + + /** + * Get the instance of ChecksumFactory. + * + * @return the instance + */ + public static ChecksumFactory getInstance() { + if (self == null) { + self = new ChecksumFactory(); + } + return self; + } + + /** + * Get an instance of a specific checksum algorithm, if supported. + * + * @param name + * of the algorithm + * @return algorithm object or null, if algorithm is not supported + */ + public ChecksumAlgorithm getAlgorithm(String name) + throws NoSuchAlgorithmException { + ConcurrentLinkedQueue cache = pool.get(name); + if (cache == null) + throw new NoSuchAlgorithmException("algorithm " + name + + " not supported"); + + ChecksumAlgorithm algorithm = cache.poll(); + if (algorithm == null) { // cache is empty + return algorithms.get(name).clone(); // create new instance + } else { + return algorithm; // return caches instance + } + } + + /** + * Returns an instance of a specific checksum algorithm for caching. + * + * @param instance + * of the algorithm + */ + public void returnAlgorithm(ChecksumAlgorithm algorithm) { + ConcurrentLinkedQueue cache = pool.get(algorithm + .getName()); + if (cache.size() < MAX_CACHE_SIZE) { + algorithm.reset(); + cache.add(algorithm); + } + } + + /** + * Adds a new provider to factory and adds all supported algorithms from the + * provider to the algorithms-list. NOTE: Existing algorithms will be + * overridden when the new provider contains the same algorithm (maybe + * another implementation). + * + * @param provider + */ + public void addProvider(ChecksumProvider provider) { + knownProvider.put(provider.getName(), provider); + for (ChecksumAlgorithm algorithm : provider.getSupportedAlgorithms()) { + addAlgorithm(algorithm); + } + } + + /** + * Adds a new Algorithm to factory. NOTE: The same existing algorithm will + * be overridden. + * + * @param algorithm + */ + public void addAlgorithm(ChecksumAlgorithm algorithm) { + algorithms.put(algorithm.getName(), algorithm); + pool.put(algorithm.getName(), + new ConcurrentLinkedQueue()); + } + + /** + * Removes a provider, but not the added algorithms. + * + * @param provider + */ + public void removeProvider(ChecksumProvider provider) { + knownProvider.remove(provider.getName()); + } + + /** + * Removes an algorithm. + * + * @param algorithm + */ + public void removeAlgorithm(String algorithm) { + algorithms.remove(algorithm); + pool.remove(algorithm); + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumProvider.java b/java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumProvider.java new file mode 100644 index 0000000..2256898 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/checksums/ChecksumProvider.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.checksums; + +import java.util.Collection; +import java.util.HashMap; + +/** + * An abstract class which must be implemented by a checksum provider for + * XtreemFS. + * + * 19.08.2008 + * + * @author clorenz + */ +public abstract class ChecksumProvider { + /** + * contains the supported algorithms + */ + protected HashMap algorithms; + + protected ChecksumProvider() { + super(); + this.algorithms = new HashMap(); + } + + /** + * Returns the name of the provider. + * + * @return name + */ + public abstract String getName(); + + /** + * Returns all from this provider supported checksum algorithms. + * + * @return a collection with ChecksumAlgorithms + */ + public Collection getSupportedAlgorithms() { + return algorithms.values(); + } + + /** + * adds an algorithm to the map + * + * @param newAlgorithm + */ + protected void addAlgorithm(ChecksumAlgorithm newAlgorithm) { + this.algorithms.put(newAlgorithm.getName(), newAlgorithm); + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/checksums/StringChecksumAlgorithm.java b/java/foundation/src/org/xtreemfs/foundation/checksums/StringChecksumAlgorithm.java new file mode 100644 index 0000000..5b1243d --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/checksums/StringChecksumAlgorithm.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.checksums; + +/** + * An interface for checksum algorithms, which are based on computations on + * strings. + * + * 02.09.2008 + * + * @author clorenz + */ +public interface StringChecksumAlgorithm extends ChecksumAlgorithm { + /** + * Updates checksum with specified data. + * + * @param data + */ + public void digest(String data); +} diff --git a/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/Adler32.java b/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/Adler32.java new file mode 100644 index 0000000..41823ed --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/Adler32.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.checksums.algorithms; + +/** + * The Adler32 algorithm. It uses the Java internal implementation. + * + * 19.08.2008 + * + * @author clorenz + */ +@SuppressWarnings("unchecked") +public class Adler32 extends JavaChecksumAlgorithm { + + public Adler32() { + super(new java.util.zip.Adler32(), "Adler32"); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.checksum.ChecksumAlgorithm#clone() + */ + @Override + public Adler32 clone() { + return new Adler32(); + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/CRC32.java b/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/CRC32.java new file mode 100644 index 0000000..11b637d --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/CRC32.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.checksums.algorithms; + +/** + * The CRC32 algorithm. It uses the Java internal implementation. + * + * 19.08.2008 + * + * @author clorenz + */ +@SuppressWarnings("unchecked") +public class CRC32 extends JavaChecksumAlgorithm { + + public CRC32() { + super(new java.util.zip.CRC32(), "CRC32"); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.checksum.ChecksumAlgorithm#clone() + */ + @Override + public CRC32 clone() { + return new CRC32(); + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/JavaChecksumAlgorithm.java b/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/JavaChecksumAlgorithm.java new file mode 100644 index 0000000..ede5203 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/JavaChecksumAlgorithm.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.checksums.algorithms; + +import java.nio.ByteBuffer; +import java.util.zip.Checksum; + +import org.xtreemfs.foundation.checksums.ChecksumAlgorithm; + +/** + * An abstract wrapper for Java internal checksums. + * + * 19.08.2008 + * + * @author clorenz + */ +abstract public class JavaChecksumAlgorithm + implements ChecksumAlgorithm { + /** + * the class, which really implements the selected algorithm + */ + protected RealJavaAlgorithm realAlgorithm; + + protected String name; + + public JavaChecksumAlgorithm(RealJavaAlgorithm realAlgorithm, String name) { + super(); + this.realAlgorithm = realAlgorithm; + this.name = name; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.checksum.ChecksumAlgorithm#digest(java.nio.ByteBuffer) + */ + @Override + public void update(ByteBuffer data) { + byte[] array; + + if (data.hasArray()) { + array = data.array(); + } else { + array = new byte[data.capacity()]; + final int oldPos = data.position(); + data.position(0); + data.get(array); + data.position(oldPos); + } + + realAlgorithm.update(array, 0, array.length); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.checksum.ChecksumAlgorithm#getName() + */ + @Override + public String getName() { + return name; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.checksum.ChecksumAlgorithm#getValue() + */ + @Override + public long getValue() { + final long tmp = realAlgorithm.getValue(); + realAlgorithm.reset(); + return tmp; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.checksum.ChecksumAlgorithm#reset() + */ + @Override + public void reset() { + realAlgorithm.reset(); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.checksum.ChecksumAlgorithm#clone() + */ + @Override + public abstract JavaChecksumAlgorithm clone(); +} diff --git a/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/JavaHash.java b/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/JavaHash.java new file mode 100644 index 0000000..d913e1c --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/JavaHash.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.checksums.algorithms; + +import java.nio.ByteBuffer; + +import org.xtreemfs.foundation.checksums.StringChecksumAlgorithm; + +/** + * The Java algorithm, which is used for string.hashCode(). It uses the Java + * internal implementation. + * + * 02.09.2008 + * + * @author clorenz + */ +public class JavaHash implements StringChecksumAlgorithm { + private Long hash = null; + + private String name = "Java-Hash"; + + /** + * Updates checksum with specified data. + * + * @param data + */ + public void digest(String data) { + this.hash = Long.valueOf(data.hashCode()); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#digest(java.nio.ByteBuffer) + */ + @Override + public void update(ByteBuffer data) { + byte[] array; + + if (data.hasArray()) { + array = data.array(); + } else { + array = new byte[data.capacity()]; + final int oldPos = data.position(); + data.position(0); + data.get(array); + data.position(oldPos); + } + + this.hash = (long)new String(array).hashCode(); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#getName() + */ + @Override + public String getName() { + return this.name; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#getValue() + */ + @Override + public long getValue() { + long value; + if (this.hash != null) + value = this.hash; + else + value = 0; + reset(); + return value; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#reset() + */ + @Override + public void reset() { + hash = null; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.checksum.ChecksumAlgorithm#clone() + */ + @Override + public JavaHash clone() { + return new JavaHash(); + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/SDBM.java b/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/SDBM.java new file mode 100644 index 0000000..e97e404 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/checksums/algorithms/SDBM.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.checksums.algorithms; + +import java.nio.ByteBuffer; + +import org.xtreemfs.foundation.checksums.StringChecksumAlgorithm; + +/** + * The SDBM algorithm. + * + * 02.09.2008 + * + * @author clorenz + */ +public class SDBM implements StringChecksumAlgorithm { + private Long hash = null; + + private String name = "SDBM"; + + /** + * Updates checksum with specified data. + * + * @param data + */ + public void digest(String data) { + this.hash = sdbmHash(data); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#digest(java.nio.ByteBuffer) + */ + @Override + public void update(ByteBuffer data) { + byte[] array; + + if (data.hasArray()) { + array = data.array(); + } else { + array = new byte[data.capacity()]; + final int oldPos = data.position(); + data.position(0); + data.get(array); + data.position(oldPos); + } + + this.hash = sdbmHash(new String(array)); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#getName() + */ + @Override + public String getName() { + return this.name; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#getValue() + */ + @Override + public long getValue() { + long value; + if (this.hash != null) + value = this.hash; + else + value = 0; + reset(); + return value; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.foundation.checksums.ChecksumAlgorithm#reset() + */ + @Override + public void reset() { + hash = null; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.checksum.ChecksumAlgorithm#clone() + */ + @Override + public SDBM clone() { + return new SDBM(); + } + + /** + * SDBM algorithm + * + * @param str + * @return + */ + protected static long sdbmHash(String str) { + long hash = 0; + for (int c : str.toCharArray()) { + hash = c + (hash << 6) + (hash << 16) - hash; + } + return hash; + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/checksums/provider/JavaChecksumProvider.java b/java/foundation/src/org/xtreemfs/foundation/checksums/provider/JavaChecksumProvider.java new file mode 100644 index 0000000..904bc53 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/checksums/provider/JavaChecksumProvider.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.checksums.provider; + +import org.xtreemfs.foundation.checksums.ChecksumProvider; + +/** + * A provider for Java internal checksums. offers the following algorithms: + * Adler32, CRC32, MD5, Java-Hash + * + * 19.08.2008 + * + * @author clorenz + */ +public class JavaChecksumProvider extends ChecksumProvider { + private static String NAME = "Java Checksum Provider"; + + /** + * creates a new JavaChecksumProvider + */ + public JavaChecksumProvider() { + super(); + + addAlgorithm(new org.xtreemfs.foundation.checksums.algorithms.Adler32()); + addAlgorithm(new org.xtreemfs.foundation.checksums.algorithms.CRC32()); + /*try { + addAlgorithm(new org.xtreemfs.foundation.checksums.algorithms.JavaMessageDigestAlgorithm( + "MD5", "MD5")); + addAlgorithm(new org.xtreemfs.foundation.checksums.algorithms.JavaMessageDigestAlgorithm( + "SHA1", "SHA-1")); + } catch (NoSuchAlgorithmException e) { + Logging.logMessage(Logging.LEVEL_WARN, this, e.getMessage() + + " in your java-installation"); + }*/ + addAlgorithm(new org.xtreemfs.foundation.checksums.algorithms.JavaHash()); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.foundation.checksums.ChecksumProvider#getName() + */ + @Override + public String getName() { + return NAME; + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/json/JSONCharBufferString.java b/java/foundation/src/org/xtreemfs/foundation/json/JSONCharBufferString.java new file mode 100644 index 0000000..9d0aa3c --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/json/JSONCharBufferString.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.json; + +import java.nio.BufferUnderflowException; +import java.nio.CharBuffer; + +/** + * + * @author bjko + */ +public class JSONCharBufferString implements JSONInput { + + CharBuffer cb; + + /** Creates a new instance of JSONCharBufferString */ + public JSONCharBufferString(CharBuffer cb) { + assert (cb != null); + + this.cb = cb; + this.cb.position(0); + } + + public char read() throws JSONException { + try { + return cb.get(); + } catch(BufferUnderflowException ex) { + throw new JSONException("Reached end of buffer"); + } + } + + public int skip(int skip) { + try { + + cb.position(cb.position()+skip); + + return skip; + + } catch (IllegalArgumentException e) { + return 0; + } + + } + + public String toString() { + return "JSONCharBufferString backed by "+cb.toString(); + } + + public boolean hasMore() { + return cb.hasRemaining(); + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/json/JSONException.java b/java/foundation/src/org/xtreemfs/foundation/json/JSONException.java new file mode 100644 index 0000000..63af94e --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/json/JSONException.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.json; + +/** + * Thrown by the JSON parser and writer. + * + * @author bjko + */ +public class JSONException extends java.lang.Exception { + + /***/ + private static final long serialVersionUID = 2422241603599209392L; + + /** + * Creates a new instance of JSONException without detail + * message. + */ + public JSONException() { + } + + /** + * Constructs an instance of JSONException with the specified + * detail message. + * + * @param msg + * the detail message. + */ + public JSONException(String msg) { + super(msg); + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/json/JSONInput.java b/java/foundation/src/org/xtreemfs/foundation/json/JSONInput.java new file mode 100644 index 0000000..f4872ce --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/json/JSONInput.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.json; + +/** + * + * @author bjko + */ +public interface JSONInput { + + + /** + * reads a single char + * + * @return the character at the current position is returned + */ + public char read() throws JSONException; + + /** + * It checks if there are more characters + */ + public boolean hasMore(); + + /** + * Skips skip characters + * + * @param skip + * num characters to skip + * @return the number of characters skipped + */ + public int skip(int skip); + + /** + * Get a string representation. + * + * @return A string representation of the this JSONString. + */ + public String toString(); + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/json/JSONParser.java b/java/foundation/src/org/xtreemfs/foundation/json/JSONParser.java new file mode 100644 index 0000000..7a6781d --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/json/JSONParser.java @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.json; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * JSON Parser routines. This parser accepts any value as top level element, not + * just an object or array. + * + * @author bjko + */ +public class JSONParser { + + /** + * Creates a new instance of JSONParser + */ + public JSONParser() { + } + + private static String parseString(JSONInput input) throws JSONException { + + boolean nonEscaped = true; + StringBuilder str = new StringBuilder(); + + while (input.hasMore()) { + char ch = input.read(); + + if (nonEscaped) { + if (ch == '\\') { + nonEscaped = false; + continue; + } + else if (ch == '"') { + return str.toString(); + } + else { + str.append(ch); + } + } + else { + if (ch == 'n') { + str.append('\n'); + } else if (ch == 'r') { + str.append('\r'); + } else if (ch == 't') { + str.append('\t'); + } else { + str.append(ch); + } + } + + nonEscaped = true; + } + + throw new JSONException("[ E | JSONParser ] Unexpected end while parsing string"); + + } + + private static Object parseNumber(JSONInput input) throws JSONException { + + StringBuilder str = new StringBuilder(); + input.skip(-1); + + boolean isFP = false; + + while (input.hasMore()) { + char ch = input.read(); + + if ((ch == '-') || (ch >= '0') && (ch <= '9')) { + str.append(ch); + } else if ((ch == '.') || (ch == 'E') || (ch == 'e')) { + str.append(ch); + isFP = true; + } else { + input.skip(-1); + if (isFP) + return new BigDecimal(str.toString()); + else + return Long.valueOf(str.toString()); + } + } + + if (isFP) + return new BigDecimal(str.toString()); + else + return Long.valueOf(str.toString()); + } + + private static Object parseArray(JSONInput input) throws JSONException { + LinkedList arr = new LinkedList(); + + while (input.hasMore()) { + char ch = input.read(); + + if (ch == ']') { + return arr; + } else if (ch == ',') { + arr.add(parseJSON(input)); + } else if ((ch == ' ') || (ch == '\t')) { + continue; + } else { + input.skip(-1); + arr.add(parseJSON(input)); + } + } + + throw new JSONException("[ E | JSONParser ] Unexpected end while parsing array"); + } + + private static Object parseObject(JSONInput input) throws JSONException { + + HashMap map = new HashMap(); + while (input.hasMore()) { + char ch = input.read(); + + if (ch == '}') { + return map; + } + // skip all ws + if ((ch == ' ') || (ch == '\t')) { + continue; + } + + String name = parseString(input); + ch = input.read(); + + while ((ch == ' ') || (ch == '\t')) { + ch = input.read(); + } + + if (ch != ':') { + throw new JSONException("[ E | JSONParser ] Unexpected token '" + + ((char) ch) + "' or EOF. Expected : in Object."); + } + + while ((ch == ' ') || (ch == '\t')) { + ch = input.read(); + } + + Object value = parseJSON(input); + map.put(name, value); + ch = input.read(); + + while ((ch == ' ') || (ch == '\t')) { + ch = input.read(); + } + + if (ch == '}') { + return map; + } + if (ch != ',') { + throw new JSONException("[ E | JSONParser ] Unexpected token '" + + ((char) ch) + "' or EOF. Expected , or } in Object."); + } + } + + throw new JSONException("[ E | JSONParser ] Unexpected end while parsing object"); + } + + /** + * Parses a JSON message. + * + * @return the objects encoded in input. + * @attention This routine may cause a StackOverflow exception when parsing + * incorrect, very deep or maliciously malformed JSON messages. + * @param input + * the JSON string + * @throws org.xtreemos.wp34.mrc.utils.JSONException + * if input is not valid JSON + */ + public static Object parseJSON(JSONInput input) throws JSONException { + + while (input.hasMore()) { + char ch = input.read(); + + if (ch == '[') { + return parseArray(input); + } else if (ch == '{') { + return parseObject(input); + } else if (ch == '"') { + return parseString(input); + } else if ((ch == '-') || ((ch >= '0') && (ch <= '9'))) { + return parseNumber(input); + } else if (ch == 't') { + input.skip(3); + return Boolean.valueOf(true); + } else if (ch == 'f') { + input.skip(4); + return Boolean.valueOf(false); + } else if (ch == 'n') { + input.skip(3); + return null; + } else if ((ch == ' ') || (ch == '\t')) { + continue; + } else { + throw new JSONException("[ E | JSONParser ] Unexpected token '" + + ((char) ch) + "' expected Object, Array or Value."); + } + } + + throw new JSONException("[ E | JSONParser ] Unexpected end while parsing root element"); + } + + /** + * Creates a JSON encoded message from an object. Can handle Boolean, + * Integer, Long, BigDecimal, List and Map. + * + * @param input + * object to encode, objects can be nested. + * @return a JSON encoded message + * @throws org.xtreemos.wp34.mrc.utils.JSONException + * if there are one or more objects it cannot encode + */ + public static String writeJSON(Object input) throws JSONException { + return writeJSON(input,new StringBuilder()).toString(); + } + + /** + * Creates a JSON encoded message from an object. Can handle Boolean, + * Integer, Long, BigDecimal, List and Map. + * + * @param input + * object to encode, objects can be nested. + * @return a JSON encoded message + * @throws org.xtreemos.wp34.mrc.utils.JSONException + * if there are one or more objects it cannot encode + */ + @SuppressWarnings("unchecked") + public static StringBuilder writeJSON(Object input, StringBuilder result) throws JSONException { + + if (input == null) { + return result.append("null"); + } else if (input instanceof Boolean) { + return result.append(((Boolean) input).booleanValue() ? "true" : "false"); + } else if (input instanceof BigDecimal) { + return result.append(((BigDecimal) input).toString()); + } else if (input instanceof Integer) { + return result.append((Integer) input); + } else if (input instanceof Long) { + return result.append((Long) input); + } else if (input instanceof String) { + return writeJSONString(input,result); + } else if (input instanceof Map) { + return writeJSONObject(input,result); + } else if (input instanceof Collection) { + return writeJSONArray(input,result); + } else { + throw new JSONException( + "[ E | JSONParser ] Unexpected Object type: " + + input.getClass().getName()); + } + } + + @SuppressWarnings("unchecked") + private static StringBuilder writeJSONObject(Object input, StringBuilder result) throws JSONException { + Map map = (Map) input; + result.append("{"); + int i = 1; + for (Object key : map.keySet()) { + writeJSONString(key.toString(),result); + result.append(":"); + writeJSON(map.get(key),result); + if (i < map.size()) + result.append(","); + i++; + } + return result.append("}"); + } + + @SuppressWarnings("unchecked") + private static StringBuilder writeJSONArray(Object input, StringBuilder result) throws JSONException { + Collection arr = (Collection) input; + result.append("["); + int i = 1; + for (Object obj : arr) { + writeJSON(obj,result); + if (i < arr.size()) + result.append(","); + i++; + } + return result.append("]"); + } + + private static StringBuilder writeJSONString(Object input, StringBuilder result) { + /* + * This is 10 times faster than using str.replace + */ + final String str = input.toString(); + result.append("\""); + for (int i = 0; i < str.length(); i++) { + char ch = str.charAt(i); + + switch (ch) { + case '\n' : result.append("\\n"); break; + case '\r' : result.append("\\r"); break; + case '\t' : result.append("\\t"); break; + case '"' : result.append("\\\""); break; + case '\\' : result.append("\\\\"); break; + case '/' : result.append("\\/"); break; + default: result.append(ch); + } + } + result.append("\""); + return result; + } + + + public static String toJSON(Object... args) throws JSONException { + List argList = new ArrayList(args.length); + for (Object arg : args) + argList.add(arg); + + return writeJSON(argList); + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/json/JSONString.java b/java/foundation/src/org/xtreemfs/foundation/json/JSONString.java new file mode 100644 index 0000000..6bc5f1b --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/json/JSONString.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2008-2010 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.json; + + +/** + * This class is necessary because the StringReader cannot skip back once the + * end is reached. + * + * @author bjko + */ +public class JSONString implements JSONInput { + + String str; + + int position; + + /** + * Creates a new instance of JSONString + * + * @param str + * the JSON message + */ + public JSONString(String str) { + this.str = str; + position = 0; + } + + /** + * reads a single char + * + * @return the character at the current position is returned + */ + public char read() throws JSONException { + try { + return str.charAt(position++); + } + catch (StringIndexOutOfBoundsException ex) { + throw new JSONException("Reach the end of the string"); + } + } + + /** + */ + public boolean hasMore() { + return position < str.length(); + } + + + /** + * Skips skip characters + * + * @param skip + * num characters to skip + * @return the number of characters skipped + */ + public int skip(int skip) { + if (((position + skip) < 0) || ((position + skip) >= str.length())) { + return 0; + } else { + position = position + skip; + return skip; + } + } + + /** + * Get a string representation. + * + * @return A string representation of the this JSONString. + */ + public String toString() { + return "JSONString pos=" + position + " str=" + str; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/logging/Logging.java b/java/foundation/src/org/xtreemfs/foundation/logging/Logging.java new file mode 100644 index 0000000..b0ca18d --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/logging/Logging.java @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2008-2010 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.logging; + +import java.io.PrintStream; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * + * @author bjko + */ +public class Logging { + + public enum Category { + /** + * enable logging for all categories (no real category) + */ + all, + /** + * logs messages pertaining to buffers + */ + buffer, + /** + * log messaages pertaining to service lifecycles (threads) + */ + lifecycle, + /** + * network-related log messages + */ + net, + /** + * authorization-related log messages + */ + auth, + /** + * log messages pertaining to the request flow through the stages + */ + stage, + /** + * log messages pertaining to any kind of request processing + */ + proc, + /** + * + */ + misc, + /** + * log messages pertaining storage on OSD or database access on MRC/DIR + */ + storage, + /** + * logs messages pertaining to replication + */ + replication, + /** + * logs messages from additional tools + */ + tool, + /** + * logs messages from tests + */ + test + } + + protected static final char ABBREV_LEVEL_INFO = 'I'; + + protected static final char ABBREV_LEVEL_DEBUG = 'D'; + + protected static final char ABBREV_LEVEL_WARN = 'W'; + + protected static final char ABBREV_LEVEL_ERROR = 'E'; + + protected static final char ABBREV_LEVEL_TRACE = 'T'; + + public static final int LEVEL_EMERG = 0; + + public static final int LEVEL_ALERT = 1; + + public static final int LEVEL_CRIT = 2; + + public static final int LEVEL_ERROR = 3; + + public static final int LEVEL_WARN = 4; + + public static final int LEVEL_NOTICE = 5; + + public static final int LEVEL_INFO = 6; + + public static final int LEVEL_DEBUG = 7; + + public static final String FORMAT_PATTERN = "[ %c | %-20s | %-15s | %3d | %15s ] %s"; + + private static PrintStream out = System.out; + + protected static Logging instance; + + protected static boolean tracingEnabled = false; + + private final int level; + + private final int catMask; + + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd HH:mm:ss"); + + /** + * Creates a new instance of Logging + */ + private Logging(int level, int catMask) { + + if (level < 0) + this.level = 0; + else + this.level = level; + + this.catMask = catMask; + + instance = this; + + System.currentTimeMillis(); + } + + public static void redirect(PrintStream out) { + Logging.out = out; + } + + public static String truncateString(String string, int maxLength) { + return (string.length() > maxLength) ? + (string.substring(0, maxLength - 3) + "...") : string; + } + + public static void logMessage(int level, Category cat, Object me, String formatPattern, Object... args) { + checkIfInitializedOrThrow(); + + // if the level is appropriate as well as the category, or the category + // is 'all', log the message + if (level <= instance.level && (cat == Category.all || (2 << cat.ordinal() & instance.catMask) > 0)) { + + char levelName = getLevelName(level); + + out.println(String.format(FORMAT_PATTERN, levelName, + me == null ? "-" : truncateString(me instanceof Class ? ((Class) me).getSimpleName(): me.getClass().getSimpleName(), 20), + truncateString(Thread.currentThread().getName(), 15), + Thread.currentThread().getId(), + getTimeStamp(), + String.format(formatPattern, args))); + } + } + + private static void checkIfInitializedOrThrow() { + if (instance == null) { + throw new RuntimeException( + "Cannot log message because the logging is not initialized yet. Did you forget to call Logging.start(...) in your code?"); + } + } + + public static void logMessage(int level, Object me, String formatPattern, Object... args) { + logMessage(level, Category.all, me, formatPattern, args); + } + + public static void logError(int level, Object me, Throwable msg) { + checkIfInitializedOrThrow(); + + // if the level is appropriate, log the message + if (level <= instance.level) { + + char levelName = getLevelName(level); + + out.println(String.format(FORMAT_PATTERN, levelName, + me == null ? "-" : (me instanceof Class ? ((Class) me).getSimpleName(): me.getClass().getSimpleName()), + Thread.currentThread().getName(), Thread.currentThread().getId(), + getTimeStamp(), msg.toString())); + for (StackTraceElement elem : msg.getStackTrace()) { + out.println(" ... " + elem.toString()); + } + if (msg.getCause() != null) { + out.println(String.format(FORMAT_PATTERN, levelName, me == null ? "-" : me.getClass() + .getSimpleName(), Thread.currentThread().getName(), Thread.currentThread().getId(), + getTimeStamp(), "root cause: " + msg.getCause())); + for (StackTraceElement elem : msg.getCause().getStackTrace()) { + out.println(" ... " + elem.toString()); + } + } + } + } + + public static void logUserError(int level, Category cat, Object me, Throwable msg) { + checkIfInitializedOrThrow(); + + // if the level is appropriate as well as the category, or the category + // is 'all', log the message + if (level <= instance.level && (cat == Category.all || (2 << cat.ordinal() & instance.catMask) > 0)) { + + char levelName = getLevelName(level); + + out.println(String.format(FORMAT_PATTERN, levelName, me == null ? "-" : me.getClass() + .getSimpleName(), Thread.currentThread().getName(), Thread.currentThread().getId(), + getTimeStamp(), msg.toString())); + for (StackTraceElement elem : msg.getStackTrace()) { + out.println(" ... " + elem.toString()); + } + } + } + + public static char getLevelName(int level) { + switch (level) { + case LEVEL_EMERG: + case LEVEL_ALERT: + case LEVEL_CRIT: + case LEVEL_ERROR: + return ABBREV_LEVEL_ERROR; + case LEVEL_WARN: + return ABBREV_LEVEL_WARN; + case LEVEL_NOTICE: + case LEVEL_INFO: + return ABBREV_LEVEL_INFO; + case LEVEL_DEBUG: + return ABBREV_LEVEL_DEBUG; + default: + return '?'; + } + } + + public synchronized static void start(int level, Category... categories) { + if (instance == null) { + + int catMask = 0; + for (Category cat : categories) { + + if (cat == Category.all) + catMask = -1; + + catMask |= 2 << cat.ordinal(); + } + + if(categories.length == 0) + catMask = -1; + + instance = new Logging(level, catMask); + } + } + + public static boolean isDebug() { + if (instance == null) + return false; + else + return instance.level >= LEVEL_DEBUG; + } + + public static boolean isInfo() { + if (instance == null) + return false; + else + return instance.level >= LEVEL_INFO; + } + + public static boolean isNotice() { + if (instance == null) + return false; + else + return instance.level >= LEVEL_NOTICE; + } + + private static String getTimeStamp() { + return dateFormat.format(new Date()); + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/logging/Utils.java b/java/foundation/src/org/xtreemfs/foundation/logging/Utils.java new file mode 100644 index 0000000..411839f --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/logging/Utils.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2008-2010 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.logging; + +/** + * + * @author bjko + */ +public class Utils { + + public static final char LEVEL_INFO = 'I'; + public static final char LEVEL_DEBUG = 'D'; + public static final char LEVEL_WARN = 'W'; + public static final char LEVEL_ERROR = 'E'; + + + public static void logMessage(char level, Object me, String msg) { + if (me == null) { + System.out.println(String.format("[ %c | %-20s | %3d ] %s", + level,"?",Thread.currentThread().getId(), + msg)); + } else { + System.out.println(String.format("[ %c | %-20s | %3d ] %s", + level,me.getClass().getSimpleName(),Thread.currentThread().getId(), + msg)); + } + } + + /** Creates a new instance of Utils */ + public Utils() { + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/monitoring/ListMonitoring.java b/java/foundation/src/org/xtreemfs/foundation/monitoring/ListMonitoring.java new file mode 100644 index 0000000..1d62146 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/monitoring/ListMonitoring.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2009-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.monitoring; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * The class provides the ability to monitor data. It could monitor multiple data for each key.
+ * NOTE: This class is thread-safe.
+ * 22.07.2009 + */ +public class ListMonitoring extends Monitoring> { +} diff --git a/java/foundation/src/org/xtreemfs/foundation/monitoring/Monitoring.java b/java/foundation/src/org/xtreemfs/foundation/monitoring/Monitoring.java new file mode 100644 index 0000000..d7a2317 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/monitoring/Monitoring.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2009-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.monitoring; + +import java.util.List; +import java.util.Set; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * The class provides the ability to monitor data. The data must be added via push (put-method). For getting the + * contained data poll (get-method) and push (via listeners) is supported.
+ * NOTE: This class is thread-safe.
+ * 22.07.2009 + */ +public class Monitoring { + /** + * contains the monitored data + */ + protected ConcurrentHashMap datasets; + + /** + * contains the registered listeners + */ + protected ConcurrentHashMap>> listeners; + + /** + * + */ + public Monitoring() { + datasets = new ConcurrentHashMap(); + listeners = new ConcurrentHashMap>>(); + } + + /** + * Adds the value to the given key and overwrites the old value. Notifies all associated listeners. + * + * @param key + * @param value + * @return + * @see java.util.HashMap#put(java.lang.Object, java.lang.Object) + */ + public V put(String key, V value) { + assert (key != null && value != null); + + V oldValue = datasets.put(key, value); + + // check if listeners are registered + if (listeners.containsKey(key)) { + MonitoringEvent event = new MonitoringEvent(this, key, value); + for (MonitoringListener listener : listeners.get(key)) + listener.valueAddedOrChanged(event); + } + return oldValue; + } + + /** + * @param key + * @return + * @see java.util.HashMap#get(java.lang.Object) + */ + public V get(String key) { + return datasets.get(key); + } + + /** + * @param key + * @return + * @see java.util.HashMap#containsKey(java.lang.Object) + */ + public boolean containsKey(String key) { + return datasets.containsKey(key); + } + + /** + * @return + * @see java.util.HashMap#entrySet() + */ + public Set> entrySet() { + return datasets.entrySet(); + } + + /** + * @param key + * @return + * @see java.util.HashMap#remove(java.lang.Object) + */ + public V remove(String key) { + return datasets.remove(key); + } + + /** + * @return + * @see java.util.HashMap#size() + */ + public int size() { + return datasets.size(); + } + + /** + * @return + * @see java.util.AbstractMap#toString() + */ + public String toString() { + return datasets.toString(); + } + + /** + * Registers a listener for the specified key. If the value of the key changes, the associated listeners + * will be notified. + * + * @param key + * @param listener + */ + public void registerListener(String key, MonitoringListener listener) { + List> list = listeners.get(key); + if (list == null) { + list = new CopyOnWriteArrayList>(); + listeners.put(key, list); + } + list.add(listener); + } + + /** + * Unregisters the given listener for the given key. + * + * @param key + * @param listener + */ + public void unregisterListener(String key, MonitoringListener listener) { + List> list = listeners.get(key); + if (list != null) { + int index = list.indexOf(listener); + if (index != -1) + list.remove(index); + } + } + + /* + * system-wide stuff + */ + private static boolean monitoringEnabled = false; + + /** + * enables monitoring for the whole system + */ + public static void enable() { + monitoringEnabled = true; + } + + /** + * @return the monitoringEnabled + */ + public static boolean isEnabled() { + return monitoringEnabled; + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringEvent.java b/java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringEvent.java new file mode 100644 index 0000000..fc211a2 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringEvent.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2009-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.monitoring; + +import java.util.EventObject; + +/** + * An event which is created, when a value has changed. It piggybacks the key and new value, too.
+ * 22.07.2009 + */ +public class MonitoringEvent extends EventObject { + private static final long serialVersionUID = 1L; + + /** + * the key of the changed value + */ + String key; + /** + * the changed value + */ + V newValue; + + /** + * Creates a new instance of this class. + * + * @param source + * @param key + * @param newValue + */ + public MonitoringEvent(Object source, String key, V newValue) { + super(source); + this.key = key; + this.newValue = newValue; + } + + /** + * @return the key + */ + public String getKey() { + return key; + } + + /** + * @return the value + */ + public V getNewValue() { + return newValue; + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringListener.java b/java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringListener.java new file mode 100644 index 0000000..1bac4f3 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringListener.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2009-2010, Konrad-Zuse-Zentrum fuer Informationstechnik Berlin + * + * All rights reserved. + * + * 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 the Konrad-Zuse-Zentrum fuer Informationstechnik Berlin + * 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 HOLDER 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. + */ +/* + * AUTHORS: Christian Lorenz (ZIB) + */ +package org.xtreemfs.foundation.monitoring; + +import java.util.EventListener; + +/** + * A simple listener for notification, if the value of the target has changed.
+ * 22.07.2009 + */ +public interface MonitoringListener extends EventListener { + /** + * Invoked when a value of the monitored data has changed. + * + * @param event + */ + public void valueAddedOrChanged(MonitoringEvent event); +} diff --git a/java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringLog.java b/java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringLog.java new file mode 100644 index 0000000..85f4c38 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/monitoring/MonitoringLog.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2009-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.monitoring; + +import java.io.IOException; + +/** + * + *
+ * 17.08.2009 + */ +public class MonitoringLog implements MonitoringListener { + private static MonitoringLog instance; + + private long monitoringStartTime; + + public static synchronized void initialize(String filepath) throws IOException { + if (instance == null) { + instance = new MonitoringLog(); + + instance.monitoringStartTime = System.currentTimeMillis(); + + // file to write to + // (new File(filepath)).getParentFile().mkdirs(); + // instance.out = new FileWriter(filepath); + } + } + + @Override + public void valueAddedOrChanged(MonitoringEvent event) { + monitor(event.getKey(), event.getNewValue().toString()); + } + + public static synchronized void monitor(String key, String value) { + long time = (System.currentTimeMillis() - instance.monitoringStartTime) / 1000; + System.out.println("[" + time + "s]\t" + key + "\t:\t" + value); + } + + @SuppressWarnings("unchecked") + public static void registerFor(Monitoring monitoring, String... keys) { + for (String key : keys) + monitoring.registerListener(key, instance); + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/monitoring/NumberMonitoring.java b/java/foundation/src/org/xtreemfs/foundation/monitoring/NumberMonitoring.java new file mode 100644 index 0000000..3e512ac --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/monitoring/NumberMonitoring.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2009-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.monitoring; + +/** + * The class provides the ability to monitor numeric data. It also provides methods some methods for special + * cases than only overwriting the old value.
+ * NOTE: This class is thread-safe.
+ * 22.07.2009 + */ +public class NumberMonitoring extends Monitoring { + /** + * Saves the value only if the new value is smaller than the old one. + * + * @param key + * @param value + * @return + */ + public Double putSmaller(String key, Double value) { + Double oldValue = super.get(key); + if (oldValue != null) { + if (oldValue > value) + return super.put(key, value); + else + return value; + } else + return super.put(key, value); + } + + /** + * Saves the value only if the new value is larger than the old one. + * + * @param key + * @param value + * @return + */ + public Double putLarger(String key, Double value) { + Double oldValue = super.get(key); + if (oldValue != null) { + if (oldValue < value) + return super.put(key, value); + else + return value; + } else + return super.put(key, value); + } + + /** + * Saves the average of the old and new value. + * + * @param key + * @param value + * @return + */ + public Double putAverage(String key, Double value) { + Double oldValue = super.get(key); + if (oldValue != null) { + return super.put(key, (oldValue + value) / 2); + } else + return super.put(key, value); + } + + /** + * Increases the old value about new value. + * + * @param key + * @param value + * @return + */ + public Double putIncreaseFor(String key, Double value) { + Double oldValue = super.get(key); + if (oldValue != null) { + return super.put(key, oldValue + value); + } else + return super.put(key, value); + } + + /** + * Decreases the old value about new value. + * + * @param key + * @param value + * @return + */ + public Double putDecreaseFor(String key, Double value) { + Double oldValue = super.get(key); + if (oldValue != null) { + return super.put(key, oldValue - value); + } else + return super.put(key, value); + } + + /** + * Special method for Longs. + * + * @see org.xtreemfs.foundation.monitoring.Monitoring#put(java.lang.String, java.lang.Object) + * @param key + * @param value + * @return + */ + public Long putLong(String key, Long value) { + Double oldValue = super.put(key, value.doubleValue()); + return (oldValue == null) ? null : oldValue.longValue(); + } + + /** + * Special method for Longs. Saves the value only if the new value is smaller than the old one. + * + * @see org.xtreemfs.foundation.monitoring.NumberMonitoring#putSmaller(java.lang.String, java.lang.Double) + * @param key + * @param value + * @return + */ + public Long putSmallerLong(String key, Long value) { + Double oldValue = this.putSmaller(key, value.doubleValue()); + return (oldValue == null) ? null : oldValue.longValue(); + } + + /** + * Special method for Longs. Saves the value only if the new value is larger than the old one. + * + * @see org.xtreemfs.foundation.monitoring.NumberMonitoring#putLarger(java.lang.String, java.lang.Double) + * @param key + * @param value + * @return + */ + public Long putLargerLong(String key, Long value) { + Double oldValue = this.putLarger(key, value.doubleValue()); + return (oldValue == null) ? null : oldValue.longValue(); + } + + /** + * Special method for Longs. Saves the average of the old and new value. + * + * @param key + * @param value + * @return + */ + public Long putAverageLong(String key, Long value) { + Double oldValue = super.get(key); + if (oldValue != null) { + this.put(key, (oldValue + value) / 2d).longValue(); + return oldValue.longValue(); + } else + return this.putLong(key, value); + } + + /** + * Increases the old value about new value. + * + * @param key + * @param value + * @return + */ + public Long putIncreaseForLong(String key, Long value) { + Double oldValue = this.putIncreaseFor(key, value.doubleValue()); + return (oldValue == null) ? null : oldValue.longValue(); + } + + /** + * Decreases the old value about new value. + * + * @param key + * @param value + * @return + */ + public Long putDecreaseForLong(String key, Long value) { + Double oldValue = this.putDecreaseFor(key, value.doubleValue()); + return (oldValue == null) ? null : oldValue.longValue(); + } + + /** + * + * @param key + * @return + */ + public Long getLong(String key) { + Double value = super.get(key); + return (value == null) ? null : value.longValue(); + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/Schemes.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/Schemes.java new file mode 100644 index 0000000..521594b --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/Schemes.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc; + +/** + * + * @author bjko + */ +public class Schemes { + + public static final String SCHEME_PBRPC = "pbrpc"; + public static final String SCHEME_PBRPCG = "pbrpcg"; + public static final String SCHEME_PBRPCS = "pbrpcs"; + public static final String SCHEME_PBRPCU = "pbrpcu"; + + public static String getScheme(boolean sslEnabled, boolean gridSSL) { + if (sslEnabled) { + if (gridSSL) { + return SCHEME_PBRPCG; + } else { + return SCHEME_PBRPCS; + } + } else { + return SCHEME_PBRPC; + } + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/ChannelIO.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/ChannelIO.java new file mode 100644 index 0000000..c40dfd1 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/ChannelIO.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.channels; + +import java.io.IOException; +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.NotYetConnectedException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.SocketChannel; +import java.security.cert.Certificate; + +/** + * A abstraction of the SocketChannel + * + * @author clorenz + */ +public class ChannelIO { + + protected final SocketChannel channel; + + protected Certificate[] certs; + + protected Object attachment; + + public ChannelIO(SocketChannel channel) { + this.channel = channel; + this.certs = null; + attachment = null; + } + + public SelectableChannel configureBlocking(boolean block) + throws IOException { + return channel.configureBlocking(block); + } + + public boolean connect(SocketAddress remote) throws IOException { + return this.channel.connect(remote); + } + + public void close() throws IOException { + channel.socket().close(); + channel.close(); + } + + public boolean isBlocking() { + return channel.isBlocking(); + } + + public boolean isOpen() { + return channel.isOpen(); + } + + public SelectionKey keyFor(Selector sel) { + return channel.keyFor(sel); + } + + public int read(ByteBuffer dst) throws IOException, NotYetConnectedException { + return channel.read(dst); + } + + public SelectionKey register(Selector sel, int ops, Object att) + throws ClosedChannelException { + return channel.register(sel, ops, att); + } + + public Socket socket() { + return channel.socket(); + } + + public String toString() { + return channel.toString(); + } + + public int validOps() { + return channel.validOps(); + } + + public int write(ByteBuffer src) throws IOException, NotYetConnectedException { + return channel.write(src); + } + + public long write(ByteBuffer[] src) throws IOException, NotYetConnectedException { + return channel.write(src); + } + + public boolean finishConnect() throws IOException { + return this.channel.finishConnect(); + } + + public boolean isConnectionPending() { + return this.channel.isConnectionPending(); + } + + /** + * does the handshake if needed + * @param key + * @return true, if handshake is completed + * @throws IOException + */ + public boolean doHandshake(SelectionKey key) throws IOException { + return true; + } + + /** + * prepares the channel for closing + * this can take more than 1 call + * @param key + * @return true, if channel is ready for closing + * @throws IOException + */ + public boolean shutdown(SelectionKey key) throws IOException { + return true; + } + + /** + * is channel in closing-procedure? + * @return + */ + public boolean isShutdownInProgress() { + return false; + } + + /** + * is there remaining data in channel-buffers, which must be flushed? + * @return + */ + public boolean isFlushed() { + return true; + } + + public Certificate[] getCerts() { + return certs; + } + + public Object getAttachment() { + return attachment; + } + + public void setAttachment(Object attachment) { + this.attachment = attachment; + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/SSLChannelIO.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/SSLChannelIO.java new file mode 100644 index 0000000..6c0bf2f --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/SSLChannelIO.java @@ -0,0 +1,768 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.channels; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; +import javax.net.ssl.SSLEngineResult.HandshakeStatus; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLPeerUnverifiedException; + +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; + +/** + * A secure abstraction of the SocketChannel (by using SSL) + * + * @author clorenz + */ +public class SSLChannelIO extends ChannelIO { + + /** + * Number of Threads in the ThreadPool which will be used for the + * time-consuming tasks + */ + // public static int EXECUTOR_THREADS = 4; + /** + * used SSLEngine for this channel + */ + protected final SSLEngine sslEngine; + + /** + * contains the read data encrypted by ssl + */ + protected ReusableBuffer inNetBuffer, inReadBuffer; + + /** + * contains the written data encrypted by ssl + */ + protected ReusableBuffer outNetBuffer; + + /** + * an empty buffer for e.g. handshaking and shutdown; it will never contain + * data + */ + protected ReusableBuffer dummyBuffer; + + /** + * the last SSLEngine-status + */ + protected HandshakeStatus handshakeStatus; + + protected boolean handshakeComplete; + + protected int keyOpsBeforeHandshake = -1; + + /** + * true, if shutdown was called at least one time + */ + protected boolean shutdownInProgress; + + /** + * cipher suites without symmetric encryption, wich are supported by the + * SSLEngine in Java6 + */ + protected static String[] supportedCipherSuitesWithoutEncryption = null; + + /** + * SSL-Channel is used by client + */ + protected boolean clientMode; + + /** + * for asynchronious execution of time-consuming tasks only one executor for + * ALL SSLChannelIOs + */ + // private static ExecutorService executor = null; + private boolean closed = false; + + private boolean shutdownComplete = false; + + /** + * creates a SSLChannelIO + * + * @param channel + * channel, which should be protected by SSL + * @param sslOptions + * the Options for the SSL-Connection + * @param clientMode + * true, if you are a client; false, if you are a server + * @throws SSLException + */ + public SSLChannelIO(SocketChannel channel, SSLOptions sslOptions, boolean clientMode) throws SSLException { + super(channel); + // initialize SSLEngine for a server + sslEngine = sslOptions.getSSLContext().createSSLEngine(); + sslEngine.setUseClientMode(clientMode); + sslEngine.setNeedClientAuth(true); + + List enabledProtocols = new ArrayList(); + for (String protocol : sslEngine.getSupportedProtocols()) { + if (sslOptions.isSSLEngineProtocolSupported(protocol) && !enabledProtocols.contains(protocol)) { + enabledProtocols.add(protocol); + } + } + + String[] enabledProtocolsArray = enabledProtocols.toArray(new String[enabledProtocols.size()]); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Enabling the following protocols: %s", + Arrays.toString(enabledProtocolsArray)); + } + sslEngine.setEnabledProtocols(enabledProtocolsArray); + + if (clientMode) { + // the first call for a client is wrap() + sslEngine.beginHandshake(); + handshakeStatus = HandshakeStatus.NEED_WRAP; + } else { + // the first call for a server is unwrap() + sslEngine.beginHandshake(); + handshakeStatus = HandshakeStatus.NEED_UNWRAP; + } + + handshakeComplete = false; + shutdownInProgress = false; + + int netBufSize = sslEngine.getSession().getPacketBufferSize(); + inNetBuffer = BufferPool.allocate(netBufSize); + inReadBuffer = BufferPool.allocate(sslEngine.getSession().getApplicationBufferSize() * 2); + outNetBuffer = BufferPool.allocate(netBufSize); + dummyBuffer = BufferPool.allocate(netBufSize); + + + if (sslOptions.isAuthenticationWithoutEncryption()) { // only + // authentication + // without + // protecting + // data? + // enable only cipher suites without encryption + + if (supportedCipherSuitesWithoutEncryption == null) { // runs only + // first time + // a + // SSLChannelIO + // without Encryption is created + // find all supported cipher suites without symmetric encryption + ArrayList cipherSuites = new ArrayList(); + for (String cipherSuite : sslEngine.getSupportedCipherSuites()) { + if (cipherSuite.contains("WITH_NULL")) { + cipherSuites.add(cipherSuite); + } + } + supportedCipherSuitesWithoutEncryption = new String[cipherSuites.size()]; + supportedCipherSuitesWithoutEncryption = cipherSuites + .toArray(supportedCipherSuitesWithoutEncryption); + } + sslEngine.setEnabledCipherSuites(supportedCipherSuitesWithoutEncryption); + } else // enable all supported cipher suites + { + sslEngine.setEnabledCipherSuites(sslEngine.getSupportedCipherSuites()); + } + + // only initialize the first time an SSLChannelIO is created + /* + * if(executor==null) executor = + * Executors.newFixedThreadPool(EXECUTOR_THREADS); + */ + } + + /** + * {@inheritDoc} + */ + @Override + public int read(ByteBuffer dst) throws IOException { + int returnValue = 0; + if (!shutdownInProgress) { + if (handshakeComplete) { + if (inReadBuffer.remaining() == inReadBuffer.capacity()) { + if (channel.read(inNetBuffer.getBuffer()) == -1) { + return -1; + } + inNetBuffer.flip(); // ready for being read + inDataAvail: while (inNetBuffer.hasRemaining()) { + SSLEngineResult result = sslEngine.unwrap(inNetBuffer.getBuffer(), inReadBuffer + .getBuffer()); + + switch (result.getStatus()) { + case OK: { + // returnValue += result.bytesProduced(); + // FIXME: if client does't close the connection + // after receiving close_notify => + // decomment it + if (sslEngine.isInboundDone()) // received + // close_notify + { + close(); + } + break; + } + case BUFFER_UNDERFLOW: { + // needed more data in inNetBuffer, maybe nexttime + // inNetBuffer.compact(); + break inDataAvail; + // return returnValue; + } + case BUFFER_OVERFLOW: { + // needed more space in dst + throw new IOException( + "BufferOverflow in the SSLEngine: Destination-Buffer is too small."); + } + case CLOSED: { + throw new IOException("The SSLEngine is already closed."); + } + default: { + throw new IOException("The SSLEngine is in an undefined state."); + } + } + } + inNetBuffer.compact(); // ready for reading from channel + } + inReadBuffer.flip(); + if (dst.remaining() >= inReadBuffer.remaining()) { + returnValue += inReadBuffer.remaining(); + dst.put(inReadBuffer.getBuffer()); + } else { + while (inReadBuffer.hasRemaining() && dst.hasRemaining()) { + dst.put(inReadBuffer.get()); + returnValue++; + } + } + inReadBuffer.compact(); + } + } + return returnValue; + } + + /** + * {@inheritDoc} warning: maybe more bytes would be consumed from src-buffer + * than will be written to channel (returned value) + */ + @Override + public int write(ByteBuffer src) throws IOException { + int returnValue = 0; + if (!shutdownInProgress) { + if (handshakeComplete) { + SSLEngineResult result = sslEngine.wrap(src, outNetBuffer.getBuffer()); + outNetBuffer.flip(); // ready for writing to channel + + switch (result.getStatus()) { + case OK: { + tryFlush(); + + break; + } + case BUFFER_OVERFLOW: { + // needed more space in outNetBuffer + // two reasons for overflow: + // 1. buffer is too small + // 2. buffer is nearly full + tryFlush(); + /* + * throw new IOException( + * "BufferOverflow in SSLEngine. Buffer for SSLEngine-generated data is too small." + * ); + */ + break; + } + case CLOSED: { + throw new IOException("The SSLEngine is already closed."); + } + default: { + throw new IOException("The SSLEngine is in a curiuos state."); + } + } + returnValue = result.bytesConsumed(); + } + } + return returnValue; + } + + /** + * {@inheritDoc} + */ + /** + * {@inheritDoc} warning: maybe more bytes would be consumed from src-buffer + * than will be written to channel (returned value) + */ + @Override + public long write(ByteBuffer[] src) throws IOException { + int returnValue = 0; + if (!shutdownInProgress) { + if (handshakeComplete) { + SSLEngineResult result = sslEngine.wrap(src, outNetBuffer.getBuffer()); + outNetBuffer.flip(); // ready for writing to channel + + switch (result.getStatus()) { + case OK: { + tryFlush(); + + break; + } + case BUFFER_OVERFLOW: { + // needed more space in outNetBuffer + // two reasons for overflow: + // 1. buffer is too small + // 2. buffer is nearly full + tryFlush(); + /* + * throw new IOException( + * "BufferOverflow in SSLEngine. Buffer for SSLEngine-generated data is too small." + * ); + */ + break; + } + case CLOSED: { + throw new IOException("The SSLEngine is already closed."); + } + default: { + throw new IOException("The SSLEngine is in a curiuos state."); + } + } + returnValue = result.bytesConsumed(); + } + } + return returnValue; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isShutdownInProgress() { + return this.shutdownInProgress; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean shutdown(SelectionKey key) throws IOException, CancelledKeyException { + if (!handshakeComplete) { // no SSL connection is established => simple + // close + shutdownInProgress = true; + return true; + } + + if (shutdownComplete) { + return shutdownComplete; + } + + if (!shutdownInProgress) { // initiate shutdown + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "shutdown SSL connection of %s:%d", channel.socket().getInetAddress().toString(), channel + .socket().getPort()); + + sslEngine.closeOutbound(); + shutdownInProgress = true; + key.interestOps(key.interestOps() & ~SelectionKey.OP_READ); // don't + // wait + // for + // the + // close_notify-reply + } + + outNetBuffer.flip(); // ready for writing to channel + if (tryFlush() && sslEngine.isOutboundDone()) { // shutdown complete + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + shutdownComplete = true; + } + + if (!sslEngine.isOutboundDone()) { + // Get close message + SSLEngineResult result = sslEngine.wrap(dummyBuffer.getBuffer(), outNetBuffer.getBuffer()); + outNetBuffer.flip(); // ready for writing to channel + switch (result.getStatus()) { + case OK: { + throw new IOException("This should not happen."); + } + case BUFFER_OVERFLOW: { + // needed more space in outNetBuffer + // two reasons for overflow: + // 1. buffer is too small + // 2. buffer is nearly full + tryFlush(); + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + /* + * throw new IOException( + * "BufferOverflow in SSLEngine. Buffer for SSLEngine-generated data is too small." + * ); + */ + break; + } + case CLOSED: { + if (tryFlush() && sslEngine.isOutboundDone()) { + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + shutdownComplete = true; + } else { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + } + break; + } + default: { + throw new IOException("The SSLEngine is in a curiuos state."); + } + } + } + return shutdownComplete; + } + + /** + * {@inheritDoc} + */ + @Override + public void close() throws IOException { + try { + super.close(); + try { + sslEngine.closeInbound(); + sslEngine.closeOutbound(); + } catch (SSLException e) { + // ignore it + } + // free buffers + BufferPool.free(inNetBuffer); + inNetBuffer = null; + BufferPool.free(inReadBuffer); + inReadBuffer = null; + BufferPool.free(outNetBuffer); + BufferPool.free(dummyBuffer); + shutdownInProgress = true; + closed = true; + } catch (Throwable th) { + System.out.println("CANNOT CLOSE DUE TO: " + th); + throw new IOException(th); + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void finalize() { + if (inNetBuffer != null) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, "buffers not freed!"); + BufferPool.free(inNetBuffer); + inNetBuffer = null; + BufferPool.free(outNetBuffer); + BufferPool.free(dummyBuffer); + } + if (!closed) { + System.out.println("CONNECTION WAS NOT CLOSED PROPERLY: " + this); + } + } + + /** + * Writes the outNetBuffer-data to the channel. After write, the buffer is + * empty or ready for add new data + * + * @return true, if write was successful; false, if buffer is not empty + * @throws IOException + */ + protected boolean tryFlush() throws IOException { + // if (outNetBuffer.hasRemaining()) { // flush the buffer + channel.write(outNetBuffer.getBuffer()); + if (outNetBuffer.hasRemaining()) { + outNetBuffer.compact(); + return false; + } else { + outNetBuffer.compact(); + } + // } + return true; + } + + /** + * {@inheritDoc} warning: the function manipulates the SelectionKey Ops, so + * don't do anything in your programm beetween first call of this function + * until the function returns true + */ + @Override + public boolean doHandshake(SelectionKey key) throws IOException, CancelledKeyException { + if (handshakeComplete || shutdownInProgress) { // quick return + return handshakeComplete; + } + + if (keyOpsBeforeHandshake == -1) { + keyOpsBeforeHandshake = key.interestOps(); + key.interestOps(key.interestOps() & ~SelectionKey.OP_READ & ~SelectionKey.OP_WRITE); + } + + if (!handshakeComplete) { + // Logging.logMessage(Logging.LEVEL_DEBUG, this, + // "SSL-handshake next step: "+handshakeStatus); + + SSLEngineResult result; + switch (handshakeStatus) { + case NEED_UNWRAP: { + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + if (channel.read(inNetBuffer.getBuffer()) == -1) { + throw new IOException("End of stream has reached."); + } + + boolean underflow = false; + do { // read all read data in buffer + // Logging.logMessage(Logging.LEVEL_DEBUG, this, + // "SSL-handshake doing: unwrap"); + inNetBuffer.flip(); // ready for being read + result = sslEngine.unwrap(inNetBuffer.getBuffer(), dummyBuffer.getBuffer()); + inNetBuffer.compact(); // ready for reading from channel + + handshakeStatus = result.getHandshakeStatus(); + switch (result.getStatus()) { + case OK: { + analyseHandshakeStatus(key, handshakeStatus); + break; + } + case BUFFER_UNDERFLOW: { + // needed more data in inNetBuffer, maybe nexttime + underflow = true; + key.interestOps(key.interestOps() | SelectionKey.OP_READ); + break; + } + case CLOSED: { + throw new IOException("The SSLEngine is already closed."); + } + default: { + throw new IOException("The SSLEngine is in a curiuos state."); + } + } + } while (bufferRemaining(inNetBuffer) != 0 && handshakeStatus == HandshakeStatus.NEED_UNWRAP + && !underflow); + break; + } + case NEED_WRAP: { + key.interestOps(key.interestOps() & ~SelectionKey.OP_READ); + // Logging.logMessage(Logging.LEVEL_DEBUG, this, + // "SSL-handshake doing: wrap"); + + result = sslEngine.wrap(dummyBuffer.getBuffer(), outNetBuffer.getBuffer()); + outNetBuffer.flip(); // ready for writing to channel + + handshakeStatus = result.getHandshakeStatus(); + switch (result.getStatus()) { + case OK: { + tryFlush(); + + analyseHandshakeStatus(key, handshakeStatus); + break; + } + case BUFFER_OVERFLOW: { + // needed more space in outNetBuffer + // two reasons for overflow: + // 1. buffer is too small + // 2. buffer is nearly full + tryFlush(); + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + /* + * throw new IOException( + * "BufferOverflow in SSLEngine. Buffer for SSLEngine-generated data is too small." + * ); + */ + break; + } + case CLOSED: { + throw new IOException("The SSLEngine is already closed."); + } + default: { + throw new IOException("The SSLEngine is in a curiuos state."); + } + } + break; + } + case FINISHED: { + outNetBuffer.flip(); // ready for writing to channel + if (tryFlush()) { + handshakeFinished(key); + } else { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + } + break; + } + case NEED_TASK: { + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + doTasks(key); + break; + } + case NOT_HANDSHAKING: { + // TODO: Exception or maybe handshakeComplete = true? + throw new IOException("The SSLEngine is not handshaking."); + } + default: { + throw new IOException("The SSLEngine is in a curiuos handshake-state."); + } + } + } + return handshakeComplete; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isFlushed() { + return bufferRemaining(outNetBuffer) == 0; + } + + /** + * finishing operations for handshake + * + * @param key + */ + private void handshakeFinished(SelectionKey key) throws CancelledKeyException { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "SSL-handshake for %s:%d finished", + channel.socket().getInetAddress().toString(), channel.socket().getPort()); + + // all handshake-data processed and sent + handshakeComplete = true; + inNetBuffer.clear(); + outNetBuffer.clear(); + key.interestOps(keyOpsBeforeHandshake); + try { + this.certs = sslEngine.getSession().getPeerCertificates(); + } catch (SSLPeerUnverifiedException ex) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.auth, this, OutputUtils.stackTraceToString(ex)); + this.certs = null; + } + + } + + /** + * + * @param key + * @param handshakeStatus + * @throws IOException + */ + private void analyseHandshakeStatus(SelectionKey key, HandshakeStatus handshakeStatus) throws IOException, CancelledKeyException { + switch (handshakeStatus) { + case NEED_UNWRAP: { + key.interestOps(key.interestOps() | SelectionKey.OP_READ & ~SelectionKey.OP_WRITE); + break; + } + case NEED_WRAP: { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + break; + } + case NEED_TASK: { + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + doTasks(key); + break; + } + case FINISHED: { + outNetBuffer.flip(); // ready for writing to channel + if (tryFlush()) { + handshakeFinished(key); + } else { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + } + break; + } + case NOT_HANDSHAKING: { + // TODO: Exception or maybe handshakeComplete = true? + throw new IOException("The SSLEngine is not handshaking."); + } + default: { + throw new IOException("The SSLEngine is in a curiuos handshake-state."); + } + } + } + + /** + * checks the remaining data of the buffer (only for internal buffers) + * + * @param buffer + * @return + */ + private int bufferRemaining(ReusableBuffer buffer) { + buffer.flip(); // ready for being read + int tmp = buffer.remaining(); + buffer.compact(); // ready for being read + return tmp; + } + + /** + * runs the time-consuming tasks + * + * @param key + * @throws IOException + */ + protected void doTasks(final SelectionKey key) throws CancelledKeyException { + // Logging.logMessage(Logging.LEVEL_DEBUG, this, + // "SSL-handshake doing: doing task"); + + final int tmp = key.interestOps(); + // clear all interests, so no one other than this thread can modify the + // selector + key.interestOps(0); + + /* + * executor.execute(new Runnable(){ public void run() { + */ + // TODO: running in a different thread + Runnable run; + while ((run = sslEngine.getDelegatedTask()) != null) { + run.run(); + } + + switch (handshakeStatus = sslEngine.getHandshakeStatus()) { + case NEED_WRAP: { + key.interestOps(tmp | SelectionKey.OP_WRITE); + break; + } + case NEED_UNWRAP: { + // need to read from channel + key.interestOps(tmp | SelectionKey.OP_READ); + break; + } + case FINISHED: { + // should not happen + handshakeFinished(key); + break; + } + case NEED_TASK: { + // should not happen + doTasks(key); + break; + } + case NOT_HANDSHAKING: { + // should not happen + Logging.logMessage(Logging.LEVEL_ERROR, Category.auth, this, + "Exception in worker-thread: The SSLEngine is not handshaking."); + break; + } + default: { + Logging.logMessage(Logging.LEVEL_ERROR, Category.auth, this, + "Exception in worker-thread: The SSLEngine is in a curiuos handshake-state."); + assert (false); + // throw new + // IOException("The SSLEngine is in a curiuos handshake-state."); + } + } + + /* + * key.selector().wakeup(); } }); + */ + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/SSLHandshakeOnlyChannelIO.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/SSLHandshakeOnlyChannelIO.java new file mode 100644 index 0000000..78ca8f9 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/channels/SSLHandshakeOnlyChannelIO.java @@ -0,0 +1,647 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.channels; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; +import java.util.ArrayList; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLEngineResult.HandshakeStatus; + +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; + +/** + * A secure abstraction of the SocketChannel (by using SSL) + * + * @author clorenz + */ +public class SSLHandshakeOnlyChannelIO extends ChannelIO { + + /** + * Number of Threads in the ThreadPool which will be used for the + * time-consuming tasks + */ + // public static int EXECUTOR_THREADS = 4; + /** + * used SSLEngine for this channel + */ + protected final SSLEngine sslEngine; + + /** + * contains the read data encrypted by ssl + */ + protected ReusableBuffer inNetBuffer, inReadBuffer; + + /** + * contains the written data encrypted by ssl + */ + protected ReusableBuffer outNetBuffer; + + /** + * an empty buffer for e.g. handshaking and shutdown; it will never contain + * data + */ + protected ReusableBuffer dummyBuffer; + + /** + * the last SSLEngine-status + */ + protected HandshakeStatus handshakeStatus; + + protected boolean handshakeComplete; + + protected int keyOpsBeforeHandshake = -1; + + /** + * true, if shutdown was called at least one time + */ + protected boolean shutdownInProgress; + + /** + * cipher suites without symmetric encryption, wich are supported by the + * SSLEngine in Java6 + */ + protected static String[] supportedCipherSuitesWithoutEncryption = null; + + /** + * SSL-Channel is used by client + */ + protected boolean clientMode; + + /** + * for asynchronious execution of time-consuming tasks only one executor for + * ALL SSLChannelIOs + */ + // private static ExecutorService executor = null; + private boolean closed = false; + + private boolean shutdownComplete = false; + + /** + * creates a SSLChannelIO + * + * @param channel + * channel, which should be protected by SSL + * @param sslOptions + * the Options for the SSL-Connection + * @param clientMode + * true, if you are a client; false, if you are a server + * @throws SSLException + */ + public SSLHandshakeOnlyChannelIO(SocketChannel channel, SSLOptions sslOptions, boolean clientMode) throws SSLException { + super(channel); + // initialize SSLEngine for a server + sslEngine = sslOptions.getSSLContext().createSSLEngine(); + sslEngine.setUseClientMode(clientMode); + sslEngine.setNeedClientAuth(true); + + if (clientMode) { + // the first call for a client is wrap() + sslEngine.beginHandshake(); + handshakeStatus = HandshakeStatus.NEED_WRAP; + } else { + // the first call for a server is unwrap() + sslEngine.beginHandshake(); + handshakeStatus = HandshakeStatus.NEED_UNWRAP; + } + + handshakeComplete = false; + shutdownInProgress = false; + + int netBufSize = sslEngine.getSession().getPacketBufferSize(); + inNetBuffer = BufferPool.allocate(netBufSize); + inReadBuffer = BufferPool.allocate(sslEngine.getSession().getApplicationBufferSize() * 2); + outNetBuffer = BufferPool.allocate(netBufSize); + dummyBuffer = BufferPool.allocate(netBufSize); + + sslEngine.setEnabledProtocols(sslEngine.getSupportedProtocols()); + if (sslOptions.isAuthenticationWithoutEncryption()) { // only + // authentication + // without + // protecting + // data? + // enable only cipher suites without encryption + + if (supportedCipherSuitesWithoutEncryption == null) { // runs only + // first time + // a + // SSLChannelIO + // without Encryption is created + // find all supported cipher suites without symmetric encryption + ArrayList cipherSuites = new ArrayList(); + for (String cipherSuite : sslEngine.getSupportedCipherSuites()) { + if (cipherSuite.contains("WITH_NULL")) { + cipherSuites.add(cipherSuite); + } + } + supportedCipherSuitesWithoutEncryption = new String[cipherSuites.size()]; + supportedCipherSuitesWithoutEncryption = cipherSuites + .toArray(supportedCipherSuitesWithoutEncryption); + } + sslEngine.setEnabledCipherSuites(supportedCipherSuitesWithoutEncryption); + } else // enable all supported cipher suites + { + sslEngine.setEnabledCipherSuites(sslEngine.getSupportedCipherSuites()); + } + + // only initialize the first time an SSLChannelIO is created + /* + * if(executor==null) executor = + * Executors.newFixedThreadPool(EXECUTOR_THREADS); + */ + } + + /** + * {@inheritDoc} + */ + @Override + public int read(ByteBuffer dst) throws IOException { + int returnValue = 0; + if (!shutdownInProgress) { + if (handshakeComplete) { + /*if (inNetBuffer.hasRemaining()) { + //read something which is still in the buffer after the handshake + while (dst.hasRemaining() && inNetBuffer.hasRemaining()) + dst.put(inNetBuffer.get()); + } else {*/ + returnValue = channel.read(dst); + // } + } + } + return returnValue; + } + + /** + * {@inheritDoc} warning: maybe more bytes would be consumed from src-buffer + * than will be written to channel (returned value) + */ + @Override + public int write(ByteBuffer src) throws IOException { + int returnValue = 0; + if (!shutdownInProgress) { + if (handshakeComplete) { + return channel.write(src); + } + } + return returnValue; + } + + /** + * {@inheritDoc} + */ + /** + * {@inheritDoc} warning: maybe more bytes would be consumed from src-buffer + * than will be written to channel (returned value) + */ + @Override + public long write(ByteBuffer[] src) throws IOException { + int returnValue = 0; + if (!shutdownInProgress) { + if (handshakeComplete) { + return channel.write(src); + } + } + return returnValue; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isShutdownInProgress() { + return this.shutdownInProgress; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean shutdown(SelectionKey key) throws IOException, CancelledKeyException { + if (!handshakeComplete) { // no SSL connection is established => simple + // close + shutdownInProgress = true; + return true; + } + + if (shutdownComplete) { + return shutdownComplete; + } + + if (!shutdownInProgress) { // initiate shutdown + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "shutdown SSL connection of %s:%d", channel.socket().getInetAddress().toString(), channel + .socket().getPort()); + + sslEngine.closeOutbound(); + shutdownInProgress = true; + key.interestOps(key.interestOps() & ~SelectionKey.OP_READ); // don't + // wait + // for + // the + // close_notify-reply + } + + outNetBuffer.flip(); // ready for writing to channel + if (tryFlush() && sslEngine.isOutboundDone()) { // shutdown complete + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + shutdownComplete = true; + } + + if (!sslEngine.isOutboundDone()) { + // Get close message + SSLEngineResult result = sslEngine.wrap(dummyBuffer.getBuffer(), outNetBuffer.getBuffer()); + outNetBuffer.flip(); // ready for writing to channel + switch (result.getStatus()) { + case OK: { + throw new IOException("This should not happen."); + } + case BUFFER_OVERFLOW: { + // needed more space in outNetBuffer + // two reasons for overflow: + // 1. buffer is too small + // 2. buffer is nearly full + tryFlush(); + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + /* + * throw new IOException( + * "BufferOverflow in SSLEngine. Buffer for SSLEngine-generated data is too small." + * ); + */ + break; + } + case CLOSED: { + if (tryFlush() && sslEngine.isOutboundDone()) { + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + shutdownComplete = true; + } else { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + } + break; + } + default: { + throw new IOException("The SSLEngine is in a curiuos state."); + } + } + } + return shutdownComplete; + } + + /** + * {@inheritDoc} + */ + @Override + public void close() throws IOException { + try { + super.close(); + try { + sslEngine.closeInbound(); + sslEngine.closeOutbound(); + } catch (SSLException e) { + // ignore it + } + // free buffers + BufferPool.free(inNetBuffer); + inNetBuffer = null; + BufferPool.free(inReadBuffer); + inReadBuffer = null; + BufferPool.free(outNetBuffer); + BufferPool.free(dummyBuffer); + shutdownInProgress = true; + closed = true; + } catch (Throwable th) { + System.out.println("CANNOT CLOSE DUE TO: " + th); + throw new IOException(th); + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void finalize() { + if (inNetBuffer != null) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, "buffers not freed!"); + BufferPool.free(inNetBuffer); + inNetBuffer = null; + BufferPool.free(outNetBuffer); + BufferPool.free(dummyBuffer); + } + if (!closed) { + System.out.println("CONNECTION WAS NOT CLOSED PROPERLY: " + this); + } + } + + /** + * Writes the outNetBuffer-data to the channel. After write, the buffer is + * empty or ready for add new data + * + * @return true, if write was successful; false, if buffer is not empty + * @throws IOException + */ + protected boolean tryFlush() throws IOException { + // if (outNetBuffer.hasRemaining()) { // flush the buffer + channel.write(outNetBuffer.getBuffer()); + if (outNetBuffer.hasRemaining()) { + outNetBuffer.compact(); + return false; + } else { + outNetBuffer.compact(); + } + // } + return true; + } + + /** + * {@inheritDoc} warning: the function manipulates the SelectionKey Ops, so + * don't do anything in your programm beetween first call of this function + * until the function returns true + */ + @Override + public boolean doHandshake(SelectionKey key) throws IOException, CancelledKeyException { + if (handshakeComplete || shutdownInProgress) { // quick return + return handshakeComplete; + } + + if (keyOpsBeforeHandshake == -1) { + keyOpsBeforeHandshake = key.interestOps(); + key.interestOps(key.interestOps() & ~SelectionKey.OP_READ & ~SelectionKey.OP_WRITE); + } + + if (!handshakeComplete) { + // Logging.logMessage(Logging.LEVEL_DEBUG, this, + // "SSL-handshake next step: "+handshakeStatus); + + SSLEngineResult result; + switch (handshakeStatus) { + case NEED_UNWRAP: { + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + if (channel.read(inNetBuffer.getBuffer()) == -1) { + throw new IOException("End of stream has reached."); + } + + boolean underflow = false; + do { // read all read data in buffer + // Logging.logMessage(Logging.LEVEL_DEBUG, this, + // "SSL-handshake doing: unwrap"); + inNetBuffer.flip(); // ready for being read + result = sslEngine.unwrap(inNetBuffer.getBuffer(), dummyBuffer.getBuffer()); + inNetBuffer.compact(); // ready for reading from channel + + handshakeStatus = result.getHandshakeStatus(); + switch (result.getStatus()) { + case OK: { + analyseHandshakeStatus(key, handshakeStatus); + break; + } + case BUFFER_UNDERFLOW: { + // needed more data in inNetBuffer, maybe nexttime + underflow = true; + key.interestOps(key.interestOps() | SelectionKey.OP_READ); + break; + } + case CLOSED: { + throw new IOException("The SSLEngine is already closed."); + } + default: { + throw new IOException("The SSLEngine is in a curiuos state."); + } + } + } while (bufferRemaining(inNetBuffer) != 0 && handshakeStatus == HandshakeStatus.NEED_UNWRAP + && !underflow); + break; + } + case NEED_WRAP: { + key.interestOps(key.interestOps() & ~SelectionKey.OP_READ); + // Logging.logMessage(Logging.LEVEL_DEBUG, this, + // "SSL-handshake doing: wrap"); + + result = sslEngine.wrap(dummyBuffer.getBuffer(), outNetBuffer.getBuffer()); + outNetBuffer.flip(); // ready for writing to channel + + handshakeStatus = result.getHandshakeStatus(); + switch (result.getStatus()) { + case OK: { + tryFlush(); + + analyseHandshakeStatus(key, handshakeStatus); + break; + } + case BUFFER_OVERFLOW: { + // needed more space in outNetBuffer + // two reasons for overflow: + // 1. buffer is too small + // 2. buffer is nearly full + tryFlush(); + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + /* + * throw new IOException( + * "BufferOverflow in SSLEngine. Buffer for SSLEngine-generated data is too small." + * ); + */ + break; + } + case CLOSED: { + throw new IOException("The SSLEngine is already closed."); + } + default: { + throw new IOException("The SSLEngine is in a curiuos state."); + } + } + break; + } + case FINISHED: { + outNetBuffer.flip(); // ready for writing to channel + if (tryFlush()) { + handshakeFinished(key); + } else { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + } + break; + } + case NEED_TASK: { + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + doTasks(key); + break; + } + case NOT_HANDSHAKING: { + // TODO: Exception or maybe handshakeComplete = true? + throw new IOException("The SSLEngine is not handshaking."); + } + default: { + throw new IOException("The SSLEngine is in a curiuos handshake-state."); + } + } + } + return handshakeComplete; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isFlushed() { + return bufferRemaining(outNetBuffer) == 0; + } + + /** + * finishing operations for handshake + * + * @param key + */ + private void handshakeFinished(SelectionKey key) throws CancelledKeyException { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "SSL-handshake for %s:%d finished", + channel.socket().getInetAddress().toString(), channel.socket().getPort()); + + // all handshake-data processed and sent + handshakeComplete = true; + inNetBuffer.clear(); + outNetBuffer.clear(); + key.interestOps(keyOpsBeforeHandshake); + try { + this.certs = sslEngine.getSession().getPeerCertificates(); + } catch (SSLPeerUnverifiedException ex) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.auth, this, OutputUtils.stackTraceToString(ex)); + this.certs = null; + } + + } + + /** + * + * @param key + * @param handshakeStatus + * @throws IOException + */ + private void analyseHandshakeStatus(SelectionKey key, HandshakeStatus handshakeStatus) throws IOException, CancelledKeyException { + switch (handshakeStatus) { + case NEED_UNWRAP: { + key.interestOps(key.interestOps() | SelectionKey.OP_READ & ~SelectionKey.OP_WRITE); + break; + } + case NEED_WRAP: { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + break; + } + case NEED_TASK: { + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + doTasks(key); + break; + } + case FINISHED: { + outNetBuffer.flip(); // ready for writing to channel + if (tryFlush()) { + handshakeFinished(key); + } else { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + } + break; + } + case NOT_HANDSHAKING: { + // TODO: Exception or maybe handshakeComplete = true? + throw new IOException("The SSLEngine is not handshaking."); + } + default: { + throw new IOException("The SSLEngine is in a curiuos handshake-state."); + } + } + } + + /** + * checks the remaining data of the buffer (only for internal buffers) + * + * @param buffer + * @return + */ + private int bufferRemaining(ReusableBuffer buffer) { + buffer.flip(); // ready for being read + int tmp = buffer.remaining(); + buffer.compact(); // ready for being read + return tmp; + } + + /** + * runs the time-consuming tasks + * + * @param key + * @throws IOException + */ + protected void doTasks(final SelectionKey key) throws CancelledKeyException { + // Logging.logMessage(Logging.LEVEL_DEBUG, this, + // "SSL-handshake doing: doing task"); + + final int tmp = key.interestOps(); + // clear all interests, so no one other than this thread can modify the + // selector + key.interestOps(0); + + /* + * executor.execute(new Runnable(){ public void run() { + */ + // TODO: running in a different thread + Runnable run; + while ((run = sslEngine.getDelegatedTask()) != null) { + run.run(); + } + + switch (handshakeStatus = sslEngine.getHandshakeStatus()) { + case NEED_WRAP: { + key.interestOps(tmp | SelectionKey.OP_WRITE); + break; + } + case NEED_UNWRAP: { + // need to read from channel + key.interestOps(tmp | SelectionKey.OP_READ); + break; + } + case FINISHED: { + // should not happen + handshakeFinished(key); + break; + } + case NEED_TASK: { + // should not happen + doTasks(key); + break; + } + case NOT_HANDSHAKING: { + // should not happen + Logging.logMessage(Logging.LEVEL_ERROR, Category.auth, this, + "Exception in worker-thread: The SSLEngine is not handshaking."); + break; + } + default: { + Logging.logMessage(Logging.LEVEL_ERROR, Category.auth, this, + "Exception in worker-thread: The SSLEngine is in a curiuos handshake-state."); + assert (false); + // throw new + // IOException("The SSLEngine is in a curiuos handshake-state."); + } + } + + /* + * key.selector().wakeup(); } }); + */ + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/PBRPCException.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/PBRPCException.java new file mode 100644 index 0000000..d0de0f4 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/PBRPCException.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.client; + +import java.io.IOException; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; + +/** + * + * @author bjko + */ +public class PBRPCException extends IOException { + + final ErrorResponse response; + + final String message; + + public PBRPCException(String ioError) { + super(); + this.message = ioError; + response = null; + } + + public PBRPCException(ErrorResponse response) { + super(); + this.response = response; + this.message = null; + } + + public RPC.ErrorType getErrorType() { + if (response != null) + return response.getErrorType(); + else + return RPC.ErrorType.IO_ERROR; + } + + public RPC.POSIXErrno getPOSIXErrno() { + if (response != null) + return response.getPosixErrno(); + else + return RPC.POSIXErrno.POSIX_ERROR_NONE; + } + + public String getErrorMessage() { + if (response != null) + return response.getErrorMessage(); + else + return this.message; + } + + public String getDebugInfo() { + if (response != null) + return response.getDebugInfo(); + else + return ""; + } + + public String getRedirectToServerUUID() { + if (response != null) + return response.getRedirectToServerUuid(); + else + return ""; + } + + public ErrorResponse getErrorResponse() { + return response; + } + + @Override + public String getMessage() { + if (response != null) { + return response.getErrorType().toString()+"/"+response.getPosixErrno().toString()+": "+response.getErrorMessage()+" / "+response.getDebugInfo(); + } else { + return this.message; + } + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCAuthentication.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCAuthentication.java new file mode 100644 index 0000000..a275365 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCAuthentication.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.client; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; + +/** + * + * @author bjko + */ +public class RPCAuthentication { + + public static final Auth authNone; + + public static final UserCredentials userService; + + static { + authNone = Auth.newBuilder().setAuthType(AuthType.AUTH_NONE).build(); + userService = UserCredentials.newBuilder().setUsername("srv").addGroups("xtreemfs").build(); + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCClientConnection.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCClientConnection.java new file mode 100644 index 0000000..70f21b9 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCClientConnection.java @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.client; + +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.channels.ChannelIO; +import org.xtreemfs.foundation.pbrpc.server.RPCNIOSocketServerConnection.ReceiveState; +import org.xtreemfs.foundation.pbrpc.utils.RecordMarker; + +/** + * + * @author bjko + */ +public class RPCClientConnection { + + public static final int RETRY_RESET_IN_MS = 500; + + /** max wait is one minute */ + public static final int MAX_RETRY_WAIT_MS = 1000*60; + + private ChannelIO channel; + + private final Map requests; + + private final List sendQueue; + + private long lastUsed; + + private long nextReconnectTime; + + private int numConnectAttempts; + + private final ByteBuffer requestRecordMarker; + + private final ByteBuffer responseRecordMarker; + + private ReusableBuffer[] responseBuffers; + + private ByteBuffer[] requestBuffers; + + private RPCClientRequest pendingRequest; + + private ReceiveState receiveState; + + private final InetSocketAddress endpoint; + + volatile long bytesRX, bytesTX; + + + public RPCClientConnection(InetSocketAddress endpoint) { + requests = new HashMap(); + lastUsed = TimeSync.getLocalSystemTime(); + numConnectAttempts = 0; + nextReconnectTime = 0; + sendQueue = new LinkedList(); + requestRecordMarker = ByteBuffer.allocateDirect(RecordMarker.HDR_SIZE); + responseRecordMarker = ByteBuffer.allocateDirect(RecordMarker.HDR_SIZE); + this.endpoint = endpoint; + receiveState = ReceiveState.RECORD_MARKER; + bytesTX = 0; + bytesRX = 0; + } + + public void freeBuffers() { + if (responseBuffers != null) { + for (ReusableBuffer buf: responseBuffers) + BufferPool.free(buf); + } + for (RPCClientRequest rq : sendQueue) { + rq.freeBuffers(); + } + for (RPCClientRequest rq : requests.values()) { + rq.freeBuffers(); + } + } + + boolean isConnected() { + return channel != null; + } + + void connectFailed() { + numConnectAttempts++; + long waitt = Math.round(RETRY_RESET_IN_MS*Math.pow(2,this.numConnectAttempts)); + if (waitt > MAX_RETRY_WAIT_MS) { + waitt = MAX_RETRY_WAIT_MS; + } + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "next reconnect possible after %d s, attempt = %d", (waitt / 1000), this.numConnectAttempts); + this.nextReconnectTime = System.currentTimeMillis()+waitt; + } + + boolean canReconnect() { + return (this.nextReconnectTime < System.currentTimeMillis()); + } + + void setChannel(ChannelIO channel) { + this.channel = channel; + } + + void connected() { + numConnectAttempts = 0; + lastUsed = TimeSync.getLocalSystemTime(); + } + + void useConnection() { + lastUsed = TimeSync.getLocalSystemTime(); + } + + long getLastUsed() { + return lastUsed; + } + + ChannelIO getChannel() { + return channel; + } + + RPCClientRequest getRequest(int callId) { + return requests.remove(callId); + } + + void addRequest(int callId, RPCClientRequest rq) { + requests.put(callId,rq); + } + + void removeRequest(int callId) { + requests.remove(callId); + } + + Map getRequests() { + return this.requests; + } + + List getSendQueue() { + return sendQueue; + } + + + /** + * @return the requestFragHdr + */ + ByteBuffer getRequestRecordMarker() { + return requestRecordMarker; + } + + /** + * @return the responseFragHdr + */ + ByteBuffer getResponseRecordMarker() { + return responseRecordMarker; + } + + public String getEndpointString() { + String endpointString = "unknown"; + try { + endpointString = endpoint.toString(); + } catch (Exception ex2) { + } + + return endpointString; + } + + /** + * @return the requestBuffers + */ + public ByteBuffer[] getRequestBuffers() { + return requestBuffers; + } + + /** + * @param requestBuffers the requestBuffers to set + */ + public void setRequestBuffers(ByteBuffer[] requestBuffers) { + this.requestBuffers = requestBuffers; + } + + public RPCClientRequest getPendingRequest() { + return pendingRequest; + } + + public void setPendingRequest(RPCClientRequest pendingRequest) { + this.pendingRequest = pendingRequest; + } + + /** + * @return the receiveState + */ + public ReceiveState getReceiveState() { + return receiveState; + } + + /** + * @param receiveState the receiveState to set + */ + public void setReceiveState(ReceiveState receiveState) { + this.receiveState = receiveState; + } + + /** + * @return the responseBuffers + */ + public ReusableBuffer[] getResponseBuffers() { + return responseBuffers; + } + + /** + * @param responseBuffers the responseBuffers to set + */ + public void setResponseBuffers(ReusableBuffer[] responseBuffers) { + this.responseBuffers = responseBuffers; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCClientRequest.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCClientRequest.java new file mode 100644 index 0000000..26cbdc4 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCClientRequest.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.client; + +import com.google.protobuf.Message; +import java.io.IOException; +import java.nio.ByteBuffer; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferOutputStream; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.pbrpc.utils.RecordMarker; + + +/** + * + * @author bjko + */ +public class RPCClientRequest { + + private final RPC.RPCHeader requestHeader; + private RPC.RPCHeader responseHeader; + final ReusableBuffer[] buffers; + final int hdrLen; + final int msgLen; + final int dataLen; + + private final RPCResponse response; + + private long timeQueued; + private long bytesWritten; + + + RPCClientRequest(Auth authHeader, UserCredentials uCreds, int callId, int interfaceId, int procId, Message message, ReusableBuffer data, RPCResponse response) throws IOException { + if (uCreds == null) { + throw new IOException("No UserCredentials object given (null). Make sure it's set."); + } + if (authHeader == null) { + throw new IOException("No Auth object given (null). Make sure it's set."); + } + + RPC.RPCHeader.RequestHeader rqHdr = RPC.RPCHeader.RequestHeader.newBuilder().setAuthData(authHeader).setUserCreds(uCreds). + setInterfaceId(interfaceId).setProcId(procId).build(); + requestHeader = RPC.RPCHeader.newBuilder().setCallId(callId).setMessageType(RPC.MessageType.RPC_REQUEST).setRequestHeader(rqHdr).build(); + this.response = response; + + ReusableBufferOutputStream os = new ReusableBufferOutputStream(ReusableBufferOutputStream.BUFF_SIZE); + requestHeader.writeTo(os); + hdrLen = os.length(); + if (message != null) { + message.writeTo(os); + msgLen = os.length()-hdrLen; + } else { + msgLen = 0; + } + if (data != null) { + os.appendBuffer(data); + dataLen = data.limit(); + } else { + dataLen = 0; + } + assert(hdrLen > 0); + assert(msgLen >= 0); + assert(dataLen >= 0); + os.flip(); + buffers = os.getBuffers(); + } + + public ReusableBuffer[] getBuffers() { + return buffers; + } + + public ByteBuffer[] packBuffers(ByteBuffer recordMarker) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "sending record marker: %d/%d/%d", hdrLen,msgLen,dataLen); + } + recordMarker.putInt(hdrLen); + recordMarker.putInt(msgLen); + recordMarker.putInt(dataLen); + recordMarker.flip(); + ByteBuffer[] arr = new ByteBuffer[buffers.length+1]; + arr[0] = recordMarker; + for (int i = 0; i < buffers.length; i++) { + arr[i+1] = buffers[i].getBuffer(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "send buffer #%d: %s", i+1,buffers[i]); + } + } + return arr; + } + + public void freeBuffers() { + for (int i = 0; i < buffers.length; i++) { + BufferPool.free(buffers[i]); + buffers[i] = null; + } + } + + /** + * duration of request from sending the request until the response + * was received completeley. + * @return duration in ns + */ + public long getDuration() { + if (RPCNIOSocketClient.ENABLE_STATISTICS) { + return 0; + } else { + return 0l; + } + } + + /** + * @return the requestHeader + */ + public RPC.RPCHeader getRequestHeader() { + return requestHeader; + } + + void queued() { + this.timeQueued = TimeSync.getLocalSystemTime(); + } + + long getTimeQueued() { + return this.timeQueued; + } + + /** + * @return the responseHeader + */ + public RPC.RPCHeader getResponseHeader() { + return responseHeader; + } + + /** + * @param responseHeader the responseHeader to set + */ + public void setResponseHeader(RPC.RPCHeader responseHeader) { + this.responseHeader = responseHeader; + } + + public RPCResponse getResponse() { + return response; + } + + public void recordBytesWritten(long bytesWritten) { + this.bytesWritten += bytesWritten; + if (this.bytesWritten > RecordMarker.HDR_SIZE + hdrLen + dataLen + msgLen) { + String errorMessage = "Too many bytes written (expected: " + + (RecordMarker.HDR_SIZE + hdrLen + dataLen + msgLen) + + ", actual: " + + this.bytesWritten + + ") for message " + + requestHeader; + Logging.logMessage(Logging.LEVEL_ERROR, this, errorMessage); + throw new IllegalStateException(errorMessage); + } + } + + public void checkEnoughBytesSent() { + if (bytesWritten != RecordMarker.HDR_SIZE + hdrLen + dataLen + msgLen) { + String errorMessage = "Not enough bytes written (expected: " + + (RecordMarker.HDR_SIZE + hdrLen + dataLen + msgLen) + + ", actual: " + + bytesWritten + + ") for message " + + requestHeader; + Logging.logMessage(Logging.LEVEL_ERROR, this, errorMessage); + throw new IllegalStateException(errorMessage); + } + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCNIOSocketClient.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCNIOSocketClient.java new file mode 100644 index 0000000..9ea4ecf --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCNIOSocketClient.java @@ -0,0 +1,806 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * Copyright (c) 2013 by Bjoern Kolbeck. + * Copyright (c) 2014 by Quobyte Inc. + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.client; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.NotYetConnectedException; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.SocketChannel; +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; + +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.channels.ChannelIO; +import org.xtreemfs.foundation.pbrpc.channels.SSLChannelIO; +import org.xtreemfs.foundation.pbrpc.channels.SSLHandshakeOnlyChannelIO; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.pbrpc.server.RPCNIOSocketServer; +import org.xtreemfs.foundation.pbrpc.server.RPCNIOSocketServerConnection; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; +import org.xtreemfs.foundation.util.OutputUtils; + +import com.google.protobuf.Message; +/** + * + * @author bjko + */ +public class RPCNIOSocketClient extends LifeCycleThread { + + public static boolean ENABLE_STATISTICS = false; + + + /** + * Maximum tries to reconnect to the server + */ + public static final int MAX_RECONNECT = 4; + + /** + * milliseconds between two timeout checks + */ + public static final int TIMEOUT_GRANULARITY = 250; + + private final Map connections; + + private final int requestTimeout; + + private final int connectionTimeout; + + private long lastCheck; + + private final Selector selector; + + private volatile boolean quit; + + private final SSLOptions sslOptions; + + private final AtomicInteger transactionId; + + private final ConcurrentLinkedQueue toBeEstablished; + + private final int sendBufferSize; + + private final int receiveBufferSize; + + private final SocketAddress localBindPoint; + + + /** + * on some platforms (e.g. FreeBSD 7.2 with openjdk6) Selector.select(int timeout) + * returns immediately. If this problem is detected, the thread waits 25ms after each + * invocation to avoid excessive CPU consumption. See also issue #75 + */ + private boolean brokenSelect; + + public RPCNIOSocketClient(SSLOptions sslOptions, int requestTimeout, int connectionTimeout) + throws IOException { + this(sslOptions, requestTimeout, connectionTimeout, -1, -1, null, "", false); + } + + public RPCNIOSocketClient(SSLOptions sslOptions, int requestTimeout, int connectionTimeout, String threadName) + throws IOException { + this(sslOptions, requestTimeout, connectionTimeout, -1, -1, null, threadName, false); + } + + public RPCNIOSocketClient(SSLOptions sslOptions, int requestTimeout, int connectionTimeout, + int sendBufferSize, int receiveBufferSize, SocketAddress localBindPoint) throws IOException { + this(sslOptions, requestTimeout, connectionTimeout, sendBufferSize, receiveBufferSize, localBindPoint, "", false); + } + + public RPCNIOSocketClient(SSLOptions sslOptions, int requestTimeout, int connectionTimeout, String threadName, boolean startAsDaemon) throws IOException { + this(sslOptions, requestTimeout, connectionTimeout, -1, -1, null, threadName, startAsDaemon); + } + + public RPCNIOSocketClient(SSLOptions sslOptions, int requestTimeout, int connectionTimeout, + int sendBufferSize, int receiveBufferSize, SocketAddress localBindPoint, String threadName) throws IOException { + this(sslOptions, requestTimeout, connectionTimeout, sendBufferSize, receiveBufferSize, localBindPoint, threadName, false); + } + + public RPCNIOSocketClient(SSLOptions sslOptions, int requestTimeout, int connectionTimeout, + int sendBufferSize, int receiveBufferSize, SocketAddress localBindPoint, String threadName, boolean startAsDaemon) throws IOException { + super(threadName); + setDaemon(startAsDaemon); + if (requestTimeout >= connectionTimeout - TIMEOUT_GRANULARITY * 2) { + throw new IllegalArgumentException( + "request timeout must be smaller than connection timeout less " + TIMEOUT_GRANULARITY * 2 + + "ms"); + } + this.requestTimeout = requestTimeout; + this.connectionTimeout = connectionTimeout; + this.sendBufferSize = sendBufferSize; + this.receiveBufferSize = receiveBufferSize; + this.localBindPoint = localBindPoint; + connections = new HashMap(); + selector = Selector.open(); + this.sslOptions = sslOptions; + quit = false; + transactionId = new AtomicInteger((int) (Math.random() * 1e6 + 1.0)); + toBeEstablished = new ConcurrentLinkedQueue(); + + if (this.localBindPoint != null && Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "RPC Client '%s': Using the following address for outgoing connections: %s", threadName, this.localBindPoint); + } + } + + + public void sendRequest(InetSocketAddress server, Auth auth, UserCredentials uCred, int interface_id, int proc_id, Message message, ReusableBuffer data, + RPCResponse response, boolean highPriority) { + try { + RPCClientRequest rq = new RPCClientRequest(auth, uCred, transactionId.incrementAndGet(), interface_id, proc_id, message, data, response); + internalSendRequest(server, rq, highPriority); + } catch (Throwable e) { // CancelledKeyException, RuntimeException (caused by missing TimeSyncThread) + //e.printStackTrace(); + response.requestFailed(e.toString()); + } + } + + private void internalSendRequest(InetSocketAddress server, RPCClientRequest request, boolean highPriority) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "sending request %s no %d", request + .toString(), transactionId.get()); + } + // get connection + RPCClientConnection con = null; + synchronized (connections) { + con = connections.get(server); + if (con == null) { + con = new RPCClientConnection(server); + connections.put(server, con); + } + } + synchronized (con) { + boolean isEmpty = con.getSendQueue().isEmpty(); + request.queued(); + con.useConnection(); + if (highPriority) + con.getSendQueue().add(0, request); + else + con.getSendQueue().add(request); + + if (!con.isConnected()) { + establishConnection(server, con); + + } else { + if (isEmpty) { + final SelectionKey key = con.getChannel().keyFor(selector); + if (key != null) { + try { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + } catch (CancelledKeyException e) { + // Ignore it since the timeout mechanism will deal with it. + } + } + selector.wakeup(); + } + } + } + } + + @Override + public void run() { + + brokenSelect = false; + // Doesn't work properly, should be a replaced with a better way to detect + // a broken selector on FreeBSD. + /*try { + long now = System.currentTimeMillis(); + int numKeys = selector.select(100); + long duration = System.currentTimeMillis()-now; + if ((duration < 10) && (numKeys == 0)) { + Logging.logMessage(Logging.LEVEL_WARN, this,"detected broken select(int timeout)!"); + brokenSelect = true; + } + } catch (Throwable th) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"could not check Selector for broken select(int timeout): "+th); + }*/ + + notifyStarted(); + lastCheck = System.currentTimeMillis(); + + try { + while (!quit) { + if (!toBeEstablished.isEmpty()) { + while (true) { + RPCClientConnection con = toBeEstablished.poll(); + if (con == null) { + break; + } + try { + con.getChannel().register(selector, + SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE | SelectionKey.OP_READ, con); + } catch (ClosedChannelException ex) { + closeConnection(con.getChannel().keyFor(selector), ex.toString()); + } + } + toBeEstablished.clear(); + } + + int numKeys = 0; + try { + numKeys = selector.select(TIMEOUT_GRANULARITY); + } catch (CancelledKeyException ex) { + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, "Exception while selecting: %s", + ex.toString()); + continue; + } catch (IOException ex) { + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, "Exception while selecting: %s", + ex.toString()); + continue; + } + if (numKeys > 0) { + // fetch events + Set keys = selector.selectedKeys(); + Iterator iter = keys.iterator(); + + // process all events + while (iter.hasNext()) { + try { + SelectionKey key = iter.next(); + + // remove key from the list + iter.remove(); + + if (key.isConnectable()) { + connectConnection(key); + } + if (key.isReadable()) { + readConnection(key); + } + if (key.isWritable()) { + writeConnection(key); + } + } catch (CancelledKeyException ex) { + continue; + } + } + } + + if (numKeys == 0 && brokenSelect) { + + try { + sleep(25); + } catch (InterruptedException ex) { + break; + } + } + try { + checkForTimers(); + } catch (ConcurrentModificationException ce) { + Logging.logMessage(Logging.LEVEL_CRIT, this, + OutputUtils.getThreadDump()); + } + } + } catch (Throwable thr) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this, "PBRPC Client CRASHED!"); + notifyCrashed(thr); + } + + synchronized (connections) { + for (RPCClientConnection con : connections.values()) { + synchronized (con) { + for (RPCClientRequest rq : con.getSendQueue()) { + rq.getResponse().requestFailed("RPC cancelled due to client shutdown"); + rq.freeBuffers(); + } + for (RPCClientRequest rq : con.getRequests().values()) { + rq.getResponse().requestFailed("RPC cancelled due to client shutdown"); + rq.freeBuffers(); + } + try { + if (con.getChannel() != null) + con.getChannel().close(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + } + + notifyStopped(); + } + + private void establishConnection(InetSocketAddress server, RPCClientConnection con) { + + if (con.canReconnect()) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connect to %s", server + .toString()); + } + ChannelIO channel; + try { + if (sslOptions == null) { // no SSL + channel = new ChannelIO(SocketChannel.open()); + } else { + if (sslOptions.isFakeSSLMode()) { + channel = new SSLHandshakeOnlyChannelIO(SocketChannel.open(), sslOptions, true); + } else { + channel = new SSLChannelIO(SocketChannel.open(), sslOptions, true); + } + } + channel.configureBlocking(false); + channel.socket().setTcpNoDelay(true); + if (localBindPoint != null) { + channel.socket().bind(localBindPoint); + } + + if (sendBufferSize != -1) { + channel.socket().setSendBufferSize(sendBufferSize); + if (channel.socket().getSendBufferSize() != sendBufferSize) { + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "could not set socket send buffer size to " + sendBufferSize + + ", using default size of " + channel.socket().getSendBufferSize()); + } + } + + if (receiveBufferSize != -1) { + channel.socket().setReceiveBufferSize(receiveBufferSize); + if (channel.socket().getReceiveBufferSize() != receiveBufferSize) { + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "could not set socket receive buffer size to " + receiveBufferSize + + ", using default size of " + channel.socket().getReceiveBufferSize()); + } + } else { + channel.socket().setReceiveBufferSize(256 * 1024); + } + + channel.connect(server); + con.setChannel(channel); + toBeEstablished.add(con); + selector.wakeup(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connection created"); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "socket send buffer size: %d", + channel.socket().getSendBufferSize()); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "socket receive buffer size: %d", + channel.socket().getReceiveBufferSize()); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "local bind point: %s", channel + .socket().getLocalAddress()); + } + + } catch (Exception ex) { + if (ex.getClass() == java.net.SocketException.class && ex.getMessage().equals("Invalid argument")) { + Logging.logMessage( + Logging.LEVEL_ERROR, + Category.net, + this, + "FAILED TO USE THE FOLLOWING ADDRESS FOR OUTGOING REQUESTS: %s. Make sure that the hostname is correctly spelled in the configuration and it resolves to the correct IP.", + localBindPoint); + } + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "cannot contact server %s", + con.getEndpointString()); + } + con.connectFailed(); + for (RPCClientRequest rq : con.getSendQueue()) { + rq.getResponse().requestFailed("sending RPC failed: server '"+con.getEndpointString()+"' not reachable ("+ex+")"); + rq.freeBuffers(); + } + con.getSendQueue().clear(); + + } + } else { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "reconnect to server still blocked locally to avoid flooding (server: %s)", con.getEndpointString()); + } + synchronized (con) { + for (RPCClientRequest rq : con.getSendQueue()) { + rq.getResponse().requestFailed("sending RPC failed: reconnecting to the server '"+con.getEndpointString()+"' was blocked locally to avoid flooding"); + rq.freeBuffers(); + } + con.getSendQueue().clear(); + } + } + + } + + private void readConnection(SelectionKey key) { + final RPCClientConnection con = (RPCClientConnection) key.attachment(); + final ChannelIO channel = con.getChannel(); + + try { + + if (!channel.isShutdownInProgress()) { + if (channel.doHandshake(key)) { + + while (true) { + ByteBuffer buf = null; + switch (con.getReceiveState()) { + case RECORD_MARKER: { + buf = con.getResponseRecordMarker(); break; + } + case RPC_MESSAGE: { + buf = con.getResponseBuffers()[1].getBuffer(); break; + } + case RPC_HEADER: { + buf = con.getResponseBuffers()[0].getBuffer(); break; + } + case DATA: { + buf = con.getResponseBuffers()[2].getBuffer(); break; + } + } + + // read fragment header + final int numBytesRead = RPCNIOSocketServer.readData(key, channel, buf); + if (numBytesRead == -1) { + // connection closed + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "client closed connection (EOF): %s", channel.socket() + .getRemoteSocketAddress().toString()); + } + closeConnection(key,"server ("+channel.socket() + .getRemoteSocketAddress().toString()+") closed connection"); + return; + } + if (buf.hasRemaining()) { + // not enough data... + break; + } + + switch (con.getReceiveState()) { + case RECORD_MARKER: { + buf.position(0); + final int hdrLen = buf.getInt(); + final int msgLen = buf.getInt(); + final int dataLen = buf.getInt(); + + if ((hdrLen <= 0) || (hdrLen >= RPCNIOSocketServer.MAX_FRAGMENT_SIZE) + || (msgLen < 0) || (msgLen >= RPCNIOSocketServer.MAX_FRAGMENT_SIZE) + || (dataLen < 0) || (dataLen >= RPCNIOSocketServer.MAX_FRAGMENT_SIZE)) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this, + "invalid record marker size (%d/%d/%d) received, closing connection to client %s", + hdrLen,msgLen,dataLen,channel.socket() + .getRemoteSocketAddress().toString()); + closeConnection(key,"received invalid record marker from server ("+channel.socket() + .getRemoteSocketAddress().toString()+"), closed connection"); + return; + } + final ReusableBuffer[] buffers = new ReusableBuffer[]{BufferPool.allocate(hdrLen), + ((msgLen > 0) ? BufferPool.allocate(msgLen) : null), + ((dataLen > 0) ? BufferPool.allocate(dataLen) : null) }; + con.setResponseBuffers(buffers); + con.setReceiveState(RPCNIOSocketServerConnection.ReceiveState.RPC_HEADER); + continue; + } + + case RPC_HEADER: { + if (con.getResponseBuffers()[1] != null) { + con.setReceiveState(RPCNIOSocketServerConnection.ReceiveState.RPC_MESSAGE); + continue; + } else if (con.getResponseBuffers()[2] != null) { + // this is necessary, because we may receive some default + // instance of a message (empty) with data attached BUG #188 + con.setReceiveState(RPCNIOSocketServerConnection.ReceiveState.DATA); + continue; + } else { + break; + } + } + case RPC_MESSAGE: { + if (con.getResponseBuffers()[2] != null) { + con.setReceiveState(RPCNIOSocketServerConnection.ReceiveState.DATA); + continue; + } else { + break; + } + + } + } + + //assemble ServerRequest + con.setReceiveState(RPCNIOSocketServerConnection.ReceiveState.RECORD_MARKER); + con.getResponseRecordMarker().clear(); + + //assemble response... + assembleResponse(key, con); + } + } + } + } catch (IOException ex) { + // simply close the connection + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, OutputUtils + .stackTraceToString(ex)); + } + closeConnection(key, "server closed connection ("+ex+")"); + } catch (NotYetConnectedException e) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, OutputUtils + .stackTraceToString(e)); + } + closeConnection(key, "server closed connection: "+e); + } + } + + private void assembleResponse(SelectionKey key, RPCClientConnection con) throws IOException { + + try { + ReusableBuffer[] receiveBuffers = con.getResponseBuffers(); + receiveBuffers[0].flip(); + if (receiveBuffers[1] != null) + receiveBuffers[1].flip(); + if (receiveBuffers[2] != null) + receiveBuffers[2].flip(); + + + ReusableBufferInputStream rbis = new ReusableBufferInputStream(receiveBuffers[0]); + final RPC.RPCHeader header = RPC.RPCHeader.parseFrom(rbis); + BufferPool.free(receiveBuffers[0]); + + RPCClientRequest rq = con.getRequest(header.getCallId()); + if (rq == null) { + // Might happen when a request timed out before a response was + // sent. + BufferPool.free(receiveBuffers[1]); + BufferPool.free(receiveBuffers[2]); + con.setResponseBuffers(null); + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "received response for unknown request callId=%d", + header.getCallId()); + return; + } + RPCResponse response = rq.getResponse(); + rq.setResponseHeader(header); + con.setResponseBuffers(null); + + response.responseAvailable(rq, receiveBuffers[1], receiveBuffers[2]); + } catch (IOException ex) { + closeConnection(key,"invalid response received: "+ex); + } + + } + + private void writeConnection(SelectionKey key) { + final RPCClientConnection con = (RPCClientConnection) key.attachment(); + final ChannelIO channel = con.getChannel(); + + try { + + if (!channel.isShutdownInProgress()) { + if (channel.doHandshake(key)) { + + while (true) { + ByteBuffer[] buffers = con.getRequestBuffers(); + RPCClientRequest send = con.getPendingRequest(); + if (buffers == null) { + assert(send == null); + synchronized (con) { + if (con.getSendQueue().isEmpty()) { + // no more responses, stop writing... + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + break; + } + send = con.getSendQueue().remove(0); + } + assert(send != null); + con.getRequestRecordMarker().clear(); + buffers = send.packBuffers(con.getRequestRecordMarker()); + con.setRequestBuffers(buffers); + con.setPendingRequest(send); + } + + assert(buffers != null); + final long numBytesWritten = channel.write(buffers); + if (numBytesWritten == -1) { + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "client closed connection (EOF): %s", channel.socket() + .getRemoteSocketAddress().toString()); + } + // connection closed + closeConnection(key, "server unexpectedly closed connection (EOF)"); + return; + } + // Detect if the client writes outside of the fragment. + send.recordBytesWritten(numBytesWritten); + + if (buffers[buffers.length-1].hasRemaining()) { + // not enough data... + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + break; + } + + //remove from queue + synchronized (con) { + con.addRequest(send.getRequestHeader().getCallId(), send); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "sent request %d to %s", send.getRequestHeader().getCallId(), con.getEndpointString()); + } + } + send.checkEnoughBytesSent(); + con.setRequestBuffers(null); + con.setPendingRequest(null); + } + } + } + } catch (CancelledKeyException ex) { + // simply close the connection + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, OutputUtils + .stackTraceToString(ex)); + } + closeConnection(key, "server closed connection: "+ex); + } catch (IOException ex) { + // simply close the connection + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, OutputUtils + .stackTraceToString(ex)); + } + closeConnection(key, "server closed connection: "+ex); + } catch (NotYetConnectedException e) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, OutputUtils + .stackTraceToString(e)); + } + closeConnection(key, "server closed connection: "+e); + } + } + + private void connectConnection(SelectionKey key) { + final RPCClientConnection con = (RPCClientConnection) key.attachment(); + final ChannelIO channel = con.getChannel(); + + try { + if (channel.isConnectionPending()) { + channel.finishConnect(); + } + synchronized (con) { + if (!con.getSendQueue().isEmpty()) { + key.interestOps(SelectionKey.OP_WRITE | SelectionKey.OP_READ); + } + } + con.connected(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connected from %s to %s", con + .getChannel().socket().getLocalSocketAddress().toString(), con.getEndpointString()); + } + } catch (CancelledKeyException ex) { + con.connectFailed(); + closeConnection(key, "server '" + con.getEndpointString() + "' not reachable ("+ex+")"); + } catch (IOException ex) { + con.connectFailed(); + closeConnection(key, "server '" + con.getEndpointString() + "' not reachable ("+ex+")"); + } + + } + + private void closeConnection(SelectionKey key, String errorMessage) { + final RPCClientConnection con = (RPCClientConnection) key.attachment(); + final ChannelIO channel = con.getChannel(); + + List cancelRq = new LinkedList(); + synchronized (con) { + // remove the connection from the selector and close socket + try { + key.cancel(); + channel.close(); + } catch (Exception ex) { + } + cancelRq.addAll(con.getRequests().values()); + cancelRq.addAll(con.getSendQueue()); + con.getRequests().clear(); + con.getSendQueue().clear(); + con.setChannel(null); + } + + // notify listeners + for (RPCClientRequest rq : cancelRq) { + rq.getResponse().requestFailed("sending RPC failed: "+errorMessage); + rq.freeBuffers(); + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "closing connection to %s", con + .getEndpointString()); + } + } + + private void checkForTimers() { + // poor man's timer + long now = System.currentTimeMillis(); + if (now >= lastCheck + TIMEOUT_GRANULARITY) { + // check for timed out requests + synchronized (connections) { + Iterator conIter = connections.values().iterator(); + while (conIter.hasNext()) { + final RPCClientConnection con = conIter.next(); + + if (con.getLastUsed() < (now - connectionTimeout)) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "removing idle connection"); + } + try { + conIter.remove(); + closeConnection(con.getChannel().keyFor(selector), null); + } catch (Exception ex) { + } + } else { + // check for request timeout + List cancelRq = new LinkedList(); + synchronized (con) { + Iterator iter = con.getRequests().values().iterator(); + while (iter.hasNext()) { + final RPCClientRequest rq = iter.next(); + if (rq.getTimeQueued() + requestTimeout < now) { + cancelRq.add(rq); + iter.remove(); + } + } + iter = con.getSendQueue().iterator(); + while (iter.hasNext()) { + final RPCClientRequest rq = iter.next(); + if (rq.getTimeQueued() + requestTimeout < now) { + cancelRq.add(rq); + iter.remove(); + } else { + // requests are ordered :-) + break; + } + } + } + for (RPCClientRequest rq : cancelRq) { + rq.getResponse().requestFailed("sending RPC failed: request timed out"); + rq.freeBuffers(); + } + + } + } + + lastCheck = now; + } + } + } + + @Override + public void shutdown() { + this.quit = true; + this.interrupt(); + } + + /** + * Returns the number of bytes received and transferred from/to a server. + * @param server + * @return an array with the number of bytes received [0] and sent [1] + */ + public long[] getTransferStats(InetSocketAddress server) { + RPCClientConnection con = null; + synchronized (connections) { + con = connections.get(server); + } + if (con == null) + return null; + else + return new long[]{con.bytesRX,con.bytesTX}; + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponse.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponse.java new file mode 100644 index 0000000..569ef7e --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponse.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.client; + +import com.google.protobuf.Message; +import java.io.IOException; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; + +/** + * + * @author bjko + */ +public class RPCResponse implements RPCResponseListener { + + private static final boolean TRACE_DUPLICATE_RESPONSES = false; + + private RPCClientRequest request; + + private RPCResponseAvailableListener listener; + + private String errorMessage; + + private boolean failed; + + private final V responsePrototype; + + private Object attachment; + + private ReusableBuffer message, data; + + + public RPCResponse(V responsePrototype) { + failed = false; + this.responsePrototype = responsePrototype; + } + + public void freeBuffers() { + if (request != null) + request.freeBuffers(); + } + + public void registerListener(RPCResponseAvailableListener listener) { + synchronized (this) { + this.listener = listener; + + if (request != null || failed) { + //do notification + listener.responseAvailable(this); + } + } + } + + public V get() throws IOException, InterruptedException { + waitForResult(); + if (failed) { + throw new IOException(errorMessage); + } else { + if (request.getResponseHeader().getMessageType() == MessageType.RPC_RESPONSE_SUCCESS) { + if (responsePrototype != null) { + if (message != null) { + ReusableBufferInputStream rbis = new ReusableBufferInputStream(message); + V responseObject = (V) responsePrototype.newBuilderForType().mergeFrom(rbis).build(); + assert(responseObject != null); + BufferPool.free(message); + message = null; + return responseObject; + } else { + return (V) responsePrototype.getDefaultInstanceForType(); + } + } else { + if (message != null) + throw new RuntimeException("specify response prototype for null message!"); + return null; + } + } else { + ErrorResponse err = request.getResponseHeader().getErrorResponse(); + throw new PBRPCException(err); + } + } + } + + public void setAttachment(Object attachment) { + this.attachment = attachment; + } + + public Object getAttachment() { + return this.attachment; + } + + public ReusableBuffer getData() throws InterruptedException { + waitForResult(); + return data; + } + + public void waitForResult() throws InterruptedException { + synchronized (this) { + if (request == null && !failed) + this.wait(); + } + } + + @Override + public void responseAvailable(RPCClientRequest request, ReusableBuffer message, ReusableBuffer data) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "response received"); + synchronized (this) { + /*if (TRACE_DUPLICATE_RESPONSES) { + if (responseTrace != null) { + StringBuffer strace = new StringBuffer(); + for (int i = responseTrace.length-1; i >= 0; i--) { + strace.append("\t"); + strace.append(responseTrace[i].toString()); + } + throw new RuntimeException("response already set:\n"+strace.toString()); + } else { + responseTrace = Thread.currentThread().getStackTrace(); + } + }*/ + this.message = message; + this.data = data; + this.request = request; + if (listener != null) + listener.responseAvailable(this); + this.notify(); + } + } + + @Override + public void requestFailed(String errorMessage) { + synchronized (this) { + this.failed = true; + this.errorMessage = errorMessage; + if (listener != null) + listener.responseAvailable(this); + this.notify(); + } + } + + /** + * duration of request from sending the request until the response + * was received completeley. + * @return duration in ns + */ + public long getDuration() { + return request.getDuration(); + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponseAvailableListener.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponseAvailableListener.java new file mode 100644 index 0000000..c5fb512 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponseAvailableListener.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + + +package org.xtreemfs.foundation.pbrpc.client; + +import com.google.protobuf.Message; + + +/** + * + * @author bjko + */ +public interface RPCResponseAvailableListener { + + public void responseAvailable(RPCResponse r); + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponseListener.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponseListener.java new file mode 100644 index 0000000..ec3781e --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/client/RPCResponseListener.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.client; + +import com.google.protobuf.Message; +import org.xtreemfs.foundation.buffer.ReusableBuffer; + +/** + * + * @author bjko + */ +public interface RPCResponseListener { + + public void responseAvailable(RPCClientRequest request, ReusableBuffer message, ReusableBuffer data); + + public void requestFailed(String reason); + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PBRPC.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PBRPC.java new file mode 100644 index 0000000..eb0e279 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PBRPC.java @@ -0,0 +1,98 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: include/PBRPC.proto + +package org.xtreemfs.foundation.pbrpc.generatedinterfaces; + +public final class PBRPC { + private PBRPC() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.dataIn); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.dataOut); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.interfaceId); + } + public static final int PROC_ID_FIELD_NUMBER = 50001; + /** + * extend .google.protobuf.MethodOptions { ... } + */ + public static final + com.google.protobuf.GeneratedMessage.GeneratedExtension< + com.google.protobuf.DescriptorProtos.MethodOptions, + java.lang.Integer> procId = com.google.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + java.lang.Integer.class, + null); + public static final int DATA_IN_FIELD_NUMBER = 50004; + /** + * extend .google.protobuf.MethodOptions { ... } + */ + public static final + com.google.protobuf.GeneratedMessage.GeneratedExtension< + com.google.protobuf.DescriptorProtos.MethodOptions, + java.lang.Boolean> dataIn = com.google.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + java.lang.Boolean.class, + null); + public static final int DATA_OUT_FIELD_NUMBER = 50003; + /** + * extend .google.protobuf.MethodOptions { ... } + */ + public static final + com.google.protobuf.GeneratedMessage.GeneratedExtension< + com.google.protobuf.DescriptorProtos.MethodOptions, + java.lang.Boolean> dataOut = com.google.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + java.lang.Boolean.class, + null); + public static final int INTERFACE_ID_FIELD_NUMBER = 50002; + /** + * extend .google.protobuf.ServiceOptions { ... } + */ + public static final + com.google.protobuf.GeneratedMessage.GeneratedExtension< + com.google.protobuf.DescriptorProtos.ServiceOptions, + java.lang.Integer> interfaceId = com.google.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + java.lang.Integer.class, + null); + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\023include/PBRPC.proto\022\016xtreemfs.pbrpc\032 g" + + "oogle/protobuf/descriptor.proto:1\n\007proc_" + + "id\022\036.google.protobuf.MethodOptions\030\321\206\003 \001" + + "(\007:1\n\007data_in\022\036.google.protobuf.MethodOp" + + "tions\030\324\206\003 \001(\010:2\n\010data_out\022\036.google.proto" + + "buf.MethodOptions\030\323\206\003 \001(\010:7\n\014interface_i" + + "d\022\037.google.protobuf.ServiceOptions\030\322\206\003 \001" + + "(\007B3\n1org.xtreemfs.foundation.pbrpc.gene" + + "ratedinterfaces" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + procId.internalInit(descriptor.getExtensions().get(0)); + dataIn.internalInit(descriptor.getExtensions().get(1)); + dataOut.internalInit(descriptor.getExtensions().get(2)); + interfaceId.internalInit(descriptor.getExtensions().get(3)); + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + com.google.protobuf.DescriptorProtos.getDescriptor(), + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/Ping.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/Ping.java new file mode 100644 index 0000000..3c0916f --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/Ping.java @@ -0,0 +1,2991 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: pbrpc/Ping.proto + +package org.xtreemfs.foundation.pbrpc.generatedinterfaces; + +public final class Ping { + private Ping() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + public interface PingRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string text = 1; + /** + * required string text = 1; + */ + boolean hasText(); + /** + * required string text = 1; + */ + java.lang.String getText(); + /** + * required string text = 1; + */ + com.google.protobuf.ByteString + getTextBytes(); + + // required bool sendError = 2; + /** + * required bool sendError = 2; + */ + boolean hasSendError(); + /** + * required bool sendError = 2; + */ + boolean getSendError(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.PingRequest} + */ + public static final class PingRequest extends + com.google.protobuf.GeneratedMessage + implements PingRequestOrBuilder { + // Use PingRequest.newBuilder() to construct. + private PingRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private PingRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final PingRequest defaultInstance; + public static PingRequest getDefaultInstance() { + return defaultInstance; + } + + public PingRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private PingRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + text_ = input.readBytes(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + sendError_ = input.readBool(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public PingRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new PingRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string text = 1; + public static final int TEXT_FIELD_NUMBER = 1; + private java.lang.Object text_; + /** + * required string text = 1; + */ + public boolean hasText() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string text = 1; + */ + public java.lang.String getText() { + java.lang.Object ref = text_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + text_ = s; + } + return s; + } + } + /** + * required string text = 1; + */ + public com.google.protobuf.ByteString + getTextBytes() { + java.lang.Object ref = text_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + text_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required bool sendError = 2; + public static final int SENDERROR_FIELD_NUMBER = 2; + private boolean sendError_; + /** + * required bool sendError = 2; + */ + public boolean hasSendError() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool sendError = 2; + */ + public boolean getSendError() { + return sendError_; + } + + private void initFields() { + text_ = ""; + sendError_ = false; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasText()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasSendError()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getTextBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBool(2, sendError_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getTextBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(2, sendError_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.PingRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + text_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + sendError_ = false; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingRequest_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.text_ = text_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.sendError_ = sendError_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest.getDefaultInstance()) return this; + if (other.hasText()) { + bitField0_ |= 0x00000001; + text_ = other.text_; + onChanged(); + } + if (other.hasSendError()) { + setSendError(other.getSendError()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasText()) { + + return false; + } + if (!hasSendError()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string text = 1; + private java.lang.Object text_ = ""; + /** + * required string text = 1; + */ + public boolean hasText() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string text = 1; + */ + public java.lang.String getText() { + java.lang.Object ref = text_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + text_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string text = 1; + */ + public com.google.protobuf.ByteString + getTextBytes() { + java.lang.Object ref = text_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + text_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string text = 1; + */ + public Builder setText( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + text_ = value; + onChanged(); + return this; + } + /** + * required string text = 1; + */ + public Builder clearText() { + bitField0_ = (bitField0_ & ~0x00000001); + text_ = getDefaultInstance().getText(); + onChanged(); + return this; + } + /** + * required string text = 1; + */ + public Builder setTextBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + text_ = value; + onChanged(); + return this; + } + + // required bool sendError = 2; + private boolean sendError_ ; + /** + * required bool sendError = 2; + */ + public boolean hasSendError() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool sendError = 2; + */ + public boolean getSendError() { + return sendError_; + } + /** + * required bool sendError = 2; + */ + public Builder setSendError(boolean value) { + bitField0_ |= 0x00000002; + sendError_ = value; + onChanged(); + return this; + } + /** + * required bool sendError = 2; + */ + public Builder clearSendError() { + bitField0_ = (bitField0_ & ~0x00000002); + sendError_ = false; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.PingRequest) + } + + static { + defaultInstance = new PingRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.PingRequest) + } + + public interface PingResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + boolean hasResult(); + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult getResult(); + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResultOrBuilder getResultOrBuilder(); + + // optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + boolean hasError(); + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError getError(); + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingErrorOrBuilder getErrorOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.PingResponse} + */ + public static final class PingResponse extends + com.google.protobuf.GeneratedMessage + implements PingResponseOrBuilder { + // Use PingResponse.newBuilder() to construct. + private PingResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private PingResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final PingResponse defaultInstance; + public static PingResponse getDefaultInstance() { + return defaultInstance; + } + + public PingResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private PingResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = result_.toBuilder(); + } + result_ = input.readMessage(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(result_); + result_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = error_.toBuilder(); + } + error_ = input.readMessage(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(error_); + error_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public PingResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new PingResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public interface PingResultOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string text = 1; + /** + * required string text = 1; + */ + boolean hasText(); + /** + * required string text = 1; + */ + java.lang.String getText(); + /** + * required string text = 1; + */ + com.google.protobuf.ByteString + getTextBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.PingResponse.PingResult} + */ + public static final class PingResult extends + com.google.protobuf.GeneratedMessage + implements PingResultOrBuilder { + // Use PingResult.newBuilder() to construct. + private PingResult(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private PingResult(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final PingResult defaultInstance; + public static PingResult getDefaultInstance() { + return defaultInstance; + } + + public PingResult getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private PingResult( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + text_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_PingResult_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_PingResult_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public PingResult parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new PingResult(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string text = 1; + public static final int TEXT_FIELD_NUMBER = 1; + private java.lang.Object text_; + /** + * required string text = 1; + */ + public boolean hasText() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string text = 1; + */ + public java.lang.String getText() { + java.lang.Object ref = text_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + text_ = s; + } + return s; + } + } + /** + * required string text = 1; + */ + public com.google.protobuf.ByteString + getTextBytes() { + java.lang.Object ref = text_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + text_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + text_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasText()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getTextBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getTextBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.PingResponse.PingResult} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResultOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_PingResult_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_PingResult_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + text_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_PingResult_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.text_ = text_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.getDefaultInstance()) return this; + if (other.hasText()) { + bitField0_ |= 0x00000001; + text_ = other.text_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasText()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string text = 1; + private java.lang.Object text_ = ""; + /** + * required string text = 1; + */ + public boolean hasText() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string text = 1; + */ + public java.lang.String getText() { + java.lang.Object ref = text_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + text_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string text = 1; + */ + public com.google.protobuf.ByteString + getTextBytes() { + java.lang.Object ref = text_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + text_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string text = 1; + */ + public Builder setText( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + text_ = value; + onChanged(); + return this; + } + /** + * required string text = 1; + */ + public Builder clearText() { + bitField0_ = (bitField0_ & ~0x00000001); + text_ = getDefaultInstance().getText(); + onChanged(); + return this; + } + /** + * required string text = 1; + */ + public Builder setTextBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + text_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.PingResponse.PingResult) + } + + static { + defaultInstance = new PingResult(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.PingResponse.PingResult) + } + + public interface PingErrorOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string errorMessage = 1; + /** + * required string errorMessage = 1; + */ + boolean hasErrorMessage(); + /** + * required string errorMessage = 1; + */ + java.lang.String getErrorMessage(); + /** + * required string errorMessage = 1; + */ + com.google.protobuf.ByteString + getErrorMessageBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.PingResponse.PingError} + */ + public static final class PingError extends + com.google.protobuf.GeneratedMessage + implements PingErrorOrBuilder { + // Use PingError.newBuilder() to construct. + private PingError(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private PingError(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final PingError defaultInstance; + public static PingError getDefaultInstance() { + return defaultInstance; + } + + public PingError getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private PingError( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + errorMessage_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_PingError_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_PingError_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public PingError parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new PingError(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string errorMessage = 1; + public static final int ERRORMESSAGE_FIELD_NUMBER = 1; + private java.lang.Object errorMessage_; + /** + * required string errorMessage = 1; + */ + public boolean hasErrorMessage() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string errorMessage = 1; + */ + public java.lang.String getErrorMessage() { + java.lang.Object ref = errorMessage_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + errorMessage_ = s; + } + return s; + } + } + /** + * required string errorMessage = 1; + */ + public com.google.protobuf.ByteString + getErrorMessageBytes() { + java.lang.Object ref = errorMessage_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + errorMessage_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + errorMessage_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasErrorMessage()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getErrorMessageBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getErrorMessageBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.PingResponse.PingError} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingErrorOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_PingError_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_PingError_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + errorMessage_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_PingError_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.errorMessage_ = errorMessage_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.getDefaultInstance()) return this; + if (other.hasErrorMessage()) { + bitField0_ |= 0x00000001; + errorMessage_ = other.errorMessage_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasErrorMessage()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string errorMessage = 1; + private java.lang.Object errorMessage_ = ""; + /** + * required string errorMessage = 1; + */ + public boolean hasErrorMessage() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string errorMessage = 1; + */ + public java.lang.String getErrorMessage() { + java.lang.Object ref = errorMessage_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + errorMessage_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string errorMessage = 1; + */ + public com.google.protobuf.ByteString + getErrorMessageBytes() { + java.lang.Object ref = errorMessage_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + errorMessage_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string errorMessage = 1; + */ + public Builder setErrorMessage( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + errorMessage_ = value; + onChanged(); + return this; + } + /** + * required string errorMessage = 1; + */ + public Builder clearErrorMessage() { + bitField0_ = (bitField0_ & ~0x00000001); + errorMessage_ = getDefaultInstance().getErrorMessage(); + onChanged(); + return this; + } + /** + * required string errorMessage = 1; + */ + public Builder setErrorMessageBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + errorMessage_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.PingResponse.PingError) + } + + static { + defaultInstance = new PingError(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.PingResponse.PingError) + } + + private int bitField0_; + // optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + public static final int RESULT_FIELD_NUMBER = 1; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult result_; + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + public boolean hasResult() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult getResult() { + return result_; + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResultOrBuilder getResultOrBuilder() { + return result_; + } + + // optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + public static final int ERROR_FIELD_NUMBER = 2; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError error_; + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + public boolean hasError() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError getError() { + return error_; + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingErrorOrBuilder getErrorOrBuilder() { + return error_; + } + + private void initFields() { + result_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.getDefaultInstance(); + error_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (hasResult()) { + if (!getResult().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasError()) { + if (!getError().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, result_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, error_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, result_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, error_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.PingResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getResultFieldBuilder(); + getErrorFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (resultBuilder_ == null) { + result_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.getDefaultInstance(); + } else { + resultBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (errorBuilder_ == null) { + error_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.getDefaultInstance(); + } else { + errorBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_PingResponse_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (resultBuilder_ == null) { + result.result_ = result_; + } else { + result.result_ = resultBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + if (errorBuilder_ == null) { + result.error_ = error_; + } else { + result.error_ = errorBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.getDefaultInstance()) return this; + if (other.hasResult()) { + mergeResult(other.getResult()); + } + if (other.hasError()) { + mergeError(other.getError()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (hasResult()) { + if (!getResult().isInitialized()) { + + return false; + } + } + if (hasError()) { + if (!getError().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult result_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResultOrBuilder> resultBuilder_; + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + public boolean hasResult() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult getResult() { + if (resultBuilder_ == null) { + return result_; + } else { + return resultBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + public Builder setResult(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult value) { + if (resultBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + result_ = value; + onChanged(); + } else { + resultBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + public Builder setResult( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.Builder builderForValue) { + if (resultBuilder_ == null) { + result_ = builderForValue.build(); + onChanged(); + } else { + resultBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + public Builder mergeResult(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult value) { + if (resultBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + result_ != org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.getDefaultInstance()) { + result_ = + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.newBuilder(result_).mergeFrom(value).buildPartial(); + } else { + result_ = value; + } + onChanged(); + } else { + resultBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + public Builder clearResult() { + if (resultBuilder_ == null) { + result_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.getDefaultInstance(); + onChanged(); + } else { + resultBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.Builder getResultBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getResultFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResultOrBuilder getResultOrBuilder() { + if (resultBuilder_ != null) { + return resultBuilder_.getMessageOrBuilder(); + } else { + return result_; + } + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingResult result = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResultOrBuilder> + getResultFieldBuilder() { + if (resultBuilder_ == null) { + resultBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResult.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingResultOrBuilder>( + result_, + getParentForChildren(), + isClean()); + result_ = null; + } + return resultBuilder_; + } + + // optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError error_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingErrorOrBuilder> errorBuilder_; + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + public boolean hasError() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError getError() { + if (errorBuilder_ == null) { + return error_; + } else { + return errorBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + public Builder setError(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError value) { + if (errorBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + error_ = value; + onChanged(); + } else { + errorBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + public Builder setError( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.Builder builderForValue) { + if (errorBuilder_ == null) { + error_ = builderForValue.build(); + onChanged(); + } else { + errorBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + public Builder mergeError(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError value) { + if (errorBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + error_ != org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.getDefaultInstance()) { + error_ = + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.newBuilder(error_).mergeFrom(value).buildPartial(); + } else { + error_ = value; + } + onChanged(); + } else { + errorBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + public Builder clearError() { + if (errorBuilder_ == null) { + error_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.getDefaultInstance(); + onChanged(); + } else { + errorBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.Builder getErrorBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getErrorFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingErrorOrBuilder getErrorOrBuilder() { + if (errorBuilder_ != null) { + return errorBuilder_.getMessageOrBuilder(); + } else { + return error_; + } + } + /** + * optional .xtreemfs.pbrpc.PingResponse.PingError error = 2; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingErrorOrBuilder> + getErrorFieldBuilder() { + if (errorBuilder_ == null) { + errorBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingError.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse.PingErrorOrBuilder>( + error_, + getParentForChildren(), + isClean()); + error_ = null; + } + return errorBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.PingResponse) + } + + static { + defaultInstance = new PingResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.PingResponse) + } + + public interface Ping_emptyRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Ping_emptyRequest} + */ + public static final class Ping_emptyRequest extends + com.google.protobuf.GeneratedMessage + implements Ping_emptyRequestOrBuilder { + // Use Ping_emptyRequest.newBuilder() to construct. + private Ping_emptyRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Ping_emptyRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Ping_emptyRequest defaultInstance; + public static Ping_emptyRequest getDefaultInstance() { + return defaultInstance; + } + + public Ping_emptyRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Ping_emptyRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_Ping_emptyRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_Ping_emptyRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Ping_emptyRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Ping_emptyRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private void initFields() { + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Ping_emptyRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_Ping_emptyRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_Ping_emptyRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_Ping_emptyRequest_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest(this); + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest.getDefaultInstance()) return this; + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.Ping_emptyRequest) + } + + static { + defaultInstance = new Ping_emptyRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Ping_emptyRequest) + } + + public interface Ping_emptyResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Ping_emptyResponse} + */ + public static final class Ping_emptyResponse extends + com.google.protobuf.GeneratedMessage + implements Ping_emptyResponseOrBuilder { + // Use Ping_emptyResponse.newBuilder() to construct. + private Ping_emptyResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Ping_emptyResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Ping_emptyResponse defaultInstance; + public static Ping_emptyResponse getDefaultInstance() { + return defaultInstance; + } + + public Ping_emptyResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Ping_emptyResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_Ping_emptyResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_Ping_emptyResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Ping_emptyResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Ping_emptyResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private void initFields() { + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Ping_emptyResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_Ping_emptyResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_Ping_emptyResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.internal_static_xtreemfs_pbrpc_Ping_emptyResponse_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse(this); + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse.getDefaultInstance()) return this; + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.Ping_emptyResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.Ping_emptyResponse) + } + + static { + defaultInstance = new Ping_emptyResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Ping_emptyResponse) + } + + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_PingRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_PingRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_PingResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_PingResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_PingResponse_PingResult_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_PingResponse_PingResult_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_PingResponse_PingError_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_PingResponse_PingError_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_Ping_emptyRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_Ping_emptyRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_Ping_emptyResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_Ping_emptyResponse_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\020pbrpc/Ping.proto\022\016xtreemfs.pbrpc\032\023incl" + + "ude/PBRPC.proto\".\n\013PingRequest\022\014\n\004text\030\001" + + " \002(\t\022\021\n\tsendError\030\002 \002(\010\"\275\001\n\014PingResponse" + + "\0227\n\006result\030\001 \001(\0132\'.xtreemfs.pbrpc.PingRe" + + "sponse.PingResult\0225\n\005error\030\002 \001(\0132&.xtree" + + "mfs.pbrpc.PingResponse.PingError\032\032\n\nPing" + + "Result\022\014\n\004text\030\001 \002(\t\032!\n\tPingError\022\024\n\014err" + + "orMessage\030\001 \002(\t\"\023\n\021Ping_emptyRequest\"\024\n\022" + + "Ping_emptyResponse2\305\001\n\013PingService\022P\n\006do" + + "Ping\022\033.xtreemfs.pbrpc.PingRequest\032\034.xtre", + "emfs.pbrpc.PingResponse\"\013\215\265\030\001\000\000\000\240\265\030\001\022[\n\t" + + "emptyPing\022!.xtreemfs.pbrpc.Ping_emptyReq" + + "uest\032\".xtreemfs.pbrpc.Ping_emptyResponse" + + "\"\007\215\265\030\002\000\000\000\032\007\225\265\030\001\000\000\000B3\n1org.xtreemfs.found" + + "ation.pbrpc.generatedinterfaces" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_xtreemfs_pbrpc_PingRequest_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_xtreemfs_pbrpc_PingRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_PingRequest_descriptor, + new java.lang.String[] { "Text", "SendError", }); + internal_static_xtreemfs_pbrpc_PingResponse_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_xtreemfs_pbrpc_PingResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_PingResponse_descriptor, + new java.lang.String[] { "Result", "Error", }); + internal_static_xtreemfs_pbrpc_PingResponse_PingResult_descriptor = + internal_static_xtreemfs_pbrpc_PingResponse_descriptor.getNestedTypes().get(0); + internal_static_xtreemfs_pbrpc_PingResponse_PingResult_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_PingResponse_PingResult_descriptor, + new java.lang.String[] { "Text", }); + internal_static_xtreemfs_pbrpc_PingResponse_PingError_descriptor = + internal_static_xtreemfs_pbrpc_PingResponse_descriptor.getNestedTypes().get(1); + internal_static_xtreemfs_pbrpc_PingResponse_PingError_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_PingResponse_PingError_descriptor, + new java.lang.String[] { "ErrorMessage", }); + internal_static_xtreemfs_pbrpc_Ping_emptyRequest_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_xtreemfs_pbrpc_Ping_emptyRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_Ping_emptyRequest_descriptor, + new java.lang.String[] { }); + internal_static_xtreemfs_pbrpc_Ping_emptyResponse_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_xtreemfs_pbrpc_Ping_emptyResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_Ping_emptyResponse_descriptor, + new java.lang.String[] { }); + com.google.protobuf.ExtensionRegistry registry = + com.google.protobuf.ExtensionRegistry.newInstance(); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.dataIn); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.interfaceId); + return registry; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.getDescriptor(), + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PingServiceClient.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PingServiceClient.java new file mode 100644 index 0000000..d3acf62 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PingServiceClient.java @@ -0,0 +1,56 @@ +//automatically generated from Ping.proto at Thu Dec 11 16:01:46 CET 2014 +//(c) 2014. See LICENSE file for details. + +package org.xtreemfs.foundation.pbrpc.generatedinterfaces; + +import java.io.IOException; +import java.util.List; +import java.net.InetSocketAddress; +import com.google.protobuf.Message; +import com.google.protobuf.ByteString; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; + +public class PingServiceClient { + + private RPCNIOSocketClient client; + private InetSocketAddress defaultServer; + + public PingServiceClient(RPCNIOSocketClient client, InetSocketAddress defaultServer) { + this.client = client; + this.defaultServer = defaultServer; + } + + public RPCResponse doPing(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Ping.PingRequest input, ReusableBuffer data) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(Ping.PingResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 1, 1, input, data, response, false); + return response; + } + + public RPCResponse doPing(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String text, boolean sendError, ReusableBuffer data) throws IOException { + final Ping.PingRequest msg = Ping.PingRequest.newBuilder().setText(text).setSendError(sendError).build(); + return doPing(server, authHeader, userCreds,msg, data); + } + + public RPCResponse emptyPing(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Ping.Ping_emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 1, 2, input, null, response, false); + return response; + } + + public RPCResponse emptyPing(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return emptyPing(server, authHeader, userCreds,null); + } + + public boolean clientIsAlive() { + return client.isAlive(); + } +} \ No newline at end of file diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PingServiceConstants.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PingServiceConstants.java new file mode 100644 index 0000000..444a62a --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PingServiceConstants.java @@ -0,0 +1,32 @@ +//automatically generated from Ping.proto at Thu Dec 11 16:01:46 CET 2014 +//(c) 2014. See LICENSE file for details. + +package org.xtreemfs.foundation.pbrpc.generatedinterfaces; + +import com.google.protobuf.Message; + +public class PingServiceConstants { + + public static final int INTERFACE_ID = 1; + public static final int PROC_ID_DOPING = 1; + public static final int PROC_ID_EMPTYPING = 2; + + public static Message getRequestMessage(int procId) { + switch (procId) { + case 1: return Ping.PingRequest.getDefaultInstance(); + case 2: return null; + default: throw new RuntimeException("unknown procedure id"); + } + } + + + public static Message getResponseMessage(int procId) { + switch (procId) { + case 1: return Ping.PingResponse.getDefaultInstance(); + case 2: return null; + default: throw new RuntimeException("unknown procedure id"); + } + } + + +} \ No newline at end of file diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/RPC.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/RPC.java new file mode 100644 index 0000000..8ae30f8 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/RPC.java @@ -0,0 +1,6305 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: pbrpc/RPC.proto + +package org.xtreemfs.foundation.pbrpc.generatedinterfaces; + +public final class RPC { + private RPC() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + /** + * Protobuf enum {@code xtreemfs.pbrpc.MessageType} + * + *
+   * Encodes the type of the RPC message sent.
+   * 
+ */ + public enum MessageType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * RPC_REQUEST = 0; + * + *
+     * RPC request to execute method.
+     * 
+ */ + RPC_REQUEST(0, 0), + /** + * RPC_RESPONSE_SUCCESS = 1; + * + *
+     * RPC response after successful execution of method.
+     * 
+ */ + RPC_RESPONSE_SUCCESS(1, 1), + /** + * RPC_RESPONSE_ERROR = 2; + * + *
+     * RPC response when execution of a method failed, including POSIX errors.
+     * 
+ */ + RPC_RESPONSE_ERROR(2, 2), + ; + + /** + * RPC_REQUEST = 0; + * + *
+     * RPC request to execute method.
+     * 
+ */ + public static final int RPC_REQUEST_VALUE = 0; + /** + * RPC_RESPONSE_SUCCESS = 1; + * + *
+     * RPC response after successful execution of method.
+     * 
+ */ + public static final int RPC_RESPONSE_SUCCESS_VALUE = 1; + /** + * RPC_RESPONSE_ERROR = 2; + * + *
+     * RPC response when execution of a method failed, including POSIX errors.
+     * 
+ */ + public static final int RPC_RESPONSE_ERROR_VALUE = 2; + + + public final int getNumber() { return value; } + + public static MessageType valueOf(int value) { + switch (value) { + case 0: return RPC_REQUEST; + case 1: return RPC_RESPONSE_SUCCESS; + case 2: return RPC_RESPONSE_ERROR; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public MessageType findValueByNumber(int number) { + return MessageType.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.getDescriptor().getEnumTypes().get(0); + } + + private static final MessageType[] VALUES = values(); + + public static MessageType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private MessageType(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.MessageType) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.AuthType} + * + *
+   * Authentication type provided for request.
+   * 
+ */ + public enum AuthType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * AUTH_NONE = 0; + * + *
+     * No authentication.
+     * 
+ */ + AUTH_NONE(0, 0), + /** + * AUTH_PASSWORD = 1; + * + *
+     * Plain text admin password authentication.
+     * 
+ */ + AUTH_PASSWORD(1, 1), + ; + + /** + * AUTH_NONE = 0; + * + *
+     * No authentication.
+     * 
+ */ + public static final int AUTH_NONE_VALUE = 0; + /** + * AUTH_PASSWORD = 1; + * + *
+     * Plain text admin password authentication.
+     * 
+ */ + public static final int AUTH_PASSWORD_VALUE = 1; + + + public final int getNumber() { return value; } + + public static AuthType valueOf(int value) { + switch (value) { + case 0: return AUTH_NONE; + case 1: return AUTH_PASSWORD; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public AuthType findValueByNumber(int number) { + return AuthType.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.getDescriptor().getEnumTypes().get(1); + } + + private static final AuthType[] VALUES = values(); + + public static AuthType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private AuthType(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.AuthType) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.ErrorType} + * + *
+   * Error types.
+   * 
+ */ + public enum ErrorType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * INVALID_INTERFACE_ID = 1; + * + *
+     * Requested interface_id not implemented by server.
+     * 
+ */ + INVALID_INTERFACE_ID(0, 1), + /** + * INVALID_PROC_ID = 2; + * + *
+     * Requested procedure_id not implemented by serevr.
+     * 
+ */ + INVALID_PROC_ID(1, 2), + /** + * GARBAGE_ARGS = 3; + * + *
+     * Server cannot parse the RPC request.
+     * 
+ */ + GARBAGE_ARGS(2, 3), + /** + * AUTH_FAILED = 4; + * + *
+     * Authentication failed, access denied.
+     * 
+ */ + AUTH_FAILED(3, 4), + /** + * INTERNAL_SERVER_ERROR = 5; + * + *
+     * Unspecific internal server error that caused the RPC to fail.
+     * 
+ */ + INTERNAL_SERVER_ERROR(4, 5), + /** + * ERRNO = 6; + * + *
+     * POSIX errno error (not necessarily a failure), e.g. ENOENT.
+     * POSIXErrno contains details that can be passed to an application.
+     * 
+ */ + ERRNO(5, 6), + /** + * REDIRECT = 7; + * + *
+     * Server redirects to another server implementing the same interface.
+     * 
+ */ + REDIRECT(6, 7), + /** + * INVALID_VIEW = 8; + * + *
+     * Request failed, due to an invalid view (i.e. an outdated xlocset).
+     * 
+ */ + INVALID_VIEW(7, 8), + /** + * IO_ERROR = 100; + * + *
+     * Generic IO_ERROR to be used by the RPC implementation.
+     * 
+ */ + IO_ERROR(8, 100), + ; + + /** + * INVALID_INTERFACE_ID = 1; + * + *
+     * Requested interface_id not implemented by server.
+     * 
+ */ + public static final int INVALID_INTERFACE_ID_VALUE = 1; + /** + * INVALID_PROC_ID = 2; + * + *
+     * Requested procedure_id not implemented by serevr.
+     * 
+ */ + public static final int INVALID_PROC_ID_VALUE = 2; + /** + * GARBAGE_ARGS = 3; + * + *
+     * Server cannot parse the RPC request.
+     * 
+ */ + public static final int GARBAGE_ARGS_VALUE = 3; + /** + * AUTH_FAILED = 4; + * + *
+     * Authentication failed, access denied.
+     * 
+ */ + public static final int AUTH_FAILED_VALUE = 4; + /** + * INTERNAL_SERVER_ERROR = 5; + * + *
+     * Unspecific internal server error that caused the RPC to fail.
+     * 
+ */ + public static final int INTERNAL_SERVER_ERROR_VALUE = 5; + /** + * ERRNO = 6; + * + *
+     * POSIX errno error (not necessarily a failure), e.g. ENOENT.
+     * POSIXErrno contains details that can be passed to an application.
+     * 
+ */ + public static final int ERRNO_VALUE = 6; + /** + * REDIRECT = 7; + * + *
+     * Server redirects to another server implementing the same interface.
+     * 
+ */ + public static final int REDIRECT_VALUE = 7; + /** + * INVALID_VIEW = 8; + * + *
+     * Request failed, due to an invalid view (i.e. an outdated xlocset).
+     * 
+ */ + public static final int INVALID_VIEW_VALUE = 8; + /** + * IO_ERROR = 100; + * + *
+     * Generic IO_ERROR to be used by the RPC implementation.
+     * 
+ */ + public static final int IO_ERROR_VALUE = 100; + + + public final int getNumber() { return value; } + + public static ErrorType valueOf(int value) { + switch (value) { + case 1: return INVALID_INTERFACE_ID; + case 2: return INVALID_PROC_ID; + case 3: return GARBAGE_ARGS; + case 4: return AUTH_FAILED; + case 5: return INTERNAL_SERVER_ERROR; + case 6: return ERRNO; + case 7: return REDIRECT; + case 8: return INVALID_VIEW; + case 100: return IO_ERROR; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public ErrorType findValueByNumber(int number) { + return ErrorType.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.getDescriptor().getEnumTypes().get(2); + } + + private static final ErrorType[] VALUES = values(); + + public static ErrorType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private ErrorType(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.ErrorType) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.POSIXErrno} + * + *
+   * Additional error code which can be passed to applications.
+   * See errno.h for details. Values are equivalent to Linux
+   * values, but are different for other unix platforms such as
+   * Mac OS X and Solaris!
+   * 
+ */ + public enum POSIXErrno + implements com.google.protobuf.ProtocolMessageEnum { + /** + * POSIX_ERROR_NONE = 9999; + */ + POSIX_ERROR_NONE(0, 9999), + /** + * POSIX_ERROR_EPERM = 1; + */ + POSIX_ERROR_EPERM(1, 1), + /** + * POSIX_ERROR_ENOENT = 2; + */ + POSIX_ERROR_ENOENT(2, 2), + /** + * POSIX_ERROR_EINTR = 4; + */ + POSIX_ERROR_EINTR(3, 4), + /** + * POSIX_ERROR_EIO = 5; + */ + POSIX_ERROR_EIO(4, 5), + /** + * POSIX_ERROR_EAGAIN = 11; + */ + POSIX_ERROR_EAGAIN(5, 11), + /** + * POSIX_ERROR_EACCES = 13; + */ + POSIX_ERROR_EACCES(6, 13), + /** + * POSIX_ERROR_EEXIST = 17; + */ + POSIX_ERROR_EEXIST(7, 17), + /** + * POSIX_ERROR_EXDEV = 18; + */ + POSIX_ERROR_EXDEV(8, 18), + /** + * POSIX_ERROR_ENODEV = 19; + */ + POSIX_ERROR_ENODEV(9, 19), + /** + * POSIX_ERROR_ENOTDIR = 20; + */ + POSIX_ERROR_ENOTDIR(10, 20), + /** + * POSIX_ERROR_EISDIR = 21; + */ + POSIX_ERROR_EISDIR(11, 21), + /** + * POSIX_ERROR_EINVAL = 22; + */ + POSIX_ERROR_EINVAL(12, 22), + /** + * POSIX_ERROR_ENOSPC = 28; + */ + POSIX_ERROR_ENOSPC(13, 28), + /** + * POSIX_ERROR_ENOTEMPTY = 39; + */ + POSIX_ERROR_ENOTEMPTY(14, 39), + /** + * POSIX_ERROR_ENODATA = 61; + */ + POSIX_ERROR_ENODATA(15, 61), + ; + + /** + * POSIX_ERROR_NONE = 9999; + */ + public static final int POSIX_ERROR_NONE_VALUE = 9999; + /** + * POSIX_ERROR_EPERM = 1; + */ + public static final int POSIX_ERROR_EPERM_VALUE = 1; + /** + * POSIX_ERROR_ENOENT = 2; + */ + public static final int POSIX_ERROR_ENOENT_VALUE = 2; + /** + * POSIX_ERROR_EINTR = 4; + */ + public static final int POSIX_ERROR_EINTR_VALUE = 4; + /** + * POSIX_ERROR_EIO = 5; + */ + public static final int POSIX_ERROR_EIO_VALUE = 5; + /** + * POSIX_ERROR_EAGAIN = 11; + */ + public static final int POSIX_ERROR_EAGAIN_VALUE = 11; + /** + * POSIX_ERROR_EACCES = 13; + */ + public static final int POSIX_ERROR_EACCES_VALUE = 13; + /** + * POSIX_ERROR_EEXIST = 17; + */ + public static final int POSIX_ERROR_EEXIST_VALUE = 17; + /** + * POSIX_ERROR_EXDEV = 18; + */ + public static final int POSIX_ERROR_EXDEV_VALUE = 18; + /** + * POSIX_ERROR_ENODEV = 19; + */ + public static final int POSIX_ERROR_ENODEV_VALUE = 19; + /** + * POSIX_ERROR_ENOTDIR = 20; + */ + public static final int POSIX_ERROR_ENOTDIR_VALUE = 20; + /** + * POSIX_ERROR_EISDIR = 21; + */ + public static final int POSIX_ERROR_EISDIR_VALUE = 21; + /** + * POSIX_ERROR_EINVAL = 22; + */ + public static final int POSIX_ERROR_EINVAL_VALUE = 22; + /** + * POSIX_ERROR_ENOSPC = 28; + */ + public static final int POSIX_ERROR_ENOSPC_VALUE = 28; + /** + * POSIX_ERROR_ENOTEMPTY = 39; + */ + public static final int POSIX_ERROR_ENOTEMPTY_VALUE = 39; + /** + * POSIX_ERROR_ENODATA = 61; + */ + public static final int POSIX_ERROR_ENODATA_VALUE = 61; + + + public final int getNumber() { return value; } + + public static POSIXErrno valueOf(int value) { + switch (value) { + case 9999: return POSIX_ERROR_NONE; + case 1: return POSIX_ERROR_EPERM; + case 2: return POSIX_ERROR_ENOENT; + case 4: return POSIX_ERROR_EINTR; + case 5: return POSIX_ERROR_EIO; + case 11: return POSIX_ERROR_EAGAIN; + case 13: return POSIX_ERROR_EACCES; + case 17: return POSIX_ERROR_EEXIST; + case 18: return POSIX_ERROR_EXDEV; + case 19: return POSIX_ERROR_ENODEV; + case 20: return POSIX_ERROR_ENOTDIR; + case 21: return POSIX_ERROR_EISDIR; + case 22: return POSIX_ERROR_EINVAL; + case 28: return POSIX_ERROR_ENOSPC; + case 39: return POSIX_ERROR_ENOTEMPTY; + case 61: return POSIX_ERROR_ENODATA; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public POSIXErrno findValueByNumber(int number) { + return POSIXErrno.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.getDescriptor().getEnumTypes().get(3); + } + + private static final POSIXErrno[] VALUES = values(); + + public static POSIXErrno valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private POSIXErrno(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.POSIXErrno) + } + + public interface UserCredentialsOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string username = 1; + /** + * required string username = 1; + * + *
+     * Globally unique user ID (GUID).
+     * 
+ */ + boolean hasUsername(); + /** + * required string username = 1; + * + *
+     * Globally unique user ID (GUID).
+     * 
+ */ + java.lang.String getUsername(); + /** + * required string username = 1; + * + *
+     * Globally unique user ID (GUID).
+     * 
+ */ + com.google.protobuf.ByteString + getUsernameBytes(); + + // repeated string groups = 2; + /** + * repeated string groups = 2; + * + *
+     * List of one or more globally unique group IDs (GGID).
+     * 
+ */ + java.util.List + getGroupsList(); + /** + * repeated string groups = 2; + * + *
+     * List of one or more globally unique group IDs (GGID).
+     * 
+ */ + int getGroupsCount(); + /** + * repeated string groups = 2; + * + *
+     * List of one or more globally unique group IDs (GGID).
+     * 
+ */ + java.lang.String getGroups(int index); + /** + * repeated string groups = 2; + * + *
+     * List of one or more globally unique group IDs (GGID).
+     * 
+ */ + com.google.protobuf.ByteString + getGroupsBytes(int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.UserCredentials} + * + *
+   * File system user credentials for executing an operation.
+   * Might be ignored by some operations.
+   * 
+ */ + public static final class UserCredentials extends + com.google.protobuf.GeneratedMessage + implements UserCredentialsOrBuilder { + // Use UserCredentials.newBuilder() to construct. + private UserCredentials(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private UserCredentials(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final UserCredentials defaultInstance; + public static UserCredentials getDefaultInstance() { + return defaultInstance; + } + + public UserCredentials getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private UserCredentials( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + username_ = input.readBytes(); + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + groups_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000002; + } + groups_.add(input.readBytes()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + groups_ = new com.google.protobuf.UnmodifiableLazyStringList(groups_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_UserCredentials_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_UserCredentials_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public UserCredentials parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new UserCredentials(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string username = 1; + public static final int USERNAME_FIELD_NUMBER = 1; + private java.lang.Object username_; + /** + * required string username = 1; + * + *
+     * Globally unique user ID (GUID).
+     * 
+ */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string username = 1; + * + *
+     * Globally unique user ID (GUID).
+     * 
+ */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 1; + * + *
+     * Globally unique user ID (GUID).
+     * 
+ */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // repeated string groups = 2; + public static final int GROUPS_FIELD_NUMBER = 2; + private com.google.protobuf.LazyStringList groups_; + /** + * repeated string groups = 2; + * + *
+     * List of one or more globally unique group IDs (GGID).
+     * 
+ */ + public java.util.List + getGroupsList() { + return groups_; + } + /** + * repeated string groups = 2; + * + *
+     * List of one or more globally unique group IDs (GGID).
+     * 
+ */ + public int getGroupsCount() { + return groups_.size(); + } + /** + * repeated string groups = 2; + * + *
+     * List of one or more globally unique group IDs (GGID).
+     * 
+ */ + public java.lang.String getGroups(int index) { + return groups_.get(index); + } + /** + * repeated string groups = 2; + * + *
+     * List of one or more globally unique group IDs (GGID).
+     * 
+ */ + public com.google.protobuf.ByteString + getGroupsBytes(int index) { + return groups_.getByteString(index); + } + + private void initFields() { + username_ = ""; + groups_ = com.google.protobuf.LazyStringArrayList.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getUsernameBytes()); + } + for (int i = 0; i < groups_.size(); i++) { + output.writeBytes(2, groups_.getByteString(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getUsernameBytes()); + } + { + int dataSize = 0; + for (int i = 0; i < groups_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(groups_.getByteString(i)); + } + size += dataSize; + size += 1 * getGroupsList().size(); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.UserCredentials} + * + *
+     * File system user credentials for executing an operation.
+     * Might be ignored by some operations.
+     * 
+ */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentialsOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_UserCredentials_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_UserCredentials_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + groups_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_UserCredentials_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.username_ = username_; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + groups_ = new com.google.protobuf.UnmodifiableLazyStringList( + groups_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.groups_ = groups_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.getDefaultInstance()) return this; + if (other.hasUsername()) { + bitField0_ |= 0x00000001; + username_ = other.username_; + onChanged(); + } + if (!other.groups_.isEmpty()) { + if (groups_.isEmpty()) { + groups_ = other.groups_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureGroupsIsMutable(); + groups_.addAll(other.groups_); + } + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasUsername()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string username = 1; + private java.lang.Object username_ = ""; + /** + * required string username = 1; + * + *
+       * Globally unique user ID (GUID).
+       * 
+ */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string username = 1; + * + *
+       * Globally unique user ID (GUID).
+       * 
+ */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + username_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 1; + * + *
+       * Globally unique user ID (GUID).
+       * 
+ */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 1; + * + *
+       * Globally unique user ID (GUID).
+       * 
+ */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 1; + * + *
+       * Globally unique user ID (GUID).
+       * 
+ */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000001); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 1; + * + *
+       * Globally unique user ID (GUID).
+       * 
+ */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + + // repeated string groups = 2; + private com.google.protobuf.LazyStringList groups_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureGroupsIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + groups_ = new com.google.protobuf.LazyStringArrayList(groups_); + bitField0_ |= 0x00000002; + } + } + /** + * repeated string groups = 2; + * + *
+       * List of one or more globally unique group IDs (GGID).
+       * 
+ */ + public java.util.List + getGroupsList() { + return java.util.Collections.unmodifiableList(groups_); + } + /** + * repeated string groups = 2; + * + *
+       * List of one or more globally unique group IDs (GGID).
+       * 
+ */ + public int getGroupsCount() { + return groups_.size(); + } + /** + * repeated string groups = 2; + * + *
+       * List of one or more globally unique group IDs (GGID).
+       * 
+ */ + public java.lang.String getGroups(int index) { + return groups_.get(index); + } + /** + * repeated string groups = 2; + * + *
+       * List of one or more globally unique group IDs (GGID).
+       * 
+ */ + public com.google.protobuf.ByteString + getGroupsBytes(int index) { + return groups_.getByteString(index); + } + /** + * repeated string groups = 2; + * + *
+       * List of one or more globally unique group IDs (GGID).
+       * 
+ */ + public Builder setGroups( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureGroupsIsMutable(); + groups_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string groups = 2; + * + *
+       * List of one or more globally unique group IDs (GGID).
+       * 
+ */ + public Builder addGroups( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureGroupsIsMutable(); + groups_.add(value); + onChanged(); + return this; + } + /** + * repeated string groups = 2; + * + *
+       * List of one or more globally unique group IDs (GGID).
+       * 
+ */ + public Builder addAllGroups( + java.lang.Iterable values) { + ensureGroupsIsMutable(); + super.addAll(values, groups_); + onChanged(); + return this; + } + /** + * repeated string groups = 2; + * + *
+       * List of one or more globally unique group IDs (GGID).
+       * 
+ */ + public Builder clearGroups() { + groups_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + return this; + } + /** + * repeated string groups = 2; + * + *
+       * List of one or more globally unique group IDs (GGID).
+       * 
+ */ + public Builder addGroupsBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureGroupsIsMutable(); + groups_.add(value); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.UserCredentials) + } + + static { + defaultInstance = new UserCredentials(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.UserCredentials) + } + + public interface AuthPasswordOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string password = 1; + /** + * required string password = 1; + */ + boolean hasPassword(); + /** + * required string password = 1; + */ + java.lang.String getPassword(); + /** + * required string password = 1; + */ + com.google.protobuf.ByteString + getPasswordBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.AuthPassword} + * + *
+   * Admin password if AuthType AUTH_PASSWORD.
+   * 
+ */ + public static final class AuthPassword extends + com.google.protobuf.GeneratedMessage + implements AuthPasswordOrBuilder { + // Use AuthPassword.newBuilder() to construct. + private AuthPassword(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private AuthPassword(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final AuthPassword defaultInstance; + public static AuthPassword getDefaultInstance() { + return defaultInstance; + } + + public AuthPassword getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AuthPassword( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + password_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_AuthPassword_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_AuthPassword_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public AuthPassword parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AuthPassword(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string password = 1; + public static final int PASSWORD_FIELD_NUMBER = 1; + private java.lang.Object password_; + /** + * required string password = 1; + */ + public boolean hasPassword() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string password = 1; + */ + public java.lang.String getPassword() { + java.lang.Object ref = password_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + password_ = s; + } + return s; + } + } + /** + * required string password = 1; + */ + public com.google.protobuf.ByteString + getPasswordBytes() { + java.lang.Object ref = password_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + password_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + password_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasPassword()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getPasswordBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getPasswordBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.AuthPassword} + * + *
+     * Admin password if AuthType AUTH_PASSWORD.
+     * 
+ */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPasswordOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_AuthPassword_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_AuthPassword_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + password_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_AuthPassword_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.password_ = password_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.getDefaultInstance()) return this; + if (other.hasPassword()) { + bitField0_ |= 0x00000001; + password_ = other.password_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasPassword()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string password = 1; + private java.lang.Object password_ = ""; + /** + * required string password = 1; + */ + public boolean hasPassword() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string password = 1; + */ + public java.lang.String getPassword() { + java.lang.Object ref = password_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + password_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string password = 1; + */ + public com.google.protobuf.ByteString + getPasswordBytes() { + java.lang.Object ref = password_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + password_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string password = 1; + */ + public Builder setPassword( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + password_ = value; + onChanged(); + return this; + } + /** + * required string password = 1; + */ + public Builder clearPassword() { + bitField0_ = (bitField0_ & ~0x00000001); + password_ = getDefaultInstance().getPassword(); + onChanged(); + return this; + } + /** + * required string password = 1; + */ + public Builder setPasswordBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + password_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.AuthPassword) + } + + static { + defaultInstance = new AuthPassword(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.AuthPassword) + } + + public interface AuthOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.AuthType auth_type = 1; + /** + * required .xtreemfs.pbrpc.AuthType auth_type = 1; + * + *
+     * Selected authentication type.
+     * 
+ */ + boolean hasAuthType(); + /** + * required .xtreemfs.pbrpc.AuthType auth_type = 1; + * + *
+     * Selected authentication type.
+     * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType getAuthType(); + + // optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+     * Optional data, depends on auth_type selected.
+     * 
+ */ + boolean hasAuthPasswd(); + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+     * Optional data, depends on auth_type selected.
+     * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword getAuthPasswd(); + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+     * Optional data, depends on auth_type selected.
+     * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPasswordOrBuilder getAuthPasswdOrBuilder(); + + // optional bytes auth_data = 2; + /** + * optional bytes auth_data = 2; + */ + boolean hasAuthData(); + /** + * optional bytes auth_data = 2; + */ + com.google.protobuf.ByteString getAuthData(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Auth} + * + *
+   * RPC Authentication information.
+   * 
+ */ + public static final class Auth extends + com.google.protobuf.GeneratedMessage + implements AuthOrBuilder { + // Use Auth.newBuilder() to construct. + private Auth(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Auth(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Auth defaultInstance; + public static Auth getDefaultInstance() { + return defaultInstance; + } + + public Auth getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Auth( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + int rawValue = input.readEnum(); + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType value = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(1, rawValue); + } else { + bitField0_ |= 0x00000001; + authType_ = value; + } + break; + } + case 18: { + bitField0_ |= 0x00000004; + authData_ = input.readBytes(); + break; + } + case 26: { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = authPasswd_.toBuilder(); + } + authPasswd_ = input.readMessage(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(authPasswd_); + authPasswd_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_Auth_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_Auth_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Auth parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Auth(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.AuthType auth_type = 1; + public static final int AUTH_TYPE_FIELD_NUMBER = 1; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType authType_; + /** + * required .xtreemfs.pbrpc.AuthType auth_type = 1; + * + *
+     * Selected authentication type.
+     * 
+ */ + public boolean hasAuthType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.AuthType auth_type = 1; + * + *
+     * Selected authentication type.
+     * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType getAuthType() { + return authType_; + } + + // optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + public static final int AUTH_PASSWD_FIELD_NUMBER = 3; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword authPasswd_; + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+     * Optional data, depends on auth_type selected.
+     * 
+ */ + public boolean hasAuthPasswd() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+     * Optional data, depends on auth_type selected.
+     * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword getAuthPasswd() { + return authPasswd_; + } + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+     * Optional data, depends on auth_type selected.
+     * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPasswordOrBuilder getAuthPasswdOrBuilder() { + return authPasswd_; + } + + // optional bytes auth_data = 2; + public static final int AUTH_DATA_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString authData_; + /** + * optional bytes auth_data = 2; + */ + public boolean hasAuthData() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional bytes auth_data = 2; + */ + public com.google.protobuf.ByteString getAuthData() { + return authData_; + } + + private void initFields() { + authType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType.AUTH_NONE; + authPasswd_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.getDefaultInstance(); + authData_ = com.google.protobuf.ByteString.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasAuthType()) { + memoizedIsInitialized = 0; + return false; + } + if (hasAuthPasswd()) { + if (!getAuthPasswd().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeEnum(1, authType_.getNumber()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(2, authData_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(3, authPasswd_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(1, authType_.getNumber()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, authData_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, authPasswd_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Auth} + * + *
+     * RPC Authentication information.
+     * 
+ */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_Auth_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_Auth_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getAuthPasswdFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + authType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType.AUTH_NONE; + bitField0_ = (bitField0_ & ~0x00000001); + if (authPasswdBuilder_ == null) { + authPasswd_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.getDefaultInstance(); + } else { + authPasswdBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + authData_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_Auth_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.authType_ = authType_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + if (authPasswdBuilder_ == null) { + result.authPasswd_ = authPasswd_; + } else { + result.authPasswd_ = authPasswdBuilder_.build(); + } + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.authData_ = authData_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.getDefaultInstance()) return this; + if (other.hasAuthType()) { + setAuthType(other.getAuthType()); + } + if (other.hasAuthPasswd()) { + mergeAuthPasswd(other.getAuthPasswd()); + } + if (other.hasAuthData()) { + setAuthData(other.getAuthData()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasAuthType()) { + + return false; + } + if (hasAuthPasswd()) { + if (!getAuthPasswd().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.AuthType auth_type = 1; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType authType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType.AUTH_NONE; + /** + * required .xtreemfs.pbrpc.AuthType auth_type = 1; + * + *
+       * Selected authentication type.
+       * 
+ */ + public boolean hasAuthType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.AuthType auth_type = 1; + * + *
+       * Selected authentication type.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType getAuthType() { + return authType_; + } + /** + * required .xtreemfs.pbrpc.AuthType auth_type = 1; + * + *
+       * Selected authentication type.
+       * 
+ */ + public Builder setAuthType(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + authType_ = value; + onChanged(); + return this; + } + /** + * required .xtreemfs.pbrpc.AuthType auth_type = 1; + * + *
+       * Selected authentication type.
+       * 
+ */ + public Builder clearAuthType() { + bitField0_ = (bitField0_ & ~0x00000001); + authType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType.AUTH_NONE; + onChanged(); + return this; + } + + // optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword authPasswd_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPasswordOrBuilder> authPasswdBuilder_; + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+       * Optional data, depends on auth_type selected.
+       * 
+ */ + public boolean hasAuthPasswd() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+       * Optional data, depends on auth_type selected.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword getAuthPasswd() { + if (authPasswdBuilder_ == null) { + return authPasswd_; + } else { + return authPasswdBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+       * Optional data, depends on auth_type selected.
+       * 
+ */ + public Builder setAuthPasswd(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword value) { + if (authPasswdBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + authPasswd_ = value; + onChanged(); + } else { + authPasswdBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+       * Optional data, depends on auth_type selected.
+       * 
+ */ + public Builder setAuthPasswd( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.Builder builderForValue) { + if (authPasswdBuilder_ == null) { + authPasswd_ = builderForValue.build(); + onChanged(); + } else { + authPasswdBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+       * Optional data, depends on auth_type selected.
+       * 
+ */ + public Builder mergeAuthPasswd(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword value) { + if (authPasswdBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + authPasswd_ != org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.getDefaultInstance()) { + authPasswd_ = + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.newBuilder(authPasswd_).mergeFrom(value).buildPartial(); + } else { + authPasswd_ = value; + } + onChanged(); + } else { + authPasswdBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+       * Optional data, depends on auth_type selected.
+       * 
+ */ + public Builder clearAuthPasswd() { + if (authPasswdBuilder_ == null) { + authPasswd_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.getDefaultInstance(); + onChanged(); + } else { + authPasswdBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+       * Optional data, depends on auth_type selected.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.Builder getAuthPasswdBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getAuthPasswdFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+       * Optional data, depends on auth_type selected.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPasswordOrBuilder getAuthPasswdOrBuilder() { + if (authPasswdBuilder_ != null) { + return authPasswdBuilder_.getMessageOrBuilder(); + } else { + return authPasswd_; + } + } + /** + * optional .xtreemfs.pbrpc.AuthPassword auth_passwd = 3; + * + *
+       * Optional data, depends on auth_type selected.
+       * 
+ */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPasswordOrBuilder> + getAuthPasswdFieldBuilder() { + if (authPasswdBuilder_ == null) { + authPasswdBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPasswordOrBuilder>( + authPasswd_, + getParentForChildren(), + isClean()); + authPasswd_ = null; + } + return authPasswdBuilder_; + } + + // optional bytes auth_data = 2; + private com.google.protobuf.ByteString authData_ = com.google.protobuf.ByteString.EMPTY; + /** + * optional bytes auth_data = 2; + */ + public boolean hasAuthData() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional bytes auth_data = 2; + */ + public com.google.protobuf.ByteString getAuthData() { + return authData_; + } + /** + * optional bytes auth_data = 2; + */ + public Builder setAuthData(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + authData_ = value; + onChanged(); + return this; + } + /** + * optional bytes auth_data = 2; + */ + public Builder clearAuthData() { + bitField0_ = (bitField0_ & ~0x00000004); + authData_ = getDefaultInstance().getAuthData(); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.Auth) + } + + static { + defaultInstance = new Auth(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Auth) + } + + public interface RPCHeaderOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed32 call_id = 1; + /** + * required fixed32 call_id = 1; + * + *
+     * A unique id to identify the request. The response sent back by the server will have
+     * the same call_id.
+     * The call_id must be unqiue per TCP connection. In addition, clients should start
+     * with a value based e.g. on time to avoid problems after a client restart.
+     * 
+ */ + boolean hasCallId(); + /** + * required fixed32 call_id = 1; + * + *
+     * A unique id to identify the request. The response sent back by the server will have
+     * the same call_id.
+     * The call_id must be unqiue per TCP connection. In addition, clients should start
+     * with a value based e.g. on time to avoid problems after a client restart.
+     * 
+ */ + int getCallId(); + + // required .xtreemfs.pbrpc.MessageType message_type = 2; + /** + * required .xtreemfs.pbrpc.MessageType message_type = 2; + * + *
+     * Type of this RPC message (Request, Response).
+     * 
+ */ + boolean hasMessageType(); + /** + * required .xtreemfs.pbrpc.MessageType message_type = 2; + * + *
+     * Type of this RPC message (Request, Response).
+     * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType getMessageType(); + + // optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+     * Optional request_header, required if message_type is RPC_REQUEST.
+     * 
+ */ + boolean hasRequestHeader(); + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+     * Optional request_header, required if message_type is RPC_REQUEST.
+     * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader getRequestHeader(); + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+     * Optional request_header, required if message_type is RPC_REQUEST.
+     * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeaderOrBuilder getRequestHeaderOrBuilder(); + + // optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+     * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+     * 
+ */ + boolean hasErrorResponse(); + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+     * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+     * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse getErrorResponse(); + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+     * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+     * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponseOrBuilder getErrorResponseOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.RPCHeader} + * + *
+   * RPC header message sent in the first request fragment.
+   * 
+ */ + public static final class RPCHeader extends + com.google.protobuf.GeneratedMessage + implements RPCHeaderOrBuilder { + // Use RPCHeader.newBuilder() to construct. + private RPCHeader(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private RPCHeader(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final RPCHeader defaultInstance; + public static RPCHeader getDefaultInstance() { + return defaultInstance; + } + + public RPCHeader getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private RPCHeader( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 13: { + bitField0_ |= 0x00000001; + callId_ = input.readFixed32(); + break; + } + case 16: { + int rawValue = input.readEnum(); + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType value = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(2, rawValue); + } else { + bitField0_ |= 0x00000002; + messageType_ = value; + } + break; + } + case 26: { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.Builder subBuilder = null; + if (((bitField0_ & 0x00000004) == 0x00000004)) { + subBuilder = requestHeader_.toBuilder(); + } + requestHeader_ = input.readMessage(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(requestHeader_); + requestHeader_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000004; + break; + } + case 34: { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.Builder subBuilder = null; + if (((bitField0_ & 0x00000008) == 0x00000008)) { + subBuilder = errorResponse_.toBuilder(); + } + errorResponse_ = input.readMessage(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(errorResponse_); + errorResponse_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000008; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public RPCHeader parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new RPCHeader(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public interface RequestHeaderOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed32 interface_id = 1; + /** + * required fixed32 interface_id = 1; + * + *
+       * Interface id of the requested method.
+       * 
+ */ + boolean hasInterfaceId(); + /** + * required fixed32 interface_id = 1; + * + *
+       * Interface id of the requested method.
+       * 
+ */ + int getInterfaceId(); + + // required fixed32 proc_id = 2; + /** + * required fixed32 proc_id = 2; + * + *
+       * Procedure id of the requested method.
+       * 
+ */ + boolean hasProcId(); + /** + * required fixed32 proc_id = 2; + * + *
+       * Procedure id of the requested method.
+       * 
+ */ + int getProcId(); + + // required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+       * File system user credentials for the operation.
+       * 
+ */ + boolean hasUserCreds(); + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+       * File system user credentials for the operation.
+       * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials getUserCreds(); + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+       * File system user credentials for the operation.
+       * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentialsOrBuilder getUserCredsOrBuilder(); + + // required .xtreemfs.pbrpc.Auth auth_data = 4; + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+       * Authentication details.
+       * 
+ */ + boolean hasAuthData(); + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+       * Authentication details.
+       * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth getAuthData(); + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+       * Authentication details.
+       * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthOrBuilder getAuthDataOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.RPCHeader.RequestHeader} + * + *
+     * Header data for requests, i.e. message_type is RPC_REQUEST.
+     * 
+ */ + public static final class RequestHeader extends + com.google.protobuf.GeneratedMessage + implements RequestHeaderOrBuilder { + // Use RequestHeader.newBuilder() to construct. + private RequestHeader(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private RequestHeader(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final RequestHeader defaultInstance; + public static RequestHeader getDefaultInstance() { + return defaultInstance; + } + + public RequestHeader getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private RequestHeader( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 13: { + bitField0_ |= 0x00000001; + interfaceId_ = input.readFixed32(); + break; + } + case 21: { + bitField0_ |= 0x00000002; + procId_ = input.readFixed32(); + break; + } + case 26: { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000004) == 0x00000004)) { + subBuilder = userCreds_.toBuilder(); + } + userCreds_ = input.readMessage(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(userCreds_); + userCreds_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000004; + break; + } + case 34: { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.Builder subBuilder = null; + if (((bitField0_ & 0x00000008) == 0x00000008)) { + subBuilder = authData_.toBuilder(); + } + authData_ = input.readMessage(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(authData_); + authData_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000008; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_RequestHeader_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_RequestHeader_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public RequestHeader parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new RequestHeader(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed32 interface_id = 1; + public static final int INTERFACE_ID_FIELD_NUMBER = 1; + private int interfaceId_; + /** + * required fixed32 interface_id = 1; + * + *
+       * Interface id of the requested method.
+       * 
+ */ + public boolean hasInterfaceId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 interface_id = 1; + * + *
+       * Interface id of the requested method.
+       * 
+ */ + public int getInterfaceId() { + return interfaceId_; + } + + // required fixed32 proc_id = 2; + public static final int PROC_ID_FIELD_NUMBER = 2; + private int procId_; + /** + * required fixed32 proc_id = 2; + * + *
+       * Procedure id of the requested method.
+       * 
+ */ + public boolean hasProcId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 proc_id = 2; + * + *
+       * Procedure id of the requested method.
+       * 
+ */ + public int getProcId() { + return procId_; + } + + // required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + public static final int USER_CREDS_FIELD_NUMBER = 3; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials userCreds_; + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+       * File system user credentials for the operation.
+       * 
+ */ + public boolean hasUserCreds() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+       * File system user credentials for the operation.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials getUserCreds() { + return userCreds_; + } + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+       * File system user credentials for the operation.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentialsOrBuilder getUserCredsOrBuilder() { + return userCreds_; + } + + // required .xtreemfs.pbrpc.Auth auth_data = 4; + public static final int AUTH_DATA_FIELD_NUMBER = 4; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth authData_; + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+       * Authentication details.
+       * 
+ */ + public boolean hasAuthData() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+       * Authentication details.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth getAuthData() { + return authData_; + } + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+       * Authentication details.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthOrBuilder getAuthDataOrBuilder() { + return authData_; + } + + private void initFields() { + interfaceId_ = 0; + procId_ = 0; + userCreds_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.getDefaultInstance(); + authData_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasInterfaceId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasProcId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasUserCreds()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasAuthData()) { + memoizedIsInitialized = 0; + return false; + } + if (!getUserCreds().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getAuthData().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed32(1, interfaceId_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed32(2, procId_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeMessage(3, userCreds_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeMessage(4, authData_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(1, interfaceId_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(2, procId_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, userCreds_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, authData_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.RPCHeader.RequestHeader} + * + *
+       * Header data for requests, i.e. message_type is RPC_REQUEST.
+       * 
+ */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeaderOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_RequestHeader_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_RequestHeader_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getUserCredsFieldBuilder(); + getAuthDataFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + interfaceId_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + procId_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + if (userCredsBuilder_ == null) { + userCreds_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.getDefaultInstance(); + } else { + userCredsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + if (authDataBuilder_ == null) { + authData_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.getDefaultInstance(); + } else { + authDataBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_RequestHeader_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.interfaceId_ = interfaceId_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.procId_ = procId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + if (userCredsBuilder_ == null) { + result.userCreds_ = userCreds_; + } else { + result.userCreds_ = userCredsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + if (authDataBuilder_ == null) { + result.authData_ = authData_; + } else { + result.authData_ = authDataBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.getDefaultInstance()) return this; + if (other.hasInterfaceId()) { + setInterfaceId(other.getInterfaceId()); + } + if (other.hasProcId()) { + setProcId(other.getProcId()); + } + if (other.hasUserCreds()) { + mergeUserCreds(other.getUserCreds()); + } + if (other.hasAuthData()) { + mergeAuthData(other.getAuthData()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasInterfaceId()) { + + return false; + } + if (!hasProcId()) { + + return false; + } + if (!hasUserCreds()) { + + return false; + } + if (!hasAuthData()) { + + return false; + } + if (!getUserCreds().isInitialized()) { + + return false; + } + if (!getAuthData().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed32 interface_id = 1; + private int interfaceId_ ; + /** + * required fixed32 interface_id = 1; + * + *
+         * Interface id of the requested method.
+         * 
+ */ + public boolean hasInterfaceId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 interface_id = 1; + * + *
+         * Interface id of the requested method.
+         * 
+ */ + public int getInterfaceId() { + return interfaceId_; + } + /** + * required fixed32 interface_id = 1; + * + *
+         * Interface id of the requested method.
+         * 
+ */ + public Builder setInterfaceId(int value) { + bitField0_ |= 0x00000001; + interfaceId_ = value; + onChanged(); + return this; + } + /** + * required fixed32 interface_id = 1; + * + *
+         * Interface id of the requested method.
+         * 
+ */ + public Builder clearInterfaceId() { + bitField0_ = (bitField0_ & ~0x00000001); + interfaceId_ = 0; + onChanged(); + return this; + } + + // required fixed32 proc_id = 2; + private int procId_ ; + /** + * required fixed32 proc_id = 2; + * + *
+         * Procedure id of the requested method.
+         * 
+ */ + public boolean hasProcId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 proc_id = 2; + * + *
+         * Procedure id of the requested method.
+         * 
+ */ + public int getProcId() { + return procId_; + } + /** + * required fixed32 proc_id = 2; + * + *
+         * Procedure id of the requested method.
+         * 
+ */ + public Builder setProcId(int value) { + bitField0_ |= 0x00000002; + procId_ = value; + onChanged(); + return this; + } + /** + * required fixed32 proc_id = 2; + * + *
+         * Procedure id of the requested method.
+         * 
+ */ + public Builder clearProcId() { + bitField0_ = (bitField0_ & ~0x00000002); + procId_ = 0; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials userCreds_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentialsOrBuilder> userCredsBuilder_; + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+         * File system user credentials for the operation.
+         * 
+ */ + public boolean hasUserCreds() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+         * File system user credentials for the operation.
+         * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials getUserCreds() { + if (userCredsBuilder_ == null) { + return userCreds_; + } else { + return userCredsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+         * File system user credentials for the operation.
+         * 
+ */ + public Builder setUserCreds(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials value) { + if (userCredsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + userCreds_ = value; + onChanged(); + } else { + userCredsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+         * File system user credentials for the operation.
+         * 
+ */ + public Builder setUserCreds( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.Builder builderForValue) { + if (userCredsBuilder_ == null) { + userCreds_ = builderForValue.build(); + onChanged(); + } else { + userCredsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+         * File system user credentials for the operation.
+         * 
+ */ + public Builder mergeUserCreds(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials value) { + if (userCredsBuilder_ == null) { + if (((bitField0_ & 0x00000004) == 0x00000004) && + userCreds_ != org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.getDefaultInstance()) { + userCreds_ = + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.newBuilder(userCreds_).mergeFrom(value).buildPartial(); + } else { + userCreds_ = value; + } + onChanged(); + } else { + userCredsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+         * File system user credentials for the operation.
+         * 
+ */ + public Builder clearUserCreds() { + if (userCredsBuilder_ == null) { + userCreds_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.getDefaultInstance(); + onChanged(); + } else { + userCredsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+         * File system user credentials for the operation.
+         * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.Builder getUserCredsBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getUserCredsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+         * File system user credentials for the operation.
+         * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentialsOrBuilder getUserCredsOrBuilder() { + if (userCredsBuilder_ != null) { + return userCredsBuilder_.getMessageOrBuilder(); + } else { + return userCreds_; + } + } + /** + * required .xtreemfs.pbrpc.UserCredentials user_creds = 3; + * + *
+         * File system user credentials for the operation.
+         * 
+ */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentialsOrBuilder> + getUserCredsFieldBuilder() { + if (userCredsBuilder_ == null) { + userCredsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentialsOrBuilder>( + userCreds_, + getParentForChildren(), + isClean()); + userCreds_ = null; + } + return userCredsBuilder_; + } + + // required .xtreemfs.pbrpc.Auth auth_data = 4; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth authData_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthOrBuilder> authDataBuilder_; + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+         * Authentication details.
+         * 
+ */ + public boolean hasAuthData() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+         * Authentication details.
+         * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth getAuthData() { + if (authDataBuilder_ == null) { + return authData_; + } else { + return authDataBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+         * Authentication details.
+         * 
+ */ + public Builder setAuthData(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth value) { + if (authDataBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + authData_ = value; + onChanged(); + } else { + authDataBuilder_.setMessage(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+         * Authentication details.
+         * 
+ */ + public Builder setAuthData( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.Builder builderForValue) { + if (authDataBuilder_ == null) { + authData_ = builderForValue.build(); + onChanged(); + } else { + authDataBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+         * Authentication details.
+         * 
+ */ + public Builder mergeAuthData(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth value) { + if (authDataBuilder_ == null) { + if (((bitField0_ & 0x00000008) == 0x00000008) && + authData_ != org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.getDefaultInstance()) { + authData_ = + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.newBuilder(authData_).mergeFrom(value).buildPartial(); + } else { + authData_ = value; + } + onChanged(); + } else { + authDataBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+         * Authentication details.
+         * 
+ */ + public Builder clearAuthData() { + if (authDataBuilder_ == null) { + authData_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.getDefaultInstance(); + onChanged(); + } else { + authDataBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+         * Authentication details.
+         * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.Builder getAuthDataBuilder() { + bitField0_ |= 0x00000008; + onChanged(); + return getAuthDataFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+         * Authentication details.
+         * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthOrBuilder getAuthDataOrBuilder() { + if (authDataBuilder_ != null) { + return authDataBuilder_.getMessageOrBuilder(); + } else { + return authData_; + } + } + /** + * required .xtreemfs.pbrpc.Auth auth_data = 4; + * + *
+         * Authentication details.
+         * 
+ */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthOrBuilder> + getAuthDataFieldBuilder() { + if (authDataBuilder_ == null) { + authDataBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthOrBuilder>( + authData_, + getParentForChildren(), + isClean()); + authData_ = null; + } + return authDataBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.RPCHeader.RequestHeader) + } + + static { + defaultInstance = new RequestHeader(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.RPCHeader.RequestHeader) + } + + public interface ErrorResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.ErrorType error_type = 1; + /** + * required .xtreemfs.pbrpc.ErrorType error_type = 1; + * + *
+       * Error type details.
+       * 
+ */ + boolean hasErrorType(); + /** + * required .xtreemfs.pbrpc.ErrorType error_type = 1; + * + *
+       * Error type details.
+       * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType getErrorType(); + + // optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + /** + * optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + * + *
+       * Optional POSIX errno.
+       * 
+ */ + boolean hasPosixErrno(); + /** + * optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + * + *
+       * Optional POSIX errno.
+       * 
+ */ + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno getPosixErrno(); + + // optional string error_message = 3; + /** + * optional string error_message = 3; + * + *
+       * Optional human readable error message in English (not localized!).
+       * 
+ */ + boolean hasErrorMessage(); + /** + * optional string error_message = 3; + * + *
+       * Optional human readable error message in English (not localized!).
+       * 
+ */ + java.lang.String getErrorMessage(); + /** + * optional string error_message = 3; + * + *
+       * Optional human readable error message in English (not localized!).
+       * 
+ */ + com.google.protobuf.ByteString + getErrorMessageBytes(); + + // optional string debug_info = 4; + /** + * optional string debug_info = 4; + * + *
+       * Optional debug information that only makes sense to developers such
+       * as stack traces.
+       * 
+ */ + boolean hasDebugInfo(); + /** + * optional string debug_info = 4; + * + *
+       * Optional debug information that only makes sense to developers such
+       * as stack traces.
+       * 
+ */ + java.lang.String getDebugInfo(); + /** + * optional string debug_info = 4; + * + *
+       * Optional debug information that only makes sense to developers such
+       * as stack traces.
+       * 
+ */ + com.google.protobuf.ByteString + getDebugInfoBytes(); + + // optional string redirect_to_server_uuid = 5; + /** + * optional string redirect_to_server_uuid = 5; + * + *
+       * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+       * 
+ */ + boolean hasRedirectToServerUuid(); + /** + * optional string redirect_to_server_uuid = 5; + * + *
+       * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+       * 
+ */ + java.lang.String getRedirectToServerUuid(); + /** + * optional string redirect_to_server_uuid = 5; + * + *
+       * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+       * 
+ */ + com.google.protobuf.ByteString + getRedirectToServerUuidBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.RPCHeader.ErrorResponse} + * + *
+     * Header data for error responses, i.e. message_type is RPC_ERROR_RESPONSE.
+     * 
+ */ + public static final class ErrorResponse extends + com.google.protobuf.GeneratedMessage + implements ErrorResponseOrBuilder { + // Use ErrorResponse.newBuilder() to construct. + private ErrorResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ErrorResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final ErrorResponse defaultInstance; + public static ErrorResponse getDefaultInstance() { + return defaultInstance; + } + + public ErrorResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ErrorResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + int rawValue = input.readEnum(); + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType value = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(1, rawValue); + } else { + bitField0_ |= 0x00000001; + errorType_ = value; + } + break; + } + case 16: { + int rawValue = input.readEnum(); + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno value = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(2, rawValue); + } else { + bitField0_ |= 0x00000002; + posixErrno_ = value; + } + break; + } + case 26: { + bitField0_ |= 0x00000004; + errorMessage_ = input.readBytes(); + break; + } + case 34: { + bitField0_ |= 0x00000008; + debugInfo_ = input.readBytes(); + break; + } + case 42: { + bitField0_ |= 0x00000010; + redirectToServerUuid_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_ErrorResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_ErrorResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public ErrorResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ErrorResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.ErrorType error_type = 1; + public static final int ERROR_TYPE_FIELD_NUMBER = 1; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType errorType_; + /** + * required .xtreemfs.pbrpc.ErrorType error_type = 1; + * + *
+       * Error type details.
+       * 
+ */ + public boolean hasErrorType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.ErrorType error_type = 1; + * + *
+       * Error type details.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType getErrorType() { + return errorType_; + } + + // optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + public static final int POSIX_ERRNO_FIELD_NUMBER = 2; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno posixErrno_; + /** + * optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + * + *
+       * Optional POSIX errno.
+       * 
+ */ + public boolean hasPosixErrno() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + * + *
+       * Optional POSIX errno.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno getPosixErrno() { + return posixErrno_; + } + + // optional string error_message = 3; + public static final int ERROR_MESSAGE_FIELD_NUMBER = 3; + private java.lang.Object errorMessage_; + /** + * optional string error_message = 3; + * + *
+       * Optional human readable error message in English (not localized!).
+       * 
+ */ + public boolean hasErrorMessage() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string error_message = 3; + * + *
+       * Optional human readable error message in English (not localized!).
+       * 
+ */ + public java.lang.String getErrorMessage() { + java.lang.Object ref = errorMessage_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + errorMessage_ = s; + } + return s; + } + } + /** + * optional string error_message = 3; + * + *
+       * Optional human readable error message in English (not localized!).
+       * 
+ */ + public com.google.protobuf.ByteString + getErrorMessageBytes() { + java.lang.Object ref = errorMessage_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + errorMessage_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string debug_info = 4; + public static final int DEBUG_INFO_FIELD_NUMBER = 4; + private java.lang.Object debugInfo_; + /** + * optional string debug_info = 4; + * + *
+       * Optional debug information that only makes sense to developers such
+       * as stack traces.
+       * 
+ */ + public boolean hasDebugInfo() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional string debug_info = 4; + * + *
+       * Optional debug information that only makes sense to developers such
+       * as stack traces.
+       * 
+ */ + public java.lang.String getDebugInfo() { + java.lang.Object ref = debugInfo_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + debugInfo_ = s; + } + return s; + } + } + /** + * optional string debug_info = 4; + * + *
+       * Optional debug information that only makes sense to developers such
+       * as stack traces.
+       * 
+ */ + public com.google.protobuf.ByteString + getDebugInfoBytes() { + java.lang.Object ref = debugInfo_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + debugInfo_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string redirect_to_server_uuid = 5; + public static final int REDIRECT_TO_SERVER_UUID_FIELD_NUMBER = 5; + private java.lang.Object redirectToServerUuid_; + /** + * optional string redirect_to_server_uuid = 5; + * + *
+       * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+       * 
+ */ + public boolean hasRedirectToServerUuid() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * optional string redirect_to_server_uuid = 5; + * + *
+       * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+       * 
+ */ + public java.lang.String getRedirectToServerUuid() { + java.lang.Object ref = redirectToServerUuid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + redirectToServerUuid_ = s; + } + return s; + } + } + /** + * optional string redirect_to_server_uuid = 5; + * + *
+       * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+       * 
+ */ + public com.google.protobuf.ByteString + getRedirectToServerUuidBytes() { + java.lang.Object ref = redirectToServerUuid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + redirectToServerUuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + errorType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType.INVALID_INTERFACE_ID; + posixErrno_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno.POSIX_ERROR_NONE; + errorMessage_ = ""; + debugInfo_ = ""; + redirectToServerUuid_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasErrorType()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeEnum(1, errorType_.getNumber()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeEnum(2, posixErrno_.getNumber()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getErrorMessageBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBytes(4, getDebugInfoBytes()); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeBytes(5, getRedirectToServerUuidBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(1, errorType_.getNumber()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(2, posixErrno_.getNumber()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getErrorMessageBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, getDebugInfoBytes()); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(5, getRedirectToServerUuidBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.RPCHeader.ErrorResponse} + * + *
+       * Header data for error responses, i.e. message_type is RPC_ERROR_RESPONSE.
+       * 
+ */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_ErrorResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_ErrorResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + errorType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType.INVALID_INTERFACE_ID; + bitField0_ = (bitField0_ & ~0x00000001); + posixErrno_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno.POSIX_ERROR_NONE; + bitField0_ = (bitField0_ & ~0x00000002); + errorMessage_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + debugInfo_ = ""; + bitField0_ = (bitField0_ & ~0x00000008); + redirectToServerUuid_ = ""; + bitField0_ = (bitField0_ & ~0x00000010); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_ErrorResponse_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.errorType_ = errorType_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.posixErrno_ = posixErrno_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.errorMessage_ = errorMessage_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.debugInfo_ = debugInfo_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.redirectToServerUuid_ = redirectToServerUuid_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.getDefaultInstance()) return this; + if (other.hasErrorType()) { + setErrorType(other.getErrorType()); + } + if (other.hasPosixErrno()) { + setPosixErrno(other.getPosixErrno()); + } + if (other.hasErrorMessage()) { + bitField0_ |= 0x00000004; + errorMessage_ = other.errorMessage_; + onChanged(); + } + if (other.hasDebugInfo()) { + bitField0_ |= 0x00000008; + debugInfo_ = other.debugInfo_; + onChanged(); + } + if (other.hasRedirectToServerUuid()) { + bitField0_ |= 0x00000010; + redirectToServerUuid_ = other.redirectToServerUuid_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasErrorType()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.ErrorType error_type = 1; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType errorType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType.INVALID_INTERFACE_ID; + /** + * required .xtreemfs.pbrpc.ErrorType error_type = 1; + * + *
+         * Error type details.
+         * 
+ */ + public boolean hasErrorType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.ErrorType error_type = 1; + * + *
+         * Error type details.
+         * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType getErrorType() { + return errorType_; + } + /** + * required .xtreemfs.pbrpc.ErrorType error_type = 1; + * + *
+         * Error type details.
+         * 
+ */ + public Builder setErrorType(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + errorType_ = value; + onChanged(); + return this; + } + /** + * required .xtreemfs.pbrpc.ErrorType error_type = 1; + * + *
+         * Error type details.
+         * 
+ */ + public Builder clearErrorType() { + bitField0_ = (bitField0_ & ~0x00000001); + errorType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType.INVALID_INTERFACE_ID; + onChanged(); + return this; + } + + // optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno posixErrno_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno.POSIX_ERROR_NONE; + /** + * optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + * + *
+         * Optional POSIX errno.
+         * 
+ */ + public boolean hasPosixErrno() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + * + *
+         * Optional POSIX errno.
+         * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno getPosixErrno() { + return posixErrno_; + } + /** + * optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + * + *
+         * Optional POSIX errno.
+         * 
+ */ + public Builder setPosixErrno(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + posixErrno_ = value; + onChanged(); + return this; + } + /** + * optional .xtreemfs.pbrpc.POSIXErrno posix_errno = 2 [default = POSIX_ERROR_NONE]; + * + *
+         * Optional POSIX errno.
+         * 
+ */ + public Builder clearPosixErrno() { + bitField0_ = (bitField0_ & ~0x00000002); + posixErrno_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno.POSIX_ERROR_NONE; + onChanged(); + return this; + } + + // optional string error_message = 3; + private java.lang.Object errorMessage_ = ""; + /** + * optional string error_message = 3; + * + *
+         * Optional human readable error message in English (not localized!).
+         * 
+ */ + public boolean hasErrorMessage() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string error_message = 3; + * + *
+         * Optional human readable error message in English (not localized!).
+         * 
+ */ + public java.lang.String getErrorMessage() { + java.lang.Object ref = errorMessage_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + errorMessage_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string error_message = 3; + * + *
+         * Optional human readable error message in English (not localized!).
+         * 
+ */ + public com.google.protobuf.ByteString + getErrorMessageBytes() { + java.lang.Object ref = errorMessage_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + errorMessage_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string error_message = 3; + * + *
+         * Optional human readable error message in English (not localized!).
+         * 
+ */ + public Builder setErrorMessage( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + errorMessage_ = value; + onChanged(); + return this; + } + /** + * optional string error_message = 3; + * + *
+         * Optional human readable error message in English (not localized!).
+         * 
+ */ + public Builder clearErrorMessage() { + bitField0_ = (bitField0_ & ~0x00000004); + errorMessage_ = getDefaultInstance().getErrorMessage(); + onChanged(); + return this; + } + /** + * optional string error_message = 3; + * + *
+         * Optional human readable error message in English (not localized!).
+         * 
+ */ + public Builder setErrorMessageBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + errorMessage_ = value; + onChanged(); + return this; + } + + // optional string debug_info = 4; + private java.lang.Object debugInfo_ = ""; + /** + * optional string debug_info = 4; + * + *
+         * Optional debug information that only makes sense to developers such
+         * as stack traces.
+         * 
+ */ + public boolean hasDebugInfo() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional string debug_info = 4; + * + *
+         * Optional debug information that only makes sense to developers such
+         * as stack traces.
+         * 
+ */ + public java.lang.String getDebugInfo() { + java.lang.Object ref = debugInfo_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + debugInfo_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string debug_info = 4; + * + *
+         * Optional debug information that only makes sense to developers such
+         * as stack traces.
+         * 
+ */ + public com.google.protobuf.ByteString + getDebugInfoBytes() { + java.lang.Object ref = debugInfo_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + debugInfo_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string debug_info = 4; + * + *
+         * Optional debug information that only makes sense to developers such
+         * as stack traces.
+         * 
+ */ + public Builder setDebugInfo( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + debugInfo_ = value; + onChanged(); + return this; + } + /** + * optional string debug_info = 4; + * + *
+         * Optional debug information that only makes sense to developers such
+         * as stack traces.
+         * 
+ */ + public Builder clearDebugInfo() { + bitField0_ = (bitField0_ & ~0x00000008); + debugInfo_ = getDefaultInstance().getDebugInfo(); + onChanged(); + return this; + } + /** + * optional string debug_info = 4; + * + *
+         * Optional debug information that only makes sense to developers such
+         * as stack traces.
+         * 
+ */ + public Builder setDebugInfoBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + debugInfo_ = value; + onChanged(); + return this; + } + + // optional string redirect_to_server_uuid = 5; + private java.lang.Object redirectToServerUuid_ = ""; + /** + * optional string redirect_to_server_uuid = 5; + * + *
+         * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+         * 
+ */ + public boolean hasRedirectToServerUuid() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * optional string redirect_to_server_uuid = 5; + * + *
+         * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+         * 
+ */ + public java.lang.String getRedirectToServerUuid() { + java.lang.Object ref = redirectToServerUuid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + redirectToServerUuid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string redirect_to_server_uuid = 5; + * + *
+         * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+         * 
+ */ + public com.google.protobuf.ByteString + getRedirectToServerUuidBytes() { + java.lang.Object ref = redirectToServerUuid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + redirectToServerUuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string redirect_to_server_uuid = 5; + * + *
+         * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+         * 
+ */ + public Builder setRedirectToServerUuid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + redirectToServerUuid_ = value; + onChanged(); + return this; + } + /** + * optional string redirect_to_server_uuid = 5; + * + *
+         * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+         * 
+ */ + public Builder clearRedirectToServerUuid() { + bitField0_ = (bitField0_ & ~0x00000010); + redirectToServerUuid_ = getDefaultInstance().getRedirectToServerUuid(); + onChanged(); + return this; + } + /** + * optional string redirect_to_server_uuid = 5; + * + *
+         * Optional UUID of the server to use instead. Required when error_type is REDIRECT.
+         * 
+ */ + public Builder setRedirectToServerUuidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + redirectToServerUuid_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.RPCHeader.ErrorResponse) + } + + static { + defaultInstance = new ErrorResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.RPCHeader.ErrorResponse) + } + + private int bitField0_; + // required fixed32 call_id = 1; + public static final int CALL_ID_FIELD_NUMBER = 1; + private int callId_; + /** + * required fixed32 call_id = 1; + * + *
+     * A unique id to identify the request. The response sent back by the server will have
+     * the same call_id.
+     * The call_id must be unqiue per TCP connection. In addition, clients should start
+     * with a value based e.g. on time to avoid problems after a client restart.
+     * 
+ */ + public boolean hasCallId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 call_id = 1; + * + *
+     * A unique id to identify the request. The response sent back by the server will have
+     * the same call_id.
+     * The call_id must be unqiue per TCP connection. In addition, clients should start
+     * with a value based e.g. on time to avoid problems after a client restart.
+     * 
+ */ + public int getCallId() { + return callId_; + } + + // required .xtreemfs.pbrpc.MessageType message_type = 2; + public static final int MESSAGE_TYPE_FIELD_NUMBER = 2; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType messageType_; + /** + * required .xtreemfs.pbrpc.MessageType message_type = 2; + * + *
+     * Type of this RPC message (Request, Response).
+     * 
+ */ + public boolean hasMessageType() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required .xtreemfs.pbrpc.MessageType message_type = 2; + * + *
+     * Type of this RPC message (Request, Response).
+     * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType getMessageType() { + return messageType_; + } + + // optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + public static final int REQUEST_HEADER_FIELD_NUMBER = 3; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader requestHeader_; + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+     * Optional request_header, required if message_type is RPC_REQUEST.
+     * 
+ */ + public boolean hasRequestHeader() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+     * Optional request_header, required if message_type is RPC_REQUEST.
+     * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader getRequestHeader() { + return requestHeader_; + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+     * Optional request_header, required if message_type is RPC_REQUEST.
+     * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeaderOrBuilder getRequestHeaderOrBuilder() { + return requestHeader_; + } + + // optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + public static final int ERROR_RESPONSE_FIELD_NUMBER = 4; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse errorResponse_; + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+     * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+     * 
+ */ + public boolean hasErrorResponse() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+     * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+     * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse getErrorResponse() { + return errorResponse_; + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+     * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+     * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponseOrBuilder getErrorResponseOrBuilder() { + return errorResponse_; + } + + private void initFields() { + callId_ = 0; + messageType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType.RPC_REQUEST; + requestHeader_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.getDefaultInstance(); + errorResponse_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasCallId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMessageType()) { + memoizedIsInitialized = 0; + return false; + } + if (hasRequestHeader()) { + if (!getRequestHeader().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasErrorResponse()) { + if (!getErrorResponse().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed32(1, callId_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeEnum(2, messageType_.getNumber()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeMessage(3, requestHeader_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeMessage(4, errorResponse_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(1, callId_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(2, messageType_.getNumber()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, requestHeader_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, errorResponse_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.RPCHeader} + * + *
+     * RPC header message sent in the first request fragment.
+     * 
+ */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeaderOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.class, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.Builder.class); + } + + // Construct using org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getRequestHeaderFieldBuilder(); + getErrorResponseFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + callId_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + messageType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType.RPC_REQUEST; + bitField0_ = (bitField0_ & ~0x00000002); + if (requestHeaderBuilder_ == null) { + requestHeader_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.getDefaultInstance(); + } else { + requestHeaderBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + if (errorResponseBuilder_ == null) { + errorResponse_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.getDefaultInstance(); + } else { + errorResponseBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.internal_static_xtreemfs_pbrpc_RPCHeader_descriptor; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader getDefaultInstanceForType() { + return org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.getDefaultInstance(); + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader build() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader buildPartial() { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader result = new org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.callId_ = callId_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.messageType_ = messageType_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + if (requestHeaderBuilder_ == null) { + result.requestHeader_ = requestHeader_; + } else { + result.requestHeader_ = requestHeaderBuilder_.build(); + } + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + if (errorResponseBuilder_ == null) { + result.errorResponse_ = errorResponse_; + } else { + result.errorResponse_ = errorResponseBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader) { + return mergeFrom((org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader other) { + if (other == org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.getDefaultInstance()) return this; + if (other.hasCallId()) { + setCallId(other.getCallId()); + } + if (other.hasMessageType()) { + setMessageType(other.getMessageType()); + } + if (other.hasRequestHeader()) { + mergeRequestHeader(other.getRequestHeader()); + } + if (other.hasErrorResponse()) { + mergeErrorResponse(other.getErrorResponse()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasCallId()) { + + return false; + } + if (!hasMessageType()) { + + return false; + } + if (hasRequestHeader()) { + if (!getRequestHeader().isInitialized()) { + + return false; + } + } + if (hasErrorResponse()) { + if (!getErrorResponse().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed32 call_id = 1; + private int callId_ ; + /** + * required fixed32 call_id = 1; + * + *
+       * A unique id to identify the request. The response sent back by the server will have
+       * the same call_id.
+       * The call_id must be unqiue per TCP connection. In addition, clients should start
+       * with a value based e.g. on time to avoid problems after a client restart.
+       * 
+ */ + public boolean hasCallId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 call_id = 1; + * + *
+       * A unique id to identify the request. The response sent back by the server will have
+       * the same call_id.
+       * The call_id must be unqiue per TCP connection. In addition, clients should start
+       * with a value based e.g. on time to avoid problems after a client restart.
+       * 
+ */ + public int getCallId() { + return callId_; + } + /** + * required fixed32 call_id = 1; + * + *
+       * A unique id to identify the request. The response sent back by the server will have
+       * the same call_id.
+       * The call_id must be unqiue per TCP connection. In addition, clients should start
+       * with a value based e.g. on time to avoid problems after a client restart.
+       * 
+ */ + public Builder setCallId(int value) { + bitField0_ |= 0x00000001; + callId_ = value; + onChanged(); + return this; + } + /** + * required fixed32 call_id = 1; + * + *
+       * A unique id to identify the request. The response sent back by the server will have
+       * the same call_id.
+       * The call_id must be unqiue per TCP connection. In addition, clients should start
+       * with a value based e.g. on time to avoid problems after a client restart.
+       * 
+ */ + public Builder clearCallId() { + bitField0_ = (bitField0_ & ~0x00000001); + callId_ = 0; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.MessageType message_type = 2; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType messageType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType.RPC_REQUEST; + /** + * required .xtreemfs.pbrpc.MessageType message_type = 2; + * + *
+       * Type of this RPC message (Request, Response).
+       * 
+ */ + public boolean hasMessageType() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required .xtreemfs.pbrpc.MessageType message_type = 2; + * + *
+       * Type of this RPC message (Request, Response).
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType getMessageType() { + return messageType_; + } + /** + * required .xtreemfs.pbrpc.MessageType message_type = 2; + * + *
+       * Type of this RPC message (Request, Response).
+       * 
+ */ + public Builder setMessageType(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + messageType_ = value; + onChanged(); + return this; + } + /** + * required .xtreemfs.pbrpc.MessageType message_type = 2; + * + *
+       * Type of this RPC message (Request, Response).
+       * 
+ */ + public Builder clearMessageType() { + bitField0_ = (bitField0_ & ~0x00000002); + messageType_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType.RPC_REQUEST; + onChanged(); + return this; + } + + // optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader requestHeader_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeaderOrBuilder> requestHeaderBuilder_; + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+       * Optional request_header, required if message_type is RPC_REQUEST.
+       * 
+ */ + public boolean hasRequestHeader() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+       * Optional request_header, required if message_type is RPC_REQUEST.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader getRequestHeader() { + if (requestHeaderBuilder_ == null) { + return requestHeader_; + } else { + return requestHeaderBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+       * Optional request_header, required if message_type is RPC_REQUEST.
+       * 
+ */ + public Builder setRequestHeader(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader value) { + if (requestHeaderBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + requestHeader_ = value; + onChanged(); + } else { + requestHeaderBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+       * Optional request_header, required if message_type is RPC_REQUEST.
+       * 
+ */ + public Builder setRequestHeader( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.Builder builderForValue) { + if (requestHeaderBuilder_ == null) { + requestHeader_ = builderForValue.build(); + onChanged(); + } else { + requestHeaderBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+       * Optional request_header, required if message_type is RPC_REQUEST.
+       * 
+ */ + public Builder mergeRequestHeader(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader value) { + if (requestHeaderBuilder_ == null) { + if (((bitField0_ & 0x00000004) == 0x00000004) && + requestHeader_ != org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.getDefaultInstance()) { + requestHeader_ = + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.newBuilder(requestHeader_).mergeFrom(value).buildPartial(); + } else { + requestHeader_ = value; + } + onChanged(); + } else { + requestHeaderBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+       * Optional request_header, required if message_type is RPC_REQUEST.
+       * 
+ */ + public Builder clearRequestHeader() { + if (requestHeaderBuilder_ == null) { + requestHeader_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.getDefaultInstance(); + onChanged(); + } else { + requestHeaderBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+       * Optional request_header, required if message_type is RPC_REQUEST.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.Builder getRequestHeaderBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getRequestHeaderFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+       * Optional request_header, required if message_type is RPC_REQUEST.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeaderOrBuilder getRequestHeaderOrBuilder() { + if (requestHeaderBuilder_ != null) { + return requestHeaderBuilder_.getMessageOrBuilder(); + } else { + return requestHeader_; + } + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.RequestHeader request_header = 3; + * + *
+       * Optional request_header, required if message_type is RPC_REQUEST.
+       * 
+ */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeaderOrBuilder> + getRequestHeaderFieldBuilder() { + if (requestHeaderBuilder_ == null) { + requestHeaderBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeader.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.RequestHeaderOrBuilder>( + requestHeader_, + getParentForChildren(), + isClean()); + requestHeader_ = null; + } + return requestHeaderBuilder_; + } + + // optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + private org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse errorResponse_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponseOrBuilder> errorResponseBuilder_; + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+       * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+       * 
+ */ + public boolean hasErrorResponse() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+       * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse getErrorResponse() { + if (errorResponseBuilder_ == null) { + return errorResponse_; + } else { + return errorResponseBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+       * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+       * 
+ */ + public Builder setErrorResponse(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse value) { + if (errorResponseBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + errorResponse_ = value; + onChanged(); + } else { + errorResponseBuilder_.setMessage(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+       * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+       * 
+ */ + public Builder setErrorResponse( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.Builder builderForValue) { + if (errorResponseBuilder_ == null) { + errorResponse_ = builderForValue.build(); + onChanged(); + } else { + errorResponseBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+       * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+       * 
+ */ + public Builder mergeErrorResponse(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse value) { + if (errorResponseBuilder_ == null) { + if (((bitField0_ & 0x00000008) == 0x00000008) && + errorResponse_ != org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.getDefaultInstance()) { + errorResponse_ = + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.newBuilder(errorResponse_).mergeFrom(value).buildPartial(); + } else { + errorResponse_ = value; + } + onChanged(); + } else { + errorResponseBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+       * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+       * 
+ */ + public Builder clearErrorResponse() { + if (errorResponseBuilder_ == null) { + errorResponse_ = org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.getDefaultInstance(); + onChanged(); + } else { + errorResponseBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+       * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.Builder getErrorResponseBuilder() { + bitField0_ |= 0x00000008; + onChanged(); + return getErrorResponseFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+       * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+       * 
+ */ + public org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponseOrBuilder getErrorResponseOrBuilder() { + if (errorResponseBuilder_ != null) { + return errorResponseBuilder_.getMessageOrBuilder(); + } else { + return errorResponse_; + } + } + /** + * optional .xtreemfs.pbrpc.RPCHeader.ErrorResponse error_response = 4; + * + *
+       * Optional error_response, required if message_type is RPC_ERROR_RESPONSE.
+       * 
+ */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponseOrBuilder> + getErrorResponseFieldBuilder() { + if (errorResponseBuilder_ == null) { + errorResponseBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse.Builder, org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponseOrBuilder>( + errorResponse_, + getParentForChildren(), + isClean()); + errorResponse_ = null; + } + return errorResponseBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.RPCHeader) + } + + static { + defaultInstance = new RPCHeader(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.RPCHeader) + } + + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_UserCredentials_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_UserCredentials_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_AuthPassword_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_AuthPassword_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_Auth_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_Auth_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_RPCHeader_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_RPCHeader_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_RPCHeader_RequestHeader_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_RPCHeader_RequestHeader_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_RPCHeader_ErrorResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_RPCHeader_ErrorResponse_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\017pbrpc/RPC.proto\022\016xtreemfs.pbrpc\"3\n\017Use" + + "rCredentials\022\020\n\010username\030\001 \002(\t\022\016\n\006groups" + + "\030\002 \003(\t\" \n\014AuthPassword\022\020\n\010password\030\001 \002(\t" + + "\"y\n\004Auth\022+\n\tauth_type\030\001 \002(\0162\030.xtreemfs.p" + + "brpc.AuthType\0221\n\013auth_passwd\030\003 \001(\0132\034.xtr" + + "eemfs.pbrpc.AuthPassword\022\021\n\tauth_data\030\002 " + + "\001(\014\"\270\004\n\tRPCHeader\022\017\n\007call_id\030\001 \002(\007\0221\n\014me" + + "ssage_type\030\002 \002(\0162\033.xtreemfs.pbrpc.Messag" + + "eType\022?\n\016request_header\030\003 \001(\0132\'.xtreemfs" + + ".pbrpc.RPCHeader.RequestHeader\022?\n\016error_", + "response\030\004 \001(\0132\'.xtreemfs.pbrpc.RPCHeade" + + "r.ErrorResponse\032\224\001\n\rRequestHeader\022\024\n\014int" + + "erface_id\030\001 \002(\007\022\017\n\007proc_id\030\002 \002(\007\0223\n\nuser" + + "_creds\030\003 \002(\0132\037.xtreemfs.pbrpc.UserCreden" + + "tials\022\'\n\tauth_data\030\004 \002(\0132\024.xtreemfs.pbrp" + + "c.Auth\032\315\001\n\rErrorResponse\022-\n\nerror_type\030\001" + + " \002(\0162\031.xtreemfs.pbrpc.ErrorType\022A\n\013posix" + + "_errno\030\002 \001(\0162\032.xtreemfs.pbrpc.POSIXErrno" + + ":\020POSIX_ERROR_NONE\022\025\n\rerror_message\030\003 \001(" + + "\t\022\022\n\ndebug_info\030\004 \001(\t\022\037\n\027redirect_to_ser", + "ver_uuid\030\005 \001(\t*P\n\013MessageType\022\017\n\013RPC_REQ" + + "UEST\020\000\022\030\n\024RPC_RESPONSE_SUCCESS\020\001\022\026\n\022RPC_" + + "RESPONSE_ERROR\020\002*,\n\010AuthType\022\r\n\tAUTH_NON" + + "E\020\000\022\021\n\rAUTH_PASSWORD\020\001*\261\001\n\tErrorType\022\030\n\024" + + "INVALID_INTERFACE_ID\020\001\022\023\n\017INVALID_PROC_I" + + "D\020\002\022\020\n\014GARBAGE_ARGS\020\003\022\017\n\013AUTH_FAILED\020\004\022\031" + + "\n\025INTERNAL_SERVER_ERROR\020\005\022\t\n\005ERRNO\020\006\022\014\n\010" + + "REDIRECT\020\007\022\020\n\014INVALID_VIEW\020\010\022\014\n\010IO_ERROR" + + "\020d*\212\003\n\nPOSIXErrno\022\025\n\020POSIX_ERROR_NONE\020\217N" + + "\022\025\n\021POSIX_ERROR_EPERM\020\001\022\026\n\022POSIX_ERROR_E", + "NOENT\020\002\022\025\n\021POSIX_ERROR_EINTR\020\004\022\023\n\017POSIX_" + + "ERROR_EIO\020\005\022\026\n\022POSIX_ERROR_EAGAIN\020\013\022\026\n\022P" + + "OSIX_ERROR_EACCES\020\r\022\026\n\022POSIX_ERROR_EEXIS" + + "T\020\021\022\025\n\021POSIX_ERROR_EXDEV\020\022\022\026\n\022POSIX_ERRO" + + "R_ENODEV\020\023\022\027\n\023POSIX_ERROR_ENOTDIR\020\024\022\026\n\022P" + + "OSIX_ERROR_EISDIR\020\025\022\026\n\022POSIX_ERROR_EINVA" + + "L\020\026\022\026\n\022POSIX_ERROR_ENOSPC\020\034\022\031\n\025POSIX_ERR" + + "OR_ENOTEMPTY\020\'\022\027\n\023POSIX_ERROR_ENODATA\020=B" + + "3\n1org.xtreemfs.foundation.pbrpc.generat" + + "edinterfaces" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_xtreemfs_pbrpc_UserCredentials_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_xtreemfs_pbrpc_UserCredentials_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_UserCredentials_descriptor, + new java.lang.String[] { "Username", "Groups", }); + internal_static_xtreemfs_pbrpc_AuthPassword_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_xtreemfs_pbrpc_AuthPassword_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_AuthPassword_descriptor, + new java.lang.String[] { "Password", }); + internal_static_xtreemfs_pbrpc_Auth_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_xtreemfs_pbrpc_Auth_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_Auth_descriptor, + new java.lang.String[] { "AuthType", "AuthPasswd", "AuthData", }); + internal_static_xtreemfs_pbrpc_RPCHeader_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_xtreemfs_pbrpc_RPCHeader_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_RPCHeader_descriptor, + new java.lang.String[] { "CallId", "MessageType", "RequestHeader", "ErrorResponse", }); + internal_static_xtreemfs_pbrpc_RPCHeader_RequestHeader_descriptor = + internal_static_xtreemfs_pbrpc_RPCHeader_descriptor.getNestedTypes().get(0); + internal_static_xtreemfs_pbrpc_RPCHeader_RequestHeader_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_RPCHeader_RequestHeader_descriptor, + new java.lang.String[] { "InterfaceId", "ProcId", "UserCreds", "AuthData", }); + internal_static_xtreemfs_pbrpc_RPCHeader_ErrorResponse_descriptor = + internal_static_xtreemfs_pbrpc_RPCHeader_descriptor.getNestedTypes().get(1); + internal_static_xtreemfs_pbrpc_RPCHeader_ErrorResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_RPCHeader_ErrorResponse_descriptor, + new java.lang.String[] { "ErrorType", "PosixErrno", "ErrorMessage", "DebugInfo", "RedirectToServerUuid", }); + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCNIOSocketServer.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCNIOSocketServer.java new file mode 100644 index 0000000..27fe375 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCNIOSocketServer.java @@ -0,0 +1,787 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.server; + +import java.io.IOException; +import java.net.BindException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketException; +import java.nio.ByteBuffer; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.ClosedByInterruptException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.channels.ChannelIO; +import org.xtreemfs.foundation.pbrpc.channels.SSLChannelIO; +import org.xtreemfs.foundation.pbrpc.channels.SSLHandshakeOnlyChannelIO; +import org.xtreemfs.foundation.util.OutputUtils; + +/** + * + * @author bjko + */ +public class RPCNIOSocketServer extends LifeCycleThread implements RPCServerInterface { + + /** + * Maximum number of record fragments supported. + */ + public static final int MAX_FRAGMENTS = 1; + + /** + * Maximum fragment size to accept. If the size is larger, the connection is + * closed. + */ + public static final int MAX_FRAGMENT_SIZE = 1024 * 1024 * 32; + + /** + * the server socket + */ + private final ServerSocketChannel socket; + + /** + * Selector for server socket + */ + private final Selector selector; + + /** + * If set to true thei main loop will exit upon next invocation + */ + private volatile boolean quit; + + /** + * The receiver that gets all incoming requests. + */ + private volatile RPCServerRequestListener receiver; + + /** + * sslOptions if SSL is enabled, null otherwise + */ + private final SSLOptions sslOptions; + + /** + * Connection count + */ + private final AtomicInteger numConnections; + + /** + * Number of requests received but not answered + */ + private long pendingRequests; + + /** + * Port on which the server listens for incoming connections. + */ + private final int bindPort; + + private final List connections; + + /** + * maximum number of pending client requests to allow + */ + private final int maxClientQLength; + + /** + * if the Q was full we need at least CLIENT_Q_THR spaces before we start + * reading from the client again. This is to prevent it from oscillating + */ + private final int clientQThreshold; + + public static final int DEFAULT_MAX_CLIENT_Q_LENGTH = 100; + + public RPCNIOSocketServer(int bindPort, InetAddress bindAddr, RPCServerRequestListener rl, + SSLOptions sslOptions) throws IOException { + this(bindPort, bindAddr, rl, sslOptions, -1); + } + + public RPCNIOSocketServer(int bindPort, InetAddress bindAddr, RPCServerRequestListener rl, + SSLOptions sslOptions, int receiveBufferSize) throws IOException { + this(bindPort, bindAddr, rl, sslOptions, receiveBufferSize, DEFAULT_MAX_CLIENT_Q_LENGTH); + } + + public RPCNIOSocketServer(int bindPort, InetAddress bindAddr, RPCServerRequestListener rl, + SSLOptions sslOptions, int receiveBufferSize, + int maxClientQLength) throws IOException { + super("PBRPCSrv@" + bindPort); + + // open server socket + socket = ServerSocketChannel.open(); + socket.configureBlocking(false); + + if (receiveBufferSize != -1) { + socket.socket().setReceiveBufferSize(receiveBufferSize); + try { + if (socket.socket().getReceiveBufferSize() != receiveBufferSize) { + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "could not set socket receive buffer size to " + receiveBufferSize + + ", using default size of " + socket.socket().getReceiveBufferSize()); + } + } catch (SocketException exc) { + Logging.logMessage(Logging.LEVEL_WARN, this, + "could not check whether receive buffer size was successfully set to %d bytes", receiveBufferSize); + } + } else { + socket.socket().setReceiveBufferSize(256 * 1024); + } + + socket.socket().setReuseAddress(true); + try { + socket.socket().bind( + bindAddr == null ? new InetSocketAddress(bindPort) : new InetSocketAddress(bindAddr, bindPort)); + } catch (BindException e) { + // Rethrow exception with the failed port number. + throw new BindException(e.getMessage() + ". Port number: " + bindPort); + } + this.bindPort = bindPort; + + // create a selector and register socket + selector = Selector.open(); + socket.register(selector, SelectionKey.OP_ACCEPT); + + // server is ready to accept connections now + + this.receiver = rl; + + this.sslOptions = sslOptions; + + this.numConnections = new AtomicInteger(0); + + this.connections = new LinkedList(); + + this.maxClientQLength = maxClientQLength; + this.clientQThreshold = (maxClientQLength/2 >= 0) ? maxClientQLength/2 : 0; + if (maxClientQLength <= 1) { + Logging.logMessage(Logging.LEVEL_WARN, this, "max client queue length is 1, pipelining is disabled."); + } + } + + /** + * Stop the server and close all connections. + */ + @Override + public void shutdown() { + this.quit = true; + this.interrupt(); + } + + /** + * sends a response. + * + * @param request + * the request + */ + @Override + public void sendResponse(RPCServerRequest request, RPCServerResponse response) { + assert (response != null); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "response sent"); + final RPCNIOSocketServerConnection connection = (RPCNIOSocketServerConnection)request.getConnection(); + try { + request.freeBuffers(); + } catch (AssertionError ex) { + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, "Caught an AssertionError while trying to free buffers:"); + Logging.logError(Logging.LEVEL_INFO, this, ex); + } + } + assert (connection.getServer() == this); + + if (!connection.isConnectionClosed()) { + synchronized (connection) { + boolean isEmpty = connection.getPendingResponses().isEmpty(); + connection.addPendingResponse(response); + if (isEmpty) { + final SelectionKey key = connection.getChannel().keyFor(selector); + if (key != null) { + try { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + } catch (CancelledKeyException e) { + // Ignore it since the timeout mechanism will deal with it. + } + } + selector.wakeup(); + } + } + } else { + // ignore and free bufers + response.freeBuffers(); + } + } + + @Override + public void run() { + + notifyStarted(); + + if (Logging.isInfo()) { + String sslMode = ""; + if (sslOptions != null) { + if (sslOptions.isFakeSSLMode()) { + sslMode = "GRID SSL mode enabled (SSL handshake only)"; + } else { + sslMode = "SSL enabled (" + sslOptions.getSSLProtocol() + ")"; + } + } + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, "PBRPC Srv %d ready %s", bindPort,sslMode); + } + + try { + while (!quit) { + // try to select events... + int numKeys = 0; + try { + numKeys = selector.select(); + } catch (CancelledKeyException ex) { + // who cares + } catch (IOException ex) { + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "Exception while selecting: %s", ex.toString()); + continue; + } + + if (numKeys > 0) { + // fetch events + Set keys = selector.selectedKeys(); + Iterator iter = keys.iterator(); + + // process all events + while (iter.hasNext()) { + SelectionKey key = iter.next(); + + // remove key from the list + iter.remove(); + try { + + if (key.isAcceptable()) { + acceptConnection(key); + } + if (key.isReadable()) { + readConnection(key); + } + if (key.isWritable()) { + writeConnection(key); + } + } catch (CancelledKeyException ex) { + // nobody cares... + continue; + } + } + } + } + + for (RPCNIOSocketServerConnection con : connections) { + try { + con.getChannel().close(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + // close socket + selector.close(); + socket.close(); + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "PBRPC Server %d shutdown complete", bindPort); + + notifyStopped(); + } catch (Throwable thr) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this, "PBRPC Server %d CRASHED!", bindPort); + notifyCrashed(thr); + } + + } + + /** + * read data from a readable connection + * + * @param key + * a readable key + */ + private void readConnection(SelectionKey key) { + + final RPCNIOSocketServerConnection con = (RPCNIOSocketServerConnection) key.attachment(); + final ChannelIO channel = con.getChannel(); + + try { + + if (!channel.isShutdownInProgress()) { + if (channel.doHandshake(key)) { + while (true) { + if (con.getOpenRequests().get() > maxClientQLength) { + key.interestOps(key.interestOps() & ~SelectionKey.OP_READ); + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "client sent too many requests... not accepting new requests from %s, q=%d", con + .getChannel().socket().getRemoteSocketAddress().toString(), con.getOpenRequests().get()); + return; + } + + ByteBuffer buf = null; + switch (con.getReceiveState()) { + case RECORD_MARKER: { + buf = con.getReceiveRecordMarker(); break; + } + case RPC_MESSAGE: { + buf = con.getReceiveBuffers()[1].getBuffer(); break; + } + case RPC_HEADER: { + buf = con.getReceiveBuffers()[0].getBuffer(); break; + } + case DATA: { + buf = con.getReceiveBuffers()[2].getBuffer(); break; + } + } + + // read fragment header + final int numBytesRead = readData(key, channel, buf); + if (numBytesRead == -1) { + // connection closed + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "client closed connection (EOF): %s", channel.socket() + .getRemoteSocketAddress().toString()); + } + closeConnection(key); + return; + } + if (buf.hasRemaining()) { + // not enough data... + break; + } + + switch (con.getReceiveState()) { + case RECORD_MARKER: { + buf.position(0); + final int hdrLen = buf.getInt(); + final int msgLen = buf.getInt(); + final int dataLen = buf.getInt(); + + if ((hdrLen <= 0) || (hdrLen >= MAX_FRAGMENT_SIZE) + || (msgLen < 0) || (msgLen >= MAX_FRAGMENT_SIZE) + || (dataLen < 0) || (dataLen >= MAX_FRAGMENT_SIZE)) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this, + "invalid record marker size (%d/%d/%d) received, closing connection to client %s", + hdrLen,msgLen,dataLen,channel.socket() + .getRemoteSocketAddress().toString()); + closeConnection(key); + return; + } + final ReusableBuffer[] buffers = new ReusableBuffer[]{BufferPool.allocate(hdrLen), + ((msgLen > 0) ? BufferPool.allocate(msgLen) : null), + ((dataLen > 0) ? BufferPool.allocate(dataLen) : null) }; + con.setReceiveBuffers(buffers); + con.setReceiveState(RPCNIOSocketServerConnection.ReceiveState.RPC_HEADER); + continue; + } + + case RPC_HEADER: { + if (con.getReceiveBuffers()[1] != null) { + con.setReceiveState(RPCNIOSocketServerConnection.ReceiveState.RPC_MESSAGE); + continue; + } else { + if (con.getReceiveBuffers()[2] != null) { + con.setReceiveState(RPCNIOSocketServerConnection.ReceiveState.DATA); + continue; + } else { + break; + } + } + } + case RPC_MESSAGE: { + if (con.getReceiveBuffers()[2] != null) { + con.setReceiveState(RPCNIOSocketServerConnection.ReceiveState.DATA); + continue; + } else { + break; + } + + } + } + + //assemble ServerRequest + con.setReceiveState(RPCNIOSocketServerConnection.ReceiveState.RECORD_MARKER); + con.getReceiveRecordMarker().clear(); + + ReusableBuffer[] receiveBuffers = con.getReceiveBuffers(); + receiveBuffers[0].flip(); + if (receiveBuffers[1] != null) + receiveBuffers[1].flip(); + if (receiveBuffers[2] != null) + receiveBuffers[2].flip(); + con.setReceiveBuffers(null); + + RPCServerRequest rq = null; + try { + rq = new RPCServerRequest(con, receiveBuffers[0], receiveBuffers[1], receiveBuffers[2]); + } catch (IOException ex) { + // close connection if the header cannot be parsed + Logging.logMessage(Logging.LEVEL_ERROR, Category.net,this,"invalid PBRPC header received: "+ex); + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this,ex); + } + closeConnection(key); + BufferPool.free(receiveBuffers[1]); + BufferPool.free(receiveBuffers[2]); + return; + } + // request is + // complete... send to receiver + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, rq + .toString()); + } + con.getOpenRequests().incrementAndGet(); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "request received"); + pendingRequests++; + if (!receiveRequest(key, rq, con)) { + closeConnection(key); + return; + } + } + } + } + } catch (CancelledKeyException ex) { + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "client closed connection (CancelledKeyException): %s", channel.socket().getRemoteSocketAddress() + .toString()); + } + closeConnection(key); + } catch (ClosedByInterruptException ex) { + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "client closed connection (EOF): %s", channel.socket().getRemoteSocketAddress() + .toString()); + } + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "connection to %s closed by remote peer", con.getChannel().socket() + .getRemoteSocketAddress().toString()); + } + closeConnection(key); + } catch (IOException ex) { + // simply close the connection + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, OutputUtils + .stackTraceToString(ex)); + } + closeConnection(key); + } + } + + /** + * write data to a writeable connection + * + * @param key + * the writable key + */ + private void writeConnection(SelectionKey key) { + + final RPCNIOSocketServerConnection con = (RPCNIOSocketServerConnection) key.attachment(); + final ChannelIO channel = con.getChannel(); + + try { + + if (!channel.isShutdownInProgress()) { + if (channel.doHandshake(key)) { + + while (true) { + + // final ByteBuffer fragmentHeader = + // con.getSendFragHdr(); + + ByteBuffer[] response = con.getSendBuffers(); + if (response == null) { + synchronized (con) { + RPCServerResponse rq = con.getPendingResponses().peek(); + if (rq == null) { + // no more responses, stop writing... + con.setSendBuffers(null); + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + break; + } + response = rq.packBuffers(con.getSendFragHdr()); + con.setSendBuffers(response); + con.setExpectedRecordSize(rq.getRpcMessageSize()); + } + } + + /* + * if (fragmentHeader.hasRemaining()) { final int + * numBytesWritten = writeData(key, channel, + * fragmentHeader); if (numBytesWritten == -1) { + * //connection closed closeConnection(key); return; } + * if (fragmentHeader.hasRemaining()) { //not enough + * data... break; } //finished sending... send fragment + * data now... } else { + */ + // send fragment data + assert(response != null); + final long numBytesWritten = channel.write(response); + if (numBytesWritten == -1) { + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "client closed connection (EOF): %s", channel.socket() + .getRemoteSocketAddress().toString()); + } + // connection closed + closeConnection(key); + return; + } + con.recordBytesSent(numBytesWritten); + + if (response[response.length-1].hasRemaining()) { + // not enough data... + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + break; + } + con.checkEnoughBytesSent(); + // finished sending fragment + // clean up :-) request finished + pendingRequests--; + RPCServerResponse rq = con.getPendingResponses().poll(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "sent response for %s", rq.toString()); + } + rq.freeBuffers(); + con.setSendBuffers(null); + con.getSendFragHdr().clear(); + int numRq = con.getOpenRequests().decrementAndGet(); + + if ((key.interestOps() & SelectionKey.OP_READ) == 0) { + if (numRq < clientQThreshold) { + // read from client again + key.interestOps(key.interestOps() | SelectionKey.OP_READ); + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "client allowed to send data again: %s, q=%d", con.getChannel().socket() + .getRemoteSocketAddress().toString(), numRq); + } + } + + continue; + } + } + } + } catch (CancelledKeyException ex) { + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "client closed connection (CancelledKeyException): %s", channel.socket().getRemoteSocketAddress() + .toString()); + } + closeConnection(key); + } catch (ClosedByInterruptException ex) { + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "client closed connection (EOF): %s", channel.socket().getRemoteSocketAddress() + .toString()); + } + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "connection to %s closed by remote peer", con.getChannel().socket() + .getRemoteSocketAddress().toString()); + } + closeConnection(key); + } catch (IOException ex) { + // simply close the connection + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, OutputUtils + .stackTraceToString(ex)); + } + closeConnection(key); + } + } + + /** + * Reads data from the socket, ensures that SSL connection is ready + * + * @param key + * the SelectionKey + * @param channel + * the channel to read from + * @param buf + * the buffer to read to + * @return number of bytes read, -1 on EOF + * @throws java.io.IOException + */ + public static int readData(SelectionKey key, ChannelIO channel, ByteBuffer buf) throws IOException { + return channel.read(buf); + /* + * if (!channel.isShutdownInProgress()) { if (channel.doHandshake(key)) + * { return channel.read(buf); } else { return 0; } } else { return 0; } + */ + } + + public static int writeData(SelectionKey key, ChannelIO channel, ByteBuffer buf) throws IOException { + return channel.write(buf); + /* + * if (!channel.isShutdownInProgress()) { if (channel.doHandshake(key)) + * { return channel.write(buf); } else { return 0; } } else { return 0; + * } + */ + } + + /** + * close a connection + * + * @param key + * matching key + */ + private void closeConnection(SelectionKey key) { + final RPCNIOSocketServerConnection con = (RPCNIOSocketServerConnection) key.attachment(); + final ChannelIO channel = con.getChannel(); + + // remove the connection from the selector and close socket + try { + connections.remove(con); + con.setConnectionClosed(true); + key.cancel(); + channel.close(); + } catch (Exception ex) { + } finally { + // adjust connection count and make sure buffers are freed + numConnections.decrementAndGet(); + con.freeBuffers(); + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "closing connection to %s", channel + .socket().getRemoteSocketAddress().toString()); + } + } + + /** + * accept a new incomming connection + * + * @param key + * the acceptable key + */ + private void acceptConnection(SelectionKey key) { + SocketChannel client = null; + RPCNIOSocketServerConnection con = null; + ChannelIO channelIO = null; + // FIXME: Better exception handling! + + try { + + // accept that connection + client = socket.accept(); + + if (sslOptions == null) { + channelIO = new ChannelIO(client); + } else { + if (sslOptions.isFakeSSLMode()) { + channelIO = new SSLHandshakeOnlyChannelIO(client, sslOptions, false); + } else { + channelIO = new SSLChannelIO(client, sslOptions, false); + } + } + con = new RPCNIOSocketServerConnection(this,channelIO); + + // and configure it to be non blocking + // IMPORTANT! + client.configureBlocking(false); + client.register(selector, SelectionKey.OP_READ, con); + client.socket().setTcpNoDelay(true); + + numConnections.incrementAndGet(); + + this.connections.add(con); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "connect from client at %s", + client.socket().getRemoteSocketAddress().toString()); + } + + } catch (ClosedChannelException ex) { + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "client closed connection during accept"); + } + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "cannot establish connection: %s", ex.toString()); + if (channelIO != null) { + try { + channelIO.close(); + } catch (IOException ex2) { + } + } + } catch (IOException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "cannot establish connection: %s", ex.toString()); + if (channelIO != null) { + try { + channelIO.close(); + } catch (IOException ex2) { + } + } + } + } + + /** + * + * @param key + * @param request + * @param con + * @return true on success, false on error + */ + private boolean receiveRequest(SelectionKey key, RPCServerRequest request, RPCNIOSocketServerConnection con) { + try { + request.getHeader(); + + receiver.receiveRecord(request); + return true; + } catch (IllegalArgumentException ex) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.net,this,"invalid PBRPC header received: "+ex); + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this,ex); + } + return false; + //closeConnection(key); + } + } + + public int getNumConnections() { + return this.numConnections.get(); + } + + public long getPendingRequests() { + return this.pendingRequests; + } + + /** + * Updates the listener. Handle with care. + * + * @param rl + */ + public void updateRequestDispatcher(RPCServerRequestListener rl) { + this.receiver = rl; + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCNIOSocketServerConnection.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCNIOSocketServerConnection.java new file mode 100644 index 0000000..c4976dd --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCNIOSocketServerConnection.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.server; + +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; + +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.channels.ChannelIO; +import org.xtreemfs.foundation.pbrpc.utils.RecordMarker; + +/** + * + * @author bjko + */ +public class RPCNIOSocketServerConnection implements RPCServerConnectionInterface { + + public enum ReceiveState { + RECORD_MARKER, + RPC_HEADER, + RPC_MESSAGE, + DATA + }; + + private final AtomicInteger openRequests; + + private Queue pendingResponses; + + private final ChannelIO channel; + + private final ByteBuffer receiveRecordMarker; + + private final ByteBuffer sendFragHdr; + + private ReusableBuffer[] receiveBuffers; + + private ReceiveState receiveState; + + private ByteBuffer[] sendBuffers; + + private volatile boolean connectionClosed; + + private SocketAddress clientAddress; + + private RPCServerInterface server; + + private long bytesSent; + + private int expectedRecordSize; + + public RPCNIOSocketServerConnection(RPCServerInterface server, ChannelIO channel) { + assert(server != null); + assert(channel != null); + this.channel = channel; + this.openRequests = new AtomicInteger(0); + this.pendingResponses = new ConcurrentLinkedQueue(); + this.connectionClosed = false; + this.receiveRecordMarker = ByteBuffer.allocate(RecordMarker.HDR_SIZE); + this.sendFragHdr = ByteBuffer.allocate(RecordMarker.HDR_SIZE); + this.receiveState = ReceiveState.RECORD_MARKER; + this.server = server; + try { + this.clientAddress = channel.socket().getRemoteSocketAddress(); + } catch (Exception ex) { + } + } + + /** + * @return the receiveState + */ + public ReceiveState getReceiveState() { + return receiveState; + } + + /** + * @param receiveState the receiveState to set + */ + public void setReceiveState(ReceiveState receiveState) { + this.receiveState = receiveState; + } + + @Override + public RPCServerInterface getServer() { + return server; + } + + @Override + public SocketAddress getSender() { + return clientAddress; + } + + public void freeBuffers() { + if (receiveBuffers != null) { + for (ReusableBuffer buffer : receiveBuffers) + BufferPool.free(buffer); + } + for (RPCServerResponse r : pendingResponses) { + r.freeBuffers(); + } + } + + /** + * @return the openRequests + */ + public AtomicInteger getOpenRequests() { + return openRequests; + } + + /** + * @return the channel + */ + @Override + public ChannelIO getChannel() { + return channel; + } + + + /** + * @return the connectionClosed + */ + public boolean isConnectionClosed() { + return connectionClosed; + } + + /** + * @param connectionClosed the connectionClosed to set + */ + public void setConnectionClosed(boolean connectionClosed) { + this.connectionClosed = connectionClosed; + } + + /** + * @return the pendingResponses + */ + public Queue getPendingResponses() { + return pendingResponses; + } + + public void addPendingResponse(RPCServerResponse rq) { + this.pendingResponses.add(rq); + } + + /** + * @return the fragmentHeader + */ + ByteBuffer getReceiveRecordMarker() { + return receiveRecordMarker; + } + + /** + * @return the fragmentHeader + */ + ByteBuffer getSendFragHdr() { + return sendFragHdr; + } + + /** + * @return the receive + */ + ReusableBuffer[] getReceiveBuffers() { + return receiveBuffers; + } + + /** + * @param receive the receive to set + */ + void setReceiveBuffers(ReusableBuffer[] receive) { + this.receiveBuffers = receive; + } + + /** + * @return the send + */ + ByteBuffer[] getSendBuffers() { + return sendBuffers; + } + + /** + * @param send the send to set + */ + void setSendBuffers(ByteBuffer[] send) { + this.sendBuffers = send; + } + + + /** + * @return the clientAddress + */ + public SocketAddress getClientAddress() { + return clientAddress; + } + + public void setExpectedRecordSize(int expectedRecordSize) { + this.expectedRecordSize = expectedRecordSize; + bytesSent = 0; + } + + public void recordBytesSent(long bytesSent) { + this.bytesSent += bytesSent; + if (this.bytesSent > expectedRecordSize) { + String errorMessage = "Too many bytes written (expected: " + + expectedRecordSize + + ", actual: " + + this.bytesSent + + ") in connection to " + + clientAddress; + Logging.logMessage(Logging.LEVEL_ERROR, this, errorMessage); + throw new IllegalStateException(errorMessage); + } + } + + public void checkEnoughBytesSent() { + if (bytesSent != expectedRecordSize) { + String errorMessage = "Incorrect record length sent (expected: " + + expectedRecordSize + + ", actual: " + + bytesSent + + ") in connection to " + + clientAddress; + Logging.logMessage(Logging.LEVEL_ERROR, this, errorMessage); + throw new IllegalStateException(errorMessage); + } + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerConnectionInterface.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerConnectionInterface.java new file mode 100644 index 0000000..70f8808 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerConnectionInterface.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + + +package org.xtreemfs.foundation.pbrpc.server; + +import java.net.SocketAddress; + +import org.xtreemfs.foundation.pbrpc.channels.ChannelIO; + +/** + * + * @author bjko + */ +public interface RPCServerConnectionInterface { + + public RPCServerInterface getServer(); + + public SocketAddress getSender(); + + public ChannelIO getChannel(); + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerInterface.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerInterface.java new file mode 100644 index 0000000..db32c9b --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerInterface.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.server; + +/** + * + * @author bjko + */ +public interface RPCServerInterface { + + public void sendResponse(RPCServerRequest request, RPCServerResponse response); + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerRequest.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerRequest.java new file mode 100644 index 0000000..e710a3c --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerRequest.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.server; + +import com.google.protobuf.Message; +import java.io.IOException; +import java.net.SocketAddress; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; + +/** + * + * @author bjko + */ +public class RPCServerRequest { + + private RPC.RPCHeader header; + private ReusableBuffer message; + private ReusableBuffer data; + private final RPCServerConnectionInterface connection; + + public RPCServerRequest(RPCServerConnectionInterface connection, ReusableBuffer headerBuffer, ReusableBuffer message, ReusableBuffer data) throws IOException { + try { + ReusableBufferInputStream rbis = new ReusableBufferInputStream(headerBuffer); + header = RPC.RPCHeader.parseFrom(rbis); + this.message = message; + this.data = data; + this.connection = connection; + } finally { + BufferPool.free(headerBuffer); + } + } + + public RPCServerRequest(RPCServerConnectionInterface connection, RPC.RPCHeader header, ReusableBuffer message) { + this.header = header; + this.message = message; + this.data = null; + this.connection = connection; + } + + public RPC.RPCHeader getHeader() { + return header; + } + + /** + * @return the message + */ + public ReusableBuffer getMessage() { + return message; + } + + /** + * @return the data + */ + public ReusableBuffer getData() { + return data; + } + + public void freeBuffers() { + BufferPool.free(message); + BufferPool.free(data); + } + + public void sendError(RPC.ErrorType type, RPC.POSIXErrno errno, String message, String debugInfo) { + RPC.RPCHeader.ErrorResponse resp = RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(type).setPosixErrno(errno).setErrorMessage(message).setDebugInfo(debugInfo).build(); + sendError(resp); + } + + public void sendError(RPC.ErrorType type, RPC.POSIXErrno errno, String message) { + RPC.RPCHeader.ErrorResponse resp = RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(type).setPosixErrno(errno).setErrorMessage(message).build(); + sendError(resp); + } + + public void sendRedirect(String target_uuid) { + RPC.RPCHeader.ErrorResponse resp = RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(RPC.ErrorType.REDIRECT).setPosixErrno(RPC.POSIXErrno.POSIX_ERROR_NONE).setRedirectToServerUuid(target_uuid).build(); + sendError(resp); + } + + public void sendError(RPC.RPCHeader.ErrorResponse error) { + try { + RPC.RPCHeader rqHdr = getHeader(); + RPC.RPCHeader respHdr = RPC.RPCHeader.newBuilder().setCallId(rqHdr.getCallId()).setMessageType(RPC.MessageType.RPC_RESPONSE_ERROR).setErrorResponse(error).build(); + RPCServerResponse response = new RPCServerResponse(respHdr, null, null); + getConnection().getServer().sendResponse(this, response); + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + public void sendResponse(Message message, ReusableBuffer data) throws IOException { + RPC.RPCHeader rqHdr = getHeader(); + RPC.RPCHeader respHdr = RPC.RPCHeader.newBuilder().setCallId(rqHdr.getCallId()).setMessageType(RPC.MessageType.RPC_RESPONSE_SUCCESS).build(); + RPCServerResponse response = new RPCServerResponse(respHdr, message, data); + getConnection().getServer().sendResponse(this, response); + } + + public SocketAddress getSenderAddress() { + return connection.getSender(); + } + + /** + * @return the connection + */ + public RPCServerConnectionInterface getConnection() { + return connection; + } + + public String toString() { + try { + RPC.RPCHeader hdr = getHeader(); + String headerContent = ""; + if (hdr.getMessageType() == RPC.MessageType.RPC_REQUEST) { + headerContent = ",proc="+hdr.getRequestHeader().getProcId()+",interf="+hdr.getRequestHeader().getInterfaceId(); + } + return this.getClass().getCanonicalName()+": callid="+hdr.getCallId()+", type="+hdr.getMessageType()+headerContent; + } catch (Exception ex) { + return this.getClass().getCanonicalName()+": unparseable data: "+ex; + } + } + + +} + diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerRequestListener.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerRequestListener.java new file mode 100644 index 0000000..d2545fc --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerRequestListener.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.server; + +/** + * + * @author bjko + */ +public interface RPCServerRequestListener { + + public void receiveRecord(RPCServerRequest rq); + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerResponse.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerResponse.java new file mode 100644 index 0000000..e9199e4 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCServerResponse.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.server; + +import com.google.protobuf.Message; +import java.io.IOException; +import java.nio.ByteBuffer; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferOutputStream; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; +import org.xtreemfs.foundation.pbrpc.utils.RecordMarker; + +/** + * + * @author bjko + */ +public class RPCServerResponse { + + final int callId; + + final ReusableBuffer[] buffers; + final int hdrLen; + final int msgLen; + final int dataLen; + + public RPCServerResponse(RPC.RPCHeader header, Message message, ReusableBuffer data) throws IOException { + ReusableBufferOutputStream os = new ReusableBufferOutputStream(ReusableBufferOutputStream.BUFF_SIZE); + callId = header.getCallId(); + + hdrLen = header.getSerializedSize(); + msgLen = (message != null) ? message.getSerializedSize() : 0; + dataLen = (data != null) ? data.capacity() : 0; + + assert(hdrLen > 0); + assert(msgLen >= 0); + assert(dataLen >= 0); + + RecordMarker rm = new RecordMarker(hdrLen, msgLen, dataLen); + rm.writeFragmentHeader(os); + header.writeTo(os); + if (message != null) { + message.writeTo(os); + } + if (data != null) { + data.position(data.limit()); + os.appendBuffer(data); + } + os.flip(); + buffers = os.getBuffers(); + } + + public ReusableBuffer[] getBuffers() { + return buffers; + } + + public ByteBuffer[] packBuffers(ByteBuffer recordMarker) { + ByteBuffer[] arr = new ByteBuffer[buffers.length]; + for (int i = 0; i < buffers.length; i++) + arr[i] = buffers[i].getBuffer(); + return arr; + } + + public void freeBuffers() { + for (int i = 0; i < buffers.length; i++) { + BufferPool.free(buffers[i]); + buffers[i] = null; + } + } + + public String toString() { + return this.getClass().getCanonicalName()+": callid="+callId; + } + + public int getRpcMessageSize() { + return RecordMarker.HDR_SIZE + hdrLen + dataLen + msgLen; + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCUDPSocketServer.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCUDPSocketServer.java new file mode 100644 index 0000000..617b8bd --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/RPCUDPSocketServer.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.server; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.ClosedByInterruptException; +import java.nio.channels.DatagramChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicInteger; + +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.utils.PBRPCDatagramPacket; +import org.xtreemfs.foundation.pbrpc.utils.RecordMarker; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class RPCUDPSocketServer extends LifeCycleThread implements RPCServerInterface { + + public final int port; + + private final DatagramChannel channel; + + private final Selector selector; + + private volatile boolean quit; + + private final LinkedBlockingQueue q; + + private final RPCServerRequestListener receiver; + + public static final int MAX_UDP_SIZE = 2048; + + private final AtomicInteger callIdCounter; + + public RPCUDPSocketServer(int port, RPCServerRequestListener receiver) throws IOException { + super("UDPComStage"); + this.port = port; + q = new LinkedBlockingQueue(); + this.receiver = receiver; + callIdCounter = new AtomicInteger(1); + + selector = Selector.open(); + + channel = DatagramChannel.open(); + channel.socket().setReuseAddress(true); + channel.socket().bind(new InetSocketAddress(port)); + channel.configureBlocking(false); + channel.register(selector, SelectionKey.OP_READ); + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, "UDP socket on port %d ready", port); + } + + @Override + public void sendResponse(RPCServerRequest request, RPCServerResponse response) { + UDPMessage msg = (UDPMessage)request.getConnection(); + UDPMessage responseMsg = new UDPMessage(response.getBuffers()[0], msg.getAddress(), this); + request.freeBuffers(); + send(responseMsg); + } + + public void sendRequest(RPCHeader header, Message message, InetSocketAddress receiver) throws IOException { + PBRPCDatagramPacket dpack = new PBRPCDatagramPacket(header, message); + header = header.toBuilder().setCallId(callIdCounter.getAndIncrement()).build(); + UDPMessage msg = new UDPMessage(dpack.assembleDatagramPacket(), receiver, this); + //msg.getBuffer().flip(); + send(msg); + } + + private void send(UDPMessage rq) { + q.add(rq); + + if (q.size() == 1) { + // System.out.println("wakeup!"); + selector.wakeup(); + } + } + + @Override + public void shutdown() { + quit = true; + interrupt(); + } + + @Override + public void run() { + + try { + notifyStarted(); + + boolean isRdOnly = true; + + while (!quit) { + + if (q.size() == 0) { + if (!isRdOnly) { + channel.keyFor(selector).interestOps(SelectionKey.OP_READ); + // System.out.println("read only"); + isRdOnly = true; + } + } else { + if (isRdOnly) { + channel.keyFor(selector).interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE); + // System.out.println("read write"); + isRdOnly = false; + } + } + + int numKeys = selector.select(); + + if (q.size() == 0) { + if (!isRdOnly) { + channel.keyFor(selector).interestOps(SelectionKey.OP_READ); + // System.out.println("read only"); + isRdOnly = true; + } + } else { + if (isRdOnly) { + channel.keyFor(selector).interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE); + // System.out.println("read write"); + isRdOnly = false; + } + } + + if (numKeys == 0) + continue; + + if (q.size() > 10000) { + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, "QS!!!!! %d", q.size()); + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, "is readOnly: " + isRdOnly); + } + + // fetch events + Set keys = selector.selectedKeys(); + Iterator iter = keys.iterator(); + + // process all events + while (iter.hasNext()) { + + SelectionKey key = iter.next(); + + // remove key from the list + iter.remove(); + + if (key.isReadable()) { + InetSocketAddress sender = null; + // do { + ReusableBuffer data = BufferPool.allocate(MAX_UDP_SIZE); + sender = (InetSocketAddress) channel.receive(data.getBuffer()); + if (sender == null || !data.hasRemaining()) { + BufferPool.free(data); + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "read key for empty read/empty packet"); + } else { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "read data from %s", sender.toString()); + + try { + data.flip(); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "data: %s", + data.toString()); + RecordMarker rm = new RecordMarker(data.getBuffer()); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "rm: %d/%d data: %d", + rm.getRpcHeaderLength(), rm.getMessageLength(), data.limit()); + ReusableBufferInputStream rbis = new ReusableBufferInputStream(data); + + final int origLimit = data.limit(); + assert (origLimit == RecordMarker.HDR_SIZE + rm.getRpcHeaderLength() + + rm.getMessageLength()); + data.limit(RecordMarker.HDR_SIZE + rm.getRpcHeaderLength()); + + RPCHeader header = RPCHeader.newBuilder().mergeFrom(rbis).build(); + + data.range(RecordMarker.HDR_SIZE + rm.getRpcHeaderLength(), rm.getMessageLength()); + + UDPMessage msg = new UDPMessage(null, sender, this); + RPCServerRequest rq = new RPCServerRequest(msg, header, data); + receiver.receiveRecord(rq); + } catch (Throwable ex) { + ex.printStackTrace(); + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "received invalid UPD message: "+ex); + BufferPool.free(data); + } + } + // } while (sender != null); + } else if (key.isWritable()) { + UDPMessage r = q.poll(); + while (r != null) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "sent packet to %s", r.getAddress().toString()); + int sent = channel.send(r.getBuffer().getBuffer(), r.getAddress()); + BufferPool.free(r.getBuffer()); + if (sent == 0) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "cannot send anymore"); + q.put(r); + break; + } + r = q.poll(); + } + } else { + throw new RuntimeException("strange key state: " + key); + } + } + + } + + selector.close(); + channel.close(); + + } catch (CancelledKeyException ex) { + // ignore + } catch (ClosedByInterruptException ex) { + // ignore + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } catch (Throwable th) { + notifyCrashed(th); + return; + } + + notifyStopped(); + } + + + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/UDPMessage.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/UDPMessage.java new file mode 100644 index 0000000..8a90a2d --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/server/UDPMessage.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.server; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.channels.ChannelIO; + +/** + * + * @author bjko + */ +public class UDPMessage implements RPCServerConnectionInterface { + private final ReusableBuffer buffer; + private final InetSocketAddress address; + final RPCUDPSocketServer server; + + public UDPMessage(ReusableBuffer buffer, InetSocketAddress address, RPCUDPSocketServer server) { + this.buffer = buffer; + this.address = address; + this.server = server; + } + + @Override + public RPCServerInterface getServer() { + return server; + } + + /** + * @return the buffer + */ + public ReusableBuffer getBuffer() { + return buffer; + } + + /** + * @return the address + */ + public InetSocketAddress getAddress() { + return address; + } + + @Override + public SocketAddress getSender() { + return address; + } + + @Override + public ChannelIO getChannel() { + return null; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ErrorUtils.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ErrorUtils.java new file mode 100644 index 0000000..d774365 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ErrorUtils.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.utils; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.util.OutputUtils; + +/** + * + * @author bjko + */ +public class ErrorUtils { + + public static ErrorResponse getErrorResponse(ErrorType type, POSIXErrno errno, String message, String debug) { + return ErrorResponse.newBuilder().setErrorType(type).setPosixErrno(errno).setErrorMessage(message).setDebugInfo(debug).build(); + } + + public static ErrorResponse getErrorResponse(ErrorType type, POSIXErrno errno, String message, Throwable cause) { + return ErrorResponse.newBuilder().setErrorType(type).setPosixErrno(errno).setErrorMessage(message).setDebugInfo(OutputUtils.stackTraceToString(cause)).build(); + } + + public static ErrorResponse getErrorResponse(ErrorType type, POSIXErrno errno, String message) { + return ErrorResponse.newBuilder().setErrorType(type).setPosixErrno(errno).setErrorMessage(message).build(); + } + + public static ErrorResponse getInternalServerError(Throwable cause) { + return ErrorResponse.newBuilder().setErrorType(ErrorType.INTERNAL_SERVER_ERROR).setPosixErrno(POSIXErrno.POSIX_ERROR_EIO). + setErrorMessage(cause.toString()).setDebugInfo(OutputUtils.stackTraceToString(cause)).build(); + } + + public static ErrorResponse getInternalServerError(Throwable cause, String additionalErrorMessage) { + return ErrorResponse.newBuilder().setErrorType(ErrorType.INTERNAL_SERVER_ERROR).setPosixErrno(POSIXErrno.POSIX_ERROR_EIO). + setErrorMessage(additionalErrorMessage + "; " + cause.toString()).setDebugInfo(OutputUtils.stackTraceToString(cause)).build(); + } + + public static String formatError(ErrorResponse error) { + if (error == null) + return "no error"; + return error.getErrorType()+"/"+error.getPosixErrno()+": "+error.getErrorMessage() +(error.hasDebugInfo() ? ";\n"+error.getDebugInfo() : ""); + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/PBRPCDatagramPacket.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/PBRPCDatagramPacket.java new file mode 100644 index 0000000..1ae360e --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/PBRPCDatagramPacket.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.utils; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.Message; +import java.io.IOException; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; + +/** + * + * @author bjko + */ +public class PBRPCDatagramPacket { + + private final RPCHeader header; + private final Message message; + + public PBRPCDatagramPacket(ReusableBuffer datagramToParse, Message msgPrototype) throws IOException { + RecordMarker rm = new RecordMarker(datagramToParse.getBuffer()); + ReusableBufferInputStream rbis = new ReusableBufferInputStream(datagramToParse); + + final int origLimit = datagramToParse.limit(); + assert(origLimit == rm.HDR_SIZE+rm.getRpcHeaderLength()+rm.getMessageLength()); + datagramToParse.limit(rm.HDR_SIZE+rm.getRpcHeaderLength()); + + header = RPCHeader.newBuilder().mergeFrom(rbis).build(); + + datagramToParse.limit(origLimit); + message = msgPrototype.newBuilderForType().mergeFrom(rbis).build(); + } + + public PBRPCDatagramPacket(RPCHeader header, Message message) { + this.header = header; + this.message = message; + } + + public ReusableBuffer assembleDatagramPacket() throws IOException { + + ReusableBufferOutputStream out = new ReusableBufferOutputStream(RecordMarker.HDR_SIZE+getHeader().getSerializedSize()+getMessage().getSerializedSize()); + RecordMarker rm = new RecordMarker(getHeader().getSerializedSize(), getMessage().getSerializedSize(), 0); + rm.writeFragmentHeader(out); + getHeader().writeTo(out); + getMessage().writeTo(out); + out.flip(); + ReusableBuffer[] bufs = out.getBuffers(); + assert(bufs.length == 1); + return bufs[0]; + } + + /** + * @return the header + */ + public RPCHeader getHeader() { + return header; + } + + /** + * @return the message + */ + public Message getMessage() { + return message; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/RecordMarker.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/RecordMarker.java new file mode 100644 index 0000000..ac52343 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/RecordMarker.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.utils; + +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * + * @author bjko + */ +public class RecordMarker { + + public static final int HDR_SIZE = Integer.SIZE/8*3; + + private final int rpcHeaderLength; + private final int messageLength; + private final int dataLength; + + public RecordMarker(ByteBuffer buf) throws IOException { + rpcHeaderLength = buf.getInt(); + messageLength = buf.getInt(); + dataLength = buf.getInt(); + } + + public RecordMarker(int rpcHeaderLength, int messageLength, int dataLength) { + this.rpcHeaderLength = rpcHeaderLength; + this.messageLength = messageLength; + this.dataLength = dataLength; + } + + public void writeFragmentHeader(ByteBuffer buf) { + buf.putInt(getRpcHeaderLength()); + buf.putInt(getMessageLength()); + buf.putInt(getDataLength()); + } + + public void writeFragmentHeader(ReusableBufferOutputStream out) throws IOException { + ByteBuffer buf = ByteBuffer.allocate(HDR_SIZE); + buf.putInt(getRpcHeaderLength()); + buf.putInt(getMessageLength()); + buf.putInt(getDataLength()); + out.write(buf.array()); + } + + /** + * @return the rpcHeaderLength + */ + public int getRpcHeaderLength() { + return rpcHeaderLength; + } + + /** + * @return the messageLength + */ + public int getMessageLength() { + return messageLength; + } + + /** + * @return the dataLength + */ + public int getDataLength() { + return dataLength; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ReusableBufferInputStream.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ReusableBufferInputStream.java new file mode 100644 index 0000000..7880016 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ReusableBufferInputStream.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.utils; + +import java.io.IOException; +import java.io.InputStream; +import org.xtreemfs.foundation.buffer.ReusableBuffer; + +/** + * + * @author bjko + */ +public class ReusableBufferInputStream extends InputStream { + + private final ReusableBuffer data; + + public ReusableBufferInputStream(ReusableBuffer data) { + assert(data != null); + this.data = data; + } + + @Override + public int read() throws IOException { + if (data.hasRemaining()) + return data.get(); + else + return -1; + } + + @Override + public int read(byte[] buf, int offset, int length) throws IOException { + final int bytesRemaining = data.remaining(); + if (bytesRemaining == 0) + return -1; + final int bytesToRead = (bytesRemaining >= length) ? length : bytesRemaining; + data.get(buf, offset, bytesToRead); + return bytesToRead; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ReusableBufferOutputStream.java b/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ReusableBufferOutputStream.java new file mode 100644 index 0000000..a158b56 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/pbrpc/utils/ReusableBufferOutputStream.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.pbrpc.utils; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; + +/** + * + * @author bjko + */ +public class ReusableBufferOutputStream extends OutputStream { + + public static final int BUFF_SIZE = 1024*8; + + private final int bufSize; + + private final ReusableBuffer firstBuffer; + + private List buffers; + + private ReusableBuffer currentBuffer; + + private int length; + + public ReusableBufferOutputStream(int bufSize) { + this.bufSize = bufSize; + + firstBuffer = BufferPool.allocate(bufSize); + currentBuffer = firstBuffer; + length = 0; + } + + private ReusableBuffer checkAndGetBuffer(int requiredSpace) { + if (currentBuffer.remaining() < requiredSpace) { + if (buffers == null) + buffers = new ArrayList(15); + final int newBufSize = (bufSize >= requiredSpace) ? bufSize : requiredSpace; + final ReusableBuffer buf = BufferPool.allocate(newBufSize); + buffers.add(buf); + currentBuffer = buf; + } + return currentBuffer; + } + + public void appendBuffer(ReusableBuffer buffer) { + currentBuffer = buffer; + if (buffers == null) + buffers = new ArrayList(15); + buffer.position(buffer.limit()); + buffers.add(buffer); + length += buffer.remaining(); + } + + public void flip() { + firstBuffer.flip(); + if (buffers != null) { + for (ReusableBuffer buffer : buffers) { + buffer.flip(); + } + } + currentBuffer = firstBuffer; + } + + public void freeBuffers() { + BufferPool.free(firstBuffer); + if (buffers != null) { + for (ReusableBuffer buffer : buffers) { + BufferPool.free(buffer); + } + } + } + + @Override + public void write(int b) throws IOException { + checkAndGetBuffer(1).put((byte)b); + length++; + } + + public void write(byte b[], int off, int len) throws IOException { + checkAndGetBuffer(len).put(b, off, len); + length += len; + } + + public ReusableBuffer[] getBuffers() { + if (buffers == null) { + return new ReusableBuffer[]{firstBuffer}; + } else { + ReusableBuffer[] arr = new ReusableBuffer[buffers.size()+1]; + arr[0] = firstBuffer; + for (int i = 1; i <= buffers.size(); i++) + arr[i] = buffers.get(i-1); + return arr; + } + } + + public int length() { + return length; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/trace/Tracer.java b/java/foundation/src/org/xtreemfs/foundation/trace/Tracer.java new file mode 100644 index 0000000..f8e2e83 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/trace/Tracer.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.trace; + +import java.io.FileOutputStream; +import java.io.IOException; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * + * @author bjko + */ +public class Tracer { + + /** + * Set this to true to enable trace log file for all requests. + * + * @attention: MUST BE SET TO FALSE FOR NORMAL OPERATIONS. + */ + public static final boolean COLLECT_TRACES = false; + + public enum TraceEvent { + + RECEIVED('>'), RESPONSE_SENT('<'), ERROR_SENT('E'); + + private final char eventType; + + TraceEvent(char eventType) { + this.eventType = eventType; + } + + public char getEventType() { + return this.eventType; + } + }; + + private static Tracer theInstance; + + private final FileOutputStream fos; + + private Tracer(String traceFileName) throws IOException { + theInstance = this; + + fos = new FileOutputStream(traceFileName, true); + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, this, + "TRACING IS ENABLED, THIS WILL CAUSE PERFORMANCE TO BE REDUCED!"); + fos.write("#requestId;internal rq sequence no;event;component;message\n".getBytes()); + } + + /** + * Initialize the tracer. + * + * @param traceFileName + * file name to write trace data to (append mode). + * @throws java.io.IOException + * if the file cannot be opened + */ + public static void initialize(String traceFileName) throws IOException { + new Tracer(traceFileName); + } + + private void writeTraceRecord(String requestId, long intRqSeqNo, TraceEvent event, String component, + String message) { + StringBuffer sb = new StringBuffer(); + + if (requestId != null) + sb.append(requestId); + + sb.append(';'); + sb.append(intRqSeqNo); + sb.append(';'); + sb.append(event.getEventType()); + sb.append(';'); + if (component != null) + sb.append(component); + sb.append(';'); + if (message != null) + sb.append(message); + sb.append("\n"); + try { + fos.write(sb.toString().getBytes()); + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + public static void trace(String requestId, long intRqSeqNo, TraceEvent event, String component, + String message) { + assert (theInstance != null) : "Tracer not initialized"; + theInstance.writeTraceRecord(requestId, intRqSeqNo, event, component, message); + } + + @Override + public void finalize() { + try { + fos.close(); + } catch (IOException ex) { + } + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/util/CLIParser.java b/java/foundation/src/org/xtreemfs/foundation/util/CLIParser.java new file mode 100644 index 0000000..26d7652 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/util/CLIParser.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.util; + +import java.io.File; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class CLIParser { + + public static final class CliOption { + public enum OPTIONTYPE { + NUMBER, STRING, SWITCH, URL, FILE + }; + + public final OPTIONTYPE optType; + + public Boolean switchValue; + + public String stringValue; + + public Long numValue; + + public PBRPCServiceURL urlValue; + + public File fileValue; + + public String urlDefaultProtocol; + + public int urlDefaultPort; + + public String usageParams; + + public String usageText; + + public CliOption(OPTIONTYPE oType) { + this.optType = oType; + if (optType == OPTIONTYPE.SWITCH) + switchValue = new Boolean(false); + } + + public CliOption(OPTIONTYPE oType, String usageText, String usageParams) { + this(oType); + this.usageText = usageText; + this.usageParams = usageParams == null? "": usageParams; + } + } + + public static void parseCLI(String[] args, Map options, List arguments) + throws IllegalArgumentException { + List argList = Arrays.asList(args); + + Iterator iter = argList.iterator(); + while (iter.hasNext()) { + final String arg = iter.next().trim(); + if (arg.startsWith("-")) { + // option + final String optName = arg.substring(1); + final CliOption option = options.get(optName); + if (option == null) { + throw new IllegalArgumentException(arg + " is not a valid option"); + } + switch (option.optType) { + case SWITCH: { + option.switchValue = true; + break; + } + case STRING: { + if (iter.hasNext()) { + final String value = iter.next(); + option.stringValue = value.trim(); + } else { + throw new IllegalArgumentException(arg + " requires a string argument"); + } + break; + } + case NUMBER: { + if (iter.hasNext()) { + final String value = iter.next(); + try { + option.numValue = Long.valueOf(value.trim()); + } catch (NumberFormatException ex) { + throw new IllegalArgumentException(arg + " requires a integer argument and " + + value + " is not an integer"); + } + } else { + throw new IllegalArgumentException(arg + " requires a string argument"); + } + break; + } + case URL: { + if (iter.hasNext()) { + final String value = iter.next(); + try { + final PBRPCServiceURL tmp = new PBRPCServiceURL(value, + option.urlDefaultProtocol, option.urlDefaultPort); + option.urlValue = tmp; + } catch (Exception ex) { + throw new IllegalArgumentException(ex); + } + } else { + throw new IllegalArgumentException(arg + " requires a string argument"); + } + break; + } + + case FILE: { + if (iter.hasNext()) { + final String value = iter.next(); + try { + final File tmp = new File(value); + option.fileValue = tmp; + } catch (Exception ex) { + throw new IllegalArgumentException(arg + " requires ://:"); + } + } else { + throw new IllegalArgumentException(arg + " requires a string argument"); + } + break; + } + + } + } else { + arguments.add(arg); + } + } + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/util/CLOption.java b/java/foundation/src/org/xtreemfs/foundation/util/CLOption.java new file mode 100644 index 0000000..6cca3d6 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/util/CLOption.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.util; + +import java.net.MalformedURLException; + +/** + * + * @author bjko + */ +public abstract class CLOption { + + protected String shortName; + protected String longName; + protected String helpText; + protected boolean set; + + public CLOption(String shortName, String longName, String helpText) { + this.shortName = shortName; + this.longName = longName; + this.helpText = helpText; + if ((shortName == null )&& (longName == null)) + throw new IllegalArgumentException("must specify either a shortName or a longName or both"); + } + + public String getName() { + StringBuilder sb = new StringBuilder(); + if (shortName != null) { + sb.append("-"); + sb.append(shortName); + if (longName != null) + sb.append("/"); + else + sb.append(" "); + } + if (longName != null) { + sb.append("--"); + sb.append(longName); + sb.append("="); + } + return sb.toString(); + } + + public String getName(boolean useShortName) { + if (useShortName) + return this.shortName; + else + return this.longName; + } + + public abstract String getHelp(); + + /** + * called only when the option is present + * @param value + * @throws IllegalArgumentException + */ + public void parse(String value) throws IllegalArgumentException { + set = true; + } + + public boolean isSet() { + return set; + } + + public abstract boolean requiresArgument(); + + @Override + public String toString() { + return getHelp(); + } + + public static class Switch extends CLOption { + + protected boolean value; + + public Switch(String shortName, String longName, String helpText) { + super(shortName,longName,helpText); + } + + @Override + public String getHelp() { + return getName()+helpText; + } + + @Override + public void parse(String value) throws IllegalArgumentException { + super.parse(value); + this.value = true; + } + + @Override + public boolean requiresArgument() { + return false; + } + + public boolean getValue() { + return value; + } + } + + public static class StringValue extends CLOption { + + protected String value; + + public StringValue(String shortName, String longName, String helpText) { + super(shortName,longName,helpText); + } + + @Override + public String getHelp() { + return getName()+" "+helpText; + } + + @Override + public void parse(String value) throws IllegalArgumentException { + super.parse(value); + this.value = value; + } + + @Override + public boolean requiresArgument() { + return true; + } + + public String getValue() { + return value; + } + + } + + public static class IntegerValue extends CLOption { + + protected int value; + + public IntegerValue(String shortName, String longName, String helpText) { + super(shortName,longName,helpText); + } + + @Override + public String getHelp() { + return getName()+" "+helpText; + } + + @Override + public void parse(String value) throws IllegalArgumentException { + super.parse(value); + try { + this.value = Integer.valueOf(value); + } catch (NumberFormatException ex) { + throw new IllegalArgumentException("'"+value+"' is not a valid number"); + } + } + + @Override + public boolean requiresArgument() { + return true; + } + + public int getValue() { + return value; + } + } + + public static class URLValue extends CLOption { + + protected PBRPCServiceURL value; + + protected final String defaultSchema; + + protected final int defaultPort; + + public URLValue(String shortName, String longName, String helpText, + String defaultSchema, int defaultPort) { + super(shortName,longName,helpText); + this.defaultSchema = defaultSchema; + this.defaultPort = defaultPort; + } + + @Override + public String getHelp() { + return getName()+"[://][:] "+helpText+ + " (default schema is "+defaultSchema+", default port is "+defaultPort+")"; + } + + @Override + public void parse(String value) throws IllegalArgumentException { + super.parse(value); + try { + this.value = new PBRPCServiceURL(value, defaultSchema, defaultPort); + } catch (MalformedURLException ex) { + throw new IllegalArgumentException("'"+value+"' is not a valid URL ("+ex.getMessage()+")"); + } + } + + @Override + public boolean requiresArgument() { + return true; + } + + public PBRPCServiceURL getValue() { + return value; + } + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/util/CLOptionParser.java b/java/foundation/src/org/xtreemfs/foundation/util/CLOptionParser.java new file mode 100644 index 0000000..ae00932 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/util/CLOptionParser.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.util; + +import java.util.LinkedList; +import java.util.List; + +/** + * + * @author bjko + */ +public class CLOptionParser { + + private final String programName; + + private final List options; + + private final List arguments; + + + public CLOptionParser(String programName) { + this.programName = programName; + options = new LinkedList(); + arguments = new LinkedList(); + } + + public CLOption addOption(CLOption option) { + CLOption rv = option; + for (CLOption tmp : options) { + if (( (tmp.getName(true) == null) || tmp.getName(true).equals(option.getName(true)) ) && + ( (tmp.getName(false) == null) || tmp.getName(false).equals(option.getName(false))) ) { + rv = tmp; + break; + } + } + if (rv == option) + options.add(option); + return rv; + } + + public void printUsage(String arguments) { + System.out.println(programName+" [options] "+arguments); + printOptionHelp(); + System.out.println(""); + } + + public void printOptionHelp() { + for (CLOption option : options) { + System.out.println("\t"+option.getHelp()); + } + } + + public void parse(String[] args) throws IllegalArgumentException { + int position = 0; + boolean nextIsValue = false; + CLOption currentOption = null; + while (position < args.length) { + if (nextIsValue) { + assert(currentOption != null); + currentOption.parse(args[position]); + currentOption = null; + nextIsValue = false; + } else { + if (args[position].charAt(0) == '-') { + boolean useShortName; + String name; + String value = null; + if (args[position].charAt(1) == '-') { + useShortName = false; + name = args[position].substring(2); + if (name.length() == 0) { + throw new IllegalArgumentException("-- is not a valid option"); + } + int posEq = name.indexOf("="); + if (posEq >= 0) { + value = name.substring(posEq+1); + name = name.substring(0, posEq); + } + } else { + useShortName = true; + name = args[position].substring(1); + if (name.length() == 0) { + throw new IllegalArgumentException("- is not a valid option"); + } + } + boolean optFound = false; + for (CLOption option : options) { + final String optName = option.getName(useShortName); + if ((optName != null) && optName.equals(name)) { + if (option.requiresArgument()) { + if (value == null) { + currentOption = option; + nextIsValue = true; + } else { + option.parse(value); + } + } else { + option.parse(null); + } + optFound = true; + break; + } + } + if (!optFound) + throw new IllegalArgumentException("'"+args[position]+"' is not a valid option"); + + } else { + arguments.add(args[position]); + } + } + position++; + } + if (nextIsValue) { + throw new IllegalArgumentException("expected value for option '"+currentOption.getName()+"'"); + } + } + + public List getArguments() { + return this.arguments; + } + + + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/util/FSUtils.java b/java/foundation/src/org/xtreemfs/foundation/util/FSUtils.java new file mode 100644 index 0000000..21231ba --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/util/FSUtils.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Jan Stender, + * Felix Langner, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.util; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.util.ArrayList; +import java.util.List; + +/** + * A class containing helper functions for working with the local file system. + * + * @author stender + */ +public class FSUtils { + + /** + * Recursively deletes all contents of the given directory. + * + * @param file + * the directory to delete + */ + public static void delTree(File file) { + + if (!file.exists()) + return; + + File[] fileList; + if ((fileList = file.listFiles())!=null){ + for (File f : fileList) { + if (f.isDirectory()) + delTree(f); + else + f.delete(); + } + } + + file.delete(); + } + + /** + * Copies a whole directory tree to another directory. + * + * @param srcFile + * the source tree + * @param trgFile + * the target point where to copy the source tree + * @throws IOException + * if an I/O error occurs + */ + public static void copyTree(File srcFile, File trgFile) throws IOException { + + if (srcFile.isDirectory()) { + + trgFile.mkdir(); + for (File file : srcFile.listFiles()) { + copyTree(file, new File(trgFile, file.getName())); + } + } else { + + FileChannel in = null, out = null; + try { + in = new FileInputStream(srcFile).getChannel(); + out = new FileOutputStream(trgFile).getChannel(); + + in.transferTo(0, in.size(), out); + } finally { + if (in != null) + in.close(); + if (out != null) + out.close(); + } + } + } + + /** + * Returns the free disk space on the partition storing the given directory. + * + * @param dir + * the directory stored in the partition + * @return the free disk space + */ + public static long getFreeSpace(String dir) { + return new File(dir).getFreeSpace(); + } + + /** + * Returns the available disk space on the partition storing the given directory. + * + * @param dir + * the directory stored in the partition + * @return the available disk space (for non-privileged users) + */ + public static long getUsableSpace(String dir) { + return new File(dir).getUsableSpace(); + } + + public static File[] listRecursively(File rootDir, FileFilter filter) { + List list = new ArrayList(); + listRecursively(rootDir, filter, list); + return list.toArray(new File[list.size()]); + } + + private static void listRecursively(File rootDir, FileFilter filter, List list) { + + if (!rootDir.exists()) + return; + + // first, all files in subdirectories + File[] nestedDirs = rootDir.listFiles(new FileFilter() { + public boolean accept(File pathname) { + return pathname.isDirectory(); + } + }); + + for (File dir : nestedDirs) + listRecursively(dir, filter, list); + + for (File f : rootDir.listFiles(filter)) + list.add(f); + } +} diff --git a/java/foundation/src/org/xtreemfs/foundation/util/InvalidUsageException.java b/java/foundation/src/org/xtreemfs/foundation/util/InvalidUsageException.java new file mode 100644 index 0000000..efdad0b --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/util/InvalidUsageException.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010, Konrad-Zuse-Zentrum fuer Informationstechnik Berlin + * + * All rights reserved. + * + * 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 the Konrad-Zuse-Zentrum fuer Informationstechnik Berlin + * 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 HOLDER 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. + */ +/* + * AUTHORS: Bjoern Kolbeck (ZIB) + */ + +package org.xtreemfs.foundation.util; + +/** + * + * @author bjko + */ +public class InvalidUsageException extends Exception { + private static final long serialVersionUID = -5461559345851901506L; + + public InvalidUsageException(String message) { + super(message); + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/util/OutputUtils.java b/java/foundation/src/org/xtreemfs/foundation/util/OutputUtils.java new file mode 100644 index 0000000..fe9a7c5 --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/util/OutputUtils.java @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; + +/** + * + * @author bjko + */ +public final class OutputUtils { + + public static final char[] trHex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + public static final byte[] fromHex; + + static { + fromHex = new byte[128]; + fromHex['0'] = 0; + fromHex['1'] = 1; + fromHex['2'] = 2; + fromHex['3'] = 3; + fromHex['4'] = 4; + fromHex['5'] = 5; + fromHex['6'] = 6; + fromHex['7'] = 7; + fromHex['8'] = 8; + fromHex['9'] = 9; + fromHex['A'] = 10; + fromHex['a'] = 10; + fromHex['B'] = 11; + fromHex['b'] = 11; + fromHex['C'] = 12; + fromHex['c'] = 12; + fromHex['D'] = 13; + fromHex['d'] = 13; + fromHex['E'] = 14; + fromHex['e'] = 14; + fromHex['F'] = 15; + fromHex['f'] = 15; + + } + + public static final String byteToHexString(byte b) { + StringBuilder sb = new StringBuilder(2); + sb.append(trHex[((b >> 4) & 0x0F)]); + sb.append(trHex[(b & 0x0F)]); + return sb.toString(); + } + + public static final String byteArrayToHexString(byte[] array) { + StringBuilder sb = new StringBuilder(2 * array.length); + for (byte b : array) { + sb.append(trHex[((b >> 4) & 0x0F)]); + sb.append(trHex[(b & 0x0F)]); + } + return sb.toString(); + } + + public static final String byteArrayToFormattedHexString(byte[] array) { + return byteArrayToFormattedHexString(array, 0, array.length); + } + + public static final String byteArrayToFormattedHexString(byte[] array, int offset, int len) { + StringBuilder sb = new StringBuilder(2 * len); + for (int i = offset; i < offset + len; i++) { + sb.append(trHex[((array[i] >> 4) & 0x0F)]); + sb.append(trHex[(array[i] & 0x0F)]); + if ((i - offset) % 4 == 3) { + if ((i - offset) % 16 == 15) + sb.append("\n"); + else + sb.append(" "); + } + + } + return sb.toString(); + } + + public static final String stackTraceToString(Throwable th) { + + PrintStream ps = null; + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ps = new PrintStream(out); + if (th != null) + th.printStackTrace(ps); + + return new String(out.toByteArray()); + + } finally { + if (ps != null) + ps.close(); + } + + } + + public static String formatBytes(long bytes) { + + double kb = bytes / 1024.0; + double mb = bytes / (1024.0 * 1024.0); + double gb = bytes / (1024.0 * 1024.0 * 1024.0); + double tb = bytes / (1024.0 * 1024.0 * 1024.0 * 1024.0); + + if (tb >= 1.0) { + return String.format("%.2f TB", tb); + } else if (gb >= 1.0) { + return String.format("%.2f GB", gb); + } else if (mb >= 1.0) { + return String.format("%.2f MB", mb); + } else if (kb >= 1.0) { + return String.format("%.2f kB", kb); + } else { + return bytes + " bytes"; + } + } + + public static String escapeToXML(String st) { + st = st.replace("&", "&"); + st = st.replace("'", "'"); + st = st.replace("<", "<"); + st = st.replace(">", ">"); + st = st.replace("\"", """); + return st; + } + + public static String unescapeFromXML(String st) { + st = st.replace("&", "&"); + st = st.replace("'", "'"); + st = st.replace("<", "<"); + st = st.replace(">", ">"); + st = st.replace(""", "\""); + return st; + } + + public static String encodeBase64(byte[] bytes) { + return new String(Base64.encodeBase64(bytes)); + } + + public static byte[] decodeBase64(String s) throws IOException { + return Base64.decodeBase64(s.getBytes()); + } + + public static byte[] hexStringToByteArray(String hexString) { + + assert (hexString.length() % 2 == 0); + byte[] bytes = new byte[hexString.length() / 2]; + + for (int i = 0; i < hexString.length(); i += 2) { + int b = Integer.parseInt(hexString.substring(i, i + 2), 16); + bytes[i / 2] = b >= 128 ? (byte) (b - 256) : (byte) b; + } + + return bytes; + } + + /** + * Writes an integer as a hex string to sb starting with the LSB. + * + * @param sb + * @param value + */ + public static void writeHexInt(final StringBuffer sb, final int value) { + sb.append(OutputUtils.trHex[(value & 0x0F)]); + sb.append(OutputUtils.trHex[((value >> 4) & 0x0F)]); + sb.append(OutputUtils.trHex[((value >> 8) & 0x0F)]); + sb.append(OutputUtils.trHex[((value >> 12) & 0x0F)]); + sb.append(OutputUtils.trHex[((value >> 16) & 0x0F)]); + sb.append(OutputUtils.trHex[((value >> 20) & 0x0F)]); + sb.append(OutputUtils.trHex[((value >> 24) & 0x0F)]); + sb.append(OutputUtils.trHex[((value >> 28) & 0x0F)]); + } + + public static void writeHexLong(final StringBuffer sb, final long value) { + OutputUtils.writeHexInt(sb, (int) (value & 0xFFFFFFFF)); + OutputUtils.writeHexInt(sb, (int) (value >> 32)); + } + + /** + * Reads an integer from a hex string (starting with the LSB). + * + * @param str + * @param position + * @return + */ + public static int readHexInt(final String str, int position) { + int value = OutputUtils.fromHex[str.charAt(position)]; + value += ((int) OutputUtils.fromHex[str.charAt(position + 1)]) << 4; + value += ((int) OutputUtils.fromHex[str.charAt(position + 2)]) << 8; + value += ((int) OutputUtils.fromHex[str.charAt(position + 3)]) << 12; + value += ((int) OutputUtils.fromHex[str.charAt(position + 4)]) << 16; + value += ((int) OutputUtils.fromHex[str.charAt(position + 5)]) << 20; + value += ((int) OutputUtils.fromHex[str.charAt(position + 6)]) << 24; + value += ((int) OutputUtils.fromHex[str.charAt(position + 7)]) << 28; + + return value; + } + + public static long readHexLong(final String str, int position) { + int low = OutputUtils.readHexInt(str, position); + int high = OutputUtils.readHexInt(str, position + 8); + + // calculate the value: left-shift the upper 4 bytes by 32 bit and + // append the lower 32 bit + long value = ((long) high) << 32 | (((long) low) & 4294967295L); + return value; + } + + public static String getThreadDump() { + StringBuilder sb = new StringBuilder(); + sb.append("

THREAD STATES

");
+        final Map traces = Thread.getAllStackTraces();
+        for (Thread t : traces.keySet()) {
+            sb.append("thread: ");
+            sb.append(t.getName());
+            sb.append("\n");
+            final StackTraceElement[] elems = traces.get(t);
+            for (int i = elems.length - 1; i >= 0; i--) {
+                sb.append(elems[i].toString());
+                sb.append("\n");
+            }
+            sb.append("\n");
+        }
+        sb.append("
"); + return sb.toString(); + } + + /** + * Formats number of seconds to a string consists of number of seconds, minutes, hours or days and the + * corresponding entity (e.g. "3 minutes" if seconds is between 180 and 239). + * + * @param seconds + * @return + */ + public static String SecondsToString(long seconds) { + String timeString = null; + if (seconds < 60) { + // seconds less than one minute + timeString = seconds + " seconds"; + } else if (seconds < 3600) { + // seconds less than one hour + timeString = (seconds / 60) + " minutes"; + } else if (seconds < 86400) { + // seconds less than one day + timeString = (seconds / 3600) + " hours"; + } else { + // seconds equals or longer than one day + timeString = (seconds / 86400) + " days"; + } + return timeString; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/util/PBRPCServiceURL.java b/java/foundation/src/org/xtreemfs/foundation/util/PBRPCServiceURL.java new file mode 100644 index 0000000..8cfea6d --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/util/PBRPCServiceURL.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.util; + +import java.net.MalformedURLException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @author bjko + */ +public class PBRPCServiceURL { + + static { + + urlPattern = Pattern.compile("((pbrpc[gs]?):\\/\\/)?([^:]+)(:([0-9]+))?/?"); + } + + private static final Pattern urlPattern; + + private final String protocol; + + private final String host; + + private final int port; + + public PBRPCServiceURL(String url, String defaultProtocol, int defaultPort) throws MalformedURLException { + + //parse URL + Matcher m = urlPattern.matcher(url); + if (m.matches()) { + + if (m.group(2) != null) + protocol = m.group(2); + else + protocol = defaultProtocol; + + host = m.group(3); + + if (m.group(4) != null) + port = Integer.valueOf(m.group(4).substring(1)); + else + port = defaultPort; + + } else + throw new MalformedURLException("'"+url+"' is not a valid XtreemFS service URL"); + + } + + /** + * @return the protocol + */ + public String getProtocol() { + return protocol; + } + + /** + * @return the host + */ + public String getHost() { + return host; + } + + /** + * @return the port + */ + public int getPort() { + return port; + } + + public String toString() { + return protocol+"://"+host+":"+port; + } + +} diff --git a/java/foundation/src/org/xtreemfs/foundation/util/PingServer.java b/java/foundation/src/org/xtreemfs/foundation/util/PingServer.java new file mode 100644 index 0000000..cd97c7f --- /dev/null +++ b/java/foundation/src/org/xtreemfs/foundation/util/PingServer.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.util; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; +import org.xtreemfs.foundation.pbrpc.server.RPCNIOSocketServer; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequestListener; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; + +/** + * + * @author bjko + */ +public class PingServer { + + public static final String CERT_DIR = "../../tests/certs/"; + + public static void main(String[] args) { + + try { + Logging.start(Logging.LEVEL_DEBUG, Category.all); + + SSLOptions ssl = null; + if (true) { + ssl = new SSLOptions(new FileInputStream(PingServer.CERT_DIR + "Client.p12"), + "passphrase", SSLOptions.PKCS12_CONTAINER, new FileInputStream(PingServer.CERT_DIR + "trusted.jks"), + "passphrase", SSLOptions.JKS_CONTAINER, false, true, null, null); + } + + RPCNIOSocketServer server = new RPCNIOSocketServer(12345, null, new RPCServerRequestListener() { + int cnt = 0; + + @Override + public void receiveRecord(RPCServerRequest rq) { + try { + ReusableBufferInputStream is = new ReusableBufferInputStream(rq.getMessage()); + Ping.PingRequest pingRq = Ping.PingRequest.parseFrom(is); + + Ping.PingResponse resp = null; + if (pingRq.getSendError()) { + resp = Ping.PingResponse.newBuilder().setError(Ping.PingResponse.PingError.newBuilder().setErrorMessage("error message")).build(); + } else { + Ping.PingResponse.PingResult result = Ping.PingResponse.PingResult.newBuilder().setText(pingRq.getText()).build(); + resp = Ping.PingResponse.newBuilder().setResult(result).build(); + } + ReusableBuffer data = null; + if (rq.getData() != null) { + data = rq.getData().createViewBuffer(); + data.limit(data.capacity()); + data.position(data.capacity()); + } + rq.sendResponse(resp,data); + cnt++; + if (cnt%1000 == 0) { + System.out.println(BufferPool.getStatus()); + } + } catch (Exception ex) { + ex.printStackTrace(); + rq.sendError(RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(RPC.ErrorType.GARBAGE_ARGS).setErrorMessage(ex.getMessage()).setDebugInfo(OutputUtils.stackTraceToString(ex)).build()); + } finally { + rq.freeBuffers(); + } + } + }, ssl); + server.start(); + server.waitForStartup(); + System.out.println("PING server running"); + } catch (Exception ex) { + Logger.getLogger(PingServer.class.getName()).log(Level.SEVERE, null, ex); + } + + } + +} diff --git a/java/foundation/test/org/xtreemfs/foundation/buffer/BufferPoolTest.java b/java/foundation/test/org/xtreemfs/foundation/buffer/BufferPoolTest.java new file mode 100644 index 0000000..b8a8fa1 --- /dev/null +++ b/java/foundation/test/org/xtreemfs/foundation/buffer/BufferPoolTest.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2014 by Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.buffer; + +import static org.junit.Assert.*; + +import org.junit.Test; + +/** + * Tests different sequences of {@link BufferPool#allocate(int)} and {@link BufferPool#free(ReusableBuffer)} + * operations, some also regarding view buffers. + * + * Please note that {@link BufferPool} is a singleton and therefore the pool size increases as the number of + * run tests does. Therefore, each test has to evaluate changes in the pool size relative to the pool size at + * the start of test. + * + */ +public class BufferPoolTest { + public static final int TEST_BUFFER_SIZE = 8192; + + @Test + public final void testSimpleAllocateAndFree() { + ReusableBuffer buf = null; + // There may be already a buffer pooled. If not, the pool size will stay 0 after an allocate(). + int currentPoolSize = Math.max(0, BufferPool.getPoolSize(TEST_BUFFER_SIZE) - 1); + + buf = BufferPool.allocate(TEST_BUFFER_SIZE); + assertEquals("BufferPool must be empty because a buffer was only allocated but not returned so far.", + currentPoolSize, + BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + + BufferPool.free(buf); + assertEquals("One buffer must have been returned and pooled.", currentPoolSize + 1, + BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + + buf = BufferPool.allocate(TEST_BUFFER_SIZE); + assertEquals("Pooled buffer must have been re-allocated.", currentPoolSize, + BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + + BufferPool.free(buf); + assertEquals("One buffer must have been returned and pooled again.", currentPoolSize + 1, + BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + } + + @Test + public final void testReusableViewBuffers() { + ReusableBuffer buf = null; + // There may be already a buffer pooled. If not, the pool size will stay 0 after an allocate(). + int currentPoolSize = Math.max(0, BufferPool.getPoolSize(TEST_BUFFER_SIZE) - 1); + + buf = BufferPool.allocate(TEST_BUFFER_SIZE); + assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + + BufferPool.free(buf); + assertEquals(currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + + buf = BufferPool.allocate(TEST_BUFFER_SIZE); + assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + ReusableBuffer viewBuffer = buf.createViewBuffer(); + + BufferPool.free(viewBuffer); + assertEquals("Buffer not returned to pool yet since one reference is left.", currentPoolSize, + BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + BufferPool.free(buf); + assertEquals("Buffer must have been returned to pool since no reference is left.", currentPoolSize + 1, + BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + } + + @Test + public final void testReusableViewBuffersOfReusableViewBuffers() { + ReusableBuffer buf = null; + // There may be already a buffer pooled. If not, the pool size will stay 0 after an allocate(). + int currentPoolSize = Math.max(0, BufferPool.getPoolSize(TEST_BUFFER_SIZE) - 1); + + buf = BufferPool.allocate(TEST_BUFFER_SIZE); + assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + + BufferPool.free(buf); + assertEquals(currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + + buf = BufferPool.allocate(TEST_BUFFER_SIZE); + assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + ReusableBuffer viewBuffer = buf.createViewBuffer(); + // Create a view buffer of a view buffer. + ReusableBuffer viewBuffer2 = viewBuffer.createViewBuffer(); + + BufferPool.free(viewBuffer2); + assertEquals("Buffer not returned to pool yet since two references are left.", currentPoolSize, + BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + BufferPool.free(viewBuffer); + assertEquals("Buffer not returned to pool yet since one reference is left.", currentPoolSize, + BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + BufferPool.free(buf); + assertEquals("Buffer must have been returned to pool since no reference is left.", currentPoolSize + 1, + BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + } + + private void assertThatAssertionsAreEnabled() { + boolean assertOn = false; + // *assigns* true if assertions are on. + assert assertOn = true; + assertTrue("Enable assertions or this test won't work correctly.", assertOn); + } + + @Test(expected = AssertionError.class) + public final void testDoubleFreeThrows() { + assertThatAssertionsAreEnabled(); + + ReusableBuffer buf = null; + // There may be already a buffer pooled. If not, the pool size will stay 0 after an allocate(). + int currentPoolSize = Math.max(0, BufferPool.getPoolSize(TEST_BUFFER_SIZE) - 1); + + buf = BufferPool.allocate(TEST_BUFFER_SIZE); + assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + + BufferPool.free(buf); + assertEquals(currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + + // Double free will trigger assertion. + BufferPool.free(buf); + } + + @Test(expected = AssertionError.class) + public final void testDoubleFreeOfRecursiveViewBuffersThrows() { + assertThatAssertionsAreEnabled(); + + ReusableBuffer buf = null; + // There may be already a buffer pooled. If not, the pool size will stay 0 after an allocate(). + int currentPoolSize = Math.max(0, BufferPool.getPoolSize(TEST_BUFFER_SIZE) - 1); + + buf = BufferPool.allocate(TEST_BUFFER_SIZE); + assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + + BufferPool.free(buf); + assertEquals(currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + + buf = BufferPool.allocate(TEST_BUFFER_SIZE); + assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); + ReusableBuffer viewBuffer = buf.createViewBuffer(); + // Create a view buffer of a view buffer. + ReusableBuffer viewBuffer2 = viewBuffer.createViewBuffer(); + + BufferPool.free(viewBuffer2); + BufferPool.free(viewBuffer); + BufferPool.free(buf); + + // Double free will trigger assertion. + BufferPool.free(viewBuffer2); + } +} diff --git a/java/foundation/test/org/xtreemfs/foundation/buffer/ReusableBufferTest.java b/java/foundation/test/org/xtreemfs/foundation/buffer/ReusableBufferTest.java new file mode 100644 index 0000000..5c62c19 --- /dev/null +++ b/java/foundation/test/org/xtreemfs/foundation/buffer/ReusableBufferTest.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2010 by Bjoern Kolbeck, Zuse Institute Berlin + * 2014 by Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.foundation.buffer; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class ReusableBufferTest { + + @Test + public final void testArray() { + ReusableBuffer rb = ReusableBuffer.wrap("Yagga Yagga".getBytes()); + ReusableBuffer vb = rb.createViewBuffer(); + + vb.position(0); + vb.limit(5); + String result = new String(vb.array()); + + assertEquals("Yagga", result); + } + + @Test + public final void testRecursiveNonResuableViewBuffer() { + ReusableBuffer rb = ReusableBuffer.wrap("Yagga Yagga".getBytes()); + assertFalse(rb.isReusable()); + + ReusableBuffer viewBuffer = rb.createViewBuffer(); + assertFalse(viewBuffer.isReusable()); + + ReusableBuffer viewBuffer2 = viewBuffer.createViewBuffer(); + assertFalse(viewBuffer2.isReusable()); + } + + @Test + public final void testNonResuableViewBufferHasIndependentPositions() { + ReusableBuffer rb = ReusableBuffer.wrap("Yagga Yagga".getBytes()); + assertFalse(rb.isReusable()); + rb.position(0); + rb.limit(5); + + ReusableBuffer viewBuffer = rb.createViewBuffer(); + assertFalse(viewBuffer.isReusable()); + viewBuffer.position(1); + viewBuffer.limit(4); + + assertEquals(0, rb.position()); + assertEquals(5, rb.limit()); + assertEquals(1, viewBuffer.position()); + assertEquals(4, viewBuffer.limit()); + + ReusableBuffer viewBufferOfViewBuffer = viewBuffer.createViewBuffer(); + assertFalse(viewBufferOfViewBuffer.isReusable()); + viewBufferOfViewBuffer.position(2); + viewBufferOfViewBuffer.limit(3); + + assertEquals(0, rb.position()); + assertEquals(5, rb.limit()); + assertEquals(1, viewBuffer.position()); + assertEquals(4, viewBuffer.limit()); + assertEquals(2, viewBufferOfViewBuffer.position()); + assertEquals(3, viewBufferOfViewBuffer.limit()); + } + + @Test + public final void testRange() { + // Test with a view buffer and with a reusable buffer. + ReusableBuffer[] buffers = new ReusableBuffer[] { ReusableBuffer.wrap("Yagga Yagga".getBytes()), + BufferPool.allocate(12) }; + for (ReusableBuffer buf : buffers) { + buf.range(1, 4); + assertEquals(0, buf.position()); + assertEquals(4, buf.limit()); + assertEquals(4, buf.capacity()); + assertEquals(4, buf.remaining()); + + // Now create a view buffer which will have a different range. + ReusableBuffer viewBuf = buf.createViewBuffer(); + viewBuf.range(2, 2); + assertEquals(0, viewBuf.position()); + assertEquals(2, viewBuf.limit()); + assertEquals(2, viewBuf.capacity()); + assertEquals(2, viewBuf.remaining()); + + // The range of the original buffer was not affected. + assertEquals(0, buf.position()); + assertEquals(4, buf.limit()); + assertEquals(4, buf.capacity()); + assertEquals(4, buf.remaining()); + + if (buf.isReusable()) { + BufferPool.free(buf); + } + } + } + + @Test + public final void testShrink() { + // Test with a view buffer and with a reusable buffer. + ReusableBuffer[] buffers = new ReusableBuffer[] { ReusableBuffer.wrap("Yagga Yagga".getBytes()), + BufferPool.allocate(12) }; + for (ReusableBuffer buf : buffers) { + buf.shrink(4); + assertEquals(0, buf.position()); + assertEquals(4, buf.limit()); + assertEquals(4, buf.capacity()); + assertEquals(4, buf.remaining()); + + // Now create a view buffer which will have a different range. + ReusableBuffer viewBuf = buf.createViewBuffer(); + viewBuf.shrink(2); + assertEquals(0, viewBuf.position()); + assertEquals(2, viewBuf.limit()); + assertEquals(2, viewBuf.capacity()); + assertEquals(2, viewBuf.remaining()); + + // The range of the original buffer was not affected. + assertEquals(0, buf.position()); + assertEquals(4, buf.limit()); + assertEquals(4, buf.capacity()); + assertEquals(4, buf.remaining()); + + if (buf.isReusable()) { + BufferPool.free(buf); + } + } + } + + @Test + public final void testEnlarge() { + // Test with a view buffer and with a reusable buffer. + ReusableBuffer[] buffers = new ReusableBuffer[] { ReusableBuffer.wrap("Yagga Yagga".getBytes()), + BufferPool.allocate(11) }; + for (ReusableBuffer buf : buffers) { + int originalBufSize = buf.capacity(); + + // When there is no underlying, larger buffer, enlarge won't have an effect (the capacity of the + // underlying buffer can be higher than the current buffer size.) + assertFalse(buf.enlarge(buf.capacityUnderlying() + 1)); + // Enlarging to the current size should always work. + assertTrue(buf.enlarge(originalBufSize)); + assertEquals(originalBufSize, buf.capacity()); + + // Create a view buffer first which is smaller than the original one. + buf.limit(originalBufSize / 2); + ReusableBuffer smallerBuf = buf.createViewBuffer(); + + // Enlarge it, but not larger than the underlying buffer. + int newBufSize = smallerBuf.capacity() * 2; + assertTrue(smallerBuf.enlarge(newBufSize)); + assertEquals(0, buf.position()); + assertEquals(newBufSize, smallerBuf.limit()); + assertEquals(newBufSize, smallerBuf.capacity()); + assertEquals(newBufSize, smallerBuf.remaining()); + + // You cannot enlarge it over the capacity of the original buffer. + assertFalse(smallerBuf.enlarge(buf.capacityUnderlying() + 1)); + + // The range of the original buffer was not affected. + assertEquals(0, buf.position()); + assertEquals(originalBufSize / 2, buf.limit()); + assertEquals(originalBufSize, buf.capacity()); + assertEquals(originalBufSize / 2, buf.remaining()); + + if (buf.isReusable()) { + BufferPool.free(buf); + } + } + } +} diff --git a/java/foundation/test/org/xtreemfs/test/foundation/checksums/ChecksumFactoryTest.java b/java/foundation/test/org/xtreemfs/test/foundation/checksums/ChecksumFactoryTest.java new file mode 100644 index 0000000..4e00b1e --- /dev/null +++ b/java/foundation/test/org/xtreemfs/test/foundation/checksums/ChecksumFactoryTest.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.foundation.checksums; + +import static org.junit.Assert.assertEquals; + +import java.nio.ByteBuffer; +import java.security.NoSuchAlgorithmException; +import java.util.LinkedList; +import java.util.Random; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.zip.Adler32; +import java.util.zip.Checksum; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.xtreemfs.foundation.checksums.ChecksumAlgorithm; +import org.xtreemfs.foundation.checksums.ChecksumFactory; +import org.xtreemfs.foundation.checksums.ChecksumProvider; +import org.xtreemfs.foundation.checksums.provider.JavaChecksumProvider; +import org.xtreemfs.foundation.logging.Logging; + +/** + * tests the checksum factory and some checksums + * + * 19.08.2008 + * + * @author clorenz + */ +public class ChecksumFactoryTest { + private ChecksumFactory factory; + private ByteBuffer data; + + @Before + public void setUp() throws Exception { + Logging.start(Logging.LEVEL_ERROR); + + this.factory = ChecksumFactory.getInstance(); + + ChecksumProvider provider = new JavaChecksumProvider(); + this.factory.addProvider(provider); + + this.data = ByteBuffer.wrap(generateRandomBytes(1024 * 128)); + } + + @After + public void tearDown() throws Exception { + } + + /** + * generates randomly filled byte-array + * + * @param length + * of the byte-array + */ + public static byte[] generateRandomBytes(int length) { + Random r = new Random(); + byte[] bytes = new byte[length]; + + r.nextBytes(bytes); + return bytes; + } + + /** + * tests the internal java checksum algorithms + * + * @throws Exception + */ + @Test + public void testJavaChecksumAlgorithm() throws Exception { + // compute checksum with xtreemfs ChecksumFactory + long xtreemfsValue = computeXtreemfsChecksum("Adler32", true); + + // compute checksum with java API + Checksum javaAlgorithm = new Adler32(); + javaAlgorithm.update(data.array(), 0, data.array().length); + long javaValue = javaAlgorithm.getValue(); + + // System.out.println(javaValue); + // System.out.println(xtreemfsValue); + + assertEquals(javaValue, xtreemfsValue); + } + + // /** + // * tests the internal java message digest algorithms + // * @throws Exception + // */ + // public void testJavaMessageDigestAlgorithm() throws Exception { + // // compute checksum with xtreemfs ChecksumFactory + // String xtreemfsValue = computeXtreemfsChecksum("MD5", true); + // + // // compute checksum with java API + // String javaValue = computeJavaMessageDigest("MD5"); + // + // // System.out.println("java: "+xtreemfsValue); + // // System.out.println("xtreemfs: "+javaValue.toString()); + // + // assertEquals(javaValue.toString(), xtreemfsValue); + // } + + /** + * @param algorithm + * @param returnAlgorithm + * @return + * @throws NoSuchAlgorithmException + */ + private long computeXtreemfsChecksum(String algorithm, boolean returnAlgorithm) throws NoSuchAlgorithmException { + // compute checksum with xtreemfs ChecksumFactory + ChecksumAlgorithm xtreemfsAlgorithm = factory.getAlgorithm(algorithm); + xtreemfsAlgorithm.update(data); + long xtreemfsValue = xtreemfsAlgorithm.getValue(); + if (returnAlgorithm) + this.factory.returnAlgorithm(xtreemfsAlgorithm); + return xtreemfsValue; + } + + private long computeJavaCheckSum(String algorithm) throws NoSuchAlgorithmException { + // compute checksum with java API + Adler32 adler = new Adler32(); + adler.update(data.array()); + return adler.getValue(); + } + + /** + * tests, if the internal buffer of the checksums is working correctly, if the checksum is used more than once + * + * @throws Exception + */ + @Test + public void testIfChecksumIsAlwaysTheSame() throws Exception { + ChecksumAlgorithm algorithm = factory.getAlgorithm("Adler32"); + algorithm.update(data); + long oldValue = algorithm.getValue(); + + for (int i = 0; i < 32; i++) { + algorithm.update(data); + long newValue = algorithm.getValue(); + + assertEquals(oldValue, newValue); + oldValue = newValue; + } + } + + /** + * tests, if the ChecksumFactory delivers only "thread-safe" instances (cache-pool) + * + * @throws Exception + */ + @Test + public void testThreadSafety() throws Exception { + final int THREADS = 8; + this.data = ByteBuffer.wrap(generateRandomBytes(1024 * 1024 * 32)); + + // compute correct checksum with java API + Long javaValue = computeJavaCheckSum("Adler32"); + + Callable computation = new Callable() { + @Override + public Long call() { + try { + // compute checksum with xtreemfs ChecksumFactory + long xtreemfsValue = computeXtreemfsChecksum("Adler32", true); + return xtreemfsValue; + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return 0l; + } catch (Exception e) { + e.printStackTrace(); + return 0l; + } + } + }; + LinkedList> results = useMultipleThreads(THREADS, computation); + + // compare correct java checksum with xtreemfs checksums + for (Future result : results) { + assertEquals(javaValue, result.get()); + } + } + + /** + * tests, if the ChecksumFactory cache-pool works correctly + * + * @throws Exception + */ + @Test + public void testChecksumFactoryCache() throws Exception { + // FIXME: use bigger values for more comprehensive testing, but this will slow down the test + final int THREADS = 8; + final int ROUNDS = 50; + this.data = ByteBuffer.wrap(generateRandomBytes(1024 * 1024)); + + // compute correct checksum with java API + Long javaValue = computeJavaCheckSum("Adler32"); + + Callable> computation = new Callable>() { + @Override + public LinkedList call() { + try { + LinkedList values = new LinkedList(); + boolean returning = false; + for (int i = 0; i < ROUNDS; i++) { + // compute checksum with xtreemfs ChecksumFactory + long xtreemfsValue = computeXtreemfsChecksum("Adler32", returning); + values.add(xtreemfsValue); + returning = !returning; + } + return values; + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return null; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + }; + LinkedList>> results = useMultipleThreads(THREADS, computation); + + // compare correct java checksum with xtreemfs checksums + for (Future> result : results) { + for (Long value : result.get()) { + assertEquals(javaValue, value); + } + } + } + + /** + * executes a given computation in a couple of threads and returns the results of the computations + * + * @param THREADS + * @param computation + * @return a list of futures, which contain the results of the computations + * @throws InterruptedException + */ + private LinkedList> useMultipleThreads(final int THREADS, Callable computation) + throws InterruptedException { + LinkedList> results = new LinkedList>(); + // compute xtreemfs checksums with multiple threads + ExecutorService executor = Executors.newFixedThreadPool(THREADS); + for (int i = 0; i < THREADS; i++) { + Future tmp = executor.submit(computation); + results.add(tmp); + } + executor.shutdown(); + executor.awaitTermination(60, TimeUnit.SECONDS); + return results; + } +} diff --git a/java/foundation/test/org/xtreemfs/test/foundation/checksums/StringChecksumAlgorithmTest.java b/java/foundation/test/org/xtreemfs/test/foundation/checksums/StringChecksumAlgorithmTest.java new file mode 100644 index 0000000..2c4b222 --- /dev/null +++ b/java/foundation/test/org/xtreemfs/test/foundation/checksums/StringChecksumAlgorithmTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2008-2010 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.foundation.checksums; + +import static org.junit.Assert.assertEquals; + +import java.nio.ByteBuffer; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.xtreemfs.foundation.checksums.StringChecksumAlgorithm; +import org.xtreemfs.foundation.checksums.algorithms.SDBM; +import org.xtreemfs.foundation.logging.Logging; + +/** + * some tests for the checksum algorithms, which are based on strings + * + * 02.09.2008 + * + * @author clorenz + */ +public class StringChecksumAlgorithmTest { + private ByteBuffer bufferData; + private String stringData; + + @Before + public void setUp() throws Exception { + Logging.start(Logging.LEVEL_ERROR); + + this.stringData = ""; + for (int i = 0; i < 1024; i++) { + this.stringData += "Test, "; + } + this.bufferData = ByteBuffer.wrap(stringData.getBytes()); + } + + @After + public void tearDown() throws Exception { + } + + /** + * tests, if the SDBM algorithm generates the same checksum with a String-input and ByteBuffer-input + * + * @throws Exception + */ + @Test + public void testSDBMStringBufferEquality() throws Exception { + // compute checksum with xtreemfs ChecksumFactory + StringChecksumAlgorithm algorithm = new SDBM(); + + // string + algorithm.digest(stringData); + long stringValue = algorithm.getValue(); + + // buffer + algorithm.update(bufferData); + long bufferValue = algorithm.getValue(); + + // System.out.println(stringValue); + // System.out.println(bufferValue); + + assertEquals(stringValue, bufferValue); + } +} diff --git a/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCClientServerTest.java b/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCClientServerTest.java new file mode 100644 index 0000000..6542df3 --- /dev/null +++ b/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCClientServerTest.java @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.foundation.pbrpc; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.junit.Test; +import org.xtreemfs.foundation.pbrpc.Schemes; +import java.net.InetSocketAddress; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.PingServiceClient; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; +import org.xtreemfs.foundation.pbrpc.server.RPCNIOSocketServer; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequestListener; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; +import org.xtreemfs.foundation.util.OutputUtils; + +import static org.junit.Assert.*; + +/** + * + * @author bjko + */ +public class PBRPCClientServerTest { + private final int TEST_PORT = 12999; + + private static final String[] schemes = new String[]{Schemes.SCHEME_PBRPC, Schemes.SCHEME_PBRPCS, Schemes.SCHEME_PBRPCG}; + + private static TimeSync ts = null; + + public PBRPCClientServerTest() { + } + + @BeforeClass + public static void setUpClass() throws Exception { + Logging.start(Logging.LEVEL_WARN, Logging.Category.all); + ts = TimeSync.initializeLocal(50); + } + + @AfterClass + public static void tearDownClass() throws Exception { + ts.close(); + } + + // TODO add test methods here. + // The methods must be annotated with annotation @Test. For example: + // + // @Test + // public void hello() {}\ + @Test + public void testRegularRPC() throws Exception { + ResponseCreator creator = new ResponseCreator() { + @Override + public void answer(RPCServerRequest rq, PingRequest pRq) throws Exception { + Ping.PingResponse.PingResult result = Ping.PingResponse.PingResult.newBuilder().setText(pRq.getText()).build(); + Ping.PingResponse resp = Ping.PingResponse.newBuilder().setResult(result).build(); + + rq.sendResponse(resp, null); + } + }; + + TestExecutor exec = new TestExecutor() { + + @Override + public void execTest(RPCNIOSocketClient client) throws Exception { + PingServiceClient psClient = new PingServiceClient(client,null); + + RPC.UserCredentials userCred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("tester").build(); + RPCResponse response = psClient.doPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred, "Hello World!", false, null); + assertEquals(response.get().getResult().getText(),"Hello World!"); + response.freeBuffers(); + + response = psClient.doPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred, "Murpel", false, null); + assertEquals(response.get().getResult().getText(),"Murpel"); + response.freeBuffers(); + } + }; + for (String scheme: schemes) + runTest(scheme, creator, exec); + + } + + + @Test + public void testErrorResponse() throws Exception { + ResponseCreator creator = new ResponseCreator() { + @Override + public void answer(RPCServerRequest rq, PingRequest pRq) throws Exception { + rq.sendError(RPC.ErrorType.ERRNO, RPC.POSIXErrno.POSIX_ERROR_EIO, "YaggYagga"); + } + }; + + TestExecutor exec = new TestExecutor() { + + @Override + public void execTest(RPCNIOSocketClient client) throws Exception { + PingServiceClient psClient = new PingServiceClient(client,null); + + RPC.UserCredentials userCred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("tester").build(); + RPCResponse response = psClient.doPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred, "Hello World!", false, null); + + try { + response.get(); + fail("expected error response"); + } catch (PBRPCException ex) { + assertEquals(ex.getErrorType(),RPC.ErrorType.ERRNO); + assertEquals(ex.getPOSIXErrno(),RPC.POSIXErrno.POSIX_ERROR_EIO); + } + response.freeBuffers(); + + + } + }; + for (String scheme: schemes) + runTest(scheme, creator, exec); + + } + + @Test + public void testInternalServerError() throws Exception { + ResponseCreator creator = new ResponseCreator() { + @Override + public void answer(RPCServerRequest rq, PingRequest pRq) throws Exception { + rq.sendRedirect("redirtome"); + } + }; + + TestExecutor exec = new TestExecutor() { + + @Override + public void execTest(RPCNIOSocketClient client) throws Exception { + PingServiceClient psClient = new PingServiceClient(client,null); + + RPC.UserCredentials userCred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("tester").build(); + RPCResponse response = psClient.doPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred, "Hello World!", false, null); + + try { + response.get(); + fail("expected error response"); + } catch (PBRPCException ex) { + assertEquals(ex.getErrorType(),RPC.ErrorType.REDIRECT); + assertEquals(ex.getRedirectToServerUUID(),"redirtome"); + } + response.freeBuffers(); + + + } + }; + for (String scheme: schemes) + runTest(scheme, creator, exec); + + } + + @Test + public void testDataPing() throws Exception { + ResponseCreator creator = new ResponseCreator() { + @Override + public void answer(RPCServerRequest rq, PingRequest pRq) throws Exception { + Ping.PingResponse.PingResult result = Ping.PingResponse.PingResult.newBuilder().setText(pRq.getText()).build(); + Ping.PingResponse resp = Ping.PingResponse.newBuilder().setResult(result).build(); + + ReusableBuffer data = null; + if (rq.getData() != null) { + data = rq.getData().createViewBuffer(); + data.limit(data.capacity()); + data.position(data.capacity()); + } + + rq.sendResponse(resp, data); + } + }; + + TestExecutor exec = new TestExecutor() { + + @Override + public void execTest(RPCNIOSocketClient client) throws Exception { + PingServiceClient psClient = new PingServiceClient(client,null); + byte[] arr = new byte[2065]; + for (int i= 0; i < arr.length; i++) + arr[i] = 'x'; + ReusableBuffer sendData = ReusableBuffer.wrap(arr); + // System.out.println("data: "+sendData); + + RPC.UserCredentials userCred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("tester").build(); + RPCResponse response = psClient.doPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred, "Hello World!", false, sendData); + assertEquals(response.get().getResult().getText(),"Hello World!"); + + ReusableBuffer recdata = response.getData(); + assertTrue(recdata.hasRemaining()); + while (recdata.hasRemaining()) { + assertEquals(recdata.get(),(byte)'x'); + } + response.freeBuffers(); + + } + }; + for (String scheme: schemes) + runTest(scheme, creator, exec); + + } + + @Test + public void testTimeout() throws Exception { + ResponseCreator creator = new ResponseCreator() { + @Override + public void answer(RPCServerRequest rq, PingRequest pRq) throws Exception { + //don't do anything + } + }; + + TestExecutor exec = new TestExecutor() { + + @Override + public void execTest(RPCNIOSocketClient client) throws Exception { + PingServiceClient psClient = new PingServiceClient(client,null); + + RPC.UserCredentials userCred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("tester").build(); + RPCResponse response = psClient.doPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred, "Hello World!", false, null); + + try { + response.get(); + fail("expected error response"); + } catch (IOException ex) { + } + response.freeBuffers(); + + + } + }; + for (String scheme: schemes) + runTest(scheme, creator, exec); + + } + + public void runTest(String pbrpcScheme, ResponseCreator creator, TestExecutor exec) throws Exception { + RPCNIOSocketClient client = null; + RPCNIOSocketServer server = null; + + // System.out.println("loading ssl context"); + + SSLOptions srvSSL = null; + SSLOptions clientSSL = null; + if (pbrpcScheme.equals(Schemes.SCHEME_PBRPCS) || pbrpcScheme.equals(Schemes.SCHEME_PBRPCG)) { + srvSSL = createSSLOptions("DIR.p12", "passphrase", SSLOptions.PKCS12_CONTAINER, + "trusted.jks", "passphrase", SSLOptions.JKS_CONTAINER, pbrpcScheme.equals(Schemes.SCHEME_PBRPCG), null); + + clientSSL= createSSLOptions("Client.p12", "passphrase", + SSLOptions.PKCS12_CONTAINER, "trusted.jks", "passphrase", SSLOptions.JKS_CONTAINER, pbrpcScheme.equals(Schemes.SCHEME_PBRPCG), null); + } + + // System.out.println("setup done"); + + try { + + server = getServer(creator,srvSSL); + + server.start(); + server.waitForStartup(); + + client = new RPCNIOSocketClient(clientSSL, 5000, 5*60*1000, "runTest"); + client.start(); + client.waitForStartup(); + + exec.execTest(client); + + } finally { + //clean up + if (client != null) { + client.shutdown(); + client.waitForShutdown(); + } + if (server != null) { + server.shutdown(); + server.waitForShutdown(); + } + } + } + + private RPCNIOSocketServer getServer(final ResponseCreator creator, SSLOptions sslOpt) throws IOException { + return new RPCNIOSocketServer(TEST_PORT, null, new RPCServerRequestListener() { + + @Override + public void receiveRecord(RPCServerRequest rq) { + // System.out.println("received request"); + try { + ReusableBufferInputStream is = new ReusableBufferInputStream(rq.getMessage()); + Ping.PingRequest pingRq = Ping.PingRequest.parseFrom(is); + + creator.answer(rq, pingRq); + } catch (Exception ex) { + ex.printStackTrace(); + rq.sendError(RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(RPC.ErrorType.GARBAGE_ARGS).setErrorMessage(ex.getMessage()).setDebugInfo(OutputUtils.stackTraceToString(ex)).build()); + fail(ex.toString()); + + } + } + }, sslOpt); + } + + private SSLOptions createSSLOptions(String keyStoreName, String ksPassphrase, + String ksContainerType, String trustStoreName, String tsPassphrase, String tsContainerType, boolean gridSSL, String sslProtocolString) + throws IOException { + + ClassLoader cl = this.getClass().getClassLoader(); + + InputStream ks = cl.getResourceAsStream(keyStoreName); + if (ks == null) { + // Assume the working directory is "java/servers". + String testCert = "../../tests/certs/" + keyStoreName; + if (new File(testCert).isFile()) { + ks = new FileInputStream(testCert); + } else { + // Assume the working directory is the root of the project. + ks = new FileInputStream("tests/certs/" + keyStoreName); + } + } + + InputStream ts = cl.getResourceAsStream(trustStoreName); + if (ts == null) { + // Assume the working directory is "java/servers". + String testCert = "../../tests/certs/" + trustStoreName; + if (new File(testCert).isFile()) { + ts = new FileInputStream(testCert); + } else { + // Assume the working directory is the root of the project. + ts = new FileInputStream("tests/certs/" + trustStoreName); + } + } + + return new SSLOptions(ks, ksPassphrase, ksContainerType, ts, tsPassphrase, tsContainerType, false, gridSSL, sslProtocolString, null); + } + + private static interface ResponseCreator { + public void answer(RPCServerRequest rq, PingRequest pRq) throws Exception; + } + + private static interface TestExecutor { + public void execTest(RPCNIOSocketClient client) throws Exception; + } + +} \ No newline at end of file diff --git a/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCDatagramPacketTest.java b/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCDatagramPacketTest.java new file mode 100644 index 0000000..5931d4a --- /dev/null +++ b/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCDatagramPacketTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.foundation.pbrpc; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.utils.PBRPCDatagramPacket; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import static org.junit.Assert.*; + +/** + * + * @author bjko + */ +public class PBRPCDatagramPacketTest { + + public PBRPCDatagramPacketTest() { + } + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + // TODO add test methods here. + // The methods must be annotated with annotation @Test. For example: + // + // @Test + // public void hello() {} + + @Test + public void testPacket() throws Exception { + + RPCHeader.RequestHeader rqHdr = RPCHeader.RequestHeader.newBuilder().setAuthData(RPCAuthentication.authNone).setUserCreds(RPCAuthentication.userService).setInterfaceId(1).setProcId(2).build(); + RPCHeader hdr = RPCHeader.newBuilder().setCallId(12345).setMessageType(MessageType.RPC_REQUEST).setRequestHeader(rqHdr).build(); + + PingRequest pRq = PingRequest.newBuilder().setText("YAGGA!").setSendError(false).build(); + + PBRPCDatagramPacket dp = new PBRPCDatagramPacket(hdr, pRq); + ReusableBuffer data = dp.assembleDatagramPacket(); + + dp = new PBRPCDatagramPacket(data, PingRequest.getDefaultInstance()); + + PingRequest response = (PingRequest)dp.getMessage(); + + assertEquals(dp.getHeader().getCallId(),12345); + assertEquals(dp.getHeader().getMessageType(),MessageType.RPC_REQUEST); + assertEquals(response.getText(),pRq.getText()); + } + +} \ No newline at end of file diff --git a/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCTest.java b/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCTest.java new file mode 100644 index 0000000..6fed7a1 --- /dev/null +++ b/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/PBRPCTest.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + + +package org.xtreemfs.test.foundation.pbrpc; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.TimeSync; +import java.io.IOException; +import java.net.InetSocketAddress; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequestListener; +import org.xtreemfs.foundation.pbrpc.server.RPCNIOSocketServer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.PingServiceClient; +import static org.junit.Assert.*; + +/** + * + * @author bjko + */ +public class PBRPCTest { + private final int TEST_PORT = 12999; + + private static TimeSync ts = null; + + public PBRPCTest() { + + } + + @BeforeClass + public static void setUpClass() throws Exception { + Logging.start(Logging.LEVEL_WARN, Logging.Category.all); + ts = TimeSync.initializeLocal(50); + } + + @AfterClass + public static void tearDownClass() throws Exception { + ts.close(); + } + + + @Test + public void testRPCClient() throws Exception { + RPCNIOSocketClient client = null; + RPCNIOSocketServer server = null; + + try { + + server = new RPCNIOSocketServer(TEST_PORT, null, new RPCServerRequestListener() { + + @Override + public void receiveRecord(RPCServerRequest rq) { + // System.out.println("received request"); + try { + ReusableBufferInputStream is = new ReusableBufferInputStream(rq.getMessage()); + Ping.PingRequest pingRq = Ping.PingRequest.parseFrom(is); + + Ping.PingResponse.PingResult result = Ping.PingResponse.PingResult.newBuilder().setText(pingRq.getText()).build(); + Ping.PingResponse resp = Ping.PingResponse.newBuilder().setResult(result).build(); + + rq.sendResponse(resp, null); + } catch (Exception ex) { + ex.printStackTrace(); + rq.sendError(RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(RPC.ErrorType.GARBAGE_ARGS).setErrorMessage(ex.getMessage()).setDebugInfo(OutputUtils.stackTraceToString(ex)).build()); + fail(ex.toString()); + + } + } + }, null); + + server.start(); + server.waitForStartup(); + + client = new RPCNIOSocketClient(null, 15000, 5*60*1000, "testRPCClient"); + client.start(); + client.waitForStartup(); + + PingServiceClient psClient = new PingServiceClient(client,null); + + RPC.UserCredentials userCred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("tester").build(); + RPCResponse response = psClient.doPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred, "Hello World!", false, null); + assertEquals(response.get().getResult().getText(),"Hello World!"); + + response = psClient.doPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred, "Murpel", false, null); + assertEquals(response.get().getResult().getText(),"Murpel"); + + } finally { + //clean up + if (client != null) { + client.shutdown(); + client.waitForShutdown(); + } + if (server != null) { + server.shutdown(); + server.waitForShutdown(); + } + } + + } + + + @Test + public void testRPCWithData() throws Exception { + RPCNIOSocketClient client = null; + RPCNIOSocketServer server = null; + + try { + + server = new RPCNIOSocketServer(TEST_PORT, null, new RPCServerRequestListener() { + + @Override + public void receiveRecord(RPCServerRequest rq) { + // System.out.println("received request"); + try { + ReusableBufferInputStream is = new ReusableBufferInputStream(rq.getMessage()); + Ping.PingRequest pingRq = Ping.PingRequest.parseFrom(is); + + Ping.PingResponse.PingResult result = Ping.PingResponse.PingResult.newBuilder().setText(pingRq.getText()).build(); + Ping.PingResponse resp = Ping.PingResponse.newBuilder().setResult(result).build(); + + ReusableBuffer data = null; + if (rq.getData() != null) { + data = rq.getData().createViewBuffer(); + data.limit(data.capacity()); + data.position(data.capacity()); + } + + rq.sendResponse(resp, data); + } catch (Exception ex) { + ex.printStackTrace(); + rq.sendError(RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(RPC.ErrorType.GARBAGE_ARGS).setErrorMessage(ex.getMessage()).setDebugInfo(OutputUtils.stackTraceToString(ex)).build()); + fail(ex.toString()); + + } + } + }, null); + + server.start(); + server.waitForStartup(); + + client = new RPCNIOSocketClient(null, 15000, 5*60*1000, "testRPCWithData"); + client.start(); + client.waitForStartup(); + + PingServiceClient psClient = new PingServiceClient(client,null); + + byte[] arr = new byte[2065]; + for (int i= 0; i < arr.length; i++) + arr[i] = 'x'; + ReusableBuffer sendData = ReusableBuffer.wrap(arr); + // System.out.println("data: "+sendData); + + RPC.UserCredentials userCred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("tester").build(); + RPCResponse response = psClient.doPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred, "Hello World!", false, sendData); + assertEquals(response.get().getResult().getText(),"Hello World!"); + + ReusableBuffer recdata = response.getData(); + assertTrue(recdata.hasRemaining()); + while (recdata.hasRemaining()) { + assertEquals(recdata.get(),(byte)'x'); + } + + response = psClient.doPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred, "Murpel", false, null); + assertEquals(response.get().getResult().getText(),"Murpel"); + + } finally { + //clean up + if (client != null) { + client.shutdown(); + client.waitForShutdown(); + } + if (server != null) { + server.shutdown(); + server.waitForShutdown(); + } + } + + } + + + @Test + public void testEmptyMessages() throws Exception { + RPCNIOSocketClient client = null; + RPCNIOSocketServer server = null; + + try { + + server = new RPCNIOSocketServer(TEST_PORT, null, new RPCServerRequestListener() { + + @Override + public void receiveRecord(RPCServerRequest rq) { + // System.out.println("received request"); + try { + assertNull(rq.getMessage()); + rq.sendResponse(null, null); + } catch (Exception ex) { + ex.printStackTrace(); + rq.sendError(RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(RPC.ErrorType.GARBAGE_ARGS).setErrorMessage(ex.getMessage()).setDebugInfo(OutputUtils.stackTraceToString(ex)).build()); + fail(ex.toString()); + + } + } + }, null); + + server.start(); + server.waitForStartup(); + + client = new RPCNIOSocketClient(null, 15000, 5*60*1000, "PBRPCTest::testEmptyMessages()"); + client.start(); + client.waitForStartup(); + + PingServiceClient psClient = new PingServiceClient(client,null); + + RPC.UserCredentials userCred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("tester").build(); + RPCResponse response = psClient.emptyPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred); + assertNull(response.get()); + + response = psClient.emptyPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred); + assertNull(response.get()); + + response = psClient.emptyPing(new InetSocketAddress("localhost", TEST_PORT), RPCAuthentication.authNone, userCred); + assertNull(response.get()); + + } finally { + //clean up + if (client != null) { + client.shutdown(); + client.waitForShutdown(); + } + if (server != null) { + server.shutdown(); + server.waitForShutdown(); + } + } + + } + +} \ No newline at end of file diff --git a/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/RPCNIOSocketServerTest.java b/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/RPCNIOSocketServerTest.java new file mode 100644 index 0000000..cd7e071 --- /dev/null +++ b/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/RPCNIOSocketServerTest.java @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.foundation.pbrpc; + +import java.io.IOException; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.nio.ByteBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; +import org.junit.After; +import org.junit.Before; +import org.xtreemfs.foundation.pbrpc.server.RPCNIOSocketServer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequestListener; +import org.xtreemfs.foundation.pbrpc.utils.RecordMarker; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferOutputStream; +import static org.junit.Assert.*; + +/** + * + * @author bjko + */ +public class RPCNIOSocketServerTest { + + private RPCNIOSocketServer server; + + public RPCNIOSocketServerTest() { + Logging.start(Logging.LEVEL_WARN, Logging.Category.all); + } + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + // TODO add test methods here. + // The methods must be annotated with annotation @Test. For example: + // + // @Test + // public void hello() {} + + @Test + public void testSerialization() throws Exception { + final int CALLID = 5464566; + + RPC.Auth auth = RPC.Auth.newBuilder().setAuthType(RPC.AuthType.AUTH_NONE).build(); + RPC.UserCredentials ucred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("user").build(); + RPC.RPCHeader.RequestHeader rqHdr = RPC.RPCHeader.RequestHeader.newBuilder().setAuthData(auth).setUserCreds(ucred).setProcId(2).setInterfaceId(2).build(); + RPC.RPCHeader header = RPC.RPCHeader.newBuilder().setCallId(CALLID).setMessageType(RPC.MessageType.RPC_REQUEST).setRequestHeader(rqHdr).build(); + + ReusableBufferOutputStream ois = new ReusableBufferOutputStream(ReusableBufferOutputStream.BUFF_SIZE); + header.writeTo(ois); + ois.flip(); + + byte[] data = new byte[ois.getBuffers()[0].remaining()]; + ois.getBuffers()[0].get(data); + + ReusableBufferInputStream is = new ReusableBufferInputStream(ReusableBuffer.wrap(data)); + + RPC.RPCHeader deser = RPC.RPCHeader.parseFrom(is); + + } + + @Test + public void testSimpleRPC() throws Exception { + + final int CALLID = 5464566; + final int TEST_PORT = 9991; + final String USERID = "yaggaYagga"; + + server = new RPCNIOSocketServer(TEST_PORT, null, new RPCServerRequestListener() { + + @Override + public void receiveRecord(RPCServerRequest rq) { + // System.out.println("received request"); + try { + assertEquals(CALLID,rq.getHeader().getCallId()); + assertEquals(RPC.MessageType.RPC_REQUEST, rq.getHeader().getMessageType()); + + //send a dummy message + RPC.UserCredentials msg = RPC.UserCredentials.newBuilder().setUsername(USERID).build(); + + ReusableBuffer data = BufferPool.allocate(2); + data.put((byte)15); + data.put((byte)20); + + rq.sendResponse(msg, data); + } catch (Exception ex) { + ex.printStackTrace(); + rq.sendError(RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(RPC.ErrorType.GARBAGE_ARGS).setErrorMessage(ex.getMessage()).setDebugInfo(OutputUtils.stackTraceToString(ex)).build()); + fail(ex.toString()); + + } + } + }, null); + + server.start(); + server.waitForStartup(); + + Socket sock = new Socket("localhost", TEST_PORT); + OutputStream out = sock.getOutputStream(); + InputStream in = sock.getInputStream(); + + RPC.Auth auth = RPC.Auth.newBuilder().setAuthType(RPC.AuthType.AUTH_NONE).build(); + RPC.UserCredentials ucred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("user").build(); + RPC.RPCHeader.RequestHeader rqHdr = RPC.RPCHeader.RequestHeader.newBuilder().setAuthData(auth).setUserCreds(ucred).setProcId(2).setInterfaceId(2).build(); + RPC.RPCHeader header = RPC.RPCHeader.newBuilder().setCallId(CALLID).setMessageType(RPC.MessageType.RPC_REQUEST).setRequestHeader(rqHdr).build(); + + ReusableBufferOutputStream ois = new ReusableBufferOutputStream(ReusableBufferOutputStream.BUFF_SIZE); + header.writeTo(ois); + int hdrLen = ois.length(); + + ByteBuffer recordMarker = ByteBuffer.allocate(RecordMarker.HDR_SIZE); + recordMarker.putInt(hdrLen); + recordMarker.putInt(0); + recordMarker.putInt(0); + recordMarker.flip(); + + ois.flip(); + + out.write(recordMarker.array()); + byte[] data = new byte[ois.getBuffers()[0].remaining()]; + ois.getBuffers()[0].get(data); + out.write(data); + + byte[] markerIn = new byte[RecordMarker.HDR_SIZE]; + in.read(markerIn); + ReusableBuffer marker = ReusableBuffer.wrap(markerIn); + + hdrLen = marker.getInt(); + int msgLen = marker.getInt(); + int dataLen = marker.getInt(); + + // System.out.println("header: "+hdrLen+"/"+msgLen+"/"+dataLen); + + byte[] hdrIn = new byte[hdrLen]; + byte[] msgIn = new byte[msgLen]; + byte[] dataIn = new byte[dataLen]; + + in.read(hdrIn); + in.read(msgIn); + in.read(dataIn); + + // System.out.println("read data"); + + RPC.RPCHeader respHdr = RPC.RPCHeader.parseFrom(hdrIn); + + RPC.UserCredentials uc = RPC.UserCredentials.parseFrom(msgIn); + + assertEquals(RPC.MessageType.RPC_RESPONSE_SUCCESS,respHdr.getMessageType()); + assertEquals(header.getCallId(),respHdr.getCallId()); + + assertEquals(USERID,uc.getUsername()); + + assertEquals(15,dataIn[0]); + assertEquals(20,dataIn[1]); + + sock.close(); + server.shutdown(); + server.waitForShutdown(); + } + + @Test + public void testRPCWithoutMessage() throws Exception { + + final int CALLID = 5464566; + final int TEST_PORT = 9991; + final String USERID = "yaggaYagga"; + + server = new RPCNIOSocketServer(TEST_PORT, null, new RPCServerRequestListener() { + + @Override + public void receiveRecord(RPCServerRequest rq) { + // System.out.println("received request"); + try { + assertNotNull(rq.getData()); + assertNull(rq.getMessage()); + assertEquals(CALLID,rq.getHeader().getCallId()); + assertEquals(RPC.MessageType.RPC_REQUEST, rq.getHeader().getMessageType()); + + //send a dummy message + RPC.UserCredentials msg = RPC.UserCredentials.newBuilder().setUsername(USERID).build(); + + ReusableBuffer data = BufferPool.allocate(2); + data.put((byte)15); + data.put((byte)20); + + rq.sendResponse(msg, data); + } catch (Exception ex) { + ex.printStackTrace(); + rq.sendError(RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(RPC.ErrorType.GARBAGE_ARGS).setErrorMessage(ex.getMessage()).setDebugInfo(OutputUtils.stackTraceToString(ex)).build()); + fail(ex.toString()); + + } + } + }, null); + + server.start(); + server.waitForStartup(); + + Socket sock = new Socket("localhost", TEST_PORT); + OutputStream out = sock.getOutputStream(); + InputStream in = sock.getInputStream(); + + RPC.Auth auth = RPC.Auth.newBuilder().setAuthType(RPC.AuthType.AUTH_NONE).build(); + RPC.UserCredentials ucred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("user").build(); + RPC.RPCHeader.RequestHeader rqHdr = RPC.RPCHeader.RequestHeader.newBuilder().setAuthData(auth).setUserCreds(ucred).setProcId(2).setInterfaceId(2).build(); + RPC.RPCHeader header = RPC.RPCHeader.newBuilder().setCallId(CALLID).setMessageType(RPC.MessageType.RPC_REQUEST).setRequestHeader(rqHdr).build(); + + ReusableBufferOutputStream ois = new ReusableBufferOutputStream(ReusableBufferOutputStream.BUFF_SIZE); + header.writeTo(ois); + int hdrLen = ois.length(); + + ByteBuffer recordMarker = ByteBuffer.allocate(RecordMarker.HDR_SIZE); + recordMarker.putInt(hdrLen); + recordMarker.putInt(0); + recordMarker.putInt(16); + recordMarker.flip(); + + ois.flip(); + + out.write(recordMarker.array()); + byte[] data = new byte[ois.getBuffers()[0].remaining()]; + ois.getBuffers()[0].get(data); + out.write(data); + + for (int i = 0; i < 16; i++) { + out.write('a'); + } + + byte[] markerIn = new byte[RecordMarker.HDR_SIZE]; + in.read(markerIn); + ReusableBuffer marker = ReusableBuffer.wrap(markerIn); + + hdrLen = marker.getInt(); + int msgLen = marker.getInt(); + int dataLen = marker.getInt(); + + // System.out.println("header: "+hdrLen+"/"+msgLen+"/"+dataLen); + + byte[] hdrIn = new byte[hdrLen]; + byte[] msgIn = new byte[msgLen]; + byte[] dataIn = new byte[dataLen]; + + in.read(hdrIn); + in.read(msgIn); + in.read(dataIn); + + // System.out.println("read data"); + + RPC.RPCHeader respHdr = RPC.RPCHeader.parseFrom(hdrIn); + + RPC.UserCredentials uc = RPC.UserCredentials.parseFrom(msgIn); + + assertEquals(RPC.MessageType.RPC_RESPONSE_SUCCESS,respHdr.getMessageType()); + assertEquals(header.getCallId(),respHdr.getCallId()); + + assertEquals(USERID,uc.getUsername()); + + assertEquals(15,dataIn[0]); + assertEquals(20,dataIn[1]); + + sock.close(); + server.shutdown(); + server.waitForShutdown(); + } + + @Test + public void testErrorResponse() throws Exception { + + final int CALLID = 5464566; + final int TEST_PORT = 9991; + final String USERID = "yaggaYagga"; + + server = new RPCNIOSocketServer(TEST_PORT, null, new RPCServerRequestListener() { + + @Override + public void receiveRecord(RPCServerRequest rq) { + // System.out.println("received request"); + try { + assertEquals(CALLID,rq.getHeader().getCallId()); + assertEquals(RPC.MessageType.RPC_REQUEST, rq.getHeader().getMessageType()); + + rq.sendError(RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(RPC.ErrorType.AUTH_FAILED).setErrorMessage("dummy error").setDebugInfo("no info here").build()); + } catch (Exception ex) { + ex.printStackTrace(); + rq.sendError(RPC.RPCHeader.ErrorResponse.newBuilder().setErrorType(RPC.ErrorType.GARBAGE_ARGS).setErrorMessage(ex.getMessage()).setDebugInfo(OutputUtils.stackTraceToString(ex)).build()); + rq.freeBuffers(); + fail(ex.toString()); + } + } + }, null); + + server.start(); + server.waitForStartup(); + + Socket sock = new Socket("localhost", TEST_PORT); + OutputStream out = sock.getOutputStream(); + InputStream in = sock.getInputStream(); + + RPC.Auth auth = RPC.Auth.newBuilder().setAuthType(RPC.AuthType.AUTH_NONE).build(); + RPC.UserCredentials ucred = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("user").build(); + RPC.RPCHeader.RequestHeader rqHdr = RPC.RPCHeader.RequestHeader.newBuilder().setAuthData(auth).setUserCreds(ucred).setProcId(2).setInterfaceId(2).build(); + RPC.RPCHeader header = RPC.RPCHeader.newBuilder().setCallId(CALLID).setMessageType(RPC.MessageType.RPC_REQUEST).setRequestHeader(rqHdr).build(); + + ReusableBufferOutputStream ois = new ReusableBufferOutputStream(ReusableBufferOutputStream.BUFF_SIZE); + header.writeTo(ois); + int hdrLen = ois.length(); + + ByteBuffer recordMarker = ByteBuffer.allocate(RecordMarker.HDR_SIZE); + recordMarker.putInt(hdrLen); + recordMarker.putInt(0); + recordMarker.putInt(0); + recordMarker.flip(); + + ois.flip(); + + out.write(recordMarker.array()); + byte[] data = new byte[ois.getBuffers()[0].remaining()]; + ois.getBuffers()[0].get(data); + out.write(data); + + byte[] markerIn = new byte[RecordMarker.HDR_SIZE]; + in.read(markerIn); + ReusableBuffer marker = ReusableBuffer.wrap(markerIn); + + hdrLen = marker.getInt(); + int msgLen = marker.getInt(); + int dataLen = marker.getInt(); + + assertEquals(0,msgLen); + assertEquals(0,dataLen); + + // System.out.println("header: "+hdrLen+"/"+msgLen+"/"+dataLen); + + byte[] hdrIn = new byte[hdrLen]; + + in.read(hdrIn); + + RPC.RPCHeader respHdr = RPC.RPCHeader.parseFrom(hdrIn); + + assertEquals(RPC.MessageType.RPC_RESPONSE_ERROR,respHdr.getMessageType()); + assertEquals(header.getCallId(),respHdr.getCallId()); + assertEquals(RPC.ErrorType.AUTH_FAILED,respHdr.getErrorResponse().getErrorType()); + + sock.close(); + server.shutdown(); + server.waitForShutdown(); + } + +} \ No newline at end of file diff --git a/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/RPCUDPSocketServerTest.java b/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/RPCUDPSocketServerTest.java new file mode 100644 index 0000000..58d3d4a --- /dev/null +++ b/java/foundation/test/org/xtreemfs/test/foundation/pbrpc/RPCUDPSocketServerTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.foundation.pbrpc; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import java.net.InetSocketAddress; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.pbrpc.server.RPCUDPSocketServer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.Ping.PingRequest; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequestListener; +import static org.junit.Assert.*; + +/** + * + * @author bjko + */ +public class RPCUDPSocketServerTest { + + RPCUDPSocketServer server1, server2; + + final static int PORT_1 = 33333; + final static int PORT_2 = 33334; + + public RPCUDPSocketServerTest() { + Logging.start(Logging.LEVEL_WARN, Logging.Category.all); + } + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + // TODO add test methods here. + // The methods must be annotated with annotation @Test. For example: + // + // @Test + // public void hello() {} + + @Test + public void testUDP() throws Exception { + server1 = new RPCUDPSocketServer(PORT_1, new RPCServerRequestListener() { + + @Override + public void receiveRecord(RPCServerRequest rq) { + // System.out.println("srv1: "+rq); + } + }); + + server2 = new RPCUDPSocketServer(PORT_2, new RPCServerRequestListener() { + + @Override + public void receiveRecord(RPCServerRequest rq) { + // System.out.println("srv2: "+rq); + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, "yagga"); + } + }); + + server1.start(); + server2.start(); + + server1.waitForStartup(); + server2.waitForStartup(); + + RPCHeader.RequestHeader rqHdr = RPCHeader.RequestHeader.newBuilder().setAuthData(RPCAuthentication.authNone).setUserCreds(RPCAuthentication.userService).setInterfaceId(1).setProcId(5).build(); + RPCHeader hdr = RPCHeader.newBuilder().setCallId(555).setMessageType(MessageType.RPC_REQUEST).setRequestHeader(rqHdr).build(); + PingRequest pRq = PingRequest.newBuilder().setSendError(false).setText("yagga").build(); + server1.sendRequest(hdr, pRq, new InetSocketAddress("localhost",PORT_2)); + + Thread.sleep(100); + + server1.shutdown(); + server2.shutdown(); + + server1.waitForShutdown(); + server2.waitForShutdown(); + + } + +} \ No newline at end of file diff --git a/java/foundation/test/org/xtreemfs/test/foundation/util/OutputUtilsTest.java b/java/foundation/test/org/xtreemfs/test/foundation/util/OutputUtilsTest.java new file mode 100644 index 0000000..05985ef --- /dev/null +++ b/java/foundation/test/org/xtreemfs/test/foundation/util/OutputUtilsTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + + +package org.xtreemfs.test.foundation.util; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.xtreemfs.foundation.util.OutputUtils; + +public class OutputUtilsTest { + + @Test + public void testLongHexEncoding() throws Exception { + + final long[] values = { 805306368000L, Integer.MIN_VALUE, Integer.MAX_VALUE, Long.MIN_VALUE, + Long.MAX_VALUE, 1, 0, -1 }; + + for (long value : values) { + StringBuffer sb = new StringBuffer(); + OutputUtils.writeHexLong(sb, value); + + assertEquals(value, OutputUtils.readHexLong(sb.toString(), 0)); + } + } + + @Test + public void testReadWriteHex() { + final int objno = 129; + final int objver = 459435; + final int trepo = 1; + final long checksum = 843349439598l; + + final StringBuffer sb = new StringBuffer(Integer.SIZE/8*3+2*Long.SIZE/8); + OutputUtils.writeHexInt(sb,objno); + OutputUtils.writeHexInt(sb,objver); + OutputUtils.writeHexInt(sb,trepo); + OutputUtils.writeHexInt(sb,(int) (checksum >> 32)); + OutputUtils.writeHexInt(sb,(int) (checksum & 0xFFFFFFFF)); + OutputUtils.writeHexLong(sb, checksum); + final String result = sb.toString(); + // System.out.println("result: "+result); + + int tmp = OutputUtils.readHexInt(result, 0); + assertEquals(objno,tmp); + tmp = OutputUtils.readHexInt(result, 8); + assertEquals(objver,tmp); + tmp = OutputUtils.readHexInt(result, 16); + assertEquals(trepo,tmp); + tmp = OutputUtils.readHexInt(result, 24); + long tmp2 = ((long)tmp)<< 32; + tmp = OutputUtils.readHexInt(result, 32); + tmp2 += tmp; + assertEquals(checksum,tmp2); + tmp2 = OutputUtils.readHexLong(result, 40); + assertEquals(checksum,tmp2); + } + +} diff --git a/java/foundation/test/org/xtreemfs/test/foundation/util/PBRPCServiceURLTest.java b/java/foundation/test/org/xtreemfs/test/foundation/util/PBRPCServiceURLTest.java new file mode 100644 index 0000000..632e333 --- /dev/null +++ b/java/foundation/test/org/xtreemfs/test/foundation/util/PBRPCServiceURLTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, Felix Langner, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + + +package org.xtreemfs.test.foundation.util; + +import org.junit.*; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.util.PBRPCServiceURL; + +import static org.junit.Assert.assertEquals; + +/** + * + * @author bjko + */ +public class PBRPCServiceURLTest { + + public PBRPCServiceURLTest() { + } + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + /** + * Test of getProtocol method, of class ONCRPCServiceURL. + */ + @Test + public void testURLParse() throws Exception { + String host = "yagga"; + int port = 1254; + PBRPCServiceURL u = new PBRPCServiceURL("pbrpcg://"+host+":"+port+"/", + Schemes.SCHEME_PBRPC,12345); + assertEquals(host, u.getHost()); + assertEquals(port, u.getPort()); + } + +} \ No newline at end of file diff --git a/java/init_eclipse_projects_linux.sh b/java/init_eclipse_projects_linux.sh new file mode 100755 index 0000000..4b8cd54 --- /dev/null +++ b/java/init_eclipse_projects_linux.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +for p in flease foundation pbrpcgen servers +do + for f in .classpath .project + do + dest="${p}/${f}" + + if [ ! -f "$dest" ] + then + source="${p}/eclipse-project/${f}" + + if [ -f "$source" ] + then + cp "$source" "$dest" + else + echo "$source not found and therefore not copied." + fi + fi + done +done + +echo Finished. +echo Press any key to continue... +read diff --git a/java/init_eclipse_projects_windows.bat b/java/init_eclipse_projects_windows.bat new file mode 100644 index 0000000..fae1741 --- /dev/null +++ b/java/init_eclipse_projects_windows.bat @@ -0,0 +1,22 @@ +@echo off + +Setlocal EnableDelayedExpansion + +FOR %%p IN (flease foundation pbrpcgen servers) DO ( + FOR %%f IN (.classpath .project) DO ( + set dest=%CD%\%%p\%%f + + IF not exist !dest! ( + set source=%cd%\%%p\eclipse-project\%%f + + if exist !source! ( + copy "!source!" "!dest!" + ) else ( + echo !source! not found and therefore not copied. + ) + ) + ) +) + +echo Finished. +pause diff --git a/java/lib/BabuDB.jar b/java/lib/BabuDB.jar new file mode 100644 index 0000000000000000000000000000000000000000..7187450b174b945a36f4b6c86eb2422dbd574ccf GIT binary patch literal 701320 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

kxVWV7|nXwJfy+k>VBg z1xvMslMho5--DA5gHe`Y2XH-V;yDf0+ipqgCCl&7j28eap9L1zl|o6!ea)t z0qZ~oK9cPcO&$fOLOY9iH_3571(s;WC(?|08xqXx%y7tO@u;`~LmPg6aeyuoUiQ0S zH=U`zch5-nNLPw}@i8~ymN}#JQet=Va`vpAgFMY7ZRKUYm$1_Uc%0PEP z0qkO`F`bgUu^M~)oM~4ei_*CybUH$fRz`v`^!YPrO}0es3SW)EcHV%#u)Go53p`%h zJNSw_%6Mt4jRe>VIoJxUbd!Hpd=xMq3;NF?&99Ewr7dHRwlz8xJN)%U7h}c6p))W& zjmPE0ko@ObnxdVFke%4N+Bi*F&8N%x-WAH$9nscjk30LwQQd76;8LtVIz-pR|7<1a zjf`w`+VqnkkvnxuiHyiVx1hEQUD=FM(Twt#+b8>YBk$guuy#uADI}QjWxO9Tnfv>@ zK6!2bSL*VZs4prh1FeEu!v%J_hEhDUw2gK!bn%a*%Ozo=c%e{JM!kDF z#hyB_=%6p^H9VSO@%FR$?HI%{5c?<)%Y{i78fX%KV3`P-D9i#(N&BX;5-Ol#SB6b= z6*=6PL_4RXkk2lZlbF4BmGrqs`MtqNnSzV3F+2E;c6UltPbYOJkpA(y_xUR zq;q!K%TssvClq7gBH=66Azgdb$Ki4YhqY~GMaqVi7K?1i8e3=I+A6F)TV(hpR&r~@ zw*@@w#@z00ns>~U=1ie`7CfJ#?&(IL-D2b0fq94U3@EVF=eWv*RTOd5D6|5@j-`eS z*e^C_!_#(BafXm0;Wxqq6zbG&^k|n`pXJ{sOW=XDzo+dN++;*Bk47~mU&MZmP){00 z7Gn1A$HE_g?%(hAXDW!r1M9Da*p+0&qrxUPa7zc+Ri7L{nM)>Bgl}pt*@|?O8+O-Q zDqg_7E%<_rTFPl3`miF8$(u{>kSpsf^yZ`j#}hhBvf)m-fT{b(O_klISSL&w!1)hl>>?JltEEj%9!4H%X|5)tMQm}H zhJ^8mNyJ^^{u_tyn`}60b`rU9N$%E}Txk91^l;_lL87XXwd?3r| z#eeX*f?4;Rt(2y~Dm99Dc-q}eIHw9VxIt^~Y__9;Wq0=h5W#RJhd;Ok-z-(GYo}A8 zJE=mGvKB{^at0{XrSFJ3!j7+_tfgz@nSb{3lyPwqa=FEwIagl#J*zEJF1|7UZHats z-wXbidv*63lyguxF}?_>JKFPCGHqtMYsyiQJmJmoo&_lEUp6=Sb14eT$k9X1ls^uw+!+IV~;fqr~ z9i*&=jXe0*?{e&+I-dKD13u;~&yn0nWmXhZZgbKEtFGYk`c!FvA^6;e@_}WNI}- z7}jA{sQI(GKgsLAWx$(AfG;=1$n8alVFrdrX=2?gyA1vOx9Geb95YIO95Q;AWTvv-tIo$F0PtSYpd z%@160u%!TRjCyN4aFk&xUg&#Gh;#oDbeM%Oe(`iP`SPHv>P%8v-Df!kStR~mTKsW| znMf*Gr0z z)&L@pjBgrjO^DAUV{J;9_ZEY`D1M2}8a_=Ktz#M)bG|afShwg_3OLoSZ+OcUeH#jT zO@Uv&P(Q5O7aF5mwpEiQ@O`Ch-f%W=hEbPS8Yj89;U-1G>wMI(-Lyl;FADf(1~0Sl zbImnY==GwLUzj6H;gz`2*xg3=#PCZp6xuz{=!B3Mas|yh?BD`7CH2#6xv$VKIKL}cj_cPe z!C&}{!9pHJ{Rf{l{}G?X|4n>$b}@4KZ|JQ4_fl|v8EV^pIlJ8tUl>ABMWxwrK_!=> zJaG8vJ@9(DW-|Go^QQTKH^yAV&G526c)ED9HVTO7F1ANR>f0&)gCwtkXoty)zJ#ih_WOgE?PR+#< zJG>+KNVukRt9^K!Ah67=%55JKErT}O#0l*p{~^fgFtNoDudr2tTzFk#7k*SAzwE&_ zJjQCD!Co!*bRd)=o5xiZ4RbI(b5eQ)XPlO`6=|646OwJj4NH!H&Tr;rkxj-i4Z722 z_c+~@L>)m#S`97^Iq&IEBXiEcnJ^0H6pwoYUu@4v4lm2U+u3@Byz;EEX=6g-Lk}xn zxKhm5gFUcqR4 zxb8#u>@q87aK?HNz+z%q`z>nBu!wAdwNvRv4J4C{Kgj}1p#W0CV6SMT``DEch!kQW z9FQ=B;8)JZ=PL;1r;7OBCC$5{R6Y&Mzno~rD)#@ykj-WcpW+-2fAe7bb5&~DC7Y}Y zrJWS%l($Cf!%|}$=I(}w}WXype~L$80vSQJp_c962h%Zcd>O}OKDe{ zGqKP&!oXSf&U|t0;F{(S{P^6vKm+d2)&vdW?8=pO4;a4JJ$pGD=S? zVWZhOKEYuhhiWgo%#+vB0e&{Jg6!mI)$HCJWF*C8=Vj|AWem($zI@tX;RA{gxj}?> zgN?9bvJji8^BbfVb)%(-IZ>cdJ6i!Fgl0T~>p&jVUHWk`qM*2sl^4aHmbTrp9ET zLGCJCkd`eL(_)HK3|j(T4`!fN#!z9g;b7uaTc{1rvo{`$PiuI(vg7h+nE|fNllpjg zkIUolaA!?I{dj%-HVnkKOQr%oAdRa+v^`ec`O994vI_X`Cd&nuN@>qWGc#X$6%IAr zc^(Xe5Qs;%S?%nZ>$;xri6w`+!_M%-Wh#R+A@m5hi(9;OZao zE;Yz3l^3Zc+EGNqoma2A+Z<(O&LaR?#yzj&9Z6@ZC!Y#>{8ioBKduG&qtT(*;GtbO z%#vuxPROru+dl-e`o2&0y?0G_S17kNEt>T7%~su4ZKoW+k`32_D5 zmopK*{(5pVwFAyscI#;~V~wlp-_R#II&_jSCaa6GiVdyI5|lOYKZdo-v1hu+ux5I+ zal_jHVD=^g4{}U3dGJ~lZ5-Oy|PSi+UC)O_TF6&tzG`Pc}kB zEGrZ@T+6t`26268VHd*Z^{NHa=1-i$FFQkB8iUx9wDI*azjvPqI|Zf{6sN>@5URf$ zW47SwrGx3^&e8xjPZGNxGL(_dvoy~9F$Ol z*s{EmOEKQrpQ|EOu7eMj1MTfnmqc4WgHIm&zXRGfMY_I7U&lN}n|b$TgRZulbpL3cXj*Hwy`w|iChPj9 zO2f5uw#NVX4V2ku>lLqf+Pr@ewu4Lk3hacWA1oO2W#~*-J<;E(e#>% z9`f=g73D4PLZK_$9M=ffB!5cN@GZ7-#H`jsr$sosdge&U7|1D}LAXgMk5U|_wF~c< z%qfvUaTwYh>alA~V)iIcX|5gOlS}~##T#VO0^Cd8A05vnh~OM8e??bM4P}O^@fYIl zJ1I)!?fueqg!vKo9Q*Y%H7(})hNbvXN5w2TA5b)+X~$BBIzw88O1FzMLzEmwUn^XJ zx)g>x@HQ|NiWF+V%6!K-GVXLX?(&kyIXs?WzK_`?_6Zmpf$X}ac{=L`{R>XxRh94O zAV5IY{&8;N->tmM>W$;jA5^BYY zMmqUFytsX3V&%N4F}sxEK7&0&W$NU{RUod~)6<-pevBM%zH2$8mFKSg>GLXc<;Um8 znLP*#V?LH)3xFr;y}F7-w0?6^siyM4eX+yxZney! z*`}N>56hJEJ>&QI9eFd(%a^31yi;+e0S8}#rX!r9`)Nof(M1_|tYzl@UdXzZbtjIN zlQ3vxk1@tw=p|=bfN?6-m54!x0kf>5L5p`>ySH3RJ-momKl3`5Q&Q%tA(n29HE}ew zG7O$5b2te+rT{vw1Wu_DBc7Zg1Po9F(2q)^Ur(Ijs?S8V=(1Af0NPGWu9Fdrfd40kmTDjNq4Z^wQ z+PO6(I=R!;gRsFH?cP~Lg~IXe>_1YpxB2Zyf71W@xtR=Lc=FbeWA89yrIp7ZyovB3 z$MCAZvJK@D9%Mw7fO$fF#sNsDDg#o_m-;%3D9HgBlZx#RFbR2Eonlf#opScxEr$$EL5Hw{N<_s<#GIF2FB7F^SFiO4jk|= zMZX0P0npC0glnJ%O;iR=0m-%{)utx?gur(~p!eu8?NSDr-q6hw=M$-q5iTZx^_%YH zw$&@t26rmLup2S*S_^>=3J2R=fV>SOhR2(i#l=a_s?d*%41y_-PWJdu>T@^Z8rEF~ zz7vh^0y6BZ$xfltz~FCcyQlr6jSnk+%>7-={k{t)=7L+v^S^jt-&8dO$bv@;uiR?h zp`Lg&JqmZ1dyh)Gry#GX2(pRa!2<;D_fnE2R(C{m(4F*@xx&ZKzr&C_#^Ky4_sGmX z#ov2HPU=t4S|3`}*phVxHZs0YUo=>Q-j*of4{|IknsS@7wN{OqR4Wl*CooIR*=AmG zKYu!27FNs0XVn>*q>?!?Z5zpYg~mBexlzqG^3L*mCTX=k zdEul)qQ|(4*z?lhZ=EdLZOfFQp|-3^+=JHPp4OOtuNo5g_;8ZG7ysUfR3w$o3g3WG*nnP`WB5}M>|hqvI9EgaVxp-*wTD@* z=tPhijRGy_yM}7VmSReG4<>;Fos?ExGMvGO(kZ_=`P`^!88pA?VFt^Q_uHD+53lU^ zo1^M((Bq*e(0ORA>3i9CVD6ZcT_LhTa&pAUK}#M^T^DiTzOc9WqVW(vn%GgDlGCo09dYs=6f;G+aQ1V^JJO)FO0PcaVXqeD%6tX{%1m@W83@y{`8 zk-R9$En5lERw|qlf*r+{oMg(Cja;cH4ruxWmP902zu+vqEmu=tu1 zN+WIHd6*@&4AbaUt6oV=#$&|2>N9r^C5ttpapBZ>XacsOC)vR=U8#+AdK-~hS)G4? zP*8r@CHm*Z%Z+&=cbYac%f&?_N0amxxR3^szJh(%7o39v8?zT*6vOMc6n7l&$Ay|< zFa`-MP^ZdHS!nR1XRt3zrnM>#!1}7_Ttfn_F8vmegSF)1!n}`}cEL%cf^}E`FXfN0 zczaurm=KtX>X5wuQ!?@4r(|k?94R|`y5x5$_BaO)|CC={^~y0Z@m=HvylCUJXybTu z^WPWTvkG3d$nvGdm5Nyyy!TJ5Xjr;AbE1ESJ zH5!SI8h}UwathRoaiPf|_{lX4MI7EDPVLk{Gv^+EV)C-T!0X+h(K9pbN0Q6EY5}mX z6Jw1cFDl^B)HpVtYZmQ@av!nlk~BVlK;9!6O^{xi#?$k%Nbsw$5M!H=VXG>o;>#{; z@sLya>M~fP{K?M`zYPvroQ*6yVCxbGG9o1dLJ;u`kv;pMl{DrNbNML1DY967SL^pl z0nGo)=ZH}sPc((2vtX zxh<>)(WM!zhYb-<9J?+Fl}DS8wCpvpDef+sNH@>$Lzwd+m3uP_1sw}a%jWErZHo)| z3qtU-+n&|Q+Pp(wxQM9J%BzVCcLV~aLw-BU7=UGXSB?EeR!4p;_$4|dI zY>;YyBR#c2byb&y#M>SE^Y^mNaFtgIZzzr$l?gUHeV|HCvc`rveM(OpY-?M zi(&l`g8U|ey(TY#*0wJ%JDP=hOV! zkW_jjGm-$JPaT;Iu$E&8Nt5QE#~ZF_U^%e}ENDRwJ1 z3ETxMPs>GNy6PZEFup5Cvia%PZ{@f@#*Vf=5dO-W+Sn)VeNZ4EdjB}2CjEbJqxyfz zcea1IDu#cj5C)Ov{Y6tK{&rRTp((Ra$p0Hx1@J#y6{H3(f4eH|`g)Edc+Xe7e2+4I zb3JYT`2F^Wrp#F& z)#?x#WiR@lbo@Uovg={@LG;f|@%BSkrRJ@8e< zjA0#`UM#^34iR;;I&^jmSo9B0r_80aX1kP(_nDcmq z=WwGibZT@rQfhSXDA-`VIM`tQJrzn9`)Mvp@{XBl_y6LoxX}NXvx4D&Ix8-~ISV{30=opR{E5j5#2T)YHHXn|o_$~i zwk5*XZY5WA_!9YI7g@uqzHuY{CEVG0smsY{ndzt%tEq*&h!Q z{8;{$EzI+ja3x$EIqL94662Dc)I(EnGOydnSNsbTfvINYc&L-MEzr3^!Q@}U-N4Cj zWW8M<$>|U~ve#^KTs`Z1pP(#QCq4%krwIPF5#F`Fzl;@0`V_}rf?ZRFiCrq6+QvVm zy91n+9nCCV2|mb4DYgO~WKpBv%F%`1Wu(gtqo@{94@lJkBwTWbJe(MV(LpsUAnAiz zRKT8S0+2T?^z;qzH!ga~bFqDN^@ORvgu7TDwB8KpQ8&t1TjJQtoWF%T3(7Em!Z3e9 z<~EzZg*zKul_}+-=)xNuH1yV1t_>cJ1iCRe^O&slIU zk6*g#h4@nv?P>1-tmofH*uJ)8!L%7D$HU7V{{BN?Ui8#ZZwDc9&LW5aKrjF>plVJ| z?CNXb5nq^3S(^ZD(5U&Pd(C`re=~EKo?F%-fO-HQak+m$pZqqT(8I{1BJW~+xg$J2 zQOS6YT9osH=H819oftbv5^7GYIRGpf!-15yCSapiI?+4uad`sSgOo7F5MfK2c>^R| zS7U$1HWB*0K{oGMbL0MT7(oNqjlJ{QURd{iD|3PgG=(ARwIosNDU#;Oz9T%m1$4z5NBw zpLPMr!j!0?e#_E6f`o$9{AK>s3Q6o>V0nv8EmG`8wsm1|iZlG@XWb`A+$wvrX(#tb zpE8sG3C=;MNGt1JPgz$yN9{)$?Z4mOjtoG^uXW(S;O_wWvEIhmW!k^eMdMk|)o8@%$~CpM4A%AJaGaF%)Cg9~EE{vecCNt>;^JwkJ&9T~JaWt|8`F#$ zK)Y-$#U_azuma9lmavwIMc#C^IOxQh*%R|Bq5QXTJ@r^!fhs3ZIVX*UQb5I8UCn7a zlXRn&+~9R-vk8@-Raz-wwEP{t)2tekrA81l7(!nVn+b;;@|b>LZ5&%cir7QghBjxyxi_u4Hg!#`2|HH#hDa_& z1q0IWgu(=x+Er$>S&zjql_6A%b13k;q#`=-5f`G_n*kkQ6iumBN_%nO%G$OY-Udz?rPdCWM&iJ}H9?pQ_MPj>m;BET+) ztXJ5InWwD;uCr$_lGXv+*z`S^2uJPZ;8lfu(>AI|%ny&n#c-|#X#eB0O&}>>(^97|DU3U zhN*k4RgxoiZu|fD`Vl_W@fT<)TULH z`fM~ZbE+Jwkz#FMx89gKfpWNT!XbsqHlQJ4=bXoH2IYI(*jm!|ulfLbd96r8IGpTL zltiHo3e8%n!w6SX{+w$cN@Y83fPzH&mPCU0%AzwdW&(iETD9)BOjrM>j$WE`U#qP} za(V2;1{+t1+`+YGhjFThy^B>}B8*nMBw3Akonw_biVev`YZg;OViSj4t~srBNrSci z1dZE_w%P>j#!iE8kz@AS2cm;)$+wSzn(M5m)If|OXO|g-8ug~A3Qx5?DZD$(2TlQ6 zZ&^0Hf-NG?$6QDvoaWhKWe}s+88-SM7qYn@n4S4opq_5CHbTpwA0*W%-&Ta4HkLSV zVfk3k^NoJf;CWF+3gnsBFXIe4dWz$*z$0@(?8Cr#1iHe*AmUyM854LWLb~jEINx0?x7?AIOg2fE<`wo$w*yzMa|k`9Ae=^RTom)TH?w>f zCtJT*0weoPkMGivZKv%OayH&rcW7lE+xxD4>ak$BX|%C(r;UT$HgJYa;DRc~a+>X% z%bklj^*nd{GcJu<#bp@!SB72Hyng&#ZM|IWje-K)w9O6FWLz-ygwd5LS7}ju4aef} z>K5s+<0a$U37H)fidR9^MXVEkdGq-D*oSu0578zm)h9kkJ_xbdtHl91DO|LM-Y~t% zA{Z&GYvim#=qaV%%qQd_-M&;EWEU#w=ZYYL+hknxGU78j9(k?cQ;H7JOj0q21pGdt z6bEPzbO<87u=wjRQoQwESbqV@ghcs6A04q1cFPmeO%W!q9cr9HR?w>H89B5mctCGO zh_j*-(4zV#xok3=xRa63Hh#_ZmnI$dHpvgaCFpH#wsSEgtzuk53VanoJkPa>S022xDYeK&os0b3uQN>F zR}4tcvWQ_?#cm^(AI|=M?a9&emFe?O)|vdrVJg{wJL}lmy8u*N>>d8QcA@vLWn2)r zYmNcE{_Oh^MFWPY2kl`Fk_c4(1ODigK}B?N7mZ3*GWc3n>7PaVq%4(bmS)_Ymsg{% z#pX-6xg%zVvv4wtGndYjT}K-W0>3|BF#XP+nZo&jVr!+A-7SbmQC2cE*kskpv$A6c z@(YxA$xTD)uJtx8MYeR^F;AS*LOV<(IoBWXWPn)oUy*V#mo&_< zp>B%+ZO#x=^0v(P49gh!5)dL%coNj%M!>LsA;$tHR%oD#6lts}rxGh&*Djm%`U<18 zYZ--J!#ZBy+;PNJXiKcQD+S)(2~Wj@G7UpzqIWolXn;HT{n*NEmsODI zTxpry+B_goOzbIcATMJ#BFz$XFm8RTrSyo@hHc=vMYdk3{M)3^XU+Rdq~>Pr zBtwTacG9k4q{QZvxH@-FN-xsN(TJ*VoFw>o zIid@X72)@P$N`{OOWpkA^jF{NT=1lH6W-i|D^-}ZLG0a+WF=tVZ>YI2@k$0S*Fbm$ z<1p4nQqD^zQQT@bZRMWlwhJymmj$d!q?>&VjWD=w&IWSs7SsI>nkY*C@4$Py3y}=p zd$F9~6jb8b=xtd!6nfFc$M^Ujo5Y=+A#nn+9wg>bv#x?&3MP?NqmzGm_1t^8Dmk55 z+hQ&qM@JtB;brO#u%ezMy&IMVo}(A$m!t$EN&Y}c#lV!XmV#ONx1P~KiPPp`xIw|;!C zb9HBpS=o{L2xPbsGqUX}@Ey5#=a6D&OnyWOY>dCGdIVIu)bRovRGqKHKRma}Gy5`pc@9IK}WE@1p;>B=tXo z00H^&k9x(wJHGZ`O8fuK%xdmPA#{L72R&hhpPwCExSEp6jA8&2f9#2y_M(k@dS}UV zy7x4u94iz5TZ&|)xmokr<5$%CTpkwlsh3HvtrxSmx2dOWkQ(Txy=jr{IDkeHQq_cJ z7lLUVfEbngXu+AY!CVI+yF1izc2i1aNcKU6rXsOHDs< zlX)UaguuVm1oeBB-8CyeGN`4wNdkz6v>{>4*OZ@^^lZH3ppqdFuTE{H?Ptdn3RkG1 z2bIh+{t$td$04l#y#aQ0bk*v{kBD^G(45LOtXAjBI!8x6Sk6zbAw6b0-3{4f4%+k$ zP1%{7a-jaTtdaec{-4awSYM5f32OcP!)+HHA4}`IHS%5c0Xm$(U-oUeS$ic35XxX7 ztL%J)u_xQ|gge?|ON$fK{z@L)yE{7dFfEa}wsNC$BW_8pJPp*#Lt*!KdqSDEGdMCm z2w+pO{A#w>#bx~dWu5~$Wo~(jYCMwAcL))?Eu@JQk`vC_N1c9D55MFO!(?&p7jM{0M>(q+38)k;Uft?ZS!qyxH z6cxmkPSFvf#U&Ti6w)}bL1!WfoAl4_6elm=#Vu=Mc~y$6o>f{hxXAM0Gq<9+WM`y( zK;CMka#`_{>FW+*>xUu7!ox@cO?TZPwkED@g%qV%RYBCa#7J;5kD1?38J5V3A!I`zT+>G5 zNZu~oKJxnUH=C~sK_mA3KhCa6{F@I(k6mPY0rzT zpb5Fmf@ImRWBw1B2b!|2$Z@ncKH8st@sfwj@|2Isej|7(EOsZ~tFsAMT}HBTGk5oW z+C1WC>EHVO{->mpd1i{_2WpK~nfbceOycTP%1SY`CMgdwezUVb0c`$4_o%l^bRDi4 z=dl-OIrwSKPj#z4$E?E}=?mN$epT=+s!CrNS3Y54;4y+{%<%fM?i$$!Jp;uQq;6)< zQo{rP<&JgtxTwBtNe>@PxEkA--CcJrQ3O5(&g&ScRn?C1Yr=|^mPN&>xv53YrnxZX z)LWi^k`aC%e$K&8xnlpGTI9!O*)^pw){F!4jSwT=EOOuwqbj3p*D<^Fx;_dtP_&o& z>_KgVeV`ua+}%n%g2>?6kcg_?dK5n#)isg~t`~9od*UzbB?r7=$qrb1$6pvfewW^(om?6{sPiHl5`I}W!yzVlK-e1phIcpFU*<^{SbQ`oy|m*^i+?LRXvOI>f& zLC_s50K@F#)cur9?k3F==6#Y(crb`lt>T@17toXOwoj~tT#nq~mKm7pBM_`=l1d+} z^i~bN^a*MAW(nyS%$^)CJZ9x1EGW8UDPx-1FtZOJ+j14nAa(FQXmbIva}H2azk*Hm zXUb=n8~luSZ?qB^P7&~XY5VEodDDIJJ=oXWEZEzvXKb3%CF)mttfp8ZM+OE?Cun1X zFHhul!m5KP>|oZ=xi@7J5b1H%REnXLublMwf4N#sQ=Q2Piy=oCBN|v!ZsV)THZse0 z=6|uGj3fg_{9gI7e@U;VRO|Hwp{#oW$KhGU5ROp+yxI17ntFKI1$WFhLO6q`@P_lz z+IT)Id1x5EZ!i|Q4_LiibAPN-QL8&X2yJ=KF+z*6(4Q*=>R-)HKUp!gZq<6Huf6kQ z*lSg3#o0}1nyuI+C*{aQyzG8>w}-Q>Iqc)pv?Sq` zW=$M*Sg?^>R>RC}f!^<6^@UD<5Przag;0LXtjIm}vx*;a>4hAhz(%pWMisd+W*Gk< zyh(reO{@aHl>;+zSy(mLVT_)xCd5+w{cTS@)U;w&o6`^wt#nsEBON@99sOCs78L z-qVcRn)qs@lz20VvGecEnN9yWXPlW;_m@o>t%S8_=(6756bjMYn;f4oz9t;Iv(|D~H+sjg!`Cyks{DU#4a zSLlBE6tOn@^DE_c&}_UgXmG%48T5^!ZHAoHzD&(h#@t={BzT7(1nO?uRzHie+eM2V zJvA8q?nY+ji`n6ty~fMq-W(=KYRDI@W1{PxyR+Bsb@TC3NY7yPJ}a?i-N|gm zm65iu>9ZdU%Bt(g=4#r|d@UD2>94ZOs`^jagO54sz+cqn0+m*I$v(l)vZJVd6=3J-kbz0l=?z8T_t;LUse=*`4 zG5Xv4)B8J$H_?1gx)39k3YeR9VC{@3P3c2K$2$@@Ra+APHv&zR(JBv`vovzVMLC z2h|%oo)Nh*0%%E)+^@52guse=;s|Bdt~oZf!AUWbt}84lsNlc{a(7Vga9bA`h6KR| zc=%^{a$EEhS0#NHKmbP^$f)2#-rlW;nLP+^j{-Z4pvx6}j!kn=QABPmaJpO<_^48d zth9F^g9->DBt7oyFvR{-@+4v6`73KRGQb~s<~NIU0+SJ0W4v9Mu;p+8;EO5%D8wbv zb`P*SvciqSP;7kIgz_YYjT6@-bLMxfrrkRZ)gwd3kJ>#vl^j)Nd-;@f>?^m};Z0r& zg!y<1@bMBL<8!R0$HvwnIV(>v{Pak5sluZH6GkHUlM_H#hyw%~(SEkcnj2>}Z5>Ia z%^n9y>;4K0&Nt@b+YHA>+%K&bLcp5t{sgl;8f{y~{YHDlkZbvgqU|R?6Nl#7`htmJ zYBNAYl*Rv2^k7lN?Rv@mw4st5({nxevDZoAzA6a_{3+={mAL8Nw+2mO4v`moiO z$?AZ!bsN-0a|zuRAzhNAhHKPl8pHxzs?fu~m-lVX}Za_B;& z%goZULJ@W*#dMuIGktKGc=}$~_VNC(umNN|h1UbrXEkcQ`^~{}LgP-RGgoyLKw^^u z*L32Z=yE;UzQ$bIYM{2ioy4NEW;?Dr`f8Hwl7R@rh~r-Jk$aHdx-|UtFE-93b#eEiqs_Vhp$>*m$~@3aBR4JBfIv{81HUo64g` zg3d&{sU><&m>Z9Qwxa%oQA6i%>fu66OZLq;hSBoCWJv6xkU_4IF6;x#%-%)p@N-sW z4V^hItn(V~8pN|qnf8;s8aRJI*L>L56ZmrzIGLcIwRiQey02C=`WuEWQ-G z{fj4%o`KkNn(l4m<5+!x-tq2IlzvO(%t5}2@xV@roGJEUij$Wt5!V4ZLY|z znN~>xnXM!VrEi#L>aAj#D|B8=mnTR#Cu8CWLP?UlWDC5Dn}pBKLzdT2_h=qolgF7` z^_ivC?5xZa1iteJuAh29e-$kz-)2C$`r>ONR~SH{3>bX_G%OHH*!sDb%0{3(Pc(>L zm)yDB8dVPIDwQjUo%?%5$BC!}M@r{h&T#7 z)!Z)kEmdNO6kBI6p!1hPp6@Z;(T}08jamx#BKSrR1uRZE24K$qTy5m?O`3J2ZL~J2 z%57T8D^Ga^GuJzD$s@?W$66@~XVB+vx+JIsui|^^UF46-tQB1zp+ZSknUOY|2k2+q zJJw@?jZ0aJKDoGRxuj1pUeq5s61?nnxMWu#|40{TlZ@|u4>()h>A!@cSf*2@UZ}hV z6J)laY}Ta(H))fc=LvqBNn-? z`llg3SgJ)W>fn(D(?~7&m?6(=43(=);@OF+VJBg{4WZa>*-_%K1?I_C*LUKF!DLc# z+38aGF{BoROZrM~Av0OE4T5MBw{p+U!;*?*KRlTnG2{c65-U`e&>in!Ub$w&eA_YT zj`v(!%Qn@HZgfLJCk?$i}^!Nv2iUrU`%Pk%qayIS|~KEd(faK85K{q2Sh zsOic81q23crNrVlpcn^eP+=QY0p@=Lit*yh#>O!X*gE~@LaXr$KtrQNvuA3PM&r+Y zc^JkFPpel$Q`o*zi}1aL_U+%(6>kX52WhZdxzPF{E)4DoGt1^Ep96m}dGQ7oc9 zUG_{NVDTVilG$x&?Ygl{<-FBw*BO#Fedc+XAru269LJ_HR>7-kHTdLIg_blPi64Zc zQjI9I5KB8KA5X-zx*7H5*Q`Zy*!xu|`&VfOY-~*t_w&ZHrlFedNs7ly$>8#I(8r*H zn)Wb54D0k6$4r?7$_MB6)lsUo@uFphrMLi0hcna#h6>I;a{l`ar;1s5O%rxx)=78c zydRku%%$7Bp>^mx%|RNu4A#NSN&}Lb_g<5BgsRR=Db;CrVlkIJtG=)G3CX^k@ zHK|{fTz)X2%ruY}cHRPsgD*PGuY$?WutLB{Y?Otc&=ya9@Fwyj)}zfN3%Unj0+&Hk?wm+H@n+tWht z%>3uXrIla+b>4KOp)6g-2Y9fPj=Mk>bD&NL(r!b_@p9^}k4Xo=#C}&_mh} z!Re?af2>$Xqb4Q?+#LLWkTC?!BPpbVmJcBhV9sdJ31+x9d?qbPhh8 z$Loet_9zl}6r#MFMi_mT&9{k8f>f}=jE&o_IoWYnAU>^FZw@mnGy%>XK>^ReiOl*i zGTT5+@x993d_}qkqDU?~unv5#(XX`Mu1oOyA2zW9+i_3%&ACdo&3AGHPi))ldn;Uw zmn2?1Od(F!`yWFWZiiWfeNZ4E<9}om|7qKiqm8tl!>HJh-){5;+X<%a)q}?<(^lIs&uk329UgL+hKrXMP$^LD|MaE60 zO>39;x0g>q51VF4oDk)l*1|8tT7#uVvQ#sA#OYJE=r8$+j6bYHW>WLa^kyJF&}x^Xktl#2(wSi+rRM5L)`98 z_m+&ilmor70(I*wi0=3+c}`(nxhxajKcC7C^Z@}I z%ATinlD313gzU6&2hBo%7ky9%?laG+c{#nc{tTgc7=(yHIHjzQ*M~)YgS>x1(I(?$ z^WFW$Lm7Z9%o=D={M?9pOybKa@`cE*_+$nI*q>$v|ZUmd!kT;Yo4< zB#$XwY>E>AIddXR#s-=ZO8TNs0QktNPG9l7P0XS)P_eRQ&p0iKWKK66CFQB!C&pJ! zDEgff(^vSe{#I(G`W0ywrU>9HT5!=XdPZpU=s@0GS?ENYVGL|*Ua=R%esk|!G`^1(FN?c4YOXNmB+%O;f`IV&K zB;Frmy~%OUz#Gw-0{HKlGweWbkEd`r08>D$zn9D*We|8!{>jsAAPW%?S*dTpeUT9U zNLvD%sDvSF!oLjxYMj+}BGm+~s!2C%`&)rk1j#8JtXM6jm#_uy-51>q30wR1Ih4?rL zk-ri>TFZz`NG_t=N0&qyuE)F2VW5O&LkK|fuZEhVCbbc`dMUtfXJ3&XEc?uZGy8pv znDDJyfYbmzko1G7!4NnfyFbAlr&m=grSL?!!;otT{YV0sk_Hw97d^vJyY#_CPf%Xl zr4u?0ON40V7vfa*QswLp%FdxAkcnhP6Z}LaS$3zkq3)3+n2>${bNA#IoRg2=cA7K) z2q*qi2i?DUh%gI96i_QcH3koJ6dQ@NMTHMPWyN~E`I&-zaFf=9c*;Hf40SpB>#+oW?5AEcFg(5 z#mO?E!(5$-CYg&RuXkk`%Z6nvY%8s?;dP>vLu&`irpdBwJP*T={dx6qX$mVyc|m1# z(rqA8KSa+Rzx}tI%Ks&&EKx2Ps*QsBpbhO{N7tCK@S=fYn_!6GTzH1!NP|4h@ZCo$ zHySjDcF)v9j3M!bAL2~R95Q7Vy_b`pk7 zATtIr#5MP0JiTfodW5qi3!j$Bwd;$_t6YlQ)3mf=A;mw-H?)l7^B-E}W}wy^#1t zNZdNAGTohLG7oFJ^*oLLF&_!}ZK~2CYIYO;J_Kr?7>@9&?50Hmxyg?ty<8pehqT-j zgg|!DwRtkBu=lq$al%qu_nSNr<7T|&s6u5kSLI6OQ{&mj`dZa8yWsoA1+-roubk6Z zkepLwT)sGrDzBelFF5P@3v87>ig{r`QxPQhV3Yo%An;fH@YhCeqz4gvJ9uKYyIc$K ziBK*Na``%*GD;8Gx{9#b(&De(zgs@~0(FUgv zyVk8n_Cww;Sp~fo{kNm6xk6!Zetdsz$2F{dGY&#URdG@UevoN1(beQqn;7_w|!plANxFA z0sTp$qTjMAxbU6t-Uz~h@XHFpf00$w|65k&QcdJi?krkpy2fQK^#~(MgR62jCv}Q9 z!5R0}WJ2|`?hmPS(+p(Dhr$*T+I)kr;K5eoI;_gP*-2HgAUaynYufQGK>T)O*7Yn* zGIFW(4jYC`eOii?j89rzF$tc4d7p@RUncVb^4v(Sx*oq+RQgOoAjR7;*K>`{eW<&a z7-4|^z39CYp}WY_GwiYq^xNSO9d&d<-xVK4e`~%YN=y3*NlL%4`IzJ>o3# zWWRFRYKFgZ*;4L)u@;ky-&3jzypdT@E{f#AisUoBPdt>GV9CvC8$}POw3rkbr$O4^ zRM=ZqYSy~ZjmU_r=YCJAre9YZy3!8)J*5gCZ{~9GOIaoUqq6$Xeaio(tp1HaXerK0 z{c&Rg3E@NR`l`d?gTOB=P31R$o>_7TxRT8c)iyRQ#CUK82k*jX7lT5#1DJ z!e$0x#?_v8AzZfasWvf^_?sWnH2 zo0B=Cj*bb<3L{06=7Ic5slx-qon768HrUv~9{>^8S=cI_8T6k29G7Z(MrL~l^ys6} zC`M=pL7qNZ20BaxENHZF#o_db)&NonME(`>Hko>8JN&Rn+8S{-*<~2!-pTZ z4|P<}g1_!ZyELEy(|0<|Lct^4J!w(&H-PX2hNt`xybuQ70g$YD*x5^h0gHm`0Yia) zHXk!l^Rw#cyA^brw6eaC`)1N6u8}(!Wef9D`&NL5L{1h#js)(GyH!%RJeiVb5UA9jRU#(>Y#MZ+?ZRUNJp!8K$KQzV_M4`PHV zg6AG458EqfItO=*l@J;kFojP@6Ky7W%R%$pPFY;+=t&p$bih^~B4(M0Qkf#w2SX zulHqR*adj>8*Fe9IGO%u);&u>=Xk4g>z8Y*)mw}-Rkh5|tU4y%&{YWalX_hrS6EPj zVd`pw`yc1d5IIU}NcDetGU-T$6vc1?*Xd)};-OY;ULd?j38L9I?_cGfgP_9gaB15< z;s}ICQT5zS&6%*j%D3Y5m~=5m^+NE13xcmkZc+L{%U=?@KWvqTZI&F#(r1Za#6yS* zRzdK$k}f`F7|+DRxAGf6K!Nj(J^1_! zKzw0caesnZzL~TwV|*hxXUP8pAcUDXR(}Hs)6{UrKLCO!j5(W}K%yp1qWL#~;A|-> ztmbC8wg)b$AfKMsa?^*z3-dsn;RXnwud1r`I$solHKrk`(W0rTyH~t^{(We8t?|`# z{*q=z{|F%d)6w?-EzSOYK+gqP_?I%9y(N$qATR?_4&yG4VGZPSLukxND?|&+(FH(< z09Z$ewZxovj8z9FccIxu`#A1#qO0Bn+HYJ{b3N5e;9jPN2=qGimbrsvYI#f@9K<(#CN(Jz{M+6`@pvP8oh| z=Yh%?gb`@(;L3bri`1c5Byw6Yx3WIUtQb#PN5j06BKyQB`;g~NSbTt?AD6e%_#UU% zK4}|d>d$3VmAf?dQDRoVBOAdvpY{hr_+hkZbDz9I&@yH~q@(`@AvnxeJD^M^`su@| za=G>ejw$konF1{!$G%Vvu8VClt>(+ju2@;mW6<8G&lxB%jEUwjz+|MN66V3q@?j*XdsnqeAH6zg zB$|mO9t(=?OAfkDOQu=!^p2w}6hB>iecto9xv2O6&dCiKlI!jO?Gy-AC^W>JcsN3}{^7(DX%4{a_k1pRKsk{Au1m&7^8~;$%Hb>CDx;ko&5% zR!d6!md2RR52L!_D_9Dya`)gkM+~M)13N3UdQt8 z!s_~HB&Sgpi`onOB=v?B<%XWGYBWjsXdO~`OF=s)3W%}1d6ggP08FS0*g~2J2_2{O z*1iQX>aD_9pdqWE*!j`%C=`0F1`b%YZKpLWPNQ|RSvSFZDsUSiE|Vm-K<5-v!K;o& z=V+8ZXkxP+%{tAtAIY%Ol{+5jXC(5N83im@ITjEgk3d8rGcV-0M<5~7!eq!DWFsO6 z*lW=<$)rOdL&ob<4Uu#4Y$=Z*M+^4zkgf2e9~4qEJX?_@_rbR)8S!Cte0ku9nDH5w z_`S`R3w%gNG;wXhF~mW&Af)%g9@beOnIVRhv{*c&33 z$Vwz_Y}JKk2Y%947FkbMgg@C@76I2tKh^BnX)w^0^nZ?zZR!gAZLNuWdqDem^~YLs zvd{Wo)|$uY3B-9!OI`AZxy@w~Qt#}tR==$^i>t!zJnu1TR6}38e^Urb8!jFdr9Tux<~M~%%~A#a7lj}s*A@Rn z_J=|w^zEM14_bo`BlEfepFE1hnLViPwi3!(=kaY0ksu9Nq>*WHdnI`7NivE2p%BO% z_?Pr0zbVAxDp9nFTd^na$=?)$4;lU8Uld|pvAIUy2{;`ZWK>!)B3NP zm~}kN=PasooF(DFycJjenfhKDO{jX?IU7C2sM_~G6ru^vGMN+%2uS4rm!=XqdmBd^ z0~^c#(|JVI%wbjqg(oa?kpT+9KmZK@Ofy#lNvapgAPJ#SEItD&ppf)sG>oX4Mm5QI zs-xgV;6dgaf7dNYCIy_LG3RANSAJLSnb+iGm?f1W)R@m*(#r(TL#IPk!q<=AH>deO zP6v}h4#6@Zx0$7;C8g61DoB(j$PC=J7o^^Vm7*HN0|?5>!V0jTrjN}ndzq;PS!#!D zN&&uBPn(I=FJH4IlCo$92ZuyR$wW@$k+@BQWhG)nNa`aoo^lIzE6hkVX1IOWDD)C@ z8D}|`tBFCGXPL)1eu`Pt3tJpFaEubWLiX$`@3kV0Qa(vp{$RZG-1iAc3dmZh5ZonM zWuxig5&#Fe%+?aYR%sIG<;1Ko)yunM1U9`g@CU7SOO8;EAt@I>cC#u^kTly@CrR9^ zgi#)mp(>o%*PphaITVH@i=QOU>-Q3Lb*yI~MH_ssHt^zhQdXn^z#|-tGdAiX7m!w< zvg9WJv_WiWbekO>ry(B*Y{^h4mQG}+%^~vCBbiIaI9B<=J0vfqsGi^7k|L>=IbE)I z5GlWXWUh*SlGL#!k0y?titnOnrcvWOv00eWgah@^vc}X`RZ}J&OXTD|T0G{tC`nP- z!~vM8GaJ7(_zJdYOR=>MbpK_dzK+TV6z<7ZPT++RqHQX|_{U;oUqoLqwEAZT>K$?s zu`G$4?7dl}=e0vtYDj1B*I(bt%%cjw+`jRVAJh8y%wU*~X#*rcDwM0tPz=(tT5W1D zA!C22Ibb$_(zTs(%C$Xr%GFan_o_KvWXCSK_FDlKFV*=Xg~B3cK{qke0I@?-3FT7t zBwenP#N;k&nc<8PiDm>+B&6Bg3W48s9*Ym;*bi4!bTJ#0ssJl%)S2df+N-#T(U3Ss z$7xs3W&uAyqcql&6p%ynu4s3(GB3hT!`-eJEv>J@YeR(}tw4Qv4jEi(X@F#=j4d_( zGw~_x!aXiem9eB5O(9lGMr?F}#LZ2bct??vp=i`KMb$YD41O^z{OiRIBNVlblo@dx zkdzv)9Qf(C@`vuRnh^)fFL?nc`Glf`u?5>L!k^C_{a<9>jf$_gR- z^*I{5J^W1~eBK1xM~WUp&j@cMATSEh%aVx6OO6gk>~s6&f*u}!-QgEl-X!|hIa?() zr80AhGPPwCI}=1NnjLIU$*M8JgN(UrOba~$@uG%XC_2pJfzH)!%~)tsdZPp>Wv-mM zxC>L$Y_3H+%R+B)9j?n<=yB7W)M#Vr%h_+wtXn%it~2P6Jc5RT8+5mALB_#mnVss@ zytM%hh?6{^OS0rhr_I3=I!`s$&sJL^{I^q8njAinu2ESqr*5B|W6L|nz<#B_y4aX% zUC{HKQK%)0(A2Evs4oOEZK2T^cJL4N;;vYExQz>EB3wu`c}?p&AulJz8MSXtJ7Dc% zFEAb_JNh)-K>@zEtMJ`;=16$2s=6e-2WOHZv za|cML36UuEf~i8~ctUAakr-T%a@>*DsA3=>khmB&1#)k!aiyZELitb4zaTor&JUuB zm2Zb2y$mC=FEp3?Y=JK_VXrm?5IEC4*kwl$^%>G47^(mQ|YPEZf(Iftjt@@|kyv27OgZOiF6P}(L_ofvbQJ(v08s{aL@b(6gTzCfg z!Cm`fU{4}}NTOpgowCeMl{SULm5BR^tN2-*dpi5U^4VC^OHWLu=$J>yo*$0{NJg5k zm=>k8EsQ8CiqpD3^wLUMq&cJn4NI@x0Gf@-OmNrhh(w)Sp+i7QNW+Xb_2b;qV+Wxw zgEFuh>e;a}J7<^LxBSn+bJIey_#M7Wimj)O!+BNrp`wJxS7LKa!#iq%{^kgb_$xi` zWoX*Lfi6>s1~;4bK6s)&9wU3aIDOvcQi4%HLuWuk!g+{WQV#pxJ+J10PZ2AG@CRuS zCMu?R;SJ5yWaHn3&Um%UDC(eU{6SqHERIlTLW$t?wODItSG%PvQ-xQNtk326naXm& zQ&O~gPsC>iK!}aiw`jH^8P_>w7wA+3?!y2joLK7(H?#b5*<(}RnVG-x*L=^H%Cwim zL{fSsj(#u~l2cbl*j=xhTyYilu3 z{fMwdz9zPo)P7#*yS&&bqYBO1vzCLbQm`1$xBWU1zknH>eC$ydI^Ttid+)*fvGu1} z^AKgndgC(?P}x7)k}&;0$5kgsGt1x6^}iOLBO|4udg)OD$nMA}A+&|?-65L%czPtg zXei96#3{F@HC=(=Nl2j|;KsU}p7!6|I)QMi=g3hS{cR5MI>c1L87&9H306d}SX7Zr zBj&+4C7a>A5F$%@3-_?&cRF+8%?iS>90K2TauwQ*OzId3Ccljo z(~D;ki1HWFR6hd$UMsmLoJshvm2?69zq}{>ueHj`2r9@43ftS;*#Di)DQf+m`r(;P zLQ4W}xF*;XMVz(*LyLX%Bj_Q7EaVrg86;zB%baI<@olRMdq?@^4{y#)oOamOCHN6^ zbzVL1r!S;qyuaRZu*zg|;r)L9PUIu3IYKZ{y$Nn*p!!*$xnhdG1(QX(?>-*_u!@v} zD82$2xsv{~g6n5G|0XzxAx2V^|8hfrRJ~Vp4nkP>zKkF!!GH_fJjNnTkZKj;00^7W7k3ko;=D>HV9GwEMa|Q5CAS)gPyn4LNSP(o zgGnL1k1OYj6w+p``pwVqrq9F7Oe(v!6vq+)Di3+xNGHzRJb|=q2L^o%!bB;B8`Oc2 zw_haXWrRD(`yIp&aQ3b-vYldbomwTQE0yo*l~O%}w=I;vN}XiuV~KnwI_x8_$W~UK z<^5c&I41D{A*08=#jFH#tF)f`SSy&UJYpvtzdpP{tN}ODsX1VQ6?pO%#W%&W(b!4FPEVly1 zWK`JsU}Mk8^KhQl@52<;Yxt1mF>&E?{?u&p@pf_X4Jbly)*l4P`sb~^>+Bq6Sta(C zpF*`nV0CG#l#XiH7=%V4fT0(LSmCt1cbuJ>KYDCF`3dGY@j6^lsjfdg=*<>KlFrIhhI4&65!4cmpnyX1ck!pRCE< z50xwd77|B_0m8EMD976feGDl!X$-{HCBop_WmT!Zp!}P zOTNlZb(dCmBDwQtBM}`vkhahQMujwD?FqtEC95Dd_|x3b=VwHC%TRbPIoW(BO2RbsWmxPY%f3(DrJW06vK>OnB@t`BMR1B; zDn&AOVeYEcjKO-iHLIv*sZ&c}+YKlkx=&w{15gJHYsoofy+kNH_-LFu-C9Y;tB>!} ztZQckGLLd|u$~_Luxi+pnLuFky3v^EUM^uQn8o(e3ecCd5@mCH-mF)R&LN6SA({^t zKJh|wU(P&#`TlSjyZV#R;Vp;tZHv{*C45!zIu@-Zc{h*79)DyAu40Z= zg9pSDCVs2~-XH*hOe`&*?SpHE%4%nq%5}A?_v{(jMCWD_abmVkF(rdfF6I;ZW6@{u zSC_-Ko}%17$H;`$YNp-goGwwQWXZw0aE^iuJH)+dm#hy!eA zC<~CxwB*lLOu>FtQQ;`IwG6?hysMk|!ZxO+DT|ejb!&u5Le*fFZJ*N@^meGSdO`di zTKhBzmZUE_r{D$!1#N7Zm|s7~P7PyAv3lJqHgmUFuNL-7$%ht|Sh@ss#YEaXo>)Ad zIK1*F{Gf4Gn)#iwYZ63!mDPo%t+#czXXZ^lev}vQd)8n7(!t_B_+?s86 zE*ymA9a=fe*zf@*Ln!+EGl>?8^%$X_TVcBzTCHC8OJ;72E6F#wNb4N})buWE__l97 zQ?#`$TIIX$sxFsnm#o(-5%|oKnNoHdA>Yv4u-G)pg-lGyj~6wI3uBYn=w8?OR1fO9<`Q3{Gpc|uArf$vBV4-;jo`C;kmmnP7-&u1VO5IBZU8QtXdRT`SLXpk8u zPur>rYD7v*B=m>Qx*vP28m~*jGK|SZM`tY@1Ys6C%VbRJv@oT_W>yO}wUllj53CY&W$=q@!%eR@hziEc(L;_xC z514(px+U;MP=pe#fz!n}frv7|4R)zwzjA?>`OE(tcWiY9`4bRO!l(aFRJ@vyg7WV- z|K-kz1x)WK5(^^_hMq+P!W~NS_#d@3UqHq5L27X0Ll%PoB7=c*+Tug{dJSdeDk(9{ z-*^2TpTXT@Q^y>G(lrCH<0)|6Q&Zo4*YCd8yBtl`Pja;R^aR04(AFOaUJTuMb6=cq zc)#Az0MTted|n2lWx?P?_lilsG#?C^>(h@XBgTt^>$T6w}pS&K8^9SCxmZ>gt@1+ zwWpn#xx0BGLLc&`lm3|V*=7hIHIo`jh^#y6QYc1a+M%C#gV{=A-8ew}`9@_V7MN#N zd&xd5$)?P~5fgr53D$S@)spK-{vi+TmKD;4-<(Uc@6V!L{<&`T;wq2z(N-#3-=ZluKx zU}9kTA7HF8K6bGL3NqPcw=!R_Z?w1kw8&^^W6%P-DRok6j^!r{@s?c6Dwx;zDXFw) zNra3k4_b`6w4+RI^_}g{cMXeMH&=X*HH{A;v{`JGHV+Rw!wTxYk`)DR;v7M7FD=TI zm>sG3J5+4%*Poh!@-iVVbC@Yp))G!7r*^WLLIZS_?A-B$L5j|?`?k7B(QMNyhO@Hd zB8zJ2U4t@l^W0dN*-{j7IGAz}>M2^RPQY`L5L`PNwwihpeT{rg&b1D3MOA1_R;ySo zW?&0x6OFWf_V9`89{3+4ORtoOeT7U+rdKy>i-qH+J5%#kE@aBAuFloQ_!(?iSxjt+ ze87)KTJEmZ$~<57c}1{2l2jgfk%2vhL{30R-qU13tN;tvoUd ze!A7=T7bLFrBiqZ-);wAAFk9JQag?o8|)PPXyWE!Vj4TRDPe&rj554)c7yd$5P74@ z*9YHOm>L-EfL7hkrL(?ly}tYQ!SPCCbwo$$96WO14fqy|2cL}%e)NX$e1-J+l5r!j zN*6Tm)g_`x9;Z(}@@@bDegOpQhWJj2dc}>mUkAIPu0A&VyH~`H(fM{gm<*ASF3Wxswm<@A_hdZ4}YzQE%2l+e-#-KhR6E3K_@l?Q?^d|!^k}bt%S;iN?_TI zRj_9iXN?SHreLSI@_T`mCw#A=$k)Sn|NUmlIJnj^J4NvIT0hts#CABpzf^`|?OP>1eIRSmH4%x6hTLeUHum z0p(v=d9xt;&BV#2;$i5HwUNrj2GQv79Q;SIcLKpz_qcBY_oPW^HobsTiVYv)uM>Cd z7PcO7<`1kc7N)D+$2yAN#3u}c7i`V8NcYi$Z8q1IMB_~+d9EW6m~DM4anH?(<0Y|N zE%!JJFIiVcO=Pgj^P?GQD~Y1|Ul8q*u6*InzL50?!!$*vnPnbg_-o5%XbWeci)DNQ z!N*ML63mRg5>E)?Y%t(F*~k-AJZPnS8@rrxX|{j!HP_W9 zC8lK60PR+t=uXhDT2C`w((w(=?Sm^%eou3FopZIT2J{V{rbkQr+dF&vdq5Et=q1HH zQtu~E86}-fWlbaCF5l!4MptrOstHo9seyAj+wNcR-H)miK&ULlX!SE2&s~En-BD6s_5O2C7Ug>GMGQ0d*}{0)ieWN}2=9A{cyC>!G392bm?Q8{F&Dy95eydJZQ41`sg z)np@f@(RLeV7)cfSniYvkkoec9x)^=Z=A5{P_cv-6Moh2B?*^=`(1L%5QgOtM%5Uf<~R?kLjwn!(it^ z{i4hx_`~Sq+m<#9q+aJid1L#@HIEC2bB77H^R4gSK3=iAQ5f~=DN;&Oz|I1VpyYon z)JJ61IAD&GYxIttsLRhc^9IcDvFb#myP#Z zh5>p3D68&N-&cB>Z*#BwvnZgze9=W@eB%@l%F_~o$7|><&Q(?T7t4*;0>w&H*y}s1 zkY-C(=BM>Ki}6*Zz;fL3EY%(kDR~72bO-&f}Q7|*9S{@6a6AY!UVc+7ciocW( zm7oT5J0R?s97n<@OX>zFD^4x6*NsMCB-R2amT5>O3@?$kINdmC&6&INpVBKbwlbh< zF}BiL7nG^PQ@B_c%k9bZms)BR${U}*>=;-?{%9?8&|5X!1|%n2<_+r-rs#Wn&$CH<7bKzTa^*Vh+_i^Ic9#a(<{ryC^(>Jwlg{U+3!W8hpBV(q;u1i%5@z*;}R^o$?xLDZwZO#vNTUo_mR%@ zrADL5PUHGl9G9U-*Vwf68_?14tYm(|seIAACvfyjR1px@5h!yKK*nQ7@R)M9DTTx; z7F2xf^?x6mRnUjtQQ#qSWygyVY{SVX=H}X5dVda`6%@RPS0Z0bCQ>`tS>=n!bb`=; zxs}}iI?mTr5{|n%K(uPW6o30!6Y7qwy1UMdtk5dUG4y>KQJQp6_ELwJlS z63(@8qYixLlqE=I@Wt>opkjxr^P|Y~X!22nDdAg`0Ltq^+7J?yt4|*3;0Wgqv7HWA z#P@kgK$XM=rknSUMxvmO8(zKNw_D{trh|m{Kf#kKf;}n)6bNVm>YvU)#{W4N`Y&B? zkMi)&q%Oh{+Byx%7Hd4n2jq)1cuubNV6OeW*(*pjut; z-nn&vs(r;_5dD=6B)naM4mH(iv2IQeO!_aTL366V00Tpn#9`Gx;HCt)SgbUgB;UWU;h}WiC*{gK4=4G>R z?C`}mW^))4E*?ReG|!#NJJG>{*1i&?6UMA2POdtG32v#mGnO*!vNi!=0BbhTARG~B zIR+_uxdc3RcrI3mnnkz;K^L}71EB&hr*h%eM#Hv?kCRHGFp1-X4@%?YG1>>FWd(i- zN-^S}JE(eNT;hPfmc#7R`EEBLm*bgA4M%Nh$TW^SxOpX2($!P%Gd{s zBe6+W#UllaxLk2kL?A_63zJ{jNQw-2+yW5#l)uKQ=j zpE&y?abl!g$VfJ+_k7n)7g(BkV8R2JtzYCs#yv!9$CP@c1JTd(zd2N4yL=D^F$wNf8I zia+tSdyy0rIhn}wPdN#XWALrw*AgNAakDf0!;c_j=3pUZV`5@tPyGA$khU@WyMULd zXz_=U_BF0KtK*^ZYx5!`@cLZe{)A$diyK5kYMQfrbcBtro39?B0ndhEsn2;7+AXH#X z(s=f~qB&kGAGib97M%t*a0r(|XS68iz?(?L#ulu$HG zPYp+e0G&^QY6A$?jGzkIKg5U^%v3F!8x2V6ru9SYMU@^AAq4hyr2@zJWBkQY`QZd` zR+SOA`L;GYp};0&ncI!)0a^qspY%qHCIkkF040T=qGz@P~oQUi7J_yzw#f|4mG7if+M3K86VOp|!$sX(5d=j~yiCcyeiFckxcPnuCIt^KVbW|DruWJE2^0fWca^R?0H_HB zcolIoi@ICsl8T@tQcwD!fuZ#1o%Mfl_Rhh%z0102_{B5)V%s)nY}>Z&WX85JW6o&C zwr$(CeSUlGb#L9eRcD=Dr)tz&HU50NM|VFxy8CHzR=$}bJlVAM^f@`E&j_i<9njA> zXJu9)Uyb}nY_nVVij|+(j=X4^ANlsICsw0|e)$x}sNcqiI4j+rD5?h) z!yd$Y%2sjd$-VId_mj1`|78orQ1j|l|2PBH|5!?;{2$rEzumkRjE~CVqQLRw9eEN| zK(Giv69AnK86Ihb0Br&qLkbE*hM;j`azuueF%hh}(r{I^rY7JXvQ(wIzeb%2lSz#Z zTv(!STBNsXTx@cy)w0$GPCg4fPs)%RQY!jQY4W1||Ga(XX`fWHedQj0urxij|1AOk_ixS9|XZkZ_OLwjVNLMpeGR z14VTvH#?H>@5H(n58}I(Kx1)X!Hol$Duu97AtQ$V`AGOHfE;5~`G*N}%LHI0jQm|< z&~hIgoPpHmN!L5|mmw!SQ)aSIuchqPAu&KDH6Y;<4g+pE3$>RMwMLi?X%*Y-&qQYk z1ODlcw+bs2MVyFW8GX$2&Ab&NC=wwrRT0SEaf78GNq}g#Q1b2Cp`mNq^NYUG5KrHGB>0Csy{)CKhO+zG5F1-#%(zsqvSnteQdFr@cs*+vXGX(ge2#U3 z02(~he$;M;>7jN095;O1sRp-R>3%wF=#&Bm7!+W#6g6FHC%?B0t4#8K0VPa-5G}#g zbD*Io&j~y1(Sfp_Yj)F4Y#DmmXbriWpi~7X~2i_H1v)VT79Rs`bfWb`AnrWQa;Nwu#{CJKKg)I=3YbX@^=TK1a`OSvJ zGu;Qz7vq#Ht#a8?2KXq{B}aHI@pD5*GfpIH1Zt=eS2I(7eb%yY@{@*y)3O9*E7V?v zpHpj6{6T9lAVv1b@|vr?tnC*HH8cV)7#y~FUax12Wl24e^UL$#L%$?jJ-CZ#27?Nm zQw6i2Yo~#68bLCsV@?-T$FMl8DJ7Cs!+C`k1#&;LBZQS%z8Yw;V|K!`sOZnKE9TL& zZCw@UF#gVzV?o=Pr-2gFxQ~*@CrsR#hR1;vlY-z?F#2u_@PCkl2o-KNdPpm9{>fam6G-kyhC;o%b%9;mO2eH~8c9Ge;0{ zCJ2O*vVi`#zpT9V?q96*c)t-sD6SBRTtUe*bEjV;cV0bx&~#>|x^*|mL3bln^B^d3 zvnBF&Udh-dxBGy@B%;X{R(}Hp(3tttQAJQ4YI&!5elIPER{iAmsl){qKuoF7?;IXn zbuJWS4nFJJ+YZ5`6AO&bU@Cp)q-qONT*)4Ke*oeQ!ucy#(s1Mr<`0P5u{OoD5;f;B3e3qYV_u?rB$s{A@Qy2;;>W7;<2^x%IxSZ3t9AqZLJdK*u z3WTwcg^`xVk^|)ko|V|SGvTfl#^(>EF~`WNS%ZyeQ=Rd4AoL~B!&?{W?wRD*?cb41 zfLIyD7EnY;fjd$oW_60Lyi!G7(oUKsFao01Zo7#ko<#%^X6B|J>BjHE!5j=${MWu( z;C?t8mF)-k>4^C_2x(52^^5={jEw_wz>>e@yKe|oDcsVB_{~GNM8p`j+%%S@)~PUz zGJ#}=^$1hHD8c^Udy%D}c(yavR$8d?1`FNj^-N#AJiM=~Skq0&p}>B$>}CjeXp{PR z1Ko7jP$jP8$~uy5vv{|^S(ax=;E8%7g%S7%;2Er-b%y;rOvG7Wn2rk}u*Ah(6GR7yhHw*LUA({LT?I(o+42}BEVU;pnxS~V6zy@=;xuahPL`9#> zoD9!yz1KQE_<>%;*{v7>i&hVMARTV)FT`kz^k1+dN1JC+o-Ff$Eo1%m$1v(?m_Fq% z*>D)A2Ieh9gunG!Ud}%dQZ{#`a04?lGV5|(lNH@EBn(kD;l!csMeb&DPEHsLq0L|( ze=1aDBAozzil-zR;@%gc5V|63nu=^)cZ5=Z8!y?#A=)YrE@S)P=_CG9IE7%|tIJj% zPe|^bjloVVnpIMu#O|u~ zyZS`+HdCWTXZ~X5@XxYe#(MtMT4>O_<^`7m~~m-Jd;|x?T{aGm`()&u2Z=@$Iq>o7Djk~6X08t z6e35K(OEhOTnp01lC2$%&DgP<=`D!m*s27I$p{7Bmi2;D_d=)lqr&@z6R^BEZo&O* zp35;+BUbd{^ciJG511gp?2t!VfoV&iD{YecCe7h{e$Sg=#(EVcx}U-$bDQy8u2SmLJOA3Ewt1 z+I8fJpj0cho#beVc^jJ~aTYOLLf=A={Cucyha9j9N$(*UU1moKhQ^WC|xEO8WdhWwYna2 zuxRH%8Db+E3}3#6lfDBG$2Z@x)-c3U`8ng`s%McRnx)vSmCLd>P_3yj`FJXYbmMBP zb$uy!Hj^}2=m}?4@5M#Z%(2YRNEHv$;o)ejb5v@QZ`LDRVxH1tpKYx)*vQ5Nlj_nC zJSlAAT1vjOr$RY0DUFmW7tchIBF$8KYc7Gm^J+p3vhA#)s0!#(9?LsR&O1(~=BhkzuzK1no8q^sX2=7~ViX^1UGh8B%ilbxMKo#T7bxKlO;uCGXGIpT6+bh1Y0JMx zSw&O+0kzbfE4o7gDOhjCC%MH--WKdfOn8NF<3qB^`byzLt)ikQSs?VsGddILVN1lx zclJI+6y;VJr%!ry>-Ytz1R|v|a(&IpvKg|u$`BE9L&JiZwJJH-e=Lc(G0H8me+x+m z|Di)fg(vp=Tky9e_lz1~;h9yHD|cQ91mdd`u&LtbF@ZPKRoz7US*>bowvbC&yDRyL zniBk8l}`F=Agq0e|E44WX)+%ITOg;gO4xMSqsJEDyI#wp^#8@){HSch zFobG5|88kba9LJ%QtJG6(gE6*SG8xzU6V`yXX^fd>~xP*w=Igi;%tse`}aInyJ&`ZF#I}RV5Y4NJG z(?WIS?F6RbIf69ztPs3RAgY$&X*MqMcl(Iy%f6ly+E)X&f41^y%?+f)bQ0nz@T(6c z|B}he5%H6n@9R(WzDErL0)pkIS32tKqQdzrW0kdm)^aaWO&H#WglYq-bC=|#3rkhL z_NnxPZRET=UT9^3y%`47j$@2-(TReV=JmsiyS#Fdi zqW39s^}ykS2KG+z17=NLXGdht4vS;ZRZ%IYp!~h-2tPp{_!zABjus>R8+a#?mY}Ro zgzBX%W_O8|e~~~$Q~~*q0|homqS8N~SZunBTY)^SC)_zQ{`uW~p3lU*9|#W{EAGgj zc#S@$_Y^bfg1FnosOJk~Zg`T6R`&hPQf7EX#oW3M@#qF4rwzU$Y*(6WWkG4qRLM?F zswT}ok^_j7xt5xoRtcn?K}O<)zD11loRou z;|O1b(6b<^*s+>T)nO?J!KRcUgijJ|&8ZpaLCE1>Z~7aEM_;Qb2`XgnR*2eZAwUbZ z^L(&CUSWUUELNgU$gD$59thF*4N+92=!EN1fIN!b{r&kPVlL#jU-H2o6icZiO<+yG zgkP>JvHF|H9cvoO#BIN&#}y7y0*7;TZg%euGOrBQXutN(E(4dPhv(Z&1ntG)F_ZS* ztT#|Hr#5Qnhl8ay^7PelT_?EC7W>A^hM9mmJB$Q-p}BkFG1bq#SD>?aUJ0JZ2?&0H zuPOjpex$D-OEcHWCl(T)o0iu_!{g-d&CHc!Gyrk<6t+0>1!7!u3MbT1{2D@IOp%sk zbyw~#kPFeI(gZw^s@Hvx5AGB%xXV32>pQq?TR7f}K=4VR0VQW%h+sy`XR0*F1;$rK z9VD%KD8kOTq+PQxY!}LV7rf?gl3rMSHzbQ++NKm%6djW}?G+zCRzPa)a=p$Z3VOva z-Kbv#>=&->LKr-59jf_J!kQ&%*&#s-vU0y*&vkwbfJ8&v#S0}MobZ#`Qof00Lm4i* zt%5Mv;m8v_-Oml>TcMJw4X{yxA~@)33oxKI;{PS{^sKQ}D)vxLl=lwAN!r-Rtn;XF zewGmDX`waZ0M+8woMD@#RXUf$8Z(l8dJc~CWWvM5yxAaZ4VlOud%sGg?-WZacJV#yTl%pl$r8aLMjMt#xI z`R6iA_+RR1QC&BLR8Na@E{dg$x8?6pg{{9pFa{DSl-mk3R@;(J-}#=zU$|m^tX?iV zSDMNj6}_7sm{E4sh564(LoU8j4cr}E%PxAI?pd|h_Ze^ZGf-|B2-fpW!Q015nc!M( zC4Ly0@t9k+V;mQ?4vcALq{J-#$mrhQN8->9i`gi?oZ(=&ToSLePp?W=(iDtu`Gt0XS`gsuWX@*CCst6!mP{MWlX$ zfxw}4NuU(pAs0s?w@9@>5ZMq{QzlvP6Uf4OP}A*OEciO*$vYsLmqZc%nxvO8ek`X2gl-WlZDq2hb=8#L7b`{0>IVo*4H) zt~nyRI4p$laNL#j@MWbztf4rFp&X zh};(Ujn`)7sF^LfJ$8iDE~ML0tIAxqr19)*%9&pHD09CD*s|C!pj^yP?Ydo}{IE!? zE!Q2zTVtcN-=n`o|6%2Rr@01VKbLb9|Agyq&5-xWEZ(r}QUAm*Zp$9KdgobRm5v(! zgubq_WtcT-zAm@tY!mf5-o)LI^d8O!)#nd+kh)^@!Lh*lr@^-8bPEulrPA~L%kLt-;rF&;Z0-rD<2S2XuazlxFZ z?So=yY0!!A%Z?fM5o%F(hsI}3mScRRi`_?jwr9`?3Tc_iP|rM|K=7cgzl}*3!AEA% z<~tl4Q7L9hec|lmR*<^qIjjg_FES%(L8T7yyyP}0-Xyj>sT2*7*dZp}mIpp=9)OH4 zJ^>89!*S7K4qvb5zW{MyYqSv?eGnYj-i1?~3~G>a)#{S@4alM=9CiSEFCsIBZVJk% zytq(t(^4`_i&EF#?}{X)1+BiWM4L|Y_6ukm#URecFjI;{ab0`?G`Mp$_(R4BYEGz| z9omyoNhd+%X&h)vWVWd|L?Xv%)E~+)Ad<4Zhd(6NjHX~)P2rASy_S>6s`o6lFo-%} zv{q&2_;TZ&Hg@pH1enTWIkw>t-r*Q7^H>s}>3yl8!_C*rssC&Wx>L7$KT|%g8{gMJ z*C(Lqs+Qs_nE=D_PSoJ268urbAMp^ub9=gWvjcTR9jzu?K?rAt69tpEsk1oJjWMC@1< z;jDnr9J>jjep9wJ{5f94pPBmxHc5@lE&Vps;+lf@$VcN2Tg572bvc<9z_I@BtQ5sB z%QiJ8iI&WQvardcS|6S$p!PHp@!vq2GVERwR4XXch zaYM}V|LM^Gt^V$fb_n$Ao(v5z{e=k~zx4Cx>?VW;=wPaa77D%H2B}2fT-oB3U6&2O z%zWv$Cj0|&V^!1B)^Jm5liKAVPSZ-JZ1URI)^~Z@^TfrG5&J;m@oI*B*Y!ke$1&fr z%-3UX+!yE$BR@Nma?5xH+B}P(==of7?v(cHnF;@;$KV6ZdUyI`WT}lfPB=}2?q7OM z%VDRe)7cM5U1+pDWnPt)Y=k%)2D(09STVyjC*4cRi`ZD5oWvT`1S%Eug9+R;#55-Qf5lJkNx<72D9}#R+SJoUj zS=tL@D_)0ihZ01HyXz514<6WzM(Kls0uTFlEUkWYNe zQ?@8(0(8ln3^@AjQFN)(dhj<)4Qhmz=}6cdIi9F&D9;GZ&&^qqCghn@5|*#o5=5j7 zQKyFqEQQ3^HRpXbZ-nB8?9fllV zYStKVaa9E^sHF*mDlKr#j1tGkxl&Nc3dz|CiJamxIHQ=* zAtD%8%I^6P2-T}x6rHAm10G?rhl2wc*sLr(%QHQ2m!E95{f<8~!}FBWLd`(zDdG8);e!+|By zR8MqM9oFeM7bSnwdlV-g!zM(UNO0q9%IXXO&vxB(+7^D4^~iRwP4q^Wu|E# zrVeFeDmPfsHA15L)mnQ!IpDwS$bH$C=4X@a6k0dTcd}s18wb!UVcfQvZ*6_T%p@iy zNB!q7q_w%@Fl2o&wv!YOR!p4?s1VNsiJyE?1>&cgVn>{1NN-3!272OF#q2`7_*E2^ zormsmiH_xgv9KfpgHh(Lix>lEu?@s;QPS}O7=a&wcr08EYNw<(u+>;EDSi3h>tzx8 z`y7hmaqKG)iId}!6CKnJiAOcN2;em|E;T8fsNKT^XzX%U`t=OlMcsjE9SAOJIG4GB z#yGbW9i}_7a`8t}G97d=b&Wy{{RiFFd)!;7YYJ7Q5A3*dhfDhm!OroTcY$_9)*PE> zOMCORc3523;|p)+6rqcMf_xk`bW=dln!$CIIGu2+YeicZ=T`svsDz#(`eMT+6~3&u zvzJ`Z8|yVH&6M`pcQlb1U*vI4$%8cs)U^T~GZ^};Pp@`=7ZP{WABMU&ohT$K18u{1 zV;$01kk(tMZ$wxxPg^5mBepy*(uJ45u-jhS&GGrzHq`q+onJQI(IR*6JIFntlupDD zV;vXqsD2XQ!%EvA;)@9&jGV!}5El30%-(~_ zP4CWXMn5=kDfMS)Mn7ZTk4)}KO7XHWh1E>-X+2nD5P>`?pMwIt;?d_HZuskVkodT9 z-`e=?8pVK*~xhvJwIU8?K$0Yy{(wMJwi%q+$?jP)%c^r;t#*ZruleGn^IVXM>*GAi{B9ofw85|! zlCVqOt<&gjOtZi57(pqUSuNZ|tTx}yB7HbSk6%ynZ@B$x9?|(h^;_D%jDy>uQQZ?? za`)yfrFaAB{b(-wks@v=QF9MZ8Sx7rxT5zgvwK-{as8w`F@>@A2M%#_#OZ_U1S(6d zT`7%iCI}2tEo?(Wu#Z|uGLKuW@~hc>!sEitGE`7UjEN3@hkxSW0rV8V2O*3AXv=vYj@Si~n%gY2W35<->KOMvk4iZiwZX8pZf8xqc*?ufP8zwXpx#N<{uYkn8^o zFZ`7cvA%OkMlI)+X&0Ta21O~VWo=m$#-QLNv;zS`+F44pWe%CRbA^&}5_0j(#|x(= z?Yr#k6jSFN`nPjn1%D@P^^Vv#Hx3b3G`9H3; zOF=68x?LA6pgCJjPJU(8S3Yd{SZv@jkPZn`QD8-Kk2(xZ%AS=i&bUOiZo?N($S|{V z`b7cV*)UO4GyXa$(j>W1uv#D^#C*z;UuR;uFUSCC5vynqcb+sn+`nCSzp834*Nt>q zl*w5UFn&D7ib8pFT;gNlz+T6~5A^kuWM3s&T4;C-x!B~nmuVIGb8hgUq#m*@j=w{N z4Vm;Q)74YqB4C)dRFIixl%+pg-CQ(O9fH^F*3^O`=E+aanJUvyZTR%VBe z7am87+c2ZXr7kHB*|$|=|2WxRHz zINJj3lBzoP=+Bl0mEDHiI4o`&8sn_WF5OX532dRyES4R5ZP*`5%X)r7RnPpTG(5b_ zPC5Clh~+HX9Ir0rw!~7T3+Ms}92U9_VN(_jS8ar+FU;V&?wMIFOsvi^Ah0X(`<=71 zXrH|=QI&q&>`({6bO^b);b?&6KHtyDhgP%yMbpn;z6zE-Ps>4_%Rr-`1IO5}m^7EfM*^97N!DvpC^JOc7NTj!j}_4E-HwOg(7g z6rt&^ZNk4Zl4Hl}kYsUh3TH>UFZK7IYXNd)G66%#X>ANGisBzvcI(Xg(y0NR@m0zh zlxJBr#M)?^1%^ia<-GcZB78Bx%EnGA9vbl20NN)ecufj>>1u~qL(CK|l#nQ}`}K*# z3CRqL?L`XIW-Ly^@*UY#%XQlx!Hw$uER*C`<*lA(2Pk9Z5ptF6$0l9hgv1!0!LRVL zmh~QY2Sh$etwC_f;xr?>vlCe|$ph&rRTY&n*E4b- zT*AeT_{wA(Yij}fKczb}6EO8{T35X1oq7tCc;>QuqZt&L@}WlH*z{a!`o;YwdE&#< zY_#8fY<{>yK|-@xY_tl;q}C%+M>g(CN1l(Z!D!TVjmMFA$msa$2unv816Kz(aH+~m(^ciMUm8ivdIqW%b}e&^ z3g`y!O36#(vv2k_d29B$5b*RH1Ty86YCUM}!5MZ$htm7kD}A)TdXg zFS)%H-!1U;mi}6s^kr@u_e?>Z1Sd_E&@P|BmPxwW?mP6MSIhhbI&kTAEI`usS&-dX zg|lBI2N#4JIaveY zf}TTHgQhZ;C4KzN_jSy>a~Jq+|4APtw9bC=81B#+{?J{NB&RaA$MJwFl>p!>ixh;P za{&CJge%K9=f@h0dLr>h5845KaRTv+PSNqjv5(;pCww_aEH9HDYpQmVq-MhAW+#=nwGdov-lIMX+_74k>e&e(wKRB z+*HGR+wc$$FpCG%D)Ww8X-Y)HkoCCg9T{)Nazq%-?CWRboTydw5iIoinym#Kw_=AO zaeTV`U<$+D`g|XUe&Fu_?D0>?3w?#zwAYfzFQKO_nm3F(e?`&mkWW$I=U`dNc&U%f zNQ`o4TFP6;c{zu@mlYk8lJC~@$qPy=bbWU`zkVoi!Gp{D{3Ug}&&(EEUjVH0Nprz# z>*ulc9aRugE`Os5Ojmv~7|o$HB-@Z!%%-ZT?6OlUtqvw{C`}NXvIbrUv~|hfCpI#Q z%*<1G2ZUT2n6(rLqry2WG{{+D_X8dq;8I%hmSiz8YMC1LMS5T84p4aoQ-?pKOA`l! zChv{f<^gp;HkevQgPq2^w_qxf&l1KZ)5>=55B4I;iixzL6tJ_k>p)i6A;SZO)7TkK z#ZLr!5`C{j6$`ekHnc7u0OXNvB=usm(T_TRi7k_`OfDv(>u*XUDb*7{MrMWD9yk-9 zaX^`^HOAzu0x<0DtiAOE`(>rM8Vs?6yqB8sho1tbmMkyUW=DIo%&{xXv8_vM#o69U z5)=?%q;the<_p_=%(ywz?{8|qA;_(Jhnm~1qoTOwcIXkF%Zuq6nVlN4 zg?KXhdqBXM!fBxQvEfk@F#B1Bikj}Z#@erc=#kt1>gRd%liG;Yh5xqOh~j$zmErxx zi7yN$PcnLM4L1MxmR$+ij*-$r^SOYPAdQ3@h-HbQ)dnQz_-<(i!#};yF3QdaTb{zZ#{>S#CFX z&zx)*hl|>oX25B3-vWhC%sy=*kVj0U@+ohUz+FR=2=zuj}FS(qV zd)EOz?Z{iG)>WiNZ@pPa!AVDqv(UG67?>^BV2UrGC@2hrtJ-mCTD@JvXh%lUQBvm?@6a)oDh~QH z^c6m;ae8LTAK(Ac1KeKCIRDbPJ(eUaaG0r>-46vDW^d(Z=|hQw^J%Bn*6^s|9ls=s zt*ut(Ni`6F%_Hf7Q8Y3A$oX5&kg_mm@p5=4!9`boa&iK zTW>A;&wY zvaQ0g=Zrl9l_D?W*3_@axZ|=t`9D-UghzuK-WUZ52D z))Ts{xL;l5#J|ebKF|LJ^KJOCDpF7v*C`X$!_fS|V`M(%Sd z>f;q@)n4BIo{+y-IGG6tb_Ou`oGT&r@@QnU*4vD;s&Qwuk0RG~j0)|3rVEx#i*LBJ zF0-7w5v)fFE^`4n!Of5NU@0Z5 zAd6)7M%qI1hw6>fljgLtAMK0>uvlMme-u&V zfQv}kV4rS>#m3@3U(&QLEn4@g9>KzPNB9!8N(v~(4E*ukF)_)j-!$@9qCF|pvPBsl zVRpfYb{r|ak=+x?ui;P2FLr=GYpN|kSR*8moatO;Hkwe_dX4eb$&+IEa*iAv%9d!B0D5!_QMGJQ?{i)PZXZQ zNXt$n4$V`LK}@1AoTM|=zNKJ2HmQSY^3PqGZR% z4|8cRN%r=@VF=|NyQOw#2;pXWk<^L&sO9Xm=cJms4gs&JP9zviE_Nlb&J$eabJv7QOjpwD%ipe zS|r^dpW2Ol4HlaWv(=({1^epEuQO!*18x{G7*r1^S`HazKZC)jqG{7WxlkEprXb?w z`*iZZRqG%v7U@8bEw2jwC3t>bYxy89KRI;%z(~&89Hk(DA(+~!R9 zF#n@5lZm=G&>sX8Nek6u^9kz$cd5ZMu%PRTOW=zR-LBlRgM5B+_(rrH5on8}QhZbR zW#$Yl;)VH0oL6O?H2qyrvOtK($0(RWL3K|`v`O)Z zAOA^Y$sWV=FcFi$|CoeVQ_dcXXfafz76To;pb)NRt?{gp%A2b7!SJ_+5$PK>`UEC( zyRg3P3~3_ApN{hl@!l$dqCtkPO^7!Kw{O|%1)KdQKTKXCXpi;8@p*<|^c`YWLf9J2 znSdaIzW}|R<|oZd^4e*d@mLLkQddpn0=w+kac3pd9Xf3$TW@#Z}<3@u2?I6~_+?>!qFCs#ccFv|wF5*u1t`7em#8R@BM^!}P zn}0U0)j*=m+XJ^~o>BGjExQ%AWtEL2Us@o{b!$&+(`YkmCwr-3MV4T_g?cHBcD}A2 z)UYL#z5dO|<2*Hy@p*fH?hc~ukt`Cd;MQ5~c;GFBdw~Ey-VoYk`T&6PS$fIWvwnc; zyU+E$x)DZU>U-$&w7}-8-)7U(dN0^VEyy`RV$b?6g_Y2Yh&^A8{38{9?N}n4*Bm@x zTzdT?5AEd$CSBjC%i%lE3{{|Ig=!?Pt8Icbm>kMV??^JJ#1nBEp&ZkgD2QJ#If0}$ zO;)uFdjzelyZarA-85%s65k(qQQR{L#3^>e4kklzBsFnS6-J>Fsy=-fjM@z#>sT&X zL=Ecw=FW==WgbIs5MmC_L8hg%+w%0llp7g0 zH)+!}79)@$SZh#_{_diSEfQQXNZN{u+t{^>S@ySh3MDoui^{p-l9K?mt|nhM`Ana> z!_;rguTo&-sg^tF_v_jqGt;@BxDK$0d$DsINrCsLI>?Nl%&i}Z|8=NU?R&XEjjzoVbCSxB#6}<8NJ{KD6J@e9}SmL?MZ2M6)%y@i8|H_a?ws#1~jD z6Kn*zn7+@Ac)5Ejpu6d3)@G}-`_YE;aSqS6zt0D}0m?nL5PazVQnc+fus|jitUjv7JR18oqgF)*826Yo+Fqn-9#gw2=Vg`qlKRPYMzVepgB6lk z$%NG8rZPr&s3bLtBzG&#b!Yc*XSB|fd4~kUofR}!9iHeWEa*X_nByR^Ynb8hz8MaG|t){_qowh+RYOYtTxj)9A#mFL{m)H$)pI>wwy z+Ir*YX~%cd^@Dp-2@u}FU|5!ByT?5_k0uy6~CEudctsMp?T)28t3F75EJH=r5@?dI-w! z5&N(*qcz+J&9vyUWG`DFTyYf^3(T7BHe87(7{SfEDy+OViVLYR`TI;}R7ScUyynuo zbHE$glvf__q&`;aK1!a)He;M(u|{g0LP~5U)0Ep%7P^pjgE85$7_hhF;$xdO*CRUm z;ykffT=bALNq11bOM^{ESILBMDwh*MxfRmL+#F^nIN3%3DqJiY;Z=v>8 z+&z<16Pjzy?EBB-*?EzSV#TUUOm9SAM2xRq15FE?+2Io|jpYFaH39m0J2C3kH4$%F zAK-YhkhH%r?I$pTBfO-W@D{yRUV_&*toH$5=^b;sf1o;7bwb>})I$2iNPcGcZXrQ> z!2nXgX%FO{(diGCre?Ean8zkrI|0$z`&RCWhz9t)gM8r;Y=ZPX^3{8Wta0cNJ8uuk zL;{dv8_9QiLhk|j^!Z=xC9qiEv)KQ@;$Xo4*Z7J&|7Toq|6AkxHy4~1oR7+4#<&0I z#D+-=3=%vNG?HE-#cqBcOx^*gh|o;1x(BTcGX^tbMg$8gQR5n{RFxVXb=Nk7iWFop zL^N2ScJov1qFr-SdsWq@Tf6IG)#m2fTi&45S)*=2KyB&HZk}X2+trriTDd!Xt=tHckiNTSy9b$!jz=3H7nl9 zR0E5~)K%=;*Qhj4tp$tU_R>A5mI#h6j?=TAi<_`ZqC#CgsdIj0k1EwJpz3T56Vx>Z zl6!0wV8~JHm=6V(F}+8re|~cA!LVv=xL;x@FJs(j@kEZV5v$RaY8~n=L(9yWu;Jrt}t6l1QFH8H~N%*|@12BKN?{frEV2;AL7*W82Qn5DKm zAk?1BG$IDtEw;~yWNwbLF`?OkzXnF3Wc}$|yRdu|f2&Q$2}!rh3-38=l4#vV{gFjE z1ixnx1*}bQ7qrvU|87YLyC6!Bi9*m3fqK3vjo?Zj*KKMLgGf7gYV_RZ@$|JXx7D*U z;$&8-Sr~xU$=mC}_-mz=g;O~LD<8D2#E-!4^-;k~l-m}&l1EFgeurkN4pbVzGnxP3QckfLE@kYFHVl>1NA5VEJVRaaEQhqrmM)jUu>(~-dWktgXw zU)6>-4zB`7{@c4LVm!sG1O544B z&#q@FfVoqJyjiEl8WOl}3xyD+zD}M^15mp6p)$AFcw6jZ4B%`VzB?4`&ZRW=ak>kH z5WWXcO!kCU+nzz9hYIDeld1Gt6h_EuNT;?A?b|o@*;R@M)fp5L(lq;rBol=VoNm*E z7vSR{De8_EJIEEwpsm9StTg(H8+HtblT zSWVu=xYCTL*;G06j}yvP+es%cL_e|pczR&0$hy2x)Ho5$MjWp;uRrRvU|nl7Q-^BP;J zcOKdPwEP*UBJawloW*_M`Q9;Jvi%dQy% zTuFhv1y7e*Y*_E%Z&VaR5##Fqn+l{N2m2#XHE@gy^XA8y-k;<%}L3Y4MoVi_sLaydk9#4)W4bKti?1H?nL9W~}h{ zk&}5RUcbzxbu%af4Z4r)h+|c*1QeLHILsGxu9Jo%uvLDVpZ z^i<;MRVpQgc*0xuvs+5=fx2tt1{}_@8{7jDa_)tr4KxigGHM@M)Y!uL9%;TQ=%*>w zjxHa&uNZ6|AcezNkED@a+-u#(vq&v__;K@8+qXY6c)4_RnD5{2)JWlsZDXq8ces(+Nff;;D z&yd)kReDihc6L7ikvLi$_Dw>AjsIjUs`RFBa|7Kw`mIw>@ui}S9PYZB4Cx4F2}-5` z`k5Y3-F1!1S%%mXIDa*ww`-ji+sXZc{7FdnU;%?qE~Y7Kd)G1_Jbu$NW^7Z*gz57X z&+tmC&9_jf*Si8(hC1VJd~rF)^s<1?FDP>Ug|79B=f<-5ufmA98w#GHiXiQWSuR65 zybUFtT{!#t<5RRp0rD>lf3sig+Q^90xoVUJjJi*d3pmjdswAAMN{X&6%lzK1#{7!D zNt_ax%e3onh%sF@qo<<_x{U8|Hq$-$a{|c;KXSz;xwAF9M%?W#vAp%)4|JTdd)b{dj z4NbF0SY>$tSJz)TH~TWjA+|<)_LR3`Q z$xzzhUfxkMnzYhw)`1#^yiucf9T7BKl{T5me1DCT-@%vM*x1N67O-yt%}}8dF*=qb zPN7czVaCeUiCS{cj%-<~;!m6%>Y~?aKN5g-WAQ1`IbDS%m1<~v3N`Ry1{DigN->US z39coT>bHiho_%b%YzNm6sHomWOKq8@Z{gbPgzHF%&)JlUjFKt<;(T^tj|T?+nr9_t zv$kSE+K~9kwm{xe{;|zE$;<^3lV*h0?_8>yYPy*+J$nt%DQe}!CdqoDFA)ZKFB8e7 zvOXzitH1_ybIQ&zggK)E$+-zDx7Wh|#o0RsX%?7ZQHhO+qP}nth8<0wkk0P_fFi2i9XTYfA{Yd z>)r7zfe8mPdCqFrG6|+bYSViloRG!SmN3cK-}pc#dN0`<&!VR-aeh2F-gJP?TxK0D zY0;(8X&y~slv~zQ7id;7U_1cez_hfQOWY21gxsY8>~RpNO}^W~=&KJN9m~mfV>YdR zR}}`&ne@EesMZ*nZsiC+WaFi$;e>8b01o(frGwjclejIL3Eg448-Q=s1Jy>?YVzMB z->!+3HWd_7_ho}ctfb@#TN+$El<3y!OePj?ze>{^f-VjYrIxWU84uwcI&JMNGY>ot zVchnRih&9^@T#R^av6`xON2(ro_dJ{GnAj^k1xqTW-=bKgk0Y>C7#3ksb7wL@pjKI zl67w?V`TT#!4)gXc9YP}zwE>Yh2=A~meCn~ltw#!;mWr92tDTG2O-1j!}_JyNyWtT zwmLSrn10!iQ*hF;FUan!X;qS_;3j9!KJv&H?D&Z=Gd$ss@@(6TQCBm4Gz1bT{aL>K zD>JTBX7&58$j_PYnpdZ0^s}^zzjwu-hH@rzOPZj|0^1OV1oAZFZ;pMz#1DQ@{qzse zAupjdxxn$u=JrcxUHF(Typi4gu|2!c56eO=TOeW%)<`ut-Ix)Kmt0f6h-;O1T#PI| zdz8aRt^}ps00}XMjxMg2E-u=i-=!u;Ek*gr9^EXD?53nfF1?2ofc!J*cC{dS8yzdt2DrA;+oH>V#HCb^l4AZKX}}j4C@^pXAqb zUU_TiGTqUBD5`)!G5TIy)a&*_t(Jsl2KmWd)aHFj>3&P;QLLIs3p!jCk@6!)UX#sN zNm^cEI!YHYr}M;*i^U1yE7_Yq6)-b6v}}%w9=BiDaNjWtHjSxSGid6w^RV4rys|rI z<=v>QvontD>2;eLzmTNVmnE_Afoa#JS>>FcUu%{(rJS!tl>SfPsc*{oG(s9q4 zafkYl%fIBZ88tov7{*p?x*26~p6_jyvKbFOshLXK7Ek!Wd|s& zbyVLtLtPA=zYN}(1aZT&X}B?z2!rB)Xq8EaeADS;%vl_-LJaG($9it^^PNT2uzQ8) zC0T%CQNDw%FT`ef)_Le;e^55CDA_lu>OJ?)EGIo(=v_8_aK5Angl;rAL5HBU9JbmL z+SXhFIw z;L)0oB4f_pmEq1(!5ppP_mf)TW{DF!Y3Hof*>m+GLtH>J>Rb?R0?{=e4jZwf`Fzvs zT8v@>;&Zf7uzzGBcFy|Xo3WIbbe!E%iAVU7pbr4nj2{ZAk5jxDpFHC%e%^-Z9p}f% zMsF4oOp_VM=A(2Q_m{4pt}dxbgFpRbo4uB!f3pqf9`#1=b~R#ynvVs$!{E(l;qSz@ zH_Cf+*}-2HCSK=^UKzQz#I|-O>kCcpfO=f{Ob-pF`i=G=)2g@yTD=mz?@$^(Nr2r$ z&3D4Y?r1pIa|fKFvLVpCrj74 z5(f29Fs?-r1@T~GUi^@GPvr(-neNkRZ%X`*>m$!TEe!QDnDUvJx0Q z<%W|EymXRgwO{GWN&H|?!o`743$r;5L*`mItBSBQTL@>XeHT{;Z33s}ejSciIs z0P#qq=SD`YHe(zu7Gfhm?^L$|y@z8Hbl)2+c*iVeE@~#S%SuRgwO>l%IJEl!DHRGY zgR~Ko@W8b@Y_;auE3^|DpKQLGs3(qWELjh8>8K^M9VAB|>@;>dtVJL@P|%&lUm>Zb zR_Ty!#U<0MGGrtl&+)rtb7&03R-H|a8w@fV+w`rVSQw*Oq$iT@utj#xdxVo=1QiVd zzpYkiJqH}BwALL&+uBsyF8jU#U|+$_yyMh%N0~o?O5O;m)&Tu+>25niWZfY)Zwv`{ z$c;H6?7Zg zdNo+`k#N^DqK;Tt$(M1As3}Vz^GKW}-yvc|-AQEG8KLZ^RX7j-;SH!;7*P+g9jj3! zI4lwu-zP3AkuSZpsohHvRQ80i4Y_74V%ymvHryevICn(!lH93I z@5XpY)KM_pUI$@dDP9L9=xT=;GfdV@4_AbS$X5>YRYY>qLuBK1!)KJr_SB%nBz$bj z#&ujDcV`4lIX{Vwgxniz7qcr(;D}r+u7{=MyvS;ov2byraB+35chKJyN(rT{%q_#d z4A_oU0Z~R4nX8o!+S*jQqHe$%1t1>=^-Hkt%8mv4xm~)_1$`N00Aw=+`~*!Wah64c z4B4RJ;=vbLzaj)1+VUYIb4 zm&GQ<#}mgHMI+sL)J7&t7zNPkd!lW?HZ8{!JToZpGDu{yF_S5g5}=R4GfMBXf~60&@^*2ZFW`YF@83xQdQA@y5*(Mh!shup6i2VMDD8 z*-SoEp3JGfI;3oyrEEBakg1e-N*`Wit{s^$WtacP3c(EPE!~~ajvl)TL^$CS!MI+l zuPYr;D4KRu>D*8{z%o6Eje(3%bB~d^9k};kd6Wy`)l|8a-yqi!y99IhzzcPO=gkGl zV)^Om^t3+e9Hn#`J$R?~dWy?grUgmni_T1Mk5L*(3vttzB)Hxgwp$lW`!vs}Zg^m$ zh2vKhV;Vr}qu04f#UtJrIforsf2-4AbCZdAz#weg+n(#gkRb-Oojs*QW7Z#GaI6XV z)up5rGhx}a^}kbwUb;`#AIi91I-dK(PBm$7hX1h{!-K=1iPlDfW%0=Pai_;lG%uZZ zBJ(oy*tikH!u1S9G0n?~eC~&s>)yV!Ca!TH7dBf0mT*-3$wg98jNY%!%CM8u%O!=~ z;Em^L)Y?C?`{&IM?w9y!5;71FDB%C5t@FR-a2aVkJ1ZCa|92Mkzpm{m21?i>7^6Q~ zINC^YXchrv{-OW)ohHzRZZSu001xEB=7$|7qS8$Ss|)U$+8&nJ{ebj7B)@|$R~n4Y zX`tgeG;_qs>j?%T?3X5U>-u~3$o=Q*w#m!y=kKW=5So1IzEOJ96-dj?MmGL6m!$&T z%7jSE0nR*=p8BlTia||f2B7Wr87YmB0fukYZ*Do#7Oy;O__X_o5p<%n3f(1)X=_{$ z%f5w$VVXXjL3&WfRD9&`lY}*sIJIg<*xslXlraU&x4R+N?@($eaQZQO7Q1xsB3I?3 zmsH(qgaz>(s`C_^ZC2qwEEFBP*l>fN#}!;Fbmi1L2thcju1yi!G(r?=boZ53>ZQa+ z*#@OrV>CUgP1hNO!3>1N1NK#QE!62lD3CsVI@2_doP*cxsb^4jzq{_X3-6r~ZVfd> zlL?n0RB6mMQ)x+5?U9*ags`)`LdvM)UYlc^Xc?Kb8Us1UGkZgjjSYlvS57BkZZ!mZfCOyXLHvlz2%D;Mg zy`olpo-t`A-{K8E{MdB*S-gdbhPA+`yi{Y346$(2g}wv($zc-11;IAOa1|&~w0oS} zYt^*KDG1>FMIk{m$sB#DWJR2!8@Wn#Q8`j7r(a_{dtGb?b~-Eo4JTNrDn)}OU8ypZ zfnbMyOWT<;`}j|pX&g+V%njM+8+43a>)Th3o*6HnP8*4)GA_2>;9y`L)(l(Wug1UG zYi+yaf<+Tfpt@$YE-bonJ0)&+TEvu#_{w9>bx{lH!ku*VFSAC8Ctc~@ zp*dj?HdaMD`bQ`uu0Mx4YT?(>TfCy#FipgkAg@^Me$lUbWhYqTKa#e-@J2(>hz0)0 z7=>C)A(Zf>>oD7*8bie1(iI}qQK*5C3)w116f;;c3yD7hlBL^7^?BO>EjZ4<$@ zLuq>yY~KaFpN6+D$4sUio`e3*ZKO1BmXl0X;h6UETK*eth62k_FXZQ6vi0k)^hY{SARzt!C|m!p3e^8iNBMA8U)U-3~WA%8ai#Yl&NB~&w| zl@}rO%ZA40@4{5o3n{t_A-%tItKE0;;={@^As-E>{$n1$rb8SIQM(O&KL zdOhO)k-66DYO4L}Lb?$A($r<=2!VyC=uWgr`g)2W7ZDw^`l%#yJ(Wh2lmZLk#g+w% zph5hsxEV1J3GmHpZ&8>2NHk19b7CG}ymR1wGYnT|yR&F0C`8(Z3H!djd5l%(M}D?c z#Yl7F1X43st{nAxv7x!Qp2~)#Tnmv9$&PvHV6tR%e@k(yVarxHenqCZOB}iRBZPY- z+y?nH4Ji`xhEt*}sidUmaj#}(!dzq0RCzE2 zvY8#B3f8eW%iDSNm(xML$p8DOz~M>{CL62(154x>A-C3c7FE=at-NsLz} z4&S3Pj1qJ^RF0$wk=wH&(}ncjn4n6|!h5ho40d~p2jeKcs&eS6N{O~y2>JlsBe44W zhX;2?0Yd$pwryZqPa<*aGX|wfsT!^^AH1MWx(kP%_i8in z6ctx}ucR)mj~}&RACZGkl)7|J0N6|doB7urnzw)am3!7+$B>X#@KBJJ#Ad*Z<(UBI zzUs{48tivqYs|D~JDEc~%3Y&{a){a40GEnCea+{T?9NSESoY})$L8hC_9&+p92XzQ zN=KQjPpxE67S|7?TUL_Nn#SH{PRR6zs}f4!U~70`@fq(zv)XIFo7(;?q}B=Pu}8O7 z%p>yf{wf>Z0lIR3NJcz=ErGct>eFmGjyEA_XUH3ZUeNp*wy zd{)5=Bv?!I_m-e*B>kk|sAvYrq9yV!|OSCF0s!JsU8>J2({=iV`YEH?AW@6h% z>}w7wvHzPzpF)#UHvYk)+W)bF{Xd(3{(mg`Z{loG)pA2tLHU-&N@vB@{A~jU6=2v; zW)bn5h&e$@tIv=^yx{lq07*t_0CPnWB-&lzD_0~@+QD%GIv#%sSXb)DiRL%(Pv9ha z+HK@6M@FedWVMKnYmMy5RnzRw?)Qt^Oora~_csJk+@2LIUV!}yUUW2js|6hF5fLPD zf*dK)`4&Rnc1E@Z*WW4Q71`_NrgsBa-GKMeXk<|m8)I-{FQn0_V&eSu3G&hL_RMK6 zRZgTfM_J|k%2li>4A~u4umh9DhBqH$J3xyt8&fl#3A^aPSjINxuX)<~`t>mheCn)m z7Yz>L1lHpzgMbNjMjI0vvnGBKsd~A-%?z0gUYb5ZSl@t+ib~E!n8G5sXJA-LCbM-@ z%T41o-LR4)<@iAr1b2Qh7U$YHEzBlzzGV9AFUA^wzFZlsbKb$$qcxV9!;ho;?U8z} zTx=%+53SB1A6{jG{31jaEY;sjDTyf@wxuK{yfk9`roQr{I8!NhRnE%&qZl&^QF9wN zVan?S#3@v35=v5Teqw%N^>RY$`iItCheE$?8sqg@h}5h04FWRHYgQ}zT#gdP!7j88 zjw>U<*IA|~il-3Qw<8ZvB!0>Hh4p14i*m}{cn6g#iBA-M(e`I7TxJ-2#sy}LChL%9 z7D1JFZV&~4sRfK`ndXT({!!7NM!W@@U5Bgj=~MX3u6XH(>K98;;-pz8r8)DhK!4S zI6aR=7h|zH@LI;Qh)G&Eh=QpOTB4g7ttk$dCP)_FlQAVs!$KP~#EJOm^*0iHOm%Jk z!m&h8@VNZ`!lEc`dF|02WpYo=a%Pt+;6M^|vqvK^9-h5C8x$C!YX4oGB|;EjnJcE0 zOkyfB?t=@T$g4C8WH?mIiX%r5P~_-DmlA@zn9%1CaP<>w(&iJpi$Ho>jyqqJ_qGYU_e#_X=$Z?RA_Cya_^yCdUS9&a_{*MHuI z8_Gy0t!^`+-l60Y+J4v9Bi%U!J4=eiKYK&KZ-^PWtIr^$wQ+UD0*<=fr(bo2*VD6OwIiR#P3_jl zHXSpMfe|QiHe)QU=`=Z6vY&vLK~V$aOQhOMNTU(M62nt|$Wx=G_e0jm@Uz6jmD?_h1yY2k5P3W53F3LKZ!#7yOR>e z@V*jd*WegbFbqp;b7bBV+lrf=J!POwkcHt%5|vX~T^Y%<2a0wVZy22I-pIQu--VcU zUQxeJrzC~~gGRHoM^{>D&m={%03Bxw1z17E`u*U<$|NetP2(zoJh+Q}JV6-!4IH+p z9QG&r0@9kWVbeEReLyJ%T~noqc}_HOHGV@JvLV3m`ImEk(tTRF%E0VuEzyRPbET`<8fPevm?1MaDZS@u+lbZh6>PPDZ>d*(Y{se)m|u{w zdZBtjd`J`vc!S=vK0^jCKQ~^;DEut$!JQ?7VqX`9*2f)|5^6spmFygE8K_}S@LE2BCHDyG7}khX zy#`qPDW+JUHCzlKYL-9y5_@d_wi*MSGqh@4vUR3X#ypo_t1cZ8G{v}$L2XTRTTGb) z#GfC)Bz0;ORomb{_5SQ3pJyi=XGEVt4#vey z$YV;r^~a#G|{*!7l`zYN%zmmfST z{u;~qngq?Hs`=%LErLDxC7@~#7-*ZSq}gMsNq#tuT+5M)vb$xV;+h7}pMR}izL4vk z$swQCQmp#~(4o==YD0O4RQ}twPtE(&;{^VX7wtcWtpD?wLde|2$jaXCUyB<5(-fGZ zsAIQCkHVuXwHR6-A~?zhqbj-~1G|Z=h)A~_PX^|`#!Rx4J=DB|R3@oC6n78;!G92d z--nF!1981kg#m)sDjr)`H`_7FySnS=^98OCeF=w#!5Zm^)4N)N@V-eE?ZGW|NMGgn z5l2SEk&UKkp>T7wSlxA=KeLB_=f*wNjulpS0Fq!10UK(Pl_K({Z7O)LJtxf_8k##+ z`8Peeut^Fw;#HZdB99@s-y^)oC-kFSTm%{>jho%Pv)o`@2%1-jmfpWaoa){&b+mBn z(18qNLm}bLIxlUZ`gFXLgL7~X=VM#O$vKzAuo6=>=uA#4bUwnRt25b>`>My{fRhq- zf!)agxea%V)8w9EW)OGF#2hL`wXP(W-Z}6GwFtU2QCg3?Mhdu;^d$2q9%F0UP?fCI zAo%RlrzpT6-ei+%JTel4E;tvZB1jD8s|owC!0huiNztBG))liGw?vp@!d)c-ih8LP zD+XG>*RE5{&Luz;8el@F_!PWCcKEW&*MI5Pe;^jsVeRNTTJM)HlOWbGuG_DYb*t~8 zYmybul9?0p(lXnAzwZ_iTJqWalwvfNZCmK|;!oBY2hloIY2tbxf5N$fkZ(ttF+A@E z`cKrTHp6kO`~m`U_>Wl+vHvsF$QU^P_qgmov-|R9mrW?h4gw7*f&?mT)k9-(@GFNqX@m;fl*JdmMt98zUvFWi_5j1s zNE^%-?4p$hx6U+dT-H2=jSo>6EK53%L_!_jdPQ;hAK z&nuu~A#n`Kw3<)*23v(D_{il9Q_RIkWkEEE!*aRBC8yofi)dx-<$ido(sGIW=0~cx z6WQ6TneX}LQAQRSX}W(l+YIR68Wan|6>D4O@OYU(f9hnuMXL^>J>1U89V-+mg41J) zt5L)?Fo#bUIYe}zAW$o#`thY9xP+#_x`b#zy@Y7KN;`t!odL+`@?~@&hU@*zt_}V? z)pN}5o^dMGzepQ9tA$n9DHE1mA?wnzvERg7RBs+4T=D$=1q%(>C(6Qqz~V3PfATrf z{~y8PzfF#i-q|WGKY1C(z2iqx3uH3q%_TX>t?QYhoxus|$FP^Q|utA{0Uo`UaK{`wVcIFB%5L_Z4E%ZLyNkev!6D6OVOnAcTS zh(a#S7!_^3J(a8N$ajETd^8)>lfWz%$z%sf|zcCFHz+rQQuft)lsQc<&%7#?m}tJVnI)Y3goU-hIU*!9il z!V;%^7^=mGv?hOGt4C9eL6W)KE3hIf(kUN~da2M8*J)3=hlTTGK%yq0@{f;u{VM+X z%MI zFp-9c9brTkRw%GzF;8AhSSOPh>*@+%Wmq7Ns4 zIV4DcvtvP%w{|oJ%QhW>ZQ+sAc3}Ex#C(tH4VEiNZ-U>uSIaJMWtPo>2RD93h$gXBBIR>}UM^39S4ZeAZbrP0`*F!G#~ z;&@09EMAtJY~-g3gIx(k-i{gNH(hVd(Vq6WeqRctmyfSrvO$_o!Q6r~e)du#mt)p8 zq;Fqb_&tFD*1d>UY)8d3trR%EszawY?ijXCE`&!od9F(kDqnzMJYU3cvug`m`8E9I zTcBbMFODSjYJk`sDQq0n3^yehuAXXJmY5TRj*N}B^yr~`Ah1KTRDt8zr5!vru${6Q zZ@v+V0~M#k32g%ZNkR+M>xj+G#I)tP0B+bFi5*J?UWoCa(D`r&DwVU<8$4cLdozE# zDz09~;v#449;Q-fseL(JU%3KL47x|md+=puR7FmayY8S<;Dgdu;bE0~0HT72939I# zPPlYynXs|b9zB|cd&HY77Uk?Z9M0gXviBEf&@=N`DlTRUFZ^K^r*40nxvIcmg%uK| zsGtSmYsJ*uTfJO!?;hsE)jJ;8UDWIZ*P8G@yMM}DlgLF4 zqkrv=!n-%qyi?uGg5o#_=**stvHbz=0YdvZF`-?4#@3fo=r`CD!DXMdL2u|!*LXct#C z_Xp0mF7Qq-QF08yaNC~X>{0CM4ZC3aRIS3cd>0k&L%UZO9i*`;ZdL8pagUZpk?&{D z0oaa7;~oa~U8pxn_ez-+Hgc#PAkS+Q7cwmorcNS;Ozq<`Kp1|~Z;+Q~%f^lYN9lfc zdaUy-MgH8p2aD%pQ^1IP524)!cBPM17PB?FL9EVkxZ)i?X$d{ka6;c z6hENt;p!S*dM<*=u+0l-u-zPaQURX&4xCC>xr%ugVunhkxz%S8w$Zz7UOobKKh!M9 zL6`ka2TOGm{FhQ#BK2$l*BNlytl(eh^f-h?+v7sNxl+98WMv&cWYdLou5Y{aM~N`8 zGCrnA>(lFOtwsZ7E5DhufV0DqLZhI1yz(XqwSn@h+GcL3Vw^}IWAs$&K;tDb)kFfV zZR2ESf;^J|wMGU>CLdEl@d7mF=N4*{u<96R1YaYC?zvGExw72e5Vvm9V*qPyqDZFF zC@Hp4#Y4!B>zCMZXmT>@*?EpwQmI9sQztF64%+3u&bOPQTkBnR4ch6ugBad&gFqT| zF@xU9xTp?5d0*NHDqptjKs*a@Es4vz@CsTaX_e*NF^0hiX84eZvY{Lyl2Y5$NZObk zb%nzGg{>>8UTCs^ck3C{AO;a?bg>@!Tw}dlQ1PK^+y%H*IXBgsM&k zMu~+;Qa_I}k|^A}l8QI*qvZj7MF_;EDb->gLu9;o24aTyS<2L|9)qj2Cs%qq>1eH?pFz9xjGt1PM5 zwRtNia~>F)>Seg}3hQ~iGLyY4vCAU0I-)jZt>PM2yx)txC6l_qQp&V3E*sTeNEttd zqW7|^HD)MyowA24-p(jcS2 z=8UqqpfeVQ;Ym+VT`&{EGLS`-n#S9fO05%f$)LNu6WrNrC_Ryz_LsLtk*<9K;yL7a$y0l|1IXSzuGAFMb z`Rj{28oC^GjMSp2jZ~D(q>S3Sind#N=eIo_%%n1e4jko^8pi#ZDa}|8tVivw&DmWU zx?tGCf`@G!lzTW`#JF`$Z%Z$t-6pH!^fV?I4eq&^Fm05~ln`$$bYe03SG=XIVZc4y zOew~_aoWKCPMu;7l3Bc0*UHY4BFEL0Xqc4VsDR}L;GSG|6j5{I+<#23MlOu6HEJgi z(RT_F`V~iXR3_}7l;lEZq?w4}CkF`R`E|@W1P$N<4PWGB)rj=mV%hwHifJ7)k6ONL zn@1}O_Afxt4$Alyt6@w zHWXA^qhK%6M0tSjX##p;sXB9^I{Nh$Orq0D)swNHP>a<3RfYT&g(@zfHrjUrU1N{$ zss<7EHj6DxwA5JaP|!0v&n>t#QyGP zQABZ{y$ztVGSYpjJM?=6*#ViW-O5t9y7t%Xv#Knyi_N}P)v$1?pK^&(@ zx-T)cQAhu3y}JNZG<<%qLgo%YY}B}LDCSM>pRn5=--UraZ~R7MZxL!&x`Vl?ZCg%0 z*-9ps-DFzB9_7)oykH9SIkYRc`Rt;I4ZCm>lUKH5gN$Ln7DM7$kW;FeEw-Fv32>PGEx7?}lv;>HS*x&;-TXXyjxU99^mE1&-1fy7 zb=~y9ef#F&A<&{-V0{8fb9k#}&Q#Z$(8@X;z#v9si==Bb*HxBtNU}^~7 z1mH^o=mwy^HB|S>rEB#PPQO(+ADA`b+D+JgYV*eEjRk4{!T*yudS_)gTizYMi{<)N z4prw!W3U=B)U)mgZsSwnt$Y%$^wm}7ovy8!LUt6yD0i|LlqFAMHUX^pS67+b)9xUv zF}`t);t-KCN#rRH*8}`RNNaJEr<+!3C46JTsh=Rnh$+w1Txs zyYAfa=Ztei|1uKOCv7AV-fIr9-|B2vjraX2cEBwr8vb$gM zE7<)?kr>(i-Q#x}5r=I269~<*8{&tBrEWse&Q%g{lMLQjlEedDkxi|$AoF2jKR(=u z*+H4bblPff8}{qG!>%a#BfmizUrhHwa`Fg?D9EG43W@%ZAXHLLMY~mI0K+}Xx=0`Fm4adtrjQEHM^OR2gq)hM zXRayeO%7!xVOE}U7E)fSZ5=83V<}ymo_zm1gAsr_r)b7VRic4fCW|etIQ@kPHg))7 z6@fy^nBE6|nTa^*Au8$wr1O`)F7i6GJy?vssOQ4}=_(}0V7Cxuu|>3mPp2YUETB>t z>-0M4=3sQB>n7>;!DtyKD?pf(Q94=y*ZUYI?sbHUXPPiiEm^A!EP&OU@tMxRN-AOOl2K1E#s6p6PL0;^qGsau$$o1RQ zJqzpO4m1Gf*AemT*yyDVq(Ss{*b(wkNn-$rW89)?v`Oc+&xn{d-c)wfo(gAR2c`d8AaMEQ~qn>%*2>d;l*1AL3qHVg@NulPGu%pMyVK4QyxO}Up##>`F6&VEf&Qse3vw=~X32&!9Jt96xx# z&JaPzt{m8D$Zy?^iFdtFYz;j*yKa)WH%U(J11;`?fW9QqO!TqyuB)G9{s$?I*(YNV zUt-(r_!vb=tt>k1bj4=L7H4{8yF}tQ^?7B6ZF5U^w)}nl}gKD zsaD8@m1B$~vlyh(q|OxvkVYjVfCMv0aI};=QlK&{bcKmi{iHAt5X&49-Jm4OxyOjY z)7x~vz%)kLp-CF=k0)2Ak=(xOY?TklDgBXq)>QMxO#WrVgH~4@H?MVEa<`}r>nj{H z!+0}q%%6;miDHpYO%JN56BC*Pen(7?D(x|C$du%qWHf8Z(xLlQvP({1AJjbQd@&nf zRFx&}*9M7rcNuW;BQgQOFZ|Y0{)1&maczB2AP^+Gct2%}P4V-~qD#;c!y zbuJ)_M+G&Y00F&F{iiEA;D0Oj{Xcb;9MwxFWEGU3ZIbKONw5V7g79=f3X4pnNIGk1 z!+d@co019@O;on5O=p9y%^TZ%RMcI&uUb8qQYPLJ0m9$qN`LP9`6fJX$Y`(QQeogHqY>zsU=qnx*$gl zrlL?K{WDE53X!m+isoaeQLgK?VT;5g#RctNZ#|X!#=ZJYgVNNo`WE_T*K#87={D4S`FR16x~<6x%3 zW9k06>;{)}-o)n#1r+-<;;Ro%&g;kSduG?xnk0D(z!xQ(+;p4iwU* z?x#P-r~nD3a%a1AQ90}4v~Ls&&!F_g!tHjjEqB2l{b1@cN-X(3icru#q}Zc%<@|M3 z@ggd>g**5x6}#XCezD_|KO;)xQ1$3sXR(1u)C(2+guO9Hu85kUGI!W1Dvp_XU5z2T zBD;XEMJGV}&+hE-AJhe^1@@{vFsjweW(Q+> zesH>TLOG-Ji&Tt6fQi`eTP=p6d!m_?5;2x03ND%zhTOzvn$hs$W#sGXbR~vJHI(kD zxqnWEoid0fhUP(L1~uF-xl6XLQ0N}J!`2})&`Iylhqy3EB$_;chlS!a$XVXx>mj1V zGoX4%Qy^GrcUykjqZkXZO3x8Elbg)0Lavv?c;WAS!2AljXg4F?ZmV1q7s^qX5qJ*h z;rs=Y)s$PRhc#D9y;$Qb$RusyA_tpfDN^+`dttc2WF0k<2HZin61&7`N6f9QDqno8 z4C2tHP=>l#Z<0FS*Og#Hm078Yt@Skr`2NpWV=mjwgi(q(=^oO&%XR6Q4!8=gE# znuy$~>MSyp8(thnv=}SXkfF#B)OIxDp0)4&d{*tVA1QCbGg=Qt%|M(K>mxF3R zeOP}FxPH&Hy=T+qFZI@14yJgEU(rK_YVlnGaCWkrj4iR%WRpOU@?8)4O0n6bUEw0^ z6z812!Q?Hr3GCRLGnP_Mr|8)6e%+GJETZ{%WYe>(qBdh;r3IZQ-K=ucN?9s-ULe4P z9rr>EOgnD=wcB`p>OdD~s9_zMUd`N5kNA?ZKb>WYs z-5b)b5xPLOeqw*o+Vvs+U~VHX86Vlj@3c#r{rfjq<}?IaLSJm=ZirKd=1bOGQ+57b zAjH8xhw6pFNu=55kcjl|@U&c{^fd6K-OTX1ylM2ZiRc);I@$#ND@ae5y>ttmt`7+5 z|*T`fyudHef+JZ^+V=t^Y10vc)d|i~0WToM= zM4s@0QELJ5z@-QR1>@l&2Q}2hC{Kuz1qzaDq083A%OlRDGrI*lao%R6fSL#|bIH$` z47+?XG;Ok+qef^ibK@b6!^nV?w&PznZ#9+1RI8SKzmkt?>XwJkTAY;)>1wC&RJ7rGWT zH99R`RW&WkD;p~tDHA_juRR`2Nf|WaKOy*!J6mpPP2Q(mr#o!khhL+4B!wNC6|z{1 zPxi%Kwq7)bnLIl4op5?$Te}MA(Jy;V^XQK*Z-u38Wo+e1Q58qryQ+FRbLbbfT8j?3 z>zIp_dFR3VX8IG4Zo(NNM^~mY>q{%y*{H-1X`q4uYl@{R zDnc?m1MjA_MvgVV|H{B0D>Micm4ha#O>3)(OB=y1RPf)7U@D8_l^&Gxk6A~&I;SVJ z^u`i2<7}ebJb|sg6a9L(W$QG|0-57!^IuOztMT-nPscQ%3b&0N{oJ=9B%7VM&M~#4 zL4Xr+$sA)gv3JSI#pBE+yHp-$wh;!WKLgDSROy;dXFFnR1Ho0<$>2DK8*{?!Lc5OQ zVU969W6rU7sLz3|L~6S5Wx|RIb_pPAId13OY*HxBH(kC4^C#7x3?sls*du(5#}!RQOv& zi2xVeJf*f|5%1doBkswT!84>(ng!VBxWzDG1`_Fa1oqH}cl0DxR8xwH^_etYm8weiu?sAm?#`kP^wE0m#1kHXe=3Q!N1GSc}QA`?h-JVtFQ}20v`ER2+K_sofS-RRigB{XG?O?(UPhB(YcUP;> z6Cs?74&fyEA<3+0hM%VgY;7RGgMOJ7`vXK}3`L|(h8#6a2sANSgc>H)+a0qK z%N!%a0L5{U*mSsiqFEKgh_Fu%LA-=76pqcR9TMPv6Zw;8i+A;PZL2W-0;q;D0>zp% z!~nK4s7|Ddp@9{lB_x$~q2!uc)-$XR8gW!K3)Uh9J+@>$?c?bYt(UhK?fj*4Cm~g@ z2@SZRx{}LbRyO);97=3>d@rG8gY`F5h%Mo^Gv~+p=O|dlAls5nea5?r9-=wc?6+8Z z#gpmMP1sH$s4ybC$&Hj6+R3cyhXVf_Ln`>!OvJoki(^*3W=0_JXyJn%hDAE-p3Qt7 zXL!a$K7@err05;j;9}Np)ZsKA=_Ezjmr@dmDx3%6$V++ZSbaql44}1UM2F-%FA7fP zKW2ZCQ|kW+EkN2~_YTP|fG@;t7D+$1fG?XvAdrW@a)gG`(5Fg_}sfn zSMVwm)Js~x)@d?5(#oWo-8#Ry(Ed;j{LxzJKUdS}-y3D4R>Eg3N-eanUedvXprZZh zvwwgOl+Y3G{ady+UoH5=cWlZ1spV_R#c%^3`w4kmM*Zfdf(<QfJlQMRFkSCBPZT-gpV zAoMfUTu5zX^#Ow*Wt7p!xOh3w4OC!mr(VFu+9SK)gnNfFCDYn!TDdZoBpsZZfU&8@ z9Kc~9+*G*}IDZ)bTJ6k4KP!C*6~x1h2v<9R*VFS0n}>I2PjVd!%^6HE;LLRW0<#CP ziMpPrLiNdAps zg~&t|Xj6w81~Nn&v!V9b6M4?zX z1iFY>nhZ1e3unqRVgE^%a_Q5_2GlnKvBHMQN8p)s(pA*QG_LXL>-lhiO1343XP^}}{#WSq!GUP0W1t{xsH^!{Cdzb7k)C|F_Z99b8UV4GJ^Uw6=vls$`kvseRX*60 zW$!dxL)bkw8LswVCSqg2GBaD_a>hj*SIb6M8Zo}?ZL}; zmljI*oPo6`c#qo2d$f>AXPf-3p4}B?tQ|1+8Oq(F*ZM!wN|zW)m#e_u_d-31%P8ak zj=;xFcbnHmr^REyV&Bfx@vA%QBu0KY6@Gmbbs=$aiQ#tP6W@fpO~&1xORos?s4s-S z&|u|s+%P(5p|zf!x(p7n7U0@SVgLfHXjVVuGwG21IwE6=1bHux?Loty7Xn{SKR%o= z-zcXKu2=H4DJE^>LTHzQ>ZKqhy4Y9?bHe-lC1N1n352&?=NO(!>t1W_756JWrLt(5 z#TuP<4ifGMMj-H2V;ynmkI;fcj!9pix*JEu6R7SZ7p2s)SLy-Ha4cGiH? z3gcdgG-uX<_x!hMt25F8QPtvMRJ-dXHRse(9qt#1|B#nl&#&`n5P}lyGu2AuDc@xM z#SiV^ZqC{5Cyq~H{`mr%Z}=Z}e@NA3<58apmhIQdFvR?ON%k$4wb;YE2Sk^jAEFC) zMi1<-#())m;bi#6kQYQUwlB#Wg@n8A#v}O1Ij6D(p@L|vCOs?Cx90S661;e+1bAq( z4dZaNv8d94g%~{=VuQH0BMH(Hwe#=Eef_7Z^`;F&Z!_|O3-v)rNthaGM%v9|S2x$_ z9zP1!_tJ>u=+`(^JSx`is;!@^j(T2FA6ZaXN)c9&4CLL>+hgdbmouA+c4hfD2^Zrpdyzy4>p=vC1gulWDbP0HO7f)`|y=E zcfix>O9vh{VrHw1i`J_uemjjr6;>a-h&kmgV$u$JUniEEgN)~a%$L1SE zFKh9p>N}G|hf&9rplea*PY2szTK0RSDGO1b(w+?)B+6ZcgUHD&F2^z`#@E1Ry07lF zeaH78%ZVoGnZ2P<`1KAW4p^N=!w^g9G@w z(F?gPTYBXtf1(7>GJIo`Mi{~|ni_aEv=WXtTj>*%^QKBe(j_mM`F%(4u8^*lmCv?v za_jUvXj7R6jcR6gWIgu%R;7xz#moVZIdWEYb8<&>a?Ys@*xmE8HfMIUvd9uHCpcsK z+!Lb4`FNAk=>fo0W^gtN+HCn@N!$U@KURlI9a`;ot!V&Bh&j#>mn1*>>l*% z<>TZ7@}l~?`Nb?#UC}pyUPr*~w}7tlY3u2`hJ6r!M*iF}pOEM0Mdjlcs7uWv{?hA` zD|BZ=JoVL!7A$xkp|^Pl0+zu5KXr9&#Z6h4^&7P!puZV?S;%n{!KEW5P|FgJe{N`r zDEBp=4oo4;@|Tzej93Lu59Yi&kP&WoH$MFaaB7=zTJ(KKwA=2%*c84GugJ9NE+k;28a4xKEsk8 zmIsBA4Iv*`JFiXfNahjpG%-*O`8Q*V!$r`v8u!UXvy>eT%pQPHCDg%t37dOIyHd*J zrobDIf}dJ`IZXt?@etO{g$~`HjPe1CZ&vm0wrJGp&G?yhX~|{Y>1d5&SFUJz#+G%c z@o)5`Kf{23C4MdLXAYPz;?GqXATJ48kz(7)!=DiQrB)LL>$BR`uXA4QbW@?P+FT1h2*fUjar zz}GT-+g%_uq1(0}J)X!j7jI8s=>Qq*1-X_O2k06H@CS#%FdbUHHgL#RIp8*6=`JMs zE-33RY~pSH=9yIMZU2rX{Y4Y&p36&k*YNOgO$ci7YZ zG4FVNfbMme3vl}y$PfZ|&eOwkXlhTjGjM-BB;VbcZ~*W&4-njHcf5ffu!wBGqWp&x zW4^@_F)e-=-6D=Fw*`m7#LAjvfo1Zq?x>(4A_cych^s8_9=g3d{P4zsp`xUEBN4|T zt@DbbPt!qosIfRN0H;D=j07xjKtDo~06+WWiY(Q!K>RA#)f4vRQy$&M7shIC?5rh~EDn^^pAKE;6*yQaSezD&5z+!f zONXHLXa!)>G!PW{fMFQHLgdV9FjDy=n+;<$sA?PWH)a3M@rg$35pFgfsDS z_0;2LaO)Zd++B+!Row}hhde@?ZNS#%L2FZi4bQe4JzO8tj4dplDJJJ6y+ev_!bvMQ z=#Dx_4H&c(J_aRu2SRi-T^(*CDZU^{xfQ}9S4M`#fdky36U<_!pPtED(QUKWa*k5` z<6(@K3o7-DhZ)~wRz*UaA{AssjJE|yxIyPrMH&e!pr|>*czN9M52JmFy3X9dn_PGD zp%1X_5$uIgZv=nj6}k_!#nECjnrn{n<<&cyUg@-Fj!L{2D=n<}M3Ueua1tNbagQw5(r`}?;T=*` z`cN$rqD5j>{*)0^^5N{yw9qdRf!Pc_kHhifu zm77rjJwU?0U~S`J^b9Rir`l3ybHM_3WfeZ=T9h-cs@Yc|i#k70x2!8}X`9P*YRZ;J z4YAPK4pOEkxz?d-|vxc_XjyMzmZ*HQjcKto-@|Bg<*`c6?c|cx88T_Je=bJ z;9ETg-h3_2g#FxaJYbUL^(>s-UFEEO{5C~kddyr)I@bni^}%IqH`Uh4I&~Asm=wF-s$hQ8LH5#}D1i@tzWVE$q9TDd1re zm14s!@vpQSp^X7PdaBlPK2_*#YCPXQqUW4(Ug=Eg5s410jYX-v&0|T<-&{8W)dXI| zAoSZg;P=lP(YFBG(5Ng+*fzX<$kn$e01&00Lr)5scZs-sDYsucUYE@+rUPGZUY?B* z{LtL%!ZR?Cj~;PaUmAkY?;6{o@2^5%cSbrR)#er6(LK}t^VBpvzONSVRO~dBqTpTn zc`D2DZ#Kl(Me!wzn)Fd?GFDAok(N!3%(B!)6k9wtE7N9aT!ooUCYMq-+MMVr#5MV5 zS8G(td^JUeTBVvK`bF}kvgQhx9`>Bud9!)U<_yb{Cs2e!!hOOgg_H`y{k$Mk*74O6 z_HEB|fh_+~We|CB)^Ct?hb8K52BnBzg1M0^j52xhH^Xw1gFoJlOzILL6kpNesRV@+ zFwj1HeVM6P?3#qi`Gqed4))h@^t}$gfa97#FVw;VuqY6B~Pu9?Xj&C_46ysX6Vai&R8d}rLtgjX+duNdw{v{X< zoWbPv85XS~f4%%@WFF1dN zl#*|;{w-Z$2WL>L;}tA%)QeM(r~C`b=SOL2%G}5QI41}jTo3+Ndi*O}N$@uo5YVH*zYBQt z{&$>5qQbxJovclrNdJ`rrr==eWcYu|x8|tcDJ&_X@x|L+vBSg!iaO* zD`HI)+k`Y;96~O}GDqu%+e#dF`6t97BE=5R{V0uoUWQ09GFdP7y4&6Hy=Av;eZPO4 z;PsR6qArZoE4EcmAjXwgw)paBs!zrCI4#y&Kc}S5v|!d)-thfPx?H z>K19xH@P9-%pSvJp^lt65f?Gi_FQx~2Mu941 z+LV7WeJu7IYIJJKnI4S*o$My;ht44;24|s&B7EV+NZvam?eC|B0Qva1YYQXo!1*@X zS#^llRBQ5BZOmg0I`tIdh^;JgxdjVBol`i@YVVNqNmL4nV<|UyjO_+T5EK8JMY4Kw zvEk8@8)P-Z0;x2u7)$+gz$8+*R)nyHwUS8#qgb;mNkhNsc(JOV->?GeBg z_ThG@Cem`V?3(kFtM;cSSh~kht=Tn)(51X)hgN}XE=rG0t;}%Y3h;Y!DF;TsbX0kj zm2FC`a^n{UHu>M^SXI3f?Tn%a>^pj5wd4RU50}A zkdKxp^lG$QRC#3Xfqd9s1ekCg2J2Tr<*?$u^jN5U$S9dus?xdSVJS&%k>$#dY)qxu z245@>ZU+c_B*pOU3c6)TC5BnTcnXY>U3L(C7e`i9nIr<+iRtMCd?P(FD1>DBYNQ?B z$f(;m*x96ydnd5VQ2>cdECySs$S38@s%gifU^QikAr;yhxc~b9VJCt3UIGFHWL2Syr1%$BCBwd(a^)z1A>!xrG{*4B07=HAu1@%Q7_#7r0k^|=jJ;MDKU zJNqvC??>KK&fVkWUEkNQfR;x`SgxSd1r7TdgI}kd-+T|5wSvEy*VRzt-k#bze7%jo zZ!N0lA~o-!qH3XaFw3DKfAz58e;UgZSrF?hvR4FH*voweO1e8!<~sb6msLb^u9f3{ z5Y48^jLkRsg;skJC*GOdkd7*~yc}M%<69tkcOpe`u?%h267EG3D9U^aMV~j2B$HXj zR5G)&kFxit^Cji3gB@EM$^yJ<~9j2>D{IPwKV|3jAb;qKx0b>R&BLcZ~V>_B0R{uV0Jpk^LiXs~=W zkhzle??4TGn^4T?`r%P*4QdU=U7yR!&L~~(BRt#^4e=TfP*8bNN)6@Px^zaa7O|XK z4Z|Wh8mUClWqh=3C4NWfvs0tUP$!|0nD65et9R8iX)T@JGNUzGsMYoKSS}1Ju#;qI zD+IAW+54Pso=UOKYV%s?$L`=c_Cvyf2sKLuu;3jhx8o!1r-hQ*uI#4+7}F(+Wn>$B zC&Szzx`s)e?OdDqPZ#qXW+}K);jMHY<6$b_%ez+MK zPn#x}>cd#$?-a;c4=8zR>y@CkrdA1Xy;FsngpCt4+m#vpbrxgw?rzfwqc}2C#CmU( z;vj8Y3<>wV@p0JR{s>YwP~liB+#H7n>%sCJIkm%v$9{KKN&JR-Jd6~iEdcqn31PEv zI+7O#WiTQ!fg+F*UnX4Jj3BP{fq&*IgRp_Igq0eo%rGoM(y=eX3dYe#_x{!+bqJ2d zbxiIrRnye0OUs&}>_m=%_B=c3 zcK81_Y1Wb>jJ+u_ZZ*V~)1%DIW%Jx`~HZH3!dO`UYO3VXFYeC3q z7l*x|=Cn9@#jrUCxN+wWpeF9%xOXPN*sAl)>QrQFvPh-MKSp_;6t?lqq}npf5M;Hs5jdjHGX%Lk1D%79S^Uoxn>FnF`Gh z6u@cB7y+#C3a-TpCP*sMoWrWRzFzZ-LFuRpVW?UfvVs||K||A>PU5A|W;!wo7)qB5 z_FL}=y;D{p1g=X3i}H$3aVc)*tz0|PwOPhWK?fsO@4caYoNVqrPt3UX>7+9=TOu5c zgFh(#rU&8GU%OPmZe-qG*&1>^p4SH77DsgtB#UH7W`W3xy>&}kZV=3y*(N#)R=?94 z4k_6EqWTP93u_Am)2%An-HByUSGC_eLi3K>n~62# zyY&bGP8pbC>xpU=W2?s$=*HS1P)MUw_(Jv0M*JXyK(b#Vzyn>QhVH=+_ zpVehKvMpsI@40mu!-!yypgTy(b~H--E)4q2R5XpIl)1KQf_J+6X1MlOCtmcZQcu!o zvkt#-DW=oVmCbr}+D+yBK6bsL_79M*Gk<2e)HxC$6HNqapj>&nfmL%5sK9^cn6;SE zd;f%_?Ja1y5!SVvk~33kh}F4Aa}6q4%A{5k>ws#WwCu~axS=-u6@`S@&}MK^;3iX+qoa!_29L)Y4DWzNrojdJ-lWow!2mW-zgQx)L!5;_%= z(|Vn>g9pd$RYl}98L4X}Q%2|g3}JhNIILan7TBFa*6kTujFkA=u2YKMR3A?Wr%&RvxFco!CjVV>D zq0_}bP}a?14nzd*hiTh9qXQ38b4i~SJMF-W6L1Z;a!orCQ;Ko8xlurA4Z>3=eZ0p@ z`WP_lx!^>QdfTP?)9duB@$IKvm|~|~3ZK#4mxjHVjx*RA{d=K4p9H)q5H?TvV}-Ma zNyxN%%rQ;j4L)F1>usGZ?qKK=iY@(5Sf@=zoz8*gV0S!0PhpH>-SPV%y&u%^`@i-U zNy_;|9Xr}X`lc#~9FW_((%G!&)C&y;u*JZA`C}XF2!O0($_!rEF{E6*chd zl26SgX2+T8e4o4)2HyNm;#ACYK^hjzNeEgac7tZ}JA=>!y&o!Awk#NTCNkg{e{zRB zQ^)4BgJVYZSeAk4s@0l8Z?>7 zCD~);q*8<>=zAX0gmbb-V_@K(WgF(+-onBoWPNmnvV6H5V{lt#Ee!A28cL(K_y%t3 z#o!rtozH#x%Pi26)iacgYZYNB3Tjt{Ile4GK<-fQJ-3-e(o05SxGW`P(>|*%(orR+ zRgkicqrWqD+tH-k=7cuYrz8Uo@t&qzYh#OUo=qWVO}fy!np8E?Om}pSdt+JXs_kSq zT4V*9ORqPLu1S4*b->ecjuDP<_MrYCmeA3bz6xS;+>j>-*szi4POLkvIqqZoau2L?0&7Do(8_a%XYzaR zHit65dg>*noqj|2XMF?blz3p8Q}VHb$~C)f`rJPc7E7ypPh3{S7$j(!-2c>o*wgvB z8DVpo&hdbP?069J8Rg|0y{`#VLY~DjKpVj#VH!2aPD~+kkh<=7Z3hVsIRPr!4&k4T zT^QgvQkU+Ae>-yH9e*Y9nHugdqUw*ThxF&9hu9{F1%Am0nni zS2{d?balv*)6r|d~Kr8W37{Cb3SX>t@Vem_R1W*v8sfw%0n&ZHyk z(>u+Y;z`0QtWeiaoh>=w$PNv;E$8{>aIB~N#2>dC?{w=;PryiCYtC!Y925GnnG)%_ z{5E&b{E{j0oDKVofTx)@mdWd;+40za>Ij}?rHfuM=CcnUqk z>@J^ENV-Pq;gw|OYt7U1x93GB{t&Vym%8O)?9bDwWA-)e!+Uzp-(L1Q(s-7?k+L1- zr1n^U2gPrM%*+>W_k74aN#0)ySb0`6MGjH74}{D*6c)V^9p@AbnfT>`5ejh-S%?UT z(c%{)#>zL$n}{|u!z`?E3dz4Hex~q*aPRk~r#n(KqxTN|;Y6n%*!{*du_Ic|8cM*J zC+Qx?h`e&*+i0^{4YqSeqW5t1zJhv}%e$m6^7~_I>+mq<7RL@&&PX_aM>^n9a3e;S zKyLbE%%IARd6drpI)<1P;@P=^Rk4L5XKR^@8YALIhMW+vQ-P->iUKIgf6mtb@UGws zWA_S@gqLrrfbB=i8Ymn{^V$kNc5IdibyCACmsO{zK@=ls+6qnr4QeXqf)pcl^oc}{ zcxVoN)&3=Bh6q&s5)j(Y0t;eT2r*yhmW9eC1DpG2Sh2-8gG&rH6taKr9g^?G3?*uH zKc%|bmlfRtq*49lhc%-5=DX#qChf%hz2?IwQ1qr5RyT)QgPD*1#_JO*tY`EWy2!kO zhPvj=s3U>b^q&i`>QQ#Hn_YYwJp3sws$4|hYH+RK94edxh~8DlBc;nRn)$H`l>?__$tS z%)ZHnHH}}s$&eFm9<9Bjpch-bqP@Ym_qwNRYZIOkhB z*^Bc6d8OkKE+xtnh9VepWD2;A9_`i|on+&hOev8he8Znozy4M}$H_3vnU?_gHHy4| zikG4rVbUCIQY7Bq{bbm)koUGIn~Gghc5{3Raw<8NzID7_epP;Fv8v&#l!G?GOJJ7_ z4K)g=n9VW;3l#1Ols4y?AUnC?q;5FH5}Ob#;3!D8nU_@r_LBQn(0xjJq$(C_m-gW1 zGAvXwoyDb!+u3wW0qq&-e8s#BYFCr*nTWkU(W*%=R;CmiiF~5nW*35d6J9Kj&Sla- zKm9T6XnivE$ldT&J!Ig&+d1W-U28IXY;K(2m;vB^ByqetvFJaJ>Diq`pY*!$)2#7} zxMMojkvT#3G{d0#{Ba;yeefh!$bjH?Zkk+27q@P6T5HqPrtPp!nJzKDUCiUDxBWs~ zx(Jt5?$N#t)KlesH0)5|Pny$alOLDhNEtUH5JyY^{@k6j`8p z491W1qs`$))uGKF4bBs&|8;LS;6Ww%y8GDVZ22FrMXR~ z2Dg-K2Wl8$V4~bNdQ@wMmXFmsR<5E~xyqK6oe;YYoOe!nd4Z` zO``Obd}6gB&Fo44ixXK7BccNdV zfqH6wnnMo*z9}D*raHdY##XM5_R36iRy&&is>n0X zi?5-clO@ZuGjryIfR1jQLJIy(jf?~E?qxInw$W$#$mcsUWfofYnAY3MRAygU2yGy4 zu#Ub2L;wTlMusbx7x1G0d-Z2Z0^=`s&#*0ucSedu6g zpyYsN7bGHKz~)9MiQQ`pL%p+00|PE3F{_tcCNuOdPfD_i?R0#3RhN1b> zWJrlbI~8XmYI*#$SiF@cZp^cl@XWI{@*ZLL<$VW==c7RTA_Z?nvhp}Tr}3WFN$+T`;`<2fUtld)= z!lYGYN7LEH=W7!If3nZrrVnb=-CVN|f{!tB9Vu3_D*8p1EqsoT2rnV=9_7bwaX8jT zT%vupkA32u?Fh%>b7OQ}Oly4x2e$uz)Dg$wl^){L9tu|uhFW}d&Q-+u6Ym?pk1^^W z;txx>;Y2UPh3Vt=W!&}h?sm~Jw4wV)VISo~r>G72Poz;cH~G7X@`V&T-=-HzYi>v- zVSHmTb6sPp1_!?>pJ3D#4-RVUXvpIE2&?Vs1$^)Uq99np>0cWlLRc50D9YlQq1_T6x`0rdN<^L#`N7z+ilN7c3G_Y3uk z{T)LckYYFqs4`rf@x?=8TEs!mVVpx!?+_^Z;x3vNr*HwVCB#Xf2O2L@;uy~?kgly@ z+Q7w~Mb}XOz2aUJ61M7$miNH&%3^#sL~s<1l7)>JOi6E|BeO|Al?z*snE28k5TdlN zmGO~+*CR=6MH7ccIDYV166}=n_9;$07%CT9^x#g-E4rC$312+NE2$#6l_L<*4%ny^ zFcxq)+NPBzFZECFHJm9nx#-3RVxbaSRjK?)mbI52$#YTVquW(--oKGO`J|fu>W}?j zDqU;IuV3~P>f^KSN1~k`H;~KQhiCPzNzhPJCIraKisk8WY!_YkgoKARo|wmw@!&C{0+z-p?V`>Yn4ZYO-#*dR~oddRG6|`R;cF3;4tJ>vU*^lc(dvwy4`k56dYig zgBGJv&FL{N{Wx-DNrMt2dDv9k-os-L2GJyOpoIz%NmMiU^A3A%11K>I|?%6MPmt$Zdzg||B5u(&NPWd1&Ify(81Fuj7o=}h%;kpRi>k% ztci#CI#B!3kX&Jj6~iO6&_BJKUcP~4&dStbPujH_swK+;F)J&{jFSo~3J2UJyA%K= z!+RK(_sBCTLUqLzfs5B3xX5D0+;IpR|H6oBR;Lg-$j5d*(3qZAB2Q=h3WAtqQrWj* zL%m?Zn5NB2{9W|?VLDn8TBVa73xn?rHb!uY1Uh!$u^9rZ{&{3(OG%D3g$_wGP@&K- z#VwDw?|8uv`sC0kxVMi;F>^u}WITBZ>20dEOI3D&X1Xj*;J-2dgI$%v4-1!F*=pes z-7>>Qmo`;dP=>7$GQ#WSZ(fF7;5|FbF_us|?Wj?;hE=ZS%!9JvQUz(^gI0kr{cg?Z6%z3+XlFo? zd*`G_Qx9Yx2~D+7Hg7eX&oGVmOpS9s7gm>GMuz##n7cJ&;7cjbQaxf~df*J7T_!kS zXJ^DxRIj-|1EK6y*ePkwJix;Ajn5slQ9e1WDPIN)++6<6s4NbE4`DhH@C#AB^Rn98 z%VOatL1Ui}gz`NhnlLrd^!!K{c5>$)CcN9I`ae~+!wB&Bxw0j zRrE0Gk7R!gP3|=!)1pBtF2|u6K8KQ%V0fVa7@dpx;A}x4*HZEN7dt4A0}n~i*xvqK zenlxEh#p;M+vv}De|)OaHnOv^+mw~RF2wDyLI-wOo`GNP4BqLhIyGJgQrBrhz z>ne!bPkxF3CvJ)J3ksgA+s5~(vAR83@FP8tZ+(g+HVYe2ZuykVP%JLgj|u~ltBRz^ zf-*BRssfR#?!hxDO~cJCCGAL4aWT+D9pX={k#**9^~hSInZ>aj?s`zkMlJ7lF-&Z3Kfw7(@ zDj4P9yN#v*g=_baVaD6#9cydtZ3wKnT8`7>xYz!oaJ9NwvK);N&Fum;{o;WCLa;AU z$vQy>Z_UoRI3Xst{O26|y?RG?$2UZ1Z_SEIJ-W+u5BZh2y=iA>r^+P24J)2Tn$`Y% z_fXq-nkU(1%9X>m;E?Vozm^}ky&nGN`sE3f@6aCDw-35WYvv}(ksdvCfK0AgME)_} zuaDlgd06lyw^F~?zjyDxNteP%N1;@Z*)`EA%Omol@>Li2*Km`yd9B|Z#>6Iy1`Wr@ za9^e+js#7rTDhW}dF(d?0`*r@Sz8s0n|QaDY1~+>-U1wz;zYshl2Y%$jAQ|^8@iNN zmcVYmEB+yoKExMtDp@FPxlG6x^b+QIG!RNjyM?VIZ03(=;k2dZ21c}O)D>k7lo67PiG36S&3G2Z>PLo|Cmc?eb zK`>`f&(yUO50mSbP|U*GJ-Z*fKE}MpQY9JQJSMU9aN~1MAg`Q-lnKc~==6gm(2rh) zdP_7Jy0ZYg8Wus?11-w2H=$8b{T#`?k@nUpy>WH<^7OHl zH{(2-F#LYkW*S;-_9jM5TkY{M2_n02N_rq9Pzk^@O%~fI4SaX$7p5G<^^3YCUp1N7 z+Jw&6(l{o?ME9@FH2!ZYkdFvax;@ro9Wn3`E`U2arB(f2f|)C>n|AQhmZEV`Sb9`k z6z3?+0uDj%%9532R@D7Nh6`=-hG`K)ZPFaJb+~wsR?SXAeP{#Sfk}6)TY}q51kNH= zcNvD$WJwFFOqv4AX*JtXphmgMNV&{m(sC$w+!TZ1IK-8=gpV_6ej45kO_vS(vCo0& zA~Flf_R*w8?$s+!`28y-6!WP9sGX2ZN~U}{;q5Y=NvswjbGU#p z48C_dG^T=NV5X^==@FABt?aSwf+;S37gJ^o`1JGILg6)J4wn^>ZUa3Eld&%<*XKEo zO1dr@&{t|DLx>NJT3%v663OzK+$yZ5^H9DHvNfzmr9hDkS*Q|+aGUFZ`aRL;Z8JIc zSlJFrM%aUo)fc{@Tp@O}D*4d}7(2lPIj%Ko4Og2}1PX6UH?BnLoDWv-BY~{#_P^OP~?d_%g|= z)5bD}#up#UmCqpj*OjegRYxP<)dis}Y7dO`bm``INi}3%o);(J@r4GMwI*ZkuZJPh zJ18z13T0y-l(khZ=+n;bhPvv5=^se7Z#Z3!!C^hu^p6;P!4-POn07UIC-|v@`0CbL zliJO=0#yB0G8ZUh7wTH>N40!eF-8QY*Tq zuEiTyf!L)Uyxpba6}~v1@T--Idr%M7(6NfvG0UgUKcYWHxO2t#I+&Z@^;r*oRDw0p^=pHYlkq6MZE zpp(iysa{^VU1DJBM^*^PS^J~AWnBjBCcNe`=S^KB9p>+yOy&I4_C1Xrt4oY#CB?{QWQ@bm#7USQY;v@#|l%!i;ZteW!CHpO7rk6v^c2QKfv z;3Y@C*?xrO1N!X9PwalGIFA&=Pf{EYCH-0N3r!D5{WDuza0ctx;e562C##GAQ|4F~ zcf8p|oNOBNeO|8Qj=$WjG9bVmSVA2sFE=)Q5Oj|s&6D32$z#Y#01bcis}ltafWka+ zPlN@#Xv;4b3o=gKtbh=9Sg9LQn|b*maa(wHOZ@d}+k?-QcEK(POe+qDpfOXwI%#CZB{h{;?olZ$luywOp07ljb zJIBo~Q4^Q2FS-V$b8%382cpEdqZ6q z$%4$E5vQMel~^2xV6(xD%EVm9Q^m@EEbro6qE|$DhnULlfD~o>AsE_jvEXB7bRvk&d?yOh`F&>mgrjWi zgbk;yWBBNibKD-(W9)X}=`qe1=#JAy?+j_zQ8S^AX4moLK8{bjXw&MFsgafE0E>&n zwjze96+NnK-gwLL{^lN;DB9S1vZg4rq)61GP?^}{RvPMc`Y@Ns}eZPlKDXhZ&XN4l{e<7x+`dq+0% z*$c?q2XQgPy&YD2r}7gdZ%21O8fy=q^L_xj9isn&i%-Va84U++8q*!X|;1S z0H7W5-_}W#?jv(0Mz~QEB(wSGkF}azCvv_{s`JwCjiNf?PVqQUbnIJhM4Fp0qz4a z7P{-Eb(|l%%YE~h5xR@8Y19|GE6mY)WA_=Y61ebnAl@S^bOI0D+nWYe2Lh8!RVL$K#KI`gV(K) z^cy?!d+?%hOB1-zVu@8f(vxaC&pVn)_pUZyM-o_aKFgWLWTy^rYc9-_#LB_7G^tfu zC`@p4v(p5oID>6$miSyuQGYs(tsXd!xung2wJ5)BrhiX%revSBc*4|RtBDBqG}u(Q zpiMiwA>Y{Og^zIooVKzL9krNwyadi=*z4Xll^gxsq`BXti%Cl_aS^YKR_o}~R583@ z{|0X9NVC`64yOC5cJ>RGXezi3@Lx^v@vMlc$y$=cq&)ih6C<7ocSxpYY@J~QLElSo zzjSp^_Ktb)^OL9D6=3+A6~6N)&-dkH6XxR+9%}iB27J&A92o}<`|*yNTvC1E&mEz5 zPd*~1d<5vV66T=__x1z(NVV}0jqTGwOaTjz3t5WP{bBx z-k5I+qDGKlNWGO|f^o5&FJa0tdUgV>72>P*sVtHJ+{6%xoDdDg_EZb-!&IkJ)tWy0 z44ls&JAq$MbcmIX_570^#nQcTL1qcZB|078Af0uXoFW`#j#eR(+ z0s?{rg5M2-TpXh1tI*{;DyeXJdAr%@yLh;GF@^Ly`%s7IB0DiNTQ?yu<9CwQ@NEC! zI8j2XMp}7Zayp>)E-xiDQ)h6zKNarx@OXc90X77hQ;noN9p%LI9F3XzzKMzAs97*- zf|FxVm5KSjnMr~O)*W@KfSmyl zuz0?;CiZ%Oj~h{ZY+z(ya3JjX5%6O=mdAf`2}OqwD|G)eXE5M@w<-+(Bm7m)(9Y2O ze=kg|vYf)8Ad+viBr>|t7yHAZQ2Y9DviK43LI{}fuSiUVEjJr0=`EW!h@VVI{{VqW z&O&A7tZ@Q2ceC9r&!(n3!a94PSqF=JqIsB9>$sL*ID8|eWHrMLvH}DTyNOy_%%#0> z#WItEO8Kv}`o$Mh{cMn{EE`$|D`elW=$!Vi%HxVO3=Rz1J%6KhU{vkK*u^$sgV+0` z`W*?XW+ck^L}03CQscodXI9$+M7?`A0LT=2*j{!-u7w)<9Jqads@#z~*0S5IXp%A) zPZ^vt@95Wi0As$>CtiUf#!Y++E^`K*&=QHN%HdWEfLiY3rSAKi?h3y9qfJ9rDMJdb zdfvi7{J>Gx{ZKP^MqEH3Utm$n0z4~Ks%U0*N1}R|VWCaulTU3&>PJ|a{&iA7KT5B9 zr2h%Cv<B<@&fmRkL>D z^nX%9d2h;C{i8yae_PUq?!S#d{!5epo2xHY#QaBT-|Z*<7=J|-$%7>T$qg58IWgC1C%HT}YKHqG&r^ZjwP zg$VSd!Jc504pn4(Mid!h(H)Nu=#rar{c0ETwKeulrPw}cpq#}XXVmEO$>ZTiY|R1O z)|OL1G{S-YFIL{MNf)hI*PP{9wl&MPZQHhO+qP{Rvur(O+qUiMwe~qDx=%;++dDdX zd>Q!zuFS~1$H?1LEp$5bQKSz$a70)bX3bb^WLSf>m_yr4TxI8wAy^^hOD5F!113Wz1cOOosEyOlP7V}ruwI8I2e`F_ibHx<$;way zaRO$+Od^jeKV6BmlwmMlYT)3HP@Yew;Ht(Xb~=|q@j-e7SKCB<95NosomIwVwiAG+ zGMj8nn}kPCJ|zGa0ihaz2Uzti(JOdi=&Hf zFx@oKID4XRRMlv2KX zKXB@;bQyp-wrA&GZl_J12X+2kG64Pmhg-(~#qHHU+@k!$ZA&uh@^~6>q@uAFFWTJ( zFjTojl8E18{(jxs^(yV!HEX9*pxplk?hQ3;A^*ILshR6>w$sg~*YnEF4IdD-5m6B6 zpf$qsln*A<+$TZ?YwJd=ji*A=wyMhoX4>X)0y(u=yy2|d8y*|a^~#jmb8Yz;%sdRy zT`hJxownR-7lnB$p|SWxC^l*;dH9l2GNX`boEO;2nwdT-lDdPBS}nsQCJ&`@;ui(Ex1)11Y7I zBicyP#4pHTm0ieGi=dPRg}!LNRdc`%gEU(54yBDsXWB4T5*IltQr%FUUFuyMXgGVN z-d`lN8YUJFGcvy+W7;Y2sg)~EvOTwUHo2N)J}Vi{Unxakpn>D1pBF_a-Ptb zd%i<~bfy~Qs;)Fb9PC@D67?^**DGCr2yav4WBSJQQw&PWOs(7l%NDyj;?d%Y!;P0t zYRVDCQDdZ;T(y5%oOzshVBW+gVu(vhRJ`?qv+&{w5e*`}Gm9O7Aa&G6z#h9AX})S9 zvA$+c9|>zz&$uKW^ewJ`fs{mmoR$b3_Kx%!c%B#nZ)N!m{H{Ss*u@xD@A3mv>r}i+ zh%6yJ@zej*@x4b_k=n_3vuE~b}9@V3ZPT>Eg`Ig&e#_1oL+^Xpic1^q`$OMzIg&2Dxi@Gnmgv_I!naEUhm2`G?s5!VafE4t12q+?i zz#m8i?nVX%Vj1K{#r5W?W%+sPDZ$K^vqXORAFmzj#1Xjfp7p$wt(WcYlU%Q9zi+4M z2elo~YZ(6&$1I?*-9&Zowj*&yTa6;2h*Xe0kb@uyO;Mzx&#UvRYZ$UYhyln6e<^ua zq1RIT32}DL&Bm)f*kyi2`NeLBn{RnJGxLRG-GE@w;Vi>BVMZL8Yq+>*E!jSx{=n_r zm<_L;cAJxLDj}ULFIHE(?Ovk?m8=(AbYgj4%Y^iq8TbGt2;pqQu5C%c>D zs;8&SZ%fb0DhTW$TJ>%&Z7_Yq+sui$3oL3@h+B=WuZ) zH#`^fl20pBA^hciMLs81g+Ax?-&11X)eJUBAX9-+&|{~&B~3(J3-DyAS?2sPoF|gV z4|@tlOQe)n3RMw~udvl5+|8v4>Jupmh?*|2>x+`_Wb(V(Pn}EAPo%8m$X?Y%!X|<| z9Row6U*?aq`oy{NUe=5X1<$L}fMfeE20VCt75(QTWVMQ#ZHc($kaM>x7AETn%S9u?@DShFmaH~S88$J)y?&~L28F=Gcp%a1!0b{DKf73fkprKremfAB;~jo9 zE}yGG-F&%ReS6>D%#M%9Dc~=7En@Oyv@!CE0bcqVFeiWIqhqiUdgn z8F{rGmMGi}REKSg{h3?efc^?s)pRx^Q%|Ns%IblXK&W!VT@dDBn6LID$&%+cu*d-T zIfSMow`eg@@R~Mse6-{$|C6S5>Fdg;gCKJyzL%`m-*|uSf&nAdi$j3qfUdE0o}D;I@6A4)t@MZJ^b_gEx8PzTEK<@PW^zIn$=IL$I}|l^x3zqw%Bb&AgX~AJFY~M zA8~To>^uA`&nQTF%kDKjvx3p-=$VP;hA?;v5i-I<0Z0%=V=bB_7Z0R8{=J5qFaVJA4-jOs|?})zXZfKFD&9sm1;5z%>EakWM7~`f#_+5@}S?I6Kh&n3MThaNa zD)b#=65~OyVBu`>W0dE8yHU-8Zm1i-s>0J7(4~;asp0XRq;prVyEtN8)n?z#z#DR( z-U-7>c{nO($Nm?YPh?+ySpt{G(v-3MNZ)d3h6Gg79zWJQEZ@;7WK~7XQvN?nGd_pI zaiIO?)L!@N1?t=YV%<++`4m~TNV7}flp;`1CBD5L*E?Qe6J#tTF;}tb!OBxee1cVT zoDObx)z!+9X9APv*)AAzOjkCGcJ7lH*1RxlFj|%Cw?Q8N#wEY3SNu;p6BsJ3sR4s^ zM(!Zpa?XJLN!l#K1BF_8k6xM;9O_!CE(c#Pc|)>~XgL)PwVj#8=BW8wuMjDr_CL(x z2ORH0l;}zrQtPb_#6qhV9_Q~uPnHFW8`px7@BpGWEiCFFc8gZENOhiyv^RnEWT%gJ z%{r6?Zes7cWTco34$lBspt|Iwt_yJZa-0e^WyLekZsNXO8w)&)I6#d#+Q@k|dU_*& zAd2`%{i;ATy~N35mR`BWY&Mljsj?L87w$?yJ<|xT={;?gU>&ugpCGIygpop3%e1O; z#fWTq_{qeXCxe6PO^TFx81;RMKmbuduD_zHb11I48WZ7N5=40xKI`8tr zPedY(imKR+lC#ddR5I-_c6WWO=cuV&jiH}x2-x_T)l*g4O=RUd=P45&)g`_|DrXH+ z%M@~Tbl&l^9{9oPI2c%H%y~P4wAjizzGr>msIjqeCc0iG$W@%I(_tvNNgkIcsIJC6 zFv`nbN0f%OW1*j(F17I#TFM~mg{n8vN5rlSJ->NExWQKORERfAMK@&HHQoGzmcvt; zQRdbrPqF5^P8GA1#56mZZj3;g;w}x26S^rMQ1rj7j}`PFw4Ym(z&tF1x}0{+Y2B(R z(sod==@!nfaQ2?xfo3G#T+>Z#o?3+b6=iH9u$*_ zfZ`YsQi3IeKPNSg(zA`n*07h_=!t+$9*dcw`z8 zzr@=ZFeR9&DV|N%F^d5h^(<>Ye;UejkhvauQs2Cc4(@;^wtJ{&(x)tiC@~^MX*wg6 zd|yns)Tm9j4nXCD|7_mgPW!(%pAHMY?#^tZ7YO?N+ViRCp*!&5*a=#ReEgeuvBbst z_U_x$QzxG%^~fTgL9Uh0YkTL5_fjqjOQJj4>C#oncZ8ZaPza&lM!M(diVE;M%B-B%R~c$T zX1``peP-p3mL{`z&uTZDHP8XEtF+>FX<^PC5F5I1dI{ZDYJUV7j1`!Rytm;e;qkzMTf(&!wn1y- zMKkx&GnY;}4kw=l;&eg)YgiCEv>t14H9V*d3eouh!Bsz4(J-4Qbg(TU#RUeQP@qD> z8|&bbB-VT|c5a~=BQMsR5BSiZhzh^YH==JX5au4pR#3~*cC~)U&xkaI zVYh=8=JfACN{S~{3i#{+eCRkgsWhiAV&Ir1@0P!wCQz+qw>{fNa23yFOwc)q56bI|fo_zwgaIE^ zzp*?NJV#%+=_Ge`+-~h0rTN=~hAPrhzp0b^uXEV9hFz!**@L;B&`b*M)B$80Td^v@ zoTV~K&X5@f`E?KLgS1sb(-L3Apa9dZ-r7hx-S<-f_~rzXMLFr~4!wkYB#J;d`t< zzyU`Njq{D|wFs_ggzlk?GenKDXIP-GNc1OP6kLp>#`$r&$$^2&yGrG=k|ud5>6P`R z0?r+HjO{8FemIxbP2R}{%3 z9g#KQWe>6Tot-yAZkHHuIE_BSZkM4;F!7x=uP2i178z+`hU16L9jkYcNilk69EzLj zf};nR%otwLk*f4iR`+H^;*C8wsmxw87w~YeqTAa~c`U{*RHNtYe(NFj>xJF&RsLCu0#y`Nb6NCHv2Sz&I-wKk27On2BX$C_(;R@Y;Q-v z1B+4zgPk~Ui0+Pa?3{JeUymW&huZ<;CsdDVR&HMMXWD~=`w8h2LabzwE^i!EZ_GAxYT03k;87G%Qa2FDLhlz7Y;Gj!m-ot+Nvv{#%?$A z9PWOf8FQebZ1qR)HSaN8Mi9cIZq&O1eDkvsLP0_0I^WBTzxEvEdm;e6feH}i+kKgJ z_?-5a>v+Sk5z~mmw`xnFPE9<1aA!~5b7jfm{J~7(WlZDq<%;|Jp)3R{?$H$JzS%VC z1RgrRtbWjss{56lMRCp2#`WXmi<3_I>~$QcrL4hI18QNz)Fcf5&?GE`bMPzB>nl;# zGbiAY$}~W)Foj-$lX>-{*oA&h7@Zs<`L+gjN`!uhf>Oc6Nu-^?ww>RCI+r^}1<%r! z`=P6Mqul^0Dp@p!WeU?|LtBPLAWe0Jf+fa`v{cV3v*yH(;=pb50Cri|Zr?CA%RGtm z3W0{_qT7_AIoEd4Dh3xOLaKR0w)V*~Mu#KjOY(qne}bx~3lw$bY2}4{7+__SA%?75 z^6C_=MsYlevUHw1w6e4Ye0@2`y_Q0vjj4a{UZOZ|9oQP8Jc+=VR6%8u`_(e_+cQvf z7S*1u%=mj!0?19pCUtV7ixL$amQ;}E)-gUY#H-O#J6)-WRWByWwA>;3DUu7GU1se` z3QEDZcIZkTQb%&FA+^9*Cen$5GZjs) zf3fznbTQyuZlcoMTu4h7VvWc*?rAK_js6c^%VZv2S5tv*rOXA9%W3BFrBg*%OBTxl z7}W5MzXaUH&7?NJRdmpfaChVZFQec-uSZU|xzhOGzGhUNXt)IuRCOPKiD z>K5tDlA{G)sL>pb8pI{HCEijRS$H(i{Z#(C-lgeTc?ISsJGYudSrOH>$)Zr#@&$IE z)D~2c%1`fvHE_#&dR_6r7s}eOE3HW@)GCuhrm=^%8vCMc(f!wS`93 zL9r0cXU-depJ|Q|yI-}i^Q*Nh%*Dl(!IT}L=bUckoisQ_L6jP#yO!O*X zM~w+>qG@IxE}JUkIUk;~1g(eKg6d;$yNx?m!Z-UA$EjSnP2;!`sN`;+=RfuHQDF;5 zvfZ|9x}_KBrkMqm(sasMiCZc2W<-Y1;1ON6t-32N=W;$HWH@WQcM^PGmUflu@^}53 zF_y4yIU;o=k)2p7LFEGl3=sPxIDsmI$qNO-S5&R~cv>O(U0ikR+Erf_Jp?p!-zb*$ zIhS%)v$f~4x)Tqqb>xy`PfeCG?L;%aM~?haD3}N$WbaIA>Y38IWZ9H&mAXF2nTZ4{ zVG{YJODXu1wvK@?FBNn`ND4VkmRYzpx?F8O0&;pLoP(f(>r zwKhj!<^|kh(5NzHN1;t!@T$ee#g>vIiixXE)#AV+Ku(69?UlS79>YUgd<#!yQrMj1 zm5BEOsb%j6?dU9y_!pCLh9TZCRYwNR6QC^H1R7>D&P`qe<2Byd_%0=xg;pGP(UTM;aCJkQJ$3;loPn1#zd8mAn%KPm`15d*{7{ zBS)m1D|9SpnJv=NTYoy_2gy}%_Dxwnsip|Q@M8c&@Q-BiBW(4qWVUp zQ^B!jL7U{Jhd5M}$<1H5;`jYuVyVBO58@)quU~Xj|4A%m`+pEi9Zl@5EsXxlSBp;Z zf5s+?CQkNtw*N~wjZwK!MOH)kmZd!$2qz&&2g}mWmp~viv?8%2VawtKCMB?`uCYqQ z(O;)eVqtPP19?>2=_@nu1Wk3R;pNw>uxj5lV+>vlo`65j&Te}7?)kdvhX3(>{lNd# zdOHAtKGv2ocP%qjWI^Q4bOB&pMPeu=z`aa0)z~@Wcaf=*$Jo?;t)U5u%wotXv-{Srmv$5D z2lR35FqPn#2c+Jg5qfIob5(BFM0sM{v%ji*jnZ%N`fa?U%ra7}IbJF!Gy**S*y{HN z2?lpK%X8TVr=jI7!Nj(V(Wp*Yjs#7rwAR(Vqjji-g{17~vGzK4 zY}f`etphB0yoniXgaShjTFm`vFl+rX_KcyQQTK`xtf(=`jW8-31+17OxSLOVR-vaJ z$|?0w4EP($Gz`vFC+Tr`tF%?g=^4-@QWZb%!WJCersy49<#S3wFfjgTVuftTl^1~zGvyXd-gF|JFB^#Da{jhweCK;4?GyLj1aBfr>(1dY- zLS@Fmqt!oGLF#}~cx)J^GTEl!GIGVz)NKcoHsSS0Fcg0iNUc8>VacjdR>Xb#e-3+y z$cWAd@G*ez?8~|k5gnMqsqvUVr93yvAG#zC;eD8dxupc0(npH${4;(QvPp}VXyOy;XhTL)<53eWb*Gusol!FnQf793+~n(E)^9PyjHMhfN)g)VL+s zDy#&#g*c?lJlgv1FAAUbF=_nxepA5_3qNztq>S%b{7gR5q>-=dtrU`8Md17M>-K*i zXU~Ayh#wF2i^*6gIWjd}#a{5X-71^NI$o5uyv(Ws@29&q1U49xf@Gj1 ziz_8i!jwr`bsweHxW$430m(+`P6MTsVf#2Ou2Jo6)xUv!iVo`(O zumZ{V-es9AoXy0HLS4kIsVK#VpM>jdGxoPwQXPG~i>2f`Z@x`4lo3SA=WlV785z7r z55coIdtn{oU&2x^@2!m5Ht(I*F30M!pp>CW|%xaVvkmVMfU=md20)b&e zH`yz%HyiIGE}}ZsnZnKt)aA1q6}w2aDy61-$__rPPDMXCuZt^&!%CsHjvg-mDH3D3 zL=*wNOlG2>v|70Ji4g8hptnXU&esuwct*N*ADB%FbNWnc$L>&Oh1^Tyj5eW>SauZD zQYEBjOg(WL{(OZB3;{GqkE-Bjk&WqJw6`Usk|_@p;H_!LT$0PMl?>! zRSra8(ZZD+0x9!~8lGQ2l|#%_2Qk|dG91vT*vky0m2nVIPYA!|2c-t;h9=o*h)iNC z+%*JDbUmEDYL*&<-Dip<%Q;g1?#s?mVi(Ye^#GAoqyW$z>qv7LR~;afwUzHguY)^y zug090OJiYun8T&osHZ=589EC0%G@UixHyZ+l0*dsTx!*b+qtjRnHXa)=8N}pv{A3& zcr-foqgov_xNAWjPK0Vef6VJQF5TJj1=M?NTDAoLwc`H(? zW=MGOs(cc-WfGT!g;p?E1l$WNY-dn)*ihnH-IysLJv`$qr~eB2r$@st5n|elMBeR37K&5BKABZ$7C& za@cE6Ae1jIsDUEGoPM%`iHxuMG~P|ja_`k(i7P;hg^tWUpF1lJX5 zq~raW2dtFc7+o-9-4t3tb&i90OBaOH>KL41?W$cQynnbC=)&BSa8oL*_JQW^*9FF` z_E*tFVzKUNIv47azO*I%+UYc|?3|0iD{TcqT?HhFq4fag{t#9cX6DgF7&AOOl|VqS zpOm}^D8xF(9);ubX=zV)htZt`cD~cgY+b*S17f!0(^yz{~;XKIAaupKsKtzBnZlGs+5E}vxB1$c5wkC1W)_1s;yi6ZlE zzdx`w@8An*?0x$MOyN%APV9XrhTDU_m_`&3jj+O<4o!w^PESSwZ6(dm^6F0B-io7u zJ|u7HHg9i*Q8Azn9k5eZ=v-2S-Id*hus>4u1Zu|Ty#evJ-hzTX6fkty-3CBZzI!-u zZ{m_dqjVViu|;A7wZHE_o%6G2f`p$C8hE9L@e4ZQ44LXS2id2gpFy2@clsm>eKJ2! z-T8xmWUYTB4!=VPKC{wx{OGm&me8HFeXboly(L5Gh5S5U+UG`y zt}TzK53@6PN5I~4=MGI6pQ7$N1Z01PyXY0y>J6fH#aanpwLX3z(@Gt-I+9cYsvbje zbmB)pZh_QviFGMS+g1Pc##;GNC!mwxgxRIaLpZYc((nT1?&j_n2vs&2`=CsH%2J(HUE09vR+$}2kZbFbVZd7ZXi8#E(0Rj5BhjzJNF4E2N;gfzJ)R%0>>W-i zNh|1KV`j7!(tCfpEx-l;Rpvw)%-*LCYAxkiB$fd*O`9PIsY z*rM5UqSCV5G#dt9*H@LvfbyyEZTq_G_irQ9j6P*x@lO*|gz%pl8L|J?4E0~mBf=I= z_6E*I<|dBB|7WP={LgIlKR=@=YseuhpnPA;r_&CqCg4&;&8M1xIuwOBhBH?n)cjM% zWXe_;>7_5IMP;IY2KjcYNEHi7dEa;A6lZc$bL5$MC;#nVX5M<7uG8M$E-u`DDTz}Mp+=uZon^&9-lPcUS4`hf=>Sp*!C(qkRoYRy*=1(_hg7uIaz;5E016UN1eM=$;TcSw8~ zARG!*s3FED7@?}j4QeybwHA*L`%#8SeyBzmV_xVI#qBVky;)-C3^8}O3b)RyP!4xx zT=aYP3ISLVgMcECR6+n^*eHeBxe)r62WY~(F3X?fF~06nYybrj)RThHf5n^*7tB;e z{|vz%8Hf$p9vZ0iz3(ce8M#k-v|jU*=Ll*y#qQJ(3wL!`{+_AOM4N&LGv|-cMhia1 zeO#St>_(4%WI?pn9EuM4!8F98*a_t|!06yquxv5Lq5|UK(Cw0~L(#;gZr~v&`g*0PPVE-9P`vYvcvz+?q^V+2CFg9E)FAaPjE?TAsb18yUBw0Hgvs4(Gm4c~;j zl{S){@3+jlQ{KYEJ$LKL^Tvx@*)Kc;0TK8??}du89j{n~7+f};gTKqJG*{t16U=R9 ztXGev?kh;Ot(F}hn@p}DOe(WH*N~_{|4d=NeG6!<7iV2tmh|PG?ad7ddM4`Ry3LNM z1kEkgX%AU20^M!eV@WhAdQzKNdOMm~mDK31_nbn{S0Uadn+zn+ISS+$#E#pwXGnPIGVe-XlbRBJ7EUZcIrbhFVGT{-!Q5%PgDR5_JMf#eIR_84}Id(AO-yBFmL(-UxMOhhGI1k8<>kF zee5Dnmc@}^-{7%0)Tp8L|GC4+c^Z^eMjOgz4koNI~9UR4H?lKA}2 zwiO9K$wm{;u9&fNY!VmEDG61p@m0v{8Eu0fv*pu70{{A@2lk(+|L^H{|2OLY2kyg~9{S2l zPv5ePW7we(#s<)la8c>71Eq$7gan|FQ^1gc0fae|UBpC58T3+rRIUCwe-$^@E1eru zsA!u}lR=9kRjssatlX}87AQ5Z3jd-#y==W~TaSSvy#wTow|(3=UZ{68u6?+_o(JQA z)w981H3CHn?A3;A%~$C?If+nlb7Rx%iU_SA!9R877V)7}o3XeIMTtAc@z0)wySGHu zgM{MU+RJ8?5N|;{DK$B1*}4>9+XI&@hCT)C{v0z=atbx%&k&+Pc@B1OM}{L_GYz2D zT%4~@rgn=J@gcDUT0)%2k1)XFW}F1NO@G&4g(VI{$|hzx$~tEK1* z>X2hZcm~eJ1W4k{M2H){$>wyP@@uoVnkfO-+5p;TF8 z75jCa0u=3?gru}aJGa6$nXLm;*8%+W77d^RQQ(lr2|IXx%$Bd!Jmqy=C^6&@_NsUB zv|3UEM3N+!bDDW{*209Pqia2I^XyDT)2jCkmLz0Hvxy3ne!fsTbnP)AgObj2%!>yv zs*9O%sznR>bt}7^KkCPHd?j0uE55Lh1NbASouk)?z?7pY%t4FyH9=GQUKvLoQy9lqES`e$IW*X(($!roP!?}>c@}U% zY(X0!IlW4fIu&JJN_AdRN*TP;M0===i$45*fb-_>RGuUi=0`8!Z>mJExlMfZ>Q_B0 zQ1taXNZdT-=au9yp}q3+P7OfW9j5IRuL_8|)uklAy{dzRXG}cnbiOmyvw2%ggW;hD zCvVgYgSK1AYz}X-ZK5GpPyT_ccfz0j$d;CoRNYQsZBFI^<5?lPK}|mqM^wn`5!~^M zYm`mx&3KQMhBST5sAHuC%#mEwxSnbws8UMRm-9A=mw7xyqRfI0JS;X*r6ebK*q1mw zAtJQeHGA)KH`>jxI!Yhkn3Cy=c1%+HAl$&03-Tdj5u3WkHz7_qL;sNAfzq(Qp({HV z3>T}P?8=ko^QOX>rf_=(uwe@WFc8i-{VN(5uSMf-f(EE%iYu(EU&OcMcnkK)D&w~b zxN!&A=f4dv4VyEyvk8zWR{1IpvfLv{Ukjw@uAVkx5H-Yxvt8bZ-}N7r zO>e~0(M4ogN}%Z0kg>i4QZ}(P8z${q4WLgC(21 zgY`Xxlc-A`JlLR{tAy;dXu&=m9ol=F&f>V1p}3-U0ESCPDK}+0YTuylr>JsCck!B4 z+3u8Oxxu>F8ar6^8W!675X}iy>2xu;C$F9p?fi-Sv!77-*H_0#NardvH1*h~$_g8c z&Y}igIs4E!F+ep1xej{SHlM4rM#8owu%Mg^2O9hg&(?2t%P1B6!HeB5)k~;#Pqxj} zyOFH+0E`xA5StS8N35Qb$zRmew9Sc94*63J0NF({>ro0XX0szt@^G9uCEG=mo~D>Y zmFxWsv~U&CQDodkwm68x5Y;T~{E619RAa4!lPJ`CZft>kCQBrxH>w!cw^rr~w7vlR zUhmFM={9TZ{poHF)lR9Vh&FK18l$l(7#y;HJ1d~fy%4~|El!lip?l-%!j2rbX$Q2~H0PS2MpXn-! zl=CtMTt;o`f^ZW_m9da^?wFg&OJSRytRf}BXYCH_hkuaGhH|W7Hmv?2BISguB>L$q zc2=aAYNg2X_?v-MutQl2_CZRmtIhKE4uF4UMvgm7O!i+)`a@^siRpEn<$`6P3MfE(2S6) zdg8cxoFeVFYDZ^A9)|1|9-T;R+u(QYwfPV(Yt8fq&!-S_0Vc+^uVVcs&T2l z3~fb{REqP}qKJc#kmy@@5=}>!R?EC9qGR?xBD!hpI>m^*i{VhH^t=vr<%Y9I-0aQ$ zZ#-;SE10;MN*TtoZ$$F4n$py6L-T#?y%8&BX6G|yvPr=QW(&C;^I#%M6RB41+K4>V z{j*;TN@cVgOSb=zWw)PCm3J_|Z*)nq>y{aIFIh(IiJ#t(Ems@eyCaHeYLs?#b zU`)9k?93iGQeq4!RxdCr1EwU}&NxdW7TR+M(`hkQca+r<}%(4R`AwVOtTo#Yt#C%7P*D!+%=;Yqs#lh)1RF@V@B zl-vAphqoYD-5r$pSGQBx$5SEi71Ae3_6DuP+%&^G0( z1BV{qE&86$O$?HWgEGl^v_h=|KIJ$?dAEd4W)_SCZrM%!SYp84LnG$=*3ofg?>Bfo69&ZXQsspNl8hboSPmw3b+xSt(;2UY58Kch7}2En8E zfmSc~3PaIe5Tndq+^i>??~cuc5AlM@Q|gf^WBm}f><6aOZj2VsT;%@6Q!~MIuXBuH zwK+*$_U&5!CmX-cUg_C8m0EP^Wh+0i4>uyi@*)}x_zQ(>hS#l_`W10c{~0ciCx&(d z=c2)Kx zHlHAY}_i!@i@V6wVtVawVh7x}zZw$QHom@BxcFsLzfrG?Q zeSp>^FtNBSPmhM|8z7#^_l_e0$<5m;&qD(79`o9X5L#RLqt{uQ*@<6^9PJsa>ML@g zV(?iv-hG@%*;WX#obbkG`A?oh9u1x#t`<Y*gKpmme3~9G zGc+muqv6emZQH~H-Guz*^qL*zd$zGIfH}R(YbA&$nYy6qt=`w`q zLx6gHX4;y1&#soE1WQULu+QT&D~Q?$Oo(k70CuT8LJP4&tIXU~NnuC(ho&T`oRTN- z{28Rp9N`I~p|tt(&vI%izA({8)&@kw^`GUmRQUWWhGzUBv}aqJ8N8vEpi}acpxcI` zq=gRn0YA`<4T*-b_D6!(6ZrfWg!g0ok(9MnXV8`M0(cXg4pmqm;)7Wi%hPulp%Rd` z0IeI_li5_DO=BKj7Jn_tn&T6QyON-`C^|QX>#c0BJf4?_w}ud~5AeH`Aa{Qrc>7m> zmit`;7{=Gb%i+($>_K{!Y6o~-`0z>d zMQw0$2Su+GwE(-dZxCC3=T5{rBew047{b@K=)p1*JYJ%cJv5DBS0-DQx%y=G{ERzl z-+cO^Wntv~$`XFb=R0uUaQr(QzBq(024BHkRA19S7q}S#+OUOtWmv4{s{)JMP{`>g z2OQA3_dt@DyPtYl@|1qRtx&>WyQnHYPmo3Re?TfUPd+?D=%Ah93l#QZXK0`-yx&p! zUN7a%KYl>geHR*%4Y*Fv`p_xv(=Z6G^KW(}2De4vzZu6J*id`Y@VwwH9q6#^@s|&L zn~m_f+4&dvf-&Isi7PR+SJlnb)05oA~xQ8c_rHUp5&eQ$ze`8=Q15hS!wrY@b@g80>51W)E9d2 z4)*oXH;4c}psJupv{GzP9bsK3=Yd>eH{b2h#V5#-RwXxQd zEGAWHA}PqENt6nYTyva9ZWQ;yjcJVZq9m5%e}+u9QfFuvK~5Vi;9aOHudxli!uU{0 zR1RoTJrg|RCnX<+6VDYq_eW8;3t8S+>`tFc*U}_kXv7zICZHInq2VGnfv3XlM{1%bb;JMz7AN7*-}rVpdQ} zFdM(IP~?v9H*@!Y$gtj^qQyPX;GtieP!zgrCyy8@_I#C&kS3O~mzgE-7XQjbX>?O6P8u5Kk+-gqlIc#=M+nZDpI zwH%ec_e7(@U@IM^j-3wGI?mTVHe@JTbL3zPIkC(#dy&s=UE|jKGeMo(WSd`BeyOgc z$@&K!ZdAm}-ggbL!fIwJ%U<|=1NvxRz@mNx3&L2ZzLv5{Int4i#ftwOs)TPr zwB!Neu)9=G_Gtd)@5#he$h|LSven`#VtY%swLGulS^7*d34YBa#kdEQRIIoI7gO3M zxwJUdr6pMM1 zpfl=sX->755_%p%8z)Wg;QbE2~cgYY!1Pt=ymVJ0$X**7n2^UdvUJr`o zT~SFyTc>huAps3vX0hR=HLMo)*ke|9dI>M)x;6f8C)AqM{2Hkr{Ng0B`Pws2h{QR= zANWiWlkBT6Q|6hWE9(XR&QTk__HN*idtJ(R$!wuo$+gz>lrhDHos^MO;x=7FC!KH$ zM{&3fj)BA8j7B%Jk!=#!H7yPi)ev_qynig34b96Q(6`QyKc{D%tx$WTB;1lws;#3^a7x{Oun&_mr5(uM5Z3dk zK*~uXz6+TN3*ZLKeUUaXfDnzvX|8Alql-*2m8MYpH82Pb@?MVxBtOjzy`LVv4ZT+_ zJqi3w#6N|F)w+j&D*Ks2|Fx!-g*2HTC%CW>!SW&xG4K;+>E+_ePh&=WcN7=y<)b2c z(*+mqosvAmdZRbbFjsghl)9^RgWAnTR<0V-9uYP4yvR!~?SQ<2cp32h74>WodE9~$ zH^wCVQycVfpad8xZLbN9s!vT`EtvP=R!)2&I0x}3X8oBu@`YtNW}r;P&;ZAi;2X_6 zN?OT3*B5G$$uHr9)lJH{Hl`AnkrPebX+mTaeA`97{Iy z(&Y8o0PZ$|7L`*xf%2S~|IQU*Z8fj_ySZ{>@FK8jV^caZ>wgIQhHx^LRTlqK5IKv@ zm2hx?K_=QhR;7eOKQox#Wu|rPimU`Q(=Ys*-c?@^4jMAFBoKqdRbK$vo7Q@S7yTjd z&vrCxaT_c(`mbL>tp9GERQ12mj#jZTbTf7S*WAUKRNmf2%+B7`+(O9B(9*`x$j0=) ze~Wn-n>zf@tFG0GlhPnUh*hzk7SWlaF||p1{TTEfa*&d$im8O6&UrD$xa(6BQ#NA= zuXuhzdZ7O_9w&RY69q#c_BhY2sJW>*Uu`|b`1PSdLnvY)QF0rTo#5nP+ARorZ@P!& ziBpm5K)s+xfhuCjBhP8cv5~;DptRM?j|q(yNtk^2FkePtkKzfWIq(^S3C)1oaqEi? zX-X4=Y^aVs`Fd~^FIXC!p;lClvf(O*IhpP6|Nd8lr<3FeN1A4pl-BNDAB1Oya=X^v z6>440g(@n&&jw0N7UjgJ*pvq!bRnB!2NED~aWCB;h20V8{KlQU)ySm;Ww@v2l z&q^C z&U~Bg^)Dl*)qM#P3!q=WegpqIq&fd@k^Wx>Z7C|7c8h|Dd^o4Vf%#GaPIB6WAwzP; z;qku$;uT4YRF!Cu!bNvio{@EMdDi47?e7r*z!3<0g^1>O_#TkqV;ec^IT|yhcB!98M&oo7g{6_OHsUl&^|O2>oPTiy^09z8Ys-^6-jNobjm+v&D!MBoazH5f?s){ zYKo&Rq3v{v7SAsjg6?w3O7k1B5s!?`Zo5NZI;a{ruld~Ra=2){3G#jFIs~FMu;R?m zPj4@#dW%$d7G&b+g(A{4gBIwW7b&&*R{k9>eRq@a9So~a|&Y)TBW za zS^A26O=no>;qj<&H8QuY? zB7*kIxT`C;1LOp{`FVjgMs47!2K-F8cdA*G^>Q?4G5l(;y~W)`&>%~Ruh~Q#>1-FF zD6R*}dzR*7_>o7-1zkhjI$Hy-MuNDCpbjw(v^?_X@NORi7>$aRh;5{dvGP{jAzcJ9 zE5tUqPb?zpC|G8%-#;hsSFnjXtDBqv!j|>-Vrwqq=kliIVv?%`EmMUEgJ4HYl9cSp zsbSqT`k5&EVTp_@;lQb=v{SEz8E&T&$ne-dPv_8C%@MU4_hIV7Jy=h&gfFVJ0`EC) zbh+fH7g{nZFd@wgCya6$Ur}5GR}9aL5C=2?hp^0JPBTo>`FS*v3ZwOXIn*!8*^QGl zFPI%NW|6p$j%n=i`Et>W^t}p(sK$cIF~)&h%9Lb0rn2PPOdqJ$@Lm6MKD*Wy4>A7- z#CHFdM*b^H!2c`6|LNHRGE^Aa z@>i>44Z5L7PYSWa^^(N0vBa`9-V8?OQH$eNX(ir(XUKNUSZ-Bft;6nequ5Yx(Y?jZ zva>pR@2mIr!c@BtcjET+W81suljGr(s2!PDEiglkNut+OE!Ah#Ra_E zUxKw|6j=PTi<>iKL~XDW7xIJhCM1PhCL^py+zb6$1%vVD*j9qG&G~I_1M?TU&Q6g| zVF)*uTV6zHx2yA$C47j{WoQp&r$yZn!70>q0@Y2kg?WuVGZMC@ZOIlW)!>34N0OX+ z&V#-wr0W(+yAlvS9~V*L)C}onF!Ms^ZmSJ;M-D!6u=AOrI|pKV2ia@PgnFBHYj7BP!0)(5!d@!0E!8Wc;FoM`& zP^-yQ^f(xVIaAkHq!oAyH}A!bNpNldRef>|V2c7fsiieW$X!&HB=I9%-@Zt>ge*Tm z5lL$mt2cQu`noz$z@;ng2=WYq_@SA-nMYq!!(15@`GB}hoT1pUyBcTM<6u~Lz*TD{ zpLZGGcP=rBbWZ6$5jMgoGZKqK{7&RrXhCtc38&z2QM3Ea+12$q%>0sBhf2goQSLbw zj6zTz9|^>OTyLr^pTi%31WBq@o6sLGaYzqD!OEsxY&>U1^+9_`*6$yoqkb*#cR6l! zgZxl9;3#PPDeub72IN$T%lQh!!oGz`@lc3sk4oOZo0!Dkxz%vqNAOv$s)gb`uIK4- z6Vf*Q)7XA01~;mW7iU1{!x@o1tE#VO2}yz6==sV$PZwp)yKZN98!*>PNCWf*ESc!iohR@GTB-;TsjsQ3G2L`vx@_W+AEfLag?aMV`In=1~@5wnJEokYwx47bYnNs8i>BhO#?e3E%n#Nw1?TKsKl#6ZU#N8D;9v(eIcd|o>k`v9 zblxx^QB#k_p0{D-nZzf|rB}#+YDUCY5JG+C#|i|>%dUo(qF#$CP|XI$kpoWutz zoO>X$MPqQ)6pj@vAR=6PfW|e{6%0rXGP{$3rly&t0RO`FI_ejwK2*3jAKEn3EJSat z6ZSDDMn6J2+Tsde!Im(eU3LODO{FKqXUynD9}urASdb|%M; zN>9a!t9Q^k?uX)~$GV3K0Q=4;Nps^5P{K3DJavpQS%^;B(UykGA)2sTJ{hqLcn9=Y zOpKDe(>g2SCjioBB|k`0-a_H1ES}n#`a#wp8fu!LdnU>o7H4l;sk>;LJc~wi*Z8tLac3~tq-_R1{~*(>3`n`d zX-1H+cLR{>`l$fEIX@FiN+gfZf8X28pq)@NtY3LjNgBC*?TNSX6imRwN~-hBG2rx3 zG}IJJDCEO5GfXz3k47PFvK`YGRs)nhRT^Fe)zO}QGi!P1as()wEki;8hb zjH2Qi!W=3w4HzSo&<_#uWRWxlS2m>Kj_*BzYSM3i=vYEiO1(OD6dL@2uJTTbI`a@w z?jT7e_RbwGq9;T;o*{K7>)@2%;p>^b)%fna-2LlmIcYe^y_9faB)s3;*>sXtK|CnD z7^1B@7cgX#<~jE#O}NB$t?A+Tqv8DcV`(9riGPf*7K`)QC&o#xGfY)miAz~jggr2 zv6-bLvtkdG%a+^-Si4lZ_Cy`b^T4#DOZBT%64 zqxY#wRVSBPJv*F{u5rf4j;d__NGT{93Ywc(ZY?i7)FbtlsCY3l;`8fkYd+Z9UAZwv zo0Kga+~V^R<8;6{6B2V5bOJHkz_SKF;O2)^RnOd`cQa6!UpiDwbM(*NzgWhq>?Dth1j=!UR@|zcl0)=VxFa4v_`+sYs*?2 zyOVZb2n(+2(I4E0jjv>=SnyTkkuKR6^Z;MrDYrt8%&ObWft*$>2InE0! z+?{6)$a=$ z#H}=`G;3(+(M5qds+y5dTwbHq<&W*f?f2qRXunuTVpZ4!`9k5G*MD4h%ue=--dCMY zdbmd=a5aA2!kmdd%wXAhIF$>uWQ#a$d!vnEb*JMvLSKrlqeKh*hwC;2ep!oeSS=<-GKO35G7nVumKI!c8% zIO>@B#c&7wK<9&e>OkN(@RH|rt$%MvB;?c>c^u^#uR{u(3%KbGKgDb{y}0%ij|sZr z59;m5c+C|JuT*oo*%lqfpmL^3w+Z=xyIMt@GmteRqlQF)BUqWcX$lz-AMcRD3SZ=b zN_xC=w|?Dx+>+aye3edx0!F-$J#IlV6~rj`Au0}!S%0V^2G$>r(mDFFQpJ)9@0~^N z7og<4`I8(O1%~p<9rT$O2<@|(hZ8UgJ|)n&POfxEdD6H()7umNp8GkI^m=ka)ga+8 zi<;gp?l5#YF<7;wU1NZrdhLt$vJ>~t{iFrc>UbNZaYpBk+{2y?b!AJ^CiR?`rT$T7 zf-*5Hm7X^VO)!!@utrYhbIjVK9@_1s05;E)8Nsdo_-LMqs<7@A?>n>c=PLoU`T}cE z!RlLN;Mv@Va;(R%3*{0ZBa$S%o6J#PQ%vllV+5_6K~Gd$cugzbZZrIOp2O zM~;3wNVRi)${> zy~IiJl=QKCp|mTcsit8CcyU+Oe%~fDj#oOXtmH#GNjjEPJAtkb0wop}>op`~Rg)?b zg~TiNk3I~GRHx|{`uowh%x~QjD1LE`di~&^@fk;>6J;;}MfYQo9+_k)i4~n?N_`I? znKCUkCXTmls)@$P?h(3kq+n?3_==FIw`uaL9rTdD*4j?LZ<6}1Y5JPQ0y6ARRfixI z#%@3eOPaLr)1HHh~b>1%x*k!{q1@x5ktFy^-(L| zLX$EIPP~F#(yFSYa+tUZeW!q>W?YOZGgzJW_WNw~jjX>*3Exwe_82ILq%5IcmDJJ;XqkD=q>pJ0Kiek+xtnspX+*!o zX#jes`jSb#s_4GnQfC4493}tei z{si6J@)<22!?j;*QUeRhPWk>{G7tq>E@*4`U%%Y&|6M7|_g^SwW&c^jy2z@?0~}2L z@szc6b}_a4&xPC^WnJqfK~z3>j%`-!s}(U90`&uq-%i z0~58IK_VQooUTTqN<7Y{KaM)StsT7>yBBz$yL z>tHX2aaT$NfZ^gh0kw}-yhA4+TclX3b!ccW%EzLf_)D+u`et)W+Z^?%4%5BS-e=P( zCoU@8*4`B&+V^j-50ovpQ{0$1pNc*7T9{7;2OMd;?PZgk-|a8fKCE>fK@awxBA+)j2i|5XW?+#REuUqvow3@_8W9Z--;_W zvnm?OrkQW>sG0x6zZ4A6OR;GyK)-(N{6E=;|8I7=|Dz3}X6wBqipsZW+sOcztOhM6 zh=I6f3zGnRY??oZPQ7d!rCaq-kUlNn8er2Pi!9pvLGp?5z`It!`wsG{#J`gfY_k!g z(a(@IezfB}%l9&q^YvJ}`~8a%N+1e9G^xhoV%DeM(|UUGQk>6X$+ds8#T2{enEM^t zAK4);+8gVcmpK=^!jX?iSp-^vvx^ElmYZtp!4hcgCo`XAZJ93OqI zQ$7R3boEwl)D{hFr&ycLQLZ^F*WkJpHs9oZy9SHw&3S{Ol~#TpBP6xI!J)KHu%m zy(&WAF{{$0au|BI7dnum-EUJzw(SJX8(eVajN|bbHJ7tk0Yxl{*h%?e0>*9k{zGPK zWGb;7nDp0oO~JZ7Y*94nGY8azuUXXgozo>^P=LYGQ0q2%Ut>=W4?c?uOGkz%O=@w9 zw@ijH7xuagZqN{*w8x*548h%X_tu}x-Mf)XOBJy zLi)I?R?&o5sqvnK3IP*NRV|OC7TC~G?tkQ4rNX=_ST$dZM_c=BDPYCyA2+9^zriyb z##gYUEuD&>hUQ8YG1mrGE;*T%!WQzRw$@23b<4@?Dv9ER%M=%ktzkx9eDY7g2aX<7 ztE$n*9ks9zAoESn;uOILA2Le-akw`ZQbcD|G|azZ{M_d^d9Po_w(I4t@Ns^?L}pX2 zz5jM<6QRw^lzHL~>v?TrXc-5qDbiqti1ztKi>D)ui+jaJclXVK!_&qpd`2R86Yj^k z?}b5Oa>^gc8z53Z^%M!Cikxx|LHbT2xy1I#P$qE#UTfg=& zAHUTho-B$#WhxFwcL2fwq_QFsn+W|a_J1Rz7TCYby;`H0+QQ4-9Fi;WwFX(9x*h8p zx~5FvnFS!YnDhun>JRrw6U zdF4j(2iffrKD_CNYKdq@C0-16i3y*Iw`+tVBR3{as=Jei*-&p|8~I9aKMPk`MTNkS!_aU-rQ7Y%NB_y+$ci{ey2 z7G8q>`qd2k|E~l4AMgJ-sv%|TVDq0>8LHJbRd4{9KX}Luh%IEt3mYpkRjMMux`M;P zh;r>smMCRV#YVpCSGmE(S=((Gln67ge-L`!F*tkvW?%(u)E5j-M*k$R?DRB3HR)s{ zZJ0d!>~ekR`t2V3jNkeTd;;|$@~6%XIjp-;Pw>s|cWJq$Bx*f8B_7;mT3S??ucaz` z44eXFsvRh_t26k5kOyGv$y_x7vda~ejm2a&p2)($X0#79iHV!rQ zIE2+Fi-oy|G>9e4yv{L)R9NG-2NMZ{g`x|*Oq`D_+moNPsB~r+i+3cBM4TDtjCh32 z4_36F#X`@!uOz#fiWrE`$*wLx>AJu)+U10eqGpQ5X9401Nz9i$=@sU(>MjuPhxM7ed9j4-H<$5|6dj5(n;1zJ-1%V~^Mg$}N!0*B2%b zx&5i>iI!0;^W$E{)gvp9F4jlGFRRfsbWkiIA|!>pTtqH_*h#!^ISU9k^%nPR2D@b> zjVkGwI?TMz^2(k$B*U+L)7z@!<++J;{{mPw&%cUsL?RWDMKinbN0?sZj#v|;Fpu2P zZ&O8b%<86j8ThY>%`#O%hkW5PBkz=MdRaKJb!rt4Wx5p$A4u28o9gs~W|SW4KAwv{ z8>k_0cR4FcCUb^RDUpbwepEzT6SLTw0y_^gq_vCq&RQrI=jE%61Lt4O;3d*|xqIEl zXjflvb*!Im&B9Vd=2mP^S2p(r1tUBsJJ`+Ft6$U!u?;U>PH zzQEiQ1T-lmC~X#3oV2%ETq4`Cz!KPVk8AWvs5&jPo?h*tD~>}TE65oEk#ActMR`l7 zrWRChAM1&)T2{69(pk$0s}wi3B=J5PH_XQ0fAX*Iq_iH3pcqKxOa=Vtl}3tchecWnr4^ z8i(@@U~USBo{@eaajYpQt{c-L>l^nPgnUH<3i2BC@3H1**X@OX4^>&E1Uk8`pDZI#v$jP=o!-g_R86(J{=}7zy(^p0&1?E`gipWG0 zPy+{0alkSMs|kBNeZqN!95wgC_a4mum9uj!~83R-nQL}o!F1?P`qB1EX&BTNm#hl6L+P=EQs#>Pnc6p_l z8ZaNY48=;^W;k5D(&4(=(WJGhmA27w@Bh-nktD^eIR|cb<9)m1eba9KHpBHYy`$jo zC-8eP#*rMhe@mmQ{b9;vt3^8tIVC1wM76A**{)S=pkI&~H%e{ARks#W6lB`1tE8FE zXn=&0kIq5-4>NK&yLyck?=(EQ94Zw2u74!3K4rEA3~3PE#Yy-^fK+yF1IoDRy3}%D zf(md%FrNAslp82EiJK%L4(JY8za%HNJUuFEvVuOv9c@gA4MC`3TZD3dU5zhoOni6< z5+)TUN(0J%8=h7+k#-&|sS1>wi3k&DAsy=A=v(uCSvT|YhQ;V=nJE~Fm2tnIi7p|& z+RM!#Q8vL=8}Z!94hEe=hL%RI`=HDkt+sMbD?_5ivAgZpgjF-a?gLAZTh>l{1PB#$ zcfLbagBhS@bVw*LLYJpHg8bTpcR965WSxm0)gUp1S%V)px}3ZO68m~CIJb0&7< zT8oK|U-f_yB@DX6g#<4aoTNNnZlk)oiIA<*PleTD-vL($iW(3Ml5nS~I`#J<6TkD! z*r{3TN)pDINr91CD0D#Xc|oo}To*^4bQ~qd)6UaRS*~7{^+?0HR#UYiq7ZyP`zfIh z%ZA9(AbPos#j#+o?khDl#H)&Ehtn=O^3pJH{mavg zLBCRMre$WpD_d~$#LkOJPd0=@W9@fRxM}r`9?b&-GSue0Nx{PUrn2uSSWmEutdFK5 z{~8y%Jm4ytjA!zyM36eMs`b!(%`uHc;%YB^QYa7wehwIPW`JwLymki5lX;Kf7cMs9s4_o@__dOeu}dGii7}Ipxp3?$;<7G979Hf}JX6Z)luuQnQ0g*aF|IP=sqv{r(dU(0~Br;om+_<{{8Un~nh?Fpfy|{@ls$4ql(RHJGL~Ck9fDBwqiEzkB5M~X0Q8QDo850>V4|WvdH4dw_QoOY1V59+E)@3bs?vJ8Sj%2z7 z$>RXN{bItM5g{1)cie$vY@rg;uK}yr;mUi_@IV&TbmR&*7u(!x$EEZes*92q*-UQl zA4NsQkKQ366pqZc#w_KPrXl0&NDhK-PcTOc69|%kwr=v0MFR1|hk$55wwsna7Bqut z2jN*|p%*5&c4$&WGJ7X}t3%Q^VtS%KS}54eg%N9OVm+N&Y82lVKW!r`?L z2-&L=h%130woC>XgaaZWL*MHI*GVuyo?$6l23*Yu3HtM%k`Z-dm#fjgDSXw)h z77zon4z2{yzbl#X@gy|iYW^OO0IM^foPzlGjcdMZ8sXh zRZf>F)xxxxWvPZ`g2L?!&SXs5qFGHvTkob%Q==2-E2{E8KojfRm;<-umfL14WlXA) zGnnNW3*2kTAj-A|P?~3DGnt7{@R*UzC!B`GBBIkGQgMsKsZ**{lvO{nO~y^Ct>1+S z6YnNaC+LJim}*2bs@^vT$I*Y9$|Eczhlo;TRY)Tx4?w+>5Ka#~&E%8~$6<5W$aH@_ zK)VVk$vw70Ap5EP_!Wpw-Kq+IuV{?rRxebmpk@mUFmO#J4jx0A5pqQ}DiTN@fmoUZ zsmGc`mUEUrpa57obZLUkyiM_&ah2|S$V$2@bYmNeq_0OxuLLYt7n`~pe)BIk6F_8{ z(G1fz9bw|}Y6C~4XhBrnpTY%q$EJH3_9&o3!MreQl9zqZ0yX>?+@=_75|V>J7n}tv zb#BjU_Q%*p7gpfMAJXDRF}ym|;o6TwDPIasE?i;i4nHSAb1Ki`Y1>Xn#}aHAxUTIb zp*3tIq7=t2+#W=)==KOX_KIUs&@rzSu*cife^qT|4p4t^X{=~A==Gc>w^#J2bm1>x z)YhL!OWPK*#HQB^$+L$vzaIriXg`ppP=BB<@hB|)RiWhq0J}Jb3Ao|ns9_zNIPw2Z zs5lpr5ss`#iFBJcwIY#AWxYHyS zMH-TW2|WExd?i774kYg{_(Xf#YrmZ(UJUag_i zYv!4wt{iypT5h3A6)}icnpZsX0iaa>ux&k(T_5_QHa%yQmnt)k2nZIFBF*lwIsYLf zB3pz~*VqwdolCWdAX{d6NiJe6AcsAed7`G6L7wAkMTI#gRWNCkYhAZa<|PhVnX@ROI4 zHerfliMOPG=~PYr#XWOk_R~BN9z*di6Bh;4au5}sE`EdA zb&53D*uCV$C#178OFB(EgIBYVSQ2W z{0%YYfvzG{-NbDY&Rqn8_K}(ld*#AFDSUN~i172cZR!@iyW$>@8Ss3(fm+X2^D0SN zo|RZ``68%~@XxZNk-@k#lSEJV4lukl%yt}40|Z2cS&BDpyLw2TFrHHS1*vjOgaPl? z+U#VeP`MHT;~2cm!a$~fe;;W>zkw}IH^WOcf-cofBHotuTy9solYpF+VC~(wysWZ5 z#>ZXq*2SPGcHmWV7@eo+c(@}+nVw`h<8v8VucDngc54<|={;<()vEWhrcs!Bt^ruu zBQ#MGpIW)QY}pn`l_!YGB?v;;@G{JxDc5cGCcg^#dpkUD z_-(+Tk4F3Ad#^m8WCQ8??L8AIMAtxmR zFl*dtu08@!uzKk|6dXwwJ5vl3-hzBhqG&2eFv1$L`u2M+aORd5FiQx`M1z?|t z#I6GBAaww{PN72Ov8&8Cv461?Im@Uo+!w)%Z!GU%G6#g~Q0gt&LGqx_Lugm=+E3?R zWIu>hoO{AsoW(71L2I%&;vL-W)6Qg#}?iH8Tr+iGtZqh89yO?y4`R$%x+-fUK3&BCPA7 z+(4M%cFD+gA{ma6Pifgc>mo1n4jcRtS{KwECXYUM`U*N%1%+RStQ9&G{4hW?suLQ6 zEfQ0kSt?rJeIs9rdZ$fFd1lT?NYl-N7!7tIFiSaMj69LTne3)qB}+I+8Lw5@mTNKW z!jB*D)$^`Fjo*}$XyfB|nOR*VxxXS>c#%@^-XER#<3!<4uu|yqhY+ugIflviQ@OCV zQ4KsFNI{z^Vt`?<6cPL<;|{p^a7n@HSM-T46zwzo{x)#Sh5aj}l<^rGBVX1&)hm{` z?cpGB^uBunz7yrh!{(kjt^lbG9kN^U{x5#q+AypsNph$ex@U5q|gSu88=pR=Nz&t z{pfRziuHS*N&~FaOI_765XfmeuviheWF-7Jl&x+((0N~pgouqwrltdY+IEP_1&vOC zF8}X0b>o7LjhMHWy(n+Su1oTmq}GX*Dp_)x1S7Q8c5D*G(U{ew@@7upOUAToULPeE z3oe)rSn6?4gXr{uQXtmE?ms(jlJ(|OC92CS`jl)m;%i_$N_BYCEN*`Q4lWc2aCnk6 z*>x!8)C&Du1=D|iZQ^9p*<>_ z8^6UGTbv3h_HBgM0XDTmW^}M*Q{2%9?!O11jYvb7@Y(4&qb)gO-gm;a^lHVT8|5Wn z4vOOY+9eZ5u!<4~Y;D~C;JwuQ1|H@PYHGd8ZS3feX^q0PfeRF!NgNn{LathMb|b9r zdp#Y}7CD00kxIyvMQ7a^QyW9W4^HE%i<<-{fF&Cu+$!jtjhK5poo9+*CL0)m!N_pE>mkcMG z)Dyu*n-JXPHY;I?V>(+*w#V;x9-XS@FQG;6RBT*xRtI@TU3<%Eldluti*3~h8)Lqm zX1%VPFAO1C77cY*|2Vr>Om;f@V;|5QjC++s*>f~!W9=V#R zaYz_}_z97ZSVAigOpcD#4(5oNUKPjj3E}4{>!9Pwtiv9o>pSbL8`i6F%`AqvWQPV~ zz3gSM=2qI@-Cc0-^j%r==v9hc&Hge7{ml_OE0LV;xnq#@x@2TDVslT*nu059npJdDoxtmsolZNR#3Z*{r8*!fr_YW|(DD>bDbr|L ztrK;2*!}%`k!`vyH%&>?fiY_{f=HHL2)63;t}IqcyMS}8Y#v6N&xp{4eVjStgrWNM z>rGh8%54(5SVuui%~m`GUv<}cPK%A04$f;WZTuP$tj^MsmS(GXGqQ77UPeYN4bL}z zazI>;{p6~jiFOs0>)u74md?n3;rv#Mjn14BJxq3N>eWHI$q*f3EM9zfms;~ zG)0^kHQZ9qXdSU&jgwe|Y;!OI;2fbGwMI{(R!zoTP4PQBl4m};^A1h8@6Dz+!1nLF zH|K}mflj7H2VNZF;IjdR-|#co)quB$VC3B&)I*~CMn25AG1jYuH=DST!Uo8=ag4e& z9e#RO4`KO{Bq!)iMn5VlUOIil4}TAF`u^HuZx1y)lQ%C4y?9%j^MZwd-SMwiKKB<0 zPgwtC{X>NZ-p#bThOR(?No|ji@!QDP%K}@lxVF>H2%; z7M@{d{M7uBMdm4wjO$9}3Z+YB2p63tY@;qpb4UF^(;^3UW0?BEHq{>JC+A(W_Kc72 zT~Xhm%NF3=U$`G#Dm#k0*DCfVmVqWC?( z50nUaZi;<@KcQdb{yFw9pWtEY=My_wc8iK(f{LcQ9Y_li#8)zgNo7Ch>C*+&zRg%=w=n*dQuqN?85;f<6 z2T-{ivy1sbw^;Bbf@6cF=nTttyUPiAS&Oq|9BlCkIXtJws-~^P)Vv~7nXs*PnMT%7 zYuoXd87I(ICJbX!{E_)6goHu|%FTLi?-gs)!bjY88NZ75Y!dDBdhlv9V7rvgZP+lW z5wDagNF)l9-|gGV$ZwjnUkoLLX-6_LOEA=FBSyNtZNl06W)(x#$!znSp$mFDIwid@d4e^RohV}i^HdSQa>J%lk#8M989mGr zK&fBn)@9Xs~yM%AQq~ah*1Ej>unTQefs~!s6CqHs-@mNo`H>*jJIv z$_4~@FS_y!NvJY4E%UC4aah7!z6q`m)6*%Z~RnQRTrCZ^*F zA2Bc6<$Nmpt3V;JRq4?z=fiAJu3tEM?Mz5m%6^-(_u`01_}B;mgqL|B7Q_izR>>T} z8;W|O-O{gORuTiO3+gjd7~tm1>VWR*i&tax0jW2&pWXPR!qXwVZGiQTE1&*o6Zww$I07lDxLq9ij>51M>oxr-@d@v3 z{1V+sC4MWqEE8lVlGNpD;fS=Xbyj5rvTv6FOSlFkpXN{KN`QXG%ZC3r6?y5(yfP zKxHNoml8J-Y8LbXHlIvK^(jV~XyUFzEO)


U4t9J`q7uej;CCdfQaV%!ep0!~g? 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%0ASIq9$ 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
oiw1)&~6+ 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%0A^+ zo}(;5QdnYH1Cy!Lx?n5f}3+y_g_s=BQN8_A`Hr(=EEs`bEUj< z13Wi)Me1dLHuG)p#t}2I!)`oo_e?i=`)~0uW~c_a9k?Q$R4m3umznAenj)kf>+m1H zwgy(giWL}rN@o%cc=;+Zw;R%qJukhstM`NkIawN*G49) zqI_mB4zNBsL=`j#(=C7f5^)z=ut#5~sbTi`mn6&BscglEN)~?99RtQITBvq#2Dw%CFpD!+}yy#4t zd8Fuu<6nuSGZ;m8`cER2|67A9rvI}<`Y&s54JdCM4K%(PZE?VeTlJt+a%+u@aD1m| zgh(QCo0dt3s8~bL6?cP}P-txaSBLjoXvIr#qfEoo~FoE(Gd!e$58-(3B%vu+>DYRvVwaJ+$KCEDS@h zHKf~Gusju?tu|a|^QEu?-Yym8dun@W>JKX2y+|*_`p+7(qItEBr=W^mP zK?AY}JMyO>7t3_&1Cu63R*^6u;Sb4Sr>HdBdxsv2aw?W`l0u6VPSttUEPwyQFwV5q zTh#Hw^T<1USj-Rq;n{o%Y!*LbQ&`CN&pPtSj&Zy4oFD0(y~Gb}(SQYfH{ zK{bsE(^sl@gyjrJnW+q?^Yow+G?W^BS^=po4Eo?u0em=DGN?|T@=5Zp6FJ^s@HIyT z$pv?ju{k0tKTg0!W%&iF_kAUqM4B?Nwnl5kZSeB4+Q)yjI&@LLIV1#g9t&nH=_W+} z&J*fcToydy-893F6%Dhxg`}r4;9st#!J?)&PG4hF$p<4S7o6OxpmqmO7%qb5uNQ;2 z9lZ|XOEuMI?o;zYEGi~h<5*wV*;!#gtU6s!{W1Adjxd`E=GEpOUOVNfGQr*<%No~_ zp&u4anz)Bun_c|dSYy|>+1z2Cxz5_ybE^hl^=|s;Qtqjy!uYWwyWknUbi~D4aT*=6 zWHLIHV7@xrhr!(|XDnOp38*HH3AC9`49|i^yEVo17sg++n=+e6dCaDZiWl5!FC=v& zs~OzVDxjQ;b97Ic2{GR%wJhS#GQ5&f%MXLGg21I?5hH3BrDQ~%B}qY7)Sz0(roKf~ zB_4Aj&Xku#@|PVNx#KjXa5?cW`-|=Cr#w_vylUnBE)Icz#x0O}d3D`}+gp|~N7gqA z>#I!ussbvP0NrfImGbk2mSiKF&2wXk2sD><Y2SN!h@HWY6hHOjy>iXU8-p6)_~Jld-`cKr(WO* zlTJ7~W9XYRaJ(PScRkX2udBa2jq8NjI(=#b#!s}LMq9Wq^Tpzv_1L`ankI`1Op!W5 zPa59YF118GT3zwqy*Dr%Zx|u6qBtGKah~Awpf~voJmg>OjYx4V9^AA4hP*;`RfU(| zNUydSmxpU2;k7vIi`E~hU0T9!3;Q6MhhjL|wLYS^AKxjSc8QS=@cW@T7Su4U?q!U; zV=$ifl~8;X&h3EY)cG^z$-j>u6a-q~n@XxT;5wakbbfG4f9Hj%N{HG-nXZDUerpIx)N{uG zOXnD4ZmJ3N!sGaYC1s(<#G(%C@0jGT_-c=$5ys28}MYe?Rf z2L)>G=IT>{CVCp|@IqU$xp$oj0x^`EKT|dvjMBdPhN8ndGnq2pseIOjeDiLp9{}_a z>vvz}C?X9T*;~(iw}=elLu)BlwU;EEdVvEucNK&$VZ)xIG>t&+k1LyWfrHJS@Bc8S zluf+$$oPk`KmFTN2&(^Q-?y|gwsAEvWiYn4wY9fnP&RdR{U5u$auRh_76dUvW`JbP zSIUS~eo<&umX)FfBp96K1CWt;r+-ws;MFwGixWE9sb{+Uq20?mRONtVQN>H1R!z|yL@+=a@1RP(9I^U9(6`G(ForA5#}YC zWC^tMXdA7$@SMv$DYZd<3IK8t^!tfJt>~7mcdmGBY3j!mma-m+mZ(LBc`~}~SnBCQ ztI@#JFY+mH|7KT+#gTzyz*D^$Z8+)V5w+O!0R0hbo64G?moe2J?r)QEU@Kf(=m3)Y z#3Q6;n2BC(3E%^?5+I(TRQh0#370Bt8%P_UdMY0FHD(%;PA#UcIH~3nuB{o+@HR%Y zLrF1iIf3M{ywV#;eb<&z;ifbqv@M+Tt%4Npg|rF}e?1dr7I<(`W--af9)@PwCKHb` zqT&O+aj{IKcH^L--`2d=w58siPM?Y;LP*LIUy8oVb>C7^kEEI$y+)Mp!-Hhxwh3Ov z>da@Zyy+SYC*1BCHwsOp(4^9e%LD>~Wu+REZHQu^u!LjU9Hy4iOCqHXr8vZ@;MNsJ zbq_E~W5yM9-fFE*PO~(oWmJ1)_0)7qmo}x?YImvg%~noTy$)MraSF<$*kqZp1RU-! zdgWEJXvRbHP=ncF?_2p08v|Nj=!o@V&@g^kF88x$DshS5u}Z05@smv57oe^ahLn0y zAn5gOVa6+?n((0?@;`9?D@tOm8~!sYlLV1wykRN2@k)+<2!anUn0SuPX8eUIj%pId z`p881cS$mSNE49-8h`=wmlJ<5IYa&@7feez^XU6uDZH_gvT5^={<#GIcPUK$ zze!db?$y1|5=|+>$CuMY(av zz6Dqd_NAhG6Uy0>I3?IkVo@!)8ZF;(85YaFW3(1zbAYPp^QM*}S3K zV^n)`0hIwq4}mmO0Kq(6nhYRl8#SJ%g5V+egCb}1J{6Z33g}!%z|s9}%=81R#_I)SF$x zoxA=L;9@KZh06{aM;sK4MN}dlF@i^;=59LnR}*pIZ!{RZahX^2sR!Q3XtGwFOxVzx zLMgC#$0a_BXhO3}Pdg)5v6KQlmM^aMJ47+n{>%gC26FI2TZF2frgT07ge0ihm!Gc;jaek6lftp$Z*90i4SdjzK60`u9l&rQ-zNq zi8={&^j92-Qza%fU9~0Z>{X)SOa~UlSI*tVTVTTOKZQu21cwk6v$8Q1U1*a~y6vf+Jzdo2|1 zX>hW;&sn=rj;*U(8|j6WrkWh@Qzn5&rELo-?JQXucyxc1p+{XBWeHD`8J~?i97kSB zk=9dirou#1%{wVyjrL6mIZx;YXb`^uoPukpWfhj5WpmiRfjpdZo)^tUd}NHB!W7~& zl*+}iq6d*iYOGjEOmn)b@NWqQb-L84xQrz}vZ=51Y1Wt^mNB{3kA_*u4_Hm5j@-B4lBs z-B+h?A1o-&;Xoom)jP_*Ozk9u;yu<}_=-4}$%TsE)1RlO_O>eOBvuySk2fak0{1h+ zSAnrr+7RREE`yYkGm7se91Y##C-s}BU;RgiHEwOwC^o8EB1ZD;s zu224@`6VZs2| z5eDZJ_?Q0Sl}u~wM0$x2{K{@VWZFELwA#KnNr~CM$Rc_L+M@VN77-l><&DS#LvxQ= zoppNbLp^lMtya?GpD#4e0fF8ZI4L<&0ef-zzM?Wj7Vi~9^idJZL!=uvqaB=O*VLIT z(s%S<4q2*MoP(4+;8=Fc-#_y1qZNbaLz1MiL~ z00#iv1iwUZxbn znW+<_@V_2KdwZMz+0F^=qPmRzZD;10v@b*i1to-wNtA`Hs!GHR15B34lpy2)g+a*5 z=;)AocLI-;)^QN@p^grYSyo?(M3hfrP$_0z-Q29cNuW?&T3TJ|#(jOCox76i_tN8; zL>xlEG`aQl(R%xHo5T6@u>cHox(5nR4q|RvRWk>%$ug~K&XFuRn%Lfk9c8LqE(>S^ ztgc&X=eJi_&YC3Rbb%DEVqL~4E=anE4pgqDGwTp>z5E4-RTtA%pNfY{c4>l&vC48D zu6TB6Th4iMeeg*I;n7}x%g&KhmItIZ(y`ixXTol;h`!^n`f1HfWx#_JCx~in)H$b8 zGu?{LZ~(j)BV{e@;%x!qY;01J<q8LA{0nT46DO}1|Lb%K2?t0z-c zIVooPGvb0R+_HBR!_(qMlOo5OFu_6SrX*e4$yq0 z2FpQAgYT{7Q3NH(rP1557L?-ZlV^!CqMgf^OPW5?h>Zt?zxJUyFZ zW{JQqgDrr5C~AK=zo@`CcKo;qfzu88kqrw-kX;bYQqP%%9~FrrH~x zjLz2r2vSS`QQga`7%k5uEl;xPQZkiOQE~HZt(%pwsL%RLPH2M5g{MydEbNfdx4f(ZoBy+htK^cXgz)+6Q`5cSY6lfR!O_Yp5V zpb!`DS!h*}6Va`(TI~l40XEPo=1!K%<ThkaV`ZY_$5SBAQ`}uX z(F6)R0j%m11`+1)BD-;ik7Kjo3=_r0lv5t2YDsM6?-mN5zc87qw6dXsp8RZDsPy^3)NsKJWP~Kj}aHjo?c! ze{bOIv}j@OZMQ^ZcxHP(Xv*B?>NO%XQ><)9MqoI}qrSivbUxxBra8JXNA%|^v*E*s z(-ls^T*#nbI#HJGC!yJj67NwxF<|x|)ExK2WKaoGe+eU6>?gF^J=4>^tOGUhDE5! zt|itR_ssm95`g3A8^6R<{v9gTEOm_1GdGL#xV^o&g^<%O%-#IjZp#S@-j~alwZx(B z9y+@N(Ovw-P^IZJ7kF#59rFENQh%oqo|B}Sx0ZJdU zUq|q+14@THD2p2L1lflnh%tW88QBLM>`!!^GD+Jy@(k +*Et|1HTYER-LnVWKG2 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%0DLOrp1hma9RD(TUP5+5*D4-qiMrE{9XDDDj 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
cs4KQiICt56 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
f*Q)Rb^(6gp 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 yPDZBg+tP~sB}`6a;w~=KSr~P6C@873k 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 C?NEIH literal 0 HcmV?d00001 diff --git a/java/lib/jdmkrt.jar b/java/lib/jdmkrt.jar new file mode 100644 index 0000000000000000000000000000000000000000..c70ef48ae6caba3ba66551c78e2007d4e5c50ae6 GIT binary patch literal 2549806 zcmd44d3x-ra0XHGn2D#L@!LBwLHA0#HB~ z380{=0-HUuV@Ht_ElzC7Rv#OvPe1j)k7SwteTc`3TNmp~^H=9q*QOS)E;jaB zTg`57^3`Ui+iLG!$j?oky}wr9ORm)S8yh#9IoJ5|`KfdF*Je7+Mz6U!dF8h5e|GBZ z8|R;%TtE9LNh+vqj{>HgaNwWY>x^FqGS-ra5Q-CtX6Hg=ku7xG@`fNxj# zn;WgI)<#1kPOi0jJKXx&#@mh4Yl~;{+1q=K-PT6V@*3OC-6o*F((3g;Rjm0LEvh== ztIfU5cIQIgzn}?Q(fzgg-TfUKxB@`m!X^@k7GIgjR}S`it=(pRt+DYIaCHZUDIjWt zna$m|CZPt1J)fUHdyYS!nL7LQ8|R+B@YGWm&Ypi`1`-Y#;Rv{e)RIT~+3CY6k1Wi+ zR9|>wX?bm)X{HZ<=)v@%ZnN`tYopms?*Gh>)}KpQ7LLs_D4N`Hx{s@2bi1Q_u$SD` z5A6NPU2lS^BW@LlnoUQU{xf|5e01pjt-W5ev)9-;;=zaeAKYwiH4b)qDL(qw zA*5G;+iZ0=+HW^Iw~v_Uk^YAaxQ*t1uiZ%=>z``?zGJLOilYKwr@7niHIrHT(f5f% zp4ez~HyWF*z3n5O{p1~=-S4#DISMrcYwR{R4mz#gQO^tzym+SD=pIGzNBhC8KDfWr zXr(;dkE#6V$5EC?P5#0Dr+ba=TPdr_25?XDU;4mqp%@ct^z+Nt@o1!d@<5;X^iT7# z;ZF_Wwf^~1bSCo^Pj>fq_rH2@@9{l3>rpzTLfJ{(Op zufvgwa{tq*p!7o>pFZfOTCN}VL&)Uw?;rK#$B%&gpm8L^j+*pna34ErQWnb7yRG#E z-&*hIFMrG8?>&%Z`X_uB9#GY~%`9KLu`>VC%WIQg+y82{nfCtePHX#SFaIe_I1bXF zJ7NCBM4mr=?wPasQnPof-FYjYX>~Ssnq19S8+*M*KC{#4G$!)eOk=0D)$Z)I8u<&) zoPFl$iTwK1>QsFyukY;SHc>b4G-ZaHn^U#g;B0co@|%rrE}`1l!3jHP?Bpob{br|k zyBuN%w`OlU@3r$@bK~Y-d#Am9JFhi&*V~(|<|a?)JzPSb+dROJ>)mYh@>VzBY<4&B z^5PA;(%v|b`!&Tf^ZiDr*V;H>EfaZTZ!@pmYV~fm4|@4dYq!-iM`}XjcAH0ox7)bQ z4I4WLo6Wqv$G=X#+wL^;T6-%uxP%mD>oIXRXLMZA%^VQ(o4wxth3V;Aw{A`04NOV7 z6}Jf@8?GF$vANlje+i1p;h0U%nb70U=8gURo#2TwUBHdOU}JKj&8j+iZKI6?*l9Jp z(8j)hNtS-k{L>Y&NjIO&XYfv%osAZgcH3LMTa8Y03Pwn7J%GU7oa=e_VBH*P=u{Iy z4k38A2Oy2kCaBnG?t$LMcBkoXu^4-)@BPwBS{l{&0d%=3102R_`)*Kb3`7T_Ag2wSWRVHjMU zQCpYc&o*}`0MM`2UTY#>ZNq7;E>8I3>k|^KE6oP$(u!-kF^vx9-ho+s-G*4AjK*ej zx6yeEib8RuYFlj70leyWTLxAw4SGCA7+?fvf`kXIFU`L$^ffBO7c&oGrM@9pYV#fB zpxXj<$Y((QCTQuj54LaSuTLw)5=-qj_HIw)3q7d?qezrp=FiRHl!!t@p>Z?n}= zz$t(bUH#3sCPB#KMi1nHkDIOa7MeoR7FNvt2#T);87pX4U9#Z_-Pq`Cw~br471aZ1 zK$N#O_4k(4ChEl$w#a5^3Dn~ zE3`QAx(bUMJ7NZuacg@|aeB^A(_&rIg(!bScF4MGwXd!Hn;c>QhY7Ka63cpz7H|&B z(Ve`$*FxQ_wGU7vowjsU=Uv&sccp8GC=N4(`R2ROh~&TygbI&gQ)CW1t#^CxLX2o7 zn`o#`Q)Y1s)%e@UKxr9UvR51J4kUe7l#!NkUAlSD>gC^l(1PII9tIPqP6|2BU<-q^&SK+D&TGM$397+<(7M>dP`t}I*wvEv(opj&Dcs|nT} z7z77PEz6CSI(R2H>S7f|UriH`i~c$2X}tZ$ZBcmPaYak5t}(hHyW2iMpZFj$M%>FJ zkZnOWaHGjXGfgI{nkGy;GKXKV-$9QEZ9I{;C%D(3dYTLiK!28zqsi`&JaXV(tkT5&kcFhE@ z6FJiCPG#{bl-+q38!ZtfGzlo9w7bKyZ z{42-f?`Ucn3W<>cb^p;Ij5gISO@KEz(hZE?WDz{BG_IVjvVsOphu%!dP{S(*T&W4i zCS*qXgM}?f>-h0|wLX+a%QV*(l<6R@IHny}HWmYjN~OiM4+ZTLh7r1MyAF`|$kI_g z$P00`@z9>kb@QE@je~9v$BR4QJ=2;-Whi4Nc~2NO-M=M#4v4$OcG^G98JD0vg!I zAWy_5L4#PlkQWDBp(RcCkqUFGayGZXUK=DYGx-UY`F zS8E%VZsNz;*9p^n?H!XcphjgK*Xk>Cx_)E%dTn`W;YNP_ z+VYZpJF~nrJHIw>pXzJ6A+OKO%w1c{>kA9{@>RQOZEj_8HRsl~`ux(|EHiU?ezoQc z=Zo37V#@kUD|2&;b4zQ0R{TAFW-7n7Fjrrl%U9;=vo>h)Wo-uNu3leQxG|MqxslH< zzqYinT%XlamRFc-bq!E#Va!=9XCj4F>(mG}ht$C4-eL-j`?;xnwu!Q|0A4P__-crz z$Mane1j(7i2wS4_HlDgX?EHp_8nK7bc0&Y$u)B&&v6;1ly-k97BGhg{H%q8&DhI#_ z$gDi{@vw(8MPNJiCh_LfUb8oz-)gRR(S*db0UYA+6-mD08r zlJhYpRNTtBN4mFN1L|VD{-rqB80tHLZ7GC1fn7TfY4N98_)eQS2>^Gniv)m{Zo$6= zBL55-i5Y|RMhyY6qjR2Y8>%#s4QGf-aTQw{tn$o;QC5seG9_;Pu&qlwJfXXmg znk0c?Pp|hwP}~5D)7ei8JaQ;)oC5T%MakqP0)rVKNfZjRt~86GgpP>c3R3gNhWuWb z5|C|-IN+IyL|l~m1LgVY)|qkveektA_I%&0UEp~ziIMDpsmeI^AF{+ zS(+0_f;`97i;(>*nXs{#o5|aIFh_yj0Za@$n`X}%4%0xE&JwJEPBIn_huM(;V@0IL z0PZR|g_j{V7V2yq7ekrtVmYR@3JG*lWsQ+% zCWbK$BL37A>`*E|2|a3Ojj1-;`^p|MdK@E>xwerjQRoFlmD&j^ZPRhC^bvBjNoL(2 zb8|3dDw7pzuK>(r3&Z|_9)JRT)rFBwsoG|O)R8Qsl76~pm#qM?M3JL@xqS<5M}|#` zUV)FN{@qd?s!RY^JZy<8>N$pLFqq|Fr9^;e;Vwt4F<{YE90i zxuWObM#@I0tX)*ysNxRzNI;VI?8+2L*2MO3^X@vUD^SXVoBrVOG#W!4uFVXvK0`Xe z49znnS3sxYClv2S@V;$fAtP$?;+q_@7RXbH46(vyQu#m{ODEe2yr)qJ-cZouI{6QHLdLlyYOk zc(;u#;Qj3sq?o{cG8`Er`kYcZ(yT}i$_xXB<7R^e0TkW0&lE#QG?8lG4|IvTS^d^g zshFsVxJEG+Ye?6lgg4F4a6iOl%yPVrb)bQ<*^aY?YD3Q@kH?jPV1R~%!u3^=Lf>j^ zNFz%hZVF$v0R3H6@xq~$so_6p2Lp^UD5asGWaM(mdpvRd{6H>Nfd}zH zjipX-p)*CNH;JgWB;dqvsdFoUsy0*6J+328qI6u;C9(t+wgiaO7t_u0`%-p}bQQv; zimg)!i42i!-u-KG3qZ)zQ&yY@%u=CT5Mm`H_?Kp<+4tEayh^R(_D*{pkwF#g9uRgJ zFDM3zdN^+Iu`^?yKG5&6y(ZL@&xm0(YRHY@(n!i;>7Y-oL2GeOvpczt7A0;g_Ngb> z_Gw`*1hTfe8=LKYx%$XJ8wSEJfKfCDnp@k~3Sh38E|y)B!-kGXi5CfHrVry#Xngaw zc*fjD35`SMW+%vRa34$v;xc8~bvv9@?sEFP+qNTYNI}lEqs zRgR4GH!O_6d>t3{xj% z?=A_mxw5Cq4tuWcV%!3Y=bZBSbvB5LmBnlF$uI$Et|_+AmB=YFBS7BVZiB>$B=ePc&*Sw~lA7Z|s*2PN3jzAVJ%P8C z~Mf<@VEITEJ9%X6ik@Z&ifruU(qWNmZ}Z zm)7RzRxQK5aNQEY^`#rd2;q(!WT$J3b1O41b9?>D{KEX&jfwo~{MwRcyvmgI{91j5 zg7xbQlq_AlzH)7u{4>{=mX~xyVuhTtXR66R*JkHeXBO)7i*vIR`P}Q40ViRu#PZzh zYf5LYy-a?b&x}#ry8_HBbNS123*@wy^DA>Tt0W}BKEL#8ePMnUJU$;J+PFaSvk*Cz zFRN25EwAO*R+e9$zcRlDsz`<})L#=C06Cv~RZu9&pKC8bC|z3(Y4_z7lJUyH*RL#) z3D?>|*uwJaTE3#^uFsJlTUiDRYZEm{v^w{V*O_kK zznGby6_MBv5FVG3glVEJC(V}bx7L+4ENG8>Zo(LJ$VQQ>qYRsSxDi|%M0roa5gUr(` zQ=w*)Z9E^Y$n=pE=}IwjKg+JkrNB^B^qW+1nMiP4BNi{nT*$>G9kxw@sC2a4@_OP2 zvZoy~N+fyA+qbeX3?3za@;l|CczIcArZ$^9XiJhl>8?$IXs-Y(ix<6+%Kw|6Xg zXv0fIuQ!WYH()0Y7RVqZRJmc{BJgsI25Q}I;Ego2#fRQyI~AjFJM5DOk5G8SO(_cO z(gAIW8*lBkZ;_bV4q=LT$-H;*84t=q0ndrw$h;>J=+^c!r0ujQr^?E%d=+~6J)Zl zD7oPi(x9PhapkW373iaZ7>-`a;NIdydj< z@?X+L7LKFGu-pQ@l8SY>S}=GW0R^TS-6U?SNeqK#;f5(?hc<4uiKxW~dZcrpIuJgH zgl}?|r^`mG7E1Yej2Q(r`;x25KL@wa*-p<`xUSk>=d23Ie7M;pykRk@CWT#jS=#in5P|}x7gSsX_EOLfztHTk%7D{b(C>&9;P@Kp}wsGS+)3(9PJ7fa) z*f=(&8!J$2;gx8zh~9(l(c}b#Fe$`(+s7F-H%SPN$VUwXd)WOw(*LBkhsAt z1Ytx9?T3bCP9{=~4dDnG809pe2jb{5C;@Crr8M@MD&OG`GaibiShDn=@6+g;fA-}xz*?9T`d(x-XwqhIpigtr{Db^Aq+I0O6l!pMCMF--ome*F*%;_Sy@*x>uSt~1R#=2iYQn<8u(9BV zNhhCS8B>|qD%}$Fkz+mxfuwf|J(fI)`J$p+AX%99U{3$kj>O* zr`g`Jm69nRpL>Txrac*rxJH55zkaj*C@O3@>VP{`!3WHZJMS@p)A* z!D6%6H64v9cu>PjB@Aal5?I}ygS<<=uv;Lcz;sSIQftSObx8mcWYeZ6FEzfvfd+tl zjWkbOS0lIcX~8rZ8#4aDN+a|4W6Wt_#V*?HN*x6)sZi8r?^19`PK<}o5fr;8dSnJO zk$1Q$B?a!Wm_p;5k0&X#lsTTDr(kv)@3eLgc5#bkiX*K#i(-{RF%ZOwG#KS=25W8A zWzffl6Z7JChQJ7yQ1w6VTpPA0@wFbSJ`LGhBpb+(B8Tuu+`@FGJqSQC#YeoH^50Q$OT>kNE*e&+kW_H-; z?M9#+!}f)30H5v>K@o%I?OUpl0xe=%3lM$SgyReKX=2}h&~umkN*lSr@1yDpuTQao z$&6A2+D(TaY)-yIEhmsT=%&7~MJ9dij){$;017<|@rcWaHb+h;4uh-UEg8}(8Up}^ z%)$jvIUSzsLpn-AvH6ZpjCQ5xf=)4NdtO9~+_Cu8=1%la)VIOpqYB`i z$QSulfJx@Eu*AU(OLF;hKs;J0&}Rn)MYkYDXdf`J&Tb2Xa?zPFP{ZVmREvSf>Zigm z0w5`PCg!mzSnYsM;r9fb&%}CN zDGcqVi5X2y!e*G!C~SY_PfeWzFzkw1p}4U}Zp*|NZVJ2G+Q=)n_bk%0?Y$`7qQW3t zQY`DijGByht^Ukhke$uRTO=e272CJj=Dt0t%_=FTr0O@Oyv*WB0XWkQ2PKHj>C!L5 zu$bBd`9&d0a7_bxqXHTL-8>7}%OhD88StlR5d?s3Y|4*rNA`pVq>WVK#?E{=o{eTH zcDtQP2dsv4MPP+~FAEKAWCC*img240RZ|PvA6E4m)-!UHHe?f@?_$u%(s7QuiiLot zzBy~Lgh+_9i3TF=VTy?HyKL!7Cq+kO&=ECE$w{TWKt%|$tQvqH`yC~mggFh9nuoS( z@@!*~bOGNZELu$=f`(!hO$3P=z+G6dwCw=yBnT?kldJ@Kl;uOH@M7!t{M0!ymEv!+ z0+@xeSb$`Yn=;|W_GAZ`1Ra2zp3vFkyj+C4?mQnx8dyc?fyj~NJZd6uPA^R!b-ZcM zFjQ3WS}FyGOYNTcq|iE1ytP8vH)Zf8TTvn+o1(`}F3B5&flr@1V{|E<5%h=qkJ?YB zOjsZdti*NZd3!dD6q!q!7#kvGEk3(InCd}bYLxp49ma@(rw^~%Y|W0*IV^ZC+(wg| zFp6u0!q0+dC}e^!wLd{Nbt;X0qb{ZK2MS!l;vYAEd}$p5Bu6NHlmvRHLWs&* z!w4zN6<9?_(mQ9&0OqIBOM`kNjB)rR6_gCaQyAeWY^At9gSt7kWjY@%6AEg;IE9Jf zXf4Z(Q;LeO(kxXmPz1#TCdt7+(%Lwvhg+Kfc(gf2Wqc<%RK7SNxrM*!T2%gN*$X5; znx8OAdRw3Yr-$4I6|T)8)(5{fjAE&DckSX%hK$jW!4EY;ksQaC&P3Tns}#mK&7Qq# zu7Y0|&EgPfh&F=56s?((E&7k^r=L28!#9xgLp8upVUz}WuuyGYWsph&IROmzAPS}c zsi^hMm&;03`<4Kv?l~9V-v-Y~q|Yr%;tYUgJYil)92>tdbrz+15?6|9zy5UEuC_z$ zcpZC$)!Yx9k^mB( zP^|59tN<0p;vqoC)`r@JLx&hZF2gp`GE_o&LS$KP=p8rJ8{}0sTO@loAS$gHIxS&e z&ZRU-Ax{VrVfwaG@lVOet1vMa*U+4mYesOxo^Jrzob9lOEB4!nz8TC$s1Q@%HM75c zZhAp>8?e~LE9W5SZb4*y-KkaK(BQfZ0O1Tv+-@Ru7mT?LYZkS8u%)a5G^>RO7&4fG z6(M3W3D`YBZNQe?X4pY&S7MD#Y+3iHt%bg`pJ9hMoW3Er9E|N%#VO#8Qe>=Q329ou6()jSDGIktoy+jVr&x~1 zMHcY7QDRS=jz3hKLaH9S3pu5md|hMnJf3JUJ862Wblr_zhh#(y-Rw8jy@D!k|JBPb zb!#fQ;x@y6IH%{H6l1EshoD$MhoI1tssk#MCA)AD#$Z)Vwv8@!puoaZvQjKThf#%` zq@)W`uasJZP_q`+RH}%g99_(8q~l11 zseZ|!6%X=VwWMh<2LOnoN5a~PS~bf=-9N^(y+gJiO=YdpTo33uQ;tXBKzJX91La^1 zw{ST^Eq*a?-+|Z15I+{>Y5}dB_!PwlS0bb5b|+bkDOCYlz(5swII|lR-{44q9F%@3 z64-}E*rWpP+EGiclHEC73$o>!2(h(VaWo)$Vvk;R4o<}=F^F1xa&nGIPw57(? zMFofu&V8l!6re-wetFP~`vIKvtJOor5^fdep^&Yx&sSF*QjI=tIfrepgvJ)y=QBc+ ziblkV!Qu%A^C-21pcne!jQ)(RGA4gyE_r0YS=wx)LdE^65Zc8VMcAx>Rm=4gNt&sU zxuWz=FzK5CyB;0)XpIKz?1GY^9LX@I!%41SSrH@lOSGJ}ei}L<8hB>mz;A4(NZ*lY z%I++Wjz8ZW_mOG=`jRAO{)fw+&~}(uNRkuDa%I^kq*3=BC8V`u2r1*-SxBh`qfR0L zNnuAKq^8*Ho?$Ymb1!9iK`Ly)f2t%ygcZ*j$hr>Dvy6zSD#Kz4kI})32tAy&`?$ry zs;TP1SEOvV`cU|3K^51ze!>H1W3`_@IQL^*hbL6L0$r-w=}jUVcBHfk z(Y*=q9MuCdt}C^!t?^*l2i2H!xXL0Bb+zN9n41zBYvQFUr&uSeb1Qfp7W{xx>Q!;B zw&S>*NY>$Z6@nKrY&cmj%@A|aPftB%sc5s`2)EbJR5VjulY)O!HP(QcU8!B~Sdi*q zLn8kDoShI9hWpTI!Vh8^JGXSsN{Y9&M`JyfYT2rUdB9UOd#~AXp+Fp%EF!EjMKVPB z3*La}K5~ZwcGoR}D*E@f$8VO%RwN}wAU^1!Nn7ZKTk5gLIt!I8JrPuk(hRz(GssMVyz*nLSkfp9 zu3$qGQ8g3@Lf{9W6XVGtMFu6q%hnrRG<57=>=5;tAPb?N5LNU7>53e>F*XWFABqYi zrq8$)anQh_<|{7AO?q+KvIHxpirFpeQvt|I;PIE1Zktok%m9TZh*MV5@;TVMi_Krt(#=#Q8s=W?&IQI!EOUejS?Q zD4*`*)FVeHIcleVd#9H;_NQs)b+V3AcA?@K?1EF>zHF#g|2->wUS2r^?5o!o?Pwj7 zuCCPrZI; zYuDGH5RAc)ei+aWR615l?!o2oV|fn4Q0A*&hnH67zX?8pYv!BwgDGEt$$W?`%0E<=Kn3}I4f$|ggmeHmloqMMg>2wd73BwhdnmBE zCZEO|&6~te1pl;!lSRc_2Y=GiW&`I;)|&yGs*+M!(<2XHpGtvbq211Y7r-LR%#gJuE) z&{tw!KtJ^6N-PmZy>*kK0W(Gpw-LZLy&VlOhbeivSdbH!k2*$`rMEb=)uW6KOwhWY zr4-sc`QFDUT(i@vx$}GFVU+2IU>$WR6uOE7lR?O(_&C+YvU=S(=t>33+FU9k$CL5|)@Bk7(4 zFngP*2RvJyqgRp^^cu1%3M2Rc9F%PNi7Gkf#)dwT0~98snv2d1020pW&>F>a$jJk- zeS^@fZ#O%fa^piN=Q8GYg+!KBkcqMTFqecAK~RQLD^@RX&Wb~|I%MY@L{(+?AUJQ7 zh4_iA@+g=u$)f56ai&P{8IP|>qH0J6@u80t%5rVPS=5IZ#`!@$4cCrFQx9ZMc^^)G z+ODG^Vo_mq8ey!m8Q~d19UYkoIB!|N98>KsU{wH28>*?HH(_zMPt%CbS`s@;o>VB zZP^Qj=17)pLapo6At1Fj;m!md5)g(Hj71n2fs`Wl*-LUIfF&lZm@tl9Xt=iZ+}r+ntN$s{-rq{r#!~|z&hTe+(UB>U!&ateQRD;%Vs>viQ(SlL~W=q zX~XE7;$WSIy*l8_#{1|*eNC-A>?Rx0dn$Od4K;))J5k_X>keG%RYHu|m!j-6ku;x( zJtl0LN(YMAX+l70G#Y-auzUb05Hvi@2u&VrUV35BhU9Ag((>}GdT4;_<&{_R)wSho z*JxuQtS(-|-(9I)t(&oL&uKCc zQ7gMs%)D&q!7Vo;y<8_2uwE7PAtBgM_~fC+kOkMp( zXi`$NEukq4{WTJyAU;|qP+_9^)!BK&C1J;M%>Z3kSboizl~7>e`l{NH3w=eXs1-uw zr2R;RGh!PLcz@aBnQ|P_DH&+7euFS2!Hq&UYtCXv&R73gcRzJ?YGn$KMMv*XFK_gw@^de| z@C@=y;IDSQ(#ojQbYKM|l~X%NO$V&)^%Ke{S-*v*(^BH$nlNJ6Fl@ z)^VaTe6^v0t;lSoR6L8u)kS67!Ig3bEPx3I4X{G6wP~CO!*Wb;k)+Vv!a{v%Zuz?NFaR&Ol_fR`C+WpSR{PBR+emHM zwys%yxREYZ7WKpf9DahmCKPeVRsNp22?hM-#w3&Q=b=p$e3z(PyN9OuEkte9A;Dcv zCHHXs1SZ=JIuWK;RoLpV>sCuzGX%25MHXZB@A;^GMDV#PjUz(eENAT^_YEersmj&h zvkPN`;aiy{w5{C$a#8}ptW+Tw(u(a@c1^@0$`+#m%J|y6_7pa@LxIB@8BDgfCbfbB zd0k3BV7AiN1c|uy=H3Z^#GwNyi8KxFY&um$4gR8QOe}@gowl73*(X$2mNxXQVV6x=WA7M_(1k37*H?3lC26lFH44~%uc?>B+h*%I zGz(Xyh+<>CSHPQ!i+3m?sg}?PB;GKkE}=_yYR@W~T|+%EtMKl7Yu z;!Oa$ffK;197GX5Uuw5$CXYZcox~f5)`_itkw!eRq*~0yPC=nDn-N)CF-4kUhx)Sv zb!cE%75g~=rQ^>PcDWA#IfPlpjs%m|tjA@7sI+XITu~jKQ}JFzMPY!~ds7}TNRh!> zfq<`7?}F!jgg7@$=1sfrh8V_)%cPmRs31g#TWv*YgQfCjTXIyZsKW5pOj;AhtqJt9 zourD}{GhZDFxMF6eh|uQz(Alnbr@H9SyG?#p<9?7R%;3;Jz7_zB5(UKnAC`CF}_fD z2O4Z5*XkVLJPivZNUS+u@91Q$abxJ2g^jgSn_A1T{0@eM!&@+bdau}fpgw1a)umu7 zJP1l@YZEATinTl8%s#1xn4U@Y0JV~I6;ioHv=tJb#Y#fqt+J!JwzsY4LCp?9sGSK= z;MBNjb+gF{I<>8aJcW|p)SE{wS!W#F>fw?w9xasM9S+?SR5<-hnoc7e4`@Au2t?2M_$|}_~BygM)I;^cnYcIlw*k%DCszVY3X|Y66aaf5a^nn zdMp-tnpQDq;$~!io_DtfU+~;}Z}5`7h4S>w89dA9Uzm`8c`m=IUTj7B_bMQB90Cqx zM~in-)}DDGU!#Tz)qYJ4;|V)p`DXsqQ)dZ!d98(RT&(A3&!0PYj>fON-}(A#y*7uV zO0M1`c{cb6dg7Ak+?pu?Fn~eRfn<>0H#l^=IeuAVN#uIpE1vn-xZ7V8vHy`s& zdTAE}WhJ)Of=QknFD1A1tsjXM_D);xSbs`W72Xl&?IZh@69N53C?Fv}C_xso7g~DT z#qGlurtKKslQHG5j!-SVmde(bfnt~s@M5!i?KXmGd;Yh~y=%NBOjOX1w8I6^$G2L7 z!>L=~6P4r8FP&;&N|Ki0pDMbeXnQ=FvRz6|qFLbbbReswYA*6%Dl9G|1K_!9;l;th zKLc+tfR1U_@WeGVuJ=uyHIuWW&zM{5{N07+DSRu>(iO|jv)k%TvEm?1SxVx+Ak8}${uNaSIi*2UOXX(Qx^cLtk`hbe*w0oaH@qx+Tt z!JkN&-hOJeRnXkKILd9NA$@fggjp}#)Zj(0+KY3fhK;0c96p zMlUzx0E1}EZE}Ud1BRSf0pn?9r_2QyW;MEy7PgeqMIG;m?x2goi?KorKwgza`iH(` z@@S+fE)L{t$VJb--m5gypFUGYRX$THW8r)LrFtczTgaWk+ zsdjdxpba9FMj@`^U62^xd?*Dd`2hSxL?V+rpLriG6qDRJ4Qj98R8pG^xWBQ}o1D)q zU%O#dKE?Kpvgo>Tae0>J>@!w9Q>zi(n)9;|GJ%P=W2+Ai3!u3#Qt9hvi7+g-RxBGz z9gV#*sc7|4YLc70TMW8)8`fb6G>7KF1qZ-TF-En4T%(z@1=|gG76dzQ(7fhAj^q5Q z%Z$`13Q8WEAks2S)kiL7En0=^Gg9`pB!4?hkdQcFXs+bv+%=XsID9EWYiL&0dK=ln zD%e22h;rei<}Nt9OM1|=p{Gk|kq7-_-?RR~W783L5sDTAMJS+k5UdNXlsPPOAe~Bf z#m#Pbr%eMYq3r0E>lq`Q%$L!9NV`%&)@UX^BBle}Q26VaPNf*i7UPmQ0W31*J3%8F6u+3{Mfqb1%9Nrk&Pi97vJV%GdTlBduV?6XGq8}QTM9$!m z0E`B+#5I13W)-#V;H&A*kkfF!8ODI>A-~xqA&Ez3YXnSmmGql!hR0LV@r9uxNC1MY z0nU2FCk`geM-~uv)o@l*0F9%;iBI8ITEh|w>TY1({R|PugQclTNmbQt8jT8j$?XC(OBhQ<>qbt>eI80`0QJ{zjVgRQHX!2L0xbqj6l)7TF!Qni#IZ!q= zKv7f}figW2@&`sO)D*u>_Nyxo+BNiD3Mx=w^={Jd4^v43Ss)*(yj{HqmZ)&AZKg0% zsCl8F^5NH&(7mg^MUGb_(6Kk`EzH(;}>I2f&EoJQy`L zp#r@R3}aLsW-10v1RmrBVGE%#v?hl^63O7;Yc43Gt>wy|89w1yvyNIpy4J{wfoDrqF!f2Ka zU@te2l-?1RX6jH`tLzO4H${o?0?&v|p^G}hnWo#@BO4Uo#Thrke57M2LNFV&q7mKb zAWN|qTJsfBuD&-4Y6w5vfh(9Kh=OPo&RBavf!$!)HHSu;B=Pq>gpMdL$X1aTmtZvn zl&AxokEB7p1w=c4yTwV8;VmxkZsy`U!Y?SPAZfVfH1>fo$W7iO!Fp3-D1TZUPAz!B zk?$D;S*{Z8B?ANnGSrY8Qe`~C%Pb0d#>UR+kT_6+aLp1tmGgm~pyOdJrr=!Dfu)?- zR($M@pyq=btgF&hrF={pkR*QyuLuq}R7`^sg_U@v38NI7r<(ipMh>fP199VRpe(z#}Kxuni(ie_7@R-Ntp%Z>V;X z-e9R3sLY&rax8f79;l)0tfZjuIkX84HEpIKIkJ=<19|!c(pbdm>ti34Bc1l10HEYK z3Vd~($&zSHzsBSEY34eLM+CA2MM_B01Udpeq@BEuwoDbu4v=XKM2dMR-D!*$Yl$6d zlr0$qh;uQAZ?FckGR1666jtHwYh8EPR5mj+b=V-*6aBbPf-|oO-5_w5B!p;>pUtB=qT@unER;Zd{Y_<|VhX)kbi+4yuC(2SU?f9ybAK^Ss2G-GRC-{h z2F(3JZ7Ba1q^{b`9M7vx(X+j!M{HeCMc1s_iTCYzR@%=MA@dris>uokYq1t6dl zY^njN>xC%R1@oa23se`2iO48c;scpS>7))cJhJ1ENnpnvIkhF{&D?p8GdH+02ovh{ z&10YN%4v7Z3FN6cmq;tycDvcoyLN3|$Y&9sAmXtxuP0$Kv>sI8g;_@wjJ&-EMozr# zjQJoj%20^rZEIz~!wyP;CDbE&O8%8&zaQT|mPZM0y{q&|c4W*yLa`QOrxXYai>_ec z$$|{-)8CN-K1!MRmHXC527JmvGPoX7ykhxPW7QA`TO!14n>bb}bystV2~qfv@?^4R z{2NQ$S+5Kg7@^W+p?sg$!L`(bTuvGu%a2v}Z-T!9O|noj*fB*R^H=}}#9A=PICl>gy6mtV1^j9aO)7%LGT$H%ZH1_T(<&H!2 zLqcN*<4a5>aLUf_F21}>U5S|3pxlGL@Q6)f-Joo9+RVE~#lmSQL8&u3k#gF@h2(xA zsJ(J&Nlzkk53MTCTZ0p+Q<-Zr*uSoVJ;1PS9m=+aRG^lGUNC>0Z51Gb=L#=5eUj8w zJXREt2IAFGmykwu(+gy&G-7h6*qeN<)uF%D8Sb>NRIb2V)T1=Lv$J+T+IwXWbkqw= zmvXty{?)EVf~8$8Ygr{K6oKK+gacO=ofNad7ZwSKMP(j{BsEfXfZ!DHp4+%*AsT@4 zWDb^)8aYrCGjt{l0IG4BhLS&bT}bX&XiU2ctF*vt-t-*0xj>o#Ue^j0IdJ#|~JN{zdc+K(d*d9Wc;7*cOeVAyAC1Oe!29D10hLdeUWT|!TE1+3PW94`d%3p9Tfpj$U-UklgAEyJ9cAGeL=y}ZqIYA3RI%ZZ zIYz3q4Qlr=7%IM26$FOX#+JL=_O>;Vw{k2{PCiVJUyX7t+~8rb745?meFPSiS8khA zg;oYizB9bIvyEw1Zbhnla8zWBSHJ<3kZc1%Aa;cVdOh4S@QB)Iz@)UI;wK$n4q#vq z^ony7fX1O2&5n_s!aMQ~P?CNF@)rYFR3cn4x;i^4R0t#>fq*9Qm#P~)0?bQ{G`tja zfd{@aO=G*MSRiq)mRZI{k|9&_BvTWI*ffebF|rC@Dz;3b0a**H`%w*rk~#{FwFcP7 z8koS-e*RCT)uGBD2Bm|`vW*1H60dKtliCiH#MTW`!NR(fLZ-w@k$D>yKTwOpnhiJP z5mkEajO4hrw?oEgETC9O0aERp%eE^?Rs_}>M;Eauci43_&;xS&f%Y{S3d@+s!bZ;K z+rE$5`xvbTQa+I+hb~+ohMTMoCn>b(6RjW<&@J+Fk!I8&amze>38F!a3wc2f3#0-E zrDQ4VCp8k^NK2RpS;byeizS^Cd0#qDA@51GjREDMKcI)&k;i2}^iq~0Y6&s4F+5zT z+$b-5N`*`V73DLb7~YRPh*DC@E}aUhtGXKuq|%7^a#C?#r&WYSxWZpcg@D3Tx}e(m z;w-;-RmbEDZ=*ct8jsnA6Qb@LC3_q?;hLY8u*dh514`Ihr<(Vm$@_w|tb{QojgC<{ zsK!mFN#YnIS^$7${`9J z{?ky>86MfA4e@|1D^orhoQDCb3N&S6flZ^7;2Bz?Y=SW8?5=WJNmVq12<8LN`C!Mu z(OOL{lj2O?v;vnFQv`2G=#TS2MQJBLdWESINI|F}k?jf%uXpDWfA=lx2}{+u7RH47 zRE-6T@XpqV>~-*kCN%w*3W2Xedk#nJ=!5hdBMvPoi`g9)_5 zPpv&W!7O`Kd5x?aZ_Q+*$OZ6MCT_Gk8wb0pSW;!Nmbuf`9%Aghb6u!Qcq#%6`ImcK90F6esg$xas(mvb>mn+ zX8oXJU2S=A->W2pQ4=ge+cwD(8&{~RRDG3FBGP-H5mP_D1B{lU3JaDor@?p1HVT^* zUr>X)v1qhywz=KCF$)j2RpX8Z5GbaobWp?`5|%D-^a>*qqZCeQ;YALj5G@fr2!ynq z#&IxN85|vq0l+hQJb!6*KIvQe5PE;;qJ#ue9_(wN0D_m^O>ee|^>mGfFIGuGJpw@K z*oI{vb)59SKPkjGe1XP%C!Us^rriCF#MY{qGCN(b0Tbw#0uB91h;7yoc2>^NO zZPOBHR`Ftze+C)}#yw`xtrvxf-`9lVUqhD8^#N%G2P( zZH45;Q%|TId<$N=C-)^{L`Frs{aT$*qtkKop{=Gj)vPFTB8xU+uB|6ua{{M_y*TnQ zD+(Qimi6{#5PQHXiOhl7HNL&7{OD@r-K6qfD2wGMM>N3{=;k6&kU#t+i#rvSu9&Ne zzS35j8pVn^;Z$4(@;|oUPI(MUD@v%&5y}goHb;k}{2++H^lo(Uora;;N9br3%CT%B zRHE0BLIre$4*CXdZ{B?R(%oeKl;5$)z_h`@;km96$r zko-I&jA$S5Q70NG8$-YwuET8^+R!DE+N3>2>3AWPvsFEf`<#ai`TAR%2j&vm8(s@|EQ?n0^ z!HsIWK~u%o*XR$Zz9O_HS)-ZB6+L~5JlN;K6Xb$zQ$!UwDN9c_B z+6w&-=|Z9*Ro1*R|I*8A`OC`-^sBVCIn&H<4{Dfe^_4YskPLk-Q^1N&mPfX*)F8*~ zVwv;0d21hH9Yuh4ZP~Dt&o8PK&a5rVQ7(|^T2gkZv~ECFkbQN2ZHZQjhQ_+XKXZMd zPD7UKEA)Mto6<0b&-c=#vLviQ)8C#_+~2`_4$!yuuVP}1AfAfqYM+)ABx zLPJ^^X=&AdHRU*YoqjlCc6C?{y?-R4JVL|EaQ+;G^owoM6pFzH+0uFsX~5a~T3w^r z?<;efYK7J|))tl-W@fIhAa~rM#d*UbTK6D~^Gi-9t)1uTIkZAk)F5nJsMFUZbVv#< zi-Ja3Th>s^U{nKJe^hG^B}tF0w@Rw7(iO?2TN5Ru)Hp9g9P5x&pM4cIaa4n(NE=k2 zn)e8sLrzQ7Y9yRxf$A15uUW2d&2oKQydg!bUf;oncWbp^JbAk#hYj{|XXL8kL1~ZF zQ?6!PNmt8pVGO)Bw6@FwSt|Lay&AEoy*A#$1#Z!oX2dr_h_BE?nGC*D83J>e@sSJ0 zC9_QoE(=jBbiG?h`2=>5PY218{0sIL3*lSV#ZEzy*91pvW!kt$`Lk`!B~BFHID0ZS zy+P{>Myf4X>^8OpGIhf=f)~i{{RS@7(cnX( z5pqNQzGUrimnrzp(HlJ<**t_%wn=pwk{}PAnwO8OIJD1$7wh#cxbPtW%f7jXp<@Dan3mc zo4Abr<{*!{6jGs2$d!}~TkPv80}(6z{q*)>B+@2bE$p3_d_vY{OKII>`n%q_VB$Tt zF3`D56~{pw))*>V$bs0QR8QCG{Dkx%4slZzcb)cLYr`aPzd`iR8U29!}acggbU5f}rlSEXzX@&Wby^&oqryoTB`ak+hN3wEFv(_HdptZ^whGG>ZC@3uk z6jc#e0A_o>9&94-dj-}ikcCrSp5Zs)W)%9CcAJwMWUr_?CR`&W%W-n*Lb{Wa(#SH6 z>}_i|R4OT|*s54s9ifi)+bwGA(Z0=NYFsR!t<1<$=z(V`sh@Y!K{^VFo6&RF za`t-YpMljWjgfLE;pox0kteY!da_ouHDfPa_6b&j@$Eo6wr|I57qpPs=o(MsrQ9Zs zwFi>t=|{pl(s>NQixcrY5oTcxT`**>UAM|SMFIS_gv%e#*>7v%2uKQ56m4zj(7;fU zA|&!m)bNBFL(hhMRv_gsH#R8Q0jrFw)my)E>De{C!Az;Cb2wYPQPEng=&s@mdXuQA z+)IpK)sa%S4a3>1tkVyBPh}!Q5phamt+|~Z1db~vo<|2&Z#8@$tdl&}&KeGYwb3Xt zF?5POe?teV9X{bl2JF= z%a^o>Q)F-Y8hg~PRlDPa#vX2t8L~`kj?=bkb@dtzKgUDlty94vT&Jf_PPX80zbIc}O=yF6tRH5fo|swun%t6}kdv}75NcWGMK5CJs@63ywJaSc|~ zVBzMPOHyvbnXAcM<*M{>ZG2`2u^?lAb3B1wZd5E#Mh-P}aAN`~tmKaY*sLjw&a{gI zwN!ODHD0TI{__yd*~qR3PLYi>-Hoe^jzjDlyHe$RG;8FV6MN@1iCuNWvHXz4mijyS zK04-=6q_(Xp(|QUNcJ3)5o3mz^pHx#js({GCZMisWg(wVkf(9LrwMwZmY@p=W_7_pgDPu?$%ao;&YQEhy>~ySIDIGRU z+GA+p#`?vPVYxl9!Gvj=f}GH$pPX@VMqM<#KQ{%1#JR#2?D>CGM?t-g4A>a3sS=ZL&|NKQ{T_r@>RF6qn5GM@P*DKr1mK9a<4@N92?(rQLu z9G}tl`Ce~w4bN~~)YqpM$Mve&X$^DH>iTJV`(mrxo_zlKXI_{*#}pb&|6S^}dOOX_ z*E(%Gzp=~#^4Y~#NE>M_m!|z&hh*A8@ekTsOGbH==3J{YGph=c_j(ud&zyejjQ$0j z5Z~8J^XTzg&*g{m_BaW@ zKT9{rOEm4hd}#|L;kGGv%eVxy`*42hSr*W+C=oJF)WT^bo zbPC_4>9~aArs0cPzkKDOMLI+1*xY?<^4!$f$@R16FHNtPi%kYAM+4~T{p6mTpew=P z&GVOM<7JMe$Kcw z-MDNjf?Zu9KUm(-JyBi>X2G&L&*((}mKqxv^wRnOI0i!ZU~dXLGVOZ1*PVV7EKN&C zy)*S@cYhGN2qn8rV&fObMdU*WNbM={)-^~ve4NWiJgZe#R&m;IUVP<@h&NTCPC$6& z{xyuuZi6!TP>2$lRSYb7v(pGD%E8y^Su|J~ODfUz{Sfq~sI~VDys>1RGgqgB8JOz5 z(;L4WK4@JP?i1{BvpIS-b1&5w;wbX;@U3X@E@Xy^e@GT8`zvtr5=k!tkX@{Nb1Yum z*jH{iejU*0oLeN=M{>dDDFN#~RB|#$zSvd`%fPhRc~|;%;{$pXjRo;YmRb}E~fmgsHK7)BIWq{_Jti=$-1QuOJ@COum;3JOJ z_*N%^0LysEb%k~~=w&O-qvhZ@>h8{T>?2y__(Xg>6t=Ziv;Zo%0{R+K3v(&3KUxPz zN*&Gj0cEA=9m4C@u)!Qh;&q*f$1kwf1URT~k_WSf5><+?wYiCtGRmhP_6X*a7Cw1jWbzJjm7DFdb@WKjB$Hq0JKiS)ElC{gZs7zK1%rR zfMOUYu|)mED~bknZf1+!8eX+VkitSu{mP%ERG|V5>NINl)UZisl8jBxI2FuZdb4O} z<-FLm*luiiJf}|lD)ZlDt9)MN70STa=7zQW@wZm8HxWns11-0xNU;f&7()l3S*SS0 zT%CKd)7x@X;Qb+3=^C+>o%}7KRqhtu7(e3 zKBsgV&noe8lU|!-7kuGHsyty65~-4N@3v9$jKPkZQ$^{e{tLQot&fGt;gJ=VToNA# zSe$?Rff-oS01uaEoX8+*E67RZ~dYJ0=Mq)UdD&l?>wtrdvLNM~{ z?qneiFq=;pw_S#e$?hMJp` zE|HU3e$|JCK3?&wd5ZrOrl)?a9rO$PuIl*hbu9^83J(UgD@zM(l>(q8YTDt8F9$8< zNN@#qIVOiJ(U6iOfg~J!&&KhNoxCKMxr%VRGJww@J0pP!HVegPKfFy+amt z+J@4-XA2N0Sum9+1&PKzO@>`W*m6llIG|j7UXQ2WA)whp*Bg=9%tvW4{$A zIT}PaaS>SkuCmUh=~Tah&o#-S;in>wPRappC>$j3K~~J8%nxklun}lRKJN?b2d#W% z^_Qc`?|027&kv-1qf@~CUW2N@;418UV!V_gqhm3NEPmX`yP>TM6&l9f&({f=3cpzTYY(-!`r`tZ+290Z6#m61|~@ z%7`4x*rRu*DCPnC3f`xZ*{=Fg}RGuwF~iW9HF4Yd;J+iR1KvfXt_=+VpCOwI^>&! zXY!nK!XZeZ^oS}Zi9kPY2Ix{O)ip5cO^*fUU{WCTO%{ z08{8b(ph1bA>>BP>39M8JImmX#~Qo`b4d+}SN%%jjl>k~~*2$1E%Ee2iDZ`RwaT+g9r23OZG%KWwwv zH?En%3N9)bF|17Yl46%)!IaAcwAk^$!|(#vR8V95I9O~EYCVSJ2e4&*({m-E6Q9&9 zG-UiRK2`*Si)ZCJWtq^ElnMRuH~;?XlavSP-{rJSNVwEt8`sCFQ|B(~6y8zc@?zcP z>2xXvkq^6=N|Fm~kxk8T!syC*EA_wk)0}Rsuf!A05l?$wtShfV+1z``AeK%zK)9BzwOGbQC)gMzRy9g`YFW9x%%x^4(A# z77|eWRAt`1{2bw5ExV83WBhf4J5KQXfhWF{jXd$>FJ*Tsi8o=>)!0e?2qfmzdf4$J2htfZhiP3{rKL| z?E7ljpUD2*8UX%#quHMn7XH+I+4pBZpdWvFG@H4XD}P2mez2DP``HiGvLDWVq{gE^ zs^|Y~EqfvR4^CyR(d<90v6Ao7kN@aY_G9|}dHwivy5q<7z@OKTpE#B6oXY;=TK1FK z7fxl(Q`uh_&3>wueLDMT0roSa+0WLpGudA}m32;K|H-NBKh>x2)>l8Lzy8vx?C16S z7fxljG}~3goE!{0e;i5weejWJ4b2a5x#wYLW2boutJB|O`zI1ty@s- zZmeSG_8&x3-p%1Rk$r>(jI{VS&q7o;I+ES1X$)s0*{9qrxLyk+K9f-0ZUfAFH&h2D z{s7Xscp3s;G4`>$#6TQO8ObiCW7<~>W*ILg;~p{9sP>O-pa%*-uUH35t)SQ5AIZM& z^m`SJK@gHFhrpU%9)_C{a5COM3}t6mbyl~)6-Yd(U2af@^mHUWtwwNuAWmmG9v1~S* z8Oc6q%CV|Yb<Ep?62$Qzwur@580Z-x7mLOW23W_ws+>tU(81`E2T>u(*d#2GXBw6_TOj!1J9QTbp{^G{>SV$ zMzTj@$$;u+I37sq*{66BFg$niBB1_H**_l3emnc0k&p28SoS-@&02PS3`gnuNcN;= zsBoR`1m@{$_Oirg!f|>8pdKnwm3)c!S#gPm8M~3}>$s;(pFou;s(CCV7Wi7rrkusm>Vo-@D z2f?U45>$#^o1xv6_td{=a$OSH2Yo2jKXFW~)@ZM70E}d(hfX^Ll#%SC0|YMB3JZaM zsA!6dG;FO}gLar+Z;86CB*RGd#1N3?2Uk9C2pgqcezUW@XYl}V-@|!I$|y#%ic%k9 z@cfcX9;&)>d&EOBY2WRqdTqZll6~lOYL>!GBiY>s*huzxx|;Cqz_>=62l{v&B2e1s zR{zBzqkK~`Ou|)>CCYe|~viNWbdEel)3#UIJ;tAeyiI+U& z$poyU#;Rco=e$8?AAIpC;Je=qU$`$jhrfTBsOcMstUe-RV9^xzfZq>F@7r%wKfgbc zy`0T+?`Q3vi+n}{^Y;T>!;e7@Y90$PyVWPiL=NNc%wcsqCAGT2BBK>e!(g`5>6&cv^N#5dG@q z6VIM}=;X(LJZtIWLnqH)xckZ9%sw>n$lbq~z5ge((UV`u-hbi?+1Qi1@PRL84?cU( zL-+hh_RPmmZvNHmz6+yz>ck_XJo(Gn2YrZ>-}cBTL!R7x=;Wp@J~Crh7`Rq?Z@IM7%zn_KuK(?Lz8PNTMS(|$f2tl;qWevu=H`~e9vkgPgtpY)}3IyE>2)ZZx_H2{;P7s_o zvn>!V2KfwQDPu79gx2%q$jFzn5B(gUogDWVivOZP^041m%rFMLV!)f+EhhUkLl zxl7~zb;eaT;#+?{d+3YV!#|RZ^T&f9{&MzpH@=iTGV#UiBM*L*A5VTU``8z=kAE@y z1cZ3NV3=?io)FJ`y|mLJ?D{-3!{&W{$^I2I5G0e*<(NV$mrxxX7_v{yY$HDBPZ>z=OeAZUbOyX zK*)oi0vV5t7KENag7o}_(eJtkA^EW{XP>?SsUQC}=6)Z-y8$OXMixZBC$gvP_p`>~ zpAN*mj09!bKj!}5=850QKAioN>|@zK<*EOL=l)lo`e!`%yVS4_5aL*QS&lYgc7H~fw;Qjz6>2`qjGps|}^VAcP6Gb;e9DVZF!pa`f3(2AlFqVTTBAwS z^L^H9q@G}GtQglqSw=aP{jtJXIuGyZzlTp??SCP=>&w{-Hy*t3;KeUxmwq98NVFX> zC&g%s?HwJNWy$|0*YC={GyAvnXjbQ+65sb>*+0{t`2POcKk~obbsx9$?*(qG#85LF z-em8U-HycD9f;ogQsA%GvWK#ZquHfX*^2_}^1USAzu`Wnu8(F{?n9l;jApaA5H5qv0O!i3wFSI3Mredc zeO2k3F}$+J2=z-au9pH&HK5)`*WOEDnJO+?HG+>M9n$H+2TZU&qlmW24&z(NxB zNgl77i!L?(NOnHtUMg6)liIM&>El0<zQNev zL|Bi7_2-%UQ9dz}&C5oTI4#U_E4UM9uykc{WsPiKz<7&*b? z12J|7Aoduz4G{YP@$C%UIW`c8L%_s$f(dyh3WgmMOOu9)4@?RZ6C_qn9F2bpE0+Jhu>225mGGTd{msCHd4c-H31j%kbQ4Vd0jB0&pU+wThne?B82d+I z?LS-0n=w~p`J50{B36U-o$sDz3?)*Y0W;{a0Kq{Z{-Xs1O9Xrg+fRxC9y~Ds!k=U4 z9|wd#4+uYz(EHH>ghvDGXGo!d5xqYg=$!(iT$7{Yc))yc5SX80=${6dp8=Sk{R03q zVt(^o*@d#EOcf=MPJGw=D};FZcL6k3bpNcE`}Z_bDKL{}`&`!O`sE zSavCUaf}q;H;kdSJ~5ho1`NCxAsEf-=Is$Yj*;=29qJK%YQUjMkrHVg-J*{lc{d(C z{*PDQ^=~#6oP956I^r!uk&E~B$>S{dPJ4Js9bVkJd%rbqqdS%Anw)4uL6}FaoX#TLnzbl88vbr;;x7Iw8Qr@>>sk-nW7Z$iOFBePP#Wkg&g*QMEc2p zo}E1TFS2`2{vX-bJW~~e+aGmQSMaVy^k^Pi2bFRW#Lqf_aHFIdHY0| z`P+kCd+f>I$Q~wfayQoHfQvts^a_`e`fBwYaeq73id0W&N+9^-4f9L-~Y>p zoO|xMb7r3BnP;APX69Ke4O0njBO0vy?dpui^3GM5IBL4hDs5mhhW8C-4Y56 zcl2nbE%V-w1N9-1y7yBuX>#9FYKi!-3@>zrUBgq7{5&T1iXYfwpDiAaQA9k#mq%mt zk$5DZJ{0@;@)%!!$d|`$@dV~D{o9lL7ENQ#$i@e3%0;t@yul0RSOhp+J6D~@=T8+k28 z?~7kKqQnuucEs!a?KcJD4e=&l-YO7pi{CQD?=UXE<7dC;Cg0`D9~|+XBi`qSe{{qL z{P`y?_96fHkt05K#GebWTlg18U=l7Be|5wsw)k6&W;2|B=eqyFzyH$_pE6wka>W1g ztN-R-{$q>JxW>;5uw^LlSV}yW5nEc0zzqJr%(G?Gk+vh97_CH>)Z57}dxER4QE{ zC%f@`g|;k;(TPm{4`p$I>@MR4vWM)+ml7`D3%|LoU@s4PS(Xrx1M^13$Ar2o#*eKTl?`r|{jOjy%kfRgRp>G@0he z>5iNcqqscWmNS`vpusGr%xp(AIdTr)&UM7ej+|%9`HnookqaETkn6)9;*Ii1TP}9w z5=U0^qosUV=7=*K3DlN5as^Xxr6Z5#AC9r*D*k?~BWrBA+L6b_=t1!!S95#;-6v1r zLMNhY@n^j)8ys<|BiD1e4NS<5wrq6dNsip)NI=`{$QE0+^2?iJ z^gr@sFuiPx$#&Uc%Plc_Q9QzLox+z>9l6z!+xYf0Tb^#qGh+0LJkyqEIpSu%J-a}j zBhTf_dA9sYjNXti1ul>m*z&>{y)9vO{I-N0Z-KnTk(b&MM#tC5H8FaZDfl%{X18Gn5qTN0u)vrMF5|_Vp|KG$Pm67n_6{j>YBU4c`A}0DjU;< z!bxo_Q2+mHTk0di-I+yC1;&SDP`-^lFH`q6jCB?t@LOSc4EEwvg97c4t=bi|Tvr~l zMNU`llf%q2GYaja>0kX_NbXtHLE41LTfrIj%eK7QmfsN6dZ0~zVYp(vN7&%mR&71d z<}=v7nUDM)%Lb)EANy3bw8o)Oe`8#DkphDKVjkZJSzp@>5zxbI$ZbSnq?yfS2r~S zPUfQnASmp`HtS(L-1H%-xr6r}kE}RY>#F>shAsZVW&7GK( zf@!*A;iz%;Sx(SQ-EkQZR6WrZ^u<;f$EFhzJ4f&aMb!S#SqH$VNH2@&VGhn4IR$lx z>M4`gBOovMQq5WFN3i|E++e4-a1_sY^R{mGts&K%xuSucKJrw}Sn1|?D{vPmQiUpw z*JJ8+rWW9mJX{8+R}>~Y8f7n#o<>~@!K18x;3qhtaNvK8T;q41+BLY5mR2+rLtoBS zb3DG3j2fL`d;qf+4OO(Gc{5(dO1rUrxi=vA39w4;bV2mTYN0ZnPBlsPHy z4r)gt7v*Mkz$*!n^&vOrbfJGjQ;S)vCKf1>k1TP1jgD5*>KbhMO$}Di94O$;R@vA% z19dWRY)~QV2xy*@)amBYf{QJcpg`bOldZvY4hY^=yMkK0hu%&W0C%+7@)}@iwh0*4 zbb+dw>r@zZ0p-#hfO}MlHnyD7x(R*U*ac`peQfrE*T?3gkXR4xqk<9$>!VLid7wd2 z1{-G6sNBC{-MjVaCmwRi-+Jx^5L8D;B z%nd1m;p(?DM}-Ee_nUM4VJ&EU?rzLDFe}s1TvFS_fp;6cCKw7+h!?ZG(&q|VY^Cm9 z2AWB4*nykN1!g-wbr5t`Zb;K%%2dtN+{NI`3`wjDg?NxPNzFZoWnup)X)3(BQ96N93;FTgRgFJok=}EYH~+#*Ylj zmIEb*@qTU?vv##20c!zDTUdyUkAkM=1|!3K6ub-~M39HdUkHULVHR>5+kItr>3TK* zNe4d_x6m9g8ahsfZdu;2-gA>Oh1i$p1=+(Vlv;HyR;y2~pc@YmdJ1bV-MS$o-)T=O52{)POsS@I=7v#>fp>mtd;VS zA+~nX-%>rRjj_x|!3+-PTjKbk8N17P&))#VJ25W^nDVp!N(Rm_UYnXlok)4iq4_k? z^lqU!QTVh7=_M(9ES}%LQl3pZgV!-zTdd=PKyADw2>oBr94sxDuGa*`Q*Tfummuk6 z%(2+XV4J#Vi3y2p!NBbsMw=&dkM}^i*X%<7g$&cL!72)s5Ld6x zAS5!@3l?c$_J#YXQhvZ-I%12i4&k^ed5aVS8!=-MR1k>pS-5W?5Y?Mskk)z&1|u)3 zHminp-7Q~k9p6RYbGdaK;7xi$>*xzzKh*|rCtaa!d95q26Fae<<9%0+uM#65RM_nu z8`jAp)vc-!v@%_&t*y1q6|Q*5mD}a@F8z)E?$ST#pDsK>{^ipD(!Zfks@GFDoL%}4 zedf~VASv|=vA;3GuvT>Cw?w@wZ;;;(9h2*UgYE3ltI3h$if@S66UMMJ$Sz9GKp%17i6 z{Na@J%++*s<)d=HEgy5`55+haQVPgEE}!rWibJqw-ehy-lkzFRs*YjIfK};hQTBbW zZ5hcK5LFsiW58fJSBf32DqPY%^&wj3WZtoZ5l~vYy8nG`gGa~Hu9z;Sxk3o(ikrnP z=*gsL@ix0$F;z^n1jruV5p) z#JZC(9K})cHHcb`HBX+IIX@A+jdZRd>Ey}jP*(?qc`C*1p=;;Xj*-7Q035NWl#Zi| zIL!WL*K}L{+7&hObaF$~Rn5E8j%%w2t>OAbOM>loZK|Ds2r& zoW!YSJ;Qs9889PDY3RC2!USWwGG`b1yBtXwfh{A0{465hl5e}>>*6X`{#L$&Uaj^8 zhVC3Mk}GeEPVnYeTiV@^|w0*hwt-@QgF^=oW>P%0nh3+pL=Ai$RBvW^or4@Vv>_BV76jd@IgeZuh6V2v zx#AA7!xbmX_n^7ugvQrNVL{x5#{JS}%LPHJJPuD5X#5Ou7F0(ctymH*UXS?Mm{8aj zj!!K!a$^>BUGaTZ@bo#jDbdaH-u{6rVqCW_o2~BP%sky|#77iWr)rPIN4IQ3wuzPi zZQv{4=gWJH`30{0BTxDT+`guLw)Xu-TydfN0NUV23)2zs!jWVx&`S2mR-qy3eULr7$1`KV?`qfN-G>(%pC(>#W*F1fub8Jm7TzrSQsB2hB-F)-)D^uKc@v9@<0N z2s4(G&;jKOw)}@H|0%k;@>5ZLkXE*g{J&iJzYbS`BTo~%wf8=Knri+#= z^aq`Cx~k$lgVPN{`}+k4;;!`tqYd@WVhF;3LzH&WFxN1>)iWKKJj4%5LTb}}Ge9>~ zM&F`8lVYbxV`{&_bd*W4Q>Bd(>55{YL1YjonFgg=5(O_ISlX84IRcg%%x=aC7fM$U z6DOayd*;+4U_KT%dOJdwT)DBW^;C|E>L30pCQm+v9>?2po=p};34cr7>A^}N?aV2) z4E7X4rq14uklK7R0ZKa%GWI=;ck&zCmq9B-a9)hxQM^-mu+fZ+@I=V~Ne3R0C@gO> zkZ2f!93`DYJvP_EIJun1YPJJ$!_dkWRt-r|Gje?H7o zuR(}~j;D29`m`{GaWqiqumaw5gV_O0`%u-obWn~nfYSplWS`>i`em*^+&(1ZNh859$GqRuvvJAMu1<54f^qqpd>W%wnn68OBq2P-X=D>u^?VnPvj$= zi=8!XZG)W+91&v=Ei@ebTCg7+1lr_tLFoLgElFdf5^R3rtT3&v9DbkU(uQX4_-g3) z@-TPhE{{n(L&Qb4r%{7I5mHmIv(Q;yAAtfK4~!RbW!btgO?ZKB2Y$YRm%1t5^i5XK z%Z-pJ+Sav~KVH zL!=0%JJyQ9n|+!1nM()?4SBB_C89FF5E}6TtafAjyyndvh_1KNWWUa1bM{jDru^8pKX?v=~{6X|z_i8v@r{9{NkJ3`a0#v8*S&tj2i4s`ECuFx#jF zmZak{P$dH&c}m6lRt$rY8D23aV}CqBKsXQ|>PvSnu?+4V-on9iP8h)7u<2ra!xl*J z4IcP7R_lfS`GSC04^ci}Vu&zVfS7;oL)4AG7nY5IuV2w# z#Ni@+(;fQo#y7;bkr zAq?`Zg8eIXK#2vSJA#w(zXg2K2Z}MIJv>Nn1*GhBIPZ%tJvpG=ix^f9D`>TI>Ffa7*#We( zJ!k{*(jZAu&`6Q!&HTx) zi$36VDH6DMQRQRwl;|t^A^Zq8*57OFSdU1>XsjaHTA$R`UNBH94q7V?S}WGAp{-&u z0PRLpyM?Gd+3sxB@<83P*bA6qDF1r73M1NgA0=wyeRos8DtjOGuSwYP0lR77{_>}3 zGNP{yvTmZWTx1`WVmJ(rBSz#~9b&<_&y%3+}|fhcoNDhy(gQ;tG9; z2rnNYc;?3lyYg2!H-Cb-rvIdGgFn7YpVI?E(6bObKNnHe6{n$7Zs#{v7;2`9up>){ej zki{0nTMKaAv&7{&9&AjG&DhM-i4-z!GIuXZHWqq~~XRo9BKbe9-U_lOB}pE!gb z5))~km`qQKDfBlnO-M0IbQ5z$A2Amt(Fd3K(jBaJL#^?KD%|h4HN! z%LR4EEC|tzXUu|mm|17(`ouVo-E47~$8Js*Nm7o` zkXm5gfx2uAuJZC~jO1}uR>ImvRaNYipP#VwfaM5|Q_&%byfKMrh_X7kc`O#ae|`80$sO{84pzjcGv}ApR6h=UVvtKSBtkhoLx=c6 zZ6NdL;hszmKvh8(8ae!t4W zW|i?HP#r2+5Y$>0Ux;{}i^3HiDG3i2ZzmPNaxX0r#C1MR1qlnSR7l@+zK4 zECr;0P_G;uneA+UNT&MbY2B=>MXMYx^5rle*i18RR7BVb!6Ng~bup04xzya^8e#emwJ+62`&#|n> z%|_1(F$rT#_iHiUMDz(drwsI3y2K;>GD+1tsG-VYDlcbdU9pc=1~c2yn%pzv$KZy4 zov9|cRr?S4g?&_0GX@IG>YacsiZ~WM5zLc6=Yjt;mCJYz7B^8;+=|$xcT-Ps8^XKZ zPNm`wgslB89U<<-2)~O?5%&a?>P3}eiZ~Rw9ii?H!yRx8=yQ%opD6mG3S)(Xj<%}N zptS;y(!{y|>^X2{E%;lYI`e;JSxuFt`5Y{IT!g9<7MP}>Di5FF8W8aK?UYxsv#bI! zk56E<@_-b_T5waGw4pZ?L9*A>T7=F#j1HB7ROY#7kh#U(jOlOH6t%1DIE6y?B*2i`NvzIO_Wh8m=g2f!POQ!ejkr zF*t;mb5Uqr(-ak1&pykeVllN~0-Oov9Eu3di*Y9rcdigr9HzKni9lKa#jfX~E@t@( zh-<`-?vJ4h-IYZ)Uszacl7enckcv;-t;mV$FlR$*5dOxfPmQXIP$PZ=RNtW9;vLNG zzXPNGUZJ8_W)(q4S9l#Q#8R=$17{*Y=J|-@uEh325b9uN$+d#`qpC{>UWs{i32~HI zuH_WMpKFAg(-CS>O1Ozur8Nhm8T zA#${!iJ``RnAT^5+k`kqtn$!(%|o{>gl~{>C0*(*yHh_I$08#^(_~-F&HZSt96;;kKm+f#0PnT{?>2EP zxKkoHqpL)%##>EA3g;TJ+Qa!B;LKA|2AogN+{Nm#k7XHm@foRD#?RD!eHK14_43(J zf^{e+)z2E|k-&KraIOH(V}bJonj#NDw3o?LFQ?GS@=%5IL=A05oL4|SlL$;%sQVg` zA%!>|y>2NLix<1I#nDjT`Y9TmDAss1xD&tdxLugu@98u+hx=VW-bLqP)+yhqX7PZ9 z&ojGI337QjP@4(V<^r{OKy49FTTIjC5~CXz1}H5Ix^W@8aV=1qo~0XW#X1j#Q-MMh zDD+macsg!gIhLY(=_`50z*m7ARW15d)O+Hm(i1;Q-%d_#YL`ORs>ZeC$@3bw*yLE_Bft#6i0BIFj^}Tu z_N0omI8c!;@KmH@Ln;zhU8yS4g`SFZ0552!G!T_C?2 z(7$(}I4w|j8x%KQ5%kFw{<4X#(26A!M)gxtaXJ=U4l`yl3L_b=%HumEcqk4L_SO3kk8Rg@&(!l1FzDS6 zRiE-i{h{hp1dXB(1n;~=utoj6T1Hz)4D>B=5^F1J#IYpj<)X!=`kn}whw`kq*h=@D znmXb>Qb6jhQafne4jQ+0!cTh8j$q=nU_ zwZD8PC^8fg7w04I&sw?}5nBm=-&LP_+|Eazk^B?_`d=8YpV3f|a84vj^CN7v zBtokr4jmuKr?rt7ZHg37Ys96kk#2N#q=;^ebf@n{;)=Meha7>8it$*AvfR8UAoD$n zxB@AZj?zmXMP`4&0|UGaGP5wH2P3^zBVm~-*q+qup-S`*5Bh8Uk*rjZZ~G(pJGvWq z)yVr%tah=2{zJO)dK&L*t03$G3^Mn5So9;|Pr8J1hh3LJD z6a-qN_{#^p6F?BtJ)_#ty61!7^D}≫pL_BBg*284?!M=d@-nr�))r?mB3Iaq6 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

  • -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�I)%8Y*i|HX_XXQw^zsEnCzQkalzmn)6e?toj& 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 <|}^lyDVzxiXFP`ye{q9 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%0DG(&E{T_8W=uRVt~XC5dNUXG zCTl_P{Q^MIe5jGME*m4a8`e+4?<-7fD1WVqN^lv2O9wLuog5G57ZM-GgXz)?>tm^$ zG?;_wiK?e2*^&QUqH_jEoijK>To#?6ajS#IjXGn-A_^E+ zKmMd?QcWk#1g=h+iKX53qXfL8qQK~$^Nv`~hJCP4e$eZ~9T z*>9Xb=u$#p=}#)I-Wafyt?vDK$oAE>=nJpWVGk}%d6vJud2aUM%#mkuaFaFdI$W#6 zejN_z&>?Z*^*S8HgP{(8QZ~Vd%@JL({~a9ce;c&_ZP0HG=BN(Gbhy#iPI$E0o6}}^ zw7Er9vK>Zd;G0{0^8(-8=9}B$@%psK{o+Sn^xY4P@~(nYgi||uONA|}4>t1E^ykbDv1a;aylCPbe zy<&r2%r!?}lxbGYzSe^WRdXewL6LEutmj;1#k=HaN0$?$tda8!sl+OSQ?w-sxqG`w zuC{~E)}^EbhI~%+B5ZuXaJ%|y-Q9|V*pOA)nZl{dysu~%Jg+>g<@eN8K*_9TpISj| zaSXg?h}#bx>84M}BFO$sd)-Q#^`0C3#pU5k>7ux4XC-pDq_;|v(;_g}DjLI*de2T) z<95&zWyL{;dWyPIcJf8rv4oHyA$};@mlwbwOGAa71$fyz3eeq|1!(lFa4(vWhUtwv z3rZsprUol&^QObyn>BqSo7RHz3=}ZrDFN-Hf61DB#*f*~& zz?V|M>&+&a1HR$xHs^0NZwl-O38&x7mR#MTWw-n&Ukx^VBSwPvKP)Pzte!_|? zmhBx?!0tM=$z}KRbIyu#ON{4aeSSxmt+X;3kbp|!r$4~PKM+Adi2_*w^F1L9=)0W4 zi5ZKf6~%-%5>K9$94{d+3I#4TWYcLqDA~x7q)f3dBF(bmvPv?xeoI8;B9uWYGMPQ+ zD7jz4S532g)pVXaqsxruGS9@zIiDNJMUL`?Bp*$2P*ErPIAgLf|J4$OU?_;qp18ER z9G$b$RqS!Lv5no1G3V7hy9R%rJyx>fRA@~|?-uYjB_m}~{3TtT2L#$V$x9_;aj{EM_wBj|i z;&pI@uSb6KMn>#SiPlVuS~D$b%`_`n$XFRo*qT)lK-UBSHI@M=NMj)o-2VPOfbd>G zcsNmQV^nQpRBdBQwX0EKxxu@fbA~cUrd4~=6dvO@hcs^ZTyB-YSdopuicDfSCs`O7 z)jTq&IXP%+*}%I&dxX+tfUq(^P8sQDkhX0i`H7XbP2<7|+ZJaVvly)5tc$qqUQ?&L zp`Lm4`0u~Um<(_`SoMbsUHc{aY zSv8>0c4Y+lN(9StyUOw9Ms`_3bHXtMkS7HWf;g_2%28s1zu7`m>mJUO4<{Q(JEcpL26iBqa+~17y3Gl za3eLLu|~OjM&4^iG}bUw?DYpW))2~fRM3#qiH2A!J#P>rJJ^i(hG1+^Z{~SJ%_gq_ zXM^F$(MQ+@Z3UR|P_K2+s~V_dv$YQO5sh4In*TM@G*_?}Tk~(79%6$i0yShI6 zyFdRZpPXYZ)fW3a9nRNbk#B>><-sH_FVMz(nGP4~u$)N7(i)$aGb?por7u?NYK?E! z`sSj(Zlmvc+ZTVC8!>r9!XL@8MrWsz4K}j9uwhZl(b6V1i|G7I^eG{44x^Sm)Y^q> zPwLLSmM!EZ?T7Yi-&AQI2LmUyZKb_y4$aSjRix6ktRY*Ah|4M3G$a%~Nr)oeD%a5! z0^}dEkoB^G^KOjVme@(qKLxi(4NFUGQHt5RXg^)Fa~T+Qb)ZhfrMiGwH6bV} z7E)rg7ziojvaSHAD{Wbh8>xXMQ(58$UD(!SsZu)%bYq!Xk>X6i;HgBnnjc7%mWfKs zu<%G#DP^VNQK^iW4JCu3;}hdz4yH5^goe3rAGgsw0Wf*y$4&M=^8S3>RI_Z-UsYnJ zZ_|O0{nCCsutFHAguEk zp1Cm_8Wdg&e#nzdy*w`hI|~2WW2D}eC?jp8#QVF>PAsWb=UYGEB%TJRUGwCaGC|2=ChBSu zIajn$PS9aeo}M5X0pTKaHN!W}^5)yOj}#qrl$L;{9eB+m-3SQ7A7V+2Acy2)Nf9Dz^{1N;@-7=b~a+b z{@JK0oX*az>$k6gXj%(h=t5TA$&}Xif!^f_>MC}tjx5*7r^u6wK(OQt=0``umh#CW zrs)N&gdqv5gI+4qw(_(L3z%_5>vn~1g+6NcQNU{gx|>?+a+aS(e7(Y!>f|tmsMG?a zQjtx?=&Sq;>#YkvBcSI~x_+zG)_N3zA4kvxvRl(I>9?QSmuvyDQy9rA<^WtqZ-{{B zRe)MvQ(D5hL}O8&0*wACu&BtSHaZG&Dqy;T9-OJ|)Zjt*#LfIrV0ohlgC8_Q!v~zP z#L4Y+41&OQ@~Mpgx0wnr<$gPB+z!^woe2PDM*T9=E*)Ahw9IErQ!#aZXyT{-W*U1t z{mG!HGB%4kA6$9x@V@Iy=re>EzCwp_z8RmVx4Eg(P1AEkew!;(COe@WXdwX><^Nwy zga_|E)^V_nFwJCw2oy}ApS#_FtYaV4ZG(Ymg~_(H%knpf3{mm|I~QBn`p#<)A3YQm zS43|ICwe%bxW361*uoC(l?cXY(|5`W9jXGI^iN0X0)^!o8gsj%KW<{k=E|{UB0U#C zBto)N!|anYsY+4SDa~&{4$4|j9U?ovB|8BfiwhIQSz!xv)W(kr^OOSCa>fuTV9z_pRh znI(oQ%Q0nG0mfbBfRI0W*iCFxgKlzr6wwP8-??HDJ9;TX3}eQODJD5P-}A)hpJ7eW zpCtBuAUW#^Cs9IiW-EZvH0AxBuEPu+$hKE&X8NW@glL)$+_0KQ%wR8kO2idFLaG1@ z&ZbwYldv%E(q{+T5d`!Sb%%PkCC&Ny?m1ymQ^W4XOof}l>dXHlBvNsK+;)O}Wp6B3 za`2VEDLJr6ef#iv@(X%6MMpNb52ci1MiCVr6pvv*gl)b;4xd$72BeZcj zy}cPTyO87>CYXU_ibWLl$Od#H8xS$Xrqn(J>QT?tu7J^LaI7Nsvw`6;S6N4n#1gvT zaLWRwaWUj{30%{K{DtJH0m?X>JHy!}_fs_r)2?dT0xFJ@4d&6t0<2KaN*Wh)j;y_NY zlQovW_sD8PT^0ojxQq&jFFk#%7idwv`!3gcF| z;0Uf2@yF7`_WU?l&A=0y#4d zZAdNH)TEmUzC;GqW}FV(OhVng&t((siz(T&kr>Q6o5kb*2ubddDWxw$@S#wvk>H>pcap%l9dVcn&7i(=JK};PbMeQwpd5R z23QKLVqG>Y6+6IIATHI>4^@yLV$~vI!H!lihg_;)4T+fBzN-MyT@{cZV%3(21!OQT zVO^rNG97g^TtOw(TCtd-u_`M`!~!}L7qih86Vf5AFB%MqM-gfklakD+`oU{qEcGX? z-&v57t`b@@*UB7qmc9vZ(;gOW=d9rV&NPXwTj=nT8&j|;2*8HXwHU2N(=?<}* z(*yxPtb5iXNBM<52V%!z#Z;s#;KHoj(bAxnv%$CmVjI#Qm5rgELbt5VVkoWbI}wxR z+X3VSN9A%m`HIRbQy}K;E3NLk|6rf}Jz;LDETt`_wQ0M55em2aU&0!{G(mG}B2rkB zLSa*P|8Zd#LI#&7=&Hm9qCDF3iZ?p}F;rm*$Q<%r z&q^jpOhvY)D$H?P&zVecr7bk%wj{?pTbbb6L>tp(f?}9P6f;bN&u!S;!L-!he5&ki z`3gtQ`ofoROl-7pS=QETw62({Xok@TSS>(W1dHc{XF7Xf+aFXvn-VbKteKUp6pZi% zm6z!vwQ5Nuf`-HtbwlMgO?I!k_EJ*1ZPs}dv49WGx0?#L&8iDzQ`%e&rdVw}Xnas;spc`Q z)FptmfUlR@Qr*0_qBiPHZr-$^%h{Dt*#sTXGOW;AS!=a@CqucHKz2OKg?zF+0dA-d z(Cl|oe2L^Wa~q3i?uZ|~>Ck^c2ldy?3%$);>7h#|>^a)qOv_1xUTtRRrWu8}Bqd1C zt964YJ!fXYZ}!y=@m*tJ(IxCz z(baW$Ux$L@M+So0QT3ueh~5oM5{g)YLeSFzE5HWd)69TBlxzdmtg>TK@HJxkidb9( zf(phAaYDr}H2URiQZ2!eI7b$Fu{b9Ky>L=&CkS!E3JIgj3wmVZ=P1zm%$sv5ZIKmr zgn}L?0alNMNzUmMD1=I_An1vUT?z?0m(MS-#X1r+zzTCH0qWso)4Eax67-BiMC>Xk zBj{1#PSCU578nY{4- zk@qI>RTXFB|I9h}=HA@gz~z##1_(hwlCTJf$|eBb{}URQL3MIdoj+s+GP+k|*?UHYxsXyvu=Yv4 zQ%5)!YA_9I(Dl+oEVp{8j&K6gb-F3c&j0_~(qpD6G&TQ^Wa%*{(8pdcJzn0kW=byf zSFWD7eHK?+jmatw2WsfR$Kcs-h?*M_>j_8A&4%pEm!Mn%&XgT2XUYy%C&{miBv>3# zC(FG;f+Z0-R<@6-l*BTjSr~BiQOk4aQ=D9Er~x97 z>}QR#jb;r^tlP|d3~#M%+01WFEBc)xq;`g1T4Bvj!z~TC7JzkYX>M*4DIkQiC$>PcQCxJ}_STK|l`%c2S(rDB+AFfi zQQcEFuk^^a=54lc+!!`&w$bb+sxE736f1k$4}AO7ZE2`&kzcDgb%fUE5;g_WWN2*Q3NI>p}F6j6u8m1Z0_Rg}M8O_H-@u;$n(Nqml(b98!?TxWE!Q&Wx3?549lCu(J) zuqGPL>8ASjIUzweQGh=5$4>LRAW%oP*e@)~nTh6TF?RR_y|_^=T5}O}tt-JGCM~fl zJV?|cK&M$bB+KwzC?a)mUsSRMu^1Q2J;^BvqVOq9$1v|M44I@EJ9C#!c;N``(TA2r zsq+||(P9;XTQ3LmHshtuj~X}XS>n1aVgU#%1YQpNFP9p2OkNhpMN;r!Sg{a-WNu-((YTH+ zv^pLYeC(D$TbCk0u4GlaEKtEXInSTs~|2F;Gik?lJbsSPd9Q!pbTRaMT4YY zle{vP0a96j%TXU83@+lU#M^zAoL!NXhM;BMPlN3}owltuWm@Jv&u>>AUn#M46+v05 zg=@V5n_vqShx+29KXNbiS#adOBo-8X

    )CCDMUD*m`SO%B++57U;_azuu{SZQ{^R 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 literal 0 HcmV?d00001 diff --git a/java/lib/jdmktk.jar b/java/lib/jdmktk.jar new file mode 100644 index 0000000000000000000000000000000000000000..67df5da1a333fd446bb3c50ca234f6dccdf9a77d GIT binary patch literal 679104 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 literal 0 HcmV?d00001 diff --git a/java/lib/protobuf-java-2.5.0.jar b/java/lib/protobuf-java-2.5.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..1e78f17baffa4b07ae6e9c4d30725abf5c9300bd GIT binary patch literal 532453 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ȾQVrR#qdjJa3g# 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 literal 0 HcmV?d00001 diff --git a/java/lib/test/commons-httpclient-3.0.1-contrib.jar b/java/lib/test/commons-httpclient-3.0.1-contrib.jar new file mode 100644 index 0000000000000000000000000000000000000000..4fa5f5d2bfe8cef1e6d75347ae58e0de1d7fd8ab GIT binary patch literal 23437 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 AqyPW_ literal 0 HcmV?d00001 diff --git a/java/lib/test/commons-httpclient-3.0.1.jar b/java/lib/test/commons-httpclient-3.0.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..cfc777c71d600a90001b7b2dcd68993d0977b0cb GIT binary patch literal 279781 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 z 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 V2|F!^stWvxw}M?7A`sFs{|9fY&<_9r literal 0 HcmV?d00001 diff --git a/java/lib/test/commons-logging-1.1.jar b/java/lib/test/commons-logging-1.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..2ff9bbd90d63f92cdffea944869ed9bea7ead49c GIT binary patch literal 52915 zcmb5U1CS`emMz-0ZQHhO+qP}nwr!ubZS!>ZY1?-9Klja@8*}GJ%$rvgRh1F7vyf|L z=H6?kf;2D)6u>_=$c{>u|5Nzq3G(k%R#ZihR#HxkUg4i+5C9N=%{G|lA!h&HZU6)T zK>4p`vVwAwVxr0_bh2Wx@r`mr0tg}>$=CR;Fro6pprV}!frkzc<*MnYj<=l~#@9DZ%$pX|{Voi?sKvAbOJ?^t=RG48IlA;Z=^V^uc@yAmZ!3_0 z&|2_ewSC4)AhMxh>G_wu_r(@}+0fSd84!7-5wn{gt}^QDj1-nj)ckmV!}j^mSDEqM zqMzTyv8P#2l(Me+0RHFy0|0>iw`KzQ`~UV%=KpG;|Gx$FKP?O$42>;J{|7_le>XI? zx3#smbN(+C{?Yb-ZT_`k|1JIF-T!>@e^#)uH#fJm`>&t$-zyUQ&lN3g9c=#f+W&yO zrDZ?N79IdVkLJHYE+Z){DyJ+;=i=eAt)=a}Ig0A{Qort0rfdmTmdj#^eG=Jt7*;E6 zDbis_mK;vnK+p!(FiuAh_4UM?-V<12;{L8CTgEDRxzT)bpL>%t0)5xfCrUq+i*(~! z$yKh$^Ki(Y;`-ZV|KjaJ=u_6MxCQ*~>0)h%r^A9B<||vh{`uoeXOYd>xUC-R&t#8R zAoNZBjh|NZ$hlN^kESl|O*(t^FAsNTa=w~+Xh(NnZ+GXXJz78Ad1dvfr?2h%aQIhP z$X6@6I+a>(-T)`N??G$k2l6b)wq#jiEmCgAeo1gsZE_R!$VC^_dZb^CMlMwdYEP>w z#*zBydMJF_mh2imn0MZUxfKr5s*y8-HL4Rry+CiPF`K!sav4~B79O)H#?_sB8uZ5U zDAcn44PIT?AsgG1Z#2ZVZm@~ETIT%q42SkI{TM)+lx|3f3K^Nb|ICxYcVa1~p?dmw0G=bZtiYiH_Gn+>fbxuBk^^=eku0w^ zXhTv$oUP!AYuT&T)`T8CTFavSglM;vEjqABYNF!QbTwg4pd^G8F$Y_?R6Dxg7BfFJ zjNLl55OS0PU4(BD3+ln}D};R3Ke@F$a<`W%V)|^^e1jG`RCQj$ed4wo+feXZS!=yE zZcV_oz(E2jE^zuNg#{GZWBoLuDK&UX=rHmYq&vFENM!373t=kF;yXhp0+B47HJp7mYH0!{@JMWr z%Oc<1%RAh2`C0c;&~!+xIikhBUa_z>fA)fcPO zIKapFMc|E6ZAEQ`b~NmqIi&{za##mo0c2XP1e2*7p#)p{waR$>ba5VuE$dQr8M@b($j)M zX@SlqR$XHSmjJ#^&a?$q1bR@CT-ymFw+0~6nnsEmNmQM@`2^Q zdN9U`pv<;Ok2O!OQ&Fl2kHU5bIpT1XDUo2Z&ej6u=P&g}Bpn5)xYNHX8(_Hc3$a_~=z7B{5gAp)^f%stZ*hMHYsS9i{k`dm-t>N^nI78O z2gFo^1ZzUTDgXxhX=tnsMcgymnyU!k=&ZKB0otLM`hJb7QtGkMZkW^LTH>4ZC8lM?;qVkPI-c~?F{MAC45%{DH$}qBmn5YDt z)X7H)iOYE#;(qyntu*lSu~TdayEH#oQT@q&y+pOcX4~Cspl0OL_{hrG`Gy&pbTdvW zs)}SHrUXGq!0hmT1Udj`h%(U7#R@RKz^slH zuJ1vl=%2PD7Jehf#G_=~xfJI?G`D$tX7Ft(knJDf8=Zcp75EH;c_)}aqQIay>>}xf z2TkT1KwWS{?ze)7Bhb)_csAEq9{8vLD*(SYe?Y|;+;v7oa300yngj!~92nVtKB%tA zUi*e^7F>?pnwa$?Rch?Yfj^%%ZX69nkQ24oj?KZBu5wzk8=Bez`SS}DxK{dkujtoE zzYUfs^$`KT0}@5lmYvF(WSAz^FIs0B|sT-ahc9* zs|nhXe#;P?V82AGG!V75j&`J*Fz|?3iXF;-V)D?762I6j1LOTt)TRS6Xe{vA2NAD$ z#pzd+H5kdY|COA>#Cd`chx)mIqzuX^Gg6j_L7{9R=35pbMtqb(?-{7-=-Q7WdK0RV zNQcl0)eAF#UJJe0AYX$4)ted3ohl!8+~P_N54jPi2;rarZpS=OY_5UV0b)sP!v-|2 zh(lN$_`}{vB)@4!wVFnj6@Q~8>nfn98#AULTS20^QW$wQWv%sdNM>2N10C;hZ+ zu|gW8_Sk3tIlt1pGV^tR^#qf2<4E9b{QHeJ!O8sNa3fW)KU0RYk>-sW8C6Rjk}n1I zDTDHKS+kjlLNe#U%!sD~k?B_O6k;TOofX;n&!G90)BqS07AbD4@>|LuddUr_VF)%~ zF_R0ELP?blbJtfs@CV6+BTrsj0Z3i)oPnecS=3vV-o}y2RMTCrjg+YuF!LG} zd{Zbyh*N+KO@etf`n!bi(`>jC=XnO=Mg^p-`43!o!wCIyv)NDC!$9pbj>BL)BG&qG zg|hS4EuvvA8MB8*oAIhaf9*^6`-tfhkd>a$UJ_)e)?Q%oL-Qg(s4;BS(oQQIVB1^~ z8345FpCImd##k7fFbspR<_VD{s?*F2@bx>6?{xtK1GIBgPHg#L77f<&u`lN=+V~g{Z@&jtnUh__oRMxEgHp36WC9I5OkR^-3I9Amnf#>6y4b$Xz|wMgewoe6EV3xSTRP!(t`l4{4-k z=p>FE4xHw3n~c=h#ylKd(z1ANJb0&!bKCo~2mhrk&n!_ZGr%FDj83(^=ft)8>450{ zE7+Cv*u65CB{%6S+%!a`nOFt5oGKK35JM~zx;t#fu3bP%4aQax?b9=gTX;U<3S#B> zs%e6}0Cue5s@fKxdY3Kl*RBA5Kol^beFQXSJY7to*+5EnH{y`67j!Eb{Xy0+8%H}d zOjx;|6yN^L-X93AH;m(O;d!uF;gS-zm8u=FEBp9{0`6PLG#4jI6u+hYCl)JUHLyR5 zgMdBMMoWRozmwl=#>;lu^0+6`CfFDo`76O3I`mcv-o2VrXro`9qT|7__b?BoOqG>X;!CP8Lr2U zzT(;OuSdp4wzrL3`?~d_v%5aEzK?S?YW&dr_3P>at}S{2{f5sfq{$aTs8!j>WHCjY zl`tL70c7biqp*m)p&AXQKaRdWE`Vx!y*hMyy0q)Qy}p*7&U+E~b$5Ec5Lzmx9|O2dydz@(ey^I_Tg}z_rCV!w*1<=dNlQ&e;sWOg4v@9{NS;zxLgRZGjE~F z4T18Q%i6OpI&(R|E`-J_e3A~&9GCLgy1;QD;<5MtatpbfP2p;tfI0upOD$`B6TPrx zo@#ta=k$Ri8xg(vwRIXsHS zK)P)K~z))5c!hITLwxHoY3)a}#9kHJfB5**Gn zXbMXf`y&#dL#@?`J9qEk{8mc9i?ja;>Snch(_Dgrpw%Ze03^)3(}VCN6f9&k6ZQj2N_;#uMv9)u#2_q_XSx#u3u1* z&AZ-y3IgXqMAVuRd-0JKNw(J|Qb!??$FVFzH)#Lv%+&xkHF#jKV+6>T2f~TzuwiEn z9*b_$>h}}uIDmb~ty3`i9Omt|4vka|q(x{zcl!eo>NyQ1-*rN#{L<5F)9uDZYroJ` zE+Y?UspQFFQ?6NE|E86w2atj|)?}TEPek5W0p1rJihI@7?Mf00f^jpOpt~VkY`zep zy=Q1c@N{~;)-F#5eQ)0)prCQ^UGau7`EacX3&sXBa?Y%{eT$2%8#WSWTOV2>Vcic_ zAj<&7nY0Y~b`gn)d~y*D%%=>7H<>OopYfn`Z?f&VMYhz+eBCXS!RSinLPrZNp(4TB zLKJ1Lxb>24WCa$^is#&@$Q5e*E}F?f(_QhCtvhv44arPM?k&0x`z5( z514o#y`BAD;t~H&0kowSK!n$AJ^f+*^`3pnB;Oy>ft@dOI*LzglqE}{f)%i)Q6X%; zkV>&ct~agfGAAG?5EAa-Z!mjGRFUJ$bbWKgR|}@S>TN<0CYZ;IAL5pF&>2dE#v~eTxTt5>++kSz+>teF#)^ zw}G#-M@KIdM32M}AUeIDuRQY}+iz?s1&m@UB^*SqUuMEfOq`e-p#o{b5HE8*PVac_ zA6C9!NGfHd`h)ZN`*`2E%qYpR%W^vogVMpDf#n#lKN5YwcVx}AsaX{WK{*z%!!S6t zn{fyZ0+0nXE@Sr3Z26bac=P$q)&d03`pj&LCrNPG@Xm=zBX$9yb;yPFF@Q@5W=fL z<@Pzru1!0s#zyI5hvyaeQ*nRumO?Pvdz_(}`QeXHZ!bSzArx_Y&5$Q99f%6}kUHSD zV8fvMqp?it4@#X$$_|`4P@VfJscC16S+F4ubhEqpv62Aue5H>Ld0~sPJ9)uFTZq{8 zrK1_LA&+o%Za?ftpd$M${Vo-Q+S_Z`g3^1UBvP`OpH0f5iU?a3hX`3NWa_IWvNZ5SUF4r)`pmA@NW7u-p{%N{i<X*Xu!)hcT?8aiP@e&bnae@7nI zFp+V^=57sRDg6lqqnQm}ikHJp`J#FXCKvr;iZMFNKF*NqLkWWn>B}rZ`{yi!tuXfI zETjydB?nFw$72jtBHWDmu*;QZJ{SW)faI`$Zu}H~OF^AZVNf_+fR%f^}nzGMn_5}X# zcny^bwoL!UOC0$B1uv$5;`Pq~2RobtlFm-JP)EA3GAkqq5xyHFL7`Mi;+UxP{KKr7 zLz`2t<&VguexL~GejxlVH3EK6hAWL0Me6y=Y)t%IPG-;RM}7Uy?jB&P&(?F}^+8;G zEExut>|i#misM2iK|d57XnW`pKz2J)L2NZlb*`PyxH*rMXPSt8Sh&(UU+~%)9>b-J zoX@7LXWm#=e92jU0QhPJ%^CN5^Q`43OyCb%Ew5^3(;Q}1mlp|UP`W0WY$BO+7=v1- z4{t6^>Bh-W3WT+J1#^p>`@R6JhgW~B(^;t)#)U~dboI<<;gsR&=x-84|G5zjF(G*} zuBl=ba>z=NvCC)UBpbNLWr&XQ92H}Rxl0W#QjD~a#I4DssfN!RFU(bFigY8Zlw5K9 z*sMeuB60cUHtxks94ky&}ep1J>z}WKVqPJKE!Xmxy38|X(FmktWzLvz*i~$XecRq{7b&F~v`3RR)%7C_;S!(v3gwplfc}E_uUzZN5A|x;O+825qPS$$A-nlb zIyYkM`!7DqKe8sDNsm)+e`yi&|3nMs|D=Vi{oi@W_hQ)5NJe)tMFFZ*Kq^^*0cnh& zq)Mq&YEQW2-1nd+r`E>a)Sl=_A2kwazdsR}AByoJL}`I&WpQ@8_sxU(_uZWSPH%CD z`6-vj>26~17@QVdtBywdUeEyZz8NfATFfmki^J3qaE-@0OHnL09+!r(MGN4)z6R|%6I=vx7ErdThs?xkL!d|@R}@UsaKWGW9K zkW_W1)OS{4Px)AoUp@(CMARH2v%4>*RDa}>3diBz7|H^U{k04$^vzfcpgetsnJpL5 zSwDNDo;@p6*}UzXDvo+5ivsd*9cY3SNF${l2-FlsRD=2!YSUE~aVsRzqI@l-R=}E7 z;zQF2hondz!4uK{Z2RyL4Pg}qYu1T6ZM1nE(ZEdo@PQ7A0Ui0GuY@mD|vm|2)Ryq(VUTPQO0ZE74=nhl<**W2zr|?q@_x%&QK-x06whD zxaIE9aKR4J)FeHHxkR??d<99poMBpR=Q6kBNB5IWK#>l%I;LOFcv7@F)>9nOLt#%L zXhB1Tk!z5>h4+ipxbqi22YW~?IPwp1vc6MSm7kbMizu|>zPh2xZqiEhc)kZM4}J;N z9k5wGsBb)A`u{h_29R1=5c@BG68}0j|NE(cN^cSLt81`93O zFPP>VNgpDzK%gBqxM)99lG(zVS#}(lo!|5WRE?rpdtZ$IshHMgzHiK`mbtvO>3iLC z@`sQ4>v?->4P%&x&8gy$!G6Cp5}Qm-W{aiK%4kMpMr3=K7J4Y7!C=1y6q^5hMIOy5 zqlF=a(suT=UlaHB4I{3&Vull2HKm1e^Hn*!kHOd&6WvB_tyx~Q6E5SuX!uV1s3hx?yHdfPg%&_`#fzdULFf~9-LLRCm*Ps!po)RJ|leWD!i5XD@^Z2Hw&LjC)wj2yaPq@sPjS zRPxnE8-U83r65Xh+&0Oa)-h~ooo9C1*_k9?!ATGT<*rGZuI9^VNSxKc|$Ml zn`m*>T)3zrarHd$8aeVCrKCkISyYg^is@PB8qL_lwusW{gk!quB8rxQEc@QxL>7q# zDaM{ee+mFzER2_qdn1&fxI6+|XY5d-XU%sjVpd6BfKUCZjw?AkGV_By^+Xb6-h2-0pJrKz|T53Zi*nyu>jC1b5`L zegMCyPoX~?*#+cL`x5etSHRu`@82e&*Hh1(V^ojxj6W^2P7_vA7-sj>wa}YYY7W{` zsCI}~ska>p)`IrfW|LQ7zl*W9oqFzJjO{DnIlV^V9nS?mh*99M#4+B`m+B4pXkfbg z;Wc^m4NR)SIV7(Uip4nw;P4uPQ|ywygDdNYPGdVEvc-A=2#Z6y8Dk-h!IH%=mBm0$ zVmWEB9yA!MG?;OgV?no=(iV+l&4HieSVN)clCxswca$;H91^=l$M0n3UjBUoe_)6G zSpVy6ef>>t|L=Pl>py#$inj8S0LnKS1SKIdC8f?HM&r13hvyB+G zUOC3N9n{#~I8?ifB(u<}P0-Gjst0`q9@e^?n!-eo+&S%;XnO0XGY7u$x8mlnV8*a4$;JuH$D9i%`$b0I{0|sd&&?y~(rwu59%gnNsED8P+idg> zOsz=)$_8BH31rc0P_~x|#2M%*msOd$v>4RiVciraveXEFz5{s15@w<64KhTRejkUC zy19p5V8>CQRNx%YaB<3{{EnjVM4S7aRApzn1Ka9ppbaxqU3VxCLL|t=j!Z&3fWSx_ z{o&`7aLyhrdTqxi^xk=MLNDk!B#Upop+^0$}=ilPN*bwTC$9n-Pe9$*k zWTwMQbN=#H$LJDP&(|iEhkL2KbIDs(+0Q;!>omHqDqDKSIY^R6L=JC&t;mhtO!eWdhE`-g&C8s>mGR zrNkVJMH(K#1g)DXEHhE8n<*aN6hLPR33){8m0}u0WnFkKqA4lr3R3GKoX?C!<|sP^ z(GfoAghuv(0Du%F008R$ZA|hX9psk}xDU$O-R*SOcF&PZ zOL3H!K|@HDEF%Go7%YO7#tINJN3Psr=2EVYXaINnNY4n{uAbu-&^lsMW2`oToul+t zQhVuoWA1Qc?mDIaN495|dmDK!z{v;b*Yg$i!|}{?HaoLD+S!{uzAunX0=-|QaZem9 z7u)%IiE(or`Pq8WfferBsYg?swd-eK+=YuyeX;nM8g36)>)Gj2qwW|SF1IU>=ol;) zn9JoNV}-HAm>sVC3S*72$XG>Om+MyXfiM?e&4Ik@<%(l{oG;h)(j6mi{=%I(7vB6` zK^*@1Yhs-L;vF(B|H|DQ*SF|c-}!4toc`IXJMK^6!5Wue@d3ZK#AVcYfT? zIgl%%i{Vme5wt3L7Tsm%yep#!I-IV_>0o7aVJAje^j;@MVRT}r!7u9tI-%}XVRUY1 zyEr=k>PSy#yF9vYCr3f_iOXG;uFK{~r5j>vbcC+R6_FV_uUq2+9oxo;Sr^9)om^Wq z^X0xw7snLcY-_ahrBSr5&97+Zt9_m>jvYF>hG^)k{ctzOL|q*l^z`+SQa8s;T^&1g z_4ScdH^)9*9s_jv-y`yuM(Mhjtk+2`*a{rG zVsv)<`#3F}yFzqy2S(UbaO)vdYb@YfF>ZMC9TKrX~1>EIAK#qM00@J4Ef+tI4xp@z;!1^+;~GHjXYeN zfa-fWFzsk3OyfLw9C6WaaP3&=3~8ZTG)B9kI^22DBRVvD`ygPNlMqpvp-9)%rg4)v z4s>bE;#2J!v(fbiaa0;~)R=Wi*{V9##~rNGrnJzlX-7>_(a4&^u5w$U=8led=qJvO zfavH>j;QEuj*ZFD-tF!2(cn2m&}|NlsnO0I?QzlCIYwxCS127GzmyO6V&xL!`y8Tx z=#CeKjPTH*?_kO)2500Pd3vu|CQ(+9xPicYEX5Fxs^EFrsk^9~qLL@9{eF5H^=Hw3@?f{73uS`u4S zg?9VNFRvZ{IgNK)Z0FyvgL0*L@F*_4Jq7|<$<6NzL7PdqdB0!mya&71?Ox9fWr$;F zC*J0(@7tE=&|>e}`~t*}=h&*{bN8k|vmquCu8mgOJhFp+BeE-+z1l<}rSlkFHYx9` z=H9)y2Q98_k&zM#@$%Vg=$kRG5uY|=Tzz(^pbq5^xhG+wHosogSnf%TNDoMIlAphV z_Y&6K&a3ES-MtWR+9#VJFc~E;(X?_2s)|UhalEz|-#&u$;_~?-i*b2*<^6gm)2zhe z;MrO)zi!}1c@}3^j?Zv}0b1m`rg4YjccNF$%*bOk=p)J|R@6r)gmL{CMA{3XQFitK z?8-5p*X^5!}9@T4G&gA`S$!4!4AMRB9KO78B_0}43L zK-`eBSVttAt)WedPQI&8LKZb@wW;N3l(%}XM*MtZF1 zTfoqhVf6^wTZ3v<)5#{3d=Zn?e5NQ-p}ly1>FUny9ZHh2OCl~bP(d7gK`}$cIOvz@ zoK@11RS4ro^J)pPw~^bKfSZ)j)s+$ma`O}%rNNeM7tOURKOe9lTrZ+1wZi$Gh)XX4FK zh@c`1E|5P~WLYYY(8P;aqL^*;4>w6Q4D`XvUF7r!9!D13ufs&iG{>06eTKQW8mN%s zrKfUc$Z%kpoYrn)AQ_y(mXJg~T8Sn9kPX4e_SSy@8zUT{+g&9iq}UD85@{u4vc zOizsQc1^x_28T1!d@zQdLvT70u0)){ z@z;2q&!6lT7pzn<$&bzVzy!(gsea=nfOMC8u#qQM%d9tRuzpSRFyAY{{lbRd z=vOemG`CE#nhvD!9z~(CFRH-Wa*02H*+^MA@%$HH{NY0jaC=*gFhfe$IKDjW`|%&e z(+MobvQc%S7`ix4%Ou!P+`_v<7^c^P<>D+j`J#7-f6qv0f!T?o5T-A$F0S+s)K~r9 zZ@TAl+TN;Pl3WSmYM^D-|QD`qQ8LcKr#MfL?nkj3`PJEU{~qRAeQu?m zy2jdqaC4O1-D`*WxcF!~QVRRal@_F>roAyr43T3dK<8B4IkE~Rfm|uBVM$~1;1&lUP3s?N1D_T>=WB3aAq_Y#ZXgpzB|i< zsFw$Bm)I}Onjf!l({6CCf9}0KtqflDdM09LL7HYKI!J_^-Tn(i>7I!>oA;`pR1>^qo3#u6Ow5An7oyWgz|yeaE_LN z9Ib?0X>&(aT~TXYQK6}>Dd$Gnr78-R*y-Ozx82w=%yt+tB6ea*6Jb2nvttc5(ED&@ zxp7_O2n||i5ai5@!ez&ZI8R5evZ$pd>=Q25Pq2rn=P^>Y#F~d4j;4o|wco7~T{Gfk zWzjx`mNC|MoX8^cl8cxT8OR}TQwuDUT1Fb@{NDYO>UkT6AmF~;oMuzqAGw_26 z?=ym0e*=spc{>W)TBhOF-av?3m*$bwdqQTLnLiT2S+mb&QY*4zyl582Z3xj0i{xmo z9=lSL?*T1WApsl=89tOldDPf5ZO6dS>iRVtQe75Zu`PqAoXJeCe4Yni5s}} z@ycAfjRMQ^(%P1HSZH~{!2|csh?qbut17F@Y-0+D zD7WuWO1tBBB^C-o#TpuKk{oz)u>p%Djd4wb-k!el3~;jIJiE!BbC$7!_f;l|6`6lb zh^HF{Va!g(jo8xB)$63epi5Opo}O4oR*q0Q=VP7Lvy%3i+$~eP3hTOkXc0NgWG#(- zg>8RzRk?L+#t66nbhmt|sT;1mNGuoK-aQ-?6Xs7#WYg)|W%Ku&$2xmS;!31y>BvV# z#CR_zFUYfkk&s|kqLwB~u#C}+nk)FyJE)7)1YAL;CiWQmiRjT93OguWF(;jL-CHM@`J9%(f4a=Mql+5i9eRRkgJ> zJ)q)Kb4GG)>(*j`ysr*6jKr7&I1)RRnWmCEUh{>FJ$DzDu1c}If2U0ltBr-u@rLEh zIaC_>SwND+#A$>W7wgT*P&MrcY<>I9d&mH{*WLt&SkF*FYEfBGc1J4I=_{{ZMI>pS z-9SjGKOw`^{56V7i2!A503~a^hwCwxBl_DVDYST?0{%lTc0us4UY2l(pygx8hK-_= zjYm1_gL-fUZ5fP`DQMrGiRqZ(M&at3fVtzi59WRq%d9%r7A@J#kQm9Dm0viFmF@wCZQAob@NVlpe2v#a7mx2!wrjU^!tIGW4^*b)fAnVKP~V>EZ)XIhUY}j3oe~ z$>Upq$3&tt#D(JRgZLoZlfvhYw+wmNEL3_0WTFA^MgLsr-dHcyHS@>K9oCYma{|(( z`aN38PmITE-tl5=^j@%#qW~^!I+mTt+H!MIBF7#lc)t1nV*{)9|7FSk{=eNIaG< zD@AAdlo_??V_FFa=d~Jfmp$36O>Lvw`QyDD*|ksBp)uIDODxpK4W`dQo}mwU>Fpo} z0d0n%#Q=;lv{{B0!;n|_^sN>phMna~LWQJO8XhsPz#p||%mbzvt=>cz>N~+#BiA0M^^FnpU(7z zq7^i8N^1+L$?Y?KP0V*QJf${KwUCxnJEse-Hh8f1KAyr+792kPb)w_XBy($W8!;%-!`nkO(w*Zu6l2SwRb@R^^E8eTf7+@PVk9I>i|Ki*oI|pQvU9!R>(`7~ zah$wOC1FVv-7dvC0q-IDMe-}*M80w#uB5W(Gm6q6PaZ*JNBR-+FK~hBI zM>U=)H@Udt(hy2tk}fv>LYs(@N-hx{ms!HrCt@5*>LuO8y0L{3Gur;UOmvR!NYFl_ zSZ2zJ7~JQK1=K)tnMj69Wi|bg#da2bz_&f7o>CgPM5gTg;IpJGK-mE{O%@}Y?<<<& zXnsOJq*5*5J)>=jgXZjvC27dS0bCw7d5>Gfhyzr6YdHRD$J9cJs)k3GQr8g_Cw0-( z$Derak#}*zQCBuuhD~08Clv?Xf+*4E5=6VoA>x?~XD#B}@{l95QqqJg;!J7WB%kAv zomC-v=ZJZtM>C~{XZ-*^JSc1mL+Y=nCL4t#fdPR$li|k;DKGLx{V8I$z9~6s0>XO1 zgI(L+LZ^(Li^I^XaTS72|vNTf_`nb`4b^3&heg+0?u2U*+E3F$wkC)$%f@H0nxM%H&k)Lc7I6TT#4Y?LzCabOu(^`zyZD`M~p{b2?c z#3OLHPOza56vK#pN)2ZV3R}OaAIXI6q8o=%s5Zjpb+h=BFw6q6E{gQ%VXJvZuZHP% zeqBwntiz!L_Ct&h$KTls_@rn75iNf&E?yTtFQvI9{Fc}HU9R*&Dcyxkwr8I9+{p4B z@>eN^`-Z<(alid>D|aX3v&MuU0QsC_@<`8>d+#O!GlWd$?z(_}7}!q<-%8+jzasc-gWte2 zy@&I8#2mj2+_VN?b9KUhw`W%lpHxf(f~S@T2PIoP@in7OdNWZ@YnW zobhhCp~tjsQ>0^A6Ci~;9kjRRP>_Wl?gTPW)-k3#BaVQ(sa^#`Yg?qQJrDMLzzUt2 zTSvhhYdCa4ENwc4_`~n743Bb;0CjI0NMJ%iEm2Z6a=ifbCTA}}_tndFHG1~k?zvGU zY>Xc@vP3&ZO zB}OkyaMEF;3)3`b$8N+QKMiI}D291>yWHz6}An@z{TmpmSidB+luefe*JpCI(>y*eglRbHn9E0b(XTZ-k#k`54F zsJjX^9WUq#0egZIm@Bxh0}ee8w4$jie(SaSqpMfm@6uH&b)A`4`}D!1-(#2ea}tPz zjR!oyq>cbpkf7#(2xZF5q0FaLK28IaGa)yn78eRkgpp3tRH!u>pgyfoKNN~;Lim+J zuu(=EWIOR}RnY`+r;OYhmtwe4mo|t~28*YdHt1^t(o><{TAOlqSE~$uNWuCPEDw%N zM&6>A=H&X-u4sR6a?-5FOehF(b_ zuu~E82%nA8PF8vZB8^I?K5zC|k~kS)=m&WPa{vu2b!~<;Hzge;R1?_om>2Kr0K_Ip z$tFzNDgoFLX@NUABIuSdEL7^D);YY8K=`{fAjb&u83PTiJh_P}S+Hgc*jH)hLt_Rw zEbFD?a~-;#c`jc0D45(3x=}}ocBMC@=J(f!CQ6?t6x{}3M^jtMCeJ)i#)}E%x&ajD zkPnA`FZ!UWh&t}q=X}bfRnwk9HuxZ0eqLyTC3O(wW1f+=%p6jN9XDWHkvrV42V3dF zel?h8TT+JjKhULFg)-^-YvaXh;oR_X-2B_SlytkGs zau}m=jp%-IW~Ef_>ijz%bdGL(7Ol|(f;WY&(i7}@hIjhN!#mVV=`k+NKGQz4mCvYj*1GD>C1O#!b-dG)6xpSUb{@LI>%PGdhI zHg~LtQU2NzljzP8q3fk)3mcx%4YIrXL@W|bkVwhNDd*uDyf&n0m7FDPHz<~wzXfrk zyO@57?;?kg?`08rm-WE^p;%;o0=~`f4sKvtl5^9lpLG`X+N&)h98xobBV3ulSp@gj zq~!D#c52Pzm}+6RK3MmQFEvu5zl`(V+RpUC84v{d$)^x;$=fg;FlB6XG;VA+XV}hP$O_g9BLoXjG&V>#c3}y4Xjzs) zY8%FQnb|PQi_N6^M4-15G)}c`kmpH9qaY7ldgY-|qz53a8eQm@7vpkux=@!FX2^;( zfmlQKGPPl}7ivzq9xQt0T7T-ft3!_$?^cOjxb8Wehe{7%p0a(2e&yya?GxH-tQU26 z`5!QRq%Hhq?p@_4x>vOxY*$zEIOUsx;$`kTizgT!vDiJFCvpz;ZBedY*zyYgQAbwv zY8AfgC452r3NJ4DKY*~cEOB)1ugfzku@cVSPgq(33 zK(CS7Ci&hzTFhR#HoKJ-QvR-A|FQMGCBd98!F0H7w}n}^Ek0QATU_r)_%77}PWIwl zFd`4g{@6uNHPH*p{GDVxOgE>h$WwQGoz$aTYR1xx*bo*_hg|ul7+2j4uU9o&S=c|C zdvdCSHnAe*+Ue1a59^MW(X$#~I8&k7(Ber%w6h;XoQ`?cwou~C@Kar}99E@QmFyi_Gvb-0 z*4HY%m-!@j9?04Zbg_@*lH-kZ@x$0_nXH!(aDyJr8^hQ>R9EdeB3>;KGj8;V4B0$y zI~)-CS(O=OAB#k+@urVziD}uDO%&e)#x^6pAGUPjy^QPN@(DeAFJlgjXak3U*FYGd>HQu~<;k~98A5!fVB1^|cUVwPbwNa*h%}|q zmrmW#RJV3f6K+Dpe}Jp+_$`fb+v>Utx42_=BzQ0Jh@h z26bEBftUNB^#kg79|1XLB6uVz zIOfhb$ex~}3o{Vmv}h6(6^^WdD`+RDk?3$aL^%CHJrE-Avp*`GkJLV`1`|Ke=k5DL* zY#9Y|Na4^sRrU$cpgM~}u0&b31bC$@Rtu#>9z8k}iLSb;utj>kTO!pO_1s3X?Um=l z7D?MUS#$Hh4muV{- zd$jVG*;HcKCSc~0l!5#9hBKqkv<*ulei@jd<@DYo$GJ(a?&OPf!q`DtHZ7<=Vi2)y z3<)7F4F+-gn`p(_IpS~a_a_(>=@A;;03d!Ih^6K1@HQ+T_R-=euc!)9Z8X3otYdo+ z3cJOu2CrvmbVE`LyN1sGZhja<(^CR4+} z)el@XfCJf{SLtN!5#-^1ozujq-oIKt&V2bDH^&L!?zp8ZE2tG#E%bX0zhg2oB3?%j zy9aL7LFaq#4*6iVX$xY~RLZ1%l$yTZ+%rx|H*jKd zib41tbXr+AK>I|6LRmKmIeE>1vqw#_OY-8{cWg!G0Xj@(^Y(Oyv-W7b&h9Mx zB=7fp#9hEJ#!A2Y6n&l14bRqcEN^`;u)@bt6!Lr}yHUq>N5-!qGbe~~m??qh%3KD?TTcU(rWk zmzXn=W!!ak+((*#`{z%%}PV%X>FS^unty`U3Uhqh8?)k#c$V z{0VEhLZ7ejg(O?}iuH0=pZl-pa&5lU7Z~@lZ{PamT}0>)v5y`JGL(=~ueTe36j**Dw#ESa;OtD560p&Z-^0xl2uH>$^GQpJw#C+{Fg1!2HcZApp6A3X3ymC zD%${tVHFBX4b1hXqo-;=N)6Ddf=@sz5}IX7y+~Dn;*E&sr9Nm6b&F^DV&=Ya4dSZB zOueoau)&Qnhp-l`nU$46mZ~A6@zxBt2PI3yhT=K3xm2``COq`aCdhXY_o*mLR<03~ z%`o72u_HXs0<>QVRK&TH=gZ(+V#a5KGbxY_Qv(BNsFjjI^=YUCB|Z$)R#xerW#m>OtNb3qPS?vz{xlm)K_v;v=)fe1|$tY$p(Wj4X6 zR?Nc93;R-6Fzc1s;HYM&^9`W1r4K3_YVDdF=&hEgebF1CcHs}g>t(t?@RlfpHdoAN z3tTkd_wcuhgrDNfgx_?HSd>x4oG8lH@Z3o*yHJ)!lu*X_K{UB^VLL%BIJFEf2JMUf zFu@l6PI;=-_UV8;ExxD)XKD?;jVBbHzD&Iz{Km+}2Tqb|q%? zcps!mD2HEZiNtHZ5&rgkqEy1f&f*k5=vM0xjpN^~>EF9s4~95N-O9u@;i=z3`sVXq zIvR87*Zjo!lt<7U4un_V121fSHz2=-Z_s>0oUZ?YvE3@CpL(N|ZuNmY-S&kUY3&zM z(%LsbwS`_k`ihIL$)Va6W>t=PWRat{0dnvHbSXXesFQU8N{JG4nV-N6 z*|SS(qHB9uPI(&=ozK(XJ0hdb=KiV53D8)mukney&`Tpe#fz`Px$Xd_QQ!w0mh>oH z5(%&UP!9;o5n+_aedw}es)rtSM4Qqt$qL)!YH--^>?~Ho!%7kG74-I(VY}p+ZTp;H zaw(j0N*mB}2{)J-X1bmc(1!$b-KV}}fOsj^@G^}#L(wM~(J>^@+B3LcFaHzq8y(JA`Ql7 zsElME=ID6^%rjl@%$?XzoqkCtcMoTaQswo+mIctZ414UEcUjY~Gov5>J%0BeYy0dv zeoG4&0KhXW007nhuNzFs&c)Hlz|#-^Uv7l7n+6p@i1wdN^$)l9XdQK&`XCMi&<_@98^AX7cfpQawW zSGlAU>GBn~AGskf@xf z;3_zZ4t0^;kqW4<743Q>z*Kn34(cPqRCuZng^_8>-8dq&M1spvYe?F7A_!I^&rl8Z zveMi^=EEt5&3xeqwV6{FV1ON((Y1(mF^4S@`?au!h_%R7Yf%@lhRZ5JVB6&d_*x@Z zXs{B)EX4>b@uQ}&Xtpcy1G2Det>)u}YD0)H7VaSIRvc8KaR+d)a{IEdV<5Mb&lc{W z+$`Nxf4yMYEjVIzpz{0I7B`FZ4Wz7|{e9)*NM4+Y7IT)HHe#UAWETH&wr0r6>!`_} z;V@%fFlWa&X8D4?(AET{(5$vdZ}qTRZbXFVE*uSslGv6gs&ZjVXhwk05-Cs6GXTgYJW7*4k#^iI%{y&IMAN<~I@9uc9ogFyeA_z!gknU z4CUDHw%Z=(Aj70AkIA$kPL;Z0zSjBIOVZ$i+K645Jb~I2s-d@ zy=J3C!PEDYan46=HWpJ~uUPN+w~}QJ$l;Zk;XJlAeK4sp45c(JCalg-7hRP{!goiO z!4D9MJdcqh8ykJA_yt90`oP^;IiPc|(Ma(~3Ip!ITgon44MyrhQC|2D{Fx`0Z9B6l zK{TW)r_(Fqzns<-Mr-oAd<6#RD3Gw8`XLrcjO|)iNpIRxSc_pk#PtrI#lX_xICTV=xs4yT!Oldv=z_)+X{T7kTz1x?<1a z@hMjPCs~la9B?v1%koPJlf>F005gX+7+*L_AxfX&aLh3EI>nVQ+mGeq7-7;AM>daj zo5%XKD~3|QPIPv*oCX%>@2v@}5D-pHO#?^C1d z{0pJk4ynIC`hnKP;;U&B4en8mkMR*qn3Tjf=eA?-P1Y_@X6qMcDtJf|VvhAdz|0$ZFkwpjvW z7@c53D~|OB`Y<_V^WHeD1)PdY-cT}zr)f>1@NN0}`HTH-NK|%$HRt_8)qhZWlE2pB zlbB|_{-DULVDJxA5=|wBz@>_OH*Wv2{WFF1&0}0$jkyaAmHv( zQ&auWI7=s(gi~MdClarCjj#3@P7sgZqZ>0{k1!|C9sul2!yd>^w3u>vh&_`LaZjE& zj<_brbNeADmyF%gsyl?>+zurg0gP_xmvIp#6<#@Q@(eE|Iw+77X;bP@Vj%mk*2Or} zSlT>B)!at|S{<~x0;FW68-5C=`TFC*c|US;eX`YVsU}g&<_Bq0{X#|-{yvo(sWpp+ z)cWAu0N<3@V2cC4VX?l2>U`7Q4V~4)>`Ac0-m2**v4bzCuGGL zwRr2fqPgS|YKPP@xJd#;61mkTHpih_;FH_nn{*+)W4OBJIjpiz>G*ATbJ-tTf>uU`0D>`*E^d-E6ry0p>$M7>C{WjhD zB95qb-a(sMzYHmFGzi;JRVjX_YE^>D{L*#B7H7h+c@0T+s6I#L)R{omsdNeFN9)Hd z{R=%kr17oBsE|4j*1DWu?T5Ryn%}mQ4Qjz0my#0)x_CyLJ7=V8soD@cCE^-59edT@ zGvq?!i-IB{&^)5JS{I*aY76?8;ht`%M~wU~X&Zbv8u5it?of;;!Y-}E5LIqLSE5#7 z@t8ES3o=tBv2-*AXa?)@km$~-AJhN6`28=ioS>_L zwVmy6_S?+F@qZV=5>+YZEoFqB$ue2(GTFt`Gl8mm3F|YXeEeTi0x7x9wI zzvB=5g-8i=+;*&i7l_@c{VxdHKlvi@F^f$}3eEe=3eCc%%!?5axd%H<*11McJXs2C zMhc#p$2yTRnKK+&kZeiTrR&BRCm|G@_eA)5hE80eQ5;jIT%pvp84(7EcBA#fW2Ahw z_qHK!YxkBgc1O}MRo7Z3dswq0^|PiyGh|t`Z0r~%{%J-Oj`oPmNMuPBf0n3>lWqRc zMn*fTEyxfjwIwI6GuCip?$DqFr)W5*T0quJEQcD^Nnyy)?Un{d*J6ZBOa5(@zqwG3 zv6^XRDH4$Ii2;Hn+v(Rk(xBHojZIt$LH1_E4Cd3m^NB(Dv~mBQXDdw%E1!VGWv;Bn z%=8f)Ou)2Ta+;WMDk^PH4sO+8CMOw2XBDPVlhiP%aZ-Tn5lpzu`QT!|&J2=KSzt$z z`i0JM`%>JLS{A7^DKo`1B8#LjYg%Z{Eh`oVpJ!?`C^zIg)cnmJSA}v8<4jPa>ZI+u zcT}L9YNa#_(cVR?OkER^U43lSS)Oc^M76Fe+$<$sYEVS$K!nu63)BjW4>8H;K1J19 zsHkq5?V2?LHJC$ViTR0K*E6aiyv0%=`}kuv*zA%tZy4wp zG*q$0Wl09eTyMiOv2$^WUHltTgWmiL2CY`lBC+##GTGQ0ou{S%{A&R6GO~S&f7yaW z&WHsPya8s>@sZFM9Sz8?<3Fq+nP~+Dy6;Ri?+`-{DqY%KygKSdsr&pKEn~DX^FDaI zy1+4935-uD-G_cP-g}XMTFmv)R0)RRGw;Z6x>@Ax5>(u>SIH#1FM7+Y~&mZN^pcURi%6xqO zlZqHAzWgahf>ij3^F5^%G+_#u_X-i<72dMSeBAz%ju=m*jH7=3FIi8WD;cwq|o!|%0(gWU!Zzycxq*hSW1gfU=YF_<|}~9QU0^7;K9u&dLbmtG0&VdA^&*s`)^A3AB3iu zh~}gy1ONcRFZ7iAf1q@d##W5X(k?cJCXSW{Mppk_@^aLy+)>O>ea)ISCS=L9g^<*3 zOVABAwl{$Qm5NI&0;PllNst8pkY!0=G^W*aXMtGKKi`(H*EN@DE=#VcPT2$%gSMjpVDdEwMUS#PK}hOlc@O03c!k} z`05Ja^bpR_N1l>H%O0X5&8Y9QLrLEf)9In(>dfD$dP@(kI1~fUPTm94(MNDlpAsYO zKpteeY3Rp-$J&lxwvfKKnLPhYyN%$WKh{;g=cPwRe2?y|7kVu2B+-9~9bl`E%kY;CPNti4#HqqJ|GwIAWdeoX_S=>p% zw%39(X6$C;*yrF@SUU;?G-?H~#mkVuxn>rbY734>1xqu^>KCOnU&}yQ4yi4w_au>Q zDFVZ=wk=6!>THPgW!$p4TzEDoJ1b`kGYS8Qf<>vgkKd`2~!Y43`*DYm&J zlB_JH7`DrbK#UCjsBg=%kYZElKKT2P&S|JsQG9ILe?12`GcV@$W;^M)kYQiIYR$oyZ1YxJT=PqGB68d{!)aW(#i_ zL{Oo5MfOU#79PnuU#W+o;a)WaSj>=xB~>&O$HE&0#i}y8=@-QkUMoFx#^N7}RsX0s z)5hDKpCfG}w@ZylFqYYCihN+Ep$t8wSayl%*t(tT~F$>thSW7z;b5F(#u7YsaWK|lgDRKGuy=aV;pqiRN)N4hc0B0)*0o>ya(sBJ7#8N z3?wPS37nVSDBkh|Gl`2Go}3eaRe^3t5(Y)bdCGXz4V^_8$B zuSbvpc~0m-Iae@=3F4T(^adA5=w}4ybaE8WALg+nLj0Kkdo4ujnlw({0F!5k_d5TB zdFnu4fiW!?tt=gOt+`k}RP#nrSS%t0x~Wy4;-Q?q(6jA7hv~uuX@c{l>)2ME?j+O{U9rO!(W$e&G+672q`Mq1Oc6Fx^DRNMf%>RMpVQyC`iRih z);-ry6Cm&3)kzqJ%DH{+m9gczGxqb*c9?-4MfQycrMxGir*9X91vL$QX742RheEz; zRrT0j%8CIcdo6h=OtV>>LS40Lft(Z`)Qa_I7e}@6aqQqOS{~>U(yZ@HJy+%3`?es~ zAA~Ai1XZzo1S0haz*aO9bWR>fqtZJ09cM^3nt3R!{gMx7_)Ga3*c}S~5CU(Ik?P)s zNBVj!{2PLPW9)$~*WS_|g6ly}QD_UJ53O$BC^<3CA+`{_XW9+;2ht~-^`3dxVD!Rh zg-ibk`FUc(++f5_*rZu>)th}GcAreu7kI=IhR{2cFNSg8-;KjxcSb$4kk0iibQA7} zl1Y_>B#5=V5la)G1Pcp`+2baX5AB56DyYDU!sdUFr11?r#_WVsk%ZVh1aU}@q~MMr zU2jn0n6M1oe6ccey)Pwic;s(YP4}$4@2hEtUXk%-bs2a2FAuzO_s~uExZQlcX%O$b ztWPKO%RKJO9%kewM-M$woQQl=vxS10>L-%&;*f zi}&b2pDw8^>bVx?G%2Be2#i??LQ8?a7bVDQMI$7y-U;!jQ~~x|FV}Q-Hu#M?-aRB(OBhg*a!m@uI#03*r7g zI1_o@sAYV4fl5tvq8v!(gtb$svqC5~mBB!M$})s7V71n4Wrw-hV_kglG&DU`m!s1gm!xeM-TVZ|a7!vK3Ff{T`4H24L2GD53OUvh2b(YT_Ph z2Fe{A*|S7(f@I_*k14Vvn5)oX<3?Le7Mv3bbMBxz+Q&R?AwU+h&PaUF1v4tYJ&QJx zlo+^?7_})%!-$l6Aig0Oo5_*pk)obLQa!aHFh4kp$@ZW%n$CI39b1s?AvT(u$1`oj zi{>v8#e7qYX})?cpB7c83;^S8HkwnMX>ggcrI=2a&h6;0A5!vS>5+$~4tkRvFV7Y? zWkRz8+S%1*?J}?@s~prA2<}Rf51(DD#H8h!O;^U+b=$h|kqO^)90eQtZ&FBg>{7kAV;#K?p%)MF6BoU4Q$v~liz?!<(glaVV zTo%0g=eC8}J$T4(1z10DnlGE?r&l8(-$oNZ@V2u%GmxL|(7vFpr&nsB-JQn1XN&6o zv1zw_+Gl`R@^bivrFRIK?N*j2mlf%rh#t9;Hvk!mjMC%B)kw;Kqf`s?R;eL)khca= ztXQqmf(<&@K7_|L+Oh)>S=Ie9DvR|2HHZ{O9Rjy1^SFwCHag?nm4tbX!YrBuzHK5f zcHj?Tq=(J8g&RN*Wu!!wVdf12pC%C)4Zltzg6~$5XiZi5C>c;ldgFsC1;L_J)MY~@ z!NQRE8m-!V=G5=j&G#+A`&q2-+=l12mDxQ!p})2Zdh{(H8&KUt%K%6!A3oQeW~F{N z?t>(A8Ks6lK>w$*>ua}BWd6>Vk`e!B%Kj_rERz3S*;CZCc!}dQRu$}h00P6o zU}-w3MPy(yK@8Lsv{B@T)5q#zruLbFnt&rcGKSM%g`e2yjrgi19}6(ls8#kotXc@rP5 zBGN^E=nQ8U>83oSMYM}@7aPVz#E;@2KSV~%i+r1ghlKTgTR0!{WmtPwjh2ZE9xIS=51dJ|HYOo?c9_#o5^4iM{z4Mnh;HB<=q;<48(dna zKft^;a1t17GEck5$vSIL8-zZOzbAr|;F#%Y;-EOtfsu00bMl6i=}+A3{7dK|4M%Q5 zi+IZft0Kh$Sx(SqOEUNvj)Si}D8bv{K(Sp*jua`_faKJZmZmJ4|=7Hk- z;;bjlUi7bg6`vDNO;lQCje=soB+fsLC(Uy;DCng|s}fr%W+l^B zbxDZTVlG*o*|kF`TAcj0R!tipZ?y$wjaD#X=<;5i=~`15bIPf_fJp2H^sVbzfw)#g z#Z+;bwKgLtvSPGib|+_s7Lm$c&WU`bgJJfi5^-MN4WemuwA$fqh2zsQT`wjIf5K=K zD@shJi>Z_Zw0fG!CyXrNLhYX@@-kIu0kZypzx8CZBF=nFI*;`76H=r^3CUI^LUzHk zR$JI#ky>t^&*iqn zd`~u7XmuXU!$(zF&#mTUN~=<;C+Xo@o0Vf{>9%;S6hQ0^IEoBk{!)@jZIDFoR6Pr4 zP3QjNiee|a!}}cJiM49v3Ub=bSiDd5%9`#6V*;$|95;;t zeuSb}%#X8g3xK!dxnGexZcp9v>vLN1>WCc&NEE<|h0TQJ5-VllO<~yl6C=iUDGmOI zn>C;^PhR9NQL(_TOZ9nAU?t0KPv8l1d24BGvQ{{Z%u7)^M z_{AUHNKSEuu=Ap01|L5bffgztO+SvNCI}A@%c!8WdJ+olKjAWOji{6RfX7KONjpLo zt&3x7+dzreCT~Cz;EiJe*JUZ$rH)j_^|>+(F<6h%hxBDZz@gf2V&_lv5?Ppyk2FmU z**x1v#HiKLJxwOkMXM7$#77EhqCt(t6h{j*m>Sa0;!kP>GY+E|kby-&16S%U6<=Vd zuZoQ=YxUQqDrrFf9ys5jXyt;Sxdp@_twQ^VQlig6aD>a6%5sAH8%VVqAXC*Wcqa_L zj`==UKiQqZ^t$S$n7XCz@xZDjafQ=@HYLhEmgLtw@=GCKDnm4F#^wZ0cF!=HkDYkH zubAXk{gA))n(Fy-gIqGmulyii@;ICD<_0>qqgv#{4GZ+qR*yK<(|%nsK*62nv(*=K zFyMVN9i1fucL@J5p@Wt~>x^Kh@_5piEYO&$>v0O@1N`d;U3{dN*Itcd4VB&T4&s!r zwVF_l{%cnk?CCW-lFwg*^C?P=|Al7u$r89{YF~3jUhQzRnYQs#G5t?Qmho)sb8@jf z53XSsl#w6!L6I%o5k6cd7on`_#&GBPWsAq{!I2FLn}_21zW82}EnE^lJe_>_9S3T2 zzaqcMdDYBRVgA2%Ppd^NYM?sf1D%UWFL%K|TQt@5$ND-K6aVCdzKmw8U94Ub{=Y^F zd(y+EOhN#FE^z>W|2%c{e|g>Lf6bD9YutbFJ|%wNEc)Nmq#A8VZ{?L0{C(E10Ta^M8TAz-P+ur*oduvRtDVLFItV25M_O9i zm2FxqUz%=LODy|3m2V8+XFKj@j%AntKYhO*vbwUpZacO*&OYa6VB~&2(BXrC-VeQT z$uH7Nj9O!pT&5Qo)y8;mpMLSI4f114F4=`g%D81096Dpn&OAzEm|U~V4ymz!xMo)! znqmcUx16IdF_s#H$7s21R~)ip&(7U*WA~OE%3}A{9)NJ&uHJxgf279p&fS}0e}Oux zxPGNaxLmsxM}AlCaj~x#?($iH2#o$AFu zJ#?y9g@Wi-&JC)+{G4Eyh1w`59HJ#cS*LIbxP%jg4LHUPLPs2;HNr<6qCG+=oWglR zS+{UXIK~yiQqE!LFpeR@RnB40FpeogHjV;RU3;PQBv;wOY?gt$j)27QjP7(eM)wE} z-P1*U4v&x|wTwGI4v&~5ex@52a%+F~Y-P`+Dm#ZqHu5|BM>_Jmhj>53)Yp!GfN6Zj z5BQt~px@IgaXIyfdlCrE-$qk+vCIpQ_I91c&78QS0u7Ug9_9oi10u@8c0&JO}anQTy?F=l{9 z?Ja21Mi<};(o|!QESfki1|Vrnh<<<5tp^tL(1z%wCJqaSgPr!NkiH=<^j?4XuKU;Q z?(qq!_Vgr8+11W_lkSC(pP&;uZ)CNud)n^p5Id(wIPyEkM?Suj!8r9#^7ZqHl(f!adu!JSL>9Ay17nmL#pnSQI>uBDvivzxQ~e65=|N69#ynLLwEZ~k zLX1572&7FBh1d_B!oVu%4$YCLszDh#g_tKDLrOX~Nd8*q2r_Gz2vf~E^N~Mv4s26f zlS@0J6L6cq?4JxbL*79EJB|E_F5c|}8)k1pJG4O%JEiq-PvL{~wuyUiAH*SS+c?lc zLcMr*!feK zs;|<(HaCJrGY})k{wfD(b_6KQL^FK+PH?l5toQ9SsTW&^&>$LxZ4Jb$M#0RaVp;@P zu)&(}%Vv7c8LHo|?a`a7`+6d!d2J)9ifzFYDyUap%7D@>BWC|XrY144+(uk+YjISj_)pKc zO9Mm>U_uyq!mmAIP|M?MnTfB0)R3i#3oSKNctO25sBMuiE>@jDT^;YzoSBGE^>)MY zyUMsz6t0(TgejCP2{{QXRYx<^u~oQW7aZe>;-2@ZTB9{J3I{2==3 zxj5;*WcM8KHthm%MEagqa0zT# zvs`l#apMOMn%v*a$=w_(YLA&tnmUVL!Cl=ItOK zGA!2%rWn^FS-p%L>Qfqm_`on*FhwVS;wC@<^ZTW7jAT2vkEO*@$>OD;Jj zkCIoWhGxM8e?Qh+3{-g!z*WXk!McHDNh@1yLGp>}>SQe7F@Ev@BF(O6U}gb3Z!U8+ z&>*~owP92{J`}|fD?u`oXi`zdiI_7LLq%^9ZPnz!x(#na2C{*A(-zpXpxq;Lkn$3t z;Oq%=20YsM3LiQsVvB_=GZURYFR0O|?-WFj*Z3sno}OHa^;rXMHC!Ugz4}8cImNa5@ekm5P)EuA9_;lonMuqnd2wDRR?7t_h^~G8BedKi?x|`k znUBPm|B5t&r28C-`nW-HY_f-0f_(|go|Vn}5E)|Xscm9Ma2nGp8NFbhzIkKC{1!5G zX2VqI8^ppZk~wI3Xk`ZvCOu`f17=14c!Xst!6dX08}3jDxkO5Wf=E_<90%IAM4GXV zaC_hSuN7mrwfM)I~(^CO2PIW{)K>jJX<%G3r)k`LLp$99At%eld)a=qDb2-YfSYCK+)(Ee)jxXI{G;?iJ|8eUt(bc+0^)cf%fC?7a0m4s-i&SvUmFXI zPAX?7_w;tz1eLXmz_d(6Rncy9A%3CQnBMXP5eL@HIC512f8(zZKPYmg3G(^HOduJ@ zUJFM(CdzR(Xm8hy-|uvT&^Qy;c$i6sIMqUDTl(tIbP+AlHU}!JWeH+QZgOUpf%)Cu zyzWb4s&&P3{61bd5rw#u2xre!mv%|0QK#rJ7MF?L8!>ea7USZYMn`H>q775=UV6M; zi+sPHh&9zVRdPbGN@hlo2=*GzD-|&s#=5AUC>BIq+5}#GfjmJKX{gu@KVW423gsUnFW&J&>O|%XoZu0x z?E%38{ZU$}B~VZ=+94J}#a|f=V})yCxP<1KZ(JX0tOqWb>J z^z$O9j*vK>>UThp#+WH?F6IQo2redG9LnhC&>%h!S3~ryys<6-OOu_z9$e=FhXjj9 ze?oHrw<3x`DP}jNafE>sw9Xvg!SOan5(3QQ-nu!y-H3Gqtg~~a69wa9Sd=D+MuJ_iJbM>C^3ZK6Zoz z>42mtatV-*b7i2h2+=mE);891Q_`{xA#*+7M!K8_dC5;l&Bv9O7{6#0H#vePRf~(( zhe2ZIN|!@7%U_FNq|)KFI9K&eWH4w;NV3iE8g8Hyjj&JVP;3=Dy_^(8d2YGW+fY*h!E(NCvySFhA1jp6<~+<-7JkIalx94Ndb+Y>hf zVfzz?6!IRwD^^?5rhQviGcXn(E3ht78wfEdgQqIKj0n zp+`9PS0oHSnmK!aCR~5_=S*ROry1E<3P*Fm&C4?p8BV^6em#v)u1I`vZB(|F_h2UF zFP!4$H)2tUdZiB|Rt%xONbf-XKm>+OagnjkbReuMqLSDASlcvegLj`tTZLS6&_Ll3 zO?7hAuJnGiXQUcHVCeQoZpHa^4zb z@tdcL92)WDZj6lHVP=tSGf|}>nc|X)Pi>K|L5;+kC8LA(Iz>uy_F`v|b7vfs^*Ra@ zk{Tro;psc_!p0G?iq;X3=+5a0R-`r!>(B>;APRu!&;)nHThL)#Wn_7|7igOo73Dpn zs=DHTBdwmmD|d}6YVu#U+kZ^pbq$N?Ll)dCYI;LAw`^Wal=-(*^<-bdYjmX?_r}WF zr}YdDv-|%3>6p~RILhu*B;7j8a{m5Ko{oBe%t$-(%}^Wf+^;K`_t9D z0uWf;m8k5=Quf+X#g=Jn~XX!_Ya@WODynUQ%VLmC}<$%thhSZsfsPkhcn?lMrUb4^Kz8bDpj z%K>Ha00Sn#%;L6An5-MRY`{xi+5^)YCgmQJCUmYK;}M`bh)rE?(*w;qjMXuQ&goAf zF!xDsUqqD!h^`GRg(LVjr`Ucbu!>kg1z{VsEkDc_eu59nzcurj(QS06wa|IJA9gg5=Ff`YJWpVv?;XAy8#*~hp&qfUW zMPAuD_j`XXau_l*cxR1UiS5-CI?2Bv)2(AU==cg}iMcwONf=GZr7s6gOlzO%)=jjK z(MrxLc{X}@F3~a}B06$HX)n$G=HlJu7-*$z4WVkDIYA0`ICIe$Y9>q_T?!BT>-KOR zc*uFq0^i%CZ!0ICN<5Y8+;hksGIDs~!#ozFbMnlJ9b6ODAagmH`z^u`_2k%N+6A$O zH;oZ|dCe?k@EnFBJL9=G&LX!z5&ya1>^L>PJqWtGD*$dU62JTWiyh|*Q;XdMUpqU& z3j%-YzW4^^iF51HJU-T$pG2R9^Vq!mZv}GcYUYZ9lS=U-Nz1;GZ(+xdl?r&RipzF> zsZrA9Fv9|oCI7WN`2PE)z;+Sb5cSGIyBcl)dpTaWL{4zdL-!_~ZplCV6^blTX<~Na(^;lg?aZlI_0&@Z346#qv2TT8;{{UhHxkS@9*4g4 zn6`ul8WiyRxns{I{mOQ&X+rc1|BOQ9pFn<+u~u-D2HZMwH+wj1WWdC;;H~`8LLX50 zeXC_+Ton#2Ym%hvVHk77l;JgabfEwUq?r&e{qFLCs)`q~bF-FR(545e?#O?x11J(s zhhmAYqzk>_OT#4c;jY}pQQH58@3|!121T3b)2e&VnAP)L#Kimfhh9p#324$mu@LV7fzYx!ZoO$=1J>zQ;3)O_zLM6lKw_`EP?JxJ~Zyfw>~1ST^q$zf(WA=2Pf z$}){^RUOJDgTwrwV!MsT_R2V)%^+`un!E;G^rYahhTG!FzG3M?4o&|6wk3iMq2h{C zUNGo72-Pmao674J8~5Xw08FcZ4f0T>Q3Rcbb{TXqVW?6I>lZNrWum}0QxY3QF+sUf z6&(lUNo+utQKR=eo1o(!*{0Wg`o}u3)5y~m&;4F33d=OGlN(Veh1_wGa>J;rg+ z6mzFtMjv7jefqN$2dqkG3qf+PIJ|4APGfEE0Q^%Q#oui_N8NZOs)etC>L<@a`aly~el zM-g_7vo8)*SENr68#=%dipGjXcEph$sGA;e1exhs07gEkA;*4(9M)YgPBVbNR1H1| z#0YGc&ngq(V8|RI0`(Bf#+o(y4}G?YMg_0se$a*q% zdERlta$7qmDa{MRwrau;h)jM+7D(M;rJ5vXiko0&7=sP@-J@+lBx#J+BlM*GOtR^o*pdDlQLS3J}BZ6HNHd_bmMX*Uf3g`6TP(Z!ywg@cUsNPAM{d2UdW@v zlbWXZMyGHWawVBw?Jhv&61YCM5R3oDHOUhtlM)_*www><=F$kEz&q-nRhFSm)8Bbu z>|wM=K?sd{9RAY8e19v(UP)5Y2{P{}UnzRch%ghFiGrSY#=97{f3=^)_ulBAYdR4x z9T{TXvaOG>kMwqdQr#xle&Rw;q2bIja!|teeiMFBi%T#Lza-yBG4a*%km?+qZh3hp zVYw3Dc{D_eH$qOSSP#H8b<=AstmLpS`P^yyrQl>Ogn35+{Rj0+i0E+Qz&jK0%Y~;hFc&et^YBp6W)pq~<2d3PJ0KzUXuvac;*W zjk*__A&*{ymJ2&aU`MFNpzL@1d3hB*TAsq9n1xfaitr#YHP=CeJGY7)_nG#Knpc|@ zu2s)e>sApDsI-*Tb$+fc+&9!hg0)KVsiFHfcr1mm67)=%p90>>G$r|9a`USfJ@k!o z`8Bj@EBxibda6QqmZ{k57LrmCygjwewCJRwwLXm#LMUcG{3hI}jX~rdAuum{$aMK- zWzkNGi~z+Yj#B4&+`*!K-@(9fLwf2P)>ZTaIViI%tZQs_A=l5cX7P?_Uccea27zPi z6HDO53%cvSEwcOj;F+#(h|#1o#J9I4x%l42!dP0%kiiU3wPlVuGM(Wo+P{QzON@79 zE+Yz`WQl>oEN4P8VMKZ-w<1W^PHvI~nH=!Str`%+wR5nuFeoLDKRsk=9rTmBkuy@%w7lcPX z+*%*6ZOI|X{d9S_lER5b81vqEy)62kJkQE>eThAb$|;Ce<`N`E+nlXwni!GK+gXYi zyUdvoaRK*LiAdC$Ng}s}3RoRNz2Mn)hAHExCcY0&{!JSv>Agp7|X*pMfA}GONdw z{05vu=cqTZnWm15wn=5`3PX}`-=@d`@psbECZ(euE1n$40X*&0_$8E*4nO_6Qqh7yRlgh8GLE(X+ zVO`p@$=t{`{mZ8&3+Qd~JvgLO1}jMJ66Kz2b(Z$hh3?fAg$Hqs;7?W@pQg?2iob*y zG$f{!RSZ(7gP@vOR10f_hc`HVFRd7IKBZo(oalCF5M3*Hyi}-wteSyo7qA#yZ9r`o zvlsxc2ja~Ky)>hV=$c!(R6e!z)Ck`iQb+EZ)_7GQaMZb=6O~$?;Rw2r|e$WOOy2LuUx`C zT|iBuZXDLy%NWYBiOsP%Hmx4aZNc1(2nk$A>mn?LPO9RIe*D{BTDE=~43VeS_xf`R z*#39`Qv~Eel&tQzlB;nYg8TjdeT717i4jh^r%^!(>bYwuSsW6>$xL_Y;!h6Q3td#{2UI>KwH+TIK-$gVHY zLZ((_;@^%A>(b`SKY)EcLp|0_P=!;|CtBvl%M>O;h6a%ofldg;KQ;cklUw&q9bg5? zt(JB4C1_NztQWE#&)1G+Ir>rtm{lGoK7?5M(t{Q#khRa{eay4cA&zSJcFSI~%jPZ(`bHRhMYAGJTX zaWx!S_!xQ~L!lY7{U^%yh?YAPu4vwWlL@UIrvc{yBwh(a@J_e(Y` z-%g0&w)x?FW(YT_Ec&Df_L>|!er>`#KhDLY!sm>0$b96xfHp=XY<7pzcToSOE{ zX!5wUBxPXq`5M^3qsbw-u!Qs!mb7Tes-4i5JGG25U9zx{xqjUITPbSAqgk}s1mkV6 zX#R|K6mk5K{=MoI%3N~^vU%xghU{75S?0ben~jh7&<2y?L;l8eMLGXLhP(o3usuMO z#cTn(G}VO6FTex(yVcsEz!Le1C350QtNxLtts#=q5a{}m64RKlpPEgDNS-zurc9+8 z(QAZum;9KkM80RUi9@c1=oodW6z9;2iUKrEWLBveCMnNYSi$`8h&QcsL|>XYO|emd za^0E)!q=DvB1-(WV-nK98_{L>uZI($NjjFcdL*m5Qtq%)&N)_n7ma$!s~(A^W*-~N*tN{57rksTcQgiOJrg34IEU3{7^MXNQ~0o_Ld z*KiwP-;D#toP7wjsU7BR4tJ{MtZu_2jT5<08~PslR7s}%6?XBYDl;D-=)hga;}2@H zqxk+D{kBkj`78pB*Yys?d7!XWAMU~o6lOiAI1n6U`(2-S^|1*$fD3 zL$yYN%<^qT+hyx>=iK-}i2IPxzozIsnZ&&X5qlqTy)NY3guF0#=b?8gK6QcRcVVV@ zuhG4dNxX|7`rKsldfl(xfS-0;&TC0?^Ak3Ryt^FuVa@1l5C!n9PU(-f(wB(rQPC*9_QZ^d$z!8%tH-eSV5Ug8peoUG{^OdRsLUxtn%v zfP9;a;srJDmd;hIhbrD5IjN4Uy7*4hZ?$BcN+kEDykA??Uz!AhJ2*%wH%`*CyDEmP zriz%AjL$}Vc=^+O41RU#{k7<>iSqe=W=%FrM>a_0uf31~-?2O26pQ!bt+zJ%Q%Mg` zb7I(O0gok0=R|P>6Rc%{IZLw*zq9=aIG7<@vZpD3)_xoo81V!N9!5+bb{xOZ`y%Xw z2HTCzI^$VK;l`9yWHw-LVZb*QR{jq9N3{R1YEtnJuh7hZJg!oxzm{gMXk_nfY2+wm zW9?|<>L_Gsq-Xt)${LwptXz@5beok^TU5{rv+*ft^ zyulJkZ>K{rB4~zhxqsyL2S?ymkpC>NB(I=Xs;X!w7gUg2-us0>Nl9rEa!%ydY+y@#X_o2{HeS_UYmd43A)VlByj_?+1^=fXHNh;U6L+WFWLM=-Kx@7FhE8Gi@j z;%mec_5&-im)JeudAGgT6b|PtS)It*Tv?dfJg-H=iY?1BVvs4PYjcm#JvS15IGV6o zRrT}C;oqsBXZgRePVhI4#0(KZeFB9pVI))*#k3Ca?+}IWMmckj`u@YsUIC3})`~gR zh&Q2^M|8oiI8b0$VbeaOe8JzAv0PgI4w)iZbjwd)$R5@{@`qIIN0HR@u2?{@^s)3) z&X$aa)>=H9c5r5l9$DJwr&VTPr}0nrM|U(bIrwj_sHO^P_0-yii{(Bpm`YLYN+S?> z`%rWr*`tVtCv@`!8_g5^4YBa=&ZxEG$=ePA5`M%hwERBt;@l9NhprX@w1|md@f%60 zLfCBVeAOCUROoKXOhqzKV@cf38p5WT$Fya#)>XH;6-Q!u^PHhMPKdXQ67w2lm$l#^ z9qa1l^5^64<|0rvz1Uw0edoj4*--6r7N0XKUA-D)1cq6}G4Ejd;uHbiIpK3VxB~_u z@Ye$Y(1XW<{RBX!>w9l~E?M#*RsGnv@Gsp5{SGJD5bt5bk_Q-{Uj3{wv-zWgn`~|O zz_CZ)0>3LNobZPY;yx7u$s&Bmh?s5{=HdbBU3wUHk%Z$glOn^IJ1oSK>OiLb|;8vC?d&#{$h5#u!N0igynxTsBEYg7rAs0BR}cF|U;G;4ywo-@`X zxKF+y*x=21c+=U^Chv{4z5{lk*XQke{RirXw`AZ+AIZ4j^*-pyRncWkeF1(0zZr~jKNEFfzCW!{AhHNqG%x8kMbA!}74tC*K zF$m=+{2jv%*+ne)@A*iw3c(>tNkd9b632r4${nBWZ_&*N<2tWQJNOZfY)1&i^6&Zx zpFu}0;QInS5+zwAHm!7agu0ZPnxy#AK6tkzBsUQk?=`_TC~31RAIYLf3LKgIJ{g0- zVE}^w76uUj)$zZQRIB)Fd0+%s8W1!5ZE=vOXa!gtzz(lheH z$)r&d$b>Gn8j=dGM^E`H?oypPeu`u9!@MaVAo(rKOMcuPVoD0)*?O zaU;hpL-Vc#DNC9#Mqdqy(bu#Jgw=@&7=uN0C@(3aLkPWwLJ%;@Us;x(1|YzsfpJeS zl`!u)hJv&6zYURbqeIh)@370KqLJu{^JYbm#j?>WJV<H||`i!gM0$1v4 z30M>P{Y2A6ndsO~XeR13*zy?df(2Hy0QPkurPdBPTV7;VHt{dR;EM#-Gw!$jP&jL} zsu>O$FjksmX6Tz!80liwuN!d99cN>&Pf@{6o}{V{ zxaHD^&SpapT6CW0x)tJnGb9tm?_hs^ygTjRys^Ur0fi6)0nz=19EX37sK1XVb!b3( zL+X2Hy2ROptwb-sFFfuCkYI^n->Yd~@nH}`faEJ8A*C!S+eo(|>9{n+2ge4}2CY-| zQ|Iu3m4(ImC8%%2W`~Pn8pU4C$`(4SA&qV8r`Bz!mCw_seXlZnh}MYxF9F6SbE%8UsWD|k#`j&?hAe*y^e zOzS{DG}C(tE_#V}PleT!1&viFf0^0;c%QJ9mGl$CEGzLRhuNE`X?F6@e9NZ<%j1OU zEX1|1(^-p$=Z8|W?f4T*`Hx&?+Djbi+6!t$Hiz8t-enF^%x&&#IYA?1Ze{`BtaXRyhYlq{!_U;i$aXgDB zrId--n0o~BQcFvA`#!dhpJGhhwO_>bdm-op*p??g#!bL)vYJ{ zi~>oDcw3{JjIcS(Y%;4U#fTeqr|D~b8j00Io3k$?G6WWoiC~aNQ8Hm^qd!Vl;$U?2 zp>yJ>+T2Ua|il0ux;-Ep>N>k1o;bC5AAHvPOE5>$slD~9|%E)(rk<#p#g*`XNFWf`ZN&l1( zsaU>KOKX%^YeuuiIlXQboOO)5LhCQqt-0%;U1K)gsw`Qq zH&`JS7PhpMxFHrc);1t2ahOSK8CcB`H_9|L#EYw^Q>s&YNN%95e4! z>}Y&k6hS12WE<-rxN!c)@0)*-WTl8yr&(*VAtH5NTf!7sV`ycGzoP6wZg`V^W_;Dc zv9|wn<1u--J{nbt0e2MdYEY02+?=3{1U4Wn%p3uM01Tr~(j zq7h+aHkiju>!A>GiWV*iV(yy~lw3<4)+IM2MjR-!!v`Z`@2c~EeHE>T*4^i4>z18k zKo9Ic9iWe8iJ?IbcM7jSN~X}2=_VdXk_fYkM_whRNP0ypD(_|{O8CTBIR2S9$(O`l z{_~C~b12E}AV9-sqMiXM&e*xYGYNSV+fSpX9J<8k>EnX@wq(c(S=*wkXiPSSyzzBld_3zq#-MHT46aL$K-yBHD5CO_UM)0 zVDhbrJ-?5xaab!Od}AvZ?Fpzvi7h#>zqOr>YlY~gMK57?n5Z#a4wBm80r7%x8p<6w z6p3U|RBf2Cf~@Ox40R9~<1b!FA2gZYRdy&6>H}5Ga~rW;W3ic?o1xb{6zYV zl*`p#O$_wa2iXZ53yta!NmNoxlv+yaXuyEpk`lg9$rBsNtX?@KBc3C^iV{h>FyoWB zGCPSH+9~5FmT!jcgbd5JqQa6Hs1nKyC_-gnhQgnq*4Se2)V%I!x#cZ*7h!p+(q9j{i5G{~?GV(VoYVlM!DUO-xx+{q`C8#^BCeQN7=pEKut6Ly- z)bu26sA@)mj!9Y+%8)%v1P2-4)|(L`>7(lGM6g+P-OWP72d-~t`88wAM(JvEoVJ0? z8m?G`FXe>YYB({Vuh=Z=1*V0Dioc$Vt?f`B;0arjDipr}M{ZRWVQjIfnHdGA z=L0=W!KouGg_6{V(W0P?9G9<$MORmmNkCCE9_V!W*&G+%$B|%f9%_sIqXH-?_qFH2`)0l++nW^OwBQHO27eor#Mf)hn?$H?I9cRy_U5P zB_=yJ()a*rxcfc__(WJ=Tw_Q|It=Sj=9SB1a!X-xd5#Sph`#Sra7ea^9!}bYF(*XL zfqOoY<9z3qCMm!O7d?!6nx9o@ax&VN(8%Y$d`m|+d`=q8x3OL(Uw6(heqh2kL$7SJ z2i|5t=;(Aq`YMeyb4HcHZ**JkfVMcP#A}4(K6 zOAi=#;_nZZJR6!fsrf5MrDdRSBc&G2HCeWbUc_Q#`($v+_4XWdZLMZ8tUUUUFd$`@ zWv-pLrd!DS&2jyVXy1ChS7M#o@jMxd;42-9GPKHKZ+>TYdrd9imJF?zv;WZqKF=Q+ zpD+fF{c^3~JiN>L1ZRspsnf*Ktta^`s^O8HivAkM=%!}TrYBt>V!8?@rndE;&N_^J{3sQ!gE@CGyvS945LL^+P@9+`haBC^9Pc2@!t zGHQb@`aps3?DKL0c2&u_7(y8whv7JbL&*4yW>RSiB-dS<+K)s$yc4LF{*93j8{2$x zGDP#l*x5#6>akQe9%==9OI%+h`aPM5f zDMm9B3f6-5(Px=!X8Laq%fdh=d?d`@lBG)XqtQPWIg#(wG*J1Q&doX-dlrE;nsZNNE9 z#0$3k@;p%nD^IXQ#N2z^_rr{iM~hs8v@~z zu|yUk?kHu5T%Bc9UGrLyy2H0h+k#K|#Y^AkOO;~^<7^ya$|$ZDXnWU-HM9afey~ZT zyO-faaRkMoMaQT4}+GW1FU>(HGoJY4FBwB63aTp5gt5W|ST1Ub|7YqPWQtV7XM##wt!RHvShF z=r;3&vs#x-qE|Kbb%wEk+3%{cZb_qDP>e&xC4?5r9|%qP)6${1LB#|4;s@SeZuaIP4NwuDQ(Ch8=}q?Q9Djh z`f0}S6?2u@xupi%FH&~ z;iyZ`2|fk`$>#2S+3|%qDxd^LRu9c3v|DW!svXc)X;kd-*#ScQ3il0){VET>PF4v) z>C>S)*KVRoR;o+K^YQ(X5OPgKQji5|rAD*ab`t1RaCbx`1v?XYj`?^Alw^w2=RPxV z75einN=BatyJDvod% zF);PorUTqyFmTN=eZz@m1f?`_R7~Z!7kUHnfOMAHy&ivt{{B#2rCRQV-^aO^R^3~q zdZD;=m=-YhhB!`sRlW`5qqfz=atC_ne2p|Zu_*Ta+)cS#t4LkvL2~z2e%p516;*BIt zq!Y{hd8FRlhmPCr&}0i$0!^(K6Jwf2Sq`Q)o#MwtA-T4*@9al5+4T;5QP%D}q>~kx z124ZYL0XQntz270gnVyczkmfk zaT~DhBeJ>UqYgfJ{TCnguQRL?@M2{HFhjopDuHqQ&-bi|wWGb;-_CNT(yBF}&ZE|9 zmMh{?v)Kyi4KTVn_K+;2j36|#Omn_~737FecZYZZ4i~sb+(<+!hDt?0$PV2o+(j>l zI5Pr%!-WDdufLqYiI?#aG85hQUWV7A+H>RN-c*;5n?JR2HD?3`QnEC4TC?R257PO5 zY>z4~2lf=xULds`uAiS>&)`5ByoDgEHm=@r0!$HfaSm}G2gWEs@D~fTJ#q=kRV>)$ z()@!|3hfqDA!O>68^%w=6f(my#U%)`Qbmi^JFiuHt12ri<|bt-_4#yI!GfpF4yC6N z<{hhEL#V7?OBmtr5x_$h7B9w56L2d@>kS$>Mh!3PTAR=`OEyiZdK_(9ORe8dGRvI5 zhn^Icjb2kg&MN+-<;p^$L5e`}kwOUm(n0PjPJZadswCg%>{0q7kYp-aQm<#GBz z-r2Ml5-s-ZzT1aKnJ%>Yd9f&B+-1)L5gZf_n#vQM7d47(e$Q$l%0}1?SAS&?wU~>xI}rE|uaEO@JLSD`?YDaF<3yK%ehzqVK31zfYz95~7 zGY(h|Ca#j1Ix%>__mtI)i)l!ig)`fMp~ji*Unb5ERrx-uugxURo0cEn<*M_NzFhFc zv{v%|X%_+Wc2l=}>F)CbNFEd4F2ptlY3-(6dc;6C?o~AX$g%#on*_TFqAUYg$~BGj zAdJD`$^GjQ-M3+p`j~Gt#uO1VXzU_ZO2q-7jdZiDNv7aSBLlFFHt_*%5t~HkK~d?i zQR%9SgvPdTcw01H?#IpDK2AyUZ*uY4A}BLP#dk=eKIrh*7C5c&NO9A|@3vvrH3Iup z3Ym}ZvKcl<9s^=n7L;*62G(}5@=-jakTD*A@|WalqCu&BgD}d1t5teZn^?!#B%8d z+{GUufq;1b=et~A~{7R z>m@d?v+&NZx%UqbTkfa2@ZSB&p;Fi`lS0QxH(2ck`jwI5A>lufxHi&#;DHE1qPG<$ z)t1Ef&tptVvKFnC&JgMfv_wSJj=d-ij7PMWh|s4Gm2%|>Wq{meC(vULHOn9p2Ah(+ zs3Rmu!%8E(*$XzdX3u7KUMNXCc`U#hwTgO*hYsv(@tNXrcroaG)Eab&a5W!z zThP4qmTE|dW=%~m@gP}k*=sg3YP(%naIer)IWABL3a2b40OGuwoP=-Yn zb4hM^(E;MoIbVOzE|l_jzOALRt<>=2I(FfL9W0Qnn8hYDMY=T-!RKWkDN&bkLsBl9 z`3&3ZmntbU(eNcX;r^R0qCy)1&Zfs^paBlFu&KvPan7PvQR|i~iXLRiq|<8vyr}jX zk)VFtQ0DP%(thbkn0Tm8m!d_Ia@|htViEl0@Zfi@x9ooGCFRKA7d%*}wmqfgZc_;s zx8PlWMJon{^6^B!&5lgjtJez{JjhoM^kHVU1sqg)GUV13zU`gxCz0l9t&*EU5##d7 zFYey0K2)&lGd5#>+ay^R>@1DMX8`}=g;JjKoIs@cc2{xI#nkJD35h%Ll4&YzI19=5Hzo4#4cWD8xr*r*Ijv$8x%&OF3o+YNuE* zs#pg!7x%{%Gb|@k7G_=`BQ+=P8j`V~zMW!$iwH${(?Wc?(Psog_YC}Sx-)XshYYk1 zKK|ZA%siJy(crl&o#Xn1+|+X^J?U$A7xAxJS$oM~8;jUefWiWhor9^9*Dq^uO{y?j zVQO%(E8TChd5g~ID9{)Z+8Di0R>^ofTkc|)O>!;R$YK|*cyw2*pYZ8uIK$g~$NBy| zH`tn)IWq&C%{PGPpT8n7@#j_fuTN4&e}Bez0G{!HwK>l*yIp20O`wGac@t1*`j$4o zc>YcSA~1qqPBC})*x)*;HBQ_2PYOQ4Hb9Wbq2Ro}D#S5cI`B-g^UNZGl9ZQQ%gf6g z`{R?N*SGikbi+AeVSdM8)|ljb1oW{*IU}StajEsTU}Ve4)W~+d{*mFp>UN zWxy5%_B;`3QETzmQXJObtwRJ(9`x!CL1l(4&L1bGNL=tnn-hnFtHP!h8pD*fN-NU3 z%}Y9oHYJCW6JF|T^49X5$q`Ge_VM4<#GI5W+9{@SF<87K%kL|h3B3#Me4r!5XkuKV z7rakZqmwnRf$3W4a;ic!B)i>_KT@jS8)28J>K2}X9!V6ff1ZH`gGPQk3+wLf!s;uY zPJAnj;5I%~q=|kZ1ip`QSZ*_LR>ki^a3%zZsWe+V81RX!Q(kJeeuv*dZ4&4{068p5 zs4Uw_@o6n7lmuIV7>8?$AOIf%PSpxl5i3>MnpC|<8t&Y70mQe4K+VS|p&5i4hXNf? zU3?^v3mH@lA~Z3(Pn&d7r}3zn4YF3@>v`b!fZZRFoulY?`Oyz29cGhKl(IfHM2PA; z-{!Zh)F+7H5NH_P03jt=MBXb|1(95^P*1g>))9WfPdaqL`+BN9`=LX^5KX}yNs&0e zV1pUbNWmsJ&{0#?fy@@R=-K|09(rO!+i(XT;Vn~Qtvh6Wtx~k$uHNeTgzpYfL>_Wi zFuD7Jd2_-F6}uRf+%3#$rT!V*p9dqQx`S&jK<$JUpmxIazdoq`_H?RHwfL;GkKxVx zeZ7vltTwz!gbE8m8~LWAoH2`+n5rVWUf@ zB}{*QTa*DPI>wug_h2vpv$J@+Jebbxp*EO|nY(100(PG{!t^06xXQv+yN`{zeajCz zoo70*Ifz~UyhqdWvO5F}ZgiS_?F+#w_l1E6MZ2p9<*x$MuisJ-MHGJbZBc1bwCX)l--k$ zS81<1bK6rQhKWV^eIAy)kfCV9VunL6bW%o~>~$ z=0J#6RHfFlrHW}<&^HXeG3?*aNNH*!qu~lAX7h9dgslJ(9R-l`lvme2eK`QFQ2Ts< z4?2&gnjI;=%I9C6>yF7~G?(4BjEljFrct(vIO6x&kR1_cUTCI&`g5;%&`zk|hf$b; z;NabFxIFgyF2pP;QP`2kREuc6;sPNXPy#_B_gw?I*Ni4QqEiQjX&2H9hDJANQ3~dT zz($QKd_rb*V7WPqRLzZp5vuNO{&^fTRaE07LOc`7n5sp_dQ?+0n9xy_3 ztV2X430Vp$OQ=jYw#Em=S!;B?scb=(8qOX*l+@ zO8ICIVus>H5E}q54|doEYiE4^e(~<=b4@K&37@tsbLe_16Y`V>h=z1&aJ)Y?H9I{p zKRo81ZYT@Fq00yzDw91hQBaP}*ES-aRgQH9WN~jyv6`P{#z~V`YiumfH~7dYrjwLZ zwe0e{cKMskip#blr5Y;PM203ywN9ZQ3h>~BGs3t*EQu!|Gp`DRx)5V7D3+jDEDI97 zA}e9y7``1$ghs?Bsr8DB>5GnXpBxu;LS{O*w%#`L=3|)^mMCVc#>J|2=Pyk#=Useo zkTfqLG1%{5MVAP=om*SbFG>2g&D<2OpV4aIOvqSAhNOYLkopy4&4L4GA%w&aC2529 z8q$-IV*rJ;{_3TnUQ4xU@q-i#-RgCvaT(!xLP^d;pz0AJ33fQc(z>DLDoz|MHq6{x zD+UQxorAGihxH)a_XgJSTqP?5DSE3uw?#BtzzKAPdilX9EbPqfps*-U~|=1(f&GN*p)r&u>sNM%ptQm6rE zSLrPTH{d>zB`aqGuA?wO{;ZPJW=>(7Ra-k~bPHL&>oGU6Uk8Hn03<6&(4&UnLwWHn zgX362+naRCghUK)=>e03g?)8wzj>z_pM7-GuGw8o-W&4Re;~Q~#NUlZnt1th2 zfV&; zbtCn5mT21Sj|s0>_W|_I5Ua;@j<7RC;Hq7lg+~g1JR;vA2mT~Ofh!&>Ncp`NSMqK3 zaa4P;Rd!}~U2l&G^wP(V7y=dmHArM_5wifIE%ZL9Z7EIX(_W~it2v0+JtW-x@t*8~7C*wO(Vs8e*5slqg?Vs$ z%#PHe)in$8G84R#4>izOs0Um|%;x2LRog=(3Vvwp-pRK+l-B9&JY4xi?u%ADvO!VPw_65>ik>kPC^l(GwLrbV_TM!{uk`;PGUu|q!MRoZ|u#w;4 zCvcJpqvAQ3@Hjg5)k6BIuLiG;G6E~iP01frnL}+V506yH4Kh|bt@Kq**GKiqdy4Ev zPk`x+E#43&^D`{`(P}Cyem+68_q0-}a)!b3)H-4`RP}CRd7n;fF0G;amHixSfNn3< z(lA&}Glr3-Qk+-O$`)>A ztJKOi-nZ9@&B6C4QCWW&#W3gBawP8tIA~=wN)DZZ6$i%p715vj(LwsksL^qB##mFw zFcI+vIujNtOrK1ux?GW=s}^L(u^FN7wEJuOqKHmXjb5kpvM`trbBHcxe2t8t@3Bx1v8XpT^=Z6^G~EM8Ucr;j@KP;& zdaYkDcpk#dR@PDHEiZ4E2gouK+z{mG^au0J4B`lX4KyZXm}@`%4>AsdJzyoi;1oQ7$G>IYymwXmy?l9L0l#Ua zKCqJBV+vFp<+G1YGukz&R5elzvTsZ0_~C=WdN4?#W%x=AR41y$(>9FSyin+$X-K_# zhD(TClKu3~lhb2qV)!L%icK@|oAe{S&LaYTml91*0BWr;>i)dB*W!gcm%8K|2a`-d zyN7vzrpR0=bea=N#~j2mdx2LOd{8+J`47&sOwr-O5oQ?`rkKrpi_Zg zhcY5c0yGk`qI7>Wg8=#^y|T&dZ+Tl+CzrO81+W-!*{`uh-K;FLxump&Gnpyw(EBp?G|0kfe{|xkhIXHiu zkiT7o`ud$W#t0+S2=<4`8LY^Q7x;mgA#(>{H&djgN z*aA>q_$Pv_oDu-zcYt44(NcnQToBN8djKIIyz`%1zMnASf2?Nx&s?H^?b0vAFPi0= z&Hyw*z$+o=KkP`R_cAd^$`< zfS#)YxM=>wlZ5);c>Z33`yXzh-=X^o1nS2D&|(0q*Po$9(f=y+-~9u>L%+n`j6DLN z1OGp0EzG|P&Ghe2$OkG#0W1J)Ea1fdx!2#Y|0*=|zlXkNgMI!EIM1(u8~xAF;P`(P zn&sa^^GuW_50C(qLKJ|2sQz>rDT)3f^uGuGUE=;9*!h0!68{bOUj^@fzk!3=6B7`Kk)IC|2zJFQ1JYn=y&z4KZrWD{u;6}o-(5n#bNy~q{)5Z6>3`+=lZp9vqTdaMe-Od8{*Ofe7-FCR TS2tko1Nh1OwZ!fF_38fs60)DA literal 0 HcmV?d00001 diff --git a/java/lib/test/hamcrest-core-1.3.jar b/java/lib/test/hamcrest-core-1.3.jar new file mode 100644 index 0000000000000000000000000000000000000000..9d5fe16e3dd37ebe79a36f61f5d0e1a69a653a8a GIT binary patch literal 45024 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 UgpPtD2z>DYYp}SJr5?)v0beu;=l}o! literal 0 HcmV?d00001 diff --git a/java/lib/test/junit-4.11.jar b/java/lib/test/junit-4.11.jar new file mode 100644 index 0000000000000000000000000000000000000000..aaf74448492932e95902b40a70c7a4da5bad4744 GIT binary patch literal 245039 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
    +     * The .proto files that were explicitly listed on the command-line.  The
    +     * code generator should generate code only for these files.  Each file's
    +     * descriptor will be included in proto_file, below.
    +     * 
    + */ + java.util.List + getFileToGenerateList(); + /** + * repeated string file_to_generate = 1; + * + *
    +     * The .proto files that were explicitly listed on the command-line.  The
    +     * code generator should generate code only for these files.  Each file's
    +     * descriptor will be included in proto_file, below.
    +     * 
    + */ + int getFileToGenerateCount(); + /** + * repeated string file_to_generate = 1; + * + *
    +     * The .proto files that were explicitly listed on the command-line.  The
    +     * code generator should generate code only for these files.  Each file's
    +     * descriptor will be included in proto_file, below.
    +     * 
    + */ + java.lang.String getFileToGenerate(int index); + /** + * repeated string file_to_generate = 1; + * + *
    +     * The .proto files that were explicitly listed on the command-line.  The
    +     * code generator should generate code only for these files.  Each file's
    +     * descriptor will be included in proto_file, below.
    +     * 
    + */ + com.google.protobuf.ByteString + getFileToGenerateBytes(int index); + + // optional string parameter = 2; + /** + * optional string parameter = 2; + * + *
    +     * The generator parameter passed on the command-line.
    +     * 
    + */ + boolean hasParameter(); + /** + * optional string parameter = 2; + * + *
    +     * The generator parameter passed on the command-line.
    +     * 
    + */ + java.lang.String getParameter(); + /** + * optional string parameter = 2; + * + *
    +     * The generator parameter passed on the command-line.
    +     * 
    + */ + com.google.protobuf.ByteString + getParameterBytes(); + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +     * FileDescriptorProtos for all files in files_to_generate and everything
    +     * they import.  The files will appear in topological order, so each file
    +     * appears before any file that imports it.
    +     *
    +     * protoc guarantees that all proto_files will be written after
    +     * the fields above, even though this is not technically guaranteed by the
    +     * protobuf wire format.  This theoretically could allow a plugin to stream
    +     * in the FileDescriptorProtos and handle them one by one rather than read
    +     * the entire set into memory at once.  However, as of this writing, this
    +     * is not similarly optimized on protoc's end -- it will store all fields in
    +     * memory at once before sending them to the plugin.
    +     * 
    + */ + java.util.List + getProtoFileList(); + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +     * FileDescriptorProtos for all files in files_to_generate and everything
    +     * they import.  The files will appear in topological order, so each file
    +     * appears before any file that imports it.
    +     *
    +     * protoc guarantees that all proto_files will be written after
    +     * the fields above, even though this is not technically guaranteed by the
    +     * protobuf wire format.  This theoretically could allow a plugin to stream
    +     * in the FileDescriptorProtos and handle them one by one rather than read
    +     * the entire set into memory at once.  However, as of this writing, this
    +     * is not similarly optimized on protoc's end -- it will store all fields in
    +     * memory at once before sending them to the plugin.
    +     * 
    + */ + com.google.protobuf.DescriptorProtos.FileDescriptorProto getProtoFile(int index); + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +     * FileDescriptorProtos for all files in files_to_generate and everything
    +     * they import.  The files will appear in topological order, so each file
    +     * appears before any file that imports it.
    +     *
    +     * protoc guarantees that all proto_files will be written after
    +     * the fields above, even though this is not technically guaranteed by the
    +     * protobuf wire format.  This theoretically could allow a plugin to stream
    +     * in the FileDescriptorProtos and handle them one by one rather than read
    +     * the entire set into memory at once.  However, as of this writing, this
    +     * is not similarly optimized on protoc's end -- it will store all fields in
    +     * memory at once before sending them to the plugin.
    +     * 
    + */ + int getProtoFileCount(); + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +     * FileDescriptorProtos for all files in files_to_generate and everything
    +     * they import.  The files will appear in topological order, so each file
    +     * appears before any file that imports it.
    +     *
    +     * protoc guarantees that all proto_files will be written after
    +     * the fields above, even though this is not technically guaranteed by the
    +     * protobuf wire format.  This theoretically could allow a plugin to stream
    +     * in the FileDescriptorProtos and handle them one by one rather than read
    +     * the entire set into memory at once.  However, as of this writing, this
    +     * is not similarly optimized on protoc's end -- it will store all fields in
    +     * memory at once before sending them to the plugin.
    +     * 
    + */ + java.util.List + getProtoFileOrBuilderList(); + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +     * FileDescriptorProtos for all files in files_to_generate and everything
    +     * they import.  The files will appear in topological order, so each file
    +     * appears before any file that imports it.
    +     *
    +     * protoc guarantees that all proto_files will be written after
    +     * the fields above, even though this is not technically guaranteed by the
    +     * protobuf wire format.  This theoretically could allow a plugin to stream
    +     * in the FileDescriptorProtos and handle them one by one rather than read
    +     * the entire set into memory at once.  However, as of this writing, this
    +     * is not similarly optimized on protoc's end -- it will store all fields in
    +     * memory at once before sending them to the plugin.
    +     * 
    + */ + com.google.protobuf.DescriptorProtos.FileDescriptorProtoOrBuilder getProtoFileOrBuilder( + int index); + } + /** + * Protobuf type {@code google.protobuf.compiler.CodeGeneratorRequest} + * + *
    +   * An encoded CodeGeneratorRequest is written to the plugin's stdin.
    +   * 
    + */ + public static final class CodeGeneratorRequest extends + com.google.protobuf.GeneratedMessage + implements CodeGeneratorRequestOrBuilder { + // Use CodeGeneratorRequest.newBuilder() to construct. + private CodeGeneratorRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private CodeGeneratorRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final CodeGeneratorRequest defaultInstance; + public static CodeGeneratorRequest getDefaultInstance() { + return defaultInstance; + } + + public CodeGeneratorRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CodeGeneratorRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + fileToGenerate_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000001; + } + fileToGenerate_.add(input.readBytes()); + break; + } + case 18: { + bitField0_ |= 0x00000001; + parameter_ = input.readBytes(); + break; + } + case 122: { + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + protoFile_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000004; + } + protoFile_.add(input.readMessage(com.google.protobuf.DescriptorProtos.FileDescriptorProto.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + fileToGenerate_ = new com.google.protobuf.UnmodifiableLazyStringList(fileToGenerate_); + } + if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + protoFile_ = java.util.Collections.unmodifiableList(protoFile_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest.class, com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public CodeGeneratorRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CodeGeneratorRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // repeated string file_to_generate = 1; + public static final int FILE_TO_GENERATE_FIELD_NUMBER = 1; + private com.google.protobuf.LazyStringList fileToGenerate_; + /** + * repeated string file_to_generate = 1; + * + *
    +     * The .proto files that were explicitly listed on the command-line.  The
    +     * code generator should generate code only for these files.  Each file's
    +     * descriptor will be included in proto_file, below.
    +     * 
    + */ + public java.util.List + getFileToGenerateList() { + return fileToGenerate_; + } + /** + * repeated string file_to_generate = 1; + * + *
    +     * The .proto files that were explicitly listed on the command-line.  The
    +     * code generator should generate code only for these files.  Each file's
    +     * descriptor will be included in proto_file, below.
    +     * 
    + */ + public int getFileToGenerateCount() { + return fileToGenerate_.size(); + } + /** + * repeated string file_to_generate = 1; + * + *
    +     * The .proto files that were explicitly listed on the command-line.  The
    +     * code generator should generate code only for these files.  Each file's
    +     * descriptor will be included in proto_file, below.
    +     * 
    + */ + public java.lang.String getFileToGenerate(int index) { + return fileToGenerate_.get(index); + } + /** + * repeated string file_to_generate = 1; + * + *
    +     * The .proto files that were explicitly listed on the command-line.  The
    +     * code generator should generate code only for these files.  Each file's
    +     * descriptor will be included in proto_file, below.
    +     * 
    + */ + public com.google.protobuf.ByteString + getFileToGenerateBytes(int index) { + return fileToGenerate_.getByteString(index); + } + + // optional string parameter = 2; + public static final int PARAMETER_FIELD_NUMBER = 2; + private java.lang.Object parameter_; + /** + * optional string parameter = 2; + * + *
    +     * The generator parameter passed on the command-line.
    +     * 
    + */ + public boolean hasParameter() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string parameter = 2; + * + *
    +     * The generator parameter passed on the command-line.
    +     * 
    + */ + public java.lang.String getParameter() { + java.lang.Object ref = parameter_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + parameter_ = s; + } + return s; + } + } + /** + * optional string parameter = 2; + * + *
    +     * The generator parameter passed on the command-line.
    +     * 
    + */ + public com.google.protobuf.ByteString + getParameterBytes() { + java.lang.Object ref = parameter_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + parameter_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + public static final int PROTO_FILE_FIELD_NUMBER = 15; + private java.util.List protoFile_; + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +     * FileDescriptorProtos for all files in files_to_generate and everything
    +     * they import.  The files will appear in topological order, so each file
    +     * appears before any file that imports it.
    +     *
    +     * protoc guarantees that all proto_files will be written after
    +     * the fields above, even though this is not technically guaranteed by the
    +     * protobuf wire format.  This theoretically could allow a plugin to stream
    +     * in the FileDescriptorProtos and handle them one by one rather than read
    +     * the entire set into memory at once.  However, as of this writing, this
    +     * is not similarly optimized on protoc's end -- it will store all fields in
    +     * memory at once before sending them to the plugin.
    +     * 
    + */ + public java.util.List getProtoFileList() { + return protoFile_; + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +     * FileDescriptorProtos for all files in files_to_generate and everything
    +     * they import.  The files will appear in topological order, so each file
    +     * appears before any file that imports it.
    +     *
    +     * protoc guarantees that all proto_files will be written after
    +     * the fields above, even though this is not technically guaranteed by the
    +     * protobuf wire format.  This theoretically could allow a plugin to stream
    +     * in the FileDescriptorProtos and handle them one by one rather than read
    +     * the entire set into memory at once.  However, as of this writing, this
    +     * is not similarly optimized on protoc's end -- it will store all fields in
    +     * memory at once before sending them to the plugin.
    +     * 
    + */ + public java.util.List + getProtoFileOrBuilderList() { + return protoFile_; + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +     * FileDescriptorProtos for all files in files_to_generate and everything
    +     * they import.  The files will appear in topological order, so each file
    +     * appears before any file that imports it.
    +     *
    +     * protoc guarantees that all proto_files will be written after
    +     * the fields above, even though this is not technically guaranteed by the
    +     * protobuf wire format.  This theoretically could allow a plugin to stream
    +     * in the FileDescriptorProtos and handle them one by one rather than read
    +     * the entire set into memory at once.  However, as of this writing, this
    +     * is not similarly optimized on protoc's end -- it will store all fields in
    +     * memory at once before sending them to the plugin.
    +     * 
    + */ + public int getProtoFileCount() { + return protoFile_.size(); + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +     * FileDescriptorProtos for all files in files_to_generate and everything
    +     * they import.  The files will appear in topological order, so each file
    +     * appears before any file that imports it.
    +     *
    +     * protoc guarantees that all proto_files will be written after
    +     * the fields above, even though this is not technically guaranteed by the
    +     * protobuf wire format.  This theoretically could allow a plugin to stream
    +     * in the FileDescriptorProtos and handle them one by one rather than read
    +     * the entire set into memory at once.  However, as of this writing, this
    +     * is not similarly optimized on protoc's end -- it will store all fields in
    +     * memory at once before sending them to the plugin.
    +     * 
    + */ + public com.google.protobuf.DescriptorProtos.FileDescriptorProto getProtoFile(int index) { + return protoFile_.get(index); + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +     * FileDescriptorProtos for all files in files_to_generate and everything
    +     * they import.  The files will appear in topological order, so each file
    +     * appears before any file that imports it.
    +     *
    +     * protoc guarantees that all proto_files will be written after
    +     * the fields above, even though this is not technically guaranteed by the
    +     * protobuf wire format.  This theoretically could allow a plugin to stream
    +     * in the FileDescriptorProtos and handle them one by one rather than read
    +     * the entire set into memory at once.  However, as of this writing, this
    +     * is not similarly optimized on protoc's end -- it will store all fields in
    +     * memory at once before sending them to the plugin.
    +     * 
    + */ + public com.google.protobuf.DescriptorProtos.FileDescriptorProtoOrBuilder getProtoFileOrBuilder( + int index) { + return protoFile_.get(index); + } + + private void initFields() { + fileToGenerate_ = com.google.protobuf.LazyStringArrayList.EMPTY; + parameter_ = ""; + protoFile_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + for (int i = 0; i < getProtoFileCount(); i++) { + if (!getProtoFile(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < fileToGenerate_.size(); i++) { + output.writeBytes(1, fileToGenerate_.getByteString(i)); + } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(2, getParameterBytes()); + } + for (int i = 0; i < protoFile_.size(); i++) { + output.writeMessage(15, protoFile_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < fileToGenerate_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(fileToGenerate_.getByteString(i)); + } + size += dataSize; + size += 1 * getFileToGenerateList().size(); + } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getParameterBytes()); + } + for (int i = 0; i < protoFile_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(15, protoFile_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code google.protobuf.compiler.CodeGeneratorRequest} + * + *
    +     * An encoded CodeGeneratorRequest is written to the plugin's stdin.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest.class, com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest.Builder.class); + } + + // Construct using com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getProtoFileFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileToGenerate_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + parameter_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + if (protoFileBuilder_ == null) { + protoFile_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + } else { + protoFileBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorRequest_descriptor; + } + + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest getDefaultInstanceForType() { + return com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest.getDefaultInstance(); + } + + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest build() { + com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest buildPartial() { + com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest result = new com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + fileToGenerate_ = new com.google.protobuf.UnmodifiableLazyStringList( + fileToGenerate_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.fileToGenerate_ = fileToGenerate_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000001; + } + result.parameter_ = parameter_; + if (protoFileBuilder_ == null) { + if (((bitField0_ & 0x00000004) == 0x00000004)) { + protoFile_ = java.util.Collections.unmodifiableList(protoFile_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.protoFile_ = protoFile_; + } else { + result.protoFile_ = protoFileBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest) { + return mergeFrom((com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest other) { + if (other == com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest.getDefaultInstance()) return this; + if (!other.fileToGenerate_.isEmpty()) { + if (fileToGenerate_.isEmpty()) { + fileToGenerate_ = other.fileToGenerate_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureFileToGenerateIsMutable(); + fileToGenerate_.addAll(other.fileToGenerate_); + } + onChanged(); + } + if (other.hasParameter()) { + bitField0_ |= 0x00000002; + parameter_ = other.parameter_; + onChanged(); + } + if (protoFileBuilder_ == null) { + if (!other.protoFile_.isEmpty()) { + if (protoFile_.isEmpty()) { + protoFile_ = other.protoFile_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureProtoFileIsMutable(); + protoFile_.addAll(other.protoFile_); + } + onChanged(); + } + } else { + if (!other.protoFile_.isEmpty()) { + if (protoFileBuilder_.isEmpty()) { + protoFileBuilder_.dispose(); + protoFileBuilder_ = null; + protoFile_ = other.protoFile_; + bitField0_ = (bitField0_ & ~0x00000004); + protoFileBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getProtoFileFieldBuilder() : null; + } else { + protoFileBuilder_.addAllMessages(other.protoFile_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + for (int i = 0; i < getProtoFileCount(); i++) { + if (!getProtoFile(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated string file_to_generate = 1; + private com.google.protobuf.LazyStringList fileToGenerate_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureFileToGenerateIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + fileToGenerate_ = new com.google.protobuf.LazyStringArrayList(fileToGenerate_); + bitField0_ |= 0x00000001; + } + } + /** + * repeated string file_to_generate = 1; + * + *
    +       * The .proto files that were explicitly listed on the command-line.  The
    +       * code generator should generate code only for these files.  Each file's
    +       * descriptor will be included in proto_file, below.
    +       * 
    + */ + public java.util.List + getFileToGenerateList() { + return java.util.Collections.unmodifiableList(fileToGenerate_); + } + /** + * repeated string file_to_generate = 1; + * + *
    +       * The .proto files that were explicitly listed on the command-line.  The
    +       * code generator should generate code only for these files.  Each file's
    +       * descriptor will be included in proto_file, below.
    +       * 
    + */ + public int getFileToGenerateCount() { + return fileToGenerate_.size(); + } + /** + * repeated string file_to_generate = 1; + * + *
    +       * The .proto files that were explicitly listed on the command-line.  The
    +       * code generator should generate code only for these files.  Each file's
    +       * descriptor will be included in proto_file, below.
    +       * 
    + */ + public java.lang.String getFileToGenerate(int index) { + return fileToGenerate_.get(index); + } + /** + * repeated string file_to_generate = 1; + * + *
    +       * The .proto files that were explicitly listed on the command-line.  The
    +       * code generator should generate code only for these files.  Each file's
    +       * descriptor will be included in proto_file, below.
    +       * 
    + */ + public com.google.protobuf.ByteString + getFileToGenerateBytes(int index) { + return fileToGenerate_.getByteString(index); + } + /** + * repeated string file_to_generate = 1; + * + *
    +       * The .proto files that were explicitly listed on the command-line.  The
    +       * code generator should generate code only for these files.  Each file's
    +       * descriptor will be included in proto_file, below.
    +       * 
    + */ + public Builder setFileToGenerate( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileToGenerateIsMutable(); + fileToGenerate_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string file_to_generate = 1; + * + *
    +       * The .proto files that were explicitly listed on the command-line.  The
    +       * code generator should generate code only for these files.  Each file's
    +       * descriptor will be included in proto_file, below.
    +       * 
    + */ + public Builder addFileToGenerate( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileToGenerateIsMutable(); + fileToGenerate_.add(value); + onChanged(); + return this; + } + /** + * repeated string file_to_generate = 1; + * + *
    +       * The .proto files that were explicitly listed on the command-line.  The
    +       * code generator should generate code only for these files.  Each file's
    +       * descriptor will be included in proto_file, below.
    +       * 
    + */ + public Builder addAllFileToGenerate( + java.lang.Iterable values) { + ensureFileToGenerateIsMutable(); + super.addAll(values, fileToGenerate_); + onChanged(); + return this; + } + /** + * repeated string file_to_generate = 1; + * + *
    +       * The .proto files that were explicitly listed on the command-line.  The
    +       * code generator should generate code only for these files.  Each file's
    +       * descriptor will be included in proto_file, below.
    +       * 
    + */ + public Builder clearFileToGenerate() { + fileToGenerate_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * repeated string file_to_generate = 1; + * + *
    +       * The .proto files that were explicitly listed on the command-line.  The
    +       * code generator should generate code only for these files.  Each file's
    +       * descriptor will be included in proto_file, below.
    +       * 
    + */ + public Builder addFileToGenerateBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileToGenerateIsMutable(); + fileToGenerate_.add(value); + onChanged(); + return this; + } + + // optional string parameter = 2; + private java.lang.Object parameter_ = ""; + /** + * optional string parameter = 2; + * + *
    +       * The generator parameter passed on the command-line.
    +       * 
    + */ + public boolean hasParameter() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string parameter = 2; + * + *
    +       * The generator parameter passed on the command-line.
    +       * 
    + */ + public java.lang.String getParameter() { + java.lang.Object ref = parameter_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + parameter_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string parameter = 2; + * + *
    +       * The generator parameter passed on the command-line.
    +       * 
    + */ + public com.google.protobuf.ByteString + getParameterBytes() { + java.lang.Object ref = parameter_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + parameter_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string parameter = 2; + * + *
    +       * The generator parameter passed on the command-line.
    +       * 
    + */ + public Builder setParameter( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + parameter_ = value; + onChanged(); + return this; + } + /** + * optional string parameter = 2; + * + *
    +       * The generator parameter passed on the command-line.
    +       * 
    + */ + public Builder clearParameter() { + bitField0_ = (bitField0_ & ~0x00000002); + parameter_ = getDefaultInstance().getParameter(); + onChanged(); + return this; + } + /** + * optional string parameter = 2; + * + *
    +       * The generator parameter passed on the command-line.
    +       * 
    + */ + public Builder setParameterBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + parameter_ = value; + onChanged(); + return this; + } + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + private java.util.List protoFile_ = + java.util.Collections.emptyList(); + private void ensureProtoFileIsMutable() { + if (!((bitField0_ & 0x00000004) == 0x00000004)) { + protoFile_ = new java.util.ArrayList(protoFile_); + bitField0_ |= 0x00000004; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.google.protobuf.DescriptorProtos.FileDescriptorProto, com.google.protobuf.DescriptorProtos.FileDescriptorProto.Builder, com.google.protobuf.DescriptorProtos.FileDescriptorProtoOrBuilder> protoFileBuilder_; + + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public java.util.List getProtoFileList() { + if (protoFileBuilder_ == null) { + return java.util.Collections.unmodifiableList(protoFile_); + } else { + return protoFileBuilder_.getMessageList(); + } + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public int getProtoFileCount() { + if (protoFileBuilder_ == null) { + return protoFile_.size(); + } else { + return protoFileBuilder_.getCount(); + } + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public com.google.protobuf.DescriptorProtos.FileDescriptorProto getProtoFile(int index) { + if (protoFileBuilder_ == null) { + return protoFile_.get(index); + } else { + return protoFileBuilder_.getMessage(index); + } + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public Builder setProtoFile( + int index, com.google.protobuf.DescriptorProtos.FileDescriptorProto value) { + if (protoFileBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureProtoFileIsMutable(); + protoFile_.set(index, value); + onChanged(); + } else { + protoFileBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public Builder setProtoFile( + int index, com.google.protobuf.DescriptorProtos.FileDescriptorProto.Builder builderForValue) { + if (protoFileBuilder_ == null) { + ensureProtoFileIsMutable(); + protoFile_.set(index, builderForValue.build()); + onChanged(); + } else { + protoFileBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public Builder addProtoFile(com.google.protobuf.DescriptorProtos.FileDescriptorProto value) { + if (protoFileBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureProtoFileIsMutable(); + protoFile_.add(value); + onChanged(); + } else { + protoFileBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public Builder addProtoFile( + int index, com.google.protobuf.DescriptorProtos.FileDescriptorProto value) { + if (protoFileBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureProtoFileIsMutable(); + protoFile_.add(index, value); + onChanged(); + } else { + protoFileBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public Builder addProtoFile( + com.google.protobuf.DescriptorProtos.FileDescriptorProto.Builder builderForValue) { + if (protoFileBuilder_ == null) { + ensureProtoFileIsMutable(); + protoFile_.add(builderForValue.build()); + onChanged(); + } else { + protoFileBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public Builder addProtoFile( + int index, com.google.protobuf.DescriptorProtos.FileDescriptorProto.Builder builderForValue) { + if (protoFileBuilder_ == null) { + ensureProtoFileIsMutable(); + protoFile_.add(index, builderForValue.build()); + onChanged(); + } else { + protoFileBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public Builder addAllProtoFile( + java.lang.Iterable values) { + if (protoFileBuilder_ == null) { + ensureProtoFileIsMutable(); + super.addAll(values, protoFile_); + onChanged(); + } else { + protoFileBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public Builder clearProtoFile() { + if (protoFileBuilder_ == null) { + protoFile_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + } else { + protoFileBuilder_.clear(); + } + return this; + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public Builder removeProtoFile(int index) { + if (protoFileBuilder_ == null) { + ensureProtoFileIsMutable(); + protoFile_.remove(index); + onChanged(); + } else { + protoFileBuilder_.remove(index); + } + return this; + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public com.google.protobuf.DescriptorProtos.FileDescriptorProto.Builder getProtoFileBuilder( + int index) { + return getProtoFileFieldBuilder().getBuilder(index); + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public com.google.protobuf.DescriptorProtos.FileDescriptorProtoOrBuilder getProtoFileOrBuilder( + int index) { + if (protoFileBuilder_ == null) { + return protoFile_.get(index); } else { + return protoFileBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public java.util.List + getProtoFileOrBuilderList() { + if (protoFileBuilder_ != null) { + return protoFileBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(protoFile_); + } + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public com.google.protobuf.DescriptorProtos.FileDescriptorProto.Builder addProtoFileBuilder() { + return getProtoFileFieldBuilder().addBuilder( + com.google.protobuf.DescriptorProtos.FileDescriptorProto.getDefaultInstance()); + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public com.google.protobuf.DescriptorProtos.FileDescriptorProto.Builder addProtoFileBuilder( + int index) { + return getProtoFileFieldBuilder().addBuilder( + index, com.google.protobuf.DescriptorProtos.FileDescriptorProto.getDefaultInstance()); + } + /** + * repeated .google.protobuf.FileDescriptorProto proto_file = 15; + * + *
    +       * FileDescriptorProtos for all files in files_to_generate and everything
    +       * they import.  The files will appear in topological order, so each file
    +       * appears before any file that imports it.
    +       *
    +       * protoc guarantees that all proto_files will be written after
    +       * the fields above, even though this is not technically guaranteed by the
    +       * protobuf wire format.  This theoretically could allow a plugin to stream
    +       * in the FileDescriptorProtos and handle them one by one rather than read
    +       * the entire set into memory at once.  However, as of this writing, this
    +       * is not similarly optimized on protoc's end -- it will store all fields in
    +       * memory at once before sending them to the plugin.
    +       * 
    + */ + public java.util.List + getProtoFileBuilderList() { + return getProtoFileFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.google.protobuf.DescriptorProtos.FileDescriptorProto, com.google.protobuf.DescriptorProtos.FileDescriptorProto.Builder, com.google.protobuf.DescriptorProtos.FileDescriptorProtoOrBuilder> + getProtoFileFieldBuilder() { + if (protoFileBuilder_ == null) { + protoFileBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.google.protobuf.DescriptorProtos.FileDescriptorProto, com.google.protobuf.DescriptorProtos.FileDescriptorProto.Builder, com.google.protobuf.DescriptorProtos.FileDescriptorProtoOrBuilder>( + protoFile_, + ((bitField0_ & 0x00000004) == 0x00000004), + getParentForChildren(), + isClean()); + protoFile_ = null; + } + return protoFileBuilder_; + } + + // @@protoc_insertion_point(builder_scope:google.protobuf.compiler.CodeGeneratorRequest) + } + + static { + defaultInstance = new CodeGeneratorRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) + } + + public interface CodeGeneratorResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional string error = 1; + /** + * optional string error = 1; + * + *
    +     * Error message.  If non-empty, code generation failed.  The plugin process
    +     * should exit with status code zero even if it reports an error in this way.
    +     *
    +     * This should be used to indicate errors in .proto files which prevent the
    +     * code generator from generating correct code.  Errors which indicate a
    +     * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +     * unparseable -- should be reported by writing a message to stderr and
    +     * exiting with a non-zero status code.
    +     * 
    + */ + boolean hasError(); + /** + * optional string error = 1; + * + *
    +     * Error message.  If non-empty, code generation failed.  The plugin process
    +     * should exit with status code zero even if it reports an error in this way.
    +     *
    +     * This should be used to indicate errors in .proto files which prevent the
    +     * code generator from generating correct code.  Errors which indicate a
    +     * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +     * unparseable -- should be reported by writing a message to stderr and
    +     * exiting with a non-zero status code.
    +     * 
    + */ + java.lang.String getError(); + /** + * optional string error = 1; + * + *
    +     * Error message.  If non-empty, code generation failed.  The plugin process
    +     * should exit with status code zero even if it reports an error in this way.
    +     *
    +     * This should be used to indicate errors in .proto files which prevent the
    +     * code generator from generating correct code.  Errors which indicate a
    +     * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +     * unparseable -- should be reported by writing a message to stderr and
    +     * exiting with a non-zero status code.
    +     * 
    + */ + com.google.protobuf.ByteString + getErrorBytes(); + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + java.util.List + getFileList(); + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File getFile(int index); + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + int getFileCount(); + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + java.util.List + getFileOrBuilderList(); + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.FileOrBuilder getFileOrBuilder( + int index); + } + /** + * Protobuf type {@code google.protobuf.compiler.CodeGeneratorResponse} + * + *
    +   * The plugin writes an encoded CodeGeneratorResponse to stdout.
    +   * 
    + */ + public static final class CodeGeneratorResponse extends + com.google.protobuf.GeneratedMessage + implements CodeGeneratorResponseOrBuilder { + // Use CodeGeneratorResponse.newBuilder() to construct. + private CodeGeneratorResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private CodeGeneratorResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final CodeGeneratorResponse defaultInstance; + public static CodeGeneratorResponse getDefaultInstance() { + return defaultInstance; + } + + public CodeGeneratorResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CodeGeneratorResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + error_ = input.readBytes(); + break; + } + case 122: { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + file_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + file_.add(input.readMessage(com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + file_ = java.util.Collections.unmodifiableList(file_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.class, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public CodeGeneratorResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CodeGeneratorResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public interface FileOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional string name = 1; + /** + * optional string name = 1; + * + *
    +       * The file name, relative to the output directory.  The name must not
    +       * contain "." or ".." components and must be relative, not be absolute (so,
    +       * the file cannot lie outside the output directory).  "/" must be used as
    +       * the path separator, not "\".
    +       *
    +       * If the name is omitted, the content will be appended to the previous
    +       * file.  This allows the generator to break large files into small chunks,
    +       * and allows the generated text to be streamed back to protoc so that large
    +       * files need not reside completely in memory at one time.  Note that as of
    +       * this writing protoc does not optimize for this -- it will read the entire
    +       * CodeGeneratorResponse before writing files to disk.
    +       * 
    + */ + boolean hasName(); + /** + * optional string name = 1; + * + *
    +       * The file name, relative to the output directory.  The name must not
    +       * contain "." or ".." components and must be relative, not be absolute (so,
    +       * the file cannot lie outside the output directory).  "/" must be used as
    +       * the path separator, not "\".
    +       *
    +       * If the name is omitted, the content will be appended to the previous
    +       * file.  This allows the generator to break large files into small chunks,
    +       * and allows the generated text to be streamed back to protoc so that large
    +       * files need not reside completely in memory at one time.  Note that as of
    +       * this writing protoc does not optimize for this -- it will read the entire
    +       * CodeGeneratorResponse before writing files to disk.
    +       * 
    + */ + java.lang.String getName(); + /** + * optional string name = 1; + * + *
    +       * The file name, relative to the output directory.  The name must not
    +       * contain "." or ".." components and must be relative, not be absolute (so,
    +       * the file cannot lie outside the output directory).  "/" must be used as
    +       * the path separator, not "\".
    +       *
    +       * If the name is omitted, the content will be appended to the previous
    +       * file.  This allows the generator to break large files into small chunks,
    +       * and allows the generated text to be streamed back to protoc so that large
    +       * files need not reside completely in memory at one time.  Note that as of
    +       * this writing protoc does not optimize for this -- it will read the entire
    +       * CodeGeneratorResponse before writing files to disk.
    +       * 
    + */ + com.google.protobuf.ByteString + getNameBytes(); + + // optional string insertion_point = 2; + /** + * optional string insertion_point = 2; + * + *
    +       * If non-empty, indicates that the named file should already exist, and the
    +       * content here is to be inserted into that file at a defined insertion
    +       * point.  This feature allows a code generator to extend the output
    +       * produced by another code generator.  The original generator may provide
    +       * insertion points by placing special annotations in the file that look
    +       * like:
    +       *   @@protoc_insertion_point(NAME)
    +       * The annotation can have arbitrary text before and after it on the line,
    +       * which allows it to be placed in a comment.  NAME should be replaced with
    +       * an identifier naming the point -- this is what other generators will use
    +       * as the insertion_point.  Code inserted at this point will be placed
    +       * immediately above the line containing the insertion point (thus multiple
    +       * insertions to the same point will come out in the order they were added).
    +       * The double-@ is intended to make it unlikely that the generated code
    +       * could contain things that look like insertion points by accident.
    +       *
    +       * For example, the C++ code generator places the following line in the
    +       * .pb.h files that it generates:
    +       *   // @@protoc_insertion_point(namespace_scope)
    +       * This line appears within the scope of the file's package namespace, but
    +       * outside of any particular class.  Another plugin can then specify the
    +       * insertion_point "namespace_scope" to generate additional classes or
    +       * other declarations that should be placed in this scope.
    +       *
    +       * Note that if the line containing the insertion point begins with
    +       * whitespace, the same whitespace will be added to every line of the
    +       * inserted text.  This is useful for languages like Python, where
    +       * indentation matters.  In these languages, the insertion point comment
    +       * should be indented the same amount as any inserted code will need to be
    +       * in order to work correctly in that context.
    +       *
    +       * The code generator that generates the initial file and the one which
    +       * inserts into it must both run as part of a single invocation of protoc.
    +       * Code generators are executed in the order in which they appear on the
    +       * command line.
    +       *
    +       * If |insertion_point| is present, |name| must also be present.
    +       * 
    + */ + boolean hasInsertionPoint(); + /** + * optional string insertion_point = 2; + * + *
    +       * If non-empty, indicates that the named file should already exist, and the
    +       * content here is to be inserted into that file at a defined insertion
    +       * point.  This feature allows a code generator to extend the output
    +       * produced by another code generator.  The original generator may provide
    +       * insertion points by placing special annotations in the file that look
    +       * like:
    +       *   @@protoc_insertion_point(NAME)
    +       * The annotation can have arbitrary text before and after it on the line,
    +       * which allows it to be placed in a comment.  NAME should be replaced with
    +       * an identifier naming the point -- this is what other generators will use
    +       * as the insertion_point.  Code inserted at this point will be placed
    +       * immediately above the line containing the insertion point (thus multiple
    +       * insertions to the same point will come out in the order they were added).
    +       * The double-@ is intended to make it unlikely that the generated code
    +       * could contain things that look like insertion points by accident.
    +       *
    +       * For example, the C++ code generator places the following line in the
    +       * .pb.h files that it generates:
    +       *   // @@protoc_insertion_point(namespace_scope)
    +       * This line appears within the scope of the file's package namespace, but
    +       * outside of any particular class.  Another plugin can then specify the
    +       * insertion_point "namespace_scope" to generate additional classes or
    +       * other declarations that should be placed in this scope.
    +       *
    +       * Note that if the line containing the insertion point begins with
    +       * whitespace, the same whitespace will be added to every line of the
    +       * inserted text.  This is useful for languages like Python, where
    +       * indentation matters.  In these languages, the insertion point comment
    +       * should be indented the same amount as any inserted code will need to be
    +       * in order to work correctly in that context.
    +       *
    +       * The code generator that generates the initial file and the one which
    +       * inserts into it must both run as part of a single invocation of protoc.
    +       * Code generators are executed in the order in which they appear on the
    +       * command line.
    +       *
    +       * If |insertion_point| is present, |name| must also be present.
    +       * 
    + */ + java.lang.String getInsertionPoint(); + /** + * optional string insertion_point = 2; + * + *
    +       * If non-empty, indicates that the named file should already exist, and the
    +       * content here is to be inserted into that file at a defined insertion
    +       * point.  This feature allows a code generator to extend the output
    +       * produced by another code generator.  The original generator may provide
    +       * insertion points by placing special annotations in the file that look
    +       * like:
    +       *   @@protoc_insertion_point(NAME)
    +       * The annotation can have arbitrary text before and after it on the line,
    +       * which allows it to be placed in a comment.  NAME should be replaced with
    +       * an identifier naming the point -- this is what other generators will use
    +       * as the insertion_point.  Code inserted at this point will be placed
    +       * immediately above the line containing the insertion point (thus multiple
    +       * insertions to the same point will come out in the order they were added).
    +       * The double-@ is intended to make it unlikely that the generated code
    +       * could contain things that look like insertion points by accident.
    +       *
    +       * For example, the C++ code generator places the following line in the
    +       * .pb.h files that it generates:
    +       *   // @@protoc_insertion_point(namespace_scope)
    +       * This line appears within the scope of the file's package namespace, but
    +       * outside of any particular class.  Another plugin can then specify the
    +       * insertion_point "namespace_scope" to generate additional classes or
    +       * other declarations that should be placed in this scope.
    +       *
    +       * Note that if the line containing the insertion point begins with
    +       * whitespace, the same whitespace will be added to every line of the
    +       * inserted text.  This is useful for languages like Python, where
    +       * indentation matters.  In these languages, the insertion point comment
    +       * should be indented the same amount as any inserted code will need to be
    +       * in order to work correctly in that context.
    +       *
    +       * The code generator that generates the initial file and the one which
    +       * inserts into it must both run as part of a single invocation of protoc.
    +       * Code generators are executed in the order in which they appear on the
    +       * command line.
    +       *
    +       * If |insertion_point| is present, |name| must also be present.
    +       * 
    + */ + com.google.protobuf.ByteString + getInsertionPointBytes(); + + // optional string content = 15; + /** + * optional string content = 15; + * + *
    +       * The file contents.
    +       * 
    + */ + boolean hasContent(); + /** + * optional string content = 15; + * + *
    +       * The file contents.
    +       * 
    + */ + java.lang.String getContent(); + /** + * optional string content = 15; + * + *
    +       * The file contents.
    +       * 
    + */ + com.google.protobuf.ByteString + getContentBytes(); + } + /** + * Protobuf type {@code google.protobuf.compiler.CodeGeneratorResponse.File} + * + *
    +     * Represents a single generated file.
    +     * 
    + */ + public static final class File extends + com.google.protobuf.GeneratedMessage + implements FileOrBuilder { + // Use File.newBuilder() to construct. + private File(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private File(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final File defaultInstance; + public static File getDefaultInstance() { + return defaultInstance; + } + + public File getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private File( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + name_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + insertionPoint_ = input.readBytes(); + break; + } + case 122: { + bitField0_ |= 0x00000004; + content_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorResponse_File_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorResponse_File_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.class, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public File parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new File(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional string name = 1; + public static final int NAME_FIELD_NUMBER = 1; + private java.lang.Object name_; + /** + * optional string name = 1; + * + *
    +       * The file name, relative to the output directory.  The name must not
    +       * contain "." or ".." components and must be relative, not be absolute (so,
    +       * the file cannot lie outside the output directory).  "/" must be used as
    +       * the path separator, not "\".
    +       *
    +       * If the name is omitted, the content will be appended to the previous
    +       * file.  This allows the generator to break large files into small chunks,
    +       * and allows the generated text to be streamed back to protoc so that large
    +       * files need not reside completely in memory at one time.  Note that as of
    +       * this writing protoc does not optimize for this -- it will read the entire
    +       * CodeGeneratorResponse before writing files to disk.
    +       * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string name = 1; + * + *
    +       * The file name, relative to the output directory.  The name must not
    +       * contain "." or ".." components and must be relative, not be absolute (so,
    +       * the file cannot lie outside the output directory).  "/" must be used as
    +       * the path separator, not "\".
    +       *
    +       * If the name is omitted, the content will be appended to the previous
    +       * file.  This allows the generator to break large files into small chunks,
    +       * and allows the generated text to be streamed back to protoc so that large
    +       * files need not reside completely in memory at one time.  Note that as of
    +       * this writing protoc does not optimize for this -- it will read the entire
    +       * CodeGeneratorResponse before writing files to disk.
    +       * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * optional string name = 1; + * + *
    +       * The file name, relative to the output directory.  The name must not
    +       * contain "." or ".." components and must be relative, not be absolute (so,
    +       * the file cannot lie outside the output directory).  "/" must be used as
    +       * the path separator, not "\".
    +       *
    +       * If the name is omitted, the content will be appended to the previous
    +       * file.  This allows the generator to break large files into small chunks,
    +       * and allows the generated text to be streamed back to protoc so that large
    +       * files need not reside completely in memory at one time.  Note that as of
    +       * this writing protoc does not optimize for this -- it will read the entire
    +       * CodeGeneratorResponse before writing files to disk.
    +       * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string insertion_point = 2; + public static final int INSERTION_POINT_FIELD_NUMBER = 2; + private java.lang.Object insertionPoint_; + /** + * optional string insertion_point = 2; + * + *
    +       * If non-empty, indicates that the named file should already exist, and the
    +       * content here is to be inserted into that file at a defined insertion
    +       * point.  This feature allows a code generator to extend the output
    +       * produced by another code generator.  The original generator may provide
    +       * insertion points by placing special annotations in the file that look
    +       * like:
    +       *   @@protoc_insertion_point(NAME)
    +       * The annotation can have arbitrary text before and after it on the line,
    +       * which allows it to be placed in a comment.  NAME should be replaced with
    +       * an identifier naming the point -- this is what other generators will use
    +       * as the insertion_point.  Code inserted at this point will be placed
    +       * immediately above the line containing the insertion point (thus multiple
    +       * insertions to the same point will come out in the order they were added).
    +       * The double-@ is intended to make it unlikely that the generated code
    +       * could contain things that look like insertion points by accident.
    +       *
    +       * For example, the C++ code generator places the following line in the
    +       * .pb.h files that it generates:
    +       *   // @@protoc_insertion_point(namespace_scope)
    +       * This line appears within the scope of the file's package namespace, but
    +       * outside of any particular class.  Another plugin can then specify the
    +       * insertion_point "namespace_scope" to generate additional classes or
    +       * other declarations that should be placed in this scope.
    +       *
    +       * Note that if the line containing the insertion point begins with
    +       * whitespace, the same whitespace will be added to every line of the
    +       * inserted text.  This is useful for languages like Python, where
    +       * indentation matters.  In these languages, the insertion point comment
    +       * should be indented the same amount as any inserted code will need to be
    +       * in order to work correctly in that context.
    +       *
    +       * The code generator that generates the initial file and the one which
    +       * inserts into it must both run as part of a single invocation of protoc.
    +       * Code generators are executed in the order in which they appear on the
    +       * command line.
    +       *
    +       * If |insertion_point| is present, |name| must also be present.
    +       * 
    + */ + public boolean hasInsertionPoint() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string insertion_point = 2; + * + *
    +       * If non-empty, indicates that the named file should already exist, and the
    +       * content here is to be inserted into that file at a defined insertion
    +       * point.  This feature allows a code generator to extend the output
    +       * produced by another code generator.  The original generator may provide
    +       * insertion points by placing special annotations in the file that look
    +       * like:
    +       *   @@protoc_insertion_point(NAME)
    +       * The annotation can have arbitrary text before and after it on the line,
    +       * which allows it to be placed in a comment.  NAME should be replaced with
    +       * an identifier naming the point -- this is what other generators will use
    +       * as the insertion_point.  Code inserted at this point will be placed
    +       * immediately above the line containing the insertion point (thus multiple
    +       * insertions to the same point will come out in the order they were added).
    +       * The double-@ is intended to make it unlikely that the generated code
    +       * could contain things that look like insertion points by accident.
    +       *
    +       * For example, the C++ code generator places the following line in the
    +       * .pb.h files that it generates:
    +       *   // @@protoc_insertion_point(namespace_scope)
    +       * This line appears within the scope of the file's package namespace, but
    +       * outside of any particular class.  Another plugin can then specify the
    +       * insertion_point "namespace_scope" to generate additional classes or
    +       * other declarations that should be placed in this scope.
    +       *
    +       * Note that if the line containing the insertion point begins with
    +       * whitespace, the same whitespace will be added to every line of the
    +       * inserted text.  This is useful for languages like Python, where
    +       * indentation matters.  In these languages, the insertion point comment
    +       * should be indented the same amount as any inserted code will need to be
    +       * in order to work correctly in that context.
    +       *
    +       * The code generator that generates the initial file and the one which
    +       * inserts into it must both run as part of a single invocation of protoc.
    +       * Code generators are executed in the order in which they appear on the
    +       * command line.
    +       *
    +       * If |insertion_point| is present, |name| must also be present.
    +       * 
    + */ + public java.lang.String getInsertionPoint() { + java.lang.Object ref = insertionPoint_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + insertionPoint_ = s; + } + return s; + } + } + /** + * optional string insertion_point = 2; + * + *
    +       * If non-empty, indicates that the named file should already exist, and the
    +       * content here is to be inserted into that file at a defined insertion
    +       * point.  This feature allows a code generator to extend the output
    +       * produced by another code generator.  The original generator may provide
    +       * insertion points by placing special annotations in the file that look
    +       * like:
    +       *   @@protoc_insertion_point(NAME)
    +       * The annotation can have arbitrary text before and after it on the line,
    +       * which allows it to be placed in a comment.  NAME should be replaced with
    +       * an identifier naming the point -- this is what other generators will use
    +       * as the insertion_point.  Code inserted at this point will be placed
    +       * immediately above the line containing the insertion point (thus multiple
    +       * insertions to the same point will come out in the order they were added).
    +       * The double-@ is intended to make it unlikely that the generated code
    +       * could contain things that look like insertion points by accident.
    +       *
    +       * For example, the C++ code generator places the following line in the
    +       * .pb.h files that it generates:
    +       *   // @@protoc_insertion_point(namespace_scope)
    +       * This line appears within the scope of the file's package namespace, but
    +       * outside of any particular class.  Another plugin can then specify the
    +       * insertion_point "namespace_scope" to generate additional classes or
    +       * other declarations that should be placed in this scope.
    +       *
    +       * Note that if the line containing the insertion point begins with
    +       * whitespace, the same whitespace will be added to every line of the
    +       * inserted text.  This is useful for languages like Python, where
    +       * indentation matters.  In these languages, the insertion point comment
    +       * should be indented the same amount as any inserted code will need to be
    +       * in order to work correctly in that context.
    +       *
    +       * The code generator that generates the initial file and the one which
    +       * inserts into it must both run as part of a single invocation of protoc.
    +       * Code generators are executed in the order in which they appear on the
    +       * command line.
    +       *
    +       * If |insertion_point| is present, |name| must also be present.
    +       * 
    + */ + public com.google.protobuf.ByteString + getInsertionPointBytes() { + java.lang.Object ref = insertionPoint_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + insertionPoint_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string content = 15; + public static final int CONTENT_FIELD_NUMBER = 15; + private java.lang.Object content_; + /** + * optional string content = 15; + * + *
    +       * The file contents.
    +       * 
    + */ + public boolean hasContent() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string content = 15; + * + *
    +       * The file contents.
    +       * 
    + */ + public java.lang.String getContent() { + java.lang.Object ref = content_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + content_ = s; + } + return s; + } + } + /** + * optional string content = 15; + * + *
    +       * The file contents.
    +       * 
    + */ + public com.google.protobuf.ByteString + getContentBytes() { + java.lang.Object ref = content_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + content_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + name_ = ""; + insertionPoint_ = ""; + content_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getInsertionPointBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(15, getContentBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getInsertionPointBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(15, getContentBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code google.protobuf.compiler.CodeGeneratorResponse.File} + * + *
    +       * Represents a single generated file.
    +       * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.FileOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorResponse_File_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorResponse_File_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.class, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.Builder.class); + } + + // Construct using com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + insertionPoint_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + content_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorResponse_File_descriptor; + } + + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File getDefaultInstanceForType() { + return com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.getDefaultInstance(); + } + + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File build() { + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File buildPartial() { + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File result = new com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.insertionPoint_ = insertionPoint_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.content_ = content_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File) { + return mergeFrom((com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File other) { + if (other == com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.getDefaultInstance()) return this; + if (other.hasName()) { + bitField0_ |= 0x00000001; + name_ = other.name_; + onChanged(); + } + if (other.hasInsertionPoint()) { + bitField0_ |= 0x00000002; + insertionPoint_ = other.insertionPoint_; + onChanged(); + } + if (other.hasContent()) { + bitField0_ |= 0x00000004; + content_ = other.content_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional string name = 1; + private java.lang.Object name_ = ""; + /** + * optional string name = 1; + * + *
    +         * The file name, relative to the output directory.  The name must not
    +         * contain "." or ".." components and must be relative, not be absolute (so,
    +         * the file cannot lie outside the output directory).  "/" must be used as
    +         * the path separator, not "\".
    +         *
    +         * If the name is omitted, the content will be appended to the previous
    +         * file.  This allows the generator to break large files into small chunks,
    +         * and allows the generated text to be streamed back to protoc so that large
    +         * files need not reside completely in memory at one time.  Note that as of
    +         * this writing protoc does not optimize for this -- it will read the entire
    +         * CodeGeneratorResponse before writing files to disk.
    +         * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string name = 1; + * + *
    +         * The file name, relative to the output directory.  The name must not
    +         * contain "." or ".." components and must be relative, not be absolute (so,
    +         * the file cannot lie outside the output directory).  "/" must be used as
    +         * the path separator, not "\".
    +         *
    +         * If the name is omitted, the content will be appended to the previous
    +         * file.  This allows the generator to break large files into small chunks,
    +         * and allows the generated text to be streamed back to protoc so that large
    +         * files need not reside completely in memory at one time.  Note that as of
    +         * this writing protoc does not optimize for this -- it will read the entire
    +         * CodeGeneratorResponse before writing files to disk.
    +         * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string name = 1; + * + *
    +         * The file name, relative to the output directory.  The name must not
    +         * contain "." or ".." components and must be relative, not be absolute (so,
    +         * the file cannot lie outside the output directory).  "/" must be used as
    +         * the path separator, not "\".
    +         *
    +         * If the name is omitted, the content will be appended to the previous
    +         * file.  This allows the generator to break large files into small chunks,
    +         * and allows the generated text to be streamed back to protoc so that large
    +         * files need not reside completely in memory at one time.  Note that as of
    +         * this writing protoc does not optimize for this -- it will read the entire
    +         * CodeGeneratorResponse before writing files to disk.
    +         * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string name = 1; + * + *
    +         * The file name, relative to the output directory.  The name must not
    +         * contain "." or ".." components and must be relative, not be absolute (so,
    +         * the file cannot lie outside the output directory).  "/" must be used as
    +         * the path separator, not "\".
    +         *
    +         * If the name is omitted, the content will be appended to the previous
    +         * file.  This allows the generator to break large files into small chunks,
    +         * and allows the generated text to be streamed back to protoc so that large
    +         * files need not reside completely in memory at one time.  Note that as of
    +         * this writing protoc does not optimize for this -- it will read the entire
    +         * CodeGeneratorResponse before writing files to disk.
    +         * 
    + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + /** + * optional string name = 1; + * + *
    +         * The file name, relative to the output directory.  The name must not
    +         * contain "." or ".." components and must be relative, not be absolute (so,
    +         * the file cannot lie outside the output directory).  "/" must be used as
    +         * the path separator, not "\".
    +         *
    +         * If the name is omitted, the content will be appended to the previous
    +         * file.  This allows the generator to break large files into small chunks,
    +         * and allows the generated text to be streamed back to protoc so that large
    +         * files need not reside completely in memory at one time.  Note that as of
    +         * this writing protoc does not optimize for this -- it will read the entire
    +         * CodeGeneratorResponse before writing files to disk.
    +         * 
    + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000001); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * optional string name = 1; + * + *
    +         * The file name, relative to the output directory.  The name must not
    +         * contain "." or ".." components and must be relative, not be absolute (so,
    +         * the file cannot lie outside the output directory).  "/" must be used as
    +         * the path separator, not "\".
    +         *
    +         * If the name is omitted, the content will be appended to the previous
    +         * file.  This allows the generator to break large files into small chunks,
    +         * and allows the generated text to be streamed back to protoc so that large
    +         * files need not reside completely in memory at one time.  Note that as of
    +         * this writing protoc does not optimize for this -- it will read the entire
    +         * CodeGeneratorResponse before writing files to disk.
    +         * 
    + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + + // optional string insertion_point = 2; + private java.lang.Object insertionPoint_ = ""; + /** + * optional string insertion_point = 2; + * + *
    +         * If non-empty, indicates that the named file should already exist, and the
    +         * content here is to be inserted into that file at a defined insertion
    +         * point.  This feature allows a code generator to extend the output
    +         * produced by another code generator.  The original generator may provide
    +         * insertion points by placing special annotations in the file that look
    +         * like:
    +         *   @@protoc_insertion_point(NAME)
    +         * The annotation can have arbitrary text before and after it on the line,
    +         * which allows it to be placed in a comment.  NAME should be replaced with
    +         * an identifier naming the point -- this is what other generators will use
    +         * as the insertion_point.  Code inserted at this point will be placed
    +         * immediately above the line containing the insertion point (thus multiple
    +         * insertions to the same point will come out in the order they were added).
    +         * The double-@ is intended to make it unlikely that the generated code
    +         * could contain things that look like insertion points by accident.
    +         *
    +         * For example, the C++ code generator places the following line in the
    +         * .pb.h files that it generates:
    +         *   // @@protoc_insertion_point(namespace_scope)
    +         * This line appears within the scope of the file's package namespace, but
    +         * outside of any particular class.  Another plugin can then specify the
    +         * insertion_point "namespace_scope" to generate additional classes or
    +         * other declarations that should be placed in this scope.
    +         *
    +         * Note that if the line containing the insertion point begins with
    +         * whitespace, the same whitespace will be added to every line of the
    +         * inserted text.  This is useful for languages like Python, where
    +         * indentation matters.  In these languages, the insertion point comment
    +         * should be indented the same amount as any inserted code will need to be
    +         * in order to work correctly in that context.
    +         *
    +         * The code generator that generates the initial file and the one which
    +         * inserts into it must both run as part of a single invocation of protoc.
    +         * Code generators are executed in the order in which they appear on the
    +         * command line.
    +         *
    +         * If |insertion_point| is present, |name| must also be present.
    +         * 
    + */ + public boolean hasInsertionPoint() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string insertion_point = 2; + * + *
    +         * If non-empty, indicates that the named file should already exist, and the
    +         * content here is to be inserted into that file at a defined insertion
    +         * point.  This feature allows a code generator to extend the output
    +         * produced by another code generator.  The original generator may provide
    +         * insertion points by placing special annotations in the file that look
    +         * like:
    +         *   @@protoc_insertion_point(NAME)
    +         * The annotation can have arbitrary text before and after it on the line,
    +         * which allows it to be placed in a comment.  NAME should be replaced with
    +         * an identifier naming the point -- this is what other generators will use
    +         * as the insertion_point.  Code inserted at this point will be placed
    +         * immediately above the line containing the insertion point (thus multiple
    +         * insertions to the same point will come out in the order they were added).
    +         * The double-@ is intended to make it unlikely that the generated code
    +         * could contain things that look like insertion points by accident.
    +         *
    +         * For example, the C++ code generator places the following line in the
    +         * .pb.h files that it generates:
    +         *   // @@protoc_insertion_point(namespace_scope)
    +         * This line appears within the scope of the file's package namespace, but
    +         * outside of any particular class.  Another plugin can then specify the
    +         * insertion_point "namespace_scope" to generate additional classes or
    +         * other declarations that should be placed in this scope.
    +         *
    +         * Note that if the line containing the insertion point begins with
    +         * whitespace, the same whitespace will be added to every line of the
    +         * inserted text.  This is useful for languages like Python, where
    +         * indentation matters.  In these languages, the insertion point comment
    +         * should be indented the same amount as any inserted code will need to be
    +         * in order to work correctly in that context.
    +         *
    +         * The code generator that generates the initial file and the one which
    +         * inserts into it must both run as part of a single invocation of protoc.
    +         * Code generators are executed in the order in which they appear on the
    +         * command line.
    +         *
    +         * If |insertion_point| is present, |name| must also be present.
    +         * 
    + */ + public java.lang.String getInsertionPoint() { + java.lang.Object ref = insertionPoint_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + insertionPoint_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string insertion_point = 2; + * + *
    +         * If non-empty, indicates that the named file should already exist, and the
    +         * content here is to be inserted into that file at a defined insertion
    +         * point.  This feature allows a code generator to extend the output
    +         * produced by another code generator.  The original generator may provide
    +         * insertion points by placing special annotations in the file that look
    +         * like:
    +         *   @@protoc_insertion_point(NAME)
    +         * The annotation can have arbitrary text before and after it on the line,
    +         * which allows it to be placed in a comment.  NAME should be replaced with
    +         * an identifier naming the point -- this is what other generators will use
    +         * as the insertion_point.  Code inserted at this point will be placed
    +         * immediately above the line containing the insertion point (thus multiple
    +         * insertions to the same point will come out in the order they were added).
    +         * The double-@ is intended to make it unlikely that the generated code
    +         * could contain things that look like insertion points by accident.
    +         *
    +         * For example, the C++ code generator places the following line in the
    +         * .pb.h files that it generates:
    +         *   // @@protoc_insertion_point(namespace_scope)
    +         * This line appears within the scope of the file's package namespace, but
    +         * outside of any particular class.  Another plugin can then specify the
    +         * insertion_point "namespace_scope" to generate additional classes or
    +         * other declarations that should be placed in this scope.
    +         *
    +         * Note that if the line containing the insertion point begins with
    +         * whitespace, the same whitespace will be added to every line of the
    +         * inserted text.  This is useful for languages like Python, where
    +         * indentation matters.  In these languages, the insertion point comment
    +         * should be indented the same amount as any inserted code will need to be
    +         * in order to work correctly in that context.
    +         *
    +         * The code generator that generates the initial file and the one which
    +         * inserts into it must both run as part of a single invocation of protoc.
    +         * Code generators are executed in the order in which they appear on the
    +         * command line.
    +         *
    +         * If |insertion_point| is present, |name| must also be present.
    +         * 
    + */ + public com.google.protobuf.ByteString + getInsertionPointBytes() { + java.lang.Object ref = insertionPoint_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + insertionPoint_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string insertion_point = 2; + * + *
    +         * If non-empty, indicates that the named file should already exist, and the
    +         * content here is to be inserted into that file at a defined insertion
    +         * point.  This feature allows a code generator to extend the output
    +         * produced by another code generator.  The original generator may provide
    +         * insertion points by placing special annotations in the file that look
    +         * like:
    +         *   @@protoc_insertion_point(NAME)
    +         * The annotation can have arbitrary text before and after it on the line,
    +         * which allows it to be placed in a comment.  NAME should be replaced with
    +         * an identifier naming the point -- this is what other generators will use
    +         * as the insertion_point.  Code inserted at this point will be placed
    +         * immediately above the line containing the insertion point (thus multiple
    +         * insertions to the same point will come out in the order they were added).
    +         * The double-@ is intended to make it unlikely that the generated code
    +         * could contain things that look like insertion points by accident.
    +         *
    +         * For example, the C++ code generator places the following line in the
    +         * .pb.h files that it generates:
    +         *   // @@protoc_insertion_point(namespace_scope)
    +         * This line appears within the scope of the file's package namespace, but
    +         * outside of any particular class.  Another plugin can then specify the
    +         * insertion_point "namespace_scope" to generate additional classes or
    +         * other declarations that should be placed in this scope.
    +         *
    +         * Note that if the line containing the insertion point begins with
    +         * whitespace, the same whitespace will be added to every line of the
    +         * inserted text.  This is useful for languages like Python, where
    +         * indentation matters.  In these languages, the insertion point comment
    +         * should be indented the same amount as any inserted code will need to be
    +         * in order to work correctly in that context.
    +         *
    +         * The code generator that generates the initial file and the one which
    +         * inserts into it must both run as part of a single invocation of protoc.
    +         * Code generators are executed in the order in which they appear on the
    +         * command line.
    +         *
    +         * If |insertion_point| is present, |name| must also be present.
    +         * 
    + */ + public Builder setInsertionPoint( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + insertionPoint_ = value; + onChanged(); + return this; + } + /** + * optional string insertion_point = 2; + * + *
    +         * If non-empty, indicates that the named file should already exist, and the
    +         * content here is to be inserted into that file at a defined insertion
    +         * point.  This feature allows a code generator to extend the output
    +         * produced by another code generator.  The original generator may provide
    +         * insertion points by placing special annotations in the file that look
    +         * like:
    +         *   @@protoc_insertion_point(NAME)
    +         * The annotation can have arbitrary text before and after it on the line,
    +         * which allows it to be placed in a comment.  NAME should be replaced with
    +         * an identifier naming the point -- this is what other generators will use
    +         * as the insertion_point.  Code inserted at this point will be placed
    +         * immediately above the line containing the insertion point (thus multiple
    +         * insertions to the same point will come out in the order they were added).
    +         * The double-@ is intended to make it unlikely that the generated code
    +         * could contain things that look like insertion points by accident.
    +         *
    +         * For example, the C++ code generator places the following line in the
    +         * .pb.h files that it generates:
    +         *   // @@protoc_insertion_point(namespace_scope)
    +         * This line appears within the scope of the file's package namespace, but
    +         * outside of any particular class.  Another plugin can then specify the
    +         * insertion_point "namespace_scope" to generate additional classes or
    +         * other declarations that should be placed in this scope.
    +         *
    +         * Note that if the line containing the insertion point begins with
    +         * whitespace, the same whitespace will be added to every line of the
    +         * inserted text.  This is useful for languages like Python, where
    +         * indentation matters.  In these languages, the insertion point comment
    +         * should be indented the same amount as any inserted code will need to be
    +         * in order to work correctly in that context.
    +         *
    +         * The code generator that generates the initial file and the one which
    +         * inserts into it must both run as part of a single invocation of protoc.
    +         * Code generators are executed in the order in which they appear on the
    +         * command line.
    +         *
    +         * If |insertion_point| is present, |name| must also be present.
    +         * 
    + */ + public Builder clearInsertionPoint() { + bitField0_ = (bitField0_ & ~0x00000002); + insertionPoint_ = getDefaultInstance().getInsertionPoint(); + onChanged(); + return this; + } + /** + * optional string insertion_point = 2; + * + *
    +         * If non-empty, indicates that the named file should already exist, and the
    +         * content here is to be inserted into that file at a defined insertion
    +         * point.  This feature allows a code generator to extend the output
    +         * produced by another code generator.  The original generator may provide
    +         * insertion points by placing special annotations in the file that look
    +         * like:
    +         *   @@protoc_insertion_point(NAME)
    +         * The annotation can have arbitrary text before and after it on the line,
    +         * which allows it to be placed in a comment.  NAME should be replaced with
    +         * an identifier naming the point -- this is what other generators will use
    +         * as the insertion_point.  Code inserted at this point will be placed
    +         * immediately above the line containing the insertion point (thus multiple
    +         * insertions to the same point will come out in the order they were added).
    +         * The double-@ is intended to make it unlikely that the generated code
    +         * could contain things that look like insertion points by accident.
    +         *
    +         * For example, the C++ code generator places the following line in the
    +         * .pb.h files that it generates:
    +         *   // @@protoc_insertion_point(namespace_scope)
    +         * This line appears within the scope of the file's package namespace, but
    +         * outside of any particular class.  Another plugin can then specify the
    +         * insertion_point "namespace_scope" to generate additional classes or
    +         * other declarations that should be placed in this scope.
    +         *
    +         * Note that if the line containing the insertion point begins with
    +         * whitespace, the same whitespace will be added to every line of the
    +         * inserted text.  This is useful for languages like Python, where
    +         * indentation matters.  In these languages, the insertion point comment
    +         * should be indented the same amount as any inserted code will need to be
    +         * in order to work correctly in that context.
    +         *
    +         * The code generator that generates the initial file and the one which
    +         * inserts into it must both run as part of a single invocation of protoc.
    +         * Code generators are executed in the order in which they appear on the
    +         * command line.
    +         *
    +         * If |insertion_point| is present, |name| must also be present.
    +         * 
    + */ + public Builder setInsertionPointBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + insertionPoint_ = value; + onChanged(); + return this; + } + + // optional string content = 15; + private java.lang.Object content_ = ""; + /** + * optional string content = 15; + * + *
    +         * The file contents.
    +         * 
    + */ + public boolean hasContent() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string content = 15; + * + *
    +         * The file contents.
    +         * 
    + */ + public java.lang.String getContent() { + java.lang.Object ref = content_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + content_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string content = 15; + * + *
    +         * The file contents.
    +         * 
    + */ + public com.google.protobuf.ByteString + getContentBytes() { + java.lang.Object ref = content_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + content_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string content = 15; + * + *
    +         * The file contents.
    +         * 
    + */ + public Builder setContent( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + content_ = value; + onChanged(); + return this; + } + /** + * optional string content = 15; + * + *
    +         * The file contents.
    +         * 
    + */ + public Builder clearContent() { + bitField0_ = (bitField0_ & ~0x00000004); + content_ = getDefaultInstance().getContent(); + onChanged(); + return this; + } + /** + * optional string content = 15; + * + *
    +         * The file contents.
    +         * 
    + */ + public Builder setContentBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + content_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:google.protobuf.compiler.CodeGeneratorResponse.File) + } + + static { + defaultInstance = new File(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) + } + + private int bitField0_; + // optional string error = 1; + public static final int ERROR_FIELD_NUMBER = 1; + private java.lang.Object error_; + /** + * optional string error = 1; + * + *
    +     * Error message.  If non-empty, code generation failed.  The plugin process
    +     * should exit with status code zero even if it reports an error in this way.
    +     *
    +     * This should be used to indicate errors in .proto files which prevent the
    +     * code generator from generating correct code.  Errors which indicate a
    +     * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +     * unparseable -- should be reported by writing a message to stderr and
    +     * exiting with a non-zero status code.
    +     * 
    + */ + public boolean hasError() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string error = 1; + * + *
    +     * Error message.  If non-empty, code generation failed.  The plugin process
    +     * should exit with status code zero even if it reports an error in this way.
    +     *
    +     * This should be used to indicate errors in .proto files which prevent the
    +     * code generator from generating correct code.  Errors which indicate a
    +     * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +     * unparseable -- should be reported by writing a message to stderr and
    +     * exiting with a non-zero status code.
    +     * 
    + */ + public java.lang.String getError() { + java.lang.Object ref = error_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + error_ = s; + } + return s; + } + } + /** + * optional string error = 1; + * + *
    +     * Error message.  If non-empty, code generation failed.  The plugin process
    +     * should exit with status code zero even if it reports an error in this way.
    +     *
    +     * This should be used to indicate errors in .proto files which prevent the
    +     * code generator from generating correct code.  Errors which indicate a
    +     * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +     * unparseable -- should be reported by writing a message to stderr and
    +     * exiting with a non-zero status code.
    +     * 
    + */ + public com.google.protobuf.ByteString + getErrorBytes() { + java.lang.Object ref = error_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + error_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + public static final int FILE_FIELD_NUMBER = 15; + private java.util.List file_; + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public java.util.List getFileList() { + return file_; + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public java.util.List + getFileOrBuilderList() { + return file_; + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public int getFileCount() { + return file_.size(); + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File getFile(int index) { + return file_.get(index); + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.FileOrBuilder getFileOrBuilder( + int index) { + return file_.get(index); + } + + private void initFields() { + error_ = ""; + file_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getErrorBytes()); + } + for (int i = 0; i < file_.size(); i++) { + output.writeMessage(15, file_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getErrorBytes()); + } + for (int i = 0; i < file_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(15, file_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code google.protobuf.compiler.CodeGeneratorResponse} + * + *
    +     * The plugin writes an encoded CodeGeneratorResponse to stdout.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.class, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.Builder.class); + } + + // Construct using com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + error_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + if (fileBuilder_ == null) { + file_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + } else { + fileBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.google.protobuf.compiler.PluginProtos.internal_static_google_protobuf_compiler_CodeGeneratorResponse_descriptor; + } + + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse getDefaultInstanceForType() { + return com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.getDefaultInstance(); + } + + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse build() { + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse buildPartial() { + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse result = new com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.error_ = error_; + if (fileBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002)) { + file_ = java.util.Collections.unmodifiableList(file_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.file_ = file_; + } else { + result.file_ = fileBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse) { + return mergeFrom((com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse other) { + if (other == com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.getDefaultInstance()) return this; + if (other.hasError()) { + bitField0_ |= 0x00000001; + error_ = other.error_; + onChanged(); + } + if (fileBuilder_ == null) { + if (!other.file_.isEmpty()) { + if (file_.isEmpty()) { + file_ = other.file_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureFileIsMutable(); + file_.addAll(other.file_); + } + onChanged(); + } + } else { + if (!other.file_.isEmpty()) { + if (fileBuilder_.isEmpty()) { + fileBuilder_.dispose(); + fileBuilder_ = null; + file_ = other.file_; + bitField0_ = (bitField0_ & ~0x00000002); + fileBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getFileFieldBuilder() : null; + } else { + fileBuilder_.addAllMessages(other.file_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional string error = 1; + private java.lang.Object error_ = ""; + /** + * optional string error = 1; + * + *
    +       * Error message.  If non-empty, code generation failed.  The plugin process
    +       * should exit with status code zero even if it reports an error in this way.
    +       *
    +       * This should be used to indicate errors in .proto files which prevent the
    +       * code generator from generating correct code.  Errors which indicate a
    +       * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +       * unparseable -- should be reported by writing a message to stderr and
    +       * exiting with a non-zero status code.
    +       * 
    + */ + public boolean hasError() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string error = 1; + * + *
    +       * Error message.  If non-empty, code generation failed.  The plugin process
    +       * should exit with status code zero even if it reports an error in this way.
    +       *
    +       * This should be used to indicate errors in .proto files which prevent the
    +       * code generator from generating correct code.  Errors which indicate a
    +       * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +       * unparseable -- should be reported by writing a message to stderr and
    +       * exiting with a non-zero status code.
    +       * 
    + */ + public java.lang.String getError() { + java.lang.Object ref = error_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + error_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string error = 1; + * + *
    +       * Error message.  If non-empty, code generation failed.  The plugin process
    +       * should exit with status code zero even if it reports an error in this way.
    +       *
    +       * This should be used to indicate errors in .proto files which prevent the
    +       * code generator from generating correct code.  Errors which indicate a
    +       * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +       * unparseable -- should be reported by writing a message to stderr and
    +       * exiting with a non-zero status code.
    +       * 
    + */ + public com.google.protobuf.ByteString + getErrorBytes() { + java.lang.Object ref = error_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + error_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string error = 1; + * + *
    +       * Error message.  If non-empty, code generation failed.  The plugin process
    +       * should exit with status code zero even if it reports an error in this way.
    +       *
    +       * This should be used to indicate errors in .proto files which prevent the
    +       * code generator from generating correct code.  Errors which indicate a
    +       * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +       * unparseable -- should be reported by writing a message to stderr and
    +       * exiting with a non-zero status code.
    +       * 
    + */ + public Builder setError( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + error_ = value; + onChanged(); + return this; + } + /** + * optional string error = 1; + * + *
    +       * Error message.  If non-empty, code generation failed.  The plugin process
    +       * should exit with status code zero even if it reports an error in this way.
    +       *
    +       * This should be used to indicate errors in .proto files which prevent the
    +       * code generator from generating correct code.  Errors which indicate a
    +       * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +       * unparseable -- should be reported by writing a message to stderr and
    +       * exiting with a non-zero status code.
    +       * 
    + */ + public Builder clearError() { + bitField0_ = (bitField0_ & ~0x00000001); + error_ = getDefaultInstance().getError(); + onChanged(); + return this; + } + /** + * optional string error = 1; + * + *
    +       * Error message.  If non-empty, code generation failed.  The plugin process
    +       * should exit with status code zero even if it reports an error in this way.
    +       *
    +       * This should be used to indicate errors in .proto files which prevent the
    +       * code generator from generating correct code.  Errors which indicate a
    +       * problem in protoc itself -- such as the input CodeGeneratorRequest being
    +       * unparseable -- should be reported by writing a message to stderr and
    +       * exiting with a non-zero status code.
    +       * 
    + */ + public Builder setErrorBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + error_ = value; + onChanged(); + return this; + } + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + private java.util.List file_ = + java.util.Collections.emptyList(); + private void ensureFileIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + file_ = new java.util.ArrayList(file_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.Builder, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.FileOrBuilder> fileBuilder_; + + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public java.util.List getFileList() { + if (fileBuilder_ == null) { + return java.util.Collections.unmodifiableList(file_); + } else { + return fileBuilder_.getMessageList(); + } + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public int getFileCount() { + if (fileBuilder_ == null) { + return file_.size(); + } else { + return fileBuilder_.getCount(); + } + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File getFile(int index) { + if (fileBuilder_ == null) { + return file_.get(index); + } else { + return fileBuilder_.getMessage(index); + } + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public Builder setFile( + int index, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File value) { + if (fileBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileIsMutable(); + file_.set(index, value); + onChanged(); + } else { + fileBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public Builder setFile( + int index, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.Builder builderForValue) { + if (fileBuilder_ == null) { + ensureFileIsMutable(); + file_.set(index, builderForValue.build()); + onChanged(); + } else { + fileBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public Builder addFile(com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File value) { + if (fileBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileIsMutable(); + file_.add(value); + onChanged(); + } else { + fileBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public Builder addFile( + int index, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File value) { + if (fileBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileIsMutable(); + file_.add(index, value); + onChanged(); + } else { + fileBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public Builder addFile( + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.Builder builderForValue) { + if (fileBuilder_ == null) { + ensureFileIsMutable(); + file_.add(builderForValue.build()); + onChanged(); + } else { + fileBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public Builder addFile( + int index, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.Builder builderForValue) { + if (fileBuilder_ == null) { + ensureFileIsMutable(); + file_.add(index, builderForValue.build()); + onChanged(); + } else { + fileBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public Builder addAllFile( + java.lang.Iterable values) { + if (fileBuilder_ == null) { + ensureFileIsMutable(); + super.addAll(values, file_); + onChanged(); + } else { + fileBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public Builder clearFile() { + if (fileBuilder_ == null) { + file_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + fileBuilder_.clear(); + } + return this; + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public Builder removeFile(int index) { + if (fileBuilder_ == null) { + ensureFileIsMutable(); + file_.remove(index); + onChanged(); + } else { + fileBuilder_.remove(index); + } + return this; + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.Builder getFileBuilder( + int index) { + return getFileFieldBuilder().getBuilder(index); + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.FileOrBuilder getFileOrBuilder( + int index) { + if (fileBuilder_ == null) { + return file_.get(index); } else { + return fileBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public java.util.List + getFileOrBuilderList() { + if (fileBuilder_ != null) { + return fileBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(file_); + } + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.Builder addFileBuilder() { + return getFileFieldBuilder().addBuilder( + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.getDefaultInstance()); + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.Builder addFileBuilder( + int index) { + return getFileFieldBuilder().addBuilder( + index, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.getDefaultInstance()); + } + /** + * repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + */ + public java.util.List + getFileBuilderList() { + return getFileFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.Builder, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.FileOrBuilder> + getFileFieldBuilder() { + if (fileBuilder_ == null) { + fileBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File.Builder, com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.FileOrBuilder>( + file_, + ((bitField0_ & 0x00000002) == 0x00000002), + getParentForChildren(), + isClean()); + file_ = null; + } + return fileBuilder_; + } + + // @@protoc_insertion_point(builder_scope:google.protobuf.compiler.CodeGeneratorResponse) + } + + static { + defaultInstance = new CodeGeneratorResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse) + } + + private static com.google.protobuf.Descriptors.Descriptor + internal_static_google_protobuf_compiler_CodeGeneratorRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_google_protobuf_compiler_CodeGeneratorRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_google_protobuf_compiler_CodeGeneratorResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_google_protobuf_compiler_CodeGeneratorResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_google_protobuf_compiler_CodeGeneratorResponse_File_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_google_protobuf_compiler_CodeGeneratorResponse_File_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\014plugin.proto\022\030google.protobuf.compiler" + + "\032 google/protobuf/descriptor.proto\"}\n\024Co" + + "deGeneratorRequest\022\030\n\020file_to_generate\030\001" + + " \003(\t\022\021\n\tparameter\030\002 \001(\t\0228\n\nproto_file\030\017 " + + "\003(\0132$.google.protobuf.FileDescriptorProt" + + "o\"\252\001\n\025CodeGeneratorResponse\022\r\n\005error\030\001 \001" + + "(\t\022B\n\004file\030\017 \003(\01324.google.protobuf.compi" + + "ler.CodeGeneratorResponse.File\032>\n\004File\022\014" + + "\n\004name\030\001 \001(\t\022\027\n\017insertion_point\030\002 \001(\t\022\017\n" + + "\007content\030\017 \001(\tB,\n\034com.google.protobuf.co", + "mpilerB\014PluginProtos" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_google_protobuf_compiler_CodeGeneratorRequest_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_google_protobuf_compiler_CodeGeneratorRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_google_protobuf_compiler_CodeGeneratorRequest_descriptor, + new java.lang.String[] { "FileToGenerate", "Parameter", "ProtoFile", }); + internal_static_google_protobuf_compiler_CodeGeneratorResponse_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_google_protobuf_compiler_CodeGeneratorResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_google_protobuf_compiler_CodeGeneratorResponse_descriptor, + new java.lang.String[] { "Error", "File", }); + internal_static_google_protobuf_compiler_CodeGeneratorResponse_File_descriptor = + internal_static_google_protobuf_compiler_CodeGeneratorResponse_descriptor.getNestedTypes().get(0); + internal_static_google_protobuf_compiler_CodeGeneratorResponse_File_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_google_protobuf_compiler_CodeGeneratorResponse_File_descriptor, + new java.lang.String[] { "Name", "InsertionPoint", "Content", }); + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + com.google.protobuf.DescriptorProtos.getDescriptor(), + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/java/pbrpcgen/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PBRPC.java b/java/pbrpcgen/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PBRPC.java new file mode 100644 index 0000000..eb2bc1f --- /dev/null +++ b/java/pbrpcgen/src/org/xtreemfs/foundation/pbrpc/generatedinterfaces/PBRPC.java @@ -0,0 +1,98 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: PBRPC.proto + +package org.xtreemfs.foundation.pbrpc.generatedinterfaces; + +public final class PBRPC { + private PBRPC() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.dataIn); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.dataOut); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.interfaceId); + } + public static final int PROC_ID_FIELD_NUMBER = 50001; + /** + * extend .google.protobuf.MethodOptions { ... } + */ + public static final + com.google.protobuf.GeneratedMessage.GeneratedExtension< + com.google.protobuf.DescriptorProtos.MethodOptions, + java.lang.Integer> procId = com.google.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + java.lang.Integer.class, + null); + public static final int DATA_IN_FIELD_NUMBER = 50004; + /** + * extend .google.protobuf.MethodOptions { ... } + */ + public static final + com.google.protobuf.GeneratedMessage.GeneratedExtension< + com.google.protobuf.DescriptorProtos.MethodOptions, + java.lang.Boolean> dataIn = com.google.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + java.lang.Boolean.class, + null); + public static final int DATA_OUT_FIELD_NUMBER = 50003; + /** + * extend .google.protobuf.MethodOptions { ... } + */ + public static final + com.google.protobuf.GeneratedMessage.GeneratedExtension< + com.google.protobuf.DescriptorProtos.MethodOptions, + java.lang.Boolean> dataOut = com.google.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + java.lang.Boolean.class, + null); + public static final int INTERFACE_ID_FIELD_NUMBER = 50002; + /** + * extend .google.protobuf.ServiceOptions { ... } + */ + public static final + com.google.protobuf.GeneratedMessage.GeneratedExtension< + com.google.protobuf.DescriptorProtos.ServiceOptions, + java.lang.Integer> interfaceId = com.google.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + java.lang.Integer.class, + null); + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\013PBRPC.proto\022\016xtreemfs.pbrpc\032 google/pr" + + "otobuf/descriptor.proto:1\n\007proc_id\022\036.goo" + + "gle.protobuf.MethodOptions\030\321\206\003 \001(\007:1\n\007da" + + "ta_in\022\036.google.protobuf.MethodOptions\030\324\206" + + "\003 \001(\010:2\n\010data_out\022\036.google.protobuf.Meth" + + "odOptions\030\323\206\003 \001(\010:7\n\014interface_id\022\037.goog" + + "le.protobuf.ServiceOptions\030\322\206\003 \001(\007B3\n1or" + + "g.xtreemfs.foundation.pbrpc.generatedint" + + "erfaces" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + procId.internalInit(descriptor.getExtensions().get(0)); + dataIn.internalInit(descriptor.getExtensions().get(1)); + dataOut.internalInit(descriptor.getExtensions().get(2)); + interfaceId.internalInit(descriptor.getExtensions().get(3)); + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + com.google.protobuf.DescriptorProtos.getDescriptor(), + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/java/pbrpcgen/src/org/xtreemfs/pbrpcgen/RPCCPPSourceGenerator.java b/java/pbrpcgen/src/org/xtreemfs/pbrpcgen/RPCCPPSourceGenerator.java new file mode 100644 index 0000000..45eaccf --- /dev/null +++ b/java/pbrpcgen/src/org/xtreemfs/pbrpcgen/RPCCPPSourceGenerator.java @@ -0,0 +1,586 @@ +package org.xtreemfs.pbrpcgen; + +import com.google.protobuf.DescriptorProtos.DescriptorProto; +import com.google.protobuf.DescriptorProtos.EnumDescriptorProto; +import com.google.protobuf.DescriptorProtos.FieldDescriptorProto; +import com.google.protobuf.DescriptorProtos.FieldDescriptorProto.Type; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.google.protobuf.DescriptorProtos.FileDescriptorProto; +import com.google.protobuf.DescriptorProtos.MethodDescriptorProto; +import com.google.protobuf.DescriptorProtos.ServiceDescriptorProto; +import com.google.protobuf.Descriptors; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.ExtensionRegistry; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC; + +public class RPCCPPSourceGenerator { + + private static final Map ttt; + + private static final Map tttr; + + static { + ttt = new HashMap(); + ttt.put(Type.TYPE_BOOL,"boolean"); + ttt.put(Type.TYPE_BYTES,"ByteString"); + ttt.put(Type.TYPE_DOUBLE,"double"); + ttt.put(Type.TYPE_FIXED32,"uint32_t"); + ttt.put(Type.TYPE_FIXED64,"uint64_t"); + ttt.put(Type.TYPE_FLOAT,"float"); + ttt.put(Type.TYPE_STRING,"std::string"); + + tttr = new HashMap(); + tttr.put(Type.TYPE_BOOL,"List"); + tttr.put(Type.TYPE_BYTES,"List"); + tttr.put(Type.TYPE_DOUBLE,"List"); + tttr.put(Type.TYPE_FIXED32,"List"); + tttr.put(Type.TYPE_FIXED64,"List"); + tttr.put(Type.TYPE_FLOAT,"List"); + tttr.put(Type.TYPE_STRING,"List"); + } + + //public static final String PACKAGE = "org.xtreemfs.foundation.pbrpc.generated"; + + public static void main(String[] args) throws Exception { + final String ONE_INDENT = " "; + + ExtensionRegistry er = ExtensionRegistry.newInstance(); + PBRPC.registerAllExtensions(er); + CodeGeneratorRequest rq = CodeGeneratorRequest.parseFrom(System.in,er); + CodeGeneratorResponse.Builder responseBuilder = CodeGeneratorResponse.newBuilder(); + + Map typeDefs = new HashMap(); + + + Map map = rq.getAllFields(); + // System.err.println(map); + + for (Entry files : map.entrySet()) { + + if (files.getKey().getName().equals("proto_file")) { + + for (FileDescriptorProto proto : (List) files.getValue()) { + java.io.File filchen = new java.io.File(proto.getName()); + System.err.println("proto name: "+proto.getName()); + final String fileName = proto.getName().replace(".proto", ".pb.h"); + System.err.println("include: "+fileName); + String pkgName = proto.getPackage(); + if (pkgName.length() > 0) + pkgName = pkgName+"."; + for (DescriptorProto msg : proto.getMessageTypeList()) { + TypeDef def = new TypeDef(); + def.fullName = proto.getPackage().replace(".", "::")+"::"+msg.getName(); + def.message = msg; + def.fileName = fileName; + typeDefs.put("."+pkgName+msg.getName(),def); + } + for (EnumDescriptorProto msg : proto.getEnumTypeList()) { + TypeDef def = new TypeDef(); + def.fullName = proto.getPackage().replace(".", "::")+"::"+msg.getName(); + def.message = null; + def.fileName = fileName; + typeDefs.put("."+pkgName+msg.getName(),def); + } + } + } + } + System.err.println("typedefs: "+typeDefs.keySet()); + + Set includes = new HashSet(); + + for (Entry files : map.entrySet()) { + + if (files.getKey().getName().equals("proto_file")) { + // This generator is executed multiple times with different sets + // of files. Therefore it shall only write the + // "get_request_message" file if files like DIR.proto, MRC.proto + // or OSD.proto are parsed. + boolean writeFileGetRequestMessage = false; + + String fileNameGetRequestMessageH = "xtreemfs/get_request_message.h"; + String fileNameGetRequestMessageCC = "xtreemfs/get_request_message.cc"; + String includeGuardGetRequestMessage = "CPP_GENERATED_XTREEMFS_GET_REQUEST_MESSAGE_H_"; + StringBuilder codeBuilderGetRequestMessageH = new StringBuilder(); + StringBuilder codeBuilderGetRequestMessageCC = new StringBuilder(); + codeBuilderGetRequestMessageH.append("//automatically generated at "+new Date()+"\n"); + codeBuilderGetRequestMessageH.append("//(c) "+((new Date()).getYear()+1900)+". See LICENSE file for details.\n\n"); + codeBuilderGetRequestMessageCC.append("//automatically generated at "+new Date()+"\n"); + codeBuilderGetRequestMessageCC.append("//(c) "+((new Date()).getYear()+1900)+". See LICENSE file for details.\n\n"); + + codeBuilderGetRequestMessageH.append("#ifndef "+ includeGuardGetRequestMessage +"\n"); + codeBuilderGetRequestMessageH.append("#define "+ includeGuardGetRequestMessage +"\n\n"); + codeBuilderGetRequestMessageH.append("#include \n"); + codeBuilderGetRequestMessageH.append("\n"); + codeBuilderGetRequestMessageH.append("namespace google {\n"); + codeBuilderGetRequestMessageH.append("namespace protobuf {\n"); + codeBuilderGetRequestMessageH.append("class Message;\n"); + codeBuilderGetRequestMessageH.append("} // namespace protobuf\n"); + codeBuilderGetRequestMessageH.append("} // namespace google\n"); + codeBuilderGetRequestMessageH.append("\n"); + + codeBuilderGetRequestMessageCC.append("#include \"" + fileNameGetRequestMessageH + "\"\n\n"); + codeBuilderGetRequestMessageCC.append("@@@INCLUDE@@@\n"); + + boolean initializedGetRequestMessage = false; + String[] namespaceTokensGetRequestMessage = null; + + for (FileDescriptorProto proto : (List) files.getValue()) { + + final String cppPackage = proto.getPackage(); + System.err.println("package: "+cppPackage); + //final String filePrefix = cppPackage.replace(".", "/"); + java.io.File filchen = new java.io.File(proto.getName()); + final String msgName = filchen.getName().replace(".proto", ""); + System.err.println("proto: "+proto.getName()); + + boolean addThisFileToGetRequestMessage = false; + if (filchen.getName().equals("DIR.proto") || filchen.getName().equals("MRC.proto") || filchen.getName().equals("OSD.proto")) { + writeFileGetRequestMessage = true; + addThisFileToGetRequestMessage = true; + } + + + //printMessage(proto.getMessageTypeList()); + final String[] namespaceTokens = cppPackage.split("\\."); + + if (writeFileGetRequestMessage && !initializedGetRequestMessage) { + namespaceTokensGetRequestMessage = namespaceTokens.clone(); + for (int i = 0; i < namespaceTokens.length; i++) { + codeBuilderGetRequestMessageH.append("namespace " + namespaceTokens[i] + " {\n"); + codeBuilderGetRequestMessageCC.append("namespace " + namespaceTokens[i] + " {\n"); + } + codeBuilderGetRequestMessageH.append("\n"); + codeBuilderGetRequestMessageH.append( + "google::protobuf::Message* GetMessageForProcID(uint32_t interface_id,\n"); + codeBuilderGetRequestMessageH.append( + " uint32_t proc_id);\n\n"); + + codeBuilderGetRequestMessageCC.append("\n"); + codeBuilderGetRequestMessageCC.append( + "google::protobuf::Message* GetMessageForProcID(uint32_t interface_id,\n"); + codeBuilderGetRequestMessageCC.append( + " uint32_t proc_id) {\n"); + codeBuilderGetRequestMessageCC.append( + " switch (interface_id) {\n"); + initializedGetRequestMessage = true; + } + + for (ServiceDescriptorProto srv : proto.getServiceList()) { + int interfaceId = srv.getOptions().getExtension(PBRPC.interfaceId); + + if (addThisFileToGetRequestMessage) { + codeBuilderGetRequestMessageCC.append( +"// Generated from " + filchen.getName() + "\n"); + codeBuilderGetRequestMessageCC.append( +" case " + interfaceId + ": {\n"); + codeBuilderGetRequestMessageCC.append( +" switch (proc_id) {\n"); + } + + + // proto.getName() returns the file name of the .proto file + // e.g. "xtreemfs/DIR.proto" + // Example: "xtreemfs/DIR.proto" -> "DIRServiceClient" + String className = (new java.io.File(proto.getName())).getName().replace(".proto", "ServiceClient"); + // Example: "xtreemfs/DIR.proto" -> "xtreemfs/DIRServiceClient.h" + String classFileName = proto.getName().replace(".proto", "ServiceClient.h"); + String classNameConst = (new java.io.File(proto.getName())).getName().replace(".proto", "ServiceConstants"); + String classFileNameConst = proto.getName().replace(".proto", "ServiceConstants.h"); + + + StringBuilder codeBuilder = new StringBuilder(); + StringBuilder codeBuilderConst = new StringBuilder(); + + codeBuilderConst.append("//automatically generated from "+filchen.getName()+" at "+new Date()+"\n"); + codeBuilderConst.append("//(c) "+((new Date()).getYear()+1900)+". See LICENSE file for details.\n\n"); + codeBuilderConst.append("#ifndef "+classNameConst.toUpperCase()+"_H_\n"); + codeBuilderConst.append("#define "+classNameConst.toUpperCase()+"_H_\n"); + codeBuilderConst.append("#include \n\n"); + for (int i = 0; i < namespaceTokens.length; i++) { + codeBuilderConst.append("namespace " + namespaceTokens[i] + " {\n"); + } + codeBuilderConst.append("\n"); + codeBuilderConst.append("const uint32_t INTERFACE_ID_" + (new java.io.File(proto.getName())).getName().replace(".proto", "").toUpperCase() + " = " + interfaceId + ";\n"); + + //imports + codeBuilder.append("//automatically generated from "+filchen.getName()+" at "+new Date()+"\n"); + codeBuilder.append("//(c) "+((new Date()).getYear()+1900)+". See LICENSE file for details.\n\n"); + + codeBuilder.append("#ifndef "+className.toUpperCase()+"_H\n"); + codeBuilder.append("#define "+className.toUpperCase()+"_H\n\n"); + + codeBuilder.append("#include \n"); + codeBuilder.append("#include \"pbrpc/RPC.pb.h\"\n"); + codeBuilder.append("#include \"rpc/client.h\"\n"); + codeBuilder.append("#include \"rpc/sync_callback.h\"\n"); + codeBuilder.append("#include \"rpc/callback_interface.h\"\n"); + codeBuilder.append("@@@INCLUDE@@@\n"); + + codeBuilder.append("\n"); + + String indent = ""; + for (int i = 0; i < namespaceTokens.length; i++) { + codeBuilder.append("namespace "+namespaceTokens[i]+" {\n"); + indent = indent + ONE_INDENT; + } + + codeBuilder.append(indent+"using ::xtreemfs::rpc::Client;\n"); + codeBuilder.append(indent+"using ::xtreemfs::rpc::CallbackInterface;\n"); + codeBuilder.append(indent+"using ::xtreemfs::rpc::SyncCallback;\n\n"); + + codeBuilder.append(indent+"class " + className + " {\n\n"); + codeBuilder.append(indent+"public:\n"); + + //methods + + codeBuilder.append(indent+ONE_INDENT+className+"(Client* client) : client_(client) {\n"); + codeBuilder.append(indent+ONE_INDENT+"}\n\n"); + + codeBuilder.append(indent+ONE_INDENT+"virtual ~"+className+"() {\n"); + codeBuilder.append(indent+ONE_INDENT+"}\n\n"); + + for (MethodDescriptorProto method: srv.getMethodList()) { + + System.err.println("input type: "+method.getInputType()); + final String inputType = typeDefs.get(method.getInputType()).fullName;//msgName+method.getInputType(); + + final String returnType = typeDefs.get(method.getOutputType()).fullName;//msgName+method.getOutputType(); + + includes.add(typeDefs.get(method.getInputType()).fileName); + includes.add(typeDefs.get(method.getOutputType()).fileName); + + final int procId = method.getOptions().getExtension(PBRPC.procId); + codeBuilderConst.append("const uint32_t PROC_ID_"+method.getName().toUpperCase()+" = " + procId + ";\n"); + + final boolean data_in = method.getOptions().hasExtension(PBRPC.dataIn) ? method.getOptions().getExtension(PBRPC.dataIn) : false; + final String dataValue = data_in ? "data" : "null"; + + String inputTypeBuilder = "new " + inputType + "()"; + if (inputTypeBuilder.contains("emptyResponse")) { + inputTypeBuilder = "NULL"; + } + String returnTypeBuilder = "new "+returnType+"()"; + if (returnType.contains("emptyResponse")) + returnTypeBuilder = "NULL"; + + if (addThisFileToGetRequestMessage) { + codeBuilderGetRequestMessageCC.append( +" case " + procId + ": {\n"); + codeBuilderGetRequestMessageCC.append( +" return " + inputTypeBuilder + ";\n"); + codeBuilderGetRequestMessageCC.append( +" break;\n"); + codeBuilderGetRequestMessageCC.append( +" }\n"); + } + + codeBuilder.append(indent+ONE_INDENT+"void "+method.getName()+"(const std::string &address,\n"); + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+"const xtreemfs::pbrpc::Auth& auth,\n"); + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+"const xtreemfs::pbrpc::UserCredentials &creds,"); + if (!inputType.contains("emptyRequest")) + codeBuilder.append("\n"+indent+ONE_INDENT+ONE_INDENT+"const "+inputType+"* request,"); + if (data_in) + codeBuilder.append("const char* data, uint32_t data_length,"); + codeBuilder.append("\n"+indent+ONE_INDENT+ONE_INDENT+"CallbackInterface<"+returnType+"> *callback, void *context = NULL) {\n"); + + + if (!data_in) + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+"const char* data = NULL; uint32_t data_length = 0;\n"); + if (inputType.contains("emptyRequest")) + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+inputType+"* request = NULL;\n"); + + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+"client_->sendRequest(address, "+interfaceId+", "+procId+",\n"); + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+ONE_INDENT+" creds, auth, request, data, data_length, "+returnTypeBuilder+",\n"); + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+ONE_INDENT+" context, callback);\n"); + codeBuilder.append(indent+ONE_INDENT+"}\n\n"); + + + codeBuilder.append(indent+ONE_INDENT+"SyncCallback<"+returnType+">* "+method.getName()+"_sync(const std::string &address,\n"); + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+"const xtreemfs::pbrpc::Auth& auth,\n"); + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+"const xtreemfs::pbrpc::UserCredentials &creds"); + if (!inputType.contains("emptyRequest")) + codeBuilder.append("\n"+indent+ONE_INDENT+ONE_INDENT+", const "+inputType+"* request"); + if (data_in) + codeBuilder.append(", const char* data, uint32_t data_length"); + codeBuilder.append(") {\n"); + + + if (!data_in) + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+"const char* data = NULL; uint32_t data_length = 0;\n"); + if (inputType.contains("emptyRequest")) + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+inputType+"* request = NULL;\n"); + + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+"SyncCallback<"+returnType+">* sync_cb = new SyncCallback<"+returnType+">();\n"); + + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+"client_->sendRequest(address, "+interfaceId+", "+procId+",\n"); + + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+ONE_INDENT+" creds, auth, request, data, data_length, "+returnTypeBuilder+",\n"); + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+ONE_INDENT+" NULL, sync_cb);\n"); + codeBuilder.append(indent+ONE_INDENT+ONE_INDENT+"return sync_cb;\n"); + codeBuilder.append(indent+ONE_INDENT+"}\n\n"); + + /*codeBuilder.append(" public RPCResponse<"+returnType+"> " + method.getName() + "("); + codeBuilder.append("InetSocketAddress server, Auth authHeader, UserCredentials userCreds, "+inputType+" input"); + if (data_in) + codeBuilder.append(", ReusableBuffer data"); + codeBuilder.append(") throws IOException {\n"); + codeBuilder.append(" if (server == null) server = defaultServer;\n"); + codeBuilder.append(" if (server == null) throw new IllegalArgumentException(\"defaultServer must be set in constructor if you want to pass null as server in calls\");\n"); + codeBuilder.append(" RPCResponse<"+returnType+"> response = new RPCResponse<"+returnType+">("+returnType+".getDefaultInstance());\n"); + codeBuilder.append(" client.sendRequest(server, authHeader, userCreds, "+interfaceId+", "+procId+", input, "+dataValue+", response, false);\n"); + codeBuilder.append(" return response;\n"); + codeBuilder.append(" }\n\n"); + + String[] unrolled = unrollInputMessage(proto, method.getInputType(), typeDefs); + codeBuilder.append(" public RPCResponse<"+returnType+"> " + method.getName() + "("); + codeBuilder.append("InetSocketAddress server, Auth authHeader, UserCredentials userCreds"); + if (unrolled[0].length() > 0) { + codeBuilder.append(", "); + codeBuilder.append(unrolled[0]); + } + if (data_in) + codeBuilder.append(", ReusableBuffer data"); + codeBuilder.append(") throws IOException {\n"); + codeBuilder.append(" "+unrolled[1]+"\n"); + codeBuilder.append(" return "); + codeBuilder.append(method.getName()); + codeBuilder.append("(server, authHeader, userCreds, msg"); + if (data_in) + codeBuilder.append(", data"); + codeBuilder.append(");\n"); + codeBuilder.append(" }\n\n"); + * + */ + } + + + // codeBuilder.append(" public static void " + + // msg.getName() + "() {\n"); + // + // for (FieldDescriptorProto field : msg.getFieldList()) + // { + // + // String type = field.getTypeName(); + // if(type.startsWith(".")) + // type = type.substring(1); + // + // field.getType(); + // + // codeBuilder.append(" public " + type + " " + + // field.getName() + ";\n"); + // } + // + + codeBuilder.append(indent+"private:\n"); + codeBuilder.append(indent+ONE_INDENT+"Client* client_;\n"); + + codeBuilder.append(indent+"};\n"); + + for (int i = 0; i < namespaceTokens.length; i++) { + indent = indent.substring(ONE_INDENT.length()); + codeBuilder.append(indent); + codeBuilder.append("}\n"); + } + codeBuilder.append("#endif //"+className.toUpperCase()+"_H\n"); + + codeBuilderConst.append("\n"); + for (int i = Math.max(0, namespaceTokens.length - 1); i >= 0; i--) { + codeBuilderConst.append("} // namespace " + namespaceTokens[i] + "\n"); + } + codeBuilderConst.append("\n"); + codeBuilderConst.append("#endif // "+className.toUpperCase()+"_H_\n"); + + String file = codeBuilder.toString(); + + String extraIncludes = ""; + for (String incl : includes) { + extraIncludes += "#include \""+incl+"\"\n"; + } + file = file.replace("@@@INCLUDE@@@", extraIncludes); + + //filePrefix+"/"+className + ".cpp" + File f = File.newBuilder().setName(classFileName).setContent( + file).build(); + responseBuilder.addFile(f); + + f = File.newBuilder().setName(classFileNameConst).setContent( + codeBuilderConst.toString()).build(); + responseBuilder.addFile(f); + + if (addThisFileToGetRequestMessage) { + codeBuilderGetRequestMessageCC.append( +" default: {\n"); + codeBuilderGetRequestMessageCC.append( +" return NULL;\n"); + codeBuilderGetRequestMessageCC.append( +" }\n"); + codeBuilderGetRequestMessageCC.append( +" }\n"); + codeBuilderGetRequestMessageCC.append( +" break;\n"); + codeBuilderGetRequestMessageCC.append( +" }\n"); + } + + } + + } + + if (writeFileGetRequestMessage) { + codeBuilderGetRequestMessageCC.append( +" default: {\n"); + codeBuilderGetRequestMessageCC.append( +" return NULL;\n"); + codeBuilderGetRequestMessageCC.append( +" }\n"); + codeBuilderGetRequestMessageCC.append( +" }\n"); + codeBuilderGetRequestMessageCC.append( +"}\n"); + codeBuilderGetRequestMessageCC.append("\n"); + for (int i = Math.max(0, namespaceTokensGetRequestMessage.length - 1); i >= 0; i--) { + codeBuilderGetRequestMessageH.append("} // namespace " + namespaceTokensGetRequestMessage[i] + "\n"); + codeBuilderGetRequestMessageCC.append("} // namespace " + namespaceTokensGetRequestMessage[i] + "\n"); + } + codeBuilderGetRequestMessageH.append("\n"); + codeBuilderGetRequestMessageH.append("#endif // " + includeGuardGetRequestMessage + "\n"); + + String extraIncludes = ""; + for (String incl : includes) { + extraIncludes += "#include \""+incl+"\"\n"; + } + + File f = File.newBuilder().setName(fileNameGetRequestMessageH).setContent(codeBuilderGetRequestMessageH.toString()).build(); + responseBuilder.addFile(f); + + String fileContentGetRequestMessageCC = codeBuilderGetRequestMessageCC.toString(); + fileContentGetRequestMessageCC = fileContentGetRequestMessageCC.replace("@@@INCLUDE@@@", extraIncludes); + f = File.newBuilder().setName(fileNameGetRequestMessageCC).setContent(fileContentGetRequestMessageCC).build(); + responseBuilder.addFile(f); + } + } + } + + responseBuilder.build().writeTo(System.out); + + } + + private static String[] unrollInputMessage(FileDescriptorProto file, String type, Map typeDefs) { + + TypeDef unrollType = typeDefs.get(type); + if (unrollType == null) { + System.err.println("could not find message '"+type+"' to unroll"); + System.exit(1); + } + DescriptorProto message = unrollType.message; + + + StringBuilder list = new StringBuilder(); + + StringBuilder builder = new StringBuilder("final "+unrollType.fullName+" msg = "+unrollType.fullName+".newBuilder()."); + boolean wasEmpty = false; + for (int i = 0; i < message.getFieldCount(); i++) { + wasEmpty = false; + final FieldDescriptorProto field = message.getField(i); + final String FName = field.getName().substring(0, 1).toUpperCase()+field.getName().substring(1); + switch (field.getType()) { + case TYPE_MESSAGE: + case TYPE_ENUM: { + + TypeDef fieldType = typeDefs.get(field.getTypeName()); + if (fieldType == null) { + System.err.println("could not find message '"+field.getTypeName()+"' for field "+field.getName()); + System.exit(1); + } + + if (field.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED) { + list.append("List<"+fieldType.fullName+"> "+field.getName()); + builder.append("addAll"+FName+"("+field.getName()+")"); + } else { + if (!field.getTypeName().contains("emptyRequest")) { + list.append(fieldType.fullName+" "+field.getName()); + builder.append("set"+FName+"("+field.getName()+")"); + } else { + System.out.println("empty field: "+field.getName()); + wasEmpty = true; + } + + } + break; + } + default: { + if (field.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED) { + list.append(tttr.get(field.getType())+" "+field.getName()); + builder.append("addAll"+FName+"("+field.getName()+")"); + } else { + list.append(ttt.get(field.getType())+" "+field.getName()); + builder.append("set"+FName+"("+field.getName()+")"); + } + break; + } + } + builder.append("."); + if ((i < message.getFieldCount()-1) && !wasEmpty) { + list.append(", "); + } + + if ((i == message.getFieldCount()-1) && wasEmpty) { + list.delete(list.length()-2,list.length()); + } + + + } + if (message.getFieldCount() > 0) + builder.append("build();"); + else + builder = new StringBuilder("final "+unrollType.fullName+" msg = "+unrollType.fullName+".getDefaultInstance();"); + + return new String[]{list.toString(),builder.toString()}; + + } + + private static void printMessage(List msgs) { + for (DescriptorProto msg : msgs) { + System.err.println("message type: "+msg.getName()); + for (FieldDescriptorProto field : msg.getFieldList()) { + switch (field.getType()) { + case TYPE_MESSAGE: { + System.err.println(" "+field.getName()+": "+field.getTypeName()+", "+field.getLabel().toString()); + printMessage(msg.getNestedTypeList()); + break; + } + case TYPE_ENUM: { + System.err.println(" "+field.getName()+": "+field.getTypeName()); + break; + } + case TYPE_GROUP: { + System.err.println(" "+field.getName()+": List<"+field.getTypeName()+">"); + break; + } + default: { + System.err.println(" "+field.getName()+": "+ttt.get(field.getType())+","+field.getLabel().toString()); + break; + } + } + + } + } + } + + private static class TypeDef { + DescriptorProto message; + String fullName; + String fileName; + } +} diff --git a/java/pbrpcgen/src/org/xtreemfs/pbrpcgen/RPCSourceGenerator.java b/java/pbrpcgen/src/org/xtreemfs/pbrpcgen/RPCSourceGenerator.java new file mode 100644 index 0000000..68ff695 --- /dev/null +++ b/java/pbrpcgen/src/org/xtreemfs/pbrpcgen/RPCSourceGenerator.java @@ -0,0 +1,424 @@ +package org.xtreemfs.pbrpcgen; + +import com.google.protobuf.DescriptorProtos.DescriptorProto; +import com.google.protobuf.DescriptorProtos.EnumDescriptorProto; +import com.google.protobuf.DescriptorProtos.FieldDescriptorProto; +import com.google.protobuf.DescriptorProtos.FieldDescriptorProto.Type; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.File; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.google.protobuf.DescriptorProtos.FileDescriptorProto; +import com.google.protobuf.DescriptorProtos.MethodDescriptorProto; +import com.google.protobuf.DescriptorProtos.ServiceDescriptorProto; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.ExtensionRegistry; +import java.util.Date; +import java.util.HashMap; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC; + +public class RPCSourceGenerator { + + private static final Map ttt; + + private static final Map tttr; + + static { + ttt = new HashMap(); + ttt.put(Type.TYPE_BOOL,"boolean"); + ttt.put(Type.TYPE_BYTES,"ByteString"); + ttt.put(Type.TYPE_DOUBLE,"double"); + ttt.put(Type.TYPE_FIXED32,"int"); + ttt.put(Type.TYPE_FIXED64,"long"); + ttt.put(Type.TYPE_FLOAT,"float"); + ttt.put(Type.TYPE_STRING,"String"); + + tttr = new HashMap(); + tttr.put(Type.TYPE_BOOL,"List"); + tttr.put(Type.TYPE_BYTES,"List"); + tttr.put(Type.TYPE_DOUBLE,"List"); + tttr.put(Type.TYPE_FIXED32,"List"); + tttr.put(Type.TYPE_FIXED64,"List"); + tttr.put(Type.TYPE_FLOAT,"List"); + tttr.put(Type.TYPE_STRING,"List"); + } + private static final String EMPTY_REQUEST = "emptyRequest"; + private static final String EMPTY_RESPONSE = "emptyResponse"; + + //public static final String PACKAGE = "org.xtreemfs.foundation.pbrpc.generated"; + + public static void main(String[] args) throws Exception { + + ExtensionRegistry er = ExtensionRegistry.newInstance(); + PBRPC.registerAllExtensions(er); + CodeGeneratorRequest rq = CodeGeneratorRequest.parseFrom(System.in,er); + CodeGeneratorResponse.Builder responseBuilder = CodeGeneratorResponse.newBuilder(); + + Map typeDefs = new HashMap(); + + + Map map = rq.getAllFields(); + // System.err.println(map); + + for (Entry files : map.entrySet()) { + + if (files.getKey().getName().equals("proto_file")) { + + for (FileDescriptorProto proto : (List) files.getValue()) { + java.io.File filchen = new java.io.File(proto.getName()); + final String fileName = filchen.getName().replace(".proto", ""); + String pkgName = proto.getPackage(); + if (pkgName.length() > 0) + pkgName = pkgName+"."; + for (DescriptorProto msg : proto.getMessageTypeList()) { + TypeDef def = new TypeDef(); + def.fullName = fileName+"."+msg.getName(); + def.message = msg; + def.fileName = fileName; + typeDefs.put("."+pkgName+msg.getName(),def); + } + for (EnumDescriptorProto msg : proto.getEnumTypeList()) { + TypeDef def = new TypeDef(); + def.fullName = fileName+"."+msg.getName(); + def.message = null; + def.fileName = fileName; + typeDefs.put("."+pkgName+msg.getName(),def); + } + } + } + } + System.err.println("typedefs: "+typeDefs.keySet()); + + for (Entry files : map.entrySet()) { + + if (files.getKey().getName().equals("proto_file")) { + + for (FileDescriptorProto proto : (List) files.getValue()) { + + final String javaPackage = proto.getOptions().getJavaPackage(); + final String filePrefix = javaPackage.replace(".", "/"); + java.io.File filchen = new java.io.File(proto.getName()); + final String msgName = filchen.getName().replace(".proto", ""); + + + //printMessage(proto.getMessageTypeList()); + + for (ServiceDescriptorProto srv : proto.getServiceList()) { + // proto.getName() returns the file name of the .proto file + // e.g. "xtreemfs/DIR.proto" + // Example: "xtreemfs/DIR.proto" -> "DIRServiceClient" + String className = (new java.io.File(proto.getName())).getName().replace(".proto", "ServiceClient"); + String classNameConst = (new java.io.File(proto.getName())).getName().replace(".proto", "ServiceConstants"); + + + StringBuilder codeBuilder = new StringBuilder(); + StringBuilder codeBuilderConst = new StringBuilder(); + + codeBuilder.append("//automatically generated from "+filchen.getName()+" at "+new Date()+"\n"); + codeBuilder.append("//(c) "+((new Date()).getYear()+1900)+". See LICENSE file for details.\n\n"); + codeBuilder.append("package " + javaPackage + ";\n\n"); + + codeBuilderConst.append("//automatically generated from "+filchen.getName()+" at "+new Date()+"\n"); + codeBuilderConst.append("//(c) "+((new Date()).getYear()+1900)+". See LICENSE file for details.\n\n"); + codeBuilderConst.append("package " + javaPackage + ";\n\n"); + + codeBuilderConst.append("import com.google.protobuf.Message;\n"); + + codeBuilderConst.append("\n"); + codeBuilderConst.append("public class " + classNameConst + " {\n\n"); + + //imports + codeBuilder.append("import java.io.IOException;\n"); + codeBuilder.append("import java.util.List;\n"); + codeBuilder.append("import java.net.InetSocketAddress;\n"); + codeBuilder.append("import com.google.protobuf.Message;\n"); + codeBuilder.append("import com.google.protobuf.ByteString;\n"); + codeBuilder.append("import org.xtreemfs.foundation.buffer.ReusableBuffer;\n"); + codeBuilder.append("import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth;\n"); + codeBuilder.append("import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials;\n"); + codeBuilder.append("import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient;\n"); + codeBuilder.append("import org.xtreemfs.foundation.pbrpc.client.RPCResponse;\n"); + + codeBuilder.append("\n"); + codeBuilder.append("public class " + className + " {\n\n"); + + //member declarations + codeBuilder.append(" private RPCNIOSocketClient client;\n"); + codeBuilder.append(" private InetSocketAddress defaultServer;\n"); + + codeBuilder.append("\n"); + //methods + + codeBuilder.append(" public "+className+"(RPCNIOSocketClient client, InetSocketAddress defaultServer) {\n"); + codeBuilder.append(" this.client = client;\n"); + codeBuilder.append(" this.defaultServer = defaultServer;\n"); + codeBuilder.append(" }\n\n"); + + + int interfaceId = srv.getOptions().getExtension(PBRPC.interfaceId); + + codeBuilderConst.append(" public static final int INTERFACE_ID = " + interfaceId + ";\n"); + + StringBuilder cbRequest = new StringBuilder("\n public static Message getRequestMessage(int procId) {\n"); + cbRequest.append(" switch (procId) {\n"); + + StringBuilder cbResponse = new StringBuilder("\n public static Message getResponseMessage(int procId) {\n"); + cbResponse.append(" switch (procId) {\n"); + + + for (MethodDescriptorProto method: srv.getMethodList()) { + + System.err.println("input type: "+method.getInputType()); + final String inputType = typeDefs.get(method.getInputType()).fullName;//msgName+method.getInputType(); + + final String returnType = typeDefs.get(method.getOutputType()).fullName;//msgName+method.getOutputType(); + + final int procId = method.getOptions().getExtension(PBRPC.procId); + + final boolean isEmptyResponse = returnType.contains(EMPTY_RESPONSE); + final boolean isEmptyRequest = inputType.contains(EMPTY_REQUEST); + + codeBuilderConst.append(" public static final int PROC_ID_"+method.getName().toUpperCase()+" = " + procId + ";\n"); + if (isEmptyResponse) + cbResponse.append(" case "+procId+": return null;\n"); + else + cbResponse.append(" case "+procId+": return "+returnType+".getDefaultInstance();\n"); + + if (isEmptyRequest) + cbRequest.append(" case "+procId+": return null;\n"); + else + cbRequest.append(" case "+procId+": return "+inputType+".getDefaultInstance();\n"); + + final boolean data_in = method.getOptions().hasExtension(PBRPC.dataIn) ? method.getOptions().getExtension(PBRPC.dataIn) : false; + final String dataValue = data_in ? "data" : "null"; + + if (isEmptyResponse) { + codeBuilder.append(" public RPCResponse " + method.getName() + "("); + } else { + codeBuilder.append(" public RPCResponse<"+returnType+"> " + method.getName() + "("); + } + codeBuilder.append("InetSocketAddress server, Auth authHeader, UserCredentials userCreds, "+inputType+" input"); + if (data_in) + codeBuilder.append(", ReusableBuffer data"); + codeBuilder.append(") throws IOException {\n"); + codeBuilder.append(" if (server == null) server = defaultServer;\n"); + codeBuilder.append(" if (server == null) throw new IllegalArgumentException(\"defaultServer must be set in constructor if you want to pass null as server in calls\");\n"); + if (!isEmptyResponse) { + codeBuilder.append(" RPCResponse<"+returnType+"> response = new RPCResponse<"+returnType+">("+returnType+".getDefaultInstance());\n"); + } else { + codeBuilder.append(" RPCResponse response = new RPCResponse(null);\n"); + } + codeBuilder.append(" client.sendRequest(server, authHeader, userCreds, "+interfaceId+", "+procId+", input, "+dataValue+", response, false);\n"); + codeBuilder.append(" return response;\n"); + codeBuilder.append(" }\n\n"); + + String[] unrolled = unrollInputMessage(proto, method.getInputType(), typeDefs); + + if (isEmptyResponse) { + codeBuilder.append(" public RPCResponse " + method.getName() + "("); + } else { + codeBuilder.append(" public RPCResponse<"+returnType+"> " + method.getName() + "("); + } + codeBuilder.append("InetSocketAddress server, Auth authHeader, UserCredentials userCreds"); + if (unrolled[0].length() > 0) { + codeBuilder.append(", "); + codeBuilder.append(unrolled[0]); + } + if (data_in) + codeBuilder.append(", ReusableBuffer data"); + codeBuilder.append(") throws IOException {\n"); + codeBuilder.append(" "+unrolled[1]+"\n"); + codeBuilder.append(" return "); + codeBuilder.append(method.getName()); + codeBuilder.append("(server, authHeader, userCreds,"); + if (isEmptyRequest) { + codeBuilder.append("null"); + } else { + codeBuilder.append("msg"); + } + if (data_in) + codeBuilder.append(", data"); + codeBuilder.append(");\n"); + codeBuilder.append(" }\n\n"); + } + + codeBuilder.append(" public boolean clientIsAlive() {\n"); + codeBuilder.append(" return client.isAlive();\n"); + codeBuilder.append(" }\n"); + + // codeBuilder.append(" public static void " + + // msg.getName() + "() {\n"); + // + // for (FieldDescriptorProto field : msg.getFieldList()) + // { + // + // String type = field.getTypeName(); + // if(type.startsWith(".")) + // type = type.substring(1); + // + // field.getType(); + // + // codeBuilder.append(" public " + type + " " + + // field.getName() + ";\n"); + // } + // + + codeBuilder.append("}"); + + cbResponse.append(" default: throw new RuntimeException(\"unknown procedure id\");\n"); + cbRequest.append(" default: throw new RuntimeException(\"unknown procedure id\");\n"); + cbRequest.append(" }\n }\n\n"); + cbResponse.append(" }\n }\n\n"); + + codeBuilderConst.append(cbRequest); + codeBuilderConst.append(cbResponse); + codeBuilderConst.append("\n}"); + + File f = File.newBuilder().setName(filePrefix+"/"+className + ".java").setContent( + codeBuilder.toString()).build(); + responseBuilder.addFile(f); + + f = File.newBuilder().setName(filePrefix+"/"+classNameConst + ".java").setContent( + codeBuilderConst.toString()).build(); + responseBuilder.addFile(f); + } + + } + + } + } + + responseBuilder.build().writeTo(System.out); + + } + + private static String[] unrollInputMessage(FileDescriptorProto file, String type, Map typeDefs) { + + TypeDef unrollType = typeDefs.get(type); + if (unrollType == null) { + System.err.println("could not find message '"+type+"' to unroll"); + System.exit(1); + } + DescriptorProto message = unrollType.message; + + + StringBuilder list = new StringBuilder(); + + StringBuilder builder = new StringBuilder("final "+unrollType.fullName+" msg = "+unrollType.fullName+".newBuilder()."); + boolean wasEmpty = false; + for (int i = 0; i < message.getFieldCount(); i++) { + wasEmpty = false; + final FieldDescriptorProto field = message.getField(i); + final String FName = field.getName().substring(0, 1).toUpperCase()+field.getName().substring(1); + switch (field.getType()) { + case TYPE_MESSAGE: + case TYPE_ENUM: { + + TypeDef fieldType = typeDefs.get(field.getTypeName()); + if (fieldType == null) { + System.err.println("could not find message '"+field.getTypeName()+"' for field "+field.getName()); + System.exit(1); + } + + if (field.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED) { + list.append("List<"+fieldType.fullName+"> "+field.getName()); + builder.append("addAll"+camelCase(FName)+"("+field.getName()+")"); + } else { + if (!field.getTypeName().contains("emptyRequest")) { + list.append(fieldType.fullName+" "+field.getName()); + builder.append("set"+camelCase(FName)+"("+field.getName()+")"); + } else { + System.out.println("empty field: "+field.getName()); + wasEmpty = true; + } + + } + break; + } + default: { + if (field.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED) { + list.append(tttr.get(field.getType())+" "+field.getName()); + builder.append("addAll"+camelCase(FName)+"("+field.getName()+")"); + } else { + list.append(ttt.get(field.getType())+" "+field.getName()); + builder.append("set"+camelCase(FName)+"("+field.getName()+")"); + } + break; + } + } + builder.append("."); + if ((i < message.getFieldCount()-1) && !wasEmpty) { + list.append(", "); + } + + if ((i == message.getFieldCount()-1) && wasEmpty) { + list.delete(list.length()-2,list.length()); + } + + + } + if (message.getFieldCount() > 0) + builder.append("build();"); + else { + if (unrollType.fullName.contains(EMPTY_REQUEST)) { + builder = new StringBuilder(""); + } else { + builder = new StringBuilder("final "+unrollType.fullName+" msg = "+unrollType.fullName+".getDefaultInstance();"); + } + } + + + return new String[]{list.toString(),builder.toString()}; + + } + + private static String camelCase(String name) { + int pos = name.indexOf('_'); + while ((pos >= 0) && (pos+2 <= name.length())) { + String tmp = name.substring(0,pos); + tmp += name.substring(pos+1, pos+2).toUpperCase(); + tmp += name.substring(pos+2); + name = tmp; + pos = name.indexOf('_'); + } + return name; + } + + private static void printMessage(List msgs) { + for (DescriptorProto msg : msgs) { + System.err.println("message type: "+msg.getName()); + for (FieldDescriptorProto field : msg.getFieldList()) { + switch (field.getType()) { + case TYPE_MESSAGE: { + System.err.println(" "+field.getName()+": "+field.getTypeName()+", "+field.getLabel().toString()); + printMessage(msg.getNestedTypeList()); + break; + } + case TYPE_ENUM: { + System.err.println(" "+field.getName()+": "+field.getTypeName()); + break; + } + case TYPE_GROUP: { + System.err.println(" "+field.getName()+": List<"+field.getTypeName()+">"); + break; + } + default: { + System.err.println(" "+field.getName()+": "+ttt.get(field.getType())+","+field.getLabel().toString()); + break; + } + } + + } + } + } + + private static class TypeDef { + DescriptorProto message; + String fullName; + String fileName; + } +} diff --git a/java/servers/build-1.6.5.xml b/java/servers/build-1.6.5.xml new file mode 100644 index 0000000..d29dbe0 --- /dev/null +++ b/java/servers/build-1.6.5.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + Builds, tests, and runs the project XtreemFS. + + + + + + Creating XtreemFS-tests.jar. + + + + + + + + diff --git a/java/servers/build-before-profiler.xml b/java/servers/build-before-profiler.xml new file mode 100644 index 0000000..edc846a --- /dev/null +++ b/java/servers/build-before-profiler.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project XtreemFS. + + + diff --git a/java/servers/build.xml b/java/servers/build.xml new file mode 100644 index 0000000..4b2982b --- /dev/null +++ b/java/servers/build.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + Builds, tests, and runs the project XtreemFS. + + + + + + Creating XtreemFS-tests.jar. + + + + + + + + diff --git a/java/servers/eclipse-project/.classpath b/java/servers/eclipse-project/.classpath new file mode 100644 index 0000000..a1ecfe0 --- /dev/null +++ b/java/servers/eclipse-project/.classpath @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/java/servers/eclipse-project/.classpath_WITH_BabuDB_project_reference b/java/servers/eclipse-project/.classpath_WITH_BabuDB_project_reference new file mode 100644 index 0000000..cc974c5 --- /dev/null +++ b/java/servers/eclipse-project/.classpath_WITH_BabuDB_project_reference @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/java/servers/eclipse-project/.project b/java/servers/eclipse-project/.project new file mode 100644 index 0000000..3406892 --- /dev/null +++ b/java/servers/eclipse-project/.project @@ -0,0 +1,19 @@ + + + xtreemfs_server + + + xtreemfs_foundation + xtreemfs_flease + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/java/servers/nbproject/build-impl-1.6.5.xml b/java/servers/nbproject/build-impl-1.6.5.xml new file mode 100644 index 0000000..7cba3bb --- /dev/null +++ b/java/servers/nbproject/build-impl-1.6.5.xml @@ -0,0 +1,682 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + diff --git a/java/servers/nbproject/build-impl.xml b/java/servers/nbproject/build-impl.xml new file mode 100644 index 0000000..6b17438 --- /dev/null +++ b/java/servers/nbproject/build-impl.xml @@ -0,0 +1,1068 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/servers/nbproject/genfiles.properties b/java/servers/nbproject/genfiles.properties new file mode 100644 index 0000000..3dc30e2 --- /dev/null +++ b/java/servers/nbproject/genfiles.properties @@ -0,0 +1,11 @@ +build.xml.data.CRC32=4a9eff70 +build.xml.script.CRC32=ce2ddeb0 +build.xml.stylesheet.CRC32=958a1d3e +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=53818f37 +nbproject/build-impl.xml.script.CRC32=42a9c2ae +nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45 +nbproject/profiler-build-impl.xml.data.CRC32=4a9eff70 +nbproject/profiler-build-impl.xml.script.CRC32=abda56ed +nbproject/profiler-build-impl.xml.stylesheet.CRC32=42cb6bcf diff --git a/java/servers/nbproject/profiler-build-impl.xml b/java/servers/nbproject/profiler-build-impl.xml new file mode 100644 index 0000000..7c8995d --- /dev/null +++ b/java/servers/nbproject/profiler-build-impl.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/servers/nbproject/project.properties b/java/servers/nbproject/project.properties new file mode 100644 index 0000000..ffc0947 --- /dev/null +++ b/java/servers/nbproject/project.properties @@ -0,0 +1,101 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +application.args= +application.title=XtreemFS +application.vendor=bjko +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/XtreemFS.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.BabuDB.jar-1=../lib/BabuDB.jar +file.reference.bcprov-jdk16-139.jar=lib/bcprov-jdk16-139.jar +file.reference.cdaclient.jar=lib/cdaclient.jar +file.reference.junit-4.11.jar=../lib/test/junit-4.11.jar +file.reference.config.jar=lib/config.jar +file.reference.je-3.2.13.jar=lib/je-3.2.13.jar +file.reference.protobuf-java-2.5.0.jar=../lib/protobuf-java-2.5.0.jar +file.reference.xbean.jar=lib/xbean.jar +file.reference.jdmkrt.jar=../lib/jdmkrt.jar +file.reference.jdmktk.jar=../lib/jdmktk.jar +includes=** +jar.archive.disabled=${jnlp.enabled} +jar.compress=false +jar.index=${jnlp.enabled} +javac.classpath=\ + ${file.reference.BabuDB.jar-1}:\ + ${file.reference.protobuf-java-2.5.0.jar}:\ + ${reference.XtreemFS-foundation.jar}:\ + ${reference.Flease.jar}:\ + ${file.reference.junit-4.11.jar}:\ + ${file.reference.jdmkrt.jar}:\ + ${file.reference.jdmktk.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.6 +javac.target=1.6 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit_4.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding= +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +jnlp.codebase.type=local +jnlp.codebase.url=file:/home/bjko/xtreemos/xtreemfs/googlecode/servers/dist +jnlp.descriptor=application +jnlp.enabled=false +jnlp.mixed.code=default +jnlp.offline-allowed=false +jnlp.signed=false +jnlp.signing= +jnlp.signing.alias= +jnlp.signing.keystore= +main.class=org.xtreemfs.mrc.MRC +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +project.Flease=../flease +project.XtreemFS-foundation=../foundation +reference.Flease.jar=${project.Flease}/dist/Flease.jar +reference.XtreemFS-foundation.jar=${project.XtreemFS-foundation}/dist/Foundation.jar +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs=-ea +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +src.dir=src +test.src.dir=test diff --git a/java/servers/nbproject/project.xml b/java/servers/nbproject/project.xml new file mode 100644 index 0000000..f108ba5 --- /dev/null +++ b/java/servers/nbproject/project.xml @@ -0,0 +1,33 @@ + + org.netbeans.modules.java.j2seproject + + + XtreemFS + 1.6.5 + + + + + + + + + + Flease + jar + + jar + clean + jar + + + XtreemFS-foundation + jar + + jar + clean + jar + + + + diff --git a/java/servers/src/org/xtreemfs/common/Capability.java b/java/servers/src/org/xtreemfs/common/Capability.java new file mode 100644 index 0000000..7e0dd85 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/Capability.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2009 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; + +/** + * This class implements a Java representation of a capability. + * + * In general, a capability can be seen as a token granting the permission to + * carry out an operation on a remote server. + * + * When a client wants open a file, the MRC checks whether the respective kind + * of access is granted. If so, the MRC sends a capability to the client, which + * in turn sends the capability to the OSD when file contents are accessed or + * modified. The OSD has to check whether the capability is valid. A capability + * is valid as long as it has a correct signature and has not expired yet. + * Capabilities can be renewed in order to extend their validity. + * + * Each capability contains a file ID, a string representing the access mode, an + * expiration time stamp representing the time in seconds from 1/1/1970, a + * string containing data that can be used to verify the client identity, as + * well as a signature added by the MRC. + * + * + * @author stender + * + */ +public class Capability { + + private XCap xcap; + + private final String sharedSecret; + + /** + * Creates a capability from a given set of data. A signature will be added + * automatically. This constructor is meant to initially create a capability + * at the MRC. + * + * @param fileId + * the file ID + * @param accessMode + * the access mode + * @param validity + * the relative validity time span in seconds + * @param expires + * the absolute expiration time stamp (seconds since 1970) + * @param epochNo + * the epoch number associated with the capability; epoch numbers + * are incremented each time the file is truncated or deleted + * @param sharedSecret + * the shared secret to be used to sign the capability + */ + public Capability(String fileId, int accessMode, int validity, long expires, String clientIdentity, + int epochNo, boolean replicateOnClose, SnapConfig snapConfig, long snapTimestamp, String sharedSecret) { + + this.sharedSecret = sharedSecret; + + XCap.Builder builder = XCap.newBuilder().setAccessMode(accessMode).setClientIdentity(clientIdentity).setExpireTimeS(expires).setExpireTimeoutS(validity). + setFileId(fileId).setReplicateOnClose(replicateOnClose).setTruncateEpoch(epochNo).setSnapConfig(snapConfig).setSnapTimestamp(snapTimestamp); + + final String sig = calcSignature(builder); + builder.setServerSignature(sig); + xcap = builder.build(); + } + + /** + * Wrapper for XCap objects. + * + * @param xcap + * the parsed XCap object + * @param sharedSecret + * the shared secret (from configuration file) + */ + public Capability(XCap xcap, String sharedSecret) { + this.xcap = xcap; + this.sharedSecret = sharedSecret; + } + + public XCap getXCap() { + return this.xcap; + } + + public String getFileId() { + return xcap.getFileId(); + } + + public int getAccessMode() { + return xcap.getAccessMode(); + } + + /** + * returns the absolute time, when the capability expires (in seconds) + * + * @return + */ + public long getExpires() { + return xcap.getExpireTimeS(); + } + + public String getClientIdentity() { + return xcap.getClientIdentity(); + } + + public int getEpochNo() { + return xcap.getTruncateEpoch(); + } + + public String getSignature() { + return xcap.getServerSignature(); + } + + /** + * Checks whether the capability is valid. + * + * @return true, if it hasn't expired yet and the signature is + * valid, false, otherwise + */ + public boolean isValid() { + return !hasExpired() && hasValidSignature(); + } + + /** + * Checks whether the capability has expired. + * + * @return true, if the current system time is after the + * expiration time stamp false, otherwise + */ + public boolean hasExpired() { + return TimeSync.getGlobalTime() / 1000 > xcap.getExpireTimeS(); + } + + /** + * Checks whether the capability has a valid signature. + * + * @return true, if the signature is valid, false, + * otherwise + */ + public boolean hasValidSignature() { + return xcap.getServerSignature().equals(calcSignature(xcap.toBuilder())); + } + + public boolean isReplicateOnClose() { + return xcap.getReplicateOnClose(); + } + + public SnapConfig getSnapConfig() { + return xcap.getSnapConfig(); + } + + public long getSnapTimestamp() { + return xcap.getSnapTimestamp(); + } + + /** + * Returns a string representation of the capability. + * + * @return a JSON-formatted string representing the capability. + */ + public String toString() { + return xcap.toString(); + } + + protected String calcSignature(XCap.Builder builder) { + + // right now, we use a shared secret between MRC and OSDs + // as soon as we have a Public Key Infrastructure, signatures + // will be generated and checked by means of asymmetric encryption + // techniques + + String plainText = builder.getFileId() + Integer.toString(builder.getAccessMode()) + + Long.toString(builder.getExpireTimeS()) + Long.toString(builder.getTruncateEpoch()) + + Long.toString(builder.getSnapConfig().getNumber()) + Long.toString(builder.getSnapTimestamp()) + + sharedSecret; + + try { + MessageDigest md5 = MessageDigest.getInstance("MD5"); + md5.update(plainText.getBytes()); + byte[] digest = md5.digest(); + + return OutputUtils.byteArrayToHexString(digest); + } catch (NoSuchAlgorithmException exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + return null; + } + } + +} diff --git a/java/servers/src/org/xtreemfs/common/GlobalConstants.java b/java/servers/src/org/xtreemfs/common/GlobalConstants.java new file mode 100644 index 0000000..d370c51 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/GlobalConstants.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; + +/** + * + * @author bjko + */ +public class GlobalConstants { + + public static final Auth AUTH_NONE; + + static { + AUTH_NONE = Auth.newBuilder().setAuthType(AuthType.AUTH_NONE).build(); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/HeartbeatThread.java b/java/servers/src/org/xtreemfs/common/HeartbeatThread.java new file mode 100644 index 0000000..3d5cf2c --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/HeartbeatThread.java @@ -0,0 +1,623 @@ +/* + * Copyright (c) 2008-2010 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.xtreemfs.common.config.ServiceConfig; +import org.xtreemfs.common.util.NetUtils; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; + +import sun.misc.Signal; +import sun.misc.SignalHandler; + +/** + * A thread that regularly sends a heartbeat signal with fresh service data to the Directory Service. + */ +public class HeartbeatThread extends LifeCycleThread { + + /** + * An interface that generates service data to be sent to the Directory Service. Each time a heartbeat + * signal is sent, new service data will be generated by means of invoking getServiceData(). + */ + public interface ServiceDataGenerator { + + public DIR.ServiceSet getServiceData(); + } + + public static final long UPDATE_INTERVAL = 60 * 1000; // 60s + + public static final long CONCURRENT_RETRY_INTERVAL = 5 * 1000; // 5s + + private final ServiceUUID uuid; + + private final ServiceDataGenerator serviceDataGen; + + private final DIRClient client; + + private volatile boolean quit; + + private final ServiceConfig config; + + private final boolean advertiseUDPEndpoints; + + private final String proto; + + private String advertisedHostName; + + private final UserCredentials uc; + + private static final String STATIC_ATTR_PREFIX = "static."; + + public static final String STATUS_ATTR = STATIC_ATTR_PREFIX + "status"; + + /** + * If set to true, a RegisterService call (which is the call used by this + * thread to regularly report at the DIR) will not update the + * last_updated_s field for the service. + * Used by tools like xtfs_chstatus. + */ + public static final String DO_NOT_SET_LAST_UPDATED = STATIC_ATTR_PREFIX + "do_not_set_last_updated"; + + /** + * Timestamp when the last heartbeat was sent. + */ + private long lastHeartbeat; + + /** Guards pauseNumberOfWaitingThreads and paused. */ + private final Object pauseLock; + + /** While >0, the thread will stop its periodic operations. */ + private int pauseNumberOfWaitingThreads; + + /** Set to true if the periodic operation is stopped. */ + private boolean paused; + + private static Auth authNone; + + /** Determines if a renewal should take place in the next run of the main loop. **/ + private volatile boolean addressMappingRenewalPending = false; + + /** Indicates if a renewal has been triggered. **/ + private volatile boolean addressMappingRenewalTriggered = false; + + /** Used to sleep until the next heartbeat is scheduled. It can be notified to trigger an instant update **/ + private Object updateIntervalMonitor = new Object(); + + static { + authNone = Auth.newBuilder().setAuthType(AuthType.AUTH_NONE).build(); + } + + public HeartbeatThread(String name, DIRClient client, ServiceUUID uuid, ServiceDataGenerator serviceDataGen, + ServiceConfig config, boolean advertiseUDPEndpoints) { + + super(name); + + setPriority(Thread.MAX_PRIORITY); + + this.pauseLock = new Object(); + + this.client = client; + this.uuid = uuid; + this.serviceDataGen = serviceDataGen; + this.config = config; + this.advertiseUDPEndpoints = advertiseUDPEndpoints; + this.uc = UserCredentials.newBuilder().setUsername("hb-thread").addGroups("xtreemfs-services") + .build(); + if (!config.isUsingSSL()) { + proto = Schemes.SCHEME_PBRPC; + } else { + if (config.isGRIDSSLmode()) { + proto = Schemes.SCHEME_PBRPCG; + } else { + proto = Schemes.SCHEME_PBRPCS; + } + } + + if (config.isUsingMultihoming() && config.isUsingRenewalSignal()) { + enableAddressMappingRenewalSignal(); + } + + this.lastHeartbeat = TimeSync.getGlobalTime(); + } + + @Override + public void shutdown() { + try { + if (client.clientIsAlive()) { + client.xtreemfs_service_offline(null, authNone, uc, uuid.toString(), 1); + } + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_WARN, this, "could not set service offline at DIR"); + Logging.logError(Logging.LEVEL_WARN, this, ex); + } + + this.quit = true; + this.interrupt(); + } + + public void initialize() throws IOException { + // initially, ... + try { + + // ... for each UUID, ... + for (;;) { + // catch any ConcurrentModificationException and retry + try { + registerServices(-1); + break; + } catch (PBRPCException ex) { + if (ex.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_EAGAIN) { + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, this, + "concurrent service registration; will try again after %d milliseconds", + CONCURRENT_RETRY_INTERVAL); + } else + throw ex; + } + } + + // ... register the address mapping for the service + registerAddressMappings(); + + } catch (InterruptedException ex) { + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_ERROR, this, + "an error occurred while initially contacting the Directory Service: " + ex); + throw new IOException("cannot initialize service at XtreemFS DIR: " + ex, ex); + } + + try { + this.setServiceConfiguration(); + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_ERROR, this, + "An error occurred while submitting the service configuration to the DIR service:"); + Logging.logError(Logging.LEVEL_ERROR, this, e); + } + } + + @Override + public void run() { + try { + + notifyStarted(); + + // periodically, ... + while (!quit) { + synchronized (pauseLock) { + while (pauseNumberOfWaitingThreads > 0) { + pauseLock.wait(); + } + + paused = false; + } + + try { + // update data on DIR; do not retry, as this is done periodically anyway + registerServices(1); + } catch (PBRPCException ex) { + if (ex.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_EAGAIN) { + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, this, + "concurrent service registration; will try again after %d milliseconds", + UPDATE_INTERVAL); + } else + Logging.logMessage(Logging.LEVEL_ERROR, this, + "An error occurred during the periodic registration at the DIR:"); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } catch (IOException ex) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "periodic registration at DIR failed: %s", + ex.toString()); + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + } + + if (addressMappingRenewalPending) { + try { + // Reset the flag indicating a renewal has been triggered. + addressMappingRenewalTriggered = false; + // Try to renew the address mappings. + registerAddressMappings(); + // If the renewal has been successful, the renewal flag will be reset. + // If an error occurred, the renewal will be retried on the next regular heartbeat. + addressMappingRenewalPending = false; + // Renew the networks list available to the UUIDResolver. + UUIDResolver.renewNetworks(); + } catch (IOException ex) { + Logging.logMessage(Logging.LEVEL_ERROR, this, + "requested renewal of address mappings failed: %s", ex.toString()); + } + } + + if (quit) { + break; + } + + synchronized (pauseLock) { + paused = true; + pauseLock.notifyAll(); + } + + // If no renewal request has been triggered during the loop, this HeartbeatThread can wait for + // the next regular UPDATE_INTERVAL. + if (!addressMappingRenewalTriggered) { + synchronized (updateIntervalMonitor) { + updateIntervalMonitor.wait(UPDATE_INTERVAL); + } + } + } + + notifyStopped(); + + } catch (InterruptedException e) { + notifyStopped(); + } catch (Throwable ex) { + notifyCrashed(ex); + } + } + + private void registerServices(int numRetries) throws IOException, PBRPCException, InterruptedException { + + for (Service reg : serviceDataGen.getServiceData().getServicesList()) { + // retrieve old DIR entry + ServiceSet oldSet = numRetries == -1 ? client.xtreemfs_service_get_by_uuid(null, authNone, uc, + reg.getUuid()) : client.xtreemfs_service_get_by_uuid(null, authNone, uc, reg.getUuid(), + numRetries); + long currentVersion = 0; + Service oldService = oldSet.getServicesCount() == 0 ? null : oldSet.getServices(0); + + Map staticAttrs = new HashMap(); + if (oldService != null) { + currentVersion = oldService.getVersion(); + final ServiceDataMap data = oldService.getData(); + for (KeyValuePair pair : data.getDataList()) { + if (pair.getKey().startsWith(STATIC_ATTR_PREFIX)) + staticAttrs.put(pair.getKey(), pair.getValue()); + } + } + + if (!staticAttrs.containsKey(STATUS_ATTR)) + staticAttrs.put(STATUS_ATTR, + Integer.toString(DIR.ServiceStatus.SERVICE_STATUS_AVAIL.getNumber())); + + Service.Builder builder = reg.toBuilder(); + builder.setVersion(currentVersion); + final ServiceDataMap.Builder data = ServiceDataMap.newBuilder(); + for (Entry sAttr : staticAttrs.entrySet()) { + data.addData(KeyValuePair.newBuilder().setKey(sAttr.getKey()).setValue(sAttr.getValue()) + .build()); + } + + // If the service to register is a volume, and a volume with the + // same ID but a different MRC has been registered already, it + // may be necessary to register the volume's MRC as a replica. + // In this case, all keys starting with 'mrc' have to be treated + // separately. + if (reg.getType() == ServiceType.SERVICE_TYPE_VOLUME && oldService != null + && oldService.getUuid().equals(reg.getUuid())) { + + // retrieve the MRC UUID attached to the volume to be + // registered + String mrcUUID = null; + for (KeyValuePair kv : reg.getData().getDataList()) + if (kv.getKey().equals("mrc")) { + mrcUUID = kv.getValue(); + break; + } + assert (mrcUUID != null); + + // check if the UUID is already contained in the volume's + // list of MRCs and determine the next vacant key + int maxMRCNo = 1; + boolean contained = false; + for (KeyValuePair kv : oldService.getData().getDataList()) { + + if (kv.getKey().startsWith("mrc")) { + + data.addData(kv); + + if (kv.getValue().equals(mrcUUID)) + contained = true; + + if (!kv.getKey().equals("mrc")) { + int no = Integer.parseInt(kv.getKey().substring(3)); + if (no > maxMRCNo) + maxMRCNo = no; + } + } + } + + // if the UUID is not contained, add it + if (!contained) + data.addData(KeyValuePair.newBuilder().setKey("mrc" + (maxMRCNo + 1)).setValue(mrcUUID)); + + // add all other key-value pairs + for (KeyValuePair kv : reg.getData().getDataList()) + if (!kv.getKey().startsWith("mrc")) + data.addData(kv); + + } + + // in any other case, all data can be updated + else + data.addAllData(reg.getData().getDataList()); + + builder.setData(data); + if (numRetries == -1) + client.xtreemfs_service_register(null, authNone, uc, builder.build()); + else + client.xtreemfs_service_register(null, authNone, uc, builder.build(), numRetries); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "%s successfully updated at Directory Service", uuid); + } + + // update lastHeartbeat value + this.lastHeartbeat = TimeSync.getGlobalTime(); + } + } + + private void setServiceConfiguration() throws IOException, PBRPCException, InterruptedException { + Configuration conf = client.xtreemfs_configuration_get(null, authNone, uc, uuid.toString()); + long currentVersion = 0; + + currentVersion = conf.getVersion(); + + Configuration.Builder confBuilder = Configuration.newBuilder(); + confBuilder.setUuid(uuid.toString()).setVersion(currentVersion); + for (Map.Entry mapEntry : config.toHashMap().entrySet()) { + confBuilder.addParameter(KeyValuePair.newBuilder().setKey(mapEntry.getKey()) + .setValue(mapEntry.getValue()).build()); + } + + client.xtreemfs_configuration_set(null, authNone, uc, confBuilder.build()); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "%s successfully send configuration to Directory Service", uuid); + } + } + + private void registerAddressMappings() throws InterruptedException, IOException { + + List reachableEndpoints = NetUtils.getReachableEndpoints(config.getPort(), proto); + + AddressMapping.Builder advertisedEndpoint = null; + + // Use the configured hostname or listen.address if they are set for the advertised endpoint. + if (!config.getHostName().isEmpty() || config.getAddress() != null) { + // remove the leading '/' if necessary + String host = config.getHostName().isEmpty() ? config.getAddress().getHostName() : config.getHostName(); + if (host.startsWith("/")) { + host = host.substring(1); + } + + try { + // see if we can resolve the hostname + InetAddress ia = InetAddress.getByName(host); + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_WARN, this, "WARNING! Could not resolve my " + + "hostname (%s) locally! Please make sure that the hostname is set correctly " + + "(either on your system or in the service config file). This will lead to " + + "problems if clients and other OSDs cannot resolve this service's address!\n", host); + } + + advertisedEndpoint = AddressMapping.newBuilder().setUuid(uuid.toString()).setVersion(0).setProtocol(proto) + .setAddress(host).setPort(config.getPort()).setTtlS(3600) + .setUri(proto + "://" + host + ":" + config.getPort()); + } + + // Try to resolve the localHostName and find it in the endpoints to use it as the advertised endpoint if possible. + if (advertisedEndpoint == null) { + try { + InetAddress host = InetAddress.getLocalHost(); + String hostAddress = NetUtils.getHostAddress(host); + + // Try to find the + for (AddressMapping.Builder mapping : reachableEndpoints) { + if (mapping.getAddress().equals(hostAddress)) { + advertisedEndpoint = mapping; + break; + } + } + } catch (UnknownHostException e) { + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, "Could not resolve the local hostname."); + } + } + + // Use the first mapping from the reachable endpoints. This will be a global address if one exists. + if (advertisedEndpoint == null && reachableEndpoints.size() > 0) { + advertisedEndpoint = reachableEndpoints.get(0); + } + + // in case no IP address could be found at all, use 127.0.0.1 for local testing. + if (advertisedEndpoint == null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.net, this, + "Could not find a valid IP address, will use 127.0.0.1 instead."); + advertisedEndpoint = AddressMapping.newBuilder().setAddress("127.0.0.1").setPort(config.getPort()) + .setProtocol(proto).setTtlS(3600) + .setUri(NetUtils.getURI(proto, InetAddress.getByName("127.0.0.1"), config.getPort())); + } + + // Fetch the latest address mapping version from the Directory Service. + long version = 0; + AddressMappingSet ams = client.xtreemfs_address_mappings_get(null, authNone, uc, uuid.toString()); + + // Retrieve the version number from the address mapping. + if (ams.getMappingsCount() > 0) { + version = ams.getMappings(0).getVersion(); + } + + // Set the advertised endpoints version, matching network and uuid. + advertisedEndpoint.setVersion(version).setMatchNetwork("*").setUuid(uuid.toString()); + advertisedHostName = advertisedEndpoint.getAddress(); + + List endpoints = new ArrayList(); + endpoints.add(advertisedEndpoint); + if (advertiseUDPEndpoints) { + endpoints.add(NetUtils.cloneMappingForProtocol(advertisedEndpoint, Schemes.SCHEME_PBRPCU)); + } + + if (config.isUsingMultihoming()) { + for (AddressMapping.Builder mapping : reachableEndpoints) { + // Add all the remaining endpoints not advertised yet. + if (!advertisedEndpoint.getAddress().equals(mapping.getAddress())) { + mapping.setUuid(uuid.toString()); + endpoints.add(mapping); + if (advertiseUDPEndpoints) { + endpoints.add(NetUtils.cloneMappingForProtocol(mapping, Schemes.SCHEME_PBRPCU)); + } + } + } + } + + AddressMappingSet.Builder amsb = AddressMappingSet.newBuilder(); + for (AddressMapping.Builder mapping : endpoints) { + amsb.addMappings(mapping); + } + + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "Registering the following address mappings for the service:"); + for (AddressMapping mapping : amsb.getMappingsList()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, "%s --> %s (%s)", mapping.getUuid(), + mapping.getUri(), mapping.getMatchNetwork()); + } + } + + // Register or update the current address mapping. + client.xtreemfs_address_mappings_set(null, authNone, uc, amsb.build()); + } + + /** + * Getter for the timestamp when the last heartbeat was sent. + * + * @return long - timestamp like System.currentTimeMillis() returns it. + */ + public long getLastHeartbeat() { + return this.lastHeartbeat; + } + + /** + * @return the advertisedHostName + */ + public String getAdvertisedHostName() { + return advertisedHostName; + } + + /** + * Instructs the HeartbeatThread to pause its current operations. Blocks until it has done so. + * + * @remark Do not forget to call {@link #resumeOperation()} afterward or the thread won't be unpaused. + * + * @throws InterruptedException + */ + public void pauseOperation() throws InterruptedException { + synchronized (pauseLock) { + pauseNumberOfWaitingThreads++; + while (!paused) { + try { + pauseLock.wait(); + } catch (InterruptedException e) { + // In case of a shutdown, abort. + pauseNumberOfWaitingThreads--; + pauseLock.notifyAll(); + + throw e; + } + } + } + } + + /** + * Tells the HeartbeatThread to resume operation. + */ + public void resumeOperation() { + synchronized (pauseLock) { + pauseNumberOfWaitingThreads--; + + pauseLock.notifyAll(); + } + } + + /** + * Renew the address mappings immediately (HeartbeatThread will wake up when this is called). + */ + public void triggerAddressMappingRenewal() { + addressMappingRenewalPending = true; + addressMappingRenewalTriggered = true; + + // To make the changes immediate, the thread has to be notified if it is sleeping. + synchronized (updateIntervalMonitor) { + updateIntervalMonitor.notifyAll(); + } + } + + /** + * Enable a signal handler for USR2 which will trigger the address mapping renewal. + * + * Since it is possible that certain VMs are using the USR2 signal internally, the server should be started with the + * -XX:+UseAltSigs flag when signal usage is desired. + * + * @throws RuntimeException + */ + private void enableAddressMappingRenewalSignal() { + + final HeartbeatThread hbt = this; + + // TODO(jdillmann): Test on different VMs and operating systems. + try { + Signal.handle(new Signal("USR2"), new SignalHandler() { + + @Override + public void handle(Signal signal) { + // If the HeartbeatThread is still alive, renew the addresses and send them to the DIR. + if (hbt != null) { + hbt.triggerAddressMappingRenewal(); + } + } + }); + + } catch (IllegalArgumentException e) { + Logging.logMessage(Logging.LEVEL_CRIT, this, "Could not register SignalHandler for USR2."); + Logging.logError(Logging.LEVEL_CRIT, null, e); + + throw new RuntimeException("Could not register SignalHandler for USR2.", e); + } + } +} diff --git a/java/servers/src/org/xtreemfs/common/KeyValuePairs.java b/java/servers/src/org/xtreemfs/common/KeyValuePairs.java new file mode 100644 index 0000000..5f67692 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/KeyValuePairs.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2010 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + + +package org.xtreemfs.common; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; + +/** + * + * @author bjko + */ +public class KeyValuePairs { + + public static String getValue(List list, String key) { + for (KeyValuePair pair : list) { + if (pair.getKey().equals(key)) + return pair.getValue(); + } + return null; + } + + public static void putValue(List list, String key, String value) { + Iterator iter = list.iterator(); + while (iter.hasNext()) { + KeyValuePair pair = iter.next(); + if (pair.getKey().equals(key)) + iter.remove(); + } + list.add(KeyValuePair.newBuilder().setKey(key).setValue(value).build()); + } + + public static List fromMap(Map map) { + List list = new ArrayList(map.size()); + for (Entry e : map.entrySet()) { + list.add(KeyValuePair.newBuilder().setKey(e.getKey()).setValue(e.setValue(null)).build()); + } + return list; + } + + public static Map toMap(List list) { + Map map = new HashMap(); + for (KeyValuePair kv : list) + map.put(kv.getKey(), kv.getValue()); + return map; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/ReplicaUpdatePolicies.java b/java/servers/src/org/xtreemfs/common/ReplicaUpdatePolicies.java new file mode 100644 index 0000000..e64951b --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/ReplicaUpdatePolicies.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common; + + +/** + * + * @author bjko + */ +public class ReplicaUpdatePolicies { + + public static final String REPL_UPDATE_PC_NONE = ""; + public static final String REPL_UPDATE_PC_RONLY = "ronly"; + public static final String REPL_UPDATE_PC_WARONE = "WaR1"; + public static final String REPL_UPDATE_PC_WARA = "WaRa"; // @deprecated as of XtreemFS 1.3.1 and no longer allowed to set. Use WaR1 instead. + public static final String REPL_UPDATE_PC_WQRQ = "WqRq"; + + + /** + * Returns true if the replicaUpdatePolicy is read-write replicated. + */ + public static boolean isRwReplicated(String replicaUpdatePolicy) { + return (replicaUpdatePolicy.equals(REPL_UPDATE_PC_WARA) || replicaUpdatePolicy.equals(REPL_UPDATE_PC_WARONE) || replicaUpdatePolicy + .equals(REPL_UPDATE_PC_WQRQ)); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/ServiceAvailability.java b/java/servers/src/org/xtreemfs/common/ServiceAvailability.java new file mode 100755 index 0000000..898feea --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/ServiceAvailability.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common; + +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * It manages the availability for all services. If a service could not accessed it is marked as not available + * for a period.
    + * This class is thread-safe.
    + * 06.04.2009 + */ +public class ServiceAvailability { + public final static int DEFAULT_INITIAL_TIMEOUT = 1000 * 60; // 1 minute + public final static int DEFAULT_CLEANUP_INTERVAL = 1000 * 60 * 60; // 60 minutes + public final static int DEFAULT_MAX_LAST_ACCESS = 1000 * 60 * 60 * 24; // 1 day + + /** + * This thread removes services from the list, which were not accessed since a long time. + * 06.04.2009 + */ + private class ServiceRemover extends Thread { + final int cleanupInterval; + final private int maxLastAccessTime; + private final ConcurrentHashMap serviceAvailability; + boolean quit; + + public ServiceRemover(ConcurrentHashMap serviceAvailability, int maxLastAccessTime, + int cleanupInterval) { + super("ServiceAvailability Service-Remover"); + this.serviceAvailability = serviceAvailability; + this.cleanupInterval = cleanupInterval; + this.maxLastAccessTime = maxLastAccessTime; + this.quit = false; + } + + /** + * Shuts the thread down. + */ + public void quitThread() { + this.quit = true; + this.interrupt(); + } + + /** + * Main loop. + */ + public void run() { + while (!quit) { + Iterator serviceIt = serviceAvailability.values().iterator(); + while (serviceIt.hasNext()) { + ServiceInfo service = serviceIt.next(); + // osd was not accessed since a long time + if(System.currentTimeMillis() - service.lastAccessTime > maxLastAccessTime) + serviceIt.remove(); + } + try { + Thread.sleep(cleanupInterval); + } catch (InterruptedException ex) { + } + } + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.lifecycle, this, "shutdown complete"); + } + } + + /** + * encapsulates the necessary infos + * 09.04.2009 + */ + private static class ServiceInfo { + private long lastAccessTime = 0; // milliseconds + private long lastFailedAccessTime = 0; // milliseconds + private int currentTimeout; // milliseconds + + public ServiceInfo(int timeout) { + currentTimeout = timeout; + } + + public boolean isAvailable() { + lastAccessTime = System.currentTimeMillis(); + return lastFailedAccessTime + currentTimeout <= System.currentTimeMillis(); + } + + public void lastAccessFailed() { + lastFailedAccessTime = System.currentTimeMillis(); + currentTimeout = currentTimeout * 2; + } + } + + /** + * makes sure, that obsolete entries in the map will be removed from time to time + */ + private final ServiceRemover removerThread; + + /** + * saves the service-timeouts + * key: OSD-UUID + */ + private ConcurrentHashMap serviceAvailability; + + private final int initialTimeout; + + /** + * uses default time intervals + */ + public ServiceAvailability() { + this.serviceAvailability = new ConcurrentHashMap(); + + initialTimeout = DEFAULT_INITIAL_TIMEOUT; + + this.removerThread = new ServiceRemover(this.serviceAvailability, DEFAULT_MAX_LAST_ACCESS, DEFAULT_CLEANUP_INTERVAL); + this.removerThread.start(); + } + + /* + * useful for tests + */ + /** + * all params in milliseconds + */ + public ServiceAvailability(int initialTimeout, int maxLastAccessTime, int cleanupInterval) { + this.serviceAvailability = new ConcurrentHashMap(); + + this.initialTimeout = initialTimeout; + + this.removerThread = new ServiceRemover(this.serviceAvailability, maxLastAccessTime, cleanupInterval); + this.removerThread.start(); + } + + /** + * shutdown of the internal thread + */ + public void shutdown() { + this.removerThread.quitThread(); + } + + /** + * Checks if the service should be available for access. + * @param service + * @return + */ + public boolean isServiceAvailable(ServiceUUID service) { + if (!serviceAvailability.containsKey(service)) { + serviceAvailability.put(service, new ServiceInfo(initialTimeout)); + return true; + } else + return serviceAvailability.get(service).isAvailable(); + + } + + /** + * If a service could not be accessed, you must run this method. So the system can know who is available and + * can manage the timeouts. + * @param service + */ + public void setServiceWasNotAvailable(ServiceUUID service) { + if(!serviceAvailability.containsKey(service)) + serviceAvailability.put(service, new ServiceInfo(initialTimeout)); + serviceAvailability.get(service).lastAccessFailed(); + } +} diff --git a/java/servers/src/org/xtreemfs/common/auth/AuthenticationException.java b/java/servers/src/org/xtreemfs/common/auth/AuthenticationException.java new file mode 100644 index 0000000..d0f5cd9 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/auth/AuthenticationException.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.auth; + +/** + * Thrown by an authentication provide when authentication is not + * possible for any reason. + * @author bjko + */ +public class AuthenticationException extends Exception { + + /** creates a new exception. + * + * @param msg an error message that should be meaningful to users! + */ + public AuthenticationException(String msg) { + super(msg); + } +} diff --git a/java/servers/src/org/xtreemfs/common/auth/AuthenticationProvider.java b/java/servers/src/org/xtreemfs/common/auth/AuthenticationProvider.java new file mode 100644 index 0000000..01eec97 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/auth/AuthenticationProvider.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.auth; + +import org.xtreemfs.foundation.pbrpc.channels.ChannelIO; + +/** + * Authentication Providers extract the credentials (UID/GIDs/SuperUser) from + * the authentication header and the certificates. + * + * @author bjko + */ +public interface AuthenticationProvider { + + /** + * initializes the provider class + * + * @param useSSL + * true, if SSL is enabled. + * @throws java.lang.RuntimeException + * if the provider cannot be initialized. + */ + void initialize(boolean useSSL) throws RuntimeException; + + /** + * Get the effective credentials for an operation. + * + * @param ctx + * user credentials sent by the client + * @param channel + * the channel used, can be used to store attachments and to get + * certificates + * @return the effective user credentials + * @throws org.xtreemfs.common.auth.AuthenticationException + * if authentication is not possible + */ + UserCredentials getEffectiveCredentials(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials ctx, ChannelIO channel) throws AuthenticationException; + +} diff --git a/java/servers/src/org/xtreemfs/common/auth/FederationIdX509AuthProvider.java b/java/servers/src/org/xtreemfs/common/auth/FederationIdX509AuthProvider.java new file mode 100644 index 0000000..7b83256 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/auth/FederationIdX509AuthProvider.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2008 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.auth; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.channels.ChannelIO; + +/** + * authentication provider for the Contrail project. + * + * @author PS + */ +public class FederationIdX509AuthProvider implements AuthenticationProvider { + + + private final static String USER_ID = "CN"; + private final static String GROUP_ID = "O"; + + // String privilegedCertificatePathname = "privileged.txt"; + // private HashSet privilegedCertificates; + + @Override + public UserCredentials getEffectiveCredentials( + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials ctx, + ChannelIO channel) throws AuthenticationException { + + // use cached info, if present! + if (channel.getAttachment() != null) { + if (Logging.isDebug()) { + Logging.logMessage( + Logging.LEVEL_DEBUG, Category.auth, this, "using attachment..."); + } + final UserCredentials creds = (UserCredentials)channel.getAttachment(); + + if (Logging.isDebug()) { + Logging.logMessage( + Logging.LEVEL_DEBUG, Category.auth, this, "using cached creds: " + creds); + } + + return creds; + } + + // parse cert if no cached info is present + try { + final Certificate[] certs = channel.getCerts(); + if (certs.length > 0) { + final X509Certificate cert = ((X509Certificate) certs[0]); + String fullDN = cert.getSubjectX500Principal().getName(); + + final List globalUIDs = getNamedElements( + cert.getSubjectX500Principal().getName(), USER_ID); + + // only use the UUID of the certificate + String globalUID = null; + if (!globalUIDs.isEmpty()) { + globalUID = globalUIDs.iterator().next(); + } + else { + globalUID = fullDN; + } + + final List globalGIDs = getNamedElements( + cert.getSubjectX500Principal().getName(), GROUP_ID); + + if (globalGIDs.isEmpty()) { + globalGIDs.add(fullDN); + } + + if (Logging.isDebug()) { + Logging.logMessage( + Logging.LEVEL_DEBUG, Category.auth, this, + "X.509-User cert present: %s, %s", globalUID, globalGIDs); + } + + // the super user is required for the GAFS manager to + // act in behalf of a user to create/delete volumes and + // add policies to volumes + boolean isSuperUser = false; + // for (String privilegedCert : this.privilegedCertificates) { + // if (fullDN.contains(privilegedCert)) { + // isSuperUser = true; + // break; + // } + // } + + final UserCredentials creds = new UserCredentials(globalUID, globalGIDs, isSuperUser); + channel.setAttachment(creds); + + return creds; + } + else { + throw new AuthenticationException("no X.509-certificates present"); + } + } catch (Exception ex) { + Logging.logUserError(Logging.LEVEL_ERROR, Category.auth, this, ex); + throw new AuthenticationException("invalid credentials " + ex); + } + + } + + private List getNamedElements(String principal, String element) { + String[] elems = principal.split(","); + List elements = new ArrayList(); + for (String elem : elems) { + String[] kv = elem.split("="); + if (kv.length == 2 + && kv[0].equals(element)) { + elements.add(kv[1]); + } + } + return elements; + } + + public void initialize(boolean useSSL) throws RuntimeException { + if (!useSSL) { + throw new RuntimeException(this.getClass().getName() + " can only be used if SSL is enabled!"); + } + + // InputStream privilegedCertificatesStream + // = getClass().getClassLoader().getResourceAsStream(this.privilegedCertificatePathname); + + // service certs + // this.privilegedCertificates = readHosts(privilegedCertificatesStream); + } + + + public static HashSet readHosts(InputStream serviceCertificatesStream) { + HashSet serviceCertificates = new HashSet(); + + if (serviceCertificatesStream == null) { + Logging.logMessage( + Logging.LEVEL_WARN, Category.auth, FederationIdX509AuthProvider.class, + "The list of privileged-certificates does not exist."); + return serviceCertificates; + // throw new RuntimeException("The list of privileged-certificates does not exist"); + } + + InputStreamReader in = null; + BufferedReader reader = null; + try { + in = new InputStreamReader(serviceCertificatesStream); + reader = new BufferedReader(in); + String line = null; + while ((line = reader.readLine()) != null) { + line.trim(); + + if (line == null || line.equals("")) { + continue; + } + else { + serviceCertificates.add(line); + + Logging.logMessage(Logging.LEVEL_INFO, Category.auth, FederationIdX509AuthProvider.class, + "Adding service-certificate: " + line); + } + } + } catch (FileNotFoundException e) { + Logging.logMessage( + Logging.LEVEL_WARN, Category.auth, FederationIdX509AuthProvider.class, + "The list of privileged-certificates does not exist."); + + // throw new RuntimeException( + // "The list of privileged-certificates does not exist."); + } catch (IOException e) { + Logging.logMessage( + Logging.LEVEL_WARN, Category.auth, FederationIdX509AuthProvider.class, + "Could not parse the list of privileged-certificates."); + + // throw new RuntimeException( + // "Could not parse the list of privileged-certificates."); + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (IOException e) { + } + } + return serviceCertificates; + + } +} diff --git a/java/servers/src/org/xtreemfs/common/auth/NullAuthProvider.java b/java/servers/src/org/xtreemfs/common/auth/NullAuthProvider.java new file mode 100644 index 0000000..e22fa04 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/auth/NullAuthProvider.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2008 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.auth; + +import org.xtreemfs.foundation.pbrpc.channels.ChannelIO; + +/** + * A simple provider that parses the JSON string sent in the authentication + * header as described in the protocol spec. + * + * @author bjko + */ +public class NullAuthProvider implements AuthenticationProvider { + + public NullAuthProvider() { + } + + public UserCredentials getEffectiveCredentials(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials ctx, ChannelIO channel) + throws AuthenticationException { + return new UserCredentials(ctx.getUsername(), ctx.getGroupsList(), ctx.getUsername().equals("root")); + } + + public void initialize(boolean useSSL) throws RuntimeException { + } + +} diff --git a/java/servers/src/org/xtreemfs/common/auth/SimpleX509AuthProvider.java b/java/servers/src/org/xtreemfs/common/auth/SimpleX509AuthProvider.java new file mode 100644 index 0000000..53afb41 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/auth/SimpleX509AuthProvider.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2008 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.auth; + +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.channels.ChannelIO; + +/** + * authentication provider for XOS certificates. + * + * @author bjko + */ +public class SimpleX509AuthProvider implements AuthenticationProvider { + + private NullAuthProvider nullAuth; + + @Override + public UserCredentials getEffectiveCredentials(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials ctx, + ChannelIO channel) throws AuthenticationException { + // use cached info! + assert (nullAuth != null); + if (channel.getAttachment() != null) { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.auth, this, "using attachment..."); + final Object[] cache = (Object[]) channel.getAttachment(); + final Boolean serviceCert = (Boolean) cache[0]; + if (serviceCert) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.auth, this, "service cert..."); + return nullAuth.getEffectiveCredentials(ctx, channel); + } else { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.auth, this, "using cached creds: " + + cache[1]); + return (UserCredentials) cache[1]; + } + } + // parse cert if no cached info is present + try { + final Certificate[] certs = channel.getCerts(); + if (certs.length > 0) { + final X509Certificate cert = ((X509Certificate) certs[0]); + String fullDN = cert.getSubjectX500Principal().getName(); + String commonName = getNameElement(cert.getSubjectX500Principal().getName(), "CN"); + + if (commonName.startsWith("host/") || commonName.startsWith("xtreemfs-service/")) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.auth, this, + "X.509-host cert present"); + channel.setAttachment(new Object[] { new Boolean(true) }); + // use NullAuth in this case to parse JSON header + return nullAuth.getEffectiveCredentials(ctx, null); + } else { + + final String globalUID = fullDN; + final String globalGID = getNameElement(cert.getSubjectX500Principal().getName(), "OU"); + List gids = new ArrayList(1); + gids.add(globalGID); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.auth, this, + "X.509-User cert present: %s, %s", globalUID, globalGID); + + boolean isSuperUser = globalGID.contains("xtreemfs-admin"); + final UserCredentials creds = new UserCredentials(globalUID, gids, isSuperUser); + channel.setAttachment(new Object[] { new Boolean(false), creds }); + return creds; + } + } else { + throw new AuthenticationException("no X.509-certificates present"); + } + } catch (Exception ex) { + Logging.logUserError(Logging.LEVEL_ERROR, Category.auth, this, ex); + throw new AuthenticationException("invalid credentials " + ex); + } + + } + + private String getNameElement(String principal, String element) { + String[] elems = principal.split(","); + for (String elem : elems) { + String[] kv = elem.split("="); + if (kv.length != 2) + continue; + if (kv[0].equals(element)) + return kv[1]; + } + return null; + } + + public void initialize(boolean useSSL) throws RuntimeException { + if (!useSSL) { + throw new RuntimeException(this.getClass().getName() + " can only be used if SSL is enabled!"); + } + nullAuth = new NullAuthProvider(); + nullAuth.initialize(useSSL); + } +} diff --git a/java/servers/src/org/xtreemfs/common/auth/UserCredentials.java b/java/servers/src/org/xtreemfs/common/auth/UserCredentials.java new file mode 100644 index 0000000..956cb9f --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/auth/UserCredentials.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2008 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.auth; + +import java.util.List; + +/** + * User credentials. + * @author bjko + */ +public class UserCredentials { + protected String userID; + protected List groupIDs; + protected boolean superUser; + + public UserCredentials(String userID,List groupIDs, boolean superUser) { + this.userID = userID; + this.groupIDs = groupIDs; + this.superUser = superUser; + } + + public String getUserID() { + return userID; + } + + public void setUserID(String userID) { + this.userID = userID; + } + + public List getGroupIDs() { + return groupIDs; + } + + public void setGroupIDs(List groupIDs) { + this.groupIDs = groupIDs; + } + + public boolean isSuperUser() { + return superUser; + } + + public void setSuperUser(boolean superUser) { + this.superUser = superUser; + } + + +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/AbstractBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/AbstractBenchmark.java new file mode 100644 index 0000000..6957c82 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/AbstractBenchmark.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.Volume; +import org.xtreemfs.foundation.logging.Logging; + +import java.io.IOException; +import java.util.concurrent.Callable; + +/** + * Abstract baseclass for the benchmark classes. + * + * @author jensvfischer + */ + abstract class AbstractBenchmark implements Callable{ + + static volatile boolean cancelled = false; + + final int requestSize; + final long benchmarkSize; + final Volume volume; + final AdminClient client; + final BenchmarkConfig config; + final VolumeManager volumeManager; + + AbstractBenchmark(long benchmarkSize, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) throws Exception { + this.client = client; + this.benchmarkSize = benchmarkSize; + this.volume = volumeManager.getNextVolume(); + this.config = config; + this.requestSize = config.getChunkSizeInBytes(); + this.volumeManager = volumeManager; + this.cancelled = false; // reset cancellation status + } + + /* + * Performs a single sequential read- or write-benchmark. Whether a read- or write-benchmark is performed depends on + * which subclass is instantiated. This method is supposed to be called within its own thread to run a benchmark. + */ + BenchmarkResult runBenchmark() throws Exception { + + String shortClassname = this.getClass().getName().substring(this.getClass().getName().lastIndexOf('.') + 1); + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "Starting %s on volume %s", shortClassname, volume.getVolumeName()); + + // Setting up + byte[] data = new byte[requestSize]; + + long numberOfRequests = benchmarkSize / requestSize; + + /* Run the AbstractBenchmark */ + long before = System.currentTimeMillis(); + long requestCounter = performIO(data, numberOfRequests); + long after = System.currentTimeMillis(); + + if (benchmarkSize != requestCounter) + throw new BenchmarkFailedException("Data written does not equal the requested size"); + + /* Calculate results */ + double timeInSec = (after - before) / 1000.; + BenchmarkResult result = new BenchmarkResult(timeInSec, benchmarkSize, requestCounter); + + finalizeBenchmark(); + + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "Finished %s", shortClassname); + return result; + } + + /* called before a benchmark thread is started */ + abstract void prepareBenchmark() throws Exception; + + /* + * Writes or reads the specified amount of data to/from the volume specified in the object initialization. Called + * within the benchmark method. + */ + abstract long performIO(byte[] data, long numberOfBlocks) throws IOException; + + /* called at the end of every benchmark */ + abstract void finalizeBenchmark() throws Exception; + + public static void cancel(){ + cancelled = true; + } + + @Override + public BenchmarkResult call() throws Exception { + return this.runBenchmark(); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkConfig.java b/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkConfig.java new file mode 100644 index 0000000..dc3b3f4 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkConfig.java @@ -0,0 +1,857 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.config.PolicyContainer; +import org.xtreemfs.common.config.ServiceConfig; +import org.xtreemfs.common.libxtreemfs.Options; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * @author jensvfischer + */ +public class BenchmarkConfig extends ServiceConfig { + + private static final Parameter[] benchmarkParameter = { + Parameter.DEBUG_LEVEL, + Parameter.DEBUG_CATEGORIES, + Parameter.DIRECTORY_SERVICE, + Parameter.USE_SSL, + Parameter.SERVICE_CREDS_FILE, + Parameter.SERVICE_CREDS_PASSPHRASE, + Parameter.SERVICE_CREDS_CONTAINER, + Parameter.TRUSTED_CERTS_FILE, + Parameter.TRUSTED_CERTS_CONTAINER, + Parameter.TRUSTED_CERTS_PASSPHRASE, + Parameter.TRUST_MANAGER, + Parameter.USE_GRID_SSL_MODE, + Parameter.ADMIN_PASSWORD, + Parameter.BASEFILE_SIZE_IN_BYTES, + Parameter.FILESIZE, + Parameter.USERNAME, + Parameter.GROUP, + Parameter.OSD_SELECTION_POLICIES, + Parameter.REPLICATION_POLICY, + Parameter.REPLICATION_FACTOR, + Parameter.CHUNK_SIZE_IN_BYTES, + Parameter.STRIPE_SIZE_IN_BYTES, + Parameter.STRIPE_SIZE_SET, + Parameter.STRIPE_WIDTH, + Parameter.STRIPE_WIDTH_SET, + Parameter.NO_CLEANUP, + Parameter.NO_CLEANUP_VOLUMES, + Parameter.NO_CLEANUP_BASEFILE, + Parameter.OSD_CLEANUP + }; + + private Options options; + private Map policyAttributes; + private SSLOptions sslOptions = null; + + private BenchmarkConfig(Properties props, Options options, Map policyAttributes) { + super(props); + read(); + this.options = options; + this.policyAttributes = policyAttributes; + } + + private void setDefaults() { + super.setDefaults(benchmarkParameter); + } + + private void read() { + for(Parameter param : benchmarkParameter) { + parameter.put(param, readParameter(param)); + } + } + + public static Parameter[] getBenchmarkParameter() { + return benchmarkParameter; + } + + /** + * Set the stripe size on an existing {@link BenchmarkConfig} object. + * + * @param size + */ + public void setStripeSizeInBytes(Integer size) { + parameter.put(Parameter.STRIPE_SIZE_IN_BYTES, size); + } + + /** + * Set the stripe size on an existing {@link BenchmarkConfig} object. + * + * @param size + */ + public void setStripeWidth(Integer size) { + parameter.put(Parameter.STRIPE_WIDTH, size); + } + + + /** + * Get the size of the basefile for random benchmarks.
    + * The basefile is a huge file to/from which the random benchmarks write/read.
    + * Default: 3 GiB. + * @return the size of the basefile for random benchmarks + */ + public Long getBasefileSizeInBytes(){ + return (Long) parameter.get(Parameter.BASEFILE_SIZE_IN_BYTES); + } + + /** + * Get the size of files in filebased benchmarks.
    + * Filebased benchmarks write/read a huge number of files.
    + * Default: 4 KiB. + * @return the size of files in filebased benchmarks + */ + public Integer getFilesize(){ + return (Integer) parameter.get(Parameter.FILESIZE); + } + + /** + * Get the username to be used when creating files and volumes
    + * Default: benchmark. + * @return the username + */ + public String getUsername(){ + return (String) parameter.get(Parameter.USERNAME); + } + + + /** + * Get the group to be used when creating files and volumes.
    + * Default: benchmark. + * @return the group + */ + public String getGroup(){ + return (String) parameter.get(Parameter.GROUP); + } + + + /** + * Get the RPC user credentials, created from the username and group infos. + * @return the RPC user credentials + */ + public RPC.UserCredentials getUserCredentials() { + return RPC.UserCredentials.newBuilder().setUsername((String) parameter.get(Parameter.USERNAME)) + .addGroups((String) parameter.get(Parameter.USERNAME)).build(); + } + + /** + * Get the libxtreemfs {@link org.xtreemfs.common.libxtreemfs.Options}. + * + * @return the libxtreemfs {@link org.xtreemfs.common.libxtreemfs.Options} + */ + public Options getOptions(){ + return options; + } + + + /** + * Get the {@link SSLOptions} for the SSL Authetification Provider.
    + * Default: null. + * @return the {@link SSLOptions} + */ + public SSLOptions getSslOptions() throws IOException, InstantiationException, IllegalAccessException, + ClassNotFoundException { + if (isUsingSSL()) { + if (null == sslOptions) { + sslOptions = new SSLOptions( + new FileInputStream(this.getServiceCredsFile()), + this.getServiceCredsPassphrase(), + this.getServiceCredsContainer(), + new FileInputStream( + this.getTrustedCertsFile()), + this.getTrustedCertsPassphrase(), + this.getTrustedCertsContainer(), + false, + this.isGRIDSSLmode(), + this.getSSLProtocolString(), + new PolicyContainer(this).getTrustManager() + ); + } + } + return sslOptions; + } + + /** + * Get the OSD selection policies used when creating or opening volumes.
    + * + * Default: No policy is set. If an existing volume is used this means, that already set policies of the volume are + * used. If a new volume is created, the defaults are used ("1000,3002": OSD filter, Shuffling). + * + * @return the OSD selection policies + */ + public String getOsdSelectionPolicies(){ + return (String) parameter.get(Parameter.OSD_SELECTION_POLICIES); + } + + + /** + * Get the policy attributes for OSD selection policies.

    + * The attributes are set when the volumes are created / opened.
    + * A policy attribute consists of the name of the attribute, and the value the attribute is set to. For more + * information see the XtreemFS User Guide.
    + * + * Attribute Format: . e.g., "1002.uuids"
    + * Value format: , e.g. "osd01" + * + * @return the policy attributes + */ + public Map getPolicyAttributes(){ + return this.policyAttributes; + } + + /** + * Get the default replication policy (used when creating or opening volumes).
    + * As the {@code replicationFlags} in + * {@link org.xtreemfs.common.libxtreemfs.Volume#setDefaultReplicationPolicy(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials, String, String, int, int)} + * is set to 0, this is only intended for write/read replication.
    + * + * Default: No policy is set. If an existing volume is used this means, that a already set policy of the volume is + * used. If a new volume is created, the defaults (no replication policy) is used. + * + * @return the replication policy + */ + public String getReplicationPolicy(){ + return (String) parameter.get(Parameter.REPLICATION_POLICY); + } + + /** + * Get the replication factor for the replication policy.
    + * Only used when explicitly setting a replication policy for a volume.
    + * + * Default: 3 (min for WqRq) + * + * @return the replication policy + */ + public Integer getReplicationFactor(){ + return (Integer) parameter.get(Parameter.REPLICATION_FACTOR); + } + + /** + * Get the chunk size for reads/writes in benchmarks.
    + * The chuck size is the amount of data written/ret in one piece.
    + * Default: 131072 bytes (128 KiB). + * + * @return the chunk size + */ + public Integer getChunkSizeInBytes(){ + return (Integer) parameter.get(Parameter.CHUNK_SIZE_IN_BYTES); + } + + /** + * Get the size of an OSD storage block ("blocksize") in bytes.
    + * Used when creating or opening volumes.
    + * + * When opening existing volumes, by default, the stripe size of the given volume is used. When creating a new + * volume, by default a stripe size of 131072 bytes (128 KiB) is used.
    + * @return the blocksize + */ + public Integer getStripeSizeInBytes(){ + return (Integer) parameter.get(Parameter.STRIPE_SIZE_IN_BYTES); + } + + /** + * Get the size of an OSD storage block ("blocksize") in kibibytes.
    + * + * @return the blocksize in KiB + */ + public Integer getStripeSizeInKiB() { + return getStripeSizeInBytes()/1024; + } + + /** + * Indicates, whether a stripeSize was explicitly set via this config, or if the default values where used. + * @return true, if stripeSize was explicitly set + */ + public Boolean isStripeSizeSet(){ + return (Boolean) parameter.get(Parameter.STRIPE_SIZE_SET); + } + + /** + * Get the maximum number of OSDs a file is distributed to. Used when creating or opening volumes
    + * + * When opening existing volumes, by default, the stripe width of the given volume is used. When creating a new + * volume, by default a stripe width of 1 is used.
    + * + * @return the maximum number of OSDs a file is distributed to + */ + public Integer getStripeWidth(){ + return (Integer) parameter.get(Parameter.STRIPE_WIDTH); + } + + + /** + * Indicates, whether a stripeWidth was explicitly set via this config, or if the default values where used. + * @return + */ + public Boolean isStripeWidthSet(){ + return (Boolean) parameter.get(Parameter.STRIPE_WIDTH_SET); + } + + /** + * Indicates whether the files and volumes created during the benchmarks will be deleted.
    + * Default: false. + * @return true, if created files and volumes are not to be deleted + */ + public Boolean isNoCleanup(){ + return (Boolean) parameter.get(Parameter.NO_CLEANUP); + } + + /** + * Indicates, whether the volumes created during the benchmarks will be deleted.
    + * Default: false. + * @return true, if created volumes are not to be deleted + */ + public Boolean isNoCleanupVolumes(){ + return (Boolean) parameter.get(Parameter.NO_CLEANUP_VOLUMES); + } + + /** + * Indicates, whether the basefile created during the random benchmarks will be deleted.
    + * Default: false. + * @return true, if a created basefile is not to be deleted + */ + public Boolean isNoCleanupBasefile(){ + return (Boolean) parameter.get(Parameter.NO_CLEANUP_BASEFILE); + } + + /** + * Indicates, whether a OSD Cleanup will be done at the end of all benchmarks. This might be needed to actually delete + * the storage blocks from the OSD after deleting volumes.
    + * Default: false. + * @return true, if a cleanup is to be performed + */ + public Boolean isOsdCleanup(){ + return (Boolean) parameter.get(Parameter.OSD_CLEANUP); + } + + /** + * Get addresses of the DIR Servers.
    + * Default: 127.0.0.1:32638 + * @return + */ + public String[] getDirAddresses() { + InetSocketAddress[] directoryServices = getDirectoryServices(); + String[] dirAddresses = new String[directoryServices.length]; + for (int i =0; i + * + * Use like this:
    + * + * BenchmarkConfig.ConfigBuilder builder = BenchmarkConfig.newBuilder();
    + * builder.setX("x");
    + * builder.setY("y");
    + * BenchmarkConfig config = builder.build();
    + *
    or like this
    + * + * BenchmarkConfig config = BenchmarkConfig.newBuilder().setX("x").setY("y").build();
    + *
    + *

    + * The {@link Controller} and the {@link BenchmarkConfig} represent the API to the benchmark library. + * + * @author jensvfischer + */ + public static class ConfigBuilder { + + private Properties props = new Properties(); + private ServiceConfig parent; + private Map policyAttributes = new HashMap(); + private Options options = new Options(); + + + /** + * Instantiate an builder (all values are the default values, see {@link BenchmarkConfig}). + */ + private ConfigBuilder() { + } + + /** + * Set the size of the basefile for random benchmarks.
    + * Default: 3 GiB. + * + * @param basefileSizeInBytes + * @return the builder + */ + public ConfigBuilder setBasefileSizeInBytes(long basefileSizeInBytes) { + if (basefileSizeInBytes < 1) + throw new IllegalArgumentException("basefileSizeInBytes < 1 not allowed"); + props.setProperty(Parameter.BASEFILE_SIZE_IN_BYTES.getPropertyString(), + Long.toString(basefileSizeInBytes)); + return this; + } + + /** + * Set the size of files in filebased benchmark.
    + * Default: 4 KiB. + * + * @param filesize + * @return the builder + */ + public ConfigBuilder setFilesize(int filesize) { + if (filesize < 1) + throw new IllegalArgumentException("filesize < 1 not allowed"); + props.setProperty(Parameter.FILESIZE.getPropertyString(), Integer.toString(filesize)); + return this; + } + + /** + * Set the username to be used when creating files and volumes
    + * Default: benchmark. + * + * @param userName + * @return the builder + */ + public ConfigBuilder setUserName(String userName) { + if (userName.isEmpty()) + throw new IllegalArgumentException("Empty username not allowed"); + props.setProperty(Parameter.USERNAME.getPropertyString(), userName); + return this; + } + + /** + * Set the group to be used when creating files and volumes.
    + * Default: benchmark. + * + * @param group + * @return the builder + */ + public ConfigBuilder setGroup(String group) { + if (group.isEmpty()) + throw new IllegalArgumentException("Empty group name not allowed"); + props.setProperty(Parameter.USERNAME.getPropertyString(), group); + return this; + } + + /** + * Set the password for accessing the osd(s)
    + * Default: "". + * + * @param adminPassword + * @return the builder + */ + public ConfigBuilder setAdminPassword(String adminPassword) { + props.setProperty(Parameter.ADMIN_PASSWORD.getPropertyString(), adminPassword); + return this; + } + + + /** + * Set the address of the DIR Server.
    + * Default: 127.0.0.1:32638 + * + * @param dirAddress + * @return the builder + */ + public ConfigBuilder setDirAddress(String dirAddress) { + return setDirAddresses(new String[]{dirAddress}); + } + + + /** + * Set the addresses of the DIR Servers.
    + * Default: 127.0.0.1:32638 + * + * @param dirAddresses + * @return the builder + */ + public ConfigBuilder setDirAddresses(String[] dirAddresses) { + int i =-1; + for (String dirAddress : dirAddresses) { + + /* remove protocol information */ + if (dirAddress.contains("://")) + dirAddress = dirAddress.split("://", 2)[1]; + + /* remove trailing slashes */ + if (dirAddress.endsWith("/")) + dirAddress = dirAddress.substring(0, dirAddress.length() - 1); + + /* split address in host and port */ + String host; + String port; + try { + host = dirAddress.split(":")[0]; + port = dirAddress.split(":")[1]; + } catch (IndexOutOfBoundsException e) { + throw new IllegalArgumentException( + "DIR Address needs to contain a host and a port, separated by \":\" (was: \"" + dirAddress + + "\")."); + } + if (dirAddresses.length == 1 || -1 == i) { + props.setProperty("dir_service.host", host); + props.setProperty("dir_service.port", port); + } else { + props.setProperty("dir_service." + i + ".host", host); + props.setProperty("dir_service." + i + ".port", port); + } + i++; + } + return this; + } + + /** + * Set the libxtreemfs {@link org.xtreemfs.common.libxtreemfs.Options}. + * + * @param options + * @return the builder + */ + public ConfigBuilder setOptions(Options options) { + this.options = options; + return this; + } + + /** + * Set the SSL options for SSL Authetification Provider.
    + * Default: null. + * + * @param useSSL set to true to use SSL, false otherwise + * @param useGridSSL set to true to use GridSSL, false otherwise + * @param serviceCredsFile the pkcs12 file with the ssl user certificate + * @param serviceCredsFile the passphrase for the user certificate + * @param trustedCAsFile jks truststore with the CA + * @param trustedCAsPass passphrase for the jks truststore + */ + public ConfigBuilder setSslOptions(boolean useSSL, boolean useGridSSL, String serviceCredsFile, + String serviceCredsPass, String trustedCAsFile, String trustedCAsPass) { + props.setProperty(Parameter.USE_SSL.getPropertyString(), Boolean.toString(useSSL)); + props.setProperty(Parameter.USE_GRID_SSL_MODE.getPropertyString(), Boolean.toString(useGridSSL)); + props.setProperty(Parameter.SERVICE_CREDS_FILE.getPropertyString(), serviceCredsFile); + props.setProperty(Parameter.SERVICE_CREDS_PASSPHRASE.getPropertyString(), serviceCredsPass); + props.setProperty(Parameter.SERVICE_CREDS_CONTAINER.getPropertyString(), SSLOptions.PKCS12_CONTAINER); + props.setProperty(Parameter.TRUSTED_CERTS_FILE.getPropertyString(), trustedCAsFile); + props.setProperty(Parameter.TRUSTED_CERTS_CONTAINER.getPropertyString(), SSLOptions.JKS_CONTAINER); + props.setProperty(Parameter.TRUSTED_CERTS_PASSPHRASE.getPropertyString(), trustedCAsPass); + return this; + } + + /** + * Set the OSD selection policies used when creating or opening volumes.
    + * + * Default: No policy is set. If an existing volume is used this means, that already set policies of the volume are + * used. If a new volume is created, the defaults are use ("1000,3002": OSD filter, Shuffling). + * + * @param policies + * @return the builder + */ + public ConfigBuilder setOsdSelectionPolicies(String policies) { + props.setProperty(Parameter.OSD_SELECTION_POLICIES.getPropertyString(), policies); + return this; + } + + /** + * Set a policy attribute for a OSD selection policies.

    + * This method can be called multiple times, if multiple attributes are to be set.
    + * The attributes are set when the volumes are created / opened.
    + * A policy attribute consists of the name of the attribute, and the value the attribute is set to. For more information see the XtreemFS User Guide.
    + * + * Attribute Format: . e.g., "1002.uuids"
    + * Value format: , e.g. "osd01" + * + * @param attribute the attribute to be set + * @param value the value the attribute is set to + * @return the builder + */ + public ConfigBuilder setPolicyAttribute(String attribute, String value) { + this.policyAttributes.put(attribute, value); + return this; + } + + /** + * Set the UUID-based filter policy (ID 1002) as OSD selection policy and set the uuids to be used by the policy + * (applied when creating/opening the volumes). It is a shortcut for setting the policy and the attributes manually.
    + * + * Default: see {@link #setOsdSelectionPolicies(String)}. + * + * @param uuids + * the uuids of osds to be used + * @return the builder + */ + public ConfigBuilder setSelectOsdsByUuid(String uuids) { + String key = Parameter.OSD_SELECTION_POLICIES.getPropertyString(); + String osdSelectionPolicies = props.getProperty(key); + if (null == osdSelectionPolicies) + props.setProperty(key, "1002"); + else + props.setProperty(key, osdSelectionPolicies+",1002"); + this.policyAttributes.put("1002.uuids", uuids); + return this; + } + + /** + * Set the default replication policy, used when creating or opening volumes.
    + * As the {@code replicationFlags} in + * {@link org.xtreemfs.common.libxtreemfs.Volume#setDefaultReplicationPolicy(org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials, String, String, int, int)} + * is set to 0, this is only intended for write/read replication.
    + * + * Default: No policy is set. If an existing volume is used this means, that a already set policy of the volume is + * used. If a new volume is created, the default (no replication) is used. + * + * @param policy + * @return the builder + */ + public ConfigBuilder setReplicationPolicy(String policy) { + props.setProperty(Parameter.REPLICATION_POLICY.getPropertyString(), policy); + return this; + } + + /** + * Set the replication factor for the replication policy.
    + * Only used when explicitly setting a replication policy for a volume.
    + * + * Default: 3 (min for WqRq) + * + * @param replicationFactor + * @return the builder + */ + public ConfigBuilder setReplicationFactor(int replicationFactor) { + props.setProperty(Parameter.REPLICATION_FACTOR.getPropertyString(), Integer.toString(replicationFactor)); + return this; + } + + /** + * Set the chunk size for reads/writes in benchmarks. The chuck size is the amount of data written/ret in one piece.
    + * + * Default: 131072 bytes (128 KiB). + * + * @param chunkSizeInBytes the chunk size in bytes + * @return the builder + */ + public ConfigBuilder setChunkSizeInBytes(int chunkSizeInBytes) { + props.setProperty(Parameter.CHUNK_SIZE_IN_BYTES.getPropertyString(), Integer.toString(chunkSizeInBytes)); + return this; + } + + /** + * Set the size of an OSD storage block ("blocksize") in bytes when creating or opening volumes.
    + * + * When opening existing volumes, by default, the stripe size of the given volume is used. When creating a new + * volume, by default a stripe size of 131072 bytes (128 KiB) is used.
    + * + * @param stripeSizeInBytes + * the stripe size in bytes + * @return the builder + */ + public ConfigBuilder setStripeSizeInBytes(int stripeSizeInBytes) { + props.setProperty(Parameter.STRIPE_SIZE_IN_BYTES.getPropertyString(), Integer.toString(stripeSizeInBytes)); + props.setProperty(Parameter.STRIPE_SIZE_SET.getPropertyString(), Boolean.toString(true)); + return this; + } + + /** + * Set the maximum number of OSDs a file is distributed to. Used when creating or opening volumes
    + * + * When opening existing volumes, by default, the stripe width of the given volume is used. When creating a new + * volume, by default a stripe width of 1 is used.
    + * @return the builder + */ + public ConfigBuilder setStripeWidth(int stripeWidth) { + props.setProperty(Parameter.STRIPE_WIDTH.getPropertyString(), Integer.toString(stripeWidth)); + props.setProperty(Parameter.STRIPE_WIDTH_SET.getPropertyString(), Boolean.toString(true)); + return this; + } + + /** + * If set, the files and volumes created during the benchmarks will not be deleted.
    + * Default: false. + * + * @return the builder + */ + public ConfigBuilder setNoCleanup() { + props.setProperty(Parameter.NO_CLEANUP.getPropertyString(), Boolean.toString(true)); + return this; + } + + /** + * If set, the volumes created during the benchmarks will not be deleted.
    + * Default: false. + * + * @return the builder + */ + public ConfigBuilder setNoCleanupVolumes() { + props.setProperty(Parameter.NO_CLEANUP_VOLUMES.getPropertyString(), Boolean.toString(true)); + return this; + } + + /** + * If set, a basefile created during benchmarks will not be deleted.
    + * Default: false. + * + * @return the builder + */ + public ConfigBuilder setNoCleanupBasefile() { + props.setProperty(Parameter.NO_CLEANUP_BASEFILE.getPropertyString(), Boolean.toString(true)); + return this; + } + + /** + * If set, a OSD Cleanup will be done at the end of all benchmarks. This might be needed to actually delete + * the storage blocks from the OSD after deleting volumes.
    + * Default: false. + * + * @return the builder + */ + public ConfigBuilder setOsdCleanup() { + props.setProperty(Parameter.OSD_CLEANUP.getPropertyString(), Boolean.toString(true)); + return this; + } + + + /** + * If set, the {@link BenchmarkConfig} will be constructed by using as many parameters as possible from the parent + * config.

    + * Only parameters which weren't set at the current builder object (at the moment of the call to + * {@link org.xtreemfs.common.benchmark.BenchmarkConfig.ConfigBuilder#build()} will be taken from the parent. + * + * @param parent + * @return + */ + public ConfigBuilder setParent(ServiceConfig parent) { + this.parent = parent; + return this; + } + + + /** + * Build the {@link BenchmarkConfig} object. + * + * @return the build {@link BenchmarkConfig} object + * @throws Exception + */ + public BenchmarkConfig build() throws Exception { + verifyNoCleanup(); + if (null != this.parent) + mergeParent(); + + /* + * if no DirAddress is given, either directly or in the parent config, first try the DefaultDirConfig, then + * use default + */ + if (null == props.getProperty("dir_service.host")) { + String[] dirAddresses = Controller.getDefaultDir(); + if (null != dirAddresses) + setDirAddresses(dirAddresses); + else + setDirAddresses(new String[]{"127.0.0.1:32638"}); + } + + BenchmarkConfig config = new BenchmarkConfig(props, this.options, this.policyAttributes); + config.setDefaults(); + + return config; + } + + private void verifyNoCleanup() { + boolean noCleanupBasefile, noCleanup, noCleanupVolumes; + noCleanupBasefile = Boolean.parseBoolean(props.getProperty(Parameter.NO_CLEANUP_BASEFILE.getPropertyString())); + noCleanup = Boolean.parseBoolean(props.getProperty(Parameter.NO_CLEANUP.getPropertyString())); + noCleanupVolumes = Boolean.parseBoolean(props.getProperty(Parameter.NO_CLEANUP_VOLUMES.getPropertyString())); + if (noCleanupBasefile && !noCleanup && !noCleanupVolumes) + throw new IllegalArgumentException("noCleanupBasefile only works with noCleanup or noCleanupVolumes"); + } + + + /* Merge props with parent props. Current props has precedence over parent */ + private void mergeParent() { + HashMap parentParameters = parent.toHashMap(); + for (Map.Entry parentEntry : parentParameters.entrySet()) { + String parentKey = parentEntry.getKey(); + String parentValue = parentEntry.getValue(); + + /* only set hitherto unset properties */ + if (null == props.getProperty(parentKey)) { + + /* Special handling for properties of type InetSocketAddress*/ + Class parentClass = ServiceConfig.Parameter.getParameterFromString(parentKey).getPropertyClass(); + if (parentClass == InetSocketAddress.class) { + setAddressSocketProperty(parentKey, parentValue); + } else { + props.setProperty(parentKey, parentValue); + } + } + } + } + + /* + * Handles properties of type InetSocketAddress + * + * Because of the String casting on InetSocketAddresses involved in parsing the configs, one ends up with a + * string looking like "/127.0.0.1:32638" or "localhost/127.0.0.1:32638". Additionally, when handling + * InetSocketAddresses, the ServiceConfig needs as input properties in the form of property.host and + * property.port (while outputting them in only as property.host in a "[hostname]/ip:port" format). + * + * @param parentKey + * + * @param parentValue + */ + private void setAddressSocketProperty(String parentKey, String parentValue) { + /* + * Ensure the format of the casted InetSocketAddress, so the string manipulations below work. Allowed format: + * "[hostname]/ipadress:port" + */ + String pattern = "[a-z]*/[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+:[0-9]+"; + if (!parentValue.matches(pattern)) + throw new IllegalArgumentException("Unknown address format for DIR adress [was: " + parentValue + + ". allowed: [hostname]/]"); + + /* Remove (optional) hostname part and the "/" separator. Only IP is used to reconstruct the property. */ + String address = parentValue.split("/")[1]; + + /* split in IP and port */ + String hostIP = address.split(":")[0]; + String port = address.split(":")[1]; + + props.setProperty(parentKey, hostIP); + props.setProperty(parentKey.replace("host", "port"), port); + } + } +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkFactory.java b/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkFactory.java new file mode 100644 index 0000000..3f365af --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkFactory.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.libxtreemfs.AdminClient; + +/** + * Instantiates a benchmark dependig on the BenchmarkType. + * + * @author jensvfischer + */ +class BenchmarkFactory { + + static AbstractBenchmark createBenchmark(long size, BenchmarkUtils.BenchmarkType benchmarkType, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) + throws Exception { + + AbstractBenchmark benchmark = null; + + switch (benchmarkType) { + case SEQ_WRITE: + benchmark = new SequentialWriteBenchmark(size, config, client, volumeManager); + break; + case SEQ_UNALIGNED_WRITE: + benchmark = new UnalignedSequentialWriteBenchmark(size, config, client, volumeManager); + break; + case SEQ_READ: + benchmark = new SequentialReadBenchmark(size, config, client, volumeManager); + break; + case RAND_WRITE: + benchmark = new RandomWriteBenchmark(size, config, client, volumeManager); + break; + case RAND_READ: + benchmark = new RandomReadBenchmark(size, config, client, volumeManager); + break; + case FILES_WRITE: + benchmark = new FilebasedWriteBenchmark(size, config, client, volumeManager); + break; + case FILES_READ: + benchmark = new FilebasedReadBenchmark(size, config, client, volumeManager); + break; + } + return benchmark; + } +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkFailedException.java b/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkFailedException.java new file mode 100644 index 0000000..fa096df --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkFailedException.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +/** + * @author jensvfischer + */ +public class BenchmarkFailedException extends Exception { + /** + * Constructs a new exception with {@code null} as its detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + */ + public BenchmarkFailedException() { + } + + /** + * Constructs a new exception with the specified detail message. The + * cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public BenchmarkFailedException(String message) { + super(message); + } + + /** + * Constructs a new exception with the specified detail message and + * cause.

    Note that the detail message associated with + * {@code cause} is not automatically incorporated in + * this exception's detail message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public BenchmarkFailedException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new exception with the specified cause and a detail + * message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of cause). + * This constructor is useful for exceptions that are little more than + * wrappers for other throwables (for example, {@link + * java.security.PrivilegedActionException}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public BenchmarkFailedException(Throwable cause) { + super(cause); + } +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkResult.java b/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkResult.java new file mode 100644 index 0000000..5f9a882 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkResult.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import static org.xtreemfs.common.benchmark.BenchmarkUtils.BenchmarkType; + +/** + * Result object for benchmarks. + * + * @author jensvfischer + */ +public class BenchmarkResult implements Comparable { + + private BenchmarkType benchmarkType; + private int numberOfReadersOrWriters; + private double timeInSec; + private long requestedSize; + private long actualSize; + private boolean failed; + private Throwable error; + + public BenchmarkResult(double timeInSec, long requestedSize, long actualSize) { + this.timeInSec = timeInSec; + this.requestedSize = requestedSize; + this.actualSize = actualSize; + this.failed = false; + } + + public BenchmarkResult(double timeInSec, long actualSize, int numberOfReadersOrWriters, BenchmarkType benchmarkType) { + this.benchmarkType = benchmarkType; + this.numberOfReadersOrWriters = numberOfReadersOrWriters; + this.timeInSec = timeInSec; + this.actualSize = actualSize; + } + + public BenchmarkResult(Throwable error) { + this.failed = true; + this.error = error; + } + + void setBenchmarkType(BenchmarkType benchmarkType) { + this.benchmarkType = benchmarkType; + } + + void setNumberOfReadersOrWriters(int numberOfReadersOrWriters) { + this.numberOfReadersOrWriters = numberOfReadersOrWriters; + } + + /** + * Get the type of the benchmark. + *

    + * + * The benchmark type is one of the following: + * + *

      + *
    • SEQ_WRITE: Sequential write benchmark
    • + *
    • SEQ_READ: Sequential read benchmark
    • + *
    • RAND_WRITE: Random write benchmark
    • + *
    • RAND_READ: Random read benchmark
    • + *
    • FILES_WRITE: Filebased write benchmark
    • + *
    • FILES_READ: Filebased read benchmark
    • + *
    + * + * + * @return the type of the benchmark + */ + public BenchmarkType getBenchmarkType() { + return benchmarkType; + } + + /** + * Get the number of parallel benchmark threads. + * + * @return the number of parallel benchmark threads + */ + public int getNumberOfReadersOrWriters() { + return numberOfReadersOrWriters; + } + + /** + * Get the number of seconds the benchmark run took. + * + * @return the number of seconds the benchmark run took + */ + public double getTimeInSec() { + return timeInSec; + } + + /** + * Get the size, the benchmark was requested to write or read. + * + * @return the benchmark size in bytes + */ + public long getRequestedSize() { + return requestedSize; + } + + /** + * Get the count of requests actually written or red by the benchmark (should be equal to {@link #getRequestedSize()}). + * + * @return the number of requests written or red by the benchmark + */ + public long getActualSize() { + return actualSize; + } + + public Throwable getError() { + return error; + } + + /** + * Returns true, if the benchmark is either a sequential write benchmark, a random write benchmark or a filebased write benchmark. + * + * @return true, if the benchmark is a write benchmark + */ + public boolean isWriteBenchmark(){ + return benchmarkType == BenchmarkType.SEQ_WRITE || benchmarkType == BenchmarkType.RAND_WRITE + || benchmarkType == BenchmarkType.FILES_WRITE; + } + + /** + * Returns true, if the benchmark is either a sequential read benchmark, a random read benchmark or a filebased read benchmark. + * + * @return true, if the benchmark is a read benchmark + */ + public boolean isReadBenchmark(){ + return benchmarkType == BenchmarkType.SEQ_READ || benchmarkType == BenchmarkType.RAND_READ + || benchmarkType == BenchmarkType.FILES_READ; + } + + public boolean isFailed() { + return failed; + } + + @Override + public int compareTo(BenchmarkResult otherResult) { + return benchmarkType.toString().compareTo(otherResult.benchmarkType.toString()); + } +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkUtils.java b/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkUtils.java new file mode 100644 index 0000000..a352a63 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/BenchmarkUtils.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +/** + * Util class for the Benchmarks + * + * @author jensvfischer + * + */ +public class BenchmarkUtils { + + public static final int KiB_IN_BYTES = 1024; + public static final int MiB_IN_BYTES = 1024 * 1024; + public static final int GiB_IN_BYTES = 1024 * 1024 * 1024; + + /** + * Enum for the different benchmark Types. + */ + public static enum BenchmarkType { + SEQ_WRITE, SEQ_UNALIGNED_WRITE, SEQ_READ, RAND_WRITE, RAND_READ, FILES_WRITE, FILES_READ + } +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/ClientManager.java b/java/servers/src/org/xtreemfs/common/benchmark/ClientManager.java new file mode 100644 index 0000000..0490a40 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/ClientManager.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.Client; +import org.xtreemfs.common.libxtreemfs.ClientFactory; +import org.xtreemfs.foundation.logging.Logging; + +import java.util.LinkedList; + +/** + * Handles client creation, startup and deletion centrally. + *

    + * getNewClient() can be used to get an already started client. shutdownClients() is used to shutdown all clients + * created so far. + * + * @author jensvfischer + */ +class ClientManager { + + private LinkedList clients; + private BenchmarkConfig config; + + ClientManager(BenchmarkConfig config) { + this.clients = new LinkedList(); + this.config = config; + } + + /* create and start an AdminClient. */ + AdminClient getNewClient() throws Exception { + AdminClient client = ClientFactory.createAdminClient(config.getDirAddresses(), config.getUserCredentials(), + config.getSslOptions(), config.getOptions()); + clients.add(client); + client.start(); + return client; + } + + /* shutdown all clients */ + void shutdownClients() { + for (AdminClient client : clients) { + tryShutdownOfClient(client); + } + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, ClientManager.class, + "Shutting down %s clients", clients.size()); + } + + + private void tryShutdownOfClient(Client client) { + try { + client.shutdown(); + } catch (Throwable e) { + Logging.logMessage(Logging.LEVEL_WARN, Logging.Category.tool, ClientManager.class, + "Error while shutting down clients"); + Logging.logError(Logging.LEVEL_WARN, ClientManager.class, e); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/Controller.java b/java/servers/src/org/xtreemfs/common/benchmark/Controller.java new file mode 100644 index 0000000..acba0ee --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/Controller.java @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR; +import org.xtreemfs.utils.DefaultDirConfig; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.concurrent.*; + +import static org.xtreemfs.common.benchmark.BenchmarkUtils.BenchmarkType; +import static org.xtreemfs.foundation.logging.Logging.LEVEL_INFO; +import static org.xtreemfs.foundation.logging.Logging.logError; +import static org.xtreemfs.foundation.logging.Logging.logMessage; + +/** + * Controller for the benchmark library. + *

    + * + * The {@link Controller} and {@link BenchmarkConfig} represent the API to the benchmark library. + * + * @author jensvfischer + * + */ +public class Controller { + + private BenchmarkConfig config; + private ClientManager clientManager; + private VolumeManager volumeManager; + private ThreadPoolExecutor threadPool; + + /** + * Create a new controller object. + * + * @param config + * The parameters to be used for the benchmark. + */ + public Controller(BenchmarkConfig config) throws Exception { + this.config = config; + this.clientManager = new ClientManager(config); + this.volumeManager = new VolumeManager(config, clientManager.getNewClient()); + Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandlerBenchmark(this)); + } + + /** + * Create and open the volumes needed for the benchmarks.
    + * If the volumeNames given are already existing volumes, the volumes are only opened.
    + * + * @param volumeNames + * the volumes to be created/opened + * @throws Exception + */ + public void setupVolumes(String... volumeNames) throws Exception { + if (volumeNames.length < 1) + throw new IllegalArgumentException("Number of volumes < 1"); + else + volumeManager.openVolumes(volumeNames); + } + + /** + * Create and open default volumes for the benchmarks.
    + * The volumes will be created with the options given by {@link BenchmarkConfig}. + * + * @param numberOfVolumes the number of volumes to be created + * @throws Exception + */ + public void setupDefaultVolumes(int numberOfVolumes) throws Exception { + if (numberOfVolumes < 1) + throw new IllegalArgumentException("Number of volumes < 1"); + else + volumeManager.createDefaultVolumes(numberOfVolumes); + } + + + /** + * Starts sequential write benchmarks with the parameters specified in the {@link BenchmarkConfig}.
    + * + * @return the results of the benchmark (see {@link BenchmarkResult}) + * @throws Exception + */ + public ArrayList startSequentialWriteBenchmark(long size, int numberOfThreads) throws Exception { + verifySizesAndThreads(size, numberOfThreads, BenchmarkType.SEQ_WRITE); + return startBenchmark(size, numberOfThreads, BenchmarkType.SEQ_WRITE); + } + + /** + * Starts unaligned sequential write benchmarks with the parameters specified in the {@link BenchmarkConfig}.
    + * + * @return the results of the benchmark (see {@link BenchmarkResult}) + * @throws Exception + */ + public ArrayList startUnalignedSequentialWriteBenchmark(long size, int numberOfThreads) throws Exception { + verifySizesAndThreads(size, numberOfThreads, BenchmarkType.SEQ_UNALIGNED_WRITE); + return startBenchmark(size, numberOfThreads, BenchmarkType.SEQ_UNALIGNED_WRITE); + } + + /** + * Starts sequential read benchmarks with the parameters specified in the {@link BenchmarkConfig}.
    + * + * @return the results of the benchmark (see {@link BenchmarkResult}) + * @throws Exception + */ + public ArrayList startSequentialReadBenchmark(long size, int numberOfThreads) throws Exception { + verifySizesAndThreads(size, numberOfThreads, BenchmarkType.SEQ_READ); + return startBenchmark(size, numberOfThreads, BenchmarkType.SEQ_READ); + } + + /** + * Starts random write benchmarks with the parameters specified in the {@link BenchmarkConfig}.
    + * + * @return the results of the benchmark (see {@link BenchmarkResult}) + * @throws Exception + */ + public ArrayList startRandomWriteBenchmark(long size, int numberOfThreads) throws Exception { + verifySizesAndThreads(size, numberOfThreads, BenchmarkType.RAND_WRITE); + return startBenchmark(size, numberOfThreads, BenchmarkType.RAND_WRITE); + } + + /** + * Starts random read benchmarks with the parameters specified in the {@link BenchmarkConfig}.
    + * + * @return the results of the benchmark (see {@link BenchmarkResult}) + * @throws Exception + */ + public ArrayList startRandomReadBenchmark(long size, int numberOfThreads) throws Exception { + verifySizesAndThreads(size, numberOfThreads, BenchmarkType.RAND_READ); + return startBenchmark(size, numberOfThreads, BenchmarkType.RAND_READ); + } + + /** + * Starts filebased write benchmarks with the parameters specified in the {@link BenchmarkConfig}.
    + * + * @return the results of the benchmark (see {@link BenchmarkResult}) + * @throws Exception + */ + public ArrayList startFilebasedWriteBenchmark(long size, int numberOfThreads) throws Exception { + verifySizesAndThreads(size, numberOfThreads, BenchmarkType.FILES_WRITE); + return startBenchmark(size, numberOfThreads, BenchmarkType.FILES_WRITE); + } + + /** + * Starts filebased read benchmarks with the parameters specified in the {@link BenchmarkConfig}.
    + * + * @return the results of the benchmark (see {@link BenchmarkResult}) + * @throws Exception + */ + public ArrayList startFilebasedReadBenchmark(long size, int numberOfThreads) throws Exception { + verifySizesAndThreads(size, numberOfThreads, BenchmarkType.FILES_READ); + return startBenchmark(size, numberOfThreads, BenchmarkType.FILES_READ); + } + + public void tryConnection() throws Exception { + try { + clientManager.getNewClient().getServiceByType(DIR.ServiceType.SERVICE_TYPE_OSD); + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_ERROR, Logging.Category.tool, Controller.class, + "Failed to establish connection to DIR server."); + throw e; + } + } + + /** + * Get the DIR address from default_dir + * + * @return the DIR address, or null if default_dir wasn't found or couldn't be accessed. + */ + public static String[] getDefaultDir() { + String[] dirAddresses; + DefaultDirConfig cfg = null; + try { + cfg = new DefaultDirConfig(); + dirAddresses = cfg.getDirectoryServices(); + return dirAddresses; + } catch (IOException e) { + logMessage(LEVEL_INFO, Logging.Category.tool, Controller.class, + "Could not access or find Default DIR Config in %s. Using default (localhost).", + DefaultDirConfig.DEFAULT_DIR_CONFIG); + return null; + } + } + + /** + * Deletes all created volumes and files and shuts down all clients. This method should be called when all + * benchmarks are finished. The deletion of the volumes and files is regulated by the noCleanup options in + * {@link BenchmarkConfig}. + * + * @throws Exception + */ + public void teardown() throws Exception { + deleteVolumesAndFiles(); + if (config.isOsdCleanup()) + volumeManager.cleanupOSD(); + shutdownClients(); + shutdownThreadPool(); + } + + private void verifySizesAndThreads(long size, int threads, BenchmarkType type) { + if ((type == BenchmarkType.SEQ_READ) || (type == BenchmarkType.SEQ_WRITE)) { + if (size % (config.getStripeSizeInBytes() * config.getStripeWidth()) != 0) + throw new IllegalArgumentException("size of " + type + + " must satisfy: size mod (stripeSize * stripeWidth) == 0"); + if (size < config.getChunkSizeInBytes()) + throw new IllegalArgumentException("Chunksize < size of " + type); + } + if ((type == BenchmarkType.RAND_READ) || (type == BenchmarkType.RAND_WRITE)) { + if (config.getBasefileSizeInBytes() < size) + throw new IllegalArgumentException("Basefile < size of " + type); + if (size < config.getChunkSizeInBytes()) + throw new IllegalArgumentException("Chunksize < size of " + type); + } + if ((type == BenchmarkType.FILES_WRITE) || (type == BenchmarkType.FILES_READ)) { + if (size % config.getFilesize() != 0) + throw new IllegalArgumentException("Size of " + type + " must satisfy: size mod filesize == 0"); + } + if (volumeManager.getVolumes().size() < threads ) + throw new IllegalArgumentException("Less volumes than parallel threads"); + } + + /* + * Starts benchmarks in parallel. Every benchmark is started within its own thread. The method waits for all threads + * to finish. + */ + private ArrayList startBenchmark(long size, int numberOfThreads, BenchmarkType benchmarkType) + throws Exception { + + checkThreadPool(numberOfThreads); + + CompletionService completionService = new ExecutorCompletionService(threadPool); + ArrayList> futures = new ArrayList>(); + + /* create and start all benchmark tasks (i.e. submit to CompletionService) */ + for (int i = 0; i < numberOfThreads ; i++) { + AbstractBenchmark benchmark = BenchmarkFactory.createBenchmark(size, benchmarkType, config, clientManager.getNewClient(), volumeManager); + benchmark.prepareBenchmark(); + Future future = completionService.submit(benchmark); + futures.add(future); + } + + ArrayList results = awaitCompletion(numberOfThreads, completionService, futures); + + /* Set BenchmarkResult type and number of threads */ + for (BenchmarkResult res : results) { + res.setBenchmarkType(benchmarkType); + res.setNumberOfReadersOrWriters(numberOfThreads); + } + + /* reset VolumeManager to prepare for possible consecutive benchmarks */ + volumeManager.reset(); + + return results; + } + + private void checkThreadPool(int numberOfThreads) throws InterruptedException { + /* check if a thread pool is already instantiated */ + if (null == threadPool) + threadPool = new ThreadPoolExecutor(numberOfThreads, numberOfThreads, 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue()); + /* check if thread pool has the needed number of threads, adjust if necessary */ + else if (threadPool.getPoolSize() != numberOfThreads){ + threadPool.setCorePoolSize(numberOfThreads); + threadPool.setMaximumPoolSize(numberOfThreads); + } + } + + + private ArrayList awaitCompletion(int numberOfThreads, CompletionService completionService, ArrayList> futures) throws Exception { + ArrayList results = new ArrayList(numberOfThreads); + Exception exception = null; + /* wait for all threads to finish */ + for (int i = 0; i < numberOfThreads; i++) { + try { + Future benchmarkResultFuture = completionService.take(); + futures.remove(benchmarkResultFuture); + BenchmarkResult result = benchmarkResultFuture.get(); + results.add(result); + } catch (ExecutionException e) { + logMessage(Logging.LEVEL_ERROR, Logging.Category.tool, this, "An exception occurred within an benchmark task."); + logError(Logging.LEVEL_ERROR, this, e.getCause()); + /* cancel all other running benchmark tasks in case of failure in one task */ + for (Future future : futures) {future.cancel(true);} + /* + * Future.cancel(true) works by setting the interrupted flag. In some cases the cancellation doesn't + * work (the query of the interrupted status returns false). Most likely the interrupted status is + * consumed somewhere without causing the task to stop or to reach the toplevel task code (the code in + * the XYBenchmark classes). This could be due to catching an InterruptedException exception or calling + * Thread.interrupted() (both consumes the flag status) without reestablishing the status with + * Thread.currentThread().interrupt(). Therefore an additional cancellation needs to be deployed... + */ + AbstractBenchmark.cancel(); + exception = e; + } catch (CancellationException e) { + // consume (planned cancellation from calling future.cancel()) + logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "Benchmark task has been canceled due to an exception in another benchmark task."); + } + } + if (null != exception) + throw new BenchmarkFailedException(exception.getCause()); + return results; + } + + /* delete all created volumes and files depending on the noCleanup options */ + void deleteVolumesAndFiles() { + if (!config.isNoCleanup() && !config.isNoCleanupVolumes()) { + volumeManager.deleteCreatedFiles(); // is needed in case no volume was created + volumeManager.deleteCreatedVolumes(); + } else if (!config.isNoCleanup()) + volumeManager.deleteCreatedFiles(); + } + + void shutdownClients() { + clientManager.shutdownClients(); + } + + void shutdownThreadPool(){ + if (threadPool != null) + threadPool.shutdownNow(); + } +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/FilebasedBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/FilebasedBenchmark.java new file mode 100644 index 0000000..7d461d1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/FilebasedBenchmark.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.libxtreemfs.AdminClient; + +/** + * Abstract baseclass for filebased benchmarks. + *

    + * A filebased benchmark writes or reads lots of small files. + * + * @author jensvfischer + */ +abstract class FilebasedBenchmark extends AbstractBenchmark { + + static final String BENCHMARK_FILENAME = "benchmarks/randomBenchmark/benchFile"; + final int filesize; + + FilebasedBenchmark(long size, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) throws Exception { + super(size, config, client, volumeManager); + this.filesize = config.getFilesize(); + } + + static String getBenchmarkFilename() { + return BENCHMARK_FILENAME; + } +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/FilebasedReadBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/FilebasedReadBenchmark.java new file mode 100644 index 0000000..9dbfa4f --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/FilebasedReadBenchmark.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.FileHandle; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; + +import java.io.IOException; +import java.util.Random; + +/** + * Class implementing a filebased read benchmark. + * + * @author jensvfischer + */ +class FilebasedReadBenchmark extends FilebasedBenchmark { + + private String[] filenames; + + FilebasedReadBenchmark(long size, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) throws Exception { + super(size, config, client, volumeManager); + } + + @Override + void prepareBenchmark() throws Exception { + this.filenames = volumeManager.getRandomFilelistForVolume(volume, benchmarkSize); + } + + /* Called within the benchmark method. Performs the actual reading of data from the volume. */ + @Override + long performIO(byte[] data, long numberOfBlocks) throws IOException { + + long numberOfFilesToRead = benchmarkSize / filesize; + + int filenamesSize = filenames.length; + long byteCounter = 0; + Random random = new Random(); + + int flags = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber(); + + for (long i = 0; !cancelled && i < numberOfFilesToRead; i++) { + String filename = filenames[random.nextInt(filenamesSize)]; + FileHandle fileHandle = volume.openFile(config.getUserCredentials(), filename, flags); + + if (filesize <= requestSize) { + random.nextBytes(data); + byteCounter += fileHandle.read(config.getUserCredentials(), data, filesize, 0); + } else + for (long j = 0; j < filesize / requestSize; j++) { + long nextOffset = j * requestSize; + assert nextOffset >= 0 : "Offset < 0 not allowed"; + byteCounter += fileHandle.read(config.getUserCredentials(), data, requestSize, nextOffset); + } + fileHandle.close(); + } + return byteCounter; + } + + @Override + void finalizeBenchmark() throws Exception { + } + +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/FilebasedWriteBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/FilebasedWriteBenchmark.java new file mode 100644 index 0000000..1abf7a4 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/FilebasedWriteBenchmark.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.FileHandle; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.Random; + +/** + * Class implementing a filebased write benchmark. + * + * @author jensvfischer + */ +class FilebasedWriteBenchmark extends FilebasedBenchmark { + + private LinkedList filenames; + + FilebasedWriteBenchmark(long size, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) throws Exception { + super(size, config, client, volumeManager); + filenames = new LinkedList(); + } + + @Override + void prepareBenchmark() throws Exception { + } + + /* Called within the benchmark method. Performs the actual reading of data from the volume. */ + @Override + long performIO(byte[] data, long numberOfBlocks) throws IOException { + + long numberOfFiles = benchmarkSize / filesize; + long byteCounter = 0; + Random random = new Random(); + + int flags = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + + for (long i = 0; !cancelled && i < numberOfFiles; i++) { + FileHandle fileHandle = volume.openFile(config.getUserCredentials(), BENCHMARK_FILENAME + i, flags, 511); + this.filenames.add(BENCHMARK_FILENAME + i); + + if (filesize <= requestSize) { + random.nextBytes(data); + byteCounter += fileHandle.write(config.getUserCredentials(), data, filesize, 0); + } else + for (long j = 0; j < filesize / requestSize; j++) { + long nextOffset = j * requestSize; + assert nextOffset >= 0 : "Offset < 0 not allowed"; + random.nextBytes(data); + byteCounter += fileHandle.write(config.getUserCredentials(), data, requestSize, nextOffset); + } + fileHandle.close(); + } + return byteCounter; + } + + @Override + void finalizeBenchmark() throws Exception { + volumeManager.setRandomFilelistForVolume(volume, filenames); + volumeManager.addCreatedFiles(volume, filenames); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/RandomOffsetbasedBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/RandomOffsetbasedBenchmark.java new file mode 100644 index 0000000..7456f21 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/RandomOffsetbasedBenchmark.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.FileHandle; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; + +import java.util.LinkedList; +import java.util.Random; + +/** + * Abstract baseclass for random IO benchmarks. + *

    + * Random IO benchmarks write or read small blocks with random offsets within a large basefile. + * + * @author jensvfischer + */ +abstract class RandomOffsetbasedBenchmark extends AbstractBenchmark { + final static int RANDOM_IO_BLOCKSIZE = 1024 * 4; // 4 KiB + final long sizeOfBasefile; + final static String BASFILE_FILENAME = "benchmarks/basefile"; + + RandomOffsetbasedBenchmark(long size, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) throws Exception { + super(size, config, client, volumeManager); + sizeOfBasefile = config.getBasefileSizeInBytes(); + } + + @Override + void prepareBenchmark() throws Exception { + /* create file to read from if not existing */ + if (basefileDoesNotExists()) { + createBasefile(); + } + } + + @Override + void finalizeBenchmark() { + } + + /* convert to 4 KiB Blocks */ + long convertTo4KiBBlocks(long numberOfBlocks) { + return (numberOfBlocks * (long) requestSize) / (long) RANDOM_IO_BLOCKSIZE; + } + + long generateNextRandomOffset() { + long nextOffset = Math.round(Math.random() * (sizeOfBasefile - (long) RANDOM_IO_BLOCKSIZE)); + assert nextOffset >= 0 : "Offset < 0. Offset: " + nextOffset + " Basefilesize: " + sizeOfBasefile; + assert nextOffset <= (sizeOfBasefile - RANDOM_IO_BLOCKSIZE) : " Offset > Filesize. Offset: " + nextOffset + + "Basefilesize: " + sizeOfBasefile; + return nextOffset; + } + + /* check if a basefile to read from exists and if it has the right size */ + boolean basefileDoesNotExists() throws Exception { + try { + FileHandle fileHandle = volume.openFile(config.getUserCredentials(), BASFILE_FILENAME, + GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + long fileSizeInBytes = fileHandle.getAttr(config.getUserCredentials()).getSize(); + fileHandle.close(); + return sizeOfBasefile != fileSizeInBytes; + } catch (PosixErrorException e) { + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "No basefile found."); + return true; + } + } + + /* Create a large file to read from */ + private void createBasefile() throws Exception { + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, + "Start creating a basefile of size %s bytes.", sizeOfBasefile); + long numberOfBlocks = sizeOfBasefile / (long) requestSize; + Random random = new Random(); + int flags = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + FileHandle fileHandle = volume.openFile(config.getUserCredentials(), BASFILE_FILENAME, flags, 511); + long byteCounter = 0; + byte[] data = new byte[requestSize]; + for (long j = 0; j < numberOfBlocks; j++) { + long nextOffset = j * requestSize; + assert nextOffset >= 0 : "Offset < 0 not allowed"; + random.nextBytes(data); + byteCounter += fileHandle.write(config.getUserCredentials(), data, requestSize, nextOffset); + } + fileHandle.close(); + assert byteCounter == sizeOfBasefile : " Error while writing the basefile for the random io benchmark"; + + addBasefileToCreatedFiles(); + + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "Basefile written. Size %s Bytes.", + byteCounter); + + } + + private void addBasefileToCreatedFiles() throws Exception { + if (!config.isNoCleanupBasefile()) { + LinkedList createdFiles = new LinkedList(); + createdFiles.add(BASFILE_FILENAME); + volumeManager.addCreatedFiles(volume, createdFiles); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/RandomReadBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/RandomReadBenchmark.java new file mode 100644 index 0000000..818a974 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/RandomReadBenchmark.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.FileHandle; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; + +import java.io.IOException; + +/** + * Class implementing a random IO read benchmarks. + *

    + * A random IO read benchmarks reads small blocks with random offsets within a large basefile. + * + * @author jensvfischer + */ +class RandomReadBenchmark extends RandomOffsetbasedBenchmark { + + RandomReadBenchmark(long size, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) throws Exception { + super(size, config, client, volumeManager); + } + + /* Called within the benchmark method. Performs the actual reading of data from the volume. */ + @Override + long performIO(byte[] data, long numberOfBlocks) throws IOException { + + numberOfBlocks = convertTo4KiBBlocks(numberOfBlocks); + long byteCounter = 0; + + for (long j = 0; !cancelled && j < numberOfBlocks; j++) { + FileHandle fileHandle = volume.openFile(config.getUserCredentials(), BASFILE_FILENAME, + GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + long nextOffset = generateNextRandomOffset(); + byteCounter += fileHandle.read(config.getUserCredentials(), data, RANDOM_IO_BLOCKSIZE, nextOffset); + fileHandle.close(); + } + return byteCounter; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/RandomWriteBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/RandomWriteBenchmark.java new file mode 100644 index 0000000..ad184e8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/RandomWriteBenchmark.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.FileHandle; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; + +import java.io.IOException; +import java.util.Random; + +/** + * Class implementing a random IO read benchmarks. + *

    + * A random IO read benchmarks reads small blocks with random offsets within a large basefile. + * + * @author jensvfischer + */ +class RandomWriteBenchmark extends RandomOffsetbasedBenchmark { + + RandomWriteBenchmark(long size, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) throws Exception { + super(size, config, client, volumeManager); + } + + /* Called within the benchmark method. Performs the actual reading of data from the volume. */ + @Override + long performIO(byte[] data, long numberOfBlocks) throws IOException { + + Random random = new Random(); + + numberOfBlocks = convertTo4KiBBlocks(numberOfBlocks); + long byteCounter = 0; + + int flags = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_WRONLY.getNumber(); + + for (long j = 0; !cancelled && j < numberOfBlocks; j++) { + FileHandle fileHandle = volume.openFile(config.getUserCredentials(), BASFILE_FILENAME, flags, 511); + long nextOffset = generateNextRandomOffset(); + random.nextBytes(data); + byteCounter += fileHandle.write(config.getUserCredentials(), data, RANDOM_IO_BLOCKSIZE, nextOffset); + fileHandle.close(); + } + + return byteCounter; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/SequentialBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/SequentialBenchmark.java new file mode 100644 index 0000000..e2811a8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/SequentialBenchmark.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.libxtreemfs.AdminClient; + +/** + * Abstract baseclass for sequential benchmarks. + * + * @author jensvfischer + */ +abstract class SequentialBenchmark extends AbstractBenchmark { + + static final String BENCHMARK_FILENAME = "benchmarks/sequentialBenchmark/benchFile"; + + SequentialBenchmark(long size, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) throws Exception { + super(size, config, client, volumeManager); + } + + @Override + void prepareBenchmark() throws Exception { + } + + @Override + void finalizeBenchmark() throws Exception { + } + + static String getBenchmarkFilename() { + return BENCHMARK_FILENAME; + } +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/SequentialReadBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/SequentialReadBenchmark.java new file mode 100644 index 0000000..1368d27 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/SequentialReadBenchmark.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.FileHandle; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; + +import java.io.IOException; + +/** + * Class implementing a sequential read benchmark. + * + * @author jensvfischer + */ +class SequentialReadBenchmark extends SequentialBenchmark { + private String[] filenames; + + SequentialReadBenchmark(long size, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) throws Exception { + super(size, config, client, volumeManager); + } + + @Override + void prepareBenchmark() throws Exception { + this.filenames = volumeManager.getSequentialFilelistForVolume(volume, benchmarkSize); + } + + /* Called within the benchmark method. Performs the actual reading of data from the volume. */ + @Override + long performIO(byte[] data, long numberOfBlocks) throws IOException { + FileHandle fileHandle = volume.openFile(config.getUserCredentials(), filenames[0], + GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + try { + return tryPerformIO(data, numberOfBlocks, fileHandle); + } catch (IOException e) { + /* closing the filehandle manually seems to be the only way to avoid an AssertionError in + * VolumeImplementation.internalShutdown() when shutting down client */ + fileHandle.close(); + throw e; + } + } + + + private long tryPerformIO(byte[] data, long numberOfBlocks, FileHandle fileHandle) throws IOException { + long byteCounter = 0; + for (long j = 0; !cancelled && j < numberOfBlocks; j++) { + long nextOffset = j * requestSize; + assert nextOffset >= 0 : "Offset < 0 not allowed"; + byteCounter += fileHandle.read(config.getUserCredentials(), data, requestSize, nextOffset); + } + fileHandle.close(); + return byteCounter; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/SequentialWriteBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/SequentialWriteBenchmark.java new file mode 100644 index 0000000..7a8c6b9 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/SequentialWriteBenchmark.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.Random; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.FileHandle; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; + +/** + * Class implementing a sequential write benchmark. + * + * @author jensvfischer + */ +class SequentialWriteBenchmark extends SequentialBenchmark { + + private LinkedList filenames; + + SequentialWriteBenchmark(long size, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) + throws Exception { + super(size, config, client, volumeManager); + filenames = new LinkedList(); + } + + /* Called within the benchmark method. Performs the actual writing of data to the volume. */ + @Override + long performIO(byte[] data, long numberOfBlocks) throws IOException { + + int flags = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + FileHandle fileHandle = volume.openFile(config.getUserCredentials(), BENCHMARK_FILENAME + 0, flags, 511); + + try { + return tryPerformIO(data, numberOfBlocks, fileHandle); + } catch (IOException e) { + /* closing the filehandle manually seems to be the only way to avoid an AssertionError in + * VolumeImplementation.internalShutdown() when shutting down client */ + fileHandle.close(); + throw e; + } + } + + private long tryPerformIO(byte[] data, long numberOfBlocks, FileHandle fileHandle) throws IOException { + Random random = new Random(); + this.filenames.add(BENCHMARK_FILENAME + 0); + long byteCounter = 0; + + for (long j = 0; !cancelled && j < numberOfBlocks; j++) { + long nextOffset = j * requestSize; + assert nextOffset >= 0 : "Offset < 0 not allowed"; + random.nextBytes(data); + byteCounter += fileHandle.write(config.getUserCredentials(), data, requestSize, nextOffset); + } + fileHandle.close(); + return byteCounter; + } + + @Override + void finalizeBenchmark() throws Exception { + volumeManager.setSequentialFilelistForVolume(volume, filenames); + volumeManager.addCreatedFiles(volume, filenames); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/UnalignedSequentialWriteBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/UnalignedSequentialWriteBenchmark.java new file mode 100644 index 0000000..3beb257 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/UnalignedSequentialWriteBenchmark.java @@ -0,0 +1,61 @@ +package org.xtreemfs.common.benchmark; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.Random; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.FileHandle; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; + +public class UnalignedSequentialWriteBenchmark extends SequentialBenchmark { + + private final LinkedList filenames; + + UnalignedSequentialWriteBenchmark(long size, BenchmarkConfig config, AdminClient client, VolumeManager volumeManager) + throws Exception { + super(size, config, client, volumeManager); + filenames = new LinkedList(); + } + + @Override + long performIO(byte[] data, long numberOfBlocks) throws IOException { + int flags = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + FileHandle fileHandle = volume.openFile(config.getUserCredentials(), BENCHMARK_FILENAME + 0, flags, 0777); + + try { + return tryPerformIO(data, numberOfBlocks, fileHandle); + } catch (IOException e) { + /* + * closing the filehandle manually seems to be the only way to avoid an AssertionError in + * VolumeImplementation.internalShutdown() when shutting down client + */ + fileHandle.close(); + throw e; + } + } + + private long tryPerformIO(byte[] data, long numberOfBlocks, FileHandle fileHandle) throws IOException { + Random random = new Random(); + this.filenames.add(BENCHMARK_FILENAME + 0); + long byteCounter = 0; + + for (long j = 0; !cancelled && j < numberOfBlocks; j++) { + long stripesPerRequest = (long) Math.ceil((double) requestSize / (double) config.getStripeSizeInBytes()); + long nextOffset = j * stripesPerRequest * config.getStripeSizeInBytes(); + random.nextBytes(data); + byteCounter += fileHandle.write(config.getUserCredentials(), data, requestSize, nextOffset); + } + fileHandle.close(); + return byteCounter; + } + + @Override + void finalizeBenchmark() throws Exception { + volumeManager.setSequentialFilelistForVolume(volume, filenames); + volumeManager.addCreatedFiles(volume, filenames); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/UncaughtExceptionHandlerBenchmark.java b/java/servers/src/org/xtreemfs/common/benchmark/UncaughtExceptionHandlerBenchmark.java new file mode 100644 index 0000000..4ba93b2 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/UncaughtExceptionHandlerBenchmark.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import org.xtreemfs.foundation.logging.Logging; + +/** + * UncaughtExceptionHandler for the benchmark tool. + *

    + * + * Shuts down all benchmarks and cleans up in case of uncaught exceptions. + * + * @author jensvfischer + */ +class UncaughtExceptionHandlerBenchmark implements Thread.UncaughtExceptionHandler { + + private Controller controller; + + UncaughtExceptionHandlerBenchmark(Controller controller) { + this.controller = controller; + } + + /** + * Method invoked when the given thread terminates due to the given uncaught exception. + *

    + * Any exception thrown by this method will be ignored by the Java Virtual Machine. + * + * @param t + * the thread + * @param e + * the exception + */ + @Override + public void uncaughtException(Thread t, Throwable e) { + + Logging.logMessage(Logging.LEVEL_ERROR, this, + "An uncaught exception was thrown in %s (Thread-Id: %s). The benchmark tool will be shut down.", t.getName(), t.getId()); + Logging.logError(Logging.LEVEL_ERROR, this, e); + + controller.deleteVolumesAndFiles(); + controller.shutdownClients(); + controller.shutdownThreadPool(); + } +} diff --git a/java/servers/src/org/xtreemfs/common/benchmark/VolumeManager.java b/java/servers/src/org/xtreemfs/common/benchmark/VolumeManager.java new file mode 100644 index 0000000..6d70804 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/benchmark/VolumeManager.java @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.benchmark; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.Volume; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC; + +/** + * Volume Manager (Singleton). + *

    + * + * Class for managing volumes in the benchmark tools. Allows for the creation and deletion of volumes, manages the + * assignment of volumes to benchmark threads and does bookkeeping of created files and volumes. + *

    + * The bookkeeping of created volumes is necessary for the deletion (only) of created volumes and files as well as for + * the filebased benchmarks. + * + * @author jensvfischer + */ +class VolumeManager { + + private static final String VOLUME_BASE_NAME = "benchmark"; + + private BenchmarkConfig config; + private AdminClient client; + private int currentPosition; + private LinkedList volumes; + private LinkedList createdVolumes; + private HashMap> createdFiles; + private HashMap filelistsSequentialBenchmark; + private HashMap filelistsRandomBenchmark; + + VolumeManager(BenchmarkConfig config, AdminClient client) throws Exception { + this.config = config; + currentPosition = 0; + this.client = client; + this.volumes = new LinkedList(); + this.createdVolumes = new LinkedList(); + this.filelistsSequentialBenchmark = new HashMap(5); + this.filelistsRandomBenchmark = new HashMap(5); + this.createdFiles = new HashMap>(); + } + + /* cycles through the list of volumes to assign to volumes to benchmarks */ + Volume getNextVolume() { + return volumes.get(currentPosition++); + } + + /* + * reset the position counter of the volume list. Needs to be called if one wants to reuse the volumes for a + * consecutive benchmark + */ + void reset() { + currentPosition = 0; + } + + /* used if no volumes were specified */ + void createDefaultVolumes(int numberOfVolumes) throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException { + for (int i = 0; i < numberOfVolumes; i++) { + Volume volume = createAndOpenVolume(VOLUME_BASE_NAME + i); + addToVolumes(volume); + } + } + + /* add a volume to the volume list */ + private void addToVolumes(Volume volume) { + if (!volumes.contains(volume)) + volumes.add(volume); + } + + /* opens multiple volumes (and creates and opens volumes if they do not exist) */ + void openVolumes(String... volumeName) throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException { + this.volumes = new LinkedList(); + for (String each : volumeName) { + volumes.add(createAndOpenVolume(each)); + } + verifyVolumeSizes(); + } + + /* opens a single volume (or creates and opens a volume if it does not exist) */ + private Volume createAndOpenVolume(String volumeName) throws IOException, IllegalAccessException, ClassNotFoundException, InstantiationException { + + Volume volume = null; + try { /* try creating the volume */ + List volumeAttributes = new ArrayList(); + client.createVolume(config.getAuth(), config.getUserCredentials(), volumeName, 511, config.getUsername(), + config.getGroup(), GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, + GlobalTypes.StripingPolicyType.STRIPING_POLICY_RAID0, 128, 1, volumeAttributes); + volume = client.openVolume(volumeName, config.getSslOptions(), config.getOptions()); + createdVolumes.add(volume); + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "Created volume %s", volumeName); + } catch (PosixErrorException e) { + if (e.getPosixError() == POSIXErrno.POSIX_ERROR_EEXIST) { /* i.e. volume already exists */ + volume = client.openVolume(volumeName, config.getSslOptions(), config.getOptions()); + } else + throw e; + } + + setStripeSizeAndWidth(volume); + createDirStructure(volume); + + /* set osd selection policy */ + if ( ! config.getOsdSelectionPolicies().equals("")) + volume.setOSDSelectionPolicy(config.getUserCredentials(), config.getOsdSelectionPolicies()); + + /* set policy attributes */ + Map attributes = config.getPolicyAttributes(); + for (String attribute : attributes.keySet()) + volume.setPolicyAttribute(config.getUserCredentials(), attribute, attributes.get(attribute)); + + if (!config.getReplicationPolicy().equals("")) { + volume.setDefaultReplicationPolicy(config.getUserCredentials(), "/", config.getReplicationPolicy(), + config.getReplicationFactor(), 0); + } + + return volume; + } + + private void verifyVolumeSizes() throws IOException { + int stripeSize = getVolStripeSize(this.volumes.getFirst()); + int stripeWidth= getVolStripeWidth(this.volumes.getFirst()); + boolean flag = false; + for (Volume volume : this.volumes){ + if (stripeSize != getVolStripeSize(volume)) + flag = true; + if (stripeWidth != getVolStripeWidth(volume)) + flag = true; + } + if (flag) + Logging.logMessage(Logging.LEVEL_WARN, Logging.Category.tool, this, + "The stripe size and width of all volumes is not equal (it should to achieve meaningful benchmarks"); + } + + private void setStripeSizeAndWidth(Volume volume) throws IOException { + int size, width; + int sizeConf = config.getStripeSizeInKiB(); + int widthConf = config.getStripeWidth(); + int sizeVol = getVolStripeSize(volume); + int widthVol = getVolStripeWidth(volume); + + if (!config.isStripeSizeSet() && !config.isStripeWidthSet()){ + config.setStripeSizeInBytes(sizeVol*BenchmarkUtils.KiB_IN_BYTES); + config.setStripeWidth(widthVol); + return; + } + else { + if (!config.isStripeSizeSet() && config.isStripeWidthSet()) { + size = sizeVol; + width = widthConf; + } else if (config.isStripeSizeSet() && !config.isStripeWidthSet()) { + size = sizeConf; + width = widthVol; + } else if (config.isStripeSizeSet() && config.isStripeWidthSet()){ + size = sizeConf; + width = widthConf; + } else + throw new UnknownError("Logical error. The above if-else statements should have been exhausting"); + } + String val = "{\"pattern\":\"STRIPING_POLICY_RAID0\",\"width\":" + width + ",\"size\":" + size + "}"; + volume.setXAttr(config.getUserCredentials(), "", "xtreemfs.default_sp", val, + MRC.XATTR_FLAGS.XATTR_FLAGS_REPLACE); + + config.setStripeSizeInBytes(size*BenchmarkUtils.KiB_IN_BYTES); + config.setStripeWidth(width); + } + + private int getVolStripeSize(Volume volume) throws IOException { + String valueStr = volume.getXAttr(config.getUserCredentials(), "", "xtreemfs.default_sp" ); + String sizeStr = valueStr.split(",")[2]; + return Integer.valueOf(sizeStr.substring(sizeStr.indexOf(":")+1, sizeStr.length()-1)); + } + + private int getVolStripeWidth(Volume volume) throws IOException { + String valueStr = volume.getXAttr(config.getUserCredentials(), "", "xtreemfs.default_sp" ); + String widthStr = valueStr.split(",")[1]; + return Integer.valueOf(widthStr.substring(widthStr.indexOf(":")+1)); + } + + private void createDirStructure(Volume volume) throws IOException { + createDir(volume, "/benchmarks/sequentialBenchmark"); + createDir(volume, "/benchmarks/randomBenchmark"); + } + + private void createDir(Volume volume, String directory) throws IOException { + + try { /* try to create directory benchmark */ + volume.createDirectory(config.getUserCredentials(), directory, 0777, true); + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, + "/benchmarks/randomBenchmark created on volume %s", volume.getVolumeName()); + + /* catch should be entered when directory already exists */ + } catch (PosixErrorException e) { + + /* if its not because directory already exists, throw error again */ + if (!(e.getPosixError() == POSIXErrno.POSIX_ERROR_EEXIST)) { + throw e; + } + } + + } + + /* + * adds a filelist with files from a sequential benchmark (used to pass the list of files written by a sequential + * write benchmark to a sequential read benchmark) + */ + void setSequentialFilelistForVolume(Volume volume, LinkedList filelist) { + String[] files = new String[filelist.size()]; + synchronized (this) { + filelistsSequentialBenchmark.put(volume, filelist.toArray(files)); + } + } + + /* + * adds a filelist with files from a filebased benchmark (used to pass the list of files written by a filebased + * write benchmark to a filebased read benchmark) + */ + void setRandomFilelistForVolume(Volume volume, LinkedList filelist) { + String[] files = new String[filelist.size()]; + synchronized (this) { + filelistsRandomBenchmark.put(volume, filelist.toArray(files)); + } + } + + /* + * get the list of files written to a volume (used to pass the list of files written by a filebased write benchmark + * to a filebased read benchmark) + */ + synchronized String[] getSequentialFilelistForVolume(Volume volume, long benchmarkSizeInBytes) throws IOException { + String[] filelist; + + /* null means no filelist from a previous write benchmark has been deposited */ + if (null == filelistsSequentialBenchmark.get(volume)) { + filelist = inferFilelist(volume, SequentialBenchmark.getBenchmarkFilename()); + + if (benchmarkSizeInBytes == calculateTotalSizeOfFilelist(volume, filelist)) { + filelistsSequentialBenchmark.put(volume, filelist); + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, + "Succesfully infered filelist on volume %s.", volume.getVolumeName()); + } else { + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "Infering filelist failed", + volume.getVolumeName()); + throw new IllegalArgumentException("No valid files for benchmark found"); + } + + } + return filelistsSequentialBenchmark.get(volume); + } + + /* + * get the list of files written to a volume (used to pass the list of files written by a filebased write benchmark + * to a filebased read benchmark) + */ + synchronized String[] getRandomFilelistForVolume(Volume volume, long benchmarkSizeInBytes) throws IOException { + String[] filelist; + + /* null means no filelist from a previous write benchmark has been deposited */ + if (null == filelistsRandomBenchmark.get(volume)) { + filelist = inferFilelist(volume, FilebasedBenchmark.getBenchmarkFilename()); + + if (benchmarkSizeInBytes == calculateTotalSizeOfFilelist(volume, filelist)) { + filelistsRandomBenchmark.put(volume, filelist); + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, + "Succesfully infered filelist on volume %s.", volume.getVolumeName()); + } else { + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "Infering filelist failed", + volume.getVolumeName()); + throw new IllegalArgumentException("No valid files for benchmark found"); + } + + } + return filelistsRandomBenchmark.get(volume); + } + + /* + * Tries to infer a list of files from sequential benchmarks. This is called if a sequential read benchmark was + * executed without a previous write benchmark (e.g. when the benchmark tool is executed first to do write + * benchmarks with the noCleanup option, a consecutive renewed execution of a read benchmark tries to infer the + * filelist) + */ + private String[] inferFilelist(Volume volume, String pathToBasefile) throws IOException { + + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "Read benchmark without write benchmark. " + + "Trying to infer a filelist on volume %s", volume.getVolumeName()); + + String path = pathToBasefile.substring(0, pathToBasefile.lastIndexOf('/')); + String filename = pathToBasefile.substring(pathToBasefile.lastIndexOf('/') + 1); + + List directoryEntries = volume.readDir(config.getUserCredentials(), path, 0, 0, true) + .getEntriesList(); + ArrayList entries = new ArrayList(directoryEntries.size()); + + for (MRC.DirectoryEntry directoryEntry : directoryEntries) { + String entry = directoryEntry.getName(); + if (entry.matches(filename + "[0-9]+")) + entries.add(path + '/' + directoryEntry.getName()); + } + entries.trimToSize(); + String[] filelist = new String[entries.size()]; + entries.toArray(filelist); + return filelist; + } + + /* calculates the number of files on a volume */ + private long calculateTotalSizeOfFilelist(Volume volume, String[] filelist) throws IOException { + long aggregatedSizeInBytes = 0; + for (String file : filelist) { + MRC.Stat stat = volume.getAttr(config.getUserCredentials(), file); + aggregatedSizeInBytes += stat.getSize(); + } + return aggregatedSizeInBytes; + } + + /* adds the files created by a benchmark to the list of created files */ + synchronized void addCreatedFiles(Volume volume, LinkedList newFiles) { + HashSet filelistForVolume; + if (createdFiles.containsKey(volume)) + filelistForVolume = createdFiles.get(volume); + else + filelistForVolume = new HashSet(); + filelistForVolume.addAll(newFiles); + createdFiles.put(volume, filelistForVolume); + } + + /* deletes all files on in the createdFiles list */ + void deleteCreatedFiles() { + for (Volume volume : volumes) { + HashSet fileListForVolume = createdFiles.get(volume); + + if (null != fileListForVolume) { + + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "Deleted %s file(s) on volume %s", + fileListForVolume.size(), volume.getVolumeName()); + + for (String filename : fileListForVolume) { + tryToDeleteFile(volume, filename); + } + } + } + } + + /* try to delete a file. log errors, but continue */ + private void tryToDeleteFile(Volume volume, String filename) { + try { + volume.unlink(config.getUserCredentials(), filename); + } catch (IOException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Logging.Category.tool, this, + "IO Error while trying to delete a file."); + Logging.logError(Logging.LEVEL_ERROR, Logging.Category.tool, e); + } + } + + /* deletes all volumes in the list of created volumes */ + void deleteCreatedVolumes() { + for (Volume volume : createdVolumes) { + deleteVolumeIfExisting(volume); + } + } + + /* deletes the given volumes */ + void deleteVolumes(String... volumeName) { + for (String each : volumeName) { + deleteVolumeIfExisting(each); + } + } + + /* delete the default volumes */ + void deleteDefaultVolumes(int numberOfVolumes) { + for (int i = 0; i < numberOfVolumes; i++) { + deleteVolumeIfExisting(VOLUME_BASE_NAME + i); + } + } + + /* delete a volume specified by a volume ref */ + void deleteVolumeIfExisting(Volume volume) { + volume.close(); + deleteVolumeIfExisting(volume.getVolumeName()); + } + + /* delete a volume specified by a string with the volumes name */ + void deleteVolumeIfExisting(String volumeName) { + + try { + if (new ArrayList(Arrays.asList(client.listVolumeNames())).contains(volumeName)) { + client.deleteVolume(config.getAuth(), config.getUserCredentials(), volumeName); + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "Deleted volume %s", volumeName); + } + } catch (IOException e) { + Logging.logMessage(Logging.LEVEL_WARN, Logging.Category.tool, this, "Error while deleting volume %s", volumeName); + Logging.logError(Logging.LEVEL_WARN, this, e); + } + } + + /* Performs cleanup on a OSD (because deleting the volume does not delete the files in the volume) */ + void cleanupOSD() throws Exception { + + String pwd = config.getAdminPassword(); + LinkedList uuids = getOSDUUIDs(); + + for (String osd : uuids) { + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.tool, this, "Starting cleanup of OSD %s", osd); + client.startCleanUp(osd, pwd, true, true, false, true, 0); + } + + boolean cleanUpIsRunning = true; + while (cleanUpIsRunning) { + cleanUpIsRunning = false; + for (String osd : uuids) { + cleanUpIsRunning = cleanUpIsRunning || client.isRunningCleanUp(osd, pwd); + } + Thread.sleep(300); + } + + for (String osd : uuids) { + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.tool, this, "Finished cleanup. Result: %s", + client.getCleanUpResult(osd, pwd)); + } + + } + + /* get the list of all OSDs registered a the DIR */ + LinkedList getOSDUUIDs() throws IOException { + LinkedList uuids = new LinkedList(); + for (DIR.Service service : client.getServiceByType(DIR.ServiceType.SERVICE_TYPE_OSD).getServicesList()) { + uuids.add(service.getUuid()); + } + return uuids; + } + + /* get the list of volumes */ + LinkedList getVolumes() { + return volumes; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/clients/CachedXAttr.java b/java/servers/src/org/xtreemfs/common/clients/CachedXAttr.java new file mode 100644 index 0000000..d0a0fdd --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/CachedXAttr.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients; + +import org.xtreemfs.foundation.TimeSync; + +/** + * + * @author bjko + */ +class CachedXAttr { + private String value; + private long timestamp; + + CachedXAttr(String value) { + this.timestamp = TimeSync.getLocalSystemTime(); + this.value = value; + } + + /** + * @return the value + */ + public String getValue() { + return value; + } + + /** + * @param value the value to set + */ + public void setValue(String value) { + this.value = value; + this.timestamp = TimeSync.getLocalSystemTime(); + } + + /** + * @return the timestamp + */ + public long getTimestamp() { + return timestamp; + } + + + +} diff --git a/java/servers/src/org/xtreemfs/common/clients/Client.java b/java/servers/src/org/xtreemfs/common/clients/Client.java new file mode 100644 index 0000000..d9d09ea --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/Client.java @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * + * @author bjko + */ +public class Client { + + private final RPCNIOSocketClient mdClient, osdClient; + + private final InetSocketAddress[] dirAddress; + + private DIRClient dirClient; + + private final UUIDResolver uuidRes; + + private final Map volumeMap; + + public Client(InetSocketAddress[] dirAddresses, int requestTimeout, int connectionTimeout, SSLOptions ssl) + throws IOException { + this.dirAddress = dirAddresses; + mdClient = new RPCNIOSocketClient(ssl, requestTimeout, connectionTimeout, "Client (dir)"); + osdClient = new RPCNIOSocketClient(ssl, requestTimeout, connectionTimeout, "Client (osd)"); + DIRServiceClient dirRpcClient = new DIRServiceClient(mdClient, dirAddress[0]); + dirClient = new DIRClient(dirRpcClient, dirAddress, 100, 1000 * 15); + TimeSync.initializeLocal(0); + uuidRes = UUIDResolver.startNonSingelton(dirClient, 3600, 1000); + volumeMap = new HashMap(); + } + + public Volume getVolume(String volumeName, UserCredentials credentials) throws IOException { + try { + String lookupVolumeName = volumeName; + int snapNameIndex = volumeName.indexOf('@'); + if (snapNameIndex != -1) + lookupVolumeName = volumeName.substring(0, snapNameIndex); + + final ServiceSet s = dirClient.xtreemfs_service_get_by_name(null, RPCAuthentication.authNone, + RPCAuthentication.userService, lookupVolumeName); + if (s.getServicesCount() == 0) { + throw new IOException("volume '" + lookupVolumeName + "' does not exist"); + } + final Service vol = s.getServices(0); + final String mrcUUIDstr = KeyValuePairs.getValue(vol.getData().getDataList(), "mrc"); + final ServiceUUID mrc = new ServiceUUID(mrcUUIDstr, uuidRes); + + UserCredentials uc = credentials; + if (uc == null) { + List grps = new ArrayList(1); + grps.add("test"); + uc = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + } + + Logging.logMessage(Logging.LEVEL_DEBUG, this, "volume %s on MRC %s/%s", volumeName, mrcUUIDstr, + mrc.getAddress()); + + Volume v = volumeMap.get(volumeName); + if (v == null) { + v = new Volume(new OSDServiceClient(osdClient, null), new MRCServiceClient(mdClient, mrc + .getAddress()), volumeName, uuidRes, uc); + volumeMap.put(volumeName, v); + } + return v; + + } catch (InterruptedException ex) { + throw new IOException("operation was interrupted", ex); + } + } + + public void createVolume(String volumeName, Auth authentication, UserCredentials credentials, + StripingPolicy sp, AccessControlPolicyType accessCtrlPolicy, int permissions) throws IOException { + RPCResponse r2 = null; + try { + ServiceSet mrcs = dirClient.xtreemfs_service_get_by_type(null, RPCAuthentication.authNone, credentials, + ServiceType.SERVICE_TYPE_MRC); + + if (mrcs.getServicesCount() == 0) { + throw new IOException("no MRC available for volume creation"); + } + + String uuid = mrcs.getServices(0).getUuid(); + ServiceUUID mrcUUID = new ServiceUUID(uuid, uuidRes); + + MRCServiceClient m = new MRCServiceClient(mdClient, mrcUUID.getAddress()); + r2 = m.xtreemfs_mkvol(null, authentication, credentials, accessCtrlPolicy, sp, "", permissions, + volumeName, credentials.getUsername(), credentials.getGroups(0), + new LinkedList(), 0); + r2.get(); + + } catch (InterruptedException ex) { + throw new IOException("operation was interrupted", ex); + } finally { + if (r2 != null) + r2.freeBuffers(); + } + } + + public void createVolume(String volumeName, Auth authentication, UserCredentials credentials, + StripingPolicy sp, AccessControlPolicyType accessCtrlPolicy, int permissions, String mrcUUID) + throws IOException { + + RPCResponse r = null; + try { + ServiceUUID uuid = new ServiceUUID(mrcUUID, uuidRes); + uuid.resolve(); + + MRCServiceClient m = new MRCServiceClient(mdClient, uuid.getAddress()); + r = m.xtreemfs_mkvol(uuid.getAddress(), authentication, credentials, accessCtrlPolicy, sp, "", permissions, + volumeName, credentials.getUsername(), credentials.getGroups(0), + new LinkedList(), 0); + r.get(); + + } catch (InterruptedException ex) { + throw new IOException("operation was interrupted", ex); + } catch (UnknownUUIDException ex) { + throw new IOException("mrc UUID was unknown", ex); + } finally { + if (r != null) + r.freeBuffers(); + } + + } + + public void deleteVolume(String volumeName, Auth authentication, UserCredentials credentials) + throws IOException { + RPCResponse r2 = null; + assert (credentials != null); + try { + final ServiceSet s = dirClient.xtreemfs_service_get_by_name(null, RPCAuthentication.authNone, credentials, + volumeName); + if (s.getServicesCount() == 0) { + throw new IOException("volume '" + volumeName + "' does not exist"); + } + final Service vol = s.getServices(0); + final String mrcUUIDstr = KeyValuePairs.getValue(vol.getData().getDataList(), "mrc"); + final ServiceUUID mrc = new ServiceUUID(mrcUUIDstr, uuidRes); + + MRCServiceClient m = new MRCServiceClient(mdClient, mrc.getAddress()); + r2 = m.xtreemfs_rmvol(null, authentication, credentials, volumeName); + r2.get(); + + } catch (InterruptedException ex) { + throw new IOException("operation was interrupted", ex); + } finally { + if (r2 != null) + r2.freeBuffers(); + } + } + + public String[] listVolumeNames(UserCredentials credentials) throws IOException { + assert (credentials != null); + try { + final ServiceSet s = dirClient.xtreemfs_service_get_by_type(null, RPCAuthentication.authNone, credentials, ServiceType.SERVICE_TYPE_VOLUME); + String[] volNames = new String[s.getServicesCount()]; + for (int i = 0; i < volNames.length; i++) + volNames[i] = s.getServices(i).getName(); + + return volNames; + + } catch (InterruptedException ex) { + throw new IOException("operation was interrupted", ex); + } + } + + public String[] listVolumeNames(String mrcUUID, UserCredentials credentials) throws IOException { + RPCResponse r = null; + assert (credentials != null); + try { + final ServiceUUID mrc = new ServiceUUID(mrcUUID, uuidRes); + + MRCServiceClient m = new MRCServiceClient(mdClient, mrc.getAddress()); + r = m.xtreemfs_lsvol(null, RPCAuthentication.authNone, credentials); + Volumes vols = r.get(); + + String[] volNames = new String[vols.getVolumesCount()]; + for(int i = 0; i < volNames.length; i++) + volNames[i] = vols.getVolumes(i).getName(); + + return volNames; + + } catch (InterruptedException ex) { + throw new IOException("operation was interrupted", ex); + } finally { + if (r != null) + r.freeBuffers(); + } + } + + public ServiceSet getRegistry() throws IOException { + try { + return dirClient.xtreemfs_service_get_by_type(null, RPCAuthentication.authNone, + RPCAuthentication.userService, ServiceType.SERVICE_TYPE_MIXED); + } catch (InterruptedException ex) { + throw new IOException("operation was interrupted", ex); + } + } + + public void start() throws Exception { + mdClient.start(); + mdClient.waitForStartup(); + osdClient.start(); + osdClient.waitForStartup(); + } + + public synchronized void stop() { + if (dirClient != null) { + try { + mdClient.shutdown(); + osdClient.shutdown(); + mdClient.waitForShutdown(); + osdClient.waitForShutdown(); + + for (Volume v : volumeMap.values()) + v.shutdown(); + + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + dirClient = null; + } + } + } + + @Override + public void finalize() { + stop(); + } +} diff --git a/java/servers/src/org/xtreemfs/common/clients/File.java b/java/servers/src/org/xtreemfs/common/clients/File.java new file mode 100644 index 0000000..e38ea97 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/File.java @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.foundation.json.JSONException; +import org.xtreemfs.foundation.json.JSONParser; +import org.xtreemfs.foundation.json.JSONString; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse; + +/** + * + * @author bjko + */ +public class File { + + public static final String XTREEMFSSET_REPL_UPDATE_POLICY_XATTR = "xtreemfs.set_repl_update_policy"; + + public static final String XTREEMFS_DEFAULT_RP = "xtreemfs.default_rp"; + + private final Volume volume; + + private final String path; + + private final UserCredentials userCreds; + + File(Volume volume, UserCredentials userCreds, String path) { + this.volume = volume; + this.path = path; + this.userCreds = userCreds; + } + + public String getPath() { + return path; + } + + + /** + * check if path is a file + * @param userCreds the user's credentials + * @see java.io.File + * @return true if it is a file, false otherwise (also if path does not exist) + */ + public boolean isFile(UserCredentials userCreds) throws IOException { + Stat stat = volume.stat(path, userCreds); + if (stat != null) + return (stat.getMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFREG.getNumber()) > 0; + else + return false; + } + + /** + * check if path is a file + * @see java.io.File + * @return true if it is a file, false otherwise (also if path does not exist) + */ + public boolean isFile() throws IOException { + return isFile(userCreds); + } + + /** + * check if path is a directory + * @param userCreds the user's credentials + * @see java.io.File + * @return true if it is a directory, false otherwise (also if path does not exist) + */ + public boolean isDirectory(UserCredentials userCreds) throws IOException { + Stat stat = volume.stat(path, userCreds); + if (stat != null) + return (stat.getMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFDIR.getNumber()) > 0; + else + return false; + } + + /** + * check if path is a directory + * @see java.io.File + * @return true if it is a directory, false otherwise (also if path does not exist) + */ + public boolean isDirectory() throws IOException { + return isDirectory(userCreds); + } + + /** + * check if path exists (file or directory) + * @param userCreds the user's credentials + * @see java.io.File + * @return true if it exists, false otherwise + */ + public boolean exists(UserCredentials userCreds) throws IOException { + try { + Stat stat = volume.stat(path, userCreds); + } catch (FileNotFoundException ex) { + return false; + } + return true; + } + + /** + * check if path exists (file or directory) + * @see java.io.File + * @return true if it exists, false otherwise + */ + public boolean exists() throws IOException { + return exists(userCreds); + } + + public boolean canRead(UserCredentials userCreds) throws IOException { + try { + Stat stat = volume.stat(path, userCreds); + return (stat.getMode() & 0400) > 0; + } catch (FileNotFoundException ex) { + return false; + } + } + + public boolean canRead() throws IOException { + return canRead(userCreds); + } + + public boolean canWrite(UserCredentials userCreds) throws IOException { + try { + Stat stat = volume.stat(path, userCreds); + return (stat.getMode() & 0200) > 0; + } catch (FileNotFoundException ex) { + return false; + } + } + + public boolean canWrite() throws IOException { + return canWrite(userCreds); + } + + public long lastModified(UserCredentials userCreds) throws IOException { + Stat stat = volume.stat(path, userCreds); + return stat.getMtimeNs()/1000000; + } + + public long lastModified() throws IOException { + return lastModified(userCreds); + } + + /** + * get file size + * @param userCreds the user's credentials + * @return the files size in bytes, or 0L if it does not exist + * @throws IOException + */ + public long length(UserCredentials userCreds) throws IOException { + + // if the volume is a snapshot, perform a size glimpse at the OSD + if (volume.isSnapshot()) { + + RPCResponse fs = null; + try { + RandomAccessFile file = volume.openFile(this, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber(), 0, userCreds); + fs = volume.osdClient.xtreemfs_internal_get_file_size(getReplica(0).getOSDAddress(0), RPCAuthentication.authNone, RPCAuthentication.userService, + file.getCredentials(), file.getFileId()); + return fs.get().getFileSize(); + } catch (Exception exc) { + exc.printStackTrace(); + return 0; + } finally { + if (fs != null) + fs.freeBuffers(); + } + + } + + // otherwise, fetch the file size from the MRC + else { + Stat stat = volume.stat(path, userCreds); + if (stat != null) { + return stat.getSize(); + } else + return 0L; + } + } + + /** + * get file size + * @return the files size in bytes, or 0L if it does not exist + * @throws IOException + */ + public long length() throws IOException { + return length(userCreds); + } + + public void mkdir(int permissions, UserCredentials userCreds) throws IOException { + volume.mkdir(path, permissions, userCreds); + } + + public void mkdir(int permissions) throws IOException { + mkdir(permissions, userCreds); + } + + public void createFile(UserCredentials userCreds) throws IOException { + volume.touch(path, userCreds); + } + + public void createFile() throws IOException { + createFile(userCreds); + } + + public Stat stat(UserCredentials userCreds) throws IOException { + return volume.stat(path, userCreds); + } + + public Stat stat() throws IOException { + return stat(userCreds); + } + + public void renameTo(File dest, UserCredentials userCreds) throws IOException { + volume.rename(this.path,dest.path, userCreds); + } + + public void renameTo(File dest) throws IOException { + renameTo(dest, userCreds); + } + + public void delete(UserCredentials userCreds) throws IOException { + volume.unlink(this.path, userCreds); + } + + public void delete() throws IOException { + delete(userCreds); + } + + public String getxattr(String name, UserCredentials userCreds) throws IOException { + return volume.getxattr(path, name, userCreds); + } + + public String getxattr(String name) throws IOException { + return getxattr(name, userCreds); + } + + public String[] listXAttrs(UserCredentials userCreds) throws IOException { + return volume.listxattr(path, userCreds); + } + + public String[] listXAttrs() throws IOException { + return listXAttrs(userCreds); + } + + public void setxattr(String name, String value, UserCredentials userCreds) throws IOException { + volume.setxattr(path, name, value, userCreds); + } + + public void setxattr(String name, String value) throws IOException { + setxattr(name, value, userCreds); + } + + public void chmod(int mode, UserCredentials userCreds) throws IOException { + volume.chmod(path, mode, userCreds); + } + + public void chmod(int mode) throws IOException { + chmod(mode, userCreds); + } + + public void chown(String user, UserCredentials userCreds) throws IOException { + volume.chown(path, user, userCreds); + } + + public void chown(String user) throws IOException { + chown(user, userCreds); + } + + public void chgrp(String group, UserCredentials userCreds) throws IOException { + volume.chgrp(path, group, userCreds); + } + + public void chgrp(String group) throws IOException { + chgrp(group, userCreds); + } + + public void setACL(Map aclEntries, UserCredentials userCreds) throws IOException { + volume.setACL(path, aclEntries, userCreds); + } + + public void setACL(Map aclEntries) throws IOException { + setACL(aclEntries, userCreds); + } + + public Map getACL(UserCredentials userCreds) throws IOException { + return volume.getACL(path, userCreds); + } + + public Map getACL() throws IOException { + return getACL(userCreds); + } + + public RandomAccessFile open(String openMode, int permissions, UserCredentials userCreds) throws IOException { + int flags = 0; + if (openMode.contains("rw")) { + flags |= SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + flags |= SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber(); + } else if (openMode.contains("r")) { + flags |= SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber(); + } + + if (openMode.contains("t")) { + flags |= SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber(); + } + if (openMode.contains("d") || openMode.contains("s")) { + flags |= SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_SYNC.getNumber(); + } + return volume.openFile(this, flags, permissions, userCreds); + } + + public RandomAccessFile open(String openMode, int permissions) throws IOException { + return open(openMode, permissions, userCreds); + } + + public int getNumReplicas(UserCredentials userCreds) throws IOException { + try { + Map xloc = getLocations(userCreds); + List> replicas = (List>) xloc.get("replicas"); + return replicas.size(); + } catch (ClassCastException ex) { + throw new IOException("cannot parse file's location list: "+ex,ex); + } + } + + public int getNumReplicas() throws IOException { + return getNumReplicas(userCreds); + } + + public Replica getReplica(int replicaNo, UserCredentials userCreds) throws IOException { + try { + Map xloc = getLocations(userCreds); + List> replicas = (List>) xloc.get("replicas"); + if (replicas.size() <= replicaNo) + throw new IllegalArgumentException("replicaNo is out of bounds"); + return new Replica(this,replicas.get(replicaNo),userCreds); + } catch (JSONException ex) { + throw new IOException("cannot parse file's location list: "+ex,ex); + } catch (ClassCastException ex) { + throw new IOException("cannot parse file's location list: "+ex,ex); + } + } + + public Replica getReplica(int replicaNo) throws IOException { + return getReplica(replicaNo, userCreds); + } + + public Replica getReplica(String osdUUID, UserCredentials userCreds) throws IOException { + Replica[] repls = getReplicas(userCreds); + for (Replica r : repls) { + for (int i = 0; i < r.getStripeWidth(); i++) { + if (r.getOSDUuid(i).equals(osdUUID)) + return r; + } + } + return null; + } + + public Replica getReplica(String osdUUID) throws IOException { + return getReplica(osdUUID, userCreds); + } + + public Replica[] getReplicas(UserCredentials userCreds) throws IOException { + try { + Map xloc = getLocations(userCreds); + List> replicas = (List>) xloc.get("replicas"); + Replica[] repls = new Replica[replicas.size()]; + for (int i = 0; i < repls.length; i++) + repls[i] = new Replica(this,replicas.get(i),userCreds); + return repls; + } catch (JSONException ex) { + throw new IOException("cannot parse file's location list",ex); + } catch (ClassCastException ex) { + throw new IOException("cannot parse file's location list",ex); + } + } + + public Replica[] getReplicas() throws IOException { + return getReplicas(userCreds); + } + + public void setDefaultReplication(String policy, int numReplicas, UserCredentials userCreds) throws IOException { + String JSON = "{ \"update-policy\" : \""+policy+"\", \"replication-factor\" : "+numReplicas+" }"; + if (!isDirectory()) + throw new IOException("only diretories (including root) have a default replication policy"); + volume.setxattr(path, XTREEMFS_DEFAULT_RP, JSON, userCreds); + } + + public void setDefaultReplication(String policy, int numReplicas) throws IOException { + setDefaultReplication(policy, numReplicas, userCreds); + } + + public boolean isReadOnlyReplicated(UserCredentials userCreds) throws IOException { + try { + Map xloc = getLocations(userCreds); + String uPolicy = (String) xloc.get("update-policy"); + return uPolicy.equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY); + } catch (ClassCastException ex) { + throw new IOException("cannot parse file's location list",ex); + } + } + + public boolean isReadOnlyReplicated() throws IOException { + return isReadOnlyReplicated(userCreds); + } + + public void setReadOnly(boolean mode, UserCredentials userCreds) throws Exception { + + boolean currentMode = Boolean.valueOf(getxattr("xtreemfs.read_only")); + + if (currentMode == mode) + return; + + if (mode) { + //make sure the file is not open! + + //open file + RandomAccessFile raf = open("r", 0, userCreds); + //fetch file sizes + long osd_file_size = raf.getFileSizeOnOSD(); + long mrc_file_size = length(userCreds); + + //update file size if incorrect on MRC + if (osd_file_size != mrc_file_size) { + raf.forceFileSize(osd_file_size); + } + + setxattr("xtreemfs.read_only", "true"); + } else { + if (getNumReplicas() > 1) + throw new IOException("File has still replicas."); + else { + // set read only + setxattr("xtreemfs.read_only", "false"); + } + } + } + + public void setReadOnly(boolean mode) throws Exception { + setReadOnly(mode, userCreds); + } + + public boolean isReadOnly(UserCredentials userCreds) throws IOException { + return Boolean.valueOf(getxattr("xtreemfs.read_only", userCreds)); + } + + public boolean isReadOnly() throws IOException { + return isReadOnly(userCreds); + } + + public boolean isReplicated(UserCredentials userCreds) throws IOException { + Map l = getLocations(userCreds); + String updatePolicy = (String)l.get("update-policy"); + return !updatePolicy.equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE); + } + + public boolean isReplicated() throws IOException { + return isReplicated(userCreds); + } + + public String[] getSuitableOSDs(int numOSDs, UserCredentials userCreds) throws IOException { + List osds = volume.getSuitableOSDs(this, numOSDs, userCreds); + return osds.toArray(new String[osds.size()]); + } + + public String[] getSuitableOSDs(int numOSDs) throws IOException { + return getSuitableOSDs(numOSDs, userCreds); + } + + public void addReplica(int width, String[] osdUuids, int flags, UserCredentials userCreds) throws IOException { + List osdSet = new ArrayList(20); + for (String osd : osdUuids) { + if (osdSet.size() == width) + break; + osdSet.add(osd); + } + if (osdSet.size() != width) + throw new IllegalArgumentException("number of OSDs must be equal to width!"); + + volume.addReplica(this, width, osdSet, flags, userCreds); + } + + public void addReplica(int width, String[] osdUuids, int flags) throws IOException { + addReplica(width, osdUuids, flags, userCreds); + } + + public void setReplicaUpdatePolicy(String policy, UserCredentials userCreds) throws IOException { + volume.setxattr(this.getPath(), XTREEMFSSET_REPL_UPDATE_POLICY_XATTR, policy, userCreds); + } + + public void setReplicaUpdatePolicy(String policy) throws IOException { + setReplicaUpdatePolicy(policy, userCreds); + } + + public String getReplicaUpdatePolicy(UserCredentials userCreds) throws IOException { + try { + String loc = this.volume.getxattr(this.getPath(), "xtreemfs.locations", userCreds); + if ( (loc != null) && (loc.length() > 0) ) { + Map location = (Map) JSONParser.parseJSON(new JSONString(loc)); + return (String) location.get("update-policy"); + } else { + throw new IOException("cannot retrieve file's location list (is empty)"); + } + } catch (JSONException ex) { + throw new IOException("cannot parse file's location list",ex); + } catch (ClassCastException ex) { + throw new IOException("cannot parse file's location list",ex); + } + } + + public String getReplicaUpdatePolicy() throws IOException { + return getReplicaUpdatePolicy(userCreds); + } + + Map getLocations(UserCredentials userCreds) throws IOException { + try { + String loc = this.volume.getxattr(this.getPath(), "xtreemfs.locations", userCreds); + if ( (loc != null) && (loc.length() > 0) ) { + return (Map) JSONParser.parseJSON(new JSONString(loc)); + } else { + throw new IOException("cannot retrieve file's location list (is empty)"); + } + } catch (JSONException ex) { + throw new IOException("cannot parse file's location list",ex); + } catch (ClassCastException ex) { + throw new IOException("cannot parse file's location list",ex); + } + } + + void removeReplica(String headOSDuuid, UserCredentials userCreds) throws IOException { + if (!this.isFile()) + throw new IOException("cannot remove replica from a non-file object"); + + volume.removeReplica(this, headOSDuuid, userCreds); + } + + + +} diff --git a/java/servers/src/org/xtreemfs/common/clients/InvalidChecksumException.java b/java/servers/src/org/xtreemfs/common/clients/InvalidChecksumException.java new file mode 100644 index 0000000..5ccc4dc --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/InvalidChecksumException.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients; + +import java.io.IOException; + +/** + * + * @author bjko + */ +public class InvalidChecksumException extends IOException { + + public InvalidChecksumException(String message) { + super(message); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/clients/RandomAccessFile.java b/java/servers/src/org/xtreemfs/common/clients/RandomAccessFile.java new file mode 100644 index 0000000..c5ac602 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/RandomAccessFile.java @@ -0,0 +1,716 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import org.xtreemfs.common.clients.internal.ObjectMapper; +import org.xtreemfs.common.clients.internal.ObjectMapper.ObjectRequest; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.common.xloc.Replica; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.client.RPCResponseAvailableListener; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse; + +/** + * + * @author bjko + */ +public class RandomAccessFile { + + public static final int WAIT_MS_BETWEEN_WRITE_SWITCHOVER = 1000; + + private final File parent; + private final OSDServiceClient osdClient; + private final Volume parentVolume; + private final boolean readOnly; + private final boolean syncMetadata; + private long position; + private FileCredentials credentials; + private Replica currentReplica; + private int currentReplicaNo; + private final int numReplicas; + private final String fileId; + private ObjectMapper oMapper; + private boolean closed; + private UserCredentials userCreds; + + private final AtomicReference uptodateCap; + + RandomAccessFile(File parent, Volume parentVolume, OSDServiceClient client, FileCredentials fc, boolean readOnly, boolean syncMetadata, UserCredentials userCreds) { + this.parent = parent; + this.parentVolume = parentVolume; + this.osdClient = client; + this.credentials = fc; + this.readOnly = readOnly; + this.syncMetadata = syncMetadata; + this.userCreds = userCreds; + position = 0; + currentReplicaNo = 0; + closed = false; + + numReplicas = credentials.getXlocs().getReplicasCount(); + fileId = fc.getXcap().getFileId(); + + uptodateCap = new AtomicReference(fc.getXcap()); + + selectReplica(0); + } + + public void updateCap(XCap newXCap) { + uptodateCap.set(newXCap); + } + + protected void setXCap() { + credentials = credentials.toBuilder().setXcap(uptodateCap.get()).build(); + } + + protected void switchToNextReplica() { + selectReplica((currentReplicaNo + 1) % numReplicas); + + } + + protected void selectReplica(int replicaNo) { + currentReplicaNo = replicaNo; + currentReplica = new Replica(credentials.getXlocs().getReplicas(currentReplicaNo), null); + oMapper = ObjectMapper.getMapper(currentReplica.getStripingPolicy().getPolicy()); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"now using replica %d (%s)",replicaNo,credentials.getXlocs().getReplicasList()); + } + + public XLocSet getLocationsList() { + return credentials.getXlocs(); + } + + public int getCurrentReplicaStripeSize() { + return currentReplica.getStripingPolicy().getStripeSizeForObject(0); + } + + public int getCurrentReplicaStripeingWidth() { + return currentReplica.getStripingPolicy().getWidth(); + } + + public void forceReplica(int replicaNo) { + if ((replicaNo > numReplicas-1) || (replicaNo < 0)) + throw new IllegalArgumentException("invalid replica number"); + selectReplica(replicaNo); + } + + public void forceReplica(String headOSDuuid) { + final int numRepl = credentials.getXlocs().getReplicasCount(); + for (int i = 0; i < numRepl; i++) { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica r = credentials.getXlocs().getReplicas(i); + if (r.getOsdUuids(0).equals(headOSDuuid)) { + selectReplica(i); + return; + } + } + throw new IllegalArgumentException("osd "+headOSDuuid+" not in any of the replicas: "+credentials.getXlocs().getReplicasList()); + } + + public int getCurrentReplica() { + return currentReplicaNo; + } + + public String getFileId() { + return credentials.getXcap().getFileId(); + } + + public File getFile() { + return parent; + } + + public boolean isReadOnly() { + return this.readOnly; + } + + public int read(byte[] data, int offset, int length) throws IOException { + ReusableBuffer buf = ReusableBuffer.wrap(data, offset, length); + return read(buf); + } + + public int read(ReusableBuffer data) throws IOException { + + if (closed) { + throw new IllegalStateException("file was closed"); + } + + int numTries = 0; + IOException cause = null; + do { + + List ors = oMapper.readRequest(data.remaining(), position, currentReplica); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"read from file %s: %d bytes from offset %d (= %d obj rqs)",fileId,data.remaining(),position,ors.size()); + + if (ors.isEmpty()) { + return 0; + } + + final AtomicInteger responseCnt = new AtomicInteger(ors.size()); + RPCResponse[] resps = new RPCResponse[ors.size()]; + + try { + + + final RPCResponseAvailableListener rl = new RPCResponseAvailableListener() { + + @Override + public void responseAvailable(RPCResponse r) { + if (responseCnt.decrementAndGet() == 0) { + //last response + synchronized (responseCnt) { + responseCnt.notify(); + } + } + } + }; + + setXCap(); + for (int i = 0; i < ors.size(); i++) { + ObjectRequest or = ors.get(i); + ServiceUUID osd = new ServiceUUID(or.getOsdUUID(), parentVolume.uuidResolver); + RPCResponse r = osdClient.read(osd.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + credentials, fileId, or.getObjNo(), -1, or.getOffset(), or.getLength()); + resps[i] = r; + r.registerListener(rl); + } + + + synchronized (responseCnt) { + if (responseCnt.get() > 0) { + responseCnt.wait(); + } + } + + + //assemble responses + InternalObjectData[] ods = new InternalObjectData[ors.size()]; + for (int i = 0; i < ors.size(); i++) { + ods[i] = new InternalObjectData(resps[i].get(),resps[i].getData()); + } + + int numBytesRead = 0; + + for (InternalObjectData od : ods) { + if (od.getData() != null) { + numBytesRead += od.getData().remaining(); + data.put(od.getData()); + BufferPool.free(od.getData()); + } + if (od.getZero_padding() > 0) { + numBytesRead += od.getZero_padding(); + for (int i = 0; i < od.getZero_padding(); i++) + data.put((byte)0); + } + } + + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"read returned %d bytes",numBytesRead); + + position += numBytesRead; + + return numBytesRead; + + } catch (InterruptedException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + cause = new IOException("operation aborted", ex); + } catch (PBRPCException ex) { + if (ex.getErrorType() == ErrorType.REDIRECT) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"redirected to: %s",ex.getRedirectToServerUUID()); + forceReplica(ex.getRedirectToServerUUID()); + continue; + } else if (ex.getErrorType() == ErrorType.ERRNO) { + cause = ex; + } else { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + cause = new IOException("communication failure", ex); + } + } catch (IOException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + cause = ex; + } catch (Throwable th) { + th.printStackTrace(); + throw new IOException("nasty!"); + } finally { + for (RPCResponse r : resps) + r.freeBuffers(); + } + numTries++; + try { + Thread.sleep(WAIT_MS_BETWEEN_WRITE_SWITCHOVER); + } catch (InterruptedException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + throw new IOException("operation aborted", ex); + } + switchToNextReplica(); + + } while (numTries < numReplicas+parentVolume.getMaxRetries()); + throw cause; + } + + + public int checkObject(long objectNo) throws IOException { + + if (closed) { + throw new IllegalStateException("file was closed"); + } + + + RPCResponse r = null; + try { + + ServiceUUID osd = new ServiceUUID(currentReplica.getOSDForObject(objectNo).toString(), parentVolume.uuidResolver); + + setXCap(); + r = osdClient.xtreemfs_check_object(osd.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + credentials, fileId, objectNo, 0l); + ObjectData od = r.get(); + + if (od.getInvalidChecksumOnOsd()) { + // try next replica + throw new InvalidChecksumException("object " + objectNo + " has an invalid checksum"); + } + + return od.getZeroPadding(); + + + } catch (InterruptedException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + throw new IOException("operation aborted", ex); + } catch (PBRPCException ex) { + if (ex.getErrorType() == ErrorType.ERRNO) + throw ex; + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + throw new IOException("communication failure", ex); + } finally { + if (r != null) + r.freeBuffers(); + } + } + + /** + * Writes bytesToWrite bytes from the writeFromBuffer byte array starting at + * offset to this file. + * + * @param writeFromBuffer + * @param offset + * @param bytesToWrite + * @return the number of bytes written + * @throws Exception + */ + public int write(byte[] data, int offset, int length) throws IOException { + ReusableBuffer buf = ReusableBuffer.wrap(data, offset, length); + return write(buf); + } + + public int write(ReusableBuffer data) throws IOException { + + if (readOnly) { + throw new IOException("File is marked as read-only."); + } + if (closed) { + throw new IllegalStateException("file was closed"); + } + + if (data.remaining() == 0) { + return 0; + } + + List ors = oMapper.writeRequest(data, position, currentReplica); + + if (ors.isEmpty()) { + return 0; + } + + int numTries = 0; + + IOException cause = null; + + do { + final AtomicInteger responseCnt = new AtomicInteger(ors.size()); + RPCResponse[] resps = new RPCResponse[ors.size()]; + + + + try { + + + final RPCResponseAvailableListener rl = new RPCResponseAvailableListener() { + + @Override + public void responseAvailable(RPCResponse r) { + if (responseCnt.decrementAndGet() == 0) { + //last response + synchronized (responseCnt) { + responseCnt.notify(); + } + } + } + }; + + int bytesWritten = 0; + setXCap(); + ObjectData objData = ObjectData.newBuilder().setChecksum(0).setInvalidChecksumOnOsd(false).setZeroPadding(0).build(); + for (int i = 0; i < ors.size(); i++) { + ObjectRequest or = ors.get(i); + or.getData().position(0); + bytesWritten += or.getData().capacity(); + ServiceUUID osd = new ServiceUUID(or.getOsdUUID(), parentVolume.uuidResolver); + + RPCResponse r = osdClient.write(osd.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + credentials, fileId, or.getObjNo(), -1, or.getOffset(), 0l, + objData, or.getData()); + resps[i] = r; + r.registerListener(rl); + } + + + synchronized (responseCnt) { + if (responseCnt.get() > 0) { + responseCnt.wait(); + } + } + + + //assemble responses + OSDWriteResponse owr = null; + for (int i = 0; i < ors.size(); i++) { + owr = (OSDWriteResponse) resps[i].get(); + } + setXCap(); + parentVolume.storeFileSizeUpdate(fileId, owr, userCreds); + if (syncMetadata) { + parentVolume.pushFileSizeUpdate(fileId, userCreds); + } + data.flip(); + + position += bytesWritten; + + return bytesWritten; + + } catch (InterruptedException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + cause = new IOException("operation aborted", ex); + } catch (PBRPCException ex) { + if (ex.getErrorType() == ErrorType.REDIRECT) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"redirected to: %s",ex.getRedirectToServerUUID()); + forceReplica(ex.getRedirectToServerUUID()); + continue; + } else if (ex.getErrorType() == ErrorType.ERRNO) { + cause = ex; + } else { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + cause = new IOException("communication failure", ex); + } + } catch (IOException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + cause = ex; + } finally { + for (RPCResponse r : resps) { + if (r != null) + r.freeBuffers(); + } + } + numTries++; + switchToNextReplica(); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"write failed (%s), switched to replica: %s",cause,currentReplica); + try { + Thread.sleep(WAIT_MS_BETWEEN_WRITE_SWITCHOVER); + } catch (InterruptedException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + throw new IOException("operation aborted", ex); + } + } while (numTries < numReplicas+parentVolume.getMaxRetries()); + throw cause; + } + + public void seek(long position) { + this.position = position; + } + + public long getFilePointer() { + return position; + } + + public void close() throws IOException { + this.closed = true; + parentVolume.closeFile(this,fileId, readOnly, userCreds); + } + + public void fsync() throws IOException { + parentVolume.pushFileSizeUpdate(fileId, userCreds); + } + + public long length() throws IOException { + return parent.length(); + } + + public long getNumObjects() throws IOException { + long flength = length(); + if (flength > 0) + return currentReplica.getStripingPolicy().getObjectNoForOffset(flength-1)+1; + else + return 0; + } + + public void forceFileSize(long newFileSize) throws IOException { + + XCap truncCap = parentVolume.truncateFile(fileId, userCreds); + + try { + + parentVolume.storeFileSizeUpdate(fileId, OSDWriteResponse.newBuilder() + .setSizeInBytes(newFileSize).setTruncateEpoch(truncCap.getTruncateEpoch()).build(), + userCreds); + parentVolume.pushFileSizeUpdate(fileId, userCreds); + + + if (position > newFileSize) + position = newFileSize; + + } catch (PBRPCException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + throw new IOException("communication failure", ex); + } + } + + long getFileSizeOnOSD() throws IOException { + if (closed) { + throw new IllegalStateException("file was closed"); + } + + RPCResponse r = null; + try { + + ServiceUUID osd = new ServiceUUID(currentReplica.getHeadOsd().toString(), parentVolume.uuidResolver); + + setXCap(); + r = osdClient.xtreemfs_internal_get_file_size(osd.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, credentials, fileId); + + return r.get().getFileSize(); + + } catch (InterruptedException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + throw new IOException("operation aborted", ex); + } catch (PBRPCException ex) { + if (ex.getErrorType() == ErrorType.REDIRECT) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"redirected to: %s",ex.getRedirectToServerUUID()); + forceReplica(ex.getRedirectToServerUUID()); + return getFileSizeOnOSD(); + } else if (ex.getErrorType() == ErrorType.ERRNO) { + throw ex; + } else { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + throw new IOException("communication failure", ex); + } + } finally { + if (r != null) + r.freeBuffers(); + } + } + + boolean isCompleteReplica(int replicaNo) throws IOException { + if (closed) { + throw new IllegalStateException("file was closed"); + } + + + RPCResponse r = null; + try { + + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica replica = this.credentials.getXlocs().getReplicas(replicaNo); + if ((replica.getReplicationFlags() & REPL_FLAG.REPL_FLAG_IS_COMPLETE.getNumber()) > 0) { + return true; + } + setXCap(); + StripingPolicyImpl sp = StripingPolicyImpl.getPolicy(replica, 0); + long lastObjectNo = sp.getObjectNoForOffset(this.credentials.getXlocs().getReadOnlyFileSize() - 1); + int osdRelPos = 0; + for (String osdUUID : replica.getOsdUuidsList()) { + ServiceUUID osd = new ServiceUUID(osdUUID, parentVolume.uuidResolver); + + r = osdClient.xtreemfs_internal_get_object_set(osd.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, credentials, fileId); + ObjectList ol = r.get(); + r.freeBuffers(); + r = null; + + byte[] serializedBitSet = ol.getSet().toByteArray(); + ObjectSet oset = null; + try { + oset = new ObjectSet(replicaNo, replicaNo, serializedBitSet); + } catch (Exception ex) { + throw new IOException("cannot deserialize object set: "+ex,ex); + } + for (long objNo = osdRelPos; objNo <= lastObjectNo; objNo += sp.getWidth()) { + if (oset.contains(objNo) == false) + return false; + } + + } + //FIXME: mark replica as complete + try { + parent.setxattr("xtreemfs.mark_replica_complete", replica.getOsdUuids(0)); + } catch (Exception ex) { + //only an optimization, ignore errors + } + return true; + } catch (InterruptedException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + throw new IOException("operation aborted", ex); + } catch (PBRPCException ex) { + if (ex.getErrorType() == ErrorType.REDIRECT) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"redirected to: %s",ex.getRedirectToServerUUID()); + forceReplica(ex.getRedirectToServerUUID()); + return isCompleteReplica(replicaNo); + } else if (ex.getErrorType() == ErrorType.ERRNO) { + throw ex; + } else { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + throw new IOException("communication failure", ex); + } + } finally { + if (r != null) + r.freeBuffers(); + } + } + + public int getReplicaNumber(String headOSDuuid) { + for (int i = 0; i < this.credentials.getXlocs().getReplicasCount(); i++) { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica replica = this.credentials.getXlocs().getReplicas(i); + if (replica.getOsdUuidsList().contains(headOSDuuid)) + return i; + } + throw new IllegalArgumentException("osd '"+headOSDuuid+"' is not in any replica of this file"); + } + + /** + * Triggers the initial replication of the current replica by reading the + * first object on each OSD. + */ + public void triggerInitialReplication() throws IOException { + + // send requests to all OSDs of this replica + try { + setXCap(); + List osdList = currentReplica.getOSDs(); + List osdListCopy = new ArrayList(currentReplica.getOSDs()); + // take lowest objects of file + for (int objectNo = 0; osdListCopy.size() != 0; objectNo++) { + // get index of OSD for this object + ServiceUUID osd = currentReplica.getOSDForObject(objectNo); + // remove OSD + osdListCopy.remove(osd); + // send request (read only 1 byte) + RPCResponse r = osdClient.read(osd.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + credentials, fileId, objectNo, 0, 0, 1); + r.get(); + r.freeBuffers(); + } + } catch (UnknownUUIDException e) { + // ignore; should not happen + } catch (PBRPCException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this, "comm error: %s", ex.toString()); + throw new IOException("communication failure", ex); + } catch (IOException e) { + throw new IOException("At least one OSD could not be contacted to replicate the file.", e); + } catch (InterruptedException e) { + // ignore + } + } + + public void setLength(long newLength) throws IOException { + XCap truncCap = parentVolume.truncateFile(fileId, userCreds); + FileCredentials tCred = FileCredentials.newBuilder().setXcap(truncCap).setXlocs(this.credentials.getXlocs()).build(); + + RPCResponse r = null; + try { + setXCap(); + ServiceUUID osd = new ServiceUUID(currentReplica.getHeadOsd().toString(), parentVolume.uuidResolver); + + r = osdClient.truncate(osd.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, tCred, fileId, newLength); + + OSDWriteResponse resp = r.get(); + + parentVolume.storeFileSizeUpdate(fileId, resp, userCreds); + parentVolume.pushFileSizeUpdate(fileId, userCreds); + + + if (position > newLength) + position = newLength; + } catch (InterruptedException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + throw new IOException("operation aborted", ex); + } catch (PBRPCException ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this,"comm error: %s",ex.toString()); + throw new IOException("communication failure", ex); + } finally { + if (r != null) + r.freeBuffers(); + } + } + + protected FileCredentials getCredentials() { + return credentials; + } + + public void flush() throws IOException { + fsync(); + } + + +} diff --git a/java/servers/src/org/xtreemfs/common/clients/Replica.java b/java/servers/src/org/xtreemfs/common/clients/Replica.java new file mode 100644 index 0000000..e542e14 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/Replica.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.json.JSONException; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; + +/** + * + * @author bjko + */ +public class Replica { + + private final File parentFile; + + private final String[] osdAddresses; + + private final String[] osdUUIDs; + + private final StripingPolicyType stripingPolicy; + + private final int stripeSize; + + private final int stripingWidth; + + private final int replicationFlags; + + private UserCredentials userCreds; + + + Replica(File parentFile, Map json, UserCredentials userCreds) throws JSONException { + this.parentFile = parentFile; + this.userCreds = userCreds; + + try { + Map sp = (Map) json.get("striping-policy"); + String spName = (String) sp.get("pattern"); + if (spName.equals("STRIPING_POLICY_RAID0")) { + stripingPolicy = StripingPolicyType.STRIPING_POLICY_RAID0; + } else { + throw new JSONException("Unknown striping policy type: "+spName); + } + Long tmp = (Long)sp.get("size"); + stripeSize = tmp.intValue(); + + tmp = (Long) sp.get("width"); + stripingWidth = tmp.intValue(); + + tmp = (Long) json.get("replication-flags"); + replicationFlags = tmp.intValue(); + + List> osds = (List>) json.get("osds"); + osdAddresses = new String[stripingWidth]; + osdUUIDs = new String[stripingWidth]; + + + if (osds.size() != stripingWidth) { + throw new JSONException("replica information incorrect, OSD count < stripingWidth: "+stripingWidth); + } + + for (int i = 0; i < stripingWidth; i++) { + Map osd = osds.get(i); + osdAddresses[i] = (String) osd.get("address"); + osdUUIDs[i] = (String) osd.get("uuid"); + } + } catch (Exception ex) { + ex.printStackTrace(); + throw new JSONException("malformed JSON replica representation: "+ex); + } + } + + /** + * Get the location (inet address) of the replica's head OSD + * @return + */ + public InetSocketAddress getLocation() { + return getOSDAddress(0); + } + + public InetSocketAddress getOSDAddress(int osdNum) { + int colon = osdAddresses[osdNum].indexOf(":"); + String hostname = osdAddresses[osdNum].substring(0,colon); + String portStr = osdAddresses[osdNum].substring(colon+1); + int port = Integer.valueOf(portStr); + + return new InetSocketAddress(hostname,port); + } + + public String getOSDUuid(int osdNum) { + return osdUUIDs[osdNum]; + } + + public int getStripeWidth() { + return stripingWidth; + } + + public int getStripeSize() { + return stripeSize; + } + + public StripingPolicyType getStripingPolicy() { + return stripingPolicy; + } + + public boolean isFullReplica() { + return (replicationFlags & REPL_FLAG.REPL_FLAG_FULL_REPLICA.getNumber()) != 0; + } + + public boolean isRandomStrategy() { + return ReplicationFlags.isRandomStrategy(replicationFlags); + } + + public boolean isSequentialStrategy() { + return ReplicationFlags.isSequentialStrategy(replicationFlags); + } + + public boolean isSequentialPrefetchingStrategy() { + return ReplicationFlags.isSequentialPrefetchingStrategy(replicationFlags); + } + + public boolean isRarestFirstStrategy() { + return ReplicationFlags.isRarestFirstStrategy(replicationFlags); + } + + /** + * checks if the replica is complete (holds all objects of a file). + * + * @return true, if the replica is marked as complete or if the + */ + public boolean isCompleteReplica() throws IOException { + if ((replicationFlags & REPL_FLAG.REPL_FLAG_IS_COMPLETE.getNumber()) != 0) { + return true; + } else { + RandomAccessFile raf = parentFile.open("r", 0); + int myNum = raf.getReplicaNumber(osdUUIDs[0]); + boolean isComplete = raf.isCompleteReplica(myNum); + raf.close(); + return isComplete; + } + } + + public void removeReplica(boolean checkForCompleteReplica) throws IOException { + final Replica[] replicas = parentFile.getReplicas(userCreds); + if (replicas.length == 1) + throw new IOException("cannot remove last replica (delete file instead!)"); + + if (checkForCompleteReplica) { + //FIXME: make sure at least one complete replica still exists + boolean completeReplica = false; + for (Replica r : replicas) { + if (r.getOSDUuid(0).equals(this.osdUUIDs[0])) { + //ignore myself + continue; + } + if (r.isCompleteReplica()) { + completeReplica = true; + break; + } + } + if (!completeReplica) { + throw new IOException("cannot remove last complete replica!"); + } + } + + parentFile.removeReplica(osdUUIDs[0], userCreds); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/clients/Volume.java b/java/servers/src/org/xtreemfs/common/clients/Volume.java new file mode 100644 index 0000000..7b6d7b0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/Volume.java @@ -0,0 +1,885 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.clients.internal.OpenFileList; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.foundation.json.JSONException; +import org.xtreemfs.foundation.json.JSONParser; +import org.xtreemfs.foundation.json.JSONString; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Setattrs; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +import com.google.protobuf.ByteString; + +/** + * + * @author bjko + */ +public class Volume { + + private final MRCServiceClient mrcClient; + + final UUIDResolver uuidResolver; + + private final String volumeName; + + private final UserCredentials userCreds; + + protected final OSDServiceClient osdClient; + + private final OpenFileList ofl; + + private final int maxRetries; + + private static final VivaldiCoordinates emptyCoordinates; + + static { + emptyCoordinates = VivaldiCoordinates.newBuilder().setLocalError(0).setXCoordinate(0).setYCoordinate(0).build(); + } + + /* + * private final LRUCache xattrCache; + * + * private final int mdCacheTimeout_ms; + */ + + Volume(OSDServiceClient osdClient, MRCServiceClient client, String volumeName, UUIDResolver uuidResolver, + UserCredentials userCreds) { + this(osdClient, client, volumeName, uuidResolver, userCreds, 0, 5); + } + + Volume(OSDServiceClient osdClient, MRCServiceClient client, String volumeName, UUIDResolver uuidResolver, + UserCredentials userCreds, int mdCacheTimeout_ms, int maxRetries) { + this.mrcClient = client; + this.volumeName = volumeName.endsWith("/") ? volumeName : volumeName + "/"; + this.uuidResolver = uuidResolver; + this.userCreds = userCreds; + this.osdClient = osdClient; + this.maxRetries = maxRetries; + this.ofl = new OpenFileList(client); + /* + * this.xattrCache = new LRUCache(2048); + * this.mdCacheTimeout_ms = mdCacheTimeout_ms; + */ + ofl.start(); + } + + /** + * same semantics as File.list() + * + * @param path + * @param cred + * @return + * @throws IOException + */ + public String[] list(String path) throws IOException { + return list(path, userCreds); + } + + public String[] list(String path, UserCredentials userCreds) throws IOException { + + RPCResponse response = null; + + final String fixedVol = fixPath(volumeName); + final String fixedPath = fixPath(path); + try { + response = mrcClient.readdir(null, RPCAuthentication.authNone, userCreds, fixedVol, fixedPath, 0, 0, true, + 0); + DirectoryEntries entries = response.get(); + String[] list = new String[entries.getEntriesCount()]; + for (int i = 0; i < list.length; i++) { + list[i] = entries.getEntries(i).getName(); + } + return list; + } catch (PBRPCException ex) { + if (ex.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_ENOENT) + return null; + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + public DirectoryEntry[] listEntries(String path, UserCredentials userCreds) throws IOException { + RPCResponse response = null; + path = path.replace("//", "/"); + final String fixedVol = fixPath(volumeName); + final String fixedPath = fixPath(path); + try { + response = mrcClient.readdir(null, RPCAuthentication.authNone, userCreds, fixedVol, fixedPath, 0, 0, false, + 0); + DirectoryEntries entries = response.get(); + DirectoryEntry[] list = new DirectoryEntry[entries.getEntriesCount()]; + for (int i = 0; i < list.length; i++) { + list[i] = entries.getEntries(i); + Stat s = list[i].getStbuf(); + OSDWriteResponse r = ofl.getLocalFS(volumeName + s.getIno()); + if (r != null && r.hasTruncateEpoch()) { + // update with local file size, if cahced + if ((r.getTruncateEpoch() > s.getTruncateEpoch()) || (r.getTruncateEpoch() == s.getTruncateEpoch()) + && (r.getSizeInBytes() > s.getSize())) { + s = s.toBuilder().setSize(r.getSizeInBytes()).setTruncateEpoch(r.getTruncateEpoch()).build(); + list[i] = list[i].toBuilder().setStbuf(s).build(); + } + } + } + return list; + } catch (PBRPCException ex) { + if (ex.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_ENOENT) + return null; + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + public DirectoryEntry[] listEntries(String path) throws IOException { + return listEntries(path, userCreds); + } + + public File getFile(String path, UserCredentials userCreds) { + return new File(this, userCreds, path); + } + + public File getFile(String path) { + return new File(this, userCreds, path); + } + + public String getName() { + return volumeName; + } + + String fixPath(String path) { + path = path.replace("//", "/"); + if (path.endsWith("/")) + path = path.substring(0, path.length() - 1); + if (path.startsWith("/")) + path = path.substring(1); + return path; + } + + public long getFreeSpace(UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.statvfs(null, RPCAuthentication.authNone, userCreds, volumeName.replace("/", ""), 0); + StatVFS fsinfo = response.get(); + return fsinfo.getBavail() * fsinfo.getBsize(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + public long getFreeSpace() throws IOException { + return getFreeSpace(userCreds); + } + + public StatVFS statfs(UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.statvfs(null, RPCAuthentication.authNone, userCreds, volumeName.replace("/", ""), 0); + StatVFS fsinfo = response.get(); + return fsinfo; + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + public StatVFS statfs() throws IOException { + return statfs(userCreds); + } + + public boolean isReplicateOnClose(UserCredentials userCreds) throws IOException { + String numRepl = getxattr(fixPath(volumeName), "xtreemfs.repl_factor", userCreds); + if (numRepl == null) + return false; + return numRepl.equals("1"); + } + + public boolean isReplicateOnClose() throws IOException { + return isReplicateOnClose(userCreds); + } + + public boolean isSnapshot() { + return volumeName.indexOf('@') != -1; + } + + public int getDefaultReplicationFactor(UserCredentials userCreds) throws IOException { + String numRepl = getxattr(fixPath(volumeName), "xtreemfs.repl_factor", userCreds); + try { + return Integer.valueOf(numRepl); + } catch (Exception ex) { + throw new IOException("cannot fetch replication factor", ex); + } + } + + public int getDefaultReplicationFactor() throws IOException { + return getDefaultReplicationFactor(userCreds); + } + + public long getUsedSpace(UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.statvfs(null, RPCAuthentication.authNone, userCreds, volumeName.replace("/", ""), 0); + StatVFS fsinfo = response.get(); + return (fsinfo.getBlocks() - fsinfo.getBavail()) * fsinfo.getBsize(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + public long getUsedSpace() throws IOException { + return getUsedSpace(userCreds); + } + + public long getDefaultObjectSize(UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.statvfs(null, RPCAuthentication.authNone, userCreds, volumeName.replace("/", ""), 0); + StatVFS fsinfo = response.get(); + return fsinfo.getBsize(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + public long getDefaultObjectSize() throws IOException { + return getDefaultObjectSize(userCreds); + } + + public void enableSnapshots(boolean enable, UserCredentials userCreds) throws IOException { + RPCResponse r = null; + try { + String value = enable + ""; + r = mrcClient.setxattr(null, RPCAuthentication.authNone, userCreds, volumeName.replace("/", ""), "", + "xtreemfs.snapshots_enabled", value, ByteString.copyFrom(value.getBytes()), 0); + r.get(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (r != null) + r.freeBuffers(); + } + } + + public void enableSnapshots(boolean enable) throws IOException { + enableSnapshots(enable, userCreds); + } + + public void snapshot(String name, boolean recursive, UserCredentials userCreds) throws IOException { + RPCResponse r = null; + try { + String cmd = "c" + (recursive ? "r" : "") + " " + name; + r = mrcClient.setxattr(null, RPCAuthentication.authNone, userCreds, volumeName.replace("/", ""), "", + "xtreemfs.snapshots", cmd, ByteString.copyFrom(cmd.getBytes()), 0); + r.get(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (r != null) + r.freeBuffers(); + } + } + + public void snapshot(String name, boolean recursive) throws IOException { + snapshot(name, recursive, userCreds); + } + + Stat stat(String path, UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.getattr(null, RPCAuthentication.authNone, userCreds, fixPath(volumeName), + fixPath(path), 0); + Stat s = response.get().getStbuf(); + OSDWriteResponse r = ofl.getLocalFS(volumeName + s.getIno()); + if (r != null && r.hasTruncateEpoch()) { + // update with local file size, if cahced + if ((r.getTruncateEpoch() > s.getTruncateEpoch()) || (r.getTruncateEpoch() == s.getTruncateEpoch()) + && (r.getSizeInBytes() > s.getSize())) { + s = s.toBuilder().setSize(r.getSizeInBytes()).setTruncateEpoch(r.getTruncateEpoch()).build(); + } + } + return s; + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + String getxattr(String path, String name, UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.getxattr(null, RPCAuthentication.authNone, userCreds, fixPath(volumeName), + fixPath(path), name); + return response.get().getValue(); + } catch (PBRPCException ex) { + if (ex.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_ENODATA) + return null; + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + String[] listxattr(String path, UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.listxattr(null, RPCAuthentication.authNone, userCreds, fixPath(volumeName), + fixPath(path), true); + listxattrResponse result = response.get(); + List attrs = result.getXattrsList(); + String[] names = new String[attrs.size()]; + for (int i = 0; i < names.length; i++) + names[i] = attrs.get(i).getName(); + return names; + } catch (PBRPCException ex) { + if (ex.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_ENODATA) + return null; + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + void setxattr(String path, String name, String value, UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.setxattr(null, RPCAuthentication.authNone, userCreds, fixPath(volumeName), + fixPath(path), name, value, ByteString.copyFrom(value.getBytes()), 0); + response.get(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + void mkdir(String path, int permissions, UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.mkdir(null, RPCAuthentication.authNone, userCreds, fixPath(volumeName), fixPath(path), + permissions); + response.get(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + void touch(String path, UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.open(null, RPCAuthentication.authNone, userCreds, fixPath(volumeName), fixPath(path), + GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber(), 0700, 0, emptyCoordinates); + response.get(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + void rename(String src, String dest, UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.rename(null, RPCAuthentication.authNone, userCreds, fixPath(volumeName), fixPath(src), + fixPath(dest)); + response.get(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + void unlink(String path, UserCredentials userCreds) throws IOException { + RPCResponse response = null; + RPCResponse ulnkResp = null; + try { + response = mrcClient + .unlink(null, RPCAuthentication.authNone, userCreds, fixPath(volumeName), fixPath(path)); + unlinkResponse resp = response.get(); + final FileCredentials fcs = resp.hasCreds() ? resp.getCreds() : null; + if (fcs != null) { + // delete on OSDs + for (GlobalTypes.Replica r : fcs.getXlocs().getReplicasList()) { + final String headOSDuuid = r.getOsdUuids(0); + final ServiceUUID osdAddr = new ServiceUUID(headOSDuuid, uuidResolver); + osdAddr.resolve(); + ulnkResp = osdClient.unlink(osdAddr.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcs, fcs.getXcap().getFileId()); + ulnkResp.get(); + ulnkResp.freeBuffers(); + ulnkResp = null; + } + } + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + if (ulnkResp != null) + ulnkResp.freeBuffers(); + } + } + + void storeFileSizeUpdate(String fileId, OSDWriteResponse resp, UserCredentials userCreds) { + ofl.fsUpdate(fileId, resp); + } + + void pushFileSizeUpdate(String fileId, UserCredentials userCreds) throws IOException { + OSDWriteResponse owr = ofl.sendFsUpdate(fileId); + if (owr != null) { + XCap cap = ofl.getCapability(fileId); + RPCResponse response = null; + try { + if (!owr.hasSizeInBytes()) + return; + + long newSize = owr.getSizeInBytes(); + int newEpoch = owr.getTruncateEpoch(); + + OSDWriteResponse.Builder osdResp = OSDWriteResponse.newBuilder().setSizeInBytes(newSize) + .setTruncateEpoch(newEpoch); + xtreemfs_update_file_sizeRequest fsBuf = xtreemfs_update_file_sizeRequest.newBuilder().setXcap(cap) + .setOsdWriteResponse(osdResp).build(); + + response = mrcClient.xtreemfs_update_file_size(null, RPCAuthentication.authNone, userCreds, fsBuf); + response.get(); + + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + } + + void closeFile(RandomAccessFile file, String fileId, boolean readOnly, UserCredentials userCreds) + throws IOException { + + pushFileSizeUpdate(fileId, userCreds); + try { + XCap cap = ofl.getCapability(fileId); + // notify MRC that file has been closed + RPCResponse response = null; + try { + response = mrcClient.xtreemfs_update_file_size(null, RPCAuthentication.authNone, userCreds, cap, + OSDWriteResponse.newBuilder().build(), true, emptyCoordinates); + response.get(); + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + throw new IOException("file could not be closed due to exception"); + } finally { + if (response != null) + response.freeBuffers(); + } + } finally { + ofl.closeFile(fileId, file); + } + + } + + RandomAccessFile openFile(File parent, int flags, int mode, UserCredentials userCreds) throws IOException { + RPCResponse response = null; + final String fullPath = fixPath(volumeName + parent.getPath()); + final String fixedVol = fixPath(volumeName); + final String fixedPath = fixPath(parent.getPath()); + try { + response = mrcClient.open(null, RPCAuthentication.authNone, userCreds, fixedVol, fixedPath, flags, mode, 0, + emptyCoordinates); + FileCredentials cred = response.get().getCreds(); + + boolean syncMd = (flags & GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_SYNC.getNumber()) > 0; + boolean rdOnly = cred.getXlocs().getReplicaUpdatePolicy() + .equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY); + RandomAccessFile file = new RandomAccessFile(parent, this, osdClient, cred, rdOnly, syncMd, userCreds); + ofl.openFile(cred.getXcap(), file); + return file; + } catch (PBRPCException ex) { + if (ex.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_ENOENT) + throw new FileNotFoundException("file '" + fullPath + "' does not exist"); + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + XCap truncateFile(String fileId, UserCredentials userCreds) throws IOException { + RPCResponse response = null; + try { + response = mrcClient.ftruncate(null, RPCAuthentication.authNone, userCreds, ofl.getCapability(fileId)); + return response.get(); + + } catch (PBRPCException ex) { + if (ex.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_ENOENT) + throw new FileNotFoundException("file '" + fileId + "' does not exist"); + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + List getSuitableOSDs(File file, int numOSDs, UserCredentials userCreds) throws IOException { + String fileId = getxattr(file.getPath(), "xtreemfs.file_id", userCreds); + RPCResponse response = null; + try { + xtreemfs_get_suitable_osdsRequest request = xtreemfs_get_suitable_osdsRequest.newBuilder() + .setFileId(fileId).setNumOsds(numOSDs).build(); + response = mrcClient.xtreemfs_get_suitable_osds(null, RPCAuthentication.authNone, userCreds, request); + return response.get().getOsdUuidsList(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + void chmod(String path, int mode, UserCredentials userCreds) throws IOException { + + Stat stbuf = Stat.newBuilder().setAtimeNs(0).setAttributes(0).setBlksize(0).setCtimeNs(0).setDev(0).setEtag(0) + .setGroupId("").setIno(0).setMode(mode).setMtimeNs(0).setNlink(0).setSize(0).setTruncateEpoch(0) + .setUserId("").build(); + int toSet = Setattrs.SETATTR_MODE.getNumber(); + + RPCResponse response = null; + try { + response = mrcClient.setattr(null, RPCAuthentication.authNone, userCreds, fixPath(volumeName), + fixPath(path), stbuf, toSet); + response.get(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + void chown(String path, String user, UserCredentials userCreds) throws IOException { + + Stat stbuf = Stat.newBuilder().setAtimeNs(0).setAttributes(0).setBlksize(0).setCtimeNs(0).setDev(0).setEtag(0) + .setGroupId("").setIno(0).setMode(0).setMtimeNs(0).setNlink(0).setSize(0).setTruncateEpoch(0) + .setUserId(user).build(); + int toSet = Setattrs.SETATTR_UID.getNumber(); + + RPCResponse response = null; + try { + response = mrcClient.setattr(null, RPCAuthentication.authNone, userCreds, fixPath(volumeName), + fixPath(path), stbuf, toSet); + response.get(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + void chgrp(String path, String group, UserCredentials userCreds) throws IOException { + + Stat stbuf = Stat.newBuilder().setAtimeNs(0).setAttributes(0).setBlksize(0).setCtimeNs(0).setDev(0).setEtag(0) + .setGroupId(group).setIno(0).setMode(0).setMtimeNs(0).setNlink(0).setSize(0).setTruncateEpoch(0) + .setUserId("").build(); + int toSet = Setattrs.SETATTR_GID.getNumber(); + + RPCResponse response = null; + try { + response = mrcClient.setattr(null, RPCAuthentication.authNone, userCreds, fixPath(volumeName), + fixPath(path), stbuf, toSet); + response.get(); + } catch (PBRPCException ex) { + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + void setACL(String path, Map aclEntries, UserCredentials userCreds) throws IOException { + + // remove all existing entries first + Map existingACL = getACL(path, userCreds); + for (Entry entry : existingACL.entrySet()) { + String entity = entry.getKey(); + if (!entity.equals("u:") && !entity.equals("g:") && !entity.equals("o:") && !entity.equals("m:")) + setxattr(path, "xtreemfs.acl", "x " + entity, userCreds); + } + + // add all entries from the given list + for (Entry entry : aclEntries.entrySet()) + setxattr(path, "xtreemfs.acl", "m " + entry.getKey() + ":" + entry.getValue(), userCreds); + } + + Map getACL(String path, UserCredentials userCreds) throws IOException { + try { + String aclAsJSON = getxattr(path, "xtreemfs.acl", userCreds); + return (Map) JSONParser.parseJSON(new JSONString(aclAsJSON)); + } catch (JSONException e) { + throw new IOException(e); + } + } + + static IOException wrapException(PBRPCException ex) { + if (ex.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_ENOENT) + return new FileNotFoundException(ex.getErrorMessage()); + return new IOException(ex.getPOSIXErrno() + ": " + ex.getErrorMessage(), ex); + } + + static IOException wrapException(InterruptedException ex) { + return new IOException("operation was interruped: " + ex, ex); + } + + public void finalize() { + ofl.shutdown(); + } + + void addReplica(File file, int width, List osdSet, int flags, UserCredentials userCreds) throws IOException { + + RPCResponse response1 = null; + RPCResponse response3 = null; + final String fullPath = fixPath(volumeName + file.getPath()); + final String fixedVol = fixPath(volumeName); + final String fixedPath = fixPath(file.getPath()); + try { + + org.xtreemfs.common.clients.Replica r = file.getReplica(0); + StripingPolicy sp = StripingPolicy.newBuilder().setStripeSize(r.getStripeSize()).setWidth(width) + .setType(r.getStripingPolicy()).build(); + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica newReplica = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica + .newBuilder().addAllOsdUuids(osdSet).setReplicationFlags(flags).setStripingPolicy(sp).build(); + + response1 = mrcClient.open(null, RPCAuthentication.authNone, userCreds, fixedVol, fixedPath, 0, + GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0, emptyCoordinates); + FileCredentials oldCreds = response1.get().getCreds(); + response1.freeBuffers(); + response1 = null; + + boolean readOnlyRepl = (oldCreds.getXlocs().getReplicaUpdatePolicy() + .equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)); + + xtreemfs_replica_addRequest request = xtreemfs_replica_addRequest.newBuilder().setNewReplica(newReplica) + .setFileId(oldCreds.getXcap().getFileId()).build(); + response3 = mrcClient.xtreemfs_replica_add(null, RPCAuthentication.authNone, userCreds, request); + response3.get(); + response3.freeBuffers(); + response3 = null; + + if (readOnlyRepl) { + if ((flags & GlobalTypes.REPL_FLAG.REPL_FLAG_FULL_REPLICA.getNumber()) > 0) { + + response1 = mrcClient.open(null, RPCAuthentication.authNone, userCreds, fixedVol, fixedPath, 0, + GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0, emptyCoordinates); + FileCredentials newCreds = response1.get().getCreds(); + + for (int objNo = 0; objNo < width; objNo++) { + ServiceUUID osd = new ServiceUUID(osdSet.get(objNo), uuidResolver); + response3 = osdClient + .read(osd.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + newCreds, newCreds.getXcap().getFileId(), objNo, 0, 0, 1); + response3.get(); + response3.freeBuffers(); + response3 = null; + } + } + } else { + + response1 = mrcClient.open(null, RPCAuthentication.authNone, userCreds, fixedVol, fixedPath, 0, + GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0, emptyCoordinates); + FileCredentials newCreds = response1.get().getCreds(); + + ServiceUUID osd = new ServiceUUID(osdSet.get(0), uuidResolver); + response3 = osdClient.xtreemfs_rwr_notify(osd.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, newCreds); + response3.get(); + response3.freeBuffers(); + response3 = null; + + } + + } catch (PBRPCException ex) { + if (ex.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_ENOENT) + throw new FileNotFoundException("file '" + fullPath + "' does not exist"); + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response1 != null) + response1.freeBuffers(); + if (response3 != null) + response3.freeBuffers(); + } + } + + void removeReplica(File file, String headOSDuuid, UserCredentials userCreds) throws IOException { + + RPCResponse response1 = null; + RPCResponse response2 = null; + RPCResponse response3 = null; + final String fullPath = fixPath(volumeName + file.getPath()); + final String fixedVol = fixPath(volumeName); + final String fixedPath = fixPath(file.getPath()); + try { + response1 = mrcClient.open(null, RPCAuthentication.authNone, userCreds, fixedVol, fixedPath, 0, + GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0, emptyCoordinates); + FileCredentials oldCreds = response1.get().getCreds(); + + xtreemfs_replica_removeRequest request = xtreemfs_replica_removeRequest.newBuilder() + .setOsdUuid(headOSDuuid).setFileId(oldCreds.getXcap().getFileId()).build(); + + response2 = mrcClient.xtreemfs_replica_remove(null, RPCAuthentication.authNone, userCreds, request); + FileCredentials delCap = response2.get(); + + ServiceUUID osd = new ServiceUUID(headOSDuuid, uuidResolver); + + boolean readOnlyRepl = (oldCreds.getXlocs().getReplicaUpdatePolicy() + .equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)); + + FileCredentials newCreds = FileCredentials.newBuilder().setXcap(delCap.getXcap()) + .setXlocs(oldCreds.getXlocs()).build(); + response3 = osdClient.unlink(osd.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + newCreds, oldCreds.getXcap().getFileId()); + response3.get(); + + } catch (PBRPCException ex) { + if (ex.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_ENOENT) + throw new FileNotFoundException("file '" + fullPath + "' does not exist"); + throw wrapException(ex); + } catch (InterruptedException ex) { + throw wrapException(ex); + } finally { + if (response1 != null) + response1.freeBuffers(); + if (response2 != null) + response2.freeBuffers(); + if (response3 != null) + response3.freeBuffers(); + } + } + + void shutdown() { + ofl.shutdown(); + } + + /** + * @return the maxRetries + */ + public int getMaxRetries() { + return maxRetries; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/clients/internal/ObjectMapper.java b/java/servers/src/org/xtreemfs/common/clients/internal/ObjectMapper.java new file mode 100644 index 0000000..829b810 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/internal/ObjectMapper.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2009 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients.internal; + +import java.util.List; +import org.xtreemfs.common.xloc.Replica; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; + +/** + * + * @author bjko + */ +public abstract class ObjectMapper { + + private StripingPolicy fileSP; + + protected ObjectMapper(StripingPolicy fileSP) { + this.fileSP = fileSP; + } + + public static ObjectMapper getMapper(StripingPolicy fileSP) { + if (fileSP.getType() == StripingPolicyType.STRIPING_POLICY_RAID0) + return new RAID0ObjectMapper(fileSP); + else + throw new RuntimeException("unknown striping policy type: "+fileSP.getType()); + } + + public abstract List readRequest(int length, long fileOffset, Replica replica); + + public abstract List writeRequest(ReusableBuffer data, long fileOffset, Replica replica); + + public static class ObjectRequest { + private final long objNo; + private final int offset; + private final int length; + private ReusableBuffer data; + private final String osdUUID; + + public ObjectRequest(long objNo, int offset, int length, String osdUUID, ReusableBuffer data) { + this.objNo = objNo; + this.offset = offset; + this.data = data; + this.length = length; + this.osdUUID = osdUUID; + } + + /** + * @return the objNo + */ + public long getObjNo() { + return objNo; + } + + /** + * @return the offset + */ + public int getOffset() { + return offset; + } + + /** + * @return the data + */ + public ReusableBuffer getData() { + return data; + } + + /** + * @return the length + */ + public int getLength() { + return length; + } + + /** + * @return the osdUUID + */ + public String getOsdUUID() { + return osdUUID; + } + + /** + * @param data the data to set + */ + public void setData(ReusableBuffer data) { + this.data = data; + } + + } + +} diff --git a/java/servers/src/org/xtreemfs/common/clients/internal/OpenFileList.java b/java/servers/src/org/xtreemfs/common/clients/internal/OpenFileList.java new file mode 100644 index 0000000..c9e01e2 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/internal/OpenFileList.java @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2009 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients.internal; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.clients.RandomAccessFile; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.CONSTANTS; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; + +/** + * + * @author bjko + */ +public class OpenFileList extends Thread { + + private final Map capabilities; + + private final Map fsUpdateCache; + + private final MRCServiceClient client; + + private volatile boolean quit; + + public OpenFileList(MRCServiceClient client) { + super("XCapRNThr"); + capabilities = new HashMap(); + fsUpdateCache = new HashMap(); + this.client = client; + } + + public void openFile(XCap capability, RandomAccessFile f) { + synchronized (capabilities) { + CapEntry e = capabilities.get(capability.getFileId()); + if (e == null) { + e = new CapEntry(capability, TimeSync.getLocalSystemTime()+capability.getExpireTimeoutS()*1000); + capabilities.put(capability.getFileId(),e); + } else { + e.upgradeCap(capability, TimeSync.getLocalSystemTime()+capability.getExpireTimeoutS()*1000); + } + e.addFile(f); + } + } + + public void closeFile(String fileId, RandomAccessFile f) { + boolean lastFile = false; + synchronized (capabilities) { + CapEntry e = capabilities.get(fileId); + if (e != null) { + lastFile = e.removeFile(f); + if (lastFile) + capabilities.remove(fileId); + } else { + throw new IllegalStateException("entry must nut be null"); + } + } + if (lastFile) { + synchronized (fsUpdateCache) { + fsUpdateCache.remove(fileId); + } + } + } + + public OSDWriteResponse sendFsUpdate(String fileId) { + synchronized (fsUpdateCache) { + return fsUpdateCache.remove(fileId); + } + } + + public OSDWriteResponse getLocalFS(String fileId) { + synchronized (fsUpdateCache) { + return fsUpdateCache.get(fileId); + } + } + + public void fsUpdate(String fileId, OSDWriteResponse resp) { + if ((resp == null) || !resp.hasSizeInBytes()) + return; + synchronized (fsUpdateCache) { + OSDWriteResponse last = fsUpdateCache.get(fileId); + if (last == null) { + fsUpdateCache.put(fileId, resp); + return; + } + final OSDWriteResponse newFS = resp; + final OSDWriteResponse oldFS = last; + + if ( (newFS.getTruncateEpoch() > oldFS.getTruncateEpoch()) || + (newFS.getTruncateEpoch() == oldFS.getTruncateEpoch()) && + (newFS.getSizeInBytes() > oldFS.getSizeInBytes()) ) { + fsUpdateCache.put(fileId, resp); + } + } + } + + public XCap getCapability(String fileId) { + synchronized (capabilities) { + CapEntry e = capabilities.get(fileId); + if (e == null) + return null; + return e.getCap(); + } + } + + public void shutdown() { + this.quit = true; + this.interrupt(); + } + + public void run() { + + //check for CAP-renew + + do { + List renewList = new LinkedList(); + synchronized (capabilities) { + //check caps + final long expTime = TimeSync.getLocalSystemTime()+CONSTANTS.XCAP_RENEW_INTERVAL_IN_MIN.getNumber()*60*1000; + for (CapEntry e : capabilities.values()) { + if (e.getLocalTimestamp() <= expTime ) { + //needs renew! + renewList.add(e); + } + } + } + for (CapEntry cap : renewList) { + renewCap(cap); + } + try { + sleep(CONSTANTS.XCAP_RENEW_INTERVAL_IN_MIN.getNumber()*60*1000/2); + } catch (InterruptedException ex) { + break; + } + } while (!quit); + + } + + protected void renewCap(CapEntry cap) { + assert(cap != null); + RPCResponse r = null; + try { + r = client.xtreemfs_renew_capability(null, RPCAuthentication.authNone, RPCAuthentication.userService, cap.getCap()); + XCap newCap = r.get(); + synchronized (capabilities) { + cap.updateCap(newCap, TimeSync.getLocalSystemTime()+CONSTANTS.XCAP_RENEW_INTERVAL_IN_MIN.getNumber()*60*1000-1000); + } + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_ERROR, this,"cannot renew cap due to exception"); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } finally { + if (r != null) + r.freeBuffers(); + } + + } + + public static class CapEntry { + private XCap cap; + private long localTimestamp; + final List files; + + public CapEntry(XCap c, long ts) { + cap = c; + localTimestamp = ts; + files = new LinkedList(); + } + + public void addFile(RandomAccessFile file) { + files.add(file); + } + + public boolean removeFile(RandomAccessFile file) { + files.remove(file); + return files.isEmpty(); + } + + public void updateCap(XCap c, long ts) { + cap = c; + localTimestamp = ts; + for (RandomAccessFile file : files) + file.updateCap(c); + } + + public void upgradeCap(XCap c, long ts) { + //FIXME + /* + * upgrade: always from R to RW + * never from RW to R + */ + if ( ((cap.getAccessMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()) > 0) + && ((c.getAccessMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber()) > 0) ) { + updateCap(c, ts); + } + } + + /** + * @return the cap + */ + public XCap getCap() { + return cap; + } + + /** + * @return the localTimestamp + */ + public long getLocalTimestamp() { + return localTimestamp; + } + } +} diff --git a/java/servers/src/org/xtreemfs/common/clients/internal/RAID0ObjectMapper.java b/java/servers/src/org/xtreemfs/common/clients/internal/RAID0ObjectMapper.java new file mode 100644 index 0000000..a4d4778 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/internal/RAID0ObjectMapper.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2009 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients.internal; + +import java.util.LinkedList; +import java.util.List; +import org.xtreemfs.common.xloc.Replica; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; + +/** + * + * @author bjko + */ +public class RAID0ObjectMapper extends ObjectMapper { + + private final int stripeSize; + + protected RAID0ObjectMapper(StripingPolicy fileSP) { + super(fileSP); + stripeSize = fileSP.getStripeSize()*1024; + } + + @Override + public List readRequest(int length, long fileOffset, Replica replica) { + List reqs = new LinkedList(); + + final long firstObj = fileOffset / stripeSize; + final long lastObj = (fileOffset+length-1) / stripeSize; + final int firstOffset = (int)fileOffset%stripeSize; + + + if (firstObj == lastObj) { + ObjectRequest rq = new ObjectRequest(firstObj, firstOffset, length, + getOSDForObject(replica, firstObj), null); + reqs.add(rq); + return reqs; + } + + //first obj + + ObjectRequest rq = new ObjectRequest(firstObj, firstOffset, stripeSize-firstOffset, + getOSDForObject(replica, firstObj),null); + reqs.add(rq); + + for (long o = firstObj+1; o < lastObj; o++) { + rq = new ObjectRequest(o, 0, stripeSize, + getOSDForObject(replica, o), null); + reqs.add(rq); + } + + //last obj + final int lastSize = ((length+fileOffset)%stripeSize == 0) ? stripeSize : (int) (length+fileOffset)%stripeSize; + if (lastSize > 0) { + rq = new ObjectRequest(lastObj, 0, lastSize, getOSDForObject(replica, lastObj), + null); + reqs.add(rq); + } + + return reqs; + } + + @Override + public List writeRequest(ReusableBuffer data, long fileOffset, Replica replica) { + List reqs = readRequest(data.remaining(), fileOffset, replica); + + int pCnt = 0; + for (ObjectRequest rq : reqs) { + ReusableBuffer viewBuf = data.createViewBuffer(); + viewBuf.range(pCnt, rq.getLength()); + pCnt += rq.getLength(); + rq.setData(viewBuf); + } + return reqs; + } + + protected String getOSDForObject(Replica replica, long objNo) { + return replica.getOSDForObject(objNo).toString(); + } + + +} diff --git a/java/servers/src/org/xtreemfs/common/clients/io/ByteMapper.java b/java/servers/src/org/xtreemfs/common/clients/io/ByteMapper.java new file mode 100644 index 0000000..36eee19 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/io/ByteMapper.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2008 by Nele Andersen, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients.io; + +public interface ByteMapper { + + /** + * reads data from file. + * @param data a buffer of length (length+offset) in which the data is stored + * @param offset offset within buffer to write to + * @param length number of bytes to read + * @param filePosition offset within file + * @return the number of bytes read + * @throws java.lang.Exception + */ + public int read(byte[] data, int offset, int length, long filePosition) throws Exception; + + /** + * writes data to a file. + * @param data the data to write (buffer must be length+offset bytes long). + * @param offset the position within the buffer to start at. + * @param length number of bytes to write + * @param filePosition the offset within the file + * @return the number of bytes written + * @throws java.lang.Exception + */ + public int write(byte[] data, int offset, int length, long filePosition) throws Exception; +} diff --git a/java/servers/src/org/xtreemfs/common/clients/io/ByteMapperFactory.java b/java/servers/src/org/xtreemfs/common/clients/io/ByteMapperFactory.java new file mode 100644 index 0000000..f00fc67 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/io/ByteMapperFactory.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2008 by Nele Andersen, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients.io; + +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; + + +public class ByteMapperFactory { + + public static ByteMapper createByteMapper(int policy, int stripeSize, ObjectStore store) { + if( StripingPolicyType.valueOf(policy) == StripingPolicyType.STRIPING_POLICY_RAID0) + return new ByteMapperRAID0(stripeSize, store); + throw new IllegalArgumentException("Unknown striping policy ID"); + } +} diff --git a/java/servers/src/org/xtreemfs/common/clients/io/ByteMapperRAID0.java b/java/servers/src/org/xtreemfs/common/clients/io/ByteMapperRAID0.java new file mode 100644 index 0000000..247b94e --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/io/ByteMapperRAID0.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2008 by Nele Andersen, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients.io; + +import java.io.IOException; + +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; + +class ByteMapperRAID0 implements ByteMapper { + + final int stripeSize; + + ObjectStore objectStore; + + public ByteMapperRAID0(int stripeSize, ObjectStore objectStore){ + this.stripeSize = stripeSize; + this.objectStore = objectStore; + } + + /** + * + * @param resultBuffer - the buffer into which the data is read. + * @param offset - the start offset of the data. + * @param bytesToRead - the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or -1 if + * there is no more data because the end of the file has been reached. + * @throws Exception + * @throws IOException + */ + public int read(byte[] data, int offset, int length, long filePosition) throws Exception{ + + if (data.length < offset+length) + throw new RuntimeException("buffer is too small!"); + + final int firstObject = (int) (filePosition / this.stripeSize); + assert(firstObject >= 0); + + int lastObject = (int) ( (filePosition + ((long)length)) / this.stripeSize); + if (( (filePosition + ((long)length)) % this.stripeSize) == 0) + lastObject--; + assert(lastObject >= firstObject); + + final int offsetInFirstObject = (int) (filePosition % this.stripeSize); + assert(offsetInFirstObject < stripeSize); + final int bytesInLastObject = (int) (((filePosition + length) % this.stripeSize) == 0 ? this.stripeSize : + ((filePosition + length) % this.stripeSize)); + assert(bytesInLastObject > 0); + assert(bytesInLastObject <= stripeSize); + + int bytesRead = 0; + for (int obj = firstObject; obj <= lastObject; obj++) { + + int bytesToRead = this.stripeSize; + int objOffset = 0; + + if (obj == firstObject) { + objOffset = offsetInFirstObject; + bytesToRead = this.stripeSize - objOffset; + } + if (obj == lastObject) { + if (firstObject == lastObject) { + bytesToRead = bytesInLastObject-objOffset; + } else { + bytesToRead = bytesInLastObject; + } + } + + assert(bytesToRead > 0); + assert(objOffset >= 0); + assert(objOffset < stripeSize); + assert(objOffset+bytesToRead <= stripeSize); + + //System.out.println("read "+obj+" objOffset="+objOffset+" length="+bytesToRead); + + ReusableBuffer rb = objectStore.readObject(obj, objOffset, bytesToRead); + assert(offset+bytesRead <= data.length); + if (rb == null) { + //EOF! + break; + } + if (rb.capacity() < bytesToRead) { + //EOF! + final int dataToRead = Math.min(rb.capacity(),data.length-offset-bytesRead); + rb.get(data, offset+bytesRead,dataToRead); + bytesRead += rb.capacity(); + BufferPool.free(rb); + break; + } + //can get less data then requested! + rb.get(data, offset+bytesRead, rb.remaining()); + + bytesRead += rb.capacity(); + BufferPool.free(rb); + } + return bytesRead; + + } + + public int write(byte[] data, int offset, int length, long filePosition) throws Exception{ + + final int firstObject = (int) (filePosition / this.stripeSize); + int lastObject = (int) ( (filePosition + ((long)length)) / this.stripeSize); + if (( (filePosition + ((long)length)) % this.stripeSize) == 0) + lastObject--; + + final int offsetInFirstObject = (int) (filePosition % this.stripeSize); + + + int bytesInLastObject = -1; + if (firstObject == lastObject) { + bytesInLastObject = length; + } else { + if (((filePosition + length) % this.stripeSize) == 0) { + bytesInLastObject = this.stripeSize; + assert(bytesInLastObject >= 0); + } else { + bytesInLastObject = (int)((filePosition + length) % this.stripeSize); + assert(bytesInLastObject >= 0); + } + } + + + int bytesWritten = 0; + for (int obj = firstObject; obj <= lastObject; obj++) { + + int bytesToWrite = this.stripeSize; + int objOffset = 0; + + if (obj == firstObject) { + bytesToWrite = this.stripeSize-offsetInFirstObject; + objOffset = offsetInFirstObject; + } + if (obj == lastObject) + bytesToWrite = bytesInLastObject; + + + ReusableBuffer view = ReusableBuffer.wrap(data, offset+bytesWritten, bytesToWrite); + objectStore.writeObject(objOffset, obj, view); + bytesWritten += bytesToWrite; + } + return bytesWritten; + + } + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/common/clients/io/ObjectStore.java b/java/servers/src/org/xtreemfs/common/clients/io/ObjectStore.java new file mode 100644 index 0000000..d069a40 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/io/ObjectStore.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008 by Nele Andersen, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients.io; + +import java.io.IOException; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; + +public interface ObjectStore { + + /** + * read an object from an OSD. + * @param offset offset within the object + * @param objectNo object number (0 is the first object in a file) + * @param length number of bytes to read + * @return the data read. In case of an EOF the buffer's length will be smaller than requested! + * @throws java.io.IOException + * @throws org.xtreemfs.foundation.json.JSONException + * @throws java.lang.InterruptedException + * @throws org.xtreemfs.common.clients.HttpErrorException + */ + ReusableBuffer readObject(long objectNo, int offset, int length) throws IOException, + InterruptedException; + + void writeObject(long offset, long objectNo, ReusableBuffer buffer) throws IOException, + InterruptedException; +} diff --git a/java/servers/src/org/xtreemfs/common/clients/io/RandomAccessFile.java b/java/servers/src/org/xtreemfs/common/clients/io/RandomAccessFile.java new file mode 100644 index 0000000..ca660cd --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/clients/io/RandomAccessFile.java @@ -0,0 +1,970 @@ +///* Copyright (c) 2008 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin. +// +//This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based +//Grid Operating System, see for more details. +//The XtreemOS project has been developed with the financial support of the +//European Commission's IST program under contract #FP6-033576. +// +//XtreemFS is free software: you can redistribute it and/or modify it under +//the terms of the GNU General Public License as published by the Free +//Software Foundation, either version 2 of the License, or (at your option) +//any later version. +// +//XtreemFS is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with XtreemFS. If not, see . +// */ +///* +// * AUTHORS: Nele Andersen (ZIB), Björn Kolbeck (ZIB), Christian Lorenz (ZIB) +// */ +//package org.xtreemfs.common.clients.io; +// +//import java.io.IOException; +//import java.net.InetSocketAddress; +//import java.util.ArrayList; +//import java.util.Collections; +//import java.util.Iterator; +//import java.util.List; +//import java.util.concurrent.atomic.AtomicLong; +// +//import org.xtreemfs.common.uuids.ServiceUUID; +//import org.xtreemfs.common.xloc.InvalidXLocationsException; +//import org.xtreemfs.common.xloc.Replica; +//import org.xtreemfs.common.xloc.StripingPolicyImpl; +//import org.xtreemfs.common.xloc.XLocations; +//import org.xtreemfs.foundation.buffer.BufferPool; +//import org.xtreemfs.foundation.buffer.ReusableBuffer; +//import org.xtreemfs.foundation.logging.Logging; +//import org.xtreemfs.foundation.logging.Logging.Category; +//import org.xtreemfs.foundation.monitoring.Monitoring; +//import org.xtreemfs.foundation.monitoring.NumberMonitoring; +//import org.xtreemfs.foundation.oncrpc.client.RPCNIOSocketClient; +//import org.xtreemfs.foundation.oncrpc.client.RPCResponse; +//import org.xtreemfs.foundation.oncrpc.utils.ONCRPCException; +//import org.xtreemfs.interfaces.Constants; +//import org.xtreemfs.interfaces.FileCredentials; +//import org.xtreemfs.interfaces.FileCredentialsSet; +//import org.xtreemfs.interfaces.NewFileSize; +//import org.xtreemfs.interfaces.OSDWriteResponse; +//import org.xtreemfs.interfaces.ObjectData; +//import org.xtreemfs.interfaces.Stat; +//import org.xtreemfs.interfaces.StatSet; +//import org.xtreemfs.interfaces.StringSet; +//import org.xtreemfs.interfaces.StripingPolicy; +//import org.xtreemfs.interfaces.UserCredentials; +//import org.xtreemfs.interfaces.VivaldiCoordinates; +//import org.xtreemfs.interfaces.XCap; +//import org.xtreemfs.interfaces.MRCInterface.MRCInterface; +//import org.xtreemfs.interfaces.MRCInterface.setxattrResponse; +//import org.xtreemfs.interfaces.OSDInterface.OSDException; +//import org.xtreemfs.mrc.ac.FileAccessManager; +//import org.xtreemfs.mrc.client.MRCClient; +//import org.xtreemfs.osd.ErrorCodes; +//import org.xtreemfs.osd.client.OSDClient; +// +///** +// * @deprecated +// */ +//public class RandomAccessFile implements ObjectStore { +// /** +// * resorts the replicas
    +// * 12.05.2009 +// */ +// public abstract static class ReplicaSelectionPolicy { +// public abstract List getReplicaOrder(List replicas); +// } +// +// /** +// * policy randomizes the entries in list
    +// * DEFAULT POLICY +// */ +// public final ReplicaSelectionPolicy RANDOM_REPLICA_SELECTION_POLICY = new RandomAccessFile.ReplicaSelectionPolicy() { +// @Override +// public List getReplicaOrder( +// List replicas) { +// List list = new ArrayList( +// replicas); +// Collections +// .shuffle(list); +// return list; +// } +// }; +// +// /** +// * policy rotates the entries in list (like round-robin) +// */ +// public final ReplicaSelectionPolicy SEQUENTIAL_REPLICA_SELECTION_POLICY = new RandomAccessFile.ReplicaSelectionPolicy() { +// private int rotateValue = 0; +// +// @Override +// public List getReplicaOrder( +// List replicas) { +// List list = new ArrayList( +// replicas); +// Collections +// .rotate( +// list, +// rotateValue); +// rotateValue = 0 - (((0 - rotateValue) + 1) % list +// .size()); +// return list; +// } +// }; +// +// private static final int DEFAULT_CAP_VALIDITY = 60; +// +// private MRCClient mrcClient; +// +// private OSDClient osdClient; +// +// private FileCredentials fileCredentials; +// +// // all replicas have the same stripesize at the moment +// private StripingPolicyImpl stripingPolicy; +// +// private final String fileId; +// +// private final int mode; +// +// private final String volName; +// +// private final String pathName; +// +// private final InetSocketAddress mrcAddress; +// +// private ByteMapper byteMapper; +// +// private OSDWriteResponse wresp; +// +// private long filePos; +// +// private XLocations xLoc; +// +// private long capTime; +// +// private List replicaOrder; +// +// private boolean isReadOnly; +// +// private final UserCredentials credentials; +// +// private ReplicaSelectionPolicy replicaSelectionPolicy; +// +// /* +// * monitoring stuff +// */ +// private AtomicLong monitoringReadDataSizeInLastXs; +// +// private Thread monitoringThread = null; +// +// private NumberMonitoring monitoring; +// +// /** +// * Measures the throughput of the last 1 second. +// */ +// public static final String MONITORING_KEY_THROUGHPUT_OF_LAST_X_SECONDS = "RAF: throughput of last X seconds (KB/s)"; +// +// // /** +// // * Measures the throughput of the read data so far. Just the time required +// // * for the real network-transfer will be used. +// // */ +// // public static final String MONITORING_KEY_THROUGHPUT = +// // "RAF: throughput of all read data so far (KB/s)"; +// +// public static final int MONITORING_INTERVAL = 1000; // 10s +// +// public RandomAccessFile(String mode, InetSocketAddress mrcAddress, String pathName, +// RPCNIOSocketClient rpcClient, String userID, List groupIDs) throws ONCRPCException, +// InterruptedException, IOException { +// this(mode, mrcAddress, pathName, rpcClient, MRCClient.getCredentials(userID, groupIDs)); +// } +// +// public RandomAccessFile(String mode, InetSocketAddress mrcAddress, String pathName, +// RPCNIOSocketClient rpcClient, UserCredentials credentials) throws ONCRPCException, +// InterruptedException, IOException { +// +// this.mrcAddress = mrcAddress; +// this.mode = translateMode(mode); +// +// int index = pathName.indexOf('/'); +// if (index == -1) +// throw new IOException("invalid path: " + pathName); +// +// this.volName = pathName.substring(0, index); +// this.pathName = pathName.substring(index + 1); +// +// assert (rpcClient != null); +// +// // use the shared speedy to create an MRC and OSD client +// mrcClient = new MRCClient(rpcClient, mrcAddress); +// osdClient = new OSDClient(rpcClient); +// +// this.credentials = credentials; +// +// // OSD selection +// this.replicaSelectionPolicy = RANDOM_REPLICA_SELECTION_POLICY; +// +// // create a new file if necessary +// RPCResponse r = mrcClient.open(mrcAddress, credentials, volName, this.pathName, +// FileAccessManager.O_CREAT, this.mode, 0, new VivaldiCoordinates()); +// fileCredentials = r.get(); +// r.freeBuffers(); +// +// if (fileCredentials.getXlocs().getReplicas().size() == 0) { +// throw new IOException("cannot assign OSDs to file"); +// } +// +// // all replicas have the same striping policy (more precisely the same +// // stripesize) at the moment +// stripingPolicy = StripingPolicyImpl.getPolicy(fileCredentials.getXlocs().getReplicas().get(0), 0); +// try { +// this.xLoc = new XLocations(fileCredentials.getXlocs(), null); +// } catch (InvalidXLocationsException ex) { +// // ignore +// } +// +// // always use first replica at beginning (original order) +// replicaOrder = this.replicaSelectionPolicy.getReplicaOrder(xLoc.getReplicas()); +// +// byteMapper = ByteMapperFactory.createByteMapper(stripingPolicy.getPolicyId(), stripingPolicy +// .getStripeSizeForObject(0), this); +// +// capTime = System.currentTimeMillis(); +// +// isReadOnly = fileCredentials.getXlocs().getReplica_update_policy().equals( +// Constants.REPL_UPDATE_PC_RONLY); +// +// fileId = fileCredentials.getXcap().getFile_id(); +// wresp = null; +// filePos = 0; +// +// monitoring = new NumberMonitoring(); +// monitoringReadDataSizeInLastXs = new AtomicLong(0); +// if (Monitoring.isEnabled()) { +// // enable statistics in client +// RPCNIOSocketClient.ENABLE_STATISTICS = true; +// +// monitoringThread = new Thread(new Runnable() { +// @Override +// public void run() { +// try { +// while (true) { +// if (Thread.interrupted()) +// break; +// Thread.sleep(MONITORING_INTERVAL); // sleep +// +// long sizeInLastXs = monitoringReadDataSizeInLastXs.getAndSet(0); +// if (sizeInLastXs > 0) // log only interesting values +// monitoring.put(MONITORING_KEY_THROUGHPUT_OF_LAST_X_SECONDS, +// (sizeInLastXs / 1024d) / (MONITORING_INTERVAL / 1000d)); +// } +// } catch (InterruptedException e) { +// // shutdown +// } +// } +// }); +// monitoringThread.setDaemon(true); +// monitoringThread.start(); +// } +// } +// +// private static int translateMode(String mode) { +// if (mode.equals("r")) +// return FileAccessManager.O_RDONLY; +// if (mode.startsWith("rw")) +// return FileAccessManager.O_RDWR; +// throw new IllegalArgumentException("invalid mode"); +// } +// +// private void updateWriteResponse(OSDWriteResponse r) { +// if (r.getNew_file_size().size() > 0) { +// final NewFileSize nfs = r.getNew_file_size().get(0); +// if (wresp == null) { +// wresp = r; +// } else { +// final NewFileSize ofs = wresp.getNew_file_size().get(0); +// if ((nfs.getSize_in_bytes() > ofs.getSize_in_bytes()) +// && (nfs.getTruncate_epoch() == ofs.getTruncate_epoch()) +// || (nfs.getTruncate_epoch() > ofs.getTruncate_epoch())) { +// wresp = r; +// } +// } +// } +// } +// +// /** +// * +// * @param resultBuffer +// * - the buffer into which the data is read. +// * @param offset +// * - the start offset of the data. +// * @param bytesToRead +// * - the maximum number of bytes read. +// * @return - the total number of bytes read into the buffer, or -1 if there +// * is no more data because the end of the file has been reached. +// * @throws Exception +// * @throws IOException +// */ +// public int read(byte[] resultBuffer, int offset, int bytesToRead) throws Exception { +// +// int tmp = byteMapper.read(resultBuffer, offset, bytesToRead, filePos); +// filePos += tmp; +// return tmp; +// } +// +// public ReusableBuffer readObject(long objectNo) throws IOException { +// return readObject(objectNo, 0, stripingPolicy.getStripeSizeForObject(objectNo)); +// } +// +// /** +// * +// * @param objectNo +// * - relative object number. +// * @param firstByteInObject +// * - the first byte to be read. +// * @param bytesInObject +// * - the maximal number of bytes to be read. +// * @return a ReusableBuffer containing the data which was read. +// */ +// @Override +// public ReusableBuffer readObject(long objectNo, int offset, int length) throws IOException { +// +// RPCResponse response = null; +// +// int size = 0; +// ObjectData data = null; +// ReusableBuffer buffer = null; +// Iterator iterator = this.replicaOrder.iterator(); +// while (iterator.hasNext()) { // will be aborted, if object could be read +// Replica replica = iterator.next(); +// // check whether capability needs to be renewed +// checkCap(); +// +// // get OSD +// ServiceUUID osd = replica.getOSDForObject(objectNo); +// try { +// if (Logging.isDebug()) +// Logging.logMessage(Logging.LEVEL_DEBUG, Category.tool, this, +// "%s:%d - read object from OSD %s", fileId, objectNo, osd); +// +// response = osdClient.read(osd.getAddress(), fileId, fileCredentials, objectNo, 0, offset, +// length); +// data = response.get(); +// +// if (data.getInvalid_checksum_on_osd()) { +// // try next replica +// if (!iterator.hasNext()) { // all replicas had been tried +// throw new IOException("object " + objectNo + " has an invalid checksum"); +// } +// } +// +// // fill up with padding zeros +// if (data.getZero_padding() == 0) { +// buffer = data.getData(); +// } else { +// final int dataSize = data.getData().capacity(); +// if (data.getData().enlarge(dataSize + data.getZero_padding())) { +// data.getData().position(dataSize); +// while (data.getData().hasRemaining()) +// data.getData().put((byte) 0); +// buffer = data.getData(); +// buffer.position(0); +// } else { +// buffer = BufferPool.allocate(dataSize + data.getZero_padding()); +// buffer.put(data.getData()); +// while (buffer.hasRemaining()) +// buffer.put((byte) 0); +// buffer.position(0); +// BufferPool.free(data.getData()); +// } +// } +// +// // // monitor data for throughput +// // if (Monitoring.isEnabled()) { +// // monitoring.putAverage(MONITORING_KEY_THROUGHPUT, +// // (buffer.limit() / 1024d) +// // / (response.getDuration() / 1000000000d)); +// // monitoringReadDataSizeInLastXs.addAndGet(buffer.limit()); +// // } +// +// break; +// +// } catch (OSDException ex) { +// if (buffer != null) +// BufferPool.free(buffer); +// // all replicas had been tried or replication has been failed +// if (ex instanceof OSDException) +// if (iterator.hasNext() || ((OSDException) ex).getError_code() != ErrorCodes.IO_ERROR) +// continue; +// throw new IOException("cannot read object", ex); +// } catch (ONCRPCException ex) { +// if (buffer != null) +// BufferPool.free(buffer); +// // all replicas had been tried or replication has been failed +// throw new IOException("cannot read object: " + ex.getMessage(), ex); +// } catch (IOException ex) { +// if (buffer != null) +// BufferPool.free(buffer); +// // all replicas had been tried +// if (!iterator.hasNext()) { +// throw new IOException("cannot read object", ex); +// } +// } catch (InterruptedException ex) { +// // ignore +// } finally { +// if (response != null) { +// response.freeBuffers(); +// } +// } +// } +// return buffer; +// } +// +// /** +// * +// * @param objectNo +// * @return +// * @throws IOException +// */ +// public int checkObject(long objectNo) throws IOException { +// checkCap(); +// +// RPCResponse response = null; +// +// int size = 0; +// ObjectData data = null; +// ReusableBuffer buffer = null; +// Iterator iterator = this.replicaOrder.iterator(); +// while (iterator.hasNext()) { // will be aborted, if object could be read +// Replica replica = iterator.next(); +// try { +// // get OSD +// ServiceUUID osd = replica.getOSDForObject(objectNo); +// +// response = osdClient.check_object(osd.getAddress(), fileId, fileCredentials, objectNo, 0); +// data = response.get(); +// +// if (data.getInvalid_checksum_on_osd()) { +// // try next replica +// if (!iterator.hasNext()) { // all replicas had been tried +// throw new IOException("object " + objectNo + " has an invalid checksum"); +// } +// } +// +// size = data.getZero_padding(); +// +// break; +// } catch (ONCRPCException ex) { +// if (buffer != null) +// BufferPool.free(buffer); +// // all replicas had been tried or replication has been failed +// if (!iterator.hasNext() || ((OSDException) ex).getError_code() == ErrorCodes.IO_ERROR) { +// throw new IOException("cannot read object", ex); +// } +// } catch (IOException ex) { +// if (buffer != null) +// BufferPool.free(buffer); +// // all replicas had been tried +// if (!iterator.hasNext()) { +// throw new IOException("cannot read object", ex); +// } +// } catch (InterruptedException ex) { +// // ignore +// } finally { +// if (response != null) { +// response.freeBuffers(); +// } +// if ((data != null) && (data.getData() != null)) { +// BufferPool.free(data.getData()); +// data.setData(null); +// } +// } +// } +// return size; +// } +// +// /** +// * Writes bytesToWrite bytes from the writeFromBuffer byte array starting at +// * offset to this file. +// * +// * @param writeFromBuffer +// * @param offset +// * @param bytesToWrite +// * @return the number of bytes written +// * @throws Exception +// */ +// public int write(byte[] writeFromBuffer, int offset, int bytesToWrite) throws Exception { +// +// int tmp = byteMapper.write(writeFromBuffer, offset, bytesToWrite, filePos); +// filePos += bytesToWrite; +// return tmp; +// } +// +// /** +// * Writes... +// * +// * @param firstByteInObject +// * - the start offset in the file +// * @param objectNo +// * - the relative object number +// * @param data +// * - the data to be written..... +// */ +// public void writeObject(long firstByteInObject, long objectNo, ReusableBuffer data) throws IOException { +// +// // check whether capability needs to be renewed +// checkCap(); +// +// if (isReadOnly) +// throw new IOException("File is marked as read-only. You cannot write anymore."); +// +// RPCResponse response = null; +// try { +// // uses always first replica +// ServiceUUID osd = replicaOrder.get(0).getOSDs().get(stripingPolicy.getOSDforObject(objectNo)); +// ObjectData odata = new ObjectData(0, false, 0, data); +// response = osdClient.write(osd.getAddress(), fileId, fileCredentials, objectNo, 0, +// (int) firstByteInObject, 0, odata); +// OSDWriteResponse owr = response.get(); +// this.updateWriteResponse(owr); +// } catch (ONCRPCException ex) { +// throw new IOException("cannot write object: " + ex.getMessage(), ex); +// } catch (InterruptedException ex) { +// throw new IOException("cannot write object", ex); +// } finally { +// if (response != null) +// response.freeBuffers(); +// } +// +// } +// +// public void flush() throws IOException { +// if (wresp != null) { +// RPCResponse r = null; +// try { +// long fs = wresp.getNew_file_size().get(0).getSize_in_bytes(); +// int ep = wresp.getNew_file_size().get(0).getTruncate_epoch(); +// r = mrcClient.fsetattr(mrcAddress, fileCredentials.getXcap(), new Stat(0, 0, 0, 0, "", "", +// fs, 0, 0, 0, 0, 0, ep, 0), MRCInterface.SETATTR_SIZE); +// r.get(); +// wresp = null; +// } catch (ONCRPCException ex) { +// throw new IOException("cannot write object", ex); +// } catch (InterruptedException ex) { +// throw new IOException("cannot write object", ex); +// } finally { +// if (r != null) +// r.freeBuffers(); +// } +// } +// } +// +// public void delete() throws Exception { +// checkCap(); +// +// if (fileCredentials.getXlocs().getReplicas().size() == 1) { +// RPCResponse r = null; +// RPCResponse delR = null; +// try { +// r = mrcClient.unlink(mrcAddress, credentials, volName, pathName); +// FileCredentialsSet fcreds = r.get(); +// if (fcreds.size() > 0) { +// // must delete on OSDs too! +// final FileCredentials delCred = fcreds.get(0); +// // uses always first replica +// delR = osdClient.unlink(replicaOrder.get(0).getHeadOsd().getAddress(), fileId, delCred); +// delR.get(); +// delR.freeBuffers(); +// } +// } catch (ONCRPCException ex) { +// throw new IOException("cannot write object", ex); +// } catch (InterruptedException ex) { +// throw new IOException("cannot write object", ex); +// } finally { +// if (r != null) +// r.freeBuffers(); +// } +// } else { +// throw new IOException("There is more than 1 replica existing. Delete all replicas first."); +// } +// } +// +// public long length() throws IOException { +// RPCResponse r = null; +// try { +// r = mrcClient.getattr(mrcAddress, credentials, volName, pathName); +// Stat statInfo = r.get().get(0); +// +// // decide what to use... +// if (wresp != null) { +// final NewFileSize localFS = wresp.getNew_file_size().get(0); +// +// // check if we know a larger file size locally +// if (localFS.getTruncate_epoch() < statInfo.getTruncate_epoch()) +// return statInfo.getSize(); +// if (localFS.getSize_in_bytes() > statInfo.getSize()) +// return localFS.getSize_in_bytes(); +// } +// return statInfo.getSize(); +// } catch (ONCRPCException ex) { +// throw new IOException("cannot write object", ex); +// } catch (InterruptedException ex) { +// throw new IOException("cannot write object", ex); +// } finally { +// if (r != null) +// r.freeBuffers(); +// } +// +// } +// +// public void close() throws IOException { +// flush(); +// +// // shutdown +// if (monitoringThread != null) +// monitoringThread.interrupt(); +// } +// +// /** +// * Sets the file read-only and changes the access mode to "r", if mode is +// * "true". Sets the file writable and changes the access mode to the +// * original mode, if mode is "false" and no replicas exist. +// * +// * @param mode +// * @throws Exception +// */ +// public void setReadOnly(boolean mode) throws Exception { +// if (isReadOnly == mode) +// return; +// +// try { +// if (mode) { +// flush(); +// +// // set read only +// RPCResponse r = mrcClient.setxattr(mrcAddress, credentials, volName, +// pathName, "xtreemfs.read_only", "true", 0); +// r.get(); +// r.freeBuffers(); +// +// forceXCapUpdate(); +// +// // get correct filesize +// RPCResponse r2 = osdClient.internal_get_file_size(replicaOrder.get(0).getHeadOsd() +// .getAddress(), fileId, fileCredentials); +// long filesize = r2.get(); +// r2.freeBuffers(); +// +// // set filesize on mrc +// forceFileSize(filesize); +// +// forceFileCredentialsUpdate(translateMode("r")); +// } else { +// if (fileCredentials.getXlocs().getReplicas().size() > 1) +// throw new IOException("File has still replicas."); +// else { +// // set read only +// RPCResponse r = mrcClient.setxattr(mrcAddress, credentials, volName, +// pathName, "xtreemfs.read_only", "false", 0); +// r.get(); +// r.freeBuffers(); +// +// forceFileCredentialsUpdate(this.mode); +// } +// } +// } catch (ONCRPCException ex) { +// throw new IOException("Cannot change objects read-only-state.", ex); +// } catch (InterruptedException ex) { +// throw new IOException("Cannot change objects read-only-state.", ex); +// } +// } +// +// /** +// * adds a replica for this file +// * +// * @param osds +// * @param spPolicy +// * @param replicationFlags +// * @throws Exception +// */ +// public void addReplica(List osds, StripingPolicy spPolicy, int replicationFlags) +// throws Exception { +// // check correct parameters +// if (spPolicy.getStripe_size() != stripingPolicy.getPolicy().getStripe_size()) +// throw new IllegalArgumentException("New replica must have a stripe size of " +// + stripingPolicy.getPolicy().getStripe_size() + " (given value is " +// + spPolicy.getStripe_size() + ")."); +// if (osds.size() != spPolicy.getWidth()) +// throw new IllegalArgumentException("Too many or less OSDs in list."); +// for (ServiceUUID osd : osds) { +// if (xLoc.containsOSD(osd)) // OSD is used for any replica so far +// throw new IllegalArgumentException( +// "At least one OSD from list is already used for this file."); +// } +// +// if (isReadOnly) { +// StringSet osdSet = new StringSet(); +// for (ServiceUUID osd : osds) { +// osdSet.add(osd.toString()); +// } +// +// org.xtreemfs.interfaces.Replica newReplica = new org.xtreemfs.interfaces.Replica(osdSet, +// replicationFlags, spPolicy); +// RPCResponse r = mrcClient.xtreemfs_replica_add(mrcAddress, credentials, fileId, newReplica); +// r.get(); +// r.freeBuffers(); +// +// forceFileCredentialsUpdate(translateMode("r")); +// +// replicaOrder = replicaSelectionPolicy.getReplicaOrder(xLoc.getReplicas()); +// } else +// throw new IOException("File is not marked as read-only."); +// } +// +// /** +// * removes a replica for this file +// * +// * @param replica +// * @throws Exception +// */ +// public void removeReplica(Replica replica) throws Exception { +// removeReplica(replica.getHeadOsd()); +// } +// +// /** +// * removes a replica for this file +// * +// * @param osd +// * @throws Exception +// */ +// public void removeReplica(ServiceUUID osd) throws Exception { +// if (isReadOnly) { +// if (fileCredentials.getXlocs().getReplicas().size() < 2) +// throw new IOException("Cannot remove last replica."); +// +// boolean otherCompleteReplicaExists = false; +// if (xLoc.getReplica(osd).isComplete()) { // complete replica +// // check if another replica is also complete +// for (Replica r : xLoc.getReplicas()) +// if (r.isComplete() && !r.equals(xLoc.getReplica(osd))) { +// otherCompleteReplicaExists = true; +// break; +// } +// if (!otherCompleteReplicaExists) +// throw new IOException( +// "This is the last remaining COMPLETE replica. It cannot be removed," +// + " otherwise it can happen that the file will be destroyed."); +// } +// +// RPCResponse r = mrcClient.xtreemfs_replica_remove(mrcAddress, credentials, fileId, osd +// .toString()); +// XCap deleteCap = r.get(); +// r.freeBuffers(); +// +// RPCResponse r2 = osdClient.unlink(osd.getAddress(), fileId, new FileCredentials(deleteCap, +// fileCredentials.getXlocs())); +// r2.get(); +// r2.freeBuffers(); +// +// forceFileCredentialsUpdate(translateMode("r")); +// +// replicaOrder = replicaSelectionPolicy.getReplicaOrder(xLoc.getReplicas()); +// } else +// throw new IOException("File is not marked as read-only."); +// } +// +// /** +// * removes "all" replicas, so that only one (the first) replica exists +// */ +// public void removeAllReplicas() throws Exception { +// List replicas = xLoc.getReplicas(); +// for (int i = 1; i < replicas.size(); i++) { +// removeReplica(replicas.get(i)); +// } +// } +// +// /** +// * returns suitable OSDs which can be used for a replica of this file +// * +// * @return +// * @throws Exception +// */ +// public List getSuitableOSDsForAReplica() throws Exception { +// +// assert (xLoc.getNumReplicas() > 0); +// +// RPCResponse r = mrcClient.xtreemfs_get_suitable_osds(mrcAddress, fileId, xLoc +// .getReplica(0).getOSDs().size()); +// StringSet osds = r.get(); +// r.freeBuffers(); +// +// ArrayList osdList = new ArrayList(); +// for (String osd : osds) { +// ServiceUUID uuid = new ServiceUUID(osd); +// osdList.add(uuid); +// } +// return osdList; +// } +// +// public void setReplicaSelectionPolicy(ReplicaSelectionPolicy policy) { +// replicaSelectionPolicy = policy; +// replicaOrder = replicaSelectionPolicy.getReplicaOrder(xLoc.getReplicas()); +// stripingPolicy = replicaOrder.get(0).getStripingPolicy(); +// } +// +// // useful for tests +// public void changeReplicaOrder() { +// replicaOrder = replicaSelectionPolicy.getReplicaOrder(xLoc.getReplicas()); +// stripingPolicy = replicaOrder.get(0).getStripingPolicy(); +// } +// +// /** +// * returns the StripingPolicy of the first replica (but at the moment it is +// * the same for all replicas) +// * +// * @return +// */ +// public StripingPolicy getStripingPolicy() { +// return stripingPolicy.getPolicy(); +// } +// +// /** +// * returns the stripe size of used replica in bytes +// * +// * @return +// */ +// public long getStripeSize() { +// // the stripe size of a file is constant. +// return stripingPolicy.getPolicy().getStripe_size(); +// } +// +// public XLocations getXLoc() { +// return xLoc; +// } +// +// public boolean isReadOnly() { +// return isReadOnly; +// } +// +// public Replica getCurrentlyUsedReplica() { +// return replicaOrder.get(0); +// } +// +// public long noOfObjects() throws Exception { +// // all replicas have the same striping policy (more precisely the same +// // stripesize) at the moment +// return stripingPolicy.getObjectNoForOffset(length() - 1); +// } +// +// public String getFileId() { +// return fileId; +// } +// +// public String getPath() { +// return volName + "/" + pathName; +// } +// +// public void seek(long pos) { +// filePos = pos; +// } +// +// public long getFilePointer() { +// return filePos; +// } +// +// public String getStripingPolicyAsString() { +// return fileCredentials.getXlocs().getReplicas().get(0).toString(); +// } +// +// public FileCredentials getCredentials() { +// return this.fileCredentials; +// } +// +// private void checkCap() throws IOException { +// +// long time = System.currentTimeMillis(); +// +// if (time - capTime > (DEFAULT_CAP_VALIDITY - 60) * 1000) { +// try { +// forceXCapUpdate(); +// } catch (Exception e) { +// throw new IOException(e); +// } +// } +// } +// +// private void forceXCapUpdate() throws IOException { +// // update Xcap +// try { +// RPCResponse r = mrcClient.xtreemfs_renew_capability(mrcAddress, fileCredentials.getXcap()); +// XCap cap = r.get(); +// r.freeBuffers(); +// +// fileCredentials.setXcap(cap); +// +// capTime = System.currentTimeMillis(); +// } catch (Exception e) { +// throw new IOException(e); +// } +// } +// +// /** +// * @throws ONCRPCException +// * @throws IOException +// * @throws InterruptedException +// */ +// private void forceFileCredentialsUpdate(int mode) throws ONCRPCException, IOException, +// InterruptedException { +// try { +// RPCResponse r = mrcClient.open(mrcAddress, credentials, volName, pathName, +// FileAccessManager.O_CREAT, mode, 0, new VivaldiCoordinates()); +// fileCredentials = r.get(); +// r.freeBuffers(); +// xLoc = new XLocations(fileCredentials.getXlocs(), null); +// isReadOnly = fileCredentials.getXlocs().getReplica_update_policy().equals( +// Constants.REPL_UPDATE_PC_RONLY); +// } catch (InvalidXLocationsException ex) { +// throw new IOException(ex); +// } +// } +// +// public void forceFileSize(long newFileSize) throws IOException { +// RPCResponse r = null; +// try { +// r = mrcClient.fsetattr(mrcAddress, fileCredentials.getXcap(), new Stat(0, 0, 0, 0, "", "", +// newFileSize, 0, 0, 0, 0, 0, fileCredentials.getXcap().getTruncate_epoch(), 0), +// MRCInterface.SETATTR_SIZE); +// r.get(); +// } catch (ONCRPCException ex) { +// throw new IOException("cannot update file size", ex); +// } catch (InterruptedException ex) { +// throw new IOException("cannot update file size", ex); +// } finally { +// if (r != null) +// r.freeBuffers(); +// } +// } +// +// public Stat stat() throws IOException { +// RPCResponse r = null; +// try { +// r = mrcClient.getattr(mrcAddress, credentials, volName, pathName); +// return r.get().get(0); +// } catch (ONCRPCException ex) { +// throw new IOException("cannot update file size", ex); +// } catch (InterruptedException ex) { +// throw new IOException("cannot update file size", ex); +// } finally { +// if (r != null) +// r.freeBuffers(); +// } +// } +// +// public NumberMonitoring getMonitoringInfo() { +// return monitoring; +// } +//} diff --git a/java/servers/src/org/xtreemfs/common/config/Config.java b/java/servers/src/org/xtreemfs/common/config/Config.java new file mode 100644 index 0000000..bda4f87 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/config/Config.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, Bjoern Kolbeck, + * Jan Stender, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.config; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.Properties; + +import org.xtreemfs.foundation.logging.Logging; + +/** + * + * @author bjko + */ +abstract public class Config { + + protected final Properties props; + + public Config() { + props = new Properties(); + } + + public Config(Properties prop) { + this.props = new Properties(prop); + } + + /** Creates a new instance of {@link Config} */ + public Config(String filename) throws IOException { + props = new Properties(); + props.load(new FileInputStream(filename)); + } + + /** + * Writes out a properties-compatible file at the given location. + * @param filename + * @throws IOException + * @throws FileNotFoundException + */ + protected void write(String filename) throws FileNotFoundException, IOException { + props.store(new FileOutputStream(filename), ""); + } + + protected int readRequiredInt(String paramName) { + String tmp = props.getProperty(paramName); + if (tmp == null) + throw new RuntimeException("property '" + paramName + + "' is required but was not found"); + try { + return Integer.parseInt(tmp.trim()); + } catch (NumberFormatException ex) { + throw new RuntimeException("property '" + paramName + + "' is an integer but '" + tmp + "' is not a valid number"); + } + } + + protected String readRequiredString(String paramName) { + String tmp = props.getProperty(paramName); + if (tmp == null) + throw new RuntimeException("property '" + paramName + + "' is required but was not found"); + return tmp.trim(); + } + + protected InetSocketAddress readRequiredInetAddr(String hostParam, + String portParam) { + String host = readRequiredString(hostParam); + int port = readRequiredInt(portParam); + InetSocketAddress isa = new InetSocketAddress(host, port); + return isa; + } + + protected boolean readRequiredBoolean(String paramName) { + String tmp = props.getProperty(paramName); + if (tmp == null) + throw new RuntimeException("property '" + paramName + + "' is required but was not found"); + return Boolean.parseBoolean(tmp.trim()); + } + + protected boolean readOptionalBoolean(String paramName, boolean defaultValue) { + String tmp = props.getProperty(paramName); + if (tmp == null) + return defaultValue; + else + return Boolean.parseBoolean(tmp.trim()); + } + + protected int readOptionalInt(String paramName, int defaultValue) { + String tmp = props.getProperty(paramName); + if (tmp == null) + return defaultValue; + else + return Integer.parseInt(tmp.trim()); + } + + protected InetAddress readOptionalInetAddr(String paramName, + InetAddress defaultValue) throws UnknownHostException { + String tmp = props.getProperty(paramName); + if (tmp == null) + return defaultValue; + else + return InetAddress.getByName(tmp); + } + + protected InetSocketAddress readOptionalInetSocketAddr(String hostName, + String portParam, InetSocketAddress defaultValue) { + String host = readOptionalString(hostName, null); + int port = readOptionalInt(portParam, -1); + if (host==null || port==-1) + return defaultValue; + else + return new InetSocketAddress(host,port); + } + + protected String readOptionalString(String paramName, String defaultValue) { + return props.getProperty(paramName, defaultValue); + } + + protected int readOptionalDebugLevel() { + String level = props.getProperty("debug.level"); + if (level == null) + return Logging.LEVEL_WARN; + else { + + level = level.trim().toUpperCase(); + + if (level.equals("EMERG")) { + return Logging.LEVEL_EMERG; + } else if (level.equals("ALERT")) { + return Logging.LEVEL_ALERT; + } else if (level.equals("CRIT")) { + return Logging.LEVEL_CRIT; + } else if (level.equals("ERR")) { + return Logging.LEVEL_ERROR; + } else if (level.equals("WARNING")) { + return Logging.LEVEL_WARN; + } else if (level.equals("NOTICE")) { + return Logging.LEVEL_NOTICE; + } else if (level.equals("INFO")) { + return Logging.LEVEL_INFO; + } else if (level.equals("DEBUG")) { + return Logging.LEVEL_DEBUG; + } else { + + try { + int levelInt = Integer.valueOf(level); + return levelInt; + } catch (NumberFormatException ex) { + throw new RuntimeException("'" + level + + "' is not a valid level name nor an integer"); + } + } + } + } + + public Properties getProps() { + return props; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/config/PolicyClassLoader.java b/java/servers/src/org/xtreemfs/common/config/PolicyClassLoader.java new file mode 100644 index 0000000..8e19fd8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/config/PolicyClassLoader.java @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.config; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.foundation.util.OutputUtils; + +/** + * A class loader capable of loading policy classes from a given policy + * directory. + *

    + * + * It allows for an efficient retrieval of policies by means of a policy ID and + * interface. Three requirements have to be met: + *

      + *
    • the policy needs to be assignable from any of the given policy interfaces + *
    • the policy either needs to be in the list of built-in policies, or in the + * plug-in directory together with all its dependencies. + *
    • the policy needs to define a field + * public static final long POLICY_ID, which will be used as the ID + * for a later retrieval + *
    + * + *

    + * The class loader distinguishes between built-in and plug-in + * policies. Built-in policies are pre-defined and always available. Plug-in + * policies are compiled, if necessary, and dynamically loaded from the given + * policy directory. + * + * @author stender + * + */ +public class PolicyClassLoader extends ClassLoader { + + private final Map cache; + + private final Map> policyMap; + + private final Class[] policyInterfaces; + + private final Class[] builtInPolicies; + + private File policyDir; + + private File[] jarFiles; + + /** + * Instantiates a new policy class loader. + * + * @param policyDirPath + * the path for the directory with all compiled and uncompiled + * policies + * @param policyInterfaceNames + * the names of all policy interfaces + * @param builtInPolicyNames + * the names of all built-in policies + * @throws IOException + * if an error occurs while initializing the policy interfaces + * or built-in policies + */ + public PolicyClassLoader(String policyDirPath, String[] policyInterfaceNames, String[] builtInPolicyNames) + throws IOException { + + this.cache = new HashMap(); + this.policyMap = new HashMap>(); + + try { + + // load policy interfaces + policyInterfaces = new Class[policyInterfaceNames.length]; + for (int i = 0; i < policyInterfaceNames.length; i++) + policyInterfaces[i] = Class.forName(policyInterfaceNames[i]); + + // load built-in policies + builtInPolicies = new Class[builtInPolicyNames.length]; + for (int i = 0; i < builtInPolicyNames.length; i++) + builtInPolicies[i] = Class.forName(builtInPolicyNames[i]); + + } catch (ClassNotFoundException exc) { + throw new IOException("could not initialize policy class loader:", exc); + } + + // initialize the policy dir file if defined + if (policyDirPath != null) + policyDir = new File(policyDirPath); + } + + /** + * Initializes the class loader. This first causes all source code in the + * policy directory to be compiled. In a second step, each class in the + * directory is loaded and checked for assignability to one of the given + * policy interfaces. If the check is successful, the class is added to a + * map, from which it can be efficiently retrieved by means of a policy ID. + * + * @throws IOException + * if an I/O error occurs while compiling or loading any of the + * classes + */ + public void init() throws IOException { + + // initialize plug-in policies + if (policyDir != null && policyDir.exists()) { + + // get all JAR files + jarFiles = policyDir.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.getAbsolutePath().endsWith(".jar"); + } + }); + + // get all Java files recursively + File[] javaFiles = FSUtils.listRecursively(policyDir, new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.getAbsolutePath().endsWith(".java"); + } + }); + + // compile all Java files + if (javaFiles.length != 0) { + + String cp = System.getProperty("java.class.path") + ":"; + for (int i = 0; i < jarFiles.length; i++) { + cp += jarFiles[i]; + if (i != jarFiles.length - 1) + cp += ":"; + } + + List options = new ArrayList(1); + options.add("-cp"); + options.add(cp); + + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + if (compiler == null) { + Logging.logMessage( + Logging.LEVEL_WARN, + Category.misc, + this, + "No Java compiler was found to compile additional policies. Make sure that a Java development environment is installed on your system."); + } else { + StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); + + Iterable compilationUnits = fileManager + .getJavaFileObjectsFromFiles(Arrays.asList(javaFiles)); + if (!compiler.getTask(null, fileManager, null, options, null, compilationUnits).call()) + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "some policies in '%s' could not be compiled", policyDir.getAbsolutePath()); + + fileManager.close(); + } + } + + // retrieve all policies from class files + File[] classFiles = FSUtils.listRecursively(policyDir, new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.getAbsolutePath().endsWith(".class"); + } + }); + + for (File cls : classFiles) { + try { + + String className = cls.getAbsolutePath().substring( + policyDir.getAbsolutePath().length() + 1, + cls.getAbsolutePath().length() - ".class".length()).replace('/', '.'); + if (cache.containsKey(className)) + continue; + + // load the class + Class clazz = loadFromStream(new FileInputStream(cls)); + + // check whether the class refers to a policy; if so, + // cache it + checkClass(clazz); + + } catch (LinkageError err) { + // ignore linkage errors + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "an error occurred while trying to load class from file " + cls); + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, OutputUtils + .stackTraceToString(exc)); + } + } + + // retrieve all policies from JAR files + // for (File jar : jarFiles) { + // + // JarFile arch = new JarFile(jar); + // + // Enumeration entries = arch.entries(); + // while (entries.hasMoreElements()) { + // JarEntry entry = entries.nextElement(); + // if (entry.getName().endsWith(".class")) { + // + // try { + // + // // load the class + // Class clazz = loadFromStream(arch.getInputStream(entry)); + // + // // check whether the class refers to a policy; if + // // so, cache it + // checkClass(clazz); + // + // } catch (IOException exc) { + // Logging.logMessage(Logging.LEVEL_WARN, this, "could not load + // class '" + // + entry.getName() + "' from JAR '" + jar.getAbsolutePath() + + // "'"); + // Logging.logMessage(Logging.LEVEL_WARN, this, exc); + // } catch (LinkageError err) { + // // ignore + // } + // } + // } + // } + + } + + // initialize all built-in policies + for (Class polClass : builtInPolicies) + checkClass(polClass); + } + + @Override + public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + + // first, check whether the class is cached + if (cache.containsKey(name)) + return cache.get(name); + + // if not cached, try to resolve the class by means of the system + // class loader + try { + return findSystemClass(name); + } catch (ClassNotFoundException exc) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "could not find system class '%s', trying to define the class", name); + } + + if (policyDir == null || !policyDir.exists()) + throw new ClassNotFoundException("no built-in policy '" + name + + "' available, and no plug-in policy directory specified"); + + // if it could not be loaded w/ the system class loader, try to load it + // from a file and + // define it + try { + + File classFile = new File(policyDir.getAbsolutePath() + "/" + name.replace('.', '/') + ".class"); + + Class clazz = loadFromStream(new FileInputStream(classFile)); + + if (resolve) + resolveClass(clazz); + + return clazz; + + } catch (IOException exc) { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "could not define class '%s', trying to load the class from a plug-in JAR file", name); + + } catch (LinkageError err) { + + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, "could not define class '%s'", name); + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, OutputUtils.stackTraceToString(err)); + + } + + // if the class could not be loaded by the system class loader, try + // to load it from an external JAR file + URL[] urls = new URL[jarFiles.length]; + try { + for (int i = 0; i < jarFiles.length; i++) + urls[i] = jarFiles[i].toURI().toURL(); + } catch (MalformedURLException exc) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, OutputUtils.stackTraceToString(exc)); + } + + return new URLClassLoader(urls) { + + @Override + public URL getResource(String name) { + + URL resource = super.getResource(name); + if (resource != null) + return resource; + + return PolicyClassLoader.this.getResource(name); + } + + @Override + public InputStream getResourceAsStream(String name) { + + InputStream stream = super.getResourceAsStream(name); + if (stream != null) + return stream; + + return PolicyClassLoader.this.getResourceAsStream(name); + } + + }.loadClass(name); + } + + /** + * Returns a policy class for a given ID and interface. + * + * @param id + * the policy ID + * @param policyInterface + * the policy interface + * @return a class that has the given ID and is assignable from the given + * interface, or null, if no such class exists + */ + public Class loadClass(long id, Class policyInterface) { + + Map map = policyMap.get(policyInterface); + if (map == null) + return null; + + Class clazz = map.get(id); + + return clazz; + } + + @Override + public URL getResource(String name) { + + // first, try to get the resource from the parent class loader + URL resource = super.getResource(name); + if (resource != null) + return resource; + + // if no resource could be retrieved, look into the policy directory + File file = new File(policyDir.getAbsolutePath() + "/" + name); + if (file.exists()) + try { + return file.toURI().toURL(); + } catch (MalformedURLException e) { + return null; + } + + return null; + } + + @Override + public InputStream getResourceAsStream(String name) { + + // first, try to get the stream from the parent class loader + InputStream stream = super.getResourceAsStream(name); + if (stream != null) + return stream; + + // if no stream could be retrieved, look into the policy directory + File file = new File(policyDir.getAbsolutePath() + "/" + name); + try { + return new FileInputStream(file); + } catch (FileNotFoundException exc) { + return null; + } + + } + + private Class loadFromStream(InputStream in) throws IOException { + + // load the binary class content + byte[] classData = new byte[in.available()]; + in.read(classData); + in.close(); + + Class clazz = defineClass(null, classData, 0, classData.length); + cache.put(clazz.getName(), clazz); + + return clazz; + } + + private void checkClass(Class clazz) { + + // check whether the class matches any of the policy + // interfaces + for (Class ifc : policyInterfaces) { + + if (ifc.isAssignableFrom(clazz)) { + + // get the policy ID + try { + long policyId = clazz.getDeclaredField("POLICY_ID").getLong(null); + + // add the policy to the internal map + Map polIdMap = policyMap.get(ifc); + if (polIdMap == null) { + polIdMap = new HashMap(); + policyMap.put(ifc, polIdMap); + } + + if (polIdMap.containsKey(policyId)) + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "duplicate ID for policy '%s': %d", ifc.getName(), policyId); + + polIdMap.put(policyId, clazz); + + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_WARN, this, "could not load malformed policy '%s'", + clazz.getName()); + Logging.logMessage(Logging.LEVEL_WARN, this, OutputUtils.stackTraceToString(exc)); + } + } + } + } + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/common/config/PolicyContainer.java b/java/servers/src/org/xtreemfs/common/config/PolicyContainer.java new file mode 100644 index 0000000..65ec3bc --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/config/PolicyContainer.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.config; + +import java.io.IOException; + +import org.xtreemfs.foundation.SSLOptions.TrustManager; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +public class PolicyContainer { + + protected final ServiceConfig config; + + protected final PolicyClassLoader policyClassLoader; + + public PolicyContainer(ServiceConfig config) throws IOException { + + this.config = config; + this.policyClassLoader = new PolicyClassLoader(config.getPolicyDir(), new String[0], new String[0]); + + policyClassLoader.init(); + } + + protected PolicyContainer(ServiceConfig config, PolicyClassLoader policyClassLoader) throws IOException { + + this.config = config; + this.policyClassLoader = policyClassLoader; + + policyClassLoader.init(); + } + + public TrustManager getTrustManager() throws ClassNotFoundException, InstantiationException, + IllegalAccessException { + + String trustManager = config.getTrustManager(); + if (trustManager == null || trustManager.equals("")) + return null; + + // first, check whether a built-in policy exists with the given name + try { + return (TrustManager) Class.forName(trustManager).newInstance(); + } catch (Exception exc) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "no built-in policy '%s' exists, searching for plug-in policies...", config + .getTrustManager()); + } + + // if no built-in policy could be found, check for plug-in policy + // directory + + // if the class file could be found, load it + Class cls = policyClassLoader.loadClass(trustManager); + + return (TrustManager) cls.newInstance(); + + } + +} diff --git a/java/servers/src/org/xtreemfs/common/config/RemoteConfigHelper.java b/java/servers/src/org/xtreemfs/common/config/RemoteConfigHelper.java new file mode 100644 index 0000000..5ba63dc --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/config/RemoteConfigHelper.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2010-2011 by Paul Seiferth, Zuse Institute Berlin + * 2012 by Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.config; + +import java.io.FileInputStream; +import java.util.HashMap; + +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; + +public class RemoteConfigHelper { + public static ServiceConfig getConfigurationFromDIR(ServiceConfig config) throws Exception { + TimeSync ts = null; + boolean timeSyncAlreadyRunning = true; + + try { + final int WAIT_BETWEEN_RETRIES = 1000; + int retries = config.getWaitForDIR() * 1000 / WAIT_BETWEEN_RETRIES; + if (retries <= 0) { + retries = 1; + } + Logging.logMessage(Logging.LEVEL_INFO, null, "Loading configuration from DIR (will retry up to %d times)", retries); + + SSLOptions sslOptions; + sslOptions = config.isUsingSSL() ? new SSLOptions(new FileInputStream( + config.getServiceCredsFile()), config.getServiceCredsPassphrase(), + config.getServiceCredsContainer(), new FileInputStream(config.getTrustedCertsFile()), + config.getTrustedCertsPassphrase(), config.getTrustedCertsContainer(), false, + config.isGRIDSSLmode(), config.getSSLProtocolString(), + new PolicyContainer(config).getTrustManager()) : null; + + RPCNIOSocketClient clientStage = new RPCNIOSocketClient(sslOptions, 1000, 60 * 1000, "RemoteConfigHelper"); + DIRServiceClient dirRPCClient = new DIRServiceClient(clientStage, config.getDirectoryService()); + DIRClient dirClient = new DIRClient(dirRPCClient, config.getDirectoryServices(), retries, + WAIT_BETWEEN_RETRIES); + + clientStage.start(); + clientStage.waitForStartup(); + + timeSyncAlreadyRunning = TimeSync.isInitialized(); + if (!timeSyncAlreadyRunning) { + ts = TimeSync.initializeLocal(0); + ts.waitForStartup(); + } + + Auth authNone = Auth.newBuilder().setAuthType(AuthType.AUTH_NONE).build(); + UserCredentials uc = UserCredentials.newBuilder().setUsername("main-method") + .addGroups("xtreemfs-services").build(); + + Configuration conf = dirClient.xtreemfs_configuration_get(null, authNone, uc, config.getUUID() + .toString()); + + clientStage.shutdown(); + clientStage.waitForShutdown(); + + HashMap returnMap = new HashMap(); + + for (KeyValuePair kvp : conf.getParameterList()) { + returnMap.put(kvp.getKey(), kvp.getValue()); + } + + return new ServiceConfig(returnMap); + } finally { + if (!timeSyncAlreadyRunning && ts != null) { + ts.close(); + } + } + }; +} diff --git a/java/servers/src/org/xtreemfs/common/config/ServiceConfig.java b/java/servers/src/org/xtreemfs/common/config/ServiceConfig.java new file mode 100644 index 0000000..6140eac --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/config/ServiceConfig.java @@ -0,0 +1,786 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, Bjoern Kolbeck, + * Jan Stender, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.config; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.Schemes; + +public class ServiceConfig extends Config { + + final private static Category[] debugCategoryDefault = { Category.all }; + + public static enum Parameter { + /* + * general configuration parameter + */ + DEBUG_LEVEL("debug.level", 6, Integer.class, false), + DEBUG_CATEGORIES("debug.categories", debugCategoryDefault, Category[].class, false), + DIRECTORY_SERVICE("dir_service.host", null, InetSocketAddress.class, true), + DIRECTORY_SERVICE0("dir_service.0.host", null, InetSocketAddress.class, false), + DIRECTORY_SERVICE1("dir_service.1.host", null, InetSocketAddress.class, false), + DIRECTORY_SERVICE2("dir_service.2.host", null, InetSocketAddress.class, false), + DIRECTORY_SERVICE3("dir_service.3.host", null, InetSocketAddress.class, false), + DIRECTORY_SERVICE4("dir_service.4.host", null, InetSocketAddress.class, false), + PORT("listen.port", null, Integer.class, true), + HTTP_PORT("http_port", null, Integer.class, true), + LISTEN_ADDRESS("listen.address", null, InetAddress.class, false), + USE_SSL("ssl.enabled", false, Boolean.class, false), + SSL_PROTOCOL_STRING("ssl.protocol", null, String.class, false), + SERVICE_CREDS_FILE("ssl.service_creds", null, String.class, false ), + SERVICE_CREDS_PASSPHRASE("ssl.service_creds.pw", null, String.class, false), + SERVICE_CREDS_CONTAINER("ssl.service_creds.container", null, String.class, false), + TRUSTED_CERTS_FILE("ssl.trusted_certs", null, String.class, false), + TRUSTED_CERTS_CONTAINER("ssl.trusted_certs.container", null, String.class, false), + TRUSTED_CERTS_PASSPHRASE("ssl.trusted_certs.pw", null, String.class, false), + TRUST_MANAGER("ssl.trust_manager", "", String.class, false), + GEO_COORDINATES("geographic_coordinates", "", String.class, false ), + ADMIN_PASSWORD("admin_password", "", String.class, false), + HOSTNAME("hostname", "", String.class, false ), + USE_GRID_SSL_MODE("ssl.grid_ssl", false, Boolean.class, false), + WAIT_FOR_DIR("startup.wait_for_dir", 30, Integer.class, false), + POLICY_DIR("policy_dir", "/etc/xos/xtreemfs/policies/", String.class, false), + USE_SNMP("snmp.enabled", false, Boolean.class, false), + SNMP_ADDRESS("snmp.address", null, InetAddress.class, false), + SNMP_PORT("snmp.port", null, Integer.class, false), + SNMP_ACL("snmp.aclfile", null, String.class, false), + FAILOVER_MAX_RETRIES("failover.retries", 15, Integer.class, false), + FAILOVER_WAIT("failover.wait_ms", 15 * 1000, Integer.class, false), + MAX_CLIENT_Q("max_client_queue", 100, Integer.class, false), + MAX_REQUEST_QUEUE_LENGTH("max_requests_queue_length", 1000, Integer.class, false), + USE_MULTIHOMING("multihoming.enabled", false, Boolean.class, false), + USE_RENEWAL_SIGNAL("multihoming.renewal_signal", false, Boolean.class, false ), + + /* + * DIR specific configuration parameter + */ + AUTODISCOVER_ENABLED("discover", true, Boolean.class, false), + MONITORING_ENABLED("monitoring.enabled", false, Boolean.class, false ), + ADMIN_EMAIL("monitoring.email.receiver", "", String.class, false), + SENDER_ADDRESS("monitoring.email.sender", "XtreemFS DIR monitoring ", String.class, false), + MAX_WARNINGS("monitoring.max_warnings", 1, Integer.class, false), + SENDMAIL_BIN("monitoring.email.programm", "/usr/sbin/sendmail", String.class, false), + TIMEOUT_SECONDS("monitoring.service_timeout_s", 5 * 60, Integer.class, false), + VIVALDI_MAX_CLIENTS("vivaldi.max_clients", 32, Integer.class, false), + VIVALDI_CLIENT_TIMEOUT("vivaldi.client_timeout", 600000, Integer.class, false), // default: twice the recalculation interval + + + /* + * MRC specific configuration parameter + */ + UUID("uuid", null, ServiceUUID.class, true), + LOCAL_CLOCK_RENEW("local_clock_renewal", null, Integer.class, true), + REMOTE_TIME_SYNC("remote_time_sync", null, Integer.class, true), + OSD_CHECK_INTERVAL("osd_check_interval", null, Integer.class, true), + NOATIME("no_atime", null, Boolean.class, true), + AUTHENTICATION_PROVIDER("authentication_provider", null, String.class, true), + CAPABILITY_SECRET("capability_secret", null, String.class, true), + CAPABILITY_TIMEOUT("capability_timeout", 600, Integer.class, false), + RENEW_TIMED_OUT_CAPS("renew_to_caps", false, Boolean.class, false), + + /* + * OSD specific configuration parameter + */ + OBJECT_DIR("object_dir", null, String.class, true), + REPORT_FREE_SPACE("report_free_space", null, Boolean.class, true), + CHECKSUM_ENABLED("checksums.enabled", false, Boolean.class, false), + CHECKSUM_PROVIDER("checksums.algorithm", null, String.class, false), + STORAGE_LAYOUT("storage_layout", "HashStorageLayout", String.class, false), + IGNORE_CAPABILITIES("ignore_capabilities", false, Boolean.class, false), + /** Maximum assumed drift between two server clocks. If the drift is higher, the system may not function properly. */ + FLEASE_DMAX_MS("flease.dmax_ms", 1000, Integer.class, false), + FLEASE_LEASE_TIMEOUT_MS("flease.lease_timeout_ms", 14000, Integer.class, false), + /** Message timeout. Maximum allowed in-transit time for a Flease message. */ + FLEASE_MESSAGE_TO_MS("flease.message_to_ms", 500, Integer.class, false), + FLEASE_RETRIES("flease.retries", 3, Integer.class, false), + SOCKET_SEND_BUFFER_SIZE("socket.send_buffer_size", -1, Integer.class, false), + SOCKET_RECEIVE_BUFFER_SIZE("socket.recv_buffer_size", -1, Integer.class, false), + VIVALDI_RECALCULATION_INTERVAL_IN_MS("vivaldi.recalculation_interval_ms", 300000, Integer.class, false), + VIVALDI_RECALCULATION_EPSILON_IN_MS("vivaldi.recalculation_epsilon_ms", 30000, Integer.class, false), + VIVALDI_ITERATIONS_BEFORE_UPDATING("vivaldi.iterations_before_updating", 12, Integer.class, false), + VIVALDI_MAX_RETRIES_FOR_A_REQUEST("vivaldi.max_retries_for_a_request", 2, Integer.class, false), + VIVALDI_MAX_REQUEST_TIMEOUT_IN_MS("vivaldi.max_request_timeout_ms", 10000, Integer.class, false), + VIVALDI_TIMER_INTERVAL_IN_MS("vivaldi.timer_interval_ms", 60000, Integer.class, false), + STORAGE_THREADS("storage_threads", 1, Integer.class, false), + HEALTH_CHECK("health_check", "", String.class, false), + + /* + * Benchmark specific configuration parameter + */ + BASEFILE_SIZE_IN_BYTES("basefilesize_in_bytes", 3221225472L, Long.class, false), // 3221225472L = 3 GiB + FILESIZE("filesize", 4096, Integer.class, false), // 4096 = 4 KiB + USERNAME("username", "benchmark", String.class, false), + GROUP("group", "benchmark", String.class, false), + OSD_SELECTION_POLICIES("osd_selection_policies", "", String.class, false), + REPLICATION_POLICY("replication_policy", "", String.class, false), + REPLICATION_FACTOR("replication_factor", 3, Integer.class, false), + CHUNK_SIZE_IN_BYTES("chunk_size_in_bytes", 131072, Integer.class, false), // 131072 = 128 KiB + STRIPE_SIZE_IN_BYTES("stripe_size_in_bytes", 131072, Integer.class, false), // 131072 = 128 KiB + STRIPE_SIZE_SET("stripe_size_set", false, Boolean.class, false), + STRIPE_WIDTH("stripe_width", 1, Integer.class, false), + STRIPE_WIDTH_SET("stripe_width_set", false, Boolean.class, false), + NO_CLEANUP("no_cleanup", false, Boolean.class, false), + NO_CLEANUP_VOLUMES("no_cleanup_volumes", false, Boolean.class, false), + NO_CLEANUP_BASEFILE("no_cleanup_basefile", false, Boolean.class, false), + OSD_CLEANUP("osd_cleanup", false, Boolean.class, false); + + + Parameter(String propString, Object defaultValue, Class propClass, Boolean req) { + propertyString = propString; + this.defaultValue = defaultValue; + propertyClass = propClass; + required = req; + } + + /** + * number of values the enumeration contains + */ + private static final int size = Parameter.values().length; + + /** + * String representation of the parameter in .property file + */ + private final String propertyString; + + /** + * Class of the parameter. Used for deserilization. Note: If you add a new Class type, don't forget to + * update the ServiceConfig(HashMap ) constructor + */ + private final Class propertyClass; + + /** + * Default parameter which will be used if there is neither a Parameter in the properties file nor in + * the DIR + */ + private final Object defaultValue; + + /** + * True if this is a required parameter. False otherwise. + */ + private final Boolean required; + + public String getPropertyString() { + return propertyString; + } + + public Object getDefaultValue() { + return defaultValue; + } + + public Class getPropertyClass() { + return propertyClass; + } + + public static int getSize() { + return size; + } + + public Boolean isRequired() { + return required; + } + + public Boolean isOptional() { + return !required; + } + + public static Parameter getParameterFromString(String s) throws RuntimeException { + for (Parameter parm : Parameter.values()) { + if (s.equals(parm.getPropertyString())) + return parm; + } + throw new RuntimeException("Configuration parameter " + s + " doesn't exist!"); + } + + } + /** + * Parameter which are required to connect to the DIR. + * + */ + private final Parameter[] connectionParameter = { + Parameter.DEBUG_CATEGORIES, + Parameter.DEBUG_LEVEL, + Parameter.HOSTNAME, + Parameter.DIRECTORY_SERVICE, + Parameter.WAIT_FOR_DIR, + Parameter.PORT, + Parameter.USE_SSL, + Parameter.UUID + }; + + /** + * Checks if there are all required configuration parameter to initialize a connection to the DIR and + * request the rest of the configuration + * + * @return {@link Boolean} + */ + public Boolean isInitializable() { + for (Parameter param : connectionParameter) { + if (parameter.get(param) == null) { + throw new RuntimeException("property '" + param.getPropertyString() + + "' is required but was not found"); + } + } + checkSSLConfiguration(); + return true; + } + + public Parameter[] getConnectionParameter() { + return this.connectionParameter; + } + + /** + * reads only the given Parameters from the config file + * + * @throws IOException + */ + public void readParameters(Parameter[] params) throws IOException { + for (Parameter param : params) { + parameter.put(param, readParameter(param)); + } + setDefaults(params); + } + + protected EnumMap parameter = new EnumMap( + Parameter.class); + + public static final String OSD_CUSTOM_PROPERTY_PREFIX = "config."; + + public ServiceConfig() { + super(); + } + + public ServiceConfig(Properties prop) { + super(prop); + } + + public ServiceConfig(String filename) throws IOException { + super(filename); + } + + public ServiceConfig(HashMap hm) { + super(); + + /* + * Create a configuration from String Key-Values of a HashMap + */ + for (Entry entry : hm.entrySet()) { + + // ignore custom configuration properties for OSDs here + if (entry.getKey().startsWith(OSD_CUSTOM_PROPERTY_PREFIX)) { + continue; + } + + Parameter param = null; + try { + param = Parameter.getParameterFromString(entry.getKey()); + } catch (RuntimeException e) { + e.printStackTrace(); + } + + /* Integer values */ + if (Integer.class == param.getPropertyClass()) { + parameter.put(param, Integer.parseInt(entry.getValue())); + } + + /* Long values */ + if (Long.class == param.getPropertyClass()) { + parameter.put(param, Long.parseLong(entry.getValue())); + } + + /* String values */ + if (String.class == param.getPropertyClass()) { + parameter.put(param, entry.getValue()); + } + + /* Boolean values */ + if (Boolean.class == param.getPropertyClass()) { + parameter.put(param, Boolean.valueOf(entry.getValue())); + } + + /* ServiceUUID values */ + if (ServiceUUID.class == param.getPropertyClass()) { + parameter.put(param, new ServiceUUID(entry.getValue())); + } + + /* InetAddress values */ + if (InetAddress.class == param.getPropertyClass()) { + + InetAddress inetAddr = null; + + try { + + inetAddr = InetAddress.getByName(entry.getValue().substring( + entry.getValue().indexOf('/') + 1)); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + parameter.put(param, inetAddr); + } + /* InetSocketAddress values */ + if (InetSocketAddress.class == param.getPropertyClass()) { + + /* + * Get a host and port of a string like 'hostname/192.168.2.141:36365' and create a + * InetSocketAddress + */ + String host = entry.getValue().substring(0, entry.getValue().indexOf("/")); + String port = entry.getValue().substring(entry.getValue().lastIndexOf(":") + 1); + InetSocketAddress isa = new InetSocketAddress(host, Integer.parseInt(port)); + + parameter.put(param, isa); + } + + /* Category[] values */ + if (Category[].class == param.getPropertyClass()) { + + StringTokenizer stk = new StringTokenizer(entry.getValue(), ", "); + + Category[] catArray = new Category[stk.countTokens()]; + int count = 0; + while (stk.hasMoreElements()) { + catArray[count] = Category.valueOf(stk.nextToken()); + count++; + } + + parameter.put(param, catArray); + } + } + } + + /** + * Merges a second configuration in this one. Only required parameters which aren't set will be used from + * the new configuration. + * + * @param conf + */ + public void mergeConfig(ServiceConfig conf) { + for (Entry entry : conf.parameter.entrySet()) { + if (entry.getKey().isRequired() && parameter.get(entry.getKey()) == null) { + parameter.put(entry.getKey(), entry.getValue()); + } + } + } + + /** + * Set the default value for a specific Parameter + * + * @param param + * - {@link Parameter} + */ + public void setDefaults(Parameter param) { + if (parameter.get(param) == null) { + parameter.put(param, param.getDefaultValue()); + } + } + + /** + * Set the default values for the parameter in p + * + * @param p + */ + public void setDefaults(Parameter[] p) { + for (Parameter parm : p) { + if (parm.isOptional() && parameter.get(parm) == null) { + parameter.put(parm, parm.getDefaultValue()); + } + } + } + + protected int readDebugLevel() { + String level = props.getProperty("debug.level"); + if (level == null) + return Logging.LEVEL_INFO; + else { + + level = level.trim().toUpperCase(); + + if (level.equals("EMERG")) { + return Logging.LEVEL_EMERG; + } else if (level.equals("ALERT")) { + return Logging.LEVEL_ALERT; + } else if (level.equals("CRIT")) { + return Logging.LEVEL_CRIT; + } else if (level.equals("ERR")) { + return Logging.LEVEL_ERROR; + } else if (level.equals("WARNING")) { + return Logging.LEVEL_WARN; + } else if (level.equals("NOTICE")) { + return Logging.LEVEL_NOTICE; + } else if (level.equals("INFO")) { + return Logging.LEVEL_INFO; + } else if (level.equals("DEBUG")) { + return Logging.LEVEL_DEBUG; + } else { + + try { + int levelInt = Integer.valueOf(level); + return levelInt; + } catch (NumberFormatException ex) { + throw new RuntimeException("'" + level + "' is not a valid level name nor an integer"); + } + + } + + } + + } + + /** + * Read configuration parameter from property file and return an Object of the value if the parameter was + * set. Else return null. + * + * @param param the parameter + * + * @return Object + */ + protected Object readParameter(Parameter param) { + + String tmpString = props.getProperty(param.getPropertyString()); + if (tmpString == null) { + return null; + } + + // Integer values + if (Integer.class == param.getPropertyClass()) { + return Integer.parseInt(tmpString.trim()); + } + + + /* Long values */ + if (Long.class == param.getPropertyClass()) { + return(Long.parseLong(tmpString.trim())); + } + + + // Boolean values + if (Boolean.class == param.getPropertyClass()) { + return Boolean.parseBoolean(tmpString.trim()); + } + + // String values + if (String.class == param.getPropertyClass()) { + return tmpString.trim(); + } + + // ServiceUUID values + if (ServiceUUID.class == param.getPropertyClass()) { + return new ServiceUUID(tmpString); + } + + // InetAddress values + if (InetAddress.class == param.getPropertyClass()) { + InetAddress iAddr = null; + try { + iAddr = InetAddress.getByName(tmpString); + } catch (Exception e) { + e.printStackTrace(); + } + return iAddr; + } + + // InetSocketAddress values + if (InetSocketAddress.class == param.getPropertyClass()) { + // assumes that the parameter in the property file like + // "foobar.host" and "foobar.port" if you + // want to read a InetSocketAddress + return readRequiredInetAddr(param.getPropertyString(), + param.getPropertyString().replaceAll("host", "port")); + } + + // Category[] values + if (Category[].class == param.getPropertyClass()) { + return readCategories(param.getPropertyString()); + } + + return null; + } + + protected Category[] readCategories(String property) { + + String tmp = this.readOptionalString(property, ""); + StringTokenizer st = new StringTokenizer(tmp, " \t,"); + + List cats = new LinkedList(); + while (st.hasMoreTokens()) { + String token = st.nextToken(); + try { + cats.add(Category.valueOf(token)); + } catch (IllegalArgumentException exc) { + System.err.println("invalid logging category: " + token); + } + } + + if (cats.size() == 0) + cats.add(Category.all); + + return cats.toArray(new Category[cats.size()]); + } + + public HashMap toHashMap() { + + HashMap hm = new HashMap(); + + for (Parameter param : Parameter.values()) { + if (parameter.get(param) != null) { + + if (Category[].class == param.getPropertyClass()) { + Category[] debugCategories = (Category[]) parameter.get(param); + String putString = ""; + + boolean firstValue = true; + for (Category cat : debugCategories) { + if (firstValue) { + putString = putString + cat.toString(); + firstValue = false; + } else { + putString += ", " + cat.toString(); + } + } + + hm.put(param.getPropertyString(), putString); + } else { + hm.put(param.getPropertyString(), parameter.get(param).toString()); + + } + } + } + return hm; + + } + + public int getDebugLevel() { + return (Integer) parameter.get(Parameter.DEBUG_LEVEL); + } + + public Category[] getDebugCategories() { + return (Category[]) parameter.get(Parameter.DEBUG_CATEGORIES); + } + + public int getPort() { + return (Integer) parameter.get(Parameter.PORT); + } + + public int getHttpPort() { + return (Integer) parameter.get(Parameter.HTTP_PORT); + } + + public InetAddress getAddress() { + return (InetAddress) parameter.get(Parameter.LISTEN_ADDRESS); + } + + public boolean isUsingSSL() { + return (Boolean) parameter.get(Parameter.USE_SSL); + } + + public String getServiceCredsContainer() { + return (String) parameter.get(Parameter.SERVICE_CREDS_CONTAINER); + } + + public String getServiceCredsFile() { + return (String) parameter.get(Parameter.SERVICE_CREDS_FILE); + } + + public String getServiceCredsPassphrase() { + return (String) parameter.get(Parameter.SERVICE_CREDS_PASSPHRASE); + } + + public String getTrustedCertsContainer() { + return (String) parameter.get(Parameter.TRUSTED_CERTS_CONTAINER); + } + + public String getTrustedCertsFile() { + return (String) parameter.get(Parameter.TRUSTED_CERTS_FILE); + } + + public String getTrustedCertsPassphrase() { + return (String) parameter.get(Parameter.TRUSTED_CERTS_PASSPHRASE); + } + + public String getTrustManager() { + return (String) parameter.get(Parameter.TRUST_MANAGER); + } + + public String getGeoCoordinates() { + return (String) parameter.get(Parameter.GEO_COORDINATES); + } + + public void setGeoCoordinates(String geoCoordinates) { + parameter.put(Parameter.GEO_COORDINATES, geoCoordinates); + } + + public String getAdminPassword() { + return (String) parameter.get(Parameter.ADMIN_PASSWORD); + } + + public String getHostName() { + return (String) parameter.get(Parameter.HOSTNAME); + } + + public ServiceUUID getUUID() { + return (ServiceUUID) parameter.get(Parameter.UUID); + } + + /** + * @return the useFakeSSLmodeport + */ + public boolean isGRIDSSLmode() { + return parameter.get(Parameter.USE_GRID_SSL_MODE) != null + && (Boolean) parameter.get(Parameter.USE_GRID_SSL_MODE); + } + + public String getSSLProtocolString() { + return (String) parameter.get(Parameter.SSL_PROTOCOL_STRING); + } + + public int getWaitForDIR() { + return (Integer) parameter.get(Parameter.WAIT_FOR_DIR); + } + + public String getURLScheme() { + if (isUsingSSL()) { + if (isGRIDSSLmode()) { + return Schemes.SCHEME_PBRPCG; + } else { + return Schemes.SCHEME_PBRPCS; + } + } + return Schemes.SCHEME_PBRPC; + } + + public String getPolicyDir() { + return (String) parameter.get(Parameter.POLICY_DIR); + } + + public Boolean isUsingSnmp() { + return (Boolean) parameter.get(Parameter.USE_SNMP); + } + + public InetAddress getSnmpAddress() { + return (InetAddress) parameter.get(Parameter.SNMP_ADDRESS); + } + + public Integer getSnmpPort() { + return (Integer) parameter.get(Parameter.SNMP_PORT); + } + + public String getSnmpACLFile() { + return (String) parameter.get(Parameter.SNMP_ACL); + } + + public Integer getFailoverMaxRetries() { + return (Integer) parameter.get(Parameter.FAILOVER_MAX_RETRIES); + } + + public Integer getFailoverWait() { + return (Integer) parameter.get(Parameter.FAILOVER_WAIT); + } + + public InetSocketAddress getDirectoryService() { + return (InetSocketAddress) parameter.get(Parameter.DIRECTORY_SERVICE); + } + + public InetSocketAddress[] getDirectoryServices() { + List addresses = new ArrayList(); + addresses.add((InetSocketAddress) parameter.get(Parameter.DIRECTORY_SERVICE)); + if (parameter.get(Parameter.DIRECTORY_SERVICE0) != null) { + addresses.add((InetSocketAddress) parameter.get(Parameter.DIRECTORY_SERVICE0)); + } + if (parameter.get(Parameter.DIRECTORY_SERVICE1) != null) { + addresses.add((InetSocketAddress) parameter.get(Parameter.DIRECTORY_SERVICE1)); + } + if (parameter.get(Parameter.DIRECTORY_SERVICE2) != null) { + addresses.add((InetSocketAddress) parameter.get(Parameter.DIRECTORY_SERVICE2)); + } + if (parameter.get(Parameter.DIRECTORY_SERVICE3) != null) { + addresses.add((InetSocketAddress) parameter.get(Parameter.DIRECTORY_SERVICE3)); + } + if (parameter.get(Parameter.DIRECTORY_SERVICE4) != null) { + addresses.add((InetSocketAddress) parameter.get(Parameter.DIRECTORY_SERVICE4)); + } + return addresses.toArray(new InetSocketAddress[0]); + } + + public void setDirectoryService(InetSocketAddress addr) { + parameter.put(Parameter.DIRECTORY_SERVICE, addr); + } + + /** + * Checks if the SSL Configuration is valid. If not throws a {@link RuntimeException}. + * + * @throws RuntimeException + */ + public void checkSSLConfiguration() { + + Parameter[] sslRelatedParameter = { Parameter.SERVICE_CREDS_CONTAINER, Parameter.SERVICE_CREDS_FILE, + Parameter.SERVICE_CREDS_PASSPHRASE, Parameter.TRUSTED_CERTS_CONTAINER, + Parameter.TRUSTED_CERTS_FILE, Parameter.TRUSTED_CERTS_PASSPHRASE }; + + if (isUsingSSL() == true) { + for (Parameter param : sslRelatedParameter) { + if (parameter.get(param) == null) { + throw new RuntimeException("for SSL " + param.getPropertyString() + " must be set!"); + } + } + } else { + if (parameter.get(Parameter.USE_GRID_SSL_MODE) != null) { + if (isGRIDSSLmode()) { + throw new RuntimeException( + "ssl must be enabled to use the grid_ssl mode. Please make sure to set ssl.enabled = true and to configure all SSL options."); + } + } + } + + } + + /** + * Checks if the multihoming configuration is valid. If not throws a {@link RuntimeException}. + * + * @throws RuntimeException + */ + protected void checkMultihomingConfiguration() { + if (isUsingMultihoming() && getAddress() != null) { + throw new RuntimeException(ServiceConfig.Parameter.USE_MULTIHOMING.getPropertyString() + " and " + + ServiceConfig.Parameter.LISTEN_ADDRESS.getPropertyString() + " parameters are incompatible."); + } + } + + protected void checkConfig(Parameter[] params) { + for (Parameter param : params) { + if (param.isRequired() && parameter.get(param) == null) { + throw new RuntimeException("property '" + param.getPropertyString() + + "' is required but was not found"); + + } + } + this.checkSSLConfiguration(); + } + + public boolean isUsingRenewalSignal() { + return (Boolean) parameter.get(Parameter.USE_RENEWAL_SIGNAL); + } + + public boolean isUsingMultihoming() { + return (Boolean) parameter.get(Parameter.USE_MULTIHOMING); + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/AdminClient.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/AdminClient.java new file mode 100644 index 0000000..4275943 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/AdminClient.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2012 by Lukas Kairies, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; +import java.util.List; +import java.util.Set; + +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.VolumeNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.XtreemFSException; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; + +public interface AdminClient extends Client { + + /** + * Open an admin volume and use the returned class to access it. + * + * @throws AddressToUUIDNotFoundException + * @throws VolumeNotFoundException + * @thorws IOException + * @throws {@link IOException} + */ + public AdminVolume openVolume(String volumeName, SSLOptions sslOptions, Options options) + throws AddressToUUIDNotFoundException, VolumeNotFoundException, IOException; + + /** + * Starts a cleanup on the OSD with the given UUID. + * + * @param osdUUID + * UUID of the OSD + * @param password + * admin password + * @param remove + * erase potential zombies + * @param deleteVolumes + * deletes volumes that might be dead + * @param restore + * restore zombies found on the OSD + * @param removeMetadata + * remove metadata from deleted or abandoned files + * @param metaDataTimeoutS + * time in seconds to wait after the last view update before deleting metadata + * @throws IOException + */ + public void startCleanUp(String osdUUID, String password, boolean remove, boolean deleteVolumes, boolean restore, + boolean removeMetadata, int metaDataTimeoutS) throws IOException; + + /** + * Run a version cleanup (only if file content versioning is enabled). + * + * @param osdUUID + * UUID of the OSD + * @param password + * admin password + * @throws IOException + */ + public void startVersionCleanUp(String osdUUID, String password) throws IOException; + + /** + * Suspends the currently running cleanup process. + * + * @param osdUUID + * UUID of the OSD + * @param password + * admin password + * @throws IOException + */ + public void stopCleanUp(String osdUUID, String password) throws IOException; + + /** + * Returns true if a cleanup is running. + * + * @param osdUUID + * UUID of the OSD + * @param password + * admin password + * @throws IOException + */ + public boolean isRunningCleanUp(String osdUUID, String password) throws IOException; + + /** + * Returns the current cleanup state. + * + * @param osdUUID + * UUID of the OSD + * @param password + * admin password + * @throws IOException + * + */ + public String getCleanUpState(String osdUUID, String password) throws IOException; + + /** + * Returns the cleanup Result. + * + * @param osdUUID + * UUID of the OSD + * @param password + * admin password + * @throws IOException + * + */ + public List getCleanUpResult(String osdUUID, String password) throws IOException; + + /** + * Returns a ServiceSet with all services of the given type. + * + * @param serviceType + * + * @return ServiceSet + * @throws XtreemFSException + * @throws IOException + */ + public ServiceSet getServiceByType(ServiceType serviceType) throws IOException; + + /** + * Returns the Service with the given UUID + * + * @param uuid + * UUID of the Service + * @throws IOException + */ + public Service getServiceByUUID(String uuid) throws IOException; + + /** + * Set the service status of the OSD with UUID "osdUUID" to "serviceStatus". + * + * @param osdUUID + * UUID of the OSD. + * @param serviceStatus + * service status which will be set. + * @throws IOException + */ + public void setOSDServiceStatus(String osdUUID, ServiceStatus serviceStatus) throws IOException; + + /** + * Returns the current status of the OSD with the UUID "osdUUID". + * + * @param osdUUID + * @return + * @throws IOException + */ + public ServiceStatus getOSDServiceStatus(String osdUUID) throws IOException; + + /** + * Returns a set of all removed OSDs. + * + * @throws IOException + */ + public Set getRemovedOsds() throws IOException; + +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/AdminFileHandle.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/AdminFileHandle.java new file mode 100644 index 0000000..a9d5198 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/AdminFileHandle.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011 by Lukas Kairies, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; +import java.util.List; + +import org.xtreemfs.common.clients.InvalidChecksumException; +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; + +public interface AdminFileHandle extends FileHandle { + + /** + * Returns a list with all replicas of the File. + * + */ + public List getReplicasList(); + + /** + * Returns the replica with index "replicaIndex". + * + * @param replicaIndex + * Index of the replica. + */ + public Replica getReplica(int replicaIndex); + + /** + * Returns the striping policy of the file. If the file is replicated, the striping policy of the first + * replica is returned. + */ + public StripingPolicy getStripingPolicy(); + + /** + * Returns the striping policy of the replica with index "replicaIndex". + * + * @param replicaIndex + */ + public StripingPolicy getStripingPolicy(int replicaIndex); + + /** + * Returns the replica update policy of the file as a String. Constants for replica update policies are + * defined in {@link org.xtreemfs.common.ReplicaUpdatePolicies}. + * + */ + public String getReplicaUpdatePolicy(); + + /** + * Returns the global ID of the file. + * + */ + public String getGlobalFileId(); + + /** + * Checks if a read-only replica with index "replicaIndex" is a complete replica and marks it as complete + * if not done yet. + * + * @param replicaIndex + * Index of the replica. + */ + public boolean checkAndMarkIfReadOnlyReplicaComplete(int replicaIndex, UserCredentials userCredentials) + throws IOException, AddressToUUIDNotFoundException; + + /** + * Returns the number of objects. + * + * @param userCredentials + * Name and Groups of the user. + * + * @throws IOException + */ + public long getNumObjects(UserCredentials userCredentials) throws IOException; + + /** + * Checks the object's checksum and returns the total number of bytes (data + sparse data) or throws an + * InvalidChecksumException. + * + * @param replicaIndex + * Replica from which the object will be checked. + * @param objectNo + * Object which will be checked. + * + * @throws InvalidChecksumException + * @throws IOException + */ + public int checkObjectAndGetSize(int replicaIndex, long objectNo) throws IOException, + InvalidChecksumException; + + /** + * Repairs the Object with number "objectNo" of the replica with index "replicaIndex". + * + * @param replicaIndex + * Index of the Replica in the xlocset from which the object will be repaired. + * @param objectNo + * Object which will be repaired. + */ + public void repairObject(int replicaIndex, long objectNo) throws IOException; + + /** + * + * Returns file size on the OSDs. + * + * @throws IOException + */ + public long getSizeOnOSD() throws IOException; + + /** + * Same as truncate(userCredentials, newFileSize) but with the option to truncate the file only at the + * MRC. + * + * @param userCredentials + * Name and Groups of the user. + * @param newFileSize + * New size of the file. + * @param truncateOnlyAtMRC + * true if the file should be truncated only at the MRC, otherwise false. + * + * @throws PosixErrorException + * @throws AddressToUUIDNotFoundException + * @throws IOException + */ + public void truncate(UserCredentials userCredentials, long newFileSize, boolean truncateOnlyAtMRC) + throws PosixErrorException, AddressToUUIDNotFoundException, IOException; + +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/AdminVolume.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/AdminVolume.java new file mode 100644 index 0000000..42dc6bf --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/AdminVolume.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2012 by Lukas Kairies, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; + +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; + +/** + * Extends the default Volume with additional functions. An admin volume object can be obtain by opening a + * volume with an admin client. + * + */ +public interface AdminVolume extends Volume { + + /** + * Opens a file and returns the pointer to a {@link FileHandle} object. + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file. + * @param flags + * Open flags as specified in xtreemfs::pbrpc::SYSTEM_V_FCNTL. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + * @throws AddressToUUIDNotFoundException + * + */ + public AdminFileHandle openFile(UserCredentials userCredentials, String path, int flags) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Same as previous openFile() except for the additional mode parameter, which sets the permissions for + * the file in case SYSTEM_V_FCNTL_H_O_CREAT is specified as flag and the file will be created. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + * @throws AddressToUUIDNotFoundException + */ + public AdminFileHandle openFile(UserCredentials userCredentials, String path, int flags, int mode) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Returns the object number for the file at "path". + * + * @param userCredentials + * Name and groups of the user. + * @param path + * Path to the file. + * + * @throws IOException + */ + public long getNumObjects(UserCredentials userCredentials, String path) throws IOException; + + /** + * Same as unlink(userCredentials, newFileSize) but with the option to unlink the file only at the MRC. + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file. + * @param unlinkOnlyAtMrc + * true if the file should be unlinked only at the MRC, otherwise false. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + * @throws AddressToUUIDNotFoundException + */ + public abstract void unlink(UserCredentials userCredentials, String path, boolean unlinkOnlyAtMrc) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/AsyncWriteBuffer.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/AsyncWriteBuffer.java new file mode 100644 index 0000000..44be0ab --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/AsyncWriteBuffer.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest; + +/** + * + * Stores all information needed for an asynchronous write. + */ +public class AsyncWriteBuffer { + + /** + * Creates a new {@link AsyncWriteBuffer} which is using the osdUuidIterator from + * {@link AsyncWriteHandler} + * + */ + protected AsyncWriteBuffer(writeRequest writeRequest, ReusableBuffer data, int dataLength, + FileHandleImplementation fileHandle) { + this.writeRequest = writeRequest; + this.data = data; + this.dataLength = dataLength; + this.fileHandle = fileHandle; + + this.osdUuid = null; + this.useUuidIterator = true; + } + + /** + * Creates a new {@link AsyncWriteBuffer} with a own osdUuid + */ + protected AsyncWriteBuffer(writeRequest writeRequest, ReusableBuffer data, int dataLength, + FileHandleImplementation fileHandle, String osdUuid) { + this.writeRequest = writeRequest; + this.data = data; + this.dataLength = dataLength; + this.fileHandle = fileHandle; + this.osdUuid = osdUuid; + + this.useUuidIterator = false; + } + + /** + * Additional information of the write request. + */ + private writeRequest writeRequest; + + /** + * Actual payload of the write request. + */ + private ReusableBuffer data; + + /** + * Length of the payload. + */ + private int dataLength; + + /** + * FileHandle which did receive the write() command. + */ + private FileHandleImplementation fileHandle; + + /** + * Set to false if the member "osdUuid" is used instead of the FileInfo's osdUuidIterator in order to + * determine the OSD to be used. + */ + private boolean useUuidIterator; + + /** + * UUID of the OSD which was used for the last retry or if useUuidIterator is false, this variable is + * initialized to the OSD to be used. + */ + private String osdUuid; + + protected writeRequest getWriteRequest() { + return writeRequest; + } + + protected ReusableBuffer getData() { + return data; + } + + protected int getDataLength() { + return dataLength; + } + + protected FileHandleImplementation getFileHandle() { + return fileHandle; + } + + protected boolean isUsingUuidIterator() { + return useUuidIterator; + } + + protected String getOsdUuid() { + return osdUuid; + } + + /** + * @param osdUuid + */ + protected void setOsdUuid(String osdUuid) { + this.osdUuid = osdUuid; + } +}; diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/AsyncWriteHandler.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/AsyncWriteHandler.java new file mode 100644 index 0000000..3244ea4 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/AsyncWriteHandler.java @@ -0,0 +1,349 @@ +package org.xtreemfs.common.libxtreemfs; + +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; + +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.UUIDIteratorListIsEmpyException; +import org.xtreemfs.common.libxtreemfs.exceptions.XtreemFSException; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.client.RPCResponseAvailableListener; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +import com.google.protobuf.Descriptors.EnumValueDescriptor; + +//JCIP import net.jcip.annotations.GuardedBy; + +/** + * Handles asynchronous writes. Used only internally. + */ +public class AsyncWriteHandler { + + /** + * Possible states of this object. + */ + private enum State { + IDLE, WRITES_PENDING + } + + /** + * State of this object. + */ +// JCIP @GuardedBy("this") + private State state; + + /** + * List of pending writes. + */ + // TODO(mberlin): Limit the size of writes in flight to avoid flooding. +// JCIP @GuardedBy("this") + private List writesInFlight; + + /** + * Number of pending bytes. + */ +// JCIP @GuardedBy("this") + private int pendingBytes; + + /** + * Set by WaitForPendingWrites() to true if there are temporarily no new async writes allowed and will be + * set to false again once the state IDLE is reached. + */ +// JCIP @GuardedBy("this") + private boolean writingPaused; + + /** + * Used to notify blocked WaitForPendingWrites() callers for the state change back to IDLE. + */ + private Object allPendingWritesDidComplete; + + /** + * Number of threads blocked by WaitForPendingWrites() waiting on allPendingWritesDidComplete for a state + * change back to IDLE. + */ +// JCIP @GuardedBy("this") + private int waitingBlockingThreadsCount; + + /** + * FileInfo object to which this AsyncWriteHandler does belong. Accessed for file size updates. + */ + private FileInfo fileInfo; + + /** + * Pointer to the UUIDIterator of the FileInfo object. + */ + private UUIDIterator uuidIterator; + + /** + * Required for resolving UUIDs to addresses. + */ + private UUIDResolver uuidResolver; + + /** + * Client which is used to send out the writes. + */ + OSDServiceClient osdServiceClient; + + /** + * Auth needed for ServiceClients. Always set to AUTH_NONE by Volume. + */ + private Auth authBogus; + + /** + * For same reason needed as authBogus. Always set to user "xtreemfs". + */ + private UserCredentials userCredentialsBogus; + + /** + * Maximum number in bytes which may be pending. + */ + private int maxWriteahead; + + /** + * Maximum number of pending write requests. + */ + private int maxWriteaheadRequests; + + /** + * Maximum number of attempts a write will be tried. + */ + private int maxWriteTries; + + protected AsyncWriteHandler(FileInfo fileInfo, UUIDIterator uuidIterator, UUIDResolver uuidResolver, + OSDServiceClient osdServiceClient, Auth authBogus, UserCredentials userCredentialsBogus, + int maxWriteahead, int maxWriteaheadRequests, int maxWriteTries) { + + this.fileInfo = fileInfo; + this.uuidIterator = uuidIterator; + this.uuidResolver = uuidResolver; + this.osdServiceClient = osdServiceClient; + this.authBogus = authBogus; + this.userCredentialsBogus = userCredentialsBogus; + this.maxWriteahead = maxWriteahead; + this.maxWriteaheadRequests = maxWriteaheadRequests; + this.maxWriteTries = maxWriteTries; + + writesInFlight = new ArrayList(); + allPendingWritesDidComplete = new Object(); + state = State.IDLE; + } + + /** + * Adds writeBuffer to the list of pending writes and sends it to the OSD specified by + * writeBuffer.uuidIterator (or write_buffer.osdUuid if writeBuffer.useUuidIterator is false). + * + * Blocks if the number of pending bytes exceeds the maximum write-ahead or waitForPendingWrites() was + * called beforehand. + */ + protected void write(AsyncWriteBuffer writeBuffer) throws AddressToUUIDNotFoundException, + XtreemFSException { + assert (writeBuffer != null); + + if (writeBuffer.getDataLength() > maxWriteahead) { + throw new XtreemFSException("The maximum allowed writeahead size: " + maxWriteahead + + " is smaller than the size of this write request: " + writeBuffer.getDataLength()); + } + + // append to the list of write in flight + synchronized (this) { + while (writingPaused || (pendingBytes + writeBuffer.getDataLength()) > maxWriteahead + || writesInFlight.size() == maxWriteaheadRequests) { + // TODO: Allow interruption and set the write status of the FileHandle of the + // interrupted write to an error state. + try { + this.wait(); + } catch (InterruptedException e) { + // TODO: handle exception + } + } + increasePendingBytesHelper(writeBuffer); + } + + String osdUuid = retrieveOSDUuidAndSetItInWriteBuffer(writeBuffer); + String osdAddress = uuidResolver.uuidToAddress(osdUuid); + InetSocketAddress osdInetSocketAddress = + Helper.stringToInetSocketAddress(osdAddress, + GlobalTypes.PORTS.OSD_PBRPC_PORT_DEFAULT.getNumber()); + + // Sending request + final AsyncWriteBuffer finalWriteBufferForCallback = writeBuffer; + RPCResponse response; + try { + response = + osdServiceClient.write(osdInetSocketAddress, authBogus, userCredentialsBogus, + writeBuffer.getWriteRequest(), writeBuffer.getData()); + + response.registerListener(new RPCResponseAvailableListener() { + @Override + public void responseAvailable(RPCResponse r) { + try { + OSDWriteResponse osdWriteResponse = r.get(); + writeFinished(osdWriteResponse, r.getData(), finalWriteBufferForCallback); + } catch (PBRPCException e) { + String errorTypeName = e.getErrorType().toString(); + EnumValueDescriptor enumDescriptor = + ErrorType.getDescriptor().findValueByNumber(e.getErrorType().getNumber()); + if (enumDescriptor != null) { + errorTypeName = enumDescriptor.getName(); + } + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, + "An async write sent to the server %s failed." + + " Error type: %s Error message: %s Complete error header: %s", + finalWriteBufferForCallback.getOsdUuid(), errorTypeName, e.getErrorMessage(), + e.getDebugInfo()); + System.out.println("CLASSNAME: " + this.toString()); + decreasePendingBytesHelper(finalWriteBufferForCallback); + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, "asyncWrite:" + + " failed due to the following reasons ", e.getMessage()); + decreasePendingBytesHelper(finalWriteBufferForCallback); + + } finally { + r.freeBuffers(); + } + } + }); + } catch (IOException e1) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, "asyncWrite:" + + " failed due to the following reasons ", e1.getMessage()); + decreasePendingBytesHelper(finalWriteBufferForCallback); + } + } + + private String retrieveOSDUuidAndSetItInWriteBuffer(AsyncWriteBuffer writeBuffer) + throws UUIDIteratorListIsEmpyException { + String osdUuid; + if (writeBuffer.isUsingUuidIterator()) { + osdUuid = uuidIterator.getUUID(); + // Store used OSD in writeBuffer for the callback. + writeBuffer.setOsdUuid(osdUuid); + } else { + osdUuid = writeBuffer.getOsdUuid(); + } + return osdUuid; + } + + /** + * Blocks until state changes back to IDLE and prevents allowing new writes. by blocking further write() + * calls. + */ + protected void waitForPendingWrites() { + synchronized (this) { + if (state != State.IDLE) { + writingPaused = false; + waitingBlockingThreadsCount++; + } else { + return; + } + } + + while (state != State.IDLE) { + synchronized (allPendingWritesDidComplete) { + try { + allPendingWritesDidComplete.wait(); + } catch (InterruptedException e) { + // TODO: REALLY handle exception. + e.printStackTrace(); + } + } + } + + synchronized (this) { + waitingBlockingThreadsCount--; + } + } + + /** + * Implements callback for an async write request. + */ + private void writeFinished(OSDWriteResponse response, ReusableBuffer data, AsyncWriteBuffer writeBuffer) { + // Tell FileInfo about the OSDWriteResponse. + if (response.hasSizeInBytes()) { + XCap xcap = writeBuffer.getFileHandle().getXcap(); + fileInfo.tryToUpdateOSDWriteResponse(response, xcap); + } + + decreasePendingBytesHelper(writeBuffer); + } + + /** + * Helper function which adds "writeBuffer" to the list "writesInFlight", increases the number of pending + * bytes and takes care of state changes. + */ + protected void increasePendingBytesHelper(AsyncWriteBuffer writeBuffer) { + assert (writeBuffer != null); + + pendingBytes += writeBuffer.getDataLength(); + writesInFlight.add(writeBuffer); + + assert (writesInFlight.size() <= maxWriteaheadRequests); + + state = State.WRITES_PENDING; + } + + /** + * Helper function which removes "writeBuffer" from the list "writesInFlight", deletes "writeBuffer", + * reduces the number of pending bytes and takes care of state changes. + * + * @remark Ownership of "writeBuffer" is transferred to the caller. + * @remark Requires a lock on "asyncWriteHandlerLock". + */ + private synchronized void decreasePendingBytesHelper(AsyncWriteBuffer writeBuffer) { + assert (writeBuffer != null); + + writesInFlight.remove(writeBuffer); + pendingBytes -= writeBuffer.getDataLength(); + + if (pendingBytes == 0) { + state = State.IDLE; + if (writingPaused) { + writingPaused = false; + } + // Issue notifyAll() as long as there are remaining blocked threads. + // + // Please note the following here: After the two notifyAll()s on the + // condition variables "allPendingWritesDidComplete and + // pendingBytesWereDecreased, two different thread types + // (waiting blocked ones AND further waiting writes) do race for + // re-acquiring the lock on mutex_. + // Example: + // T1: write1 "state" = PENDING + // T2: getattr "writingPaused" = true => blocked as "state" != IDLE + // T1: write2 => blocked as "writingPaused" = true + // Tx: write1 callback: "state" = IDLE, writing_paused_ = false + // T1: write2 succeeds to obtain lock on mutex_ *before* getattr + // => state = IDLE (writing_paused_ remains false) + // Tx: write2 callback: state = IDLE, writing paused remains false + // - however its necessary to notify the blocked getattr. + // As you can see the order of concurrent writes and reads/getattrs + // is undefined and we don't enforce any order as it's up to the user to + // synchronize his threads himself when working on the same file. + if (waitingBlockingThreadsCount > 0) { + synchronized (allPendingWritesDidComplete) { + allPendingWritesDidComplete.notifyAll(); + } + } + } + // Tell blocked writers there may be enough space/writing was unpaused now. + this.notifyAll(); + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/Client.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/Client.java new file mode 100644 index 0000000..4791438 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/Client.java @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.common.libxtreemfs.exceptions.VolumeNotFoundException; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes; + +/** + * Provides methods to open, close, create, delete and list volumes and to instantiate a new client object, to + * start and shutdown a Client object. + */ +public interface Client { + /** + * Need to be called before client can be used. Initializes required stuff. + */ + public void start() throws Exception; + + /** + * Same as start(), but add option to start Threads as daemons. Daemon threads are only used by the XtreemFSHadoopClient. + * + * @param startThreadsAsDaemons if true, all threads are as daemons. + */ + public void start(boolean startThreadsAsDaemons) throws Exception; + + public void shutdown(); + + /** + * Open a volume and use the returned class to access it. + * + * @remark Ownership is NOT transferred to the caller. Instead Volume->Close() has to be called to destroy + * the object. + * + * @throws AddressToUUIDNotFoundException + * @throws VolumeNotFoundException + * @throws {@link IOException} + */ + public Volume openVolume(String volumeName, SSLOptions sslOptions, Options options) + throws AddressToUUIDNotFoundException, VolumeNotFoundException, IOException; + + /** + * Creates a volume on the MRC at mrc_address using certain default values ( POSIX access policy type, + * striping size = 128k and width = 1 (i.e. no striping), mode = 777 and owner username and groupname + * retrieved from the user_credentials. + * + * @param mrcAddress + * String of the form "hostname:port". + * @param auth + * Authentication data, e.g. of type AUTH_PASSWORD. + * @param userCredentials + * Username and groups of the user who executes CreateVolume(). Not checked so far? + * @param volumeName + * Name of the new volume. + * + * @throws IOException + * @throws PosixErrorException + */ + public void createVolume(String mrcAddress, Auth auth, UserCredentials userCredentials, String volumeName) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Creates a volume on the MRC at mrc_address using certain default values ( POSIX access policy type, + * striping size = 128k and width = 1 (i.e. no striping), mode = 777 and owner username and groupname + * retrieved from the user_credentials. + * + * @param mrcAddresses + * List of Strings of the form "hostname:port". + * @param auth + * Authentication data, e.g. of type AUTH_PASSWORD. + * @param userCredentials + * Username and groups of the user who executes CreateVolume(). Not checked so far? + * @param volumeName + * Name of the new volume. + * + * @throws IOException + * @throws PosixErrorException + * @throws AddressToUUIDNotFoundException + */ + public void createVolume(List mrcAddresses, Auth auth, UserCredentials userCredentials, + String volumeName) throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Creates a volume on the first found MRC. + * + * @param auth + * Authentication data, e.g. of type AUTH_PASSWORD. + * @param userCredentials + * Username and groups of the user who executes CreateVolume(). + * @param volumeName + * Name of the new volume. + * @param mode + * Mode of the volume's root directory (in octal representation (e.g. 511), not decimal (777)). + * @param ownerUsername + * Name of the owner user. + * @param ownerGroupname + * Name of the owner group. + * @param accessPolicyType + * Access policy type (Null, Posix, Volume, ...). + * @param defaultStripingPolicyType + * Only RAID0 so far. + * @param defaultStripeSize + * Size of an object on the OSD (in kBytes). + * @param defaultStripeWidth + * Number of OSDs objects of a file are striped across. + * @param volumeAttributes + * Reference to a list of key-value pairs of volume attributes which will bet set at creation + * time of the volume. + * + * @throws AddressToUUIDNotFoundException + * @throws PosixErrorException + * @throws IOException + */ + public void createVolume(Auth auth, UserCredentials userCredentials, String volumeName, int mode, + String ownerUsername, String ownerGroupname, AccessControlPolicyType accessPolicyType, + StripingPolicyType defaultStripingPolicyType, int defaultStripeSize, int defaultStripeWidth, + List volumeAttributes) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException; + + /** + * Creates a volume on the MRC at mrc_address. + * + * @param mrcAddress + * String of the form "hostname:port". + * @param auth + * Authentication data, e.g. of type AUTH_PASSWORD. + * @param userCredentials + * Username and groups of the user who executes CreateVolume(). + * @param volumeName + * Name of the new volume. + * @param mode + * Mode of the volume's root directory (in octal representation (e.g. 511), not decimal (777)). + * @param ownerUsername + * Name of the owner user. + * @param ownerGroupname + * Name of the owner group. + * @param accessPolicyType + * Access policy type (Null, Posix, Volume, ...). + * @param defaultStripingPolicyType + * Only RAID0 so far. + * @param defaultStripeSize + * Size of an object on the OSD (in kBytes). + * @param defaultStripeWidth + * Number of OSDs objects of a file are striped across. + * @param volumeAttributes + * Reference to a list of key-value pairs of volume attributes which will bet set at creation + * time of the volume. + * + * @throws IOException + * @throws PosixErrorException + * @throws AddressToUUIDNotFoundException + */ + public void createVolume(String mrcAddress, Auth auth, UserCredentials userCredentials, + String volumeName, int mode, String ownerUsername, String ownerGroupname, + AccessControlPolicyType accessPolicyType, StripingPolicyType defaultStripingPolicyType, + int defaultStripeSize, int defaultStripeWidth, List volumeAttributes) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Creates a volume on the MRC at mrc_address. + * + * @param mrcAddresses + * List of Strings of the form "hostname:port". + * @param auth + * Authentication data, e.g. of type AUTH_PASSWORD. + * @param userCredentials + * Username and groups of the user who executes CreateVolume(). + * @param volumeName + * Name of the new volume. + * @param mode + * Mode of the volume's root directory (in octal representation (e.g. 511), not decimal (777)). + * @param ownerUsername + * Name of the owner user. + * @param ownerGroupname + * Name of the owner group. + * @param accessPolicyType + * Access policy type (Null, Posix, Volume, ...). + * @param defaultStripingPolicyType + * Only RAID0 so far. + * @param defaultStripeSize + * Size of an object on the OSD (in kBytes). + * @param defaultStripeWidth + * Number of OSDs objects of a file are striped across. + * @param volumeAttributes + * Reference to a list of key-value pairs of volume attributes which will bet set at creation + * time of the volume. + * + * @throws IOException + * @throws PosixErrorException + * @throws AddressToUUIDNotFoundException + */ + public void createVolume(List mrcAddresses, Auth auth, UserCredentials userCredentials, + String volumeName, int mode, String ownerUsername, String ownerGroupname, + AccessControlPolicyType accessPolicyType, StripingPolicyType defaultStripingPolicyType, + int defaultStripeSize, int defaultStripeWidth, List volumeAttributes) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Deletes the volume "volume_name" at the MRC "mrc_address". + * + * @param mrcAddress + * String of the form "hostname:port". + * @param auth + * Authentication data, e.g. of type AUTH_PASSWORD. + * @param userCredentials + * Username and groups of the user who executes CreateVolume(). + * @param volumeName + * Name of the volume to be deleted. + * + * @throws IOException + * @throws PosixErrorException + */ + public void deleteVolume(String mrcAddress, Auth auth, UserCredentials userCredentials, String volumeName) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Deletes the volume "volume_name" at the MRC "mrc_address". + * + * @param mrcAddresses + * List of Strings of the form "hostname:port". + * @param auth + * Authentication data, e.g. of type AUTH_PASSWORD. + * @param userCredentials + * Username and groups of the user who executes CreateVolume(). + * @param volumeName + * Name of the volume to be deleted. + * + * @throws IOException + * @throws PosixErrorException + * @throws AddressToUUIDNotFoundException + */ + public void deleteVolume(List mrcAddresses, Auth auth, UserCredentials userCredentials, + String volumeName) throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Retrieves the first MRC from the DIR and deletes the volume "volume_name" at this the MRC. + * + * @param auth + * Authentication data, e.g. of type AUTH_PASSWORD. + * @param userCredentials + * Username and groups of the user who executes CreateVolume(). + * @param volumeName + * Name of the volume to be deleted. + * + * @throws IOException + * @throws PosixErrorException + */ + public void deleteVolume(Auth auth, UserCredentials userCredentials, String volumeName) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Returns the available volumes on a MRC. + * + * @param mrcAddress + * String of the form "hostname:port". + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * + */ + public Volumes listVolumes(String mrcAddress) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException; + + /** + * Returns the available volumes on a MRC. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * + * @remark Ownership of the return value is transferred to the caller. + */ + public Volumes listVolumes() throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Returns the available volumes as list of names + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * + */ + public String[] listVolumeNames() throws IOException; + + /** + * Returns the available volumes on a MRC. + * + * @param mrcAddresses + * List which contains MRC addresses of the form "hostname:port". + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * + * @remark Ownership of the return value is transferred to the caller. + */ + public Volumes listVolumes(List mrcAddresses) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException; + + /** + * List all servers and return their host names + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public Map listServers() throws IOException, PosixErrorException; + + /** + * Returns the registered UUID of the OSDs and their attributes on the DIR. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public Map listOSDsAndAttributes() throws IOException, PosixErrorException; +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/ClientFactory.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/ClientFactory.java new file mode 100644 index 0000000..47205f4 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/ClientFactory.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2012 by Lukas Kairies, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.libxtreemfs; + +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; + +/** + * Returns different kinds of Client implementations. + * + */ +public class ClientFactory { + + /** + * Returns an instance of a default client with one DIR Address. + * + * @param dirServiceAddress + * Address of the DIR service (Format: ip-addr:port, e.g. localhost:32638) + * @param userCredentials + * Name and Groups of the user. + * @param sslOptions + * NULL if no SSL is used. + * @param options + * Has to contain loglevel string and logfile path. + */ + public static Client createClient(String dirServiceAddress, UserCredentials userCredentials, + SSLOptions sslOptions, Options options) { + String[] dirAddresses = new String[1]; + dirAddresses[0] = dirServiceAddress; + return new ClientImplementation(dirAddresses, userCredentials, sslOptions, options); + } + + /** + * Returns an instance of a default client with multiple DIR Addresses. + * + * @param dirServiceAddresses + * Addresses of the DIR services (Format: ip-addr:port, e.g. localhost:32638) + * @param userCredentials + * Name and Groups of the user. + * @param sslOptions + * NULL if no SSL is used. + * @param options + * Has to contain loglevel string and logfile path. + */ + public static Client createClient(String[] dirServiceAddresses, UserCredentials userCredentials, + SSLOptions sslOptions, Options options) { + return new ClientImplementation(dirServiceAddresses, userCredentials, sslOptions, options); + } + + /** + * Returns an instance of an admin client with one DIR address. + * + * @param dirServiceAddress + * Address of the DIR service (Format: ip-addr:port, e.g. localhost:32638) + * @param userCredentials + * Name and Groups of the user. + * @param sslOptions + * NULL if no SSL is used. + * @param options + * Has to contain loglevel string and logfile path. + */ + public static AdminClient createAdminClient(String dirServiceAddress, UserCredentials userCredentials, + SSLOptions sslOptions, Options options) { + String[] dirAddresses = new String[1]; + dirAddresses[0] = dirServiceAddress; + return new ClientImplementation(dirAddresses, userCredentials, sslOptions, options); + } + + /** + * Returns an instance of a admin client with multiple DIR Addresses. + * + * @param dirServiceAddresses + * Addresses of the DIR services (Format: ip-addr:port, e.g. localhost:32638) + * @param userCredentials + * Name and Groups of the user. + * @param sslOptions + * NULL if no SSL is used. + * @param options + * Has to contain loglevel string and logfile path. + * + */ + public static AdminClient createAdminClient(String[] dirServiceAddresses, + UserCredentials userCredentials, SSLOptions sslOptions, Options options) { + return new ClientImplementation(dirServiceAddresses, userCredentials, sslOptions, options); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/ClientImplementation.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/ClientImplementation.java new file mode 100644 index 0000000..0caa0d0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/ClientImplementation.java @@ -0,0 +1,1037 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.xtreemfs.common.HeartbeatThread; +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.common.libxtreemfs.RPCCaller.CallGenerator; +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.common.libxtreemfs.exceptions.VolumeNotFoundException; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SERVICES; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * Standard implementation of the client. Used only internally. + */ +public class ClientImplementation implements UUIDResolver, Client, AdminClient { + + /** + * Contains all addresses of the DIR Service. + */ + private UUIDIterator dirServiceAddresses = null; + + /** + * Auth of type AUTH_NONE which is required for most operations which do not check the authentication data + * (except Create, Delete, ListVolume(s)). + */ + private Auth authBogus = null; + + /** The auth_type of this object will always be set to AUTH_NONE. */ + // TODO: change this when the DIR service supports real auth. + private Auth dirServiceAuth; + + /** These credentials will be used for messages to the DIR service. */ + private UserCredentials dirServiceUserCredentials = null; + + private SSLOptions dirServiceSSLOptions = null; + + /** Options class which contains the log_level string and logfile path. */ + private Options options = null; + + private ConcurrentLinkedQueue listOpenVolumes = null; + + private org.xtreemfs.common.uuids.UUIDResolver uuidResolver = null; + + /** + * A DIRServiceClient is a wrapper for an RPC Client. + */ + private DIRServiceClient dirServiceClient = null; + + /** + * An OSDServiceClient is a wrapper for an RPC Client. + */ + private OSDServiceClient osdServiceClient = null; + + /** + * The RPC Client processes requests from a queue and executes callbacks in its thread. + */ + private RPCNIOSocketClient networkClient = null; + + /** + * Random, non-persistent UUID to distinguish locks of different clients. + */ + private String clientUUID = null; + + /** + * Array with all DIR addresses. + */ + private String[] dirAddresses = null; + + /** + * If true, all threads (inclusive volumes opened by this client) are daemons. + */ + private boolean startThreadsAsDaemons = false; + + protected ClientImplementation(String[] dirAddresses, UserCredentials userCredentials, + SSLOptions sslOptions, Options options) { + this.dirServiceUserCredentials = userCredentials; + this.dirServiceSSLOptions = sslOptions; + this.options = options; + + this.dirAddresses = dirAddresses; + + this.dirServiceAddresses = new UUIDIterator(); + + for (String address : dirAddresses) { + this.dirServiceAddresses.addUUID(address); + } + + // Set bogus auth object + this.authBogus = Auth.newBuilder().setAuthType(AuthType.AUTH_NONE).build(); + + // Currently no AUTH is required to access the DIR + this.dirServiceAuth = Auth.newBuilder().setAuthType(AuthType.AUTH_NONE).build(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Created a new libxtreemfs Client " + + "object (version %s)", options.getVersion()); + } + + this.listOpenVolumes = new ConcurrentLinkedQueue(); + } + @Override + public void start() throws Exception { + start(false); + } + @Override + public void start(boolean startThreadsAsDaemons) throws Exception { + + this.startThreadsAsDaemons = startThreadsAsDaemons; + this.networkClient = new RPCNIOSocketClient(this.dirServiceSSLOptions, + this.options.getRequestTimeout_s() * 1000, this.options.getLingerTimeout_s() * 1000, "Client", startThreadsAsDaemons); + this.networkClient.start(); + this.networkClient.waitForStartup(); + + TimeSync tsInstance = TimeSync.initializeLocal(50); + tsInstance.waitForStartup(); + + this.dirServiceClient = new DIRServiceClient(this.networkClient, null); + + osdServiceClient = new OSDServiceClient(networkClient, null); + + this.clientUUID = Helper.generateVersion4UUID(); + assert (this.clientUUID != null && this.clientUUID != ""); + + // Create nonSingleton uuidResolver to resolve UUIDs. + + InetSocketAddress[] isas = new InetSocketAddress[dirAddresses.length]; + + for (int i = 0; i < dirAddresses.length; i++) { + isas[i] = Helper.stringToInetSocketAddress(dirAddresses[i], + GlobalTypes.PORTS.DIR_PBRPC_PORT_DEFAULT.getNumber()); + } + + DIRClient dirClient = new DIRClient(this.dirServiceClient, isas, this.options.getMaxTries(), + this.options.getRetryDelay_s() * 1000); + + this.uuidResolver = org.xtreemfs.common.uuids.UUIDResolver.startNonSingelton(dirClient, 3600, 1000); + } + + @Override + public synchronized void shutdown() { + for (Volume volume : this.listOpenVolumes) { + volume.close(); + } + + if (this.dirServiceClient != null) { + try { + this.networkClient.shutdown(); + this.networkClient.waitForShutdown(); + } catch (Exception e) { + // TODO: handle exception + e.printStackTrace(); + } + } + } + + protected void closeVolume(Volume volume) { + boolean removed = this.listOpenVolumes.remove(volume); + assert (removed); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#openVolume(java.lang.String, + * org.xtreemfs.foundation.SSLOptions, org.xtreemfs.common.libxtreemfs.Options) + */ + @Override + public AdminVolume openVolume(String volumeName, SSLOptions sslOptions, Options options) + throws AddressToUUIDNotFoundException, VolumeNotFoundException, IOException { + UUIDIterator mrcUuidIterator = new UUIDIterator(); + volumeNameToMRCUUID(volumeName, mrcUuidIterator); + + VolumeImplementation volume = new VolumeImplementation(this, this.clientUUID, mrcUuidIterator, + volumeName, sslOptions, options); + volume.start(startThreadsAsDaemons); + + this.listOpenVolumes.add(volume); + return volume; + } + + public void createVolume(String mrcAddress, Auth auth, UserCredentials userCredentials, String volumeName) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + + List volumeAttributes = new ArrayList(); + createVolume(mrcAddress, auth, userCredentials, volumeName, 511, "", "", + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, + StripingPolicyType.STRIPING_POLICY_RAID0, 128, 1, volumeAttributes); + }; + + public void createVolume(List mrcAddresses, Auth auth, UserCredentials userCredentials, + String volumeName) throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + + List volumeAttributes = new ArrayList(); + createVolume(mrcAddresses, auth, userCredentials, volumeName, 511, "", "", + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, + StripingPolicyType.STRIPING_POLICY_RAID0, 128, 1, volumeAttributes); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#createVolume(java.lang.String, + * org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth, org.xtreemfs.common.auth.UserCredentials, + * java.lang.String, int, java.lang.String, java.lang.String, org.xtreemfs.pbrpc.generatedinterfaces + * .GlobalTypes.AccessControlPolicyType, + * org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType, int, int, java.util.List) + */ + @Override + public void createVolume(String mrcAddress, Auth auth, UserCredentials userCredentials, + String volumeName, int mode, String ownerUsername, String ownerGroupname, + AccessControlPolicyType accessPolicyType, StripingPolicyType defaultStripingPolicyType, + int defaultStripeSize, int defaultStripeWidth, List volumeAttributes) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + UUIDIterator iteratorWithAddresses = new UUIDIterator(); + iteratorWithAddresses.addUUID(mrcAddress); + + createVolume(iteratorWithAddresses, auth, userCredentials, volumeName, mode, ownerUsername, + ownerGroupname, accessPolicyType, defaultStripingPolicyType, defaultStripeSize, + defaultStripeWidth, volumeAttributes); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#createVolume(java.lang.String, + * org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth, org.xtreemfs.common.auth.UserCredentials, + * java.lang.String, int, java.lang.String, java.lang.String, org.xtreemfs.pbrpc.generatedinterfaces + * .GlobalTypes.AccessControlPolicyType, + * org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType, int, int, java.util.List) + */ + @Override + public void createVolume(Auth auth, UserCredentials userCredentials, String volumeName, int mode, + String ownerUsername, String ownerGroupname, AccessControlPolicyType accessPolicyType, + StripingPolicyType defaultStripingPolicyType, int defaultStripeSize, int defaultStripeWidth, + List volumeAttributes) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + + // access the list of MRCs + ServiceSet mrcs = RPCCaller. syncCall(SERVICES.DIR, + this.dirServiceUserCredentials, this.dirServiceAuth, this.options, this, + this.dirServiceAddresses, true, null, new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, String input) throws IOException { + return ClientImplementation.this.dirServiceClient.xtreemfs_service_get_by_type( + server, authHeader, userCreds, ServiceType.SERVICE_TYPE_MRC); + } + }); + + if (mrcs.getServicesCount() == 0) { + throw new IOException("no MRC available for volume creation"); + } + + List mrcAddresses = new ArrayList(); + for (Service uuid : mrcs.getServicesList()) { + mrcAddresses.add(uuidToAddress(uuid.getUuid())); + } + createVolume(mrcAddresses, auth, userCredentials, volumeName, mode, ownerUsername, ownerGroupname, + accessPolicyType, defaultStripingPolicyType, defaultStripeSize, defaultStripeWidth, + volumeAttributes); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#createVolume(java.util.List, + * org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth, org.xtreemfs.common.auth.UserCredentials, + * java.lang.String, int, java.lang.String, java.lang.String, org.xtreemfs.pbrpc.generatedinterfaces + * .GlobalTypes.AccessControlPolicyType, + * org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType, int, int, java.util.List) + */ + @Override + public void createVolume(List mrcAddresses, Auth auth, UserCredentials userCredentials, + String volumeName, int mode, String ownerUsername, String ownerGroupname, + AccessControlPolicyType accessPolicyType, StripingPolicyType defaultStripingPolicyType, + int defaultStripeSize, int defaultStripeWidth, List volumeAttributes) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + UUIDIterator iteratorWithAddresses = new UUIDIterator(); + iteratorWithAddresses.addUUIDs(mrcAddresses); + createVolume(iteratorWithAddresses, auth, userCredentials, volumeName, mode, ownerUsername, + ownerGroupname, accessPolicyType, defaultStripingPolicyType, defaultStripeSize, + defaultStripeWidth, volumeAttributes); + } + + private void createVolume(UUIDIterator mrcAddresses, Auth auth, UserCredentials userCredentials, + String volumeName, int mode, String ownerUsername, String ownerGroupname, + AccessControlPolicyType accessPolicyType, StripingPolicyType defaultStripingPolicyType, + int defaultStripeSize, int defaultStripeWidth, List volumeAttributes) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + final MRCServiceClient mrcClient = new MRCServiceClient(this.networkClient, null); + + StripingPolicy sp = StripingPolicy.newBuilder().setType(defaultStripingPolicyType) + .setStripeSize(defaultStripeSize).setWidth(defaultStripeWidth).build(); + + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume volume = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume + .newBuilder().setName(volumeName).setMode(mode).setOwnerUserId(ownerUsername) + .setOwnerGroupId(ownerGroupname).setAccessControlPolicy(accessPolicyType) + .setDefaultStripingPolicy(sp).addAllAttrs(volumeAttributes).setId("").build(); + + RPCCaller. syncCall(SERVICES.MRC, + userCredentials, auth, this.options, this, mrcAddresses, true, volume, + new CallGenerator() { + @SuppressWarnings("unchecked") + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth auth, + UserCredentials userCreds, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume input) + throws IOException { + return mrcClient.xtreemfs_mkvol(server, auth, userCreds, input); + }; + }); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#deleteVolume(java.lang.String, + * org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth, org.xtreemfs.common.auth.UserCredentials, + * java.lang.String) + */ + @Override + public void deleteVolume(Auth auth, UserCredentials userCredentials, String volumeName) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + + ServiceSet s = RPCCaller. syncCall(SERVICES.DIR, this.dirServiceUserCredentials, + this.dirServiceAuth, this.options, this, this.dirServiceAddresses, true, volumeName, + new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, String volumeName) throws IOException { + return ClientImplementation.this.dirServiceClient.xtreemfs_service_get_by_name( + server, authHeader, userCreds, volumeName); + } + }); + + if (s == null || s.getServicesCount() == 0) { + throw new IOException("volume '" + volumeName + "' does not exist"); + } + + if (s != null) { + final Service vol = s.getServices(0); + final String mrcAddress = uuidToAddress(KeyValuePairs + .getValue(vol.getData().getDataList(), "mrc")); + deleteVolume(mrcAddress, auth, userCredentials, volumeName); + } + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#deleteVolume(java.lang.String, + * org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth, org.xtreemfs.common.auth.UserCredentials, + * java.lang.String) + */ + @Override + public void deleteVolume(String mrcAddress, Auth auth, UserCredentials userCredentials, String volumeName) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + UUIDIterator iteratorWithAddresses = new UUIDIterator(); + iteratorWithAddresses.addUUID(mrcAddress); + + deleteVolume(iteratorWithAddresses, auth, userCredentials, volumeName); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#deleteVolume(java.util.List, + * org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth, org.xtreemfs.common.auth.UserCredentials, + * java.lang.String) + */ + @Override + public void deleteVolume(List mrcAddresses, Auth auth, UserCredentials userCredentials, + String volumeName) throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + UUIDIterator iteratorWithAddresses = new UUIDIterator(); + iteratorWithAddresses.addUUIDs(mrcAddresses); + + deleteVolume(iteratorWithAddresses, auth, userCredentials, volumeName); + } + + private void deleteVolume(UUIDIterator mrcAddresses, Auth auth, UserCredentials userCredentials, + String volumeName) throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + final MRCServiceClient mrcServiceClient = new MRCServiceClient(this.networkClient, null); + + RPCCaller. syncCall(SERVICES.MRC, userCredentials, auth, this.options, this, + mrcAddresses, true, volumeName, new CallGenerator() { + @SuppressWarnings("unchecked") + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, String input) throws IOException { + return mrcServiceClient.xtreemfs_rmvol(server, authHeader, userCreds, input); + } + }); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#listVolumes(java.lang.String) + */ + @Override + public Volumes listVolumes(String mrcAddress) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + UUIDIterator iteratorWithAddresses = new UUIDIterator(); + iteratorWithAddresses.addUUID(mrcAddress); + return listVolumes(iteratorWithAddresses); + } + + @Override + public Volumes listVolumes(List mrcAddresses) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + UUIDIterator iteratorWithAddresses = new UUIDIterator(); + iteratorWithAddresses.addUUIDs(mrcAddresses); + return listVolumes(iteratorWithAddresses); + } + + private Volumes listVolumes(UUIDIterator uuidIteratorWithAddresses) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + final MRCServiceClient mrcServiceClient = new MRCServiceClient(this.networkClient, null); + + // use bogus user credentials + UserCredentials userCredentials = UserCredentials.newBuilder().setUsername("xtreemfs").build(); + + Volumes volumes = RPCCaller. syncCall(SERVICES.MRC, userCredentials, + this.authBogus, this.options, this, uuidIteratorWithAddresses, true, + emptyRequest.getDefaultInstance(), new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, emptyRequest input) throws IOException { + return mrcServiceClient.xtreemfs_lsvol(server, authHeader, userCreds, input); + }; + }); + return volumes; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#listVolumes() + */ + @Override + public Volumes listVolumes() throws IOException { + ServiceSet sSet = RPCCaller. syncCall(SERVICES.DIR, + this.dirServiceUserCredentials, this.dirServiceAuth, this.options, this, + this.dirServiceAddresses, true, null, new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, String input) throws IOException { + return ClientImplementation.this.dirServiceClient.xtreemfs_service_get_by_type( + server, authHeader, userCreds, ServiceType.SERVICE_TYPE_VOLUME); + } + }); + + UUIDIterator iteratorWithAddresses = new UUIDIterator(); + for (int i = 0; i < sSet.getServicesCount(); i++) { + for (KeyValuePair kvp : sSet.getServices(i).getData().getDataList()) { + if (kvp.getKey().substring(0, 3).equals("mrc")) { + String mrcUuid = kvp.getValue(); + iteratorWithAddresses.addUUID(uuidToAddress(mrcUuid)); + break; + } + } + } + return listVolumes(iteratorWithAddresses); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#listVolumeNames() + */ + @Override + public String[] listVolumeNames() throws IOException { + ServiceSet sSet = RPCCaller. syncCall(SERVICES.DIR, + this.dirServiceUserCredentials, this.dirServiceAuth, this.options, this, + this.dirServiceAddresses, true, null, new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, String input) throws IOException { + return ClientImplementation.this.dirServiceClient.xtreemfs_service_get_by_type( + server, authHeader, userCreds, ServiceType.SERVICE_TYPE_VOLUME); + } + }); + + String[] volNames = new String[sSet.getServicesCount()]; + for (int i = 0; i < volNames.length; i++) { + volNames[i] = sSet.getServices(i).getName(); + } + return volNames; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#listServers() + */ + @Override + public Map listServers() throws IOException, PosixErrorException { + // access the list of servers at the DIR + ServiceSet osds = RPCCaller. syncCall(SERVICES.DIR, + this.dirServiceUserCredentials, this.dirServiceAuth, this.options, this, + this.dirServiceAddresses, true, null, new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, String input) throws IOException { + return ClientImplementation.this.dirServiceClient.xtreemfs_service_get_by_type( + server, authHeader, userCreds, ServiceType.SERVICE_TYPE_MIXED); + } + }); + + Map serviceConfigs = new HashMap(); + for (Service service : osds.getServicesList()) { + if (service.getType() == ServiceType.SERVICE_TYPE_MRC + || service.getType() == ServiceType.SERVICE_TYPE_OSD) { + serviceConfigs.put(uuidToAddress(service.getUuid()), service); + } + } + + return serviceConfigs; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Client#listOSDsAndAttributes() + */ + @Override + public Map listOSDsAndAttributes() throws IOException, PosixErrorException { + // access the list of OSDs + ServiceSet osds = RPCCaller. syncCall(SERVICES.DIR, + this.dirServiceUserCredentials, this.dirServiceAuth, this.options, this, + this.dirServiceAddresses, true, null, new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, String input) throws IOException { + return ClientImplementation.this.dirServiceClient.xtreemfs_service_get_by_type( + server, authHeader, userCreds, ServiceType.SERVICE_TYPE_OSD); + } + }); + + Map osdConfigs = new HashMap(); + for (Service service : osds.getServicesList()) { + // // access the config files of each OSD + // Configuration config = RPCCaller. syncCall(SERVICES.DIR, + // this.dirServiceUserCredentials, + // this.dirServiceAuth, this.options, this, this.dirServiceAddresses, true, uuid.getUuid(), + // new CallGenerator() { + // @Override + // public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + // UserCredentials userCreds, String input) throws IOException { + // return ClientImplementation.this.dirServiceClient.xtreemfs_configuration_get(server, + // authHeader, userCreds, input); + // } + // }); + osdConfigs.put(service.getUuid(), service); + } + + return osdConfigs; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.UUIDResolver#uuidToAddress(java.lang. String, java.lang.String) + */ + @Override + public String uuidToAddress(String uuid) throws AddressToUUIDNotFoundException { + + // The uuid must never be empty. + assert (!uuid.isEmpty()); + + String address = ""; + + ServiceUUID serviceUuid = new ServiceUUID(uuid, this.uuidResolver); + try { + serviceUuid.resolve(); + address = serviceUuid.getAddressString(); + } catch (UnknownUUIDException e) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "UUID: SERVICE NOT FOUND FOR UUID %S", uuid); + } + throw new AddressToUUIDNotFoundException(uuid); + } + + return address; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.UUIDResolver#volumeNameToMRCUUID(java .lang.String, + * java.lang.String) + */ + @Override + public String volumeNameToMRCUUID(String volumeName) throws VolumeNotFoundException, + AddressToUUIDNotFoundException { + assert (!volumeName.isEmpty()); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "Searching MRC for volume %s", + volumeName); + } + + // Check if there is an '@' in the volume. Everything behind the '@' is + // the snapshot, + // cut if off. + String parsedVolumeName = parseVolumeName(volumeName); + ServiceSet sSet = null; + try { + sSet = RPCCaller. syncCall(SERVICES.DIR, this.dirServiceUserCredentials, + this.dirServiceAuth, this.options, this, this.dirServiceAddresses, true, + parsedVolumeName, new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, String input) throws IOException { + return ClientImplementation.this.dirServiceClient.xtreemfs_service_get_by_name( + server, authHeader, userCreds, input); + } + }); + } catch (IOException e) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "volumeNameToMRCUUID: " + + "couldn't resolve mrc UUID for volumeName %s Reason: %s", volumeName, + e.getMessage()); + } + + throw new VolumeNotFoundException(parsedVolumeName); + } + + // check if there is an service which is a VOLUME and then filter the + // MRC of this volume + // from its ServiceDataMap. + String mrcUuid = ""; + for (Service service : sSet.getServicesList()) { + if (service.getType().equals(ServiceType.SERVICE_TYPE_VOLUME) + && service.getName().equals(parsedVolumeName)) { + for (KeyValuePair kvp : service.getData().getDataList()) { + if (kvp.getKey().substring(0, 3).equals("mrc")) { + mrcUuid = kvp.getValue(); + break; + } + } + // don't check other services if there are any left when an + // mrcUuid is already determined. + if (!mrcUuid.isEmpty()) { + break; + } + } + } + + // Error Handling + if (mrcUuid.isEmpty()) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "No MRC found for volume $s.", + parsedVolumeName); + } + throw new VolumeNotFoundException(parsedVolumeName); + } + + return mrcUuid; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.UUIDResolver#volumeNameToMRCUUID(java .lang.String, + * org.xtreemfs.common.libxtreemfs.UUIDIterator) + */ + @Override + public void volumeNameToMRCUUID(String volumeName, UUIDIterator uuidIterator) + throws VolumeNotFoundException, AddressToUUIDNotFoundException { + + assert (uuidIterator != null); + assert (!volumeName.isEmpty()); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "Searching MRC for volume %s", + volumeName); + } + + // Check if there is a @ in the volume_name. + // Everything behind the @ has to be removed as it identifies the + // snapshot. + String parsedVolumeName = parseVolumeName(volumeName); + ServiceSet sSet = null; + try { + sSet = RPCCaller. syncCall(SERVICES.DIR, this.dirServiceUserCredentials, + this.dirServiceAuth, this.options, this, this.dirServiceAddresses, true, + parsedVolumeName, new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, String input) throws IOException { + return ClientImplementation.this.dirServiceClient.xtreemfs_service_get_by_name( + server, authHeader, userCreds, input); + } + }); + } catch (IOException e) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "volumeNameToMRCUUID: " + + "couldn't resolve mrc UUID for volumeName %s Reason: %s", volumeName, + e.getMessage()); + } + + throw new VolumeNotFoundException(parsedVolumeName); + } + + // Iterate over ServiceSet to find an appropriate MRC + boolean mrcFound = false; + for (Service service : sSet.getServicesList()) { + if (service.getType().equals(ServiceType.SERVICE_TYPE_VOLUME) + && service.getName().equals(parsedVolumeName)) { + for (KeyValuePair kvp : service.getData().getDataList()) { + if (kvp.getKey().substring(0, 3).equals("mrc")) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "MRC with UUID: %s" + + " added (key: %s).", kvp.getValue(), kvp.getKey()); + } + uuidIterator.addUUID(kvp.getValue()); + mrcFound = true; + } + } + } + } + + // Error handling + if (!mrcFound) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "No MRC found for volume $s.", + parsedVolumeName); + } + throw new VolumeNotFoundException(parsedVolumeName); + } + } + + /** + * If volumeName contains an '@', cut off everything after the at because this belongs to the snapshot. + * The real volumename is everything before the '@'. + * + * @param volumeName + * The volumeName that should be parsed + * @return String The parsed volume name. + * + */ + private String parseVolumeName(String volumeName) { + + int pos = 0; + String parsedVolumeName; + if ((pos = volumeName.indexOf('@')) == -1) { + parsedVolumeName = volumeName; + } else { + parsedVolumeName = volumeName.substring(0, pos); + } + + return parsedVolumeName; + } + + // Methods for AdminClient + + private Auth StringToAuth(String password) { + return Auth.newBuilder().setAuthType(AuthType.AUTH_PASSWORD) + .setAuthPasswd(AuthPassword.newBuilder().setPassword(password).build()).build(); + } + + public void startCleanUp(String osdUUID, String password, boolean remove, boolean deleteVolumes, boolean restore, + boolean removeMetdata, int metaDataTimeoutS) throws IOException { + try { + xtreemfs_cleanup_startRequest request = xtreemfs_cleanup_startRequest.newBuilder() + .setRemoveZombies(remove).setRemoveUnavailVolume(deleteVolumes).setLostAndFound(restore) + .setDeleteMetadata(removeMetdata).setMetadataTimeout(metaDataTimeoutS) + .build(); + Auth pw = StringToAuth(password); + UUIDIterator it = new UUIDIterator(); + it.addUUID(osdUUID); + RPCCaller. syncCall(SERVICES.OSD, + RPCAuthentication.userService, pw, options, this, it, false, request, + new CallGenerator() { + @Override + @SuppressWarnings("unchecked") + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, + xtreemfs_cleanup_startRequest input) throws IOException { + return osdServiceClient.xtreemfs_cleanup_start(server, authHeader, userCreds, input); + } + }); + } catch (Exception e) { + throw new IOException("Cleanup could not be started on the given OSD, because: " + e.getMessage()); + } + } + + public void startVersionCleanUp(String osdUUID, String password) throws IOException { + try { + Auth pw = StringToAuth(password); + UUIDIterator it = new UUIDIterator(); + it.addUUID(osdUUID); + RPCCaller. syncCall(SERVICES.OSD, RPCAuthentication.userService, pw, + options, this, it, false, null, new CallGenerator() { + @Override + @SuppressWarnings("unchecked") + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, emptyRequest input) + throws IOException { + return osdServiceClient.xtreemfs_cleanup_versions_start(server, authHeader, + userCreds); + } + }); + } catch (Exception e) { + throw new IOException("Version cleanup could not be started on the given OSD, because: " + + e.getMessage()); + } + } + + public void stopCleanUp(String osdUUID, String password) throws IOException { + Auth pw = StringToAuth(password); + UUIDIterator it = new UUIDIterator(); + it.addUUID(osdUUID); + RPCCaller. syncCall(SERVICES.OSD, RPCAuthentication.userService, pw, + options, this, it, false, null, new CallGenerator() { + @Override + @SuppressWarnings("unchecked") + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, emptyRequest input) throws IOException, + PosixErrorException { + return osdServiceClient.xtreemfs_cleanup_stop(server, authHeader, userCreds); + } + }); + } + + public boolean isRunningCleanUp(String osdUUID, String password) throws IOException { + Auth pw = StringToAuth(password); + UUIDIterator it = new UUIDIterator(); + it.addUUID(osdUUID); + xtreemfs_cleanup_is_runningResponse response = RPCCaller + . syncCall(SERVICES.OSD, + RPCAuthentication.userService, pw, options, this, it, false, null, + new CallGenerator() { + @Override + public RPCResponse executeCall( + InetSocketAddress server, Auth authHeader, UserCredentials userCreds, + emptyRequest input) throws IOException, PosixErrorException { + return osdServiceClient.xtreemfs_cleanup_is_running(server, authHeader, + userCreds); + } + }); + assert (response != null); + return response.getIsRunning(); + } + + public String getCleanUpState(String osdUUID, String password) throws IOException { + Auth pw = StringToAuth(password); + UUIDIterator it = new UUIDIterator(); + it.addUUID(osdUUID); + xtreemfs_cleanup_statusResponse response = RPCCaller + . syncCall(SERVICES.OSD, + RPCAuthentication.userService, pw, options, this, it, false, null, + new CallGenerator() { + @Override + public RPCResponse executeCall( + InetSocketAddress server, Auth authHeader, UserCredentials userCreds, + emptyRequest input) throws IOException, PosixErrorException { + return osdServiceClient + .xtreemfs_cleanup_status(server, authHeader, userCreds); + } + }); + assert (response != null); + return response.getStatus(); + } + + public List getCleanUpResult(String osdUUID, String password) throws IOException { + Auth pw = StringToAuth(password); + UUIDIterator it = new UUIDIterator(); + it.addUUID(osdUUID); + xtreemfs_cleanup_get_resultsResponse response = RPCCaller + . syncCall(SERVICES.OSD, + RPCAuthentication.userService, pw, options, this, it, false, null, + new CallGenerator() { + @Override + public RPCResponse executeCall( + InetSocketAddress server, Auth authHeader, UserCredentials userCreds, + emptyRequest input) throws IOException, PosixErrorException { + return osdServiceClient.xtreemfs_cleanup_get_results(server, authHeader, + userCreds); + } + }); + + assert (response != null); + return response.getResultsList(); + } + + public ServiceSet getServiceByType(ServiceType serviceType) throws IOException { + serviceGetByTypeRequest request = serviceGetByTypeRequest.newBuilder().setType(serviceType).build(); + + ServiceSet sSet = RPCCaller. syncCall(SERVICES.DIR, + RPCAuthentication.userService, RPCAuthentication.authNone, options, this, + dirServiceAddresses, true, request, new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, serviceGetByTypeRequest input) throws IOException { + return dirServiceClient.xtreemfs_service_get_by_type(server, authHeader, userCreds, + input); + } + }); + + assert (sSet != null); + return sSet; + } + + public Service getServiceByUUID(String uuid) throws IOException { + serviceGetByUUIDRequest request = serviceGetByUUIDRequest.newBuilder().setName(uuid).build(); + + ServiceSet sSet = RPCCaller. syncCall(SERVICES.DIR, + RPCAuthentication.userService, RPCAuthentication.authNone, options, this, + dirServiceAddresses, true, request, new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, serviceGetByUUIDRequest input) throws IOException { + return dirServiceClient.xtreemfs_service_get_by_uuid(server, authHeader, userCreds, + input); + } + }); + + if (sSet.getServicesCount() == 0) { + throw new IOException("No Service with UUID " + uuid + " available"); + } + return sSet.getServices(0); + } + + public void setOSDServiceStatus(String osdUUID, ServiceStatus serviceStatus) throws IOException { + // Get OSD services + Service osdService = getServiceByUUID(osdUUID); + + // Change service status + List data = new LinkedList(osdService.getData().getDataList()); + KeyValuePairs.putValue(data, HeartbeatThread.STATUS_ATTR, Integer.toString(serviceStatus.getNumber())); + KeyValuePairs.putValue(data, HeartbeatThread.DO_NOT_SET_LAST_UPDATED, Boolean.toString(true)); + ServiceDataMap dataMap = ServiceDataMap.newBuilder().addAllData(data).build(); + osdService = osdService.toBuilder().setData(dataMap).build(); + + // Send changed service status to DIR + serviceRegisterRequest request = serviceRegisterRequest.newBuilder().setService(osdService).build(); + RPCCaller. syncCall(SERVICES.DIR, + RPCAuthentication.userService, RPCAuthentication.authNone, options, this, + dirServiceAddresses, true, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, serviceRegisterRequest input) + throws IOException { + return dirServiceClient.xtreemfs_service_register(server, RPCAuthentication.authNone, + userCreds, input); + } + }); + } + + public ServiceStatus getOSDServiceStatus(String osdUUID) throws IOException { + Service osdService = getServiceByUUID(osdUUID); + String serviceStatus = KeyValuePairs.getValue(osdService.getData().getDataList(), + HeartbeatThread.STATUS_ATTR); + return ServiceStatus.valueOf(Integer.valueOf(serviceStatus)); + } + + public Set getRemovedOsds() throws IOException { + + Set removedOSDs = new TreeSet(); + + String statusRemoved = Integer.toString(ServiceStatus.SERVICE_STATUS_REMOVED.getNumber()); + ServiceSet servs = getServiceByType(ServiceType.SERVICE_TYPE_OSD); + + for (Service serv : servs.getServicesList()) { + String hbAttr = KeyValuePairs.getValue(serv.getData().getDataList(), HeartbeatThread.STATUS_ATTR); + if (hbAttr != null && hbAttr.equalsIgnoreCase(statusRemoved)) { + removedOSDs.add(serv.getUuid()); + } + } + return removedOSDs; + + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/FileHandle.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/FileHandle.java new file mode 100644 index 0000000..964bbd5 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/FileHandle.java @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; + +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.common.libxtreemfs.exceptions.UUIDNotInXlocSetException; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock; + +/** + * FileHandle represents an open file. + */ +public interface FileHandle { + + /** + * Read from a file 'count' bytes starting at 'offset' into 'buf'. + * + * @param userCredentials + * Name and Groups of the user. + * @param data + * [out] Byte array to be filled with read data. + * @param count + * Number of requested bytes. + * @param offset + * Offset in bytes. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * + * @return Number of bytes read. + */ + public int read(UserCredentials userCredentials, byte[] data, int count, long offset) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Read from a file 'count' bytes starting at 'offset' into 'buf'. + * + * @param userCredentials + * Name and Groups of the user. + * @param data + * [out] Byte array to be filled with read data. + * @param dataOffset + * Offset in data array. This is the position of the first bytes in the data array that should + * be read. + * @param count + * Number of requested bytes. + * @param offset + * Offset in bytes. At this position in the file the data will be read. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * + * @return Number of bytes read. + */ + public int read(UserCredentials userCredentials, byte[] data, int dataOffset, int count, long offset) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Write to a file 'count' bytes at file offset 'offset' from 'buf'. + * + * @attention If asynchronous writes are enabled (which is the default unless the file was opened with + * O_SYNC or async writes were disabled globally), no possible write errors can be returned as + * write() does return immediately after putting the write request into the send queue instead + * of waiting until the result was received. In this case, only after calling flush() or + * close() occurred write errors are returned to the user. + * + * @param userCredentials + * Name and Groups of the user. + * @param data + * [] [in] Byte array which contains data to be written. + * @param count + * Number of bytes to be written from buf. + * @param offset + * Offset in bytes. + * + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * + * @return Number of bytes written (see @attention above). + */ + public int write(UserCredentials userCredentials, byte[] data, int count, long offset) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Write to a file 'count' bytes at file offset 'offset' from 'buf'. + * + * @attention If asynchronous writes are enabled (which is the default unless the file was opened with + * O_SYNC or async writes were disabled globally), no possible write errors can be returned as + * write() does return immediately after putting the write request into the send queue instead + * of waiting until the result was received. In this case, only after calling flush() or + * close() occurred write errors are returned to the user. + * + * @param userCredentials + * Name and Groups of the user. + * + * @param data + * [] [in] Byte array which contains data to be written. + * @param dataOffset + * Offset in data array. This is the position of the first bytes in the data array that should + * be written. + * @param count + * Number of bytes to be written from buf. + * @param offset + * Offset in bytes. At this position in the file the data will be written. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * + * @return Number of bytes written (see @attention above). + */ + public int write(UserCredentials userCredentials, byte[] data, int dataOffset, int count, + long offset) throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Flushes pending writes and file size updates (corresponds to a fsync() system call). + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public void flush() throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Truncates the file to "newFileSize_ bytes". + * + * @param userCredentials + * Name and Groups of the user. + * @param newFileSize + * New size of the file. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + **/ + public void truncate(UserCredentials userCredentials, long newFileSize) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Retrieve the attributes of this file and writes the result in "stat". + * + * @param userCredentials + * Name and Groups of the user. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public Stat getAttr(UserCredentials userCredentials) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException; + + /** + * Sets a lock on the specified file region and returns the resulting Lock object. + * + * If the acquisition of the lock fails, PosixErrorException will be thrown and posix_errno() will return + * POSIX_ERROR_EAGAIN. + * + * @param userCredentials + * Name and Groups of the user. + * @param processId + * ID of the process to which the lock belongs. + * @param offset + * Start of the region to be locked in the file. + * @param length + * Length of the region. + * @param exclusive + * shared/read lock (false) or write/exclusive (true)? + * @param waitForLock + * if true, blocks until lock acquired. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * + * @remark Ownership is transferred to the caller. + */ + public Lock acquireLock(UserCredentials userCredentials, int processId, long offset, + long length, boolean exclusive, boolean waitForLock) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException; + + /** + * Checks if the requested lock does not result in conflicts. If true, the returned Lock object contains + * the requested 'process_id' in 'client_pid', otherwise the Lock object is a copy of the conflicting + * lock. + * + * @param userCredentials + * Name and Groups of the user. + * @param processId + * ID of the process to which the lock belongs. + * @param offset + * Start of the region to be locked in the file. + * @param length + * Length of the region. + * @param exclusive + * shared/read lock (false) or write/exclusive (true)? + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * + * @remark Ownership is transferred to the caller. + */ + public Lock checkLock(UserCredentials userCredentials, int processId, long offset, long length, + boolean exclusive) throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Releases "lock". + * + * @param userCredentials + * Name and Groups of the user. + * @param processId + * ID of the process to which the lock belongs. + * @param offset + * Start of the region to be locked in the file. + * @param length + * Length of the region. + * @param exclusive + * shared/read lock (false) or write/exclusive (true)? + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public void releaseLock(UserCredentials userCredentials, int processId, long offset, + long length, boolean exclusive) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException; + + /** + * Releases "lock" (parameters given in Lock object). + * + * @param userCredentials + * Name and Groups of the user. + * @param lock + * Lock to be released. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public void releaseLock(UserCredentials userCredentials, Lock lock) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Releases the lock possibly hold by "processId". Use this before closing a file to ensure POSIX + * semantics: + * + * "All locks associated with a file for a given process shall be removed when a file descriptor for that + * file is closed by that process or the process holding that file descriptor terminates." + * (http://pubs.opengroup.org/onlinepubs/009695399/functions/fcntl.html) + * + * @param processId + * ID of the process whose lock shall be released. + * + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public void releaseLockOfProcess(int processId) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException; + + /** + * Triggers the replication of the replica on the OSD with the UUID "osd_uuid" if the replica is a full + * replica (and not a partial one). + * + * The Replica had to be added beforehand and "osd_uuid" has to be included in the XlocSet of the file. + * + * @param userCredentials + * Name and Groups of the user. + * @param osdUuid + * UUID of the OSD where the replica is located. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + * @throws UUIDNotInXlocSetException + */ + public void pingReplica(UserCredentials userCredentials, String osdUuid) throws IOException, + AddressToUUIDNotFoundException; + + /** + * Closes the open file handle (flushing any pending data). + * + * @attention Please execute ReleaseLockOfProcess() first if there're multiple open file handles for the + * same file and you want to ensure the POSIX semantics that with the close of a file handle + * the lock (XtreemFS allows only one per tuple (client UUID, Process ID)) of the process will + * be closed. If you do not care about this, you don't have to release any locks on your own as + * all locks will be automatically released if the last open file handle of a file will be + * closed. + * + * @throws IOException + */ + public void close() throws IOException; +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/FileHandleImplementation.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/FileHandleImplementation.java new file mode 100644 index 0000000..cf181fa --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/FileHandleImplementation.java @@ -0,0 +1,1380 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.libxtreemfs.RPCCaller.CallGenerator; +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.InternalServerErrorException; +import org.xtreemfs.common.libxtreemfs.exceptions.InvalidChecksumException; +import org.xtreemfs.common.libxtreemfs.exceptions.InvalidViewException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.common.libxtreemfs.exceptions.UUIDIteratorListIsEmpyException; +import org.xtreemfs.common.libxtreemfs.exceptions.UUIDNotInXlocSetException; +import org.xtreemfs.common.libxtreemfs.exceptions.XtreemFSException; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.client.RPCResponseAvailableListener; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SERVICES; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.XATTR_FLAGS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +//JCIP import net.jcip.annotations.GuardedBy; + +/** + * Implementation of FileHandle and AdminFileHandle. Used only internally. + */ +public class FileHandleImplementation implements FileHandle, AdminFileHandle { + + /** + * UUID of the Client (needed to distinguish Locks of different clients). + */ + final private String clientUuid; + + /** + * UUIDIterator of the MRC. + */ + final private UUIDIterator mrcUuidIterator; + + /** + * UUIDIterator which contains the UUIDs of all replicas. + */ + final private UUIDIterator osdUuidIterator; + + /** + * Needed to resolve UUIDs. + */ + final private UUIDResolver uuidResolver; + + /** + * Multiple FileHandle may refer to the same File and therefore unique file properties (e.g. Path, FileId, XlocSet) + * are stored in a FileInfo object. + */ + final private FileInfo fileInfo; + + /** + * Volume which did open this file. + */ + final private VolumeImplementation volume; + + // TODO(mberlin): Add flags member. + + /** + * Capabilitiy for the file, used to authorize against services. + */ + private XCap xcap; + + /** + * True if there is an outstanding xcapRenew callback. + */ + // JCIP @GuardedBy("xcapRenewalPendingLock") + private boolean xcapRenewalPending; + + /** + * Used to wait for pending XCap renewal callbacks. + */ + final private Object xcapRenewalPendingLock; + + /** + * Contains a file size update which has to be written back (or NULL). + */ + private OSDWriteResponse osdWriteResponseForAsyncWriteBack; + + /** + * MRCServiceClient from the VolumeImplemention. + */ + final private MRCServiceClient mrcServiceClient; + + /** + * Pointer to object owned by VolumeImplemention. + */ + final private OSDServiceClient osdServiceClient; + + /** + * Stores which {@link StripingPolicyType} corresponds to which {@link StripeTranslator}. + */ + final Map stripeTranslators; + + /** + * Set to true if async writes (max requests > 0, no O_SYNC) are enabled. + */ + private boolean asyncWritesEnabled; + + /** + * Set to true if an async write of this file_handle failed. If true, this file_handle is broken and no further + * writes/reads/truncates are possible. + */ + private boolean asyncWritesFailed; + + + final private Options volumeOptions; + + /** + * Auth needed for ServiceClients. Always set to AUTH_NONE by Volume. + */ + final private Auth authBogus; + + /** + * For same reason needed as authBogus. Always set to user "xtreemfs". + */ + final private UserCredentials userCredentialsBogus; + + public FileHandleImplementation(VolumeImplementation volume, String clientUuid, FileInfo fileInfo, XCap xcap, + UUIDIterator mrcUuidIterator, UUIDIterator osdUuidIterator, UUIDResolver uuidResolver, + MRCServiceClient mrcServiceClient, OSDServiceClient osdServiceClient, + Map stripeTranslators, boolean asyncWritesEnabled, Options options, + Auth authBogus, UserCredentials userCredentialsBogus) { + this.volume = volume; + this.clientUuid = clientUuid; + this.fileInfo = fileInfo; + this.xcap = xcap; + this.mrcUuidIterator = mrcUuidIterator; + this.osdUuidIterator = osdUuidIterator; + this.uuidResolver = uuidResolver; + this.mrcServiceClient = mrcServiceClient; + this.osdServiceClient = osdServiceClient; + this.stripeTranslators = stripeTranslators; + this.asyncWritesEnabled = asyncWritesEnabled; + this.volumeOptions = options; + this.authBogus = authBogus; + this.userCredentialsBogus = userCredentialsBogus; + + xcapRenewalPending = false; + xcapRenewalPendingLock = new Object(); + } + + /** + * Used to execute an operation and check on invalid view exceptions.
    + * If the view the operation was executed with is outdated, it will be renewed and the operation retried. + */ + private abstract class ViewCheckedOperation { + + T execute() throws IOException { + int maxTries = volumeOptions.getMaxViewRenewals(); + int attempt = 0; + + while (++attempt <= maxTries || maxTries == 0) { + try { + return doOperation(); + } catch (InvalidViewException e) { + if (attempt == maxTries && maxTries > 0) { + // The request did finally fail. + // Append the number of attempts to the message and rethrow. + String errorMsg = e.getMessage() + " Request finally failed after " + attempt + " attempts"; + throw new InvalidViewException(errorMsg); + + } else { + // Delay the xLocSet renewal and the next run of the operation. + RPCCaller.waitDelay(volumeOptions.getRetryDelay_s()); + + // Try to renew the XLocSet. + renewXLocSet(); + } + } + } + + throw new InvalidViewException("The operation did fail due to an outdated view after " + + attempt + " attempts."); + } + + abstract T doOperation() throws IOException; + } + + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#read(org.xtreemfs.foundation .pbrpc.generatedinterfaces.RPC + * .UserCredentials, org.xtreemfs.foundation.buffer.ReusableBuffer, int, long) + */ + @Override + public int read(UserCredentials userCredentials, byte[] data, int count, long offset) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + return read(userCredentials, data, 0, count, offset); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#read(org.xtreemfs.foundation .pbrpc.generatedinterfaces.RPC + * .UserCredentials, org.xtreemfs.foundation.buffer.ReusableBuffer, int, long) + */ + @Override + public int read(final UserCredentials userCredentials, final byte[] data, final int dataOffset, final int count, + final long offset) throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + + ViewCheckedOperation operation = new ViewCheckedOperation() { + @Override + Integer doOperation() throws IOException { + return doRead(userCredentials, data, dataOffset, count, offset); + } + }; + return operation.execute(); + } + + private int doRead(UserCredentials userCredentials, byte[] data, int dataOffset, int count, long offset) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + fileInfo.waitForPendingAsyncWrites(); + FileCredentials.Builder fcBuilder = FileCredentials.newBuilder(); + synchronized (this) { + if (asyncWritesFailed) { + throw new PosixErrorException(POSIXErrno.POSIX_ERROR_EIO, "A previous asynchronous" + + " write did fail. No more actions on this file handle are allowed."); + } + // TODO(mberlin): XCap might expire while retrying a request. + // Provide a mechanism to renew the xcap in the request. + fcBuilder.setXcap(xcap.toBuilder()); + } + FileCredentials fc = fcBuilder.setXlocs(fileInfo.getXLocSet()).build(); + + ReusableBuffer buf = ReusableBuffer.wrap(data, dataOffset, count); + int receivedData = 0; + + if (fc.getXlocs().getReplicasCount() == 0) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, "No replica found for file %s", + fileInfo.getPath()); + throw new PosixErrorException(POSIXErrno.POSIX_ERROR_EIO, "no replica found for file: " + + fileInfo.getPath()); + } + + // Pick the first replica to determine striping policy. + // (We assume that all replicas use the same striping policy.) + StripingPolicy policy = fc.getXlocs().getReplicas(0).getStripingPolicy(); + StripeTranslator translator = getStripeTranslator(policy.getType()); + + // Map offset to corresponding OSDs. + Vector operations = new Vector(); + translator.translateReadRequest(count, offset, policy, operations); + + UUIDIterator tempUuidIteratorForStriping = new UUIDIterator(); + // Read all objects + for (int j = 0; j < operations.size(); j++) { + readRequest.Builder readRqBuilder = readRequest.newBuilder(); + + readRqBuilder.setFileCredentials(fc); + readRqBuilder.setFileId(fc.getXcap().getFileId()); + readRqBuilder.setObjectNumber(operations.get(j).getObjNumber()); + readRqBuilder.setObjectVersion(0); + readRqBuilder.setOffset(operations.get(j).getReqOffset()); + readRqBuilder.setLength(operations.get(j).getReqSize()); + + // Differ between striping and the rest (replication, no replication). + UUIDIterator uuidIterator; + if (readRqBuilder.getFileCredentials().getXlocs().getReplicas(0).getOsdUuidsCount() > 1) { + // Replica is striped. Pick UUID from xlocset. + tempUuidIteratorForStriping.clear(); + + // Replicas may have different stripe widths. However, the current Java client + // StripeTranslator code only supports the same stripe width as the first replica has. + int stripeWidthFirstReplica = fc.getXlocs().getReplicas(0).getStripingPolicy().getWidth(); + + for (int replicaIdx = 0; replicaIdx < fc.getXlocs().getReplicasCount(); replicaIdx++) { + if (fc.getXlocs().getReplicas(replicaIdx).getStripingPolicy().getWidth() == stripeWidthFirstReplica) { + tempUuidIteratorForStriping.addUUID(Helper.getOSDUUIDFromXlocSet(fc.getXlocs(), + replicaIdx, + operations.get(j).getOsdOffset())); + } + } + + uuidIterator = tempUuidIteratorForStriping; + } else { + // TODO(mberlin): Enhance UUIDIterator to read from different replicas. + uuidIterator = osdUuidIterator; + } + + buf.position(operations.get(j).getBufferStart()); + // If synccall gets a buffer it fill it with data from the response. + ObjectData objectData = RPCCaller. syncCall(SERVICES.OSD, userCredentialsBogus, + authBogus, volumeOptions, uuidResolver, uuidIterator, false, readRqBuilder.build(), buf, + new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth auth, + UserCredentials userCreds, readRequest callRequest) throws IOException { + return osdServiceClient.read(server, auth, userCreds, callRequest); + + } + }); + // if zeropadding > 0, put zeros at the end of the buffer. + for (int i = 0; i < objectData.getZeroPadding(); i++) { + buf.put((byte) 0); + } + receivedData += buf.position() - operations.get(j).getBufferStart(); + } + return receivedData; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#write(org.xtreemfs.foundation .pbrpc.generatedinterfaces. + * RPC.UserCredentials, org.xtreemfs.foundation.buffer.ReusableBuffer, int, long) + */ + @Override + public synchronized int write(UserCredentials userCredentials, byte[] data, int count, long offset) + throws IOException, PosixErrorException, InternalServerErrorException, AddressToUUIDNotFoundException { + ReusableBuffer buffer = ReusableBuffer.wrap(data); + return write(userCredentials, buffer, count, offset); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#write(org.xtreemfs.foundation.pbrpc.generatedinterfaces. + * RPC.UserCredentials, byte[], int, int, long) + */ + @Override + public synchronized int write(UserCredentials userCredentials, byte[] data, int dataOffset, int count, long offset) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + ReusableBuffer buffer = ReusableBuffer.wrap(data, dataOffset, count); + return write(userCredentials, buffer, count, offset); + } + + private int write(UserCredentials userCredentials, ReusableBuffer buffer, int count, long offset) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + FileCredentials.Builder fcBuilder = FileCredentials.newBuilder(); + synchronized (this) { + if (asyncWritesFailed) { + throw new PosixErrorException(POSIXErrno.POSIX_ERROR_EIO, "A previous asynchronous " + + "write did fail. No further writes on this file handle are allowed."); + } + fcBuilder.setXcap(xcap.toBuilder()); + } + + fcBuilder.setXlocs(fileInfo.getXLocSet()); + + String globalFileId = fcBuilder.getXcap().getFileId(); + XLocSet xlocs = fcBuilder.getXlocs(); + + if (xlocs.getReplicasCount() == 0) { + String error = "No replica found for file: " + fileInfo.getPath(); + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, error); + throw new PosixErrorException(POSIXErrno.POSIX_ERROR_EIO, error); + } + + // Map operation to stripes. + Vector operations = new Vector(); + StripingPolicy stripingPolicy = xlocs.getReplicas(0).getStripingPolicy(); + StripeTranslator translator = getStripeTranslator(stripingPolicy.getType()); + + translator.translateWriteRequest(count, offset, stripingPolicy, buffer, operations); + + FileCredentials fileCredentials = fcBuilder.build(); + + String osdUuid = ""; + writeRequest.Builder request; + + if (asyncWritesEnabled) { + // Write all objects. + for (int j = 0; j < operations.size(); j++) { + request = writeRequest.newBuilder(); + request.setFileCredentials(fileCredentials); + request.setFileId(globalFileId); + + request.setObjectNumber(operations.get(j).getObjNumber()); + request.setObjectVersion(0); + request.setOffset(operations.get(j).getReqOffset()); + request.setLeaseTimeout(0); + + ObjectData objectData = ObjectData.newBuilder().setChecksum(0).setInvalidChecksumOnOsd(false) + .setZeroPadding(0).build(); + request.setObjectData(objectData); + + // Create new WriteBuffer and differ between striping and the + // rest ( + // (replication = use UUIDIterator, no replication = set + // specific UUID). + AsyncWriteBuffer writeBuffer; + + if (xlocs.getReplicas(0).getOsdUuidsCount() > 1) { + // Replica is striped. Pick UUID from xlocset + writeBuffer = new AsyncWriteBuffer(request.build(), operations.get(j).getReqData(), operations.get( + j).getReqSize(), this, Helper.getOSDUUIDFromXlocSet(xlocs, 0, operations.get(j) + .getOsdOffset())); + } else { + writeBuffer = new AsyncWriteBuffer(request.build(), operations.get(j).getReqData(), operations.get( + j).getReqSize(), this); + } + + // TODO(mberlin): Currently the UserCredentials are ignored by the OSD and + // therefore we avoid copying them into writeBuffer. + fileInfo.asyncWrite(writeBuffer); + + // Processing of file size updates is handled by the FileInfo's AsyncWriteHandler. + } + } else { + // synchroneous write + for (int j = 0; j < operations.size(); j++) { + request = writeRequest.newBuilder(); + request.setFileCredentials(fileCredentials); + request.setFileId(globalFileId); + request.setObjectNumber(operations.get(j).getObjNumber()); + request.setObjectVersion(0); + request.setOffset(operations.get(j).getReqOffset()); + request.setLeaseTimeout(0); + + ObjectData objectData = ObjectData.newBuilder().setChecksum(0).setInvalidChecksumOnOsd(false) + .setZeroPadding(0).build(); + + request.setObjectData(objectData); + + // Differ between striping and the rest (replication, no replication). + UUIDIterator uuidIterator; + if (xlocs.getReplicas(0).getOsdUuidsCount() > 1) { + // Replica is striped. Pick UUID from Xlocset. Use first and only replica. + osdUuid = Helper.getOSDUUIDFromXlocSet(xlocs, 0, operations.get(j).getOsdOffset()); + uuidIterator = new UUIDIterator(); + uuidIterator.clearAndAddUUID(osdUuid); + } else { + // TODO: enhance UUIDIterator to read from different replicas. + uuidIterator = osdUuidIterator; + } + + final ReusableBuffer writeDataBuffer = operations.get(j).getReqData(); + OSDWriteResponse response = RPCCaller. syncCall(SERVICES.OSD, + userCredentials, authBogus, volumeOptions, uuidResolver, uuidIterator, false, request.build(), + new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, writeRequest input) throws IOException { + return osdServiceClient.write(server, authHeader, userCreds, input, + writeDataBuffer.createViewBuffer()); + } + }); + + assert (response != null); + + // If the filesize has changed, remember OSDWriteResponse for later file size + // update towards the MRC (executed by PeriodicFileSizeUpdateThread). + if (response.hasSizeInBytes()) { + fileInfo.tryToUpdateOSDWriteResponse(response, xcap); + } + } + } + return count; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#flush() + */ + @Override + public void flush() throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + flush(false); + } + + protected void flush(boolean closeFile) throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + fileInfo.flush(this, closeFile); + throwIfAsyncWritesFailed(); + } + + private boolean didAsyncWriteFail() { + synchronized (this) { + return this.asyncWritesFailed; + } + } + + private void throwIfAsyncWritesFailed() throws PosixErrorException { + if (didAsyncWriteFail()) { + String error = "Flush for file " + fileInfo.getPath() + " did not succeed flushing " + + "all pending writes as at least one asynchronous write did fail."; + + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, error); + throw new PosixErrorException(POSIXErrno.POSIX_ERROR_EIO, error); + } + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#truncate(org.xtreemfs.foundation .pbrpc.generatedinterfaces + * .RPC.UserCredentials, int) + */ + @Override + public void truncate(UserCredentials userCredentials, long newFileSize) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + truncate(userCredentials, newFileSize, false); + } + + public void truncate(UserCredentials userCredentials, long newFileSize, boolean updateOnlyMRC) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + fileInfo.waitForPendingAsyncWrites(); + XCap xcapCopy; + boolean awf = false; + synchronized (this) { + awf = asyncWritesFailed; + } + if (awf) { + throw new PosixErrorException(POSIXErrno.POSIX_ERROR_EIO, "A previous asynchronous " + + "write did fail.No further action on this file handle are allowed."); + } + xcapCopy = getXcap(); + + // 1. Call truncate at the MRC (in order to increase the trunc epoch). + XCap truncateXCap = RPCCaller. syncCall(SERVICES.MRC, userCredentials, authBogus, volumeOptions, + uuidResolver, mrcUuidIterator, false, xcapCopy, new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, XCap input) throws IOException { + return mrcServiceClient.ftruncate(server, authHeader, userCreds, input); + } + }); + // set new XCap received from MRC. Necessary to invoke truncate at OSD. + synchronized (xcap) { + xcap = truncateXCap; + } + truncatePhaseTwoAndThree(userCredentials, newFileSize, updateOnlyMRC); + } + + /** + * Used by truncate() and Volume.openFile() to truncate the file to "newFileSize" on the OSD and update the file + * size at the MRC. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + **/ + protected void truncatePhaseTwoAndThree(UserCredentials userCredentials, long newFileSize, boolean updateOnlyMRC) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + + OSDWriteResponse response = null; + + XCap xCapCopy = getXcap(); + + if (!updateOnlyMRC) { + + // 2. Call truncate at the head OSD. + truncateRequest.Builder requestBuilder = truncateRequest.newBuilder(); + FileCredentials.Builder fileCredentialsBuilder = FileCredentials.newBuilder(); + fileCredentialsBuilder.setXlocs(fileInfo.getXLocSet()); + fileCredentialsBuilder.setXcap(xCapCopy); + requestBuilder.setFileId(fileCredentialsBuilder.getXcap().getFileId()); + requestBuilder.setFileCredentials(fileCredentialsBuilder.build()); + requestBuilder.setNewFileSize(newFileSize); + + response = RPCCaller. syncCall(SERVICES.OSD, userCredentials, authBogus, + volumeOptions, uuidResolver, osdUuidIterator, false, requestBuilder.build(), + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, truncateRequest input) throws IOException { + return osdServiceClient.truncate(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + assert (response.hasSizeInBytes()); + } else { + + // create OSDWriteResponse + response = OSDWriteResponse.newBuilder().setTruncateEpoch(xCapCopy.getTruncateEpoch()) + .setSizeInBytes(newFileSize).build(); + + } + + // register the new OSDWriteResponse to this file's FileInfo. + fileInfo.tryToUpdateOSDWriteResponse(response, xCapCopy); + + // 3. Update the file size at the MRC. + fileInfo.flushPendingFileSizeUpdate(this); + + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#getAttr(org.xtreemfs.foundation .pbrpc.generatedinterfaces + * .RPC.UserCredentials) + */ + @Override + public Stat getAttr(UserCredentials userCredentials) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + return volume.getAttr(userCredentials, fileInfo.getPath()); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#acquireLock(org.xtreemfs. foundation.pbrpc.generatedinterfaces + * .RPC.UserCredentials, int, long, long, boolean, boolean) + */ + @Override + public Lock acquireLock(UserCredentials userCredentials, int processId, long offset, long length, + boolean exclusive, boolean waitForLock) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + // Create Lock object for the acquire lock request. + Lock.Builder lockBuilder = Lock.newBuilder(); + lockBuilder.setClientUuid(clientUuid); + lockBuilder.setClientPid(processId); + lockBuilder.setOffset(offset); + lockBuilder.setLength(length); + lockBuilder.setExclusive(exclusive); + + Lock lock = lockBuilder.build(); + + // Check active locks first. + Tupel checkLockReturn = fileInfo.checkLock(lock); + boolean conflictFound = checkLockReturn.getSecond()[0]; + boolean cachedLockForPidEqual = checkLockReturn.getSecond()[2]; + + if (conflictFound) { + throw new PosixErrorException(POSIXErrno.POSIX_ERROR_EAGAIN, "conflicting lock"); + } + + // We allow only one lock per PID, i.e. an existing lock can be always + // overwritten. In consequence, acquireLock() always has to be executed + // except the new lock is equal to the current lock. + if (cachedLockForPidEqual) { + return lock; + } + + // Cache could not be used. Create FileCredentials, complete lockRequest + // and send to OSD. + FileCredentials.Builder fcBuilder = FileCredentials.newBuilder(); + fcBuilder.setXlocs(fileInfo.getXLocSet()); + fcBuilder.setXcap(getXcap()); + lockRequest request = lockRequest.newBuilder().setLockRequest(lock).setFileCredentials(fcBuilder.build()) + .build(); + + Lock response = null; + if (!waitForLock) { + response = RPCCaller. syncCall(SERVICES.OSD, userCredentials, authBogus, volumeOptions, + uuidResolver, osdUuidIterator, false, request, new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, lockRequest input) throws IOException { + return osdServiceClient.xtreemfs_lock_acquire(server, authHeader, userCreds, input); + } + }); + } else { + // Retry to obtain the lock in case of EAGAIN responses.\ + int retriesLeft = volumeOptions.getMaxTries(); + while (retriesLeft >= 0) { + retriesLeft--; + try { + response = RPCCaller. syncCall(SERVICES.OSD, userCredentials, authBogus, + volumeOptions, uuidResolver, osdUuidIterator, false, true, 1, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, lockRequest input) throws IOException { + return osdServiceClient.xtreemfs_lock_acquire(server, authHeader, userCreds, input); + } + }); + // break if there is no error. + break; + } catch (PosixErrorException pe) { + if (pe.getPosixError().equals(POSIXErrno.POSIX_ERROR_EAGAIN) == false) { + // Only retry if there exists a conflicting lock and the server did + // return an EAGAIN - otherwise rethrow the exception. + throw pe; + } + } + } + } + // "Cache" new lock. + fileInfo.putLock(response); + return response; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#checkLock(org.xtreemfs.foundation .pbrpc.generatedinterfaces + * .RPC.UserCredentials, int, long, long, boolean) + */ + @Override + public Lock checkLock(UserCredentials userCredentials, int processId, long offset, long length, boolean exclusive) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + // Create lock object for the check lock request. + Lock.Builder lockBuilder = Lock.newBuilder(); + lockBuilder.setClientUuid(clientUuid); + lockBuilder.setClientPid(processId); + lockBuilder.setOffset(offset); + lockBuilder.setLength(length); + lockBuilder.setExclusive(exclusive); + + Lock lock = lockBuilder.build(); + + // Check active locks first. + Tupel checkLockReturn = fileInfo.checkLock(lock); + Lock conflictingLock = checkLockReturn.getFirst(); + boolean conflictFound = checkLockReturn.getSecond()[0]; + boolean lockForPidCached = checkLockReturn.getSecond()[1]; + + if (conflictFound) { + return conflictingLock; + } + + // We allow only one lock per PID, i.e. an existing lock can be always + // overwritten. + if (lockForPidCached) { + return lock; + } + + // Cache could not be used. Create lockRequest and send to OSD. + FileCredentials.Builder fcBuilder = FileCredentials.newBuilder(); + fcBuilder.setXlocs(fileInfo.getXLocSet()); + fcBuilder.setXcap(getXcap()); + lockRequest request = lockRequest.newBuilder().setLockRequest(lock).setFileCredentials(fcBuilder.build()) + .build(); + + Lock response = RPCCaller. syncCall(SERVICES.OSD, userCredentials, authBogus, volumeOptions, + uuidResolver, osdUuidIterator, false, request, new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, lockRequest input) throws IOException { + return osdServiceClient.xtreemfs_lock_check(server, authHeader, userCreds, input); + } + }); + return response; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#releaseLock(org.xtreemfs. foundation.pbrpc.generatedinterfaces + * .RPC.UserCredentials, int, long, long, boolean) + */ + @Override + public void releaseLock(UserCredentials userCredentials, int processId, long offset, long length, boolean exclusive) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + Lock.Builder lockBuilder = Lock.newBuilder(); + lockBuilder.setClientUuid(clientUuid); + lockBuilder.setClientPid(processId); + lockBuilder.setOffset(offset); + lockBuilder.setLength(length); + lockBuilder.setExclusive(exclusive); + releaseLock(userCredentials, lockBuilder.build()); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#releaseLock(org.xtreemfs. foundation.pbrpc.generatedinterfaces + * .RPC.UserCredentials, org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock) + */ + @Override + public void releaseLock(UserCredentials userCredentials, Lock lock) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + // Only release locks which are known to this client. + if (!fileInfo.checkIfProcessHasLocks(lock.getClientPid())) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "FileHandleImplementation.releaseLock(): Skipping unlock request as there" + + " is no lock known for PID: %s (Lock description: %s, %s ,%s)", lock.getClientPid(), + lock.getOffset(), lock.getLength(), lock.getExclusive()); + } + return; + } + + FileCredentials.Builder fcBuilder = FileCredentials.newBuilder(); + fcBuilder.setXlocs(fileInfo.getXLocSet()); + fcBuilder.setXcap(getXcap()); + + lockRequest unlockRequest = lockRequest.newBuilder().setFileCredentials(fcBuilder.build()).setLockRequest(lock) + .build(); + + RPCCaller. syncCall(SERVICES.OSD, userCredentials, authBogus, volumeOptions, + uuidResolver, osdUuidIterator, false, unlockRequest, new CallGenerator() { + @SuppressWarnings("unchecked") + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, lockRequest input) throws IOException { + return osdServiceClient.xtreemfs_lock_release(server, authHeader, userCreds, input); + } + }); + fileInfo.delLock(lock); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#releaseLockOfProcess(int) + */ + @Override + public void releaseLockOfProcess(int processId) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + fileInfo.releaseLockOfProcess(this, processId); + } + + /** + * Releases "lock" with userCredentials from this fileHandle object. + * + * @param lock + */ + protected void releaseLock(Lock lock) throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + releaseLock(userCredentialsBogus, lock); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#pingReplica(org.xtreemfs. foundation.pbrpc.generatedinterfaces + * .RPC.UserCredentials, java.lang.String) + */ + @Override + public void pingReplica(UserCredentials userCredentials, String osdUuid) throws IOException, + AddressToUUIDNotFoundException { + readRequest.Builder readRequestBuilder = readRequest.newBuilder(); + FileCredentials.Builder fileCredentialsBuilder = FileCredentials.newBuilder(); + synchronized (xcap) { + fileCredentialsBuilder.setXcap(xcap.toBuilder()); + } + XLocSet xlocs = fileInfo.getXLocSet(); + fileCredentialsBuilder.setXlocs(xlocs); + readRequestBuilder.setFileId(fileCredentialsBuilder.getXcap().getFileId()); + readRequestBuilder.setFileCredentials(fileCredentialsBuilder); + + // Check if osdUuid is part of the xlocset + if (xlocs.getReplicasCount() == 0) { + throw new UUIDIteratorListIsEmpyException("pingReplica: The Xlocset contains no replicas"); + } + boolean uuidFound = false; + for (Replica replica : xlocs.getReplicasList()) { + // TODO(mberlin): Every OSD in a striped replica has to be pinged. + // Always check only the head OSD. + if (replica.getOsdUuids(0).equals(osdUuid)) { + uuidFound = true; + // Check replication flags, if it's a full replica. + if (xlocs.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY) + && ((replica.getReplicationFlags() & REPL_FLAG.REPL_FLAG_FULL_REPLICA.getNumber()) == 0)) { + // Nothing to do here because the replication does not need to be + // triggered for partial replicas. + return; + } + break; + } + } + if (uuidFound == false) { + throw new UUIDNotInXlocSetException("UUID: " + osdUuid + " not found in the xlocset: " + xlocs.toString()); + } + + // Read one byte from the replica to trigger the replication. + readRequestBuilder.setObjectNumber(0); + readRequestBuilder.setObjectVersion(0); + readRequestBuilder.setOffset(0); + readRequestBuilder.setLength(1); + + UUIDIterator tempUuidIterator = new UUIDIterator(); + tempUuidIterator.addUUID(osdUuid); + + RPCCaller. syncCall(SERVICES.OSD, userCredentialsBogus, authBogus, volumeOptions, + uuidResolver, tempUuidIterator, false, readRequestBuilder.build(), + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth auth, + UserCredentials userCreds, readRequest callRequest) throws IOException { + return osdServiceClient.read(server, auth, userCreds, callRequest); + + } + }); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.FileHandle#close() + */ + @Override + public void close() throws IOException { + try { + flush(true); + } catch (Exception e) { + // TODO: handle exception + e.printStackTrace(); + } finally { + fileInfo.closeFileHandle(this); + } + } + + protected void writeBackFileSizeAsync() throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + xtreemfs_update_file_sizeRequest.Builder rqBuilder = xtreemfs_update_file_sizeRequest.newBuilder(); + + synchronized (this) { + if (osdWriteResponseForAsyncWriteBack == null) { + return; + } + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "updateFileSize: %s " + "#bytes: %s", + fileInfo.getPath(), osdWriteResponseForAsyncWriteBack.getSizeInBytes()); + } + rqBuilder.setXcap(xcap).setOsdWriteResponse(osdWriteResponseForAsyncWriteBack.toBuilder()); + } + + // set close file to false because true implies synchronous call. + rqBuilder.setCloseFile(false); + + String address = uuidResolver.uuidToAddress(mrcUuidIterator.getUUID()); + InetSocketAddress server = RPCCaller.getInetSocketAddressFromAddress(address, SERVICES.MRC); + + RPCResponse r = mrcServiceClient.xtreemfs_update_file_size(server, authBogus, + userCredentialsBogus, rqBuilder.build()); + + final FileHandleImplementation fileHandle = this; + + r.registerListener(new RPCResponseAvailableListener() { + + @Override + public void responseAvailable(RPCResponse r) { + try { + r.get(); + fileInfo.asyncFileSizeUpdateResponseHandler(osdWriteResponseForAsyncWriteBack, fileHandle, true); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "renewXcapAsync: The following " + + "error occurred during the async all: ", e.getMessage()); + } + fileInfo.asyncFileSizeUpdateResponseHandler(osdWriteResponseForAsyncWriteBack, fileHandle, false); + } finally { + r.freeBuffers(); + } + } + }); + } + + protected void setOsdWriteResponseForAsyncWriteBack(OSDWriteResponse osdwr) { + synchronized (this) { + assert (osdWriteResponseForAsyncWriteBack == null); + this.osdWriteResponseForAsyncWriteBack = osdwr.toBuilder().build(); + } + } + + protected void renewXCapAsync() throws IOException, AddressToUUIDNotFoundException { + XCap xcapCopy; + + synchronized (this) { + // TODO: Only renew after some time has elapsed. + // TODO: Cope with local clocks which have high clock skew. + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "Renew SCap for fileId: %s Expiration in: %s", Helper.extractFileIdFromXcap(xcap), + xcap.getExpireTimeoutS() - System.currentTimeMillis() / 1000); + } + xcapCopy = this.xcap.toBuilder().build(); + + synchronized (xcapRenewalPendingLock) { + xcapRenewalPending = true; + } + } + + String address = uuidResolver.uuidToAddress(mrcUuidIterator.getUUID()); + InetSocketAddress server = RPCCaller.getInetSocketAddressFromAddress(address, SERVICES.MRC); + RPCResponse r = mrcServiceClient.xtreemfs_renew_capability(server, authBogus, userCredentialsBogus, + xcapCopy); + + r.registerListener(new RPCResponseAvailableListener() { + @Override + public void responseAvailable(RPCResponse r) { + try { + XCap newXCap = r.get(); + setRenewedXcap(newXCap); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "renewXcapAsync: Renewing XCap" + + " of file %s failed. Error: %s", fileInfo.getPath(), e.getMessage()); + } + } finally { + r.freeBuffers(); + synchronized (xcapRenewalPendingLock) { + xcapRenewalPending = false; + xcapRenewalPendingLock.notifyAll(); + } + } + } + }); + } + + private void setRenewedXcap(XCap newXCap) { + synchronized (xcap) { + // Overwrite current XCap only by a newer one (i.e. later expire time) + if (newXCap.getExpireTimeS() > xcap.getExpireTimeS()) { + xcap = newXCap; + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "XCap renewed for fileId %s", + Helper.extractFileIdFromXcap(xcap)); + } + } + } + } + + /** + * Sets asyncWritesFailed to true. + */ + protected void markAsyncWritesAsFailed() { + synchronized (this) { + asyncWritesFailed = true; + } + } + + protected XCap getXcap() { + synchronized (this) { + return xcap.toBuilder().build(); + } + } + + /** + * Sends pending file size updates synchronous (needed for flush/close). + * + * @throws IOException + */ + protected void writeBackFileSize(OSDWriteResponse response, boolean closeFile) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + + long fileId = 0; + fileId = Helper.extractFileIdFromXcap(getXcap()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "WriteBackFileSize: fileId: %s #bytes: %s close file?: %s", fileId, response.getSizeInBytes(), + closeFile); + } + + xtreemfs_update_file_sizeRequest.Builder requestBuilder = xtreemfs_update_file_sizeRequest.newBuilder(); + + requestBuilder.setXcap(getXcap()); + requestBuilder.setOsdWriteResponse(response.toBuilder().build()); + requestBuilder.setCloseFile(closeFile); + + RPCCaller. syncCall(SERVICES.MRC, userCredentialsBogus, + authBogus, volumeOptions, uuidResolver, mrcUuidIterator, false, requestBuilder.build(), + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, xtreemfs_update_file_sizeRequest input) throws IOException { + + return mrcServiceClient.xtreemfs_update_file_size(server, authHeader, userCreds, input); + } + }); + } + + public String getGlobalFileId() { + return getXcap().getFileId(); + } + + private StripeTranslator getStripeTranslator(StripingPolicyType type) throws IOException { + // Find the corresponding StripingPolicy + StripeTranslator st = stripeTranslators.get(type); + + if (st == null) { + throw new XtreemFSException("No StripingPolicy found for type:" + type); + } + return st; + } + + /** + * Blocks as long as the async xcap renewal is finished. + */ + protected void waitForAsyncXcapRenewalFinished() { + synchronized (xcapRenewalPendingLock) { + if (xcapRenewalPending == true) { + try { + xcapRenewalPendingLock.wait(); + } catch (InterruptedException ie) { + // TODO: find out what to do in this case; + return; + } + } + } + } + + protected XLocSet getXlocSet() { + return fileInfo.getXLocSet(); + } + + public List getReplicasList() { + return getXlocSet().getReplicasList(); + } + + public Replica getReplica(int replicaIndex) { + return getReplicasList().get(replicaIndex); + } + + public StripingPolicy getStripingPolicy() { + return getStripingPolicy(0); + } + + public StripingPolicy getStripingPolicy(int replicaIndex) { + return getReplica(replicaIndex).getStripingPolicy(); + } + + public String getReplicaUpdatePolicy() { + return getXlocSet().getReplicaUpdatePolicy(); + } + + public long getNumObjects(UserCredentials userCredentials) throws IOException, AddressToUUIDNotFoundException, + PosixErrorException { + + return Helper.getNumObjects(userCredentials, getAttr(userCredentials), getStripingPolicy()); + } + + public boolean checkAndMarkIfReadOnlyReplicaComplete(int replicaIndex, UserCredentials userCredentials) + throws IOException, AddressToUUIDNotFoundException { + + Replica replica = getReplica(replicaIndex); + if (((replica.getReplicationFlags() & REPL_FLAG.REPL_FLAG_IS_COMPLETE.getNumber()) != 0)) { + return true; + } + + long lastObjectNo = getNumObjects(userCredentials) - 1; + + // Number of the first Object the OSD (with index "osdRelPos") should hold + int osdRelPos = 0; + + FileCredentials.Builder fcBuilder = FileCredentials.newBuilder(); + fcBuilder.setXlocs(fileInfo.getXLocSet()); + fcBuilder.setXcap(getXcap()); + + String fileId = Helper.extractGlobalFileIdFromXcap(fcBuilder.getXcap()); + + for (String osdUUID : replica.getOsdUuidsList()) { + + UUIDIterator it = new UUIDIterator(); + it.addUUID(osdUUID); + + xtreemfs_internal_get_object_setRequest request = xtreemfs_internal_get_object_setRequest.newBuilder() + .setFileId(fileId).setFileCredentials(fcBuilder.build()).build(); + + // Remark: GetObjectSetOperation does not validate views, thus no XLocSetHandler is required. + ObjectList ol = RPCCaller. syncCall(SERVICES.OSD, + RPCAuthentication.userService, RPCAuthentication.authNone, volumeOptions, uuidResolver, it, false, + request, new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, xtreemfs_internal_get_object_setRequest input) + throws IOException, PosixErrorException { + return osdServiceClient.xtreemfs_internal_get_object_set(server, authHeader, userCreds, + input); + } + }); + + byte[] serializedBitSet = ol.getSet().toByteArray(); + ObjectSet oset = null; + + try { + oset = new ObjectSet(replica.getStripingPolicy().getWidth(), osdRelPos, serializedBitSet); + } catch (Exception e) { + throw new IOException("cannot deserialize object set: " + e, e); + } + + // check if the stripecolumn holds all Objects it should + for (long objNo = osdRelPos; objNo <= lastObjectNo; objNo += replica.getStripingPolicy().getWidth()) { + if (oset.contains(objNo) == false) { + return false; + } + } + + // increase osdRelPos for the next stripecolumn (stored on the next OSD) + osdRelPos++; + } + try { + volume.setXAttr(userCredentials, fileInfo.getPath(), "xtreemfs.mark_replica_complete", + replica.getOsdUuids(0), XATTR_FLAGS.XATTR_FLAGS_CREATE); + } catch (IOException e) { + // Couldn't mark replica as complete but it is complete, so just log it and ignore exception + Logging.logMessage(Logging.LEVEL_DEBUG, this, "unable to mark replica as complete: %s", e.toString()); + } + return true; + + } + + public int checkObjectAndGetSize(int replicaIndex, long objectNo) throws IOException, InvalidChecksumException { + ObjectData od = null; + RPCResponse osdRsp = null; + try { + + FileCredentials.Builder fcBuilder = FileCredentials.newBuilder(); + fcBuilder.setXlocs(fileInfo.getXLocSet()); + fcBuilder.setXcap(getXcap()); + + String fileId = Helper.extractGlobalFileIdFromXcap(fcBuilder.getXcap()); + + Replica r = getReplica(replicaIndex); + String objOsd = r.getOsdUuids((int) objectNo % r.getStripingPolicy().getWidth()); + + UUIDIterator it = new UUIDIterator(); + it.addUUID(objOsd); + + xtreemfs_check_objectRequest request = xtreemfs_check_objectRequest.newBuilder() + .setFileCredentials(fcBuilder.build()).setFileId(fileId).setObjectNumber(objectNo) + .setObjectVersion(0l).build(); + + // Remark: CheckObjectOperation does not validate views, thus no XLocSetHandler is required. + od = RPCCaller. syncCall(SERVICES.OSD, + RPCAuthentication.userService, RPCAuthentication.authNone, volumeOptions, uuidResolver, it, false, + request, new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, xtreemfs_check_objectRequest input) throws IOException, + PosixErrorException { + return osdServiceClient.xtreemfs_check_object(server, authHeader, userCreds, input); + } + }); + } catch (IOException e) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, this, "IO error: %s", e.toString()); + throw new IOException("operation aborted", e); + } + + if (od.getInvalidChecksumOnOsd()) { + throw new InvalidChecksumException("object " + objectNo + " has an invalid checksum"); + } + + return od.getZeroPadding(); + } + + @Override + public long getSizeOnOSD() throws IOException { + + // build FC + FileCredentials.Builder fcBuilder = FileCredentials.newBuilder(); + fcBuilder.setXlocs(fileInfo.getXLocSet()); + fcBuilder.setXcap(getXcap()); + + // get fileId + String fileId = Helper.extractGlobalFileIdFromXcap(fcBuilder.getXcap()); + + xtreemfs_internal_get_file_sizeRequest request = xtreemfs_internal_get_file_sizeRequest.newBuilder() + .setFileCredentials(fcBuilder.build()).setFileId(fileId).build(); + + xtreemfs_internal_get_file_sizeResponse response = RPCCaller + . syncCall( + SERVICES.OSD, + RPCAuthentication.userService, + RPCAuthentication.authNone, + volumeOptions, + uuidResolver, + osdUuidIterator, + false, + request, + new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, xtreemfs_internal_get_file_sizeRequest input) + throws IOException, PosixErrorException { + + return osdServiceClient.xtreemfs_internal_get_file_size(server, authHeader, userCreds, + input); + } + }); + + assert (response != null); + return response.getFileSize(); + } + + @Override + public void repairObject(int replicaIndex, long objectNo) throws IOException { + + // check if file is replicated + if (this.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE)) { + // unable to repair object if file is not replicated + throw new IOException("file must be replicated"); + } else { + FileCredentials.Builder fcBuilder = FileCredentials.newBuilder(); + fcBuilder.setXlocs(fileInfo.getXLocSet()); + fcBuilder.setXcap(getXcap()); + + String fileId = Helper.extractGlobalFileIdFromXcap(fcBuilder.getXcap()); + + String objOsd = Helper.getOSDUUIDFromObjectNo(getReplica(replicaIndex), objectNo); + + UUIDIterator it = new UUIDIterator(); + it.addUUID(objOsd); + + xtreemfs_repair_objectRequest request = xtreemfs_repair_objectRequest.newBuilder() + .setFileCredentials(fcBuilder.build()).setFileId(fileId).setObjectNumber(objectNo) + .setObjectVersion(0l).build(); + + emptyResponse response = RPCCaller. syncCall(SERVICES.OSD, + RPCAuthentication.userService, RPCAuthentication.authNone, volumeOptions, uuidResolver, it, false, + request, new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, xtreemfs_repair_objectRequest input) throws IOException, + PosixErrorException { + return osdServiceClient.xtreemfs_repair_object(server, authHeader, userCreds, input); + } + }); + } + } + + /** + * Renew the xLocSet synchronously.
    + * If another renewal is in pending, no additional renewal will be started and the caller will wait until the + * pending one finished. + */ + void renewXLocSet() throws PosixErrorException, InternalServerErrorException, IOException { + // Store the current xLocSet before entering the renewal mutex section. + XLocSet xLocSetToRenew = fileInfo.getXLocSet(); + + synchronized (fileInfo.xLocSetRenewalLock) { + XLocSet xLocSetCurrent = fileInfo.getXLocSet(); + + // Renew the xLocSet only if the xLocSet has not been renewed yet by another process. + if (xLocSetCurrent.getVersion() <= xLocSetToRenew.getVersion()) { + // The xCap is required to prevent unauthorized access to the XLocSet. + XCap xCap = getXcap(); + xtreemfs_get_xlocsetRequest request = xtreemfs_get_xlocsetRequest.newBuilder().setXcap(xCap).build(); + + XLocSet newXLocSet = RPCCaller. syncCall(SERVICES.MRC, + userCredentialsBogus, authBogus, volumeOptions, uuidResolver, mrcUuidIterator, false, false, 1, + request, new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, xtreemfs_get_xlocsetRequest input) throws IOException, + PosixErrorException { + return mrcServiceClient.xtreemfs_get_xlocset(server, authHeader, userCreds, input); + } + }); + + fileInfo.updateXLocSetAndRest(newXLocSet); + } + } + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/FileInfo.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/FileInfo.java new file mode 100644 index 0000000..0b06889 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/FileInfo.java @@ -0,0 +1,667 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; + +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.common.libxtreemfs.exceptions.XtreemFSException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock; + +//JCIP import net.jcip.annotations.GuardedBy; +/** + * Stores metadata of the the file as well as the current size. One FileInfo is responsible for all open FileHandles. + */ +public class FileInfo { + /** + * Different states regarding osdWriteResponse and its write back. + */ + enum FilesizeUpdateStatus { + kClean, kDirty, kDirtyAndAsyncPending, kDirtyAndSyncPending + }; + + /** + * Volume which did open this file. + */ + private VolumeImplementation volume; + + /** + * XtreemFS File ID of this file (does never change). + */ + long fileId; + + /** + * Path of the File, used for debug output and writing back the OSDWriteResponse to the MetadataCache. + */ + // JCIP @GuardedBy("pathLock") + private String path; + + /** + * Used to protect "path". + */ + private final Object pathLock; + + /** + * Extracted from the FileHandle's XCap: true if an explicit close() has to be send to the MRC in order to + * trigger the on close replication. + */ + boolean replicateOnClose; + + /** + * Number of file handles which hold a pointer on this object. + */ + private AtomicInteger referenceCount; + + /** + * List of corresponding OSDs. + */ + // JCIP @GuardedBy("xLocSetLock") + private XLocSet xlocset; + + /** + * Use this to protect "xlocset" and "replicateOnClose". + */ + Object xLocSetLock; + + /** + * Use this to protect the renewal of xLocSets. + */ + Object xLocSetRenewalLock; + + /** + * UUIDIterator which contains the UUIDs of all replicas. + * + * If striping is used, replication is not possible. Therefore, for striped files the UUID Iterator will + * contain only the head OSD. + */ + private UUIDIterator osdUuidIterator; + + /** + * List of active locks (acts as a cache). The OSD allows only one lock per (client UUID, PID) tuple. + */ + private ConcurrentHashMap activeLocks; + + /** + * Random UUID of this client to distinguish them while locking. + */ + private String clientUuid; + + /** + * List of open FileHandles for this file. + */ + private ConcurrentLinkedQueue openFileHandles; + + /** + * List of open FileHandles which solely exist to propagate a pending file size update (a OSDWriteResponse + * object) to the MRC. + * + * This extra list is needed to distinguish between the regular file handles (see open_file_handles_) and + * the ones used for file size updates. The intersection of both lists is empty. + */ + // JCIP @GuardedBy("osdWriteResponseLock") + private List pendingFilesizeUpdates; + + /** + * Pending file size update after a write() operation, may be NULL. + * + * If osdWriteResponse != NULL, the fileSize and "truncateEpoch" of the referenced + * {@link OSDWriteResponse} have to be respected, e.g. when answering a {@link getattrRequest}. This + * "osdWriteResponse" also corresponds to the "maximum" of all known OSDWriteReponses. The maximum has the + * highest "truncateEpoch", or if equal compared to another response, the higher "sizeInBytes" value. + */ + // JCIP @GuardedBy("osdWriteResponseLock") + private OSDWriteResponse osdWriteResponse; + + /** + * Denotes the state of the stored "osdWriteResponse" object. + */ + // JCIP @GuardedBy("osdWriteResponseLock") + private FilesizeUpdateStatus osdWriteResponseStatus; + + /** + * XCap required to send an OSDWriteResponse to the MRC. + */ + // JCIP @GuardedBy("osdWriteResponseLock") + private XCap osdWriteResponseXcap; + + /** + * Always lock to access "osdWriteResponse", "osdWriteResponseStatus", "osdWriteResponseXcap" or + * "pendingFilesizeUpdates". + */ + private final Object osdWriteResponseLock; + + /** + * Proceeds async writes, handles the callbacks and provides a waitForPendingWrites() method for barrier + * operations like read. + */ + AsyncWriteHandler asyncWriteHandler; + + /** + * + */ + public FileInfo(VolumeImplementation volume, long fileId, String path, boolean replicateOnClose, + XLocSet xlocset, String clientUuid) { + this.volume = volume; + this.fileId = fileId; + this.path = path; + this.replicateOnClose = replicateOnClose; + this.xlocset = xlocset; + this.clientUuid = clientUuid; + + referenceCount = new AtomicInteger(0); + osdWriteResponse = null; + osdWriteResponseStatus = FilesizeUpdateStatus.kClean; + osdWriteResponseLock = new Object(); + + pathLock = new Object(); + xLocSetLock = new Object(); + + xLocSetRenewalLock = new Object(); + + openFileHandles = new ConcurrentLinkedQueue(); + activeLocks = new ConcurrentHashMap(); + + // Add the UUIDs of all replicas to the UUID Iterator. + osdUuidIterator = new UUIDIterator(); + osdUuidIterator.addUUIDs(Helper.getOSDUUIDsFromXlocSet(xlocset)); + + asyncWriteHandler = new AsyncWriteHandler(this, osdUuidIterator, volume.getUUIDResolver(), + volume.getOsdServiceClient(), volume.getAuthBogus(), volume.getUserCredentialsBogus(), volume + .getOptions().getMaxWriteahead(), volume.getOptions().getMaxWriteaheadRequests(), + volume.getOptions().getMaxWriteTries()); + + pendingFilesizeUpdates = new ArrayList(volume.getOptions().getMaxWriteahead()); + } + + /** + * @see FileInfo#updateXLocSetAndRest(XLocSet, boolean) + */ + + + /** + * Create a copy of "newXlocSet" and save it to the "xlocset" member. "replicateOnClose" will be save in + * the corresponding member, too. + * + * @param newXlocset + * XlocSet that will be copied and set. + * @param replicateOnClose + * true if replicate on close is used. false otherwise. + * + */ + protected void updateXLocSetAndRest(XLocSet newXlocset, boolean replicateOnClose) { + synchronized (xLocSetLock) { + xlocset = XLocSet.newBuilder(newXlocset).build(); + this.replicateOnClose = replicateOnClose; + } + + // Update the osdUuidIterator to reflect the changes in the xlocset. + osdUuidIterator.clearAndAddUUIDs(Helper.getOSDUUIDsFromXlocSet(newXlocset)); + } + + /** + * @see FileInfo#updateXLocSetAndRest(XLocSet, boolean) + */ + protected void updateXLocSetAndRest(XLocSet newXlocset) { + synchronized (xLocSetLock) { + xlocset = XLocSet.newBuilder(newXlocset).build(); + } + + // Update the osdUuidIterator to reflect the changes in the xlocset. + osdUuidIterator.clearAndAddUUIDs(Helper.getOSDUUIDsFromXlocSet(newXlocset)); + } + + /** + * Returns a new FileHandle object to which xcap belongs. + * + */ + FileHandleImplementation createFileHandle(XCap xcap, boolean asyncWritesEnabled) { + return createFileHandle(xcap, asyncWritesEnabled, false); + } + + /** + * See createFileHandle(xcap). Does not add fileHandle to list of open file handles if + * usedForPendingFilesizeUpdate=true. + * + * This function will be used if a FileHandle was solely created to asynchronously write back a dirty file + * size update (osdWriteResponse). + * + * @remark Ownership is transferred to the caller. + */ + FileHandleImplementation createFileHandle(XCap xcap, boolean asyncWritesEnabled, + boolean usedForPendingFilesizeUpdate) { + FileHandleImplementation fileHandleImplementation = new FileHandleImplementation(volume, clientUuid, this, + xcap, volume.getMrcUuidIterator(), osdUuidIterator, volume.getUUIDResolver(), + volume.getMrcServiceClient(), volume.getOsdServiceClient(), volume.getStripeTranslators(), + asyncWritesEnabled, volume.getOptions(), volume.getAuthBogus(), + volume.getUserCredentialsBogus()); + + // increase reference count and add it to openFileHandles + referenceCount.incrementAndGet(); + openFileHandles.add(fileHandleImplementation); + + return fileHandleImplementation; + } + + /** + * Deregisters a closed FileHandle. Called by FileHandle.close(). + */ + protected void closeFileHandle(FileHandleImplementation fileHandle) { + // Pending async writes and file size updates have already been flushed + // by fileHandle. + + // remove file handle. + openFileHandles.remove(fileHandle); + + // Decreasing reference count is handle by Volume.closeFile(). + volume.closeFile(fileId, this, fileHandle); + } + + /** + * Decreases the reference count and returns the current value. + */ + protected int decreaseReferenceCount() { + int count = referenceCount.decrementAndGet(); + assert (count >= 0); + return count; + } + + /** + * Returns a copy of "osdWriteResponse" if not NULL. + */ + protected OSDWriteResponse getOSDWriteResponse() { + synchronized (osdWriteResponseLock) { + if (osdWriteResponse == null) { + return null; + } else { + return osdWriteResponse.toBuilder().build(); + } + } + } + + /** + * Returns path. + */ + protected String getPath() { + synchronized (pathLock) { + return path; + } + } + + /** + * Changes path to newPath if this.path == path. + */ + protected void renamePath(String path, String newPath) { + synchronized (pathLock) { + if (this.path.equals(path)) { + this.path = newPath; + } + } + } + + /** + * Compares "response" against the current "osdWriteResponse". Returns true if response is newer and + * assigns "response" to "osdWriteResponse". + * + * If successful, a new file handle will be created and xcap is required to send the osdWriteResponse to + * the MRC in the background. + * + */ + protected boolean tryToUpdateOSDWriteResponse(OSDWriteResponse response, XCap xcap) { + assert (response != null); + + synchronized (osdWriteResponseLock) { + if (Helper.compareOSDWriteResponses(response, osdWriteResponse) == 1) { + // update osdWriteResponse + osdWriteResponse = response.toBuilder().build(); + osdWriteResponseXcap = xcap.toBuilder().build(); + osdWriteResponseStatus = FilesizeUpdateStatus.kDirty; + return true; + } else { + return false; + } + } + } + + /** + * Merge into a possibly outdated Stat object (e.g. from the StatCache) the current file size and + * truncateEpoch from a stored OSDWriteResponse. + */ + protected Stat mergeStatAndOSDWriteResponse(Stat stat) { + synchronized (osdWriteResponseLock) { + if (osdWriteResponse != null) { + // Check if information in Stat is newer than + // osdWriteResponse_. + if (stat.getTruncateEpoch() < osdWriteResponse.getTruncateEpoch() + || stat.getTruncateEpoch() == osdWriteResponse.getTruncateEpoch() + && stat.getSize() < osdWriteResponse.getSizeInBytes()) { + // Information from "osdWriteResponse" are newer. + stat = stat.toBuilder().setSize(osdWriteResponse.getSizeInBytes()) + .setTruncateEpoch(osdWriteResponse.getTruncateEpoch()).build(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "getattr: merged infos from osdWriteResponse, size: %s", stat.getSize()); + } + } + } + } + return stat; + } + + /** + * Sends pending file size updates to the MRC asynchronously. + */ + protected void writeBackFileSizeAsync() throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + synchronized (osdWriteResponseLock) { + // Only update pending file size updates. + if (osdWriteResponse != null && osdWriteResponseStatus == FilesizeUpdateStatus.kDirty) { + FileHandleImplementation fileHandle = createFileHandle(osdWriteResponseXcap, false, true); + pendingFilesizeUpdates.add(fileHandle); + osdWriteResponseStatus = FilesizeUpdateStatus.kDirtyAndAsyncPending; + + fileHandle.setOsdWriteResponseForAsyncWriteBack(osdWriteResponse); + fileHandle.writeBackFileSizeAsync(); + } + } + } + + /** + * Renews xcap of all file handles of this file asynchronously. + */ + protected void renewXCapsAsync() throws AddressToUUIDNotFoundException { + Iterator fhiIterator = openFileHandles.iterator(); + try { + while (fhiIterator.hasNext()) { + fhiIterator.next().renewXCapAsync(); + } + } catch (IOException ioe) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "renewXcapsSync: Failed to renew XCap for fileHandles. Reason: %s", ioe.getCause()); + } + } + } + + /** + * Releases all locks of processId using fileHandle to issue ReleaseLock(). + */ + protected void releaseLockOfProcess(FileHandleImplementation fileHandle, int processId) + throws PosixErrorException, AddressToUUIDNotFoundException { + Lock lock = activeLocks.get(processId); + + if (lock != null) { + try { + // releaseLock deletes Lock from activeLocks + fileHandle.releaseLock(lock); + } catch (IOException ioe) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "releaseLock: Failed to release Lock for processID: %s. Reason: %s", processId, + ioe.getCause()); + } + } + } + } + + /** + * Uses fileHandle to release all known local locks. + */ + protected void releaseAllLocks(FileHandleImplementation fileHandle) throws PosixErrorException, + AddressToUUIDNotFoundException { + for (Lock lock : activeLocks.values()) { + // FileHandleImplementation.releaseLock(lock) will delete the lock + // from activeLocks. + try { + fileHandle.releaseLock(lock); + } catch (IOException ioe) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "releaseAllLocks: Failed to release for some Locks. Reason: %s", ioe.getCause()); + } + } + } + } + + /** + * Blocks until all asynchronous file size updates are completed. + */ + protected void waitForPendingFileSizeUpdates() { + synchronized (osdWriteResponseLock) { + while (pendingFilesizeUpdates.size() > 0) { + try { + osdWriteResponseLock.wait(); + } catch (InterruptedException e) { + // TODO: handle exception and figure out what happens if thread + // gets interrupted. + return; + } + } + } + } + + /** + * Called by the file size update callback of FileHandle. + */ + protected void asyncFileSizeUpdateResponseHandler(OSDWriteResponse owr, + FileHandleImplementation fileHandle, boolean success) { + synchronized (osdWriteResponseLock) { + // Only change the status of the OSDWriteResponse has not changed + // meanwhile. + if (Helper.compareOSDWriteResponses(owr, osdWriteResponse) == 0) { + // The status must not have changed. + assert (osdWriteResponseStatus == FilesizeUpdateStatus.kDirtyAndAsyncPending); + if (success) { + osdWriteResponseStatus = FilesizeUpdateStatus.kClean; + } else { + osdWriteResponseStatus = FilesizeUpdateStatus.kDirty; // Still dirty. + } + } + // Always remove the temporary FileHandle. + pendingFilesizeUpdates.remove(fileHandle); + decreaseReferenceCount(); + if (pendingFilesizeUpdates.size() == 0) { + osdWriteResponseLock.notifyAll(); + } + } + } + + /** + * Compares "lock" against list of active locks. + * + * Returns a {@link Tupel} where the first elements is the conflicting lock if such exits or null. The + * second element is a array of three boolean value in the following order: conflictFound, + * lockForPidCached, cachedLockForPidEqual. + * + * conflictFound is set to true and the conflicting, active lock return if there is a conflict. If no + * conflict was found, lockForPidCached is set to true if there exists already a lock for + * lock.getClientPid(). Additionally, cachedLockForPidEqual" will be set to true, lock is equal to the + * lock active for this pid. + * + * + * @param lock + * The {@link Lock} the locks in the list of active locks should be compared with. + * + * @return A Tupel. + */ + protected Tupel checkLock(Lock lock) { + assert (lock.getClientUuid().equals(clientUuid)); + + boolean conflictFound = false; + boolean lockForPidCached = false; + boolean cachedLockForPidEqual = false; + + Lock conflictionLock = null; + + for (Entry entry : activeLocks.entrySet()) { + + if (entry.getKey() == lock.getClientPid()) { + lockForPidCached = true; + if (Helper.checkIfLocksAreEqual(lock, entry.getValue())) { + cachedLockForPidEqual = true; + } + continue; + } + + if (Helper.checkIfLocksDoConflict(lock, entry.getValue())) { + conflictFound = true; + conflictionLock = entry.getValue(); + // A conflicting lock has a higher priority than a cached lock with the same PID. + break; + } + } + + boolean[] bools = new boolean[] { conflictFound, lockForPidCached, cachedLockForPidEqual }; + return new Tupel(conflictionLock, bools); + } + + /** + * Returns true if a lock for "processId" is known. + */ + protected boolean checkIfProcessHasLocks(int processId) { + return activeLocks.containsKey(processId); + } + + /** + * Add a copy of "lock" to list of active locks. + */ + protected void putLock(Lock lock) { + assert (lock.getClientUuid().equals(clientUuid)); + + // Delete lock if it already exists. + activeLocks.remove(lock.getClientPid()); + + // Insert copy of lock. + Lock newLock = lock.toBuilder().build(); + activeLocks.put(newLock.getClientPid(), newLock); + } + + /** + * Remove locks equal to "lock" from list of active locks. + */ + protected void delLock(Lock lock) { + assert (lock.getClientUuid().equals(clientUuid)); + + // There is only up to one element per PID. Just find and delete it. + activeLocks.remove(lock.getClientPid()); + } + + /** + * Flushes pending async writes and file size updates. + */ + protected void flush(FileHandleImplementation fileHandle) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + flush(fileHandle, false); + } + + /** + * Same as Flush(), takes special actions if called by FileHandle.close(). + */ + protected void flush(FileHandleImplementation fileHandle, boolean closeFile) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + // We don't wait only for fileHandle's pending writes but for all writes of this file. + waitForPendingAsyncWrites(); + flushPendingFileSizeUpdate(fileHandle, closeFile); + } + + /** + * Flushes a pending file size update. + */ + protected void flushPendingFileSizeUpdate(FileHandleImplementation fileHandle) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + flushPendingFileSizeUpdate(fileHandle, false); + } + + /** + * Calls asyncWriteHandler.write(). + */ + void asyncWrite(AsyncWriteBuffer writeBuffer) throws XtreemFSException { + asyncWriteHandler.write(writeBuffer); + } + + /** + * Calls asyncWriteHandler.waitForPendingWrites() (resulting in blocking until all pending async writes + * are finished). + */ + protected void waitForPendingAsyncWrites() { + asyncWriteHandler.waitForPendingWrites(); + } + + /** + * Same as flushPendingFileSizeUpdate(), takes special actions if called by close(). + * + * @throws IOException + * @throws PosixErrorException + */ + private void flushPendingFileSizeUpdate(FileHandleImplementation fileHandle, boolean closeFile) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + // File size write back. + OSDWriteResponse responseCopy = null; + synchronized (osdWriteResponseLock) { + if (osdWriteResponse != null) { + waitForPendingFileSizeUpdates(); + if (osdWriteResponseStatus == FilesizeUpdateStatus.kDirty) { + osdWriteResponseStatus = FilesizeUpdateStatus.kDirtyAndSyncPending; + // Create a copy of OSDWriteResponse to pass to FileHandle. + responseCopy = osdWriteResponse.toBuilder().build(); + } else { + return; + } + } else { + return; + } + } + + try { + fileHandle.writeBackFileSize(responseCopy, closeFile); + } catch (IOException e) { + osdWriteResponseStatus = FilesizeUpdateStatus.kDirty; + throw e; + } + + synchronized (osdWriteResponseLock) { + // Only update the status if the response object has not changed meanwhile. + if (Helper.compareOSDWriteResponses(osdWriteResponse, responseCopy) == 0) { + osdWriteResponseStatus = FilesizeUpdateStatus.kClean; + } + + boolean replicateOnCloseValue = false; + synchronized (xLocSetLock) { + replicateOnCloseValue = this.replicateOnClose; + } + if (closeFile && replicateOnCloseValue) { + // Send an explicit close only if the on-close-replication should be + // triggered. Use an empty OSDWriteResponse object therefore. + fileHandle.writeBackFileSize(OSDWriteResponse.getDefaultInstance(), closeFile); + } + } + } + + /** + * Returns a new copy of xlocSet. + */ + protected XLocSet getXLocSet() { + synchronized (xLocSetLock) { + return xlocset.toBuilder().build(); + } + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/Helper.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/Helper.java new file mode 100644 index 0000000..e8e0382 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/Helper.java @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock; + +/** + * Some static Helper functions which are used internally by different classes. + */ +public class Helper { + + /** + * Generates a pseudorandom UUID with 32 chars length. + * + * @return String The pseudorandom UUID of length 32. + * + */ + // TODO: Ask michael why his uuid has length 36. oO + public static String generateVersion4UUID() { + // Base62 characters for UUID generation. + char set[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray(); + String uuid = ""; + + int block_length[] = { 8, 4, 4, 4, 12 }; + + Random generator = new Random(); + + for (int i = 0; i < block_length.length; i++) { + for (int j = 0; j < block_length[i]; j++) { + // choose a pseudorandom, uniformly distributed char from the + // array set and append it + // to the uuid. + uuid = uuid + set[generator.nextInt(62)]; + } + } + + assert (uuid.length() == 32); + + // TODO: Avoid this stupid new Helper() + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, new Helper(), "Generated client UUID: %s", + uuid); + } + return uuid; + } + + /** + * Converts a address in format "hostname:port" to a InetSocketAddress + * + * @param address + * String which represents the address in format "hostname:port". + * @param defaultPort + * Port that is used if address String is just a hostname. + */ + static protected InetSocketAddress stringToInetSocketAddress(String address, int defaultPort) { + InetSocketAddress isa; + int pos = 0; + + if ((pos = address.indexOf(':')) == -1) { + isa = new InetSocketAddress(address, defaultPort); + } else { + isa = new InetSocketAddress(address.substring(0, pos), Integer.parseInt(address + .substring(pos + 1))); + } + return isa; + } + + /** + * Returns the UUID of the OSD which stores the object with number "objectNo" of the replica "replica" + * + * @param replica + * @param objectNo + * @return + */ + static public String getOSDUUIDFromObjectNo(Replica replica, long objectNo) { + return replica.getOsdUuids((int) objectNo % replica.getStripingPolicy().getWidth()); + } + + static public String getOSDUUIDFromXlocSet(XLocSet xlocs, int replicaIndex, int stripeIndex) { + if (xlocs.getReplicasCount() == 0) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, xlocs, + "getOSDUUIDFromXlocSet: Empty replicas list in XlocSet: %s", xlocs.toString()); + return ""; + } + + Replica replica = xlocs.getReplicas(replicaIndex); + if (replica.getOsdUuidsCount() == 0) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, xlocs, + "GetOSDUUIDFromXlocSet: No head OSD available in XlocSet: %s", xlocs.toString()); + return ""; + } + + return replica.getOsdUuids(stripeIndex); + } + + static public String getOSDUUIDFromXlocSet(XLocSet xlocs) { + // Get the UUID for the first replica (r=0) and the head OSD (i.e. the + // first stripe, s=0). + return getOSDUUIDFromXlocSet(xlocs, 0, 0); + } + + /** + * Creates a list containing the UUIDs for the head OSD of every replica in the XLocSet. + */ + public static List getOSDUUIDsFromXlocSet(XLocSet xlocs) { + List uuids = new ArrayList(xlocs.getReplicasCount()); + + for (int i = 0; i < xlocs.getReplicasCount(); i++) { + uuids.add(xlocs.getReplicas(i).getOsdUuids(0)); + } + + return uuids; + } + + static public long extractFileIdFromXcap(XCap xcap) { + String fileId = xcap.getFileId(); + int start = fileId.indexOf(':'); + return Long.parseLong(fileId.substring(start + 1, fileId.length())); + } + + static public String extractGlobalFileIdFromXcap(XCap xcap) { + return xcap.getFileId(); + } + + static public String resolveParentDirectory(String path) { + path = setLeadingSlashIfMissing(path); + int lastSlash = path.lastIndexOf('/'); + if (path.equals("/") || lastSlash == 0) { + return "/"; + } else { + // We don't allow "path" to have a trailing "/" + assert (lastSlash != path.length() - 1); + return path.substring(0, lastSlash); + } + } + + private static String setLeadingSlashIfMissing(String path) { + if (!path.startsWith("/")) { + path = "/" + path; + } + return path; + } + + static protected long getNumObjects(UserCredentials userCredentials, Stat fileAttr, + StripingPolicy stripingPolicy) throws IOException, AddressToUUIDNotFoundException, + PosixErrorException { + long fileSize = fileAttr.getSize(); + + if (fileSize > 0) { + int stripeSize = stripingPolicy.getStripeSize() * 1024; + return ((fileSize - 1) / stripeSize) + 1; + } else + return 0; + } + + static public String getBasename(String path) { + path = setLeadingSlashIfMissing(path); + int lastSlash = path.lastIndexOf('/'); + if (path.equals("/")) { + return path; + } else { + // We don't allow path to have a trailing "/". + assert (lastSlash != path.length() - 1); + + return path.substring(lastSlash + 1); + } + } + + static public String concatenatePath(String directory, String file) { + directory = setLeadingSlashIfMissing(directory); + // handle ".." and "." + if (file.equals(".")) { + return directory; + } else { + if (file.equals("..")) { + ; + if (directory.equals("/")) { + return "/"; + } else { + return directory.substring(0, directory.lastIndexOf('/')); + } + } + } + + if (directory.endsWith("/")) { + return directory + file; + } else { + return directory + "/" + file; + } + } + + /** + * Compares newResponse with currentResponse. Returns 0 iff newResponse == currentResponse; 1 iff + * newResponse < currentResponse; -1 iff newResponse > currentResponse. + * + * @param newResponse + * + * @param currentResponse + * + * @return {1, 0, -1} + */ + static protected int compareOSDWriteResponses(OSDWriteResponse newResponse, + OSDWriteResponse currentResponse) { + if (newResponse == null && currentResponse == null) { + return 0; + } + + // newResponse > currentResponse + if (newResponse != null && currentResponse == null) { + return 1; + } + + // newResponse < currentResponse + if (newResponse == null && currentResponse != null) { + return -1; + } + + // newResponse > currentResponse + if (newResponse.getTruncateEpoch() > currentResponse.getTruncateEpoch() + || (newResponse.getTruncateEpoch() == currentResponse.getTruncateEpoch() && newResponse + .getSizeInBytes() > currentResponse.getSizeInBytes())) { + return 1; + } + + // newResponse < currentResponse + if (newResponse.getTruncateEpoch() < currentResponse.getTruncateEpoch() + || (newResponse.getTruncateEpoch() == currentResponse.getTruncateEpoch() && newResponse + .getSizeInBytes() < currentResponse.getSizeInBytes())) { + return -1; + } + + // newResponse == currentResponse + return 0; + + } + + /** + * Compares "lock1 "with "lock2". Returns true if lock1 equals lock2. false otherwise. They are equal iff + * clientUuid, clientPid, offset and length are equal. + * + * @param lock1 + * @param lock2 + * @return true iff lock1 equals lock2 + */ + protected static boolean checkIfLocksAreEqual(Lock lock1, Lock lock2) { + return lock1.getClientUuid().equals(lock2.getClientUuid()) + && lock1.getClientPid() == lock2.getClientPid() && lock1.getOffset() == lock2.getOffset() + && lock1.getLength() == lock2.getLength(); + } + + protected static boolean checkIfLocksDoConflict(Lock lock1, Lock lock2) { + // 0 means to lock till the end of the file. + long lock1End = lock1.getLength() == 0 ? 0 : lock1.getLength() + lock1.getOffset(); + long lock2End = lock2.getLength() == 0 ? 0 : lock2.getLength() + lock2.getOffset(); + + // Check for overlaps + if (lock1End == 0) { + if (lock2End >= lock1.getOffset() || lock2End == 0) { + return true; + } + } + + if (lock2End == 0) { + if (lock1End >= lock2.getOffset() || lock1End == 0) { + return true; + } + } + + // Overlapping? + if (!(lock1End < lock2.getOffset() || lock2End < lock1.getOffset())) { + // Does overlap! Check for conflicting modes. + return (lock1.getExclusive() || lock2.getExclusive()); + } + + return false; + } + + public static String policiesToString(OSDSelectionPolicyType[] policies) { + StringBuffer policiesSB = new StringBuffer(); + boolean firstEntry = true; + for (OSDSelectionPolicyType policy : policies) { + if (firstEntry) { + firstEntry = false; + } else { + policiesSB.append(","); + } + + policiesSB.append(String.valueOf(policy.getNumber())); + } + + return policiesSB.toString(); + } + + /** + * Convert the given flags to their corresponding bit patterns and combine them by an or. + * + * @param flags + * Variable number of SYSTEM_V_FCNTL flags + * @return bit pattern as an integer of the or'ed flags + */ + public static int flagsToInt(SYSTEM_V_FCNTL... flags) { + int flagsInt = 0; + + for (SYSTEM_V_FCNTL flag: flags) { + flagsInt = flagsInt | flag.getNumber(); + } + + return flagsInt; + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/MetadataCache.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/MetadataCache.java new file mode 100644 index 0000000..f44e4de --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/MetadataCache.java @@ -0,0 +1,1074 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Setattrs; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse; + +/** + * Caches metadata for libxtreemfs. + */ +public class MetadataCache { + + private final long maxNumberOfEntries; + + private final long ttlS; + + private boolean enabled; + + /** + * A map containing all {@link MetadataCacheEntry} in insertion order. Also it is possible to access an + * entry in a hashmap like way in time O(1). + */ + private final LinkedHashMap cache; + + /** + * A map sorted by the path. This is used to iterate recursively over a path when a directory is + * invalidated to delete all subdirectories and files belonging to the invalidated directory from the + * cache. + */ + private final SortedSet pathIndex; + + private final ReadWriteLock readWriteLock; + + /** + * Lock that is used when writing to the "pathIndex" and "cache" together. + */ + private final Lock writeLock; + + /** + * Lock that is used when reading "pathIndex" and "cache" together. + */ + private final Lock readLock; + + /** + * MetadataCache for Stat, listxattrResponse and XAttr objects per path. + * + */ + protected MetadataCache(long maxNumberOfEntries, long ttlS) { + this.maxNumberOfEntries = maxNumberOfEntries; + this.ttlS = ttlS; + + enabled = maxNumberOfEntries > 0 ? true : false; + + cache = new LinkedHashMap(); + pathIndex = new TreeSet(); + + readWriteLock = new ReentrantReadWriteLock(); + writeLock = readWriteLock.writeLock(); + readLock = readWriteLock.readLock(); + } + + /** + * Removes MetadataCacheEntry for path from cache + * + * @param path + * The path for the entry which should be invalidated. + */ + protected void invalidate(String path) { + if (path.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + cache.remove(path); + pathIndex.remove(path); + } finally { + writeLock.unlock(); + } + } + + /** + * Removes MetadataCacheEntry for path and any objects matching path+"/". + * + * @param path + * Path which should be invalidated. + */ + protected void invalidatePrefix(String path) { + if (path.isEmpty() || !enabled) { + return; + } + // collect all entries that should be removed from pathIndex to remove them at the end. + List indicesToRemove = new ArrayList(); + + writeLock.lock(); + try { + // At first, delete "path" from "cache" and "pathIndex" + cache.remove(path); + pathIndex.remove(path); + + // At second, remove all entries which have "path" respectively "path+'/'" + if (!path.endsWith("/")) { + path = path + "/"; + } + + for (String deletePath : pathIndex.tailSet(path)) { + // if the we reach the first element which don't have "path" as + // prefix we are finished. + if (!deletePath.startsWith(path)) { + break; + } + + // else delete this element from "pathIndex"and "cache" + cache.remove(deletePath); + indicesToRemove.add(deletePath); + } + // do the removing after looping over "pathIndex" to avoid ConcurrentModificationException + pathIndex.removeAll(indicesToRemove); + } finally { + writeLock.unlock(); + } + } + + /** + * Renames "path" to "newPath" and any object's path matching path+"/". + * + * @param path + * Path which should be renamed to "newPath". + * @param newPath + * New name of "path". + */ + protected void renamePrefix(String path, String newPath) { + if (path.isEmpty() || !enabled) { + return; + } + // Temporary TreeSet to store the new paths + TreeSet tempPaths = new TreeSet(); + + writeLock.lock(); + try { + // At first, rename the directory itself. + MetadataCacheEntry entry = cache.remove(path); + cache.put(newPath, entry); + + // Seconde, rename all entries with prefix that matches "path" respectively "path+'/'" + if (!path.endsWith("/")) + path = path + "/"; + if (!newPath.endsWith("/")) + newPath = newPath + "/"; + + for (String renamePath : pathIndex.tailSet(path)) { + // if the we reach the first element which don't have "path" as + // prefix we are finished. + if (!renamePath.startsWith(path)) { + break; + } + + // delete object from cache and insert it with new path + entry = cache.remove(renamePath); + cache.put(renamePath.replaceFirst(path, newPath), entry); + + // add the oldPath to the "tempPaths" in order to remove them later from "pathIndex" + // and add them with the new path + tempPaths.add(renamePath.replaceFirst(path, newPath)); + } + + // remove all collected tempPaths to the "pathIndex" and readd them with the correct new + // path + for (String tmpPath : tempPaths) { + pathIndex.remove(tmpPath); + pathIndex.add(tmpPath.replace(path, newPath)); + } + } finally { + writeLock.unlock(); + } + } + + /** + * Returns the Stat object if its exists. null otherwise. + * + * @param path + * Path of the cached object. + * @return {@link Stat} object or null. + */ + protected Stat getStat(String path) { + if (path.isEmpty() || !enabled) { + return null; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + if (entry != null) { // cache hit + // We must never have cached a hard link. + assert (entry.getStat() == null || entry.getStat().getNlink() == 1); + + long currentTimeS = System.currentTimeMillis() / 1000; + if (entry.getStatTimeoutS() >= currentTimeS) { // Stat object is still valid + return entry.getStat(); + } else { // Stat object is expired => delete it from cache + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getStat expired: %s", path); + } + + // Only delete object, if the maximum timeout of all three objects is + // reached. + if (entry.getTimeoutS() < currentTimeS) { + // Free MetadataCacheEntry and delete from Index. This increases the + // run time of GetStat() roughly by factor 3. + cache.remove(path); + pathIndex.remove(path); + } + } + } else { // cache miss + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getStat miss: ", cache.size()); + } + } + } finally { + writeLock.unlock(); + } + return null; + } + + /** + * Stores/updates stat in cache for path. + * + * @param path + * Path related to the {@link Stat} object. + * @param stat + * The {@link Stat} object which should be cached under "path". + */ + protected void updateStat(String path, Stat stat) { + if (path.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + // remove entry if it exists in the cache + MetadataCacheEntry entry = cache.remove(path); + if (entry == null) { // cache miss. entry has to be created + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache: registering %s", path); + } + entry = new MetadataCacheEntry(); + + // entry doesn't exists yet in cache => there is no entry "pathIndex" for it. We + // have to create one. + pathIndex.add(path); + } + + // set net stat object and update timeouts + entry.setStat(stat); + entry.setStatTimeoutS(System.currentTimeMillis() / 1000 + ttlS); + entry.setTimeoutS(entry.getStatTimeoutS()); + + // (re-)add entry to "cache" + evictUnmutexed(1); + cache.put(path, entry); + + } finally { + writeLock.unlock(); + } + } + + /** + * Updates timestamp of the cached stat object. + * + * @param path + * Path of the cached object. + * @param timestampS + * timestamp in seconds which should be set + * @param toSet + * int value of attributes that should be set as defined in {@link Setattrs}. Possible values: + * SETATTR_ATIME, SETATTR_MTIME, SETATTR_CTIME + * + * + */ + protected void updateStatTime(String path, long timestampS, int toSet) { + if (path.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + + if (entry != null) { + if (entry.getStat() == null) { + return; + } + + // build new Stat object and update (a,c,m)time value if toSet says so. + Stat.Builder newStat = entry.getStat().toBuilder(); + long timeNS = timestampS * 1000000000; + + if ((toSet & Setattrs.SETATTR_ATIME.getNumber()) > 0 + && (timeNS > entry.getStat().getAtimeNs())) { + newStat.setAtimeNs(timeNS); + } + if ((toSet & Setattrs.SETATTR_MTIME.getNumber()) > 0 + && (timeNS > entry.getStat().getMtimeNs())) { + newStat.setMtimeNs(timeNS); + } + if ((toSet & Setattrs.SETATTR_CTIME.getNumber()) > 0 + && (timeNS > entry.getStat().getCtimeNs())) { + newStat.setCtimeNs(timeNS); + } + + // set new Stat object and update timeouts + entry.setStat(newStat.build()); + entry.setStatTimeoutS(System.currentTimeMillis() / 1000 + ttlS); + entry.setTimeoutS(entry.getStatTimeoutS()); + + // readd the entry in the cache + cache.remove(path); + cache.put(path, entry); + } + } finally { + writeLock.unlock(); + } + } + + /** + * Updates the attributes given in "stat" and selected by "toSet". + * + * @param path + * Path of the cached object. + * @param stat + * The {@link Stat} object cotaining the new values. + * @param toSet + * Bitmap describing which values should be updated. See {@link Setattrs}. + */ + protected void updateStatAttributes(String path, Stat stat, int toSet) { + if (path.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + + if (entry != null) { + if (entry.getStat() == null) { + return; + } + + // Update Stat object regarding to "toSet" and "stat" + Stat.Builder statBuilder = entry.getStat().toBuilder(); + + if ((toSet & Setattrs.SETATTR_ATTRIBUTES.getNumber()) > 0) { + statBuilder.setAttributes(stat.getAttributes()); + } + + if ((toSet & Setattrs.SETATTR_MODE.getNumber()) > 0) { + // Modify only the last 12 Bits (3 bits for sticky bit, set GID and + // set UID and 3 * 3 bits for the file access mode). + statBuilder.setMode((statBuilder.getMode() & 0xFFFFF000) | (stat.getMode() & 0x00000FFF)); + } + + if ((toSet & Setattrs.SETATTR_UID.getNumber()) > 0) { + statBuilder.setUserId(stat.getUserId()); + } + + if ((toSet & Setattrs.SETATTR_GID.getNumber()) > 0) { + statBuilder.setGroupId(stat.getGroupId()); + } + + if ((toSet & Setattrs.SETATTR_SIZE.getNumber()) > 0) { + + if (stat.hasTruncateEpoch() && stat.getTruncateEpoch() > statBuilder.getTruncateEpoch()) { + statBuilder.setSize(stat.getSize()); + statBuilder.setTruncateEpoch(stat.getTruncateEpoch()); + } else { + if (stat.hasTruncateEpoch() + && stat.getTruncateEpoch() == statBuilder.getTruncateEpoch() + && stat.getSize() > statBuilder.getSize()) { + statBuilder.setSize(stat.getSize()); + } + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache UpdateStatAttributes SETATTR_SIZE: new size: %s " + + "truncate epoch: %s", statBuilder.getSize(), + statBuilder.getTruncateEpoch()); + } + } + + if ((toSet & Setattrs.SETATTR_ATIME.getNumber()) > 0) { + statBuilder.setAtimeNs(stat.getAtimeNs()); + } + + if ((toSet & Setattrs.SETATTR_MTIME.getNumber()) > 0) { + statBuilder.setMtimeNs(stat.getMtimeNs()); + } + + if ((toSet & Setattrs.SETATTR_CTIME.getNumber()) > 0) { + statBuilder.setCtimeNs(stat.getCtimeNs()); + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache UpdateStatAttributes: %s toSet: %s", path, toSet); + } + + // update stat, timeouts and then re-add "entry" to the cache + entry.setStat(statBuilder.build()); + entry.setStatTimeoutS(System.currentTimeMillis() / 1000 + ttlS); + entry.setTimeoutS(entry.getStatTimeoutS()); + + cache.remove(path); + cache.put(path, entry); + } + } finally { + writeLock.unlock(); + } + } + + /** + * Updates file size and truncate epoch from an OSDWriteResponse. + * + * @param path + * Path of the cached object. + * @param response + * {@link OSDWriteResponse} with new file size and truncate epoch. + */ + protected void updateStatFromOSDWriteResponse(String path, OSDWriteResponse response) { + if (path.isEmpty() || !enabled || !response.hasSizeInBytes() || !response.hasTruncateEpoch()) { + return; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + if (entry != null) { + if (entry.getStat() == null) { + return; + } + + Stat.Builder statBuilder = entry.getStat().toBuilder(); + if (response.getTruncateEpoch() > statBuilder.getTruncateEpoch() + || (response.getTruncateEpoch() == statBuilder.getTruncateEpoch() // + && response.getSizeInBytes() > statBuilder.getSize())) { + + statBuilder.setSize(response.getSizeInBytes()); + statBuilder.setTruncateEpoch(response.getTruncateEpoch()); + entry.setStat(statBuilder.build()); + } + } + } finally { + writeLock.unlock(); + } + } + + /** + * Returns a {@link DirectoryEntries} object (if it's found for "path") limited to entries starting from + * "offset" up to "count" (or the maximum)S. + * + * @param path + * Path of the cache object. + * @param offset + * Index where to begin with retrieving DiretoryEntries. + * @param count + * Number of entries which should be return. + * @return {@link DirectoryEntries} + */ + protected DirectoryEntries getDirEntries(String path, int offset, int count) { + if (path.isEmpty() || !enabled) { + return null; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + if (entry != null && entry.getDirectoryEntries() != null) { + long currentTimeS = System.currentTimeMillis() / 1000; + if (entry.getDirectoryEntriesTimeoutS() >= currentTimeS) { // entry is valid => use it + + DirectoryEntries.Builder result; + + // copy all entries from cache + if (offset == 0 && count >= entry.getDirectoryEntries().getEntriesCount()) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getDirEntries() hit: %s [%s]", path, cache.size()); + } + result = entry.getDirectoryEntries().toBuilder(); + } else { // copy just the selected entries from cache + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getDirectoryEntries() hit (partial copy): " + + "%s [%s] offset: %s", path, cache.size(), offset); + } + result = DirectoryEntries.newBuilder(); + for (int i = offset; i < offset + count; i++) { + result.addEntries(entry.getDirectoryEntries().getEntries(i)); + } + } + return result.build(); + } else { // Expired! => remove from cache + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache entry expired: %s", path); + } + + // Only delete object, if the maximum timeout is reached. + if (entry.getTimeoutS() < currentTimeS) { + cache.remove(path); + pathIndex.remove(path); + } + return null; + } + } + } finally { + writeLock.unlock(); + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getDirectoryEntries() miss: %s", path); + } + return null; + } + + /** + * Invalidates the stat entry stored for "path". + * + * @param path + * Path of the cache object. + */ + protected void invalidateStat(String path) { + if (path.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + if (entry != null) { + entry.setStat(null); + entry.setStatTimeoutS(0); + } + } finally { + writeLock.unlock(); + } + } + + /** + * Stores/updates DirectoryEntries in cache for path. + * + * @param path + * Path where the object should be stored. + * @param dirEntries + * {@link DirectoryEntries} object which should be cached. + * + * @note This implementation assumes that "dirEntries" is always complete, i.e. it must be guaranteed that + * it contains all entries. + */ + protected void updateDirEntries(String path, DirectoryEntries dirEntries) { + if (path.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + boolean created = false; + + if (entry == null) { // entry does not exist, create new one + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache updateDirEntries(): new entry for path %s", path); + } + entry = new MetadataCacheEntry(); + entry.setPath(path); + created = true; + } + + entry.setDirectoryEntries(dirEntries); + entry.setDirectoryEntriesTimeoutS(System.currentTimeMillis() / 1000 + ttlS); + entry.setTimeoutS(entry.getDirectoryEntriesTimeoutS()); + + if (created) { + evictUnmutexed(1); + pathIndex.add(path); + cache.put(path, entry); + } else { + cache.remove(path); + cache.put(path, entry); + } + } finally { + writeLock.unlock(); + } + } + + /** + * Removes "entryName" from the cached directory "pathToDirectory". + * + * @param pathToDirectory + * Path of the cached directory. + * @param entryName + * Name from the entry that should be removed from the cache {@link DirectoryEntries}. + */ + protected void invalidateDirEntry(String pathToDirectory, String entryName) { + if (pathToDirectory.isEmpty() || entryName.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(pathToDirectory); + if (entry != null) { + if (entry.getDirectoryEntries() == null) { + return; + } + + DirectoryEntries.Builder dirEntriesBuilder = DirectoryEntries.newBuilder(); + + // Copy DirectoryEntries to "dirEntriesBuilder" except entries with "entryName". + for (int i = 0; i < entry.getDirectoryEntries().getEntriesCount(); i++) { + if (!entry.getDirectoryEntries().getEntries(i).getName().equals(entryName)) { + dirEntriesBuilder.addEntries(entry.getDirectoryEntries().getEntries(i)); + } + } + entry.setDirectoryEntries(dirEntriesBuilder.build()); + } + + } finally { + writeLock.unlock(); + } + } + + /** + * Remove cached DirectoryEntries in cache for path. + * + * @param path + * Path of the cached object. + */ + protected void invalidateDirEntries(String path) { + if (path.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + if (entry != null) { + entry.setDirectoryEntries(null); + entry.setDirectoryEntriesTimeoutS(0); + } + } finally { + writeLock.unlock(); + } + } + + /** + * Returns a {@link Tupel} with and Xattr and a boolean value. Xattr may be null if it is not found. The + * boolean value determines if the Xattrs where cached. (Xattrs can be cached but the Xattr "name" can not + * be in Xattrs) + * + * + * @param path + * Path of the cached object. + * @param name + * Name of the {@link XAttr}. + * + * @return {@link Tupel} with Xattr value or null as first value and boolean as second. + */ + protected Tupel getXAttr(String path, String name) { + boolean xattrsCached = false; + + if (path.isEmpty() || !enabled) { + return new Tupel(null, xattrsCached); + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + long currentTimeMS = System.currentTimeMillis() / 1000; + + if (entry != null && entry.getXattrs() != null) { + // Entry found with valid Xattrs. Check timeout Xattrs + if (entry.getXattrTimeoutS() >= currentTimeMS) { + xattrsCached = true; + + for (XAttr xattr : entry.getXattrs().getXattrsList()) { + if (xattr.getName().equals(name)) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getXattr() hit: %s [%s]", path, cache.size()); + } + return new Tupel(xattr.getValue(), xattrsCached); + } + } + // the Xattr "name" was not found; + return new Tupel(null, xattrsCached); + } else { // Cache entry is expired => remove from cache. + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getXattr() expired: %s", path); + } + // Only delete object if maximum timeout is reached. + if (entry.getTimeoutS() < currentTimeMS) { + cache.remove(path); + pathIndex.remove(path); + } + return new Tupel(null, xattrsCached); + } + } + + } finally { + writeLock.unlock(); + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getXattr() miss: %s [%s]", path, cache.size()); + } + return new Tupel(null, xattrsCached); + } + + /** + * Returns a Tupel the size of a value (string length) of an XAttribute "name" cached for "path" if it + * exists and is still valid as first item. 0 otherwhise. And true as second item if the Xattrs where + * cached for path. + * + * + * @param path + * Path of the cached object. + * @param name + * Name of the {@link XAttr}. + * + * @return A {@link Tupel} with size of the value of the Xattr or 0 as first and Boolean as second item. + */ + protected Tupel getXAttrSize(String path, String name) { + boolean xattrCached = false; + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + long currentTimeS = System.currentTimeMillis() / 1000; + + if (entry != null && entry.getXattrs() != null) { + if (entry.getXattrTimeoutS() >= currentTimeS) { // entry is still valid + xattrCached = true; + for (XAttr xattr : entry.getXattrs().getXattrsList()) { + if (xattr.getName().equals(name)) { + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getXattrSize() hit: %s [%s]", path, cache.size()); + } + return new Tupel(xattr.getValue().length(), xattrCached); + } + } + + } else { // cache entry is expired => remove from cache + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getXattrSize() expired: %s", path); + } + + // only delete entry when overall timeout is expired + if (entry.getTimeoutS() < currentTimeS) { + cache.remove(path); + pathIndex.remove(path); + } + } + } + + } finally { + writeLock.unlock(); + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getXattrSize() miss: %s [%s]", path, cache.size()); + } + return new Tupel(0, xattrCached); + } + + /** + * Get all extended attributes cached for "path". Return null if not cached Xattrs exists for that path. + * + * @param path + * Path of the cached object. + * @return {@link listxattrResponse} or null. + */ + protected listxattrResponse getXAttrs(String path) { + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + long currentTimeS = System.currentTimeMillis() / 1000; + + if (entry != null && entry.getXattrs() != null) { + if (entry.getXattrTimeoutS() >= currentTimeS) { // cache entry is still valid; hit + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getXattrs() hit: %s [%s]", path, cache.size()); + } + return entry.getXattrs(); + + } else { // entry is expired => remove it + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getXattrs() expired: %s", path, cache.size()); + } + + // only delete object when overall timeout is expired + if (entry.getTimeoutS() < currentTimeS) { + cache.remove(path); + pathIndex.remove(path); + } + return null; + } + } + } finally { + writeLock.unlock(); + } + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache getXattrs() miss %s [%s]", path, cache.size()); + } + return null; + } + + /** + * Updates the "value" for the attribute "name" of "path" if the list of attributes for "path" is already + * cached. + * + * @param path + * Path of the cached object. + * @param name + * Name of the {@link XAttr}. + * @param value + * New value that should be set. + */ + protected void updateXAttr(String path, String name, String value) { + if (path.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + // check if there is already an entry for "path" + MetadataCacheEntry entry = cache.get(path); + if (entry == null) { + // Don't create a new entry with an incomplete xattr list. + return; + } + + if (entry.getXattrs() == null) { + // Don't create a new xattr list for an existing cache entry. + return; + } + + long currentTimeS = System.currentTimeMillis() / 1000; + if (entry.getXattrTimeoutS() < currentTimeS) { + // Don't update expired xattrs. + return; + } + + listxattrResponse.Builder newXattrs = entry.getXattrs().toBuilder(); + boolean nameFound = false; + for (int i = 0; i < newXattrs.getXattrsList().size(); i++) { + + // if Xattr with "name" found, update it, set "nameFound" to true und stop the loop + if (newXattrs.getXattrs(i).getName().equals(name)) { + nameFound = true; + XAttr.Builder xattr = newXattrs.getXattrs(i).toBuilder(); + xattr.setValue(value); + newXattrs.setXattrs(i, xattr.build()); + break; + } + + } + // if Xattr with "name" don't exists, add it to teh Xattr list. + if (!nameFound) { + newXattrs.addXattrs(XAttr.newBuilder().setName(name).setValue(value).build()); + } + + // Replace the existing entry in cache - do not update TTL + entry.setXattrs(newXattrs.build()); + } finally { + writeLock.unlock(); + } + } + + /** + * Stores/updates XAttrs in cache for path. + * + * @note This implementation assumes that the list of extended attributes is always complete. + * + * @param path + * Path of the cached object. + * @param xattrs + * New {@link listxattrResponse} that should be cached. + */ + protected void updateXAttrs(String path, listxattrResponse xattrs) { + if (path.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + // create a new entry if there isn't one in cache + if (entry == null) { + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache updateXattrs: new entry for path %s", path); + } + entry = new MetadataCacheEntry(); + entry.setPath(path); + } + + entry.setXattrs(xattrs); + entry.setXattrTimeoutS(System.currentTimeMillis() / 1000 + ttlS); + entry.setTimeoutS(entry.getXattrTimeoutS()); + + // we have to remove and readd the entry. If it was not in cache we are dealing with a + // new entry and we have to insert in "pathIndex" too + if (cache.remove(path) == null) { + pathIndex.add(path); + } + cache.put(path, entry); + } finally { + writeLock.unlock(); + } + } + + /** + * Removes "name" from the list of extended attributes cached for "path". + * + * @param path + * Path of the cached object. + * @param name + * Name of the {@link XAttr} that should be removed from cached Xattrs. + */ + protected void invalidateXAttr(String path, String name) { + if (path.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + if (entry == null) { + // there is no entry in the cache => nothing to do + return; + } + + if (entry.getXattrs() == null) { + // don't create a new incomplete Xattr list. + return; + } + + long currentTimeS = System.currentTimeMillis() / 1000; + if (entry.getXattrTimeoutS() < currentTimeS) { + // Don't alter expired Xattr. + return; + } + + // Copy old Xattr without entry "name" + listxattrResponse.Builder xattrs = listxattrResponse.newBuilder(); + for (XAttr xattr : entry.getXattrs().getXattrsList()) { + if (!xattr.getName().equals(name)) { + xattrs.addXattrs(xattr); + } + } + + entry.setXattrs(xattrs.build()); + + } finally { + writeLock.unlock(); + } + } + + /** + * Remove cached XAttrs in cache for path. + * + * @param path + * Path of the cached object. + */ + protected void invalidateXAttrs(String path) { + if (path.isEmpty() || !enabled) { + return; + } + + writeLock.lock(); + try { + MetadataCacheEntry entry = cache.get(path); + if (entry != null) { + entry.setXattrs(null); + entry.setXattrTimeoutS(0); + } + + } finally { + writeLock.unlock(); + } + } + + /** + * Returns the current number of elements. + * + * @return long + */ + protected long size() { + readLock.lock(); + try { + return cache.size(); + } finally { + readLock.unlock(); + } + } + + /** + * Returns the maximum number of elements. + * + * @return long + */ + protected long capacity() { + return maxNumberOfEntries; + } + + /** + * Evicts first n oldest entries from cache. + * + * @param n + * Number of elements that should be evicted. + */ + private void evictUnmutexed(int n) { + while (cache.size() > maxNumberOfEntries - n) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "MetadataCache evictUnmutexed: Deleting one entry from cache; " + + "entries in total: %s", cache.size()); + } + // get first element of keys of the LinkedHashMap "cache". + String path = cache.keySet().iterator().next(); + cache.remove(path); + pathIndex.remove(path); + } + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/MetadataCacheEntry.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/MetadataCacheEntry.java new file mode 100644 index 0000000..3719b20 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/MetadataCacheEntry.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse; + + +/** + * + * Represents an entry in the metadatacache. + */ +public class MetadataCacheEntry { + + private long statTimeoutS; + + private long dirEntriesTimeoutS; + + private long xattrTimeoutS; + + private long timeoutS; + + private Stat stat; + + private DirectoryEntries dirEntries; + + private String path; + + private listxattrResponse xattrs; + + + protected Stat getStat() { + return stat; + } + + protected long getStatTimeoutS() { + return statTimeoutS; + } + + protected void setStatTimeoutS(long timeout) { + this.statTimeoutS = timeout; + } + + protected long getTimeoutS() { + return timeoutS; + } + + protected void setTimeoutS(long timeout) { + this.timeoutS = timeout; + } + + protected void setStat(Stat stat) { + this.stat = stat; + } + + protected DirectoryEntries getDirectoryEntries() { + return dirEntries; + } + + protected void setDirectoryEntries(DirectoryEntries dirEntries) { + this.dirEntries = dirEntries; + } + + protected long getDirectoryEntriesTimeoutS() { + return dirEntriesTimeoutS; + } + + protected void setDirectoryEntriesTimeoutS(long timeout) { + this.dirEntriesTimeoutS = timeout; + } + + protected void setPath(String path) { + this.path = path; + } + + protected String getPath() { + return path; + } + + protected listxattrResponse getXattrs() { + return xattrs; + } + + protected void setXattrs(listxattrResponse xattrs) { + this.xattrs = xattrs; + } + + protected long getXattrTimeoutS() { + return xattrTimeoutS; + } + + protected void setXattrTimeoutS(long timeout) { + this.xattrTimeoutS = timeout; + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/Options.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/Options.java new file mode 100644 index 0000000..520a17f --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/Options.java @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.VersionManagement; + +/** + * Represents all possible options for libxtreemfs. + */ +public class Options { + + enum XtreemFSServiceType { + kDIR, kMRC + }; + + // Optimizations. + /** + * Maximum number of entries of the StatCache. Default: 100000 + */ + private int metadataCacheSize = 100000; + + /** + * Time to live for MetadataCache entries. Default: 120 + */ + private final long metadataCacheTTLs = 120; + + /** + * Maximum number of pending bytes (of async writes) per file. TODO: Reenable async writes when retry + * support is completed. + */ + private int maxWriteahead = 0; + + /** + * Maximum number of pending async write requests per file. Default: 10 + */ + private final int maxWriteaheadRequests = 10; + + /** + * Number of retrieved entries per readdir request. Default: 1024 + */ + private int readdirChunkSize = 1024; + + // Error Handling options. + /** + * How often shall a failed operation get retried? Default: 40 + */ + private int maxTries = 40; + /** + * How often shall a failed read operation get retried? Default: 40 + */ + private int maxReadTries = 40; + /** + * How often shall a failed write operation get retried? Default: 40 + */ + private final int maxWriteTries = 40; + /** + * How often shall a view be tried to renewed? + */ + private int maxViewRenewals = 5; + /** + * How long to wait after a failed request? Default: 15 + */ + private final int retryDelay_s = 15; + + /** + * Stops retrying to execute a synchronous request if this signal was send to the thread responsible for + * the execution of the request. Default: 0 + */ + private final int interruptSignal = 0; + + /** + * Maximum time until a connection attempt will be aborted. Default: 60 + */ + private final int connectTimeout_s = 60; + /** + * Maximum time until a request will be aborted and the response returned. Default: + */ + private final int requestTimeout_s = 30; + + /** + * The RPC Client closes connections after "linger_timeout_s" time of inactivity. Default: 600 + */ + private final int lingerTimeout_s = 600; + + public int getMetadataCacheSize() { + return metadataCacheSize; + } + + public void setMetadataCacheSize(int metadataCacheSize) { + this.metadataCacheSize = metadataCacheSize; + } + + public long getMetadataCacheTTLs() { + return metadataCacheTTLs; + } + + public int getInterruptSignal() { + return interruptSignal; + } + + public int getConnectTimeout_s() { + return connectTimeout_s; + } + + public int getRequestTimeout_s() { + return requestTimeout_s; + } + + public int getLingerTimeout_s() { + return lingerTimeout_s; + } + + // SSL options. + private final String sslPemCertPath = ""; + private final String sslPemPath = ""; + private final String sslPemKeyPass = ""; + private final String sslPKCS2Path = ""; + private final String sslPKCS12Pass = ""; + + // Grid Support options. + /** + * True, if the XtreemFS Grid-SSL Mode (only SSL handshake, no encryption of data itself) shall be used. + * Default: false + */ + private final boolean gridSSL = false; + /** + * True if the Globus user mapping shall be used. Default: false + * */ + private final boolean gridAuthModeGlobus = false; + /** + * True if the Unicore user mapping shall be used. Default: false + * */ + private final boolean gridAuthModeUnicore = false; + /** + * Location of the gridmap file. Default: "" + */ + private final String gridGridmapLocation = ""; + /** + * Default Location of the Globus gridmap file. Default: "/etc/grid-security/grid-mapfile" + */ + private final String gridGridmapLocationDefaultGlobus = "/etc/grid-security/grid-mapfile"; + /** + * Default Location of the Unicore gridmap file. Default: "/etc/grid-security/d-grid_uudb" + */ + private final String gridGridmapLocationDefaultUnicore = "/etc/grid-security/d-grid_uudb"; + /** + * Periodic interval after which the gridmap file will be reloaded. Default: 60 + */ + private final int gridGridmapReloadInterval_m = 60; // 60 minutes = 1 + // hour + + // Advanced XtreemFS options + /** + * Interval for periodic file size updates in seconds. Default: 60 + */ + private int periodicFileSizeUpdatesIntervalS = 60; + + /** + * Interval for periodic xcap renewal in seconds. Default: 60 + */ + private final int periodicXcapRenewalIntervalS = 60; + + protected int getPeriodicXcapRenewalIntervalS() { + return periodicXcapRenewalIntervalS; + } + + protected int getPeriodicFileSizeUpdatesIntervalS() { + return periodicFileSizeUpdatesIntervalS; + } + + /** + * Returns the version string and prepends "component". + */ + String showVersion(String component) { + return component + VersionManagement.RELEASE_VERSION; + } + + /** + * Return the version. + * + */ + String getVersion() { + return VersionManagement.RELEASE_VERSION; + } + + /** + * Creates a new SSLOptions object based on the value of the members: - sslPem_path - sslPemCertPath - + * sslPemKeyPass - sslPkcs12Path - sslPkcs12Pass - gridSsl || protocol. + * + */ + public SSLOptions generateSSLOptions() { + SSLOptions sslOptions = null; + if (sslEnabled()) { + // TODO: Find out how to create SSLOptions object. + // sslOptions = new SSLOptions(new FileInputStream(new File(sslPemPath)), + // sslPemKeyPass, sslPemCertPath, + // new FileInputStream(new File(sslPKCS2Path)), + // sslPKCS12Pass, new String(), gridSSL || protocol == Schemes.SCHEME_PBRPCG ); + } + return null; + } + + /** Extract volume name and dir service address from dir_volume_url. */ + protected void parseURL(XtreemFSServiceType service_type) { + // TODO: Implement! + } + + public boolean sslEnabled() { + return !sslPemCertPath.isEmpty() || !sslPKCS2Path.isEmpty(); + } + + public int getMaxTries() { + return maxTries; + } + + public void setMaxTries(int maxTries) { + this.maxTries = maxTries; + } + + protected int getMaxWriteTries() { + return maxWriteTries; + } + + public int getMaxViewRenewals() { + return maxViewRenewals; + } + + public void setMaxViewRenewals(int maxViewRenewals) { + this.maxViewRenewals = maxViewRenewals; + } + + public int getRetryDelay_s() { + return retryDelay_s; + } + + public int getMaxWriteahead() { + return maxWriteahead; + } + + protected int getMaxWriteaheadRequests() { + return maxWriteaheadRequests; + } + + public int getReaddirChunkSize() { + return readdirChunkSize; + } + + public void setReaddirChunkSize(int readdirChunkSize) { + this.readdirChunkSize = readdirChunkSize; + } + + public void setPeriodicFileSizeUpdatesIntervalS(int periodicFileSizeUpdatesIntervalS) { + this.periodicFileSizeUpdatesIntervalS = periodicFileSizeUpdatesIntervalS; + } + + public void setMaxWriteAhead(int maxWriteAhead) { + this.maxWriteahead = maxWriteAhead; + } + + public void setMaxReadTries(int maxReadTries) { + this.maxReadTries = maxReadTries; + } + + public int getMaxReadTries() { + return maxReadTries; + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/PeriodicFileSizeUpdateThread.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/PeriodicFileSizeUpdateThread.java new file mode 100644 index 0000000..1904971 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/PeriodicFileSizeUpdateThread.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; +import java.util.Map.Entry; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * Updates periodically the fileSize at the MRC. + */ +public class PeriodicFileSizeUpdateThread extends Thread { + + private VolumeImplementation volume = null; + + public PeriodicFileSizeUpdateThread(VolumeImplementation volume, boolean startAsDaemon) { + this.volume = volume; + setDaemon(startAsDaemon); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Thread#run() + */ + @Override + public void run() { + + while (!isInterrupted()) { + // send thread to sleep (default 1minute) + try { + Thread.sleep(volume.getOptions().getPeriodicFileSizeUpdatesIntervalS() * 1000); + } catch (InterruptedException e) { + break; + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "START openFileTable: Periodic filesize update for %s open files.", volume + .getOpenFileTable().size()); + } + + // Iterate over the openFileTable + for (Entry entry : volume.getOpenFileTable().entrySet()) { + try { + entry.getValue().writeBackFileSizeAsync(); + } catch (IOException e) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "PeriodicFileSizeUpdateThread: failed to update filesize. Reason: ", + e.getMessage()); + } + } + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "END openFileTable: Periodic filesize update for %s open files.", volume + .getOpenFileTable().size()); + } + } + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/PeriodicXcapRenewalThread.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/PeriodicXcapRenewalThread.java new file mode 100644 index 0000000..11217f8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/PeriodicXcapRenewalThread.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.util.Map.Entry; + +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * Renews periodically the XCap + */ +public class PeriodicXcapRenewalThread extends Thread { + + private VolumeImplementation volume = null; + + public PeriodicXcapRenewalThread(VolumeImplementation volume, boolean startAsDaemon) { + this.volume = volume; + setDaemon(startAsDaemon); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Thread#run() + */ + @Override + public void run() { + while (!isInterrupted()) { + // send thread to sleep (default 1minute) + try { + Thread.sleep(volume.getOptions().getPeriodicXcapRenewalIntervalS()*1000); + } catch (Exception e) { + break; + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "START openFileTable: Periodic Xcap renewal for %s open files.", volume + .getOpenFileTable().size()); + } + + // iterate over the openFileTable. + for (Entry entry : volume.getOpenFileTable().entrySet()) { + try { + entry.getValue().renewXCapsAsync(); + } catch (AddressToUUIDNotFoundException e) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "PeriodicXCapThread: failed to renew XCap. Reason: ", + e.getMessage()); + } + } + + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "END openFileTable: Periodic Xcap renewal for %s open files.", volume + .getOpenFileTable().size()); + } + } + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/RPCCaller.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/RPCCaller.java new file mode 100644 index 0000000..410d318 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/RPCCaller.java @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; +import java.net.InetSocketAddress; + +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.InternalServerErrorException; +import org.xtreemfs.common.libxtreemfs.exceptions.InvalidViewException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.common.libxtreemfs.exceptions.XtreemFSException; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SERVICES; + +import com.google.protobuf.Message; + +/** + * Helper class provides static methods for all kinds of RPC calls to the servers. Abstracts error + * handling and retrying of failure. + */ +public class RPCCaller { + + /** + * Interface for syncCall which generates the calls. Will be called for each retry. + */ + protected interface CallGenerator { + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, C input) throws IOException, PosixErrorException; + } + + protected static R syncCall(SERVICES service, UserCredentials userCreds, + Auth auth, Options options, UUIDResolver uuidResolver, UUIDIterator it, + boolean uuidIteratorHasAddresses, C callRequest, CallGenerator callGen) throws IOException, + PosixErrorException, InternalServerErrorException, AddressToUUIDNotFoundException { + return syncCall(service, userCreds, auth, options, uuidResolver, it, uuidIteratorHasAddresses, false, + options.getMaxTries(), callRequest, null, callGen); + } + + protected static R + syncCall(SERVICES service, UserCredentials userCreds, Auth auth, Options options, + UUIDResolver uuidResolver, UUIDIterator it, boolean uuidIteratorHasAddresses, + boolean delayNextTry, int maxRetries, C callRequest, CallGenerator callGen) throws IOException, + PosixErrorException, InternalServerErrorException, AddressToUUIDNotFoundException { + return syncCall(service, userCreds, auth, options, uuidResolver, it, uuidIteratorHasAddresses, + delayNextTry, maxRetries, callRequest, null, callGen); + } + + protected static R syncCall(SERVICES service, UserCredentials userCreds, + Auth auth, Options options, UUIDResolver uuidResolver, UUIDIterator it, + boolean uuidIteratorHasAddresses, C callRequest, ReusableBuffer buf, CallGenerator callGen) + throws IOException, PosixErrorException, InternalServerErrorException, + AddressToUUIDNotFoundException { + return syncCall(service, userCreds, auth, options, uuidResolver, it, uuidIteratorHasAddresses, false, + options.getMaxTries(), callRequest, buf, callGen); + } + + protected static R syncCall(SERVICES service, UserCredentials userCreds, + Auth auth, Options options, UUIDResolver uuidResolver, UUIDIterator it, + boolean uuidIteratorHasAddresses, boolean delayNextTry, int maxRetries, C callRequest, + ReusableBuffer buffer, CallGenerator callGen) throws PosixErrorException, IOException, + InternalServerErrorException, AddressToUUIDNotFoundException { + int maxTries = maxRetries; + int attempt = 0; + + R response = null; + try { + while (++attempt <= maxTries || maxTries == 0) { + // Retry only if it is a recoverable error (REDIRECT, IO_ERROR, INTERNAL_SERVER_ERROR). + boolean retry = false; + IOException responseError = null; + + RPCResponse r = null; + try { + // create an InetSocketAddresse depending on the uuidIterator and + // the kind of service + InetSocketAddress server; + if (uuidIteratorHasAddresses) { + server = getInetSocketAddressFromAddress(it.getUUID(), service); + } else { // UUIDIterator has really1 UUID, not just address Strings. + String address = uuidResolver.uuidToAddress(it.getUUID()); + server = getInetSocketAddressFromAddress(address, service); + } + + r = callGen.executeCall(server, auth, userCreds, callRequest); + response = r.get(); + + // If the buffer is not null it should be filled with data + // piggybacked in the RPCResponse. + // This is used by the read request. + if (r.getData() != null) { + if (buffer != null) { + buffer.put(r.getData()); + } + BufferPool.free(r.getData()); + } + } catch (PBRPCException pbe) { + responseError = pbe; + // handle special redirect + if (pbe.getErrorType().equals(ErrorType.REDIRECT)) { + assert (pbe.getRedirectToServerUUID() != null); + // Log redirect. + if (Logging.isInfo()) { + String error; + if (uuidIteratorHasAddresses) { + error = + "The server " + it.getUUID() + " redirected to the current master: " + + pbe.getRedirectToServerUUID() + " at attempt: " + attempt; + } else { + error = + "The server with UUID " + it.getUUID() + + " redirected to the current master: " + + pbe.getRedirectToServerUUID() + " at attempt: " + attempt; + } + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, pbe, error); + } + + if (maxTries != 0 && attempt == maxTries) { + // This was the last retry, but we give it another chance. + maxTries++; + } + // Do a fast retry and do not delay until next attempt. + it.markUUIDAsFailed(it.getUUID()); + continue; + } + + if (pbe.getErrorType().equals(ErrorType.IO_ERROR) + || pbe.getErrorType().equals(ErrorType.INTERNAL_SERVER_ERROR)) { + // Mark the current UUID as failed and get the next one. + it.markUUIDAsFailed(it.getUUID()); + retry = true; + } + } catch (IOException ioe) { + responseError = ioe; + // Mark the current UUID as failed and get the next one. + it.markUUIDAsFailed(it.getUUID()); + retry = true; + } catch (InterruptedException ie) { + // TODO: Ask what that is. + if (options.getInterruptSignal() == 0) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, ie, + "Caught interrupt, aborting sync request"); + } + break; + } + throw new IOException(); + } finally { + if (r != null) { + r.freeBuffers(); + } + } + + if (responseError != null) { + // Log only the first retry. + if (attempt == 1 && maxTries != 1) { + String retriesLeft = (maxTries == 0) ? ("infinite") : (String.valueOf(maxTries - attempt)); + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, responseError, + "Got no response from %s, " + "retrying (%s attemps left, waiting at least %s seconds" + + " between two attemps) Error was: %s", it.getUUID(), retriesLeft, + options.getRetryDelay_s(), responseError.getMessage()); + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, null, responseError); + } + } + + // Retry (and delay)? + if (retry && + // Retry (and delay) only if at least one retry is left + (attempt < maxTries || maxTries == 0) + // or this last retry should be delayed + || (attempt == maxTries && delayNextTry)) { + waitDelay(options.getRetryDelay_s()); + continue; + } else { + throw responseError; + } + } + + return response; + } + } catch (PBRPCException e) { + // Max attempts reached or non-IO error seen. Throw an exception. + handleErrorAfterMaxTriesExceeded(e, it); + } + return null; + } + + /** + * Blocks the thread for delay_s seconds and throws an exception if interrupted. + * + * @param delay_s + * @throws IOException + */ + static void waitDelay(long delay_s) throws IOException { + try { + Thread.sleep(delay_s * 1000); + } catch (InterruptedException e) { + String msg = "Caught interrupt while waiting for the next attempt, aborting sync request"; + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, e, msg); + } + throw new IOException(msg); + } + } + + /** + * Determines what to throw when the maximum number of retries is reached and there is still no valid + * answer. + * + * @param e + * @param it + */ + private static void handleErrorAfterMaxTriesExceeded(PBRPCException e, UUIDIterator it) throws PosixErrorException, + IOException, InternalServerErrorException, InvalidViewException, XtreemFSException { + // By default all errors are logged as errors. + int logLevel = Logging.LEVEL_INFO; + + String errorMsg = ""; + switch (e.getErrorType()) { + case ERRNO: + // Posix error are usally not logged as errors. + if (e.getPOSIXErrno().equals(POSIXErrno.POSIX_ERROR_ENOENT)) { + logLevel = Logging.LEVEL_DEBUG; + } + errorMsg = + "The server " + it.getUUID() + " denied the requested operation. " + "Error value: " + + e.getErrorType().name() + " Error message: " + e.getErrorMessage(); + + Logging.logMessage(logLevel, Category.misc, e, errorMsg); + throw new PosixErrorException(e.getPOSIXErrno(), errorMsg); + case IO_ERROR: + Logging.logMessage(logLevel, Category.misc, e, "The client encountered a communication " + + "error sending a request to the server %s Error: %s", it.getUUID(), e.getErrorMessage()); + throw new IOException(e.getErrorMessage()); + case INTERNAL_SERVER_ERROR: + Logging.logMessage(logLevel, Category.misc, e, "The server %s returned an internal server" + + "error: %s", it.getUUID(), e.getErrorMessage()); + throw new InternalServerErrorException(errorMsg); + case REDIRECT: + throw new XtreemFSException("This error (A REDIRECT error was not handled " + + "and retried but thrown instead) should never happen. Report this"); + case INVALID_VIEW: + Logging.logMessage(logLevel, Category.replication, e, + "The server %s denied the requested operation because the clients view is outdated. Error: %s", + it.getUUID(), e.getErrorMessage()); + throw new InvalidViewException(e.getErrorMessage()); + default: + errorMsg = + "The server " + it.getUUID() + "returned an error: " + e.getErrorType().name() + + " Error: " + e.getErrorMessage(); + Logging.logMessage(logLevel, Category.misc, e, errorMsg); + throw new XtreemFSException(errorMsg); + } // end of switch + } + + // private static void handlePBException(PBRPCException e) throws IOException, PosixErrorException { + // int loglevel = Logging.LEVEL_INFO; + // + // switch (e.getErrorType()) { + // + // case ErrorType.ERRNO: + // // Posix errors are usually not logged as errors. + // if (e.getPOSIXErrno().equals(POSIXErrno.POSIX_ERROR_ENOENT)) { + // loglevel = Logging.LEVEL_DEBUG; + // } + // Logging.logMessage(loglevel, Category.misc, e, "The server %s (" + , args) + // + // default: + // return; + // } + // } + + /** + * Create an InetSocketAddress depending on the address and the type of service object is. If address does + * not contain a port a default port depending on the client object is used. + * + * @param address + * The address. + * @param service + * The service used to determine which default port should used when address does not contain a + * port. + * @return + */ + protected static InetSocketAddress getInetSocketAddressFromAddress(String address, SERVICES service) { + if (SERVICES.DIR.equals(service)) { + return Helper.stringToInetSocketAddress(address, + GlobalTypes.PORTS.DIR_PBRPC_PORT_DEFAULT.getNumber()); + } + if (SERVICES.MRC.equals(service)) { + return Helper.stringToInetSocketAddress(address, + GlobalTypes.PORTS.MRC_PBRPC_PORT_DEFAULT.getNumber()); + } + if (SERVICES.OSD.equals(service)) { + return Helper.stringToInetSocketAddress(address, + GlobalTypes.PORTS.OSD_PBRPC_PORT_DEFAULT.getNumber()); + } + return null; + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/ReadOperation.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/ReadOperation.java new file mode 100644 index 0000000..6c217b5 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/ReadOperation.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + + +/** + * + * Represents a read operation for the StripeTranslator. + */ +public class ReadOperation { + + private long objNumber; + + private int osdOffset; + + private int reqSize; + + private int reqOffset; + + /** + * The position where the result of this request should put into the global Buffer. + */ + private int bufferStart; + + protected ReadOperation(long objNumber, int osdOffset, int reqSize, int reqOffset, int bufferStart) { + + this.objNumber = objNumber; + this.osdOffset = osdOffset; + this.reqSize = reqSize; + this.reqOffset = reqOffset; + this.bufferStart = bufferStart ; + + } + + protected long getObjNumber() { + return objNumber; + } + + public int getOsdOffset() { + return osdOffset; + } + + protected int getReqSize() { + return reqSize; + } + + protected int getReqOffset() { + return reqOffset; + } + + protected int getBufferStart() { + return bufferStart; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/StripeTranslator.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/StripeTranslator.java new file mode 100644 index 0000000..7edaffb --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/StripeTranslator.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.util.Vector; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; + +public interface StripeTranslator { + + /** + * Create a new {@link ReadOperation} from "size","offset" and "policy" and append the new + * {@link ReadOperation} to operations. + * + * @param size + * @param offset + * @param policy + * @param operations + */ + public abstract void translateReadRequest(int size, long offset, StripingPolicy policy, + Vector operations); + + /** + * Create a new {@link WriteOperation} from "size","offset" and "policy" and append the new + * {@link WriteOperation} to operations. + * + * @param size + * @param offset + * @param policy + * @param buf + * @param operations + */ + public abstract void translateWriteRequest(int size, long offset, StripingPolicy policy, + ReusableBuffer buf, Vector operations); +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/StripeTranslatorRaid0.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/StripeTranslatorRaid0.java new file mode 100644 index 0000000..cd50230 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/StripeTranslatorRaid0.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.util.Vector; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; + +public class StripeTranslatorRaid0 implements StripeTranslator { + + public void translateWriteRequest(int size, long offset, StripingPolicy policy, ReusableBuffer buf, + Vector operations) { + // need to know stripe size and stripe width + int stripeSize = policy.getStripeSize() * 1024; // stripe size in kB + int osdCount = policy.getWidth(); + + int start = 0; + while (start < size) { + long objNumber = (start + offset) / stripeSize; + int osdOffset = (int) (objNumber % osdCount); + int reqOffset = (int) ((start + offset) % stripeSize); + int reqSize = Math.min(size - start, stripeSize - reqOffset); + + ReusableBuffer viewBuffer = buf.createViewBuffer(); + viewBuffer.range(start, reqSize); + operations.add(new WriteOperation(objNumber, osdOffset, reqSize, reqOffset, viewBuffer)); + start += reqSize; + } + } + + public void translateReadRequest(int size, long offset, StripingPolicy policy, + Vector operations) { + // need to know stripe size and stripe width + int stripeSize = policy.getStripeSize() * 1024; // strip size in kB + int osdCount = policy.getWidth(); + + int start = 0; + while (start < size) { + long objNumber = (start + offset) / stripeSize; + int osdOffset = (int) (objNumber % osdCount); + int reqOffset = (int) ((start + offset) % stripeSize); + int reqSize = Math.min(size - start, stripeSize - reqOffset); + + operations.add(new ReadOperation(objNumber, osdOffset, reqSize, reqOffset, start)); + start += reqSize; + } + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/Tupel.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/Tupel.java new file mode 100644 index 0000000..f2bd76b --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/Tupel.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +/** + * + * Java donsn't have tupels. + */ +public class Tupel { + + private T object1; + private V object2; + + + protected Tupel(T object1, V object2) { + this.object1 = object1; + this.object2 = object2; + } + + protected T getFirst() { + return object1; + } + + protected V getSecond() { + return object2; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/UUIDIterator.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/UUIDIterator.java new file mode 100644 index 0000000..56de6e4 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/UUIDIterator.java @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.util.ArrayList; +import java.util.Collection; + +import org.xtreemfs.common.libxtreemfs.exceptions.UUIDIteratorListIsEmpyException; + +/** + * Stores a list of all UUIDs of a replicated service and allows to iterate through them. + * + * If an UUID was marked as failed and this is the current UUID, the next call of GetUUID() will return + * another available, not as failed marked, UUID. + * + * If the last UUID in the list is marked as failed, the status of all entries will be reset and the current + * UUID is set to the first in the list. + * + * Additionally, it is allowed to set the current UUID to a specific one, regardless of its current state. + * This is needed in case a service did redirect a request to another UUID. + */ +public class UUIDIterator { + + static private class UUIDItem { + public String uuid; + + /** + * Shows whether this UUID has failed + */ + public boolean markedAsFailed; + + /** + * Represents a UUID + */ + public UUIDItem(String addUUID) { + markedAsFailed = false; + uuid = addUUID; + } + } + + private ArrayList uuids; + private UUIDItem currentUUID; + + /** + * Creates a new instance of UUIDIterator with an empty UUID list. + */ + public UUIDIterator() { + uuids = new ArrayList(); + currentUUID = null; + } + + /** + * Creates a new instance of UUIDIterator with an UUID list containing all the UUIDs in the specified collection. + */ + public UUIDIterator(Collection uuids) { + this(); + addUUIDs(uuids); + } + + /** + * Appends "uuid" to the list of UUIDs. Does not change the current UUID. + */ + public synchronized void addUUID(String uuid) { + UUIDItem entry = new UUIDItem(uuid); + + uuids.add(entry); + + if (uuids.size() == 1) { + currentUUID = entry; + } + } + + /** + * Appends all the UUIDs in the specified collection to list of UUIDs. Does not change the current UUID. + */ + public synchronized void addUUIDs(Collection uuids) { + for (String uuid : uuids) { + addUUID(uuid); + } + } + + /** + * Clears the list of UUIDs. + */ + public synchronized void clear() { + uuids.clear(); + currentUUID = null; + } + + /** + * Atomically clears the list and adds "uuid" to avoid an empty list. + */ + public synchronized void clearAndAddUUID(String uuid) { + this.clear(); + this.addUUID(uuid); + } + + /** + * Atomically clears the list and adds all the UUIDs in the specified collection. + */ + public synchronized void clearAndAddUUIDs(Collection uuids) { + this.clear(); + this.addUUIDs(uuids); + } + + /** + * Returns the list of UUIDs and their status. + */ + public synchronized String debugString() { + StringBuffer debugStringBuffer = new StringBuffer("[ "); + + for (UUIDItem item : uuids) { + debugStringBuffer.append("[ " + item.uuid + ", " + item.markedAsFailed + " ]"); + } + + debugStringBuffer.append(" ]"); + + return debugStringBuffer.toString(); + } + + /** + * Get the current UUID (by default the first in the list). + **/ + public synchronized String getUUID() throws UUIDIteratorListIsEmpyException { + if (uuids.isEmpty()) { + throw new UUIDIteratorListIsEmpyException("GetUUID() failed as no current " + + " UUID is set. Size of list of UUIDs: " + uuids.size()); + } else { + assert (!currentUUID.markedAsFailed); + return currentUUID.uuid; + + } + } + + /** + * Marks "uuid" as failed. Use this function to advance to the next in the list. + */ + public synchronized void markUUIDAsFailed(String uuid) { + // Only do something if currentUUID is uuid + if (currentUUID != null && currentUUID.uuid.equals(uuid)) { + currentUUID.markedAsFailed = true; + + int index = uuids.indexOf(currentUUID); + // if this is the last UUID in the list, revert all + if (index == (uuids.size() - 1)) { + for (UUIDItem item : uuids) { + item.markedAsFailed = false; + } + currentUUID = uuids.get(0); + } else { // set currenUUID to the following UUID + currentUUID = uuids.get(index + 1); + } + } + } + + /** + * Sets "uuid" as current UUID. If uuid was not found in the list of UUIDs, it will be added to the + * UUIDIterator. + */ + public synchronized void setCurrentUUID(String uuid) { + // Search "uuid" in "uuids_" and set it to the current UUID. + for (UUIDItem item : uuids) { + if (item.uuid.equals(uuid)) { + currentUUID = item; + return; + } + } + + // UUID was not found, add it. + UUIDItem entry = new UUIDItem(uuid); + uuids.add(entry); + currentUUID = entry; + return; + } + + /** + * Get the number of UUIDs in this iterator regardless if they are marked as failed or not. + * + * @return int + * Number of UUIDs. + */ + public synchronized int size() { + return uuids.size(); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/UUIDResolver.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/UUIDResolver.java new file mode 100644 index 0000000..a15099d --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/UUIDResolver.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.VolumeNotFoundException; + + +public interface UUIDResolver { + + + /** + * Resolves the address (ip-address:port) for a given UUID. + * + * @return String + * The resolved address as String. + * + + * @throws AddressToUUIDNotFoundException + */ + public String uuidToAddress(String uuid) throws AddressToUUIDNotFoundException; + + /** + * Resolves the UUID for a given volume name. + * + * @param volumeName + * Name of the volume. + * @return String + * UUID of the MRC the volume 'volumeName' is registered. + * + * @throws AddressToUUIDNotFoundException + * @throws VolumeNotFoundException + */ + public String volumeNameToMRCUUID(String volumeName) throws VolumeNotFoundException, AddressToUUIDNotFoundException; + + /** + * Resolves the list of UUIDs of the MRC replicas and adds them to the uuid_iterator object. + * + * @throws VolumeNotFoundException + * @throws AddressToUUIDNotFoundException + */ + public void volumeNameToMRCUUID(String volumeName, UUIDIterator uuidIterator) + throws VolumeNotFoundException, AddressToUUIDNotFoundException; +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/Volume.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/Volume.java new file mode 100644 index 0000000..b002fa1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/Volume.java @@ -0,0 +1,788 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.mrc.metadata.ReplicationPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.XATTR_FLAGS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse; + +/** + * Represents a volume. A volume object can be obtain by opening a volume with a client. + */ +public interface Volume { + + public void internalShutdown(); + + /** + * Start this volume, e.g. initialize all required things. + */ + void start() throws Exception; + + + /** + * Same as start(), but add option to start threads as daemons. Daemon threads are only used by the XtreemFSHadoopClient. + * + * @param startThreadsAsDaemons if true, all threads are daemons. + */ + void start(boolean startThreadsAsDaemons) throws Exception; + + /** + * Close the volume. + */ + public void close(); + + /** + * Returns information about the volume (e.g. used/free space). + * + * @param userCredentials + * Name and groups of the User. + * @return {@link StatVFS} + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public StatVFS statFS(UserCredentials userCredentials) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException; + + /** + * + * Resolves the symbolic link at "path" and returns it in "linkTargetPath". + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the symbolic link. + * @return String where to store the result. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public String readLink(UserCredentials userCredentials, String path) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException; + + /** + * + * Creates a symbolic link pointing to "targetPath" at "linkPath". + * + * @param userCredentials + * Name and Groups of the user. + * @param targetPath + * Path to the target. + * @param linkPath + * Path to the symbolic link. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public void symlink(UserCredentials userCredentials, String targetPath, String linkPath) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Creates a hard link pointing to "targetPath" at "linkPath". + * + * @param userCredentials + * Name and Groups of the user. + * @param targetPath + * Path to the target. + * @param linkPath + * Path to the hard link. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public void link(UserCredentials userCredentials, String targetPath, String linkPath) + throws IOException, PosixErrorException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Tests if the subject described by "userCredentials" is allowed to access "path" as specified by + * "flags". "flags" is a bit mask which may contain the values ACCESS_FLAGS_{F_OK,R_OK,W_OK,X_OK}. + * + * Throws a PosixErrorException if not allowed. + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file/directory. + * @param flags + * Open flags as specified in xtreemfs::pbrpc::SYSTEM_V_FCNTL. + * + * @throws AddressToUUIDNotFoundException + * @throws IOException + * @throws PosixErrorException + */ + public void access(UserCredentials userCredentials, String path, int flags) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Opens a file and returns the pointer to a {@link FileHandle} object. + * + * When creating files, use the function {@link #openFile(UserCredentials, String, int, int)} with the + * additional mode parameter instead. + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file. + * @param flags + * Open flags as specified in xtreemfs::pbrpc::SYSTEM_V_FCNTL. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + * + * @remark Ownership is NOT transferred to the caller. Instead FileHandle.close() has to be called to + * destroy the object. + */ + public FileHandle openFile(UserCredentials userCredentials, String path, int flags) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Same as previous openFile() except for the additional mode parameter, which sets the permissions for + * the file in case SYSTEM_V_FCNTL_H_O_CREAT is specified as flag and the file will be created. + * + * Please note that the mode parameter requires octal values, i.e. use 0777 instead of 777 for the + * permissions. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public FileHandle openFile(UserCredentials userCredentials, String path, int flags, int mode) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Truncates the file to "newFileSize" bytes. + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file. + * @param newFileSize + * New size of file. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public void truncate(UserCredentials userCredentials, String path, int newFileSize) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Retrieve the attributes of a file and writes the result in "stat". + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file/directory. + * @return stat Result of the operation will be stored here. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public Stat getAttr(UserCredentials userCredentials, String path) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Sets the attributes given by "stat" and specified in "toSet". + * + * @note If the mode, uid or gid is changed, the ctime of the file will be updated according to POSIX + * semantics. + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file/directory. + * @param stat + * Stat object with attributes which will be set. + * @param toSet + * Bitmask which defines which attributes to set. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public void setAttr(UserCredentials userCredentials, String path, Stat stat, int toSet) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Remove the file at "path" (deletes the entry at the MRC and all objects on one OSD). + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public void unlink(UserCredentials userCredentials, String path) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Rename a file or directory "path" to "newPath". + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Old path. + * @param newPath + * New path. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + * */ + public void rename(UserCredentials userCredentials, String path, String newPath) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Creates a directory with the modes "mode". Creates missing parent directories if and only if recursive + * is set to true. Results in an error otherwise. + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the new directory. + * @param mode + * Permissions of the new directory. + * @param recursive + * Whether or not non existing parent directories should be created. + * + * @throws IOException + * @throws PosixErrorException + * @throws AddressToUUIDNotFoundException + */ + public void createDirectory(UserCredentials userCredentials, String path, int mode, + boolean recursive) throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Creates a directory with the modes "mode". Results in an error when parent directory doesn't exist. + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the new directory. + * @param mode + * Permissions of the new directory. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public void createDirectory(UserCredentials userCredentials, String path, int mode) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Removes the directory at "path" which has to be empty. + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the directory to be removed. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public void removeDirectory(UserCredentials userCredentials, String path) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Returns a list of "count" directories/files contained in the directory "path" beginning by "offset". If + * count equals 0 all entries beginning by "offset" will be in the list. + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the directory. + * @param offset + * Index of first requested entry. + * @param count + * Number of requested entries. + * @param namesOnly + * If set to true, the {@link Stat} object of every entry will be omitted. + * + * @return {@link DirectoryEntries} will contain the names of the entries and, if not disabled by + * "namesOnly", a {@link Stat} object for every entry. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public DirectoryEntries readDir(UserCredentials userCredentials, String path, int offset, + int count, boolean namesOnly) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException; + + /** + * Returns the list of extended attributes stored for "path" (Entries may be cached). + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file/directory. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + * + * @return {@link listxattrResponse} + * + * @remark Ownership is transferred to the caller. + */ + public listxattrResponse listXAttrs(UserCredentials userCredentials, String path) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Returns the list of extended attributes stored for "path" (Set "useCache" to false to make sure no + * cached entries are returned). + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file/directory. + * @param useCache + * Set to false to fetch the attributes from the MRC. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + * + * @remark Ownership is transferred to the caller. + */ + public listxattrResponse listXAttrs(UserCredentials userCredentials, String path, + boolean useCache) throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Sets the extended attribute "name" of "path" to "value". + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file/directory. + * @param name + * Name of the extended attribute. + * @param value + * Value of the extended attribute. + * @param flags + * May be XATTR_CREATE or XATTR_REPLACE. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public void setXAttr(UserCredentials userCredentials, String path, String name, String value, + XATTR_FLAGS flags) throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + + /** + * Sets the extended attribute "name" of "path" to "value". + * + * @param userCredentials + * Name and Groups of the user. + * @param auth + * Authentication data, e.g. of type AUTH_PASSWORD. + * @param path + * Path to the file/directory. + * @param name + * Name of the extended attribute. + * @param value + * Value of the extended attribute. + * @param flags + * May be XATTR_CREATE or XATTR_REPLACE. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public void setXAttr(UserCredentials userCredentials, Auth auth, String path, String name, String value, + XATTR_FLAGS flags) throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + + /** + * Returns value for an XAttribute with "name" stored for "path" in "value". + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file/directory. + * @param name + * Name of the extended attribute. + * @return String Will contain the content of the extended attribute. NULL if attribute was not found. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + * + */ + public String getXAttr(UserCredentials userCredentials, String path, String name) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Writes the size of a value (string size without null-termination) of an XAttribute "name" stored for + * "path" in "size". + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file/directory. + * @param name + * Name of the extended attribute. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + * + * @return true if the attribute was found. + */ + public int getXAttrSize(UserCredentials userCredentials, String path, String name) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Removes the extended attribute "name", stored for "path". + * + * @param userCredentials + * Name and Groups of the user. + * @param path + * Path to the file/directory. + * @param name + * Name of the extended attribute. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public void removeXAttr(UserCredentials userCredentials, String path, String name) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Adds a new replica for the file at "path" and triggers the replication of this replica if it's a full + * replica. + * + * Please note, in case of a read-only replica the replication flags of newReplica must contain a + * replication strategy flag. + * For a partial replica, use {@link REPL_FLAG.REPL_FLAG_STRATEGY_SEQUENTIAL_PREFETCHING}. + * If you create a full replica (with the flag {@link REPL_FLAG.REPL_FLAG_FULL_REPLICA}), + * use the strategy {@link REPL_FLAG.REPL_FLAG_STRATEGY_RAREST_FIRST}. + * + * @param userCredentials + * Username and groups of the user. + * @param path + * Path to the file. + * @param newReplica + * Description of the new replica to be added. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + * */ + public void addReplica(UserCredentials userCredentials, String path, Replica newReplica) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Return the list of replicas of the file at "path". + * + * @param userCredentials + * Username and groups of the user. + * @param path + * Path to the file. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + * + * @remark Ownership is transferred to the caller. + */ + public Replicas listReplicas(UserCredentials userCredentials, String path) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Removes the replica of file at "path" located on the OSD with the UUID "osdUuid" (which has to be the + * head OSD in case of striping). + * + * @param userCredentials + * Username and groups of the user. + * @param path + * Path to the file. + * @param osdUuid + * UUID of the OSD from which the replica will be deleted. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public void removeReplica(UserCredentials userCredentials, String path, String osdUuid) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Returns a list of all available OSDs where the file (described by "path") can be placed. + * + * @param userCredentials + * Username and groups of the user. + * @param path + * Path to the file. + * @param numberOfOsds + * Number of OSDs required in a valid group. This is only relevant for grouping and will be ignored by + * filtering and sorting policies. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public List getSuitableOSDs(UserCredentials userCredentials, String path, + int numberOfOsds) throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Sets the default replication policy for "directory". + * + * @param userCredentials + * Username and groups of the user. + * @param directory + * Path of the directory. + * @param replicationPolicy + * Replication policy which is defined in {@link ReplicaUpdatePolicies} + * @param replicationFactor + * Number of replicas that should be assigned to new files. + * @param replicationFlags + * Replication flags as number. Defined in {@link REPL_FLAG}. + * Use the helper functions available in {@link ReplicationFlags}. + * + * @throws AddressToUUIDNotFoundException + * @throws {@link IOException} + * @throws PosixErrorException + */ + public void setDefaultReplicationPolicy(UserCredentials userCredentials, String directory, + String replicationPolicy, int replicationFactor, int replicationFlags) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Gets the default replication policy for "directory". + * + * @param userCredentials + * Username and groups of the user. + * @param directory + * Path of the directory. + * @return {@link ReplicationPolicy} + * @throws IOException + * @throws PosixErrorException + * @throws AddressToUUIDNotFoundException + */ + public ReplicationPolicy getDefaultReplicationPolicy(UserCredentials userCredentials, String directory) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException; + + /** + * Returns a list of {@link StripeLocation} where each stripe of the file is located. To determine where the a + * particular stripe is located the UUIDs of all replicas which have a copy of this stripe will be collected and + * resolved to hostnames. If a uuid can't be resolved it will be deleted from the list because HDFS can't handle IP + * addresses. + * + * @param userCredentials + * Username and groups of the user. + * @param path + * Path of the file. + * @param startSize + * Size in byte where to start collecting the {@link StripeLocation}s. + * @param length + * The length of the part of the file where the {@link StripeLocation}s should be collected in + * byte. + * @return {@link List} of {@link StripeLocation} + * + * @throws IOException + * @throws PosixErrorException + * @throws AddressToUUIDNotFoundException + */ + + public List getStripeLocations(UserCredentials userCredentials, String path, + long startSize, long length) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException; + + + /** + * Removes the user from the ACL stored in path + * + * @param userCreds + * Username and groups of the user. + * @param path + * The path on the volume where the ACL is stored + * @param user + * The user to remove access rights + * @throws IOException + */ + public void removeACL(UserCredentials userCreds, String path, String user) throws IOException; + + /** + * Removes all provided users from the ACL stored in path + * + * @param userCreds + * Username and groups of the user. + * @param path + * The path on the volume where the ACL is stored + * @param aclEntries + * Set of acl entries to remove + * @throws IOException + */ + public void removeACL(UserCredentials userCreds, String path, Set aclEntries) throws IOException; + + /** + * Adds the user to the ACL for the provided path + * + * @param userCreds + * Username and groups of the user. + * @param path + * The path on the volume where the ACL is stored + * @param user + * The user to remove access rights + * @param accessrights + * The accessrights to be set for the user. I.e. rwx, rx, rw, ... + * @throws IOException + */ + public void setACL(UserCredentials userCreds, String path, String user, String accessrights) + throws IOException; + + /** + * Adds all users to the ACL for the provided path + * + * @param userCreds + * Username and groups of the user. + * @param path + * The path on the volume where the ACL is stored + * @param aclEntries + * ACL entries to set + * @throws IOException + */ + public void setACL(UserCredentials userCreds, String path, Map aclEntries) + throws IOException; + + /** + * Returns all users in the ACL for the provided path + * + * @param userCreds + * Username and groups of the user. + * @param path + * The path on the volume where the ACL is stored + * @throws IOException + */ + public Map listACL(UserCredentials userCreds, String path) throws IOException; + + /** Get the OSD selection policies of the volume (replica placement). + * + * @param userCreds Username and groups of the user. + * + * @return List of policies as comma separated string. + * @throws IOException + */ + public String getOSDSelectionPolicy(UserCredentials userCreds) throws IOException; + + /** Set the OSD selection policies for the volume (replica placement). + * + * @param userCreds Username and groups of the user. + * @param policies List of policies as comma separated string. + * @throws IOException + */ + public void setOSDSelectionPolicy(UserCredentials userCreds, String policies) throws IOException; + + /** Get the Replica selection policies of the volume (replica selection). + * + * + * @param userCreds Username and groups of the user. + * + * @return List of policies as comma separated string. + * @throws IOException + */ + public String getReplicaSelectionPolicy(UserCredentials userCreds) throws IOException; + + /** Set the Replica selection policies for the volume (replica selection). + * + * @param userCreds Username and groups of the user. + * @param policies List of policies as comma separated string. + * @throws IOException + */ + public void setReplicaSelectionPolicy(UserCredentials userCreds, String policies) throws IOException; + + + /** Set attribute of a policy to further customize replica placement and + * selection. See the user guide for more information. + * + * @param userCreds Username and groups of the user. + * @param attribute Format: . e.g., "1001.domains" + * @param value Value of the attribute. + * @throws IOException + */ + public void setPolicyAttribute(UserCredentials userCreds, String attribute, String value) throws IOException; + + /** + * Get the name of the volume. + * @return The name of the volume. + */ + public String getVolumeName(); + + /** + * Used only for Hadoop Interface. + * + * Encapsulates information about one stripe, i.e. the size in kb where the stripe begins, the length of + * the stripe and lists of hostnames and corresponding uuids where the stripe is located. Hostnames are + * usually the ones which are configured through the "hostname = " option of the OSD. Otherwise it is the + * resolved hostname of registred IP address at the DIR. + * + */ + public class StripeLocation { + private final long startSize; + private final long length; + private final String[] uuids; + + /** + * The hostname as configured with "hostname = " parameter of the OSD or otherwise the resolved + * hostname from the IP address registered at DIR. + */ + private final String[] hostnames; + + protected StripeLocation(long startSize, long length, String[] uuids, String[] hostnames) { + this.startSize = startSize; + this.length = length; + this.uuids = uuids; + this.hostnames = hostnames; + } + + public long getStartSize() { + return startSize; + } + + public long getLength() { + return length; + } + + public String[] getUuids() { + return uuids; + } + + public String[] getHostnames() { + return hostnames; + } + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/VolumeImplementation.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/VolumeImplementation.java new file mode 100644 index 0000000..a608340 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/VolumeImplementation.java @@ -0,0 +1,1776 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Pattern; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.libxtreemfs.RPCCaller.CallGenerator; +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.common.libxtreemfs.exceptions.XtreemFSException; +import org.xtreemfs.common.xloc.ReplicationPolicyImplementation; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.json.JSONException; +import org.xtreemfs.foundation.json.JSONParser; +import org.xtreemfs.foundation.json.JSONString; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.mrc.metadata.ReplicationPolicy; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SERVICES; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Setattrs; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.XATTR_FLAGS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * This class represents the volume as it is used internally by libxtreemfs-java. + * + */ +public class VolumeImplementation implements Volume, AdminVolume { + + /** + * UUID String of the client. + */ + private final String clientUuid; + + /** + * Client who opened this volume. + */ + private final ClientImplementation client; + + /** + * UUIDResolver used by this volume. + */ + private final UUIDResolver uuidResolver; + + /** + * Name of this volume. + */ + private final String volumeName; + + /** + * The options of the client that should be used for this volume. + */ + private final Options volumeOptions; + + /** + * Bogus object of UserCredentials. Used when no real UserCredentials are needed. + */ + private final UserCredentials userCredentialsBogus; + + /** + * The RPC Client. + * */ + private RPCNIOSocketClient networkClient; + + /** + * An MRCServiceClient is a wrapper for an RPC Client. + * */ + private MRCServiceClient mrcServiceClient; + + /** + * A OSDServiceClient is a wrapper for an RPC Client. + */ + private OSDServiceClient osdServiceClient; + + /** + * SSLOptions required for connections to the services. + */ + private final SSLOptions sslOptions; + + /** + * Bogus auth used for calls where no valid Auth is required. + */ + private final Auth authBogus; + + /** + * UUIDIterator for all MRCs which know this volume. + */ + private final UUIDIterator mrcUUIDIterator; + + /** + * Concurrent map that stores all open files. + */ + private ConcurrentHashMap openFileTable; + + /** + * MetadataCache to cache already fetches Metadata. + */ + private final MetadataCache metadataCache; + + /** + * XCap renewal thread to renew Xcap periodically. + */ + private PeriodicXcapRenewalThread xcapRenewalThread; + + /** + * FileSize update thread to update file size periodically. + */ + private PeriodicFileSizeUpdateThread fileSizeUpdateThread; + + /** + * Maps a StripingPolicyType to a StripeTranslator. Should be filled with all possible StripingPolicys. + */ + private final Map stripeTranslators; + + private static final String XTREEMFS_DEFAULT_RP = "xtreemfs.default_rp"; + + private static final String OSD_SELECTION_POLICY = "xtreemfs.osel_policy"; + private static final String REPLICA_SELECTION_POLICY = "xtreemfs.rsel_policy"; + + /** + * + */ + public VolumeImplementation(ClientImplementation client, String clientUUID, UUIDIterator mrcUuidIterator, + String volumeName, SSLOptions sslOptions, Options options) { + + this.client = client; + this.clientUuid = clientUUID; + this.uuidResolver = client; + this.volumeName = volumeName; + this.volumeOptions = options; + this.sslOptions = sslOptions; + + this.mrcUUIDIterator = mrcUuidIterator; + + this.userCredentialsBogus = UserCredentials.newBuilder().setUsername("xtreemfs").build(); + this.authBogus = RPCAuthentication.authNone; + + this.metadataCache = new MetadataCache(options.getMetadataCacheSize(), options.getMetadataCacheTTLs()); + + // register all stripe translators + this.stripeTranslators = new HashMap(); + stripeTranslators.put(StripingPolicyType.STRIPING_POLICY_RAID0, new StripeTranslatorRaid0()); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#start() + */ + @Override + public void start() throws IOException { + start(false); + + } + + @Override + public void start(boolean startThreadsAsDaemons) throws IOException { + networkClient = new RPCNIOSocketClient(sslOptions, volumeOptions.getRequestTimeout_s() * 1000, + volumeOptions.getLingerTimeout_s() * 1000, "Volume", startThreadsAsDaemons); + networkClient.start(); + try { + networkClient.waitForStartup(); + } catch (Exception e) { + throw new IOException("Volume: Could not start networkClient!"); + } + + mrcServiceClient = new MRCServiceClient(networkClient, null); + osdServiceClient = new OSDServiceClient(networkClient, null); + + openFileTable = new ConcurrentHashMap(); + + // // Start periodic threads. + fileSizeUpdateThread = new PeriodicFileSizeUpdateThread(this, startThreadsAsDaemons); + fileSizeUpdateThread.start(); + + xcapRenewalThread = new PeriodicXcapRenewalThread(this, startThreadsAsDaemons); + xcapRenewalThread.start(); + + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#internalShutdown() + */ + @Override + public void internalShutdown() { + // Stop periodic threads + try { + fileSizeUpdateThread.interrupt(); + xcapRenewalThread.interrupt(); + fileSizeUpdateThread.join(); + xcapRenewalThread.join(); + } catch (InterruptedException e) { + // TODO: Handle exception + e.printStackTrace(); + } + + // There must no FileInfo left in "openFileTable". + assert (openFileTable.size() == 0); + + // Shutdown network client. + networkClient.shutdown(); + try { + networkClient.waitForShutdown(); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "Volume: Couldn't shut" + + " down network client corretly: %s ", e.getMessage()); + } + } + + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#close() + */ + @Override + public void close() { + internalShutdown(); + + client.closeVolume(this); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#statFS(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials) + */ + @Override + public StatVFS statFS(UserCredentials userCredentials) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException, AddressToUUIDNotFoundException { + statvfsRequest request = statvfsRequest.newBuilder().setKnownEtag(0).setVolumeName(volumeName) + .build(); + + StatVFS stat = RPCCaller. syncCall(SERVICES.MRC, userCredentials, authBogus, + volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, statvfsRequest input) throws IOException { + return mrcServiceClient.statvfs(server, authHeader, userCreds, input); + } + }); + return stat; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#readLink(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, java.lang.String) + */ + @Override + public String readLink(UserCredentials userCredentials, String path) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException, AddressToUUIDNotFoundException { + readlinkRequest request = readlinkRequest.newBuilder().setVolumeName(volumeName).setPath(path) + .build(); + + readlinkResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, readlinkRequest input) + throws IOException { + return mrcServiceClient.readlink(server, authHeader, userCreds, input); + } + }); + // The XtreemFS MRC always returns one resolved target or throws an + // EINVAL. + assert (response != null && response.getLinkTargetPathCount() == 1); + + return response.getLinkTargetPath(0); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#symlink(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, java.lang.String) + */ + @Override + public void symlink(UserCredentials userCredentials, String targetPath, String linkPath) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + symlinkRequest request = symlinkRequest.newBuilder().setLinkPath(linkPath).setTargetPath(targetPath) + .setVolumeName(volumeName).build(); + + timestampResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, symlinkRequest input) + throws IOException { + return mrcServiceClient.symlink(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + String parentDir = Helper.resolveParentDirectory(linkPath); + metadataCache.updateStatTime(parentDir, response.getTimestampS(), Setattrs.SETATTR_CTIME.getNumber() + | Setattrs.SETATTR_MTIME.getNumber()); + // TODO: Retrieve stat as optional member of the response instead + // and update cached DirectoryEntries accordingly. + metadataCache.invalidateDirEntries(parentDir); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#link(org.xtreemfs.foundation.pbrpc + * .generatedinterfaces.RPC. UserCredentials, java.lang.String, java.lang.String) + */ + @Override + public void link(UserCredentials userCredentials, String targetPath, String linkPath) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + linkRequest request = linkRequest.newBuilder().setLinkPath(linkPath).setTargetPath(targetPath) + .setVolumeName(volumeName).build(); + + timestampResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, linkRequest input) throws IOException { + return mrcServiceClient.link(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + String parentDir = Helper.resolveParentDirectory(linkPath); + metadataCache.updateStatTime(parentDir, response.getTimestampS(), Setattrs.SETATTR_CTIME.getNumber() + | Setattrs.SETATTR_MTIME.getNumber()); + + // TODO: Retrieve stat as optional member of the response instead + // and update cached DirectoryEntries accordingly. + metadataCache.invalidateDirEntries(parentDir); + + // Invalidate caches as we don't cache links and their targets. + metadataCache.invalidate(linkPath); + metadataCache.invalidate(targetPath); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#access(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, + * org.xtreemfs.pbrpc.generatedinterfaces.MRC.ACCESS_FLAGS) + */ + @Override + public void access(UserCredentials userCredentials, String path, int flags) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + accessRequest request = accessRequest.newBuilder().setFlags(flags).setPath(path) + .setVolumeName(volumeName).build(); + RPCCaller. syncCall(SERVICES.MRC, userCredentials, authBogus, + volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @SuppressWarnings("unchecked") + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, accessRequest input) throws IOException { + return mrcServiceClient.access(server, authHeader, userCreds, input); + } + }); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#openFile(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, + * org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL) + */ + @Override + public AdminFileHandle openFile(UserCredentials userCredentials, String path, int flags) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + return openFile(userCredentials, path, flags, 0, 0); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#openFile(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, + * org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL, int) + */ + @Override + public AdminFileHandle openFile(UserCredentials userCredentials, String path, int flags, int mode) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + return openFile(userCredentials, path, flags, mode, 0); + } + + /** + * Used by Volume.truncate() method. Otherwise truncateNewFileSize = 0;. + * + * @param userCredentials + * @param path + * @param flags + * @param mode + * @param truncateNewFileSize + * @return + */ + public AdminFileHandle openFile(UserCredentials userCredentials, String path, int flags, int mode, + int truncateNewFileSize) throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + boolean asyncWritesEnabled = (volumeOptions.getMaxWriteahead() > 0); + + if ((SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_SYNC.getNumber() & flags) > 0) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "open called with" + + " O_SYNC, async writes were disabled"); + } + asyncWritesEnabled = false; + } + + openRequest request = openRequest.newBuilder().setVolumeName(volumeName).setPath(path) + .setFlags(flags).setMode(mode).setAttributes(0).build(); + + openResponse response = RPCCaller. syncCall(SERVICES.MRC, userCredentials, + authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, openRequest input) throws IOException { + return mrcServiceClient.open(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + // We must have obtained file credentials. + assert (response.hasCreds()); + + if (response.getCreds().getXlocs().getReplicasCount() == 0) { + String errorMessage = "MRC assigned no OSDs to file on open" + path + ", xloc: " + + response.getCreds().getXlocs().toString(); + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, errorMessage); + throw new PosixErrorException(POSIXErrno.POSIX_ERROR_EIO, errorMessage); + } + + FileHandleImplementation fileHandle = null; + + // Create a FileInfo object if it does not exist yet. + FileInfo fileInfo = getOrCreateFileInfo(Helper.extractFileIdFromXcap(response.getCreds().getXcap()), + path, response.getCreds().getXcap().getReplicateOnClose(), response.getCreds().getXlocs()); + + fileHandle = fileInfo.createFileHandle(response.getCreds().getXcap(), asyncWritesEnabled); + + // If O_CREAT is set and the file did not previously exist, upon + // successful + // completion, open() shall mark for update the st_atime, st_ctime, and + // st_mtime fields of the file and the st_ctime and st_mtime fields of + // the parent directory. + if ((flags & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber()) > 0) { + String parentDir = Helper.resolveParentDirectory(path); + metadataCache.updateStatTime(path, response.getTimestampS(), Setattrs.SETATTR_CTIME.getNumber() + | Setattrs.SETATTR_MTIME.getNumber()); + // TODO: Retrieve stat as optional member of the response instead + // and update cached DirectoryEntries accordingly. + metadataCache.invalidate(parentDir); + } + + // If O_TRUNC was set, go on processing the truncate request. + if ((flags & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber()) > 0) { + + // Update mtime and ctime of the file if O_TRUNC was set. + metadataCache.updateStatTime(path, response.getTimestampS(), Setattrs.SETATTR_CTIME.getNumber() + | Setattrs.SETATTR_MTIME.getNumber()); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "open called with O_TRUNK."); + } + + try { + fileHandle.truncatePhaseTwoAndThree(userCredentials, truncateNewFileSize, false); + } catch (XtreemFSException e) { + // Truncate did fail, close file again + // TODO: Ask what should happen if other exception is thrown. + fileHandle.close(); + throw e; + } + } + return fileHandle; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#truncate(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, int) + */ + @Override + public void truncate(UserCredentials userCredentials, String path, int newFileSize) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + // Open file with O_TRUNC + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_WRONLY.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber(); + FileHandle fileHandle = openFile(userCredentials, path, flags, 0, newFileSize); + // close file + fileHandle.close(); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#getAttr(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, + * org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat) + */ + @Override + public Stat getAttr(UserCredentials userCredentials, String path) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + return getAttr(userCredentials, path, null); + } + + /** + * If fileInfo is unknown and set to NULL, getFileInfo(path) is used. + */ + protected Stat getAttr(UserCredentials userCredentials, String path, FileInfo fileInfo) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + // Retrieve stat object from cache or MRC. + Stat stat = getAttrHelper(userCredentials, path); + + // Wait until async writes have finished and merge StatCache object with + // possibly newer information from FileInfo. + if (fileInfo == null) { + // Unknown if this file at "path" is open - look it up by its + // fileId. + FileInfo fileInfoFromOpenFileTable = openFileTable.get(stat.getIno()); // Ino == fileId + if (fileInfoFromOpenFileTable != null) { + // File at "path" is opened. + + // Wait for pending asynchronous writes which haven't finished + // yet and whose new file size is not considered yet by the stat object. + fileInfoFromOpenFileTable.waitForPendingAsyncWrites(); + stat = fileInfoFromOpenFileTable.mergeStatAndOSDWriteResponse(stat); + } + } else { + fileInfo.waitForPendingAsyncWrites(); + stat = fileInfo.mergeStatAndOSDWriteResponse(stat); + } + return stat; + } + + private Stat getAttrHelper(UserCredentials userCredentials, String path) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + // Check if Stat object is cached. + Stat stat = metadataCache.getStat(path); + + if (stat != null) { + // Found in StatCache + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "getattr: serving from stat-cache %s %s", path, stat.getSize()); + } + } else { + + // if not, retrive stat from MRC + getattrRequest request = getattrRequest.newBuilder().setVolumeName(volumeName).setPath(path) + .setKnownEtag(0).build(); + + getattrResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, getattrRequest input) + throws IOException { + return mrcServiceClient.getattr(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + stat = response.getStbuf(); + if (stat.getNlink() > 1) { // Do not cache hardlinks + metadataCache.invalidate(path); + } else { + metadataCache.updateStat(path, stat); + } + } + return stat; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#setAttr(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, + * org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Setattrs) + */ + @Override + public void setAttr(UserCredentials userCredentials, String path, Stat stat, int toSet) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + setattrRequest request = setattrRequest.newBuilder().setVolumeName(volumeName).setPath(path) + .setStbuf(stat).setToSet(toSet).build(); + + timestampResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, setattrRequest input) + throws IOException { + return mrcServiceClient.setattr(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + // "chmod" or "chown" operations result into updating the ctime + // attribute. + if (((toSet & Setattrs.SETATTR_MODE.getNumber()) > 0) + || ((toSet & Setattrs.SETATTR_UID.getNumber()) > 0) + || ((toSet & Setattrs.SETATTR_GID.getNumber()) > 0)) { + + toSet = (toSet | Setattrs.SETATTR_CTIME.getNumber()); + stat = stat.toBuilder().setAtimeNs(1000000000L * response.getTimestampS()).build(); + } + + // Do not cache hardlinks or chmod operations which try to set the SGID + // bit + // as it might get cleared by the MRC. + if (stat.getNlink() > 1 + || (((toSet & Setattrs.SETATTR_MODE.getNumber()) > 0) && ((stat.getMode() & (1 << 10))) > 0)) { + metadataCache.invalidate(path); + } else { + metadataCache.updateStatAttributes(path, stat, toSet); + } + } + + @Override + public void unlink(UserCredentials userCredentials, String path) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + unlink(userCredentials, path, false); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#nnlink(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String) + */ + @Override + public void unlink(UserCredentials userCredentials, String path, boolean unlinkOnlyAtMrc) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + // 1. Delete file at MRC. + unlinkRequest request = unlinkRequest.newBuilder().setPath(path).setVolumeName(volumeName).build(); + + unlinkResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, unlinkRequest input) throws IOException { + return mrcServiceClient.unlink(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + // 2. Invalidate metadata cache + metadataCache.invalidate(path); + String parentDir = Helper.resolveParentDirectory(path); + metadataCache.updateStatTime(path, response.getTimestampS(), Setattrs.SETATTR_CTIME.getNumber() + | Setattrs.SETATTR_MTIME.getNumber()); + metadataCache.invalidateDirEntry(parentDir, Helper.getBasename(path)); + + // 3. Delete objects of all replicas on the OSDs. + if (response.hasCreds() & !unlinkOnlyAtMrc) { + unlinkAtOsd(response.getCreds(), path); + } + } + + private void unlinkAtOsd(FileCredentials fc, String path) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + unlink_osd_Request request = unlink_osd_Request.newBuilder().setFileCredentials(fc) + .setFileId(fc.getXcap().getFileId()).build(); + + UUIDIterator osdUuidIterator = new UUIDIterator(); + + // Remove _all_ replicas. + for (int i = 0; i < fc.getXlocs().getReplicasCount(); i++) { + String headOsd = Helper.getOSDUUIDFromXlocSet(fc.getXlocs(), i, 0); + + osdUuidIterator.clearAndAddUUID(headOsd); + RPCCaller. syncCall(SERVICES.OSD, userCredentialsBogus, + authBogus, volumeOptions, uuidResolver, osdUuidIterator, false, request, + new CallGenerator() { + @SuppressWarnings("unchecked") + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, unlink_osd_Request input) + throws IOException { + return osdServiceClient.unlink(server, authHeader, userCreds, input); + } + }); + } + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#rename(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, java.lang.String) + */ + @Override + public void rename(UserCredentials userCredentials, String path, String newPath) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + if (path.equals(newPath)) { + return; // Do nothing. + } + + // 1. Issue rename at MRC. + renameRequest request = renameRequest.newBuilder().setVolumeName(volumeName).setSourcePath(path) + .setTargetPath(newPath).build(); + + renameResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, renameRequest input) throws IOException { + return mrcServiceClient.rename(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + // 2. Remove file content of any previous files at "newPath". + if (response.hasCreds()) { + unlinkAtOsd(response.getCreds(), newPath); + } + + // 3. Update caches + // Update the timestamps of parents of both directories. + String parentPath = Helper.resolveParentDirectory(path); + String parentNewPath = Helper.resolveParentDirectory(parentPath); + if (response.getTimestampS() != 0) { + metadataCache.updateStatTime(parentPath, response.getTimestampS(), + Setattrs.SETATTR_CTIME.getNumber() | Setattrs.SETATTR_MTIME.getNumber()); + metadataCache.updateStatTime(parentNewPath, response.getTimestampS(), + Setattrs.SETATTR_CTIME.getNumber() | Setattrs.SETATTR_MTIME.getNumber()); + } + + metadataCache.invalidateDirEntry(parentPath, Helper.getBasename(path)); + // TODO(mberlin): Add DirEntry instead to parent_new_path if stat + // available. + metadataCache.invalidateDirEntries(parentNewPath); + // Overwrite an existing entry; no Prefix() operation needed because: + // "If new names an existing directory, it shall be required to be an + // empty + // directory." + // see + // http://pubs.opengroup.org/onlinepubs/009695399/functions/rename.html + metadataCache.invalidate(newPath); + // Rename all affected entries. + metadataCache.renamePrefix(path, newPath); + // http://pubs.opengroup.org/onlinepubs/009695399/functions/rename.html: + // "Some implementations mark for update the st_ctime field of renamed + // files + // and some do not." + // => XtreemFS does so, i.e. update the client's cache, too. + metadataCache.updateStatTime(newPath, response.getTimestampS(), Setattrs.SETATTR_CTIME.getNumber()); + + // 4. Rename path in all open FileInfo objects. + for (Entry entry : openFileTable.entrySet()) { + entry.getValue().renamePath(path, newPath); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.xtreemfs.common.libxtreemfs.Volume#createDirectory(org.xtreemfs.foundation.pbrpc.generatedinterfaces + * .RPC.UserCredentials, java.lang.String, int, boolean) + */ + @Override + public void createDirectory(UserCredentials userCredentials, String path, int mode, boolean recursive) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + if (recursive) { + if (path.equals("/")) { + return; + } + if (path.endsWith("/")) { + path = path.substring(0, path.length() - 1); + } + final String parent = path.substring(0, path.lastIndexOf("/")); + if (isDirectory(userCredentials, parent) || parent.isEmpty()) { + createDirectory(userCredentials, path, mode, false); + } else { + createDirectory(userCredentials, parent, mode, true); + createDirectory(userCredentials, path, mode, false); + } + } else { + mkdirRequest request = mkdirRequest.newBuilder().setVolumeName(volumeName).setPath(path) + .setMode(mode).build(); + + timestampResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, mkdirRequest input) + throws IOException { + return mrcServiceClient.mkdir(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + String parentDir = Helper.resolveParentDirectory(path); + metadataCache.updateStatTime(path, response.getTimestampS(), Setattrs.SETATTR_CTIME.getNumber() + | Setattrs.SETATTR_MTIME.getNumber()); + // TODO: Retrieve stat as optional member of openResponse instead + // and update cached DirectoryEntries accordingly. + metadataCache.invalidateDirEntries(parentDir); + } + } + + private boolean isDirectory(UserCredentials userCredentials, String path) throws PosixErrorException, + IOException, AddressToUUIDNotFoundException { + try { + Stat stat = getAttr(userCredentials, path); + return (stat.getMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFDIR.getNumber()) > 0; + } catch (PosixErrorException pee) { + if (pee.getPosixError().equals(POSIXErrno.POSIX_ERROR_ENOENT)) { + return false; + } else { + throw pee; + } + } + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#createDirectory(org.xtreemfs. + * foundation.pbrpc.generatedinterfaces .RPC.UserCredentials, java.lang.String, int) + */ + @Override + public void createDirectory(UserCredentials userCredentials, String path, int mode) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + this.createDirectory(userCredentials, path, mode, false); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#removeDirectory(org.xtreemfs. + * foundation.pbrpc.generatedinterfaces .RPC.UserCredentials, java.lang.String) + */ + @Override + public void removeDirectory(UserCredentials userCredentials, String path) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + rmdirRequest request = rmdirRequest.newBuilder().setVolumeName(volumeName).setPath(path).build(); + + timestampResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, rmdirRequest input) + throws IOException { + return mrcServiceClient.rmdir(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + // Invalidate Metadatacache. + String parentDir = Helper.resolveParentDirectory(path); + metadataCache.updateStatTime(parentDir, response.getTimestampS(), Setattrs.SETATTR_CTIME.getNumber() + | Setattrs.SETATTR_MTIME.getNumber()); + metadataCache.invalidatePrefix(path); + metadataCache.invalidateDirEntry(path, Helper.getBasename(path)); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#readDir(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, long, long, boolean) + */ + @Override + public DirectoryEntries readDir(UserCredentials userCredentials, String path, int offset, int count, + boolean namesOnly) throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + DirectoryEntries result = null; + if (count == 0) { + count = Integer.MAX_VALUE - offset - 1; + } + + // Try to get DirectoryEntries from cache + result = metadataCache.getDirEntries(path, offset, count); + if (result != null) { + return result; + } + + DirectoryEntries.Builder dirEntriesBuilder = DirectoryEntries.newBuilder(); + + // Process large requests in multiples of readdirChunkSize. + for (int currentOffset = offset; currentOffset < offset + count; currentOffset += volumeOptions + .getReaddirChunkSize()) { + + int limitDirEntriesCount = (currentOffset > offset + count) ? (currentOffset - offset - count) + : volumeOptions.getReaddirChunkSize(); + + readdirRequest request = readdirRequest.newBuilder().setPath(path).setVolumeName(volumeName) + .setNamesOnly(namesOnly).setKnownEtag(0).setSeenDirectoryEntriesCount(currentOffset) + .setLimitDirectoryEntriesCount(limitDirEntriesCount).build(); + + DirectoryEntries readDirResponse = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, + authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, readdirRequest input) + throws IOException { + return mrcServiceClient.readdir(server, authHeader, userCreds, input); + } + }); + + assert (readDirResponse != null); + + dirEntriesBuilder.addAllEntries(readDirResponse.getEntriesList()); + + // Break if this is the last chunk. + if (dirEntriesBuilder.getEntriesCount() < (currentOffset + volumeOptions.getReaddirChunkSize())) { + break; + } + } + + // TODO: Merge possible pending file size updates of files into + // the stat entries of listed files. + + // Cache the first stat buffers that fit into the cache. + int minimum = // + (volumeOptions.getMetadataCacheSize() > dirEntriesBuilder.getEntriesCount()) // + ? dirEntriesBuilder.getEntriesCount() + : volumeOptions.getMetadataCacheSize(); + + for (int i = 0; i < minimum; i++) { + if (dirEntriesBuilder.getEntries(i).hasStbuf()) { + if (dirEntriesBuilder.getEntries(i).getStbuf().getNlink() > 1) { // Do not cache hard links. + metadataCache.invalidate(path); + } else { + metadataCache.updateStat( + Helper.concatenatePath(path, dirEntriesBuilder.getEntries(i).getName()), + dirEntriesBuilder.getEntries(i).getStbuf()); + } + } + } + + // Cache the result if it's the complete directory. + // We can't tell for sure whether result contains all directory entries + // if + // it's size is not less than the requested "count". + // TODO: Cache only names and no stat entries and remove names_only + // condition. + // TODO: Set an upper bound of dentries, otherwise don't cache it. + + result = dirEntriesBuilder.build(); + + if (!namesOnly && offset == 0 && result.getEntriesCount() < count) { + metadataCache.updateDirEntries(path, result); + } + return result; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#listXAttrs(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces .RPC.UserCredentials, java.lang.String) + */ + @Override + public listxattrResponse listXAttrs(UserCredentials userCredentials, String path) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + return listXAttrs(userCredentials, path, true); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#listXAttrs(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces .RPC.UserCredentials, java.lang.String, boolean) + */ + @Override + public listxattrResponse listXAttrs(UserCredentials userCredentials, String path, boolean useCache) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + // Check if information was cached. + listxattrResponse response = null; + if (useCache) { + response = metadataCache.getXAttrs(path); + if (response != null) { + return response; + } + } + + listxattrRequest request = listxattrRequest.newBuilder().setVolumeName(volumeName).setPath(path) + .setNamesOnly(false).build(); + + response = RPCCaller. syncCall(SERVICES.MRC, userCredentials, + authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, listxattrRequest input) + throws IOException { + return mrcServiceClient.listxattr(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + metadataCache.updateXAttrs(path, response); + + return response; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#setXAttr( + * org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials, + * org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth, + * java.lang.String, java.lang.String, java.lang.String, + * org.xtreemfs.pbrpc.generatedinterfaces.MRC.XATTR_FLAGS) + */ + @Override + public void setXAttr(UserCredentials userCredentials, Auth auth, String path, String name, String value, + XATTR_FLAGS flags) throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + setxattrRequest request = setxattrRequest.newBuilder().setVolumeName(volumeName).setPath(path) + .setName(name).setValue(value).setFlags(flags.getNumber()).build(); + + timestampResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, auth, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, setxattrRequest input) + throws IOException { + return mrcServiceClient.setxattr(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + metadataCache.updateXAttr(path, name, value); + } + + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#setXAttr(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, java.lang.String, java.lang.String, + * org.xtreemfs.pbrpc.generatedinterfaces.MRC.XATTR_FLAGS) + */ + @Override + public void setXAttr(UserCredentials userCredentials, String path, String name, String value, + XATTR_FLAGS flags) throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + setxattrRequest request = setxattrRequest.newBuilder().setVolumeName(volumeName).setPath(path) + .setName(name).setValue(value).setFlags(flags.getNumber()).build(); + + timestampResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, setxattrRequest input) + throws IOException { + return mrcServiceClient.setxattr(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + metadataCache.updateXAttr(path, name, value); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#getXAttr(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces.RPC .UserCredentials, java.lang.String, java.lang.String, java.lang.String) + */ + @Override + public String getXAttr(UserCredentials userCredentials, String path, String name) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + boolean xtreemfsAttrRequest = name.substring(0, 9).equals("xtreemfs."); + + if (xtreemfsAttrRequest) { + // Retrive only the value of the requested attribute, not the whole + // list. + getxattrRequest request = getxattrRequest.newBuilder().setVolumeName(volumeName).setPath(path) + .setName(name).build(); + + getxattrResponse response = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, getxattrRequest input) + throws IOException { + return mrcServiceClient.getxattr(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + if (response.hasValue()) { + return response.getValue(); + } else { + return null; + } + + } else { + // No "xtreemfs." attribute, lookup metadata cache. + Tupel cachedXattr = metadataCache.getXAttr(path, name); + if (cachedXattr.getFirst() == null) { + // Xattr not found in cache + if (cachedXattr.getSecond()) { + // All attributes were cached but the requested attribute + // was not found, + // i.e. it won't exist on the server. + return null; + } + } + + // If not found in metadatacache retrieve the whole list when attrs + // weren't cached. + listxattrResponse xattrList = listXAttrs(userCredentials, path); + if (xattrList.getXattrsCount() > 0) { + for (XAttr xattr : xattrList.getXattrsList()) { + if (xattr.getName().equals(name)) { + return xattr.getValue(); + } + } + } + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#getXAttrSize(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces .RPC.UserCredentials, java.lang.String, java.lang.String, int) + */ + @Override + public int getXAttrSize(UserCredentials userCredentials, String path, String name) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + // Try to get it from cache first. + // We also return the size of cached "xtreemfs." attributes. However, + // the actual size may differ as getXAttr() does never return "xtreemfs." + // attributes from the cache. + boolean xtreemfsAttributeRequested; + if (name.length() >= 9) { + xtreemfsAttributeRequested = name.substring(0, 9).equals("xtreemfs."); + } else { + xtreemfsAttributeRequested = false; + } + + // Differ between "xtreeemfs." attributes and user attributes. + if (xtreemfsAttributeRequested) { + // Always retrive from the server + String attr = getXAttr(userCredentials, path, name); + return attr.length(); + } else { + // user attribute + Tupel cachedXattrSize = metadataCache.getXAttrSize(path, name); + + // valid user attribute was found in cache + if (cachedXattrSize.getFirst() != 0) { + return cachedXattrSize.getFirst(); + } + + // no valid user attribute was found in cache, but Xattrs for this + // path where cached. + if (cachedXattrSize.getSecond()) { + return -1; + } + + // Retrive complete list of xattrs. + listxattrResponse xattrList = listXAttrs(userCredentials, path); + if (xattrList.getXattrsCount() > 0) { + for (XAttr xattr : xattrList.getXattrsList()) { + if (xattr.getName().equals(name)) { + return xattr.getValue().length(); + } + } + } + return -1; + } + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#removeXAttr(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces .RPC.UserCredentials, java.lang.String, java.lang.String) + */ + @Override + public void removeXAttr(UserCredentials userCredentials, String path, String name) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + removexattrRequest request = removexattrRequest.newBuilder().setVolumeName(volumeName).setPath(path) + .setName(name).build(); + + RPCCaller. syncCall(SERVICES.MRC, userCredentials, authBogus, + volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, removexattrRequest input) + throws IOException { + return mrcServiceClient.removexattr(server, authHeader, userCreds, input); + } + }); + metadataCache.invalidateXAttr(path, name); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#addReplica(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces .RPC.UserCredentials, java.lang.String, + * org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica) + */ + @Override + public void addReplica(UserCredentials userCredentials, String path, Replica newReplica) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + xtreemfs_replica_addRequest request = xtreemfs_replica_addRequest.newBuilder() + .setVolumeName(volumeName).setPath(path).setNewReplica(newReplica).build(); + + RPCCaller. syncCall(SERVICES.MRC, userCredentials, + authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @SuppressWarnings("unchecked") + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, xtreemfs_replica_addRequest input) throws IOException { + return mrcServiceClient.xtreemfs_replica_add(server, authHeader, userCreds, input); + } + }); + + // Renew the local XLocSet by reopening the file. + // TODO(jdillmann): Return the updated XLocSet as a response to the addReplicaOperation. + AdminFileHandle fileHandle = openFile(userCredentials, path, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + + // Only the files with the RONLY policy have to be pinged. WqRq, WaR1, WaRa policies handled on the MRC side by + // the XLocSetCoordinator. + if (fileHandle.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)) { + // Trigger the replication at this point by reading at least one byte. + fileHandle.pingReplica(userCredentials, newReplica.getOsdUuids(0)); + } + fileHandle.close(); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#listReplicas(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces .RPC.UserCredentials, java.lang.String) + */ + @Override + public Replicas listReplicas(UserCredentials userCredentials, String path) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + xtreemfs_get_xlocsetRequest request = xtreemfs_get_xlocsetRequest.newBuilder() + .setVolumeName(volumeName).setPath(path).build(); + + XLocSet xlocset = RPCCaller. syncCall(SERVICES.MRC, + userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, false, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, xtreemfs_get_xlocsetRequest input) throws IOException { + return mrcServiceClient.xtreemfs_get_xlocset(server, authHeader, userCreds, input); + } + }); + + assert (xlocset != null); + + Replicas.Builder replicas = Replicas.newBuilder(); + replicas.addAllReplicas(xlocset.getReplicasList()); + + return replicas.build(); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#removeReplica(org.xtreemfs.foundation + * .pbrpc.generatedinterfaces .RPC.UserCredentials, java.lang.String, java.lang.String) + */ + @Override + public void removeReplica(UserCredentials userCredentials, String path, String osdUuid) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + // remove the replica + xtreemfs_replica_removeRequest request = xtreemfs_replica_removeRequest.newBuilder() + .setVolumeName(volumeName).setPath(path).setOsdUuid(osdUuid).build(); + + FileCredentials response = RPCCaller. syncCall( + SERVICES.MRC, userCredentials, authBogus, volumeOptions, uuidResolver, mrcUUIDIterator, + false, request, new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, xtreemfs_replica_removeRequest input) + throws IOException { + return mrcServiceClient.xtreemfs_replica_remove(server, authHeader, userCreds, input); + } + }); + + assert (response != null); + + // Now unlink the replica at the OSD. + UUIDIterator osdUuidIterator = new UUIDIterator(); + osdUuidIterator.addUUID(osdUuid); + + unlink_osd_Request request2 = unlink_osd_Request.newBuilder() + .setFileId(response.getXcap().getFileId()).setFileCredentials(response).build(); + + RPCCaller. syncCall(SERVICES.OSD, userCredentials, authBogus, + volumeOptions, uuidResolver, osdUuidIterator, false, request2, + new CallGenerator() { + @SuppressWarnings("unchecked") + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, unlink_osd_Request input) throws IOException { + return osdServiceClient.unlink(server, authHeader, userCreds, input); + } + }); + + // Update the local XLocSet cached at FileInfo if it exists. + if (openFileTable.containsKey(response.getXcap().getFileId())) { + // File has already been opened: refresh the xlocset. + // TODO(jdillmann): Return the new XLocSet and the replicateOnClose flag with the response. + FileHandle file = openFile(userCredentials, path, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + file.close(); + } + } + + @Override + public void removeACL(UserCredentials userCreds, String path, String user) throws IOException { + Set elements = new HashSet(); + elements.add(user); + removeACL(userCreds, path, elements); + } + + @Override + public void removeACL(UserCredentials userCreds, String path, Set aclEntries) throws IOException { + // add all entries from the given list + for (String entity : aclEntries) { + if (!entity.equals("u:") && !entity.equals("g:") && !entity.equals("o:") && !entity.equals("m:")) { + setXAttr(userCreds, path, "xtreemfs.acl", "x " + entity, XATTR_FLAGS.XATTR_FLAGS_REPLACE); + } + } + } + + @Override + public void setACL(UserCredentials userCreds, String path, String user, String accessrights) + throws IOException { + HashMap elements = new HashMap(); + elements.put(user, accessrights); + setACL(userCreds, path, elements); + } + + @Override + public void setACL(UserCredentials userCreds, String path, Map aclEntries) + throws IOException { + // add all entries from the given list + for (Entry entry : aclEntries.entrySet()) + setXAttr(userCreds, path, "xtreemfs.acl", "m " + entry.getKey() + ":" + entry.getValue(), + XATTR_FLAGS.XATTR_FLAGS_REPLACE); + } + + @SuppressWarnings("unchecked") + @Override + public Map listACL(UserCredentials userCreds, String path) throws IOException { + try { + String aclAsJSON = getXAttr(userCreds, path, "xtreemfs.acl"); + return (Map) JSONParser.parseJSON(new JSONString(aclAsJSON)); + } catch (JSONException e) { + throw new IOException(e); + } + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#getSuitableOSDs(org.xtreemfs. + * foundation.pbrpc.generatedinterfaces .RPC.UserCredentials, java.lang.String, int, java.util.List) + */ + @Override + public List getSuitableOSDs(UserCredentials userCredentials, String path, int numberOfOsds) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + xtreemfs_get_suitable_osdsRequest request = xtreemfs_get_suitable_osdsRequest.newBuilder() + .setVolumeName(volumeName).setPath(path).setNumOsds(numberOfOsds).build(); + + xtreemfs_get_suitable_osdsResponse response = RPCCaller + . syncCall( + SERVICES.MRC, + userCredentials, + authBogus, + volumeOptions, + uuidResolver, + mrcUUIDIterator, + false, + request, + new CallGenerator() { + @Override + public RPCResponse executeCall( + InetSocketAddress server, Auth authHeader, UserCredentials userCreds, + xtreemfs_get_suitable_osdsRequest input) throws IOException { + return mrcServiceClient.xtreemfs_get_suitable_osds(server, authHeader, + userCreds, input); + } + }); + + assert (response != null); + + return response.getOsdUuidsList(); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.common.libxtreemfs.Volume#setDefaultReplicationPolicy(org.xtreemfs.foundation.pbrpc. + * generatedinterfaces.RPC.UserCredentials, java.lang.String, java.lang.String, int, int) + */ + @Override + public void setDefaultReplicationPolicy(UserCredentials userCredentials, String directory, + String replicationPolicy, int replicationFactor, int replicationFlags) throws IOException, + PosixErrorException, AddressToUUIDNotFoundException { + String JSON = "{ " + "\"replication-factor\": " + String.valueOf(replicationFactor) + "," + + "\"update-policy\": " + "\"" + replicationPolicy + "\"," + "\"replication-flags\": " + + String.valueOf(replicationFlags) + " }"; + setXAttr(userCredentials, directory, XTREEMFS_DEFAULT_RP, JSON, XATTR_FLAGS.XATTR_FLAGS_CREATE); + } + + @SuppressWarnings("unchecked") + public ReplicationPolicy getDefaultReplicationPolicy(UserCredentials userCredentials, String directory) + throws IOException, PosixErrorException, AddressToUUIDNotFoundException { + + Object replicationPolicyObject; + Map replicationPolicyMap; + + try { + String rpAsJSON = getXAttr(userCredentials, directory, XTREEMFS_DEFAULT_RP); + replicationPolicyObject = JSONParser.parseJSON(new JSONString(rpAsJSON)); + } catch (JSONException e) { + throw new IOException(e); + } + + try { + replicationPolicyMap = (Map) replicationPolicyObject; + } catch (ClassCastException e) { + throw new IOException("JSON response does not contain a Map.", e); + } + + if (!(replicationPolicyMap.containsKey("replication-factor") + && replicationPolicyMap.containsKey("update-policy") + && replicationPolicyMap.containsKey("replication-flags"))) { + throw new IOException("Incomplete JSON response from MRC."); + } + + final String updatePolicy; + final int replicationFactor; + final int replicationFlags; + try { + // The JSONParser returns every number as a Long object. + replicationFlags = ((Long) replicationPolicyMap.get("replication-flags")).intValue(); + replicationFactor = ((Long) replicationPolicyMap.get("replication-factor")).intValue(); + updatePolicy = (String) replicationPolicyMap.get("update-policy"); + } catch (ClassCastException e) { + throw new IOException(e); + } + + return new ReplicationPolicyImplementation(updatePolicy, replicationFactor, replicationFlags); + } + + /** + * Called by FileHandle.close() to remove fileHandle from the list. + */ + protected void closeFile(long fileId, FileInfo fileInfo, FileHandleImplementation fileHandle) { + // Remove file_info if it has no more open file handles. + if (fileInfo.decreaseReferenceCount() == 0) { + // The last file handle of this file was closed: Release all locks. + // All locks for the process of this file handle have to be released. + try { + fileInfo.releaseAllLocks(fileHandle); + } catch (XtreemFSException e) { + // Ignore errors. + } + + fileInfo.waitForPendingFileSizeUpdates(); + openFileTable.remove(fileId); + + // Write back the OSDWriteResponse to the stat cache if there is one. + OSDWriteResponse response = fileInfo.getOSDWriteResponse(); + if (response != null) { + String path = fileInfo.getPath(); + metadataCache.updateStatFromOSDWriteResponse(path, response); + } + } + } + + /** + * Returns FileInfo object. Looking for it at first in the openFileTable and if it is not found there it + * creates a new one. + * + * @return FileInfo + */ + private FileInfo getOrCreateFileInfo(long fileId, String path, boolean replicateOnClose, XLocSet xlocset) { + FileInfo fileInfo = openFileTable.get(fileId); + + if (fileInfo != null) { + fileInfo.updateXLocSetAndRest(xlocset, replicateOnClose); + return fileInfo; + } else { + // File has not been opened yet, add it. + fileInfo = new FileInfo(this, fileId, path, replicateOnClose, xlocset, clientUuid); + openFileTable.put(fileId, fileInfo); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "Created a new FileInfo" + + " object for the fileId: %s", fileId); + } + return fileInfo; + } + } + + protected UUIDIterator getMrcUuidIterator() { + return this.mrcUUIDIterator; + } + + protected UUIDResolver getUUIDResolver() { + return this.uuidResolver; + } + + protected MRCServiceClient getMrcServiceClient() { + return this.mrcServiceClient; + } + + protected OSDServiceClient getOsdServiceClient() { + return this.osdServiceClient; + } + + protected Options getOptions() { + return this.volumeOptions; + } + + protected ConcurrentHashMap getOpenFileTable() { + return this.openFileTable; + } + + protected Auth getAuthBogus() { + return this.authBogus; + } + + protected UserCredentials getUserCredentialsBogus() { + return this.userCredentialsBogus; + } + + protected Map getStripeTranslators() { + return this.stripeTranslators; + } + + protected MetadataCache getMetaDataCache() { + return this.metadataCache; + } + + /* + * (non-Javadoc) + * + * @see + * org.xtreemfs.common.libxtreemfs.Volume#getStripeLocations(org.xtreemfs.foundation.pbrpc.generatedinterfaces + * .RPC.UserCredentials, java.lang.String, int, int) + */ + @Override + public List getStripeLocations(UserCredentials userCredentials, String path, + long startSize, long length) throws IOException, PosixErrorException, + AddressToUUIDNotFoundException { + FileHandleImplementation fileHandle = (FileHandleImplementation) this.openFile(userCredentials, path, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + XLocSet xLocs = fileHandle.getXlocSet(); + fileHandle.close(); + + long stripeSize = xLocs.getReplicas(0).getStripingPolicy().getStripeSize() * 1024; + long indexOfFirstStripeToConsider = (startSize / stripeSize); + long remainingLengthOfFirstStripe = Math.min(length, stripeSize - (startSize % stripeSize)); + int numberOfStrips = (int) (length / stripeSize + 1); + + List stripeLocations = new ArrayList(numberOfStrips); + // add first Stripe + ArrayList uuids = getUuidsForStripeFromReplicas(xLocs.getReplicasList(), + indexOfFirstStripeToConsider); + ArrayList hostnames = resolveHostnamesFromUuids(uuids); + stripeLocations.add(new StripeLocation(startSize, remainingLengthOfFirstStripe, uuids + .toArray(new String[uuids.size()]), hostnames.toArray(new String[hostnames.size()]))); + + for (long index = indexOfFirstStripeToConsider + 1; index * stripeSize < startSize + length; index++) { + uuids = getUuidsForStripeFromReplicas(xLocs.getReplicasList(), index); + hostnames = resolveHostnamesFromUuids(uuids); + stripeLocations.add(new StripeLocation(index * stripeSize, Math.min(stripeSize, startSize + + length - index * stripeSize), uuids.toArray(new String[uuids.size()]), hostnames + .toArray(new String[hostnames.size()]))); + } + return stripeLocations; + } + + @Override + public long getNumObjects(UserCredentials userCredentials, String path) throws IOException { + StripingPolicy stripingPolicy = this.listReplicas(userCredentials, path).getReplicas(0) + .getStripingPolicy(); + Stat fileAttr = this.getAttr(userCredentials, path); + return Helper.getNumObjects(userCredentials, fileAttr, stripingPolicy); + } + + private ArrayList resolveHostnamesFromUuids(ArrayList uuids) + throws AddressToUUIDNotFoundException { + ArrayList hostnames = new ArrayList(); + for (int i = 0; i < uuids.size(); i++) { + String hostname = uuidResolver.uuidToAddress(uuids.get(i)); + hostname = hostname.substring(0, hostname.lastIndexOf(':')); + if (isIpAddress(hostname)) { + try { + InetSocketAddress address = new InetSocketAddress(InetAddress.getByName(hostname), 0); + hostname = address.getHostName(); + } catch (Exception e) { + hostname = null; + } + + if (hostname == null) { + // if hostname can't be resolved correctly, delete corresponding uuid. Also decrement + // the counter i to not skip entries in the uuid list! + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, + "Couldn't resolve hostname for uuid %s", uuids.get(i)); + } + uuids.remove(i); + i--; + } else { + hostnames.add(hostname); + } + } else { + hostnames.add(hostname); + } + } + return hostnames; + } + + private ArrayList getUuidsForStripeFromReplicas(List replicasList, long stripeIndex) { + ArrayList uuids = new ArrayList(); + for (Replica replica : replicasList) { + int osdIndex = (int) stripeIndex % replica.getStripingPolicy().getWidth(); + uuids.add(replica.getOsdUuids(osdIndex)); + } + return uuids; + } + + private boolean isIpAddress(String hostname) { + // TODO: Move this Function to a place where it can be reused. + final String IPADDRESS_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"; + + Pattern pattern = Pattern.compile(IPADDRESS_PATTERN); + return pattern.matcher(hostname).matches(); + } + + @Override + public String getOSDSelectionPolicy(UserCredentials userCreds) throws IOException { + return getXAttr(userCreds, "/", OSD_SELECTION_POLICY); + } + + @Override + public void setOSDSelectionPolicy(UserCredentials userCreds, String policies) throws IOException { + setXAttr(userCreds, "/", OSD_SELECTION_POLICY, policies, XATTR_FLAGS.XATTR_FLAGS_REPLACE); + } + + @Override + public String getReplicaSelectionPolicy(UserCredentials userCreds) throws IOException { + return getXAttr(userCreds, "/", REPLICA_SELECTION_POLICY); + } + + @Override + public void setReplicaSelectionPolicy(UserCredentials userCreds, String policies) throws IOException { + setXAttr(userCreds, "/", REPLICA_SELECTION_POLICY, policies, XATTR_FLAGS.XATTR_FLAGS_REPLACE); + } + + @Override + public void setPolicyAttribute(UserCredentials userCreds, String attribute, String value) throws IOException { + setXAttr(userCreds, "/", MRCHelper.XTREEMFS_POLICY_ATTR_PREFIX + attribute, value, XATTR_FLAGS.XATTR_FLAGS_REPLACE); + } + + public String getVolumeName() { + return volumeName; + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/WriteOperation.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/WriteOperation.java new file mode 100644 index 0000000..8c54d13 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/WriteOperation.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; + + +/** + * + *
    + * Nov 2, 2011 + */ +public class WriteOperation { + + private long objNumber; + + private int osdOffset; + + private int reqSize; + + private int reqOffset; + + private ReusableBuffer buf; + + protected WriteOperation(long objNumber, int osdOffset, int reqSize, int reqOffset, ReusableBuffer buf) { + this.objNumber = objNumber; + this.osdOffset = osdOffset; + this.reqSize = reqSize; + this.reqOffset = reqOffset; + this.buf = buf; + } + + protected long getObjNumber() { + return objNumber; + } + + + public int getOsdOffset() { + return osdOffset; + } + + protected int getReqSize() { + return reqSize; + } + + protected int getReqOffset() { + return reqOffset; + } + + + protected ReusableBuffer getReqData() { + return buf; + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/AddressToUUIDNotFoundException.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/AddressToUUIDNotFoundException.java new file mode 100644 index 0000000..0b1f4bc --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/AddressToUUIDNotFoundException.java @@ -0,0 +1,14 @@ +package org.xtreemfs.common.libxtreemfs.exceptions; + +public class AddressToUUIDNotFoundException extends XtreemFSException { + + public AddressToUUIDNotFoundException(String uuid) { + super("UUID: service not found for uuid " + uuid); + } + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InternalServerErrorException.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InternalServerErrorException.java new file mode 100644 index 0000000..e26788c --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InternalServerErrorException.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs.exceptions; + +/** + * + *
    Nov 22, 2011 + */ +public class InternalServerErrorException extends XtreemFSException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * + */ + public InternalServerErrorException(String errorMsg) { + super(errorMsg); + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InvalidChecksumException.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InvalidChecksumException.java new file mode 100644 index 0000000..59e818d --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InvalidChecksumException.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2012 by Lukas Kairies, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs.exceptions; + +public class InvalidChecksumException extends XtreemFSException { + + private static final long serialVersionUID = 1L; + + public InvalidChecksumException(String errorMsg) { + super(errorMsg); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InvalidViewException.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InvalidViewException.java new file mode 100644 index 0000000..8fd0ecc --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/InvalidViewException.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2013 by Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs.exceptions; + +import org.xtreemfs.common.libxtreemfs.UUIDIterator; + +/** + * This exception is thrown, when a request was denied due to an outdated view (XLocSet).
    + * The client should reload the view (XLocSet), refresh {@link UUIDIterator}s based on it and retry the request. + **/ +public class InvalidViewException extends XtreemFSException { + + private static final long serialVersionUID = 1L; + + public InvalidViewException(String errorMsg) { + super(errorMsg); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/PosixErrorException.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/PosixErrorException.java new file mode 100644 index 0000000..7bd6814 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/PosixErrorException.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs.exceptions; + +import java.io.IOException; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; + +public class PosixErrorException extends XtreemFSException { + /** + * + */ + private static final long serialVersionUID = 1L; + + private POSIXErrno posixError; + + public PosixErrorException(String message) { + super(message); + } + public PosixErrorException(POSIXErrno posixError, String message) { + super(message); + this.posixError = posixError; + } + + public POSIXErrno getPosixError() { + return this.posixError; + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/UUIDIteratorListIsEmpyException.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/UUIDIteratorListIsEmpyException.java new file mode 100644 index 0000000..e991be8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/UUIDIteratorListIsEmpyException.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs.exceptions; + +/** + * {@link Exception} that is thrown when the UUIDIterator list reached its end. + *
    Sep 3, 2011 + */ +@SuppressWarnings("serial") +public class UUIDIteratorListIsEmpyException extends XtreemFSException { + + public UUIDIteratorListIsEmpyException(String message) { + super(message); + } +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/UUIDNotInXlocSetException.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/UUIDNotInXlocSetException.java new file mode 100644 index 0000000..f32a3d2 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/UUIDNotInXlocSetException.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs.exceptions; + +/** + * + * Thrown if a given UUID was not found in the xlocset of a file. + */ +public class UUIDNotInXlocSetException extends XtreemFSException { + + /** + * @param errorMsg + */ + public UUIDNotInXlocSetException(String errorMsg) { + super(errorMsg); + } + + private static final long serialVersionUID = 1L; + +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/VolumeNotFoundException.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/VolumeNotFoundException.java new file mode 100644 index 0000000..81ecad2 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/VolumeNotFoundException.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs.exceptions; + +/** + * + *
    + * Sep 2, 2011 + */ +@SuppressWarnings("serial") +public class VolumeNotFoundException extends XtreemFSException { + + /** + * + */ + public VolumeNotFoundException(String volumeName) { + super("Volume not found: " + volumeName); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/XtreemFSException.java b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/XtreemFSException.java new file mode 100644 index 0000000..6c3391c --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/libxtreemfs/exceptions/XtreemFSException.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs.exceptions; + +import java.io.IOException; + +/** + * + *
    + * Nov 22, 2011 + */ +public class XtreemFSException extends IOException { + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * + */ + public XtreemFSException(String errorMsg) { + super(errorMsg); + } +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/DirImpl.java b/java/servers/src/org/xtreemfs/common/monitoring/DirImpl.java new file mode 100644 index 0000000..49e3b6b --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/DirImpl.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + + +package org.xtreemfs.common.monitoring; + +import javax.management.MBeanServer; + +import org.xtreemfs.common.monitoring.StatusMonitor.ServiceTypes; +import org.xtreemfs.common.monitoring.generatedcode.Dir; + +import com.sun.management.snmp.SnmpStatusException; + + + + +/** + * This class represents the monitoring information exposed by the SNMP agent regarding to the + * Directory Service. + * + */ +@SuppressWarnings("serial") +public class DirImpl extends Dir { + + private StatusMonitor statusMonitor; + + public DirImpl(XTREEMFS_MIBImpl myMib, StatusMonitor statusMonitor) { + super(myMib); + + AddressMappingCount = 0; + ServiceCount = 0; + + this.statusMonitor = statusMonitor; + // Set a reference to this Object to be able to access it within + // the application + statusMonitor.setDirGroup(this); + } + + public DirImpl(XTREEMFS_MIBImpl myMib, MBeanServer server, StatusMonitor statusMonitor) { + super(myMib, server); + + AddressMappingCount = 0; + ServiceCount = 0; + + this.statusMonitor = statusMonitor; + // Set a reference to this Object to be able to access it within + // the application + statusMonitor.setDirGroup(this); + } + + + /** + * This method will be called when a AddressMapping is registered at the DIR. + **/ + protected void addressMappingAdded() { + AddressMappingCount++; + } + + /** + * This method will be called when a AddressMapping is deregistered at the DIR. + **/ + protected void addressMappingDeleted() { + AddressMappingCount--; + } + + /** + * This method will be called when a Service is registered at the DIR. + **/ + protected void serviceRegistered() { + ServiceCount++; + } + + /** + * This method will be called when a Service is deregistered at the DIR. + **/ + protected void serviceDeregistered() { + ServiceCount--; + } + + @Override + public Integer getServiceCount() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.DIR)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + return ServiceCount; + } + + @Override + public Integer getAddressMappingCount() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.DIR)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + return AddressMappingCount; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/GeneralImpl.java b/java/servers/src/org/xtreemfs/common/monitoring/GeneralImpl.java new file mode 100644 index 0000000..18a2cfe --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/GeneralImpl.java @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.monitoring; + +import javax.management.MBeanServer; + +import org.xtreemfs.babudb.BabuDBFactory; +import org.xtreemfs.common.HeartbeatThread; +import org.xtreemfs.common.monitoring.StatusMonitor.ServiceTypes; +import org.xtreemfs.common.monitoring.generatedcode.General; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceConstants; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +import com.sun.management.snmp.SnmpStatusException; + +/** + * This class represents the monitoring information exposed by the SNMP agent + * regarding to all services. + * + *
    + * May 5, 2011 + * + * @author bzcseife + */ +@SuppressWarnings("serial") +public class GeneralImpl extends General { + + private StatusMonitor statusMonitor; + + public GeneralImpl(XTREEMFS_MIBImpl myMib, StatusMonitor statusMonitor) { + super(myMib); + + this.statusMonitor = statusMonitor; + } + + public GeneralImpl(XTREEMFS_MIBImpl myMib, MBeanServer server, StatusMonitor statusMonitor) { + super(myMib, server); + + this.statusMonitor = statusMonitor; + + } + + @Override + public Long getJvmMaxMemory() throws SnmpStatusException { + return Runtime.getRuntime().maxMemory(); + } + + @Override + public Long getJvmUsedMemory() throws SnmpStatusException { + return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + } + + @Override + public Long getJvmFreeMemory() throws SnmpStatusException { + return Runtime.getRuntime().freeMemory(); + } + + @Override + public String getDatabaseVersion() throws SnmpStatusException { + return BabuDBFactory.BABUDB_VERSION; + } + + @Override + public Integer getTcpPort() throws SnmpStatusException { + if (statusMonitor.getInitiatingService().equals(ServiceTypes.DIR)) { + return statusMonitor.getDirConfig().getPort(); + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.MRC)) { + return statusMonitor.getMrcConfig().getPort(); + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + return statusMonitor.getOsdConfig().getPort(); + } + return -1; + } + + @Override + public Integer getDebugLevel() throws SnmpStatusException { + if (statusMonitor.getInitiatingService().equals(ServiceTypes.DIR)) { + return statusMonitor.getDirConfig().getDebugLevel(); + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.MRC)) { + return statusMonitor.getMrcConfig().getDebugLevel(); + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + return statusMonitor.getOsdConfig().getDebugLevel(); + } + throw new SnmpStatusException("Internal error. Couldn't fetch values."); + } + + @Override + public Integer getRpcInterface() throws SnmpStatusException { + if (statusMonitor.getInitiatingService().equals(ServiceTypes.DIR)) { + return DIRServiceConstants.INTERFACE_ID; + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.MRC)) { + return MRCServiceConstants.INTERFACE_ID; + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + return OSDServiceConstants.INTERFACE_ID; + } + throw new SnmpStatusException("Internal error. Couldn't fetch values."); + } + + @Override + public Integer getNumClientConnections() throws SnmpStatusException { + if (statusMonitor.getInitiatingService().equals(ServiceTypes.DIR)) { + return statusMonitor.getMasterDIR().getNumConnections(); + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.MRC)) { + return statusMonitor.getMasterMRC().getNumConnections(); + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + return statusMonitor.getMasterOSD().getNumClientConnections(); + } + throw new SnmpStatusException("Internal error. Couldn't fetch values."); + } + + @Override + public Long getNumPendingRequests() throws SnmpStatusException { + if (statusMonitor.getInitiatingService().equals(ServiceTypes.DIR)) { + return statusMonitor.getMasterDIR().getNumRequests(); + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.MRC)) { + return statusMonitor.getMasterMRC().getNumRequests(); + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + return statusMonitor.getMasterOSD().getPendingRequests(); + } + throw new SnmpStatusException("Internal error. Couldn't fetch values."); + } + + @Override + public Long getCurrentTime() { + return System.currentTimeMillis(); + } + + @Override + public String getServiceType() throws SnmpStatusException { + if (statusMonitor.getInitiatingService().equals(ServiceTypes.DIR)) { + return "DIR"; + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.MRC)) { + return "MRC"; + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + return "OSD"; + } + throw new SnmpStatusException("Internal error. Couldn't fetch values."); + } + + @Override + public String getIsRunning() throws SnmpStatusException { + if (statusMonitor.getInitiatingService().equals(ServiceTypes.DIR)) { + // TODO: Since the DIR don't have a heartbeatthread find a method to + // determine if + // the DIR is still alive. + return "ONLINE"; + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.MRC)) { + // calculate the difference between the last hearbeat an the current + // time. If these values + // differ too much, return OFFLINE. + long difference = System.currentTimeMillis() - statusMonitor.getMasterMRC().getLastHeartbeat(); + if (difference > 10 * HeartbeatThread.UPDATE_INTERVAL) { + return "OFFLINE"; + } else { + return "ONLINE"; + } + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + // calculate the difference between the last hearbeat an the current + // time. If these values + // differ too much, return OFFLINE. + long difference = System.currentTimeMillis() - statusMonitor.getMasterOSD().getLastHeartbeat(); + if (difference > 10 * HeartbeatThread.UPDATE_INTERVAL) { + return "OFFLINE"; + } else { + return "ONLINE"; + } + + } + throw new SnmpStatusException("Internal error. Couldn't fetch values."); + } + + @Override + public String getServiceUUID() throws SnmpStatusException { + if (statusMonitor.getInitiatingService().equals(ServiceTypes.DIR)) { + return statusMonitor.getDirConfig().getUUID().toString(); + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.MRC)) { + return statusMonitor.getMrcConfig().getUUID().toString(); + } + + if (statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + return statusMonitor.getOsdConfig().getUUID().toString(); + } + throw new SnmpStatusException("Internal error. Couldn't fetch values."); + } + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/common/monitoring/MrcImpl.java b/java/servers/src/org/xtreemfs/common/monitoring/MrcImpl.java new file mode 100644 index 0000000..e8879df --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/MrcImpl.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.monitoring; + +import javax.management.MBeanServer; + +import org.xtreemfs.common.monitoring.StatusMonitor.ServiceTypes; +import org.xtreemfs.common.monitoring.generatedcode.Mrc; + +import com.sun.management.snmp.SnmpStatusException; +import com.sun.management.snmp.agent.SnmpMib; + + +/** + * This class represents the monitoring information exposed by the SNMP agent regarding to the + * MRC Service. + */ +@SuppressWarnings("serial") +public class MrcImpl extends Mrc { + + + StatusMonitor statusMonitor = null; + + public MrcImpl(SnmpMib myMib, StatusMonitor statusMonitor) { + super(myMib); + + VolumeCount = 0; + + this.statusMonitor = statusMonitor; + // Set a reference to this Object to be able to access it within + // the application + statusMonitor.setMrcGroup(this); + } + + public MrcImpl(SnmpMib myMib, MBeanServer server, StatusMonitor statusMonitor) { + super(myMib, server); + + VolumeCount = 0; + + this.statusMonitor = statusMonitor; + // Set a reference to this Object to be able to access it within + // the application + statusMonitor.setMrcGroup(this); + } + + + + protected void volumeCreated() { + VolumeCount++; + } + + protected void volumeDeleted() { + VolumeCount--; + } + + @Override + public Integer getVolumeCount() throws SnmpStatusException { + if(!statusMonitor.getInitiatingService().equals(ServiceTypes.MRC)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + return VolumeCount; + } +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/OsdImpl.java b/java/servers/src/org/xtreemfs/common/monitoring/OsdImpl.java new file mode 100644 index 0000000..0a78416 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/OsdImpl.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.monitoring; + +import javax.management.MBeanServer; + +import org.xtreemfs.common.monitoring.StatusMonitor.ServiceTypes; +import org.xtreemfs.common.monitoring.generatedcode.Osd; + +import com.sun.management.snmp.SnmpStatusException; + + +/** + * This class represents the monitoring information exposed by the SNMP agent regarding to the + * OSD. + * + */ +@SuppressWarnings("serial") +public class OsdImpl extends Osd { + + private StatusMonitor statusMonitor; + + public OsdImpl(XTREEMFS_MIBImpl myMib, StatusMonitor statusMonitor) { + super(myMib); + this.statusMonitor = statusMonitor; + + // Set a reference to this Object to be able to access it within + // the application + statusMonitor.setOsdGroup(this); + } + + public OsdImpl(XTREEMFS_MIBImpl myMib, MBeanServer server, StatusMonitor statusMonitor) { + super(myMib, server); + this.statusMonitor = statusMonitor; + + // Set a reference to this Object to be able to access it within + // the application + statusMonitor.setOsdGroup(this); + } + + /** + * Setter for NumBytexTX(number of bytes transmitted) + */ + public void setNumBytesTX(long numBytesTX) { + NumBytesTX = numBytesTX; + } + + /** + * Setter for NumBytesRX(number of bytes received) + */ + public void setNumBytesRX(long numBytesRX) { + NumBytesRX = numBytesRX; + } + + /** + * Setter for NumReplBytesRX(number of bytes received which have to do something with replication) + */ + public void setNumReplBytesRX(long numReplBytesRX) { + NumReplBytesRX = numReplBytesRX; + } + + /** + * Setter for NumObjsTX(number of objects transmitted) + */ + public void setNumObjsTX(long numObjsTX) { + NumObjsTX = numObjsTX; + } + + /** + * Setter for NumObjsRX(number of objects received) + */ + public void setNumObjsRX(long numObjsRX) { + NumObjsRX = numObjsRX; + } + + /** + * Setter for getNumReplObjsRX(number of objects received which have to do something with + * replication + */ + public void setNumReplObjsRX(long numReplObjsRX) { + NumReplObjsRX = numReplObjsRX; + } + + @Override + public Integer getPreprocStageQueueLength() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + if (statusMonitor.getMasterOSD() != null) { + return statusMonitor.getMasterOSD().getPreprocStage().getQueueLength(); + } + return -1; + } + + @Override + public Integer getStorageStageQueueLength() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + if (statusMonitor.getMasterOSD() != null) { + return statusMonitor.getMasterOSD().getStorageStage().getQueueLength(); + } + return -1; + } + + @Override + public Integer getDeletionStageQueueLength() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + if (statusMonitor.getMasterOSD() != null) { + return statusMonitor.getMasterOSD().getDeletionStage().getQueueLength(); + } + return -1; + } + + @Override + public Long getFreeSpace() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + if (statusMonitor.getMasterOSD() != null) { + return statusMonitor.getMasterOSD().getFreeSpace(); + } + return -1l; + } + + @Override + public Integer getNumOpenFiles() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + if (statusMonitor.getMasterOSD() != null) { + return statusMonitor.getMasterOSD().getPreprocStage().getNumOpenFiles(); + } + return -1; + } + + @Override + public Long getNumDeletedFiles() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + if (statusMonitor.getMasterOSD() != null) { + return statusMonitor.getMasterOSD().getDeletionStage().getNumFilesDeleted(); + } + return -1l; + } + + @Override + public Long getNumBytesTX() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + return NumBytesTX; + } + + @Override + public Long getNumBytesRX() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + return NumBytesRX; + } + + @Override + public Long getNumReplBytesRX() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + return NumReplBytesRX; + } + + @Override + public Long getNumObjsTX() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + return NumObjsTX; + } + + @Override + public Long getNumReplObjsRX() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + return NumReplObjsRX; + } + + @Override + public Long getNumObjsRX() throws SnmpStatusException { + if (!statusMonitor.getInitiatingService().equals(ServiceTypes.OSD)) { + throw new SnmpStatusException(SnmpStatusException.noSuchName); + } + return NumObjsRX; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/StatusMonitor.java b/java/servers/src/org/xtreemfs/common/monitoring/StatusMonitor.java new file mode 100644 index 0000000..075d59e --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/StatusMonitor.java @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.monitoring; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.xtreemfs.common.monitoring.generatedcode.XTREEMFS_MIB; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.dir.DIRStatusListener; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.mrc.MRCConfig; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.MRCStatusListener; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.OSDStatusListener; + +import com.sun.management.comm.SnmpAdaptorServer; +import com.sun.management.snmp.IPAcl.JdmkAcl; + +/** + * + * + *
    + * May 19, 2011 + * + * @author bzcseife + */ +public class StatusMonitor implements DIRStatusListener, MRCStatusListener, OSDStatusListener { + + protected static enum ServiceTypes { + DIR, MRC, OSD + } + + private DIRConfig dirConfig = null; + private MRCConfig mrcConfig = null; + private OSDConfig osdConfig = null; + + private DIRRequestDispatcher masterDIR = null; + private MRCRequestDispatcher masterMRC = null; + private OSDRequestDispatcher masterOSD = null; + + /** + * The {@link SnmpAdaptorServer} representing the SNMP adaptor. + */ + private SnmpAdaptorServer snmpAdaptor = null; + + /** + * The MIB containing all SNMP related information + */ + private XTREEMFS_MIB xtfsmib = null; + + /** + * Reference to the DIR Implementation to access it + */ + private DirImpl dirGroup = null; + + /** + * Reference to the MRC implementation to access it + */ + private MrcImpl mrcGroup = null; + + /** + * Reference to the OSD implementation to access it + */ + private OsdImpl osdGroup = null; + + /** + * Saves what kind of service (DIR, MRC or OSD) uses this class. This is used in the General Group to know + * where to get specific information. + */ + private ServiceTypes initiatingService = null; + + /** + * Constructor when this class is running inside a DIR. + * + * @param dirReqDisp + * @param port + */ + public StatusMonitor(DIRRequestDispatcher dirReqDisp, int port) { + this(ServiceTypes.DIR, null, port, null); + this.masterDIR = dirReqDisp; + } + + /** + * Constructor when this class is running inside a DIR. + * + * @param dirReqDisp + * @param addr + * @param port + */ + public StatusMonitor(DIRRequestDispatcher dirReqDisp, InetAddress addr, int port) { + this(ServiceTypes.DIR, addr, port, null); + this.masterDIR = dirReqDisp; + } + + /** + * Constructor when this class is running inside a DIR. + * + * @param dirReqDisp + * @param addr + * @param port + */ + public StatusMonitor(DIRRequestDispatcher dirReqDisp, int port, String aclFile) { + this(ServiceTypes.DIR, null, port, aclFile); + this.masterDIR = dirReqDisp; + } + + /** + * Constructor when this class is running inside a DIR. + * + * @param dirReqDisp + * @param addr + * @param port + */ + public StatusMonitor(DIRRequestDispatcher dirReqDisp, InetAddress addr, int port, String aclFile) { + this(ServiceTypes.DIR, addr, port, aclFile); + this.masterDIR = dirReqDisp; + } + + /** + * Constructor when this class is running inside a MRC. + * + * @param mrcReqDisp + * @param port + */ + public StatusMonitor(MRCRequestDispatcher mrcReqDisp, int port) { + this(ServiceTypes.MRC, null, port, null); + this.masterMRC = mrcReqDisp; + } + + /** + * Constructor when this class is running inside a MRC. + * + * @param mrcReqDisp + * @param addr + * @param port + */ + public StatusMonitor(MRCRequestDispatcher mrcReqDisp, InetAddress addr, int port) { + this(ServiceTypes.MRC, addr, port, null); + this.masterMRC = mrcReqDisp; + } + + /** + * Constructor when this class is running inside a MRC. + * + * @param mrcReqDisp + * @param port + */ + public StatusMonitor(MRCRequestDispatcher mrcReqDisp, int port, String aclFile) { + this(ServiceTypes.MRC, null, port, aclFile); + this.masterMRC = mrcReqDisp; + } + + /** + * Constructor when this class is running inside a MRC. + * + * @param mrcReqDisp + * @param addr + * @param port + */ + public StatusMonitor(MRCRequestDispatcher mrcReqDisp, InetAddress addr, int port, String aclFile) { + this(ServiceTypes.MRC, addr, port, aclFile); + this.masterMRC = mrcReqDisp; + } + + /** + * Constructor when this class is running inside an OSD. + * + * @param osdReqDisp + * @param port + */ + public StatusMonitor(OSDRequestDispatcher osdReqDisp, int port) { + this(ServiceTypes.OSD, null, port, null); + this.masterOSD = osdReqDisp; + } + + /** + * Constructor when this class is running inside an OSD. + * + * @param osdReqDisp + * @param addr + * @param port + */ + public StatusMonitor(OSDRequestDispatcher osdReqDisp, InetAddress addr, int port) { + this(ServiceTypes.OSD, addr, port, null); + this.masterOSD = osdReqDisp; + } + + /** + * Constructor when this class is running inside an OSD. + * + * @param osdReqDisp + * @param port + * @param aclFile + */ + public StatusMonitor(OSDRequestDispatcher osdReqDisp, int port, String aclFile) { + this(ServiceTypes.OSD, null, port, aclFile); + this.masterOSD = osdReqDisp; + } + + /** + * Constructor when this class is running inside an OSD. + * + * @param osdReqDisp + * @param port + * @param aclFile + */ + public StatusMonitor(OSDRequestDispatcher osdReqDisp, InetAddress addr, int port, String aclFile) { + this(ServiceTypes.OSD, addr, port, aclFile); + this.masterOSD = osdReqDisp; + } + + private StatusMonitor(ServiceTypes type, InetAddress addr, int port, String aclFile) { + + initiatingService = type; + + JdmkAcl acl = null; + if (aclFile != null) { + // JdmkACL specifies the ACL file. + try { + acl = new JdmkAcl("Xtreemfs ACL", aclFile); + } catch (IllegalArgumentException iae) { + Logging.logMessage(Logging.LEVEL_ERROR, Logging.Category.misc, this, + "ACL file problem. The file %s is not a valid ACL file or did not exist.", aclFile); + } catch (UnknownHostException uhe) { + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.misc, this, "", uhe.getMessage()); + } + } + + // if there is no ACL File everyone who can access the the network can read the information + // exposed by SNMP from everywhere within the network! + if (acl == null) { + Logging.logMessage(Logging.LEVEL_NOTICE, Logging.Category.misc, this, + "SNMP agen will start without a ACL file. Everyone on your network can access the " + + "information exposed by the SNMP agent!"); + } + + // create and start the SNMP adaptor + if (addr != null) { + snmpAdaptor = new SnmpAdaptorServer(acl, port, addr); + } else { + snmpAdaptor = new SnmpAdaptorServer(acl, port); + } + snmpAdaptor.start(); + + // send a coldstart trap; every SNMP agent should do this on initialization + try { + snmpAdaptor.setTrapPort(port + 1); + snmpAdaptor.snmpV1Trap(0, 0, null); + + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.misc, this, + "SNMP agent started at port %s", port); + + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_ERROR, Logging.Category.misc, this, + "Failed to start SNMP agent at port %s", port); + } + + xtfsmib = new XTREEMFS_MIBImpl(this); + + try { + xtfsmib.init(); + } catch (IllegalAccessException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Logging.Category.misc, this, + "Failed to start SNMP agent: %s", e.getMessage()); + + } + + xtfsmib.setSnmpAdaptor(snmpAdaptor); + + } + + protected ServiceTypes getInitiatingService() { + return initiatingService; + } + + protected DIRConfig getDirConfig() { + return dirConfig; + } + + protected MRCConfig getMrcConfig() { + return mrcConfig; + } + + protected OSDConfig getOsdConfig() { + return osdConfig; + } + + public DIRRequestDispatcher getMasterDIR() { + return masterDIR; + } + + public MRCRequestDispatcher getMasterMRC() { + return masterMRC; + } + + public OSDRequestDispatcher getMasterOSD() { + return masterOSD; + } + + // Methods of the DIR Listener Interface. + @Override + public void addressMappingAdded() { + dirGroup.addressMappingAdded(); + } + + @Override + public void addressMappingDeleted() { + dirGroup.addressMappingDeleted(); + } + + @Override + public void DIRConfigChanged(DIRConfig config) { + this.dirConfig = config; + } + + @Override + public void serviceRegistered() { + this.dirGroup.serviceRegistered(); + } + + @Override + public void serviceDeregistered() { + this.dirGroup.serviceDeregistered(); + } + + // MIB Groups registrations + /** + * This method is used by {@link DirImpl} constructor to make itself accessible by this class. + * + * @param DirImpl + */ + protected void setDirGroup(DirImpl dirGroup) { + this.dirGroup = dirGroup; + } + + /** + * This method is used by {@link MRCImpl} constructor to make itself accessible by this class. + * + * @param MrcImpl + */ + protected void setMrcGroup(MrcImpl mrcGroup) { + this.mrcGroup = mrcGroup; + } + + /** + * This method is used by {@link OsdImpl} constructor to make itself accessible by this class. + * + * @param OsdImpl + */ + protected void setOsdGroup(OsdImpl osdGroup) { + this.osdGroup = osdGroup; + } + + // + // MRCListener related functions + @Override + public void MRCConfigChanged(MRCConfig config) { + this.mrcConfig = config; + + } + + @Override + public void volumeCreated() { + mrcGroup.volumeCreated(); + } + + @Override + public void volumeDeleted() { + mrcGroup.volumeDeleted(); + } + + // + // OSDListener related functions + @Override + public void OSDConfigChanged(OSDConfig config) { + this.osdConfig = config; + } + + @Override + public void numBytesTXChanged(long numBytesTX) { + osdGroup.setNumBytesTX(numBytesTX); + } + + @Override + public void numBytesRXChanged(long numBytesRX) { + osdGroup.setNumBytesRX(numBytesRX); + } + + @Override + public void numReplBytesRXChanged(long numReplBytesRX) { + osdGroup.setNumReplBytesRX(numReplBytesRX); + } + + @Override + public void numObjsTXChanged(long numObjsTX) { + osdGroup.setNumObjsTX(numObjsTX); + } + + @Override + public void numObjsRXChanged(long numObjsRX) { + osdGroup.setNumObjsRX(numObjsRX); + } + + @Override + public void numReplObjsRX(long numReplObjsRX) { + osdGroup.setNumReplObjsRX(numReplObjsRX); + } + + @Override + public void shuttingDown() { + snmpAdaptor.stop(); + } +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/XTREEMFS_MIBImpl.java b/java/servers/src/org/xtreemfs/common/monitoring/XTREEMFS_MIBImpl.java new file mode 100644 index 0000000..dbfb616 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/XTREEMFS_MIBImpl.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.monitoring; + +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import org.xtreemfs.common.monitoring.generatedcode.XTREEMFS_MIB; + +@SuppressWarnings("serial") +public class XTREEMFS_MIBImpl extends XTREEMFS_MIB { + + private StatusMonitor statusMonitor; + + /** + * Defines what kind of service is created the snmp agent + */ + + public XTREEMFS_MIBImpl(StatusMonitor statusMonitor) { + super(); + this.statusMonitor = statusMonitor; + } + + // Overwrite this method in order to ensure that your own Dir implementation is used. + @Override + protected Object createDirMBean(String groupName, String groupOid, ObjectName groupObjname, + MBeanServer server) { + // if this runs in a DIR Service, return customized Dir group. Otherwise return the default + // one created method of the super-class + if (server != null) { + return new DirImpl(this, server, statusMonitor); + } else { + return new DirImpl(this, statusMonitor); + } + } + + // Overwrite this method in order to ensure that your own General implementation is used. + @Override + protected Object createGeneralMBean(String groupName, String groupOid, ObjectName groupObjname, + MBeanServer server) { + if (server != null) { + return new GeneralImpl(this, server, statusMonitor); + } else { + return new GeneralImpl(this, statusMonitor); + } + } + + // Overwrite this method in order to ensure that your own Mrc implementation is used. + @Override + protected Object createMrcMBean(String groupName, String groupOid, ObjectName groupObjname, + MBeanServer server) { + // if this runs in a DIR Service, return customized Mrc group. Otherwise return the default + // one created method of the super-class + if (server != null) { + return new MrcImpl(this, server, statusMonitor); + } else { + return new MrcImpl(this, statusMonitor); + } + } + + // Overwrite this method in order to ensure that your own Osd implementation is used. + @Override + protected Object createOsdMBean(String groupName, String groupOid, ObjectName groupObjname, + MBeanServer server) { + // if this runs in a DIR Service, return customized Dir group. Otherwhise return the default + // one created method of the super-class + if (server != null) { + return new OsdImpl(this, server, statusMonitor); + } else { + return new OsdImpl(this, statusMonitor); + } + + } + +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Dir.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Dir.java new file mode 100644 index 0000000..46daf58 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Dir.java @@ -0,0 +1,69 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB. +// + +// java imports +// +import java.io.Serializable; + +// jmx imports +// +import javax.management.MBeanServer; +import com.sun.management.snmp.SnmpString; +import com.sun.management.snmp.SnmpStatusException; + +// jdmk imports +// +import com.sun.management.snmp.agent.SnmpMib; + +/** + * The class is used for implementing the "Dir" group. + * The group is defined with the following oid: 1.3.6.1.4.1.38350.2. + */ +public class Dir implements DirMBean, Serializable { + + /** + * Variable for storing the value of "ServiceCount". + * The variable is identified by: "1.3.6.1.4.1.38350.2.2". + */ + protected Integer ServiceCount = new Integer(1); + + /** + * Variable for storing the value of "AddressMappingCount". + * The variable is identified by: "1.3.6.1.4.1.38350.2.1". + */ + protected Integer AddressMappingCount = new Integer(1); + + + /** + * Constructor for the "Dir" group. + * If the group contains a table, the entries created through an SNMP SET will not be registered in Java DMK. + */ + public Dir(SnmpMib myMib) { + } + + + /** + * Constructor for the "Dir" group. + * If the group contains a table, the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK. + */ + public Dir(SnmpMib myMib, MBeanServer server) { + } + + /** + * Getter for the "ServiceCount" variable. + */ + public Integer getServiceCount() throws SnmpStatusException { + return ServiceCount; + } + + /** + * Getter for the "AddressMappingCount" variable. + */ + public Integer getAddressMappingCount() throws SnmpStatusException { + return AddressMappingCount; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/DirMBean.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/DirMBean.java new file mode 100644 index 0000000..fec314a --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/DirMBean.java @@ -0,0 +1,27 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB in standard metadata mode. +// + + +// jmx imports +// +import com.sun.management.snmp.SnmpStatusException; + +/** + * This interface is used for representing the remote management interface for the "Dir" MBean. + */ +public interface DirMBean { + + /** + * Getter for the "ServiceCount" variable. + */ + public Integer getServiceCount() throws SnmpStatusException; + + /** + * Getter for the "AddressMappingCount" variable. + */ + public Integer getAddressMappingCount() throws SnmpStatusException; + +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/DirMeta.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/DirMeta.java new file mode 100644 index 0000000..69d6a4e --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/DirMeta.java @@ -0,0 +1,247 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB in standard metadata mode. +// + +// java imports +// +import java.io.Serializable; + +// jmx imports +// +import javax.management.MBeanServer; +import com.sun.management.snmp.SnmpCounter; +import com.sun.management.snmp.SnmpCounter64; +import com.sun.management.snmp.SnmpGauge; +import com.sun.management.snmp.SnmpInt; +import com.sun.management.snmp.SnmpUnsignedInt; +import com.sun.management.snmp.SnmpIpAddress; +import com.sun.management.snmp.SnmpTimeticks; +import com.sun.management.snmp.SnmpOpaque; +import com.sun.management.snmp.SnmpString; +import com.sun.management.snmp.SnmpStringFixed; +import com.sun.management.snmp.SnmpOid; +import com.sun.management.snmp.SnmpNull; +import com.sun.management.snmp.SnmpValue; +import com.sun.management.snmp.SnmpVarBind; +import com.sun.management.snmp.SnmpStatusException; + +// jdmk imports +// +import com.sun.management.snmp.agent.SnmpMib; +import com.sun.management.snmp.agent.SnmpMibGroup; +import com.sun.management.snmp.agent.SnmpStandardObjectServer; +import com.sun.management.snmp.agent.SnmpStandardMetaServer; +import com.sun.management.snmp.agent.SnmpMibSubRequest; +import com.sun.management.snmp.agent.SnmpMibTable; +import com.sun.management.snmp.EnumRowStatus; +import com.sun.management.snmp.SnmpDefinitions; + +/** + * The class is used for representing SNMP metadata for the "Dir" group. + * The group is defined with the following oid: 1.3.6.1.4.1.38350.2. + */ +public class DirMeta extends SnmpMibGroup + implements Serializable, SnmpStandardMetaServer { + + /** + * Constructor for the metadata associated to "Dir". + */ + public DirMeta(SnmpMib myMib, SnmpStandardObjectServer objserv) { + objectserver = objserv; + try { + registerObject(2); + registerObject(1); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } + + /** + * Get the value of a scalar variable + */ + public SnmpValue get(long var, Object data) + throws SnmpStatusException { + switch((int)var) { + case 2: + return new SnmpInt(node.getServiceCount()); + + case 1: + return new SnmpInt(node.getAddressMappingCount()); + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.noSuchObject); + } + + /** + * Set the value of a scalar variable + */ + public SnmpValue set(SnmpValue x, long var, Object data) + throws SnmpStatusException { + switch((int)var) { + case 2: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 1: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + } + + /** + * Check the value of a scalar variable + */ + public void check(SnmpValue x, long var, Object data) + throws SnmpStatusException { + switch((int) var) { + case 2: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 1: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + default: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + } + } + + /** + * Allow to bind the metadata description to a specific object. + */ + protected void setInstance(DirMBean var) { + node = var; + } + + + // ------------------------------------------------------------ + // + // Implements the "get" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void get(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.get(this,req,depth); + } + + + // ------------------------------------------------------------ + // + // Implements the "set" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void set(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.set(this,req,depth); + } + + + // ------------------------------------------------------------ + // + // Implements the "check" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void check(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.check(this,req,depth); + } + + /** + * Returns true if "arc" identifies a scalar object. + */ + public boolean isVariable(long arc) { + + switch((int)arc) { + case 2: + case 1: + return true; + default: + break; + } + return false; + } + + /** + * Returns true if "arc" identifies a readable scalar object. + */ + public boolean isReadable(long arc) { + + switch((int)arc) { + case 2: + case 1: + return true; + default: + break; + } + return false; + } + + + // ------------------------------------------------------------ + // + // Implements the "skipVariable" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public boolean skipVariable(long var, Object data, int pduVersion) { + return false; + } + + /** + * Return the name of the attribute corresponding to the SNMP variable identified by "id". + */ + public String getAttributeName(long id) + throws SnmpStatusException { + switch((int)id) { + case 2: + return "ServiceCount"; + + case 1: + return "AddressMappingCount"; + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.noSuchObject); + } + + /** + * Returns true if "arc" identifies a table object. + */ + public boolean isTable(long arc) { + + switch((int)arc) { + default: + break; + } + return false; + } + + /** + * Returns the table object identified by "arc". + */ + public SnmpMibTable getTable(long arc) { + return null; + } + + /** + * Register the group's SnmpMibTable objects with the meta-data. + */ + public void registerTableNodes(SnmpMib mib, MBeanServer server) { + } + + protected DirMBean node; + protected SnmpStandardObjectServer objectserver = null; +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/General.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/General.java new file mode 100644 index 0000000..961a202 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/General.java @@ -0,0 +1,212 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB. +// + +// java imports +// +import java.io.Serializable; + +// jmx imports +// +import javax.management.MBeanServer; +import com.sun.management.snmp.SnmpString; +import com.sun.management.snmp.SnmpStatusException; + +// jdmk imports +// +import com.sun.management.snmp.agent.SnmpMib; + +/** + * The class is used for implementing the "General" group. + * The group is defined with the following oid: 1.3.6.1.4.1.38350.1. + */ +public class General implements GeneralMBean, Serializable { + + /** + * Variable for storing the value of "NumPendingRequests". + * The variable is identified by: "1.3.6.1.4.1.38350.1.9". + */ + protected Long NumPendingRequests = new Long(1); + + /** + * Variable for storing the value of "NumClientConnections". + * The variable is identified by: "1.3.6.1.4.1.38350.1.8". + */ + protected Integer NumClientConnections = new Integer(1); + + /** + * Variable for storing the value of "DebugLevel". + * The variable is identified by: "1.3.6.1.4.1.38350.1.7". + */ + protected Integer DebugLevel = new Integer(1); + + /** + * Variable for storing the value of "TcpPort". + * The variable is identified by: "1.3.6.1.4.1.38350.1.6". + */ + protected Integer TcpPort = new Integer(1); + + /** + * Variable for storing the value of "DatabaseVersion". + * The variable is identified by: "1.3.6.1.4.1.38350.1.5". + */ + protected String DatabaseVersion = new String("JDMK 5.1"); + + /** + * Variable for storing the value of "RpcInterface". + * The variable is identified by: "1.3.6.1.4.1.38350.1.4". + */ + protected Integer RpcInterface = new Integer(1); + + /** + * Variable for storing the value of "ServiceUUID". + * The variable is identified by: "1.3.6.1.4.1.38350.1.13". + */ + protected String ServiceUUID = new String("JDMK 5.1"); + + /** + * Variable for storing the value of "ServiceType". + * The variable is identified by: "1.3.6.1.4.1.38350.1.12". + */ + protected String ServiceType = new String("JDMK 5.1"); + + /** + * Variable for storing the value of "JvmFreeMemory". + * The variable is identified by: "1.3.6.1.4.1.38350.1.3". + */ + protected Long JvmFreeMemory = new Long(1); + + /** + * Variable for storing the value of "JvmMaxMemory". + * The variable is identified by: "1.3.6.1.4.1.38350.1.2". + */ + protected Long JvmMaxMemory = new Long(1); + + /** + * Variable for storing the value of "IsRunning". + * The variable is identified by: "1.3.6.1.4.1.38350.1.11". + */ + protected String IsRunning = new String("JDMK 5.1"); + + /** + * Variable for storing the value of "CurrentTime". + * The variable is identified by: "1.3.6.1.4.1.38350.1.10". + */ + protected Long CurrentTime = new Long(1); + + /** + * Variable for storing the value of "JvmUsedMemory". + * The variable is identified by: "1.3.6.1.4.1.38350.1.1". + */ + protected Long JvmUsedMemory = new Long(1); + + + /** + * Constructor for the "General" group. + * If the group contains a table, the entries created through an SNMP SET will not be registered in Java DMK. + */ + public General(SnmpMib myMib) { + } + + + /** + * Constructor for the "General" group. + * If the group contains a table, the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK. + */ + public General(SnmpMib myMib, MBeanServer server) { + } + + /** + * Getter for the "NumPendingRequests" variable. + */ + public Long getNumPendingRequests() throws SnmpStatusException { + return NumPendingRequests; + } + + /** + * Getter for the "NumClientConnections" variable. + */ + public Integer getNumClientConnections() throws SnmpStatusException { + return NumClientConnections; + } + + /** + * Getter for the "DebugLevel" variable. + */ + public Integer getDebugLevel() throws SnmpStatusException { + return DebugLevel; + } + + /** + * Getter for the "TcpPort" variable. + */ + public Integer getTcpPort() throws SnmpStatusException { + return TcpPort; + } + + /** + * Getter for the "DatabaseVersion" variable. + */ + public String getDatabaseVersion() throws SnmpStatusException { + return DatabaseVersion; + } + + /** + * Getter for the "RpcInterface" variable. + */ + public Integer getRpcInterface() throws SnmpStatusException { + return RpcInterface; + } + + /** + * Getter for the "ServiceUUID" variable. + */ + public String getServiceUUID() throws SnmpStatusException { + return ServiceUUID; + } + + /** + * Getter for the "ServiceType" variable. + */ + public String getServiceType() throws SnmpStatusException { + return ServiceType; + } + + /** + * Getter for the "JvmFreeMemory" variable. + */ + public Long getJvmFreeMemory() throws SnmpStatusException { + return JvmFreeMemory; + } + + /** + * Getter for the "JvmMaxMemory" variable. + */ + public Long getJvmMaxMemory() throws SnmpStatusException { + return JvmMaxMemory; + } + + /** + * Getter for the "IsRunning" variable. + */ + public String getIsRunning() throws SnmpStatusException { + return IsRunning; + } + + /** + * Getter for the "CurrentTime" variable. + */ + public Long getCurrentTime() throws SnmpStatusException { + return CurrentTime; + } + + /** + * Getter for the "JvmUsedMemory" variable. + */ + public Long getJvmUsedMemory() throws SnmpStatusException { + return JvmUsedMemory; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/GeneralMBean.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/GeneralMBean.java new file mode 100644 index 0000000..6dc2ce8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/GeneralMBean.java @@ -0,0 +1,82 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB in standard metadata mode. +// + + +// jmx imports +// +import com.sun.management.snmp.SnmpStatusException; + +/** + * This interface is used for representing the remote management interface for the "General" MBean. + */ +public interface GeneralMBean { + + /** + * Getter for the "NumPendingRequests" variable. + */ + public Long getNumPendingRequests() throws SnmpStatusException; + + /** + * Getter for the "NumClientConnections" variable. + */ + public Integer getNumClientConnections() throws SnmpStatusException; + + /** + * Getter for the "DebugLevel" variable. + */ + public Integer getDebugLevel() throws SnmpStatusException; + + /** + * Getter for the "TcpPort" variable. + */ + public Integer getTcpPort() throws SnmpStatusException; + + /** + * Getter for the "DatabaseVersion" variable. + */ + public String getDatabaseVersion() throws SnmpStatusException; + + /** + * Getter for the "RpcInterface" variable. + */ + public Integer getRpcInterface() throws SnmpStatusException; + + /** + * Getter for the "ServiceUUID" variable. + */ + public String getServiceUUID() throws SnmpStatusException; + + /** + * Getter for the "ServiceType" variable. + */ + public String getServiceType() throws SnmpStatusException; + + /** + * Getter for the "JvmFreeMemory" variable. + */ + public Long getJvmFreeMemory() throws SnmpStatusException; + + /** + * Getter for the "JvmMaxMemory" variable. + */ + public Long getJvmMaxMemory() throws SnmpStatusException; + + /** + * Getter for the "IsRunning" variable. + */ + public String getIsRunning() throws SnmpStatusException; + + /** + * Getter for the "CurrentTime" variable. + */ + public Long getCurrentTime() throws SnmpStatusException; + + /** + * Getter for the "JvmUsedMemory" variable. + */ + public Long getJvmUsedMemory() throws SnmpStatusException; + +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/GeneralMeta.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/GeneralMeta.java new file mode 100644 index 0000000..066abc2 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/GeneralMeta.java @@ -0,0 +1,423 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB in standard metadata mode. +// + +// java imports +// +import java.io.Serializable; + +// jmx imports +// +import javax.management.MBeanServer; +import com.sun.management.snmp.SnmpCounter; +import com.sun.management.snmp.SnmpCounter64; +import com.sun.management.snmp.SnmpGauge; +import com.sun.management.snmp.SnmpInt; +import com.sun.management.snmp.SnmpUnsignedInt; +import com.sun.management.snmp.SnmpIpAddress; +import com.sun.management.snmp.SnmpTimeticks; +import com.sun.management.snmp.SnmpOpaque; +import com.sun.management.snmp.SnmpString; +import com.sun.management.snmp.SnmpStringFixed; +import com.sun.management.snmp.SnmpOid; +import com.sun.management.snmp.SnmpNull; +import com.sun.management.snmp.SnmpValue; +import com.sun.management.snmp.SnmpVarBind; +import com.sun.management.snmp.SnmpStatusException; + +// jdmk imports +// +import com.sun.management.snmp.agent.SnmpMib; +import com.sun.management.snmp.agent.SnmpMibGroup; +import com.sun.management.snmp.agent.SnmpStandardObjectServer; +import com.sun.management.snmp.agent.SnmpStandardMetaServer; +import com.sun.management.snmp.agent.SnmpMibSubRequest; +import com.sun.management.snmp.agent.SnmpMibTable; +import com.sun.management.snmp.EnumRowStatus; +import com.sun.management.snmp.SnmpDefinitions; + +/** + * The class is used for representing SNMP metadata for the "General" group. + * The group is defined with the following oid: 1.3.6.1.4.1.38350.1. + */ +public class GeneralMeta extends SnmpMibGroup + implements Serializable, SnmpStandardMetaServer { + + /** + * Constructor for the metadata associated to "General". + */ + public GeneralMeta(SnmpMib myMib, SnmpStandardObjectServer objserv) { + objectserver = objserv; + try { + registerObject(9); + registerObject(8); + registerObject(7); + registerObject(6); + registerObject(5); + registerObject(4); + registerObject(13); + registerObject(12); + registerObject(3); + registerObject(2); + registerObject(11); + registerObject(10); + registerObject(1); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } + + /** + * Get the value of a scalar variable + */ + public SnmpValue get(long var, Object data) + throws SnmpStatusException { + switch((int)var) { + case 9: + return new SnmpCounter64(node.getNumPendingRequests()); + + case 8: + return new SnmpInt(node.getNumClientConnections()); + + case 7: + return new SnmpInt(node.getDebugLevel()); + + case 6: + return new SnmpInt(node.getTcpPort()); + + case 5: + return new SnmpString(node.getDatabaseVersion()); + + case 4: + return new SnmpInt(node.getRpcInterface()); + + case 13: + return new SnmpString(node.getServiceUUID()); + + case 12: + return new SnmpString(node.getServiceType()); + + case 3: + return new SnmpCounter64(node.getJvmFreeMemory()); + + case 2: + return new SnmpCounter64(node.getJvmMaxMemory()); + + case 11: + return new SnmpString(node.getIsRunning()); + + case 10: + return new SnmpCounter64(node.getCurrentTime()); + + case 1: + return new SnmpCounter64(node.getJvmUsedMemory()); + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.noSuchObject); + } + + /** + * Set the value of a scalar variable + */ + public SnmpValue set(SnmpValue x, long var, Object data) + throws SnmpStatusException { + switch((int)var) { + case 9: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 8: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 7: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 6: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 5: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 4: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 13: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 12: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 3: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 2: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 11: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 10: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 1: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + } + + /** + * Check the value of a scalar variable + */ + public void check(SnmpValue x, long var, Object data) + throws SnmpStatusException { + switch((int) var) { + case 9: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 8: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 7: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 6: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 5: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 4: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 13: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 12: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 3: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 2: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 11: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 10: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 1: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + default: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + } + } + + /** + * Allow to bind the metadata description to a specific object. + */ + protected void setInstance(GeneralMBean var) { + node = var; + } + + + // ------------------------------------------------------------ + // + // Implements the "get" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void get(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.get(this,req,depth); + } + + + // ------------------------------------------------------------ + // + // Implements the "set" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void set(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.set(this,req,depth); + } + + + // ------------------------------------------------------------ + // + // Implements the "check" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void check(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.check(this,req,depth); + } + + /** + * Returns true if "arc" identifies a scalar object. + */ + public boolean isVariable(long arc) { + + switch((int)arc) { + case 9: + case 8: + case 7: + case 6: + case 5: + case 4: + case 13: + case 12: + case 3: + case 2: + case 11: + case 10: + case 1: + return true; + default: + break; + } + return false; + } + + /** + * Returns true if "arc" identifies a readable scalar object. + */ + public boolean isReadable(long arc) { + + switch((int)arc) { + case 9: + case 8: + case 7: + case 6: + case 5: + case 4: + case 13: + case 12: + case 3: + case 2: + case 11: + case 10: + case 1: + return true; + default: + break; + } + return false; + } + + + // ------------------------------------------------------------ + // + // Implements the "skipVariable" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public boolean skipVariable(long var, Object data, int pduVersion) { + switch((int)var) { + case 9: + case 3: + case 2: + case 10: + case 1: + if (pduVersion==SnmpDefinitions.snmpVersionOne) return true; + break; + default: + break; + } + return false; + } + + /** + * Return the name of the attribute corresponding to the SNMP variable identified by "id". + */ + public String getAttributeName(long id) + throws SnmpStatusException { + switch((int)id) { + case 9: + return "NumPendingRequests"; + + case 8: + return "NumClientConnections"; + + case 7: + return "DebugLevel"; + + case 6: + return "TcpPort"; + + case 5: + return "DatabaseVersion"; + + case 4: + return "RpcInterface"; + + case 13: + return "ServiceUUID"; + + case 12: + return "ServiceType"; + + case 3: + return "JvmFreeMemory"; + + case 2: + return "JvmMaxMemory"; + + case 11: + return "IsRunning"; + + case 10: + return "CurrentTime"; + + case 1: + return "JvmUsedMemory"; + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.noSuchObject); + } + + /** + * Returns true if "arc" identifies a table object. + */ + public boolean isTable(long arc) { + + switch((int)arc) { + default: + break; + } + return false; + } + + /** + * Returns the table object identified by "arc". + */ + public SnmpMibTable getTable(long arc) { + return null; + } + + /** + * Register the group's SnmpMibTable objects with the meta-data. + */ + public void registerTableNodes(SnmpMib mib, MBeanServer server) { + } + + protected GeneralMBean node; + protected SnmpStandardObjectServer objectserver = null; +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Mrc.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Mrc.java new file mode 100644 index 0000000..e8b5152 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Mrc.java @@ -0,0 +1,56 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB. +// + +// java imports +// +import java.io.Serializable; + +// jmx imports +// +import javax.management.MBeanServer; +import com.sun.management.snmp.SnmpString; +import com.sun.management.snmp.SnmpStatusException; + +// jdmk imports +// +import com.sun.management.snmp.agent.SnmpMib; + +/** + * The class is used for implementing the "Mrc" group. + * The group is defined with the following oid: 1.3.6.1.4.1.38350.3. + */ +public class Mrc implements MrcMBean, Serializable { + + /** + * Variable for storing the value of "VolumeCount". + * The variable is identified by: "1.3.6.1.4.1.38350.3.1". + */ + protected Integer VolumeCount = new Integer(1); + + + /** + * Constructor for the "Mrc" group. + * If the group contains a table, the entries created through an SNMP SET will not be registered in Java DMK. + */ + public Mrc(SnmpMib myMib) { + } + + + /** + * Constructor for the "Mrc" group. + * If the group contains a table, the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK. + */ + public Mrc(SnmpMib myMib, MBeanServer server) { + } + + /** + * Getter for the "VolumeCount" variable. + */ + public Integer getVolumeCount() throws SnmpStatusException { + return VolumeCount; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/MrcMBean.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/MrcMBean.java new file mode 100644 index 0000000..552c31c --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/MrcMBean.java @@ -0,0 +1,22 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB in standard metadata mode. +// + + +// jmx imports +// +import com.sun.management.snmp.SnmpStatusException; + +/** + * This interface is used for representing the remote management interface for the "Mrc" MBean. + */ +public interface MrcMBean { + + /** + * Getter for the "VolumeCount" variable. + */ + public Integer getVolumeCount() throws SnmpStatusException; + +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/MrcMeta.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/MrcMeta.java new file mode 100644 index 0000000..c6c14d0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/MrcMeta.java @@ -0,0 +1,232 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB in standard metadata mode. +// + +// java imports +// +import java.io.Serializable; + +// jmx imports +// +import javax.management.MBeanServer; +import com.sun.management.snmp.SnmpCounter; +import com.sun.management.snmp.SnmpCounter64; +import com.sun.management.snmp.SnmpGauge; +import com.sun.management.snmp.SnmpInt; +import com.sun.management.snmp.SnmpUnsignedInt; +import com.sun.management.snmp.SnmpIpAddress; +import com.sun.management.snmp.SnmpTimeticks; +import com.sun.management.snmp.SnmpOpaque; +import com.sun.management.snmp.SnmpString; +import com.sun.management.snmp.SnmpStringFixed; +import com.sun.management.snmp.SnmpOid; +import com.sun.management.snmp.SnmpNull; +import com.sun.management.snmp.SnmpValue; +import com.sun.management.snmp.SnmpVarBind; +import com.sun.management.snmp.SnmpStatusException; + +// jdmk imports +// +import com.sun.management.snmp.agent.SnmpMib; +import com.sun.management.snmp.agent.SnmpMibGroup; +import com.sun.management.snmp.agent.SnmpStandardObjectServer; +import com.sun.management.snmp.agent.SnmpStandardMetaServer; +import com.sun.management.snmp.agent.SnmpMibSubRequest; +import com.sun.management.snmp.agent.SnmpMibTable; +import com.sun.management.snmp.EnumRowStatus; +import com.sun.management.snmp.SnmpDefinitions; + +/** + * The class is used for representing SNMP metadata for the "Mrc" group. + * The group is defined with the following oid: 1.3.6.1.4.1.38350.3. + */ +public class MrcMeta extends SnmpMibGroup + implements Serializable, SnmpStandardMetaServer { + + /** + * Constructor for the metadata associated to "Mrc". + */ + public MrcMeta(SnmpMib myMib, SnmpStandardObjectServer objserv) { + objectserver = objserv; + try { + registerObject(1); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } + + /** + * Get the value of a scalar variable + */ + public SnmpValue get(long var, Object data) + throws SnmpStatusException { + switch((int)var) { + case 1: + return new SnmpInt(node.getVolumeCount()); + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.noSuchObject); + } + + /** + * Set the value of a scalar variable + */ + public SnmpValue set(SnmpValue x, long var, Object data) + throws SnmpStatusException { + switch((int)var) { + case 1: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + } + + /** + * Check the value of a scalar variable + */ + public void check(SnmpValue x, long var, Object data) + throws SnmpStatusException { + switch((int) var) { + case 1: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + default: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + } + } + + /** + * Allow to bind the metadata description to a specific object. + */ + protected void setInstance(MrcMBean var) { + node = var; + } + + + // ------------------------------------------------------------ + // + // Implements the "get" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void get(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.get(this,req,depth); + } + + + // ------------------------------------------------------------ + // + // Implements the "set" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void set(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.set(this,req,depth); + } + + + // ------------------------------------------------------------ + // + // Implements the "check" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void check(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.check(this,req,depth); + } + + /** + * Returns true if "arc" identifies a scalar object. + */ + public boolean isVariable(long arc) { + + switch((int)arc) { + case 1: + return true; + default: + break; + } + return false; + } + + /** + * Returns true if "arc" identifies a readable scalar object. + */ + public boolean isReadable(long arc) { + + switch((int)arc) { + case 1: + return true; + default: + break; + } + return false; + } + + + // ------------------------------------------------------------ + // + // Implements the "skipVariable" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public boolean skipVariable(long var, Object data, int pduVersion) { + return false; + } + + /** + * Return the name of the attribute corresponding to the SNMP variable identified by "id". + */ + public String getAttributeName(long id) + throws SnmpStatusException { + switch((int)id) { + case 1: + return "VolumeCount"; + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.noSuchObject); + } + + /** + * Returns true if "arc" identifies a table object. + */ + public boolean isTable(long arc) { + + switch((int)arc) { + default: + break; + } + return false; + } + + /** + * Returns the table object identified by "arc". + */ + public SnmpMibTable getTable(long arc) { + return null; + } + + /** + * Register the group's SnmpMibTable objects with the meta-data. + */ + public void registerTableNodes(SnmpMib mib, MBeanServer server) { + } + + protected MrcMBean node; + protected SnmpStandardObjectServer objectserver = null; +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Osd.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Osd.java new file mode 100644 index 0000000..6adbdd2 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/Osd.java @@ -0,0 +1,199 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB. +// + +// java imports +// +import java.io.Serializable; + +// jmx imports +// +import javax.management.MBeanServer; +import com.sun.management.snmp.SnmpString; +import com.sun.management.snmp.SnmpStatusException; + +// jdmk imports +// +import com.sun.management.snmp.agent.SnmpMib; + +/** + * The class is used for implementing the "Osd" group. + * The group is defined with the following oid: 1.3.6.1.4.1.38350.4. + */ +public class Osd implements OsdMBean, Serializable { + + /** + * Variable for storing the value of "DeletionStageQueueLength". + * The variable is identified by: "1.3.6.1.4.1.38350.4.9". + */ + protected Integer DeletionStageQueueLength = new Integer(1); + + /** + * Variable for storing the value of "StorageStageQueueLength". + * The variable is identified by: "1.3.6.1.4.1.38350.4.8". + */ + protected Integer StorageStageQueueLength = new Integer(1); + + /** + * Variable for storing the value of "PreprocStageQueueLength". + * The variable is identified by: "1.3.6.1.4.1.38350.4.7". + */ + protected Integer PreprocStageQueueLength = new Integer(1); + + /** + * Variable for storing the value of "NumBytesTX". + * The variable is identified by: "1.3.6.1.4.1.38350.4.6". + */ + protected Long NumBytesTX = new Long(1); + + /** + * Variable for storing the value of "NumBytesRX". + * The variable is identified by: "1.3.6.1.4.1.38350.4.5". + */ + protected Long NumBytesRX = new Long(1); + + /** + * Variable for storing the value of "NumReplBytesRX". + * The variable is identified by: "1.3.6.1.4.1.38350.4.4". + */ + protected Long NumReplBytesRX = new Long(1); + + /** + * Variable for storing the value of "FreeSpace". + * The variable is identified by: "1.3.6.1.4.1.38350.4.12". + */ + protected Long FreeSpace = new Long(1); + + /** + * Variable for storing the value of "NumObjsTX". + * The variable is identified by: "1.3.6.1.4.1.38350.4.3". + */ + protected Long NumObjsTX = new Long(1); + + /** + * Variable for storing the value of "NumReplObjsRX". + * The variable is identified by: "1.3.6.1.4.1.38350.4.2". + */ + protected Long NumReplObjsRX = new Long(1); + + /** + * Variable for storing the value of "NumDeletedFiles". + * The variable is identified by: "1.3.6.1.4.1.38350.4.11". + */ + protected Long NumDeletedFiles = new Long(1); + + /** + * Variable for storing the value of "NumObjsRX". + * The variable is identified by: "1.3.6.1.4.1.38350.4.1". + */ + protected Long NumObjsRX = new Long(1); + + /** + * Variable for storing the value of "NumOpenFiles". + * The variable is identified by: "1.3.6.1.4.1.38350.4.10". + */ + protected Integer NumOpenFiles = new Integer(1); + + + /** + * Constructor for the "Osd" group. + * If the group contains a table, the entries created through an SNMP SET will not be registered in Java DMK. + */ + public Osd(SnmpMib myMib) { + } + + + /** + * Constructor for the "Osd" group. + * If the group contains a table, the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK. + */ + public Osd(SnmpMib myMib, MBeanServer server) { + } + + /** + * Getter for the "DeletionStageQueueLength" variable. + */ + public Integer getDeletionStageQueueLength() throws SnmpStatusException { + return DeletionStageQueueLength; + } + + /** + * Getter for the "StorageStageQueueLength" variable. + */ + public Integer getStorageStageQueueLength() throws SnmpStatusException { + return StorageStageQueueLength; + } + + /** + * Getter for the "PreprocStageQueueLength" variable. + */ + public Integer getPreprocStageQueueLength() throws SnmpStatusException { + return PreprocStageQueueLength; + } + + /** + * Getter for the "NumBytesTX" variable. + */ + public Long getNumBytesTX() throws SnmpStatusException { + return NumBytesTX; + } + + /** + * Getter for the "NumBytesRX" variable. + */ + public Long getNumBytesRX() throws SnmpStatusException { + return NumBytesRX; + } + + /** + * Getter for the "NumReplBytesRX" variable. + */ + public Long getNumReplBytesRX() throws SnmpStatusException { + return NumReplBytesRX; + } + + /** + * Getter for the "FreeSpace" variable. + */ + public Long getFreeSpace() throws SnmpStatusException { + return FreeSpace; + } + + /** + * Getter for the "NumObjsTX" variable. + */ + public Long getNumObjsTX() throws SnmpStatusException { + return NumObjsTX; + } + + /** + * Getter for the "NumReplObjsRX" variable. + */ + public Long getNumReplObjsRX() throws SnmpStatusException { + return NumReplObjsRX; + } + + /** + * Getter for the "NumDeletedFiles" variable. + */ + public Long getNumDeletedFiles() throws SnmpStatusException { + return NumDeletedFiles; + } + + /** + * Getter for the "NumObjsRX" variable. + */ + public Long getNumObjsRX() throws SnmpStatusException { + return NumObjsRX; + } + + /** + * Getter for the "NumOpenFiles" variable. + */ + public Integer getNumOpenFiles() throws SnmpStatusException { + return NumOpenFiles; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/OsdMBean.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/OsdMBean.java new file mode 100644 index 0000000..b29887a --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/OsdMBean.java @@ -0,0 +1,77 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB in standard metadata mode. +// + + +// jmx imports +// +import com.sun.management.snmp.SnmpStatusException; + +/** + * This interface is used for representing the remote management interface for the "Osd" MBean. + */ +public interface OsdMBean { + + /** + * Getter for the "DeletionStageQueueLength" variable. + */ + public Integer getDeletionStageQueueLength() throws SnmpStatusException; + + /** + * Getter for the "StorageStageQueueLength" variable. + */ + public Integer getStorageStageQueueLength() throws SnmpStatusException; + + /** + * Getter for the "PreprocStageQueueLength" variable. + */ + public Integer getPreprocStageQueueLength() throws SnmpStatusException; + + /** + * Getter for the "NumBytesTX" variable. + */ + public Long getNumBytesTX() throws SnmpStatusException; + + /** + * Getter for the "NumBytesRX" variable. + */ + public Long getNumBytesRX() throws SnmpStatusException; + + /** + * Getter for the "NumReplBytesRX" variable. + */ + public Long getNumReplBytesRX() throws SnmpStatusException; + + /** + * Getter for the "FreeSpace" variable. + */ + public Long getFreeSpace() throws SnmpStatusException; + + /** + * Getter for the "NumObjsTX" variable. + */ + public Long getNumObjsTX() throws SnmpStatusException; + + /** + * Getter for the "NumReplObjsRX" variable. + */ + public Long getNumReplObjsRX() throws SnmpStatusException; + + /** + * Getter for the "NumDeletedFiles" variable. + */ + public Long getNumDeletedFiles() throws SnmpStatusException; + + /** + * Getter for the "NumObjsRX" variable. + */ + public Long getNumObjsRX() throws SnmpStatusException; + + /** + * Getter for the "NumOpenFiles" variable. + */ + public Integer getNumOpenFiles() throws SnmpStatusException; + +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/OsdMeta.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/OsdMeta.java new file mode 100644 index 0000000..5474c91 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/OsdMeta.java @@ -0,0 +1,411 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB in standard metadata mode. +// + +// java imports +// +import java.io.Serializable; + +// jmx imports +// +import javax.management.MBeanServer; +import com.sun.management.snmp.SnmpCounter; +import com.sun.management.snmp.SnmpCounter64; +import com.sun.management.snmp.SnmpGauge; +import com.sun.management.snmp.SnmpInt; +import com.sun.management.snmp.SnmpUnsignedInt; +import com.sun.management.snmp.SnmpIpAddress; +import com.sun.management.snmp.SnmpTimeticks; +import com.sun.management.snmp.SnmpOpaque; +import com.sun.management.snmp.SnmpString; +import com.sun.management.snmp.SnmpStringFixed; +import com.sun.management.snmp.SnmpOid; +import com.sun.management.snmp.SnmpNull; +import com.sun.management.snmp.SnmpValue; +import com.sun.management.snmp.SnmpVarBind; +import com.sun.management.snmp.SnmpStatusException; + +// jdmk imports +// +import com.sun.management.snmp.agent.SnmpMib; +import com.sun.management.snmp.agent.SnmpMibGroup; +import com.sun.management.snmp.agent.SnmpStandardObjectServer; +import com.sun.management.snmp.agent.SnmpStandardMetaServer; +import com.sun.management.snmp.agent.SnmpMibSubRequest; +import com.sun.management.snmp.agent.SnmpMibTable; +import com.sun.management.snmp.EnumRowStatus; +import com.sun.management.snmp.SnmpDefinitions; + +/** + * The class is used for representing SNMP metadata for the "Osd" group. + * The group is defined with the following oid: 1.3.6.1.4.1.38350.4. + */ +public class OsdMeta extends SnmpMibGroup + implements Serializable, SnmpStandardMetaServer { + + /** + * Constructor for the metadata associated to "Osd". + */ + public OsdMeta(SnmpMib myMib, SnmpStandardObjectServer objserv) { + objectserver = objserv; + try { + registerObject(9); + registerObject(8); + registerObject(7); + registerObject(6); + registerObject(5); + registerObject(4); + registerObject(12); + registerObject(3); + registerObject(2); + registerObject(11); + registerObject(1); + registerObject(10); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } + + /** + * Get the value of a scalar variable + */ + public SnmpValue get(long var, Object data) + throws SnmpStatusException { + switch((int)var) { + case 9: + return new SnmpInt(node.getDeletionStageQueueLength()); + + case 8: + return new SnmpInt(node.getStorageStageQueueLength()); + + case 7: + return new SnmpInt(node.getPreprocStageQueueLength()); + + case 6: + return new SnmpCounter64(node.getNumBytesTX()); + + case 5: + return new SnmpCounter64(node.getNumBytesRX()); + + case 4: + return new SnmpCounter64(node.getNumReplBytesRX()); + + case 12: + return new SnmpCounter64(node.getFreeSpace()); + + case 3: + return new SnmpCounter64(node.getNumObjsTX()); + + case 2: + return new SnmpCounter64(node.getNumReplObjsRX()); + + case 11: + return new SnmpCounter64(node.getNumDeletedFiles()); + + case 1: + return new SnmpCounter64(node.getNumObjsRX()); + + case 10: + return new SnmpInt(node.getNumOpenFiles()); + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.noSuchObject); + } + + /** + * Set the value of a scalar variable + */ + public SnmpValue set(SnmpValue x, long var, Object data) + throws SnmpStatusException { + switch((int)var) { + case 9: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 8: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 7: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 6: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 5: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 4: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 12: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 3: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 2: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 11: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 1: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 10: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + } + + /** + * Check the value of a scalar variable + */ + public void check(SnmpValue x, long var, Object data) + throws SnmpStatusException { + switch((int) var) { + case 9: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 8: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 7: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 6: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 5: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 4: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 12: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 3: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 2: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 11: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 1: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + case 10: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + + default: + throw new SnmpStatusException(SnmpStatusException.snmpRspNotWritable); + } + } + + /** + * Allow to bind the metadata description to a specific object. + */ + protected void setInstance(OsdMBean var) { + node = var; + } + + + // ------------------------------------------------------------ + // + // Implements the "get" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void get(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.get(this,req,depth); + } + + + // ------------------------------------------------------------ + // + // Implements the "set" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void set(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.set(this,req,depth); + } + + + // ------------------------------------------------------------ + // + // Implements the "check" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void check(SnmpMibSubRequest req, int depth) + throws SnmpStatusException { + objectserver.check(this,req,depth); + } + + /** + * Returns true if "arc" identifies a scalar object. + */ + public boolean isVariable(long arc) { + + switch((int)arc) { + case 9: + case 8: + case 7: + case 6: + case 5: + case 4: + case 12: + case 3: + case 2: + case 11: + case 1: + case 10: + return true; + default: + break; + } + return false; + } + + /** + * Returns true if "arc" identifies a readable scalar object. + */ + public boolean isReadable(long arc) { + + switch((int)arc) { + case 9: + case 8: + case 7: + case 6: + case 5: + case 4: + case 12: + case 3: + case 2: + case 11: + case 1: + case 10: + return true; + default: + break; + } + return false; + } + + + // ------------------------------------------------------------ + // + // Implements the "skipVariable" method defined in "SnmpMibGroup". + // See the "SnmpMibGroup" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public boolean skipVariable(long var, Object data, int pduVersion) { + switch((int)var) { + case 6: + case 5: + case 4: + case 12: + case 3: + case 2: + case 11: + case 1: + if (pduVersion==SnmpDefinitions.snmpVersionOne) return true; + break; + default: + break; + } + return false; + } + + /** + * Return the name of the attribute corresponding to the SNMP variable identified by "id". + */ + public String getAttributeName(long id) + throws SnmpStatusException { + switch((int)id) { + case 9: + return "DeletionStageQueueLength"; + + case 8: + return "StorageStageQueueLength"; + + case 7: + return "PreprocStageQueueLength"; + + case 6: + return "NumBytesTX"; + + case 5: + return "NumBytesRX"; + + case 4: + return "NumReplBytesRX"; + + case 12: + return "FreeSpace"; + + case 3: + return "NumObjsTX"; + + case 2: + return "NumReplObjsRX"; + + case 11: + return "NumDeletedFiles"; + + case 1: + return "NumObjsRX"; + + case 10: + return "NumOpenFiles"; + + default: + break; + } + throw new SnmpStatusException(SnmpStatusException.noSuchObject); + } + + /** + * Returns true if "arc" identifies a table object. + */ + public boolean isTable(long arc) { + + switch((int)arc) { + default: + break; + } + return false; + } + + /** + * Returns the table object identified by "arc". + */ + public SnmpMibTable getTable(long arc) { + return null; + } + + /** + * Register the group's SnmpMibTable objects with the meta-data. + */ + public void registerTableNodes(SnmpMib mib, MBeanServer server) { + } + + protected OsdMBean node; + protected SnmpStandardObjectServer objectserver = null; +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/XTREEMFS_MIB.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/XTREEMFS_MIB.java new file mode 100644 index 0000000..10eaf15 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/XTREEMFS_MIB.java @@ -0,0 +1,526 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB in standard metadata mode. +// + +// java imports +// +import java.io.Serializable; +import java.util.Hashtable; + +// jmx imports +// +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.InstanceAlreadyExistsException; + +// jdmk imports +// +import com.sun.management.snmp.agent.SnmpMib; +import com.sun.management.snmp.agent.SnmpMibNode; +import com.sun.management.snmp.agent.SnmpMibTable; +import com.sun.management.snmp.agent.SnmpStandardObjectServer; + +/** + * The class is used for representing "XTREEMFS-MIB". + * You can edit the file if you want to modify the behavior of the MIB. + */ +public class XTREEMFS_MIB extends SnmpMib implements Serializable { + + /** + * Default constructor. Initialize the Mib tree. + */ + public XTREEMFS_MIB() { + mibName = "XTREEMFS_MIB"; + } + + /** + * Initialization of the MIB with no registration in Java DMK. + */ + public void init() throws IllegalAccessException { + // Allow only one initialization of the MIB. + // + if (isInitialized == true) { + return ; + } + + try { + populate(null, null); + } catch(IllegalAccessException x) { + throw x; + } catch(RuntimeException x) { + throw x; + } catch(Exception x) { + throw new Error(x.getMessage()); + } + + isInitialized = true; + } + + /** + * Initialization of the MIB with AUTOMATIC REGISTRATION in Java DMK. + */ + public ObjectName preRegister(MBeanServer server, ObjectName name) + throws Exception { + // Allow only one initialization of the MIB. + // + if (isInitialized == true) { + throw new InstanceAlreadyExistsException(); + } + + // Initialize MBeanServer information. + // + this.server = server; + + populate(server, name); + + isInitialized = true; + return name; + } + + /** + * Initialization of the MIB with no registration in Java DMK. + */ + public void populate(MBeanServer server, ObjectName name) + throws Exception { + // Allow only one initialization of the MIB. + // + if (isInitialized == true) { + return ; + } + + if (objectserver == null) + objectserver = new SnmpStandardObjectServer(); + + // Initialization of the "Osd" group. + // To disable support of this group, redefine the + // "createOsdMetaNode()" factory method, and make it return "null" + // + initOsd(server); + + // Initialization of the "Mrc" group. + // To disable support of this group, redefine the + // "createMrcMetaNode()" factory method, and make it return "null" + // + initMrc(server); + + // Initialization of the "Dir" group. + // To disable support of this group, redefine the + // "createDirMetaNode()" factory method, and make it return "null" + // + initDir(server); + + // Initialization of the "General" group. + // To disable support of this group, redefine the + // "createGeneralMetaNode()" factory method, and make it return "null" + // + initGeneral(server); + + isInitialized = true; + } + + + // ------------------------------------------------------------ + // + // Initialization of the "Osd" group. + // + // ------------------------------------------------------------ + + + /** + * Initialization of the "Osd" group. + * + * To disable support of this group, redefine the + * "createOsdMetaNode()" factory method, and make it return "null" + * + * @param server MBeanServer for this group (may be null) + * + **/ + protected void initOsd(MBeanServer server) + throws Exception { + final String oid = getGroupOid("Osd", "1.3.6.1.4.1.38350.4"); + ObjectName objname = null; + if (server != null) { + objname = getGroupObjectName("Osd", oid, mibName + ":name=org.xtreemfs.common.monitoring.generatedcode.Osd"); + } + final OsdMeta meta = createOsdMetaNode("Osd", oid, objname, server); + if (meta != null) { + meta.registerTableNodes( this, server ); + + // Note that when using standard metadata, + // the returned object must implement the "OsdMBean" + // interface. + // + final OsdMBean group = (OsdMBean) createOsdMBean("Osd", oid, objname, server); + meta.setInstance( group ); + registerGroupNode("Osd", oid, objname, meta, group, server); + } + } + + + /** + * Factory method for "Osd" group metadata class. + * + * You can redefine this method if you need to replace the default + * generated metadata class with your own customized class. + * + * @param groupName Name of the group ("Osd") + * @param groupOid OID of this group + * @param groupObjname ObjectName for this group (may be null) + * @param server MBeanServer for this group (may be null) + * + * @return An instance of the metadata class generated for the + * "Osd" group (OsdMeta) + * + **/ + protected OsdMeta createOsdMetaNode(String groupName, + String groupOid, ObjectName groupObjname, MBeanServer server) { + return new OsdMeta(this, objectserver); + } + + + /** + * Factory method for "Osd" group MBean. + * + * You can redefine this method if you need to replace the default + * generated MBean class with your own customized class. + * + * @param groupName Name of the group ("Osd") + * @param groupOid OID of this group + * @param groupObjname ObjectName for this group (may be null) + * @param server MBeanServer for this group (may be null) + * + * @return An instance of the MBean class generated for the + * "Osd" group (Osd) + * + * Note that when using standard metadata, + * the returned object must implement the "OsdMBean" + * interface. + **/ + protected Object createOsdMBean(String groupName, + String groupOid, ObjectName groupObjname, MBeanServer server) { + + // Note that when using standard metadata, + // the returned object must implement the "OsdMBean" + // interface. + // + if (server != null) + return new Osd(this,server); + else + return new Osd(this); + } + + + // ------------------------------------------------------------ + // + // Initialization of the "Mrc" group. + // + // ------------------------------------------------------------ + + + /** + * Initialization of the "Mrc" group. + * + * To disable support of this group, redefine the + * "createMrcMetaNode()" factory method, and make it return "null" + * + * @param server MBeanServer for this group (may be null) + * + **/ + protected void initMrc(MBeanServer server) + throws Exception { + final String oid = getGroupOid("Mrc", "1.3.6.1.4.1.38350.3"); + ObjectName objname = null; + if (server != null) { + objname = getGroupObjectName("Mrc", oid, mibName + ":name=org.xtreemfs.common.monitoring.generatedcode.Mrc"); + } + final MrcMeta meta = createMrcMetaNode("Mrc", oid, objname, server); + if (meta != null) { + meta.registerTableNodes( this, server ); + + // Note that when using standard metadata, + // the returned object must implement the "MrcMBean" + // interface. + // + final MrcMBean group = (MrcMBean) createMrcMBean("Mrc", oid, objname, server); + meta.setInstance( group ); + registerGroupNode("Mrc", oid, objname, meta, group, server); + } + } + + + /** + * Factory method for "Mrc" group metadata class. + * + * You can redefine this method if you need to replace the default + * generated metadata class with your own customized class. + * + * @param groupName Name of the group ("Mrc") + * @param groupOid OID of this group + * @param groupObjname ObjectName for this group (may be null) + * @param server MBeanServer for this group (may be null) + * + * @return An instance of the metadata class generated for the + * "Mrc" group (MrcMeta) + * + **/ + protected MrcMeta createMrcMetaNode(String groupName, + String groupOid, ObjectName groupObjname, MBeanServer server) { + return new MrcMeta(this, objectserver); + } + + + /** + * Factory method for "Mrc" group MBean. + * + * You can redefine this method if you need to replace the default + * generated MBean class with your own customized class. + * + * @param groupName Name of the group ("Mrc") + * @param groupOid OID of this group + * @param groupObjname ObjectName for this group (may be null) + * @param server MBeanServer for this group (may be null) + * + * @return An instance of the MBean class generated for the + * "Mrc" group (Mrc) + * + * Note that when using standard metadata, + * the returned object must implement the "MrcMBean" + * interface. + **/ + protected Object createMrcMBean(String groupName, + String groupOid, ObjectName groupObjname, MBeanServer server) { + + // Note that when using standard metadata, + // the returned object must implement the "MrcMBean" + // interface. + // + if (server != null) + return new Mrc(this,server); + else + return new Mrc(this); + } + + + // ------------------------------------------------------------ + // + // Initialization of the "Dir" group. + // + // ------------------------------------------------------------ + + + /** + * Initialization of the "Dir" group. + * + * To disable support of this group, redefine the + * "createDirMetaNode()" factory method, and make it return "null" + * + * @param server MBeanServer for this group (may be null) + * + **/ + protected void initDir(MBeanServer server) + throws Exception { + final String oid = getGroupOid("Dir", "1.3.6.1.4.1.38350.2"); + ObjectName objname = null; + if (server != null) { + objname = getGroupObjectName("Dir", oid, mibName + ":name=org.xtreemfs.common.monitoring.generatedcode.Dir"); + } + final DirMeta meta = createDirMetaNode("Dir", oid, objname, server); + if (meta != null) { + meta.registerTableNodes( this, server ); + + // Note that when using standard metadata, + // the returned object must implement the "DirMBean" + // interface. + // + final DirMBean group = (DirMBean) createDirMBean("Dir", oid, objname, server); + meta.setInstance( group ); + registerGroupNode("Dir", oid, objname, meta, group, server); + } + } + + + /** + * Factory method for "Dir" group metadata class. + * + * You can redefine this method if you need to replace the default + * generated metadata class with your own customized class. + * + * @param groupName Name of the group ("Dir") + * @param groupOid OID of this group + * @param groupObjname ObjectName for this group (may be null) + * @param server MBeanServer for this group (may be null) + * + * @return An instance of the metadata class generated for the + * "Dir" group (DirMeta) + * + **/ + protected DirMeta createDirMetaNode(String groupName, + String groupOid, ObjectName groupObjname, MBeanServer server) { + return new DirMeta(this, objectserver); + } + + + /** + * Factory method for "Dir" group MBean. + * + * You can redefine this method if you need to replace the default + * generated MBean class with your own customized class. + * + * @param groupName Name of the group ("Dir") + * @param groupOid OID of this group + * @param groupObjname ObjectName for this group (may be null) + * @param server MBeanServer for this group (may be null) + * + * @return An instance of the MBean class generated for the + * "Dir" group (Dir) + * + * Note that when using standard metadata, + * the returned object must implement the "DirMBean" + * interface. + **/ + protected Object createDirMBean(String groupName, + String groupOid, ObjectName groupObjname, MBeanServer server) { + + // Note that when using standard metadata, + // the returned object must implement the "DirMBean" + // interface. + // + if (server != null) + return new Dir(this,server); + else + return new Dir(this); + } + + + // ------------------------------------------------------------ + // + // Initialization of the "General" group. + // + // ------------------------------------------------------------ + + + /** + * Initialization of the "General" group. + * + * To disable support of this group, redefine the + * "createGeneralMetaNode()" factory method, and make it return "null" + * + * @param server MBeanServer for this group (may be null) + * + **/ + protected void initGeneral(MBeanServer server) + throws Exception { + final String oid = getGroupOid("General", "1.3.6.1.4.1.38350.1"); + ObjectName objname = null; + if (server != null) { + objname = getGroupObjectName("General", oid, mibName + ":name=org.xtreemfs.common.monitoring.generatedcode.General"); + } + final GeneralMeta meta = createGeneralMetaNode("General", oid, objname, server); + if (meta != null) { + meta.registerTableNodes( this, server ); + + // Note that when using standard metadata, + // the returned object must implement the "GeneralMBean" + // interface. + // + final GeneralMBean group = (GeneralMBean) createGeneralMBean("General", oid, objname, server); + meta.setInstance( group ); + registerGroupNode("General", oid, objname, meta, group, server); + } + } + + + /** + * Factory method for "General" group metadata class. + * + * You can redefine this method if you need to replace the default + * generated metadata class with your own customized class. + * + * @param groupName Name of the group ("General") + * @param groupOid OID of this group + * @param groupObjname ObjectName for this group (may be null) + * @param server MBeanServer for this group (may be null) + * + * @return An instance of the metadata class generated for the + * "General" group (GeneralMeta) + * + **/ + protected GeneralMeta createGeneralMetaNode(String groupName, + String groupOid, ObjectName groupObjname, MBeanServer server) { + return new GeneralMeta(this, objectserver); + } + + + /** + * Factory method for "General" group MBean. + * + * You can redefine this method if you need to replace the default + * generated MBean class with your own customized class. + * + * @param groupName Name of the group ("General") + * @param groupOid OID of this group + * @param groupObjname ObjectName for this group (may be null) + * @param server MBeanServer for this group (may be null) + * + * @return An instance of the MBean class generated for the + * "General" group (General) + * + * Note that when using standard metadata, + * the returned object must implement the "GeneralMBean" + * interface. + **/ + protected Object createGeneralMBean(String groupName, + String groupOid, ObjectName groupObjname, MBeanServer server) { + + // Note that when using standard metadata, + // the returned object must implement the "GeneralMBean" + // interface. + // + if (server != null) + return new General(this,server); + else + return new General(this); + } + + + // ------------------------------------------------------------ + // + // Implements the "registerTableMeta" method defined in "SnmpMib". + // See the "SnmpMib" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public void registerTableMeta( String name, SnmpMibTable meta) { + if (metadatas == null) return; + if (name == null) return; + metadatas.put(name,meta); + } + + + // ------------------------------------------------------------ + // + // Implements the "getRegisteredTableMeta" method defined in "SnmpMib". + // See the "SnmpMib" Javadoc API for more details. + // + // ------------------------------------------------------------ + + public SnmpMibTable getRegisteredTableMeta( String name ) { + if (metadatas == null) return null; + if (name == null) return null; + return (SnmpMibTable) metadatas.get(name); + } + + public SnmpStandardObjectServer getStandardObjectServer() { + if (objectserver == null) + objectserver = new SnmpStandardObjectServer(); + return objectserver; + } + + private boolean isInitialized = false; + + protected SnmpStandardObjectServer objectserver; + + protected final Hashtable metadatas = new Hashtable(); +} diff --git a/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/XTREEMFS_MIBOidTable.java b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/XTREEMFS_MIBOidTable.java new file mode 100644 index 0000000..77a3e8f --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/monitoring/generatedcode/XTREEMFS_MIBOidTable.java @@ -0,0 +1,62 @@ +package org.xtreemfs.common.monitoring.generatedcode; + +// +// Generated by mibgen version 5.1 (03/08/07) when compiling XTREEMFS-MIB. +// + +// java imports +// +import java.io.Serializable; + +// jmx imports +// +import com.sun.management.snmp.SnmpOidRecord; + +// jdmk imports +// +import com.sun.management.snmp.SnmpOidTableSupport; + +/** + * The class contains metadata definitions for "XTREEMFS-MIB". + * Call SnmpOid.setSnmpOidTable(new XTREEMFS_MIBOidTable()) to load the metadata in the SnmpOidTable. + */ +public class XTREEMFS_MIBOidTable extends SnmpOidTableSupport implements Serializable { + + /** + * Default constructor. Initialize the Mib tree. + */ + public XTREEMFS_MIBOidTable() { + super("XTREEMFS_MIB"); + loadMib(varList); + } + + static SnmpOidRecord varList [] = { + new SnmpOidRecord("deletionStageQueueLength", "1.3.6.1.4.1.38350.4.9", "I"), + new SnmpOidRecord("storageStageQueueLength", "1.3.6.1.4.1.38350.4.8", "I"), + new SnmpOidRecord("preprocStageQueueLength", "1.3.6.1.4.1.38350.4.7", "I"), + new SnmpOidRecord("numBytesTX", "1.3.6.1.4.1.38350.4.6", "C64"), + new SnmpOidRecord("numBytesRX", "1.3.6.1.4.1.38350.4.5", "C64"), + new SnmpOidRecord("numReplBytesRX", "1.3.6.1.4.1.38350.4.4", "C64"), + new SnmpOidRecord("freeSpace", "1.3.6.1.4.1.38350.4.12", "C64"), + new SnmpOidRecord("numObjsTX", "1.3.6.1.4.1.38350.4.3", "C64"), + new SnmpOidRecord("numReplObjsRX", "1.3.6.1.4.1.38350.4.2", "C64"), + new SnmpOidRecord("numDeletedFiles", "1.3.6.1.4.1.38350.4.11", "C64"), + new SnmpOidRecord("numObjsRX", "1.3.6.1.4.1.38350.4.1", "C64"), + new SnmpOidRecord("numOpenFiles", "1.3.6.1.4.1.38350.4.10", "I"), + new SnmpOidRecord("volumeCount", "1.3.6.1.4.1.38350.3.1", "I"), + new SnmpOidRecord("serviceCount", "1.3.6.1.4.1.38350.2.2", "I"), + new SnmpOidRecord("addressMappingCount", "1.3.6.1.4.1.38350.2.1", "I"), + new SnmpOidRecord("numPendingRequests", "1.3.6.1.4.1.38350.1.9", "C64"), + new SnmpOidRecord("numClientConnections", "1.3.6.1.4.1.38350.1.8", "I"), + new SnmpOidRecord("debugLevel", "1.3.6.1.4.1.38350.1.7", "I"), + new SnmpOidRecord("tcpPort", "1.3.6.1.4.1.38350.1.6", "I"), + new SnmpOidRecord("databaseVersion", "1.3.6.1.4.1.38350.1.5", "S"), + new SnmpOidRecord("rpcInterface", "1.3.6.1.4.1.38350.1.4", "I"), + new SnmpOidRecord("serviceUUID", "1.3.6.1.4.1.38350.1.13", "S"), + new SnmpOidRecord("serviceType", "1.3.6.1.4.1.38350.1.12", "S"), + new SnmpOidRecord("jvmFreeMemory", "1.3.6.1.4.1.38350.1.3", "C64"), + new SnmpOidRecord("jvmMaxMemory", "1.3.6.1.4.1.38350.1.2", "C64"), + new SnmpOidRecord("isRunning", "1.3.6.1.4.1.38350.1.11", "S"), + new SnmpOidRecord("currentTime", "1.3.6.1.4.1.38350.1.10", "C64"), + new SnmpOidRecord("jvmUsedMemory", "1.3.6.1.4.1.38350.1.1", "C64") }; +} diff --git a/java/servers/src/org/xtreemfs/common/statusserver/BabuDBStatusPage.java b/java/servers/src/org/xtreemfs/common/statusserver/BabuDBStatusPage.java new file mode 100644 index 0000000..1415cfb --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/statusserver/BabuDBStatusPage.java @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2013 Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.statusserver; + +import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; + +import com.sun.net.httpserver.HttpExchange; + +/** + * Serves a simple HTML status page with BabuDBs runtime state. + */ +public class BabuDBStatusPage extends StatusServerModule { + + private final BabuDBStatusProvider statusProvider; + + public BabuDBStatusPage(BabuDBStatusProvider statusProvider) { + this.statusProvider = statusProvider; + } + + @Override + public String getDisplayName() { + return "BabuDB Status Summary"; + } + + @Override + public String getUriPath() { + return "/babudb"; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + StringBuilder sb = new StringBuilder(); + sb.append("

    BABUDB STATE

    "); + + Map dbStatus = statusProvider.getStatus(); + if (dbStatus == null) { + sb.append("BabuDB has not yet been initialized."); + } else { + sb.append(""); + Map status = new TreeMap(dbStatus); + for (Entry entry : status.entrySet()) { + sb.append(""); + } + sb.append("
    "); + sb.append(entry.getKey()); + sb.append(":"); + sb.append(entry.getValue()); + sb.append("
    "); + } + + sb.append(""); + + sendResponse(httpExchange, sb.toString()); + httpExchange.close(); + } + + @Override + public boolean isAvailableForService(ServiceType service) { + return true; + } + + @Override + public void initialize(ServiceType service, Object serviceRequestDispatcher) { + } + + @Override + public void shutdown() { + } + + /** + * Simple interface which is used to provide the BabuDB status when the page is served. + */ + public interface BabuDBStatusProvider { + Map getStatus(); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/statusserver/PrintStackTrace.java b/java/servers/src/org/xtreemfs/common/statusserver/PrintStackTrace.java new file mode 100644 index 0000000..d2b0a11 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/statusserver/PrintStackTrace.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012 by Bjoern Kolbeck. + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.statusserver; + +import java.io.IOException; + +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; + +import com.sun.net.httpserver.HttpExchange; + +/** + * Status page that shows the stack traces of all threads in the VM. + * + * @author bjko + */ +public class PrintStackTrace extends StatusServerModule { + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + sendResponse(httpExchange, OutputUtils.getThreadDump()); + } + + @Override + public String getDisplayName() { + return "Thread Status Page"; + } + + @Override + public String getUriPath() { + return "/strace"; + } + + @Override + public boolean isAvailableForService(ServiceType service) { + return true; // Available for all services. + } + + @Override + public void initialize(ServiceType service, Object serviceRequestDispatcher) { + // Noop. + } + + @Override + public void shutdown() { + // Noop. + } + +} diff --git a/java/servers/src/org/xtreemfs/common/statusserver/StatusServer.java b/java/servers/src/org/xtreemfs/common/statusserver/StatusServer.java new file mode 100644 index 0000000..82c3e89 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/statusserver/StatusServer.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2012 by Bjoern Kolbeck. + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.statusserver; + +import java.io.IOException; +import java.net.BindException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; + +import com.sun.net.httpserver.BasicAuthenticator; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpServer; + +/** + * HTTP Server displaying status and debug information. + * + * @author bjko + */ +public class StatusServer { + /** + * Block server up to this time if the StatusServer cannot bind the port due to "Address already in use". + * Necessary because the Sun webserver does not support SO_REUSEADDR. + */ + private static final double MAX_TIME_CHECK_IF_ADDRESS_ALREADY_IN_USE_S = 180.0; + /** Interval between two attempts to start the webserver. */ + private static final double INTERVAL_CHECK_IF_ADDRESS_ALREADY_IN_USE_S = 0.1; + + private final int statusHttpPort; + private final List modules; + private final ServiceType serviceType; + private final Object serviceRequestDispatcher; + private final Map authorizedUsers; + + private HttpServer httpServ; + private BasicAuthenticator passwordProtection; + private boolean running; + + public StatusServer( + ServiceType serviceType, + Object serviceRequestDispatcher, + int statusHttpPort) { + this.serviceType = serviceType; + this.serviceRequestDispatcher = serviceRequestDispatcher; + this.statusHttpPort = statusHttpPort; + authorizedUsers = new HashMap(); + modules = new ArrayList(); + running = false; + } + + /** + * Adds a user to the list of authorized users that can access status pages. + */ + public void addAuthorizedUser(String userName, String password) { + if (running) { + throw new IllegalStateException("Cannot add users after startup."); + } + // TODO(bjko): Don't store plaintext passwords. + authorizedUsers.put(userName, password); + } + + public void start() throws IOException { + if (!authorizedUsers.isEmpty()) { + passwordProtection = new BasicAuthenticator("XtreemFS " + serviceType) { + + @Override + public boolean checkCredentials(String userName, String password) { + String storedPassword = authorizedUsers.get(userName); + return storedPassword != null && storedPassword.equals(password); + } + }; + } else { + passwordProtection = null; + } + + // Try to start the webserver and bind the port. Retry if "address already in use" because the Sun + // webserver does not support SO_REUSEADDR. + for (double elapsedSeconds = 0.0; + elapsedSeconds < MAX_TIME_CHECK_IF_ADDRESS_ALREADY_IN_USE_S; + elapsedSeconds += INTERVAL_CHECK_IF_ADDRESS_ALREADY_IN_USE_S) { + try { + httpServ = HttpServer.create(new InetSocketAddress(statusHttpPort), 0); + // Port successfully bound, do not retry. + break; + } catch (BindException e) { + if (e.getMessage().contains("Address already in use")) { + if ((elapsedSeconds + INTERVAL_CHECK_IF_ADDRESS_ALREADY_IN_USE_S) >= MAX_TIME_CHECK_IF_ADDRESS_ALREADY_IN_USE_S) { + // Retries exceeded. Throw error. + throw new BindException(e.getMessage() + ". Port number: " + statusHttpPort); + } else { + // Wait between two attempts. + try { + Thread.sleep((long) (INTERVAL_CHECK_IF_ADDRESS_ALREADY_IN_USE_S * 1000)); + } catch (InterruptedException e1) { + } + } + } else { + throw e; + } + } + } + running = true; + for (StatusServerModule module : modules) { + String modulePath = module.getUriPath(); + if (modulePath.isEmpty()) { + Logging.logMessage( + Logging.LEVEL_ERROR, + this, + "Invalid path or path for module %s", + module.getClass().getCanonicalName()); + + } + HttpContext context = httpServ.createContext(module.getUriPath(), module); + if (passwordProtection != null) { + context.setAuthenticator(passwordProtection); + } + module.initialize(serviceType, serviceRequestDispatcher); + } + httpServ.start(); + } + + public void shutdown() { + if (running) { + httpServ.stop(0); + for (StatusServerModule module : modules) { + module.shutdown(); + } + } + } + + public void registerModule(StatusServerModule module) { + if (running) { + throw new IllegalStateException("Cannot add modules after calling start()"); + } + if (module.isAvailableForService(serviceType)) { + modules.add(module); + } else { + Logging.logMessage(Logging.LEVEL_INFO, + this, + "Module %s not suitable for service %s, skipping module", + module.getClass().getCanonicalName(), + serviceType); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/common/statusserver/StatusServerHelper.java b/java/servers/src/org/xtreemfs/common/statusserver/StatusServerHelper.java new file mode 100644 index 0000000..d7ac712 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/statusserver/StatusServerHelper.java @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2013 Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.statusserver; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; + +import com.sun.net.httpserver.HttpExchange; + +/** + * Provides useful helper methods, that can be used in StatusServerModules. + */ +public class StatusServerHelper { + + /** + * Finds the resource with the given name and reads it to a StringBuffer. + * + * @see Class#getResourceAsStream() + * + * @param name + * Name of the resource + * @return StringBuffer with the contents of the template or null on errors + */ + public static StringBuffer readTemplate(String name) { + StringBuffer sb = null; + BufferedReader br = null; + + try { + InputStream is = StatusServerHelper.class.getClassLoader().getResourceAsStream(name); + if (is == null) { + throw new FileNotFoundException(); + } + + br = new BufferedReader(new InputStreamReader(is)); + sb = new StringBuffer(); + + String line = br.readLine(); + while (line != null) { + sb.append(line + "\n"); + line = br.readLine(); + } + } catch (IOException ex) { + sb = null; + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, (Object) null, + "could not load page template '%s': %s", name, OutputUtils.stackTraceToString(ex)); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { } + } + } + + return sb; + } + + /** + * Finds the resource with the given name and sends it as a response to a HTTP request. + * + * @see Class#getResourceAsStream() + * + * @param name + * Name of the resource + * @param httpExchange + * HTTP request the file will be delivered to + * @throws IOException + */ + public static void sendFile(String name, HttpExchange httpExchange) throws IOException { + InputStream htmlFile = null; + try { + htmlFile = StatusServerHelper.class.getClassLoader().getResourceAsStream(name); + if (htmlFile == null) { + throw new FileNotFoundException(); + } + + httpExchange.getResponseHeaders().add("Content-Type", "text/html; charset=UTF-8"); + httpExchange.sendResponseHeaders(200, 0); + + byte[] buffer = new byte[4096]; + int len = 0; + while ((len = htmlFile.read(buffer)) >= 0) { + httpExchange.getResponseBody().write(buffer, 0, len); + } + + } catch (IOException e) { + byte[] msg = ("Sorry, could not read the requested file " + name + " (" + e.toString() + ")") + .getBytes("ascii"); + + httpExchange.getResponseHeaders().add("Content-Type", "text/html; charset=UTF-8"); + httpExchange.sendResponseHeaders(404, msg.length); + httpExchange.getResponseBody().write(msg); + + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, (Object) null, "could not read page '%s': %s", name, + OutputUtils.stackTraceToString(e)); + } finally { + httpExchange.close(); + if (htmlFile != null) { + try { + htmlFile.close(); + } catch (IOException e) { } + } + } + } + +} diff --git a/java/servers/src/org/xtreemfs/common/statusserver/StatusServerModule.java b/java/servers/src/org/xtreemfs/common/statusserver/StatusServerModule.java new file mode 100644 index 0000000..d85ded8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/statusserver/StatusServerModule.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012 by Bjoern Kolbeck. + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.statusserver; + +import java.io.IOException; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +/** + * Status Server module to display information about a service. + */ +public abstract class StatusServerModule implements HttpHandler { + + /** + * Name which is shown to the user. + */ + public abstract String getDisplayName(); + + /** + * Path for accessing this module. + */ + public abstract String getUriPath(); + + /** + * Should return true, if the module is suiatble for a service type. + */ + public abstract boolean isAvailableForService(ServiceType service); + + /** + * Initialize instance of the module for a service. + * @param service indicates the service type for which the module is initialized. + * @param serviceRequestDispatcher request dispatcher of service, must be casted according + * to the service type running. + */ + public abstract void initialize(ServiceType service, Object serviceRequestDispatcher); + + /** + * Shuts down the module, should also end any tasks/threads started. + */ + public abstract void shutdown(); + + protected void sendResponse(HttpExchange httpExchange, String html) throws IOException { + try { + byte[] content = html.getBytes("UTF-8"); + httpExchange.getResponseHeaders().add("Content-Type", "text/html; charset=UTF-8"); + httpExchange.sendResponseHeaders(200, content.length); + httpExchange.getResponseBody().write(content); + httpExchange.getResponseBody().close(); + } catch (Exception ex) { + Logging.logMessage( + Logging.LEVEL_ERROR, + this, + "Error while sending response for module %s: %s", + this.getClass().getCanonicalName(), + ex.toString()); + httpExchange.sendResponseHeaders(500, 0); + httpExchange.getResponseBody().close(); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/common/util/NetUtils.java b/java/servers/src/org/xtreemfs/common/util/NetUtils.java new file mode 100644 index 0000000..680a897 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/util/NetUtils.java @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.util; + +import java.io.IOException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InterfaceAddress; +import java.net.NetworkInterface; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping; + +public class NetUtils { + + /** + * Returns a list of mappings for all reachable network endpoints. + * + * The returned list contains global addresses in front of local ones. + * + * @param port + * The port to assign to the mappings. + * @param protocol + * The protocol for the endpoint. + * + * @return A list of mappings, containing global ones up front. + * @throws IOException + */ + public static List getReachableEndpoints(int port, String protocol) throws IOException { + + List endpoints = new ArrayList(); + List localEndpoints = new ArrayList(); + + // Iterate over the existing network interfaces and their addresses. + Enumeration ifcs = NetworkInterface.getNetworkInterfaces(); + while (ifcs.hasMoreElements()) { + NetworkInterface ifc = ifcs.nextElement(); + + // Ignore loopback interfaces and interfaces that are down. + if (ifc.isLoopback() || !ifc.isUp()) + continue; + + List addrs = ifc.getInterfaceAddresses(); + for (InterfaceAddress addr : addrs) { + InetAddress inetAddr = addr.getAddress(); + + // Ignore local, wildcard and multicast addresses. + if (inetAddr.isLoopbackAddress() || inetAddr.isLinkLocalAddress() + || inetAddr.isAnyLocalAddress() || inetAddr.isMulticastAddress()) + continue; + + final String hostAddr = getHostAddress(inetAddr); + final String uri = getURI(protocol, inetAddr, port); + final String network = getNetworkCIDR(inetAddr, addr.getNetworkPrefixLength()); + AddressMapping.Builder amap = AddressMapping.newBuilder().setAddress(hostAddr).setPort(port) + .setMatchNetwork(network).setProtocol(protocol).setTtlS(3600).setUri(uri).setVersion(0) + .setUuid(""); + + if (inetAddr.isSiteLocalAddress()) { + localEndpoints.add(amap); + } else { + endpoints.add(amap); + } + } + } + + // Append the local endpoints to the end of the list containing the global ones. + endpoints.addAll(localEndpoints); + + return endpoints; + } + + public static String getHostAddress(InetAddress host) { + + String hostAddr = host.getHostAddress(); + if (host instanceof Inet6Address) { + if (hostAddr.lastIndexOf('%') >= 0) { + hostAddr = hostAddr.substring(0, hostAddr.lastIndexOf('%')); + } + } + + return hostAddr; + + } + + public static String getURI(String protocol, InetAddress host, int port) { + + String hostAddr = host.getHostAddress(); + if (host instanceof Inet6Address) { + if (hostAddr.lastIndexOf('%') >= 0) { + hostAddr = hostAddr.substring(0, hostAddr.lastIndexOf('%')); + } + hostAddr = "["+hostAddr+"]"; + } + + return protocol+"://"+hostAddr+":"+port; + + } + + /** + * Creates a clone of the {@link AddressMapping.Builder} passed as src and replaces the + * protocol in the corresponding field and the uri string. + * + * @param src + * {@link AddressMapping.Builder} whose protocol should be replaced. + * @param protocol + * The new protocol used for the mapping. + * @return Clone of the passed src with the protocol replaced. + */ + public static AddressMapping.Builder cloneMappingForProtocol(AddressMapping.Builder src, String protocol) { + // An uri looks like "protocol://address:port". The following code replaces the "protocol" part. + String uri = protocol + src.getUri().substring(src.getUri().indexOf("://")); + AddressMapping.Builder result = src.clone() + .setProtocol(protocol).setUri(uri); + return result; + } + + public static String getDomain(String hostName) { + int i = hostName.indexOf('.'); + return i == -1? "": hostName.substring(i + 1); + } + + private static String getSubnetMaskString(short prefixLength) { + + long addr = (0xFFFFFFFFL << (32 - prefixLength)) & 0xFFFFFFFFL; + StringBuffer sb = new StringBuffer(); + for (int i = 3; i >= 0; i--) { + sb.append((addr & (0xFF << (i * 8))) >> (i * 8)); + if (i > 0) + sb.append("."); + } + + return sb.toString(); + } + + private static String getNetworkCIDR(InetAddress addr, short prefixLength) { + byte[] raw = addr.getAddress(); + + // If the address is more then 32bit long it has to be an v6 address. + boolean isV6 = raw.length > 4; + + // Get the number of fields that are network specific and null the remaining host fields. + int networkFields = prefixLength / 8; + for (int i = networkFields + 1; i < raw.length; i++) { + raw[i] = 0x00; + } + + // Get the remaining bytes attributed to the network amidst a byte field. + int networkRemainder = prefixLength % 8; + if (networkFields < raw.length) { + // Construct a 8bit mask, with bytes set for the network. + byte mask = (byte) (0xFF << (8 - networkRemainder)); + raw[networkFields] = (byte) (raw[networkFields] & mask); + } + + StringBuilder sb = new StringBuilder(); + + // Use the InetAddress implementation to convert the raw byte[] to a string. + try { + sb.append(InetAddress.getByAddress(raw).getHostAddress()); + } catch (UnknownHostException e) { + // This should never happen, since the foundation of every calculation is the byte array + // returned by a valid InetAddress. + throw new RuntimeException(e); + } + + sb.append("/").append(prefixLength); + + return sb.toString(); + } + + public static void main(String[] args) throws Exception { + + System.out.println("all network interfaces: "); + Enumeration ifcs = NetworkInterface.getNetworkInterfaces(); + while (ifcs.hasMoreElements()) { + for (InterfaceAddress addr : ifcs.nextElement().getInterfaceAddresses()) { + InetAddress inetAddr = addr.getAddress(); + System.out.println(inetAddr + ", loopback: " + inetAddr.isLoopbackAddress() + ", linklocal: " + + inetAddr.isLinkLocalAddress() + ", reachable: " + inetAddr.isReachable(1000)); + } + } + + System.out.println("\nsuitable network interfaces: "); + for (AddressMapping.Builder endpoint : NetUtils.getReachableEndpoints(32640, "http")) + System.out.println(endpoint.build().toString()); + } +} diff --git a/java/servers/src/org/xtreemfs/common/uuids/Mapping.java b/java/servers/src/org/xtreemfs/common/uuids/Mapping.java new file mode 100644 index 0000000..b4604bf --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/uuids/Mapping.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.uuids; + +import java.net.InetSocketAddress; + +public class Mapping { + + public String protocol; + + public InetSocketAddress resolvedAddr; + + /** Address of the service as returned by the DIR, Format: host:port. */ + public String address; + + public Mapping(String protocol, InetSocketAddress resolvedAddr, String address) { + this.protocol = protocol; + this.resolvedAddr = resolvedAddr; + this.address = address; + } + + public String toString() { + return this.protocol + "://" + this.resolvedAddr.getAddress().getHostAddress() + ":" + + this.resolvedAddr.getPort(); + } + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/common/uuids/ServiceUUID.java b/java/servers/src/org/xtreemfs/common/uuids/ServiceUUID.java new file mode 100644 index 0000000..8fd9253 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/uuids/ServiceUUID.java @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.uuids; + +import java.io.Serializable; +import java.net.InetSocketAddress; +import java.util.Arrays; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; + +/** + * Encapsules the UUID and InetSocketAddress for a service. + * + * @author bjko + */ +public final class ServiceUUID implements Serializable, Comparable { + + private final String uuid; + + private long validUntil; + + private UUIDCacheEntry cacheEntry; + + private final UUIDResolver nonSingleton; + + /** + * Creates a new ServiceUUID. + * + * @param uuid + * the uuid string + */ + public ServiceUUID(String uuid) { + this.uuid = uuid; + this.validUntil = 0; + this.nonSingleton = null; + } + + /** + * Creates a new ServiceUUID with an individual UUIDresolver (rather than + * the global instance) + * + * @param uuid + * the uuid string + */ + public ServiceUUID(String uuid, UUIDResolver nonSingleton) { + this.uuid = uuid; + this.validUntil = 0; + this.nonSingleton = nonSingleton; + } + + /** + * Creates a new ServiceUUID. + * + * @param uuid + * the uuid string. + */ + public ServiceUUID(ASCIIString uuid) { + this(uuid.toString()); + + } + + /** + * Resolves the uuid to a InetSocketAddress and protocol. + * + * @throws org.xtreemfs.common.uuids.UnknownUUIDException + * if the uuid cannot be resolved (not local, no mapping on + * DIR). + */ + public void resolve() throws UnknownUUIDException { + resolve(null); + } + + public void resolve(String protocol) throws UnknownUUIDException { + updateMe(protocol); + } + + /** + * Retrieves the InetSocketAddress for the service. + * + * @return the InetSocketAddress of the service + * @throws org.xtreemfs.common.uuids.UnknownUUIDException + * if the UUID cannot be resolved + */ + public Mapping[] getMappings() throws UnknownUUIDException { + if (validUntil > TimeSync.getLocalSystemTime()) { + cacheEntry.setLastAccess(TimeSync.getLocalSystemTime()); + } else { + updateMe(); + } + + return cacheEntry.getMappings(); + } + + /** + * Returns the first socket address from the list of mappings. + * + * @return the socket address associated with the first list entry + * @throws org.xtreemfs.common.uuids.UnknownUUIDException + * if the UUID cannot be resolved + */ + public InetSocketAddress getAddress() throws UnknownUUIDException { + return getMappings()[0].resolvedAddr; + } + + /** + * Returns the address as stored on the DIR. + * + * @return String of the form "host:port". + * @throws org.xtreemfs.common.uuids.UnknownUUIDException + * if the UUID cannot be resolved + */ + public String getAddressString() throws UnknownUUIDException { + return getMappings()[0].address; + } + + /** + * Returns the full URl of the service. + * + * @return the URL of the service + * @throws org.xtreemfs.common.uuids.UnknownUUIDException + * if the UUID cannot be resolved + */ + public String toURL() throws UnknownUUIDException { + if (validUntil > TimeSync.getLocalSystemTime()) { + cacheEntry.setLastAccess(TimeSync.getLocalSystemTime()); + } else { + updateMe(); + } + return cacheEntry.toString(); + } + + /** + * Get a details of the UUID mapping. + * + * @return details of the UUID mapping. + */ + public String debugString() { + String mappingsStr = cacheEntry == null ? "" : Arrays.toString(cacheEntry.getMappings()); + return this.uuid + " -> " + mappingsStr + " (still valid for " + + ((validUntil - TimeSync.getLocalSystemTime()) / 1000) + "s)"; + } + + /** + * return the UUID string + * + * @return UUID string + */ + public String toString() { + return this.uuid; + } + + @Override + public boolean equals(Object other) { + try { + final ServiceUUID o = (ServiceUUID) other; + return this.uuid.equals(o.uuid); + } catch (ClassCastException ex) { + return false; + } + } + + @Override + public int hashCode() { + return uuid.hashCode(); + } + + /** + * updates the UUID mapping via UUIDResolver + * + * @throws org.xtreemfs.common.uuids.UnknownUUIDException + */ + private void updateMe() throws UnknownUUIDException { + updateMe(null); + } + + private void updateMe(String protocol) throws UnknownUUIDException { + if (nonSingleton == null) { + cacheEntry = UUIDResolver.resolve(this.uuid, protocol); + } else { + cacheEntry = UUIDResolver.resolve(this.uuid, protocol, nonSingleton); + } + + this.validUntil = cacheEntry.getValidUntil(); + } + + @Override + public int compareTo(Object o) { + return uuid.compareTo((String) o); + } +} diff --git a/java/servers/src/org/xtreemfs/common/uuids/UUIDCacheEntry.java b/java/servers/src/org/xtreemfs/common/uuids/UUIDCacheEntry.java new file mode 100644 index 0000000..dc644d9 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/uuids/UUIDCacheEntry.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.uuids; + + +import org.xtreemfs.foundation.TimeSync; + +/** + * Cache entry for the UUIDResolver. + * + * @author bjko + */ +class UUIDCacheEntry { + + private String uuid; + + private Mapping[] mappings; + + private long validUntil; + + private long lastAccess; + + private boolean sticky; + + public UUIDCacheEntry(String uuid, long validUntil, Mapping... mappings) { + this.uuid = uuid; + this.mappings = mappings; + this.validUntil = validUntil; + this.lastAccess = TimeSync.getLocalSystemTime(); + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Mapping[] getMappings() { + return mappings; + } + + public void setMappings(Mapping... mappings) { + this.mappings = mappings; + } + + public void addMapping(Mapping mapping) { + Mapping[] tmp = this.mappings; + this.mappings = new Mapping[tmp.length + 1]; + System.arraycopy(tmp, 0, this.mappings, 0, tmp.length); + this.mappings[this.mappings.length - 1] = mapping; + } + + public long getValidUntil() { + return validUntil; + } + + public void setValidUntil(long validUntil) { + this.validUntil = validUntil; + } + + public long getLastAccess() { + return lastAccess; + } + + public void setLastAccess(long lastAccess) { + this.lastAccess = lastAccess; + } + + public boolean isSticky() { + return sticky; + } + + public void setSticky(boolean sticky) { + this.sticky = sticky; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + for (Mapping mapping : mappings) { + sb.append(mapping.protocol); + sb.append("://"); + sb.append(mapping.resolvedAddr.toString()); + sb.append(","); + } + return sb.toString(); + } +} diff --git a/java/servers/src/org/xtreemfs/common/uuids/UUIDResolver.java b/java/servers/src/org/xtreemfs/common/uuids/UUIDResolver.java new file mode 100644 index 0000000..a764920 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/uuids/UUIDResolver.java @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.uuids; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import org.xtreemfs.common.GlobalConstants; +import org.xtreemfs.common.util.NetUtils; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet; + +/** + * Resolves UUID to InetSocketAddress+Protocol mappings. + * + * @author bjko + */ +public final class UUIDResolver extends Thread { + + Map cache; + + protected transient boolean quit; + + protected final DIRClient dir; + + protected final List myNetworks; + + /** + * interval between two cache cleanups/renewals in milliseconds + */ + public final int cacheCleanInterval; + + public final int maxUnusedEntry; + + protected static UUIDResolver theInstance; + + protected final UserCredentials uc; + + protected UUIDResolver(DIRClient client, int cacheCleanInterval, int maxUnusedEntry, boolean singleton) + throws IOException { + + super("UUID Resolver"); + setDaemon(true); + + cache = new ConcurrentHashMap(); + quit = false; + this.dir = client; + this.maxUnusedEntry = maxUnusedEntry; + this.cacheCleanInterval = cacheCleanInterval; + this.uc = UserCredentials.newBuilder().setUsername("uuidresolver").addGroups("xtreemfs-services").build(); + myNetworks = new ArrayList(); + renewNetworks(this); + + if (singleton) { + assert (theInstance == null); + theInstance = this; + } + } + + /** + * Starts the UUIDResolver thread. + * + * @param client + * a DIRClient used to resolve non-cached and non-local mappings + * @param cacheCleanInterval + * the interval between two cleanup/renewals of cache entries (in + * ms) + * @param maxUnusedEntry + * the duration for which to keep an unused entry (in ms, should + * be set to several tens of minutes) + * @throws org.xtreemfs.foundation.json.JSONException + * @throws java.io.IOException + */ + public static synchronized void start(DIRClient client, int cacheCleanInterval, int maxUnusedEntry) + throws IOException { + if (theInstance == null) { + new UUIDResolver(client, cacheCleanInterval, maxUnusedEntry, true); + theInstance.start(); + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, null, "started UUIDResolver", + new Object[0]); + } else { + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, null, + "UUIDResolver already running!", new Object[0]); + } + } + + public static synchronized UUIDResolver startNonSingelton(DIRClient client, int cacheCleanInterval, + int maxUnusedEntry) throws IOException { + UUIDResolver tmp = new UUIDResolver(client, cacheCleanInterval, maxUnusedEntry, false); + tmp.start(); + return tmp; + } + + public static boolean isRunning() { + return theInstance != null; + } + + static UUIDCacheEntry resolve(String uuid) throws UnknownUUIDException { + return resolve(uuid, (String)null); // call the method below + } + + static UUIDCacheEntry resolve(String uuid, String protocol) throws UnknownUUIDException { + assert (theInstance != null); + + UUIDCacheEntry entry = theInstance.cache.get(uuid); + // check if it is still valid + if ((entry != null) && (entry.getValidUntil() > TimeSync.getLocalSystemTime())) { + entry.setLastAccess(TimeSync.getLocalSystemTime()); + return entry; + } + return theInstance.fetchUUID(uuid, protocol); + } + + static UUIDCacheEntry resolve(String uuid, UUIDResolver nonSingleton) throws UnknownUUIDException { + return resolve(uuid, null, nonSingleton); + } + + static UUIDCacheEntry resolve(String uuid, String protocol, UUIDResolver nonSingleton) throws UnknownUUIDException { + + UUIDCacheEntry entry = nonSingleton.cache.get(uuid); + // check if it is still valid + if ((entry != null) && (entry.getValidUntil() > TimeSync.getLocalSystemTime())) { + entry.setLastAccess(TimeSync.getLocalSystemTime()); + return entry; + } + return nonSingleton.fetchUUID(uuid, protocol); + } + + UUIDCacheEntry fetchUUID(String uuid) throws UnknownUUIDException { + return fetchUUID(uuid, null); + } + + UUIDCacheEntry fetchUUID(String uuid, String protocol) throws UnknownUUIDException { + if (dir == null) + throw new UnknownUUIDException("there is no mapping for " + uuid + + ". Attention: local mode enabled, no remote lookup possible."); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "loading uuid mapping for %s", uuid); + try { + AddressMappingSet ams = dir.xtreemfs_address_mappings_get(null, GlobalConstants.AUTH_NONE, uc, uuid); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "sent request to DIR"); + if (Logging.isDebug()) + Logging + .logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "received response for %s", + uuid); + if (ams.getMappingsCount() == 0) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "NO UUID MAPPING FOR: %s", + uuid); + throw new UnknownUUIDException("uuid " + uuid + " is not registered at directory server"); + } + + List mappings = ams.getMappingsList(); + + // Iterate through the mappings and look for a matching network. Matches on the same network will be + // preferred to global ones. + AddressMapping matchingAddress = null; + synchronized (myNetworks) { + for (AddressMapping addrMapping : mappings) { + final String network = addrMapping.getMatchNetwork(); + + // Cache the first default network found. This will be overwritten by direct network matches. + if (network.equals("*")) { + if (matchingAddress == null + && ((protocol == null) || addrMapping.getProtocol().equals(protocol))) { + matchingAddress = addrMapping; + } + } else if (myNetworks.contains(network)) { + // Use the first address found in the same network and stop looking for further matches. + if ((protocol == null) || addrMapping.getProtocol().equals(protocol)) { + matchingAddress = addrMapping; + break; + } + } + } + } + + if (matchingAddress != null) { + final String address = matchingAddress.getAddress(); + final String proto = matchingAddress.getProtocol(); + final int port = matchingAddress.getPort(); + final long validUntil = TimeSync.getLocalSystemTime() + matchingAddress.getTtlS() * 1000; + final InetSocketAddress endpoint = new InetSocketAddress(address, port); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "matching uuid record found for uuid " + + uuid + " with network " + matchingAddress.getMatchNetwork()); + UUIDCacheEntry e = new UUIDCacheEntry(uuid, validUntil, new Mapping(proto, endpoint, address + ":" + + port)); + cache.put(uuid, e); + return e; + } + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "NO UUID MAPPING FOR: %s", uuid); + throw new UnknownUUIDException( + "there is no matching entry for my network in the uuid address mapping. The service at " + + uuid + + " is either not reachable from this machine or the mapping entry is misconfigured."); + } catch (InterruptedException ex) { + throw new UnknownUUIDException("cannot retrieve mapping from server due to IO error: " + ex); + } catch (IOException ex) { + throw new UnknownUUIDException("cannot retrieve mapping from server due to IO error: " + ex); + } catch (Exception ex) { + ex.printStackTrace(); + throw new UnknownUUIDException( + "cannot retrieve mapping from server due to invalid data sent by the server: " + ex); + } + } + + @Override + public void run() { + List updates = new LinkedList(); + do { + Iterator iter = cache.values().iterator(); + while (iter.hasNext()) { + final UUIDCacheEntry entry = iter.next(); + if (entry.isSticky()) + continue; + if (entry.getLastAccess() + maxUnusedEntry < TimeSync.getLocalSystemTime()) { + // dump entry! + iter.remove(); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "removed entry from UUID cache: %s", entry.getUuid()); + } else { + // check if update is necessary + if (entry.getValidUntil() < TimeSync.getLocalSystemTime() + cacheCleanInterval) { + // renew entry... + try { + updates.add(fetchUUID(entry.getUuid())); + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "cannot refresh UIID mapping: %s", ex.toString()); + iter.remove(); + } + } + } + + } + try { + sleep(cacheCleanInterval); + } catch (InterruptedException ex) { + } + } while (!quit); + } + + /** + * Add a UUID which is mapped on localhost + * + * @param localUUID + * the UUID to map + * @param port + * the port to map the UUID to + * @param useSSL + * defines the protocol + */ + public static void addLocalMapping(String localUUID, int port, String protocol) { + assert (theInstance != null); + + UUIDCacheEntry e = theInstance.cache.get(localUUID); + if (e == null) + e = new UUIDCacheEntry(localUUID, Long.MAX_VALUE, new Mapping(protocol, new InetSocketAddress( + "localhost", port), "localhost:" + port)); + else + e.addMapping(new Mapping(protocol, new InetSocketAddress("localhost", port), "localhost:" + port)); + + e.setSticky(true); + theInstance.cache.put(localUUID, e); + } + + public static void addLocalMapping(ServiceUUID uuid, int port, String protocol) { + addLocalMapping(uuid.toString(), port, protocol); + } + + public static void addTestMapping(String uuid, String hostname, int port, boolean useSSL) { + assert (theInstance != null); + + final String protocol = useSSL ? Schemes.SCHEME_PBRPCS : Schemes.SCHEME_PBRPC; + + UUIDCacheEntry e = theInstance.cache.get(uuid); + if (e == null) + e = new UUIDCacheEntry(uuid, Long.MAX_VALUE, new Mapping(protocol, new InetSocketAddress( + hostname, port), hostname + ":" + port)); + else + e.addMapping(new Mapping(protocol, new InetSocketAddress(hostname, port), hostname + ":" + port)); + + e.setSticky(true); + theInstance.cache.put(uuid, e); + } + + public static String getCache() { + StringBuilder sb = new StringBuilder(); + for (UUIDCacheEntry e : theInstance.cache.values()) { + sb.append(e.getUuid()); + sb.append(" -> "); + for (Mapping mapping : e.getMappings()) { + sb.append(mapping.protocol); + sb.append("://"); + sb.append(mapping.resolvedAddr); + sb.append(" "); + } + if (e.isSticky()) { + sb.append(" - STICKY"); + } else { + sb.append(" - valid for "); + sb.append((e.getValidUntil() - TimeSync.getLocalSystemTime()) / 1000l); + sb.append("s"); + } + sb.append("\n"); + } + return sb.toString(); + } + + public static void shutdown() { + if (theInstance != null) { + theInstance.quit = true; + theInstance.interrupt(); + theInstance = null; + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, null, "UUIDREsolver shut down", + new Object[0]); + } else { + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, null, + "UUIDREsolver was already shut down or is not running", new Object[0]); + } + } + + /** + * Renew the list of networks available to the service running this UUIDResolver instance. + * + * @throws IOException + */ + public static void renewNetworks() throws IOException { + if (theInstance != null) { + renewNetworks(theInstance); + } else { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, (Object) null, + "Networks can't be renewed, because the UUIDResolver is not running."); + } + } + } + + static void renewNetworks(UUIDResolver instance) throws IOException { + List ntwrks = NetUtils.getReachableEndpoints(0, "http"); + synchronized (instance.myNetworks) { + instance.myNetworks.clear(); + for (AddressMapping.Builder network : ntwrks) { + instance.myNetworks.add(network.getMatchNetwork()); + } + } + } +} diff --git a/java/servers/src/org/xtreemfs/common/uuids/UnknownUUIDException.java b/java/servers/src/org/xtreemfs/common/uuids/UnknownUUIDException.java new file mode 100644 index 0000000..b1327b4 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/uuids/UnknownUUIDException.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.uuids; + +import java.io.IOException; + +/** + * Thrown when a UUID cannot be mapped to a service's InetSocketAddress and Protoco. + * @author bjko + */ +public class UnknownUUIDException extends IOException { + + public UnknownUUIDException(String message) { + super(message); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/xloc/InvalidXLocationsException.java b/java/servers/src/org/xtreemfs/common/xloc/InvalidXLocationsException.java new file mode 100644 index 0000000..8386948 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/xloc/InvalidXLocationsException.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.xloc; + +/** + * + * @author bjko + */ +public class InvalidXLocationsException extends Exception { + + public InvalidXLocationsException(String message) { + super(message); + } + +} diff --git a/java/servers/src/org/xtreemfs/common/xloc/RAID0Impl.java b/java/servers/src/org/xtreemfs/common/xloc/RAID0Impl.java new file mode 100644 index 0000000..b48de58 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/xloc/RAID0Impl.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.xloc; + +import java.util.Iterator; + +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; + +/** + * + * @author bjko + */ +public class RAID0Impl extends StripingPolicyImpl { + + protected final int stripe_size_in_bytes; + + RAID0Impl(Replica replica, int relOsdPosition) { + super(replica,relOsdPosition); + stripe_size_in_bytes = policy.getStripeSize() * 1024; + if (stripe_size_in_bytes <= 0) + throw new IllegalArgumentException("size must be > 0"); + } + + @Override + public long getObjectNoForOffset(long fileOffset) { + return (fileOffset / stripe_size_in_bytes); + } + + @Override + public int getOSDforOffset(long fileOffset) { + return getOSDforObject(getObjectNoForOffset(fileOffset)); + } + + @Override + public int getOSDforObject(long objectNo) { + return (int) (objectNo % getWidth()); + } + + @Override + public long getRow(long objectNo) { + return objectNo / this.getWidth(); + } + + @Override + public long getObjectStartOffset(long objectNo) { + return objectNo * stripe_size_in_bytes; + } + + @Override + public long getObjectEndOffset(long objectNo) { + return getObjectStartOffset(objectNo + 1) - 1; + } + + public String toString() { + return "StripingPolicy RAID0: " + policy; + } + + @Override + public int getStripeSizeForObject(long objectNo) { + return stripe_size_in_bytes; + } + + @Override + public boolean isLocalObject(long objNo, int relativeOsdNo) { + return objNo % getWidth() == relativeOsdNo; + } + + @Override + public Iterator getObjectsOfOSD(final int osdIndex, final long startObjectNo, + final long endObjectNo) { + return new Iterator() { + // first correct objectNo will be set if the first time "next()" is called + private long object = (getRow(startObjectNo) * getWidth() + osdIndex) - getWidth(); + + @Override + public boolean hasNext() { + return (object + getWidth() <= endObjectNo); + } + + @Override + public Long next() { + object += getWidth(); + return object; + } + + /** + * method does nothing, because it's a virtual iterator + */ + @Override + public void remove() { + // nothing to do + } + }; + } + + @Override + public long getLocalObjectNumber(long objectNo) { + return getRow(objectNo); + } + + @Override + public long getGloablObjectNumber(long osdLocalObjNo) { + return osdLocalObjNo*getWidth()+this.relOsdPosition; + } +} diff --git a/java/servers/src/org/xtreemfs/common/xloc/Replica.java b/java/servers/src/org/xtreemfs/common/xloc/Replica.java new file mode 100644 index 0000000..2531a90 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/xloc/Replica.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.xloc; + +import java.util.ArrayList; +import java.util.List; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; + +/** + * + * @author bjko + */ +public class Replica { + + List osds; + + StripingPolicyImpl stripingPolicy; + + ServiceUUID localOSD; + + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica replica; + + public Replica(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica replica, ServiceUUID localOSD) { + this.replica = replica; + this.localOSD = localOSD; + } + + public StripingPolicyImpl getStripingPolicy() { + if (stripingPolicy == null) { + int relOsdPosition = (localOSD == null) ? -1 : osds.indexOf(localOSD); + stripingPolicy = StripingPolicyImpl.getPolicy(replica,relOsdPosition); + } + return stripingPolicy; + } + + public List getOSDs() { + if (osds == null) { + osds = new ArrayList(replica.getOsdUuidsCount()); + for (String osd : replica.getOsdUuidsList()) { + ServiceUUID uuid = new ServiceUUID(osd); + osds.add(uuid); + } + } + return osds; + } + + public boolean isStriped() { + return getStripingPolicy().getWidth() > 1; + } + + public ServiceUUID getHeadOsd() { + return new ServiceUUID(replica.getOsdUuids(0)); + } + + public String toString() { + return "Replica " + stripingPolicy + ", " + replica + ", Flags: " + replica.getReplicationFlags() + + ", OSD: " + osds; + } + + /** + * Provides the responsible OSD for this object. + * + * @param objectNo + * @return + */ + public ServiceUUID getOSDForObject(long objectNo) { + return getOSDs().get(getStripingPolicy().getOSDforObject(objectNo)); + } + + /** + * Provides the responsible OSD for this offset. + * + * @param objectID + * @return + */ + public ServiceUUID getOSDForOffset(long offset) { + return getOSDs().get(getStripingPolicy().getOSDforOffset(offset)); + } + + /** + * Checks if the given OSD is part of this Replica. + * @param osd + * @return + */ + public boolean containsOSD(ServiceUUID osd) { + boolean contained = false; + for(ServiceUUID o : getOSDs()) { + contained = osd.equals(o); + if(contained) + break; + } + return contained; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Replica) { + return this.toString().equals(((Replica) obj).toString()); + } else + return false; + } + + /** + * Returns the replication flags. These could be used with the ReplicationFlags methods to identify which + * strategy is set. + * + * @return + */ + public int getTransferStrategyFlags() { + return replica.getReplicationFlags(); + } + + /** + * checks if this replica is complete, so it contains ALL objects of the file + * + * @return + */ + public boolean isComplete() { + return ReplicationFlags.isReplicaComplete(replica.getReplicationFlags()); + } + + /** + * Resets the complete Flag and restores the strategy flag. + * + */ + public void resetCompleteFlagAndRestoreStrageyFlag() { + int replFlags = replica.getReplicationFlags(); + + // Reset complete Flag + replFlags &= ~REPL_FLAG.REPL_FLAG_IS_COMPLETE.getNumber(); + + // Restore strategy flag from replication flags + if (isPartialReplica()) { + // Assumption: partial replica -> sequential prefetching + replFlags = ReplicationFlags.setSequentialPrefetchingStrategy(replFlags); + } else { + // Assumption: full replica -> rarest first strategy + replFlags = ReplicationFlags.setRarestFirstStrategy(replFlags); + } + + //set new replication flags + replica = replica.toBuilder().setReplicationFlags(replFlags).build(); + } + + /** + * checks if this replica is a partial (ondemand) or full replica + * @return true, if partial; false if full + */ + public boolean isPartialReplica() { + return ReplicationFlags.isPartialReplica(replica.getReplicationFlags()); + } +} diff --git a/java/servers/src/org/xtreemfs/common/xloc/ReplicationFlags.java b/java/servers/src/org/xtreemfs/common/xloc/ReplicationFlags.java new file mode 100755 index 0000000..a5bb221 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/xloc/ReplicationFlags.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.xloc; + +import org.xtreemfs.osd.replication.transferStrategies.RandomStrategy; +import org.xtreemfs.osd.replication.transferStrategies.RarestFirstStrategy; +import org.xtreemfs.osd.replication.transferStrategies.SequentialPrefetchingStrategy; +import org.xtreemfs.osd.replication.transferStrategies.SequentialStrategy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; + +/** + * + *
    + * 14.07.2009 + */ +public class ReplicationFlags { + private static final int STRATEGY_BITS = SequentialStrategy.REPLICATION_FLAG.getNumber() + | RandomStrategy.REPLICATION_FLAG.getNumber() + | SequentialPrefetchingStrategy.REPLICATION_FLAG.getNumber() + | RarestFirstStrategy.REPLICATION_FLAG.getNumber(); + + private static final int OTHER_BITS = REPL_FLAG.REPL_FLAG_IS_COMPLETE.getNumber() + | REPL_FLAG.REPL_FLAG_FULL_REPLICA.getNumber(); + + public static int setReplicaIsComplete(int flags) { + return flags | REPL_FLAG.REPL_FLAG_IS_COMPLETE.getNumber(); + } + + public static int setReplicaIsNotComplete(int flags) { + return flags & ~REPL_FLAG.REPL_FLAG_IS_COMPLETE.getNumber(); + } + + public static int setPartialReplica(int flags) { + return flags & ~REPL_FLAG.REPL_FLAG_FULL_REPLICA.getNumber(); + } + + public static int setFullReplica(int flags) { + return flags | REPL_FLAG.REPL_FLAG_FULL_REPLICA.getNumber(); + } + + public static int setRandomStrategy(int flags) { + return resetStrategy(flags) | RandomStrategy.REPLICATION_FLAG.getNumber(); + } + + public static int setSequentialStrategy(int flags) { + return resetStrategy(flags) | SequentialStrategy.REPLICATION_FLAG.getNumber(); + } + + public static int setSequentialPrefetchingStrategy(int flags) { + return resetStrategy(flags) | SequentialPrefetchingStrategy.REPLICATION_FLAG.getNumber(); + } + + public static int setRarestFirstStrategy(int flags) { + return resetStrategy(flags) | RarestFirstStrategy.REPLICATION_FLAG.getNumber(); + } + + public static boolean isReplicaComplete(int flags) { + return (flags & REPL_FLAG.REPL_FLAG_IS_COMPLETE.getNumber()) == REPL_FLAG.REPL_FLAG_IS_COMPLETE.getNumber(); + } + + public static boolean isPartialReplica(int flags) { + return (flags & REPL_FLAG.REPL_FLAG_FULL_REPLICA.getNumber()) == 0; + } + + public static boolean isFullReplica(int flags) { + return (flags & REPL_FLAG.REPL_FLAG_FULL_REPLICA.getNumber()) == REPL_FLAG.REPL_FLAG_FULL_REPLICA.getNumber(); + } + + public static boolean isRandomStrategy(int flags) { + return resetOther(flags) == RandomStrategy.REPLICATION_FLAG.getNumber(); + } + + public static boolean isSequentialStrategy(int flags) { + return resetOther(flags) == SequentialStrategy.REPLICATION_FLAG.getNumber(); + } + + public static boolean isSequentialPrefetchingStrategy(int flags) { + return resetOther(flags) == SequentialPrefetchingStrategy.REPLICATION_FLAG.getNumber(); + } + + public static boolean isRarestFirstStrategy(int flags) { + return resetOther(flags) == RarestFirstStrategy.REPLICATION_FLAG.getNumber(); + } + + /** + * resets the bits used for strategies to zero + */ + private static int resetStrategy(int flags) { + return (flags | STRATEGY_BITS) ^ STRATEGY_BITS; + } + + /** + * resets the bits NOT used for strategies to zero + */ + private static int resetOther(int flags) { + return (flags | OTHER_BITS) ^ OTHER_BITS; + } +} diff --git a/java/servers/src/org/xtreemfs/common/xloc/ReplicationPolicyImplementation.java b/java/servers/src/org/xtreemfs/common/xloc/ReplicationPolicyImplementation.java new file mode 100644 index 0000000..e85bccb --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/xloc/ReplicationPolicyImplementation.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014 by Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.xloc; + +import org.xtreemfs.mrc.metadata.ReplicationPolicy; + +public class ReplicationPolicyImplementation implements ReplicationPolicy { + + final String updatePolicy; + final int replicationFactor; + final int replicationFlags; + + public ReplicationPolicyImplementation(String updatePolicy, int replicationFactor, int replicationFlags) { + this.updatePolicy = updatePolicy; + this.replicationFactor = replicationFactor; + this.replicationFlags = replicationFlags; + } + + @Override + public String getName() { + return updatePolicy; + } + + @Override + public int getFactor() { + return replicationFactor; + } + + @Override + public int getFlags() { + return replicationFlags; + } + +} diff --git a/java/servers/src/org/xtreemfs/common/xloc/StripingPolicyImpl.java b/java/servers/src/org/xtreemfs/common/xloc/StripingPolicyImpl.java new file mode 100644 index 0000000..21dcc21 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/xloc/StripingPolicyImpl.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.xloc; + +import java.util.Iterator; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; + + +/** + * + * @author bjko + */ +public abstract class StripingPolicyImpl { + + protected final StripingPolicy policy; + + protected final int relOsdPosition; + + StripingPolicyImpl(Replica replica, int relOsdPosition) { + policy = replica.getStripingPolicy(); + this.relOsdPosition = relOsdPosition; + } + + /** + * + * @param replica replica to use + * @param relOsdPosition relative OSD position in replica (0..width-1) + * @return + */ + public static StripingPolicyImpl getPolicy(Replica replica, int relOsdPosition) { + if (replica.getStripingPolicy().getType() == StripingPolicyType.STRIPING_POLICY_RAID0) { + return new RAID0Impl(replica,relOsdPosition); + } else { + throw new IllegalArgumentException("unknown striping polciy requested"); + } + } + + /** + * returns the width (number of OSDs) of the striping policy + * + * @return + */ + public int getWidth() { + return policy.getWidth(); + } + + public int getPolicyId() { + return policy.getType().getNumber(); + } + + public StripingPolicy getPolicy() { + return this.policy; + } + + /** + * returns the object number for the given offset + * + * @param fileOffset + * @return + */ + public abstract long getObjectNoForOffset(long fileOffset); + + /** + * returns the index of the OSD for the given offset + * + * @param fileOffset + * @return + */ + public abstract int getOSDforOffset(long fileOffset); + + /** + * returns the index of the OSD for the given object + * + * @param objectNo + * @return + */ + public abstract int getOSDforObject(long objectNo); + + public abstract long getRow(long objectNo); + + /** + * returns the first offset of this object + * + * @param objectNo + * @return + */ + public abstract long getObjectStartOffset(long objectNo); + + /** + * returns the last offset of this object + * + * @param objectNo + * @return + */ + public abstract long getObjectEndOffset(long objectNo); + + public abstract int getStripeSizeForObject(long objectNo); + + public abstract boolean isLocalObject(long objNo, int relativeOsdNo); + + + public abstract long getLocalObjectNumber(long objectNo); + + public abstract long getGloablObjectNumber(long osdLocalObjNo); + + /** + * Returns a virtual iterator which iterates over all objects the given OSD should save. It starts with + * the correct object in the row of startObjectNo (inclusive) and ends with endObjectNo (maybe inclusive). + * + * @param osdIndex + * @param filesize + * @return + */ + public abstract Iterator getObjectsOfOSD(final int osdIndex, final long startObjectNo, + final long endObjectNo); +} diff --git a/java/servers/src/org/xtreemfs/common/xloc/XLocations.java b/java/servers/src/org/xtreemfs/common/xloc/XLocations.java new file mode 100644 index 0000000..80bd836 --- /dev/null +++ b/java/servers/src/org/xtreemfs/common/xloc/XLocations.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.xloc; + +import java.util.ArrayList; +import java.util.List; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; + + + +/** + * + * @author bjko + */ +public class XLocations { + + private final XLocSet xloc; + + private Replica localReplica; + + private List replicas; + + public XLocations(XLocSet xloc, ServiceUUID localOSD) throws InvalidXLocationsException { + this.xloc = xloc; + replicas = new ArrayList(xloc.getReplicasCount()); + for (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica r : xloc.getReplicasList()) { + replicas.add(new Replica(r,null)); + } + if (localOSD != null) { + for (Replica r : replicas) { + if (r.getOSDs().contains(localOSD)) { + localReplica = r; + break; + } + } + if (localReplica == null) + throw new InvalidXLocationsException("local OSD (" + localOSD + ") is not in any replica in XLocations list: " + xloc); + } + } + + + public XLocSet getXLocSet() { + return xloc; + } + + public int getVersion() { + return xloc.getVersion(); + } + + public int getNumReplicas() { + return xloc.getReplicasCount(); + } + + public List getReplicas() { + return replicas; + } + + public String getReplicaUpdatePolicy() { + return xloc.getReplicaUpdatePolicy(); + } + + public Replica getLocalReplica() { + return localReplica; + } + + public Replica getReplica(int replicaNo) { + return replicas.get(replicaNo); + } + + /** + * returns replica which contains the given OSD + * @param osd + * @return null, of no replica contains the given OSD, otherwise the replica + */ + public Replica getReplica(ServiceUUID osd) { + for (Replica replica : getReplicas()) + for (ServiceUUID osd2 : replica.getOSDs()) + if (osd.equals(osd2)) + return replica; + return null; + } + + /** + * Checks if the given OSD is already used for this file. + * @param osd + * @return + */ + public boolean containsOSD(ServiceUUID osd) { + boolean contained = false; + for(Replica r : getReplicas()) { + contained = r.containsOSD(osd); + if(contained) + break; + } + return contained; + } + + /** + * Provides a list of OSDs which are containing replicas of the given object. + * NOTE: If the replicas use different striping policies the same object must not contain the same data. + * @param objectNo + * @return + */ + public List getOSDsForObject(long objectNo, Replica localReplica){ + List osds = new ArrayList(); + if (localReplica == null) { + for(Replica replica : replicas){ + osds.add(replica.getOSDForObject(objectNo)); + } + } else { + for(Replica replica : replicas){ + if (localReplica == replica) + continue; + final ServiceUUID osd = replica.getOSDForObject(objectNo); + osds.add(osd); + } + } + return osds; + } + + public List getOSDsForObject(long objectNo) { + return getOSDsForObject(objectNo, null); + } + + @Override + public String toString() { + return "local replica: " + localReplica + ", other replicas: " + replicas; + } +} diff --git a/java/servers/src/org/xtreemfs/dir/DIR.java b/java/servers/src/org/xtreemfs/dir/DIR.java new file mode 100644 index 0000000..ee8823b --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/DIR.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir; + +import java.io.IOException; + +import org.xtreemfs.babudb.config.BabuDBConfig; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * This class can be used to start a new instance of the Directory Service. + * + * @author stender + * + */ +public class DIR { + + /** + * @param args + * the command line arguments + */ + public static void main(String[] args) throws IOException { + + String configFileName = "etc/xos/xtreemfs/dirconfig.test"; + if (args.length != 1) + System.out.println("using default config file " + configFileName); + else + configFileName = args[0]; + + DIRConfig config = null; + try { + config = new DIRConfig(configFileName); + } catch (IOException ex) { + ex.printStackTrace(); + return; + } + config.setDefaults(); + + config.checkConfig(); + + + Logging.start(config.getDebugLevel(), config.getDebugCategories()); + + BabuDBConfig dbsConfig = new BabuDBConfig(configFileName); + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, (Object) null, "JAVA_HOME=%s", System + .getProperty("java.home")); + + try { + final DIRRequestDispatcher rq = new DIRRequestDispatcher(config, dbsConfig); + rq.startup(); + + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + try { + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, + "received shutdown signal!"); + rq.shutdown(); + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, + "DIR shutdown complete"); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + }); + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_CRIT, null, + "DIR could not start up due to an exception. Aborted."); + Logging.logError(Logging.LEVEL_CRIT, null, ex); + System.exit(1); + } + + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/DIRClient.java b/java/servers/src/org/xtreemfs/dir/DIRClient.java new file mode 100644 index 0000000..d8f2ef7 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/DIRClient.java @@ -0,0 +1,463 @@ +/* + * Copyright (c) 2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.List; + +import org.xtreemfs.foundation.TimeServerClient; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; + +/** + * DIR Client with automatic fail-over and redirect support. All operations are + * synchronous. + * + * @author bjko + */ +public class DIRClient implements TimeServerClient { + + /** + * Generated DIR service rpc client. + */ + protected DIRServiceClient rpcClient; + + /** + * List of DIR servers. + */ + protected final InetSocketAddress[] servers; + + /** + * number of server currently used. + */ + protected int currentServer; + + /** + * Maximum number of retries. + */ + protected final int maxRetries; + + /** + * Time to wait between retries (in milliseconds). + */ + protected final int retryWaitMs; + + /** + * True, if the client was redirected before. + */ + protected boolean redirectedBefore; + + /** + * Auth used for TimeServerClient calls. + */ + protected final Auth auth; + + /** + * UserCredentials used for TimeServerClient calls. + */ + protected final UserCredentials user; + + /** + * Initializes the DIRClient. + * + * @param rpcClient + * RPC client (must be running). + * @param servers + * list of servers to use (must contain at least one item). + * @param maxRetries + * maximum retries before throwing exception. + * @param retryWaitMs + * time (milliseconds) to wait between retries. + */ + public DIRClient(DIRServiceClient rpcClient, InetSocketAddress[] servers, int maxRetries, int retryWaitMs) { + if (servers.length == 0) { + throw new IllegalArgumentException("Must provide at least one directory service address."); + } + this.maxRetries = maxRetries; + this.servers = servers; + this.rpcClient = rpcClient; + this.currentServer = 0; + this.retryWaitMs = retryWaitMs; + auth = Auth.newBuilder().setAuthType(AuthType.AUTH_NONE).build(); + user = UserCredentials.newBuilder().setUsername("service").addGroups("xtreemfs").build(); + } + + public AddressMappingSet xtreemfs_address_mappings_get(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String uuid) throws IOException, InterruptedException { + return xtreemfs_address_mappings_get(server, authHeader, userCreds, uuid, maxRetries); + } + + public AddressMappingSet xtreemfs_address_mappings_get(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String uuid, int maxRetries) throws IOException, + InterruptedException { + AddressMappingSet response = (AddressMappingSet) syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_address_mappings_get(server, authHeader, userCreds, uuid); + } + }, maxRetries); + return response; + } + + public void xtreemfs_address_mappings_remove(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String uuid) throws IOException, InterruptedException { + xtreemfs_address_mappings_remove(server, authHeader, userCreds, uuid, maxRetries); + } + + public void xtreemfs_address_mappings_remove(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String uuid, int maxRetries) throws IOException, + InterruptedException { + Object response = syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_address_mappings_remove(server, authHeader, userCreds, uuid); + } + }, maxRetries); + } + + public addressMappingSetResponse xtreemfs_address_mappings_set(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final List mappings) throws IOException, + InterruptedException { + return xtreemfs_address_mappings_set(server, authHeader, userCreds, mappings, maxRetries); + } + + public addressMappingSetResponse xtreemfs_address_mappings_set(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final List mappings, int maxRetries) throws IOException, + InterruptedException { + addressMappingSetResponse response = (addressMappingSetResponse) syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_address_mappings_set(server, authHeader, userCreds, mappings); + } + }, maxRetries); + return response; + } + + public addressMappingSetResponse xtreemfs_address_mappings_set(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final AddressMappingSet input) throws IOException, InterruptedException { + return xtreemfs_address_mappings_set(server, authHeader, userCreds, input, maxRetries); + } + + public addressMappingSetResponse xtreemfs_address_mappings_set(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final AddressMappingSet input, int maxRetries) throws IOException, + InterruptedException { + addressMappingSetResponse response = (addressMappingSetResponse) syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_address_mappings_set(server, authHeader, userCreds, input); + } + }, maxRetries); + return response; + } + + public void xtreemfs_service_deregister(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String uuid) throws IOException, + InterruptedException { + xtreemfs_service_deregister(server, authHeader, userCreds, uuid, maxRetries); + } + + public void xtreemfs_service_deregister(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String uuid, int maxRetries) throws IOException, InterruptedException { + Object response = syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_service_deregister(server, authHeader, userCreds, uuid); + } + }, maxRetries); + } + + public void xtreemfs_service_offline(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String name) throws IOException, InterruptedException { + xtreemfs_service_offline(server, authHeader, userCreds, name, maxRetries); + } + + public void xtreemfs_service_offline(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String name, int maxRetries) throws IOException, + InterruptedException { + Object response = syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_service_offline(server, authHeader, userCreds, name); + } + }, maxRetries); + } + + public ServiceSet xtreemfs_service_get_by_name(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String name) throws IOException, InterruptedException { + return xtreemfs_service_get_by_name(server, authHeader, userCreds, name, maxRetries); + } + + public ServiceSet xtreemfs_service_get_by_name(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String name, int maxRetries) throws IOException, + InterruptedException { + ServiceSet response = (ServiceSet) syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_service_get_by_name(server, authHeader, userCreds, name); + } + }, maxRetries); + return response; + } + + public ServiceSet xtreemfs_service_get_by_uuid(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String uuid) throws IOException, InterruptedException { + return xtreemfs_service_get_by_uuid(server, authHeader, userCreds, uuid, maxRetries); + } + + public ServiceSet xtreemfs_service_get_by_uuid(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String uuid, int maxRetries) throws IOException, + InterruptedException { + ServiceSet response = (ServiceSet) syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_service_get_by_uuid(server, authHeader, userCreds, uuid); + } + }, maxRetries); + return response; + } + + public ServiceSet xtreemfs_service_get_by_type(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final ServiceType type) throws IOException, InterruptedException { + return xtreemfs_service_get_by_type(server, authHeader, userCreds, type, maxRetries); + } + + public ServiceSet xtreemfs_service_get_by_type(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final ServiceType type, int maxRetries) throws IOException, + InterruptedException { + ServiceSet response = (ServiceSet) syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_service_get_by_type(server, authHeader, userCreds, type); + } + }, maxRetries); + return response; + } + + public serviceRegisterResponse xtreemfs_service_register(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final Service service) throws IOException, InterruptedException { + return xtreemfs_service_register(server, authHeader, userCreds, service, maxRetries); + } + + public serviceRegisterResponse xtreemfs_service_register(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final Service service, int maxRetries) throws IOException, + InterruptedException { + serviceRegisterResponse response = (serviceRegisterResponse) syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_service_register(server, authHeader, userCreds, service); + } + }, maxRetries); + return response; + } + + public Configuration xtreemfs_configuration_get(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String uuid) throws IOException, InterruptedException { + return xtreemfs_configuration_get(server, authHeader, userCreds, uuid, maxRetries); + } + + public Configuration xtreemfs_configuration_get(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final String uuid, int maxRetries) throws IOException, + InterruptedException { + Configuration response = (Configuration) syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_configuration_get(server, authHeader, userCreds, uuid); + } + }, maxRetries); + return response; + } + + public configurationSetResponse xtreemfs_configuration_set(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final Configuration config) throws IOException, InterruptedException { + return xtreemfs_configuration_set(server, authHeader, userCreds, config, maxRetries); + } + + public configurationSetResponse xtreemfs_configuration_set(InetSocketAddress server, final Auth authHeader, + final UserCredentials userCreds, final Configuration config, int maxRetries) throws IOException, + InterruptedException { + configurationSetResponse response = (configurationSetResponse) syncCall(new CallGenerator() { + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_configuration_set(server, authHeader, userCreds, config); + } + }, maxRetries); + return response; + } + + @Override + public long xtreemfs_global_time_get(InetSocketAddress server) { + try { + return xtreemfs_global_time_get(); + } catch (Exception ex) { + return 0; + } + } + + public long xtreemfs_global_time_get() throws InterruptedException, PBRPCException, IOException { + globalTimeSGetResponse response = (globalTimeSGetResponse) syncCall(new CallGenerator() { + + @Override + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException { + return client.xtreemfs_global_time_s_get(server, auth, user); + } + }, 1); + return response.getTimeInSeconds(); + } + + public boolean clientIsAlive() { + return rpcClient.clientIsAlive(); + } + + /** + * Interface for syncCall which generates the calls. Will be called for each + * retry. + */ + protected interface CallGenerator { + public RPCResponse executeCall(DIRServiceClient client, InetSocketAddress server) throws IOException; + } + + protected Object syncCall(CallGenerator call, int maxRetries) throws InterruptedException, PBRPCException, + IOException { + assert maxRetries != 0 : "Current DIRClient implementation supports no infinite retries."; + InetSocketAddress server = null; + redirectedBefore = false; + int numTries = 1; + Exception lastException = null; + while (numTries <= maxRetries) { + boolean countRedirectAsRetry = redirectedBefore; + + synchronized (this) { + server = servers[currentServer]; + } + RPCResponse response = null; + try { + response = call.executeCall(rpcClient, server); + Object result = response.get(); + return result; + + } catch (PBRPCException ex) { + + switch (ex.getErrorType()) { + + case REDIRECT: { + lastException = ex; + if (numTries <= maxRetries) { + redirect(ex); + } else + countRedirectAsRetry = true; + break; + } + + case ERRNO: + throw ex; + + default: { + lastException = ex; + if (numTries <= maxRetries) { + failover(ex); + } + break; + } + } + + } catch (IOException ex) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "Request failed due to exception: %s", ex); + lastException = ex; + if (numTries <= maxRetries) { + failover(ex); + } + } finally { + if (response != null) { + response.freeBuffers(); + } + } + + // only count a redirect as a retry if a redirect was already + // performed before + if (!(lastException instanceof PBRPCException) + || (((PBRPCException) lastException).getErrorType() == ErrorType.REDIRECT && countRedirectAsRetry)) + numTries++; + + } + throw new IOException("Request finally failed after " + (numTries - 1) + " tries.", lastException); + } + + protected void redirect(PBRPCException exception) throws InterruptedException { + assert (exception.getErrorType() == ErrorType.REDIRECT); + // We "abuse" the UUID field for the address (hostname:port) as the + // DIR service has no UUIDs. + final String address = exception.getRedirectToServerUUID(); + try { + final int colon = address.indexOf(':'); + final String hostname = address.substring(0, colon); + final String portStr = address.substring(colon + 1); + final int port = Integer.valueOf(portStr); + final InetSocketAddress redirectTo = new InetSocketAddress(hostname, port); + + // Find the entry in the list. + for (int i = 0; i < servers.length; i++) { + final InetSocketAddress server = servers[i]; + if (server.equals(redirectTo)) { + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.net, this, "redirected to DIR: %s", server); + synchronized (this) { + currentServer = i; + } + if (redirectedBefore) { + // Wait between redirects, but not for the first + // redirect. + Thread.sleep(retryWaitMs); + } else { + redirectedBefore = true; + } + return; + } + } + throw new IOException("Cannot redirect to unknown server: " + redirectTo); + } catch (InterruptedException ex) { + // Pass on interruped exception, ignore everything else. + throw ex; + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + protected void failover(IOException exception) throws InterruptedException { + // wait for next retry + Thread.sleep(retryWaitMs); + + synchronized (this) { + currentServer++; + if (currentServer >= servers.length) { + currentServer = 0; + } + } + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "Switching to server %s since the last attempt failed with the error: %s", + servers[currentServer], exception.getMessage()); + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/DIRConfig.java b/java/servers/src/org/xtreemfs/dir/DIRConfig.java new file mode 100644 index 0000000..ed372ee --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/DIRConfig.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.xtreemfs.common.config.ServiceConfig; + +/** + * + * @author bjko + */ +public class DIRConfig extends ServiceConfig { + + private final Parameter[] dirParameter = { + Parameter.DEBUG_LEVEL, + Parameter.DEBUG_CATEGORIES, + Parameter.PORT, + Parameter.HTTP_PORT, + Parameter.LISTEN_ADDRESS, + Parameter.USE_SSL, + Parameter.SSL_PROTOCOL_STRING, + Parameter.SERVICE_CREDS_FILE, + Parameter.SERVICE_CREDS_PASSPHRASE, + Parameter.SERVICE_CREDS_CONTAINER, + Parameter.TRUSTED_CERTS_FILE, + Parameter.TRUSTED_CERTS_CONTAINER, + Parameter.TRUSTED_CERTS_PASSPHRASE, + Parameter.TRUST_MANAGER, + Parameter.USE_GRID_SSL_MODE, + Parameter.UUID, + Parameter.WAIT_FOR_DIR, + Parameter.ADMIN_PASSWORD, + Parameter.AUTODISCOVER_ENABLED, + Parameter.MONITORING_ENABLED, + Parameter.ADMIN_EMAIL, + Parameter.SENDER_ADDRESS, + Parameter.MAX_WARNINGS, + Parameter.TIMEOUT_SECONDS, + Parameter.SENDMAIL_BIN, + Parameter.POLICY_DIR, + Parameter.USE_SNMP, + Parameter.SNMP_ADDRESS, + Parameter.SNMP_PORT, + Parameter.SNMP_ACL, + Parameter.VIVALDI_MAX_CLIENTS, + Parameter.VIVALDI_CLIENT_TIMEOUT + }; + + private Map mirrors; + + + /** Creates a new instance of DIRConfig */ + public DIRConfig(String filename) throws IOException { + super(filename); + read(); + } + + public DIRConfig(Properties prop) throws IOException { + super(prop); + read(); + } + + public void read() throws IOException { + + for(Parameter param : dirParameter) { + parameter.put(param, readParameter(param)); + } + + this.mirrors = new HashMap(); + if (this.getAddress() != null) { + this.mirrors.put(this.getAddress().getHostAddress(), this.getPort()); + } + int id = 0; + String host; + InetSocketAddress addrs; + int port; + while ((host = this.readOptionalString("babudb.repl.participant." + id,null)) != null) { + port = this.readRequiredInt("babudb.repl.participant." + id + + ".dirPort"); + addrs = new InetSocketAddress(host, port); + this.mirrors.put(addrs.getAddress().getHostAddress(), port); + + id++; + } + } + + /** + * @return the autodiscoverEnabled + */ + public boolean isAutodiscoverEnabled() { + return (Boolean)parameter.get(Parameter.AUTODISCOVER_ENABLED); + } + + /** + * @return the monitoringEnabled + */ + public boolean isMonitoringEnabled() { + return (Boolean)parameter.get(Parameter.MONITORING_ENABLED); + } + + /** + * @return the adminEmail + */ + public String getAdminEmail() { + return (String)parameter.get(Parameter.ADMIN_EMAIL); + } + + /** + * @return the senderAddress + */ + public String getSenderAddress() { + return (String)parameter.get(Parameter.SENDER_ADDRESS); + } + + /** + * @return the maxWarnings + */ + public int getMaxWarnings() { + return (Integer)parameter.get(Parameter.MAX_WARNINGS); + } + + /** + * @return the timeoutSeconds + */ + public int getTimeoutSeconds() { + return (Integer)parameter.get(Parameter.TIMEOUT_SECONDS); + } + + /** + * @return the sendmailBin + */ + public String getSendmailBin() { + return (String)parameter.get(Parameter.SENDMAIL_BIN); + } + + /** + * @return the mirror DIRs + */ + public Map getMirrors() { + return mirrors; + } + public void setDefaults() { + super.setDefaults(dirParameter); + } + + /** + * Check if the configuration contain all necessary values to start the Service + */ + public void checkConfig() { + super.checkConfig(dirParameter); + } + + public int getVivaldiMaxClients() { + return (Integer)parameter.get(Parameter.VIVALDI_MAX_CLIENTS); + } + + public int getVivaldiClientTimeout() { + return (Integer)parameter.get(Parameter.VIVALDI_CLIENT_TIMEOUT); + } +} diff --git a/java/servers/src/org/xtreemfs/dir/DIRRequest.java b/java/servers/src/org/xtreemfs/dir/DIRRequest.java new file mode 100644 index 0000000..dc2b25d --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/DIRRequest.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir; + +import com.google.protobuf.Message; +import java.io.IOException; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.RequestDetails; + +/** + * + * @author bjko + */ +public class DIRRequest { + + private final RPCServerRequest rpcRequest; + + private Message requestMessage; + + private RequestDetails details; + + public DIRRequest(RPCServerRequest rpcRequest) { + this.rpcRequest = rpcRequest; + details = new RequestDetails(); + } + + public void deserializeMessage(Message message) throws IOException { + final ReusableBuffer payload = rpcRequest.getMessage(); + if (message != null) { + if (payload != null) { + ReusableBufferInputStream istream = new ReusableBufferInputStream(payload); + requestMessage = message.newBuilderForType().mergeFrom(istream).build(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "parsed request: %s",message.getClass().getSimpleName()); + } + } else { + requestMessage = message.getDefaultInstanceForType(); + } + } else { + requestMessage = null; + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "parsed request: empty message (emptyRequest)"); + } + } + + } + + public Message getRequestMessage() { + return requestMessage; + } + + public void sendSuccess(Message response) { + try { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "sending response: %s",response.getClass().getSimpleName()); + } + rpcRequest.sendResponse(response,null); + } catch (IOException ex) { + //not much we can do if error occurs during send + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + public void sendInternalServerError(Throwable rootCause) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "sending internal server error: "+rootCause.toString()); + } + rpcRequest.sendError(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_EIO, "internal server error: "+rootCause.toString(), OutputUtils.stackTraceToString(rootCause)); + } + + public void sendRedirectException(String addr, int port) { + rpcRequest.sendRedirect(addr+":"+port); + } + + public void sendError(ErrorType type, POSIXErrno error, String message) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "sending error return value: "+type+"/"+error+"/"+message); + } + rpcRequest.sendError(type, error, message); + } + + + public RequestDetails getDetails() { + return details; + } + + public void setDetails(RequestDetails details) { + this.details = details; + } + + public RPCServerRequest getRPCRequest() { + return rpcRequest; + } +} diff --git a/java/servers/src/org/xtreemfs/dir/DIRRequestDispatcher.java b/java/servers/src/org/xtreemfs/dir/DIRRequestDispatcher.java new file mode 100644 index 0000000..e6903f5 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/DIRRequestDispatcher.java @@ -0,0 +1,597 @@ +/* + * Copyright (c) 2009-2012 by Bjoern Kolbeck, Matthias Noack, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.xtreemfs.babudb.BabuDBFactory; +import org.xtreemfs.babudb.api.BabuDB; +import org.xtreemfs.babudb.api.DatabaseManager; +import org.xtreemfs.babudb.api.SnapshotManager; +import org.xtreemfs.babudb.api.StaticInitialization; +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.babudb.config.BabuDBConfig; +import org.xtreemfs.common.config.PolicyContainer; +import org.xtreemfs.common.monitoring.StatusMonitor; +import org.xtreemfs.common.statusserver.BabuDBStatusPage; +import org.xtreemfs.common.statusserver.PrintStackTrace; +import org.xtreemfs.common.statusserver.StatusServer; +import org.xtreemfs.dir.data.ServiceRecord; +import org.xtreemfs.dir.data.ServiceRecords; +import org.xtreemfs.dir.discovery.DiscoveryMsgThread; +import org.xtreemfs.dir.operations.DIROperation; +import org.xtreemfs.dir.operations.DeleteAddressMappingOperation; +import org.xtreemfs.dir.operations.DeregisterServiceOperation; +import org.xtreemfs.dir.operations.GetAddressMappingOperation; +import org.xtreemfs.dir.operations.GetConfigurationOperation; +import org.xtreemfs.dir.operations.GetGlobalTimeOperation; +import org.xtreemfs.dir.operations.GetServiceByNameOperation; +import org.xtreemfs.dir.operations.GetServiceByUuidOperation; +import org.xtreemfs.dir.operations.GetServicesByTypeOperation; +import org.xtreemfs.dir.operations.RegisterServiceOperation; +import org.xtreemfs.dir.operations.ServiceOfflineOperation; +import org.xtreemfs.dir.operations.SetAddressMappingOperation; +import org.xtreemfs.dir.operations.SetConfigurationOperation; +import org.xtreemfs.dir.operations.UpdateVivaldiClientOperation; +import org.xtreemfs.foundation.CrashReporter; +import org.xtreemfs.foundation.LifeCycleListener; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.SSLOptions.TrustManager; +import org.xtreemfs.foundation.VersionManagement; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.server.RPCNIOSocketServer; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequestListener; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +/** + * + * @author bjko + */ +public class DIRRequestDispatcher extends LifeCycleThread implements RPCServerRequestListener, + LifeCycleListener { + + /** + * index for address mappings, stores uuid -> AddressMappingSet + */ + public static final int INDEX_ID_ADDRMAPS = 0; + + /** + * index for service registries, stores uuid -> ServiceRegistry + */ + public static final int INDEX_ID_SERVREG = 1; + + /** + * index for configuration of services, stores uuid -> Configuration + */ + public static final int INDEX_ID_CONFIGURATIONS = 2; + + public static final int DB_VERSION = 2010111010; + + protected final StatusServer statusServer; + + private int numRequests; + + private final Map registry; + + private final RPCNIOSocketServer server; + + private final BlockingQueue queue; + + private volatile boolean quit; + + private final BabuDB database; + + private final DiscoveryMsgThread discoveryThr; + + private final MonitoringThread monThr; + + private final DIRConfig config; + + public static final String DB_NAME = "dirdb"; + + private List statusListener; + + private VivaldiClientMap vivaldiClientMap; + + public DIRRequestDispatcher(final DIRConfig config, final BabuDBConfig dbsConfig) throws IOException, + BabuDBException { + super("DIR RqDisp"); + this.config = config; + + Logging.logMessage(Logging.LEVEL_INFO, this, "XtreemFS Direcory Service version " + + VersionManagement.RELEASE_VERSION); + + registry = new HashMap(); + + vivaldiClientMap = new VivaldiClientMap(config.getVivaldiMaxClients(), config.getVivaldiClientTimeout()); + + // start up babudb + database = BabuDBFactory.createBabuDB(dbsConfig, new StaticInitialization() { + @Override + public void initialize(DatabaseManager dbMan, SnapshotManager sMan) { + initDB(dbMan, sMan); + } + }); + + registerOperations(); + + // start the server + + SSLOptions sslOptions = null; + if (config.isUsingSSL()) { + + PolicyContainer policyContainer = new PolicyContainer(config); + TrustManager tm = null; + try { + tm = policyContainer.getTrustManager(); + } catch (Exception e) { + throw new IOException(e); + } + + sslOptions = new SSLOptions(new FileInputStream(config.getServiceCredsFile()), config + .getServiceCredsPassphrase(), config.getServiceCredsContainer(), new FileInputStream( + config.getTrustedCertsFile()), config.getTrustedCertsPassphrase(), config + .getTrustedCertsContainer(), false, config.isGRIDSSLmode(), + config.getSSLProtocolString(), tm); + + if (Logging.isInfo() && tm != null) + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, this, + "using custom trust manager '%s'", tm.getClass().getName()); + } + + queue = new LinkedBlockingQueue(); + quit = false; + + server = new RPCNIOSocketServer(config.getPort(), config.getAddress(), this, sslOptions); + server.setLifeCycleListener(this); + + if (config.isAutodiscoverEnabled()) { + + String scheme = Schemes.SCHEME_PBRPC; + if (config.isGRIDSSLmode()) + scheme = Schemes.SCHEME_PBRPCG; + else if (config.isUsingSSL()) + scheme = Schemes.SCHEME_PBRPCS; + + discoveryThr = new DiscoveryMsgThread(InetAddress.getLocalHost().getCanonicalHostName(), config + .getPort(), scheme); + discoveryThr.setLifeCycleListener(this); + } else { + discoveryThr = null; + } + + if (config.getHttpPort() == -1) { + // Webinterface is explicitly disabled. + statusServer = null; + } else { + statusServer = new StatusServer(ServiceType.SERVICE_TYPE_DIR, this, config.getHttpPort()); + statusServer.registerModule(new PrintStackTrace()); + statusServer.registerModule(new StatusPage(config)); + statusServer.registerModule(new ReplicaStatusPage()); + statusServer.registerModule(new VivaldiStatusPage(config)); + statusServer.registerModule(new BabuDBStatusPage(new BabuDBStatusPage.BabuDBStatusProvider() { + @Override + public Map getStatus() { + // NOTE(jdillmann): Access to the database is not synchronized. This might result in + // reading stale data. + return database.getRuntimeState(); + } + })); + + if (config.getAdminPassword().length() > 0) { + statusServer.addAuthorizedUser("admin", config.getAdminPassword()); + } + + statusServer.start(); + } + + numRequests = 0; + + if (config.isMonitoringEnabled()) { + monThr = new MonitoringThread(config, this); + monThr.setLifeCycleListener(this); + } else { + monThr = null; + } + + statusListener = new ArrayList(); + if (config.isUsingSnmp()) { + statusListener.add(new StatusMonitor( + this, config.getSnmpAddress(), config.getSnmpPort(), config.getSnmpACLFile())); + + // tell the StatusMonitor about the new (initial) configuration + notifyConfigurationChange(); + } + + + //notify listener about further ServiceRecords which are already in the database on initialization + try { + for (ServiceRecord sRec : this.getServices().getList()) { + this.notifyServiceRegistred(sRec.getUuid(),sRec.getName() ,sRec.getType().toString(), "", "", 0, 0, + sRec.getLast_updated_s(), 0, 0, 0); + } + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, ": %s", + ex.getMessage()); + } + + + } + + @Override + public void run() { + try { + notifyStarted(); + while (!quit) { + final RPCServerRequest rq = queue.take(); + synchronized (database) { + processRequest(rq); + } + } + } catch (InterruptedException ex) { + quit = true; + } catch (Throwable ex) { + final String report = CrashReporter.createCrashReport("DIR", VersionManagement.RELEASE_VERSION, + ex); + System.out.println(report); + CrashReporter.reportXtreemFSCrash(report); + notifyCrashed(ex); + System.exit(2); + } + notifyStopped(); + } + + public ServiceRecords getServices() throws Exception { + + synchronized (database) { + Database db = getDirDatabase(); + Iterator> iter = db.prefixLookup(DIRRequestDispatcher.INDEX_ID_SERVREG, + new byte[0], null).get(); + + ServiceRecords services = new ServiceRecords(); + + while (iter.hasNext()) { + final Entry e = iter.next(); + final ServiceRecord servEntry = new ServiceRecord(ReusableBuffer.wrap(e.getValue())); + services.add(servEntry); + } + return services; + } + + } + + public void startup() throws Exception { + this.start(); + + server.start(); + server.waitForStartup(); + + if (discoveryThr != null) { + discoveryThr.start(); + discoveryThr.waitForStartup(); + } + + if (monThr != null) { + monThr.start(); + monThr.waitForStartup(); + } + } + + @Override + public void shutdown() throws Exception { + + for (DIRStatusListener listener : statusListener) { + listener.shuttingDown(); + } + + if (statusServer != null) { + statusServer.shutdown(); + } + server.shutdown(); + server.waitForShutdown(); + database.shutdown(); + + if (discoveryThr != null) { + discoveryThr.shutdown(); + discoveryThr.waitForShutdown(); + } + + if (monThr != null) { + monThr.shutdown(); + monThr.waitForShutdown(); + } + + this.quit = true; + this.interrupt(); + this.waitForShutdown(); + } + + private void registerOperations() throws BabuDBException { + + DIROperation op; + op = new GetGlobalTimeOperation(this); + registry.put(op.getProcedureId(), op); + + op = new GetAddressMappingOperation(this); + registry.put(op.getProcedureId(), op); + + op = new SetAddressMappingOperation(this); + registry.put(op.getProcedureId(), op); + + op = new DeleteAddressMappingOperation(this); + registry.put(op.getProcedureId(), op); + + op = new RegisterServiceOperation(this); + registry.put(op.getProcedureId(), op); + + op = new DeregisterServiceOperation(this); + registry.put(op.getProcedureId(), op); + + op = new GetServiceByUuidOperation(this); + registry.put(op.getProcedureId(), op); + + op = new GetServicesByTypeOperation(this); + registry.put(op.getProcedureId(), op); + + op = new GetServiceByNameOperation(this); + registry.put(op.getProcedureId(), op); + + op = new ServiceOfflineOperation(this); + registry.put(op.getProcedureId(), op); + + op = new SetConfigurationOperation(this); + registry.put(op.getProcedureId(), op); + + op = new GetConfigurationOperation(this); + registry.put(op.getProcedureId(), op); + + op = new UpdateVivaldiClientOperation(this); + registry.put(op.getProcedureId(), op); + } + + public Database getDirDatabase() throws BabuDBException { + return database.getDatabaseManager().getDatabase(DB_NAME); + } + + @Override + public void receiveRecord(RPCServerRequest rq) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "received new request: %s", rq + .toString()); + this.queue.add(rq); + } + + public void processRequest(RPCServerRequest rq) { + RPCHeader hdr = rq.getHeader(); + + if (hdr.getMessageType() != MessageType.RPC_REQUEST) { + rq.sendError(ErrorType.GARBAGE_ARGS, POSIXErrno.POSIX_ERROR_EIO, + "expected RPC request message type but got " + hdr.getMessageType()); + return; + } + + RPCHeader.RequestHeader rqHdr = hdr.getRequestHeader(); + + /* + * if (rqHdr.hasInterfaceId() == NettestInterface.getVersion()) { + * Nettest.handleNettest(hdr,rq); return; } + */ + + if (rqHdr.getInterfaceId() != DIRServiceConstants.INTERFACE_ID) { + rq.sendError( + ErrorType.INVALID_INTERFACE_ID, + POSIXErrno.POSIX_ERROR_EIO, + "Invalid interface id. This is a DIR service. You probably wanted to contact another service. Check the used address and port."); + return; + } + + // everything ok, find the right operation + DIROperation op = registry.get(rqHdr.getProcId()); + if (op == null) { + rq.sendError(ErrorType.INVALID_PROC_ID, POSIXErrno.POSIX_ERROR_EIO, + "unknown procedure id requested"); + return; + } + + DIRRequest dirRq = new DIRRequest(rq); + try { + op.parseRPCMessage(dirRq); + numRequests++; + op.startRequest(dirRq); + } catch (Throwable ex) { + ex.printStackTrace(); + rq.sendError(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_EIO, + "internal server error: " + ex.toString(), OutputUtils.stackTraceToString(ex)); + return; + } + } + + @Override + public void startupPerformed() { + } + + @Override + public void shutdownPerformed() { + } + + @Override + public void crashPerformed(Throwable cause) { + final String report = CrashReporter + .createCrashReport("DIR", VersionManagement.RELEASE_VERSION, cause); + System.out.println(report); + CrashReporter.reportXtreemFSCrash(report); + try { + shutdown(); + } catch (Exception e) { + Logging.logError(Logging.LEVEL_ERROR, this, e); + } + } + + public long getNumRequests() { + return server.getPendingRequests(); + } + + public int getNumConnections() { + return server.getNumConnections(); + } + + //public HashMap getVivaldiClientMap(){ + public VivaldiClientMap getVivaldiClientMap(){ + return vivaldiClientMap; + } + + public DIRConfig getConfig() { + return config; + } + + private void initDB(DatabaseManager dbMan, SnapshotManager sMan) { + final byte[] versionKey = "version".getBytes(); + try { + Database db = dbMan.createDatabase("dirdbver", 2); + ReusableBuffer rb = null; + try { + byte[] keyData = new byte[4]; + rb = ReusableBuffer.wrap(keyData); + rb.putInt(DB_VERSION); + db.singleInsert(0, versionKey, keyData, null).get(); + } catch (Exception ex) { + ex.printStackTrace(); + System.err.println("cannot initialize database"); + System.exit(1); + } finally { + if (rb != null) + BufferPool.free(rb); + } + } catch (BabuDBException ex) { + // database exists: check version + if (ex.getErrorCode() == BabuDBException.ErrorCode.DB_EXISTS) { + ReusableBuffer rb = null; + try { + Database db = dbMan.getDatabase("dirdbver"); + + byte[] value = db.lookup(0, versionKey, null).get(); + int ver = -1; + if ((value != null) && (value.length == 4)) { + rb = ReusableBuffer.wrap(value); + ver = rb.getInt(); + } + if (ver != DB_VERSION) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "OUTDATED DATABASE VERSION DETECTED!"); + Logging + .logMessage( + Logging.LEVEL_ERROR, + this, + "the database was created contains data with version no %d, this DIR uses version %d.", + ver, DB_VERSION); + Logging.logMessage(Logging.LEVEL_ERROR, this, + "please start an older version of the DIR or remove the old database"); + System.exit(1); + } + } catch (Exception ex2) { + ex2.printStackTrace(); + System.err.println("cannot initialize database"); + System.exit(1); + } finally { + if (rb != null) + BufferPool.free(rb); + } + } else { + ex.printStackTrace(); + System.err.println("cannot initialize database"); + System.exit(1); + } + } + + try { + dbMan.createDatabase("dirdb", 3); + } catch (BabuDBException ex) { + // database already created + } + } + + public void addStatusListener(DIRStatusListener listener) { + this.statusListener.add(listener); + } + + public void removeStatusListener(DIRStatusListener listener) { + this.statusListener.remove(listener); + } + + /** + * Tells all listeners when an AddressMapping was added. + */ + public void notifyAddressMappingAdded(String uuid, String uri) { + for (DIRStatusListener listener : statusListener) { + listener.addressMappingAdded(); + } + } + + /** + * Tells all listeners when an AddressMapping was deleted. + */ + public void notifyAddressMappingDeleted(String uuid, String uri) { + for (DIRStatusListener listener : statusListener) { + listener.addressMappingDeleted(); + } + } + + /** + * Tells all listeners when the configuration has changed. + */ + public void notifyConfigurationChange() { + for (DIRStatusListener listener : statusListener) { + listener.DIRConfigChanged(this.config); + } + } + + /** + * Tells all listeners when an ServiceRegistred or Updated its registration at the DIR. + * + */ + public void notifyServiceRegistred(String uuid, String name, String type, String pageUrl, + String geoCoordinates, long totalRam, long usedRam, long lastUpdated, int status, int load, + int protoVersion) { + for (DIRStatusListener listener : statusListener) { + listener.serviceRegistered(); + } + } + + /** + * Tells all listeners that a service was deregistred. + * + */ + public void notifyServiceDeregistred(String uuid) { + for (DIRStatusListener listener : statusListener) { + listener.serviceDeregistered(); + } + } +} diff --git a/java/servers/src/org/xtreemfs/dir/DIRStatusListener.java b/java/servers/src/org/xtreemfs/dir/DIRStatusListener.java new file mode 100644 index 0000000..ddae04b --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/DIRStatusListener.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir; + + +public interface DIRStatusListener { + + public void addressMappingAdded(); + + public void addressMappingDeleted(); + + public void DIRConfigChanged(DIRConfig config); + + public void serviceRegistered(); + + public void serviceDeregistered(); + + /** + * Called when DIR is shutting down. + */ + public void shuttingDown(); +} diff --git a/java/servers/src/org/xtreemfs/dir/MonitoringThread.java b/java/servers/src/org/xtreemfs/dir/MonitoringThread.java new file mode 100644 index 0000000..f3eb3e4 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/MonitoringThread.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir; + +import java.io.OutputStream; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import org.xtreemfs.dir.data.ServiceRecord; +import org.xtreemfs.dir.data.ServiceRecords; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; + +/** + * + * @author bjko + */ +public class MonitoringThread extends LifeCycleThread { + + private final DIRConfig cfg; + + /** + * check every 10 seconds + */ + private final int sleep; + + private final Map warnCount; + + private volatile boolean quit; + + private final DIRRequestDispatcher master; + + public MonitoringThread(DIRConfig config, DIRRequestDispatcher master) { + super("MonThr"); + this.master = master; + this.cfg = config; + this.sleep = cfg.getTimeoutSeconds()/2*1000; + warnCount = new HashMap(); + } + + public void run() { + + notifyStarted(); + + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, "MonitoringThread started"); + + do { + + try { + sleep(sleep); + } catch (InterruptedException ex) { + break; + } + + long now = System.currentTimeMillis()/1000l; + + try { + ServiceRecords services = master.getServices(); + + List offlineServices = new LinkedList(); + boolean sendWarning = false; + + for (ServiceRecord srv : services.getList()) { + + if (srv.getType() == ServiceType.SERVICE_TYPE_VOLUME) + continue; + + if (srv.getLast_updated_s() < now+cfg.getTimeoutSeconds()) { + + //we have a timeout + + int wc = 0; + if (warnCount.get(srv.getUuid()) != null) { + wc = warnCount.get(srv.getUuid()); + } + wc++; + final String str = srv.getUuid()+"/"+srv.getName()+" - "+(srv.getLast_updated_s() == 0 ? "service was shut down" : "last heartbeat "+new Date(srv.getLast_updated_s() * 1000)); + offlineServices.add(str); + warnCount.put(srv.getUuid(), wc); + if (wc <= cfg.getMaxWarnings()) { + sendWarning = true; + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, "service is offline: %s", str); + } + + } else { + //service is online, remove warn cound + warnCount.remove(srv.getUuid()); + } + + } + + if ( sendWarning && (cfg.getAdminEmail().length() > 0)) { + //send warning email + StringBuilder sendmailData = new StringBuilder(); + sendmailData.append("To: "+cfg.getAdminEmail()); + sendmailData.append("\n"); + if (cfg.getSenderAddress().length() > 0) { + sendmailData.append("From: "+cfg.getSenderAddress()); + sendmailData.append("\n"); + } + sendmailData.append("Subject: XtreemFS service(s) offline\n"); + sendmailData.append("The following service(s) did not send a heartbeat signal for at least "+cfg.getTimeoutSeconds()+" seconds: \n\n"); + for (String srv : offlineServices) { + sendmailData.append(srv); + sendmailData.append("\n"); + } + sendmailData.append("\n--END--\n.\n"); + + Process p = Runtime.getRuntime().exec(cfg.getSendmailBin()+" -t "+cfg.getAdminEmail()); + OutputStream os = p.getOutputStream(); + os.write(sendmailData.toString().getBytes()); + os.close(); + p.waitFor(); + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, "sent email to %s", cfg.getAdminEmail()); + } + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_INFO, Category.all, ex); + } + + } while (!quit); + + notifyStopped(); + + } + + public void shutdown() { + this.quit = true; + this.interrupt(); + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/ReplicaStatusPage.java b/java/servers/src/org/xtreemfs/dir/ReplicaStatusPage.java new file mode 100644 index 0000000..bcf0a99 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/ReplicaStatusPage.java @@ -0,0 +1,154 @@ +/** + * Copyright (c) 2013 Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map.Entry; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.ResultSet; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.common.statusserver.StatusServerHelper; +import org.xtreemfs.common.statusserver.StatusServerModule; +import org.xtreemfs.dir.data.ServiceRecord; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.json.JSONException; +import org.xtreemfs.foundation.json.JSONParser; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; + +import com.sun.net.httpserver.HttpExchange; + +/** + * Serves a HTML page, which is using JavaScript to monitor and present the states of the OSDs and open files. + */ +public class ReplicaStatusPage extends StatusServerModule { + + private DIRRequestDispatcher master; + + private final String statusPageTemplate; + + private enum Vars { + OSDSJSON(""); + + private String template; + + Vars(String template) { + this.template = template; + } + + @Override + public String toString() { + return template; + } + }; + + public ReplicaStatusPage() { + StringBuffer sb = StatusServerHelper.readTemplate("org/xtreemfs/dir/templates/replica_status.html"); + if (sb == null) { + statusPageTemplate = "

    Template was not found, unable to show status page!

    "; + } else { + statusPageTemplate = sb.toString(); + } + } + + @Override + public String getDisplayName() { + return "Replica Status Summary"; + } + + @Override + public String getUriPath() { + return "/replica_status"; + } + + @Override + public boolean isAvailableForService(ServiceType service) { + return service == ServiceType.SERVICE_TYPE_DIR; + } + + @Override + public void initialize(ServiceType service, Object serviceRequestDispatcher) { + assert (service == ServiceType.SERVICE_TYPE_DIR); + master = (DIRRequestDispatcher) serviceRequestDispatcher; + } + + @Override + public void shutdown() { + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + + String uriPath = httpExchange.getRequestURI().getPath(); + if (uriPath.equals("/replica_status/d3.v3.js")) { + StatusServerHelper.sendFile("org/xtreemfs/dir/templates/d3.v3.js", httpExchange); + } else if (uriPath.equals("/replica_status")) { + handleStatusPage(httpExchange); + } else { + httpExchange.sendResponseHeaders(404, -1); + httpExchange.close(); + } + + } + + private void handleStatusPage(HttpExchange httpExchange) throws IOException { + // The OSDs will be saved as a map associating the OSDs uuid with a map consisting of the uuid, the + // name and the status page url. This map will be served as JSON. + // For example: { "osd-uuid-1": { "uuid": "osd-uuid-1", "name": "OSD Number 1", "status_page_url": "http://osd1.cluster.tld"} } + HashMap> osds = new HashMap>(); + ResultSet iter = null; + + try { + // NOTE(jdillmann): Access to the database is not synchronized. This might result in reading stale data. + final Database database = master.getDirDatabase(); + + iter = database.prefixLookup(DIRRequestDispatcher.INDEX_ID_SERVREG, new byte[0], null).get(); + while (iter.hasNext()) { + Entry e = iter.next(); + final String uuid = new String(e.getKey()); + final ServiceRecord sreg = new ServiceRecord(ReusableBuffer.wrap(e.getValue())); + + if (sreg.getType() == ServiceType.SERVICE_TYPE_OSD) { + HashMap data = new HashMap(); + data.put("uuid", sreg.getUuid()); + data.put("name", sreg.getName()); + + for (Entry dataEntry : sreg.getData().entrySet()) { + if (dataEntry.getKey().equals("status_page_url")) { + data.put("status_page_url", dataEntry.getValue()); + } + } + + // Add only OSDs with a status_page_url and are not shutdown. + if (data.containsKey("status_page_url") && sreg.getLast_updated_s() != 0) { + osds.put(sreg.getUuid(), data); + } + } + + } + + String osdsJSON = JSONParser.writeJSON(osds); + sendResponse(httpExchange, statusPageTemplate.replace(Vars.OSDSJSON.toString(), osdsJSON)); + + } catch (BabuDBException ex) { + Logging.logError(Logging.LEVEL_WARN, (Object) null, ex); + httpExchange.sendResponseHeaders(500, 0); + } catch (JSONException ex) { + Logging.logError(Logging.LEVEL_WARN, (Object) null, ex); + httpExchange.sendResponseHeaders(500, 0); + } finally { + httpExchange.close(); + if (iter != null) { + iter.free(); + } + } + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/StatusPage.java b/java/servers/src/org/xtreemfs/dir/StatusPage.java new file mode 100644 index 0000000..29f361b --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/StatusPage.java @@ -0,0 +1,394 @@ +/** + * Copyright (c) 2013 Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir; + +import java.io.IOException; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.Map.Entry; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.xtreemfs.babudb.BabuDBFactory; +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.ResultSet; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.common.HeartbeatThread; +import org.xtreemfs.common.config.ServiceConfig; +import org.xtreemfs.common.statusserver.StatusServerHelper; +import org.xtreemfs.common.statusserver.StatusServerModule; +import org.xtreemfs.dir.data.AddressMappingRecord; +import org.xtreemfs.dir.data.AddressMappingRecords; +import org.xtreemfs.dir.data.ConfigurationRecord; +import org.xtreemfs.dir.data.ServiceRecord; +import org.xtreemfs.foundation.VersionManagement; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.osd.vivaldi.VivaldiNode; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.OSDHealthResult; + +import com.sun.net.httpserver.HttpExchange; + +/** + * Serves a simple HTML status page with DIR stats. + */ +public class StatusPage extends StatusServerModule { + + private DIRRequestDispatcher master; + + private final DIRConfig config; + + private final String statusPageTemplate; + + /** + * Time after a service, which has not send a heartbeat signal, will be displayed as not available + * (default: 10 min). + */ + private final static int SERVICE_TIMEOUT = 600000; + + private enum Vars { + + MAXMEM(""), + FREEMEM(""), + AVAILPROCS(""), + BPSTATS(""), + PORT(""), + DEBUG(""), + NUMCON(""), + PINKYQ(""), + NUMREQS(""), + TIME(""), + TABLEDUMP(""), + PROTOVERSION(""), + VERSION(""), + DBVERSION(""); + + private String template; + + Vars(String template) { + this.template = template; + } + + public String toString() { + return template; + } + }; + + public StatusPage(DIRConfig config) { + StringBuffer sb = StatusServerHelper.readTemplate("org/xtreemfs/dir/templates/status.html"); + if (sb == null) { + statusPageTemplate = "

    Template was not found, unable to show status page!

    "; + } else { + statusPageTemplate = sb.toString(); + } + + this.config = config; + } + + @Override + public String getDisplayName() { + return "DIR Status Summary"; + } + + @Override + public String getUriPath() { + return "/"; + } + + @Override + public boolean isAvailableForService(ServiceType service) { + return service == ServiceType.SERVICE_TYPE_DIR; + } + + @Override + public void initialize(ServiceType service, Object serviceRequestDispatcher) { + assert (service == ServiceType.SERVICE_TYPE_DIR); + master = (DIRRequestDispatcher) serviceRequestDispatcher; + } + + @Override + public void shutdown() { + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + + ResultSet addrMapsIter = null; + ResultSet servRegIter = null; + ResultSet confIter = null; + + try { + // NOTE(jdillmann): Access to the database is not synchronized. This might result in reading stale data. + final Database database = master.getDirDatabase(); + + assert (statusPageTemplate != null); + + long time = System.currentTimeMillis(); + + addrMapsIter = database.prefixLookup(DIRRequestDispatcher.INDEX_ID_ADDRMAPS, new byte[0], null).get(); + StringBuilder dump = new StringBuilder(); + dump.append("
    "); + dump.append(""); + while (addrMapsIter.hasNext()) { + Entry e = addrMapsIter.next(); + AddressMappingRecords ams = new AddressMappingRecords(ReusableBuffer.wrap(e.getValue())); + + final String uuid = new String(e.getKey()); + + dump.append("
    Address Mapping
    UUIDmapping
    "); + dump.append(uuid); + dump.append(""); + dump.append(""); + dump.append("
    "); + long version = 0; + for (AddressMappingRecord am : ams.getRecords()) { + dump.append(""); + version = am.getVersion(); + } + dump.append("
    "); + String endpoint = am.getUri() + " (" + am.getProtocol() + "," + am.getAddress() + "," + + am.getPort() + ")"; + dump.append(endpoint); + dump.append(""); + dump.append(am.getMatch_network()); + dump.append(""); + dump.append(am.getTtl_s()); + dump.append("
    version: "); + dump.append(version); + dump.append("
    "); + } + dump.append("
    "); + addrMapsIter.free(); + + servRegIter = database.prefixLookup(DIRRequestDispatcher.INDEX_ID_SERVREG, new byte[0], null).get(); + + dump.append("
    "); + dump.append(""); + while (servRegIter.hasNext()) { + Entry e = servRegIter.next(); + final String uuid = new String(e.getKey()); + final ServiceRecord sreg = new ServiceRecord(ReusableBuffer.wrap(e.getValue())); + + dump.append(""); + } + + dump.append("
    Service Registry
    UUIDmapping
    "); + dump.append(uuid); + dump.append(""); + + dump.append(""); + + dump.append(""); + + // sort the set of entries + SortedMap sMap = new TreeMap(); + for (Entry entry : sreg.getData().entrySet()) + sMap.put(entry.getKey(), entry.getValue()); + + //remove osd_health_check_output from map to display it together with osd_health_check_result + String osdHealthCheckOutput = sMap.remove("osd_health_check_output"); + + for (Entry dataEntry : sMap.entrySet()) { + dump.append(""); + } + + dump.append(""); + } + + dump.append("
    "); + dump.append("type"); + dump.append(""); + dump.append(sreg.getType()); + dump.append("
    "); + dump.append("name"); + dump.append(""); + dump.append(sreg.getName()); + dump.append("
    "); + dump.append(dataEntry.getKey()); + dump.append(""); + + if (dataEntry.getKey().equals("status_page_url")) { + dump.append(""); + } + + if (!(dataEntry.getKey().equals(HeartbeatThread.STATUS_ATTR) || dataEntry.getKey().equals( + "osd_health_check"))) { + dump.append(dataEntry.getValue()); + } + + if (dataEntry.getKey().equals("status_page_url")) { + dump.append(""); + } else if (dataEntry.getKey().equals("last_updated")) { + + } else if (dataEntry.getKey().equals(HeartbeatThread.STATUS_ATTR)) { + ServiceStatus status = ServiceStatus.valueOf(Integer.valueOf(dataEntry.getValue())); + switch (status) { + case SERVICE_STATUS_AVAIL: + dump.append("online (new files will be assigned to it)"); + break; + case SERVICE_STATUS_TO_BE_REMOVED: + dump.append("locked (new files will not be assigned to it)"); + break; + case SERVICE_STATUS_REMOVED: + dump.append("removed (replicas assigned to this OSD will be replaced)"); + break; + } + } else if (dataEntry.getKey().equals("free") || dataEntry.getKey().equals("total") + || dataEntry.getKey().endsWith("RAM") || dataEntry.getKey().equals("used")) { + dump.append(" bytes ("); + dump.append(OutputUtils.formatBytes(Long.parseLong(dataEntry.getValue()))); + dump.append(")"); + } else if (dataEntry.getKey().equals("load")) { + dump.append("%"); + } else if (dataEntry.getKey().equals("vivaldi_coordinates")) { + final VivaldiCoordinates coord = VivaldiNode.stringToCoordinates(dataEntry.getValue()); + dump.append(" ("); + dump.append(coord.getXCoordinate()); + dump.append(","); + dump.append(coord.getYCoordinate()); + dump.append(" err "); + dump.append(coord.getLocalError()); + dump.append(")"); + } else if (dataEntry.getKey().equals("osd_health_check")) { + switch (OSDHealthResult.valueOf(Integer.valueOf(dataEntry.getValue()))) { + case OSD_HEALTH_RESULT_PASSED: + dump.append("passed (" + osdHealthCheckOutput + ")"); + break; + case OSD_HEALTH_RESULT_FAILED: + dump.append("failed (" + osdHealthCheckOutput + ")"); + break; + case OSD_HEALTH_RESULT_WARNING: + dump.append("warning (" + osdHealthCheckOutput + ")"); + break; + case OSD_HEALTH_RESULT_NOT_AVAIL: + dump.append("Not available (" + dataEntry.getValue() + ")"); + } + } + dump.append("
    "); + dump.append("last updated"); + dump.append(""); + dump.append(sreg.getLast_updated_s()); + if (sreg.getLast_updated_s() == 0) { + dump.append(" (service was shutdown)"); + } else { + dump.append(" ("); + Date lastUpdatedDate = new Date(sreg.getLast_updated_s() * 1000); + dump.append(lastUpdatedDate); + // check timeout only for MRCs and OSDs + if (sreg.getType() == ServiceType.SERVICE_TYPE_MRC + || sreg.getType() == ServiceType.SERVICE_TYPE_OSD) { + long lastUpdateDateTime = lastUpdatedDate.getTime(); + if (lastUpdateDateTime < (System.currentTimeMillis() - SERVICE_TIMEOUT)) { + dump.append(", that's "); + dump.append(OutputUtils.SecondsToString((System.currentTimeMillis() - lastUpdateDateTime) / 1000)); + dump.append(" ago. Please check connectivity of the server"); + } + } + dump.append(")"); + dump.append("
    version: "); + dump.append(sreg.getVersion()); + dump.append("
    "); + servRegIter.free(); + + // Configuration part + + confIter = database.prefixLookup(DIRRequestDispatcher.INDEX_ID_CONFIGURATIONS, new byte[0], null).get(); + + dump.append("
    "); + dump.append(""); + + while (confIter.hasNext()) { + Entry e = confIter.next(); + final String uuid = new String(e.getKey()); + final ConfigurationRecord conf = new ConfigurationRecord(ReusableBuffer.wrap(e.getValue())); + + dump.append(""); + } + confIter.free(); + + dump.append("
    Configurations
    UUIDConfiguration Parameter
    "); + dump.append(uuid); + dump.append(""); + + Collections.sort(conf.getData(), new Comparator() { + public int compare(KeyValuePair o1, KeyValuePair o2) { + return o1.getKey().compareTo(o2.getKey()); + } + }); + + for (KeyValuePair kvp : conf.getData()) { + dump.append(""); + } + + dump.append("
    "); + dump.append(kvp.getKey()); + dump.append(""); + + dump.append(kvp.getKey().equals(ServiceConfig.Parameter.ADMIN_PASSWORD.getPropertyString()) + || kvp.getKey().equals(ServiceConfig.Parameter.CAPABILITY_SECRET.getPropertyString()) + || kvp.getKey() + .equals(ServiceConfig.Parameter.SERVICE_CREDS_PASSPHRASE.getPropertyString()) + || kvp.getKey() + .equals(ServiceConfig.Parameter.TRUSTED_CERTS_PASSPHRASE.getPropertyString()) ? "*******" + : kvp.getValue()); + dump.append("
    version: "); + dump.append(conf.getVersion()); + dump.append("
    "); + dump.append(""); + + String tmp = null; + try { + tmp = statusPageTemplate.replace(Vars.AVAILPROCS.toString(), Runtime.getRuntime().availableProcessors() + + " bytes"); + } catch (Exception e) { + tmp = statusPageTemplate; + } + tmp = tmp.replace(Vars.FREEMEM.toString(), Runtime.getRuntime().freeMemory() + " bytes"); + tmp = tmp.replace(Vars.MAXMEM.toString(), Runtime.getRuntime().maxMemory() + " bytes"); + tmp = tmp.replace(Vars.BPSTATS.toString(), BufferPool.getStatus()); + tmp = tmp.replace(Vars.PORT.toString(), Integer.toString(config.getPort())); + tmp = tmp.replace(Vars.DEBUG.toString(), Integer.toString(config.getDebugLevel())); + tmp = tmp.replace(Vars.NUMCON.toString(), Integer.toString(master.getNumConnections())); + tmp = tmp.replace(Vars.NUMREQS.toString(), Long.toString(master.getNumRequests())); + tmp = tmp.replace(Vars.TIME.toString(), new Date(time).toString() + " (" + time + ")"); + tmp = tmp.replace(Vars.TABLEDUMP.toString(), dump.toString()); + + tmp = tmp.replace(Vars.VERSION.toString(), VersionManagement.RELEASE_VERSION); + tmp = tmp.replace(Vars.PROTOVERSION.toString(), Integer.toString(DIRServiceConstants.INTERFACE_ID)); + tmp = tmp.replace(Vars.DBVERSION.toString(), BabuDBFactory.BABUDB_VERSION); + + sendResponse(httpExchange, tmp); + + } catch (BabuDBException ex) { + Logging.logError(Logging.LEVEL_WARN, (Object) null, ex); + httpExchange.sendResponseHeaders(500, 0); + } finally { + httpExchange.close(); + if (addrMapsIter != null) { + addrMapsIter.free(); + } + if (servRegIter != null) { + servRegIter.free(); + } + if (confIter != null) { + confIter.free(); + } + } + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/VivaldiClientMap.java b/java/servers/src/org/xtreemfs/dir/VivaldiClientMap.java new file mode 100644 index 0000000..17f9e63 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/VivaldiClientMap.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2012 by Matthias Noack, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir; + +import java.net.InetSocketAddress; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.xtreemfs.dir.VivaldiClientMap.VivaldiClientValue; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +public class VivaldiClientMap extends ConcurrentHashMap { + + private static final long serialVersionUID = 1L; + private final int MAX_SIZE; + private final long TIME_OUT_IN_MS; + + public class VivaldiClientValue { + private InetSocketAddress address; + private VivaldiCoordinates coordinates; + private long timeStamp; + + public VivaldiClientValue(InetSocketAddress addr, VivaldiCoordinates coords, long time) { + this.address = addr; + this.coordinates = coords; + this.timeStamp = time; + } + + public VivaldiClientValue(InetSocketAddress addr, VivaldiCoordinates coords) { + this.address = addr; + this.coordinates = coords; + this.timeStamp = System.currentTimeMillis(); + } + + public InetSocketAddress getAddress() { + return address; + } + + public VivaldiCoordinates getCoordinates() { + return coordinates; + } + + public long getTimeStamp() { + return timeStamp; + } + } + + public VivaldiClientMap(int maxSize, long timeOutInMS) { + super(maxSize + 1); // +1 because put inserts first, and then removes an old element if necessary + MAX_SIZE = maxSize; + TIME_OUT_IN_MS = timeOutInMS; + } + + public void put(InetSocketAddress addr, VivaldiCoordinates coords) { + // TODO (mno): InetSocketAddress changes as a side effect when + // some getter or toString trigger a lookup or reverse-lookup respectively + if(MAX_SIZE > 0) + { + // first put ... + this.put(addr.getHostName(), new VivaldiClientValue(addr, coords)); + + // ...then check if size was exceeded, this avoids re-inserts for puts with existing keys + if (this.size() > MAX_SIZE) { + filterTimeOuts(); + if (this.size() > MAX_SIZE) { + removeOldestEntry(); + } + } + } + } + + private void removeOldestEntry() { + long minTime = Long.MAX_VALUE; + String minKey = null; + boolean first = true; + + for (Map.Entry e : this.entrySet()) { + final long putTime = e.getValue().getTimeStamp(); + if (first || (minTime < putTime)) { + minTime = putTime; + minKey = e.getKey(); + first = false; + } + } + + if(minKey != null) + this.remove(minKey); + } + + public void filterTimeOuts() { + for (Iterator> it = this.entrySet().iterator(); it.hasNext(); ) { + final long timeSinceLastUpdate = System.currentTimeMillis() - it.next().getValue().getTimeStamp(); + if (timeSinceLastUpdate > TIME_OUT_IN_MS) { + it.remove(); + } + } + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/VivaldiStatusPage.java b/java/servers/src/org/xtreemfs/dir/VivaldiStatusPage.java new file mode 100644 index 0000000..934ffeb --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/VivaldiStatusPage.java @@ -0,0 +1,191 @@ +/** + * Copyright (c) 2013 Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.dir; + +import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.ResultSet; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.common.HeartbeatThread; +import org.xtreemfs.common.statusserver.StatusServerHelper; +import org.xtreemfs.common.statusserver.StatusServerModule; +import org.xtreemfs.dir.data.ServiceRecord; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.osd.vivaldi.VivaldiNode; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +import com.sun.net.httpserver.HttpExchange; + +/** + * Serves a HTML status page, which is using JavaScript to visualize vivaldi distances and states. + */ +public class VivaldiStatusPage extends StatusServerModule { + + private DIRRequestDispatcher master; + + private DIRConfig config; + + public VivaldiStatusPage(DIRConfig config) { + this.config = config; + } + + @Override + public String getDisplayName() { + return "Vivaldi Status Summary"; + } + + @Override + public String getUriPath() { + return "/vivaldi"; + } + + @Override + public boolean isAvailableForService(ServiceType service) { + return service == ServiceType.SERVICE_TYPE_DIR; + } + + @Override + public void initialize(ServiceType service, Object serviceRequestDispatcher) { + assert (service == ServiceType.SERVICE_TYPE_DIR); + master = (DIRRequestDispatcher) serviceRequestDispatcher; + } + + @Override + public void shutdown() { + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + + String uriPath = httpExchange.getRequestURI().getPath(); + if (uriPath.equals("/vivaldi/data")) { + try { + String content = getVivaldiData(); + sendResponse(httpExchange, content); + } catch (BabuDBException ex) { + Logging.logError(Logging.LEVEL_WARN, (Object) null, ex); + httpExchange.sendResponseHeaders(500, 0); + } finally { + httpExchange.close(); + } + } else if (uriPath.equals("/vivaldi")) { + StatusServerHelper.sendFile("org/xtreemfs/dir/templates/vivaldi.html", httpExchange); + } else if (uriPath.equals("/vivaldi/d3.js")) { + StatusServerHelper.sendFile("org/xtreemfs/dir/templates/d3.js", httpExchange); + } else { + httpExchange.sendResponseHeaders(404, -1); + httpExchange.close(); + } + + } + + private String getVivaldiData() throws BabuDBException, IOException { + // NOTE(jdillmann): Access to the database is not synchronized. This might result in reading stale data. + final Database database = master.getDirDatabase(); + StringBuilder dump = new StringBuilder(); + ResultSet iter = database + .prefixLookup(DIRRequestDispatcher.INDEX_ID_SERVREG, new byte[0], null).get(); + + // create tab separated plain text table + dump.append("uuid"); + dump.append("\t"); + dump.append("name"); + dump.append("\t"); + dump.append("type"); + dump.append("\t"); + dump.append("status"); + dump.append("\t"); + dump.append("vivaldi_x"); + dump.append("\t"); + dump.append("vivaldi_y"); + dump.append("\t"); + dump.append("vivaldi_err"); + + while (iter.hasNext()) { + Entry e = iter.next(); + final String uuid = new String(e.getKey()); + final ServiceRecord sreg = new ServiceRecord(ReusableBuffer.wrap(e.getValue())); + + final ServiceStatus status = ServiceStatus.valueOf(Integer.valueOf(sreg.getData().get( + HeartbeatThread.STATUS_ATTR))); + String statusString = "unknown value"; + switch (status) { + case SERVICE_STATUS_AVAIL: + statusString = "online"; + break; + case SERVICE_STATUS_TO_BE_REMOVED: + statusString = "locked"; + break; + case SERVICE_STATUS_REMOVED: + statusString = "removed"; + break; + } + + VivaldiCoordinates coords; + // TODO: remove this condition if other services support coordinates too + if (sreg.getType() == ServiceType.SERVICE_TYPE_OSD) { + coords = VivaldiNode.stringToCoordinates(sreg.getData().get("vivaldi_coordinates")); + } else { + VivaldiCoordinates.Builder coordBuilder = VivaldiCoordinates.newBuilder(); + coordBuilder.setXCoordinate(0.0); + coordBuilder.setYCoordinate(0.0); + coordBuilder.setLocalError(0.0); + coords = coordBuilder.build(); + } + + dump.append("\n"); + dump.append(uuid); + dump.append("\t"); + dump.append(sreg.getName()); + dump.append("\t"); + dump.append(sreg.getType()); + dump.append("\t"); + dump.append(statusString); + dump.append("\t"); + dump.append(coords.getXCoordinate()); + dump.append("\t"); + dump.append(coords.getYCoordinate()); + dump.append("\t"); + dump.append(coords.getLocalError()); + + } // while + + iter.free(); + + master.getVivaldiClientMap().filterTimeOuts(); + // append clients + + // for (Map.Entry entry: + // master.getVivaldiClientMap().entrySet()) { + for (Map.Entry entry : master + .getVivaldiClientMap().entrySet()) { + dump.append("\n"); + dump.append(entry.getValue().getAddress().toString()); + dump.append("\t"); + dump.append(entry.getValue().getAddress().getHostName()); + dump.append("\t"); + dump.append("CLIENT"); + dump.append("\t"); + dump.append("online"); + dump.append("\t"); + dump.append(entry.getValue().getCoordinates().getXCoordinate()); + dump.append("\t"); + dump.append(entry.getValue().getCoordinates().getYCoordinate()); + dump.append("\t"); + dump.append(entry.getValue().getCoordinates().getLocalError()); + } + + return dump.toString(); + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/data/AddressMappingRecord.java b/java/servers/src/org/xtreemfs/dir/data/AddressMappingRecord.java new file mode 100644 index 0000000..35c544e --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/data/AddressMappingRecord.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.data; + +import java.io.IOException; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping; + +/** + * + * @author bjko + */ +public class AddressMappingRecord { + + public static final byte CURRENT_VERSION = 1; + private String uuid; + private long version; + + private String protocol; + + private String address; + + private int port; + + private String match_network; + + private int ttl_s; + + private String uri; + + public AddressMappingRecord(AddressMapping m) { + this.uuid = m.getUuid(); + this.version = m.getVersion(); + this.protocol = m.getProtocol(); + this.address = m.getAddress(); + this.port = m.getPort(); + this.match_network = m.getMatchNetwork(); + this.ttl_s = m.getTtlS(); + this.uri = m.getUri(); + } + + public AddressMappingRecord(ReusableBuffer rb) throws IOException { + byte recVersion = rb.get(); + + if (recVersion == 1) { + uuid = rb.getString(); + version = rb.getLong(); + protocol = rb.getString(); + address = rb.getString(); + port = rb.getInt(); + match_network = rb.getString(); + ttl_s = rb.getInt(); + uri = rb.getString(); + } else { + throw new IOException("don't know how to handle version "+recVersion); + } + } + + public int getSize() { + final int INT_SIZE = Integer.SIZE/8; + final int LONG_SIZE = Long.SIZE/8; + final int BYTE_SIZE = Byte.SIZE/8; + return INT_SIZE*7+LONG_SIZE+getUuid().length()+getProtocol().length()+getAddress().length()+getMatch_network().length()+ + getUri().length()+BYTE_SIZE; + } + + public void serialize(ReusableBuffer rb) { + + rb.put(CURRENT_VERSION); + rb.putString(getUuid()); + rb.putLong(getVersion()); + rb.putString(getProtocol()); + rb.putString(getAddress()); + rb.putInt(getPort()); + rb.putString(getMatch_network()); + rb.putInt(getTtl_s()); + rb.putString(getUri()); + + } + + public AddressMapping getAddressMapping() { + AddressMapping m = AddressMapping.newBuilder().setUuid(uuid). + setVersion(version).setProtocol(protocol).setAddress(address). + setPort(port).setMatchNetwork(match_network).setTtlS(ttl_s). + setUri(uri).build(); + return m; + } + + /** + * @return the uuid + */ + public String getUuid() { + return uuid; + } + + /** + * @return the version + */ + public long getVersion() { + return version; + } + + /** + * @return the protocol + */ + public String getProtocol() { + return protocol; + } + + /** + * @return the address + */ + public String getAddress() { + return address; + } + + /** + * @return the port + */ + public int getPort() { + return port; + } + + /** + * @return the match_network + */ + public String getMatch_network() { + return match_network; + } + + /** + * @return the ttl_s + */ + public int getTtl_s() { + return ttl_s; + } + + /** + * @return the uri + */ + public String getUri() { + return uri; + } + + + +} diff --git a/java/servers/src/org/xtreemfs/dir/data/AddressMappingRecords.java b/java/servers/src/org/xtreemfs/dir/data/AddressMappingRecords.java new file mode 100644 index 0000000..1fab314 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/data/AddressMappingRecords.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.data; + +import java.io.IOException; +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.util.ArrayList; +import java.util.List; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet; + +/** + * + * @author bjko + */ +public class AddressMappingRecords { + + ArrayList records; + + public AddressMappingRecords() { + records = new ArrayList(2); + } + + public AddressMappingRecords(ReusableBuffer rb) throws IOException { + try { + int numEntries = rb.getInt(); + records = new ArrayList(numEntries); + for (int i = 0; i < numEntries; i++) { + AddressMappingRecord m = new AddressMappingRecord(rb); + records.add(m); + } + } catch (BufferUnderflowException ex) { + throw new IOException("corrupted AddressMappingRecords entry: "+ex,ex); + } + } + + public AddressMappingRecords(AddressMappingSet set) { + records = new ArrayList(set.getMappingsCount()); + for (AddressMapping am : set.getMappingsList()) { + records.add(new AddressMappingRecord(am)); + } + } + + public AddressMappingSet getAddressMappingSet() { + AddressMappingSet.Builder set = AddressMappingSet.newBuilder(); + for (AddressMappingRecord rec : records) { + set.addMappings(rec.getAddressMapping()); + } + return set.build(); + } + + public void add(AddressMappingRecords otherList) { + records.addAll(otherList.records); + } + + public int size() { + return records.size(); + } + + public AddressMappingRecord getRecord(int index) { + return records.get(index); + } + + public List getRecords() { + return records; + } + + public int getSize() { + final int INT_SIZE = Integer.SIZE/8; + int size = INT_SIZE; + for (AddressMappingRecord rec: records) { + size += rec.getSize(); + } + return size; + } + + public void serialize(ReusableBuffer rb) throws IOException { + try { + rb.putInt(records.size()); + for (AddressMappingRecord rec: records) { + rec.serialize(rb); + } + } catch (BufferOverflowException ex) { + throw new IOException("buffer too small",ex); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/data/ConfigurationRecord.java b/java/servers/src/org/xtreemfs/dir/data/ConfigurationRecord.java new file mode 100644 index 0000000..472d55a --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/data/ConfigurationRecord.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.data; + +import java.io.IOException; +import java.util.Vector; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; + +public class ConfigurationRecord { + + public static final byte CURRENT_VERSION = 1; + + private String uuid; + + /** + * + */ + private long version; + + private Vector configurationParameter; + + public ConfigurationRecord(Configuration c) { + this.uuid = c.getUuid(); + this.version = c.getVersion(); + this.configurationParameter = new Vector(); + for (KeyValuePair kvp : c.getParameterList()) { + configurationParameter.add(kvp); + } + } + + public ConfigurationRecord(ReusableBuffer rb) throws IOException { + byte recVersion = rb.get(); + + if (recVersion == 1) { + this.uuid = rb.getString(); + this.version = rb.getLong(); + + this.configurationParameter = new Vector(); + while (rb.remaining() != 0) { + configurationParameter.add(KeyValuePair.newBuilder().setKey(rb.getString()) + .setValue(rb.getString()).build()); + + } + } else { + throw new IOException("don't know how to handle version "+recVersion); + } + + } + + public void serialize(ReusableBuffer rb) { + rb.put(CURRENT_VERSION); + rb.putString(uuid); + rb.putLong(getVersion()); + + for (KeyValuePair kvp : configurationParameter) { + rb.putString(kvp.getKey()); + rb.putString(kvp.getValue()); + } + } + + public String getUuid() { + return uuid; + } + + public Configuration getConfiguration() { + Configuration.Builder conf = Configuration.newBuilder(); + + conf.setUuid(this.getUuid()).setVersion(this.getVersion()); + + for (KeyValuePair kvp : configurationParameter) { + conf.addParameter(kvp); + } + + return conf.build(); + + } + + + public int getSize() { + + final int BYTE_SIZE = Byte.SIZE/8; + final int INT_SIZE = Integer.SIZE/8; + final int LONG_SIZE = Long.SIZE/8; + + + //length of the uuid + 1*INT_SIZE for the uuid datatype + int size = getUuid().length() + INT_SIZE; + //+size of the version + size += LONG_SIZE; + //+size of the CURRENT_VERSION + size += BYTE_SIZE; + //+size of the data HashMap + size += (getData().size()*INT_SIZE*2); + + //+size of the values in the HashMap + for (KeyValuePair kvp : configurationParameter) { + size += kvp.getKey().length() + kvp.getValue().length(); + } + + return size; + } + + public Vector getData() { + return this.configurationParameter; + } + + public void setVersion(long version) { + this.version = version; + } + + public long getVersion() { + return version; + } +} diff --git a/java/servers/src/org/xtreemfs/dir/data/ServiceRecord.java b/java/servers/src/org/xtreemfs/dir/data/ServiceRecord.java new file mode 100644 index 0000000..bcacd97 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/data/ServiceRecord.java @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.data; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; + +/** + * + * @author bjko + */ +public class ServiceRecord { + + public static final byte CURRENT_VERSION = 1; + + private ServiceType type; + + private String uuid; + + private long version; + + private String name; + + private long last_updated_s; + + private Map data; + + + public ServiceRecord(Service service) { + type = service.getType(); + uuid = service.getUuid(); + version = service.getVersion(); + name = service.getName(); + last_updated_s = service.getLastUpdatedS(); + data = new HashMap(); + for (KeyValuePair kvp : service.getData().getDataList()) { + data.put(kvp.getKey(),kvp.getValue()); + } + } + + public ServiceRecord(ReusableBuffer rb) throws IOException { + byte recVersion = rb.get(); + + if (recVersion == 1) { + type = ServiceType.valueOf(rb.getInt()); + uuid = rb.getString(); + version = rb.getLong(); + name = rb.getString(); + last_updated_s = rb.getLong(); + final int numEntries = rb.getInt(); + data = new HashMap(); + for (int i = 0; i < numEntries; i++) { + String key = rb.getString(); + String value = rb.getString(); + data.put(key, value); + } + } else { + throw new IOException("don't know how to handle version "+recVersion); + } + } + + public Service getService() { + Service.Builder s = Service.newBuilder(); + s.setType(type); + s.setUuid(uuid); + s.setVersion(version); + s.setName(name); + s.setLastUpdatedS(last_updated_s); + ServiceDataMap.Builder sm = ServiceDataMap.newBuilder(); + for (Entry e : data.entrySet()) { + KeyValuePair kvp = KeyValuePair.newBuilder().setKey(e.getKey()).setValue(e.getValue()).build(); + sm.addData(kvp); + } + s.setData(sm); + return s.build(); + } + + public int getSize() { + final int INT_SIZE = Integer.SIZE/8; + final int LONG_SIZE = Long.SIZE/8; + final int BYTE_SIZE = Byte.SIZE/8; + int size = BYTE_SIZE+INT_SIZE*4+(getData().size()*INT_SIZE*2)+LONG_SIZE*2+getUuid().length()+getName().length(); + for (Entry e : getData().entrySet()) { + size += e.getKey().length()+e.getValue().length(); + } + return size; + } + + public void serialize(ReusableBuffer rb) { + + rb.put(CURRENT_VERSION); + rb.putInt(getType().getNumber()); + rb.putString(getUuid()); + rb.putLong(getVersion()); + rb.putString(getName()); + rb.putLong(getLast_updated_s()); + rb.putInt(getData().size()); + for (Entry e : getData().entrySet()) { + rb.putString(e.getKey()); + rb.putString(e.getValue()); + } + + } + + /** + * @return the type + */ + public ServiceType getType() { + return type; + } + + /** + * @return the uuid + */ + public String getUuid() { + return uuid; + } + + /** + * @return the version + */ + public long getVersion() { + return version; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @return the last_updated_s + */ + public long getLast_updated_s() { + return last_updated_s; + } + + /** + * @return the data + */ + public Map getData() { + return data; + } + + /** + * @param type the type to set + */ + public void setType(ServiceType type) { + this.type = type; + } + + /** + * @param uuid the uuid to set + */ + public void setUuid(String uuid) { + this.uuid = uuid; + } + + /** + * @param version the version to set + */ + public void setVersion(long version) { + this.version = version; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @param last_updated_s the last_updated_s to set + */ + public void setLast_updated_s(long last_updated_s) { + this.last_updated_s = last_updated_s; + } + + /** + * @param data the data to set + */ + public void setData(Map data) { + this.data = data; + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/data/ServiceRecords.java b/java/servers/src/org/xtreemfs/dir/data/ServiceRecords.java new file mode 100644 index 0000000..fce7ee6 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/data/ServiceRecords.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.data; + +import java.io.IOException; +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.util.ArrayList; +import java.util.List; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; + +/** + * + * @author bjko + */ +public class ServiceRecords { + + ArrayList records; + + public ServiceRecords() { + records = new ArrayList(1); + } + + public ServiceRecords(ReusableBuffer rb) throws IOException { + try { + int numEntries = rb.getInt(); + records = new ArrayList(numEntries); + for (int i = 0; i < numEntries; i++) { + ServiceRecord m = new ServiceRecord(rb); + records.add(m); + } + } catch (BufferUnderflowException ex) { + throw new IOException("corrupted ServiceRecords entry: "+ex,ex); + } + } + + public ServiceRecords(ServiceSet set) { + records = new ArrayList(set.getServicesCount()); + for (Service serv : set.getServicesList()) { + records.add(new ServiceRecord(serv)); + } + } + + public ServiceSet getServiceSet() { + ServiceSet.Builder set = ServiceSet.newBuilder(); + for (ServiceRecord rec : records) { + set.addServices(rec.getService()); + } + return set.build(); + } + + public void add(ServiceRecords otherList) { + records.addAll(otherList.records); + } + + public void add(ServiceRecord item) { + records.add(item); + } + + public int size() { + return records.size(); + } + + public ServiceRecord getRecord(int index) { + return records.get(index); + } + + public List getList() { + return records; + } + + public int getSize() { + final int INT_SIZE = Integer.SIZE/8; + int size = INT_SIZE; + for (ServiceRecord rec: records) { + size += rec.getSize(); + } + return size; + } + + public void serialize(ReusableBuffer rb) throws IOException { + try { + rb.putInt(records.size()); + for (ServiceRecord rec: records) { + rec.serialize(rb); + } + } catch (BufferOverflowException ex) { + throw new IOException("buffer too small",ex); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/discovery/DiscoveryMsgThread.java b/java/servers/src/org/xtreemfs/dir/discovery/DiscoveryMsgThread.java new file mode 100644 index 0000000..7227e13 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/discovery/DiscoveryMsgThread.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.discovery; + +import java.net.InetSocketAddress; +import java.nio.channels.DatagramChannel; + +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.utils.PBRPCDatagramPacket; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService; + +/** + * + * @author bjko + */ +public class DiscoveryMsgThread extends LifeCycleThread { + + private final DirService me; + private boolean quit; + + public DiscoveryMsgThread(String address, int port, String protocol) { + super("DiscovMsgThr"); + me = DirService.newBuilder().setAddress(address).setPort(port).setProtocol(protocol).setInterfaceVersion(10001).build(); + quit = false; + } + + @Override + public void run() { + + notifyStarted(); + + final ReusableBuffer data = BufferPool.allocate(2048); + + try { + + final DatagramChannel channel = DatagramChannel.open(); + channel.socket().bind(new InetSocketAddress(me.getPort())); + channel.configureBlocking(true); + + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.lifecycle, me, "DiscoveryMessageThread started"); + + do { + + data.position(0); + data.limit(data.capacity()); + + ReusableBuffer dataOut = null; + try { + InetSocketAddress sender = (InetSocketAddress) channel.receive(data.getBuffer()); + data.flip(); + + PBRPCDatagramPacket packetIn = new PBRPCDatagramPacket(data, emptyRequest.getDefaultInstance()); + + RPCHeader resp = RPCHeader.newBuilder().setMessageType(MessageType.RPC_RESPONSE_SUCCESS).setCallId(packetIn.getHeader().getCallId()).build(); + PBRPCDatagramPacket packetOut = new PBRPCDatagramPacket(resp, me); + dataOut = packetOut.assembleDatagramPacket(); + + channel.send(dataOut.getBuffer(), sender); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.net, this, "responded to UDP dir discover message from %s", sender); + + } catch (Exception ex) { + //bad packet + continue; + } finally { + if (dataOut != null) + BufferPool.free(dataOut); + } + + + } while (!quit); + + channel.close(); + + } catch (Throwable ex) { + if (!quit) + notifyCrashed(ex); + } finally { + BufferPool.free(data); + } + notifyStopped(); + Logging.logMessage(Logging.LEVEL_INFO, Logging.Category.lifecycle, me, "DiscoveryMessageThread shutdown complete"); + + } + + @Override + public void shutdown() { + this.quit = true; + this.interrupt(); + } +} diff --git a/java/servers/src/org/xtreemfs/dir/discovery/DiscoveryUtils.java b/java/servers/src/org/xtreemfs/dir/discovery/DiscoveryUtils.java new file mode 100644 index 0000000..3899ddd --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/discovery/DiscoveryUtils.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.discovery; + +import com.google.protobuf.ByteString; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.InterfaceAddress; +import java.net.NetworkInterface; +import java.net.SocketTimeoutException; +import java.util.Enumeration; +import java.util.LinkedList; +import java.util.List; +import org.xtreemfs.foundation.buffer.BufferPool; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.utils.PBRPCDatagramPacket; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferOutputStream; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.PORTS; + +/** + * + * @author bjko + */ +public class DiscoveryUtils { + + public static final String AUTODISCOVER_HOSTNAME = ".autodiscover"; + + public static DirService discoverDir(int maxWaitSeconds) { + try { + + final DatagramSocket dsock = new DatagramSocket(); + dsock.setBroadcast(true); + dsock.setSoTimeout(1000); + + final byte[] data = new byte[2048]; + + Enumeration nifs = NetworkInterface.getNetworkInterfaces(); + + List broadcasts = new LinkedList(); + + broadcasts.add(InetAddress.getLocalHost()); + + while (nifs.hasMoreElements()) { + NetworkInterface nif = nifs.nextElement(); + for (InterfaceAddress ia : nif.getInterfaceAddresses()) { + InetAddress bc = ia.getBroadcast(); + if (bc != null) { + broadcasts.add(bc); + } + } + } + + + + for (int i = 0; i < maxWaitSeconds; i++) { + + RPCHeader resp = RPCHeader.newBuilder().setMessageType(MessageType.RPC_REQUEST).setCallId(1).build(); + PBRPCDatagramPacket dpack = new PBRPCDatagramPacket(resp, emptyRequest.getDefaultInstance()); + ReusableBuffer buf = dpack.assembleDatagramPacket(); + + byte[] rdata = buf.getData(); + BufferPool.free(buf); + + for (InetAddress bc : broadcasts) { + DatagramPacket rp = new DatagramPacket(rdata, rdata.length, bc, PORTS.DIR_PBRPC_PORT_DEFAULT.getNumber()); + dsock.send(rp); + } + + + DatagramPacket p = new DatagramPacket(data, data.length); + + try { + dsock.receive(p); + } catch (SocketTimeoutException ex) { + continue; + } + + ReusableBuffer b = ReusableBuffer.wrap(data, 0, p.getLength()); + dpack = new PBRPCDatagramPacket(b, DirService.getDefaultInstance()); + DirService service = (DirService)dpack.getMessage(); + + return service; + + } + + dsock.close(); + + return null; + + } catch (Exception ex) { + ex.printStackTrace(); + return null; + } + } + + +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/DIROperation.java b/java/servers/src/org/xtreemfs/dir/operations/DIROperation.java new file mode 100644 index 0000000..df3b44b --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/DIROperation.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import java.io.IOException; + +import org.xtreemfs.babudb.api.database.DatabaseRequestListener; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public abstract class DIROperation { + + protected final DIRRequestDispatcher master; + + public DIROperation(DIRRequestDispatcher master) { + this.master = master; + } + + public abstract int getProcedureId(); + + /** + * called after request was parsed and operation assigned. + * + * @param rq + * the new request + */ + public abstract void startRequest(DIRRequest rq); + + /** + * Method to check if operation needs user authentication. + * + * @return true, if the user needs to be authenticated + */ + public abstract boolean isAuthRequired(); + + protected abstract Message getRequestMessagePrototype(); + + /** + * parses the RPC request message. Can throw any exception which + * will result in an error message telling the client that the + * request message data is garbage. + * @param rq + * @throws java.lang.Exception + */ + public void parseRPCMessage(DIRRequest rq) throws IOException { + rq.deserializeMessage(getRequestMessagePrototype()); + } + + void requestFailed(BabuDBException error, DIRRequest rq) { + assert(error != null); + rq.sendError(ErrorType.ERRNO,POSIXErrno.POSIX_ERROR_EINVAL,error.toString()); + } + + /** + * Operation to give a failure back to the client. + * Will decide, if a {@link RedirectException} should be returned. + * + * @param error - Exception thrown. + * @param rq - original {@link DIRRequest}. + */ + /* + void requestFailed(Exception error, DIRRequest rq) { + // handle connection errors caused by being not the replication master + if (error != null && dbsReplicationManager != null + && ((error instanceof BabuDBException + && ((BabuDBException) error).getErrorCode().equals(NO_ACCESS)) || ( // TODO better exception handling + error instanceof ConcurrentModificationException)) // && !dbsReplicationManager.isMaster() ... removed for testing + ) { + + InetAddress altMaster = dbsReplicationManager.getMaster(); + if (altMaster != null) { + // retrieve the correct port for the DIR mirror + String host = altMaster.getHostAddress(); + Integer port = this.master.getConfig().getMirrors().get(host); + if (port == null) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "The port for " + + "the mirror DIR '%s' could not be retrieved.", + host); + + rq.sendInternalServerError(error); + } else { + rq.sendRedirectException(host, port); + } + } else { + // if there is a handover in progress, redirect to the local + // server to notify the client about this process + InetAddress host = this.master.getConfig().getAddress(); + int port = this.master.getConfig().getPort(); + InetSocketAddress address = + (host == null) + ? new InetSocketAddress(port) + : new InetSocketAddress(host, port); + + rq.sendRedirectException(address.getAddress().getHostAddress(), + port); + } + // handle errors caused by ServerExceptions + } else if (error != null && error instanceof ONCRPCException) { + Logging.logError(Logging.LEVEL_ERROR, this, error); + rq.sendException((ONCRPCException) error); + + // handle user errors + } else if (error != null + && error instanceof BabuDBException + && (((BabuDBException) error).getErrorCode().equals(NO_SUCH_DB) + || ((BabuDBException) error).getErrorCode().equals(DB_EXISTS) + || ((BabuDBException) error).getErrorCode().equals(NO_SUCH_INDEX) + || ((BabuDBException) error).getErrorCode().equals(NO_SUCH_SNAPSHOT) + || ((BabuDBException) error).getErrorCode().equals(SNAP_EXISTS))) { // blame the client + Logging.logError(Logging.LEVEL_ERROR, this, error); + rq.sendException(new InvalidArgumentException(error.getMessage())); + // handle unknown errors + } else { + if (error != null && !(error instanceof BabuDBException)) { + Logging.logError(Logging.LEVEL_ERROR, this, error); + } + + if (error != null) { + Logging.logError(Logging.LEVEL_ERROR, this, error); + } + + rq.sendInternalServerError(error); + } + }*/ + + /** + * Method-interface for sending a response + * + * @param result - can be null, if not necessary. + * @param rq - original {@link DIRRequest}. + */ + abstract void requestFinished(Object result, DIRRequest rq); + + /** + * Listener implementation for non-blocking BabuDB requests. + * + * @author flangner + * @since 11/16/2009 + * @param - input type. + * @param - output type. + */ + abstract class DBRequestListener implements DatabaseRequestListener { + + private final boolean finishRequest; + + DBRequestListener(boolean finishRequest) { + this.finishRequest = finishRequest; + } + + abstract O execute(I result, DIRRequest rq) throws Exception; + + /* + * (non-Javadoc) + * @see org.xtreemfs.babudb.BabuDBRequestListener#failed(org.xtreemfs.babudb.BabuDBException, java.lang.Object) + */ + @Override + public void failed(BabuDBException error, Object request) { + requestFailed(error, (DIRRequest) request); + } + + /* + * (non-Javadoc) + * @see org.xtreemfs.babudb.BabuDBRequestListener#finished(java.lang.Object, java.lang.Object) + */ + @Override + public void finished(I data, Object context) { + try { + O result = execute(data, (DIRRequest) context); + if (finishRequest) { + requestFinished(result, (DIRRequest) context); + } + } catch (IllegalArgumentException ex) { + DIRRequest rq = (DIRRequest) context; + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (java.util.ConcurrentModificationException ex) { + DIRRequest rq = (DIRRequest) context; + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EAGAIN, ex.toString()); + } catch (Exception e) { + DIRRequest rq = (DIRRequest) context; + rq.sendInternalServerError(e); + } + } + } +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/DeleteAddressMappingOperation.java b/java/servers/src/org/xtreemfs/dir/operations/DeleteAddressMappingOperation.java new file mode 100644 index 0000000..91bdb7d --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/DeleteAddressMappingOperation.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.DatabaseInsertGroup; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class DeleteAddressMappingOperation extends DIROperation { + + private final Database database; + + public DeleteAddressMappingOperation(DIRRequestDispatcher master) throws BabuDBException { + super(master); + database = master.getDirDatabase(); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_ADDRESS_MAPPINGS_REMOVE; + } + + @Override + public void startRequest(DIRRequest rq) { + addressMappingGetRequest request = (addressMappingGetRequest) rq.getRequestMessage(); + + DatabaseInsertGroup ig = database.createInsertGroup(); + ig.addDelete(DIRRequestDispatcher.INDEX_ID_ADDRMAPS, request.getUuid().getBytes()); + database.insert(ig, rq).registerListener(new DBRequestListener(true) { + + @Override + Object execute(Object result, DIRRequest rq) throws Exception { + return result; + } + }); + } + + @Override + public boolean isAuthRequired() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + protected Message getRequestMessagePrototype() { + return addressMappingGetRequest.getDefaultInstance(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xtreemfs.dir.operations.DIROperation#requestFinished(java.lang.Object + * , org.xtreemfs.dir.DIRRequest) + */ + @Override + void requestFinished(Object result, DIRRequest rq) { + rq.sendSuccess(emptyResponse.getDefaultInstance()); + } +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/DeregisterServiceOperation.java b/java/servers/src/org/xtreemfs/dir/operations/DeregisterServiceOperation.java new file mode 100644 index 0000000..2d1ef30 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/DeregisterServiceOperation.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.DatabaseInsertGroup; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class DeregisterServiceOperation extends DIROperation { + + private final Database database; + + public DeregisterServiceOperation(DIRRequestDispatcher master) throws BabuDBException { + super(master); + database = master.getDirDatabase(); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_SERVICE_DEREGISTER; + } + + @Override + public void startRequest(DIRRequest rq) { + serviceDeregisterRequest request = (serviceDeregisterRequest) rq.getRequestMessage(); + + DatabaseInsertGroup ig = database.createInsertGroup(); + ig.addDelete(DIRRequestDispatcher.INDEX_ID_SERVREG, request.getUuid().getBytes()); + database.insert(ig, rq).registerListener(new DBRequestListener(true) { + + @Override + Object execute(Object result, DIRRequest rq) throws Exception { + return result; + } + }); + + master.notifyServiceDeregistred(request.getUuid()); + } + + @Override + public boolean isAuthRequired() { + return false; + } + + @Override + protected Message getRequestMessagePrototype() { + return serviceDeregisterRequest.getDefaultInstance(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xtreemfs.dir.operations.DIROperation#requestFinished(java.lang.Object + * , org.xtreemfs.dir.DIRRequest) + */ + @Override + void requestFinished(Object result, DIRRequest rq) { + rq.sendSuccess(emptyResponse.getDefaultInstance()); + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/GetAddressMappingOperation.java b/java/servers/src/org/xtreemfs/dir/operations/GetAddressMappingOperation.java new file mode 100644 index 0000000..ed63af2 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/GetAddressMappingOperation.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import java.util.Map.Entry; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.ResultSet; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.dir.data.AddressMappingRecords; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class GetAddressMappingOperation extends DIROperation { + + private final Database database; + + public GetAddressMappingOperation(DIRRequestDispatcher master) throws BabuDBException { + super(master); + database = master.getDirDatabase(); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_ADDRESS_MAPPINGS_GET; + } + + @Override + public void startRequest(DIRRequest rq) { + addressMappingGetRequest request = + (addressMappingGetRequest)rq.getRequestMessage(); + + if (request.getUuid().length() > 0) { + //single mapping was requested + database.lookup(DIRRequestDispatcher.INDEX_ID_ADDRMAPS, + request.getUuid().getBytes(),rq).registerListener( + new DBRequestListener(true) { + + @Override + AddressMappingSet execute(byte[] result, DIRRequest rq) + throws Exception { + + if (result == null) + return AddressMappingSet.getDefaultInstance(); + else + return new AddressMappingRecords(ReusableBuffer + .wrap(result)).getAddressMappingSet(); + } + }); + } else { + //full list requested + database.prefixLookup(DIRRequestDispatcher.INDEX_ID_ADDRMAPS, + new byte[0], rq).registerListener( + new DBRequestListener,AddressMappingSet>(true) { + + @Override + AddressMappingSet execute(ResultSet result, + DIRRequest rq) throws Exception { + + AddressMappingRecords list = new AddressMappingRecords(); + while (result.hasNext()) { + Entry e = result.next(); + AddressMappingRecords recs = + new AddressMappingRecords( + ReusableBuffer.wrap(e.getValue())); + list.add(recs); + } + return list.getAddressMappingSet(); + } + }); + } + } + + @Override + public boolean isAuthRequired() { + return false; + } + + @Override + protected Message getRequestMessagePrototype() { + return addressMappingGetRequest.getDefaultInstance(); + } + + /* + * (non-Javadoc) + * @see org.xtreemfs.dir.operations.DIROperation#requestFinished(java.lang.Object, org.xtreemfs.dir.DIRRequest) + */ + @Override + void requestFinished(Object result, DIRRequest rq) { + rq.sendSuccess((AddressMappingSet) result); + } +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/GetConfigurationOperation.java b/java/servers/src/org/xtreemfs/dir/operations/GetConfigurationOperation.java new file mode 100644 index 0000000..3635d4b --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/GetConfigurationOperation.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.dir.data.ConfigurationRecord; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; + +public class GetConfigurationOperation extends DIROperation { + + private final Database database; + + public GetConfigurationOperation(DIRRequestDispatcher master) throws BabuDBException { + super(master); + database = master.getDirDatabase(); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_CONFIGURATION_GET; + } + + @Override + protected Message getRequestMessagePrototype() { + + return configurationGetRequest.getDefaultInstance(); + } + + @Override + public boolean isAuthRequired() { + // TODO Auto-generated method stub + return false; + } + + @Override + void requestFinished(Object result, DIRRequest rq) { + rq.sendSuccess((Configuration) result); + + } + + @Override + public void startRequest(DIRRequest rq) { + configurationGetRequest request = (configurationGetRequest) rq.getRequestMessage(); + + database.lookup(DIRRequestDispatcher.INDEX_ID_CONFIGURATIONS, request.getUuid().getBytes(), rq) + .registerListener(new DBRequestListener(true) { + + @Override + Configuration execute(byte[] result, DIRRequest rq) throws Exception { + + if (result == null) { + return Configuration.getDefaultInstance(); + } else { + return new ConfigurationRecord(ReusableBuffer.wrap(result)).getConfiguration(); + + } + } + }); + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/GetGlobalTimeOperation.java b/java/servers/src/org/xtreemfs/dir/operations/GetGlobalTimeOperation.java new file mode 100644 index 0000000..6b02eb0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/GetGlobalTimeOperation.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; +/** + * + * @author bjko + */ +public class GetGlobalTimeOperation extends DIROperation { + + + public GetGlobalTimeOperation(DIRRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_GLOBAL_TIME_S_GET; + } + + @Override + public void startRequest(DIRRequest rq) { + requestFinished(null, rq); + } + + @Override + public boolean isAuthRequired() { + return false; + } + + @Override + protected Message getRequestMessagePrototype() { + return emptyRequest.getDefaultInstance(); + } + + /* + * (non-Javadoc) + * @see org.xtreemfs.dir.operations.DIROperation#requestFinished(java.lang.Object, org.xtreemfs.dir.DIRRequest) + */ + @Override + void requestFinished(Object result, DIRRequest rq) { + globalTimeSGetResponse resp = globalTimeSGetResponse.newBuilder().setTimeInSeconds(System.currentTimeMillis()).build(); + rq.sendSuccess(resp); + } +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/GetServiceByNameOperation.java b/java/servers/src/org/xtreemfs/dir/operations/GetServiceByNameOperation.java new file mode 100644 index 0000000..ba79188 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/GetServiceByNameOperation.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import java.util.Map.Entry; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.ResultSet; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.dir.data.ServiceRecord; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class GetServiceByNameOperation extends DIROperation { + + private final Database database; + + public GetServiceByNameOperation(DIRRequestDispatcher master) throws BabuDBException { + super(master); + database = master.getDirDatabase(); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_SERVICE_GET_BY_NAME; + } + + @Override + public void startRequest(DIRRequest rq) { + final serviceGetByNameRequest request = (serviceGetByNameRequest) rq.getRequestMessage(); + + database.prefixLookup(DIRRequestDispatcher.INDEX_ID_SERVREG, new byte[0], rq).registerListener( + new DBRequestListener, ServiceSet>(true) { + + @Override + ServiceSet execute(ResultSet result, DIRRequest rq) throws Exception { + + ServiceSet.Builder services = ServiceSet.newBuilder(); + long now = System.currentTimeMillis() / 1000l; + + while (result.hasNext()) { + Entry e = result.next(); + ServiceRecord servEntry = new ServiceRecord(ReusableBuffer.wrap(e.getValue())); + if (servEntry.getName().equals(request.getName())) + services.addServices(servEntry.getService()); + + long secondsSinceLastUpdate = now - servEntry.getLast_updated_s(); + servEntry.getData().put("seconds_since_last_update", Long.toString(secondsSinceLastUpdate)); + } + return services.build(); + } + }); + + } + + @Override + public boolean isAuthRequired() { + return false; + } + + @Override + protected Message getRequestMessagePrototype() { + return serviceGetByNameRequest.getDefaultInstance(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xtreemfs.dir.operations.DIROperation#requestFinished(java.lang.Object + * , org.xtreemfs.dir.DIRRequest) + */ + @Override + void requestFinished(Object result, DIRRequest rq) { + + rq.sendSuccess((ServiceSet) result); + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/GetServiceByUuidOperation.java b/java/servers/src/org/xtreemfs/dir/operations/GetServiceByUuidOperation.java new file mode 100644 index 0000000..a9a95ce --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/GetServiceByUuidOperation.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.dir.data.ServiceRecord; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class GetServiceByUuidOperation extends DIROperation { + + private final Database database; + + public GetServiceByUuidOperation(DIRRequestDispatcher master) throws BabuDBException { + super(master); + database = master.getDirDatabase(); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_SERVICE_GET_BY_UUID; + } + + @Override + public void startRequest(DIRRequest rq) { + serviceGetByUUIDRequest request = (serviceGetByUUIDRequest) rq.getRequestMessage(); + + database.lookup(DIRRequestDispatcher.INDEX_ID_SERVREG, request.getName().getBytes(), rq).registerListener( + new DBRequestListener(true) { + + @Override + ServiceSet execute(byte[] result, DIRRequest rq) throws Exception { + + ServiceSet.Builder services = ServiceSet.newBuilder(); + if (result != null) { + ServiceRecord dbData = new ServiceRecord(ReusableBuffer.wrap(result)); + services.addServices(dbData.getService()); + } + return services.build(); + } + }); + } + + @Override + public boolean isAuthRequired() { + return false; + } + + @Override + protected Message getRequestMessagePrototype() { + return serviceGetByUUIDRequest.getDefaultInstance(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xtreemfs.dir.operations.DIROperation#requestFinished(java.lang.Object + * , org.xtreemfs.dir.DIRRequest) + */ + @Override + void requestFinished(Object result, DIRRequest rq) { + rq.sendSuccess((ServiceSet) result); + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/GetServicesByTypeOperation.java b/java/servers/src/org/xtreemfs/dir/operations/GetServicesByTypeOperation.java new file mode 100644 index 0000000..5cbf20e --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/GetServicesByTypeOperation.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import java.util.Map.Entry; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.ResultSet; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.dir.data.ServiceRecord; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class GetServicesByTypeOperation extends DIROperation { + + private final Database database; + + public GetServicesByTypeOperation(DIRRequestDispatcher master) throws BabuDBException { + super(master); + database = master.getDirDatabase(); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_SERVICE_GET_BY_TYPE; + } + + @Override + public void startRequest(DIRRequest rq) { + final serviceGetByTypeRequest request = (serviceGetByTypeRequest) rq.getRequestMessage(); + + database.prefixLookup(DIRRequestDispatcher.INDEX_ID_SERVREG, new byte[0], rq).registerListener( + new DBRequestListener, ServiceSet>(true) { + + @Override + ServiceSet execute(ResultSet result, DIRRequest rq) throws Exception { + + ServiceSet.Builder services = ServiceSet.newBuilder(); + long now = System.currentTimeMillis() / 1000l; + + while (result.hasNext()) { + Entry e = result.next(); + ServiceRecord servEntry = new ServiceRecord(ReusableBuffer.wrap(e.getValue())); + + if ((request.getType() == ServiceType.SERVICE_TYPE_MIXED) + || (servEntry.getType() == request.getType())) { + long secondsSinceLastUpdate = now - servEntry.getLast_updated_s(); + servEntry.getData().put("seconds_since_last_update", + Long.toString(secondsSinceLastUpdate)); + services.addServices(servEntry.getService()); + } + + } + return services.build(); + } + }); + } + + @Override + public boolean isAuthRequired() { + return false; + } + + @Override + protected Message getRequestMessagePrototype() { + return serviceGetByTypeRequest.getDefaultInstance(); + } + + /* + * (non-Javadoc) + * + * @see + * org.xtreemfs.dir.operations.DIROperation#requestFinished(java.lang.Object + * , org.xtreemfs.dir.DIRRequest) + */ + @Override + void requestFinished(Object result, DIRRequest rq) { + rq.sendSuccess((ServiceSet) result); + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/RegisterServiceOperation.java b/java/servers/src/org/xtreemfs/dir/operations/RegisterServiceOperation.java new file mode 100644 index 0000000..99de226 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/RegisterServiceOperation.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import java.util.ConcurrentModificationException; +import java.util.Map; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.common.HeartbeatThread; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.dir.data.ServiceRecord; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class RegisterServiceOperation extends DIROperation { + + private final Database database; + + public RegisterServiceOperation(DIRRequestDispatcher master) throws BabuDBException { + super(master); + database = master.getDirDatabase(); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_SERVICE_REGISTER; + } + + @Override + public void startRequest(DIRRequest rq) { + final serviceRegisterRequest request = (serviceRegisterRequest) rq.getRequestMessage(); + + final Service.Builder reg = request.getService().toBuilder(); + + database.lookup(DIRRequestDispatcher.INDEX_ID_SERVREG, reg.getUuid().getBytes(), rq) + .registerListener(new DBRequestListener(false) { + + @Override + Long execute(byte[] result, DIRRequest rq) throws Exception { + long currentVersion = 0; + ServiceRecord sRec = new ServiceRecord(request.getService().toBuilder().build()); + + // If this request comes from a tool like xtfs_chstatus, this value will be set to + // "true" and the last updated time must not be set to the current time. If it does + // not exist, it will be set to false. + boolean doNotSetLastUpdated = Boolean.parseBoolean(sRec.getData().get( + HeartbeatThread.DO_NOT_SET_LAST_UPDATED)); + + if (result != null) { + ReusableBuffer buf = ReusableBuffer.wrap(result); + ServiceRecord dbData = new ServiceRecord(buf); + currentVersion = dbData.getVersion(); + } else { + // The registered service wasn't registered before. + // Collect data from the request and inform all + // listeners about this registration + String uuid, name, type, pageUrl, geoCoordinates; + long totalRam, usedRam, lastUpdated; + int status, load, protoVersion; + + uuid = sRec.getUuid(); + name = sRec.getName(); + type = sRec.getType().toString(); + + pageUrl = sRec.getData().get("status_page_url") == null ? "" : sRec.getData() + .get("status_page_url"); + geoCoordinates = sRec.getData().get("vivaldi_coordinates") == null ? "" : sRec + .getData().get("vivaldi_coordinates"); + try { + totalRam = Long.parseLong(sRec.getData().get("totalRAM")); + } catch (NumberFormatException nfe) { + totalRam = -1; + } + try { + usedRam = Long.parseLong(sRec.getData().get("usedRAM")); + } catch (NumberFormatException nfe) { + usedRam = -1; + } + lastUpdated = System.currentTimeMillis() / 1000l; + try { + status = Integer.parseInt(sRec.getData().get(HeartbeatThread.STATUS_ATTR)); + } catch (NumberFormatException nfe) { + status = -1; + } + try { + load = Integer.parseInt(sRec.getData().get("load")); + } catch (NumberFormatException nfe) { + load = -1; + } + try { + protoVersion = Integer.parseInt(sRec.getData().get("proto_version")); + } catch (NumberFormatException nfe) { + protoVersion = -1; + } + + master.notifyServiceRegistred(uuid, name, type, pageUrl, geoCoordinates, + totalRam, usedRam, lastUpdated, status, load, protoVersion); + } + + if (reg.getVersion() != currentVersion) { + throw new ConcurrentModificationException("The requested version number (" + + reg.getVersion() + ") did not match the " + "expected version (" + + currentVersion + ")!"); + } + + final long version = ++currentVersion; + + reg.setVersion(currentVersion); + if (!doNotSetLastUpdated) { + reg.setLastUpdatedS(System.currentTimeMillis() / 1000l); + } + + ServiceRecord newRec = new ServiceRecord(reg.build()); + + Map newRecData = newRec.getData(); + // Remove attributes which must not be stored. + newRecData.remove(HeartbeatThread.DO_NOT_SET_LAST_UPDATED); + newRec.setData(newRecData); + + byte[] newData = new byte[newRec.getSize()]; + newRec.serialize(ReusableBuffer.wrap(newData)); + database.singleInsert(DIRRequestDispatcher.INDEX_ID_SERVREG, + newRec.getUuid().getBytes(), newData, rq).registerListener( + new DBRequestListener(true) { + + @Override + Long execute(Object result, DIRRequest rq) throws Exception { + + return version; + } + }); + return null; + } + }); + } + + @Override + public boolean isAuthRequired() { + return false; + } + + @Override + protected Message getRequestMessagePrototype() { + return serviceRegisterRequest.getDefaultInstance(); + } + + @Override + void requestFinished(Object result, DIRRequest rq) { + serviceRegisterResponse resp = serviceRegisterResponse.newBuilder().setNewVersion((Long) result) + .build(); + rq.sendSuccess(resp); + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/ServiceOfflineOperation.java b/java/servers/src/org/xtreemfs/dir/operations/ServiceOfflineOperation.java new file mode 100644 index 0000000..6ea2509 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/ServiceOfflineOperation.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.dir.data.ServiceRecord; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class ServiceOfflineOperation extends DIROperation { + + private final Database database; + + public ServiceOfflineOperation(DIRRequestDispatcher master) throws BabuDBException { + super(master); + database = master.getDirDatabase(); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_SERVICE_OFFLINE; + } + + @Override + public void startRequest(DIRRequest rq) { + final serviceGetByUUIDRequest request = (serviceGetByUUIDRequest) rq.getRequestMessage(); + + database.lookup(DIRRequestDispatcher.INDEX_ID_SERVREG, request.getName().getBytes(), rq).registerListener( + new DBRequestListener(false) { + + @Override + Object execute(byte[] result, DIRRequest rq) throws Exception { + if (result != null) { + ReusableBuffer buf = ReusableBuffer.wrap(result); + ServiceRecord dbData = new ServiceRecord(buf); + + dbData.setLast_updated_s(0); + dbData.setVersion(dbData.getVersion() + 1); + + byte[] newData = new byte[dbData.getSize()]; + dbData.serialize(ReusableBuffer.wrap(newData)); + database.singleInsert(DIRRequestDispatcher.INDEX_ID_SERVREG, request.getName().getBytes(), + newData, rq).registerListener(new DBRequestListener(true) { + + @Override + Object execute(Object result, DIRRequest rq) throws Exception { + return null; + } + }); + } else + requestFinished(null, rq); + + return null; + } + }); + } + + @Override + public boolean isAuthRequired() { + return false; + } + + @Override + protected Message getRequestMessagePrototype() { + return serviceGetByUUIDRequest.getDefaultInstance(); + } + + @Override + void requestFinished(Object result, DIRRequest rq) { + rq.sendSuccess(emptyResponse.getDefaultInstance()); + } +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/SetAddressMappingOperation.java b/java/servers/src/org/xtreemfs/dir/operations/SetAddressMappingOperation.java new file mode 100644 index 0000000..e67caf8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/SetAddressMappingOperation.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import java.util.ConcurrentModificationException; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.dir.data.AddressMappingRecord; +import org.xtreemfs.dir.data.AddressMappingRecords; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class SetAddressMappingOperation extends DIROperation { + + private final Database database; + + public SetAddressMappingOperation(DIRRequestDispatcher master) throws BabuDBException { + super(master); + database = master.getDirDatabase(); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_ADDRESS_MAPPINGS_SET; + } + + @Override + public void startRequest(DIRRequest rq) { + + final AddressMappingSet mappings = (AddressMappingSet) rq.getRequestMessage(); + String uuid = null; + if (mappings.getMappingsCount() == 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "non-empty address mapping set not allowed"); + return; + } + for (AddressMapping am : mappings.getMappingsList()) { + if (uuid == null) + uuid = am.getUuid(); + if (!am.getUuid().equals(uuid)) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "all mappings must have the same UUID"); + return; + } + } + + assert (uuid != null); + assert (database != null); + + final String UUID = uuid; + + database.lookup(DIRRequestDispatcher.INDEX_ID_ADDRMAPS, uuid.getBytes(), rq).registerListener( + new DBRequestListener(false) { + + @Override + Long execute(byte[] result, DIRRequest rq) throws Exception { + long currentVersion = 0; + if (result != null) { + ReusableBuffer buf = ReusableBuffer.wrap(result); + AddressMappingRecords dbData = new AddressMappingRecords(buf); + if (dbData.size() > 0) { + currentVersion = dbData.getRecord(0).getVersion(); + } + } + + if (mappings.getMappings(0).getVersion() != currentVersion) + throw new ConcurrentModificationException(); + + final long version = ++currentVersion; + + AddressMappingSet.Builder newSet = mappings.toBuilder(); + for (int i = 0; i < mappings.getMappingsCount(); i++) { + newSet.setMappings(i, mappings.getMappings(i).toBuilder().setVersion(currentVersion)); + } + + AddressMappingRecords newData = new AddressMappingRecords(newSet.build()); + final int size = newData.getSize(); + byte[] newBytes = new byte[size]; + ReusableBuffer buf = ReusableBuffer.wrap(newBytes); + newData.serialize(buf); + database.singleInsert(DIRRequestDispatcher.INDEX_ID_ADDRMAPS, UUID.getBytes(), newBytes, rq) + .registerListener(new DBRequestListener(true) { + + @Override + Long execute(Object result, DIRRequest rq) throws Exception { + return version; + } + }); + + // notify all listeners about the insert + for (AddressMappingRecord amr : newData.getRecords()) { + master.notifyAddressMappingAdded(amr.getUuid(), amr.getUri()); + } + + return null; + } + }); + } + + @Override + public boolean isAuthRequired() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + protected Message getRequestMessagePrototype() { + return AddressMappingSet.getDefaultInstance(); + } + + @Override + void requestFinished(Object result, DIRRequest rq) { + addressMappingSetResponse resp = addressMappingSetResponse.newBuilder().setNewVersion((Long) result).build(); + rq.sendSuccess(resp); + } +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/SetConfigurationOperation.java b/java/servers/src/org/xtreemfs/dir/operations/SetConfigurationOperation.java new file mode 100644 index 0000000..d7af9e0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/SetConfigurationOperation.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import java.util.ConcurrentModificationException; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.dir.data.ConfigurationRecord; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; + +import com.google.protobuf.Message; + +public class SetConfigurationOperation extends DIROperation { + + private final Database database; + + public SetConfigurationOperation(DIRRequestDispatcher master) throws BabuDBException { + super(master); + database = master.getDirDatabase(); + + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_CONFIGURATION_SET; + } + + @Override + protected Message getRequestMessagePrototype() { + + return Configuration.getDefaultInstance(); + } + + @Override + public boolean isAuthRequired() { + throw new UnsupportedOperationException("Not supported yet."); + + } + + @Override + void requestFinished(Object result, DIRRequest rq) { + + configurationSetResponse response = configurationSetResponse.newBuilder().setNewVersion((Long) result).build(); + rq.sendSuccess(response); + } + + @Override + public void startRequest(DIRRequest rq) { + + final Configuration conf = (Configuration) rq.getRequestMessage(); + + String uuid = null; + + if (conf.getParameterCount() == 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "empty configuration set not allowed"); + return; + } + + uuid = conf.getUuid(); + + assert (uuid != null); + assert (database != null); + + final String UUID = uuid; + + database.lookup(DIRRequestDispatcher.INDEX_ID_CONFIGURATIONS, uuid.getBytes(), rq).registerListener( + new DBRequestListener(false) { + @Override + Long execute(byte[] result, DIRRequest rq) throws Exception { + + long currentVersion = 0; + if (result != null) { + ReusableBuffer buf = ReusableBuffer.wrap(result); + ConfigurationRecord dbData = new ConfigurationRecord(buf); + currentVersion = dbData.getVersion(); + + } + + if (conf.getVersion() != currentVersion) { + throw new ConcurrentModificationException(); + } + + final long version = ++currentVersion; + + ConfigurationRecord newRec = new ConfigurationRecord(conf); + newRec.setVersion(version); + + final int size = newRec.getSize(); + byte[] newBytes = new byte[size]; + ReusableBuffer buf = ReusableBuffer.wrap(newBytes); + newRec.serialize(buf); + + database.singleInsert(DIRRequestDispatcher.INDEX_ID_CONFIGURATIONS, UUID.getBytes(), newBytes, + rq).registerListener(new DBRequestListener(true) { + + @Override + Long execute(Object result, DIRRequest rq) throws Exception { + return version; + } + }); + + return null; + + } + + }); + + // + // database.lookup(DIRRequestDispatcher.INDEX_ID_CONFIGURATIONS, + // uuid.getBytes(), rq).registerListener( + // new DBRequestListener(true) { + // + // @Override + // Configuration execute(byte[] result, DIRRequest rq) throws Exception + // { + // + // if (result == null) { + // return Configuration.getDefaultInstance(); + // } else + // return new + // ConfigurationRecord(ReusableBuffer.wrap(result)).getConfiguration(); + // } + // }); + + } + +} diff --git a/java/servers/src/org/xtreemfs/dir/operations/UpdateVivaldiClientOperation.java b/java/servers/src/org/xtreemfs/dir/operations/UpdateVivaldiClientOperation.java new file mode 100644 index 0000000..0fa194b --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/operations/UpdateVivaldiClientOperation.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 by Matthias Noack, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.dir.operations; + +import java.net.InetSocketAddress; + +import org.xtreemfs.dir.DIRRequest; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.dir.VivaldiClientMap; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +import com.google.protobuf.Message; + +public class UpdateVivaldiClientOperation extends DIROperation { + + + //private HashMap vivaldiClientMap; + private VivaldiClientMap vivaldiClientMap; + + public UpdateVivaldiClientOperation(DIRRequestDispatcher master) { + super(master); + vivaldiClientMap = master.getVivaldiClientMap(); + } + + @Override + public int getProcedureId() { + return DIRServiceConstants.PROC_ID_XTREEMFS_VIVALDI_CLIENT_UPDATE; + } + + @Override + public void startRequest(DIRRequest rq) { + VivaldiCoordinates coords = (VivaldiCoordinates) rq.getRequestMessage(); + InetSocketAddress clientAddress = (InetSocketAddress)rq.getRPCRequest().getSenderAddress(); + vivaldiClientMap.put(clientAddress, coords); + //vivaldiClientMap.filterTimeOuts(); + // send response + rq.sendSuccess(emptyResponse.getDefaultInstance()); + } + + @Override + public boolean isAuthRequired() { + return false; + } + + @Override + protected Message getRequestMessagePrototype() { + return VivaldiCoordinates.getDefaultInstance(); + } + + @Override + void requestFinished(Object result, DIRRequest rq) { + // NOTE(mno): this method is not called, a response is sent directly in startRequest + //rq.sendSuccess(emptyResponse.getDefaultInstance()); + } +} diff --git a/java/servers/src/org/xtreemfs/dir/templates/d3.js b/java/servers/src/org/xtreemfs/dir/templates/d3.js new file mode 100644 index 0000000..237e327 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/templates/d3.js @@ -0,0 +1,4762 @@ +(function(){if (!Date.now) Date.now = function() { + return +new Date; +}; +try { + document.createElement("div").style.setProperty("opacity", 0, ""); +} catch (error) { + var d3_style_prototype = CSSStyleDeclaration.prototype, + d3_style_setProperty = d3_style_prototype.setProperty; + d3_style_prototype.setProperty = function(name, value, priority) { + d3_style_setProperty.call(this, name, value + "", priority); + }; +} +d3 = {version: "2.7.4"}; // semver +var d3_array = d3_arraySlice; // conversion for NodeLists + +function d3_arrayCopy(pseudoarray) { + var i = -1, n = pseudoarray.length, array = []; + while (++i < n) array.push(pseudoarray[i]); + return array; +} + +function d3_arraySlice(pseudoarray) { + return Array.prototype.slice.call(pseudoarray); +} + +try { + d3_array(document.documentElement.childNodes)[0].nodeType; +} catch(e) { + d3_array = d3_arrayCopy; +} + +var d3_arraySubclass = [].__proto__? + +// Until ECMAScript supports array subclassing, prototype injection works well. +function(array, prototype) { + array.__proto__ = prototype; +}: + +// And if your browser doesn't support __proto__, we'll use direct extension. +function(array, prototype) { + for (var property in prototype) array[property] = prototype[property]; +}; +function d3_this() { + return this; +} +d3.functor = function(v) { + return typeof v === "function" ? v : function() { return v; }; +}; +// Copies a variable number of methods from source to target. +d3.rebind = function(target, source) { + var i = 1, n = arguments.length, method; + while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); + return target; +}; + +// Method is assumed to be a standard D3 getter-setter: +// If passed with no arguments, gets the value. +// If passed with arguments, sets the value and returns the target. +function d3_rebind(target, source, method) { + return function() { + var value = method.apply(source, arguments); + return arguments.length ? target : value; + }; +} +d3.ascending = function(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; +}; +d3.descending = function(a, b) { + return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; +}; +d3.mean = function(array, f) { + var n = array.length, + a, + m = 0, + i = -1, + j = 0; + if (arguments.length === 1) { + while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j; + } else { + while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j; + } + return j ? m : undefined; +}; +d3.median = function(array, f) { + if (arguments.length > 1) array = array.map(f); + array = array.filter(d3_number); + return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined; +}; +d3.min = function(array, f) { + var i = -1, + n = array.length, + a, + b; + if (arguments.length === 1) { + while (++i < n && ((a = array[i]) == null || a != a)) a = undefined; + while (++i < n) if ((b = array[i]) != null && a > b) a = b; + } else { + while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined; + while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; + } + return a; +}; +d3.max = function(array, f) { + var i = -1, + n = array.length, + a, + b; + if (arguments.length === 1) { + while (++i < n && ((a = array[i]) == null || a != a)) a = undefined; + while (++i < n) if ((b = array[i]) != null && b > a) a = b; + } else { + while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined; + while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; + } + return a; +}; +d3.extent = function(array, f) { + var i = -1, + n = array.length, + a, + b, + c; + if (arguments.length === 1) { + while (++i < n && ((a = c = array[i]) == null || a != a)) a = c = undefined; + while (++i < n) if ((b = array[i]) != null) { + if (a > b) a = b; + if (c < b) c = b; + } + } else { + while (++i < n && ((a = c = f.call(array, array[i], i)) == null || a != a)) a = undefined; + while (++i < n) if ((b = f.call(array, array[i], i)) != null) { + if (a > b) a = b; + if (c < b) c = b; + } + } + return [a, c]; +}; +d3.random = { + normal: function(mean, deviation) { + if (arguments.length < 2) deviation = 1; + if (arguments.length < 1) mean = 0; + return function() { + var x, y, r; + do { + x = Math.random() * 2 - 1; + y = Math.random() * 2 - 1; + r = x * x + y * y; + } while (!r || r > 1); + return mean + deviation * x * Math.sqrt(-2 * Math.log(r) / r); + }; + } +}; +function d3_number(x) { + return x != null && !isNaN(x); +} +d3.sum = function(array, f) { + var s = 0, + n = array.length, + a, + i = -1; + + if (arguments.length === 1) { + while (++i < n) if (!isNaN(a = +array[i])) s += a; + } else { + while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a; + } + + return s; +}; +// R-7 per +d3.quantile = function(values, p) { + var H = (values.length - 1) * p + 1, + h = Math.floor(H), + v = values[h - 1], + e = H - h; + return e ? v + e * (values[h] - v) : v; +}; +d3.transpose = function(matrix) { + return d3.zip.apply(d3, matrix); +}; +d3.zip = function() { + if (!(n = arguments.length)) return []; + for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m;) { + for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n;) { + zip[j] = arguments[j][i]; + } + } + return zips; +}; + +function d3_zipLength(d) { + return d.length; +} +// Locate the insertion point for x in a to maintain sorted order. The +// arguments lo and hi may be used to specify a subset of the array which should +// be considered; by default the entire array is used. If x is already present +// in a, the insertion point will be before (to the left of) any existing +// entries. The return value is suitable for use as the first argument to +// `array.splice` assuming that a is already sorted. +// +// The returned insertion point i partitions the array a into two halves so that +// all v < x for v in a[lo:i] for the left side and all v >= x for v in a[i:hi] +// for the right side. +d3.bisectLeft = function(a, x, lo, hi) { + if (arguments.length < 3) lo = 0; + if (arguments.length < 4) hi = a.length; + while (lo < hi) { + var mid = (lo + hi) >> 1; + if (a[mid] < x) lo = mid + 1; + else hi = mid; + } + return lo; +}; + +// Similar to bisectLeft, but returns an insertion point which comes after (to +// the right of) any existing entries of x in a. +// +// The returned insertion point i partitions the array into two halves so that +// all v <= x for v in a[lo:i] for the left side and all v > x for v in a[i:hi] +// for the right side. +d3.bisect = +d3.bisectRight = function(a, x, lo, hi) { + if (arguments.length < 3) lo = 0; + if (arguments.length < 4) hi = a.length; + while (lo < hi) { + var mid = (lo + hi) >> 1; + if (x < a[mid]) hi = mid; + else lo = mid + 1; + } + return lo; +}; +d3.first = function(array, f) { + var i = 0, + n = array.length, + a = array[0], + b; + if (arguments.length === 1) f = d3.ascending; + while (++i < n) { + if (f.call(array, a, b = array[i]) > 0) { + a = b; + } + } + return a; +}; +d3.last = function(array, f) { + var i = 0, + n = array.length, + a = array[0], + b; + if (arguments.length === 1) f = d3.ascending; + while (++i < n) { + if (f.call(array, a, b = array[i]) <= 0) { + a = b; + } + } + return a; +}; +d3.nest = function() { + var nest = {}, + keys = [], + sortKeys = [], + sortValues, + rollup; + + function map(array, depth) { + if (depth >= keys.length) return rollup + ? rollup.call(nest, array) : (sortValues + ? array.sort(sortValues) + : array); + + var i = -1, + n = array.length, + key = keys[depth++], + keyValue, + object, + o = {}; + + while (++i < n) { + if ((keyValue = key(object = array[i])) in o) { + o[keyValue].push(object); + } else { + o[keyValue] = [object]; + } + } + + for (keyValue in o) { + o[keyValue] = map(o[keyValue], depth); + } + + return o; + } + + function entries(map, depth) { + if (depth >= keys.length) return map; + + var a = [], + sortKey = sortKeys[depth++], + key; + + for (key in map) { + a.push({key: key, values: entries(map[key], depth)}); + } + + if (sortKey) a.sort(function(a, b) { + return sortKey(a.key, b.key); + }); + + return a; + } + + nest.map = function(array) { + return map(array, 0); + }; + + nest.entries = function(array) { + return entries(map(array, 0), 0); + }; + + nest.key = function(d) { + keys.push(d); + return nest; + }; + + // Specifies the order for the most-recently specified key. + // Note: only applies to entries. Map keys are unordered! + nest.sortKeys = function(order) { + sortKeys[keys.length - 1] = order; + return nest; + }; + + // Specifies the order for leaf values. + // Applies to both maps and entries array. + nest.sortValues = function(order) { + sortValues = order; + return nest; + }; + + nest.rollup = function(f) { + rollup = f; + return nest; + }; + + return nest; +}; +d3.keys = function(map) { + var keys = []; + for (var key in map) keys.push(key); + return keys; +}; +d3.values = function(map) { + var values = []; + for (var key in map) values.push(map[key]); + return values; +}; +d3.entries = function(map) { + var entries = []; + for (var key in map) entries.push({key: key, value: map[key]}); + return entries; +}; +d3.permute = function(array, indexes) { + var permutes = [], + i = -1, + n = indexes.length; + while (++i < n) permutes[i] = array[indexes[i]]; + return permutes; +}; +d3.merge = function(arrays) { + return Array.prototype.concat.apply([], arrays); +}; +d3.split = function(array, f) { + var arrays = [], + values = [], + value, + i = -1, + n = array.length; + if (arguments.length < 2) f = d3_splitter; + while (++i < n) { + if (f.call(values, value = array[i], i)) { + values = []; + } else { + if (!values.length) arrays.push(values); + values.push(value); + } + } + return arrays; +}; + +function d3_splitter(d) { + return d == null; +} +function d3_collapse(s) { + return s.replace(/(^\s+)|(\s+$)/g, "").replace(/\s+/g, " "); +} +/** + * @param {number} start + * @param {number=} stop + * @param {number=} step + */ +d3.range = function(start, stop, step) { + if (arguments.length < 3) { + step = 1; + if (arguments.length < 2) { + stop = start; + start = 0; + } + } + if ((stop - start) / step == Infinity) throw new Error("infinite range"); + var range = [], + i = -1, + j; + if (step < 0) while ((j = start + step * ++i) > stop) range.push(j); + else while ((j = start + step * ++i) < stop) range.push(j); + return range; +}; +d3.requote = function(s) { + return s.replace(d3_requote_re, "\\$&"); +}; + +var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; +d3.round = function(x, n) { + return n + ? Math.round(x * (n = Math.pow(10, n))) / n + : Math.round(x); +}; +d3.xhr = function(url, mime, callback) { + var req = new XMLHttpRequest; + if (arguments.length < 3) callback = mime, mime = null; + else if (mime && req.overrideMimeType) req.overrideMimeType(mime); + req.open("GET", url, true); + if (mime) req.setRequestHeader("Accept", mime); + req.onreadystatechange = function() { + if (req.readyState === 4) callback(req.status < 300 ? req : null); + }; + req.send(null); +}; +d3.text = function(url, mime, callback) { + function ready(req) { + callback(req && req.responseText); + } + if (arguments.length < 3) { + callback = mime; + mime = null; + } + d3.xhr(url, mime, ready); +}; +d3.json = function(url, callback) { + d3.text(url, "application/json", function(text) { + callback(text ? JSON.parse(text) : null); + }); +}; +d3.html = function(url, callback) { + d3.text(url, "text/html", function(text) { + if (text != null) { // Treat empty string as valid HTML. + var range = document.createRange(); + range.selectNode(document.body); + text = range.createContextualFragment(text); + } + callback(text); + }); +}; +d3.xml = function(url, mime, callback) { + function ready(req) { + callback(req && req.responseXML); + } + if (arguments.length < 3) { + callback = mime; + mime = null; + } + d3.xhr(url, mime, ready); +}; +var d3_nsPrefix = { + svg: "http://www.w3.org/2000/svg", + xhtml: "http://www.w3.org/1999/xhtml", + xlink: "http://www.w3.org/1999/xlink", + xml: "http://www.w3.org/XML/1998/namespace", + xmlns: "http://www.w3.org/2000/xmlns/" +}; + +d3.ns = { + prefix: d3_nsPrefix, + qualify: function(name) { + var i = name.indexOf(":"); + return i < 0 ? (name in d3_nsPrefix + ? {space: d3_nsPrefix[name], local: name} : name) + : {space: d3_nsPrefix[name.substring(0, i)], local: name.substring(i + 1)}; + } +}; +d3.dispatch = function() { + var dispatch = new d3_dispatch(), + i = -1, + n = arguments.length; + while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); + return dispatch; +}; + +function d3_dispatch() {} + +d3_dispatch.prototype.on = function(type, listener) { + var i = type.indexOf("."), + name = ""; + + // Extract optional namespace, e.g., "click.foo" + if (i > 0) { + name = type.substring(i + 1); + type = type.substring(0, i); + } + + return arguments.length < 2 + ? this[type].on(name) + : this[type].on(name, listener); +}; + +function d3_dispatch_event(dispatch) { + var listeners = [], + listenerByName = {}; + + function event() { + var z = listeners, // defensive reference + i = -1, + n = z.length, + l; + while (++i < n) if (l = z[i].on) l.apply(this, arguments); + return dispatch; + } + + event.on = function(name, listener) { + var l, i; + + // return the current listener, if any + if (arguments.length < 2) return (l = listenerByName[name]) && l.on; + + // remove the old listener, if any (with copy-on-write) + if (l = listenerByName[name]) { + l.on = null; + listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); + delete listenerByName[name]; + } + + // add the new listener, if any + if (listener) { + listeners.push(listenerByName[name] = {on: listener}); + } + + return dispatch; + }; + + return event; +}; +// TODO align +d3.format = function(specifier) { + var match = d3_format_re.exec(specifier), + fill = match[1] || " ", + sign = match[3] || "", + zfill = match[5], + width = +match[6], + comma = match[7], + precision = match[8], + type = match[9], + scale = 1, + suffix = "", + integer = false; + + if (precision) precision = +precision.substring(1); + + if (zfill) { + fill = "0"; // TODO align = "="; + if (comma) width -= Math.floor((width - 1) / 4); + } + + switch (type) { + case "n": comma = true; type = "g"; break; + case "%": scale = 100; suffix = "%"; type = "f"; break; + case "p": scale = 100; suffix = "%"; type = "r"; break; + case "d": integer = true; precision = 0; break; + case "s": scale = -1; type = "r"; break; + } + + // If no precision is specified for r, fallback to general notation. + if (type == "r" && !precision) type = "g"; + + type = d3_format_types[type] || d3_format_typeDefault; + + return function(value) { + + // Return the empty string for floats formatted as ints. + if (integer && (value % 1)) return ""; + + // Convert negative to positive, and record the sign prefix. + var negative = (value < 0) && (value = -value) ? "\u2212" : sign; + + // Apply the scale, computing it from the value's exponent for si format. + if (scale < 0) { + var prefix = d3.formatPrefix(value, precision); + value *= prefix.scale; + suffix = prefix.symbol; + } else { + value *= scale; + } + + // Convert to the desired precision. + value = type(value, precision); + + // If the fill character is 0, the sign and group is applied after the fill. + if (zfill) { + var length = value.length + negative.length; + if (length < width) value = new Array(width - length + 1).join(fill) + value; + if (comma) value = d3_format_group(value); + value = negative + value; + } + + // Otherwise (e.g., space-filling), the sign and group is applied before. + else { + if (comma) value = d3_format_group(value); + value = negative + value; + var length = value.length; + if (length < width) value = new Array(width - length + 1).join(fill) + value; + } + + return value + suffix; + }; +}; + +// [[fill]align][sign][#][0][width][,][.precision][type] +var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/; + +var d3_format_types = { + g: function(x, p) { return x.toPrecision(p); }, + e: function(x, p) { return x.toExponential(p); }, + f: function(x, p) { return x.toFixed(p); }, + r: function(x, p) { return d3.round(x, p = d3_format_precision(x, p)).toFixed(Math.max(0, Math.min(20, p))); } +}; + +function d3_format_precision(x, p) { + return p - (x ? 1 + Math.floor(Math.log(x + Math.pow(10, 1 + Math.floor(Math.log(x) / Math.LN10) - p)) / Math.LN10) : 1); +} + +function d3_format_typeDefault(x) { + return x + ""; +} + +// Apply comma grouping for thousands. +function d3_format_group(value) { + var i = value.lastIndexOf("."), + f = i >= 0 ? value.substring(i) : (i = value.length, ""), + t = []; + while (i > 0) t.push(value.substring(i -= 3, i + 3)); + return t.reverse().join(",") + f; +} +var d3_formatPrefixes = ["y","z","a","f","p","n","μ","m","","k","M","G","T","P","E","Z","Y"].map(d3_formatPrefix); + +d3.formatPrefix = function(value, precision) { + var i = 0; + if (value) { + if (value < 0) value *= -1; + if (precision) value = d3.round(value, d3_format_precision(value, precision)); + i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); + i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3)); + } + return d3_formatPrefixes[8 + i / 3]; +}; + +function d3_formatPrefix(d, i) { + return { + scale: Math.pow(10, (8 - i) * 3), + symbol: d + }; +} + +/* + * TERMS OF USE - EASING EQUATIONS + * + * Open source under the BSD License. + * + * Copyright 2001 Robert Penner + * All rights reserved. + * + * 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 the author nor the names of 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. + */ + +var d3_ease_quad = d3_ease_poly(2), + d3_ease_cubic = d3_ease_poly(3); + +var d3_ease = { + linear: function() { return d3_ease_linear; }, + poly: d3_ease_poly, + quad: function() { return d3_ease_quad; }, + cubic: function() { return d3_ease_cubic; }, + sin: function() { return d3_ease_sin; }, + exp: function() { return d3_ease_exp; }, + circle: function() { return d3_ease_circle; }, + elastic: d3_ease_elastic, + back: d3_ease_back, + bounce: function() { return d3_ease_bounce; } +}; + +var d3_ease_mode = { + "in": function(f) { return f; }, + "out": d3_ease_reverse, + "in-out": d3_ease_reflect, + "out-in": function(f) { return d3_ease_reflect(d3_ease_reverse(f)); } +}; + +d3.ease = function(name) { + var i = name.indexOf("-"), + t = i >= 0 ? name.substring(0, i) : name, + m = i >= 0 ? name.substring(i + 1) : "in"; + return d3_ease_clamp(d3_ease_mode[m](d3_ease[t].apply(null, Array.prototype.slice.call(arguments, 1)))); +}; + +function d3_ease_clamp(f) { + return function(t) { + return t <= 0 ? 0 : t >= 1 ? 1 : f(t); + }; +} + +function d3_ease_reverse(f) { + return function(t) { + return 1 - f(1 - t); + }; +} + +function d3_ease_reflect(f) { + return function(t) { + return .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t))); + }; +} + +function d3_ease_linear(t) { + return t; +} + +function d3_ease_poly(e) { + return function(t) { + return Math.pow(t, e); + } +} + +function d3_ease_sin(t) { + return 1 - Math.cos(t * Math.PI / 2); +} + +function d3_ease_exp(t) { + return Math.pow(2, 10 * (t - 1)); +} + +function d3_ease_circle(t) { + return 1 - Math.sqrt(1 - t * t); +} + +function d3_ease_elastic(a, p) { + var s; + if (arguments.length < 2) p = 0.45; + if (arguments.length < 1) { a = 1; s = p / 4; } + else s = p / (2 * Math.PI) * Math.asin(1 / a); + return function(t) { + return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * Math.PI / p); + }; +} + +function d3_ease_back(s) { + if (!s) s = 1.70158; + return function(t) { + return t * t * ((s + 1) * t - s); + }; +} + +function d3_ease_bounce(t) { + return t < 1 / 2.75 ? 7.5625 * t * t + : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 + : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 + : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; +} +d3.event = null; + +function d3_eventCancel() { + d3.event.stopPropagation(); + d3.event.preventDefault(); +} +d3.interpolate = function(a, b) { + var i = d3.interpolators.length, f; + while (--i >= 0 && !(f = d3.interpolators[i](a, b))); + return f; +}; + +d3.interpolateNumber = function(a, b) { + b -= a; + return function(t) { return a + b * t; }; +}; + +d3.interpolateRound = function(a, b) { + b -= a; + return function(t) { return Math.round(a + b * t); }; +}; + +d3.interpolateString = function(a, b) { + var m, // current match + i, // current index + j, // current index (for coallescing) + s0 = 0, // start index of current string prefix + s1 = 0, // end index of current string prefix + s = [], // string constants and placeholders + q = [], // number interpolators + n, // q.length + o; + + // Reset our regular expression! + d3_interpolate_number.lastIndex = 0; + + // Find all numbers in b. + for (i = 0; m = d3_interpolate_number.exec(b); ++i) { + if (m.index) s.push(b.substring(s0, s1 = m.index)); + q.push({i: s.length, x: m[0]}); + s.push(null); + s0 = d3_interpolate_number.lastIndex; + } + if (s0 < b.length) s.push(b.substring(s0)); + + // Find all numbers in a. + for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) { + o = q[i]; + if (o.x == m[0]) { // The numbers match, so coallesce. + if (o.i) { + if (s[o.i + 1] == null) { // This match is followed by another number. + s[o.i - 1] += o.x; + s.splice(o.i, 1); + for (j = i + 1; j < n; ++j) q[j].i--; + } else { // This match is followed by a string, so coallesce twice. + s[o.i - 1] += o.x + s[o.i + 1]; + s.splice(o.i, 2); + for (j = i + 1; j < n; ++j) q[j].i -= 2; + } + } else { + if (s[o.i + 1] == null) { // This match is followed by another number. + s[o.i] = o.x; + } else { // This match is followed by a string, so coallesce twice. + s[o.i] = o.x + s[o.i + 1]; + s.splice(o.i + 1, 1); + for (j = i + 1; j < n; ++j) q[j].i--; + } + } + q.splice(i, 1); + n--; + i--; + } else { + o.x = d3.interpolateNumber(parseFloat(m[0]), parseFloat(o.x)); + } + } + + // Remove any numbers in b not found in a. + while (i < n) { + o = q.pop(); + if (s[o.i + 1] == null) { // This match is followed by another number. + s[o.i] = o.x; + } else { // This match is followed by a string, so coallesce twice. + s[o.i] = o.x + s[o.i + 1]; + s.splice(o.i + 1, 1); + } + n--; + } + + // Special optimization for only a single match. + if (s.length === 1) { + return s[0] == null ? q[0].x : function() { return b; }; + } + + // Otherwise, interpolate each of the numbers and rejoin the string. + return function(t) { + for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }; +}; + +d3.interpolateTransform = function(a, b) { + var s = [], // string constants and placeholders + q = [], // number interpolators + n, + A = d3.transform(a), + B = d3.transform(b), + ta = A.translate, + tb = B.translate, + ra = A.rotate, + rb = B.rotate, + wa = A.skew, + wb = B.skew, + ka = A.scale, + kb = B.scale; + + if (ta[0] != tb[0] || ta[1] != tb[1]) { + s.push("translate(", null, ",", null, ")"); + q.push({i: 1, x: d3.interpolateNumber(ta[0], tb[0])}, {i: 3, x: d3.interpolateNumber(ta[1], tb[1])}); + } else if (tb[0] || tb[1]) { + s.push("translate(" + tb + ")"); + } else { + s.push(""); + } + + if (ra != rb) { + q.push({i: s.push(s.pop() + "rotate(", null, ")") - 2, x: d3.interpolateNumber(ra, rb)}); + } else if (rb) { + s.push(s.pop() + "rotate(" + rb + ")"); + } + + if (wa != wb) { + q.push({i: s.push(s.pop() + "skewX(", null, ")") - 2, x: d3.interpolateNumber(wa, wb)}); + } else if (wb) { + s.push(s.pop() + "skewX(" + wb + ")"); + } + + if (ka[0] != kb[0] || ka[1] != kb[1]) { + n = s.push(s.pop() + "scale(", null, ",", null, ")"); + q.push({i: n - 4, x: d3.interpolateNumber(ka[0], kb[0])}, {i: n - 2, x: d3.interpolateNumber(ka[1], kb[1])}); + } else if (kb[0] != 1 || kb[1] != 1) { + s.push(s.pop() + "scale(" + kb + ")"); + } + + n = q.length; + return function(t) { + var i = -1, o; + while (++i < n) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }; +}; + +d3.interpolateRgb = function(a, b) { + a = d3.rgb(a); + b = d3.rgb(b); + var ar = a.r, + ag = a.g, + ab = a.b, + br = b.r - ar, + bg = b.g - ag, + bb = b.b - ab; + return function(t) { + return "#" + + d3_rgb_hex(Math.round(ar + br * t)) + + d3_rgb_hex(Math.round(ag + bg * t)) + + d3_rgb_hex(Math.round(ab + bb * t)); + }; +}; + +// interpolates HSL space, but outputs RGB string (for compatibility) +d3.interpolateHsl = function(a, b) { + a = d3.hsl(a); + b = d3.hsl(b); + var h0 = a.h, + s0 = a.s, + l0 = a.l, + h1 = b.h - h0, + s1 = b.s - s0, + l1 = b.l - l0; + return function(t) { + return d3_hsl_rgb(h0 + h1 * t, s0 + s1 * t, l0 + l1 * t).toString(); + }; +}; + +d3.interpolateArray = function(a, b) { + var x = [], + c = [], + na = a.length, + nb = b.length, + n0 = Math.min(a.length, b.length), + i; + for (i = 0; i < n0; ++i) x.push(d3.interpolate(a[i], b[i])); + for (; i < na; ++i) c[i] = a[i]; + for (; i < nb; ++i) c[i] = b[i]; + return function(t) { + for (i = 0; i < n0; ++i) c[i] = x[i](t); + return c; + }; +}; + +d3.interpolateObject = function(a, b) { + var i = {}, + c = {}, + k; + for (k in a) { + if (k in b) { + i[k] = d3_interpolateByName(k)(a[k], b[k]); + } else { + c[k] = a[k]; + } + } + for (k in b) { + if (!(k in a)) { + c[k] = b[k]; + } + } + return function(t) { + for (k in i) c[k] = i[k](t); + return c; + }; +} + +var d3_interpolate_number = /[-+]?(?:\d*\.?\d+)(?:[eE][-+]?\d+)?/g; + +function d3_interpolateByName(n) { + return n == "transform" + ? d3.interpolateTransform + : d3.interpolate; +} + +d3.interpolators = [ + d3.interpolateObject, + function(a, b) { return (b instanceof Array) && d3.interpolateArray(a, b); }, + function(a, b) { return (typeof a === "string" || typeof b === "string") && d3.interpolateString(a + "", b + ""); }, + function(a, b) { return (typeof b === "string" ? b in d3_rgb_names || /^(#|rgb\(|hsl\()/.test(b) : b instanceof d3_Rgb || b instanceof d3_Hsl) && d3.interpolateRgb(a, b); }, + function(a, b) { return !isNaN(a = +a) && !isNaN(b = +b) && d3.interpolateNumber(a, b); } +]; +function d3_uninterpolateNumber(a, b) { + b = b - (a = +a) ? 1 / (b - a) : 0; + return function(x) { return (x - a) * b; }; +} + +function d3_uninterpolateClamp(a, b) { + b = b - (a = +a) ? 1 / (b - a) : 0; + return function(x) { return Math.max(0, Math.min(1, (x - a) * b)); }; +} +d3.rgb = function(r, g, b) { + return arguments.length === 1 + ? (r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b) + : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb)) + : d3_rgb(~~r, ~~g, ~~b); +}; + +function d3_rgb(r, g, b) { + return new d3_Rgb(r, g, b); +} + +function d3_Rgb(r, g, b) { + this.r = r; + this.g = g; + this.b = b; +} + +d3_Rgb.prototype.brighter = function(k) { + k = Math.pow(0.7, arguments.length ? k : 1); + var r = this.r, + g = this.g, + b = this.b, + i = 30; + if (!r && !g && !b) return d3_rgb(i, i, i); + if (r && r < i) r = i; + if (g && g < i) g = i; + if (b && b < i) b = i; + return d3_rgb( + Math.min(255, Math.floor(r / k)), + Math.min(255, Math.floor(g / k)), + Math.min(255, Math.floor(b / k))); +}; + +d3_Rgb.prototype.darker = function(k) { + k = Math.pow(0.7, arguments.length ? k : 1); + return d3_rgb( + Math.floor(k * this.r), + Math.floor(k * this.g), + Math.floor(k * this.b)); +}; + +d3_Rgb.prototype.hsl = function() { + return d3_rgb_hsl(this.r, this.g, this.b); +}; + +d3_Rgb.prototype.toString = function() { + return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); +}; + +function d3_rgb_hex(v) { + return v < 0x10 + ? "0" + Math.max(0, v).toString(16) + : Math.min(255, v).toString(16); +} + +function d3_rgb_parse(format, rgb, hsl) { + var r = 0, // red channel; int in [0, 255] + g = 0, // green channel; int in [0, 255] + b = 0, // blue channel; int in [0, 255] + m1, // CSS color specification match + m2, // CSS color specification type (e.g., rgb) + name; + + /* Handle hsl, rgb. */ + m1 = /([a-z]+)\((.*)\)/i.exec(format); + if (m1) { + m2 = m1[2].split(","); + switch (m1[1]) { + case "hsl": { + return hsl( + parseFloat(m2[0]), // degrees + parseFloat(m2[1]) / 100, // percentage + parseFloat(m2[2]) / 100 // percentage + ); + } + case "rgb": { + return rgb( + d3_rgb_parseNumber(m2[0]), + d3_rgb_parseNumber(m2[1]), + d3_rgb_parseNumber(m2[2]) + ); + } + } + } + + /* Named colors. */ + if (name = d3_rgb_names[format]) return rgb(name.r, name.g, name.b); + + /* Hexadecimal colors: #rgb and #rrggbb. */ + if (format != null && format.charAt(0) === "#") { + if (format.length === 4) { + r = format.charAt(1); r += r; + g = format.charAt(2); g += g; + b = format.charAt(3); b += b; + } else if (format.length === 7) { + r = format.substring(1, 3); + g = format.substring(3, 5); + b = format.substring(5, 7); + } + r = parseInt(r, 16); + g = parseInt(g, 16); + b = parseInt(b, 16); + } + + return rgb(r, g, b); +} + +function d3_rgb_hsl(r, g, b) { + var min = Math.min(r /= 255, g /= 255, b /= 255), + max = Math.max(r, g, b), + d = max - min, + h, + s, + l = (max + min) / 2; + if (d) { + s = l < .5 ? d / (max + min) : d / (2 - max - min); + if (r == max) h = (g - b) / d + (g < b ? 6 : 0); + else if (g == max) h = (b - r) / d + 2; + else h = (r - g) / d + 4; + h *= 60; + } else { + s = h = 0; + } + return d3_hsl(h, s, l); +} + +function d3_rgb_parseNumber(c) { // either integer or percentage + var f = parseFloat(c); + return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; +} + +var d3_rgb_names = { + aliceblue: "#f0f8ff", + antiquewhite: "#faebd7", + aqua: "#00ffff", + aquamarine: "#7fffd4", + azure: "#f0ffff", + beige: "#f5f5dc", + bisque: "#ffe4c4", + black: "#000000", + blanchedalmond: "#ffebcd", + blue: "#0000ff", + blueviolet: "#8a2be2", + brown: "#a52a2a", + burlywood: "#deb887", + cadetblue: "#5f9ea0", + chartreuse: "#7fff00", + chocolate: "#d2691e", + coral: "#ff7f50", + cornflowerblue: "#6495ed", + cornsilk: "#fff8dc", + crimson: "#dc143c", + cyan: "#00ffff", + darkblue: "#00008b", + darkcyan: "#008b8b", + darkgoldenrod: "#b8860b", + darkgray: "#a9a9a9", + darkgreen: "#006400", + darkgrey: "#a9a9a9", + darkkhaki: "#bdb76b", + darkmagenta: "#8b008b", + darkolivegreen: "#556b2f", + darkorange: "#ff8c00", + darkorchid: "#9932cc", + darkred: "#8b0000", + darksalmon: "#e9967a", + darkseagreen: "#8fbc8f", + darkslateblue: "#483d8b", + darkslategray: "#2f4f4f", + darkslategrey: "#2f4f4f", + darkturquoise: "#00ced1", + darkviolet: "#9400d3", + deeppink: "#ff1493", + deepskyblue: "#00bfff", + dimgray: "#696969", + dimgrey: "#696969", + dodgerblue: "#1e90ff", + firebrick: "#b22222", + floralwhite: "#fffaf0", + forestgreen: "#228b22", + fuchsia: "#ff00ff", + gainsboro: "#dcdcdc", + ghostwhite: "#f8f8ff", + gold: "#ffd700", + goldenrod: "#daa520", + gray: "#808080", + green: "#008000", + greenyellow: "#adff2f", + grey: "#808080", + honeydew: "#f0fff0", + hotpink: "#ff69b4", + indianred: "#cd5c5c", + indigo: "#4b0082", + ivory: "#fffff0", + khaki: "#f0e68c", + lavender: "#e6e6fa", + lavenderblush: "#fff0f5", + lawngreen: "#7cfc00", + lemonchiffon: "#fffacd", + lightblue: "#add8e6", + lightcoral: "#f08080", + lightcyan: "#e0ffff", + lightgoldenrodyellow: "#fafad2", + lightgray: "#d3d3d3", + lightgreen: "#90ee90", + lightgrey: "#d3d3d3", + lightpink: "#ffb6c1", + lightsalmon: "#ffa07a", + lightseagreen: "#20b2aa", + lightskyblue: "#87cefa", + lightslategray: "#778899", + lightslategrey: "#778899", + lightsteelblue: "#b0c4de", + lightyellow: "#ffffe0", + lime: "#00ff00", + limegreen: "#32cd32", + linen: "#faf0e6", + magenta: "#ff00ff", + maroon: "#800000", + mediumaquamarine: "#66cdaa", + mediumblue: "#0000cd", + mediumorchid: "#ba55d3", + mediumpurple: "#9370db", + mediumseagreen: "#3cb371", + mediumslateblue: "#7b68ee", + mediumspringgreen: "#00fa9a", + mediumturquoise: "#48d1cc", + mediumvioletred: "#c71585", + midnightblue: "#191970", + mintcream: "#f5fffa", + mistyrose: "#ffe4e1", + moccasin: "#ffe4b5", + navajowhite: "#ffdead", + navy: "#000080", + oldlace: "#fdf5e6", + olive: "#808000", + olivedrab: "#6b8e23", + orange: "#ffa500", + orangered: "#ff4500", + orchid: "#da70d6", + palegoldenrod: "#eee8aa", + palegreen: "#98fb98", + paleturquoise: "#afeeee", + palevioletred: "#db7093", + papayawhip: "#ffefd5", + peachpuff: "#ffdab9", + peru: "#cd853f", + pink: "#ffc0cb", + plum: "#dda0dd", + powderblue: "#b0e0e6", + purple: "#800080", + red: "#ff0000", + rosybrown: "#bc8f8f", + royalblue: "#4169e1", + saddlebrown: "#8b4513", + salmon: "#fa8072", + sandybrown: "#f4a460", + seagreen: "#2e8b57", + seashell: "#fff5ee", + sienna: "#a0522d", + silver: "#c0c0c0", + skyblue: "#87ceeb", + slateblue: "#6a5acd", + slategray: "#708090", + slategrey: "#708090", + snow: "#fffafa", + springgreen: "#00ff7f", + steelblue: "#4682b4", + tan: "#d2b48c", + teal: "#008080", + thistle: "#d8bfd8", + tomato: "#ff6347", + turquoise: "#40e0d0", + violet: "#ee82ee", + wheat: "#f5deb3", + white: "#ffffff", + whitesmoke: "#f5f5f5", + yellow: "#ffff00", + yellowgreen: "#9acd32" +}; + +for (var d3_rgb_name in d3_rgb_names) { + d3_rgb_names[d3_rgb_name] = d3_rgb_parse( + d3_rgb_names[d3_rgb_name], + d3_rgb, + d3_hsl_rgb); +} +d3.hsl = function(h, s, l) { + return arguments.length === 1 + ? (h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) + : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl)) + : d3_hsl(+h, +s, +l); +}; + +function d3_hsl(h, s, l) { + return new d3_Hsl(h, s, l); +} + +function d3_Hsl(h, s, l) { + this.h = h; + this.s = s; + this.l = l; +} + +d3_Hsl.prototype.brighter = function(k) { + k = Math.pow(0.7, arguments.length ? k : 1); + return d3_hsl(this.h, this.s, this.l / k); +}; + +d3_Hsl.prototype.darker = function(k) { + k = Math.pow(0.7, arguments.length ? k : 1); + return d3_hsl(this.h, this.s, k * this.l); +}; + +d3_Hsl.prototype.rgb = function() { + return d3_hsl_rgb(this.h, this.s, this.l); +}; + +d3_Hsl.prototype.toString = function() { + return this.rgb().toString(); +}; + +function d3_hsl_rgb(h, s, l) { + var m1, + m2; + + /* Some simple corrections for h, s and l. */ + h = h % 360; if (h < 0) h += 360; + s = s < 0 ? 0 : s > 1 ? 1 : s; + l = l < 0 ? 0 : l > 1 ? 1 : l; + + /* From FvD 13.37, CSS Color Module Level 3 */ + m2 = l <= .5 ? l * (1 + s) : l + s - l * s; + m1 = 2 * l - m2; + + function v(h) { + if (h > 360) h -= 360; + else if (h < 0) h += 360; + if (h < 60) return m1 + (m2 - m1) * h / 60; + if (h < 180) return m2; + if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; + return m1; + } + + function vv(h) { + return Math.round(v(h) * 255); + } + + return d3_rgb(vv(h + 120), vv(h), vv(h - 120)); +} +function d3_selection(groups) { + d3_arraySubclass(groups, d3_selectionPrototype); + return groups; +} + +var d3_select = function(s, n) { return n.querySelector(s); }, + d3_selectAll = function(s, n) { return n.querySelectorAll(s); }, + d3_selectRoot = document.documentElement, + d3_selectMatcher = d3_selectRoot.matchesSelector || d3_selectRoot.webkitMatchesSelector || d3_selectRoot.mozMatchesSelector || d3_selectRoot.msMatchesSelector || d3_selectRoot.oMatchesSelector, + d3_selectMatches = function(n, s) { return d3_selectMatcher.call(n, s); }; + +// Prefer Sizzle, if available. +if (typeof Sizzle === "function") { + d3_select = function(s, n) { return Sizzle(s, n)[0]; }; + d3_selectAll = function(s, n) { return Sizzle.uniqueSort(Sizzle(s, n)); }; + d3_selectMatches = Sizzle.matchesSelector; +} + +var d3_selectionPrototype = []; + +d3.selection = function() { + return d3_selectionRoot; +}; + +d3.selection.prototype = d3_selectionPrototype; +d3_selectionPrototype.select = function(selector) { + var subgroups = [], + subgroup, + subnode, + group, + node; + + if (typeof selector !== "function") selector = d3_selection_selector(selector); + + for (var j = -1, m = this.length; ++j < m;) { + subgroups.push(subgroup = []); + subgroup.parentNode = (group = this[j]).parentNode; + for (var i = -1, n = group.length; ++i < n;) { + if (node = group[i]) { + subgroup.push(subnode = selector.call(node, node.__data__, i)); + if (subnode && "__data__" in node) subnode.__data__ = node.__data__; + } else { + subgroup.push(null); + } + } + } + + return d3_selection(subgroups); +}; + +function d3_selection_selector(selector) { + return function() { + return d3_select(selector, this); + }; +} +d3_selectionPrototype.selectAll = function(selector) { + var subgroups = [], + subgroup, + node; + + if (typeof selector !== "function") selector = d3_selection_selectorAll(selector); + + for (var j = -1, m = this.length; ++j < m;) { + for (var group = this[j], i = -1, n = group.length; ++i < n;) { + if (node = group[i]) { + subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i))); + subgroup.parentNode = node; + } + } + } + + return d3_selection(subgroups); +}; + +function d3_selection_selectorAll(selector) { + return function() { + return d3_selectAll(selector, this); + }; +} +d3_selectionPrototype.attr = function(name, value) { + name = d3.ns.qualify(name); + + // If no value is specified, return the first value. + if (arguments.length < 2) { + var node = this.node(); + return name.local + ? node.getAttributeNS(name.space, name.local) + : node.getAttribute(name); + } + + function attrNull() { + this.removeAttribute(name); + } + + function attrNullNS() { + this.removeAttributeNS(name.space, name.local); + } + + function attrConstant() { + this.setAttribute(name, value); + } + + function attrConstantNS() { + this.setAttributeNS(name.space, name.local, value); + } + + function attrFunction() { + var x = value.apply(this, arguments); + if (x == null) this.removeAttribute(name); + else this.setAttribute(name, x); + } + + function attrFunctionNS() { + var x = value.apply(this, arguments); + if (x == null) this.removeAttributeNS(name.space, name.local); + else this.setAttributeNS(name.space, name.local, x); + } + + return this.each(value == null + ? (name.local ? attrNullNS : attrNull) : (typeof value === "function" + ? (name.local ? attrFunctionNS : attrFunction) + : (name.local ? attrConstantNS : attrConstant))); +}; +d3_selectionPrototype.classed = function(name, value) { + var names = name.split(d3_selection_classedWhitespace), + n = names.length, + i = -1; + if (arguments.length > 1) { + while (++i < n) d3_selection_classed.call(this, names[i], value); + return this; + } else { + while (++i < n) if (!d3_selection_classed.call(this, names[i])) return false; + return true; + } +}; + +var d3_selection_classedWhitespace = /\s+/g; + +function d3_selection_classed(name, value) { + var re = new RegExp("(^|\\s+)" + d3.requote(name) + "(\\s+|$)", "g"); + + // If no value is specified, return the first value. + if (arguments.length < 2) { + var node = this.node(); + if (c = node.classList) return c.contains(name); + var c = node.className; + re.lastIndex = 0; + return re.test(c.baseVal != null ? c.baseVal : c); + } + + function classedAdd() { + if (c = this.classList) return c.add(name); + var c = this.className, + cb = c.baseVal != null, + cv = cb ? c.baseVal : c; + re.lastIndex = 0; + if (!re.test(cv)) { + cv = d3_collapse(cv + " " + name); + if (cb) c.baseVal = cv; + else this.className = cv; + } + } + + function classedRemove() { + if (c = this.classList) return c.remove(name); + var c = this.className, + cb = c.baseVal != null, + cv = cb ? c.baseVal : c; + cv = d3_collapse(cv.replace(re, " ")); + if (cb) c.baseVal = cv; + else this.className = cv; + } + + function classedFunction() { + (value.apply(this, arguments) + ? classedAdd + : classedRemove).call(this); + } + + return this.each(typeof value === "function" + ? classedFunction : value + ? classedAdd + : classedRemove); +} +d3_selectionPrototype.style = function(name, value, priority) { + if (arguments.length < 3) priority = ""; + + // If no value is specified, return the first value. + if (arguments.length < 2) return window + .getComputedStyle(this.node(), null) + .getPropertyValue(name); + + function styleNull() { + this.style.removeProperty(name); + } + + function styleConstant() { + this.style.setProperty(name, value, priority); + } + + function styleFunction() { + var x = value.apply(this, arguments); + if (x == null) this.style.removeProperty(name); + else this.style.setProperty(name, x, priority); + } + + return this.each(value == null + ? styleNull : (typeof value === "function" + ? styleFunction : styleConstant)); +}; +d3_selectionPrototype.property = function(name, value) { + + // If no value is specified, return the first value. + if (arguments.length < 2) return this.node()[name]; + + function propertyNull() { + delete this[name]; + } + + function propertyConstant() { + this[name] = value; + } + + function propertyFunction() { + var x = value.apply(this, arguments); + if (x == null) delete this[name]; + else this[name] = x; + } + + return this.each(value == null + ? propertyNull : (typeof value === "function" + ? propertyFunction : propertyConstant)); +}; +d3_selectionPrototype.text = function(value) { + return arguments.length < 1 + ? this.node().textContent : this.each(typeof value === "function" + ? function() { var v = value.apply(this, arguments); this.textContent = v == null ? "" : v; } : value == null + ? function() { this.textContent = ""; } + : function() { this.textContent = value; }); +}; +d3_selectionPrototype.html = function(value) { + return arguments.length < 1 + ? this.node().innerHTML : this.each(typeof value === "function" + ? function() { var v = value.apply(this, arguments); this.innerHTML = v == null ? "" : v; } : value == null + ? function() { this.innerHTML = ""; } + : function() { this.innerHTML = value; }); +}; +// TODO append(node)? +// TODO append(function)? +d3_selectionPrototype.append = function(name) { + name = d3.ns.qualify(name); + + function append() { + return this.appendChild(document.createElementNS(this.namespaceURI, name)); + } + + function appendNS() { + return this.appendChild(document.createElementNS(name.space, name.local)); + } + + return this.select(name.local ? appendNS : append); +}; +// TODO insert(node, function)? +// TODO insert(function, string)? +// TODO insert(function, function)? +d3_selectionPrototype.insert = function(name, before) { + name = d3.ns.qualify(name); + + function insert() { + return this.insertBefore( + document.createElementNS(this.namespaceURI, name), + d3_select(before, this)); + } + + function insertNS() { + return this.insertBefore( + document.createElementNS(name.space, name.local), + d3_select(before, this)); + } + + return this.select(name.local ? insertNS : insert); +}; +// TODO remove(selector)? +// TODO remove(node)? +// TODO remove(function)? +d3_selectionPrototype.remove = function() { + return this.each(function() { + var parent = this.parentNode; + if (parent) parent.removeChild(this); + }); +}; +// TODO data(null) for clearing data? +d3_selectionPrototype.data = function(data, join) { + var enter = [], + update = [], + exit = []; + + function bind(group, groupData) { + var i, + n = group.length, + m = groupData.length, + n0 = Math.min(n, m), + n1 = Math.max(n, m), + updateNodes = [], + enterNodes = [], + exitNodes = [], + node, + nodeData; + + if (join) { + var nodeByKey = {}, + keys = [], + key, + j = groupData.length; + + for (i = -1; ++i < n;) { + key = join.call(node = group[i], node.__data__, i); + if (key in nodeByKey) { + exitNodes[j++] = node; // duplicate key + } else { + nodeByKey[key] = node; + } + keys.push(key); + } + + for (i = -1; ++i < m;) { + node = nodeByKey[key = join.call(groupData, nodeData = groupData[i], i)]; + if (node) { + node.__data__ = nodeData; + updateNodes[i] = node; + enterNodes[i] = exitNodes[i] = null; + } else { + enterNodes[i] = d3_selection_dataNode(nodeData); + updateNodes[i] = exitNodes[i] = null; + } + delete nodeByKey[key]; + } + + for (i = -1; ++i < n;) { + if (keys[i] in nodeByKey) { + exitNodes[i] = group[i]; + } + } + } else { + for (i = -1; ++i < n0;) { + node = group[i]; + nodeData = groupData[i]; + if (node) { + node.__data__ = nodeData; + updateNodes[i] = node; + enterNodes[i] = exitNodes[i] = null; + } else { + enterNodes[i] = d3_selection_dataNode(nodeData); + updateNodes[i] = exitNodes[i] = null; + } + } + for (; i < m; ++i) { + enterNodes[i] = d3_selection_dataNode(groupData[i]); + updateNodes[i] = exitNodes[i] = null; + } + for (; i < n1; ++i) { + exitNodes[i] = group[i]; + enterNodes[i] = updateNodes[i] = null; + } + } + + enterNodes.update + = updateNodes; + + enterNodes.parentNode + = updateNodes.parentNode + = exitNodes.parentNode + = group.parentNode; + + enter.push(enterNodes); + update.push(updateNodes); + exit.push(exitNodes); + } + + var i = -1, + n = this.length, + group; + if (typeof data === "function") { + while (++i < n) { + bind(group = this[i], data.call(group, group.parentNode.__data__, i)); + } + } else { + while (++i < n) { + bind(group = this[i], data); + } + } + + var selection = d3_selection(update); + selection.enter = function() { return d3_selection_enter(enter); }; + selection.exit = function() { return d3_selection(exit); }; + return selection; +}; + +function d3_selection_dataNode(data) { + return {__data__: data}; +} +d3_selectionPrototype.filter = function(filter) { + var subgroups = [], + subgroup, + group, + node; + + if (typeof filter !== "function") filter = d3_selection_filter(filter); + + for (var j = 0, m = this.length; j < m; j++) { + subgroups.push(subgroup = []); + subgroup.parentNode = (group = this[j]).parentNode; + for (var i = 0, n = group.length; i < n; i++) { + if ((node = group[i]) && filter.call(node, node.__data__, i)) { + subgroup.push(node); + } + } + } + + return d3_selection(subgroups); +}; + +function d3_selection_filter(selector) { + return function() { + return d3_selectMatches(this, selector); + }; +} +d3_selectionPrototype.map = function(map) { + return this.each(function() { + this.__data__ = map.apply(this, arguments); + }); +}; +d3_selectionPrototype.order = function() { + for (var j = -1, m = this.length; ++j < m;) { + for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0;) { + if (node = group[i]) { + if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); + next = node; + } + } + } + return this; +}; +d3_selectionPrototype.sort = function(comparator) { + comparator = d3_selection_sortComparator.apply(this, arguments); + for (var j = -1, m = this.length; ++j < m;) this[j].sort(comparator); + return this.order(); +}; + +function d3_selection_sortComparator(comparator) { + if (!arguments.length) comparator = d3.ascending; + return function(a, b) { + return comparator(a && a.__data__, b && b.__data__); + }; +} +// type can be namespaced, e.g., "click.foo" +// listener can be null for removal +d3_selectionPrototype.on = function(type, listener, capture) { + if (arguments.length < 3) capture = false; + + // parse the type specifier + var name = "__on" + type, i = type.indexOf("."); + if (i > 0) type = type.substring(0, i); + + // if called with only one argument, return the current listener + if (arguments.length < 2) return (i = this.node()[name]) && i._; + + // remove the old event listener, and add the new event listener + return this.each(function(d, i) { + var node = this; + + if (node[name]) node.removeEventListener(type, node[name], capture); + if (listener) node.addEventListener(type, node[name] = l, capture); + + // wrapped event listener that preserves i + function l(e) { + var o = d3.event; // Events can be reentrant (e.g., focus). + d3.event = e; + try { + listener.call(node, node.__data__, i); + } finally { + d3.event = o; + } + } + + // stash the unwrapped listener for retrieval + l._ = listener; + }); +}; +d3_selectionPrototype.each = function(callback) { + for (var j = -1, m = this.length; ++j < m;) { + for (var group = this[j], i = -1, n = group.length; ++i < n;) { + var node = group[i]; + if (node) callback.call(node, node.__data__, i, j); + } + } + return this; +}; +// +// Note: assigning to the arguments array simultaneously changes the value of +// the corresponding argument! +// +// TODO The `this` argument probably shouldn't be the first argument to the +// callback, anyway, since it's redundant. However, that will require a major +// version bump due to backwards compatibility, so I'm not changing it right +// away. +// +d3_selectionPrototype.call = function(callback) { + callback.apply(this, (arguments[0] = this, arguments)); + return this; +}; +d3_selectionPrototype.empty = function() { + return !this.node(); +}; +d3_selectionPrototype.node = function(callback) { + for (var j = 0, m = this.length; j < m; j++) { + for (var group = this[j], i = 0, n = group.length; i < n; i++) { + var node = group[i]; + if (node) return node; + } + } + return null; +}; +d3_selectionPrototype.transition = function() { + var subgroups = [], + subgroup, + node; + + for (var j = -1, m = this.length; ++j < m;) { + subgroups.push(subgroup = []); + for (var group = this[j], i = -1, n = group.length; ++i < n;) { + subgroup.push((node = group[i]) ? {node: node, delay: 0, duration: 250} : null); + } + } + + return d3_transition(subgroups, d3_transitionInheritId || ++d3_transitionId, Date.now()); +}; +var d3_selectionRoot = d3_selection([[document]]); + +d3_selectionRoot[0].parentNode = d3_selectRoot; + +// TODO fast singleton implementation! +// TODO select(function) +d3.select = function(selector) { + return typeof selector === "string" + ? d3_selectionRoot.select(selector) + : d3_selection([[selector]]); // assume node +}; + +// TODO selectAll(function) +d3.selectAll = function(selector) { + return typeof selector === "string" + ? d3_selectionRoot.selectAll(selector) + : d3_selection([d3_array(selector)]); // assume node[] +}; +function d3_selection_enter(selection) { + d3_arraySubclass(selection, d3_selection_enterPrototype); + return selection; +} + +var d3_selection_enterPrototype = []; + +d3_selection_enterPrototype.append = d3_selectionPrototype.append; +d3_selection_enterPrototype.insert = d3_selectionPrototype.insert; +d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; +d3_selection_enterPrototype.node = d3_selectionPrototype.node; +d3_selection_enterPrototype.select = function(selector) { + var subgroups = [], + subgroup, + subnode, + upgroup, + group, + node; + + for (var j = -1, m = this.length; ++j < m;) { + upgroup = (group = this[j]).update; + subgroups.push(subgroup = []); + subgroup.parentNode = group.parentNode; + for (var i = -1, n = group.length; ++i < n;) { + if (node = group[i]) { + subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i)); + subnode.__data__ = node.__data__; + } else { + subgroup.push(null); + } + } + } + + return d3_selection(subgroups); +}; +function d3_transition(groups, id, time) { + d3_arraySubclass(groups, d3_transitionPrototype); + + var tweens = {}, + event = d3.dispatch("start", "end"), + ease = d3_transitionEase; + + groups.id = id; + + groups.time = time; + + groups.tween = function(name, tween) { + if (arguments.length < 2) return tweens[name]; + if (tween == null) delete tweens[name]; + else tweens[name] = tween; + return groups; + }; + + groups.ease = function(value) { + if (!arguments.length) return ease; + ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments); + return groups; + }; + + groups.each = function(type, listener) { + if (arguments.length < 2) return d3_transition_each.call(groups, type); + event.on(type, listener); + return groups; + }; + + d3.timer(function(elapsed) { + groups.each(function(d, i, j) { + var tweened = [], + node = this, + delay = groups[j][i].delay, + duration = groups[j][i].duration, + lock = node.__transition__ || (node.__transition__ = {active: 0, count: 0}); + + ++lock.count; + + delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time); + + function start(elapsed) { + if (lock.active > id) return stop(); + lock.active = id; + + for (var tween in tweens) { + if (tween = tweens[tween].call(node, d, i)) { + tweened.push(tween); + } + } + + event.start.call(node, d, i); + if (!tick(elapsed)) d3.timer(tick, 0, time); + return 1; + } + + function tick(elapsed) { + if (lock.active !== id) return stop(); + + var t = (elapsed - delay) / duration, + e = ease(t), + n = tweened.length; + + while (n > 0) { + tweened[--n].call(node, e); + } + + if (t >= 1) { + stop(); + d3_transitionInheritId = id; + event.end.call(node, d, i); + d3_transitionInheritId = 0; + return 1; + } + } + + function stop() { + if (!--lock.count) delete node.__transition__; + return 1; + } + }); + return 1; + }, 0, time); + + return groups; +} + +var d3_transitionRemove = {}; + +function d3_transitionNull(d, i, a) { + return a != "" && d3_transitionRemove; +} + +function d3_transitionTween(name, b) { + var interpolate = d3_interpolateByName(name); + + function transitionFunction(d, i, a) { + var v = b.call(this, d, i); + return v == null + ? a != "" && d3_transitionRemove + : a != v && interpolate(a, v); + } + + function transitionString(d, i, a) { + return a != b && interpolate(a, b); + } + + return typeof b === "function" ? transitionFunction + : b == null ? d3_transitionNull + : (b += "", transitionString); +} + +var d3_transitionPrototype = [], + d3_transitionId = 0, + d3_transitionInheritId = 0, + d3_transitionEase = d3.ease("cubic-in-out"); + +d3_transitionPrototype.call = d3_selectionPrototype.call; + +d3.transition = function() { + return d3_selectionRoot.transition(); +}; + +d3.transition.prototype = d3_transitionPrototype; +d3_transitionPrototype.select = function(selector) { + var subgroups = [], + subgroup, + subnode, + node; + + if (typeof selector !== "function") selector = d3_selection_selector(selector); + + for (var j = -1, m = this.length; ++j < m;) { + subgroups.push(subgroup = []); + for (var group = this[j], i = -1, n = group.length; ++i < n;) { + if ((node = group[i]) && (subnode = selector.call(node.node, node.node.__data__, i))) { + if ("__data__" in node.node) subnode.__data__ = node.node.__data__; + subgroup.push({node: subnode, delay: node.delay, duration: node.duration}); + } else { + subgroup.push(null); + } + } + } + + return d3_transition(subgroups, this.id, this.time).ease(this.ease()); +}; +d3_transitionPrototype.selectAll = function(selector) { + var subgroups = [], + subgroup, + subnodes, + node; + + if (typeof selector !== "function") selector = d3_selection_selectorAll(selector); + + for (var j = -1, m = this.length; ++j < m;) { + for (var group = this[j], i = -1, n = group.length; ++i < n;) { + if (node = group[i]) { + subnodes = selector.call(node.node, node.node.__data__, i); + subgroups.push(subgroup = []); + for (var k = -1, o = subnodes.length; ++k < o;) { + subgroup.push({node: subnodes[k], delay: node.delay, duration: node.duration}); + } + } + } + } + + return d3_transition(subgroups, this.id, this.time).ease(this.ease()); +}; +d3_transitionPrototype.attr = function(name, value) { + return this.attrTween(name, d3_transitionTween(name, value)); +}; + +d3_transitionPrototype.attrTween = function(nameNS, tween) { + var name = d3.ns.qualify(nameNS); + + function attrTween(d, i) { + var f = tween.call(this, d, i, this.getAttribute(name)); + return f === d3_transitionRemove + ? (this.removeAttribute(name), null) + : f && function(t) { this.setAttribute(name, f(t)); }; + } + + function attrTweenNS(d, i) { + var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); + return f === d3_transitionRemove + ? (this.removeAttributeNS(name.space, name.local), null) + : f && function(t) { this.setAttributeNS(name.space, name.local, f(t)); }; + } + + return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); +}; +d3_transitionPrototype.style = function(name, value, priority) { + if (arguments.length < 3) priority = ""; + return this.styleTween(name, d3_transitionTween(name, value), priority); +}; + +d3_transitionPrototype.styleTween = function(name, tween, priority) { + if (arguments.length < 3) priority = ""; + return this.tween("style." + name, function(d, i) { + var f = tween.call(this, d, i, window.getComputedStyle(this, null).getPropertyValue(name)); + return f === d3_transitionRemove + ? (this.style.removeProperty(name), null) + : f && function(t) { this.style.setProperty(name, f(t), priority); }; + }); +}; +d3_transitionPrototype.text = function(value) { + return this.tween("text", function(d, i) { + this.textContent = typeof value === "function" + ? value.call(this, d, i) + : value; + }); +}; +d3_transitionPrototype.remove = function() { + return this.each("end.transition", function() { + var p; + if (!this.__transition__ && (p = this.parentNode)) p.removeChild(this); + }); +}; +d3_transitionPrototype.delay = function(value) { + var groups = this; + return groups.each(typeof value === "function" + ? function(d, i, j) { groups[j][i].delay = +value.apply(this, arguments); } + : (value = +value, function(d, i, j) { groups[j][i].delay = value; })); +}; +d3_transitionPrototype.duration = function(value) { + var groups = this; + return groups.each(typeof value === "function" + ? function(d, i, j) { groups[j][i].duration = +value.apply(this, arguments); } + : (value = +value, function(d, i, j) { groups[j][i].duration = value; })); +}; +function d3_transition_each(callback) { + for (var j = 0, m = this.length; j < m; j++) { + for (var group = this[j], i = 0, n = group.length; i < n; i++) { + var node = group[i]; + if (node) callback.call(node = node.node, node.__data__, i, j); + } + } + return this; +} +d3_transitionPrototype.transition = function() { + return this.select(d3_this); +}; +var d3_timer_queue = null, + d3_timer_interval, // is an interval (or frame) active? + d3_timer_timeout; // is a timeout active? + +// The timer will continue to fire until callback returns true. +d3.timer = function(callback, delay, then) { + var found = false, + t0, + t1 = d3_timer_queue; + + if (arguments.length < 3) { + if (arguments.length < 2) delay = 0; + else if (!isFinite(delay)) return; + then = Date.now(); + } + + // See if the callback's already in the queue. + while (t1) { + if (t1.callback === callback) { + t1.then = then; + t1.delay = delay; + found = true; + break; + } + t0 = t1; + t1 = t1.next; + } + + // Otherwise, add the callback to the queue. + if (!found) d3_timer_queue = { + callback: callback, + then: then, + delay: delay, + next: d3_timer_queue + }; + + // Start animatin'! + if (!d3_timer_interval) { + d3_timer_timeout = clearTimeout(d3_timer_timeout); + d3_timer_interval = 1; + d3_timer_frame(d3_timer_step); + } +} + +function d3_timer_step() { + var elapsed, + now = Date.now(), + t1 = d3_timer_queue; + + while (t1) { + elapsed = now - t1.then; + if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed); + t1 = t1.next; + } + + var delay = d3_timer_flush() - now; + if (delay > 24) { + if (isFinite(delay)) { + clearTimeout(d3_timer_timeout); + d3_timer_timeout = setTimeout(d3_timer_step, delay); + } + d3_timer_interval = 0; + } else { + d3_timer_interval = 1; + d3_timer_frame(d3_timer_step); + } +} + +d3.timer.flush = function() { + var elapsed, + now = Date.now(), + t1 = d3_timer_queue; + + while (t1) { + elapsed = now - t1.then; + if (!t1.delay) t1.flush = t1.callback(elapsed); + t1 = t1.next; + } + + d3_timer_flush(); +}; + +// Flush after callbacks, to avoid concurrent queue modification. +function d3_timer_flush() { + var t0 = null, + t1 = d3_timer_queue, + then = Infinity; + while (t1) { + if (t1.flush) { + t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next; + } else { + then = Math.min(then, t1.then + t1.delay); + t1 = (t0 = t1).next; + } + } + return then; +} + +var d3_timer_frame = window.requestAnimationFrame + || window.webkitRequestAnimationFrame + || window.mozRequestAnimationFrame + || window.oRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 17); }; +d3.transform = function(string) { + var g = document.createElementNS(d3.ns.prefix.svg, "g"), + identity = {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0}; + return (d3.transform = function(string) { + g.setAttribute("transform", string); + var t = g.transform.baseVal.consolidate(); + return new d3_transform(t ? t.matrix : identity); + })(string); +}; + +// Compute x-scale and normalize the first row. +// Compute shear and make second row orthogonal to first. +// Compute y-scale and normalize the second row. +// Finally, compute the rotation. +function d3_transform(m) { + var r0 = [m.a, m.b], + r1 = [m.c, m.d], + kx = d3_transformNormalize(r0), + kz = d3_transformDot(r0, r1), + ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; + if (r0[0] * r1[1] < r1[0] * r0[1]) { + r0[0] *= -1; + r0[1] *= -1; + kx *= -1; + kz *= -1; + } + this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_transformDegrees; + this.translate = [m.e, m.f]; + this.scale = [kx, ky]; + this.skew = ky ? Math.atan2(kz, ky) * d3_transformDegrees : 0; +}; + +d3_transform.prototype.toString = function() { + return "translate(" + this.translate + + ")rotate(" + this.rotate + + ")skewX(" + this.skew + + ")scale(" + this.scale + + ")"; +}; + +function d3_transformDot(a, b) { + return a[0] * b[0] + a[1] * b[1]; +} + +function d3_transformNormalize(a) { + var k = Math.sqrt(d3_transformDot(a, a)); + if (k) { + a[0] /= k; + a[1] /= k; + } + return k; +} + +function d3_transformCombine(a, b, k) { + a[0] += k * b[0]; + a[1] += k * b[1]; + return a; +} + +var d3_transformDegrees = 180 / Math.PI; +function d3_noop() {} +d3.scale = {}; + +function d3_scaleExtent(domain) { + var start = domain[0], stop = domain[domain.length - 1]; + return start < stop ? [start, stop] : [stop, start]; +} + +function d3_scaleRange(scale) { + return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); +} +function d3_scale_nice(domain, nice) { + var i0 = 0, + i1 = domain.length - 1, + x0 = domain[i0], + x1 = domain[i1], + dx; + + if (x1 < x0) { + dx = i0; i0 = i1; i1 = dx; + dx = x0; x0 = x1; x1 = dx; + } + + if (dx = x1 - x0) { + nice = nice(dx); + domain[i0] = nice.floor(x0); + domain[i1] = nice.ceil(x1); + } + + return domain; +} + +function d3_scale_niceDefault() { + return Math; +} +d3.scale.linear = function() { + return d3_scale_linear([0, 1], [0, 1], d3.interpolate, false); +}; + +function d3_scale_linear(domain, range, interpolate, clamp) { + var output, + input; + + function rescale() { + var linear = domain.length == 2 ? d3_scale_bilinear : d3_scale_polylinear, + uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; + output = linear(domain, range, uninterpolate, interpolate); + input = linear(range, domain, uninterpolate, d3.interpolate); + return scale; + } + + function scale(x) { + return output(x); + } + + // Note: requires range is coercible to number! + scale.invert = function(y) { + return input(y); + }; + + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = x.map(Number); + return rescale(); + }; + + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + + scale.rangeRound = function(x) { + return scale.range(x).interpolate(d3.interpolateRound); + }; + + scale.clamp = function(x) { + if (!arguments.length) return clamp; + clamp = x; + return rescale(); + }; + + scale.interpolate = function(x) { + if (!arguments.length) return interpolate; + interpolate = x; + return rescale(); + }; + + scale.ticks = function(m) { + return d3_scale_linearTicks(domain, m); + }; + + scale.tickFormat = function(m) { + return d3_scale_linearTickFormat(domain, m); + }; + + scale.nice = function() { + d3_scale_nice(domain, d3_scale_linearNice); + return rescale(); + }; + + scale.copy = function() { + return d3_scale_linear(domain, range, interpolate, clamp); + }; + + return rescale(); +}; + +function d3_scale_linearRebind(scale, linear) { + return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); +} + +function d3_scale_linearNice(dx) { + dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1); + return { + floor: function(x) { return Math.floor(x / dx) * dx; }, + ceil: function(x) { return Math.ceil(x / dx) * dx; } + }; +} + +function d3_scale_linearTickRange(domain, m) { + var extent = d3_scaleExtent(domain), + span = extent[1] - extent[0], + step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), + err = m / span * step; + + // Filter ticks to get closer to the desired count. + if (err <= .15) step *= 10; + else if (err <= .35) step *= 5; + else if (err <= .75) step *= 2; + + // Round start and stop values to step interval. + extent[0] = Math.ceil(extent[0] / step) * step; + extent[1] = Math.floor(extent[1] / step) * step + step * .5; // inclusive + extent[2] = step; + return extent; +} + +function d3_scale_linearTicks(domain, m) { + return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); +} + +function d3_scale_linearTickFormat(domain, m) { + return d3.format(",." + Math.max(0, -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01)) + "f"); +} +function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { + var u = uninterpolate(domain[0], domain[1]), + i = interpolate(range[0], range[1]); + return function(x) { + return i(u(x)); + }; +} +function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { + var u = [], + i = [], + j = 0, + k = domain.length - 1; + + // Handle descending domains. + if (domain[k] < domain[0]) { + domain = domain.slice().reverse(); + range = range.slice().reverse(); + } + + while (++j <= k) { + u.push(uninterpolate(domain[j - 1], domain[j])); + i.push(interpolate(range[j - 1], range[j])); + } + + return function(x) { + var j = d3.bisect(domain, x, 1, k) - 1; + return i[j](u[j](x)); + }; +} +d3.scale.log = function() { + return d3_scale_log(d3.scale.linear(), d3_scale_logp); +}; + +function d3_scale_log(linear, log) { + var pow = log.pow; + + function scale(x) { + return linear(log(x)); + } + + scale.invert = function(x) { + return pow(linear.invert(x)); + }; + + scale.domain = function(x) { + if (!arguments.length) return linear.domain().map(pow); + log = x[0] < 0 ? d3_scale_logn : d3_scale_logp; + pow = log.pow; + linear.domain(x.map(log)); + return scale; + }; + + scale.nice = function() { + linear.domain(d3_scale_nice(linear.domain(), d3_scale_niceDefault)); + return scale; + }; + + scale.ticks = function() { + var extent = d3_scaleExtent(linear.domain()), + ticks = []; + if (extent.every(isFinite)) { + var i = Math.floor(extent[0]), + j = Math.ceil(extent[1]), + u = pow(extent[0]), + v = pow(extent[1]); + if (log === d3_scale_logn) { + ticks.push(pow(i)); + for (; i++ < j;) for (var k = 9; k > 0; k--) ticks.push(pow(i) * k); + } else { + for (; i < j; i++) for (var k = 1; k < 10; k++) ticks.push(pow(i) * k); + ticks.push(pow(i)); + } + for (i = 0; ticks[i] < u; i++) {} // strip small values + for (j = ticks.length; ticks[j - 1] > v; j--) {} // strip big values + ticks = ticks.slice(i, j); + } + return ticks; + }; + + scale.tickFormat = function(n, format) { + if (arguments.length < 2) format = d3_scale_logFormat; + if (arguments.length < 1) return format; + var k = n / scale.ticks().length, + f = log === d3_scale_logn ? (e = -1e-12, Math.floor) : (e = 1e-12, Math.ceil), + e; + return function(d) { + return d / pow(f(log(d) + e)) < k ? format(d) : ""; + }; + }; + + scale.copy = function() { + return d3_scale_log(linear.copy(), log); + }; + + return d3_scale_linearRebind(scale, linear); +}; + +var d3_scale_logFormat = d3.format(".0e"); + +function d3_scale_logp(x) { + return Math.log(x < 0 ? 0 : x) / Math.LN10; +} + +function d3_scale_logn(x) { + return -Math.log(x > 0 ? 0 : -x) / Math.LN10; +} + +d3_scale_logp.pow = function(x) { + return Math.pow(10, x); +}; + +d3_scale_logn.pow = function(x) { + return -Math.pow(10, -x); +}; +d3.scale.pow = function() { + return d3_scale_pow(d3.scale.linear(), 1); +}; + +function d3_scale_pow(linear, exponent) { + var powp = d3_scale_powPow(exponent), + powb = d3_scale_powPow(1 / exponent); + + function scale(x) { + return linear(powp(x)); + } + + scale.invert = function(x) { + return powb(linear.invert(x)); + }; + + scale.domain = function(x) { + if (!arguments.length) return linear.domain().map(powb); + linear.domain(x.map(powp)); + return scale; + }; + + scale.ticks = function(m) { + return d3_scale_linearTicks(scale.domain(), m); + }; + + scale.tickFormat = function(m) { + return d3_scale_linearTickFormat(scale.domain(), m); + }; + + scale.nice = function() { + return scale.domain(d3_scale_nice(scale.domain(), d3_scale_linearNice)); + }; + + scale.exponent = function(x) { + if (!arguments.length) return exponent; + var domain = scale.domain(); + powp = d3_scale_powPow(exponent = x); + powb = d3_scale_powPow(1 / exponent); + return scale.domain(domain); + }; + + scale.copy = function() { + return d3_scale_pow(linear.copy(), exponent); + }; + + return d3_scale_linearRebind(scale, linear); +}; + +function d3_scale_powPow(e) { + return function(x) { + return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); + }; +} +d3.scale.sqrt = function() { + return d3.scale.pow().exponent(.5); +}; +d3.scale.ordinal = function() { + return d3_scale_ordinal([], {t: "range", x: []}); +}; + +function d3_scale_ordinal(domain, ranger) { + var index, + range, + rangeBand; + + function scale(x) { + return range[((index[x] || (index[x] = domain.push(x))) - 1) % range.length]; + } + + function steps(start, step) { + return d3.range(domain.length).map(function(i) { return start + step * i; }); + } + + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = []; + index = {}; + var i = -1, n = x.length, xi; + while (++i < n) if (!index[xi = x[i]]) index[xi] = domain.push(xi); + return scale[ranger.t](ranger.x, ranger.p); + }; + + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + rangeBand = 0; + ranger = {t: "range", x: x}; + return scale; + }; + + scale.rangePoints = function(x, padding) { + if (arguments.length < 2) padding = 0; + var start = x[0], + stop = x[1], + step = (stop - start) / (domain.length - 1 + padding); + range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step); + rangeBand = 0; + ranger = {t: "rangePoints", x: x, p: padding}; + return scale; + }; + + scale.rangeBands = function(x, padding) { + if (arguments.length < 2) padding = 0; + var start = x[0], + stop = x[1], + step = (stop - start) / (domain.length + padding); + range = steps(start + step * padding, step); + rangeBand = step * (1 - padding); + ranger = {t: "rangeBands", x: x, p: padding}; + return scale; + }; + + scale.rangeRoundBands = function(x, padding) { + if (arguments.length < 2) padding = 0; + var start = x[0], + stop = x[1], + step = Math.floor((stop - start) / (domain.length + padding)); + range = steps(start + Math.round((stop - start - (domain.length - padding) * step) / 2), step); + rangeBand = Math.round(step * (1 - padding)); + ranger = {t: "rangeRoundBands", x: x, p: padding}; + return scale; + }; + + scale.rangeBand = function() { + return rangeBand; + }; + + scale.rangeExtent = function() { + return ranger.t === "range" ? d3_scaleExtent(ranger.x) : ranger.x; + }; + + scale.copy = function() { + return d3_scale_ordinal(domain, ranger); + }; + + return scale.domain(domain); +}; +/* + * This product includes color specifications and designs developed by Cynthia + * Brewer (http://colorbrewer.org/). See lib/colorbrewer for more information. + */ + +d3.scale.category10 = function() { + return d3.scale.ordinal().range(d3_category10); +}; + +d3.scale.category20 = function() { + return d3.scale.ordinal().range(d3_category20); +}; + +d3.scale.category20b = function() { + return d3.scale.ordinal().range(d3_category20b); +}; + +d3.scale.category20c = function() { + return d3.scale.ordinal().range(d3_category20c); +}; + +var d3_category10 = [ + "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", + "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf" +]; + +var d3_category20 = [ + "#1f77b4", "#aec7e8", + "#ff7f0e", "#ffbb78", + "#2ca02c", "#98df8a", + "#d62728", "#ff9896", + "#9467bd", "#c5b0d5", + "#8c564b", "#c49c94", + "#e377c2", "#f7b6d2", + "#7f7f7f", "#c7c7c7", + "#bcbd22", "#dbdb8d", + "#17becf", "#9edae5" +]; + +var d3_category20b = [ + "#393b79", "#5254a3", "#6b6ecf", "#9c9ede", + "#637939", "#8ca252", "#b5cf6b", "#cedb9c", + "#8c6d31", "#bd9e39", "#e7ba52", "#e7cb94", + "#843c39", "#ad494a", "#d6616b", "#e7969c", + "#7b4173", "#a55194", "#ce6dbd", "#de9ed6" +]; + +var d3_category20c = [ + "#3182bd", "#6baed6", "#9ecae1", "#c6dbef", + "#e6550d", "#fd8d3c", "#fdae6b", "#fdd0a2", + "#31a354", "#74c476", "#a1d99b", "#c7e9c0", + "#756bb1", "#9e9ac8", "#bcbddc", "#dadaeb", + "#636363", "#969696", "#bdbdbd", "#d9d9d9" +]; +d3.scale.quantile = function() { + return d3_scale_quantile([], []); +}; + +function d3_scale_quantile(domain, range) { + var thresholds; + + function rescale() { + var k = 0, + n = domain.length, + q = range.length; + thresholds = []; + while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); + return scale; + } + + function scale(x) { + if (isNaN(x = +x)) return NaN; + return range[d3.bisect(thresholds, x)]; + } + + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = x.filter(function(d) { return !isNaN(d); }).sort(d3.ascending); + return rescale(); + }; + + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + + scale.quantiles = function() { + return thresholds; + }; + + scale.copy = function() { + return d3_scale_quantile(domain, range); // copy on write! + }; + + return rescale(); +}; +d3.scale.quantize = function() { + return d3_scale_quantize(0, 1, [0, 1]); +}; + +function d3_scale_quantize(x0, x1, range) { + var kx, i; + + function scale(x) { + return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; + } + + function rescale() { + kx = range.length / (x1 - x0); + i = range.length - 1; + return scale; + } + + scale.domain = function(x) { + if (!arguments.length) return [x0, x1]; + x0 = +x[0]; + x1 = +x[x.length - 1]; + return rescale(); + }; + + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + + scale.copy = function() { + return d3_scale_quantize(x0, x1, range); // copy on write + }; + + return rescale(); +}; +d3.svg = {}; +d3.svg.arc = function() { + var innerRadius = d3_svg_arcInnerRadius, + outerRadius = d3_svg_arcOuterRadius, + startAngle = d3_svg_arcStartAngle, + endAngle = d3_svg_arcEndAngle; + + function arc() { + var r0 = innerRadius.apply(this, arguments), + r1 = outerRadius.apply(this, arguments), + a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, + a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, + da = (a1 < a0 && (da = a0, a0 = a1, a1 = da), a1 - a0), + df = da < Math.PI ? "0" : "1", + c0 = Math.cos(a0), + s0 = Math.sin(a0), + c1 = Math.cos(a1), + s1 = Math.sin(a1); + return da >= d3_svg_arcMax + ? (r0 + ? "M0," + r1 + + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1) + + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + + "M0," + r0 + + "A" + r0 + "," + r0 + " 0 1,0 0," + (-r0) + + "A" + r0 + "," + r0 + " 0 1,0 0," + r0 + + "Z" + : "M0," + r1 + + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1) + + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + + "Z") + : (r0 + ? "M" + r1 * c0 + "," + r1 * s0 + + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + + "L" + r0 * c1 + "," + r0 * s1 + + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0 + + "Z" + : "M" + r1 * c0 + "," + r1 * s0 + + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + + "L0,0" + + "Z"); + } + + arc.innerRadius = function(v) { + if (!arguments.length) return innerRadius; + innerRadius = d3.functor(v); + return arc; + }; + + arc.outerRadius = function(v) { + if (!arguments.length) return outerRadius; + outerRadius = d3.functor(v); + return arc; + }; + + arc.startAngle = function(v) { + if (!arguments.length) return startAngle; + startAngle = d3.functor(v); + return arc; + }; + + arc.endAngle = function(v) { + if (!arguments.length) return endAngle; + endAngle = d3.functor(v); + return arc; + }; + + arc.centroid = function() { + var r = (innerRadius.apply(this, arguments) + + outerRadius.apply(this, arguments)) / 2, + a = (startAngle.apply(this, arguments) + + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset; + return [Math.cos(a) * r, Math.sin(a) * r]; + }; + + return arc; +}; + +var d3_svg_arcOffset = -Math.PI / 2, + d3_svg_arcMax = 2 * Math.PI - 1e-6; + +function d3_svg_arcInnerRadius(d) { + return d.innerRadius; +} + +function d3_svg_arcOuterRadius(d) { + return d.outerRadius; +} + +function d3_svg_arcStartAngle(d) { + return d.startAngle; +} + +function d3_svg_arcEndAngle(d) { + return d.endAngle; +} +function d3_svg_line(projection) { + var x = d3_svg_lineX, + y = d3_svg_lineY, + interpolate = "linear", + interpolator = d3_svg_lineInterpolators[interpolate], + tension = .7; + + function line(d) { + return d.length < 1 ? null : "M" + interpolator(projection(d3_svg_linePoints(this, d, x, y)), tension); + } + + line.x = function(v) { + if (!arguments.length) return x; + x = v; + return line; + }; + + line.y = function(v) { + if (!arguments.length) return y; + y = v; + return line; + }; + + line.interpolate = function(v) { + if (!arguments.length) return interpolate; + interpolator = d3_svg_lineInterpolators[interpolate = v]; + return line; + }; + + line.tension = function(v) { + if (!arguments.length) return tension; + tension = v; + return line; + }; + + return line; +} + +d3.svg.line = function() { + return d3_svg_line(Object); +}; + +// Converts the specified array of data into an array of points +// (x-y tuples), by evaluating the specified `x` and `y` functions on each +// data point. The `this` context of the evaluated functions is the specified +// "self" object; each function is passed the current datum and index. +function d3_svg_linePoints(self, d, x, y) { + var points = [], + i = -1, + n = d.length, + fx = typeof x === "function", + fy = typeof y === "function", + value; + if (fx && fy) { + while (++i < n) points.push([ + x.call(self, value = d[i], i), + y.call(self, value, i) + ]); + } else if (fx) { + while (++i < n) points.push([x.call(self, d[i], i), y]); + } else if (fy) { + while (++i < n) points.push([x, y.call(self, d[i], i)]); + } else { + while (++i < n) points.push([x, y]); + } + return points; +} + +// The default `x` property, which references d[0]. +function d3_svg_lineX(d) { + return d[0]; +} + +// The default `y` property, which references d[1]. +function d3_svg_lineY(d) { + return d[1]; +} + +// The various interpolators supported by the `line` class. +var d3_svg_lineInterpolators = { + "linear": d3_svg_lineLinear, + "step-before": d3_svg_lineStepBefore, + "step-after": d3_svg_lineStepAfter, + "basis": d3_svg_lineBasis, + "basis-open": d3_svg_lineBasisOpen, + "basis-closed": d3_svg_lineBasisClosed, + "bundle": d3_svg_lineBundle, + "cardinal": d3_svg_lineCardinal, + "cardinal-open": d3_svg_lineCardinalOpen, + "cardinal-closed": d3_svg_lineCardinalClosed, + "monotone": d3_svg_lineMonotone +}; + +// Linear interpolation; generates "L" commands. +function d3_svg_lineLinear(points) { + var i = 0, + n = points.length, + p = points[0], + path = [p[0], ",", p[1]]; + while (++i < n) path.push("L", (p = points[i])[0], ",", p[1]); + return path.join(""); +} + +// Step interpolation; generates "H" and "V" commands. +function d3_svg_lineStepBefore(points) { + var i = 0, + n = points.length, + p = points[0], + path = [p[0], ",", p[1]]; + while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); + return path.join(""); +} + +// Step interpolation; generates "H" and "V" commands. +function d3_svg_lineStepAfter(points) { + var i = 0, + n = points.length, + p = points[0], + path = [p[0], ",", p[1]]; + while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); + return path.join(""); +} + +// Open cardinal spline interpolation; generates "C" commands. +function d3_svg_lineCardinalOpen(points, tension) { + return points.length < 4 + ? d3_svg_lineLinear(points) + : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), + d3_svg_lineCardinalTangents(points, tension)); +} + +// Closed cardinal spline interpolation; generates "C" commands. +function d3_svg_lineCardinalClosed(points, tension) { + return points.length < 3 + ? d3_svg_lineLinear(points) + : points[0] + d3_svg_lineHermite((points.push(points[0]), points), + d3_svg_lineCardinalTangents([points[points.length - 2]] + .concat(points, [points[1]]), tension)); +} + +// Cardinal spline interpolation; generates "C" commands. +function d3_svg_lineCardinal(points, tension, closed) { + return points.length < 3 + ? d3_svg_lineLinear(points) + : points[0] + d3_svg_lineHermite(points, + d3_svg_lineCardinalTangents(points, tension)); +} + +// Hermite spline construction; generates "C" commands. +function d3_svg_lineHermite(points, tangents) { + if (tangents.length < 1 + || (points.length != tangents.length + && points.length != tangents.length + 2)) { + return d3_svg_lineLinear(points); + } + + var quad = points.length != tangents.length, + path = "", + p0 = points[0], + p = points[1], + t0 = tangents[0], + t = t0, + pi = 1; + + if (quad) { + path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + + "," + p[0] + "," + p[1]; + p0 = points[1]; + pi = 2; + } + + if (tangents.length > 1) { + t = tangents[1]; + p = points[pi]; + pi++; + path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + + "," + p[0] + "," + p[1]; + for (var i = 2; i < tangents.length; i++, pi++) { + p = points[pi]; + t = tangents[i]; + path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + + "," + p[0] + "," + p[1]; + } + } + + if (quad) { + var lp = points[pi]; + path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + + "," + lp[0] + "," + lp[1]; + } + + return path; +} + +// Generates tangents for a cardinal spline. +function d3_svg_lineCardinalTangents(points, tension) { + var tangents = [], + a = (1 - tension) / 2, + p0, + p1 = points[0], + p2 = points[1], + i = 1, + n = points.length; + while (++i < n) { + p0 = p1; + p1 = p2; + p2 = points[i]; + tangents.push([a * (p2[0] - p0[0]), a * (p2[1] - p0[1])]); + } + return tangents; +} + +// B-spline interpolation; generates "C" commands. +function d3_svg_lineBasis(points) { + if (points.length < 3) return d3_svg_lineLinear(points); + var i = 1, + n = points.length, + pi = points[0], + x0 = pi[0], + y0 = pi[1], + px = [x0, x0, x0, (pi = points[1])[0]], + py = [y0, y0, y0, pi[1]], + path = [x0, ",", y0]; + d3_svg_lineBasisBezier(path, px, py); + while (++i < n) { + pi = points[i]; + px.shift(); px.push(pi[0]); + py.shift(); py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + i = -1; + while (++i < 2) { + px.shift(); px.push(pi[0]); + py.shift(); py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + return path.join(""); +} + +// Open B-spline interpolation; generates "C" commands. +function d3_svg_lineBasisOpen(points) { + if (points.length < 4) return d3_svg_lineLinear(points); + var path = [], + i = -1, + n = points.length, + pi, + px = [0], + py = [0]; + while (++i < 3) { + pi = points[i]; + px.push(pi[0]); + py.push(pi[1]); + } + path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); + --i; while (++i < n) { + pi = points[i]; + px.shift(); px.push(pi[0]); + py.shift(); py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + return path.join(""); +} + +// Closed B-spline interpolation; generates "C" commands. +function d3_svg_lineBasisClosed(points) { + var path, + i = -1, + n = points.length, + m = n + 4, + pi, + px = [], + py = []; + while (++i < 4) { + pi = points[i % n]; + px.push(pi[0]); + py.push(pi[1]); + } + path = [ + d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) + ]; + --i; while (++i < m) { + pi = points[i % n]; + px.shift(); px.push(pi[0]); + py.shift(); py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + return path.join(""); +} + +function d3_svg_lineBundle(points, tension) { + var n = points.length - 1, + x0 = points[0][0], + y0 = points[0][1], + dx = points[n][0] - x0, + dy = points[n][1] - y0, + i = -1, + p, + t; + while (++i <= n) { + p = points[i]; + t = i / n; + p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); + p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); + } + return d3_svg_lineBasis(points); +} + +// Returns the dot product of the given four-element vectors. +function d3_svg_lineDot4(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; +} + +// Matrix to transform basis (b-spline) control points to bezier +// control points. Derived from FvD 11.2.8. +var d3_svg_lineBasisBezier1 = [0, 2/3, 1/3, 0], + d3_svg_lineBasisBezier2 = [0, 1/3, 2/3, 0], + d3_svg_lineBasisBezier3 = [0, 1/6, 2/3, 1/6]; + +// Pushes a "C" Bézier curve onto the specified path array, given the +// two specified four-element arrays which define the control points. +function d3_svg_lineBasisBezier(path, x, y) { + path.push( + "C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), + ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), + ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), + ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), + ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), + ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); +} + +// Computes the slope from points p0 to p1. +function d3_svg_lineSlope(p0, p1) { + return (p1[1] - p0[1]) / (p1[0] - p0[0]); +} + +// Compute three-point differences for the given points. +// http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Finite_difference +function d3_svg_lineFiniteDifferences(points) { + var i = 0, + j = points.length - 1, + m = [], + p0 = points[0], + p1 = points[1], + d = m[0] = d3_svg_lineSlope(p0, p1); + while (++i < j) { + m[i] = d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1])); + } + m[i] = d; + return m; +} + +// Interpolates the given points using Fritsch-Carlson Monotone cubic Hermite +// interpolation. Returns an array of tangent vectors. For details, see +// http://en.wikipedia.org/wiki/Monotone_cubic_interpolation +function d3_svg_lineMonotoneTangents(points) { + var tangents = [], + d, + a, + b, + s, + m = d3_svg_lineFiniteDifferences(points), + i = -1, + j = points.length - 1; + + // The first two steps are done by computing finite-differences: + // 1. Compute the slopes of the secant lines between successive points. + // 2. Initialize the tangents at every point as the average of the secants. + + // Then, for each segment… + while (++i < j) { + d = d3_svg_lineSlope(points[i], points[i + 1]); + + // 3. If two successive yk = y{k + 1} are equal (i.e., d is zero), then set + // mk = m{k + 1} = 0 as the spline connecting these points must be flat to + // preserve monotonicity. Ignore step 4 and 5 for those k. + + if (Math.abs(d) < 1e-6) { + m[i] = m[i + 1] = 0; + } else { + // 4. Let ak = mk / dk and bk = m{k + 1} / dk. + a = m[i] / d; + b = m[i + 1] / d; + + // 5. Prevent overshoot and ensure monotonicity by restricting the + // magnitude of vector to a circle of radius 3. + s = a * a + b * b; + if (s > 9) { + s = d * 3 / Math.sqrt(s); + m[i] = s * a; + m[i + 1] = s * b; + } + } + } + + // Compute the normalized tangent vector from the slopes. Note that if x is + // not monotonic, it's possible that the slope will be infinite, so we protect + // against NaN by setting the coordinate to zero. + i = -1; while (++i <= j) { + s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) + / (6 * (1 + m[i] * m[i])); + tangents.push([s || 0, m[i] * s || 0]); + } + + return tangents; +} + +function d3_svg_lineMonotone(points) { + return points.length < 3 + ? d3_svg_lineLinear(points) + : points[0] + + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); +} +d3.svg.line.radial = function() { + var line = d3_svg_line(d3_svg_lineRadial); + line.radius = line.x, delete line.x; + line.angle = line.y, delete line.y; + return line; +}; + +function d3_svg_lineRadial(points) { + var point, + i = -1, + n = points.length, + r, + a; + while (++i < n) { + point = points[i]; + r = point[0]; + a = point[1] + d3_svg_arcOffset; + point[0] = r * Math.cos(a); + point[1] = r * Math.sin(a); + } + return points; +} +function d3_svg_area(projection) { + var x0 = d3_svg_lineX, + x1 = d3_svg_lineX, + y0 = 0, + y1 = d3_svg_lineY, + interpolate, + i0, + i1, + tension = .7; + + function area(d) { + if (d.length < 1) return null; + var points0 = d3_svg_linePoints(this, d, x0, y0), + points1 = d3_svg_linePoints(this, d, x0 === x1 ? d3_svg_areaX(points0) : x1, y0 === y1 ? d3_svg_areaY(points0) : y1); + return "M" + i0(projection(points1), tension) + + "L" + i1(projection(points0.reverse()), tension) + + "Z"; + } + + area.x = function(x) { + if (!arguments.length) return x1; + x0 = x1 = x; + return area; + }; + + area.x0 = function(x) { + if (!arguments.length) return x0; + x0 = x; + return area; + }; + + area.x1 = function(x) { + if (!arguments.length) return x1; + x1 = x; + return area; + }; + + area.y = function(y) { + if (!arguments.length) return y1; + y0 = y1 = y; + return area; + }; + + area.y0 = function(y) { + if (!arguments.length) return y0; + y0 = y; + return area; + }; + + area.y1 = function(y) { + if (!arguments.length) return y1; + y1 = y; + return area; + }; + + area.interpolate = function(x) { + if (!arguments.length) return interpolate; + i0 = d3_svg_lineInterpolators[interpolate = x]; + i1 = i0.reverse || i0; + return area; + }; + + area.tension = function(x) { + if (!arguments.length) return tension; + tension = x; + return area; + }; + + return area.interpolate("linear"); +} + +d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; +d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; + +d3.svg.area = function() { + return d3_svg_area(Object); +}; + +function d3_svg_areaX(points) { + return function(d, i) { + return points[i][0]; + }; +} + +function d3_svg_areaY(points) { + return function(d, i) { + return points[i][1]; + }; +} +d3.svg.area.radial = function() { + var area = d3_svg_area(d3_svg_lineRadial); + area.radius = area.x, delete area.x; + area.innerRadius = area.x0, delete area.x0; + area.outerRadius = area.x1, delete area.x1; + area.angle = area.y, delete area.y; + area.startAngle = area.y0, delete area.y0; + area.endAngle = area.y1, delete area.y1; + return area; +}; +d3.svg.chord = function() { + var source = d3_svg_chordSource, + target = d3_svg_chordTarget, + radius = d3_svg_chordRadius, + startAngle = d3_svg_arcStartAngle, + endAngle = d3_svg_arcEndAngle; + + // TODO Allow control point to be customized. + + function chord(d, i) { + var s = subgroup(this, source, d, i), + t = subgroup(this, target, d, i); + return "M" + s.p0 + + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) + ? curve(s.r, s.p1, s.r, s.p0) + : curve(s.r, s.p1, t.r, t.p0) + + arc(t.r, t.p1, t.a1 - t.a0) + + curve(t.r, t.p1, s.r, s.p0)) + + "Z"; + } + + function subgroup(self, f, d, i) { + var subgroup = f.call(self, d, i), + r = radius.call(self, subgroup, i), + a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset, + a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset; + return { + r: r, + a0: a0, + a1: a1, + p0: [r * Math.cos(a0), r * Math.sin(a0)], + p1: [r * Math.cos(a1), r * Math.sin(a1)] + }; + } + + function equals(a, b) { + return a.a0 == b.a0 && a.a1 == b.a1; + } + + function arc(r, p, a) { + return "A" + r + "," + r + " 0 " + +(a > Math.PI) + ",1 " + p; + } + + function curve(r0, p0, r1, p1) { + return "Q 0,0 " + p1; + } + + chord.radius = function(v) { + if (!arguments.length) return radius; + radius = d3.functor(v); + return chord; + }; + + chord.source = function(v) { + if (!arguments.length) return source; + source = d3.functor(v); + return chord; + }; + + chord.target = function(v) { + if (!arguments.length) return target; + target = d3.functor(v); + return chord; + }; + + chord.startAngle = function(v) { + if (!arguments.length) return startAngle; + startAngle = d3.functor(v); + return chord; + }; + + chord.endAngle = function(v) { + if (!arguments.length) return endAngle; + endAngle = d3.functor(v); + return chord; + }; + + return chord; +}; + +function d3_svg_chordSource(d) { + return d.source; +} + +function d3_svg_chordTarget(d) { + return d.target; +} + +function d3_svg_chordRadius(d) { + return d.radius; +} + +function d3_svg_chordStartAngle(d) { + return d.startAngle; +} + +function d3_svg_chordEndAngle(d) { + return d.endAngle; +} +d3.svg.diagonal = function() { + var source = d3_svg_chordSource, + target = d3_svg_chordTarget, + projection = d3_svg_diagonalProjection; + + function diagonal(d, i) { + var p0 = source.call(this, d, i), + p3 = target.call(this, d, i), + m = (p0.y + p3.y) / 2, + p = [p0, {x: p0.x, y: m}, {x: p3.x, y: m}, p3]; + p = p.map(projection); + return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; + } + + diagonal.source = function(x) { + if (!arguments.length) return source; + source = d3.functor(x); + return diagonal; + }; + + diagonal.target = function(x) { + if (!arguments.length) return target; + target = d3.functor(x); + return diagonal; + }; + + diagonal.projection = function(x) { + if (!arguments.length) return projection; + projection = x; + return diagonal; + }; + + return diagonal; +}; + +function d3_svg_diagonalProjection(d) { + return [d.x, d.y]; +} +d3.svg.diagonal.radial = function() { + var diagonal = d3.svg.diagonal(), + projection = d3_svg_diagonalProjection, + projection_ = diagonal.projection; + + diagonal.projection = function(x) { + return arguments.length + ? projection_(d3_svg_diagonalRadialProjection(projection = x)) + : projection; + }; + + return diagonal; +}; + +function d3_svg_diagonalRadialProjection(projection) { + return function() { + var d = projection.apply(this, arguments), + r = d[0], + a = d[1] + d3_svg_arcOffset; + return [r * Math.cos(a), r * Math.sin(a)]; + }; +} +d3.svg.mouse = function(container) { + return d3_svg_mousePoint(container, d3.event); +}; + +// https://bugs.webkit.org/show_bug.cgi?id=44083 +var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0; + +function d3_svg_mousePoint(container, e) { + var point = (container.ownerSVGElement || container).createSVGPoint(); + if ((d3_mouse_bug44083 < 0) && (window.scrollX || window.scrollY)) { + var svg = d3.select(document.body) + .append("svg") + .style("position", "absolute") + .style("top", 0) + .style("left", 0); + var ctm = svg[0][0].getScreenCTM(); + d3_mouse_bug44083 = !(ctm.f || ctm.e); + svg.remove(); + } + if (d3_mouse_bug44083) { + point.x = e.pageX; + point.y = e.pageY; + } else { + point.x = e.clientX; + point.y = e.clientY; + } + point = point.matrixTransform(container.getScreenCTM().inverse()); + return [point.x, point.y]; +}; +d3.svg.touches = function(container, touches) { + if (arguments.length < 2) touches = d3.event.touches; + + return touches ? d3_array(touches).map(function(touch) { + var point = d3_svg_mousePoint(container, touch); + point.identifier = touch.identifier; + return point; + }) : []; +}; +d3.svg.symbol = function() { + var type = d3_svg_symbolType, + size = d3_svg_symbolSize; + + function symbol(d, i) { + return (d3_svg_symbols[type.call(this, d, i)] + || d3_svg_symbols.circle) + (size.call(this, d, i)); + } + + symbol.type = function(x) { + if (!arguments.length) return type; + type = d3.functor(x); + return symbol; + }; + + // size of symbol in square pixels + symbol.size = function(x) { + if (!arguments.length) return size; + size = d3.functor(x); + return symbol; + }; + + return symbol; +}; + +function d3_svg_symbolSize() { + return 64; +} + +function d3_svg_symbolType() { + return "circle"; +} + +// TODO cross-diagonal? +var d3_svg_symbols = { + "circle": function(size) { + var r = Math.sqrt(size / Math.PI); + return "M0," + r + + "A" + r + "," + r + " 0 1,1 0," + (-r) + + "A" + r + "," + r + " 0 1,1 0," + r + + "Z"; + }, + "cross": function(size) { + var r = Math.sqrt(size / 5) / 2; + return "M" + -3 * r + "," + -r + + "H" + -r + + "V" + -3 * r + + "H" + r + + "V" + -r + + "H" + 3 * r + + "V" + r + + "H" + r + + "V" + 3 * r + + "H" + -r + + "V" + r + + "H" + -3 * r + + "Z"; + }, + "diamond": function(size) { + var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), + rx = ry * d3_svg_symbolTan30; + return "M0," + -ry + + "L" + rx + ",0" + + " 0," + ry + + " " + -rx + ",0" + + "Z"; + }, + "square": function(size) { + var r = Math.sqrt(size) / 2; + return "M" + -r + "," + -r + + "L" + r + "," + -r + + " " + r + "," + r + + " " + -r + "," + r + + "Z"; + }, + "triangle-down": function(size) { + var rx = Math.sqrt(size / d3_svg_symbolSqrt3), + ry = rx * d3_svg_symbolSqrt3 / 2; + return "M0," + ry + + "L" + rx +"," + -ry + + " " + -rx + "," + -ry + + "Z"; + }, + "triangle-up": function(size) { + var rx = Math.sqrt(size / d3_svg_symbolSqrt3), + ry = rx * d3_svg_symbolSqrt3 / 2; + return "M0," + -ry + + "L" + rx +"," + ry + + " " + -rx + "," + ry + + "Z"; + } +}; + +d3.svg.symbolTypes = d3.keys(d3_svg_symbols); + +var d3_svg_symbolSqrt3 = Math.sqrt(3), + d3_svg_symbolTan30 = Math.tan(30 * Math.PI / 180); +d3.svg.axis = function() { + var scale = d3.scale.linear(), + orient = "bottom", + tickMajorSize = 6, + tickMinorSize = 6, + tickEndSize = 6, + tickPadding = 3, + tickArguments_ = [10], + tickFormat_, + tickSubdivide = 0; + + function axis(selection) { + selection.each(function(d, i, j) { + var g = d3.select(this); + + // If selection is a transition, create subtransitions. + var transition = selection.delay ? function(o) { + var id = d3_transitionInheritId; + try { + d3_transitionInheritId = selection.id; + return o.transition() + .delay(selection[j][i].delay) + .duration(selection[j][i].duration) + .ease(selection.ease()); + } finally { + d3_transitionInheritId = id; + } + } : Object; + + // Ticks, or domain values for ordinal scales. + var ticks = scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain(), + tickFormat = tickFormat_ == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : String) : tickFormat_; + + // Minor ticks. + var subticks = d3_svg_axisSubdivide(scale, ticks, tickSubdivide), + subtick = g.selectAll(".minor").data(subticks, String), + subtickEnter = subtick.enter().insert("line", "g").attr("class", "tick minor").style("opacity", 1e-6), + subtickExit = transition(subtick.exit()).style("opacity", 1e-6).remove(), + subtickUpdate = transition(subtick).style("opacity", 1); + + // Major ticks. + var tick = g.selectAll("g").data(ticks, String), + tickEnter = tick.enter().insert("g", "path").style("opacity", 1e-6), + tickExit = transition(tick.exit()).style("opacity", 1e-6).remove(), + tickUpdate = transition(tick).style("opacity", 1), + tickTransform; + + // Domain. + var range = d3_scaleRange(scale), + path = g.selectAll(".domain").data([0]), + pathEnter = path.enter().append("path").attr("class", "domain"), + pathUpdate = transition(path); + + // Stash a snapshot of the new scale, and retrieve the old snapshot. + var scale1 = scale.copy(), + scale0 = this.__chart__ || scale1; + this.__chart__ = scale1; + + tickEnter.append("line").attr("class", "tick"); + tickEnter.append("text"); + tickUpdate.select("text").text(tickFormat); + + switch (orient) { + case "bottom": { + tickTransform = d3_svg_axisX; + subtickEnter.attr("y2", tickMinorSize); + subtickUpdate.attr("x2", 0).attr("y2", tickMinorSize); + tickEnter.select("line").attr("y2", tickMajorSize); + tickEnter.select("text").attr("y", Math.max(tickMajorSize, 0) + tickPadding); + tickUpdate.select("line").attr("x2", 0).attr("y2", tickMajorSize); + tickUpdate.select("text").attr("x", 0).attr("y", Math.max(tickMajorSize, 0) + tickPadding).attr("dy", ".71em").attr("text-anchor", "middle"); + pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize); + break; + } + case "top": { + tickTransform = d3_svg_axisX; + subtickEnter.attr("y2", -tickMinorSize); + subtickUpdate.attr("x2", 0).attr("y2", -tickMinorSize); + tickEnter.select("line").attr("y2", -tickMajorSize); + tickEnter.select("text").attr("y", -(Math.max(tickMajorSize, 0) + tickPadding)); + tickUpdate.select("line").attr("x2", 0).attr("y2", -tickMajorSize); + tickUpdate.select("text").attr("x", 0).attr("y", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("dy", "0em").attr("text-anchor", "middle"); + pathUpdate.attr("d", "M" + range[0] + "," + -tickEndSize + "V0H" + range[1] + "V" + -tickEndSize); + break; + } + case "left": { + tickTransform = d3_svg_axisY; + subtickEnter.attr("x2", -tickMinorSize); + subtickUpdate.attr("x2", -tickMinorSize).attr("y2", 0); + tickEnter.select("line").attr("x2", -tickMajorSize); + tickEnter.select("text").attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)); + tickUpdate.select("line").attr("x2", -tickMajorSize).attr("y2", 0); + tickUpdate.select("text").attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("y", 0).attr("dy", ".32em").attr("text-anchor", "end"); + pathUpdate.attr("d", "M" + -tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + -tickEndSize); + break; + } + case "right": { + tickTransform = d3_svg_axisY; + subtickEnter.attr("x2", tickMinorSize); + subtickUpdate.attr("x2", tickMinorSize).attr("y2", 0); + tickEnter.select("line").attr("x2", tickMajorSize); + tickEnter.select("text").attr("x", Math.max(tickMajorSize, 0) + tickPadding); + tickUpdate.select("line").attr("x2", tickMajorSize).attr("y2", 0); + tickUpdate.select("text").attr("x", Math.max(tickMajorSize, 0) + tickPadding).attr("y", 0).attr("dy", ".32em").attr("text-anchor", "start"); + pathUpdate.attr("d", "M" + tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + tickEndSize); + break; + } + } + + // For quantitative scales: + // - enter new ticks from the old scale + // - exit old ticks to the new scale + if (scale.ticks) { + tickEnter.call(tickTransform, scale0); + tickUpdate.call(tickTransform, scale1); + tickExit.call(tickTransform, scale1); + subtickEnter.call(tickTransform, scale0); + subtickUpdate.call(tickTransform, scale1); + subtickExit.call(tickTransform, scale1); + } + + // For ordinal scales: + // - any entering ticks are undefined in the old scale + // - any exiting ticks are undefined in the new scale + // Therefore, we only need to transition updating ticks. + else { + var dx = scale1.rangeBand() / 2, x = function(d) { return scale1(d) + dx; }; + tickEnter.call(tickTransform, x); + tickUpdate.call(tickTransform, x); + } + }); + } + + axis.scale = function(x) { + if (!arguments.length) return scale; + scale = x; + return axis; + }; + + axis.orient = function(x) { + if (!arguments.length) return orient; + orient = x; + return axis; + }; + + axis.ticks = function() { + if (!arguments.length) return tickArguments_; + tickArguments_ = arguments; + return axis; + }; + + axis.tickFormat = function(x) { + if (!arguments.length) return tickFormat_; + tickFormat_ = x; + return axis; + }; + + axis.tickSize = function(x, y, z) { + if (!arguments.length) return tickMajorSize; + var n = arguments.length - 1; + tickMajorSize = +x; + tickMinorSize = n > 1 ? +y : tickMajorSize; + tickEndSize = n > 0 ? +arguments[n] : tickMajorSize; + return axis; + }; + + axis.tickPadding = function(x) { + if (!arguments.length) return tickPadding; + tickPadding = +x; + return axis; + }; + + axis.tickSubdivide = function(x) { + if (!arguments.length) return tickSubdivide; + tickSubdivide = +x; + return axis; + }; + + return axis; +}; + +function d3_svg_axisX(selection, x) { + selection.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; }); +} + +function d3_svg_axisY(selection, y) { + selection.attr("transform", function(d) { return "translate(0," + y(d) + ")"; }); +} + +function d3_svg_axisSubdivide(scale, ticks, m) { + subticks = []; + if (m && ticks.length > 1) { + var extent = d3_scaleExtent(scale.domain()), + subticks, + i = -1, + n = ticks.length, + d = (ticks[1] - ticks[0]) / ++m, + j, + v; + while (++i < n) { + for (j = m; --j > 0;) { + if ((v = +ticks[i] - j * d) >= extent[0]) { + subticks.push(v); + } + } + } + for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) { + subticks.push(v); + } + } + return subticks; +} +d3.svg.brush = function() { + var event = d3.dispatch("brushstart", "brush", "brushend"), + x, // x-scale, optional + y, // y-scale, optional + extent = [[0, 0], [0, 0]]; // [x0, y0], [x1, y1] + + function brush(g) { + var resizes = x && y ? ["n", "e", "s", "w", "nw", "ne", "se", "sw"] + : x ? ["e", "w"] + : y ? ["n", "s"] + : []; + + g.each(function() { + var g = d3.select(this).on("mousedown.brush", down), + bg = g.selectAll(".background").data([0]), + fg = g.selectAll(".extent").data([0]), + tz = g.selectAll(".resize").data(resizes, String), + e; + + // An invisible, mouseable area for starting a new brush. + bg.enter().append("rect") + .attr("class", "background") + .style("visibility", "hidden") + .style("pointer-events", "all") + .style("cursor", "crosshair"); + + // The visible brush extent; style this as you like! + fg.enter().append("rect") + .attr("class", "extent") + .style("cursor", "move"); + + // More invisible rects for resizing the extent. + tz.enter().append("rect") + .attr("class", function(d) { return "resize " + d; }) + .attr("width", 6) + .attr("height", 6) + .style("visibility", "hidden") + .style("cursor", function(d) { return d3_svg_brushCursor[d]; }); + + // Update the resizers. + tz.style("pointer-events", brush.empty() ? "none" : "all"); + + // Remove any superfluous resizers. + tz.exit().remove(); + + // Initialize the background to fill the defined range. + // If the range isn't defined, you can post-process. + if (x) { + e = d3_scaleRange(x); + bg.attr("x", e[0]).attr("width", e[1] - e[0]); + d3_svg_brushRedrawX(g, extent); + } + if (y) { + e = d3_scaleRange(y); + bg.attr("y", e[0]).attr("height", e[1] - e[0]); + d3_svg_brushRedrawY(g, extent); + } + }); + } + + function down() { + var target = d3.select(d3.event.target); + + // Store some global state for the duration of the brush gesture. + d3_svg_brush = brush; + d3_svg_brushTarget = this; + d3_svg_brushExtent = extent; + d3_svg_brushOffset = d3.svg.mouse(d3_svg_brushTarget); + + // If the extent was clicked on, drag rather than brush; + // store the offset between the mouse and extent origin instead. + if (d3_svg_brushDrag = target.classed("extent")) { + d3_svg_brushOffset[0] = extent[0][0] - d3_svg_brushOffset[0]; + d3_svg_brushOffset[1] = extent[0][1] - d3_svg_brushOffset[1]; + } + + // If a resizer was clicked on, record which side is to be resized. + // Also, set the offset to the opposite side. + else if (target.classed("resize")) { + d3_svg_brushResize = d3.event.target.__data__; + d3_svg_brushOffset[0] = extent[+/w$/.test(d3_svg_brushResize)][0]; + d3_svg_brushOffset[1] = extent[+/^n/.test(d3_svg_brushResize)][1]; + } + + // If the ALT key is down when starting a brush, the center is at the mouse. + else if (d3.event.altKey) { + d3_svg_brushCenter = d3_svg_brushOffset.slice(); + } + + // Restrict which dimensions are resized. + d3_svg_brushX = !/^(n|s)$/.test(d3_svg_brushResize) && x; + d3_svg_brushY = !/^(e|w)$/.test(d3_svg_brushResize) && y; + + // Notify listeners. + d3_svg_brushDispatch = dispatcher(this, arguments); + d3_svg_brushDispatch("brushstart"); + d3_svg_brushMove(); + d3_eventCancel(); + } + + function dispatcher(that, argumentz) { + return function(type) { + var e = d3.event; + try { + d3.event = {type: type, target: brush}; + event[type].apply(that, argumentz); + } finally { + d3.event = e; + } + }; + } + + brush.x = function(z) { + if (!arguments.length) return x; + x = z; + return brush; + }; + + brush.y = function(z) { + if (!arguments.length) return y; + y = z; + return brush; + }; + + brush.extent = function(z) { + var x0, x1, y0, y1, t; + + // Invert the pixel extent to data-space. + if (!arguments.length) { + if (x) { + x0 = extent[0][0], x1 = extent[1][0]; + if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); + if (x1 < x0) t = x0, x0 = x1, x1 = t; + } + if (y) { + y0 = extent[0][1], y1 = extent[1][1]; + if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); + if (y1 < y0) t = y0, y0 = y1, y1 = t; + } + return x && y ? [[x0, y0], [x1, y1]] : x ? [x0, x1] : y && [y0, y1]; + } + + // Scale the data-space extent to pixels. + if (x) { + x0 = z[0], x1 = z[1]; + if (y) x0 = x0[0], x1 = x1[0]; + if (x.invert) x0 = x(x0), x1 = x(x1); + if (x1 < x0) t = x0, x0 = x1, x1 = t; + extent[0][0] = x0, extent[1][0] = x1; + } + if (y) { + y0 = z[0], y1 = z[1]; + if (x) y0 = y0[1], y1 = y1[1]; + if (y.invert) y0 = y(y0), y1 = y(y1); + if (y1 < y0) t = y0, y0 = y1, y1 = t; + extent[0][1] = y0, extent[1][1] = y1; + } + + return brush; + }; + + brush.clear = function() { + extent[0][0] = + extent[0][1] = + extent[1][0] = + extent[1][1] = 0; + return brush; + }; + + brush.empty = function() { + return (x && extent[0][0] === extent[1][0]) + || (y && extent[0][1] === extent[1][1]); + }; + + d3.select(window) + .on("mousemove.brush", d3_svg_brushMove) + .on("mouseup.brush", d3_svg_brushUp) + .on("keydown.brush", d3_svg_brushKeydown) + .on("keyup.brush", d3_svg_brushKeyup); + + return d3.rebind(brush, event, "on"); +}; + +var d3_svg_brush, + d3_svg_brushDispatch, + d3_svg_brushTarget, + d3_svg_brushX, + d3_svg_brushY, + d3_svg_brushExtent, + d3_svg_brushDrag, + d3_svg_brushResize, + d3_svg_brushCenter, + d3_svg_brushOffset; + +function d3_svg_brushRedrawX(g, extent) { + g.select(".extent").attr("x", extent[0][0]); + g.selectAll(".n,.s,.w,.nw,.sw").attr("x", extent[0][0] - 2); + g.selectAll(".e,.ne,.se").attr("x", extent[1][0] - 3); + g.selectAll(".extent,.n,.s").attr("width", extent[1][0] - extent[0][0]); +} + +function d3_svg_brushRedrawY(g, extent) { + g.select(".extent").attr("y", extent[0][1]); + g.selectAll(".n,.e,.w,.nw,.ne").attr("y", extent[0][1] - 3); + g.selectAll(".s,.se,.sw").attr("y", extent[1][1] - 4); + g.selectAll(".extent,.e,.w").attr("height", extent[1][1] - extent[0][1]); +} + +function d3_svg_brushKeydown() { + if (d3.event.keyCode == 32 && d3_svg_brushTarget && !d3_svg_brushDrag) { + d3_svg_brushCenter = null; + d3_svg_brushOffset[0] -= d3_svg_brushExtent[1][0]; + d3_svg_brushOffset[1] -= d3_svg_brushExtent[1][1]; + d3_svg_brushDrag = 2; + d3_eventCancel(); + } +} + +function d3_svg_brushKeyup() { + if (d3.event.keyCode == 32 && d3_svg_brushDrag == 2) { + d3_svg_brushOffset[0] += d3_svg_brushExtent[1][0]; + d3_svg_brushOffset[1] += d3_svg_brushExtent[1][1]; + d3_svg_brushDrag = 0; + d3_eventCancel(); + } +} + +function d3_svg_brushMove() { + if (d3_svg_brushOffset) { + var mouse = d3.svg.mouse(d3_svg_brushTarget), + g = d3.select(d3_svg_brushTarget); + + if (!d3_svg_brushDrag) { + + // If needed, determine the center from the current extent. + if (d3.event.altKey) { + if (!d3_svg_brushCenter) { + d3_svg_brushCenter = [ + (d3_svg_brushExtent[0][0] + d3_svg_brushExtent[1][0]) / 2, + (d3_svg_brushExtent[0][1] + d3_svg_brushExtent[1][1]) / 2 + ]; + } + + // Update the offset, for when the ALT key is released. + d3_svg_brushOffset[0] = d3_svg_brushExtent[+(mouse[0] < d3_svg_brushCenter[0])][0]; + d3_svg_brushOffset[1] = d3_svg_brushExtent[+(mouse[1] < d3_svg_brushCenter[1])][1]; + } + + // When the ALT key is released, we clear the center. + else d3_svg_brushCenter = null; + } + + // Update the brush extent for each dimension. + if (d3_svg_brushX) { + d3_svg_brushMove1(mouse, d3_svg_brushX, 0); + d3_svg_brushRedrawX(g, d3_svg_brushExtent); + } + if (d3_svg_brushY) { + d3_svg_brushMove1(mouse, d3_svg_brushY, 1); + d3_svg_brushRedrawY(g, d3_svg_brushExtent); + } + + // Notify listeners. + d3_svg_brushDispatch("brush"); + } +} + +function d3_svg_brushMove1(mouse, scale, i) { + var range = d3_scaleRange(scale), + r0 = range[0], + r1 = range[1], + offset = d3_svg_brushOffset[i], + size = d3_svg_brushExtent[1][i] - d3_svg_brushExtent[0][i], + min, + max; + + // When dragging, reduce the range by the extent size and offset. + if (d3_svg_brushDrag) { + r0 -= offset; + r1 -= size + offset; + } + + // Clamp the mouse so that the extent fits within the range extent. + min = Math.max(r0, Math.min(r1, mouse[i])); + + // Compute the new extent bounds. + if (d3_svg_brushDrag) { + max = (min += offset) + size; + } else { + + // If the ALT key is pressed, then preserve the center of the extent. + if (d3_svg_brushCenter) offset = Math.max(r0, Math.min(r1, 2 * d3_svg_brushCenter[i] - min)); + + // Compute the min and max of the offset and mouse. + if (offset < min) { + max = min; + min = offset; + } else { + max = offset; + } + } + + // Update the stored bounds. + d3_svg_brushExtent[0][i] = min; + d3_svg_brushExtent[1][i] = max; +} + +function d3_svg_brushUp() { + if (d3_svg_brushOffset) { + d3_svg_brushMove(); + d3.select(d3_svg_brushTarget).selectAll(".resize").style("pointer-events", d3_svg_brush.empty() ? "none" : "all"); + d3_svg_brushDispatch("brushend"); + d3_svg_brush = + d3_svg_brushDispatch = + d3_svg_brushTarget = + d3_svg_brushX = + d3_svg_brushY = + d3_svg_brushExtent = + d3_svg_brushDrag = + d3_svg_brushResize = + d3_svg_brushCenter = + d3_svg_brushOffset = null; + d3_eventCancel(); + } +} + +var d3_svg_brushCursor = { + n: "ns-resize", + e: "ew-resize", + s: "ns-resize", + w: "ew-resize", + nw: "nwse-resize", + ne: "nesw-resize", + se: "nwse-resize", + sw: "nesw-resize" +}; +d3.behavior = {}; +// TODO Track touch points by identifier. + +d3.behavior.drag = function() { + var event = d3.dispatch("drag", "dragstart", "dragend"), + origin = null; + + function drag() { + this + .on("mousedown.drag", mousedown) + .on("touchstart.drag", mousedown); + + d3.select(window) + .on("mousemove.drag", d3_behavior_dragMove) + .on("touchmove.drag", d3_behavior_dragMove) + .on("mouseup.drag", d3_behavior_dragUp, true) + .on("touchend.drag", d3_behavior_dragUp, true) + .on("click.drag", d3_behavior_dragClick, true); + } + + // snapshot the local context for subsequent dispatch + function start() { + d3_behavior_dragEvent = event; + d3_behavior_dragEventTarget = d3.event.target; + d3_behavior_dragTarget = this; + d3_behavior_dragArguments = arguments; + d3_behavior_dragOrigin = d3_behavior_dragPoint(); + if (origin) { + d3_behavior_dragOffset = origin.apply(d3_behavior_dragTarget, d3_behavior_dragArguments); + d3_behavior_dragOffset = [d3_behavior_dragOffset.x - d3_behavior_dragOrigin[0], d3_behavior_dragOffset.y - d3_behavior_dragOrigin[1]]; + } else { + d3_behavior_dragOffset = [0, 0]; + } + d3_behavior_dragMoved = 0; + } + + function mousedown() { + start.apply(this, arguments); + d3_behavior_dragDispatch("dragstart"); + } + + drag.origin = function(x) { + if (!arguments.length) return origin; + origin = x; + return drag; + }; + + return d3.rebind(drag, event, "on"); +}; + +var d3_behavior_dragEvent, + d3_behavior_dragEventTarget, + d3_behavior_dragTarget, + d3_behavior_dragArguments, + d3_behavior_dragOffset, + d3_behavior_dragOrigin, + d3_behavior_dragMoved; + +function d3_behavior_dragDispatch(type) { + var p = d3_behavior_dragPoint(), + o = d3.event, + e = d3.event = {type: type}; + + if (p) { + e.x = p[0] + d3_behavior_dragOffset[0]; + e.y = p[1] + d3_behavior_dragOffset[1]; + e.dx = p[0] - d3_behavior_dragOrigin[0]; + e.dy = p[1] - d3_behavior_dragOrigin[1]; + d3_behavior_dragMoved |= e.dx | e.dy; + d3_behavior_dragOrigin = p; + } + + try { + d3_behavior_dragEvent[type].apply(d3_behavior_dragTarget, d3_behavior_dragArguments); + } finally { + d3.event = o; + } + + o.stopPropagation(); + o.preventDefault(); +} + +function d3_behavior_dragPoint() { + var p = d3_behavior_dragTarget.parentNode, + t = d3.event.changedTouches; + return p && (t + ? d3.svg.touches(p, t)[0] + : d3.svg.mouse(p)); +} + +function d3_behavior_dragMove() { + if (!d3_behavior_dragTarget) return; + var parent = d3_behavior_dragTarget.parentNode; + + // O NOES! The drag element was removed from the DOM. + if (!parent) return d3_behavior_dragUp(); + + d3_behavior_dragDispatch("drag"); + d3_eventCancel(); +} + +function d3_behavior_dragUp() { + if (!d3_behavior_dragTarget) return; + d3_behavior_dragDispatch("dragend"); + + // If the node was moved, prevent the mouseup from propagating. + // Also prevent the subsequent click from propagating (e.g., for anchors). + if (d3_behavior_dragMoved) { + d3_eventCancel(); + d3_behavior_dragMoved = d3.event.target === d3_behavior_dragEventTarget; + } + + d3_behavior_dragEvent = + d3_behavior_dragEventTarget = + d3_behavior_dragTarget = + d3_behavior_dragArguments = + d3_behavior_dragOffset = + d3_behavior_dragOrigin = null; +} + +function d3_behavior_dragClick() { + if (d3_behavior_dragMoved) { + d3_eventCancel(); + d3_behavior_dragMoved = 0; + } +} +// TODO unbind zoom behavior? +d3.behavior.zoom = function() { + var xyz = [0, 0, 0], + event = d3.dispatch("zoom"), + extent = d3_behavior_zoomInfiniteExtent; + + function zoom() { + this + .on("mousedown.zoom", mousedown) + .on("mousewheel.zoom", mousewheel) + .on("DOMMouseScroll.zoom", mousewheel) + .on("dblclick.zoom", dblclick) + .on("touchstart.zoom", touchstart); + + d3.select(window) + .on("mousemove.zoom", d3_behavior_zoomMousemove) + .on("mouseup.zoom", d3_behavior_zoomMouseup) + .on("touchmove.zoom", d3_behavior_zoomTouchmove) + .on("touchend.zoom", d3_behavior_zoomTouchup) + .on("click.zoom", d3_behavior_zoomClick, true); + } + + // snapshot the local context for subsequent dispatch + function start() { + d3_behavior_zoomXyz = xyz; + d3_behavior_zoomExtent = extent; + d3_behavior_zoomDispatch = event.zoom; + d3_behavior_zoomEventTarget = d3.event.target; + d3_behavior_zoomTarget = this; + d3_behavior_zoomArguments = arguments; + } + + function mousedown() { + start.apply(this, arguments); + d3_behavior_zoomPanning = d3_behavior_zoomLocation(d3.svg.mouse(d3_behavior_zoomTarget)); + d3_behavior_zoomMoved = 0; + d3.event.preventDefault(); + window.focus(); + } + + // store starting mouse location + function mousewheel() { + start.apply(this, arguments); + if (!d3_behavior_zoomZooming) d3_behavior_zoomZooming = d3_behavior_zoomLocation(d3.svg.mouse(d3_behavior_zoomTarget)); + d3_behavior_zoomTo(d3_behavior_zoomDelta() + xyz[2], d3.svg.mouse(d3_behavior_zoomTarget), d3_behavior_zoomZooming); + } + + function dblclick() { + start.apply(this, arguments); + var mouse = d3.svg.mouse(d3_behavior_zoomTarget); + d3_behavior_zoomTo(d3.event.shiftKey ? Math.ceil(xyz[2] - 1) : Math.floor(xyz[2] + 1), mouse, d3_behavior_zoomLocation(mouse)); + } + + // doubletap detection + function touchstart() { + start.apply(this, arguments); + var touches = d3_behavior_zoomTouchup(), + touch, + now = Date.now(); + if ((touches.length === 1) && (now - d3_behavior_zoomLast < 300)) { + d3_behavior_zoomTo(1 + Math.floor(xyz[2]), touch = touches[0], d3_behavior_zoomLocations[touch.identifier]); + } + d3_behavior_zoomLast = now; + } + + zoom.extent = function(x) { + if (!arguments.length) return extent; + extent = x == null ? d3_behavior_zoomInfiniteExtent : x; + return zoom; + }; + + return d3.rebind(zoom, event, "on"); +}; + +var d3_behavior_zoomDiv, + d3_behavior_zoomPanning, + d3_behavior_zoomZooming, + d3_behavior_zoomLocations = {}, // identifier -> location + d3_behavior_zoomLast = 0, + d3_behavior_zoomXyz, + d3_behavior_zoomExtent, + d3_behavior_zoomDispatch, + d3_behavior_zoomEventTarget, + d3_behavior_zoomTarget, + d3_behavior_zoomArguments, + d3_behavior_zoomMoved; + +function d3_behavior_zoomLocation(point) { + return [ + point[0] - d3_behavior_zoomXyz[0], + point[1] - d3_behavior_zoomXyz[1], + d3_behavior_zoomXyz[2] + ]; +} + +// detect the pixels that would be scrolled by this wheel event +function d3_behavior_zoomDelta() { + + // mousewheel events are totally broken! + // https://bugs.webkit.org/show_bug.cgi?id=40441 + // not only that, but Chrome and Safari differ in re. to acceleration! + if (!d3_behavior_zoomDiv) { + d3_behavior_zoomDiv = d3.select("body").append("div") + .style("visibility", "hidden") + .style("top", 0) + .style("height", 0) + .style("width", 0) + .style("overflow-y", "scroll") + .append("div") + .style("height", "2000px") + .node().parentNode; + } + + var e = d3.event, delta; + try { + d3_behavior_zoomDiv.scrollTop = 1000; + d3_behavior_zoomDiv.dispatchEvent(e); + delta = 1000 - d3_behavior_zoomDiv.scrollTop; + } catch (error) { + delta = e.wheelDelta || (-e.detail * 5); + } + + return delta * .005; +} + +// Note: Since we don't rotate, it's possible for the touches to become +// slightly detached from their original positions. Thus, we recompute the +// touch points on touchend as well as touchstart! +function d3_behavior_zoomTouchup() { + var touches = d3.svg.touches(d3_behavior_zoomTarget), + i = -1, + n = touches.length, + touch; + while (++i < n) d3_behavior_zoomLocations[(touch = touches[i]).identifier] = d3_behavior_zoomLocation(touch); + return touches; +} + +function d3_behavior_zoomTouchmove() { + var touches = d3.svg.touches(d3_behavior_zoomTarget); + switch (touches.length) { + + // single-touch pan + case 1: { + var touch = touches[0]; + d3_behavior_zoomTo(d3_behavior_zoomXyz[2], touch, d3_behavior_zoomLocations[touch.identifier]); + break; + } + + // double-touch pan + zoom + case 2: { + var p0 = touches[0], + p1 = touches[1], + p2 = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2], + l0 = d3_behavior_zoomLocations[p0.identifier], + l1 = d3_behavior_zoomLocations[p1.identifier], + l2 = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2, l0[2]]; + d3_behavior_zoomTo(Math.log(d3.event.scale) / Math.LN2 + l0[2], p2, l2); + break; + } + } +} + +function d3_behavior_zoomMousemove() { + d3_behavior_zoomZooming = null; + if (d3_behavior_zoomPanning) { + d3_behavior_zoomMoved = 1; + d3_behavior_zoomTo(d3_behavior_zoomXyz[2], d3.svg.mouse(d3_behavior_zoomTarget), d3_behavior_zoomPanning); + } +} + +function d3_behavior_zoomMouseup() { + if (d3_behavior_zoomPanning) { + if (d3_behavior_zoomMoved) { + d3_eventCancel(); + d3_behavior_zoomMoved = d3_behavior_zoomEventTarget === d3.event.target; + } + + d3_behavior_zoomXyz = + d3_behavior_zoomExtent = + d3_behavior_zoomDispatch = + d3_behavior_zoomEventTarget = + d3_behavior_zoomTarget = + d3_behavior_zoomArguments = + d3_behavior_zoomPanning = null; + } +} + +function d3_behavior_zoomClick() { + if (d3_behavior_zoomMoved) { + d3_eventCancel(); + d3_behavior_zoomMoved = 0; + } +} + +function d3_behavior_zoomTo(z, x0, x1) { + z = d3_behavior_zoomExtentClamp(z, 2); + var j = Math.pow(2, d3_behavior_zoomXyz[2]), + k = Math.pow(2, z), + K = Math.pow(2, (d3_behavior_zoomXyz[2] = z) - x1[2]), + x_ = d3_behavior_zoomXyz[0], + y_ = d3_behavior_zoomXyz[1], + x = d3_behavior_zoomXyz[0] = d3_behavior_zoomExtentClamp((x0[0] - x1[0] * K), 0, k), + y = d3_behavior_zoomXyz[1] = d3_behavior_zoomExtentClamp((x0[1] - x1[1] * K), 1, k), + o = d3.event; // Events can be reentrant (e.g., focus). + + d3.event = { + scale: k, + translate: [x, y], + transform: function(sx, sy) { + if (sx) transform(sx, x_, x); + if (sy) transform(sy, y_, y); + } + }; + + function transform(scale, a, b) { + scale.domain(scale.range().map(function(v) { return scale.invert(((v - b) * j) / k + a); })); + } + + try { + d3_behavior_zoomDispatch.apply(d3_behavior_zoomTarget, d3_behavior_zoomArguments); + } finally { + d3.event = o; + } + + o.preventDefault(); +} + +var d3_behavior_zoomInfiniteExtent = [ + [-Infinity, Infinity], + [-Infinity, Infinity], + [-Infinity, Infinity] +]; + +function d3_behavior_zoomExtentClamp(x, i, k) { + var range = d3_behavior_zoomExtent[i], + r0 = range[0], + r1 = range[1]; + return arguments.length === 3 + ? Math.max(r1 * (r1 === Infinity ? -Infinity : 1 / k - 1), + Math.min(r0 === -Infinity ? Infinity : r0, x / k)) * k + : Math.max(r0, Math.min(r1, x)); +} +})(); diff --git a/java/servers/src/org/xtreemfs/dir/templates/d3.v3.js b/java/servers/src/org/xtreemfs/dir/templates/d3.v3.js new file mode 100644 index 0000000..dd90012 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/templates/d3.v3.js @@ -0,0 +1,8580 @@ +d3 = function() { + var d3 = { + version: "3.1.9" + }; + if (!Date.now) Date.now = function() { + return +new Date(); + }; + var d3_document = document, d3_window = window; + try { + d3_document.createElement("div").style.setProperty("opacity", 0, ""); + } catch (error) { + var d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; + d3_style_prototype.setProperty = function(name, value, priority) { + d3_style_setProperty.call(this, name, value + "", priority); + }; + } + d3.ascending = function(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; + }; + d3.descending = function(a, b) { + return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; + }; + d3.min = function(array, f) { + var i = -1, n = array.length, a, b; + if (arguments.length === 1) { + while (++i < n && ((a = array[i]) == null || a != a)) a = undefined; + while (++i < n) if ((b = array[i]) != null && a > b) a = b; + } else { + while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined; + while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; + } + return a; + }; + d3.max = function(array, f) { + var i = -1, n = array.length, a, b; + if (arguments.length === 1) { + while (++i < n && ((a = array[i]) == null || a != a)) a = undefined; + while (++i < n) if ((b = array[i]) != null && b > a) a = b; + } else { + while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined; + while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; + } + return a; + }; + d3.extent = function(array, f) { + var i = -1, n = array.length, a, b, c; + if (arguments.length === 1) { + while (++i < n && ((a = c = array[i]) == null || a != a)) a = c = undefined; + while (++i < n) if ((b = array[i]) != null) { + if (a > b) a = b; + if (c < b) c = b; + } + } else { + while (++i < n && ((a = c = f.call(array, array[i], i)) == null || a != a)) a = undefined; + while (++i < n) if ((b = f.call(array, array[i], i)) != null) { + if (a > b) a = b; + if (c < b) c = b; + } + } + return [ a, c ]; + }; + d3.sum = function(array, f) { + var s = 0, n = array.length, a, i = -1; + if (arguments.length === 1) { + while (++i < n) if (!isNaN(a = +array[i])) s += a; + } else { + while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a; + } + return s; + }; + function d3_number(x) { + return x != null && !isNaN(x); + } + d3.mean = function(array, f) { + var n = array.length, a, m = 0, i = -1, j = 0; + if (arguments.length === 1) { + while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j; + } else { + while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j; + } + return j ? m : undefined; + }; + d3.quantile = function(values, p) { + var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; + return e ? v + e * (values[h] - v) : v; + }; + d3.median = function(array, f) { + if (arguments.length > 1) array = array.map(f); + array = array.filter(d3_number); + return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined; + }; + d3.bisector = function(f) { + return { + left: function(a, x, lo, hi) { + if (arguments.length < 3) lo = 0; + if (arguments.length < 4) hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (f.call(a, a[mid], mid) < x) lo = mid + 1; else hi = mid; + } + return lo; + }, + right: function(a, x, lo, hi) { + if (arguments.length < 3) lo = 0; + if (arguments.length < 4) hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (x < f.call(a, a[mid], mid)) hi = mid; else lo = mid + 1; + } + return lo; + } + }; + }; + var d3_bisector = d3.bisector(function(d) { + return d; + }); + d3.bisectLeft = d3_bisector.left; + d3.bisect = d3.bisectRight = d3_bisector.right; + d3.shuffle = function(array) { + var m = array.length, t, i; + while (m) { + i = Math.random() * m-- | 0; + t = array[m], array[m] = array[i], array[i] = t; + } + return array; + }; + d3.permute = function(array, indexes) { + var permutes = [], i = -1, n = indexes.length; + while (++i < n) permutes[i] = array[indexes[i]]; + return permutes; + }; + d3.zip = function() { + if (!(n = arguments.length)) return []; + for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { + for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { + zip[j] = arguments[j][i]; + } + } + return zips; + }; + function d3_zipLength(d) { + return d.length; + } + d3.transpose = function(matrix) { + return d3.zip.apply(d3, matrix); + }; + d3.keys = function(map) { + var keys = []; + for (var key in map) keys.push(key); + return keys; + }; + d3.values = function(map) { + var values = []; + for (var key in map) values.push(map[key]); + return values; + }; + d3.entries = function(map) { + var entries = []; + for (var key in map) entries.push({ + key: key, + value: map[key] + }); + return entries; + }; + d3.merge = function(arrays) { + return Array.prototype.concat.apply([], arrays); + }; + d3.range = function(start, stop, step) { + if (arguments.length < 3) { + step = 1; + if (arguments.length < 2) { + stop = start; + start = 0; + } + } + if ((stop - start) / step === Infinity) throw new Error("infinite range"); + var range = [], k = d3_range_integerScale(Math.abs(step)), i = -1, j; + start *= k, stop *= k, step *= k; + if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); + return range; + }; + function d3_range_integerScale(x) { + var k = 1; + while (x * k % 1) k *= 10; + return k; + } + function d3_class(ctor, properties) { + try { + for (var key in properties) { + Object.defineProperty(ctor.prototype, key, { + value: properties[key], + enumerable: false + }); + } + } catch (e) { + ctor.prototype = properties; + } + } + d3.map = function(object) { + var map = new d3_Map(); + for (var key in object) map.set(key, object[key]); + return map; + }; + function d3_Map() {} + d3_class(d3_Map, { + has: function(key) { + return d3_map_prefix + key in this; + }, + get: function(key) { + return this[d3_map_prefix + key]; + }, + set: function(key, value) { + return this[d3_map_prefix + key] = value; + }, + remove: function(key) { + key = d3_map_prefix + key; + return key in this && delete this[key]; + }, + keys: function() { + var keys = []; + this.forEach(function(key) { + keys.push(key); + }); + return keys; + }, + values: function() { + var values = []; + this.forEach(function(key, value) { + values.push(value); + }); + return values; + }, + entries: function() { + var entries = []; + this.forEach(function(key, value) { + entries.push({ + key: key, + value: value + }); + }); + return entries; + }, + forEach: function(f) { + for (var key in this) { + if (key.charCodeAt(0) === d3_map_prefixCode) { + f.call(this, key.substring(1), this[key]); + } + } + } + }); + var d3_map_prefix = "\0", d3_map_prefixCode = d3_map_prefix.charCodeAt(0); + d3.nest = function() { + var nest = {}, keys = [], sortKeys = [], sortValues, rollup; + function map(mapType, array, depth) { + if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; + var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; + while (++i < n) { + if (values = valuesByKey.get(keyValue = key(object = array[i]))) { + values.push(object); + } else { + valuesByKey.set(keyValue, [ object ]); + } + } + if (mapType) { + object = mapType(); + setter = function(keyValue, values) { + object.set(keyValue, map(mapType, values, depth)); + }; + } else { + object = {}; + setter = function(keyValue, values) { + object[keyValue] = map(mapType, values, depth); + }; + } + valuesByKey.forEach(setter); + return object; + } + function entries(map, depth) { + if (depth >= keys.length) return map; + var array = [], sortKey = sortKeys[depth++]; + map.forEach(function(key, keyMap) { + array.push({ + key: key, + values: entries(keyMap, depth) + }); + }); + return sortKey ? array.sort(function(a, b) { + return sortKey(a.key, b.key); + }) : array; + } + nest.map = function(array, mapType) { + return map(mapType, array, 0); + }; + nest.entries = function(array) { + return entries(map(d3.map, array, 0), 0); + }; + nest.key = function(d) { + keys.push(d); + return nest; + }; + nest.sortKeys = function(order) { + sortKeys[keys.length - 1] = order; + return nest; + }; + nest.sortValues = function(order) { + sortValues = order; + return nest; + }; + nest.rollup = function(f) { + rollup = f; + return nest; + }; + return nest; + }; + d3.set = function(array) { + var set = new d3_Set(); + if (array) for (var i = 0; i < array.length; i++) set.add(array[i]); + return set; + }; + function d3_Set() {} + d3_class(d3_Set, { + has: function(value) { + return d3_map_prefix + value in this; + }, + add: function(value) { + this[d3_map_prefix + value] = true; + return value; + }, + remove: function(value) { + value = d3_map_prefix + value; + return value in this && delete this[value]; + }, + values: function() { + var values = []; + this.forEach(function(value) { + values.push(value); + }); + return values; + }, + forEach: function(f) { + for (var value in this) { + if (value.charCodeAt(0) === d3_map_prefixCode) { + f.call(this, value.substring(1)); + } + } + } + }); + d3.behavior = {}; + d3.rebind = function(target, source) { + var i = 1, n = arguments.length, method; + while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); + return target; + }; + function d3_rebind(target, source, method) { + return function() { + var value = method.apply(source, arguments); + return value === source ? target : value; + }; + } + d3.dispatch = function() { + var dispatch = new d3_dispatch(), i = -1, n = arguments.length; + while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); + return dispatch; + }; + function d3_dispatch() {} + d3_dispatch.prototype.on = function(type, listener) { + var i = type.indexOf("."), name = ""; + if (i >= 0) { + name = type.substring(i + 1); + type = type.substring(0, i); + } + if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); + if (arguments.length === 2) { + if (listener == null) for (type in this) { + if (this.hasOwnProperty(type)) this[type].on(name, null); + } + return this; + } + }; + function d3_dispatch_event(dispatch) { + var listeners = [], listenerByName = new d3_Map(); + function event() { + var z = listeners, i = -1, n = z.length, l; + while (++i < n) if (l = z[i].on) l.apply(this, arguments); + return dispatch; + } + event.on = function(name, listener) { + var l = listenerByName.get(name), i; + if (arguments.length < 2) return l && l.on; + if (l) { + l.on = null; + listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); + listenerByName.remove(name); + } + if (listener) listeners.push(listenerByName.set(name, { + on: listener + })); + return dispatch; + }; + return event; + } + d3.event = null; + function d3_eventCancel() { + d3.event.stopPropagation(); + d3.event.preventDefault(); + } + function d3_eventSource() { + var e = d3.event, s; + while (s = e.sourceEvent) e = s; + return e; + } + function d3_eventSuppress(target, type) { + function off() { + target.on(type, null); + } + target.on(type, function() { + d3_eventCancel(); + off(); + }, true); + setTimeout(off, 0); + } + function d3_eventDispatch(target) { + var dispatch = new d3_dispatch(), i = 0, n = arguments.length; + while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); + dispatch.of = function(thiz, argumentz) { + return function(e1) { + try { + var e0 = e1.sourceEvent = d3.event; + e1.target = target; + d3.event = e1; + dispatch[e1.type].apply(thiz, argumentz); + } finally { + d3.event = e0; + } + }; + }; + return dispatch; + } + d3.mouse = function(container) { + return d3_mousePoint(container, d3_eventSource()); + }; + var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0; + function d3_mousePoint(container, e) { + var svg = container.ownerSVGElement || container; + if (svg.createSVGPoint) { + var point = svg.createSVGPoint(); + if (d3_mouse_bug44083 < 0 && (d3_window.scrollX || d3_window.scrollY)) { + svg = d3.select(d3_document.body).append("svg").style("position", "absolute").style("top", 0).style("left", 0); + var ctm = svg[0][0].getScreenCTM(); + d3_mouse_bug44083 = !(ctm.f || ctm.e); + svg.remove(); + } + if (d3_mouse_bug44083) { + point.x = e.pageX; + point.y = e.pageY; + } else { + point.x = e.clientX; + point.y = e.clientY; + } + point = point.matrixTransform(container.getScreenCTM().inverse()); + return [ point.x, point.y ]; + } + var rect = container.getBoundingClientRect(); + return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; + } + var d3_array = d3_arraySlice; + function d3_arrayCopy(pseudoarray) { + var i = -1, n = pseudoarray.length, array = []; + while (++i < n) array.push(pseudoarray[i]); + return array; + } + function d3_arraySlice(pseudoarray) { + return Array.prototype.slice.call(pseudoarray); + } + try { + d3_array(d3_document.documentElement.childNodes)[0].nodeType; + } catch (e) { + d3_array = d3_arrayCopy; + } + var d3_arraySubclass = [].__proto__ ? function(array, prototype) { + array.__proto__ = prototype; + } : function(array, prototype) { + for (var property in prototype) array[property] = prototype[property]; + }; + d3.touches = function(container, touches) { + if (arguments.length < 2) touches = d3_eventSource().touches; + return touches ? d3_array(touches).map(function(touch) { + var point = d3_mousePoint(container, touch); + point.identifier = touch.identifier; + return point; + }) : []; + }; + d3.behavior.drag = function() { + var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null; + function drag() { + this.on("mousedown.drag", mousedown).on("touchstart.drag", mousedown); + } + function mousedown() { + var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, touchId = d3.event.touches ? d3.event.changedTouches[0].identifier : null, offset, origin_ = point(), moved = 0; + var w = d3.select(d3_window).on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true); + if (origin) { + offset = origin.apply(target, arguments); + offset = [ offset.x - origin_[0], offset.y - origin_[1] ]; + } else { + offset = [ 0, 0 ]; + } + if (touchId == null) d3_eventCancel(); + event_({ + type: "dragstart" + }); + function point() { + var p = target.parentNode; + return touchId != null ? d3.touches(p).filter(function(p) { + return p.identifier === touchId; + })[0] : d3.mouse(p); + } + function dragmove() { + if (!target.parentNode) return dragend(); + var p = point(), dx = p[0] - origin_[0], dy = p[1] - origin_[1]; + moved |= dx | dy; + origin_ = p; + d3_eventCancel(); + event_({ + type: "drag", + x: p[0] + offset[0], + y: p[1] + offset[1], + dx: dx, + dy: dy + }); + } + function dragend() { + event_({ + type: "dragend" + }); + if (moved) { + d3_eventCancel(); + if (d3.event.target === eventTarget) d3_eventSuppress(w, "click"); + } + w.on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", null).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", null); + } + } + drag.origin = function(x) { + if (!arguments.length) return origin; + origin = x; + return drag; + }; + return d3.rebind(drag, event, "on"); + }; + function d3_selection(groups) { + d3_arraySubclass(groups, d3_selectionPrototype); + return groups; + } + var d3_select = function(s, n) { + return n.querySelector(s); + }, d3_selectAll = function(s, n) { + return n.querySelectorAll(s); + }, d3_selectRoot = d3_document.documentElement, d3_selectMatcher = d3_selectRoot.matchesSelector || d3_selectRoot.webkitMatchesSelector || d3_selectRoot.mozMatchesSelector || d3_selectRoot.msMatchesSelector || d3_selectRoot.oMatchesSelector, d3_selectMatches = function(n, s) { + return d3_selectMatcher.call(n, s); + }; + if (typeof Sizzle === "function") { + d3_select = function(s, n) { + return Sizzle(s, n)[0] || null; + }; + d3_selectAll = function(s, n) { + return Sizzle.uniqueSort(Sizzle(s, n)); + }; + d3_selectMatches = Sizzle.matchesSelector; + } + d3.selection = function() { + return d3_selectionRoot; + }; + var d3_selectionPrototype = d3.selection.prototype = []; + d3_selectionPrototype.select = function(selector) { + var subgroups = [], subgroup, subnode, group, node; + if (typeof selector !== "function") selector = d3_selection_selector(selector); + for (var j = -1, m = this.length; ++j < m; ) { + subgroups.push(subgroup = []); + subgroup.parentNode = (group = this[j]).parentNode; + for (var i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + subgroup.push(subnode = selector.call(node, node.__data__, i)); + if (subnode && "__data__" in node) subnode.__data__ = node.__data__; + } else { + subgroup.push(null); + } + } + } + return d3_selection(subgroups); + }; + function d3_selection_selector(selector) { + return function() { + return d3_select(selector, this); + }; + } + d3_selectionPrototype.selectAll = function(selector) { + var subgroups = [], subgroup, node; + if (typeof selector !== "function") selector = d3_selection_selectorAll(selector); + for (var j = -1, m = this.length; ++j < m; ) { + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i))); + subgroup.parentNode = node; + } + } + } + return d3_selection(subgroups); + }; + function d3_selection_selectorAll(selector) { + return function() { + return d3_selectAll(selector, this); + }; + } + var d3_nsPrefix = { + svg: "http://www.w3.org/2000/svg", + xhtml: "http://www.w3.org/1999/xhtml", + xlink: "http://www.w3.org/1999/xlink", + xml: "http://www.w3.org/XML/1998/namespace", + xmlns: "http://www.w3.org/2000/xmlns/" + }; + d3.ns = { + prefix: d3_nsPrefix, + qualify: function(name) { + var i = name.indexOf(":"), prefix = name; + if (i >= 0) { + prefix = name.substring(0, i); + name = name.substring(i + 1); + } + return d3_nsPrefix.hasOwnProperty(prefix) ? { + space: d3_nsPrefix[prefix], + local: name + } : name; + } + }; + d3_selectionPrototype.attr = function(name, value) { + if (arguments.length < 2) { + if (typeof name === "string") { + var node = this.node(); + name = d3.ns.qualify(name); + return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); + } + for (value in name) this.each(d3_selection_attr(value, name[value])); + return this; + } + return this.each(d3_selection_attr(name, value)); + }; + function d3_selection_attr(name, value) { + name = d3.ns.qualify(name); + function attrNull() { + this.removeAttribute(name); + } + function attrNullNS() { + this.removeAttributeNS(name.space, name.local); + } + function attrConstant() { + this.setAttribute(name, value); + } + function attrConstantNS() { + this.setAttributeNS(name.space, name.local, value); + } + function attrFunction() { + var x = value.apply(this, arguments); + if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); + } + function attrFunctionNS() { + var x = value.apply(this, arguments); + if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); + } + return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; + } + function d3_collapse(s) { + return s.trim().replace(/\s+/g, " "); + } + d3.requote = function(s) { + return s.replace(d3_requote_re, "\\$&"); + }; + var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; + d3_selectionPrototype.classed = function(name, value) { + if (arguments.length < 2) { + if (typeof name === "string") { + var node = this.node(), n = (name = name.trim().split(/^|\s+/g)).length, i = -1; + if (value = node.classList) { + while (++i < n) if (!value.contains(name[i])) return false; + } else { + value = node.getAttribute("class"); + while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; + } + return true; + } + for (value in name) this.each(d3_selection_classed(value, name[value])); + return this; + } + return this.each(d3_selection_classed(name, value)); + }; + function d3_selection_classedRe(name) { + return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); + } + function d3_selection_classed(name, value) { + name = name.trim().split(/\s+/).map(d3_selection_classedName); + var n = name.length; + function classedConstant() { + var i = -1; + while (++i < n) name[i](this, value); + } + function classedFunction() { + var i = -1, x = value.apply(this, arguments); + while (++i < n) name[i](this, x); + } + return typeof value === "function" ? classedFunction : classedConstant; + } + function d3_selection_classedName(name) { + var re = d3_selection_classedRe(name); + return function(node, value) { + if (c = node.classList) return value ? c.add(name) : c.remove(name); + var c = node.getAttribute("class") || ""; + if (value) { + re.lastIndex = 0; + if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); + } else { + node.setAttribute("class", d3_collapse(c.replace(re, " "))); + } + }; + } + d3_selectionPrototype.style = function(name, value, priority) { + var n = arguments.length; + if (n < 3) { + if (typeof name !== "string") { + if (n < 2) value = ""; + for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); + return this; + } + if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name); + priority = ""; + } + return this.each(d3_selection_style(name, value, priority)); + }; + function d3_selection_style(name, value, priority) { + function styleNull() { + this.style.removeProperty(name); + } + function styleConstant() { + this.style.setProperty(name, value, priority); + } + function styleFunction() { + var x = value.apply(this, arguments); + if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); + } + return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; + } + d3_selectionPrototype.property = function(name, value) { + if (arguments.length < 2) { + if (typeof name === "string") return this.node()[name]; + for (value in name) this.each(d3_selection_property(value, name[value])); + return this; + } + return this.each(d3_selection_property(name, value)); + }; + function d3_selection_property(name, value) { + function propertyNull() { + delete this[name]; + } + function propertyConstant() { + this[name] = value; + } + function propertyFunction() { + var x = value.apply(this, arguments); + if (x == null) delete this[name]; else this[name] = x; + } + return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; + } + d3_selectionPrototype.text = function(value) { + return arguments.length ? this.each(typeof value === "function" ? function() { + var v = value.apply(this, arguments); + this.textContent = v == null ? "" : v; + } : value == null ? function() { + this.textContent = ""; + } : function() { + this.textContent = value; + }) : this.node().textContent; + }; + d3_selectionPrototype.html = function(value) { + return arguments.length ? this.each(typeof value === "function" ? function() { + var v = value.apply(this, arguments); + this.innerHTML = v == null ? "" : v; + } : value == null ? function() { + this.innerHTML = ""; + } : function() { + this.innerHTML = value; + }) : this.node().innerHTML; + }; + d3_selectionPrototype.append = function(name) { + name = d3.ns.qualify(name); + function append() { + return this.appendChild(d3_document.createElementNS(this.namespaceURI, name)); + } + function appendNS() { + return this.appendChild(d3_document.createElementNS(name.space, name.local)); + } + return this.select(name.local ? appendNS : append); + }; + d3_selectionPrototype.insert = function(name, before) { + name = d3.ns.qualify(name); + if (typeof before !== "function") before = d3_selection_selector(before); + function insert(d, i) { + return this.insertBefore(d3_document.createElementNS(this.namespaceURI, name), before.call(this, d, i)); + } + function insertNS(d, i) { + return this.insertBefore(d3_document.createElementNS(name.space, name.local), before.call(this, d, i)); + } + return this.select(name.local ? insertNS : insert); + }; + d3_selectionPrototype.remove = function() { + return this.each(function() { + var parent = this.parentNode; + if (parent) parent.removeChild(this); + }); + }; + d3_selectionPrototype.data = function(value, key) { + var i = -1, n = this.length, group, node; + if (!arguments.length) { + value = new Array(n = (group = this[0]).length); + while (++i < n) { + if (node = group[i]) { + value[i] = node.__data__; + } + } + return value; + } + function bind(group, groupData) { + var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; + if (key) { + var nodeByKeyValue = new d3_Map(), dataByKeyValue = new d3_Map(), keyValues = [], keyValue; + for (i = -1; ++i < n; ) { + keyValue = key.call(node = group[i], node.__data__, i); + if (nodeByKeyValue.has(keyValue)) { + exitNodes[i] = node; + } else { + nodeByKeyValue.set(keyValue, node); + } + keyValues.push(keyValue); + } + for (i = -1; ++i < m; ) { + keyValue = key.call(groupData, nodeData = groupData[i], i); + if (node = nodeByKeyValue.get(keyValue)) { + updateNodes[i] = node; + node.__data__ = nodeData; + } else if (!dataByKeyValue.has(keyValue)) { + enterNodes[i] = d3_selection_dataNode(nodeData); + } + dataByKeyValue.set(keyValue, nodeData); + nodeByKeyValue.remove(keyValue); + } + for (i = -1; ++i < n; ) { + if (nodeByKeyValue.has(keyValues[i])) { + exitNodes[i] = group[i]; + } + } + } else { + for (i = -1; ++i < n0; ) { + node = group[i]; + nodeData = groupData[i]; + if (node) { + node.__data__ = nodeData; + updateNodes[i] = node; + } else { + enterNodes[i] = d3_selection_dataNode(nodeData); + } + } + for (;i < m; ++i) { + enterNodes[i] = d3_selection_dataNode(groupData[i]); + } + for (;i < n; ++i) { + exitNodes[i] = group[i]; + } + } + enterNodes.update = updateNodes; + enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; + enter.push(enterNodes); + update.push(updateNodes); + exit.push(exitNodes); + } + var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); + if (typeof value === "function") { + while (++i < n) { + bind(group = this[i], value.call(group, group.parentNode.__data__, i)); + } + } else { + while (++i < n) { + bind(group = this[i], value); + } + } + update.enter = function() { + return enter; + }; + update.exit = function() { + return exit; + }; + return update; + }; + function d3_selection_dataNode(data) { + return { + __data__: data + }; + } + d3_selectionPrototype.datum = function(value) { + return arguments.length ? this.property("__data__", value) : this.property("__data__"); + }; + d3_selectionPrototype.filter = function(filter) { + var subgroups = [], subgroup, group, node; + if (typeof filter !== "function") filter = d3_selection_filter(filter); + for (var j = 0, m = this.length; j < m; j++) { + subgroups.push(subgroup = []); + subgroup.parentNode = (group = this[j]).parentNode; + for (var i = 0, n = group.length; i < n; i++) { + if ((node = group[i]) && filter.call(node, node.__data__, i)) { + subgroup.push(node); + } + } + } + return d3_selection(subgroups); + }; + function d3_selection_filter(selector) { + return function() { + return d3_selectMatches(this, selector); + }; + } + d3_selectionPrototype.order = function() { + for (var j = -1, m = this.length; ++j < m; ) { + for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { + if (node = group[i]) { + if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); + next = node; + } + } + } + return this; + }; + d3_selectionPrototype.sort = function(comparator) { + comparator = d3_selection_sortComparator.apply(this, arguments); + for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); + return this.order(); + }; + function d3_selection_sortComparator(comparator) { + if (!arguments.length) comparator = d3.ascending; + return function(a, b) { + return !a - !b || comparator(a.__data__, b.__data__); + }; + } + function d3_noop() {} + d3_selectionPrototype.on = function(type, listener, capture) { + var n = arguments.length; + if (n < 3) { + if (typeof type !== "string") { + if (n < 2) listener = false; + for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); + return this; + } + if (n < 2) return (n = this.node()["__on" + type]) && n._; + capture = false; + } + return this.each(d3_selection_on(type, listener, capture)); + }; + function d3_selection_on(type, listener, capture) { + var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; + if (i > 0) type = type.substring(0, i); + var filter = d3_selection_onFilters.get(type); + if (filter) type = filter, wrap = d3_selection_onFilter; + function onRemove() { + var l = this[name]; + if (l) { + this.removeEventListener(type, l, l.$); + delete this[name]; + } + } + function onAdd() { + var l = wrap(listener, d3_array(arguments)); + onRemove.call(this); + this.addEventListener(type, this[name] = l, l.$ = capture); + l._ = listener; + } + function removeAll() { + var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; + for (var name in this) { + if (match = name.match(re)) { + var l = this[name]; + this.removeEventListener(match[1], l, l.$); + delete this[name]; + } + } + } + return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; + } + var d3_selection_onFilters = d3.map({ + mouseenter: "mouseover", + mouseleave: "mouseout" + }); + d3_selection_onFilters.forEach(function(k) { + if ("on" + k in d3_document) d3_selection_onFilters.remove(k); + }); + function d3_selection_onListener(listener, argumentz) { + return function(e) { + var o = d3.event; + d3.event = e; + argumentz[0] = this.__data__; + try { + listener.apply(this, argumentz); + } finally { + d3.event = o; + } + }; + } + function d3_selection_onFilter(listener, argumentz) { + var l = d3_selection_onListener(listener, argumentz); + return function(e) { + var target = this, related = e.relatedTarget; + if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { + l.call(target, e); + } + }; + } + d3_selectionPrototype.each = function(callback) { + return d3_selection_each(this, function(node, i, j) { + callback.call(node, node.__data__, i, j); + }); + }; + function d3_selection_each(groups, callback) { + for (var j = 0, m = groups.length; j < m; j++) { + for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { + if (node = group[i]) callback(node, i, j); + } + } + return groups; + } + d3_selectionPrototype.call = function(callback) { + var args = d3_array(arguments); + callback.apply(args[0] = this, args); + return this; + }; + d3_selectionPrototype.empty = function() { + return !this.node(); + }; + d3_selectionPrototype.node = function() { + for (var j = 0, m = this.length; j < m; j++) { + for (var group = this[j], i = 0, n = group.length; i < n; i++) { + var node = group[i]; + if (node) return node; + } + } + return null; + }; + function d3_selection_enter(selection) { + d3_arraySubclass(selection, d3_selection_enterPrototype); + return selection; + } + var d3_selection_enterPrototype = []; + d3.selection.enter = d3_selection_enter; + d3.selection.enter.prototype = d3_selection_enterPrototype; + d3_selection_enterPrototype.append = d3_selectionPrototype.append; + d3_selection_enterPrototype.insert = d3_selectionPrototype.insert; + d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; + d3_selection_enterPrototype.node = d3_selectionPrototype.node; + d3_selection_enterPrototype.select = function(selector) { + var subgroups = [], subgroup, subnode, upgroup, group, node; + for (var j = -1, m = this.length; ++j < m; ) { + upgroup = (group = this[j]).update; + subgroups.push(subgroup = []); + subgroup.parentNode = group.parentNode; + for (var i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i)); + subnode.__data__ = node.__data__; + } else { + subgroup.push(null); + } + } + } + return d3_selection(subgroups); + }; + d3_selectionPrototype.transition = function() { + var id = d3_transitionInheritId || ++d3_transitionId, subgroups = [], subgroup, node, transition = Object.create(d3_transitionInherit); + transition.time = Date.now(); + for (var j = -1, m = this.length; ++j < m; ) { + subgroups.push(subgroup = []); + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) d3_transitionNode(node, i, id, transition); + subgroup.push(node); + } + } + return d3_transition(subgroups, id); + }; + d3.select = function(node) { + var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ]; + group.parentNode = d3_selectRoot; + return d3_selection([ group ]); + }; + d3.selectAll = function(nodes) { + var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes); + group.parentNode = d3_selectRoot; + return d3_selection([ group ]); + }; + var d3_selectionRoot = d3.select(d3_selectRoot); + d3.behavior.zoom = function() { + var translate = [ 0, 0 ], translate0, scale = 1, scale0, scaleExtent = d3_behavior_zoomInfinity, event = d3_eventDispatch(zoom, "zoom"), x0, x1, y0, y1, touchtime; + function zoom() { + this.on("mousedown.zoom", mousedown).on("mousemove.zoom", mousemove).on(d3_behavior_zoomWheel + ".zoom", mousewheel).on("dblclick.zoom", dblclick).on("touchstart.zoom", touchstart).on("touchmove.zoom", touchmove).on("touchend.zoom", touchstart); + } + zoom.translate = function(x) { + if (!arguments.length) return translate; + translate = x.map(Number); + rescale(); + return zoom; + }; + zoom.scale = function(x) { + if (!arguments.length) return scale; + scale = +x; + rescale(); + return zoom; + }; + zoom.scaleExtent = function(x) { + if (!arguments.length) return scaleExtent; + scaleExtent = x == null ? d3_behavior_zoomInfinity : x.map(Number); + return zoom; + }; + zoom.x = function(z) { + if (!arguments.length) return x1; + x1 = z; + x0 = z.copy(); + translate = [ 0, 0 ]; + scale = 1; + return zoom; + }; + zoom.y = function(z) { + if (!arguments.length) return y1; + y1 = z; + y0 = z.copy(); + translate = [ 0, 0 ]; + scale = 1; + return zoom; + }; + function location(p) { + return [ (p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale ]; + } + function point(l) { + return [ l[0] * scale + translate[0], l[1] * scale + translate[1] ]; + } + function scaleTo(s) { + scale = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); + } + function translateTo(p, l) { + l = point(l); + translate[0] += p[0] - l[0]; + translate[1] += p[1] - l[1]; + } + function rescale() { + if (x1) x1.domain(x0.range().map(function(x) { + return (x - translate[0]) / scale; + }).map(x0.invert)); + if (y1) y1.domain(y0.range().map(function(y) { + return (y - translate[1]) / scale; + }).map(y0.invert)); + } + function dispatch(event) { + rescale(); + d3.event.preventDefault(); + event({ + type: "zoom", + scale: scale, + translate: translate + }); + } + function mousedown() { + var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, moved = 0, w = d3.select(d3_window).on("mousemove.zoom", mousemove).on("mouseup.zoom", mouseup), l = location(d3.mouse(target)); + d3_window.focus(); + d3_eventCancel(); + function mousemove() { + moved = 1; + translateTo(d3.mouse(target), l); + dispatch(event_); + } + function mouseup() { + if (moved) d3_eventCancel(); + w.on("mousemove.zoom", null).on("mouseup.zoom", null); + if (moved && d3.event.target === eventTarget) d3_eventSuppress(w, "click.zoom"); + } + } + function mousewheel() { + if (!translate0) translate0 = location(d3.mouse(this)); + scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * scale); + translateTo(d3.mouse(this), translate0); + dispatch(event.of(this, arguments)); + } + function mousemove() { + translate0 = null; + } + function dblclick() { + var p = d3.mouse(this), l = location(p), k = Math.log(scale) / Math.LN2; + scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1)); + translateTo(p, l); + dispatch(event.of(this, arguments)); + } + function touchstart() { + var touches = d3.touches(this), now = Date.now(); + scale0 = scale; + translate0 = {}; + touches.forEach(function(t) { + translate0[t.identifier] = location(t); + }); + d3_eventCancel(); + if (touches.length === 1) { + if (now - touchtime < 500) { + var p = touches[0], l = location(touches[0]); + scaleTo(scale * 2); + translateTo(p, l); + dispatch(event.of(this, arguments)); + } + touchtime = now; + } + } + function touchmove() { + var touches = d3.touches(this), p0 = touches[0], l0 = translate0[p0.identifier]; + if (p1 = touches[1]) { + var p1, l1 = translate0[p1.identifier]; + p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; + l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; + scaleTo(d3.event.scale * scale0); + } + translateTo(p0, l0); + touchtime = null; + dispatch(event.of(this, arguments)); + } + return d3.rebind(zoom, event, "on"); + }; + var d3_behavior_zoomInfinity = [ 0, Infinity ]; + var d3_behavior_zoomDelta, d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { + return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); + }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { + return d3.event.wheelDelta; + }, "mousewheel") : (d3_behavior_zoomDelta = function() { + return -d3.event.detail; + }, "MozMousePixelScroll"); + function d3_Color() {} + d3_Color.prototype.toString = function() { + return this.rgb() + ""; + }; + d3.hsl = function(h, s, l) { + return arguments.length === 1 ? h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : d3_hsl(+h, +s, +l); + }; + function d3_hsl(h, s, l) { + return new d3_Hsl(h, s, l); + } + function d3_Hsl(h, s, l) { + this.h = h; + this.s = s; + this.l = l; + } + var d3_hslPrototype = d3_Hsl.prototype = new d3_Color(); + d3_hslPrototype.brighter = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + return d3_hsl(this.h, this.s, this.l / k); + }; + d3_hslPrototype.darker = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + return d3_hsl(this.h, this.s, k * this.l); + }; + d3_hslPrototype.rgb = function() { + return d3_hsl_rgb(this.h, this.s, this.l); + }; + function d3_hsl_rgb(h, s, l) { + var m1, m2; + h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; + s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; + l = l < 0 ? 0 : l > 1 ? 1 : l; + m2 = l <= .5 ? l * (1 + s) : l + s - l * s; + m1 = 2 * l - m2; + function v(h) { + if (h > 360) h -= 360; else if (h < 0) h += 360; + if (h < 60) return m1 + (m2 - m1) * h / 60; + if (h < 180) return m2; + if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; + return m1; + } + function vv(h) { + return Math.round(v(h) * 255); + } + return d3_rgb(vv(h + 120), vv(h), vv(h - 120)); + } + var Ï€ = Math.PI, ε = 1e-6, d3_radians = Ï€ / 180, d3_degrees = 180 / Ï€; + function d3_sgn(x) { + return x > 0 ? 1 : x < 0 ? -1 : 0; + } + function d3_acos(x) { + return Math.acos(Math.max(-1, Math.min(1, x))); + } + function d3_asin(x) { + return x > 1 ? Ï€ / 2 : x < -1 ? -Ï€ / 2 : Math.asin(x); + } + function d3_sinh(x) { + return (Math.exp(x) - Math.exp(-x)) / 2; + } + function d3_cosh(x) { + return (Math.exp(x) + Math.exp(-x)) / 2; + } + function d3_haversin(x) { + return (x = Math.sin(x / 2)) * x; + } + d3.hcl = function(h, c, l) { + return arguments.length === 1 ? h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l) : h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : d3_hcl(+h, +c, +l); + }; + function d3_hcl(h, c, l) { + return new d3_Hcl(h, c, l); + } + function d3_Hcl(h, c, l) { + this.h = h; + this.c = c; + this.l = l; + } + var d3_hclPrototype = d3_Hcl.prototype = new d3_Color(); + d3_hclPrototype.brighter = function(k) { + return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); + }; + d3_hclPrototype.darker = function(k) { + return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); + }; + d3_hclPrototype.rgb = function() { + return d3_hcl_lab(this.h, this.c, this.l).rgb(); + }; + function d3_hcl_lab(h, c, l) { + if (isNaN(h)) h = 0; + if (isNaN(c)) c = 0; + return d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); + } + d3.lab = function(l, a, b) { + return arguments.length === 1 ? l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b) : l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h) : d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b) : d3_lab(+l, +a, +b); + }; + function d3_lab(l, a, b) { + return new d3_Lab(l, a, b); + } + function d3_Lab(l, a, b) { + this.l = l; + this.a = a; + this.b = b; + } + var d3_lab_K = 18; + var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; + var d3_labPrototype = d3_Lab.prototype = new d3_Color(); + d3_labPrototype.brighter = function(k) { + return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); + }; + d3_labPrototype.darker = function(k) { + return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); + }; + d3_labPrototype.rgb = function() { + return d3_lab_rgb(this.l, this.a, this.b); + }; + function d3_lab_rgb(l, a, b) { + var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; + x = d3_lab_xyz(x) * d3_lab_X; + y = d3_lab_xyz(y) * d3_lab_Y; + z = d3_lab_xyz(z) * d3_lab_Z; + return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); + } + function d3_lab_hcl(l, a, b) { + return l > 0 ? d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : d3_hcl(NaN, NaN, l); + } + function d3_lab_xyz(x) { + return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; + } + function d3_xyz_lab(x) { + return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; + } + function d3_xyz_rgb(r) { + return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); + } + d3.rgb = function(r, g, b) { + return arguments.length === 1 ? r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : d3_rgb(~~r, ~~g, ~~b); + }; + function d3_rgb(r, g, b) { + return new d3_Rgb(r, g, b); + } + function d3_Rgb(r, g, b) { + this.r = r; + this.g = g; + this.b = b; + } + var d3_rgbPrototype = d3_Rgb.prototype = new d3_Color(); + d3_rgbPrototype.brighter = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + var r = this.r, g = this.g, b = this.b, i = 30; + if (!r && !g && !b) return d3_rgb(i, i, i); + if (r && r < i) r = i; + if (g && g < i) g = i; + if (b && b < i) b = i; + return d3_rgb(Math.min(255, Math.floor(r / k)), Math.min(255, Math.floor(g / k)), Math.min(255, Math.floor(b / k))); + }; + d3_rgbPrototype.darker = function(k) { + k = Math.pow(.7, arguments.length ? k : 1); + return d3_rgb(Math.floor(k * this.r), Math.floor(k * this.g), Math.floor(k * this.b)); + }; + d3_rgbPrototype.hsl = function() { + return d3_rgb_hsl(this.r, this.g, this.b); + }; + d3_rgbPrototype.toString = function() { + return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); + }; + function d3_rgb_hex(v) { + return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); + } + function d3_rgb_parse(format, rgb, hsl) { + var r = 0, g = 0, b = 0, m1, m2, name; + m1 = /([a-z]+)\((.*)\)/i.exec(format); + if (m1) { + m2 = m1[2].split(","); + switch (m1[1]) { + case "hsl": + { + return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); + } + + case "rgb": + { + return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); + } + } + } + if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b); + if (format != null && format.charAt(0) === "#") { + if (format.length === 4) { + r = format.charAt(1); + r += r; + g = format.charAt(2); + g += g; + b = format.charAt(3); + b += b; + } else if (format.length === 7) { + r = format.substring(1, 3); + g = format.substring(3, 5); + b = format.substring(5, 7); + } + r = parseInt(r, 16); + g = parseInt(g, 16); + b = parseInt(b, 16); + } + return rgb(r, g, b); + } + function d3_rgb_hsl(r, g, b) { + var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; + if (d) { + s = l < .5 ? d / (max + min) : d / (2 - max - min); + if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; + h *= 60; + } else { + h = NaN; + s = l > 0 && l < 1 ? 0 : h; + } + return d3_hsl(h, s, l); + } + function d3_rgb_lab(r, g, b) { + r = d3_rgb_xyz(r); + g = d3_rgb_xyz(g); + b = d3_rgb_xyz(b); + var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); + return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); + } + function d3_rgb_xyz(r) { + return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); + } + function d3_rgb_parseNumber(c) { + var f = parseFloat(c); + return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; + } + var d3_rgb_names = d3.map({ + aliceblue: "#f0f8ff", + antiquewhite: "#faebd7", + aqua: "#00ffff", + aquamarine: "#7fffd4", + azure: "#f0ffff", + beige: "#f5f5dc", + bisque: "#ffe4c4", + black: "#000000", + blanchedalmond: "#ffebcd", + blue: "#0000ff", + blueviolet: "#8a2be2", + brown: "#a52a2a", + burlywood: "#deb887", + cadetblue: "#5f9ea0", + chartreuse: "#7fff00", + chocolate: "#d2691e", + coral: "#ff7f50", + cornflowerblue: "#6495ed", + cornsilk: "#fff8dc", + crimson: "#dc143c", + cyan: "#00ffff", + darkblue: "#00008b", + darkcyan: "#008b8b", + darkgoldenrod: "#b8860b", + darkgray: "#a9a9a9", + darkgreen: "#006400", + darkgrey: "#a9a9a9", + darkkhaki: "#bdb76b", + darkmagenta: "#8b008b", + darkolivegreen: "#556b2f", + darkorange: "#ff8c00", + darkorchid: "#9932cc", + darkred: "#8b0000", + darksalmon: "#e9967a", + darkseagreen: "#8fbc8f", + darkslateblue: "#483d8b", + darkslategray: "#2f4f4f", + darkslategrey: "#2f4f4f", + darkturquoise: "#00ced1", + darkviolet: "#9400d3", + deeppink: "#ff1493", + deepskyblue: "#00bfff", + dimgray: "#696969", + dimgrey: "#696969", + dodgerblue: "#1e90ff", + firebrick: "#b22222", + floralwhite: "#fffaf0", + forestgreen: "#228b22", + fuchsia: "#ff00ff", + gainsboro: "#dcdcdc", + ghostwhite: "#f8f8ff", + gold: "#ffd700", + goldenrod: "#daa520", + gray: "#808080", + green: "#008000", + greenyellow: "#adff2f", + grey: "#808080", + honeydew: "#f0fff0", + hotpink: "#ff69b4", + indianred: "#cd5c5c", + indigo: "#4b0082", + ivory: "#fffff0", + khaki: "#f0e68c", + lavender: "#e6e6fa", + lavenderblush: "#fff0f5", + lawngreen: "#7cfc00", + lemonchiffon: "#fffacd", + lightblue: "#add8e6", + lightcoral: "#f08080", + lightcyan: "#e0ffff", + lightgoldenrodyellow: "#fafad2", + lightgray: "#d3d3d3", + lightgreen: "#90ee90", + lightgrey: "#d3d3d3", + lightpink: "#ffb6c1", + lightsalmon: "#ffa07a", + lightseagreen: "#20b2aa", + lightskyblue: "#87cefa", + lightslategray: "#778899", + lightslategrey: "#778899", + lightsteelblue: "#b0c4de", + lightyellow: "#ffffe0", + lime: "#00ff00", + limegreen: "#32cd32", + linen: "#faf0e6", + magenta: "#ff00ff", + maroon: "#800000", + mediumaquamarine: "#66cdaa", + mediumblue: "#0000cd", + mediumorchid: "#ba55d3", + mediumpurple: "#9370db", + mediumseagreen: "#3cb371", + mediumslateblue: "#7b68ee", + mediumspringgreen: "#00fa9a", + mediumturquoise: "#48d1cc", + mediumvioletred: "#c71585", + midnightblue: "#191970", + mintcream: "#f5fffa", + mistyrose: "#ffe4e1", + moccasin: "#ffe4b5", + navajowhite: "#ffdead", + navy: "#000080", + oldlace: "#fdf5e6", + olive: "#808000", + olivedrab: "#6b8e23", + orange: "#ffa500", + orangered: "#ff4500", + orchid: "#da70d6", + palegoldenrod: "#eee8aa", + palegreen: "#98fb98", + paleturquoise: "#afeeee", + palevioletred: "#db7093", + papayawhip: "#ffefd5", + peachpuff: "#ffdab9", + peru: "#cd853f", + pink: "#ffc0cb", + plum: "#dda0dd", + powderblue: "#b0e0e6", + purple: "#800080", + red: "#ff0000", + rosybrown: "#bc8f8f", + royalblue: "#4169e1", + saddlebrown: "#8b4513", + salmon: "#fa8072", + sandybrown: "#f4a460", + seagreen: "#2e8b57", + seashell: "#fff5ee", + sienna: "#a0522d", + silver: "#c0c0c0", + skyblue: "#87ceeb", + slateblue: "#6a5acd", + slategray: "#708090", + slategrey: "#708090", + snow: "#fffafa", + springgreen: "#00ff7f", + steelblue: "#4682b4", + tan: "#d2b48c", + teal: "#008080", + thistle: "#d8bfd8", + tomato: "#ff6347", + turquoise: "#40e0d0", + violet: "#ee82ee", + wheat: "#f5deb3", + white: "#ffffff", + whitesmoke: "#f5f5f5", + yellow: "#ffff00", + yellowgreen: "#9acd32" + }); + d3_rgb_names.forEach(function(key, value) { + d3_rgb_names.set(key, d3_rgb_parse(value, d3_rgb, d3_hsl_rgb)); + }); + function d3_functor(v) { + return typeof v === "function" ? v : function() { + return v; + }; + } + d3.functor = d3_functor; + function d3_identity(d) { + return d; + } + d3.xhr = function(url, mimeType, callback) { + var xhr = {}, dispatch = d3.dispatch("progress", "load", "error"), headers = {}, response = d3_identity, request = new (d3_window.XDomainRequest && /^(http(s)?:)?\/\//.test(url) ? XDomainRequest : XMLHttpRequest)(); + "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { + request.readyState > 3 && respond(); + }; + function respond() { + var s = request.status; + !s && request.responseText || s >= 200 && s < 300 || s === 304 ? dispatch.load.call(xhr, response.call(xhr, request)) : dispatch.error.call(xhr, request); + } + request.onprogress = function(event) { + var o = d3.event; + d3.event = event; + try { + dispatch.progress.call(xhr, request); + } finally { + d3.event = o; + } + }; + xhr.header = function(name, value) { + name = (name + "").toLowerCase(); + if (arguments.length < 2) return headers[name]; + if (value == null) delete headers[name]; else headers[name] = value + ""; + return xhr; + }; + xhr.mimeType = function(value) { + if (!arguments.length) return mimeType; + mimeType = value == null ? null : value + ""; + return xhr; + }; + xhr.response = function(value) { + response = value; + return xhr; + }; + [ "get", "post" ].forEach(function(method) { + xhr[method] = function() { + return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); + }; + }); + xhr.send = function(method, data, callback) { + if (arguments.length === 2 && typeof data === "function") callback = data, data = null; + request.open(method, url, true); + if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; + if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); + if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); + if (callback != null) xhr.on("error", callback).on("load", function(request) { + callback(null, request); + }); + request.send(data == null ? null : data); + return xhr; + }; + xhr.abort = function() { + request.abort(); + return xhr; + }; + d3.rebind(xhr, dispatch, "on"); + if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, + mimeType = null; + return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); + }; + function d3_xhr_fixCallback(callback) { + return callback.length === 1 ? function(error, request) { + callback(error == null ? request : null); + } : callback; + } + function d3_dsv(delimiter, mimeType) { + var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); + function dsv(url, row, callback) { + if (arguments.length < 3) callback = row, row = null; + var xhr = d3.xhr(url, mimeType, callback); + xhr.row = function(_) { + return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; + }; + return xhr.row(row); + } + function response(request) { + return dsv.parse(request.responseText); + } + function typedResponse(f) { + return function(request) { + return dsv.parse(request.responseText, f); + }; + } + dsv.parse = function(text, f) { + var o; + return dsv.parseRows(text, function(row, i) { + if (o) return o(row, i - 1); + var a = new Function("d", "return {" + row.map(function(name, i) { + return JSON.stringify(name) + ": d[" + i + "]"; + }).join(",") + "}"); + o = f ? function(row, i) { + return f(a(row), i); + } : a; + }); + }; + dsv.parseRows = function(text, f) { + var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; + function token() { + if (I >= N) return EOF; + if (eol) return eol = false, EOL; + var j = I; + if (text.charCodeAt(j) === 34) { + var i = j; + while (i++ < N) { + if (text.charCodeAt(i) === 34) { + if (text.charCodeAt(i + 1) !== 34) break; + ++i; + } + } + I = i + 2; + var c = text.charCodeAt(i + 1); + if (c === 13) { + eol = true; + if (text.charCodeAt(i + 2) === 10) ++I; + } else if (c === 10) { + eol = true; + } + return text.substring(j + 1, i).replace(/""/g, '"'); + } + while (I < N) { + var c = text.charCodeAt(I++), k = 1; + if (c === 10) eol = true; else if (c === 13) { + eol = true; + if (text.charCodeAt(I) === 10) ++I, ++k; + } else if (c !== delimiterCode) continue; + return text.substring(j, I - k); + } + return text.substring(j); + } + while ((t = token()) !== EOF) { + var a = []; + while (t !== EOL && t !== EOF) { + a.push(t); + t = token(); + } + if (f && !(a = f(a, n++))) continue; + rows.push(a); + } + return rows; + }; + dsv.format = function(rows) { + if (Array.isArray(rows[0])) return dsv.formatRows(rows); + var fieldSet = new d3_Set(), fields = []; + rows.forEach(function(row) { + for (var field in row) { + if (!fieldSet.has(field)) { + fields.push(fieldSet.add(field)); + } + } + }); + return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { + return fields.map(function(field) { + return formatValue(row[field]); + }).join(delimiter); + })).join("\n"); + }; + dsv.formatRows = function(rows) { + return rows.map(formatRow).join("\n"); + }; + function formatRow(row) { + return row.map(formatValue).join(delimiter); + } + function formatValue(text) { + return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; + } + return dsv; + } + d3.csv = d3_dsv(",", "text/csv"); + d3.tsv = d3_dsv(" ", "text/tab-separated-values"); + var d3_timer_id = 0, d3_timer_byId = {}, d3_timer_queue = null, d3_timer_interval, d3_timer_timeout; + d3.timer = function(callback, delay, then) { + if (arguments.length < 3) { + if (arguments.length < 2) delay = 0; else if (!isFinite(delay)) return; + then = Date.now(); + } + var timer = d3_timer_byId[callback.id]; + if (timer && timer.callback === callback) { + timer.then = then; + timer.delay = delay; + } else d3_timer_byId[callback.id = ++d3_timer_id] = d3_timer_queue = { + callback: callback, + then: then, + delay: delay, + next: d3_timer_queue + }; + if (!d3_timer_interval) { + d3_timer_timeout = clearTimeout(d3_timer_timeout); + d3_timer_interval = 1; + d3_timer_frame(d3_timer_step); + } + }; + function d3_timer_step() { + var elapsed, now = Date.now(), t1 = d3_timer_queue; + while (t1) { + elapsed = now - t1.then; + if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed); + t1 = t1.next; + } + var delay = d3_timer_flush() - now; + if (delay > 24) { + if (isFinite(delay)) { + clearTimeout(d3_timer_timeout); + d3_timer_timeout = setTimeout(d3_timer_step, delay); + } + d3_timer_interval = 0; + } else { + d3_timer_interval = 1; + d3_timer_frame(d3_timer_step); + } + } + d3.timer.flush = function() { + var elapsed, now = Date.now(), t1 = d3_timer_queue; + while (t1) { + elapsed = now - t1.then; + if (!t1.delay) t1.flush = t1.callback(elapsed); + t1 = t1.next; + } + d3_timer_flush(); + }; + function d3_timer_flush() { + var t0 = null, t1 = d3_timer_queue, then = Infinity; + while (t1) { + if (t1.flush) { + delete d3_timer_byId[t1.callback.id]; + t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next; + } else { + then = Math.min(then, t1.then + t1.delay); + t1 = (t0 = t1).next; + } + } + return then; + } + var d3_timer_frame = d3_window.requestAnimationFrame || d3_window.webkitRequestAnimationFrame || d3_window.mozRequestAnimationFrame || d3_window.oRequestAnimationFrame || d3_window.msRequestAnimationFrame || function(callback) { + setTimeout(callback, 17); + }; + var d3_format_decimalPoint = ".", d3_format_thousandsSeparator = ",", d3_format_grouping = [ 3, 3 ]; + var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); + d3.formatPrefix = function(value, precision) { + var i = 0; + if (value) { + if (value < 0) value *= -1; + if (precision) value = d3.round(value, d3_format_precision(value, precision)); + i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); + i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3)); + } + return d3_formatPrefixes[8 + i / 3]; + }; + function d3_formatPrefix(d, i) { + var k = Math.pow(10, Math.abs(8 - i) * 3); + return { + scale: i > 8 ? function(d) { + return d / k; + } : function(d) { + return d * k; + }, + symbol: d + }; + } + d3.round = function(x, n) { + return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); + }; + d3.format = function(specifier) { + var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "", basePrefix = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, suffix = "", integer = false; + if (precision) precision = +precision.substring(1); + if (zfill || fill === "0" && align === "=") { + zfill = fill = "0"; + align = "="; + if (comma) width -= Math.floor((width - 1) / 4); + } + switch (type) { + case "n": + comma = true; + type = "g"; + break; + + case "%": + scale = 100; + suffix = "%"; + type = "f"; + break; + + case "p": + scale = 100; + suffix = "%"; + type = "r"; + break; + + case "b": + case "o": + case "x": + case "X": + if (basePrefix) basePrefix = "0" + type.toLowerCase(); + + case "c": + case "d": + integer = true; + precision = 0; + break; + + case "s": + scale = -1; + type = "r"; + break; + } + if (basePrefix === "#") basePrefix = ""; + if (type == "r" && !precision) type = "g"; + if (precision != null) { + if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); + } + type = d3_format_types.get(type) || d3_format_typeDefault; + var zcomma = zfill && comma; + return function(value) { + if (integer && value % 1) return ""; + var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign; + if (scale < 0) { + var prefix = d3.formatPrefix(value, precision); + value = prefix.scale(value); + suffix = prefix.symbol; + } else { + value *= scale; + } + value = type(value, precision); + if (!zfill && comma) value = d3_format_group(value); + var length = basePrefix.length + value.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; + if (zcomma) value = d3_format_group(padding + value); + if (d3_format_decimalPoint) value.replace(".", d3_format_decimalPoint); + negative += basePrefix; + return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + suffix; + }; + }; + var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; + var d3_format_types = d3.map({ + b: function(x) { + return x.toString(2); + }, + c: function(x) { + return String.fromCharCode(x); + }, + o: function(x) { + return x.toString(8); + }, + x: function(x) { + return x.toString(16); + }, + X: function(x) { + return x.toString(16).toUpperCase(); + }, + g: function(x, p) { + return x.toPrecision(p); + }, + e: function(x, p) { + return x.toExponential(p); + }, + f: function(x, p) { + return x.toFixed(p); + }, + r: function(x, p) { + return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); + } + }); + function d3_format_precision(x, p) { + return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); + } + function d3_format_typeDefault(x) { + return x + ""; + } + var d3_format_group = d3_identity; + if (d3_format_grouping) { + var d3_format_groupingLength = d3_format_grouping.length; + d3_format_group = function(value) { + var i = value.lastIndexOf("."), f = i >= 0 ? "." + value.substring(i + 1) : (i = value.length, + ""), t = [], j = 0, g = d3_format_grouping[0]; + while (i > 0 && g > 0) { + t.push(value.substring(i -= g, i + g)); + g = d3_format_grouping[j = (j + 1) % d3_format_groupingLength]; + } + return t.reverse().join(d3_format_thousandsSeparator || "") + f; + }; + } + d3.geo = {}; + d3.geo.stream = function(object, listener) { + if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { + d3_geo_streamObjectType[object.type](object, listener); + } else { + d3_geo_streamGeometry(object, listener); + } + }; + function d3_geo_streamGeometry(geometry, listener) { + if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { + d3_geo_streamGeometryType[geometry.type](geometry, listener); + } + } + var d3_geo_streamObjectType = { + Feature: function(feature, listener) { + d3_geo_streamGeometry(feature.geometry, listener); + }, + FeatureCollection: function(object, listener) { + var features = object.features, i = -1, n = features.length; + while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); + } + }; + var d3_geo_streamGeometryType = { + Sphere: function(object, listener) { + listener.sphere(); + }, + Point: function(object, listener) { + var coordinate = object.coordinates; + listener.point(coordinate[0], coordinate[1]); + }, + MultiPoint: function(object, listener) { + var coordinates = object.coordinates, i = -1, n = coordinates.length, coordinate; + while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]); + }, + LineString: function(object, listener) { + d3_geo_streamLine(object.coordinates, listener, 0); + }, + MultiLineString: function(object, listener) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); + }, + Polygon: function(object, listener) { + d3_geo_streamPolygon(object.coordinates, listener); + }, + MultiPolygon: function(object, listener) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); + }, + GeometryCollection: function(object, listener) { + var geometries = object.geometries, i = -1, n = geometries.length; + while (++i < n) d3_geo_streamGeometry(geometries[i], listener); + } + }; + function d3_geo_streamLine(coordinates, listener, closed) { + var i = -1, n = coordinates.length - closed, coordinate; + listener.lineStart(); + while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]); + listener.lineEnd(); + } + function d3_geo_streamPolygon(coordinates, listener) { + var i = -1, n = coordinates.length; + listener.polygonStart(); + while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); + listener.polygonEnd(); + } + d3.geo.area = function(object) { + d3_geo_areaSum = 0; + d3.geo.stream(object, d3_geo_area); + return d3_geo_areaSum; + }; + var d3_geo_areaSum, d3_geo_areaRingSum; + var d3_geo_area = { + sphere: function() { + d3_geo_areaSum += 4 * Ï€; + }, + point: d3_noop, + lineStart: d3_noop, + lineEnd: d3_noop, + polygonStart: function() { + d3_geo_areaRingSum = 0; + d3_geo_area.lineStart = d3_geo_areaRingStart; + }, + polygonEnd: function() { + var area = 2 * d3_geo_areaRingSum; + d3_geo_areaSum += area < 0 ? 4 * Ï€ + area : area; + d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; + } + }; + function d3_geo_areaRingStart() { + var λ00, φ00, λ0, cosφ0, sinφ0; + d3_geo_area.point = function(λ, φ) { + d3_geo_area.point = nextPoint; + λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + Ï€ / 4), + sinφ0 = Math.sin(φ); + }; + function nextPoint(λ, φ) { + λ *= d3_radians; + φ = φ * d3_radians / 2 + Ï€ / 4; + var dλ = λ - λ0, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(dλ), v = k * Math.sin(dλ); + d3_geo_areaRingSum += Math.atan2(v, u); + λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; + } + d3_geo_area.lineEnd = function() { + nextPoint(λ00, φ00); + }; + } + function d3_geo_cartesian(spherical) { + var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); + return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; + } + function d3_geo_cartesianDot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + function d3_geo_cartesianCross(a, b) { + return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; + } + function d3_geo_cartesianAdd(a, b) { + a[0] += b[0]; + a[1] += b[1]; + a[2] += b[2]; + } + function d3_geo_cartesianScale(vector, k) { + return [ vector[0] * k, vector[1] * k, vector[2] * k ]; + } + function d3_geo_cartesianNormalize(d) { + var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); + d[0] /= l; + d[1] /= l; + d[2] /= l; + } + function d3_geo_spherical(cartesian) { + return [ Math.atan2(cartesian[1], cartesian[0]), Math.asin(Math.max(-1, Math.min(1, cartesian[2]))) ]; + } + function d3_geo_sphericalEqual(a, b) { + return Math.abs(a[0] - b[0]) < ε && Math.abs(a[1] - b[1]) < ε; + } + d3.geo.bounds = function() { + var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; + var bound = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + bound.point = ringPoint; + bound.lineStart = ringStart; + bound.lineEnd = ringEnd; + dλSum = 0; + d3_geo_area.polygonStart(); + }, + polygonEnd: function() { + d3_geo_area.polygonEnd(); + bound.point = point; + bound.lineStart = lineStart; + bound.lineEnd = lineEnd; + if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; + range[0] = λ0, range[1] = λ1; + } + }; + function point(λ, φ) { + ranges.push(range = [ λ0 = λ, λ1 = λ ]); + if (φ < φ0) φ0 = φ; + if (φ > φ1) φ1 = φ; + } + function linePoint(λ, φ) { + var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); + if (p0) { + var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); + d3_geo_cartesianNormalize(inflection); + inflection = d3_geo_spherical(inflection); + var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = Math.abs(dλ) > 180; + if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { + var φi = inflection[1] * d3_degrees; + if (φi > φ1) φ1 = φi; + } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { + var φi = -inflection[1] * d3_degrees; + if (φi < φ0) φ0 = φi; + } else { + if (φ < φ0) φ0 = φ; + if (φ > φ1) φ1 = φ; + } + if (antimeridian) { + if (λ < λ_) { + if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; + } else { + if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; + } + } else { + if (λ1 >= λ0) { + if (λ < λ0) λ0 = λ; + if (λ > λ1) λ1 = λ; + } else { + if (λ > λ_) { + if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; + } else { + if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; + } + } + } + } else { + point(λ, φ); + } + p0 = p, λ_ = λ; + } + function lineStart() { + bound.point = linePoint; + } + function lineEnd() { + range[0] = λ0, range[1] = λ1; + bound.point = point; + p0 = null; + } + function ringPoint(λ, φ) { + if (p0) { + var dλ = λ - λ_; + dλSum += Math.abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; + } else λ__ = λ, φ__ = φ; + d3_geo_area.point(λ, φ); + linePoint(λ, φ); + } + function ringStart() { + d3_geo_area.lineStart(); + } + function ringEnd() { + ringPoint(λ__, φ__); + d3_geo_area.lineEnd(); + if (Math.abs(dλSum) > ε) λ0 = -(λ1 = 180); + range[0] = λ0, range[1] = λ1; + p0 = null; + } + function angle(λ0, λ1) { + return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; + } + function compareRanges(a, b) { + return a[0] - b[0]; + } + function withinRange(x, range) { + return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; + } + return function(feature) { + φ1 = λ1 = -(λ0 = φ0 = Infinity); + ranges = []; + d3.geo.stream(feature, bound); + ranges.sort(compareRanges); + for (var i = 1, n = ranges.length, a = ranges[0], b, merged = [ a ]; i < n; ++i) { + b = ranges[i]; + if (withinRange(b[0], a) || withinRange(b[1], a)) { + if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; + if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; + } else { + merged.push(a = b); + } + } + var best = -Infinity, dλ; + for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { + b = merged[i]; + if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; + } + ranges = range = null; + return [ [ λ0, φ0 ], [ λ1, φ1 ] ]; + }; + }(); + d3.geo.centroid = function(object) { + d3_geo_centroidDimension = d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; + d3.geo.stream(object, d3_geo_centroid); + var m; + if (d3_geo_centroidW && Math.abs(m = Math.sqrt(d3_geo_centroidX * d3_geo_centroidX + d3_geo_centroidY * d3_geo_centroidY + d3_geo_centroidZ * d3_geo_centroidZ)) > ε) { + return [ Math.atan2(d3_geo_centroidY, d3_geo_centroidX) * d3_degrees, Math.asin(Math.max(-1, Math.min(1, d3_geo_centroidZ / m))) * d3_degrees ]; + } + }; + var d3_geo_centroidDimension, d3_geo_centroidW, d3_geo_centroidX, d3_geo_centroidY, d3_geo_centroidZ; + var d3_geo_centroid = { + sphere: function() { + if (d3_geo_centroidDimension < 2) { + d3_geo_centroidDimension = 2; + d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; + } + }, + point: d3_geo_centroidPoint, + lineStart: d3_geo_centroidLineStart, + lineEnd: d3_geo_centroidLineEnd, + polygonStart: function() { + if (d3_geo_centroidDimension < 2) { + d3_geo_centroidDimension = 2; + d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; + } + d3_geo_centroid.lineStart = d3_geo_centroidRingStart; + }, + polygonEnd: function() { + d3_geo_centroid.lineStart = d3_geo_centroidLineStart; + } + }; + function d3_geo_centroidPoint(λ, φ) { + if (d3_geo_centroidDimension) return; + ++d3_geo_centroidW; + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians); + d3_geo_centroidX += (cosφ * Math.cos(λ) - d3_geo_centroidX) / d3_geo_centroidW; + d3_geo_centroidY += (cosφ * Math.sin(λ) - d3_geo_centroidY) / d3_geo_centroidW; + d3_geo_centroidZ += (Math.sin(φ) - d3_geo_centroidZ) / d3_geo_centroidW; + } + function d3_geo_centroidRingStart() { + var λ00, φ00; + d3_geo_centroidDimension = 1; + d3_geo_centroidLineStart(); + d3_geo_centroidDimension = 2; + var linePoint = d3_geo_centroid.point; + d3_geo_centroid.point = function(λ, φ) { + linePoint(λ00 = λ, φ00 = φ); + }; + d3_geo_centroid.lineEnd = function() { + d3_geo_centroid.point(λ00, φ00); + d3_geo_centroidLineEnd(); + d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; + }; + } + function d3_geo_centroidLineStart() { + var x0, y0, z0; + if (d3_geo_centroidDimension > 1) return; + if (d3_geo_centroidDimension < 1) { + d3_geo_centroidDimension = 1; + d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; + } + d3_geo_centroid.point = function(λ, φ) { + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians); + x0 = cosφ * Math.cos(λ); + y0 = cosφ * Math.sin(λ); + z0 = Math.sin(φ); + d3_geo_centroid.point = nextPoint; + }; + function nextPoint(λ, φ) { + λ *= d3_radians; + var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); + d3_geo_centroidW += w; + d3_geo_centroidX += w * (x0 + (x0 = x)); + d3_geo_centroidY += w * (y0 + (y0 = y)); + d3_geo_centroidZ += w * (z0 + (z0 = z)); + } + } + function d3_geo_centroidLineEnd() { + d3_geo_centroid.point = d3_geo_centroidPoint; + } + function d3_true() { + return true; + } + function d3_geo_clipPolygon(segments, compare, inside, interpolate, listener) { + var subject = [], clip = []; + segments.forEach(function(segment) { + if ((n = segment.length - 1) <= 0) return; + var n, p0 = segment[0], p1 = segment[n]; + if (d3_geo_sphericalEqual(p0, p1)) { + listener.lineStart(); + for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); + listener.lineEnd(); + return; + } + var a = { + point: p0, + points: segment, + other: null, + visited: false, + entry: true, + subject: true + }, b = { + point: p0, + points: [ p0 ], + other: a, + visited: false, + entry: false, + subject: false + }; + a.other = b; + subject.push(a); + clip.push(b); + a = { + point: p1, + points: [ p1 ], + other: null, + visited: false, + entry: false, + subject: true + }; + b = { + point: p1, + points: [ p1 ], + other: a, + visited: false, + entry: true, + subject: false + }; + a.other = b; + subject.push(a); + clip.push(b); + }); + clip.sort(compare); + d3_geo_clipPolygonLinkCircular(subject); + d3_geo_clipPolygonLinkCircular(clip); + if (!subject.length) return; + if (inside) for (var i = 1, e = !inside(clip[0].point), n = clip.length; i < n; ++i) { + clip[i].entry = e = !e; + } + var start = subject[0], current, points, point; + while (1) { + current = start; + while (current.visited) if ((current = current.next) === start) return; + points = current.points; + listener.lineStart(); + do { + current.visited = current.other.visited = true; + if (current.entry) { + if (current.subject) { + for (var i = 0; i < points.length; i++) listener.point((point = points[i])[0], point[1]); + } else { + interpolate(current.point, current.next.point, 1, listener); + } + current = current.next; + } else { + if (current.subject) { + points = current.prev.points; + for (var i = points.length; --i >= 0; ) listener.point((point = points[i])[0], point[1]); + } else { + interpolate(current.point, current.prev.point, -1, listener); + } + current = current.prev; + } + current = current.other; + points = current.points; + } while (!current.visited); + listener.lineEnd(); + } + } + function d3_geo_clipPolygonLinkCircular(array) { + if (!(n = array.length)) return; + var n, i = 0, a = array[0], b; + while (++i < n) { + a.next = b = array[i]; + b.prev = a; + a = b; + } + a.next = b = array[0]; + b.prev = a; + } + function d3_geo_clip(pointVisible, clipLine, interpolate) { + return function(listener) { + var line = clipLine(listener); + var clip = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + clip.point = pointRing; + clip.lineStart = ringStart; + clip.lineEnd = ringEnd; + invisible = false; + invisibleArea = visibleArea = 0; + segments = []; + listener.polygonStart(); + }, + polygonEnd: function() { + clip.point = point; + clip.lineStart = lineStart; + clip.lineEnd = lineEnd; + segments = d3.merge(segments); + if (segments.length) { + d3_geo_clipPolygon(segments, d3_geo_clipSort, null, interpolate, listener); + } else if (visibleArea < -ε || invisible && invisibleArea < -ε) { + listener.lineStart(); + interpolate(null, null, 1, listener); + listener.lineEnd(); + } + listener.polygonEnd(); + segments = null; + }, + sphere: function() { + listener.polygonStart(); + listener.lineStart(); + interpolate(null, null, 1, listener); + listener.lineEnd(); + listener.polygonEnd(); + } + }; + function point(λ, φ) { + if (pointVisible(λ, φ)) listener.point(λ, φ); + } + function pointLine(λ, φ) { + line.point(λ, φ); + } + function lineStart() { + clip.point = pointLine; + line.lineStart(); + } + function lineEnd() { + clip.point = point; + line.lineEnd(); + } + var segments, visibleArea, invisibleArea, invisible; + var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), ring; + function pointRing(λ, φ) { + ringListener.point(λ, φ); + ring.push([ λ, φ ]); + } + function ringStart() { + ringListener.lineStart(); + ring = []; + } + function ringEnd() { + pointRing(ring[0][0], ring[0][1]); + ringListener.lineEnd(); + var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; + if (!n) { + invisible = true; + invisibleArea += d3_geo_clipAreaRing(ring, -1); + ring = null; + return; + } + ring = null; + if (clean & 1) { + segment = ringSegments[0]; + visibleArea += d3_geo_clipAreaRing(segment, 1); + var n = segment.length - 1, i = -1, point; + listener.lineStart(); + while (++i < n) listener.point((point = segment[i])[0], point[1]); + listener.lineEnd(); + return; + } + if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); + segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); + } + return clip; + }; + } + function d3_geo_clipSegmentLength1(segment) { + return segment.length > 1; + } + function d3_geo_clipBufferListener() { + var lines = [], line; + return { + lineStart: function() { + lines.push(line = []); + }, + point: function(λ, φ) { + line.push([ λ, φ ]); + }, + lineEnd: d3_noop, + buffer: function() { + var buffer = lines; + lines = []; + line = null; + return buffer; + }, + rejoin: function() { + if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); + } + }; + } + function d3_geo_clipAreaRing(ring, invisible) { + if (!(n = ring.length)) return 0; + var n, i = 0, area = 0, p = ring[0], λ = p[0], φ = p[1], cosφ = Math.cos(φ), x0 = Math.atan2(invisible * Math.sin(λ) * cosφ, Math.sin(φ)), y0 = 1 - invisible * Math.cos(λ) * cosφ, x1 = x0, x, y; + while (++i < n) { + p = ring[i]; + cosφ = Math.cos(φ = p[1]); + x = Math.atan2(invisible * Math.sin(λ = p[0]) * cosφ, Math.sin(φ)); + y = 1 - invisible * Math.cos(λ) * cosφ; + if (Math.abs(y0 - 2) < ε && Math.abs(y - 2) < ε) continue; + if (Math.abs(y) < ε || Math.abs(y0) < ε) {} else if (Math.abs(Math.abs(x - x0) - Ï€) < ε) { + if (y + y0 > 2) area += 4 * (x - x0); + } else if (Math.abs(y0 - 2) < ε) area += 4 * (x - x1); else area += ((3 * Ï€ + x - x0) % (2 * Ï€) - Ï€) * (y0 + y); + x1 = x0, x0 = x, y0 = y; + } + return area; + } + function d3_geo_clipSort(a, b) { + return ((a = a.point)[0] < 0 ? a[1] - Ï€ / 2 - ε : Ï€ / 2 - a[1]) - ((b = b.point)[0] < 0 ? b[1] - Ï€ / 2 - ε : Ï€ / 2 - b[1]); + } + var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate); + function d3_geo_clipAntimeridianLine(listener) { + var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; + return { + lineStart: function() { + listener.lineStart(); + clean = 1; + }, + point: function(λ1, φ1) { + var sλ1 = λ1 > 0 ? Ï€ : -Ï€, dλ = Math.abs(λ1 - λ0); + if (Math.abs(dλ - Ï€) < ε) { + listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? Ï€ / 2 : -Ï€ / 2); + listener.point(sλ0, φ0); + listener.lineEnd(); + listener.lineStart(); + listener.point(sλ1, φ0); + listener.point(λ1, φ0); + clean = 0; + } else if (sλ0 !== sλ1 && dλ >= Ï€) { + if (Math.abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; + if (Math.abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; + φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); + listener.point(sλ0, φ0); + listener.lineEnd(); + listener.lineStart(); + listener.point(sλ1, φ0); + clean = 0; + } + listener.point(λ0 = λ1, φ0 = φ1); + sλ0 = sλ1; + }, + lineEnd: function() { + listener.lineEnd(); + λ0 = φ0 = NaN; + }, + clean: function() { + return 2 - clean; + } + }; + } + function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { + var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); + return Math.abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; + } + function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { + var φ; + if (from == null) { + φ = direction * Ï€ / 2; + listener.point(-Ï€, φ); + listener.point(0, φ); + listener.point(Ï€, φ); + listener.point(Ï€, 0); + listener.point(Ï€, -φ); + listener.point(0, -φ); + listener.point(-Ï€, -φ); + listener.point(-Ï€, 0); + listener.point(-Ï€, φ); + } else if (Math.abs(from[0] - to[0]) > ε) { + var s = (from[0] < to[0] ? 1 : -1) * Ï€; + φ = direction * s / 2; + listener.point(-s, φ); + listener.point(0, φ); + listener.point(s, φ); + } else { + listener.point(to[0], to[1]); + } + } + function d3_geo_clipCircle(radius) { + var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = Math.abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); + return d3_geo_clip(visible, clipLine, interpolate); + function visible(λ, φ) { + return Math.cos(λ) * Math.cos(φ) > cr; + } + function clipLine(listener) { + var point0, c0, v0, v00, clean; + return { + lineStart: function() { + v00 = v0 = false; + clean = 1; + }, + point: function(λ, φ) { + var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? Ï€ : -Ï€), φ) : 0; + if (!point0 && (v00 = v0 = v)) listener.lineStart(); + if (v !== v0) { + point2 = intersect(point0, point1); + if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { + point1[0] += ε; + point1[1] += ε; + v = visible(point1[0], point1[1]); + } + } + if (v !== v0) { + clean = 0; + if (v) { + listener.lineStart(); + point2 = intersect(point1, point0); + listener.point(point2[0], point2[1]); + } else { + point2 = intersect(point0, point1); + listener.point(point2[0], point2[1]); + listener.lineEnd(); + } + point0 = point2; + } else if (notHemisphere && point0 && smallRadius ^ v) { + var t; + if (!(c & c0) && (t = intersect(point1, point0, true))) { + clean = 0; + if (smallRadius) { + listener.lineStart(); + listener.point(t[0][0], t[0][1]); + listener.point(t[1][0], t[1][1]); + listener.lineEnd(); + } else { + listener.point(t[1][0], t[1][1]); + listener.lineEnd(); + listener.lineStart(); + listener.point(t[0][0], t[0][1]); + } + } + } + if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { + listener.point(point1[0], point1[1]); + } + point0 = point1, v0 = v, c0 = c; + }, + lineEnd: function() { + if (v0) listener.lineEnd(); + point0 = null; + }, + clean: function() { + return clean | (v00 && v0) << 1; + } + }; + } + function intersect(a, b, two) { + var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); + var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; + if (!determinant) return !two && a; + var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); + d3_geo_cartesianAdd(A, B); + var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); + if (t2 < 0) return; + var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); + d3_geo_cartesianAdd(q, A); + q = d3_geo_spherical(q); + if (!two) return q; + var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; + if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; + var δλ = λ1 - λ0, polar = Math.abs(δλ - Ï€) < ε, meridian = polar || δλ < ε; + if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; + if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (Math.abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > Ï€ ^ (λ0 <= q[0] && q[0] <= λ1)) { + var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); + d3_geo_cartesianAdd(q1, A); + return [ q, d3_geo_spherical(q1) ]; + } + } + function code(λ, φ) { + var r = smallRadius ? radius : Ï€ - radius, code = 0; + if (λ < -r) code |= 1; else if (λ > r) code |= 2; + if (φ < -r) code |= 4; else if (φ > r) code |= 8; + return code; + } + } + var d3_geo_clipViewMAX = 1e9; + function d3_geo_clipView(x0, y0, x1, y1) { + return function(listener) { + var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), segments, polygon, ring; + var clip = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + listener = bufferListener; + segments = []; + polygon = []; + }, + polygonEnd: function() { + listener = listener_; + if ((segments = d3.merge(segments)).length) { + listener.polygonStart(); + d3_geo_clipPolygon(segments, compare, inside, interpolate, listener); + listener.polygonEnd(); + } else if (insidePolygon([ x0, y0 ])) { + listener.polygonStart(), listener.lineStart(); + interpolate(null, null, 1, listener); + listener.lineEnd(), listener.polygonEnd(); + } + segments = polygon = ring = null; + } + }; + function inside(point) { + var a = corner(point, -1), i = insidePolygon([ a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0 ]); + return i; + } + function insidePolygon(p) { + var wn = 0, n = polygon.length, y = p[1]; + for (var i = 0; i < n; ++i) { + for (var j = 1, v = polygon[i], m = v.length, a = v[0]; j < m; ++j) { + b = v[j]; + if (a[1] <= y) { + if (b[1] > y && isLeft(a, b, p) > 0) ++wn; + } else { + if (b[1] <= y && isLeft(a, b, p) < 0) --wn; + } + a = b; + } + } + return wn !== 0; + } + function isLeft(a, b, c) { + return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]); + } + function interpolate(from, to, direction, listener) { + var a = 0, a1 = 0; + if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { + do { + listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); + } while ((a = (a + direction + 4) % 4) !== a1); + } else { + listener.point(to[0], to[1]); + } + } + function visible(x, y) { + return x0 <= x && x <= x1 && y0 <= y && y <= y1; + } + function point(x, y) { + if (visible(x, y)) listener.point(x, y); + } + var x__, y__, v__, x_, y_, v_, first; + function lineStart() { + clip.point = linePoint; + if (polygon) polygon.push(ring = []); + first = true; + v_ = false; + x_ = y_ = NaN; + } + function lineEnd() { + if (segments) { + linePoint(x__, y__); + if (v__ && v_) bufferListener.rejoin(); + segments.push(bufferListener.buffer()); + } + clip.point = point; + if (v_) listener.lineEnd(); + } + function linePoint(x, y) { + x = Math.max(-d3_geo_clipViewMAX, Math.min(d3_geo_clipViewMAX, x)); + y = Math.max(-d3_geo_clipViewMAX, Math.min(d3_geo_clipViewMAX, y)); + var v = visible(x, y); + if (polygon) ring.push([ x, y ]); + if (first) { + x__ = x, y__ = y, v__ = v; + first = false; + if (v) { + listener.lineStart(); + listener.point(x, y); + } + } else { + if (v && v_) listener.point(x, y); else { + var a = [ x_, y_ ], b = [ x, y ]; + if (clipLine(a, b)) { + if (!v_) { + listener.lineStart(); + listener.point(a[0], a[1]); + } + listener.point(b[0], b[1]); + if (!v) listener.lineEnd(); + } else if (v) { + listener.lineStart(); + listener.point(x, y); + } + } + } + x_ = x, y_ = y, v_ = v; + } + return clip; + }; + function corner(p, direction) { + return Math.abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : Math.abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : Math.abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; + } + function compare(a, b) { + return comparePoints(a.point, b.point); + } + function comparePoints(a, b) { + var ca = corner(a, 1), cb = corner(b, 1); + return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; + } + function clipLine(a, b) { + var dx = b[0] - a[0], dy = b[1] - a[1], t = [ 0, 1 ]; + if (Math.abs(dx) < ε && Math.abs(dy) < ε) return x0 <= a[0] && a[0] <= x1 && y0 <= a[1] && a[1] <= y1; + if (d3_geo_clipViewT(x0 - a[0], dx, t) && d3_geo_clipViewT(a[0] - x1, -dx, t) && d3_geo_clipViewT(y0 - a[1], dy, t) && d3_geo_clipViewT(a[1] - y1, -dy, t)) { + if (t[1] < 1) { + b[0] = a[0] + t[1] * dx; + b[1] = a[1] + t[1] * dy; + } + if (t[0] > 0) { + a[0] += t[0] * dx; + a[1] += t[0] * dy; + } + return true; + } + return false; + } + } + function d3_geo_clipViewT(num, denominator, t) { + if (Math.abs(denominator) < ε) return num <= 0; + var u = num / denominator; + if (denominator > 0) { + if (u > t[1]) return false; + if (u > t[0]) t[0] = u; + } else { + if (u < t[0]) return false; + if (u < t[1]) t[1] = u; + } + return true; + } + function d3_geo_compose(a, b) { + function compose(x, y) { + return x = a(x, y), b(x[0], x[1]); + } + if (a.invert && b.invert) compose.invert = function(x, y) { + return x = b.invert(x, y), x && a.invert(x[0], x[1]); + }; + return compose; + } + function d3_geo_resample(project) { + var δ2 = .5, maxDepth = 16; + function resample(stream) { + var λ0, x0, y0, a0, b0, c0; + var resample = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + stream.polygonStart(); + resample.lineStart = polygonLineStart; + }, + polygonEnd: function() { + stream.polygonEnd(); + resample.lineStart = lineStart; + } + }; + function point(x, y) { + x = project(x, y); + stream.point(x[0], x[1]); + } + function lineStart() { + x0 = NaN; + resample.point = linePoint; + stream.lineStart(); + } + function linePoint(λ, φ) { + var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); + resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); + stream.point(x0, y0); + } + function lineEnd() { + resample.point = point; + stream.lineEnd(); + } + function polygonLineStart() { + var λ00, φ00, x00, y00, a00, b00, c00; + lineStart(); + resample.point = function(λ, φ) { + linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; + resample.point = linePoint; + }; + resample.lineEnd = function() { + resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); + resample.lineEnd = lineEnd; + lineEnd(); + }; + } + return resample; + } + function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { + var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; + if (d2 > 4 * δ2 && depth--) { + var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; + if (dz * dz / d2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3) { + resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); + stream.point(x2, y2); + resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); + } + } + } + resample.precision = function(_) { + if (!arguments.length) return Math.sqrt(δ2); + maxDepth = (δ2 = _ * _) > 0 && 16; + return resample; + }; + return resample; + } + d3.geo.projection = d3_geo_projection; + d3.geo.projectionMutator = d3_geo_projectionMutator; + function d3_geo_projection(project) { + return d3_geo_projectionMutator(function() { + return project; + })(); + } + function d3_geo_projectionMutator(projectAt) { + var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { + x = project(x, y); + return [ x[0] * k + δx, δy - x[1] * k ]; + }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null; + function projection(point) { + point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); + return [ point[0] * k + δx, δy - point[1] * k ]; + } + function invert(point) { + point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); + return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; + } + projection.stream = function(stream) { + return d3_geo_projectionRadiansRotate(rotate, preclip(projectResample(postclip(stream)))); + }; + projection.clipAngle = function(_) { + if (!arguments.length) return clipAngle; + preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); + return projection; + }; + projection.clipExtent = function(_) { + if (!arguments.length) return clipExtent; + clipExtent = _; + postclip = _ == null ? d3_identity : d3_geo_clipView(_[0][0], _[0][1], _[1][0], _[1][1]); + return projection; + }; + projection.scale = function(_) { + if (!arguments.length) return k; + k = +_; + return reset(); + }; + projection.translate = function(_) { + if (!arguments.length) return [ x, y ]; + x = +_[0]; + y = +_[1]; + return reset(); + }; + projection.center = function(_) { + if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; + λ = _[0] % 360 * d3_radians; + φ = _[1] % 360 * d3_radians; + return reset(); + }; + projection.rotate = function(_) { + if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; + δλ = _[0] % 360 * d3_radians; + δφ = _[1] % 360 * d3_radians; + δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; + return reset(); + }; + d3.rebind(projection, projectResample, "precision"); + function reset() { + projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); + var center = project(λ, φ); + δx = x - center[0] * k; + δy = y + center[1] * k; + return projection; + } + return function() { + project = projectAt.apply(this, arguments); + projection.invert = project.invert && invert; + return reset(); + }; + } + function d3_geo_projectionRadiansRotate(rotate, stream) { + return { + point: function(x, y) { + y = rotate(x * d3_radians, y * d3_radians), x = y[0]; + stream.point(x > Ï€ ? x - 2 * Ï€ : x < -Ï€ ? x + 2 * Ï€ : x, y[1]); + }, + sphere: function() { + stream.sphere(); + }, + lineStart: function() { + stream.lineStart(); + }, + lineEnd: function() { + stream.lineEnd(); + }, + polygonStart: function() { + stream.polygonStart(); + }, + polygonEnd: function() { + stream.polygonEnd(); + } + }; + } + function d3_geo_equirectangular(λ, φ) { + return [ λ, φ ]; + } + (d3.geo.equirectangular = function() { + return d3_geo_projection(d3_geo_equirectangular); + }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; + d3.geo.rotation = function(rotate) { + rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); + function forward(coordinates) { + coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); + return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; + } + forward.invert = function(coordinates) { + coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); + return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; + }; + return forward; + }; + function d3_geo_rotation(δλ, δφ, δγ) { + return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_equirectangular; + } + function d3_geo_forwardRotationλ(δλ) { + return function(λ, φ) { + return λ += δλ, [ λ > Ï€ ? λ - 2 * Ï€ : λ < -Ï€ ? λ + 2 * Ï€ : λ, φ ]; + }; + } + function d3_geo_rotationλ(δλ) { + var rotation = d3_geo_forwardRotationλ(δλ); + rotation.invert = d3_geo_forwardRotationλ(-δλ); + return rotation; + } + function d3_geo_rotationφγ(δφ, δγ) { + var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); + function rotation(λ, φ) { + var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; + return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), Math.asin(Math.max(-1, Math.min(1, k * cosδγ + y * sinδγ))) ]; + } + rotation.invert = function(λ, φ) { + var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; + return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), Math.asin(Math.max(-1, Math.min(1, k * cosδφ - x * sinδφ))) ]; + }; + return rotation; + } + d3.geo.circle = function() { + var origin = [ 0, 0 ], angle, precision = 6, interpolate; + function circle() { + var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; + interpolate(null, null, 1, { + point: function(x, y) { + ring.push(x = rotate(x, y)); + x[0] *= d3_degrees, x[1] *= d3_degrees; + } + }); + return { + type: "Polygon", + coordinates: [ ring ] + }; + } + circle.origin = function(x) { + if (!arguments.length) return origin; + origin = x; + return circle; + }; + circle.angle = function(x) { + if (!arguments.length) return angle; + interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); + return circle; + }; + circle.precision = function(_) { + if (!arguments.length) return precision; + interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); + return circle; + }; + return circle.angle(90); + }; + function d3_geo_circleInterpolate(radius, precision) { + var cr = Math.cos(radius), sr = Math.sin(radius); + return function(from, to, direction, listener) { + if (from != null) { + from = d3_geo_circleAngle(cr, from); + to = d3_geo_circleAngle(cr, to); + if (direction > 0 ? from < to : from > to) from += direction * 2 * Ï€; + } else { + from = radius + direction * 2 * Ï€; + to = radius; + } + var point; + for (var step = direction * precision, t = from; direction > 0 ? t > to : t < to; t -= step) { + listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); + } + }; + } + function d3_geo_circleAngle(cr, point) { + var a = d3_geo_cartesian(point); + a[0] -= cr; + d3_geo_cartesianNormalize(a); + var angle = d3_acos(-a[1]); + return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); + } + d3.geo.distance = function(a, b) { + var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; + return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); + }; + d3.geo.graticule = function() { + var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; + function graticule() { + return { + type: "MultiLineString", + coordinates: lines() + }; + } + function lines() { + return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { + return Math.abs(x % DX) > ε; + }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { + return Math.abs(y % DY) > ε; + }).map(y)); + } + graticule.lines = function() { + return lines().map(function(coordinates) { + return { + type: "LineString", + coordinates: coordinates + }; + }); + }; + graticule.outline = function() { + return { + type: "Polygon", + coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] + }; + }; + graticule.extent = function(_) { + if (!arguments.length) return graticule.minorExtent(); + return graticule.majorExtent(_).minorExtent(_); + }; + graticule.majorExtent = function(_) { + if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ]; + X0 = +_[0][0], X1 = +_[1][0]; + Y0 = +_[0][1], Y1 = +_[1][1]; + if (X0 > X1) _ = X0, X0 = X1, X1 = _; + if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; + return graticule.precision(precision); + }; + graticule.minorExtent = function(_) { + if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; + x0 = +_[0][0], x1 = +_[1][0]; + y0 = +_[0][1], y1 = +_[1][1]; + if (x0 > x1) _ = x0, x0 = x1, x1 = _; + if (y0 > y1) _ = y0, y0 = y1, y1 = _; + return graticule.precision(precision); + }; + graticule.step = function(_) { + if (!arguments.length) return graticule.minorStep(); + return graticule.majorStep(_).minorStep(_); + }; + graticule.majorStep = function(_) { + if (!arguments.length) return [ DX, DY ]; + DX = +_[0], DY = +_[1]; + return graticule; + }; + graticule.minorStep = function(_) { + if (!arguments.length) return [ dx, dy ]; + dx = +_[0], dy = +_[1]; + return graticule; + }; + graticule.precision = function(_) { + if (!arguments.length) return precision; + precision = +_; + x = d3_geo_graticuleX(y0, y1, 90); + y = d3_geo_graticuleY(x0, x1, precision); + X = d3_geo_graticuleX(Y0, Y1, 90); + Y = d3_geo_graticuleY(X0, X1, precision); + return graticule; + }; + return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); + }; + function d3_geo_graticuleX(y0, y1, dy) { + var y = d3.range(y0, y1 - ε, dy).concat(y1); + return function(x) { + return y.map(function(y) { + return [ x, y ]; + }); + }; + } + function d3_geo_graticuleY(x0, x1, dx) { + var x = d3.range(x0, x1 - ε, dx).concat(x1); + return function(y) { + return x.map(function(x) { + return [ x, y ]; + }); + }; + } + function d3_source(d) { + return d.source; + } + function d3_target(d) { + return d.target; + } + d3.geo.greatArc = function() { + var source = d3_source, source_, target = d3_target, target_; + function greatArc() { + return { + type: "LineString", + coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] + }; + } + greatArc.distance = function() { + return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); + }; + greatArc.source = function(_) { + if (!arguments.length) return source; + source = _, source_ = typeof _ === "function" ? null : _; + return greatArc; + }; + greatArc.target = function(_) { + if (!arguments.length) return target; + target = _, target_ = typeof _ === "function" ? null : _; + return greatArc; + }; + greatArc.precision = function() { + return arguments.length ? greatArc : 0; + }; + return greatArc; + }; + d3.geo.interpolate = function(source, target) { + return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); + }; + function d3_geo_interpolate(x0, y0, x1, y1) { + var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); + var interpolate = d ? function(t) { + var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; + return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; + } : function() { + return [ x0 * d3_degrees, y0 * d3_degrees ]; + }; + interpolate.distance = d; + return interpolate; + } + d3.geo.length = function(object) { + d3_geo_lengthSum = 0; + d3.geo.stream(object, d3_geo_length); + return d3_geo_lengthSum; + }; + var d3_geo_lengthSum; + var d3_geo_length = { + sphere: d3_noop, + point: d3_noop, + lineStart: d3_geo_lengthLineStart, + lineEnd: d3_noop, + polygonStart: d3_noop, + polygonEnd: d3_noop + }; + function d3_geo_lengthLineStart() { + var λ0, sinφ0, cosφ0; + d3_geo_length.point = function(λ, φ) { + λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); + d3_geo_length.point = nextPoint; + }; + d3_geo_length.lineEnd = function() { + d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; + }; + function nextPoint(λ, φ) { + var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = Math.abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); + d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); + λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; + } + } + function d3_geo_conic(projectAt) { + var φ0 = 0, φ1 = Ï€ / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); + p.parallels = function(_) { + if (!arguments.length) return [ φ0 / Ï€ * 180, φ1 / Ï€ * 180 ]; + return m(φ0 = _[0] * Ï€ / 180, φ1 = _[1] * Ï€ / 180); + }; + return p; + } + function d3_geo_conicEqualArea(φ0, φ1) { + var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), Ï0 = Math.sqrt(C) / n; + function forward(λ, φ) { + var Ï = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; + return [ Ï * Math.sin(λ *= n), Ï0 - Ï * Math.cos(λ) ]; + } + forward.invert = function(x, y) { + var Ï0_y = Ï0 - y; + return [ Math.atan2(x, Ï0_y) / n, d3_asin((C - (x * x + Ï0_y * Ï0_y) * n * n) / (2 * n)) ]; + }; + return forward; + } + (d3.geo.conicEqualArea = function() { + return d3_geo_conic(d3_geo_conicEqualArea); + }).raw = d3_geo_conicEqualArea; + d3.geo.albers = function() { + return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); + }; + d3.geo.albersUsa = function() { + var lower48 = d3.geo.albers(); + var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); + var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); + var point, pointStream = { + point: function(x, y) { + point = [ x, y ]; + } + }, lower48Point, alaskaPoint, hawaiiPoint; + function albersUsa(coordinates) { + var x = coordinates[0], y = coordinates[1]; + point = null; + (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); + return point; + } + albersUsa.invert = function(coordinates) { + var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; + return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); + }; + albersUsa.stream = function(stream) { + var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); + return { + point: function(x, y) { + lower48Stream.point(x, y); + alaskaStream.point(x, y); + hawaiiStream.point(x, y); + }, + sphere: function() { + lower48Stream.sphere(); + alaskaStream.sphere(); + hawaiiStream.sphere(); + }, + lineStart: function() { + lower48Stream.lineStart(); + alaskaStream.lineStart(); + hawaiiStream.lineStart(); + }, + lineEnd: function() { + lower48Stream.lineEnd(); + alaskaStream.lineEnd(); + hawaiiStream.lineEnd(); + }, + polygonStart: function() { + lower48Stream.polygonStart(); + alaskaStream.polygonStart(); + hawaiiStream.polygonStart(); + }, + polygonEnd: function() { + lower48Stream.polygonEnd(); + alaskaStream.polygonEnd(); + hawaiiStream.polygonEnd(); + } + }; + }; + albersUsa.precision = function(_) { + if (!arguments.length) return lower48.precision(); + lower48.precision(_); + alaska.precision(_); + hawaii.precision(_); + return albersUsa; + }; + albersUsa.scale = function(_) { + if (!arguments.length) return lower48.scale(); + lower48.scale(_); + alaska.scale(_ * .35); + hawaii.scale(_); + return albersUsa.translate(lower48.translate()); + }; + albersUsa.translate = function(_) { + if (!arguments.length) return lower48.translate(); + var k = lower48.scale(), x = +_[0], y = +_[1]; + lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; + alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; + hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; + return albersUsa; + }; + return albersUsa.scale(1070); + }; + var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { + point: d3_noop, + lineStart: d3_noop, + lineEnd: d3_noop, + polygonStart: function() { + d3_geo_pathAreaPolygon = 0; + d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; + }, + polygonEnd: function() { + d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; + d3_geo_pathAreaSum += Math.abs(d3_geo_pathAreaPolygon / 2); + } + }; + function d3_geo_pathAreaRingStart() { + var x00, y00, x0, y0; + d3_geo_pathArea.point = function(x, y) { + d3_geo_pathArea.point = nextPoint; + x00 = x0 = x, y00 = y0 = y; + }; + function nextPoint(x, y) { + d3_geo_pathAreaPolygon += y0 * x - x0 * y; + x0 = x, y0 = y; + } + d3_geo_pathArea.lineEnd = function() { + nextPoint(x00, y00); + }; + } + var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; + var d3_geo_pathBounds = { + point: d3_geo_pathBoundsPoint, + lineStart: d3_noop, + lineEnd: d3_noop, + polygonStart: d3_noop, + polygonEnd: d3_noop + }; + function d3_geo_pathBoundsPoint(x, y) { + if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; + if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; + if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; + if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; + } + function d3_geo_pathBuffer() { + var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; + var stream = { + point: point, + lineStart: function() { + stream.point = pointLineStart; + }, + lineEnd: lineEnd, + polygonStart: function() { + stream.lineEnd = lineEndPolygon; + }, + polygonEnd: function() { + stream.lineEnd = lineEnd; + stream.point = point; + }, + pointRadius: function(_) { + pointCircle = d3_geo_pathBufferCircle(_); + return stream; + }, + result: function() { + if (buffer.length) { + var result = buffer.join(""); + buffer = []; + return result; + } + } + }; + function point(x, y) { + buffer.push("M", x, ",", y, pointCircle); + } + function pointLineStart(x, y) { + buffer.push("M", x, ",", y); + stream.point = pointLine; + } + function pointLine(x, y) { + buffer.push("L", x, ",", y); + } + function lineEnd() { + stream.point = point; + } + function lineEndPolygon() { + buffer.push("Z"); + } + return stream; + } + function d3_geo_pathBufferCircle(radius) { + return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; + } + var d3_geo_pathCentroid = { + point: d3_geo_pathCentroidPoint, + lineStart: d3_geo_pathCentroidLineStart, + lineEnd: d3_geo_pathCentroidLineEnd, + polygonStart: function() { + d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; + }, + polygonEnd: function() { + d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; + d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; + d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; + } + }; + function d3_geo_pathCentroidPoint(x, y) { + if (d3_geo_centroidDimension) return; + d3_geo_centroidX += x; + d3_geo_centroidY += y; + ++d3_geo_centroidZ; + } + function d3_geo_pathCentroidLineStart() { + var x0, y0; + if (d3_geo_centroidDimension !== 1) { + if (d3_geo_centroidDimension < 1) { + d3_geo_centroidDimension = 1; + d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; + } else return; + } + d3_geo_pathCentroid.point = function(x, y) { + d3_geo_pathCentroid.point = nextPoint; + x0 = x, y0 = y; + }; + function nextPoint(x, y) { + var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); + d3_geo_centroidX += z * (x0 + x) / 2; + d3_geo_centroidY += z * (y0 + y) / 2; + d3_geo_centroidZ += z; + x0 = x, y0 = y; + } + } + function d3_geo_pathCentroidLineEnd() { + d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; + } + function d3_geo_pathCentroidRingStart() { + var x00, y00, x0, y0; + if (d3_geo_centroidDimension < 2) { + d3_geo_centroidDimension = 2; + d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; + } + d3_geo_pathCentroid.point = function(x, y) { + d3_geo_pathCentroid.point = nextPoint; + x00 = x0 = x, y00 = y0 = y; + }; + function nextPoint(x, y) { + var z = y0 * x - x0 * y; + d3_geo_centroidX += z * (x0 + x); + d3_geo_centroidY += z * (y0 + y); + d3_geo_centroidZ += z * 3; + x0 = x, y0 = y; + } + d3_geo_pathCentroid.lineEnd = function() { + nextPoint(x00, y00); + }; + } + function d3_geo_pathContext(context) { + var pointRadius = 4.5; + var stream = { + point: point, + lineStart: function() { + stream.point = pointLineStart; + }, + lineEnd: lineEnd, + polygonStart: function() { + stream.lineEnd = lineEndPolygon; + }, + polygonEnd: function() { + stream.lineEnd = lineEnd; + stream.point = point; + }, + pointRadius: function(_) { + pointRadius = _; + return stream; + }, + result: d3_noop + }; + function point(x, y) { + context.moveTo(x, y); + context.arc(x, y, pointRadius, 0, 2 * Ï€); + } + function pointLineStart(x, y) { + context.moveTo(x, y); + stream.point = pointLine; + } + function pointLine(x, y) { + context.lineTo(x, y); + } + function lineEnd() { + stream.point = point; + } + function lineEndPolygon() { + context.closePath(); + } + return stream; + } + d3.geo.path = function() { + var pointRadius = 4.5, projection, context, projectStream, contextStream; + function path(object) { + if (object) d3.geo.stream(object, projectStream(contextStream.pointRadius(typeof pointRadius === "function" ? +pointRadius.apply(this, arguments) : pointRadius))); + return contextStream.result(); + } + path.area = function(object) { + d3_geo_pathAreaSum = 0; + d3.geo.stream(object, projectStream(d3_geo_pathArea)); + return d3_geo_pathAreaSum; + }; + path.centroid = function(object) { + d3_geo_centroidDimension = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; + d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); + return d3_geo_centroidZ ? [ d3_geo_centroidX / d3_geo_centroidZ, d3_geo_centroidY / d3_geo_centroidZ ] : undefined; + }; + path.bounds = function(object) { + d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); + d3.geo.stream(object, projectStream(d3_geo_pathBounds)); + return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; + }; + path.projection = function(_) { + if (!arguments.length) return projection; + projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; + return path; + }; + path.context = function(_) { + if (!arguments.length) return context; + contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); + return path; + }; + path.pointRadius = function(_) { + if (!arguments.length) return pointRadius; + pointRadius = typeof _ === "function" ? _ : +_; + return path; + }; + return path.projection(d3.geo.albersUsa()).context(null); + }; + function d3_geo_pathProjectStream(project) { + var resample = d3_geo_resample(function(λ, φ) { + return project([ λ * d3_degrees, φ * d3_degrees ]); + }); + return function(stream) { + stream = resample(stream); + return { + point: function(λ, φ) { + stream.point(λ * d3_radians, φ * d3_radians); + }, + sphere: function() { + stream.sphere(); + }, + lineStart: function() { + stream.lineStart(); + }, + lineEnd: function() { + stream.lineEnd(); + }, + polygonStart: function() { + stream.polygonStart(); + }, + polygonEnd: function() { + stream.polygonEnd(); + } + }; + }; + } + function d3_geo_azimuthal(scale, angle) { + function azimuthal(λ, φ) { + var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); + return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; + } + azimuthal.invert = function(x, y) { + var Ï = Math.sqrt(x * x + y * y), c = angle(Ï), sinc = Math.sin(c), cosc = Math.cos(c); + return [ Math.atan2(x * sinc, Ï * cosc), Math.asin(Ï && y * sinc / Ï) ]; + }; + return azimuthal; + } + var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { + return Math.sqrt(2 / (1 + cosλcosφ)); + }, function(Ï) { + return 2 * Math.asin(Ï / 2); + }); + (d3.geo.azimuthalEqualArea = function() { + return d3_geo_projection(d3_geo_azimuthalEqualArea); + }).raw = d3_geo_azimuthalEqualArea; + var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { + var c = Math.acos(cosλcosφ); + return c && c / Math.sin(c); + }, d3_identity); + (d3.geo.azimuthalEquidistant = function() { + return d3_geo_projection(d3_geo_azimuthalEquidistant); + }).raw = d3_geo_azimuthalEquidistant; + function d3_geo_conicConformal(φ0, φ1) { + var cosφ0 = Math.cos(φ0), t = function(φ) { + return Math.tan(Ï€ / 4 + φ / 2); + }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; + if (!n) return d3_geo_mercator; + function forward(λ, φ) { + var Ï = Math.abs(Math.abs(φ) - Ï€ / 2) < ε ? 0 : F / Math.pow(t(φ), n); + return [ Ï * Math.sin(n * λ), F - Ï * Math.cos(n * λ) ]; + } + forward.invert = function(x, y) { + var Ï0_y = F - y, Ï = d3_sgn(n) * Math.sqrt(x * x + Ï0_y * Ï0_y); + return [ Math.atan2(x, Ï0_y) / n, 2 * Math.atan(Math.pow(F / Ï, 1 / n)) - Ï€ / 2 ]; + }; + return forward; + } + (d3.geo.conicConformal = function() { + return d3_geo_conic(d3_geo_conicConformal); + }).raw = d3_geo_conicConformal; + function d3_geo_conicEquidistant(φ0, φ1) { + var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; + if (Math.abs(n) < ε) return d3_geo_equirectangular; + function forward(λ, φ) { + var Ï = G - φ; + return [ Ï * Math.sin(n * λ), G - Ï * Math.cos(n * λ) ]; + } + forward.invert = function(x, y) { + var Ï0_y = G - y; + return [ Math.atan2(x, Ï0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + Ï0_y * Ï0_y) ]; + }; + return forward; + } + (d3.geo.conicEquidistant = function() { + return d3_geo_conic(d3_geo_conicEquidistant); + }).raw = d3_geo_conicEquidistant; + var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { + return 1 / cosλcosφ; + }, Math.atan); + (d3.geo.gnomonic = function() { + return d3_geo_projection(d3_geo_gnomonic); + }).raw = d3_geo_gnomonic; + function d3_geo_mercator(λ, φ) { + return [ λ, Math.log(Math.tan(Ï€ / 4 + φ / 2)) ]; + } + d3_geo_mercator.invert = function(x, y) { + return [ x, 2 * Math.atan(Math.exp(y)) - Ï€ / 2 ]; + }; + function d3_geo_mercatorProjection(project) { + var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; + m.scale = function() { + var v = scale.apply(m, arguments); + return v === m ? clipAuto ? m.clipExtent(null) : m : v; + }; + m.translate = function() { + var v = translate.apply(m, arguments); + return v === m ? clipAuto ? m.clipExtent(null) : m : v; + }; + m.clipExtent = function(_) { + var v = clipExtent.apply(m, arguments); + if (v === m) { + if (clipAuto = _ == null) { + var k = Ï€ * scale(), t = translate(); + clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); + } + } else if (clipAuto) { + v = null; + } + return v; + }; + return m.clipExtent(null); + } + (d3.geo.mercator = function() { + return d3_geo_mercatorProjection(d3_geo_mercator); + }).raw = d3_geo_mercator; + var d3_geo_orthographic = d3_geo_azimuthal(function() { + return 1; + }, Math.asin); + (d3.geo.orthographic = function() { + return d3_geo_projection(d3_geo_orthographic); + }).raw = d3_geo_orthographic; + var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { + return 1 / (1 + cosλcosφ); + }, function(Ï) { + return 2 * Math.atan(Ï); + }); + (d3.geo.stereographic = function() { + return d3_geo_projection(d3_geo_stereographic); + }).raw = d3_geo_stereographic; + function d3_geo_transverseMercator(λ, φ) { + var B = Math.cos(φ) * Math.sin(λ); + return [ Math.log((1 + B) / (1 - B)) / 2, Math.atan2(Math.tan(φ), Math.cos(λ)) ]; + } + d3_geo_transverseMercator.invert = function(x, y) { + return [ Math.atan2(d3_sinh(x), Math.cos(y)), d3_asin(Math.sin(y) / d3_cosh(x)) ]; + }; + (d3.geo.transverseMercator = function() { + return d3_geo_mercatorProjection(d3_geo_transverseMercator); + }).raw = d3_geo_transverseMercator; + d3.geom = {}; + d3.svg = {}; + function d3_svg_line(projection) { + var x = d3_svg_lineX, y = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; + function line(data) { + var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); + function segment() { + segments.push("M", interpolate(projection(points), tension)); + } + while (++i < n) { + if (defined.call(this, d = data[i], i)) { + points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); + } else if (points.length) { + segment(); + points = []; + } + } + if (points.length) segment(); + return segments.length ? segments.join("") : null; + } + line.x = function(_) { + if (!arguments.length) return x; + x = _; + return line; + }; + line.y = function(_) { + if (!arguments.length) return y; + y = _; + return line; + }; + line.defined = function(_) { + if (!arguments.length) return defined; + defined = _; + return line; + }; + line.interpolate = function(_) { + if (!arguments.length) return interpolateKey; + if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; + return line; + }; + line.tension = function(_) { + if (!arguments.length) return tension; + tension = _; + return line; + }; + return line; + } + d3.svg.line = function() { + return d3_svg_line(d3_identity); + }; + function d3_svg_lineX(d) { + return d[0]; + } + function d3_svg_lineY(d) { + return d[1]; + } + var d3_svg_lineInterpolators = d3.map({ + linear: d3_svg_lineLinear, + "linear-closed": d3_svg_lineLinearClosed, + "step-before": d3_svg_lineStepBefore, + "step-after": d3_svg_lineStepAfter, + basis: d3_svg_lineBasis, + "basis-open": d3_svg_lineBasisOpen, + "basis-closed": d3_svg_lineBasisClosed, + bundle: d3_svg_lineBundle, + cardinal: d3_svg_lineCardinal, + "cardinal-open": d3_svg_lineCardinalOpen, + "cardinal-closed": d3_svg_lineCardinalClosed, + monotone: d3_svg_lineMonotone + }); + d3_svg_lineInterpolators.forEach(function(key, value) { + value.key = key; + value.closed = /-closed$/.test(key); + }); + function d3_svg_lineLinear(points) { + return points.join("L"); + } + function d3_svg_lineLinearClosed(points) { + return d3_svg_lineLinear(points) + "Z"; + } + function d3_svg_lineStepBefore(points) { + var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; + while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); + return path.join(""); + } + function d3_svg_lineStepAfter(points) { + var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; + while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); + return path.join(""); + } + function d3_svg_lineCardinalOpen(points, tension) { + return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension)); + } + function d3_svg_lineCardinalClosed(points, tension) { + return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), + points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); + } + function d3_svg_lineCardinal(points, tension) { + return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); + } + function d3_svg_lineHermite(points, tangents) { + if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { + return d3_svg_lineLinear(points); + } + var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; + if (quad) { + path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; + p0 = points[1]; + pi = 2; + } + if (tangents.length > 1) { + t = tangents[1]; + p = points[pi]; + pi++; + path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; + for (var i = 2; i < tangents.length; i++, pi++) { + p = points[pi]; + t = tangents[i]; + path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; + } + } + if (quad) { + var lp = points[pi]; + path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; + } + return path; + } + function d3_svg_lineCardinalTangents(points, tension) { + var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; + while (++i < n) { + p0 = p1; + p1 = p2; + p2 = points[i]; + tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); + } + return tangents; + } + function d3_svg_lineBasis(points) { + if (points.length < 3) return d3_svg_lineLinear(points); + var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0 ]; + d3_svg_lineBasisBezier(path, px, py); + while (++i < n) { + pi = points[i]; + px.shift(); + px.push(pi[0]); + py.shift(); + py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + i = -1; + while (++i < 2) { + px.shift(); + px.push(pi[0]); + py.shift(); + py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + return path.join(""); + } + function d3_svg_lineBasisOpen(points) { + if (points.length < 4) return d3_svg_lineLinear(points); + var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; + while (++i < 3) { + pi = points[i]; + px.push(pi[0]); + py.push(pi[1]); + } + path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); + --i; + while (++i < n) { + pi = points[i]; + px.shift(); + px.push(pi[0]); + py.shift(); + py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + return path.join(""); + } + function d3_svg_lineBasisClosed(points) { + var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; + while (++i < 4) { + pi = points[i % n]; + px.push(pi[0]); + py.push(pi[1]); + } + path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; + --i; + while (++i < m) { + pi = points[i % n]; + px.shift(); + px.push(pi[0]); + py.shift(); + py.push(pi[1]); + d3_svg_lineBasisBezier(path, px, py); + } + return path.join(""); + } + function d3_svg_lineBundle(points, tension) { + var n = points.length - 1; + if (n) { + var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; + while (++i <= n) { + p = points[i]; + t = i / n; + p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); + p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); + } + } + return d3_svg_lineBasis(points); + } + function d3_svg_lineDot4(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; + } + var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; + function d3_svg_lineBasisBezier(path, x, y) { + path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); + } + function d3_svg_lineSlope(p0, p1) { + return (p1[1] - p0[1]) / (p1[0] - p0[0]); + } + function d3_svg_lineFiniteDifferences(points) { + var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); + while (++i < j) { + m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; + } + m[i] = d; + return m; + } + function d3_svg_lineMonotoneTangents(points) { + var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; + while (++i < j) { + d = d3_svg_lineSlope(points[i], points[i + 1]); + if (Math.abs(d) < 1e-6) { + m[i] = m[i + 1] = 0; + } else { + a = m[i] / d; + b = m[i + 1] / d; + s = a * a + b * b; + if (s > 9) { + s = d * 3 / Math.sqrt(s); + m[i] = s * a; + m[i + 1] = s * b; + } + } + } + i = -1; + while (++i <= j) { + s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); + tangents.push([ s || 0, m[i] * s || 0 ]); + } + return tangents; + } + function d3_svg_lineMonotone(points) { + return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); + } + d3.geom.hull = function(vertices) { + var x = d3_svg_lineX, y = d3_svg_lineY; + if (arguments.length) return hull(vertices); + function hull(data) { + if (data.length < 3) return []; + var fx = d3_functor(x), fy = d3_functor(y), n = data.length, vertices, plen = n - 1, points = [], stack = [], d, i, j, h = 0, x1, y1, x2, y2, u, v, a, sp; + if (fx === d3_svg_lineX && y === d3_svg_lineY) vertices = data; else for (i = 0, + vertices = []; i < n; ++i) { + vertices.push([ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]); + } + for (i = 1; i < n; ++i) { + if (vertices[i][1] < vertices[h][1] || vertices[i][1] == vertices[h][1] && vertices[i][0] < vertices[h][0]) h = i; + } + for (i = 0; i < n; ++i) { + if (i === h) continue; + y1 = vertices[i][1] - vertices[h][1]; + x1 = vertices[i][0] - vertices[h][0]; + points.push({ + angle: Math.atan2(y1, x1), + index: i + }); + } + points.sort(function(a, b) { + return a.angle - b.angle; + }); + a = points[0].angle; + v = points[0].index; + u = 0; + for (i = 1; i < plen; ++i) { + j = points[i].index; + if (a == points[i].angle) { + x1 = vertices[v][0] - vertices[h][0]; + y1 = vertices[v][1] - vertices[h][1]; + x2 = vertices[j][0] - vertices[h][0]; + y2 = vertices[j][1] - vertices[h][1]; + if (x1 * x1 + y1 * y1 >= x2 * x2 + y2 * y2) { + points[i].index = -1; + continue; + } else { + points[u].index = -1; + } + } + a = points[i].angle; + u = i; + v = j; + } + stack.push(h); + for (i = 0, j = 0; i < 2; ++j) { + if (points[j].index > -1) { + stack.push(points[j].index); + i++; + } + } + sp = stack.length; + for (;j < plen; ++j) { + if (points[j].index < 0) continue; + while (!d3_geom_hullCCW(stack[sp - 2], stack[sp - 1], points[j].index, vertices)) { + --sp; + } + stack[sp++] = points[j].index; + } + var poly = []; + for (i = sp - 1; i >= 0; --i) poly.push(data[stack[i]]); + return poly; + } + hull.x = function(_) { + return arguments.length ? (x = _, hull) : x; + }; + hull.y = function(_) { + return arguments.length ? (y = _, hull) : y; + }; + return hull; + }; + function d3_geom_hullCCW(i1, i2, i3, v) { + var t, a, b, c, d, e, f; + t = v[i1]; + a = t[0]; + b = t[1]; + t = v[i2]; + c = t[0]; + d = t[1]; + t = v[i3]; + e = t[0]; + f = t[1]; + return (f - b) * (c - a) - (d - b) * (e - a) > 0; + } + d3.geom.polygon = function(coordinates) { + coordinates.area = function() { + var i = 0, n = coordinates.length, area = coordinates[n - 1][1] * coordinates[0][0] - coordinates[n - 1][0] * coordinates[0][1]; + while (++i < n) { + area += coordinates[i - 1][1] * coordinates[i][0] - coordinates[i - 1][0] * coordinates[i][1]; + } + return area * .5; + }; + coordinates.centroid = function(k) { + var i = -1, n = coordinates.length, x = 0, y = 0, a, b = coordinates[n - 1], c; + if (!arguments.length) k = -1 / (6 * coordinates.area()); + while (++i < n) { + a = b; + b = coordinates[i]; + c = a[0] * b[1] - b[0] * a[1]; + x += (a[0] + b[0]) * c; + y += (a[1] + b[1]) * c; + } + return [ x * k, y * k ]; + }; + coordinates.clip = function(subject) { + var input, i = -1, n = coordinates.length, j, m, a = coordinates[n - 1], b, c, d; + while (++i < n) { + input = subject.slice(); + subject.length = 0; + b = coordinates[i]; + c = input[(m = input.length) - 1]; + j = -1; + while (++j < m) { + d = input[j]; + if (d3_geom_polygonInside(d, a, b)) { + if (!d3_geom_polygonInside(c, a, b)) { + subject.push(d3_geom_polygonIntersect(c, d, a, b)); + } + subject.push(d); + } else if (d3_geom_polygonInside(c, a, b)) { + subject.push(d3_geom_polygonIntersect(c, d, a, b)); + } + c = d; + } + a = b; + } + return subject; + }; + return coordinates; + }; + function d3_geom_polygonInside(p, a, b) { + return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); + } + function d3_geom_polygonIntersect(c, d, a, b) { + var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); + return [ x1 + ua * x21, y1 + ua * y21 ]; + } + d3.geom.delaunay = function(vertices) { + var edges = vertices.map(function() { + return []; + }), triangles = []; + d3_geom_voronoiTessellate(vertices, function(e) { + edges[e.region.l.index].push(vertices[e.region.r.index]); + }); + edges.forEach(function(edge, i) { + var v = vertices[i], cx = v[0], cy = v[1]; + edge.forEach(function(v) { + v.angle = Math.atan2(v[0] - cx, v[1] - cy); + }); + edge.sort(function(a, b) { + return a.angle - b.angle; + }); + for (var j = 0, m = edge.length - 1; j < m; j++) { + triangles.push([ v, edge[j], edge[j + 1] ]); + } + }); + return triangles; + }; + d3.geom.voronoi = function(points) { + var size = null, x = d3_svg_lineX, y = d3_svg_lineY, clip; + if (arguments.length) return voronoi(points); + function voronoi(data) { + var points, polygons = data.map(function() { + return []; + }), fx = d3_functor(x), fy = d3_functor(y), d, i, n = data.length, Z = 1e6; + if (fx === d3_svg_lineX && fy === d3_svg_lineY) points = data; else for (points = [], + i = 0; i < n; ++i) { + points.push([ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]); + } + d3_geom_voronoiTessellate(points, function(e) { + var s1, s2, x1, x2, y1, y2; + if (e.a === 1 && e.b >= 0) { + s1 = e.ep.r; + s2 = e.ep.l; + } else { + s1 = e.ep.l; + s2 = e.ep.r; + } + if (e.a === 1) { + y1 = s1 ? s1.y : -Z; + x1 = e.c - e.b * y1; + y2 = s2 ? s2.y : Z; + x2 = e.c - e.b * y2; + } else { + x1 = s1 ? s1.x : -Z; + y1 = e.c - e.a * x1; + x2 = s2 ? s2.x : Z; + y2 = e.c - e.a * x2; + } + var v1 = [ x1, y1 ], v2 = [ x2, y2 ]; + polygons[e.region.l.index].push(v1, v2); + polygons[e.region.r.index].push(v1, v2); + }); + polygons = polygons.map(function(polygon, i) { + var cx = points[i][0], cy = points[i][1], angle = polygon.map(function(v) { + return Math.atan2(v[0] - cx, v[1] - cy); + }), order = d3.range(polygon.length).sort(function(a, b) { + return angle[a] - angle[b]; + }); + return order.filter(function(d, i) { + return !i || angle[d] - angle[order[i - 1]] > ε; + }).map(function(d) { + return polygon[d]; + }); + }); + polygons.forEach(function(polygon, i) { + var n = polygon.length; + if (!n) return polygon.push([ -Z, -Z ], [ -Z, Z ], [ Z, Z ], [ Z, -Z ]); + if (n > 2) return; + var p0 = points[i], p1 = polygon[0], p2 = polygon[1], x0 = p0[0], y0 = p0[1], x1 = p1[0], y1 = p1[1], x2 = p2[0], y2 = p2[1], dx = Math.abs(x2 - x1), dy = y2 - y1; + if (Math.abs(dy) < ε) { + var y = y0 < y1 ? -Z : Z; + polygon.push([ -Z, y ], [ Z, y ]); + } else if (dx < ε) { + var x = x0 < x1 ? -Z : Z; + polygon.push([ x, -Z ], [ x, Z ]); + } else { + var y = (x2 - x1) * (y1 - y0) < (x1 - x0) * (y2 - y1) ? Z : -Z, z = Math.abs(dy) - dx; + if (Math.abs(z) < ε) { + polygon.push([ dy < 0 ? y : -y, y ]); + } else { + if (z > 0) y *= -1; + polygon.push([ -Z, y ], [ Z, y ]); + } + } + }); + if (clip) for (i = 0; i < n; ++i) clip(polygons[i]); + for (i = 0; i < n; ++i) polygons[i].point = data[i]; + return polygons; + } + voronoi.x = function(_) { + return arguments.length ? (x = _, voronoi) : x; + }; + voronoi.y = function(_) { + return arguments.length ? (y = _, voronoi) : y; + }; + voronoi.size = function(_) { + if (!arguments.length) return size; + if (_ == null) { + clip = null; + } else { + size = [ +_[0], +_[1] ]; + clip = d3.geom.polygon([ [ 0, 0 ], [ 0, size[1] ], size, [ size[0], 0 ] ]).clip; + } + return voronoi; + }; + voronoi.links = function(data) { + var points, graph = data.map(function() { + return []; + }), links = [], fx = d3_functor(x), fy = d3_functor(y), d, i, n = data.length; + if (fx === d3_svg_lineX && fy === d3_svg_lineY) points = data; else for (i = 0; i < n; ++i) { + points.push([ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]); + } + d3_geom_voronoiTessellate(points, function(e) { + var l = e.region.l.index, r = e.region.r.index; + if (graph[l][r]) return; + graph[l][r] = graph[r][l] = true; + links.push({ + source: data[l], + target: data[r] + }); + }); + return links; + }; + voronoi.triangles = function(data) { + if (x === d3_svg_lineX && y === d3_svg_lineY) return d3.geom.delaunay(data); + var points, point, fx = d3_functor(x), fy = d3_functor(y), d, i, n; + for (i = 0, points = [], n = data.length; i < n; ++i) { + point = [ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]; + point.data = d; + points.push(point); + } + return d3.geom.delaunay(points).map(function(triangle) { + return triangle.map(function(point) { + return point.data; + }); + }); + }; + return voronoi; + }; + var d3_geom_voronoiOpposite = { + l: "r", + r: "l" + }; + function d3_geom_voronoiTessellate(points, callback) { + var Sites = { + list: points.map(function(v, i) { + return { + index: i, + x: v[0], + y: v[1] + }; + }).sort(function(a, b) { + return a.y < b.y ? -1 : a.y > b.y ? 1 : a.x < b.x ? -1 : a.x > b.x ? 1 : 0; + }), + bottomSite: null + }; + var EdgeList = { + list: [], + leftEnd: null, + rightEnd: null, + init: function() { + EdgeList.leftEnd = EdgeList.createHalfEdge(null, "l"); + EdgeList.rightEnd = EdgeList.createHalfEdge(null, "l"); + EdgeList.leftEnd.r = EdgeList.rightEnd; + EdgeList.rightEnd.l = EdgeList.leftEnd; + EdgeList.list.unshift(EdgeList.leftEnd, EdgeList.rightEnd); + }, + createHalfEdge: function(edge, side) { + return { + edge: edge, + side: side, + vertex: null, + l: null, + r: null + }; + }, + insert: function(lb, he) { + he.l = lb; + he.r = lb.r; + lb.r.l = he; + lb.r = he; + }, + leftBound: function(p) { + var he = EdgeList.leftEnd; + do { + he = he.r; + } while (he != EdgeList.rightEnd && Geom.rightOf(he, p)); + he = he.l; + return he; + }, + del: function(he) { + he.l.r = he.r; + he.r.l = he.l; + he.edge = null; + }, + right: function(he) { + return he.r; + }, + left: function(he) { + return he.l; + }, + leftRegion: function(he) { + return he.edge == null ? Sites.bottomSite : he.edge.region[he.side]; + }, + rightRegion: function(he) { + return he.edge == null ? Sites.bottomSite : he.edge.region[d3_geom_voronoiOpposite[he.side]]; + } + }; + var Geom = { + bisect: function(s1, s2) { + var newEdge = { + region: { + l: s1, + r: s2 + }, + ep: { + l: null, + r: null + } + }; + var dx = s2.x - s1.x, dy = s2.y - s1.y, adx = dx > 0 ? dx : -dx, ady = dy > 0 ? dy : -dy; + newEdge.c = s1.x * dx + s1.y * dy + (dx * dx + dy * dy) * .5; + if (adx > ady) { + newEdge.a = 1; + newEdge.b = dy / dx; + newEdge.c /= dx; + } else { + newEdge.b = 1; + newEdge.a = dx / dy; + newEdge.c /= dy; + } + return newEdge; + }, + intersect: function(el1, el2) { + var e1 = el1.edge, e2 = el2.edge; + if (!e1 || !e2 || e1.region.r == e2.region.r) { + return null; + } + var d = e1.a * e2.b - e1.b * e2.a; + if (Math.abs(d) < 1e-10) { + return null; + } + var xint = (e1.c * e2.b - e2.c * e1.b) / d, yint = (e2.c * e1.a - e1.c * e2.a) / d, e1r = e1.region.r, e2r = e2.region.r, el, e; + if (e1r.y < e2r.y || e1r.y == e2r.y && e1r.x < e2r.x) { + el = el1; + e = e1; + } else { + el = el2; + e = e2; + } + var rightOfSite = xint >= e.region.r.x; + if (rightOfSite && el.side === "l" || !rightOfSite && el.side === "r") { + return null; + } + return { + x: xint, + y: yint + }; + }, + rightOf: function(he, p) { + var e = he.edge, topsite = e.region.r, rightOfSite = p.x > topsite.x; + if (rightOfSite && he.side === "l") { + return 1; + } + if (!rightOfSite && he.side === "r") { + return 0; + } + if (e.a === 1) { + var dyp = p.y - topsite.y, dxp = p.x - topsite.x, fast = 0, above = 0; + if (!rightOfSite && e.b < 0 || rightOfSite && e.b >= 0) { + above = fast = dyp >= e.b * dxp; + } else { + above = p.x + p.y * e.b > e.c; + if (e.b < 0) { + above = !above; + } + if (!above) { + fast = 1; + } + } + if (!fast) { + var dxs = topsite.x - e.region.l.x; + above = e.b * (dxp * dxp - dyp * dyp) < dxs * dyp * (1 + 2 * dxp / dxs + e.b * e.b); + if (e.b < 0) { + above = !above; + } + } + } else { + var yl = e.c - e.a * p.x, t1 = p.y - yl, t2 = p.x - topsite.x, t3 = yl - topsite.y; + above = t1 * t1 > t2 * t2 + t3 * t3; + } + return he.side === "l" ? above : !above; + }, + endPoint: function(edge, side, site) { + edge.ep[side] = site; + if (!edge.ep[d3_geom_voronoiOpposite[side]]) return; + callback(edge); + }, + distance: function(s, t) { + var dx = s.x - t.x, dy = s.y - t.y; + return Math.sqrt(dx * dx + dy * dy); + } + }; + var EventQueue = { + list: [], + insert: function(he, site, offset) { + he.vertex = site; + he.ystar = site.y + offset; + for (var i = 0, list = EventQueue.list, l = list.length; i < l; i++) { + var next = list[i]; + if (he.ystar > next.ystar || he.ystar == next.ystar && site.x > next.vertex.x) { + continue; + } else { + break; + } + } + list.splice(i, 0, he); + }, + del: function(he) { + for (var i = 0, ls = EventQueue.list, l = ls.length; i < l && ls[i] != he; ++i) {} + ls.splice(i, 1); + }, + empty: function() { + return EventQueue.list.length === 0; + }, + nextEvent: function(he) { + for (var i = 0, ls = EventQueue.list, l = ls.length; i < l; ++i) { + if (ls[i] == he) return ls[i + 1]; + } + return null; + }, + min: function() { + var elem = EventQueue.list[0]; + return { + x: elem.vertex.x, + y: elem.ystar + }; + }, + extractMin: function() { + return EventQueue.list.shift(); + } + }; + EdgeList.init(); + Sites.bottomSite = Sites.list.shift(); + var newSite = Sites.list.shift(), newIntStar; + var lbnd, rbnd, llbnd, rrbnd, bisector; + var bot, top, temp, p, v; + var e, pm; + while (true) { + if (!EventQueue.empty()) { + newIntStar = EventQueue.min(); + } + if (newSite && (EventQueue.empty() || newSite.y < newIntStar.y || newSite.y == newIntStar.y && newSite.x < newIntStar.x)) { + lbnd = EdgeList.leftBound(newSite); + rbnd = EdgeList.right(lbnd); + bot = EdgeList.rightRegion(lbnd); + e = Geom.bisect(bot, newSite); + bisector = EdgeList.createHalfEdge(e, "l"); + EdgeList.insert(lbnd, bisector); + p = Geom.intersect(lbnd, bisector); + if (p) { + EventQueue.del(lbnd); + EventQueue.insert(lbnd, p, Geom.distance(p, newSite)); + } + lbnd = bisector; + bisector = EdgeList.createHalfEdge(e, "r"); + EdgeList.insert(lbnd, bisector); + p = Geom.intersect(bisector, rbnd); + if (p) { + EventQueue.insert(bisector, p, Geom.distance(p, newSite)); + } + newSite = Sites.list.shift(); + } else if (!EventQueue.empty()) { + lbnd = EventQueue.extractMin(); + llbnd = EdgeList.left(lbnd); + rbnd = EdgeList.right(lbnd); + rrbnd = EdgeList.right(rbnd); + bot = EdgeList.leftRegion(lbnd); + top = EdgeList.rightRegion(rbnd); + v = lbnd.vertex; + Geom.endPoint(lbnd.edge, lbnd.side, v); + Geom.endPoint(rbnd.edge, rbnd.side, v); + EdgeList.del(lbnd); + EventQueue.del(rbnd); + EdgeList.del(rbnd); + pm = "l"; + if (bot.y > top.y) { + temp = bot; + bot = top; + top = temp; + pm = "r"; + } + e = Geom.bisect(bot, top); + bisector = EdgeList.createHalfEdge(e, pm); + EdgeList.insert(llbnd, bisector); + Geom.endPoint(e, d3_geom_voronoiOpposite[pm], v); + p = Geom.intersect(llbnd, bisector); + if (p) { + EventQueue.del(llbnd); + EventQueue.insert(llbnd, p, Geom.distance(p, bot)); + } + p = Geom.intersect(bisector, rrbnd); + if (p) { + EventQueue.insert(bisector, p, Geom.distance(p, bot)); + } + } else { + break; + } + } + for (lbnd = EdgeList.right(EdgeList.leftEnd); lbnd != EdgeList.rightEnd; lbnd = EdgeList.right(lbnd)) { + callback(lbnd.edge); + } + } + d3.geom.quadtree = function(points, x1, y1, x2, y2) { + var x = d3_svg_lineX, y = d3_svg_lineY, compat; + if (compat = arguments.length) { + x = d3_geom_quadtreeCompatX; + y = d3_geom_quadtreeCompatY; + if (compat === 3) { + y2 = y1; + x2 = x1; + y1 = x1 = 0; + } + return quadtree(points); + } + function quadtree(data) { + var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; + if (x1 != null) { + x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; + } else { + x2_ = y2_ = -(x1_ = y1_ = Infinity); + xs = [], ys = []; + n = data.length; + if (compat) for (i = 0; i < n; ++i) { + d = data[i]; + if (d.x < x1_) x1_ = d.x; + if (d.y < y1_) y1_ = d.y; + if (d.x > x2_) x2_ = d.x; + if (d.y > y2_) y2_ = d.y; + xs.push(d.x); + ys.push(d.y); + } else for (i = 0; i < n; ++i) { + var x_ = +fx(d = data[i], i), y_ = +fy(d, i); + if (x_ < x1_) x1_ = x_; + if (y_ < y1_) y1_ = y_; + if (x_ > x2_) x2_ = x_; + if (y_ > y2_) y2_ = y_; + xs.push(x_); + ys.push(y_); + } + } + var dx = x2_ - x1_, dy = y2_ - y1_; + if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; + function insert(n, d, x, y, x1, y1, x2, y2) { + if (isNaN(x) || isNaN(y)) return; + if (n.leaf) { + var nx = n.x, ny = n.y; + if (nx != null) { + if (Math.abs(nx - x) + Math.abs(ny - y) < .01) { + insertChild(n, d, x, y, x1, y1, x2, y2); + } else { + var nPoint = n.point; + n.x = n.y = n.point = null; + insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); + insertChild(n, d, x, y, x1, y1, x2, y2); + } + } else { + n.x = x, n.y = y, n.point = d; + } + } else { + insertChild(n, d, x, y, x1, y1, x2, y2); + } + } + function insertChild(n, d, x, y, x1, y1, x2, y2) { + var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, right = x >= sx, bottom = y >= sy, i = (bottom << 1) + right; + n.leaf = false; + n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); + if (right) x1 = sx; else x2 = sx; + if (bottom) y1 = sy; else y2 = sy; + insert(n, d, x, y, x1, y1, x2, y2); + } + var root = d3_geom_quadtreeNode(); + root.add = function(d) { + insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); + }; + root.visit = function(f) { + d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); + }; + i = -1; + if (x1 == null) { + while (++i < n) { + insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); + } + --i; + } else data.forEach(root.add); + xs = ys = data = d = null; + return root; + } + quadtree.x = function(_) { + return arguments.length ? (x = _, quadtree) : x; + }; + quadtree.y = function(_) { + return arguments.length ? (y = _, quadtree) : y; + }; + quadtree.size = function(_) { + if (!arguments.length) return x1 == null ? null : [ x2, y2 ]; + if (_ == null) { + x1 = y1 = x2 = y2 = null; + } else { + x1 = y1 = 0; + x2 = +_[0], y2 = +_[1]; + } + return quadtree; + }; + return quadtree; + }; + function d3_geom_quadtreeCompatX(d) { + return d.x; + } + function d3_geom_quadtreeCompatY(d) { + return d.y; + } + function d3_geom_quadtreeNode() { + return { + leaf: true, + nodes: [], + point: null, + x: null, + y: null + }; + } + function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { + if (!f(node, x1, y1, x2, y2)) { + var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; + if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); + if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); + if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); + if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); + } + } + d3.interpolateRgb = d3_interpolateRgb; + function d3_interpolateRgb(a, b) { + a = d3.rgb(a); + b = d3.rgb(b); + var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; + return function(t) { + return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); + }; + } + d3.transform = function(string) { + var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); + return (d3.transform = function(string) { + if (string != null) { + g.setAttribute("transform", string); + var t = g.transform.baseVal.consolidate(); + } + return new d3_transform(t ? t.matrix : d3_transformIdentity); + })(string); + }; + function d3_transform(m) { + var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; + if (r0[0] * r1[1] < r1[0] * r0[1]) { + r0[0] *= -1; + r0[1] *= -1; + kx *= -1; + kz *= -1; + } + this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; + this.translate = [ m.e, m.f ]; + this.scale = [ kx, ky ]; + this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; + } + d3_transform.prototype.toString = function() { + return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; + }; + function d3_transformDot(a, b) { + return a[0] * b[0] + a[1] * b[1]; + } + function d3_transformNormalize(a) { + var k = Math.sqrt(d3_transformDot(a, a)); + if (k) { + a[0] /= k; + a[1] /= k; + } + return k; + } + function d3_transformCombine(a, b, k) { + a[0] += k * b[0]; + a[1] += k * b[1]; + return a; + } + var d3_transformIdentity = { + a: 1, + b: 0, + c: 0, + d: 1, + e: 0, + f: 0 + }; + d3.interpolateNumber = d3_interpolateNumber; + function d3_interpolateNumber(a, b) { + b -= a = +a; + return function(t) { + return a + b * t; + }; + } + d3.interpolateTransform = d3_interpolateTransform; + function d3_interpolateTransform(a, b) { + var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; + if (ta[0] != tb[0] || ta[1] != tb[1]) { + s.push("translate(", null, ",", null, ")"); + q.push({ + i: 1, + x: d3_interpolateNumber(ta[0], tb[0]) + }, { + i: 3, + x: d3_interpolateNumber(ta[1], tb[1]) + }); + } else if (tb[0] || tb[1]) { + s.push("translate(" + tb + ")"); + } else { + s.push(""); + } + if (ra != rb) { + if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; + q.push({ + i: s.push(s.pop() + "rotate(", null, ")") - 2, + x: d3_interpolateNumber(ra, rb) + }); + } else if (rb) { + s.push(s.pop() + "rotate(" + rb + ")"); + } + if (wa != wb) { + q.push({ + i: s.push(s.pop() + "skewX(", null, ")") - 2, + x: d3_interpolateNumber(wa, wb) + }); + } else if (wb) { + s.push(s.pop() + "skewX(" + wb + ")"); + } + if (ka[0] != kb[0] || ka[1] != kb[1]) { + n = s.push(s.pop() + "scale(", null, ",", null, ")"); + q.push({ + i: n - 4, + x: d3_interpolateNumber(ka[0], kb[0]) + }, { + i: n - 2, + x: d3_interpolateNumber(ka[1], kb[1]) + }); + } else if (kb[0] != 1 || kb[1] != 1) { + s.push(s.pop() + "scale(" + kb + ")"); + } + n = q.length; + return function(t) { + var i = -1, o; + while (++i < n) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }; + } + d3.interpolateObject = d3_interpolateObject; + function d3_interpolateObject(a, b) { + var i = {}, c = {}, k; + for (k in a) { + if (k in b) { + i[k] = d3_interpolateByName(k)(a[k], b[k]); + } else { + c[k] = a[k]; + } + } + for (k in b) { + if (!(k in a)) { + c[k] = b[k]; + } + } + return function(t) { + for (k in i) c[k] = i[k](t); + return c; + }; + } + d3.interpolateString = d3_interpolateString; + function d3_interpolateString(a, b) { + var m, i, j, s0 = 0, s1 = 0, s = [], q = [], n, o; + a = a + "", b = b + ""; + d3_interpolate_number.lastIndex = 0; + for (i = 0; m = d3_interpolate_number.exec(b); ++i) { + if (m.index) s.push(b.substring(s0, s1 = m.index)); + q.push({ + i: s.length, + x: m[0] + }); + s.push(null); + s0 = d3_interpolate_number.lastIndex; + } + if (s0 < b.length) s.push(b.substring(s0)); + for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) { + o = q[i]; + if (o.x == m[0]) { + if (o.i) { + if (s[o.i + 1] == null) { + s[o.i - 1] += o.x; + s.splice(o.i, 1); + for (j = i + 1; j < n; ++j) q[j].i--; + } else { + s[o.i - 1] += o.x + s[o.i + 1]; + s.splice(o.i, 2); + for (j = i + 1; j < n; ++j) q[j].i -= 2; + } + } else { + if (s[o.i + 1] == null) { + s[o.i] = o.x; + } else { + s[o.i] = o.x + s[o.i + 1]; + s.splice(o.i + 1, 1); + for (j = i + 1; j < n; ++j) q[j].i--; + } + } + q.splice(i, 1); + n--; + i--; + } else { + o.x = d3_interpolateNumber(parseFloat(m[0]), parseFloat(o.x)); + } + } + while (i < n) { + o = q.pop(); + if (s[o.i + 1] == null) { + s[o.i] = o.x; + } else { + s[o.i] = o.x + s[o.i + 1]; + s.splice(o.i + 1, 1); + } + n--; + } + if (s.length === 1) { + return s[0] == null ? (o = q[0].x, function(t) { + return o(t) + ""; + }) : function() { + return b; + }; + } + return function(t) { + for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }; + } + var d3_interpolate_number = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; + d3.interpolate = d3_interpolate; + function d3_interpolate(a, b) { + var i = d3.interpolators.length, f; + while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; + return f; + } + function d3_interpolateByName(name) { + return name == "transform" ? d3_interpolateTransform : d3_interpolate; + } + d3.interpolators = [ function(a, b) { + var t = typeof b; + return (t === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_Color ? d3_interpolateRgb : t === "object" ? Array.isArray(b) ? d3_interpolateArray : d3_interpolateObject : d3_interpolateNumber)(a, b); + } ]; + d3.interpolateArray = d3_interpolateArray; + function d3_interpolateArray(a, b) { + var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; + for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); + for (;i < na; ++i) c[i] = a[i]; + for (;i < nb; ++i) c[i] = b[i]; + return function(t) { + for (i = 0; i < n0; ++i) c[i] = x[i](t); + return c; + }; + } + var d3_ease_default = function() { + return d3_identity; + }; + var d3_ease = d3.map({ + linear: d3_ease_default, + poly: d3_ease_poly, + quad: function() { + return d3_ease_quad; + }, + cubic: function() { + return d3_ease_cubic; + }, + sin: function() { + return d3_ease_sin; + }, + exp: function() { + return d3_ease_exp; + }, + circle: function() { + return d3_ease_circle; + }, + elastic: d3_ease_elastic, + back: d3_ease_back, + bounce: function() { + return d3_ease_bounce; + } + }); + var d3_ease_mode = d3.map({ + "in": d3_identity, + out: d3_ease_reverse, + "in-out": d3_ease_reflect, + "out-in": function(f) { + return d3_ease_reflect(d3_ease_reverse(f)); + } + }); + d3.ease = function(name) { + var i = name.indexOf("-"), t = i >= 0 ? name.substring(0, i) : name, m = i >= 0 ? name.substring(i + 1) : "in"; + t = d3_ease.get(t) || d3_ease_default; + m = d3_ease_mode.get(m) || d3_identity; + return d3_ease_clamp(m(t.apply(null, Array.prototype.slice.call(arguments, 1)))); + }; + function d3_ease_clamp(f) { + return function(t) { + return t <= 0 ? 0 : t >= 1 ? 1 : f(t); + }; + } + function d3_ease_reverse(f) { + return function(t) { + return 1 - f(1 - t); + }; + } + function d3_ease_reflect(f) { + return function(t) { + return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); + }; + } + function d3_ease_quad(t) { + return t * t; + } + function d3_ease_cubic(t) { + return t * t * t; + } + function d3_ease_cubicInOut(t) { + if (t <= 0) return 0; + if (t >= 1) return 1; + var t2 = t * t, t3 = t2 * t; + return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); + } + function d3_ease_poly(e) { + return function(t) { + return Math.pow(t, e); + }; + } + function d3_ease_sin(t) { + return 1 - Math.cos(t * Ï€ / 2); + } + function d3_ease_exp(t) { + return Math.pow(2, 10 * (t - 1)); + } + function d3_ease_circle(t) { + return 1 - Math.sqrt(1 - t * t); + } + function d3_ease_elastic(a, p) { + var s; + if (arguments.length < 2) p = .45; + if (arguments.length) s = p / (2 * Ï€) * Math.asin(1 / a); else a = 1, s = p / 4; + return function(t) { + return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * Ï€ / p); + }; + } + function d3_ease_back(s) { + if (!s) s = 1.70158; + return function(t) { + return t * t * ((s + 1) * t - s); + }; + } + function d3_ease_bounce(t) { + return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; + } + d3.interpolateHcl = d3_interpolateHcl; + function d3_interpolateHcl(a, b) { + a = d3.hcl(a); + b = d3.hcl(b); + var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; + if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; + if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; + return function(t) { + return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; + }; + } + d3.interpolateHsl = d3_interpolateHsl; + function d3_interpolateHsl(a, b) { + a = d3.hsl(a); + b = d3.hsl(b); + var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; + if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; + if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; + return function(t) { + return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; + }; + } + d3.interpolateLab = d3_interpolateLab; + function d3_interpolateLab(a, b) { + a = d3.lab(a); + b = d3.lab(b); + var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; + return function(t) { + return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; + }; + } + d3.interpolateRound = d3_interpolateRound; + function d3_interpolateRound(a, b) { + b -= a; + return function(t) { + return Math.round(a + b * t); + }; + } + function d3_uninterpolateNumber(a, b) { + b = b - (a = +a) ? 1 / (b - a) : 0; + return function(x) { + return (x - a) * b; + }; + } + function d3_uninterpolateClamp(a, b) { + b = b - (a = +a) ? 1 / (b - a) : 0; + return function(x) { + return Math.max(0, Math.min(1, (x - a) * b)); + }; + } + d3.layout = {}; + d3.layout.bundle = function() { + return function(links) { + var paths = [], i = -1, n = links.length; + while (++i < n) paths.push(d3_layout_bundlePath(links[i])); + return paths; + }; + }; + function d3_layout_bundlePath(link) { + var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; + while (start !== lca) { + start = start.parent; + points.push(start); + } + var k = points.length; + while (end !== lca) { + points.splice(k, 0, end); + end = end.parent; + } + return points; + } + function d3_layout_bundleAncestors(node) { + var ancestors = [], parent = node.parent; + while (parent != null) { + ancestors.push(node); + node = parent; + parent = parent.parent; + } + ancestors.push(node); + return ancestors; + } + function d3_layout_bundleLeastCommonAncestor(a, b) { + if (a === b) return a; + var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; + while (aNode === bNode) { + sharedNode = aNode; + aNode = aNodes.pop(); + bNode = bNodes.pop(); + } + return sharedNode; + } + d3.layout.chord = function() { + var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; + function relayout() { + var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; + chords = []; + groups = []; + k = 0, i = -1; + while (++i < n) { + x = 0, j = -1; + while (++j < n) { + x += matrix[i][j]; + } + groupSums.push(x); + subgroupIndex.push(d3.range(n)); + k += x; + } + if (sortGroups) { + groupIndex.sort(function(a, b) { + return sortGroups(groupSums[a], groupSums[b]); + }); + } + if (sortSubgroups) { + subgroupIndex.forEach(function(d, i) { + d.sort(function(a, b) { + return sortSubgroups(matrix[i][a], matrix[i][b]); + }); + }); + } + k = (2 * Ï€ - padding * n) / k; + x = 0, i = -1; + while (++i < n) { + x0 = x, j = -1; + while (++j < n) { + var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; + subgroups[di + "-" + dj] = { + index: di, + subindex: dj, + startAngle: a0, + endAngle: a1, + value: v + }; + } + groups[di] = { + index: di, + startAngle: x0, + endAngle: x, + value: (x - x0) / k + }; + x += padding; + } + i = -1; + while (++i < n) { + j = i - 1; + while (++j < n) { + var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; + if (source.value || target.value) { + chords.push(source.value < target.value ? { + source: target, + target: source + } : { + source: source, + target: target + }); + } + } + } + if (sortChords) resort(); + } + function resort() { + chords.sort(function(a, b) { + return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); + }); + } + chord.matrix = function(x) { + if (!arguments.length) return matrix; + n = (matrix = x) && matrix.length; + chords = groups = null; + return chord; + }; + chord.padding = function(x) { + if (!arguments.length) return padding; + padding = x; + chords = groups = null; + return chord; + }; + chord.sortGroups = function(x) { + if (!arguments.length) return sortGroups; + sortGroups = x; + chords = groups = null; + return chord; + }; + chord.sortSubgroups = function(x) { + if (!arguments.length) return sortSubgroups; + sortSubgroups = x; + chords = null; + return chord; + }; + chord.sortChords = function(x) { + if (!arguments.length) return sortChords; + sortChords = x; + if (chords) resort(); + return chord; + }; + chord.chords = function() { + if (!chords) relayout(); + return chords; + }; + chord.groups = function() { + if (!groups) relayout(); + return groups; + }; + return chord; + }; + d3.layout.force = function() { + var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, gravity = .1, theta = .8, nodes = [], links = [], distances, strengths, charges; + function repulse(node) { + return function(quad, x1, _, x2) { + if (quad.point !== node) { + var dx = quad.cx - node.x, dy = quad.cy - node.y, dn = 1 / Math.sqrt(dx * dx + dy * dy); + if ((x2 - x1) * dn < theta) { + var k = quad.charge * dn * dn; + node.px -= dx * k; + node.py -= dy * k; + return true; + } + if (quad.point && isFinite(dn)) { + var k = quad.pointCharge * dn * dn; + node.px -= dx * k; + node.py -= dy * k; + } + } + return !quad.charge; + }; + } + force.tick = function() { + if ((alpha *= .99) < .005) { + event.end({ + type: "end", + alpha: alpha = 0 + }); + return true; + } + var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; + for (i = 0; i < m; ++i) { + o = links[i]; + s = o.source; + t = o.target; + x = t.x - s.x; + y = t.y - s.y; + if (l = x * x + y * y) { + l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; + x *= l; + y *= l; + t.x -= x * (k = s.weight / (t.weight + s.weight)); + t.y -= y * k; + s.x += x * (k = 1 - k); + s.y += y * k; + } + } + if (k = alpha * gravity) { + x = size[0] / 2; + y = size[1] / 2; + i = -1; + if (k) while (++i < n) { + o = nodes[i]; + o.x += (x - o.x) * k; + o.y += (y - o.y) * k; + } + } + if (charge) { + d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); + i = -1; + while (++i < n) { + if (!(o = nodes[i]).fixed) { + q.visit(repulse(o)); + } + } + } + i = -1; + while (++i < n) { + o = nodes[i]; + if (o.fixed) { + o.x = o.px; + o.y = o.py; + } else { + o.x -= (o.px - (o.px = o.x)) * friction; + o.y -= (o.py - (o.py = o.y)) * friction; + } + } + event.tick({ + type: "tick", + alpha: alpha + }); + }; + force.nodes = function(x) { + if (!arguments.length) return nodes; + nodes = x; + return force; + }; + force.links = function(x) { + if (!arguments.length) return links; + links = x; + return force; + }; + force.size = function(x) { + if (!arguments.length) return size; + size = x; + return force; + }; + force.linkDistance = function(x) { + if (!arguments.length) return linkDistance; + linkDistance = typeof x === "function" ? x : +x; + return force; + }; + force.distance = force.linkDistance; + force.linkStrength = function(x) { + if (!arguments.length) return linkStrength; + linkStrength = typeof x === "function" ? x : +x; + return force; + }; + force.friction = function(x) { + if (!arguments.length) return friction; + friction = +x; + return force; + }; + force.charge = function(x) { + if (!arguments.length) return charge; + charge = typeof x === "function" ? x : +x; + return force; + }; + force.gravity = function(x) { + if (!arguments.length) return gravity; + gravity = +x; + return force; + }; + force.theta = function(x) { + if (!arguments.length) return theta; + theta = +x; + return force; + }; + force.alpha = function(x) { + if (!arguments.length) return alpha; + x = +x; + if (alpha) { + if (x > 0) alpha = x; else alpha = 0; + } else if (x > 0) { + event.start({ + type: "start", + alpha: alpha = x + }); + d3.timer(force.tick); + } + return force; + }; + force.start = function() { + var i, j, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; + for (i = 0; i < n; ++i) { + (o = nodes[i]).index = i; + o.weight = 0; + } + for (i = 0; i < m; ++i) { + o = links[i]; + if (typeof o.source == "number") o.source = nodes[o.source]; + if (typeof o.target == "number") o.target = nodes[o.target]; + ++o.source.weight; + ++o.target.weight; + } + for (i = 0; i < n; ++i) { + o = nodes[i]; + if (isNaN(o.x)) o.x = position("x", w); + if (isNaN(o.y)) o.y = position("y", h); + if (isNaN(o.px)) o.px = o.x; + if (isNaN(o.py)) o.py = o.y; + } + distances = []; + if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; + strengths = []; + if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; + charges = []; + if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; + function position(dimension, size) { + var neighbors = neighbor(i), j = -1, m = neighbors.length, x; + while (++j < m) if (!isNaN(x = neighbors[j][dimension])) return x; + return Math.random() * size; + } + function neighbor() { + if (!neighbors) { + neighbors = []; + for (j = 0; j < n; ++j) { + neighbors[j] = []; + } + for (j = 0; j < m; ++j) { + var o = links[j]; + neighbors[o.source.index].push(o.target); + neighbors[o.target.index].push(o.source); + } + } + return neighbors[i]; + } + return force.resume(); + }; + force.resume = function() { + return force.alpha(.1); + }; + force.stop = function() { + return force.alpha(0); + }; + force.drag = function() { + if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); + if (!arguments.length) return drag; + this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); + }; + function dragmove(d) { + d.px = d3.event.x, d.py = d3.event.y; + force.resume(); + } + return d3.rebind(force, event, "on"); + }; + function d3_layout_forceDragstart(d) { + d.fixed |= 2; + } + function d3_layout_forceDragend(d) { + d.fixed &= ~6; + } + function d3_layout_forceMouseover(d) { + d.fixed |= 4; + d.px = d.x, d.py = d.y; + } + function d3_layout_forceMouseout(d) { + d.fixed &= ~4; + } + function d3_layout_forceAccumulate(quad, alpha, charges) { + var cx = 0, cy = 0; + quad.charge = 0; + if (!quad.leaf) { + var nodes = quad.nodes, n = nodes.length, i = -1, c; + while (++i < n) { + c = nodes[i]; + if (c == null) continue; + d3_layout_forceAccumulate(c, alpha, charges); + quad.charge += c.charge; + cx += c.charge * c.cx; + cy += c.charge * c.cy; + } + } + if (quad.point) { + if (!quad.leaf) { + quad.point.x += Math.random() - .5; + quad.point.y += Math.random() - .5; + } + var k = alpha * charges[quad.point.index]; + quad.charge += quad.pointCharge = k; + cx += k * quad.point.x; + cy += k * quad.point.y; + } + quad.cx = cx / quad.charge; + quad.cy = cy / quad.charge; + } + var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1; + d3.layout.hierarchy = function() { + var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; + function recurse(node, depth, nodes) { + var childs = children.call(hierarchy, node, depth); + node.depth = depth; + nodes.push(node); + if (childs && (n = childs.length)) { + var i = -1, n, c = node.children = [], v = 0, j = depth + 1, d; + while (++i < n) { + d = recurse(childs[i], j, nodes); + d.parent = node; + c.push(d); + v += d.value; + } + if (sort) c.sort(sort); + if (value) node.value = v; + } else if (value) { + node.value = +value.call(hierarchy, node, depth) || 0; + } + return node; + } + function revalue(node, depth) { + var children = node.children, v = 0; + if (children && (n = children.length)) { + var i = -1, n, j = depth + 1; + while (++i < n) v += revalue(children[i], j); + } else if (value) { + v = +value.call(hierarchy, node, depth) || 0; + } + if (value) node.value = v; + return v; + } + function hierarchy(d) { + var nodes = []; + recurse(d, 0, nodes); + return nodes; + } + hierarchy.sort = function(x) { + if (!arguments.length) return sort; + sort = x; + return hierarchy; + }; + hierarchy.children = function(x) { + if (!arguments.length) return children; + children = x; + return hierarchy; + }; + hierarchy.value = function(x) { + if (!arguments.length) return value; + value = x; + return hierarchy; + }; + hierarchy.revalue = function(root) { + revalue(root, 0); + return root; + }; + return hierarchy; + }; + function d3_layout_hierarchyRebind(object, hierarchy) { + d3.rebind(object, hierarchy, "sort", "children", "value"); + object.nodes = object; + object.links = d3_layout_hierarchyLinks; + return object; + } + function d3_layout_hierarchyChildren(d) { + return d.children; + } + function d3_layout_hierarchyValue(d) { + return d.value; + } + function d3_layout_hierarchySort(a, b) { + return b.value - a.value; + } + function d3_layout_hierarchyLinks(nodes) { + return d3.merge(nodes.map(function(parent) { + return (parent.children || []).map(function(child) { + return { + source: parent, + target: child + }; + }); + })); + } + d3.layout.partition = function() { + var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; + function position(node, x, dx, dy) { + var children = node.children; + node.x = x; + node.y = node.depth * dy; + node.dx = dx; + node.dy = dy; + if (children && (n = children.length)) { + var i = -1, n, c, d; + dx = node.value ? dx / node.value : 0; + while (++i < n) { + position(c = children[i], x, d = c.value * dx, dy); + x += d; + } + } + } + function depth(node) { + var children = node.children, d = 0; + if (children && (n = children.length)) { + var i = -1, n; + while (++i < n) d = Math.max(d, depth(children[i])); + } + return 1 + d; + } + function partition(d, i) { + var nodes = hierarchy.call(this, d, i); + position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); + return nodes; + } + partition.size = function(x) { + if (!arguments.length) return size; + size = x; + return partition; + }; + return d3_layout_hierarchyRebind(partition, hierarchy); + }; + d3.layout.pie = function() { + var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = 2 * Ï€; + function pie(data) { + var values = data.map(function(d, i) { + return +value.call(pie, d, i); + }); + var a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle); + var k = ((typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a) / d3.sum(values); + var index = d3.range(data.length); + if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { + return values[j] - values[i]; + } : function(i, j) { + return sort(data[i], data[j]); + }); + var arcs = []; + index.forEach(function(i) { + var d; + arcs[i] = { + data: data[i], + value: d = values[i], + startAngle: a, + endAngle: a += d * k + }; + }); + return arcs; + } + pie.value = function(x) { + if (!arguments.length) return value; + value = x; + return pie; + }; + pie.sort = function(x) { + if (!arguments.length) return sort; + sort = x; + return pie; + }; + pie.startAngle = function(x) { + if (!arguments.length) return startAngle; + startAngle = x; + return pie; + }; + pie.endAngle = function(x) { + if (!arguments.length) return endAngle; + endAngle = x; + return pie; + }; + return pie; + }; + var d3_layout_pieSortByValue = {}; + d3.layout.stack = function() { + var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; + function stack(data, index) { + var series = data.map(function(d, i) { + return values.call(stack, d, i); + }); + var points = series.map(function(d) { + return d.map(function(v, i) { + return [ x.call(stack, v, i), y.call(stack, v, i) ]; + }); + }); + var orders = order.call(stack, points, index); + series = d3.permute(series, orders); + points = d3.permute(points, orders); + var offsets = offset.call(stack, points, index); + var n = series.length, m = series[0].length, i, j, o; + for (j = 0; j < m; ++j) { + out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); + for (i = 1; i < n; ++i) { + out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); + } + } + return data; + } + stack.values = function(x) { + if (!arguments.length) return values; + values = x; + return stack; + }; + stack.order = function(x) { + if (!arguments.length) return order; + order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; + return stack; + }; + stack.offset = function(x) { + if (!arguments.length) return offset; + offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; + return stack; + }; + stack.x = function(z) { + if (!arguments.length) return x; + x = z; + return stack; + }; + stack.y = function(z) { + if (!arguments.length) return y; + y = z; + return stack; + }; + stack.out = function(z) { + if (!arguments.length) return out; + out = z; + return stack; + }; + return stack; + }; + function d3_layout_stackX(d) { + return d.x; + } + function d3_layout_stackY(d) { + return d.y; + } + function d3_layout_stackOut(d, y0, y) { + d.y0 = y0; + d.y = y; + } + var d3_layout_stackOrders = d3.map({ + "inside-out": function(data) { + var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { + return max[a] - max[b]; + }), top = 0, bottom = 0, tops = [], bottoms = []; + for (i = 0; i < n; ++i) { + j = index[i]; + if (top < bottom) { + top += sums[j]; + tops.push(j); + } else { + bottom += sums[j]; + bottoms.push(j); + } + } + return bottoms.reverse().concat(tops); + }, + reverse: function(data) { + return d3.range(data.length).reverse(); + }, + "default": d3_layout_stackOrderDefault + }); + var d3_layout_stackOffsets = d3.map({ + silhouette: function(data) { + var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; + for (j = 0; j < m; ++j) { + for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; + if (o > max) max = o; + sums.push(o); + } + for (j = 0; j < m; ++j) { + y0[j] = (max - sums[j]) / 2; + } + return y0; + }, + wiggle: function(data) { + var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; + y0[0] = o = o0 = 0; + for (j = 1; j < m; ++j) { + for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; + for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { + for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { + s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; + } + s2 += s3 * data[i][j][1]; + } + y0[j] = o -= s1 ? s2 / s1 * dx : 0; + if (o < o0) o0 = o; + } + for (j = 0; j < m; ++j) y0[j] -= o0; + return y0; + }, + expand: function(data) { + var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; + for (j = 0; j < m; ++j) { + for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; + if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; + } + for (j = 0; j < m; ++j) y0[j] = 0; + return y0; + }, + zero: d3_layout_stackOffsetZero + }); + function d3_layout_stackOrderDefault(data) { + return d3.range(data.length); + } + function d3_layout_stackOffsetZero(data) { + var j = -1, m = data[0].length, y0 = []; + while (++j < m) y0[j] = 0; + return y0; + } + function d3_layout_stackMaxIndex(array) { + var i = 1, j = 0, v = array[0][1], k, n = array.length; + for (;i < n; ++i) { + if ((k = array[i][1]) > v) { + j = i; + v = k; + } + } + return j; + } + function d3_layout_stackReduceSum(d) { + return d.reduce(d3_layout_stackSum, 0); + } + function d3_layout_stackSum(p, d) { + return p + d[1]; + } + d3.layout.histogram = function() { + var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; + function histogram(data, i) { + var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; + while (++i < m) { + bin = bins[i] = []; + bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); + bin.y = 0; + } + if (m > 0) { + i = -1; + while (++i < n) { + x = values[i]; + if (x >= range[0] && x <= range[1]) { + bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; + bin.y += k; + bin.push(data[i]); + } + } + } + return bins; + } + histogram.value = function(x) { + if (!arguments.length) return valuer; + valuer = x; + return histogram; + }; + histogram.range = function(x) { + if (!arguments.length) return ranger; + ranger = d3_functor(x); + return histogram; + }; + histogram.bins = function(x) { + if (!arguments.length) return binner; + binner = typeof x === "number" ? function(range) { + return d3_layout_histogramBinFixed(range, x); + } : d3_functor(x); + return histogram; + }; + histogram.frequency = function(x) { + if (!arguments.length) return frequency; + frequency = !!x; + return histogram; + }; + return histogram; + }; + function d3_layout_histogramBinSturges(range, values) { + return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); + } + function d3_layout_histogramBinFixed(range, n) { + var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; + while (++x <= n) f[x] = m * x + b; + return f; + } + function d3_layout_histogramRange(values) { + return [ d3.min(values), d3.max(values) ]; + } + d3.layout.tree = function() { + var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ]; + function tree(d, i) { + var nodes = hierarchy.call(this, d, i), root = nodes[0]; + function firstWalk(node, previousSibling) { + var children = node.children, layout = node._tree; + if (children && (n = children.length)) { + var n, firstChild = children[0], previousChild, ancestor = firstChild, child, i = -1; + while (++i < n) { + child = children[i]; + firstWalk(child, previousChild); + ancestor = apportion(child, previousChild, ancestor); + previousChild = child; + } + d3_layout_treeShift(node); + var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim); + if (previousSibling) { + layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); + layout.mod = layout.prelim - midpoint; + } else { + layout.prelim = midpoint; + } + } else { + if (previousSibling) { + layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); + } + } + } + function secondWalk(node, x) { + node.x = node._tree.prelim + x; + var children = node.children; + if (children && (n = children.length)) { + var i = -1, n; + x += node._tree.mod; + while (++i < n) { + secondWalk(children[i], x); + } + } + } + function apportion(node, previousSibling, ancestor) { + if (previousSibling) { + var vip = node, vop = node, vim = previousSibling, vom = node.parent.children[0], sip = vip._tree.mod, sop = vop._tree.mod, sim = vim._tree.mod, som = vom._tree.mod, shift; + while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { + vom = d3_layout_treeLeft(vom); + vop = d3_layout_treeRight(vop); + vop._tree.ancestor = node; + shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip); + if (shift > 0) { + d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift); + sip += shift; + sop += shift; + } + sim += vim._tree.mod; + sip += vip._tree.mod; + som += vom._tree.mod; + sop += vop._tree.mod; + } + if (vim && !d3_layout_treeRight(vop)) { + vop._tree.thread = vim; + vop._tree.mod += sim - sop; + } + if (vip && !d3_layout_treeLeft(vom)) { + vom._tree.thread = vip; + vom._tree.mod += sip - som; + ancestor = node; + } + } + return ancestor; + } + d3_layout_treeVisitAfter(root, function(node, previousSibling) { + node._tree = { + ancestor: node, + prelim: 0, + mod: 0, + change: 0, + shift: 0, + number: previousSibling ? previousSibling._tree.number + 1 : 0 + }; + }); + firstWalk(root); + secondWalk(root, -root._tree.prelim); + var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost), right = d3_layout_treeSearch(root, d3_layout_treeRightmost), deep = d3_layout_treeSearch(root, d3_layout_treeDeepest), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2, y1 = deep.depth || 1; + d3_layout_treeVisitAfter(root, function(node) { + node.x = (node.x - x0) / (x1 - x0) * size[0]; + node.y = node.depth / y1 * size[1]; + delete node._tree; + }); + return nodes; + } + tree.separation = function(x) { + if (!arguments.length) return separation; + separation = x; + return tree; + }; + tree.size = function(x) { + if (!arguments.length) return size; + size = x; + return tree; + }; + return d3_layout_hierarchyRebind(tree, hierarchy); + }; + function d3_layout_treeSeparation(a, b) { + return a.parent == b.parent ? 1 : 2; + } + function d3_layout_treeLeft(node) { + var children = node.children; + return children && children.length ? children[0] : node._tree.thread; + } + function d3_layout_treeRight(node) { + var children = node.children, n; + return children && (n = children.length) ? children[n - 1] : node._tree.thread; + } + function d3_layout_treeSearch(node, compare) { + var children = node.children; + if (children && (n = children.length)) { + var child, n, i = -1; + while (++i < n) { + if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) { + node = child; + } + } + } + return node; + } + function d3_layout_treeRightmost(a, b) { + return a.x - b.x; + } + function d3_layout_treeLeftmost(a, b) { + return b.x - a.x; + } + function d3_layout_treeDeepest(a, b) { + return a.depth - b.depth; + } + function d3_layout_treeVisitAfter(node, callback) { + function visit(node, previousSibling) { + var children = node.children; + if (children && (n = children.length)) { + var child, previousChild = null, i = -1, n; + while (++i < n) { + child = children[i]; + visit(child, previousChild); + previousChild = child; + } + } + callback(node, previousSibling); + } + visit(node, null); + } + function d3_layout_treeShift(node) { + var shift = 0, change = 0, children = node.children, i = children.length, child; + while (--i >= 0) { + child = children[i]._tree; + child.prelim += shift; + child.mod += shift; + shift += child.shift + (change += child.change); + } + } + function d3_layout_treeMove(ancestor, node, shift) { + ancestor = ancestor._tree; + node = node._tree; + var change = shift / (node.number - ancestor.number); + ancestor.change += change; + node.change -= change; + node.shift += shift; + node.prelim += shift; + node.mod += shift; + } + function d3_layout_treeAncestor(vim, node, ancestor) { + return vim._tree.ancestor.parent == node.parent ? vim._tree.ancestor : ancestor; + } + d3.layout.pack = function() { + var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ]; + function pack(d, i) { + var nodes = hierarchy.call(this, d, i), root = nodes[0]; + root.x = 0; + root.y = 0; + d3_layout_treeVisitAfter(root, function(d) { + d.r = Math.sqrt(d.value); + }); + d3_layout_treeVisitAfter(root, d3_layout_packSiblings); + var w = size[0], h = size[1], k = Math.max(2 * root.r / w, 2 * root.r / h); + if (padding > 0) { + var dr = padding * k / 2; + d3_layout_treeVisitAfter(root, function(d) { + d.r += dr; + }); + d3_layout_treeVisitAfter(root, d3_layout_packSiblings); + d3_layout_treeVisitAfter(root, function(d) { + d.r -= dr; + }); + k = Math.max(2 * root.r / w, 2 * root.r / h); + } + d3_layout_packTransform(root, w / 2, h / 2, 1 / k); + return nodes; + } + pack.size = function(x) { + if (!arguments.length) return size; + size = x; + return pack; + }; + pack.padding = function(_) { + if (!arguments.length) return padding; + padding = +_; + return pack; + }; + return d3_layout_hierarchyRebind(pack, hierarchy); + }; + function d3_layout_packSort(a, b) { + return a.value - b.value; + } + function d3_layout_packInsert(a, b) { + var c = a._pack_next; + a._pack_next = b; + b._pack_prev = a; + b._pack_next = c; + c._pack_prev = b; + } + function d3_layout_packSplice(a, b) { + a._pack_next = b; + b._pack_prev = a; + } + function d3_layout_packIntersects(a, b) { + var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; + return dr * dr - dx * dx - dy * dy > .001; + } + function d3_layout_packSiblings(node) { + if (!(nodes = node.children) || !(n = nodes.length)) return; + var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; + function bound(node) { + xMin = Math.min(node.x - node.r, xMin); + xMax = Math.max(node.x + node.r, xMax); + yMin = Math.min(node.y - node.r, yMin); + yMax = Math.max(node.y + node.r, yMax); + } + nodes.forEach(d3_layout_packLink); + a = nodes[0]; + a.x = -a.r; + a.y = 0; + bound(a); + if (n > 1) { + b = nodes[1]; + b.x = b.r; + b.y = 0; + bound(b); + if (n > 2) { + c = nodes[2]; + d3_layout_packPlace(a, b, c); + bound(c); + d3_layout_packInsert(a, c); + a._pack_prev = c; + d3_layout_packInsert(c, b); + b = a._pack_next; + for (i = 3; i < n; i++) { + d3_layout_packPlace(a, b, c = nodes[i]); + var isect = 0, s1 = 1, s2 = 1; + for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { + if (d3_layout_packIntersects(j, c)) { + isect = 1; + break; + } + } + if (isect == 1) { + for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { + if (d3_layout_packIntersects(k, c)) { + break; + } + } + } + if (isect) { + if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); + i--; + } else { + d3_layout_packInsert(a, c); + b = c; + bound(c); + } + } + } + } + var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; + for (i = 0; i < n; i++) { + c = nodes[i]; + c.x -= cx; + c.y -= cy; + cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); + } + node.r = cr; + nodes.forEach(d3_layout_packUnlink); + } + function d3_layout_packLink(node) { + node._pack_next = node._pack_prev = node; + } + function d3_layout_packUnlink(node) { + delete node._pack_next; + delete node._pack_prev; + } + function d3_layout_packTransform(node, x, y, k) { + var children = node.children; + node.x = x += k * node.x; + node.y = y += k * node.y; + node.r *= k; + if (children) { + var i = -1, n = children.length; + while (++i < n) d3_layout_packTransform(children[i], x, y, k); + } + } + function d3_layout_packPlace(a, b, c) { + var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; + if (db && (dx || dy)) { + var da = b.r + c.r, dc = dx * dx + dy * dy; + da *= da; + db *= db; + var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); + c.x = a.x + x * dx + y * dy; + c.y = a.y + x * dy - y * dx; + } else { + c.x = a.x + db; + c.y = a.y; + } + } + d3.layout.cluster = function() { + var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ]; + function cluster(d, i) { + var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; + d3_layout_treeVisitAfter(root, function(node) { + var children = node.children; + if (children && children.length) { + node.x = d3_layout_clusterX(children); + node.y = d3_layout_clusterY(children); + } else { + node.x = previousNode ? x += separation(node, previousNode) : 0; + node.y = 0; + previousNode = node; + } + }); + var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; + d3_layout_treeVisitAfter(root, function(node) { + node.x = (node.x - x0) / (x1 - x0) * size[0]; + node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; + }); + return nodes; + } + cluster.separation = function(x) { + if (!arguments.length) return separation; + separation = x; + return cluster; + }; + cluster.size = function(x) { + if (!arguments.length) return size; + size = x; + return cluster; + }; + return d3_layout_hierarchyRebind(cluster, hierarchy); + }; + function d3_layout_clusterY(children) { + return 1 + d3.max(children, function(child) { + return child.y; + }); + } + function d3_layout_clusterX(children) { + return children.reduce(function(x, child) { + return x + child.x; + }, 0) / children.length; + } + function d3_layout_clusterLeft(node) { + var children = node.children; + return children && children.length ? d3_layout_clusterLeft(children[0]) : node; + } + function d3_layout_clusterRight(node) { + var children = node.children, n; + return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; + } + d3.layout.treemap = function() { + var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); + function scale(children, k) { + var i = -1, n = children.length, child, area; + while (++i < n) { + area = (child = children[i]).value * (k < 0 ? 0 : k); + child.area = isNaN(area) || area <= 0 ? 0 : area; + } + } + function squarify(node) { + var children = node.children; + if (children && children.length) { + var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; + scale(remaining, rect.dx * rect.dy / node.value); + row.area = 0; + while ((n = remaining.length) > 0) { + row.push(child = remaining[n - 1]); + row.area += child.area; + if (mode !== "squarify" || (score = worst(row, u)) <= best) { + remaining.pop(); + best = score; + } else { + row.area -= row.pop().area; + position(row, u, rect, false); + u = Math.min(rect.dx, rect.dy); + row.length = row.area = 0; + best = Infinity; + } + } + if (row.length) { + position(row, u, rect, true); + row.length = row.area = 0; + } + children.forEach(squarify); + } + } + function stickify(node) { + var children = node.children; + if (children && children.length) { + var rect = pad(node), remaining = children.slice(), child, row = []; + scale(remaining, rect.dx * rect.dy / node.value); + row.area = 0; + while (child = remaining.pop()) { + row.push(child); + row.area += child.area; + if (child.z != null) { + position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); + row.length = row.area = 0; + } + } + children.forEach(stickify); + } + } + function worst(row, u) { + var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; + while (++i < n) { + if (!(r = row[i].area)) continue; + if (r < rmin) rmin = r; + if (r > rmax) rmax = r; + } + s *= s; + u *= u; + return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; + } + function position(row, u, rect, flush) { + var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; + if (u == rect.dx) { + if (flush || v > rect.dy) v = rect.dy; + while (++i < n) { + o = row[i]; + o.x = x; + o.y = y; + o.dy = v; + x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); + } + o.z = true; + o.dx += rect.x + rect.dx - x; + rect.y += v; + rect.dy -= v; + } else { + if (flush || v > rect.dx) v = rect.dx; + while (++i < n) { + o = row[i]; + o.x = x; + o.y = y; + o.dx = v; + y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); + } + o.z = false; + o.dy += rect.y + rect.dy - y; + rect.x += v; + rect.dx -= v; + } + } + function treemap(d) { + var nodes = stickies || hierarchy(d), root = nodes[0]; + root.x = 0; + root.y = 0; + root.dx = size[0]; + root.dy = size[1]; + if (stickies) hierarchy.revalue(root); + scale([ root ], root.dx * root.dy / root.value); + (stickies ? stickify : squarify)(root); + if (sticky) stickies = nodes; + return nodes; + } + treemap.size = function(x) { + if (!arguments.length) return size; + size = x; + return treemap; + }; + treemap.padding = function(x) { + if (!arguments.length) return padding; + function padFunction(node) { + var p = x.call(treemap, node, node.depth); + return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); + } + function padConstant(node) { + return d3_layout_treemapPad(node, x); + } + var type; + pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], + padConstant) : padConstant; + return treemap; + }; + treemap.round = function(x) { + if (!arguments.length) return round != Number; + round = x ? Math.round : Number; + return treemap; + }; + treemap.sticky = function(x) { + if (!arguments.length) return sticky; + sticky = x; + stickies = null; + return treemap; + }; + treemap.ratio = function(x) { + if (!arguments.length) return ratio; + ratio = x; + return treemap; + }; + treemap.mode = function(x) { + if (!arguments.length) return mode; + mode = x + ""; + return treemap; + }; + return d3_layout_hierarchyRebind(treemap, hierarchy); + }; + function d3_layout_treemapPadNull(node) { + return { + x: node.x, + y: node.y, + dx: node.dx, + dy: node.dy + }; + } + function d3_layout_treemapPad(node, padding) { + var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; + if (dx < 0) { + x += dx / 2; + dx = 0; + } + if (dy < 0) { + y += dy / 2; + dy = 0; + } + return { + x: x, + y: y, + dx: dx, + dy: dy + }; + } + d3.random = { + normal: function(µ, σ) { + var n = arguments.length; + if (n < 2) σ = 1; + if (n < 1) µ = 0; + return function() { + var x, y, r; + do { + x = Math.random() * 2 - 1; + y = Math.random() * 2 - 1; + r = x * x + y * y; + } while (!r || r > 1); + return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); + }; + }, + logNormal: function() { + var random = d3.random.normal.apply(d3, arguments); + return function() { + return Math.exp(random()); + }; + }, + irwinHall: function(m) { + return function() { + for (var s = 0, j = 0; j < m; j++) s += Math.random(); + return s / m; + }; + } + }; + d3.scale = {}; + function d3_scaleExtent(domain) { + var start = domain[0], stop = domain[domain.length - 1]; + return start < stop ? [ start, stop ] : [ stop, start ]; + } + function d3_scaleRange(scale) { + return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); + } + function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { + var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); + return function(x) { + return i(u(x)); + }; + } + function d3_scale_nice(domain, nice) { + var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; + if (x1 < x0) { + dx = i0, i0 = i1, i1 = dx; + dx = x0, x0 = x1, x1 = dx; + } + if (nice = nice(x1 - x0)) { + domain[i0] = nice.floor(x0); + domain[i1] = nice.ceil(x1); + } + return domain; + } + function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { + var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; + if (domain[k] < domain[0]) { + domain = domain.slice().reverse(); + range = range.slice().reverse(); + } + while (++j <= k) { + u.push(uninterpolate(domain[j - 1], domain[j])); + i.push(interpolate(range[j - 1], range[j])); + } + return function(x) { + var j = d3.bisect(domain, x, 1, k) - 1; + return i[j](u[j](x)); + }; + } + d3.scale.linear = function() { + return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); + }; + function d3_scale_linear(domain, range, interpolate, clamp) { + var output, input; + function rescale() { + var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; + output = linear(domain, range, uninterpolate, interpolate); + input = linear(range, domain, uninterpolate, d3_interpolate); + return scale; + } + function scale(x) { + return output(x); + } + scale.invert = function(y) { + return input(y); + }; + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = x.map(Number); + return rescale(); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + scale.rangeRound = function(x) { + return scale.range(x).interpolate(d3_interpolateRound); + }; + scale.clamp = function(x) { + if (!arguments.length) return clamp; + clamp = x; + return rescale(); + }; + scale.interpolate = function(x) { + if (!arguments.length) return interpolate; + interpolate = x; + return rescale(); + }; + scale.ticks = function(m) { + return d3_scale_linearTicks(domain, m); + }; + scale.tickFormat = function(m, format) { + return d3_scale_linearTickFormat(domain, m, format); + }; + scale.nice = function() { + d3_scale_nice(domain, d3_scale_linearNice); + return rescale(); + }; + scale.copy = function() { + return d3_scale_linear(domain, range, interpolate, clamp); + }; + return rescale(); + } + function d3_scale_linearRebind(scale, linear) { + return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); + } + function d3_scale_linearNice(dx) { + dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1); + return dx && { + floor: function(x) { + return Math.floor(x / dx) * dx; + }, + ceil: function(x) { + return Math.ceil(x / dx) * dx; + } + }; + } + function d3_scale_linearTickRange(domain, m) { + var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; + if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; + extent[0] = Math.ceil(extent[0] / step) * step; + extent[1] = Math.floor(extent[1] / step) * step + step * .5; + extent[2] = step; + return extent; + } + function d3_scale_linearTicks(domain, m) { + return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); + } + function d3_scale_linearTickFormat(domain, m, format) { + var precision = -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01); + return d3.format(format ? format.replace(d3_format_re, function(a, b, c, d, e, f, g, h, i, j) { + return [ b, c, d, e, f, g, h, i || "." + (precision - (j === "%") * 2), j ].join(""); + }) : ",." + precision + "f"); + } + d3.scale.log = function() { + return d3_scale_log(d3.scale.linear().domain([ 0, Math.LN10 ]), 10, d3_scale_logp, d3_scale_powp, [ 1, 10 ]); + }; + function d3_scale_log(linear, base, log, pow, domain) { + function scale(x) { + return linear(log(x)); + } + scale.invert = function(x) { + return pow(linear.invert(x)); + }; + scale.domain = function(x) { + if (!arguments.length) return domain; + if (x[0] < 0) log = d3_scale_logn, pow = d3_scale_pown; else log = d3_scale_logp, + pow = d3_scale_powp; + linear.domain((domain = x.map(Number)).map(log)); + return scale; + }; + scale.base = function(_) { + if (!arguments.length) return base; + base = +_; + return scale; + }; + scale.nice = function() { + linear.domain(d3_scale_nice(domain, nice).map(log)); + return scale; + }; + scale.ticks = function() { + var extent = d3_scaleExtent(linear.domain()), ticks = []; + if (extent.every(isFinite)) { + var b = Math.log(base), i = Math.floor(extent[0] / b), j = Math.ceil(extent[1] / b), u = pow(extent[0]), v = pow(extent[1]), n = base % 1 ? 2 : base; + if (log === d3_scale_logn) { + ticks.push(-Math.pow(base, -i)); + for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(-Math.pow(base, -i) * k); + } else { + for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(Math.pow(base, i) * k); + ticks.push(Math.pow(base, i)); + } + for (i = 0; ticks[i] < u; i++) {} + for (j = ticks.length; ticks[j - 1] > v; j--) {} + ticks = ticks.slice(i, j); + } + return ticks; + }; + scale.tickFormat = function(n, format) { + if (arguments.length < 2) format = d3_scale_logFormat; + if (!arguments.length) return format; + var b = Math.log(base), k = Math.max(.1, n / scale.ticks().length), f = log === d3_scale_logn ? (e = -1e-12, + Math.floor) : (e = 1e-12, Math.ceil), e; + return function(d) { + return d / pow(b * f(log(d) / b + e)) <= k ? format(d) : ""; + }; + }; + scale.copy = function() { + return d3_scale_log(linear.copy(), base, log, pow, domain); + }; + function nice() { + return log === d3_scale_logp ? { + floor: floor, + ceil: ceil + } : { + floor: function(x) { + return -ceil(-x); + }, + ceil: function(x) { + return -floor(-x); + } + }; + } + function floor(x) { + return Math.pow(base, Math.floor(Math.log(x) / Math.log(base))); + } + function ceil(x) { + return Math.pow(base, Math.ceil(Math.log(x) / Math.log(base))); + } + return d3_scale_linearRebind(scale, linear); + } + var d3_scale_logFormat = d3.format(".0e"); + function d3_scale_logp(x) { + return Math.log(x < 0 ? 0 : x); + } + function d3_scale_powp(x) { + return Math.exp(x); + } + function d3_scale_logn(x) { + return -Math.log(x > 0 ? 0 : -x); + } + function d3_scale_pown(x) { + return -Math.exp(-x); + } + d3.scale.pow = function() { + return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); + }; + function d3_scale_pow(linear, exponent, domain) { + var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); + function scale(x) { + return linear(powp(x)); + } + scale.invert = function(x) { + return powb(linear.invert(x)); + }; + scale.domain = function(x) { + if (!arguments.length) return domain; + linear.domain((domain = x.map(Number)).map(powp)); + return scale; + }; + scale.ticks = function(m) { + return d3_scale_linearTicks(domain, m); + }; + scale.tickFormat = function(m, format) { + return d3_scale_linearTickFormat(domain, m, format); + }; + scale.nice = function() { + return scale.domain(d3_scale_nice(domain, d3_scale_linearNice)); + }; + scale.exponent = function(x) { + if (!arguments.length) return exponent; + powp = d3_scale_powPow(exponent = x); + powb = d3_scale_powPow(1 / exponent); + linear.domain(domain.map(powp)); + return scale; + }; + scale.copy = function() { + return d3_scale_pow(linear.copy(), exponent, domain); + }; + return d3_scale_linearRebind(scale, linear); + } + function d3_scale_powPow(e) { + return function(x) { + return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); + }; + } + d3.scale.sqrt = function() { + return d3.scale.pow().exponent(.5); + }; + d3.scale.ordinal = function() { + return d3_scale_ordinal([], { + t: "range", + a: [ [] ] + }); + }; + function d3_scale_ordinal(domain, ranger) { + var index, range, rangeBand; + function scale(x) { + return range[((index.get(x) || index.set(x, domain.push(x))) - 1) % range.length]; + } + function steps(start, step) { + return d3.range(domain.length).map(function(i) { + return start + step * i; + }); + } + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = []; + index = new d3_Map(); + var i = -1, n = x.length, xi; + while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); + return scale[ranger.t].apply(scale, ranger.a); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + rangeBand = 0; + ranger = { + t: "range", + a: arguments + }; + return scale; + }; + scale.rangePoints = function(x, padding) { + if (arguments.length < 2) padding = 0; + var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding); + range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step); + rangeBand = 0; + ranger = { + t: "rangePoints", + a: arguments + }; + return scale; + }; + scale.rangeBands = function(x, padding, outerPadding) { + if (arguments.length < 2) padding = 0; + if (arguments.length < 3) outerPadding = padding; + var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); + range = steps(start + step * outerPadding, step); + if (reverse) range.reverse(); + rangeBand = step * (1 - padding); + ranger = { + t: "rangeBands", + a: arguments + }; + return scale; + }; + scale.rangeRoundBands = function(x, padding, outerPadding) { + if (arguments.length < 2) padding = 0; + if (arguments.length < 3) outerPadding = padding; + var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step; + range = steps(start + Math.round(error / 2), step); + if (reverse) range.reverse(); + rangeBand = Math.round(step * (1 - padding)); + ranger = { + t: "rangeRoundBands", + a: arguments + }; + return scale; + }; + scale.rangeBand = function() { + return rangeBand; + }; + scale.rangeExtent = function() { + return d3_scaleExtent(ranger.a[0]); + }; + scale.copy = function() { + return d3_scale_ordinal(domain, ranger); + }; + return scale.domain(domain); + } + d3.scale.category10 = function() { + return d3.scale.ordinal().range(d3_category10); + }; + d3.scale.category20 = function() { + return d3.scale.ordinal().range(d3_category20); + }; + d3.scale.category20b = function() { + return d3.scale.ordinal().range(d3_category20b); + }; + d3.scale.category20c = function() { + return d3.scale.ordinal().range(d3_category20c); + }; + var d3_category10 = [ "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf" ]; + var d3_category20 = [ "#1f77b4", "#aec7e8", "#ff7f0e", "#ffbb78", "#2ca02c", "#98df8a", "#d62728", "#ff9896", "#9467bd", "#c5b0d5", "#8c564b", "#c49c94", "#e377c2", "#f7b6d2", "#7f7f7f", "#c7c7c7", "#bcbd22", "#dbdb8d", "#17becf", "#9edae5" ]; + var d3_category20b = [ "#393b79", "#5254a3", "#6b6ecf", "#9c9ede", "#637939", "#8ca252", "#b5cf6b", "#cedb9c", "#8c6d31", "#bd9e39", "#e7ba52", "#e7cb94", "#843c39", "#ad494a", "#d6616b", "#e7969c", "#7b4173", "#a55194", "#ce6dbd", "#de9ed6" ]; + var d3_category20c = [ "#3182bd", "#6baed6", "#9ecae1", "#c6dbef", "#e6550d", "#fd8d3c", "#fdae6b", "#fdd0a2", "#31a354", "#74c476", "#a1d99b", "#c7e9c0", "#756bb1", "#9e9ac8", "#bcbddc", "#dadaeb", "#636363", "#969696", "#bdbdbd", "#d9d9d9" ]; + d3.scale.quantile = function() { + return d3_scale_quantile([], []); + }; + function d3_scale_quantile(domain, range) { + var thresholds; + function rescale() { + var k = 0, q = range.length; + thresholds = []; + while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); + return scale; + } + function scale(x) { + if (isNaN(x = +x)) return NaN; + return range[d3.bisect(thresholds, x)]; + } + scale.domain = function(x) { + if (!arguments.length) return domain; + domain = x.filter(function(d) { + return !isNaN(d); + }).sort(d3.ascending); + return rescale(); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + scale.quantiles = function() { + return thresholds; + }; + scale.copy = function() { + return d3_scale_quantile(domain, range); + }; + return rescale(); + } + d3.scale.quantize = function() { + return d3_scale_quantize(0, 1, [ 0, 1 ]); + }; + function d3_scale_quantize(x0, x1, range) { + var kx, i; + function scale(x) { + return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; + } + function rescale() { + kx = range.length / (x1 - x0); + i = range.length - 1; + return scale; + } + scale.domain = function(x) { + if (!arguments.length) return [ x0, x1 ]; + x0 = +x[0]; + x1 = +x[x.length - 1]; + return rescale(); + }; + scale.range = function(x) { + if (!arguments.length) return range; + range = x; + return rescale(); + }; + scale.copy = function() { + return d3_scale_quantize(x0, x1, range); + }; + return rescale(); + } + d3.scale.threshold = function() { + return d3_scale_threshold([ .5 ], [ 0, 1 ]); + }; + function d3_scale_threshold(domain, range) { + function scale(x) { + return range[d3.bisect(domain, x)]; + } + scale.domain = function(_) { + if (!arguments.length) return domain; + domain = _; + return scale; + }; + scale.range = function(_) { + if (!arguments.length) return range; + range = _; + return scale; + }; + scale.copy = function() { + return d3_scale_threshold(domain, range); + }; + return scale; + } + d3.scale.identity = function() { + return d3_scale_identity([ 0, 1 ]); + }; + function d3_scale_identity(domain) { + function identity(x) { + return +x; + } + identity.invert = identity; + identity.domain = identity.range = function(x) { + if (!arguments.length) return domain; + domain = x.map(identity); + return identity; + }; + identity.ticks = function(m) { + return d3_scale_linearTicks(domain, m); + }; + identity.tickFormat = function(m, format) { + return d3_scale_linearTickFormat(domain, m, format); + }; + identity.copy = function() { + return d3_scale_identity(domain); + }; + return identity; + } + d3.svg.arc = function() { + var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; + function arc() { + var r0 = innerRadius.apply(this, arguments), r1 = outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, da = (a1 < a0 && (da = a0, + a0 = a1, a1 = da), a1 - a0), df = da < Ï€ ? "0" : "1", c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1); + return da >= d3_svg_arcMax ? r0 ? "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "M0," + r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + -r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + r0 + "Z" : "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "Z" : r0 ? "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L" + r0 * c1 + "," + r0 * s1 + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0 + "Z" : "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L0,0" + "Z"; + } + arc.innerRadius = function(v) { + if (!arguments.length) return innerRadius; + innerRadius = d3_functor(v); + return arc; + }; + arc.outerRadius = function(v) { + if (!arguments.length) return outerRadius; + outerRadius = d3_functor(v); + return arc; + }; + arc.startAngle = function(v) { + if (!arguments.length) return startAngle; + startAngle = d3_functor(v); + return arc; + }; + arc.endAngle = function(v) { + if (!arguments.length) return endAngle; + endAngle = d3_functor(v); + return arc; + }; + arc.centroid = function() { + var r = (innerRadius.apply(this, arguments) + outerRadius.apply(this, arguments)) / 2, a = (startAngle.apply(this, arguments) + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset; + return [ Math.cos(a) * r, Math.sin(a) * r ]; + }; + return arc; + }; + var d3_svg_arcOffset = -Ï€ / 2, d3_svg_arcMax = 2 * Ï€ - 1e-6; + function d3_svg_arcInnerRadius(d) { + return d.innerRadius; + } + function d3_svg_arcOuterRadius(d) { + return d.outerRadius; + } + function d3_svg_arcStartAngle(d) { + return d.startAngle; + } + function d3_svg_arcEndAngle(d) { + return d.endAngle; + } + d3.svg.line.radial = function() { + var line = d3_svg_line(d3_svg_lineRadial); + line.radius = line.x, delete line.x; + line.angle = line.y, delete line.y; + return line; + }; + function d3_svg_lineRadial(points) { + var point, i = -1, n = points.length, r, a; + while (++i < n) { + point = points[i]; + r = point[0]; + a = point[1] + d3_svg_arcOffset; + point[0] = r * Math.cos(a); + point[1] = r * Math.sin(a); + } + return points; + } + function d3_svg_area(projection) { + var x0 = d3_svg_lineX, x1 = d3_svg_lineX, y0 = 0, y1 = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; + function area(data) { + var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { + return x; + } : d3_functor(x1), fy1 = y0 === y1 ? function() { + return y; + } : d3_functor(y1), x, y; + function segment() { + segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); + } + while (++i < n) { + if (defined.call(this, d = data[i], i)) { + points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); + points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); + } else if (points0.length) { + segment(); + points0 = []; + points1 = []; + } + } + if (points0.length) segment(); + return segments.length ? segments.join("") : null; + } + area.x = function(_) { + if (!arguments.length) return x1; + x0 = x1 = _; + return area; + }; + area.x0 = function(_) { + if (!arguments.length) return x0; + x0 = _; + return area; + }; + area.x1 = function(_) { + if (!arguments.length) return x1; + x1 = _; + return area; + }; + area.y = function(_) { + if (!arguments.length) return y1; + y0 = y1 = _; + return area; + }; + area.y0 = function(_) { + if (!arguments.length) return y0; + y0 = _; + return area; + }; + area.y1 = function(_) { + if (!arguments.length) return y1; + y1 = _; + return area; + }; + area.defined = function(_) { + if (!arguments.length) return defined; + defined = _; + return area; + }; + area.interpolate = function(_) { + if (!arguments.length) return interpolateKey; + if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; + interpolateReverse = interpolate.reverse || interpolate; + L = interpolate.closed ? "M" : "L"; + return area; + }; + area.tension = function(_) { + if (!arguments.length) return tension; + tension = _; + return area; + }; + return area; + } + d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; + d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; + d3.svg.area = function() { + return d3_svg_area(d3_identity); + }; + d3.svg.area.radial = function() { + var area = d3_svg_area(d3_svg_lineRadial); + area.radius = area.x, delete area.x; + area.innerRadius = area.x0, delete area.x0; + area.outerRadius = area.x1, delete area.x1; + area.angle = area.y, delete area.y; + area.startAngle = area.y0, delete area.y0; + area.endAngle = area.y1, delete area.y1; + return area; + }; + d3.svg.chord = function() { + var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; + function chord(d, i) { + var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); + return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; + } + function subgroup(self, f, d, i) { + var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset, a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset; + return { + r: r, + a0: a0, + a1: a1, + p0: [ r * Math.cos(a0), r * Math.sin(a0) ], + p1: [ r * Math.cos(a1), r * Math.sin(a1) ] + }; + } + function equals(a, b) { + return a.a0 == b.a0 && a.a1 == b.a1; + } + function arc(r, p, a) { + return "A" + r + "," + r + " 0 " + +(a > Ï€) + ",1 " + p; + } + function curve(r0, p0, r1, p1) { + return "Q 0,0 " + p1; + } + chord.radius = function(v) { + if (!arguments.length) return radius; + radius = d3_functor(v); + return chord; + }; + chord.source = function(v) { + if (!arguments.length) return source; + source = d3_functor(v); + return chord; + }; + chord.target = function(v) { + if (!arguments.length) return target; + target = d3_functor(v); + return chord; + }; + chord.startAngle = function(v) { + if (!arguments.length) return startAngle; + startAngle = d3_functor(v); + return chord; + }; + chord.endAngle = function(v) { + if (!arguments.length) return endAngle; + endAngle = d3_functor(v); + return chord; + }; + return chord; + }; + function d3_svg_chordRadius(d) { + return d.radius; + } + d3.svg.diagonal = function() { + var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; + function diagonal(d, i) { + var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { + x: p0.x, + y: m + }, { + x: p3.x, + y: m + }, p3 ]; + p = p.map(projection); + return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; + } + diagonal.source = function(x) { + if (!arguments.length) return source; + source = d3_functor(x); + return diagonal; + }; + diagonal.target = function(x) { + if (!arguments.length) return target; + target = d3_functor(x); + return diagonal; + }; + diagonal.projection = function(x) { + if (!arguments.length) return projection; + projection = x; + return diagonal; + }; + return diagonal; + }; + function d3_svg_diagonalProjection(d) { + return [ d.x, d.y ]; + } + d3.svg.diagonal.radial = function() { + var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; + diagonal.projection = function(x) { + return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; + }; + return diagonal; + }; + function d3_svg_diagonalRadialProjection(projection) { + return function() { + var d = projection.apply(this, arguments), r = d[0], a = d[1] + d3_svg_arcOffset; + return [ r * Math.cos(a), r * Math.sin(a) ]; + }; + } + d3.svg.symbol = function() { + var type = d3_svg_symbolType, size = d3_svg_symbolSize; + function symbol(d, i) { + return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); + } + symbol.type = function(x) { + if (!arguments.length) return type; + type = d3_functor(x); + return symbol; + }; + symbol.size = function(x) { + if (!arguments.length) return size; + size = d3_functor(x); + return symbol; + }; + return symbol; + }; + function d3_svg_symbolSize() { + return 64; + } + function d3_svg_symbolType() { + return "circle"; + } + function d3_svg_symbolCircle(size) { + var r = Math.sqrt(size / Ï€); + return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; + } + var d3_svg_symbols = d3.map({ + circle: d3_svg_symbolCircle, + cross: function(size) { + var r = Math.sqrt(size / 5) / 2; + return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; + }, + diamond: function(size) { + var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; + return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; + }, + square: function(size) { + var r = Math.sqrt(size) / 2; + return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; + }, + "triangle-down": function(size) { + var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; + return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; + }, + "triangle-up": function(size) { + var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; + return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; + } + }); + d3.svg.symbolTypes = d3_svg_symbols.keys(); + var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); + function d3_transition(groups, id) { + d3_arraySubclass(groups, d3_transitionPrototype); + groups.id = id; + return groups; + } + var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit = { + ease: d3_ease_cubicInOut, + delay: 0, + duration: 250 + }; + d3_transitionPrototype.call = d3_selectionPrototype.call; + d3_transitionPrototype.empty = d3_selectionPrototype.empty; + d3_transitionPrototype.node = d3_selectionPrototype.node; + d3.transition = function(selection) { + return arguments.length ? d3_transitionInheritId ? selection.transition() : selection : d3_selectionRoot.transition(); + }; + d3.transition.prototype = d3_transitionPrototype; + d3_transitionPrototype.select = function(selector) { + var id = this.id, subgroups = [], subgroup, subnode, node; + if (typeof selector !== "function") selector = d3_selection_selector(selector); + for (var j = -1, m = this.length; ++j < m; ) { + subgroups.push(subgroup = []); + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i))) { + if ("__data__" in node) subnode.__data__ = node.__data__; + d3_transitionNode(subnode, i, id, node.__transition__[id]); + subgroup.push(subnode); + } else { + subgroup.push(null); + } + } + } + return d3_transition(subgroups, id); + }; + d3_transitionPrototype.selectAll = function(selector) { + var id = this.id, subgroups = [], subgroup, subnodes, node, subnode, transition; + if (typeof selector !== "function") selector = d3_selection_selectorAll(selector); + for (var j = -1, m = this.length; ++j < m; ) { + for (var group = this[j], i = -1, n = group.length; ++i < n; ) { + if (node = group[i]) { + transition = node.__transition__[id]; + subnodes = selector.call(node, node.__data__, i); + subgroups.push(subgroup = []); + for (var k = -1, o = subnodes.length; ++k < o; ) { + d3_transitionNode(subnode = subnodes[k], k, id, transition); + subgroup.push(subnode); + } + } + } + } + return d3_transition(subgroups, id); + }; + d3_transitionPrototype.filter = function(filter) { + var subgroups = [], subgroup, group, node; + if (typeof filter !== "function") filter = d3_selection_filter(filter); + for (var j = 0, m = this.length; j < m; j++) { + subgroups.push(subgroup = []); + for (var group = this[j], i = 0, n = group.length; i < n; i++) { + if ((node = group[i]) && filter.call(node, node.__data__, i)) { + subgroup.push(node); + } + } + } + return d3_transition(subgroups, this.id, this.time).ease(this.ease()); + }; + d3_transitionPrototype.tween = function(name, tween) { + var id = this.id; + if (arguments.length < 2) return this.node().__transition__[id].tween.get(name); + return d3_selection_each(this, tween == null ? function(node) { + node.__transition__[id].tween.remove(name); + } : function(node) { + node.__transition__[id].tween.set(name, tween); + }); + }; + function d3_transition_tween(groups, name, value, tween) { + var id = groups.id; + return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { + node.__transition__[id].tween.set(name, tween(value.call(node, node.__data__, i, j))); + } : (value = tween(value), function(node) { + node.__transition__[id].tween.set(name, value); + })); + } + d3_transitionPrototype.attr = function(nameNS, value) { + if (arguments.length < 2) { + for (value in nameNS) this.attr(value, nameNS[value]); + return this; + } + var interpolate = d3_interpolateByName(nameNS), name = d3.ns.qualify(nameNS); + function attrNull() { + this.removeAttribute(name); + } + function attrNullNS() { + this.removeAttributeNS(name.space, name.local); + } + function attrTween(b) { + return b == null ? attrNull : (b += "", function() { + var a = this.getAttribute(name), i; + return a !== b && (i = interpolate(a, b), function(t) { + this.setAttribute(name, i(t)); + }); + }); + } + function attrTweenNS(b) { + return b == null ? attrNullNS : (b += "", function() { + var a = this.getAttributeNS(name.space, name.local), i; + return a !== b && (i = interpolate(a, b), function(t) { + this.setAttributeNS(name.space, name.local, i(t)); + }); + }); + } + return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); + }; + d3_transitionPrototype.attrTween = function(nameNS, tween) { + var name = d3.ns.qualify(nameNS); + function attrTween(d, i) { + var f = tween.call(this, d, i, this.getAttribute(name)); + return f && function(t) { + this.setAttribute(name, f(t)); + }; + } + function attrTweenNS(d, i) { + var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); + return f && function(t) { + this.setAttributeNS(name.space, name.local, f(t)); + }; + } + return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); + }; + d3_transitionPrototype.style = function(name, value, priority) { + var n = arguments.length; + if (n < 3) { + if (typeof name !== "string") { + if (n < 2) value = ""; + for (priority in name) this.style(priority, name[priority], value); + return this; + } + priority = ""; + } + var interpolate = d3_interpolateByName(name); + function styleNull() { + this.style.removeProperty(name); + } + function styleString(b) { + return b == null ? styleNull : (b += "", function() { + var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i; + return a !== b && (i = interpolate(a, b), function(t) { + this.style.setProperty(name, i(t), priority); + }); + }); + } + return d3_transition_tween(this, "style." + name, value, styleString); + }; + d3_transitionPrototype.styleTween = function(name, tween, priority) { + if (arguments.length < 3) priority = ""; + function styleTween(d, i) { + var f = tween.call(this, d, i, d3_window.getComputedStyle(this, null).getPropertyValue(name)); + return f && function(t) { + this.style.setProperty(name, f(t), priority); + }; + } + return this.tween("style." + name, styleTween); + }; + d3_transitionPrototype.text = function(value) { + return d3_transition_tween(this, "text", value, d3_transition_text); + }; + function d3_transition_text(b) { + if (b == null) b = ""; + return function() { + this.textContent = b; + }; + } + d3_transitionPrototype.remove = function() { + return this.each("end.transition", function() { + var p; + if (!this.__transition__ && (p = this.parentNode)) p.removeChild(this); + }); + }; + d3_transitionPrototype.ease = function(value) { + var id = this.id; + if (arguments.length < 1) return this.node().__transition__[id].ease; + if (typeof value !== "function") value = d3.ease.apply(d3, arguments); + return d3_selection_each(this, function(node) { + node.__transition__[id].ease = value; + }); + }; + d3_transitionPrototype.delay = function(value) { + var id = this.id; + return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { + node.__transition__[id].delay = value.call(node, node.__data__, i, j) | 0; + } : (value |= 0, function(node) { + node.__transition__[id].delay = value; + })); + }; + d3_transitionPrototype.duration = function(value) { + var id = this.id; + return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { + node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j) | 0); + } : (value = Math.max(1, value | 0), function(node) { + node.__transition__[id].duration = value; + })); + }; + d3_transitionPrototype.each = function(type, listener) { + var id = this.id; + if (arguments.length < 2) { + var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; + d3_transitionInheritId = id; + d3_selection_each(this, function(node, i, j) { + d3_transitionInherit = node.__transition__[id]; + type.call(node, node.__data__, i, j); + }); + d3_transitionInherit = inherit; + d3_transitionInheritId = inheritId; + } else { + d3_selection_each(this, function(node) { + node.__transition__[id].event.on(type, listener); + }); + } + return this; + }; + d3_transitionPrototype.transition = function() { + var id0 = this.id, id1 = ++d3_transitionId, subgroups = [], subgroup, group, node, transition; + for (var j = 0, m = this.length; j < m; j++) { + subgroups.push(subgroup = []); + for (var group = this[j], i = 0, n = group.length; i < n; i++) { + if (node = group[i]) { + transition = Object.create(node.__transition__[id0]); + transition.delay += transition.duration; + d3_transitionNode(node, i, id1, transition); + } + subgroup.push(node); + } + } + return d3_transition(subgroups, id1); + }; + function d3_transitionNode(node, i, id, inherit) { + var lock = node.__transition__ || (node.__transition__ = { + active: 0, + count: 0 + }), transition = lock[id]; + if (!transition) { + var time = inherit.time; + transition = lock[id] = { + tween: new d3_Map(), + event: d3.dispatch("start", "end"), + time: time, + ease: inherit.ease, + delay: inherit.delay, + duration: inherit.duration + }; + ++lock.count; + d3.timer(function(elapsed) { + var d = node.__data__, ease = transition.ease, event = transition.event, delay = transition.delay, duration = transition.duration, tweened = []; + return delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time), 1; + function start(elapsed) { + if (lock.active > id) return stop(); + lock.active = id; + event.start.call(node, d, i); + transition.tween.forEach(function(key, value) { + if (value = value.call(node, d, i)) { + tweened.push(value); + } + }); + if (!tick(elapsed)) d3.timer(tick, 0, time); + return 1; + } + function tick(elapsed) { + if (lock.active !== id) return stop(); + var t = (elapsed - delay) / duration, e = ease(t), n = tweened.length; + while (n > 0) { + tweened[--n].call(node, e); + } + if (t >= 1) { + stop(); + event.end.call(node, d, i); + return 1; + } + } + function stop() { + if (--lock.count) delete lock[id]; else delete node.__transition__; + return 1; + } + }, 0, time); + return transition; + } + } + d3.svg.axis = function() { + var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, tickMajorSize = 6, tickMinorSize = 6, tickEndSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_, tickSubdivide = 0; + function axis(g) { + g.each(function() { + var g = d3.select(this); + var ticks = tickValues == null ? scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain() : tickValues, tickFormat = tickFormat_ == null ? scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : String : tickFormat_; + var subticks = d3_svg_axisSubdivide(scale, ticks, tickSubdivide), subtick = g.selectAll(".tick.minor").data(subticks, String), subtickEnter = subtick.enter().insert("line", ".tick").attr("class", "tick minor").style("opacity", 1e-6), subtickExit = d3.transition(subtick.exit()).style("opacity", 1e-6).remove(), subtickUpdate = d3.transition(subtick).style("opacity", 1); + var tick = g.selectAll(".tick.major").data(ticks, String), tickEnter = tick.enter().insert("g", "path").attr("class", "tick major").style("opacity", 1e-6), tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(), tickUpdate = d3.transition(tick).style("opacity", 1), tickTransform; + var range = d3_scaleRange(scale), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), + d3.transition(path)); + var scale1 = scale.copy(), scale0 = this.__chart__ || scale1; + this.__chart__ = scale1; + tickEnter.append("line"); + tickEnter.append("text"); + var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"); + switch (orient) { + case "bottom": + { + tickTransform = d3_svg_axisX; + subtickEnter.attr("y2", tickMinorSize); + subtickUpdate.attr("x2", 0).attr("y2", tickMinorSize); + lineEnter.attr("y2", tickMajorSize); + textEnter.attr("y", Math.max(tickMajorSize, 0) + tickPadding); + lineUpdate.attr("x2", 0).attr("y2", tickMajorSize); + textUpdate.attr("x", 0).attr("y", Math.max(tickMajorSize, 0) + tickPadding); + text.attr("dy", ".71em").style("text-anchor", "middle"); + pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize); + break; + } + + case "top": + { + tickTransform = d3_svg_axisX; + subtickEnter.attr("y2", -tickMinorSize); + subtickUpdate.attr("x2", 0).attr("y2", -tickMinorSize); + lineEnter.attr("y2", -tickMajorSize); + textEnter.attr("y", -(Math.max(tickMajorSize, 0) + tickPadding)); + lineUpdate.attr("x2", 0).attr("y2", -tickMajorSize); + textUpdate.attr("x", 0).attr("y", -(Math.max(tickMajorSize, 0) + tickPadding)); + text.attr("dy", "0em").style("text-anchor", "middle"); + pathUpdate.attr("d", "M" + range[0] + "," + -tickEndSize + "V0H" + range[1] + "V" + -tickEndSize); + break; + } + + case "left": + { + tickTransform = d3_svg_axisY; + subtickEnter.attr("x2", -tickMinorSize); + subtickUpdate.attr("x2", -tickMinorSize).attr("y2", 0); + lineEnter.attr("x2", -tickMajorSize); + textEnter.attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)); + lineUpdate.attr("x2", -tickMajorSize).attr("y2", 0); + textUpdate.attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("y", 0); + text.attr("dy", ".32em").style("text-anchor", "end"); + pathUpdate.attr("d", "M" + -tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + -tickEndSize); + break; + } + + case "right": + { + tickTransform = d3_svg_axisY; + subtickEnter.attr("x2", tickMinorSize); + subtickUpdate.attr("x2", tickMinorSize).attr("y2", 0); + lineEnter.attr("x2", tickMajorSize); + textEnter.attr("x", Math.max(tickMajorSize, 0) + tickPadding); + lineUpdate.attr("x2", tickMajorSize).attr("y2", 0); + textUpdate.attr("x", Math.max(tickMajorSize, 0) + tickPadding).attr("y", 0); + text.attr("dy", ".32em").style("text-anchor", "start"); + pathUpdate.attr("d", "M" + tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + tickEndSize); + break; + } + } + if (scale.ticks) { + tickEnter.call(tickTransform, scale0); + tickUpdate.call(tickTransform, scale1); + tickExit.call(tickTransform, scale1); + subtickEnter.call(tickTransform, scale0); + subtickUpdate.call(tickTransform, scale1); + subtickExit.call(tickTransform, scale1); + } else { + var dx = scale1.rangeBand() / 2, x = function(d) { + return scale1(d) + dx; + }; + tickEnter.call(tickTransform, x); + tickUpdate.call(tickTransform, x); + } + }); + } + axis.scale = function(x) { + if (!arguments.length) return scale; + scale = x; + return axis; + }; + axis.orient = function(x) { + if (!arguments.length) return orient; + orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; + return axis; + }; + axis.ticks = function() { + if (!arguments.length) return tickArguments_; + tickArguments_ = arguments; + return axis; + }; + axis.tickValues = function(x) { + if (!arguments.length) return tickValues; + tickValues = x; + return axis; + }; + axis.tickFormat = function(x) { + if (!arguments.length) return tickFormat_; + tickFormat_ = x; + return axis; + }; + axis.tickSize = function(x, y) { + if (!arguments.length) return tickMajorSize; + var n = arguments.length - 1; + tickMajorSize = +x; + tickMinorSize = n > 1 ? +y : tickMajorSize; + tickEndSize = n > 0 ? +arguments[n] : tickMajorSize; + return axis; + }; + axis.tickPadding = function(x) { + if (!arguments.length) return tickPadding; + tickPadding = +x; + return axis; + }; + axis.tickSubdivide = function(x) { + if (!arguments.length) return tickSubdivide; + tickSubdivide = +x; + return axis; + }; + return axis; + }; + var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { + top: 1, + right: 1, + bottom: 1, + left: 1 + }; + function d3_svg_axisX(selection, x) { + selection.attr("transform", function(d) { + return "translate(" + x(d) + ",0)"; + }); + } + function d3_svg_axisY(selection, y) { + selection.attr("transform", function(d) { + return "translate(0," + y(d) + ")"; + }); + } + function d3_svg_axisSubdivide(scale, ticks, m) { + subticks = []; + if (m && ticks.length > 1) { + var extent = d3_scaleExtent(scale.domain()), subticks, i = -1, n = ticks.length, d = (ticks[1] - ticks[0]) / ++m, j, v; + while (++i < n) { + for (j = m; --j > 0; ) { + if ((v = +ticks[i] - j * d) >= extent[0]) { + subticks.push(v); + } + } + } + for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1]; ) { + subticks.push(v); + } + } + return subticks; + } + d3.svg.brush = function() { + var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, resizes = d3_svg_brushResizes[0], extent = [ [ 0, 0 ], [ 0, 0 ] ], extentDomain; + function brush(g) { + g.each(function() { + var g = d3.select(this), bg = g.selectAll(".background").data([ 0 ]), fg = g.selectAll(".extent").data([ 0 ]), tz = g.selectAll(".resize").data(resizes, String), e; + g.style("pointer-events", "all").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); + bg.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); + fg.enter().append("rect").attr("class", "extent").style("cursor", "move"); + tz.enter().append("g").attr("class", function(d) { + return "resize " + d; + }).style("cursor", function(d) { + return d3_svg_brushCursor[d]; + }).append("rect").attr("x", function(d) { + return /[ew]$/.test(d) ? -3 : null; + }).attr("y", function(d) { + return /^[ns]/.test(d) ? -3 : null; + }).attr("width", 6).attr("height", 6).style("visibility", "hidden"); + tz.style("display", brush.empty() ? "none" : null); + tz.exit().remove(); + if (x) { + e = d3_scaleRange(x); + bg.attr("x", e[0]).attr("width", e[1] - e[0]); + redrawX(g); + } + if (y) { + e = d3_scaleRange(y); + bg.attr("y", e[0]).attr("height", e[1] - e[0]); + redrawY(g); + } + redraw(g); + }); + } + function redraw(g) { + g.selectAll(".resize").attr("transform", function(d) { + return "translate(" + extent[+/e$/.test(d)][0] + "," + extent[+/^s/.test(d)][1] + ")"; + }); + } + function redrawX(g) { + g.select(".extent").attr("x", extent[0][0]); + g.selectAll(".extent,.n>rect,.s>rect").attr("width", extent[1][0] - extent[0][0]); + } + function redrawY(g) { + g.select(".extent").attr("y", extent[0][1]); + g.selectAll(".extent,.e>rect,.w>rect").attr("height", extent[1][1] - extent[0][1]); + } + function brushstart() { + var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), center, origin = mouse(), offset; + var w = d3.select(d3_window).on("mousemove.brush", brushmove).on("mouseup.brush", brushend).on("touchmove.brush", brushmove).on("touchend.brush", brushend).on("keydown.brush", keydown).on("keyup.brush", keyup); + if (dragging) { + origin[0] = extent[0][0] - origin[0]; + origin[1] = extent[0][1] - origin[1]; + } else if (resizing) { + var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); + offset = [ extent[1 - ex][0] - origin[0], extent[1 - ey][1] - origin[1] ]; + origin[0] = extent[ex][0]; + origin[1] = extent[ey][1]; + } else if (d3.event.altKey) center = origin.slice(); + g.style("pointer-events", "none").selectAll(".resize").style("display", null); + d3.select("body").style("cursor", eventTarget.style("cursor")); + event_({ + type: "brushstart" + }); + brushmove(); + d3_eventCancel(); + function mouse() { + var touches = d3.event.changedTouches; + return touches ? d3.touches(target, touches)[0] : d3.mouse(target); + } + function keydown() { + if (d3.event.keyCode == 32) { + if (!dragging) { + center = null; + origin[0] -= extent[1][0]; + origin[1] -= extent[1][1]; + dragging = 2; + } + d3_eventCancel(); + } + } + function keyup() { + if (d3.event.keyCode == 32 && dragging == 2) { + origin[0] += extent[1][0]; + origin[1] += extent[1][1]; + dragging = 0; + d3_eventCancel(); + } + } + function brushmove() { + var point = mouse(), moved = false; + if (offset) { + point[0] += offset[0]; + point[1] += offset[1]; + } + if (!dragging) { + if (d3.event.altKey) { + if (!center) center = [ (extent[0][0] + extent[1][0]) / 2, (extent[0][1] + extent[1][1]) / 2 ]; + origin[0] = extent[+(point[0] < center[0])][0]; + origin[1] = extent[+(point[1] < center[1])][1]; + } else center = null; + } + if (resizingX && move1(point, x, 0)) { + redrawX(g); + moved = true; + } + if (resizingY && move1(point, y, 1)) { + redrawY(g); + moved = true; + } + if (moved) { + redraw(g); + event_({ + type: "brush", + mode: dragging ? "move" : "resize" + }); + } + } + function move1(point, scale, i) { + var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], size = extent[1][i] - extent[0][i], min, max; + if (dragging) { + r0 -= position; + r1 -= size + position; + } + min = Math.max(r0, Math.min(r1, point[i])); + if (dragging) { + max = (min += position) + size; + } else { + if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); + if (position < min) { + max = min; + min = position; + } else { + max = position; + } + } + if (extent[0][i] !== min || extent[1][i] !== max) { + extentDomain = null; + extent[0][i] = min; + extent[1][i] = max; + return true; + } + } + function brushend() { + brushmove(); + g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); + d3.select("body").style("cursor", null); + w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); + event_({ + type: "brushend" + }); + d3_eventCancel(); + } + } + brush.x = function(z) { + if (!arguments.length) return x; + x = z; + resizes = d3_svg_brushResizes[!x << 1 | !y]; + return brush; + }; + brush.y = function(z) { + if (!arguments.length) return y; + y = z; + resizes = d3_svg_brushResizes[!x << 1 | !y]; + return brush; + }; + brush.extent = function(z) { + var x0, x1, y0, y1, t; + if (!arguments.length) { + z = extentDomain || extent; + if (x) { + x0 = z[0][0], x1 = z[1][0]; + if (!extentDomain) { + x0 = extent[0][0], x1 = extent[1][0]; + if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); + if (x1 < x0) t = x0, x0 = x1, x1 = t; + } + } + if (y) { + y0 = z[0][1], y1 = z[1][1]; + if (!extentDomain) { + y0 = extent[0][1], y1 = extent[1][1]; + if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); + if (y1 < y0) t = y0, y0 = y1, y1 = t; + } + } + return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; + } + extentDomain = [ [ 0, 0 ], [ 0, 0 ] ]; + if (x) { + x0 = z[0], x1 = z[1]; + if (y) x0 = x0[0], x1 = x1[0]; + extentDomain[0][0] = x0, extentDomain[1][0] = x1; + if (x.invert) x0 = x(x0), x1 = x(x1); + if (x1 < x0) t = x0, x0 = x1, x1 = t; + extent[0][0] = x0 | 0, extent[1][0] = x1 | 0; + } + if (y) { + y0 = z[0], y1 = z[1]; + if (x) y0 = y0[1], y1 = y1[1]; + extentDomain[0][1] = y0, extentDomain[1][1] = y1; + if (y.invert) y0 = y(y0), y1 = y(y1); + if (y1 < y0) t = y0, y0 = y1, y1 = t; + extent[0][1] = y0 | 0, extent[1][1] = y1 | 0; + } + return brush; + }; + brush.clear = function() { + extentDomain = null; + extent[0][0] = extent[0][1] = extent[1][0] = extent[1][1] = 0; + return brush; + }; + brush.empty = function() { + return x && extent[0][0] === extent[1][0] || y && extent[0][1] === extent[1][1]; + }; + return d3.rebind(brush, event, "on"); + }; + var d3_svg_brushCursor = { + n: "ns-resize", + e: "ew-resize", + s: "ns-resize", + w: "ew-resize", + nw: "nwse-resize", + ne: "nesw-resize", + se: "nwse-resize", + sw: "nesw-resize" + }; + var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; + d3.time = {}; + var d3_time = Date, d3_time_daySymbols = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ]; + function d3_time_utc() { + this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); + } + d3_time_utc.prototype = { + getDate: function() { + return this._.getUTCDate(); + }, + getDay: function() { + return this._.getUTCDay(); + }, + getFullYear: function() { + return this._.getUTCFullYear(); + }, + getHours: function() { + return this._.getUTCHours(); + }, + getMilliseconds: function() { + return this._.getUTCMilliseconds(); + }, + getMinutes: function() { + return this._.getUTCMinutes(); + }, + getMonth: function() { + return this._.getUTCMonth(); + }, + getSeconds: function() { + return this._.getUTCSeconds(); + }, + getTime: function() { + return this._.getTime(); + }, + getTimezoneOffset: function() { + return 0; + }, + valueOf: function() { + return this._.valueOf(); + }, + setDate: function() { + d3_time_prototype.setUTCDate.apply(this._, arguments); + }, + setDay: function() { + d3_time_prototype.setUTCDay.apply(this._, arguments); + }, + setFullYear: function() { + d3_time_prototype.setUTCFullYear.apply(this._, arguments); + }, + setHours: function() { + d3_time_prototype.setUTCHours.apply(this._, arguments); + }, + setMilliseconds: function() { + d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); + }, + setMinutes: function() { + d3_time_prototype.setUTCMinutes.apply(this._, arguments); + }, + setMonth: function() { + d3_time_prototype.setUTCMonth.apply(this._, arguments); + }, + setSeconds: function() { + d3_time_prototype.setUTCSeconds.apply(this._, arguments); + }, + setTime: function() { + d3_time_prototype.setTime.apply(this._, arguments); + } + }; + var d3_time_prototype = Date.prototype; + var d3_time_formatDateTime = "%a %b %e %X %Y", d3_time_formatDate = "%m/%d/%Y", d3_time_formatTime = "%H:%M:%S"; + var d3_time_days = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], d3_time_dayAbbreviations = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], d3_time_months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], d3_time_monthAbbreviations = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; + function d3_time_interval(local, step, number) { + function round(date) { + var d0 = local(date), d1 = offset(d0, 1); + return date - d0 < d1 - date ? d0 : d1; + } + function ceil(date) { + step(date = local(new d3_time(date - 1)), 1); + return date; + } + function offset(date, k) { + step(date = new d3_time(+date), k); + return date; + } + function range(t0, t1, dt) { + var time = ceil(t0), times = []; + if (dt > 1) { + while (time < t1) { + if (!(number(time) % dt)) times.push(new Date(+time)); + step(time, 1); + } + } else { + while (time < t1) times.push(new Date(+time)), step(time, 1); + } + return times; + } + function range_utc(t0, t1, dt) { + try { + d3_time = d3_time_utc; + var utc = new d3_time_utc(); + utc._ = t0; + return range(utc, t1, dt); + } finally { + d3_time = Date; + } + } + local.floor = local; + local.round = round; + local.ceil = ceil; + local.offset = offset; + local.range = range; + var utc = local.utc = d3_time_interval_utc(local); + utc.floor = utc; + utc.round = d3_time_interval_utc(round); + utc.ceil = d3_time_interval_utc(ceil); + utc.offset = d3_time_interval_utc(offset); + utc.range = range_utc; + return local; + } + function d3_time_interval_utc(method) { + return function(date, k) { + try { + d3_time = d3_time_utc; + var utc = new d3_time_utc(); + utc._ = date; + return method(utc, k)._; + } finally { + d3_time = Date; + } + }; + } + d3.time.year = d3_time_interval(function(date) { + date = d3.time.day(date); + date.setMonth(0, 1); + return date; + }, function(date, offset) { + date.setFullYear(date.getFullYear() + offset); + }, function(date) { + return date.getFullYear(); + }); + d3.time.years = d3.time.year.range; + d3.time.years.utc = d3.time.year.utc.range; + d3.time.day = d3_time_interval(function(date) { + var day = new d3_time(1970, 0); + day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); + return day; + }, function(date, offset) { + date.setDate(date.getDate() + offset); + }, function(date) { + return date.getDate() - 1; + }); + d3.time.days = d3.time.day.range; + d3.time.days.utc = d3.time.day.utc.range; + d3.time.dayOfYear = function(date) { + var year = d3.time.year(date); + return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); + }; + d3_time_daySymbols.forEach(function(day, i) { + day = day.toLowerCase(); + i = 7 - i; + var interval = d3.time[day] = d3_time_interval(function(date) { + (date = d3.time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); + return date; + }, function(date, offset) { + date.setDate(date.getDate() + Math.floor(offset) * 7); + }, function(date) { + var day = d3.time.year(date).getDay(); + return Math.floor((d3.time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); + }); + d3.time[day + "s"] = interval.range; + d3.time[day + "s"].utc = interval.utc.range; + d3.time[day + "OfYear"] = function(date) { + var day = d3.time.year(date).getDay(); + return Math.floor((d3.time.dayOfYear(date) + (day + i) % 7) / 7); + }; + }); + d3.time.week = d3.time.sunday; + d3.time.weeks = d3.time.sunday.range; + d3.time.weeks.utc = d3.time.sunday.utc.range; + d3.time.weekOfYear = d3.time.sundayOfYear; + d3.time.format = function(template) { + var n = template.length; + function format(date) { + var string = [], i = -1, j = 0, c, p, f; + while (++i < n) { + if (template.charCodeAt(i) === 37) { + string.push(template.substring(j, i)); + if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); + if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); + string.push(c); + j = i + 1; + } + } + string.push(template.substring(j, i)); + return string.join(""); + } + format.parse = function(string) { + var d = { + y: 1900, + m: 0, + d: 1, + H: 0, + M: 0, + S: 0, + L: 0 + }, i = d3_time_parse(d, template, string, 0); + if (i != string.length) return null; + if ("p" in d) d.H = d.H % 12 + d.p * 12; + var date = new d3_time(); + date.setFullYear(d.y, d.m, d.d); + date.setHours(d.H, d.M, d.S, d.L); + return date; + }; + format.toString = function() { + return template; + }; + return format; + }; + function d3_time_parse(date, template, string, j) { + var c, p, i = 0, n = template.length, m = string.length; + while (i < n) { + if (j >= m) return -1; + c = template.charCodeAt(i++); + if (c === 37) { + p = d3_time_parsers[template.charAt(i++)]; + if (!p || (j = p(date, string, j)) < 0) return -1; + } else if (c != string.charCodeAt(j++)) { + return -1; + } + } + return j; + } + function d3_time_formatRe(names) { + return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); + } + function d3_time_formatLookup(names) { + var map = new d3_Map(), i = -1, n = names.length; + while (++i < n) map.set(names[i].toLowerCase(), i); + return map; + } + function d3_time_formatPad(value, fill, width) { + value += ""; + var length = value.length; + return length < width ? new Array(width - length + 1).join(fill) + value : value; + } + var d3_time_dayRe = d3_time_formatRe(d3_time_days), d3_time_dayAbbrevRe = d3_time_formatRe(d3_time_dayAbbreviations), d3_time_monthRe = d3_time_formatRe(d3_time_months), d3_time_monthLookup = d3_time_formatLookup(d3_time_months), d3_time_monthAbbrevRe = d3_time_formatRe(d3_time_monthAbbreviations), d3_time_monthAbbrevLookup = d3_time_formatLookup(d3_time_monthAbbreviations); + var d3_time_formatPads = { + "-": "", + _: " ", + "0": "0" + }; + var d3_time_formats = { + a: function(d) { + return d3_time_dayAbbreviations[d.getDay()]; + }, + A: function(d) { + return d3_time_days[d.getDay()]; + }, + b: function(d) { + return d3_time_monthAbbreviations[d.getMonth()]; + }, + B: function(d) { + return d3_time_months[d.getMonth()]; + }, + c: d3.time.format(d3_time_formatDateTime), + d: function(d, p) { + return d3_time_formatPad(d.getDate(), p, 2); + }, + e: function(d, p) { + return d3_time_formatPad(d.getDate(), p, 2); + }, + H: function(d, p) { + return d3_time_formatPad(d.getHours(), p, 2); + }, + I: function(d, p) { + return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); + }, + j: function(d, p) { + return d3_time_formatPad(1 + d3.time.dayOfYear(d), p, 3); + }, + L: function(d, p) { + return d3_time_formatPad(d.getMilliseconds(), p, 3); + }, + m: function(d, p) { + return d3_time_formatPad(d.getMonth() + 1, p, 2); + }, + M: function(d, p) { + return d3_time_formatPad(d.getMinutes(), p, 2); + }, + p: function(d) { + return d.getHours() >= 12 ? "PM" : "AM"; + }, + S: function(d, p) { + return d3_time_formatPad(d.getSeconds(), p, 2); + }, + U: function(d, p) { + return d3_time_formatPad(d3.time.sundayOfYear(d), p, 2); + }, + w: function(d) { + return d.getDay(); + }, + W: function(d, p) { + return d3_time_formatPad(d3.time.mondayOfYear(d), p, 2); + }, + x: d3.time.format(d3_time_formatDate), + X: d3.time.format(d3_time_formatTime), + y: function(d, p) { + return d3_time_formatPad(d.getFullYear() % 100, p, 2); + }, + Y: function(d, p) { + return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); + }, + Z: d3_time_zone, + "%": function() { + return "%"; + } + }; + var d3_time_parsers = { + a: d3_time_parseWeekdayAbbrev, + A: d3_time_parseWeekday, + b: d3_time_parseMonthAbbrev, + B: d3_time_parseMonth, + c: d3_time_parseLocaleFull, + d: d3_time_parseDay, + e: d3_time_parseDay, + H: d3_time_parseHour24, + I: d3_time_parseHour24, + L: d3_time_parseMilliseconds, + m: d3_time_parseMonthNumber, + M: d3_time_parseMinutes, + p: d3_time_parseAmPm, + S: d3_time_parseSeconds, + x: d3_time_parseLocaleDate, + X: d3_time_parseLocaleTime, + y: d3_time_parseYear, + Y: d3_time_parseFullYear + }; + function d3_time_parseWeekdayAbbrev(date, string, i) { + d3_time_dayAbbrevRe.lastIndex = 0; + var n = d3_time_dayAbbrevRe.exec(string.substring(i)); + return n ? i += n[0].length : -1; + } + function d3_time_parseWeekday(date, string, i) { + d3_time_dayRe.lastIndex = 0; + var n = d3_time_dayRe.exec(string.substring(i)); + return n ? i += n[0].length : -1; + } + function d3_time_parseMonthAbbrev(date, string, i) { + d3_time_monthAbbrevRe.lastIndex = 0; + var n = d3_time_monthAbbrevRe.exec(string.substring(i)); + return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i += n[0].length) : -1; + } + function d3_time_parseMonth(date, string, i) { + d3_time_monthRe.lastIndex = 0; + var n = d3_time_monthRe.exec(string.substring(i)); + return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i += n[0].length) : -1; + } + function d3_time_parseLocaleFull(date, string, i) { + return d3_time_parse(date, d3_time_formats.c.toString(), string, i); + } + function d3_time_parseLocaleDate(date, string, i) { + return d3_time_parse(date, d3_time_formats.x.toString(), string, i); + } + function d3_time_parseLocaleTime(date, string, i) { + return d3_time_parse(date, d3_time_formats.X.toString(), string, i); + } + function d3_time_parseFullYear(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 4)); + return n ? (date.y = +n[0], i += n[0].length) : -1; + } + function d3_time_parseYear(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.y = d3_time_expandYear(+n[0]), i += n[0].length) : -1; + } + function d3_time_expandYear(d) { + return d + (d > 68 ? 1900 : 2e3); + } + function d3_time_parseMonthNumber(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.m = n[0] - 1, i += n[0].length) : -1; + } + function d3_time_parseDay(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.d = +n[0], i += n[0].length) : -1; + } + function d3_time_parseHour24(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.H = +n[0], i += n[0].length) : -1; + } + function d3_time_parseMinutes(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.M = +n[0], i += n[0].length) : -1; + } + function d3_time_parseSeconds(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 2)); + return n ? (date.S = +n[0], i += n[0].length) : -1; + } + function d3_time_parseMilliseconds(date, string, i) { + d3_time_numberRe.lastIndex = 0; + var n = d3_time_numberRe.exec(string.substring(i, i + 3)); + return n ? (date.L = +n[0], i += n[0].length) : -1; + } + var d3_time_numberRe = /^\s*\d+/; + function d3_time_parseAmPm(date, string, i) { + var n = d3_time_amPmLookup.get(string.substring(i, i += 2).toLowerCase()); + return n == null ? -1 : (date.p = n, i); + } + var d3_time_amPmLookup = d3.map({ + am: 0, + pm: 1 + }); + function d3_time_zone(d) { + var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(Math.abs(z) / 60), zm = Math.abs(z) % 60; + return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); + } + d3.time.format.utc = function(template) { + var local = d3.time.format(template); + function format(date) { + try { + d3_time = d3_time_utc; + var utc = new d3_time(); + utc._ = date; + return local(utc); + } finally { + d3_time = Date; + } + } + format.parse = function(string) { + try { + d3_time = d3_time_utc; + var date = local.parse(string); + return date && date._; + } finally { + d3_time = Date; + } + }; + format.toString = local.toString; + return format; + }; + var d3_time_formatIso = d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ"); + d3.time.format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; + function d3_time_formatIsoNative(date) { + return date.toISOString(); + } + d3_time_formatIsoNative.parse = function(string) { + var date = new Date(string); + return isNaN(date) ? null : date; + }; + d3_time_formatIsoNative.toString = d3_time_formatIso.toString; + d3.time.second = d3_time_interval(function(date) { + return new d3_time(Math.floor(date / 1e3) * 1e3); + }, function(date, offset) { + date.setTime(date.getTime() + Math.floor(offset) * 1e3); + }, function(date) { + return date.getSeconds(); + }); + d3.time.seconds = d3.time.second.range; + d3.time.seconds.utc = d3.time.second.utc.range; + d3.time.minute = d3_time_interval(function(date) { + return new d3_time(Math.floor(date / 6e4) * 6e4); + }, function(date, offset) { + date.setTime(date.getTime() + Math.floor(offset) * 6e4); + }, function(date) { + return date.getMinutes(); + }); + d3.time.minutes = d3.time.minute.range; + d3.time.minutes.utc = d3.time.minute.utc.range; + d3.time.hour = d3_time_interval(function(date) { + var timezone = date.getTimezoneOffset() / 60; + return new d3_time((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); + }, function(date, offset) { + date.setTime(date.getTime() + Math.floor(offset) * 36e5); + }, function(date) { + return date.getHours(); + }); + d3.time.hours = d3.time.hour.range; + d3.time.hours.utc = d3.time.hour.utc.range; + d3.time.month = d3_time_interval(function(date) { + date = d3.time.day(date); + date.setDate(1); + return date; + }, function(date, offset) { + date.setMonth(date.getMonth() + offset); + }, function(date) { + return date.getMonth(); + }); + d3.time.months = d3.time.month.range; + d3.time.months.utc = d3.time.month.utc.range; + function d3_time_scale(linear, methods, format) { + function scale(x) { + return linear(x); + } + scale.invert = function(x) { + return d3_time_scaleDate(linear.invert(x)); + }; + scale.domain = function(x) { + if (!arguments.length) return linear.domain().map(d3_time_scaleDate); + linear.domain(x); + return scale; + }; + scale.nice = function(m) { + return scale.domain(d3_scale_nice(scale.domain(), function() { + return m; + })); + }; + scale.ticks = function(m, k) { + var extent = d3_scaleExtent(scale.domain()); + if (typeof m !== "function") { + var span = extent[1] - extent[0], target = span / m, i = d3.bisect(d3_time_scaleSteps, target); + if (i == d3_time_scaleSteps.length) return methods.year(extent, m); + if (!i) return linear.ticks(m).map(d3_time_scaleDate); + if (Math.log(target / d3_time_scaleSteps[i - 1]) < Math.log(d3_time_scaleSteps[i] / target)) --i; + m = methods[i]; + k = m[1]; + m = m[0].range; + } + return m(extent[0], new Date(+extent[1] + 1), k); + }; + scale.tickFormat = function() { + return format; + }; + scale.copy = function() { + return d3_time_scale(linear.copy(), methods, format); + }; + return d3_scale_linearRebind(scale, linear); + } + function d3_time_scaleDate(t) { + return new Date(t); + } + function d3_time_scaleFormat(formats) { + return function(date) { + var i = formats.length - 1, f = formats[i]; + while (!f[1](date)) f = formats[--i]; + return f[0](date); + }; + } + function d3_time_scaleSetYear(y) { + var d = new Date(y, 0, 1); + d.setFullYear(y); + return d; + } + function d3_time_scaleGetYear(d) { + var y = d.getFullYear(), d0 = d3_time_scaleSetYear(y), d1 = d3_time_scaleSetYear(y + 1); + return y + (d - d0) / (d1 - d0); + } + var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; + var d3_time_scaleLocalMethods = [ [ d3.time.second, 1 ], [ d3.time.second, 5 ], [ d3.time.second, 15 ], [ d3.time.second, 30 ], [ d3.time.minute, 1 ], [ d3.time.minute, 5 ], [ d3.time.minute, 15 ], [ d3.time.minute, 30 ], [ d3.time.hour, 1 ], [ d3.time.hour, 3 ], [ d3.time.hour, 6 ], [ d3.time.hour, 12 ], [ d3.time.day, 1 ], [ d3.time.day, 2 ], [ d3.time.week, 1 ], [ d3.time.month, 1 ], [ d3.time.month, 3 ], [ d3.time.year, 1 ] ]; + var d3_time_scaleLocalFormats = [ [ d3.time.format("%Y"), d3_true ], [ d3.time.format("%B"), function(d) { + return d.getMonth(); + } ], [ d3.time.format("%b %d"), function(d) { + return d.getDate() != 1; + } ], [ d3.time.format("%a %d"), function(d) { + return d.getDay() && d.getDate() != 1; + } ], [ d3.time.format("%I %p"), function(d) { + return d.getHours(); + } ], [ d3.time.format("%I:%M"), function(d) { + return d.getMinutes(); + } ], [ d3.time.format(":%S"), function(d) { + return d.getSeconds(); + } ], [ d3.time.format(".%L"), function(d) { + return d.getMilliseconds(); + } ] ]; + var d3_time_scaleLinear = d3.scale.linear(), d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats); + d3_time_scaleLocalMethods.year = function(extent, m) { + return d3_time_scaleLinear.domain(extent.map(d3_time_scaleGetYear)).ticks(m).map(d3_time_scaleSetYear); + }; + d3.time.scale = function() { + return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); + }; + var d3_time_scaleUTCMethods = d3_time_scaleLocalMethods.map(function(m) { + return [ m[0].utc, m[1] ]; + }); + var d3_time_scaleUTCFormats = [ [ d3.time.format.utc("%Y"), d3_true ], [ d3.time.format.utc("%B"), function(d) { + return d.getUTCMonth(); + } ], [ d3.time.format.utc("%b %d"), function(d) { + return d.getUTCDate() != 1; + } ], [ d3.time.format.utc("%a %d"), function(d) { + return d.getUTCDay() && d.getUTCDate() != 1; + } ], [ d3.time.format.utc("%I %p"), function(d) { + return d.getUTCHours(); + } ], [ d3.time.format.utc("%I:%M"), function(d) { + return d.getUTCMinutes(); + } ], [ d3.time.format.utc(":%S"), function(d) { + return d.getUTCSeconds(); + } ], [ d3.time.format.utc(".%L"), function(d) { + return d.getUTCMilliseconds(); + } ] ]; + var d3_time_scaleUTCFormat = d3_time_scaleFormat(d3_time_scaleUTCFormats); + function d3_time_scaleUTCSetYear(y) { + var d = new Date(Date.UTC(y, 0, 1)); + d.setUTCFullYear(y); + return d; + } + function d3_time_scaleUTCGetYear(d) { + var y = d.getUTCFullYear(), d0 = d3_time_scaleUTCSetYear(y), d1 = d3_time_scaleUTCSetYear(y + 1); + return y + (d - d0) / (d1 - d0); + } + d3_time_scaleUTCMethods.year = function(extent, m) { + return d3_time_scaleLinear.domain(extent.map(d3_time_scaleUTCGetYear)).ticks(m).map(d3_time_scaleUTCSetYear); + }; + d3.time.scale.utc = function() { + return d3_time_scale(d3.scale.linear(), d3_time_scaleUTCMethods, d3_time_scaleUTCFormat); + }; + d3.text = function() { + return d3.xhr.apply(d3, arguments).response(d3_text); + }; + function d3_text(request) { + return request.responseText; + } + d3.json = function(url, callback) { + return d3.xhr(url, "application/json", callback).response(d3_json); + }; + function d3_json(request) { + return JSON.parse(request.responseText); + } + d3.html = function(url, callback) { + return d3.xhr(url, "text/html", callback).response(d3_html); + }; + function d3_html(request) { + var range = d3_document.createRange(); + range.selectNode(d3_document.body); + return range.createContextualFragment(request.responseText); + } + d3.xml = function() { + return d3.xhr.apply(d3, arguments).response(d3_xml); + }; + function d3_xml(request) { + return request.responseXML; + } + return d3; +}(); \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/dir/templates/replica_status.html b/java/servers/src/org/xtreemfs/dir/templates/replica_status.html new file mode 100644 index 0000000..d0c3a74 --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/templates/replica_status.html @@ -0,0 +1,383 @@ + + + + + + + Server Status + + + + + + + + + + + +
    +
    + + diff --git a/java/servers/src/org/xtreemfs/dir/templates/status.html b/java/servers/src/org/xtreemfs/dir/templates/status.html new file mode 100644 index 0000000..df6c47e --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/templates/status.html @@ -0,0 +1,138 @@ + + + XtreemFS Directory Service + + + + +

    DIR

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Version +
    XtreemFSDIR
    RPC Interface
    Database
    + Configuration +
    TCP port
    Debug Level
    + Load +
    # client connections
    # pending requests
    + Transfer +
    # requests processed
    + VM Info / Memory +
    Buffer Pool stats
    + Time +
    global XtreemFS time
    + Detailed Status +
    + Replica Status
    + Vivaldi Visualization
    + BabuDB state
    + Full stack trace (all threads) +
     
    + Database Dump +
    + + diff --git a/java/servers/src/org/xtreemfs/dir/templates/vivaldi.html b/java/servers/src/org/xtreemfs/dir/templates/vivaldi.html new file mode 100644 index 0000000..5e4c7ec --- /dev/null +++ b/java/servers/src/org/xtreemfs/dir/templates/vivaldi.html @@ -0,0 +1,540 @@ + + + + + + + + Vivaldi Status + + + + + +

    XtreemFS Logo VIVALDI

    +
    + + + +
    +
    +
    + Usage:
    + - move the mouse over a node to get information
    + - left click and drag to measure distance +
    + + diff --git a/java/servers/src/org/xtreemfs/mrc/ErrorRecord.java b/java/servers/src/org/xtreemfs/mrc/ErrorRecord.java new file mode 100644 index 0000000..558f68d --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/ErrorRecord.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.util.OutputUtils; + +/** + * Encapsuls all types of errors. + */ +public final class ErrorRecord { + + /** + * error type + */ + private final ErrorType type; + + /** + * error code (as defined in the protocol) + */ + private final POSIXErrno errno; + + /** + * an error message, can include a stack trace + */ + private final String message; + + /** + * the throwable thrown in the service that caused the error + */ + private final Throwable throwable; + + public ErrorRecord(ErrorType type, POSIXErrno errno, String message) { + this(type, errno, message, null); + } + + public ErrorRecord(ErrorType type, POSIXErrno errno, String message, Throwable throwable) { + this.type = type; + this.errno = errno; + this.message = message; + this.throwable = throwable; + } + + public POSIXErrno getErrorCode() { + return errno; + } + + public String getErrorMessage() { + return message; + } + + public ErrorType getErrorType() { + return type; + } + + public Throwable getThrowable() { + return throwable; + } + + public String getStackTrace() { + return OutputUtils.stackTraceToString(throwable); + } + + public String toString() { + String stackTrace = OutputUtils.stackTraceToString(throwable); + return this.type + "." + this.errno + ":" + this.message + + (stackTrace == null ? "" : ", caused by: " + stackTrace); + } + + public String toJSON() { + return "{ \"errno\": " + this.errno + ", \"errorMessage\" : \"" + + (this.message.replace("\"", "\\\"")) + "\" }"; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/MRC.java b/java/servers/src/org/xtreemfs/mrc/MRC.java new file mode 100644 index 0000000..e13560d --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/MRC.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + +import java.io.IOException; +import org.xtreemfs.babudb.config.BabuDBConfig; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * + * @author bjko + */ +public class MRC { + + private MRCRequestDispatcher rc; + + /** + * @param args + * the command line arguments + */ + public MRC(MRCConfig config, BabuDBConfig dbConfig) { + + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, (Object) null, "JAVA_HOME=%s", System + .getProperty("java.home")); + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, (Object) null, "UUID: %s", config.getUUID() + .toString()); + } + + try { + rc = new MRCRequestDispatcher(config, dbConfig); + rc.startup(); + + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + try { + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, + "received shutdown signal!"); + rc.shutdown(); + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, + "MRC shutdown complete"); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + }); + + } catch (Exception ex) { + + Logging.logMessage(Logging.LEVEL_CRIT, null, + "MRC could not start up due to an exception. Aborted."); + Logging.logError(Logging.LEVEL_CRIT, null, ex); + + if (rc != null) + try { + rc.shutdown(); + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_ERROR, config.getUUID(), "could not shutdown MRC: "); + Logging.logError(Logging.LEVEL_ERROR, config.getUUID(), e); + } + } + + } + + /** + * Main routine + * + * @param args + * the command line arguments + */ + public static void main(String[] args) throws Exception { + + Thread.currentThread().setName("MRC"); + + String configFileName = "etc/xos/xtreemfs/mrcconfig.test"; + + configFileName = (args.length == 1) ? args[0] : configFileName; + + MRCConfig config = new MRCConfig(configFileName); + + config.setDefaults(); + + config.checkConfig(); + + BabuDBConfig dbsConfig = null; + try { + dbsConfig = new BabuDBConfig(configFileName); + } catch (IOException ex) { + ex.printStackTrace(); + return; + } + + Logging.start(config.getDebugLevel(), config.getDebugCategories()); + + new MRC(config, dbsConfig); + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/MRCConfig.java b/java/servers/src/org/xtreemfs/mrc/MRCConfig.java new file mode 100644 index 0000000..84be5df --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/MRCConfig.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Properties; + +import org.xtreemfs.common.config.ServiceConfig; +import org.xtreemfs.mrc.stages.XLocSetCoordinator; + +/** + * + * @author bjko + */ +public class MRCConfig extends ServiceConfig { + /* + * @formatter:off + */ + final Parameter[] mrcParameter = { + Parameter.DEBUG_LEVEL, + Parameter.DEBUG_CATEGORIES, + Parameter.PORT, + Parameter.HTTP_PORT, + Parameter.LISTEN_ADDRESS, + Parameter.HOSTNAME, + Parameter.OSD_CHECK_INTERVAL, + Parameter.DIRECTORY_SERVICE, + Parameter.NOATIME, + Parameter.LOCAL_CLOCK_RENEW, + Parameter.REMOTE_TIME_SYNC, + Parameter.USE_SSL, + Parameter.SSL_PROTOCOL_STRING, + Parameter.SERVICE_CREDS_FILE, + Parameter.SERVICE_CREDS_PASSPHRASE, + Parameter.SERVICE_CREDS_CONTAINER, + Parameter.TRUSTED_CERTS_FILE, + Parameter.TRUSTED_CERTS_CONTAINER, + Parameter.TRUSTED_CERTS_PASSPHRASE, + Parameter.TRUST_MANAGER, + Parameter.USE_GRID_SSL_MODE, + Parameter.UUID, + Parameter.WAIT_FOR_DIR, + Parameter.GEO_COORDINATES, + Parameter.AUTHENTICATION_PROVIDER, + Parameter.POLICY_DIR, + Parameter.CAPABILITY_SECRET, + Parameter.CAPABILITY_TIMEOUT, + Parameter.ADMIN_PASSWORD, + Parameter.RENEW_TIMED_OUT_CAPS, + Parameter.USE_SNMP, + Parameter.SNMP_ADDRESS, + Parameter.SNMP_PORT, + Parameter.SNMP_ACL, + Parameter.FAILOVER_MAX_RETRIES, + Parameter.FAILOVER_WAIT, + Parameter.USE_RENEWAL_SIGNAL, + Parameter.USE_MULTIHOMING, + Parameter.FLEASE_LEASE_TIMEOUT_MS + }; + /* + * @formatter:on + */ + + /** Creates a new instance of MRCConfig */ + public MRCConfig(String filename) throws IOException { + super(filename); + read(); + } + + public MRCConfig(Properties prop) throws IOException { + super(prop); + read(); + } + + public MRCConfig(HashMap hm) { + super(hm); + } + + public void read() throws IOException { + + for (Parameter parm : mrcParameter) { + parameter.put(parm, readParameter(parm)); + } + } + + public int getOsdCheckInterval() { + return (Integer) parameter.get(Parameter.OSD_CHECK_INTERVAL); + } + + public boolean isNoAtime() { + return (Boolean) parameter.get(Parameter.NOATIME); + } + + public int getLocalClockRenew() { + return (Integer) parameter.get(Parameter.LOCAL_CLOCK_RENEW); + } + + public int getRemoteTimeSync() { + return (Integer) parameter.get(Parameter.REMOTE_TIME_SYNC); + } + + public String getAuthenticationProvider() { + return (String) parameter.get(Parameter.AUTHENTICATION_PROVIDER); + } + + public String getCapabilitySecret() { + return (String) parameter.get(Parameter.CAPABILITY_SECRET); + } + + public int getCapabilityTimeout() { + return (Integer) parameter.get(Parameter.CAPABILITY_TIMEOUT); + } + + /** + * @return the renewTimedOutCaps + */ + public boolean isRenewTimedOutCaps() { + return (Boolean) parameter.get(Parameter.RENEW_TIMED_OUT_CAPS); + + } + + /** + * Set default values according to the value in {@link Parameter} for all configuration parameter which + * are null. + */ + public void setDefaults() { + super.setDefaults(mrcParameter); + } + + /** + * Check if the configuration contain all necessary values to start the service + */ + public void checkConfig() { + super.checkConfig(mrcParameter); + checkMultihomingConfiguration(); + } + + /** + * The flease lease timeout is needed for the {@link XLocSetCoordinator}. + * + * @return the fleaseLeaseToMS + */ + public int getFleaseLeaseToMS() { + return (Integer) parameter.get(Parameter.FLEASE_LEASE_TIMEOUT_MS); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/MRCException.java b/java/servers/src/org/xtreemfs/mrc/MRCException.java new file mode 100644 index 0000000..43fec0d --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/MRCException.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + +public class MRCException extends Exception { + + public MRCException(String message, Exception cause) { + super(message, cause); + } + + public MRCException(String message) { + super(message); + } + + public MRCException(Exception cause) { + super(cause); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/MRCPolicyContainer.java b/java/servers/src/org/xtreemfs/mrc/MRCPolicyContainer.java new file mode 100644 index 0000000..873b153 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/MRCPolicyContainer.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + +import java.io.IOException; + +import org.xtreemfs.common.auth.AuthenticationProvider; +import org.xtreemfs.common.config.PolicyClassLoader; +import org.xtreemfs.common.config.PolicyContainer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.ac.FileAccessPolicy; +import org.xtreemfs.mrc.ac.POSIXFileAccessPolicy; +import org.xtreemfs.mrc.ac.VolumeACLFileAccessPolicy; +import org.xtreemfs.mrc.ac.YesToAnyoneFileAccessPolicy; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.osdselection.FilterDefaultPolicy; +import org.xtreemfs.mrc.osdselection.FilterFQDNPolicy; +import org.xtreemfs.mrc.osdselection.FilterUUIDPolicy; +import org.xtreemfs.mrc.osdselection.GroupDCMapPolicy; +import org.xtreemfs.mrc.osdselection.GroupFQDNPolicy; +import org.xtreemfs.mrc.osdselection.OSDSelectionPolicy; +import org.xtreemfs.mrc.osdselection.SortDCMapPolicy; +import org.xtreemfs.mrc.osdselection.SortFQDNPolicy; +import org.xtreemfs.mrc.osdselection.SortHostRoundRobinPolicy; +import org.xtreemfs.mrc.osdselection.SortRandomPolicy; +import org.xtreemfs.mrc.osdselection.SortReversePolicy; +import org.xtreemfs.mrc.osdselection.SortUUIDPolicy; +import org.xtreemfs.mrc.osdselection.SortVivaldiPolicy; + +public class MRCPolicyContainer extends PolicyContainer { + + private static final String[] POLICY_INTERFACES = { FileAccessPolicy.class.getName(), + OSDSelectionPolicy.class.getName() }; + + private static final String[] BUILT_IN_POLICIES = { POSIXFileAccessPolicy.class.getName(), + VolumeACLFileAccessPolicy.class.getName(), YesToAnyoneFileAccessPolicy.class.getName(), + FilterDefaultPolicy.class.getName(), FilterFQDNPolicy.class.getName(), FilterUUIDPolicy.class.getName(), + GroupDCMapPolicy.class.getName(), GroupFQDNPolicy.class.getName(), SortDCMapPolicy.class.getName(), + SortFQDNPolicy.class.getName(), SortRandomPolicy.class.getName(), SortVivaldiPolicy.class.getName(), + SortUUIDPolicy.class.getName(), SortReversePolicy.class.getName(), SortHostRoundRobinPolicy.class.getName() }; + + private final MRCConfig config; + + public MRCPolicyContainer(MRCConfig config) throws IOException { + super(config, new PolicyClassLoader(config.getPolicyDir(), POLICY_INTERFACES, BUILT_IN_POLICIES)); + this.config = config; + } + + public AuthenticationProvider getAuthenticationProvider() throws InstantiationException, + IllegalAccessException, ClassNotFoundException { + + String authPolicy = config.getAuthenticationProvider(); + + // first, check whether a built-in policy exists with the given name + try { + return (AuthenticationProvider) Class.forName(authPolicy).newInstance(); + } catch (Exception exc) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "no built-in policy '%s' exists, searching for plug-in policies...", config + .getAuthenticationProvider()); + } + + // if no built-in policy could be found, check for plug-in policy + // directory + + // if the class file could be found, load it + Class cls = policyClassLoader.loadClass(authPolicy); + + return (AuthenticationProvider) cls.newInstance(); + } + + public FileAccessPolicy getFileAccessPolicy(short id, VolumeManager volMan) throws Exception { + + try { + // load the class + Class policyClass = policyClassLoader.loadClass(id, FileAccessPolicy.class); + + if (policyClass == null) + throw new MRCException("policy not found"); + + // check whether a default constructor exists; if so, invoke the + // default + // constructor + try { + return (FileAccessPolicy) policyClass.newInstance(); + } catch (InstantiationException exc) { + // ignore + } + + // otherwise, check whether a constructor exists that needs the + // slice + // manager; if so, invoke it + try { + return (FileAccessPolicy) policyClass.getConstructor(new Class[] { VolumeManager.class }) + .newInstance(volMan); + } catch (InstantiationException exc) { + // ignore + } + + // otherwise, throw an exception indicating that no suitable + // constructor + // was found + throw new InstantiationException("policy " + policyClass + + " does not have a suitable constructor"); + + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "could not load FileAccessPolicy with ID %d", id); + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, OutputUtils.stackTraceToString(exc)); + throw exc; + } + + } + + public OSDSelectionPolicy getOSDSelectionPolicy(short id) throws Exception { + + try { + Class policyClass = policyClassLoader.loadClass(id, OSDSelectionPolicy.class); + if (policyClass == null) + throw new MRCException("policy not found"); + return (OSDSelectionPolicy) policyClass.newInstance(); + + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "could not load OSDSelectionPolicy with ID %d", id); + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, OutputUtils.stackTraceToString(exc)); + throw exc; + } + } + + // public static void main(String[] args) throws Exception { + // + // Logging.start(Logging.LEVEL_DEBUG); + // + // PolicyClassLoader loader = new PolicyClassLoader("/tmp/policies"); + // loader.init(); + // System.out.println(loader.loadClass(3, FileAccessPolicy.class)); + // } +} diff --git a/java/servers/src/org/xtreemfs/mrc/MRCRequest.java b/java/servers/src/org/xtreemfs/mrc/MRCRequest.java new file mode 100644 index 0000000..a503b61 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/MRCRequest.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + +import java.io.IOException; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; + +import com.google.protobuf.GeneratedMessage; +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class MRCRequest { + + private final RPCServerRequest rpcRequest; + + private Message requestArgs; + + private GeneratedMessage response; + + private ErrorRecord error; + + private RequestDetails details; + + public MRCRequest() { + this(null); + } + + public MRCRequest(RPCServerRequest rpcRequest) { + this.rpcRequest = rpcRequest; + details = new RequestDetails(); + } + + public RPCServerRequest getRPCRequest() { + return rpcRequest; + } + + public ErrorRecord getError() { + return error; + } + + public void deserializeMessage(Message message) throws IOException { + final ReusableBuffer payload = rpcRequest.getMessage(); + requestArgs = message.newBuilderForType().mergeFrom(new ReusableBufferInputStream(payload)).build(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "parsed request: %s", requestArgs.toString()); + } + } + + public void setError(ErrorType type, POSIXErrno errno, String message, Throwable th) { + this.error = new ErrorRecord(type, errno, message, th); + } + + public void setError(ErrorType type, String message, Throwable th) { + this.error = new ErrorRecord(type, POSIXErrno.POSIX_ERROR_NONE, message, th); + } + + public void setError(ErrorType type, POSIXErrno errno, String message) { + this.error = new ErrorRecord(type, errno, message); + } + + public void setError(ErrorType type, String message) { + this.error = new ErrorRecord(type, POSIXErrno.POSIX_ERROR_NONE, message); + } + + public void setError(ErrorRecord error) { + this.error = error; + } + + public GeneratedMessage getResponse() { + return response; + } + + public void setResponse(GeneratedMessage response) { + this.response = response; + } + + public Message getRequestArgs() { + return requestArgs; + } + + public void setRequestArgs(Message requestArgs) { + this.requestArgs = requestArgs; + } + + public RequestDetails getDetails() { + return details; + } + + public void setDetails(RequestDetails details) { + this.details = details; + } + + public String toString() { + + if (rpcRequest == null) + return null; + + return rpcRequest.toString(); + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/MRCRequestDispatcher.java b/java/servers/src/org/xtreemfs/mrc/MRCRequestDispatcher.java new file mode 100644 index 0000000..499b716 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/MRCRequestDispatcher.java @@ -0,0 +1,952 @@ +/* + * Copyright (c) 2008 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.lang.management.OperatingSystemMXBean; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.xtreemfs.babudb.config.BabuDBConfig; +import org.xtreemfs.common.HeartbeatThread; +import org.xtreemfs.common.HeartbeatThread.ServiceDataGenerator; +import org.xtreemfs.common.auth.AuthenticationProvider; +import org.xtreemfs.common.config.RemoteConfigHelper; +import org.xtreemfs.common.config.ServiceConfig; +import org.xtreemfs.common.monitoring.StatusMonitor; +import org.xtreemfs.common.statusserver.BabuDBStatusPage; +import org.xtreemfs.common.statusserver.PrintStackTrace; +import org.xtreemfs.common.statusserver.StatusServer; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.dir.discovery.DiscoveryUtils; +import org.xtreemfs.foundation.CrashReporter; +import org.xtreemfs.foundation.LifeCycleListener; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.TimeSync.ExtSyncSource; +import org.xtreemfs.foundation.VersionManagement; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.server.RPCNIOSocketServer; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequestListener; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.StatusPage.Vars; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.DBAccessResultListener; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.database.babudb.BabuDBVolumeManager; +import org.xtreemfs.mrc.metadata.StripingPolicy; +import org.xtreemfs.mrc.osdselection.OSDStatusManager; +import org.xtreemfs.mrc.stages.OnCloseReplicationThread; +import org.xtreemfs.mrc.stages.ProcessingStage; +import org.xtreemfs.mrc.stages.XLocSetCoordinator; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceConstants; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * + * @author bjko + */ +public class MRCRequestDispatcher implements RPCServerRequestListener, LifeCycleListener, + DBAccessResultListener { + + private static final int RPC_TIMEOUT = 15000; + + private static final int CONNECTION_TIMEOUT = 5 * 60 * 1000; + + private final RPCNIOSocketServer serverStage; + + private final RPCNIOSocketClient clientStage; + + private final DIRClient dirClient; + + private final ProcessingStage procStage; + + private final MRCStatusManager mrcMonitor; + + private final OSDStatusManager osdMonitor; + + private final MRCPolicyContainer policyContainer; + + private final AuthenticationProvider authProvider; + + private final MRCConfig config; + + private final HeartbeatThread heartbeatThread; + + private final OnCloseReplicationThread onCloseReplicationThread; + + private final VolumeManager volumeManager; + + private final FileAccessManager fileAccessManager; + + private final StatusServer statusServer; + + private final OSDServiceClient osdClient; + + private final boolean replicated; + + private List statusListener; + + private final XLocSetCoordinator xLocSetCoordinator; + + private final long initTimeMS; + + public MRCRequestDispatcher(final MRCConfig config, final BabuDBConfig dbConfig) throws Exception { + initTimeMS = System.currentTimeMillis(); + + Logging.logMessage(Logging.LEVEL_INFO, this, "XtreemFS Metadata Service version " + + VersionManagement.RELEASE_VERSION); + + this.config = config; + + if (this.config.getDirectoryService().getHostName().equals(DiscoveryUtils.AUTODISCOVER_HOSTNAME)) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "trying to discover local XtreemFS DIR service..."); + DirService dir = DiscoveryUtils.discoverDir(10); + if (dir == null) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this, + "CANNOT FIND XtreemFS DIR service via discovery broadcasts... no response"); + throw new IOException("no DIR service found via discovery broadcast"); + } + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "found XtreemFS DIR service at " + dir.getAddress() + ":" + dir.getPort()); + config.setDirectoryService(new InetSocketAddress(dir.getAddress(), dir.getPort())); + } + + if (config.isInitializable()) { + try { + ServiceConfig remoteConfig = RemoteConfigHelper.getConfigurationFromDIR(config); + config.mergeConfig(remoteConfig); + // TODO(mberlin): Also add support for remote BabuDB configurations. + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_WARN, this, + "Couldn't fetch configuration from DIR. Reason: " + e.getMessage()); + Logging.logError(Logging.LEVEL_DEBUG, this, e); + } + } + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, this, "use SSL=%b", config.isUsingSSL()); + + policyContainer = new MRCPolicyContainer(config); + + if (Logging.isInfo() && config.isUsingSSL() && policyContainer.getTrustManager() != null) + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, this, "using custom trust manager '%s'", + policyContainer.getTrustManager().getClass().getName()); + + SSLOptions sslOptions = config.isUsingSSL() ? new SSLOptions(new FileInputStream(config.getServiceCredsFile()), + config.getServiceCredsPassphrase(), config.getServiceCredsContainer(), new FileInputStream( + config.getTrustedCertsFile()), config.getTrustedCertsPassphrase(), + config.getTrustedCertsContainer(), false, config.isGRIDSSLmode(), config.getSSLProtocolString(), + policyContainer.getTrustManager()) + : null; + + InetSocketAddress bindPoint = config.getAddress() != null ? new InetSocketAddress(config.getAddress(), 0) + : null; + if (Logging.isInfo() && bindPoint != null) + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, this, + "outgoing server connections will be bound to '%s'", config.getAddress()); + + clientStage = new RPCNIOSocketClient(sslOptions, RPC_TIMEOUT, CONNECTION_TIMEOUT, -1, -1, bindPoint, + "MRCRequestDispatcher"); + clientStage.setLifeCycleListener(this); + + serverStage = new RPCNIOSocketServer(config.getPort(), config.getAddress(), this, sslOptions); + serverStage.setLifeCycleListener(this); + + DIRServiceClient dirRpcClient = new DIRServiceClient(clientStage, config.getDirectoryService()); + dirClient = new DIRClient(dirRpcClient, config.getDirectoryServices(), config.getFailoverMaxRetries(), + config.getFailoverWait()); + osdClient = new OSDServiceClient(clientStage, null); + TimeSync.initialize(dirClient, config.getRemoteTimeSync(), config.getLocalClockRenew()); + + authProvider = policyContainer.getAuthenticationProvider(); + authProvider.initialize(config.isUsingSSL()); + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, this, "using authentication provider '%s'", + authProvider.getClass().getName()); + + osdMonitor = new OSDStatusManager(this); + osdMonitor.setLifeCycleListener(this); + + xLocSetCoordinator = new XLocSetCoordinator(this); + xLocSetCoordinator.setLifeCycleListener(this); + + procStage = new ProcessingStage(this); + + volumeManager = new BabuDBVolumeManager(this, dbConfig); + fileAccessManager = new FileAccessManager(volumeManager, policyContainer); + + statusListener = new ArrayList(); + if (config.isUsingSnmp()) { + statusListener.add(new StatusMonitor(this, config.getSnmpAddress(), config.getSnmpPort(), config + .getSnmpACLFile())); + notifyConfigurationChange(); + } + + // initialize flag that indicates whether the service is replicated + replicated = dbConfig.getPlugins().size() > 0; + + ServiceDataGenerator gen = new ServiceDataGenerator() { + @Override + public ServiceSet getServiceData() { + + String uuid = config.getUUID().toString(); + + OperatingSystemMXBean osb = ManagementFactory.getOperatingSystemMXBean(); + String load = String.valueOf((int) (osb.getSystemLoadAverage() * 100 / osb.getAvailableProcessors())); + + long totalRAM = Runtime.getRuntime().maxMemory(); + long usedRAM = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + + // get service data + ServiceDataMap.Builder dmap = ServiceDataMap.newBuilder(); + dmap.addData(KeyValuePair.newBuilder().setKey("load").setValue(load).build()); + dmap.addData(KeyValuePair.newBuilder().setKey("proto_version") + .setValue(Integer.toString(MRCServiceConstants.INTERFACE_ID)).build()); + dmap.addData(KeyValuePair.newBuilder().setKey("totalRAM").setValue(Long.toString(totalRAM)).build()); + dmap.addData(KeyValuePair.newBuilder().setKey("usedRAM").setValue(Long.toString(usedRAM)).build()); + dmap.addData(KeyValuePair.newBuilder().setKey("geoCoordinates").setValue(config.getGeoCoordinates()) + .build()); + + // If BabuDB replication is enabled, determine and register the + // local communication endpoint for the BabuDB replication. + // Registering this information at the DIR is necessary to + // enable MRCs to send REDIRECTs to the client with the MRC + // address rather than the BabuDB address of the correct master. + if (replicated) { + InetSocketAddress localReplAddr = (InetSocketAddress) volumeManager.getDBStatus().get( + "replication.control.address"); + assert (localReplAddr != null); + dmap.addData(KeyValuePair.newBuilder().setKey("babudbReplAddr") + .setValue(localReplAddr.getAddress().getHostAddress() + ":" + localReplAddr.getPort()) + .build()); + } + + if (config.getHttpPort() != -1) { + try { + final String address = "".equals(config.getHostName()) ? config.getAddress() == null ? config + .getUUID().getMappings()[0].resolvedAddr.getAddress().getHostAddress() : config + .getAddress().getHostAddress() : config.getHostName(); + dmap.addData(KeyValuePair.newBuilder().setKey("status_page_url") + .setValue("http://" + address + ":" + config.getHttpPort())); + } catch (UnknownUUIDException ex) { + // should never happen + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + Service mrcReg = Service.newBuilder().setType(ServiceType.SERVICE_TYPE_MRC).setUuid(uuid).setData(dmap) + .setVersion(0).setLastUpdatedS(0).setName("MRC @ " + uuid).build(); + // (ServiceType.SERVICE_TYPE_MRC, uuid, 0, "MRC @ " + uuid, 0, + // dmap); + ServiceSet.Builder sregs = ServiceSet.newBuilder().addServices(mrcReg); + + Collection storageManagers = volumeManager.getStorageManagers(); + if (storageManagers == null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, + "cannot register volumes because volume manager not initialized yet"); + } else { + for (StorageManager sMan : storageManagers) { + + VolumeInfo vol = sMan.getVolumeInfo(); + + try { + Service dsVolumeInfo = MRCHelper.createDSVolumeInfo(vol, osdMonitor, sMan, uuid); + sregs.addServices(dsVolumeInfo); + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "could not send heartbeat signal for volume '%s': %s", vol.getName(), + exc.toString()); + } + } + } + + return sregs.build(); + } + + }; + + if (config.getHttpPort() == -1) { + // Webinterface is explicitly disabled. + statusServer = null; + } else { + statusServer = new StatusServer(ServiceType.SERVICE_TYPE_MRC, this, config.getHttpPort()); + statusServer.registerModule(new StatusPage()); + statusServer.registerModule(new PrintStackTrace()); + + final MRCRequestDispatcher master = this; + statusServer.registerModule(new BabuDBStatusPage(new BabuDBStatusPage.BabuDBStatusProvider() { + @Override + public Map getStatus() { + return master.getDBStatus(); + } + })); + + if (config.getAdminPassword().length() > 0) { + statusServer.addAuthorizedUser("admin", config.getAdminPassword()); + } + + statusServer.start(); + } + + heartbeatThread = new HeartbeatThread("MRC Heartbeat Thread", dirClient, config.getUUID(), gen, config, false); + heartbeatThread.setLifeCycleListener(this); + + onCloseReplicationThread = new OnCloseReplicationThread(this); + onCloseReplicationThread.setLifeCycleListener(this); + + if (replicated) { + mrcMonitor = new MRCStatusManager(this); + mrcMonitor.setLifeCycleListener(this); + } else + mrcMonitor = null; + } + + public void asyncShutdown() { + + onCloseReplicationThread.shutdown(); + + heartbeatThread.shutdown(); + + serverStage.shutdown(); + + clientStage.shutdown(); + + osdMonitor.shutdown(); + + procStage.shutdown(); + + xLocSetCoordinator.shutdown(); + + volumeManager.shutdown(); + + if (statusServer != null) { + statusServer.shutdown(); + } + + if (replicated) + mrcMonitor.shutdown(); + + // TimeSync.getInstance().shutdown(); + } + + public void startup() { + + try { + + TimeSync.getInstance().init(ExtSyncSource.XTREEMFS_DIR, dirClient, null, config.getRemoteTimeSync(), + config.getLocalClockRenew()); + + clientStage.start(); + clientStage.waitForStartup(); + + UUIDResolver.start(dirClient, 10 * 1000, 600 * 1000); + UUIDResolver.addLocalMapping(config.getUUID(), config.getPort(), + Schemes.getScheme(config.isUsingSSL(), config.isGRIDSSLmode())); + UUIDResolver.addLocalMapping(config.getUUID(), config.getPort(), Schemes.SCHEME_PBRPCU); + + volumeManager.init(); + volumeManager.addVolumeChangeListener(osdMonitor); + + heartbeatThread.initialize(); + heartbeatThread.start(); + + // TimeSync.getInstance().enableRemoteSynchronization(dirClient); + // XXX + osdMonitor.start(); + osdMonitor.waitForStartup(); + + if (replicated) { + mrcMonitor.start(); + mrcMonitor.waitForStartup(); + } + + xLocSetCoordinator.start(); + xLocSetCoordinator.waitForStartup(); + + procStage.start(); + procStage.waitForStartup(); + + onCloseReplicationThread.start(); + onCloseReplicationThread.waitForStartup(); + + serverStage.start(); + serverStage.waitForStartup(); + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, + "MRC operational, listening on port %d", config.getPort()); + + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "STARTUP FAILED!"); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + System.exit(1); + } + } + + public void shutdown() throws Exception { + + for (MRCStatusListener listener : statusListener) { + listener.shuttingDown(); + } + + onCloseReplicationThread.shutdown(); + onCloseReplicationThread.waitForShutdown(); + + heartbeatThread.shutdown(); + heartbeatThread.waitForShutdown(); + + serverStage.shutdown(); + serverStage.waitForShutdown(); + + clientStage.shutdown(); + clientStage.waitForShutdown(); + + osdMonitor.shutdown(); + osdMonitor.waitForShutdown(); + + if (replicated) { + mrcMonitor.shutdown(); + mrcMonitor.waitForShutdown(); + } + + procStage.shutdown(); + procStage.waitForShutdown(); + + xLocSetCoordinator.shutdown(); + xLocSetCoordinator.waitForShutdown(); + + volumeManager.shutdown(); + + statusServer.shutdown(); + } + + public void requestFinished(MRCRequest request) { + // send response back to client, if a pinky request is present + assert (request != null); + + final RPCServerRequest rpcRequest = request.getRPCRequest(); + assert (rpcRequest != null); + + if (request.getError() != null) { + + final ErrorRecord error = request.getError(); + final String errorMessage = error.getErrorMessage() == null ? "" : error.getErrorMessage(); + + switch (error.getErrorType()) { + + case INTERNAL_SERVER_ERROR: { + Logging.logMessage(Logging.LEVEL_ERROR, this, "%s / request: %s", errorMessage, request.toString()); + if (error.getThrowable() != null) + Logging.logError(Logging.LEVEL_ERROR, this, error.getThrowable()); + rpcRequest.sendError(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_EIO, errorMessage, + error.getStackTrace()); + break; + } + case ERRNO: { + if (Logging.isDebug()) { + Logging.logUserError(Logging.LEVEL_DEBUG, Category.proc, this, error.getThrowable()); + } + rpcRequest.sendError(ErrorType.ERRNO, error.getErrorCode(), errorMessage, ""); + break; + } + case AUTH_FAILED: { + if (Logging.isDebug()) { + Logging.logUserError(Logging.LEVEL_DEBUG, Category.proc, this, error.getThrowable()); + } + rpcRequest.sendError(ErrorType.AUTH_FAILED, error.getErrorCode(), errorMessage, ""); + break; + } + case GARBAGE_ARGS: { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "invalid request arguments"); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, errorMessage); + } + rpcRequest.sendError(ErrorType.GARBAGE_ARGS, POSIXErrno.POSIX_ERROR_EINVAL, errorMessage, + error.getStackTrace()); + break; + } + case INVALID_INTERFACE_ID: { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "invalid interface: %d", request + .getRPCRequest().getHeader().getRequestHeader().getInterfaceId()); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, errorMessage); + } + rpcRequest.sendError(ErrorType.INVALID_INTERFACE_ID, POSIXErrno.POSIX_ERROR_EINVAL, errorMessage, + error.getStackTrace()); + break; + } + + case INVALID_PROC_ID: { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "unknown operation: %d", request + .getRPCRequest().getHeader().getRequestHeader().getProcId()); + } + rpcRequest.sendError(ErrorType.INVALID_PROC_ID, POSIXErrno.POSIX_ERROR_EINVAL, errorMessage, + error.getStackTrace()); + break; + } + + case REDIRECT: { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "redirect to: %s", errorMessage); + } + rpcRequest.sendRedirect(errorMessage); + break; + } + + default: { + Logging.logMessage(Logging.LEVEL_ERROR, this, "some unexpected exception occurred"); + Logging.logError(Logging.LEVEL_ERROR, this, error.getThrowable()); + rpcRequest.sendError(ErrorType.IO_ERROR, POSIXErrno.POSIX_ERROR_EIO, errorMessage, + error.getStackTrace()); + break; + } + } + } + + else { + assert (request.getResponse() != null); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "sending response for request %d", request + .getRPCRequest().getHeader().getCallId()); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "%s", request.getResponse().toString()); + } + + try { + rpcRequest.sendResponse(request.getResponse(), null); + } catch (IOException e) { + Logging.logError(Logging.LEVEL_ERROR, this, e); + } + } + + } + + public int getNumConnections() { + return this.serverStage.getNumConnections(); + } + + public long getNumRequests() { + return this.serverStage.getPendingRequests(); + } + + public Map getStatusInformation() { + HashMap data = new HashMap(); + + data.put(Vars.AVAILPROCS, String.valueOf(Runtime.getRuntime().availableProcessors())); + data.put(Vars.BPSTATS, BufferPool.getStatus()); + data.put(Vars.DEBUG, Integer.toString(config.getDebugLevel())); + data.put(Vars.DIRURL, (config.isUsingSSL() ? (config.isGRIDSSLmode() ? Schemes.SCHEME_PBRPCG + : Schemes.SCHEME_PBRPCS) : Schemes.SCHEME_PBRPC) + + "://" + + config.getDirectoryService().getHostName() + + ":" + config.getDirectoryService().getPort()); + data.put(Vars.GLOBALRESYNC, Long.toString(TimeSync.getTimeSyncInterval())); + + final long globalTime = TimeSync.getGlobalTime(); + final long localTime = TimeSync.getLocalSystemTime(); + data.put(Vars.GLOBALTIME, new Date(globalTime).toString() + " (" + globalTime + ")"); + data.put(Vars.LOCALTIME, new Date(localTime).toString() + " (" + localTime + ")"); + data.put(Vars.LOCALRESYNC, Long.toString(TimeSync.getLocalRenewInterval())); + + data.put(Vars.PORT, Integer.toString(config.getPort())); + + data.put(Vars.UUID, config.getUUID().toString()); + data.put(Vars.UUIDCACHE, UUIDResolver.getCache()); + data.put(Vars.PROTOVERSION, Integer.toString(MRCServiceConstants.INTERFACE_ID)); + data.put(Vars.VERSION, VersionManagement.RELEASE_VERSION); + data.put(Vars.DBVERSION, volumeManager.getDBVersion()); + + data.put(Vars.PINKYQ, Long.toString(this.serverStage.getPendingRequests())); + data.put(Vars.NUMCON, Integer.toString(this.serverStage.getNumConnections())); + + long freeMem = Runtime.getRuntime().freeMemory(); + String span = ""; + if (freeMem < 1024 * 1024 * 32) { + span = ""; + } else if (freeMem < 1024 * 1024 * 2) { + span = ""; + } + data.put( + Vars.MEMSTAT, + span + OutputUtils.formatBytes(freeMem) + " / " + + OutputUtils.formatBytes(Runtime.getRuntime().maxMemory()) + " / " + + OutputUtils.formatBytes(Runtime.getRuntime().totalMemory()) + ""); + + StringBuffer rqTableBuf = new StringBuffer(); + long totalRequests = 0; + for (Entry entry : procStage.get_opCountMap().entrySet()) { + + long count = entry.getValue(); + totalRequests += count; + + if (count != 0) { + + try { + String req = StatusPage.getOpName(entry.getKey()); + rqTableBuf.append("'"); + rqTableBuf.append(req); + rqTableBuf.append("'"); + rqTableBuf.append(count); + rqTableBuf.append(""); + + } catch (Exception e) { + // ignore + } + } + } + + data.put(Vars.TOTALNUMRQ, totalRequests + ""); + data.put(Vars.RQSTATS, rqTableBuf.toString()); + + // add volume statistics + try { + Collection sMans = volumeManager.getStorageManagers(); + + if (sMans != null) { + + StringBuffer volTableBuf = new StringBuffer(); + + List volumes = new ArrayList(sMans.size()); + for (StorageManager sMan : sMans) + volumes.add(sMan.getVolumeInfo()); + + Collections.sort(volumes, new Comparator() { + @Override + public int compare(VolumeInfo o1, VolumeInfo o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + + boolean first = true; + for (VolumeInfo v : volumes) { + + ServiceSet osdList = osdMonitor.getUsableOSDs(v.getId()).build(); + + if (!first) + volTableBuf.append("
    "); + + volTableBuf.append(""); + volTableBuf.append(v.getName()); + volTableBuf + .append("
    selectable OSDs"); + Iterator it = osdList.getServicesList().iterator(); + while (it.hasNext()) { + Service osd = it.next(); + final ServiceUUID osdUUID = new ServiceUUID(osd.getUuid()); + volTableBuf.append(osdUUID); + if (it.hasNext()) + volTableBuf.append(", "); + } + + StripingPolicy defaultSP = volumeManager.getStorageManager(v.getId()).getDefaultStripingPolicy(1); + + AccessControlPolicyType policy = AccessControlPolicyType.valueOf(v.getAcPolicyId()); + + volTableBuf.append("
    striping policy"); + volTableBuf.append(Converter.stripingPolicyToString(defaultSP)); + volTableBuf.append("
    access policy"); + volTableBuf.append(policy != null ? policy.name() : v.getAcPolicyId()); + volTableBuf.append("
    osd policy"); + volTableBuf.append(Converter.shortArrayToString(v.getOsdPolicy())); + volTableBuf.append("
    replica policy"); + volTableBuf.append(Converter.shortArrayToString(v.getReplicaPolicy())); + volTableBuf.append("
    #files"); + volTableBuf.append(v.getNumFiles()); + volTableBuf.append("
    #directories"); + volTableBuf.append(v.getNumDirs()); + volTableBuf.append("
    free disk space:"); + + // Use minimum of free space relative to the quota and free space on osds as free disk space. + long quota = v.getVolumeQuota(); + long freeSpaceOnOsds = osdMonitor.getFreeSpace(v.getId()); + long quotaFreeSpace = quota - v.getVolumeSize(); + if (quota != 0 && quotaFreeSpace < freeSpaceOnOsds) { + quotaFreeSpace = quotaFreeSpace < 0 ? 0 : quotaFreeSpace; + volTableBuf.append(OutputUtils.formatBytes(quotaFreeSpace)); + } else { + volTableBuf.append(OutputUtils.formatBytes(freeSpaceOnOsds)); + } + + volTableBuf.append("
    occupied disk space:"); + volTableBuf.append(OutputUtils.formatBytes(v.getVolumeSize())); + volTableBuf.append("
    "); + + first = false; + } + + data.put(Vars.VOLUMES, volTableBuf.toString()); + } + + else { + data.put(Vars.VOLUMES, "Volumes not yet initialized!"); + } + + } catch (Exception exc) { + data.put(Vars.VOLUMES, + "could not retrieve volume info due to an server internal error: " + exc + + ""); + } + + return data; + } + + public VolumeManager getVolumeManager() { + return volumeManager; + } + + public FileAccessManager getFileAccessManager() { + return fileAccessManager; + } + + public AuthenticationProvider getAuthProvider() { + return authProvider; + } + + public OSDStatusManager getOSDStatusManager() { + return osdMonitor; + } + + public OnCloseReplicationThread getOnCloseReplicationThread() { + return onCloseReplicationThread; + } + + public MRCPolicyContainer getPolicyContainer() { + return policyContainer; + } + + public DIRClient getDirClient() { + return dirClient; + } + + public OSDServiceClient getOSDClient() { + return osdClient; + } + + public MRCConfig getConfig() { + return config; + } + + @Override + public void startupPerformed() { + } + + @Override + public void shutdownPerformed() { + } + + @Override + public void crashPerformed(Throwable cause) { + final String report = CrashReporter.createCrashReport("MRC", VersionManagement.RELEASE_VERSION, cause); + System.out.println(report); + CrashReporter.reportXtreemFSCrash(report); + try { + shutdown(); + } catch (Exception e) { + Logging.logError(Logging.LEVEL_ERROR, this, e); + System.exit(1); + } + } + + @Override + public void receiveRecord(RPCServerRequest rq) { + + // final ONCRPCRequestHeader hdr = rq.getRequestHeader(); + RPCHeader hdr = rq.getHeader(); + + if (hdr.getMessageType() != MessageType.RPC_REQUEST) { + rq.sendError(ErrorType.GARBAGE_ARGS, POSIXErrno.POSIX_ERROR_EIO, + "expected RPC request message type but got " + hdr.getMessageType()); + return; + } + + final RPCHeader.RequestHeader rqHdr = hdr.getRequestHeader(); + + if (rqHdr.getInterfaceId() != MRCServiceConstants.INTERFACE_ID) { + rq.sendError( + ErrorType.INVALID_INTERFACE_ID, + POSIXErrno.POSIX_ERROR_EIO, + "Invalid interface id. This is a MRC service. You probably wanted to contact another service. Check the used address and port."); + return; + } + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "enqueueing request: %s", rq.toString()); + + // no callback, special stage which executes the operatios + procStage.enqueueOperation(new MRCRequest(rq), ProcessingStage.STAGEOP_PARSE_AND_EXECUTE, null); + } + + @Override + public void failed(Throwable error, Object context) { + MRCRequest request = (MRCRequest) context; + assert (request != null); + + final RPCServerRequest rpcRequest = request.getRPCRequest(); + assert (rpcRequest != null); + + if (request.getError() == null) + request.setError(ErrorType.INTERNAL_SERVER_ERROR, error.getMessage()); + requestFinished(request); + } + + @Override + public void finished(Object result, Object context) { + requestFinished((MRCRequest) context); + } + + public void addStatusListener(MRCStatusListener listener) { + this.statusListener.add(listener); + } + + public void removeStatusListener(MRCStatusListener listener) { + this.statusListener.remove(listener); + } + + /** + * Tells all listeners when the configuration has changed. + */ + public void notifyConfigurationChange() { + for (MRCStatusListener listener : statusListener) { + listener.MRCConfigChanged(this.config); + } + } + + /** + * Tells all listeners when a Volume was created. + */ + public void notifyVolumeCreated() { + for (MRCStatusListener listener : statusListener) { + listener.volumeCreated(); + } + } + + public void notifyVolumeDeleted() { + for (MRCStatusListener listener : statusListener) { + listener.volumeDeleted(); + } + } + + /** + * Getter for a timestamp when the heartbeatthread sent his last heartbeat + * + * @return long - timestamp as returned by System.currentTimeMillis() + */ + public long getLastHeartbeat() { + return heartbeatThread.getLastHeartbeat(); + } + + public Map getDBStatus() { + return volumeManager == null ? null : volumeManager.getDBStatus(); + } + + public String getReplMasterUUID() throws MRCException { + + if (replicated) { + InetSocketAddress addr = (InetSocketAddress) volumeManager.getDBStatus().get("replication.control.master"); + + String uuid = addr == null ? null : mrcMonitor.getUUIDForReplHost(addr); + + // if the UUID could not be resolved immediately, fetch MRC status + // and try again + if (uuid == null) { + try { + mrcMonitor.waitForNextSync(true); + + addr = (InetSocketAddress) volumeManager.getDBStatus().get("replication.control.master"); + uuid = addr == null ? null : mrcMonitor.getUUIDForReplHost(addr); + + } catch (InterruptedException e) { + } + + if (uuid == null) { + Logging.logMessage(Logging.LEVEL_INFO, this, + "unable to detect replication master; BabuDB addr=%s, UUID=%s", addr.toString(), uuid); + throw new MRCException("could not detect replication master"); + } + } + + return uuid; + + } else + return null; + } + + /** + * @see HeartbeatThread#pauseOperation() + * @throws InterruptedException + */ + public void pauseHeartbeatThread() throws InterruptedException { + heartbeatThread.pauseOperation(); + } + + /** + * @see HeartbeatThread#resumeOperation() + */ + public void resumeHeartbeatThread() { + heartbeatThread.resumeOperation(); + } + + public XLocSetCoordinator getXLocSetCoordinator() { + return xLocSetCoordinator; + } + + public ProcessingStage getProcStage() { + return procStage; + } + + /** + * The hashCode is based on the UUID and the system time when {@link MRCRequestDispatcher} was initialized.
    + * It will be unique between different MRCs and instances on the same MRC. + */ + @Override + public int hashCode() { + StringBuilder hashString = new StringBuilder(); + hashString.append(super.hashCode()); + hashString.append(config.getUUID()); + hashString.append(initTimeMS); + return hashString.toString().hashCode(); + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/MRCStatusListener.java b/java/servers/src/org/xtreemfs/mrc/MRCStatusListener.java new file mode 100644 index 0000000..bbb7bc4 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/MRCStatusListener.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + + +public interface MRCStatusListener { + public void MRCConfigChanged(MRCConfig config); + + public void volumeCreated(); + + public void volumeDeleted(); + + /** + * Called when DIR is shutting down. + */ + public void shuttingDown(); + +} diff --git a/java/servers/src/org/xtreemfs/mrc/MRCStatusManager.java b/java/servers/src/org/xtreemfs/mrc/MRCStatusManager.java new file mode 100644 index 0000000..9b2994c --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/MRCStatusManager.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; + +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; + +/** + * Checks regularly for remote MRCs and their replication endpoints. + * + * @author stenjan + */ +public class MRCStatusManager extends LifeCycleThread { + + /** + * Interval in ms to wait between two checks. + */ + private int checkIntervalMillis = 1000 * 5; + + private ServiceSet.Builder knownMRCs; + + private Map mrcAddrMap; + + private Object syncLock = new Object(); + + /** + * Thread shuts down if true. + */ + private boolean quit = false; + + /** + * Reference to the MRCRequestDispatcher. + */ + private MRCRequestDispatcher master; + + public MRCStatusManager(MRCRequestDispatcher master) throws IOException { + + super("MRCStatusManager"); + + this.master = master; + + knownMRCs = ServiceSet.newBuilder(); + mrcAddrMap = new HashMap(); + + int interval = master.getConfig().getOsdCheckInterval(); + checkIntervalMillis = 1000 * interval; + } + + /** + * Shuts down the thread. + */ + public synchronized void shutdown() { + quit = true; + this.interrupt(); + this.notifyAll(); + } + + /** + * Main loop. + */ + public void run() { + + // initially fetch the list of MRCs from the Directory Service + try { + + knownMRCs = master + .getDirClient() + .xtreemfs_service_get_by_type(null, RPCAuthentication.authNone, RPCAuthentication.userService, + ServiceType.SERVICE_TYPE_MRC).toBuilder(); + + } catch (Throwable exc) { + this.notifyCrashed(exc); + } + + notifyStarted(); + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, + "MRC status manager operational, using DIR %s", master.getConfig().getDirectoryService().toString()); + + while (!quit) { + + synchronized (this) { + try { + this.wait(knownMRCs == null || knownMRCs.getServicesCount() == 0 ? checkIntervalMillis / 2 + : checkIntervalMillis); + } catch (InterruptedException ex) { + break; + } + } + + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "sending request for MRC list to DIR..."); + + try { + // request list of registered MRCs from Directory + // Service + + knownMRCs = master + .getDirClient() + .xtreemfs_service_get_by_type(null, RPCAuthentication.authNone, RPCAuthentication.userService, + ServiceType.SERVICE_TYPE_MRC).toBuilder(); + + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "... received MRC list from DIR"); + + evaluateResponse(knownMRCs); + + } catch (InterruptedException ex) { + break; + } catch (Exception exc) { + if (!quit) + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, OutputUtils.stackTraceToString(exc)); + } + + synchronized (syncLock) { + syncLock.notifyAll(); + } + + } + + notifyStopped(); + } + + public synchronized void evaluateResponse(ServiceSet.Builder knownMRCs) { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "response..."); + + assert (knownMRCs != null); + assert (knownMRCs.getServicesCount() != 0); + + if (Logging.isDebug()) { + + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "registered MRCs"); + for (Service mrc : knownMRCs.getServicesList()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "%s", mrc.getUuid()); + } + } + + // update the list + this.knownMRCs = knownMRCs; + mrcAddrMap.clear(); + for (Service mrc : knownMRCs.getServicesList()) { + String endpoint = KeyValuePairs.getValue(mrc.getData().getDataList(), "babudbReplAddr"); + if (endpoint != null) { + int index = endpoint.indexOf(':'); + if (index != -1) + mrcAddrMap.put( + new InetSocketAddress(endpoint.substring(0, index), Integer.parseInt(endpoint + .substring(index + 1))), mrc.getUuid()); + } + } + } + + public void waitForNextSync(boolean immediately) throws InterruptedException { + + synchronized (this) { + if (immediately) + notify(); + } + + synchronized (syncLock) { + syncLock.wait(); + } + } + + public synchronized String getUUIDForReplHost(InetSocketAddress host) { + return mrcAddrMap.get(host); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/RequestDetails.java b/java/servers/src/org/xtreemfs/mrc/RequestDetails.java new file mode 100644 index 0000000..cc364c9 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/RequestDetails.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + +import java.util.List; +import java.util.Map; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; + +/** + * + * 29.09.2008 + * + * @author clorenz + */ +public final class RequestDetails { + + public String userId; + + public boolean superUser; + + public List groupIds; + + public Auth auth; + + public String password; + + public Map context; + + /** + * + */ + public RequestDetails() { + userId = null; + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/StatusPage.java b/java/servers/src/org/xtreemfs/mrc/StatusPage.java new file mode 100644 index 0000000..d95b535 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/StatusPage.java @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2013 Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +import org.xtreemfs.common.statusserver.StatusServerHelper; +import org.xtreemfs.common.statusserver.StatusServerModule; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceConstants; + +import com.sun.net.httpserver.HttpExchange; + +/** + * Serves a simple HTML status page with MRC stats. + */ +public class StatusPage extends StatusServerModule { + + public enum Vars { + LASTRQDATE(""), TOTALNUMRQ(""), RQSTATS(""), VOLUMES( + ""), UUID(""), AVAILPROCS(""), BPSTATS( + ""), PORT(""), DIRURL(""), DEBUG(""), NUMCON( + ""), PINKYQ(""), PROCQ(""), GLOBALTIME( + ""), GLOBALRESYNC(""), LOCALTIME(""), LOCALRESYNC( + ""), MEMSTAT(""), UUIDCACHE(""), DISKFREE( + ""), PROTOVERSION(""), VERSION(""), DBVERSION( + ""); + + private String template; + + Vars(String template) { + this.template = template; + } + + public String toString() { + return template; + } + } + + private final String statusPageTemplate; + private MRCRequestDispatcher master; + + /** + * opNames contains a mapping from numerical operation ids to their textual representation. + * It is used by the static method {@link #getOpName} and has therefore to be statically initialized. + */ + private static final Map opNames; + static { + opNames = new HashMap(); + for (Field field : MRCServiceConstants.class.getDeclaredFields()) { + if (field.getName().startsWith("PROC_ID")) + try { + opNames.put(field.getInt(null), field.getName().substring("PROC_ID_".length()).toLowerCase()); + } catch (IllegalArgumentException e) { + Logging.logError(Logging.LEVEL_ERROR, null, e); + } catch (IllegalAccessException e) { + Logging.logError(Logging.LEVEL_ERROR, null, e); + } + } + } + + public StatusPage() { + StringBuffer sb = StatusServerHelper.readTemplate("org/xtreemfs/mrc/templates/status.html"); + if (sb == null) { + statusPageTemplate = "

    Template was not found, unable to show status page!

    "; + } else { + statusPageTemplate = sb.toString(); + } + } + + @Override + public void initialize(ServiceType service, Object serviceRequestDispatcher) { + assert (service == ServiceType.SERVICE_TYPE_MRC); + master = (MRCRequestDispatcher) serviceRequestDispatcher; + } + + @Override + public String getDisplayName() { + return "MRC Status Page"; + } + + @Override + public String getUriPath() { + return "/"; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + Map vars = master.getStatusInformation(); + String tmp = statusPageTemplate; + for (Vars key : vars.keySet()) { + tmp = tmp.replace(key.toString(), vars.get(key)); + } + + sendResponse(httpExchange, tmp); + httpExchange.close(); + } + + @Override + public boolean isAvailableForService(ServiceType service) { + return service == ServiceType.SERVICE_TYPE_MRC; + } + + @Override + public void shutdown() { + } + + /** + * Returns the textual representation of an operation defined in {@link MRCServiceConstants}. + * + * @param opId + * numeric if of an operation. + * @return The textual representation of the operation or null if the opId does not exist. + */ + public static String getOpName(int opId) { + String name = opNames.get(opId); + return name == null ? null : name; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/UserException.java b/java/servers/src/org/xtreemfs/mrc/UserException.java new file mode 100644 index 0000000..9ee6da6 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/UserException.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; + +/** + * This exception is thrown if something + * + * @author bjko, stender + */ +public class UserException extends java.lang.Exception { + + private POSIXErrno errno; + + /** + * Creates a new instance of XtreemFSException without detail + * message. + */ + public UserException() { + this.errno = POSIXErrno.POSIX_ERROR_NONE; + } + + public UserException(POSIXErrno errno) { + this.errno = errno; + } + + public UserException(POSIXErrno errno, String message) { + super(message + " (errno=" + errno + ")"); + this.errno = errno; + } + + public POSIXErrno getErrno() { + return this.errno; + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/ac/FileAccessManager.java b/java/servers/src/org/xtreemfs/mrc/ac/FileAccessManager.java new file mode 100644 index 0000000..52e7ccb --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/ac/FileAccessManager.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.ac; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.MRCException; +import org.xtreemfs.mrc.MRCPolicyContainer; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; + +/** + * This class is responsible for checking policy-based file access. + * + * @author stender + * + */ +public class FileAccessManager { + + public static final int O_RDONLY = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY + .getNumber(); + + public static final int O_WRONLY = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_WRONLY + .getNumber(); + + public static final int O_RDWR = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR + .getNumber(); + + public static final int O_CREAT = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT + .getNumber(); + + public static final int O_TRUNC = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC + .getNumber(); + + public static final int O_APPEND = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_APPEND + .getNumber(); + + public static final int O_EXCL = GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_EXCL + .getNumber(); + + public static final int NON_POSIX_SEARCH = 04000000; + + public static final int NON_POSIX_DELETE = 010000000; + + public static final int NON_POSIX_RM_MV_IN_DIR = 020000000; + + private final VolumeManager volMan; + + private final Map policies; + + private MRCPolicyContainer policyContainer; + + public FileAccessManager(VolumeManager volMan, MRCPolicyContainer policyContainer) { + + this.volMan = volMan; + this.policyContainer = policyContainer; + + policies = new HashMap(); + } + + public void checkSearchPermission(StorageManager sMan, PathResolver path, String userId, + boolean superUser, List groupIds) throws UserException, MRCException { + + if (superUser) + return; + + getVolumeFileAccessPolicy(sMan.getVolumeInfo().getId()).checkSearchPermission(sMan, path, userId, + groupIds); + } + + public void checkPrivilegedPermissions(StorageManager sMan, FileMetadata file, String userId, + boolean superUser, List groupIds) throws UserException, MRCException { + + if (superUser) + return; + + getVolumeFileAccessPolicy(sMan.getVolumeInfo().getId()).checkPrivilegedPermissions(sMan, file, + userId, groupIds); + } + + public void checkPermission(int flags, StorageManager sMan, FileMetadata file, long parentDirId, + String userId, boolean superUser, List groupIds) throws UserException, MRCException { + + checkPermission(translateAccessFlags(sMan.getVolumeInfo().getId(), flags), sMan, file, parentDirId, + userId, superUser, groupIds); + } + + public void checkPermission(String accessMode, StorageManager sMan, FileMetadata file, long parentDirId, + String userId, boolean superUser, List groupIds) throws UserException, MRCException { + + if (superUser) + return; + + getVolumeFileAccessPolicy(sMan.getVolumeInfo().getId()).checkPermission(sMan, file, parentDirId, + userId, groupIds, accessMode); + } + + public String translateAccessFlags(String volumeId, int accessMode) throws MRCException { + return getVolumeFileAccessPolicy(volumeId).translateAccessFlags(accessMode); + } + + public int getPosixAccessMode(StorageManager sMan, FileMetadata file, String userId, List groupIds) + throws MRCException { + return getVolumeFileAccessPolicy(sMan.getVolumeInfo().getId()).getPosixAccessRights(sMan, file, + userId, groupIds); + } + + public void setPosixAccessMode(StorageManager sMan, FileMetadata file, long parentId, String userId, + List groupIds, int posixRights, boolean superUser, AtomicDBUpdate update) + throws MRCException, UserException { + getVolumeFileAccessPolicy(sMan.getVolumeInfo().getId()).setPosixAccessRights(sMan, file, parentId, + userId, groupIds, posixRights, superUser, update); + } + + public Map getACLEntries(StorageManager sMan, FileMetadata file) throws MRCException { + return getVolumeFileAccessPolicy(sMan.getVolumeInfo().getId()).getACLEntries(sMan, file); + } + + public void updateACLEntries(StorageManager sMan, FileMetadata file, long parentId, + Map entries, AtomicDBUpdate update) throws MRCException, UserException { + getVolumeFileAccessPolicy(sMan.getVolumeInfo().getId()).updateACLEntries(sMan, file, parentId, + entries, update); + } + + public void removeACLEntries(StorageManager sMan, FileMetadata file, long parentId, + List entities, AtomicDBUpdate update) throws MRCException, UserException { + getVolumeFileAccessPolicy(sMan.getVolumeInfo().getId()).removeACLEntries(sMan, file, parentId, + entities, update); + } + + public FileAccessPolicy getFileAccessPolicy(short policyId) { + + FileAccessPolicy policy = policies.get(policyId); + + // if the policy is not built-in, try to load it from the plug-in + // directory + if (policy == null) { + try { + policy = policyContainer.getFileAccessPolicy(policyId, volMan); + policies.put(policyId, policy); + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "could not load FileAccessPolicy with ID %d", policyId); + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, OutputUtils + .stackTraceToString(exc)); + } + } + + return policy; + } + + protected FileAccessPolicy getVolumeFileAccessPolicy(String volumeId) throws MRCException { + + try { + + short policyId = volMan.getStorageManager(volumeId).getVolumeInfo().getAcPolicyId(); + FileAccessPolicy policy = getFileAccessPolicy(policyId); + + if (policy == null) + throw new MRCException("unknown file access policy for volume " + volumeId + ": " + policyId); + + return policy; + + } catch (Exception exc) { + throw new MRCException(exc); + } + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/ac/FileAccessPolicy.java b/java/servers/src/org/xtreemfs/mrc/ac/FileAccessPolicy.java new file mode 100644 index 0000000..5a04fd5 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/ac/FileAccessPolicy.java @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.ac; + +import java.util.List; +import java.util.Map; + +import org.xtreemfs.mrc.MRCException; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.metadata.ACLEntry; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.PathResolver; + +/** + * An interface for a policy defining file access. + * + * @author stender + */ +public interface FileAccessPolicy { + + /** + * Returns a string representing the policy-specific translation of the + * given POSIX access mode. This method can be used to obtain a valid access + * mode string to pass with checkAccess. + * + * @param accessMode + * the POSIX access mode, see {@link FileAccessManager} constants + * @return a policy-specific string describing the access mode + */ + public String translateAccessFlags(int accessMode); + + /** + * Returns a string representing the policy-specific translation of the + * given permissions into the 'rwx' scheme. + * + * @param permissions + * an integer representing the permissions for a specific user or + * group + * @return an 'rwx' string describing the permissions + */ + public String translatePermissions(int permissions); + + /** + * Checks whether the user with the given ID is allowed to perform + * operations for the given file with the given access mode. + * + * @param sMan + * the volume's Storage Manager + * @param file + * the file + * @param parentId + * the file's parent ID - note that 0 is provided unless the + * check refers to an entity being added, deleted or moved in a + * directory + * @param userId + * the user ID + * @param groupIds + * a list of group IDs + * @param accessMode + * the access mode. How the access mode has to be interpreted + * depends on the policy implementation. + * @throws UserException + * if the permission was denied + * @throws MRCException + * if an error occurs while trying to get permissions + */ + public void checkPermission(StorageManager sMan, FileMetadata file, long parentId, String userId, + List groupIds, String accessMode) throws UserException, MRCException; + + /** + * Checks whether search permission is granted on the given path. The method + * should return without throwing an exception if + * checkPermission() for an access mode implying the right to + * switch to the directory returns true. + * + * POSIX-compliant implementations might have to check permissions + * recursively for each path component. Since there might not be an explicit + * access mode for searching directories, the framework will invoke this + * method instead of using checkPermission() when checking + * search access on directories. + * + * @param sMan + * the volume's Storage Manager + * @param res + * the path resolver + * @param userId + * the user ID + * @param groupIds + * a list of group IDs + * @throws UserException + * if the permission was denied + * @throws MRCException + * if an error occurs at the backend + */ + public void checkSearchPermission(StorageManager sMan, PathResolver res, String userId, + List groupIds) throws UserException, MRCException; + + /** + * Checks whether permission is granted to change the owner of the file with + * the given ID. + * + * @param sMan + * the volume's Storage Manager + * @param file + * the file in the volume + * @param userId + * the ID of the user on behalf of whom the access check is + * performed + * @param groupIds + * a list of group IDs + * @throws UserException + * if the permissoin was denied + * @throws MRCException + * if an error occurs at the backend + */ + public void checkPrivilegedPermissions(StorageManager sMan, FileMetadata file, String userId, + List groupIds) throws UserException, MRCException; + + /** + * Returns a POSIX access mode bit mask for the given file and user in the + * form of a long. As specified in POSIX, the first three bits represent + * read, write and execute access for the user, the next three bits do the + * same for the group, and the last three bits for the rest of the world. + * Any other bits may be used in a policy-specific manner. + * + * @param sMan + * the volume's Storage Manager + * @param file + * the file + * @param userId + * the user ID + * @param groupIds + * a list of group IDs + * @return the POSIX access rights + * @throws MRCException + * if an error occurs when trying to tranlate access rights + */ + public int getPosixAccessRights(StorageManager sMan, FileMetadata file, String userId, + List groupIds) throws MRCException; + + /** + * Modifies the file ACL by means of a POSIX access mode bit mask. + * + * @param sMan + * the volume's Storage Manager + * @param file + * the file + * @param parentId + * the file's parent ID + * @param userId + * the user ID + * @param groupIds + * a list of group IDs + * @param posixAccessRights + * a long value describing the POSIX access rights + * @param update + * the database update + * @throws MRCException + * if an error occurs when trying to tranlate access rights + * @throws UserException + * if access is denied + */ + public void setPosixAccessRights(StorageManager sMan, FileMetadata file, long parentId, String userId, + List groupIds, int posixAccessRights, boolean superUser, AtomicDBUpdate update) throws MRCException, + UserException; + + /** + * Creates or changes a set of entries the current ACL of a file. + * + * @param sMan + * the volume's Storage Manager + * @param file + * the file + * @param parentId + * the file's parent ID + * @param entries + * a mapping from entity names (ac entities) to long values + * (rights masks) representing the ACL entries to add/modify + * @param update + * the database update + * @throws MRCException + * if an error occurs when trying to change the ACL + * @throws UserException + * if access is denied + */ + public void updateACLEntries(StorageManager sMan, FileMetadata file, long parentId, + Map entries, AtomicDBUpdate update) throws MRCException, UserException; + + /** + * Returns the ACL of a file. + * + * @param sMan + * the volume's Storage Manager + * @param file + * the file + * @return the ACL of the given file + */ + public Map getACLEntries(StorageManager sMan, FileMetadata file) throws MRCException; + + /** + * Creates or changes an entry in the current ACL of a file. + * + * @param sMan + * the volume's Storage Manager + * @param file + * the file + * @param parentId + * the file's parent ID + * @param entities + * a list of access control entity names to delete from the ACL + * @param update + * the database update + * @throws MRCException + * if an error occurs when trying to change the ACL + * @throws UserException + * if access is denied + */ + public void removeACLEntries(StorageManager sMan, FileMetadata file, long parentId, + List entities, AtomicDBUpdate update) throws MRCException, UserException; + + /** + * Returns the default ACL for the root directory. The method is invoked in + * order to assign an initial ACL to a the root directory of a newly-created + * volume. + * + * @return the default root ACL + */ + public ACLEntry[] getDefaultRootACL(); +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/ac/POSIXFileAccessPolicy.java b/java/servers/src/org/xtreemfs/mrc/ac/POSIXFileAccessPolicy.java new file mode 100644 index 0000000..dbdc9b7 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/ac/POSIXFileAccessPolicy.java @@ -0,0 +1,688 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.ac; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCException; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.metadata.ACLEntry; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; + +/** + * This policy evaluates access rights according to POSIX permissions and access control lists (ACLs). The + * implementation is based on the description provided in "POSIX Access Control Lists on Linux" by Andreas + * Grünbacher (http://www.suse.de/~agruen/acl/linux-acls/online/). + * + *

    + * In the general case, access permissions are granted or denied based on the 16 bit permissions value which + * is directly associated with the file metadata. This allows to distinguish 'read', 'write' and 'execute' + * rights for the owner, the owing group and the rest of the world. + * + *

    + * A more fine-grained access control model can be supported by using ACLs. Access control decisions will be + * made based on ACLs if at least the following ACL entries exist for a file: + * + *

      + *
    • "user:" - owner, has to occur exactly once + *
    • "user:<name>" - named user, may occur zero or more times + *
    • "group:" - owning group, has to occur exactly once + *
    • "group:<name>" - named group, may occur zero or more times + *
    • "other:" - other, has to occur exactly once + *
    • "mask:" - mask, may occur at most once + *
    + * + *

    + * The access control granularity w/ ACLs is not restricted to 'read', 'write' and 'execute'. Further access + * modes and bits are evaluated (the values in brackets decribe the corresponding bit value in the ACL entry): + * + *

      + *
    • "r" - read (0x01) + *
    • "w" - write (0x02) + *
    • "x" - execute (0x04) + *
    • "a" - append (0x08) + *
    • "ga" - GFS-like append (0x10) + *
    • "c" - create (0x20) + *
    • "t" - truncate (0x40) + *
    • "sr" - strict read-only (0x80) + *
    • "d" - delete (0x100) + *
    + * + *

    + * When checking access to a file or directory, the policy will search for the relevant ACL entry according to + * the POSIX access check algorithm, where the 'rights' value of the ACL entry is interpreted as a bit mask. + * The bits for the corresponding access modes are set in the reverse order as they are enumerated above. + * + *

    + * Example: an ACL entry ("user:", 35) would grant read, write and create access to the file owner, because 35 + * represents the bit mask 000100011. + * + * @author stender + */ +public class POSIXFileAccessPolicy implements FileAccessPolicy { + + public static final short POLICY_ID = (short) AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX + .getNumber(); + + protected static final String OWNER = "u:"; + + protected static final String OWNER_GROUP = "g:"; + + protected static final String OTHER = "o:"; + + protected static final String MASK = "m:"; + + protected static final String NAMED_USER_PREFIX = "u:"; + + protected static final String NAMED_GROUP_PREFIX = "g:"; + + protected static final String STICKY_BIT = "sticky"; + + protected static final String AM_WRITE = "w"; + + protected static final String AM_READ = "r"; + + protected static final String AM_READ_WRITE = "rw"; + + protected static final String AM_EXECUTE = "x"; + + protected static final String AM_DELETE = "d"; + + protected static final String AM_MV_RM_IN_DIR = "m"; + + protected static final int POSIX_OTHER_EXEC = 1 << 0; + + protected static final int POSIX_OTHER_WRITE = 1 << 1; + + protected static final int POSIX_OTHER_READ = 1 << 2; + + protected static final int POSIX_GROUP_EXEC = 1 << 3; + + protected static final int POSIX_GROUP_WRITE = 1 << 4; + + protected static final int POSIX_GROUP_READ = 1 << 5; + + protected static final int POSIX_OWNER_EXEC = 1 << 6; + + protected static final int POSIX_OWNER_WRITE = 1 << 7; + + protected static final int POSIX_OWNER_READ = 1 << 8; + + protected static final int POSIX_STICKY = 1 << 9; + + protected static final int POSIX_SGID = 1 << 10; + + protected static final int POSIX_SUID = 1 << 11; + + protected static final short PERM_READ = 1 << 0; + + protected static final short PERM_WRITE = 1 << 1; + + protected static final short PERM_EXECUTE = 1 << 2; + + protected static final short PERM_APPEND = 1 << 3; + + protected static final short PERM_GFS_APPEND = 1 << 4; + + protected static final short PERM_CREATE = 1 << 5; + + protected static final short PERM_TRUNCATE = 1 << 6; + + protected static final short PERM_STRICT_READ = 1 << 7; + + protected static final short PERM_DELETE = 1 << 8; + + protected static final short PERM_SUID_SGID = 1 << 14; + + protected static final short READ_MASK = PERM_READ | PERM_STRICT_READ; + + protected static final short WRITE_MASK = PERM_WRITE | PERM_APPEND | PERM_GFS_APPEND | PERM_CREATE + | PERM_TRUNCATE | PERM_DELETE; + + protected static final short EXEC_MASK = PERM_EXECUTE; + + protected static final short READ_ONLY_MASK = (-1 & 365); + + public POSIXFileAccessPolicy() { + } + + @Override + public String translateAccessFlags(int accessMode) { + + accessMode = accessMode + & (FileAccessManager.O_RDWR | FileAccessManager.O_WRONLY | FileAccessManager.O_APPEND + | FileAccessManager.O_TRUNC | FileAccessManager.NON_POSIX_SEARCH + | FileAccessManager.NON_POSIX_DELETE | FileAccessManager.NON_POSIX_RM_MV_IN_DIR); + + if (accessMode == FileAccessManager.O_RDONLY) + return AM_READ; + if (((accessMode & FileAccessManager.O_WRONLY) != 0) || ((accessMode & FileAccessManager.O_APPEND) != 0) + || ((accessMode & FileAccessManager.O_TRUNC) != 0)) + return AM_WRITE; + if ((accessMode & FileAccessManager.O_RDWR) != 0) + return AM_READ_WRITE; + if ((accessMode & FileAccessManager.NON_POSIX_SEARCH) != 0) + return AM_EXECUTE; + if ((accessMode & FileAccessManager.NON_POSIX_DELETE) != 0) + return AM_DELETE; + if ((accessMode & FileAccessManager.NON_POSIX_RM_MV_IN_DIR) != 0) + return AM_MV_RM_IN_DIR; + + assert (false) : "unknown access mode: " + accessMode; + return null; + } + + @Override + public String translatePermissions(int permissions) { + + StringBuilder sb = new StringBuilder(); + sb.append((permissions & PERM_READ) > 0 ? "r" : "-"); + sb.append((permissions & PERM_WRITE) > 0 ? "w" : "-"); + sb.append((permissions & PERM_EXECUTE) > 0 ? "x" : "-"); + + return sb.toString(); + } + + @Override + public void checkPermission(StorageManager sMan, FileMetadata file, long parentId, String userId, + List groupIds, String accessMode) throws UserException, MRCException { + + assert (file != null); + + DatabaseResultSet aclSet = null; + try { + + // check whether an ACL exists; if so, use the ACL for the access + // check ... + aclSet = sMan.getACL(file.getId()); + if (aclSet.hasNext()) { + + // retrieve the relevant ACL entry for evaluating the access + // rights + ACLEntry entry = getRelevantACLEntry(sMan, file, parentId, userId, groupIds, accessMode); + assert (entry != null); + + // if the ACL entry is 'owner' or 'others', evaluate the access + // rights without taking into account the 'mask' entry + if (OTHER.equals(entry.getEntity()) || OWNER.equals(entry.getEntity())) { + + if (checkIfAllowed(sMan, accessMode, entry.getRights(), file, parentId, userId)) { + return; + } else + accessDenied(sMan.getVolumeInfo().getId(), file, accessMode, userId); + + } + + // otherwise, check whether both the entry and the mask entry + // grant access + ACLEntry maskEntry = sMan.getACLEntry(file.getId(), MASK); + if (checkIfAllowed(sMan, accessMode, entry.getRights(), file, parentId, userId) + && (maskEntry == null || checkIfAllowed(sMan, accessMode, maskEntry.getRights(), file, + parentId, userId))) + return; + else + accessDenied(sMan.getVolumeInfo().getId(), file, accessMode, userId); + + } + + // if not, use the file permissions for the access check ... + else { + if (checkIfAllowed(sMan, accessMode, + toRelativeACLRights(file.getPerms(), file, parentId, userId, groupIds), file, parentId, userId)) + return; + else + accessDenied(sMan.getVolumeInfo().getId(), file, accessMode, userId); + } + + } catch (UserException exc) { + throw exc; + } catch (Exception exc) { + throw new MRCException(exc); + } finally { + if (aclSet != null) + aclSet.destroy(); + } + + } + + @Override + public void checkSearchPermission(StorageManager sMan, PathResolver res, String userId, List groupIds) + throws UserException, MRCException { + + try { + + // iteratively check search permissions for all directories in the + // path + FileMetadata[] rp = res.getResolvedPath(); + for (int i = 0; i < rp.length - 1; i++) + checkPermission(sMan, rp[i], i == 0 ? 0 : rp[i - 1].getId(), userId, groupIds, AM_EXECUTE); + + } catch (UserException exc) { + throw exc; + } catch (Exception exc) { + throw new MRCException(exc); + } + } + + @Override + public void checkPrivilegedPermissions(StorageManager sMan, FileMetadata file, String userId, List groupIds) + throws UserException, MRCException { + + try { + + if (!file.getOwnerId().equals(userId)) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "no privileged permissions granted"); + + } catch (UserException exc) { + throw exc; + } catch (Exception exc) { + throw new MRCException(exc); + } + } + + @Override + public void updateACLEntries(StorageManager sMan, FileMetadata file, long parentId, Map entries, + AtomicDBUpdate update) throws MRCException, UserException { + + DatabaseResultSet acl = null; + try { + + Map aclMap = null; + + // if no ACL has been defined yet, create a minimal ACL first + acl = sMan.getACL(file.getId()); + if (!acl.hasNext()) + aclMap = convertToACL(file.getPerms()); + + // otherwise, retrieve the current ACL + else { + aclMap = new HashMap(); + while (acl.hasNext()) { + ACLEntry next = acl.next(); + aclMap.put(next.getEntity(), next.getRights()); + } + } + + for (Entry entry : entries.entrySet()) { + + String entity = entry.getKey(); + String rwx = (String) entry.getValue(); + + if (rwx != null) { + int rights = 0; + + // numeric value + if (rwx.length() == 1 && rwx.charAt(0) >= '0' && rwx.charAt(0) <= '7') { + + rights = Integer.parseInt(rwx, 8); + + // fix: swap 'r' and 'x' bits for a correct internal + // representation + int tmp = ((rights >> 2) ^ rights) & 1; + rights = rights ^ ((tmp << 2) | (tmp << 0)); + } + + // 'rwx' value + else { + if (rwx.indexOf('r') != -1) + rights |= PERM_READ; + if (rwx.indexOf('w') != -1) + rights |= PERM_WRITE; + if (rwx.indexOf('x') != -1) + rights |= PERM_EXECUTE; + } + + aclMap.put(entity, rights); + } else + aclMap.put(entity, null); + } + + // add the ACL entries + for (Entry entry : aclMap.entrySet()) { + Number rights = (Number) entry.getValue(); + sMan.setACLEntry(file.getId(), entry.getKey(), rights == null ? null : rights.shortValue(), update); + } + + // modify the POSIX access value + int owner = ((Number) aclMap.get(OWNER)).intValue(); + Integer group = aclMap.get(MASK) != null ? ((Number) aclMap.get(MASK)).intValue() : null; + if (group == null) + group = ((Number) aclMap.get(OWNER_GROUP)).intValue(); + int other = ((Number) aclMap.get(OTHER)).intValue(); + + int posixRights = ((owner & PERM_SUID_SGID) > 0 ? POSIX_SUID : 0) + | ((group & PERM_SUID_SGID) > 0 ? POSIX_SGID : 0) | (file.getPerms() & POSIX_STICKY) + | ((owner & PERM_READ) > 0 ? POSIX_OWNER_READ : 0) + | ((owner & PERM_WRITE) > 0 ? POSIX_OWNER_WRITE : 0) + | ((owner & PERM_EXECUTE) > 0 ? POSIX_OWNER_EXEC : 0) + | ((group & PERM_READ) > 0 ? POSIX_GROUP_READ : 0) + | ((group & PERM_WRITE) > 0 ? POSIX_GROUP_WRITE : 0) + | ((group & PERM_EXECUTE) > 0 ? POSIX_GROUP_EXEC : 0) + | ((other & PERM_READ) > 0 ? POSIX_OTHER_READ : 0) + | ((other & PERM_WRITE) > 0 ? POSIX_OTHER_WRITE : 0) + | ((other & PERM_EXECUTE) > 0 ? POSIX_OTHER_EXEC : 0); + + file.setPerms(posixRights); + + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + } catch (Exception exc) { + throw new MRCException(exc); + } finally { + if (acl != null) + acl.destroy(); + } + + } + + @Override + public Map getACLEntries(StorageManager sMan, FileMetadata file) throws MRCException { + + try { + DatabaseResultSet acl = sMan.getACL(file.getId()); + Map aclMap = Converter.aclToMap(acl, this); + acl.destroy(); + return aclMap; + + } catch (Exception exc) { + throw new MRCException(exc); + } + } + + @Override + public void removeACLEntries(StorageManager sMan, FileMetadata file, long parentId, List entities, + AtomicDBUpdate update) throws MRCException, UserException { + + Map entries = new HashMap(); + for (Object entity : entities) + entries.put((String) entity, null); + + updateACLEntries(sMan, file, parentId, entries, update); + } + + @Override + public void setPosixAccessRights(StorageManager sMan, FileMetadata file, long parentId, String userId, + List groupIds, int posixAccessRights, boolean superUser, AtomicDBUpdate update) + throws MRCException, UserException { + + DatabaseResultSet aclSet = null; + try { + + // clear SGID flag if file's owning group is not contained in user + // groups + if ((posixAccessRights & POSIX_SGID) > 0 && !superUser && !file.isDirectory() + && !groupIds.contains(file.getOwningGroupId())) + posixAccessRights ^= POSIX_SGID; + + // update the permissions value + file.setPerms(posixAccessRights); + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + // check whether an ACL is defined; if not, return; + // otherwise, change the ACL entries accordingly + aclSet = sMan.getACL(file.getId()); + if (!aclSet.hasNext()) + return; + + // determine rights mask for owner + short owr = (posixAccessRights & POSIX_OWNER_EXEC) > 0 ? EXEC_MASK : 0; + owr |= (posixAccessRights & POSIX_OWNER_WRITE) > 0 ? WRITE_MASK : 0; + owr |= (posixAccessRights & POSIX_OWNER_READ) > 0 ? READ_MASK : 0; + owr |= (posixAccessRights & POSIX_SUID) > 0 ? PERM_SUID_SGID : 0; + + // determine rights mask for group + short grr = (posixAccessRights & POSIX_GROUP_EXEC) > 0 ? EXEC_MASK : 0; + grr |= (posixAccessRights & POSIX_GROUP_WRITE) > 0 ? WRITE_MASK : 0; + grr |= (posixAccessRights & POSIX_GROUP_READ) > 0 ? READ_MASK : 0; + grr |= (posixAccessRights & POSIX_SGID) > 0 ? PERM_SUID_SGID : 0; + + // determine rights mask for others + short otr = (posixAccessRights & POSIX_OTHER_EXEC) > 0 ? EXEC_MASK : 0; + otr |= (posixAccessRights & POSIX_OTHER_WRITE) > 0 ? WRITE_MASK : 0; + otr |= (posixAccessRights & POSIX_OTHER_READ) > 0 ? READ_MASK : 0; + + sMan.setACLEntry(file.getId(), OWNER, owr, update); + sMan.setACLEntry(file.getId(), OWNER_GROUP, grr, update); + sMan.setACLEntry(file.getId(), MASK, grr, update); + sMan.setACLEntry(file.getId(), OTHER, otr, update); + + } catch (Exception exc) { + throw new MRCException(exc); + } finally { + if (aclSet != null) + aclSet.destroy(); + } + + } + + @Override + public int getPosixAccessRights(StorageManager sMan, FileMetadata file, String userId, List groupIds) + throws MRCException { + return !file.isDirectory() && file.isReadOnly() ? file.getPerms() & READ_ONLY_MASK : file.getPerms(); + } + + @Override + public ACLEntry[] getDefaultRootACL() { + return null; + } + + private static boolean checkIfAllowed(StorageManager sMan, String accessMode, short aclRights, FileMetadata file, + long parentId, String userId) throws DatabaseException { + + if (accessMode.length() == 1) { + switch (accessMode.charAt(0)) { + case 'r': + return (aclRights & PERM_READ) != 0; + case 'w': + return (aclRights & PERM_WRITE) != 0; + case 'x': + return (aclRights & PERM_EXECUTE) != 0; + case 'a': + return (aclRights & PERM_APPEND) != 0; + case 'c': + return (aclRights & PERM_CREATE) != 0; + case 't': + return (aclRights & PERM_TRUNCATE) != 0; + case 'd': + return (aclRights & PERM_DELETE) != 0; + case 'm': + + assert (parentId != 0); + + // get the parent directory + FileMetadata parent = sMan.getMetadata(parentId); + + assert (parent != null) : "cannot resolve metadata for file ID " + parentId; + + // evaluate the parent's sticky bit + if ((parent.getPerms() & POSIX_STICKY) != 0) + return parent.getOwnerId().equals(userId) || file.getOwnerId().equals(userId); + else + return true; + } + + } else if (accessMode.length() == 2) { + if (accessMode.equals("rw") && (aclRights & PERM_READ) != 0 & (aclRights & PERM_WRITE) != 0) + return true; + else if (accessMode.equals("ga") && (aclRights & PERM_GFS_APPEND) != 0) + return true; + else if (accessMode.equals("sr") && (aclRights & PERM_STRICT_READ) != 0) + return true; + } + + return false; + } + + private static short toRelativeACLRights(int posixRights, FileMetadata file, long parentId, String userId, + List groupIDs) { + + // owner is relevant + if (userId.equals(file.getOwnerId())) { + + short tmp = 0; + + if ((posixRights & POSIX_OWNER_EXEC) > 0) + tmp |= EXEC_MASK; + if ((posixRights & POSIX_OWNER_WRITE) > 0) + tmp |= WRITE_MASK; + if ((posixRights & POSIX_OWNER_READ) > 0) + tmp |= READ_MASK; + + return tmp; + } + + // owning group is relevant + else if (groupIDs.contains(file.getOwningGroupId())) { + + short tmp = 0; + + if ((posixRights & POSIX_GROUP_EXEC) > 0) + tmp |= EXEC_MASK; + if ((posixRights & POSIX_GROUP_WRITE) > 0) + tmp |= WRITE_MASK; + if ((posixRights & POSIX_GROUP_READ) > 0) + tmp |= READ_MASK; + + return tmp; + } + + // other is relevant + else { + + short tmp = 0; + + if ((posixRights & POSIX_OTHER_EXEC) > 0) + tmp |= EXEC_MASK; + if ((posixRights & POSIX_OTHER_WRITE) > 0) + tmp |= WRITE_MASK; + if ((posixRights & POSIX_OTHER_READ) > 0) + tmp |= READ_MASK; + + return tmp; + } + + } + + private static ACLEntry getRelevantACLEntry(StorageManager sMan, FileMetadata file, long parentId, String userId, + List groupIds, String accessMode) throws UserException, DatabaseException { + + // if the user ID is the owner, check access according to the rights + // associated with the owner entry + if (file.getOwnerId().equals(userId)) { + + ACLEntry entry = sMan.getACLEntry(file.getId(), OWNER); + assert (entry != null); + + return entry; + } + + // if the user ID refers to a named user, check access according to + // the corresponding user rights + ACLEntry entry = sMan.getACLEntry(file.getId(), NAMED_USER_PREFIX + userId); + if (entry != null) + return entry; + + boolean groupFound = false; + + // if a group ID refers to the owning group, check whether access is + // granted according to the owning group rights + for (String groupId : groupIds) { + if (groupId.equals(file.getOwningGroupId())) { + + entry = sMan.getACLEntry(file.getId(), OWNER_GROUP); + if (checkIfAllowed(sMan, accessMode, entry.getRights(), file, parentId, userId)) + return entry; + + groupFound = true; + } + } + + // if a group ID refers to any of the named groups, check whether + // access is granted according to the corresponding group rights + for (String groupId : groupIds) { + + entry = sMan.getACLEntry(file.getId(), NAMED_GROUP_PREFIX + groupId); + + if (entry != null) { + + if (checkIfAllowed(sMan, accessMode, entry.getRights(), file, parentId, userId)) + return entry; + + groupFound = true; + } + } + + // if there was a matching entry but access was not granted, access + // is denied + if (groupFound) + accessDenied(sMan.getVolumeInfo().getId(), file, accessMode, userId); + + entry = sMan.getACLEntry(file.getId(), OTHER); + assert (entry != null); + return entry; + } + + protected static Map convertToACL(long mode) throws MRCException { + + try { + + Map aclMap = new HashMap(); + + // determine the sticky bit + long stickyBit = (mode & (1 << 9)) > 0 ? 1 : 0; + if (stickyBit != 0) + aclMap.put(STICKY_BIT, stickyBit); + + // determine ACL for owner + long owr = (mode & POSIX_OWNER_EXEC) > 0 ? EXEC_MASK : 0; + owr |= (mode & POSIX_OWNER_WRITE) > 0 ? WRITE_MASK : 0; + owr |= (mode & POSIX_OWNER_READ) > 0 ? READ_MASK : 0; + owr |= (mode & POSIX_SUID) > 0 ? PERM_SUID_SGID : 0; + aclMap.put(OWNER, owr); + + // determine ACL for group + long grr = (mode & POSIX_GROUP_EXEC) > 0 ? EXEC_MASK : 0; + grr |= (mode & POSIX_GROUP_WRITE) > 0 ? WRITE_MASK : 0; + grr |= (mode & POSIX_GROUP_READ) > 0 ? READ_MASK : 0; + grr |= (mode & POSIX_SGID) > 0 ? PERM_SUID_SGID : 0; + aclMap.put(OWNER_GROUP, grr); + + // determine ACL for others + long otr = (mode & POSIX_OTHER_EXEC) > 0 ? EXEC_MASK : 0; + otr |= (mode & POSIX_OTHER_WRITE) > 0 ? WRITE_MASK : 0; + otr |= (mode & POSIX_OTHER_READ) > 0 ? READ_MASK : 0; + aclMap.put(OTHER, otr); + + return aclMap; + + } catch (Exception exc) { + throw new MRCException(exc); + } + } + + private static void accessDenied(String volumeId, FileMetadata file, String accessMode, String userId) + throws UserException { + + throw new UserException(POSIXErrno.POSIX_ERROR_EACCES, "access denied, volumeId = " + volumeId + ", file = " + + file.getId() + " (" + file.getFileName() + "), accessMode = \"" + accessMode + + "\", requestor's uid = \"" + userId + "\", owner = \"" + file.getOwnerId() + "\""); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/ac/VolumeACLFileAccessPolicy.java b/java/servers/src/org/xtreemfs/mrc/ac/VolumeACLFileAccessPolicy.java new file mode 100644 index 0000000..1d58841 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/ac/VolumeACLFileAccessPolicy.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.ac; + +import java.util.List; +import java.util.Map; + +import org.xtreemfs.mrc.MRCException; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; + +/** + * This policy grants or denies access based on immutable volume ACLs. Note that + * ACLs are no POSIX ACLs. A 'default' entry may be defined that is valid for + * any user except for those having a user-specific entry. + * + * @author stender + * + */ +public class VolumeACLFileAccessPolicy extends POSIXFileAccessPolicy { + + public static final short POLICY_ID = (short) AccessControlPolicyType.ACCESS_CONTROL_POLICY_VOLUME + .getNumber(); + + @Override + public void checkPermission(StorageManager sMan, FileMetadata file, long parentId, String userId, + List groupIds, String accessMode) throws UserException, MRCException { + + try { + FileMetadata rootDir = sMan.getMetadata(0, sMan.getVolumeInfo().getName()); + super.checkPermission(sMan, rootDir, parentId, userId, groupIds, accessMode); + } catch (DatabaseException exc) { + throw new MRCException(exc); + } + + } + + @Override + public void checkSearchPermission(StorageManager sMan, PathResolver res, String userId, + List groupIds) throws UserException, MRCException { + + try { + FileMetadata rootDir = sMan.getMetadata(0, sMan.getVolumeInfo().getName()); + super.checkPermission(sMan, rootDir, 0, userId, groupIds, AM_EXECUTE); + } catch (UserException exc) { + throw exc; + } catch (Exception exc) { + throw new MRCException(exc); + } + } + + @Override + public int getPosixAccessRights(StorageManager sMan, FileMetadata file, String userId, + List groupIds) throws MRCException { + + try { + FileMetadata rootDir = sMan.getMetadata(0, sMan.getVolumeInfo().getName()); + return super.getPosixAccessRights(sMan, rootDir, userId, groupIds); + } catch (DatabaseException e) { + throw new MRCException(e); + } + } + + @Override + public void setPosixAccessRights(StorageManager sMan, FileMetadata file, long parentId, String userId, + List groupIds, int posixAccessRights, boolean superUser, AtomicDBUpdate update) + throws MRCException { + + try { + FileMetadata rootDir = sMan.getMetadata(0, sMan.getVolumeInfo().getName()); + super.setPosixAccessRights(sMan, rootDir, parentId, userId, groupIds, posixAccessRights, + superUser, update); + } catch (Exception exc) { + throw new MRCException(exc); + } + } + + @Override + public Map getACLEntries(StorageManager sMan, FileMetadata file) throws MRCException { + + try { + FileMetadata rootDir = sMan.getMetadata(0, sMan.getVolumeInfo().getName()); + return super.getACLEntries(sMan, rootDir); + } catch (DatabaseException e) { + throw new MRCException(e); + } + } + + @Override + public void updateACLEntries(StorageManager sMan, FileMetadata file, long parentId, + Map entries, AtomicDBUpdate update) throws MRCException, UserException { + + try { + FileMetadata rootDir = sMan.getMetadata(0, sMan.getVolumeInfo().getName()); + super.updateACLEntries(sMan, rootDir, parentId, entries, update); + } catch (DatabaseException e) { + throw new MRCException(e); + } + } + + @Override + public void removeACLEntries(StorageManager sMan, FileMetadata file, long parentId, + List entities, AtomicDBUpdate update) throws MRCException, UserException { + + try { + FileMetadata rootDir = sMan.getMetadata(0, sMan.getVolumeInfo().getName()); + super.removeACLEntries(sMan, rootDir, parentId, entities, update); + } catch (DatabaseException e) { + throw new MRCException(e); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/ac/YesToAnyoneFileAccessPolicy.java b/java/servers/src/org/xtreemfs/mrc/ac/YesToAnyoneFileAccessPolicy.java new file mode 100644 index 0000000..980ad61 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/ac/YesToAnyoneFileAccessPolicy.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.ac; + +import java.util.List; +import java.util.Map; + +import org.xtreemfs.mrc.MRCException; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.metadata.ACLEntry; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; + +/** + * This policy will grant access to anyone. It does not allow changeing access + * rights, any ACLs set on files or volumes will be ignored. + * + * @author stender + * + */ +public class YesToAnyoneFileAccessPolicy implements FileAccessPolicy { + + public static final short POLICY_ID = (short) AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL + .getNumber(); + + @Override + public String translateAccessFlags(int accessMode) { + return null; + } + + @Override + public String translatePermissions(int permissions) { + return null; + } + + @Override + public void checkPermission(StorageManager sMan, FileMetadata file, long parentId, String userId, + List groupIds, String accessMode) { + // do nothing + } + + @Override + public void checkSearchPermission(StorageManager sMan, PathResolver res, String userId, + List groupIds) { + // do nothing + } + + @Override + public void checkPrivilegedPermissions(StorageManager sMan, FileMetadata file, String userId, + List groupIds) { + // do nothing + } + + @Override + public int getPosixAccessRights(StorageManager sMan, FileMetadata file, String userId, + List groupIds) { + return 511; // rwxrwxrwx + } + + @Override + public void setPosixAccessRights(StorageManager sMan, FileMetadata file, long parentId, String userId, + List groupIds, int posixAccessRights, boolean superUser, AtomicDBUpdate update) { + // do nothing + } + + @Override + public Map getACLEntries(StorageManager sMan, FileMetadata file) throws MRCException { + return null; + } + + @Override + public void updateACLEntries(StorageManager sMan, FileMetadata file, long parentId, + Map entries, AtomicDBUpdate update) throws MRCException, UserException { + // do nothing + } + + @Override + public void removeACLEntries(StorageManager sMan, FileMetadata file, long parentId, + List entities, AtomicDBUpdate update) throws MRCException, UserException { + // do nothing + } + + @Override + public ACLEntry[] getDefaultRootACL() { + return null; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/AtomicDBUpdate.java b/java/servers/src/org/xtreemfs/mrc/database/AtomicDBUpdate.java new file mode 100644 index 0000000..c3a91b0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/AtomicDBUpdate.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database; + +/** + * Defines a collection of database updates that have to be executed atomically. + * + * @author stender + * + */ +public interface AtomicDBUpdate { + + /** + * Adds a new update to the collection. + * + * @param update + * an array of objects describing the update + */ + public void addUpdate(Object... update); + + /** + * Atomically executes all updates. + * + * @throws DatabaseException + */ + public void execute() throws DatabaseException; + +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/DBAccessResultListener.java b/java/servers/src/org/xtreemfs/mrc/database/DBAccessResultListener.java new file mode 100644 index 0000000..6cd9594 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/DBAccessResultListener.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database; + +public interface DBAccessResultListener { + + public void finished(T result, Object context); + + public void failed(Throwable error, Object context); +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/DatabaseException.java b/java/servers/src/org/xtreemfs/mrc/database/DatabaseException.java new file mode 100644 index 0000000..fd54b8e --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/DatabaseException.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database; + +public class DatabaseException extends Exception { + private static final long serialVersionUID = -8079959463034197259L; + + public enum ExceptionType { + INTERNAL_DB_ERROR, FILE_EXISTS, WRONG_DB_VERSION, NOT_ALLOWED, REDIRECT, REPLICATION + } + + private ExceptionType type; + private Object attachment = null; + + public DatabaseException(ExceptionType type) { + this.type = type; + } + + public DatabaseException(ExceptionType type, Object attachment) { + this.type = type; + this.attachment = attachment; + } + + public DatabaseException(String message, ExceptionType type) { + super(message); + this.type = type; + } + + public DatabaseException(Throwable cause) { + super(cause); + this.type = ExceptionType.INTERNAL_DB_ERROR; + } + + public DatabaseException(String message, Throwable cause) { + super(message, cause); + } + + public ExceptionType getType() { + return type; + } + + public Object getAttachment() { + return this.attachment; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/DatabaseResultSet.java b/java/servers/src/org/xtreemfs/mrc/database/DatabaseResultSet.java new file mode 100644 index 0000000..966a0da --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/DatabaseResultSet.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database; + +import java.util.Iterator; + +/** + * A result set for MRC database queries. + * + * @author stender + * + * @param + */ +public interface DatabaseResultSet extends Iterator { + + /** + * Frees all resources attached to the result set. + */ + public void destroy(); + +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/ReplicationManager.java b/java/servers/src/org/xtreemfs/mrc/database/ReplicationManager.java new file mode 100644 index 0000000..0acba27 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/ReplicationManager.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2009-2011 by Felix Langner, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database; + +/** + * Interface to manipulate the replication-setup of the MRC DB. + * + * @author flangner + * @since 10/19/2009 + */ + +public interface ReplicationManager { + + /** + *

    + * Changes the database replication master. Uses this, if + * your {@link BabuDBRequestListener} recognizes an failure due + * the replication and want to help BabuDB to recognize it. + *

    + */ + public void manualFailover(); +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/StorageManager.java b/java/servers/src/org/xtreemfs/mrc/database/StorageManager.java new file mode 100644 index 0000000..d11ae33 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/StorageManager.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database; + +import java.io.BufferedWriter; +import java.io.IOException; + +import org.xtreemfs.mrc.metadata.ACLEntry; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.ReplicationPolicy; +import org.xtreemfs.mrc.metadata.StripingPolicy; +import org.xtreemfs.mrc.metadata.XAttr; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.utils.Path; + +public interface StorageManager { + + /** + * userID for system attributes; can be used w/ getXAttr() and + * getXAttrs() to retrieve extended attributes assigned by the + * system + */ + public static final String SYSTEM_UID = ""; + + /** + * userID for global attributes; can be used w/ getXAttr() and + * getXAttrs() to retrieve extended attributes visible to any + * user + */ + public static final String GLOBAL_ID = "*"; + + /** + * key prefix for XtreemFS system attributes + */ + public static final String SYS_ATTR_KEY_PREFIX = "xtreemfs."; + + // file ID counter operations + + public long getNextFileId() throws DatabaseException; + + public void setLastFileId(long fileId, AtomicDBUpdate update) throws DatabaseException; + + // entity generators + + public AtomicDBUpdate createAtomicDBUpdate(DBAccessResultListener listener, Object context) + throws DatabaseException; + + public ACLEntry createACLEntry(long fileId, String entity, short rights); + + public XLoc createXLoc(StripingPolicy stripingPolicy, String[] osds, int replFlags); + + public XLocList createXLocList(XLoc[] replicas, String replUpdatePolicy, int version); + + public StripingPolicy createStripingPolicy(String pattern, int stripeSize, int width); + + public XAttr createXAttr(long fileId, String owner, String key, byte[] value); + + public void dumpDB(BufferedWriter xmlWriter) throws DatabaseException, IOException; + + // handling volumes + + public VolumeInfo getVolumeInfo(); + + public void addVolumeChangeListener(VolumeChangeListener listener); + + public void deleteDatabase() throws DatabaseException; + + // handling XAttrs + + public void setXAttr(long fileId, String uid, String key, byte[] value, AtomicDBUpdate update) + throws DatabaseException; + + public byte[] getXAttr(long fileId, String uid, String key) throws DatabaseException; + + public DatabaseResultSet getXAttrs(long fileId) throws DatabaseException; + + public DatabaseResultSet getXAttrs(long fileId, String uid) throws DatabaseException; + + // handling ACLs + + public void setACLEntry(long fileId, String entity, Short rights, AtomicDBUpdate update) + throws DatabaseException; + + public ACLEntry getACLEntry(long fileId, String entity) throws DatabaseException; + + public DatabaseResultSet getACL(long fileId) throws DatabaseException; + + // creating, linking, modifying and deleting files/directories + + public FileMetadata createDir(long fileId, long parentId, String fileName, int atime, int ctime, + int mtime, String userId, String groupId, int perms, long w32Attrs, AtomicDBUpdate update) + throws DatabaseException; + + public FileMetadata createFile(long fileId, long parentId, String fileName, int atime, int ctime, + int mtime, String userId, String groupId, int perms, long w32Attrs, long size, boolean readOnly, + int epoch, int issEpoch, AtomicDBUpdate update) throws DatabaseException; + + public FileMetadata createSymLink(long fileId, long parentId, String fileName, int atime, int ctime, + int mtime, String userId, String groupId, String ref, AtomicDBUpdate update) throws DatabaseException; + + public void link(FileMetadata metadata, long newParentId, String newFileName, AtomicDBUpdate update) + throws DatabaseException; + + public void setMetadata(FileMetadata metadata, byte type, AtomicDBUpdate update) throws DatabaseException; + + public void setDefaultStripingPolicy(long fileId, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy defaultSp, + AtomicDBUpdate update) throws DatabaseException; + + public void setVolumeQuota(long quota, AtomicDBUpdate update) throws DatabaseException; + + public void setDefaultReplicationPolicy(long fileId, ReplicationPolicy defaultRp, + AtomicDBUpdate update) throws DatabaseException; + + public short unlink(long parentId, String fileName, AtomicDBUpdate update) throws DatabaseException; + + public short delete(long parentId, String fileName, AtomicDBUpdate update) throws DatabaseException; + + // retrieving metadata + + public FileMetadata[] resolvePath(Path path) throws DatabaseException; + + public FileMetadata getMetadata(long fileId) throws DatabaseException; + + public FileMetadata getMetadata(long parentId, String fileName) throws DatabaseException; + + public StripingPolicy getDefaultStripingPolicy(long fileId) throws DatabaseException; + + public ReplicationPolicy getDefaultReplicationPolicy(long fileId) throws DatabaseException; + + public long getVolumeQuota() throws DatabaseException; + + public String getSoftlinkTarget(long fileId) throws DatabaseException; + + public DatabaseResultSet getChildren(long parentId, int seen, int num) throws DatabaseException; + + // handling snapshots + + public void createSnapshot(String snapName, long parentId, String dirName, boolean recursive) + throws DatabaseException; + + public void deleteSnapshot(String snapName) throws DatabaseException; + + public String[] getAllSnapshots() throws DatabaseException; + +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/VolumeChangeListener.java b/java/servers/src/org/xtreemfs/mrc/database/VolumeChangeListener.java new file mode 100644 index 0000000..0371396 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/VolumeChangeListener.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + + +package org.xtreemfs.mrc.database; + + +public interface VolumeChangeListener { + + public void volumeChanged(VolumeInfo vol); + + public void volumeDeleted(String volumeId); + + public void attributeSet(String volumeId, String key, String value); + +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/VolumeInfo.java b/java/servers/src/org/xtreemfs/mrc/database/VolumeInfo.java new file mode 100644 index 0000000..59fa5cd --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/VolumeInfo.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database; + +/** + * This interface defines how volume-related metadata is accessed. + * + * XtreemFS file system content is arranged in volumes, with each volume having + * its own directory tree. A volume has a globally unique name and id. + * + * A volume holds different policies. The OSD policy determines which OSDs may + * by default be allocated to files. The behavior of this policy may depend on + * the policy's arguments, which are represented by an opaque string. The access + * control policy defines the circumstances under which users are allowed to + * access the volume. + * + * @author stender + * + */ +public interface VolumeInfo { + + /** + * Returns the volume's ID + * + * @return the volume's ID + */ + public String getId(); + + /** + * Returns the volume's name. + * + * @return the volume's name + */ + public String getName(); + + /** + * Returns the volume's OSD selection policy. + * + * @return the volume's OSD selection policy + */ + public short[] getOsdPolicy(); + + /** + * Returns the volume's replica selection policy. + * + * @return the volume's replica selection policy + */ + public short[] getReplicaPolicy(); + + /** + * Returns the volume's access control policy ID. + * + * @return the volume's access control policy ID. + */ + public short getAcPolicyId(); + + /** + * Returns the current approximate size of all files in the volume in bytes. + * + * @return the volume's approximate size + */ + public long getVolumeSize() throws DatabaseException; + + /** + * Returns the volume's quota in bytes. + * + * @return the volume's quota in bytes + */ + public long getVolumeQuota() throws DatabaseException; + /** + * Returns the number of files currently stored in the volume. + * + * @return the number of files + */ + public long getNumFiles() throws DatabaseException; + + /** + * Returns the number of directories currently stored in the volume. + * + * @return the number of directories + */ + public long getNumDirs() throws DatabaseException; + + /** + * Checks whether this volume refers to a snapshot. + * + * @return true, if the volume refers to a snapshot, + * false, otherwise + */ + public boolean isSnapVolume() throws DatabaseException; + + /** + * Checks whether snapshots are allowed for this volume. + * + * @return true, if the volume allows snapshots, + * false, otherwise + */ + public boolean isSnapshotsEnabled() throws DatabaseException; + + /** + * Returns the time at which the volume was created in milliseconds since 1970 + * + * @return the creation time stamp in milliseconds since 1970 + */ + public long getCreationTime() throws DatabaseException; + + /** + * Sets the volume's OSD selection policy. + * + * @param osdPolicy + * the new OSD selection policy for the volume + */ + public void setOsdPolicy(short[] osdPolicy, AtomicDBUpdate update) throws DatabaseException; + + /** + * Sets the volume's replica selection policy. + * + * @param replicaPolicy + * the new replica selection policy for the volume + */ + public void setReplicaPolicy(short[] replicaPolicy, AtomicDBUpdate update) throws DatabaseException; + + /** + * Specifies whether snapshots may be created on this volume. + * + * @param allowSnaps + * a flag specifying whether snapshots may be created + */ + public void setAllowSnaps(boolean allowSnaps, AtomicDBUpdate update) throws DatabaseException; + + /** + * Set the volume's quota. + * + * @param quota + * quota in bytes + * @throws DatabaseException + */ + public void setVolumeQuota(long quota, AtomicDBUpdate update) throws DatabaseException; + + /** + * Adds diff to the current volume size. + * + * @param diff + * the difference between the new and the old volume size + */ + public void updateVolumeSize(long diff, AtomicDBUpdate update) throws DatabaseException; + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/database/VolumeManager.java b/java/servers/src/org/xtreemfs/mrc/database/VolumeManager.java new file mode 100644 index 0000000..5e7d110 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/VolumeManager.java @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; + +public interface VolumeManager { + + public static final short[] DEFAULT_OSD_POLICY = { + (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_FILTER_DEFAULT.getNumber(), + (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_RANDOM.getNumber() }; + + public static final short[] DEFAULT_REPL_POLICY = {}; + + public static final boolean DEFAULT_ALLOW_SNAPS = false; + + public static final char SNAPSHOT_SEPARATOR = '@'; + + /** + * Initializes the volume manager, including all volume databases. + * + * @throws DatabaseException + */ + public void init() throws DatabaseException; + + /** + * Shuts down the volume manager. + */ + public void shutdown(); + + /** + * Creates a new volume. + * + * @param faMan + * the file access manager + * @param volumeId + * the volume ID + * @param volumeName + * the volume name + * @param fileAccessPolicyId + * the access policy + * @param ownerId + * the owner ID + * @param owningGroupId + * the owning group ID + * @param defaultStripingPolicy + * the default striping policy + * @param initialAccessMode + * the initial access mode for the volume's root directory + * @param volumeQuota + * the volume quota + * @param attrs + * a list of user-defined attributes for the volume + * @throws UserException + * @throws DatabaseException + */ + public void createVolume(FileAccessManager faMan, String volumeId, String volumeName, + short fileAccessPolicyId, String ownerId, String owningGroupId, StripingPolicy defaultStripingPolicy, + int initialAccessMode, + long volumeQuota, List attrs) throws UserException, DatabaseException; + + /** + * Checks whether a volume with the given name is known locally. + * + * @param volumeName + * the volume name + * @return true, if the volume is known locally, + * false, otherwise + */ + public boolean hasVolume(String volumeName) throws DatabaseException; + + /** + * Checks whether a volume with the given ID is known locally. + * + * @param volumeId + * the volume ID + * @return true, if the volume is known locally, + * false, otherwise + */ + public boolean hasVolumeWithId(String volumeId) throws DatabaseException; + + /** + * Deletes a volume. + * + * @param volumeName + * the volume name + * @throws UserException + * @throws DatabaseException + */ + public void deleteVolume(String volumeName, DBAccessResultListener listener, Object context) + throws DatabaseException, UserException; + + /** + * Returns the storage manager for a given volume. + * + * @param volumeId + * the volume ID + * @return the storage manager + * @throws UserException + * if the volume does not exist + */ + public StorageManager getStorageManager(String volumeId) throws UserException; + + /** + * Returns the storage manager for a given volume. + * + * @param volumeName + * the volume name + * @return the storage manager + * @throws UserException + * if the volume does not exist + */ + public StorageManager getStorageManagerByName(String volumeName) throws UserException; + + /** + * Returns a collection of all storage managers. + * + * @return a collection of all storage managers + */ + public Collection getStorageManagers(); + + /** + * Enforces a database checkpoint and blocks until the checkpoint is + * complete. + */ + public void checkpointDB() throws DatabaseException; + + /** + * Generates a new unique volume ID. + * + * @return a unique volume ID + */ + public String newVolumeId(); + + /** + * Adds a new listener to all volumes that responds to volume changes. + * + * @param listener + * the listener to add + */ + public void addVolumeChangeListener(VolumeChangeListener listener); + + /** + * Creates a new snapshot of the given directory in the given volume. + * + * @param volumeId + * the volume ID + * @param snapName + * the name to be assigned to the new snapshot + * @param parentId + * the directory's parent directory ID + * @param dir + * the directory + * @param recursive + * specifies whether the snapshot will only contain the nested + * files in the directory, or the whole tree with all + * subdirectories + * @throws UserException + * if the volume does not exist, or the snapshot exists already + * @throws DatabaseException + * if a database error occurs + */ + public void createSnapshot(String volumeId, String snapName, long parentId, FileMetadata dir, + boolean recursive) throws UserException, DatabaseException; + + /** + * Deletes the snapshot with the given name in the given directory. + * + * @param volumeId + * the volume ID + * @param dir + * the directory + * @param snapName + * the name of the snapshot to delete + * @throws UserException + * if the volume does not exist, or the snapshot does not exist + * @throws DatabaseException + * if a database error occurs + */ + public void deleteSnapshot(String volumeId, FileMetadata dir, String snapName) throws UserException, + DatabaseException; + + /** + * Resturns a collection of timestamps for all snapshots of the given + * volume. + * + * @param volName + * the volume name + * @return a collection of snapshot timestamps + * @throws UserException + * if the volume does not exist, or the snapshot does not exist + * @throws DatabaseException + * if a database error occurs + */ + public Collection getSnapTimestamps(String volName) throws UserException, DatabaseException; + + /** + * Returns a version string for the database backend. + * + * @return the database version of the backend + */ + public String getDBVersion(); + + /** + * Returns the runtime status of the internal database as a collection of key-value pairs. + * + * @return the database status + */ + public Map getDBStatus(); + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/database/babudb/AtomicBabuDBSnapshotUpdate.java b/java/servers/src/org/xtreemfs/mrc/database/babudb/AtomicBabuDBSnapshotUpdate.java new file mode 100644 index 0000000..cf80b7b --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/babudb/AtomicBabuDBSnapshotUpdate.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database.babudb; + +import org.xtreemfs.babudb.api.database.DatabaseRequestListener; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; + +public class AtomicBabuDBSnapshotUpdate implements AtomicDBUpdate { + + private DatabaseRequestListener listener; + + private Object context; + + public AtomicBabuDBSnapshotUpdate(DatabaseRequestListener listener, Object context) + throws BabuDBException { + + this.listener = listener; + this.context = context; + } + + @Override + public void addUpdate(Object... update) { + } + + @Override + public void execute() throws DatabaseException { + if (listener != null) + listener.finished(null, context); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/babudb/AtomicBabuDBUpdate.java b/java/servers/src/org/xtreemfs/mrc/database/babudb/AtomicBabuDBUpdate.java new file mode 100644 index 0000000..fc946b6 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/babudb/AtomicBabuDBUpdate.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database.babudb; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.DatabaseInsertGroup; +import org.xtreemfs.babudb.api.database.DatabaseRequestListener; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; + +public class AtomicBabuDBUpdate implements AtomicDBUpdate { + + private DatabaseInsertGroup ig; + + private Database database; + + private DatabaseRequestListener listener; + + private Object context; + + // private List updates; + // + // private String dbName; + + public AtomicBabuDBUpdate(Database database, DatabaseRequestListener listener, Object context) + throws BabuDBException { + + ig = database.createInsertGroup(); + + this.database = database; + this.listener = listener; + this.context = context; + + // updates = new LinkedList(); + // this.dbName = dbName; + } + + @Override + public void addUpdate(Object... update) { + ig.addInsert((Integer) update[0], (byte[]) update[1], (byte[]) update[2]); + // updates.add(update); + } + + @Override + public void execute() throws DatabaseException { + try { + + // checkDBConsistency(); + + if (listener != null) { + database.insert(ig, context).registerListener(listener); + } else + database.insert(ig, context).get(); + + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + public String toString() { + return ig.toString(); + } + + // private void checkDBConsistency() { + // + // Map prefixEntries = new HashMap(); + // + // for (Object[] update : updates) { + // if ((Integer) update[0] == BabuDBStorageManager.FILE_INDEX) { + // + // byte[] bytes = (byte[]) update[1]; + // byte type = bytes[bytes.length - 1]; + // + // byte[] prefix = new byte[bytes.length - 1]; + // System.arraycopy(bytes, 0, prefix, 0, prefix.length); + // + // byte[][] entry = prefixEntries.get(new String(prefix)); + // if (entry == null) { + // + // entry = new byte[3][]; + // prefixEntries.put(new String(prefix), entry); + // + // Iterator> entries = null; + // try { + // entries = database + // .directPrefixLookup(dbName, BabuDBStorageManager.FILE_INDEX, prefix); + // } catch (BabuDBException e) { + // e.printStackTrace(); + // System.exit(1); + // } + // + // while (entries.hasNext()) { + // byte[] key = entries.next().getKey(); + // byte entryType = key[key.length - 1]; + // entry[entryType] = key; + // } + // + // } + // + // // do the update in memory + // entry[type] = update[2] == null ? null : (byte[]) update[1]; + // } + // } + // + // // check the data structure + // for (byte[][] entry : prefixEntries.values()) { + // if ((entry[0] != null || entry[2] != null) && entry[1] == null) { + // System.err.println("CORRUPTED DATABASE!"); + // System.err.println("updated entry:"); + // for (int i = 0; i < entry.length; i++) + // System.out.println(i + ": " + Arrays.toString(entry[i])); + // + // System.err.println("all updates:"); + // for (Object[] update : updates) { + // System.out.println(update[0] + ": " + Arrays.toString((byte[]) update[1]) + // + " = " + // + Arrays.toString((byte[]) update[2])); + // } + // + // try { + // throw new Exception(); + // } catch (Exception exc) { + // exc.printStackTrace(); + // } + // + // System.exit(1); + // } + // } + // + // } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBRequestListenerWrapper.java b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBRequestListenerWrapper.java new file mode 100644 index 0000000..422d9f9 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBRequestListenerWrapper.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database.babudb; + +import org.xtreemfs.babudb.api.database.DatabaseRequestListener; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.mrc.database.DBAccessResultListener; + +/** + * @author stender + * @parma + */ +public class BabuDBRequestListenerWrapper implements DatabaseRequestListener { + + private DBAccessResultListener listener; + + public BabuDBRequestListenerWrapper(DBAccessResultListener listener) { + this.listener = listener; + } + + /* + * (non-Javadoc) + * @see org.xtreemfs.babudb.BabuDBRequestListener#failed(org.xtreemfs.babudb.BabuDBException, java.lang.Object) + */ + @Override + public void failed(BabuDBException arg0, Object arg1) { + listener.failed(arg0,arg1); + } + + /* + * (non-Javadoc) + * @see org.xtreemfs.babudb.BabuDBRequestListener#finished(java.lang.Object, java.lang.Object) + */ + @Override + public void finished(T arg0, Object arg1) { + listener.finished(arg0, arg1); + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBSnapshotStorageManager.java b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBSnapshotStorageManager.java new file mode 100644 index 0000000..fb139ce --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBSnapshotStorageManager.java @@ -0,0 +1,580 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database.babudb; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Map.Entry; + +import org.xtreemfs.babudb.api.SnapshotManager; +import org.xtreemfs.babudb.api.database.DatabaseRO; +import org.xtreemfs.babudb.api.database.ResultSet; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DBAccessResultListener; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeChangeListener; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.babudb.BabuDBStorageHelper.ACLIterator; +import org.xtreemfs.mrc.database.babudb.BabuDBStorageHelper.XAttrIterator; +import org.xtreemfs.mrc.metadata.ACLEntry; +import org.xtreemfs.mrc.metadata.BufferBackedACLEntry; +import org.xtreemfs.mrc.metadata.BufferBackedFileMetadata; +import org.xtreemfs.mrc.metadata.BufferBackedXAttr; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.ReplicationPolicy; +import org.xtreemfs.mrc.metadata.StripingPolicy; +import org.xtreemfs.mrc.metadata.XAttr; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.DBAdminHelper; +import org.xtreemfs.mrc.utils.Path; + +public class BabuDBSnapshotStorageManager implements StorageManager { + + public static final int FILE_INDEX = 0; + + public static final int XATTRS_INDEX = 1; + + public static final int ACL_INDEX = 2; + + public static final int FILE_ID_INDEX = 3; + + public static final int VOLUME_INDEX = 4; + + public static final byte[] LAST_ID_KEY = { 'i' }; + + public static final byte[] VOL_SIZE_KEY = { 's' }; + + public static final byte[] NUM_FILES_KEY = { 'f' }; + + public static final byte[] NUM_DIRS_KEY = { 'd' }; + + private static final String DEFAULT_SP_ATTR_NAME = "sp"; + + private static final String DEFAULT_RP_ATTR_NAME = "rp"; + + private static final String LINK_TARGET_ATTR_NAME = "lt"; + + protected static final String OSD_POL_ATTR_NAME = "osdPol"; + + protected static final String REPL_POL_ATTR_NAME = "replPol"; + + protected static final String AC_POL_ATTR_NAME = "acPol"; + + protected static final String AUTO_REPL_FACTOR_ATTR_NAME = "replFactor"; + + protected static final String AUTO_REPL_FULL_ATTR_NAME = "replFull"; + + protected static final String VOL_ID_ATTR_NAME = "volId"; + + protected static final String VOL_QUOTA = "quota"; + + protected static final int[] ALL_INDICES = { FILE_INDEX, XATTRS_INDEX, + ACL_INDEX, FILE_ID_INDEX, VOLUME_INDEX }; + + private final DatabaseRO database; + + private final BabuDBSnapshotVolumeInfo volume; + + private final String volumeName; + + private final String rootDirName; + + private final long rootParentId; + + /** + * Instantiates a storage manager by creating a new database. + * + * @param sMan + * the snapshot manager + * @param volumeId + * the volume ID + */ + public BabuDBSnapshotStorageManager(SnapshotManager sMan, String volumeName, String volumeId, String snapName, + long timestamp, long rootParentId) throws DatabaseException { + + this.volumeName = volumeName; + + try { + database = sMan.getSnapshotDB(volumeId, snapName); + } catch (BabuDBException e) { + throw new DatabaseException("could not retrieve database for snapshot '" + snapName + "'", e); + } + + try { + this.rootParentId = rootParentId; + this.rootDirName = BabuDBStorageHelper.getRootDirName(database, rootParentId); + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + if (this.rootParentId == -1) + throw new DatabaseException("no root directory found", ExceptionType.INTERNAL_DB_ERROR); + + this.volume = new BabuDBSnapshotVolumeInfo(timestamp); + volume.init(this); + } + + @Override + public VolumeInfo getVolumeInfo() { + return volume; + } + + @Override + public DatabaseResultSet getACL(long fileId) throws DatabaseException { + + try { + + byte[] prefix = BabuDBStorageHelper.createACLPrefixKey(fileId, null); + ResultSet it = database.prefixLookup(ACL_INDEX, prefix, null).get(); + + return new ACLIterator(it); + + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public ACLEntry getACLEntry(long fileId, String entity) throws DatabaseException { + + try { + + byte[] key = BabuDBStorageHelper.createACLPrefixKey(fileId, entity); + byte[] value = database.lookup(ACL_INDEX, key, null).get(); + + return value == null ? null : new BufferBackedACLEntry(key, value); + + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public DatabaseResultSet getChildren(long parentId, int from, int num) throws DatabaseException { + + try { + return BabuDBStorageHelper.getChildren(database, parentId, from, num); + } catch (Exception exc) { + throw new DatabaseException(exc); + } + + } + + @Override + public StripingPolicy getDefaultStripingPolicy(long fileId) throws DatabaseException { + + try { + byte[] spBytes = getXAttr(fileId, SYSTEM_UID, DEFAULT_SP_ATTR_NAME); + if (spBytes == null) + return null; + + return Converter.stringToStripingPolicy(this, new String(spBytes)); + + } catch (DatabaseException exc) { + throw exc; + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public ReplicationPolicy getDefaultReplicationPolicy(long fileId) throws DatabaseException { + + try { + byte[] rpBytes = getXAttr(fileId, SYSTEM_UID, DEFAULT_RP_ATTR_NAME); + if (rpBytes == null) + return null; + + return Converter.stringToReplicationPolicy(this, new String(rpBytes)); + + } catch (DatabaseException exc) { + throw exc; + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + public long getVolumeQuota() throws DatabaseException { + try { + byte[] quotaBytes = getXAttr(1, SYSTEM_UID, VOL_QUOTA); + if (quotaBytes == null) { + return 0; + } else { + return Long.valueOf(new String(quotaBytes)); + } + } catch (DatabaseException exc) { + throw exc; + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public FileMetadata getMetadata(long fileId) throws DatabaseException { + + ResultSet it = null; + try { + + // create the key for the file ID index lookup + byte[] key = BabuDBStorageHelper.createFileIdIndexKey(fileId, (byte) -1); + ByteBuffer.wrap(key).putLong(fileId); + + byte[][] valBufs = new byte[BufferBackedFileMetadata.NUM_BUFFERS][]; + + // retrieve the metadata from the link index + it = database.prefixLookup( + BabuDBSnapshotStorageManager.FILE_ID_INDEX, key, null).get(); + + while (it.hasNext()) { + + Entry curr = it.next(); + + int type = BabuDBStorageHelper.getType(curr.getKey(), + BabuDBSnapshotStorageManager.FILE_ID_INDEX); + + // if the value is a back link, resolve it + if (type == 3) { + + long parentId = ByteBuffer.wrap(curr.getValue()).getLong(); + String fileName = new String(curr.getValue(), 8, curr.getValue().length - 8); + + return getMetadata(parentId, fileName); + } + + valBufs[type] = curr.getValue(); + } + + // if not metadata was found for the file ID, return null + if (valBufs[FileMetadata.RC_METADATA] == null) + return null; + + byte[][] keyBufs = new byte[][] { null, + BabuDBStorageHelper.createFileKey(0, "", FileMetadata.RC_METADATA) }; + + // otherwise, a hard link target is contained in the index; create a + // new metadata object in this case + return new BufferBackedFileMetadata(keyBufs, valBufs, BabuDBSnapshotStorageManager.FILE_ID_INDEX); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } finally { + if (it != null) + it.free(); + } + } + + @Override + public FileMetadata getMetadata(final long parentId, final String fileName) throws DatabaseException { + + try { + return BabuDBStorageHelper.getMetadata(database, parentId, fileName); + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public String getSoftlinkTarget(long fileId) throws DatabaseException { + + try { + byte[] target = getXAttr(fileId, SYSTEM_UID, LINK_TARGET_ATTR_NAME); + return target == null? null: new String(target); + + } catch (DatabaseException exc) { + throw exc; + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public byte[] getXAttr(long fileId, String uid, String key) throws DatabaseException { + + ResultSet it = null; + try { + + // peform a prefix lookup + byte[] prefix = BabuDBStorageHelper.createXAttrPrefixKey(fileId, uid, key); + it = database.prefixLookup(XATTRS_INDEX, prefix, null).get(); + + // check whether the entry is the correct one + while (it.hasNext()) { + + Entry curr = it.next(); + BufferBackedXAttr xattr = new BufferBackedXAttr(curr.getKey(), curr.getValue()); + if (uid.equals(xattr.getOwner()) && key.equals(xattr.getKey())) + return xattr.getValue(); + } + + return null; + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } finally { + if (it != null) + it.free(); + } + } + + @Override + public DatabaseResultSet getXAttrs(long fileId) throws DatabaseException { + + try { + + // peform a prefix lookup + byte[] prefix = BabuDBStorageHelper.createXAttrPrefixKey(fileId, null, null); + ResultSet it = database.prefixLookup(XATTRS_INDEX, prefix, null).get(); + + return new XAttrIterator(it, null); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public DatabaseResultSet getXAttrs(long fileId, String uid) throws DatabaseException { + + try { + + // peform a prefix lookup + byte[] prefix = BabuDBStorageHelper.createXAttrPrefixKey(fileId, uid, null); + ResultSet it = database.prefixLookup(XATTRS_INDEX, prefix, null).get(); + + return new XAttrIterator(it, uid); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + + } + + @Override + public FileMetadata[] resolvePath(final Path path) throws DatabaseException { + + try { + FileMetadata[] md = new FileMetadata[path.getCompCount()]; + + long parentId = rootParentId; + for (int i = 0; i < md.length; i++) { + md[i] = BabuDBStorageHelper.getMetadata(database, parentId, i == 0 ? rootDirName : path + .getComp(i)); + if (md[i] == null || i < md.length - 1 && !md[i].isDirectory()) { + md[i] = null; + return md; + } + parentId = md[i].getId(); + } + + return md; + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + protected long getVolumeSize() throws DatabaseException { + try { + byte[] sizeBytes = BabuDBStorageHelper.getVolumeMetadata(database, VOL_SIZE_KEY); + return ByteBuffer.wrap(sizeBytes).getLong(0); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + protected long getNumFiles() throws DatabaseException { + try { + byte[] sizeBytes = BabuDBStorageHelper.getVolumeMetadata(database, NUM_FILES_KEY); + return ByteBuffer.wrap(sizeBytes).getLong(0); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + protected long getNumDirs() throws DatabaseException { + try { + byte[] sizeBytes = BabuDBStorageHelper.getVolumeMetadata(database, NUM_DIRS_KEY); + return ByteBuffer.wrap(sizeBytes).getLong(0); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public void addVolumeChangeListener(VolumeChangeListener listener) { + } + + @Override + public ACLEntry createACLEntry(long fileId, String entity, short rights) { + return null; + } + + @Override + public AtomicDBUpdate createAtomicDBUpdate(DBAccessResultListener listener, Object context) + throws DatabaseException { + + try { + return new AtomicBabuDBSnapshotUpdate(listener == null ? null + : new BabuDBRequestListenerWrapper(listener), context); + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public FileMetadata createDir(long fileId, long parentId, String fileName, int atime, int ctime, + int mtime, String userId, String groupId, int perms, long w32Attrs, AtomicDBUpdate update) + throws DatabaseException { + throwException(); + return null; + } + + @Override + public FileMetadata createFile(long fileId, long parentId, String fileName, int atime, int ctime, + int mtime, String userId, String groupId, int perms, long w32Attrs, long size, boolean readOnly, + int epoch, int issEpoch, AtomicDBUpdate update) throws DatabaseException { + throwException(); + return null; + } + + @Override + public void createSnapshot(String snapName, long parentId, String dirName, boolean recursive) + throws DatabaseException { + throwException(); + } + + @Override + public StripingPolicy createStripingPolicy(String pattern, int stripeSize, int width) { + return null; + } + + @Override + public FileMetadata createSymLink(long fileId, long parentId, String fileName, int atime, int ctime, + int mtime, String userId, String groupId, String ref, AtomicDBUpdate update) throws DatabaseException { + throwException(); + return null; + } + + @Override + public XAttr createXAttr(long fileId, String owner, String key, byte[] value) { + return null; + } + + @Override + public XLoc createXLoc(StripingPolicy stripingPolicy, String[] osds, int replFlags) { + return null; + } + + @Override + public XLocList createXLocList(XLoc[] replicas, String replUpdatePolicy, int version) { + return null; + } + + @Override + public short delete(long parentId, String fileName, AtomicDBUpdate update) throws DatabaseException { + throwException(); + return -1; + } + + @Override + public void deleteDatabase() throws DatabaseException { + throwException(); + } + + @Override + public void deleteSnapshot(String snapName) throws DatabaseException { + throwException(); + } + + @Override + public void dumpDB(BufferedWriter xmlWriter) throws DatabaseException, IOException { + DBAdminHelper.dumpVolume(xmlWriter, this); + } + + @Override + public String[] getAllSnapshots() throws DatabaseException { + throwException(); + return null; + } + + @Override + public long getNextFileId() throws DatabaseException { + throwException(); + return -1; + } + + @Override + public void link(FileMetadata metadata, long newParentId, String newFileName, AtomicDBUpdate update) + throws DatabaseException { + throwException(); + } + + @Override + public void setACLEntry(long fileId, String entity, Short rights, AtomicDBUpdate update) + throws DatabaseException { + throwException(); + } + + @Override + public void setDefaultStripingPolicy(long fileId, + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy defaultSp, AtomicDBUpdate update) + throws DatabaseException { + throwException(); + } + + @Override + public void setDefaultReplicationPolicy(long fileId, ReplicationPolicy defaultRp, AtomicDBUpdate update) + throws DatabaseException { + throwException(); + } + + @Override + public void setVolumeQuota(long quota, AtomicDBUpdate update) throws DatabaseException { + throwException(); + } + + @Override + public void setLastFileId(long fileId, AtomicDBUpdate update) throws DatabaseException { + throwException(); + } + + @Override + public void setMetadata(FileMetadata metadata, byte type, AtomicDBUpdate update) throws DatabaseException { + throwException(); + } + + @Override + public void setXAttr(long fileId, String uid, String key, byte[] value, AtomicDBUpdate update) + throws DatabaseException { + throwException(); + } + + @Override + public short unlink(long parentId, String fileName, AtomicDBUpdate update) throws DatabaseException { + throwException(); + return -1; + } + + protected String getVolumeName() { + return volumeName; + } + + protected void throwException() throws DatabaseException { + throw new DatabaseException("cannot invoke this operation on a snapshot", ExceptionType.NOT_ALLOWED); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBSnapshotVolumeInfo.java b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBSnapshotVolumeInfo.java new file mode 100644 index 0000000..ebdf02a --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBSnapshotVolumeInfo.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database.babudb; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.utils.Converter; + +/** + * A VolumeInfo implementation backed by a byte buffer. + * + * @author stender + * + */ +public class BabuDBSnapshotVolumeInfo implements VolumeInfo { + + private String id; + + private String name; + + private short[] osdPolicy; + + private short[] replicaPolicy; + + private short acPolicy; + + private long creationTimestamp; + + private BabuDBSnapshotStorageManager sMan; + + public BabuDBSnapshotVolumeInfo(long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + } + + public void init(BabuDBSnapshotStorageManager sMan) throws DatabaseException { + + this.sMan = sMan; + + try { + id = new String(sMan.getXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.VOL_ID_ATTR_NAME)); + name = sMan.getVolumeName(); + osdPolicy = Converter.stringToShortArray(new String(sMan.getXAttr(1, StorageManager.SYSTEM_UID, + BabuDBStorageManager.OSD_POL_ATTR_NAME))); + replicaPolicy = Converter.stringToShortArray(new String(sMan.getXAttr(1, StorageManager.SYSTEM_UID, + BabuDBStorageManager.REPL_POL_ATTR_NAME))); + acPolicy = Short.parseShort(new String(sMan.getXAttr(1, StorageManager.SYSTEM_UID, + BabuDBStorageManager.AC_POL_ATTR_NAME))); + } catch (NumberFormatException exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + throw new DatabaseException("currpted MRC database", ExceptionType.INTERNAL_DB_ERROR); + } + } + + @Override + public String getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public short[] getOsdPolicy() { + return osdPolicy; + } + + @Override + public short[] getReplicaPolicy() { + return replicaPolicy; + } + + @Override + public long getVolumeQuota() throws DatabaseException { + return sMan.getVolumeQuota(); + } + + @Override + public short getAcPolicyId() { + return acPolicy; + } + + @Override + public void setOsdPolicy(short[] osdPolicy, AtomicDBUpdate update) throws DatabaseException { + sMan.throwException(); + } + + @Override + public void setReplicaPolicy(short[] replicaPolicy, AtomicDBUpdate update) throws DatabaseException { + sMan.throwException(); + } + + @Override + public void setVolumeQuota(long quota, AtomicDBUpdate update) throws DatabaseException { + sMan.throwException(); + } + + @Override + public void setAllowSnaps(boolean allowSnaps, AtomicDBUpdate update) throws DatabaseException { + sMan.throwException(); + } + + @Override + public void updateVolumeSize(long diff, AtomicDBUpdate update) throws DatabaseException { + sMan.throwException(); + } + + @Override + public long getNumFiles() throws DatabaseException { + return 0; + } + + @Override + public long getNumDirs() throws DatabaseException { + return 0; + } + + @Override + public long getVolumeSize() throws DatabaseException { + return 0; + } + + @Override + public boolean isSnapVolume() throws DatabaseException { + return true; + } + + @Override + public boolean isSnapshotsEnabled() throws DatabaseException { + return true; + } + + @Override + public long getCreationTime() throws DatabaseException { + return creationTimestamp; + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBStorageHelper.java b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBStorageHelper.java new file mode 100644 index 0000000..b3d908e --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBStorageHelper.java @@ -0,0 +1,592 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database.babudb; + +import java.nio.ByteBuffer; +import java.util.List; +import java.util.Map.Entry; + +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.DatabaseRO; +import org.xtreemfs.babudb.api.database.ResultSet; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.metadata.ACLEntry; +import org.xtreemfs.mrc.metadata.BufferBackedACLEntry; +import org.xtreemfs.mrc.metadata.BufferBackedFileMetadata; +import org.xtreemfs.mrc.metadata.BufferBackedRCMetadata; +import org.xtreemfs.mrc.metadata.BufferBackedXAttr; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.XAttr; + +public class BabuDBStorageHelper { + + static class ChildrenIterator implements DatabaseResultSet { + + private final DatabaseRO database; + + private final ResultSet it; + + private Entry next; + + private String prevFileName; + + private byte[][] keyBufs; + + private byte[][] valBufs; + + private int remaining; + + public ChildrenIterator(DatabaseRO database, ResultSet it, int from, int num) { + + this.database = database; + this.it = it; + + this.keyBufs = new byte[BufferBackedFileMetadata.NUM_BUFFERS][]; + this.valBufs = new byte[BufferBackedFileMetadata.NUM_BUFFERS][]; + + remaining = Integer.MAX_VALUE; + + // move to the 'from' element + for (int i = 0; i < from && hasNext(); i++) + next(); + + remaining = num; + } + + @Override + public boolean hasNext() { + return (next != null || it.hasNext()) && remaining > 0; + } + + @Override + public FileMetadata next() { + + while (next != null || it.hasNext()) { + + if (next == null) + next = it.next(); + + final String currFileName = new String(next.getKey(), 8, next.getKey().length - 9); + + if (prevFileName != null && !prevFileName.equals(currFileName)) { + assert (valBufs[FileMetadata.RC_METADATA] != null) : "*** DATABASE CORRUPTED *** incomplete file metadata"; + break; + } + + final byte currType = next.getKey()[next.getKey().length - 1]; + + keyBufs[currType] = next.getKey(); + valBufs[currType] = next.getValue(); + next = null; + + prevFileName = currFileName; + } + + byte[][] tmpKeys = keyBufs; + byte[][] tmpVals = valBufs; + keyBufs = new byte[BufferBackedFileMetadata.NUM_BUFFERS][]; + valBufs = new byte[BufferBackedFileMetadata.NUM_BUFFERS][]; + + // if (tmpVals[FileMetadata.RC_METADATA] == null) { + // //dump the record + // for (int i = 0; i < tmpVals.length; i++) { + // System.out.println("index "+i); + // if (tmpVals[i] == null) { + // System.out.println("IS NULL!"); + // continue; + // } + // String content = new String(tmpVals[i]); + // System.out.println("content: "+content); + // } + // System.exit(1); + // } + + BufferBackedFileMetadata md = null; + + // in case of a hardlink ... + if (tmpVals[FileMetadata.RC_METADATA][0] == 2) + try { + md = BabuDBStorageHelper.resolveLink(database, tmpVals[FileMetadata.RC_METADATA], + prevFileName); + } catch (BabuDBException exc) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "could not resolve hard link"); + } + + else + md = new BufferBackedFileMetadata(tmpKeys, tmpVals, BabuDBStorageManager.FILE_INDEX); + + remaining--; + + prevFileName = null; + return md; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + public void destroy() { + it.free(); + } + + } + + static class XAttrIterator implements DatabaseResultSet { + + private ResultSet it; + + private String owner; + + private BufferBackedXAttr next; + + public XAttrIterator(ResultSet it, String owner) { + this.it = it; + this.owner = owner; + } + + @Override + public boolean hasNext() { + + if (owner == null) + return it.hasNext(); + + if (next != null) + return true; + + if (!it.hasNext()) + return false; + + while (it.hasNext()) { + + Entry tmp = it.next(); + next = new BufferBackedXAttr(tmp.getKey(), tmp.getValue()); + if (!owner.equals(next.getOwner())) + continue; + + return true; + } + + return false; + } + + @Override + public XAttr next() { + + if (next != null) { + XAttr tmp = next; + next = null; + return tmp; + } + + for (;;) { + + Entry tmp = it.next(); + + next = new BufferBackedXAttr(tmp.getKey(), tmp.getValue()); + if (owner != null && !owner.equals(next.getOwner())) + continue; + + BufferBackedXAttr tmp2 = next; + next = null; + return tmp2; + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + public void destroy() { + it.free(); + } + + } + + static class ACLIterator implements DatabaseResultSet { + + private ResultSet it; + + public ACLIterator(ResultSet it) { + this.it = it; + } + + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public ACLEntry next() { + Entry entry = it.next(); + return new BufferBackedACLEntry(entry.getKey(), entry.getValue()); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + public void destroy() { + it.free(); + } + + } + + public static byte[] getLastAssignedFileId(Database database) throws BabuDBException { + + byte[] bytes = database.lookup(BabuDBStorageManager.VOLUME_INDEX, BabuDBStorageManager.LAST_ID_KEY, + null).get(); + + if (bytes == null) { + bytes = new byte[8]; + ByteBuffer tmp = ByteBuffer.wrap(bytes); + tmp.putLong(0); + } + + return bytes; + } + + public static byte[] getVolumeMetadata(DatabaseRO database, byte[] key) throws BabuDBException { + + byte[] bytes = database.lookup(BabuDBStorageManager.VOLUME_INDEX, key, null).get(); + + if (bytes == null) { + bytes = new byte[8]; + ByteBuffer tmp = ByteBuffer.wrap(bytes); + tmp.putLong(0); + } + + return bytes; + } + + /** + * Returns the collision number assigned to an extended attribute, -1 if the + * attribute does not exist. + * + * @param database + * @param fileId + * @param owner + * @param attrKey + * @return the collision number + * @throws BabuDBException + */ + public static short findXAttrCollisionNumber(Database database, long fileId, String owner, String attrKey) + throws BabuDBException { + + // first, determine the collision number + byte[] prefix = createXAttrPrefixKey(fileId, owner, attrKey); + ResultSet it = database.prefixLookup(BabuDBStorageManager.XATTRS_INDEX, prefix, null) + .get(); + + Entry next = null; + while (it.hasNext()) { + + Entry curr = it.next(); + BufferBackedXAttr attr = new BufferBackedXAttr(curr.getKey(), curr.getValue()); + + if (owner.equals(attr.getOwner()) && attrKey.equals(attr.getKey())) { + next = curr; + break; + } + } + + it.free(); + + if (next == null) + return -1; + + return getXAttrCollisionNumber(next.getKey()); + } + + /** + * Returns the collision number assigned to an extended attribute, or the + * next largest unused number if the attribute does not exist. + * + * @param database + * @param fileId + * @param owner + * @param attrKey + * @return the collision number + * @throws BabuDBException + */ + public static short findUsedOrNextFreeXAttrCollisionNumber(Database database, long fileId, String owner, + String attrKey) throws BabuDBException { + + // first, determine the collision number + byte[] prefix = createXAttrPrefixKey(fileId, owner, attrKey); + ResultSet it = database.prefixLookup(BabuDBStorageManager.XATTRS_INDEX, prefix, null) + .get(); + + Entry next = null; + Entry curr = null; + while (it.hasNext()) { + + curr = it.next(); + BufferBackedXAttr attr = new BufferBackedXAttr(curr.getKey(), curr.getValue()); + + if (owner.equals(attr.getOwner()) && attrKey.equals(attr.getKey())) { + next = curr; + break; + } + } + + it.free(); + + if (next == null) + return curr == null ? 0 : (short) (getXAttrCollisionNumber(curr.getKey()) + 1); + + return getXAttrCollisionNumber(next.getKey()); + } + + public static byte[] createFileKey(long parentId, String fileName, byte type) { + + byte[] bytes = fileName.getBytes(); + + byte[] prefix = new byte[(type >= 0 ? 9 : 8) + bytes.length]; + ByteBuffer buf = ByteBuffer.wrap(prefix); + buf.putLong(parentId).put(bytes); + if (type >= 0) + buf.put(type); + + return prefix; + } + + public static byte[] createXAttrPrefixKey(long fileId, String owner, String attrKey) { + + byte[] prefix = new byte[owner == null ? 8 : attrKey == null ? 12 : 16]; + ByteBuffer buf = ByteBuffer.wrap(prefix); + buf.putLong(fileId); + if (owner != null) + buf.putInt(owner.hashCode()); + if (attrKey != null) + buf.putInt(attrKey.hashCode()); + + return prefix; + } + + public static byte[] createFilePrefixKey(long parentId) { + + byte[] prefix = new byte[8]; + ByteBuffer buf = ByteBuffer.wrap(prefix); + buf.putLong(parentId); + + return prefix; + } + + public static byte[] createACLPrefixKey(long fileId, String entityName) { + + byte[] entityBytes = entityName == null ? new byte[0] : entityName.getBytes(); + byte[] prefix = new byte[8 + entityBytes.length]; + ByteBuffer buf = ByteBuffer.wrap(prefix); + buf.putLong(fileId).put(entityBytes); + + return prefix; + } + + public static byte[] createFileIdIndexValue(long parentId, String fileName) { + + byte[] nameBytes = fileName.getBytes(); + + byte[] buf = new byte[8 + nameBytes.length]; + ByteBuffer tmp = ByteBuffer.wrap(buf); + tmp.putLong(parentId).put(nameBytes); + + return buf; + } + + public static byte[] createFileIdIndexKey(long fileId, byte type) { + + byte[] buf = new byte[type == -1 ? 8 : 9]; + ByteBuffer tmp = ByteBuffer.wrap(buf); + tmp.putLong(fileId); + if (type != -1) + tmp.put(type); + + return buf; + } + + public static byte[] createLinkTarget(long fileId) { + + byte[] buf = new byte[9]; + ByteBuffer tmp = ByteBuffer.wrap(buf); + tmp.put((byte) 2).putLong(fileId); + + return buf; + } + + public static short getXAttrCollisionNumber(byte[] key) { + + short collNum = 0; + ByteBuffer tmp = ByteBuffer.wrap(key); + if (key.length == 16) + collNum = 0; + else + collNum = tmp.getShort(16); + + return collNum; + } + + public static BufferBackedFileMetadata getMetadata(DatabaseRO database, long parentId, String fileName) + throws BabuDBException { + + byte[] rcKey = BabuDBStorageHelper.createFileKey(parentId, fileName, FileMetadata.RC_METADATA); + byte[] rcValue = database.lookup(BabuDBStorageManager.FILE_INDEX, rcKey, null).get(); + + if (rcValue != null) { + + // if the value refers to a link, resolve the link + if (rcValue[0] == 2) + return resolveLink(database, rcValue, fileName); + + byte[] fcKey = BabuDBStorageHelper.createFileKey(parentId, fileName, FileMetadata.FC_METADATA); + byte[] fcValue = database.lookup(BabuDBStorageManager.FILE_INDEX, fcKey, null).get(); + + byte[][] keyBufs = new byte[][] { fcKey, rcKey }; + byte[][] valBufs = new byte[][] { fcValue, rcValue }; + + return new BufferBackedFileMetadata(keyBufs, valBufs, BabuDBStorageManager.FILE_INDEX); + } + + else + return null; + + } + + public static long getId(Database database, long parentId, String fileName, Boolean directory) + throws BabuDBException { + + byte[] key = createFileKey(parentId, fileName, BufferBackedFileMetadata.RC_METADATA); + byte[] value = database.lookup(BabuDBStorageManager.FILE_INDEX, key, null).get(); + + if (value == null) + return -1; + + return ByteBuffer.wrap(value).getLong(1); + } + + public static byte getType(byte[] key, int index) { + return key[index == BabuDBStorageManager.FILE_ID_INDEX ? 8 : 12]; + } + + public static BufferBackedFileMetadata resolveLink(DatabaseRO database, byte[] target, String fileName) + throws BabuDBException { + + ResultSet it = null; + + try { + // determine the key for the link index + byte[] fileIdBytes = new byte[8]; + System.arraycopy(target, 1, fileIdBytes, 0, fileIdBytes.length); + + byte[][] valBufs = new byte[BufferBackedFileMetadata.NUM_BUFFERS][]; + + // retrieve the metadata from the link index + it = database.prefixLookup(BabuDBStorageManager.FILE_ID_INDEX, + fileIdBytes, null).get(); + + while (it.hasNext()) { + + Entry curr = it.next(); + + int type = getType(curr.getKey(), BabuDBStorageManager.FILE_ID_INDEX); + if (type == 3) { + long fileId = ByteBuffer.wrap(fileIdBytes).getLong(); + Logging.logMessage(Logging.LEVEL_WARN, Category.storage, (Object) null, + "MRC database contains redundant data for file %d", fileId); + continue; + } + valBufs[type] = curr.getValue(); + } + + assert (valBufs[FileMetadata.RC_METADATA] != null) : "*** DATABASE CORRUPTED *** dangling hardlink"; + if (valBufs[FileMetadata.RC_METADATA] == null) + return null; + + // replace the file name with the link name + BufferBackedRCMetadata tmp = new BufferBackedRCMetadata(null, valBufs[FileMetadata.RC_METADATA]); + BufferBackedRCMetadata tmp2 = tmp.isDirectory() ? new BufferBackedRCMetadata(0, fileName, tmp + .getOwnerId(), tmp.getOwningGroupId(), tmp.getId(), tmp.getPerms(), tmp.getW32Attrs(), tmp + .getLinkCount()) : new BufferBackedRCMetadata(0, fileName, tmp.getOwnerId(), tmp + .getOwningGroupId(), tmp.getId(), tmp.getPerms(), tmp.getW32Attrs(), tmp.getLinkCount(), tmp + .getEpoch(), tmp.getIssuedEpoch(), tmp.isReadOnly()); + if (!tmp2.isDirectory()) + tmp2.setXLocList(tmp.getXLocList()); + valBufs[FileMetadata.RC_METADATA] = tmp2.getValue(); + byte[][] keyBufs = new byte[][] { null, tmp2.getKey() }; + + return new BufferBackedFileMetadata(keyBufs, valBufs, BabuDBStorageManager.FILE_ID_INDEX); + + } finally { + if (it != null) + it.free(); + } + } + + public static ChildrenIterator getChildren(DatabaseRO database, long parentId, int from, int num) + throws BabuDBException { + + byte[] prefix = BabuDBStorageHelper.createFilePrefixKey(parentId); + ResultSet it = database.prefixLookup(BabuDBStorageManager.FILE_INDEX, prefix, null) + .get(); + + return new ChildrenIterator(database, it, from, num); + } + + public static void getNestedFiles(List files, Database database, long dirId, + boolean recursive) throws BabuDBException { + + ChildrenIterator children = getChildren(database, dirId, 0, Integer.MAX_VALUE); + while (children.hasNext()) { + + FileMetadata metadata = children.next(); + files.add(metadata); + + if (recursive && metadata.isDirectory()) + getNestedFiles(files, database, metadata.getId(), recursive); + + } + + children.destroy(); + } + + public static long getRootParentId(DatabaseRO database) throws BabuDBException { + + ResultSet it = database.prefixLookup(BabuDBStorageManager.FILE_INDEX, null, null) + .get(); + if (!it.hasNext()) + return -1; + + byte[] key = it.next().getKey(); + it.free(); + + return ByteBuffer.wrap(key).getLong(); + } + + public static String getRootDirName(DatabaseRO database, long rootParentId) throws BabuDBException { + + byte[] rootParentIdBytes = ByteBuffer.wrap(new byte[8]).putLong(rootParentId).array(); + + ResultSet it = database.prefixLookup(BabuDBStorageManager.FILE_INDEX, + rootParentIdBytes, null).get(); + if (!it.hasNext()) + return null; + + byte[] key = it.next().getKey(); + it.free(); + + return new String(key, 8, key.length - 9); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBStorageManager.java b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBStorageManager.java new file mode 100644 index 0000000..3624e41 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBStorageManager.java @@ -0,0 +1,1070 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database.babudb; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.xtreemfs.babudb.api.BabuDB; +import org.xtreemfs.babudb.api.DatabaseManager; +import org.xtreemfs.babudb.api.SnapshotManager; +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.ResultSet; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.babudb.index.DefaultByteRangeComparator; +import org.xtreemfs.babudb.snapshots.DefaultSnapshotConfig; +import org.xtreemfs.babudb.snapshots.SnapshotConfig; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DBAccessResultListener; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeChangeListener; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.babudb.BabuDBStorageHelper.ACLIterator; +import org.xtreemfs.mrc.database.babudb.BabuDBStorageHelper.XAttrIterator; +import org.xtreemfs.mrc.metadata.ACLEntry; +import org.xtreemfs.mrc.metadata.BufferBackedACLEntry; +import org.xtreemfs.mrc.metadata.BufferBackedFileMetadata; +import org.xtreemfs.mrc.metadata.BufferBackedStripingPolicy; +import org.xtreemfs.mrc.metadata.BufferBackedXAttr; +import org.xtreemfs.mrc.metadata.BufferBackedXLoc; +import org.xtreemfs.mrc.metadata.BufferBackedXLocList; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.ReplicationPolicy; +import org.xtreemfs.mrc.metadata.StripingPolicy; +import org.xtreemfs.mrc.metadata.XAttr; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.DBAdminHelper; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.Path; + +public class BabuDBStorageManager implements StorageManager { + + public static final int FILE_INDEX = 0; + + public static final int XATTRS_INDEX = 1; + + public static final int ACL_INDEX = 2; + + public static final int FILE_ID_INDEX = 3; + + public static final int VOLUME_INDEX = 4; + + public static final byte[] LAST_ID_KEY = { 'i' }; + + public static final byte[] VOL_SIZE_KEY = { 's' }; + + public static final byte[] NUM_FILES_KEY = { 'f' }; + + public static final byte[] NUM_DIRS_KEY = { 'd' }; + + private static final String DEFAULT_SP_ATTR_NAME = "sp"; + + private static final String DEFAULT_RP_ATTR_NAME = "rp"; + + private static final String LINK_TARGET_ATTR_NAME = "lt"; + + protected static final String OSD_POL_ATTR_NAME = "osdPol"; + + protected static final String REPL_POL_ATTR_NAME = "replPol"; + + protected static final String AC_POL_ATTR_NAME = "acPol"; + + protected static final String AUTO_REPL_FACTOR_ATTR_NAME = "replFactor"; + + protected static final String AUTO_REPL_FULL_ATTR_NAME = "replFull"; + + protected static final String ALLOW_SNAPS_ATTR_NAME = "allowSnaps"; + + protected static final String VOL_ID_ATTR_NAME = "volId"; + + protected static final String VOL_QUOTA_ATTR_NAME = "quota"; + + protected static final int[] ALL_INDICES = { FILE_INDEX, XATTRS_INDEX, ACL_INDEX, + FILE_ID_INDEX, VOLUME_INDEX }; + + private final DatabaseManager dbMan; + + private final SnapshotManager snapMan; + + private final Database database; + + private final List vcListeners; + + private final BabuDBVolumeInfo volume; + + /** + * Instantiates a storage manager by loading an existing volume database. + * + * @param dbs + * the database system + * @param db + * the database + */ + public BabuDBStorageManager(BabuDB dbs, Database db) throws DatabaseException { + + this.dbMan = dbs.getDatabaseManager(); + this.snapMan = dbs.getSnapshotManager(); + this.database = db; + this.vcListeners = new LinkedList(); + + volume = new BabuDBVolumeInfo(); + volume.init(this); + } + + /** + * Instantiates a storage manager by loading an existing volume database. + * + * @param dbMan + * the database manager + * @param sMan + * the snapshot manager + * @param db + * the database + */ + public BabuDBStorageManager(DatabaseManager dbMan, SnapshotManager sMan, Database db) throws DatabaseException { + + this.dbMan = dbMan; + this.snapMan = sMan; + this.database = db; + this.vcListeners = new LinkedList(); + + volume = new BabuDBVolumeInfo(); + volume.init(this); + } + + /** + * Instantiates a storage manager by creating a new database. + * + * @param dbs + * the database system + * @param volumeId + * the volume ID + */ + public BabuDBStorageManager(BabuDB dbs, String volumeId, String volumeName, short fileAccessPolicyId, + short[] osdPolicy, short[] replPolicy, String ownerId, String owningGroupId, int perms, ACLEntry[] acl, + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy rootDirDefSp, boolean allowSnaps, + long volumeQuota, Map attrs) throws DatabaseException { + + this.dbMan = dbs.getDatabaseManager(); + this.snapMan = dbs.getSnapshotManager(); + this.vcListeners = new LinkedList(); + this.volume = new BabuDBVolumeInfo(); + + TransactionalBabuDBUpdate update = new TransactionalBabuDBUpdate(dbMan); + update.createDatabase(volumeId, 5); + + // atime, ctime, mtime + int time = (int) (TimeSync.getGlobalTime() / 1000); + + // create the root directory; the name is the database name + createDir(1, 0, volumeName, time, time, time, ownerId, owningGroupId, perms, 0, true, update); + setLastFileId(1, update); + + volume.init(this, update.getDatabaseName(), volumeName, osdPolicy, replPolicy, fileAccessPolicyId, allowSnaps, + volumeQuota, update); + + // set the default striping policy + if (rootDirDefSp != null) + setDefaultStripingPolicy(1, rootDirDefSp, true, update); + + if (acl != null) + for (ACLEntry entry : acl) + setACLEntry(1L, entry.getEntity(), entry.getRights(), update); + + if (attrs != null) + for (Entry attr : attrs.entrySet()) + setXAttr(1L, SYSTEM_UID, "xtreemfs.volattr." + attr.getKey(), attr.getValue().getBytes(), true, update); + + update.execute(); + + try { + database = dbMan.getDatabase(update.getDatabaseName()); + } catch (Exception exc) { + throw new DatabaseException(exc); + } + + notifyVolumeChange(volume); + } + + @Override + public VolumeInfo getVolumeInfo() { + return volume; + } + + @Override + public void deleteDatabase() throws DatabaseException { + try { + dbMan.deleteDatabase(database.getName()); + notifyVolumeDelete(volume.getId()); + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public void addVolumeChangeListener(VolumeChangeListener listener) { + vcListeners.add(listener); + notifyVolumeChange(volume); + } + + @Override + public AtomicDBUpdate createAtomicDBUpdate(DBAccessResultListener listener, Object context) + throws DatabaseException { + try { + return new AtomicBabuDBUpdate(database, listener == null ? null : new BabuDBRequestListenerWrapper( + listener), context); + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public ACLEntry createACLEntry(long fileId, String entity, short rights) { + return new BufferBackedACLEntry(fileId, entity, rights); + } + + @Override + public XLoc createXLoc(StripingPolicy stripingPolicy, String[] osds, int replFlags) { + assert (stripingPolicy instanceof BufferBackedStripingPolicy); + return new BufferBackedXLoc((BufferBackedStripingPolicy) stripingPolicy, osds, replFlags); + } + + @Override + public XLocList createXLocList(XLoc[] replicas, String replUpdatePolicy, int version) { + BufferBackedXLoc[] tmp = new BufferBackedXLoc[replicas.length]; + for (int i = 0; i < replicas.length; i++) + tmp[i] = (BufferBackedXLoc) replicas[i]; + return new BufferBackedXLocList(tmp, replUpdatePolicy, version); + } + + @Override + public StripingPolicy createStripingPolicy(String pattern, int stripeSize, int width) { + return new BufferBackedStripingPolicy(pattern, stripeSize, width); + } + + @Override + public XAttr createXAttr(long fileId, String owner, String key, byte[] value) { + return new BufferBackedXAttr(fileId, owner, key, value, (short) 0); + } + + @Override + public long getNextFileId() throws DatabaseException { + + try { + // get the file ID assigned to the last created file or + // directory + byte[] idBytes = BabuDBStorageHelper.getLastAssignedFileId(database); + + // calculate the new file ID + ByteBuffer tmp = ByteBuffer.wrap(idBytes); + long id = tmp.getLong(0) + 1; + + return id; + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public void setLastFileId(long fileId, AtomicDBUpdate update) throws DatabaseException { + + byte[] idBytes = new byte[8]; + ByteBuffer.wrap(idBytes).putLong(0, fileId); + + update.addUpdate(VOLUME_INDEX, LAST_ID_KEY, idBytes); + } + + @Override + public FileMetadata createDir(long fileId, long parentId, String fileName, int atime, int ctime, int mtime, + String userId, String groupId, int perms, long w32Attrs, AtomicDBUpdate update) throws DatabaseException { + + return createDir(fileId, parentId, fileName, atime, ctime, mtime, userId, groupId, perms, w32Attrs, false, + update); + } + + public FileMetadata createDir(long fileId, long parentId, String fileName, int atime, int ctime, int mtime, + String userId, String groupId, int perms, long w32Attrs, boolean initCount, AtomicDBUpdate update) + throws DatabaseException { + + // create metadata + BufferBackedFileMetadata fileMetadata = new BufferBackedFileMetadata(parentId, fileName, userId, groupId, + fileId, atime, ctime, mtime, perms, w32Attrs, (short) 1); + + // update main metadata in the file index + update.addUpdate(FILE_INDEX, fileMetadata.getFCMetadataKey(), fileMetadata.getFCMetadataValue()); + update.addUpdate(FILE_INDEX, fileMetadata.getRCMetadata().getKey(), fileMetadata.getRCMetadata().getValue()); + + // add an entry to the file ID index + update.addUpdate(FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(fileId, (byte) 3), + BabuDBStorageHelper.createFileIdIndexValue(parentId, fileName)); + + if (initCount) + initCount(NUM_DIRS_KEY, update); + else + updateCount(NUM_DIRS_KEY, true, update); + + return fileMetadata; + } + + @Override + public FileMetadata createFile(long fileId, long parentId, String fileName, int atime, int ctime, int mtime, + String userId, String groupId, int perms, long w32Attrs, long size, boolean readOnly, int epoch, + int issEpoch, AtomicDBUpdate update) throws DatabaseException { + + // create metadata + BufferBackedFileMetadata fileMetadata = new BufferBackedFileMetadata(parentId, fileName, userId, groupId, + fileId, atime, ctime, mtime, size, perms, w32Attrs, (short) 1, epoch, issEpoch, readOnly); + + // update main metadata in the file index + update.addUpdate(FILE_INDEX, fileMetadata.getFCMetadataKey(), fileMetadata.getFCMetadataValue()); + update.addUpdate(FILE_INDEX, fileMetadata.getRCMetadata().getKey(), fileMetadata.getRCMetadata().getValue()); + + // add an entry to the file ID index + update.addUpdate(FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(fileId, (byte) 3), + BabuDBStorageHelper.createFileIdIndexValue(parentId, fileName)); + + volume.updateVolumeSize(size, update); + updateCount(NUM_FILES_KEY, true, update); + + return fileMetadata; + } + + @Override + public FileMetadata createSymLink(long fileId, long parentId, String fileName, int atime, int ctime, int mtime, + String userId, String groupId, String ref, AtomicDBUpdate update) { + + // create metadata + BufferBackedFileMetadata fileMetadata = new BufferBackedFileMetadata(parentId, fileName, userId, groupId, + fileId, atime, ctime, mtime, ref.length(), 0777, 0, (short) 1, 0, 0, false); + + // create link target (XAttr) + BufferBackedXAttr lt = new BufferBackedXAttr(fileId, SYSTEM_UID, LINK_TARGET_ATTR_NAME, ref.getBytes(), + (short) 0); + update.addUpdate(XATTRS_INDEX, lt.getKeyBuf(), lt.getValBuf()); + + // update main metadata in the file index + update.addUpdate(FILE_INDEX, fileMetadata.getFCMetadataKey(), fileMetadata.getFCMetadataValue()); + update.addUpdate(FILE_INDEX, fileMetadata.getRCMetadata().getKey(), fileMetadata.getRCMetadata().getValue()); + + // add an entry to the file ID index + update.addUpdate(FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(fileId, (byte) 3), + BabuDBStorageHelper.createFileIdIndexValue(parentId, fileName)); + + return fileMetadata; + } + + @Override + public short unlink(final long parentId, final String fileName, final AtomicDBUpdate update) + throws DatabaseException { + + try { + + // retrieve the file metadata + BufferBackedFileMetadata file = BabuDBStorageHelper.getMetadata(database, parentId, fileName); + + // determine and set the new link count + short newLinkCount = (short) (file.getLinkCount() - 1); + file.setLinkCount(newLinkCount); + + // if there will be links remaining after the deletion, update the + // link count; it must be in the FILE_ID_INDEX, because there have + // been at least two links + if (newLinkCount > 0) + update.addUpdate(FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(file.getId(), + FileMetadata.RC_METADATA), file.getRCMetadata().getValue()); + + // remove all entries from the file index + update.addUpdate(FILE_INDEX, + BabuDBStorageHelper.createFileKey(parentId, fileName, FileMetadata.FC_METADATA), null); + update.addUpdate(FILE_INDEX, + BabuDBStorageHelper.createFileKey(parentId, fileName, FileMetadata.RC_METADATA), null); + + return newLinkCount; + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + + } + + @Override + public short delete(final long parentId, final String fileName, final AtomicDBUpdate update) + throws DatabaseException { + + try { + + // retrieve the file metadata + BufferBackedFileMetadata file = BabuDBStorageHelper.getMetadata(database, parentId, fileName); + + // check whether there is only one link remaining + short newLinkCount = (short) (file.getLinkCount() - 1); + assert (newLinkCount >= 0); + + // decrement the link count + file.setLinkCount(newLinkCount); + + // if there will be links remaining after the deletion, update the + // link count + if (newLinkCount > 0) + update.addUpdate(FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(file.getId(), + FileMetadata.RC_METADATA), file.getRCMetadata().getValue()); + + // delete all keys ... + + // remove all content from the file index + update.addUpdate(BabuDBStorageManager.FILE_INDEX, + BabuDBStorageHelper.createFileKey(parentId, fileName, FileMetadata.FC_METADATA), null); + update.addUpdate(BabuDBStorageManager.FILE_INDEX, + BabuDBStorageHelper.createFileKey(parentId, fileName, FileMetadata.RC_METADATA), null); + + // if the last link to the file is supposed to be deleted, remove + // the remaining metadata, including ACLs and XAttrs + if (newLinkCount == 0) { + + // remove the back link from the file ID index + update.addUpdate(BabuDBStorageManager.FILE_ID_INDEX, + BabuDBStorageHelper.createFileIdIndexKey(file.getId(), (byte) 3), null); + + // remove potentially existing metadata from the file ID index + update.addUpdate(BabuDBStorageManager.FILE_ID_INDEX, + BabuDBStorageHelper.createFileIdIndexKey(file.getId(), FileMetadata.FC_METADATA), null); + update.addUpdate(BabuDBStorageManager.FILE_ID_INDEX, + BabuDBStorageHelper.createFileIdIndexKey(file.getId(), FileMetadata.RC_METADATA), null); + + byte[] idBytes = new byte[8]; + ByteBuffer.wrap(idBytes).putLong(file.getId()); + + // remove all ACLs + ResultSet it = database.prefixLookup(BabuDBStorageManager.ACL_INDEX, idBytes, + null).get(); + while (it.hasNext()) + update.addUpdate(BabuDBStorageManager.ACL_INDEX, it.next().getKey(), null); + it.free(); + + // remove all extended attributes + it = database.prefixLookup(BabuDBStorageManager.XATTRS_INDEX, idBytes, null).get(); + while (it.hasNext()) + update.addUpdate(BabuDBStorageManager.XATTRS_INDEX, it.next().getKey(), null); + it.free(); + + // if a file is deleted, update file count and volume size + if (file.isDirectory()) { + updateCount(NUM_DIRS_KEY, false, update); + } + + else if (file.getXLocList() != null) { + volume.updateVolumeSize(-file.getSize(), update); + updateCount(NUM_FILES_KEY, false, update); + } + + } + + return file.getLinkCount(); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public DatabaseResultSet getACL(long fileId) throws DatabaseException { + + try { + + byte[] prefix = BabuDBStorageHelper.createACLPrefixKey(fileId, null); + ResultSet it = database.prefixLookup(ACL_INDEX, prefix, null).get(); + + return new ACLIterator(it); + + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public ACLEntry getACLEntry(long fileId, String entity) throws DatabaseException { + + try { + + byte[] key = BabuDBStorageHelper.createACLPrefixKey(fileId, entity); + byte[] value = database.lookup(ACL_INDEX, key, null).get(); + + return value == null ? null : new BufferBackedACLEntry(key, value); + + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public DatabaseResultSet getChildren(long parentId, int seen, int num) throws DatabaseException { + + try { + return BabuDBStorageHelper.getChildren(database, parentId, seen, num); + } catch (Exception exc) { + throw new DatabaseException(exc); + } + + } + + @Override + public StripingPolicy getDefaultStripingPolicy(long fileId) throws DatabaseException { + + try { + byte[] sp = getXAttr(fileId, SYSTEM_UID, DEFAULT_SP_ATTR_NAME); + if (sp == null) + return null; + + return Converter.stringToStripingPolicy(this, new String(sp)); + + } catch (DatabaseException exc) { + throw exc; + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public ReplicationPolicy getDefaultReplicationPolicy(long fileId) throws DatabaseException { + + try { + byte[] rp = getXAttr(fileId, SYSTEM_UID, DEFAULT_RP_ATTR_NAME); + if (rp == null) + return null; + + return Converter.stringToReplicationPolicy(this, new String(rp)); + + } catch (DatabaseException exc) { + throw exc; + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public long getVolumeQuota() throws DatabaseException { + try { + byte[] quota = getXAttr(1, SYSTEM_UID, VOL_QUOTA_ATTR_NAME); + if (quota == null) + return 0; + else { + return Long.valueOf(new String(quota)); + } + + } catch (DatabaseException exc) { + throw exc; + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public FileMetadata getMetadata(long fileId) throws DatabaseException { + + try { + + // create the key for the file ID index lookup + byte[] key = BabuDBStorageHelper.createFileIdIndexKey(fileId, (byte) -1); + ByteBuffer.wrap(key).putLong(fileId); + + byte[][] valBufs = new byte[BufferBackedFileMetadata.NUM_BUFFERS][]; + + // retrieve the metadata from the link index + ResultSet it = database.prefixLookup(BabuDBStorageManager.FILE_ID_INDEX, key, null) + .get(); + + while (it.hasNext()) { + + Entry curr = it.next(); + + int type = BabuDBStorageHelper.getType(curr.getKey(), BabuDBStorageManager.FILE_ID_INDEX); + + // if the value is a back link, resolve it + if (type == 3) { + + long parentId = ByteBuffer.wrap(curr.getValue()).getLong(); + String fileName = new String(curr.getValue(), 8, curr.getValue().length - 8); + + return getMetadata(parentId, fileName); + } + + valBufs[type] = curr.getValue(); + } + + it.free(); + + // if not metadata was found for the file ID, return null + if (valBufs[FileMetadata.RC_METADATA] == null) + return null; + + byte[][] keyBufs = new byte[][] { null, BabuDBStorageHelper.createFileKey(0, "", FileMetadata.RC_METADATA) }; + + // otherwise, a hard link target is contained in the index; create a + // new metadata object in this case + return new BufferBackedFileMetadata(keyBufs, valBufs, BabuDBStorageManager.FILE_ID_INDEX); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public FileMetadata getMetadata(final long parentId, final String fileName) throws DatabaseException { + + try { + return BabuDBStorageHelper.getMetadata(database, parentId, fileName); + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public String getSoftlinkTarget(long fileId) throws DatabaseException { + + try { + byte[] target = getXAttr(fileId, SYSTEM_UID, LINK_TARGET_ATTR_NAME); + return target == null ? null : new String(target); + } catch (DatabaseException exc) { + throw exc; + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public byte[] getXAttr(long fileId, String uid, String key) throws DatabaseException { + + ResultSet it = null; + try { + + // peform a prefix lookup + byte[] prefix = BabuDBStorageHelper.createXAttrPrefixKey(fileId, uid, key); + it = database.prefixLookup(XATTRS_INDEX, prefix, null).get(); + + // check whether the entry is the correct one + while (it.hasNext()) { + + Entry curr = it.next(); + BufferBackedXAttr xattr = new BufferBackedXAttr(curr.getKey(), curr.getValue()); + if (uid.equals(xattr.getOwner()) && key.equals(xattr.getKey())) + return xattr.getValue(); + } + + return null; + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } finally { + if (it != null) + it.free(); + } + } + + @Override + public DatabaseResultSet getXAttrs(long fileId) throws DatabaseException { + + try { + + // peform a prefix lookup + byte[] prefix = BabuDBStorageHelper.createXAttrPrefixKey(fileId, null, null); + ResultSet it = database.prefixLookup(XATTRS_INDEX, prefix, null).get(); + + return new XAttrIterator(it, null); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public DatabaseResultSet getXAttrs(long fileId, String uid) throws DatabaseException { + + try { + + // peform a prefix lookup + byte[] prefix = BabuDBStorageHelper.createXAttrPrefixKey(fileId, uid, null); + ResultSet it = database.prefixLookup(XATTRS_INDEX, prefix, null).get(); + + return new XAttrIterator(it, uid); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + + } + + @Override + public void link(final FileMetadata metadata, final long newParentId, final String newFileName, + final AtomicDBUpdate update) { + + // get the link source + BufferBackedFileMetadata md = (BufferBackedFileMetadata) metadata; + + // increment the link count + short links = metadata.getLinkCount(); + md.setLinkCount((short) (links + 1)); + + // insert the whole metadata of the original file in the file ID + // index + update.addUpdate(FILE_ID_INDEX, + BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), FileMetadata.FC_METADATA), + md.getFCMetadataValue()); + update.addUpdate(FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), + FileMetadata.RC_METADATA), md.getRCMetadata().getValue()); + + // remove the back link + update.addUpdate(FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), (byte) 3), null); + + // if the metadata was retrieved from the FILE_INDEX and hasn't + // been deleted before (i.e. links == 0), ensure that the original + // file in the file index now points to the file ID index, and + // remove the FC and XLoc metadata entries + if (links != 0 && md.getIndexId() == FILE_INDEX) { + + update.addUpdate(FILE_INDEX, md.getRCMetadata().getKey(), + BabuDBStorageHelper.createLinkTarget(metadata.getId())); + update.addUpdate(FILE_INDEX, md.getFCMetadataKey(), null); + } + + // create an entry for the new link to the metadata in the file + // index + update.addUpdate(FILE_INDEX, + BabuDBStorageHelper.createFileKey(newParentId, newFileName, FileMetadata.RC_METADATA), + BabuDBStorageHelper.createLinkTarget(metadata.getId())); + + } + + @Override + public FileMetadata[] resolvePath(final Path path) throws DatabaseException { + + try { + FileMetadata[] md = new FileMetadata[path.getCompCount()]; + + long parentId = 0; + for (int i = 0; i < md.length; i++) { + md[i] = BabuDBStorageHelper.getMetadata(database, parentId, path.getComp(i)); + if (md[i] == null || i < md.length - 1 && !md[i].isDirectory()) { + md[i] = null; + return md; + } + parentId = md[i].getId(); + } + + return md; + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public void setACLEntry(long fileId, String entity, Short rights, AtomicDBUpdate update) throws DatabaseException { + + BufferBackedACLEntry entry = new BufferBackedACLEntry(fileId, entity, rights == null ? 0 : rights); + update.addUpdate(ACL_INDEX, entry.getKeyBuf(), rights == null ? null : entry.getValBuf()); + } + + @Override + public void setDefaultStripingPolicy(long fileId, + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy defaultSp, AtomicDBUpdate update) + throws DatabaseException { + + setDefaultStripingPolicy(fileId, defaultSp, false, update); + } + + public void setDefaultStripingPolicy(long fileId, + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy defaultSp, boolean init, + AtomicDBUpdate update) throws DatabaseException { + + setXAttr(fileId, SYSTEM_UID, DEFAULT_SP_ATTR_NAME, Converter.stripingPolicyToString(defaultSp).getBytes(), + init, update); + } + + @Override + public void setDefaultReplicationPolicy(long fileId, ReplicationPolicy defaultRp, AtomicDBUpdate update) + throws DatabaseException { + + setXAttr(fileId, SYSTEM_UID, DEFAULT_RP_ATTR_NAME, Converter.replicationPolicyToString(defaultRp).getBytes(), + update); + } + + @Override + public void setVolumeQuota(long quota, AtomicDBUpdate update) throws DatabaseException { + setXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.VOL_QUOTA_ATTR_NAME, String.valueOf(quota).getBytes(), update); + } + + @Override + public void setMetadata(FileMetadata metadata, byte type, AtomicDBUpdate update) throws DatabaseException { + + assert (metadata instanceof BufferBackedFileMetadata); + BufferBackedFileMetadata md = (BufferBackedFileMetadata) metadata; + + int index = md.getIndexId(); + if (type == -1) + for (byte i = 0; i < BufferBackedFileMetadata.NUM_BUFFERS; i++) { + byte[] valBuf = md.getValueBuffer(i); + assert (valBuf != null); + update.addUpdate( + index, + index == FILE_ID_INDEX ? BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), i) : md + .getKeyBuffer(i), valBuf); + } + + else { + byte[] valBuf = md.getValueBuffer(type); + assert (valBuf != null); + update.addUpdate( + index, + index == FILE_ID_INDEX ? BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), type) : md + .getKeyBuffer(type), valBuf); + } + } + + @Override + public void setXAttr(long fileId, String uid, String key, byte[] value, AtomicDBUpdate update) + throws DatabaseException { + + setXAttr(fileId, uid, key, value, false, update); + } + + public void setXAttr(long fileId, String uid, String key, byte[] value, boolean init, AtomicDBUpdate update) + throws DatabaseException { + + try { + short collNumber = init ? -1 : BabuDBStorageHelper.findXAttrCollisionNumber(database, fileId, uid, key); + + BufferBackedXAttr xattr = new BufferBackedXAttr(fileId, uid, key, value, collNumber); + update.addUpdate(XATTRS_INDEX, xattr.getKeyBuf(), value == null ? null : xattr.getValBuf()); + + if (key.startsWith(SYS_ATTR_KEY_PREFIX + MRCHelper.POLICY_ATTR_PREFIX)) + notifyAttributeSet(volume.getId(), key, value == null ? null : new String(value)); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + + } + + @Override + public void createSnapshot(String snapName, long parentId, String dirName, boolean recursive) + throws DatabaseException { + + try { + + // determine the prefixes for the snapshot + byte[][][] prefixes = null; + + FileMetadata snapDir = getMetadata(parentId, dirName); + + // for a full volume snapshot, simply use a 'null' prefix (full: + // dirID == 1 && recursive) + if (snapDir.getId() != 1 || !recursive) { + + // get the IDs of all files and directories contained in the + // given directory; if recursive == true, include subdirectories + List nestedFiles = new LinkedList(); + BabuDBStorageHelper.getNestedFiles(nestedFiles, database, snapDir.getId(), recursive); + + List dirEntryPrefixes = new ArrayList(nestedFiles.size()); + List filePrefixes = new ArrayList(nestedFiles.size()); + + // include the extended attributes of the volume's root + // directory if it's not the snapshot directory - they are + // needed to access volume-wide parameters in the snapshot, such + // as the access control policy + if (snapDir.getId() != 1) + filePrefixes.add(ByteBuffer.wrap(new byte[8]).putLong(1).array()); + + // include all metadata of the snapshot (i.e. top level) dir + byte[] idxKey = BabuDBStorageHelper.createFileKey(parentId, dirName, (byte) -1); + byte[] fileKey = BabuDBStorageHelper.createFilePrefixKey(snapDir.getId()); + dirEntryPrefixes.add(idxKey); + filePrefixes.add(fileKey); + + // include the snapshot directory content + idxKey = BabuDBStorageHelper.createFilePrefixKey(snapDir.getId()); + dirEntryPrefixes.add(idxKey); + + // determine the key prefixes of all nested files to include and + // exclude + for (FileMetadata file : nestedFiles) { + + // create a prefix key for the nested file + byte[] key = BabuDBStorageHelper.createFilePrefixKey(file.getId()); + + // if the nested file is a directory, ... + if (file.isDirectory()) { + + // include the directory in the file prefixes + // and the directory prefix in the dir entry prefixes + filePrefixes.add(key); + dirEntryPrefixes.add(key); + } + + // if the nested file is a file, ... + else + filePrefixes.add(key); + } + + byte[][] dirEntryPrefixesA = dirEntryPrefixes.toArray(new byte[dirEntryPrefixes.size()][]); + byte[][] filePrefixesA = filePrefixes.toArray(new byte[filePrefixes.size()][]); + + Arrays.sort(dirEntryPrefixesA, DefaultByteRangeComparator.getInstance()); + Arrays.sort(filePrefixesA, DefaultByteRangeComparator.getInstance()); + + // FILE_INDEX, XATTRS_INDEX, ACL_INDEX, FILE_ID_INDEX, + // VOLUME_INDEX + prefixes = new byte[][][] { dirEntryPrefixesA, filePrefixesA, filePrefixesA, filePrefixesA, null }; + } + + // create the snapshot + SnapshotConfig snap = new DefaultSnapshotConfig(snapName, ALL_INDICES, prefixes, null); + snapMan.createPersistentSnapshot(database.getName(), snap); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + + } + + @Override + public void deleteSnapshot(String snapName) throws DatabaseException { + + try { + + // check if the snapshot exists; if not, throw an exception + snapMan.getSnapshotDB(database.getName(), snapName); + + // delete the snapshot + snapMan.deletePersistentSnapshot(database.getName(), snapName); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public String[] getAllSnapshots() { + return snapMan.getAllSnapshots(volume.getId()); + } + + public void dump() throws BabuDBException { + + System.out.println("FILE_ID_INDEX"); + + ResultSet it = database.prefixLookup(FILE_ID_INDEX, new byte[0], null).get(); + while (it.hasNext()) { + Entry next = it.next(); + System.out.println(Arrays.toString(next.getKey()) + " = " + Arrays.toString(next.getValue())); + } + it.free(); + + System.out.println("\nFILE_INDEX"); + + it = database.prefixLookup(FILE_INDEX, new byte[0], null).get(); + while (it.hasNext()) { + Entry next = it.next(); + System.out.println(Arrays.toString(next.getKey()) + " = " + Arrays.toString(next.getValue())); + } + it.free(); + } + + public void dumpDB(BufferedWriter xmlWriter) throws DatabaseException, IOException { + DBAdminHelper.dumpVolume(xmlWriter, this); + } + + protected void updateVolumeSize(long diff, AtomicDBUpdate update) throws DatabaseException { + + long newSize = getVolumeSize() + diff; + + byte[] sizeBytes = new byte[8]; + ByteBuffer.wrap(sizeBytes).putLong(0, newSize); + + update.addUpdate(VOLUME_INDEX, VOL_SIZE_KEY, sizeBytes); + } + + protected long getVolumeSize() throws DatabaseException { + try { + byte[] sizeBytes = BabuDBStorageHelper.getVolumeMetadata(database, VOL_SIZE_KEY); + return ByteBuffer.wrap(sizeBytes).getLong(0); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + protected long getNumFiles() throws DatabaseException { + try { + byte[] sizeBytes = BabuDBStorageHelper.getVolumeMetadata(database, NUM_FILES_KEY); + return ByteBuffer.wrap(sizeBytes).getLong(0); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + protected long getNumDirs() throws DatabaseException { + try { + byte[] sizeBytes = BabuDBStorageHelper.getVolumeMetadata(database, NUM_DIRS_KEY); + return ByteBuffer.wrap(sizeBytes).getLong(0); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + protected void notifyVolumeChange(VolumeInfo vol) { + for (VolumeChangeListener listener : vcListeners) + listener.volumeChanged(vol); + } + + protected void notifyVolumeDelete(String volId) { + for (VolumeChangeListener listener : vcListeners) + listener.volumeDeleted(volId); + } + + protected void notifyAttributeSet(String volId, String key, String value) { + for (VolumeChangeListener listener : vcListeners) + listener.attributeSet(volId, key, value); + } + + private void updateCount(byte[] key, boolean increment, AtomicDBUpdate update) throws DatabaseException { + + try { + byte[] countBytes = BabuDBStorageHelper.getVolumeMetadata(database, key); + ByteBuffer countBuf = ByteBuffer.wrap(countBytes); + countBuf.putLong(0, countBuf.getLong() + (increment ? 1 : -1)); + + update.addUpdate(VOLUME_INDEX, key, countBytes); + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + private void initCount(byte[] key, AtomicDBUpdate update) { + + byte[] countBytes = new byte[Long.SIZE / 8]; + ByteBuffer countBuf = ByteBuffer.wrap(countBytes); + countBuf.putLong(0, 1); + + update.addUpdate(VOLUME_INDEX, key, countBytes); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBVolumeInfo.java b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBVolumeInfo.java new file mode 100644 index 0000000..10619f0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBVolumeInfo.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database.babudb; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.utils.Converter; + +/** + * A VolumeInfo implementation backed by a byte buffer. + * + * @author stender + * + */ +public class BabuDBVolumeInfo implements VolumeInfo { + + private BabuDBStorageManager sMan; + + private String id; + + private String name; + + private short[] osdPolicy; + + private short[] replicaPolicy; + + private short acPolicy; + + private boolean allowSnaps; + + private long quota; + + public void init(BabuDBStorageManager sMan, String id, String name, short[] osdPolicy, short[] replicaPolicy, + short acPolicy, boolean allowSnaps, long quota, AtomicDBUpdate update) throws DatabaseException { + + this.sMan = sMan; + this.id = id; + this.name = name; + this.osdPolicy = osdPolicy; + this.replicaPolicy = replicaPolicy; + this.acPolicy = acPolicy; + this.allowSnaps = allowSnaps; + this.quota = quota; + + // set the policies + sMan.setXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.VOL_ID_ATTR_NAME, id.getBytes(), true, update); + sMan.setXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.OSD_POL_ATTR_NAME, Converter + .shortArrayToString(osdPolicy).getBytes(), true, update); + sMan.setXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.REPL_POL_ATTR_NAME, Converter + .shortArrayToString(replicaPolicy).getBytes(), true, update); + sMan.setXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.AC_POL_ATTR_NAME, String.valueOf(acPolicy) + .getBytes(), true, update); + sMan.setXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.ALLOW_SNAPS_ATTR_NAME, + String.valueOf(allowSnaps).getBytes(), true, update); + sMan.setXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.VOL_QUOTA_ATTR_NAME, String.valueOf(quota) + .getBytes(), + true, update); + } + + public void init(BabuDBStorageManager sMan) throws DatabaseException { + + this.sMan = sMan; + + try { + + // retrieve volume attributes + byte[] idAttr = sMan.getXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.VOL_ID_ATTR_NAME); + byte[] acPolicyAttr = sMan.getXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.AC_POL_ATTR_NAME); + byte[] allowSnapsAttr = sMan.getXAttr(1, StorageManager.SYSTEM_UID, + BabuDBStorageManager.ALLOW_SNAPS_ATTR_NAME); + byte[] osdPolicyAttr = sMan.getXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.OSD_POL_ATTR_NAME); + byte[] replicaPolicyAttr = sMan.getXAttr(1, StorageManager.SYSTEM_UID, + BabuDBStorageManager.REPL_POL_ATTR_NAME); + byte[] quotaAttr = sMan.getXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.VOL_QUOTA_ATTR_NAME); + + if (idAttr != null) + id = new String(idAttr); + else + throw new DatabaseException("database corrupted: volume parameter 'id' not found", + ExceptionType.INTERNAL_DB_ERROR); + + name = sMan.getMetadata(1).getFileName(); + + if (osdPolicyAttr != null) + osdPolicy = Converter.stringToShortArray(new String(osdPolicyAttr)); + else + throw new DatabaseException("database corrupted: volume parameter 'osdPolicy' not found", + ExceptionType.INTERNAL_DB_ERROR); + + if (replicaPolicyAttr != null) + replicaPolicy = Converter.stringToShortArray(new String(replicaPolicyAttr)); + else + throw new DatabaseException("database corrupted: volume parameter 'replicaPolicy' not found", + ExceptionType.INTERNAL_DB_ERROR); + + if (acPolicyAttr != null) + acPolicy = Short.parseShort(new String(acPolicyAttr)); + else + throw new DatabaseException("database corrupted: volume parameter 'acPolicy' not found", + ExceptionType.INTERNAL_DB_ERROR); + + if (allowSnapsAttr != null) + allowSnaps = "true".equalsIgnoreCase(new String(allowSnapsAttr)); + + if (quotaAttr != null) + quota = Long.valueOf(new String(quotaAttr)); + + } catch (NumberFormatException exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + throw new DatabaseException("corrupted MRC database", ExceptionType.INTERNAL_DB_ERROR); + } + } + + @Override + public String getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public short[] getOsdPolicy() { + return osdPolicy; + } + + @Override + public short[] getReplicaPolicy() { + return replicaPolicy; + } + + @Override + public short getAcPolicyId() { + return acPolicy; + } + + @Override + public long getVolumeQuota() throws DatabaseException { + return quota; + } + + @Override + public void setOsdPolicy(short[] osdPolicy, AtomicDBUpdate update) throws DatabaseException { + this.osdPolicy = osdPolicy; + sMan.setXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.OSD_POL_ATTR_NAME, Converter + .shortArrayToString(osdPolicy).getBytes(), update); + sMan.notifyVolumeChange(this); + } + + @Override + public void setReplicaPolicy(short[] replicaPolicy, AtomicDBUpdate update) throws DatabaseException { + this.replicaPolicy = replicaPolicy; + sMan.setXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.REPL_POL_ATTR_NAME, Converter + .shortArrayToString(replicaPolicy).getBytes(), update); + sMan.notifyVolumeChange(this); + } + + @Override + public void setAllowSnaps(boolean allowSnaps, AtomicDBUpdate update) throws DatabaseException { + this.allowSnaps = allowSnaps; + sMan.setXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.ALLOW_SNAPS_ATTR_NAME, + String.valueOf(allowSnaps).getBytes(), update); + sMan.notifyVolumeChange(this); + } + + @Override + public void setVolumeQuota(long quota, AtomicDBUpdate update) throws DatabaseException { + this.quota = quota; + sMan.setXAttr(1, StorageManager.SYSTEM_UID, BabuDBStorageManager.VOL_QUOTA_ATTR_NAME, String.valueOf(quota) + .getBytes(), + update); + sMan.notifyVolumeChange(this); + } + + @Override + public void updateVolumeSize(long diff, AtomicDBUpdate update) throws DatabaseException { + sMan.updateVolumeSize(diff, update); + } + + @Override + public long getNumFiles() throws DatabaseException { + return sMan.getNumFiles(); + } + + @Override + public long getNumDirs() throws DatabaseException { + return sMan.getNumDirs(); + } + + @Override + public long getVolumeSize() throws DatabaseException { + return sMan.getVolumeSize(); + } + + @Override + public boolean isSnapVolume() throws DatabaseException { + return false; + } + + @Override + public boolean isSnapshotsEnabled() throws DatabaseException { + return allowSnaps; + } + + @Override + public long getCreationTime() throws DatabaseException { + return 0; + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBVolumeManager.java b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBVolumeManager.java new file mode 100644 index 0000000..ed1b7ac --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/babudb/BabuDBVolumeManager.java @@ -0,0 +1,594 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database.babudb; + +import java.nio.ByteBuffer; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.xtreemfs.babudb.BabuDBFactory; +import org.xtreemfs.babudb.api.BabuDB; +import org.xtreemfs.babudb.api.DatabaseManager; +import org.xtreemfs.babudb.api.SnapshotManager; +import org.xtreemfs.babudb.api.database.Database; +import org.xtreemfs.babudb.api.database.ResultSet; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.babudb.api.exception.BabuDBException.ErrorCode; +import org.xtreemfs.babudb.api.transaction.Operation; +import org.xtreemfs.babudb.api.transaction.Transaction; +import org.xtreemfs.babudb.api.transaction.TransactionListener; +import org.xtreemfs.babudb.config.BabuDBConfig; +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.VersionManagement; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.DBAccessResultListener; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeChangeListener; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.ACLEntry; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; + +public class BabuDBVolumeManager implements VolumeManager { + + private static final String VERSION_DB_NAME = "V"; + + private static final String SNAP_VERSIONS_DB_NAME = "snapVers"; + + private static final int VERSION_INDEX = 0; + + private static final String VERSION_KEY = "v"; + + /** the volume database */ + private BabuDB database; + + private Database snapVersionDB; + + private AtomicBoolean initialized; + + /** maps the IDs of all locally known volumes to their managers */ + private final Map volsById; + + /** maps the names of all locally known volumes to their managers */ + private final Map volsByName; + + private final Collection listeners; + + private final BabuDBConfig config; + + private final AtomicBoolean waitLock; + + public BabuDBVolumeManager(MRCRequestDispatcher master, BabuDBConfig dbconfig) { + initialized = new AtomicBoolean(false); + volsById = Collections.synchronizedMap(new HashMap()); + volsByName = Collections.synchronizedMap(new HashMap()); + listeners = new LinkedList(); + config = dbconfig; + waitLock = new AtomicBoolean(false); + } + + /* + * (non-Javadoc) + * + * @see org.xtreemfs.mrc.database.VolumeManager#init() + */ + @Override + public void init() throws DatabaseException { + try { + + // try to create a new database + database = BabuDBFactory.createBabuDB(config); + + database.getDatabaseManager().addTransactionListener(new TransactionListener() { + public void transactionPerformed(Transaction txn) { + + Operation op = txn.getOperations().get(0); + + if ((op.getType() == Operation.TYPE_CREATE_DB || op.getType() == Operation.TYPE_DELETE_DB) + && !VERSION_DB_NAME.equals(op.getDatabaseName()) + && !SNAP_VERSIONS_DB_NAME.equals(op.getDatabaseName())) { + + // register/deregister the volume + try { + if (op.getType() == Operation.TYPE_CREATE_DB) { + + registerVolume(op.getDatabaseName()); + + synchronized (waitLock) { + waitLock.set(true); + waitLock.notify(); + } + + } else + deregisterVolume(op.getDatabaseName()); + } catch (Exception exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + } + } + } + }); + + initDB(database.getDatabaseManager(), database.getSnapshotManager()); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + @Override + public void shutdown() { + + try { + database.shutdown(); + } catch (BabuDBException exc) { + Logging.logMessage(Logging.LEVEL_WARN, Category.lifecycle, this, "could not shut down volume manager"); + Logging.logError(Logging.LEVEL_WARN, this, exc); + } + } + + @Override + public void createVolume(FileAccessManager faMan, String volumeId, String volumeName, short fileAccessPolicyId, + String ownerId, String owningGroupId, StripingPolicy defaultStripingPolicy, int initialAccessMode, + long volumeQuota, List attrs) throws UserException, DatabaseException { + + waitLock.set(false); + + if (volumeName.indexOf(SNAPSHOT_SEPARATOR) != -1 || volumeName.indexOf('/') != -1 + || volumeName.indexOf('\\') != -1) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "volume name must not contain '" + + SNAPSHOT_SEPARATOR + "', '/' or '\\'"); + + if (hasVolume(volumeName)) + throw new UserException(POSIXErrno.POSIX_ERROR_EEXIST, "volume ' " + volumeName + + "' already exists locally"); + + // get the default permissions and ACL for the new volume + ACLEntry[] acl = faMan.getFileAccessPolicy(fileAccessPolicyId).getDefaultRootACL(); + + // create the new volume (local registration will be initiated through + // the transaction listener) + new BabuDBStorageManager(database, volumeId, volumeName, fileAccessPolicyId, DEFAULT_OSD_POLICY, + DEFAULT_REPL_POLICY, ownerId, owningGroupId, initialAccessMode, acl, defaultStripingPolicy, + DEFAULT_ALLOW_SNAPS, volumeQuota, KeyValuePairs.toMap(attrs)); + + // wait for the notification from the transaction listener before + // continuing + synchronized (waitLock) { + while (!waitLock.get()) + try { + waitLock.wait(); + } catch (InterruptedException e) { + // ignore + } + } + + } + + @Override + public boolean hasVolume(String volumeName) throws DatabaseException { + return volsByName.containsKey(volumeName); + } + + @Override + public boolean hasVolumeWithId(String volumeId) throws DatabaseException { + return volsById.containsKey(volumeId); + } + + @Override + public void deleteVolume(String volumeId, DBAccessResultListener listener, Object context) + throws DatabaseException, UserException { + + // check if the volume exists + StorageManager sMan = getStorageManager(volumeId); + + // remove the volume from the maps + volsById.remove(volumeId); + volsByName.remove(sMan.getVolumeInfo().getName()); + + // delete the volume's database + sMan.deleteDatabase(); + } + + @Override + public StorageManager getStorageManager(String volumeId) throws UserException { + + StorageManager sMan = volsById.get(volumeId); + if (sMan == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "volume '" + volumeId + "' not found on this MRC"); + + return sMan; + } + + @Override + public StorageManager getStorageManagerByName(String volumeName) throws UserException { + + StorageManager sMan = volsByName.get(volumeName); + if (sMan == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "volume '" + volumeName + "' not found on this MRC"); + + return sMan; + } + + @Override + public void checkpointDB() throws DatabaseException { + try { + database.getCheckpointer().checkpoint(); + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + @Override + public String newVolumeId() { + return UUID.randomUUID().toString(); + } + + @Override + public Collection getStorageManagers() { + + if (!initialized.get()) + return null; + + final Collection result = new HashSet(); + final Collection sMans = volsById.values(); + synchronized (volsById) { + for (StorageManager sMan : sMans) { + result.add(sMan); + } + } + return result; + } + + @Override + public void addVolumeChangeListener(VolumeChangeListener listener) { + this.listeners.add(listener); + for (StorageManager sMan : volsById.values()) + sMan.addVolumeChangeListener(listener); + } + + @Override + public void createSnapshot(String volumeId, String snapName, long parentId, FileMetadata dir, boolean recursive) + throws UserException, DatabaseException { + + try { + // check if the volume exists + StorageManager sMan = getStorageManager(volumeId); + + if (!snapName.equals(".dump") && !sMan.getVolumeInfo().isSnapshotsEnabled()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, + "snapshot operations are not allowed on this volume"); + + // get the time for the snapshot; this will be needed to attach the + // snapshot to file content snapshots + long currentTime = TimeSync.getGlobalTime(); + byte[] currentTimeAndParentAsBytes = ByteBuffer.wrap(new byte[2 * Long.SIZE / 8]).putLong(currentTime) + .putLong(parentId).array(); + + // if no snapshot name was passed, use the current time as the name + if ("".equals(snapName)) + snapName = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date(currentTime)) + ""; + + // determine the unique identifier for the snapshot + String snapVolName = sMan.getVolumeInfo().getName() + SNAPSHOT_SEPARATOR + snapName; + + // update the snapshot version table in order to persistently store + // the snapshot time stamp + try { + snapVersionDB.singleInsert(0, snapVolName.getBytes(), currentTimeAndParentAsBytes, null).get(); + } catch (BabuDBException exc2) { + throw new DatabaseException(exc2); + } + + // create the snapshot + sMan.createSnapshot(snapName, parentId, dir.getFileName(), recursive); + volsByName.put(snapVolName, new BabuDBSnapshotStorageManager(database.getSnapshotManager(), sMan + .getVolumeInfo().getName(), volumeId, snapName, currentTime, parentId)); + + } catch (DatabaseException exc) { + + if (((BabuDBException) exc.getCause()).getErrorCode() == ErrorCode.SNAP_EXISTS) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, exc.getMessage()); + else + throw exc; + } + } + + @Override + public void deleteSnapshot(String volumeId, FileMetadata dir, String snapName) throws UserException, + DatabaseException { + + try { + + // check if the volume exists + StorageManager sMan = getStorageManager(volumeId); + + // determine the unique identifier for the snapshot + String snapVolName = sMan.getVolumeInfo().getName() + SNAPSHOT_SEPARATOR + snapName; + + // delete the snapshot + volsByName.remove(snapVolName); + sMan.deleteSnapshot(snapName); + + // update the snapshot version table + try { + snapVersionDB.singleInsert(0, snapVolName.getBytes(), null, null).get(); + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + + } catch (DatabaseException exc) { + + if (((BabuDBException) exc.getCause()).getErrorCode() == ErrorCode.NO_SUCH_SNAPSHOT) + throw new UserException(POSIXErrno.POSIX_ERROR_ENODEV, exc.getMessage()); + else + throw exc; + } + } + + @Override + public Collection getSnapTimestamps(String volName) throws UserException, DatabaseException { + + try { + + Collection result = new LinkedList(); + + byte[] prefix = (volName + SNAPSHOT_SEPARATOR).getBytes(); + + ResultSet it = null; + try { + it = snapVersionDB.prefixLookup(0, prefix, null).get(); + + while (it.hasNext()) { + byte[] bytes = it.next().getValue(); + long ts = ByteBuffer.wrap(bytes).getLong(); + result.add(ts); + } + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } finally { + if (it != null) + it.free(); + } + + return result; + + } catch (DatabaseException exc) { + + if (((BabuDBException) exc.getCause()).getErrorCode() == ErrorCode.SNAP_EXISTS) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, exc.getMessage()); + else + throw exc; + } + } + + @Override + public String getDBVersion() { + return BabuDBFactory.BABUDB_VERSION; + } + + @Override + public Map getDBStatus() { + return database == null ? null : database.getRuntimeState(); + } + + private void initDB(DatabaseManager dbMan, SnapshotManager snapMan) throws DatabaseException { + + // check if the snapshot version DB exists; if not, make sure that it is + // created + if (snapVersionDB == null) + try { + snapVersionDB = dbMan.createDatabase(SNAP_VERSIONS_DB_NAME, 1); + } catch (BabuDBException exc) { + + if (exc.getErrorCode() == ErrorCode.DB_EXISTS) + try { + snapVersionDB = dbMan.getDatabase(SNAP_VERSIONS_DB_NAME); + } catch (BabuDBException exc2) { + throw new DatabaseException(exc2); + } + + // if a replication failure occurred, wait and retry + // else if (exc.getErrorCode() == ErrorCode.REPLICATION_FAILURE) + // { + // + // Logging.logMessage( + // Logging.LEVEL_INFO, + // Category.storage, + // this, + // "could not initialize database because of a replication failure: %s, will retry after %d ms", + // exc.toString(), RETRY_PERIOD); + // + // try { + // Thread.sleep(RETRY_PERIOD); + // initDB(dbMan, snapMan); + // } catch (InterruptedException e1) { + // } + // + // } + + else + throw new DatabaseException(exc); + } + + assert (snapVersionDB != null); + + try { + + Transaction txn = dbMan.createTransaction(); + txn.createDatabase(VERSION_DB_NAME, 3); + + // if the creation succeeds, set the version number to the current + // MRC DB version + byte[] verBytes = ByteBuffer.wrap(new byte[4]).putInt((int) VersionManagement.getMrcDataVersion()).array(); + txn.insertRecord(VERSION_DB_NAME, VERSION_INDEX, VERSION_KEY.getBytes(), verBytes); + dbMan.executeTransaction(txn); + + } catch (BabuDBException e) { + + if (e.getErrorCode() == ErrorCode.DB_EXISTS) { + + Database verDB = null; + try { + verDB = dbMan.getDatabase(VERSION_DB_NAME); + } catch (BabuDBException e1) { + throw new DatabaseException(e1); + } + + // database already exists + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, "database loaded from '%s'", + config.getBaseDir()); + + try { + + // retrieve the database version number + byte[] verBytes = verDB.lookup(VERSION_INDEX, VERSION_KEY.getBytes(), null).get(); + int ver = ByteBuffer.wrap(verBytes).getInt(); + + // check the database version number + if (ver != VersionManagement.getMrcDataVersion()) { + + String errMsg = "Wrong database version. Expected version = " + + VersionManagement.getMrcDataVersion() + ", version on disk = " + ver; + + Logging.logMessage(Logging.LEVEL_CRIT, this, errMsg); + if (VersionManagement.getMrcDataVersion() > ver) + Logging.logMessage( + Logging.LEVEL_CRIT, + this, + "Please create an XML dump with the old MRC version and restore the dump with this MRC, or delete the database if the file system is no longer needed."); + + throw new DatabaseException(errMsg, ExceptionType.WRONG_DB_VERSION); + } + + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_CRIT, this, + "The MRC database is either corrupted or outdated. The expected database version for this server is " + + VersionManagement.getMrcDataVersion()); + throw new DatabaseException(exc); + } + + // initialize all volumes + initVolumes(dbMan, snapMan); + + } + + else + throw new DatabaseException(e); + + } finally { + initialized.set(true); + } + } + + private void initVolumes(DatabaseManager dbMan, SnapshotManager snapMan) throws DatabaseException { + + // iterate over the list of databases in the storage manager + for (Entry dbEntry : dbMan.getDatabases().entrySet()) { + + // ignore the volume database + if (dbEntry.getKey().equals(VERSION_DB_NAME) || dbEntry.getKey().equals(SNAP_VERSIONS_DB_NAME)) + continue; + + BabuDBStorageManager sMan = new BabuDBStorageManager(dbMan, snapMan, dbEntry.getValue()); + VolumeInfo vol = sMan.getVolumeInfo(); + + volsById.put(vol.getId(), sMan); + volsByName.put(vol.getName(), sMan); + + // initialize all snapshots + for (String snapName : sMan.getAllSnapshots()) { + + // ignore snapshots that have been created for MRC + // dumps + if (snapName.equals(".dump")) + continue; + + String snapVolName = vol.getName() + SNAPSHOT_SEPARATOR + snapName; + + // retrieve the version time stamp from the snap + // version database + try { + byte[] timeStampAndParentBytes = snapVersionDB.lookup(0, snapVolName.getBytes(), null).get(); + if (timeStampAndParentBytes == null) + Logging.logMessage(Logging.LEVEL_WARN, Category.storage, this, + "no version mapping exists for snapshot %s; file contents may be corrupted", + snapVolName); + long snapTime = timeStampAndParentBytes == null ? 0 : ByteBuffer.wrap(timeStampAndParentBytes) + .getLong(); + long parentId = timeStampAndParentBytes == null ? 0 : ByteBuffer.wrap(timeStampAndParentBytes) + .getLong(8); + + volsByName.put(snapVolName, new BabuDBSnapshotStorageManager(snapMan, vol.getName(), vol.getId(), + snapName, snapTime, parentId)); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + } + + for (VolumeChangeListener l : listeners) + sMan.addVolumeChangeListener(l); + + } + } + + private void registerVolume(String volumeId) throws DatabaseException { + + DatabaseManager dbMan = database.getDatabaseManager(); + + try { + + BabuDBStorageManager sMan = new BabuDBStorageManager(dbMan, database.getSnapshotManager(), + dbMan.getDatabase(volumeId)); + + VolumeInfo vol = sMan.getVolumeInfo(); + + volsById.put(vol.getId(), sMan); + volsByName.put(vol.getName(), sMan); + + for (VolumeChangeListener l : listeners) + sMan.addVolumeChangeListener(l); + + } catch (BabuDBException exc) { + throw new DatabaseException(exc); + } + + } + + private void deregisterVolume(String volumeId) { + + // deregister the volumes if necessary + StorageManager sMan = volsById.remove(volumeId); + if (sMan != null) + volsByName.remove(sMan.getVolumeInfo().getName()); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/database/babudb/TransactionalBabuDBUpdate.java b/java/servers/src/org/xtreemfs/mrc/database/babudb/TransactionalBabuDBUpdate.java new file mode 100644 index 0000000..b60d5a6 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/database/babudb/TransactionalBabuDBUpdate.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.database.babudb; + +import java.net.InetSocketAddress; +import java.util.StringTokenizer; + +import org.xtreemfs.babudb.api.DatabaseManager; +import org.xtreemfs.babudb.api.exception.BabuDBException; +import org.xtreemfs.babudb.api.exception.BabuDBException.ErrorCode; +import org.xtreemfs.babudb.api.transaction.Transaction; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; + +public class TransactionalBabuDBUpdate implements AtomicDBUpdate { + + private final DatabaseManager dbMan; + + private final Transaction txn; + + private String databaseName; + + public TransactionalBabuDBUpdate(DatabaseManager dbMan) { + this.dbMan = dbMan; + this.txn = dbMan.createTransaction(); + } + + public void createDatabase(String databaseName, int numIndices) { + this.databaseName = databaseName; + txn.createDatabase(databaseName, numIndices); + } + + public String getDatabaseName() { + return databaseName; + } + + @Override + public void addUpdate(Object... update) { + assert (databaseName != null); + txn.insertRecord(databaseName, (Integer) update[0], (byte[]) update[1], (byte[]) update[2]); + } + + @Override + public void execute() throws DatabaseException { + + try { + dbMan.executeTransaction(txn); + } catch (BabuDBException exc) { + + // handle REDIRECTs (only relevant if replication is enabled) + if (exc.getErrorCode() == ErrorCode.REDIRECT) { + StringTokenizer st = new StringTokenizer(exc.getMessage(), ": "); + InetSocketAddress target = new InetSocketAddress(st.nextToken(), Integer.parseInt(st.nextToken())); + throw new DatabaseException(ExceptionType.REDIRECT, target); + + } else + throw new DatabaseException(exc); + + } catch (Exception exc) { + throw new DatabaseException(exc); + } + } + + public String toString() { + return txn.toString(); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/ACLEntry.java b/java/servers/src/org/xtreemfs/mrc/metadata/ACLEntry.java new file mode 100644 index 0000000..37999e0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/ACLEntry.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +public interface ACLEntry { + + public String getEntity(); + + public short getRights(); + +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedACLEntry.java b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedACLEntry.java new file mode 100644 index 0000000..9cf856f --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedACLEntry.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +import java.nio.ByteBuffer; + +public class BufferBackedACLEntry extends BufferBackedIndexMetadata implements ACLEntry { + + private String entity; + + private short rights; + + public BufferBackedACLEntry(byte[] key, byte[] val) { + + super(key, 0, key.length, val, 0, val.length); + + ByteBuffer tmp = ByteBuffer.wrap(val); + entity = new String(key, 8, key.length - 8); + rights = tmp.getShort(0); + } + + public BufferBackedACLEntry(long fileId, String entity, short rights) { + + super(null, 0, 0, null, 0, 0); + + keyLen = 8 + entity.getBytes().length; + keyBuf = new byte[keyLen]; + + ByteBuffer tmp = ByteBuffer.wrap(keyBuf); + tmp.putLong(fileId); + tmp.put(entity.getBytes()); + + valLen = 2; + valBuf = new byte[valLen]; + tmp = ByteBuffer.wrap(valBuf); + tmp.putShort(rights); + + this.entity = entity; + this.rights = rights; + } + + @Override + public String getEntity() { + return entity; + } + + @Override + public short getRights() { + return rights; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedFileMetadata.java b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedFileMetadata.java new file mode 100644 index 0000000..1fbb21e --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedFileMetadata.java @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +import java.nio.ByteBuffer; + +public class BufferBackedFileMetadata implements FileMetadata { + + public static final short NUM_BUFFERS = 2; + + protected static final int FC_ATIME = 0; + + protected static final int FC_CTIME = 4; + + protected static final int FC_MTIME = 8; + + protected static final int FC_SIZE = 12; + + private final ByteBuffer fcKeyBuf; + + private final ByteBuffer fcValBuf; + + private BufferBackedRCMetadata rcMetadata; + + private int indexId; + + /** + * Creates a new buffer-backed metadata object from a set of buffers. + * + * @param keyBufs + * the database keys + * @param valBufs + * the database values + * @param indexId + * indicates the index from which the key and value buffers were + * retrieved + */ + public BufferBackedFileMetadata(byte[][] keyBufs, byte[][] valBufs, int indexId) { + + assert (keyBufs.length == NUM_BUFFERS); + assert (valBufs.length == NUM_BUFFERS); + + byte[][] keyBufsCopy = new byte[keyBufs.length][]; + byte[][] valBufsCopy = new byte[valBufs.length][]; + for (int i = 0; i < keyBufs.length; i++) { + keyBufsCopy[i] = keyBufs[i] == null ? null : new byte[keyBufs[i].length]; + valBufsCopy[i] = new byte[valBufs[i].length]; + if (keyBufsCopy[i] != null) + System.arraycopy(keyBufs[i], 0, keyBufsCopy[i], 0, keyBufs[i].length); + System.arraycopy(valBufs[i], 0, valBufsCopy[i], 0, valBufs[i].length); + } + + // frequently changed metadata + fcKeyBuf = keyBufsCopy[FC_METADATA] == null ? null : ByteBuffer.wrap(keyBufsCopy[FC_METADATA]); + fcValBuf = ByteBuffer.wrap(valBufsCopy[FC_METADATA]); + + // rarely changed metadata + rcMetadata = new BufferBackedRCMetadata(keyBufsCopy[RC_METADATA], valBufsCopy[RC_METADATA]); + + this.indexId = indexId; + } + + /** + * Creates a new buffer-backed file metadata object. + * + * @param parentId + * @param fileName + * @param ownerId + * @param groupId + * @param fileId + * @param atime + * @param ctime + * @param mtime + * @param size + * @param perms + * @param linkCount + * @param epoch + * @param issEpoch + * @param readOnly + */ + public BufferBackedFileMetadata(long parentId, String fileName, String ownerId, String groupId, + long fileId, int atime, int ctime, int mtime, long size, int perms, long w32Atrrs, short linkCount, + int epoch, int issEpoch, boolean readOnly) { + + // frequently changed metadata + fcKeyBuf = generateKeyBuf(parentId, fileName, FC_METADATA); + fcValBuf = ByteBuffer.wrap(new byte[20]).putInt(atime).putInt(ctime).putInt(mtime).putLong(size); + + // rarely changed metadata + rcMetadata = new BufferBackedRCMetadata(parentId, fileName, ownerId, groupId, fileId, perms, + w32Atrrs, linkCount, epoch, issEpoch, readOnly); + } + + /** + * Constructor for creating a new directory metadata object. + * + * @param parentId + * @param dirName + * @param ownerId + * @param groupId + * @param fileId + * @param atime + * @param ctime + * @param mtime + * @param perms + */ + public BufferBackedFileMetadata(long parentId, String dirName, String ownerId, String groupId, + long fileId, int atime, int ctime, int mtime, int perms, long w32Attrs, short linkCount) { + + // frequently changed metadata + fcKeyBuf = generateKeyBuf(parentId, dirName, FC_METADATA); + fcValBuf = ByteBuffer.wrap(new byte[12]).putInt(atime).putInt(ctime).putInt(mtime); + + // rarely changed metadata + rcMetadata = new BufferBackedRCMetadata(parentId, dirName, ownerId, groupId, fileId, perms, w32Attrs, + linkCount); + } + + @Override + public long getId() { + return rcMetadata.getId(); + } + + @Override + public int getAtime() { + return fcValBuf.getInt(FC_ATIME); + } + + @Override + public int getCtime() { + return fcValBuf.getInt(FC_CTIME); + } + + @Override + public int getMtime() { + return fcValBuf.getInt(FC_MTIME); + } + + @Override + public int getEpoch() { + return rcMetadata.getEpoch(); + } + + @Override + public int getIssuedEpoch() { + return rcMetadata.getIssuedEpoch(); + } + + @Override + public short getLinkCount() { + return rcMetadata.getLinkCount(); + } + + @Override + public int getPerms() { + return rcMetadata.getPerms(); + } + + @Override + public long getSize() { + return fcValBuf.getLong(FC_SIZE); + } + + @Override + public boolean isReadOnly() { + return rcMetadata.isReadOnly(); + } + + @Override + public void setId(long id) { + rcMetadata.setId(id); + } + + @Override + public void setAtime(int atime) { + fcValBuf.putInt(FC_ATIME, atime); + } + + @Override + public void setCtime(int ctime) { + fcValBuf.putInt(FC_CTIME, ctime); + } + + @Override + public void setMtime(int mtime) { + fcValBuf.putInt(FC_MTIME, mtime); + } + + @Override + public void setEpoch(int epoch) { + rcMetadata.setEpoch(epoch); + } + + @Override + public void setIssuedEpoch(int issuedEpoch) { + rcMetadata.setIssuedEpoch(issuedEpoch); + } + + @Override + public void setLinkCount(short linkCount) { + rcMetadata.setLinkCount(linkCount); + } + + @Override + public void setPerms(int perms) { + rcMetadata.setPerms(perms); + } + + @Override + public void setReadOnly(boolean readOnly) { + rcMetadata.setReadOnly(readOnly); + } + + @Override + public void setSize(long size) { + fcValBuf.putLong(FC_SIZE, size); + } + + @Override + public void setW32Attrs(long w32Attrs) { + rcMetadata.setW32Attrs(w32Attrs); + } + + @Override + public String getFileName() { + return rcMetadata.getFileName(); + } + + @Override + public String getOwnerId() { + return rcMetadata.getOwnerId(); + } + + @Override + public String getOwningGroupId() { + return rcMetadata.getOwningGroupId(); + } + + @Override + public long getW32Attrs() { + return rcMetadata.getW32Attrs(); + } + + @Override + public XLocList getXLocList() { + return rcMetadata.getXLocList(); + } + + @Override + public boolean isDirectory() { + return rcMetadata.isDirectory(); + } + + @Override + public void setXLocList(XLocList xlocList) { + + assert (!isDirectory()) : "cannot assign locations list to directory"; + assert (xlocList instanceof BufferBackedXLocList); + + BufferBackedXLocList bbXLocList = (BufferBackedXLocList) xlocList; + rcMetadata.setXLocList(bbXLocList); + } + + @Override + public void setOwnerAndGroup(String owner, String group) { + + BufferBackedRCMetadata tmp = isDirectory() ? new BufferBackedRCMetadata(0, rcMetadata.getFileName(), + owner, group, rcMetadata.getId(), rcMetadata.getPerms(), rcMetadata.getW32Attrs(), rcMetadata + .getLinkCount()) : new BufferBackedRCMetadata(0, rcMetadata.getFileName(), owner, group, + rcMetadata.getId(), rcMetadata.getPerms(), rcMetadata.getW32Attrs(), rcMetadata.getLinkCount(), + rcMetadata.getEpoch(), rcMetadata.getIssuedEpoch(), rcMetadata.isReadOnly()); + + BufferBackedRCMetadata oldRCMetadata = rcMetadata; + + rcMetadata = new BufferBackedRCMetadata(rcMetadata == null ? null : rcMetadata.getKey(), tmp + .getValue()); + + if (!rcMetadata.isDirectory()) + rcMetadata.setXLocList(oldRCMetadata.getXLocList()); + } + + public byte[] getFCMetadataKey() { + return fcKeyBuf == null ? null : fcKeyBuf.array(); + } + + public byte[] getFCMetadataValue() { + return fcValBuf.array(); + } + + public BufferBackedRCMetadata getRCMetadata() { + return rcMetadata; + } + + public byte[] getKeyBuffer(int type) { + + switch (type) { + case 0: + return fcKeyBuf.array(); + case 1: + return rcMetadata.getKey(); + } + + return null; + } + + public byte[] getValueBuffer(byte type) { + + switch (type) { + case 0: + return fcValBuf.array(); + case 1: + return rcMetadata.getValue(); + } + + return null; + } + + public int getIndexId() { + return indexId; + } + + public String toString() { + + String s = (isDirectory() ? "dir" : "file") + " id=" + getId() + " name=" + getFileName() + " mode=" + + getPerms() + " w32Attrs=" + getW32Attrs() + " atime=" + getAtime() + " mtime=" + getMtime() + + " ctime=" + getCtime() + " owner=" + getOwnerId() + " group=" + getOwningGroupId(); + if (!isDirectory()) + s += " size=" + getSize() + " epoch=" + getEpoch() + " issEpoch=" + getIssuedEpoch(); + + return s; + } + + protected static ByteBuffer generateKeyBuf(long parentId, String fileName, int type) { + + byte[] bytes = fileName.getBytes(); + + byte[] tmp = new byte[9 + bytes.length]; + ByteBuffer buf = ByteBuffer.wrap(tmp); + buf.putLong(parentId).put(bytes).put((byte) type); + + return buf; + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedIndexMetadata.java b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedIndexMetadata.java new file mode 100644 index 0000000..a99cfd8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedIndexMetadata.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +import org.xtreemfs.foundation.util.OutputUtils; + +public abstract class BufferBackedIndexMetadata { + + protected byte[] keyBuf; + + protected byte[] valBuf; + + protected int keyOffs; + + protected int keyLen; + + protected int valOffs; + + protected int valLen; + + protected BufferBackedIndexMetadata(byte[] keyBuf, int keyOffs, int keyLen, byte[] valBuf, + int valOffs, int valLen) { + this.keyBuf = keyBuf; + this.keyOffs = keyOffs; + this.valBuf = valBuf; + this.valOffs = valOffs; + this.keyLen = keyLen; + this.valLen = valLen; + } + + public byte[] getKeyBuf() { + return keyBuf; + } + + public int getKeyOffs() { + return keyOffs; + } + + public int getKeyLen() { + return keyLen; + } + + public byte[] getValBuf() { + return valBuf; + } + + public int getValOffs() { + return valOffs; + } + + public int getValLen() { + return valLen; + } + + public String toString() { + return "key: " + OutputUtils.byteArrayToFormattedHexString(keyBuf) + ", val: " + + OutputUtils.byteArrayToFormattedHexString(valBuf); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedMetadata.java b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedMetadata.java new file mode 100644 index 0000000..2ff4ec7 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedMetadata.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +import org.xtreemfs.foundation.util.OutputUtils; + +public abstract class BufferBackedMetadata { + + protected byte[] buffer; + + protected int offset; + + protected int len; + + /** + * Creates a new metadata object backed by the given buffer. + * + * @param buffer + * the backing buffer + * @param offset + * the starting offset in the buffer + * @param len + * the number of bytes from the starting offset + */ + protected BufferBackedMetadata(byte[] buffer, int offset, int len) { + this.buffer = buffer; + this.offset = offset; + this.len = len; + } + + /** + * Returns the backing buffer. + * + * @return the backing buffer + */ + public byte[] getBuffer() { + return buffer; + } + + /** + * Returns the offset in the backing buffer where the data starts. + * + * @return the offset in the backing buffer where the data starts + */ + public int getOffset() { + return offset; + } + + /** + * Returns the number of bytes from the starting offset. + * + * @return the number of bytes from the starting offset + */ + public int getLength() { + return len; + } + + /** + * Generates a formatted hex string from the backing buffer. + */ + public String toString() { + return OutputUtils.byteArrayToFormattedHexString(buffer, offset, len); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedRCMetadata.java b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedRCMetadata.java new file mode 100644 index 0000000..a1e75a1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedRCMetadata.java @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +import java.nio.ByteBuffer; + +public class BufferBackedRCMetadata { + + protected static final int RC_TYPE = 0; + + protected static final int RC_ID = 1; + + protected static final int RC_PERMS = 9; + + protected static final int RC_LINKCOUNT = 13; + + protected static final int RC_W32ATTRS = 15; + + protected static final int RC_EPOCH = 23; + + protected static final int RC_ISSEPOCH = 27; + + protected static final int RC_READONLY = 31; + + protected static final int RC_DIR_GROUP_OFFSET = 23; + + protected static final int DIR_VAR_LEN_PART_OFFSET = 25; + + protected static final int RC_FILE_GROUP_OFFSET = 32; + + protected static final int RC_XLOC_OFFSET = 34; + + protected static final int FILE_VAR_LEN_PART_OFFSET = 36; + + private final short groupOffset; + + private final short xLocOffset; + + private final boolean directory; + + private final ByteBuffer keyBuf; + + private ByteBuffer valBuf; + + private BufferBackedXLocList cachedXLocList; + + /** + * Creates a new buffer-backed metadata object from a key and a value + * buffer. + * + * @param keyBuf + * the database key + * @param valBuf + * the database value + */ + public BufferBackedRCMetadata(byte[] keyBuf, byte[] valBuf) { + + // assign the key and value + this.keyBuf = keyBuf == null ? null : ByteBuffer.wrap(keyBuf); + this.valBuf = ByteBuffer.wrap(valBuf); + + directory = valBuf[0] == 1; + groupOffset = this.valBuf.getShort(directory ? RC_DIR_GROUP_OFFSET : RC_FILE_GROUP_OFFSET); + xLocOffset = directory ? (short) valBuf.length : this.valBuf.getShort(RC_XLOC_OFFSET); + } + + /** + * Creates a new buffer-backed file metadata object. + * + * @param parentId + * @param fileName + * @param ownerId + * @param groupId + * @param fileId + * @param perms + * @param linkCount + * @param epoch + * @param issEpoch + * @param readOnly + */ + public BufferBackedRCMetadata(long parentId, String fileName, String ownerId, String groupId, + long fileId, int perms, long w32Attrs, short linkCount, int epoch, int issEpoch, boolean readOnly) { + + // assign the key + keyBuf = BufferBackedFileMetadata.generateKeyBuf(parentId, fileName, + BufferBackedFileMetadata.RC_METADATA); + + // assign the value + byte[] oBytes = ownerId.getBytes(); + byte[] gBytes = groupId.getBytes(); + + final int bufSize = FILE_VAR_LEN_PART_OFFSET + oBytes.length + gBytes.length; + groupOffset = (short) (bufSize - gBytes.length); + xLocOffset = (short) bufSize; + + valBuf = ByteBuffer.wrap(new byte[bufSize]); + valBuf.put((byte) 0).putLong(fileId).putInt(perms).putShort(linkCount).putLong(w32Attrs) + .putInt(epoch).putInt(issEpoch).put((byte) (readOnly ? 1 : 0)).putShort(groupOffset) + .putShort(xLocOffset).put(oBytes).put(gBytes); + + directory = false; + } + + /** + * Constructor for creating a new directory metadata object. + * + * @param parentId + * @param dirName + * @param ownerId + * @param groupId + * @param fileId + * @param perms + */ + public BufferBackedRCMetadata(long parentId, String dirName, String ownerId, String groupId, long fileId, + int perms, long w32Attrs, short linkCount) { + + // assign the key + keyBuf = BufferBackedFileMetadata.generateKeyBuf(parentId, dirName, + BufferBackedFileMetadata.RC_METADATA); + + // assign the value + byte[] oBytes = ownerId.getBytes(); + byte[] gBytes = groupId.getBytes(); + + final int bufSize = DIR_VAR_LEN_PART_OFFSET + oBytes.length + gBytes.length; + groupOffset = (short) (bufSize - gBytes.length); + xLocOffset = (short) bufSize; + + valBuf = ByteBuffer.wrap(new byte[bufSize]); + valBuf.put((byte) 1).putLong(fileId).putInt(perms).putShort(linkCount).putLong(w32Attrs).putShort( + groupOffset).put(oBytes).put(gBytes); + + directory = true; + } + + public long getId() { + return valBuf.getLong(RC_ID); + } + + public byte getType() { + return valBuf.get(); + } + + public int getEpoch() { + return valBuf.getInt(RC_EPOCH); + } + + public int getIssuedEpoch() { + return valBuf.getInt(RC_ISSEPOCH); + } + + public short getLinkCount() { + return valBuf.getShort(RC_LINKCOUNT); + } + + public int getPerms() { + return valBuf.getInt(RC_PERMS); + } + + public BufferBackedXLocList getXLocList() { + + // directories do not have XLocLists + if (directory) + return null; + + if (cachedXLocList == null) { + + byte[] bytes = valBuf.array(); + int index = valBuf.getShort(RC_XLOC_OFFSET); + + assert (bytes.length - index >= 0); + if (bytes.length - index != 0) + cachedXLocList = new BufferBackedXLocList(bytes, index, bytes.length - index); + } + + return cachedXLocList; + } + + public boolean isReadOnly() { + return valBuf.get(RC_READONLY) != 0; + } + + public void setId(long id) { + valBuf.putLong(RC_ID, id); + } + + public void setEpoch(int epoch) { + valBuf.putInt(RC_EPOCH, epoch); + } + + public void setIssuedEpoch(int issuedEpoch) { + valBuf.putInt(RC_ISSEPOCH, issuedEpoch); + } + + public void setLinkCount(short linkCount) { + valBuf.putShort(RC_LINKCOUNT, linkCount); + } + + public void setPerms(int perms) { + valBuf.putInt(RC_PERMS, perms); + } + + public void setReadOnly(boolean readOnly) { + valBuf.put(RC_READONLY, (byte) (readOnly ? 1 : 0)); + } + + public void setW32Attrs(long w32Attrs) { + valBuf.putLong(RC_W32ATTRS, w32Attrs); + } + + public void setXLocList(BufferBackedXLocList xLocList) { + + int offset = valBuf.getShort(RC_XLOC_OFFSET); + + byte[] bytes = this.valBuf.array(); + assert (offset <= bytes.length) : "offset=" + offset + ", bufsize=" + bytes.length; + + byte[] xLocBytes = xLocList == null ? new byte[0] : xLocList.getBuffer(); + int xLocOffs = xLocList == null ? 0 : xLocList.getOffset(); + int xLocLen = xLocList == null ? 0 : xLocList.getLength(); + byte[] tmp = new byte[offset + xLocLen]; + + System.arraycopy(bytes, 0, tmp, 0, offset); + System.arraycopy(xLocBytes, xLocOffs, tmp, offset, xLocLen); + this.valBuf = ByteBuffer.wrap(tmp); + + cachedXLocList = xLocList; + } + + public String getFileName() { + byte[] bytes = keyBuf.array(); + return new String(bytes, 8, bytes.length - 9); + } + + public String getOwnerId() { + int index = directory ? DIR_VAR_LEN_PART_OFFSET : FILE_VAR_LEN_PART_OFFSET; + int length = groupOffset - index; + return new String(valBuf.array(), index, length); + } + + public String getOwningGroupId() { + int startIndex = groupOffset; + int endIndex = directory ? valBuf.limit() : xLocOffset; + int length = endIndex - startIndex; + return new String(valBuf.array(), startIndex, length); + } + + public long getW32Attrs() { + return valBuf.getLong(RC_W32ATTRS); + } + + public boolean isDirectory() { + return directory; + } + + public byte[] getKey() { + return keyBuf == null ? null : keyBuf.array(); + } + + public byte[] getValue() { + return valBuf.array(); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedStripingPolicy.java b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedStripingPolicy.java new file mode 100644 index 0000000..1d7c15a --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedStripingPolicy.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +import java.nio.ByteBuffer; + +public class BufferBackedStripingPolicy extends BufferBackedMetadata implements StripingPolicy { + + private static final int SIZE_INDEX = 0; + + private static final int WIDTH_INDEX = 4; + + private static final int PATTERN_INDEX = 8; + + private String pattern; + + private int stripeSize; + + private int width; + + public BufferBackedStripingPolicy(byte[] buffer) { + this(buffer, 0, buffer.length); + } + + public BufferBackedStripingPolicy(byte[] buffer, int offset, int len) { + + super(buffer, offset, len); + + this.pattern = new String(buffer, offset + PATTERN_INDEX, len - PATTERN_INDEX); + + ByteBuffer tmp = ByteBuffer.wrap(buffer, offset + SIZE_INDEX, Integer.SIZE / 8); + this.stripeSize = tmp.getInt(); + + tmp = ByteBuffer.wrap(buffer, offset + WIDTH_INDEX, Integer.SIZE / 8); + this.width = tmp.getInt(); + } + + public BufferBackedStripingPolicy(String pattern, int stripeSize, int width) { + + super(null, 0, 0); + + len = pattern.getBytes().length + 8; + buffer = new byte[len]; + ByteBuffer tmp = ByteBuffer.wrap(buffer); + tmp.putInt(stripeSize).putInt(width).put(pattern.getBytes()); + + this.pattern = pattern; + this.stripeSize = stripeSize; + this.width = width; + } + + public boolean equals(StripingPolicy pol) { + return toString().equals(pol.toString()); + } + + public String getPattern() { + return pattern; + } + + public int getStripeSize() { + return stripeSize; + } + + public int getWidth() { + return width; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXAttr.java b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXAttr.java new file mode 100644 index 0000000..d540adf --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXAttr.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +import java.nio.ByteBuffer; +import java.util.Arrays; + +public class BufferBackedXAttr extends BufferBackedIndexMetadata implements XAttr { + + private final short ownerOffset; + + private final short keyOffset; + + private final short valOffset; + + public BufferBackedXAttr(byte[] key, byte[] val) { + + super(key, 0, key.length, val, 0, val.length); + + ByteBuffer tmp = ByteBuffer.wrap(val); + + ownerOffset = 4; + keyOffset = tmp.getShort(); + valOffset = tmp.getShort(); + } + + public BufferBackedXAttr(long fileId, String owner, String key, byte[] value, short collCount) { + + super(null, 0, 0, null, 0, 0); + + byte[] ownerBytes = owner.getBytes(); + byte[] keyBytes = key.getBytes(); + byte[] valBytes = value == null ? new byte[0] : value; + + keyLen = 18; + keyBuf = new byte[keyLen]; + ByteBuffer tmp = ByteBuffer.wrap(keyBuf); + tmp.putLong(fileId).putInt(owner.hashCode()).putInt(key.hashCode()).putShort(collCount); + + ownerOffset = 4; + keyOffset = (short) (4 + ownerBytes.length); + valOffset = (short) (4 + ownerBytes.length + keyBytes.length); + + valLen = 4 + ownerBytes.length + keyBytes.length + valBytes.length; + valBuf = new byte[valLen]; + tmp = ByteBuffer.wrap(valBuf).putShort(keyOffset).putShort(valOffset).put(ownerBytes).put( + keyBytes).put(valBytes); + } + + public String getKey() { + return new String(valBuf, keyOffset, valOffset - keyOffset); + } + + public String getOwner() { + return new String(valBuf, ownerOffset, keyOffset - ownerOffset); + } + + public byte[] getValue() { + return Arrays.copyOfRange(valBuf, valOffset, valBuf.length); + } + + public void setCollisionNumber(short collisionNumber) { + ByteBuffer tmp = ByteBuffer.wrap(keyBuf); + tmp.putShort(16, collisionNumber); + } + + public String toString() { + return "(" + getKey() + " = " + getValue() + " [" + getOwner() + "])"; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXLoc.java b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXLoc.java new file mode 100644 index 0000000..4e0e62f --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXLoc.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +import java.nio.ByteBuffer; + +public class BufferBackedXLoc extends BufferBackedMetadata implements XLoc { + + private String[] osdCache; + + private StripingPolicy stripingPolicy; + + public BufferBackedXLoc(byte[] buffer) { + this(buffer, 0, buffer.length); + } + + public BufferBackedXLoc(byte[] buffer, int offset, int len) { + + super(buffer, offset, len); + + ByteBuffer tmp = ByteBuffer.wrap(buffer, offset, len); + short numOSDs = tmp.getShort(offset + tmp.getShort(offset)); + + osdCache = new String[numOSDs]; + } + + public BufferBackedXLoc(BufferBackedStripingPolicy stripingPolicy, String[] osds, int replFlags) { + + super(null, 0, 0); + + assert (osds.length <= Short.MAX_VALUE); + + // determine required buffer size + osdCache = new String[osds.length]; + + int osdListSize = 2; // 2 bytes for # OSDs + for (String osd : osds) + // size + 2 length bytes + osdListSize += osd.getBytes().length + 2; + + int spolSize = stripingPolicy.getLength(); + assert (spolSize <= Short.MAX_VALUE); + + int bufSize = spolSize + osdListSize + 6; + + // allocate a new buffer + len = bufSize; + buffer = new byte[len]; + ByteBuffer tmp = ByteBuffer.wrap(buffer); + + // first 6 bytes: osd list offset + replication flags + tmp.putShort((short) (spolSize + 6)); + + // next 4 bytes: replication flags + tmp.putInt(replFlags); + + // next bytes: striping policy + tmp.put(stripingPolicy.getBuffer(), stripingPolicy.getOffset(), stripingPolicy.getLength()); + + // next 2 bytes: # OSDs + tmp.putShort((short) osds.length); + + // next bytes: osd offsets + byte[][] osdBytes = new byte[osds.length][]; + int ofs0 = tmp.position() - offset; + int ofs = 0; + for (int i = 0; i < osds.length; i++) { + osdBytes[i] = osds[i].getBytes(); + assert (ofs0 + ofs <= Short.MAX_VALUE); + tmp.putShort((short) (ofs0 + osds.length * Short.SIZE / 8 + ofs)); + ofs += osdBytes[i].length; + } + + // next bytes: osd bytes + for (byte[] b : osdBytes) + tmp.put(b); + } + + public short getOSDCount() { + return (short) osdCache.length; + } + + public String getOSD(int osdIndex) { + + if (osdCache[osdIndex] == null) { + + // find the correct index offset in the buffer + int bufOffset = getOSDBufferOffset(osdIndex); + int nextBufOffset = getOSDBufferOffset(osdIndex + 1); + + osdCache[osdIndex] = new String(buffer, bufOffset, nextBufOffset - bufOffset); + } + + return osdCache[osdIndex]; + } + + public StripingPolicy getStripingPolicy() { + + if (stripingPolicy == null) { + + ByteBuffer tmp = ByteBuffer.wrap(buffer, offset, len); + short osdListStart = tmp.getShort(offset); + assert (osdListStart >= 0); + + if (osdListStart == 6) + return null; + + // create the target object from a view buffer (skip the len bytes) + stripingPolicy = new BufferBackedStripingPolicy(buffer, offset + 6, osdListStart - 6); + } + + return stripingPolicy; + } + + public int getReplicationFlags() { + ByteBuffer tmp = ByteBuffer.wrap(buffer, offset, len); + return tmp.getInt(offset + 2); + } + + public void setReplicationFlags(int replFlags) { + ByteBuffer tmp = ByteBuffer.wrap(buffer, offset, len); + tmp.putInt(offset + 2, replFlags); + } + + private int getOSDBufferOffset(int osdPosition) { + + ByteBuffer tmp = ByteBuffer.wrap(buffer, offset, len); + int osdOffset = offset + + (osdPosition >= osdCache.length ? len : tmp.getShort(offset + tmp.getShort(offset) + 2 + + osdPosition * Short.SIZE / 8)); + + return osdOffset; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXLocList.java b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXLocList.java new file mode 100644 index 0000000..3416310 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/BufferBackedXLocList.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +import java.nio.ByteBuffer; +import java.util.Iterator; + +public class BufferBackedXLocList extends BufferBackedMetadata implements XLocList { + + private XLoc[] replicaCache; + + public BufferBackedXLocList(byte[] buffer, int offset, int length) { + + super(buffer, offset, length); + + ByteBuffer tmp = ByteBuffer.wrap(buffer, offset, len); + int numReplicas = tmp.getInt(offset + 4); + + replicaCache = new XLoc[numReplicas]; + } + + public BufferBackedXLocList(BufferBackedXLoc[] replicas, String replUpdatePolicy, int version) { + + super(null, 0, 0); + + byte[] replUpdatePolicyBytes = replUpdatePolicy.getBytes(); + + // determine required buffer size + replicaCache = new XLoc[replicas.length]; + int bufSize = 12; // 1st & 2nd & 3rd 4 bytes: version + #replicas + + // update pol offs + for (BufferBackedXLoc repl : replicas) + // size + 4 length bytes + bufSize += repl.len + 4; + + // add the length of the update policy string + bufSize += replUpdatePolicyBytes.length; + + // allocate a new buffer and fill it with the given data + buffer = new byte[bufSize]; + ByteBuffer tmp = ByteBuffer.wrap(buffer); + + // version + tmp.putInt(version); + + // # replicas + tmp.putInt(replicas.length); + + // jump 4 bytes ahead, leave the space for the update policy offset + tmp.position(tmp.position() + 4); + + // replica offsets + int replOffset = tmp.position() - offset + replicas.length * Integer.SIZE / 8; + for (BufferBackedXLoc replica : replicas) { + tmp.putInt(replOffset); + replOffset += replica.getLength(); + } + + // replicas + for (BufferBackedXLoc replica : replicas) + tmp.put(replica.getBuffer(), replica.getOffset(), replica.getLength()); + + // insert the repl update policy offset + int offs = tmp.position(); + tmp.position(8); + tmp.putInt(replOffset); + + tmp.position(offs); + tmp.put(replUpdatePolicyBytes); + + offset = 0; + len = buffer.length; + } + + public int getReplicaCount() { + return replicaCache.length; + } + + public XLoc getReplica(int replicaIndex) { + + if (replicaCache[replicaIndex] == null) { + + // find the correct offset position in the buffer + int index = getBufferOffset(replicaIndex); + + // find the following offset position + int nextIndex = replicaIndex >= getReplicaCount() - 1 ? getReplUpdatePolicyOffset() + : getBufferOffset(replicaIndex + 1); + + int length = nextIndex - index; + if (length == 0) + return null; + + replicaCache[replicaIndex] = new BufferBackedXLoc(buffer, index, length); + } + + return replicaCache[replicaIndex]; + } + + public String getReplUpdatePolicy() { + + ByteBuffer tmp = ByteBuffer.wrap(buffer, offset, len); + int offs = tmp.getInt(offset + 8); + + return new String(buffer, offset + offs, len - offs); + } + + public int getVersion() { + ByteBuffer tmp = ByteBuffer.wrap(buffer, offset, len); + return tmp.getInt(offset); + } + + public Iterator iterator() { + + return new Iterator() { + + private int index = 0; + + public boolean hasNext() { + return index < getReplicaCount(); + } + + public XLoc next() { + return getReplica(index++); + } + + public void remove() { + throw new UnsupportedOperationException("remove not implemented"); + } + }; + } + + private int getBufferOffset(int replicaIndex) { + ByteBuffer tmp = ByteBuffer.wrap(buffer, offset, len); + return offset + tmp.getInt(offset + 12 + replicaIndex * Integer.SIZE / 8); + } + + private int getReplUpdatePolicyOffset() { + ByteBuffer tmp = ByteBuffer.wrap(buffer, offset, len); + return offset + tmp.getInt(offset + 8); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/FileMetadata.java b/java/servers/src/org/xtreemfs/mrc/metadata/FileMetadata.java new file mode 100644 index 0000000..7892847 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/FileMetadata.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +public interface FileMetadata { + + /** frequently-changed metadata */ + public static final byte FC_METADATA = 0; + + /** rarely-changed metadata */ + public static final byte RC_METADATA = 1; + + public long getId(); + + public void setId(long id); + + public int getAtime(); + + public void setAtime(int atime); + + public int getCtime(); + + public void setCtime(int ctime); + + public int getMtime(); + + public void setMtime(int mtime); + + public long getSize(); + + public void setSize(long size); + + public int getPerms(); + + public void setPerms(int perms); + + public short getLinkCount(); + + public void setLinkCount(short linkCount); + + public int getEpoch(); + + public void setEpoch(int epoch); + + public int getIssuedEpoch(); + + public void setIssuedEpoch(int issuedEpoch); + + public boolean isReadOnly(); + + public void setReadOnly(boolean readOnly); + + public XLocList getXLocList(); + + public void setXLocList(XLocList xLocList); + + public String getFileName(); + + public String getOwnerId(); + + public String getOwningGroupId(); + + public void setOwnerAndGroup(String owner, String group); + + public void setW32Attrs(long w32Attrs); + + public long getW32Attrs(); + + public boolean isDirectory(); + +} diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/ReplicationPolicy.java b/java/servers/src/org/xtreemfs/mrc/metadata/ReplicationPolicy.java new file mode 100644 index 0000000..8fa5b5b --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/ReplicationPolicy.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + + +/** + * Interface for accessing a replication policy. + */ +public interface ReplicationPolicy { + + /** + * Returns the policy name. + * + * @return the policy name + */ + public String getName(); + + /** + * Returns the number of replicas. + * + * @return the number of replicas + */ + public int getFactor(); + + /** + * Returns a bit mask of replication flags. + * + * @return a bit mask of replication flags + */ + public int getFlags(); + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/StripingPolicy.java b/java/servers/src/org/xtreemfs/mrc/metadata/StripingPolicy.java new file mode 100644 index 0000000..5230147 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/StripingPolicy.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + + +/** + * Interface for accessing a striping policy. Striping policies may either be + * part of a file's X-Locations List, or default striping policies assigned for + * directories, which will be assigned to newly created files. + */ +public interface StripingPolicy { + + /** + * Returns the striping pattern. + * + * @return the striping pattern + */ + public String getPattern(); + + /** + * Returns the striping width, i.e. number of OSDs used for the pattern. + * + * @return the striping width + */ + public int getWidth(); + + /** + * Returns the stripe size, i.e. size of a single object in kBytes. + * + * @return the stripe size + */ + public int getStripeSize(); + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/XAttr.java b/java/servers/src/org/xtreemfs/mrc/metadata/XAttr.java new file mode 100644 index 0000000..2040ed0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/XAttr.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + + +/** + * Represents a single extended attribute. + */ +public interface XAttr { + + public String getKey(); + + public byte[] getValue(); + + public String getOwner(); +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/XLoc.java b/java/servers/src/org/xtreemfs/mrc/metadata/XLoc.java new file mode 100644 index 0000000..092efab --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/XLoc.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + + +/** + * Interface for accessing information about single replica (X-Location) of a + * file. X-Locations are stored in a file's X-Locations List and contain + * information about file data storage locations. + */ +public interface XLoc { + + /** + * The number of OSDs in the replica. + * + * @return the number of OSDs + */ + public short getOSDCount(); + + /** + * Returns the OSD UUID at the given index position. + * + * @param index the index of the OSD UUID + * @return the OSD UUID at index position position + */ + public String getOSD(int index); + + /** + * Returns the striping policy assigned to the replica. + * + * @return the striping policy + */ + public StripingPolicy getStripingPolicy(); + + /** + * Returns the replication flags assigned to the replica + * + * @return the replication flags + */ + public int getReplicationFlags(); + + /** + * Assigns new replication flags to the replica. + * + * @param replFlags the replication flags + */ + public void setReplicationFlags(int replFlags); +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/metadata/XLocList.java b/java/servers/src/org/xtreemfs/mrc/metadata/XLocList.java new file mode 100644 index 0000000..a13a57d --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/metadata/XLocList.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.metadata; + +import java.util.Iterator; + +/** + * Interface for accessing an X-Locations List. X-Locations Lists contain + * information about storage locations (OSDs) used for different replicas of a + * file. + */ +public interface XLocList { + + /** + * Returns the number of replicas currently stored in the X-Locations List. + * + * @return the number of replicas + */ + public int getReplicaCount(); + + /** + * Returns the replica at the given index position. + * + * @param index + * position for the replica to return + * @return the replica at position index + */ + public XLoc getReplica(int index); + + /** + * Returns the version number associated with the X-Locations List. + * + * @return the version number + */ + public int getVersion(); + + /** + * Returns an iterator for all replicas. + * + * @return an iterator + */ + public Iterator iterator(); + + /** + * Returns the replica update policy. + * + * @return the replica update policy + */ + public String getReplUpdatePolicy(); + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/operations/AccessOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/AccessOperation.java new file mode 100644 index 0000000..be3c19f --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/AccessOperation.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.ACCESS_FLAGS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest; + +/** + * + * @author stender + */ +public class AccessOperation extends MRCOperation { + + public AccessOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final accessRequest rqArgs = (accessRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + final Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + final StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + final PathResolver res = new PathResolver(sMan, p); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // F_OK(==0) is always set, check if the file exists + if (res.getFile() == null) { + throw new UserException(POSIXErrno.POSIX_ERROR_EACCES, "file or directory '" + rqArgs.getPath() + + "' does not exist"); + } + + // in any other case, check if the file grants the respective access + else { + + if ((rqArgs.getFlags() & ACCESS_FLAGS.ACCESS_FLAGS_R_OK.getNumber()) != 0) + faMan.checkPermission("r", sMan, res.getFile(), res.getParentDirId(), rq.getDetails().userId, + rq.getDetails().superUser, rq.getDetails().groupIds); + + if ((rqArgs.getFlags() & ACCESS_FLAGS.ACCESS_FLAGS_W_OK.getNumber()) != 0) + faMan.checkPermission("w", sMan, res.getFile(), res.getParentDirId(), rq.getDetails().userId, + rq.getDetails().superUser, rq.getDetails().groupIds); + + if ((rqArgs.getFlags() & ACCESS_FLAGS.ACCESS_FLAGS_X_OK.getNumber()) != 0) + faMan.checkPermission("x", sMan, res.getFile(), res.getParentDirId(), rq.getDetails().userId, + rq.getDetails().superUser, rq.getDetails().groupIds); + + } + + // set the response + rq.setResponse(emptyResponse.getDefaultInstance()); + + finishRequest(rq); + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/AddReplicaOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/AddReplicaOperation.java new file mode 100644 index 0000000..bfba065 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/AddReplicaOperation.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.StripingPolicy; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.stages.XLocSetCoordinator; +import org.xtreemfs.mrc.stages.XLocSetCoordinatorCallback; +import org.xtreemfs.mrc.stages.XLocSetLock; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest; + +/** + * + * @author stender + */ +public class AddReplicaOperation extends MRCOperation implements XLocSetCoordinatorCallback { + + public AddReplicaOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // Perform master redirect if necessary. + if (master.getReplMasterUUID() != null && !master.getReplMasterUUID().equals(master.getConfig().getUUID().toString())) + throw new DatabaseException(ExceptionType.REDIRECT); + + final xtreemfs_replica_addRequest rqArgs = (xtreemfs_replica_addRequest) rq.getRequestArgs(); + + final FileAccessManager faMan = master.getFileAccessManager(); + final VolumeManager vMan = master.getVolumeManager(); + + validateContext(rq); + + StorageManager sMan = null; + FileMetadata file = null; + String fileId; + + if (rqArgs.hasFileId()) { + + fileId = rqArgs.getFileId(); + + // Parse volume and file ID from global file ID. + GlobalFileIdResolver idRes = new GlobalFileIdResolver(fileId); + + sMan = vMan.getStorageManager(idRes.getVolumeId()); + + // Retrieve the file metadata. + file = sMan.getMetadata(idRes.getLocalFileId()); + if (file == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + rqArgs.getFileId() + + "' does not exist"); + + } else if (rqArgs.hasVolumeName() && rqArgs.hasPath()) { + + final Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + sMan = vMan.getStorageManagerByName(p.getComp(0)); + final PathResolver res = new PathResolver(sMan, p); + + res.checkIfFileDoesNotExist(); + file = res.getFile(); + + fileId = MRCHelper.createGlobalFileId(sMan.getVolumeInfo(), file); + + // Check whether the path prefix is searchable. + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + } else { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "either file ID or volume name + path required"); + } + + if (file.isDirectory()) { + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "replicas may only be added to files"); + } + + if (sMan.getSoftlinkTarget(file.getId()) != null) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "file '" + rqArgs.getFileId() + + "' is a symbolic link"); + } + + // Check if a xLocSetChange is already in progress. + XLocSetLock lock = master.getXLocSetCoordinator().getXLocSetLock(file, sMan); + if (lock.isLocked()) { + if (lock.hasCrashed()) { + // Ignore if a previous xLocSet change did not finish, because the replicas will be revalidated when the + // new xLocSet is installed by this operation. + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Previous xLocSet change did not finish."); + } + } else { + throw new UserException(POSIXErrno.POSIX_ERROR_EAGAIN, + "xLocSet change already in progress. Please retry."); + } + } + + // Check whether privileged permissions are granted for adding replicas. + faMan.checkPrivilegedPermissions(sMan, file, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + Replica newRepl = rqArgs.getNewReplica(); + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy sp = newRepl.getStripingPolicy(); + + StripingPolicy sPol = sMan.createStripingPolicy(sp.getType().toString(), sp.getStripeSize(), sp + .getWidth()); + + // Check whether the new replica relies on a set of OSDs which hasn't been used yet. + XLocList xLocList = file.getXLocList(); + assert (xLocList != null); + + if (ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE.equals(xLocList.getReplUpdatePolicy())) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, + "missing replica update policy - needs to be specified before adding replicas"); + + if (!MRCHelper.isResolvable(newRepl.getOsdUuidsList())) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "replica contains unresolvable OSD UUIDs in '" + newRepl.getOsdUuidsList() + "'"); + + if (xLocList.getReplica(0).getStripingPolicy().getStripeSize() != newRepl.getStripingPolicy() + .getStripeSize()) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid stripe size; must be " + + xLocList.getReplica(0).getStripingPolicy().getStripeSize()); + + if (!MRCHelper.isAddable(xLocList, newRepl.getOsdUuidsList())) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "at least one OSD already used in current X-Locations list '" + + Converter.xLocListToString(xLocList) + "'"); + + // Create a new replica and add it to the client's X-Locations list. + XLoc replica = sMan.createXLoc(sPol, newRepl.getOsdUuidsList().toArray( + new String[newRepl.getOsdUuidsCount()]), newRepl.getReplicationFlags()); + + XLoc[] repls = new XLoc[xLocList.getReplicaCount() + 1]; + for (int i = 0; i < xLocList.getReplicaCount(); i++) { + XLoc repl = xLocList.getReplica(i); + repls[i] = repl; + } + + repls[repls.length - 1] = replica; + XLocList extXLocList = sMan.createXLocList(repls, xLocList.getReplUpdatePolicy(), xLocList.getVersion() + 1); + + XLocSetCoordinator coordinator = master.getXLocSetCoordinator(); + XLocSetCoordinator.RequestMethod m = coordinator.addReplicas(fileId, file, xLocList, extXLocList, rq, this); + + // Make an update with the RequestMethod as context and the Coordinator as callback. This will enqueue + // the RequestMethod when the update is complete. + AtomicDBUpdate update = sMan.createAtomicDBUpdate(coordinator, m); + + // Lock the replica and start the coordination. + coordinator.lockXLocSet(file, sMan, update); + + update.execute(); + } + + @Override + public void installXLocSet(MRCRequest rq, String fileId, XLocList xLocList, XLocList oldxLocList) throws Throwable { + + final VolumeManager vMan = master.getVolumeManager(); + final GlobalFileIdResolver idRes = new GlobalFileIdResolver(fileId); + final StorageManager sMan = vMan.getStorageManager(idRes.getVolumeId()); + + // Retrieve the file metadata. + final FileMetadata file = sMan.getMetadata(idRes.getLocalFileId()); + if (file == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + fileId + "' does not exist"); + + file.setXLocList(xLocList); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // Update the X-Locations list. + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + // Unlock the replica. + master.getXLocSetCoordinator().unlockXLocSet(file, sMan, update); + + // Set the response. + rq.setResponse(emptyResponse.getDefaultInstance()); + + update.execute(); + } + + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/CheckFileListOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/CheckFileListOperation.java new file mode 100644 index 0000000..4809a5f --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/CheckFileListOperation.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.util.Iterator; + +import org.xtreemfs.mrc.MRCException; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE; + +public class CheckFileListOperation extends MRCOperation { + + public CheckFileListOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final xtreemfs_check_file_existsRequest rqArgs = (xtreemfs_check_file_existsRequest) rq.getRequestArgs(); + final String osd = rqArgs.getOsdUuid(); + final VolumeManager vMan = master.getVolumeManager(); + StorageManager sMan = null; + + xtreemfs_check_file_existsResponse.Builder response = xtreemfs_check_file_existsResponse.newBuilder(); + + // Try to open the requested Volume if it exists. + try { + sMan = vMan.getStorageManager(rqArgs.getVolumeId()); + response.setVolumeExists(true); + } catch (UserException e) { + response.setVolumeExists(false); + } + + if (rqArgs.getFileIdsCount() == 0) { + // TODO(jdillmann): state ?? + } + + if (sMan != null && rqArgs.getFileIdsCount() > 0) { + + for (String fileId : rqArgs.getFileIdsList()) { + if (fileId == null) { + throw new MRCException("checkFileList caused an Exception: file ID was null!"); + } + + FileMetadata mData = sMan.getMetadata(Long.parseLong(fileId)); + if (mData == null) { + // If no metadata exists, the file has been deleted. + response.addFileStates(FILE_STATE.DELETED); + } else { + // Check the xLocations-list of the recognized file. + boolean registered = false; + XLocList list = mData.getXLocList(); + + if (list != null) { + // Try to find the requesting OSD in the XLocList. + Iterator iter = list.iterator(); + XLoc loc; + while (iter.hasNext() && !registered) { + loc = iter.next(); + short count = loc.getOSDCount(); + for (int i = 0; i < count; i++) { + // Stop if entry was found. + if (loc.getOSD(i).equals(osd)) { + registered = true; + break; + } + } + } + } + + response.addFileStates(registered ? FILE_STATE.REGISTERED : FILE_STATE.ABANDONED); + } + } + } + + // Set the response. + rq.setResponse(response.build()); + finishRequest(rq); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/CheckpointOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/CheckpointOperation.java new file mode 100644 index 0000000..157acb3 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/CheckpointOperation.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.ErrorRecord; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class CheckpointOperation extends MRCOperation { + + public CheckpointOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) { + + try { + + // check password to ensure that user is authorized + if (master.getConfig().getAdminPassword().length() > 0 + && !master.getConfig().getAdminPassword().equals(rq.getDetails().password)) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "invalid password"); + + master.getVolumeManager().checkpointDB(); + + // set the response + rq.setResponse(emptyResponse.getDefaultInstance()); + finishRequest(rq); + + } catch (Throwable exc) { + finishRequest(rq, new ErrorRecord(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_NONE, + "an error has occurred", exc)); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/CreateDirOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/CreateDirOperation.java new file mode 100644 index 0000000..b9a2e11 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/CreateDirOperation.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse; + +/** + * + * @author stender + */ +public class CreateDirOperation extends MRCOperation { + + public CreateDirOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // perform master redirect if necessary + if (master.getReplMasterUUID() != null && !master.getReplMasterUUID().equals(master.getConfig().getUUID().toString())) + throw new DatabaseException(ExceptionType.REDIRECT); + + final mkdirRequest rqArgs = (mkdirRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + final Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + final StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + final PathResolver res = new PathResolver(sMan, p); + + // check if dir == volume + if (res.getParentDir() == null) + throw new UserException(POSIXErrno.POSIX_ERROR_EEXIST, "file or directory '" + res.getFileName() + + "' exists already"); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether the parent directory grants write access + faMan.checkPermission(FileAccessManager.O_WRONLY, sMan, res.getParentDir(), res.getParentsParentId(), + rq.getDetails().userId, rq.getDetails().superUser, rq.getDetails().groupIds); + + // check whether the file/directory exists already + res.checkIfFileExistsAlready(); + + // prepare directory creation in database + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // get the next free file ID + long fileId = sMan.getNextFileId(); + + // atime, ctime, mtime + int time = (int) (TimeSync.getGlobalTime() / 1000); + + // create the metadata object + sMan.createDir(fileId, res.getParentDirId(), res.getFileName(), time, time, time, + rq.getDetails().userId, rq.getDetails().groupIds.get(0), rqArgs.getMode(), 0, update); + + // set the file ID as the last one + sMan.setLastFileId(fileId, update); + + // update POSIX timestamps of parent directory + MRCHelper.updateFileTimes(res.getParentsParentId(), res.getParentDir(), false, true, true, sMan, + time, update); + + // set the response + rq.setResponse(timestampResponse.newBuilder().setTimestampS(time).build()); + + update.execute(); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/CreateLinkOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/CreateLinkOperation.java new file mode 100644 index 0000000..98c6fa1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/CreateLinkOperation.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse; + +/** + * + * @author stender + */ +public class CreateLinkOperation extends MRCOperation { + + public CreateLinkOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // perform master redirect if necessary + if (master.getReplMasterUUID() != null && !master.getReplMasterUUID().equals(master.getConfig().getUUID().toString())) + throw new DatabaseException(ExceptionType.REDIRECT); + + final linkRequest rqArgs = (linkRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + final Path lp = new Path(rqArgs.getVolumeName(), rqArgs.getLinkPath()); + final Path tp = new Path(rqArgs.getVolumeName(), rqArgs.getTargetPath()); + + if (!lp.getComp(0).equals(tp.getComp(0))) + throw new UserException(POSIXErrno.POSIX_ERROR_EXDEV, + "cannot create hard links across volume boundaries"); + + final StorageManager sMan = vMan.getStorageManagerByName(lp.getComp(0)); + final PathResolver lRes = new PathResolver(sMan, lp); + final PathResolver tRes = new PathResolver(sMan, tp); + + // check whether the link's path prefix is searchable + faMan.checkSearchPermission(sMan, lRes, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether the link's parent directory grants write access + faMan.checkPermission(FileAccessManager.O_WRONLY, sMan, lRes.getParentDir(), 0, + rq.getDetails().userId, rq.getDetails().superUser, rq.getDetails().groupIds); + + // check whether the link exists already + lRes.checkIfFileExistsAlready(); + + // check whether the target path prefix is searchable + faMan.checkSearchPermission(sMan, tRes, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether the target exists + tRes.checkIfFileDoesNotExist(); + + FileMetadata target = tRes.getFile(); + + if (target.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "no support for links to directories"); + + // check whether the target file grants write access + faMan.checkPermission(FileAccessManager.O_WRONLY, sMan, target, tRes.getParentDirId(), rq + .getDetails().userId, rq.getDetails().superUser, rq.getDetails().groupIds); + + // prepare file creation in database + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // create the link + sMan.link(target, lRes.getParentDirId(), lRes.getFileName(), update); + + // update POSIX timestamps + int time = (int) (TimeSync.getGlobalTime() / 1000); + MRCHelper.updateFileTimes(lRes.getParentsParentId(), lRes.getParentDir(), false, true, true, sMan, + time, update); + MRCHelper.updateFileTimes(tRes.getParentDirId(), target, false, true, false, sMan, time, update); + + // set the response + rq.setResponse(timestampResponse.newBuilder().setTimestampS(time).build()); + + update.execute(); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/CreateSymLinkOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/CreateSymLinkOperation.java new file mode 100644 index 0000000..d941d38 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/CreateSymLinkOperation.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse; + +/** + * + * @author stender + */ +public class CreateSymLinkOperation extends MRCOperation { + + public CreateSymLinkOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // perform master redirect if necessary + if (master.getReplMasterUUID() != null && !master.getReplMasterUUID().equals(master.getConfig().getUUID().toString())) + throw new DatabaseException(ExceptionType.REDIRECT); + + final symlinkRequest rqArgs = (symlinkRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + final Path p = new Path(rqArgs.getVolumeName(), rqArgs.getLinkPath()); + + final StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + final PathResolver res = new PathResolver(sMan, p); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether the parent directory grants write access + faMan.checkPermission(FileAccessManager.O_WRONLY, sMan, res.getParentDir(), 0, + rq.getDetails().userId, rq.getDetails().superUser, rq.getDetails().groupIds); + + // check whether the file/directory exists already + res.checkIfFileExistsAlready(); + + // prepare file creation in database + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // atime, ctime, mtime + int time = (int) (TimeSync.getGlobalTime() / 1000); + + // get the next free file ID + long fileId = sMan.getNextFileId(); + + // create the metadata object + sMan.createSymLink(fileId, res.getParentDirId(), res.getFileName(), time, time, time, + rq.getDetails().userId, rq.getDetails().groupIds.get(0), rqArgs.getTargetPath(), update); + + // set the file ID as the last one + sMan.setLastFileId(fileId, update); + + // update POSIX timestamps of parent directory + MRCHelper.updateFileTimes(res.getParentsParentId(), res.getParentDir(), false, true, true, sMan, + time, update); + + // set the response + rq.setResponse(timestampResponse.newBuilder().setTimestampS(time).build()); + + update.execute(); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/CreateVolumeOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/CreateVolumeOperation.java new file mode 100644 index 0000000..584adba --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/CreateVolumeOperation.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.ErrorRecord; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume; + +/** + * + * @author stender + */ +public class CreateVolumeOperation extends MRCOperation { + + public CreateVolumeOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(final MRCRequest rq) throws Throwable { + + // perform master redirect if replicated and required + String replMasterUUID = master.getReplMasterUUID(); + if (replMasterUUID != null && !replMasterUUID.equals(master.getConfig().getUUID().toString())) { + ServiceUUID uuid = new ServiceUUID(replMasterUUID); + throw new DatabaseException(ExceptionType.REDIRECT, uuid.getAddress().getHostName() + ":" + + uuid.getAddress().getPort()); + } + + final Volume volData = (Volume) rq.getRequestArgs(); + + // check password to ensure that user is authorized + if (master.getConfig().getAdminPassword().length() > 0 + && !master.getConfig().getAdminPassword().equals(rq.getDetails().password)) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "invalid password"); + + validateContext(rq); + + try { + master.getFileAccessManager().getFileAccessPolicy((short) volData.getAccessControlPolicy().getNumber()); + } catch (Exception exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid file access policy ID: " + + volData.getAccessControlPolicy()); + } + + // in order to allow volume creation in a single-threaded + // non-blocking manner, it needs to be performed in two steps: + // * first, the volume is registered with the directory service + // * when registration has been confirmed at the directory service, + // request processing is continued with step 2 + + final String volumeId = master.getVolumeManager().newVolumeId(); + + // check whether a volume with the same name has already been + // registered at the Directory Service + + Map queryMap = new HashMap(); + queryMap.put("name", volData.getName()); + List attrs = new LinkedList(); + attrs.add("version"); + + // Ugly workaround for async call. + Runnable rqThr = new Runnable() { + @Override + public void run() { + try { + ServiceSet sset = master.getDirClient().xtreemfs_service_get_by_type(null, rq.getDetails().auth, + RPCAuthentication.userService, ServiceType.SERVICE_TYPE_VOLUME); + processStep2(volData, volumeId, rq, sset); + } catch (Exception ex) { + finishRequest(rq, new ErrorRecord(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_NONE, + "an error has occurred", ex)); + } + } + }; + Thread thr = new Thread(rqThr); + thr.start(); + } + + private void processStep2(final Volume volData, final String volumeId, final MRCRequest rq, ServiceSet response) { + try { + // check if the volume already exists; if so, return an error + for (Service reg : response.getServicesList()) + if (volData.getName().equals(reg.getName())) { + String uuid = reg.getUuid(); + throw new UserException(POSIXErrno.POSIX_ERROR_EEXIST, "volume '" + volData.getName() + + "' already exists in Directory Service, id='" + uuid + "'"); + } + + // determine owner and owning group for the new volume + String uid = volData.getOwnerUserId(); + String gid = volData.getOwnerGroupId(); + + if ("".equals(uid)) + uid = rq.getDetails().userId; + if ("".equals(gid)) + gid = rq.getDetails().groupIds.get(0); + + // create the volume locally + master.getVolumeManager().createVolume(master.getFileAccessManager(), volumeId, volData.getName(), + (short) volData.getAccessControlPolicy().getNumber(), uid, gid, volData.getDefaultStripingPolicy(), + volData.getMode(), volData.getQuota(), volData.getAttrsList()); + + master.notifyVolumeCreated(); + + // register the volume at the Directory Service + + ServiceDataMap.Builder dmap = ServiceDataMap.newBuilder(); + dmap.addData(KeyValuePair.newBuilder().setKey("mrc").setValue(master.getConfig().getUUID().toString())); + dmap.addData(KeyValuePair.newBuilder().setKey("free").setValue("0")); + + // add all user-defined volume attributes + for (KeyValuePair kv : volData.getAttrsList()) + dmap.addData(KeyValuePair.newBuilder().setKey("attr." + kv.getKey()).setValue(kv.getValue())); + + final Service vol = Service.newBuilder().setType(ServiceType.SERVICE_TYPE_VOLUME).setUuid(volumeId) + .setVersion(0).setName(volData.getName()).setLastUpdatedS(0).setData(dmap).build(); + + // Ugly workaround for async call. + Runnable rqThr = new Runnable() { + @Override + public void run() { + try { + master.getDirClient().xtreemfs_service_register(null, rq.getDetails().auth, + RPCAuthentication.userService, vol); + processStep3(volData, volumeId, rq); + } catch (Exception ex) { + finishRequest(rq, new ErrorRecord(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_NONE, + "an error has occurred", ex)); + } + } + }; + Thread thr = new Thread(rqThr); + thr.start(); + + } catch (UserException exc) { + if (Logging.isDebug()) + Logging.logUserError(Logging.LEVEL_DEBUG, Category.proc, this, exc); + finishRequest(rq, new ErrorRecord(ErrorType.ERRNO, exc.getErrno(), exc.getMessage(), exc)); + } catch (DatabaseException exc) { + finishRequest(rq, new ErrorRecord(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_NONE, + "an error has occurred", exc)); + } catch (Throwable exc) { + finishRequest(rq, new ErrorRecord(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_NONE, + "an error has occurred", exc)); + } + } + + public void processStep3(final Volume rqArgs, final String volumeId, final MRCRequest rq) { + try { + // set the response + rq.setResponse(emptyResponse.getDefaultInstance()); + finishRequest(rq); + } catch (Throwable exc) { + finishRequest(rq, new ErrorRecord(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_NONE, + "an error has occurred", exc)); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/DeleteOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/DeleteOperation.java new file mode 100644 index 0000000..a1d4102 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/DeleteOperation.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.net.InetSocketAddress; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse; + +/** + * + * @author stender + */ +public class DeleteOperation extends MRCOperation { + + public DeleteOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // perform master redirect if necessary + if (master.getReplMasterUUID() != null && !master.getReplMasterUUID().equals(master.getConfig().getUUID().toString())) + throw new DatabaseException(ExceptionType.REDIRECT); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + Path p = new Path((rq.getRequestArgs() instanceof unlinkRequest ? ((unlinkRequest) rq + .getRequestArgs()).getVolumeName() : ((rmdirRequest) rq.getRequestArgs()).getVolumeName()), + (rq.getRequestArgs() instanceof unlinkRequest ? ((unlinkRequest) rq.getRequestArgs()).getPath() + : ((rmdirRequest) rq.getRequestArgs()).getPath())); + + final StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + final PathResolver res = new PathResolver(sMan, p); + final VolumeInfo volume = sMan.getVolumeInfo(); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether the parent directory grants write access + faMan.checkPermission(FileAccessManager.O_WRONLY, sMan, res.getParentDir(), 0, + rq.getDetails().userId, rq.getDetails().superUser, rq.getDetails().groupIds); + + // check whether the file/directory exists + res.checkIfFileDoesNotExist(); + + FileMetadata file = res.getFile(); + + // check whether the entry itself can be deleted (this is e.g. + // important w/ POSIX access control if the sticky bit is set) + faMan.checkPermission(FileAccessManager.NON_POSIX_RM_MV_IN_DIR, sMan, file, res.getParentDirId(), rq + .getDetails().userId, rq.getDetails().superUser, rq.getDetails().groupIds); + + DatabaseResultSet children = sMan.getChildren(file.getId(), 0, Integer.MAX_VALUE); + boolean hasChildren = children.hasNext(); + children.destroy(); + + if (file.isDirectory() && hasChildren) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOTEMPTY, "'" + p + "' is not empty"); + + FileCredentials.Builder creds = null; + + // unless the file is a directory, retrieve X-headers for file + // deletion on OSDs; if the request was authorized before, + // assume that a capability has been issued already. + if (!file.isDirectory()) { + + // create a deletion capability for the file + Capability cap = new Capability(MRCHelper.createGlobalFileId(volume, file), + FileAccessManager.NON_POSIX_DELETE, master.getConfig().getCapabilityTimeout(), + Integer.MAX_VALUE, ((InetSocketAddress) rq.getRPCRequest().getSenderAddress()).getAddress() + .getHostAddress(), file.getEpoch(), false, + !volume.isSnapshotsEnabled() ? SnapConfig.SNAP_CONFIG_SNAPS_DISABLED + : volume.isSnapVolume() ? SnapConfig.SNAP_CONFIG_ACCESS_SNAP + : SnapConfig.SNAP_CONFIG_ACCESS_CURRENT, volume.getCreationTime(), master.getConfig() + .getCapabilitySecret()); + + // set the XCapability and XLocationsList headers + XLocList xloc = file.getXLocList(); + if (xloc != null && xloc.getReplicaCount() > 0) + creds = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs( + Converter.xLocListToXLocSet(xloc)); + } + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // unlink the file; if there are still links to the file, reset the + // X-headers to null, as the file content must not be deleted + sMan.delete(res.getParentDirId(), res.getFileName(), update); + if (file.getLinkCount() > 1) + creds = null; + + int time = (int) (TimeSync.getGlobalTime() / 1000); + + // update POSIX timestamps of parent directory + MRCHelper.updateFileTimes(res.getParentsParentId(), res.getParentDir(), false, true, true, sMan, + time, update); + + if (file.getLinkCount() > 1) + MRCHelper.updateFileTimes(res.getParentDirId(), file, false, true, false, sMan, time, update); + + // set the response, depending on whether the request was for + // deleting a + // file or directory + if (rq.getRequestArgs() instanceof unlinkRequest) { + + unlinkResponse.Builder builder = unlinkResponse.newBuilder().setTimestampS(time); + if (creds != null) + builder.setCreds(creds); + rq.setResponse(builder.build()); + } + + else { + rq.setResponse(timestampResponse.newBuilder().setTimestampS(time).build()); + } + + update.execute(); + + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/DeleteVolumeOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/DeleteVolumeOperation.java new file mode 100644 index 0000000..f99a313 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/DeleteVolumeOperation.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.ErrorRecord; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest; + +/** + * + * @author stender + */ +public class DeleteVolumeOperation extends MRCOperation { + + public DeleteVolumeOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(final MRCRequest rq) throws Throwable { + + // perform master redirect if replicated and required + String replMasterUUID = master.getReplMasterUUID(); + if (replMasterUUID != null && !replMasterUUID.equals(master.getConfig().getUUID().toString())) { + ServiceUUID uuid = new ServiceUUID(replMasterUUID); + throw new DatabaseException(ExceptionType.REDIRECT, uuid.getAddress().getHostName() + ":" + + uuid.getAddress().getPort()); + } + + final xtreemfs_rmvolRequest rqArgs = (xtreemfs_rmvolRequest) rq.getRequestArgs(); + + // check password to ensure that user is authorized + if (master.getConfig().getAdminPassword().length() > 0 + && !master.getConfig().getAdminPassword().equals(rq.getDetails().password)) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "invalid password"); + + final StorageManager sMan = master.getVolumeManager().getStorageManagerByName(rqArgs.getVolumeName()); + final VolumeInfo volume = sMan.getVolumeInfo(); + + // get the volume's root directory + FileMetadata file = sMan.getMetadata(0, volume.getName()); + + // if no admin password has been set, check whether privileged + // permissions are granted for deleting the volume + if (master.getConfig().getAdminPassword().length() == 0) + master.getFileAccessManager().checkPrivilegedPermissions(sMan, file, rq.getDetails().userId, + rq.getDetails().superUser, rq.getDetails().groupIds); + + // Pause the HeartbeatThread while we are deleting the volume. Otherwise, the thread may re-register a + // volume at the DIR which was already deregistered. + master.pauseHeartbeatThread(); + + // Delete the volume from the local database. + try { + master.getVolumeManager().deleteVolume(volume.getId(), master, rq); + master.notifyVolumeDeleted(); + } finally { + master.resumeHeartbeatThread(); + } + + + // Deregister the volume from the Directory Service asynchronously. + // Ugly workaround for async call. + Runnable asyncDeregisterRunner = new Runnable() { + @Override + public void run() { + try { + // Deregister from the DIR. + master.getDirClient().xtreemfs_service_deregister(null, rq.getDetails().auth, + RPCAuthentication.userService, volume.getId()); + + // Set the response. + rq.setResponse(emptyResponse.getDefaultInstance()); + finishRequest(rq); + + } catch (Exception exc) { + finishRequest(rq, new ErrorRecord(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_NONE, + "An error has occurred at the MRC. Details: " + exc.getMessage(), exc)); + } + } + }; + (new Thread(asyncDeregisterRunner)).start(); + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/DumpDBOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/DumpDBOperation.java new file mode 100644 index 0000000..3d70dc1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/DumpDBOperation.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +import org.xtreemfs.foundation.VersionManagement; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest; + +/** + * + * @author stender + */ +public class DumpDBOperation extends MRCOperation { + + class DumpWriter extends Thread { + + private File dumpFile; + + private List sManList; + + public DumpWriter(List sManList, File dumpFile) { + this.dumpFile = dumpFile; + this.sManList = sManList; + } + + public void run() { + + File df = new File(dumpFile + ".inprogress"); + + try { + BufferedWriter xmlWriter = new BufferedWriter(new FileWriter(df)); + xmlWriter.write("\n"); + xmlWriter.write("\n"); + + for (StorageManager sMan : sManList) { + VolumeInfo vol = sMan.getVolumeInfo(); + xmlWriter.write("\n"); + sMan.dumpDB(xmlWriter); + xmlWriter.write("\n"); + } + + xmlWriter.write("\n"); + xmlWriter.close(); + + df.renameTo(dumpFile); + + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "an error has occurred while dumping the database: %s", OutputUtils + .stackTraceToString(exc)); + } + } + + } + + public DumpDBOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final xtreemfs_dump_restore_databaseRequest rqArgs = (xtreemfs_dump_restore_databaseRequest) rq + .getRequestArgs(); + + // check password to ensure that user is authorized + if (master.getConfig().getAdminPassword().length() > 0 + && !master.getConfig().getAdminPassword().equals(rq.getDetails().password)) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "invalid password"); + + // check if the creation of a dump is already in progress; if not, + // create a new dump + if (!new File(rqArgs.getDumpFile() + ".inprogress").exists()) { + + // create snapshots of all volumes + List storageManagers = new LinkedList(); + final VolumeManager vMan = master.getVolumeManager(); + + Collection sManColl = vMan.getStorageManagers(); + if (sManColl == null) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "cannot dump volumes because volume manager has not yet been initialized"); + + for (StorageManager sMan : sManColl) { + + FileMetadata rootDir = sMan.getMetadata(1); + try { + vMan.createSnapshot(sMan.getVolumeInfo().getId(), ".dump", 0, rootDir, true); + + } catch (UserException exc) { + + // if the snapshot exists already, delete it and create it + // again + vMan.deleteSnapshot(sMan.getVolumeInfo().getId(), rootDir, ".dump"); + vMan.createSnapshot(sMan.getVolumeInfo().getId(), ".dump", 0, rootDir, true); + } + + storageManagers.add(vMan.getStorageManagerByName(sMan.getVolumeInfo().getName() + + VolumeManager.SNAPSHOT_SEPARATOR + ".dump")); + } + + // write the dump asynchronously + DumpWriter dw = new DumpWriter(storageManagers, new File(rqArgs.getDumpFile())); + dw.start(); + } + + // set the response + rq.setResponse(emptyResponse.getDefaultInstance()); + finishRequest(rq); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/FSetAttrOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/FSetAttrOperation.java new file mode 100644 index 0000000..046c568 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/FSetAttrOperation.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2010-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest; + +/** + * Sets attributes of a file. + * + * @author stender + */ +public class FSetAttrOperation extends MRCOperation { + + public FSetAttrOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final fsetattrRequest rqArgs = (fsetattrRequest) rq.getRequestArgs(); + + Capability cap = new Capability(rqArgs.getCap(), master.getConfig().getCapabilitySecret()); + + // check whether the capability has a valid signature + if (!cap.hasValidSignature()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, cap + " does not have a valid signature"); + + // check whether the capability has expired + if (cap.hasExpired()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, cap + " has expired"); + + // parse volume and file ID from global file ID + GlobalFileIdResolver idRes = new GlobalFileIdResolver(cap.getFileId()); + + StorageManager sMan = master.getVolumeManager().getStorageManager(idRes.getVolumeId()); + + FileMetadata file = sMan.getMetadata(idRes.getLocalFileId()); + if (file == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + cap.getFileId() + + "' does not exist"); + + // determine which attributes to set + boolean setMode = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_MODE.getNumber()) == MRC.Setattrs.SETATTR_MODE + .getNumber(); + boolean setUID = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_UID.getNumber()) == MRC.Setattrs.SETATTR_UID + .getNumber(); + boolean setGID = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_GID.getNumber()) == MRC.Setattrs.SETATTR_GID + .getNumber(); + boolean setSize = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_SIZE.getNumber()) == MRC.Setattrs.SETATTR_SIZE + .getNumber(); + boolean setAtime = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_ATIME.getNumber()) == MRC.Setattrs.SETATTR_ATIME + .getNumber(); + boolean setCtime = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_CTIME.getNumber()) == MRC.Setattrs.SETATTR_CTIME + .getNumber(); + boolean setMtime = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_MTIME.getNumber()) == MRC.Setattrs.SETATTR_MTIME + .getNumber(); + boolean setAttributes = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_ATTRIBUTES.getNumber()) == MRC.Setattrs.SETATTR_ATTRIBUTES + .getNumber(); + + if (setSize) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "setting file sizes not allowed on open files; use 'xtreemfs_update_file_size' instead"); + + if (setMode || setUID || setGID || setAttributes) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "setting modes, UIDs, GIDs and Win32 attributes not allowed on open files"); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // if ATIME, CTIME or MTIME bits are set, peform 'utimens' + if (setAtime || setCtime || setMtime) { + + // check whether write permissions are granted to file + // faMan.checkPermission("w", sMan, file, res.getParentDirId(), + // rq.getDetails().userId, rq + // .getDetails().superUser, rq.getDetails().groupIds); + + if (setAtime) + file.setAtime((int) (rqArgs.getStbuf().getAtimeNs() / (long) 1e9)); + if (setCtime) + file.setCtime((int) (rqArgs.getStbuf().getCtimeNs() / (long) 1e9)); + if (setMtime) + file.setMtime((int) (rqArgs.getStbuf().getMtimeNs() / (long) 1e9)); + } + + if (setUID || setGID || setAttributes) + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + if (setAtime || setCtime || setMtime || setSize) + sMan.setMetadata(file, FileMetadata.FC_METADATA, update); + + // set the response + rq.setResponse(emptyResponse.getDefaultInstance()); + + update.execute(); + + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/GetFileCredentialsOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/GetFileCredentialsOperation.java new file mode 100644 index 0000000..975b7a1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/GetFileCredentialsOperation.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.net.InetSocketAddress; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest; + +public class GetFileCredentialsOperation extends MRCOperation { + + public GetFileCredentialsOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + final xtreemfs_get_file_credentialsRequest rqArgs = (xtreemfs_get_file_credentialsRequest) rq + .getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + GlobalFileIdResolver gfr = new GlobalFileIdResolver(rqArgs.getFileId()); + + final String volId = gfr.getVolumeId(); + final Long localFileID = gfr.getLocalFileId(); + + StorageManager sMan = vMan.getStorageManager(volId); + VolumeInfo volume = sMan.getVolumeInfo(); + + // get file and check if it exist + FileMetadata file = sMan.getMetadata(localFileID); + if (file == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + rqArgs.getFileId() + + "' does not exist"); + + // check whether privileged permissions are granted for starting replication + faMan.checkPrivilegedPermissions(sMan, file, rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + // create FileCredentials + Capability cap = new Capability(MRCHelper.createGlobalFileId(volume, file), FileAccessManager.O_RDONLY, + master.getConfig().getCapabilityTimeout(), TimeSync.getGlobalTime() / 1000 + + master.getConfig().getCapabilityTimeout(), ((InetSocketAddress) rq.getRPCRequest() + .getSenderAddress()).getAddress().getHostAddress(), file.getEpoch(), false, + !volume.isSnapshotsEnabled() ? SnapConfig.SNAP_CONFIG_SNAPS_DISABLED + : volume.isSnapVolume() ? SnapConfig.SNAP_CONFIG_ACCESS_SNAP + : SnapConfig.SNAP_CONFIG_ACCESS_CURRENT, volume.getCreationTime(), master + .getConfig().getCapabilitySecret()); + + // build new XlocSet with readonlyFileSize set. Necessary to check if replication is complete. + XLocSet newXlocSet = null; + if (file.isReadOnly()) { + newXlocSet = Converter.xLocListToXLocSet(file.getXLocList()).setReadOnlyFileSize(file.getSize()) + .build(); + } else { + newXlocSet = Converter.xLocListToXLocSet(file.getXLocList()).build(); + } + + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(newXlocSet).build(); + + rq.setResponse(fc); + finishRequest(rq); + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/GetLocalVolumesOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/GetLocalVolumesOperation.java new file mode 100644 index 0000000..bfe54d7 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/GetLocalVolumesOperation.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.util.Collection; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.metadata.XAttr; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes; + +/** + * + * @author stender + */ +public class GetLocalVolumesOperation extends MRCOperation { + + public GetLocalVolumesOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + Collection sMans = master.getVolumeManager().getStorageManagers(); + if (sMans == null) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "cannot retrieve volume list because volume manager has not yet been initialized"); + + // check password to ensure that user is authorized + if (master.getConfig().getAdminPassword().length() > 0 + && !master.getConfig().getAdminPassword().equals(rq.getDetails().password)) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "Invalid password. If you see this error at mount.xtreemfs when mounting a volume, please update your client to version 1.3.1 or newer."); + + Volumes.Builder vSet = Volumes.newBuilder(); + for (StorageManager sMan : sMans) { + + Volume.Builder vol = Volume.newBuilder(); + StatVFS vInfo = StatFSOperation.getVolumeInfo(master, sMan); + vol.setAccessControlPolicy(vInfo.getAccessControlPolicy()).setDefaultStripingPolicy( + vInfo.getDefaultStripingPolicy()).setId(vInfo.getFsid()).setMode(vInfo.getMode()).setName( + vInfo.getName()).setOwnerGroupId(vInfo.getOwnerGroupId()).setOwnerUserId( + vInfo.getOwnerUserId()); + + // add volume attributes + final String prefix = "xtreemfs." + MRCHelper.VOL_ATTR_PREFIX + "."; + DatabaseResultSet attrs = sMan.getXAttrs(1, StorageManager.SYSTEM_UID); + while (attrs.hasNext()) { + XAttr attr = attrs.next(); + if (attr.getKey().startsWith(prefix)) { + byte[] valBytes = attr.getValue(); + vol.addAttrs(KeyValuePair.newBuilder().setKey(attr.getKey().substring(prefix.length())) + .setValue(valBytes == null ? null : new String(valBytes))); + } + } + attrs.destroy(); + + vSet.addVolumes(vol); + } + + rq.setResponse(vSet.build()); + finishRequest(rq); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/GetSuitableOSDsOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/GetSuitableOSDsOperation.java new file mode 100644 index 0000000..e62dff2 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/GetSuitableOSDsOperation.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.net.InetSocketAddress; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse; + +/** + * + * @author stender + */ +public class GetSuitableOSDsOperation extends MRCOperation { + + public GetSuitableOSDsOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final xtreemfs_get_suitable_osdsRequest rqArgs = (xtreemfs_get_suitable_osdsRequest) rq + .getRequestArgs(); + + final FileAccessManager faMan = master.getFileAccessManager(); + final VolumeManager vMan = master.getVolumeManager(); + + StorageManager sMan; + String volumeId; + FileMetadata file; + if (rqArgs.hasFileId()) { + + // parse volume and file ID from global file ID + GlobalFileIdResolver idRes = new GlobalFileIdResolver(rqArgs.getFileId()); + volumeId = idRes.getVolumeId(); + + sMan = vMan.getStorageManager(idRes.getVolumeId()); + + // retrieve the file metadata + file = sMan.getMetadata(idRes.getLocalFileId()); + if (file == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + rqArgs.getFileId() + + "' does not exist"); + + } else if (rqArgs.hasVolumeName() && rqArgs.hasPath()) { + + final Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + sMan = vMan.getStorageManagerByName(p.getComp(0)); + final PathResolver res = new PathResolver(sMan, p); + + res.checkIfFileDoesNotExist(); + file = res.getFile(); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + volumeId = sMan.getVolumeInfo().getId(); + + } else + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "either file ID or volume name + path required"); + + if (file.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_EISDIR, + "xtreemfs_get_suitable_osds must be invoked on a file"); + + // retrieve the set of OSDs for the new replica + ServiceSet.Builder usableOSDs = master.getOSDStatusManager().getUsableOSDs(volumeId, + ((InetSocketAddress) rq.getRPCRequest().getSenderAddress()).getAddress(), null, + file.getXLocList(), rqArgs.getNumOsds()); + + xtreemfs_get_suitable_osdsResponse.Builder resp = xtreemfs_get_suitable_osdsResponse.newBuilder(); + for (int i = 0; i < usableOSDs.getServicesCount(); i++) + resp.addOsdUuids(usableOSDs.getServices(i).getUuid()); + + // set the response + rq.setResponse(resp.build()); + finishRequest(rq); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/GetXAttrOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/GetXAttrOperation.java new file mode 100644 index 0000000..b6c6d7d --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/GetXAttrOperation.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse; + +import com.google.protobuf.ByteString; + +/** + * + * @author stender + */ +public class GetXAttrOperation extends MRCOperation { + + public GetXAttrOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final getxattrRequest rqArgs = (getxattrRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + PathResolver res = new PathResolver(sMan, p); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether file exists + res.checkIfFileDoesNotExist(); + + // retrieve and prepare the metadata to return + FileMetadata file = res.getFile(); + + byte[] value = null; + if (rqArgs.getName().startsWith("xtreemfs.")) + value = MRCHelper.getSysAttrValue(master.getConfig(), sMan, master.getOSDStatusManager(), faMan, + res.toString(), file, rqArgs.getName().substring(9)).getBytes(); + else { + + // first, try to fetch an individual user attribute + value = sMan.getXAttr(file.getId(), rq.getDetails().userId, rqArgs.getName()); + + // if no such attribute exists, try to fetch a global attribute + if (value == null) + value = sMan.getXAttr(file.getId(), StorageManager.GLOBAL_ID, rqArgs.getName()); + } + + if (value == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENODATA); + + // set the response + rq.setResponse(getxattrResponse.newBuilder().setValue(new String(value)) + .setValueBytes(ByteString.copyFrom(value)).build()); + finishRequest(rq); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/GetXAttrsOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/GetXAttrsOperation.java new file mode 100644 index 0000000..01f458c --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/GetXAttrsOperation.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.XAttr; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.MRCHelper.SysAttrs; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse; + +import com.google.protobuf.ByteString; + +/** + * + * @author stender + */ +public class GetXAttrsOperation extends MRCOperation { + + public GetXAttrsOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final listxattrRequest rqArgs = (listxattrRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + PathResolver res = new PathResolver(sMan, p); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + // check whether file exists + res.checkIfFileDoesNotExist(); + + // retrieve and prepare the metadata to return + FileMetadata file = res.getFile(); + + Map attrs = new HashMap(); + + DatabaseResultSet myAttrs = sMan.getXAttrs(file.getId(), rq.getDetails().userId); + DatabaseResultSet globalAttrs = sMan.getXAttrs(file.getId(), StorageManager.GLOBAL_ID); + + // include global attributes + while (globalAttrs.hasNext()) { + XAttr attr = globalAttrs.next(); + attrs.put(attr.getKey(), attr.getValue()); + } + globalAttrs.destroy(); + + // include individual user attributes + while (myAttrs.hasNext()) { + XAttr attr = myAttrs.next(); + attrs.put(attr.getKey(), attr.getValue()); + } + myAttrs.destroy(); + + // include system attributes + for (SysAttrs attr : SysAttrs.values()) { + String key = "xtreemfs." + attr.toString(); + String value = MRCHelper.getSysAttrValue(master.getConfig(), sMan, master.getOSDStatusManager(), faMan, + res.toString(), file, attr.toString()); + if (!value.equals("")) + attrs.put(key, value.getBytes()); + } + + // if file ID is root volume + if (file.getId() == 1) { + + // include policy attributes + List policyAttrNames = MRCHelper.getSpecialAttrNames(sMan, MRCHelper.POLICY_ATTR_PREFIX); + for (String attr : policyAttrNames) + attrs.put(attr, sMan.getXAttr(1, StorageManager.SYSTEM_UID, attr)); + + // include volume attributes + List volAttrAttrNames = MRCHelper.getSpecialAttrNames(sMan, MRCHelper.VOL_ATTR_PREFIX); + for (String attr : volAttrAttrNames) + attrs.put(attr, sMan.getXAttr(1, StorageManager.SYSTEM_UID, attr)); + } + + listxattrResponse.Builder result = listxattrResponse.newBuilder(); + for (Entry attr : attrs.entrySet()) { + + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder builder = org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr + .newBuilder().setName(attr.getKey()); + + if (!rqArgs.getNamesOnly()) + builder.setValue(new String(attr.getValue())).setValueBytes(ByteString.copyFrom(attr.getValue())); + + result.addXattrs(builder.build()); + } + + // set the response + rq.setResponse(result.build()); + finishRequest(rq); + + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/GetXLocListOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/GetXLocListOperation.java new file mode 100644 index 0000000..c24383f --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/GetXLocListOperation.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest; + +/** + * @deprecated Replaced by {@link GetXLocSetOperation} + * @author stender + */ +@Deprecated +public class GetXLocListOperation extends MRCOperation { + + public GetXLocListOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final xtreemfs_replica_listRequest rqArgs = (xtreemfs_replica_listRequest) rq.getRequestArgs(); + + final FileAccessManager faMan = master.getFileAccessManager(); + final VolumeManager vMan = master.getVolumeManager(); + + validateContext(rq); + + StorageManager sMan = null; + FileMetadata file = null; + + if (rqArgs.hasFileId()) { + + // parse volume and file ID from global file ID + GlobalFileIdResolver idRes = new GlobalFileIdResolver(rqArgs.getFileId()); + + sMan = vMan.getStorageManager(idRes.getVolumeId()); + + // retrieve the file metadata + file = sMan.getMetadata(idRes.getLocalFileId()); + if (file == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + idRes.getLocalFileId() + + "' does not exist"); + + } else if (rqArgs.hasVolumeName() && rqArgs.hasPath()) { + + final Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + sMan = vMan.getStorageManagerByName(p.getComp(0)); + final PathResolver res = new PathResolver(sMan, p); + + res.checkIfFileDoesNotExist(); + file = res.getFile(); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + } else + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "either file ID or volume name + path required"); + + if (file.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_EISDIR, file.getId() + " is a directory"); + + if (sMan.getSoftlinkTarget(file.getId()) != null) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "file '" + rqArgs.getFileId() + + "' is a symbolic link"); + + XLocList xloc = file.getXLocList(); + assert (xloc != null); + + // get the replicas from the X-Loc list + Replicas.Builder replicas = Replicas.newBuilder(); + for (Replica repl : Converter.xLocListToXLocSet(xloc).getReplicasList()) + replicas.addReplicas(repl); + + // set the response + rq.setResponse(replicas.build()); + finishRequest(rq); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/GetXLocSetOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/GetXLocSetOperation.java new file mode 100644 index 0000000..b129964 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/GetXLocSetOperation.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013 by Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest; + +/** + * Returns the current XLocSet for the file specified in the request.
    + * This is different to {@link GetXLocListOperation} which returns a list of {@link Replicas}. + */ +public class GetXLocSetOperation extends MRCOperation { + + public GetXLocSetOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final xtreemfs_get_xlocsetRequest rqArgs = (xtreemfs_get_xlocsetRequest) rq.getRequestArgs(); + + final FileAccessManager faMan = master.getFileAccessManager(); + final VolumeManager vMan = master.getVolumeManager(); + + StorageManager sMan = null; + FileMetadata file = null; + + if (rqArgs.hasXcap()) { + // Create a capability object to verify the capability. + Capability cap = new Capability(rqArgs.getXcap(), master.getConfig().getCapabilitySecret()); + + // Check whether the capability has a valid signature. + if (!cap.hasValidSignature()) { + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, cap + " does not have a valid signature"); + } + + // Check whether the capability has expired. + if (cap.hasExpired()) { + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, cap + " has expired"); + } + } else { + validateContext(rq); + } + + + // Retrieve the FileMetadata. + if (rqArgs.hasXcap() || rqArgs.hasFileId()) { + String fileId = rqArgs.hasFileId() ? rqArgs.getFileId() : rqArgs.getXcap().getFileId(); + + // Parse volume and file ID from global file ID. + GlobalFileIdResolver idRes = new GlobalFileIdResolver(fileId); + + sMan = vMan.getStorageManager(idRes.getVolumeId()); + + // Retrieve the file metadata. + file = sMan.getMetadata(idRes.getLocalFileId()); + if (file == null) { + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + idRes.getLocalFileId() + + "' does not exist"); + } + + } else if (rqArgs.hasVolumeName() && rqArgs.hasPath()) { + + final Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + sMan = vMan.getStorageManagerByName(p.getComp(0)); + final PathResolver res = new PathResolver(sMan, p); + + res.checkIfFileDoesNotExist(); + file = res.getFile(); + + // Check whether the path prefix is searchable. + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + } else { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "Either file ID, volume name + path or a valid XCap is required"); + } + + if (file.isDirectory()) { + throw new UserException(POSIXErrno.POSIX_ERROR_EISDIR, file.getId() + " is a directory"); + } + + if (sMan.getSoftlinkTarget(file.getId()) != null) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "file '" + rqArgs.getFileId() + + "' is a symbolic link"); + } + + // Get the XLocSet from the XLocList. + XLocList xLocList = file.getXLocList(); + assert (xLocList != null); + XLocSet xLocSet = Converter.xLocListToXLocSet(xLocList).build(); + + // Set the response. + rq.setResponse(xLocSet); + finishRequest(rq); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/InternalDebugOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/InternalDebugOperation.java new file mode 100644 index 0000000..9c7f065 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/InternalDebugOperation.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.util.concurrent.atomic.AtomicBoolean; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class InternalDebugOperation extends MRCOperation { + + private Thread bgrChkptr; + + private final AtomicBoolean asyncChkptRunning; + + public InternalDebugOperation(MRCRequestDispatcher master) { + super(master); + asyncChkptRunning = new AtomicBoolean(false); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final stringMessage rqArgs = (stringMessage) rq.getRequestArgs(); + + // check password to ensure that user is authorized + if (master.getConfig().getAdminPassword().length() > 0 + && !master.getConfig().getAdminPassword().equals(rq.getDetails().password)) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "invalid password"); + + if (rqArgs.getAString().equals("shutdown_babudb")) { + master.getVolumeManager().checkpointDB(); + master.getVolumeManager().shutdown(); + + // set the response + rq.setResponse(stringMessage.newBuilder().setAString("ok").build()); + } else if (rqArgs.getAString().equals("startup_babudb")) { + master.getVolumeManager().init(); + rq.setResponse(stringMessage.newBuilder().setAString("ok").build()); + } else if (rqArgs.getAString().equals("async_checkpoint")) { + Runnable asynChkpt = new Runnable() { + + @Override + public void run() { + try { + asyncChkptRunning.set(true); + final long tStart = System.currentTimeMillis(); + master.getVolumeManager().checkpointDB(); + final long tEnd = System.currentTimeMillis(); + asyncChkptRunning.set(false); + Logging.logMessage(Logging.LEVEL_INFO, this, "checkpoint took " + (tEnd - tStart) + + " ms "); + } catch (DatabaseException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + }; + bgrChkptr = new Thread(asynChkpt); + bgrChkptr.start(); + rq.setResponse(stringMessage.newBuilder().setAString("ok").build()); + } else if (rqArgs.getAString().equals("checkpoint_done")) { + if (asyncChkptRunning.get() == false) + rq.setResponse(stringMessage.newBuilder().setAString("yes").build()); + else + rq.setResponse(stringMessage.newBuilder().setAString("no").build()); + } else { + rq.setResponse(stringMessage.newBuilder().setAString("unknown command").build()); + } + finishRequest(rq); + + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/MRCOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/MRCOperation.java new file mode 100644 index 0000000..2f0af90 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/MRCOperation.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.io.IOException; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; +import org.xtreemfs.mrc.ErrorRecord; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceConstants; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public abstract class MRCOperation { + + protected final MRCRequestDispatcher master; + + public MRCOperation(MRCRequestDispatcher master) { + this.master = master; + } + + /** + * called after request was parsed and operation assigned. + * + * @param rq + * the new request + */ + public abstract void startRequest(MRCRequest rq) throws Throwable; + + /** + * Parses the request arguments. + * + * @param rq + * the request + * + * @return null if successful, error message otherwise + */ + public ErrorRecord parseRequestArgs(MRCRequest rq) { + try { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "parsing request arguments"); + + final Message rqPrototype = MRCServiceConstants.getRequestMessage(rq.getRPCRequest().getHeader() + .getRequestHeader().getProcId()); + if (rqPrototype == null) { + rq.setRequestArgs(null); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "received request with empty message"); + } else { + if (rq.getRPCRequest().getMessage() != null) { + rq.setRequestArgs(rqPrototype.newBuilderForType().mergeFrom( + new ReusableBufferInputStream(rq.getRPCRequest().getMessage())).build()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "received request of type %s", rq.getRequestArgs().getClass().getName()); + } + } else { + rq.setRequestArgs(rqPrototype.getDefaultInstanceForType()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "received request of type %s (empty message)", rq.getRequestArgs().getClass() + .getName()); + } + } + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "parsed request: %s", rqPrototype); + } + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, + "successfully parsed request arguments:"); + + return null; + + } catch (Throwable exc) { + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, + "could not parse request arguments:"); + Logging.logUserError(Logging.LEVEL_DEBUG, Category.stage, this, exc); + } + return new ErrorRecord(ErrorType.GARBAGE_ARGS, POSIXErrno.POSIX_ERROR_EINVAL, exc.getMessage(), + exc); + } + } + + /** + * Returns the context associated with a request. If the request is not + * bound to a context, null is returned. + * + * @param rq + * the MRC request + * @return the context, or null, if not available + */ + public UserCredentials getUserCredentials(MRCRequest rq) throws IOException { + UserCredentials cred = (UserCredentials) rq.getRPCRequest().getHeader().getRequestHeader() + .getUserCreds(); + return cred; + } + + /** + * Completes a request. This method should be used if no error has occurred. + * + * @param rq + */ + public void finishRequest(MRCRequest rq) { + master.requestFinished(rq); + } + + /** + * Completes a request. This method should be used if an error has occurred. + * + * @param rq + * @param error + */ + public void finishRequest(MRCRequest rq, ErrorRecord error) { + rq.setError(error); + master.requestFinished(rq); + } + + protected void validateContext(MRCRequest rq) throws UserException, IOException { + UserCredentials ctx = getUserCredentials(rq); + if ((ctx == null) || (ctx.getGroupsCount() == 0) || (ctx.getUsername().length() == 0)) { + throw new UserException(POSIXErrno.POSIX_ERROR_EACCES, + "UserCredentials must contain a non-empty userID and at least one groupID!"); + } + + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/MoveOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/MoveOperation.java new file mode 100644 index 0000000..2187ff5 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/MoveOperation.java @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.net.InetSocketAddress; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.MRCHelper.FileType; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse; + +/** + * + * @author stender + */ +public class MoveOperation extends MRCOperation { + + public MoveOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // perform master redirect if necessary + if (master.getReplMasterUUID() != null && !master.getReplMasterUUID().equals(master.getConfig().getUUID().toString())) + throw new DatabaseException(ExceptionType.REDIRECT); + + final renameRequest rqArgs = (renameRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + final Path sp = new Path(rqArgs.getVolumeName(), rqArgs.getSourcePath()); + + final StorageManager sMan = vMan.getStorageManagerByName(sp.getComp(0)); + final PathResolver sRes = new PathResolver(sMan, sp); + final VolumeInfo volume = sMan.getVolumeInfo(); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, sRes, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether the parent directory grants write access + faMan.checkPermission(FileAccessManager.O_WRONLY, sMan, sRes.getParentDir(), sRes + .getParentsParentId(), rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + Path tp = new Path(rqArgs.getVolumeName(), rqArgs.getTargetPath()); + + // check arguments + if (sp.getCompCount() == 1) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "cannot move a volume"); + + if (!sp.getComp(0).equals(tp.getComp(0))) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "cannot move between volumes"); + + // check whether the file/directory exists + sRes.checkIfFileDoesNotExist(); + + // check whether the entry itself can be moved (this is e.g. + // important w/ POSIX access control if the sticky bit is set) + faMan.checkPermission(FileAccessManager.NON_POSIX_RM_MV_IN_DIR, sMan, sRes.getFile(), sRes + .getParentDirId(), rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + FileMetadata source = sRes.getFile(); + + // find out what the source path refers to (1 = directory, 2 = file) + FileType sourceType = source.isDirectory() ? FileType.dir : FileType.file; + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + PathResolver tRes = null; + // + // // check if the file is a fuse-hidden file; if so, move it to the + // // .fuse-hidden diretory + // if (tp.getLastComp(0).startsWith(".fuse_hidden")) { + // + // // generate the new path + // tp = MRCHelper.getFuseHiddenPath(tp); + // + // // check if the fuse-hidden directory exists + // try { + // tRes = new PathResolver(sMan, tp); + // + // } catch (UserException exc) { + // + // // if no fuse-hidden directory exists yet ... + // if (exc.getErrno() == ErrNo.ENOENT) { + // + // // get the next free file ID + // long fileId = sMan.getNextFileId(); + // + // // create fuse-hidden directory + // FileMetadata dir = sMan.createDir(fileId, 1, tp.getComp(1), 0, 0, 0, + // "", "", 0777, 0, update); + // + // // set the file ID as the last one + // sMan.setLastFileId(fileId, update); + // + // // re-initialize the path resolver + // tRes = new PathResolver(tp, dir, null); + // } + // + // else + // throw exc; + // } + // + // } + // + // // in the normal case, resolve the target directory + // else + tRes = new PathResolver(sMan, tp); + + FileMetadata targetParentDir = tRes.getParentDir(); + if (targetParentDir == null || !targetParentDir.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOTDIR, "'" + + tp.getComps(0, tp.getCompCount() - 2) + "' is not a directory"); + + FileMetadata target = tRes.getFile(); + + // find out what the target path refers to (0 = does not exist, 1 = + // directory, 2 = file) + FileType targetType = tp.getCompCount() == 1 ? FileType.dir : target == null ? FileType.nexists + : target.isDirectory() ? FileType.dir : FileType.file; + + FileCredentials.Builder creds = null; + + // if both the old and the new directory point to the same + // entity, do nothing + if (sp.equals(tp)) { + rq.setResponse(buildResponse(0, creds)); + finishRequest(rq); + return; + } + + // check whether the path prefix of the target file is + // searchable + faMan.checkSearchPermission(sMan, tRes, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether the parent directory of the target file grants + // write access + faMan.checkPermission(FileAccessManager.O_WRONLY, sMan, tRes.getParentDir(), tRes + .getParentsParentId(), rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + int time = (int) (TimeSync.getGlobalTime() / 1000); + + switch (sourceType) { + + // source is a directory + case dir: { + + // check whether the target is a subdirectory of the + // source directory; if so, throw an exception + if (tp.isSubDirOf(sp)) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "cannot move '" + sp + + "' to one of its own subdirectories"); + + switch (targetType) { + + case nexists: // target does not exist + { + // relink the metadata object to the parent directory of + // the target path and remove the former link + relink(sMan, sRes.getParentDirId(), sRes.getFileName(), source, tRes.getParentDirId(), tRes + .getFileName(), update); + + break; + } + + case dir: // target is a directory + { + + // check whether the target directory may be overwritten; if + // so, delete it + faMan.checkPermission(FileAccessManager.NON_POSIX_DELETE, sMan, target, + tRes.getParentDirId(), rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + DatabaseResultSet children = sMan.getChildren(target.getId(), 0, Integer.MAX_VALUE); + boolean hasChildren = children.hasNext(); + children.destroy(); + + if (hasChildren) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOTEMPTY, "target directory '" + tRes + + "' is not empty"); + else + sMan.delete(tRes.getParentDirId(), tRes.getFileName(), update); + + // relink the metadata object to the parent directory of + // the target path and remove the former link + relink(sMan, sRes.getParentDirId(), sRes.getFileName(), source, tRes.getParentDirId(), tRes + .getFileName(), update); + + break; + } + + case file: // target is a file + throw new UserException(POSIXErrno.POSIX_ERROR_ENOTDIR, "cannot rename directory '" + sRes + + "' to file '" + tRes + "'"); + + } + + break; + + } + + // source is a file + case file: { + + switch (targetType) { + + case nexists: // target does not exist + { + + // relink the metadata object to the parent directory of + // the target path and remove the former link + relink(sMan, sRes.getParentDirId(), sRes.getFileName(), source, tRes.getParentDirId(), tRes + .getFileName(), update); + + break; + } + + case dir: // target is a directory + { + throw new UserException(POSIXErrno.POSIX_ERROR_EISDIR, "cannot rename file '" + sRes + + "' to directory '" + tRes + "'"); + } + + case file: // target is a file + { + + // check whether the target file may be overwritten + // important w/ POSIX access control if the sticky bit is set) + faMan.checkPermission(FileAccessManager.NON_POSIX_RM_MV_IN_DIR, sMan, tRes.getFile(), tRes + .getParentDirId(), rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + // if the file is not a symbolic link, and unless there is still + // another link to the target file, i.e. the target file must + // not be deleted yet, create a 'delete' capability and include + // the XCapability and XLocationsList headers in the response + if (sMan.getSoftlinkTarget(target.getId()) == null && target.getLinkCount() == 1) { + + // create a deletion capability for the file + Capability cap = new Capability(MRCHelper.createGlobalFileId(volume, target), + FileAccessManager.NON_POSIX_DELETE, master.getConfig().getCapabilityTimeout(), + Integer.MAX_VALUE, ((InetSocketAddress) rq.getRPCRequest().getSenderAddress()) + .getAddress().getHostAddress(), target.getEpoch(), false, !volume + .isSnapshotsEnabled() ? SnapConfig.SNAP_CONFIG_SNAPS_DISABLED : volume + .isSnapVolume() ? SnapConfig.SNAP_CONFIG_ACCESS_SNAP + : SnapConfig.SNAP_CONFIG_ACCESS_CURRENT, volume.getCreationTime(), master + .getConfig().getCapabilitySecret()); + + creds = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs( + Converter.xLocListToXLocSet(target.getXLocList())); + } + + // delete the target + sMan.delete(tRes.getParentDirId(), tRes.getFileName(), update); + + // relink the metadata object to the parent directory of + // the target path and remove the former link + relink(sMan, sRes.getParentDirId(), sRes.getFileName(), source, tRes.getParentDirId(), tRes + .getFileName(), update); + + break; + } + + } + + } + } + + // update POSIX timestamps of source and target parent directories + MRCHelper.updateFileTimes(sRes.getParentsParentId(), sRes.getParentDir(), false, true, true, sMan, + time, update); + MRCHelper.updateFileTimes(tRes.getParentsParentId(), tRes.getParentDir(), false, true, true, sMan, + time, update); + + // set the response + rq.setResponse(buildResponse(time, creds)); + + update.execute(); + + } + + private static void relink(StorageManager sMan, long sourceParentDirId, String sourceFileName, + FileMetadata source, long targetParentDirId, String targetFileName, AtomicDBUpdate update) + throws DatabaseException { + + short newLinkCount = sMan.unlink(sourceParentDirId, sourceFileName, update); + source.setLinkCount(newLinkCount); + source.setCtime((int) (TimeSync.getGlobalTime() / 1000)); + sMan.link(source, targetParentDirId, targetFileName, update); + } + + private static renameResponse buildResponse(int time, FileCredentials.Builder creds) { + + renameResponse.Builder resp = renameResponse.newBuilder(); + if (creds != null) + resp.setCreds(creds); + resp.setTimestampS(time); + + return resp.build(); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/OpenOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/OpenOperation.java new file mode 100644 index 0000000..58f79f2 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/OpenOperation.java @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.ReplicationPolicy; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.stages.XLocSetLock; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse; + +/** + * + * @author stender + */ +public class OpenOperation extends MRCOperation { + + public OpenOperation(MRCRequestDispatcher master) { + super(master); + /* + * try { logfile = new PrintWriter(new + * FileOutputStream("/var/lib/xtreemfs/open.log",true)); } catch + * (IOException ex) { ex.printStackTrace(); } + */ + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // perform master redirect if necessary + if (master.getReplMasterUUID() != null && !master.getReplMasterUUID().equals(master.getConfig().getUUID().toString())) + throw new DatabaseException(ExceptionType.REDIRECT); + + final openRequest rqArgs = (openRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + PathResolver res = new PathResolver(sMan, p); + VolumeInfo volume = sMan.getVolumeInfo(); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + FileMetadata file = null; + + // analyze the flags + boolean create = (rqArgs.getFlags() & FileAccessManager.O_CREAT) != 0; + boolean excl = (rqArgs.getFlags() & FileAccessManager.O_EXCL) != 0; + boolean truncate = (rqArgs.getFlags() & FileAccessManager.O_TRUNC) != 0; + boolean write = (rqArgs.getFlags() & (FileAccessManager.O_WRONLY | FileAccessManager.O_RDWR)) != 0; + + boolean createNew = false; + + // atime, ctime, mtime + int time = (int) (TimeSync.getGlobalTime() / 1000); + + // check whether the file/directory exists + try { + + // check if volume is full + long volumeQuota = volume.getVolumeQuota(); + if ((write || create) && volumeQuota != 0 && volumeQuota <= volume.getVolumeSize()) { + throw new UserException(POSIXErrno.POSIX_ERROR_ENOSPC, "the volume's quota is reached"); + } + + res.checkIfFileDoesNotExist(); + + // check if O_CREAT and O_EXCL are set; if so, send an exception + if (create && excl) + res.checkIfFileExistsAlready(); + + file = res.getFile(); + + if (file.isDirectory() || sMan.getSoftlinkTarget(file.getId()) != null) + throw new UserException(POSIXErrno.POSIX_ERROR_EISDIR, "open is restricted to files"); + + // check whether the file is marked as 'read-only'; in this + // case, throw an exception if write access is requested + if (file.isReadOnly() + && ((rqArgs.getFlags() & (FileAccessManager.O_RDWR | FileAccessManager.O_WRONLY + | FileAccessManager.O_TRUNC | FileAccessManager.O_APPEND)) != 0)) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "read-only files cannot be written"); + + // check whether the permission is granted + faMan.checkPermission(rqArgs.getFlags(), sMan, file, res.getParentDirId(), + rq.getDetails().userId, rq.getDetails().superUser, rq.getDetails().groupIds); + + } catch (UserException exc) { + + // if the file does not exist, check whether the O_CREAT flag + // has been provided + if (exc.getErrno() == POSIXErrno.POSIX_ERROR_ENOENT && create) { + + // check for write permission in parent dir + // check whether the parent directory grants write access + faMan.checkPermission(FileAccessManager.O_WRONLY, sMan, res.getParentDir(), res + .getParentsParentId(), rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // get the next free file ID + long fileId = sMan.getNextFileId(); + + if ((rqArgs.getMode() & GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFIFO.getNumber()) != 0) { + throw new UserException(POSIXErrno.POSIX_ERROR_EIO, "FIFOs not supported"); + } + + // create the metadata object + file = sMan.createFile(fileId, res.getParentDirId(), res.getFileName(), time, time, time, rq + .getDetails().userId, rq.getDetails().groupIds.get(0), rqArgs.getMode(), rqArgs + .getAttributes(), 0, false, 0, 0, update); + + // set the file ID as the last one + sMan.setLastFileId(fileId, update); + + createNew = true; + } + + else + throw exc; + } + + XLocList xLocList = file.getXLocList(); + + // Check if a xLocSet change is in progress and recover if a previous change failed due to an MRC error. + XLocSetLock lock = master.getXLocSetCoordinator().getXLocSetLock(file, sMan); + if (lock.isLocked()) { + if (lock.hasCrashed()) { + // If the xLocSet change did not finish, the majority of the replicas could be invalidated. To allow + // operations on the (old) xLocSet, the version has to be increased to revalidate the replicas. + XLoc[] replicas = new XLoc[xLocList.getReplicaCount()]; + for (int i = 0; i < xLocList.getReplicaCount(); i++) { + replicas[i] = xLocList.getReplica(i); + } + xLocList = sMan.createXLocList(replicas, xLocList.getReplUpdatePolicy(), xLocList.getVersion() + 1); + + // Unlock the replica. + master.getXLocSetCoordinator().unlockXLocSet(file, sMan, update); + } else { + throw new UserException(POSIXErrno.POSIX_ERROR_EAGAIN, + "xLocSet change already in progress. Please retry."); + } + } + + // get the current epoch, use (and increase) the truncate number if + // the open mode is truncate + int trEpoch = file.getEpoch(); + if (truncate) { + file.setIssuedEpoch(file.getIssuedEpoch() + 1); + trEpoch = file.getIssuedEpoch(); + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + } + + // retrieve the default replication policy + ReplicationPolicy defaultReplPolicy = sMan.getDefaultReplicationPolicy(res.getParentDirId()); + if (defaultReplPolicy == null) + defaultReplPolicy = sMan.getDefaultReplicationPolicy(1); + + // flag indicating whether on-close replication will be triggered + boolean replicateOnClose = defaultReplPolicy != null + && ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY.equals(defaultReplPolicy.getName()); + + // if no replicas have been assigned yet ... + if ((xLocList == null || xLocList.getReplicaCount() == 0) && (create || write)) { + + // if the file is supposed to be read-only replicated, create a + // non-replicated file and defer the replication until the file is + // closed + boolean singleReplica = defaultReplPolicy == null + || ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE.equals(defaultReplPolicy.getName()) + || replicateOnClose; + + if (singleReplica) { + + // create a replica with the default striping policy together + // with a set of feasible OSDs from the OSD status manager + XLoc replica = MRCHelper.createReplica(null, sMan, master.getOSDStatusManager(), volume, res + .getParentDirId(), p.toString(), ((InetSocketAddress) rq.getRPCRequest() + .getSenderAddress()).getAddress(), rqArgs.getCoordinates(), xLocList, 0); + + // integrate the new replica in the XLoc list + String[] osds = new String[replica.getOSDCount()]; + for (int j = 0; j < osds.length; j++) + osds[j] = replica.getOSD(j); + + List repls = new ArrayList(); + repls.add(replica); + + // update the XLoc list with the new replica; this is + // necessary to ensure that its OSDs will be included when + // adding further replias in the following loop iterations + xLocList = sMan.createXLocList(repls.toArray(new XLoc[repls.size()]), + ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE, 0); + + } + + // otherwise, create the requested number of replicas + else { + + // determine the number of replicas to be added + int numReplicas = 1; + if (defaultReplPolicy != null) + numReplicas = defaultReplPolicy.getFactor(); + + // assign as many new replicas as needed + List repls = new ArrayList(); + for (int i = 0; i < numReplicas; i++) { + + // create a replica with the default striping policy + // together + // with a set of feasible OSDs from the OSD status manager + XLoc replica = MRCHelper.createReplica(null, sMan, master.getOSDStatusManager(), volume, + res.getParentDirId(), p.toString(), ((InetSocketAddress) rq.getRPCRequest() + .getSenderAddress()).getAddress(), rqArgs.getCoordinates(), xLocList, + defaultReplPolicy != null ? defaultReplPolicy.getFlags() : 0); + + // integrate the new replica in the XLoc list + String[] osds = new String[replica.getOSDCount()]; + for (int j = 0; j < osds.length; j++) + osds[j] = replica.getOSD(j); + + repls.add(replica); + + // update the XLoc list with the new replica; this is + // necessary to ensure that its OSDs will be included when + // adding further replias in the following loop iterations + xLocList = sMan.createXLocList(repls.toArray(new XLoc[repls.size()]), + defaultReplPolicy != null ? defaultReplPolicy.getName() + : ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE, 0); + } + + } + + // update the file's XLoc list + file.setXLocList(xLocList); + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "assigned the following XLoc list to file %s:%d: %s", volume.getId(), file.getId(), + xLocList.toString()); + } + + // convert the XLocList to an XLocSet (necessary for later client + // transfer) + XLocSet.Builder xLocSet = Converter.xLocListToXLocSet(xLocList); + + // re-order the replica list, based on the replica selection policy + List sortedReplList = master.getOSDStatusManager().getSortedReplicaList(volume.getId(), + ((InetSocketAddress) rq.getRPCRequest().getSenderAddress()).getAddress(), + rqArgs.getCoordinates(), xLocSet.getReplicasList(), xLocList).getReplicasList(); + xLocSet.clearReplicas(); + xLocSet.addAllReplicas(sortedReplList); + xLocSet.setReadOnlyFileSize(file.getSize()); + + // issue a new capability + Capability cap = new Capability(MRCHelper.createGlobalFileId(volume, file), rqArgs.getFlags(), master + .getConfig().getCapabilityTimeout(), TimeSync.getGlobalTime() / 1000 + + master.getConfig().getCapabilityTimeout(), ((InetSocketAddress) rq.getRPCRequest() + .getSenderAddress()).getAddress().getHostAddress(), trEpoch, replicateOnClose, !volume + .isSnapshotsEnabled() ? SnapConfig.SNAP_CONFIG_SNAPS_DISABLED + : volume.isSnapVolume() ? SnapConfig.SNAP_CONFIG_ACCESS_SNAP + : SnapConfig.SNAP_CONFIG_ACCESS_CURRENT, volume.getCreationTime(), master.getConfig() + .getCapabilitySecret()); + + if (Logging.isDebug()) + Logging + .logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "issued the following capability for %s:%d: %s", volume.getId(), file.getId(), cap + .toString()); + + // update POSIX timestamps of file + + if (createNew || truncate) { + // create or truncate: ctime + mtime, atime only if create + MRCHelper.updateFileTimes(res.getParentsParentId(), file, createNew ? !master.getConfig() + .isNoAtime() : false, true, true, sMan, time, update); + + } else if (!master.getConfig().isNoAtime()) { + // otherwise: only atime, if necessary + MRCHelper.updateFileTimes(res.getParentsParentId(), file, true, false, false, sMan, time, update); + } else { + time = 0; + } + + // update POSIX timestamps of parent directory, in case of a newly + // created file + if (createNew) + MRCHelper.updateFileTimes(res.getParentsParentId(), res.getParentDir(), false, true, true, sMan, + time, update); + + // set the response + rq.setResponse(openResponse.newBuilder().setCreds( + FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLocSet)).setTimestampS(time) + .build()); + + update.execute(); + + // enable only for test servers that should log each file + // create/write/trunc + /* + * if (create || write || truncate) { try { + * logfile.print(System.currentTimeMillis + * ()+";"+rq.getRPCRequest().getClientIdentity + * ()+";"+rqArgs.getPath()+"\n"); logfile.flush(); } catch (Exception + * ex) { + * + * } } + */ + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/ReadDirAndStatOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/ReadDirAndStatOperation.java new file mode 100644 index 0000000..1cbd8ca --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/ReadDirAndStatOperation.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.io.File; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCException; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest; + +/** + * + * @author stender + */ +public class ReadDirAndStatOperation extends MRCOperation { + + public ReadDirAndStatOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final readdirRequest rqArgs = (readdirRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + PathResolver res = new PathResolver(sMan, p); + VolumeInfo volume = sMan.getVolumeInfo(); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether file exists + res.checkIfFileDoesNotExist(); + + FileMetadata file = res.getFile(); + + // check whether the directory grants read access + faMan.checkPermission(FileAccessManager.O_RDONLY, sMan, file, res.getParentDirId(), + rq.getDetails().userId, rq.getDetails().superUser, rq.getDetails().groupIds); + + // TODO: support dirs w/ more than Integer.MAX_VALUE entries + int seenEntries = (int) rqArgs.getSeenDirectoryEntriesCount(); + int numEntries = rqArgs.getLimitDirectoryEntriesCount() <= 0 ? Integer.MAX_VALUE : rqArgs + .getLimitDirectoryEntriesCount(); + boolean namesOnly = rqArgs.getNamesOnly(); + + // do not report stat info for individual files if there are no search + // permissions on the directory + try { + faMan.checkPermission(FileAccessManager.NON_POSIX_SEARCH, sMan, file, res.getParentDirId(), rq + .getDetails().userId, rq.getDetails().superUser, rq.getDetails().groupIds); + } catch (UserException exc) { + if (exc.getErrno() == POSIXErrno.POSIX_ERROR_EACCES) + namesOnly = true; + else + throw exc; + } + + DirectoryEntries.Builder dirContent = DirectoryEntries.newBuilder(); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // if required, update POSIX timestamps + int time = (int) (TimeSync.getGlobalTime() / 1000); + if (!master.getConfig().isNoAtime()) + MRCHelper.updateFileTimes(res.getParentDirId(), file, true, false, false, sMan, time, update); + + // get the parent directory + FileMetadata parentDir = res.getParentDir(); + + if (seenEntries == 0 && numEntries > 0) { + + // dir is not root directory + if (parentDir != null) { + + DirectoryEntry.Builder entry = DirectoryEntry.newBuilder().setName(".."); + if (!namesOnly) + entry.setStbuf(getStat(sMan, faMan, rq, volume, parentDir)); + + dirContent.addEntries(entry); + + } + + // dir is root directory + else { + + DirectoryEntry.Builder entry = DirectoryEntry.newBuilder().setName(".."); + if (!namesOnly) + entry.setStbuf(getStat(sMan, faMan, rq, volume, file)); + + dirContent.addEntries(entry); + } + + } + + // get the current directory + Stat stat = getStat(sMan, faMan, rq, volume, file); + long newEtag = stat.getEtag(); + long knownEtag = rqArgs.getKnownEtag(); + + if (newEtag != knownEtag) { + + if ((seenEntries == 0 && numEntries >= 2) || (seenEntries == 1 && numEntries >= 1)) { + + DirectoryEntry.Builder entry = DirectoryEntry.newBuilder().setName("."); + if (!namesOnly) + entry.setStbuf(stat); + + dirContent.addEntries(entry); + } + + // get all children + DatabaseResultSet it = sMan.getChildren(res.getFile().getId(), seenEntries - 2, numEntries + - dirContent.getEntriesCount()); + while (it.hasNext()) { + + FileMetadata child = it.next(); + if (child.getFileName().equals("")) { + Logging.logMessage(Logging.LEVEL_WARN, this, "WARNING: found nested %s w/ empty name", child + .isDirectory() ? "directory" : "file"); + continue; + } + + DirectoryEntry.Builder entry = DirectoryEntry.newBuilder().setName(child.getFileName()); + if (!namesOnly) + entry.setStbuf(getStat(sMan, faMan, rq, volume, child)); + + dirContent.addEntries(entry); + } + it.destroy(); + + } + + // set the response + rq.setResponse(dirContent.build()); + + update.execute(); + } + + private Stat getStat(StorageManager sMan, FileAccessManager faMan, MRCRequest rq, VolumeInfo volume, + FileMetadata file) throws DatabaseException, MRCException { + + // FIXME: merge w/ 'stat' operation + + String linkTarget = sMan.getSoftlinkTarget(file.getId()); + int mode = faMan.getPosixAccessMode(sMan, file, rq.getDetails().userId, rq.getDetails().groupIds); + mode |= linkTarget != null ? GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFLNK.getNumber() + : file.isDirectory() ? GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFDIR.getNumber() + : ((file.getPerms() & GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFIFO.getNumber()) != 0) ? GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFIFO + .getNumber() + : GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFREG.getNumber(); + long size = linkTarget != null ? linkTarget.length() : file.isDirectory() ? 0 : file.getSize(); + int blkSize = 0; + if ((linkTarget == null) && (!file.isDirectory())) { + XLocList xlocList = file.getXLocList(); + if ((xlocList != null) && (xlocList.getReplicaCount() > 0)) + blkSize = xlocList.getReplica(0).getStripingPolicy().getStripeSize() * 1024; + } + + final long newEtag = file.getMtime() + file.getCtime(); + + Stat stat = Stat.newBuilder().setDev(volume.getId().hashCode()).setIno(file.getId()).setMode(mode) + .setNlink(file.getLinkCount()).setUserId(file.getOwnerId()).setGroupId( + file.getOwningGroupId()).setSize(size).setAtimeNs((long) file.getAtime() * (long) 1e9) + .setCtimeNs((long) file.getCtime() * (long) 1e9).setMtimeNs( + (long) file.getMtime() * (long) 1e9).setBlksize(blkSize).setTruncateEpoch( + file.isDirectory() ? 0 : file.getEpoch()).setAttributes((int) file.getW32Attrs()) + .setEtag(newEtag).build(); + + return stat; + } + + public static void main(String[] args) throws Exception { + + String path = "/home/stender/mnt"; + File f = new File(path); + System.out.println(f.createNewFile()); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/ReadLinkOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/ReadLinkOperation.java new file mode 100644 index 0000000..f5c85cf --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/ReadLinkOperation.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse; + +import com.google.protobuf.Message; + +/** + * + * @author stender + */ +public class ReadLinkOperation extends MRCOperation { + + public ReadLinkOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final readlinkRequest rqArgs = (readlinkRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + PathResolver res = new PathResolver(sMan, p); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether file exists + res.checkIfFileDoesNotExist(); + + FileMetadata file = res.getFile(); + + // if the file refers to a symbolic link, resolve the link + String target = sMan.getSoftlinkTarget(file.getId()); + if (target == null) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, rqArgs.getPath() + " is not a softlink"); + + // set the response + rq.setResponse(readlinkResponse.newBuilder().addLinkTargetPath(target).build()); + finishRequest(rq); + + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/RemoveReplicaOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/RemoveReplicaOperation.java new file mode 100644 index 0000000..dcfa858 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/RemoveReplicaOperation.java @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.net.InetSocketAddress; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.stages.XLocSetCoordinator; +import org.xtreemfs.mrc.stages.XLocSetCoordinatorCallback; +import org.xtreemfs.mrc.stages.XLocSetLock; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest; + +/** + * + * @author stender + */ +public class RemoveReplicaOperation extends MRCOperation implements XLocSetCoordinatorCallback { + + public RemoveReplicaOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // Perform master redirect if necessary. + if (master.getReplMasterUUID() != null + && !master.getReplMasterUUID().equals(master.getConfig().getUUID().toString())) { + throw new DatabaseException(ExceptionType.REDIRECT); + } + + final xtreemfs_replica_removeRequest rqArgs = (xtreemfs_replica_removeRequest) rq.getRequestArgs(); + + final FileAccessManager faMan = master.getFileAccessManager(); + final VolumeManager vMan = master.getVolumeManager(); + + validateContext(rq); + + StorageManager sMan; + FileMetadata file; + String volumeId; + String fileId; + + if (rqArgs.hasFileId()) { + + fileId = rqArgs.getFileId(); + + // Parse volume and file ID from global file ID. + GlobalFileIdResolver idRes = new GlobalFileIdResolver(fileId); + volumeId = idRes.getVolumeId(); + + sMan = vMan.getStorageManager(idRes.getVolumeId()); + + // Retrieve the file metadata. + file = sMan.getMetadata(idRes.getLocalFileId()); + if (file == null) { + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + rqArgs.getFileId() + + "' does not exist"); + } + + } else if (rqArgs.hasVolumeName() && rqArgs.hasPath()) { + + final Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + sMan = vMan.getStorageManagerByName(p.getComp(0)); + volumeId = sMan.getVolumeInfo().getId(); + + final PathResolver res = new PathResolver(sMan, p); + + res.checkIfFileDoesNotExist(); + file = res.getFile(); + + fileId = MRCHelper.createGlobalFileId(sMan.getVolumeInfo(), file); + + // Check whether the path prefix is searchable. + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + } else { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "either file ID or volume name + path required"); + } + + if (file.isDirectory()) { + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "replicas may only be removed from files"); + } + + if (sMan.getSoftlinkTarget(file.getId()) != null) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "file '" + rqArgs.getFileId() + + "' is a symbolic link"); + } + + // Check if a xLocSetChange is already in progress. + XLocSetLock lock = master.getXLocSetCoordinator().getXLocSetLock(file, sMan); + if (lock.isLocked()) { + if (lock.hasCrashed()) { + // Ignore if a previous xLocSet change did not finish, because the replicas will be revalidated when the + // new xLocSet is installed by this operation. + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Previous xLocSet change did not finish."); + } + } else { + throw new UserException(POSIXErrno.POSIX_ERROR_EAGAIN, + "xLocSet change already in progress. Please retry."); + } + } + + // Check whether privileged permissions are granted for removing replicas. + faMan.checkPrivilegedPermissions(sMan, file, rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + XLocList oldXLocList = file.getXLocList(); + assert (oldXLocList != null); + + // Do not delete replicas from non-replicated files. + if (ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE.equals(oldXLocList.getReplUpdatePolicy())) { + throw new UserException( + POSIXErrno.POSIX_ERROR_EINVAL, + "Replica cannot be removed because the file's replication policy is set to 'none' i.e., " + + "the file has only one replica which shouldn't be deleted. Delete the whole file instead."); + } + + // Find and remove the replica from the X-Locations list. + int i = 0; + XLoc replica = null; + for (; i < oldXLocList.getReplicaCount(); i++) { + + replica = oldXLocList.getReplica(i); + + // Compare the first elements from the lists; since an OSD may + // only occur once in each X-Locations list, it is not necessary + // to go through the entire list. + if (replica.getOSD(0).equals(rqArgs.getOsdUuid())) + break; + } + + // If the OSD could not be found, throw a corresponding user exception. + if (i == oldXLocList.getReplicaCount()) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "OSD '" + rqArgs.getOsdUuid() + + "' is not head OSD of any replica"); + } + + // Create a new X-Locations list that excludes the replica to remove. + XLoc[] newReplList = new XLoc[oldXLocList.getReplicaCount() - 1]; + for (int j = 0, count = 0; j < oldXLocList.getReplicaCount(); j++) { + if (j != i) { + newReplList[count++] = oldXLocList.getReplica(j); + } + } + XLocList newXLocList = sMan.createXLocList(newReplList, oldXLocList.getReplUpdatePolicy(), + oldXLocList.getVersion() + 1); + + // If the file is read-only replicated, check if at + // least one complete or one full replica remains. + if (ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY.equals(oldXLocList.getReplUpdatePolicy())) { + + boolean completeOrFullExists = false; + for (int k = 0; k < newXLocList.getReplicaCount(); k++) { + if (ReplicationFlags.isReplicaComplete(newXLocList.getReplica(k).getReplicationFlags()) + || ReplicationFlags.isFullReplica(newXLocList.getReplica(k).getReplicationFlags())) { + completeOrFullExists = true; + break; + } + } + + if (!completeOrFullExists) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "Could not remove OSD '" + rqArgs.getOsdUuid() + + "': read-only replication w/ partial replicas requires at " + + "least one remaining replica that is full or complete"); + } + } + + XLocSetCoordinator coordinator = master.getXLocSetCoordinator(); + XLocSetCoordinator.RequestMethod m = coordinator.removeReplicas(fileId, file, oldXLocList, newXLocList, rq, + this); + + // Make an update with the RequestMethod as context and the Coordinator as callback. This will enqueue + // the RequestMethod when the update is complete + AtomicDBUpdate update = sMan.createAtomicDBUpdate(coordinator, m); + + // Lock the replica and start the coordination. + coordinator.lockXLocSet(file, sMan, update); + + update.execute(); + } + + @Override + public void installXLocSet(MRCRequest rq, String fileId, XLocList xLocList, XLocList oldXLocList) throws Throwable { + + final VolumeManager vMan = master.getVolumeManager(); + final GlobalFileIdResolver idRes = new GlobalFileIdResolver(fileId); + final StorageManager sMan = vMan.getStorageManager(idRes.getVolumeId()); + + // Retrieve the file metadata. + final FileMetadata file = sMan.getMetadata(idRes.getLocalFileId()); + if (file == null) { + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + fileId + "' does not exist"); + } + + // Assign the new XLoc list. + file.setXLocList(xLocList); + + // Remove the read-only flag if only one replica remains. + if (xLocList.getReplicaCount() == 1) { + file.setReadOnly(false); + } + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // Update the X-Locations list. + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + // Unlock the replica. + master.getXLocSetCoordinator().unlockXLocSet(file, sMan, update); + + // Create a deletion capability for the replica. + Capability deleteCap = new Capability(idRes.getVolumeId() + ":" + file.getId(), + FileAccessManager.NON_POSIX_DELETE, master.getConfig().getCapabilityTimeout(), Integer.MAX_VALUE, + ((InetSocketAddress) rq.getRPCRequest().getSenderAddress()).getAddress().getHostAddress(), + file.getEpoch(), false, + !sMan.getVolumeInfo().isSnapshotsEnabled() ? SnapConfig.SNAP_CONFIG_SNAPS_DISABLED : sMan + .getVolumeInfo().isSnapVolume() ? SnapConfig.SNAP_CONFIG_ACCESS_SNAP + : SnapConfig.SNAP_CONFIG_ACCESS_CURRENT, sMan.getVolumeInfo().getCreationTime(), master + .getConfig().getCapabilitySecret()); + + // Convert xloc list. + XLocSet.Builder xLocSet = Converter.xLocListToXLocSet(oldXLocList); + + // Wrap xcap and xloc list. + FileCredentials fc = FileCredentials.newBuilder().setXcap(deleteCap.getXCap()).setXlocs(xLocSet).build(); + + // Set the response. + rq.setResponse(fc); + + update.execute(); + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/RemoveXAttrOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/RemoveXAttrOperation.java new file mode 100644 index 0000000..35de52e --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/RemoveXAttrOperation.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse; + +/** + * + * @author stender + */ +public class RemoveXAttrOperation extends MRCOperation { + + public RemoveXAttrOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final removexattrRequest rqArgs = (removexattrRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + validateContext(rq); + + StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + PathResolver res = new PathResolver(sMan, p); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether file exists + res.checkIfFileDoesNotExist(); + + // retrieve and prepare the metadata to return + FileMetadata file = res.getFile(); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // if the attribute is a system attribute, set it + + final String attrKey = rqArgs.getName(); + + // set a system attribute + if (attrKey.startsWith("xtreemfs.")) { + + // check whether the user has privileged permissions to set + // system attributes + faMan.checkPrivilegedPermissions(sMan, file, rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + MRCHelper.setSysAttrValue(sMan, vMan, faMan, res.getParentDirId(), file, attrKey.substring(9), + "", update); + } + + // set a user attribute + else { + + sMan.setXAttr(file.getId(), rq.getDetails().userId, attrKey, null, update); + } + + // update POSIX timestamps + int time = (int) (TimeSync.getGlobalTime() / 1000); + MRCHelper.updateFileTimes(res.getParentDirId(), file, false, true, false, sMan, time, update); + + // set the response + rq.setResponse(timestampResponse.newBuilder().setTimestampS(time).build()); + + update.execute(); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/RenewOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/RenewOperation.java new file mode 100644 index 0000000..8580d19 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/RenewOperation.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; + +import com.google.protobuf.Message; + +/** + * + * @author stender + */ +public class RenewOperation extends MRCOperation { + + public final boolean renewTimedOutCaps; + + public RenewOperation(MRCRequestDispatcher master) { + super(master); + renewTimedOutCaps = master.getConfig().isRenewTimedOutCaps(); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final XCap xcap = (XCap) rq.getRequestArgs(); + + // create a capability object to verify the capability + Capability cap = new Capability(xcap, master.getConfig().getCapabilitySecret()); + + // check whether the capability has a valid signature + if (!cap.hasValidSignature()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, cap + " does not have a valid signature"); + + // check whether the capability has expired + if (cap.hasExpired() && !renewTimedOutCaps) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, cap + " has expired"); + + Capability newCap = new Capability(cap.getFileId(), cap.getAccessMode(), master.getConfig() + .getCapabilityTimeout(), TimeSync.getGlobalTime() / 1000 + + master.getConfig().getCapabilityTimeout(), cap.getClientIdentity(), cap.getEpochNo(), cap + .isReplicateOnClose(), cap.getSnapConfig(), cap.getSnapTimestamp(), master.getConfig() + .getCapabilitySecret()); + + // set the response + rq.setResponse(newCap.getXCap()); + finishRequest(rq); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/RestoreDBOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/RestoreDBOperation.java new file mode 100644 index 0000000..7be5002 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/RestoreDBOperation.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.io.File; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.ErrorRecord; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.utils.DBAdminHelper; +import org.xtreemfs.mrc.utils.DBAdminHelper.DBRestoreState; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest; + +/** + * + * @author stender + */ +public class RestoreDBOperation extends MRCOperation { + + public RestoreDBOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + try { + + final xtreemfs_dump_restore_databaseRequest rqArgs = (xtreemfs_dump_restore_databaseRequest) rq + .getRequestArgs(); + + // check password to ensure that user is authorized + if (master.getConfig().getAdminPassword().length() > 0 + && !master.getConfig().getAdminPassword().equals(rq.getDetails().password)) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "invalid password"); + + final VolumeManager vMan = master.getVolumeManager(); + + if (vMan.getStorageManagers() == null) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "cannot restore database because volume manager has not yet been initialized"); + + // First, check if any volume exists already. If so, deny the + // operation for security reasons. + if (vMan.getStorageManagers().size() != 0) + throw new UserException( + POSIXErrno.POSIX_ERROR_EPERM, + "Restoring from a dump is only possible on an MRC with no database. Please delete the existing MRC database on the server and restart the MRC!"); + + SAXParserFactory spf = SAXParserFactory.newInstance(); + SAXParser sp = spf.newSAXParser(); + sp.parse(new File(rqArgs.getDumpFile()), new DefaultHandler() { + + private DBRestoreState state; + + private int dbVersion = 1; + + public void startElement(String uri, String localName, String qName, Attributes attributes) + throws SAXException { + + try { + + if (qName.equals("volume")) { + + state = new DBRestoreState(); + state.currentVolumeId = attributes.getValue(attributes.getIndex("id")); + state.currentVolumeName = attributes.getValue(attributes.getIndex("name")); + state.currentVolumeACPolicy = Short.parseShort(attributes.getValue(attributes + .getIndex("acPolicy"))); + state.currentVolumeQuota = Long.valueOf(attributes.getValue(attributes.getIndex("quota"))); + + } + + else if (qName.equals("filesystem")) + try { + dbVersion = Integer.parseInt(attributes.getValue(attributes + .getIndex("dbversion"))); + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_WARN, Category.storage, this, + "restoring database with invalid version number"); + } + + else + handleNestedElement(qName, attributes, true); + + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "could not restore DB from XML dump"); + Logging.logUserError(Logging.LEVEL_ERROR, Category.storage, this, exc); + throw new SAXException(exc); + } + } + + public void endElement(String uri, String localName, String qName) throws SAXException { + + try { + if (qName.equals("slice") || qName.equals("filesystem")) + return; + + handleNestedElement(qName, null, false); + + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "could not restore DB from XML dump"); + Logging.logUserError(Logging.LEVEL_ERROR, Category.storage, this, exc); + throw new SAXException(exc); + } + } + + private void handleNestedElement(String qName, Attributes attributes, boolean openTag) + throws UserException, DatabaseException { + + if (qName.equalsIgnoreCase("volume")) { + + // set the largest file ID + StorageManager sMan = vMan.getStorageManager(state.currentVolumeId); + AtomicDBUpdate update = sMan.createAtomicDBUpdate(null, null); + sMan.setLastFileId(state.largestFileId, update); + update.execute(); + state.largestFileId = 0; + + } else if (qName.equalsIgnoreCase("dir")) + DBAdminHelper.restoreDir(vMan, master.getFileAccessManager(), attributes, state, + dbVersion, openTag); + else if (qName.equalsIgnoreCase("file")) + DBAdminHelper.restoreFile(vMan, master.getFileAccessManager(), attributes, state, + dbVersion, openTag); + else if (qName.equalsIgnoreCase("xLocList")) + DBAdminHelper.restoreXLocList(vMan, master.getFileAccessManager(), attributes, state, + dbVersion, openTag); + else if (qName.equalsIgnoreCase("xLoc")) + DBAdminHelper.restoreXLoc(vMan, master.getFileAccessManager(), attributes, state, + dbVersion, openTag); + else if (qName.equalsIgnoreCase("osd")) + DBAdminHelper.restoreOSD(vMan, master.getFileAccessManager(), attributes, state, + dbVersion, openTag); + else if (qName.equalsIgnoreCase("acl")) + DBAdminHelper.restoreACL(vMan, master.getFileAccessManager(), attributes, state, + dbVersion, openTag); + else if (qName.equalsIgnoreCase("entry")) + DBAdminHelper.restoreEntry(vMan, master.getFileAccessManager(), attributes, state, + dbVersion, openTag); + else if (qName.equalsIgnoreCase("attr")) + DBAdminHelper.restoreAttr(vMan, master.getFileAccessManager(), attributes, state, + dbVersion, openTag); + } + + }); + + // set the response + rq.setResponse(emptyResponse.getDefaultInstance()); + finishRequest(rq); + + } catch (SAXException exc) { + finishRequest(rq, new ErrorRecord(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_NONE, exc + .getException().getMessage() == null ? "an error has occurred" : exc.getException() + .getMessage(), exc.getException())); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/RestoreFileOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/RestoreFileOperation.java new file mode 100644 index 0000000..d2c20d6 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/RestoreFileOperation.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.StripingPolicy; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest; + +/** + * + * @author stender + */ +public class RestoreFileOperation extends MRCOperation { + + public RestoreFileOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // perform master redirect if necessary + if (master.getReplMasterUUID() != null && !master.getReplMasterUUID().equals(master.getConfig().getUUID())) + throw new DatabaseException(ExceptionType.REDIRECT); + + final xtreemfs_restore_fileRequest rqArgs = (xtreemfs_restore_fileRequest) rq.getRequestArgs(); + + // check password to ensure that user is authorized + if (master.getConfig().getAdminPassword().length() > 0 + && !master.getConfig().getAdminPassword().equals(rq.getDetails().password)) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "invalid password"); + + final VolumeManager vMan = master.getVolumeManager(); + + // parse volume and file ID from global file ID + GlobalFileIdResolver idRes = new GlobalFileIdResolver(rqArgs.getFileId()); + + final Path p = new Path(vMan.getStorageManager(idRes.getVolumeId()).getVolumeInfo().getName(), rqArgs + .getFilePath()); + final StorageManager sMan = vMan.getStorageManager(idRes.getVolumeId()); + + // prepare file creation in database + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + int time = (int) (TimeSync.getGlobalTime() / 1000); + long nextFileId = sMan.getNextFileId(); + + // create parent directories if necessary + FileMetadata[] path = sMan.resolvePath(p); + long parentId = 1; + for (int i = 0; i < p.getCompCount(); i++) + try { + if (path[i] != null) + parentId = path[i].getId(); + + else { + sMan.createDir(nextFileId, parentId, p.getComp(i), time, time, time, + rq.getDetails().userId, rq.getDetails().groupIds.get(0), 509, 0, update); + parentId = nextFileId; + nextFileId++; + + // set the file ID as the last one + sMan.setLastFileId(nextFileId, update); + } + } catch (DatabaseException exc) { + if (exc.getType() != ExceptionType.FILE_EXISTS) + throw exc; + } + + // create the metadata object + FileMetadata file = sMan.createFile(idRes.getLocalFileId(), parentId, rqArgs.getFileId(), time, time, + time, rq.getDetails().userId, rq.getDetails().groupIds.get(0), 511, 0, rqArgs.getFileSize(), + false, 0, 0, update); + + int size = (rqArgs.getStripeSize() < 1024 ? 1 : (rqArgs.getStripeSize() % 1024 != 0) ? rqArgs + .getStripeSize() / 1024 + 1 : rqArgs.getStripeSize() / 1024); + + // create and assign the new XLocList + StripingPolicy sp = sMan.createStripingPolicy(StripingPolicyType.STRIPING_POLICY_RAID0.name(), size, + 1); + XLoc replica = sMan.createXLoc(sp, new String[] { rqArgs.getOsdUuid() }, 0); + XLocList xLocList = sMan.createXLocList(new XLoc[] { replica }, ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE, 0); + + file.setXLocList(xLocList); + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + // set the response + rq.setResponse(emptyResponse.getDefaultInstance()); + + update.execute(); + + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/SetReadOnlyXattrOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/SetReadOnlyXattrOperation.java new file mode 100644 index 0000000..40cb101 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/SetReadOnlyXattrOperation.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse; + +public class SetReadOnlyXattrOperation extends MRCOperation { + + public SetReadOnlyXattrOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final xtreemfs_set_read_only_xattrRequest rqArgs = (xtreemfs_set_read_only_xattrRequest) rq + .getRequestArgs(); + + final FileAccessManager fam = master.getFileAccessManager(); + final VolumeManager vMan = master.getVolumeManager(); + + validateContext(rq); + + GlobalFileIdResolver gfr = new GlobalFileIdResolver(rqArgs.getFileId()); + + final String volId = gfr.getVolumeId(); + final Long localFileID = gfr.getLocalFileId(); + + StorageManager sMan = vMan.getStorageManager(volId); + + FileMetadata file = sMan.getMetadata(localFileID); + + + if (file == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + rqArgs.getFileId() + + "' does not exist"); + + if (file.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, + "replica-update policies may only be set on files"); + + // check whether privileged permissions are granted for editing Xattr + fam.checkPrivilegedPermissions(sMan, file, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + Boolean currentMode = file.isReadOnly(); + + if (currentMode == rqArgs.getValue()) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.storage, (Object) null, + "File with fileID %s has already set Xattr xtreemfs.read_only=%s", localFileID, + currentMode.toString()); + } + rq.setResponse(xtreemfs_set_read_only_xattrResponse.newBuilder().setWasSet(false).build()); + finishRequest(rq); + + } else { + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + file.setReadOnly(rqArgs.getValue()); + + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + rq.setResponse(xtreemfs_set_read_only_xattrResponse.newBuilder().setWasSet(true).build()); + update.execute(); + } + + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/SetReplicaUpdatePolicyOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/SetReplicaUpdatePolicyOperation.java new file mode 100644 index 0000000..6150cc0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/SetReplicaUpdatePolicyOperation.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.StripingPolicy; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.stages.XLocSetLock; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse; + +public class SetReplicaUpdatePolicyOperation extends MRCOperation { + + public SetReplicaUpdatePolicyOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final xtreemfs_set_replica_update_policyRequest rqArgs = (xtreemfs_set_replica_update_policyRequest) rq + .getRequestArgs(); + + final String newReplUpdatePolicy = rqArgs.getUpdatePolicy(); + + final FileAccessManager fam = master.getFileAccessManager(); + final VolumeManager vMan = master.getVolumeManager(); + + validateContext(rq); + + GlobalFileIdResolver gfr = new GlobalFileIdResolver(rqArgs.getFileId()); + + final String volId = gfr.getVolumeId(); + final Long localFileID = gfr.getLocalFileId(); + + StorageManager sMan = vMan.getStorageManager(volId); + + FileMetadata file = sMan.getMetadata(localFileID); + + if (file == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + rqArgs.getFileId() + + "' does not exist"); + + if (file.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, + "replica-update policies may only be set on files"); + + // check whether privileged permissions are granted for adding replicas + fam.checkPrivilegedPermissions(sMan, file, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // Check if a xLocSetChange is already in progress. + XLocSetLock lock = master.getXLocSetCoordinator().getXLocSetLock(file, sMan); + if (lock.isLocked()) { + throw new UserException(POSIXErrno.POSIX_ERROR_EAGAIN, "xLocSet change already in progress. Please retry."); + } + + XLocList curXLocList = file.getXLocList(); + + // if (ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY.equals(xlocs.getReplUpdatePolicy())) + // throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + // "changing replica update policies of read-only-replicated files is not allowed"); + + if (ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE.equals(newReplUpdatePolicy)) { + // if there is more than one replica, report an error + if (curXLocList.getReplicaCount() > 1) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "number of replicas has to be reduced 1 before replica update policy can be set to " + + ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE + " (current replica count = " + + curXLocList.getReplicaCount() + ")"); + } + + if (ReplicaUpdatePolicies.REPL_UPDATE_PC_WARA.equals(newReplUpdatePolicy)) { + throw new UserException( + POSIXErrno.POSIX_ERROR_EINVAL, + "Do no longer use the policy WaRa. Instead you're probably looking for the WaR1 policy (write all replicas, read from one)." + + newReplUpdatePolicy); + } + + if (!ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE.equals(newReplUpdatePolicy) + && !ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE.equals(newReplUpdatePolicy) + && !ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY.equals(newReplUpdatePolicy) + && !ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ.equals(newReplUpdatePolicy)) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid replica update policy: " + + newReplUpdatePolicy); + + // check if striping + rw replication would be set + StripingPolicy stripingPolicy = file.getXLocList().getReplica(0).getStripingPolicy(); + if (stripingPolicy.getWidth() > 1 + && (newReplUpdatePolicy.equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE) || newReplUpdatePolicy + .equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ))) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "RW-replication of striped files is not supported yet."); + } + + // Create a new XLoc. + XLoc[] xLocs = new XLoc[file.getXLocList().getReplicaCount()]; + for (int i = 0; i < file.getXLocList().getReplicaCount(); i++) { + xLocs[i] = file.getXLocList().getReplica(i); + } + XLocList newXLocList = sMan.createXLocList(xLocs, newReplUpdatePolicy, file.getXLocList().getVersion() + 1); + + // Update the X-Locations list. + file.setXLocList(newXLocList); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + // Set the response. + xtreemfs_set_replica_update_policyResponse response = xtreemfs_set_replica_update_policyResponse.newBuilder() + .setOldUpdatePolicy(curXLocList.getReplUpdatePolicy()).build(); + rq.setResponse(response); + + update.execute(); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/SetXAttrOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/SetXAttrOperation.java new file mode 100644 index 0000000..4e44411 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/SetXAttrOperation.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.XATTR_FLAGS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest; + +/** + * + * @author stender + */ +public class SetXAttrOperation extends MRCOperation { + + public SetXAttrOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final setxattrRequest rqArgs = (setxattrRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + PathResolver res = new PathResolver(sMan, p); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether file exists + res.checkIfFileDoesNotExist(); + + // retrieve and prepare the metadata to return + FileMetadata file = res.getFile(); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // if the attribute is a system attribute, set it + + final String attrKey = rqArgs.getName(); + final byte[] attrVal = rqArgs.hasValueBytesString() ? rqArgs.getValueBytesString().toByteArray() + : rqArgs.hasValue() ? rqArgs.getValue().getBytes() : null; + + // set a system attribute + if (attrKey.startsWith(StorageManager.SYS_ATTR_KEY_PREFIX)) { + + // check for the admin password to match the provided password + boolean privileged = false; + if (master.getConfig().getAdminPassword().length() > 0 + && master.getConfig().getAdminPassword().equals(rq.getDetails().password)) { + privileged = true; + } + + // whether the user has privileged permissions to set system attributes + faMan.checkPrivilegedPermissions(sMan, file, rq.getDetails().userId, + rq.getDetails().superUser || privileged, // the admin password accounts for priviledged access + rq.getDetails().groupIds); + + MRCHelper.setSysAttrValue(sMan, vMan, faMan, res.getParentDirId(), file, attrKey + .substring(StorageManager.SYS_ATTR_KEY_PREFIX.length()), new String(attrVal), update); + } + + // set a user attribute + else { + + // first, check the flags to ensure that the op can be executed + + boolean exists = sMan.getXAttr(file.getId(), rq.getDetails().userId, attrKey) != null; + if (exists && rqArgs.getFlags() == XATTR_FLAGS.XATTR_FLAGS_CREATE.getNumber()) + throw new UserException(POSIXErrno.POSIX_ERROR_EEXIST, "attribute exists already"); + if (!exists && rqArgs.getFlags() == XATTR_FLAGS.XATTR_FLAGS_REPLACE.getNumber()) + throw new UserException(POSIXErrno.POSIX_ERROR_ENODATA, "attribute does not exist"); + + sMan.setXAttr(file.getId(), rq.getDetails().userId, attrKey, attrVal.length == 0 ? null + : attrVal, update); + } + + // update POSIX timestamps + int time = (int) (TimeSync.getGlobalTime() / 1000); + MRCHelper.updateFileTimes(res.getParentDirId(), file, false, true, false, sMan, time, update); + + // set the response + rq.setResponse(emptyResponse.getDefaultInstance()); + + update.execute(); + + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/SetattrOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/SetattrOperation.java new file mode 100644 index 0000000..c27871d --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/SetattrOperation.java @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2010-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse; + +/** + * Sets attributes of a file. + * + * @author stender, bjko + */ +public class SetattrOperation extends MRCOperation { + + public SetattrOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final setattrRequest rqArgs = (setattrRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + PathResolver res = new PathResolver(sMan, p); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether file exists + res.checkIfFileDoesNotExist(); + + // retrieve and prepare the metadata to return + FileMetadata file = res.getFile(); + int time = 0; + + // determine which attributes to set + boolean setMode = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_MODE.getNumber()) == MRC.Setattrs.SETATTR_MODE + .getNumber(); + boolean setUID = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_UID.getNumber()) == MRC.Setattrs.SETATTR_UID + .getNumber(); + boolean setGID = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_GID.getNumber()) == MRC.Setattrs.SETATTR_GID + .getNumber(); + boolean setSize = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_SIZE.getNumber()) == MRC.Setattrs.SETATTR_SIZE + .getNumber(); + boolean setAtime = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_ATIME.getNumber()) == MRC.Setattrs.SETATTR_ATIME + .getNumber(); + boolean setCtime = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_CTIME.getNumber()) == MRC.Setattrs.SETATTR_CTIME + .getNumber(); + boolean setMtime = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_MTIME.getNumber()) == MRC.Setattrs.SETATTR_MTIME + .getNumber(); + boolean setAttributes = (rqArgs.getToSet() & MRC.Setattrs.SETATTR_ATTRIBUTES.getNumber()) == MRC.Setattrs.SETATTR_ATTRIBUTES + .getNumber(); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // if MODE bit is set, peform 'chmod' + if (setMode) { + + // check whether the access mode may be changed + faMan.checkPrivilegedPermissions(sMan, file, rq.getDetails().userId, rq.getDetails().superUser, + rq.getDetails().groupIds); + + // change the access mode; only bits 0-12 may be changed + faMan.setPosixAccessMode(sMan, file, res.getParentDirId(), rq.getDetails().userId, rq + .getDetails().groupIds, (file.getPerms() & 0xFFFFF000) + | (rqArgs.getStbuf().getMode() & 0xFFF), rq.getDetails().superUser, update); + + // update POSIX timestamps + if (time == 0) + time = (int) (TimeSync.getGlobalTime() / 1000); + MRCHelper.updateFileTimes(res.getParentDirId(), file, false, true, false, sMan, time, update); + } + + // if USER_ID or GROUP_ID are set, perform 'chown' + if (setUID || setGID) { + + // check whether the owner may be changed + + if (setUID) { + + // if a UID is supposed to be set, check if the operation needs + // to be restricted to root users + byte[] value = sMan.getXAttr(1, StorageManager.SYSTEM_UID, "xtreemfs." + + MRCHelper.VOL_ATTR_PREFIX + ".chown_non_root"); + + // check permission + if (value != null && new String(value).equals("true")) { + faMan.checkPrivilegedPermissions(sMan, file, rq.getDetails().userId, + rq.getDetails().superUser, rq.getDetails().groupIds); + + } else if (!rq.getDetails().superUser) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, + "changing owners is restricted to superusers"); + + } + + if (setGID) { + // if a GID is provided, restrict the op to a privileged + // user that is either root or in the group that is supposed to + // be assigned + faMan.checkPrivilegedPermissions(sMan, file, rq.getDetails().userId, + rq.getDetails().superUser, rq.getDetails().groupIds); + if (!(rq.getDetails().superUser || rq.getDetails().groupIds.contains(rqArgs.getStbuf() + .getGroupId()))) + throw new UserException( + POSIXErrno.POSIX_ERROR_EPERM, + "changing owning groups is restricted to superusers or file owners who are in the group that is supposed to be assigned"); + } + + // change owner and owning group + file.setOwnerAndGroup(setUID ? rqArgs.getStbuf().getUserId() : file.getOwnerId(), setGID ? rqArgs + .getStbuf().getGroupId() : file.getOwningGroupId()); + + // update POSIX timestamps + if (time == 0) + time = (int) (TimeSync.getGlobalTime() / 1000); + MRCHelper.updateFileTimes(res.getParentDirId(), file, false, true, false, sMan, time, update); + } + + // if SIZE bit is set, peform 'xtreemfs_updateFileSize' + if (setSize) { + + long newFileSize = rqArgs.getStbuf().getSize(); + int epochNo = rqArgs.getStbuf().getTruncateEpoch(); + + // only accept valid file size updates + if (epochNo >= file.getEpoch()) { + + boolean epochChanged = epochNo > file.getEpoch(); + + // accept any file size in a new epoch but only larger file + // sizes in + // the current epoch + if (epochChanged || newFileSize > file.getSize()) { + + long oldFileSize = file.getSize(); + if (time == 0) + time = (int) (TimeSync.getGlobalTime() / 1000); + + file.setSize(newFileSize); + file.setEpoch(epochNo); + file.setCtime(time); + file.setMtime(time); + + if (epochChanged) + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + // update the volume size + sMan.getVolumeInfo().updateVolumeSize(newFileSize - oldFileSize, update); + } + + else if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "received update for outdated file size: " + newFileSize + ", current file size=" + + file.getSize()); + } + + else { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "received file size update w/ outdated epoch: " + epochNo + ", current epoch=" + + file.getEpoch()); + } + } + + // if ATIME, CTIME or MTIME bits are set, peform 'utimens' + if (setAtime || setCtime || setMtime) { + + // check whether write permissions are granted to file + // faMan.checkPermission("w", sMan, file, res.getParentDirId(), + // rq.getDetails().userId, rq + // .getDetails().superUser, rq.getDetails().groupIds); + + if (setAtime) + file.setAtime((int) (rqArgs.getStbuf().getAtimeNs() / (long) 1e9)); + if (setCtime) + file.setCtime((int) (rqArgs.getStbuf().getCtimeNs() / (long) 1e9)); + if (setMtime) + file.setMtime((int) (rqArgs.getStbuf().getMtimeNs() / (long) 1e9)); + } + + // if ATTRIBUTES bit is set, peform 'setattr' for Win32 attributes + if (setAttributes) { + + // check whether write permissions are granted to the parent + // directory + faMan.checkPermission("w", sMan, file, res.getParentDirId(), rq.getDetails().userId, rq + .getDetails().superUser, rq.getDetails().groupIds); + + file.setW32Attrs(rqArgs.getStbuf().getAttributes()); + } + + if (setUID || setGID || setAttributes) + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + if (setAtime || setCtime || setMtime || setSize) + sMan.setMetadata(file, FileMetadata.FC_METADATA, update); + + // set the response + rq.setResponse(timestampResponse.newBuilder().setTimestampS(time).build()); + + update.execute(); + + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/ShutdownOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/ShutdownOperation.java new file mode 100644 index 0000000..c652d91 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/ShutdownOperation.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; + +import com.google.protobuf.Message; + +/** + * + * @author bjko + */ +public class ShutdownOperation extends MRCOperation { + + public ShutdownOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // check password to ensure that user is authorized + if (master.getConfig().getAdminPassword().length() > 0 + && !master.getConfig().getAdminPassword().equals(rq.getDetails().password)) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "invalid password"); + + rq.setResponse(emptyResponse.getDefaultInstance()); + finishRequest(rq); + + master.asyncShutdown(); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/StatFSOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/StatFSOperation.java new file mode 100644 index 0000000..baefa68 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/StatFSOperation.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest; + +/** + * + * @author stender + */ +public class StatFSOperation extends MRCOperation { + + public StatFSOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final statvfsRequest rqArgs = (statvfsRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final StorageManager sMan = vMan.getStorageManagerByName(rqArgs.getVolumeName()); + + StatVFS volumeInfo = getVolumeInfo(master, sMan); + // long knownEtag = rqArgs.getKnownEtag(); + + // StatVFSSet set = new StatVFSSet(); + // if (knownEtag != volumeInfo.getEtag()) + // set.add(volumeInfo); + + // set the response + rq.setResponse(volumeInfo); + finishRequest(rq); + + } + + protected static StatVFS getVolumeInfo(MRCRequestDispatcher master, StorageManager sMan) + throws DatabaseException { + + final VolumeInfo volume = sMan.getVolumeInfo(); + final FileMetadata volumeRoot = sMan.getMetadata(1); + + int blockSize = sMan.getDefaultStripingPolicy(1).getStripeSize() * 1024; + + long availSpace = master.getOSDStatusManager().getUsableSpace(volume.getId()); + long freeSpace = master.getOSDStatusManager().getFreeSpace(volume.getId()); + long totalSpace = master.getOSDStatusManager().getTotalSpace(volume.getId()); + long quota = sMan.getVolumeQuota(); + + // Use minimum of free space relative to the quota and free space on OSDs as free/available space. + if (quota != 0) { + long quotaFreeSpace = quota - sMan.getVolumeInfo().getVolumeSize(); + quotaFreeSpace = quotaFreeSpace < 0 ? 0 : quotaFreeSpace; + freeSpace = freeSpace < quotaFreeSpace ? freeSpace : quotaFreeSpace; + availSpace = availSpace < quotaFreeSpace ? availSpace : quotaFreeSpace; + } + + long bavail = availSpace / blockSize; + long bfree = freeSpace / blockSize; + long blocks = totalSpace / blockSize; + String volumeId = volume.getId(); + AccessControlPolicyType acPolId = AccessControlPolicyType.valueOf(volume.getAcPolicyId()); + StripingPolicy.Builder defaultStripingPolicy = Converter.stripingPolicyToStripingPolicy(sMan + .getDefaultStripingPolicy(1)); + String volumeName = volume.getName(); + String owningGroupId = volumeRoot.getOwningGroupId(); + String ownerId = volumeRoot.getOwnerId(); + int perms = volumeRoot.getPerms(); + + long newEtag = blockSize + bavail + blocks; + + return StatVFS.newBuilder().setBsize(blockSize).setBfree(bfree).setBavail(bavail).setBlocks(blocks).setFsid(volumeId) + .setNamemax(1024).setOwnerUserId(ownerId).setOwnerGroupId(owningGroupId).setName(volumeName) + .setEtag(newEtag).setMode(perms).setAccessControlPolicy(acPolId).setDefaultStripingPolicy( + defaultStripingPolicy).build(); + + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/StatOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/StatOperation.java new file mode 100644 index 0000000..0cff9a3 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/StatOperation.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.mrc.utils.PathResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse; + +/** + * + * @author stender + */ +public class StatOperation extends MRCOperation { + + public StatOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + final getattrRequest rqArgs = (getattrRequest) rq.getRequestArgs(); + + final VolumeManager vMan = master.getVolumeManager(); + final FileAccessManager faMan = master.getFileAccessManager(); + + validateContext(rq); + + Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); + + // if(p.getLastComp(0).startsWith(".fuse_hidden")) + // p = MRCHelper.getFuseHiddenPath(p); + + final StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); + final PathResolver res = new PathResolver(sMan, p); + final VolumeInfo volume = sMan.getVolumeInfo(); + + // check whether the path prefix is searchable + faMan.checkSearchPermission(sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq + .getDetails().groupIds); + + // check whether file exists + res.checkIfFileDoesNotExist(); + + FileMetadata file = res.getFile(); + + final long knownEtag = rqArgs.getKnownEtag(); + final long newEtag = file.getCtime() + file.getMtime(); + + getattrResponse.Builder stat = getattrResponse.newBuilder(); + + // retrieve and prepare the metadata to return + if (knownEtag != newEtag) { + + String linkTarget = sMan.getSoftlinkTarget(file.getId()); + int mode = faMan.getPosixAccessMode(sMan, file, rq.getDetails().userId, rq.getDetails().groupIds); + mode |= linkTarget != null ? GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFLNK.getNumber() + : file.isDirectory() ? GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFDIR.getNumber() + : ((file.getPerms() & GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFIFO.getNumber()) != 0) ? GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFIFO + .getNumber() + : GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFREG.getNumber(); + + long size = linkTarget != null ? linkTarget.length() : file.isDirectory() ? 0 : file.getSize(); + int blkSize = 0; + if ((linkTarget == null) && (!file.isDirectory())) { + XLocList xlocList = file.getXLocList(); + if ((xlocList != null) && (xlocList.getReplicaCount() > 0)) + blkSize = xlocList.getReplica(0).getStripingPolicy().getStripeSize() * 1024; + } + + stat.setStbuf(Stat.newBuilder().setDev(volume.getId().hashCode()).setIno(file.getId()).setMode( + mode).setNlink(file.getLinkCount()).setUserId(file.getOwnerId()).setGroupId( + file.getOwningGroupId()).setSize(size).setAtimeNs((long) file.getAtime() * (long) 1e9) + .setCtimeNs((long) file.getCtime() * (long) 1e9).setMtimeNs( + (long) file.getMtime() * (long) 1e9).setBlksize(blkSize).setTruncateEpoch( + file.isDirectory() ? 0 : file.getEpoch()).setAttributes((int) file.getW32Attrs()) + .setEtag(newEtag)); + + } + + // set the response + rq.setResponse(stat.build()); + + finishRequest(rq); + + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/TruncateOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/TruncateOperation.java new file mode 100644 index 0000000..29857db --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/TruncateOperation.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + + +package org.xtreemfs.mrc.operations; + +import java.net.InetSocketAddress; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; + +/** + * + * @author stender + */ +public class TruncateOperation extends MRCOperation { + + public TruncateOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // perform master redirect if necessary + if (master.getReplMasterUUID() != null && !master.getReplMasterUUID().equals(master.getConfig().getUUID().toString())) + throw new DatabaseException(ExceptionType.REDIRECT); + + final XCap xcap = (XCap) rq.getRequestArgs(); + + Capability writeCap = new Capability(xcap, master.getConfig().getCapabilitySecret()); + + // check whether the capability has a valid signature + if (!writeCap.hasValidSignature()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, writeCap + + " does not have a valid signature"); + + // check whether the capability has expired + if (writeCap.hasExpired()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, writeCap + " has expired"); + + // check whether the capability grants write permissions + if ((writeCap.getAccessMode() & (FileAccessManager.O_WRONLY | FileAccessManager.O_RDWR | FileAccessManager.O_TRUNC)) == 0) + throw new UserException(POSIXErrno.POSIX_ERROR_EACCES, writeCap + " is not a write capability"); + + // parse volume and file ID from global file ID + GlobalFileIdResolver idRes = new GlobalFileIdResolver(writeCap.getFileId()); + + StorageManager sMan = master.getVolumeManager().getStorageManager(idRes.getVolumeId()); + + FileMetadata file = sMan.getMetadata(idRes.getLocalFileId()); + if (file == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + writeCap.getFileId() + + "' does not exist"); + + // get the current epoch, use (and increase) the truncate number if + // the open mode is truncate + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + int newEpoch = file.getIssuedEpoch() + 1; + file.setIssuedEpoch(newEpoch); + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + // create a truncate capability from the previous write capability + Capability truncCap = new Capability(writeCap.getFileId(), + writeCap.getAccessMode() | FileAccessManager.O_TRUNC, master.getConfig().getCapabilityTimeout(), + TimeSync.getGlobalTime() / 1000 + master.getConfig().getCapabilityTimeout(), ((InetSocketAddress) rq + .getRPCRequest().getSenderAddress()).getAddress().getHostAddress(), newEpoch, + writeCap.isReplicateOnClose(), + !sMan.getVolumeInfo().isSnapshotsEnabled() ? SnapConfig.SNAP_CONFIG_SNAPS_DISABLED : sMan + .getVolumeInfo().isSnapVolume() ? SnapConfig.SNAP_CONFIG_ACCESS_SNAP + : SnapConfig.SNAP_CONFIG_ACCESS_CURRENT, sMan.getVolumeInfo().getCreationTime(), master + .getConfig().getCapabilitySecret()); + + // set the response + rq.setResponse(truncCap.getXCap()); + update.execute(); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/operations/UpdateFileSizeOperation.java b/java/servers/src/org/xtreemfs/mrc/operations/UpdateFileSizeOperation.java new file mode 100644 index 0000000..c363d99 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/operations/UpdateFileSizeOperation.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2010-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.operations; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.ReplicationPolicy; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.mrc.utils.MRCHelper.GlobalFileIdResolver; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest; + +/** + * Sets attributes of a file. + * + * @author stender + */ +public class UpdateFileSizeOperation extends MRCOperation { + + public UpdateFileSizeOperation(MRCRequestDispatcher master) { + super(master); + } + + @Override + public void startRequest(MRCRequest rq) throws Throwable { + + // perform master redirect if necessary + if (master.getReplMasterUUID() != null && !master.getReplMasterUUID().equals(master.getConfig().getUUID().toString())) + throw new DatabaseException(ExceptionType.REDIRECT); + + final xtreemfs_update_file_sizeRequest rqArgs = (xtreemfs_update_file_sizeRequest) rq + .getRequestArgs(); + + Capability cap = new Capability(rqArgs.getXcap(), master.getConfig().getCapabilitySecret()); + + // check whether the capability has a valid signature + if (!cap.hasValidSignature()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, cap + " does not have a valid signature"); + + // check whether the capability has expired + if (cap.hasExpired()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, cap + " has expired"); + + // parse volume and file ID from global file ID + GlobalFileIdResolver idRes = new GlobalFileIdResolver(cap.getFileId()); + + StorageManager sMan = master.getVolumeManager().getStorageManager(idRes.getVolumeId()); + + FileMetadata file = sMan.getMetadata(idRes.getLocalFileId()); + if (file == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file '" + cap.getFileId() + + "' does not exist"); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); + + // update the file size if necessary + if (rqArgs.getOsdWriteResponse().hasSizeInBytes()) { + + if (file.isReadOnly()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "file '" + cap.getFileId() + + "' is read-only"); + + if (!rqArgs.getOsdWriteResponse().hasTruncateEpoch()) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "missing truncate epoch in OSDWriteResponse"); + + long newFileSize = rqArgs.getOsdWriteResponse().getSizeInBytes(); + int epochNo = rqArgs.getOsdWriteResponse().getTruncateEpoch(); + + // only accept valid file size updates + if (epochNo >= file.getEpoch()) { + + boolean epochChanged = epochNo > file.getEpoch(); + + // accept any file size in a new epoch but only larger file + // sizes in the current epoch + if (epochChanged || newFileSize > file.getSize()) { + + long oldFileSize = file.getSize(); + int time = (int) (TimeSync.getGlobalTime() / 1000); + + file.setSize(newFileSize); + file.setEpoch(epochNo); + file.setCtime(time); + file.setMtime(time); + + sMan.setMetadata(file, FileMetadata.FC_METADATA, update); + + if (epochChanged) + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + // update the volume size + sMan.getVolumeInfo().updateVolumeSize(newFileSize - oldFileSize, update); + } + + else if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "received update for outdated file size: " + newFileSize + ", current file size=" + + file.getSize()); + } + + else { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "received file size update w/ outdated epoch: " + epochNo + ", current epoch=" + + file.getEpoch()); + } + } + + // check if file is closed and on-close replication is required + if (rqArgs.getCloseFile() && cap.getXCap().getReplicateOnClose()) { + + VolumeInfo vol = sMan.getVolumeInfo(); + + file.setReadOnly(true); + + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "file closed and set to readOnly"); + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "replicating file"); + + XLocList xLocList = file.getXLocList(); + + // retrieve the default replication policy + // FIXME: use the parent directory's default replication policy + ReplicationPolicy defaultReplPolicy = sMan.getDefaultReplicationPolicy(file.getId()); + if (defaultReplPolicy == null) + defaultReplPolicy = sMan.getDefaultReplicationPolicy(1); + + // determine the number of replicas to create + int requiredReplicaCount; + if (defaultReplPolicy == null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.replication, + "replicate on close enabled w/o default replication policy"); + requiredReplicaCount = 1; + + } else + requiredReplicaCount = defaultReplPolicy.getFactor(); + + // if replicas need to be created on close ... + if (requiredReplicaCount > xLocList.getReplicaCount()) { + + assert (defaultReplPolicy != null); + + List repls = new ArrayList(); + for (int i = 0; i < xLocList.getReplicaCount(); i++) + repls.add(xLocList.getReplica(i)); + + int newVer = xLocList.getVersion() + 1; + int initialReplCount = xLocList.getReplicaCount(); + + // mark the first replica as complete + XLoc firstRepl = repls.get(0); + firstRepl.setReplicationFlags(ReplicationFlags.setFullReplica(ReplicationFlags + .setReplicaIsComplete(firstRepl.getReplicationFlags()))); + + // determine the replication flags for the new replicas: + // full + 'rarest first' strategy for full replicas, + // 'sequential prefetching' strategy for partial replicas + // + // final int replFlags = vol.getAutoReplFull() ? + // ReplicationFlags + // .setFullReplica(ReplicationFlags.setRarestFirstStrategy(0)) : + // ReplicationFlags + // .setSequentialPrefetchingStrategy(0); + + // try to replicate the file + try { + + for (int i = 0; i < requiredReplicaCount - initialReplCount; i++) { + + // create the new replica + XLoc newRepl = MRCHelper.createReplica(firstRepl.getStripingPolicy(), sMan, master + .getOSDStatusManager(), vol, -1, cap.getFileId(), ((InetSocketAddress) rq + .getRPCRequest().getSenderAddress()).getAddress(), rqArgs.getCoordinates(), + xLocList, defaultReplPolicy.getFlags()); + + String[] osds = new String[newRepl.getOSDCount()]; + for (int j = 0; j < osds.length; j++) + osds[j] = newRepl.getOSD(j); + + repls.add(sMan.createXLoc(firstRepl.getStripingPolicy(), osds, newRepl + .getReplicationFlags())); + + xLocList = sMan.createXLocList(repls.toArray(new XLoc[repls.size()]), + ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY, newVer); + + } + + } catch (Exception exc) { + + // if the attempt to replicate the file fails for whatever + // reason, print a warning message and continue + + Logging.logMessage(Logging.LEVEL_WARN, Category.replication, this, + "could not replicate file '%d' on close", file.getId()); + Logging.logMessage(Logging.LEVEL_WARN, Category.replication, this, OutputUtils + .stackTraceToString(exc)); + } + + file.setXLocList(xLocList); + } + + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "added %d replicas", + requiredReplicaCount - xLocList.getReplicaCount()); + + // if the file has data and 'full' replicas are enabled, trigger the replication + if (file.getSize() > 0 && ReplicationFlags.isFullReplica(defaultReplPolicy.getFlags())) { + + XLocSet.Builder xLocSet = Converter.xLocListToXLocSet(xLocList); + xLocSet.setReadOnlyFileSize(file.getSize()); + + rq.getDetails().context = new HashMap(); + rq.getDetails().context.put("xLocList", xLocSet.build()); + master.getOnCloseReplicationThread().enqueueRequest(rq); + } + } + + // set the response + rq.setResponse(emptyResponse.getDefaultInstance()); + + update.execute(); + + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/DCMapPolicyBase.java b/java/servers/src/org/xtreemfs/mrc/osdselection/DCMapPolicyBase.java new file mode 100644 index 0000000..8284a43 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/DCMapPolicyBase.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.Inet4Address; +import java.net.InetAddress; +import java.util.Properties; + +import org.xtreemfs.foundation.LRUCache; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +/** + * Base class for policies that use datacenter maps. + * + * @author bjko, stender + */ +public abstract class DCMapPolicyBase implements OSDSelectionPolicy { + + public static final String CONFIG_FILE_PATH = "/etc/xos/xtreemfs/datacentermap"; + + protected int[][] distMap; + + protected Inet4AddressMatcher[][] matchers; + + protected LRUCache matchingDCcache; + + private boolean initialized; + + public DCMapPolicyBase() { + try { + File f = new File(CONFIG_FILE_PATH); + Properties p = new Properties(); + p.load(new FileInputStream(f)); + readConfig(p); + int maxCacheSize = Integer.valueOf(p.getProperty("max_cache_size", "1000").trim()); + matchingDCcache = new LRUCache(maxCacheSize); + initialized = true; + + } catch (IOException ex) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "cannot load %s, DCMap replica selection policy will not work", CONFIG_FILE_PATH); + Logging.logError(Logging.LEVEL_WARN, this, ex); + initialized = false; + } + + } + + public DCMapPolicyBase(Properties p) { + readConfig(p); + int maxCacheSize = Integer.valueOf(p.getProperty("max_cache_size", "1000")); + matchingDCcache = new LRUCache(maxCacheSize); + initialized = true; + } + + private void readConfig(Properties p) { + + String tmp = p.getProperty("datacenters"); + if (tmp == null) { + throw new IllegalArgumentException("Cannot initialize " + this.getClass().getSimpleName() + + ": a list of datacenters must be specified in the configuration"); + } + + final String[] dcs = tmp.split(","); + if (dcs.length == 0) { + Logging.logMessage(Logging.LEVEL_WARN, this, "no datacenters specified"); + return; + } + + for (int i = 0; i < dcs.length; i++) { + if (!dcs[i].matches("[a-zA-Z0-9_]+")) { + throw new IllegalArgumentException("Cannot initialize " + this.getClass().getSimpleName() + + ": datacenter name '" + dcs[i] + "' is invalid"); + } + } + + distMap = new int[dcs.length][dcs.length]; + matchers = new Inet4AddressMatcher[dcs.length][]; + for (int i = 0; i < dcs.length; i++) { + for (int j = i + 1; j < dcs.length; j++) { + String distStr = p.getProperty("distance." + dcs[i] + "-" + dcs[j]); + if (distStr == null) { + distStr = p.getProperty("distance." + dcs[j] + "-" + dcs[i]); + } + if (distStr == null) { + throw new IllegalArgumentException("Cannot initialize " + this.getClass().getSimpleName() + + ": distance between datacenter '" + dcs[i] + "' and '" + dcs[j] + + "' is not specified"); + } + try { + distMap[i][j] = distMap[j][i] = Integer.valueOf(distStr); + } catch (NumberFormatException ex) { + throw new IllegalArgumentException("Cannot initialize " + this.getClass().getSimpleName() + + ": distance '" + distStr + "' between datacenter '" + dcs[i] + "' and '" + dcs[j] + + "' is not a valid integer"); + } + } + + // evaluate the address ranges for the data centers + String dcMatch = p.getProperty("addresses." + dcs[i]); + if (dcMatch == null) + dcMatch = p.getProperty(dcs[i] + ".addresses"); + if (dcMatch == null) { + matchers[i] = new Inet4AddressMatcher[0]; + // allow empty datacenters + Logging.logMessage(Logging.LEVEL_WARN, this, "datacenter '" + dcs[i] + "' has no entries!"); + } + + else { + String entries[] = dcMatch.split(","); + matchers[i] = new Inet4AddressMatcher[entries.length]; + for (int e = 0; e < entries.length; e++) { + final String entry = entries[e]; + if (entry.contains("/")) { + // network match + try { + String ipAddr = entry.substring(0, entry.indexOf("/")); + String prefix = entry.substring(entry.indexOf("/") + 1); + Inet4Address ia = (Inet4Address) InetAddress.getByName(ipAddr); + matchers[i][e] = new Inet4AddressMatcher(ia, Integer.valueOf(prefix)); + } catch (NumberFormatException ex) { + throw new IllegalArgumentException("Cannot initialize " + + this.getClass().getSimpleName() + ": netmask in '" + entry + + "' for datacenter '" + dcs[i] + "' is not a valid integer"); + } catch (Exception ex) { + throw new IllegalArgumentException("Cannot initialize " + + this.getClass().getSimpleName() + ": address '" + entry + + "' for datacenter '" + dcs[i] + "' is not a valid IPv4 address"); + } + } else { + // IP match + try { + Inet4Address ia = (Inet4Address) InetAddress.getByName(entry); + matchers[i][e] = new Inet4AddressMatcher(ia); + } catch (Exception ex) { + throw new IllegalArgumentException("Cannot initialize " + + this.getClass().getSimpleName() + ": address '" + entry + + "' for datacenter '" + dcs[i] + "' is not a valid IPv4 address"); + } + } + } + + } + } + + } + + protected int getDistance(Inet4Address addr1, Inet4Address addr2) { + + if(!initialized) + return 0; + + final int dc1 = getMatchingDC(addr1); + final int dc2 = getMatchingDC(addr2); + + if ((dc1 != -1) && (dc2 != -1)) { + return distMap[dc1][dc2]; + } else { + return Integer.MAX_VALUE; + } + } + + protected int getMatchingDC(Inet4Address addr) { + + if(!initialized) + return -1; + + Integer cached = matchingDCcache.get(addr); + if (cached == null) { + for (int i = 0; i < matchers.length; i++) { + for (int j = 0; j < matchers[i].length; j++) { + if (matchers[i][j].matches(addr)) { + matchingDCcache.put(addr, i); + return i; + } + } + } + matchingDCcache.put(addr, -1); + return -1; + } else { + return cached; + } + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/FQDNPolicyBase.java b/java/servers/src/org/xtreemfs/mrc/osdselection/FQDNPolicyBase.java new file mode 100644 index 0000000..6ad0e56 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/FQDNPolicyBase.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.util.ArrayList; +import java.util.List; + +/** + * Base class for policies that use datacenter maps. + * + * @author bjko, stender + */ +public abstract class FQDNPolicyBase implements OSDSelectionPolicy { + + /** + * Counts the number of consecutive matching components in the given domain + * names, starting at the last component. + * + * @param dn1 + * the first domain name + * @param dn2 + * the second domain name + * @return the number of consecutive matching components, starting at the + * last component + */ + protected int getMatch(String dn1, String dn2) { + + String[] array1 = tokenizeAndReverseDN(dn1); + String[] array2 = tokenizeAndReverseDN(dn2); + + int len = Math.min(array1.length, array2.length); + + int match = 0; + for (int i = 0; i < len; i++) { + if (array1[i].equals(array2[i])) + match++; + else + break; + } + + return match; + } + + private static String[] tokenizeAndReverseDN(String dn) { + + List dots = new ArrayList(); + + // determine the positions of all dots + for (int i = 0; i < dn.length(); i++) { + if (dn.charAt(i) == '.') + dots.add(i); + } + + String[] array = new String[dots.size() + 1]; + for (int i = 0; i < array.length; i++) { + int currDot = i >= dots.size() ? dn.length() : dots.get(i); + int prevDot = i == 0 ? -1 : dots.get(i - 1); + array[array.length - i - 1] = dn.substring(prevDot + 1, currDot); + } + + return array; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/FilterDefaultPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/FilterDefaultPolicy.java new file mode 100644 index 0000000..f749d3b --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/FilterDefaultPolicy.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.StringTokenizer; + +import org.xtreemfs.common.HeartbeatThread; +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.common.config.ServiceConfig; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.OSDHealthResult; + +/** + * Filters all those OSDs that haven't been assigned to the current XLoc list + * yet, have recently sent a heartbeat signal and have sufficient space. + * + * @author stender + */ +public class FilterDefaultPolicy implements OSDSelectionPolicy { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_FILTER_DEFAULT + .getNumber(); + + private static final String OFFLINE_TIME_SECS = "offline_time_secs"; + + private static final String FREE_CAPACITY_BYTES = "free_capacity_bytes"; + + private static final String OSD_HEALTH_CHECK = "osd_health_check"; + + private static final String NOT_IN = "not."; + // default: 2GB + private long minFreeCapacity = 2 * 1024 * 1024 * 1024; + + // default: 5 min + private long maxOfflineTime = 300; + + // default: WARNING + private OSDHealthResult osdHealthCheck = OSDHealthResult.OSD_HEALTH_RESULT_WARNING; + + private HashMap customFilter = new HashMap(); + private HashMap customNotFilter = new HashMap(); + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + + if (allOSDs == null) + return null; + + // first, remove all OSDs from the set that have already been assigned + // to the current XLoc list + ServiceSet.Builder osds = PolicyHelper.removeUsedOSDs(allOSDs, currentXLoc); + + return getOSDs(osds); + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs) { + + if (allOSDs == null) + return null; + + ServiceSet.Builder filteredOSDs = ServiceSet.newBuilder(); + for (Service osd : allOSDs.getServicesList()) { + + if (!hasTimedOut(osd) && hasFreeCapacity(osd) && isAvailable(osd) && isHealthy(osd)) { + + // if no custom filters have been assigned, add the OSD to the + // list + if (customFilter.isEmpty()) { + if (customNotFilter.isEmpty() || + !checkMatch(customNotFilter, filteredOSDs, osd)) { + filteredOSDs.addServices(osd); + } + } + + // otherwise, check if the filters allow the OSD to be added to + // the list + else { + // ckeck if a policy prohibits this OSD from being added to the list. + if (checkMatch(customNotFilter, filteredOSDs, osd)) { + continue; + } + else if (checkMatch(customFilter, filteredOSDs, osd)) { + filteredOSDs.addServices(osd); + } + } + } + } + + return filteredOSDs; + } + + private static boolean checkMatch( + Map customFilter, + ServiceSet.Builder filteredOSDs, + Service osd) { + for (Entry entry : customFilter.entrySet()) { + String osdParameterValue + = KeyValuePairs.getValue(osd.getData().getDataList(), + ServiceConfig.OSD_CUSTOM_PROPERTY_PREFIX + entry.getKey()); + + if (matches(entry.getValue(), osdParameterValue)) { + return true; + } + } + return false; + } + + @Override + public void setAttribute(String key, String value) { + if (OFFLINE_TIME_SECS.equals(key)) { + maxOfflineTime = Long.parseLong(value); + } + else if (FREE_CAPACITY_BYTES.equals(key)) { + minFreeCapacity = Long.parseLong(value); + } + else if (OSD_HEALTH_CHECK.equals(key)){ + if (value.toUpperCase().equals("WARNING")) { + osdHealthCheck = OSDHealthResult.OSD_HEALTH_RESULT_WARNING; + } else if (value.toUpperCase().equals("FAILED")) { + osdHealthCheck = OSDHealthResult.OSD_HEALTH_RESULT_FAILED; + } + } + else { + if (value == null) { + if (key.toLowerCase().startsWith(NOT_IN)) { + key = key.substring(NOT_IN.length(), key.length()); + customNotFilter.remove(key); + } + else { + customFilter.remove(key); + } + } + else { + if (key.toLowerCase().startsWith(NOT_IN)) { + key = key.substring(NOT_IN.length(), key.length()); + customNotFilter.put(key,value); + } + else { + customFilter.put(key, value); + } + } + } + } + + private boolean hasTimedOut(Service osd) { + long lastUpdate = Long.parseLong(KeyValuePairs.getValue(osd.getData().getDataList(), + "seconds_since_last_update")); + return lastUpdate > maxOfflineTime; + } + + private boolean hasFreeCapacity(Service osd) { + String freeStr = KeyValuePairs.getValue(osd.getData().getDataList(), "free"); + if (freeStr == null) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "invalid OSD registry (free is null!): %s", + osd.toString()); + } + return false; + } + long free = Long.parseLong(freeStr); + return free > minFreeCapacity; + } + + private boolean isAvailable(Service osd) { + String osdStatus = KeyValuePairs.getValue(osd.getData().getDataList(), HeartbeatThread.STATUS_ATTR); + if (osdStatus == null) + return true; + if (Integer.valueOf(osdStatus) == ServiceStatus.SERVICE_STATUS_AVAIL.getNumber()) { + return true; + } else { + return false; + } + } + + private boolean isHealthy(Service osd) { + String smartTestResult = KeyValuePairs.getValue(osd.getData().getDataList(), OSD_HEALTH_CHECK); + if (smartTestResult == null) { + return true; + } + + if (osdHealthCheck == OSDHealthResult.OSD_HEALTH_RESULT_WARNING) { + return Integer.valueOf(smartTestResult) != OSDHealthResult.OSD_HEALTH_RESULT_FAILED_VALUE + && Integer.valueOf(smartTestResult) != OSDHealthResult.OSD_HEALTH_RESULT_WARNING_VALUE; + } else { + return Integer.valueOf(smartTestResult) != OSDHealthResult.OSD_HEALTH_RESULT_FAILED_VALUE; + } + } + + private static boolean matches(String filterString, String customProperty) { + + StringTokenizer st = new StringTokenizer(filterString); + while (st.hasMoreTokens()) { + if (st.nextToken().equals(customProperty)) + return true; + } + + return false; + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/FilterFQDNPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/FilterFQDNPolicy.java new file mode 100644 index 0000000..6ccc3bc --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/FilterFQDNPolicy.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; +import java.util.LinkedList; +import java.util.List; +import java.util.StringTokenizer; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Filters all OSDs that have a matching domain. Domains are specified via an + * extended attribute value, as defined in DOMAINS. Attribute values may contain + * '*'s to indicate that subdomains also match. By default, the list of domains + * contains '*' to indicate that any domain matches. + * + * @author stender + */ +public class FilterFQDNPolicy implements OSDSelectionPolicy { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_FILTER_FQDN + .getNumber(); + + private static final String DOMAINS = "domains"; + + private final List domains = new LinkedList(); + + { + // default: all domains match + domains.add("*"); + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, InetAddress clientIP, VivaldiCoordinates clientCoords, + XLocList currentXLoc, int numOSDs) { + return getOSDs(allOSDs); + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs) { + + if (allOSDs == null) + return null; + + ServiceSet.Builder filteredOSDs = ServiceSet.newBuilder(); + for (Service osd : allOSDs.getServicesList()) + if (isInDomains(osd)) + filteredOSDs.addServices(osd); + + return filteredOSDs; + } + + @Override + public void setAttribute(String key, String value) { + if (key.equals(DOMAINS)) { + domains.clear(); + if (value == null) { + value = ""; + } + StringTokenizer st = new StringTokenizer(value, " ,;\t\n"); + if (st != null) { + while (st.hasMoreTokens()) { + domains.add(st.nextToken()); + } + } + } + } + + private boolean isInDomains(Service osd) { + + try { + + final ServiceUUID uuid = new ServiceUUID(osd.getUuid()); + final String osdHostName = uuid.getAddress().getHostName(); + + for (String domain : domains) { + + if (domain.endsWith("*") && osdHostName.startsWith(domain.substring(0, domain.length() - 1))) + return true; + + if (domain.startsWith("*") && osdHostName.endsWith(domain.substring(1, domain.length()))) + return true; + + if (domain.equals(osdHostName)) + return true; + } + + return false; + + } catch (UnknownUUIDException exc) { + + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, "invalid OSD UUID"); + Logging.logError(Logging.LEVEL_ERROR, this, exc); + + return false; + } + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/FilterUUIDPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/FilterUUIDPolicy.java new file mode 100644 index 0000000..d2c8b99 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/FilterUUIDPolicy.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; +import java.util.LinkedList; +import java.util.List; +import java.util.StringTokenizer; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Filters all OSDs that have a matching UUID. UUIDs are specified via an + * extended attribute value, as defined in UUIDs. Attribute values may contain + * '*'s to indicate that parts of the UUID also match. By default, the list of + * UUIDs contains '*' to indicate that any UUID matches. + * + * @author stender + */ +public class FilterUUIDPolicy implements OSDSelectionPolicy { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_FILTER_UUID + .getNumber(); + + private static final String UUIDS = "uuids"; + + private List uuids = new LinkedList(); + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + return getOSDs(allOSDs); + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs) { + + if (allOSDs == null) + return null; + + ServiceSet.Builder filteredOSDs = ServiceSet.newBuilder(); + for (Service osd : allOSDs.getServicesList()) + if (isInUUIDs(osd)) + filteredOSDs.addServices(osd); + + return filteredOSDs; + } + + @Override + public void setAttribute(String key, String value) { + + if (key.equals(UUIDS)) { + + uuids.clear(); + + if (value != null) { + StringTokenizer st = new StringTokenizer(value, " ,;\t\n"); + while (st.hasMoreTokens()) + uuids.add(st.nextToken()); + } + } + } + + private boolean isInUUIDs(Service osd) { + + final String osdUUID = new ServiceUUID(osd.getUuid()).toString(); + + if (uuids.size() == 0) + return true; + + for (String uuid : uuids) { + + if (uuid.endsWith("*") && osdUUID.startsWith(uuid.substring(0, uuid.length() - 1))) + return true; + + if (uuid.startsWith("*") && osdUUID.endsWith(uuid.substring(1, uuid.length()))) + return true; + + if (uuid.equals(osdUUID)) + return true; + } + + return false; + + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/GroupDCMapPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/GroupDCMapPolicy.java new file mode 100644 index 0000000..e38e721 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/GroupDCMapPolicy.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.util.Comparator; +import java.util.Properties; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Determines a subgroup of OSDs that can be assigned to new replica, by means + * of the datacenter map. The selection will be restricted to OSDs that are + * located in the same datacenter. If multiple such possible subgroups exist, + * the one closest to the client will be returned. + * + * @author bjko, stender + */ +public class GroupDCMapPolicy extends DCMapPolicyBase { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_GROUP_DCMAP + .getNumber(); + + public GroupDCMapPolicy() { + } + + public GroupDCMapPolicy(Properties p) { + super(p); + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + + allOSDs = getOSDs(allOSDs); + + // find the closest group to the client that is large enough + int currentDC = 0; + int currentDCSize = 0; + int currentIndex = 0; + + int bestClientDist = Integer.MAX_VALUE; + int bestIndex = -1; + + for (int i = 0; i < allOSDs.getServicesCount(); i++) { + + try { + Service s = allOSDs.getServices(i); + Inet4Address addr = (Inet4Address) new ServiceUUID(s.getUuid()).getAddress().getAddress(); + final int dc = getMatchingDC(addr); + + if (dc == currentDC) { + + currentDCSize++; + if (currentDCSize == numOSDs) { + int cd = getDistance(addr, (Inet4Address) clientIP); + if (cd < bestClientDist) { + bestClientDist = cd; + bestIndex = currentIndex; + } + } + } + + else { + currentDCSize = 1; + currentDC = dc; + currentIndex = i; + + if (currentDCSize == numOSDs) { + int cd = getDistance(addr, (Inet4Address) clientIP); + if (cd < bestClientDist) { + bestClientDist = cd; + bestIndex = currentIndex; + } + } + } + + } catch (UnknownUUIDException exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + break; + } + + } + + ServiceSet.Builder result = ServiceSet.newBuilder(); + + if (bestIndex != -1) + for (int i = 0; i < numOSDs; i++) + result.addServices(allOSDs.getServices(bestIndex + i)); + + return result; + + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs) { + + // sort the list by their data centers + if (allOSDs != null) { + allOSDs = PolicyHelper.sortServiceSet(allOSDs, new Comparator() { + public int compare(Service o1, Service o2) { + + try { + Inet4Address addr1 = (Inet4Address) new ServiceUUID(o1.getUuid()).getAddress() + .getAddress(); + Inet4Address addr2 = (Inet4Address) new ServiceUUID(o2.getUuid()).getAddress() + .getAddress(); + + return getMatchingDC(addr1) - getMatchingDC(addr2); + + } catch (UnknownUUIDException exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + return 0; + } + } + }); + } + + return allOSDs; + } + + @Override + public void setAttribute(String key, String value) { + // don't accept any attributes + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/GroupFQDNPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/GroupFQDNPolicy.java new file mode 100644 index 0000000..1bbd3f8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/GroupFQDNPolicy.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; +import java.util.Comparator; + +import org.xtreemfs.common.util.NetUtils; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Determines a subgroup of OSDs that can be assigned to a new replica, by means + * of the fully qualified distinguished server names. The selection will be + * restricted to OSDs that are located in the same domain. If multiple such + * possible subgroups exist, the one closest to the client will be returned. + * + * @author bjko, stender + */ +public class GroupFQDNPolicy extends FQDNPolicyBase { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_GROUP_FQDN + .getNumber(); + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, final InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + + if (allOSDs == null) + return null; + + // sort the list by their FQDN distance to the client + allOSDs = PolicyHelper.sortServiceSet(allOSDs, new Comparator() { + public int compare(Service o1, Service o2) { + + try { + final String host1 = new ServiceUUID(o1.getUuid()).getAddress().getHostName(); + final String host2 = new ServiceUUID(o2.getUuid()).getAddress().getHostName(); + + return getMatch(host2, clientIP.getHostName()) - getMatch(host1, clientIP.getHostName()); + + } catch (UnknownUUIDException exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + return 0; + } + } + }); + + // find the closest group to the client that is large enough + String currentDomain = ""; + int currentDomainSize = 0; + int currentIndex = 0; + + int bestClientMatch = 0; + int bestIndex = -1; + + for (int i = 0; i < allOSDs.getServicesCount(); i++) { + + try { + Service s = allOSDs.getServices(i); + String hostName = new ServiceUUID(s.getUuid()).getAddress().getHostName(); + String domain = NetUtils.getDomain(hostName); + + if (domain.equals(currentDomain)) { + + currentDomainSize++; + if (currentDomainSize == numOSDs) { + int cd = getMatch(hostName, clientIP.getCanonicalHostName()); + if (cd > bestClientMatch) { + bestClientMatch = cd; + bestIndex = currentIndex; + } + } + } + + else { + currentDomainSize = 1; + currentDomain = domain; + currentIndex = i; + + if (currentDomainSize == numOSDs) { + int cd = getMatch(hostName, clientIP.getCanonicalHostName()); + if (cd > bestClientMatch) { + bestClientMatch = cd; + bestIndex = currentIndex; + } + } + } + + } catch (UnknownUUIDException exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + break; + } + + } + + ServiceSet.Builder result = ServiceSet.newBuilder(); + + if (bestIndex != -1) + for (int i = 0; i < numOSDs; i++) + result.addServices(allOSDs.getServices(bestIndex + i)); + + return result; + + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs) { + return allOSDs; + } + + @Override + public void setAttribute(String key, String value) { + // don't accept any attributes + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/Inet4AddressMatcher.java b/java/servers/src/org/xtreemfs/mrc/osdselection/Inet4AddressMatcher.java new file mode 100644 index 0000000..7a26464 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/Inet4AddressMatcher.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.Inet4Address; +import java.net.InetAddress; + +/** + * + * @author bjko + */ +public class Inet4AddressMatcher implements InetAddressMatcher { + + private final Inet4Address addr; + + private final int addrAsInt; + + private final int networkPrefixLen; + + private final int netmask; + + public static final int NETWORK_PREFIX_SINGLE_ADDR = 32; + + public Inet4AddressMatcher(Inet4Address addr) { + this(addr,NETWORK_PREFIX_SINGLE_ADDR); + } + + public Inet4AddressMatcher(Inet4Address addr, int networkPrefixLen) { + this.networkPrefixLen = networkPrefixLen; + this.addr = addr; + addrAsInt = bytesToInt(addr.getAddress()); + netmask = (0xFFFFFFFF << (32 - networkPrefixLen)) & 0xFFFFFFFF; + } + + @Override + public boolean matches(InetAddress addr) { + try { + Inet4Address i4addr = (Inet4Address) addr; + if (networkPrefixLen == NETWORK_PREFIX_SINGLE_ADDR) { + return this.addr.equals(i4addr); + } else { + final int otherAddrAsInt = bytesToInt(i4addr.getAddress()); + + return (this.addrAsInt & netmask) == (otherAddrAsInt & netmask); + } + } catch (ClassCastException ex) { + return false; + } + } + + private static int bytesToInt(byte[] arr) { + int tmp = (arr[3] & 0xFF); + tmp += (arr[2] & 0xFF) << 8; + tmp += (arr[1] & 0xFF) << 16; + tmp += (arr[0] & 0xFF) << 24; + return tmp; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/InetAddressMatcher.java b/java/servers/src/org/xtreemfs/mrc/osdselection/InetAddressMatcher.java new file mode 100644 index 0000000..1d6b488 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/InetAddressMatcher.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; + +/** + * + * @author bjko + */ +public interface InetAddressMatcher { + + public boolean matches(InetAddress addr); + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/OSDSelectionPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/OSDSelectionPolicy.java new file mode 100644 index 0000000..631770e --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/OSDSelectionPolicy.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; + +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Interface for policies implementing a selection mechanism for OSDs. + * + * @author stender + */ +public interface OSDSelectionPolicy { + + /** + * Selects a list of OSDs. + * + * @param allOSDs + * a list of all available OSDs + * @param clientIP + * the client's IP address + * @param clientCoords + * the client's Vivaldi coordinates + * @param currentXLoc + * the current X-Locations list + * @param numOSDs + * the number of OSDs required in a valid group. This is only relevant for grouping and will be ignored + * by filtering and sorting policies. + * @return a list of selected OSDs + */ + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, InetAddress clientIP, VivaldiCoordinates clientCoords, + XLocList currentXLoc, int numOSDs); + + /** + * Simplified version of + * getOSDs(ServiceSet allOSDs, InetAddress clientIP, XLocList currentXLoc, int numOSDs). + * This method will be invoked by the framework if no context is available e.g., when displaying + * the list of suitable OSDs in the webinterface or a maintenance tool. + * + * @param allOSDs + * a list of all available OSDs + * @return a list of selected OSDs + */ + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs); + + /** + * Sets a new policy attribute. This method is invoked each time a + * policy-related extended attribute is set. + * + * @param key + * the attribute key + * @param value + * the attribute value + */ + public void setAttribute(String key, String value); + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/OSDStatusManager.java b/java/servers/src/org/xtreemfs/mrc/osdselection/OSDStatusManager.java new file mode 100644 index 0000000..d304e0e --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/OSDStatusManager.java @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.io.IOException; +import java.net.InetAddress; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.VolumeChangeListener; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Checks regularly for suitable OSDs for each volume. + * + * @author bjko + */ +public class OSDStatusManager extends LifeCycleThread implements VolumeChangeListener { + + /** + * Interval in ms to wait between two checks. + */ + private int checkIntervalMillis = 1000 * 5; + + /** + * A list of volumes registered with the thread. + */ + private final Map volumeMap; + + /** + * The latest set of all known OSDs fetched from the Directory Service. + */ + private ServiceSet.Builder knownOSDs; + + /** + * A map containing all known OSDs sorted by their UUIDs. + */ + private final Map knownOSDMap; + + /** + * Thread shuts down if true. + */ + private boolean quit = false; + + /** + * Reference to the MRCRequestDispatcher. + */ + private final MRCRequestDispatcher master; + + public OSDStatusManager(MRCRequestDispatcher master) throws IOException { + + super("OSDStatusManager"); + + this.master = master; + + volumeMap = new HashMap(); + knownOSDs = ServiceSet.newBuilder(); + knownOSDMap = new HashMap(); + + int interval = master.getConfig().getOsdCheckInterval(); + checkIntervalMillis = 1000 * interval; + } + + @Override + public synchronized void volumeChanged(VolumeInfo volume) { + + final String volId = volume.getId(); + VolumeOSDFilter vol = volumeMap.get(volId); + + if (vol == null) { + vol = new VolumeOSDFilter(master, knownOSDMap); + volumeMap.put(volId, vol); + } + + try { + vol.init(volume); + } catch (DatabaseException e) { + Logging.logError(Logging.LEVEL_ERROR, this, e); + } + + this.notifyAll(); + } + + @Override + public synchronized void volumeDeleted(String volumeId) { + volumeMap.remove(volumeId); + } + + @Override + public synchronized void attributeSet(String volumeId, String key, String value) { + + VolumeOSDFilter vol = volumeMap.get(volumeId); + + if (vol == null) { + Logging.logError(Logging.LEVEL_ERROR, this, new Exception( + "no volume OSD filter found for volume " + volumeId)); + return; + } + + vol.setAttribute(key, value); + + } + + /** + * Shuts down the thread. + */ + @Override + public synchronized void shutdown() { + quit = true; + this.interrupt(); + this.notifyAll(); + } + + /** + * Main loop. + */ + @Override + public void run() { + + // initially fetch the list of OSDs from the Directory Service + try { + knownOSDs = master.getDirClient().xtreemfs_service_get_by_type(null, RPCAuthentication.authNone, + RPCAuthentication.userService, ServiceType.SERVICE_TYPE_OSD).toBuilder(); + } catch (Throwable exc) { + this.notifyCrashed(exc); + } + + notifyStarted(); + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, + "OSD status manager operational, using DIR %s", master.getConfig().getDirectoryService() + .toString()); + + while (!quit) { + + synchronized (this) { + try { + this + .wait(knownOSDs == null || knownOSDs.getServicesCount() == 0 ? checkIntervalMillis / 2 + : checkIntervalMillis); + } catch (InterruptedException ex) { + break; + } + } + + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "sending request for OSD list to DIR..."); + + try { + // request list of registered OSDs from Directory + // Service + knownOSDs = master.getDirClient().xtreemfs_service_get_by_type(null, RPCAuthentication.authNone, + RPCAuthentication.userService, ServiceType.SERVICE_TYPE_OSD).toBuilder(); + + Logging + .logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "... received OSD list from DIR"); + + evaluateResponse(knownOSDs); + + } catch (InterruptedException ex) { + break; + } catch (Exception exc) { + if (!quit) + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, OutputUtils + .stackTraceToString(exc)); + } + + } + + notifyStopped(); + } + + /** + * Returns the list of usable OSDs for the given volume id. + * + * @param volumeId + * the volume id + * @param clientIP + * the client's IP address + * @param currentXLoc + * the file's current XLoc list + * @param numOSDs + * the number of requested OSDs + * @return a list of feasible OSDs + */ + public synchronized ServiceSet.Builder getUsableOSDs(String volumeId, InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + + VolumeOSDFilter vol = volumeMap.get(volumeId); + if (vol == null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "no volume registered at OSDStatusManager with ID '%s'", volumeId); + return null; + } + + // return a set of OSDs + ServiceSet.Builder result = vol.filterByOSDSelectionPolicy(knownOSDs, clientIP, clientCoords, + currentXLoc, numOSDs); + + return result; + } + + public synchronized ServiceSet.Builder getUsableOSDs(String volumeId) { + + VolumeOSDFilter vol = volumeMap.get(volumeId); + if (vol == null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "no volume registered at OSDStatusManager with ID '%s'", volumeId); + return null; + } + + // return a set of OSDs + return vol.filterByOSDSelectionPolicy(knownOSDs); + } + + public synchronized Replicas getSortedReplicaList(String volumeId, InetAddress clientIP, + VivaldiCoordinates clientCoords, List repls, XLocList xLocList) { + + VolumeOSDFilter vol = volumeMap.get(volumeId); + if (vol == null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "no volume registered at OSDStatusManager with ID '%s'", volumeId); + return null; + } + + // return a sorted set of replicas + return vol.sortByReplicaSelectionPolicy(clientIP, clientCoords, repls, xLocList); + + } + + public synchronized void evaluateResponse(ServiceSet.Builder knownOSDs) { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "response..."); + + assert (knownOSDs != null); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "registered OSDs"); + if (knownOSDs.getServicesCount() == 0) + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "there are currently no OSDs available"); + if (Logging.isDebug()) + for (Service osd : knownOSDs.getServicesList()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, "%s", osd.getUuid()); + } + + // update the list of known OSDs + this.knownOSDs = knownOSDs; + knownOSDMap.clear(); + for (Service osd : knownOSDs.getServicesList()) + knownOSDMap.put(osd.getUuid(), osd); + } + + public synchronized Service getOSDService(String uuid) { + return knownOSDMap.get(uuid); + } + + /** + * Returns the approximate amount of free space in the given volume. + * + * @param volumeId + * the ID of the volume + * + * @return the approximate number of free bytes in the volume + * + */ + public long getFreeSpace(String volumeId) { + + long free = 0; + + ServiceSet.Builder usableOSDs = getUsableOSDs(volumeId); + if (usableOSDs == null) + return 0; + + for (Service entry : usableOSDs.getServicesList()) { + String freeStr = KeyValuePairs.getValue(entry.getData().getDataList(), "free"); + if (freeStr != null) + free += Long.valueOf(freeStr); + } + return free; + } + + /** + * Returns the approximate amount of usable space in the given volume. + * + * @param volumeId + * the ID of the volume + * + * @return the approximate number of usable bytes in the volume by non-privileged users + * + */ + public long getUsableSpace(String volumeId) { + + long usable = 0; + + ServiceSet.Builder usableOSDs = getUsableOSDs(volumeId); + if (usableOSDs == null) + return 0; + + for (Service entry : usableOSDs.getServicesList()) { + String usableStr = KeyValuePairs.getValue(entry.getData().getDataList(), "usable"); + if (usableStr != null) + usable += Long.valueOf(usableStr); + } + return usable; + } + + public long getTotalSpace(String volumeId) { + + long total = 0; + + ServiceSet.Builder usableOSDs = getUsableOSDs(volumeId); + if (usableOSDs == null) + return 0; + + for (Service entry : usableOSDs.getServicesList()) { + String totalStr = KeyValuePairs.getValue(entry.getData().getDataList(), "total"); + if (totalStr != null) + total += Long.valueOf(totalStr); + } + return total; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/PolicyHelper.java b/java/servers/src/org/xtreemfs/mrc/osdselection/PolicyHelper.java new file mode 100644 index 0000000..cb82827 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/PolicyHelper.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; + +/** + * Class with static helper methods for policies. + * + * @author stender + * + */ +public class PolicyHelper { + + /** + * Removes all OSDs from the given serivce set that are already included in + * the given XLoc list. + * + * @param allOSDs + * the set of OSDs + * @param xLocList + * the XLoc list containing all OSDs to remove + */ + public static ServiceSet.Builder removeUsedOSDs(ServiceSet.Builder allOSDs, XLocList xLocList) { + + if (xLocList == null) + return allOSDs; + + Set newOSDs = new HashSet(allOSDs.getServicesList()); + + for (int i = 0; i < xLocList.getReplicaCount(); i++) { + XLoc currentRepl = xLocList.getReplica(i); + for (int j = 0; j < currentRepl.getOSDCount(); j++) + for (Service osd : allOSDs.getServicesList()) + if (currentRepl.getOSD(j).equals(osd.getUuid())) { + newOSDs.remove(osd); + } + } + + return ServiceSet.newBuilder().addAllServices(newOSDs); + } + + public static ServiceSet.Builder sortServiceSet(ServiceSet.Builder set, Comparator comp) { + + List immutableList = set.getServicesList(); + List list = new ArrayList(immutableList); + Collections.sort(list, comp); + + return ServiceSet.newBuilder().addAllServices(list); + } + + public static ServiceSet.Builder shuffleServiceSet(ServiceSet.Builder set) { + + List immutableList = set.getServicesList(); + List list = new ArrayList(immutableList); + Collections.shuffle(list); + + return ServiceSet.newBuilder().addAllServices(list); + } + + public static ServiceSet.Builder reverseServiceSet(ServiceSet.Builder set) { + + List immutableList = set.getServicesList(); + List list = new ArrayList(immutableList); + Collections.reverse(list); + + return ServiceSet.newBuilder().addAllServices(list); + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/SortDCMapPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/SortDCMapPolicy.java new file mode 100644 index 0000000..40d8366 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/SortDCMapPolicy.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.util.Comparator; +import java.util.Properties; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Sorts the list of OSDs in ascending order of their distance to the client. + * The distance needs to be defined in the datacenter map. + * + * @author bjko, stender + */ +public class SortDCMapPolicy extends DCMapPolicyBase { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_DCMAP + .getNumber(); + + public SortDCMapPolicy() { + } + + public SortDCMapPolicy(Properties p) { + super(p); + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + + final Inet4Address cAddr = (Inet4Address) clientIP; + + if (allOSDs != null) { + allOSDs = PolicyHelper.sortServiceSet(allOSDs, new Comparator() { + public int compare(Service o1, Service o2) { + try { + ServiceUUID uuid1 = new ServiceUUID(o1.getUuid()); + ServiceUUID uuid2 = new ServiceUUID(o2.getUuid()); + Inet4Address osdAddr1 = (Inet4Address) uuid1.getAddress().getAddress(); + Inet4Address osdAddr2 = (Inet4Address) uuid2.getAddress().getAddress(); + + return getDistance(osdAddr1, cAddr) - getDistance(osdAddr2, cAddr); + + } catch (UnknownUUIDException e) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, "cannot compare UUIDs"); + Logging.logMessage(Logging.LEVEL_WARN, this, OutputUtils.stackTraceToString(e)); + return 0; + } + } + }); + } + + return allOSDs; + + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs) { + return allOSDs; + } + + @Override + public void setAttribute(String key, String value) { + // don't accept any attributes + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/SortFQDNPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/SortFQDNPolicy.java new file mode 100644 index 0000000..26b29f7 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/SortFQDNPolicy.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; +import java.util.Comparator; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Sorts the list of OSDs in ascending order of their distance to the client. + * The distance is determined by means of the server's and client's FQDNs. + * + * @author bjko, stender + */ +public class SortFQDNPolicy extends FQDNPolicyBase { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_FQDN + .getNumber(); + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, final InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + + if (allOSDs == null) + return null; + + allOSDs = PolicyHelper.sortServiceSet(allOSDs, new Comparator() { + public int compare(Service o1, Service o2) { + try { + return getMatch(new ServiceUUID(o2.getUuid()).getAddress().getHostName(), clientIP + .getCanonicalHostName()) + - getMatch(new ServiceUUID(o1.getUuid()).getAddress().getHostName(), clientIP + .getCanonicalHostName()); + } catch (UnknownUUIDException e) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, "cannot compare FQDNs"); + Logging.logMessage(Logging.LEVEL_WARN, this, OutputUtils.stackTraceToString(e)); + return 0; + } + } + }); + + return allOSDs; + + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs) { + return allOSDs; + } + + @Override + public void setAttribute(String key, String value) { + // don't accept any attributes + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/SortHostRoundRobinPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/SortHostRoundRobinPolicy.java new file mode 100644 index 0000000..bb55230 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/SortHostRoundRobinPolicy.java @@ -0,0 +1,66 @@ +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; +import java.util.HashMap; +import java.util.LinkedList; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet.Builder; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +public class SortHostRoundRobinPolicy implements OSDSelectionPolicy { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_HOST_ROUND_ROBIN + .getNumber(); + @Override + public Builder getOSDs(Builder allOSDs, InetAddress clientIP, VivaldiCoordinates clientCoords, + XLocList currentXLoc, int numOSDs) { + return getOSDs(allOSDs); + } + + @Override + public Builder getOSDs(Builder allOSDs) { + + // Map OSDs to hosts + HashMap> hostToOsdsMap = new HashMap>(); + for (Service osd : allOSDs.getServicesList()) { + + try { + String host = new ServiceUUID(osd.getUuid()).getAddress().getHostName(); + if (hostToOsdsMap.containsKey(host)) { + hostToOsdsMap.get(host).add(osd); + } else { + hostToOsdsMap.put(host, new LinkedList()); + hostToOsdsMap.get(host).add(osd); + } + + } catch (UnknownUUIDException exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + continue; + } + } + + // Create result ServiceSet + Builder result = ServiceSet.newBuilder(); + while (result.getServicesCount() < allOSDs.getServicesCount()) { + for (LinkedList osds : hostToOsdsMap.values()) { + if (!osds.isEmpty()) { + result.addServices(osds.pop()); + } + } + } + + return result; + } + + @Override + public void setAttribute(String key, String value) { + // don't accept any attributes + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/SortRandomPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/SortRandomPolicy.java new file mode 100644 index 0000000..b4eeeae --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/SortRandomPolicy.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; + +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Randomly shuffles the list of OSDs. + * + * @author stender + */ +public class SortRandomPolicy implements OSDSelectionPolicy { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_RANDOM + .getNumber(); + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + return getOSDs(allOSDs); + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs) { + + if (allOSDs == null) + return null; + + allOSDs = PolicyHelper.shuffleServiceSet(allOSDs); + return allOSDs; + } + + @Override + public void setAttribute(String key, String value) { + // don't accept any attributes + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/SortReversePolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/SortReversePolicy.java new file mode 100644 index 0000000..5e85abf --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/SortReversePolicy.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; + +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Reverses the list of replicas. Mainly used internally in unit tests. + */ +public class SortReversePolicy implements OSDSelectionPolicy { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_REVERSE.getNumber(); + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + return getOSDs(allOSDs); + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs) { + if (allOSDs == null) + return null; + + allOSDs = PolicyHelper.reverseServiceSet(allOSDs); + return allOSDs; + } + + @Override + public void setAttribute(String key, String value) { + // don't accept any attributes + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/SortUUIDPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/SortUUIDPolicy.java new file mode 100644 index 0000000..f8d90f8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/SortUUIDPolicy.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013 Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; +import java.util.Comparator; + +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Sorts the list of OSDs based on their UUID. This is mainly used by internal tests. + */ +public class SortUUIDPolicy implements OSDSelectionPolicy { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_UUID.getNumber(); + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, final InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + + if (allOSDs == null) { + return null; + } + + allOSDs = PolicyHelper.sortServiceSet(allOSDs, new Comparator() { + @Override + public int compare(Service o1, Service o2) { + return o1.getUuid().compareTo(o2.getUuid()); + } + }); + + return allOSDs; + + } + + @Override + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs) { + return allOSDs; + } + + @Override + public void setAttribute(String key, String value) { + // don't accept any attributes + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/SortVivaldiPolicy.java b/java/servers/src/org/xtreemfs/mrc/osdselection/SortVivaldiPolicy.java new file mode 100644 index 0000000..5b83122 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/SortVivaldiPolicy.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Juan Gonzalez de Benito, + * Zuse Institute Berlin, Barcelona Supercomputing Center + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; + +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.osd.vivaldi.VivaldiNode; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * + * @author Juan González (BSC) + */ +public class SortVivaldiPolicy implements OSDSelectionPolicy { + + public static final short POLICY_ID = (short) OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_VIVALDI + .getNumber(); + + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs, InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + + if (allOSDs == null) + return null; + + // Calculate the distances from the client to all the OSDs + Hashtable distances = new Hashtable(); + + for (Service oneOSD : allOSDs.getServicesList()) { + + ServiceDataMap sdm = oneOSD.getData(); + String strCoords = org.xtreemfs.common.KeyValuePairs.getValue(sdm.getDataList(), + "vivaldi_coordinates"); + + if (strCoords != null) { + + VivaldiCoordinates osdCoords = VivaldiNode.stringToCoordinates(strCoords); + if (osdCoords != null) { + + double currentDistance = VivaldiNode.calculateDistance(clientCoords, osdCoords); + + distances.put(oneOSD.getUuid(), currentDistance); + } + } + } + + // Create a new ServiceSet and add the sorted services to it + List retSet = new LinkedList(); + for (Service oneOSD : allOSDs.getServicesList()) { + + Double oneOSDDistance = distances.get(oneOSD.getUuid()); + if (oneOSDDistance != null) { // Does the DS contain the info for + // this service? + + boolean inserted = false; + int i = 0; + + while (!inserted) { + + if (i >= retSet.size()) { + + retSet.add(oneOSD); + inserted = true; + + } else { + + Double iDistance = distances.get(retSet.get(i).getUuid()); + + if ((iDistance == null) || // The OSDs without + // coordinates must be left + // at the end of the list + (oneOSDDistance.doubleValue() < iDistance.doubleValue())) { + + retSet.add(i, oneOSD); + inserted = true; + + } else { + i++; + } + } + } + } else { + // If the OSD cannot be sorted because the DS does not provide + // all its information, we append it to the end of the list + retSet.add(oneOSD); + } + } + + return ServiceSet.newBuilder().addAllServices(retSet); + } + + public ServiceSet.Builder getOSDs(ServiceSet.Builder allOSDs) { + // It's not possible to calculate the most appropiate OSD without + // knowing the client's coordinates + return allOSDs; + } + + public void setAttribute(String key, String value) { + // No attribute defined yet + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/osdselection/VolumeOSDFilter.java b/java/servers/src/org/xtreemfs/mrc/osdselection/VolumeOSDFilter.java new file mode 100644 index 0000000..35466ff --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/osdselection/VolumeOSDFilter.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.osdselection; + +import java.net.InetAddress; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.metadata.XAttr; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Volume and policy record. + */ +public class VolumeOSDFilter { + + private final MRCRequestDispatcher master; + + /** + * volume ID + */ + private String volId; + + /** + * OSD selection policy + */ + private short[] osdPolicy; + + /** + * replica selection policy + */ + private short[] replPolicy; + + /** + * map containing instances of all OSD policies + */ + private Map policyMap; + + /** + * map containing all known OSDs + */ + private final Map knownOSDMap; + + public VolumeOSDFilter(MRCRequestDispatcher master, Map knownOSDMap) { + this.master = master; + this.knownOSDMap = knownOSDMap; + } + + public void init(VolumeInfo volume) throws DatabaseException { + + this.volId = volume.getId(); + this.osdPolicy = volume.getOsdPolicy(); + this.replPolicy = volume.getReplicaPolicy(); + + // initialize the policy map + policyMap = new HashMap(); + for (short pol : osdPolicy) { + try { + if (!policyMap.containsKey(pol)) { + policyMap.put(pol, master.getPolicyContainer().getOSDSelectionPolicy(pol)); + } + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, "could not instantiate OSDSelectionPolicy %d", + pol); + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, OutputUtils.stackTraceToString(e)); + } + } + + for (short pol : replPolicy) { + try { + if (!policyMap.containsKey(pol)) { + policyMap.put(pol, master.getPolicyContainer().getOSDSelectionPolicy(pol)); + } + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, "could not instantiate OSDSelectionPolicy %d", + pol); + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, OutputUtils.stackTraceToString(e)); + } + } + + // get all policy attributes + + try { + DatabaseResultSet xattrs = master.getVolumeManager().getStorageManager(this.volId) + .getXAttrs(1, StorageManager.SYSTEM_UID); + + while (xattrs.hasNext()) { + XAttr xattr = xattrs.next(); + if (xattr.getKey().startsWith(MRCHelper.XTREEMFS_POLICY_ATTR_PREFIX)) { + setAttribute(xattr.getKey(), new String(xattr.getValue())); + } + } + + xattrs.destroy(); + + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, "could not set policy attributes"); + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, OutputUtils.stackTraceToString(exc)); + } + + } + + public void setAttribute(String key, String value) { + + assert (key.startsWith(MRCHelper.XTREEMFS_POLICY_ATTR_PREFIX)); + key = key.substring(MRCHelper.XTREEMFS_POLICY_ATTR_PREFIX.length()); + + int index = key.indexOf('.'); + + // TODO refactored. is now moved to MRCHelper.setPolicyValue()! + // so: delete this? + if (index == -1) { + Logging.logMessage( + Logging.LEVEL_WARN, + Category.misc, + this, + "'%s=%s :' XtreemFS no longer supports global policy attributes. It is necessary to specify a policy e.g., '1000.%s=%s'", + key, value, key, value); +// for (OSDSelectionPolicy pol : policyMap.values()) +// pol.setAttribute(key, value); + } else { + short policyId = Short.parseShort(key.substring(0, index)); + OSDSelectionPolicy pol = policyMap.get(policyId); + if (pol != null) { + pol.setAttribute(key.substring(index + 1), value); + } + } + + } + + public ServiceSet.Builder filterByOSDSelectionPolicy(ServiceSet.Builder knownOSDs, InetAddress clientIP, + VivaldiCoordinates clientCoords, XLocList currentXLoc, int numOSDs) { + + ServiceSet.Builder result = ServiceSet.newBuilder().addAllServices(knownOSDs.getServicesList()); + for (short id : osdPolicy) { + OSDSelectionPolicy policy = policyMap.get(id); + if (policy == null) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.proc, this, + "could not find OSD selection policy with ID=%d, will be ignored", id); + continue; + } + + result = policy.getOSDs(result, clientIP, clientCoords, currentXLoc, numOSDs); + } + + return result; + } + + public ServiceSet.Builder filterByOSDSelectionPolicy(ServiceSet.Builder knownOSDs) { + + ServiceSet.Builder result = ServiceSet.newBuilder().addAllServices(knownOSDs.getServicesList()); + for (short id : osdPolicy) { + + OSDSelectionPolicy policy = policyMap.get(id); + + if (policy == null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "could not find OSD selection policy with ID %d, will be ignored", id); + continue; + } + + result = policy.getOSDs(result); + } + + return result; + } + + public Replicas sortByReplicaSelectionPolicy(InetAddress clientIP, VivaldiCoordinates clientCoords, + List unsortedRepls, XLocList xLocList) { + + // head OSD -> replica + Map replMap = new HashMap(); + + // get a list of all head OSDs in the XLoc + ServiceSet.Builder headOSDServiceSetBuilder = ServiceSet.newBuilder(); + for (int i = 0; i < unsortedRepls.size(); i++) { + + Replica repl = unsortedRepls.get(i); + assert (repl.getOsdUuidsCount() > 0); + + String headOSD = repl.getOsdUuids(0); + + // store the mapping in a temporary replica map + replMap.put(headOSD, repl); + + // retrieve the service name from the 'known OSDs' map; if no such + // service has been registered, create a dummy service object from + // the OSD UUID + Service s = knownOSDMap.get(headOSD); + if (s == null) { + s = Service.newBuilder().setData(ServiceDataMap.newBuilder()).setLastUpdatedS(0) + .setName("OSD @ " + headOSD).setType(ServiceType.SERVICE_TYPE_OSD).setUuid(headOSD) + .setVersion(0).build(); + } + + headOSDServiceSetBuilder.addServices(s); + } + + // sort the list of head OSDs according to the policy + for (short id : replPolicy) { + OSDSelectionPolicy policy = policyMap.get(id); + + if (policy == null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "could not find Replica selection policy with ID %d, will be ignored", id); + continue; + } + + headOSDServiceSetBuilder = policy.getOSDs(headOSDServiceSetBuilder, clientIP, clientCoords, + xLocList, headOSDServiceSetBuilder.getServicesCount()); + } + + // arrange the resulting list of replicas in the same order as the list + // of sorted head OSDs + Replicas.Builder sortedReplsBuilder = Replicas.newBuilder(); + for (Service headOSD : headOSDServiceSetBuilder.getServicesList()) { + + Replica r = replMap.get(headOSD.getUuid()); + assert (r != null); + assert (r.getOsdUuidsCount() > 0); + + Replica.Builder replBuilder = Replica.newBuilder().setReplicationFlags(r.getReplicationFlags()) + .setStripingPolicy(r.getStripingPolicy()); + + for (int j = 0; j < r.getOsdUuidsCount(); j++) { + replBuilder.addOsdUuids(r.getOsdUuids(j)); + } + + sortedReplsBuilder.addReplicas(replBuilder); + } + + return sortedReplsBuilder.build(); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/stages/InternalCallbackInterface.java b/java/servers/src/org/xtreemfs/mrc/stages/InternalCallbackInterface.java new file mode 100644 index 0000000..ab8454a --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/stages/InternalCallbackInterface.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 by Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.mrc.stages; + +import org.xtreemfs.mrc.MRCRequest; + +/** + * Internal callbacks can be used to execute something in the context of the ProcessingStage. This is needed to ensure + * database calls are exclusive and always from the same process. + * + * @see ProcessingStage#enqueueInternalCallbackOperation(MRCRequest, InternalCallbackInterface) + */ +public interface InternalCallbackInterface { + public void execute(MRCRequest rq) throws Throwable; +} diff --git a/java/servers/src/org/xtreemfs/mrc/stages/InternalCallbackMRCRequest.java b/java/servers/src/org/xtreemfs/mrc/stages/InternalCallbackMRCRequest.java new file mode 100644 index 0000000..9251c30 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/stages/InternalCallbackMRCRequest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013 by Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.mrc.stages; + +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.mrc.MRCRequest; + +/** + * This class is used internally to execute callbacks ({@link InternalCallbackInterface}) in the context of the + * ProcessingStage. + * + * @see ProcessingStage#enqueueInternalCallbackOperation(MRCRequest, InternalCallbackInterface) + */ +class InternalCallbackMRCRequest extends MRCRequest { + + private final InternalCallbackInterface callback; + + public InternalCallbackMRCRequest(InternalCallbackInterface callback) { + this((RPCServerRequest) null, callback); + } + + public InternalCallbackMRCRequest(MRCRequest rq, InternalCallbackInterface callback) { + this(rq.getRPCRequest(), callback); + } + + public InternalCallbackMRCRequest(RPCServerRequest rpcRequest, InternalCallbackInterface callback) { + super(rpcRequest); + this.callback = callback; + } + + public InternalCallbackInterface getCallback() { + return callback; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/stages/MRCStage.java b/java/servers/src/org/xtreemfs/mrc/stages/MRCStage.java new file mode 100644 index 0000000..588b455 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/stages/MRCStage.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.stages; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.mrc.MRCRequest; + +public abstract class MRCStage extends LifeCycleThread { + + /** + * global stage response codes. These codes are sent back by a stage to + * indicate to the operation's state machine, which action to take next. + * + * This list contains some basic codes as well as all specialized codes used + * by individual stages. + * + */ + public enum StageResponseCode { + /** + * go to next operation + */ + OK, + /** + * request failed, send error + */ + FAILED, + /** + * stay in current state and wait for next event + */ + WAIT, + /** + * finish request by sending the response + */ + FINISH + + } + + /** + * queue containing all requests + */ + protected BlockingQueue q; + + /** + * set to true if stage should shut down + */ + protected volatile boolean quit; + + public AtomicInteger _numRq, _maxRqTime, _minRqTime; + + public AtomicLong _sumRqTime; + + public MRCStage(String stageName) { + super(stageName); + q = new LinkedBlockingQueue(); + this.quit = false; + + _numRq = new AtomicInteger(0); + _maxRqTime = new AtomicInteger(0); + _minRqTime = new AtomicInteger(Integer.MAX_VALUE); + _sumRqTime = new AtomicLong(0); + } + + /** + * send an request for a stage operation + * + * @param rq + * the request + * @param the + * method in the stage to execute + */ + public void enqueueOperation(MRCRequest rq, int method, MRCStageCallbackInterface callback) { + q.add(new StageMethod(rq, method, callback)); + } + + /** + * shut the stage thread down + */ + public void shutdown() { + this.quit = true; + this.interrupt(); + } + + /** + * Get current number of requests in the queue. + * + * @return queue length + */ + public int getQueueLength() { + return q.size(); + } + + @Override + public void run() { + + notifyStarted(); + + while (!quit) { + MRCRequest rq = null; + try { + final StageMethod op = q.take(); + + rq = op.getRq(); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, + "processing request XID=%d method %d", + rq.getRPCRequest().getHeader().getCallId(), op.getStageMethod()); + + processMethod(op); + + } catch (InterruptedException ex) { + break; + } catch (Throwable ex) { + this.notifyCrashed(ex); + break; + } + } + + notifyStopped(); + } + + /** + * Handles the actual execution of a stage method. Must be implemented by + * all stages. + * + * @param method + * the stage method to execute + */ + protected abstract void processMethod(StageMethod method); + + protected static final class StageMethod { + private MRCRequest rq; + + private int stageMethod; + + private MRCStageCallbackInterface callback; + + public StageMethod(MRCRequest rq, int stageMethod, MRCStageCallbackInterface callback) { + this.rq = rq; + this.stageMethod = stageMethod; + this.callback = callback; + } + + public int getStageMethod() { + return stageMethod; + } + + public void setStageMethod(int stageMethod) { + this.stageMethod = stageMethod; + } + + public MRCRequest getRq() { + return rq; + } + + public void setRq(MRCRequest rq) { + this.rq = rq; + } + + public MRCStageCallbackInterface getCallback() { + return callback; + } + + public void setCallback(MRCStageCallbackInterface callback) { + this.callback = callback; + } + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/stages/MRCStageCallbackInterface.java b/java/servers/src/org/xtreemfs/mrc/stages/MRCStageCallbackInterface.java new file mode 100644 index 0000000..aec1c9d --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/stages/MRCStageCallbackInterface.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.stages; + +import org.xtreemfs.mrc.MRCRequest; + + +public interface MRCStageCallbackInterface { + + public void methodExecutionCompleted(MRCRequest request, MRCStage.StageResponseCode result); + +} diff --git a/java/servers/src/org/xtreemfs/mrc/stages/OnCloseReplicationThread.java b/java/servers/src/org/xtreemfs/mrc/stages/OnCloseReplicationThread.java new file mode 100644 index 0000000..4fd408c --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/stages/OnCloseReplicationThread.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.stages; + +import java.net.InetSocketAddress; +import java.util.Iterator; +import java.util.concurrent.LinkedBlockingQueue; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; + +/** + * + * @author stender + */ +public class OnCloseReplicationThread extends LifeCycleThread { + + private final MRCRequestDispatcher master; + + private boolean quit; + + private final LinkedBlockingQueue requests; + + public OnCloseReplicationThread(MRCRequestDispatcher master) { + super("OnCloseReplThr"); + this.master = master; + this.requests = new LinkedBlockingQueue(); + } + + public void shutdown() { + this.quit = true; + this.interrupt(); + } + + public void enqueueRequest(MRCRequest req) { + assert (this.isAlive()); + assert (req != null); + requests.add(req); + } + + public void run() { + + notifyStarted(); + try { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.lifecycle, this, + "OnCloseReplicationThread started"); + + do { + final MRCRequest req = requests.take(); + final XCap xcap = ((xtreemfs_update_file_sizeRequest) req.getRequestArgs()).getXcap(); + final XLocSet xlocSet = (XLocSet) req.getDetails().context.get("xLocList"); + final FileCredentials creds = FileCredentials.newBuilder().setXcap(xcap).setXlocs(xlocSet) + .build(); + + try { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "triggering replication for %s", xlocSet.toString()); + + for (int i = 1; i < xlocSet.getReplicasCount(); i++) { + + Replica repl = xlocSet.getReplicas(i); + StripingPolicyImpl spol = StripingPolicyImpl.getPolicy(repl, 0); + + for (int j = 0; j < repl.getOsdUuidsCount(); j++) { + + Iterator objs = spol.getObjectsOfOSD(j, 0, Long.MAX_VALUE); + long obj = objs.next(); + + RPCResponse resp = null; + try { + + InetSocketAddress osd = new ServiceUUID(repl.getOsdUuids(j)).getAddress(); + + // read one byte from each OSD in each replica + // to trigger the replication + resp = master.getOSDClient().read(osd, RPCAuthentication.authNone, + RPCAuthentication.userService, creds, xcap.getFileId(), obj, 0, 0, 1); + resp.get(); + + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_WARN, Category.proc, this, OutputUtils + .stackTraceToString(e)); + } finally { + if (resp != null) + resp.freeBuffers(); + } + + } + } + + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } while (!quit); + } catch (InterruptedException ex) { + // idontcare + } + + notifyStopped(); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.lifecycle, this, + "OnCloseReplicationThread finished"); + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/stages/ProcessingStage.java b/java/servers/src/org/xtreemfs/mrc/stages/ProcessingStage.java new file mode 100644 index 0000000..f0c0309 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/stages/ProcessingStage.java @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.stages; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.xtreemfs.common.auth.AuthenticationException; +import org.xtreemfs.common.auth.UserCredentials; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.mrc.ErrorRecord; +import org.xtreemfs.mrc.MRCException; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.StatusPage; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.operations.AccessOperation; +import org.xtreemfs.mrc.operations.AddReplicaOperation; +import org.xtreemfs.mrc.operations.CheckFileListOperation; +import org.xtreemfs.mrc.operations.CheckpointOperation; +import org.xtreemfs.mrc.operations.CreateDirOperation; +import org.xtreemfs.mrc.operations.CreateLinkOperation; +import org.xtreemfs.mrc.operations.CreateSymLinkOperation; +import org.xtreemfs.mrc.operations.CreateVolumeOperation; +import org.xtreemfs.mrc.operations.DeleteOperation; +import org.xtreemfs.mrc.operations.DeleteVolumeOperation; +import org.xtreemfs.mrc.operations.DumpDBOperation; +import org.xtreemfs.mrc.operations.FSetAttrOperation; +import org.xtreemfs.mrc.operations.GetFileCredentialsOperation; +import org.xtreemfs.mrc.operations.GetLocalVolumesOperation; +import org.xtreemfs.mrc.operations.GetSuitableOSDsOperation; +import org.xtreemfs.mrc.operations.GetXAttrOperation; +import org.xtreemfs.mrc.operations.GetXAttrsOperation; +import org.xtreemfs.mrc.operations.GetXLocListOperation; +import org.xtreemfs.mrc.operations.GetXLocSetOperation; +import org.xtreemfs.mrc.operations.InternalDebugOperation; +import org.xtreemfs.mrc.operations.MRCOperation; +import org.xtreemfs.mrc.operations.MoveOperation; +import org.xtreemfs.mrc.operations.OpenOperation; +import org.xtreemfs.mrc.operations.ReadDirAndStatOperation; +import org.xtreemfs.mrc.operations.ReadLinkOperation; +import org.xtreemfs.mrc.operations.RemoveReplicaOperation; +import org.xtreemfs.mrc.operations.RemoveXAttrOperation; +import org.xtreemfs.mrc.operations.RenewOperation; +import org.xtreemfs.mrc.operations.RestoreDBOperation; +import org.xtreemfs.mrc.operations.RestoreFileOperation; +import org.xtreemfs.mrc.operations.SetReadOnlyXattrOperation; +import org.xtreemfs.mrc.operations.SetReplicaUpdatePolicyOperation; +import org.xtreemfs.mrc.operations.SetXAttrOperation; +import org.xtreemfs.mrc.operations.SetattrOperation; +import org.xtreemfs.mrc.operations.ShutdownOperation; +import org.xtreemfs.mrc.operations.StatFSOperation; +import org.xtreemfs.mrc.operations.StatOperation; +import org.xtreemfs.mrc.operations.TruncateOperation; +import org.xtreemfs.mrc.operations.UpdateFileSizeOperation; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceConstants; + +import com.google.protobuf.Descriptors.FieldDescriptor; + +/** + * + * @author bjko + */ +public class ProcessingStage extends MRCStage { + + public static final int STAGEOP_PARSE_AND_EXECUTE = 1; + + public static final int STAGEOP_INTERNAL_CALLBACK = 2; + + private final MRCRequestDispatcher master; + + private final Map operations; + + private final Map _opCountMap; + + private final boolean statisticsEnabled = true; + + public ProcessingStage(MRCRequestDispatcher master) { + super("ProcSt"); + this.master = master; + + operations = new HashMap(); + installOperations(); + + if (statisticsEnabled) { + // initialize operations counter + _opCountMap = new HashMap(); + for (Integer i : operations.keySet()) + _opCountMap.put(i, 0); + } + } + + public void installOperations() { + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_SHUTDOWN, new ShutdownOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_MKVOL, new CreateVolumeOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_RMVOL, new DeleteVolumeOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_LSVOL, new GetLocalVolumesOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_GETATTR, new StatOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_READDIR, new ReadDirAndStatOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_MKDIR, new CreateDirOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_SYMLINK, new CreateSymLinkOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_UNLINK, new DeleteOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_RMDIR, new DeleteOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_GETXATTR, new GetXAttrOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_LISTXATTR, new GetXAttrsOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_SETXATTR, new SetXAttrOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_REMOVEXATTR, new RemoveXAttrOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_OPEN, new OpenOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_RENEW_CAPABILITY, new RenewOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_REPLICA_ADD, new AddReplicaOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_REPLICA_REMOVE, + new RemoveReplicaOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_REPLICA_LIST, new GetXLocListOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_RENAME, new MoveOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_LINK, new CreateLinkOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_STATVFS, new StatFSOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_READLINK, new ReadLinkOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_DUMP_DATABASE, new DumpDBOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_RESTORE_DATABASE, new RestoreDBOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_CHECK_FILE_EXISTS, new CheckFileListOperation( + master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_RESTORE_FILE, new RestoreFileOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_CHECKPOINT, new CheckpointOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_SETATTR, new SetattrOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_FSETATTR, new FSetAttrOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_GET_SUITABLE_OSDS, new GetSuitableOSDsOperation( + master)); + operations.put(MRCServiceConstants.PROC_ID_FTRUNCATE, new TruncateOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_INTERNAL_DEBUG, + new InternalDebugOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_UPDATE_FILE_SIZE, new UpdateFileSizeOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_ACCESS, new AccessOperation(master)); + // TODO operations.put(replication_toMasterRequest.TAG, new + // ReplicationToMasterOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_SET_REPLICA_UPDATE_POLICY, + new SetReplicaUpdatePolicyOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_SET_READ_ONLY_XATTR, new SetReadOnlyXattrOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_GET_FILE_CREDENTIALS, new GetFileCredentialsOperation(master)); + operations.put(MRCServiceConstants.PROC_ID_XTREEMFS_GET_XLOCSET, new GetXLocSetOperation(master)); + } + + public Map get_opCountMap() { + return _opCountMap; + } + +// public String getOpName(int opId) { +// String opName = operations.get(opId).getClass().getSimpleName(); +// return (opName.charAt(0) + "").toLowerCase() + opName.substring(0, opName.length() - "Operation".length()).substring(1); +// } + + @Override + protected void processMethod(StageMethod method) { + switch (method.getStageMethod()) { + case STAGEOP_PARSE_AND_EXECUTE: + parseAndExecute(method); + break; + + case STAGEOP_INTERNAL_CALLBACK: + executeInternalCallback(method); + break; + + default: + method.getRq().setError(ErrorType.INTERNAL_SERVER_ERROR, "unknown stage operation"); + master.requestFinished(method.getRq()); + } + } + + /** + * Parse request and execute method + * + * @param method + * stagemethod to execute + */ + private void parseAndExecute(StageMethod method) { + + final MRCRequest rq = method.getRq(); + final RPCServerRequest rpcRequest = rq.getRPCRequest(); + final RPCHeader header = rpcRequest.getHeader(); + final RPCHeader.RequestHeader rqHeader = header.getRequestHeader(); + + if (header.getMessageType() != MessageType.RPC_REQUEST) { + rq.setError(ErrorType.GARBAGE_ARGS, POSIXErrno.POSIX_ERROR_EIO, + "expected RPC request message type but got " + header.getMessageType()); + return; + } + + final MRCOperation op = operations.get(rqHeader.getProcId()); + + if (op == null) { + rq.setError(ErrorType.INVALID_PROC_ID, "requested operation (" + rqHeader.getProcId() + + ") is not available on this MRC"); + master.requestFinished(rq); + return; + } + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "operation for request %s: %s", rq + .toString(), op.getClass().getSimpleName()); + + if (statisticsEnabled) { + _opCountMap.put(rqHeader.getProcId(), _opCountMap.get(rqHeader.getProcId()) + 1); + } + + // parse request arguments + ErrorRecord error = op.parseRequestArgs(rq); + if (error != null) { + rq.setError(error); + master.requestFinished(rq); + return; + } + + try { + + // get the auth data if available + Auth auth = header.getRequestHeader().hasAuthData() ? header.getRequestHeader().getAuthData() + : null; + + // get the user credentials + org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials ctx = op + .getUserCredentials(rq); + + if (ctx != null) + try { + UserCredentials cred = master.getAuthProvider().getEffectiveCredentials(ctx, + rpcRequest.getConnection().getChannel()); + rq.getDetails().superUser = cred.isSuperUser(); + rq.getDetails().groupIds = cred.getGroupIDs(); + rq.getDetails().userId = cred.getUserID(); + rq.getDetails().auth = auth; + rq.getDetails().password = auth != null && auth.hasAuthPasswd() ? auth.getAuthPasswd() + .getPassword() : ""; + } catch (AuthenticationException ex) { + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, ex.getMessage()); + } + + } catch (Exception exc) { + + method.getRq().setError(ErrorType.INTERNAL_SERVER_ERROR, + "could not initialize authentication module", exc); + master.requestFinished(method.getRq()); + return; + } + + execute(op, method); + + } + + /** + * Execute an operation + * + * @param operation + * MRCOperation to execute + * @param method + * StageMethod to serve as the context + */ + private void execute(MRCOperation op, StageMethod method) { + final MRCRequest rq = method.getRq(); + final RPCServerRequest rpcRequest = rq.getRPCRequest(); + final RPCHeader header = rpcRequest.getHeader(); + final RPCHeader.RequestHeader rqHeader = header.getRequestHeader(); + + try { + + if (Logging.isDebug()) { + + StringBuffer params = new StringBuffer(); + Map fieldMap = rq.getRequestArgs() == null ? null : rq + .getRequestArgs().getAllFields(); + if (fieldMap != null) { + int i = 0; + for (Entry entry : fieldMap.entrySet()) { + params.append(entry.getKey().getName() + "='" + entry.getValue() + + (i == fieldMap.size() - 1 ? "'" : "', ")); + i++; + } + } + Logging.logMessage(Logging.LEVEL_DEBUG, this, "parsed request: %s (%s)\n", + StatusPage.getOpName(rqHeader.getProcId()), params.toString()); + } + + op.startRequest(rq); + + } catch (UserException exc) { + reportUserError(op, rq, exc, exc.getErrno()); + + } catch (MRCException exc) { + Throwable cause = exc.getCause(); + if (cause instanceof DatabaseException + && ((DatabaseException) cause).getType() == ExceptionType.NOT_ALLOWED) + reportUserError(op, rq, exc, POSIXErrno.POSIX_ERROR_EPERM); + else + reportServerError(op, rq, exc); + + } catch (DatabaseException exc) { + if (exc.getType() == ExceptionType.NOT_ALLOWED) { + reportUserError(op, rq, exc, POSIXErrno.POSIX_ERROR_EPERM); + } else if (exc.getType() == ExceptionType.REDIRECT) { + try { + redirect(rq, exc.getAttachment() != null? (String) exc.getAttachment(): master.getReplMasterUUID()); + } catch (MRCException e) { + reportServerError(op, rq, e); + } + } else + reportServerError(op, rq, exc); + + } catch (Throwable exc) { + reportServerError(op, rq, exc); + } + } + + /** + * Enqueue an internal callback operation.
    + * Internal callbacks can be used to execute something in the context of the ProcessingStage. This is needed to + * ensure database calls are exclusive and always from the same process. + * + * @param rq + * The internal callback request. + */ + public void enqueueInternalCallbackOperation(MRCRequest rq, InternalCallbackInterface callback) { + InternalCallbackMRCRequest cbRq = new InternalCallbackMRCRequest(rq, callback); + q.add(new StageMethod(cbRq, ProcessingStage.STAGEOP_INTERNAL_CALLBACK, null)); + } + + /** + * Execute an internal callback operation. + * + * @param method + * with an RPCRequest of type {@link InternalCallbackMRCRequest}. + */ + private void executeInternalCallback(StageMethod method) { + // Call execute on an anonymous operation to avoid duplicating the error handling. + execute(new MRCOperation(master) { + @Override + public void startRequest(MRCRequest rq) throws Throwable { + if (!(rq instanceof InternalCallbackMRCRequest)) { + throw new MRCException("InternalCallbackOperations must be called with a MRCCallbackRequest."); + } + + InternalCallbackInterface callback = ((InternalCallbackMRCRequest) rq).getCallback(); + callback.execute(rq); + } + }, method); + } + + private void reportUserError(MRCOperation op, MRCRequest rq, Throwable exc, POSIXErrno errno) { + if (Logging.isDebug()) + Logging.logUserError(Logging.LEVEL_DEBUG, Category.proc, this, exc); + op.finishRequest(rq, new ErrorRecord(ErrorType.ERRNO, errno, exc.getMessage(), exc)); + } + + private void reportServerError(MRCOperation op, MRCRequest rq, Throwable exc) { + if (Logging.isDebug()) + Logging.logUserError(Logging.LEVEL_DEBUG, Category.proc, this, exc); + op.finishRequest(rq, new ErrorRecord(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_NONE, + "An error has occurred at the MRC. Details: " + exc.getMessage(), exc)); + } + + private void redirect(MRCRequest rq, String uuid) { + rq.getRPCRequest().sendRedirect(uuid); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/stages/XLocSetCoordinator.java b/java/servers/src/org/xtreemfs/mrc/stages/XLocSetCoordinator.java new file mode 100644 index 0000000..6fbdf0e --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/stages/XLocSetCoordinator.java @@ -0,0 +1,866 @@ +/* + * Copyright (c) 2013 by Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.mrc.stages; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.libxtreemfs.Helper; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.client.RPCResponseAvailableListener; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.ErrorRecord; +import org.xtreemfs.mrc.MRCException; +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DBAccessResultListener; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseException.ExceptionType; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.operations.MRCOperation; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.osd.rwre.CoordinatedReplicaUpdatePolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * Changes to xLocSet can harm the data consistency. The XLocSetCoordinator assures that a xLocSet change is atomic from + * a global point of view and that enough replicas are up to date to maintain consistency.
    + * Since database calls have to be exclusively from one process the coordinator calls the + * {@link XLocSetCoordinatorCallback} in the context of the {@link ProcessingStage} when consistency in the new XLocSet + * is assured. + */ +public class XLocSetCoordinator extends LifeCycleThread implements DBAccessResultListener { + private enum RequestType { + ADD_REPLICAS, REMOVE_REPLICAS + }; + + public final static String XLOCSET_CHANGE_ATTR_KEY = "xlocsetchange"; + + protected volatile boolean quit; + private final MRCRequestDispatcher master; + private BlockingQueue q; + + /** The lease timeout is needed to ensure no primary can exist after invalidating. */ + private final int leaseToMS; + + public XLocSetCoordinator(MRCRequestDispatcher master) { + super("XLocSetCoordinator"); + quit = false; + q = new LinkedBlockingQueue(); + this.master = master; + + leaseToMS = master.getConfig().getFleaseLeaseToMS(); + } + + @Override + public void run() { + notifyStarted(); + while (!quit) { + try { + RequestMethod m = q.take(); + processRequest(m); + } catch (InterruptedException ex) { + continue; + } catch (Throwable ex) { + this.notifyCrashed(ex); + break; + } + } + notifyStopped(); + } + + @Override + public void shutdown() { + this.quit = true; + this.interrupt(); + } + + /** + * Choose the matching method and process the request. + * + * ErrorHandling is done separately in the handleError method. + * + * @param m + */ + private void processRequest(RequestMethod m) throws InterruptedException { + try { + switch (m.getRequestType()) { + case ADD_REPLICAS: + processAddReplicas(m); + break; + case REMOVE_REPLICAS: + processRemoveReplicas(m); + break; + default: + throw new Exception("unknown stage operation"); + } + } catch (InterruptedException e) { + throw e; + } catch (Throwable e) { + handleError(m, e); + } + } + + /** + * The RequestMethod keeps all the properties needed to coordinate a xLocSet change. + */ + public final static class RequestMethod { + + /** The type of the coordination request **/ + RequestType type; + /** The MRCOPeration the coordination request is originating from. **/ + MRCOperation op; + /** The original client request asking to change the XLocSet. **/ + MRCRequest rq; + /** The fileId whose XLocSet has to be changed. **/ + String fileId; + /** A capability which will grant sufficient rights to invalidate and update replicas. **/ + Capability capability; + /** + * The callback which will be executed in the context of the {@link ProcessingStage} when the coordination is + * finished. + **/ + XLocSetCoordinatorCallback callback; + /** The current XLocList. **/ + XLocList curXLocList; + /** The new xLocList requested to be installed. **/ + XLocList newXLocList; + + public RequestMethod(RequestType type, String fileId, MRCRequest rq, MRCOperation op, + XLocSetCoordinatorCallback callback, Capability cap, XLocList curXLocList, XLocList newXLocList) { + this.type = type; + this.op = op; + this.rq = rq; + this.fileId = fileId; + this.callback = callback; + this.capability = cap; + this.curXLocList = curXLocList; + this.newXLocList = newXLocList; + } + + public RequestType getRequestType() { + return type; + } + + public String getFileId() { + return fileId; + } + + public MRCRequest getRequest() { + return rq; + } + + public MRCOperation getOperation() { + return op; + } + + public XLocSetCoordinatorCallback getCallback() { + return callback; + } + + public Capability getCapability() { + return capability; + } + + public XLocList getCurXLocList() { + return curXLocList; + } + + public XLocList getNewXLocList() { + return newXLocList; + } + } + + public RequestMethod addReplicas(String fileId, + FileMetadata file, XLocList curXLocList, XLocList extXLocList, MRCRequest rq, O op) + throws DatabaseException { + return addReplicas(fileId, file, curXLocList, extXLocList, rq, op, op); + } + + public RequestMethod addReplicas(String fileId, FileMetadata file, XLocList curXLocList, XLocList extXLocList, + MRCRequest rq, MRCOperation op, XLocSetCoordinatorCallback callback) throws DatabaseException { + + Capability cap = buildCapability(fileId, file); + RequestMethod m = new RequestMethod(RequestType.ADD_REPLICAS, fileId, rq, op, callback, cap, curXLocList, + extXLocList); + + return m; + } + + private void processAddReplicas(final RequestMethod m) throws Throwable { + final MRCRequest rq = m.getRequest(); + + final String fileId = m.getFileId(); + final Capability cap = m.getCapability(); + + final XLocList curXLocList = m.getCurXLocList(); + final XLocList extXLocList = m.getNewXLocList(); + + final XLocSet curXLocSet = Converter.xLocListToXLocSet(curXLocList).build(); + // Ensure the next view won't be propagated until it is installed at the MRC. + final XLocSet extXLocSet = Converter.xLocListToXLocSet(extXLocList).setVersion(curXLocSet.getVersion()).build(); + + // TODO(jdillmann): Use centralized method to check if a lease is required. + if (extXLocSet.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ) + || extXLocSet.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE) + || extXLocSet.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARA)) { + + // Invalidate the majority of the replicas and get their ReplicaStatus. + int curNumRequiredAcks = calculateNumRequiredAcks(fileId, curXLocSet); + ReplicaStatus[] states = invalidateReplicas(fileId, cap, curXLocSet, curNumRequiredAcks); + + // Calculate the AuthState and determine how many replicas have to be updated. + AuthoritativeReplicaState authState = calculateAuthoritativeState(fileId, curXLocSet, states); + Set replicasUpToDate = calculateReplicasUpToDate(authState); + + // Calculate the number of required updates and send them an update request. + int extNumRequiredAcks = calculateNumRequiredAcks(fileId, extXLocSet); + updateReplicas(fileId, cap, extXLocSet, authState, extNumRequiredAcks, replicasUpToDate); + + } else if (extXLocSet.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)) { + // In case of the read-only replication the replicas will be invalidated. But the coordination takes place + // at the client by libxtreemfs. + // The INVALIDATION request will be send to every replica, but the coordination continues on the first + // response. + invalidateReplicas(fileId, cap, curXLocSet, 1); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "replication policy (%s) will be handled by VolumeImplementation", + extXLocSet.getReplicaUpdatePolicy()); + } + } else { + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "Unknown replica update policy: " + + extXLocSet.getReplicaUpdatePolicy()); + } + + // Call the installXLocSet method in the context of the ProcessingStage. + master.getProcStage().enqueueInternalCallbackOperation(rq, new InternalCallbackInterface() { + @Override + public void execute(MRCRequest rq) throws Throwable { + m.getCallback().installXLocSet(rq, fileId, extXLocList, curXLocList); + } + }); + } + + public RequestMethod removeReplicas(String fileId, + FileMetadata file, XLocList curXLocList, XLocList newXLocList, MRCRequest rq, O op) + throws DatabaseException { + return removeReplicas(fileId, file, curXLocList, newXLocList, rq, op, op); + } + + public RequestMethod removeReplicas(String fileId, FileMetadata file, XLocList curXLocList, XLocList newXLocList, + MRCRequest rq, MRCOperation op, XLocSetCoordinatorCallback callback) throws DatabaseException { + + Capability cap = buildCapability(fileId, file); + RequestMethod m = new RequestMethod(RequestType.REMOVE_REPLICAS, fileId, rq, op, callback, cap, curXLocList, + newXLocList); + + return m; + } + + private void processRemoveReplicas(final RequestMethod m) throws Throwable { + final MRCRequest rq = m.getRequest(); + + final String fileId = m.getFileId(); + final Capability cap = m.getCapability(); + + final XLocList curXLocList = m.getCurXLocList(); + final XLocList newXLocList = m.getNewXLocList(); + + final XLocSet curXLocSet = Converter.xLocListToXLocSet(curXLocList).build(); + // Ensure the next view won't be propagated until it is installed at the MRC. + final XLocSet newXLocSet = Converter.xLocListToXLocSet(newXLocList).setVersion(curXLocSet.getVersion()).build(); + + + if (curXLocSet.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ) + || curXLocSet.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE) + || curXLocSet.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARA)) { + + // Invalidate the majority of the replicas and get their ReplicaStatus + int numRequiredAcks = calculateNumRequiredAcks(fileId, curXLocSet); + ReplicaStatus[] states = invalidateReplicas(fileId, cap, curXLocSet, numRequiredAcks); + + // Calculate the AuthState and determine how many replicas have to be updated. + AuthoritativeReplicaState authState = calculateAuthoritativeState(fileId, curXLocSet, states); + Set replicasUpToDate = calculateReplicasUpToDate(authState); + + // Remove the replicas, that will be removed from the xLocSet, from the set containing up to date replicas. + HashSet newReplicas = new HashSet(); + for (int i = 0; i < newXLocSet.getReplicasCount(); i++) { + String OSDUUID = Helper.getOSDUUIDFromXlocSet(curXLocSet, i, 0); + newReplicas.add(OSDUUID); + } + + Iterator iterator = replicasUpToDate.iterator(); + while (iterator.hasNext()) { + String OSDUUID = iterator.next(); + if (!newReplicas.contains(OSDUUID)) { + iterator.remove(); + } + } + + // Calculate the number of required updates and send them an update request. + int newNumRequiredAcks = calculateNumRequiredAcks(fileId, newXLocSet); + updateReplicas(fileId, cap, newXLocSet, authState, newNumRequiredAcks, replicasUpToDate); + + } else if (curXLocSet.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)) { + // In case of the read-only replication the replicas will be invalidated. But the coordination takes place + // at the client by libxtreemfs. + // The INVALIDATION request will be send to every replica, but the coordination continues on the first + // response. + ReplicaStatus[] states = invalidateReplicas(fileId, cap, curXLocSet, 1); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "replication policy (%s) will be handled by VolumeImplementation", + curXLocSet.getReplicaUpdatePolicy()); + } + } else { + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "Unknown replica update policy: " + + curXLocSet.getReplicaUpdatePolicy()); + } + + // Call the installXLocSet method in the context of the ProcessingStage. + master.getProcStage().enqueueInternalCallbackOperation(rq, new InternalCallbackInterface() { + @Override + public void execute(MRCRequest rq) throws Throwable { + m.getCallback().installXLocSet(rq, fileId, newXLocList, curXLocList); + } + }); + } + + /** + * Lock the xLocSet for a file. The lock should be released, when the coordination succeeded or on crash recovery.
    + * + * Currently the lock is saving the {@link MRCRequestDispatcher#hashCode()} to be able to identify if a previous MRC + * instance crashed while a xLocSet change was in progress. + * + * @param file + * @param sMan + * @param update + * @throws DatabaseException + */ + public void lockXLocSet(FileMetadata file, StorageManager sMan, AtomicDBUpdate update) throws DatabaseException { + byte[] hashValue = new byte[4]; + ByteBuffer hashByte = ByteBuffer.wrap(hashValue).putInt(master.hashCode()); + sMan.setXAttr(file.getId(), StorageManager.SYSTEM_UID, StorageManager.SYS_ATTR_KEY_PREFIX + + XLocSetCoordinator.XLOCSET_CHANGE_ATTR_KEY, hashValue, update); + hashByte.clear(); + } + + /** + * Unlock the xLocSet for a file. This will clear the lock in the database. + * + * @param file + * @param sMan + * @param update + * @throws DatabaseException + */ + public void unlockXLocSet(FileMetadata file, StorageManager sMan, AtomicDBUpdate update) + throws DatabaseException { + sMan.setXAttr(file.getId(), StorageManager.SYSTEM_UID, StorageManager.SYS_ATTR_KEY_PREFIX + + XLocSetCoordinator.XLOCSET_CHANGE_ATTR_KEY, null, update); + } + + /** + * Check if the XLocSet of the file is locked and if the lock was acquired by a previous MRC instance. If this is + * the case, it can be assumed the previous MRC crashed and the {@link XLocSetLock} should be released and replicas + * revalidated. + * + * @param file + * @param sMan + * @return XLocSetLock + * @throws DatabaseException + */ + public XLocSetLock getXLocSetLock(FileMetadata file, StorageManager sMan) throws DatabaseException { + XLocSetLock lock; + + // Check if a hashCode has been saved to to the files XAttr to lock the xLocSet. + byte[] prevHashBytes = sMan.getXAttr(file.getId(), StorageManager.SYSTEM_UID, + StorageManager.SYS_ATTR_KEY_PREFIX + XLocSetCoordinator.XLOCSET_CHANGE_ATTR_KEY); + if (prevHashBytes != null) { + // Check if the saved hashCode differs from the current one. If this is the case, the MRC has crashed. + ByteBuffer prevHashBuffer = ByteBuffer.wrap(prevHashBytes); + int prevHash = prevHashBuffer.getInt(); + prevHashBuffer.clear(); + + if (prevHash != master.hashCode()) { + lock = new XLocSetLock(true, true); + } else { + lock = new XLocSetLock(true, false); + } + } else { + lock = new XLocSetLock(false, false); + } + + return lock; + } + + + /** + * Build a valid Capability for the given file + * + * @param fileId + * @param file + */ + private Capability buildCapability(String fileId, FileMetadata file) { + // Build the Capability + int accessMode = FileAccessManager.O_RDWR; + int validity = master.getConfig().getCapabilityTimeout(); + long expires = TimeSync.getGlobalTime() / 1000 + master.getConfig().getCapabilityTimeout(); + + String clientIdentity; + try { + clientIdentity = master.getConfig().getAddress() != null ? master.getConfig().getAddress().toString() + : InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + clientIdentity = ""; + } + + int epochNo = file.getEpoch(); + boolean replicateOnClose = false; + SnapConfig snapConfig = SnapConfig.SNAP_CONFIG_SNAPS_DISABLED; + long snapTimestamp = 0; + String sharedSecret = master.getConfig().getCapabilitySecret(); + + Capability cap = new Capability(fileId, accessMode, validity, expires, clientIdentity, epochNo, + replicateOnClose, snapConfig, snapTimestamp, sharedSecret); + return cap; + } + + /** + * Invalidate the majority of the replicas listed in xLocList. Will sleep until the lease has timed out if the + * primary didn't respond. + * + * @param fileId + * @param capability + * @param xLocSet + * @param numAcksRequired + * @throws InterruptedException + * @throws MRCException + */ + private ReplicaStatus[] invalidateReplicas(String fileId, Capability cap, XLocSet xLocSet, int numAcksRequired) + throws InterruptedException, MRCException { + + @SuppressWarnings("unchecked") + final RPCResponse[] responses = new RPCResponse[xLocSet + .getReplicasCount()]; + + // Send INVALIDATE requests to every replica in the set. + OSDServiceClient client = master.getOSDClient(); + FileCredentials creds = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLocSet).build(); + for (int i = 0; i < responses.length; i++) { + ServiceUUID OSDServiceUUID = new ServiceUUID(Helper.getOSDUUIDFromXlocSet(xLocSet, i, 0)); + try { + responses[i] = client.xtreemfs_xloc_set_invalidate(OSDServiceUUID.getAddress(), + RPCAuthentication.authNone, + RPCAuthentication.userService, creds, fileId); + } catch (IOException ex) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + } + throw new MRCException(ex); + } + } + + /** + * This local class is used to collect responses to the asynchronous invalidate requests.
    + * It counts the number of errors and successful requests and stores an array of returned ReplicaStatus and a + * flag indicating if the primary did respond. + */ + class InvalidatedResponseListener implements RPCResponseAvailableListener { + private int numResponses = 0; + private int numErrors = 0; + private boolean primaryResponded = false; + private boolean primaryExists = false; + private RPCResponse[] responses; + private ReplicaStatus[] states; + + public InvalidatedResponseListener(RPCResponse[] responses) { + this.responses = responses; + states = new ReplicaStatus[responses.length]; + + for (int i = 0; i < responses.length; i++) { + responses[i].registerListener(this); + } + } + + @Override + synchronized public void responseAvailable(RPCResponse r) { + + // Get the index of the responding OSD. + int osdNum = -1; + for (int i = 0; i < responses.length; i++) { + if (responses[i] == r) { + osdNum = i; + break; + } + } + assert (osdNum > -1); + + try { + xtreemfs_xloc_set_invalidateResponse response = r.get(); + + if (response.hasReplicaStatus()) { + states[osdNum] = response.getReplicaStatus(); + } + + if (response.getLeaseState() == LeaseState.PRIMARY) { + primaryResponded = true; + } else if (response.getLeaseState() == LeaseState.BACKUP) { + primaryExists = true; + } + + numResponses++; + } catch (Exception ex) { + numErrors++; + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "no invalidated response from replica due to exception: %s", ex.toString()); + } finally { + r.freeBuffers(); + this.notifyAll(); + } + } + + synchronized ReplicaStatus[] getReplicaStates() { + ReplicaStatus[] result = new ReplicaStatus[states.length]; + System.arraycopy(states, 0, result, 0, states.length); + return result; + } + } + InvalidatedResponseListener listener = new InvalidatedResponseListener(responses); + + // Wait until the majority responded. + int numMaxErrors = responses.length - numAcksRequired; + synchronized (listener) { + while (listener.numResponses < numAcksRequired) { + listener.wait(); + + if (listener.numErrors > numMaxErrors) { + throw new MRCException( + "XLocSetCoordinator failed because too many replicas didn't respond to the invalidate request."); + } + } + } + + // If a primary exists, wait until either the primary responded, every replica responded or the lease has timed out. + synchronized (listener) { + if (listener.primaryExists) { + long now = System.currentTimeMillis(); + long leaseEndTimeMs = now + leaseToMS; + + while (!listener.primaryResponded + && now < leaseEndTimeMs + && (listener.numResponses + listener.numErrors) < responses.length) { + listener.wait(leaseEndTimeMs - now); + now = System.currentTimeMillis(); + } + } + } + + // Clone the states and return them. + ReplicaStatus[] states = listener.getReplicaStates(); + return states; + } + + /** + * Send update requests to every replica in the xLocSet that is not already up to date. + * + * @param fileId + * @param cap + * @param xLocSet + * @param authState + * @param numAcksRequired + * @param replicasUpToDate + * @throws InterruptedException + * @throws MRCException + */ + private void updateReplicas(String fileId, Capability cap, XLocSet xLocSet, AuthoritativeReplicaState authState, + int numAcksRequired, Set replicasUpToDate) throws InterruptedException, MRCException { + final OSDServiceClient client = master.getOSDClient(); + + // Create a list of OSDs which should be updated. Replicas that are up to date will be filtered. + ArrayList OSDServiceUUIDs = new ArrayList(); + for (int i = 0; i < xLocSet.getReplicasCount(); i++) { + String OSDUUID = Helper.getOSDUUIDFromXlocSet(xLocSet, i, 0); + if (!replicasUpToDate.contains(OSDUUID.toString())) { + OSDServiceUUIDs.add(new ServiceUUID(OSDUUID)); + } + } + + // Build the authState request. + FileCredentials fileCredentials = FileCredentials.newBuilder().setXlocs(xLocSet).setXcap(cap.getXCap()).build(); + xtreemfs_rwr_auth_stateRequest authStateRequest = xtreemfs_rwr_auth_stateRequest.newBuilder() + .setFileId(fileId).setFileCredentials(fileCredentials).setState(authState).build(); + + // Send the request to every replica not up to date yet. + @SuppressWarnings("unchecked") + final RPCResponse[] responses = new RPCResponse[OSDServiceUUIDs.size()]; + for (int i = 0; i < OSDServiceUUIDs.size(); i++) { + try { + final ServiceUUID OSDUUID = OSDServiceUUIDs.get(i); + @SuppressWarnings("unchecked") + final RPCResponse rpcResponse = client.xtreemfs_rwr_auth_state_invalidated( + OSDUUID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, authStateRequest); + responses[i] = rpcResponse; + } catch (IOException ex) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + } + throw new MRCException(ex); + } + } + + /** + * This local class is used to collect responses to the asynchronous update requests.
    + * It counts the number of errors and successful requests. + */ + class FetchInvalidatedResponseListener implements RPCResponseAvailableListener { + private int numResponses = 0; + private int numErrors = 0; + + FetchInvalidatedResponseListener(RPCResponse[] responses) { + for (int i = 0; i < responses.length; i++) { + responses[i].registerListener(this); + } + } + + @Override + synchronized public void responseAvailable(RPCResponse r) { + try { + r.get(); + numResponses++; + } catch (Exception ex) { + numErrors++; + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "no fetchInvalidated response from replica due to exception: %s", ex.toString()); + } finally { + r.freeBuffers(); + this.notifyAll(); + } + } + } + FetchInvalidatedResponseListener listener = new FetchInvalidatedResponseListener(responses); + + + // Wait until the required number of updates has been successfully executed. + int numRequiredUpdates = numAcksRequired - replicasUpToDate.size(); + int numMaxErrors = OSDServiceUUIDs.size() - numRequiredUpdates; + synchronized (listener) { + while (listener.numResponses < numRequiredUpdates) { + listener.wait(); + + if (listener.numErrors > numMaxErrors) { + throw new MRCException( + "XLocSetCoordinator failed because too many replicas didn't respond to the update request."); + } + } + } + } + + + + /** + * Calculate the set of replicas that are up-to-date, which means they have the latest version of every + * object associated to a file. + * + * @param authState + * @return set of replicas that are up-to-date + */ + private Set calculateReplicasUpToDate(AuthoritativeReplicaState authState) { + + HashMap replicaObjCount = new HashMap(); + + int totalObjCount = 0; + for (ObjectVersionMapping ovm : authState.getObjectVersionsList()) { + if (ovm.getOsdUuidsCount() == 0) { + continue; + } + + totalObjCount++; + + for (String OSDUUID : ovm.getOsdUuidsList()) { + Integer c = replicaObjCount.get(OSDUUID); + c = (c == null) ? 1 : c + 1; + replicaObjCount.put(OSDUUID, c); + } + } + + Iterator> iter = replicaObjCount.entrySet().iterator(); + while (iter.hasNext()) { + final Entry e = iter.next(); + if (e.getValue() < totalObjCount) { + iter.remove(); + } + } + + return replicaObjCount.keySet(); + } + + /** + * Calculate the AuthoritativeReplicaState from the ReplicaStatus returned by the INVALIDATE operation. + * + * @param fileId + * @param xLocSet + * @param states + * @return + */ + private AuthoritativeReplicaState calculateAuthoritativeState(String fileId, XLocSet xLocSet, ReplicaStatus[] states) { + // Generate a list of ServiceUUIDs from the XLocSet. + int i; + List OSDUUIDs = new ArrayList(xLocSet.getReplicasCount() - 1); + for (i = 0; i < xLocSet.getReplicasCount() - 1; i++) { + // Add each head OSDUUID to the list. + OSDUUIDs.add(i, new ServiceUUID(Helper.getOSDUUIDFromXlocSet(xLocSet, i, 0))); + } + // Save the last OSD as the localUUID. + String localUUID = Helper.getOSDUUIDFromXlocSet(xLocSet, i, 0); + + // Calculate an return the AuthoritativeReplicaState. + return CoordinatedReplicaUpdatePolicy.CalculateAuthoritativeState(states, fileId, localUUID, OSDUUIDs); + } + + /** + * Calculate the number of required ACKS that are constituting a majority. + * + * @param fileId + * @param xLocSet + * @return + */ + private int calculateNumRequiredAcks(String fileId, XLocSet xLocSet) { + /* + * Essentially it is required to get ACKs from a majority for WqRq replicated files, + * but for WaR1 it is required to + * - wait until every OSD is up to date in case of the addition of a replica + * - and to wait for the invalidation/installation of the view on the removed OSD and one other. + * + * But at the moment every read/write policy is depending on a majority due to the lease mechanism, + * which results in an issue as seen at https://github.com/xtreemfs/xtreemfs/issues/235 but allows + * for simpler handling of ACKs for view coordination. + */ + + int numRequiredAcks = xLocSet.getReplicasCount() / 2 + 1; + return numRequiredAcks; + } + + /** + * Add the RequestMethod saved as context in the local queue when the update operation completes.
    + * Attention the context of the DB operation calling this, has to be a {@link RequestMethod}. + */ + @Override + public void finished(Object result, Object context) { + if (!(context instanceof RequestMethod)) { + throw new RuntimeException( + "The XLocSetCoordinator DBAccessResultListener has to be called with a RequestMethod as the context."); + } + + RequestMethod m = (RequestMethod) context; + q.add(m); + } + + @Override + public void failed(Throwable error, Object context) { + if (!(context instanceof RequestMethod)) { + throw new RuntimeException( + "The XLocSetCoordinator DBAccessResultListener has to be called with a RequestMethod as the context."); + } + + RequestMethod m = (RequestMethod) context; + master.failed(error, m.getRequest()); + } + + // TODO(jdillmann): Share error reporting between ProcessingStage.parseAndExecure and this + private void handleError(RequestMethod m, Throwable err) { + MRCOperation op = m.getOperation(); + MRCRequest rq = m.getRequest(); + try { + // simply rethrow the exception + throw err; + + } catch (UserException exc) { + reportUserError(op, rq, exc, exc.getErrno()); + + } catch (MRCException exc) { + Throwable cause = exc.getCause(); + if (cause instanceof DatabaseException + && ((DatabaseException) cause).getType() == ExceptionType.NOT_ALLOWED) + reportUserError(op, rq, exc, POSIXErrno.POSIX_ERROR_EPERM); + else + reportServerError(op, rq, exc); + + } catch (DatabaseException exc) { + if (exc.getType() == ExceptionType.NOT_ALLOWED) { + reportUserError(op, rq, exc, POSIXErrno.POSIX_ERROR_EPERM); + } else if (exc.getType() == ExceptionType.REDIRECT) { + try { + redirect(rq, + exc.getAttachment() != null ? (String) exc.getAttachment() : master.getReplMasterUUID()); + } catch (MRCException e) { + reportServerError(op, rq, e); + } + } else + reportServerError(op, rq, exc); + + } catch (Throwable exc) { + reportServerError(op, rq, exc); + } + } + + private void reportUserError(MRCOperation op, MRCRequest rq, Throwable exc, POSIXErrno errno) { + if (Logging.isDebug()) + Logging.logUserError(Logging.LEVEL_DEBUG, Category.proc, this, exc); + op.finishRequest(rq, new ErrorRecord(ErrorType.ERRNO, errno, exc.getMessage(), exc)); + } + + private void reportServerError(MRCOperation op, MRCRequest rq, Throwable exc) { + if (Logging.isDebug()) + Logging.logUserError(Logging.LEVEL_DEBUG, Category.proc, this, exc); + op.finishRequest(rq, new ErrorRecord(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_NONE, + "An error has occurred at the MRC. Details: " + exc.getMessage(), exc)); + } + + private void redirect(MRCRequest rq, String uuid) { + rq.getRPCRequest().sendRedirect(uuid); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/stages/XLocSetCoordinatorCallback.java b/java/servers/src/org/xtreemfs/mrc/stages/XLocSetCoordinatorCallback.java new file mode 100644 index 0000000..3b68f76 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/stages/XLocSetCoordinatorCallback.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2013 by Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.mrc.stages; + +import org.xtreemfs.mrc.MRCRequest; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.operations.AddReplicaOperation; + +/** + * This callback will be executed, when the {@link XLocSetCoordinator} ensured the data is updated on a sufficient + * number of replicas and the new xLocList can be installed without inconsistencies.
    + * The callback is intended to be implemented by an operation such as {@link AddReplicaOperation}. + */ +public interface XLocSetCoordinatorCallback { + public void installXLocSet(MRCRequest rq, String fileId, XLocList newXLocList, XLocList prevXLocList) + throws Throwable; +} diff --git a/java/servers/src/org/xtreemfs/mrc/stages/XLocSetLock.java b/java/servers/src/org/xtreemfs/mrc/stages/XLocSetLock.java new file mode 100644 index 0000000..659a67f --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/stages/XLocSetLock.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013 by Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.mrc.stages; + +/** + * Concurrent changes to a files' xLocSet, will be prevented by a lock stored in the database (see also + * {@link XLocSetCoordinator#lockXLocSet}). If the MRC failed while a xLocSet change was in progress, a crash recovery + * routine has to be started to revalidate replicas.
    + * This class is a simple wrapper to hold the information if a xLocSet is locked and if the lock has been acquired by + * the current instance or if it is a leftover from a previously crashed one. + */ +public class XLocSetLock { + + final boolean locked; + final boolean crashed; + + public XLocSetLock(boolean locked, boolean crashed) { + this.locked = locked; + this.crashed = crashed; + } + + public boolean isLocked() { + return locked; + } + + public boolean hasCrashed() { + return crashed; + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/templates/status.html b/java/servers/src/org/xtreemfs/mrc/templates/status.html new file mode 100644 index 0000000..2f2e77e --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/templates/status.html @@ -0,0 +1,148 @@ + + + XtreemFS MRC @ <!-- $UUID --> + + + + +

    MRC

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Version +
    XtreemFSMRC
    RPC Interface
    Database
    + Configuration +
    TCP & UDP port
    Directory Service
    Debug Level
    + Load +
    # client connections
    # pending client requests
    Processing Stage queue length
    + Requests +
    + Volumes +
    + VM Info / Memory +
    Java VM stats (free/max/total)
    Buffer Pool stats
    + Time +
    global XtreeemFS time
    resync interval for global time ms
    local system time
    local time update interval ms
    + Detailed Status +
    + BabuDB state
    + Full stack trace (all threads)
     
    + UUID Mapping Cache +
    + + \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/mrc/utils/Converter.java b/java/servers/src/org/xtreemfs/mrc/utils/Converter.java new file mode 100644 index 0000000..42b067a --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/utils/Converter.java @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.utils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.StringTokenizer; + +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.foundation.json.JSONException; +import org.xtreemfs.foundation.json.JSONParser; +import org.xtreemfs.foundation.json.JSONString; +import org.xtreemfs.mrc.ac.FileAccessPolicy; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.metadata.ACLEntry; +import org.xtreemfs.mrc.metadata.ReplicationPolicy; +import org.xtreemfs.mrc.metadata.StripingPolicy; +import org.xtreemfs.mrc.metadata.XAttr; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.osdselection.OSDStatusManager; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; + +/** + * Contains static methods for converting Java objects to JSON-compliant data + * structures and vice versa. + * + * @author stender + * + */ +public class Converter { + + /** + * Converts an ACLEntry iterator to a mapping: userID:String -> + * rights:Long. + * + * @param acl + * @return + */ + public static Map aclToMap(Iterator acl, FileAccessPolicy policy) { + + if (acl == null) + return null; + + Map aclMap = new HashMap(); + while (acl.hasNext()) { + ACLEntry next = acl.next(); + aclMap.put(next.getEntity(), policy.translatePermissions(next.getRights())); + } + + return aclMap; + } + + /** + * Converts a mapping: userID:String -> rights:Long to an + * ACLEntry array sorted by userID. + * + * @param aclMap + * @return + */ + public static ACLEntry[] mapToACL(StorageManager sMan, long fileId, Map aclMap) { + + if (aclMap == null) + return null; + + ACLEntry[] acl = new ACLEntry[aclMap.size()]; + Iterator> entries = aclMap.entrySet().iterator(); + for (int i = 0; i < acl.length; i++) { + assert (entries.hasNext()); + Entry entry = entries.next(); + acl[i] = sMan.createACLEntry(fileId, entry.getKey(), ((Long) entry.getValue()).shortValue()); + } + + Arrays.sort(acl, new Comparator() { + public int compare(ACLEntry o1, ACLEntry o2) { + return o1.getEntity().compareTo(o2.getEntity()); + } + }); + + return acl; + } + + /** + * Converts an XLocList to a String + * + * @param xLocList + * the XLocList + * @return the string representation of the XLocList + */ + public static String xLocListToString(XLocList xLocList) { + + StringBuilder sb = new StringBuilder(); + sb.append("["); + for (int i = 0; i < xLocList.getReplicaCount(); i++) { + sb.append("[<"); + XLoc repl = xLocList.getReplica(i); + StripingPolicy sp = repl.getStripingPolicy(); + + sb.append(stripingPolicyToString(sp)).append(">, ("); + for (int j = 0; j < repl.getOSDCount(); j++) + sb.append(repl.getOSD(j)).append(j == repl.getOSDCount() - 1 ? "" : ", "); + sb.append(")]").append(i == xLocList.getReplicaCount() - 1 ? "" : ", "); + } + sb.append(", ").append(xLocList.getVersion()).append(", ").append(xLocList.getReplUpdatePolicy()) + .append("]"); + + return sb.toString(); + } + + public static String xLocListToJSON(XLocList xLocList, OSDStatusManager osdMan) throws JSONException, + UnknownUUIDException { + + Map list = new HashMap(); + list.put("update-policy", xLocList.getReplUpdatePolicy()); + list.put("version", Long.valueOf(xLocList.getVersion())); + List> replicas = new ArrayList(xLocList.getReplicaCount()); + Iterator iter = xLocList.iterator(); + while (iter.hasNext()) { + XLoc l = iter.next(); + Map replica = new HashMap(); + replica.put("striping-policy", getStripingPolicyAsJSON(l.getStripingPolicy())); + replica.put("replication-flags", l.getReplicationFlags()); + List> osds = new ArrayList(l.getOSDCount()); + for (int i = 0; i < l.getOSDCount(); i++) { + Map osd = new HashMap(); + final ServiceUUID uuid = new ServiceUUID(l.getOSD(i)); + final Service osdData = osdMan.getOSDService(uuid.toString()); + final String coords = osdData == null ? "" : KeyValuePairs.getValue(osdData.getData() + .getDataList(), "vivaldi_coordinates"); + osd.put("uuid", uuid.toString()); + osd.put("vivaldi_coordinates", coords); + osd.put("address", uuid.getAddressString()); + osds.add(osd); + } + replica.put("osds", osds); + replicas.add(replica); + } + list.put("replicas", replicas); + + return JSONParser.writeJSON(list); + } + + // public static void main(String[] args) { + // BufferBackedStripingPolicy sp = new BufferBackedStripingPolicy("RAID0", + // 256, 2); + // BufferBackedXLoc repl1 = new BufferBackedXLoc(sp, new String[] { "osd1", + // "osd2" }, 0); + // BufferBackedXLoc repl2 = new BufferBackedXLoc(sp, new String[] { "osd4" + // }, 0); + // XLocList xLocList = new BufferBackedXLocList(new BufferBackedXLoc[] { + // repl1, repl2 }, "policy", 3); + // + // System.out.println(xLocListToString(xLocList)); + // } + + /** + * Converts an XLocSet to an XLocList + * + * @param sMan + * the storage manager + * @param xLocSet + * the XLocSet + * @return the XLocList + */ + public static XLocList xLocSetToXLocList(StorageManager sMan, XLocSet.Builder xLocSet) { + + XLoc[] replicas = new XLoc[xLocSet.getReplicasCount()]; + for (int i = 0; i < xLocSet.getReplicasCount(); i++) { + + Replica repl = xLocSet.getReplicas(i); + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy sp = repl.getStripingPolicy(); + + replicas[i] = sMan.createXLoc(sMan.createStripingPolicy(sp.getType().toString(), sp + .getStripeSize(), sp.getWidth()), repl.getOsdUuidsList().toArray( + new String[repl.getOsdUuidsList().size()]), repl.getReplicationFlags()); + } + + return sMan.createXLocList(replicas, xLocSet.getReplicaUpdatePolicy(), xLocSet.getVersion()); + } + + /** + * Converts an XLocList to an XLocSet + * + * @param xLocList + * the XLocList + * @return the xLocSet + */ + public static XLocSet.Builder xLocListToXLocSet(XLocList xLocList) { + + if (xLocList == null) + return null; + + XLocSet.Builder xLocSetBuilder = XLocSet.newBuilder().setReplicaUpdatePolicy( + xLocList.getReplUpdatePolicy()).setVersion(xLocList.getVersion()).setReadOnlyFileSize(0); + + for (int i = 0; i < xLocList.getReplicaCount(); i++) { + + XLoc xRepl = xLocList.getReplica(i); + StripingPolicy xSP = xRepl.getStripingPolicy(); + + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder sp = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy + .newBuilder().setType(StripingPolicyType.valueOf(xSP.getPattern())).setStripeSize( + xSP.getStripeSize()).setWidth(xSP.getWidth()); + + Replica.Builder replBuilder = Replica.newBuilder().setReplicationFlags( + xRepl.getReplicationFlags()).setStripingPolicy(sp); + for (int j = 0; j < xRepl.getOSDCount(); j++) + replBuilder.addOsdUuids(xRepl.getOSD(j)); + + xLocSetBuilder.addReplicas(replBuilder); + } + + return xLocSetBuilder; + } + + /** + * Converts a string containing striping policy information to a + * StripingPolicy object. + * + * @param sMan + * the storage manager + * @param spString + * the striping policy string + * @return the striping policy + */ + public static StripingPolicy stringToStripingPolicy(StorageManager sMan, String spString) { + + StringTokenizer st = new StringTokenizer(spString, " ,\t"); + String policy = st.nextToken(); + if (policy.equals("RAID0")) + policy = StripingPolicyType.STRIPING_POLICY_RAID0.toString(); + + int size = Integer.parseInt(st.nextToken()); + int width = Integer.parseInt(st.nextToken()); + + return sMan.createStripingPolicy(policy, size, width); + } + + /** + * Converts a string containing striping policy information to a + * StripingPolicy object. + * + * @param sMan + * the storage manager + * @param spString + * the striping policy string + * @return the striping policy + */ + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy jsonStringToStripingPolicy( + String spString) throws JSONException { + + Map spMap = (Map) JSONParser.parseJSON(new JSONString(spString)); + + if (spMap == null || spMap.isEmpty()) + return null; + + String pattern = (String) spMap.get("pattern"); + long size = (Long) spMap.get("size"); + long width = (Long) spMap.get("width"); + + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.newBuilder().setType( + StripingPolicyType.valueOf(pattern)).setStripeSize((int) size).setWidth((int) width).build(); + } + + /** + * Converts a striping policy object to a string. + * + * @param sp + * the striping policy object + * @return a string containing the striping policy information + */ + public static String stripingPolicyToString(StripingPolicy sp) { + return sp.getPattern() + ", " + sp.getStripeSize() + ", " + sp.getWidth(); + } + + /** + * Converts a striping policy object to a string. + * + * @param sp + * the striping policy object + * @return a string containing the striping policy information + */ + public static String stripingPolicyToString( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy sp) { + return sp.getType().toString() + ", " + sp.getStripeSize() + ", " + sp.getWidth(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder stripingPolicyToStripingPolicy( + StripingPolicy sp) { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.newBuilder().setType( + StripingPolicyType.valueOf(sp.getPattern())).setStripeSize(sp.getStripeSize()).setWidth( + sp.getWidth()); + } + + public static String stripingPolicyToJSONString(StripingPolicy sp) throws JSONException { + return JSONParser.writeJSON(getStripingPolicyAsJSON(sp)); + } + + static Replica.Builder replicaFromJSON(String value) throws JSONException { + Map jsonObj = (Map) JSONParser.parseJSON(new JSONString(value)); + long rf = (Long) jsonObj.get("replication-flags"); + Map jsonSP = (Map) jsonObj.get("striping-policy"); + final String spName = (String) jsonSP.get("pattern"); + StripingPolicyType spType = StripingPolicyType.STRIPING_POLICY_RAID0; + final long width = (Long) jsonSP.get("width"); + final long size = (Long) jsonSP.get("size"); + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder sp = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy + .newBuilder().setType(spType).setStripeSize((int) size).setWidth((int) width); + + List osds = (List) jsonObj.get("osds"); + + Replica.Builder builder = Replica.newBuilder(); + for (String osd : osds) + builder.addOsdUuids(osd); + return builder; + } + + private static Map getStripingPolicyAsJSON(StripingPolicy sp) { + Map spMap = new HashMap(); + spMap.put("pattern", sp.getPattern()); + spMap.put("size", sp.getStripeSize()); + spMap.put("width", sp.getWidth()); + return spMap; + } + + /** + * Converts a String array to a list of Strings. + * + * @param array + * @return + */ + public static List stringArrayToList(String[] array) { + + if (array == null) + return null; + + List list = new ArrayList(array.length); + + for (String s : array) + list.add(s); + + return list; + } + + /** + * Converts a list of FileAttributeEntitys to a list containing + * maps storing file attribute information. + * + * @param mappedData + * @return + */ + public static List attrMapsToAttrList(StorageManager sMan, long fileId, + List> mappedData) { + + List list = new LinkedList(); + for (Map attr : mappedData) + list.add(sMan.createXAttr(fileId, (String) attr.get("userId"), (String) attr.get("key"), + (byte[]) attr.get("value"))); + + return list; + } + + public static short[] stringToShortArray(String shortList) { + + StringTokenizer st = new StringTokenizer(shortList, " \t,;"); + short[] result = new short[st.countTokens()]; + + for (int i = 0; st.hasMoreTokens(); i++) + result[i] = Short.parseShort(st.nextToken()); + + return result; + } + + public static String shortArrayToString(short[] shorts) { + + String result = ""; + for (int i = 0; i < shorts.length; i++) { + result += shorts[i]; + if (i < shorts.length - 1) + result += ","; + } + + return result; + } + + /** + * Converts a replication policy object to a string. + * + * @param rp + * the replication policy object + * @return a string containing the replication policy information + */ + public static String replicationPolicyToString(ReplicationPolicy rp) { + return rp.getName() + ", " + rp.getFactor() + ", " + rp.getFlags(); + } + + /** + * Converts a string containing replication policy information to a + * ReplicationPolicy object. + * + * @param sMan + * the storage manager + * @param rpString + * the replication policy string + * @return the replication policy + */ + public static ReplicationPolicy stringToReplicationPolicy(StorageManager sMan, String rpString) { + + StringTokenizer st = new StringTokenizer(rpString, " ,\t"); + + final String policy = rpString.startsWith(",")? "": st.nextToken(); + final int numRepls = Integer.parseInt(st.nextToken()); + final int flags = Integer.parseInt(st.nextToken()); + + return new ReplicationPolicy() { + + @Override + public String getName() { + return policy; + } + + @Override + public int getFactor() { + return numRepls; + } + + @Override + public int getFlags() { + return flags; + } + + }; + } + + /** + * Converts a string containing replication policy information to a + * ReplicationPolicy object. + * + * @param rpString + * the replication policy string + * @return the replication policy + */ + public static ReplicationPolicy jsonStringToReplicationPolicy(String rpString) throws JSONException { + + Map rpMap = (Map) JSONParser.parseJSON(new JSONString(rpString)); + + if (rpMap == null || rpMap.isEmpty()) + return null; + + final String name = (String) rpMap.get("update-policy"); + if (name == null) + return null; + + Long factor = (Long) rpMap.get("replication-factor"); + final int numRepls = factor == null ? 1 : factor.intValue(); + + Long flags = (Long) rpMap.get("replication-flags"); + final int replFlags = flags == null ? 0 : flags.intValue(); + + return new ReplicationPolicy() { + + @Override + public String getName() { + return name; + } + + @Override + public int getFactor() { + return numRepls; + } + + @Override + public int getFlags() { + return replFlags; + } + + }; + } + + public static String replicationPolicyToJSONString(ReplicationPolicy rp) throws JSONException { + return JSONParser.writeJSON(getReplicationPolicyAsJSON(rp)); + } + + private static Map getReplicationPolicyAsJSON(ReplicationPolicy rp) { + Map rpMap = new HashMap(); + rpMap.put("update-policy", rp.getName()); + rpMap.put("replication-factor", rp.getFactor()); + rpMap.put("replication-flags", rp.getFlags()); + return rpMap; + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/utils/DBAdminHelper.java b/java/servers/src/org/xtreemfs/mrc/utils/DBAdminHelper.java new file mode 100644 index 0000000..73eae5f --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/utils/DBAdminHelper.java @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.utils; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.xml.sax.Attributes; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.foundation.json.JSONException; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.MRCException; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.ACLEntry; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.StripingPolicy; +import org.xtreemfs.mrc.metadata.XAttr; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; + +public class DBAdminHelper { + + public static class DBRestoreState { + + public String currentVolumeId; + + public String currentVolumeName; + + public short currentVolumeACPolicy; + + public List parentIds; + + public FileMetadata currentEntity; + + public int currentXLocVersion; + + public String currentReplUpdatePolicy; + + public StripingPolicy currentXLocSp; + + public List currentReplicaList; + + public int currentReplFlags; + + public List currentOSDList; + + public Map currentACL; + + public long largestFileId; + + public long currentVolumeQuota; + + public DBRestoreState() { + parentIds = new LinkedList(); + parentIds.add((long) 0); + currentOSDList = new LinkedList(); + currentReplicaList = new LinkedList(); + currentACL = new HashMap(); + } + + } + + public static void restoreDir(VolumeManager vMan, FileAccessManager faMan, Attributes attrs, DBRestoreState state, + int dbVersion, boolean openTag) throws DatabaseException, UserException { + + if (openTag) { + + long id = Long.parseLong(attrs.getValue(attrs.getIndex("id"))); + String name = OutputUtils.unescapeFromXML(attrs.getValue(attrs.getIndex("name"))); + String owner = attrs.getValue(attrs.getIndex("uid")); + String owningGroup = attrs.getValue(attrs.getIndex("gid")); + int atime = Integer.parseInt(attrs.getValue(attrs.getIndex("atime"))); + int ctime = Integer.parseInt(attrs.getValue(attrs.getIndex("ctime"))); + int mtime = Integer.parseInt(attrs.getValue(attrs.getIndex("mtime"))); + + short rights = 511; // set all rights to 511 by default + if (attrs.getIndex("rights") != -1) + rights = Short.parseShort(attrs.getValue(attrs.getIndex("rights"))); + + long w32Attrs = 0; // set all Win32 attributes to 0 by default + if (attrs.getIndex("w32Attrs") != -1) + w32Attrs = Long.parseLong(attrs.getValue(attrs.getIndex("w32Attrs"))); + + // if the directory is the root directory, restore the volume + if (id == 1) { + vMan.createVolume(faMan, state.currentVolumeId, state.currentVolumeName, state.currentVolumeACPolicy, + owner, owningGroup, null, rights, state.currentVolumeQuota, new LinkedList()); + + StorageManager sMan = vMan.getStorageManager(state.currentVolumeId); + state.currentEntity = sMan.getMetadata(1); + } + + // otherwise, restore the directory + else { + + // there must not be hard links to directories, so it is not + // necessary to check if the directory exists already + + StorageManager sMan = vMan.getStorageManager(state.currentVolumeId); + AtomicDBUpdate update = sMan.createAtomicDBUpdate(null, null); + FileMetadata dir = sMan.createDir(id, state.parentIds.get(0), name, atime, ctime, mtime, owner, + owningGroup, rights, w32Attrs, update); + update.execute(); + state.currentEntity = dir; + } + + state.parentIds.add(0, id); + + if (state.currentEntity.getId() > state.largestFileId) + state.largestFileId = state.currentEntity.getId(); + } + + else + state.parentIds.remove(0); + } + + public static void restoreFile(VolumeManager vMan, FileAccessManager faMan, Attributes attrs, DBRestoreState state, + int dbVersion, boolean openTag) throws DatabaseException, UserException { + + if (!openTag) + return; + + long id = Long.parseLong(attrs.getValue(attrs.getIndex("id"))); + String name = OutputUtils.unescapeFromXML(attrs.getValue(attrs.getIndex("name"))); + + StorageManager sMan = vMan.getStorageManager(state.currentVolumeId); + + FileMetadata file = sMan.getMetadata(id); + + // First, check whether a file with the same ID already exists. This is + // necessary, since files may be linked to multiple directories. + if (file == null) { + + String owner = attrs.getValue(attrs.getIndex("uid")); + String owningGroup = attrs.getValue(attrs.getIndex("gid")); + int atime = Integer.parseInt(attrs.getValue(attrs.getIndex("atime"))); + int ctime = Integer.parseInt(attrs.getValue(attrs.getIndex("ctime"))); + int mtime = Integer.parseInt(attrs.getValue(attrs.getIndex("mtime"))); + long size = Long.parseLong(attrs.getValue(attrs.getIndex("size"))); + + int epoch = 0; // set the epoch to 0 by default + if (attrs.getIndex("epoch") != -1) + epoch = Integer.parseInt(attrs.getValue(attrs.getIndex("epoch"))); + + int issuedEpoch = 0; // set the issued epoch to 0 by default + if (attrs.getIndex("issuedEpoch") != -1) + epoch = Integer.parseInt(attrs.getValue(attrs.getIndex("issuedEpoch"))); + + int rights = 511; // set all rights to 511 by default + if (attrs.getIndex("rights") != -1) + rights = Integer.parseInt(attrs.getValue(attrs.getIndex("rights"))); + + long w32Attrs = 0; // set all Win32 attributes to 0 by default + if (attrs.getIndex("w32Attrs") != -1) + w32Attrs = Long.parseLong(attrs.getValue(attrs.getIndex("w32Attrs"))); + + boolean readOnly = false; // set readOnly attribute to false by + // default + if (attrs.getIndex("readOnly") != -1) + readOnly = Boolean.getBoolean(attrs.getValue(attrs.getIndex("readOnly"))); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(null, null); + file = sMan.createFile(id, state.parentIds.get(0), name, atime, ctime, mtime, owner, owningGroup, rights, + w32Attrs, size, readOnly, epoch, issuedEpoch, update); + update.execute(); + } + + // otherwise, create a link + else { + AtomicDBUpdate update = sMan.createAtomicDBUpdate(null, null); + sMan.link(file, state.parentIds.get(0), name, update); + update.execute(); + } + + state.currentEntity = file; + + if (state.currentEntity.getId() > state.largestFileId) + state.largestFileId = state.currentEntity.getId(); + } + + public static void restoreXLocList(VolumeManager vMan, FileAccessManager faMan, Attributes attrs, + DBRestoreState state, int dbVersion, boolean openTag) throws DatabaseException, UserException { + + StorageManager sMan = vMan.getStorageManager(state.currentVolumeId); + + if (openTag) { + state.currentXLocVersion = Integer.parseInt(attrs.getValue(attrs.getIndex("version"))); + if (attrs.getIndex("ruPolicy") != -1) + state.currentReplUpdatePolicy = attrs.getValue(attrs.getIndex("ruPolicy")); + else + state.currentReplUpdatePolicy = ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE; + } + + else { + + state.currentEntity.setXLocList(sMan.createXLocList( + state.currentReplicaList.toArray(new XLoc[state.currentReplicaList.size()]), + state.currentReplUpdatePolicy, state.currentXLocVersion)); + state.currentReplicaList.clear(); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(null, null); + sMan.setMetadata(state.currentEntity, FileMetadata.RC_METADATA, update); + update.execute(); + } + } + + public static void restoreXLoc(VolumeManager vMan, FileAccessManager faMan, Attributes attrs, DBRestoreState state, + int dbVersion, boolean openTag) throws DatabaseException, UserException { + + StorageManager sMan = vMan.getStorageManager(state.currentVolumeId); + + if (openTag) { + state.currentXLocSp = Converter.stringToStripingPolicy(sMan, attrs.getValue(attrs.getIndex("pattern"))); + state.currentReplFlags = attrs.getIndex("replFlags") == -1 ? 0 : Integer.parseInt(attrs.getValue(attrs + .getIndex("replFlags"))); + + } else { + + state.currentReplicaList.add(sMan.createXLoc(state.currentXLocSp, + state.currentOSDList.toArray(new String[state.currentOSDList.size()]), state.currentReplFlags)); + state.currentOSDList.clear(); + } + } + + public static void restoreOSD(VolumeManager vMan, FileAccessManager faMan, Attributes attrs, DBRestoreState state, + int dbVersion, boolean openTag) throws DatabaseException { + + if (openTag) + state.currentOSDList.add(attrs.getValue(attrs.getIndex("location"))); + } + + public static void restoreACL(VolumeManager vMan, FileAccessManager faMan, Attributes attrs, DBRestoreState state, + int dbVersion, boolean openTag) throws DatabaseException, UserException { + + // convert old ACLs to POSIX access rights + if (!openTag) { + + StorageManager sMan = vMan.getStorageManager(state.currentVolumeId); + AtomicDBUpdate update = sMan.createAtomicDBUpdate(null, null); + try { + faMan.updateACLEntries(sMan, state.currentEntity, state.parentIds.get(0), state.currentACL, update); + } catch (MRCException e) { + throw new DatabaseException(e); + } catch (UserException e) { + throw new DatabaseException(e); + } + + update.execute(); + state.currentACL.clear(); + } + } + + public static void restoreEntry(VolumeManager vMan, FileAccessManager faMan, Attributes attrs, + DBRestoreState state, int dbVersion, boolean openTag) throws DatabaseException { + + if (openTag) { + + String entityId = attrs.getValue(attrs.getIndex("entity")); + if (dbVersion < 3 && entityId.contains("::")) + entityId = entityId.replace("::", ":"); + + short rights = (short) Long.parseLong(attrs.getValue(attrs.getIndex("rights"))); + state.currentACL.put(entityId, rights); + } + } + + public static void restoreAttr(VolumeManager vMan, FileAccessManager faMan, Attributes attrs, DBRestoreState state, + int dbVersion, boolean openTag) throws DatabaseException, UserException { + + if (openTag) { + + int encIndex = attrs.getIndex("enc"); + boolean base64 = encIndex != -1 && "BASE64".equals(attrs.getValue(encIndex)); + + int oIndex = attrs.getIndex("owner"); + String owner = oIndex == -1 ? "" : attrs.getValue(oIndex); + + String key = OutputUtils.unescapeFromXML(attrs.getValue(attrs.getIndex("key"))); + String valueEncoded = attrs.getValue(attrs.getIndex("value")); + + try { + byte[] value = base64 ? OutputUtils.decodeBase64(valueEncoded) : OutputUtils.unescapeFromXML( + valueEncoded).getBytes(); + + StorageManager sMan = vMan.getStorageManager(state.currentVolumeId); + + // if the value refers to a read-only flag, set it directly + if (key.equals("ro")) { + + String valueString = new String(value); + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(null, null); + state.currentEntity.setReadOnly(Boolean.getBoolean(valueString)); + update.execute(); + } + + else { + + if (owner.isEmpty() && key.equals("ref")) + key = "lt"; + + if (owner.isEmpty() && key.equals("spol")) + key = "sp"; + + AtomicDBUpdate update = sMan.createAtomicDBUpdate(null, null); + sMan.setXAttr(state.currentEntity.getId(), owner, key, value, update); + update.execute(); + } + + } catch (IOException exc) { + throw new DatabaseException( + "BASE64 decoding of extended attribute value '" + valueEncoded + "' failed", exc); + } + } + } + + /** + * Creates an XML dump from a volume. The dump contains all files and directories of the volume, including + * their attributes and ACLs. + * + * @param xmlWriter + * the XML writer creating the dump + * @param sMan + * the volume's storage manager + * @throws IOException + * if an I/O error occurs + * @throws DatabaseException + * if an error occurs while accessing the database + */ + public static void dumpVolume(BufferedWriter xmlWriter, StorageManager sMan) throws IOException, DatabaseException { + try { + dumpDir(xmlWriter, sMan, 1); + } catch (JSONException exc) { + throw new DatabaseException(exc); + } + } + + private static void dumpDir(BufferedWriter xmlWriter, StorageManager sMan, long parentId) throws DatabaseException, + IOException, JSONException { + + FileMetadata parent = sMan.getMetadata(parentId); + + // serialize the parent directory + xmlWriter.write("\n"); + + // serialize the root directory's ACL + dumpACL(xmlWriter, sMan.getACL(parentId)); + + // serialize the root directory's attributes + dumpAttrs(xmlWriter, sMan.getXAttrs(parentId)); + + // serialize all nested elements + DatabaseResultSet children = sMan.getChildren(parentId, 0, Integer.MAX_VALUE); + while (children.hasNext()) { + + FileMetadata child = children.next(); + + if (child.isDirectory()) + dumpDir(xmlWriter, sMan, child.getId()); + else + dumpFile(xmlWriter, sMan, child); + } + children.destroy(); + + xmlWriter.write("\n"); + } + + private static void dumpFile(BufferedWriter xmlWriter, StorageManager sMan, FileMetadata file) + throws DatabaseException, IOException, JSONException { + + // serialize the file + xmlWriter.write("\n"); + + // serialize the file's xLoc list + XLocList xloc = file.getXLocList(); + if (xloc != null) { + xmlWriter.write("\n"); + for (int i = 0; i < xloc.getReplicaCount(); i++) { + XLoc repl = xloc.getReplica(i); + xmlWriter.write("\n"); + for (int j = 0; j < repl.getOSDCount(); j++) + xmlWriter.write("\n"); + xmlWriter.write("\n"); + } + xmlWriter.write("\n"); + } + + // serialize the file's ACL + dumpACL(xmlWriter, sMan.getACL(file.getId())); + + // serialize the file's attributes + dumpAttrs(xmlWriter, sMan.getXAttrs(file.getId())); + + xmlWriter.write("\n"); + } + + private static void dumpAttrs(BufferedWriter xmlWriter, DatabaseResultSet attrs) throws IOException { + + if (attrs.hasNext()) { + xmlWriter.write("\n"); + + while (attrs.hasNext()) { + + XAttr attr = attrs.next(); + String key = attr.getKey(); + byte[] value = attr.getValue(); + + xmlWriter.write("\n"); + } + xmlWriter.write("\n"); + } + + attrs.destroy(); + } + + private static void dumpACL(BufferedWriter xmlWriter, DatabaseResultSet acl) throws IOException { + + if (acl.hasNext()) { + xmlWriter.write("\n"); + while (acl.hasNext()) { + ACLEntry entry = acl.next(); + xmlWriter.write("\n"); + } + xmlWriter.write("\n"); + } + + acl.destroy(); + } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/utils/MRCHelper.java b/java/servers/src/org/xtreemfs/mrc/utils/MRCHelper.java new file mode 100644 index 0000000..ef49cfa --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/utils/MRCHelper.java @@ -0,0 +1,917 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.utils; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.json.JSONException; +import org.xtreemfs.foundation.json.JSONParser; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.mrc.MRCConfig; +import org.xtreemfs.mrc.MRCException; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.database.VolumeInfo; +import org.xtreemfs.mrc.database.VolumeManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.ReplicationPolicy; +import org.xtreemfs.mrc.metadata.StripingPolicy; +import org.xtreemfs.mrc.metadata.XAttr; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.mrc.metadata.XLocList; +import org.xtreemfs.mrc.osdselection.OSDStatusManager; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +public class MRCHelper { + + public static class GlobalFileIdResolver { + + final String volumeId; + + final long localFileId; + + public GlobalFileIdResolver(String globalFileId) throws UserException { + + try { + int i = globalFileId.indexOf(':'); + volumeId = globalFileId.substring(0, i); + localFileId = Long.parseLong(globalFileId.substring(i + 1)); + } catch (Exception exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid global file ID: " + globalFileId + + "; expected pattern: :"); + } + } + + public String getVolumeId() { + return volumeId; + } + + public long getLocalFileId() { + return localFileId; + } + } + + /** + * Create a global fileId for the file on the volume. + * + * @param volume + * @param file + * @return Global fileId + */ + public static String createGlobalFileId(VolumeInfo volume, FileMetadata file) { + return volume.getId() + ":" + file.getId(); + } + + public static final String POLICY_ATTR_PREFIX = "policies"; + + public static final String VOL_ATTR_PREFIX = "volattr"; + + public static final String XTREEMFS_POLICY_ATTR_PREFIX = "xtreemfs." + POLICY_ATTR_PREFIX + "."; + + public enum SysAttrs { + locations, + file_id, + object_type, + url, + owner, + group, + default_sp, + ac_policy_id, + rsel_policy, + osel_policy, + usable_osds, + free_space, + used_space, + num_files, + num_dirs, + snapshots, + snapshots_enabled, + snapshot_time, + acl, + read_only, + mark_replica_complete, + set_repl_update_policy, + default_rp, + quota + } + + public enum FileType { + nexists, dir, file + } + + public static Service createDSVolumeInfo(VolumeInfo vol, OSDStatusManager osdMan, StorageManager sMan, + String mrcUUID) { + + String free = String.valueOf(osdMan.getFreeSpace(vol.getId())); + String volSize = null; + try { + volSize = String.valueOf(sMan.getVolumeInfo().getVolumeSize()); + try { + // Use minimum of free space relative to the quota and free space on osds as free disk space. + long quota = vol.getVolumeQuota(); + long quotaFreeSpace = quota - vol.getVolumeSize(); + if (quota != 0 && quotaFreeSpace < Long.valueOf(free)) { + quotaFreeSpace = quotaFreeSpace < 0 ? 0 : quotaFreeSpace; + free = String.valueOf(quotaFreeSpace); + } + } catch (DatabaseException e) { + Logging.logMessage(Logging.LEVEL_WARN, Category.storage, null, + "could not retrieve volume quota from database for volume '%s': %s", + new Object[] { vol.getName(), e.toString() }); + } + } catch (DatabaseException e) { + Logging.logMessage(Logging.LEVEL_WARN, Category.storage, null, + "could not retrieve volume size from database for volume '%s': %s", + new Object[] { vol.getName(), e.toString() }); + } + + ServiceDataMap.Builder dmap = buildServiceDataMap("mrc", mrcUUID, "free", free, "used", volSize); + + try { + + DatabaseResultSet attrIt = sMan.getXAttrs(1, StorageManager.SYSTEM_UID); + while (attrIt.hasNext()) { + XAttr attr = attrIt.next(); + if (attr.getKey().startsWith("xtreemfs.volattr.")) { + byte[] value = attr.getValue(); + dmap.addData(KeyValuePair.newBuilder() + .setKey("attr." + attr.getKey().substring("xtreemfs.volattr.".length())) + .setValue(value == null ? null : new String(value))); + } + } + attrIt.destroy(); + + } catch (DatabaseException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, null, OutputUtils.stackTraceToString(e), + new Object[0]); + } + + Service sreg = Service.newBuilder().setType(ServiceType.SERVICE_TYPE_VOLUME).setUuid(vol.getId()).setVersion(0) + .setName(vol.getName()).setData(dmap).setLastUpdatedS(0).build(); + + return sreg; + } + + public static int updateFileTimes(long parentId, FileMetadata file, boolean setATime, boolean setCTime, + boolean setMTime, StorageManager sMan, int currentTime, AtomicDBUpdate update) throws DatabaseException { + + if (parentId == -1) + return -1; + + if (setATime) + file.setAtime(currentTime); + if (setCTime) + file.setCtime(currentTime); + if (setMTime) + file.setMtime(currentTime); + + sMan.setMetadata(file, FileMetadata.FC_METADATA, update); + + return currentTime; + } + + public static XLoc createReplica(StripingPolicy stripingPolicy, StorageManager sMan, OSDStatusManager osdMan, + VolumeInfo volume, long parentDirId, String path, InetAddress clientAddress, + VivaldiCoordinates clientCoordinates, XLocList currentXLoc, int replFlags) throws DatabaseException, + UserException, MRCException { + + // if no striping policy is provided, try to retrieve it from the parent + // directory + if (stripingPolicy == null) + stripingPolicy = sMan.getDefaultStripingPolicy(parentDirId); + + // if the parent directory has no default policy, take the one + // associated with the volume + if (stripingPolicy == null) + stripingPolicy = sMan.getDefaultStripingPolicy(1); + + if (stripingPolicy == null) + throw new UserException(POSIXErrno.POSIX_ERROR_EIO, "could not open file " + path + + ": no default striping policy available"); + + // determine the set of OSDs to be assigned to the replica + ServiceSet.Builder usableOSDs = osdMan.getUsableOSDs(volume.getId(), clientAddress, clientCoordinates, + currentXLoc, stripingPolicy.getWidth()); + + if (usableOSDs == null || usableOSDs.getServicesCount() == 0) { + + Logging.logMessage(Logging.LEVEL_WARN, Category.all, (Object) null, + "no suitable OSDs available for file %s", path); + + throw new UserException(POSIXErrno.POSIX_ERROR_EIO, "could not assign OSDs to file " + path + + ": no feasible OSDs available"); + } + + // determine the actual striping width; if not enough OSDs are + // available, the width will be limited to the amount of available OSDs + int width = Math.min(stripingPolicy.getWidth(), usableOSDs.getServicesCount()); + + // convert the set of OSDs to a string array of OSD UUIDs + List osdServices = usableOSDs.getServicesList(); + String[] osds = new String[width]; + for (int i = 0; i < width; i++) + osds[i] = osdServices.get(i).getUuid(); + + if (width != stripingPolicy.getWidth()) + stripingPolicy = sMan.createStripingPolicy(stripingPolicy.getPattern(), stripingPolicy.getStripeSize(), + width); + + return sMan.createXLoc(stripingPolicy, osds, replFlags); + } + + /** + * Checks whether the given replica (i.e. list of OSDs) can be added to the + * given X-Locations list without compromising consistency. + * + * @param xLocList + * the X-Locations list + * @param newOSDs + * the list of new OSDs to add + * @return true, if adding the OSD list is possible, false + * , otherwise + */ + public static boolean isAddable(XLocList xLocList, List newOSDs) { + if (xLocList != null) + for (int i = 0; i < xLocList.getReplicaCount(); i++) { + XLoc replica = xLocList.getReplica(i); + for (int j = 0; j < replica.getOSDCount(); j++) + for (String newOsd : newOSDs) + if (replica.getOSD(j).equals(newOsd)) + return false; + } + + return true; + } + + /** + * Checks whether all service UUIDs from the list can be resolved, i.e. + * refer to valid services. + * + * @param newOSDs + * the list of OSDs + * @return true, if all OSDs are resolvable, false, + * otherwise + */ + public static boolean isResolvable(List newOSDs) { + if (newOSDs != null) + for (String osd : newOSDs) { + try { + new ServiceUUID(osd).getAddress(); + } catch (Exception exc) { + return false; + } + } + + return true; + } + + /** + * Checks whether the given X-Locations list is consistent. It is regarded + * as consistent if no OSD in any replica occurs more than once. + * + * @param xLocList + * the X-Locations list to check for consistency + * @return true, if the list is consistent, false, + * otherwise + */ + public static boolean isConsistent(XLocList xLocList) { + Set tmp = new HashSet(); + if (xLocList != null) { + for (int i = 0; i < xLocList.getReplicaCount(); i++) { + XLoc replica = xLocList.getReplica(i); + for (int j = 0; j < replica.getOSDCount(); j++) { + String osd = replica.getOSD(j); + if (!tmp.contains(osd)) + tmp.add(osd); + else + return false; + } + } + } + + return true; + } + + public static String getSysAttrValue(MRCConfig config, StorageManager sMan, OSDStatusManager osdMan, + FileAccessManager faMan, String path, FileMetadata file, String keyString) throws DatabaseException, + UserException, JSONException { + + if (keyString.startsWith(POLICY_ATTR_PREFIX + ".")) + return getPolicyValue(sMan, keyString); + + if (keyString.startsWith(VOL_ATTR_PREFIX + ".")) + return getVolAttrValue(sMan, keyString); + + SysAttrs key = null; + try { + key = SysAttrs.valueOf(keyString); + } catch (IllegalArgumentException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "unknown system attribute '" + keyString + "'"); + } + + if (key != null) { + + switch (key) { + + case locations: + if (file.isDirectory()) { + return ""; + } else { + XLocList xLocList = file.getXLocList(); + + try { + return xLocList == null ? "" : Converter.xLocListToJSON(xLocList, osdMan); + } catch (UnknownUUIDException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EIO, "cannot retrieve '" + + SysAttrs.locations.name() + "' attribute value: " + exc); + } + } + case file_id: + return createGlobalFileId(sMan.getVolumeInfo(), file); + case object_type: + String ref = sMan.getSoftlinkTarget(file.getId()); + return ref != null ? "3" : file.isDirectory() ? "2" : "1"; + case url: + InetSocketAddress addr = config.getDirectoryService(); + return config.getURLScheme() + "://" + addr.getHostName() + ":" + addr.getPort() + "/" + path; + case owner: + return file.getOwnerId(); + case group: + return file.getOwningGroupId(); + case default_sp: + if (!file.isDirectory()) + return ""; + StripingPolicy sp = sMan.getDefaultStripingPolicy(file.getId()); + if (sp == null) + return ""; + return Converter.stripingPolicyToJSONString(sp); + case ac_policy_id: + return file.getId() == 1 ? sMan.getVolumeInfo().getAcPolicyId() + "" : ""; + case osel_policy: + return file.getId() == 1 ? Converter.shortArrayToString(sMan.getVolumeInfo().getOsdPolicy()) : ""; + case rsel_policy: + return file.getId() == 1 ? Converter.shortArrayToString(sMan.getVolumeInfo().getReplicaPolicy()) : ""; + case read_only: + if (file.isDirectory()) + return ""; + + return String.valueOf(file.isReadOnly()); + + case usable_osds: { + + // only return a value for the volume root + if (file.getId() != 1) + return ""; + + try { + ServiceSet.Builder srvs = osdMan.getUsableOSDs(sMan.getVolumeInfo().getId()); + Map osds = new HashMap(); + for (Service srv : srvs.getServicesList()) { + ServiceUUID uuid = new ServiceUUID(srv.getUuid()); + osds.put(uuid.toString(), uuid.getAddressString()); + } + return JSONParser.writeJSON(osds); + + } catch (UnknownUUIDException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EIO, "cannot retrieve '" + + SysAttrs.usable_osds.name() + "' attribute value: " + exc); + } + } + case free_space: + return file.getId() == 1 ? String.valueOf(osdMan.getFreeSpace(sMan.getVolumeInfo().getId())) : ""; + case used_space: + return file.getId() == 1 ? String.valueOf(sMan.getVolumeInfo().getVolumeSize()) : ""; + case num_files: + return file.getId() == 1 ? String.valueOf(sMan.getVolumeInfo().getNumFiles()) : ""; + case num_dirs: + return file.getId() == 1 ? String.valueOf(sMan.getVolumeInfo().getNumDirs()) : ""; + + case snapshots: { + + if (file.getId() != 1 || sMan.getVolumeInfo().isSnapVolume()) + return ""; + + String[] snaps = sMan.getAllSnapshots(); + Arrays.sort(snaps); + List snapshots = new ArrayList(snaps.length); + for (String snap : snaps) { + if (snap.equals(".dump")) + continue; + + snapshots.add(snap); + } + + return JSONParser.writeJSON(snapshots); + } + + case snapshots_enabled: + return file.getId() == 1 && !sMan.getVolumeInfo().isSnapVolume() ? String.valueOf(sMan.getVolumeInfo() + .isSnapshotsEnabled()) : ""; + case snapshot_time: + return file.getId() == 1 && sMan.getVolumeInfo().isSnapVolume() ? Long.toString(sMan.getVolumeInfo() + .getCreationTime()) : ""; + + case acl: + + Map acl; + try { + acl = faMan.getACLEntries(sMan, file); + } catch (MRCException e) { + Logging.logError(Logging.LEVEL_ERROR, null, e); + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL); + } + + if (acl != null) { + + Map map = new HashMap(); + for (Entry entry : acl.entrySet()) + map.put(entry.getKey(), "" + entry.getValue()); + + return JSONParser.writeJSON(map); + } + + case default_rp: + + if (!file.isDirectory()) + return ""; + ReplicationPolicy rp = sMan.getDefaultReplicationPolicy(file.getId()); + if (rp == null) + return ""; + + return Converter.replicationPolicyToJSONString(rp); + + case quota: + return String.valueOf(sMan.getVolumeInfo().getVolumeQuota()); + } + } + + return ""; + } + + public static void setSysAttrValue(StorageManager sMan, VolumeManager vMan, FileAccessManager faMan, long parentId, + FileMetadata file, String keyString, String value, AtomicDBUpdate update) throws UserException, + DatabaseException { + + // handle policy-specific values + if (keyString.startsWith(POLICY_ATTR_PREFIX.toString() + ".")) { + setPolicyValue(sMan, keyString, value, update); + return; + } + + SysAttrs key = null; + try { + key = SysAttrs.valueOf(keyString); + } catch (IllegalArgumentException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "unknown system attribute '" + keyString + "'"); + } + + switch (key) { + + case default_sp: + + if (!file.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, + "default striping policies can only be set on volumes and directories"); + + try { + + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy sp = null; + sp = Converter.jsonStringToStripingPolicy(value); + + if (file.getId() == 1 && sp == null) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, + "cannot remove the volume's default striping policy"); + + // check if striping + rw replication would be set + ReplicationPolicy replPolicy = sMan.getDefaultReplicationPolicy(file.getId()); + if (sp != null + && sp.getWidth() > 1 + && replPolicy != null && (replPolicy.getName().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE) || replPolicy + .getName().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ))) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "Striping of rw-replicated Files is not supported yet."); + } + + sMan.setDefaultStripingPolicy(file.getId(), sp, update); + + } catch (JSONException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid default striping policy: " + value); + } catch (ClassCastException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid default striping policy: " + value); + } catch (NullPointerException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid default striping policy: " + value); + } catch (IllegalArgumentException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid default striping policy: " + value); + } + + break; + + case osel_policy: + + if (file.getId() != 1) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "OSD selection policies can only be set on volumes"); + + try { + short[] newPol = Converter.stringToShortArray(value); + sMan.getVolumeInfo().setOsdPolicy(newPol, update); + + } catch (NumberFormatException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid OSD selection policy: " + value); + } + + break; + + case rsel_policy: + + if (file.getId() != 1) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "replica selection policies can only be set and configured on volumes"); + + try { + short[] newPol = Converter.stringToShortArray(value); + sMan.getVolumeInfo().setReplicaPolicy(newPol, update); + + } catch (NumberFormatException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid replica selection policy: " + value); + } + + break; + + case read_only: + + // TODO: unify w/ 'set_repl_update_policy' + + if (file.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, "only files can be made read-only"); + + boolean readOnly = Boolean.valueOf(value); + + if (!readOnly && file.getXLocList() != null && file.getXLocList().getReplicaCount() > 1) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, + "read-only flag cannot be removed from files with multiple replicas"); + + // set the update policy string in the X-Locations list to 'read + // only replication' and mark the first replica as 'full' + if (file.getXLocList() != null) { + XLocList xLoc = file.getXLocList(); + XLoc[] replicas = new XLoc[xLoc.getReplicaCount()]; + for (int i = 0; i < replicas.length; i++) + replicas[i] = xLoc.getReplica(i); + + replicas[0].setReplicationFlags(ReplicationFlags.setFullReplica(ReplicationFlags + .setReplicaIsComplete(replicas[0].getReplicationFlags()))); + + XLocList newXLoc = sMan.createXLocList(replicas, readOnly ? ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY + : ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE, xLoc.getVersion() + 1); + file.setXLocList(newXLoc); + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + } + + // set the read-only flag + file.setReadOnly(readOnly); + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + break; + + case snapshots: + + if (!file.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOTDIR, + "snapshots of single files are not allowed so far"); + + // value format: "c|cr|d| name" + + // TODO: restrict to admin users + + int index = value.indexOf(" "); + + String command = null; + String name = null; + try { + command = value.substring(0, index); + name = value.substring(index + 1); + } catch (Exception exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "malformed snapshot configuration"); + } + + // create snapshot + if (command.charAt(0) == 'c') + vMan.createSnapshot(sMan.getVolumeInfo().getId(), name, parentId, file, command.equals("cr")); + + // delete snapshot + else if (command.equals("d")) + vMan.deleteSnapshot(sMan.getVolumeInfo().getId(), file, name); + + else + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid snapshot command: " + value); + + break; + + case snapshots_enabled: + + if (file.getId() != 1) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "snapshots can only be enabled or disabled on volumes"); + + boolean enable = Boolean.parseBoolean(value); + sMan.getVolumeInfo().setAllowSnaps(enable, update); + + break; + + case mark_replica_complete: + + if (file.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_EISDIR, "file required"); + + XLocList xlocs = file.getXLocList(); + XLoc[] xlocArray = new XLoc[xlocs.getReplicaCount()]; + Iterator it = xlocs.iterator(); + for (int i = 0; it.hasNext(); i++) { + XLoc xloc = it.next(); + if (value.equals(xloc.getOSD(0))) + xloc.setReplicationFlags(ReplicationFlags.setReplicaIsComplete(xloc.getReplicationFlags())); + xlocArray[i] = xloc; + } + XLocList newXLocList = sMan.createXLocList(xlocArray, xlocs.getReplUpdatePolicy(), xlocs.getVersion()); + file.setXLocList(newXLocList); + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + break; + + case acl: + + // parse the modification command + index = value.indexOf(" "); + try { + command = value.substring(0, index); + String params = value.substring(index + 1); + + // modify an ACL entry + if (command.equals("m")) { + + int index2 = params.lastIndexOf(':'); + + String entity = params.substring(0, index2); + String rights = params.substring(index2 + 1); + + Map entries = new HashMap(); + entries.put(entity, rights); + faMan.updateACLEntries(sMan, file, parentId, entries, update); + } + + // remove an ACL entry + else if (command.equals("x")) { + List entries = new ArrayList(1); + entries.add(params); + faMan.removeACLEntries(sMan, file, parentId, entries, update); + + } else + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid ACL modification command: " + + command); + + } catch (MRCException e) { + Logging.logError(Logging.LEVEL_ERROR, null, e); + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL); + } catch (Exception exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "malformed ACL modification request"); + } + + break; + + case set_repl_update_policy: + + if (file.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_EISDIR, "file required"); + + xlocs = file.getXLocList(); + xlocArray = new XLoc[xlocs.getReplicaCount()]; + it = xlocs.iterator(); + for (int i = 0; it.hasNext(); i++) + xlocArray[i] = it.next(); + + String replUpdatePolicy = xlocs.getReplUpdatePolicy(); + + // Check allowed policies. + if (!ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ.equals(value) + && !ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE.equals(value) + && !ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE.equals(value) + && !ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY.equals(value)) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "Invalid replica update policy: " + value); + + // WaRa was renamed to WaR1. + if (ReplicaUpdatePolicies.REPL_UPDATE_PC_WARA.equals(value)) { + throw new UserException( + POSIXErrno.POSIX_ERROR_EINVAL, + "Do no longer use the policy WaRa. Instead you're probably looking for the WaR1 policy (write all replicas, read from one)." + + value); + } + + if (ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY.equals(replUpdatePolicy) && xlocArray.length > 1) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "changing replica update policies of read-only-replicated files is not allowed"); + + if (ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE.equals(value)) { + // if there are more than one replica, report an error + if (xlocs.getReplicaCount() > 1) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "number of replicas has to be reduced to 1 before replica update policy can be set to " + + ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE + " (current replica count = " + + xlocs.getReplicaCount() + ")"); + } + + // Do not allow to switch between read-only and read/write replication + // as there are currently no mechanisms in place to guarantee that the replicas are synchronized. + if ((ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY.equals(replUpdatePolicy) + && (ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ.equals(value) + || ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE.equals(value))) + || + (ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY.equals(value) + && (ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ.equals(replUpdatePolicy) + || ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE.equals(replUpdatePolicy)))) { + throw new UserException( + POSIXErrno.POSIX_ERROR_EINVAL, + "Currently, it is not possible to change from a read-only to a read/write replication policy or vise versa."); + } + + // Update replication policy in new xloc list. + newXLocList = sMan.createXLocList(xlocArray, value, xlocs.getVersion() + 1); + + // mark the first replica in the list as 'complete' (only relevant + // for read-only replication) + if (ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY.equals(value)) { + newXLocList.getReplica(0).setReplicationFlags( + ReplicationFlags.setFullReplica(ReplicationFlags.setReplicaIsComplete(newXLocList.getReplica(0) + .getReplicationFlags()))); + file.setReadOnly(true); + } + + // check if striping + rw replication would be set + StripingPolicy stripingPolicy = file.getXLocList().getReplica(0).getStripingPolicy(); + if (stripingPolicy.getWidth() > 1 + && (value.equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE) || value + .equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ))) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "RW-replication of striped files is not supported yet."); + } + + // Remove read only state of file if readonly policy gets reverted. + if (ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY.equals(replUpdatePolicy) + && ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE.equals(value)) { + file.setReadOnly(false); + } + + // Write back updated file data. + file.setXLocList(newXLocList); + sMan.setMetadata(file, FileMetadata.RC_METADATA, update); + + break; + + case default_rp: + + if (!file.isDirectory()) + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, + "default replication policies can only be set on volumes and directories"); + + try { + + ReplicationPolicy rp = null; + rp = Converter.jsonStringToReplicationPolicy(value); + + if (rp.getFactor() == 1 && !ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE.equals(rp.getName())) { + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, + "a default replication policy requires a replication factor >= 2"); + } + + // check if rw replication + striping would be set + if (sMan.getDefaultStripingPolicy(file.getId()).getWidth() > 1 + && (rp.getName().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE) || rp.getName().equals( + ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ))) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, + "RW-replication of striped files is not supported yet."); + } + + sMan.setDefaultReplicationPolicy(file.getId(), rp, update); + + } catch (JSONException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid default replication policy: " + value); + } catch (ClassCastException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid default replication policy: " + value); + } catch (NullPointerException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid default replication policy: " + value); + } catch (IllegalArgumentException exc) { + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "invalid default replication policy: " + value); + } + + break; + + case quota: + if (file.getId() != 1) + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "quota must be set on volume root"); + + sMan.getVolumeInfo().setVolumeQuota((long) Long.valueOf(value), update); + + break; + + default: + throw new UserException(POSIXErrno.POSIX_ERROR_EINVAL, "system attribute '" + keyString + "' is immutable"); + } + } + + public static List getSpecialAttrNames(StorageManager sMan, String namePrefix) throws DatabaseException { + + final String prefix = "xtreemfs." + namePrefix; + final List result = new LinkedList(); + + DatabaseResultSet it = sMan.getXAttrs(1, StorageManager.SYSTEM_UID); + while (it.hasNext()) { + XAttr attr = it.next(); + if (attr.getKey().startsWith(prefix)) + result.add(attr.getKey()); + } + it.destroy(); + + return result; + } + + public static ServiceDataMap.Builder buildServiceDataMap(String... kvPairs) { + + assert (kvPairs.length % 2 == 0); + + ServiceDataMap.Builder builder = ServiceDataMap.newBuilder(); + for (int i = 0; i < kvPairs.length; i += 2) { + KeyValuePair.Builder kvp = KeyValuePair.newBuilder(); + kvp.setKey(kvPairs[i]); + kvp.setValue(kvPairs[i + 1]); + builder.addData(kvp); + } + + return builder; + } + + private static String getPolicyValue(StorageManager sMan, String keyString) throws DatabaseException { + byte[] value = sMan.getXAttr(1, StorageManager.SYSTEM_UID, "xtreemfs." + keyString); + return value == null ? null : new String(value); + } + + private static String getVolAttrValue(StorageManager sMan, String keyString) throws DatabaseException { + byte[] value = sMan.getXAttr(1, StorageManager.SYSTEM_UID, "xtreemfs." + keyString); + return value == null ? null : new String(value); + } + + private static void setPolicyValue(StorageManager sMan, String keyString, String value, AtomicDBUpdate update) + throws DatabaseException, UserException { + + // remove "policies." + String checkString = keyString.substring(POLICY_ATTR_PREFIX.length()+1); + int index = checkString.indexOf('.'); + + if (index <= 0) { + // remove trailing "." + if (keyString.startsWith(".")) { + keyString = keyString.substring(1); + } + throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, + "'"+keyString+"="+value+" :' " + + "XtreemFS no longer supports global policy attributes. " + + "It is necessary to specify a policy e.g., '1000."+keyString+"="+value+"'"); + } + + // set the value in the database + byte[] bytes = value.getBytes(); + sMan.setXAttr(1, StorageManager.SYSTEM_UID, "xtreemfs." + keyString, bytes == null || bytes.length == 0 ? null + : bytes, update); + } +} diff --git a/java/servers/src/org/xtreemfs/mrc/utils/Path.java b/java/servers/src/org/xtreemfs/mrc/utils/Path.java new file mode 100644 index 0000000..6ecb719 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/utils/Path.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.utils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Parses a path separated by '/' into multiple components. + * + * @author stender + * + */ +public class Path { + + private static final char SEPARATOR = '/'; + + private String path; + + private List compIndices; + + + public Path(String volumeName, String path) { + if ((path.length() > 0) && (path.charAt(0) == '/')) { + parsePath(volumeName+path); + } else { + parsePath(volumeName+"/"+path); + } + } + + public Path(String path) { + parsePath(path); + } + + private void parsePath(String path) { + if (path.length() == 0) { + this.path = ""; + this.compIndices = new ArrayList(15); + compIndices.add(-1); + } else { + + while(path.contains("//")) { + path = path.replace("//", "/"); + } + + this.path = path.charAt(path.length() - 1) == SEPARATOR ? path.substring(0, + path.length() - 1) : path; + this.compIndices = new ArrayList(15); + compIndices.add(-1); + + char[] chars = this.path.toCharArray(); + for (int i = 0; i < chars.length; i++) + if (chars[i] == SEPARATOR) + compIndices.add(i); + } + } + + public Path(String[] comps) { + + this.compIndices = new ArrayList(15); + + StringBuilder sb = new StringBuilder(); + int index = 0; + + for(String comp: comps) { + compIndices.add(index); + index += comp.length() + 1; + sb.append("/"+ comp); + } + + path = sb.toString(); + } + + public String getComp(int index) { + + if (index >= compIndices.size()) + return null; + + return path.substring(compIndices.get(index) + 1, index == compIndices.size() - 1 ? path + .length() : compIndices.get(index + 1)); + + } + + public String getLastComp(int index) { + + if (index >= compIndices.size()) + return null; + + return path.substring(compIndices.get(compIndices.size() - 1 - index) + 1, + index == 0 ? path.length() : compIndices.get(compIndices.size() - index)); + } + + public String getComps(int startIndex, int endIndex) { + + if (endIndex < startIndex) + return ""; + + if (startIndex >= compIndices.size()) + startIndex = compIndices.size() - 1; + + if (endIndex < 0) + endIndex = 0; + + return path.substring(compIndices.get(startIndex) + 1, + endIndex == compIndices.size() - 1 ? path.length() : compIndices.get(endIndex + 1)); + + } + + public boolean equals(Path p) { + return path.equals(p.path); + } + + public int getCompCount() { + return compIndices.size(); + } + + public boolean isSubDirOf(Path p) { + return path.startsWith(p.path + "/"); + } + + public String toString() { + return path; + } + +// public static void main(String[] args) { +// Path path = new Path("myVolume/test/blub/bla.txt"); +// System.out.println(path); +// System.out.println(path.getComp(0)); +// System.out.println(path.getLastComp(0)); +// System.out.println(path.getComp(1)); +// System.out.println(path.getLastComp(1)); +// System.out.println(path.getComps(1, 2)); +// System.out.println(path.getComp(path.getCompCount())); +// System.out.println(path.getLastComp(path.getCompCount())); +// System.out.println(path.getComps(0, 0)); +// System.out.println(path.getComps(1, 1)); +// System.out.println(path.getComps(2, 2)); +// System.out.println(path.getComps(3, 3)); +// System.out.println(path.getComps(5, -1)); +// System.out.println(path.getCompCount()); +// } + +} diff --git a/java/servers/src/org/xtreemfs/mrc/utils/PathResolver.java b/java/servers/src/org/xtreemfs/mrc/utils/PathResolver.java new file mode 100644 index 0000000..d3ccc32 --- /dev/null +++ b/java/servers/src/org/xtreemfs/mrc/utils/PathResolver.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.mrc.utils; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.database.DatabaseException; +import org.xtreemfs.mrc.database.StorageManager; +import org.xtreemfs.mrc.metadata.FileMetadata; + +/** + * Provides convenience methods for accessing a path to a file, and resolves + * frequently-needed pieces of metadata, such as the parent directory of the + * file described by the given path. This functionality is needed by most + * XtreemFS operations. + * + * @author stender + * + */ +public class PathResolver { + + private String fileName; + + private String parentDirName; + + private final Path path; + + private final FileMetadata[] resolvedPath; + + /** + * Creates a new resolver for the given path. + * + * @param sMan + * @param path + * @throws DatabaseException + */ + public PathResolver(StorageManager sMan, Path path) throws DatabaseException, UserException { + + this.path = path; + this.resolvedPath = sMan.resolvePath(path); + + // check if the resolved path prefix exists + if (resolvedPath.length > 1 && resolvedPath[resolvedPath.length - 2] == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "path '" + path + "' does not exist"); + } + + public PathResolver(Path path, FileMetadata... files) { + this.path = path; + this.resolvedPath = files; + } + + public String getFileName() { + if (fileName == null) + fileName = path.getLastComp(0); + return fileName; + } + + public FileMetadata getFile() throws DatabaseException { + return resolvedPath[resolvedPath.length - 1]; + } + + public void checkIfFileExistsAlready() throws DatabaseException, UserException { + if (getFile() != null) + throw new UserException(POSIXErrno.POSIX_ERROR_EEXIST, "file or directory '" + path + + "' exists already"); + } + + public void checkIfFileDoesNotExist() throws DatabaseException, UserException { + if (getFile() == null) + throw new UserException(POSIXErrno.POSIX_ERROR_ENOENT, "file or directory '" + path + + "' does not exist"); + } + + public String getParentDirName() { + if (parentDirName == null) + parentDirName = path.getCompCount() == 1 ? "" : path.getLastComp(1); + return parentDirName; + } + + public long getParentDirId() throws DatabaseException { + return resolvedPath.length == 1 ? 0 : resolvedPath[resolvedPath.length - 2].getId(); + } + + public FileMetadata getParentDir() throws DatabaseException { + return resolvedPath.length == 1 ? null : resolvedPath[resolvedPath.length - 2]; + } + + public long getParentsParentId() throws DatabaseException { + return resolvedPath.length == 1 ? -1 : resolvedPath.length == 2 ? 0 + : resolvedPath[resolvedPath.length - 3].getId(); + } + + public FileMetadata[] getResolvedPath() { + return resolvedPath; + } + + public String toString() { + return path.toString(); + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/AdvisoryLock.java b/java/servers/src/org/xtreemfs/osd/AdvisoryLock.java new file mode 100644 index 0000000..c971511 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/AdvisoryLock.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + +/** + * + * @author bjko + */ +public class AdvisoryLock { + + /** Representation of the end of file for the *length* of the locked range, + * given by fcntl(). */ + public static final long LENGTH_LOCK_TO_EOF = 0; + + /** This object's representation of the end of file for the lockEnd value + * (*offset*) of the locked range. */ + public static final long END_LOCK_TO_EOF = -1; + + private final boolean exclusive; + + private final long lockStart; + + private final long lockEnd; + + private final String clientUuid; + + private final int clientPid; + + public AdvisoryLock(long start, long len, boolean exclusive, String clientUuid, int clientPid) { + this.exclusive = exclusive; + this.lockStart = start; + if (len == LENGTH_LOCK_TO_EOF) { + this.lockEnd = END_LOCK_TO_EOF; + } else { + long end = lockStart+len-1; + if (end < 0) + end = 0; + lockEnd = end; + } + this.clientPid = clientPid; + this.clientUuid = clientUuid; + } + + public boolean isOverlappingRanges(final AdvisoryLock other) { + + if (this.lockEnd == END_LOCK_TO_EOF) { + return (other.lockEnd >= this.lockStart) || (other.lockEnd == END_LOCK_TO_EOF); + } + if (other.lockEnd == END_LOCK_TO_EOF) { + return (this.lockEnd >= other.lockStart) || (this.lockEnd == END_LOCK_TO_EOF); + } + if ( (this.lockEnd < other.lockStart) + || (this.lockStart > other.lockEnd) ) { + return false; + } else { + return true; + } + } + + public boolean isConflicting(AdvisoryLock other) { + if (isOverlappingRanges(other)) { + return (this.exclusive || other.exclusive); + } else { + return false; + } + } + + /** + * @return the clientUuid + */ + public String getClientUuid() { + return clientUuid; + } + + /** + * @return the clientPid + */ + public int getClientPid() { + return clientPid; + } + + public long getOffset() { + return lockStart; + } + + public long getLength() { + if (lockEnd == END_LOCK_TO_EOF) + return LENGTH_LOCK_TO_EOF; + return lockEnd-lockStart+1; + } + + public boolean isExclusive() { + return exclusive; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/ErrorCodes.java b/java/servers/src/org/xtreemfs/osd/ErrorCodes.java new file mode 100644 index 0000000..af52871 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/ErrorCodes.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + + +public final class ErrorCodes { + + /** + * the fileID is malformed or contains invalid characters + */ + public static final int INVALID_FILEID = 1; + + /** + * a header field is malformed or contains invalid values + */ + public static final int INVALID_HEADER = 2; + + /** + * the RPC request data is not valid + */ + public static final int INVALID_RPC = 3; + + /** + * HTTP or RPC method is not implemented + */ + public static final int METHOD_NOT_IMPLEMENTED = 4; + + /** + * the parameter count or type does not match for an RPC. + */ + public static final int INVALID_PARAMS = 5; + + /** + * this error code indicates that the server needs the full XLocation list + * instead of the XLocation version number only. + */ + public static final int NEED_FULL_XLOC = 10; + + /** + * the XLocation list sent by the client is outdated and not accepted. + */ + public static final int XLOC_OUTDATED = 11; + + /** + * this server is not part of the XLocation list. + */ + public static final int NOT_IN_XLOC = 12; + + /** + * authentication failed. + */ + public static final int AUTH_FAILED = 13; + + /** + * checksum of an object turned out to be invalid + */ + public static final int INVALID_CHECKSUM = 20; + + /** + * the client is not the owner of the lease. + */ + public static final int NOT_LEASE_OWNER = 30; + + /** + * The lease has timed out (i.e. the timeout sent in the X-Lease-Timeout + * header has passed). + */ + public static final int LEASE_TIMED_OUT = 31; + + public static final int NO_REPLICA_AVAIL = 50; + + public static final int EPOCH_OUTDATED = 14; + + public static final int FILE_IS_READ_ONLY = 15; + + /** + * + */ + public static final int IO_ERROR = 16; +} diff --git a/java/servers/src/org/xtreemfs/osd/InternalObjectData.java b/java/servers/src/org/xtreemfs/osd/InternalObjectData.java new file mode 100644 index 0000000..38f1343 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/InternalObjectData.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; + +/** + * Class as a replacement for old ObjectData which is now split into ObjectData message and data sent via RPC channel (data) + * @author bjko + */ +public class InternalObjectData { + + ReusableBuffer data; + ObjectData metadata; + + public InternalObjectData(ObjectData metadata, ReusableBuffer data) { + this.metadata = metadata; + this.data = data; + } + + public InternalObjectData( int checksum, boolean invalid_checksum_on_osd, int zero_padding, ReusableBuffer data ) { + metadata = ObjectData.newBuilder().setChecksum(checksum).setInvalidChecksumOnOsd(invalid_checksum_on_osd).setZeroPadding(zero_padding).build(); + this.data = data; + } + + public ReusableBuffer getData() { + return data; + } + + public int getChecksum() { return metadata.getChecksum(); } + public boolean getInvalid_checksum_on_osd() { return metadata.getInvalidChecksumOnOsd(); } + public int getZero_padding() { return metadata.getZeroPadding(); } + + public void setData(ReusableBuffer data) { + this.data = data; + } + + public void setZero_padding(int zero_padding) { + metadata = metadata.toBuilder().setZeroPadding(zero_padding).build(); + } + + public ObjectData getMetadata() { + return metadata; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/LocationsCache.java b/java/servers/src/org/xtreemfs/osd/LocationsCache.java new file mode 100644 index 0000000..c6d3a2e --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/LocationsCache.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + +import java.util.Map; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.LRUCache; + +/** + * This class implements a cache for Locations + * + * @author jmalo + */ +public class LocationsCache { + + private Map cache; + private final int maximumSize; + + /** + * Creates a new instance of LocationsCache + * @param size Maximum number of entries to store + */ + public LocationsCache(int size) { + maximumSize = size; + cache = new LRUCache(maximumSize); + } + + /** + * It gets the existing version number in cache of the locations of a file + * @param fileId File to look for inside the cache + * @return The version number of the stored locations or 0 if the locations are not cached. + */ + public long getVersion(String fileId) { + XLocations loc = cache.get(fileId); + return (loc != null)?loc.getVersion():0; + } + + /** + * It updates the existing entry of a file with a new locations + * @param fileId File refered by the locations + * @param updatedLoc New locations for the file + */ + public void update(String fileId, XLocations updatedLoc) { + cache.put(fileId, updatedLoc); + } + + /* + * It gets the existing cached Locations of a file + * @param fileId File referred to the requested Locations + * @return The existing cached Locations or null if there isn't any Locations related to fileId + */ + public XLocations getLocations(String fileId) { + return cache.get(fileId); + } + + public void removeLocations(String fileId) { + cache.remove(fileId); + } + + + + +} diff --git a/java/servers/src/org/xtreemfs/osd/OSD.java b/java/servers/src/org/xtreemfs/osd/OSD.java new file mode 100644 index 0000000..6977227 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/OSD.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; + +public class OSD { + + private OSDRequestDispatcher dispatcher; + + /** + * Creates a new instance of Main + */ + public OSD(OSDConfig config) { + + if (Logging.isInfo()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, (Object) null, "JAVA_HOME=%s", + System.getProperty("java.home")); + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, (Object) null, "UUID: %s", config.getUUID()); + } + + try { + // FIXME: pass UUID + useDIR + dispatcher = new OSDRequestDispatcher(config); + dispatcher.start(); + + final OSDRequestDispatcher ctrl = dispatcher; + + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + try { + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, "received shutdown signal"); + + ctrl.shutdown(); + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, "OSD shutdown complete"); + + } catch (Throwable ex) { + ex.printStackTrace(); + } + } + }); + + } catch (Exception ex) { + + Logging.logMessage(Logging.LEVEL_ERROR, null, "OSD could not start up due to an exception. Aborted."); + Logging.logError(Logging.LEVEL_ERROR, null, ex); + + if (dispatcher != null) + try { + dispatcher.shutdown(); + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_ERROR, config.getUUID(), "could not shutdown OSD: "); + Logging.logError(Logging.LEVEL_ERROR, config.getUUID(), e); + } + System.exit(1); + } + } + + public void shutdown() { + dispatcher.shutdown(); + } + + public OSDRequestDispatcher getDispatcher() { + return dispatcher; + } + + /** + * Main routine + * + * @param args + * the command line arguments + */ + public static void main(String[] args) throws Exception { + + Thread.currentThread().setName("OSD"); + + String cfgFile = (args.length > 0) ? args[0] : "./etc/xos/xtreemfs/osdconfig.test"; + OSDConfig config = new OSDConfig(cfgFile); + + config.setDefaults(); + + config.checkConfig(); + + Logging.start(config.getDebugLevel(), config.getDebugCategories()); + + new OSD(config); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/OSDConfig.java b/java/servers/src/org/xtreemfs/osd/OSDConfig.java new file mode 100644 index 0000000..e9b6ff1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/OSDConfig.java @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +import org.xtreemfs.common.config.ServiceConfig; + +/** + * + * @author bjko + */ +public class OSDConfig extends ServiceConfig { + + + /* + * @formatter:off + */ + private final Parameter[] osdParameter = { + Parameter.DEBUG_LEVEL, + Parameter.DEBUG_CATEGORIES, + Parameter.PORT, + Parameter.HTTP_PORT, + Parameter.LISTEN_ADDRESS, + Parameter.HOSTNAME, + Parameter.DIRECTORY_SERVICE, + Parameter.OBJECT_DIR, + Parameter.LOCAL_CLOCK_RENEW, + Parameter.REMOTE_TIME_SYNC, + Parameter.USE_SSL, + Parameter.SSL_PROTOCOL_STRING, + Parameter.SERVICE_CREDS_CONTAINER, + Parameter.SERVICE_CREDS_FILE, + Parameter.SERVICE_CREDS_PASSPHRASE, + Parameter.TRUSTED_CERTS_CONTAINER, + Parameter.TRUSTED_CERTS_FILE, + Parameter.TRUSTED_CERTS_PASSPHRASE, + Parameter.TRUST_MANAGER, + Parameter.USE_GRID_SSL_MODE, + Parameter.GEO_COORDINATES, + Parameter.CHECKSUM_ENABLED, + Parameter.CHECKSUM_PROVIDER, + Parameter.ADMIN_PASSWORD, + Parameter.WAIT_FOR_DIR, + Parameter.UUID, + Parameter.REPORT_FREE_SPACE, + Parameter.STORAGE_LAYOUT, + Parameter.IGNORE_CAPABILITIES, + Parameter.FLEASE_DMAX_MS, + Parameter.FLEASE_LEASE_TIMEOUT_MS, + Parameter.FLEASE_MESSAGE_TO_MS, + Parameter.FLEASE_RETRIES, + Parameter.POLICY_DIR, + Parameter.CAPABILITY_SECRET, + Parameter.SOCKET_SEND_BUFFER_SIZE, + Parameter.SOCKET_RECEIVE_BUFFER_SIZE, + Parameter.USE_SNMP, + Parameter.SNMP_ADDRESS, + Parameter.SNMP_PORT, + Parameter.SNMP_ACL, + Parameter.FAILOVER_MAX_RETRIES, + Parameter.FAILOVER_WAIT, + Parameter.MAX_CLIENT_Q, + Parameter.MAX_REQUEST_QUEUE_LENGTH, + Parameter.VIVALDI_RECALCULATION_INTERVAL_IN_MS, + Parameter.VIVALDI_RECALCULATION_EPSILON_IN_MS, + Parameter.VIVALDI_ITERATIONS_BEFORE_UPDATING, + Parameter.VIVALDI_MAX_RETRIES_FOR_A_REQUEST, + Parameter.VIVALDI_MAX_REQUEST_TIMEOUT_IN_MS, + Parameter.VIVALDI_TIMER_INTERVAL_IN_MS, + Parameter.STORAGE_THREADS, + Parameter.USE_RENEWAL_SIGNAL, + Parameter.USE_MULTIHOMING, + Parameter.HEALTH_CHECK + }; + /* + * @formatter:on + */ + public static final int CHECKSUM_NONE = 0; + + public static final int CHECKSUM_ADLER32 = 1; + + public static final int CHECKSUM_CRC32 = 2; + + private final Map customParams; + + /** Creates a new instance of OSDConfig */ + public OSDConfig(String filename) throws IOException { + super(filename); + + this.customParams = new HashMap(); + read(); + } + + public OSDConfig(Properties prop) throws IOException { + super(prop); + + this.customParams = new HashMap(); + read(); + } + + public OSDConfig(HashMap hm) { + super(hm); + + this.customParams = new HashMap(); + for (Entry entry : hm.entrySet()) + if (entry.getKey().startsWith(OSD_CUSTOM_PROPERTY_PREFIX)) + customParams.put(entry.getKey(), entry.getValue()); + + } + + public void read() throws IOException { + + for (String propName : this.props.stringPropertyNames()) { + if (propName.startsWith(ServiceConfig.OSD_CUSTOM_PROPERTY_PREFIX)) { + customParams.put(propName, this.props.getProperty(propName)); + } + } + + for (Parameter param : osdParameter) { + parameter.put(param, readParameter(param)); + } + + } + + public String getObjDir() { + return (String) parameter.get(Parameter.OBJECT_DIR); + } + + public int getLocalClockRenew() { + return (Integer) parameter.get(Parameter.LOCAL_CLOCK_RENEW); + } + + public int getRemoteTimeSync() { + return (Integer) parameter.get(Parameter.REMOTE_TIME_SYNC); + } + + public boolean isReportFreeSpace() { + return (Boolean) parameter.get(Parameter.REPORT_FREE_SPACE); + } + + public void setReportFreeSpace(boolean reportFreeSpace) { + parameter.put(Parameter.REPORT_FREE_SPACE, reportFreeSpace); + } + + public String getChecksumProvider() { + return (String) parameter.get(Parameter.CHECKSUM_PROVIDER); + } + + public boolean isUseChecksums() { + return (Boolean) parameter.get(Parameter.CHECKSUM_ENABLED); + } + + public String getCapabilitySecret() { + return (String) parameter.get(Parameter.CAPABILITY_SECRET); + } + + /** + * @return the ignoreCaps + */ + public boolean isIgnoreCaps() { + return (Boolean) parameter.get(Parameter.IGNORE_CAPABILITIES); + } + + /** + * @return the customParams + */ + public Map getCustomParams() { + return customParams; + } + + /** + * @return the storageLayout + */ + public String getStorageLayout() { + return (String) parameter.get(Parameter.STORAGE_LAYOUT); + } + + /** + * @return the fleaseDmaxMS + */ + public int getFleaseDmaxMS() { + return (Integer) parameter.get(Parameter.FLEASE_DMAX_MS); + } + + /** + * @return the fleaseLeaseToMS + */ + public int getFleaseLeaseToMS() { + return (Integer) parameter.get(Parameter.FLEASE_LEASE_TIMEOUT_MS); + } + + /** + * @return the fleaseMsgToMS + */ + public int getFleaseMsgToMS() { + return (Integer) parameter.get(Parameter.FLEASE_MESSAGE_TO_MS); + } + + /** + * @return the fleaseRetries + */ + public int getFleaseRetries() { + return (Integer) parameter.get(Parameter.FLEASE_RETRIES); + } + + /** + * @param capabilitySecret + * the capabilitySecret to set + */ + public void setCapabilitySecret(String capabilitySecret) { + parameter.put(Parameter.CAPABILITY_SECRET, capabilitySecret); + } + + public int getSocketSendBufferSize() { + return (Integer) parameter.get(Parameter.SOCKET_SEND_BUFFER_SIZE); + } + + public int getSocketReceiveBufferSize() { + return (Integer) parameter.get(Parameter.SOCKET_RECEIVE_BUFFER_SIZE); + } + + /** + * Set default values according to the value in {@link Parameter} for all configuration parameter which + * are null. + */ + public void setDefaults() { + super.setDefaults(osdParameter); + } + + /** + * Check if the configuration contain all necessary values to start the service + */ + public void checkConfig() { + super.checkConfig(osdParameter); + checkMultihomingConfiguration(); + } + + public int getMaxClientQ() { + return (Integer) parameter.get(Parameter.MAX_CLIENT_Q); + } + + public int getMaxRequestsQueueLength() { + return (Integer) parameter.get(Parameter.MAX_REQUEST_QUEUE_LENGTH); + } + + public HashMap toHashMap() { + HashMap hm = super.toHashMap(); + hm.putAll(customParams); + return hm; + } + + public int getVivaldiRecalculationInterval() { + return (Integer) parameter.get(Parameter.VIVALDI_RECALCULATION_INTERVAL_IN_MS); + } + + public int getVivaldiRecalculationEpsilon() { + return (Integer) parameter.get(Parameter.VIVALDI_RECALCULATION_EPSILON_IN_MS); + } + + public int getVivaldiIterationsBeforeUpdating() { + return (Integer) parameter.get(Parameter.VIVALDI_ITERATIONS_BEFORE_UPDATING); + } + + public int getVivaldiMaxRetriesForARequest() { + return (Integer) parameter.get(Parameter.VIVALDI_MAX_RETRIES_FOR_A_REQUEST); + } + + public int getVivaldiMaxRequestTimeout() { + return (Integer) parameter.get(Parameter.VIVALDI_MAX_REQUEST_TIMEOUT_IN_MS); + } + + public int getVivaldiTimerInterval() { + return (Integer) parameter.get(Parameter.VIVALDI_TIMER_INTERVAL_IN_MS); + } + + public int getStorageThreads() { + return (Integer) parameter.get(Parameter.STORAGE_THREADS); + } + + public String getHealthCheckScript() { + return (String) parameter.get(Parameter.HEALTH_CHECK); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/OSDRequest.java b/java/servers/src/org/xtreemfs/osd/OSDRequest.java new file mode 100644 index 0000000..1415fbd --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/OSDRequest.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + +import com.google.protobuf.Message; +import java.io.IOException; +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.osd.operations.OSDOperation; +import org.xtreemfs.osd.storage.CowPolicy; + +/** + * Request object. + * + * @author bjko + */ +public final class OSDRequest { + + private final RPCServerRequest rpcRequest; + private Message requestArgs; + /** + * Request operation which contains state machine. + */ + private OSDOperation operation; + private Object attachment; + private long requestId; + private static long rqIdCounter = 1; + private RPCResponse[] pendingRequests; + private String fileId; + private Capability capability; + private XLocations locationList; + private CowPolicy cowPolicy; + /** + * true, if this is the first call to a file + * (i.e. no entry in OFT) + */ + private boolean fileOpen; + + public OSDRequest(RPCServerRequest request) { + this.rpcRequest = request; + this.requestId = rqIdCounter++; + } + + public RPCServerRequest getRPCRequest() { + return this.getRpcRequest(); + } + + public void sendSuccess(Message response, ReusableBuffer data) { + try { + rpcRequest.sendResponse(response, data); + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + public void sendInternalServerError(Throwable cause) { + if (getRpcRequest() != null) { + rpcRequest.sendError(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_NONE, "internal server error:" + cause, OutputUtils.stackTraceToString(cause)); + } else { + Logging.logMessage(Logging.LEVEL_ERROR, this, "internal server error on internal request: %s", + cause.toString()); + Logging.logError(Logging.LEVEL_ERROR, this, cause); + } + } + + public void sendError(ErrorType type, POSIXErrno errno, String message) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "sending errno exception %s/%s/%s", type, errno, message); + } + rpcRequest.sendError(type, errno, message); + } + + public void sendError(ErrorType type, POSIXErrno errno, String message, String debugInfo) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "sending errno exception %s/%s/%s", type, errno, message); + } + rpcRequest.sendError(type, errno, message, debugInfo); + } + + + /** + * @return the rpcRequest + */ + public RPCServerRequest getRpcRequest() { + return rpcRequest; + } + + /** + * @return the requestArgs + */ + public Message getRequestArgs() { + return requestArgs; + } + + /** + * @param requestArgs the requestArgs to set + */ + public void setRequestArgs(Message requestArgs) { + this.requestArgs = requestArgs; + } + + /** + * @return the operation + */ + public OSDOperation getOperation() { + return operation; + } + + /** + * @param operation the operation to set + */ + public void setOperation(OSDOperation operation) { + this.operation = operation; + } + + /** + * @return the attachment + */ + public Object getAttachment() { + return attachment; + } + + /** + * @param attachment the attachment to set + */ + public void setAttachment(Object attachment) { + this.attachment = attachment; + } + + /** + * @return the requestId + */ + public long getRequestId() { + return requestId; + } + + /** + * @return the pendingRequests + */ + public RPCResponse[] getPendingRequests() { + return pendingRequests; + } + + /** + * @param pendingRequests the pendingRequests to set + */ + public void setPendingRequests(RPCResponse[] pendingRequests) { + this.pendingRequests = pendingRequests; + } + + /** + * @return the fileId + */ + public String getFileId() { + return fileId; + } + + /** + * @param fileId the fileId to set + */ + public void setFileId(String fileId) { + this.fileId = fileId; + } + + /** + * @return the capability + */ + public Capability getCapability() { + return capability; + } + + /** + * @param capability the capability to set + */ + public void setCapability(Capability capability) { + this.capability = capability; + } + + /** + * @return the locationList + */ + public XLocations getLocationList() { + return locationList; + } + + /** + * @param locationList the locationList to set + */ + public void setLocationList(XLocations locationList) { + this.locationList = locationList; + } + + /** + * @return the cowPolicy + */ + public CowPolicy getCowPolicy() { + return cowPolicy; + } + + /** + * @param cowPolicy the cowPolicy to set + */ + public void setCowPolicy(CowPolicy cowPolicy) { + this.cowPolicy = cowPolicy; + } + + /** + * @return the fileOpen + */ + public boolean isFileOpen() { + return fileOpen; + } + + /** + * @param fileOpen the fileOpen to set + */ + public void setFileOpen(boolean fileOpen) { + this.fileOpen = fileOpen; + } + + public void sendError(ErrorResponse error) { + this.getRPCRequest().sendError(error); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/OSDRequestDispatcher.java b/java/servers/src/org/xtreemfs/osd/OSDRequestDispatcher.java new file mode 100644 index 0000000..895b745 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/OSDRequestDispatcher.java @@ -0,0 +1,1090 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.management.ManagementFactory; +import java.lang.management.OperatingSystemMXBean; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; + +import org.xtreemfs.common.HeartbeatThread; +import org.xtreemfs.common.HeartbeatThread.ServiceDataGenerator; +import org.xtreemfs.common.ServiceAvailability; +import org.xtreemfs.common.config.PolicyContainer; +import org.xtreemfs.common.config.RemoteConfigHelper; +import org.xtreemfs.common.config.ServiceConfig; +import org.xtreemfs.common.monitoring.StatusMonitor; +import org.xtreemfs.common.statusserver.PrintStackTrace; +import org.xtreemfs.common.statusserver.StatusServer; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.dir.discovery.DiscoveryUtils; +import org.xtreemfs.foundation.CrashReporter; +import org.xtreemfs.foundation.LifeCycleListener; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.SSLOptions.TrustManager; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.VersionManagement; +import org.xtreemfs.foundation.checksums.ChecksumFactory; +import org.xtreemfs.foundation.checksums.provider.JavaChecksumProvider; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.server.RPCNIOSocketServer; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequestListener; +import org.xtreemfs.foundation.pbrpc.server.RPCUDPSocketServer; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.osd.operations.CheckObjectOperation; +import org.xtreemfs.osd.operations.CleanupGetResultsOperation; +import org.xtreemfs.osd.operations.CleanupGetStatusOperation; +import org.xtreemfs.osd.operations.CleanupIsRunningOperation; +import org.xtreemfs.osd.operations.CleanupStartOperation; +import org.xtreemfs.osd.operations.CleanupStopOperation; +import org.xtreemfs.osd.operations.CleanupVersionsStartOperation; +import org.xtreemfs.osd.operations.DeleteOperation; +import org.xtreemfs.osd.operations.EventCloseFile; +import org.xtreemfs.osd.operations.EventCreateFileVersion; +import org.xtreemfs.osd.operations.EventInsertPaddingObject; +import org.xtreemfs.osd.operations.EventRWRStatus; +import org.xtreemfs.osd.operations.EventWriteObject; +import org.xtreemfs.osd.operations.FleaseMessageOperation; +import org.xtreemfs.osd.operations.GetFileIDListOperation; +import org.xtreemfs.osd.operations.GetObjectSetOperation; +import org.xtreemfs.osd.operations.InternalGetFileSizeOperation; +import org.xtreemfs.osd.operations.InternalGetGmaxOperation; +import org.xtreemfs.osd.operations.InternalRWRAuthStateInvalidatedOperation; +import org.xtreemfs.osd.operations.InternalRWRAuthStateOperation; +import org.xtreemfs.osd.operations.InternalRWRFetchOperation; +import org.xtreemfs.osd.operations.InternalRWRStatusOperation; +import org.xtreemfs.osd.operations.InternalRWRTruncateOperation; +import org.xtreemfs.osd.operations.InternalRWRUpdateOperation; +import org.xtreemfs.osd.operations.InternalTruncateOperation; +import org.xtreemfs.osd.operations.InvalidateXLocSetOperation; +import org.xtreemfs.osd.operations.LocalReadOperation; +import org.xtreemfs.osd.operations.LockAcquireOperation; +import org.xtreemfs.osd.operations.LockCheckOperation; +import org.xtreemfs.osd.operations.LockReleaseOperation; +import org.xtreemfs.osd.operations.OSDOperation; +import org.xtreemfs.osd.operations.RWRNotifyOperation; +import org.xtreemfs.osd.operations.ReadOperation; +import org.xtreemfs.osd.operations.RepairObjectOperation; +import org.xtreemfs.osd.operations.ShutdownOperation; +import org.xtreemfs.osd.operations.TruncateOperation; +import org.xtreemfs.osd.operations.VivaldiPingOperation; +import org.xtreemfs.osd.operations.WriteOperation; +import org.xtreemfs.osd.rwre.RWReplicationStage; +import org.xtreemfs.osd.stages.DeletionStage; +import org.xtreemfs.osd.stages.PreprocStage; +import org.xtreemfs.osd.stages.ReplicationStage; +import org.xtreemfs.osd.stages.StorageStage; +import org.xtreemfs.osd.stages.VivaldiStage; +import org.xtreemfs.osd.storage.CleanupThread; +import org.xtreemfs.osd.storage.CleanupVersionsThread; +import org.xtreemfs.osd.storage.HashStorageLayout; +import org.xtreemfs.osd.storage.MetadataCache; +import org.xtreemfs.osd.storage.StorageLayout; +import org.xtreemfs.osd.vivaldi.VivaldiNode; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.OSDHealthResult; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +import com.google.protobuf.Message; + +public class OSDRequestDispatcher implements RPCServerRequestListener, LifeCycleListener { + + private static final int RPC_TIMEOUT = 15000; + + private static final int CONNECTION_TIMEOUT = 5 * 60 * 1000; + + protected final Map operations; + + protected final Map, OSDOperation> internalEvents; + + protected final HeartbeatThread heartbeatThread; + + protected final OSDConfig config; + + protected final DIRClient dirClient; + + protected final MRCServiceClient mrcClient; + + protected final OSDServiceClient osdClient; + + protected final OSDServiceClient osdClientForReplication; + + protected final RPCNIOSocketClient rpcClientForReplication; + + protected final RPCNIOSocketClient rpcClient; + + protected final RPCNIOSocketServer rpcServer; + + protected long requestId; + + protected String authString; + + protected final PreprocStage preprocStage; + + protected final StorageStage stStage; + + protected final DeletionStage delStage; + + protected final ReplicationStage replStage; + + protected final RPCUDPSocketServer udpCom; + + protected final StatusServer statusServer; + + protected final long startupTime; + + protected final AtomicLong numBytesTX, numBytesRX, numObjsTX, numObjsRX, numReplBytesRX, + numReplObjsRX; + + protected final VivaldiStage vStage; + + protected final AtomicReference myCoordinates; + + protected final CleanupThread cThread; + + protected final CleanupVersionsThread cvThread; + + protected final RWReplicationStage rwrStage; + + private List statusListener; + + /** + * reachability of services + */ + private final ServiceAvailability serviceAvailability; + + public OSDRequestDispatcher(final OSDConfig config) throws Exception { + + Logging.logMessage(Logging.LEVEL_INFO, this, "XtreemFS OSD version " + + VersionManagement.RELEASE_VERSION); + + this.config = config; + assert (config.getUUID() != null); + + if (this.config.getDirectoryService().getHostName().equals(DiscoveryUtils.AUTODISCOVER_HOSTNAME)) { + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, + "trying to discover local XtreemFS DIR service..."); + DirService dir = DiscoveryUtils.discoverDir(10); + if (dir == null) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.net, this, + "CANNOT FIND XtreemFS DIR service via discovery broadcasts... no response"); + throw new IOException("no DIR service found via discovery broadcast"); + } + Logging.logMessage(Logging.LEVEL_INFO, Category.net, this, "found XtreemFS DIR service at " + + dir.getAddress() + ":" + dir.getPort()); + config.setDirectoryService(new InetSocketAddress(dir.getAddress(), dir.getPort())); + } + + if (config.isInitializable()) { + try { + ServiceConfig remoteConfig = RemoteConfigHelper.getConfigurationFromDIR(config); + config.mergeConfig(remoteConfig); + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_WARN, this, + "Couldn't fetch configuration from DIR. Reason: " + e.getMessage()); + Logging.logError(Logging.LEVEL_DEBUG, config.getUUID(), e); + } + } + + numBytesTX = new AtomicLong(); + numBytesRX = new AtomicLong(); + numObjsTX = new AtomicLong(); + numObjsRX = new AtomicLong(); + numReplBytesRX = new AtomicLong(); + numReplObjsRX = new AtomicLong(); + + // initialize the checksum factory + ChecksumFactory.getInstance().addProvider(new JavaChecksumProvider()); + + // --------------------- + // initialize operations + // --------------------- + + // IMPORTANT: the order of operations defined in + // 'RequestDispatcher.Operations' has to be preserved! + operations = new HashMap(); + internalEvents = new HashMap, OSDOperation>(); + initializeOperations(); + + // create directory if necessary + File objDir = new File(config.getObjDir()); + if (!objDir.exists()) { + if (!objDir.mkdirs()) + throw new IOException("unable to create object directory: " + objDir.getAbsolutePath()); + } + + // ------------------------------- + // initialize communication stages + // ------------------------------- + + TrustManager tm1 = null; + TrustManager tm2 = null; + if (config.isUsingSSL()) { + + PolicyContainer policyContainer = new PolicyContainer(config); + try { + tm1 = policyContainer.getTrustManager(); + tm2 = policyContainer.getTrustManager(); + } catch (Exception e) { + throw new IOException(e); + } + + if (Logging.isInfo() && tm1 != null) + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, this, + "using custom trust manager '%s'", tm1.getClass().getName()); + } + + SSLOptions serverSSLopts = config.isUsingSSL() ? new SSLOptions(new FileInputStream(config + .getServiceCredsFile()), config.getServiceCredsPassphrase(), config + .getServiceCredsContainer(), new FileInputStream(config.getTrustedCertsFile()), config + .getTrustedCertsPassphrase(), config.getTrustedCertsContainer(), false, config + .isGRIDSSLmode(), config.getSSLProtocolString(), tm1) : null; + + rpcServer = new RPCNIOSocketServer(config.getPort(), config.getAddress(), this, serverSSLopts, + config.getSocketReceiveBufferSize(), config.getMaxClientQ()); + rpcServer.setLifeCycleListener(this); + + final SSLOptions clientSSLopts = config.isUsingSSL() ? new SSLOptions(new FileInputStream(config + .getServiceCredsFile()), config.getServiceCredsPassphrase(), config + .getServiceCredsContainer(), new FileInputStream(config.getTrustedCertsFile()), config + .getTrustedCertsPassphrase(), config.getTrustedCertsContainer(), false, config + .isGRIDSSLmode(), config.getSSLProtocolString(), tm2) : null; + + InetSocketAddress bindPoint = config.getAddress() != null ? new InetSocketAddress(config.getAddress(), 0) + : null; + if (Logging.isInfo() && bindPoint != null) + Logging.logMessage(Logging.LEVEL_INFO, Category.misc, this, + "outgoing server connections will be bound to '%s'", config.getAddress()); + + rpcClient = new RPCNIOSocketClient(clientSSLopts, RPC_TIMEOUT, CONNECTION_TIMEOUT, + config.getSocketSendBufferSize(), config.getSocketReceiveBufferSize(), bindPoint, "OSDRequestDispatcher"); + rpcClient.setLifeCycleListener(this); + + // replication uses its own RPCClient with a much higher timeout + rpcClientForReplication = new RPCNIOSocketClient(clientSSLopts, 30000, 5 * 60 * 1000, "OSDRequestDispatcher (for replication)"); + rpcClientForReplication.setLifeCycleListener(this); + + // initialize ServiceAvailability + this.serviceAvailability = new ServiceAvailability(); + + // -------------------------- + // initialize internal stages + // -------------------------- + + MetadataCache metadataCache = new MetadataCache(); + StorageLayout storageLayout = null; + if (config.getStorageLayout().equalsIgnoreCase(HashStorageLayout.class.getSimpleName())) { + storageLayout = new HashStorageLayout(config, metadataCache); + /* + * } else if + * (config.getStorageLayout().equalsIgnoreCase(SingleFileStorageLayout + * .class.getSimpleName())) { storageLayout = new + * SingleFileStorageLayout(config, metadataCache); + */ + } else { + throw new RuntimeException("unknown storage layout in config file: " + config.getStorageLayout()); + } + + udpCom = new RPCUDPSocketServer(config.getPort(), this); + udpCom.setLifeCycleListener(this); + + preprocStage = new PreprocStage(this, metadataCache, storageLayout, config.getMaxRequestsQueueLength()); + preprocStage.setLifeCycleListener(this); + + stStage = new StorageStage(this, metadataCache, storageLayout, config.getStorageThreads(), config.getMaxRequestsQueueLength()); + stStage.setLifeCycleListener(this); + + delStage = new DeletionStage(this, metadataCache, storageLayout, config.getMaxRequestsQueueLength()); + delStage.setLifeCycleListener(this); + + replStage = new ReplicationStage(this, config.getMaxRequestsQueueLength()); + replStage.setLifeCycleListener(this); + + rwrStage = new RWReplicationStage(this, serverSSLopts, config.getMaxRequestsQueueLength()); + rwrStage.setLifeCycleListener(this); + + // ---------------------------------------- + // initialize TimeSync and Heartbeat thread + // ---------------------------------------- + + DIRServiceClient dirRpcClient = new DIRServiceClient(rpcClient, config.getDirectoryService()); + dirClient = new DIRClient(dirRpcClient, config.getDirectoryServices(), config.getFailoverMaxRetries(), config.getFailoverWait()); + mrcClient = new MRCServiceClient(rpcClient, null); + osdClient = new OSDServiceClient(rpcClient, null); + osdClientForReplication = new OSDServiceClient(rpcClientForReplication, null); + + TimeSync.initialize(dirClient, config.getRemoteTimeSync(), config.getLocalClockRenew()); + UUIDResolver.start(dirClient, 10 * 1000, 600 * 1000); + UUIDResolver.addLocalMapping(config.getUUID(), config.getPort(), Schemes.getScheme(config + .isUsingSSL(), config.isGRIDSSLmode())); + UUIDResolver.addLocalMapping(config.getUUID(), config.getPort(), Schemes.SCHEME_PBRPCU); + + myCoordinates = new AtomicReference(); + + ServiceDataGenerator gen = new ServiceDataGenerator() { + @Override + public ServiceSet getServiceData() { + + OSDConfig config = OSDRequestDispatcher.this.config; + String freeSpace = "0"; + String useableSpace = "0"; + + if (config.isReportFreeSpace()) { + freeSpace = String.valueOf(FSUtils.getFreeSpace(config.getObjDir())); + useableSpace = String.valueOf(FSUtils.getUsableSpace(config.getObjDir())); + } + + String totalSpace = "-1"; + + try { + File f = new File(config.getObjDir()); + totalSpace = String.valueOf(f.getTotalSpace()); + } catch (Exception ex) { + } + + OperatingSystemMXBean osb = ManagementFactory.getOperatingSystemMXBean(); + String load = String.valueOf((int) (osb.getSystemLoadAverage() * 100 / osb + .getAvailableProcessors())); + + long totalRAM = Runtime.getRuntime().maxMemory(); + long usedRAM = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + + // Get OSD health check result from user-defined script. + OSDHealthResult healthCheckResult = OSDHealthResult.OSD_HEALTH_RESULT_NOT_AVAIL; + BufferedReader scriptOutputReader = null; + String scriptOutput = ""; + if (!config.getHealthCheckScript().equals("")) { + try { + Process scriptProcess = Runtime.getRuntime() + .exec(new String[] { config.getHealthCheckScript(), config.getObjDir() }); + + // wait until the health check is terminated and get exit value (i.e. health check result) + int healthCheckExitValue = scriptProcess.waitFor(); + healthCheckResult = OSDHealthResult.valueOf(healthCheckExitValue); + + // get output of the health check script + scriptOutputReader = new BufferedReader (new InputStreamReader(scriptProcess.getInputStream())); + String line = ""; + while(( line = scriptOutputReader.readLine()) != null) { + scriptOutput += line; + scriptOutput += "\n"; + } + + if (healthCheckResult == null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "Health check script returns invalid value (" + healthCheckExitValue + ")"); + healthCheckResult = OSDHealthResult.OSD_HEALTH_RESULT_NOT_AVAIL; + } + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "Exception while reading health check result: " + e.getMessage()); + } finally { + if (scriptOutputReader != null) { + try { + scriptOutputReader.close(); + } catch (IOException e) { + // do nothing + } + } + } + } + + ServiceSet.Builder data = ServiceSet.newBuilder(); + + ServiceDataMap.Builder dmap = ServiceDataMap.newBuilder(); + dmap.addData(KeyValuePair.newBuilder().setKey("load").setValue(load).build()); + dmap.addData(KeyValuePair.newBuilder().setKey("total").setValue(totalSpace).build()); + dmap.addData(KeyValuePair.newBuilder().setKey("free").setValue(freeSpace).build()); + dmap.addData(KeyValuePair.newBuilder().setKey("usable").setValue(useableSpace).build()); + dmap.addData(KeyValuePair.newBuilder().setKey("totalRAM").setValue(Long.toString(totalRAM)) + .build()); + dmap.addData(KeyValuePair.newBuilder().setKey("usedRAM").setValue(Long.toString(usedRAM)) + .build()); + dmap.addData(KeyValuePair.newBuilder().setKey("osd_health_check") + .setValue(String.valueOf(healthCheckResult.getNumber())).build()); + dmap.addData(KeyValuePair.newBuilder().setKey("osd_health_check_output") + .setValue(scriptOutput).build()); + dmap.addData(KeyValuePair.newBuilder().setKey("proto_version").setValue( + Integer.toString(OSDServiceConstants.INTERFACE_ID)).build()); + VivaldiCoordinates coord = myCoordinates.get(); + if (coord != null) { + dmap.addData(KeyValuePair.newBuilder().setKey("vivaldi_coordinates").setValue( + VivaldiNode.coordinatesToString(coord)).build()); + } + for (Entry e : config.getCustomParams().entrySet()) + dmap.addData(KeyValuePair.newBuilder().setKey(e.getKey()).setValue(e.getValue())); + + if (config.getHttpPort() != -1) { + try { + final String address = "".equals(config.getHostName()) ? config.getAddress() == null ? config + .getUUID().getMappings()[0].resolvedAddr.getAddress().getHostAddress() : config + .getAddress().getHostAddress() : config.getHostName(); + dmap.addData(KeyValuePair.newBuilder().setKey("status_page_url") + .setValue("http://" + address + ":" + config.getHttpPort())); + } catch (UnknownUUIDException ex) { + // should never happen + } + } + + Service.Builder me = Service.newBuilder(); + me.setType(ServiceType.SERVICE_TYPE_OSD); + me.setUuid(config.getUUID().toString()); + me.setName("OSD @ " + config.getUUID()); + me.setVersion(0); + me.setData(dmap); + me.setLastUpdatedS(0); + + data.addServices(me); + + return data.build(); + } + }; + heartbeatThread = new HeartbeatThread("OSD HB Thr", dirClient, config.getUUID(), gen, config, true); + + if (config.getHttpPort() == -1) { + // Webinterface is explicitly disabled. + statusServer = null; + } else { + statusServer = new StatusServer(ServiceType.SERVICE_TYPE_OSD, this, config.getHttpPort()); + statusServer.registerModule(new StatusPage()); + statusServer.registerModule(new PrintStackTrace()); + statusServer.registerModule(new ReplicatedFileStatusPage()); + statusServer.registerModule(new ReplicatedFileStatusJSON()); + + if (config.getAdminPassword().length() > 0) { + statusServer.addAuthorizedUser("admin", config.getAdminPassword()); + } + + statusServer.start(); + } + + startupTime = System.currentTimeMillis(); + + vStage = new VivaldiStage(this, config.getMaxRequestsQueueLength()); + vStage.setLifeCycleListener(this); + + cThread = new CleanupThread(this, storageLayout); + cThread.setLifeCycleListener(this); + + cvThread = new CleanupVersionsThread(this, storageLayout); + cvThread.setLifeCycleListener(this); + + statusListener = new ArrayList(); + if (config.isUsingSnmp()) { + statusListener.add(new StatusMonitor( + this, config.getSnmpAddress(), config.getSnmpPort(), config.getSnmpACLFile())); + + notifyConfigurationChange(); + } + + + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.lifecycle, this, "OSD at %s ready", this + .getConfig().getUUID().toString()); + } + + public CleanupThread getCleanupThread() { + return cThread; + } + + public CleanupVersionsThread getCleanupVersionsThread() { + return cvThread; + } + + public void start() { + + try { + + rpcServer.start(); + rpcClient.start(); + rpcClientForReplication.start(); + + rpcServer.waitForStartup(); + rpcClient.waitForStartup(); + + udpCom.start(); + preprocStage.start(); + delStage.start(); + stStage.start(); + replStage.start(); + vStage.start(); + cThread.start(); + cvThread.start(); + rwrStage.start(); + + udpCom.waitForStartup(); + preprocStage.waitForStartup(); + delStage.waitForStartup(); + stStage.waitForStartup(); + vStage.waitForStartup(); + cThread.waitForStartup(); + cvThread.waitForStartup(); + rwrStage.waitForStartup(); + + heartbeatThread.initialize(); + heartbeatThread.start(); + heartbeatThread.waitForStartup(); + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, + "OSD RequestController and all services operational"); + + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "STARTUP FAILED!"); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + System.exit(1); + } + + } + + public void shutdown() { + + try { + + for (OSDStatusListener listener : statusListener) { + listener.shuttingDown(); + } + + heartbeatThread.shutdown(); + heartbeatThread.waitForShutdown(); + + rpcServer.shutdown(); + rpcClient.shutdown(); + rpcClientForReplication.shutdown(); + + rpcServer.waitForShutdown(); + rpcClient.waitForShutdown(); + rpcClientForReplication.waitForShutdown(); + + serviceAvailability.shutdown(); + + udpCom.shutdown(); + preprocStage.shutdown(); + delStage.shutdown(); + stStage.shutdown(); + replStage.shutdown(); + rwrStage.shutdown(); + vStage.shutdown(); + cThread.cleanupStop(); + cThread.shutdown(); + cvThread.cleanupStop(); + cvThread.shutdown(); + serviceAvailability.shutdown(); + + udpCom.waitForShutdown(); + preprocStage.waitForShutdown(); + delStage.waitForShutdown(); + stStage.waitForShutdown(); + replStage.waitForShutdown(); + rwrStage.waitForShutdown(); + vStage.waitForShutdown(); + cThread.waitForShutdown(); + cvThread.waitForShutdown(); + + if (statusServer != null) { + statusServer.shutdown(); + } + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, "OSD and all stages terminated"); + + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "shutdown failed"); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + public void asyncShutdown() { + try { + + for (OSDStatusListener listener : statusListener) { + listener.shuttingDown(); + } + + heartbeatThread.shutdown(); + + rpcServer.shutdown(); + rpcClient.shutdown(); + rpcClientForReplication.shutdown(); + + udpCom.shutdown(); + preprocStage.shutdown(); + delStage.shutdown(); + stStage.shutdown(); + replStage.shutdown(); + rwrStage.shutdown(); + vStage.shutdown(); + cThread.cleanupStop(); + cThread.shutdown(); + cvThread.cleanupStop(); + cvThread.shutdown(); + serviceAvailability.shutdown(); + + statusServer.shutdown(); + + if (Logging.isInfo()) + Logging.logMessage(Logging.LEVEL_INFO, Category.lifecycle, this, "OSD and all stages terminated"); + + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "shutdown failed"); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + public OSDOperation getOperation(int procId) { + return operations.get(procId); + } + + public OSDOperation getInternalEvent(Class clazz) { + return internalEvents.get(clazz); + } + + public OSDConfig getConfig() { + return config; + } + + public DIRClient getDIRClient() { + return dirClient; + } + + public MRCServiceClient getMRCClient() { + return mrcClient; + } + + public OSDServiceClient getOSDClient() { + return osdClient; + } + + public OSDServiceClient getOSDClientForReplication() { + return osdClientForReplication; + } + + public RPCNIOSocketClient getRPCClient() { + return rpcClient; + } + + @Override + public void startupPerformed() { + + } + + @Override + public void shutdownPerformed() { + + } + + @Override + public void crashPerformed(Throwable cause) { + final String report = CrashReporter.createCrashReport("OSD", VersionManagement.RELEASE_VERSION, cause); + System.out.println(report); + CrashReporter.reportXtreemFSCrash(report); + this.shutdown(); + } + + /** + * Checks if the local OSD is the head OSD in one of the given X-Locations list. + * + * @param xloc + * the X-Locations list + * @return true, if the local OSD is the head OSD of the given X-Locations list; + * false, otherwise + */ + public boolean isHeadOSD(XLocations xloc) { + final ServiceUUID headOSD = xloc.getLocalReplica().getOSDs().get(0); + return config.getUUID().equals(headOSD); + } + + public long getFreeSpace() { + return FSUtils.getFreeSpace(config.getObjDir()); + } + + public long getTotalSpace() { + File f = new File(config.getObjDir()); + long s = f.getTotalSpace(); + return s; + } + + @Override + public void receiveRecord(RPCServerRequest rq) { + + // final ONCRPCRequestHeader hdr = rq.getRequestHeader(); + RPCHeader hdr = rq.getHeader(); + + if (hdr.getMessageType() != MessageType.RPC_REQUEST) { + rq.sendError(ErrorType.GARBAGE_ARGS, POSIXErrno.POSIX_ERROR_EIO, + "expected RPC request message type but got " + hdr.getMessageType()); + return; + } + + final RPCHeader.RequestHeader rqHdr = hdr.getRequestHeader(); + + if (rqHdr.getInterfaceId() != OSDServiceConstants.INTERFACE_ID) { + rq.sendError( + ErrorType.INVALID_INTERFACE_ID, + POSIXErrno.POSIX_ERROR_EIO, + "Invalid interface id. This is an OSD service. You probably wanted to contact another service. Check the used address and port."); + return; + } + + try { + OSDRequest request = new OSDRequest(rq); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "received new request: %s", rq.toString()); + preprocStage.prepareRequest(request, new PreprocStage.ParseCompleteCallback() { + + @Override + public void parseComplete(OSDRequest result, ErrorResponse error) { + if (error == null) { + result.getOperation().startRequest(result); + } else { + result.getRPCRequest().sendError(error); + } + } + }); + } catch (Exception ex) { + rq.sendError(ErrorUtils.getInternalServerError(ex)); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + public int getNumClientConnections() { + return rpcServer.getNumConnections(); + } + + public long getPendingRequests() { + return rpcServer.getPendingRequests(); + } + + private void initializeOperations() { + // register all ops + OSDOperation op = new ReadOperation(this); + operations.put(op.getProcedureId(), op); + + op = new WriteOperation(this); + operations.put(op.getProcedureId(), op); + + op = new DeleteOperation(this); + operations.put(op.getProcedureId(), op); + + op = new TruncateOperation(this); + operations.put(op.getProcedureId(), op); + + /* + * op = new KeepFileOpenOperation(this); operations.put(op.getProcedureId(),op); + */ + + op = new InternalGetGmaxOperation(this); + operations.put(op.getProcedureId(), op); + + op = new InternalTruncateOperation(this); + operations.put(op.getProcedureId(), op); + + op = new CheckObjectOperation(this); + operations.put(op.getProcedureId(), op); + + op = new RepairObjectOperation(this); + operations.put(op.getProcedureId(), op); + + op = new InternalGetFileSizeOperation(this); + operations.put(op.getProcedureId(), op); + + op = new ShutdownOperation(this); + operations.put(op.getProcedureId(), op); + + op = new LocalReadOperation(this); + operations.put(op.getProcedureId(), op); + + op = new CleanupStartOperation(this); + operations.put(op.getProcedureId(), op); + + op = new CleanupIsRunningOperation(this); + operations.put(op.getProcedureId(), op); + + op = new CleanupStopOperation(this); + operations.put(op.getProcedureId(), op); + + op = new CleanupGetStatusOperation(this); + operations.put(op.getProcedureId(), op); + + op = new CleanupGetResultsOperation(this); + operations.put(op.getProcedureId(), op); + + op = new CleanupVersionsStartOperation(this); + operations.put(op.getProcedureId(), op); + + op = new GetObjectSetOperation(this); + operations.put(op.getProcedureId(), op); + + op = new LockAcquireOperation(this); + operations.put(op.getProcedureId(), op); + + op = new LockCheckOperation(this); + operations.put(op.getProcedureId(), op); + + op = new LockReleaseOperation(this); + operations.put(op.getProcedureId(), op); + + op = new VivaldiPingOperation(this); + operations.put(op.getProcedureId(), op); + + op = new FleaseMessageOperation(this); + operations.put(op.getProcedureId(), op); + + op = new InternalRWRUpdateOperation(this); + operations.put(op.getProcedureId(), op); + + op = new InternalRWRTruncateOperation(this); + operations.put(op.getProcedureId(), op); + + op = new InternalRWRStatusOperation(this); + operations.put(op.getProcedureId(), op); + + op = new InternalRWRFetchOperation(this); + operations.put(op.getProcedureId(), op); + + op = new GetFileIDListOperation(this); + operations.put(op.getProcedureId(), op); + + op = new RWRNotifyOperation(this); + operations.put(op.getProcedureId(), op); + + op = new InternalRWRAuthStateOperation(this); + operations.put(op.getProcedureId(), op); + + op = new InvalidateXLocSetOperation(this); + operations.put(op.getProcedureId(), op); + + op = new InternalRWRAuthStateInvalidatedOperation(this); + operations.put(op.getProcedureId(), op); + + // --internal events here-- + + op = new EventCloseFile(this); + internalEvents.put(EventCloseFile.class, op); + + op = new EventCreateFileVersion(this); + internalEvents.put(EventCreateFileVersion.class, op); + + op = new EventWriteObject(this); + internalEvents.put(EventWriteObject.class, op); + + op = new EventInsertPaddingObject(this); + internalEvents.put(EventInsertPaddingObject.class, op); + + op = new EventRWRStatus(this); + internalEvents.put(EventRWRStatus.class, op); + + } + + public StorageStage getStorageStage() { + return this.stStage; + } + + public DeletionStage getDeletionStage() { + return delStage; + } + + public PreprocStage getPreprocStage() { + return preprocStage; + } + + public ReplicationStage getReplicationStage() { + return replStage; + } + + public void sendUDPMessage(RPCHeader header, Message message, InetSocketAddress receiver) throws IOException { + udpCom.sendRequest(header, message, receiver); + } + + public VivaldiStage getVivaldiStage() { + return this.vStage; + } + + public RWReplicationStage getRWReplicationStage() { + return this.rwrStage; + } + + // FIXME: implement operations for Gmax, Ping + /* + * @Override public void receiveUDP(UDPMessage msg) { assert (msg.isRequest() || msg.isResponse()); + * + * try { + * + * if (msg.isRequest()) { if (msg.getRequestData() instanceof xtreemfs_broadcast_gmaxRequest) { + * xtreemfs_broadcast_gmaxRequest rq = (xtreemfs_broadcast_gmaxRequest) msg.getRequestData(); if (Logging.isDebug()) + * Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "received GMAX packet for: %s from %s", + * rq.getFile_id(), msg.getAddress()); + * + * BufferPool.free(msg.getPayload()); stStage.receivedGMAX_ASYNC(rq.getFile_id(), rq.getTruncate_epoch(), + * rq.getLast_object()); } else if (msg.getRequestData() instanceof xtreemfs_pingRequest) { xtreemfs_pingRequest rq + * = (xtreemfs_pingRequest) msg.getRequestData(); if (Logging.isDebug()) Logging.logMessage(Logging.LEVEL_DEBUG, + * Category.stage, this, "received ping request from: %s", msg.getAddress()); + * + * vStage.receiveVivaldiMessage(msg); } } else { if (msg.getResponseData() instanceof xtreemfs_pingResponse) { + * xtreemfs_pingResponse resp = (xtreemfs_pingResponse) msg.getResponseData(); if (Logging.isDebug()) + * Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "received ping response from: %s", + * msg.getAddress()); + * + * vStage.receiveVivaldiMessage(msg); } } } catch (Exception ex) { Logging.logError(Logging.LEVEL_DEBUG, this,ex); } + * } + */ + + /** + * @return the serviceAvailability + */ + public ServiceAvailability getServiceAvailability() { + return serviceAvailability; + } + + public void objectReceived() { + long num = numObjsRX.incrementAndGet(); + for (OSDStatusListener listener : statusListener) { + listener.numObjsRXChanged(num); + } + } + + public void objectReplicated() { + long num = numReplObjsRX.incrementAndGet(); + for (OSDStatusListener listener : statusListener) { + listener.numReplObjsRX(num); + } + } + + public void objectSent() { + long num = numObjsTX.incrementAndGet(); + for (OSDStatusListener listener : statusListener) { + listener.numObjsTXChanged(num); + } + } + + public void replicatedDataReceived(int numBytes) { + long num = numReplBytesRX.addAndGet(numBytes); + for (OSDStatusListener listener : statusListener) { + listener.numReplBytesRXChanged(num); + } + } + + public void dataReceived(int numBytes) { + long num = numBytesRX.addAndGet(numBytes); + for (OSDStatusListener listener : statusListener) { + listener.numBytesRXChanged(num); + } + } + + public void dataSent(int numBytes) { + long num = numBytesTX.addAndGet(numBytes); + for (OSDStatusListener listener : statusListener) { + listener.numBytesTXChanged(num); + } + } + + public long getObjectsReceived() { + return numObjsRX.get(); + } + + public long getObjectsSent() { + return numObjsTX.get(); + } + + public long getBytesReceived() { + return numBytesRX.get(); + } + + public long getBytesSent() { + return numBytesTX.get(); + } + + public long getReplicatedObjectsReceived() { + return numReplObjsRX.get(); + } + + public long getReplicatedBytesReceived() { + return numReplBytesRX.get(); + } + + public void updateVivaldiCoordinates(VivaldiCoordinates newVC) { + myCoordinates.set(newVC); + } + + public String getHostName() { + return heartbeatThread.getAdvertisedHostName(); + } + + public void addStatusListener(OSDStatusListener listener) { + this.statusListener.add(listener); + } + + public void removeStatusListener(OSDStatusListener listener) { + this.statusListener.remove(listener); + } + + /** + * Tells all listeners when the configuration has changed. + */ + public void notifyConfigurationChange() { + for (OSDStatusListener listener : statusListener) { + listener.OSDConfigChanged(this.config); + } + } + + /** + * Getter for a timestamp when the heartbeatthread sent his last heartbeat + * + * @return long - timestamp as returned by System.currentTimeMillis() + */ + public long getLastHeartbeat() { + return heartbeatThread.getLastHeartbeat(); + } + + /** + * Returns primary OSD UUID for the file with ID "fileId" (if OSD is primary or backup) or null (if OSD does not + * know the file). + * + * @param fileId + */ + public String getPrimary(String fileId) { + return rwrStage.getPrimary(fileId); + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/OSDStatusListener.java b/java/servers/src/org/xtreemfs/osd/OSDStatusListener.java new file mode 100644 index 0000000..6ddbb92 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/OSDStatusListener.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + +public interface OSDStatusListener { + + + public void OSDConfigChanged(OSDConfig config); + + public void numBytesTXChanged(long numBytesTX); + + public void numBytesRXChanged(long numBytesRX); + + public void numReplBytesRXChanged(long numReplBytesRX); + + public void numObjsTXChanged(long numObjsTX); + + public void numObjsRXChanged(long numObjsRX); + + public void numReplObjsRX(long numReplObjsRX); + + /** + * Called when OSD is shutting down. + */ + public void shuttingDown(); +} diff --git a/java/servers/src/org/xtreemfs/osd/OpenFileTable.java b/java/servers/src/org/xtreemfs/osd/OpenFileTable.java new file mode 100644 index 0000000..e0d4f81 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/OpenFileTable.java @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Eugenio Cesario, + * Zuse Institute Berlin, + * Consiglio Nazionale delle Ricerche + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.osd.operations.EventCreateFileVersion; +import org.xtreemfs.osd.storage.CowPolicy; + +/** + * This class models an OpenFileTable, storing the set of files in an 'open' state; it makes available a 'clean' method + * that cleans the table by deleting entries whose expiration time is expired + * + * @author Eugenio Cesario + */ +public final class OpenFileTable { + + private final HashMap openFiles; + + private final SortedSet expTimes; + + private final SortedSet expTimesWrite; + + // constructor + public OpenFileTable() { + openFiles = new HashMap(); + expTimes = new TreeSet(); + expTimesWrite = new TreeSet(OpenFileTableEntry.createWriteExpComparator()); + } + + /** + * Insert a new entry in the table + * + * @param fId + * fileId + * @param expTime + * expiration time + */ + public CowPolicy refresh(String fId, long expTime, boolean write) { + OpenFileTableEntry currEntry = openFiles.get(fId); + + if (currEntry != null) { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "refreshing for %s", fId); + + // 'currEntry' isn't a new entry, so update it + // if its expiration time is renewed + if (expTime > currEntry.expTime) { + + // openFiles.remove(fId); + expTimes.remove(currEntry); + + currEntry.setExpirationTime(expTime); + openFiles.put(fId, currEntry); + boolean success = expTimes.add(currEntry); + assert (success); + + if (write) { + expTimesWrite.remove(currEntry); + currEntry.setWriteExpirationTime(expTime); + currEntry.setWrite(); + expTimesWrite.add(currEntry); + } + } + return currEntry.getCowPolicy(); + } else { + Logging.logMessage(Logging.LEVEL_WARN, this, + "attempt to keep file %s open failed because no open state exists anymore", fId); + // Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "new entry for %s", fId); + // // 'currEntry' is a new entry, so + // // insert it in the table + // OpenFileTableEntry newEntry = new OpenFileTableEntry(fId, expTime); + // openFiles.put(fId, newEntry); + // expTimes.add(newEntry); + return null; + } + } + + /** + * Insert a new entry in the table + * + * @param fId + * fileId + * @param expTime + * expiration time + */ + public void openFile(String fId, long expTime, CowPolicy policy, boolean write) { + assert (openFiles.containsKey(fId) == false); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "new entry for %s", fId); + // 'currEntry' is a new entry, so + // insert it in the table + OpenFileTableEntry newEntry = new OpenFileTableEntry(fId, expTime, policy); + openFiles.put(fId, newEntry); + expTimes.add(newEntry); + + if (write) { + newEntry.setWriteExpirationTime(expTime); + newEntry.setWrite(); + expTimesWrite.add(newEntry); + } + } + + /** + * Returns 'true' if this table contains the specified file, 'false' otherwise + */ + public boolean contains(String fId) { + return openFiles.containsKey(fId); + } + + /** + * Delete all the entries whose expiration time is strictly less than 'toTime'. + */ + public List clean(long toTime) { + + LinkedList closedFiles = new LinkedList(); + + OpenFileTableEntry dummyEntry = new OpenFileTableEntry(null, toTime); + + Iterator it = expTimes.iterator(); + + // since entries in 'expTimes' are sorted w.r.t. their expiration time + // (ascending order), 'expTimes' has to be scanned until there is an + // entry with its 'expTimes' > 'toTime' + + while (it.hasNext()) { + + OpenFileTableEntry currEntry = (OpenFileTableEntry) it.next(); + + if (currEntry.compareTo(dummyEntry) < 0) { + String fId = currEntry.fileId; + openFiles.remove(fId); + it.remove(); + currEntry.setClosed(); + closedFiles.add(currEntry); + } else { + break; + } + } + return closedFiles; + } + + /** + * Deletes all entries of files that were opened for writing whose expiration time is strictly less than 'toTime'. + * + * @param toTime + * @return + */ + public List cleanWritten(long toTime) { + + List closedFiles = new LinkedList(); + + OpenFileTableEntry dummyEntry = new OpenFileTableEntry(null, toTime); + + Iterator it = expTimesWrite.iterator(); + + while (it.hasNext()) { + + OpenFileTableEntry currEntry = it.next(); + + if (currEntry.compareTo(dummyEntry) < 0) { + String fId = currEntry.fileId; + openFiles.remove(fId); + it.remove(); + closedFiles.add(currEntry); + } else { + break; + } + } + + return closedFiles; + + } + + /** + * It tells if a file was closed + * + * @param fileId + * File to consult + * @return true if the file is closed + */ + public boolean isClosed(String fileId) { + OpenFileTableEntry fileEntry = openFiles.get(fileId); + + if (fileEntry != null) { + if (fileEntry.expTime < (System.currentTimeMillis() / 1000)) { + return true; + } else { + return false; + } + } else { + return true; + } + } + + public void setDeleteOnClose(String fileId) { + OpenFileTableEntry fileEntry = openFiles.get(fileId); + + if (fileEntry != null) { + fileEntry.setDeleteOnClose(); + } + } + + /** + * + * @param fileId + * @return true if the file with the given id is set to be deleted on close, false otherwise. + */ + public boolean isDeleteOnClose(String fileId) { + OpenFileTableEntry fileEntry = openFiles.get(fileId); + + if (fileEntry != null) { + return fileEntry.isDeleteOnClose(); + } + + return false; + } + + /** + * Remove the entries for fileId from the OpenFileTable. + * + * @param fileId + * @return the removed {@link OpenFileTableEntry} or null if it did not exist. + */ + public OpenFileTableEntry close(String fileId) { + + OpenFileTableEntry currEntry = openFiles.get(fileId); + + if (currEntry != null) { + expTimes.remove(currEntry); + expTimesWrite.remove(currEntry); + openFiles.remove(fileId); + currEntry.setClosed(); + } + + return currEntry; + } + + public int getNumOpenFiles() { + return this.openFiles.size(); + } + + public OpenFileTableEntry getEntry(String fileId) { + return this.openFiles.get(fileId); + } + + /** + * Class used to model an entry in the OpenFileTable + * + * @author Eugenio Cesario + * + */ + public static class OpenFileTableEntry implements Comparable { + + private final String fileId; + + private final CowPolicy fileCowPolicy; + + private long expTime; + + private long writeExpTime; + + private Map advisoryLocks; + + private boolean closed; + + private boolean write; + + private boolean deleteOnClose; + + private OpenFileTableEntry(String fid, long et) { + this(fid, et, null); + } + + private OpenFileTableEntry(String fid, long et, CowPolicy cow) { + fileId = fid; + expTime = et; + writeExpTime = 0; + + closed = false; + deleteOnClose = false; + write = false; + + if (cow != null) + fileCowPolicy = cow; + else + fileCowPolicy = new CowPolicy(CowPolicy.cowMode.NO_COW); + } + + private void setExpirationTime(long newExpTime) { + this.expTime = newExpTime; + } + + private void setWriteExpirationTime(long newExpTime) { + this.writeExpTime = newExpTime; + } + + /** + * Thread-safe method (access to final field). + * + * @return the fileId of this entry. + */ + public String getFileId() { + return this.fileId; + } + + /** + * Thread-safe method (access to final field). + * + * @return the cowPolicy of this entry. + */ + public CowPolicy getCowPolicy() { + return this.fileCowPolicy; + } + + /** + * @return if the entry has been removed from the OpenFileTable. + */ + public boolean isClosed() { + return closed; + } + + /** + * Mark that the entry has been removed from the OpenFileTable. + */ + private void setClosed() { + closed = true; + } + + /** + * Mark the file for deletion on close.
    + */ + private void setDeleteOnClose() { + deleteOnClose = true; + } + + /** + * @return true if the file should be deleted on close. + */ + public boolean isDeleteOnClose() { + return deleteOnClose; + } + + /** + * Mark pending copies on write for the file.
    + */ + private void setWrite() { + write = true; + } + + /** + * Clear the write flag once a {@link EventCreateFileVersion} has been triggered. + */ + public void clearWrite() { + write = false; + } + + /** + * @return true if the file should be copied after a write. + */ + public boolean isWrite() { + return write; + } + + public AdvisoryLock acquireLock(String client_uuid, int pid, long offset, long length, boolean exclusive) { + final String procId = getProcId(client_uuid, pid); + final AdvisoryLock l = new AdvisoryLock(offset, length, exclusive, client_uuid, pid); + if (advisoryLocks == null) { + advisoryLocks = new HashMap(); + // don't need to look for new locks here + advisoryLocks.put(procId, l); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.all, this, + "acquired lock for file %s by %s (%d-%d)", fileId, procId, offset, length); + } + + return l; + } else { + + for (Entry e : advisoryLocks.entrySet()) { + if (e.getKey().equals(procId)) + continue; + if (e.getValue().isConflicting(l)) { + assert ((e.getValue().getClientPid() != l.getClientPid()) || (!e.getValue().getClientUuid() + .equals(l.getClientUuid()))) : procId + " vs " + e.getKey(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.all, this, + "acquired for file %s by %s failed, conflickting lock by", fileId, procId, + e.getKey()); + } + return null; + } + } + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.all, this, + "acquired lock for file %s by %s (%d-%d)", fileId, procId, offset, length); + } + advisoryLocks.put(procId, l); + return l; + } + } + + public AdvisoryLock checkLock(String client_uuid, int pid, long offset, long length, boolean exclusive) { + final String procId = getProcId(client_uuid, pid); + final AdvisoryLock l = new AdvisoryLock(offset, length, exclusive, client_uuid, pid); + if (advisoryLocks == null) { + return l; + } else { + + for (Entry e : advisoryLocks.entrySet()) { + if (e.getKey().equals(procId)) + return l; + if (e.getValue().isConflicting(l)) { + return e.getValue(); + } + } + return l; + } + } + + public void unlock(String client_uuid, int pid) { + if (advisoryLocks == null) + return; + final String procId = getProcId(client_uuid, pid); + advisoryLocks.remove(procId); + } + + private static String getProcId(String clientUuid, int pid) { + return String.format("%010d%s", pid, clientUuid); + } + + @Override + public boolean equals(Object o) { + try { + final OpenFileTableEntry e = (OpenFileTableEntry) o; + if (fileId.equals(e.fileId)) { + return true; + } else { + return false; + } + } catch (ClassCastException ex) { + return false; + } + } + + @Override + public int compareTo(OpenFileTableEntry e) { + int res = 0; + if (this.expTime < e.expTime) { + res = -1; + } else if (this.expTime == e.expTime) { + res = e.fileId == null ? -1 : this.fileId.compareTo(e.fileId); + } else { + res = 1; + } + return res; + } + + public static Comparator createWriteExpComparator() { + return new Comparator() { + @Override + public int compare(OpenFileTableEntry e1, OpenFileTableEntry e2) { + + int res = 0; + if (e1.writeExpTime < e2.writeExpTime) { + res = -1; + } else if (e1.writeExpTime == e2.writeExpTime) { + res = e1.fileId == null ? -1 : e2.fileId.compareTo(e1.fileId); + } else { + res = 1; + } + return res; + } + }; + } + + @Override + public String toString() { + return "(" + fileId + "," + expTime + "ms)"; + } + + } +} diff --git a/java/servers/src/org/xtreemfs/osd/ReplicatedFileStatusJSON.java b/java/servers/src/org/xtreemfs/osd/ReplicatedFileStatusJSON.java new file mode 100644 index 0000000..58a93b1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/ReplicatedFileStatusJSON.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013 by Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +import org.xtreemfs.common.statusserver.StatusServerModule; +import org.xtreemfs.foundation.json.JSONParser; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.osd.rwre.RWReplicationStage; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; + +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; + +/** + * JSON interface returning the the list of files currently open in replication mode. + */ +public class ReplicatedFileStatusJSON extends StatusServerModule { + + private OSDRequestDispatcher myDispatcher; + + @Override + public String getDisplayName() { + return "OSD Replicated File Table JSON Interface"; + } + + @Override + public String getUriPath() { + return "/rft.json"; + } + + @Override + public boolean isAvailableForService(ServiceType service) { + return service == ServiceType.SERVICE_TYPE_OSD; + } + + @Override + public void initialize(ServiceType service, Object serviceRequestDispatcher) { + assert (service == ServiceType.SERVICE_TYPE_OSD); + myDispatcher = (OSDRequestDispatcher) serviceRequestDispatcher; + } + + @Override + public void shutdown() { + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + try { + final AtomicReference>> result = new AtomicReference>>(); + + myDispatcher.getRWReplicationStage().getStatus(new RWReplicationStage.StatusCallback() { + + @Override + public void statusComplete(Map> status) { + synchronized (result) { + result.set(status); + result.notifyAll(); + } + } + }); + synchronized (result) { + if (result.get() == null) + result.wait(); + } + + Map> status = result.get(); + String statusJSON = JSONParser.writeJSON(status); + + // set headers + Headers headers = httpExchange.getResponseHeaders(); + headers.set("Access-Control-Allow-Origin", "*"); + headers.set("Access-Control-Allow-Methods", "GET"); + headers.set("Content-Type", "application/json"); + + sendResponse(httpExchange, statusJSON); + + } catch (Throwable ex) { + Logging.logError(Logging.LEVEL_WARN, (Object) null, ex); + httpExchange.sendResponseHeaders(500, 0); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/ReplicatedFileStatusPage.java b/java/servers/src/org/xtreemfs/osd/ReplicatedFileStatusPage.java new file mode 100644 index 0000000..eade638 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/ReplicatedFileStatusPage.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012 by Bjoern Kolbeck. + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.osd; + +import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.atomic.AtomicReference; + +import org.xtreemfs.common.statusserver.StatusServerModule; +import org.xtreemfs.osd.rwre.RWReplicationStage; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; + +import com.sun.net.httpserver.HttpExchange; + +/** + * Status page showing the list of files currently open in replication mode. + * @author bjko + */ +class ReplicatedFileStatusPage extends StatusServerModule { + + private OSDRequestDispatcher myDispatcher; + + @Override + public String getDisplayName() { + return "OSD Replicated File Table"; + } + + @Override + public String getUriPath() { + return "/rft"; + } + + @Override + public boolean isAvailableForService(ServiceType service) { + return service == ServiceType.SERVICE_TYPE_OSD; + } + + @Override + public void initialize(ServiceType service, Object serviceRequestDispatcher) { + assert (service == ServiceType.SERVICE_TYPE_OSD); + myDispatcher = (OSDRequestDispatcher) serviceRequestDispatcher; + } + + @Override + public void shutdown() { + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + try { + final StringBuffer sb = new StringBuffer(); + final AtomicReference>> result + = new AtomicReference>>(); + sb.append("Replicated File Status List"); + sb.append(""); + sb.append("

    List of Open Replicated Files

    "); + sb.append(""); + sb.append(""); + myDispatcher.getRWReplicationStage().getStatus(new RWReplicationStage.StatusCallback() { + + @Override + public void statusComplete(Map> status) { + synchronized (result) { + result.set(status); + result.notifyAll(); + } + } + }); + synchronized (result) { + if (result.get() == null) + result.wait(); + } + Map> status = result.get(); + for (String fileId : status.keySet()) { + sb.append("\n"); + } + sendResponse(httpExchange, sb.toString()); + } catch (Throwable ex) { + ex.printStackTrace(); + httpExchange.sendResponseHeaders(500, 0); + } + } +} diff --git a/java/servers/src/org/xtreemfs/osd/StatusPage.java b/java/servers/src/org/xtreemfs/osd/StatusPage.java new file mode 100644 index 0000000..ed42dca --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/StatusPage.java @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2012 by Bjoern Kolbeck. + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.xtreemfs.common.statusserver.StatusServerModule; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.VersionManagement; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +import com.sun.net.httpserver.HttpExchange; + +/** + * OSD summary status page. + * @author bjko + */ +class StatusPage extends StatusServerModule { + + private enum Vars { + UUID(""), + MAXMEM(""), + FREEMEM(""), + AVAILPROCS(""), + BPSTATS(""), + PORT(""), + DIRURL(""), + DEBUG(""), + NUMCON(""), + PINKYQ(""), + PARSERQ(""), + AUTHQ(""), + STORAGEQ(""), + DELETIONQ(""), + OPENFILES(""), + OBJWRITE(""), + OBJREAD(""), + BYTETX(""), + BYTERX(""), + REPLOBJWRITE(""), + REPLBYTERX(""), + GMAXMSG(""), + GMAXRPC(""), + DELETES(""), + GLOBALTIME(""), + GLOBALRESYNC(""), + LOCALTIME(""), + LOCALRESYNC(""), + MEMSTAT(""), + UUIDCACHE(""), + STATCOLLECT(""), + DISKFREE(""), + PROTOVERSION(""), + VERSION(""); + + private String template; + + Vars(String template) { + this.template = template; + } + + public String toString() { + return template; + } + } + + private final String statusPageTemplate; + + private OSDRequestDispatcher myDispatcher; + + public StatusPage() { + StringBuffer sb = null; + try { + InputStream is = StatusPage.class.getClassLoader().getResourceAsStream( + "org/xtreemfs/osd/templates/status.html"); + if (is == null) { + is = StatusPage.class.getClass().getResourceAsStream("../templates/status.html"); + } + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + sb = new StringBuffer(); + String line = br.readLine(); + while (line != null) { + sb.append(line + "\n"); + line = br.readLine(); + } + br.close(); + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, null, ex); + } + if (sb == null) { + statusPageTemplate = "

    Template was not found, unable to show status page!

    "; + } else { + statusPageTemplate = sb.toString(); + } + } + + @Override + public String getDisplayName() { + return "OSD Status Summary"; + } + + @Override + public String getUriPath() { + return "/"; + } + + @Override + public boolean isAvailableForService(ServiceType service) { + return service == ServiceType.SERVICE_TYPE_OSD; + } + + @Override + public void initialize(ServiceType service, Object serviceRequestDispatcher) { + assert(service == ServiceType.SERVICE_TYPE_OSD); + myDispatcher = (OSDRequestDispatcher) serviceRequestDispatcher; + } + + @Override + public void shutdown() { + // Noop. + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + long globalTime = TimeSync.getGlobalTime(); + long localTime = TimeSync.getLocalSystemTime(); + + Map values = new HashMap(); + + values.put( + Vars.AVAILPROCS, + Runtime.getRuntime().availableProcessors() + " bytes"); + values.put( + Vars.FREEMEM, + Runtime.getRuntime().freeMemory() + " bytes"); + values.put( + Vars.MAXMEM, + Runtime.getRuntime().maxMemory() + " bytes"); + values.put( + Vars.BPSTATS, + BufferPool.getStatus()); + values.put( + Vars.UUID, + myDispatcher.getConfig().getUUID().toString()); + values.put( + Vars.PORT, + Integer.toString(myDispatcher.getConfig().getPort())); + values.put( + Vars.DEBUG, + Integer.toString(myDispatcher.getConfig().getDebugLevel())); + values.put( + Vars.NUMCON, + Integer.toString(myDispatcher.getNumClientConnections())); + values.put( + Vars.PINKYQ, + Long.toString(myDispatcher.getPendingRequests())); + values.put( + Vars.PARSERQ, + Integer.toString(myDispatcher.getPreprocStage().getQueueLength())); + values.put( + Vars.STORAGEQ, + Integer.toString(myDispatcher.getStorageStage().getQueueLength())); + values.put( + Vars.DELETIONQ, + Integer.toString(myDispatcher.getDeletionStage().getQueueLength())); + values.put( + Vars.OPENFILES, + Integer.toString(myDispatcher.getPreprocStage().getNumOpenFiles())); + values.put( + Vars.OBJWRITE, + Long.toString(myDispatcher.getObjectsReceived())); + values.put( + Vars.OBJREAD, + Long.toString(myDispatcher.getObjectsSent())); + values.put( + Vars.BYTETX, + OutputUtils.formatBytes(myDispatcher.getBytesSent())); + values.put( + Vars.BYTERX, + OutputUtils.formatBytes(myDispatcher.getBytesReceived())); + values.put( + Vars.REPLOBJWRITE, + Long.toString(myDispatcher.getReplicatedObjectsReceived())); + values.put( + Vars.REPLBYTERX, + OutputUtils.formatBytes(myDispatcher.getReplicatedBytesReceived())); + values.put( + Vars.DELETES, + Long.toString(myDispatcher.getDeletionStage().getNumFilesDeleted())); + values.put( + Vars.GLOBALTIME, + new Date(globalTime).toString() + " (" + globalTime + ")"); + values.put( + Vars.GLOBALRESYNC, + Long.toString(TimeSync.getTimeSyncInterval())); + values.put( + Vars.LOCALTIME, + new Date(localTime).toString() + " (" + localTime + ")"); + values.put( + Vars.LOCALRESYNC, + Long.toString(TimeSync.getLocalRenewInterval())); + values.put( + Vars.UUIDCACHE, + UUIDResolver.getCache()); + values.put( + Vars.VERSION, + VersionManagement.RELEASE_VERSION); + values.put( + Vars.PROTOVERSION, + Integer.toString(OSDServiceConstants.INTERFACE_ID)); + + String schema = Schemes.SCHEME_PBRPC; + if (myDispatcher.getConfig().isUsingSSL()) { + if (myDispatcher.getConfig().isGRIDSSLmode()) { + schema = Schemes.SCHEME_PBRPCG; + } else { + schema = Schemes.SCHEME_PBRPCS; + } + } + + values.put( + Vars.DIRURL, + schema + + "://" + + myDispatcher.getConfig().getDirectoryService().getHostName() + + ":" + + myDispatcher.getConfig().getDirectoryService().getPort()); + + + long freeMem = Runtime.getRuntime().freeMemory(); + String span = ""; + if (freeMem < 1024 * 1024 * 32) { + span = ""; + } else if (freeMem < 1024 * 1024 * 2) { + span = ""; + } + values.put( + Vars.MEMSTAT, + span + + OutputUtils.formatBytes(freeMem) + + " / " + + OutputUtils.formatBytes(Runtime.getRuntime().maxMemory()) + + " / " + + OutputUtils.formatBytes(Runtime.getRuntime().totalMemory()) + + ""); + + long freeDisk = myDispatcher.getFreeSpace(); + + span = ""; + if (freeDisk < 1024 * 1024 * 1024 * 2) { + span = ""; + } else if (freeDisk < 1024 * 1024 * 512) { + span = ""; + } + values.put( + Vars.DISKFREE, + span + + OutputUtils.formatBytes(freeDisk) + + ""); + + String html = statusPageTemplate; + for (Vars key : values.keySet()) { + html = html.replace(key.toString(), values.get(key)); + } + sendResponse(httpExchange, html); + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/drain/OSDDrain.java b/java/servers/src/org/xtreemfs/osd/drain/OSDDrain.java new file mode 100644 index 0000000..8bc1819 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/drain/OSDDrain.java @@ -0,0 +1,1382 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.drain; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.HeartbeatThread; +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.osd.drain.OSDDrainException.ErrorState; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * Class that provides function to remove a OSD by moving all his files to other OSDs. + * + * @author bzcseife + * + *
    + * Mar 17, 2011 + */ +public class OSDDrain { + + /** + * Container class for all information you need to move a file from one OSD to another. + * + *
    + * Mar 17, 2011 + */ + public static class FileInformation { + public String fileID; + + public InetSocketAddress mrcAddress; + + public FileCredentials fileCredentials; + + public Replica newReplica; + + // origReplica is necessary to restore the replicas if there is an error + // while removing the original replica + public Replica oldReplica; + + public Boolean wasAlreadyReadOnly; + + public String oldReplicationPolicy; + + // Flag to determine if consistency is preserved by the MRC on adding/removing replicas. + public boolean isReplicaChangeCoordinated = false; + } + + private DIRClient dirClient; + + private OSDServiceClient osdClient; + + private ServiceUUID osdUUID; + + private MRCServiceClient mrcClient; + + // private List mrcAddresses; + + private List fileInfos; + + private UserCredentials userCreds = RPCAuthentication.userService; + + private Auth password; + + private UUIDResolver resolver; + + public OSDDrain(DIRClient dirClient, OSDServiceClient osdClient, MRCServiceClient mrcClient, + ServiceUUID osdUUID, Auth password, UserCredentials usercreds, UUIDResolver resolver) + throws Exception { + + this.dirClient = dirClient; + this.osdClient = osdClient; + this.osdUUID = osdUUID; + this.mrcClient = mrcClient; + this.password = password; + this.userCreds = usercreds; + this.resolver = resolver; + + } + + /** + * Try to remove the OSD. + * + * @param shutdown + * If true the OSD will be shut down. Otherwise it will be locked for assigning of new files + * but is still running. + */ + public void drain(boolean shutdown) { + + try { + // set OSDServiceStatus to prevent further writing on this OSD + this.setServiceStatus(ServiceStatus.SERVICE_STATUS_TO_BE_REMOVED); + + // get all files the OSD has + fileInfos = this.getFileListOfOSD(); + + // get address of MRC which is responsible for every file + this.updateMRCAddresses(fileInfos); + + // remove fileIDs which has no entry on MRC. Can happen because + // object files on OSDs will be deleted delayed. + fileInfos = this.removeNonExistingFileIDs(fileInfos); + + // get the current replica configuration + fileInfos = this.getReplicaInfo(fileInfos); + + // Handle r/w coordinated files and remove them from the file info list. + fileInfos = drainCoordinatedFiles(fileInfos); + + // set ReplicationUpdatePolicy to RONLY + fileInfos = this.setReplicationUpdatePolicyRonly(fileInfos); + + // set Files read-only + fileInfos = this.setFilesReadOnlyAttribute(fileInfos); + + // create replications + fileInfos = this.createReplicasForFiles(fileInfos); + + // start replication + fileInfos = this.startReplication(fileInfos); + + // wait for replication to be finished + fileInfos = this.waitForReplicationToComplete(fileInfos); + + // remove replicas + this.removeOriginalFromReplica(fileInfos); + + // set every file to read/write again which wasn't set to read-only before + this.resetFilesReadOnlyAttribute(fileInfos); + + // set ReplicationUpdatePolicy to original value + this.resetReplicationUpdatePolicy(fileInfos); + + // TODO: delete all files on osd + + // shutdown osd + if (shutdown) { + this.shutdownOsd(); + } else { + System.out.println("The OSD is now locked and objects stored on it copied to other OSDs." + + " It is save to shutdown this OSD now!"); + } + + } catch (OSDDrainException e) { + this.handleException(e, true); + // set Service Status back to availalbe when an error occurs. + try { + this.setServiceStatus(ServiceStatus.SERVICE_STATUS_AVAIL); + } catch (OSDDrainException e1) { + this.handleException(e1, true); + System.out.println("Service Status couldn't set back to AVAILABLE. You have to do" + + " this yourself."); + } + } + + } + + /** + * Sets a new status to the Service with uuid. Throws Exception if something went wrong and does nothing + * if the current status is equivalent to the new status. + * + * @param uuid + * @param status + * @throws Exception + */ + public void setServiceStatus(DIR.ServiceStatus status) throws OSDDrainException { + ServiceSet sSet = null; + try { + sSet = dirClient.xtreemfs_service_get_by_uuid(null, RPCAuthentication.authNone, + RPCAuthentication.userService, osdUUID.toString()); + } catch (Exception e) { + Logging.logError(Logging.LEVEL_WARN, this, e); + throw new OSDDrainException(e.getMessage(), ErrorState.SET_SERVICE_STATUS); + } + + if (sSet.getServicesCount() == 0) { + System.out.println("no OSD with UUID " + this.osdUUID + " registered at directory service"); + System.exit(1); + } + + Service serv = sSet.getServices(0); + String serviceStatus = KeyValuePairs.getValue(serv.getData().getDataList(), + HeartbeatThread.STATUS_ATTR); + + if (serviceStatus == null) { + System.out.println("Service " + this.osdUUID + " is not registered at DIR."); + System.exit(3); + } + + if (Integer.valueOf(serviceStatus) == status.getNumber()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.tool, status, + "Service %s is already in status %s ", this.osdUUID, status.name()); + return; + } + + // Build new Service with status= SERVICE_STATUS_TO_BE_REMOVED and + // update DIR + List data = serv.getData().getDataList(); + + List data2 = new LinkedList(); + + for (KeyValuePair kvp : data) { + data2.add(KeyValuePair.newBuilder().setKey(kvp.getKey()).setValue(kvp.getValue()).build()); + } + + KeyValuePairs.putValue(data2, HeartbeatThread.STATUS_ATTR, Integer.toString(status.ordinal())); + KeyValuePairs.putValue(data2, HeartbeatThread.DO_NOT_SET_LAST_UPDATED, Boolean.toString(true)); + + ServiceDataMap dataMap = ServiceDataMap.newBuilder().addAllData(data2).build(); + + serv = serv.toBuilder().setData(dataMap).build(); + + try { + dirClient.xtreemfs_service_register(null, RPCAuthentication.authNone, + RPCAuthentication.userService, serv); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException(e.getMessage(), ErrorState.SET_SERVICE_STATUS); + } + } + + /** + * Returns a {@link LinkedList} of all fileIDs the OSD which will be removed has + * + * @return {@link LinkedList} + * @throws Exception + */ + public LinkedList getFileListOfOSD() throws OSDDrainException { + + LinkedList osdFileList = new LinkedList(); + + RPCResponse resp = null; + xtreemfs_internal_get_fileid_listResponse fileIDList = null; + try { + resp = osdClient.xtreemfs_internal_get_fileid_list(osdUUID.getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService); + fileIDList = resp.get(); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException(e.getMessage(), ErrorState.GET_FILE_LIST); + } finally { + if (resp != null) + resp.freeBuffers(); + } + + for (String fileID : fileIDList.getFileIdsList()) { + FileInformation info = new FileInformation(); + info.fileID = fileID; + osdFileList.push(info); + } + + return osdFileList; + } + + /** + * Get for every fileID in fileInfos the mrcAddress of the MRC responsible for this file. + * + * @param fileInfos + */ + public void updateMRCAddresses(List fileInfos) throws OSDDrainException { + for (FileInformation fileInfo : fileInfos) { + + String volumeUUID = fileInfo.fileID.substring(0, fileInfo.fileID.indexOf(':')); + + ServiceSet sSet = null; + String mrcUUIDString = null; + try { + sSet = dirClient.xtreemfs_service_get_by_uuid(null, password, userCreds, volumeUUID); + for (KeyValuePair kvp : sSet.getServices(0).getData().getDataList()) { + if (kvp.getKey().equals("mrc")) + mrcUUIDString = kvp.getValue(); + } + assert (mrcUUIDString != null); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException(e.getMessage(), ErrorState.UPDATE_MRC_ADDRESSES); + } + + try { + AddressMappingSet ams = dirClient.xtreemfs_address_mappings_get(null, password, userCreds, + mrcUUIDString); + + assert (ams != null); + assert (ams.getMappings(0).getUuid().equalsIgnoreCase(mrcUUIDString)); + InetAddress inetAddr = InetAddress.getByName(ams.getMappings(0).getAddress()); + fileInfo.mrcAddress = new InetSocketAddress(inetAddr, ams.getMappings(0).getPort()); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException(e.getMessage(), ErrorState.UPDATE_MRC_ADDRESSES); + } + + } + } + + /** + * Creates a new List without fileIDs which are available on the OSD but have no corresponding + * metadata entry on the MRC. This can happen because on file deletion the object file will be removed + * later than the metadata. + * + * @param fileInfos + * @return List of FilInformation with non-existing files removed. + */ + public List removeNonExistingFileIDs(List fileInfos) { + + List returnList = new LinkedList(); + + // Map with VolumeName as key and sublist of fileInfos as value. Used to decrease the amount of MRC queries. + Map> callMap = new HashMap>(); + // Map to store VolID-> MRCAddress Mapping to know which MRC has to be called. + Map volIDMrcAddressMapping = new HashMap(); + + for (FileInformation fileInfo : fileInfos) { + String volumeID = fileInfo.fileID.substring(0, fileInfo.fileID.indexOf(':')); + if (!callMap.containsKey(volumeID)) { + callMap.put(volumeID, new LinkedList()); + volIDMrcAddressMapping.put(volumeID, fileInfo.mrcAddress); + } + + callMap.get(volumeID).add(fileInfo); + } + + xtreemfs_check_file_existsRequest.Builder fileExistsRequest = null; + for (Map.Entry> entry : callMap.entrySet()) { + fileExistsRequest = xtreemfs_check_file_existsRequest.newBuilder().setVolumeId(entry.getKey()) + .setOsdUuid(osdUUID.toString()); + + for (FileInformation fi : entry.getValue()) { + fileExistsRequest.addFileIds(fi.fileID.substring(fi.fileID.indexOf(":") + 1)); + } + + RPCResponse r = null; + xtreemfs_check_file_existsResponse response = null; + try { + r = mrcClient.xtreemfs_check_file_exists(volIDMrcAddressMapping.get(entry.getKey()), + password, userCreds, fileExistsRequest.build()); + response = r.get(); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + } finally { + if (r != null) { + r.freeBuffers(); + } + } + + assert (response.getVolumeExists()); + + for (int i = 0; i < response.getFileStatesCount(); i++) { + if (response.getFileStates(i) == FILE_STATE.REGISTERED) { + returnList.add(entry.getValue().get(i)); + } + } + } + return returnList; + } + + /** + * Get the current replica information from the MRC for every fileID in fileIDList. + * + * @param fileInfos + * @throws OSDDrainException + */ + public List getReplicaInfo(List fileInfos) throws OSDDrainException { + LinkedList finishedFileInfos = new LinkedList(); + + for (FileInformation fileInfo : fileInfos) { + + // get Striping Policy + RPCResponse xlocsetResp = null; + XLocSet xlocset = null; + try { + + xtreemfs_get_xlocsetRequest xlocReq = xtreemfs_get_xlocsetRequest.newBuilder() + .setFileId(fileInfo.fileID).build(); + xlocsetResp = mrcClient + .xtreemfs_get_xlocset(fileInfo.mrcAddress, password, userCreds, xlocReq); + xlocset = xlocsetResp.get(); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException(e.getMessage(), ErrorState.GET_REPLICA_INFO, fileInfos, + finishedFileInfos); + } finally { + if (xlocsetResp != null) + xlocsetResp.freeBuffers(); + } + + // TODO(jdillmann): Use centralized method to check if a lease is required. + fileInfo.isReplicaChangeCoordinated = (xlocset.getReplicasCount() > 1 + && ReplicaUpdatePolicies.isRwReplicated(xlocset.getReplicaUpdatePolicy())); + + // find the replica for the given UUID + for (Replica replica : xlocset.getReplicasList()) { + if (replica.getOsdUuidsList().contains(osdUUID.toString())) { + fileInfo.oldReplica = replica; + } + } + assert (fileInfo.oldReplica != null); + + finishedFileInfos.add(fileInfo); + } + + return finishedFileInfos; + } + + /** + * Handle files that are guaranteed to retain safe when adding or removing replicas + * because they are coordinated by the MRC. At the moment this is done for r/w replicated + * files. + * @param fileInfos List of files to move from the OSD. + * @return List of files not coordinated by the MRC. + */ + public List drainCoordinatedFiles(List fileInfos) throws OSDDrainException { + LinkedList uncoordinatedFiles = new LinkedList(); + LinkedList finishedFiles = new LinkedList(); + + for (FileInformation fileInfo : fileInfos) { + // Filter uncoordinated files. + if (!fileInfo.isReplicaChangeCoordinated) { + uncoordinatedFiles.add(fileInfo); + continue; + } + + // Create a new replica. + Replica replica; + try { + replica = createReplicaForFile(fileInfo); + fileInfo.newReplica = replica; + } catch (OSDDrainException e) { + String message = "Could not create a replica for file with id: " + fileInfo.fileID + "\n" + + "It is safe to call xtfs_remove_osd again.\n" + + "Original error was:\n" + e.getMessage(); + throw new OSDDrainException(message, ErrorState.DRAIN_COORDINATED); + } + + // Add the replica. + try { + addReplicaToFile(fileInfo, fileInfo.newReplica); + } catch (OSDDrainException e) { + String message = "Could not add replica for file with id: " + fileInfo.fileID + "\n" + + "It is safe to call xtfs_remove_osd again.\n" + + "Original error was:\n" + e.getMessage(); + throw new OSDDrainException(message, ErrorState.DRAIN_COORDINATED); + } + + // Remove the replica on the drained OSD. + try { + removeReplica(fileInfo, fileInfo.oldReplica); + } catch (OSDDrainException e) { + // In case the old replica could not be removed inform the user to intervene manually before redraining. + // TODO(jdillmann): resolve fileID to path + String message = "Could not remove the replica for file with id: " + fileInfo.fileID + + " from the OSD: " + osdUUID.toString() + "\n" + + "It is NOT SAFE to call xtfs_remove_osd again. Please remove the replica manually before " + + "continuing.\n" + + "Original error was:\n" + e.getMessage(); + throw new OSDDrainException(message, ErrorState.DRAIN_COORDINATED); + } + + finishedFiles.add(fileInfo); + } + + return uncoordinatedFiles; + } + + /** + * Create a new Replica for every fileID in fileIDList on a new OSD. OSDs will be chosen by get_suitable_osds MRC + * call. + * + * @param fileIDList + * @throws Exception + */ + public List createReplicasForFiles(List fileInfos) throws OSDDrainException { + + LinkedList finishedFileInfos = new LinkedList(); + + for (FileInformation fileInfo : fileInfos) { + try { + Replica replica = createReplicaForFile(fileInfo); + fileInfo.newReplica = replica; + + addReplicaToFile(fileInfo, replica); + finishedFileInfos.add(fileInfo); + + } catch (OSDDrainException e) { + throw new OSDDrainException(e.getMessage(), ErrorState.CREATE_REPLICAS, fileInfos, finishedFileInfos); + } + } + + return finishedFileInfos; + } + + private Replica createReplicaForFile(FileInformation fileInfo) throws OSDDrainException { + // Get a suitable OSD for the new replica. + RPCResponse suitable_osdsResponseRPCResponse = null; + xtreemfs_get_suitable_osdsResponse suitable_osdsResponse; + try { + xtreemfs_get_suitable_osdsRequest suitable_osdsRequest; + suitable_osdsRequest = xtreemfs_get_suitable_osdsRequest.newBuilder() + .setFileId(fileInfo.fileID) + .setNumOsds(1) + .build(); + suitable_osdsResponseRPCResponse = mrcClient.xtreemfs_get_suitable_osds( + fileInfo.mrcAddress, password, userCreds, suitable_osdsRequest); + suitable_osdsResponse = suitable_osdsResponseRPCResponse.get(); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException("Could not get suitable OSDs for file with id: " + fileInfo.fileID, + ErrorState.CREATE_REPLICAS); + } finally { + if (suitable_osdsResponseRPCResponse != null) { + suitable_osdsResponseRPCResponse.freeBuffers(); + } + } + + if (suitable_osdsResponse.getOsdUuidsCount() == 0) { + throw new OSDDrainException("No suitable OSDs to replicate file with id: " + fileInfo.fileID, + ErrorState.CREATE_REPLICAS); + } + + // build new Replica + // TODO: set stripe-width to 1 or decide what to do with stripe-width greater than 1 (if stripe-width is + // greater than 1 all OSDs used in one of the other replicas couldn't be used again) + // current solution is to use '1' for the striping width + StripingPolicy oldSP = fileInfo.oldReplica.getStripingPolicy(); + StripingPolicy newSP = StripingPolicy.newBuilder() + .setType(oldSP.getType()) + .setStripeSize(oldSP.getStripeSize()) + .setWidth(1) + .build(); + Replica.Builder replica = Replica.newBuilder() + .addOsdUuids(suitable_osdsResponse.getOsdUuids(0)) + .setStripingPolicy(newSP); + + if (fileInfo.isReplicaChangeCoordinated) { + replica.setReplicationFlags(0); + } else { + replica.setReplicationFlags(ReplicationFlags.setRandomStrategy(ReplicationFlags.setFullReplica(0))); + } + + return replica.build(); + } + + private void addReplicaToFile(FileInformation fileInfo, Replica replica) throws OSDDrainException { + RPCResponse response = null; + try { + xtreemfs_replica_addRequest replica_addRequest = xtreemfs_replica_addRequest.newBuilder() + .setFileId(fileInfo.fileID) + .setNewReplica(replica) + .build(); + response = mrcClient.xtreemfs_replica_add(fileInfo.mrcAddress, password, userCreds, + replica_addRequest); + response.get(); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException("Could not add replica to file with id" + fileInfo.fileID, + ErrorState.CREATE_REPLICAS); + } finally { + if (response != null) { + response.freeBuffers(); + } + } + } + + /** + * Set ReplicationUpdatePolicy to RONLY for all files in fileInfos.
    + * + * @param fileInfos + * @return + * @throws Exception + */ + public List setReplicationUpdatePolicyRonly(List fileInfos) + throws OSDDrainException { + + List finishedFileInfos = new LinkedList(); + + for (FileInformation fileInfo : fileInfos) { + try { + fileInfo.oldReplicationPolicy = changeReplicationUpdatePolicy(fileInfo, + ReplicaUpdatePolicies + .REPL_UPDATE_PC_RONLY); + finishedFileInfos.add(fileInfo); + } catch (Exception e) { + throw new OSDDrainException(e.getMessage(), ErrorState.SET_UPDATE_POLICY, fileInfos, + finishedFileInfos); + } + } + + return finishedFileInfos; + } + + /** + * Set ReplicationUpdatePolicy to the initial value according to FileInformation.oldReplicationPolicy for all files + * in fileInfos. + * + * @return + */ + public List resetReplicationUpdatePolicy(List fileInfos) + throws OSDDrainException { + + // List of files which ReplicationUpdatePolicy is already set successfully + List finishedFileInfos = new LinkedList(); + // List of files which could not be reset. + List erroneousFiles = new LinkedList(); + + for (FileInformation fileInfo : fileInfos) { + try { + fileInfo.oldReplicationPolicy = this.changeReplicationUpdatePolicy(fileInfo, + fileInfo.oldReplicationPolicy); + finishedFileInfos.add(fileInfo); + } catch (Exception e) { + erroneousFiles.add(fileInfo); + } + } + + if (!erroneousFiles.isEmpty()) { + throw new OSDDrainException("Failed to reset read only attribute for some files.", + ErrorState.UNSET_UPDATE_POLICY, fileInfos, finishedFileInfos); + } + + return finishedFileInfos; + } + + private String changeReplicationUpdatePolicy(FileInformation fileInfo, String policy) throws Exception { + + RPCResponse respRepl = null; + xtreemfs_set_replica_update_policyResponse replSetResponse = null; + try { + respRepl = mrcClient.xtreemfs_set_replica_update_policy(fileInfo.mrcAddress, password, userCreds, + fileInfo.fileID, policy); + replSetResponse = respRepl.get(); + } catch (Exception ioe) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, ioe); + } + throw ioe; + } finally { + if (respRepl != null) + respRepl.freeBuffers(); + } + + return replSetResponse.getOldUpdatePolicy(); + } + + /** + * Set all files in fileIDList to read-only to be able to RO-replicate them.
    + * + * @param fileIDList + * @param mode + * true if you want to set the files to read-only mode, false otherwise + * @throws Exception + * + * @return {@link LinkedList} with all fileIDs which already were set to the desired mode + */ + public List setFilesReadOnlyAttribute(List fileInfos) throws OSDDrainException { + + // List of files which where set to read-only successfully + List finishedFileInfos = new LinkedList(); + + for (FileInformation fileInfo : fileInfos) { + try { + fileInfo.wasAlreadyReadOnly = setFileReadOnlyAttribute(fileInfo, true); + } catch (OSDDrainException e) { + throw new OSDDrainException(e.getMessage(), ErrorState.SET_RONLY, fileInfos, finishedFileInfos); + } + finishedFileInfos.add(fileInfo); + } + + return finishedFileInfos; + } + + /** + * Reset the files read only attributes to the original value + * @param fileInfos + * @return + * @throws OSDDrainException + */ + public List resetFilesReadOnlyAttribute(List fileInfos) throws OSDDrainException { + // List of files which where reset successfully. + List finishedFileInfos = new LinkedList(); + // List of files which could not be reset. + List erroneousFiles = new LinkedList(); + + for (FileInformation fileInfo : fileInfos) { + // Skip files that have been read only before draining. + if (fileInfo.wasAlreadyReadOnly) { + finishedFileInfos.add(fileInfo); + continue; + } + + try { + setFileReadOnlyAttribute(fileInfo, false); + finishedFileInfos.add(fileInfo); + } catch (OSDDrainException e) { + erroneousFiles.add(fileInfo); + } + } + + if (!erroneousFiles.isEmpty()) { + throw new OSDDrainException("Failed to reset read only attribute for some files.", ErrorState.UNSET_RONLY, + fileInfos, finishedFileInfos); + } + + return finishedFileInfos; + } + + /** + * Set the read-only attribute for a single file. + * + * @param fileInfo + * @param mode + * @return true if the read-only attribute had been already set to the requested mode. + * @throws OSDDrainException + */ + boolean setFileReadOnlyAttribute(FileInformation fileInfo, boolean mode) throws OSDDrainException { + RPCResponse response = null; + xtreemfs_set_read_only_xattrResponse setResponse = null; + try { + response = mrcClient + .xtreemfs_set_read_only_xattr(fileInfo.mrcAddress, password, userCreds, fileInfo.fileID, mode); + setResponse = response.get(); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException(e.getMessage(), ErrorState.SET_RONLY); + } finally { + if (response != null) + response.freeBuffers(); + } + + return (!setResponse.getWasSet()); + } + + /** + * Read one byte from every file in fileInfo list to trigger replication. The byte will be read from the first + * object on OSD(s) containing the new replica. + * + * @param fileInfos + * @return + * @throws Exception + */ + public List startReplication(List fileInfos) throws OSDDrainException { + + List finishedFileInfos = new LinkedList(); + + for (FileInformation fileInfo : fileInfos) { + // get FileCredentials to be able to read from the file + RPCResponse r1 = null; + try { + r1 = mrcClient.xtreemfs_get_file_credentials(fileInfo.mrcAddress, password, userCreds, + fileInfo.fileID); + fileInfo.fileCredentials = r1.get(); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException(e.getMessage(), ErrorState.WAIT_FOR_REPLICATION, fileInfos, + finishedFileInfos); + } finally { + if (r1 != null) + r1.freeBuffers(); + } + + + // read a single Byte from one object of every OSD the new replica + // is assigned to to trigger replication + StripingPolicyImpl spol = StripingPolicyImpl.getPolicy(fileInfo.newReplica, 0); + for (int i = 0; i < fileInfo.newReplica.getOsdUuidsCount(); i++) { + + Iterator objs = spol.getObjectsOfOSD(i, 0, Long.MAX_VALUE); + long obj = objs.next(); + + RPCResponse r2 = null; + try { + InetSocketAddress osd = new ServiceUUID(fileInfo.newReplica.getOsdUuids(i), resolver) + .getAddress(); + r2 = osdClient.read(osd, password, userCreds, fileInfo.fileCredentials, fileInfo.fileID, + obj, 0, 0, 1); + r2.get(); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException(e.getMessage(), ErrorState.WAIT_FOR_REPLICATION, fileInfos, + finishedFileInfos); + } finally { + if (r2 != null) + r2.freeBuffers(); + } + + } + + finishedFileInfos.add(fileInfo); + } + return fileInfos; + } + + /** + * Polls MRC regularly to discover if replication is complete. Blocks until this event happens. + * + * @param fileIDList + * @throws Exception + */ + public List waitForReplicationToComplete(List fileInfos) + throws OSDDrainException { + + List finishedFileInfos = new LinkedList(); + List toBeRemovedFileInfos = new LinkedList(); + + while (!fileInfos.isEmpty()) { + for (FileInformation fileInfo : fileInfos) { + String fileID = fileInfo.fileID; + FileCredentials fc = fileInfo.fileCredentials; + Replica replica = fileInfo.newReplica; + + boolean isReplicated = true; + + StripingPolicyImpl sp = StripingPolicyImpl.getPolicy(replica, 0); + long lastObjectNo = sp.getObjectNoForOffset(fc.getXlocs().getReadOnlyFileSize() - 1); + + int osdRelPos = 0; + for (String osdUUID : replica.getOsdUuidsList()) { + + RPCResponse r = null; + ObjectSet oSet = null; + try { + InetSocketAddress osdAddress = new ServiceUUID(osdUUID, resolver).getAddress(); + + r = osdClient.xtreemfs_internal_get_object_set(osdAddress, password, userCreds, fc, + fileID); + ObjectList ol = r.get(); + + byte[] serializedBitSet = ol.getSet().toByteArray(); + oSet = new ObjectSet(sp.getWidth(), osdRelPos, serializedBitSet); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + List allInfos = new LinkedList(); + allInfos.addAll(fileInfos); + allInfos.addAll(finishedFileInfos); + throw new OSDDrainException(e.getMessage(), ErrorState.WAIT_FOR_REPLICATION, + finishedFileInfos, allInfos); + } finally { + if (r != null) { + r.freeBuffers(); + } + } + for (long objNo = osdRelPos; objNo <= lastObjectNo; objNo += sp.getWidth()) { + if (oSet.contains(objNo) == false) + isReplicated = false; + } + } + + // TODO: Set is replicated Flag if replication is complete + if (isReplicated) { + toBeRemovedFileInfos.add(fileInfo); + finishedFileInfos.add(fileInfo); + } + + } + + fileInfos.removeAll(toBeRemovedFileInfos); + toBeRemovedFileInfos.clear(); + + if (fileInfos.isEmpty()) + return finishedFileInfos; + + Logging.logMessage(Logging.LEVEL_INFO, Category.tool, this, + "waiting 10secs for replication to be finished"); + try { + // wait 10sec until next poll + Thread.sleep(5000); + } catch (Exception e) { + // ignore + } + } + return finishedFileInfos; + } + + /** + * removes replicas of all file in fileIDList which are on osdUUID + * + * @param fileIDList + * @param mrc + * @param osdUUID + * @throws InterruptedException + * @throws IOException + */ + public void removeOriginalFromReplica(List fileInfos) throws OSDDrainException { + + List finishedFileInfos = new LinkedList(); + List erroneousFiles = new LinkedList(); + + for (FileInformation fileInfo : fileInfos) { + try { + removeReplica(fileInfo, fileInfo.oldReplica); + finishedFileInfos.add(fileInfo); + } catch (OSDDrainException e) { + erroneousFiles.add(fileInfo); + } + } + + if (!erroneousFiles.isEmpty()) { + throw new OSDDrainException("Failed to remove original replicas for some files.\n" + + "It is NOT SAFE to call xtfs_remove_osd again. Please remove the " + + "replicas manually before continuing.", + ErrorState.REMOVE_REPLICAS, fileInfos, finishedFileInfos); + } + } + + private void removeReplica(FileInformation fileInfo, Replica replica) throws OSDDrainException { + RPCResponse response = null; + + String headOSD = replica.getOsdUuids(0); + xtreemfs_replica_removeRequest replica_removeRequest; + replica_removeRequest = xtreemfs_replica_removeRequest.newBuilder() + .setFileId(fileInfo.fileID) + .setOsdUuid(headOSD) + .build(); + try { + response = mrcClient + .xtreemfs_replica_remove(fileInfo.mrcAddress, password, userCreds, replica_removeRequest); + response.get(); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException(e.getMessage(), ErrorState.REMOVE_REPLICAS); + } finally { + if (response != null) + response.freeBuffers(); + } + } + + /** + * Shuts down the OSD which should be removed. + */ + void shutdownOsd() throws OSDDrainException { + + RPCResponse r = null; + try { + r = osdClient.xtreemfs_shutdown(osdUUID.getAddress(), password, userCreds); + r.get(); + } catch (Exception e) { + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_WARN, this, e); + } + throw new OSDDrainException(e.getMessage(), ErrorState.SHUTDOWN_OSD); + } finally { + if (r != null) + r.freeBuffers(); + } + } + + /** + * Create original replicas again if the where removed before. Only used if an error occurs while removing + * original replicas. + */ + private void revertRemoveOriginalReplicas(List fileInfos) throws OSDDrainException { + + List finishedFileInfos = new LinkedList(); + List erroneousFiles = new LinkedList(); + + for (FileInformation fileInfo : fileInfos) { + try { + if (fileInfo.oldReplica != null) { + addReplicaToFile(fileInfo, fileInfo.oldReplica); + } + finishedFileInfos.add(fileInfo); + + } catch (OSDDrainException e) { + erroneousFiles.add(fileInfo); + } + } + + if (!erroneousFiles.isEmpty()) { + throw new OSDDrainException("Failed to recreate original replicas for some files.\n" + + "It is NOT SAFE to call xtfs_remove_osd again. Please ensure the " + + "files are properly replicated before continuing.", + ErrorState.CREATE_REPLICAS, fileInfos, finishedFileInfos); + } + } + + /** + * Remove the newly created replicas. Only used if an error occurs while creating the replicas. + * + * @param fileInfos + * @throws OSDDrainException + */ + private void removeNewReplicas(List fileInfos) throws OSDDrainException { + + List finishedFileInfos = new LinkedList(); + List erroneousFiles = new LinkedList(); + + for (FileInformation fileInfo : fileInfos) { + try { + if (fileInfo.newReplica != null) { + removeReplica(fileInfo, fileInfo.newReplica); + } + finishedFileInfos.add(fileInfo); + + } catch (OSDDrainException e) { + erroneousFiles.add(fileInfo); + } + } + + if (!erroneousFiles.isEmpty()) { + throw new OSDDrainException("Failed to remove new replicas for some files.\n" + + "It is NOT SAFE to call xtfs_remove_osd again. Please remove the " + + "replicas manually before continuing.", + ErrorState.CREATE_REPLICAS, fileInfos, finishedFileInfos); + } + } + + /** + * Handles all errors that can occur while removing an OSD. On error it tries to revert all changes that + * are done since the error occurred by recursively calling itself. If another error occurs on this + * procedure it prints changes that were made and not be reverted correctly. + * + * @param ex + * - {@link OSDDrainException} that should be handled + * @param printError + * - true if an error Message should be printed. First call should be true, all other recursive + * calls should be false. + */ + public void handleException(OSDDrainException ex, boolean printError) { + switch (ex.getErrorState()) { + case INITIALIZATION: + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, + "Failed to initialize connection"); + printError(); + } + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + } + break; + + case GET_FILE_LIST: + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, + "Failed to get filelist from OSD"); + printError(); + } + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + } + break; + + case UPDATE_MRC_ADDRESSES: + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, + "Failed to get all MRC Addresses from DIR"); + printError(); + } + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + } + break; + + case REMOVE_NON_EXISTING_IDS: + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, + "Failed to check if files exist on MRC"); + printError(); + } + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + break; + + case GET_REPLICA_INFO: + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, + "Failed to to get replica info from MRC"); + printError(); + } + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + break; + + case SET_SERVICE_STATUS: + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, + "ERROR: failed to set ServiceStatus for OSD"); + printError(); + } + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + break; + + case DRAIN_COORDINATED: + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, ex.getMessage()); + printError(); + } + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + break; + + case SET_UPDATE_POLICY: + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, + "Failed to set ReplicationUpdatePolicies"); + printError(); + } + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + + Logging.logMessage(Logging.LEVEL_INFO, Category.tool, this, + "Trying to revert ReplicationUpdatePolicy changes..."); + try { + this.resetReplicationUpdatePolicy(ex.getFileInfosCurrent()); + Logging.logMessage(Logging.LEVEL_INFO, Category.tool, this, + "DONE reverting ReplicationUpdatePolicy changes"); + } catch (OSDDrainException ode) { + List failedFileInfos = ode.getFileInfosAll(); + failedFileInfos.removeAll(ode.getFileInfosCurrent()); + String error = "Following files couldn't set back its originial " + + "ReplicationUpdatePolicy due to errors:"; + for (FileInformation fileInfo : failedFileInfos) { + error = error + "\n " + fileInfo.fileID; + } + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, error); + } + break; + + case SET_RONLY: + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, "Failed to set files read-only"); + printError(); + } + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + + Logging.logMessage(Logging.LEVEL_INFO, Category.tool, this, + "Trying to revert read-only mode changes..."); + try { + resetFilesReadOnlyAttribute(ex.getFileInfosCurrent()); + Logging.logMessage(Logging.LEVEL_INFO, Category.tool, this, + "DONE reverting read-only mode changes"); + } catch (OSDDrainException ode) { + List failedFileInfos = ode.getFileInfosAll(); + failedFileInfos.removeAll(ode.getFileInfosCurrent()); + String error = "Following files couldn't set back its originial read-only mode:"; + for (FileInformation fileInfo : failedFileInfos) { + error = error + "\n " + fileInfo.fileID; + } + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, error); + } + + this.handleException( + new OSDDrainException(ex.getMessage(), ErrorState.SET_UPDATE_POLICY, + ex.getFileInfosAll(), ex.getFileInfosAll()), false); + break; + + case CREATE_REPLICAS: + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, "Failed to create new replicas"); + printError(); + } + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + + Logging.logMessage(Logging.LEVEL_INFO, Category.tool, this, "Trying to revert replica changes..."); + try { + this.removeNewReplicas(ex.getFileInfosCurrent()); + Logging.logMessage(Logging.LEVEL_INFO, Category.tool, this, "DONE reverting replica changes"); + } catch (OSDDrainException ode) { + List failedFileInfos = ode.getFileInfosAll(); + failedFileInfos.removeAll(ode.getFileInfosCurrent()); + String error = ex.getMessage() + "\n" + + "From following files the newly created replicas couldn't be removed:"; + for (FileInformation fileInfo : failedFileInfos) { + error = error + "\n " + fileInfo.fileID; + } + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, error); + } + + this.handleException( + new OSDDrainException(ex.getMessage(), ErrorState.SET_RONLY, ex.getFileInfosAll(), ex + .getFileInfosAll()), false); + break; + + case WAIT_FOR_REPLICATION: + if (printError) { + + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, "Failed to replicate files"); + printError(); + } + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + + Logging.logMessage(Logging.LEVEL_INFO, Category.tool, this, "Trying to remove yet replicated files..."); + try { + this.removeNewReplicas(ex.getFileInfosAll()); + Logging.logMessage(Logging.LEVEL_INFO, Category.tool, this, "DONE removing yet replicated files"); + } catch (OSDDrainException ode) { + List failedFileInfos = ode.getFileInfosAll(); + failedFileInfos.removeAll(ode.getFileInfosCurrent()); + String error = ex.getMessage() + "\n" + + "From following files the newly created replicas couldn't be removed:"; + for (FileInformation fileInfo : failedFileInfos) { + error = error + "\n " + fileInfo.fileID; + } + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, error); + } + this.handleException( + new OSDDrainException(ex.getMessage(), ErrorState.SET_RONLY, ex.getFileInfosAll(), ex + .getFileInfosAll()), false); + + break; + + case REMOVE_REPLICAS: + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, + "Failed to remove original replicas"); + printError(); + } + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + + Logging.logMessage(Logging.LEVEL_INFO, Category.tool, this, + "Trying to revert original replica changes..."); + try { + this.revertRemoveOriginalReplicas(ex.getFileInfosCurrent()); + Logging.logMessage(Logging.LEVEL_INFO, Category.tool, this, + "DONE removing original replicate changes"); + } catch (OSDDrainException ode) { + List failedFileInfos = ode.getFileInfosAll(); + failedFileInfos.removeAll(ode.getFileInfosCurrent()); + String error = ex.getMessage() + "\n" + + "From the following files the changes to the original replica couldn't be reverted:"; + for (FileInformation fileInfo : failedFileInfos) { + error = error + "\n " + fileInfo.fileID; + } + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, error); + } + this.handleException( + new OSDDrainException(ex.getMessage(), ErrorState.CREATE_REPLICAS, ex.getFileInfosAll(), + ex.getFileInfosAll()), false); + break; + + case UNSET_RONLY: { + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, + "Failed to set files back from read-only mode"); + printError(); + } + if (Logging.isDebug()) + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + + List failedFileInfos = ex.getFileInfosAll(); + failedFileInfos.removeAll(ex.getFileInfosCurrent()); + String error = "Following files couldn't set back to read-only mode:"; + for (FileInformation fileInfo : failedFileInfos) { + error = error + "\n " + fileInfo.fileID; + } + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, error); + + this.handleException( + new OSDDrainException(ex.getMessage(), ErrorState.REMOVE_REPLICAS, ex.getFileInfosAll(), + ex.getFileInfosAll()), false); + break; + } + + case UNSET_UPDATE_POLICY: { + if (printError) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, + "Failed to set ReplicationUpdatePolicy back to the original ones"); + printError(); + } + + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + } + + List failedFileInfos = ex.getFileInfosAll(); + failedFileInfos.removeAll(ex.getFileInfosCurrent()); + String error = "For the following files the changes to ReplicationUpdatePolicy couldn't be reverted:"; + for (FileInformation fileInfo : failedFileInfos) { + error = error + "\n " + fileInfo.fileID; + } + Logging.logMessage(Logging.LEVEL_ERROR, Category.tool, this, error); + + // Rollback only the failed files. + this.handleException( + new OSDDrainException(ex.getMessage(), ErrorState.REMOVE_REPLICAS, failedFileInfos, + failedFileInfos), false); + + break; + } + + case SHUTDOWN_OSD: + if (printError) { + Logging.logMessage(Logging.LEVEL_WARN, Category.tool, this, + "Couldn't shut down OSD with UUID=" + this.osdUUID.toString() + + " but all object files are moved to other OSDs. It's safe to shutdown this OSD now."); + System.out.println("WARNING: Couldn't shut down OSD with UUID=" + this.osdUUID.toString() + + " but all object files are moved to other OSDs. It's safe to shutdown this OSD now."); + } + if (Logging.isDebug()) { + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + } + break; + + default: + break; + } + } + + private void printError() { + System.err.println("ERROR: An error accured during the OSD drain process. See logging output" + + "for details. It is NOT save to shutdown the OSD."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/drain/OSDDrainException.java b/java/servers/src/org/xtreemfs/osd/drain/OSDDrainException.java new file mode 100644 index 0000000..2745324 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/drain/OSDDrainException.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.drain; + +import java.util.List; + +import org.xtreemfs.osd.drain.OSDDrain.FileInformation; + +/** + * @author bzcseife + * + *
    Mar 31, 2011 + */ + +public class OSDDrainException extends Exception { + + + + public enum ErrorState { + INITIALIZATION, + SET_SERVICE_STATUS, + GET_FILE_LIST, + UPDATE_MRC_ADDRESSES, + REMOVE_NON_EXISTING_IDS, + GET_REPLICA_INFO, + DRAIN_COORDINATED, + SET_UPDATE_POLICY, + SET_RONLY, + CREATE_REPLICAS, + START_REPLICATION, + WAIT_FOR_REPLICATION, + REMOVE_REPLICAS, + UNSET_RONLY, + UNSET_UPDATE_POLICY, + DELETE_FILES, + SHUTDOWN_OSD + } + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * List of FileInfos from all files that has to be moved to another OSD to remove this OSD. + * For these files the operations which are done the ErrorState has to be reverted. + */ + private List fileInfosAll; + + /** + * List of FileInfos from files that where correctly processed in the current step before the + * error occurred. For these files the operation which is done in the ErrorState has to be reverted. + */ + private List fileInfosCurrent; + private ErrorState errorState; + + + public void setErrorState(ErrorState errorState) { + this.errorState = errorState; + } + + public OSDDrainException(String message, ErrorState errorState) { + super(message); + this.errorState = errorState; + this.fileInfosAll = null; + this.fileInfosCurrent = null; + + }; + + public OSDDrainException(String message, ErrorState errorState, List fileInfosAll) { + super(message); + this.fileInfosAll = fileInfosAll; + this.fileInfosCurrent = null; + }; + + public OSDDrainException(String message, ErrorState errorState, List fileInfosAll, + List fileInfosCurrent) { + super(message); + this.errorState = errorState; + this.fileInfosAll = fileInfosAll; + this.fileInfosCurrent = fileInfosCurrent; + } + + public List getFileInfosAll() { + return fileInfosAll; + } + + public void setFileInfosAll(List fileInfosAll) { + this.fileInfosAll = fileInfosAll; + } + + public List getFileInfosCurrent() { + return fileInfosCurrent; + } + + public void setFileInfosCurrent(List fileInfosCurrent) { + this.fileInfosCurrent = fileInfosCurrent; + } + + public ErrorState getErrorState() { + return errorState; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/CheckObjectOperation.java b/java/servers/src/org/xtreemfs/osd/operations/CheckObjectOperation.java new file mode 100644 index 0000000..8538087 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/CheckObjectOperation.java @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import java.io.IOException; +import java.util.List; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.StorageStage.ReadObjectCallback; +import org.xtreemfs.osd.storage.ObjectInformation; +import org.xtreemfs.osd.storage.StorageLayout; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class CheckObjectOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public CheckObjectOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_CHECK_OBJECT; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_check_objectRequest args = (xtreemfs_check_objectRequest) rq.getRequestArgs(); + + if (args.getObjectNumber() < 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "object number must be >= 0"); + return; + } + + master.getStorageStage().readObject(args.getFileId(), args.getObjectNumber(), rq.getLocationList().getLocalReplica().getStripingPolicy(), + 0,StorageLayout.FULL_OBJECT_LENGTH, rq.getCapability().getSnapConfig() == SnapConfig.SNAP_CONFIG_ACCESS_SNAP ? rq.getCapability() + .getSnapTimestamp() : 0, rq, new ReadObjectCallback() { + + @Override + public void readComplete(ObjectInformation result, ErrorResponse error) { + step2(rq, args, result, error); + } + }); + } + + public void step2(final OSDRequest rq, xtreemfs_check_objectRequest args, ObjectInformation result, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + if (rq.getLocationList().getLocalReplica().getOSDs().size() == 1) { + //non-striped case + nonStripedCheckObject(rq, args, result); + } else { + //striped read + stripedCheckObject(rq, args, result); + } + + } + + } + + private void nonStripedCheckObject(OSDRequest rq, xtreemfs_check_objectRequest args, ObjectInformation result) { + + final boolean isLastObjectOrEOF = result.getLastLocalObjectNo() <= args.getObjectNumber(); + readFinish(rq, args, result, isLastObjectOrEOF); + } + + private void stripedCheckObject(final OSDRequest rq, final xtreemfs_check_objectRequest args, final ObjectInformation result) { + //ObjectData data; + final long objNo = args.getObjectNumber(); + final long lastKnownObject = Math.max(result.getLastLocalObjectNo(), result.getGlobalLastObjectNo()); + final boolean isLastObjectLocallyKnown = lastKnownObject <= objNo; + //check if GMAX must be fetched to determin EOF + if ((objNo > lastKnownObject) || + (objNo == lastKnownObject) && (result.getData() != null) && (result.getData().remaining() < result.getStripeSize())) { + try { + final List osds = rq.getLocationList().getLocalReplica().getOSDs(); + final RPCResponse[] gmaxRPCs = new RPCResponse[osds.size() - 1]; + int cnt = 0; + for (ServiceUUID osd : osds) { + if (!osd.equals(localUUID)) { + gmaxRPCs[cnt++] = master.getOSDClient().xtreemfs_internal_get_gmax(osd.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, args.getFileCredentials(), args.getFileId()); + } + } + this.waitForResponses(gmaxRPCs, new ResponsesListener() { + + @Override + public void responsesAvailable() { + stripedCheckObjectAnalyzeGmax(rq, args, result, gmaxRPCs); + } + }); + } catch (IOException ex) { + rq.sendInternalServerError(ex); + return; + } + } else { + readFinish(rq, args, result, isLastObjectLocallyKnown); + } + } + + private void stripedCheckObjectAnalyzeGmax(final OSDRequest rq, final xtreemfs_check_objectRequest args, + final ObjectInformation result, RPCResponse[] gmaxRPCs) { + long maxObjNo = -1; + long maxTruncate = -1; + + try { + for (int i = 0; i < gmaxRPCs.length; i++) { + InternalGmax gmax = (InternalGmax) gmaxRPCs[i].get(); + if ((gmax.getLastObjectId() > maxObjNo) && (gmax.getEpoch() >= maxTruncate)) { + //found new max + maxObjNo = gmax.getLastObjectId(); + maxTruncate = gmax.getEpoch(); + } + } + final boolean isLastObjectLocallyKnown = maxObjNo <= args.getObjectNumber(); + readFinish(rq, args, result, isLastObjectLocallyKnown); + //and update gmax locally + master.getStorageStage().receivedGMAX_ASYNC(args.getFileId(), maxTruncate, maxObjNo); + } catch (Exception ex) { + rq.sendInternalServerError(ex); + } finally { + for (RPCResponse r : gmaxRPCs) + r.freeBuffers(); + } + + } + + private void readFinish(OSDRequest rq, xtreemfs_check_objectRequest args, ObjectInformation result, boolean isLastObjectOrEOF) { + + InternalObjectData data; + data = result.getObjectData(isLastObjectOrEOF,0,result.getStripeSize()); + if (data.getData() != null) { + data.setZero_padding(data.getZero_padding()+data.getData().remaining()); + BufferPool.free(data.getData()); + data.setData(null); + } + sendResponse(rq, data); + } + + public void sendResponse(OSDRequest rq, InternalObjectData result) { + rq.sendSuccess(result.getMetadata(),null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_check_objectRequest rpcrq = (xtreemfs_check_objectRequest) rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/CleanupGetResultsOperation.java b/java/servers/src/org/xtreemfs/osd/operations/CleanupGetResultsOperation.java new file mode 100644 index 0000000..ba91e02 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/CleanupGetResultsOperation.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class CleanupGetResultsOperation extends OSDOperation { + + public CleanupGetResultsOperation(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_CLEANUP_GET_RESULTS; + } + + @Override + public void startRequest(final OSDRequest rq) { + + Auth authData = rq.getRPCRequest().getHeader().getRequestHeader().getAuthData(); + if (master.getConfig().getAdminPassword().length() > 0 + && (!authData.hasAuthPasswd() || !authData.getAuthPasswd().getPassword() + .equals(master.getConfig().getAdminPassword()))) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, + "Invalid admin password."); + return; + } + xtreemfs_cleanup_get_resultsResponse response = xtreemfs_cleanup_get_resultsResponse.newBuilder() + .addAllResults(master.getCleanupThread().getResult()).build(); + rq.sendSuccess(response, null); + + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + rq.setFileId(""); + + return null; + } + + @Override + public boolean requiresCapability() { + return false; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/CleanupGetStatusOperation.java b/java/servers/src/org/xtreemfs/osd/operations/CleanupGetStatusOperation.java new file mode 100644 index 0000000..cf53d68 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/CleanupGetStatusOperation.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class CleanupGetStatusOperation extends OSDOperation { + + public CleanupGetStatusOperation(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_CLEANUP_STATUS; + } + + @Override + public void startRequest(final OSDRequest rq) { + + Auth authData = rq.getRPCRequest().getHeader().getRequestHeader().getAuthData(); + if (master.getConfig().getAdminPassword().length() > 0 + && (!authData.hasAuthPasswd() || !authData.getAuthPasswd().getPassword() + .equals(master.getConfig().getAdminPassword()))) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, + "Invalid admin password."); + return; + } + xtreemfs_cleanup_statusResponse response = xtreemfs_cleanup_statusResponse.newBuilder() + .setStatus(master.getCleanupThread().getStatus()).build(); + rq.sendSuccess(response, null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + rq.setFileId(""); + + return null; + } + + @Override + public boolean requiresCapability() { + return false; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/CleanupIsRunningOperation.java b/java/servers/src/org/xtreemfs/osd/operations/CleanupIsRunningOperation.java new file mode 100644 index 0000000..79c32ac --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/CleanupIsRunningOperation.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class CleanupIsRunningOperation extends OSDOperation { + + public CleanupIsRunningOperation(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_CLEANUP_IS_RUNNING; + } + + @Override + public void startRequest(final OSDRequest rq) { + + Auth authData = rq.getRPCRequest().getHeader().getRequestHeader().getAuthData(); + if (master.getConfig().getAdminPassword().length() > 0 + && (!authData.hasAuthPasswd() || !authData.getAuthPasswd().getPassword() + .equals(master.getConfig().getAdminPassword()))) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, + "Invalid admin password."); + return; + } + xtreemfs_cleanup_is_runningResponse response = xtreemfs_cleanup_is_runningResponse.newBuilder() + .setIsRunning(master.getCleanupThread().isRunning()).build(); + rq.sendSuccess(response, null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + rq.setFileId(""); + + return null; + } + + @Override + public boolean requiresCapability() { + return false; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/CleanupStartOperation.java b/java/servers/src/org/xtreemfs/osd/operations/CleanupStartOperation.java new file mode 100644 index 0000000..2ca8256 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/CleanupStartOperation.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class CleanupStartOperation extends OSDOperation { + + public CleanupStartOperation(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_CLEANUP_START; + } + + @Override + public void startRequest(final OSDRequest rq) { + + Auth authData = rq.getRPCRequest().getHeader().getRequestHeader().getAuthData(); + if (master.getConfig().getAdminPassword().length() > 0 + && (!authData.hasAuthPasswd() || !authData.getAuthPasswd().getPassword() + .equals(master.getConfig().getAdminPassword()))) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, + "Invalid admin password."); + return; + } + xtreemfs_cleanup_startRequest args = (xtreemfs_cleanup_startRequest) rq.getRequestArgs(); + + master.getCleanupThread().cleanupStart(args.getRemoveZombies(), args.getRemoveUnavailVolume(), + args.getLostAndFound(), args.getDeleteMetadata(), args.getMetadataTimeout(), + rq.getRPCRequest().getHeader().getRequestHeader().getUserCreds()); + rq.sendSuccess(null, null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + rq.setFileId(""); + + return null; + } + + @Override + public boolean requiresCapability() { + return false; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/CleanupStopOperation.java b/java/servers/src/org/xtreemfs/osd/operations/CleanupStopOperation.java new file mode 100644 index 0000000..8413a4c --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/CleanupStopOperation.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class CleanupStopOperation extends OSDOperation { + + public CleanupStopOperation(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_CLEANUP_STOP; + } + + @Override + public void startRequest(final OSDRequest rq) { + + Auth authData = rq.getRPCRequest().getHeader().getRequestHeader().getAuthData(); + if (master.getConfig().getAdminPassword().length() > 0 + && (!authData.hasAuthPasswd() || !authData.getAuthPasswd().getPassword() + .equals(master.getConfig().getAdminPassword()))) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, + "Invalid admin password."); + return; + } + master.getCleanupThread().cleanupStop(); + rq.sendSuccess(null, null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + rq.setFileId(""); + + return null; + } + + @Override + public boolean requiresCapability() { + return false; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/CleanupVersionsStartOperation.java b/java/servers/src/org/xtreemfs/osd/operations/CleanupVersionsStartOperation.java new file mode 100644 index 0000000..ac55f9c --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/CleanupVersionsStartOperation.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class CleanupVersionsStartOperation extends OSDOperation { + + public CleanupVersionsStartOperation(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_CLEANUP_VERSIONS_START; + } + + @Override + public void startRequest(final OSDRequest rq) { + + Auth authData = rq.getRPCRequest().getHeader().getRequestHeader().getAuthData(); + if (master.getConfig().getAdminPassword().length() > 0 + && (!authData.hasAuthPasswd() || !authData.getAuthPasswd().getPassword() + .equals(master.getConfig().getAdminPassword()))) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, + "Invalid admin password."); + return; + } + master.getCleanupVersionsThread().cleanupStart( + rq.getRPCRequest().getHeader().getRequestHeader().getUserCreds()); + rq.sendSuccess(null, null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + rq.setFileId(""); + + return null; + } + + @Override + public boolean requiresCapability() { + return false; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/DeleteOperation.java b/java/servers/src/org/xtreemfs/osd/operations/DeleteOperation.java new file mode 100644 index 0000000..923f244 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/DeleteOperation.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import java.io.IOException; +import java.util.List; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.Replica; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.OpenFileTable.OpenFileTableEntry; +import org.xtreemfs.osd.operations.EventCloseFile.EventCloseCallback; +import org.xtreemfs.osd.stages.DeletionStage.DeleteObjectsCallback; +import org.xtreemfs.osd.stages.PreprocStage.CloseCallback; +import org.xtreemfs.osd.stages.PreprocStage.DeleteOnCloseCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class DeleteOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public DeleteOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_UNLINK; + } + + @Override + public void startRequest(final OSDRequest rq) { + final unlink_osd_Request args = (unlink_osd_Request) rq.getRequestArgs(); + + // If the file is open, the deleteOnClose flag will be set. + master.getPreprocStage().checkDeleteOnClose(args.getFileId(), new DeleteOnCloseCallback() { + + @Override + public void deleteOnCloseResult(boolean isDeleteOnClose, ErrorResponse error) { + closeFileIfNecessary(rq, isDeleteOnClose, args, error); + } + }); + } + + public void closeFileIfNecessary(final OSDRequest rq, final boolean isDeleteOnClose, final unlink_osd_Request args, + final ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + return; + } + + if (!isDeleteOnClose) { + // File is not open and can be deleted immediately. + + // Cancel replication of file + if (rq.getLocationList().getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)) + master.getReplicationStage().cancelReplicationForFile(args.getFileId()); + + master.getDeletionStage().deleteObjects(args.getFileId(), null, rq.getCowPolicy().cowEnabled(), rq, false, + new DeleteObjectsCallback() { + + @Override + public void deleteComplete(ErrorResponse error) { + disseminateDeletesIfNecessary(rq, args, error); + } + }); + } else { + // Close the file explicitly. + master.getPreprocStage().close(args.getFileId(), new CloseCallback() { + + + @Override + public void closeResult(OpenFileTableEntry entry, ErrorResponse error) { + // Send close event. + // This will create new versions if necessary and delete objects (because deleteOnClose is set). + OSDOperation closeEvent = master.getInternalEvent(EventCloseFile.class); + closeEvent.startInternalEvent(new Object[] { entry.getFileId(), true, + entry.getCowPolicy().cowEnabled(), entry.isWrite(), new EventCloseCallback() { + + @Override + public void closeEventResult(ErrorResponse error) { + disseminateDeletesIfNecessary(rq, args, error); + } + + } }); + + } + }); + } + } + + + public void disseminateDeletesIfNecessary(final OSDRequest rq, final unlink_osd_Request args, + final ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + return; + } + + final Replica localReplica = rq.getLocationList().getLocalReplica(); + if (localReplica.isStriped() && localReplica.getHeadOsd().equals(localUUID)) { + // striped replica, dissmeninate unlink requests + try { + final List osds = rq.getLocationList().getLocalReplica().getOSDs(); + final RPCResponse[] gmaxRPCs = new RPCResponse[osds.size() - 1]; + int cnt = 0; + for (ServiceUUID osd : osds) { + if (!osd.equals(localUUID)) { + gmaxRPCs[cnt++] = master.getOSDClient().unlink(osd.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, args.getFileCredentials(), args.getFileId()); + } + } + this.waitForResponses(gmaxRPCs, new ResponsesListener() { + + @Override + public void responsesAvailable() { + analyzeUnlinkReponses(rq, gmaxRPCs); + } + }); + } catch (IOException ex) { + rq.sendInternalServerError(ex); + return; + } + } else { + // non striped replica, fini + sendResponse(rq); + } + } + + public void analyzeUnlinkReponses(final OSDRequest rq, RPCResponse[] gmaxRPCs) { + // analyze results + try { + for (int i = 0; i < gmaxRPCs.length; i++) { + gmaxRPCs[i].get(); + } + sendResponse(rq); + } catch (Exception ex) { + rq.sendInternalServerError(ex); + } finally { + for (RPCResponse r : gmaxRPCs) + r.freeBuffers(); + } + } + + public void sendResponse(OSDRequest rq) { + rq.sendSuccess(null, null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + unlink_osd_Request rpcrq = (unlink_osd_Request) rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public boolean bypassViewValidation() { + // Object deletion occurs for one thing if a file is unlinked, which does also delete its metadata like the + // xLocSet. Therefore it is possible to bypass validation: No more Operation will be possible after a file has + // been unlinked. + // And it occurs for another thing if a replica is removed. In that case only the objects on the removed replica + // will be deleted. It is necessary to bypass validation in that case, because the replica is invalidated and no + // longer part of the new view. + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/EventCloseFile.java b/java/servers/src/org/xtreemfs/osd/operations/EventCloseFile.java new file mode 100644 index 0000000..919805a --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/EventCloseFile.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2009-2014 by Bjoern Kolbeck, Johannes Dillmann + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.DeletionStage.DeleteObjectsCallback; +import org.xtreemfs.osd.stages.StorageStage.CachesFlushedCallback; +import org.xtreemfs.osd.stages.StorageStage.CreateFileVersionCallback; +import org.xtreemfs.osd.storage.FileMetadata; + +/** + * EventCloseFile flushes the internal metadata caches, creates create a new file version if versioning / COW is enabled + * and deletes the file along with its objects if the file has been marked for deletion.
    + * + * It is not responsible for removing files from the open file table (which has to be ensured previously) and doesn't + * disseminate to other replicas. + */ +public class EventCloseFile extends OSDOperation { + + public EventCloseFile(OSDRequestDispatcher master) { + super(master); + } + + public interface EventCloseCallback { + void closeEventResult(ErrorResponse error); + } + + /** + * @param args + * [ fileId, deleteOnClose, cowEnabled, createVersion, {@link EventCloseCallback} (optional) ] + */ + @Override + public void startInternalEvent(Object[] args) { + final String fileId = (String) args[0]; + final Boolean deleteOnClose = (Boolean) args[1]; + final Boolean cowEnabled = (Boolean) args[2]; + final Boolean createVersion = (Boolean) args[3]; + + final EventCloseCallback cb = args.length > 4 ? (EventCloseCallback) args[4] : null; + + flushCaches(fileId, deleteOnClose, cowEnabled, createVersion, cb); + } + + public void flushCaches(final String fileId, final boolean deleteOnClose, final boolean cowEnabled, + final boolean createVersion, final EventCloseCallback cb) { + master.getStorageStage().flushCaches(fileId, new CachesFlushedCallback() { + @Override + public void cachesFlushed(ErrorResponse error, FileMetadata fi) { + createVersionIfNecessary(fileId, deleteOnClose, cowEnabled, createVersion, fi, cb, error); + } + + }); + + // Asynchronously report close operation to read-write replication stage. + master.getRWReplicationStage().fileClosed(fileId); + } + + public void createVersionIfNecessary(final String fileId, final boolean deleteOnClose, final boolean cowEnabled, + final boolean createVersion, final FileMetadata fi, final EventCloseCallback cb, final ErrorResponse error) { + + if (error != null) { + finishEvent(cb, error); + return; + } + + // If versioning on close is enabled, create a new version. + if (cowEnabled && createVersion) { + + master.getStorageStage().createFileVersion(fileId, fi, null, new CreateFileVersionCallback() { + + @Override + public void createFileVersionComplete(long fileSize, ErrorResponse error) { + deleteIfNecessary(fileId, deleteOnClose, cowEnabled, fi, cb, error); + } + }); + + } else { + deleteIfNecessary(fileId, deleteOnClose, cowEnabled, fi, cb, null); + } + } + + public void deleteIfNecessary(final String fileId, final boolean deleteOnClose, final boolean cowEnabled, + final FileMetadata fi, final EventCloseCallback cb, final ErrorResponse error) { + + if (error != null) { + finishEvent(cb, error); + return; + } + + if (deleteOnClose) { + + // Cancel replication of file. + master.getReplicationStage().cancelReplicationForFile(fileId); + + // Delete the file across all stripes. + master.getDeletionStage().deleteObjects(fileId, fi, cowEnabled, null, false, new DeleteObjectsCallback() { + + @Override + public void deleteComplete(ErrorResponse error) { + finishEvent(cb, error); + } + }); + + } else { + finishEvent(cb, null); + } + } + + public void finishEvent(final EventCloseCallback cb, final ErrorResponse error) { + if (cb != null) { + cb.closeEventResult(error); + + } else if (error != null) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "exception in internal close event: %s", + ErrorUtils.formatError(error)); + } + } + + @Override + public int getProcedureId() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void startRequest(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + + } + + @Override + public boolean requiresCapability() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/EventCreateFileVersion.java b/java/servers/src/org/xtreemfs/osd/operations/EventCreateFileVersion.java new file mode 100644 index 0000000..e308a09 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/EventCreateFileVersion.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.StorageStage.CreateFileVersionCallback; +import org.xtreemfs.osd.storage.FileMetadata; + +/** + * + * @author bjko + */ +public class EventCreateFileVersion extends OSDOperation { + + public EventCreateFileVersion(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void startRequest(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + + } + + @Override + public boolean requiresCapability() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void startInternalEvent(Object[] args) { + + final String fileId = (String) args[0]; + final FileMetadata fi = (FileMetadata) args[1]; + + master.getStorageStage().createFileVersion(fileId, fi, null, new CreateFileVersionCallback() { + public void createFileVersionComplete(long fileSize, ErrorResponse error) { + if (error != null) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "exception in internal event: %s", + ErrorUtils.formatError(error)); + } + } + }); + + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/EventGmax.java b/java/servers/src/org/xtreemfs/osd/operations/EventGmax.java new file mode 100644 index 0000000..2c1c003 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/EventGmax.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * + *
    15.06.2009 + */ +public class EventGmax extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public EventGmax(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_BROADCAST_GMAX; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_broadcast_gmaxRequest args = (xtreemfs_broadcast_gmaxRequest) rq + .getRequestArgs(); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, + "received GMAX packet for: %s from %s", rq.getFileId(), rq.getRPCRequest().getSenderAddress()); + + master.getStorageStage().receivedGMAX_ASYNC(args.getFileId(), args.getTruncateEpoch(), args.getLastObject()); + + } + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + rq.setFileId(""); + + return null; + } + + @Override + public boolean requiresCapability() { + return false; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/EventInsertPaddingObject.java b/java/servers/src/org/xtreemfs/osd/operations/EventInsertPaddingObject.java new file mode 100644 index 0000000..878ab2e --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/EventInsertPaddingObject.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.StorageStage.WriteObjectCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; + +/** + * Writes an object to disk without sending GMax-messages. + * + * 01.04.2009 + */ +public class EventInsertPaddingObject extends OSDOperation { + + public EventInsertPaddingObject(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void startRequest(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + + } + + + @Override + public boolean requiresCapability() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void startInternalEvent(Object[] args) { + final String fileId = (String) args[0]; + final long objectNo = (Long) args[1]; + final XLocations xloc = (XLocations) args[2]; + final int size = (Integer) args[3]; + + master.objectReplicated(); + + master.getStorageStage().insertPaddingObject(fileId, objectNo, + xloc.getLocalReplica().getStripingPolicy(), size, null, + new WriteObjectCallback() { + @Override + public void writeComplete(OSDWriteResponse result, ErrorResponse error) { + if (error != null) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "exception in internal event: %s", + ErrorUtils.formatError(error)); + } else + triggerReplication(fileId); + } + }); + } + + public void triggerReplication(String fileId) { + // cancel replication of file + master.getReplicationStage().triggerReplicationForFile(fileId); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/EventPingFile.java b/java/servers/src/org/xtreemfs/osd/operations/EventPingFile.java new file mode 100644 index 0000000..c44d2e6 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/EventPingFile.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; + +/** + * Writes an object to disk without sending GMax-messages. + * + * 01.04.2009 + */ +public class EventPingFile extends OSDOperation { + + public EventPingFile(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void startRequest(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + + } + + @Override + public boolean requiresCapability() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void startInternalEvent(Object[] args) { + final String fileId = (String) args[0]; + + master.getPreprocStage().pingFile(fileId); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/EventRWRStatus.java b/java/servers/src/org/xtreemfs/osd/operations/EventRWRStatus.java new file mode 100644 index 0000000..ef75765 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/EventRWRStatus.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.StorageStage.InternalGetMaxObjectNoCallback; +import org.xtreemfs.osd.stages.StorageStage.InternalGetReplicaStateCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; + +/** + * Writes an object to disk without sending GMax-messages. + * + * 01.04.2009 + */ +public class EventRWRStatus extends OSDOperation { + + public EventRWRStatus(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void startRequest(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + + } + + + @Override + public boolean requiresCapability() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void startInternalEvent(Object[] args) { + final String fileId = (String) args[0]; + final StripingPolicyImpl sp = (StripingPolicyImpl) args[1]; + + master.getStorageStage().internalGetReplicaState(fileId, sp, 0, new InternalGetReplicaStateCallback() { + + @Override + public void getReplicaStateComplete(ReplicaStatus localState, ErrorResponse error) { + master.getRWReplicationStage().eventReplicaStateAvailable(fileId, localState, error); + } + }); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/EventWriteObject.java b/java/servers/src/org/xtreemfs/osd/operations/EventWriteObject.java new file mode 100755 index 0000000..7e4a875 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/EventWriteObject.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2009-2011 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.StorageStage.WriteObjectCallback; +import org.xtreemfs.osd.storage.CowPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; + +/** + * Writes an object to disk without sending GMax-messages. + * + * 01.04.2009 + */ +public class EventWriteObject extends OSDOperation { + + public EventWriteObject(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void startRequest(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + + } + + + @Override + public boolean requiresCapability() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void startInternalEvent(Object[] args) { + final String fileId = (String) args[0]; + final long objectNo = (Long) args[1]; + final ReusableBuffer data = (ReusableBuffer) args[2]; + final XLocations xloc = (XLocations) args[3]; + final CowPolicy cow = (CowPolicy) args[4]; + + master.objectReplicated(); + master.replicatedDataReceived(data.capacity()); + + master.getStorageStage().writeObjectWithoutGMax(fileId, objectNo, + xloc.getLocalReplica().getStripingPolicy(), 0, data, cow, xloc, false, null, null, + new WriteObjectCallback() { + @Override + public void writeComplete(OSDWriteResponse result, ErrorResponse error) { + if (error != null) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "exception in internal event: %s", + ErrorUtils.formatError(error)); + } else + triggerReplication(fileId); + } + }); + } + + public void triggerReplication(String fileId) { + // cancel replication of file + master.getReplicationStage().triggerReplicationForFile(fileId); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/FleaseMessageOperation.java b/java/servers/src/org/xtreemfs/osd/operations/FleaseMessageOperation.java new file mode 100644 index 0000000..5608414 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/FleaseMessageOperation.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import java.net.InetSocketAddress; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * + * @author bjko + */ +public class FleaseMessageOperation extends OSDOperation { + + public FleaseMessageOperation(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_RWR_FLEASE_MSG; + } + + @Override + public void startRequest(OSDRequest rq) { + xtreemfs_rwr_flease_msgRequest args = (xtreemfs_rwr_flease_msgRequest) rq.getRequestArgs(); + try { + InetSocketAddress sender = new InetSocketAddress(args.getSenderHostname(), args.getSenderPort()); + master.getRWReplicationStage().receiveFleaseMessage(rq.getRpcRequest().getData().createViewBuffer(),sender); + rq.sendSuccess(null,null); + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_WARN, this,ex); + } + + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("not an internal event!"); + } + + @Override + public boolean requiresCapability() { + return false; + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + return null; + } + + +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/GetFileIDListOperation.java b/java/servers/src/org/xtreemfs/osd/operations/GetFileIDListOperation.java new file mode 100644 index 0000000..51cde97 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/GetFileIDListOperation.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2009-2011 by Felix Langner, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map.Entry; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.operations.OSDOperation; +import org.xtreemfs.osd.stages.StorageStage.GetFileIDListCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse; + + +public class GetFileIDListOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public GetFileIDListOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_INTERNAL_GET_FILEID_LIST; + } + + @Override + public void startRequest(final OSDRequest rq) { + + master.getStorageStage().getFileIDList(rq, new GetFileIDListCallback() { + + @Override + public void createGetFileIDListComplete(ArrayList fileIDList, ErrorResponse error) { + + postGetFileIDList(rq, fileIDList, error); + } + }); + } + + private void postGetFileIDList(final OSDRequest rq, ArrayList fileIDList, ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + } else { + try { + xtreemfs_internal_get_fileid_listResponse.Builder responseBuilder = xtreemfs_internal_get_fileid_listResponse.newBuilder(); + for (String fileID : fileIDList) { + responseBuilder.addFileIds(fileID); + } + rq.sendSuccess(responseBuilder.build(), null); + + } catch (Exception e) { + rq.sendError(ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, e.toString())); + } + } + + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean requiresCapability() { + return false; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + + +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/GetObjectSetOperation.java b/java/servers/src/org/xtreemfs/osd/operations/GetObjectSetOperation.java new file mode 100755 index 0000000..86a4852 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/GetObjectSetOperation.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import com.google.protobuf.ByteString; +import java.io.IOException; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.stages.StorageStage.GetObjectListCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * + *
    15.06.2009 + */ +public class GetObjectSetOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public GetObjectSetOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_INTERNAL_GET_OBJECT_SET; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_internal_get_object_setRequest args = (xtreemfs_internal_get_object_setRequest) rq + .getRequestArgs(); + +// System.out.println("rq: " + args); + + master.getStorageStage().getObjectSet(args.getFileId(), rq.getLocationList().getLocalReplica().getStripingPolicy(), rq, + new GetObjectListCallback() { + @Override + public void getObjectSetComplete(ObjectSet result, ErrorResponse error) { + postReadObjectList(rq, args, result, error); + } + }); + } + + public void postReadObjectList(final OSDRequest rq, xtreemfs_internal_get_object_setRequest args, + ObjectSet result, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + // serialize objectSet + byte[] serialized; + try { + serialized = result.getSerializedBitSet(); + + ObjectList objList = ObjectList.newBuilder().setSet(ByteString.copyFrom(serialized)).setStripeWidth(result.getStripeWidth()).setFirst(result.getFirstObjectNo()).build(); + rq.sendSuccess(objList,null); + } catch (IOException e) { + rq.sendInternalServerError(e); + } + } + } + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_internal_get_object_setRequest rpcrq = (xtreemfs_internal_get_object_setRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/InternalGetFileSizeOperation.java b/java/servers/src/org/xtreemfs/osd/operations/InternalGetFileSizeOperation.java new file mode 100644 index 0000000..84677d6 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/InternalGetFileSizeOperation.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import java.io.IOException; +import java.util.List; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.rwre.RWReplicationStage; +import org.xtreemfs.osd.stages.StorageStage.GetFileSizeCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class InternalGetFileSizeOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public InternalGetFileSizeOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_INTERNAL_GET_FILE_SIZE; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_internal_get_file_sizeRequest args = (xtreemfs_internal_get_file_sizeRequest) rq + .getRequestArgs(); + + final StripingPolicyImpl sp = rq.getLocationList().getLocalReplica().getStripingPolicy(); + + final String replUpdatePolicy = args.getFileCredentials().getXlocs().getReplicaUpdatePolicy(); + + if (replUpdatePolicy.equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE) + || replUpdatePolicy.equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)) { + master.getStorageStage().getFilesize(args.getFileId(), sp, rq.getCapability().getSnapTimestamp(), rq, + new GetFileSizeCallback() { + + @Override + public void getFileSizeComplete(long fileSize, ErrorResponse error) { + step2(rq, args, fileSize, error); + } + }); + } else { + rwReplicatedGetFS(rq, args); + } + + } + + public void step2(final OSDRequest rq, xtreemfs_internal_get_file_sizeRequest args, long localFS, + ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + if (rq.getLocationList().getLocalReplica().isStriped()) { + // striped read + stripedGetFS(rq, args, localFS); + } else { + // non-striped case + sendResponse(rq, localFS); + } + } + } + + private void stripedGetFS(final OSDRequest rq, final xtreemfs_internal_get_file_sizeRequest args, final long localFS) { + try { + final List osds = rq.getLocationList().getLocalReplica().getOSDs(); + final RPCResponse[] gmaxRPCs = new RPCResponse[osds.size() - 1]; + int cnt = 0; + for (ServiceUUID osd : osds) { + if (!osd.equals(localUUID)) { + gmaxRPCs[cnt++] = master.getOSDClient().xtreemfs_internal_get_gmax(osd.getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, args.getFileCredentials(), + args.getFileId()); + } + } + this.waitForResponses(gmaxRPCs, new ResponsesListener() { + + @Override + public void responsesAvailable() { + stripedReadAnalyzeGmax(rq, args, localFS, gmaxRPCs); + } + }); + } catch (IOException ex) { + rq.sendInternalServerError(ex); + return; + } + + } + + private void stripedReadAnalyzeGmax(final OSDRequest rq, final xtreemfs_internal_get_file_sizeRequest args, + final long localFS, RPCResponse[] gmaxRPCs) { + long maxFS = localFS; + + try { + for (int i = 0; i < gmaxRPCs.length; i++) { + InternalGmax gmax = (InternalGmax) gmaxRPCs[i].get(); + if (gmax.getFileSize() > maxFS) { + // found new max + maxFS = gmax.getFileSize(); + } + } + sendResponse(rq, maxFS); + } catch (Exception ex) { + rq.sendInternalServerError(ex); + } finally { + for (RPCResponse r : gmaxRPCs) + r.freeBuffers(); + } + } + + private void rwReplicatedGetFS(final OSDRequest rq, final xtreemfs_internal_get_file_sizeRequest args) { + master.getRWReplicationStage().prepareOperation(args.getFileCredentials(), + rq.getLocationList(), 0, 0, + RWReplicationStage.Operation.READ, + new RWReplicationStage.RWReplicationCallback() { + + @Override + public void success(long newObjectVersion) { + final StripingPolicyImpl sp = rq.getLocationList().getLocalReplica().getStripingPolicy(); + + final long snapVerTS = rq.getCapability().getSnapConfig() == SnapConfig.SNAP_CONFIG_ACCESS_SNAP ? rq + .getCapability().getSnapTimestamp() : 0; + + master.getStorageStage().getFilesize(args.getFileId(), sp, snapVerTS, rq, + new GetFileSizeCallback() { + @Override + public void getFileSizeComplete(long fileSize, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + sendResponse(rq, fileSize); + } + } + }); + } + + @Override + public void redirect(String redirectTo) { + rq.getRPCRequest().sendRedirect(redirectTo); + } + + @Override + public void failed(ErrorResponse err) { + rq.sendError(err); + } + }, rq); + } + + public void sendResponse(OSDRequest rq, long fileSize) { + xtreemfs_internal_get_file_sizeResponse response = xtreemfs_internal_get_file_sizeResponse.newBuilder() + .setFileSize(fileSize).build(); + rq.sendSuccess(response, null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_internal_get_file_sizeRequest rpcrq = (xtreemfs_internal_get_file_sizeRequest) rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/InternalGetGmaxOperation.java b/java/servers/src/org/xtreemfs/osd/operations/InternalGetGmaxOperation.java new file mode 100644 index 0000000..bd75b42 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/InternalGetGmaxOperation.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.StorageStage.InternalGetGmaxCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class InternalGetGmaxOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public InternalGetGmaxOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_INTERNAL_GET_GMAX; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_internal_get_gmaxRequest args = (xtreemfs_internal_get_gmaxRequest) rq + .getRequestArgs(); + master.getStorageStage().internalGetGmax( + args.getFileId(), + rq.getLocationList().getLocalReplica().getStripingPolicy(), + rq.getCapability().getSnapConfig() == SnapConfig.SNAP_CONFIG_ACCESS_SNAP ? rq.getCapability() + .getSnapTimestamp() : 0, rq, new InternalGetGmaxCallback() { + + @Override + public void gmaxComplete(InternalGmax result, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else + sendResponse(rq, result); + } + }); + } + + public void sendResponse(OSDRequest rq, InternalGmax result) { + rq.sendSuccess(result,null); + } + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_internal_get_gmaxRequest rpcrq = (xtreemfs_internal_get_gmaxRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/InternalRWRAuthStateInvalidatedOperation.java b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRAuthStateInvalidatedOperation.java new file mode 100644 index 0000000..8ecb2cd --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRAuthStateInvalidatedOperation.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013 by Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.mrc.stages.XLocSetCoordinator; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.rwre.RWReplicationStage.RWReplicationCallback; +import org.xtreemfs.osd.stages.PreprocStage.InvalidateXLocSetCallback; +import org.xtreemfs.osd.stages.StorageStage.InternalGetReplicaStateCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * Sets the authoritative state on an invalidated replica and fetch missing data from other OSDs.
    + * In contrast to {@link InternalRWRAuthStateOperation} this operation does not require a valid view and works on + * invalidated replicas. Effectively the replica will be invalidated when executing this operation.
    + * This operation is intended to be called from the MRCs {@link XLocSetCoordinator}. + */ +public class InternalRWRAuthStateInvalidatedOperation extends OSDOperation { + + final String sharedSecret; + final ServiceUUID localUUID; + + public InternalRWRAuthStateInvalidatedOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_RWR_AUTH_STATE_INVALIDATED; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_rwr_auth_stateRequest args = (xtreemfs_rwr_auth_stateRequest) rq.getRequestArgs(); + + master.getPreprocStage().invalidateXLocSet(rq, args.getFileCredentials(), false, + new InvalidateXLocSetCallback() { + + @Override + public void invalidateComplete(LeaseState leaseState, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + postInvalidation(rq); + } + } + }); + } + + private void postInvalidation(final OSDRequest rq) { + final String fileId = rq.getFileId(); + + master.getStorageStage().internalGetReplicaState(fileId, + rq.getLocationList().getLocalReplica().getStripingPolicy(), 0, new InternalGetReplicaStateCallback() { + + @Override + public void getReplicaStateComplete(ReplicaStatus localState, ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + } else { + startFetch(rq, localState); + } + } + }); + } + + private void startFetch(final OSDRequest rq, final ReplicaStatus localState) { + final String fileId = rq.getFileId(); + final XLocations xloc = rq.getLocationList(); + final xtreemfs_rwr_auth_stateRequest args = (xtreemfs_rwr_auth_stateRequest) rq.getRequestArgs(); + + master.getRWReplicationStage().fetchInvalidated(fileId, args.getState(), localState, args.getFileCredentials(), + xloc, new RWReplicationCallback() { + + @Override + public void success(long newObjectVersion) { + rq.sendSuccess(emptyResponse.getDefaultInstance(), null); + } + + @Override + public void failed(ErrorResponse ex) { + rq.sendError(ex); + } + + @Override + public void redirect(String redirectTo) { + // Not used in fetchInvalidated + rq.sendError(ErrorUtils.getErrorResponse(ErrorType.INTERNAL_SERVER_ERROR, + POSIXErrno.POSIX_ERROR_NONE, + "FetchInvalidated called the redirect method. This should never happen")); + } + }, rq); + } + + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_rwr_auth_stateRequest rpcrq = (xtreemfs_rwr_auth_stateRequest) rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public boolean bypassViewValidation() { + return true; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/InternalRWRAuthStateOperation.java b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRAuthStateOperation.java new file mode 100644 index 0000000..85859f4 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRAuthStateOperation.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.StorageStage.InternalGetReplicaStateCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class InternalRWRAuthStateOperation extends OSDOperation { + + final String sharedSecret; + final ServiceUUID localUUID; + + public InternalRWRAuthStateOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_RWR_AUTH_STATE; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_rwr_auth_stateRequest args = (xtreemfs_rwr_auth_stateRequest)rq.getRequestArgs(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"RWR auth state request for file %s",args.getFileId()); + } + + getLocalReplicaState(rq, args); + + } + + public void getLocalReplicaState(final OSDRequest rq, final xtreemfs_rwr_auth_stateRequest args) { + master.getStorageStage().internalGetReplicaState(rq.getFileId(), rq.getLocationList().getLocalReplica().getStripingPolicy(), 0, new InternalGetReplicaStateCallback() { + + @Override + public void getReplicaStateComplete(ReplicaStatus localState, ErrorResponse error) { + if (error == null) { + master.getRWReplicationStage().eventBackupReplicaReset(rq.getFileId(), args.getState(), localState, args.getFileCredentials(), rq.getLocationList()); + rq.sendSuccess(emptyResponse.getDefaultInstance(), null); + } else { + sendResult(rq, null, error); + } + } + }); + } + + public void sendResult(final OSDRequest rq, InternalObjectData response, ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + } else { + //only locally + rq.sendSuccess(response.getMetadata(),response.getData()); + } + } + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_rwr_auth_stateRequest rpcrq = (xtreemfs_rwr_auth_stateRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/InternalRWRFetchOperation.java b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRFetchOperation.java new file mode 100644 index 0000000..b72eb80 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRFetchOperation.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.StorageStage.ReadObjectCallback; +import org.xtreemfs.osd.storage.ObjectInformation; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class InternalRWRFetchOperation extends OSDOperation { + + final String sharedSecret; + final ServiceUUID localUUID; + + public InternalRWRFetchOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_RWR_FETCH; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_rwr_fetchRequest args = (xtreemfs_rwr_fetchRequest)rq.getRequestArgs(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"RWR fetch request for file %s-%d",args.getFileId(),args.getObjectNumber()); + } + + fetchObject(rq,args); + + } + + public void fetchObject(final OSDRequest rq, final xtreemfs_rwr_fetchRequest args) { + master.getStorageStage().readObject(rq.getFileId(), args.getObjectNumber(), + rq.getLocationList().getLocalReplica().getStripingPolicy(), 0, -1, 0, rq, new ReadObjectCallback() { + + @Override + public void readComplete(ObjectInformation result, ErrorResponse error) { + if (error != null) + sendResult(rq, null, error); + else { + InternalObjectData odata = new InternalObjectData(0, false, 0, result.getData()); + sendResult(rq, odata, null); + } + } + }); + } + + public void sendResult(final OSDRequest rq, InternalObjectData response, ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + } else { + //only locally + rq.sendSuccess(response.getMetadata(),response.getData()); + } + } + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_rwr_fetchRequest rpcrq = (xtreemfs_rwr_fetchRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public boolean bypassViewValidation() { + // This operation has to be used while the replicas are invalidated and a reset triggered + // by InternalRWRAuthStateInvalidatedOperation. + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/InternalRWRStatusOperation.java b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRStatusOperation.java new file mode 100644 index 0000000..1701ba9 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRStatusOperation.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.StorageStage.InternalGetReplicaStateCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class InternalRWRStatusOperation extends OSDOperation { + + final String sharedSecret; + final ServiceUUID localUUID; + + public InternalRWRStatusOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_RWR_STATUS; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_rwr_statusRequest args = (xtreemfs_rwr_statusRequest)rq.getRequestArgs(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"RWR status request for file %s",args.getFileId()); + } + + getState(rq,args); + + } + + public void getState(final OSDRequest rq, final xtreemfs_rwr_statusRequest args) { + master.getStorageStage().internalGetReplicaState(args.getFileId(), + rq.getLocationList().getLocalReplica().getStripingPolicy(), args.getMaxLocalObjVersion(), new InternalGetReplicaStateCallback() { + + @Override + public void getReplicaStateComplete(ReplicaStatus localState, ErrorResponse error) { + sendResult(rq, localState, error); + } + }); + } + + public void sendResult(final OSDRequest rq, ReplicaStatus response, ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + } else { + //only locally + rq.sendSuccess(response,null); + } + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_rwr_statusRequest rpcrq = (xtreemfs_rwr_statusRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + + + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/InternalRWRTruncateOperation.java b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRTruncateOperation.java new file mode 100644 index 0000000..a0a100e --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRTruncateOperation.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.rwre.RWReplicationStage; +import org.xtreemfs.osd.stages.StorageStage.TruncateCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class InternalRWRTruncateOperation extends OSDOperation { + + final String sharedSecret; + final ServiceUUID localUUID; + + public InternalRWRTruncateOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_RWR_TRUNCATE; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_rwr_truncateRequest args = (xtreemfs_rwr_truncateRequest)rq.getRequestArgs(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"RWR truncate for file %s objVer %d",args.getFileId(), + args.getObjectVersion()); + } + + prepareLocalTruncate(rq,args); + } + + public void localTruncate(final OSDRequest rq, final xtreemfs_rwr_truncateRequest args) { + if (args.getNewFileSize() < 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "new_file_size for truncate must be >= 0"); + return; + } + + master.getStorageStage().truncate(args.getFileId(), args.getNewFileSize(), + rq.getLocationList().getLocalReplica().getStripingPolicy(), + rq.getLocationList().getLocalReplica(), rq.getCapability().getEpochNo(), rq.getCowPolicy(), + args.getObjectVersion(), true, rq, + new TruncateCallback() { + + @Override + public void truncateComplete(OSDWriteResponse result, ErrorResponse error) { + sendResult(rq, error); + } + }); + } + + public void prepareLocalTruncate(final OSDRequest rq, final xtreemfs_rwr_truncateRequest args) { + master.getRWReplicationStage().prepareOperation(args.getFileCredentials(), rq.getLocationList(), 0, args.getObjectVersion(), + RWReplicationStage.Operation.INTERNAL_TRUNCATE, new RWReplicationStage.RWReplicationCallback() { + + @Override + public void success(long newObjectVersion) { + localTruncate(rq, args); + } + + @Override + public void redirect(String redirectTo) { + rq.getRPCRequest().sendRedirect(redirectTo); + } + + @Override + public void failed(ErrorResponse err) { + rq.sendError(err); + } + }, rq); + } + + + public void sendResult(final OSDRequest rq, ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + } else { + //only locally + sendResponse(rq); + } + } + + + public void sendResponse(OSDRequest rq) { + rq.sendSuccess(null,null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_rwr_truncateRequest rpcrq = (xtreemfs_rwr_truncateRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/InternalRWRUpdateOperation.java b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRUpdateOperation.java new file mode 100644 index 0000000..1b13f13 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/InternalRWRUpdateOperation.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.rwre.RWReplicationStage; +import org.xtreemfs.osd.stages.StorageStage.WriteObjectCallback; +import org.xtreemfs.osd.storage.CowPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class InternalRWRUpdateOperation extends OSDOperation { + + final String sharedSecret; + final ServiceUUID localUUID; + + public InternalRWRUpdateOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_RWR_UPDATE; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_rwr_updateRequest args = (xtreemfs_rwr_updateRequest)rq.getRequestArgs(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"RWR update for file %s-%d",args.getFileId(),args.getObjectNumber()); + } + + prepareLocalWrite(rq, args); + } + + public void localWrite(final OSDRequest rq, final xtreemfs_rwr_updateRequest args) { + master.replicatedDataReceived(rq.getRPCRequest().getData().capacity()); + + ReusableBuffer viewBuffer = rq.getRPCRequest().getData().createViewBuffer(); + master.getStorageStage().writeObject(args.getFileId(), args.getObjectNumber(), + rq.getLocationList().getLocalReplica().getStripingPolicy(), args.getOffset(), viewBuffer, + CowPolicy.PolicyNoCow, rq.getLocationList(), false, args.getObjectVersion(), rq, viewBuffer, + new WriteObjectCallback() { + + @Override + public void writeComplete(OSDWriteResponse result, ErrorResponse error) { + sendResult(rq, error); + } + }); + } + + public void prepareLocalWrite(final OSDRequest rq, final xtreemfs_rwr_updateRequest args) { + master.getRWReplicationStage().prepareOperation(args.getFileCredentials(), rq.getLocationList(), + args.getObjectNumber(), args.getObjectVersion(), RWReplicationStage.Operation.INTERNAL_UPDATE, new RWReplicationStage.RWReplicationCallback() { + + @Override + public void success(long newObjectVersion) { + localWrite(rq, args); + } + + @Override + public void redirect(String redirectTo) { + rq.getRPCRequest().sendRedirect(redirectTo); + } + + @Override + public void failed(ErrorResponse err) { + rq.sendError(err); + } + }, rq); + } + + public void sendResult(final OSDRequest rq, ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + } else { + //only locally + sendResponse(rq); + } + } + + + public void sendResponse(OSDRequest rq) { + rq.sendSuccess(null,null); + } + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_rwr_updateRequest rpcrq = (xtreemfs_rwr_updateRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/InternalTruncateOperation.java b/java/servers/src/org/xtreemfs/osd/operations/InternalTruncateOperation.java new file mode 100644 index 0000000..c51833c --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/InternalTruncateOperation.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.StorageStage.TruncateCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class InternalTruncateOperation extends OSDOperation { + + final String sharedSecret; + final ServiceUUID localUUID; + + public InternalTruncateOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_INTERNAL_TRUNCATE; + } + + @Override + public void startRequest(final OSDRequest rq) { + final truncateRequest args = (truncateRequest)rq.getRequestArgs(); + + if (args.getNewFileSize() < 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "new_file_size for truncate must be >= 0"); + return; + } + + master.getStorageStage().truncate(args.getFileId(), args.getNewFileSize(), + rq.getLocationList().getLocalReplica().getStripingPolicy(), + rq.getLocationList().getLocalReplica(), rq.getCapability().getEpochNo(), rq.getCowPolicy(), + null, false, rq, + new TruncateCallback() { + + @Override + public void truncateComplete(OSDWriteResponse result, ErrorResponse error) { + step2(rq, result, error); + } + }); + } + + public void step2(final OSDRequest rq, OSDWriteResponse result, ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + } else { + //only locally + sendResponse(rq, result); + } + } + + + public void sendResponse(OSDRequest rq, OSDWriteResponse result) { + rq.sendSuccess(result,null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + truncateRequest rpcrq = (truncateRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + + + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/InvalidateXLocSetOperation.java b/java/servers/src/org/xtreemfs/osd/operations/InvalidateXLocSetOperation.java new file mode 100644 index 0000000..5725c42 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/InvalidateXLocSetOperation.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2012-2013 by Johannes Dillmann, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.mrc.stages.XLocSetCoordinator; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.PreprocStage.InvalidateXLocSetCallback; +import org.xtreemfs.osd.stages.StorageStage.InternalGetReplicaStateCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * Invalidates the XLocSet (view) on a certain replica.
    + * Invalidated replicas won't respond to operations until a newer XLocSet is installed. The installation will be + * executed implicitly when a operation with a newer XLocSet is requested.
    + * This operation is intended to be called from the MRCs {@link XLocSetCoordinator}. + */ +public class InvalidateXLocSetOperation extends OSDOperation { + final String sharedSecret; + final ServiceUUID localUUID; + + public InvalidateXLocSetOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_XLOC_SET_INVALIDATE; + } + + @Override + public void startRequest(final OSDRequest rq) { + xtreemfs_xloc_set_invalidateRequest rpcrq = (xtreemfs_xloc_set_invalidateRequest) rq.getRequestArgs(); + + master.getPreprocStage().invalidateXLocSet(rq, rpcrq.getFileCredentials(), true, + new InvalidateXLocSetCallback() { + + @Override + public void invalidateComplete(LeaseState leaseState, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + postInvalidation(rq, leaseState); + } + } + }); + } + + private void postInvalidation(final OSDRequest rq, final LeaseState leaseState) { + if (rq.getLocationList().getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)) { + invalidationFinished(rq, leaseState, null); + } else { + master.getStorageStage().internalGetReplicaState(rq.getFileId(), + rq.getLocationList().getLocalReplica().getStripingPolicy(), 0, + new InternalGetReplicaStateCallback() { + + @Override + public void getReplicaStateComplete(ReplicaStatus localState, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + invalidationFinished(rq, leaseState, localState); + } + } + }); + } + } + + private void invalidationFinished(OSDRequest rq, LeaseState leaseState, ReplicaStatus localState) { + xtreemfs_xloc_set_invalidateResponse.Builder response = xtreemfs_xloc_set_invalidateResponse.newBuilder(); + response.setLeaseState(leaseState); + + if (localState != null) { + response.setReplicaStatus(localState); + } + + rq.sendSuccess(response.build(), null); + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_xloc_set_invalidateRequest rpcrq = (xtreemfs_xloc_set_invalidateRequest) rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public boolean bypassViewValidation() { + // View validation will be handled at {@link PreprocStage#invalidateXLocSet()}. + return true; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/KeepFileOpenOperation.java b/java/servers/src/org/xtreemfs/osd/operations/KeepFileOpenOperation.java new file mode 100644 index 0000000..9471176 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/KeepFileOpenOperation.java @@ -0,0 +1,92 @@ +///* Copyright (c) 2009 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin. +// +// This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based +// Grid Operating System, see for more details. +// The XtreemOS project has been developed with the financial support of the +// European Commission's IST program under contract #FP6-033576. +// +// XtreemFS is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2 of the License, or (at your option) +// any later version. +// +// XtreemFS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with XtreemFS. If not, see . +// */ +///* +// * AUTHORS: Björn Kolbeck (ZIB) +// */ +// +//package org.xtreemfs.osd.operations; +// +//import org.xtreemfs.common.Capability; +//import org.xtreemfs.foundation.buffer.ReusableBuffer; +//import org.xtreemfs.common.uuids.ServiceUUID; +//import org.xtreemfs.common.xloc.XLocations; +//import org.xtreemfs.interfaces.OSDInterface.keep_file_openRequest; +//import org.xtreemfs.interfaces.OSDInterface.keep_file_openResponse; +//import org.xtreemfs.foundation.oncrpc.utils.Serializable; +//import org.xtreemfs.osd.OSDRequest; +//import org.xtreemfs.osd.OSDRequestDispatcher; +// +///** +// * +// * @author bjko +// */ +//public class KeepFileOpenOperation extends OSDOperation { +// +// private final int procId; +// +// private final String sharedSecret; +// +// private final ServiceUUID localUUID; +// +// private final keep_file_openResponse response; +// +// public KeepFileOpenOperation(OSDRequestDispatcher master) { +// super(master); +// keep_file_openRequest rq = new keep_file_openRequest(); +// response = new keep_file_openResponse(); +// sharedSecret = master.getConfig().getCapabilitySecret(); +// localUUID = master.getConfig().getUUID(); +// } +// +// @Override +// public int getProcedureId() { +// return procId; +// } +// +// @Override +// public void startRequest(OSDRequest rq) { +// //don't need to do anything, all done in proc stage! +// rq.sendSuccess(response); +// } +// +// @Override +// public void startInternalEvent(Object[] args) { +// throw new UnsupportedOperationException("Not supported yet."); +// } +// +// @Override +// public Serializable parseRPCMessage(ReusableBuffer data, OSDRequest rq) throws Exception { +// keep_file_openRequest rpcrq = new keep_file_openRequest(); +// rpcrq.deserialize(data); +// +// rq.setFileId(rpcrq.getFile_id()); +// rq.setCapability(new Capability(rpcrq.getCredentials().getXcap(),sharedSecret)); +// rq.setLocationList(new XLocations(rpcrq.getCredentials().getXlocs(), localUUID)); +// +// return rpcrq; +// } +// +// @Override +// public boolean requiresCapability() { +// return true; +// } +// +//} diff --git a/java/servers/src/org/xtreemfs/osd/operations/LocalReadOperation.java b/java/servers/src/org/xtreemfs/osd/operations/LocalReadOperation.java new file mode 100755 index 0000000..a2803f6 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/LocalReadOperation.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2009 Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import java.io.IOException; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.stages.StorageStage.GetObjectListCallback; +import org.xtreemfs.osd.stages.StorageStage.ReadObjectCallback; +import org.xtreemfs.osd.storage.ObjectInformation; +import org.xtreemfs.osd.storage.ObjectInformation.ObjectStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +import com.google.protobuf.ByteString; + +public final class LocalReadOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public LocalReadOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_INTERNAL_READ_LOCAL; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_internal_read_localRequest args = (xtreemfs_internal_read_localRequest) rq + .getRequestArgs(); + + // System.out.println("rq: " + args); + + if (args.getObjectNumber() < 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "object number must be >= 0"); + return; + } + + final StripingPolicyImpl sp = rq.getLocationList().getLocalReplica().getStripingPolicy(); + + master.getStorageStage().readObject(args.getFileId(), args.getObjectNumber(), sp, + (int) args.getOffset(), (int) args.getLength(), + rq.getCapability().getSnapConfig() == SnapConfig.SNAP_CONFIG_ACCESS_SNAP ? rq.getCapability() + .getSnapTimestamp() : 0, rq, new ReadObjectCallback() { + + @Override + public void readComplete(ObjectInformation result, ErrorResponse error) { + postRead(rq, args, result, error); + } + }); + } + + public void postRead(final OSDRequest rq, final xtreemfs_internal_read_localRequest args, + final ObjectInformation result, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + if (args.getAttachObjectList()) { // object list is requested + master.getStorageStage().getObjectSet(args.getFileId(), rq.getLocationList().getLocalReplica().getStripingPolicy(), rq, new GetObjectListCallback() { + @Override + public void getObjectSetComplete(ObjectSet objectSet, ErrorResponse error) { + postReadObjectSet(rq, args, result, objectSet, error); + } + }); + } else + readFinish(rq, args, result, null); + } + } + + public void postReadObjectSet(final OSDRequest rq, xtreemfs_internal_read_localRequest args, + ObjectInformation data, ObjectSet result, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + // serialize objectSet + ReusableBuffer objectSetBuffer = null; + byte[] serialized; + try { + serialized = result.getSerializedBitSet(); + + ObjectList objList = ObjectList.newBuilder().setSet(ByteString.copyFrom(serialized)).setFirst(result.getFirstObjectNo()).setStripeWidth(result.getStripeWidth()).build(); + readFinish(rq, args, data, objList); + } catch (IOException e) { + rq.sendInternalServerError(e); + } + } + } + + private void readFinish(OSDRequest rq, xtreemfs_internal_read_localRequest args, + ObjectInformation result, ObjectList objectList) { + InternalObjectData data = null; + // send raw data + if (result.getStatus() == ObjectStatus.EXISTS) { + final boolean isRangeRequested = (args.getOffset() > 0) + || (args.getLength() < result.getStripeSize()); + if (isRangeRequested) { + data = result.getObjectData(true, (int) args.getOffset(), (int) args.getLength()); + } else { + data = new InternalObjectData(0, result.isChecksumInvalidOnOSD(), 0, result.getData()); + } + } + + else if (result.getStatus() == ObjectStatus.PADDING_OBJECT) { + final boolean isRangeRequested = (args.getOffset() > 0) + || (args.getLength() < result.getStripeSize()); + if (isRangeRequested) { + data = result.getObjectData(true, (int) args.getOffset(), (int) args.getLength()); + } else { + data = result.getObjectData(false, 0, (int) args.getLength()); + } + } + + else + data = new InternalObjectData(0, result.isChecksumInvalidOnOSD(), 0, null); + + master.objectSent(); + if (data.getData() != null) + master.dataSent(data.getData().capacity()); + + // System.out.println("resp: " + data); + sendResponse(rq, data, objectList); + } + + public void sendResponse(OSDRequest rq, InternalObjectData result, ObjectList objectList) { + + InternalReadLocalResponse.Builder readLocalResponse = InternalReadLocalResponse.newBuilder().setData(result.getMetadata()); + if (objectList != null) + readLocalResponse.addObjectSet(objectList); + rq.sendSuccess(readLocalResponse.build(),result.getData()); + } + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_internal_read_localRequest rpcrq = (xtreemfs_internal_read_localRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/LockAcquireOperation.java b/java/servers/src/org/xtreemfs/osd/operations/LockAcquireOperation.java new file mode 100644 index 0000000..303d7c5 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/LockAcquireOperation.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.PreprocStage.LockOperationCompleteCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * + *
    15.06.2009 + */ +public class LockAcquireOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public LockAcquireOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_LOCK_ACQUIRE; + } + + @Override + public void startRequest(final OSDRequest rq) { + final lockRequest args = (lockRequest) rq + .getRequestArgs(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG,Category.all,this,"lock_acquire for file %s by %010d%s (%d-%d)",args.getFileCredentials().getXcap().getFileId(), + args.getLockRequest().getClientPid(),args.getLockRequest().getClientUuid(), + args.getLockRequest().getOffset(),args.getLockRequest().getLength()); + } + +// System.out.println("rq: " + args); + + master.getPreprocStage().acquireLock(args.getLockRequest().getClientUuid(), args.getLockRequest().getClientPid(), args.getFileCredentials().getXcap().getFileId(), + args.getLockRequest().getOffset(), args.getLockRequest().getLength(), args.getLockRequest().getExclusive(), rq, new LockOperationCompleteCallback() { + + @Override + public void parseComplete(Lock result, ErrorResponse error) { + postAcquireLock(rq,args,result,error); + } + }); + } + + public void postAcquireLock(final OSDRequest rq, lockRequest args, + Lock lock, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + rq.sendSuccess(lock,null); + } + } + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + lockRequest rpcrq = (lockRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileCredentials().getXcap().getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/LockCheckOperation.java b/java/servers/src/org/xtreemfs/osd/operations/LockCheckOperation.java new file mode 100644 index 0000000..915b17b --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/LockCheckOperation.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.PreprocStage.LockOperationCompleteCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * + *
    15.06.2009 + */ +public class LockCheckOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public LockCheckOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_LOCK_CHECK; + } + + @Override + public void startRequest(final OSDRequest rq) { + final lockRequest args = (lockRequest) rq + .getRequestArgs(); + +// System.out.println("rq: " + args); + + master.getPreprocStage().checkLock(args.getLockRequest().getClientUuid(), args.getLockRequest().getClientPid(), args.getFileCredentials().getXcap().getFileId(), + args.getLockRequest().getOffset(), args.getLockRequest().getLength(), args.getLockRequest().getExclusive(), rq, new LockOperationCompleteCallback() { + + @Override + public void parseComplete(Lock result, ErrorResponse error) { + postAcquireLock(rq,args,result,error); + } + }); + } + + public void postAcquireLock(final OSDRequest rq, lockRequest args, + Lock lock, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + rq.sendSuccess(lock,null); + } + } + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + lockRequest rpcrq = (lockRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileCredentials().getXcap().getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/LockReleaseOperation.java b/java/servers/src/org/xtreemfs/osd/operations/LockReleaseOperation.java new file mode 100644 index 0000000..49f1aea --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/LockReleaseOperation.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.PreprocStage.LockOperationCompleteCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * + *
    15.06.2009 + */ +public class LockReleaseOperation extends OSDOperation { + final String sharedSecret; + + final ServiceUUID localUUID; + + public LockReleaseOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_LOCK_RELEASE; + } + + @Override + public void startRequest(final OSDRequest rq) { + final lockRequest args = (lockRequest) rq + .getRequestArgs(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG,Category.all,this,"lock_release for file %s by %010d%s",args.getFileCredentials().getXcap().getFileId(), + args.getLockRequest().getClientPid(),args.getLockRequest().getClientUuid(), + args.getLockRequest().getOffset(),args.getLockRequest().getLength()); + } + +// System.out.println("rq: " + args); + + master.getPreprocStage().unlock(args.getLockRequest().getClientUuid(), args.getLockRequest().getClientPid(), args.getFileCredentials().getXcap().getFileId(), rq, new LockOperationCompleteCallback() { + + @Override + public void parseComplete(Lock result, ErrorResponse error) { + postAcquireLock(rq,args,result,error); + } + }); + } + + public void postAcquireLock(final OSDRequest rq, lockRequest args, + Lock lock, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + rq.sendSuccess(lock,null); + } + } + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + lockRequest rpcrq = (lockRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileCredentials().getXcap().getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/OSDOperation.java b/java/servers/src/org/xtreemfs/osd/operations/OSDOperation.java new file mode 100644 index 0000000..8a16681 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/OSDOperation.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReferenceArray; + +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.client.RPCResponseAvailableListener; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; + + +public abstract class OSDOperation { + + + protected OSDRequestDispatcher master; + + + public OSDOperation(OSDRequestDispatcher master) { + this.master = master; + } + + public abstract int getProcedureId(); + + /** + * called after request was parsed and operation assigned. + * @param rq the new request + */ + public abstract void startRequest(OSDRequest rq); + + public abstract void startInternalEvent(Object[] args); + + /** + * Parses the request. Should also set XLocs, XCap and fileID. + * @param rq the request + * @return null if successful, error message otherwise + */ + public abstract ErrorResponse parseRPCMessage(OSDRequest rq); + + public abstract boolean requiresCapability(); + + /** + * By default the view contained in the location list stored in a {@link OSDRequest} will be validated (if it is + * present). If it is required an operation can be allowed to run, even if the view is outdated or the replica is + * invalidated. The view validation will be bypassed by returning true. + * + * @return false [default] + */ + public boolean bypassViewValidation() { + return false; + } + + public void waitForResponses(final RPCResponse[] responses, final ResponsesListener listener) { + + assert(responses.length > 0); + + final AtomicInteger count = new AtomicInteger(0); + + final AtomicReferenceArray stackTracePerRequest = new AtomicReferenceArray(responses.length); + + final RPCResponseAvailableListener l = new RPCResponseAvailableListener() { + + @Override + public void responseAvailable(RPCResponse r) { + // TODO(mberlin): Remove this once the cause for possible duplicate calls of responseAvailable() is found. + for (int i = 0; i < responses.length; i++) { + if (responses[i] == r) { + if (!stackTracePerRequest.compareAndSet(i, null, Thread.currentThread().getStackTrace())) { + StackTraceElement[] previousStackTrace = stackTracePerRequest.get(i); + + StringBuffer strace = new StringBuffer(); + for (int i1 = previousStackTrace.length-1; i1 >= 0; i1--) { + strace.append("\t"); + strace.append(previousStackTrace[i1].toString()); + } + throw new RuntimeException("responseAvailable() was already called here:\n"+strace.toString()); + } + + break; + } + } + + if (count.incrementAndGet() == responses.length) { + listener.responsesAvailable(); + } + } + }; + + for (RPCResponse r : responses) { + r.registerListener(l); + } + + } + + /*public void sendError(OSDRequest rq, Exception error) { + if (error instanceof ONCRPCException) { + rq.sendException((ONCRPCException) error); + } else { + rq.sendInternalServerError(error); + } + }*/ + + public static interface ResponsesListener { + + public void responsesAvailable(); + + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/RWRNotifyOperation.java b/java/servers/src/org/xtreemfs/osd/operations/RWRNotifyOperation.java new file mode 100644 index 0000000..1eb6a1e --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/RWRNotifyOperation.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.PreprocStage.DeleteOnCloseCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class RWRNotifyOperation extends OSDOperation { + + final String sharedSecret; + final ServiceUUID localUUID; + + public RWRNotifyOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_RWR_NOTIFY; + } + + @Override + public void startRequest(final OSDRequest rq) { + final FileCredentials args = (FileCredentials)rq.getRequestArgs(); + + + + if (!rq.getLocationList().containsOSD(localUUID)) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"RWR notify for file %s: REMOVE REPLICA",args.getXcap().getFileId()); + } + master.getPreprocStage().checkDeleteOnClose(args.getXcap().getFileId(), new DeleteOnCloseCallback() { + + @Override + public void deleteOnCloseResult(boolean isDeleteOnClose, ErrorResponse error) { + sendResult(rq, error); + } + }); + } else { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this,"RWR notify for file %s: FORCE RESET",args.getXcap().getFileId()); + } + master.getRWReplicationStage().eventForceReset(args, rq.getLocationList()); + sendResult(rq, null); + } + } + + + + public void sendResult(final OSDRequest rq, ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + } else { + //only locally + sendResponse(rq); + } + } + + + public void sendResponse(OSDRequest rq) { + rq.sendSuccess(null,null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + FileCredentials rpcrq = (FileCredentials)rq.getRequestArgs(); + rq.setFileId(rpcrq.getXcap().getFileId()); + rq.setCapability(new Capability(rpcrq.getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + + + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/operations/ReadOperation.java b/java/servers/src/org/xtreemfs/osd/operations/ReadOperation.java new file mode 100644 index 0000000..6732071 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/ReadOperation.java @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import java.io.IOException; +import java.util.List; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.rwre.RWReplicationStage; +import org.xtreemfs.osd.stages.ReplicationStage.FetchObjectCallback; +import org.xtreemfs.osd.stages.StorageStage.ReadObjectCallback; +import org.xtreemfs.osd.storage.ObjectInformation; +import org.xtreemfs.osd.storage.ObjectInformation.ObjectStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class ReadOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public ReadOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_READ; + } + + @Override + public void startRequest(final OSDRequest rq) { + final readRequest args = (readRequest) rq.getRequestArgs(); + + if (args.getObjectNumber() < 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "object number must be >= 0"); + return; + } + + if (args.getOffset() < 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "offset must be >= 0"); + return; + } + + if (args.getLength() < 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "length must be >= 0"); + return; + } + + final StripingPolicyImpl sp = rq.getLocationList().getLocalReplica().getStripingPolicy(); + + if (args.getLength()+args.getOffset() > sp.getStripeSizeForObject(0)) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "length + ofset must be <= "+sp.getStripeSizeForObject(0)+" (stripe size)"); + return; + } + + // TODO(jdillmann): Use centralized method to check if a lease is required. + if (rq.getLocationList().getNumReplicas() > 1 + && ReplicaUpdatePolicies.isRwReplicated(rq.getLocationList().getReplicaUpdatePolicy())) { + rwReplicatedRead(rq, args); + } else { + final long snapVerTS = rq.getCapability().getSnapConfig() == SnapConfig.SNAP_CONFIG_ACCESS_SNAP? rq.getCapability().getSnapTimestamp(): 0; + + master.getStorageStage().readObject(args.getFileId(), args.getObjectNumber(), sp, + args.getOffset(),args.getLength(), snapVerTS, rq, new ReadObjectCallback() { + + @Override + public void readComplete(ObjectInformation result, ErrorResponse error) { + postRead(rq, args, result, error); + } + }); + } + } + + public void rwReplicatedRead(final OSDRequest rq, final readRequest args) { + master.getRWReplicationStage().prepareOperation(args.getFileCredentials(), rq.getLocationList(), args.getObjectNumber(), args.getObjectVersion(), + RWReplicationStage.Operation.READ, new RWReplicationStage.RWReplicationCallback() { + + @Override + public void success(long newObjectVersion) { + final StripingPolicyImpl sp = rq.getLocationList().getLocalReplica().getStripingPolicy(); + + final long snapVerTS = rq.getCapability().getSnapConfig() == SnapConfig.SNAP_CONFIG_ACCESS_SNAP? rq.getCapability().getSnapTimestamp(): 0; + + //FIXME: ignore canExecOperation for now... + master.getStorageStage().readObject(args.getFileId(), args.getObjectNumber(), sp, + args.getOffset(),args.getLength(), snapVerTS, rq, new ReadObjectCallback() { + + @Override + public void readComplete(ObjectInformation result, ErrorResponse error) { + postRead(rq, args, result, error); + } + }); + } + + @Override + public void redirect(String redirectTo) { + rq.getRPCRequest().sendRedirect(redirectTo); + } + + @Override + public void failed(ErrorResponse err) { + rq.sendError(err); + } + }, rq); + } + + public void postRead(final OSDRequest rq, readRequest args, ObjectInformation result, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + if (result.getStatus() == ObjectInformation.ObjectStatus.DOES_NOT_EXIST + && rq.getLocationList().getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY) + && rq.getLocationList().getNumReplicas() > 1 + && !rq.getLocationList().getLocalReplica().isComplete()) { + // read only replication! + readReplica(rq, args); + } else { + if (rq.getLocationList().getLocalReplica().isStriped()) { + // striped read + stripedRead(rq, args, result); + } else { + // non-striped case + nonStripedRead(rq, args, result); + } + } + } + + } + + private void nonStripedRead(OSDRequest rq, readRequest args, ObjectInformation result) { + + final boolean isLastObjectOrEOF = result.getLastLocalObjectNo() <= args.getObjectNumber(); + readFinish(rq, args, result, isLastObjectOrEOF); + } + + private void stripedRead(final OSDRequest rq, final readRequest args, final ObjectInformation result) { + InternalObjectData data; + final long objNo = args.getObjectNumber(); + final long lastKnownObject = Math.max(result.getLastLocalObjectNo(), result.getGlobalLastObjectNo()); + final boolean isLastObjectLocallyKnown = lastKnownObject <= objNo; + //check if GMAX must be fetched to determin EOF + if ((objNo > lastKnownObject) || + (objNo == lastKnownObject) && (result.getData() != null) && (result.getData().remaining() < result.getStripeSize())) { + try { + final List osds = rq.getLocationList().getLocalReplica().getOSDs(); + final RPCResponse[] gmaxRPCs = new RPCResponse[osds.size() - 1]; + int cnt = 0; + for (ServiceUUID osd : osds) { + if (!osd.equals(localUUID)) { + gmaxRPCs[cnt++] = master.getOSDClient().xtreemfs_internal_get_gmax(osd.getAddress(), RPCAuthentication.authNone,RPCAuthentication.userService,args.getFileCredentials(),args.getFileId()); + } + } + this.waitForResponses(gmaxRPCs, new ResponsesListener() { + + @Override + public void responsesAvailable() { + stripedReadAnalyzeGmax(rq, args, result, gmaxRPCs); + } + }); + } catch (IOException ex) { + rq.sendInternalServerError(ex); + return; + } + } else { + readFinish(rq, args, result, isLastObjectLocallyKnown); + } + } + + private void stripedReadAnalyzeGmax(final OSDRequest rq, final readRequest args, + final ObjectInformation result, RPCResponse[] gmaxRPCs) { + long maxObjNo = -1; + long maxTruncate = -1; + + try { + for (int i = 0; i < gmaxRPCs.length; i++) { + InternalGmax gmax = (InternalGmax) gmaxRPCs[i].get(); + if ((gmax.getLastObjectId() > maxObjNo) && (gmax.getEpoch() >= maxTruncate)) { + //found new max + maxObjNo = gmax.getLastObjectId(); + maxTruncate = gmax.getEpoch(); + } + } + final boolean isLastObjectLocallyKnown = maxObjNo <= args.getObjectNumber(); + readFinish(rq, args, result, isLastObjectLocallyKnown); + + if (args.getFileCredentials().getXcap().getSnapConfig() == SnapConfig.SNAP_CONFIG_ACCESS_SNAP) + return; + + //and update gmax locally + master.getStorageStage().receivedGMAX_ASYNC(args.getFileId(), maxTruncate, maxObjNo); + + } catch (Exception ex) { + rq.sendInternalServerError(ex); + } finally { + for (RPCResponse r : gmaxRPCs) + r.freeBuffers(); + } + + } + + private void readFinish(OSDRequest rq, readRequest args, ObjectInformation result, boolean isLastObjectOrEOF) { + //final boolean isRangeRequested = (args.getOffset() > 0) || (args.getLength() < result.getStripeSize()); + InternalObjectData data; + data = result.getObjectData(isLastObjectOrEOF, args.getOffset(), args.getLength()); + + //must deliver enough data! + int datasize = 0; + if (data.getData() != null) + datasize = data.getData().remaining(); + datasize += data.getZero_padding(); + assert((isLastObjectOrEOF && datasize <= args.getLength()) || + (!isLastObjectOrEOF && datasize == args.getLength())); + if (Logging.isDebug() && (datasize == 0)) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "zero data response (EOF), file %s",args.getFileId()); + } + master.objectSent(); + if (data.getData() != null) + master.dataSent(data.getData().capacity()); + + sendResponse(rq, data); + } + + private void readReplica(final OSDRequest rq, final readRequest args) { + XLocations xLoc = rq.getLocationList(); + StripingPolicyImpl sp = xLoc.getLocalReplica().getStripingPolicy(); + + // check if it is a EOF + if (args.getObjectNumber() > sp.getObjectNoForOffset(xLoc.getXLocSet().getReadOnlyFileSize() - 1)) { + ObjectInformation objectInfo = new ObjectInformation(ObjectStatus.DOES_NOT_EXIST, null, sp + .getStripeSizeForObject(args.getObjectNumber())); + objectInfo.setGlobalLastObjectNo(xLoc.getXLocSet().getReadOnlyFileSize()); + + readFinish(rq, args, objectInfo, true); + } else { + master.getReplicationStage().fetchObject(args.getFileId(), args.getObjectNumber(), xLoc, + rq.getCapability(), rq.getCowPolicy(), rq, new FetchObjectCallback() { + @Override + public void fetchComplete(ObjectInformation objectInfo, ErrorResponse error) { + postReadReplica(rq, args, objectInfo, error); + } + }); + } + } + + public void postReadReplica(final OSDRequest rq, readRequest args, ObjectInformation result, ErrorResponse error) { + XLocations xLoc = rq.getLocationList(); + StripingPolicyImpl sp = xLoc.getLocalReplica().getStripingPolicy(); + + if (error != null) { + rq.sendError(error); + } else { + try { + // replication always delivers full objects => cut data + if (args.getOffset() > 0 || args.getLength() < result.getStripeSize()) { + if (result.getStatus() == ObjectStatus.EXISTS) { + // cut range from object data + final int availData = result.getData().remaining(); + if (availData - args.getOffset() <= 0) { + // offset is beyond available data + BufferPool.free(result.getData()); + result.setData(BufferPool.allocate(0)); + } else { + if (availData - args.getOffset() >= args.getLength()) { + result.getData().range(args.getOffset(), args.getLength()); + } else { + // less data than requested + result.getData().range(args.getOffset(), availData - args.getOffset()); + } + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + rq.sendInternalServerError(ex); + return; + } + + if (args.getObjectNumber() == sp.getObjectNoForOffset(xLoc.getXLocSet().getReadOnlyFileSize() - 1)) + // last object + readFinish(rq, args, result, true); + else + readFinish(rq, args, result, false); + } + } + + public void sendResponse(OSDRequest rq, InternalObjectData result) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, result.toString()); + } + rq.sendSuccess(result.getMetadata(),result.getData()); + } + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + readRequest rpcrq = (readRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileCredentials().getXcap().getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/RepairObjectOperation.java b/java/servers/src/org/xtreemfs/osd/operations/RepairObjectOperation.java new file mode 100644 index 0000000..15b87e1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/RepairObjectOperation.java @@ -0,0 +1,104 @@ +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.ReplicationStage.FetchObjectCallback; +import org.xtreemfs.osd.storage.ObjectInformation; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public class RepairObjectOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public RepairObjectOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_REPAIR_OBJECT; + } + + @Override + public void startRequest(OSDRequest rq) { + final xtreemfs_repair_objectRequest args = (xtreemfs_repair_objectRequest) rq.getRequestArgs(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Repair object request for file %s-%d", args.getFileId(), + args.getObjectNumber()); + } + String replPolicy = rq.getLocationList().getReplicaUpdatePolicy(); + + if (replPolicy.equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)) { + repairROnlyObject(rq, args); + } else { + repairRWObject(rq, args); + } + } + + private void repairROnlyObject(final OSDRequest rq, final xtreemfs_repair_objectRequest args) { + if (rq.getLocationList().getLocalReplica().isComplete()) { + + //rest complete flag, otherwise replica is unable to fetch objects + rq.getLocationList().getLocalReplica().resetCompleteFlagAndRestoreStrageyFlag(); + } + //Assumption: fetched Object is not corrupted + master.getReplicationStage().fetchObject(args.getFileId(), args.getObjectNumber(), rq.getLocationList(), + rq.getCapability(), rq.getCowPolicy(), rq, new FetchObjectCallback() { + + @Override + public void fetchComplete(ObjectInformation objectInfo, ErrorResponse error) { + if (error == null) { + rq.sendSuccess(null, null); + } else { + rq.sendError(error); + } + } + }); + } + + private void repairRWObject(final OSDRequest rq, final xtreemfs_repair_objectRequest args) { + //TODO(lukas) add rw support + } + + @Override + public void startInternalEvent(Object[] args) { + // TODO Auto-generated method stub + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + xtreemfs_repair_objectRequest rpcrq = (xtreemfs_repair_objectRequest) rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/RequestTimeHelper.java b/java/servers/src/org/xtreemfs/osd/operations/RequestTimeHelper.java new file mode 100644 index 0000000..f5f9b15 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/RequestTimeHelper.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import java.util.ArrayList; + +/** + * + * @author bjko + */ +public class RequestTimeHelper { + + private final ArrayList mps; + + private final ArrayList mpNanos; + + public RequestTimeHelper() { + mpNanos = new ArrayList(30); + mps = new ArrayList(30); + mps.add("Start"); + mpNanos.add(System.nanoTime()); + } + + public void addMP(String name) { + final long now = System.nanoTime(); + + + mpNanos.add(now); + mps.add(name); + } + + public void print() { + System.out.println("rq stats--------------------------------"); + long total = 0; + for (int i = 1; i < mps.size(); i++) { + final long lastMp = mpNanos.get(i-1); + final long dur = mpNanos.get(i)-lastMp; + total += dur; + System.out.format(" %10.4f ms %s\n",(((double)dur)/1e6),mps.get(i)); + } + System.out.format(" %10.4f ms total\n",(((double)total)/1e6)); + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/ShutdownOperation.java b/java/servers/src/org/xtreemfs/osd/operations/ShutdownOperation.java new file mode 100644 index 0000000..88058ee --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/ShutdownOperation.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * + * @author bjko + */ +public class ShutdownOperation extends OSDOperation { + + public ShutdownOperation(OSDRequestDispatcher master) { + super(master); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_SHUTDOWN; + } + + @Override + public void startRequest(OSDRequest rq) { + + // check password to ensure that user is authorized + Auth authData = rq.getRPCRequest().getHeader().getRequestHeader().getAuthData(); + if (master.getConfig().getAdminPassword().length() > 0 + && !master.getConfig().getAdminPassword().equals(authData.getAuthPasswd())) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, "this operation requires an admin password"); + return; + } + + try { + rq.sendSuccess(null,null); + Thread.sleep(100); + master.asyncShutdown(); + } catch (Throwable thr) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "exception during shutdown"); + Logging.logError(Logging.LEVEL_ERROR, this, thr); + } + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + rq.setFileId(""); + + return null; + } + + @Override + public boolean requiresCapability() { + return false; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/TruncateOperation.java b/java/servers/src/org/xtreemfs/osd/operations/TruncateOperation.java new file mode 100644 index 0000000..a7293a0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/TruncateOperation.java @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import java.io.IOException; +import java.util.List; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.rwre.RWReplicationStage; +import org.xtreemfs.osd.stages.StorageStage.TruncateCallback; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class TruncateOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public TruncateOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_TRUNCATE; + } + + @Override + public void startRequest(final OSDRequest rq) { + final truncateRequest args = (truncateRequest) rq.getRequestArgs(); + + if (args.getNewFileSize() < 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "new_file_size for truncate must be >= 0"); + return; + } + + if (!rq.getLocationList().getLocalReplica().getHeadOsd().equals(localUUID)) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "truncate must be executed at the head OSD (first OSD in replica)"); + return; + } + + if (rq.getLocationList().getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)) { + // file is read only + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EPERM, "Cannot write on read-only files."); + return; + } + + // TODO(jdillmann): Use centralized method to check if a lease is required. + if (rq.getLocationList().getNumReplicas() > 1 + && ReplicaUpdatePolicies.isRwReplicated(rq.getLocationList().getReplicaUpdatePolicy())) { + rwReplicatedTruncate(rq, args); + } else { + + master.getStorageStage().truncate(args.getFileId(), args.getNewFileSize(), + rq.getLocationList().getLocalReplica().getStripingPolicy(), + rq.getLocationList().getLocalReplica(), rq.getCapability().getEpochNo(), rq.getCowPolicy(), + null, false, rq, + new TruncateCallback() { + + @Override + public void truncateComplete(OSDWriteResponse result, ErrorResponse error) { + step2(rq, args, result, error); + } + }); + } + } + + public void rwReplicatedTruncate(final OSDRequest rq, + final truncateRequest args) { + master.getRWReplicationStage().prepareOperation(args.getFileCredentials(), rq.getLocationList(), 0, 0, RWReplicationStage.Operation.TRUNCATE, new RWReplicationStage.RWReplicationCallback() { + + @Override + public void success(final long newObjectVersion) { + final StripingPolicyImpl sp = rq.getLocationList().getLocalReplica().getStripingPolicy(); + + //FIXME: ignore canExecOperation for now... + master.getStorageStage().truncate(args.getFileId(), args.getNewFileSize(), + rq.getLocationList().getLocalReplica().getStripingPolicy(), + rq.getLocationList().getLocalReplica(), rq.getCapability().getEpochNo(), rq.getCowPolicy(), + newObjectVersion, true, rq, new TruncateCallback() { + + @Override + public void truncateComplete(OSDWriteResponse result, ErrorResponse error) { + replicateTruncate(rq, newObjectVersion, args, result, error); + } + }); + } + + @Override + public void redirect(String redirectTo) { + rq.getRPCRequest().sendRedirect(redirectTo); + } + + @Override + public void failed(ErrorResponse err) { + rq.sendError(err); + } + }, rq); + } + + public void replicateTruncate(final OSDRequest rq, + final long newObjVersion, + final truncateRequest args, + final OSDWriteResponse result, ErrorResponse error) { + if (error != null) + step2(rq, args, result, error); + else { + master.getRWReplicationStage().replicateTruncate(args.getFileCredentials(), + rq.getLocationList(),args.getNewFileSize(), newObjVersion, + new RWReplicationStage.RWReplicationCallback() { + + @Override + public void success(long newObjectVersion) { + step2(rq, args, result, null); + } + + @Override + public void redirect(String redirectTo) { + rq.getRPCRequest().sendRedirect(redirectTo); + } + + @Override + public void failed(ErrorResponse err) { + rq.sendError(err); + } + }, rq); + + } + } + + public void step2(final OSDRequest rq, + final truncateRequest args, + OSDWriteResponse result, ErrorResponse error) { + + if (error != null) { + rq.sendError(error); + } else { + //check for striping + if (rq.getLocationList().getLocalReplica().isStriped()) { + //disseminate internal truncate to all other OSDs + disseminateTruncates(rq, args, result); + } else { + //non-striped + sendResponse(rq, result); + } + + } + } + + private void disseminateTruncates(final OSDRequest rq, + final truncateRequest args, + final OSDWriteResponse result) { + try { + final List osds = rq.getLocationList().getLocalReplica().getOSDs(); + final RPCResponse[] gmaxRPCs = new RPCResponse[osds.size() - 1]; + int cnt = 0; + for (ServiceUUID osd : osds) { + if (!osd.equals(localUUID)) { + gmaxRPCs[cnt++] = master.getOSDClient().xtreemfs_internal_truncate(osd.getAddress(), + RPCAuthentication.authNone,RPCAuthentication.userService, + args.getFileCredentials(), args.getFileId(), args.getNewFileSize()); + } + + } + this.waitForResponses(gmaxRPCs, new ResponsesListener() { + + @Override + public void responsesAvailable() { + analyzeTruncateResponses(rq, result, gmaxRPCs); + } + }); + } catch (IOException ex) { + rq.sendInternalServerError(ex); + } catch (Throwable ex) { + rq.sendInternalServerError(ex); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + return; + + } + + + } + + private void analyzeTruncateResponses(OSDRequest rq, OSDWriteResponse result, RPCResponse[] gmaxRPCs) { + //analyze results + try { + for (int i = 0; i < + gmaxRPCs.length; i++) { + gmaxRPCs[i].get(); + } + + sendResponse(rq, result); + } catch (IOException ex) { + rq.sendInternalServerError(ex); + } catch (Throwable ex) { + rq.sendInternalServerError(ex); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } finally { + for (RPCResponse r : gmaxRPCs) { + r.freeBuffers(); + } + } + + } + + public void sendResponse(OSDRequest rq, OSDWriteResponse result) { + rq.sendSuccess(result,null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + truncateRequest rpcrq = (truncateRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/VivaldiPingOperation.java b/java/servers/src/org/xtreemfs/osd/operations/VivaldiPingOperation.java new file mode 100644 index 0000000..f923229 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/VivaldiPingOperation.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + + +import java.net.InetSocketAddress; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.VivaldiStage; +import org.xtreemfs.osd.vivaldi.VivaldiNode; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * + *
    15.06.2009 + */ +public class VivaldiPingOperation extends OSDOperation { + + final String sharedSecret; + + final ServiceUUID localUUID; + + public VivaldiPingOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_XTREEMFS_PING; + } + + @Override + public void startRequest(final OSDRequest rq) { + final xtreemfs_pingMesssage args = (xtreemfs_pingMesssage) rq + .getRequestArgs(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG,Category.all,this,"vivaldi ping with coordinates %s",VivaldiNode.coordinatesToString(args.getCoordinates())); + } + + // Check for udp connections which don't have a channel. + if (rq.getRPCRequest().getConnection().getChannel() == null) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG,Category.all,this,"Async Ping"); + } + master.getVivaldiStage().getVivaldiCoordinatesAsync(args, (InetSocketAddress)rq.getRPCRequest().getSenderAddress(), rq); + } else { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG,Category.all,this,"Sync Ping"); + } + master.getVivaldiStage().getVivaldiCoordinatesSync(args, rq, new VivaldiStage.VivaldiPingCallback() { + + @Override + public void coordinatesCallback(VivaldiCoordinates myCoordinates, ErrorResponse error) { + xtreemfs_pingMesssage msg = xtreemfs_pingMesssage.newBuilder().setCoordinates(myCoordinates).setRequestResponse(false).build(); + rq.sendSuccess(msg, null); + } + }); + } + + } + + /*public void postGetCoordinates(final OSDRequest rq, VivaldiCoordinates args, + VivaldiCoordinates coordinates, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + rq.sendSuccess(coordinates,null); + } + }*/ + + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + rq.setFileId(""); + + return null; + } + + @Override + public boolean requiresCapability() { + return false; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/operations/WriteOperation.java b/java/servers/src/org/xtreemfs/osd/operations/WriteOperation.java new file mode 100644 index 0000000..677df3a --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/operations/WriteOperation.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.operations; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.rwre.RWReplicationStage; +import org.xtreemfs.osd.stages.StorageStage.ReadObjectCallback; +import org.xtreemfs.osd.stages.StorageStage.WriteObjectCallback; +import org.xtreemfs.osd.storage.ObjectInformation; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public final class WriteOperation extends OSDOperation { + + final String sharedSecret; + final ServiceUUID localUUID; + + public WriteOperation(OSDRequestDispatcher master) { + super(master); + sharedSecret = master.getConfig().getCapabilitySecret(); + localUUID = master.getConfig().getUUID(); + } + + @Override + public int getProcedureId() { + return OSDServiceConstants.PROC_ID_WRITE; + } + + @Override + public void startRequest(final OSDRequest rq) { + final writeRequest args = (writeRequest)rq.getRequestArgs(); + + if (args.getObjectNumber() < 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "object number must be >= 0"); + return; + } + + if (args.getOffset() < 0) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "offset must be >= 0"); + return; + } + + final StripingPolicyImpl sp = rq.getLocationList().getLocalReplica().getStripingPolicy(); + + if (args.getOffset() >= sp.getStripeSizeForObject(args.getObjectNumber())) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "offset must be < stripe size"); + return; + } + + if (rq.getLocationList().getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)) { + // file is read only + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EPERM, "Cannot write on read-only files."); + } else { + + boolean syncWrite = (rq.getCapability().getAccessMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_SYNC.getNumber()) > 0; + + + master.objectReceived(); + master.dataReceived(rq.getRPCRequest().getData().capacity()); + + // TODO(jdillmann): Use centralized method to check if a lease is required. + if (rq.getLocationList().getNumReplicas() > 1 + && ReplicaUpdatePolicies.isRwReplicated(rq.getLocationList().getReplicaUpdatePolicy())) { + replicatedWrite(rq,args,syncWrite); + } else { + + ReusableBuffer viewBuffer = rq.getRPCRequest().getData().createViewBuffer(); + master.getStorageStage().writeObject(args.getFileId(), args.getObjectNumber(), sp, + args.getOffset(), viewBuffer, rq.getCowPolicy(), + rq.getLocationList(), syncWrite, null, rq, viewBuffer, new WriteObjectCallback() { + + @Override + public void writeComplete(OSDWriteResponse result, ErrorResponse error) { + sendResult(rq, result, error); + } + }); + } + } + } + + public void replicatedWrite(final OSDRequest rq, final writeRequest args, final boolean syncWrite) { + //prepareWrite first + + master.getRWReplicationStage().prepareOperation(args.getFileCredentials(), rq.getLocationList(),args.getObjectNumber(), + args.getObjectVersion(), RWReplicationStage.Operation.WRITE, + new RWReplicationStage.RWReplicationCallback() { + + @Override + public void success(final long newObjectVersion) { + assert(newObjectVersion > 0); + + //FIXME: ignore canExecOperation for now... + ReusableBuffer viewBuffer = rq.getRPCRequest().getData().createViewBuffer(); + master.getStorageStage().writeObject(args.getFileId(), args.getObjectNumber(), + rq.getLocationList().getLocalReplica().getStripingPolicy(), + args.getOffset(), viewBuffer, rq.getCowPolicy(), + rq.getLocationList(), syncWrite, newObjectVersion, rq, viewBuffer, new WriteObjectCallback() { + + @Override + public void writeComplete(OSDWriteResponse result, ErrorResponse error) { + if (error != null) + sendResult(rq, null, error); + else + sendUpdates(rq,args,result,newObjectVersion); + } + }); + } + + @Override + public void redirect(String redirectTo) { + rq.getRPCRequest().sendRedirect(redirectTo); + } + + @Override + public void failed(ErrorResponse err) { + rq.sendError(err); + } + }, rq); + + } + + public void sendUpdates(final OSDRequest rq, final writeRequest args, final OSDWriteResponse result, final long newObjVersion) { + final StripingPolicyImpl sp = rq.getLocationList().getLocalReplica().getStripingPolicy(); + if (rq.getRPCRequest().getData().remaining() == sp.getStripeSizeForObject(args.getObjectNumber())) { + + ReusableBuffer viewBuffer = rq.getRPCRequest().getData().createViewBuffer(); + + sendUpdates2(rq, args, result, newObjVersion, new InternalObjectData(args.getObjectData(), viewBuffer), viewBuffer); + } else { + + master.getStorageStage().readObject(args.getFileId(), args.getObjectNumber(), sp, 0, -1, 0l, rq, new ReadObjectCallback() { + + @Override + public void readComplete(ObjectInformation result2, ErrorResponse error) { + if (error != null) + sendResult(rq, null, error); + else { + InternalObjectData od = result2.getObjectData(false, 0, sp.getStripeSizeForObject(args.getObjectNumber())); + sendUpdates2(rq, args, result, newObjVersion, od, null); + } + } + }); + } + } + public void sendUpdates2(final OSDRequest rq, final writeRequest args, final OSDWriteResponse result, final long newObjVersion, + final InternalObjectData data, final ReusableBuffer createdViewBuffer) { + master.getRWReplicationStage().replicatedWrite(args.getFileCredentials(),rq.getLocationList(), + args.getObjectNumber(), newObjVersion, data, createdViewBuffer, + new RWReplicationStage.RWReplicationCallback() { + + @Override + public void success(long newObjectVersion) { + sendResult(rq, result, null); + } + + @Override + public void redirect(String redirectTo) { + rq.getRPCRequest().sendRedirect(redirectTo); + } + + @Override + public void failed(ErrorResponse err) { + rq.sendError(err); + } + }, rq); + } + + + public void sendResult(final OSDRequest rq, OSDWriteResponse result, ErrorResponse error) { + if (error != null) { + rq.sendError(error); + } else { + sendResponse(rq, result); + } + + } + + public void sendResponse(OSDRequest rq, OSDWriteResponse result) { + rq.sendSuccess(result,null); + } + + @Override + public ErrorResponse parseRPCMessage(OSDRequest rq) { + try { + writeRequest rpcrq = (writeRequest)rq.getRequestArgs(); + rq.setFileId(rpcrq.getFileCredentials().getXcap().getFileId()); + rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); + rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); + + return null; + } catch (InvalidXLocationsException ex) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); + } catch (Throwable ex) { + return ErrorUtils.getInternalServerError(ex); + } + } + + @Override + public boolean requiresCapability() { + return true; + } + + @Override + public void startInternalEvent(Object[] args) { + throw new UnsupportedOperationException("Not supported yet."); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/replication/ObjectDissemination.java b/java/servers/src/org/xtreemfs/osd/replication/ObjectDissemination.java new file mode 100755 index 0000000..1d72745 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/ObjectDissemination.java @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication; + +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.LRUCache; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.monitoring.Monitoring; +import org.xtreemfs.foundation.monitoring.MonitoringLog; +import org.xtreemfs.foundation.monitoring.NumberMonitoring; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.ErrorCodes; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.TransferStrategyException; +import org.xtreemfs.osd.stages.Stage.StageRequest; +import org.xtreemfs.osd.storage.CowPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; + +/** + * Handles the fetching of replicas.
    + * 15.09.2008 + */ +public class ObjectDissemination { + private final OSDRequestDispatcher master; + + /** + * controls how many fetch-object-requests will be allowed to sent overall by all files (used for + * load-balancing) + */ + private static final int MAX_OBJECTS_IN_PROGRESS_OVERALL = 20; + + /** + * objects of these files are downloading currently or in future
    + * key: fileID + */ + private ConcurrentHashMap filesInProgress; + + /** + * Simple LRU-cache for last completed files.
    + * NOTE: contains only NOT canceled files + */ + LRUCache lastCompletedFilesCache; + + /* + * monitoring stuff + */ + private Thread monitoringThread = null; + + private NumberMonitoring monitoring; + + private AtomicLong monitoringReadDataSizeInLastXs; + + /** + * Measures the throughput of the last 1 second. + */ + public static final String MONITORING_KEY_THROUGHPUT_OF_LAST_X_SECONDS = "REPLICATION: average throughput over all files of last X seconds (KB/s)"; + +// public static final String MONITORING_KEY_REQUIRED_TIME_FOR_COMPLETING_REPLICA = "REPLICATION: time (ms) required for completing file "; +// +// /* +// * if the data contains holes this metric will be falsified +// */ +// public static final String MONITORING_KEY_UNNECESSARY_REQUESTS = "REPLICATION: number of unnecessary requests"; +// +// public static final String MONITORING_KEY_OBJECT_LIST_OVERHEAD = "REPLICATION: overhead of object lists transfer (bytes)"; + + public static final int MONITORING_THROUGHPUT_INTERVAL = 1000; // 10s + +// // FIXME: change output file +// public static final String MONITORING_OUTPUT_FILE = "/tmp/monitoringLog.txt"; + + public ObjectDissemination(final OSDRequestDispatcher master) { + this.master = master; + + this.filesInProgress = new ConcurrentHashMap(); + this.lastCompletedFilesCache = new LRUCache(20); + + // monitoring + this.monitoring = new NumberMonitoring(); + this.monitoringReadDataSizeInLastXs = new AtomicLong(0); + if (Monitoring.isEnabled()) { + // enable stats on client (maybe stats is already enabled) + //RPCNIOSocketClient.ENABLE_STATISTICS = true; + + try { + MonitoringLog.initialize(""); + } catch (IOException e1) { + // Auto-generated catch block + e1.printStackTrace(); + } + MonitoringLog.registerFor(monitoring, MONITORING_KEY_THROUGHPUT_OF_LAST_X_SECONDS); + // FIXME: debug stuff +// MonitoringLog.registerFor(monitoring, "StorageStage Queue"); + + // create new thread which monitors the average throughput of all active files in a given interval + monitoringThread = new Thread(new Runnable() { + @Override + public void run() { + try { + while (true) { + if (Thread.interrupted()) + break; + Thread.sleep(MONITORING_THROUGHPUT_INTERVAL); // sleep + + long sizeInLastXs = monitoringReadDataSizeInLastXs.getAndSet(0); + if (sizeInLastXs > 0) // log only interesting values + monitoring.put(MONITORING_KEY_THROUGHPUT_OF_LAST_X_SECONDS, + (sizeInLastXs / 1024d) / (MONITORING_THROUGHPUT_INTERVAL / 1000d)); + } + } catch (InterruptedException e) { + // shutdown + } + } + }); + monitoringThread.setDaemon(true); + monitoringThread.start(); + } + } + + /** + * saves the request and fetches the object + */ + public void fetchObject(String fileID, long objectNo, XLocations xLoc, Capability capability, + CowPolicy cow, final StageRequest rq) { + ReplicatingFile file = this.filesInProgress.get(fileID); + if (file == null) { // file not in progress + /* + * Optimization: Use a cache of last completed files, so no new instance must be created every + * time. But use file from cache only if the xLoc has not changed. Otherwise it could be not + * guaranteed, that the information in the ReplicatingFile instance are correct (up-to-date). + */ + file = this.lastCompletedFilesCache.get(fileID); + if (file == null || (file != null && file.hasXLocChanged(xLoc))) { // create new one + file = new ReplicatingFile(fileID, xLoc, capability, cow, master); + } +// // FIXME: test stuff +// if (Monitoring.isEnabled() && file.isFullReplica) +// monitoring.putLong(MONITORING_KEY_REQUIRED_TIME_FOR_COMPLETING_REPLICA + fileID, System +// .currentTimeMillis()); + + // add file to filesInProgress + this.filesInProgress.put(fileID, file); + + // update requestsPerFile for all files (load-balancing) + ReplicatingFile.setMaxObjectsInProgressPerFile(MAX_OBJECTS_IN_PROGRESS_OVERALL / filesInProgress.size()); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "%s - start replicating file", fileID); + } + + // update to newer cap, ... + file.update(capability, xLoc, cow); + + // keep in mind current request + if (file.isObjectInProgress(objectNo)) { + // propably another request is already fetching this object + file.addObjectForReplication(objectNo, rq); + } else { + file.addObjectForReplication(objectNo, rq); + + // start replication + try { + file.replicate(); + } catch (TransferStrategyException e) { + if (e.getErrorCode() == TransferStrategyException.ErrorCode.NO_OSD_FOUND) + file.reportError(ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, "no OSD could be found for fetching an object",e.getStackTrace().toString())); + else if (e.getErrorCode() == TransferStrategyException.ErrorCode.NO_OSD_REACHABLE) + file.reportError(ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, "no OSD is reachable for fetching an object",e.getStackTrace().toString())); + } + + if (!file.isReplicating()) + fileCompleted(file.fileID); + } + } + + /** + * process all necessary actions if object was fetched correctly, otherwise triggers new fetch-attempt + * + * @param usedOSD + */ + public void objectFetched(String fileID, long objectNo, final ServiceUUID usedOSD, InternalObjectData data) { + ReplicatingFile file = filesInProgress.get(fileID); + assert (file != null); + + // monitoring + monitoringReadDataSizeInLastXs.addAndGet(data.getData().limit()); + + file.objectFetched(objectNo, usedOSD, data); + +// if (!file.isReplicating()) +// fileCompleted(file.fileID); + } + + /** + * process all necessary actions, because object could not be fetched + * + * @param usedOSD + */ + public void objectNotFetched(String fileID, final ServiceUUID usedOSD, long objectNo, InternalObjectData data) { + ReplicatingFile file = filesInProgress.get(fileID); + assert (file != null); + +// // monitoring +// if (Monitoring.isEnabled()) +// monitoring.putIncreaseForLong(MONITORING_KEY_UNNECESSARY_REQUESTS, 1l); + + file.objectNotFetched(objectNo, usedOSD, data); + + if (!file.isReplicating()) + fileCompleted(file.fileID); + } + + public void objectNotFetchedBecauseError(String fileID, final ServiceUUID usedOSD, long objectNo, final ErrorResponse error) { + ReplicatingFile file = filesInProgress.get(fileID); + assert (file != null); + +// // monitoring +// if (Monitoring.isEnabled()) +// monitoring.putIncreaseForLong(MONITORING_KEY_UNNECESSARY_REQUESTS, 1l); + + file.objectNotFetchedBecauseError(objectNo, usedOSD, error); + + if (!file.isReplicating()) + fileCompleted(file.fileID); + } + + /** + * cleans up maps, lists, ... + * + * @param fileID + */ + private void fileCompleted(String fileID) { + // if the last requested object was fetched for this file => remove from map + ReplicatingFile completedFile = filesInProgress.remove(fileID); + assert (completedFile != null); + +// // monitoring +// if (Monitoring.isEnabled() && completedFile.isFullReplica) { +// long requiredTime = System.currentTimeMillis() +// - monitoring.getLong(MONITORING_KEY_REQUIRED_TIME_FOR_COMPLETING_REPLICA + fileID); +// monitoring.putLong(MONITORING_KEY_REQUIRED_TIME_FOR_COMPLETING_REPLICA + fileID, +// requiredTime); +// // FIXME: test stuff +// MonitoringLog.monitor(MONITORING_KEY_REQUIRED_TIME_FOR_COMPLETING_REPLICA + fileID, Long +// .toString(requiredTime)); +// // all monitoring keys who are not overwritten (+fileID) must be removed from map, otherwise it +// // will overflow +// monitoring.remove(MONITORING_KEY_REQUIRED_TIME_FOR_COMPLETING_REPLICA + fileID); +// } +// // FIXME: test stuff +// Long overhead = monitoring.getLong(MONITORING_KEY_OBJECT_LIST_OVERHEAD); +// if (overhead != null) +// MonitoringLog.monitor(MONITORING_KEY_OBJECT_LIST_OVERHEAD, overhead.toString()); +// Long unnecessaryRequests = monitoring.getLong(MONITORING_KEY_UNNECESSARY_REQUESTS); +// if (unnecessaryRequests != null) +// MonitoringLog.monitor(MONITORING_KEY_UNNECESSARY_REQUESTS, unnecessaryRequests.toString()); + + /* + * Optimization: Canceled files will be never reused. Because in most cases they are canceled due to + * the removal of the local replica. + */ + if(completedFile.isStopped()) { + // do not cache canceled files + // remove canceled file from cache + lastCompletedFilesCache.remove(fileID); + } else { + // cache completed file + lastCompletedFilesCache.put(fileID, completedFile); + } + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "%s - stop replicating file", + fileID); + + // update allowed max objects in progress for all files (load-balancing) + if (filesInProgress.size() == 0) + ReplicatingFile.setMaxObjectsInProgressPerFile(MAX_OBJECTS_IN_PROGRESS_OVERALL / 1); + else + ReplicatingFile.setMaxObjectsInProgressPerFile(MAX_OBJECTS_IN_PROGRESS_OVERALL / filesInProgress.size()); + + // TODO: save persistent marker that all objects of file are completely replicated, if it is a full replica + } + + /** + * Stops replication for this file. + */ + public void cancelFile(String fileID) { + ReplicatingFile file = filesInProgress.get(fileID); + if (file != null) + if (file.isReplicating()) // => probably requests were sent + // mark cancelled for deleting later + file.stopReplicatingFile(); + else + // delete directly + filesInProgress.remove(fileID); + } + + /** + * @param objectSetBytes + * + */ + public void objectSetFetched(String fileID, ServiceUUID osd, ObjectSet objectSet, long objectSetBytes) { + // TODO: find more handsome way for notifying about list-size + ReplicatingFile file = filesInProgress.get(fileID); + if (file != null) { + file.objectSetFetched(osd, objectSet); + +// // monitoring +// if(Monitoring.isEnabled()) +// monitoring.putIncreaseForLong(MONITORING_KEY_OBJECT_LIST_OVERHEAD, objectSetBytes); + } + } + + /** + * sends an error to all belonging clients of this file (for all objects) + */ + public void sendError(String fileID, ErrorResponse e) { + ReplicatingFile file = filesInProgress.get(fileID); + assert (file != null); + + file.reportError(e); + } + + public void shutdown() { + if (Monitoring.isEnabled()) { + if (monitoringThread != null) + monitoringThread.interrupt(); + } + } + + /** + * @param fileId + */ + public void startNewReplication(String fileID) { + ReplicatingFile file = filesInProgress.get(fileID); + if (file != null) + try { + file.startNewReplication(); + if (!file.isReplicating()) + fileCompleted(file.fileID); + } catch (TransferStrategyException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/ObjectSet.java b/java/servers/src/org/xtreemfs/osd/replication/ObjectSet.java new file mode 100755 index 0000000..9c11799 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/ObjectSet.java @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.BitSet; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Random; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.InflaterInputStream; + + +/** + * Stores the objects in a Java BitSet.
    + * 29.06.2009 + */ +public class ObjectSet implements /*Serializable,*/ Iterable { // FIXME + public static final int DEFAULT_INITIAL_SIZE = 1024; + + /** + * contains the objects + */ + protected BitSet objects; + + /** + * only every x object will be saved, so the set contains less free entries + */ + protected int stripeWidth; + + /** + * the first object number which should be stored + */ + protected int firstObjectNo; + + protected Random random; + + /** + * Creates an ObjectSet with a default size of 1024. All objects can be stored to this ObjectSet. + */ + public ObjectSet() { + this(1, 0, DEFAULT_INITIAL_SIZE); + } + + /** + * Creates an ObjectSet with the given size. All objects can be stored to this ObjectSet. + * + * @param initialSize + */ + public ObjectSet(int initialSize) { + this(1, 0, initialSize); + } + + /** + * Creates an ObjectSet with a default size of 1024. It uses the stripe width information to store the + * appropriate objects in a compact manner. Other objects could not be stored. + * + * @param stripeWidth + * @param firstObjectNo + * the first object of the file which should be stored in this object set + */ + public ObjectSet(int stripeWidth, int firstObjectNo) { + this(stripeWidth, firstObjectNo, DEFAULT_INITIAL_SIZE); + } + + /** + * Creates an ObjectSet with the given size. It uses the stripe width information to store the appropriate + * objects in a compact manner. Other objects could not be stored. + * + * @param stripeWidth + * @param firstObjectNo + * the first object of the file which should be stored in this object set + * @param initialSize + */ + public ObjectSet(int stripeWidth, int firstObjectNo, int initialSize) { + if (stripeWidth <= 0) + throw new IllegalArgumentException("stripeWidth must be > 0."); + if (firstObjectNo < 0) + throw new IllegalArgumentException("firstObjectNo must be >= 0."); + + this.stripeWidth = stripeWidth; + this.firstObjectNo = firstObjectNo; + this.objects = new BitSet(initialSize); + } + + public ObjectSet(int stripeWidth, int firstObjectNo, byte[] serializedBitSet) throws ClassCastException, + IOException, ClassNotFoundException { + this.objects = deserializeAndDecompress(serializedBitSet); + + this.stripeWidth = stripeWidth; + this.firstObjectNo = firstObjectNo; + } + + public ObjectSet(ObjectSet objectSet) { + this.stripeWidth = objectSet.stripeWidth; + this.firstObjectNo = objectSet.firstObjectNo; + this.objects = new BitSet(objectSet.objects.size()); + this.objects.or(objectSet.objects); + } + + /** + * + * @see java.util.Set#add(java.lang.Object) + */ + public boolean add(Long object) { + if (!objects.get((int) (object / stripeWidth))) { + objects.set((int) (object / stripeWidth)); + return true; + } else + return false; + } + + /** + * + * @see java.util.Set#contains(java.lang.Object) + */ + public boolean contains(Long object) { + return objects.get((int) (object / stripeWidth)); + } + + /** + * + * @return + */ + public Long getFirst() { + return (long) (firstObjectNo + (objects.nextSetBit(0) * stripeWidth)); + } + + /** + * + * @return + */ + public Long getRandom() { + // initialize on first call + if (random == null) + random = new Random(); + + int highestSetBit = objects.length(); // correct: objects.length() - 1, but then the highest bit would + // not be included + int randomIndex = random.nextInt(highestSetBit); + int index = objects.nextSetBit(randomIndex); + assert (index != -1); + + return (long) (firstObjectNo + (index * stripeWidth)); + } + + /** + * + * @see java.util.Set#iterator() + */ + public Iterator iterator() { + return new Iterator() { + int currentPosition = -1; + + @Override + public Long next() { + currentPosition = objects.nextSetBit(currentPosition + 1); + if (currentPosition == -1) + throw new NoSuchElementException("iteration has no more elements"); + return (long) (firstObjectNo + (currentPosition * stripeWidth)); + } + + @Override + public boolean hasNext() { + return (objects.nextSetBit(currentPosition + 1) == -1) ? false : true; + } + + @Override + public void remove() { + objects.clear(currentPosition); + } + }; + } + + /** + * + * @see java.util.Set#remove(java.lang.Object) + */ + public boolean remove(Long object) { + if (objects.get((int) (object / stripeWidth))) { + objects.clear((int) (object / stripeWidth)); + return true; + } else + return false; + } + + /** + * + * @see java.util.Set#isEmpty() + */ + public boolean isEmpty() { + return objects.isEmpty(); // O(1) + } + + /** + * + * @see java.util.Set#size() + */ + public int size() { + return objects.cardinality(); // O(n) + } + + /** + * + * @see java.util.Set#clear() + */ + public void clear() { + objects.clear(); + } + + /** + * Checks if the contents of the sets are the same.
    + */ + public boolean equals(Object obj) { + if (obj instanceof ObjectSet) { + ObjectSet otherSet = (ObjectSet) obj; + return stripeWidth == otherSet.stripeWidth && firstObjectNo == otherSet.firstObjectNo + && objects.equals(otherSet.objects); + } else + return false; + } + + /** + * Generates the intersection of this set and the given set. Modifies this set, so only the objects which + * are contained in both sets remain. + * + * @param otherSet + * @return + */ + public boolean intersection(ObjectSet otherSet) { + if (stripeWidth != otherSet.stripeWidth || firstObjectNo != otherSet.firstObjectNo) + throw new IllegalArgumentException( + "The sets are not compatible. They must have the same stripe width and first object number."); + int previousLength = objects.cardinality(); + objects.and(otherSet.objects); + return (objects.cardinality() != previousLength) ? true : false; + } + + /** + * Generates the union of this set and the given set. Modifies this set, so all objects which are + * contained in one of the two sets remain. + * + * @param otherSet + * @return + */ + public boolean union(ObjectSet otherSet) { + if (stripeWidth != otherSet.stripeWidth || firstObjectNo != otherSet.firstObjectNo) + throw new IllegalArgumentException( + "The sets are not compatible. They must have the same stripe width and first object number."); + int previousLength = objects.cardinality(); + objects.or(otherSet.objects); + return (objects.cardinality() != previousLength) ? true : false; + } + + public boolean complement(int lastObject) { + int indexOfLastObject = lastObject / stripeWidth; + int previousLength = objects.size(); + + if (objects.size() - 1 < indexOfLastObject) + objects.clear(indexOfLastObject); + objects.flip(0, objects.size()); + + return (objects.size() != previousLength) ? true : false; + } + + @Override + public String toString() { + return "stripe width: " + stripeWidth + ", first objectNo: " + firstObjectNo + ", objects: " + + objects.toString(); + } + + @Override + public ObjectSet clone() throws CloneNotSupportedException { + ObjectSet clone = new ObjectSet(this.stripeWidth, this.firstObjectNo, this.objects.size()); + clone.objects.or(this.objects); + return clone; + } + + /* + * serialization + */ + public int getStripeWidth() { + return stripeWidth; + } + + /** + * Returns NOT the first element of the set, but returns the internal value of the field + * firstObjectNo. + * + * @return + */ + public int getFirstObjectNo() { + return firstObjectNo; + } + + public byte[] getSerializedBitSet() throws IOException { + return serializeAndCompress(objects); + } + + /** + * Serializes the given BitSet. + * + * @param set + * @return + * @throws IOException + */ + protected static byte[] serialize(BitSet set) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(set); + oos.flush(); + oos.close(); + bos.close(); + return bos.toByteArray(); + } + + /** + * Serializes and compresses the given BitSet. + * + * @param set + * @return + * @throws IOException + */ + protected static byte[] serializeAndCompress(BitSet set) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DeflaterOutputStream gz = new DeflaterOutputStream(bos); + ObjectOutputStream oos = new ObjectOutputStream(gz); + oos.writeObject(set); + oos.flush(); + oos.close(); + gz.close(); + bos.close(); + return bos.toByteArray(); + } + + /** + * Deserializes the given object. + * + * @param set + * @return + * @throws IOException + * @throws ClassNotFoundException + * @throws ClassCastException + */ + protected static BitSet deserialize(byte[] set) throws IOException, ClassNotFoundException, + ClassCastException { + ByteArrayInputStream bis = new ByteArrayInputStream(set); + ObjectInputStream ois = new ObjectInputStream(bis); + Object o = ois.readObject(); + ois.close(); + bis.close(); + + return (BitSet) o; + } + + /** + * Deserializes and decompresses the given object. + * + * @param set + * @return + * @throws IOException + * @throws ClassNotFoundException + * @throws ClassCastException + */ + protected static BitSet deserializeAndDecompress(byte[] set) throws IOException, ClassNotFoundException, + ClassCastException { + ByteArrayInputStream bis = new ByteArrayInputStream(set); + InflaterInputStream gz = new InflaterInputStream(bis); + ObjectInputStream ois = new ObjectInputStream(gz); + Object o = ois.readObject(); + ois.close(); + bis.close(); + + return (BitSet) o; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/ReplicatingFile.java b/java/servers/src/org/xtreemfs/osd/replication/ReplicatingFile.java new file mode 100755 index 0000000..784beec --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/ReplicatingFile.java @@ -0,0 +1,893 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ServiceAvailability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.common.xloc.Replica; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.client.RPCResponseAvailableListener; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.mrc.UserException; +import org.xtreemfs.mrc.utils.MRCHelper; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.operations.EventInsertPaddingObject; +import org.xtreemfs.osd.operations.EventWriteObject; +import org.xtreemfs.osd.operations.OSDOperation; +import org.xtreemfs.osd.replication.transferStrategies.RandomStrategy; +import org.xtreemfs.osd.replication.transferStrategies.RarestFirstStrategy; +import org.xtreemfs.osd.replication.transferStrategies.SequentialPrefetchingStrategy; +import org.xtreemfs.osd.replication.transferStrategies.SequentialStrategy; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.NextRequest; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.TransferStrategyException; +import org.xtreemfs.osd.stages.ReplicationStage.FetchObjectCallback; +import org.xtreemfs.osd.stages.Stage.StageRequest; +import org.xtreemfs.osd.storage.CowPolicy; +import org.xtreemfs.osd.storage.ObjectInformation; +import org.xtreemfs.osd.storage.ObjectInformation.ObjectStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * attends to the replication of all objects of this file
    + * 01.04.2009 + */ +class ReplicatingFile { + /* + * inner class + */ + private class ReplicatingObject { + public final long objectNo; + + // create a list only if object is really requested + private List waitingRequests = null; + + /** + * used to save data with an invalid checksum, because it could be the + * best result we get
    + * null in all cases except an object with an invalid checksum is + * fetched + */ + InternalObjectData data = null; + + public ReplicatingObject(long objectNo) { + this.objectNo = objectNo; + } + + public List getWaitingRequests() { + if (waitingRequests == null) + this.waitingRequests = new LinkedList(); + return waitingRequests; + } + + public boolean hasWaitingRequests() { + return (waitingRequests == null) ? false : !getWaitingRequests().isEmpty(); + } + + public boolean hasDataFromEarlierResponses() { + return (data != null); + } + + /** + * is used for (complete) replicating an object which was previously + * chosen to be replicated + * + * @param objectNo + * @throws TransferStrategyException + */ + public void replicateObject() throws TransferStrategyException { + strategy.selectNextOSD(objectNo); + NextRequest next = strategy.getNext(); + + if (next != null) { // OSD found for fetching object + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "%s:%d - fetch object from OSD %s", fileID, next.objectNo, next.osd); + + try { + sendFetchObjectRequest(next.objectNo, next.osd, next.attachObjectSet); + } catch (IOException e) { + // try other OSD + replicateObject(); + } + } else { // should not happen + sendError(ErrorUtils.getErrorResponse(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_EIO, "transfer strategy returns neither a value nor an exception")); + Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this, + "transfer strategy returns neither a value nor an exception"); + + objectReplicationCompleted(objectNo); + } + } + + /** + * + * @param usedOSD + * @return true, if object is completed; false otherwise + * @throws TransferStrategyException + */ + public boolean objectFetched(InternalObjectData data, final ServiceUUID usedOSD) + throws TransferStrategyException { + if (!data.getInvalid_checksum_on_osd()) { + // correct checksum + if (hasWaitingRequests()) + sendResponses(data.getData(), ObjectStatus.EXISTS); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.replication, this, + "%s:%d - OBJECT FETCHED", fileID, objectNo); + + + if (!isStopped()) { + + // write data to disk + OSDOperation writeObjectEvent = master.getInternalEvent(EventWriteObject.class); + // NOTE: "original" buffer is used + + writeObjectEvent.startInternalEvent(new Object[] { fileID, objectNo, data.getData(), + xLoc, cow }); + + } + + return true; + } else { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "%s:%d - fetched object has an invalid checksum", fileID, objectNo); + + // save data, in case other replicas are less useful + this.data = data; + + // if (!ReplicatingFile.cancelled) { + // try next replica + strategy.addObject(objectNo, hasWaitingRequests()); + replicateObject(); + // } else { + // sendError(ReplicatingFile, objectNo, new + // OSDException(ErrorCodes.IO_ERROR, + // "Object does not exist locally and replication was cancelled.", + // "")); + // + // } + return false; + } + } + + /** + * Checks if it is a hole. Otherwise it tries to use another OSD for + * fetching. + * + * @param usedOSD + * last used OSD for fetching this object + * + * @return true, if object is completed; false otherwise + * @throws TransferStrategyException + */ + public boolean objectNotFetched(final InternalObjectData data, final ServiceUUID usedOSD) throws TransferStrategyException { + // check if it is a hole + if (xLoc.getReplica(usedOSD).isComplete()) { + // => hole or error; we assume it is a hole + if (hasDataFromEarlierResponses() && hasWaitingRequests()) { + // no hole, but an object for which only a replica with a + // wrong checksum could be found + sendResponses(this.data.getData(), ObjectStatus.EXISTS); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Logging.Category.replication, this, + "%s:%d - OBJECT FETCHED, but with wrong checksum", fileID, objectNo); + } else { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "%s:%d - OBJECT COULD NOT BE FETCHED FROM A COMPLETE REPLICA; MUST BE A HOLE.", + fileID, objectNo); + + if (hasWaitingRequests()) + sendResponses(null, ObjectStatus.PADDING_OBJECT); + + // mark the object as a hole + OSDOperation writeObjectEvent = master.getInternalEvent(EventInsertPaddingObject.class); + writeObjectEvent.startInternalEvent(new Object[] { fileID, objectNo, xLoc, + data.getZero_padding() }); + + } + return true; + } else { + return objectNotFetchedBecauseError(null, usedOSD); + } + } + + public boolean objectNotFetchedBecauseError(final ErrorResponse error, final ServiceUUID usedOSD) + throws TransferStrategyException { + if (Logging.isDebug() && error != null) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "%s:%d - an error occurred while fetching the object from OSD %s: %s", fileID, objectNo, + usedOSD.toString(), error.getErrorMessage()); + + // if (!ReplicatingFile.cancelled) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "%s:%d - object could not be fetched from OSD => try next OSD", fileID, objectNo); + + // try next replica + strategy.addObject(objectNo, hasWaitingRequests()); + replicateObject(); + // } else { + // sendError(ReplicatingFile, objectNo, new + // OSDException(ErrorCodes.IO_ERROR, + // "Object does not exist locally and replication was cancelled.", + // "")); + // + // objectCompleted(ReplicatingFile, objectNo); + // } + return false; + } + + /** + * sends the responses to all belonging clients
    + * NOTE: data-buffer will not be modified + */ + private void sendResponses(ReusableBuffer data, ObjectStatus status) { + List reqs = getWaitingRequests(); + // IMPORTANT: stripe size must be the same in all striping policies + StripingPolicyImpl sp = xLoc.getLocalReplica().getStripingPolicy(); + // responses + for (StageRequest rq : reqs) { + ObjectInformation objectInfo; + // create returning ObjectInformation + if (status == ObjectStatus.EXISTS) { + objectInfo = new ObjectInformation(status, data.createViewBuffer(), sp + .getStripeSizeForObject(objectNo)); + } else { + objectInfo = new ObjectInformation(status, null, sp.getStripeSizeForObject(objectNo)); + } + objectInfo.setGlobalLastObjectNo(lastObject); + + final FetchObjectCallback callback = (FetchObjectCallback) rq.getCallback(); + callback.fetchComplete(objectInfo, null); + } + } + + /** + * sends an error to all belonging clients + */ + public void sendError(ErrorResponse error) { + List reqs = getWaitingRequests(); + // responses + for (StageRequest rq : reqs) { + final FetchObjectCallback callback = (FetchObjectCallback) rq.getCallback(); + callback.fetchComplete(null, error); + } + } + } + + /* + * outer class + */ + /** + * the absolute maximum that can be set for maxRequestsPerFile + */ + private static final int MAX_MAX_OBJECTS_IN_PROGRESS = 5; + + private final OSDRequestDispatcher master; + + /** + * controls how many fetch-object-requests will be sent per file (used for + * load-balancing) + */ + private static int maxObjectsInProgress; + + public final String fileID; + + private final TransferStrategy strategy; + + private final long lastObject; + + private XLocations xLoc; + + private Capability cap; + + private CowPolicy cow; + + private InetSocketAddress mrcAddress = null; + + /** + * if the file is removed while it will be replicated + */ + private boolean cancelled; + + /** + * marks THIS replica as to be a full replica (enables background + * replication) + */ + // FIXME: private + public boolean isFullReplica; + + /** + * manages the OSD availability + */ + private final ServiceAvailability osdAvailability; + + /** + * key: objectNo + */ + private final HashMap objectsInProgress; + + /** + * contains all requests which are waiting for an object, where the + * replication of the object has been not started so far
    + * key: objectNo + */ + private final HashMap waitingRequests; + + public ReplicatingFile(String fileID, XLocations xLoc, Capability cap, CowPolicy cow, + OSDRequestDispatcher master) { + this.master = master; + this.osdAvailability = master.getServiceAvailability(); + + this.fileID = fileID; + this.xLoc = xLoc; + this.cap = cap; + this.cow = cow; + this.cancelled = false; + this.objectsInProgress = new HashMap(); + this.waitingRequests = new HashMap(); + + // IMPORTANT: stripe size must be the same in all striping policies + StripingPolicyImpl sp = xLoc.getLocalReplica().getStripingPolicy(); + assert (checkEqualStripeSizeOfReplicas(xLoc.getReplicas())); + this.lastObject = sp.getObjectNoForOffset(xLoc.getXLocSet().getReadOnlyFileSize() - 1); + + // create a new strategy + if (ReplicationFlags.isRandomStrategy(xLoc.getLocalReplica().getTransferStrategyFlags())) + strategy = new RandomStrategy(fileID, xLoc, osdAvailability); + // FIXME: test stuff + // strategy = new RandomStrategyWithoutObjectSets(fileID, xLoc, + // osdAvailability); + else if (ReplicationFlags.isSequentialStrategy(xLoc.getLocalReplica().getTransferStrategyFlags())) + strategy = new SequentialStrategy(fileID, xLoc, osdAvailability); + else if (ReplicationFlags.isSequentialPrefetchingStrategy(xLoc.getLocalReplica() + .getTransferStrategyFlags())) + strategy = new SequentialPrefetchingStrategy(fileID, xLoc, osdAvailability); + else if (ReplicationFlags.isRarestFirstStrategy(xLoc.getLocalReplica().getTransferStrategyFlags())) + strategy = new RarestFirstStrategy(fileID, xLoc, osdAvailability); + else + throw new IllegalArgumentException("Set Replication Strategy not known (" + + xLoc.getLocalReplica().getTransferStrategyFlags() + ")."); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "%s - using strategy: %s", + fileID, strategy.getClass().getName()); + + // check if background replication is required + isFullReplica = !xLoc.getLocalReplica().isPartialReplica(); + if (isFullReplica) { + // get striping column of local OSD + int coloumn = xLoc.getLocalReplica().getOSDs().indexOf(master.getConfig().getUUID()); + // add all objects (for this OSD) to strategy + Iterator objectsIt = sp.getObjectsOfOSD(coloumn, 0, lastObject); + while (objectsIt.hasNext()) { + strategy.addObject(objectsIt.next(), false); + } + } + + // monitoring = new NumberMonitoring(); + // startMonitoringStuff(); + } + + /** + * updates the capability and XLocations-list, if they are newer + * + * @return true, if something has changed + */ + public boolean update(Capability cap, XLocations xLoc, CowPolicy cow) { + boolean changed = false; + this.cow = cow; + // if newer + if (cap.getExpires() > this.cap.getExpires() || cap.getEpochNo() > this.cap.getEpochNo()) { + this.cap = cap; + changed = true; + } + if (hasXLocChanged(xLoc)) { + this.xLoc = xLoc; + this.strategy.updateXLoc(xLoc); + changed = true; + } + return changed; + } + + /** + * checks if the xLoc has changed since the last update (or creation-time) + * + * @param xLoc + * @return + */ + public boolean hasXLocChanged(XLocations xLoc) { + return xLoc.getXLocSet().getVersion() > this.xLoc.getXLocSet().getVersion(); + } + + /** + * enqueues the request and corresponding object for replication + * + * @see java.util.ArrayList#add(java.lang.Object) + */ + public boolean addObjectForReplication(Long objectNo, StageRequest rq) { + assert (rq != null); + + ReplicatingObject info = objectsInProgress.get(objectNo); + if (info == null) { // object is currently not replicating + // But it may be already queued in waitingRequests. + info = waitingRequests.get(objectNo); + + if (info == null) { + // Neither queued in objectsInProgress nor waitingRequests. + info = new ReplicatingObject(objectNo); + waitingRequests.put(objectNo, info); + // add to strategy + strategy.addObject(objectNo, true); + } + } + + info.getWaitingRequests().add(rq); + + return true; + } + + /** + * adds the object to the list of objects which are currently in progress + * + * @see java.util.ArrayList#add(java.lang.Object) + */ + private boolean processObject(Long objectNo) { + if (!isObjectInProgress(objectNo)) { + ReplicatingObject object = waitingRequests.remove(objectNo); + if (object != null) // at least one request is waiting + objectsInProgress.put(objectNo, object); + else + objectsInProgress.put(objectNo, new ReplicatingObject(objectNo)); + return true; + } + return false; + } + + /** + * @see java.util.HashMap#containsKey(java.lang.Object) + */ + public boolean isObjectInProgress(Long objectNo) { + return objectsInProgress.containsKey(objectNo); + } + + /** + * checks if replication of objects is in progress + * + * @see java.util.HashMap#isEmpty() + */ + public boolean isReplicating() { + return !objectsInProgress.isEmpty(); + } + + public boolean isStopped() { + return cancelled; + } + + /** + * @see java.util.HashMap#size() + */ + public int getNumberOfObjectsInProgress() { + return objectsInProgress.size(); + } + + /** + * @see java.util.HashMap#size() + */ + public int getNumberOfWaitingObjects() { + return waitingRequests.size(); + } + + /** + * chooses an object and matching OSD for replicating it + * + * @throws TransferStrategyException + */ + public void replicate() throws TransferStrategyException { + while (objectsInProgress.size() < maxObjectsInProgress) { + strategy.selectNext(); + NextRequest next = strategy.getNext(); + + if (next != null) { // there is something to fetch + // object replication is in progress + processObject(next.objectNo); + + if (Logging.isDebug()) + if (next.attachObjectSet) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "%s:%d - fetch object from OSD %s with object set", fileID, next.objectNo, + next.osd); + else + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "%s:%d - fetch object from OSD %s", fileID, next.objectNo, next.osd); + + try { + sendFetchObjectRequest(next.objectNo, next.osd, next.attachObjectSet); + } catch (IOException e) { + // try other OSD + objectsInProgress.get(next.objectNo).replicateObject(); + } + } else + break; + } + } + + /** + * + * @param objectNo + * @param usedOSD + * @param data + */ + public void objectFetched(long objectNo, final ServiceUUID usedOSD, InternalObjectData data) { + ReplicatingObject object = objectsInProgress.get(objectNo); + assert (object != null) : objectNo + ", " + usedOSD.toString(); + + try { + boolean objectCompleted = object.objectFetched(data, usedOSD); + if (objectCompleted) { + objectReplicationCompleted(objectNo); + + // if (!strategy.isObjectListEmpty()) { // there are still + // objects to fetch + // if (Logging.isDebug()) + // Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, + // this, + // "background replication: replicate next object for file %s", + // fileID); + // replicate(); // background replication + // } + } + } catch (TransferStrategyException e) { + // TODO: differ between ErrorCodes + object.sendError(ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, e.getMessage())); + objectReplicationCompleted(objectNo); + // end replicating this file + } + } + + /** + * Checks if it is a hole. Otherwise it tries to use another OSD for + * fetching. + * + * @param objectNo + * @param usedOSD + */ + public void objectNotFetched(long objectNo, final ServiceUUID usedOSD, InternalObjectData data) { + ReplicatingObject object = objectsInProgress.get(objectNo); + assert (object != null); + + try { + boolean objectCompleted = object.objectNotFetched(data, usedOSD); + if (objectCompleted) { + objectReplicationCompleted(objectNo); + + if (!strategy.isObjectListEmpty()) { // there are still objects + // to fetch + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "background replication: replicate next object for file %s", fileID); + replicate(); // background replication + } + } + } catch (TransferStrategyException e) { + // TODO: differ between ErrorCodes + object.sendError(ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, e.getMessage())); + objectReplicationCompleted(objectNo); + // end replicating this file + } + } + + /** + * Tries to use another OSD for fetching. + * + * @param objectNo + * @param usedOSD + */ + /* + * code copied from objectNotFetched(...) + */ + public void objectNotFetchedBecauseError(long objectNo, final ServiceUUID usedOSD, final ErrorResponse error) { + ReplicatingObject object = objectsInProgress.get(objectNo); + assert (object != null); + + try { + boolean objectCompleted = object.objectNotFetchedBecauseError(error, usedOSD); + if (objectCompleted) { + objectReplicationCompleted(objectNo); + + if (!strategy.isObjectListEmpty()) { // there are still objects + // to fetch + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "background replication: replicate next object for file %s", fileID); + replicate(); // background replication + } + } + } catch (TransferStrategyException e) { + // TODO: differ between ErrorCodes + object.sendError(ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, e.getMessage())); + objectReplicationCompleted(objectNo); + // end replicating this file + } + } + + /** + * cleans up maps, lists, ... + * + * @param objectNo + */ + public void objectReplicationCompleted(long objectNo) { + // delete object in maps/lists + strategy.removeObject(objectNo); + ReplicatingObject replicatingObject = objectsInProgress.remove(objectNo); + // free old data + if (replicatingObject.hasDataFromEarlierResponses()) + BufferPool.free(replicatingObject.data.getData()); + } + + public void stopReplicatingFile() { + cancelled = true; + } + + /** + * + */ + public void objectSetFetched(ServiceUUID osd, ObjectSet objectSet) { + strategy.setOSDsObjectSet(objectSet, osd); + } + + /** + * Sends a RPC for reading the object on another OSD. + * + * @param attachObjectSet + * @throws UnknownUUIDException + */ + private void sendFetchObjectRequest(final long objectNo, final ServiceUUID osd, boolean attachObjectSet) + throws UnknownUUIDException, IOException { + // check capability validity and update capability if necessary + try { + checkCap(); + } catch (IOException e1) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, + "cannot update capability for file %s due to " + e1.getLocalizedMessage(), fileID); + } + + // check that the load-restriction works + assert (objectsInProgress.size() <= MAX_MAX_OBJECTS_IN_PROGRESS); + + OSDServiceClient client = master.getOSDClientForReplication(); + // IMPORTANT: stripe size must be the same in all striping policies + FileCredentials fcred = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLoc.getXLocSet()).build(); + RPCResponse response = client.xtreemfs_internal_read_local(osd.getAddress(), RPCAuthentication.authNone,RPCAuthentication.userService, + fcred, fileID, objectNo, 0, 0, xLoc + .getLocalReplica().getStripingPolicy().getStripeSizeForObject(objectNo), attachObjectSet, + new ArrayList(0)); + + response.registerListener(new RPCResponseAvailableListener() { + @Override + public void responseAvailable(RPCResponse r) { + InternalReadLocalResponse internalReadLocalResponse = null; + try { + internalReadLocalResponse = r.get(); + ObjectData metadata = internalReadLocalResponse.getData(); + InternalObjectData data = new InternalObjectData(metadata,r.getData()); + ObjectList objectList = null; + if (internalReadLocalResponse.getObjectSetCount() == 1) + objectList = internalReadLocalResponse.getObjectSet(0); + master.getReplicationStage().internalObjectFetched(fileID, objectNo, osd, data, + objectList, null); + } catch (PBRPCException e) { + osdAvailability.setServiceWasNotAvailable(osd); + master.getReplicationStage().internalObjectFetched(fileID, objectNo, osd, null, null, + e.getErrorResponse()); + } catch (IOException e) { + osdAvailability.setServiceWasNotAvailable(osd); + master.getReplicationStage().internalObjectFetched(fileID, objectNo, osd, null, null, + ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, e.toString())); + // e.printStackTrace(); + } catch (InterruptedException e) { + // ignore + } finally { + r.freeBuffers(); + } + } + }); + } + + /** + * sends an error to all belonging clients (for all objects of the file) + */ + public void reportError(ErrorResponse error) { + Logging.logMessage(Logging.LEVEL_ERROR, this, ErrorUtils.formatError(error)); + for (ReplicatingObject object : waitingRequests.values()) + object.sendError(error); + for (ReplicatingObject object : objectsInProgress.values()) + object.sendError(error); + } + + /** + * checks if the capability is still valid; renews the capability if + * necessary + * + * @throws IOException + * @throws ONCRPCException + */ + public void checkCap() throws IOException { + try { + long curTime = TimeSync.getGlobalTime() / 1000; // s + + // get the correct MRC only once and only if the capability must be + // updated + if (cap.getExpires() - curTime < 60 * 1000) { // capability expires + // in less than 60s + if (mrcAddress == null) { + String volume = null; + try { + // get volume of file + volume = new MRCHelper.GlobalFileIdResolver(fileID).getVolumeId(); + + // get MRC appropriate for this file + ServiceSet sSet = master.getDIRClient().xtreemfs_service_get_by_uuid(null, RPCAuthentication.authNone, RPCAuthentication.userService, + volume); + + if (sSet.getServicesCount() != 0) { + for (KeyValuePair kvp : sSet.getServices(0).getData().getDataList()) { + if (kvp.getKey().equals("mrc")) { + mrcAddress = new ServiceUUID(kvp.getValue()).getAddress(); + } + } + + } + else + throw new IOException("Cannot find a MRC."); + } catch (UserException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.misc, this, e.getLocalizedMessage() + + "; for file %s", fileID); + } + + } + + // update Xcap + RPCResponse r = master.getMRCClient().xtreemfs_renew_capability(mrcAddress, RPCAuthentication.authNone, RPCAuthentication.userService, + cap.getXCap()); + XCap xCap = r.get(); + r.freeBuffers(); + + cap = new Capability(xCap, master.getConfig().getCapabilitySecret()); + } + } catch (InterruptedException e) { + // ignore + } + } + + /** + * adjust this value for load-balancing + * + * @param maxObjects + */ + public static void setMaxObjectsInProgressPerFile(int maxObjects) { + // at least one request/object MUST be sent per file + if (maxObjects >= 1) + if (maxObjects <= MAX_MAX_OBJECTS_IN_PROGRESS) + ReplicatingFile.maxObjectsInProgress = maxObjects; + else + ReplicatingFile.maxObjectsInProgress = MAX_MAX_OBJECTS_IN_PROGRESS; + else + ReplicatingFile.maxObjectsInProgress = 1; + } + + /* + * additional test if asserts are enabled + */ + private boolean checkEqualStripeSizeOfReplicas(List replicas) { + boolean allEqual = true; + int stripeSize = replicas.get(0).getStripingPolicy().getStripeSizeForObject(0); + for (Replica replica : replicas) + if (stripeSize != replica.getStripingPolicy().getStripeSizeForObject(0)) + allEqual = false; + return allEqual; + } + + public void startNewReplication() throws TransferStrategyException { + if (!strategy.isObjectListEmpty()) { // there are still objects to fetch + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "background replication: replicate next object for file %s", fileID); + replicate(); // background replication + } + } + + /* + * monitoring for HighestThroughputOSDSelection + */ + // ConcurrentHashMap requestsSentToOSDs = new + // ConcurrentHashMap(); + // ConcurrentHashMap requestsReceivedFromOSDs = new + // ConcurrentHashMap(); + // + // private Thread monitoringThread = null; + // private NumberMonitoring monitoring; + // public static final String MONITORING_KEY_THROUGHPUT = + // "requests (sent/received) for OSD "; + // + // public void startMonitoringStuff() { + // if (Monitoring.isEnabled()) { + // monitoringThread = new Thread(new Runnable() { + // public static final int MONITORING_INTERVAL = 10000; // 10s + // + // @Override + // public void run() { + // try { + // while (true) { + // if (Thread.interrupted()) + // break; + // Thread.sleep(MONITORING_INTERVAL); // sleep + // + // for (Entry e : requestsSentToOSDs.entrySet()) { + // Integer requestsReceived = requestsReceivedFromOSDs.remove(e.getKey()); + // Integer requestsSent = e.getValue(); + // monitoring.put(MONITORING_KEY_THROUGHPUT + e.getKey(), + // (requestsSent / requestsReceived) / (MONITORING_INTERVAL / 1000d)); + // } + // for (Entry e : requestsReceivedFromOSDs.entrySet()) + // { + // Integer requestsSent = requestsSentToOSDs.remove(e.getKey()); + // Integer requestsReceived = e.getValue(); + // monitoring.put(MONITORING_KEY_THROUGHPUT + e.getKey(), + // (requestsSent / requestsReceived) / (MONITORING_INTERVAL / 1000d)); + // } + // // remove all + // requestsReceivedFromOSDs.clear(); + // requestsSentToOSDs.clear(); + // } + // } catch (InterruptedException e) { + // // shutdown + // } + // } + // }); + // monitoringThread.setDaemon(true); + // monitoringThread.start(); + // } + // } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/selection/ObjectSetOSDSelection.java b/java/servers/src/org/xtreemfs/osd/replication/selection/ObjectSetOSDSelection.java new file mode 100755 index 0000000..d94416e --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/selection/ObjectSetOSDSelection.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.selection; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.ObjectSetInfo; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.TransferStrategyException; + +/** + * + *
    26.08.2009 + */ +public class ObjectSetOSDSelection { + private Random random = new Random(); + + public ServiceUUID selectNextOSD(List osds, Map objectsOnOSDs, + long objectNo) throws TransferStrategyException { + // at least one osd must be available + assert (osds.size() > 0); + + Collections.shuffle(osds, random); + + Iterator it = osds.iterator(); + ServiceUUID osd = null; + while (it.hasNext()) { + osd = it.next(); + ObjectSetInfo objectSetInfo = objectsOnOSDs.get(osd); + + // exit if OSD contains object or OSD is part of a complete replica + if (objectSetInfo != null && (objectSetInfo.complete || objectSetInfo.set.contains(objectNo))) + // OSD found + break; + } + return osd; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/selection/RandomOSDSelection.java b/java/servers/src/org/xtreemfs/osd/replication/selection/RandomOSDSelection.java new file mode 100755 index 0000000..4c82023 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/selection/RandomOSDSelection.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.selection; + +import java.util.List; +import java.util.Random; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.TransferStrategyException; + +/** + * Selects OSDs randomly.
    + * 29.06.2009 + */ +public class RandomOSDSelection { + private Random random = new Random(); + + public ServiceUUID selectNextOSD(List osds) throws TransferStrategyException { + // at least one osd must be available + assert (osds.size() > 0); + return osds.get(random.nextInt(osds.size())); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/selection/RandomObjectSelection.java b/java/servers/src/org/xtreemfs/osd/replication/selection/RandomObjectSelection.java new file mode 100755 index 0000000..d3df500 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/selection/RandomObjectSelection.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.selection; + +import java.util.Random; + +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.TransferStrategyException; + +/** + * Selects objects randomly.
    + * 29.06.2009 + */ +public class RandomObjectSelection { + private Random random = new Random(); + + public long selectNextObject(ObjectSet objects) throws TransferStrategyException { + // at least one object must be wanted + assert (!objects.isEmpty()); + + return objects.getRandom(); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/selection/RarestFirstObjectSelection.java b/java/servers/src/org/xtreemfs/osd/replication/selection/RarestFirstObjectSelection.java new file mode 100755 index 0000000..72f41ea --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/selection/RarestFirstObjectSelection.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.selection; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.Map.Entry; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.ObjectSetInfo; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.TransferStrategyException; + +/** + * + *
    + * 29.06.2009 + */ +public class RarestFirstObjectSelection { + /** + * max. occurrence of objects == #replicas, so map should not be too big + */ + protected TreeMap rarestObjects; + protected long objectsCount; + + /** + * + */ + public RarestFirstObjectSelection() { + this.rarestObjects = new TreeMap(); + this.objectsCount = 0; + } + + public long selectNextObject(ObjectSet objects, Map objectsOnOSDsMap) + throws TransferStrategyException { + // at least one object must be wanted + assert (!objects.isEmpty()); + + // build new queue, if it is empty or invalidated + if (objectsCount <= 0) + buildQueue(objects, objectsOnOSDsMap); + + // check if at least one object is contained by queue + assert (objectsCount > 0); + + Long objectNo = null; + for (ObjectSet objectWithOccurrence : rarestObjects.values()) { + // get an object of the highest priority (less occurrence) + if (objectWithOccurrence.isEmpty()) + continue; // try next priority-group + objectNo = objectWithOccurrence.getRandom(); + break; + } + return objectNo.longValue(); + } + + /** + * Rebuilds the queue of rarest objects. + * + * @param objects + * @param objectsOnOSDsMap + */ + public void buildQueue(ObjectSet objects, Map objectsOnOSDsMap) { + // iterate through all wanted objects + Iterator objectsIt = objects.iterator(); + while (objectsIt.hasNext()) { + Long objectNo = objectsIt.next(); + + addObject(objectNo, objectsOnOSDsMap); + } + } + + /** + * Adds the object to the queue of rarest objects (and counts the occurrence). + * + * @param objectNo + * @param objectsOnOSDsMap + */ + public void addObject(long objectNo, Map objectsOnOSDsMap) { + Collection objectsOnOSDs = objectsOnOSDsMap.values(); + + // check how often this object is contained + int counter = 0; + for (ObjectSetInfo setInfo : objectsOnOSDs) + if (setInfo.set.contains(objectNo)) + counter++; + + // if object occurres zero times, at least one map is missing (of a complete replica) => object gets the lowest + // priority + if (counter == 0) + counter = Integer.MAX_VALUE; + + addObject(objectNo, counter); + } + + /** + * Adds the object to the queue of rarest objects. + */ + private void addObject(Long objectNo, Integer occurrence) { + // get correct queue + ObjectSet objectWithOccurrence = rarestObjects.get(occurrence); + if (objectWithOccurrence == null) { + // new set, if does not exist yet + objectWithOccurrence = new ObjectSet(); + rarestObjects.put(occurrence, objectWithOccurrence); + } + // put into queue + objectWithOccurrence.add(objectNo); + objectsCount++; + } + + /** + * Must be called each time the map of objects on OSDs has changed. + */ + public void invalidateQueue() { + for (ObjectSet set : rarestObjects.values()) + set.clear(); + objectsCount = 0; + } + + /** + * + * @param objects + * @param oldObjectSet + * @param newObjectSet + */ + /* + * alternative to invalidation; not used so far + */ + public void newObjectSetArrived(ObjectSet objects, ObjectSet oldObjectSet, ObjectSet newObjectSet) { + ObjectSet objectSet; + if (oldObjectSet == null) + objectSet = new ObjectSet(); + else + objectSet = new ObjectSet(oldObjectSet); + + // object set should only contain new objects (difference to old object set) + objectSet.complement(newObjectSet.size()-1); + objectSet.intersection(newObjectSet); + + // object set should only contain new wanted objects + objectSet.intersection(objects); + + // iterate through all new wanted objects + Iterator objectsIt = objectSet.iterator(); + while (objectsIt.hasNext()) { + Long objectNo = objectsIt.next(); + + // find objectNo in an objectSet + for (Entry e : rarestObjects.entrySet()) + if (e.getValue().contains(objectNo)) { + // increase occurrence of objectNo + e.getValue().remove(objectNo); + objectsCount--; + addObject(objectNo, e.getKey() + 1); + break; + } + } + } + + public void removeObject(long objectNo) { + for (ObjectSet objectWithOccurrence : rarestObjects.values()) + if (objectWithOccurrence.remove(objectNo)) { + objectsCount--; + break; + } + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/selection/RoundRobinOSDSelection.java b/java/servers/src/org/xtreemfs/osd/replication/selection/RoundRobinOSDSelection.java new file mode 100755 index 0000000..abb112a --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/selection/RoundRobinOSDSelection.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.selection; + +import java.util.HashMap; +import java.util.List; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.TransferStrategyException; + +/** + * Selects the OSDs sequentially (like Round-Robin). It iterates not strictly through the replicas, because it + * uses different position-pointers for every stripe. This is necessary, otherwise it could happen some + * replicas will be never used, which could cause in an infinite loop.
    + * 29.06.2009 + */ +public class RoundRobinOSDSelection { + /** + * contains the position (replica) in xLoc list of the next OSD which should be used for this stripe
    + * key: stripe
    + * value: index of replica + */ + private HashMap nextOSDforObject; + + private final int maxStripeWidth; + + private int lastKnownNumberOfReplicas; + + /** + * Creates a new instance. Sets an initial value for the number of replicas. + * @param maxStripeWidth + */ + public RoundRobinOSDSelection(int maxStripeWidth) { + this.maxStripeWidth = maxStripeWidth; + this.nextOSDforObject = new HashMap(maxStripeWidth); + this.lastKnownNumberOfReplicas = 0; + + // set first replica as start position for all stripes + for (int i = 0; i < maxStripeWidth; i++) + this.nextOSDforObject.put(i, 0); + } + + /** + * Selects an OSD. + * @param osds + * @param objectNo + * @return + * @throws TransferStrategyException + */ + public ServiceUUID selectNextOSD(List osds, long objectNo) throws TransferStrategyException { + // at least one osd must be available + assert (osds.size() > 0); + + // update number of replicas + if (lastKnownNumberOfReplicas != osds.size()) + lastKnownNumberOfReplicas = osds.size(); + + int positionOfNextOSD = getPositionOfNextOSD(objectNo); + increasePositionOfOSD(objectNo); + + // each OSD in list represents a replica + return osds.get(positionOfNextOSD); + } + + /** + * returns the position of the next using OSD (from replica) for the stripe of the given object + * + * @param objectNo + * @return + */ + protected int getPositionOfNextOSD(long objectNo) { + return nextOSDforObject.get((int) (objectNo % maxStripeWidth)); + } + + /** + * increases the position of the next using OSD for the stripe of the given object + * + * @param objectNo + */ + protected void increasePositionOfOSD(long objectNo) { + int oldPosition = nextOSDforObject.get((int) (objectNo % maxStripeWidth)); + // do not count local replica + nextOSDforObject.put((int) (objectNo % maxStripeWidth), ++oldPosition % lastKnownNumberOfReplicas); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/selection/SequentialObjectSelection.java b/java/servers/src/org/xtreemfs/osd/replication/selection/SequentialObjectSelection.java new file mode 100755 index 0000000..089cc48 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/selection/SequentialObjectSelection.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.selection; + +import java.util.Iterator; + +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.TransferStrategyException; + +/** + * Selects objects in a sequentially way.
    + * 29.06.2009 + */ +public class SequentialObjectSelection { + private int lastSizeOfObjectList; + + private Iterator iterator = null; + + /** + * Selects always the first object in set, because it assumes that the first entry will be before next + * call. + * + * @param objects + * @return + * @throws TransferStrategyException + */ + public long selectNextObject(ObjectSet objects) throws TransferStrategyException { + // at least one object must be wanted + assert (!objects.isEmpty()); + + // reset iterator + if (iterator != null) + iterator = null; + + return objects.getFirst(); + } + + /** + * Selects sequentially the next object in set. Useful if it is ensured the set does not change during calls. + * + * @param objects + * @return + * @throws TransferStrategyException + */ + public long selectNextObjectOfSameSet(ObjectSet objects) throws TransferStrategyException { + // initialize on first call + if (iterator == null) + iterator = objects.iterator(); + + if (iterator.hasNext()) + return iterator.next(); + else + return -1; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/MasqueradingTransferStrategy.java b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/MasqueradingTransferStrategy.java new file mode 100755 index 0000000..95f6778 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/MasqueradingTransferStrategy.java @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.transferStrategies; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.ServiceAvailability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.osd.replication.ObjectSet; + +/** + * + *
    + * 08.09.2009 + */ +public abstract class MasqueradingTransferStrategy extends TransferStrategy { + private final int defaultNumberOfRequests = 20; // every 20th + // request + + private static final ObjectSet dummyObjectSet = new ObjectSet(0); + + /** + * Contains a list of possible OSDs for each object. It's used to notice which OSDs were already + * requested.
    + * key: objectNo + */ + protected Map> availableOSDsForObject; + + protected int timeSinceLastRandomRequest = 0; + + protected long lastObjectNo; + + protected boolean fetchObjectSets; + + /** + * + * @param fileID + * @param xLoc + * @param osdAvailability + * @param fetchObjectSets + * turn on fetching object sets + */ + public MasqueradingTransferStrategy(String fileID, XLocations xLoc, ServiceAvailability osdAvailability, + boolean fetchObjectSets) { + super(fileID, xLoc, osdAvailability); + this.availableOSDsForObject = new HashMap>(); + this.fetchObjectSets = fetchObjectSets; + + StripingPolicyImpl sp = xLoc.getLocalReplica().getStripingPolicy(); + this.lastObjectNo = sp.getObjectNoForOffset(xLoc.getXLocSet().getReadOnlyFileSize() - 1); + } + + @Override + public NextRequest getNext() { + NextRequest next = super.getNext(); + if (next != null) { + // remove used OSD for this object, because the OSD will not be used a second time + List osds = availableOSDsForObject.get(next.objectNo); + if (osds != null) + osds.remove(next.osd); + } + return next; + } + + @Override + public boolean removeObject(long objectNo) { + boolean contained = (null != availableOSDsForObject.remove(objectNo)); + contained = contained || super.removeObjectFromList(objectNo); + return contained; + } + + @Override + protected NextRequest selectNextHook() throws TransferStrategyException { + long objectNo; + + objectNo = selectObject(this.preferredObjects, this.requiredObjects); + + try { + // select OSD + return selectNextOSDHook(objectNo); + } catch (TransferStrategyException e) { + // special error case => take another object + + ObjectSet copyOfPreferredObjects = null; + ObjectSet copyOfRequiredObjects = null; + try { + copyOfPreferredObjects = this.preferredObjects.clone(); + copyOfRequiredObjects = this.requiredObjects.clone(); + } catch (CloneNotSupportedException e2) { + // could not happen + } + assert (copyOfPreferredObjects != null && copyOfRequiredObjects != null); + + while (true) { + objectNo = selectObject(copyOfPreferredObjects, copyOfRequiredObjects); + + try { + // select OSD + return selectNextOSDHook(objectNo); + } catch (TransferStrategyException e1) { + // remove for next time + if (copyOfPreferredObjects.contains(objectNo)) + copyOfPreferredObjects.remove(objectNo); + else if (copyOfRequiredObjects.contains(objectNo)) + copyOfRequiredObjects.remove(objectNo); + + // if all objects are tried throw exception + if (copyOfPreferredObjects.isEmpty() && copyOfRequiredObjects.isEmpty()) + throw e; + } + } + } + } + + /** + * selects an object + * + * @param preferredObjects + * @param requiredObjects + * @return + * @throws TransferStrategyException + */ + protected abstract long selectObject(ObjectSet preferredObjects, ObjectSet requiredObjects) + throws TransferStrategyException; + + @Override + protected NextRequest selectNextOSDHook(long objectNo) throws TransferStrategyException { + NextRequest next = new NextRequest(); + next.objectNo = objectNo; + + List availableOSDsForObject = this.getAvailableOSDsForObject(objectNo); + + if (availableOSDsForObject.size() == 0) + throw new TransferStrategyException("No OSD could be found for object " + objectNo + + ". Maybe it is a hole.", TransferStrategyException.ErrorCode.NO_OSD_FOUND); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "%s:%d - available OSDs for file: %s", fileID, objectNo, availableOSDsForObject + .toString()); + + if (fetchObjectSets) + // time to get a new object set from an OSD? + next.attachObjectSet = isTimeForNewObjectSet(); + + // select the OSD + ServiceUUID osd = selectOSD(availableOSDsForObject, objectNo, next.attachObjectSet); + + if (fetchObjectSets) + // if no object set is available of this OSD => get one + if (!objectsOnOSDs.containsKey(osd)) + next.attachObjectSet = true; + + // check if OSD is available at all + if (osdAvailability.isServiceAvailable(osd)) { + // remove current OSD from list (is requested) + availableOSDsForObject.remove(osd); + + // OSD is available + next.osd = osd; + } else { // OSD is not available + // special error case => "search" for another OSD + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "OSD %s is not available", osd.toString()); + + // to check, if all OSDs have been tested + List testedOSDs = new ArrayList(availableOSDsForObject); + + // test all other OSDs until one is found or all were tested + while (testedOSDs.size() != 0) { + osd = selectOSD(testedOSDs, objectNo, next.attachObjectSet); + + if (osdAvailability.isServiceAvailable(osd)) { + // OSD found + next.osd = osd; + break; + } else { + testedOSDs.remove(osd); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "OSD %s is not available", osd.toString()); + } + } + } + + // if no OSD could be found + if (next.osd == null) { + throw new TransferStrategyException("At the moment no OSD is reachable for object " + objectNo, + TransferStrategyException.ErrorCode.NO_OSD_REACHABLE); + } + + if (fetchObjectSets) + // adapt counter + if (next.attachObjectSet) { + timeSinceLastRandomRequest = 0; + if (!objectsOnOSDs.containsKey(next.osd)) + // set dummy object set, if no object set exists yet; otherwise object set will be + // requested multiple times until the first will be received + super.setOSDsObjectSet(dummyObjectSet, next.osd); + } else + timeSinceLastRandomRequest++; + + return next; + } + + /** + * selects an OSD + * + * @param availableOSDsForObject + * @param objectNo + * @param timeForNewObjectSet + * @return + * @throws TransferStrategyException + */ + protected abstract ServiceUUID selectOSD(List availableOSDsForObject, long objectNo, + boolean timeForNewObjectSet) throws TransferStrategyException; + + /** + * returns a list of available OSDs for the given object + * + * @param objectNo + * @return + */ + protected List getAvailableOSDsForObject(long objectNo) { + // assert (requiredObjects.contains(objectNo) || preferredObjects.contains(objectNo)); + + List list = availableOSDsForObject.get(objectNo); + if (list == null) { + // add existing OSDs containing the object + list = xLoc.getOSDsForObject(objectNo, xLoc.getLocalReplica()); + availableOSDsForObject.put(objectNo, list); + } + return list; + } + + /** + * decides if this request should fetch an object set + * + * @return + */ + protected boolean isTimeForNewObjectSet() { + // assert (getObjectsCount() != 0); + + double ratio = (this.lastObjectNo == 0) ? 1 : super.getObjectsCount() / this.lastObjectNo; + + // value between 10 and 100 +// if (timeSinceLastRandomRequest > defaultNumberOfRequests / ratio) + if (timeSinceLastRandomRequest > defaultNumberOfRequests) + return true; + else + return false; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RandomStrategy.java b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RandomStrategy.java new file mode 100755 index 0000000..0ebd47e --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RandomStrategy.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.transferStrategies; + +import java.util.List; + +import org.xtreemfs.common.ServiceAvailability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.replication.selection.ObjectSetOSDSelection; +import org.xtreemfs.osd.replication.selection.RandomOSDSelection; +import org.xtreemfs.osd.replication.selection.RandomObjectSelection; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; + +/** + * A simple strategy, which selects objects and replicas randomly.
    + * 08.12.2008 + */ +public class RandomStrategy extends MasqueradingTransferStrategy { + /** + * identifies the random strategy in replication flags + */ + public static final REPL_FLAG REPLICATION_FLAG = REPL_FLAG.REPL_FLAG_STRATEGY_RANDOM; + + protected RandomObjectSelection objectSelection; + protected RandomOSDSelection randomOSDselection; + protected ObjectSetOSDSelection objectSetOSDselection; + + /** + * @param rqDetails + */ + public RandomStrategy(String fileId, XLocations xLoc, ServiceAvailability osdAvailability) { + super(fileId, xLoc, osdAvailability, true); + this.objectSelection = new RandomObjectSelection(); + this.randomOSDselection = new RandomOSDSelection(); + this.objectSetOSDselection = new ObjectSetOSDSelection(); + } + + /** + * @return + * @throws TransferStrategyException + */ + @Override + protected long selectObject(ObjectSet preferredObjects, ObjectSet requiredObjects) + throws TransferStrategyException { + long objectNo; + // first fetch a preferred object + if (!preferredObjects.isEmpty()) { + objectNo = objectSelection.selectNextObject(preferredObjects); + } else { // fetch any object + objectNo = objectSelection.selectNextObject(requiredObjects); + } + return objectNo; + } + + @Override + protected ServiceUUID selectOSD(List availableOSDsForObject, long objectNo, + boolean timeForNewObjectSet) throws TransferStrategyException { + ServiceUUID osd; + if (timeForNewObjectSet) { + osd = randomOSDselection.selectNextOSD(availableOSDsForObject); + } else { + osd = objectSetOSDselection.selectNextOSD(availableOSDsForObject, objectsOnOSDs, objectNo); + } + return osd; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RandomStrategyWithoutObjectSets.java b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RandomStrategyWithoutObjectSets.java new file mode 100755 index 0000000..896a1f9 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RandomStrategyWithoutObjectSets.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.transferStrategies; + +import java.util.List; + +import org.xtreemfs.common.ServiceAvailability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.replication.selection.RandomOSDSelection; +import org.xtreemfs.osd.replication.selection.RandomObjectSelection; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; + +/** + * A simple strategy, which selects objects and replicas randomly.
    + * 08.12.2008 + */ +public class RandomStrategyWithoutObjectSets extends MasqueradingTransferStrategy { + /** + * identifies the random strategy in replication flags + */ + public static final REPL_FLAG REPLICATION_FLAG = REPL_FLAG.REPL_FLAG_STRATEGY_RANDOM; + + protected RandomObjectSelection objectSelection; + protected RandomOSDSelection randomOSDselection; +// protected ObjectSetOSDSelection objectSetOSDselection; + + /** + * @param rqDetails + */ + public RandomStrategyWithoutObjectSets(String fileId, XLocations xLoc, ServiceAvailability osdAvailability) { + super(fileId, xLoc, osdAvailability, false); + this.objectSelection = new RandomObjectSelection(); + this.randomOSDselection = new RandomOSDSelection(); +// this.objectSetOSDselection = new ObjectSetOSDSelection(); + } + + /** + * @return + * @throws TransferStrategyException + */ + @Override + protected long selectObject(ObjectSet preferredObjects, ObjectSet requiredObjects) + throws TransferStrategyException { + long objectNo; + // first fetch a preferred object + if (!preferredObjects.isEmpty()) { + objectNo = objectSelection.selectNextObject(preferredObjects); + } else { // fetch any object + objectNo = objectSelection.selectNextObject(requiredObjects); + } + return objectNo; + } + + @Override + protected ServiceUUID selectOSD(List availableOSDsForObject, long objectNo, + boolean timeForNewObjectSet) throws TransferStrategyException { + ServiceUUID osd; +// if (timeForNewObjectSet) { + osd = randomOSDselection.selectNextOSD(availableOSDsForObject); +// } else { +// osd = objectSetOSDselection.selectNextOSD(availableOSDsForObject, objectsOnOSDs, objectNo); +// } + return osd; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RarestFirstStrategy.java b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RarestFirstStrategy.java new file mode 100755 index 0000000..7f4e395 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/RarestFirstStrategy.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.transferStrategies; + +import org.xtreemfs.common.ServiceAvailability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.replication.selection.RarestFirstObjectSelection; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; + +/** + * + *
    + * 27.08.2009 + */ +public class RarestFirstStrategy extends RandomStrategy { + /** + * identifies the random strategy in replication flags + */ + public static final REPL_FLAG REPLICATION_FLAG = REPL_FLAG.REPL_FLAG_STRATEGY_RAREST_FIRST; + + protected RarestFirstObjectSelection objectSelection; + + /** + * @param rqDetails + */ + public RarestFirstStrategy(String fileId, XLocations xLoc, ServiceAvailability osdAvailability) { + super(fileId, xLoc, osdAvailability); + this.objectSelection = new RarestFirstObjectSelection(); + } + + @Override + protected long selectObject(ObjectSet preferredObjects, ObjectSet requiredObjects) + throws TransferStrategyException { + long objectNo; + // first fetch a preferred object + if (!preferredObjects.isEmpty()) { + // preferred objects will not be saved in the queue + objectNo = super.objectSelection.selectNextObject(preferredObjects); + } else { // fetch any object + objectNo = objectSelection.selectNextObject(requiredObjects, super.objectsOnOSDs); + } + return objectNo; + } + + @Override + public boolean addObject(long objectNo, boolean preferred) { + boolean returnValue = super.addObject(objectNo, preferred); + if (!preferred) // if not preferred object => update queue + objectSelection.addObject(objectNo, super.objectsOnOSDs); + return returnValue; + } + + @Override + public void setOSDsObjectSet(ObjectSet set, ServiceUUID osd) { +// objectSelection.newObjectSetArrived(requiredObjects, objectsOnOSDs.get(osd).set, set); + objectSelection.invalidateQueue(); + super.setOSDsObjectSet(set, osd); + } + + @Override + protected boolean removeObjectFromList(long objectNo) { + objectSelection.removeObject(objectNo); + return super.removeObjectFromList(objectNo); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/SequentialPrefetchingStrategy.java b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/SequentialPrefetchingStrategy.java new file mode 100755 index 0000000..43d10a7 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/SequentialPrefetchingStrategy.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.transferStrategies; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import org.xtreemfs.common.ServiceAvailability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.replication.selection.SequentialObjectSelection; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; + +/** + * A sequential strategy which is using simple prefetching. It assumes that objects are read sequentially.
    + * 23.06.2009 + */ +public class SequentialPrefetchingStrategy extends RandomStrategy { + /** + * identifies the sequential strategy in replication flags + */ + public static final REPL_FLAG REPLICATION_FLAG = REPL_FLAG.REPL_FLAG_STRATEGY_SEQUENTIAL_PREFETCHING; + + public static int DEFAULT_PREFETCHING_COUNT = 10; + + protected SequentialObjectSelection objectSelection; + + private StripingPolicyImpl stripingPolicy; + + private int osdIndex = -1; + + /** + * Saves already prefetched objects. Otherwise objects will be fetched again and again, if they are + * replicated faster than objects will be requested (sequential reading). + */ + protected ObjectSet alreadyPrefetchedObjects; + + /** + * @param fileId + * @param loc + * @param osdAvailability + */ + public SequentialPrefetchingStrategy(String fileId, XLocations loc, ServiceAvailability osdAvailability) { + super(fileId, loc, osdAvailability); + this.objectSelection = new SequentialObjectSelection(); + + this.stripingPolicy = xLoc.getLocalReplica().getStripingPolicy(); + this.alreadyPrefetchedObjects = new ObjectSet(); + } + + @Override + protected NextRequest selectNextHook() throws TransferStrategyException { + NextRequest next = super.selectNextHook(); + + if (next != null) { + if (this.osdIndex < 0) { // will be executed only first time this method is called + // save local OSD + ServiceUUID localOSD = xLoc.getLocalReplica().getOSDForObject(next.objectNo); + this.osdIndex = xLoc.getLocalReplica().getOSDs().indexOf(localOSD); + } + + // adjust prefetching count + // the more preferred objects are requested the more popular the file seems to be => prefetch more + // objects + int prefetchingCount = DEFAULT_PREFETCHING_COUNT + this.preferredObjects.size(); + + // TODO: at the moment also already local saved objects will be fetched + // add objects which should be prefetched to lists + try { + if (this.preferredObjects.contains(next.objectNo)) { + Iterator objectsIt = stripingPolicy.getObjectsOfOSD(osdIndex, next.objectNo, + super.lastObjectNo); + objectsIt.next(); // skip current object + for (int i = 0; i < prefetchingCount && objectsIt.hasNext(); i++) { + Long object = objectsIt.next(); + if (!this.preferredObjects.contains(object) && !alreadyPrefetchedObjects.contains(object)) { + // no preferred object + addObject(object, false); + alreadyPrefetchedObjects.add(object); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "%s:%d - prefetch object", fileID, object); + } + } + } + } catch (NoSuchElementException e) { + // just end prefetching + } + } + return next; + } + + @Override + protected long selectObject(ObjectSet preferredObjects, ObjectSet requiredObjects) + throws TransferStrategyException { + long objectNo; + // first try to fetch a preferred object + if (!preferredObjects.isEmpty()) { + objectNo = objectSelection.selectNextObject(preferredObjects); + } else { // fetch any object + objectNo = objectSelection.selectNextObject(requiredObjects); + } + return objectNo; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/SequentialStrategy.java b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/SequentialStrategy.java new file mode 100755 index 0000000..4a211b1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/SequentialStrategy.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.transferStrategies; + +import java.util.Iterator; +import java.util.List; + +import org.xtreemfs.common.ServiceAvailability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.replication.selection.RandomOSDSelection; +import org.xtreemfs.osd.replication.selection.SequentialObjectSelection; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; + +/** + * A simple transfer strategy, which fetches the objects in ascending order. The OSD will be a member of a + * randomly selected completed replica.
    + * 13.10.2008 + */ +public class SequentialStrategy extends MasqueradingTransferStrategy { + /** + * identifies the sequential strategy in replication flags + */ + public static final REPL_FLAG REPLICATION_FLAG = REPL_FLAG.REPL_FLAG_STRATEGY_SEQUENTIAL; + + protected SequentialObjectSelection objectSelection; + protected RandomOSDSelection osdSelection; + + /** + * @param rqDetails + */ + public SequentialStrategy(String fileId, XLocations xLoc, ServiceAvailability osdAvailability) { + super(fileId, xLoc, osdAvailability, false); + this.objectSelection = new SequentialObjectSelection(); + this.osdSelection = new RandomOSDSelection(); + } + + @Override + protected long selectObject(ObjectSet preferredObjects, ObjectSet requiredObjects) + throws TransferStrategyException { + long objectNo; + // first try to fetch a preferred object + if (!preferredObjects.isEmpty()) { + objectNo = objectSelection.selectNextObject(preferredObjects); + } else { // fetch any object + objectNo = objectSelection.selectNextObject(requiredObjects); + } + return objectNo; + } + + @Override + protected ServiceUUID selectOSD(List availableOSDsForObject, long objectNo, + boolean timeForNewObjectSet) throws TransferStrategyException { + return osdSelection.selectNextOSD(availableOSDsForObject); + } + + @Override + protected List getAvailableOSDsForObject(long objectNo) { + assert (requiredObjects.contains(objectNo) || preferredObjects.contains(objectNo)); + + List list = availableOSDsForObject.get(objectNo); + if (list == null) { + // add existing OSDs containing the object + list = xLoc.getOSDsForObject(objectNo, xLoc.getLocalReplica()); + + // remove all not complete replicas + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + ServiceUUID osd = iterator.next(); + if (!xLoc.getReplica(osd).isComplete()) + iterator.remove(); + } + + availableOSDsForObject.put(objectNo, list); + } + return list; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/TransferStrategy.java b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/TransferStrategy.java new file mode 100755 index 0000000..8b87fb8 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/replication/transferStrategies/TransferStrategy.java @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2009 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.replication.transferStrategies; + +import java.util.HashMap; +import java.util.Map; + +import org.xtreemfs.common.ServiceAvailability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.osd.replication.ObjectSet; + +/** + * This class provides the basic functionality needed by the different transfer strategies. One + * TransferStrategy manages a whole file (all objects of this file).
    + * warning: this class is NOT thread-safe
    + * 09.09.2008 + */ +public abstract class TransferStrategy { + /** + * Encapsulates the "returned"/chosen values.
    + * 12.02.2009 + */ + public class NextRequest { + public ServiceUUID osd = null; + public long objectNo = -1; + /** + * if true, the OSD must return a list of all local available objects + */ + public boolean attachObjectSet = false; + + boolean isAllSet() { + return (osd != null) && (objectNo != -1); + } + } + + public static class TransferStrategyException extends Exception { + public enum ErrorCode { + NO_OSD_REACHABLE, NO_OSD_FOUND, + // OBJECT_MUST_BE_HOLE + } + + private final ErrorCode errorCode; + + /** + * + */ + public TransferStrategyException(String message, ErrorCode errorCode) { + super(message); + this.errorCode = errorCode; + } + + public ErrorCode getErrorCode() { + return errorCode; + } + } + + protected String fileID; + protected XLocations xLoc; + /** + * contains the chosen values for the next replication request + */ + private NextRequest next; + + /** + * contains all not preferred objects which must be replicated (e.g. background-replication) + */ + protected ObjectSet requiredObjects; + + /** + * contains all objects which must be replicated first (e.g. client-request) + */ + protected ObjectSet preferredObjects; // requested objects + + /** + * checks if the OSD is available (e.g. network interrupt) + */ + protected final ServiceAvailability osdAvailability; + + public static class ObjectSetInfo { + public ObjectSet set = null; + public int lastRequestSinceXrequests = 0; + public boolean complete = false; + } + + /** + * contains the collected object sets from other OSDs (if collected) + */ + protected Map objectsOnOSDs; + + /** + * @param rqDetails + */ + protected TransferStrategy(String fileID, XLocations xLoc, ServiceAvailability osdAvailability) { + super(); + this.xLoc = xLoc; + this.fileID = fileID; + // TODO use correct stripe width for less memory usage + this.requiredObjects = new ObjectSet(); + this.preferredObjects = new ObjectSet(); + this.objectsOnOSDs = new HashMap(); + this.osdAvailability = osdAvailability; + this.next = null; + } + + public void updateXLoc(XLocations xLoc) { + this.xLoc = xLoc; + } + + /** + * chooses the next object, which will be replicated + */ + public void selectNext() throws TransferStrategyException { + this.next = null; + + if (this.getObjectsCount() > 0) { + assert (!this.preferredObjects.isEmpty() || !this.requiredObjects.isEmpty()); + + NextRequest next = selectNextHook(); + if (next != null && next.isAllSet()) + this.next = next; + } + } + + /** + * Masquerades if an object could not be used at the moment as it is using another object + * + * @return + * @throws TransferStrategyException + */ + protected abstract NextRequest selectNextHook() throws TransferStrategyException; + + /** + * chooses the next OSD for the given object + */ + public void selectNextOSD(long objectNo) throws TransferStrategyException { + this.next = null; + NextRequest next = selectNextOSDHook(objectNo); + if (next != null && next.isAllSet()) + this.next = next; + } + + /** + * Masquerades if an OSD could not be used at the moment as it is using another OSD + * + * @return + * @throws TransferStrategyException + */ + protected abstract NextRequest selectNextOSDHook(long objectNo) throws TransferStrategyException; + + /** + * Returns the "result" from selectNext(). + * + * @return null, if selectNext() has not been executed before (since getNext() was called last time) or no + * object to fetch exists + * @see java.util.ArrayList#add(java.lang.Object) + */ + public NextRequest getNext() { + if (next != null) { + // remove object from lists, so it can't be chosen twice + removeObjectFromList(next.objectNo); + } + return next; + } + + /** + * add an object which must be replicated + * + * @param objectNo + * @param preferred + * @return + * @see java.util.ArrayList#add(java.lang.Object) + */ + public boolean addObject(long objectNo, boolean preferred) { + if (preferred) { + // object must not contained in both lists + if (requiredObjects.contains(objectNo)) + requiredObjects.remove(objectNo); + return preferredObjects.add(objectNo); + } else { + // object must not contained in both lists + if (preferredObjects.contains(objectNo)) + preferredObjects.remove(objectNo); + return requiredObjects.add(objectNo); + } + } + + /** + * removes the objectNo only from the list of replicating objects (called internally) + * + * @param objectNo + * @return + * @see java.util.ArrayList#remove(java.lang.Object) + */ + protected boolean removeObjectFromList(long objectNo) { + boolean contained = preferredObjects.remove(objectNo); + contained = contained || requiredObjects.remove(objectNo); + return contained; + } + + /** + * remove an object which need not be replicated anymore + * + * @param objectNo + * @return + * @see java.util.ArrayList#remove(java.lang.Object) + */ + public abstract boolean removeObject(long objectNo); + + /** + * Returns how much objects will be replicated. + * + * @return + */ + public long getObjectsCount() { + return preferredObjects.size() + requiredObjects.size(); + } + + /** + * Returns if more objects will be replicated. + * + * @return + */ + public boolean isObjectListEmpty() { + return preferredObjects.isEmpty() && requiredObjects.isEmpty(); + } + + /** + * adds/updates the object set of the given OSD + * + * @param set + * @param osd + */ + public void setOSDsObjectSet(ObjectSet set, ServiceUUID osd) { + ObjectSetInfo objectSetInfo = objectsOnOSDs.get(osd); + if (objectSetInfo == null) { // new + objectSetInfo = new ObjectSetInfo(); + objectsOnOSDs.put(osd, objectSetInfo); + } + objectSetInfo.set = set; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/rwre/CoordinatedReplicaUpdatePolicy.java b/java/servers/src/org/xtreemfs/osd/rwre/CoordinatedReplicaUpdatePolicy.java new file mode 100644 index 0000000..102989b --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/rwre/CoordinatedReplicaUpdatePolicy.java @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2010-2012 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.rwre; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.flease.Flease; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.client.RPCResponseAvailableListener; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.rwre.RWReplicationStage.Operation; +import org.xtreemfs.osd.rwre.ReplicatedFileState.ReplicaState; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * + * @author bjko + */ +public abstract class CoordinatedReplicaUpdatePolicy extends ReplicaUpdatePolicy { + + private final OSDServiceClient client; + + public CoordinatedReplicaUpdatePolicy(List remoteOSDUUIDs, String localUUID, String fileId, + OSDServiceClient client) { + super(remoteOSDUUIDs, fileId, localUUID); + this.client = client; + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"(R:%s) created %s for %s",localUUID,this.getClass().getSimpleName(),cellId); + } + + /** + * + * @param operation + * @return number of external acks required for an operation (majority minus local replica). + */ + public abstract int getNumRequiredAcks(Operation operation); + + public abstract boolean backupCanRead(); + + + @Override + public void closeFile() { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"(R:%s) closed %s for %s",localUUID,this.getClass().getSimpleName(),cellId); + } + + @Override + public boolean requiresLease() { + return true; + } + + @Override + public void executeReset(final FileCredentials credentials, final ReplicaStatus localReplicaState, final ExecuteResetCallback callback) { + final String fileId = credentials.getXcap().getFileId(); + final int numAcksRequired = getNumRequiredAcks(Operation.INTERNAL_UPDATE); + final int numRequests = remoteOSDUUIDs.size(); + final int maxErrors = numRequests - numAcksRequired; + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"(R:%s) fetching replica state for %s from %d replicas (majority: %d), local max: %d", + localUUID, fileId, numRequests, numAcksRequired, this.localObjVersion); + } + + final RPCResponse[] responses = new RPCResponse[remoteOSDUUIDs.size()]; + try { + for (int i = 0; i < responses.length; i++) { + responses[i] = client.xtreemfs_rwr_status(remoteOSDUUIDs.get(i).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + credentials, credentials.getXcap().getFileId(), + 0); // maxObjVer = 0 => let the remote OSD assume that we don't have any objects yet. Important to detect wholes (writes not seen by this replica). + } + } catch (IOException ex) { + callback.failed(ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, ex.toString(),ex)); + return; + } + + RPCResponseAvailableListener listener = new RPCResponseAvailableListener() { + int numResponses = 0; + int numErrors = 0; + boolean exceptionSent = false; + ReplicaStatus[] states = new ReplicaStatus[remoteOSDUUIDs.size() + 1]; + + @Override + public void responseAvailable(RPCResponse r) { + if (numResponses < numAcksRequired) { + int osdNum = -1; + for (int i = 0; i < numRequests; i++) { + if (responses[i] == r) { + osdNum = i; + break; + } + } + assert(osdNum > -1); + try { + states[osdNum] = (ReplicaStatus)r.get(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"(R:%s) received status response for %s from %s", localUUID, fileId, remoteOSDUUIDs.get(osdNum)); + } + numResponses++; + } catch (Exception ex) { + numErrors++; + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"no status response from %s fro %s due to exception: %s (acks: %d, errs: %d, maxErrs: %d)", + remoteOSDUUIDs.get(osdNum), fileId, ex.toString(), numResponses, numErrors, maxErrors); + if (numErrors > maxErrors) { + if (!exceptionSent) { + exceptionSent = true; + String errorMessage = String.format("(R:%s) read status FAILED for %s on %s (this is request #%d out of %d which failed)", localUUID, fileId, remoteOSDUUIDs.get(osdNum), numErrors, remoteOSDUUIDs.size()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, errorMessage); + } + callback.failed(ErrorUtils.getInternalServerError(ex, errorMessage)); + } + } + return; + } finally { + r.freeBuffers(); + } + } else { + try { + r.get(); + } catch (Exception e) { + // ignore. + } + r.freeBuffers(); + return; + } + + if (numResponses == numAcksRequired) { + states[states.length - 1] = localReplicaState; + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"(R:%s) received enough status responses for %s",localUUID, fileId); + } + AuthoritativeReplicaState auth = CalculateAuthoritativeState(states, fileId); + final RPCResponseAvailableListener listener2 = new RPCResponseAvailableListener() { + + @Override + public void responseAvailable(RPCResponse r) { + r.freeBuffers(); + } + }; + + // TODO(mberlin): Send auth state only to those backups which don't have the latest state. + for (int i = 0; i < remoteOSDUUIDs.size(); i++) { + try { + RPCResponse r2 = client.xtreemfs_rwr_auth_state(remoteOSDUUIDs.get(i).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + credentials, credentials.getXcap().getFileId(), auth); + r2.registerListener(listener2); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"sent auth state to backup %s for file %s",remoteOSDUUIDs.get(i), fileId); + } + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_WARN, Category.replication, this,"(R:%s) cannot send auth state to backup: %s",localUUID, ex.toString()); + } + } + + callback.finished(auth); + } + + } + }; + for (int i = 0; i < responses.length; i++) { + responses[i].registerListener(listener); + } + + //callback.writeUpdateCompleted(null, null, null); + } + + private static final class ObjectMapRecord { + public long version; + public List osds; + } + + public AuthoritativeReplicaState CalculateAuthoritativeState(ReplicaStatus[] states, String fileId) { + return CalculateAuthoritativeState(states, fileId, localUUID, remoteOSDUUIDs); + } + + /** + * Calculate the AuthoritativeReplicaState containing information about the latest version of the file's objects and + * the replicas storing them. + * + * @param states + * The states array has to store at index i the ReplicaStatus returned by the replica managed by the OSD + * identified by the UUID stored at position i in the remoteOSDUUIDs list. + * @param fileId + * Identifier of the file the AuthoritativeReplicaState is calculated for. + * @param localUUID + * Special UUID that is always linked to the last element in the states array. + * @param remoteOSDUUIDs + * List of UUIDs that are corresponding to the entries in states. + * @return + */ + public static AuthoritativeReplicaState CalculateAuthoritativeState(ReplicaStatus[] states, String fileId, + String localUUID, List remoteOSDUUIDs) { + StringBuilder stateStr = new StringBuilder(); + Map truncateLog = new HashMap(); + Map all_objects = new HashMap(); + long maxTruncateEpoch = 0; + long maxObjectVersion = 0; + + for (int i = 0; i < states.length; i++) { + final ReplicaStatus state = states[i]; + if (state == null) { + // Skip null entries, server did not respond. + continue; + } + if (state.getTruncateEpoch() > maxTruncateEpoch) { + maxTruncateEpoch = state.getTruncateEpoch(); + } + for (TruncateRecord trec : state.getTruncateLog().getRecordsList()) { + truncateLog.put(trec.getVersion(), trec); + } + for (ObjectVersion over : state.getObjectVersionsList()) { + final long onum = over.getObjectNumber(); + if (over.getObjectVersion() > maxObjectVersion) { + maxObjectVersion = over.getObjectVersion(); + } + ObjectVersionMapping.Builder omr = all_objects.get(onum); + if ((omr == null) || (omr.getObjectVersion() < over.getObjectVersion())) { + omr = ObjectVersionMapping.newBuilder(); + omr.setObjectVersion(over.getObjectVersion()); + omr.setObjectNumber(onum); + all_objects.put(onum, omr); + } + if (omr.getObjectVersion() == over.getObjectVersion()) { + if (i < states.length - 1) { + omr.addOsdUuids(remoteOSDUUIDs.get(i).toString()); + } else { + // Last state is the local state, i.e. local OSD. + omr.addOsdUuids(localUUID); + } + } + } + } + + for (TruncateRecord trec : truncateLog.values()) { + Iterator> iter = all_objects.entrySet().iterator(); + while (iter.hasNext()) { + final Entry e = iter.next(); + if (e.getKey() > trec.getLastObjectNumber() && + e.getValue().getObjectVersion() < trec.getVersion()) { + iter.remove(); + } + } + } + + if (Logging.isDebug()) { + stateStr.append("tlog={"); + for (TruncateRecord trec : truncateLog.values()) { + stateStr.append("("); + stateStr.append(trec.getVersion()); + stateStr.append(","); + stateStr.append(trec.getLastObjectNumber()); + stateStr.append("),"); + } + stateStr.append("} "); + + stateStr.append("objs={"); + for (Entry obj : all_objects.entrySet()) { + stateStr.append("("); + stateStr.append(obj.getKey()); + stateStr.append(","); + stateStr.append(obj.getValue().getObjectVersion()); + stateStr.append("),"); + } + stateStr.append("} maxV="); + stateStr.append(maxObjectVersion); + stateStr.append(" maxTE="); + stateStr.append(maxTruncateEpoch); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, (Object) null, + "(R:%s) AUTH state for %s: %s", localUUID, fileId, stateStr.toString()); + } + } + + AuthoritativeReplicaState.Builder auth = AuthoritativeReplicaState.newBuilder(); + auth.setTruncateEpoch(0); + + TruncateLog.Builder tlogBuilder = TruncateLog.newBuilder(); + tlogBuilder.addAllRecords(truncateLog.values()); + auth.setTruncateLog(tlogBuilder); + auth.setTruncateEpoch(maxTruncateEpoch); + auth.setMaxObjVersion(maxObjectVersion); + + for (ObjectVersionMapping.Builder obj : all_objects.values()) { + auth.addObjectVersions(obj); + } + + return auth.build(); + } + + @Override + public void executeWrite(FileCredentials credentials, long objNo, long objVersion, InternalObjectData data, final ClientOperationCallback callback) { + final String fileId = credentials.getXcap().getFileId(); + final int numAcksRequired = getNumRequiredAcks(Operation.WRITE); + final int numRequests = remoteOSDUUIDs.size(); + final int maxErrors = numRequests - numAcksRequired; + + final RPCResponse[] responses = new RPCResponse[remoteOSDUUIDs.size()]; + final RPCResponseAvailableListener l = getResponseListener(callback, maxErrors, numAcksRequired, fileId, Operation.WRITE); + try { + for (int i = 0; i < responses.length; i++) { + responses[i] = client.xtreemfs_rwr_update(remoteOSDUUIDs.get(i).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, + credentials, credentials.getXcap().getFileId(), 0, + objNo, objVersion, 0, data.getMetadata(), data.getData().createViewBuffer()); + responses[i].registerListener(l); + } + } catch (IOException ex) { + callback.failed(ErrorUtils.getInternalServerError(ex)); + } finally { + BufferPool.free(data.getData()); + } + + //callback.writeUpdateCompleted(null, null, null); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"(R:%s) sent update for %s", localUUID, fileId); + } + + @Override + public void executeTruncate(FileCredentials credentials, long newFileSize, long newObjectVersion, final ClientOperationCallback callback) { + final String fileId = credentials.getXcap().getFileId(); + final int numAcksRequired = getNumRequiredAcks(Operation.TRUNCATE); + final int numRequests = remoteOSDUUIDs.size(); + final int maxErrors = numRequests - numAcksRequired; + + final RPCResponseAvailableListener l = getResponseListener(callback, maxErrors, numAcksRequired, fileId, Operation.TRUNCATE); + final RPCResponse[] responses = new RPCResponse[remoteOSDUUIDs.size()]; + try { + for (int i = 0; i < responses.length; i++) { + responses[i] = client.xtreemfs_rwr_truncate(remoteOSDUUIDs.get(i).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + credentials, credentials.getXcap().getFileId(), newFileSize, newObjectVersion); + responses[i].registerListener(l); + } + } catch (IOException ex) { + callback.failed(ErrorUtils.getInternalServerError(ex)); + } + + //callback.writeUpdateCompleted(null, null, null); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"(R:%s) sent truncate update for %s", localUUID, fileId); + } + + protected RPCResponseAvailableListener getResponseListener(final ClientOperationCallback callback, + final int maxErrors, final int numAcksRequired, final String fileId, final Operation operation) { + + assert(numAcksRequired <= this.remoteOSDUUIDs.size()); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"(R:%s) new response listener for %s (acks %d, errs %d)",localUUID,fileId,numAcksRequired,maxErrors); + + assert(maxErrors >= 0); + RPCResponseAvailableListener listener = new RPCResponseAvailableListener() { + int numAcks = 0; + int numErrors = 0; + boolean responseSent = false; + + @Override + public void responseAvailable(RPCResponse r) { + try { + r.get(); + numAcks++; + } catch (Exception ex) { + numErrors++; + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"exception for %s/%s (acks: %d, errs: %d, maxErrs: %d)", + operation, fileId, numAcks, numErrors, maxErrors); + if (numErrors > maxErrors) { + if (!responseSent) { + responseSent = true; + Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this,"replicated %s FAILED for %s (acks: %d, errs: %d, maxErrs: %d)", + operation, fileId, numAcks, numErrors, maxErrors); + callback.failed(ErrorUtils.getInternalServerError(ex)); + } + } + return; + } finally { + r.freeBuffers(); + } + if (numAcks == numAcksRequired) { + responseSent = true; + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"replicated %s successfull for %s",operation,fileId); + } + callback.finished(); + } + + } + }; + return listener; + } + + @Override + public long onClientOperation(Operation operation, long objVersion, ReplicaState currentState, Flease lease) throws RedirectToMasterException, IOException { + if (currentState == ReplicaState.PRIMARY) { + long tmpObjVer; + if (operation != Operation.READ) { + if (this.localObjVersion == -1) { + this.localObjVersion = 0; + } + assert(this.localObjVersion > -1); + tmpObjVer = ++this.localObjVersion; + } else { + tmpObjVer = localObjVersion; + } + final long nextObjVer = tmpObjVer; + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"(R:%s) prepared op for %s with objVer %d",localUUID, cellId,nextObjVer); + + return nextObjVer; + } else if (currentState == ReplicaState.BACKUP) { + if (backupCanRead() && (operation == Operation.READ)) { + return this.localObjVersion; + } else { + if ((lease == null) || (lease.isEmptyLease())) { + Logging.logMessage(Logging.LEVEL_WARN, Category.replication, this,"unknown lease state for %s: %s",this.cellId,lease); + throw new RetryException("unknown lease state for cell "+this.cellId+", can't redirect to master. Please retry."); + } else + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "(R:%s) local is backup, redirecting for fileid %s to %s", + localUUID, this.cellId,lease.getLeaseHolder().toString()); + throw new RedirectToMasterException(lease.getLeaseHolder().toString()); + } + } else { + throw new IOException("invalid state: "+currentState); + } + } + + @Override + public boolean onRemoteUpdate(long objVersion, ReplicaState state) throws IOException { + //apply everything... + if (state == ReplicaState.PRIMARY) { + throw new IOException("no accepting updates in PRIMARY mode"); + } + + if ((objVersion == 1) && (localObjVersion == -1)) { + localObjVersion = 1; + return false; + } + + if (objVersion <= localObjVersion) { + Logging.logMessage(Logging.LEVEL_WARN, Category.replication, this, + "Received object version %d, local is %d for file %s", + objVersion, localObjVersion, cellId.toString()); + } + + if (objVersion > localObjVersion) { + localObjVersion = objVersion; + } + + return false; + } + + @Override + public boolean acceptRemoteUpdate(long objVersion) throws IOException { + return objVersion >= localObjVersion; + } + + @Override + public boolean onPrimary(int masterEpoch) throws IOException { + //no need to catch up on primary + if (masterEpoch != FleaseMessage.IGNORE_MASTER_EPOCH) { + this.localObjVersion = (long)masterEpoch << 32; + } + return true; + } + + @Override + public boolean onBackup() throws IOException { + return false; + } + + @Override + public void onFailed() throws IOException { + //don't care + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/rwre/FleaseMasterEpochThread.java b/java/servers/src/org/xtreemfs/osd/rwre/FleaseMasterEpochThread.java new file mode 100644 index 0000000..0837862 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/rwre/FleaseMasterEpochThread.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.rwre; + +import java.io.IOException; + +import org.xtreemfs.foundation.flease.MasterEpochHandlerInterface; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.osd.stages.Stage; +import org.xtreemfs.osd.storage.StorageLayout; + +/** + * + * @author bjko + */ +public class FleaseMasterEpochThread extends Stage implements MasterEpochHandlerInterface { + private static final int STAGEOP_GET_MEPOCH = 1; + private static final int STAGEOP_SET_MEPOCH = 2; + + private final StorageLayout layout; + + public FleaseMasterEpochThread(StorageLayout layout, int maxRequestsQueueLength) { + super("FlMEpoThr", maxRequestsQueueLength); + this.layout = layout; + } + + @Override + protected void processMethod(StageRequest method) { + final Continuation callback = (Continuation) method.getCallback(); + final FleaseMessage message = (FleaseMessage) method.getArgs()[0]; + final String fileId = ReplicaUpdatePolicy.cellToFileId(message.getCellId()); + switch (method.getStageMethod()) { + case STAGEOP_GET_MEPOCH: { + try { + message.setMasterEpochNumber(layout.getMasterEpoch(fileId)); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "fetched master epoch for %s: %d", fileId, message.getMasterEpochNumber()); + } + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + message.setMasterEpochNumber(-1l); + } + callback.processingFinished(); + break; + } + case STAGEOP_SET_MEPOCH: { + try { + layout.setMasterEpoch(fileId, (int)message.getMasterEpochNumber()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "set master epoch for %s: %d", fileId, message.getMasterEpochNumber()); + } + callback.processingFinished(); + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + break; + } + default: { + throw new IllegalStateException("no such operation: " + method.getStageMethod()); + } + } + } + + @Override + public void sendMasterEpoch(FleaseMessage fm, Continuation cntntn) { + this.enqueueOperation(STAGEOP_GET_MEPOCH, new Object[]{fm}, null, cntntn); + } + + @Override + public void storeMasterEpoch(FleaseMessage fm, Continuation cntntn) { + this.enqueueOperation(STAGEOP_SET_MEPOCH, new Object[]{fm}, null, cntntn); + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/rwre/ObjectFetchRecord.java b/java/servers/src/org/xtreemfs/osd/rwre/ObjectFetchRecord.java new file mode 100644 index 0000000..ac6ba8a --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/rwre/ObjectFetchRecord.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.rwre; + +import java.net.InetSocketAddress; +import java.util.List; + +public class ObjectFetchRecord { + + private static final long NO_TRUNCATE = -1; + + private final long objNumber; + + private long objVersion; + + private final List osds; + + private int osdToUse; + + private final long newFileSize; + + private final long newTruncateEpoch; + + public ObjectFetchRecord(long objNo, long objVer, List osds) { + super(); + this.objNumber = objNo; + this.objVersion = objVer; + this.osds = osds; + osdToUse = 0; + newFileSize = NO_TRUNCATE; + newTruncateEpoch = 0; + } + + public ObjectFetchRecord(long newFileSize, long newTruncateEpoch) { + this.newFileSize = newFileSize; + this.newTruncateEpoch = newTruncateEpoch; + this.objNumber = -1; + this.osds = null; + } + + public boolean isTruncate() { + return this.newFileSize != NO_TRUNCATE; + } + + /** + * @return the objNumber + */ + public long getObjNumber() { + return objNumber; + } + + /** + * @return the objVersion + */ + public long getObjVersion() { + return objVersion; + } + + public boolean equals(Object o) { + if (o == this) { + return true; + } + try { + ObjectFetchRecord ofr = (ObjectFetchRecord) o; + return ofr.objNumber == this.objNumber; + } catch (ClassCastException ex) { + return false; + } + } + + /** + * @return the osds + */ + public InetSocketAddress getNextOSD() { + if (osdToUse < osds.size()) + return osds.get(osdToUse++); + else + return null; + } + + List getOsds() { + return osds; + } + + /** + * @param objVersion the objVersion to set + */ + public void setObjVersion(long objVersion) { + this.objVersion = objVersion; + } + + public String toString() { + return objNumber+"@"+objVersion+" osds: "+osds; + } + + /** + * @return the newFileSize + */ + public long getNewFileSize() { + return newFileSize; + } + + /** + * @return the newTruncateEpoch + */ + public long getNewTruncateEpoch() { + return newTruncateEpoch; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/rwre/RWReplicationStage.java b/java/servers/src/org/xtreemfs/osd/rwre/RWReplicationStage.java new file mode 100644 index 0000000..876c7ed --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/rwre/RWReplicationStage.java @@ -0,0 +1,1532 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.rwre; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.atomic.AtomicInteger; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.flease.Flease; +import org.xtreemfs.foundation.flease.FleaseConfig; +import org.xtreemfs.foundation.flease.FleaseMessageSenderInterface; +import org.xtreemfs.foundation.flease.FleaseStage; +import org.xtreemfs.foundation.flease.FleaseStatusListener; +import org.xtreemfs.foundation.flease.FleaseViewChangeListenerInterface; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.flease.proposer.FleaseException; +import org.xtreemfs.foundation.flease.proposer.FleaseListener; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.client.RPCResponseAvailableListener; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.operations.EventRWRStatus; +import org.xtreemfs.osd.operations.OSDOperation; +import org.xtreemfs.osd.rwre.ReplicatedFileState.ReplicaState; +import org.xtreemfs.osd.stages.PreprocStage.InvalidateXLocSetCallback; +import org.xtreemfs.osd.stages.Stage; +import org.xtreemfs.osd.stages.StorageStage.DeleteObjectsCallback; +import org.xtreemfs.osd.stages.StorageStage.InternalGetMaxObjectNoCallback; +import org.xtreemfs.osd.stages.StorageStage.WriteObjectCallback; +import org.xtreemfs.osd.storage.CowPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * + * @author bjko + */ +public class RWReplicationStage extends Stage implements FleaseMessageSenderInterface { + + public static final int STAGEOP_REPLICATED_WRITE = 1; + public static final int STAGEOP_CLOSE = 2; + public static final int STAGEOP_PROCESS_FLEASE_MSG = 3; + public static final int STAGEOP_PREPAREOP = 5; + public static final int STAGEOP_TRUNCATE = 6; + public static final int STAGEOP_GETSTATUS = 7; + + public static final int STAGEOP_INTERNAL_AUTHSTATE = 10; + public static final int STAGEOP_INTERNAL_OBJFETCHED = 11; + + public static final int STAGEOP_LEASE_STATE_CHANGED = 13; + public static final int STAGEOP_INTERNAL_STATEAVAIL = 14; + public static final int STAGEOP_INTERNAL_DELETE_COMPLETE = 15; + public static final int STAGEOP_FORCE_RESET = 16; + public static final int STAGEOP_INTERNAL_MAXOBJ_AVAIL = 17; + public static final int STAGEOP_INTERNAL_BACKUP_AUTHSTATE = 18; + + public static final int STAGEOP_SETVIEW = 21; + public static final int STAGEOP_INVALIDATEVIEW = 22; + public static final int STAGEOP_FETCHINVALIDATED = 23; + + public static enum Operation { + READ, + WRITE, + TRUNCATE, + INTERNAL_UPDATE, + INTERNAL_TRUNCATE + }; + + private final RPCNIOSocketClient client; + + private final OSDServiceClient osdClient; + + private final Map files; + + private final Map cellToFileId; + + private final OSDRequestDispatcher master; + + private final FleaseStage fstage; + + private final RPCNIOSocketClient fleaseClient; + + private final OSDServiceClient fleaseOsdClient; + + private final ASCIIString localID; + + private int numObjsInFlight; + + private static final int MAX_OBJS_IN_FLIGHT = 10; + + private static final int MAX_PENDING_PER_FILE = 10; + + private static final int MAX_EXTERNAL_REQUESTS_IN_Q = 250; + + private final Queue filesInReset; + + private final FleaseMasterEpochThread masterEpochThread; + + private final AtomicInteger externalRequestsInQueue; + + public RWReplicationStage(OSDRequestDispatcher master, SSLOptions sslOpts, int maxRequestsQueueLength) + throws IOException { + super("RWReplSt", maxRequestsQueueLength); + this.master = master; + client = new RPCNIOSocketClient(sslOpts, 15000, 60000 * 5, "RWReplicationStage"); + fleaseClient = new RPCNIOSocketClient(sslOpts, 15000, 60000 * 5, "RWReplicationStage (flease)"); + osdClient = new OSDServiceClient(client, null); + fleaseOsdClient = new OSDServiceClient(fleaseClient, null); + files = new HashMap(); + cellToFileId = new HashMap(); + numObjsInFlight = 0; + filesInReset = new LinkedList(); + externalRequestsInQueue = new AtomicInteger(0); + + localID = new ASCIIString(master.getConfig().getUUID().toString()); + + masterEpochThread = new FleaseMasterEpochThread(master.getStorageStage().getStorageLayout(), + maxRequestsQueueLength); + + FleaseConfig fcfg = new FleaseConfig(master.getConfig().getFleaseLeaseToMS(), master.getConfig() + .getFleaseDmaxMS(), master.getConfig().getFleaseMsgToMS(), null, localID.toString(), master.getConfig() + .getFleaseRetries()); + + fstage = new FleaseStage(fcfg, master.getConfig().getObjDir() + "/", this, false, + new FleaseViewChangeListenerInterface() { + + @Override + public void viewIdChangeEvent(ASCIIString cellId, int viewId) { + eventViewIdChanged(cellId, viewId); + } + }, new FleaseStatusListener() { + + @Override + public void statusChanged(ASCIIString cellId, Flease lease) { + // FIXME: change state + eventLeaseStateChanged(cellId, lease, null); + } + + @Override + public void leaseFailed(ASCIIString cellID, FleaseException error) { + // change state + // flush pending requests + eventLeaseStateChanged(cellID, null, error); + } + }, masterEpochThread); + fstage.setLifeCycleListener(master); + } + + @Override + public void start() { + masterEpochThread.start(); + client.start(); + fleaseClient.start(); + fstage.start(); + super.start(); + } + + @Override + public void shutdown() { + client.shutdown(); + fleaseClient.shutdown(); + fstage.shutdown(); + masterEpochThread.shutdown(); + super.shutdown(); + } + + @Override + public void waitForStartup() throws Exception { + masterEpochThread.waitForStartup(); + client.waitForStartup(); + fleaseClient.waitForStartup(); + fstage.waitForStartup(); + super.waitForStartup(); + } + + @Override + public void waitForShutdown() throws Exception { + client.waitForShutdown(); + fleaseClient.waitForShutdown(); + fstage.waitForShutdown(); + masterEpochThread.waitForShutdown(); + super.waitForShutdown(); + } + + public void eventReplicaStateAvailable(String fileId, ReplicaStatus localState, ErrorResponse error) { + this.enqueueOperation(STAGEOP_INTERNAL_STATEAVAIL, new Object[] { fileId, localState, error }, null, null); + } + + public void eventForceReset(FileCredentials credentials, XLocations xloc) { + this.enqueueOperation(STAGEOP_FORCE_RESET, new Object[] { credentials, xloc }, null, null); + } + + public void eventDeleteObjectsComplete(String fileId, ErrorResponse error) { + this.enqueueOperation(STAGEOP_INTERNAL_DELETE_COMPLETE, new Object[] { fileId, error }, null, null); + } + + void eventObjectFetched(String fileId, ObjectVersionMapping object, InternalObjectData data, ErrorResponse error) { + this.enqueueOperation(STAGEOP_INTERNAL_OBJFETCHED, new Object[] { fileId, object, data, error }, null, null); + } + + void eventSetAuthState(String fileId, AuthoritativeReplicaState authState, ReplicaStatus localState, + ErrorResponse error) { + this.enqueueOperation(STAGEOP_INTERNAL_AUTHSTATE, new Object[] { fileId, authState, localState, error }, null, + null); + } + + void eventLeaseStateChanged(ASCIIString cellId, Flease lease, FleaseException error) { + this.enqueueOperation(STAGEOP_LEASE_STATE_CHANGED, new Object[] { cellId, lease, error }, null, null); + } + + void eventMaxObjAvail(String fileId, long maxObjVer, long fileSize, long truncateEpoch, ErrorResponse error) { + this.enqueueOperation(STAGEOP_INTERNAL_MAXOBJ_AVAIL, new Object[] { fileId, maxObjVer, error }, null, null); + } + + public void eventBackupReplicaReset(String fileId, AuthoritativeReplicaState authState, ReplicaStatus localState, + FileCredentials credentials, XLocations xloc) { + this.enqueueOperation(STAGEOP_INTERNAL_BACKUP_AUTHSTATE, new Object[] { fileId, authState, localState, + credentials, xloc }, null, null); + } + + void eventViewIdChanged(ASCIIString cellId, int viewId) { + master.getPreprocStage().updateXLocSetFromFlease(cellId, viewId); + } + + private void executeSetAuthState(final ReplicaStatus localState, final AuthoritativeReplicaState authState, + ReplicatedFileState state, final String fileId) { + // Calculate what we need to do locally based on the local state. + boolean resetRequired = localState.getTruncateEpoch() < authState.getTruncateEpoch(); + // Create a list of missing objects. + Map objectsToBeDeleted = new HashMap(); + for (ObjectVersion localObject : localState.getObjectVersionsList()) { + // Never delete any object which is newer than auth state! + if (localObject.getObjectVersion() <= authState.getMaxObjVersion()) { + objectsToBeDeleted.put(localObject.getObjectNumber(), localObject.getObjectVersion()); + } + } + // Delete everything that is older or not part of the authoritative state. + for (ObjectVersionMapping authObject : authState.getObjectVersionsList()) { + Long version = objectsToBeDeleted.get(authObject.getObjectNumber()); + if ((version != null) && (version == authObject.getObjectVersion())) { + objectsToBeDeleted.remove(authObject.getObjectNumber()); + } + } + Map missingObjects = new HashMap(); + for (ObjectVersionMapping authObject : authState.getObjectVersionsList()) { + missingObjects.put(authObject.getObjectNumber(), authObject); + } + for (ObjectVersion localObject : localState.getObjectVersionsList()) { + ObjectVersionMapping object = missingObjects.get(localObject.getObjectNumber()); + if ((object != null) && (localObject.getObjectVersion() >= object.getObjectVersion())) { + missingObjects.remove(localObject.getObjectNumber()); + } + } + if (!missingObjects.isEmpty() || !objectsToBeDeleted.isEmpty() + || (localState.getTruncateEpoch() < authState.getTruncateEpoch())) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) replica RESET required updates for: %s", localID, state.getFileId()); + } + state.setObjectsToFetch(new LinkedList(missingObjects.values())); + filesInReset.add(state); + // Start by deleting the old objects. + master.getStorageStage().deleteObjects(fileId, state.getsPolicy(), authState.getTruncateEpoch(), + objectsToBeDeleted, new DeleteObjectsCallback() { + + @Override + public void deleteObjectsComplete(ErrorResponse error) { + eventDeleteObjectsComplete(fileId, error); + } + }); + } else { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) replica RESET finished (replica is up-to-date): %s", localID, state.getFileId()); + } + doOpen(state); + } + } + + private void processLeaseStateChanged(StageRequest method) { + try { + final ASCIIString cellId = (ASCIIString) method.getArgs()[0]; + final Flease lease = (Flease) method.getArgs()[1]; + final FleaseException error = (FleaseException) method.getArgs()[2]; + + if (error == null) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) lease change event: %s, %s", localID, cellId, lease); + } + } else { + // Logging.logMessage(Logging.LEVEL_WARN, Category.replication, + // this,"(R:%s) lease error in cell %s: %s cell debug: %s",localID, cellId, error, + // error.getFleaseCellDebugString()); + Logging.logMessage(Logging.LEVEL_WARN, Category.replication, this, "(R:%s) lease error in cell %s: %s", + localID, cellId, error); + } + + final String fileId = cellToFileId.get(cellId); + if (fileId != null) { + ReplicatedFileState state = files.get(fileId); + assert (state != null); + + // Ignore any leaseStateChange if the replica is invalidated + if (state.isInvalidated()) { + return; + } + + boolean leaseOk = false; + if (error == null) { + boolean localIsPrimary = (lease.getLeaseHolder() != null) + && (lease.getLeaseHolder().equals(localID)); + ReplicaState oldState = state.getState(); + state.setLocalIsPrimary(localIsPrimary); + state.setLease(lease); + + // Error handling for timeouts on the primary. + if (oldState == ReplicaState.PRIMARY + && lease.getLeaseHolder() == null + && lease.getLeaseTimeout_ms() == 0) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this, + "(R:%s) was primary, lease error in cell %s, restarting replication: %s", localID, + cellId, lease, error); + failed(state, + ErrorUtils.getInternalServerError(new IOException(fileId + + ": lease timed out, renew failed")), "processLeaseStateChanged"); + } else { + if ((state.getState() == ReplicaState.BACKUP) + || (state.getState() == ReplicaState.PRIMARY) + || (state.getState() == ReplicaState.WAITING_FOR_LEASE)) { + if (localIsPrimary) { + // notify onPrimary + if (oldState != ReplicaState.PRIMARY) { + state.setMasterEpoch(lease.getMasterEpochNumber()); + doPrimary(state); + } + } else { + if (oldState != ReplicaState.BACKUP) { + state.setMasterEpoch(FleaseMessage.IGNORE_MASTER_EPOCH); + doBackup(state); + } + } + } + } + } else { + failed(state, ErrorUtils.getInternalServerError(error), "processLeaseStateChanged (error != null)"); + } + } + + } catch (Exception ex) { + Logging.logMessage(Logging.LEVEL_ERROR, this, + "Exception was thrown and caught while processing the change of the lease state." + + " This is an error in the code. Please report it! Caught exception: "); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + private void processBackupAuthoritativeState(StageRequest method) { + try { + final String fileId = (String) method.getArgs()[0]; + final AuthoritativeReplicaState authState = (AuthoritativeReplicaState) method.getArgs()[1]; + final ReplicaStatus localState = (ReplicaStatus) method.getArgs()[2]; + final FileCredentials credentials = (FileCredentials) method.getArgs()[3]; + final XLocations loc = (XLocations) method.getArgs()[4]; + + ReplicatedFileState state = getState(credentials, loc, true, false); + + // Cancel the Request if the file has been invalidated. + if (state.isInvalidated()) { + Logging.logMessage(Logging.LEVEL_INFO, Category.replication, this, + "(R:%s) auth state ignored, file is invalidated %s", localID, fileId); + return; + } + + switch (state.getState()) { + case INITIALIZING: + case OPEN: + case WAITING_FOR_LEASE: { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) enqueued backup reset for file %s", localID, fileId); + state.addPendingRequest(method); + break; + } + case BACKUP: { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) backup reset triggered by AUTHSTATE request for file %s", localID, fileId); + state.setState(ReplicaState.RESET); + executeSetAuthState(localState, authState, state, fileId); + break; + } + case RESET: + default: { + // Ignore. + Logging.logMessage(Logging.LEVEL_WARN, Category.replication, this, + "(R:%s) auth state ignored, already in reset for file %s", localID, fileId); + } + } + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + private void processSetAuthoritativeState(StageRequest method) { + try { + final String fileId = (String) method.getArgs()[0]; + final AuthoritativeReplicaState authState = (AuthoritativeReplicaState) method.getArgs()[1]; + final ReplicaStatus localState = (ReplicaStatus) method.getArgs()[2]; + final ErrorResponse error = (ErrorResponse) method.getArgs()[3]; + + ReplicatedFileState state = files.get(fileId); + if (state == null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.replication, this, + "(R:%s) set AUTH for unknown file: %s", localID, fileId); + return; + } + + if (error != null) { + failed(state, error, "processSetAuthoritativeState"); + } else { + executeSetAuthState(localState, authState, state, fileId); + } + + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + private void processDeleteObjectsComplete(StageRequest method) { + try { + final String fileId = (String) method.getArgs()[0]; + final ErrorResponse error = (ErrorResponse) method.getArgs()[1]; + + ReplicatedFileState state = files.get(fileId); + if (state != null) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) deleted all objects requested by RESET for %s with %s", localID, state.getFileId(), + ErrorUtils.formatError(error)); + } + if (error != null) { + failed(state, error, "processDeleteObjectsComplete"); + } else { + fetchObjects(); + } + } + + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + private void fetchObjects() { + + while (numObjsInFlight < MAX_OBJS_IN_FLIGHT) { + + ReplicatedFileState file = filesInReset.poll(); + if (file == null) + break; + + if (!file.getObjectsToFetch().isEmpty()) { + ObjectVersionMapping o = file.getObjectsToFetch().remove(0); + file.setNumObjectsPending(file.getNumObjectsPending() + 1); + numObjsInFlight++; + fetchObject(file.getFileId(), o); + } + + if (!file.getObjectsToFetch().isEmpty()) { + filesInReset.add(file); + } + } + } + + private void fetchObject(final String fileId, final ObjectVersionMapping record) { + ReplicatedFileState state = files.get(fileId); + if (state == null) { + return; + } + + try { + final ServiceUUID osd = new ServiceUUID(record.getOsdUuidsList().get(0)); + // fetch that object + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) file %s, fetch object %d (version %d) from %s", localID, fileId, + record.getObjectNumber(), record.getObjectVersion(), osd); + + RPCResponse r = osdClient.xtreemfs_rwr_fetch(osd.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, state.getCredentials(), fileId, record.getObjectNumber(), + record.getObjectVersion()); + r.registerListener(new RPCResponseAvailableListener() { + + @Override + public void responseAvailable(RPCResponse r) { + try { + ObjectData metadata = (ObjectData) r.get(); + InternalObjectData data = new InternalObjectData(metadata, r.getData()); + eventObjectFetched(fileId, record, data, null); + } catch (PBRPCException ex) { + // Transform exception into correct ErrorResponse. + // TODO(mberlin): Generalize this functionality by returning "Throwable" instead of + // "ErrorResponse" to the event* functions. + // The "ErrorResponse" shall be created in the last 'step' at the + // invocation of failed(). + eventObjectFetched(fileId, + record, + null, + ErrorUtils.getErrorResponse(ex.getErrorType(), ex.getPOSIXErrno(), ex.toString(), ex)); + } catch (Exception ex) { + eventObjectFetched(fileId, + record, + null, + ErrorUtils.getErrorResponse(ErrorType.IO_ERROR, POSIXErrno.POSIX_ERROR_NONE, ex.toString(), ex)); + } finally { + r.freeBuffers(); + } + } + }); + } catch (IOException ex) { + eventObjectFetched(fileId, record, null, ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, ex.toString(), ex)); + } + + } + + private void processObjectFetched(StageRequest method) { + try { + final String fileId = (String) method.getArgs()[0]; + final ObjectVersionMapping record = (ObjectVersionMapping) method.getArgs()[1]; + final InternalObjectData data = (InternalObjectData) method.getArgs()[2]; + final ErrorResponse error = (ErrorResponse) method.getArgs()[3]; + + ReplicatedFileState state = files.get(fileId); + if (state != null) { + + if (error != null) { + numObjsInFlight--; + fetchObjects(); + + failed(state, error, "processObjectFetched"); + } else if (data.getData() == null) { + // data is null if object was deleted meanwhile. + numObjsInFlight--; + fetchObjects(); + + ErrorResponse generatedError = ErrorResponse + .newBuilder() + .setErrorType(RPC.ErrorType.INTERNAL_SERVER_ERROR) + .setErrorMessage("Fetching a missing object failed because no data was returned. The object was probably deleted meanwhile.") + .build(); + failed(state, generatedError, "processObjectFetched"); + } else { + final int bytes = data.getData().remaining(); + master.getStorageStage().writeObjectWithoutGMax(fileId, record.getObjectNumber(), + state.getsPolicy(), 0, data.getData(), CowPolicy.PolicyNoCow, null, false, + record.getObjectVersion(), null, new WriteObjectCallback() { + + @Override + public void writeComplete(OSDWriteResponse result, ErrorResponse error) { + if (error != null) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this, + "cannot write object locally: %s", ErrorUtils.formatError(error)); + } + } + }); + master.getPreprocStage().pingFile(fileId); + master.objectReplicated(); + master.replicatedDataReceived(bytes); + + numObjsInFlight--; + final int numPendingFile = state.getNumObjectsPending() - 1; + state.setNumObjectsPending(numPendingFile); + state.getPolicy().objectFetched(record.getObjectVersion()); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) fetched object for replica, file %s, remaining %d", localID, fileId, + numPendingFile); + fetchObjects(); + if (numPendingFile == 0) { + // reset complete! + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) RESET complete for file %s", localID, fileId); + doOpen(state); + } + } + } + + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + private void doReset(final ReplicatedFileState file, long updateObjVer) { + + if (file.getState() == ReplicaState.RESET) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "file %s is already in RESET", + file.getFileId()); + return; + } + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) replica state changed for %s from %s to %s", localID, file.getFileId(), file.getState(), + ReplicaState.RESET); + } + file.setState(ReplicaState.RESET); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) replica RESET started: %s (update objVer=%d)", localID, file.getFileId(), updateObjVer); + } + + OSDOperation op = master.getInternalEvent(EventRWRStatus.class); + op.startInternalEvent(new Object[] { file.getFileId(), file.getsPolicy() }); + + } + + private void processReplicaStateAvailExecReset(StageRequest method) { + try { + final String fileId = (String) method.getArgs()[0]; + final ReplicaStatus localReplicaState = (ReplicaStatus) method.getArgs()[1]; + final ErrorResponse error = (ErrorResponse) method.getArgs()[2]; + + final ReplicatedFileState state = files.get(fileId); + if (state != null) { + if (error != null) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this, + "local state for %s failed: %s", state.getFileId(), error); + failed(state, error, "processReplicaStateAvailExecReset"); + } else { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) local state for %s available.", localID, state.getFileId()); + } + state.getPolicy().executeReset(state.getCredentials(), localReplicaState, + new ReplicaUpdatePolicy.ExecuteResetCallback() { + + @Override + public void finished(AuthoritativeReplicaState authState) { + eventSetAuthState(state.getFileId(), authState, localReplicaState, null); + } + + @Override + public void failed(ErrorResponse error) { + eventSetAuthState(state.getFileId(), null, null, error); + } + }); + } + } + + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + private void processForceReset(StageRequest method) { + try { + final FileCredentials credentials = (FileCredentials) method.getArgs()[0]; + final XLocations loc = (XLocations) method.getArgs()[1]; + + ReplicatedFileState state = getState(credentials, loc, true, false); + if (!state.isForceReset()) { + state.setForceReset(true); + } + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + private void doWaitingForLease(final ReplicatedFileState file) { + // If the file is invalidated a XLocSetChange is in progress and we can assume, that no primary exists. + if (file.isInvalidated()) { + doInvalidated(file); + } else if (file.getPolicy().requiresLease()) { + if (file.isCellOpen()) { + if (file.isLocalIsPrimary()) { + doPrimary(file); + } else { + doBackup(file); + } + } else { + file.setCellOpen(true); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) replica state changed for %s from %s to %s", localID, file.getFileId(), + file.getState(), ReplicaState.WAITING_FOR_LEASE); + } + try { + file.setState(ReplicaState.WAITING_FOR_LEASE); + List osdAddresses = new ArrayList(); + for (ServiceUUID osd : file.getPolicy().getRemoteOSDUUIDs()) { + osdAddresses.add(osd.getAddress()); + } + + // it is save to use the version from the XLoc, because outdated or invalidated requests + // will be filtered in the preprocStage if the Operation requires a valid view + int viewId = file.getLocations().getVersion(); + + fstage.openCell(file.getPolicy().getCellId(), osdAddresses, true, viewId); + // wait for lease... + } catch (UnknownUUIDException ex) { + failed(file, + ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, ex.toString(), ex), + "doWaitingForLease"); + } + } + + } else { + // become primary immediately + doPrimary(file); + } + } + + private void doOpen(final ReplicatedFileState file) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "(R:%s) replica state changed for %s from %s to %s", localID, + file.getFileId(), file.getState(), ReplicaState.OPEN); + } + file.setState(ReplicaState.OPEN); + if (file.hasPendingRequests()) { + doWaitingForLease(file); + } + } + + private void doPrimary(final ReplicatedFileState file) { + assert (file.isLocalIsPrimary()); + try { + if (file.getPolicy().onPrimary((int) file.getMasterEpoch()) && !file.isPrimaryReset()) { + file.setPrimaryReset(true); + doReset(file, ReplicaUpdatePolicy.UNLIMITED_RESET); + } else { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) replica state changed for %s from %s to %s", localID, file.getFileId(), + file.getState(), ReplicaState.PRIMARY); + } + file.setPrimaryReset(false); + file.setState(ReplicaState.PRIMARY); + while (file.hasPendingRequests()) { + enqueuePrioritized(file.removePendingRequest()); + } + } + } catch (IOException ex) { + failed(file, ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, ex.toString(), ex), + "doPrimary"); + } + } + + private void doBackup(final ReplicatedFileState file) { + assert (!file.isLocalIsPrimary()); + //try { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) replica state changed for %s from %s to %s", localID, file.getFileId(), file.getState(), + ReplicaState.BACKUP); + } + file.setPrimaryReset(false); + file.setState(ReplicaState.BACKUP); + while (file.hasPendingRequests()) { + enqueuePrioritized(file.removePendingRequest()); + } + /*} catch (IOException ex) { + failed(file, ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, ex.toString(), ex)); + }*/ + } + + private void doInvalidated(final ReplicatedFileState file) { + assert (file.isInvalidated()); + + + if (file.isInvalidatedReset()) { + // The AuthState has been set and the file is up to date. + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) replica state changed for %s from %s to %s", localID, file.getFileId(), + file.getState(), ReplicaState.INVALIDATED); + } + + file.setInvalidatedReset(false); + file.setState(ReplicaState.INVALIDATED); + } + file.setPrimaryReset(false); + while (file.hasPendingRequests()) { + enqueuePrioritized(file.removePendingRequest()); + } + } + + private void failed(ReplicatedFileState file, ErrorResponse ex, String methodName) { + Logging.logMessage(Logging.LEVEL_WARN, Category.replication, this, + "(R:%s) replica for file %s failed (in method: %s): %s", localID, file.getFileId(), methodName, + ErrorUtils.formatError(ex)); + file.setPrimaryReset(false); + file.setState(ReplicaState.OPEN); + file.setCellOpen(false); + fstage.closeCell(file.getPolicy().getCellId(), false); + file.clearPendingRequests(ex); + } + + private void enqueuePrioritized(StageRequest rq) { + while (!q.offer(rq)) { + StageRequest otherRq = q.poll(); + otherRq.sendInternalServerError(new IllegalStateException( + "internal queue overflow, cannot enqueue operation for processing.")); + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Dropping request from rwre queue due to overload"); + } + } + + + public static interface RWReplicationCallback { + public void success(long newObjectVersion); + public void redirect(String redirectTo); + public void failed(ErrorResponse ex); + } + + /*public void openFile(FileCredentials credentials, XLocations locations, boolean forceReset, + RWReplicationCallback callback, OSDRequest request) { + this.enqueueOperation(STAGEOP_OPEN, new Object[]{credentials,locations,forceReset}, request, callback); + }*/ + + protected void enqueueExternalOperation(int stageOp, Object[] arguments, OSDRequest request, + ReusableBuffer createdViewBuffer, Object callback) { + if (externalRequestsInQueue.get() >= MAX_EXTERNAL_REQUESTS_IN_Q) { + Logging.logMessage(Logging.LEVEL_WARN, this, + "RW replication stage is overloaded, request %d for %s dropped", request.getRequestId(), + request.getFileId()); + request.sendInternalServerError(new IllegalStateException( + "RW replication stage is overloaded, request dropped")); + + // Make sure that the data buffer is returned to the pool if + // necessary, as some operations create view buffers on the + // data. Otherwise, a 'finalized but not freed before' warning + // may occur. + if (createdViewBuffer != null) { + assert (createdViewBuffer.getRefCount() >= 2); + BufferPool.free(createdViewBuffer); + } + + } else { + externalRequestsInQueue.incrementAndGet(); + this.enqueueOperation(stageOp, arguments, request, createdViewBuffer, callback); + } + } + + public void prepareOperation(FileCredentials credentials, XLocations xloc, long objNo, long objVersion, + Operation op, RWReplicationCallback callback, OSDRequest request) { + this.enqueueExternalOperation(STAGEOP_PREPAREOP, new Object[] { credentials, xloc, objNo, objVersion, op }, + request, null, callback); + } + + public void replicatedWrite(FileCredentials credentials, XLocations xloc, long objNo, long objVersion, + InternalObjectData data, ReusableBuffer createdViewBuffer, RWReplicationCallback callback, + OSDRequest request) { + this.enqueueExternalOperation(STAGEOP_REPLICATED_WRITE, new Object[] { credentials, xloc, objNo, objVersion, + data }, request, createdViewBuffer, callback); + } + + public void replicateTruncate(FileCredentials credentials, XLocations xloc, long newFileSize, + long newObjectVersion, RWReplicationCallback callback, OSDRequest request) { + this.enqueueExternalOperation(STAGEOP_TRUNCATE, + new Object[] { credentials, xloc, newFileSize, newObjectVersion }, request, null, callback); + } + + public void fileClosed(String fileId) { + this.enqueueOperation(STAGEOP_CLOSE, new Object[] { fileId }, null, null); + } + + public void receiveFleaseMessage(ReusableBuffer message, InetSocketAddress sender) { + // this.enqueueOperation(STAGEOP_PROCESS_FLEASE_MSG, new Object[]{message,sender}, null, null); + try { + FleaseMessage msg = new FleaseMessage(message); + BufferPool.free(message); + msg.setSender(sender); + fstage.receiveMessage(msg); + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + public void getStatus(StatusCallback callback) { + this.enqueueOperation(STAGEOP_GETSTATUS, new Object[] {}, null, callback); + } + + public static interface StatusCallback { + public void statusComplete(Map> status); + } + + @Override + public void sendMessage(FleaseMessage message, InetSocketAddress recipient) { + ReusableBuffer data = BufferPool.allocate(message.getSize()); + message.serialize(data); + data.flip(); + try { + RPCResponse r = fleaseOsdClient.xtreemfs_rwr_flease_msg(recipient, RPCAuthentication.authNone, + RPCAuthentication.userService, master.getHostName(), master.getConfig().getPort(), data); + r.registerListener(new RPCResponseAvailableListener() { + + @Override + public void responseAvailable(RPCResponse r) { + r.freeBuffers(); + } + }); + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + @Override + protected void processMethod(StageRequest method) { + switch (method.getStageMethod()) { + case STAGEOP_REPLICATED_WRITE: { + externalRequestsInQueue.decrementAndGet(); + processReplicatedWrite(method); + break; + } + case STAGEOP_TRUNCATE: { + externalRequestsInQueue.decrementAndGet(); + processReplicatedTruncate(method); + break; + } + case STAGEOP_CLOSE: processFileClosed(method); break; + case STAGEOP_PROCESS_FLEASE_MSG: processFleaseMessage(method); break; + case STAGEOP_PREPAREOP: { + externalRequestsInQueue.decrementAndGet(); + processPrepareOp(method); + break; + } + case STAGEOP_INTERNAL_AUTHSTATE: processSetAuthoritativeState(method); break; + case STAGEOP_LEASE_STATE_CHANGED: processLeaseStateChanged(method); break; + case STAGEOP_INTERNAL_OBJFETCHED: processObjectFetched(method); break; + case STAGEOP_INTERNAL_STATEAVAIL: processReplicaStateAvailExecReset(method); break; + case STAGEOP_INTERNAL_DELETE_COMPLETE: processDeleteObjectsComplete(method); break; + case STAGEOP_INTERNAL_MAXOBJ_AVAIL: processMaxObjAvail(method); break; + case STAGEOP_INTERNAL_BACKUP_AUTHSTATE: processBackupAuthoritativeState(method); break; + case STAGEOP_FORCE_RESET: processForceReset(method); break; + case STAGEOP_GETSTATUS: processGetStatus(method); break; + case STAGEOP_SETVIEW: processSetFleaseView(method); break; + case STAGEOP_INVALIDATEVIEW: processInvalidateReplica(method); break; + case STAGEOP_FETCHINVALIDATED: processFetchInvalidated(method); break; + default : throw new IllegalArgumentException("no such stageop"); + } + } + + private void processFleaseMessage(StageRequest method) { + try { + final ReusableBuffer data = (ReusableBuffer) method.getArgs()[0]; + final InetSocketAddress sender = (InetSocketAddress) method.getArgs()[1]; + + FleaseMessage msg = new FleaseMessage(data); + BufferPool.free(data); + msg.setSender(sender); + fstage.receiveMessage(msg); + + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + private void processFileClosed(StageRequest method) { + try { + final String fileId = (String) method.getArgs()[0]; + closeFileState(fileId, false); + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + private void closeFileState(String fileId, boolean returnLease) { + ReplicatedFileState state = files.remove(fileId); + if (state != null) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "closing file %s", fileId); + } + state.getPolicy().closeFile(); + if (state.getPolicy().requiresLease()) + fstage.closeCell(state.getPolicy().getCellId(), returnLease); + cellToFileId.remove(state.getPolicy().getCellId()); + } + } + + private ReplicatedFileState getState(FileCredentials credentials, XLocations loc, boolean forceReset, + boolean invalidated) throws IOException { + + final String fileId = credentials.getXcap().getFileId(); + + ReplicatedFileState state = files.get(fileId); + if (state == null) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "open file: " + fileId); + // "open" file + state = new ReplicatedFileState(fileId, loc, master.getConfig().getUUID(), fstage, osdClient); + files.put(fileId, state); + state.setCredentials(credentials); + state.setForceReset(forceReset); + state.setInvalidated(invalidated); + cellToFileId.put(state.getPolicy().getCellId(), fileId); + assert (state.getState() == ReplicaState.INITIALIZING); + + master.getStorageStage().internalGetMaxObjectNo(fileId, loc.getLocalReplica().getStripingPolicy(), + new InternalGetMaxObjectNoCallback() { + + @Override + public void maxObjectNoCompleted(long maxObjNo, long fileSize, long truncateEpoch, + ErrorResponse error) { + eventMaxObjAvail(fileId, maxObjNo, fileSize, truncateEpoch, error); + } + }); + } + return state; + } + + private void processMaxObjAvail(StageRequest method) { + try { + final String fileId = (String) method.getArgs()[0]; + final Long maxObjVersion = (Long) method.getArgs()[1]; + final ErrorResponse error = (ErrorResponse) method.getArgs()[2]; + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "(R:%s) max obj avail for file: " + + fileId + " max=" + maxObjVersion, localID); + + ReplicatedFileState state = files.get(fileId); + if (state == null) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this, + "received maxObjAvail event for unknow file: %s", fileId); + return; + } + + if (state.getState() == ReplicaState.INITIALIZING) { + state.getPolicy().setLocalObjectVersion(maxObjVersion); + doOpen(state); + } else { + Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this, + "ReplicaState is %s instead of INITIALIZING, maxObjectVersion=%d", state.getState().name(), + maxObjVersion); + return; + } + + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + private void processReplicatedWrite(StageRequest method) { + final RWReplicationCallback callback = (RWReplicationCallback) method.getCallback(); + try { + final FileCredentials credentials = (FileCredentials) method.getArgs()[0]; + final XLocations loc = (XLocations) method.getArgs()[1]; + final Long objNo = (Long) method.getArgs()[2]; + final Long objVersion = (Long) method.getArgs()[3]; + final InternalObjectData objData = (InternalObjectData) method.getArgs()[4]; + + final String fileId = credentials.getXcap().getFileId(); + + ReplicatedFileState state = files.get(fileId); + if (state == null) { + BufferPool.free(objData.getData()); + callback.failed(ErrorUtils.getErrorResponse(ErrorType.INTERNAL_SERVER_ERROR, + POSIXErrno.POSIX_ERROR_EIO, "file is not open!")); + return; + } + state.setCredentials(credentials); + + state.getPolicy().executeWrite(credentials, objNo, objVersion, objData, + new ReplicaUpdatePolicy.ClientOperationCallback() { + + @Override + public void finished() { + callback.success(objVersion); + } + + @Override + public void failed(ErrorResponse error) { + callback.failed(error); + } + }); + + } catch (Exception ex) { + ex.printStackTrace(); + callback.failed(ErrorUtils.getInternalServerError(ex)); + } + } + + private void processReplicatedTruncate(StageRequest method) { + final RWReplicationCallback callback = (RWReplicationCallback) method.getCallback(); + try { + final FileCredentials credentials = (FileCredentials) method.getArgs()[0]; + final XLocations loc = (XLocations) method.getArgs()[1]; + final Long newFileSize = (Long) method.getArgs()[2]; + final Long newObjVersion = (Long) method.getArgs()[3]; + + final String fileId = credentials.getXcap().getFileId(); + + ReplicatedFileState state = files.get(fileId); + if (state == null) { + callback.failed(ErrorUtils.getErrorResponse(ErrorType.INTERNAL_SERVER_ERROR, + POSIXErrno.POSIX_ERROR_EIO, "file is not open!")); + return; + } + state.setCredentials(credentials); + + state.getPolicy().executeTruncate(credentials, newFileSize, newObjVersion, + new ReplicaUpdatePolicy.ClientOperationCallback() { + + @Override + public void finished() { + callback.success(newObjVersion); + } + + @Override + public void failed(ErrorResponse error) { + callback.failed(error); + } + }); + + } catch (Exception ex) { + ex.printStackTrace(); + callback.failed(ErrorUtils.getInternalServerError(ex)); + } + } + + private void processPrepareOp(StageRequest method) { + final RWReplicationCallback callback = (RWReplicationCallback) method.getCallback(); + try { + final FileCredentials credentials = (FileCredentials) method.getArgs()[0]; + final XLocations loc = (XLocations) method.getArgs()[1]; + final Long objVersion = (Long) method.getArgs()[3]; + final Operation op = (Operation) method.getArgs()[4]; + + final String fileId = credentials.getXcap().getFileId(); + + ReplicatedFileState state = getState(credentials, loc, false, false); + + // Abort the request if the file has been invalidated. + if (state.isInvalidated()) { + callback.failed(ErrorUtils.getErrorResponse(ErrorType.INTERNAL_SERVER_ERROR, + POSIXErrno.POSIX_ERROR_NONE, "file has been invalidated")); + return; + } + + if ((op == Operation.INTERNAL_UPDATE) || (op == Operation.INTERNAL_TRUNCATE)) { + switch (state.getState()) { + case WAITING_FOR_LEASE: + case INITIALIZING: + case RESET: + case OPEN: { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "enqeue update for %s (state is %s)", fileId, state.getState()); + } + if (state.sizeOfPendingRequests() > MAX_PENDING_PER_FILE) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, + "rejecting request: too many requests (is: %d, max %d) in queue for file %s", + state.sizeOfPendingRequests(), MAX_PENDING_PER_FILE, fileId); + } + callback.failed(ErrorUtils.getErrorResponse(ErrorType.INTERNAL_SERVER_ERROR, + POSIXErrno.POSIX_ERROR_NONE, "too many requests in queue for file")); + return; + } else { + state.addPendingRequest(method); + } + if (state.getState() == ReplicaState.OPEN) { + // immediately change to backup mode...no need to check the lease + doWaitingForLease(state); + } + return; + } + } + if (!state.getPolicy().acceptRemoteUpdate(objVersion)) { + Logging.logMessage(Logging.LEVEL_WARN, Category.replication, this, + "received outdated object version %d for file %s", objVersion, fileId); + callback.failed(ErrorUtils.getErrorResponse(ErrorType.IO_ERROR, POSIXErrno.POSIX_ERROR_EIO, + "outdated object version for update rejected")); + return; + } + boolean needsReset = state.getPolicy().onRemoteUpdate(objVersion, state.getState()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, "%s needs reset: %s", fileId, + needsReset); + } + if (needsReset) { + state.addPendingRequest(method); + doReset(state, objVersion); + } else { + callback.success(0); + } + } else { + state.setCredentials(credentials); + + switch (state.getState()) { + case WAITING_FOR_LEASE: + case INITIALIZING: + case RESET: { + if (state.sizeOfPendingRequests() > MAX_PENDING_PER_FILE) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, + "rejecting request: too many requests (is: %d, max %d) in queue for file %s", + state.sizeOfPendingRequests(), MAX_PENDING_PER_FILE, fileId); + } + callback.failed(ErrorUtils.getErrorResponse(ErrorType.INTERNAL_SERVER_ERROR, + POSIXErrno.POSIX_ERROR_NONE, "too many requests in queue for file")); + } else { + state.addPendingRequest(method); + } + return; + } + case OPEN: { + if (state.sizeOfPendingRequests() > MAX_PENDING_PER_FILE) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, + "rejecting request: too many requests (is: %d, max %d) in queue for file %s", + state.sizeOfPendingRequests(), MAX_PENDING_PER_FILE, fileId); + } + callback.failed(ErrorUtils.getErrorResponse(ErrorType.INTERNAL_SERVER_ERROR, + POSIXErrno.POSIX_ERROR_NONE, "too many requests in queue for file")); + return; + } else { + state.addPendingRequest(method); + } + doWaitingForLease(state); + return; + } + } + + try { + long newVersion = state.getPolicy().onClientOperation(op, objVersion, state.getState(), + state.getLease()); + callback.success(newVersion); + } catch (RedirectToMasterException ex) { + callback.redirect(ex.getMasterUUID()); + } catch (RetryException ex) { + final ErrorResponse err = ErrorUtils.getInternalServerError(ex); + failed(state, err, "processPrepareOp"); + if (state.getState() == ReplicaState.BACKUP || state.getState() == ReplicaState.PRIMARY) { + // Request is not in queue, we must notify + // callback. + callback.failed(err); + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + callback.failed(ErrorUtils.getInternalServerError(ex)); + } + } + + private void processGetStatus(StageRequest method) { + final StatusCallback callback = (StatusCallback) method.getCallback(); + try { + Map> status = new HashMap(); + + Map fleaseState = fstage.getLocalState(); + + for (String fileId : this.files.keySet()) { + Map fStatus = new HashMap(); + final ReplicatedFileState fState = files.get(fileId); + final ASCIIString cellId = fState.getPolicy().getCellId(); + fStatus.put("policy", fState.getPolicy().getClass().getSimpleName()); + fStatus.put("peers (OSDs)", fState.getPolicy().getRemoteOSDUUIDs().toString()); + fStatus.put("pending requests", String.valueOf(fState.sizeOfPendingRequests())); + fStatus.put("cellId", cellId.toString()); + String primary = "unknown"; + if ((fState.getLease() != null) && (!fState.getLease().isEmptyLease())) { + if (fState.getLease().isValid()) { + if (fState.isLocalIsPrimary()) { + primary = "primary"; + } else { + primary = "backup ( primary is " + fState.getLease().getLeaseHolder() + ")"; + } + } else { + primary = "outdated lease: " + fState.getLease().getLeaseHolder(); + } + } + fStatus.put("role", primary); + status.put(fileId, fStatus); + } + callback.statusComplete(status); + } catch (Exception ex) { + ex.printStackTrace(); + callback.statusComplete(null); + } + } + + public String getPrimary(final String fileId) { + String primary = null; + + final ReplicatedFileState fState = files.get(fileId); + + if ((fState != null) && (fState.getLease() != null) && (!fState.getLease().isEmptyLease())) { + if (fState.getLease().isValid()) { + primary = "" + fState.getLease().getLeaseHolder(); + } else { + // outdated lease + } + } + return primary; + } + + /** + * Set the viewId associated with the fileId/cellId. This will close open cells. + * + * @param fileId + * @param cellId + * @param versionState + */ + public void setFleaseView(String fileId, ASCIIString cellId, XLocSetVersionState versionState) { + enqueueOperation(STAGEOP_SETVIEW, new Object[] { fileId, cellId, versionState }, null, null); + } + + private void processSetFleaseView(StageRequest method) { + final Object[] args = method.getArgs(); + final String fileId = (String) args[0]; + final ASCIIString cellId = (ASCIIString) args[1]; + final XLocSetVersionState versionState = (XLocSetVersionState) args[2]; + + int viewId; + if (versionState.getInvalidated()) { + viewId = FleaseMessage.VIEW_ID_INVALIDATED; + } else { + viewId = versionState.getVersion(); + } + + // Close ReplicatedFileState opened in a previous view to ensure no outdated UUIDList can exist. + ReplicatedFileState state = files.get(fileId); + if (state != null && state.getLocations().getVersion() < versionState.getVersion()) { + closeFileState(fileId, true); + } + + fstage.setViewId(cellId, viewId, new FleaseListener() { + + @Override + public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, + long masterEpochNumber) { + // Ignore because #setFleaseView is never used with a callback. + } + + @Override + public void proposalFailed(ASCIIString cellId, Throwable cause) { + // Ignore because proposalFailed will never be called in #setViewId + } + }); + } + + /** + * Invalidate the replica and the corresponding flease view.
    + * If this Replica is the primary it will ensure the lease is given back. + * + * @param fileId + * to close. + * @param fileCredentials + * used to call {@link #getState(FileCredentials, XLocations, boolean, boolean)}. + * @param xLocations + * used to call {@link #getState(FileCredentials, XLocations, boolean, boolean)}. + * @param callback + * to execute after the view has been invalidated. + */ + public void invalidateReplica(String fileId, FileCredentials fileCreds, XLocations xLoc, + InvalidateXLocSetCallback callback) { + enqueueOperation(STAGEOP_INVALIDATEVIEW, new Object[] { fileId, fileCreds, xLoc }, null, callback); + } + + private void processInvalidateReplica(StageRequest method) { + final Object[] args = method.getArgs(); + final String fileId = (String) args[0]; + final FileCredentials fileCreds = (FileCredentials) args[1]; + final XLocations xLoc = (XLocations) args[2]; + final InvalidateXLocSetCallback callback = (InvalidateXLocSetCallback) method.getCallback(); + + + // Set the fileState to invalidated (or open the file invalidated). + ReplicatedFileState state; + try { + state = getState(fileCreds, xLoc, true, true); + state.setInvalidated(true); + assert (state.isInvalidated()); + + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + callback.invalidateComplete(LeaseState.NONE, ErrorUtils.getInternalServerError(ex)); + return; + } + + // Check the replicas lease state. + final LeaseState leaseState; + if (state.isCellOpen()) { + if (state.isLocalIsPrimary()) { + leaseState = LeaseState.PRIMARY; + } else { + leaseState = LeaseState.BACKUP; + } + } else { + leaseState = LeaseState.IDLE; + } + + // Close the flease cell and return the lease if possible. + fstage.closeCell(state.getPolicy().getCellId(), true); + cellToFileId.remove(state.getPolicy().getCellId()); + + // Clear pending requests. This ensures the ReplicaState won't change from now on. + if (state.hasPendingRequests()) { + ErrorResponse er = ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, + "File got invalidated!"); + state.clearPendingRequests(er); + } + + // Transfer the view to flease. + fstage.setViewId(state.getPolicy().getCellId(), FleaseMessage.VIEW_ID_INVALIDATED, new FleaseListener() { + + @Override + public void proposalResult(ASCIIString cellId, ASCIIString leaseHolder, long leaseTimeout_ms, + long masterEpochNumber) { + callback.invalidateComplete(leaseState, null); + } + + @Override + public void proposalFailed(ASCIIString cellId, Throwable cause) { + callback.invalidateComplete(leaseState, ErrorUtils.getInternalServerError(cause)); + } + }); + + } + + public void fetchInvalidated(String fileId, AuthoritativeReplicaState authState, ReplicaStatus localState, + FileCredentials credentials, XLocations xloc, RWReplicationCallback callback, OSDRequest request) { + this.enqueueOperation(STAGEOP_FETCHINVALIDATED, + new Object[] { fileId, authState, localState, credentials, xloc }, request, null, callback); + } + + private void processFetchInvalidated(StageRequest method) { + final RWReplicationCallback callback = (RWReplicationCallback) method.getCallback(); + try { + final String fileId = (String) method.getArgs()[0]; + final AuthoritativeReplicaState authState = (AuthoritativeReplicaState) method.getArgs()[1]; + final ReplicaStatus localState = (ReplicaStatus) method.getArgs()[2]; + final FileCredentials credentials = (FileCredentials) method.getArgs()[3]; + final XLocations loc = (XLocations) method.getArgs()[4]; + + // Set the fileState to invalidated (or open the file invalidated). + ReplicatedFileState state = getState(credentials, loc, true, true); + state.setInvalidated(true); + + assert (state.isInvalidated()); + + // There should exist no pending requests, because they were cleaned when the replica got invalidated and + // subsequent requests are denied. + if (state.hasPendingRequests()) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.replication, this, + "(R:%s) pending requests were queued while the replica for %s has been invalidated.", localID, + fileId); + } + + switch (state.getState()) { + case RESET: + // Wait until this reset is done. Since fileState.isInvalidated() is true this will result in an OPEN + // state. + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) enqueued fetch invalidated reset for file %s", localID, fileId); + state.addPendingRequest(method); + break; + + case INITIALIZING: + // Wait until the initializing is done. Since fileState.isInvalidated() this will result in an OPEN + // state. + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this, + "(R:%s) enqueued fetch invalidated reset for file %s", localID, fileId); + state.addPendingRequest(method); + break; + + case OPEN: + case WAITING_FOR_LEASE: + case BACKUP: + case PRIMARY: + // At this point it is ensured, that no other Request is queued. Therefore the AuthState can be set + // regardless of the state. + state.setInvalidatedReset(true); + state.addPendingRequest(method); + executeSetAuthState(localState, authState, state, fileId); + break; + + case INVALIDATED: + // The AuthState has been set and the Replica is up to date. + + // Close the file by clearing the state. + closeFileState(fileId, true); + + // Finish the request. + callback.success(0); + break; + } + + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + callback.failed(ErrorUtils.getInternalServerError(ex)); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/rwre/RedirectToMasterException.java b/java/servers/src/org/xtreemfs/osd/rwre/RedirectToMasterException.java new file mode 100644 index 0000000..278ac82 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/rwre/RedirectToMasterException.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.rwre; + +/** + * + * @author bjko + */ +public class RedirectToMasterException extends Exception { + + final String masterUUID; + + public RedirectToMasterException(String masterUUID) { + super(); + this.masterUUID = masterUUID; + } + + public String getMasterUUID() { + return masterUUID; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/rwre/ReplicaUpdatePolicy.java b/java/servers/src/org/xtreemfs/osd/rwre/ReplicaUpdatePolicy.java new file mode 100644 index 0000000..ee7be49 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/rwre/ReplicaUpdatePolicy.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2010-2012 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.rwre; + +import java.io.IOException; +import java.util.List; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.flease.Flease; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.rwre.RWReplicationStage.Operation; +import org.xtreemfs.osd.rwre.ReplicatedFileState.ReplicaState; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * + * @author bjko + */ +public abstract class ReplicaUpdatePolicy { + + public static final long UNLIMITED_RESET = -1; + + public static final String FILE_CELLID_PREFIX = "/file/"; + + protected List remoteOSDUUIDs; + + protected final ASCIIString cellId; + + protected long localObjVersion; + + protected final String localUUID; + + /** + * Factory for generating policies objects based on their name. + * + * @param replicaUpdatePolicy + * Name of the policy. + * @param remoteOSDUUIDs + * List of UUIDs of remote OSDs. + * @param localUUID + * UUID of the local OSD. + * @param fileId + * ID of the file to be replicated. + * @param client + * OSDServiceClient instance or null. + * @return ReplicaUpdatePolicy + */ + public static ReplicaUpdatePolicy newReplicaUpdatePolicy(String replicaUpdatePolicy, + List remoteOSDUUIDs, String localUUID, String fileId, OSDServiceClient client) { + if (replicaUpdatePolicy.equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE)) { + return new WaR1UpdatePolicy(remoteOSDUUIDs, localUUID, fileId, client); + } else if (replicaUpdatePolicy.equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARA)) { + return new WaRaUpdatePolicy(remoteOSDUUIDs, localUUID, fileId, client); + } else if (replicaUpdatePolicy.equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ)) { + return new WqRqUpdatePolicy(remoteOSDUUIDs, localUUID, fileId, client); + } else { + throw new IllegalArgumentException("unsupported replica update mode: " + replicaUpdatePolicy); + } + } + + protected ReplicaUpdatePolicy(List remoteOSDUUIDs, String fileId, String localUUID) { + this.remoteOSDUUIDs = remoteOSDUUIDs; + this.cellId = fileToCellId(fileId); + this.localUUID = localUUID; + localObjVersion = -1; + } + + public static String cellToFileId(ASCIIString cellId) { + return cellId.toString().substring(FILE_CELLID_PREFIX.length()); + } + + public static ASCIIString fileToCellId(String fileId) { + return new ASCIIString(FILE_CELLID_PREFIX + fileId); + } + + public List getRemoteOSDUUIDs() { + return remoteOSDUUIDs; + } + + public ASCIIString getCellId() { + return cellId; + } + + public void objectFetched(long objVersion) { + if (objVersion > localObjVersion) + localObjVersion = objVersion; + } + + public void setLocalObjectVersion(long localMaxObjVer) { + localObjVersion = localMaxObjVer; + } + + /** + * + * @return true, if this is primary/backup, false if all replicas are + * primary + */ + public abstract boolean requiresLease(); + + /** + * called to execute a reset + * + * @param credentials + * @param maxLocalOV + */ + public abstract void executeReset( + FileCredentials credentials, + ReplicaStatus localReplicaState, + ExecuteResetCallback callback); + + public static interface ExecuteResetCallback { + public void finished(AuthoritativeReplicaState authState); + + public void failed(ErrorResponse error); + } + + /** + * called to execute a client write operation + */ + public abstract void executeWrite( + FileCredentials credentials, + long objNo, + long objVersion, + InternalObjectData data, + ClientOperationCallback callback); + + public abstract void executeTruncate( + FileCredentials credentials, + long newFileSize, + long newObjectVersion, + ClientOperationCallback callback); + + public static interface ClientOperationCallback { + public void finished(); + public void failed(ErrorResponse error); + } + + public abstract long onClientOperation( + Operation operation, + long objVersion, + ReplicaState currentState, + Flease lease) throws RedirectToMasterException, IOException; + + public abstract boolean onRemoteUpdate(long objVersion, ReplicaState currentState) + throws IOException; + + /** + * Checks if a remote update (write, truncate) can be accepted and applied. + * + * @param objVersion + * the version of the remote update. + * @return true, if the update can be accepted, false if it must be ignored. + */ + public abstract boolean acceptRemoteUpdate(long objVersion) throws IOException; + + /** + * @return true, if the policy needs to reset the replica + * @param masterEpoch + * @throws IOException + */ + public abstract boolean onPrimary(int masterEpoch) throws IOException; + + /** + * + * @return true, if the policy needs to reset the replica + * @throws IOException + */ + public abstract boolean onBackup() throws IOException; + + public abstract void onFailed() throws IOException; + + public abstract void closeFile(); +} diff --git a/java/servers/src/org/xtreemfs/osd/rwre/ReplicatedFileState.java b/java/servers/src/org/xtreemfs/osd/rwre/ReplicatedFileState.java new file mode 100644 index 0000000..3787cce --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/rwre/ReplicatedFileState.java @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.rwre; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.common.xloc.Replica; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.flease.Flease; +import org.xtreemfs.foundation.flease.FleaseStage; +import org.xtreemfs.foundation.flease.comm.FleaseMessage; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.rwre.RWReplicationStage.RWReplicationCallback; +import org.xtreemfs.osd.stages.Stage.StageRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * + * @author bjko + */ +public class ReplicatedFileState { + + public enum ReplicaState { + INITIALIZING, + OPEN, + RESET, + WAITING_FOR_LEASE, + BACKUP, + PRIMARY, + INVALIDATED + }; + + private final AtomicInteger queuedData; + + private List remoteOSDs; + + private ReplicaUpdatePolicy policy; + + private final String fileId; + + private ReplicaState state; + + private List objectsToFetch; + + private List pendingRequests; + + private Flease lease; + + private boolean localIsPrimary; + + private FileCredentials credentials; + + private boolean cellOpen; + + private int numObjectsPending; + + private boolean primaryReset; + + private boolean forceReset; + + private XLocations loc; + + private long masterEpoch; + + private boolean invalidated; + + private boolean invalidatedReset; + + public ReplicatedFileState(String fileId, XLocations locations, ServiceUUID localUUID, FleaseStage fstage, + OSDServiceClient client) throws UnknownUUIDException, IOException { + queuedData = new AtomicInteger(); + pendingRequests = new LinkedList(); + this.fileId = fileId; + this.state = ReplicaState.INITIALIZING; + this.primaryReset = false; + this.loc = locations; + this.lease = Flease.EMPTY_LEASE; + this.forceReset = false; + this.masterEpoch = FleaseMessage.IGNORE_MASTER_EPOCH; + this.invalidated = false; + this.invalidatedReset = false; + + remoteOSDs = new ArrayList(locations.getNumReplicas() - 1); + for (Replica r : locations.getReplicas()) { + final ServiceUUID headOSD = r.getHeadOsd(); + if (headOSD.equals(localUUID)) + continue; + remoteOSDs.add(headOSD); + } + + policy = ReplicaUpdatePolicy.newReplicaUpdatePolicy(locations.getReplicaUpdatePolicy(), remoteOSDs, localUUID.toString(), + fileId, client); + } + + /** + * @return the credentials + */ + public FileCredentials getCredentials() { + return credentials; + } + + /** + * @param credentials the credentials to set + */ + public void setCredentials(FileCredentials credentials) { + this.credentials = credentials; + } + + /** + * @return the fileId + */ + public String getFileId() { + return fileId; + } + + /** + * @return the cellOpen + */ + public boolean isCellOpen() { + return cellOpen; + } + + /** + * @param cellOpen the cellOpen to set + */ + public void setCellOpen(boolean cellOpen) { + this.cellOpen = cellOpen; + } + + /** + * @return the numObjectsPending + */ + public int getNumObjectsPending() { + return numObjectsPending; + } + + /** + * @param numObjectsPending the numObjectsPending to set + */ + public void setNumObjectsPending(int numObjectsPending) { + this.numObjectsPending = numObjectsPending; + } + + /** + * @return the primaryReset + */ + public boolean isPrimaryReset() { + return primaryReset; + } + + /** + * @param primaryReset the primaryReset to set + */ + public void setPrimaryReset(boolean primaryReset) { + this.primaryReset = primaryReset; + } + + /** + * @return the sPolicy + */ + public StripingPolicyImpl getsPolicy() { + return loc.getLocalReplica().getStripingPolicy(); + } + + public Replica getLocalReplica() { + return loc.getLocalReplica(); + } + + /** + * @return the forceReset + */ + public boolean isForceReset() { + return forceReset; + } + + /** + * @param forceReset the forceReset to set + */ + public void setForceReset(boolean forceReset) { + this.forceReset = forceReset; + } + + /** + * @return the masterEpoch + */ + public long getMasterEpoch() { + return masterEpoch; + } + + /** + * @param masterEpoch the masterEpoch to set + */ + public void setMasterEpoch(long masterEpoch) { + this.masterEpoch = masterEpoch; + } + + public int getDataQueueLength() { + return queuedData.get(); + } + + public ReplicaUpdatePolicy getPolicy() { + return this.policy; + } + + /** + * Appends the request to the end of the list of pending requests. + * + * @param request + */ + public void addPendingRequest(StageRequest request) { + pendingRequests.add(request); + } + + /** + * Retrieves and removes the head (first element) of the list of pending requests. + * + * @return request or null if none exists + */ + public StageRequest removePendingRequest() { + StageRequest req = null; + if (hasPendingRequests()) { + req = pendingRequests.remove(0); + } + + return req; + } + + /** + * Removes all of the requests from this list of pending requests and sends them an error response, if a + * callback of type RWReplicationCallback exists. + * + * @param error + * to respond with or null + */ + public void clearPendingRequests(ErrorResponse error) { + if (error != null) { + // Respond with the error, if a callback of type RWReplicationCallback exists. + for (StageRequest rq : pendingRequests) { + Object callback = rq.getCallback(); + if (callback != null && callback instanceof RWReplicationCallback) { + ((RWReplicationCallback) callback).failed(error); + } + } + } + + pendingRequests.clear(); + } + + /** + * Returns true if there are pending requests. + */ + public boolean hasPendingRequests() { + return (!pendingRequests.isEmpty()); + } + + /** + * Returns the number of pending requests. + */ + public int sizeOfPendingRequests() { + return pendingRequests.size(); + } + + /** + * @return the state + */ + public ReplicaState getState() { + return state; + } + + /** + * @param state the state to set + */ + public void setState(ReplicaState state) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"fileId %s changed state from: %s to: %s",this.fileId,this.state, state); + } + this.state = state; + } + + /** + * @return the objectsToFetch + */ + public List getObjectsToFetch() { + return objectsToFetch; + } + + /** + * @param objectsToFetch the objectsToFetch to set + */ + public void setObjectsToFetch(List objectsToFetch) { + this.objectsToFetch = objectsToFetch; + } + + /** + * @return the primary + */ + public Flease getLease() { + return lease; + } + + /** + * @param primary the primary to set + */ + public void setLease(Flease lease) { + this.lease = lease; + } + + /** + * @return the localIsPrimary + */ + public boolean isLocalIsPrimary() { + return localIsPrimary; + } + + /** + * @param localIsPrimary the localIsPrimary to set + */ + public void setLocalIsPrimary(boolean localIsPrimary) { + this.localIsPrimary = localIsPrimary; + } + + /** + * @return the XLocations + */ + public XLocations getLocations() { + return loc; + } + + /** + * Set the files' invalidated state. Once a file has been invalidated any other requests will be rejected. + */ + public void setInvalidated(boolean invalidated) { + this.invalidated = invalidated; + } + + /** + * @return True if the file has been invalidated. + */ + public boolean isInvalidated() { + return invalidated; + } + + /** + * InvalidatedReset should be set true when the file is invalidated but a reset is forced. + */ + public void setInvalidatedReset(boolean invalidatedReset) { + this.invalidatedReset = invalidatedReset; + } + + /** + * Returns true if the file is in an forced reset. + */ + public boolean isInvalidatedReset() { + return invalidatedReset; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/rwre/RetryException.java b/java/servers/src/org/xtreemfs/osd/rwre/RetryException.java new file mode 100644 index 0000000..db981f0 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/rwre/RetryException.java @@ -0,0 +1,20 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.xtreemfs.osd.rwre; + +import java.io.IOException; + +/** + * + * @author bjko + */ +public class RetryException extends IOException { + + public RetryException(String message) { + super(message); + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/rwre/WaR1UpdatePolicy.java b/java/servers/src/org/xtreemfs/osd/rwre/WaR1UpdatePolicy.java new file mode 100644 index 0000000..e44b3d1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/rwre/WaR1UpdatePolicy.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.rwre; + +import java.util.List; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.osd.rwre.RWReplicationStage.Operation; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * + * @author bjko + */ +public class WaR1UpdatePolicy extends CoordinatedReplicaUpdatePolicy { + + final int numResponses; + + public WaR1UpdatePolicy(List remoteOSDUUIDs, String localUUID, String fileId, OSDServiceClient client) { + super(remoteOSDUUIDs, localUUID, fileId, client); + this.numResponses = remoteOSDUUIDs.size(); + } + + @Override + public int getNumRequiredAcks(Operation operation) { + return numResponses; + } + + @Override + public boolean backupCanRead() { + return true; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/rwre/WaRaUpdatePolicy.java b/java/servers/src/org/xtreemfs/osd/rwre/WaRaUpdatePolicy.java new file mode 100644 index 0000000..bef2c5a --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/rwre/WaRaUpdatePolicy.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.rwre; + +import java.util.List; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.osd.rwre.RWReplicationStage.Operation; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * + * @author bjko + * + * @deprecated In XtreemFS 1.3.0 the policy WaR1 was accidentally named WaRa. + * + * This will be fixed in 1.3.1 and therefore the unnecessary WaRa policy is marked as deprecated. + * It is unnecessary because there is no sense to read from all replicas if the data is always written to all replicas. Instead, it suffices to read the local replica. + */ +public class WaRaUpdatePolicy extends CoordinatedReplicaUpdatePolicy { + + final int numResponses; + + public WaRaUpdatePolicy(List remoteOSDUUIDs, String localUUID, String fileId, OSDServiceClient client) { + super(remoteOSDUUIDs, localUUID, fileId, client); + this.numResponses = remoteOSDUUIDs.size(); + } + + @Override + public int getNumRequiredAcks(Operation operation) { + return numResponses; + } + + @Override + public boolean backupCanRead() { + return true; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/rwre/WqRqUpdatePolicy.java b/java/servers/src/org/xtreemfs/osd/rwre/WqRqUpdatePolicy.java new file mode 100644 index 0000000..eb8d59c --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/rwre/WqRqUpdatePolicy.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.rwre; + +import java.util.List; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.osd.rwre.RWReplicationStage.Operation; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +/** + * + * @author bjko + */ +public class WqRqUpdatePolicy extends CoordinatedReplicaUpdatePolicy { + + final int numResponses; + + public WqRqUpdatePolicy(List remoteOSDUUIDs, String localUUID, String fileId, OSDServiceClient client) { + super(remoteOSDUUIDs, localUUID, fileId, client); + this.numResponses = (int) Math.ceil((double)(remoteOSDUUIDs.size())/ 2.0); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.replication, this,"remote majority (excluding local replica) for %s is %d",fileId,numResponses); + } + + @Override + public int getNumRequiredAcks(Operation operation) { + return numResponses; + } + + @Override + public boolean backupCanRead() { + return false; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/stages/DeletionStage.java b/java/servers/src/org/xtreemfs/osd/stages/DeletionStage.java new file mode 100644 index 0000000..3ba0170 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/stages/DeletionStage.java @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.stages; + +import java.io.IOException; +import java.util.Map.Entry; +import java.util.concurrent.LinkedBlockingQueue; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.storage.FileMetadata; +import org.xtreemfs.osd.storage.MetadataCache; +import org.xtreemfs.osd.storage.StorageLayout; + +public class DeletionStage extends Stage { + + public static final int STAGEOP_DELETE_OBJECTS = 0; + + private MetadataCache cache; + + private StorageLayout layout; + + private OSDRequestDispatcher master; + + private DeleteThread deletor; + + private long numFilesDeleted; + + public DeletionStage(OSDRequestDispatcher master, MetadataCache cache, StorageLayout layout, int maxRequestsQueueLength) { + + super("OSD DelSt", maxRequestsQueueLength); + + this.master = master; + this.cache = cache; + this.layout = layout; + + deletor = new DeleteThread(layout); + } + + public void start() { + super.start(); + deletor.start(); + deletor.setPriority(MIN_PRIORITY); + } + + public void shutdown() { + super.shutdown(); + deletor.shutdown(); + } + + public void deleteObjects(String fileId, FileMetadata fi, boolean isCow, OSDRequest request, + final boolean deleteMetadata, DeleteObjectsCallback listener) { + this.enqueueOperation(STAGEOP_DELETE_OBJECTS, new Object[] { fileId, isCow, fi, deleteMetadata }, request, + listener); + } + + /** + * @return the numFilesDeleted + */ + public long getNumFilesDeleted() { + return numFilesDeleted; + } + + public static interface DeleteObjectsCallback { + + public void deleteComplete(ErrorResponse error); + } + + @Override + protected void processMethod(StageRequest method) { + + try { + switch (method.getStageMethod()) { + case STAGEOP_DELETE_OBJECTS: + numFilesDeleted++; + processDeleteObjects(method); + break; + default: + method.sendInternalServerError(new RuntimeException("unknown stage op request")); + } + + } catch (Throwable exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + method.sendInternalServerError(exc); + return; + } + } + + private void processDeleteObjects(StageRequest rq) { + + final DeleteObjectsCallback cback = (DeleteObjectsCallback) rq.getCallback(); + final String fileId = (String) rq.getArgs()[0]; + final boolean cow = (Boolean) rq.getArgs()[1]; + FileMetadata fi = (FileMetadata) rq.getArgs()[2]; + final boolean deleteMetadata = (Boolean) rq.getArgs()[3]; + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "deleting objects of file %s", + fileId); + + if (fi == null) + fi = cache.getFileInfo(fileId); + + // remove the file info from the storage cache + cache.removeFileInfo(fileId); + + // remove all local objects + if (layout.fileExists(fileId)) + deletor.enqueueFileForDeletion(fileId, cow, fi, deleteMetadata); + cback.deleteComplete(null); + } + + private final static class DeleteThread extends Thread { + + private transient boolean quit; + + private final StorageLayout layout; + + private final LinkedBlockingQueue files; + + public DeleteThread(StorageLayout layout) { + quit = false; + this.layout = layout; + files = new LinkedBlockingQueue(); + } + + public void shutdown() { + this.quit = true; + this.interrupt(); + } + + public void enqueueFileForDeletion(String fileID, boolean cow, FileMetadata fi, boolean deleteMetadata) { + assert (this.isAlive()); + assert (fileID != null); + files.add(new Object[] { fileID, cow, fi, deleteMetadata }); + } + + public void run() { + try { + do { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.lifecycle, this, + "DeleteThread started"); + + final Object[] file = files.take(); + final String fileId = (String) file[0]; + final boolean cow = (Boolean) file[1]; + final FileMetadata fi = (FileMetadata) file[2]; + final boolean deleteMetadata = (Boolean) file[3]; + + try { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "deleting objects for %s", fileId); + + // if copy-on-write is enabled ... + if (cow) { + + if (fi == null) { + Logging.logMessage( + Logging.LEVEL_ERROR, + this, + "Deleting objects failed for COW enabled file %s, because FileMetadata is missing.", + fileId); + continue; + } + + // if no previous versions exist, delete the file + // including all its metadata if requested + if (fi.getVersionTable().getVersionCount() == 0) + layout.deleteFile(fileId, deleteMetadata); + + // if other versions exist, only delete those + // objects that make up the latest version of the + // file and are not part of former file versions + else { + + for (Entry entry : fi.getLatestObjectVersions()) { + long objNo = entry.getKey(); + long objVer = entry.getValue(); + if (!fi.getVersionTable().isContained(objNo, objVer)) + layout.deleteObject(fileId, fi, objNo, objVer); + } + + layout.updateCurrentVersionSize(fileId, 0); + } + + } + + // otherwise ... + else + layout.deleteFile(fileId, deleteMetadata); + + yield(); + + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } while (!quit); + } catch (InterruptedException ex) { + // idontcare + } + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.lifecycle, this, "DeleteThread finished"); + } + + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/stages/PreprocStage.java b/java/servers/src/org/xtreemfs/osd/stages/PreprocStage.java new file mode 100644 index 0000000..40e7178 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/stages/PreprocStage.java @@ -0,0 +1,851 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.stages; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.LRUCache; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ASCIIString; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.foundation.pbrpc.utils.ReusableBufferInputStream; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.osd.AdvisoryLock; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.OpenFileTable; +import org.xtreemfs.osd.OpenFileTable.OpenFileTableEntry; +import org.xtreemfs.osd.operations.EventCloseFile; +import org.xtreemfs.osd.operations.EventCreateFileVersion; +import org.xtreemfs.osd.operations.OSDOperation; +import org.xtreemfs.osd.rwre.ReplicaUpdatePolicy; +import org.xtreemfs.osd.storage.CowPolicy; +import org.xtreemfs.osd.storage.CowPolicy.cowMode; +import org.xtreemfs.osd.storage.MetadataCache; +import org.xtreemfs.osd.storage.StorageLayout; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +import com.google.protobuf.Message; + +public class PreprocStage extends Stage { + + public final static int STAGEOP_PARSE_AUTH_OFTOPEN = 1; + + public final static int STAGEOP_OFT_DELETE = 2; + + public final static int STAGEOP_ACQUIRE_LEASE = 3; + + public final static int STAGEOP_RETURN_LEASE = 4; + + public final static int STAGEOP_VERIFIY_CLEANUP = 5; + + public final static int STAGEOP_ACQUIRE_LOCK = 10; + + public final static int STAGEOP_CHECK_LOCK = 11; + + public final static int STAGEOP_UNLOCK = 12; + + public final static int STAGEOP_PING_FILE = 14; + + public final static int STAGEOP_CLOSE_FILE = 15; + + public final static int STAGEOP_INVALIDATE_XLOC = 16; + + public final static int STAGEOP_UPDATE_XLOC = 17; + + private final static long OFT_CLEAN_INTERVAL = 1000 * 60; + + private final static long OFT_OPEN_EXTENSION = 1000 * 30; + + private final Map> capCache; + + private final OpenFileTable oft; + + // time left to next clean op + private long timeToNextOFTclean; + + // last check of the OFT + private long lastOFTcheck; + + private volatile long numRequests; + + /** + * X-Location cache + */ + private final LRUCache xLocCache; + + private final MetadataCache metadataCache; + + private final StorageLayout layout; + + private final OSDRequestDispatcher master; + + private final boolean ignoreCaps; + + private static final int MAX_CAP_CACHE = 20; + + /** Creates a new instance of AuthenticationStage */ + public PreprocStage(OSDRequestDispatcher master, MetadataCache metadataCache, StorageLayout layout, + int maxRequestsQueueLength) { + + super("OSD PreProcSt", maxRequestsQueueLength); + + capCache = new HashMap(); + oft = new OpenFileTable(); + xLocCache = new LRUCache(10000); + this.master = master; + this.metadataCache = metadataCache; + this.layout = layout; + this.ignoreCaps = master.getConfig().isIgnoreCaps(); + } + + public void prepareRequest(OSDRequest request, ParseCompleteCallback listener) { + this.enqueueOperation(STAGEOP_PARSE_AUTH_OFTOPEN, new Object[] { request }, null, listener); + } + + public static interface ParseCompleteCallback { + + public void parseComplete(OSDRequest result, ErrorResponse error); + } + + private void doPrepareRequest(StageRequest rq) { + final OSDRequest request = (OSDRequest) rq.getArgs()[0]; + final ParseCompleteCallback callback = (ParseCompleteCallback) rq.getCallback(); + + numRequests++; + + if (parseRequest(request) == false) + return; + + if (request.getOperation().requiresCapability()) { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "STAGEOP AUTH"); + ErrorResponse err = processAuthenticate(request); + if (err != null) { + callback.parseComplete(request, err); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "authentication of request failed: %s", ErrorUtils.formatError(err)); + } + return; + } + } + + // Check if the request is from the same view (same XLocationSet version) and install newer one. + if (!request.getOperation().bypassViewValidation() && request.getLocationList() != null) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "STAGEOP VIEW"); + ErrorResponse error = processValidateView(request); + if (error != null) { + callback.parseComplete(request, error); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.misc, this, + "request failed with an invalid view: %s", ErrorUtils.formatError(error)); + } + return; + } + } + + String fileId = request.getFileId(); + if (fileId != null) { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "STAGEOP OPEN"); + + CowPolicy cowPolicy = CowPolicy.PolicyNoCow; + + // check if snasphots are enabled and a write operation is executed; + // this is required to create new snapshots when files open for + // writing are closed, even if the same files are still open for + // reading + boolean write = request.getCapability() != null + && request.getCapability().getSnapConfig() != SnapConfig.SNAP_CONFIG_SNAPS_DISABLED + && ((SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_WRONLY + .getNumber()) & request.getCapability().getAccessMode()) > 0; + + if (oft.contains(fileId)) { + cowPolicy = oft.refresh(fileId, TimeSync.getLocalSystemTime() + OFT_OPEN_EXTENSION, write); + } else { + + // find out which COW mode to use, depending on the capability + if (request.getCapability() == null + || request.getCapability().getSnapConfig() == SnapConfig.SNAP_CONFIG_SNAPS_DISABLED) + cowPolicy = CowPolicy.PolicyNoCow; + else + cowPolicy = new CowPolicy(cowMode.COW_ONCE); + + oft.openFile(fileId, TimeSync.getLocalSystemTime() + OFT_OPEN_EXTENSION, cowPolicy, write); + request.setFileOpen(true); + } + request.setCowPolicy(cowPolicy); + } + + callback.parseComplete(request, null); + } + + public void pingFile(String fileId) { + this.enqueueOperation(STAGEOP_PING_FILE, new Object[] { fileId }, null, null); + } + + private void doPingFile(StageRequest m) { + + final String fileId = (String) m.getArgs()[0]; + + // TODO: check if the file was opened for writing + oft.refresh(fileId, TimeSync.getLocalSystemTime() + OFT_OPEN_EXTENSION, false); + + } + + public void checkDeleteOnClose(String fileId, DeleteOnCloseCallback listener) { + this.enqueueOperation(STAGEOP_OFT_DELETE, new Object[] { fileId }, null, listener); + } + + public static interface DeleteOnCloseCallback { + + public void deleteOnCloseResult(boolean isDeleteOnClose, ErrorResponse error); + } + + private void doCheckDeleteOnClose(StageRequest m) { + + final String fileId = (String) m.getArgs()[0]; + final DeleteOnCloseCallback callback = (DeleteOnCloseCallback) m.getCallback(); + + final boolean deleteOnClose = oft.contains(fileId); + if (deleteOnClose) + oft.setDeleteOnClose(fileId); + + callback.deleteOnCloseResult(deleteOnClose, null); + } + + public static interface LockOperationCompleteCallback { + + public void parseComplete(Lock result, ErrorResponse error); + } + + public void acquireLock(String clientUuid, int pid, String fileId, long offset, long length, + boolean exclusive, OSDRequest request, LockOperationCompleteCallback listener) { + this.enqueueOperation(STAGEOP_ACQUIRE_LOCK, new Object[] { clientUuid, pid, fileId, offset, length, + exclusive }, request, listener); + } + + public void doAcquireLock(StageRequest m) { + final LockOperationCompleteCallback callback = (LockOperationCompleteCallback) m.getCallback(); + try { + final String clientUuid = (String) m.getArgs()[0]; + final Integer pid = (Integer) m.getArgs()[1]; + final String fileId = (String) m.getArgs()[2]; + final Long offset = (Long) m.getArgs()[3]; + final Long length = (Long) m.getArgs()[4]; + final Boolean exclusive = (Boolean) m.getArgs()[5]; + + OpenFileTableEntry e = oft.getEntry(fileId); + if (e == null) { + callback.parseComplete(null, ErrorUtils.getErrorResponse(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_EIO, "no entry in OFT, programmatic error")); + return; + } + + AdvisoryLock l = e.acquireLock(clientUuid, pid, offset, length, exclusive); + if (l != null) { + Lock lock = Lock.newBuilder().setClientPid(l.getClientPid()).setClientUuid(l.getClientUuid()).setLength(l.getLength()).setOffset(l.getOffset()).setExclusive(l.isExclusive()).build(); + callback.parseComplete(lock, null); + } + else + callback.parseComplete(null, ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EAGAIN, "conflicting lock")); + + } catch (Exception ex) { + callback.parseComplete(null, ErrorUtils.getInternalServerError(ex)); + } + } + + public void checkLock(String clientUuid, int pid, String fileId, long offset, long length, + boolean exclusive, OSDRequest request, LockOperationCompleteCallback listener) { + this.enqueueOperation(STAGEOP_CHECK_LOCK, new Object[] { clientUuid, pid, fileId, offset, length, + exclusive }, request, listener); + } + + public void doCheckLock(StageRequest m) { + final LockOperationCompleteCallback callback = (LockOperationCompleteCallback) m.getCallback(); + try { + final String clientUuid = (String) m.getArgs()[0]; + final Integer pid = (Integer) m.getArgs()[1]; + final String fileId = (String) m.getArgs()[2]; + final Long offset = (Long) m.getArgs()[3]; + final Long length = (Long) m.getArgs()[4]; + final Boolean exclusive = (Boolean) m.getArgs()[5]; + + OpenFileTableEntry e = oft.getEntry(fileId); + if (e == null) { + callback.parseComplete(null, ErrorUtils.getErrorResponse(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_EIO, "no entry in OFT, programmatic error")); + return; + } + + AdvisoryLock l = e.checkLock(clientUuid, pid, offset, length, exclusive); + Lock lock = Lock.newBuilder().setClientPid(l.getClientPid()).setClientUuid(l.getClientUuid()).setLength(l.getLength()).setOffset(l.getOffset()).setExclusive(l.isExclusive()).build(); + callback.parseComplete(lock, null); + + } catch (Exception ex) { + callback.parseComplete(null, ErrorUtils.getInternalServerError(ex)); + } + } + + public void unlock(String clientUuid, int pid, String fileId, OSDRequest request, + LockOperationCompleteCallback listener) { + this.enqueueOperation(STAGEOP_UNLOCK, new Object[] { clientUuid, pid, fileId }, request, listener); + } + + public void doUnlock(StageRequest m) { + final LockOperationCompleteCallback callback = (LockOperationCompleteCallback) m.getCallback(); + try { + final String clientUuid = (String) m.getArgs()[0]; + final Integer pid = (Integer) m.getArgs()[1]; + final String fileId = (String) m.getArgs()[2]; + + OpenFileTableEntry e = oft.getEntry(fileId); + if (e == null) { + callback.parseComplete(null, ErrorUtils.getErrorResponse(ErrorType.INTERNAL_SERVER_ERROR, POSIXErrno.POSIX_ERROR_EIO, "no entry in OFT, programmatic error")); + return; + } + + e.unlock(clientUuid, pid); + callback.parseComplete(null, null); + + } catch (Exception ex) { + callback.parseComplete(null, ErrorUtils.getInternalServerError(ex)); + } + } + + /** + * Closing the file clears the capability cache and removes the entry for fileId from the {@link OpenFileTable} if + * it exists.
    + * Attention: This will not trigger {@link EventCloseFile} or {@link EventCreateFileVersion} by itself. + * TODO(jdillmann): Discuss if this should trigger the event. + * + * @param fileId + * @param listener + */ + public void close(String fileId, CloseCallback listener) { + this.enqueueOperation(STAGEOP_CLOSE_FILE, new Object[] { fileId }, null, listener); + } + + public static interface CloseCallback { + public void closeResult( OpenFileTableEntry entry, ErrorResponse error); + } + + private void doClose(StageRequest m) { + + final String fileId = (String) m.getArgs()[0]; + final CloseCallback callback = (CloseCallback) m.getCallback(); + + OpenFileTableEntry entry = oft.close(fileId); + LRUCache cachedCaps = capCache.remove(entry.getFileId()); + + callback.closeResult(entry, null); + } + + @Override + public void run() { + + notifyStarted(); + + // interval to check the OFT + + timeToNextOFTclean = OFT_CLEAN_INTERVAL; + lastOFTcheck = TimeSync.getLocalSystemTime(); + + while (!quit) { + try { + final StageRequest op = q.poll(timeToNextOFTclean, TimeUnit.MILLISECONDS); + + checkOpenFileTable(false); + + if (op == null) { + // Logging.logMessage(Logging.LEVEL_DEBUG,this,"no request + // -- timer only"); + continue; + } + + processMethod(op); + + } catch (InterruptedException ex) { + break; + } catch (Throwable ex) { + notifyCrashed(ex); + break; + } + } + + notifyStopped(); + } + + /** + * Removes all open files from the {@link OpenFileTable} whose time has expired and triggers for each file + * the internal event {@link EventCloseFile} or {@link EventCreateFileVersion}. + * + * @param force + * If true, force the cleaning and do not respect the cleaning interval. + */ + private void checkOpenFileTable(boolean force) { + final long tPassed = TimeSync.getLocalSystemTime() - lastOFTcheck; + timeToNextOFTclean = timeToNextOFTclean - tPassed; + // Logging.logMessage(Logging.LEVEL_DEBUG,this,"time to next OFT: + // "+timeToNextOFTclean); + if (force || timeToNextOFTclean <= 0) { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "OpenFileTable clean"); + + long currentTime = TimeSync.getLocalSystemTime(); + + // do OFT clean + List closedFiles = oft.clean(currentTime); + // Logging.logMessage(Logging.LEVEL_DEBUG,this,"closing + // "+closedFiles.size()+" files"); + for (OpenFileTableEntry entry : closedFiles) { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, + "send internal close event for %s, deleteOnClose=%b", entry.getFileId(), entry + .isDeleteOnClose()); + + // Remove the cached capabilities. + capCache.remove(entry.getFileId()); + + // Send close event (creates a new file version if necessary). + OSDOperation closeEvent = master.getInternalEvent(EventCloseFile.class); + closeEvent.startInternalEvent(new Object[] { entry.getFileId(), entry.isDeleteOnClose(), + entry.getCowPolicy().cowEnabled(), entry.isWrite() }); + + } + + + // Check if written files need to be versioned (copied on write). If the file has been already closed it + // unnecessary to create another version because EventCloseFile already did. + List closedWrittenFiles = oft.cleanWritten(currentTime); + for (OpenFileTableEntry entry : closedWrittenFiles) { + if (!entry.isClosed() && entry.isWrite()) { + entry.clearWrite(); + + OSDOperation createVersionEvent = master.getInternalEvent(EventCreateFileVersion.class); + createVersionEvent.startInternalEvent(new Object[] { entry.getFileId(), + metadataCache.getFileInfo(entry.getFileId()) }); + } + } + + timeToNextOFTclean = OFT_CLEAN_INTERVAL; + } + lastOFTcheck = TimeSync.getLocalSystemTime(); + } + + @Override + protected void processMethod(StageRequest m) { + + final int requestedMethod = m.getStageMethod(); + + switch (requestedMethod) { + case STAGEOP_PARSE_AUTH_OFTOPEN: + doPrepareRequest(m); + break; + case STAGEOP_OFT_DELETE: + doCheckDeleteOnClose(m); + break; + case STAGEOP_ACQUIRE_LOCK: + doAcquireLock(m); + break; + case STAGEOP_CHECK_LOCK: + doCheckLock(m); + break; + case STAGEOP_UNLOCK: + doUnlock(m); + break; + case STAGEOP_PING_FILE: + doPingFile(m); + break; + case STAGEOP_CLOSE_FILE: + doClose(m); + break; + case STAGEOP_INVALIDATE_XLOC: + doInvalidateXLocSet(m); + break; + case STAGEOP_UPDATE_XLOC: + doUpdateXLocSetFromFlease(m); + break; + default: + Logging.logMessage(Logging.LEVEL_ERROR, this, "unknown stageop called: %d", requestedMethod); + break; + } + + } + + private boolean parseRequest(OSDRequest rq) { + + RPCHeader hdr = rq.getRpcRequest().getHeader(); + + if (hdr.getMessageType() != MessageType.RPC_REQUEST) { + rq.sendError(ErrorType.GARBAGE_ARGS, POSIXErrno.POSIX_ERROR_EIO, "expected RPC request message type but got "+hdr.getMessageType()); + return false; + } + + RPCHeader.RequestHeader rqHdr = hdr.getRequestHeader(); + + if (rqHdr.getInterfaceId() != OSDServiceConstants.INTERFACE_ID) { + rq.sendError(ErrorType.INVALID_INTERFACE_ID, POSIXErrno.POSIX_ERROR_EIO, "invalid interface id. Maybe wrong service address/port configured?"); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "invalid version requested (requested=%d avail=%d)", rqHdr.getInterfaceId(), + OSDServiceConstants.INTERFACE_ID); + } + return false; + } + + // everything ok, find the right operation + OSDOperation op = master.getOperation(rqHdr.getProcId()); + if (op == null) { + rq.sendError(ErrorType.INVALID_PROC_ID, POSIXErrno.POSIX_ERROR_EINVAL, "requested operation is not available on this OSD (proc # " + + rqHdr.getProcId() + ")"); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, + "requested operation is not available on this OSD (proc #%d)", rqHdr.getProcId()); + } + return false; + } + rq.setOperation(op); + + try { + final Message rqPrototype = OSDServiceConstants.getRequestMessage(rqHdr.getProcId()); + if (rqPrototype == null) { + rq.setRequestArgs(null); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "received request with empty message"); + } else { + if (rq.getRPCRequest().getMessage() != null) { + rq.setRequestArgs(rqPrototype.newBuilderForType().mergeFrom(new ReusableBufferInputStream(rq.getRPCRequest().getMessage())).build()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "received request of type %s", + rq.getRequestArgs().getClass().getName()); + } + } else { + rq.setRequestArgs(rqPrototype.getDefaultInstanceForType()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.net, this, "received request of type %s (empty message)", + rq.getRequestArgs().getClass().getName()); + } + } + } + ErrorResponse err = op.parseRPCMessage(rq); + if (err != null) { + rq.getRpcRequest().sendError(err); + return false; + } + + } catch (Throwable ex) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, OutputUtils + .stackTraceToString(ex)); + rq.getRpcRequest().sendError(ErrorUtils.getInternalServerError(ex)); + return false; + } + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, "request parsed: %d", rq + .getRequestId()); + } + return true; + } + + private ErrorResponse processAuthenticate(OSDRequest rq) { + + final Capability rqCap = rq.getCapability(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "capability: %s", rqCap.getXCap().toString().replace('\n', '/')); + } + + // check if the capability has valid arguments + if (rqCap.getFileId().length() == 0) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "invalid capability. file_id must not be empty"); + } + + if (rqCap.getEpochNo() < 0) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, "invalid capability. epoch must not be < 0"); + } + + if (ignoreCaps) + return null; + + // check if the capability is valid + boolean isValid = false; + // look in capCache + LRUCache cachedCaps = capCache.get(rqCap.getFileId()); + if (cachedCaps != null) { + final Capability cap = cachedCaps.get(rqCap.getSignature()); + if (cap != null) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "using cached cap: %s %s", cap.getFileId(), + cap.getSignature()); + } + isValid = !cap.hasExpired(); + } + } + + if (!isValid) { + isValid = rqCap.isValid(); + if (isValid) { + // add to cache + if (cachedCaps == null) { + cachedCaps = new LRUCache(MAX_CAP_CACHE); + capCache.put(rqCap.getFileId(), cachedCaps); + } + cachedCaps.put(rqCap.getSignature(), rqCap); + } + } + + // depending on the result the event listener is sent + if (!isValid) { + if (rqCap.hasExpired()) + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, "capability is not valid (timed out)"); + + if (!rqCap.hasValidSignature()) + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, "capability is not valid (invalid signature)"); + + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, "capability is not valid (unknown cause)"); + } + + // check if the capability was issued for the requested file + if (!rqCap.getFileId().equals(rq.getFileId())) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, "capability was issued for another file than the one requested"); + } + + // check if the capability provides sufficient access rights for requested operation + if (rq.getOperation().getProcedureId() == OSDServiceConstants.PROC_ID_READ) { + + if ((rqCap.getAccessMode() & (SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_WRONLY.getNumber())) != 0) + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, + "capability does not allow read access to file " + rqCap.getFileId()); + + } else if (rq.getOperation().getProcedureId() == OSDServiceConstants.PROC_ID_WRITE) { + + if ((rqCap.getAccessMode() & (SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_WRONLY.getNumber() | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR + .getNumber())) == 0) + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, + "capability does not allow write access to file " + rqCap.getFileId()); + + } else if (rq.getOperation().getProcedureId() == OSDServiceConstants.PROC_ID_TRUNCATE) { + + if ((rqCap.getAccessMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber()) == 0) + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, + "capability does not allow truncate access to file " + rqCap.getFileId()); + + } else if (rq.getOperation().getProcedureId() == OSDServiceConstants.PROC_ID_UNLINK) { + + // TODO: replace numeric flag with constant + if ((rqCap.getAccessMode() & 010000000) == 0) + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EACCES, + "capability does not allow delete access to file " + rqCap.getFileId()); + + } + + return null; + } + + private ErrorResponse processValidateView(OSDRequest request) { + String fileId = request.getFileId(); + if (fileId == null || fileId.length() == 0) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, + "Invalid view. file_id must not be empty."); + } + + XLocSetVersionState state; + try { + state = layout.getXLocSetVersionState(fileId); + } catch (IOException e) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, + "Invalid view. Local version could not be read."); + } + + XLocations locset = request.getLocationList(); + if (state.getVersion() == locset.getVersion() && !state.getInvalidated()) { + // The request is based on the same (valid) view. + return null; + } else if (locset.getVersion() > state.getVersion()) { + XLocSetVersionState newstate = state.toBuilder() + .setInvalidated(false) + .setVersion(locset.getVersion()) + .setModifiedTime(TimeSync.getGlobalTime()) + .build(); + + try { + // Persist the view. + layout.setXLocSetVersionState(fileId, newstate); + // Inform flease about the new view. + // TODO(jdillmann): Use centralized method to check if a lease is required. + if (locset.getNumReplicas() > 1 + && ReplicaUpdatePolicies.isRwReplicated(locset.getReplicaUpdatePolicy())) { + ASCIIString cellId = ReplicaUpdatePolicy.fileToCellId(fileId); + master.getRWReplicationStage().setFleaseView(fileId, cellId, newstate); + } + } catch (IOException e) { + return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, + "Invalid view. Local version could not be written."); + } + + // The request is valid, because it is based on a newer view. + return null; + } + + // The request is either based on an outdated view, or the replica is invalidated. + String errorMessage = state.getInvalidated() ? "Replica is invalidated." + : "The request is based on an outdated view" + + "(" + locset.getVersion() + " < " + state.getVersion() + ")."; + return ErrorUtils.getErrorResponse(ErrorType.INVALID_VIEW, POSIXErrno.POSIX_ERROR_NONE, + "View is not valid. " + errorMessage); + } + + /** + * Process a viewIdChangeEvent from flease and update the persistent version/state + */ + public void updateXLocSetFromFlease(ASCIIString cellId, int version) { + enqueueOperation(STAGEOP_UPDATE_XLOC, new Object[] { cellId, version }, null, null); + } + + private void doUpdateXLocSetFromFlease(StageRequest m) { + final ASCIIString cellId = (ASCIIString) m.getArgs()[0]; + final int version = (Integer) m.getArgs()[1]; + final String fileId = ReplicaUpdatePolicy.cellToFileId(cellId); + + XLocSetVersionState state; + try { + state = layout.getXLocSetVersionState(fileId); + } catch (IOException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "VersionState could not be read for fileId: %s", fileId); + return; + } + + // If a response from a newer View is encountered, we have to install it and leave the invalidated state. + if (state.getVersion() < version) { + state = state.toBuilder() + .setInvalidated(false) + .setVersion(version) + .setModifiedTime(TimeSync.getGlobalTime()) + .build(); + try { + // persist the version + layout.setXLocSetVersionState(fileId, state); + // and pass it back to flease + master.getRWReplicationStage().setFleaseView(fileId, cellId, state); + } catch (IOException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "VersionState could not be written for fileId: %s", fileId); + return; + } + + } + + // If the local version is greater then the one flease got from it responses, the other replicas have + // to update their version. There exists no path to decrement the version if it has been seen once. + return; + } + + /** + * Invalidate the current XLocSet. The replica will not respond to read/write/truncate or flease operations until a + * new XLocSet is installed.
    + * If the request is based on a newer XLocSet, the local XLocSet version will be updated. If the request is from an + * older one, an error is returned. + */ + public void invalidateXLocSet(OSDRequest request, FileCredentials fileCreds, boolean validateView, + InvalidateXLocSetCallback listener) { + enqueueOperation(STAGEOP_INVALIDATE_XLOC, new Object[] { fileCreds, validateView }, request, listener); + } + + private void doInvalidateXLocSet(StageRequest m) { + final OSDRequest request = m.getRequest(); + final String fileId = request.getFileId(); + final XLocations xLoc = request.getLocationList(); + final FileCredentials fileCreds = (FileCredentials) m.getArgs()[0]; + final boolean validateView = (Boolean) m.getArgs()[1]; + final InvalidateXLocSetCallback callback = (InvalidateXLocSetCallback) m.getCallback(); + + XLocSetVersionState state; + try { + XLocSetVersionState.Builder stateBuilder = layout.getXLocSetVersionState(fileId).toBuilder(); + + // Return an error if the local version is newer then the requested one and the replica is not already + // invalidated. + if (validateView && !stateBuilder.getInvalidated() && stateBuilder.getVersion() > xLoc.getVersion()) { + throw new InvalidXLocationsException("View is not valid. The requests is based on an outdated view."); + } + + // Update the local version if the request is newer. + if (stateBuilder.getVersion() < xLoc.getVersion()) { + stateBuilder.setVersion(xLoc.getVersion()); + } + + // Invalidate the replica. + stateBuilder.setInvalidated(true) + .setModifiedTime(TimeSync.getGlobalTime()); + + state = stateBuilder.build(); + layout.setXLocSetVersionState(fileId, state); + + // TODO(jdillmann): Use centralized method to check if a lease is required. + if (xLoc.getNumReplicas() > 1 && ReplicaUpdatePolicies.isRwReplicated(xLoc.getReplicaUpdatePolicy())) { + master.getRWReplicationStage().invalidateReplica(fileId, fileCreds, xLoc, callback); + } else { + callback.invalidateComplete(LeaseState.NONE, null); + } + + } catch (InvalidXLocationsException e) { + ErrorResponse error = ErrorUtils.getErrorResponse(ErrorType.INVALID_VIEW, POSIXErrno.POSIX_ERROR_NONE, + e.getMessage(), e); + callback.invalidateComplete(LeaseState.NONE, error); + } catch (IOException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "VersionState could not be written for fileId: %s", fileId); + ErrorResponse error = ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, + "Invalid view. Local version could not be written."); + callback.invalidateComplete(LeaseState.NONE, error); + } + } + + public static interface InvalidateXLocSetCallback { + public void invalidateComplete(LeaseState leaseState, ErrorResponse error); + } + + public int getNumOpenFiles() { + return oft.getNumOpenFiles(); + } + + public long getNumRequests() { + return numRequests; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/stages/ReplicationStage.java b/java/servers/src/org/xtreemfs/osd/stages/ReplicationStage.java new file mode 100755 index 0000000..b91e36b --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/stages/ReplicationStage.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.stages; + +import java.io.IOException; + +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.json.JSONException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.replication.ObjectDissemination; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.storage.CowPolicy; +import org.xtreemfs.osd.storage.ObjectInformation; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList; + +/** + * + * 09.09.2008 + * + * @author clorenz + */ +public class ReplicationStage extends Stage { + /** + * fetching an object from another replica + */ + public static final int STAGEOP_FETCH_OBJECT = 1; + + public static final int STAGEOP_INTERNAL_OBJECT_FETCHED = 2; + + public static final int STAGEOP_CANCEL_REPLICATION_FOR_FILE = 3; + + public static final int STAGEOP_START_NEW_REPLICATION_FOR_FILE = 4; + + private OSDRequestDispatcher master; + + private ObjectDissemination disseminationLayer; + + public ReplicationStage(OSDRequestDispatcher master, int maxRequestsQueueLength) { + super("OSD ReplSt", maxRequestsQueueLength); + + // FIXME: test stuff +// Monitoring.enable(); + + this.master = master; + this.disseminationLayer = new ObjectDissemination(master); + } + + @Override + public void shutdown() { + disseminationLayer.shutdown(); + super.shutdown(); + } + + /** + * fetching an object from another replica + */ + public void fetchObject(String fileId, long objectNo, XLocations xLoc, Capability cap, CowPolicy cow, + final OSDRequest request, FetchObjectCallback listener) { + this.enqueueOperation(STAGEOP_FETCH_OBJECT, new Object[] { fileId, objectNo, xLoc, cap, cow }, + request, listener); + } + + public static interface FetchObjectCallback { + public void fetchComplete(ObjectInformation objectInfo, ErrorResponse error); + } + + /** + * Checks the response from a requested replica. + * Only for internal use. + * @param usedOSD + * @param objectList + * @param error + */ + public void internalObjectFetched(String fileId, long objectNo, ServiceUUID usedOSD, InternalObjectData data, + ObjectList objectList, ErrorResponse error) { + this.enqueueOperation(STAGEOP_INTERNAL_OBJECT_FETCHED, new Object[] { fileId, objectNo, usedOSD, + data, objectList, error }, null, null); + } + + /** + * Stops replication for file. + * Only for internal use. + */ + public void cancelReplicationForFile(String fileId) { + this.enqueueOperation(STAGEOP_CANCEL_REPLICATION_FOR_FILE, new Object[] { fileId }, null, + null); + } + + /** + * Triggers replication for file. + * Only for internal use. + */ + public void triggerReplicationForFile(String fileId) { + this.enqueueOperation(STAGEOP_START_NEW_REPLICATION_FOR_FILE, new Object[] { fileId }, null, + null); + } + + @Override + protected void processMethod(StageRequest rq) { + try { + switch (rq.getStageMethod()) { + case STAGEOP_FETCH_OBJECT: { + processFetchObject(rq); + break; + } + case STAGEOP_INTERNAL_OBJECT_FETCHED: { + processInternalObjectFetched(rq); + break; + } + case STAGEOP_CANCEL_REPLICATION_FOR_FILE: { + processInternalCancelFile(rq); + break; + } + case STAGEOP_START_NEW_REPLICATION_FOR_FILE: { + processInternalStartFile(rq); + break; + } + default: + rq.sendInternalServerError(new RuntimeException("unknown stage op request")); + } + } catch (Throwable exc) { + Logging.logError(Logging.LEVEL_ERROR, this, exc); + rq.sendInternalServerError(exc); + return; + } + } + + private void processFetchObject(StageRequest rq) throws IOException, JSONException { + final FetchObjectCallback callback = (FetchObjectCallback) rq.getCallback(); + String fileId = (String) rq.getArgs()[0]; + long objectNo = (Long) rq.getArgs()[1]; + XLocations xLoc = (XLocations) rq.getArgs()[2]; + Capability cap = (Capability) rq.getArgs()[3]; + CowPolicy cow = (CowPolicy) rq.getArgs()[4]; + + // if replica exist and stripe size of all replicas is the same + if (xLoc.getNumReplicas() > 1 && !xLoc.getLocalReplica().isComplete()) + disseminationLayer.fetchObject(fileId, objectNo, xLoc, cap, cow, rq); + else + // object does not exist locally and no replica exists => hole + callback.fetchComplete(new ObjectInformation(ObjectInformation.ObjectStatus.PADDING_OBJECT, null, + xLoc.getLocalReplica().getStripingPolicy().getStripeSizeForObject(objectNo)), null); + } + + private void processInternalObjectFetched(StageRequest rq) { + String fileId = (String) rq.getArgs()[0]; + long objectNo = (Long) rq.getArgs()[1]; + final ServiceUUID usedOSD = (ServiceUUID) rq.getArgs()[2]; + InternalObjectData data = (InternalObjectData) rq.getArgs()[3]; + ObjectList objectList = (ObjectList) rq.getArgs()[4]; + final ErrorResponse error = (ErrorResponse) rq.getArgs()[5]; + + if (error != null) { + if (error.getErrorType() == ErrorType.INVALID_VIEW) { + // it could happen the request is rejected, because the XLoc is outdated caused by removing + // the replica of this OSD + // send client error + disseminationLayer.sendError(fileId, error); + } else { + disseminationLayer.objectNotFetched(fileId, usedOSD, objectNo, data); + if (data != null && data.getData() != null) + BufferPool.free(data.getData()); + } + } else { + // decode object list, if attached + if (objectList != null) { + try { + ObjectSet objectSet = new ObjectSet(objectList.getStripeWidth(), objectList + .getFirst(), objectList.getSet().toByteArray()); + disseminationLayer.objectSetFetched(fileId, usedOSD, objectSet, objectList.getSet() + .size()); + } catch (IOException e) { + Logging.logError(Logging.LEVEL_ERROR, this, e); + } catch (ClassNotFoundException e) { + Logging.logError(Logging.LEVEL_ERROR, this, e); + } + } + + if (data != null && data.getData() != null && data.getData().limit() != 0) + disseminationLayer.objectFetched(fileId, objectNo, usedOSD, data); + else { + // data could not be fetched + disseminationLayer.objectNotFetched(fileId, usedOSD, objectNo, data); + + if (data != null) + BufferPool.free(data.getData()); + } + } + } + + private void processInternalCancelFile(StageRequest rq) { + String fileId = (String) rq.getArgs()[0]; + disseminationLayer.cancelFile(fileId); + } + + /** + * @param rq + */ + private void processInternalStartFile(StageRequest rq) { + String fileId = (String) rq.getArgs()[0]; + disseminationLayer.startNewReplication(fileId); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/stages/Stage.java b/java/servers/src/org/xtreemfs/osd/stages/Stage.java new file mode 100644 index 0000000..881f521 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/stages/Stage.java @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.stages; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.osd.OSDRequest; + +public abstract class Stage extends LifeCycleThread { + + /** + * queue containing all requests + */ + protected BlockingQueue q; + + private final int queueCapacity; + + /** + * set to true if stage should shut down + */ + protected volatile boolean quit; + + public AtomicInteger _numRq, _maxRqTime, _minRqTime; + + public AtomicLong _sumRqTime; + + public Stage(String stageName, int queueCapacity) { + + super(stageName); + q = new LinkedBlockingQueue(); + this.queueCapacity = queueCapacity; + this.quit = false; + + _numRq = new AtomicInteger(0); + _maxRqTime = new AtomicInteger(0); + _minRqTime = new AtomicInteger(Integer.MAX_VALUE); + _sumRqTime = new AtomicLong(0); + } + + /** + * send an request for a stage operation + * + * @param stageOp + * @param args + * @param request + * @param callback + */ + protected void enqueueOperation(int stageOp, Object[] args, OSDRequest request, Object callback) { + enqueueOperation(stageOp, args, request, null, callback); + } + + /** + * + * send an request for a stage operation + * + * @param stageOp + * stage op number + * @param args + * arguments + * @param request + * request + * @param callback + * callback + * @param createdViewBuffer + * an optional additional view buffer to the data, which will be + * freed if the request needs to be dropped due to overload + */ + protected void enqueueOperation(int stageOp, Object[] args, OSDRequest request, ReusableBuffer createdViewBuffer, + Object callback) { + // rq.setEnqueueNanos(System.nanoTime()); + + if (request == null) { + try { + q.put(new StageRequest(stageOp, args, request, callback)); + } catch (InterruptedException e) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, + "Failed to queue internal request due to InterruptedException:"); + Logging.logError(Logging.LEVEL_DEBUG, this, e); + } + } else { + if (q.size() < queueCapacity) { + try { + q.put(new StageRequest(stageOp, args, request, callback)); + } catch (InterruptedException e) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.stage, this, + "Failed to queue external request due to InterruptedException:"); + Logging.logError(Logging.LEVEL_DEBUG, this, e); + } + } else { + // Make sure that the data buffer is returned to the pool if + // necessary, as some operations create view buffers on the + // data. Otherwise, a 'finalized but not freed before' warning + // may occur. + if (createdViewBuffer != null) { + assert (createdViewBuffer.getRefCount() >= 2); + BufferPool.free(createdViewBuffer); + } + Logging.logMessage(Logging.LEVEL_WARN, this, "stage is overloaded, request %d for %s dropped", + request.getRequestId(), request.getFileId()); + request.sendInternalServerError(new IllegalStateException("server overloaded, request dropped")); + } + } + } + + /** + * shut the stage thread down + */ + public void shutdown() { + this.quit = true; + this.interrupt(); + } + + /** + * Get current number of requests in the queue. + * + * @return queue length + */ + public int getQueueLength() { + return q.size(); + } + + @Override + public void run() { + + notifyStarted(); + + while (!quit) { + try { + final StageRequest op = q.take(); + + processMethod(op); + + } catch (InterruptedException ex) { + break; + } catch (Throwable ex) { + this.notifyCrashed(ex); + break; + } + } + + notifyStopped(); + } + + protected void calcRequestDuration(OSDRequest rq) { + /* + * long d = (System.nanoTime()-rq.getEnqueueNanos())/100000l; + * _numRq.incrementAndGet(); if (_minRqTime.get() > d) + * _minRqTime.set((int)d); if (_maxRqTime.get() < d) + * _maxRqTime.set((int)d); _sumRqTime.addAndGet(d); + */ + } + + /** + * Handles the actual execution of a stage method. Must be implemented by + * all stages. + * + * @param method + * the stage method to execute + */ + protected abstract void processMethod(StageRequest method); + + public static interface NullCallback { + public void callback(ErrorResponse ex); + } + + public static final class StageRequest { + + private int stageMethod; + + private Object callback; + + private Object[] args; + + private final OSDRequest request; + + public StageRequest(int stageMethod, Object[] args, OSDRequest request, Object callback) { + this.args = args; + this.stageMethod = stageMethod; + this.callback = callback; + this.request = request; + } + + public int getStageMethod() { + return stageMethod; + } + + public Object[] getArgs() { + return args; + } + + public Object getCallback() { + return callback; + } + + public OSDRequest getRequest() { + return request; + } + + public void sendInternalServerError(Throwable cause) { + if (request != null) { + request.sendInternalServerError(cause); + } else { + Logging.logMessage(Logging.LEVEL_ERROR, this, "internal server error in internal event: %s", + cause.toString()); + Logging.logError(Logging.LEVEL_ERROR, this, cause); + } + } + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/stages/StorageStage.java b/java/servers/src/org/xtreemfs/osd/stages/StorageStage.java new file mode 100644 index 0000000..6d55c8d --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/stages/StorageStage.java @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, Eugenio Cesario + * Zuse Institute Berlin, Consiglio Nazionale delle Ricerche + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.stages; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Map; + +import org.xtreemfs.common.xloc.Replica; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.storage.CowPolicy; +import org.xtreemfs.osd.storage.FileMetadata; +import org.xtreemfs.osd.storage.MetadataCache; +import org.xtreemfs.osd.storage.ObjectInformation; +import org.xtreemfs.osd.storage.StorageLayout; +import org.xtreemfs.osd.storage.StorageThread; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; + +public class StorageStage extends Stage { + + private StorageThread[] storageThreads; + private final StorageLayout layout; + + /** Creates a new instance of MultithreadedStorageStage */ + public StorageStage(OSDRequestDispatcher master, MetadataCache cache, StorageLayout layout, + int numOfThreads, int maxRequestsQueueLength) throws IOException { + + super("OSD Storage Stage", maxRequestsQueueLength); + + this.layout = layout; + + int numberOfThreads = 5; + if (numOfThreads > 0) + numberOfThreads = numOfThreads; + + storageThreads = new StorageThread[numberOfThreads]; + for (int i = 0; i < numberOfThreads; i++) { + // Each storage thread gets the max. queue length as it is possible that one thread gets the whole load + storageThreads[i] = new StorageThread(i, master, cache, layout, maxRequestsQueueLength); + storageThreads[i].setLifeCycleListener(master); + } + } + + public StorageLayout getStorageLayout() { + return layout; + } + + + public void readObject(String fileId, long objNo, StripingPolicyImpl sp, int offset, int length, + long versionTimestamp, OSDRequest request, ReadObjectCallback listener) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_READ_OBJECT, new Object[] { fileId, objNo, sp, + offset, length, versionTimestamp }, request, listener); + } + + public static interface ReadObjectCallback { + + public void readComplete(ObjectInformation result, ErrorResponse error); + } + + public void getFilesize(String fileId, StripingPolicyImpl sp, long versionTimestamp, OSDRequest request, + GetFileSizeCallback listener) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_GET_FILE_SIZE, new Object[] { fileId, sp, versionTimestamp }, + request, listener); + } + + public static interface GetFileSizeCallback { + + public void getFileSizeComplete(long fileSize, ErrorResponse error); + } + + public void writeObject(String fileId, long objNo, StripingPolicyImpl sp, int offset, + ReusableBuffer data, CowPolicy cow, XLocations xloc, boolean sync, Long newVersion, + OSDRequest request, ReusableBuffer createdViewBuffer, WriteObjectCallback listener) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_WRITE_OBJECT, new Object[] { fileId, objNo, sp, + offset, data, cow, xloc, false, sync, newVersion }, request, createdViewBuffer, listener); + } + + public void insertPaddingObject(String fileId, long objNo, StripingPolicyImpl sp, int size, + OSDRequest request, WriteObjectCallback listener) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_INSERT_PADDING_OBJECT, new Object[] { fileId, + objNo, sp, size }, request, listener); + } + + /* + * currently only used for replication + */ + public void writeObjectWithoutGMax(String fileId, long objNo, StripingPolicyImpl sp, int offset, + ReusableBuffer data, CowPolicy cow, XLocations xloc, boolean sync, Long newVersion, + OSDRequest request, WriteObjectCallback listener) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_WRITE_OBJECT, new Object[] { fileId, objNo, sp, + offset, data, cow, xloc, true, sync, newVersion }, request, listener); + } + + public static interface WriteObjectCallback { + + public void writeComplete(OSDWriteResponse result, ErrorResponse error); + } + + public void truncate(String fileId, long newFileSize, StripingPolicyImpl sp, Replica currentReplica, + long truncateEpoch, CowPolicy cow, Long newObjVer, Boolean createTruncateLogEntry, OSDRequest request, TruncateCallback listener) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_TRUNCATE, new Object[] { fileId, newFileSize, sp, + currentReplica, truncateEpoch, cow, newObjVer, createTruncateLogEntry }, request, listener); + } + + public static interface TruncateCallback { + + public void truncateComplete(OSDWriteResponse result, ErrorResponse error); + } + + public void deleteObjects(String fileId, StripingPolicyImpl sp, + long truncateEpoch, Map objectVersionsToBeDeleted, DeleteObjectsCallback listener) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_DELETE_OBJECTS, new Object[] { fileId, sp, + truncateEpoch, objectVersionsToBeDeleted }, null, listener); + } + + public static interface DeleteObjectsCallback { + + public void deleteObjectsComplete(ErrorResponse error); + } + + public void flushCaches(String fileId, CachesFlushedCallback listener) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_FLUSH_CACHES, new Object[] { fileId }, null, + listener); + } + + public static interface CachesFlushedCallback { + public void cachesFlushed(ErrorResponse error, FileMetadata md); + } + + public void receivedGMAX_ASYNC(String fileId, long epoch, long lastObject) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_GMAX_RECEIVED, new Object[] { fileId, epoch, + lastObject }, null, null); + } + + public void internalGetGmax(String fileId, StripingPolicyImpl sp, long snapTimestamp, OSDRequest request, + InternalGetGmaxCallback listener) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_GET_GMAX, new Object[] { fileId, sp, + snapTimestamp }, request, listener); + } + + public static interface InternalGetGmaxCallback { + + public void gmaxComplete(InternalGmax result, ErrorResponse error); + } + + public void internalGetMaxObjectNo(String fileId, StripingPolicyImpl sp, InternalGetMaxObjectNoCallback callback) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_GET_MAX_OBJNO, new Object[]{fileId,sp}, null, callback); + } + + public static interface InternalGetMaxObjectNoCallback { + + public void maxObjectNoCompleted(long maxObjNo, long fileSize, long truncateEpoch, ErrorResponse error); + } + + public void internalGetReplicaState(String fileId, StripingPolicyImpl sp, long remoteMaxObjVersion, + InternalGetReplicaStateCallback callback) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_GET_REPLICA_STATE, new Object[]{fileId,sp,remoteMaxObjVersion}, null, callback); + } + + public static interface InternalGetReplicaStateCallback { + + public void getReplicaStateComplete(ReplicaStatus localState, ErrorResponse error); + + } + + public void getObjectSet(String fileId, StripingPolicyImpl sp, OSDRequest request, + GetObjectListCallback listener) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_GET_OBJECT_SET, new Object[] { fileId,sp }, + request, listener); + } + + public void createFileVersion(String fileId, FileMetadata fi, OSDRequest request, CreateFileVersionCallback listener) { + this.enqueueOperation(fileId, StorageThread.STAGEOP_CREATE_FILE_VERSION, new Object[] { fileId, fi }, + request, listener); + } + + public static interface GetObjectListCallback { + + public void getObjectSetComplete(ObjectSet result, ErrorResponse error); + } + + public static interface CreateFileVersionCallback { + + public void createFileVersionComplete(long fileSize, ErrorResponse error); + } + + public void getFileIDList(OSDRequest request, GetFileIDListCallback listener) { + this.enqueueOperation("foobar", StorageThread.STAGEOP_GET_FILEID_LIST, new Object[] {}, request, listener); + } + + public static interface GetFileIDListCallback { + + public void createGetFileIDListComplete(ArrayList fileIDList, ErrorResponse Error); + } + + public void enqueueOperation(int stageOp, Object[] args, OSDRequest request, Object callback) { + notifyCrashed(new Exception( + "wrong method call: use enqueueOperation(String fileId, int stageOp, Object[] args, OSDRequest request, Object callback) instead!")); + } + + public void enqueueOperation(String fileId, int stageOp, Object[] args, OSDRequest request, + Object callback) { + enqueueOperation(fileId, stageOp, args, request, null, callback); + } + + public void enqueueOperation(String fileId, int stageOp, Object[] args, OSDRequest request, + ReusableBuffer createdViewBuffer, Object callback) { + + // rq.setEnqueueNanos(System.nanoTime()); + + // choose the thread the new request has to be + // assigned to, for its execution + int taskId = getTaskId(fileId); + + // add the new request to the storageTask, + // in order to start/schedule its execution + // concurrently with other threads assigned to other + // storageTasks + storageThreads[taskId].enqueueOperation(stageOp, args, request, createdViewBuffer, callback); + } + + public void run() { + // start all storage threads + for (StorageThread th : storageThreads) + th.start(); + } + + public void shutdown() { + for (StorageThread th : storageThreads) + th.shutdown(); + } + + public void waitForStartup() throws Exception { + // wait for all storage threads to be ready + for (StorageThread th : storageThreads) + th.waitForStartup(); + } + + public void waitForShutdown() throws Exception { + // wait for all storage threads to be shut down + for (StorageThread th : storageThreads) + th.waitForShutdown(); + } + + private int getTaskId(String fileId) { + + // calculate a hash value from the file ID and return the responsible + // thread + assert (fileId != null); + int hash = fileId.hashCode(); + if (hash == Integer.MIN_VALUE) { + return 0; + } + int key = Math.abs(hash); + int index = (key % storageThreads.length); + + // String objId = rq.getDetails().getFileId() + // + rq.getDetails().getObjectNumber(); + // int key = Math.abs(objId.hashCode()); + // int index = (key % storageThreads.length); + + return index; + } + + @Override + protected void processMethod(StageRequest method) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getQueueLength() { + + int len = 0; + for(StorageThread th: storageThreads) + len += th.getQueueLength(); + + return len; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/stages/VivaldiStage.java b/java/servers/src/org/xtreemfs/osd/stages/VivaldiStage.java new file mode 100644 index 0000000..5adc626 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/stages/VivaldiStage.java @@ -0,0 +1,870 @@ +/* + * Copyright (c) 2008-2011 by Juan Gonzalez de Benito, Bjoern Kolbeck, + * Barcelona Supercomputing Center, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.osd.stages; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.concurrent.TimeUnit; + +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.common.uuids.Mapping; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.server.UDPMessage; +import org.xtreemfs.osd.OSDRequest; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.vivaldi.VivaldiNode; +import org.xtreemfs.osd.vivaldi.ZipfGenerator; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * Stage used in the OSD to manage Vivaldi. + * + * @author Juan Gonzalez de Benito (BSC) & Björn Kolbeck (ZIB) + */ +public class VivaldiStage extends Stage { + + private static final int STAGEOP_ASYNC_PING = 1; + private static final int STAGEOP_SYNC_PING = 2; + /** + * System time when the timer was last executed. + */ + private long lastCheck; + /** + * The main OSDRequestDispatcher used by the OSD. + */ + private final OSDRequestDispatcher master; + /** + * Client used to communicate with the Directory Service. + */ + private final DIRClient dirClient; + /** + * List of already sent Vivaldi requests. + */ + private HashMap sentRequests; + /** + * List of simultaneous VivaldiRetrys. Each of them keep track of the RTTs measured for the same node. + */ + private HashMap toBeRetried; + /** + * The node that includes the Vivaldi information of the OSD. + */ + private VivaldiNode vNode; + /** + * Number of milliseconds until the next Vivaldi recalculation + */ + private long nextRecalculationInMS; + /** + * Number of milliseconds until the next timer execution + */ + private long nextTimerRunInMS; + /** + * List of existent OSDs. The OSD contact them to get their Vivaldi information + * and use it to recalculate its position + */ + private LinkedList knownOSDs; + /** + * Number of elapsed Vivaldi iterations + */ + private long vivaldiIterations; + private ZipfGenerator rankGenerator; + private final double ZIPF_GENERATOR_SKEW = 0.5; // TODO(mno): move to global config?! (depends on keeping ZIPF or not) + /** + * Number of retries to be sent before accepting 'suspiciously high' RTT + */ + private final int MAX_RETRIES_FOR_A_REQUEST; + /** + * Recalculation interval. + * + * The recalculation period is randomly determined and lies within: + * [RECALCULATION_INTERVAL - RECALCULATION_EPSILON, RECALCULATION_INTERVAL + RECALCULATION_EPSILON] + */ + private final int RECALCULATION_INTERVAL; + /** + * Recalculation epsilon. + * + * The recalculation period is randomly determined and lies within: + * [RECALCULATION_INTERVAL - RECALCULATION_EPSILON, RECALCULATION_INTERVAL + RECALCULATION_EPSILON] + */ + private final int RECALCULATION_EPSILON; + /** + * Number of times the node recalculates its position before updating + * its list of existent OSDs. + */ + private final int ITERATIONS_BEFORE_UPDATING; + /** + * Maximum number of milliseconds an OSD waits for a RESPONSE before discarding + * its corresponding REQUEST. Expiration times under {@code TIMER_INTERVAL_IN_MS} + * are not granted. + */ + private final int MAX_REQUEST_TIMEOUT_IN_MS; + /** + * Period of time between timer executions. + */ + private final int TIMER_INTERVAL_IN_MS; + + public VivaldiStage(OSDRequestDispatcher master, int maxRequestsQueueLength) { + super("VivaldiSt", maxRequestsQueueLength); + this.master = master; + this.dirClient = master.getDIRClient(); + + this.sentRequests = new HashMap(); + this.toBeRetried = new HashMap(); + this.vNode = new VivaldiNode(); + + MAX_RETRIES_FOR_A_REQUEST = master.getConfig().getVivaldiMaxRetriesForARequest(); + RECALCULATION_INTERVAL = master.getConfig().getVivaldiRecalculationInterval(); + RECALCULATION_EPSILON = master.getConfig().getVivaldiRecalculationEpsilon(); + ITERATIONS_BEFORE_UPDATING = master.getConfig().getVivaldiIterationsBeforeUpdating(); + MAX_REQUEST_TIMEOUT_IN_MS = master.getConfig().getVivaldiMaxRequestTimeout(); + TIMER_INTERVAL_IN_MS = master.getConfig().getVivaldiTimerInterval(); + + //TOFIX: should the coordinates be initialized from a file? + if (Logging.isDebug()) { + Logging.logMessage( + Logging.LEVEL_DEBUG, + this, + String.format("Coordinates initialized:(%.3f,%.3f)", + vNode.getCoordinates().getXCoordinate(), + vNode.getCoordinates().getYCoordinate())); + } + this.knownOSDs = null; + this.rankGenerator = null; + + this.lastCheck = 0; + } + + /** + * The position of the node is recalculated from a list of previously measured RTTs. Even if the + * resulting movement is too big, the node's coordinates will be modified. + * + * @param coordinatesJ Coordinates of the node where recalculating against. If the operation + * has been triggered by a timeout, this parameter is {@code null}. + * + * @param availableRTTs List of RTTs measured after several retries. + */ + private void forceVivaldiRecalculation(VivaldiCoordinates coordinatesJ, ArrayList availableRTTs) { + + //TOFIX:In this version, the recalculation is discarded when the last retry times out: (coordinatesJ==null) + if ((coordinatesJ != null) && (availableRTTs.size() > 0)) { + + //Determine the minimum RTT of the whole sample + long minRTT = availableRTTs.get(0); + + StringBuilder strbRTTs = new StringBuilder(Long.toString(minRTT)); + + for (int i = 1; i < availableRTTs.size(); i++) { + strbRTTs.append(","); + strbRTTs.append(availableRTTs.get(i)); + + if (availableRTTs.get(i) < minRTT) { + minRTT = availableRTTs.get(i); + } + } + + vNode.recalculatePosition(coordinatesJ, minRTT, true); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, + this, + String.format("Forced(%s):%d Viv:%.3f Own:(%.3f,%.3f) lE=%.3f Rem:(%.3f,%.3f) rE=%.3f", + strbRTTs.toString(), + minRTT, + VivaldiNode.calculateDistance(vNode.getCoordinates(), coordinatesJ), + vNode.getCoordinates().getXCoordinate(), + vNode.getCoordinates().getYCoordinate(), + vNode.getCoordinates().getLocalError(), + coordinatesJ.getXCoordinate(), + coordinatesJ.getYCoordinate(), + coordinatesJ.getLocalError())); + } + } + } + + public void getVivaldiCoordinatesAsync(xtreemfs_pingMesssage coordinates, InetSocketAddress sender, OSDRequest request) { + this.enqueueOperation(STAGEOP_ASYNC_PING, new Object[]{coordinates, sender}, request, null); + } + + public void getVivaldiCoordinatesSync(xtreemfs_pingMesssage coordinates, OSDRequest request, VivaldiPingCallback listener) { + this.enqueueOperation(STAGEOP_SYNC_PING, new Object[]{coordinates}, request, listener); + } + + public static interface VivaldiPingCallback { + + public void coordinatesCallback(VivaldiCoordinates myCoordinates, ErrorResponse error); + } + + @Override + protected void processMethod(StageRequest method) { + xtreemfs_pingMesssage msg = (xtreemfs_pingMesssage) method.getArgs()[0]; + + if (method.getStageMethod() == STAGEOP_ASYNC_PING) { + try { + InetSocketAddress sender = (InetSocketAddress) method.getArgs()[1]; + if (msg.getRequestResponse()) { + RPCHeader.RequestHeader rqHdr = RPCHeader.RequestHeader.newBuilder().setAuthData(RPCAuthentication.authNone).setUserCreds(RPCAuthentication.userService).setInterfaceId(OSDServiceConstants.INTERFACE_ID).setProcId(OSDServiceConstants.PROC_ID_XTREEMFS_PING).build(); + RPCHeader hdr = RPCHeader.newBuilder().setCallId(0).setMessageType(MessageType.RPC_REQUEST).setRequestHeader(rqHdr).build(); + xtreemfs_pingMesssage response = xtreemfs_pingMesssage.newBuilder().setCoordinates(this.vNode.getCoordinates()).setRequestResponse(false).build(); + + // TODO(mno): Comment the following sleeps before committing. They are just for local testing with a simulated delay. + /* + if(master.getConfig().getUUID().toString().equals("test9-localhost-OSD") || sender.getPort() == 32649) + Thread.sleep(300); + else if (master.getConfig().getUUID().toString().equals("test8-localhost-OSD") || sender.getPort() == 32648) + Thread.sleep(150); + else + Thread.sleep(20); + */ + + master.sendUDPMessage(hdr, response, sender); + } else { + recalculateCoordinates(msg.getCoordinates(), sender); + } + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_WARN, this, ex); + } finally { + // free the request buffer, as it won't be freed otherwise + // because the response is sent asynchronously + method.getRequest().getRpcRequest().freeBuffers(); + } + } else { + VivaldiPingCallback callback = (VivaldiPingCallback) method.getCallback(); + callback.coordinatesCallback(this.vNode.getCoordinates(), null); + } + } + + protected void recalculateCoordinates(VivaldiCoordinates coordinatesJ, InetSocketAddress sender) { + try { + + boolean coordinatesModified = false; + + SentRequest correspondingReq = sentRequests.remove(sender); + + if (correspondingReq != null) { + + //Calculate the RTT + long now = System.currentTimeMillis(); + long estimatedRTT = now - correspondingReq.getSystemTime(); + + + //Two nodes will never be at the same position + if (estimatedRTT == 0) { + estimatedRTT = 1; + } + + //Recalculate Vivaldi + VivaldiRetry prevRetry = toBeRetried.get(sender); + boolean retriedTraceVar = false, forcedTraceVar = false; + + /* If MAX_RETRIES == 0 the coordinates must be recalculated without + retrying*/ + boolean retryingDisabled = (MAX_RETRIES_FOR_A_REQUEST <= 0); + + if (!vNode.recalculatePosition(coordinatesJ, estimatedRTT, retryingDisabled)) { + + //The RTT seems to be too big, so it might be a good idea to go for a retry + + if (prevRetry == null) { + toBeRetried.put(sender, new VivaldiRetry(estimatedRTT)); + retriedTraceVar = true; + } else { + + prevRetry.addRTT(estimatedRTT); + + prevRetry.setRetried(false); + + if (prevRetry.numberOfRetries() > MAX_RETRIES_FOR_A_REQUEST) { + + //Recalculate using the previous RTTs + forceVivaldiRecalculation(coordinatesJ, prevRetry.getRTTs()); + coordinatesModified = true; + + //Just for traceVar + forcedTraceVar = true; + + toBeRetried.remove(sender); + } else { + retriedTraceVar = true; + } + } + + } else { + + coordinatesModified = true; + + if (prevRetry != null) { + /*The received RTT is correct but it has been necessary to retry + some request previously, so now our structures must be updated.*/ + toBeRetried.remove(sender); + } + } + + if (!forcedTraceVar && Logging.isDebug()) { + //TOFIX: Printing getHostName() without any kind of control could be dangerous (?) + Logging.logMessage(Logging.LEVEL_DEBUG, + this, + String.format("%s:%d Viv:%.3f Own:(%.3f,%.3f) lE=%.3f Rem:(%.3f,%.3f) rE=%.3f %s", + retriedTraceVar ? "RETRY" : "RTT", + estimatedRTT, + VivaldiNode.calculateDistance(vNode.getCoordinates(), coordinatesJ), + vNode.getCoordinates().getXCoordinate(), + vNode.getCoordinates().getYCoordinate(), + vNode.getCoordinates().getLocalError(), + coordinatesJ.getXCoordinate(), + coordinatesJ.getYCoordinate(), + coordinatesJ.getLocalError(), + sender.getHostName())); + } + + }//there's not any previously registered request , so we just discard the response + + //Use coordinatesJ to update knownOSDs if possible + if ((knownOSDs != null) && (!knownOSDs.isEmpty())) { + + //Check if the message has been sent by some of the knownOSDs + String strAddress = sender.getHostName() + + ":" + + sender.getPort(); + + int sendingOSD = 0; + boolean OSDfound = false; + + //Look for the OSD that has sent the message and update its coordinates + while ((!OSDfound) && (sendingOSD < knownOSDs.size())) { + + if ((knownOSDs.get(sendingOSD).getStrAddress() != null) + && knownOSDs.get(sendingOSD).getStrAddress().equals(strAddress)) { + + knownOSDs.get(sendingOSD).setCoordinates(coordinatesJ); + OSDfound = true; + + } else { + sendingOSD++; + } + } + + if (coordinatesModified) { + /*Client's position has been modified so we must + * re-sort knownOSDs accordingly to the new vivaldi distances*/ + + LinkedList auxOSDList = new LinkedList(); + + for (int i = knownOSDs.size() - 1; i >= 0; i--) { + + KnownOSD insertedOSD = knownOSDs.get(i); + + double insertedOSDDistance = + VivaldiNode.calculateDistance(insertedOSD.getCoordinates(), + this.vNode.getCoordinates()); + int j = 0; + boolean inserted = false; + + while ((!inserted) && (j < auxOSDList.size())) { + double prevOSDDistance = + VivaldiNode.calculateDistance(auxOSDList.get(j).getCoordinates(), + this.vNode.getCoordinates()); + + if (insertedOSDDistance <= prevOSDDistance) { + auxOSDList.add(j, insertedOSD); + inserted = true; + } else { + j++; + } + } + if (!inserted) { + auxOSDList.add(insertedOSD); + } + + } + + knownOSDs = auxOSDList; + + } else if (OSDfound) { + + /* It's not necessary to resort the whole knownOSDs but only the OSD + * whose coordinates might have changed*/ + + KnownOSD kosd = knownOSDs.remove(sendingOSD); + kosd.setCoordinates(coordinatesJ); + double osdNewDistance = + VivaldiNode.calculateDistance(coordinatesJ, vNode.getCoordinates()); + + int i = 0; + boolean inserted = false; + while ((!inserted) && (i < knownOSDs.size())) { + double existingDistance = + VivaldiNode.calculateDistance(knownOSDs.get(i).getCoordinates(), + vNode.getCoordinates()); + if (osdNewDistance <= existingDistance) { + knownOSDs.add(i, kosd); + inserted = true; + } else { + i++; + } + } + + if (!inserted) { + knownOSDs.add(kosd); + } + } + } + + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + /** + * Sends a message to a OSD requesting its coordinates. + * (NOTE: the response is sent in processMethod(..).) + * + * @param osd Address of the OSD we want to contact. + * @param myCoordinates Our own coordinates. + */ + private void sendVivaldiRequest(InetSocketAddress osd, VivaldiCoordinates myCoordinates) { + + + //It's not allowed to send two requests to the same OSD simultaneously + if (sentRequests.get(osd) == null) { + + RPCHeader.RequestHeader rqHdr = RPCHeader.RequestHeader.newBuilder(). + setAuthData(RPCAuthentication.authNone). + setUserCreds(RPCAuthentication.userService). + setInterfaceId(OSDServiceConstants.INTERFACE_ID). + setProcId(OSDServiceConstants.PROC_ID_XTREEMFS_PING).build(); + RPCHeader hdr = RPCHeader.newBuilder().setCallId(0). + setMessageType(MessageType.RPC_REQUEST). + setRequestHeader(rqHdr).build(); + + + xtreemfs_pingMesssage pingMsg = xtreemfs_pingMesssage.newBuilder().setCoordinates(myCoordinates).setRequestResponse(true).build(); + + long systemTimeNow = System.currentTimeMillis(); + //getLocalSystemTime does not introduce such a big overhead, while currentTimeMillis is required to get the necessary precision. + long localTimeNow = TimeSync.getLocalSystemTime(); + + //If we're sending a request, we need to register it in our structures so we can process its response later + sentRequests.put(osd, new SentRequest(localTimeNow, systemTimeNow)); + + try { + master.sendUDPMessage(hdr, pingMsg, osd); + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + } + + /** + * Keeps the list of sent requests updated, by eliminating those whose timeout + * has expired. + */ + private void maintainSentRequests() { + + final long localNow = TimeSync.getLocalSystemTime(); + ArrayList removedRequests = new ArrayList(); + + //Check which requests have timed out + for (InetSocketAddress reqKey : sentRequests.keySet()) { + if (localNow >= sentRequests.get(reqKey).getLocalTime() + MAX_REQUEST_TIMEOUT_IN_MS) { + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "OSD times out: " + reqKey.getHostName()); + } + removedRequests.add(reqKey); + } + } + + //Manage the timed out requests + for (InetSocketAddress removed : removedRequests) { + //Is it the first time the node times out? + VivaldiRetry prevRetry = toBeRetried.get(removed); + + //The retry is marked as 'not retried' so it will have priority when sending the next request + if (prevRetry == null) { + toBeRetried.put(removed, new VivaldiRetry()); + } else { + //Take note of the new time out + prevRetry.addTimeout(); + prevRetry.setRetried(false); + + //We've already retried too many times, so it's time to recalculate with the available info + if (prevRetry.numberOfRetries() > MAX_RETRIES_FOR_A_REQUEST) { + forceVivaldiRecalculation(null, prevRetry.getRTTs()); + toBeRetried.remove(removed); + } + } + sentRequests.remove(removed); + } + } + + /** + * Performs some operations that have been defined to be executed periodically. + * + * The frequency of the timer is defined by the attribute {@code + * TIMER_INTERVAL_IN_MS} + */ + private void executeTimer() { + master.updateVivaldiCoordinates(vNode.getCoordinates()); + + //Remove the requests that are not needed anymore + maintainSentRequests(); + } + + public void receiveVivaldiMessage(UDPMessage msg) { + enqueueOperation(STAGEOP_ASYNC_PING, new Object[]{msg}, null, null); + } + + /** + * Updates the list of known OSDs, from the data stored in the DS. This + * function is responsible of keeping a list of OSDs used by the algorithm. + */ + private void updateKnownOSDs() { + try { + ServiceSet receivedOSDs = dirClient.xtreemfs_service_get_by_type(null, RPCAuthentication.authNone, RPCAuthentication.userService, ServiceType.SERVICE_TYPE_OSD); + + //We need our own UUID, to discard its corresponding entry + String ownUUID = master.getConfig().getUUID().toString(); + + knownOSDs = new LinkedList(); + + for (Service osd : receivedOSDs.getServicesList()) { + + //If it's not our own entry and the referred service is not offline + if (!ownUUID.equals(osd.getUuid()) && osd.getLastUpdatedS() != 0) { + + //Parse the coordinates provided by the DS + String strCoords = KeyValuePairs.getValue(osd.getData().getDataList(), "vivaldi_coordinates"); + + + if (strCoords != null) { + + //Calculate distance from the client to the OSD + VivaldiCoordinates osdCoords = VivaldiNode.stringToCoordinates(strCoords); + KnownOSD newOSD = new KnownOSD(osd.getUuid(), osdCoords); + + double insertedOSDDistance = + VivaldiNode.calculateDistance(osdCoords, this.vNode.getCoordinates()); + + //Insert the new OSD accordingly to its vivaldi distance + + int i = 0; + + boolean inserted = false; + + while ((!inserted) && (i < knownOSDs.size())) { + double oldOSDDistance = + VivaldiNode.calculateDistance(knownOSDs.get(i).getCoordinates(), + this.vNode.getCoordinates()); + + if (insertedOSDDistance <= oldOSDDistance) { + knownOSDs.add(i, newOSD); + inserted = true; + } else { + i++; + } + } + if (!inserted) { + knownOSDs.add(newOSD); + } + } + } + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Updating list of known OSDs (size: " + knownOSDs.size() + ")"); + } + + } catch (Exception exc) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "Error while updating known OSDs: " + exc); + //Create an empty OSDs set + knownOSDs = new LinkedList(); + } finally { + //Adapt the Zipf generator to the new sample + if (rankGenerator == null) { + rankGenerator = new ZipfGenerator(knownOSDs.size(), ZIPF_GENERATOR_SKEW); + } else { + rankGenerator.setSize(knownOSDs.size()); + } + + //Previous requests are discarded + sentRequests.clear(); + toBeRetried.clear(); + } + } + + /** + * Executes one Vivaldi iteration. For each of these iterations, the algorithm + * chooses one random node from the list of known OSDs and sends it a Vivaldi + * request, to recalculate then the position of the OSD using the received information. + */ + private void iterateVivaldi() { + + if (vivaldiIterations % ITERATIONS_BEFORE_UPDATING == 1) { + updateKnownOSDs(); + + + } //Start recalculation + if ((knownOSDs != null) && (!knownOSDs.isEmpty())) { + + //It's still necessary to retry some request + if (toBeRetried.size() > 0) { + for (InetSocketAddress addr : toBeRetried.keySet()) { + + if (!toBeRetried.get(addr).hasBeenRetried()) { + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Retrying: " + addr.getHostName()); + } + + sendVivaldiRequest(addr, vNode.getCoordinates()); + toBeRetried.get(addr).setRetried(true); + } + } + } else { + + //Choose a random OSD and send it a new request + //int chosenIndex = (int)(Math.random()*knownOSDs.size()); + + //if we get here, knownOSDs is not empty and therefore rankGenerator != null + int chosenIndex = rankGenerator.next(); + + KnownOSD chosenOSD = knownOSDs.get(chosenIndex); + + try { + + //Get the corresponding InetAddress + ServiceUUID sUUID = new ServiceUUID(chosenOSD.getUUID()); + sUUID.resolve(Schemes.SCHEME_PBRPCU); + InetSocketAddress osdAddr = null; + Mapping serviceMappings[] = sUUID.getMappings(); + + int mapIt = 0; + + while ((osdAddr == null) && (mapIt < serviceMappings.length)) { + + if (serviceMappings[mapIt].protocol.equals(Schemes.SCHEME_PBRPCU)) { + + osdAddr = serviceMappings[mapIt].resolvedAddr; + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "Recalculating against: " + chosenOSD.getUUID()); + } + + //Only at this point we known which InetAddress corresponds with which UUID + chosenOSD.setStrAddress(osdAddr.getAddress().getHostAddress() + + ":" + + osdAddr.getPort()); + + //After receiving the response, we will be able to recalculate + sendVivaldiRequest(osdAddr, vNode.getCoordinates()); + } + mapIt++; + } + + } catch (UnknownUUIDException unke) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "Unknown UUID: " + chosenOSD.getUUID()); + } catch (Exception e) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "Error detected while iterating Vivaldi"); + } + } + } + + vivaldiIterations = (vivaldiIterations + 1) % Long.MAX_VALUE; + } + + /** + * Main function of the stage. It keeps polling request methods from the stage + * queue and processing them. If there are no methods available, the function + * blocks until a new request is enqueued or the defined timer expires. + */ + @Override + public void run() { + + notifyStarted(); + + vivaldiIterations = 0; + + long pollTimeoutInMS; + + nextRecalculationInMS = -1; + nextTimerRunInMS = -1; + + while (!quit) { + try { + pollTimeoutInMS = checkTimer(); + final StageRequest op = q.poll(pollTimeoutInMS, TimeUnit.MILLISECONDS); + if (op != null) { + processMethod(op); + } + } catch (InterruptedException ex) { + break; + } catch (Throwable ex) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "Error detected: " + ex); + notifyCrashed(ex); + break; + } + } + notifyStopped(); + } + + /** + * Checks if the main timer or the last recalculation period have expired + * and executes, depending on the case, the {@code executeTimer} + * function or a new Vivaldi iteration. + * + * @return the number of milliseconds before executing a new checking. + */ + private long checkTimer() { + + final long now = TimeSync.getLocalSystemTime(); + + //Elapsed time since last check + + + long elapsedTime = lastCheck > 0 ? (now - lastCheck) : 0; + + lastCheck = now; + + nextRecalculationInMS -= elapsedTime; + nextTimerRunInMS -= elapsedTime; + + //Need to execute our timer + + + if (nextTimerRunInMS <= 0) { + executeTimer(); + nextTimerRunInMS = TIMER_INTERVAL_IN_MS; + } + + //Time to iterate + if (nextRecalculationInMS <= 0) { + //We must recalculate our position now + iterateVivaldi(); + + //Determine when the next recalculation will be executed + nextRecalculationInMS = RECALCULATION_INTERVAL - RECALCULATION_EPSILON + (long)(2 * RECALCULATION_EPSILON * Math.random()); + } + + long nextCheck = nextTimerRunInMS > nextRecalculationInMS ? nextRecalculationInMS : nextTimerRunInMS; + + return nextCheck; + } + + public class KnownOSD { + + private String uuid; + private String strAddress; + private VivaldiCoordinates coordinates; + + public KnownOSD(String uuid, VivaldiCoordinates coordinates) { + this.uuid = uuid; + this.strAddress = null; + this.coordinates = coordinates; + } + + public String getUUID() { + return this.uuid; + } + + public VivaldiCoordinates getCoordinates() { + return this.coordinates; + } + + public String getStrAddress() { + return this.strAddress; + } + + public void setStrAddress(String strAddress) { + this.strAddress = strAddress; + } + + public void setCoordinates(VivaldiCoordinates newCoordinates) { + this.coordinates = newCoordinates; + } + } + + public class VivaldiRetry { + + private ArrayList prevRTTs; + private int numRetries; + private boolean retried; + + public VivaldiRetry() { + //New retry caused by a time out + prevRTTs = new ArrayList(); + numRetries = 1; + retried = false; + } + + public VivaldiRetry(long firstRTT) { + //New retry caused by a excessively big RTT + prevRTTs = new ArrayList(); + prevRTTs.add(firstRTT); + numRetries = 1; + retried = false; + } + + public ArrayList getRTTs() { + return prevRTTs; + } + + public void addRTT(long newRTT) { + prevRTTs.add(newRTT); + numRetries++; + } + + public void addTimeout() { + numRetries++; + } + + public int numberOfRetries() { + return numRetries; + } + + public void setRetried(boolean p) { + retried = p; + } + + public boolean hasBeenRetried() { + return retried; + } + } + + public class SentRequest { + + private long localTime; + private long systemTime; + + public SentRequest(long localTime, long systemTime) { + this.localTime = localTime; + this.systemTime = systemTime; + } + + public long getLocalTime() { + return this.localTime; + } + + public long getSystemTime() { + return this.systemTime; + } + } +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/CleanupThread.java b/java/servers/src/org/xtreemfs/osd/storage/CleanupThread.java new file mode 100644 index 0000000..2732c40 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/CleanupThread.java @@ -0,0 +1,573 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +import java.io.IOException; +import java.text.DateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.stages.DeletionStage; +import org.xtreemfs.osd.stages.PreprocStage.DeleteOnCloseCallback; +import org.xtreemfs.osd.storage.StorageLayout.FileData; +import org.xtreemfs.osd.storage.StorageLayout.FileList; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState; + +/** + * + * @author bjko + */ +public class CleanupThread extends LifeCycleThread { + // where zombies will be restored + public final static String DEFAULT_RESTORE_PATH = "lost+found"; + + // PATTERN for the output. Brackets are not allowed to be used at the format strings. + public final static String STATUS_FORMAT = "files checked: %8d zombies: %8d running since: %s"; + public final static String STOPPED_FORMAT = "not running, last check started %s"; + public final static String DEAD_VOLUME_FORMAT = "volume %s is dead - not registered at directory service"; + // public final static String DELETED_VOLUME_FORMAT = "volume %s was removed from MRC %s"; + public final static String VOLUME_RESULT_FORMAT = "volume %s had %8d zombies - out of %8d files checked"; + public final static String ERROR_FORMAT = "ERROR: cannot check volume %s , reason: %s"; + public final static String ZOMBIES_RESTORED_FORMAT = "%8d zombies restored to '"+DEFAULT_RESTORE_PATH+"' on volume %s"; + public final static String ZOMBIES_DELETED_FORMAT = "%8d zombies deleted from %s volume %s"; + public final static String ZOMBIE_DELETE_ERROR_FORMAT = "%s could not be deleted, because: %s"; + + private final OSDRequestDispatcher master; + + private volatile boolean isRunning; + + private volatile boolean quit; + + /** + * remove files for which no metadata exists. if false, zombies are just reported. + */ + private volatile boolean removeZombies; + + /** + * remove files if the volume does not exist at the DIR anymore. Can be dangerous if a volume is deregistered by + * accident. + */ + private volatile boolean removeDeadVolumes; + + /** + * if enabled, zombies will be moved to new files in a lost+found directory. + */ + private volatile boolean lostAndFound; + + private volatile boolean removeMetadata; + + private volatile int metaDataTimeoutS; + + private final List results; + + private final StorageLayout layout; + + private volatile long filesChecked; + + private final AtomicLong zombies; + + private volatile long startTime; + + private UserCredentials uc; + + final ServiceUUID localUUID; + + final MRCServiceClient mrcClient; + + private final AtomicLong openDeletes; + + public CleanupThread(OSDRequestDispatcher master, StorageLayout layout) { + super("CleanupThr"); + this.zombies = new AtomicLong(0L); + this.master = master; + this.isRunning = false; + this.quit = false; + this.layout = layout; + this.results = Collections.synchronizedList(new LinkedList()); + this.localUUID = master.getConfig().getUUID(); + this.startTime = 0L; + this.filesChecked = 0L; + this.mrcClient = new MRCServiceClient(master.getRPCClient(), null); + this.openDeletes = new AtomicLong(0L); + this.removeMetadata = false; + this.metaDataTimeoutS = 0; + } + + public boolean cleanupStart(boolean removeZombies, boolean removeDeadVolumes, boolean lostAndFound, + boolean removeMetaData, int metaDataTimeoutS, UserCredentials uc) { + + synchronized (this) { + if (isRunning) { + return false; + } else { + this.removeZombies = removeZombies; + this.removeDeadVolumes = removeDeadVolumes; + this.lostAndFound = lostAndFound; + this.removeMetadata = removeMetaData; + this.metaDataTimeoutS = metaDataTimeoutS; + this.uc = uc; + isRunning = true; + this.notify(); + return true; + } + } + } + + public void cleanupStop() { + synchronized (this) { + if (isRunning) { + isRunning = false; + } + } + } + + public boolean isRunning() { + synchronized (this) { + return isRunning; + } + } + + public List getResult() { + synchronized (this) { + return results; + } + } + + public String getStatus() { + synchronized (this) { + String d = DateFormat.getDateInstance().format(new Date(startTime)); + assert (d != null); + if (isRunning) { + return String.format(STATUS_FORMAT, + filesChecked, zombies.get(), d); + } else { + return String.format(STOPPED_FORMAT, d); + } + } + + } + + public void shutdown() { + synchronized (this) { + quit = true; + this.notifyAll(); + } + } + + public void run() { + notifyStarted(); + try { + do { + synchronized (this) { + if (!isRunning) + this.wait(); + if (quit) + break; + } + runCleanup(); + isRunning = false; + } while (!quit); + + } catch (Throwable thr) { + this.notifyCrashed(thr); + } + + notifyStopped(); + } + + + private void runCleanup() throws Throwable { + FileList l = null; + results.clear(); + filesChecked = 0; + zombies.set(0L); + startTime = TimeSync.getGlobalTime(); + + do { // while(l.hasMore) + + // Retrieve the fileList from the storage Layout. + l = layout.getFileList(l, 1024 * 4); + + // Map files to their corresponding volume. + final Map> perVolume = new Hashtable>(); + final Map> metaOnlyPerVolume = new Hashtable>(); + + for (String fileName : l.files.keySet()) { + filesChecked++; + String[] tmp = fileName.split(":"); + Volume v = new Volume(tmp[0]); + String fileId = tmp[1]; + + final Map> target; + if (l.files.get(fileName).metaDataOnly) { + target = metaOnlyPerVolume; + } else { + target = perVolume; + } + + List flist = target.get(v); + if (flist == null) { + flist = new LinkedList(); + target.put(v, flist); + } + + flist.add(fileId); + } + + // Interrupt execution if the cleanup has been stopped. + synchronized (this) { + if (!isRunning) + break; + } + + // Check for zombie files on each volume. + Map> zombieFilesPerVolume = new Hashtable>(); + // final List deleteableFiles = Collections.synchronizedList(new LinkedList()); + + for (Volume volume : perVolume.keySet()) { + final Map zombieFiles = new Hashtable(); + + try { + ServiceSet s = master.getDIRClient().xtreemfs_service_get_by_uuid(null, RPCAuthentication.authNone, + RPCAuthentication.userService, volume.id); + + if (s.getServicesCount() == 0) { + // Volume does not exist (is not registered at the DIR). + results.add(String.format(DEAD_VOLUME_FORMAT, volume.id)); + volume.dead(); + + } else { + + final boolean cowEnabled = false; // FIXME: fetch COW policy for current volume + + String mrcUUID = null; + for (KeyValuePair kvp : s.getServices(0).getData().getDataList()) { + if (kvp.getKey().equals("mrc")) + mrcUUID = kvp.getValue(); + } + volume.mrc = new ServiceUUID(mrcUUID); + + RPCResponse r = mrcClient.xtreemfs_check_file_exists( + volume.mrc.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + volume.id, perVolume.get(volume), localUUID.toString()); + xtreemfs_check_file_existsResponse response = r.get(); + r.freeBuffers(); + + + if (!response.getVolumeExists()) { + // Volume does not exist (is not found at the MRC VolumeManager), + // but it is still known to the DIR. The MRC volume removal DeleteVolumeOperation() + // deregisters volumes _after_ they are deleted from the database, therefore it is + // possible to end in this case. + results.add(String.format(DEAD_VOLUME_FORMAT, volume.id)); + volume.dead(); + + } else { + // Check all files from valid volumes. + List files = perVolume.get(volume); + final AtomicInteger numZombies = new AtomicInteger(0); + final AtomicInteger openOFTChecks = new AtomicInteger(0); + + for (int i = 0; i < files.size(); i++) { + final FILE_STATE fileState = response.getFileStates(i); + if (fileState == FILE_STATE.ABANDONED || fileState == FILE_STATE.DELETED) { + // remove abandoned replicas immediately + final boolean abandoned = (fileState == FILE_STATE.ABANDONED); + + // retrieve the fileName + final String fName = volume.id + ":" + files.get(i); + + // retrieve the fileData + final FileData fData = l.files.get(fName); + + // check against the OFT + openOFTChecks.incrementAndGet(); + master.getPreprocStage().checkDeleteOnClose(files.get(i), + new DeleteOnCloseCallback() { + @Override + public void deleteOnCloseResult(boolean isDeleteOnClose, + ErrorResponse error) { + + // file is zombie + if (!isDeleteOnClose && !abandoned) { + numZombies.incrementAndGet(); + zombies.incrementAndGet(); + zombieFiles.put(fName, fData); + } + + // deal with the unrestoreable replica + if (!isDeleteOnClose && abandoned) { + deleteFile(fName, cowEnabled); + } + + if (openOFTChecks.decrementAndGet() <= 0) { + synchronized (openOFTChecks) { + openOFTChecks.notify(); + } + } + } + }); + } + } + + synchronized (openOFTChecks) { + while (openOFTChecks.get() > 0) + openOFTChecks.wait(); + } + results.add(String.format(VOLUME_RESULT_FORMAT, volume.id, numZombies.get(), files.size())); + } + } + } catch (Exception ex) { + results.add(String.format(ERROR_FORMAT, volume.id, OutputUtils.stackTraceToString(ex))); + } + + // Handle dead volumes. + if (volume.isDead()) { + // Every file associated with a dead or deleted volume is a zombie. + List files = perVolume.get(volume); + for (int i = 0; i < files.size(); i++) { + // Retrieve the fileName and fileData and store them. + final String fName = volume.id + ":" + files.get(i); + final FileData fData = l.files.get(fName); + zombieFiles.put(fName, fData); + } + + // TODO(jdillmann): results.add... + } + + if (zombieFiles.size() != 0) { + zombieFilesPerVolume.put(volume, zombieFiles); + } + } // for (Volume volume : perVolume.keySet()) + + synchronized (this) { + if (!isRunning) + break; + } + + // deal with the zombies + for (Volume volume : zombieFilesPerVolume.keySet()) { + // restore files if the flag is set (files from dead volumes cannot be restored + if (!volume.isDead() && lostAndFound) { + Map zombieFiles = zombieFilesPerVolume.get(volume); + + for (String fileName : zombieFiles.keySet()) { + FileData data = zombieFiles.get(fileName); + if (!data.metaDataOnly) { + RPCResponse r = mrcClient.xtreemfs_restore_file(volume.mrc.getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, DEFAULT_RESTORE_PATH, + fileName, data.size, localUUID.toString(), + Integer.valueOf(String.valueOf(data.objectSize))); + + // the response does not matter + r.get(); + r.freeBuffers(); + + // TODO(jdillmann): clear stored xlocset, or send version to mrc... + } + } + + results.add(String.format(ZOMBIES_RESTORED_FORMAT, zombieFiles.keySet().size(), volume.id)); + + } else if ((volume.isDead() && removeDeadVolumes) || (!volume.isDead() && removeZombies)) { + // Delete all files of dead volumes if the flag is set + // or delete zombies if the flag is set. + Map zombieFiles = zombieFilesPerVolume.get(volume); + + final boolean cowEnabled = false; // FIXME: fetch COW policy for current volume + + for (final String fileName : zombieFiles.keySet()) { + deleteFile(fileName, cowEnabled); + } + + results.add(String.format(ZOMBIES_DELETED_FORMAT, zombieFiles.keySet().size(), + (volume.isDead() ? "dead" : "existing"), volume.id)); + } + } + + // Deal with metaData only directories. + if (removeMetadata) { + for (Volume volume : metaOnlyPerVolume.keySet()) { + final boolean cowEnabled = false; // FIXME: fetch COW policy for current volume + + List metaDataDirs = metaOnlyPerVolume.get(volume); + for (String fileId : metaDataDirs) { + // retrieve the fileName + final String fName = volume.id + ":" + fileId; + deleteFile(fName, cowEnabled); + } + // TODO(jdillmann): results.add(...) + // results.add(String.format(ZOMBIES_DELETED_FORMAT, zombieFiles.keySet().size(), + // (volume.isDead() ? "dead" : "existing"), volume.id)); + } + } + + synchronized (openDeletes) { + while (openDeletes.get() > 0) + openDeletes.wait(); + } + + synchronized (this) { + if (!isRunning) + break; + } + + } while (l.hasMore); + } + + + /** + * + * @param format + * @return a regular expression for retrieving the information build into a string made with the given format. + */ + public static String getRegex(String format) { + return format.replaceAll("\\+",".").replaceAll("%8d", "(\\\\s*\\\\d+)").replaceAll("%s", "([\\\\S\\\\p{Punct}]+)"); + } + + /** + * Pass the fileName to the deletion stage, which will eventually delete the file.
    + * The openDeletes variable will be updated on progress and notified if no more deletes are open.
    + * Errors will be stored in the results.
    + * Metadata will be deleted if the XLocVersionState happened longer then metaDataTimeoutS seconds before. + * + * @param fileName + * @param cowEnabled + */ + private void deleteFile(final String fileName, final boolean cowEnabled) { + boolean deleteMetadata; + try { + deleteMetadata = checkXLocVersionStateTimeout(fileName); + } catch (IOException e) { + deleteMetadata = false; + } + + openDeletes.incrementAndGet(); + + master.getDeletionStage().deleteObjects(fileName, null, cowEnabled, null, deleteMetadata, + new DeletionStage.DeleteObjectsCallback() { + + @Override + public void deleteComplete(ErrorResponse error) { + if (error != null) { + results.add(String.format(ZOMBIE_DELETE_ERROR_FORMAT, fileName, error.getErrorMessage())); + } + + if (openDeletes.decrementAndGet() <= 0) { + synchronized (openDeletes) { + openDeletes.notifyAll(); + } + } + } + }); + } + + /** + * Check if the XLocVersionState's last update happened more then metaDataTimeoutS seconds before. + * + * @param fileName + * @return + * @throws IOException + */ + private boolean checkXLocVersionStateTimeout(final String fileName) throws IOException { + if (!removeMetadata) { + return false; + } + + if (metaDataTimeoutS == 0) { + return true; + } + + if (metaDataTimeoutS > 0) { + long toTimeMs = TimeSync.getGlobalTime() - (metaDataTimeoutS * 1000); + XLocSetVersionState vs = layout.getXLocSetVersionState(fileName); + + // Delete the metaData if the version is too old. + if (!vs.hasModifiedTime() || vs.getModifiedTime() < toTimeMs) { + return true; + } else { + return false; + } + } + + return false; + } + + /** + * Contains VolumeId and MRC Address. + * + * 23.04.2009 + * @author flangner + */ + public class Volume { + final String id; + ServiceUUID mrc = null; + boolean dead = false; + boolean deleted = false; + + /** + * Constructor for Volumes with unknown MRC. + */ + Volume(String volId) { + this.id = volId; + } + + /** + * to mark dead volumes. + */ + void dead() { + this.dead = true; + } + + boolean isDead() { + return this.dead; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof Volume)) + return false; + return id.equals(((Volume) obj).id); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return this.id.hashCode(); + } + } +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/CleanupVersionsThread.java b/java/servers/src/org/xtreemfs/osd/storage/CleanupVersionsThread.java new file mode 100644 index 0000000..00cacce --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/CleanupVersionsThread.java @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +import java.text.DateFormat; +import java.util.Date; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.Map.Entry; + +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.RAID0Impl; +import org.xtreemfs.foundation.LifeCycleThread; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.storage.StorageLayout.FileList; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse; + +/** + * + * @author bjko + */ +public class CleanupVersionsThread extends LifeCycleThread { + + // PATTERN for the output. Brackets are not allowed to be used at the format + // strings. + public final static String STATUS_FORMAT = "files checked: %8d versions deleted: %8d running since: %s"; + + public final static String STOPPED_FORMAT = "not running, last check started %s"; + + private final OSDRequestDispatcher master; + + private volatile boolean isRunning; + + private volatile boolean quit; + + private final StorageLayout layout; + + private volatile long filesChecked; + + private volatile long versionsRemoved; + + private volatile long startTime; + + private UserCredentials uc; + + final ServiceUUID localUUID; + + public CleanupVersionsThread(OSDRequestDispatcher master, StorageLayout layout) { + super("CleanupVThr"); + this.master = master; + this.isRunning = false; + this.quit = false; + this.layout = layout; + this.localUUID = master.getConfig().getUUID(); + this.startTime = 0L; + this.filesChecked = 0L; + this.versionsRemoved = 0L; + } + + public boolean cleanupStart(UserCredentials uc) { + synchronized (this) { + if (isRunning) { + return false; + } else { + this.uc = uc; + isRunning = true; + this.notify(); + return true; + } + } + } + + public void cleanupStop() { + synchronized (this) { + if (isRunning) { + isRunning = false; + } + } + } + + public boolean isRunning() { + synchronized (this) { + return isRunning; + } + } + + public String getStatus() { + synchronized (this) { + String d = DateFormat.getDateInstance().format(new Date(startTime)); + assert (d != null); + if (isRunning) { + return String.format(STATUS_FORMAT, filesChecked, versionsRemoved, d); + } else { + return String.format(STOPPED_FORMAT, d); + } + } + + } + + public void shutdown() { + synchronized (this) { + quit = true; + this.notifyAll(); + } + } + + public void run() { + notifyStarted(); + try { + + do { + synchronized (this) { + if (!isRunning) + this.wait(); + if (quit) + break; + } + FileList l = null; + filesChecked = 0; + startTime = TimeSync.getGlobalTime(); + final MRCServiceClient mrcClient = new MRCServiceClient(master.getRPCClient(), null); + + // first, determine all snapshot timestamps + volumes for all + // files + + // volume -> set of file IDs + Map> perVolume = new Hashtable>(); + + do { + + l = layout.getFileList(l, 1024 * 4); + + for (String fileName : l.files.keySet()) { + + filesChecked++; + + // parse volume and file ID + String[] tmp = fileName.split(":"); + String volId = tmp[0]; + String fileId = tmp[1]; + + // create a new volume and add it to the map if + // necessary + Volume vol = new Volume(volId); + List flist = perVolume.get(vol); + + // if the volume doesn't exist in the map yet ... + if (flist == null) { + + // determine the list of snapshot timestamps for the + // volume + + // first, determine the volume name + ServiceSet s = master.getDIRClient().xtreemfs_service_get_by_uuid( + null, RPCAuthentication.authNone, RPCAuthentication.userService, vol.id); + if (s.getServicesCount() == 0) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, + "could not retrieve volume information for '%s' from DIR", vol.id); + continue; + } + + // get the MRC responsible for the volume + String volName = s.getServices(0).getName(); + vol.mrc = new ServiceUUID(KeyValuePairs.getValue(s.getServices(0).getData() + .getDataList(), "mrc")); + + // get the list of snapshot timestamps for the + // volume + RPCResponse tsResponse = null; + String ts = null; + try { + + tsResponse = mrcClient.getxattr(vol.mrc.getAddress(), + RPCAuthentication.authNone, uc, getxattrRequest.newBuilder() + .setVolumeName(volName).setPath("").setName( + "xtreemfs.snapshot_time").build()); + ts = tsResponse.get().getValue(); + + StringTokenizer st = new StringTokenizer(ts); + long[] tsArray = new long[st.countTokens()]; + for (int i = 0; i < tsArray.length; i++) + tsArray[i] = Long.parseLong(st.nextToken()); + + vol.timestamps = tsArray; + + // add the volume entry to the map + flist = new LinkedList(); + perVolume.put(vol, flist); + + } finally { + if (tsResponse != null) + tsResponse.freeBuffers(); + } + + } + + flist.add(fileId); + + synchronized (this) { + if (!isRunning) + break; + } + + } + + synchronized (this) { + if (!isRunning) + break; + } + + } while (l.hasMore); + + // check each volume + for (Entry> entry : perVolume.entrySet()) { + + long[] timestamps = entry.getKey().timestamps; + List files = entry.getValue(); + + for (String fileId : files) { + + fileId = entry.getKey().id + ":" + fileId; + + // get the metadata; provide any striping policy + // (doesn't matter here ...) + FileMetadata md = layout.getFileMetadataNoCaching(RAID0Impl.getPolicy(Replica + .newBuilder().setReplicationFlags(0).setStripingPolicy( + StripingPolicy.newBuilder().setType( + StripingPolicyType.STRIPING_POLICY_RAID0).setStripeSize(128) + .setWidth(1).build()).build(), 0), fileId); + + // determine the set of versions to delete + Map> versionsToDelete = md.getVersionTable() + .cleanup(timestamps); + + // delete the objects + for (Entry> v : versionsToDelete.entrySet()) + for (int version : v.getValue()) { + + // delete the object version if it is not part + // of the file's current version + if (md.getLatestObjectVersion(v.getKey()) != version) + layout.deleteObject(fileId, md, v.getKey(), version); + } + + // save the updated version table + if (versionsToDelete.size() != 0) + md.getVersionTable().save(); + + synchronized (this) { + if (!isRunning) + break; + } + } + + } + + synchronized (this) { + if (!isRunning) + break; + } + + isRunning = false; + + } while (!quit); + + } catch (Exception thr) { + Logging.logError(Logging.LEVEL_ERROR, this, thr); + } + + notifyStopped(); + } + + public class Volume { + + final String id; + + ServiceUUID mrc = null; + + long[] timestamps; + + /** + * Constructor for Volumes with unknown MRC. + */ + Volume(String volId) { + this.id = volId; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof Volume)) + return false; + return id.equals(((Volume) obj).id); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return this.id.hashCode(); + } + } +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/CowPolicy.java b/java/servers/src/org/xtreemfs/osd/storage/CowPolicy.java new file mode 100644 index 0000000..5f9d345 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/CowPolicy.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +/** + * This class implements differen copy-on-write strategies. + * + * @author bjko + */ +public class CowPolicy { + + public static final CowPolicy PolicyNoCow = new CowPolicy(cowMode.NO_COW); + + public enum cowMode { + /** + * Do not copy on write, overwrite instead. + */ + NO_COW, + /** + * Create a copy only for the first write after open, then overwrite for + * each subsequent request. + */ + COW_ONCE, + /** + * Copy-on-write for all write requests. + */ + ALWAYS_COW + }; + + /** + * CoW mode to use + */ + private final cowMode mode; + + /** + * The initial number of objects. Required for COW_ONCE mode. + */ + private long initialObjectCount; + + /** + * per-object flag which indicates if the object has already been copied + * (for COW_ONCE mode). Each bit is used + */ + private byte[] cowFlags; + + /** + * Create a new cowPolicy + * + * @param mode + * the COW mode + */ + public CowPolicy(cowMode mode) { + this.mode = mode; + } + + /** + * Initializes the COW flags if necessary. + * + * @param objectCount + * the current number of objects + */ + public void initCowFlagsIfRequired(long objectCount) { + + if (mode == cowMode.COW_ONCE && cowFlags == null) { + + assert (objectCount / Byte.SIZE < Integer.MAX_VALUE) : "number of objects for COW_ONCE file (" + + objectCount + ") exceeds limit (" + Integer.MAX_VALUE * Byte.SIZE + ")"; + + final int fieldLen = (int) Math.ceil((double) objectCount / Byte.SIZE); + cowFlags = new byte[fieldLen]; + initialObjectCount = objectCount; + } + } + + /** + * Checks if an object must be copied before writing + * + * @param objectNumber + * the object to be modified + * @return true, if a new version must be created + */ + private boolean requiresCow(int objectNumber) { + + assert (mode == cowMode.COW_ONCE); + assert (cowFlags != null); + + // new objects do not need copy-on-write ;-) + if (objectNumber >= initialObjectCount) + return false; + + final int field = objectNumber / Byte.SIZE; + final int bit = objectNumber % Byte.SIZE; + return (cowFlags[field] & (0x0001 << bit)) == 0; + } + + /** + * Checks if copy-on-write is necessary for an object + * + * @param objectNumber + * the object to be modified + * @return true, if a new version must be created + */ + public boolean isCOW(int objectNumber) { + return ((mode != cowMode.NO_COW) && ((mode == cowMode.ALWAYS_COW) || requiresCow(objectNumber))); + } + + /** + * Checks if copy-on-write is generally enabled. + * + * @return true, if a COW mode other than NO_COW was assigned to the policy + */ + public boolean cowEnabled() { + return mode != cowMode.NO_COW; + } + + /** + * toggels the written flag for an object if in COW_ONMCE mode + * + * @param objectNumber + * the object which was modified + */ + public void objectChanged(int objectNumber) { + + // ignore new objects + if ((mode == cowMode.COW_ONCE) && (objectNumber < initialObjectCount)) { + assert (cowFlags != null); + final int field = objectNumber / Byte.SIZE; + final int bit = objectNumber % Byte.SIZE; + cowFlags[field] = (byte) (cowFlags[field] | (0x01 << bit)); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/FileMetadata.java b/java/servers/src/org/xtreemfs/osd/storage/FileMetadata.java new file mode 100644 index 0000000..0e1c3a2 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/FileMetadata.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2008-2011 by Eugenio Cesario, Bjoern Kolbeck, Christian Lorenz + * Zuse Institute Berlin, Consiglio Nazionale delle Ricerche + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +import java.io.RandomAccessFile; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.xtreemfs.common.xloc.StripingPolicyImpl; + +/** + * + * @author bjko + */ +public class FileMetadata { + + private Map latestObjVersions; + + private Map largestObjVersions; + + private Map> objChecksums; + + private long filesize; + + private long lastObjectNumber; + + private long globalLastObjectNumber; + + private long truncateEpoch; + + private final StripingPolicyImpl stripingPolicy; + + private VersionTable versionTable; + + private RandomAccessFile[] handles; + + private long mdFileLength; + + /** Creates a new instance of FileInfo */ + public FileMetadata(StripingPolicyImpl sp) { + stripingPolicy = sp; + } + + public long getFilesize() { + return filesize; + } + + public void setFilesize(long filesize) { + this.filesize = filesize; + } + + public long getLastObjectNumber() { + return lastObjectNumber; + } + + public void setLastObjectNumber(long lastObjectNumber) { + this.lastObjectNumber = lastObjectNumber; + } + + public long getLargestObjectVersion(long objId) { + Long v = largestObjVersions.get(objId); + return (v == null) ? 0 : v; + } + + public long getLatestObjectVersion(long objId) { + Long v = latestObjVersions.get(objId); + return (v == null) ? 0 : v; + } + + public Long getObjectChecksum(long objId, long objVer) { + + Map checksums = objChecksums.get(objId); + if (checksums == null) + return 0L; + + Long c = checksums.get(objVer); + return (c == null) ? 0 : c; + } + + public Set> getLatestObjectVersions() { + return latestObjVersions.entrySet(); + } + + public void clearLatestObjectVersions() { + latestObjVersions.clear(); + } + + public void initLargestObjectVersions(Map largestObjVersions) { + assert (this.largestObjVersions == null); + this.largestObjVersions = largestObjVersions; + } + + public void initLatestObjectVersions(Map latestObjVersions) { + assert (this.latestObjVersions == null); + this.latestObjVersions = latestObjVersions; + } + + public void initObjectChecksums(Map> objChecksums) { + assert (this.objChecksums == null); + this.objChecksums = objChecksums; + } + + public void initVersionTable(VersionTable versionTable) { + assert (this.versionTable == null); + this.versionTable = versionTable; + } + + public void updateObjectVersion(long objId, long newVersion) { + + latestObjVersions.put(objId, newVersion); + + if (largestObjVersions != latestObjVersions && newVersion != 0) + largestObjVersions.put(objId, newVersion); + + } + + public void updateObjectChecksum(long objId, long objVer, long newChecksum) { + + Map checksums = objChecksums.get(objId); + if (checksums == null) { + checksums = new HashMap(); + objChecksums.put(objId, checksums); + } + + checksums.put(objVer, newChecksum); + } + + public void discardObject(long objId, long objVer) { + latestObjVersions.remove(objId); + objChecksums.remove(objId + "." + objVer); + } + + public String toString() { + return "(fileSize=" + filesize + ", lastObjNo=" + lastObjectNumber + ")"; + } + + public long getTruncateEpoch() { + return truncateEpoch; + } + + public void setTruncateEpoch(long truncateEpoch) { + this.truncateEpoch = truncateEpoch; + } + + /** + * @return the globalLastObjectNumber + */ + public long getGlobalLastObjectNumber() { + return globalLastObjectNumber; + } + + /** + * @param globalLastObjectNumber + * the globalLastObjectNumber to set + */ + public void setGlobalLastObjectNumber(long globalLastObjectNumber) { + this.globalLastObjectNumber = globalLastObjectNumber; + } + + /** + * @return the stripingPolicy + */ + public StripingPolicyImpl getStripingPolicy() { + return stripingPolicy; + } + + public VersionTable getVersionTable() { + return versionTable; + } + + /** + * @return the handles + */ + public RandomAccessFile[] getHandles() { + return handles; + } + + /** + * @param handles the handles to set + */ + public void setHandles(RandomAccessFile[] handles) { + this.handles = handles; + } + + /** + * @return the mdFileLength + */ + public long getMdFileLength() { + return mdFileLength; + } + + /** + * @param mdFileLength the mdFileLength to set + */ + public void setMdFileLength(long mdFileLength) { + this.mdFileLength = mdFileLength; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/HashStorageLayout.java b/java/servers/src/org/xtreemfs/osd/storage/HashStorageLayout.java new file mode 100644 index 0000000..da1ac04 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/HashStorageLayout.java @@ -0,0 +1,1436 @@ +/* + * Copyright (c) 2009-2011 by Christian Lorenz, Bjoern Kolbeck, + Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +import java.io.EOFException; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.EmptyStackException; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.foundation.LRUCache; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.checksums.ChecksumAlgorithm; +import org.xtreemfs.foundation.checksums.ChecksumFactory; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState; + +/** + * + * @author clorenz + */ +public class HashStorageLayout extends StorageLayout { + + /** + * file to store the truncate epoch in (metadata) + */ + public static final String TEPOCH_FILENAME = ".tepoch"; + + /** + * File to store the master epoch. + */ + public static final String MASTER_EPOCH_FILENAME = ".mepoch"; + + public static final String TRUNCATE_LOG_FILENAME = ".tlog"; + + /** + * file that stores the mapping between file and object versions + */ + public static final String VTABLE_FILENAME = ".vtable"; + + /** + * file that stores the mapping between file and object versions + */ + public static final String CURRENT_VER_FILENAME = ".curr_file_ver"; + + /** + * file that stores the latest XLocSet version this replica belonged to and if it is invalidated + */ + public static final String XLOC_VERSION_STATE_FILENAME = ".version_state"; + + public static final int SL_TAG = 0x00000002; + + /** 32bit algorithm */ + public static final String JAVA_HASH = "Java-Hash"; + + /** 64bit algorithm */ + public static final String SDBM_HASH = "SDBM"; + + public static final int SUBDIRS_16 = 15; + + public static final int SUBDIRS_256 = 255; + + public static final int SUBDIRS_4096 = 4095; + + public static final int SUBDIRS_65535 = 65534; + + public static final int SUBDIRS_1048576 = 1048575; + + public static final int SUBDIRS_16777216 = 16777215; + + public static final String DEFAULT_HASH = JAVA_HASH; + + private static final int DEFAULT_SUBDIRS = SUBDIRS_256; + + private static final int DEFAULT_MAX_DIR_DEPTH = 4; + + private int prefixLength; + + private int hashCutLength; + + private ChecksumAlgorithm checksumAlgo; + + private long _stat_fileInfoLoads; + + private final boolean checksumsEnabled; + + private final LRUCache hashedPathCache; + + private static final boolean USE_PATH_CACHE = true; + + /** + * An incomplete read may be caused by a bad sector. This parameter defines how often the OSD should retry + * to read the data as the disk firmware might remap the sector in the meantime / recover the data. + */ + private static final int RETRIES_INCOMPLETE_READ = 2; + + private static final String ERROR_MESSAGE_INCOMPLETE_READ = "Failed to read the requested number of bytes from the file on disk. Maybe there's a media error or the file was modified outside the scope of the OSD by another process?"; + + private final LRUCache xLocSetVSCache; + + /** Creates a new instance of HashStorageLayout */ + public HashStorageLayout(OSDConfig config, MetadataCache cache) throws IOException { + this(config, cache, DEFAULT_HASH, DEFAULT_SUBDIRS, DEFAULT_MAX_DIR_DEPTH); + } + + /** + * Creates a new instance of HashStorageLayout. If some value is incorrect, the default value will be + * used. + * + * @param config + * @param hashAlgo + * @param maxSubdirsPerDir + * @param maxDirDepth + * @throws IOException + */ + public HashStorageLayout(OSDConfig config, MetadataCache cache, String hashAlgo, int maxSubdirsPerDir, + int maxDirDepth) throws IOException { + + super(config, cache); + + /* + * if (hashAlgo.equals(JAVA_HASH)) { this.hashAlgo = new JavaHash(); }else if + * (hashAlgo.equals(SDBM_HASH)) { this.hashAlgo = new SDBM(); } + */ + + this.checksumsEnabled = config.isUseChecksums(); + if (config.isUseChecksums()) { + + // get the algorithm from the factory + try { + checksumAlgo = ChecksumFactory.getInstance().getAlgorithm(config.getChecksumProvider()); + if (checksumAlgo == null) + throw new NoSuchAlgorithmException("algo is null"); + } catch (NoSuchAlgorithmException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "could not instantiate checksum algorithm '%s'", config.getChecksumProvider()); + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "OSD checksums will be switched off"); + } + } + + if (maxSubdirsPerDir != 0) { + this.prefixLength = Integer.toHexString(maxSubdirsPerDir).length(); + } else { + this.prefixLength = Integer.toHexString(DEFAULT_SUBDIRS).length(); + } + + if (maxDirDepth != 0) { + this.hashCutLength = maxDirDepth * this.prefixLength; + } else { + this.hashCutLength = DEFAULT_MAX_DIR_DEPTH * this.prefixLength; + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "initialized with checksums=%s prefixLen=%d", + this.checksumsEnabled, this.prefixLength); + } + + _stat_fileInfoLoads = 0; + + hashedPathCache = new LRUCache(2048); + + xLocSetVSCache = new LRUCache(2048); + } + + @Override + public ObjectInformation readObject(String fileId, FileMetadata md, long objNo, int offset, int length, + long version) throws IOException { + + final int stripeSize = md.getStripingPolicy().getStripeSizeForObject(objNo); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, + "fetching object %s-%d from disk", fileId, objNo); + } + + ReusableBuffer bbuf = null; + boolean checkChecksum = false; + + if (length == -1) { + assert (offset == 0) : "if length is -1 offset must be 0 but is " + offset; + length = stripeSize; + if (checksumsEnabled) { + // Check checksum only if -1 was supplied as length. Fortunately, only xtfs_scrub uses this + // parameter effectively skipping the expensive checksum check for regular operations. + checkChecksum = true; + } + } + + if (version == 0) { + // object does not exist + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, + "object does not exist (according to md cache)"); + } + return new ObjectInformation(ObjectInformation.ObjectStatus.DOES_NOT_EXIST, null, stripeSize); + } + + final long oldChecksum = md.getObjectChecksum(objNo, version); + String fileName = generateAbsoluteObjectPathFromFileId(fileId, objNo, version, oldChecksum); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, "path to object on disk: %s", + fileName); + } + + File file = new File(fileName); + + if (file.exists()) { + + RandomAccessFile f = new RandomAccessFile(file, "r"); + + final int flength = (int) f.length(); + + try { + if (flength == 0) { + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, + "object %d is a padding object", objNo); + } + + return new ObjectInformation(ObjectInformation.ObjectStatus.PADDING_OBJECT, null, + stripeSize); + + } else if (flength <= offset) { + + bbuf = BufferPool.allocate(0); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, + "object %d is read at an offset beyond its size", objNo); + } + + return new ObjectInformation(ObjectInformation.ObjectStatus.EXISTS, bbuf, stripeSize); + + } else { + + // read object data + int lastoffset = offset + length; + assert (lastoffset <= stripeSize); + + if (lastoffset > flength) { + assert (flength - offset > 0); + bbuf = BufferPool.allocate(flength - offset); + } else { + bbuf = BufferPool.allocate(length); + } + + for (int attempt = 0; attempt <= RETRIES_INCOMPLETE_READ; attempt++) { + if (attempt > 0) { + bbuf.position(0); + Logging.logMessage( + Logging.LEVEL_INFO, + Category.storage, + this, + "Retrying to read object from disk since it failed before (retry %d/%d). Path to the file on disk: %s", + attempt, RETRIES_INCOMPLETE_READ, fileName); + } + + f.getChannel().position(offset); + f.getChannel().read(bbuf.getBuffer()); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, + "object %d is read at offset %d, %d bytes read, attempt: %d", objNo, + offset, bbuf.limit(), attempt); + } + + if (bbuf.hasRemaining()) { + if (attempt == 0) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "%s Path to the file on disk: %s", ERROR_MESSAGE_INCOMPLETE_READ, + fileName); + } + } else { + if (attempt > 0) { + Logging.logMessage( + Logging.LEVEL_ERROR, + Category.storage, + this, + "Successfully read object from disk at retry %d after previous failures. Path to the file on disk: %s", + attempt, fileName); + } + break; + } + + if (attempt == RETRIES_INCOMPLETE_READ) { + throw new IOException(ERROR_MESSAGE_INCOMPLETE_READ); + } + } + + f.close(); + + bbuf.position(0); + ObjectInformation oInfo = new ObjectInformation(ObjectInformation.ObjectStatus.EXISTS, + bbuf, stripeSize); + + if (checkChecksum) { + ReusableBuffer bbufCopy = bbuf.createViewBuffer(); + checksumAlgo.reset(); + checksumAlgo.update(bbufCopy.getBuffer()); + BufferPool.free(bbufCopy); + long newChecksum = checksumAlgo.getValue(); + oInfo.setChecksumInvalidOnOSD(newChecksum != oldChecksum); + } + + return oInfo; + } + } catch (Exception e) { + if (bbuf != null) { + BufferPool.free(bbuf); + } + + if (e instanceof IOException) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "Failed to read object file from disk. Error: %s Path to the file on disk: %s", + e.getMessage(), fileName); + throw (IOException) e; + } else { + throw new IOException(e); + } + } finally { + f.close(); + } + + } else { + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, "object %d does not exist", + objNo); + } + + return new ObjectInformation(ObjectInformation.ObjectStatus.DOES_NOT_EXIST, null, stripeSize); + } + } + + @Override + public void writeObject(String fileId, FileMetadata md, ReusableBuffer data, long objNo, int offset, + long newVersion, boolean sync, boolean cow) throws IOException { + + assert (newVersion > 0) : "object version must be > 0"; + + if (data.capacity() == 0) { + return; + } + + String relPath = generateRelativeFilePath(fileId); + new File(this.storageDir + relPath).mkdirs(); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, + "writing object %s-%d to disk: %s", fileId, objNo, relPath); + } + + try { + + final boolean isRangeWrite = (offset > 0) + || (data.capacity() < md.getStripingPolicy().getStripeSizeForObject(objNo)); + if (isRangeWrite) { + if (cow || checksumsEnabled) { + partialWriteCOW(relPath, fileId, md, data, offset, objNo, newVersion, sync, !cow); + } else { + partialWriteNoCOW(relPath, fileId, md, data, objNo, offset, newVersion, sync); + } + } else { + completeWrite(relPath, fileId, md, data, objNo, newVersion, sync, !cow); + } + + } catch (FileNotFoundException ex) { + throw new IOException("unable to create file directory or object: " + ex.getMessage()); + } + } + + private void partialWriteCOW(String relativePath, String fileId, FileMetadata md, ReusableBuffer data, + int offset, long objNo, long newVersion, boolean sync, boolean deleteOldVersion) + throws IOException { + // write file + + assert (data != null); + + final long oldVersion = md.getLatestObjectVersion(objNo); + final long oldChecksum = md.getObjectChecksum(objNo, oldVersion); + + ReusableBuffer fullObj = cow(fileId, md, objNo, data, offset, oldVersion); + + long newChecksum = 0; + if (checksumsEnabled) { + checksumAlgo.reset(); + checksumAlgo.update(fullObj.getBuffer()); + newChecksum = checksumAlgo.getValue(); + } + final String newFilename = generateAbsoluteObjectPathFromRelPath(relativePath, objNo, newVersion, + newChecksum); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "writing to file (COW): %s", newFilename); + } + File file = new File(newFilename); + String mode = sync ? "rwd" : "rw"; + RandomAccessFile f = null; + + try { + f = new RandomAccessFile(file, mode); + fullObj.position(0); + f.getChannel().write(fullObj.getBuffer()); + } catch (IOException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "Failed to write object file to disk. Error: %s Path to the file on disk: %s", + e.getMessage(), newFilename); + throw e; + } finally { + if (f != null) { + f.close(); + } + BufferPool.free(fullObj); + } + + if (deleteOldVersion) { + String oldFilename = generateAbsoluteObjectPathFromRelPath(relativePath, objNo, oldVersion, + oldChecksum); + File oldFile = new File(oldFilename); + oldFile.delete(); + } + + md.updateObjectVersion(objNo, newVersion); + md.updateObjectChecksum(objNo, newVersion, newChecksum); + } + + private void partialWriteNoCOW(String relativePath, String fileId, FileMetadata md, ReusableBuffer data, + long objNo, int offset, long newVersion, boolean sync) throws IOException { + // write file + assert (!checksumsEnabled); + + final long oldVersion = md.getLatestObjectVersion(objNo); + final String filename = generateAbsoluteObjectPathFromRelPath(relativePath, objNo, oldVersion, 0l); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "writing to file: %s", filename); + } + File file = new File(filename); + String mode = sync ? "rwd" : "rw"; + RandomAccessFile f = null; + + try { + f = new RandomAccessFile(file, mode); + data.position(0); + f.seek(offset); + f.getChannel().write(data.getBuffer()); + } catch (IOException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.storage, this, + "Failed to write object file to disk. Error: %s Path to the file on disk: %s", + e.getMessage(), filename); + throw e; + } finally { + if (f != null) { + f.close(); + } + BufferPool.free(data); + } + + if (newVersion != oldVersion) { + String newFilename = generateAbsoluteObjectPathFromRelPath(relativePath, objNo, newVersion, 0l); + file.renameTo(new File(newFilename)); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "renamed to: %s", newFilename); + } + md.updateObjectVersion(objNo, newVersion); + } + } + + private void completeWrite(String relativePath, String fileId, FileMetadata md, ReusableBuffer data, + long objNo, long newVersion, boolean sync, boolean deleteOldVersion) throws IOException { + // write file + + final long oldVersion = md.getLatestObjectVersion(objNo); + final long oldChecksum = md.getObjectChecksum(objNo, oldVersion); + + long newChecksum = 0; + if (checksumsEnabled) { + checksumAlgo.reset(); + checksumAlgo.update(data.getBuffer()); + newChecksum = checksumAlgo.getValue(); + } + final String newFilename = generateAbsoluteObjectPathFromRelPath(relativePath, objNo, newVersion, + newChecksum); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "writing to file: %s", newFilename); + } + File file = new File(newFilename); + String mode = sync ? "rwd" : "rw"; + RandomAccessFile f = null; + + try { + f = new RandomAccessFile(file, mode); + data.position(0); + f.getChannel().write(data.getBuffer()); + } finally { + if (f != null) { + f.close(); + } + BufferPool.free(data); + } + + if (((oldVersion != newVersion) || (newChecksum != oldChecksum)) && (deleteOldVersion)) { + String oldFilename = generateAbsoluteObjectPathFromRelPath(relativePath, objNo, oldVersion, + oldChecksum); + File oldFile = new File(oldFilename); + oldFile.delete(); + } + + md.updateObjectVersion(objNo, newVersion); + + if (checksumsEnabled) + md.updateObjectChecksum(objNo, newVersion, newChecksum); + } + + @Override + public void updateCurrentObjVersion(String fileId, long objNo, long newVersion) throws IOException { + + File file = new File(generateAbsoluteFilePath(fileId), CURRENT_VER_FILENAME); + if (!file.exists()) + file.createNewFile(); + + RandomAccessFile versionFile = null; + try { + versionFile = new RandomAccessFile(file, "rw"); + versionFile.seek(objNo * Long.SIZE / 8); + versionFile.writeLong(newVersion); + } finally { + if (versionFile != null) { + versionFile.close(); + } + } + } + + @Override + public void updateCurrentVersionSize(String fileId, long newLastObject) throws IOException { + + File file = new File(generateAbsoluteFilePath(fileId), CURRENT_VER_FILENAME); + if (!file.exists()) + file.createNewFile(); + + RandomAccessFile versionFile = null; + try { + versionFile = new RandomAccessFile(file, "rw"); + versionFile.setLength((newLastObject + 1) * Long.SIZE / 8); + } finally { + versionFile.close(); + } + } + + @Override + public void truncateObject(String fileId, FileMetadata md, long objNo, int newLength, long newVersion, + boolean cow) throws IOException { + + final long oldVersion = md.getLatestObjectVersion(objNo); + final long oldChecksum = md.getObjectChecksum(objNo, oldVersion); + + assert (newLength <= md.getStripingPolicy().getStripeSizeForObject(objNo)); + + String oldFileName = generateAbsoluteObjectPathFromFileId(fileId, objNo, oldVersion, oldChecksum); + File oldFile = new File(oldFileName); + final long currentLength = oldFile.length(); + + String mode = "rw"; + + if (newLength == currentLength) { + return; + } + + if (cow || checksumsEnabled) { + ReusableBuffer oldData = unwrapObjectData(fileId, md, objNo, oldVersion); + + if (newLength < oldData.capacity()) { + oldData.range(0, newLength); + } else { + ReusableBuffer newData = BufferPool.allocate(newLength); + newData.put(oldData); + while (newData.hasRemaining()) { + newData.put((byte) 0); + } + BufferPool.free(oldData); + oldData = newData; + } + oldData.position(0); + + long newChecksum = 0l; + if (checksumsEnabled) { + // calc checksum + checksumAlgo.update(oldData.getBuffer()); + newChecksum = checksumAlgo.getValue(); + } + + if (!cow) { + oldFile.delete(); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, + "truncate object %d, delete old version %d: %s", objNo, oldVersion, oldFileName); + } + } + + String newFilename = generateAbsoluteObjectPathFromFileId(fileId, objNo, newVersion, newChecksum); + RandomAccessFile raf = null; + try { + raf = new RandomAccessFile(newFilename, mode); + raf.getChannel().write(oldData.getBuffer()); + } finally { + if (raf != null) { + raf.close(); + } + BufferPool.free(oldData); + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, + "truncate object %d, wrote new version %d: %s", objNo, newVersion, newFilename); + } + + md.updateObjectVersion(objNo, newVersion); + if (checksumsEnabled) + md.updateObjectChecksum(objNo, newVersion, newChecksum); + + } else { + // just make the object shorter + RandomAccessFile raf = null; + try { + raf = new RandomAccessFile(oldFile, mode); + raf.setLength(newLength); + } finally { + if (raf != null) { + raf.close(); + } + } + if (newVersion != oldVersion) { + String newFilename = generateAbsoluteObjectPathFromFileId(fileId, objNo, newVersion, 0l); + oldFile.renameTo(new File(newFilename)); + md.updateObjectVersion(objNo, newVersion); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, + "truncate object %d, renamed file for new version %d: %s", objNo, newVersion, + newFilename); + } + } + } + } + + @Override + public void createPaddingObject(String fileId, FileMetadata md, long objNo, long version, int size) + throws IOException { + + assert (size >= 0) : "size is " + size; + + String relPath = generateRelativeFilePath(fileId); + new File(this.storageDir + relPath).mkdirs(); + + // calculate the checksum for the padding object if necessary + long checksum = 0; + if (checksumAlgo != null) { + byte[] content = new byte[size]; + checksumAlgo.update(ByteBuffer.wrap(content)); + checksum = checksumAlgo.getValue(); + } + + // write file + String filename = generateAbsoluteObjectPathFromRelPath(relPath, objNo, version, checksum); + RandomAccessFile raf = null; + try { + raf = new RandomAccessFile(filename, "rw"); + raf.setLength(size); + } finally { + if (raf != null) { + raf.close(); + } + } + + md.updateObjectVersion(objNo, version); + + if (checksumsEnabled) + md.updateObjectChecksum(objNo, version, checksum); + } + + @Override + public void deleteFile(String fileId, final boolean deleteMetadata) throws IOException { + File fileDir = new File(generateAbsoluteFilePath(fileId)); + + // Filter metadata from the fileList, if deleteMetadata is not set. + File[] fileList = fileDir.listFiles(new FileFilter() { + + @Override + public boolean accept(File pathname) { + if (!deleteMetadata && pathname.getName().startsWith(".")) { + return false; + } + + return true; + } + }); + + // Stop the execution if the directory does not exist. + if (fileList == null) { + return; + } + + // Delete the filtered files. + for (File file : fileList) { + file.delete(); + } + + // Try to delete the data directory if it is empty. + if (deleteMetadata) { + del(fileDir); + } + } + + private void del(File parent) { + File storageDirFile = new File(this.storageDir); + for (File p = parent; p != null && p.list().length <= 1 && !p.equals(storageDirFile); p = p + .getParentFile()) { + parent.delete(); + } + } + + @Override + public void deleteObject(String fileId, FileMetadata md, final long objNo, long version) + throws IOException { + final long verToDel = (version == LATEST_VERSION) ? md.getLatestObjectVersion(objNo) : version; + File fileDir = new File(generateAbsoluteFilePath(fileId)); + File[] objs = fileDir.listFiles(new FileFilter() { + + @Override + public boolean accept(File pathname) { + if (pathname.getName().startsWith(".")) { + return false; + } + ObjFileData ofd = parseFileName(pathname.getName()); + return (ofd.objNo == objNo) && (ofd.objVersion == verToDel); + } + }); + for (File obj : objs) { + obj.delete(); + } + } + + @Override + public boolean fileExists(String fileId) { + File dir = new File(generateAbsoluteFilePath(fileId)); + return dir.exists(); + } + + @Override + protected FileMetadata loadFileMetadata(String fileId, StripingPolicyImpl sp) throws IOException { + + _stat_fileInfoLoads = 0; + + FileMetadata info = new FileMetadata(sp); + + File fileDir = new File(generateAbsoluteFilePath(fileId)); + + // file exists already ... + if (fileDir.exists()) { + + Map largestObjVersions = new HashMap(); + Map> objChecksums = new HashMap>(); + Map latestObjVersions = null; + + long lastObjNum = -1; + String lastObject = null; + + File currVerFile = new File(fileDir, CURRENT_VER_FILENAME); + boolean multiVersionSupport = currVerFile.exists(); + + // if multi-file-version support is enabled, retrieve the object + // versions for the current file version from the "latest versions" + // file + if (multiVersionSupport) { + + latestObjVersions = new HashMap(); + + RandomAccessFile rf = new RandomAccessFile(currVerFile, "r"); + for (long l = 0;; l++) { + // read object numbers until the file ends + try { + long objVer = rf.readLong(); + if (objVer != 0) + latestObjVersions.put(l, objVer); + } catch (EOFException exc) { + lastObjNum = l - 1; + break; + } + } + + rf.close(); + } + + // determine the largest object versions, as well as all checksums + String[] objs = fileDir.list(); + for (String obj : objs) { + + if (obj.startsWith(".")) { + continue; // ignore special files (metadata, .tepoch) + } + + ObjFileData ofd = parseFileName(obj); + + // determine the checksum + if (ofd.checksum != 0) { + + Map checksums = objChecksums.get(ofd.objNo); + if (checksums == null) { + checksums = new HashMap(); + objChecksums.put(ofd.objNo, checksums); + } + + checksums.put(ofd.objVersion, ofd.checksum); + } + + // determine the last object + if (multiVersionSupport) { + Long latestObjVer = latestObjVersions.get(ofd.objNo); + if (ofd.objNo == lastObjNum && latestObjVer != null && ofd.objVersion == latestObjVer) + lastObject = obj; + } + + else { + if (ofd.objNo > lastObjNum) { + lastObject = obj; + lastObjNum = ofd.objNo; + } + } + + // determine the largest object version + Long oldver = largestObjVersions.get(ofd.objNo); + if ((oldver == null) || (oldver < ofd.objVersion)) + largestObjVersions.put(ofd.objNo, ofd.objVersion); + } + + if (multiVersionSupport) { + + // set object versions and checksums of the latest file version + info.initLatestObjectVersions(latestObjVersions); + + // if multi-file-version support is enabled, it is also + // necessary to keep track of the largest file versions + info.initLargestObjectVersions(largestObjVersions); + } + + // if no multi-version support is enabled, the file version consists + // of the set of objects with the latest version numbers + else { + info.initLatestObjectVersions(largestObjVersions); + info.initLargestObjectVersions(largestObjVersions); + } + + info.initObjectChecksums(objChecksums); + + // determine filesize from lastObjectNumber + if (lastObjNum > -1) { + File lastObjFile = new File(fileDir.getAbsolutePath() + "/" + lastObject); + long lastObjSize = lastObjFile.length(); + // check for empty padding file + if (lastObjSize == 0) { + lastObjSize = sp.getStripeSizeForObject(lastObjSize); + } + long fsize = lastObjSize; + if (lastObjNum > 0) { + fsize += sp.getObjectEndOffset(lastObjNum - 1) + 1; + } + assert (fsize >= 0); + info.setFilesize(fsize); + info.setLastObjectNumber(lastObjNum); + } else { + // empty file! + info.setFilesize(0l); + info.setLastObjectNumber(-1); + } + + // read truncate epoch from file + File tepoch = new File(fileDir, TEPOCH_FILENAME); + if (tepoch.exists()) { + RandomAccessFile raf = null; + try { + raf = new RandomAccessFile(tepoch, "r"); + info.setTruncateEpoch(raf.readLong()); + } finally { + if (raf != null) { + raf.close(); + } + } + } + + // initialize version table + File vtFile = new File(fileDir, VTABLE_FILENAME); + VersionTable vt = new VersionTable(vtFile); + if (vtFile.exists()) + vt.load(); + + info.initVersionTable(vt); + + } + + // file does not exist + else { + info.setFilesize(0); + info.setLastObjectNumber(-1); + info.initLatestObjectVersions(new HashMap()); + info.initLargestObjectVersions(new HashMap()); + info.initObjectChecksums(new HashMap>()); + info.initVersionTable(new VersionTable(new File(fileDir, VTABLE_FILENAME))); + } + + info.setGlobalLastObjectNumber(-1); + return info; + } + + @Override + public void setTruncateEpoch(String fileId, long newTruncateEpoch) throws IOException { + File parent = new File(generateAbsoluteFilePath(fileId)); + if (!parent.exists()) { + parent.mkdirs(); + } + File tepoch = new File(parent, TEPOCH_FILENAME); + RandomAccessFile raf = null; + try { + raf = new RandomAccessFile(tepoch, "rw"); + raf.writeLong(newTruncateEpoch); + } finally { + if (raf != null) { + raf.close(); + } + } + } + + @Override + public ObjectSet getObjectSet(String fileId, FileMetadata md) { + ObjectSet objectSet; + + File fileDir = new File(generateAbsoluteFilePath(fileId)); + if (fileDir.exists()) { + String[] objs = fileDir.list(new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + if (name.startsWith(".")) // ignore special files (metadata, + // .tepoch) + { + return false; + } else { + return true; + } + } + }); + objectSet = new ObjectSet(objs.length); + + for (int i = 0; i < objs.length; i++) { + objectSet.add(parseFileName(objs[i]).objNo); + } + } else { + objectSet = new ObjectSet(0); + } + + return objectSet; + } + + public String generateAbsoluteFilePath(String fileId) { + return this.storageDir + generateRelativeFilePath(fileId); + } + + private String generateAbsoluteObjectPathFromFileId(String fileId, long objNo, long version, long checksum) { + StringBuilder path = new StringBuilder(generateAbsoluteFilePath(fileId)); + path.append(createFileName(objNo, version, checksum)); + return path.toString(); + } + + private String generateAbsoluteObjectPathFromRelPath(String relativeFilePath, long objNo, long version, + long checksum) { + StringBuilder path = new StringBuilder(this.storageDir); + path.append(relativeFilePath); + path.append(createFileName(objNo, version, checksum)); + return path.toString(); + } + + private String generateRelativeFilePath(String fileId) { + if (USE_PATH_CACHE) { + String cached = hashedPathCache.get(fileId); + if (cached != null) + return cached; + } + String id = (WIN) ? fileId.replace(':', '_') : fileId; + StringBuilder path = generateHashPath(id); + path.append(id); + path.append("/"); + final String pathStr = path.toString(); + if (USE_PATH_CACHE) { + hashedPathCache.put(fileId, pathStr); + } + return pathStr; + } + + /** + * generates the path for the file with an "/" at the end + * + * @param fileId + * @return + */ + private StringBuilder generateHashPath(String fileId) { + StringBuilder hashPath = new StringBuilder(128); + String hash = hash(fileId); + int i = 0, j = prefixLength; + + while (j < hash.length()) { + hashPath.append(hash.subSequence(i, j)); + hashPath.append("/"); + + i += prefixLength; + j += prefixLength; + } + if (j < hash.length() + prefixLength) { + hashPath.append(hash.subSequence(i, hash.length())); + hashPath.append("/"); + } + return hashPath; + } + + /** + * computes the hash for the File + * + * @param str + * @return + */ + private String hash(String str) { + assert (str != null); + // this.hashAlgo.digest(str); + StringBuffer sb = new StringBuffer(16); + // final long hashValue = this.hashAlgo.getValue(); + final long hashValue = str.hashCode(); + OutputUtils.writeHexLong(sb, hashValue); + + if (sb.length() > this.hashCutLength) { + return sb.substring(0, this.hashCutLength); + } else { + return sb.toString(); + } + } + + @Override + public long getFileInfoLoadCount() { + return _stat_fileInfoLoads; + } + + /** + * + * @param f + * @return the VersionNo of the given File. + * @throws NumberFormatException + */ + private long getVersion(File f) throws NumberFormatException { + final String name = f.getName(); + ObjFileData ofd = parseFileName(name); + return ofd.objVersion; + } + + /** + * + * @param f + * @return the ObjectNo of the given File. + * @throws NumberFormatException + */ + private long getObjectNo(File f) throws NumberFormatException { + final String name = f.getName(); + ObjFileData ofd = parseFileName(name); + return ofd.objNo; + } + + public static String createFileName(long objNo, long objVersion, long checksum) { + final StringBuffer sb = new StringBuffer(3 * Long.SIZE / 8); + OutputUtils.writeHexLong(sb, objNo); + OutputUtils.writeHexLong(sb, objVersion); + OutputUtils.writeHexLong(sb, checksum); + return sb.toString(); + } + + public static ObjFileData parseFileName(String filename) { + if (filename.length() == 32) { + // compatability mode + final long objNo = OutputUtils.readHexLong(filename, 0); + final int objVersion = OutputUtils.readHexInt(filename, 16); + final long checksum = OutputUtils.readHexLong(filename, 24); + return new ObjFileData(objNo, objVersion, checksum); + } else { + final long objNo = OutputUtils.readHexLong(filename, 0); + final long objVersion = OutputUtils.readHexLong(filename, 16); + final long checksum = OutputUtils.readHexLong(filename, 32); + return new ObjFileData(objNo, objVersion, checksum); + } + } + + @Override + public int getLayoutVersionTag() { + return SL_TAG; + } + + @Override + public boolean isCompatibleVersion(int layoutVersionTag) { + if (layoutVersionTag == SL_TAG) { + return true; + } + // we are compatible with the old layout (version was an int) + if (layoutVersionTag == 1) { + return true; + } + return false; + } + + public static final class ObjFileData { + + final long objNo; + + final long objVersion; + + final long checksum; + + public ObjFileData(long objNo, long objVersion, long checksum) { + this.objNo = objNo; + this.objVersion = objVersion; + this.checksum = checksum; + } + } + + @Override + public FileList getFileList(FileList l, int maxNumEntries) { + + if (l == null) { + l = new FileList(new Stack(), new HashMap()); + l.status.push(""); + } + l.files.clear(); + + try { + do { + int PREVIEW_LENGTH = 15; + String currentDir = l.status.pop(); + File dir = new File(storageDir + currentDir); + if (dir.listFiles() == null) { + Logging.logMessage(Logging.LEVEL_WARN, Category.misc, this, storageDir + currentDir + + " is not a valid directory!"); + continue; + } + + FileReader fReader; + + File newestFirst = null; + File newestLast = null; + Long objectSize = 0L; + boolean isFileNameDir = false; + + for (File ch : dir.listFiles()) { + // handle the directories (hash and fileName) + if (ch != null && ch.isDirectory()) { + l.status.push(currentDir + "/" + ch.getName()); + // get information from the objects + } else if (ch != null && ch.isFile() && !ch.getName().contains(".") + && !ch.getName().endsWith(".ser")) { + // get the file metadata + try { + long version = getVersion(ch); + long objNum = getObjectNo(ch); + + isFileNameDir = true; + if (newestFirst == null) { + + newestFirst = newestLast = ch; + objectSize = ch.length(); + } else if (version > getVersion(newestFirst)) { + + newestFirst = newestLast = ch; + objectSize = (objectSize >= ch.length()) ? objectSize : ch.length(); + } else if (version == getVersion(newestFirst)) { + + if (objNum < getObjectNo(newestFirst)) { + newestFirst = ch; + } else if (objNum > getObjectNo(newestLast)) { + newestLast = ch; + } + objectSize = (objectSize >= ch.length()) ? objectSize : ch.length(); + } + } catch (Exception e) { + + Logging.logMessage(Logging.LEVEL_WARN, Category.storage, this, + "CleanUp: an illegal file (" + ch.getAbsolutePath() + + ") was discovered and ignored."); + } + } else if (ch != null && ch.isFile() && ch.getName().endsWith(XLOC_VERSION_STATE_FILENAME)) { + // If no data file exists, but a version_state file, the whole data folder can be deleted after + // a certain period. + isFileNameDir = true; + } + } + + // dir is a fileName-directory + if (isFileNameDir) { + + if (newestFirst != null) { + // get a preview from the file + char[] preview = null; + try { + fReader = new FileReader(newestFirst); + preview = new char[PREVIEW_LENGTH]; + fReader.read(preview); + fReader.close(); + } catch (Exception e) { + assert (false); + } + + // get the metaInfo from the root-directory + long stripCount = getObjectNo(newestLast); + long fileSize = (stripCount == 1) ? newestFirst.length() : (objectSize * stripCount) + + newestLast.length(); + + // insert the data into the FileList + l.files.put((WIN) ? dir.getName().replace('_', ':') : dir.getName(), + new FileData(fileSize, (int) (objectSize / 1024))); + } else { + // No data file exists, but the folders some metadata is still in place. + l.files.put((WIN) ? dir.getName().replace('_', ':') : dir.getName(), + new FileData(true)); + } + } + } while (l.files.size() < maxNumEntries); + l.hasMore = true; + return l; + + } catch (EmptyStackException ex) { + // done + l.hasMore = false; + return l; + } + } + + @Override + public ArrayList getFileIDList() { + + ArrayList fileList = new ArrayList(); + + Stack directories = new Stack(); + directories.push(storageDir); + + File currentFile; + + while (!directories.empty()) { + currentFile = new File(directories.pop()); + for (File f : currentFile.listFiles()) { + if (f != null && f.isDirectory() && !f.getName().contains(":")) { + directories.push(f.getAbsolutePath()); + } else { + if (f != null && !f.getName().contains(".") && !f.getName().endsWith(".ser")) { + fileList.add(f.getName()); + } + } + } + } + + return fileList; + } + + @Override + public int getMasterEpoch(String fileId) throws IOException { + int masterEpoch = 0; + RandomAccessFile raf = null; + File fileDir = new File(generateAbsoluteFilePath(fileId)); + File mepoch = new File(fileDir, MASTER_EPOCH_FILENAME); + + try { + raf = new RandomAccessFile(mepoch, "r"); + + masterEpoch = raf.readInt(); + } catch (FileNotFoundException ex) { + // Before XtreemFS 1.4.1 the .mepoch was accidentally stored in the + // wrong directory because a leading "/" was not removed from + // fileId. + String oldFileId = "/" + fileId; + File oldFileDir = new File(generateAbsoluteFilePath(oldFileId)); + File oldMepoch = new File(oldFileDir, MASTER_EPOCH_FILENAME); + + if (oldMepoch.isFile()) { + if (!fileDir.exists()) { + fileDir.mkdirs(); + } + + if (oldMepoch.renameTo(mepoch)) { + del(oldFileDir); + + raf = new RandomAccessFile(mepoch, "r"); + } else { + Logging.logMessage(Logging.LEVEL_WARN, this, "Failed to move %s file from: %s to: %s", + MASTER_EPOCH_FILENAME, oldFileDir.getPath(), fileDir.getPath()); + + raf = new RandomAccessFile(oldMepoch, "r"); + } + + masterEpoch = raf.readInt(); + } + } finally { + if (raf != null) { + raf.close(); + } + } + return masterEpoch; + } + + @Override + public void setMasterEpoch(String fileId, int masterEpoch) throws IOException { + File fileDir = new File(generateAbsoluteFilePath(fileId)); + if (!fileDir.exists()) { + fileDir.mkdirs(); + } + File mepoch = new File(fileDir, MASTER_EPOCH_FILENAME); + RandomAccessFile rf = new RandomAccessFile(mepoch, "rw"); + rf.writeInt(masterEpoch); + rf.close(); + } + + @Override + public TruncateLog getTruncateLog(String fileId) throws IOException { + TruncateLog.Builder tlbuilder = TruncateLog.newBuilder(); + + try { + File fileDir = new File(generateAbsoluteFilePath(fileId)); + File tlog = new File(fileDir, TRUNCATE_LOG_FILENAME); + FileInputStream input = null; + try { + input = new FileInputStream(tlog); + tlbuilder.mergeDelimitedFrom(input); + } finally { + if (input != null) { + input.close(); + } + } + } catch (IOException ex) { + } + return tlbuilder.build(); + } + + @Override + public void setTruncateLog(String fileId, TruncateLog log) throws IOException { + File fileDir = new File(generateAbsoluteFilePath(fileId)); + if (!fileDir.exists()) { + fileDir.mkdirs(); + } + File tlog = new File(fileDir, TRUNCATE_LOG_FILENAME); + FileOutputStream output = null; + + try { + output = new FileOutputStream(tlog); + log.writeDelimitedTo(output); + } finally { + if (output != null) { + output.close(); + } + } + } + + @Override + public XLocSetVersionState getXLocSetVersionState(String fileId) throws IOException { + XLocSetVersionState state = xLocSetVSCache.get(fileId); + + if (state == null) { + XLocSetVersionState.Builder vsbuilder = XLocSetVersionState.newBuilder(); + + File fileDir = new File(generateAbsoluteFilePath(fileId)); + File vsFile = new File(fileDir, XLOC_VERSION_STATE_FILENAME); + + FileInputStream input = null; + try { + input = new FileInputStream(vsFile); + vsbuilder.mergeDelimitedFrom(input); + + } catch (FileNotFoundException e) { + // If the file does not exist yet, set the initial state + vsbuilder.setInvalidated(true).setVersion(-1); + + } finally { + if (input != null) { + input.close(); + } + } + + // Build the state and store it to the cache. + state = vsbuilder.build(); + xLocSetVSCache.put(fileId, state); + } + + return state; + } + + @Override + public void setXLocSetVersionState(String fileId, XLocSetVersionState versionState) throws IOException { + File fileDir = new File(generateAbsoluteFilePath(fileId)); + if (!fileDir.exists()) { + fileDir.mkdirs(); + } + + File vsFile = new File(fileDir, XLOC_VERSION_STATE_FILENAME); + FileOutputStream output = null; + try { + output = new FileOutputStream(vsFile); + versionState.writeDelimitedTo(output); + xLocSetVSCache.put(fileId, versionState); + } finally { + if (output != null) { + output.close(); + } + } + } +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/MetadataCache.java b/java/servers/src/org/xtreemfs/osd/storage/MetadataCache.java new file mode 100644 index 0000000..073252e --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/MetadataCache.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2009-2011 by Christian Lorenz, Bjoern Kolbeck, + * Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +import java.util.Map; +import java.util.concurrent.ConcurrentSkipListMap; + + +public class MetadataCache { + + private Map metadataMap; + + /** Creates a new instance of StorageCache */ + public MetadataCache() { + metadataMap = new ConcurrentSkipListMap(); + } + + public FileMetadata getFileInfo(String fileId) { + assert (fileId != null); + return metadataMap.get(fileId); + } + + public void setFileInfo(String fileId, FileMetadata info) { + assert (info.getFilesize() != 0 || info.getLastObjectNumber() <= 0); + metadataMap.put(fileId, info); + } + + public FileMetadata removeFileInfo(String fileId) { + return metadataMap.remove(fileId); + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/ObjectInformation.java b/java/servers/src/org/xtreemfs/osd/storage/ObjectInformation.java new file mode 100644 index 0000000..308545a --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/ObjectInformation.java @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; + +/** + * + * @author bjko + */ +public class ObjectInformation { + + /** + * @return the stripeSize + */ + public int getStripeSize() { + return stripeSize; + } + + /** + * @return the checksumInvalidOnOSD + */ + public boolean isChecksumInvalidOnOSD() { + return checksumInvalidOnOSD; + } + + /** + * @param checksumInvalidOnOSD the checksumInvalidOnOSD to set + */ + public void setChecksumInvalidOnOSD(boolean checksumInvalidOnOSD) { + this.checksumInvalidOnOSD = checksumInvalidOnOSD; + } + + public static enum ObjectStatus { + /** + * object exists on disk, data is available + */ + EXISTS, + /** + * object does not exist on disk + */ + DOES_NOT_EXIST, + /** + * object is an empty (file size == 0) placeholder + * for a fully zero padded object + */ + PADDING_OBJECT + }; + + private ReusableBuffer data; + + private final ObjectStatus status; + + private final int stripeSize; + + private long lastLocalObjectNo; + + private long globalLastObjectNo; + + private boolean checksumInvalidOnOSD; + + public ObjectInformation(ObjectStatus status, ReusableBuffer data, int stripeSize) { + this.data = data; + this.status = status; + this.stripeSize = stripeSize; + } + + public InternalObjectData getObjectData(boolean isLastObject, int offset, int length) { + assert(length >= 0); + if (isLastObject) { + switch (status) { + case EXISTS: return new InternalObjectData(0, checksumInvalidOnOSD, 0, data); + case DOES_NOT_EXIST: return new InternalObjectData(0,checksumInvalidOnOSD, 0, null); + case PADDING_OBJECT: throw new RuntimeException("padding object must not be last object!"); + } + } else { + switch (status) { + case EXISTS: { + final int paddingZeros = length-data.remaining(); + assert(paddingZeros >= 0) : "offset: "+offset+" length: "+length+" remaining: "+data.remaining(); + return new InternalObjectData(0,checksumInvalidOnOSD, paddingZeros, data); + } + case DOES_NOT_EXIST: + case PADDING_OBJECT: { + return new InternalObjectData(0, checksumInvalidOnOSD, length, data); + } + } + } + assert(false) : "should be unreachable"; + return null; + } + + /*public ObjectData getObjectData(boolean isLastObject, int offset, int length) { + if (offset+length > getStripeSize()) + throw new IllegalArgumentException("offset+length must be less than the stripe size"); + + ObjectData tmp = getObjectData(isLastObject,length); + + + + + final int dataLength = tmp.getZero_padding() + ((tmp.getData() != null) ? tmp.getData().remaining() : 0); + + if (dataLength < getStripeSize()) { + //this is an EOF + assert(tmp.getZero_padding() == 0); + if (tmp.getData() != null) { + final int bufLength = tmp.getData().remaining(); + if (offset > bufLength) { + //no data to be sent + BufferPool.free(tmp.getData()); + tmp.setData(null); + } else { + //create a range + final int newLength = (bufLength > offset+length) ? length : bufLength-offset; + tmp.getData().range(offset,newLength); + } + } + } else { + //full object + if (tmp.getData() == null) { + //padding object + tmp.setZero_padding(length); + } else { + final int bufLength = tmp.getData().remaining(); + int newBufLen; + if (offset >= bufLength) { + BufferPool.free(tmp.getData()); + tmp.setData(null); + //adapt zeros + //object is a full object, so length is all zeros + tmp.setZero_padding(length); + } else { + //buffer stays + if (offset+length > bufLength) { + //goes beyond buffer + tmp.getData().range(offset,bufLength-offset); + } else { + tmp.getData().range(offset,length); + } + //fill up the rest with zeros + tmp.setZero_padding(length-tmp.getData().remaining()); + } + } + } + return tmp; + + + }*/ + + /** + * @return the data + */ + public ReusableBuffer getData() { + return data; + } + + public void setData(ReusableBuffer data) { + this.data = data; + } + + /** + * @return the status + */ + public ObjectStatus getStatus() { + return status; + } + + /** + * @return the lastLocalObjectNo + */ + public long getLastLocalObjectNo() { + return lastLocalObjectNo; + } + + /** + * @param lastLocalObjectNo the lastLocalObjectNo to set + */ + public void setLastLocalObjectNo(long lastLocalObjectNo) { + this.lastLocalObjectNo = lastLocalObjectNo; + } + + /** + * @return the globalLastObjectNo + */ + public long getGlobalLastObjectNo() { + return globalLastObjectNo; + } + + /** + * @param globalLastObjectNo the globalLastObjectNo to set + */ + public void setGlobalLastObjectNo(long globalLastObjectNo) { + this.globalLastObjectNo = globalLastObjectNo; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/RealSingleFileStorageLayout.java b/java/servers/src/org/xtreemfs/osd/storage/RealSingleFileStorageLayout.java new file mode 100644 index 0000000..2dd4aee --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/RealSingleFileStorageLayout.java @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Stack; + +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.foundation.LRUCache; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.checksums.ChecksumAlgorithm; +import org.xtreemfs.foundation.checksums.ChecksumFactory; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState; + +/** + * + * @author bjko + */ +public class RealSingleFileStorageLayout extends StorageLayout { + + public static final int SL_TAG = 0x00030001; + + private static final String DATA_SUFFIX = ".data"; + + private static final String TEPOCH_SUFFIX = ".te"; + + private static final int MDRECORD_SIZE = Long.SIZE/8 * 2; + + private static final int DATA_HANDLE = 0; + + private final boolean checksumsEnabled; + + private ChecksumAlgorithm checksumAlgo; + + private final LRUCache hashedPathCache; + private static final int HASH_CUTOFF = 4; + + private final ByteBuffer mdata; + + private static final char[] hexTab = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + + + public RealSingleFileStorageLayout(OSDConfig config, MetadataCache cache) throws IOException { + super(config, cache); + checksumsEnabled = config.isUseChecksums(); + mdata = ByteBuffer.allocate(MDRECORD_SIZE); + if (config.isUseChecksums()) { + + // get the algorithm from the factory + try { + checksumAlgo = ChecksumFactory.getInstance().getAlgorithm(config.getChecksumProvider()); + if (checksumAlgo == null) + throw new NoSuchAlgorithmException("algo is null"); + } catch (NoSuchAlgorithmException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.all, this, + "could not instantiate checksum algorithm '%s'", config.getChecksumProvider()); + Logging.logMessage(Logging.LEVEL_ERROR, Category.all, this, + "OSD checksums will be switched off"); + } + } + + hashedPathCache = new LRUCache(2048); + + Logging.logMessage(Logging.LEVEL_ERROR, this,"this storage layout is still under development and should not be used except for testing!"); + } + + private long getOffsetForMetadata(int stripeSize, long row) { + return stripeSize*(row+1)+MDRECORD_SIZE*row; + } + + private long getOffsetForData(int stripeSize, long row) { + return stripeSize*row+MDRECORD_SIZE*row; + } + + @Override + protected FileMetadata loadFileMetadata(String fileId, StripingPolicyImpl sp) throws IOException { + FileMetadata fi = new FileMetadata(sp); + Map tmp = new HashMap(); + fi.initLatestObjectVersions(tmp); + fi.initLargestObjectVersions(tmp); + if (checksumsEnabled) + fi.initObjectChecksums(new HashMap()); + + File f = new File(getFilePath(fileId)+DATA_SUFFIX); + + if (f.exists()) { + openHandles(fi,fileId); + RandomAccessFile ofile = fi.getHandles()[DATA_HANDLE]; + + final int stripeSize = sp.getStripeSizeForObject(0); + final long fileSize = ofile.length(); + + final long numObjs = (long) Math.ceil((double)fileSize/(double)stripeSize); + + for (long i = 0; i < numObjs; i++) { + long globalON = sp.getGloablObjectNumber(i); + ofile.seek(getOffsetForMetadata(stripeSize, i)); + + long chkSum = ofile.readLong(); + long version = ofile.readLong(); + if (version == 0) + continue; + if (checksumsEnabled) + fi.updateObjectChecksum(globalON, chkSum, version); + fi.updateObjectVersion(globalON, version); + } + fi.setLastObjectNumber(sp.getGloablObjectNumber(numObjs-1)); + fi.setFilesize((fi.getGlobalLastObjectNumber()-1)*stripeSize+fileSize%stripeSize); + File tepoch = new File(getFilePath(fileId)+TEPOCH_SUFFIX); + if (tepoch.exists()) { + RandomAccessFile rf = new RandomAccessFile(tepoch, "r"); + fi.setTruncateEpoch(rf.readLong()); + rf.close(); + } + } else { + fi.setLastObjectNumber(-1); + fi.setFilesize(0); + fi.setTruncateEpoch(0); + } + fi.setGlobalLastObjectNumber(-1); + return fi; + } + + private void openHandles(FileMetadata md, String fileId) throws IOException{ + if (md.getHandles() == null) { + String filename = getFilePath(fileId); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "open file: %s", + filename); + } + RandomAccessFile ofile = new RandomAccessFile(filename+DATA_SUFFIX, "rw"); + RandomAccessFile[] handles = new RandomAccessFile[]{ofile}; + md.setHandles(handles); + } + } + + @Override + public ObjectInformation readObject(String fileId, FileMetadata md, long objNo, int offset, int length, + long version) throws IOException { + + openHandles(md,fileId); + final RandomAccessFile ofile = md.getHandles()[DATA_HANDLE]; + + final StripingPolicyImpl sp = md.getStripingPolicy(); + + final int stripeSize = sp.getStripeSizeForObject(objNo); + final long objFileOffset = sp.getRow(objNo)*stripeSize+offset; + final long fileSize = ofile.length(); + + + if (fileSize <= objFileOffset) { + //EOF + return new ObjectInformation(ObjectInformation.ObjectStatus.DOES_NOT_EXIST, null, stripeSize ); + } else { + long objSize = fileSize-objFileOffset; + if (objSize > stripeSize) + objSize = stripeSize-offset; + if ((length > 0) && (objSize > length)) { + objSize = length; + } + assert(objSize <= stripeSize); + ReusableBuffer obj = BufferPool.allocate((int)objSize); + final FileChannel c = ofile.getChannel(); + ofile.seek(objFileOffset); + c.read(obj.getBuffer()); + obj.flip(); + + ObjectInformation oInfo = new ObjectInformation(ObjectInformation.ObjectStatus.EXISTS, obj, stripeSize); + if (checksumsEnabled) { + //FIXME: optimize the read away + ReusableBuffer data = BufferPool.allocate(stripeSize); + ofile.seek(sp.getRow(objNo)*stripeSize); + c.read(data.getBuffer()); + checksumAlgo.reset(); + checksumAlgo.update(data.getBuffer()); + BufferPool.free(data); + long newChecksum = checksumAlgo.getValue(); + oInfo.setChecksumInvalidOnOSD(newChecksum != md.getObjectChecksum(objNo, md.getLatestObjectVersion(objNo))); + } + + return oInfo; + } + + } + + @Override + public void writeObject(String fileId, FileMetadata md, ReusableBuffer data, long objNo, int offset, + long newVersion, boolean sync, boolean cow) throws IOException { + + openHandles(md,fileId); + final RandomAccessFile ofile = md.getHandles()[DATA_HANDLE]; + + final StripingPolicyImpl sp = md.getStripingPolicy(); + + final int stripeSize = sp.getStripeSizeForObject(objNo); + final long row = sp.getRow(objNo); + final long mdOffset = getOffsetForMetadata(stripeSize, row); + final long objFileOffset = getOffsetForData(stripeSize, row)+offset; + + + final FileChannel c = ofile.getChannel(); + ofile.seek(objFileOffset); + data.position(0); + + final boolean fullObjWrite = data.remaining() == stripeSize; + + c.write(data.getBuffer()); + + //do calc checksum + long newChecksum = 0l; + + if (checksumsEnabled) { + data.position(0); + checksumAlgo.reset(); + if (!fullObjWrite) { + final long objOffset = sp.getRow(objNo)*stripeSize; + ReusableBuffer csumData = BufferPool.allocate(stripeSize); + ofile.seek(objOffset); + c.read(csumData.getBuffer()); + checksumAlgo.update(csumData.getBuffer()); + BufferPool.free(csumData); + } else { + checksumAlgo.update(data.getBuffer()); + } + newChecksum = checksumAlgo.getValue(); + md.updateObjectChecksum(objNo, newVersion, newChecksum); + } + BufferPool.free(data); + + if (!fullObjWrite) { + ofile.seek(mdOffset); + } + ofile.writeLong(newVersion); + ofile.writeLong(newChecksum); + md.updateObjectVersion(objNo, newVersion); + } + + /*private void writeMDRecord(RandomAccessFile mdfile, long objNo, long version, long checksum) throws IOException { + long seekPos = objNo*MDRECORD_SIZE; + if (md.getMdFileLength() <= seekPos) { + long newSize = seekPos+4096; + mdfile.setLength(newSize); + md.setMdFileLength(newSize); + } + mdfile.seek(seekPos); + mdfile.writeLong(checksum); + mdfile.writeLong(version); + + }*/ + + @Override + public void deleteFile(String fileId, boolean deleteMetadata) throws IOException { + File f = new File(getFilePath(fileId)+DATA_SUFFIX); + f.delete(); + if (deleteMetadata) { + //fixme + } + } + + @Override + public void deleteObject(String fileId, FileMetadata md, final long objNo, long version) throws IOException { + //can only pad with zeros or cut file length + + openHandles(md,fileId); + final RandomAccessFile ofile = md.getHandles()[DATA_HANDLE]; + + final StripingPolicyImpl sp = md.getStripingPolicy(); + + final int stripeSize = sp.getStripeSizeForObject(objNo); + final long row = sp.getRow(objNo); + final long objFileOffset = getOffsetForData(stripeSize, row); + final long fileSize = ofile.length(); + + final long lastObj = md.getLastObjectNumber(); + + if (fileSize > 0){ + if (lastObj == objNo) { + if (sp.getRow(objNo) == 0) { + ofile.setLength(0); + } else { + long newLength = getOffsetForMetadata(stripeSize, row-1)+MDRECORD_SIZE; + ofile.setLength(newLength); + } + } else if (objNo < lastObj) { + //fill with 0s + ReusableBuffer buf = BufferPool.allocate(stripeSize); + while (buf.hasRemaining()) + buf.put((byte)0); + buf.flip(); + final FileChannel c = ofile.getChannel(); + c.position(objFileOffset); + c.write(buf.getBuffer()); + ofile.writeLong(version); + //fixme: calc chekcsum + ofile.writeLong(0l); + } + //no else here, if objNo > lastObj, it does not exist + } + } + + @Override + public void createPaddingObject(String fileId, FileMetadata md, long objNo, long version, int size) + throws IOException { + + openHandles(md,fileId); + final RandomAccessFile ofile = md.getHandles()[DATA_HANDLE]; + + final StripingPolicyImpl sp = md.getStripingPolicy(); + + //FIXME:!!!! + /*final int stripeSize = sp.getStripeSizeForObject(objNo); + final long objFileOffset = sp.getRow(objNo)*stripeSize; + final long fileSize = ofile.length(); + + + if (fileSize < objFileOffset + size) { + //we need to create the object + ofile.setLength(objFileOffset + size); + //mdfile.setLength((objNo+1)*MDRECORD_SIZE); + md.setMdFileLength((objNo+1)*MDRECORD_SIZE); + }*/ + + + } + + @Override + public void setTruncateEpoch(String fileId, long newTruncateEpoch) throws IOException { + RandomAccessFile rf = new RandomAccessFile(getFilePath(fileId)+TEPOCH_SUFFIX, "rw"); + rf.writeLong(newTruncateEpoch); + rf.close(); + } + + @Override + public boolean fileExists(String fileId) { + File f = new File(getFilePath(fileId)+DATA_SUFFIX); + return f.exists(); + } + + @Override + public long getFileInfoLoadCount() { + return 0; + } + + @Override + public ObjectSet getObjectSet(String fileId, FileMetadata md) { + ObjectSet objectSet; + + objectSet = new ObjectSet(md.getLatestObjectVersions().size()); + for (Entry e : md.getLatestObjectVersions()) { + objectSet.add(e.getKey()); + } + + return objectSet; + } + + @Override + public FileList getFileList(FileList l, int maxNumEntries) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getLayoutVersionTag() { + return SL_TAG; + } + + @Override + public boolean isCompatibleVersion(int layoutVersionTag) { + return layoutVersionTag == SL_TAG; + } + + @Override + public void truncateObject(String fileId, FileMetadata md, long objNo, int newLength, long newVersion, boolean cow) throws IOException { + + openHandles(md,fileId); + final RandomAccessFile ofile = md.getHandles()[DATA_HANDLE]; + //final RandomAccessFile mdfile = md.getHandles()[MD_HANDLE]; + + final StripingPolicyImpl sp = md.getStripingPolicy(); + + final int stripeSize = sp.getStripeSizeForObject(objNo); + final long objFileOffset = sp.getRow(objNo)*stripeSize; + final long fileSize = ofile.length(); + final long lastObj = sp.getObjectNoForOffset(fileSize); + + if (lastObj == objNo) { + // System.out.println("truncating: "+(objFileOffset + newLength)); + ofile.setLength(objFileOffset + newLength); + + long newChecksum = 0l; + if (checksumsEnabled) { + checksumAlgo.reset(); + final long objOffset = sp.getRow(objNo)*stripeSize; + ReusableBuffer csumData = BufferPool.allocate(stripeSize); + ofile.seek(objOffset); + ofile.getChannel().read(csumData.getBuffer()); + checksumAlgo.update(csumData.getBuffer()); + BufferPool.free(csumData); + + newChecksum = checksumAlgo.getValue(); + md.updateObjectChecksum(objNo, newVersion, newChecksum); + } + //writeMDRecord(md, mdfile, objNo, newVersion, newChecksum); + } + + + } + + /** + * generates the path for the file with an "/" at the end + * + * @param fileId + * @return + */ + private String getFilePath(String fileId) { + //format /dir/xx/xx/fileID + + String path = hashedPathCache.get(fileId); + if (path == null) { + StringBuilder hashPath = new StringBuilder(this.storageDir.length()+fileId.length()+2+4); + hashPath.append(this.storageDir); + int hash = fileId.hashCode(); + + hashPath.append(OutputUtils.trHex[(hash & 0x0F)]); + hashPath.append(OutputUtils.trHex[((hash >> 4) & 0x0F)]); + hashPath.append("/"); + hashPath.append(OutputUtils.trHex[((hash >> 8) & 0x0F)]); + hashPath.append(OutputUtils.trHex[((hash >> 12) & 0x0F)]); + hashPath.append("/"); + + String dirs = hashPath.toString(); + + File f = new File(dirs); + f.mkdirs(); + + hashPath.append(fileId); + path = hashPath.toString(); + hashedPathCache.put(fileId, path); + + } + return path; + + + } + + @Override + public void updateCurrentObjVersion(String fileId, long objNo, long newVersion) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCurrentVersionSize(String fileId, long newLastObject) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ArrayList getFileIDList() { + + ArrayList fileList = new ArrayList(); + + Stack directories = new Stack(); + directories.push(storageDir); + + File currentFile; + + while (!directories.empty()) { + currentFile = new File(directories.pop()); + for (File f : currentFile.listFiles()) { + if(f != null && f.isDirectory()) { + directories.push(f.getAbsolutePath()); + } else { + if (f != null && f.isFile() && !f.getName().endsWith(".ser") && f.getName().contains(":")) { + String fName = f.getName().replace(DATA_SUFFIX, "").replace(TEPOCH_SUFFIX, ""); + + if (fileList.indexOf(fName) != -1) { + fileList.add(fName); + } + + } + } + } + } + return fileList; + } + + @Override + public int getMasterEpoch(String fileId) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setMasterEpoch(String fileId, int masterEpoch) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public TruncateLog getTruncateLog(String fileId) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTruncateLog(String fileId, TruncateLog log) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public XLocSetVersionState getXLocSetVersionState(String fileId) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setXLocSetVersionState(String fileId, XLocSetVersionState versionState) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/SingleFileStorageLayout.java b/java/servers/src/org/xtreemfs/osd/storage/SingleFileStorageLayout.java new file mode 100644 index 0000000..b3f59d7 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/SingleFileStorageLayout.java @@ -0,0 +1,529 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Stack; + +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.foundation.LRUCache; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.checksums.ChecksumAlgorithm; +import org.xtreemfs.foundation.checksums.ChecksumFactory; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState; + +/** + * + * @author bjko + */ +public class SingleFileStorageLayout extends StorageLayout { + + public static final int SL_TAG = 0x00020001; + + private static final String MD_SUFFIX = ".md"; + + private static final String DATA_SUFFIX = ".data"; + + private static final String TEPOCH_SUFFIX = ".te"; + + private static final int MDRECORD_SIZE = Long.SIZE/8 * 2; + + private static final int MD_HANDLE = 1; + + private static final int DATA_HANDLE = 0; + + private final boolean checksumsEnabled; + + private ChecksumAlgorithm checksumAlgo; + + private final LRUCache hashedPathCache; + private static final int HASH_CUTOFF = 4; + + private final ByteBuffer mdata; + + private static final char[] hexTab = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + + + public SingleFileStorageLayout(OSDConfig config, MetadataCache cache) throws IOException { + super(config, cache); + checksumsEnabled = config.isUseChecksums(); + mdata = ByteBuffer.allocate(MDRECORD_SIZE); + if (config.isUseChecksums()) { + + // get the algorithm from the factory + try { + checksumAlgo = ChecksumFactory.getInstance().getAlgorithm(config.getChecksumProvider()); + if (checksumAlgo == null) + throw new NoSuchAlgorithmException("algo is null"); + } catch (NoSuchAlgorithmException e) { + Logging.logMessage(Logging.LEVEL_ERROR, Category.all, this, + "could not instantiate checksum algorithm '%s'", config.getChecksumProvider()); + Logging.logMessage(Logging.LEVEL_ERROR, Category.all, this, + "OSD checksums will be switched off"); + } + } + + hashedPathCache = new LRUCache(2048); + + Logging.logMessage(Logging.LEVEL_ERROR, this,"this storage layout is still under development and should not be used except for testing!"); + } + + @Override + protected FileMetadata loadFileMetadata(String fileId, StripingPolicyImpl sp) throws IOException { + FileMetadata fi = new FileMetadata(sp); + Map tmp = new HashMap(); + fi.initLatestObjectVersions(tmp); + fi.initLargestObjectVersions(tmp); + if (checksumsEnabled) + fi.initObjectChecksums(new HashMap()); + + File f = new File(getFilePath(fileId)+DATA_SUFFIX); + + if (f.exists()) { + openHandles(fi,fileId); + RandomAccessFile ofile = fi.getHandles()[DATA_HANDLE]; + RandomAccessFile mdfile = fi.getHandles()[MD_HANDLE]; + mdfile.seek(0); + FileChannel mdChannel = mdfile.getChannel(); + + final int stripeSize = sp.getStripeSizeForObject(0); + final long fileSize = ofile.length(); + + final long numObjs = (long) Math.ceil((double)fileSize/(double)stripeSize); + + for (long i = 0; i < numObjs; i++) { + long globalON = sp.getGloablObjectNumber(i); + + long chkSum = mdfile.readLong(); + long version = mdfile.readLong(); + if (version == 0) + continue; + if (checksumsEnabled) + fi.updateObjectChecksum(globalON, chkSum, version); + fi.updateObjectVersion(globalON, version); + } + fi.setLastObjectNumber(sp.getGloablObjectNumber(numObjs-1)); + fi.setFilesize((fi.getGlobalLastObjectNumber()-1)*stripeSize+fileSize%stripeSize); + File tepoch = new File(getFilePath(fileId)+TEPOCH_SUFFIX); + if (tepoch.exists()) { + RandomAccessFile rf = new RandomAccessFile(tepoch, "r"); + fi.setTruncateEpoch(rf.readLong()); + rf.close(); + } + } else { + fi.setLastObjectNumber(-1); + fi.setFilesize(0); + fi.setTruncateEpoch(0); + } + fi.setGlobalLastObjectNumber(-1); + return fi; + } + + private void openHandles(FileMetadata md, String fileId) throws IOException{ + if (md.getHandles() == null) { + String filename = getFilePath(fileId); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "open file: %s", + filename); + } + RandomAccessFile ofile = new RandomAccessFile(filename+DATA_SUFFIX, "rw"); + RandomAccessFile mdfile = new RandomAccessFile(filename+MD_SUFFIX, "rw"); + RandomAccessFile[] handles = new RandomAccessFile[]{ofile,mdfile}; + md.setHandles(handles); + } + } + + @Override + public ObjectInformation readObject(String fileId, FileMetadata md, long objNo, int offset, int length, + long version) throws IOException { + + openHandles(md,fileId); + final RandomAccessFile ofile = md.getHandles()[DATA_HANDLE]; + + final StripingPolicyImpl sp = md.getStripingPolicy(); + + final int stripeSize = sp.getStripeSizeForObject(objNo); + final long objFileOffset = sp.getRow(objNo)*stripeSize+offset; + final long fileSize = ofile.length(); + + + if (fileSize <= objFileOffset) { + //EOF + return new ObjectInformation(ObjectInformation.ObjectStatus.DOES_NOT_EXIST, null, stripeSize ); + } else { + long objSize = fileSize-objFileOffset; + if (objSize > stripeSize) + objSize = stripeSize-offset; + if ((length > 0) && (objSize > length)) { + objSize = length; + } + assert(objSize <= stripeSize); + ReusableBuffer obj = BufferPool.allocate((int)objSize); + final FileChannel c = ofile.getChannel(); + ofile.seek(objFileOffset); + c.read(obj.getBuffer()); + obj.flip(); + + ObjectInformation oInfo = new ObjectInformation(ObjectInformation.ObjectStatus.EXISTS, obj, stripeSize); + if (checksumsEnabled) { + //FIXME: optimize the read away + ReusableBuffer data = BufferPool.allocate(stripeSize); + ofile.seek(sp.getRow(objNo)*stripeSize); + c.read(data.getBuffer()); + checksumAlgo.reset(); + checksumAlgo.update(data.getBuffer()); + BufferPool.free(data); + long newChecksum = checksumAlgo.getValue(); + oInfo.setChecksumInvalidOnOSD(newChecksum != md.getObjectChecksum(objNo, md.getLatestObjectVersion(objNo))); + } + + return oInfo; + } + + } + + @Override + public void writeObject(String fileId, FileMetadata md, ReusableBuffer data, long objNo, int offset, + long newVersion, boolean sync, boolean cow) throws IOException { + + openHandles(md,fileId); + final RandomAccessFile ofile = md.getHandles()[DATA_HANDLE]; + final RandomAccessFile mdfile = md.getHandles()[MD_HANDLE]; + + final StripingPolicyImpl sp = md.getStripingPolicy(); + + final int stripeSize = sp.getStripeSizeForObject(objNo); + final long objFileOffset = sp.getRow(objNo)*stripeSize+offset; + + final FileChannel c = ofile.getChannel(); + ofile.seek(objFileOffset); + data.position(0); + c.write(data.getBuffer()); + + //do calc checksum + long newChecksum = 0l; + + if (checksumsEnabled) { + data.position(0); + checksumAlgo.reset(); + if (data.remaining() < stripeSize) { + final long objOffset = sp.getRow(objNo)*stripeSize; + ReusableBuffer csumData = BufferPool.allocate(stripeSize); + ofile.seek(objOffset); + c.read(csumData.getBuffer()); + checksumAlgo.update(csumData.getBuffer()); + BufferPool.free(csumData); + } else { + checksumAlgo.update(data.getBuffer()); + } + newChecksum = checksumAlgo.getValue(); + md.updateObjectChecksum(objNo, newVersion, newChecksum); + } + BufferPool.free(data); + + writeMDRecord(md, mdfile, objNo, newVersion, newChecksum); + md.updateObjectVersion(objNo, newVersion); + } + + private void writeMDRecord(FileMetadata md, RandomAccessFile mdfile, long objNo, long version, long checksum) throws IOException { + long seekPos = objNo*MDRECORD_SIZE; + if (md.getMdFileLength() <= seekPos) { + long newSize = seekPos+4096; + mdfile.setLength(newSize); + md.setMdFileLength(newSize); + } + mdfile.seek(seekPos); + mdfile.writeLong(checksum); + mdfile.writeLong(version); + + } + + @Override + public void deleteFile(String fileId, boolean deleteMetadata) throws IOException { + File f = new File(getFilePath(fileId)+MD_SUFFIX); + f.delete(); + f = new File(getFilePath(fileId)+DATA_SUFFIX); + f.delete(); + if (deleteMetadata) { + //fixme + } + } + + @Override + public void deleteObject(String fileId, FileMetadata md, final long objNo, long version) throws IOException { + //can only pad with zeros or cut file length + + openHandles(md,fileId); + final RandomAccessFile ofile = md.getHandles()[DATA_HANDLE]; + final RandomAccessFile mdfile = md.getHandles()[MD_HANDLE]; + + final StripingPolicyImpl sp = md.getStripingPolicy(); + + final int stripeSize = sp.getStripeSizeForObject(objNo); + final long objFileOffset = sp.getRow(objNo)*stripeSize; + final long fileSize = ofile.length(); + + final int lastObj = (int) Math.ceil((double)fileSize/(double)stripeSize); + + if (fileSize > 0){ + if (lastObj == objNo) { + if (sp.getRow(objNo) == 0) { + ofile.setLength(0); + mdfile.setLength(0); + } else { + ofile.setLength((sp.getRow(objNo)-1)*stripeSize); + mdfile.setLength((lastObj+1)*MDRECORD_SIZE); + md.setMdFileLength((lastObj+1)*MDRECORD_SIZE); + } + } else if (objNo < lastObj) { + //fill with 0s + ReusableBuffer buf = BufferPool.allocate(stripeSize); + while (buf.hasRemaining()) + buf.put((byte)0); + buf.flip(); + final FileChannel c = ofile.getChannel(); + c.position(objFileOffset); + c.write(buf.getBuffer()); + + } + //no else here, if objNo > lastObj, it does not exist + } + } + + @Override + public void createPaddingObject(String fileId, FileMetadata md, long objNo, long version, int size) + throws IOException { + + openHandles(md,fileId); + final RandomAccessFile ofile = md.getHandles()[DATA_HANDLE]; + final RandomAccessFile mdfile = md.getHandles()[MD_HANDLE]; + + final StripingPolicyImpl sp = md.getStripingPolicy(); + + final int stripeSize = sp.getStripeSizeForObject(objNo); + final long objFileOffset = sp.getRow(objNo)*stripeSize; + final long fileSize = ofile.length(); + + + if (fileSize < objFileOffset + size) { + //we need to create the object + ofile.setLength(objFileOffset + size); + mdfile.setLength((objNo+1)*MDRECORD_SIZE); + md.setMdFileLength((objNo+1)*MDRECORD_SIZE); + } + + + } + + @Override + public void setTruncateEpoch(String fileId, long newTruncateEpoch) throws IOException { + RandomAccessFile rf = new RandomAccessFile(getFilePath(fileId)+TEPOCH_SUFFIX, "rw"); + rf.writeLong(newTruncateEpoch); + rf.close(); + } + + @Override + public boolean fileExists(String fileId) { + File f = new File(getFilePath(fileId)+DATA_SUFFIX); + return f.exists(); + } + + @Override + public long getFileInfoLoadCount() { + return 0; + } + + @Override + public ObjectSet getObjectSet(String fileId, FileMetadata md) { + ObjectSet objectSet; + + objectSet = new ObjectSet(md.getLatestObjectVersions().size()); + for (Entry e : md.getLatestObjectVersions()) { + objectSet.add(e.getKey()); + } + + return objectSet; + } + + @Override + public FileList getFileList(FileList l, int maxNumEntries) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getLayoutVersionTag() { + return SL_TAG; + } + + @Override + public boolean isCompatibleVersion(int layoutVersionTag) { + return layoutVersionTag == SL_TAG; + } + + @Override + public void truncateObject(String fileId, FileMetadata md, long objNo, int newLength, long newVersion, boolean cow) throws IOException { + + openHandles(md,fileId); + final RandomAccessFile ofile = md.getHandles()[DATA_HANDLE]; + final RandomAccessFile mdfile = md.getHandles()[MD_HANDLE]; + + final StripingPolicyImpl sp = md.getStripingPolicy(); + + final int stripeSize = sp.getStripeSizeForObject(objNo); + final long objFileOffset = sp.getRow(objNo)*stripeSize; + final long fileSize = ofile.length(); + final long lastObj = sp.getObjectNoForOffset(fileSize); + + if (lastObj == objNo) { + // System.out.println("truncating: "+(objFileOffset + newLength)); + ofile.setLength(objFileOffset + newLength); + + long newChecksum = 0l; + if (checksumsEnabled) { + checksumAlgo.reset(); + final long objOffset = sp.getRow(objNo)*stripeSize; + ReusableBuffer csumData = BufferPool.allocate(stripeSize); + ofile.seek(objOffset); + ofile.getChannel().read(csumData.getBuffer()); + checksumAlgo.update(csumData.getBuffer()); + BufferPool.free(csumData); + + newChecksum = checksumAlgo.getValue(); + md.updateObjectChecksum(objNo, newVersion, newChecksum); + } + writeMDRecord(md, mdfile, objNo, newVersion, newChecksum); + } + + + } + + /** + * generates the path for the file with an "/" at the end + * + * @param fileId + * @return + */ + private String getFilePath(String fileId) { + //format /dir/xx/xx/fileID + + String path = hashedPathCache.get(fileId); + if (path == null) { + StringBuilder hashPath = new StringBuilder(this.storageDir.length()+fileId.length()+2+4); + hashPath.append(this.storageDir); + int hash = fileId.hashCode(); + + hashPath.append(OutputUtils.trHex[(hash & 0x0F)]); + hashPath.append(OutputUtils.trHex[((hash >> 4) & 0x0F)]); + hashPath.append("/"); + hashPath.append(OutputUtils.trHex[((hash >> 8) & 0x0F)]); + hashPath.append(OutputUtils.trHex[((hash >> 12) & 0x0F)]); + hashPath.append("/"); + + String dirs = hashPath.toString(); + + File f = new File(dirs); + f.mkdirs(); + + hashPath.append(fileId); + path = hashPath.toString(); + hashedPathCache.put(fileId, path); + + } + return path; + + + } + + @Override + public void updateCurrentObjVersion(String fileId, long objNo, long newVersion) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCurrentVersionSize(String fileId, long newLastObject) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ArrayList getFileIDList() { + + ArrayList fileList = new ArrayList(); + + Stack directories = new Stack(); + directories.push(storageDir); + + File currentFile; + + while (!directories.empty()) { + currentFile = new File(directories.pop()); + for (File f : currentFile.listFiles()) { + if(f != null && f.isDirectory()) { + directories.push(f.getAbsolutePath()); + } else { + if (f != null && f.isFile() && !f.getName().endsWith(".ser") && f.getName().contains(":")) { + String fName = f.getName().replace(DATA_SUFFIX, "").replace(MD_SUFFIX, "") + .replace(TEPOCH_SUFFIX, ""); + + if (fileList.indexOf(fName) == -1) { + fileList.add(fName); + } + + } + } + } + } + + return fileList; + } + + @Override + public int getMasterEpoch(String fileId) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setMasterEpoch(String fileId, int masterEpoch) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public TruncateLog getTruncateLog(String fileId) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTruncateLog(String fileId, TruncateLog log) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public XLocSetVersionState getXLocSetVersionState(String fileId) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setXLocSetVersionState(String fileId, XLocSetVersionState versionState) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/StorageLayout.java b/java/servers/src/org/xtreemfs/osd/storage/StorageLayout.java new file mode 100644 index 0000000..4dd8b08 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/StorageLayout.java @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.osd.InternalObjectData; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState; + +/** + * Abstracts object data access from underlying on-disk storage layout. + * + * @author bjko + */ +public abstract class StorageLayout { + + /** + * read the full object (all available data) + */ + public static final int FULL_OBJECT_LENGTH = -1; + + /** + * read the full object (all available data) + */ + public static final int LATEST_VERSION = -1; + + /** + * file to store the layout and version used to create on disk data + */ + public static final String VERSION_FILENAME = ".version"; + + /** + * true, if we are on a windows platform + */ + public final static boolean WIN = System.getProperty("os.name").toLowerCase().contains( + "win"); + + /** + * base directory in which to store files + */ + protected final String storageDir; + + /** + * file metadata cache + */ + protected final MetadataCache cache; + + protected StorageLayout(OSDConfig config, MetadataCache cache) throws IOException { + + this.cache = cache; + + // initialize the storage directory + String tmp = config.getObjDir(); + if (!tmp.endsWith("/")) + tmp = tmp + "/"; + storageDir = tmp; + File stdir = new File(storageDir); + stdir.mkdirs(); + + // check the data version + File versionMetaFile = new File(storageDir, VERSION_FILENAME); + if (versionMetaFile.exists()) { + FileReader in = new FileReader(versionMetaFile); + char[] text = new char[(int) versionMetaFile.length()]; + in.read(text); + in.close(); + int versionOnDisk = Integer.valueOf(new String(text)); + if (!isCompatibleVersion(versionOnDisk)) { + throw new IOException("the OSD storage layout used to create the data on disk (" + + versionOnDisk + ") is not compatible with the storage layout loaded: " + + this.getClass().getSimpleName()); + } + } + + final File tmpFile = new File(versionMetaFile+".tmp"); + + FileWriter out = new FileWriter(tmpFile); + out.write(Integer.toString(getLayoutVersionTag())); + out.close(); + + tmpFile.renameTo(versionMetaFile); + + } + + /** + * Returns cached file metadata, or loads and caches it if it is not cached. + * + * @param sp + * @param fileId + * @return + * @throws IOException + */ + public FileMetadata getFileMetadata(final StripingPolicyImpl sp, final String fileId) throws IOException { + + // try to retrieve metadata from cache + FileMetadata fi = cache.getFileInfo(fileId); + + // if metadata is not cached ... + if (fi == null) { + + // ... load metadata from disk + fi = loadFileMetadata(fileId, sp); + + // ... cache metadata to speed up further accesses + cache.setFileInfo(fileId, fi); + } + + return fi; + } + + /** + * Returns cached file metadata, or loads it if it is not cached. + * + * @param sp + * @param fileId + * @return + * @throws IOException + */ + public FileMetadata getFileMetadataNoCaching(final StripingPolicyImpl sp, final String fileId) throws IOException { + + // try to retrieve metadata from cache + FileMetadata fi = cache.getFileInfo(fileId); + + // if metadata is not cached, load it + if (fi == null) + fi = loadFileMetadata(fileId, sp); + + return fi; + } + + /** + * Loads all metadata associated with a file on the OSD from the storage + * device. Amongst others, such metadata may comprise object version numbers + * and checksums. + * + * @param fileId + * the file ID + * @param sp + * the striping policy assigned to the file + * @return a FileInfo object comprising all metadata associated + * with the file + * @throws IOException + * if an error occurred while trying to read the metadata + */ + protected abstract FileMetadata loadFileMetadata(String fileId, StripingPolicyImpl sp) throws IOException; + + /** + * must be called when a file is closed + * @param metadata + */ + public void closeFile(FileMetadata metadata) { + //do nothing + } + + /** + * Reads a complete object from the storage device. + * + * @param fileId + * fileId of the object + * @param md + * file metadata + * @param objNo + * object number + * @param offset + * offset + * @param length + * length + * @param version + * version to be read + * @throws java.io.IOException + * when the object cannot be read + * @return ObjectInformation + */ + + public abstract ObjectInformation readObject(String fileId, FileMetadata md, long objNo, int offset, + int length, long version) throws IOException; + + /** + * Writes a partial object to the storage device. + * + * @param fileId + * the file Id the object belongs to + * @param md + * file metadata + * @param data + * buffer with the data to be written + * @param objNo + * object number + * @param offset + * the relative offset in the object at which to write the buffer + * @param newVersion + * new file version + * @param sync + * write synchronously + * @param cow + * use cow + * @throws java.io.IOException + * when the object cannot be written + */ + public abstract void writeObject(String fileId, FileMetadata md, ReusableBuffer data, long objNo, + int offset, long newVersion, boolean sync, boolean cow) throws IOException; + + /** + * Truncates an object on the storage device. + * + * @param fileId + * @param md + * @param objNo + * @param newLength + * @param newVersion + * @param cow + * @throws IOException + */ + public abstract void truncateObject(String fileId, FileMetadata md, long objNo, int newLength, + long newVersion, boolean cow) throws IOException; + + /** + * Deletes all versions of all objects of a file.
    + * Metadata (like the MasterEpoch, XLocSetVersionState, TruncateLog, ...) are kept unless deleteMetadata is set. + * + * @param fileId + * the ID of the file + * @param deleteMetadata + * delete metadata and empty directories. + * @throws IOException + * if an error occurred while deleting the objects + */ + public abstract void deleteFile(String fileId, boolean deleteMetadata) throws IOException; + + /** + * Deletes a single version of a single object of a file. + * + * @param fileId + * the ID of the file + * @param md + * file metadata + * @param objNo + * the number of the object to delete + * @param version + * the version number of the object to delete + * @throws IOException + * if an error occurred while deleting the object + */ + public abstract void deleteObject(String fileId, FileMetadata md, long objNo, long version) + throws IOException; + + /** + * Creates and stores a zero-padded object. + * + * @param fileId + * the ID of the file + * @param md + * file metadata + * @param objNo + * the number of the object to create + * @param version + * the version of the object to create + * @param size + * the size of the object to create + * @return if OSD checksums are enabled, the newly calculated checksum; + * null, otherwise + * @throws IOException + * if an error occurred when storing the object + */ + public abstract void createPaddingObject(String fileId, FileMetadata md, long objNo, long version, + int size) throws IOException; + + /** + * Persistently stores a new truncate epoch for a file. + * + * @param fileId + * the file ID + * @param newTruncateEpoch + * the new truncate epoch + * @throws IOException + * if an error occurred while storing the new epoch number + */ + public abstract void setTruncateEpoch(String fileId, long newTruncateEpoch) throws IOException; + + /** + * Checks whether the file with the given ID exists. + * + * @param fileId + * the ID of the file + * @return true, if the file exists, false, + * otherwise + */ + public abstract boolean fileExists(String fileId); + + protected ReusableBuffer unwrapObjectData(String fileId, FileMetadata md, long objNo, long oldVersion) + throws IOException { + ReusableBuffer data; + final int stripeSize = md.getStripingPolicy().getStripeSizeForObject(objNo); + final boolean isLastObj = (md.getLastObjectNumber() == objNo) || ((objNo == 0) && (md.getLastObjectNumber() == -1)); + ObjectInformation obj = readObject(fileId, md, objNo, 0, FULL_OBJECT_LENGTH, oldVersion); + InternalObjectData oldObject = obj.getObjectData(isLastObj, 0, stripeSize); + if (obj.getData() == null) { + if (oldObject.getZero_padding() > 0) { + // create a zero padded object + data = BufferPool.allocate(oldObject.getZero_padding()); + for (int i = 0; i < oldObject.getZero_padding(); i++) { + data.put((byte) 0); + } + data.position(0); + } else { + data = BufferPool.allocate(0); + } + } else { + if (oldObject.getZero_padding() > 0) { + data = BufferPool.allocate(obj.getData().capacity() + oldObject.getZero_padding()); + data.put(obj.getData()); + for (int i = 0; i < oldObject.getZero_padding(); i++) { + data.put((byte) 0); + } + } else { + data = obj.getData(); + } + } + return data; + } + + protected ReusableBuffer cow(String fileId, FileMetadata md, long objNo, ReusableBuffer data, int offset, + long oldVersion) throws IOException { + ReusableBuffer writeData = null; + final int stripeSize = md.getStripingPolicy().getStripeSizeForObject(objNo); + ObjectInformation obj = readObject(fileId, md, objNo, 0, FULL_OBJECT_LENGTH, oldVersion); + final boolean isLastObj = (md.getLastObjectNumber() == objNo) || ((objNo == 0) && (md.getLastObjectNumber() == -1)); + InternalObjectData oldObject = obj.getObjectData(isLastObj, 0, stripeSize); + if (obj.getData() == null) { + if (oldObject.getZero_padding() > 0) { + // create a zero padded object + writeData = BufferPool.allocate(stripeSize); + for (int i = 0; i < stripeSize; i++) { + writeData.put((byte) 0); + } + writeData.position(offset); + writeData.put(data); + writeData.position(0); + BufferPool.free(data); + } else { + // write beyond EOF + if (offset > 0) { + writeData = BufferPool.allocate(offset + data.capacity()); + for (int i = 0; i < offset; i++) { + writeData.put((byte) 0); + } + writeData.put(data); + writeData.position(0); + BufferPool.free(data); + } else { + writeData = data; + } + } + } else { + // object data exists on disk + if (obj.getData().capacity() >= offset + data.capacity()) { + // old object is large enough + writeData = obj.getData(); + writeData.position(offset); + writeData.put(data); + BufferPool.free(data); + } else { + // copy old data and then new data + writeData = BufferPool.allocate(offset + data.capacity()); + writeData.put(obj.getData()); + BufferPool.free(obj.getData()); + writeData.position(offset); + writeData.put(data); + BufferPool.free(data); + } + } + return writeData; + } + + /** + * Updates a single object in the current version of the file. If + * copy-on-write is enabled, this method has to be invoked when a new object + * version is written. + * + * @param fileId + * @param objNo + * @param newVersion + * @throws IOException + */ + public abstract void updateCurrentObjVersion(String fileId, long objNo, long newVersion) + throws IOException; + + /** + * Updates the size of current version of the file. If copy-on-write is + * enabled, this method has to be invoked when the file is truncated. + * + * @param fileId + * @param newLastObject + * @throws IOException + */ + public abstract void updateCurrentVersionSize(String fileId, long newLastObject) throws IOException; + + public abstract long getFileInfoLoadCount(); + + /** + * returns a list of all local saved objects of this file + * + * @param fileId + * @param md + * @return null, if file does not exist, otherwise objectList + */ + public abstract ObjectSet getObjectSet(String fileId, FileMetadata md); + + public abstract FileList getFileList(FileList l, int maxNumEntries); + + public abstract int getLayoutVersionTag(); + + public abstract boolean isCompatibleVersion(int layoutVersionTag); + + /** + * Retrieves the FleaseM master epoch stored for a file. + * @param fileId + * @return current master epoch stored on disk. + */ + public abstract int getMasterEpoch(String fileId) throws IOException; + + /** + * Stores the master epoch for a file on stable storage. + * @param fileId + * @param masterEpoch + */ + public abstract void setMasterEpoch(String fileId, int masterEpoch) throws IOException; + + public abstract TruncateLog getTruncateLog(String fileId) throws IOException; + + public abstract void setTruncateLog(String fileId, TruncateLog log) throws IOException; + /** + * returns a list of all files on OSD as fileID + * + * @return {@link HashMap} + */ + public abstract ArrayList getFileIDList(); + + /** + * Retrieves the XLocSet version and invalidated sate for a replica + * + * @param fileId + * @return current version and state stored on disk + */ + public abstract XLocSetVersionState getXLocSetVersionState(String fileId) throws IOException; + + /** + * Stores the XLocSet version for a replica on stable storage + * + * @param fileId + * @param versionState + */ + public abstract void setXLocSetVersionState(String fileId, XLocSetVersionState versionState) throws IOException; + + public static final class FileList { + // directories to scan + final Stack status; + + // fileName->fileDetails + final Map files; + + boolean hasMore; + + public FileList(Stack status, Map files) { + this.status = status; + this.files = files; + } + } + + public static final class FileData { + final long size; + final int objectSize; + final boolean metaDataOnly; + + FileData(long size, int objectSize) { + this.size = size; + this.objectSize = objectSize; + this.metaDataOnly = false; + } + + FileData(boolean metaDataOnly) { + this.size = 0; + this.objectSize = 0; + this.metaDataOnly = metaDataOnly; + } + } +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/StorageThread.java b/java/servers/src/org/xtreemfs/osd/storage/StorageThread.java new file mode 100644 index 0000000..39302af --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/StorageThread.java @@ -0,0 +1,1022 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Christian Lorenz, + * Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.Replica; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.stages.Stage; +import org.xtreemfs.osd.stages.StorageStage.CachesFlushedCallback; +import org.xtreemfs.osd.stages.StorageStage.CreateFileVersionCallback; +import org.xtreemfs.osd.stages.StorageStage.DeleteObjectsCallback; +import org.xtreemfs.osd.stages.StorageStage.GetFileIDListCallback; +import org.xtreemfs.osd.stages.StorageStage.GetFileSizeCallback; +import org.xtreemfs.osd.stages.StorageStage.GetObjectListCallback; +import org.xtreemfs.osd.stages.StorageStage.InternalGetGmaxCallback; +import org.xtreemfs.osd.stages.StorageStage.InternalGetMaxObjectNoCallback; +import org.xtreemfs.osd.stages.StorageStage.InternalGetReplicaStateCallback; +import org.xtreemfs.osd.stages.StorageStage.ReadObjectCallback; +import org.xtreemfs.osd.stages.StorageStage.TruncateCallback; +import org.xtreemfs.osd.stages.StorageStage.WriteObjectCallback; +import org.xtreemfs.osd.storage.VersionTable.Version; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +public class StorageThread extends Stage { + + public static final int STAGEOP_READ_OBJECT = 1; + + public static final int STAGEOP_WRITE_OBJECT = 2; + + public static final int STAGEOP_TRUNCATE = 3; + + public static final int STAGEOP_FLUSH_CACHES = 4; + + public static final int STAGEOP_GMAX_RECEIVED = 5; + + public static final int STAGEOP_GET_GMAX = 6; + + public static final int STAGEOP_GET_FILE_SIZE = 7; + + public static final int STAGEOP_GET_OBJECT_SET = 8; + + public static final int STAGEOP_INSERT_PADDING_OBJECT = 9; + + public static final int STAGEOP_GET_MAX_OBJNO = 10; + + public static final int STAGEOP_CREATE_FILE_VERSION = 11; + + public static final int STAGEOP_GET_REPLICA_STATE = 12; + + public static final int STAGEOP_GET_FILEID_LIST = 13; + + public static final int STAGEOP_DELETE_OBJECTS = 14; + + private MetadataCache cache; + + private StorageLayout layout; + + private OSDRequestDispatcher master; + + private final boolean checksumsEnabled; + + public StorageThread(int id, OSDRequestDispatcher dispatcher, MetadataCache cache, StorageLayout layout, + int maxQueueLength) { + + super("OSD StThr " + id, maxQueueLength); + + this.cache = cache; + this.layout = layout; + this.master = dispatcher; + this.checksumsEnabled = master.getConfig().isUseChecksums(); + } + + @Override + protected void processMethod(StageRequest method) { + + try { + + switch (method.getStageMethod()) { + case STAGEOP_READ_OBJECT: + processRead(method); + break; + case STAGEOP_WRITE_OBJECT: + processWrite(method); + break; + case STAGEOP_TRUNCATE: + processTruncate(method); + break; + case STAGEOP_FLUSH_CACHES: + processFlushCaches(method); + break; + case STAGEOP_GMAX_RECEIVED: + processGmax(method); + break; + case STAGEOP_GET_GMAX: + processGetGmax(method); + break; + case STAGEOP_GET_FILE_SIZE: + processGetFileSize(method); + break; + case STAGEOP_GET_OBJECT_SET: + processGetObjectSet(method); + break; + case STAGEOP_INSERT_PADDING_OBJECT: + processInsertPaddingObject(method); + break; + case STAGEOP_GET_MAX_OBJNO: + processGetMaxObjNo(method); + break; + case STAGEOP_CREATE_FILE_VERSION: + processCreateFileVersion(method); + break; + case STAGEOP_GET_REPLICA_STATE: + processGetReplicaState(method); + break; + case STAGEOP_GET_FILEID_LIST: + processGetFileIDList(method); + break; + case STAGEOP_DELETE_OBJECTS: + processDeleteObjects(method); + break; + } + + } catch (Exception ex) { + method.sendInternalServerError(ex); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + } + } + + private void processGetMaxObjNo(StageRequest rq) { + final InternalGetMaxObjectNoCallback cback = (InternalGetMaxObjectNoCallback) rq.getCallback(); + try { + final String fileId = (String) rq.getArgs()[0]; + final StripingPolicyImpl sp = (StripingPolicyImpl) rq.getArgs()[1]; + final FileMetadata fi = layout.getFileMetadata(sp, fileId); + + long currentMax = -1l; + + for (int i = 0; i < fi.getLastObjectNumber(); i++) { + final long objVer = fi.getLargestObjectVersion(i); + if (objVer > currentMax) + currentMax = objVer; + } + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "getmaxobjno for fileId %s: %d", + fileId, currentMax); + } + + cback.maxObjectNoCompleted(currentMax, fi.getFilesize(), fi.getTruncateEpoch(), null); + } catch (Exception ex) { + cback.maxObjectNoCompleted(0l, 0l, 0l, ErrorUtils.getErrorResponse(ErrorType.ERRNO, + POSIXErrno.POSIX_ERROR_EIO, ex.toString())); + } + } + + private void processGmax(StageRequest rq) { + try { + final String fileId = (String) rq.getArgs()[0]; + final long epoch = (Long) rq.getArgs()[1]; + final long lastObject = (Long) rq.getArgs()[2]; + + FileMetadata fi = cache.getFileInfo(fileId); + + if (fi == null) { + // file is not open, discard GMAX + return; + } + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "received new GMAX: %d/%d for %s", lastObject, epoch, fileId); + + if ((epoch == fi.getTruncateEpoch() && fi.getLastObjectNumber() < lastObject) + || epoch > fi.getTruncateEpoch()) { + + // valid file size update + fi.setGlobalLastObjectNumber(lastObject); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "received GMAX is valid; for %s, current (fs, epoch) = (%d, %d)", fileId, fi + .getFilesize(), fi.getTruncateEpoch()); + + } else { + + // outdated file size udpate + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "received GMAX is outdated; for %s, current (fs, epoch) = (%d, %d)", fileId, fi + .getFilesize(), fi.getTruncateEpoch()); + } + + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_DEBUG, this, ex); + return; + } + } + + private void processFlushCaches(StageRequest rq) { + final CachesFlushedCallback cback = (CachesFlushedCallback) rq.getCallback(); + try { + final String fileId = (String) rq.getArgs()[0]; + FileMetadata md = cache.removeFileInfo(fileId); + if (md != null) + layout.closeFile(null); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "removed file info from cache for file %s", fileId); + + cback.cachesFlushed(null, md); + } catch (Exception ex) { + rq.sendInternalServerError(ex); + return; + } + } + + private void processGetGmax(StageRequest rq) { + final InternalGetGmaxCallback cback = (InternalGetGmaxCallback) rq.getCallback(); + try { + final String fileId = (String) rq.getArgs()[0]; + final StripingPolicyImpl sp = (StripingPolicyImpl) rq.getArgs()[1]; + final long snapTimestamp = (Long) rq.getArgs()[2]; + + final FileMetadata fi = layout.getFileMetadata(sp, fileId); + // final boolean rangeRequested = (offset > 0) || (length < + // stripeSize); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "GET GMAX: %s", fileId); + } + + long fileSize = -1; + long lastObj = -1; + + // determine last object number and file size + + // in case of a previous file version, determine the last object + + // file size from the version table / data on disk + if (snapTimestamp > 0) { + Version v = fi.getVersionTable().getLatestVersionBefore(snapTimestamp); + lastObj = v.getObjCount() - 1; + fileSize = v.getFileSize(); + } + + // in case of the current version, retrieve last object + file size + // from the cached file metadata + else { + lastObj = fi.getLastObjectNumber(); + fileSize = fi.getFilesize(); + } + + InternalGmax gmax = InternalGmax.newBuilder().setEpoch(fi.getTruncateEpoch()).setFileSize( + fileSize).setLastObjectId(lastObj).build(); + + cback.gmaxComplete(gmax, null); + } catch (IOException ex) { + cback.gmaxComplete(null, ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, + ex.toString())); + } + + } + + private void processGetReplicaState(StageRequest rq) { + final InternalGetReplicaStateCallback cback = (InternalGetReplicaStateCallback) rq.getCallback(); + try { + final String fileId = (String) rq.getArgs()[0]; + final StripingPolicyImpl sp = (StripingPolicyImpl) rq.getArgs()[1]; + final long remoteMaxObjVer = (Long) rq.getArgs()[2]; + + // Do not assume that objects exist on the remote side based on the maxObjVer. + // The reason for that is the remote side may not have seen all consecutive writes + // up to maxObjVer. As an optimization, one could implement a marker which contains + // the minimal version which was actually seen by all replicas. Until then, + // remoteMaxObjVer must not be > 0. + assert remoteMaxObjVer == 0 : "Received a request with remoteMaxObjVer != 0." + + " This probably means that you run OSDs with different versions." + + " Please update all OSDs to the same version."; + + final FileMetadata fi = layout.getFileMetadata(sp, fileId); + // final boolean rangeRequested = (offset > 0) || (length < + // stripeSize); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "GET replica state: %s, remote max: %d", fileId, remoteMaxObjVer); + } + + ReplicaStatus.Builder result = ReplicaStatus.newBuilder(); + + result.setFileSize(fi.getFilesize()); + result.setTruncateEpoch(fi.getTruncateEpoch()); + + long localMaxObjVer = 0; + for (Entry e : fi.getLatestObjectVersions()) { + if (e.getValue() > remoteMaxObjVer) { + result.addObjectVersions(ObjectVersion.newBuilder().setObjectNumber(e.getKey()) + .setObjectVersion(e.getValue())); + if (e.getValue() > localMaxObjVer) + localMaxObjVer = e.getValue(); + } + } + result.setMaxObjVersion(localMaxObjVer); + result.setPrimaryEpoch(0); + result.setTruncateLog(layout.getTruncateLog(fileId)); + + cback.getReplicaStateComplete(result.build(), null); + } catch (IOException ex) { + cback.getReplicaStateComplete(null, ErrorUtils.getErrorResponse(ErrorType.ERRNO, + POSIXErrno.POSIX_ERROR_EIO, ex.toString())); + } + + } + + /** + * Reads an object from disk and checks the checksum + * + * @param rq + */ + private void processRead(StageRequest rq) { + final ReadObjectCallback cback = (ReadObjectCallback) rq.getCallback(); + try { + final String fileId = (String) rq.getArgs()[0]; + final long objNo = (Long) rq.getArgs()[1]; + final StripingPolicyImpl sp = (StripingPolicyImpl) rq.getArgs()[2]; + final int offset = (Integer) rq.getArgs()[3]; + final int length = (Integer) rq.getArgs()[4]; + final long versionTimestamp = (Long) rq.getArgs()[5]; + + final FileMetadata fi = layout.getFileMetadata(sp, fileId); + // final boolean rangeRequested = (offset > 0) || (length < + // stripeSize); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "READ: %s-%d offset=%d, length=%d", fileId, objNo, offset, length); + } + + // if a snapshot is supposed to be read, read the corresponding + // object version; otherwise, read the latest object version + long objVer = versionTimestamp != 0 ? fi.getVersionTable().getLatestVersionBefore( + versionTimestamp).getObjVersion(objNo) : fi.getLatestObjectVersion(objNo); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "getting objVer %d", objVer); + } + + long objChksm = fi.getObjectChecksum(objNo, objVer); + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "checksum is %d", objChksm); + } + + ObjectInformation obj = layout.readObject(fileId, fi, objNo, offset, length, objVer); + + if (versionTimestamp != 0) { + int lastObj = fi.getVersionTable().getLatestVersionBefore(versionTimestamp).getObjCount() - 1; + obj.setLastLocalObjectNo(lastObj); + obj.setGlobalLastObjectNo(lastObj); + } else { + obj.setLastLocalObjectNo(fi.getLastObjectNumber()); + obj.setGlobalLastObjectNo(fi.getGlobalLastObjectNumber()); + } + + cback.readComplete(obj, null); + } catch (IOException ex) { + cback.readComplete(null, ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, + ex.toString())); + } + + } + + /** + * returns the OSDs view of a files size + * + * @param rq + */ + private void processGetFileSize(StageRequest rq) { + final GetFileSizeCallback cback = (GetFileSizeCallback) rq.getCallback(); + try { + final String fileId = (String) rq.getArgs()[0]; + final StripingPolicyImpl sp = (StripingPolicyImpl) rq.getArgs()[1]; + final long snapTimestamp = (Long) rq.getArgs()[2]; + + final FileMetadata fi = layout.getFileMetadata(sp, fileId); + // final boolean rangeRequested = (offset > 0) || (length < + // stripeSize); + + // in case of a previous file version, determine + // file size from the version table / data on disk + if (snapTimestamp > 0) { + Version v = fi.getVersionTable().getLatestVersionBefore(snapTimestamp); + cback.getFileSizeComplete(v.getFileSize(), null); + } + + else + cback.getFileSizeComplete(fi.getFilesize(), null); + } catch (IOException ex) { + cback.getFileSizeComplete(-1, ErrorUtils.getErrorResponse(ErrorType.ERRNO, + POSIXErrno.POSIX_ERROR_EIO, ex.toString())); + } + + } + + private void processInsertPaddingObject(StageRequest rq) { + final WriteObjectCallback cback = (WriteObjectCallback) rq.getCallback(); + try { + final String fileId = (String) rq.getArgs()[0]; + final long objNo = (Long) rq.getArgs()[1]; + final StripingPolicyImpl sp = (StripingPolicyImpl) rq.getArgs()[2]; + final int size = (Integer) rq.getArgs()[3]; + final FileMetadata fi = layout.getFileMetadata(sp, fileId); + final long version = fi.getLatestObjectVersion(objNo) + 1; + + layout.createPaddingObject(fileId, fi, objNo, version, size); + + OSDWriteResponse response = OSDWriteResponse.newBuilder().build(); + cback.writeComplete(response, null); + + } catch (IOException ex) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, "Failed to create a padded object due to the following IOException:"); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + + cback.writeComplete(null, ErrorUtils.getErrorResponse(ErrorType.ERRNO, + POSIXErrno.POSIX_ERROR_EIO, ex.toString())); + } + } + + private void processWrite(StageRequest rq) { + final WriteObjectCallback cback = (WriteObjectCallback) rq.getCallback(); + try { + final String fileId = (String) rq.getArgs()[0]; + final long objNo = (Long) rq.getArgs()[1]; + final StripingPolicyImpl sp = (StripingPolicyImpl) rq.getArgs()[2]; + int offset = (Integer) rq.getArgs()[3]; + final ReusableBuffer data = (ReusableBuffer) rq.getArgs()[4]; + final CowPolicy cow = (CowPolicy) rq.getArgs()[5]; + final XLocations xloc = (XLocations) rq.getArgs()[6]; + final boolean gMaxOff = (Boolean) rq.getArgs()[7]; + final boolean syncWrite = (Boolean) rq.getArgs()[8]; + // use only if != null + final Long newVersionArg = (Long) rq.getArgs()[9]; + + final int dataLength = data.remaining(); + final int stripeSize = sp.getStripeSizeForObject(objNo); + final FileMetadata fi = layout.getFileMetadata(sp, fileId); + + if (Logging.isDebug()) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "WRITE: %s-%d. last objNo=%d dataSize=%d at offset=%d", fileId, objNo, fi + .getLastObjectNumber(), dataLength, offset); + } + final int dataCapacity = data.capacity(); + if (offset + dataCapacity > stripeSize) { + BufferPool.free(data); + cback.writeComplete(null, ErrorUtils.getErrorResponse(ErrorType.ERRNO, + POSIXErrno.POSIX_ERROR_EINVAL, "offset+data.length must be <= stripe size (offset=" + + offset + " data.length=" + dataCapacity + " stripe size=" + stripeSize + ")")); + return; + } + + // assign the number of objects to the COW policy if necessary (this + // is e.g. needed for the COW_ONCE policy) + cow.initCowFlagsIfRequired(fi.getLastObjectNumber() + 1); + + // determine the largest known version of the object + long largestV = fi.getLargestObjectVersion(objNo); + + // determine the object version to write + final boolean isCow = cow.isCOW((int) objNo); + + long newVersion = (isCow || checksumsEnabled) ? largestV + 1 : Math.max(1, largestV); + if (newVersionArg != null) { + // new version passed via arg always prevails + newVersion = newVersionArg; + } + assert (data != null); + + // make sure last object is set correctly! + if (objNo > fi.getLastObjectNumber()) { + fi.setLastObjectNumber(objNo); + } + + layout.writeObject(fileId, fi, data, objNo, offset, newVersion, syncWrite, isCow); + + // if a new version was created, update the "latest versions" file + if (cow.cowEnabled() && (isCow || largestV == 0)) + layout.updateCurrentObjVersion(fileId, objNo, newVersion); + + if (isCow) + cow.objectChanged((int) objNo); + + OSDWriteResponse.Builder response = OSDWriteResponse.newBuilder(); + + // if the write refers to the last known object or to an object + // beyond, i.e. the file size and globalMax are potentially + // affected: + if (objNo >= fi.getLastObjectNumber() && !gMaxOff) { + + long newObjSize = dataLength + offset; + + // calculate new filesize... + long newFS = 0; + if (objNo > 0) { + newFS = sp.getObjectEndOffset(objNo - 1) + 1 + newObjSize; + } else { + newFS = newObjSize; + } + if (newFS < fi.getFilesize()) { + newFS = fi.getFilesize(); + } + + // check whether the file size might have changed; in this case, + // ensure that the X-New-Filesize header will be set + if (newFS > fi.getFilesize() && objNo >= fi.getLastObjectNumber() + && objNo >= fi.getGlobalLastObjectNumber()) { + // Metadata meta = info.getMetadata(); + // meta.putKnownSize(newFS); + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "new filesize: %d", + newFS); + response.setSizeInBytes(newFS); + response.setTruncateEpoch((int) fi.getTruncateEpoch()); + } else { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "no new filesize: %d/%d, %d/%d", newFS, fi.getFilesize(), fi + .getLastObjectNumber(), objNo); + } + + // update file size and last object number + fi.setFilesize(newFS); + + // if the written object has a larger ID than the largest + // locally-known object of the file, send 'globalMax' messages + // to all other OSDs and update local globalMax + if (objNo > fi.getLastObjectNumber()) { + if (objNo > fi.getGlobalLastObjectNumber()) { + // send UDP packets... + final List osds = xloc.getLocalReplica().getOSDs(); + final ServiceUUID localUUID = master.getConfig().getUUID(); + if (osds.size() > 1) { + + RPCHeader.RequestHeader rqHdr = RPCHeader.RequestHeader.newBuilder().setAuthData( + RPCAuthentication.authNone).setUserCreds(RPCAuthentication.userService) + .setInterfaceId(OSDServiceConstants.INTERFACE_ID).setProcId( + OSDServiceConstants.PROC_ID_XTREEMFS_BROADCAST_GMAX).build(); + RPCHeader header = RPCHeader.newBuilder().setCallId(0).setMessageType( + MessageType.RPC_REQUEST).setRequestHeader(rqHdr).build(); + xtreemfs_broadcast_gmaxRequest gmaxRq = xtreemfs_broadcast_gmaxRequest + .newBuilder().setFileId(fileId).setTruncateEpoch(fi.getTruncateEpoch()) + .setLastObject(objNo).build(); + + for (ServiceUUID osd : osds) { + if (!osd.equals(localUUID)) { + master.sendUDPMessage(header, gmaxRq, osd.getAddress()); + } + } + } + } + } + } + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "new last object=%d gmax=%d", fi + .getLastObjectNumber(), fi.getGlobalLastObjectNumber()); + // BufferPool.free(data); + cback.writeComplete(response.build(), null); + + } catch (IOException ex) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.storage, this, "Failed to process write() request due to the following IOException:"); + Logging.logError(Logging.LEVEL_ERROR, this, ex); + + cback.writeComplete(null, ErrorUtils.getErrorResponse(ErrorType.ERRNO, + POSIXErrno.POSIX_ERROR_EIO, ex.toString())); + } + } + + private void processDeleteObjects(StageRequest rq) throws IOException { + + final DeleteObjectsCallback cback = (DeleteObjectsCallback) rq.getCallback(); + try { + final String fileId = (String) rq.getArgs()[0]; + final StripingPolicyImpl sp = (StripingPolicyImpl) rq.getArgs()[1]; + final long epochNumber = (Long) rq.getArgs()[2]; + final Map objectsToBeDeleted = (Map) rq.getArgs()[3]; + + final FileMetadata fi = layout.getFileMetadata(sp, fileId); + + // Delete objects. + for (Entry obj : objectsToBeDeleted.entrySet()) { + layout.deleteObject(fileId, fi, obj.getKey(), obj.getValue()); + } + layout.setTruncateEpoch(fileId, epochNumber); + + // Remove file info from cache to make sure it is reloaded with the next operation. + cache.removeFileInfo(fileId); + cback.deleteObjectsComplete(null); + } catch (Exception ex) { + cback.deleteObjectsComplete(ErrorUtils.getErrorResponse(ErrorType.ERRNO, + POSIXErrno.POSIX_ERROR_EIO, ex.toString())); + } + } + + private void processTruncate(StageRequest rq) throws IOException { + + final TruncateCallback cback = (TruncateCallback) rq.getCallback(); + try { + final String fileId = (String) rq.getArgs()[0]; + final long newFileSize = (Long) rq.getArgs()[1]; + final StripingPolicyImpl sp = (StripingPolicyImpl) rq.getArgs()[2]; + final Replica currentReplica = (Replica) rq.getArgs()[3]; + final long epochNumber = (Long) rq.getArgs()[4]; + final CowPolicy cow = (CowPolicy) rq.getArgs()[5]; + final Long newObjVer = (Long) rq.getArgs()[6]; + final Boolean createTLogEntry = (Boolean) rq.getArgs()[7]; + + final FileMetadata fi = layout.getFileMetadata(sp, fileId); + + if (fi.getTruncateEpoch() >= epochNumber) { + cback.truncateComplete( + OSDWriteResponse.newBuilder().setSizeInBytes(fi.getFilesize()) + .setTruncateEpoch((int) fi.getTruncateEpoch()).build(), null); + /* + * cback.truncateComplete(null, new + * OSDException(ErrorCodes.EPOCH_OUTDATED, + * "invalid truncate epoch for file " + fileId + ": " + + * epochNumber + ", current one is " + fi.getTruncateEpoch(), + * "")); + */ + return; + } + + // assign the number of objects to the COW policy if necessary (this + // is e.g. needed for the COW_ONCE policy) + cow.initCowFlagsIfRequired(fi.getLastObjectNumber() + 1); + + // find the offset of the local OSD in the current replica's + // locations list + // FIXME: unify OSD IDs + final int relativeOSDNumber = currentReplica.getOSDs().indexOf(master.getConfig().getUUID()); + + long newLastObject = -1; + long newGlobalLastObject = -1; + + if (newFileSize == 0) { + // truncate file to zero length + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "truncate to 0"); + + // if copy-on-write is enabled ... + if (cow.cowEnabled()) { + + // only delete those objects that make up the latest + // version of the file and are not part of former file + // versions + + for (Entry entry : fi.getLatestObjectVersions()) { + + long objNo = entry.getKey(); + long objVer = entry.getValue(); + + if (!fi.getVersionTable().isContained(objNo, objVer)) + layout.deleteObject(fileId, fi, objNo, objVer); + } + } + + // otherwise ... + else + // delete all objects of the file (but not the metadata) + layout.deleteFile(fileId, false); + + fi.clearLatestObjectVersions(); + + } else if (fi.getFilesize() > newFileSize) { + // shrink file + newLastObject = truncateShrink(fileId, newFileSize, epochNumber, sp, fi, relativeOSDNumber, + cow, newObjVer); + newGlobalLastObject = sp.getObjectNoForOffset(newFileSize - 1); + } else if (fi.getFilesize() < newFileSize) { + // extend file + newLastObject = truncateExtend(fileId, newFileSize, epochNumber, sp, fi, relativeOSDNumber, + cow, newObjVer); + newGlobalLastObject = sp.getObjectNoForOffset(newFileSize - 1); + } else if (fi.getFilesize() == newFileSize) { + // file size remains unchanged + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "truncate to local size: %d", newFileSize); + + newLastObject = fi.getLastObjectNumber(); + newGlobalLastObject = fi.getGlobalLastObjectNumber(); + } + + // set the new file size and last object number + fi.setFilesize(newFileSize); + fi.setLastObjectNumber(newLastObject); + fi.setTruncateEpoch(epochNumber); + + fi.setGlobalLastObjectNumber(newGlobalLastObject); + + // store the truncate epoch persistently + layout.setTruncateEpoch(fileId, epochNumber); + + // if copy-on-write is enabled, set the new object count for the + // latest version + if (cow.cowEnabled()) + layout.updateCurrentVersionSize(fileId, newLastObject); + + if (createTLogEntry) { + TruncateLog log = layout.getTruncateLog(fileId); + log = log.toBuilder().addRecords(TruncateRecord.newBuilder().setVersion(newObjVer).setLastObjectNumber(newLastObject)).build(); + layout.setTruncateLog(fileId, log); + } + + // append the new file size and epoch number to the response + OSDWriteResponse response = OSDWriteResponse.newBuilder().setSizeInBytes(newFileSize) + .setTruncateEpoch((int) epochNumber).build(); + cback.truncateComplete(response, null); + + } catch (Exception ex) { + cback.truncateComplete(null, ErrorUtils.getErrorResponse(ErrorType.ERRNO, + POSIXErrno.POSIX_ERROR_EIO, ex.toString())); + } + + } + + private void processGetObjectSet(StageRequest rq) { + final GetObjectListCallback cback = (GetObjectListCallback) rq.getCallback(); + final String fileId = (String) rq.getArgs()[0]; + final StripingPolicyImpl sp = (StripingPolicyImpl) rq.getArgs()[1]; + + try { + final FileMetadata fi = layout.getFileMetadata(sp, fileId); + ObjectSet objectSet = layout.getObjectSet(fileId, fi); + cback.getObjectSetComplete(objectSet, null); + } catch (Exception ex) { + cback.getObjectSetComplete(null, ErrorUtils.getErrorResponse(ErrorType.ERRNO, + POSIXErrno.POSIX_ERROR_EIO, ex.toString())); + } + } + + private void processCreateFileVersion(StageRequest rq) { + + final CreateFileVersionCallback cback = (CreateFileVersionCallback) rq.getCallback(); + final String fileId = (String) rq.getArgs()[0]; + + FileMetadata fi = (FileMetadata) rq.getArgs()[1]; + + try { + + if (fi == null) + fi = layout.getFileMetadataNoCaching(null, fileId); + + Set> objVersions = fi.getLatestObjectVersions(); + long fileSize = fi.getFilesize(); + + // convert the set of object versions into an array + + // first, determine the last object + long maxKey = -1; + for (Entry ver : objVersions) { + if (ver.getKey() > maxKey) + maxKey = ver.getKey(); + } + + // instantiate a sufficiently large array + assert (maxKey < Integer.MAX_VALUE); + int[] versions = new int[(int) maxKey + 1]; + + // set all object versions in the array + for (Entry ver : objVersions) + versions[ver.getKey().intValue()] = ver.getValue().intValue(); + + // create and save the new version + fi.getVersionTable().addVersion(TimeSync.getGlobalTime(), versions, fileSize); + try { + fi.getVersionTable().save(); + } catch (IOException e) { + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, OutputUtils + .stackTraceToString(e)); + } + + cback.createFileVersionComplete(fileSize, null); + + } catch (Exception ex) { + + Logging.logError(Logging.LEVEL_ERROR, this, ex); + cback.createFileVersionComplete(0, ErrorUtils.getErrorResponse(ErrorType.ERRNO, + POSIXErrno.POSIX_ERROR_EIO, ex.toString())); + } + + } + + private void processGetFileIDList(StageRequest rq) { + final GetFileIDListCallback cback = (GetFileIDListCallback) rq.getCallback(); + ArrayList fileIDList = null; + try { + + if (layout != null) { + fileIDList = layout.getFileIDList(); + } + + cback.createGetFileIDListComplete(fileIDList, null); + + } catch (Exception ex) { + Logging.logError(Logging.LEVEL_ERROR, this, ex); + cback.createGetFileIDListComplete(null, ErrorUtils.getErrorResponse(ErrorType.ERRNO, + POSIXErrno.POSIX_ERROR_EIO, ex.toString())); + + } + } + + private long truncateShrink(String fileId, long fileSize, long epoch, StripingPolicyImpl sp, + FileMetadata fi, int relOsdId, CowPolicy cow, Long newObjVer) throws IOException { + // first find out which is the new "last object" + final long newLastObject = sp.getObjectNoForOffset(fileSize - 1); + final long oldLastObject = fi.getLastObjectNumber(); + assert (newLastObject <= oldLastObject) : "new= " + newLastObject + " old=" + oldLastObject; + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "truncate shrink to: %d old last: %d new last: %d", fileSize, fi.getLastObjectNumber(), + newLastObject); + + // if copy-on-write enabled ... + if (cow.cowEnabled()) { + + // only remove objects that are no longer bound to former file + // versions + final long oldRow = sp.getRow(oldLastObject); + final long lastRow = sp.getRow(newLastObject); + + for (long r = oldRow; r >= lastRow; r--) { + + final long rowObj = r * sp.getWidth() + relOsdId; + + if (rowObj == newLastObject) { + // currently examined object is new last object and local: + // shrink it + final int newObjSize = (int) (fileSize - sp.getObjectStartOffset(newLastObject)); + truncateObject(fileId, newLastObject, sp, newObjSize, relOsdId, cow, newObjVer); + + } else if (rowObj > newLastObject) { + + // currently examined object is larger than new last object + // and not contained in any previous version of the file: + // delete it + final long v = fi.getLatestObjectVersion(rowObj); + if (!fi.getVersionTable().isContained(rowObj, v)) + layout.deleteObject(fileId, fi, rowObj, v); + + fi.discardObject(rowObj, v); + } + } + + } + + // otherwise ... + else { + + // remove all unnecessary objects + final long oldRow = sp.getRow(oldLastObject); + final long lastRow = sp.getRow(newLastObject); + + for (long r = oldRow; r >= lastRow; r--) { + final long rowObj = r * sp.getWidth() + relOsdId; + + if (rowObj == newLastObject) { + // currently examined object is new last object and local: + // shrink it + final int newObjSize = (int) (fileSize - sp.getObjectStartOffset(newLastObject)); + truncateObject(fileId, newLastObject, sp, newObjSize, relOsdId, cow, newObjVer); + + } else if (rowObj > newLastObject) { + + // currently examined object is larger than new last object: + // delete it + final long v = fi.getLatestObjectVersion(rowObj); + layout.deleteObject(fileId, fi, rowObj, v); + + fi.discardObject(rowObj, v); + } + } + + } + + // make sure that new last object exists + for (long obj = newLastObject - 1; obj > newLastObject - sp.getWidth(); obj--) { + if (obj > 0 && sp.isLocalObject(obj, relOsdId)) { + long v = fi.getLatestObjectVersion(obj); + if (v == 0) { + // does not exist + createPaddingObject(fileId, obj, sp, fi.getLargestObjectVersion(obj) + 1, sp + .getStripeSizeForObject(obj), fi); + } + } + } + + return newLastObject; + } + + private long truncateExtend(String fileId, long fileSize, long epoch, StripingPolicyImpl sp, + FileMetadata fi, int relOsdId, CowPolicy cow, Long newObjVer) throws IOException { + // first find out which is the new "last object" + final long newLastObject = sp.getObjectNoForOffset(fileSize - 1); + final long oldLastObject = fi.getLastObjectNumber(); + assert (newLastObject >= oldLastObject); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, + "truncate extend to: %d old last: %d new last: %d", fileSize, oldLastObject, newLastObject); + + // if no objects need to be added and the last object is stored locally + // ... + if ((sp.getOSDforObject(newLastObject) == relOsdId) && newLastObject == oldLastObject) { + // ... simply extend the old one + truncateObject(fileId, newLastObject, sp, (int) (fileSize - sp + .getObjectStartOffset(newLastObject)), relOsdId, cow, newObjVer); + } + + // otherwise ... + else { + + // extend the old last object to full object size + if ((oldLastObject > -1) && (sp.isLocalObject(oldLastObject, relOsdId))) { + truncateObject(fileId, oldLastObject, sp, sp.getStripeSizeForObject(oldLastObject), relOsdId, + cow, newObjVer); + } + + // if the new last object is a local object, create a padding + // object to ensure that it exists + if (sp.isLocalObject(newLastObject, relOsdId)) { + + long version = newObjVer != null ? newObjVer : (cow.isCOW((int) newLastObject) ? fi + .getLargestObjectVersion(newLastObject) + 1 : Math.max(1, fi + .getLargestObjectVersion(newLastObject))); + int objSize = (int) (fileSize - sp.getObjectStartOffset(newLastObject)); + + createPaddingObject(fileId, newLastObject, sp, version, objSize, fi); + } + + // make sure that new last objects also exist on all other OSDs + for (long obj = newLastObject - 1; obj > newLastObject - sp.getWidth(); obj--) { + if (obj > 0 && sp.isLocalObject(obj, relOsdId)) { + long v = fi.getLatestObjectVersion(obj); + if (v == 0) { + // does not exist + final boolean isCow = cow.isCOW((int) obj); + final long newVersion = newObjVer != null ? newObjVer : (isCow ? fi + .getLargestObjectVersion(obj) + 1 : Math.max(1, fi + .getLargestObjectVersion(obj))); + createPaddingObject(fileId, obj, sp, newVersion, sp.getStripeSizeForObject(obj), fi); + } + } + } + + } + + return newLastObject; + } + + private void truncateObject(String fileId, long objNo, StripingPolicyImpl sp, int newSize, long relOsdId, + CowPolicy cow, Long newObjVer) throws IOException { + + assert (newSize > 0) : "new size is " + newSize + " but should be > 0"; + assert (newSize <= sp.getStripeSizeForObject(objNo)); + assert (objNo >= 0) : "objNo is " + objNo; + assert (sp.getOSDforObject(objNo) == relOsdId); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.proc, this, "truncate object to %d", newSize); + + final FileMetadata fi = layout.getFileMetadata(sp, fileId); + final boolean isCow = cow.isCOW((int) objNo); + final long newVersion = newObjVer != null ? newObjVer + : (isCow ? fi.getLargestObjectVersion(objNo) + 1 : Math.max(1, fi.getLatestObjectVersion(objNo))); + + layout.truncateObject(fileId, fi, objNo, newSize, newVersion, isCow); + + } + + private void createPaddingObject(String fileId, long objNo, StripingPolicyImpl sp, long version, + int size, FileMetadata fi) throws IOException { + layout.createPaddingObject(fileId, fi, objNo, version, size); + } +} diff --git a/java/servers/src/org/xtreemfs/osd/storage/VersionTable.java b/java/servers/src/org/xtreemfs/osd/storage/VersionTable.java new file mode 100644 index 0000000..c1f5078 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/storage/VersionTable.java @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2010-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.storage; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.Map.Entry; + +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; + +/** + * This class implements a version table for a file. The version table maps time + * stamps to lists of object versions. + * + * @author stender + */ +public class VersionTable { + + private static final long D_MAX = 2000; // 2s + + public static class Version { + + protected static final Version EMPTY_VERSION = new Version(new int[0], 0); + + private int[] objVersions; + + private long fileSize; + + public Version(int[] objVersions, long fileSize) { + this.objVersions = objVersions; + this.fileSize = fileSize; + } + + public long getFileSize() { + return fileSize; + } + + public int getObjCount() { + return objVersions.length; + } + + public int getObjVersion(long objNo) { + assert (objNo <= Integer.MAX_VALUE); + return objNo >= objVersions.length ? 0 : objVersions[(int) objNo]; + } + + } + + /** + * internal table with file-to-object-list mappings + */ + private SortedMap vt; + + private File vtFile; + + /** + * Creates a new empty version table. + * + * @param vtFile + * the file that persistently stores the table + */ + public VersionTable(File vtFile) { + vt = new TreeMap(); + this.vtFile = vtFile; + } + + /** + * Loads a version table from a file. Previous content in the table is + * discarded. + * + * @throws IOException + * if an I/O error occurs + */ + public synchronized void load() throws IOException { + + if (vtFile == null) + throw new IOException("no source file specified"); + + vt.clear(); + + FileInputStream fi = new FileInputStream(vtFile); + ReusableBuffer buf = BufferPool.allocate((int) vtFile.length()); + fi.getChannel().read(buf.getBuffer()); + buf.position(0); + + while (buf.position() < buf.limit()) { + + final long timestamp = buf.getLong(); + final long fileSize = buf.getLong(); + final long numObjs = buf.getLong(); + + assert (numObjs <= Integer.MAX_VALUE) : "number of objects: " + numObjs + ", current limit = " + + Integer.MAX_VALUE; + // TODO: solve this problem for files with more than + // Integer.MAX_VALUE objects + + final int[] objVersions = new int[(int) numObjs]; + for (int i = 0; i < objVersions.length; i++) + objVersions[i] = buf.getInt(); + + addVersion(timestamp, objVersions, fileSize); + } + + BufferPool.free(buf); + fi.close(); + + } + + /** + * Stores the current content of the version table in a file. + * + * @throws IOException + * if an I/O error occurs + */ + public synchronized void save() throws IOException { + + if (vtFile == null) + throw new IOException("no target file specified"); + + FileOutputStream fo = new FileOutputStream(vtFile); + + for (Entry entry : vt.entrySet()) { + + ReusableBuffer buf = BufferPool.allocate((Long.SIZE / 8) * 3 + entry.getValue().getObjCount() + * Integer.SIZE / 8); + buf.putLong(entry.getKey()); + buf.putLong(entry.getValue().getFileSize()); + buf.putLong(entry.getValue().getObjCount()); + for (int i = 0; i < entry.getValue().getObjCount(); i++) + buf.putInt(entry.getValue().getObjVersion(i)); + + fo.write(buf.array()); + BufferPool.free(buf); + } + + fo.close(); + } + + /** + * Returns the latest version of a file stored in the table before the given + * timestamp. + * + * @param timestamp + * the time stamp + * @return the latest file version before timestamp. + */ + public Version getLatestVersionBefore(long timestamp) { + try { + return vt.get(vt.headMap(timestamp).lastKey()); + } catch (NoSuchElementException exc) { + // if there is no file version before the given timestamp, return an + // empty file + return Version.EMPTY_VERSION; + } + } + + /** + * Adds a new file version to the table. + * + * @param timestamp + * the time stamp attached to the file version + * @param objVersions + * the set of object versions attached to the file version + */ + public void addVersion(long timestamp, int[] objVersions, long fileSize) { + vt.put(timestamp, new Version(objVersions, fileSize)); + } + + /** + * Deletes a file version from the table. + * + * @param timestamp + * the timestamp attached to the file version + */ + public void deleteVersion(long timestamp) { + vt.remove(timestamp); + } + + /** + * Determines the set of object versions that can be cleaned up, under the + * assumption that snapshots with the given timestamps exist. The + * corresponding file versions are removed from the version table. + * + * @param timestamps + * a list of timestamps for which the object versions need to be + * preserved + * @return a mapping from object numbers to sets of object versions that + * are obsolete and may be deleted + */ + public synchronized Map> cleanup(long[] timestamps) { + + SortedMap cleanedTable = new TreeMap(vt); + + Map> result = new HashMap>(); + + // first, determine all file versions that are superseeded + + Long[] tsArray = cleanedTable.keySet().toArray(new Long[cleanedTable.size()]); + + // no object versions to delete if no file versions exist + if (tsArray.length == 0) + return result; + + // otherwise, check which versions are superseeded + SortedMap superseeded = new TreeMap(); + for (int i = 0; i < tsArray.length; i++) { + + long currentTs = tsArray[i]; + long nextTs = i == tsArray.length - 1? Long.MAX_VALUE: tsArray[i + 1]; + + // check if there is a timestamp t in 'timestamps' with currentTs - + // d_max < t < nextTs + d_max + boolean isSuperseeded = true; + for (long t : timestamps) + if (currentTs - D_MAX < t && t < nextTs + D_MAX) { + isSuperseeded = false; + break; + } + + if (isSuperseeded) + superseeded.put(currentTs, cleanedTable.get(currentTs)); + + } + + // remove all superseeded versions + for (long ts : superseeded.keySet()) + cleanedTable.remove(ts); + + // for all superseeded versions, check which objects do not occur in + // non-superseeded versions + for (Version v: superseeded.values()) { + + for (int i = 0; i < v.objVersions.length; i++) { + + int version = v.objVersions[i]; + if (!isContained(i, version, cleanedTable)) { + Set versions = result.get(i); + if (versions == null) { + versions = new HashSet(); + result.put(i, versions); + } + versions.add(version); + } + } + } + + vt = cleanedTable; + + return result; + } + + /** + * Returns the total number of versions stored in the table. + * + * @return the number of versions + */ + public long getVersionCount() { + return vt.size(); + } + + /** + * Checks if the given version of the given object is contained in any of + * the file versions. + * + * @param objNo + * the object number + * @param objVer + * the object version + * @return true, if it is contained, false, + * otherwise + */ + public boolean isContained(long objNo, long objVer) { + return isContained(objNo, objVer, vt); + } + + private static boolean isContained(long objNo, long objVer, SortedMap vtable) { + + assert (objNo <= Integer.MAX_VALUE); + + if (objVer == 0) + return false; + + for (Version versions : vtable.values()) + if (objNo < versions.getObjCount() && objVer == versions.getObjVersion((int) objNo)) + return true; + + return false; + } + +} diff --git a/java/servers/src/org/xtreemfs/osd/templates/status.html b/java/servers/src/org/xtreemfs/osd/templates/status.html new file mode 100644 index 0000000..c258ca7 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/templates/status.html @@ -0,0 +1,172 @@ + + + XtreemFS OSD @ <!-- $UUID --> + + + + +

    OSD

    +
    +
    File IDStatus
    "); + sb.append(fileId); + final String role = status.get(fileId).get("role"); + String bgcolor = "#FFFFFF"; + if (role != null && role.equals("primary")) { + bgcolor = "#A3FFA3"; + } else if (role != null && role.startsWith("backup")) { + bgcolor = "#FFFF66"; + } + sb.append(""); + for (Entry e : status.get(fileId).entrySet()) { + sb.append("\n"); + } + sb.append("
    "); + sb.append(e.getKey()); + sb.append(""); + sb.append(e.getValue()); + sb.append("
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Version +
    XtreemFSOSD
    RPC Interface
    + Configuration +
    TCP & UDP port
    Directory Service
    Debug Level
    Statistics
    + Load +
    # client connections
    # pending client requests
    Preproc Stage queue length
    Storage Stage queue length
    Deletion Stage queue length
    Open files
    + Transfer +
    # object written
    # object read
    bytes sent
    bytes received
    # files deleted
    # replicated object written
    bytes replicated
    + VM Info / Memory +
    Free Disk Space
    Java VM stats (free/max/total)
    Buffer Pool stats
    + Time +
    global XtreeemFS time
    resync interval for global time ms
    local system time
    local time update interval ms
    + UUID Mapping Cache +
    + Detailed Status +
    + List of active replicated files
    + Full stack trace (all threads)
    + + \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/osd/vivaldi/VivaldiNode.java b/java/servers/src/org/xtreemfs/osd/vivaldi/VivaldiNode.java new file mode 100644 index 0000000..3d657fc --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/vivaldi/VivaldiNode.java @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2009-2011 by Juan Gonzalez de Benito, + * Barcelona Supercomputing Center + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.vivaldi; + +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; + +/** + * Node of a Vivaldi Coordinate System. + * + * @author Juan Gonzalez de Benito (BSC) + */ +public class VivaldiNode { + + /** + * Coordinates that define a position in the coordinate system. + */ + private VivaldiCoordinates vCoordinates; + + /** + * Constant E used by the Vivaldi algorithm to manage the evolution of + * the local error. + */ + private final double CONSTANT_E = 0.10; + /** + * Constant C used by the Vivaldi algorithm to adjust the distance the node + * moves in each recalculation. + */ + private final double CONSTANT_C = 0.25; + + /** + * Ratio of the current distance between two nodes, used to set the difference + * between what we consider "right moves" and "wrong moves". + */ + private final double MAX_MOVEMENT_RATIO = 0.10; + + + public VivaldiNode(){ + + this.vCoordinates = VivaldiCoordinates.newBuilder().setLocalError(0).setXCoordinate(0).setYCoordinate(0).build(); + + } + /** + * + * @return the current coordinates of the node. + */ + public VivaldiCoordinates getCoordinates(){ + return vCoordinates; + } + + /** + * Multiplies a pair of coordinates by a given real number. + * + * @param coordA the coordinates to be multiplied. + * @param value the real number to multiply by. + * @return the result of the multiplication. + */ + private VivaldiCoordinates multiplyValueCoordinates(VivaldiCoordinates coordA, double value){ + VivaldiCoordinates.Builder ret = VivaldiCoordinates.newBuilder(); + ret.setXCoordinate( coordA.getXCoordinate() * value ); + ret.setYCoordinate( coordA.getYCoordinate() * value ); + ret.setLocalError(0); + return ret.build(); + } + + /** + * Adds two pairs of coordinates. + * + * @param coordA a pair of coordinates. + * @param coordB a pair of coordinates. + * @return a pair of coordinates that represent the result of the addition. + */ + private VivaldiCoordinates addCoordinates(VivaldiCoordinates coordA,VivaldiCoordinates coordB){ + VivaldiCoordinates.Builder ret = VivaldiCoordinates.newBuilder(); + ret.setXCoordinate( coordA.getXCoordinate() + coordB.getXCoordinate() ); + ret.setYCoordinate( coordA.getYCoordinate() + coordB.getYCoordinate() ); + ret.setLocalError(0); + return ret.build(); + } + + /** + * Subtracts two pairs of coordinates. + * + * @param coordA a pair of coordinates. + * @param coordB a pair of coordinates. + * @return a pair of coordinates that represent the result of the addition. + */ + private VivaldiCoordinates subtractCoordinates(VivaldiCoordinates coordA,VivaldiCoordinates coordB){ + return addCoordinates( coordA, multiplyValueCoordinates(coordB,-1.0) ); + } + + /** + * Multiplies two pairs of coordinates using the scalar product. + * A · B = Ax*Bx + Ay*By + * + * @param coordA a pair of coordinates. + * @param coordB a pair of coordinates. + * @return the result of the scalar product. + */ + private double scalarProductCoordinates(VivaldiCoordinates coordA, VivaldiCoordinates coordB){ + + double ret = 0.0; + + // A · B = Ax*Bx + Ay*By + ret += coordA.getXCoordinate() * coordB.getXCoordinate(); + ret += coordA.getYCoordinate() * coordB.getYCoordinate(); + + return ret; + + } + + /** + * Calculates the magnitude of a given vector. + * + * @param coordA the coordinates whose magnitude must be calculated. + * @return the distance from the position defined by the coordinates to the + * origin of the system. + */ + private double magnitudeCoordinates(VivaldiCoordinates coordA){ + // ||A|| = sqrt( Ax² + Ay² ) + return Math.sqrt( scalarProductCoordinates(coordA,coordA) ); + } + + /** + * Calculates the unitary vector of a given vector. + * + * @param coordA Coordinates to calculate the unitary vector from. + * @return a vector with the same direction but with magnitude == 1. + */ + private VivaldiCoordinates getUnitaryCoordinates(VivaldiCoordinates coordA){ + // unit(A) = A * ( 1 / ||A|| ) + // ||unit(A)|| = 1 + double magn = magnitudeCoordinates(coordA); + return multiplyValueCoordinates( coordA, 1.0/magn ); + } + + /** + * Modifies a pair of coordinates with a couple of random values, so they are + * included in the interval (-1,1) and have also a random direction. + * + * @param coordA coordinates that must be modified. + */ + private VivaldiCoordinates getRandomCoordinates(){ + VivaldiCoordinates.Builder coordA = VivaldiCoordinates.newBuilder(); + coordA.setXCoordinate( (Math.random()*2) - 1 ); + coordA.setYCoordinate( (Math.random()*2) - 1 ); + coordA.setLocalError(0.0); // this has to be set to avoid com.google.protobuf.UninitializedMessageException + return coordA.build(); + } + + public static double calculateDistance(VivaldiCoordinates pointA,VivaldiCoordinates pointB){ + VivaldiNode auxNode = new VivaldiNode(); + return auxNode.magnitudeCoordinates( auxNode.subtractCoordinates(pointA, pointB) ); + + } + public static String coordinatesToString(VivaldiCoordinates vc) { + + StringBuffer sb = new StringBuffer(3*Long.SIZE/8); + OutputUtils.writeHexLong(sb, Double.doubleToRawLongBits(vc.getXCoordinate())); + OutputUtils.writeHexLong(sb, Double.doubleToRawLongBits(vc.getYCoordinate())); + OutputUtils.writeHexLong(sb, Double.doubleToRawLongBits(vc.getLocalError())); + + return sb.toString(); + } + + public static VivaldiCoordinates stringToCoordinates(String coordinates) { + VivaldiCoordinates.Builder vc = VivaldiCoordinates.newBuilder(); + vc.setXCoordinate(Double.longBitsToDouble(OutputUtils.readHexLong(coordinates, 0))); + vc.setYCoordinate(Double.longBitsToDouble(OutputUtils.readHexLong(coordinates, 16))); + vc.setLocalError(Double.longBitsToDouble(OutputUtils.readHexLong(coordinates, 32))); + return vc.build(); + } + + /** + * Modifies the position of the node according to the current distance to a + * given point in the coordinate space and the real RTT measured against it. + * + * @param coordinatesJ coordinates of a different node. + * @param measuredRTT RTT measured with the other node. + */ + public boolean recalculatePosition(VivaldiCoordinates coordinatesJ, long measuredRTT,boolean forceRecalculation){ + + assert( measuredRTT>=0 ) : "Wrong RTT"; + + boolean ret = true; + + double localError = vCoordinates.getLocalError(); + + //SUBTRACTION = Xi - Xj + VivaldiCoordinates subtractionVector = subtractCoordinates(vCoordinates, coordinatesJ ); + // ||SUBTRACTION|| should be ~= RTT + double subtractionMagnitude = magnitudeCoordinates(subtractionVector); + + //Sample weight balances local and remote error + //If it's close to 1, J knows more than me: localError > errorJ + //If it's close to 0.5, we both know the same: A/2A = 1/2 + //If it's close to 0, I know more than it: localError < errorJ + double weight = 0.0; + + //Two nodes shouldn't be in the same position + if( measuredRTT == 0 ){ + measuredRTT = 1; + } + + //Compute relative error of this sample + double relativeError = ((double)Math.abs( subtractionMagnitude - measuredRTT)) / (double)measuredRTT; + + //Calculate weight + if( localError <= 0.0 ){ + weight = 1; + }else{ + if( coordinatesJ.getLocalError() > 0.0 ){ + weight = localError/ (localError + Math.abs(coordinatesJ.getLocalError())); + } //else weight is 0.0 + } + + //Calculate proposed movement + double delta; + delta = CONSTANT_C * weight; + double estimatedMovement = ((double)measuredRTT-subtractionMagnitude) * delta; + + if( forceRecalculation || //The recalculation must be done anyhow + (subtractionMagnitude<=0.0) || //The nodes are in the same position + (estimatedMovement<0) || //The nodes must get closer + (Math.abs(estimatedMovement) < subtractionMagnitude * MAX_MOVEMENT_RATIO) ){ //The movement is not too big + + //Update local error + if( localError <= 0 ){ + //We initialize the local error with the first measured absolute error + localError = (double)Math.abs( subtractionMagnitude - (double)measuredRTT); + }else{ + //Compute relative weight moving average of local error + localError = (relativeError * CONSTANT_E * weight) + localError* (1-(CONSTANT_E*weight)); + } + + VivaldiCoordinates additionVector = null; + + if( subtractionMagnitude > 0.0 ){ + //Xi = Xi + delta * (rtt - || Xi - Xj ||) * u(Xi - Xj) + additionVector = multiplyValueCoordinates( getUnitaryCoordinates(subtractionVector), estimatedMovement); + }else{ + //Both points have the same Coordinates, so we just pull them apart in a random direction + VivaldiCoordinates randomCoords = getRandomCoordinates(); + + //Xi = Xi + delta * (rtt - || Xi - Xj ||) * u(Xi - Xj) + additionVector = multiplyValueCoordinates( getUnitaryCoordinates(randomCoords), estimatedMovement); + } + + //Move the node according to the calculated addition vector + vCoordinates = addCoordinates( vCoordinates, additionVector); + vCoordinates = vCoordinates.toBuilder().setLocalError(localError).build(); + + } else { + //The proposed movement is too big according to the current distance btw nodes + ret = false; + } + + return ret; + } +} diff --git a/java/servers/src/org/xtreemfs/osd/vivaldi/ZipfGenerator.java b/java/servers/src/org/xtreemfs/osd/vivaldi/ZipfGenerator.java new file mode 100644 index 0000000..35221f9 --- /dev/null +++ b/java/servers/src/org/xtreemfs/osd/vivaldi/ZipfGenerator.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2009-2011 by Juan Gonzalez de Benito, Jonathan Marti, + * Barcelona Supercomputing Center + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.osd.vivaldi; + +import java.util.Random; + +public class ZipfGenerator { + + private Random rnd; + //private Random rnd = new Random(0); + private int size; + private double skew; + private double bottom; + + public ZipfGenerator(int size, double skew) { + this.rnd = new Random(System.currentTimeMillis()); + this.skew = skew; + this.setSize(size); + + + } + + /** + * Method that returns a rank id between 0 and this.size (exclusive). + * The frequency of returned rank id follows the Zipf distribution represented by this class. + * @return a rank id between 0 and this.size. + * @throws lptracegen.DistributionGenerator.DistributionException + */ + + public int next(){ + int rank = -1; + double frequency = 0.0d; + double dice = 0.0d; + while (dice >= frequency) { + rank = this.rnd.nextInt(this.size); + frequency = getProbability(rank + 1);//(0 is not allowed for probability computation) + dice = this.rnd.nextDouble(); + } + return rank; + } + + /** + * Method that computes the probability (0.0 .. 1.0) that a given rank occurs. + * The rank cannot be zero. + * @param rank + * @return probability that the given rank occurs (over 1) + * @throws lptracegen.DistributionGenerator.DistributionException + */ + public double getProbability(int rank) { + if (rank == 0) { + throw new RuntimeException("getProbability - rank must be > 0"); + } + return (1.0d / Math.pow(rank, this.skew)) / this.bottom; + } + + public void setSize(int newSize){ + this.size = newSize; + //calculate the generalized harmonic number of order 'size' of 'skew' + //http://en.wikipedia.org/wiki/Harmonic_number + this.bottom = 0; + for (int i = 1; i <= size; i++) { + this.bottom += (1.0d / Math.pow(i, this.skew)); + } + } + + /** + * Method that returns a Zipf distribution + * result[i] = probability that rank i occurs + * @return the zipf distribution + * @throws lptracegen.DistributionGenerator.DistributionException + */ + public double[] getDistribution() { + double[] result = new double[this.size]; + for ( int i = 1; i <= this.size; i++) { //i==0 is not allowed to compute probability + result[i - 1] = getProbability(i); + } + return result; + } + + /** + * Method that computes an array of length == this.size + * with the occurrences for every rank i (following the Zipf) + * result[i] = #occurrences of rank i + * @param size + * @return result[i] = #occurrences of rank i + * @throws lptracegen.DistributionGenerator.DistributionException + */ + public int[] getRankArray(int totalEvents) { + int[] result = new int[this.size]; + for (int i = 0; i < totalEvents; i++) { + int rank = next(); + result[rank] += 1; + } + return result; + } +} diff --git a/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/Common.java b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/Common.java new file mode 100644 index 0000000..aafb22c --- /dev/null +++ b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/Common.java @@ -0,0 +1,699 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: include/Common.proto + +package org.xtreemfs.pbrpc.generatedinterfaces; + +public final class Common { + private Common() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + public interface emptyRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + } + /** + * Protobuf type {@code xtreemfs.pbrpc.emptyRequest} + * + *
    +   * Dummy message for requests without parameters.
    +   * The RPC implementation sends an empty message block.
    +   * 
    + */ + public static final class emptyRequest extends + com.google.protobuf.GeneratedMessage + implements emptyRequestOrBuilder { + // Use emptyRequest.newBuilder() to construct. + private emptyRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private emptyRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final emptyRequest defaultInstance; + public static emptyRequest getDefaultInstance() { + return defaultInstance; + } + + public emptyRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private emptyRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.internal_static_xtreemfs_pbrpc_emptyRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.internal_static_xtreemfs_pbrpc_emptyRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public emptyRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new emptyRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private void initFields() { + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.emptyRequest} + * + *
    +     * Dummy message for requests without parameters.
    +     * The RPC implementation sends an empty message block.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.internal_static_xtreemfs_pbrpc_emptyRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.internal_static_xtreemfs_pbrpc_emptyRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.internal_static_xtreemfs_pbrpc_emptyRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest(this); + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest.getDefaultInstance()) return this; + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.emptyRequest) + } + + static { + defaultInstance = new emptyRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.emptyRequest) + } + + public interface emptyResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + } + /** + * Protobuf type {@code xtreemfs.pbrpc.emptyResponse} + * + *
    +   * Dummy message for responses without content.
    +   * The RPC implementation sends an empty message block.
    +   * 
    + */ + public static final class emptyResponse extends + com.google.protobuf.GeneratedMessage + implements emptyResponseOrBuilder { + // Use emptyResponse.newBuilder() to construct. + private emptyResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private emptyResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final emptyResponse defaultInstance; + public static emptyResponse getDefaultInstance() { + return defaultInstance; + } + + public emptyResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private emptyResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.internal_static_xtreemfs_pbrpc_emptyResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.internal_static_xtreemfs_pbrpc_emptyResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public emptyResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new emptyResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private void initFields() { + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.emptyResponse} + * + *
    +     * Dummy message for responses without content.
    +     * The RPC implementation sends an empty message block.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.internal_static_xtreemfs_pbrpc_emptyResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.internal_static_xtreemfs_pbrpc_emptyResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.internal_static_xtreemfs_pbrpc_emptyResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse(this); + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse.getDefaultInstance()) return this; + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.Common.emptyResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.emptyResponse) + } + + static { + defaultInstance = new emptyResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.emptyResponse) + } + + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_emptyRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_emptyRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_emptyResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_emptyResponse_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\024include/Common.proto\022\016xtreemfs.pbrpc\"\016" + + "\n\014emptyRequest\"\017\n\remptyResponseB(\n&org.x" + + "treemfs.pbrpc.generatedinterfaces" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_xtreemfs_pbrpc_emptyRequest_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_xtreemfs_pbrpc_emptyRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_emptyRequest_descriptor, + new java.lang.String[] { }); + internal_static_xtreemfs_pbrpc_emptyResponse_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_xtreemfs_pbrpc_emptyResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_emptyResponse_descriptor, + new java.lang.String[] { }); + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIR.java b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIR.java new file mode 100644 index 0000000..a9ae035 --- /dev/null +++ b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIR.java @@ -0,0 +1,13773 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/DIR.proto + +package org.xtreemfs.pbrpc.generatedinterfaces; + +public final class DIR { + private DIR() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + /** + * Protobuf enum {@code xtreemfs.pbrpc.ServiceType} + */ + public enum ServiceType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * SERVICE_TYPE_MIXED = 0; + * + *
    +     * Returns a list of all service types.
    +     * 
    + */ + SERVICE_TYPE_MIXED(0, 0), + /** + * SERVICE_TYPE_MRC = 1; + */ + SERVICE_TYPE_MRC(1, 1), + /** + * SERVICE_TYPE_OSD = 2; + */ + SERVICE_TYPE_OSD(2, 2), + /** + * SERVICE_TYPE_VOLUME = 3; + */ + SERVICE_TYPE_VOLUME(3, 3), + /** + * SERVICE_TYPE_DIR = 4; + */ + SERVICE_TYPE_DIR(4, 4), + ; + + /** + * SERVICE_TYPE_MIXED = 0; + * + *
    +     * Returns a list of all service types.
    +     * 
    + */ + public static final int SERVICE_TYPE_MIXED_VALUE = 0; + /** + * SERVICE_TYPE_MRC = 1; + */ + public static final int SERVICE_TYPE_MRC_VALUE = 1; + /** + * SERVICE_TYPE_OSD = 2; + */ + public static final int SERVICE_TYPE_OSD_VALUE = 2; + /** + * SERVICE_TYPE_VOLUME = 3; + */ + public static final int SERVICE_TYPE_VOLUME_VALUE = 3; + /** + * SERVICE_TYPE_DIR = 4; + */ + public static final int SERVICE_TYPE_DIR_VALUE = 4; + + + public final int getNumber() { return value; } + + public static ServiceType valueOf(int value) { + switch (value) { + case 0: return SERVICE_TYPE_MIXED; + case 1: return SERVICE_TYPE_MRC; + case 2: return SERVICE_TYPE_OSD; + case 3: return SERVICE_TYPE_VOLUME; + case 4: return SERVICE_TYPE_DIR; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public ServiceType findValueByNumber(int number) { + return ServiceType.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.getDescriptor().getEnumTypes().get(0); + } + + private static final ServiceType[] VALUES = values(); + + public static ServiceType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private ServiceType(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.ServiceType) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.ServiceStatus} + */ + public enum ServiceStatus + implements com.google.protobuf.ProtocolMessageEnum { + /** + * SERVICE_STATUS_AVAIL = 0; + * + *
    +     * Service is available.
    +     * 
    + */ + SERVICE_STATUS_AVAIL(0, 0), + /** + * SERVICE_STATUS_TO_BE_REMOVED = 1; + * + *
    +     * Service (OSD) will be removed, new files are
    +     * not allocated to this OSD.
    +     * 
    + */ + SERVICE_STATUS_TO_BE_REMOVED(1, 1), + /** + * SERVICE_STATUS_REMOVED = 2; + * + *
    +     * Service was removed permanently, data is lost.
    +     * 
    + */ + SERVICE_STATUS_REMOVED(2, 2), + ; + + /** + * SERVICE_STATUS_AVAIL = 0; + * + *
    +     * Service is available.
    +     * 
    + */ + public static final int SERVICE_STATUS_AVAIL_VALUE = 0; + /** + * SERVICE_STATUS_TO_BE_REMOVED = 1; + * + *
    +     * Service (OSD) will be removed, new files are
    +     * not allocated to this OSD.
    +     * 
    + */ + public static final int SERVICE_STATUS_TO_BE_REMOVED_VALUE = 1; + /** + * SERVICE_STATUS_REMOVED = 2; + * + *
    +     * Service was removed permanently, data is lost.
    +     * 
    + */ + public static final int SERVICE_STATUS_REMOVED_VALUE = 2; + + + public final int getNumber() { return value; } + + public static ServiceStatus valueOf(int value) { + switch (value) { + case 0: return SERVICE_STATUS_AVAIL; + case 1: return SERVICE_STATUS_TO_BE_REMOVED; + case 2: return SERVICE_STATUS_REMOVED; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public ServiceStatus findValueByNumber(int number) { + return ServiceStatus.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.getDescriptor().getEnumTypes().get(1); + } + + private static final ServiceStatus[] VALUES = values(); + + public static ServiceStatus valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private ServiceStatus(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.ServiceStatus) + } + + public interface AddressMappingOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string uuid = 1; + /** + * required string uuid = 1; + * + *
    +     * UUID being mapped.
    +     * 
    + */ + boolean hasUuid(); + /** + * required string uuid = 1; + * + *
    +     * UUID being mapped.
    +     * 
    + */ + java.lang.String getUuid(); + /** + * required string uuid = 1; + * + *
    +     * UUID being mapped.
    +     * 
    + */ + com.google.protobuf.ByteString + getUuidBytes(); + + // required fixed64 version = 2; + /** + * required fixed64 version = 2; + * + *
    +     * Version of this record.
    +     * 
    + */ + boolean hasVersion(); + /** + * required fixed64 version = 2; + * + *
    +     * Version of this record.
    +     * 
    + */ + long getVersion(); + + // required string protocol = 3; + /** + * required string protocol = 3; + * + *
    +     * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +     * 
    + */ + boolean hasProtocol(); + /** + * required string protocol = 3; + * + *
    +     * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +     * 
    + */ + java.lang.String getProtocol(); + /** + * required string protocol = 3; + * + *
    +     * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +     * 
    + */ + com.google.protobuf.ByteString + getProtocolBytes(); + + // required string address = 4; + /** + * required string address = 4; + * + *
    +     * FQDN or IP address of the server.
    +     * 
    + */ + boolean hasAddress(); + /** + * required string address = 4; + * + *
    +     * FQDN or IP address of the server.
    +     * 
    + */ + java.lang.String getAddress(); + /** + * required string address = 4; + * + *
    +     * FQDN or IP address of the server.
    +     * 
    + */ + com.google.protobuf.ByteString + getAddressBytes(); + + // required fixed32 port = 5; + /** + * required fixed32 port = 5; + * + *
    +     * TCP/UDP port number.
    +     * 
    + */ + boolean hasPort(); + /** + * required fixed32 port = 5; + * + *
    +     * TCP/UDP port number.
    +     * 
    + */ + int getPort(); + + // required string match_network = 6; + /** + * required string match_network = 6; + * + *
    +     * Matching network. There has to exist exactly one default address 
    +     * accessible from any network for which this is set to "*".
    +     * 
    + */ + boolean hasMatchNetwork(); + /** + * required string match_network = 6; + * + *
    +     * Matching network. There has to exist exactly one default address 
    +     * accessible from any network for which this is set to "*".
    +     * 
    + */ + java.lang.String getMatchNetwork(); + /** + * required string match_network = 6; + * + *
    +     * Matching network. There has to exist exactly one default address 
    +     * accessible from any network for which this is set to "*".
    +     * 
    + */ + com.google.protobuf.ByteString + getMatchNetworkBytes(); + + // required fixed32 ttl_s = 7; + /** + * required fixed32 ttl_s = 7; + * + *
    +     * Time to live in seconds before the
    +     * entry should be evicted from caches.
    +     * 
    + */ + boolean hasTtlS(); + /** + * required fixed32 ttl_s = 7; + * + *
    +     * Time to live in seconds before the
    +     * entry should be evicted from caches.
    +     * 
    + */ + int getTtlS(); + + // required string uri = 8; + /** + * required string uri = 8; + * + *
    +     * URI, obsolete.
    +     * 
    + */ + boolean hasUri(); + /** + * required string uri = 8; + * + *
    +     * URI, obsolete.
    +     * 
    + */ + java.lang.String getUri(); + /** + * required string uri = 8; + * + *
    +     * URI, obsolete.
    +     * 
    + */ + com.google.protobuf.ByteString + getUriBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.AddressMapping} + * + *
    +   * For each server UUID, at least one address mapping must exist.
    +   * Each record maps a UUID to one FQDN or IP address and port.
    +   * 
    + */ + public static final class AddressMapping extends + com.google.protobuf.GeneratedMessage + implements AddressMappingOrBuilder { + // Use AddressMapping.newBuilder() to construct. + private AddressMapping(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private AddressMapping(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final AddressMapping defaultInstance; + public static AddressMapping getDefaultInstance() { + return defaultInstance; + } + + public AddressMapping getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AddressMapping( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + uuid_ = input.readBytes(); + break; + } + case 17: { + bitField0_ |= 0x00000002; + version_ = input.readFixed64(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + protocol_ = input.readBytes(); + break; + } + case 34: { + bitField0_ |= 0x00000008; + address_ = input.readBytes(); + break; + } + case 45: { + bitField0_ |= 0x00000010; + port_ = input.readFixed32(); + break; + } + case 50: { + bitField0_ |= 0x00000020; + matchNetwork_ = input.readBytes(); + break; + } + case 61: { + bitField0_ |= 0x00000040; + ttlS_ = input.readFixed32(); + break; + } + case 66: { + bitField0_ |= 0x00000080; + uri_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_AddressMapping_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_AddressMapping_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public AddressMapping parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AddressMapping(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string uuid = 1; + public static final int UUID_FIELD_NUMBER = 1; + private java.lang.Object uuid_; + /** + * required string uuid = 1; + * + *
    +     * UUID being mapped.
    +     * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string uuid = 1; + * + *
    +     * UUID being mapped.
    +     * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + uuid_ = s; + } + return s; + } + } + /** + * required string uuid = 1; + * + *
    +     * UUID being mapped.
    +     * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 version = 2; + public static final int VERSION_FIELD_NUMBER = 2; + private long version_; + /** + * required fixed64 version = 2; + * + *
    +     * Version of this record.
    +     * 
    + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 version = 2; + * + *
    +     * Version of this record.
    +     * 
    + */ + public long getVersion() { + return version_; + } + + // required string protocol = 3; + public static final int PROTOCOL_FIELD_NUMBER = 3; + private java.lang.Object protocol_; + /** + * required string protocol = 3; + * + *
    +     * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +     * 
    + */ + public boolean hasProtocol() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string protocol = 3; + * + *
    +     * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +     * 
    + */ + public java.lang.String getProtocol() { + java.lang.Object ref = protocol_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + protocol_ = s; + } + return s; + } + } + /** + * required string protocol = 3; + * + *
    +     * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +     * 
    + */ + public com.google.protobuf.ByteString + getProtocolBytes() { + java.lang.Object ref = protocol_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + protocol_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string address = 4; + public static final int ADDRESS_FIELD_NUMBER = 4; + private java.lang.Object address_; + /** + * required string address = 4; + * + *
    +     * FQDN or IP address of the server.
    +     * 
    + */ + public boolean hasAddress() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required string address = 4; + * + *
    +     * FQDN or IP address of the server.
    +     * 
    + */ + public java.lang.String getAddress() { + java.lang.Object ref = address_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + address_ = s; + } + return s; + } + } + /** + * required string address = 4; + * + *
    +     * FQDN or IP address of the server.
    +     * 
    + */ + public com.google.protobuf.ByteString + getAddressBytes() { + java.lang.Object ref = address_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + address_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 port = 5; + public static final int PORT_FIELD_NUMBER = 5; + private int port_; + /** + * required fixed32 port = 5; + * + *
    +     * TCP/UDP port number.
    +     * 
    + */ + public boolean hasPort() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 port = 5; + * + *
    +     * TCP/UDP port number.
    +     * 
    + */ + public int getPort() { + return port_; + } + + // required string match_network = 6; + public static final int MATCH_NETWORK_FIELD_NUMBER = 6; + private java.lang.Object matchNetwork_; + /** + * required string match_network = 6; + * + *
    +     * Matching network. There has to exist exactly one default address 
    +     * accessible from any network for which this is set to "*".
    +     * 
    + */ + public boolean hasMatchNetwork() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required string match_network = 6; + * + *
    +     * Matching network. There has to exist exactly one default address 
    +     * accessible from any network for which this is set to "*".
    +     * 
    + */ + public java.lang.String getMatchNetwork() { + java.lang.Object ref = matchNetwork_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + matchNetwork_ = s; + } + return s; + } + } + /** + * required string match_network = 6; + * + *
    +     * Matching network. There has to exist exactly one default address 
    +     * accessible from any network for which this is set to "*".
    +     * 
    + */ + public com.google.protobuf.ByteString + getMatchNetworkBytes() { + java.lang.Object ref = matchNetwork_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + matchNetwork_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 ttl_s = 7; + public static final int TTL_S_FIELD_NUMBER = 7; + private int ttlS_; + /** + * required fixed32 ttl_s = 7; + * + *
    +     * Time to live in seconds before the
    +     * entry should be evicted from caches.
    +     * 
    + */ + public boolean hasTtlS() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required fixed32 ttl_s = 7; + * + *
    +     * Time to live in seconds before the
    +     * entry should be evicted from caches.
    +     * 
    + */ + public int getTtlS() { + return ttlS_; + } + + // required string uri = 8; + public static final int URI_FIELD_NUMBER = 8; + private java.lang.Object uri_; + /** + * required string uri = 8; + * + *
    +     * URI, obsolete.
    +     * 
    + */ + public boolean hasUri() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * required string uri = 8; + * + *
    +     * URI, obsolete.
    +     * 
    + */ + public java.lang.String getUri() { + java.lang.Object ref = uri_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + uri_ = s; + } + return s; + } + } + /** + * required string uri = 8; + * + *
    +     * URI, obsolete.
    +     * 
    + */ + public com.google.protobuf.ByteString + getUriBytes() { + java.lang.Object ref = uri_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uri_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + uuid_ = ""; + version_ = 0L; + protocol_ = ""; + address_ = ""; + port_ = 0; + matchNetwork_ = ""; + ttlS_ = 0; + uri_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasUuid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasProtocol()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasAddress()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPort()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMatchNetwork()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTtlS()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasUri()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getUuidBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(2, version_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getProtocolBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBytes(4, getAddressBytes()); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeFixed32(5, port_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeBytes(6, getMatchNetworkBytes()); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeFixed32(7, ttlS_); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + output.writeBytes(8, getUriBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getUuidBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(2, version_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getProtocolBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, getAddressBytes()); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(5, port_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(6, getMatchNetworkBytes()); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(7, ttlS_); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(8, getUriBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.AddressMapping} + * + *
    +     * For each server UUID, at least one address mapping must exist.
    +     * Each record maps a UUID to one FQDN or IP address and port.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_AddressMapping_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_AddressMapping_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + uuid_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + version_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + protocol_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + address_ = ""; + bitField0_ = (bitField0_ & ~0x00000008); + port_ = 0; + bitField0_ = (bitField0_ & ~0x00000010); + matchNetwork_ = ""; + bitField0_ = (bitField0_ & ~0x00000020); + ttlS_ = 0; + bitField0_ = (bitField0_ & ~0x00000040); + uri_ = ""; + bitField0_ = (bitField0_ & ~0x00000080); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_AddressMapping_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.uuid_ = uuid_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.version_ = version_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.protocol_ = protocol_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.address_ = address_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.port_ = port_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.matchNetwork_ = matchNetwork_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000040; + } + result.ttlS_ = ttlS_; + if (((from_bitField0_ & 0x00000080) == 0x00000080)) { + to_bitField0_ |= 0x00000080; + } + result.uri_ = uri_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.getDefaultInstance()) return this; + if (other.hasUuid()) { + bitField0_ |= 0x00000001; + uuid_ = other.uuid_; + onChanged(); + } + if (other.hasVersion()) { + setVersion(other.getVersion()); + } + if (other.hasProtocol()) { + bitField0_ |= 0x00000004; + protocol_ = other.protocol_; + onChanged(); + } + if (other.hasAddress()) { + bitField0_ |= 0x00000008; + address_ = other.address_; + onChanged(); + } + if (other.hasPort()) { + setPort(other.getPort()); + } + if (other.hasMatchNetwork()) { + bitField0_ |= 0x00000020; + matchNetwork_ = other.matchNetwork_; + onChanged(); + } + if (other.hasTtlS()) { + setTtlS(other.getTtlS()); + } + if (other.hasUri()) { + bitField0_ |= 0x00000080; + uri_ = other.uri_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasUuid()) { + + return false; + } + if (!hasVersion()) { + + return false; + } + if (!hasProtocol()) { + + return false; + } + if (!hasAddress()) { + + return false; + } + if (!hasPort()) { + + return false; + } + if (!hasMatchNetwork()) { + + return false; + } + if (!hasTtlS()) { + + return false; + } + if (!hasUri()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string uuid = 1; + private java.lang.Object uuid_ = ""; + /** + * required string uuid = 1; + * + *
    +       * UUID being mapped.
    +       * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string uuid = 1; + * + *
    +       * UUID being mapped.
    +       * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + uuid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string uuid = 1; + * + *
    +       * UUID being mapped.
    +       * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string uuid = 1; + * + *
    +       * UUID being mapped.
    +       * 
    + */ + public Builder setUuid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + uuid_ = value; + onChanged(); + return this; + } + /** + * required string uuid = 1; + * + *
    +       * UUID being mapped.
    +       * 
    + */ + public Builder clearUuid() { + bitField0_ = (bitField0_ & ~0x00000001); + uuid_ = getDefaultInstance().getUuid(); + onChanged(); + return this; + } + /** + * required string uuid = 1; + * + *
    +       * UUID being mapped.
    +       * 
    + */ + public Builder setUuidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + uuid_ = value; + onChanged(); + return this; + } + + // required fixed64 version = 2; + private long version_ ; + /** + * required fixed64 version = 2; + * + *
    +       * Version of this record.
    +       * 
    + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 version = 2; + * + *
    +       * Version of this record.
    +       * 
    + */ + public long getVersion() { + return version_; + } + /** + * required fixed64 version = 2; + * + *
    +       * Version of this record.
    +       * 
    + */ + public Builder setVersion(long value) { + bitField0_ |= 0x00000002; + version_ = value; + onChanged(); + return this; + } + /** + * required fixed64 version = 2; + * + *
    +       * Version of this record.
    +       * 
    + */ + public Builder clearVersion() { + bitField0_ = (bitField0_ & ~0x00000002); + version_ = 0L; + onChanged(); + return this; + } + + // required string protocol = 3; + private java.lang.Object protocol_ = ""; + /** + * required string protocol = 3; + * + *
    +       * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +       * 
    + */ + public boolean hasProtocol() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string protocol = 3; + * + *
    +       * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +       * 
    + */ + public java.lang.String getProtocol() { + java.lang.Object ref = protocol_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + protocol_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string protocol = 3; + * + *
    +       * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +       * 
    + */ + public com.google.protobuf.ByteString + getProtocolBytes() { + java.lang.Object ref = protocol_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + protocol_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string protocol = 3; + * + *
    +       * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +       * 
    + */ + public Builder setProtocol( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + protocol_ = value; + onChanged(); + return this; + } + /** + * required string protocol = 3; + * + *
    +       * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +       * 
    + */ + public Builder clearProtocol() { + bitField0_ = (bitField0_ & ~0x00000004); + protocol_ = getDefaultInstance().getProtocol(); + onChanged(); + return this; + } + /** + * required string protocol = 3; + * + *
    +       * Protocol, see org.xtreemfs.foundation.pbrpc.Schemes for values.
    +       * 
    + */ + public Builder setProtocolBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + protocol_ = value; + onChanged(); + return this; + } + + // required string address = 4; + private java.lang.Object address_ = ""; + /** + * required string address = 4; + * + *
    +       * FQDN or IP address of the server.
    +       * 
    + */ + public boolean hasAddress() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required string address = 4; + * + *
    +       * FQDN or IP address of the server.
    +       * 
    + */ + public java.lang.String getAddress() { + java.lang.Object ref = address_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + address_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string address = 4; + * + *
    +       * FQDN or IP address of the server.
    +       * 
    + */ + public com.google.protobuf.ByteString + getAddressBytes() { + java.lang.Object ref = address_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + address_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string address = 4; + * + *
    +       * FQDN or IP address of the server.
    +       * 
    + */ + public Builder setAddress( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + address_ = value; + onChanged(); + return this; + } + /** + * required string address = 4; + * + *
    +       * FQDN or IP address of the server.
    +       * 
    + */ + public Builder clearAddress() { + bitField0_ = (bitField0_ & ~0x00000008); + address_ = getDefaultInstance().getAddress(); + onChanged(); + return this; + } + /** + * required string address = 4; + * + *
    +       * FQDN or IP address of the server.
    +       * 
    + */ + public Builder setAddressBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + address_ = value; + onChanged(); + return this; + } + + // required fixed32 port = 5; + private int port_ ; + /** + * required fixed32 port = 5; + * + *
    +       * TCP/UDP port number.
    +       * 
    + */ + public boolean hasPort() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 port = 5; + * + *
    +       * TCP/UDP port number.
    +       * 
    + */ + public int getPort() { + return port_; + } + /** + * required fixed32 port = 5; + * + *
    +       * TCP/UDP port number.
    +       * 
    + */ + public Builder setPort(int value) { + bitField0_ |= 0x00000010; + port_ = value; + onChanged(); + return this; + } + /** + * required fixed32 port = 5; + * + *
    +       * TCP/UDP port number.
    +       * 
    + */ + public Builder clearPort() { + bitField0_ = (bitField0_ & ~0x00000010); + port_ = 0; + onChanged(); + return this; + } + + // required string match_network = 6; + private java.lang.Object matchNetwork_ = ""; + /** + * required string match_network = 6; + * + *
    +       * Matching network. There has to exist exactly one default address 
    +       * accessible from any network for which this is set to "*".
    +       * 
    + */ + public boolean hasMatchNetwork() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required string match_network = 6; + * + *
    +       * Matching network. There has to exist exactly one default address 
    +       * accessible from any network for which this is set to "*".
    +       * 
    + */ + public java.lang.String getMatchNetwork() { + java.lang.Object ref = matchNetwork_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + matchNetwork_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string match_network = 6; + * + *
    +       * Matching network. There has to exist exactly one default address 
    +       * accessible from any network for which this is set to "*".
    +       * 
    + */ + public com.google.protobuf.ByteString + getMatchNetworkBytes() { + java.lang.Object ref = matchNetwork_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + matchNetwork_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string match_network = 6; + * + *
    +       * Matching network. There has to exist exactly one default address 
    +       * accessible from any network for which this is set to "*".
    +       * 
    + */ + public Builder setMatchNetwork( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000020; + matchNetwork_ = value; + onChanged(); + return this; + } + /** + * required string match_network = 6; + * + *
    +       * Matching network. There has to exist exactly one default address 
    +       * accessible from any network for which this is set to "*".
    +       * 
    + */ + public Builder clearMatchNetwork() { + bitField0_ = (bitField0_ & ~0x00000020); + matchNetwork_ = getDefaultInstance().getMatchNetwork(); + onChanged(); + return this; + } + /** + * required string match_network = 6; + * + *
    +       * Matching network. There has to exist exactly one default address 
    +       * accessible from any network for which this is set to "*".
    +       * 
    + */ + public Builder setMatchNetworkBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000020; + matchNetwork_ = value; + onChanged(); + return this; + } + + // required fixed32 ttl_s = 7; + private int ttlS_ ; + /** + * required fixed32 ttl_s = 7; + * + *
    +       * Time to live in seconds before the
    +       * entry should be evicted from caches.
    +       * 
    + */ + public boolean hasTtlS() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required fixed32 ttl_s = 7; + * + *
    +       * Time to live in seconds before the
    +       * entry should be evicted from caches.
    +       * 
    + */ + public int getTtlS() { + return ttlS_; + } + /** + * required fixed32 ttl_s = 7; + * + *
    +       * Time to live in seconds before the
    +       * entry should be evicted from caches.
    +       * 
    + */ + public Builder setTtlS(int value) { + bitField0_ |= 0x00000040; + ttlS_ = value; + onChanged(); + return this; + } + /** + * required fixed32 ttl_s = 7; + * + *
    +       * Time to live in seconds before the
    +       * entry should be evicted from caches.
    +       * 
    + */ + public Builder clearTtlS() { + bitField0_ = (bitField0_ & ~0x00000040); + ttlS_ = 0; + onChanged(); + return this; + } + + // required string uri = 8; + private java.lang.Object uri_ = ""; + /** + * required string uri = 8; + * + *
    +       * URI, obsolete.
    +       * 
    + */ + public boolean hasUri() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * required string uri = 8; + * + *
    +       * URI, obsolete.
    +       * 
    + */ + public java.lang.String getUri() { + java.lang.Object ref = uri_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + uri_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string uri = 8; + * + *
    +       * URI, obsolete.
    +       * 
    + */ + public com.google.protobuf.ByteString + getUriBytes() { + java.lang.Object ref = uri_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uri_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string uri = 8; + * + *
    +       * URI, obsolete.
    +       * 
    + */ + public Builder setUri( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000080; + uri_ = value; + onChanged(); + return this; + } + /** + * required string uri = 8; + * + *
    +       * URI, obsolete.
    +       * 
    + */ + public Builder clearUri() { + bitField0_ = (bitField0_ & ~0x00000080); + uri_ = getDefaultInstance().getUri(); + onChanged(); + return this; + } + /** + * required string uri = 8; + * + *
    +       * URI, obsolete.
    +       * 
    + */ + public Builder setUriBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000080; + uri_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.AddressMapping) + } + + static { + defaultInstance = new AddressMapping(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.AddressMapping) + } + + public interface AddressMappingSetOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + java.util.List + getMappingsList(); + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping getMappings(int index); + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + int getMappingsCount(); + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + java.util.List + getMappingsOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingOrBuilder getMappingsOrBuilder( + int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.AddressMappingSet} + * + *
    +   * Set of mappings for a UUID.
    +   * 
    + */ + public static final class AddressMappingSet extends + com.google.protobuf.GeneratedMessage + implements AddressMappingSetOrBuilder { + // Use AddressMappingSet.newBuilder() to construct. + private AddressMappingSet(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private AddressMappingSet(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final AddressMappingSet defaultInstance; + public static AddressMappingSet getDefaultInstance() { + return defaultInstance; + } + + public AddressMappingSet getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AddressMappingSet( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + mappings_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + mappings_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + mappings_ = java.util.Collections.unmodifiableList(mappings_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_AddressMappingSet_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_AddressMappingSet_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public AddressMappingSet parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AddressMappingSet(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + public static final int MAPPINGS_FIELD_NUMBER = 1; + private java.util.List mappings_; + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public java.util.List getMappingsList() { + return mappings_; + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public java.util.List + getMappingsOrBuilderList() { + return mappings_; + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public int getMappingsCount() { + return mappings_.size(); + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping getMappings(int index) { + return mappings_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingOrBuilder getMappingsOrBuilder( + int index) { + return mappings_.get(index); + } + + private void initFields() { + mappings_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + for (int i = 0; i < getMappingsCount(); i++) { + if (!getMappings(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < mappings_.size(); i++) { + output.writeMessage(1, mappings_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < mappings_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, mappings_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.AddressMappingSet} + * + *
    +     * Set of mappings for a UUID.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSetOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_AddressMappingSet_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_AddressMappingSet_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getMappingsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (mappingsBuilder_ == null) { + mappings_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + mappingsBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_AddressMappingSet_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet(this); + int from_bitField0_ = bitField0_; + if (mappingsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001)) { + mappings_ = java.util.Collections.unmodifiableList(mappings_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.mappings_ = mappings_; + } else { + result.mappings_ = mappingsBuilder_.build(); + } + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.getDefaultInstance()) return this; + if (mappingsBuilder_ == null) { + if (!other.mappings_.isEmpty()) { + if (mappings_.isEmpty()) { + mappings_ = other.mappings_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureMappingsIsMutable(); + mappings_.addAll(other.mappings_); + } + onChanged(); + } + } else { + if (!other.mappings_.isEmpty()) { + if (mappingsBuilder_.isEmpty()) { + mappingsBuilder_.dispose(); + mappingsBuilder_ = null; + mappings_ = other.mappings_; + bitField0_ = (bitField0_ & ~0x00000001); + mappingsBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getMappingsFieldBuilder() : null; + } else { + mappingsBuilder_.addAllMessages(other.mappings_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + for (int i = 0; i < getMappingsCount(); i++) { + if (!getMappings(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + private java.util.List mappings_ = + java.util.Collections.emptyList(); + private void ensureMappingsIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + mappings_ = new java.util.ArrayList(mappings_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingOrBuilder> mappingsBuilder_; + + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public java.util.List getMappingsList() { + if (mappingsBuilder_ == null) { + return java.util.Collections.unmodifiableList(mappings_); + } else { + return mappingsBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public int getMappingsCount() { + if (mappingsBuilder_ == null) { + return mappings_.size(); + } else { + return mappingsBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping getMappings(int index) { + if (mappingsBuilder_ == null) { + return mappings_.get(index); + } else { + return mappingsBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public Builder setMappings( + int index, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping value) { + if (mappingsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMappingsIsMutable(); + mappings_.set(index, value); + onChanged(); + } else { + mappingsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public Builder setMappings( + int index, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.Builder builderForValue) { + if (mappingsBuilder_ == null) { + ensureMappingsIsMutable(); + mappings_.set(index, builderForValue.build()); + onChanged(); + } else { + mappingsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public Builder addMappings(org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping value) { + if (mappingsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMappingsIsMutable(); + mappings_.add(value); + onChanged(); + } else { + mappingsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public Builder addMappings( + int index, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping value) { + if (mappingsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMappingsIsMutable(); + mappings_.add(index, value); + onChanged(); + } else { + mappingsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public Builder addMappings( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.Builder builderForValue) { + if (mappingsBuilder_ == null) { + ensureMappingsIsMutable(); + mappings_.add(builderForValue.build()); + onChanged(); + } else { + mappingsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public Builder addMappings( + int index, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.Builder builderForValue) { + if (mappingsBuilder_ == null) { + ensureMappingsIsMutable(); + mappings_.add(index, builderForValue.build()); + onChanged(); + } else { + mappingsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public Builder addAllMappings( + java.lang.Iterable values) { + if (mappingsBuilder_ == null) { + ensureMappingsIsMutable(); + super.addAll(values, mappings_); + onChanged(); + } else { + mappingsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public Builder clearMappings() { + if (mappingsBuilder_ == null) { + mappings_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + mappingsBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public Builder removeMappings(int index) { + if (mappingsBuilder_ == null) { + ensureMappingsIsMutable(); + mappings_.remove(index); + onChanged(); + } else { + mappingsBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.Builder getMappingsBuilder( + int index) { + return getMappingsFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingOrBuilder getMappingsOrBuilder( + int index) { + if (mappingsBuilder_ == null) { + return mappings_.get(index); } else { + return mappingsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public java.util.List + getMappingsOrBuilderList() { + if (mappingsBuilder_ != null) { + return mappingsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(mappings_); + } + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.Builder addMappingsBuilder() { + return getMappingsFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.Builder addMappingsBuilder( + int index) { + return getMappingsFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.AddressMapping mappings = 1; + */ + public java.util.List + getMappingsBuilderList() { + return getMappingsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingOrBuilder> + getMappingsFieldBuilder() { + if (mappingsBuilder_ == null) { + mappingsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingOrBuilder>( + mappings_, + ((bitField0_ & 0x00000001) == 0x00000001), + getParentForChildren(), + isClean()); + mappings_ = null; + } + return mappingsBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.AddressMappingSet) + } + + static { + defaultInstance = new AddressMappingSet(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.AddressMappingSet) + } + + public interface DirServiceOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string address = 1; + /** + * required string address = 1; + */ + boolean hasAddress(); + /** + * required string address = 1; + */ + java.lang.String getAddress(); + /** + * required string address = 1; + */ + com.google.protobuf.ByteString + getAddressBytes(); + + // required fixed32 port = 2; + /** + * required fixed32 port = 2; + */ + boolean hasPort(); + /** + * required fixed32 port = 2; + */ + int getPort(); + + // required string protocol = 3; + /** + * required string protocol = 3; + */ + boolean hasProtocol(); + /** + * required string protocol = 3; + */ + java.lang.String getProtocol(); + /** + * required string protocol = 3; + */ + com.google.protobuf.ByteString + getProtocolBytes(); + + // required fixed32 interface_version = 4; + /** + * required fixed32 interface_version = 4; + */ + boolean hasInterfaceVersion(); + /** + * required fixed32 interface_version = 4; + */ + int getInterfaceVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.DirService} + * + *
    +   * DIR service address, used for auto discovery.
    +   * 
    + */ + public static final class DirService extends + com.google.protobuf.GeneratedMessage + implements DirServiceOrBuilder { + // Use DirService.newBuilder() to construct. + private DirService(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private DirService(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final DirService defaultInstance; + public static DirService getDefaultInstance() { + return defaultInstance; + } + + public DirService getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DirService( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + address_ = input.readBytes(); + break; + } + case 21: { + bitField0_ |= 0x00000002; + port_ = input.readFixed32(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + protocol_ = input.readBytes(); + break; + } + case 37: { + bitField0_ |= 0x00000008; + interfaceVersion_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_DirService_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_DirService_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public DirService parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DirService(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string address = 1; + public static final int ADDRESS_FIELD_NUMBER = 1; + private java.lang.Object address_; + /** + * required string address = 1; + */ + public boolean hasAddress() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string address = 1; + */ + public java.lang.String getAddress() { + java.lang.Object ref = address_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + address_ = s; + } + return s; + } + } + /** + * required string address = 1; + */ + public com.google.protobuf.ByteString + getAddressBytes() { + java.lang.Object ref = address_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + address_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 port = 2; + public static final int PORT_FIELD_NUMBER = 2; + private int port_; + /** + * required fixed32 port = 2; + */ + public boolean hasPort() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 port = 2; + */ + public int getPort() { + return port_; + } + + // required string protocol = 3; + public static final int PROTOCOL_FIELD_NUMBER = 3; + private java.lang.Object protocol_; + /** + * required string protocol = 3; + */ + public boolean hasProtocol() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string protocol = 3; + */ + public java.lang.String getProtocol() { + java.lang.Object ref = protocol_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + protocol_ = s; + } + return s; + } + } + /** + * required string protocol = 3; + */ + public com.google.protobuf.ByteString + getProtocolBytes() { + java.lang.Object ref = protocol_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + protocol_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 interface_version = 4; + public static final int INTERFACE_VERSION_FIELD_NUMBER = 4; + private int interfaceVersion_; + /** + * required fixed32 interface_version = 4; + */ + public boolean hasInterfaceVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 interface_version = 4; + */ + public int getInterfaceVersion() { + return interfaceVersion_; + } + + private void initFields() { + address_ = ""; + port_ = 0; + protocol_ = ""; + interfaceVersion_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasAddress()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPort()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasProtocol()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasInterfaceVersion()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getAddressBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed32(2, port_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getProtocolBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed32(4, interfaceVersion_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getAddressBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(2, port_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getProtocolBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(4, interfaceVersion_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.DirService} + * + *
    +     * DIR service address, used for auto discovery.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirServiceOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_DirService_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_DirService_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + address_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + port_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + protocol_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + interfaceVersion_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_DirService_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.address_ = address_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.port_ = port_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.protocol_ = protocol_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.interfaceVersion_ = interfaceVersion_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService.getDefaultInstance()) return this; + if (other.hasAddress()) { + bitField0_ |= 0x00000001; + address_ = other.address_; + onChanged(); + } + if (other.hasPort()) { + setPort(other.getPort()); + } + if (other.hasProtocol()) { + bitField0_ |= 0x00000004; + protocol_ = other.protocol_; + onChanged(); + } + if (other.hasInterfaceVersion()) { + setInterfaceVersion(other.getInterfaceVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasAddress()) { + + return false; + } + if (!hasPort()) { + + return false; + } + if (!hasProtocol()) { + + return false; + } + if (!hasInterfaceVersion()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string address = 1; + private java.lang.Object address_ = ""; + /** + * required string address = 1; + */ + public boolean hasAddress() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string address = 1; + */ + public java.lang.String getAddress() { + java.lang.Object ref = address_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + address_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string address = 1; + */ + public com.google.protobuf.ByteString + getAddressBytes() { + java.lang.Object ref = address_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + address_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string address = 1; + */ + public Builder setAddress( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + address_ = value; + onChanged(); + return this; + } + /** + * required string address = 1; + */ + public Builder clearAddress() { + bitField0_ = (bitField0_ & ~0x00000001); + address_ = getDefaultInstance().getAddress(); + onChanged(); + return this; + } + /** + * required string address = 1; + */ + public Builder setAddressBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + address_ = value; + onChanged(); + return this; + } + + // required fixed32 port = 2; + private int port_ ; + /** + * required fixed32 port = 2; + */ + public boolean hasPort() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 port = 2; + */ + public int getPort() { + return port_; + } + /** + * required fixed32 port = 2; + */ + public Builder setPort(int value) { + bitField0_ |= 0x00000002; + port_ = value; + onChanged(); + return this; + } + /** + * required fixed32 port = 2; + */ + public Builder clearPort() { + bitField0_ = (bitField0_ & ~0x00000002); + port_ = 0; + onChanged(); + return this; + } + + // required string protocol = 3; + private java.lang.Object protocol_ = ""; + /** + * required string protocol = 3; + */ + public boolean hasProtocol() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string protocol = 3; + */ + public java.lang.String getProtocol() { + java.lang.Object ref = protocol_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + protocol_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string protocol = 3; + */ + public com.google.protobuf.ByteString + getProtocolBytes() { + java.lang.Object ref = protocol_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + protocol_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string protocol = 3; + */ + public Builder setProtocol( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + protocol_ = value; + onChanged(); + return this; + } + /** + * required string protocol = 3; + */ + public Builder clearProtocol() { + bitField0_ = (bitField0_ & ~0x00000004); + protocol_ = getDefaultInstance().getProtocol(); + onChanged(); + return this; + } + /** + * required string protocol = 3; + */ + public Builder setProtocolBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + protocol_ = value; + onChanged(); + return this; + } + + // required fixed32 interface_version = 4; + private int interfaceVersion_ ; + /** + * required fixed32 interface_version = 4; + */ + public boolean hasInterfaceVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 interface_version = 4; + */ + public int getInterfaceVersion() { + return interfaceVersion_; + } + /** + * required fixed32 interface_version = 4; + */ + public Builder setInterfaceVersion(int value) { + bitField0_ |= 0x00000008; + interfaceVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed32 interface_version = 4; + */ + public Builder clearInterfaceVersion() { + bitField0_ = (bitField0_ & ~0x00000008); + interfaceVersion_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.DirService) + } + + static { + defaultInstance = new DirService(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.DirService) + } + + public interface ServiceDataMapOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + java.util.List + getDataList(); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair getData(int index); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + int getDataCount(); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + java.util.List + getDataOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder getDataOrBuilder( + int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ServiceDataMap} + * + *
    +   * Key/Value pairs for a service.
    +   * 
    + */ + public static final class ServiceDataMap extends + com.google.protobuf.GeneratedMessage + implements ServiceDataMapOrBuilder { + // Use ServiceDataMap.newBuilder() to construct. + private ServiceDataMap(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ServiceDataMap(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final ServiceDataMap defaultInstance; + public static ServiceDataMap getDefaultInstance() { + return defaultInstance; + } + + public ServiceDataMap getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ServiceDataMap( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + data_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + data_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + data_ = java.util.Collections.unmodifiableList(data_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_ServiceDataMap_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_ServiceDataMap_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public ServiceDataMap parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ServiceDataMap(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + public static final int DATA_FIELD_NUMBER = 1; + private java.util.List data_; + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public java.util.List getDataList() { + return data_; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public java.util.List + getDataOrBuilderList() { + return data_; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public int getDataCount() { + return data_.size(); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair getData(int index) { + return data_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder getDataOrBuilder( + int index) { + return data_.get(index); + } + + private void initFields() { + data_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + for (int i = 0; i < getDataCount(); i++) { + if (!getData(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < data_.size(); i++) { + output.writeMessage(1, data_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < data_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, data_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ServiceDataMap} + * + *
    +     * Key/Value pairs for a service.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMapOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_ServiceDataMap_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_ServiceDataMap_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getDataFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (dataBuilder_ == null) { + data_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + dataBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_ServiceDataMap_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap(this); + int from_bitField0_ = bitField0_; + if (dataBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001)) { + data_ = java.util.Collections.unmodifiableList(data_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.data_ = data_; + } else { + result.data_ = dataBuilder_.build(); + } + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.getDefaultInstance()) return this; + if (dataBuilder_ == null) { + if (!other.data_.isEmpty()) { + if (data_.isEmpty()) { + data_ = other.data_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureDataIsMutable(); + data_.addAll(other.data_); + } + onChanged(); + } + } else { + if (!other.data_.isEmpty()) { + if (dataBuilder_.isEmpty()) { + dataBuilder_.dispose(); + dataBuilder_ = null; + data_ = other.data_; + bitField0_ = (bitField0_ & ~0x00000001); + dataBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getDataFieldBuilder() : null; + } else { + dataBuilder_.addAllMessages(other.data_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + for (int i = 0; i < getDataCount(); i++) { + if (!getData(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + private java.util.List data_ = + java.util.Collections.emptyList(); + private void ensureDataIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + data_ = new java.util.ArrayList(data_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder> dataBuilder_; + + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public java.util.List getDataList() { + if (dataBuilder_ == null) { + return java.util.Collections.unmodifiableList(data_); + } else { + return dataBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public int getDataCount() { + if (dataBuilder_ == null) { + return data_.size(); + } else { + return dataBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair getData(int index) { + if (dataBuilder_ == null) { + return data_.get(index); + } else { + return dataBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public Builder setData( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair value) { + if (dataBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureDataIsMutable(); + data_.set(index, value); + onChanged(); + } else { + dataBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public Builder setData( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder builderForValue) { + if (dataBuilder_ == null) { + ensureDataIsMutable(); + data_.set(index, builderForValue.build()); + onChanged(); + } else { + dataBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public Builder addData(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair value) { + if (dataBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureDataIsMutable(); + data_.add(value); + onChanged(); + } else { + dataBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public Builder addData( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair value) { + if (dataBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureDataIsMutable(); + data_.add(index, value); + onChanged(); + } else { + dataBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public Builder addData( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder builderForValue) { + if (dataBuilder_ == null) { + ensureDataIsMutable(); + data_.add(builderForValue.build()); + onChanged(); + } else { + dataBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public Builder addData( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder builderForValue) { + if (dataBuilder_ == null) { + ensureDataIsMutable(); + data_.add(index, builderForValue.build()); + onChanged(); + } else { + dataBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public Builder addAllData( + java.lang.Iterable values) { + if (dataBuilder_ == null) { + ensureDataIsMutable(); + super.addAll(values, data_); + onChanged(); + } else { + dataBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public Builder clearData() { + if (dataBuilder_ == null) { + data_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + dataBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public Builder removeData(int index) { + if (dataBuilder_ == null) { + ensureDataIsMutable(); + data_.remove(index); + onChanged(); + } else { + dataBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder getDataBuilder( + int index) { + return getDataFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder getDataOrBuilder( + int index) { + if (dataBuilder_ == null) { + return data_.get(index); } else { + return dataBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public java.util.List + getDataOrBuilderList() { + if (dataBuilder_ != null) { + return dataBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(data_); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder addDataBuilder() { + return getDataFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder addDataBuilder( + int index) { + return getDataFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair data = 1; + */ + public java.util.List + getDataBuilderList() { + return getDataFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder> + getDataFieldBuilder() { + if (dataBuilder_ == null) { + dataBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder>( + data_, + ((bitField0_ & 0x00000001) == 0x00000001), + getParentForChildren(), + isClean()); + data_ = null; + } + return dataBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.ServiceDataMap) + } + + static { + defaultInstance = new ServiceDataMap(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ServiceDataMap) + } + + public interface ServiceOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.ServiceType type = 1; + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + */ + boolean hasType(); + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType getType(); + + // required string uuid = 2; + /** + * required string uuid = 2; + * + *
    +     * Service uuid, e.g. volume UUID.
    +     * 
    + */ + boolean hasUuid(); + /** + * required string uuid = 2; + * + *
    +     * Service uuid, e.g. volume UUID.
    +     * 
    + */ + java.lang.String getUuid(); + /** + * required string uuid = 2; + * + *
    +     * Service uuid, e.g. volume UUID.
    +     * 
    + */ + com.google.protobuf.ByteString + getUuidBytes(); + + // required fixed64 version = 3; + /** + * required fixed64 version = 3; + * + *
    +     * Version of this record, assigned by the DIR on write.
    +     * 
    + */ + boolean hasVersion(); + /** + * required fixed64 version = 3; + * + *
    +     * Version of this record, assigned by the DIR on write.
    +     * 
    + */ + long getVersion(); + + // required string name = 4; + /** + * required string name = 4; + * + *
    +     * Service name, e.g. volume name.
    +     * 
    + */ + boolean hasName(); + /** + * required string name = 4; + * + *
    +     * Service name, e.g. volume name.
    +     * 
    + */ + java.lang.String getName(); + /** + * required string name = 4; + * + *
    +     * Service name, e.g. volume name.
    +     * 
    + */ + com.google.protobuf.ByteString + getNameBytes(); + + // required fixed64 last_updated_s = 5; + /** + * required fixed64 last_updated_s = 5; + * + *
    +     * Timestamp of last update in global XtreemFS time, assigned
    +     * by the DIR on write.
    +     * 
    + */ + boolean hasLastUpdatedS(); + /** + * required fixed64 last_updated_s = 5; + * + *
    +     * Timestamp of last update in global XtreemFS time, assigned
    +     * by the DIR on write.
    +     * 
    + */ + long getLastUpdatedS(); + + // required .xtreemfs.pbrpc.ServiceDataMap data = 6; + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +     * Service details including service state.
    +     * 
    + */ + boolean hasData(); + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +     * Service details including service state.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap getData(); + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +     * Service details including service state.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMapOrBuilder getDataOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Service} + * + *
    +   * Service data in DIR.
    +   * 
    + */ + public static final class Service extends + com.google.protobuf.GeneratedMessage + implements ServiceOrBuilder { + // Use Service.newBuilder() to construct. + private Service(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Service(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Service defaultInstance; + public static Service getDefaultInstance() { + return defaultInstance; + } + + public Service getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Service( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + int rawValue = input.readEnum(); + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType value = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(1, rawValue); + } else { + bitField0_ |= 0x00000001; + type_ = value; + } + break; + } + case 18: { + bitField0_ |= 0x00000002; + uuid_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + version_ = input.readFixed64(); + break; + } + case 34: { + bitField0_ |= 0x00000008; + name_ = input.readBytes(); + break; + } + case 41: { + bitField0_ |= 0x00000010; + lastUpdatedS_ = input.readFixed64(); + break; + } + case 50: { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.Builder subBuilder = null; + if (((bitField0_ & 0x00000020) == 0x00000020)) { + subBuilder = data_.toBuilder(); + } + data_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(data_); + data_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000020; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_Service_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_Service_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Service parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Service(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.ServiceType type = 1; + public static final int TYPE_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType type_; + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + */ + public boolean hasType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType getType() { + return type_; + } + + // required string uuid = 2; + public static final int UUID_FIELD_NUMBER = 2; + private java.lang.Object uuid_; + /** + * required string uuid = 2; + * + *
    +     * Service uuid, e.g. volume UUID.
    +     * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string uuid = 2; + * + *
    +     * Service uuid, e.g. volume UUID.
    +     * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + uuid_ = s; + } + return s; + } + } + /** + * required string uuid = 2; + * + *
    +     * Service uuid, e.g. volume UUID.
    +     * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 version = 3; + public static final int VERSION_FIELD_NUMBER = 3; + private long version_; + /** + * required fixed64 version = 3; + * + *
    +     * Version of this record, assigned by the DIR on write.
    +     * 
    + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 version = 3; + * + *
    +     * Version of this record, assigned by the DIR on write.
    +     * 
    + */ + public long getVersion() { + return version_; + } + + // required string name = 4; + public static final int NAME_FIELD_NUMBER = 4; + private java.lang.Object name_; + /** + * required string name = 4; + * + *
    +     * Service name, e.g. volume name.
    +     * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required string name = 4; + * + *
    +     * Service name, e.g. volume name.
    +     * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * required string name = 4; + * + *
    +     * Service name, e.g. volume name.
    +     * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 last_updated_s = 5; + public static final int LAST_UPDATED_S_FIELD_NUMBER = 5; + private long lastUpdatedS_; + /** + * required fixed64 last_updated_s = 5; + * + *
    +     * Timestamp of last update in global XtreemFS time, assigned
    +     * by the DIR on write.
    +     * 
    + */ + public boolean hasLastUpdatedS() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed64 last_updated_s = 5; + * + *
    +     * Timestamp of last update in global XtreemFS time, assigned
    +     * by the DIR on write.
    +     * 
    + */ + public long getLastUpdatedS() { + return lastUpdatedS_; + } + + // required .xtreemfs.pbrpc.ServiceDataMap data = 6; + public static final int DATA_FIELD_NUMBER = 6; + private org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap data_; + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +     * Service details including service state.
    +     * 
    + */ + public boolean hasData() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +     * Service details including service state.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap getData() { + return data_; + } + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +     * Service details including service state.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMapOrBuilder getDataOrBuilder() { + return data_; + } + + private void initFields() { + type_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType.SERVICE_TYPE_MIXED; + uuid_ = ""; + version_ = 0L; + name_ = ""; + lastUpdatedS_ = 0L; + data_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasType()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasUuid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLastUpdatedS()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasData()) { + memoizedIsInitialized = 0; + return false; + } + if (!getData().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeEnum(1, type_.getNumber()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getUuidBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, version_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBytes(4, getNameBytes()); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeFixed64(5, lastUpdatedS_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeMessage(6, data_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(1, type_.getNumber()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getUuidBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, version_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, getNameBytes()); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(5, lastUpdatedS_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(6, data_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Service} + * + *
    +     * Service data in DIR.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_Service_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_Service_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getDataFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + type_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType.SERVICE_TYPE_MIXED; + bitField0_ = (bitField0_ & ~0x00000001); + uuid_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + version_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000008); + lastUpdatedS_ = 0L; + bitField0_ = (bitField0_ & ~0x00000010); + if (dataBuilder_ == null) { + data_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.getDefaultInstance(); + } else { + dataBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000020); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_Service_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.type_ = type_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.uuid_ = uuid_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.version_ = version_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.lastUpdatedS_ = lastUpdatedS_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + if (dataBuilder_ == null) { + result.data_ = data_; + } else { + result.data_ = dataBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.getDefaultInstance()) return this; + if (other.hasType()) { + setType(other.getType()); + } + if (other.hasUuid()) { + bitField0_ |= 0x00000002; + uuid_ = other.uuid_; + onChanged(); + } + if (other.hasVersion()) { + setVersion(other.getVersion()); + } + if (other.hasName()) { + bitField0_ |= 0x00000008; + name_ = other.name_; + onChanged(); + } + if (other.hasLastUpdatedS()) { + setLastUpdatedS(other.getLastUpdatedS()); + } + if (other.hasData()) { + mergeData(other.getData()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasType()) { + + return false; + } + if (!hasUuid()) { + + return false; + } + if (!hasVersion()) { + + return false; + } + if (!hasName()) { + + return false; + } + if (!hasLastUpdatedS()) { + + return false; + } + if (!hasData()) { + + return false; + } + if (!getData().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.ServiceType type = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType type_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType.SERVICE_TYPE_MIXED; + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + */ + public boolean hasType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType getType() { + return type_; + } + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + */ + public Builder setType(org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + type_ = value; + onChanged(); + return this; + } + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + */ + public Builder clearType() { + bitField0_ = (bitField0_ & ~0x00000001); + type_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType.SERVICE_TYPE_MIXED; + onChanged(); + return this; + } + + // required string uuid = 2; + private java.lang.Object uuid_ = ""; + /** + * required string uuid = 2; + * + *
    +       * Service uuid, e.g. volume UUID.
    +       * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string uuid = 2; + * + *
    +       * Service uuid, e.g. volume UUID.
    +       * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + uuid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string uuid = 2; + * + *
    +       * Service uuid, e.g. volume UUID.
    +       * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string uuid = 2; + * + *
    +       * Service uuid, e.g. volume UUID.
    +       * 
    + */ + public Builder setUuid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + uuid_ = value; + onChanged(); + return this; + } + /** + * required string uuid = 2; + * + *
    +       * Service uuid, e.g. volume UUID.
    +       * 
    + */ + public Builder clearUuid() { + bitField0_ = (bitField0_ & ~0x00000002); + uuid_ = getDefaultInstance().getUuid(); + onChanged(); + return this; + } + /** + * required string uuid = 2; + * + *
    +       * Service uuid, e.g. volume UUID.
    +       * 
    + */ + public Builder setUuidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + uuid_ = value; + onChanged(); + return this; + } + + // required fixed64 version = 3; + private long version_ ; + /** + * required fixed64 version = 3; + * + *
    +       * Version of this record, assigned by the DIR on write.
    +       * 
    + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 version = 3; + * + *
    +       * Version of this record, assigned by the DIR on write.
    +       * 
    + */ + public long getVersion() { + return version_; + } + /** + * required fixed64 version = 3; + * + *
    +       * Version of this record, assigned by the DIR on write.
    +       * 
    + */ + public Builder setVersion(long value) { + bitField0_ |= 0x00000004; + version_ = value; + onChanged(); + return this; + } + /** + * required fixed64 version = 3; + * + *
    +       * Version of this record, assigned by the DIR on write.
    +       * 
    + */ + public Builder clearVersion() { + bitField0_ = (bitField0_ & ~0x00000004); + version_ = 0L; + onChanged(); + return this; + } + + // required string name = 4; + private java.lang.Object name_ = ""; + /** + * required string name = 4; + * + *
    +       * Service name, e.g. volume name.
    +       * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required string name = 4; + * + *
    +       * Service name, e.g. volume name.
    +       * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string name = 4; + * + *
    +       * Service name, e.g. volume name.
    +       * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string name = 4; + * + *
    +       * Service name, e.g. volume name.
    +       * 
    + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + name_ = value; + onChanged(); + return this; + } + /** + * required string name = 4; + * + *
    +       * Service name, e.g. volume name.
    +       * 
    + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000008); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * required string name = 4; + * + *
    +       * Service name, e.g. volume name.
    +       * 
    + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + name_ = value; + onChanged(); + return this; + } + + // required fixed64 last_updated_s = 5; + private long lastUpdatedS_ ; + /** + * required fixed64 last_updated_s = 5; + * + *
    +       * Timestamp of last update in global XtreemFS time, assigned
    +       * by the DIR on write.
    +       * 
    + */ + public boolean hasLastUpdatedS() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed64 last_updated_s = 5; + * + *
    +       * Timestamp of last update in global XtreemFS time, assigned
    +       * by the DIR on write.
    +       * 
    + */ + public long getLastUpdatedS() { + return lastUpdatedS_; + } + /** + * required fixed64 last_updated_s = 5; + * + *
    +       * Timestamp of last update in global XtreemFS time, assigned
    +       * by the DIR on write.
    +       * 
    + */ + public Builder setLastUpdatedS(long value) { + bitField0_ |= 0x00000010; + lastUpdatedS_ = value; + onChanged(); + return this; + } + /** + * required fixed64 last_updated_s = 5; + * + *
    +       * Timestamp of last update in global XtreemFS time, assigned
    +       * by the DIR on write.
    +       * 
    + */ + public Builder clearLastUpdatedS() { + bitField0_ = (bitField0_ & ~0x00000010); + lastUpdatedS_ = 0L; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.ServiceDataMap data = 6; + private org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap data_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMapOrBuilder> dataBuilder_; + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +       * Service details including service state.
    +       * 
    + */ + public boolean hasData() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +       * Service details including service state.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap getData() { + if (dataBuilder_ == null) { + return data_; + } else { + return dataBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +       * Service details including service state.
    +       * 
    + */ + public Builder setData(org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap value) { + if (dataBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + data_ = value; + onChanged(); + } else { + dataBuilder_.setMessage(value); + } + bitField0_ |= 0x00000020; + return this; + } + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +       * Service details including service state.
    +       * 
    + */ + public Builder setData( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.Builder builderForValue) { + if (dataBuilder_ == null) { + data_ = builderForValue.build(); + onChanged(); + } else { + dataBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000020; + return this; + } + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +       * Service details including service state.
    +       * 
    + */ + public Builder mergeData(org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap value) { + if (dataBuilder_ == null) { + if (((bitField0_ & 0x00000020) == 0x00000020) && + data_ != org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.getDefaultInstance()) { + data_ = + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.newBuilder(data_).mergeFrom(value).buildPartial(); + } else { + data_ = value; + } + onChanged(); + } else { + dataBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000020; + return this; + } + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +       * Service details including service state.
    +       * 
    + */ + public Builder clearData() { + if (dataBuilder_ == null) { + data_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.getDefaultInstance(); + onChanged(); + } else { + dataBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000020); + return this; + } + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +       * Service details including service state.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.Builder getDataBuilder() { + bitField0_ |= 0x00000020; + onChanged(); + return getDataFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +       * Service details including service state.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMapOrBuilder getDataOrBuilder() { + if (dataBuilder_ != null) { + return dataBuilder_.getMessageOrBuilder(); + } else { + return data_; + } + } + /** + * required .xtreemfs.pbrpc.ServiceDataMap data = 6; + * + *
    +       * Service details including service state.
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMapOrBuilder> + getDataFieldBuilder() { + if (dataBuilder_ == null) { + dataBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMapOrBuilder>( + data_, + getParentForChildren(), + isClean()); + data_ = null; + } + return dataBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.Service) + } + + static { + defaultInstance = new Service(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Service) + } + + public interface ServiceSetOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated .xtreemfs.pbrpc.Service services = 1; + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + java.util.List + getServicesList(); + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service getServices(int index); + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + int getServicesCount(); + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + java.util.List + getServicesOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder getServicesOrBuilder( + int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ServiceSet} + */ + public static final class ServiceSet extends + com.google.protobuf.GeneratedMessage + implements ServiceSetOrBuilder { + // Use ServiceSet.newBuilder() to construct. + private ServiceSet(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ServiceSet(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final ServiceSet defaultInstance; + public static ServiceSet getDefaultInstance() { + return defaultInstance; + } + + public ServiceSet getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ServiceSet( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + services_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + services_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + services_ = java.util.Collections.unmodifiableList(services_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_ServiceSet_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_ServiceSet_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public ServiceSet parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ServiceSet(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated .xtreemfs.pbrpc.Service services = 1; + public static final int SERVICES_FIELD_NUMBER = 1; + private java.util.List services_; + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public java.util.List getServicesList() { + return services_; + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public java.util.List + getServicesOrBuilderList() { + return services_; + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public int getServicesCount() { + return services_.size(); + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service getServices(int index) { + return services_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder getServicesOrBuilder( + int index) { + return services_.get(index); + } + + private void initFields() { + services_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + for (int i = 0; i < getServicesCount(); i++) { + if (!getServices(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < services_.size(); i++) { + output.writeMessage(1, services_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < services_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, services_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ServiceSet} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSetOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_ServiceSet_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_ServiceSet_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getServicesFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (servicesBuilder_ == null) { + services_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + servicesBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_ServiceSet_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet(this); + int from_bitField0_ = bitField0_; + if (servicesBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001)) { + services_ = java.util.Collections.unmodifiableList(services_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.services_ = services_; + } else { + result.services_ = servicesBuilder_.build(); + } + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet.getDefaultInstance()) return this; + if (servicesBuilder_ == null) { + if (!other.services_.isEmpty()) { + if (services_.isEmpty()) { + services_ = other.services_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureServicesIsMutable(); + services_.addAll(other.services_); + } + onChanged(); + } + } else { + if (!other.services_.isEmpty()) { + if (servicesBuilder_.isEmpty()) { + servicesBuilder_.dispose(); + servicesBuilder_ = null; + services_ = other.services_; + bitField0_ = (bitField0_ & ~0x00000001); + servicesBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getServicesFieldBuilder() : null; + } else { + servicesBuilder_.addAllMessages(other.services_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + for (int i = 0; i < getServicesCount(); i++) { + if (!getServices(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated .xtreemfs.pbrpc.Service services = 1; + private java.util.List services_ = + java.util.Collections.emptyList(); + private void ensureServicesIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + services_ = new java.util.ArrayList(services_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder> servicesBuilder_; + + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public java.util.List getServicesList() { + if (servicesBuilder_ == null) { + return java.util.Collections.unmodifiableList(services_); + } else { + return servicesBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public int getServicesCount() { + if (servicesBuilder_ == null) { + return services_.size(); + } else { + return servicesBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service getServices(int index) { + if (servicesBuilder_ == null) { + return services_.get(index); + } else { + return servicesBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public Builder setServices( + int index, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service value) { + if (servicesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureServicesIsMutable(); + services_.set(index, value); + onChanged(); + } else { + servicesBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public Builder setServices( + int index, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder builderForValue) { + if (servicesBuilder_ == null) { + ensureServicesIsMutable(); + services_.set(index, builderForValue.build()); + onChanged(); + } else { + servicesBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public Builder addServices(org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service value) { + if (servicesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureServicesIsMutable(); + services_.add(value); + onChanged(); + } else { + servicesBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public Builder addServices( + int index, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service value) { + if (servicesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureServicesIsMutable(); + services_.add(index, value); + onChanged(); + } else { + servicesBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public Builder addServices( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder builderForValue) { + if (servicesBuilder_ == null) { + ensureServicesIsMutable(); + services_.add(builderForValue.build()); + onChanged(); + } else { + servicesBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public Builder addServices( + int index, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder builderForValue) { + if (servicesBuilder_ == null) { + ensureServicesIsMutable(); + services_.add(index, builderForValue.build()); + onChanged(); + } else { + servicesBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public Builder addAllServices( + java.lang.Iterable values) { + if (servicesBuilder_ == null) { + ensureServicesIsMutable(); + super.addAll(values, services_); + onChanged(); + } else { + servicesBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public Builder clearServices() { + if (servicesBuilder_ == null) { + services_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + servicesBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public Builder removeServices(int index) { + if (servicesBuilder_ == null) { + ensureServicesIsMutable(); + services_.remove(index); + onChanged(); + } else { + servicesBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder getServicesBuilder( + int index) { + return getServicesFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder getServicesOrBuilder( + int index) { + if (servicesBuilder_ == null) { + return services_.get(index); } else { + return servicesBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public java.util.List + getServicesOrBuilderList() { + if (servicesBuilder_ != null) { + return servicesBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(services_); + } + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder addServicesBuilder() { + return getServicesFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder addServicesBuilder( + int index) { + return getServicesFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.Service services = 1; + */ + public java.util.List + getServicesBuilderList() { + return getServicesFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder> + getServicesFieldBuilder() { + if (servicesBuilder_ == null) { + servicesBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder>( + services_, + ((bitField0_ & 0x00000001) == 0x00000001), + getParentForChildren(), + isClean()); + services_ = null; + } + return servicesBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.ServiceSet) + } + + static { + defaultInstance = new ServiceSet(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ServiceSet) + } + + public interface ConfigurationOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string uuid = 1; + /** + * required string uuid = 1; + * + *
    +     * Service UUID.
    +     * 
    + */ + boolean hasUuid(); + /** + * required string uuid = 1; + * + *
    +     * Service UUID.
    +     * 
    + */ + java.lang.String getUuid(); + /** + * required string uuid = 1; + * + *
    +     * Service UUID.
    +     * 
    + */ + com.google.protobuf.ByteString + getUuidBytes(); + + // repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +     * Configuration options.
    +     * 
    + */ + java.util.List + getParameterList(); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +     * Configuration options.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair getParameter(int index); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +     * Configuration options.
    +     * 
    + */ + int getParameterCount(); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +     * Configuration options.
    +     * 
    + */ + java.util.List + getParameterOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +     * Configuration options.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder getParameterOrBuilder( + int index); + + // required fixed64 version = 3; + /** + * required fixed64 version = 3; + * + *
    +     * Version of this record, assigned by the DIR on write.
    +     * 
    + */ + boolean hasVersion(); + /** + * required fixed64 version = 3; + * + *
    +     * Version of this record, assigned by the DIR on write.
    +     * 
    + */ + long getVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Configuration} + * + *
    +   * Service configuration stored in the DIR.
    +   * 
    + */ + public static final class Configuration extends + com.google.protobuf.GeneratedMessage + implements ConfigurationOrBuilder { + // Use Configuration.newBuilder() to construct. + private Configuration(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Configuration(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Configuration defaultInstance; + public static Configuration getDefaultInstance() { + return defaultInstance; + } + + public Configuration getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Configuration( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + uuid_ = input.readBytes(); + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + parameter_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + parameter_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.PARSER, extensionRegistry)); + break; + } + case 25: { + bitField0_ |= 0x00000002; + version_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + parameter_ = java.util.Collections.unmodifiableList(parameter_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_Configuration_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_Configuration_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Configuration parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Configuration(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string uuid = 1; + public static final int UUID_FIELD_NUMBER = 1; + private java.lang.Object uuid_; + /** + * required string uuid = 1; + * + *
    +     * Service UUID.
    +     * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string uuid = 1; + * + *
    +     * Service UUID.
    +     * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + uuid_ = s; + } + return s; + } + } + /** + * required string uuid = 1; + * + *
    +     * Service UUID.
    +     * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + public static final int PARAMETER_FIELD_NUMBER = 2; + private java.util.List parameter_; + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +     * Configuration options.
    +     * 
    + */ + public java.util.List getParameterList() { + return parameter_; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +     * Configuration options.
    +     * 
    + */ + public java.util.List + getParameterOrBuilderList() { + return parameter_; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +     * Configuration options.
    +     * 
    + */ + public int getParameterCount() { + return parameter_.size(); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +     * Configuration options.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair getParameter(int index) { + return parameter_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +     * Configuration options.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder getParameterOrBuilder( + int index) { + return parameter_.get(index); + } + + // required fixed64 version = 3; + public static final int VERSION_FIELD_NUMBER = 3; + private long version_; + /** + * required fixed64 version = 3; + * + *
    +     * Version of this record, assigned by the DIR on write.
    +     * 
    + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 version = 3; + * + *
    +     * Version of this record, assigned by the DIR on write.
    +     * 
    + */ + public long getVersion() { + return version_; + } + + private void initFields() { + uuid_ = ""; + parameter_ = java.util.Collections.emptyList(); + version_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasUuid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasVersion()) { + memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getParameterCount(); i++) { + if (!getParameter(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getUuidBytes()); + } + for (int i = 0; i < parameter_.size(); i++) { + output.writeMessage(2, parameter_.get(i)); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(3, version_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getUuidBytes()); + } + for (int i = 0; i < parameter_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, parameter_.get(i)); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, version_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Configuration} + * + *
    +     * Service configuration stored in the DIR.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.ConfigurationOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_Configuration_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_Configuration_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getParameterFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + uuid_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + if (parameterBuilder_ == null) { + parameter_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + } else { + parameterBuilder_.clear(); + } + version_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_Configuration_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.uuid_ = uuid_; + if (parameterBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002)) { + parameter_ = java.util.Collections.unmodifiableList(parameter_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.parameter_ = parameter_; + } else { + result.parameter_ = parameterBuilder_.build(); + } + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000002; + } + result.version_ = version_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration.getDefaultInstance()) return this; + if (other.hasUuid()) { + bitField0_ |= 0x00000001; + uuid_ = other.uuid_; + onChanged(); + } + if (parameterBuilder_ == null) { + if (!other.parameter_.isEmpty()) { + if (parameter_.isEmpty()) { + parameter_ = other.parameter_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureParameterIsMutable(); + parameter_.addAll(other.parameter_); + } + onChanged(); + } + } else { + if (!other.parameter_.isEmpty()) { + if (parameterBuilder_.isEmpty()) { + parameterBuilder_.dispose(); + parameterBuilder_ = null; + parameter_ = other.parameter_; + bitField0_ = (bitField0_ & ~0x00000002); + parameterBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getParameterFieldBuilder() : null; + } else { + parameterBuilder_.addAllMessages(other.parameter_); + } + } + } + if (other.hasVersion()) { + setVersion(other.getVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasUuid()) { + + return false; + } + if (!hasVersion()) { + + return false; + } + for (int i = 0; i < getParameterCount(); i++) { + if (!getParameter(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string uuid = 1; + private java.lang.Object uuid_ = ""; + /** + * required string uuid = 1; + * + *
    +       * Service UUID.
    +       * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string uuid = 1; + * + *
    +       * Service UUID.
    +       * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + uuid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string uuid = 1; + * + *
    +       * Service UUID.
    +       * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string uuid = 1; + * + *
    +       * Service UUID.
    +       * 
    + */ + public Builder setUuid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + uuid_ = value; + onChanged(); + return this; + } + /** + * required string uuid = 1; + * + *
    +       * Service UUID.
    +       * 
    + */ + public Builder clearUuid() { + bitField0_ = (bitField0_ & ~0x00000001); + uuid_ = getDefaultInstance().getUuid(); + onChanged(); + return this; + } + /** + * required string uuid = 1; + * + *
    +       * Service UUID.
    +       * 
    + */ + public Builder setUuidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + uuid_ = value; + onChanged(); + return this; + } + + // repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + private java.util.List parameter_ = + java.util.Collections.emptyList(); + private void ensureParameterIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + parameter_ = new java.util.ArrayList(parameter_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder> parameterBuilder_; + + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public java.util.List getParameterList() { + if (parameterBuilder_ == null) { + return java.util.Collections.unmodifiableList(parameter_); + } else { + return parameterBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public int getParameterCount() { + if (parameterBuilder_ == null) { + return parameter_.size(); + } else { + return parameterBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair getParameter(int index) { + if (parameterBuilder_ == null) { + return parameter_.get(index); + } else { + return parameterBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public Builder setParameter( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair value) { + if (parameterBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureParameterIsMutable(); + parameter_.set(index, value); + onChanged(); + } else { + parameterBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public Builder setParameter( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder builderForValue) { + if (parameterBuilder_ == null) { + ensureParameterIsMutable(); + parameter_.set(index, builderForValue.build()); + onChanged(); + } else { + parameterBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public Builder addParameter(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair value) { + if (parameterBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureParameterIsMutable(); + parameter_.add(value); + onChanged(); + } else { + parameterBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public Builder addParameter( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair value) { + if (parameterBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureParameterIsMutable(); + parameter_.add(index, value); + onChanged(); + } else { + parameterBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public Builder addParameter( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder builderForValue) { + if (parameterBuilder_ == null) { + ensureParameterIsMutable(); + parameter_.add(builderForValue.build()); + onChanged(); + } else { + parameterBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public Builder addParameter( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder builderForValue) { + if (parameterBuilder_ == null) { + ensureParameterIsMutable(); + parameter_.add(index, builderForValue.build()); + onChanged(); + } else { + parameterBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public Builder addAllParameter( + java.lang.Iterable values) { + if (parameterBuilder_ == null) { + ensureParameterIsMutable(); + super.addAll(values, parameter_); + onChanged(); + } else { + parameterBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public Builder clearParameter() { + if (parameterBuilder_ == null) { + parameter_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + parameterBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public Builder removeParameter(int index) { + if (parameterBuilder_ == null) { + ensureParameterIsMutable(); + parameter_.remove(index); + onChanged(); + } else { + parameterBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder getParameterBuilder( + int index) { + return getParameterFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder getParameterOrBuilder( + int index) { + if (parameterBuilder_ == null) { + return parameter_.get(index); } else { + return parameterBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public java.util.List + getParameterOrBuilderList() { + if (parameterBuilder_ != null) { + return parameterBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(parameter_); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder addParameterBuilder() { + return getParameterFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder addParameterBuilder( + int index) { + return getParameterFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair parameter = 2; + * + *
    +       * Configuration options.
    +       * 
    + */ + public java.util.List + getParameterBuilderList() { + return getParameterFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder> + getParameterFieldBuilder() { + if (parameterBuilder_ == null) { + parameterBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder>( + parameter_, + ((bitField0_ & 0x00000002) == 0x00000002), + getParentForChildren(), + isClean()); + parameter_ = null; + } + return parameterBuilder_; + } + + // required fixed64 version = 3; + private long version_ ; + /** + * required fixed64 version = 3; + * + *
    +       * Version of this record, assigned by the DIR on write.
    +       * 
    + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 version = 3; + * + *
    +       * Version of this record, assigned by the DIR on write.
    +       * 
    + */ + public long getVersion() { + return version_; + } + /** + * required fixed64 version = 3; + * + *
    +       * Version of this record, assigned by the DIR on write.
    +       * 
    + */ + public Builder setVersion(long value) { + bitField0_ |= 0x00000004; + version_ = value; + onChanged(); + return this; + } + /** + * required fixed64 version = 3; + * + *
    +       * Version of this record, assigned by the DIR on write.
    +       * 
    + */ + public Builder clearVersion() { + bitField0_ = (bitField0_ & ~0x00000004); + version_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.Configuration) + } + + static { + defaultInstance = new Configuration(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Configuration) + } + + public interface addressMappingGetRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string uuid = 1; + /** + * required string uuid = 1; + * + *
    +     * UUID of the service for which mapping should be returned.
    +     * 
    + */ + boolean hasUuid(); + /** + * required string uuid = 1; + * + *
    +     * UUID of the service for which mapping should be returned.
    +     * 
    + */ + java.lang.String getUuid(); + /** + * required string uuid = 1; + * + *
    +     * UUID of the service for which mapping should be returned.
    +     * 
    + */ + com.google.protobuf.ByteString + getUuidBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.addressMappingGetRequest} + */ + public static final class addressMappingGetRequest extends + com.google.protobuf.GeneratedMessage + implements addressMappingGetRequestOrBuilder { + // Use addressMappingGetRequest.newBuilder() to construct. + private addressMappingGetRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private addressMappingGetRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final addressMappingGetRequest defaultInstance; + public static addressMappingGetRequest getDefaultInstance() { + return defaultInstance; + } + + public addressMappingGetRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private addressMappingGetRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + uuid_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingGetRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingGetRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public addressMappingGetRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new addressMappingGetRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string uuid = 1; + public static final int UUID_FIELD_NUMBER = 1; + private java.lang.Object uuid_; + /** + * required string uuid = 1; + * + *
    +     * UUID of the service for which mapping should be returned.
    +     * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string uuid = 1; + * + *
    +     * UUID of the service for which mapping should be returned.
    +     * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + uuid_ = s; + } + return s; + } + } + /** + * required string uuid = 1; + * + *
    +     * UUID of the service for which mapping should be returned.
    +     * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + uuid_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasUuid()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getUuidBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getUuidBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.addressMappingGetRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingGetRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingGetRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + uuid_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingGetRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.uuid_ = uuid_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest.getDefaultInstance()) return this; + if (other.hasUuid()) { + bitField0_ |= 0x00000001; + uuid_ = other.uuid_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasUuid()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string uuid = 1; + private java.lang.Object uuid_ = ""; + /** + * required string uuid = 1; + * + *
    +       * UUID of the service for which mapping should be returned.
    +       * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the service for which mapping should be returned.
    +       * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + uuid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the service for which mapping should be returned.
    +       * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the service for which mapping should be returned.
    +       * 
    + */ + public Builder setUuid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + uuid_ = value; + onChanged(); + return this; + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the service for which mapping should be returned.
    +       * 
    + */ + public Builder clearUuid() { + bitField0_ = (bitField0_ & ~0x00000001); + uuid_ = getDefaultInstance().getUuid(); + onChanged(); + return this; + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the service for which mapping should be returned.
    +       * 
    + */ + public Builder setUuidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + uuid_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.addressMappingGetRequest) + } + + static { + defaultInstance = new addressMappingGetRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.addressMappingGetRequest) + } + + public interface addressMappingGetResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +     * List of matching mappings, might be empty.
    +     * 
    + */ + boolean hasResult(); + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +     * List of matching mappings, might be empty.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet getResult(); + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +     * List of matching mappings, might be empty.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSetOrBuilder getResultOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.addressMappingGetResponse} + */ + public static final class addressMappingGetResponse extends + com.google.protobuf.GeneratedMessage + implements addressMappingGetResponseOrBuilder { + // Use addressMappingGetResponse.newBuilder() to construct. + private addressMappingGetResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private addressMappingGetResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final addressMappingGetResponse defaultInstance; + public static addressMappingGetResponse getDefaultInstance() { + return defaultInstance; + } + + public addressMappingGetResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private addressMappingGetResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = result_.toBuilder(); + } + result_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(result_); + result_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingGetResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingGetResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public addressMappingGetResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new addressMappingGetResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + public static final int RESULT_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet result_; + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +     * List of matching mappings, might be empty.
    +     * 
    + */ + public boolean hasResult() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +     * List of matching mappings, might be empty.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet getResult() { + return result_; + } + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +     * List of matching mappings, might be empty.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSetOrBuilder getResultOrBuilder() { + return result_; + } + + private void initFields() { + result_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (hasResult()) { + if (!getResult().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, result_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, result_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.addressMappingGetResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingGetResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingGetResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getResultFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (resultBuilder_ == null) { + result_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.getDefaultInstance(); + } else { + resultBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingGetResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (resultBuilder_ == null) { + result.result_ = result_; + } else { + result.result_ = resultBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse.getDefaultInstance()) return this; + if (other.hasResult()) { + mergeResult(other.getResult()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (hasResult()) { + if (!getResult().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet result_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSetOrBuilder> resultBuilder_; + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +       * List of matching mappings, might be empty.
    +       * 
    + */ + public boolean hasResult() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +       * List of matching mappings, might be empty.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet getResult() { + if (resultBuilder_ == null) { + return result_; + } else { + return resultBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +       * List of matching mappings, might be empty.
    +       * 
    + */ + public Builder setResult(org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet value) { + if (resultBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + result_ = value; + onChanged(); + } else { + resultBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +       * List of matching mappings, might be empty.
    +       * 
    + */ + public Builder setResult( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.Builder builderForValue) { + if (resultBuilder_ == null) { + result_ = builderForValue.build(); + onChanged(); + } else { + resultBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +       * List of matching mappings, might be empty.
    +       * 
    + */ + public Builder mergeResult(org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet value) { + if (resultBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + result_ != org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.getDefaultInstance()) { + result_ = + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.newBuilder(result_).mergeFrom(value).buildPartial(); + } else { + result_ = value; + } + onChanged(); + } else { + resultBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +       * List of matching mappings, might be empty.
    +       * 
    + */ + public Builder clearResult() { + if (resultBuilder_ == null) { + result_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.getDefaultInstance(); + onChanged(); + } else { + resultBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +       * List of matching mappings, might be empty.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.Builder getResultBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getResultFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +       * List of matching mappings, might be empty.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSetOrBuilder getResultOrBuilder() { + if (resultBuilder_ != null) { + return resultBuilder_.getMessageOrBuilder(); + } else { + return result_; + } + } + /** + * optional .xtreemfs.pbrpc.AddressMappingSet result = 1; + * + *
    +       * List of matching mappings, might be empty.
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSetOrBuilder> + getResultFieldBuilder() { + if (resultBuilder_ == null) { + resultBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSetOrBuilder>( + result_, + getParentForChildren(), + isClean()); + result_ = null; + } + return resultBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.addressMappingGetResponse) + } + + static { + defaultInstance = new addressMappingGetResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.addressMappingGetResponse) + } + + public interface addressMappingSetResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional fixed64 new_version = 1; + /** + * optional fixed64 new_version = 1; + * + *
    +     * New version number assigned to the address mapping
    +     * by the DIR.
    +     * 
    + */ + boolean hasNewVersion(); + /** + * optional fixed64 new_version = 1; + * + *
    +     * New version number assigned to the address mapping
    +     * by the DIR.
    +     * 
    + */ + long getNewVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.addressMappingSetResponse} + */ + public static final class addressMappingSetResponse extends + com.google.protobuf.GeneratedMessage + implements addressMappingSetResponseOrBuilder { + // Use addressMappingSetResponse.newBuilder() to construct. + private addressMappingSetResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private addressMappingSetResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final addressMappingSetResponse defaultInstance; + public static addressMappingSetResponse getDefaultInstance() { + return defaultInstance; + } + + public addressMappingSetResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private addressMappingSetResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + newVersion_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingSetResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingSetResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public addressMappingSetResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new addressMappingSetResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional fixed64 new_version = 1; + public static final int NEW_VERSION_FIELD_NUMBER = 1; + private long newVersion_; + /** + * optional fixed64 new_version = 1; + * + *
    +     * New version number assigned to the address mapping
    +     * by the DIR.
    +     * 
    + */ + public boolean hasNewVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional fixed64 new_version = 1; + * + *
    +     * New version number assigned to the address mapping
    +     * by the DIR.
    +     * 
    + */ + public long getNewVersion() { + return newVersion_; + } + + private void initFields() { + newVersion_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, newVersion_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, newVersion_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.addressMappingSetResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingSetResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingSetResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + newVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_addressMappingSetResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.newVersion_ = newVersion_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse.getDefaultInstance()) return this; + if (other.hasNewVersion()) { + setNewVersion(other.getNewVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional fixed64 new_version = 1; + private long newVersion_ ; + /** + * optional fixed64 new_version = 1; + * + *
    +       * New version number assigned to the address mapping
    +       * by the DIR.
    +       * 
    + */ + public boolean hasNewVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional fixed64 new_version = 1; + * + *
    +       * New version number assigned to the address mapping
    +       * by the DIR.
    +       * 
    + */ + public long getNewVersion() { + return newVersion_; + } + /** + * optional fixed64 new_version = 1; + * + *
    +       * New version number assigned to the address mapping
    +       * by the DIR.
    +       * 
    + */ + public Builder setNewVersion(long value) { + bitField0_ |= 0x00000001; + newVersion_ = value; + onChanged(); + return this; + } + /** + * optional fixed64 new_version = 1; + * + *
    +       * New version number assigned to the address mapping
    +       * by the DIR.
    +       * 
    + */ + public Builder clearNewVersion() { + bitField0_ = (bitField0_ & ~0x00000001); + newVersion_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.addressMappingSetResponse) + } + + static { + defaultInstance = new addressMappingSetResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.addressMappingSetResponse) + } + + public interface globalTimeSGetResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 time_in_seconds = 1; + /** + * required fixed64 time_in_seconds = 1; + * + *
    +     * Global XtreemFS time in seconds.
    +     * 
    + */ + boolean hasTimeInSeconds(); + /** + * required fixed64 time_in_seconds = 1; + * + *
    +     * Global XtreemFS time in seconds.
    +     * 
    + */ + long getTimeInSeconds(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.globalTimeSGetResponse} + */ + public static final class globalTimeSGetResponse extends + com.google.protobuf.GeneratedMessage + implements globalTimeSGetResponseOrBuilder { + // Use globalTimeSGetResponse.newBuilder() to construct. + private globalTimeSGetResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private globalTimeSGetResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final globalTimeSGetResponse defaultInstance; + public static globalTimeSGetResponse getDefaultInstance() { + return defaultInstance; + } + + public globalTimeSGetResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private globalTimeSGetResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + timeInSeconds_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_globalTimeSGetResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_globalTimeSGetResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public globalTimeSGetResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new globalTimeSGetResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 time_in_seconds = 1; + public static final int TIME_IN_SECONDS_FIELD_NUMBER = 1; + private long timeInSeconds_; + /** + * required fixed64 time_in_seconds = 1; + * + *
    +     * Global XtreemFS time in seconds.
    +     * 
    + */ + public boolean hasTimeInSeconds() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 time_in_seconds = 1; + * + *
    +     * Global XtreemFS time in seconds.
    +     * 
    + */ + public long getTimeInSeconds() { + return timeInSeconds_; + } + + private void initFields() { + timeInSeconds_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasTimeInSeconds()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, timeInSeconds_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, timeInSeconds_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.globalTimeSGetResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_globalTimeSGetResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_globalTimeSGetResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + timeInSeconds_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_globalTimeSGetResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.timeInSeconds_ = timeInSeconds_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse.getDefaultInstance()) return this; + if (other.hasTimeInSeconds()) { + setTimeInSeconds(other.getTimeInSeconds()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasTimeInSeconds()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 time_in_seconds = 1; + private long timeInSeconds_ ; + /** + * required fixed64 time_in_seconds = 1; + * + *
    +       * Global XtreemFS time in seconds.
    +       * 
    + */ + public boolean hasTimeInSeconds() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 time_in_seconds = 1; + * + *
    +       * Global XtreemFS time in seconds.
    +       * 
    + */ + public long getTimeInSeconds() { + return timeInSeconds_; + } + /** + * required fixed64 time_in_seconds = 1; + * + *
    +       * Global XtreemFS time in seconds.
    +       * 
    + */ + public Builder setTimeInSeconds(long value) { + bitField0_ |= 0x00000001; + timeInSeconds_ = value; + onChanged(); + return this; + } + /** + * required fixed64 time_in_seconds = 1; + * + *
    +       * Global XtreemFS time in seconds.
    +       * 
    + */ + public Builder clearTimeInSeconds() { + bitField0_ = (bitField0_ & ~0x00000001); + timeInSeconds_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.globalTimeSGetResponse) + } + + static { + defaultInstance = new globalTimeSGetResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.globalTimeSGetResponse) + } + + public interface serviceDeregisterRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string uuid = 1; + /** + * required string uuid = 1; + * + *
    +     * UUID of the service that should be dregistered.
    +     * 
    + */ + boolean hasUuid(); + /** + * required string uuid = 1; + * + *
    +     * UUID of the service that should be dregistered.
    +     * 
    + */ + java.lang.String getUuid(); + /** + * required string uuid = 1; + * + *
    +     * UUID of the service that should be dregistered.
    +     * 
    + */ + com.google.protobuf.ByteString + getUuidBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceDeregisterRequest} + */ + public static final class serviceDeregisterRequest extends + com.google.protobuf.GeneratedMessage + implements serviceDeregisterRequestOrBuilder { + // Use serviceDeregisterRequest.newBuilder() to construct. + private serviceDeregisterRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private serviceDeregisterRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final serviceDeregisterRequest defaultInstance; + public static serviceDeregisterRequest getDefaultInstance() { + return defaultInstance; + } + + public serviceDeregisterRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private serviceDeregisterRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + uuid_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceDeregisterRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceDeregisterRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public serviceDeregisterRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new serviceDeregisterRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string uuid = 1; + public static final int UUID_FIELD_NUMBER = 1; + private java.lang.Object uuid_; + /** + * required string uuid = 1; + * + *
    +     * UUID of the service that should be dregistered.
    +     * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string uuid = 1; + * + *
    +     * UUID of the service that should be dregistered.
    +     * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + uuid_ = s; + } + return s; + } + } + /** + * required string uuid = 1; + * + *
    +     * UUID of the service that should be dregistered.
    +     * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + uuid_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasUuid()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getUuidBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getUuidBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceDeregisterRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceDeregisterRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceDeregisterRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + uuid_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceDeregisterRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.uuid_ = uuid_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest.getDefaultInstance()) return this; + if (other.hasUuid()) { + bitField0_ |= 0x00000001; + uuid_ = other.uuid_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasUuid()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceDeregisterRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string uuid = 1; + private java.lang.Object uuid_ = ""; + /** + * required string uuid = 1; + * + *
    +       * UUID of the service that should be dregistered.
    +       * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the service that should be dregistered.
    +       * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + uuid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the service that should be dregistered.
    +       * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the service that should be dregistered.
    +       * 
    + */ + public Builder setUuid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + uuid_ = value; + onChanged(); + return this; + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the service that should be dregistered.
    +       * 
    + */ + public Builder clearUuid() { + bitField0_ = (bitField0_ & ~0x00000001); + uuid_ = getDefaultInstance().getUuid(); + onChanged(); + return this; + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the service that should be dregistered.
    +       * 
    + */ + public Builder setUuidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + uuid_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.serviceDeregisterRequest) + } + + static { + defaultInstance = new serviceDeregisterRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceDeregisterRequest) + } + + public interface serviceGetByNameRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string name = 1; + /** + * required string name = 1; + * + *
    +     * Service name to search for.
    +     * 
    + */ + boolean hasName(); + /** + * required string name = 1; + * + *
    +     * Service name to search for.
    +     * 
    + */ + java.lang.String getName(); + /** + * required string name = 1; + * + *
    +     * Service name to search for.
    +     * 
    + */ + com.google.protobuf.ByteString + getNameBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceGetByNameRequest} + */ + public static final class serviceGetByNameRequest extends + com.google.protobuf.GeneratedMessage + implements serviceGetByNameRequestOrBuilder { + // Use serviceGetByNameRequest.newBuilder() to construct. + private serviceGetByNameRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private serviceGetByNameRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final serviceGetByNameRequest defaultInstance; + public static serviceGetByNameRequest getDefaultInstance() { + return defaultInstance; + } + + public serviceGetByNameRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private serviceGetByNameRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + name_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByNameRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByNameRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public serviceGetByNameRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new serviceGetByNameRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string name = 1; + public static final int NAME_FIELD_NUMBER = 1; + private java.lang.Object name_; + /** + * required string name = 1; + * + *
    +     * Service name to search for.
    +     * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string name = 1; + * + *
    +     * Service name to search for.
    +     * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * required string name = 1; + * + *
    +     * Service name to search for.
    +     * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + name_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasName()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getNameBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getNameBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceGetByNameRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByNameRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByNameRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByNameRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.name_ = name_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest.getDefaultInstance()) return this; + if (other.hasName()) { + bitField0_ |= 0x00000001; + name_ = other.name_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasName()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByNameRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string name = 1; + private java.lang.Object name_ = ""; + /** + * required string name = 1; + * + *
    +       * Service name to search for.
    +       * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string name = 1; + * + *
    +       * Service name to search for.
    +       * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string name = 1; + * + *
    +       * Service name to search for.
    +       * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string name = 1; + * + *
    +       * Service name to search for.
    +       * 
    + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + /** + * required string name = 1; + * + *
    +       * Service name to search for.
    +       * 
    + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000001); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * required string name = 1; + * + *
    +       * Service name to search for.
    +       * 
    + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.serviceGetByNameRequest) + } + + static { + defaultInstance = new serviceGetByNameRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceGetByNameRequest) + } + + public interface serviceGetByUUIDRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string name = 1; + /** + * required string name = 1; + * + *
    +     * UUID to search for.
    +     * 
    + */ + boolean hasName(); + /** + * required string name = 1; + * + *
    +     * UUID to search for.
    +     * 
    + */ + java.lang.String getName(); + /** + * required string name = 1; + * + *
    +     * UUID to search for.
    +     * 
    + */ + com.google.protobuf.ByteString + getNameBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceGetByUUIDRequest} + */ + public static final class serviceGetByUUIDRequest extends + com.google.protobuf.GeneratedMessage + implements serviceGetByUUIDRequestOrBuilder { + // Use serviceGetByUUIDRequest.newBuilder() to construct. + private serviceGetByUUIDRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private serviceGetByUUIDRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final serviceGetByUUIDRequest defaultInstance; + public static serviceGetByUUIDRequest getDefaultInstance() { + return defaultInstance; + } + + public serviceGetByUUIDRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private serviceGetByUUIDRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + name_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByUUIDRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByUUIDRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public serviceGetByUUIDRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new serviceGetByUUIDRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string name = 1; + public static final int NAME_FIELD_NUMBER = 1; + private java.lang.Object name_; + /** + * required string name = 1; + * + *
    +     * UUID to search for.
    +     * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string name = 1; + * + *
    +     * UUID to search for.
    +     * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * required string name = 1; + * + *
    +     * UUID to search for.
    +     * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + name_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasName()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getNameBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getNameBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceGetByUUIDRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByUUIDRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByUUIDRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByUUIDRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.name_ = name_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest.getDefaultInstance()) return this; + if (other.hasName()) { + bitField0_ |= 0x00000001; + name_ = other.name_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasName()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByUUIDRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string name = 1; + private java.lang.Object name_ = ""; + /** + * required string name = 1; + * + *
    +       * UUID to search for.
    +       * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string name = 1; + * + *
    +       * UUID to search for.
    +       * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string name = 1; + * + *
    +       * UUID to search for.
    +       * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string name = 1; + * + *
    +       * UUID to search for.
    +       * 
    + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + /** + * required string name = 1; + * + *
    +       * UUID to search for.
    +       * 
    + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000001); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * required string name = 1; + * + *
    +       * UUID to search for.
    +       * 
    + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.serviceGetByUUIDRequest) + } + + static { + defaultInstance = new serviceGetByUUIDRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceGetByUUIDRequest) + } + + public interface serviceGetByTypeRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.ServiceType type = 1; + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + * + *
    +     * Service types to search for.
    +     * 
    + */ + boolean hasType(); + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + * + *
    +     * Service types to search for.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType getType(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceGetByTypeRequest} + */ + public static final class serviceGetByTypeRequest extends + com.google.protobuf.GeneratedMessage + implements serviceGetByTypeRequestOrBuilder { + // Use serviceGetByTypeRequest.newBuilder() to construct. + private serviceGetByTypeRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private serviceGetByTypeRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final serviceGetByTypeRequest defaultInstance; + public static serviceGetByTypeRequest getDefaultInstance() { + return defaultInstance; + } + + public serviceGetByTypeRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private serviceGetByTypeRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + int rawValue = input.readEnum(); + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType value = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(1, rawValue); + } else { + bitField0_ |= 0x00000001; + type_ = value; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByTypeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByTypeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public serviceGetByTypeRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new serviceGetByTypeRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.ServiceType type = 1; + public static final int TYPE_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType type_; + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + * + *
    +     * Service types to search for.
    +     * 
    + */ + public boolean hasType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + * + *
    +     * Service types to search for.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType getType() { + return type_; + } + + private void initFields() { + type_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType.SERVICE_TYPE_MIXED; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasType()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeEnum(1, type_.getNumber()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(1, type_.getNumber()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceGetByTypeRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByTypeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByTypeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + type_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType.SERVICE_TYPE_MIXED; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceGetByTypeRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.type_ = type_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest.getDefaultInstance()) return this; + if (other.hasType()) { + setType(other.getType()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasType()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceGetByTypeRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.ServiceType type = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType type_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType.SERVICE_TYPE_MIXED; + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + * + *
    +       * Service types to search for.
    +       * 
    + */ + public boolean hasType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + * + *
    +       * Service types to search for.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType getType() { + return type_; + } + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + * + *
    +       * Service types to search for.
    +       * 
    + */ + public Builder setType(org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + type_ = value; + onChanged(); + return this; + } + /** + * required .xtreemfs.pbrpc.ServiceType type = 1; + * + *
    +       * Service types to search for.
    +       * 
    + */ + public Builder clearType() { + bitField0_ = (bitField0_ & ~0x00000001); + type_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType.SERVICE_TYPE_MIXED; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.serviceGetByTypeRequest) + } + + static { + defaultInstance = new serviceGetByTypeRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceGetByTypeRequest) + } + + public interface serviceRegisterRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.Service service = 1; + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +     * Service data to be registered.
    +     * Old data for the service with the same UUID is
    +     * overwritten.
    +     * 
    + */ + boolean hasService(); + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +     * Service data to be registered.
    +     * Old data for the service with the same UUID is
    +     * overwritten.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service getService(); + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +     * Service data to be registered.
    +     * Old data for the service with the same UUID is
    +     * overwritten.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder getServiceOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceRegisterRequest} + */ + public static final class serviceRegisterRequest extends + com.google.protobuf.GeneratedMessage + implements serviceRegisterRequestOrBuilder { + // Use serviceRegisterRequest.newBuilder() to construct. + private serviceRegisterRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private serviceRegisterRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final serviceRegisterRequest defaultInstance; + public static serviceRegisterRequest getDefaultInstance() { + return defaultInstance; + } + + public serviceRegisterRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private serviceRegisterRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = service_.toBuilder(); + } + service_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(service_); + service_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceRegisterRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceRegisterRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public serviceRegisterRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new serviceRegisterRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.Service service = 1; + public static final int SERVICE_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service service_; + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +     * Service data to be registered.
    +     * Old data for the service with the same UUID is
    +     * overwritten.
    +     * 
    + */ + public boolean hasService() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +     * Service data to be registered.
    +     * Old data for the service with the same UUID is
    +     * overwritten.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service getService() { + return service_; + } + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +     * Service data to be registered.
    +     * Old data for the service with the same UUID is
    +     * overwritten.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder getServiceOrBuilder() { + return service_; + } + + private void initFields() { + service_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasService()) { + memoizedIsInitialized = 0; + return false; + } + if (!getService().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, service_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, service_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceRegisterRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceRegisterRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceRegisterRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getServiceFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (serviceBuilder_ == null) { + service_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.getDefaultInstance(); + } else { + serviceBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceRegisterRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (serviceBuilder_ == null) { + result.service_ = service_; + } else { + result.service_ = serviceBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest.getDefaultInstance()) return this; + if (other.hasService()) { + mergeService(other.getService()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasService()) { + + return false; + } + if (!getService().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.Service service = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service service_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder> serviceBuilder_; + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +       * Service data to be registered.
    +       * Old data for the service with the same UUID is
    +       * overwritten.
    +       * 
    + */ + public boolean hasService() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +       * Service data to be registered.
    +       * Old data for the service with the same UUID is
    +       * overwritten.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service getService() { + if (serviceBuilder_ == null) { + return service_; + } else { + return serviceBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +       * Service data to be registered.
    +       * Old data for the service with the same UUID is
    +       * overwritten.
    +       * 
    + */ + public Builder setService(org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service value) { + if (serviceBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + service_ = value; + onChanged(); + } else { + serviceBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +       * Service data to be registered.
    +       * Old data for the service with the same UUID is
    +       * overwritten.
    +       * 
    + */ + public Builder setService( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder builderForValue) { + if (serviceBuilder_ == null) { + service_ = builderForValue.build(); + onChanged(); + } else { + serviceBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +       * Service data to be registered.
    +       * Old data for the service with the same UUID is
    +       * overwritten.
    +       * 
    + */ + public Builder mergeService(org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service value) { + if (serviceBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + service_ != org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.getDefaultInstance()) { + service_ = + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.newBuilder(service_).mergeFrom(value).buildPartial(); + } else { + service_ = value; + } + onChanged(); + } else { + serviceBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +       * Service data to be registered.
    +       * Old data for the service with the same UUID is
    +       * overwritten.
    +       * 
    + */ + public Builder clearService() { + if (serviceBuilder_ == null) { + service_ = org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.getDefaultInstance(); + onChanged(); + } else { + serviceBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +       * Service data to be registered.
    +       * Old data for the service with the same UUID is
    +       * overwritten.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder getServiceBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getServiceFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +       * Service data to be registered.
    +       * Old data for the service with the same UUID is
    +       * overwritten.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder getServiceOrBuilder() { + if (serviceBuilder_ != null) { + return serviceBuilder_.getMessageOrBuilder(); + } else { + return service_; + } + } + /** + * required .xtreemfs.pbrpc.Service service = 1; + * + *
    +       * Service data to be registered.
    +       * Old data for the service with the same UUID is
    +       * overwritten.
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder> + getServiceFieldBuilder() { + if (serviceBuilder_ == null) { + serviceBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service, org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service.Builder, org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceOrBuilder>( + service_, + getParentForChildren(), + isClean()); + service_ = null; + } + return serviceBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.serviceRegisterRequest) + } + + static { + defaultInstance = new serviceRegisterRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceRegisterRequest) + } + + public interface serviceRegisterResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 new_version = 1; + /** + * required fixed64 new_version = 1; + * + *
    +     * New version assigned to the service record by the DIR.
    +     * 
    + */ + boolean hasNewVersion(); + /** + * required fixed64 new_version = 1; + * + *
    +     * New version assigned to the service record by the DIR.
    +     * 
    + */ + long getNewVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceRegisterResponse} + */ + public static final class serviceRegisterResponse extends + com.google.protobuf.GeneratedMessage + implements serviceRegisterResponseOrBuilder { + // Use serviceRegisterResponse.newBuilder() to construct. + private serviceRegisterResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private serviceRegisterResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final serviceRegisterResponse defaultInstance; + public static serviceRegisterResponse getDefaultInstance() { + return defaultInstance; + } + + public serviceRegisterResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private serviceRegisterResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + newVersion_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceRegisterResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceRegisterResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public serviceRegisterResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new serviceRegisterResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 new_version = 1; + public static final int NEW_VERSION_FIELD_NUMBER = 1; + private long newVersion_; + /** + * required fixed64 new_version = 1; + * + *
    +     * New version assigned to the service record by the DIR.
    +     * 
    + */ + public boolean hasNewVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 new_version = 1; + * + *
    +     * New version assigned to the service record by the DIR.
    +     * 
    + */ + public long getNewVersion() { + return newVersion_; + } + + private void initFields() { + newVersion_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasNewVersion()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, newVersion_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, newVersion_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.serviceRegisterResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceRegisterResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceRegisterResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + newVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_serviceRegisterResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.newVersion_ = newVersion_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse.getDefaultInstance()) return this; + if (other.hasNewVersion()) { + setNewVersion(other.getNewVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasNewVersion()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 new_version = 1; + private long newVersion_ ; + /** + * required fixed64 new_version = 1; + * + *
    +       * New version assigned to the service record by the DIR.
    +       * 
    + */ + public boolean hasNewVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 new_version = 1; + * + *
    +       * New version assigned to the service record by the DIR.
    +       * 
    + */ + public long getNewVersion() { + return newVersion_; + } + /** + * required fixed64 new_version = 1; + * + *
    +       * New version assigned to the service record by the DIR.
    +       * 
    + */ + public Builder setNewVersion(long value) { + bitField0_ |= 0x00000001; + newVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 new_version = 1; + * + *
    +       * New version assigned to the service record by the DIR.
    +       * 
    + */ + public Builder clearNewVersion() { + bitField0_ = (bitField0_ & ~0x00000001); + newVersion_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.serviceRegisterResponse) + } + + static { + defaultInstance = new serviceRegisterResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.serviceRegisterResponse) + } + + public interface configurationGetRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string uuid = 1; + /** + * required string uuid = 1; + * + *
    +     * UUID of the servic for which the configuration is requested.
    +     * 
    + */ + boolean hasUuid(); + /** + * required string uuid = 1; + * + *
    +     * UUID of the servic for which the configuration is requested.
    +     * 
    + */ + java.lang.String getUuid(); + /** + * required string uuid = 1; + * + *
    +     * UUID of the servic for which the configuration is requested.
    +     * 
    + */ + com.google.protobuf.ByteString + getUuidBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.configurationGetRequest} + */ + public static final class configurationGetRequest extends + com.google.protobuf.GeneratedMessage + implements configurationGetRequestOrBuilder { + // Use configurationGetRequest.newBuilder() to construct. + private configurationGetRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private configurationGetRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final configurationGetRequest defaultInstance; + public static configurationGetRequest getDefaultInstance() { + return defaultInstance; + } + + public configurationGetRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private configurationGetRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + uuid_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_configurationGetRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_configurationGetRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public configurationGetRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new configurationGetRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string uuid = 1; + public static final int UUID_FIELD_NUMBER = 1; + private java.lang.Object uuid_; + /** + * required string uuid = 1; + * + *
    +     * UUID of the servic for which the configuration is requested.
    +     * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string uuid = 1; + * + *
    +     * UUID of the servic for which the configuration is requested.
    +     * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + uuid_ = s; + } + return s; + } + } + /** + * required string uuid = 1; + * + *
    +     * UUID of the servic for which the configuration is requested.
    +     * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + uuid_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasUuid()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getUuidBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getUuidBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.configurationGetRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_configurationGetRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_configurationGetRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + uuid_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_configurationGetRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.uuid_ = uuid_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest.getDefaultInstance()) return this; + if (other.hasUuid()) { + bitField0_ |= 0x00000001; + uuid_ = other.uuid_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasUuid()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationGetRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string uuid = 1; + private java.lang.Object uuid_ = ""; + /** + * required string uuid = 1; + * + *
    +       * UUID of the servic for which the configuration is requested.
    +       * 
    + */ + public boolean hasUuid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the servic for which the configuration is requested.
    +       * 
    + */ + public java.lang.String getUuid() { + java.lang.Object ref = uuid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + uuid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the servic for which the configuration is requested.
    +       * 
    + */ + public com.google.protobuf.ByteString + getUuidBytes() { + java.lang.Object ref = uuid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + uuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the servic for which the configuration is requested.
    +       * 
    + */ + public Builder setUuid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + uuid_ = value; + onChanged(); + return this; + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the servic for which the configuration is requested.
    +       * 
    + */ + public Builder clearUuid() { + bitField0_ = (bitField0_ & ~0x00000001); + uuid_ = getDefaultInstance().getUuid(); + onChanged(); + return this; + } + /** + * required string uuid = 1; + * + *
    +       * UUID of the servic for which the configuration is requested.
    +       * 
    + */ + public Builder setUuidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + uuid_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.configurationGetRequest) + } + + static { + defaultInstance = new configurationGetRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.configurationGetRequest) + } + + public interface configurationSetResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional fixed64 new_version = 1; + /** + * optional fixed64 new_version = 1; + * + *
    +     * New version assigned to the configuration record by the DIR.
    +     * 
    + */ + boolean hasNewVersion(); + /** + * optional fixed64 new_version = 1; + * + *
    +     * New version assigned to the configuration record by the DIR.
    +     * 
    + */ + long getNewVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.configurationSetResponse} + */ + public static final class configurationSetResponse extends + com.google.protobuf.GeneratedMessage + implements configurationSetResponseOrBuilder { + // Use configurationSetResponse.newBuilder() to construct. + private configurationSetResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private configurationSetResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final configurationSetResponse defaultInstance; + public static configurationSetResponse getDefaultInstance() { + return defaultInstance; + } + + public configurationSetResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private configurationSetResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + newVersion_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_configurationSetResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_configurationSetResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public configurationSetResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new configurationSetResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional fixed64 new_version = 1; + public static final int NEW_VERSION_FIELD_NUMBER = 1; + private long newVersion_; + /** + * optional fixed64 new_version = 1; + * + *
    +     * New version assigned to the configuration record by the DIR.
    +     * 
    + */ + public boolean hasNewVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional fixed64 new_version = 1; + * + *
    +     * New version assigned to the configuration record by the DIR.
    +     * 
    + */ + public long getNewVersion() { + return newVersion_; + } + + private void initFields() { + newVersion_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, newVersion_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, newVersion_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.configurationSetResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_configurationSetResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_configurationSetResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + newVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.internal_static_xtreemfs_pbrpc_configurationSetResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.newVersion_ = newVersion_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse.getDefaultInstance()) return this; + if (other.hasNewVersion()) { + setNewVersion(other.getNewVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional fixed64 new_version = 1; + private long newVersion_ ; + /** + * optional fixed64 new_version = 1; + * + *
    +       * New version assigned to the configuration record by the DIR.
    +       * 
    + */ + public boolean hasNewVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional fixed64 new_version = 1; + * + *
    +       * New version assigned to the configuration record by the DIR.
    +       * 
    + */ + public long getNewVersion() { + return newVersion_; + } + /** + * optional fixed64 new_version = 1; + * + *
    +       * New version assigned to the configuration record by the DIR.
    +       * 
    + */ + public Builder setNewVersion(long value) { + bitField0_ |= 0x00000001; + newVersion_ = value; + onChanged(); + return this; + } + /** + * optional fixed64 new_version = 1; + * + *
    +       * New version assigned to the configuration record by the DIR.
    +       * 
    + */ + public Builder clearNewVersion() { + bitField0_ = (bitField0_ & ~0x00000001); + newVersion_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.configurationSetResponse) + } + + static { + defaultInstance = new configurationSetResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.configurationSetResponse) + } + + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_AddressMapping_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_AddressMapping_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_AddressMappingSet_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_AddressMappingSet_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_DirService_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_DirService_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_ServiceDataMap_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_ServiceDataMap_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_Service_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_Service_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_ServiceSet_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_ServiceSet_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_Configuration_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_Configuration_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_addressMappingGetRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_addressMappingGetRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_addressMappingGetResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_addressMappingGetResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_addressMappingSetResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_addressMappingSetResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_globalTimeSGetResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_globalTimeSGetResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_serviceDeregisterRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_serviceDeregisterRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_serviceGetByNameRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_serviceGetByNameRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_serviceGetByUUIDRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_serviceGetByUUIDRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_serviceGetByTypeRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_serviceGetByTypeRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_serviceRegisterRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_serviceRegisterRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_serviceRegisterResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_serviceRegisterResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_configurationGetRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_configurationGetRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_configurationSetResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_configurationSetResponse_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\022xtreemfs/DIR.proto\022\016xtreemfs.pbrpc\032\023in" + + "clude/PBRPC.proto\032\024include/Common.proto\032" + + "\032xtreemfs/GlobalTypes.proto\"\223\001\n\016AddressM" + + "apping\022\014\n\004uuid\030\001 \002(\t\022\017\n\007version\030\002 \002(\006\022\020\n" + + "\010protocol\030\003 \002(\t\022\017\n\007address\030\004 \002(\t\022\014\n\004port" + + "\030\005 \002(\007\022\025\n\rmatch_network\030\006 \002(\t\022\r\n\005ttl_s\030\007" + + " \002(\007\022\013\n\003uri\030\010 \002(\t\"E\n\021AddressMappingSet\0220" + + "\n\010mappings\030\001 \003(\0132\036.xtreemfs.pbrpc.Addres" + + "sMapping\"X\n\nDirService\022\017\n\007address\030\001 \002(\t\022" + + "\014\n\004port\030\002 \002(\007\022\020\n\010protocol\030\003 \002(\t\022\031\n\021inter", + "face_version\030\004 \002(\007\"<\n\016ServiceDataMap\022*\n\004" + + "data\030\001 \003(\0132\034.xtreemfs.pbrpc.KeyValuePair" + + "\"\247\001\n\007Service\022)\n\004type\030\001 \002(\0162\033.xtreemfs.pb" + + "rpc.ServiceType\022\014\n\004uuid\030\002 \002(\t\022\017\n\007version" + + "\030\003 \002(\006\022\014\n\004name\030\004 \002(\t\022\026\n\016last_updated_s\030\005" + + " \002(\006\022,\n\004data\030\006 \002(\0132\036.xtreemfs.pbrpc.Serv" + + "iceDataMap\"7\n\nServiceSet\022)\n\010services\030\001 \003" + + "(\0132\027.xtreemfs.pbrpc.Service\"_\n\rConfigura" + + "tion\022\014\n\004uuid\030\001 \002(\t\022/\n\tparameter\030\002 \003(\0132\034." + + "xtreemfs.pbrpc.KeyValuePair\022\017\n\007version\030\003", + " \002(\006\"(\n\030addressMappingGetRequest\022\014\n\004uuid" + + "\030\001 \002(\t\"N\n\031addressMappingGetResponse\0221\n\006r" + + "esult\030\001 \001(\0132!.xtreemfs.pbrpc.AddressMapp" + + "ingSet\"0\n\031addressMappingSetResponse\022\023\n\013n" + + "ew_version\030\001 \001(\006\"1\n\026globalTimeSGetRespon" + + "se\022\027\n\017time_in_seconds\030\001 \002(\006\"(\n\030serviceDe" + + "registerRequest\022\014\n\004uuid\030\001 \002(\t\"\'\n\027service" + + "GetByNameRequest\022\014\n\004name\030\001 \002(\t\"\'\n\027servic" + + "eGetByUUIDRequest\022\014\n\004name\030\001 \002(\t\"D\n\027servi" + + "ceGetByTypeRequest\022)\n\004type\030\001 \002(\0162\033.xtree", + "mfs.pbrpc.ServiceType\"B\n\026serviceRegister" + + "Request\022(\n\007service\030\001 \002(\0132\027.xtreemfs.pbrp" + + "c.Service\".\n\027serviceRegisterResponse\022\023\n\013" + + "new_version\030\001 \002(\006\"\'\n\027configurationGetReq" + + "uest\022\014\n\004uuid\030\001 \002(\t\"/\n\030configurationSetRe" + + "sponse\022\023\n\013new_version\030\001 \001(\006*\200\001\n\013ServiceT" + + "ype\022\026\n\022SERVICE_TYPE_MIXED\020\000\022\024\n\020SERVICE_T" + + "YPE_MRC\020\001\022\024\n\020SERVICE_TYPE_OSD\020\002\022\027\n\023SERVI" + + "CE_TYPE_VOLUME\020\003\022\024\n\020SERVICE_TYPE_DIR\020\004*g" + + "\n\rServiceStatus\022\030\n\024SERVICE_STATUS_AVAIL\020", + "\000\022 \n\034SERVICE_STATUS_TO_BE_REMOVED\020\001\022\032\n\026S" + + "ERVICE_STATUS_REMOVED\020\0022\355\r\n\020DirectorySer" + + "vice\022u\n\035xtreemfs_address_mappings_get\022(." + + "xtreemfs.pbrpc.addressMappingGetRequest\032" + + "!.xtreemfs.pbrpc.AddressMappingSet\"\007\215\265\030\001" + + "\000\000\000\022t\n xtreemfs_address_mappings_remove\022" + + "(.xtreemfs.pbrpc.addressMappingGetReques" + + "t\032\035.xtreemfs.pbrpc.emptyResponse\"\007\215\265\030\002\000\000" + + "\000\022v\n\035xtreemfs_address_mappings_set\022!.xtr" + + "eemfs.pbrpc.AddressMappingSet\032).xtreemfs", + ".pbrpc.addressMappingSetResponse\"\007\215\265\030\003\000\000" + + "\000\022Z\n\025xtreemfs_discover_dir\022\034.xtreemfs.pb" + + "rpc.emptyRequest\032\032.xtreemfs.pbrpc.DirSer" + + "vice\"\007\215\265\030\004\000\000\000\022k\n\032xtreemfs_global_time_s_" + + "get\022\034.xtreemfs.pbrpc.emptyRequest\032&.xtre" + + "emfs.pbrpc.globalTimeSGetResponse\"\007\215\265\030\005\000" + + "\000\000\022o\n\033xtreemfs_service_deregister\022(.xtre" + + "emfs.pbrpc.serviceDeregisterRequest\032\035.xt" + + "reemfs.pbrpc.emptyResponse\"\007\215\265\030\006\000\000\000\022l\n\034x" + + "treemfs_service_get_by_name\022\'.xtreemfs.p", + "brpc.serviceGetByNameRequest\032\032.xtreemfs." + + "pbrpc.ServiceSet\"\007\215\265\030\007\000\000\000\022l\n\034xtreemfs_se" + + "rvice_get_by_type\022\'.xtreemfs.pbrpc.servi" + + "ceGetByTypeRequest\032\032.xtreemfs.pbrpc.Serv" + + "iceSet\"\007\215\265\030\010\000\000\000\022l\n\034xtreemfs_service_get_" + + "by_uuid\022\'.xtreemfs.pbrpc.serviceGetByUUI" + + "DRequest\032\032.xtreemfs.pbrpc.ServiceSet\"\007\215\265" + + "\030\t\000\000\000\022k\n\030xtreemfs_service_offline\022\'.xtre" + + "emfs.pbrpc.serviceGetByUUIDRequest\032\035.xtr" + + "eemfs.pbrpc.emptyResponse\"\007\215\265\030\n\000\000\000\022u\n\031xt", + "reemfs_service_register\022&.xtreemfs.pbrpc" + + ".serviceRegisterRequest\032\'.xtreemfs.pbrpc" + + ".serviceRegisterResponse\"\007\215\265\030\013\000\000\000\022[\n\023xtr" + + "eemfs_checkpoint\022\034.xtreemfs.pbrpc.emptyR" + + "equest\032\035.xtreemfs.pbrpc.emptyResponse\"\007\215" + + "\265\030\024\000\000\000\022Y\n\021xtreemfs_shutdown\022\034.xtreemfs.p" + + "brpc.emptyRequest\032\035.xtreemfs.pbrpc.empty" + + "Response\"\007\215\265\030\025\000\000\000\022m\n\032xtreemfs_configurat" + + "ion_get\022\'.xtreemfs.pbrpc.configurationGe" + + "tRequest\032\035.xtreemfs.pbrpc.Configuration\"", + "\007\215\265\030\026\000\000\000\022n\n\032xtreemfs_configuration_set\022\035" + + ".xtreemfs.pbrpc.Configuration\032(.xtreemfs" + + ".pbrpc.configurationSetResponse\"\007\215\265\030\027\000\000\000" + + "\022l\n\036xtreemfs_vivaldi_client_update\022\".xtr" + + "eemfs.pbrpc.VivaldiCoordinates\032\035.xtreemf" + + "s.pbrpc.emptyResponse\"\007\215\265\030\030\000\000\000\032\007\225\265\030\021\'\000\000B" + + "(\n&org.xtreemfs.pbrpc.generatedinterface" + + "s" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_xtreemfs_pbrpc_AddressMapping_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_xtreemfs_pbrpc_AddressMapping_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_AddressMapping_descriptor, + new java.lang.String[] { "Uuid", "Version", "Protocol", "Address", "Port", "MatchNetwork", "TtlS", "Uri", }); + internal_static_xtreemfs_pbrpc_AddressMappingSet_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_xtreemfs_pbrpc_AddressMappingSet_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_AddressMappingSet_descriptor, + new java.lang.String[] { "Mappings", }); + internal_static_xtreemfs_pbrpc_DirService_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_xtreemfs_pbrpc_DirService_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_DirService_descriptor, + new java.lang.String[] { "Address", "Port", "Protocol", "InterfaceVersion", }); + internal_static_xtreemfs_pbrpc_ServiceDataMap_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_xtreemfs_pbrpc_ServiceDataMap_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_ServiceDataMap_descriptor, + new java.lang.String[] { "Data", }); + internal_static_xtreemfs_pbrpc_Service_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_xtreemfs_pbrpc_Service_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_Service_descriptor, + new java.lang.String[] { "Type", "Uuid", "Version", "Name", "LastUpdatedS", "Data", }); + internal_static_xtreemfs_pbrpc_ServiceSet_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_xtreemfs_pbrpc_ServiceSet_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_ServiceSet_descriptor, + new java.lang.String[] { "Services", }); + internal_static_xtreemfs_pbrpc_Configuration_descriptor = + getDescriptor().getMessageTypes().get(6); + internal_static_xtreemfs_pbrpc_Configuration_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_Configuration_descriptor, + new java.lang.String[] { "Uuid", "Parameter", "Version", }); + internal_static_xtreemfs_pbrpc_addressMappingGetRequest_descriptor = + getDescriptor().getMessageTypes().get(7); + internal_static_xtreemfs_pbrpc_addressMappingGetRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_addressMappingGetRequest_descriptor, + new java.lang.String[] { "Uuid", }); + internal_static_xtreemfs_pbrpc_addressMappingGetResponse_descriptor = + getDescriptor().getMessageTypes().get(8); + internal_static_xtreemfs_pbrpc_addressMappingGetResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_addressMappingGetResponse_descriptor, + new java.lang.String[] { "Result", }); + internal_static_xtreemfs_pbrpc_addressMappingSetResponse_descriptor = + getDescriptor().getMessageTypes().get(9); + internal_static_xtreemfs_pbrpc_addressMappingSetResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_addressMappingSetResponse_descriptor, + new java.lang.String[] { "NewVersion", }); + internal_static_xtreemfs_pbrpc_globalTimeSGetResponse_descriptor = + getDescriptor().getMessageTypes().get(10); + internal_static_xtreemfs_pbrpc_globalTimeSGetResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_globalTimeSGetResponse_descriptor, + new java.lang.String[] { "TimeInSeconds", }); + internal_static_xtreemfs_pbrpc_serviceDeregisterRequest_descriptor = + getDescriptor().getMessageTypes().get(11); + internal_static_xtreemfs_pbrpc_serviceDeregisterRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_serviceDeregisterRequest_descriptor, + new java.lang.String[] { "Uuid", }); + internal_static_xtreemfs_pbrpc_serviceGetByNameRequest_descriptor = + getDescriptor().getMessageTypes().get(12); + internal_static_xtreemfs_pbrpc_serviceGetByNameRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_serviceGetByNameRequest_descriptor, + new java.lang.String[] { "Name", }); + internal_static_xtreemfs_pbrpc_serviceGetByUUIDRequest_descriptor = + getDescriptor().getMessageTypes().get(13); + internal_static_xtreemfs_pbrpc_serviceGetByUUIDRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_serviceGetByUUIDRequest_descriptor, + new java.lang.String[] { "Name", }); + internal_static_xtreemfs_pbrpc_serviceGetByTypeRequest_descriptor = + getDescriptor().getMessageTypes().get(14); + internal_static_xtreemfs_pbrpc_serviceGetByTypeRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_serviceGetByTypeRequest_descriptor, + new java.lang.String[] { "Type", }); + internal_static_xtreemfs_pbrpc_serviceRegisterRequest_descriptor = + getDescriptor().getMessageTypes().get(15); + internal_static_xtreemfs_pbrpc_serviceRegisterRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_serviceRegisterRequest_descriptor, + new java.lang.String[] { "Service", }); + internal_static_xtreemfs_pbrpc_serviceRegisterResponse_descriptor = + getDescriptor().getMessageTypes().get(16); + internal_static_xtreemfs_pbrpc_serviceRegisterResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_serviceRegisterResponse_descriptor, + new java.lang.String[] { "NewVersion", }); + internal_static_xtreemfs_pbrpc_configurationGetRequest_descriptor = + getDescriptor().getMessageTypes().get(17); + internal_static_xtreemfs_pbrpc_configurationGetRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_configurationGetRequest_descriptor, + new java.lang.String[] { "Uuid", }); + internal_static_xtreemfs_pbrpc_configurationSetResponse_descriptor = + getDescriptor().getMessageTypes().get(18); + internal_static_xtreemfs_pbrpc_configurationSetResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_configurationSetResponse_descriptor, + new java.lang.String[] { "NewVersion", }); + com.google.protobuf.ExtensionRegistry registry = + com.google.protobuf.ExtensionRegistry.newInstance(); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.interfaceId); + return registry; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.getDescriptor(), + org.xtreemfs.pbrpc.generatedinterfaces.Common.getDescriptor(), + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor(), + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIRServiceClient.java b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIRServiceClient.java new file mode 100644 index 0000000..5e59137 --- /dev/null +++ b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIRServiceClient.java @@ -0,0 +1,238 @@ +//automatically generated from DIR.proto at Thu Dec 11 16:09:37 CET 2014 +//(c) 2014. See LICENSE file for details. + +package org.xtreemfs.pbrpc.generatedinterfaces; + +import java.io.IOException; +import java.util.List; +import java.net.InetSocketAddress; +import com.google.protobuf.Message; +import com.google.protobuf.ByteString; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; + +public class DIRServiceClient { + + private RPCNIOSocketClient client; + private InetSocketAddress defaultServer; + + public DIRServiceClient(RPCNIOSocketClient client, InetSocketAddress defaultServer) { + this.client = client; + this.defaultServer = defaultServer; + } + + public RPCResponse xtreemfs_address_mappings_get(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.addressMappingGetRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(DIR.AddressMappingSet.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 10001, 1, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_address_mappings_get(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String uuid) throws IOException { + final DIR.addressMappingGetRequest msg = DIR.addressMappingGetRequest.newBuilder().setUuid(uuid).build(); + return xtreemfs_address_mappings_get(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_address_mappings_remove(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.addressMappingGetRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 10001, 2, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_address_mappings_remove(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String uuid) throws IOException { + final DIR.addressMappingGetRequest msg = DIR.addressMappingGetRequest.newBuilder().setUuid(uuid).build(); + return xtreemfs_address_mappings_remove(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_address_mappings_set(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.AddressMappingSet input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(DIR.addressMappingSetResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 10001, 3, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_address_mappings_set(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, List mappings) throws IOException { + final DIR.AddressMappingSet msg = DIR.AddressMappingSet.newBuilder().addAllMappings(mappings).build(); + return xtreemfs_address_mappings_set(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_discover_dir(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(DIR.DirService.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 10001, 4, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_discover_dir(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_discover_dir(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_global_time_s_get(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(DIR.globalTimeSGetResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 10001, 5, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_global_time_s_get(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_global_time_s_get(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_service_deregister(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.serviceDeregisterRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 10001, 6, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_service_deregister(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String uuid) throws IOException { + final DIR.serviceDeregisterRequest msg = DIR.serviceDeregisterRequest.newBuilder().setUuid(uuid).build(); + return xtreemfs_service_deregister(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_service_get_by_name(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.serviceGetByNameRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(DIR.ServiceSet.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 10001, 7, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_service_get_by_name(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String name) throws IOException { + final DIR.serviceGetByNameRequest msg = DIR.serviceGetByNameRequest.newBuilder().setName(name).build(); + return xtreemfs_service_get_by_name(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_service_get_by_type(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.serviceGetByTypeRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(DIR.ServiceSet.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 10001, 8, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_service_get_by_type(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.ServiceType type) throws IOException { + final DIR.serviceGetByTypeRequest msg = DIR.serviceGetByTypeRequest.newBuilder().setType(type).build(); + return xtreemfs_service_get_by_type(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_service_get_by_uuid(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.serviceGetByUUIDRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(DIR.ServiceSet.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 10001, 9, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_service_get_by_uuid(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String name) throws IOException { + final DIR.serviceGetByUUIDRequest msg = DIR.serviceGetByUUIDRequest.newBuilder().setName(name).build(); + return xtreemfs_service_get_by_uuid(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_service_offline(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.serviceGetByUUIDRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 10001, 10, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_service_offline(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String name) throws IOException { + final DIR.serviceGetByUUIDRequest msg = DIR.serviceGetByUUIDRequest.newBuilder().setName(name).build(); + return xtreemfs_service_offline(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_service_register(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.serviceRegisterRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(DIR.serviceRegisterResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 10001, 11, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_service_register(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.Service service) throws IOException { + final DIR.serviceRegisterRequest msg = DIR.serviceRegisterRequest.newBuilder().setService(service).build(); + return xtreemfs_service_register(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_checkpoint(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 10001, 20, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_checkpoint(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_checkpoint(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_shutdown(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 10001, 21, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_shutdown(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_shutdown(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_configuration_get(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.configurationGetRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(DIR.Configuration.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 10001, 22, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_configuration_get(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String uuid) throws IOException { + final DIR.configurationGetRequest msg = DIR.configurationGetRequest.newBuilder().setUuid(uuid).build(); + return xtreemfs_configuration_get(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_configuration_set(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, DIR.Configuration input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(DIR.configurationSetResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 10001, 23, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_configuration_set(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String uuid, List parameter, long version) throws IOException { + final DIR.Configuration msg = DIR.Configuration.newBuilder().setUuid(uuid).addAllParameter(parameter).setVersion(version).build(); + return xtreemfs_configuration_set(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_vivaldi_client_update(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.VivaldiCoordinates input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 10001, 24, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_vivaldi_client_update(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, double x_coordinate, double y_coordinate, double local_error) throws IOException { + final GlobalTypes.VivaldiCoordinates msg = GlobalTypes.VivaldiCoordinates.newBuilder().setXCoordinate(x_coordinate).setYCoordinate(y_coordinate).setLocalError(local_error).build(); + return xtreemfs_vivaldi_client_update(server, authHeader, userCreds,msg); + } + + public boolean clientIsAlive() { + return client.isAlive(); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIRServiceConstants.java b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIRServiceConstants.java new file mode 100644 index 0000000..e223d6e --- /dev/null +++ b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/DIRServiceConstants.java @@ -0,0 +1,74 @@ +//automatically generated from DIR.proto at Thu Dec 11 16:09:37 CET 2014 +//(c) 2014. See LICENSE file for details. + +package org.xtreemfs.pbrpc.generatedinterfaces; + +import com.google.protobuf.Message; + +public class DIRServiceConstants { + + public static final int INTERFACE_ID = 10001; + public static final int PROC_ID_XTREEMFS_ADDRESS_MAPPINGS_GET = 1; + public static final int PROC_ID_XTREEMFS_ADDRESS_MAPPINGS_REMOVE = 2; + public static final int PROC_ID_XTREEMFS_ADDRESS_MAPPINGS_SET = 3; + public static final int PROC_ID_XTREEMFS_DISCOVER_DIR = 4; + public static final int PROC_ID_XTREEMFS_GLOBAL_TIME_S_GET = 5; + public static final int PROC_ID_XTREEMFS_SERVICE_DEREGISTER = 6; + public static final int PROC_ID_XTREEMFS_SERVICE_GET_BY_NAME = 7; + public static final int PROC_ID_XTREEMFS_SERVICE_GET_BY_TYPE = 8; + public static final int PROC_ID_XTREEMFS_SERVICE_GET_BY_UUID = 9; + public static final int PROC_ID_XTREEMFS_SERVICE_OFFLINE = 10; + public static final int PROC_ID_XTREEMFS_SERVICE_REGISTER = 11; + public static final int PROC_ID_XTREEMFS_CHECKPOINT = 20; + public static final int PROC_ID_XTREEMFS_SHUTDOWN = 21; + public static final int PROC_ID_XTREEMFS_CONFIGURATION_GET = 22; + public static final int PROC_ID_XTREEMFS_CONFIGURATION_SET = 23; + public static final int PROC_ID_XTREEMFS_VIVALDI_CLIENT_UPDATE = 24; + + public static Message getRequestMessage(int procId) { + switch (procId) { + case 1: return DIR.addressMappingGetRequest.getDefaultInstance(); + case 2: return DIR.addressMappingGetRequest.getDefaultInstance(); + case 3: return DIR.AddressMappingSet.getDefaultInstance(); + case 4: return null; + case 5: return null; + case 6: return DIR.serviceDeregisterRequest.getDefaultInstance(); + case 7: return DIR.serviceGetByNameRequest.getDefaultInstance(); + case 8: return DIR.serviceGetByTypeRequest.getDefaultInstance(); + case 9: return DIR.serviceGetByUUIDRequest.getDefaultInstance(); + case 10: return DIR.serviceGetByUUIDRequest.getDefaultInstance(); + case 11: return DIR.serviceRegisterRequest.getDefaultInstance(); + case 20: return null; + case 21: return null; + case 22: return DIR.configurationGetRequest.getDefaultInstance(); + case 23: return DIR.Configuration.getDefaultInstance(); + case 24: return GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + default: throw new RuntimeException("unknown procedure id"); + } + } + + + public static Message getResponseMessage(int procId) { + switch (procId) { + case 1: return DIR.AddressMappingSet.getDefaultInstance(); + case 2: return null; + case 3: return DIR.addressMappingSetResponse.getDefaultInstance(); + case 4: return DIR.DirService.getDefaultInstance(); + case 5: return DIR.globalTimeSGetResponse.getDefaultInstance(); + case 6: return null; + case 7: return DIR.ServiceSet.getDefaultInstance(); + case 8: return DIR.ServiceSet.getDefaultInstance(); + case 9: return DIR.ServiceSet.getDefaultInstance(); + case 10: return null; + case 11: return DIR.serviceRegisterResponse.getDefaultInstance(); + case 20: return null; + case 21: return null; + case 22: return DIR.Configuration.getDefaultInstance(); + case 23: return DIR.configurationSetResponse.getDefaultInstance(); + case 24: return null; + default: throw new RuntimeException("unknown procedure id"); + } + } + + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/GlobalTypes.java b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/GlobalTypes.java new file mode 100644 index 0000000..eab9317 --- /dev/null +++ b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/GlobalTypes.java @@ -0,0 +1,10943 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/GlobalTypes.proto + +package org.xtreemfs.pbrpc.generatedinterfaces; + +public final class GlobalTypes { + private GlobalTypes() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + /** + * Protobuf enum {@code xtreemfs.pbrpc.AccessControlPolicyType} + * + *
    +   * Access control policy for a volume.
    +   * 
    + */ + public enum AccessControlPolicyType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * ACCESS_CONTROL_POLICY_NULL = 1; + * + *
    +     * No access control.
    +     * 
    + */ + ACCESS_CONTROL_POLICY_NULL(0, 1), + /** + * ACCESS_CONTROL_POLICY_POSIX = 2; + * + *
    +     * Regular POSIX permission and ACL-based access control.
    +     * 
    + */ + ACCESS_CONTROL_POLICY_POSIX(1, 2), + /** + * ACCESS_CONTROL_POLICY_VOLUME = 3; + * + *
    +     * Permissions per volume (instead of per directory),
    +     * faster since hierarchical evaluation is skipped.
    +     * 
    + */ + ACCESS_CONTROL_POLICY_VOLUME(2, 3), + ; + + /** + * ACCESS_CONTROL_POLICY_NULL = 1; + * + *
    +     * No access control.
    +     * 
    + */ + public static final int ACCESS_CONTROL_POLICY_NULL_VALUE = 1; + /** + * ACCESS_CONTROL_POLICY_POSIX = 2; + * + *
    +     * Regular POSIX permission and ACL-based access control.
    +     * 
    + */ + public static final int ACCESS_CONTROL_POLICY_POSIX_VALUE = 2; + /** + * ACCESS_CONTROL_POLICY_VOLUME = 3; + * + *
    +     * Permissions per volume (instead of per directory),
    +     * faster since hierarchical evaluation is skipped.
    +     * 
    + */ + public static final int ACCESS_CONTROL_POLICY_VOLUME_VALUE = 3; + + + public final int getNumber() { return value; } + + public static AccessControlPolicyType valueOf(int value) { + switch (value) { + case 1: return ACCESS_CONTROL_POLICY_NULL; + case 2: return ACCESS_CONTROL_POLICY_POSIX; + case 3: return ACCESS_CONTROL_POLICY_VOLUME; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public AccessControlPolicyType findValueByNumber(int number) { + return AccessControlPolicyType.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor().getEnumTypes().get(0); + } + + private static final AccessControlPolicyType[] VALUES = values(); + + public static AccessControlPolicyType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private AccessControlPolicyType(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.AccessControlPolicyType) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.OSDSelectionPolicyType} + * + *
    +   * Values for OSD (and Replica) selection policies.
    +   * 
    + */ + public enum OSDSelectionPolicyType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * OSD_SELECTION_POLICY_FILTER_DEFAULT = 1000; + * + *
    +     * Default filter.
    +     * 
    + */ + OSD_SELECTION_POLICY_FILTER_DEFAULT(0, 1000), + /** + * OSD_SELECTION_POLICY_FILTER_FQDN = 1001; + * + *
    +     * Filter based on the domain name (FQDN) of OSDs.
    +     * 
    + */ + OSD_SELECTION_POLICY_FILTER_FQDN(1, 1001), + /** + * OSD_SELECTION_POLICY_FILTER_UUID = 1002; + * + *
    +     * Filter based on the UUID of OSDs.
    +     * 
    + */ + OSD_SELECTION_POLICY_FILTER_UUID(2, 1002), + /** + * OSD_SELECTION_POLICY_GROUP_DCMAP = 2000; + * + *
    +     * Groups OSDs according to their location in the
    +     * datacenter map.
    +     * 
    + */ + OSD_SELECTION_POLICY_GROUP_DCMAP(3, 2000), + /** + * OSD_SELECTION_POLICY_GROUP_FQDN = 2001; + * + *
    +     * Groups OSDs accroding to their domain names.
    +     * 
    + */ + OSD_SELECTION_POLICY_GROUP_FQDN(4, 2001), + /** + * OSD_SELECTION_POLICY_SORT_DCMAP = 3000; + * + *
    +     * Sorts the OSDs by distance from client calculated
    +     * using the datacenter map.
    +     * 
    + */ + OSD_SELECTION_POLICY_SORT_DCMAP(5, 3000), + /** + * OSD_SELECTION_POLICY_SORT_FQDN = 3001; + * + *
    +     * Sorts the OSDs by longest postfix match of the FQDN
    +     * of OSD and client.
    +     * 
    + */ + OSD_SELECTION_POLICY_SORT_FQDN(6, 3001), + /** + * OSD_SELECTION_POLICY_SORT_RANDOM = 3002; + * + *
    +     * Random order.
    +     * 
    + */ + OSD_SELECTION_POLICY_SORT_RANDOM(7, 3002), + /** + * OSD_SELECTION_POLICY_SORT_VIVALDI = 3003; + * + *
    +     * Sorts the OSDs by proximity of vivalid network
    +     * coordinates of the client.
    +     * 
    + */ + OSD_SELECTION_POLICY_SORT_VIVALDI(8, 3003), + /** + * OSD_SELECTION_POLICY_SORT_HOST_ROUND_ROBIN = 3004; + * + *
    +     * Sorts the OSDs in a round robin manner for
    +     * multiple OSDs per host.
    +     * 
    + */ + OSD_SELECTION_POLICY_SORT_HOST_ROUND_ROBIN(9, 3004), + /** + * OSD_SELECTION_POLICY_SORT_UUID = 3998; + * + *
    +     * Sortes the OSDs by their UUID.
    +     * 
    + */ + OSD_SELECTION_POLICY_SORT_UUID(10, 3998), + /** + * OSD_SELECTION_POLICY_SORT_REVERSE = 3999; + * + *
    +     * Reverse given list. Used only internally by unit tests.
    +     * 
    + */ + OSD_SELECTION_POLICY_SORT_REVERSE(11, 3999), + ; + + /** + * OSD_SELECTION_POLICY_FILTER_DEFAULT = 1000; + * + *
    +     * Default filter.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_FILTER_DEFAULT_VALUE = 1000; + /** + * OSD_SELECTION_POLICY_FILTER_FQDN = 1001; + * + *
    +     * Filter based on the domain name (FQDN) of OSDs.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_FILTER_FQDN_VALUE = 1001; + /** + * OSD_SELECTION_POLICY_FILTER_UUID = 1002; + * + *
    +     * Filter based on the UUID of OSDs.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_FILTER_UUID_VALUE = 1002; + /** + * OSD_SELECTION_POLICY_GROUP_DCMAP = 2000; + * + *
    +     * Groups OSDs according to their location in the
    +     * datacenter map.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_GROUP_DCMAP_VALUE = 2000; + /** + * OSD_SELECTION_POLICY_GROUP_FQDN = 2001; + * + *
    +     * Groups OSDs accroding to their domain names.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_GROUP_FQDN_VALUE = 2001; + /** + * OSD_SELECTION_POLICY_SORT_DCMAP = 3000; + * + *
    +     * Sorts the OSDs by distance from client calculated
    +     * using the datacenter map.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_SORT_DCMAP_VALUE = 3000; + /** + * OSD_SELECTION_POLICY_SORT_FQDN = 3001; + * + *
    +     * Sorts the OSDs by longest postfix match of the FQDN
    +     * of OSD and client.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_SORT_FQDN_VALUE = 3001; + /** + * OSD_SELECTION_POLICY_SORT_RANDOM = 3002; + * + *
    +     * Random order.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_SORT_RANDOM_VALUE = 3002; + /** + * OSD_SELECTION_POLICY_SORT_VIVALDI = 3003; + * + *
    +     * Sorts the OSDs by proximity of vivalid network
    +     * coordinates of the client.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_SORT_VIVALDI_VALUE = 3003; + /** + * OSD_SELECTION_POLICY_SORT_HOST_ROUND_ROBIN = 3004; + * + *
    +     * Sorts the OSDs in a round robin manner for
    +     * multiple OSDs per host.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_SORT_HOST_ROUND_ROBIN_VALUE = 3004; + /** + * OSD_SELECTION_POLICY_SORT_UUID = 3998; + * + *
    +     * Sortes the OSDs by their UUID.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_SORT_UUID_VALUE = 3998; + /** + * OSD_SELECTION_POLICY_SORT_REVERSE = 3999; + * + *
    +     * Reverse given list. Used only internally by unit tests.
    +     * 
    + */ + public static final int OSD_SELECTION_POLICY_SORT_REVERSE_VALUE = 3999; + + + public final int getNumber() { return value; } + + public static OSDSelectionPolicyType valueOf(int value) { + switch (value) { + case 1000: return OSD_SELECTION_POLICY_FILTER_DEFAULT; + case 1001: return OSD_SELECTION_POLICY_FILTER_FQDN; + case 1002: return OSD_SELECTION_POLICY_FILTER_UUID; + case 2000: return OSD_SELECTION_POLICY_GROUP_DCMAP; + case 2001: return OSD_SELECTION_POLICY_GROUP_FQDN; + case 3000: return OSD_SELECTION_POLICY_SORT_DCMAP; + case 3001: return OSD_SELECTION_POLICY_SORT_FQDN; + case 3002: return OSD_SELECTION_POLICY_SORT_RANDOM; + case 3003: return OSD_SELECTION_POLICY_SORT_VIVALDI; + case 3004: return OSD_SELECTION_POLICY_SORT_HOST_ROUND_ROBIN; + case 3998: return OSD_SELECTION_POLICY_SORT_UUID; + case 3999: return OSD_SELECTION_POLICY_SORT_REVERSE; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public OSDSelectionPolicyType findValueByNumber(int number) { + return OSDSelectionPolicyType.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor().getEnumTypes().get(1); + } + + private static final OSDSelectionPolicyType[] VALUES = values(); + + public static OSDSelectionPolicyType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private OSDSelectionPolicyType(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.OSDSelectionPolicyType) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.ReplicaSelectionPolicyType} + */ + public enum ReplicaSelectionPolicyType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * REPLICA_SELECTION_POLICY_SIMPLE = 1; + */ + REPLICA_SELECTION_POLICY_SIMPLE(0, 1), + ; + + /** + * REPLICA_SELECTION_POLICY_SIMPLE = 1; + */ + public static final int REPLICA_SELECTION_POLICY_SIMPLE_VALUE = 1; + + + public final int getNumber() { return value; } + + public static ReplicaSelectionPolicyType valueOf(int value) { + switch (value) { + case 1: return REPLICA_SELECTION_POLICY_SIMPLE; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public ReplicaSelectionPolicyType findValueByNumber(int number) { + return ReplicaSelectionPolicyType.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor().getEnumTypes().get(2); + } + + private static final ReplicaSelectionPolicyType[] VALUES = values(); + + public static ReplicaSelectionPolicyType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private ReplicaSelectionPolicyType(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.ReplicaSelectionPolicyType) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.SnapConfig} + * + *
    +   * Configuration for file data snapshots.
    +   * 
    + */ + public enum SnapConfig + implements com.google.protobuf.ProtocolMessageEnum { + /** + * SNAP_CONFIG_SNAPS_DISABLED = 0; + * + *
    +     * Indicates that snapshots are disabled.
    +     * 
    + */ + SNAP_CONFIG_SNAPS_DISABLED(0, 0), + /** + * SNAP_CONFIG_ACCESS_CURRENT = 1; + * + *
    +     * Indicates access to the current version of a file.
    +     * 
    + */ + SNAP_CONFIG_ACCESS_CURRENT(1, 1), + /** + * SNAP_CONFIG_ACCESS_SNAP = 2; + * + *
    +     * Indicates access to a snapshot of a file.
    +     * 
    + */ + SNAP_CONFIG_ACCESS_SNAP(2, 2), + ; + + /** + * SNAP_CONFIG_SNAPS_DISABLED = 0; + * + *
    +     * Indicates that snapshots are disabled.
    +     * 
    + */ + public static final int SNAP_CONFIG_SNAPS_DISABLED_VALUE = 0; + /** + * SNAP_CONFIG_ACCESS_CURRENT = 1; + * + *
    +     * Indicates access to the current version of a file.
    +     * 
    + */ + public static final int SNAP_CONFIG_ACCESS_CURRENT_VALUE = 1; + /** + * SNAP_CONFIG_ACCESS_SNAP = 2; + * + *
    +     * Indicates access to a snapshot of a file.
    +     * 
    + */ + public static final int SNAP_CONFIG_ACCESS_SNAP_VALUE = 2; + + + public final int getNumber() { return value; } + + public static SnapConfig valueOf(int value) { + switch (value) { + case 0: return SNAP_CONFIG_SNAPS_DISABLED; + case 1: return SNAP_CONFIG_ACCESS_CURRENT; + case 2: return SNAP_CONFIG_ACCESS_SNAP; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public SnapConfig findValueByNumber(int number) { + return SnapConfig.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor().getEnumTypes().get(3); + } + + private static final SnapConfig[] VALUES = values(); + + public static SnapConfig valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private SnapConfig(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.SnapConfig) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.StripingPolicyType} + */ + public enum StripingPolicyType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * STRIPING_POLICY_RAID0 = 0; + * + *
    +     * Default striping policy (round-robin distribution).
    +     * 
    + */ + STRIPING_POLICY_RAID0(0, 0), + /** + * STRIPING_POLICY_ERASURECODE = 1; + * + *
    +     * Erasure code striping policy (.
    +     * 
    + */ + STRIPING_POLICY_ERASURECODE(1, 1), + ; + + /** + * STRIPING_POLICY_RAID0 = 0; + * + *
    +     * Default striping policy (round-robin distribution).
    +     * 
    + */ + public static final int STRIPING_POLICY_RAID0_VALUE = 0; + /** + * STRIPING_POLICY_ERASURECODE = 1; + * + *
    +     * Erasure code striping policy (.
    +     * 
    + */ + public static final int STRIPING_POLICY_ERASURECODE_VALUE = 1; + + + public final int getNumber() { return value; } + + public static StripingPolicyType valueOf(int value) { + switch (value) { + case 0: return STRIPING_POLICY_RAID0; + case 1: return STRIPING_POLICY_ERASURECODE; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public StripingPolicyType findValueByNumber(int number) { + return StripingPolicyType.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor().getEnumTypes().get(4); + } + + private static final StripingPolicyType[] VALUES = values(); + + public static StripingPolicyType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private StripingPolicyType(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.StripingPolicyType) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.LeaseState} + * + *
    +   * The LeaseState for a Replica.
    +   * 
    + */ + public enum LeaseState + implements com.google.protobuf.ProtocolMessageEnum { + /** + * NONE = 0; + * + *
    +     * The replica's update policy is not using lease.
    +     * 
    + */ + NONE(0, 0), + /** + * PRIMARY = 1; + * + *
    +     * The replica is the the primary.
    +     * 
    + */ + PRIMARY(1, 1), + /** + * BACKUP = 2; + * + *
    +     * The replica is a backup (and an active primary exists).
    +     * 
    + */ + BACKUP(2, 2), + /** + * IDLE = 3; + * + *
    +     * The replica is not active (currently no lease exists).
    +     * 
    + */ + IDLE(3, 3), + ; + + /** + * NONE = 0; + * + *
    +     * The replica's update policy is not using lease.
    +     * 
    + */ + public static final int NONE_VALUE = 0; + /** + * PRIMARY = 1; + * + *
    +     * The replica is the the primary.
    +     * 
    + */ + public static final int PRIMARY_VALUE = 1; + /** + * BACKUP = 2; + * + *
    +     * The replica is a backup (and an active primary exists).
    +     * 
    + */ + public static final int BACKUP_VALUE = 2; + /** + * IDLE = 3; + * + *
    +     * The replica is not active (currently no lease exists).
    +     * 
    + */ + public static final int IDLE_VALUE = 3; + + + public final int getNumber() { return value; } + + public static LeaseState valueOf(int value) { + switch (value) { + case 0: return NONE; + case 1: return PRIMARY; + case 2: return BACKUP; + case 3: return IDLE; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public LeaseState findValueByNumber(int number) { + return LeaseState.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor().getEnumTypes().get(5); + } + + private static final LeaseState[] VALUES = values(); + + public static LeaseState valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private LeaseState(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.LeaseState) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.PORTS} + * + *
    +   * TCP ports used by the services.
    +   * HTTP ports are used for the status pages.
    +   * 
    + */ + public enum PORTS + implements com.google.protobuf.ProtocolMessageEnum { + /** + * DIR_HTTP_PORT_DEFAULT = 30638; + */ + DIR_HTTP_PORT_DEFAULT(0, 30638), + /** + * DIR_PBRPC_PORT_DEFAULT = 32638; + */ + DIR_PBRPC_PORT_DEFAULT(1, 32638), + /** + * MRC_HTTP_PORT_DEFAULT = 30636; + */ + MRC_HTTP_PORT_DEFAULT(2, 30636), + /** + * MRC_PBRPC_PORT_DEFAULT = 32636; + */ + MRC_PBRPC_PORT_DEFAULT(3, 32636), + /** + * OSD_HTTP_PORT_DEFAULT = 30640; + */ + OSD_HTTP_PORT_DEFAULT(4, 30640), + /** + * OSD_PBRPC_PORT_DEFAULT = 32640; + */ + OSD_PBRPC_PORT_DEFAULT(5, 32640), + ; + + /** + * DIR_HTTP_PORT_DEFAULT = 30638; + */ + public static final int DIR_HTTP_PORT_DEFAULT_VALUE = 30638; + /** + * DIR_PBRPC_PORT_DEFAULT = 32638; + */ + public static final int DIR_PBRPC_PORT_DEFAULT_VALUE = 32638; + /** + * MRC_HTTP_PORT_DEFAULT = 30636; + */ + public static final int MRC_HTTP_PORT_DEFAULT_VALUE = 30636; + /** + * MRC_PBRPC_PORT_DEFAULT = 32636; + */ + public static final int MRC_PBRPC_PORT_DEFAULT_VALUE = 32636; + /** + * OSD_HTTP_PORT_DEFAULT = 30640; + */ + public static final int OSD_HTTP_PORT_DEFAULT_VALUE = 30640; + /** + * OSD_PBRPC_PORT_DEFAULT = 32640; + */ + public static final int OSD_PBRPC_PORT_DEFAULT_VALUE = 32640; + + + public final int getNumber() { return value; } + + public static PORTS valueOf(int value) { + switch (value) { + case 30638: return DIR_HTTP_PORT_DEFAULT; + case 32638: return DIR_PBRPC_PORT_DEFAULT; + case 30636: return MRC_HTTP_PORT_DEFAULT; + case 32636: return MRC_PBRPC_PORT_DEFAULT; + case 30640: return OSD_HTTP_PORT_DEFAULT; + case 32640: return OSD_PBRPC_PORT_DEFAULT; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public PORTS findValueByNumber(int number) { + return PORTS.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor().getEnumTypes().get(6); + } + + private static final PORTS[] VALUES = values(); + + public static PORTS valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private PORTS(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.PORTS) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.CONSTANTS} + * + *
    +   * Renew interval for clients.
    +   * 
    + */ + public enum CONSTANTS + implements com.google.protobuf.ProtocolMessageEnum { + /** + * XCAP_RENEW_INTERVAL_IN_MIN = 1; + */ + XCAP_RENEW_INTERVAL_IN_MIN(0, 1), + ; + + /** + * XCAP_RENEW_INTERVAL_IN_MIN = 1; + */ + public static final int XCAP_RENEW_INTERVAL_IN_MIN_VALUE = 1; + + + public final int getNumber() { return value; } + + public static CONSTANTS valueOf(int value) { + switch (value) { + case 1: return XCAP_RENEW_INTERVAL_IN_MIN; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public CONSTANTS findValueByNumber(int number) { + return CONSTANTS.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor().getEnumTypes().get(7); + } + + private static final CONSTANTS[] VALUES = values(); + + public static CONSTANTS valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private CONSTANTS(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.CONSTANTS) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.SYSTEM_V_FCNTL} + * + *
    +   * Flags for open command and access mode.
    +   * Values are Linux, might be different for other platforms!
    +   * 
    + */ + public enum SYSTEM_V_FCNTL + implements com.google.protobuf.ProtocolMessageEnum { + /** + * SYSTEM_V_FCNTL_H_O_RDONLY = 0; + */ + SYSTEM_V_FCNTL_H_O_RDONLY(0, 0), + /** + * SYSTEM_V_FCNTL_H_O_WRONLY = 1; + */ + SYSTEM_V_FCNTL_H_O_WRONLY(1, 1), + /** + * SYSTEM_V_FCNTL_H_O_RDWR = 2; + */ + SYSTEM_V_FCNTL_H_O_RDWR(2, 2), + /** + * SYSTEM_V_FCNTL_H_O_APPEND = 8; + */ + SYSTEM_V_FCNTL_H_O_APPEND(3, 8), + /** + * SYSTEM_V_FCNTL_H_O_CREAT = 256; + */ + SYSTEM_V_FCNTL_H_O_CREAT(4, 256), + /** + * SYSTEM_V_FCNTL_H_O_TRUNC = 512; + */ + SYSTEM_V_FCNTL_H_O_TRUNC(5, 512), + /** + * SYSTEM_V_FCNTL_H_O_EXCL = 1024; + */ + SYSTEM_V_FCNTL_H_O_EXCL(6, 1024), + /** + * SYSTEM_V_FCNTL_H_O_SYNC = 16; + */ + SYSTEM_V_FCNTL_H_O_SYNC(7, 16), + /** + * SYSTEM_V_FCNTL_H_S_IFREG = 32768; + */ + SYSTEM_V_FCNTL_H_S_IFREG(8, 32768), + /** + * SYSTEM_V_FCNTL_H_S_IFDIR = 16384; + */ + SYSTEM_V_FCNTL_H_S_IFDIR(9, 16384), + /** + * SYSTEM_V_FCNTL_H_S_IFLNK = 40960; + */ + SYSTEM_V_FCNTL_H_S_IFLNK(10, 40960), + /** + * SYSTEM_V_FCNTL_H_S_IFIFO = 4096; + */ + SYSTEM_V_FCNTL_H_S_IFIFO(11, 4096), + ; + + /** + * SYSTEM_V_FCNTL_H_O_RDONLY = 0; + */ + public static final int SYSTEM_V_FCNTL_H_O_RDONLY_VALUE = 0; + /** + * SYSTEM_V_FCNTL_H_O_WRONLY = 1; + */ + public static final int SYSTEM_V_FCNTL_H_O_WRONLY_VALUE = 1; + /** + * SYSTEM_V_FCNTL_H_O_RDWR = 2; + */ + public static final int SYSTEM_V_FCNTL_H_O_RDWR_VALUE = 2; + /** + * SYSTEM_V_FCNTL_H_O_APPEND = 8; + */ + public static final int SYSTEM_V_FCNTL_H_O_APPEND_VALUE = 8; + /** + * SYSTEM_V_FCNTL_H_O_CREAT = 256; + */ + public static final int SYSTEM_V_FCNTL_H_O_CREAT_VALUE = 256; + /** + * SYSTEM_V_FCNTL_H_O_TRUNC = 512; + */ + public static final int SYSTEM_V_FCNTL_H_O_TRUNC_VALUE = 512; + /** + * SYSTEM_V_FCNTL_H_O_EXCL = 1024; + */ + public static final int SYSTEM_V_FCNTL_H_O_EXCL_VALUE = 1024; + /** + * SYSTEM_V_FCNTL_H_O_SYNC = 16; + */ + public static final int SYSTEM_V_FCNTL_H_O_SYNC_VALUE = 16; + /** + * SYSTEM_V_FCNTL_H_S_IFREG = 32768; + */ + public static final int SYSTEM_V_FCNTL_H_S_IFREG_VALUE = 32768; + /** + * SYSTEM_V_FCNTL_H_S_IFDIR = 16384; + */ + public static final int SYSTEM_V_FCNTL_H_S_IFDIR_VALUE = 16384; + /** + * SYSTEM_V_FCNTL_H_S_IFLNK = 40960; + */ + public static final int SYSTEM_V_FCNTL_H_S_IFLNK_VALUE = 40960; + /** + * SYSTEM_V_FCNTL_H_S_IFIFO = 4096; + */ + public static final int SYSTEM_V_FCNTL_H_S_IFIFO_VALUE = 4096; + + + public final int getNumber() { return value; } + + public static SYSTEM_V_FCNTL valueOf(int value) { + switch (value) { + case 0: return SYSTEM_V_FCNTL_H_O_RDONLY; + case 1: return SYSTEM_V_FCNTL_H_O_WRONLY; + case 2: return SYSTEM_V_FCNTL_H_O_RDWR; + case 8: return SYSTEM_V_FCNTL_H_O_APPEND; + case 256: return SYSTEM_V_FCNTL_H_O_CREAT; + case 512: return SYSTEM_V_FCNTL_H_O_TRUNC; + case 1024: return SYSTEM_V_FCNTL_H_O_EXCL; + case 16: return SYSTEM_V_FCNTL_H_O_SYNC; + case 32768: return SYSTEM_V_FCNTL_H_S_IFREG; + case 16384: return SYSTEM_V_FCNTL_H_S_IFDIR; + case 40960: return SYSTEM_V_FCNTL_H_S_IFLNK; + case 4096: return SYSTEM_V_FCNTL_H_S_IFIFO; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public SYSTEM_V_FCNTL findValueByNumber(int number) { + return SYSTEM_V_FCNTL.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor().getEnumTypes().get(8); + } + + private static final SYSTEM_V_FCNTL[] VALUES = values(); + + public static SYSTEM_V_FCNTL valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private SYSTEM_V_FCNTL(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.SYSTEM_V_FCNTL) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.REPL_FLAG} + * + *
    +   * Flags for replication, multiple flags can be
    +   * OR'ed.
    +   * 
    + */ + public enum REPL_FLAG + implements com.google.protobuf.ProtocolMessageEnum { + /** + * REPL_FLAG_FULL_REPLICA = 1; + */ + REPL_FLAG_FULL_REPLICA(0, 1), + /** + * REPL_FLAG_IS_COMPLETE = 2; + */ + REPL_FLAG_IS_COMPLETE(1, 2), + /** + * REPL_FLAG_STRATEGY_RANDOM = 4; + */ + REPL_FLAG_STRATEGY_RANDOM(2, 4), + /** + * REPL_FLAG_STRATEGY_RAREST_FIRST = 8; + */ + REPL_FLAG_STRATEGY_RAREST_FIRST(3, 8), + /** + * REPL_FLAG_STRATEGY_SEQUENTIAL = 16; + */ + REPL_FLAG_STRATEGY_SEQUENTIAL(4, 16), + /** + * REPL_FLAG_STRATEGY_SEQUENTIAL_PREFETCHING = 32; + */ + REPL_FLAG_STRATEGY_SEQUENTIAL_PREFETCHING(5, 32), + ; + + /** + * REPL_FLAG_FULL_REPLICA = 1; + */ + public static final int REPL_FLAG_FULL_REPLICA_VALUE = 1; + /** + * REPL_FLAG_IS_COMPLETE = 2; + */ + public static final int REPL_FLAG_IS_COMPLETE_VALUE = 2; + /** + * REPL_FLAG_STRATEGY_RANDOM = 4; + */ + public static final int REPL_FLAG_STRATEGY_RANDOM_VALUE = 4; + /** + * REPL_FLAG_STRATEGY_RAREST_FIRST = 8; + */ + public static final int REPL_FLAG_STRATEGY_RAREST_FIRST_VALUE = 8; + /** + * REPL_FLAG_STRATEGY_SEQUENTIAL = 16; + */ + public static final int REPL_FLAG_STRATEGY_SEQUENTIAL_VALUE = 16; + /** + * REPL_FLAG_STRATEGY_SEQUENTIAL_PREFETCHING = 32; + */ + public static final int REPL_FLAG_STRATEGY_SEQUENTIAL_PREFETCHING_VALUE = 32; + + + public final int getNumber() { return value; } + + public static REPL_FLAG valueOf(int value) { + switch (value) { + case 1: return REPL_FLAG_FULL_REPLICA; + case 2: return REPL_FLAG_IS_COMPLETE; + case 4: return REPL_FLAG_STRATEGY_RANDOM; + case 8: return REPL_FLAG_STRATEGY_RAREST_FIRST; + case 16: return REPL_FLAG_STRATEGY_SEQUENTIAL; + case 32: return REPL_FLAG_STRATEGY_SEQUENTIAL_PREFETCHING; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public REPL_FLAG findValueByNumber(int number) { + return REPL_FLAG.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor().getEnumTypes().get(9); + } + + private static final REPL_FLAG[] VALUES = values(); + + public static REPL_FLAG valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private REPL_FLAG(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.REPL_FLAG) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.SERVICES} + */ + public enum SERVICES + implements com.google.protobuf.ProtocolMessageEnum { + /** + * DIR = 1; + */ + DIR(0, 1), + /** + * MRC = 2; + */ + MRC(1, 2), + /** + * OSD = 3; + */ + OSD(2, 3), + ; + + /** + * DIR = 1; + */ + public static final int DIR_VALUE = 1; + /** + * MRC = 2; + */ + public static final int MRC_VALUE = 2; + /** + * OSD = 3; + */ + public static final int OSD_VALUE = 3; + + + public final int getNumber() { return value; } + + public static SERVICES valueOf(int value) { + switch (value) { + case 1: return DIR; + case 2: return MRC; + case 3: return OSD; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public SERVICES findValueByNumber(int number) { + return SERVICES.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor().getEnumTypes().get(10); + } + + private static final SERVICES[] VALUES = values(); + + public static SERVICES valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private SERVICES(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.SERVICES) + } + + public interface NewFileSizeOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 size_in_bytes = 1; + /** + * required fixed64 size_in_bytes = 1; + * + *
    +     * New file size in bytes.
    +     * 
    + */ + boolean hasSizeInBytes(); + /** + * required fixed64 size_in_bytes = 1; + * + *
    +     * New file size in bytes.
    +     * 
    + */ + long getSizeInBytes(); + + // required fixed32 truncate_epoch = 2; + /** + * required fixed32 truncate_epoch = 2; + * + *
    +     * Truncate epoch to sort file size updates.
    +     * 
    + */ + boolean hasTruncateEpoch(); + /** + * required fixed32 truncate_epoch = 2; + * + *
    +     * Truncate epoch to sort file size updates.
    +     * 
    + */ + int getTruncateEpoch(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.NewFileSize} + * + *
    +   * File size update data sent by OSDs.
    +   * 
    + */ + public static final class NewFileSize extends + com.google.protobuf.GeneratedMessage + implements NewFileSizeOrBuilder { + // Use NewFileSize.newBuilder() to construct. + private NewFileSize(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private NewFileSize(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final NewFileSize defaultInstance; + public static NewFileSize getDefaultInstance() { + return defaultInstance; + } + + public NewFileSize getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private NewFileSize( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + sizeInBytes_ = input.readFixed64(); + break; + } + case 21: { + bitField0_ |= 0x00000002; + truncateEpoch_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_NewFileSize_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_NewFileSize_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public NewFileSize parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new NewFileSize(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 size_in_bytes = 1; + public static final int SIZE_IN_BYTES_FIELD_NUMBER = 1; + private long sizeInBytes_; + /** + * required fixed64 size_in_bytes = 1; + * + *
    +     * New file size in bytes.
    +     * 
    + */ + public boolean hasSizeInBytes() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 size_in_bytes = 1; + * + *
    +     * New file size in bytes.
    +     * 
    + */ + public long getSizeInBytes() { + return sizeInBytes_; + } + + // required fixed32 truncate_epoch = 2; + public static final int TRUNCATE_EPOCH_FIELD_NUMBER = 2; + private int truncateEpoch_; + /** + * required fixed32 truncate_epoch = 2; + * + *
    +     * Truncate epoch to sort file size updates.
    +     * 
    + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 truncate_epoch = 2; + * + *
    +     * Truncate epoch to sort file size updates.
    +     * 
    + */ + public int getTruncateEpoch() { + return truncateEpoch_; + } + + private void initFields() { + sizeInBytes_ = 0L; + truncateEpoch_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasSizeInBytes()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTruncateEpoch()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, sizeInBytes_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed32(2, truncateEpoch_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, sizeInBytes_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(2, truncateEpoch_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.NewFileSize} + * + *
    +     * File size update data sent by OSDs.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSizeOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_NewFileSize_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_NewFileSize_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + sizeInBytes_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + truncateEpoch_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_NewFileSize_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize build() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize result = new org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.sizeInBytes_ = sizeInBytes_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.truncateEpoch_ = truncateEpoch_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize.getDefaultInstance()) return this; + if (other.hasSizeInBytes()) { + setSizeInBytes(other.getSizeInBytes()); + } + if (other.hasTruncateEpoch()) { + setTruncateEpoch(other.getTruncateEpoch()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasSizeInBytes()) { + + return false; + } + if (!hasTruncateEpoch()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.NewFileSize) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 size_in_bytes = 1; + private long sizeInBytes_ ; + /** + * required fixed64 size_in_bytes = 1; + * + *
    +       * New file size in bytes.
    +       * 
    + */ + public boolean hasSizeInBytes() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 size_in_bytes = 1; + * + *
    +       * New file size in bytes.
    +       * 
    + */ + public long getSizeInBytes() { + return sizeInBytes_; + } + /** + * required fixed64 size_in_bytes = 1; + * + *
    +       * New file size in bytes.
    +       * 
    + */ + public Builder setSizeInBytes(long value) { + bitField0_ |= 0x00000001; + sizeInBytes_ = value; + onChanged(); + return this; + } + /** + * required fixed64 size_in_bytes = 1; + * + *
    +       * New file size in bytes.
    +       * 
    + */ + public Builder clearSizeInBytes() { + bitField0_ = (bitField0_ & ~0x00000001); + sizeInBytes_ = 0L; + onChanged(); + return this; + } + + // required fixed32 truncate_epoch = 2; + private int truncateEpoch_ ; + /** + * required fixed32 truncate_epoch = 2; + * + *
    +       * Truncate epoch to sort file size updates.
    +       * 
    + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 truncate_epoch = 2; + * + *
    +       * Truncate epoch to sort file size updates.
    +       * 
    + */ + public int getTruncateEpoch() { + return truncateEpoch_; + } + /** + * required fixed32 truncate_epoch = 2; + * + *
    +       * Truncate epoch to sort file size updates.
    +       * 
    + */ + public Builder setTruncateEpoch(int value) { + bitField0_ |= 0x00000002; + truncateEpoch_ = value; + onChanged(); + return this; + } + /** + * required fixed32 truncate_epoch = 2; + * + *
    +       * Truncate epoch to sort file size updates.
    +       * 
    + */ + public Builder clearTruncateEpoch() { + bitField0_ = (bitField0_ & ~0x00000002); + truncateEpoch_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.NewFileSize) + } + + static { + defaultInstance = new NewFileSize(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.NewFileSize) + } + + public interface StripingPolicyOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.StripingPolicyType type = 1; + /** + * required .xtreemfs.pbrpc.StripingPolicyType type = 1; + * + *
    +     * Type (by default STRIPING_POLICY_RAID0).
    +     * 
    + */ + boolean hasType(); + /** + * required .xtreemfs.pbrpc.StripingPolicyType type = 1; + * + *
    +     * Type (by default STRIPING_POLICY_RAID0).
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType getType(); + + // required fixed32 stripe_size = 2; + /** + * required fixed32 stripe_size = 2; + * + *
    +     * Size of a single chunk (object) in *kB*!
    +     * The name of the field is wrong: This is not the total size of the stripe.
    +     * Instead, the total size of a stripe in XtreemFS is: stripe_size * (width + parity_width)
    +     * 
    + */ + boolean hasStripeSize(); + /** + * required fixed32 stripe_size = 2; + * + *
    +     * Size of a single chunk (object) in *kB*!
    +     * The name of the field is wrong: This is not the total size of the stripe.
    +     * Instead, the total size of a stripe in XtreemFS is: stripe_size * (width + parity_width)
    +     * 
    + */ + int getStripeSize(); + + // required fixed32 width = 3; + /** + * required fixed32 width = 3; + * + *
    +     * Number of OSDs to distribute data chunks on.
    +     * 
    + */ + boolean hasWidth(); + /** + * required fixed32 width = 3; + * + *
    +     * Number of OSDs to distribute data chunks on.
    +     * 
    + */ + int getWidth(); + + // optional fixed32 parity_width = 4; + /** + * optional fixed32 parity_width = 4; + * + *
    +     * Number of OSDs to distribute parity chunks on.
    +     * 
    + */ + boolean hasParityWidth(); + /** + * optional fixed32 parity_width = 4; + * + *
    +     * Number of OSDs to distribute parity chunks on.
    +     * 
    + */ + int getParityWidth(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.StripingPolicy} + */ + public static final class StripingPolicy extends + com.google.protobuf.GeneratedMessage + implements StripingPolicyOrBuilder { + // Use StripingPolicy.newBuilder() to construct. + private StripingPolicy(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private StripingPolicy(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final StripingPolicy defaultInstance; + public static StripingPolicy getDefaultInstance() { + return defaultInstance; + } + + public StripingPolicy getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private StripingPolicy( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + int rawValue = input.readEnum(); + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType value = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(1, rawValue); + } else { + bitField0_ |= 0x00000001; + type_ = value; + } + break; + } + case 21: { + bitField0_ |= 0x00000002; + stripeSize_ = input.readFixed32(); + break; + } + case 29: { + bitField0_ |= 0x00000004; + width_ = input.readFixed32(); + break; + } + case 37: { + bitField0_ |= 0x00000008; + parityWidth_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_StripingPolicy_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_StripingPolicy_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public StripingPolicy parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new StripingPolicy(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.StripingPolicyType type = 1; + public static final int TYPE_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType type_; + /** + * required .xtreemfs.pbrpc.StripingPolicyType type = 1; + * + *
    +     * Type (by default STRIPING_POLICY_RAID0).
    +     * 
    + */ + public boolean hasType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.StripingPolicyType type = 1; + * + *
    +     * Type (by default STRIPING_POLICY_RAID0).
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType getType() { + return type_; + } + + // required fixed32 stripe_size = 2; + public static final int STRIPE_SIZE_FIELD_NUMBER = 2; + private int stripeSize_; + /** + * required fixed32 stripe_size = 2; + * + *
    +     * Size of a single chunk (object) in *kB*!
    +     * The name of the field is wrong: This is not the total size of the stripe.
    +     * Instead, the total size of a stripe in XtreemFS is: stripe_size * (width + parity_width)
    +     * 
    + */ + public boolean hasStripeSize() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 stripe_size = 2; + * + *
    +     * Size of a single chunk (object) in *kB*!
    +     * The name of the field is wrong: This is not the total size of the stripe.
    +     * Instead, the total size of a stripe in XtreemFS is: stripe_size * (width + parity_width)
    +     * 
    + */ + public int getStripeSize() { + return stripeSize_; + } + + // required fixed32 width = 3; + public static final int WIDTH_FIELD_NUMBER = 3; + private int width_; + /** + * required fixed32 width = 3; + * + *
    +     * Number of OSDs to distribute data chunks on.
    +     * 
    + */ + public boolean hasWidth() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 width = 3; + * + *
    +     * Number of OSDs to distribute data chunks on.
    +     * 
    + */ + public int getWidth() { + return width_; + } + + // optional fixed32 parity_width = 4; + public static final int PARITY_WIDTH_FIELD_NUMBER = 4; + private int parityWidth_; + /** + * optional fixed32 parity_width = 4; + * + *
    +     * Number of OSDs to distribute parity chunks on.
    +     * 
    + */ + public boolean hasParityWidth() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional fixed32 parity_width = 4; + * + *
    +     * Number of OSDs to distribute parity chunks on.
    +     * 
    + */ + public int getParityWidth() { + return parityWidth_; + } + + private void initFields() { + type_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType.STRIPING_POLICY_RAID0; + stripeSize_ = 0; + width_ = 0; + parityWidth_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasType()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasStripeSize()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasWidth()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeEnum(1, type_.getNumber()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed32(2, stripeSize_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed32(3, width_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed32(4, parityWidth_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(1, type_.getNumber()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(2, stripeSize_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(3, width_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(4, parityWidth_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.StripingPolicy} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_StripingPolicy_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_StripingPolicy_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + type_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType.STRIPING_POLICY_RAID0; + bitField0_ = (bitField0_ & ~0x00000001); + stripeSize_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + width_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + parityWidth_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_StripingPolicy_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy build() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy result = new org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.type_ = type_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.stripeSize_ = stripeSize_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.width_ = width_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.parityWidth_ = parityWidth_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance()) return this; + if (other.hasType()) { + setType(other.getType()); + } + if (other.hasStripeSize()) { + setStripeSize(other.getStripeSize()); + } + if (other.hasWidth()) { + setWidth(other.getWidth()); + } + if (other.hasParityWidth()) { + setParityWidth(other.getParityWidth()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasType()) { + + return false; + } + if (!hasStripeSize()) { + + return false; + } + if (!hasWidth()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.StripingPolicyType type = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType type_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType.STRIPING_POLICY_RAID0; + /** + * required .xtreemfs.pbrpc.StripingPolicyType type = 1; + * + *
    +       * Type (by default STRIPING_POLICY_RAID0).
    +       * 
    + */ + public boolean hasType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.StripingPolicyType type = 1; + * + *
    +       * Type (by default STRIPING_POLICY_RAID0).
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType getType() { + return type_; + } + /** + * required .xtreemfs.pbrpc.StripingPolicyType type = 1; + * + *
    +       * Type (by default STRIPING_POLICY_RAID0).
    +       * 
    + */ + public Builder setType(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + type_ = value; + onChanged(); + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicyType type = 1; + * + *
    +       * Type (by default STRIPING_POLICY_RAID0).
    +       * 
    + */ + public Builder clearType() { + bitField0_ = (bitField0_ & ~0x00000001); + type_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType.STRIPING_POLICY_RAID0; + onChanged(); + return this; + } + + // required fixed32 stripe_size = 2; + private int stripeSize_ ; + /** + * required fixed32 stripe_size = 2; + * + *
    +       * Size of a single chunk (object) in *kB*!
    +       * The name of the field is wrong: This is not the total size of the stripe.
    +       * Instead, the total size of a stripe in XtreemFS is: stripe_size * (width + parity_width)
    +       * 
    + */ + public boolean hasStripeSize() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 stripe_size = 2; + * + *
    +       * Size of a single chunk (object) in *kB*!
    +       * The name of the field is wrong: This is not the total size of the stripe.
    +       * Instead, the total size of a stripe in XtreemFS is: stripe_size * (width + parity_width)
    +       * 
    + */ + public int getStripeSize() { + return stripeSize_; + } + /** + * required fixed32 stripe_size = 2; + * + *
    +       * Size of a single chunk (object) in *kB*!
    +       * The name of the field is wrong: This is not the total size of the stripe.
    +       * Instead, the total size of a stripe in XtreemFS is: stripe_size * (width + parity_width)
    +       * 
    + */ + public Builder setStripeSize(int value) { + bitField0_ |= 0x00000002; + stripeSize_ = value; + onChanged(); + return this; + } + /** + * required fixed32 stripe_size = 2; + * + *
    +       * Size of a single chunk (object) in *kB*!
    +       * The name of the field is wrong: This is not the total size of the stripe.
    +       * Instead, the total size of a stripe in XtreemFS is: stripe_size * (width + parity_width)
    +       * 
    + */ + public Builder clearStripeSize() { + bitField0_ = (bitField0_ & ~0x00000002); + stripeSize_ = 0; + onChanged(); + return this; + } + + // required fixed32 width = 3; + private int width_ ; + /** + * required fixed32 width = 3; + * + *
    +       * Number of OSDs to distribute data chunks on.
    +       * 
    + */ + public boolean hasWidth() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 width = 3; + * + *
    +       * Number of OSDs to distribute data chunks on.
    +       * 
    + */ + public int getWidth() { + return width_; + } + /** + * required fixed32 width = 3; + * + *
    +       * Number of OSDs to distribute data chunks on.
    +       * 
    + */ + public Builder setWidth(int value) { + bitField0_ |= 0x00000004; + width_ = value; + onChanged(); + return this; + } + /** + * required fixed32 width = 3; + * + *
    +       * Number of OSDs to distribute data chunks on.
    +       * 
    + */ + public Builder clearWidth() { + bitField0_ = (bitField0_ & ~0x00000004); + width_ = 0; + onChanged(); + return this; + } + + // optional fixed32 parity_width = 4; + private int parityWidth_ ; + /** + * optional fixed32 parity_width = 4; + * + *
    +       * Number of OSDs to distribute parity chunks on.
    +       * 
    + */ + public boolean hasParityWidth() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional fixed32 parity_width = 4; + * + *
    +       * Number of OSDs to distribute parity chunks on.
    +       * 
    + */ + public int getParityWidth() { + return parityWidth_; + } + /** + * optional fixed32 parity_width = 4; + * + *
    +       * Number of OSDs to distribute parity chunks on.
    +       * 
    + */ + public Builder setParityWidth(int value) { + bitField0_ |= 0x00000008; + parityWidth_ = value; + onChanged(); + return this; + } + /** + * optional fixed32 parity_width = 4; + * + *
    +       * Number of OSDs to distribute parity chunks on.
    +       * 
    + */ + public Builder clearParityWidth() { + bitField0_ = (bitField0_ & ~0x00000008); + parityWidth_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.StripingPolicy) + } + + static { + defaultInstance = new StripingPolicy(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.StripingPolicy) + } + + public interface ReplicaOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated string osd_uuids = 1; + /** + * repeated string osd_uuids = 1; + * + *
    +     * UUIDs of OSDs to store objects on.
    +     * Length of this list must be equal to width
    +     * in striping_policy!
    +     * 
    + */ + java.util.List + getOsdUuidsList(); + /** + * repeated string osd_uuids = 1; + * + *
    +     * UUIDs of OSDs to store objects on.
    +     * Length of this list must be equal to width
    +     * in striping_policy!
    +     * 
    + */ + int getOsdUuidsCount(); + /** + * repeated string osd_uuids = 1; + * + *
    +     * UUIDs of OSDs to store objects on.
    +     * Length of this list must be equal to width
    +     * in striping_policy!
    +     * 
    + */ + java.lang.String getOsdUuids(int index); + /** + * repeated string osd_uuids = 1; + * + *
    +     * UUIDs of OSDs to store objects on.
    +     * Length of this list must be equal to width
    +     * in striping_policy!
    +     * 
    + */ + com.google.protobuf.ByteString + getOsdUuidsBytes(int index); + + // required fixed32 replication_flags = 2; + /** + * required fixed32 replication_flags = 2; + * + *
    +     * Flags to control replication, e.g. transfer strategy.
    +     * 
    + */ + boolean hasReplicationFlags(); + /** + * required fixed32 replication_flags = 2; + * + *
    +     * Flags to control replication, e.g. transfer strategy.
    +     * 
    + */ + int getReplicationFlags(); + + // required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +     * Striping policy for this replica.
    +     * 
    + */ + boolean hasStripingPolicy(); + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +     * Striping policy for this replica.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy getStripingPolicy(); + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +     * Striping policy for this replica.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder getStripingPolicyOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Replica} + * + *
    +   * Details for a file replica.
    +   * 
    + */ + public static final class Replica extends + com.google.protobuf.GeneratedMessage + implements ReplicaOrBuilder { + // Use Replica.newBuilder() to construct. + private Replica(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Replica(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Replica defaultInstance; + public static Replica getDefaultInstance() { + return defaultInstance; + } + + public Replica getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Replica( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + osdUuids_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000001; + } + osdUuids_.add(input.readBytes()); + break; + } + case 21: { + bitField0_ |= 0x00000001; + replicationFlags_ = input.readFixed32(); + break; + } + case 26: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = stripingPolicy_.toBuilder(); + } + stripingPolicy_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(stripingPolicy_); + stripingPolicy_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + osdUuids_ = new com.google.protobuf.UnmodifiableLazyStringList(osdUuids_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_Replica_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_Replica_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Replica parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Replica(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // repeated string osd_uuids = 1; + public static final int OSD_UUIDS_FIELD_NUMBER = 1; + private com.google.protobuf.LazyStringList osdUuids_; + /** + * repeated string osd_uuids = 1; + * + *
    +     * UUIDs of OSDs to store objects on.
    +     * Length of this list must be equal to width
    +     * in striping_policy!
    +     * 
    + */ + public java.util.List + getOsdUuidsList() { + return osdUuids_; + } + /** + * repeated string osd_uuids = 1; + * + *
    +     * UUIDs of OSDs to store objects on.
    +     * Length of this list must be equal to width
    +     * in striping_policy!
    +     * 
    + */ + public int getOsdUuidsCount() { + return osdUuids_.size(); + } + /** + * repeated string osd_uuids = 1; + * + *
    +     * UUIDs of OSDs to store objects on.
    +     * Length of this list must be equal to width
    +     * in striping_policy!
    +     * 
    + */ + public java.lang.String getOsdUuids(int index) { + return osdUuids_.get(index); + } + /** + * repeated string osd_uuids = 1; + * + *
    +     * UUIDs of OSDs to store objects on.
    +     * Length of this list must be equal to width
    +     * in striping_policy!
    +     * 
    + */ + public com.google.protobuf.ByteString + getOsdUuidsBytes(int index) { + return osdUuids_.getByteString(index); + } + + // required fixed32 replication_flags = 2; + public static final int REPLICATION_FLAGS_FIELD_NUMBER = 2; + private int replicationFlags_; + /** + * required fixed32 replication_flags = 2; + * + *
    +     * Flags to control replication, e.g. transfer strategy.
    +     * 
    + */ + public boolean hasReplicationFlags() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 replication_flags = 2; + * + *
    +     * Flags to control replication, e.g. transfer strategy.
    +     * 
    + */ + public int getReplicationFlags() { + return replicationFlags_; + } + + // required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + public static final int STRIPING_POLICY_FIELD_NUMBER = 3; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy stripingPolicy_; + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +     * Striping policy for this replica.
    +     * 
    + */ + public boolean hasStripingPolicy() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +     * Striping policy for this replica.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy getStripingPolicy() { + return stripingPolicy_; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +     * Striping policy for this replica.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder getStripingPolicyOrBuilder() { + return stripingPolicy_; + } + + private void initFields() { + osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + replicationFlags_ = 0; + stripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasReplicationFlags()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasStripingPolicy()) { + memoizedIsInitialized = 0; + return false; + } + if (!getStripingPolicy().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < osdUuids_.size(); i++) { + output.writeBytes(1, osdUuids_.getByteString(i)); + } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed32(2, replicationFlags_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(3, stripingPolicy_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < osdUuids_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(osdUuids_.getByteString(i)); + } + size += dataSize; + size += 1 * getOsdUuidsList().size(); + } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(2, replicationFlags_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, stripingPolicy_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Replica} + * + *
    +     * Details for a file replica.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_Replica_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_Replica_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getStripingPolicyFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + replicationFlags_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + if (stripingPolicyBuilder_ == null) { + stripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + } else { + stripingPolicyBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_Replica_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica build() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica result = new org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + osdUuids_ = new com.google.protobuf.UnmodifiableLazyStringList( + osdUuids_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.osdUuids_ = osdUuids_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000001; + } + result.replicationFlags_ = replicationFlags_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000002; + } + if (stripingPolicyBuilder_ == null) { + result.stripingPolicy_ = stripingPolicy_; + } else { + result.stripingPolicy_ = stripingPolicyBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.getDefaultInstance()) return this; + if (!other.osdUuids_.isEmpty()) { + if (osdUuids_.isEmpty()) { + osdUuids_ = other.osdUuids_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureOsdUuidsIsMutable(); + osdUuids_.addAll(other.osdUuids_); + } + onChanged(); + } + if (other.hasReplicationFlags()) { + setReplicationFlags(other.getReplicationFlags()); + } + if (other.hasStripingPolicy()) { + mergeStripingPolicy(other.getStripingPolicy()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasReplicationFlags()) { + + return false; + } + if (!hasStripingPolicy()) { + + return false; + } + if (!getStripingPolicy().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated string osd_uuids = 1; + private com.google.protobuf.LazyStringList osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureOsdUuidsIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + osdUuids_ = new com.google.protobuf.LazyStringArrayList(osdUuids_); + bitField0_ |= 0x00000001; + } + } + /** + * repeated string osd_uuids = 1; + * + *
    +       * UUIDs of OSDs to store objects on.
    +       * Length of this list must be equal to width
    +       * in striping_policy!
    +       * 
    + */ + public java.util.List + getOsdUuidsList() { + return java.util.Collections.unmodifiableList(osdUuids_); + } + /** + * repeated string osd_uuids = 1; + * + *
    +       * UUIDs of OSDs to store objects on.
    +       * Length of this list must be equal to width
    +       * in striping_policy!
    +       * 
    + */ + public int getOsdUuidsCount() { + return osdUuids_.size(); + } + /** + * repeated string osd_uuids = 1; + * + *
    +       * UUIDs of OSDs to store objects on.
    +       * Length of this list must be equal to width
    +       * in striping_policy!
    +       * 
    + */ + public java.lang.String getOsdUuids(int index) { + return osdUuids_.get(index); + } + /** + * repeated string osd_uuids = 1; + * + *
    +       * UUIDs of OSDs to store objects on.
    +       * Length of this list must be equal to width
    +       * in striping_policy!
    +       * 
    + */ + public com.google.protobuf.ByteString + getOsdUuidsBytes(int index) { + return osdUuids_.getByteString(index); + } + /** + * repeated string osd_uuids = 1; + * + *
    +       * UUIDs of OSDs to store objects on.
    +       * Length of this list must be equal to width
    +       * in striping_policy!
    +       * 
    + */ + public Builder setOsdUuids( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureOsdUuidsIsMutable(); + osdUuids_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 1; + * + *
    +       * UUIDs of OSDs to store objects on.
    +       * Length of this list must be equal to width
    +       * in striping_policy!
    +       * 
    + */ + public Builder addOsdUuids( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureOsdUuidsIsMutable(); + osdUuids_.add(value); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 1; + * + *
    +       * UUIDs of OSDs to store objects on.
    +       * Length of this list must be equal to width
    +       * in striping_policy!
    +       * 
    + */ + public Builder addAllOsdUuids( + java.lang.Iterable values) { + ensureOsdUuidsIsMutable(); + super.addAll(values, osdUuids_); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 1; + * + *
    +       * UUIDs of OSDs to store objects on.
    +       * Length of this list must be equal to width
    +       * in striping_policy!
    +       * 
    + */ + public Builder clearOsdUuids() { + osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 1; + * + *
    +       * UUIDs of OSDs to store objects on.
    +       * Length of this list must be equal to width
    +       * in striping_policy!
    +       * 
    + */ + public Builder addOsdUuidsBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureOsdUuidsIsMutable(); + osdUuids_.add(value); + onChanged(); + return this; + } + + // required fixed32 replication_flags = 2; + private int replicationFlags_ ; + /** + * required fixed32 replication_flags = 2; + * + *
    +       * Flags to control replication, e.g. transfer strategy.
    +       * 
    + */ + public boolean hasReplicationFlags() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 replication_flags = 2; + * + *
    +       * Flags to control replication, e.g. transfer strategy.
    +       * 
    + */ + public int getReplicationFlags() { + return replicationFlags_; + } + /** + * required fixed32 replication_flags = 2; + * + *
    +       * Flags to control replication, e.g. transfer strategy.
    +       * 
    + */ + public Builder setReplicationFlags(int value) { + bitField0_ |= 0x00000002; + replicationFlags_ = value; + onChanged(); + return this; + } + /** + * required fixed32 replication_flags = 2; + * + *
    +       * Flags to control replication, e.g. transfer strategy.
    +       * 
    + */ + public Builder clearReplicationFlags() { + bitField0_ = (bitField0_ & ~0x00000002); + replicationFlags_ = 0; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy stripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder> stripingPolicyBuilder_; + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +       * Striping policy for this replica.
    +       * 
    + */ + public boolean hasStripingPolicy() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +       * Striping policy for this replica.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy getStripingPolicy() { + if (stripingPolicyBuilder_ == null) { + return stripingPolicy_; + } else { + return stripingPolicyBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +       * Striping policy for this replica.
    +       * 
    + */ + public Builder setStripingPolicy(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy value) { + if (stripingPolicyBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + stripingPolicy_ = value; + onChanged(); + } else { + stripingPolicyBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +       * Striping policy for this replica.
    +       * 
    + */ + public Builder setStripingPolicy( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder builderForValue) { + if (stripingPolicyBuilder_ == null) { + stripingPolicy_ = builderForValue.build(); + onChanged(); + } else { + stripingPolicyBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +       * Striping policy for this replica.
    +       * 
    + */ + public Builder mergeStripingPolicy(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy value) { + if (stripingPolicyBuilder_ == null) { + if (((bitField0_ & 0x00000004) == 0x00000004) && + stripingPolicy_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance()) { + stripingPolicy_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.newBuilder(stripingPolicy_).mergeFrom(value).buildPartial(); + } else { + stripingPolicy_ = value; + } + onChanged(); + } else { + stripingPolicyBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +       * Striping policy for this replica.
    +       * 
    + */ + public Builder clearStripingPolicy() { + if (stripingPolicyBuilder_ == null) { + stripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + onChanged(); + } else { + stripingPolicyBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +       * Striping policy for this replica.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder getStripingPolicyBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getStripingPolicyFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +       * Striping policy for this replica.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder getStripingPolicyOrBuilder() { + if (stripingPolicyBuilder_ != null) { + return stripingPolicyBuilder_.getMessageOrBuilder(); + } else { + return stripingPolicy_; + } + } + /** + * required .xtreemfs.pbrpc.StripingPolicy striping_policy = 3; + * + *
    +       * Striping policy for this replica.
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder> + getStripingPolicyFieldBuilder() { + if (stripingPolicyBuilder_ == null) { + stripingPolicyBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder>( + stripingPolicy_, + getParentForChildren(), + isClean()); + stripingPolicy_ = null; + } + return stripingPolicyBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.Replica) + } + + static { + defaultInstance = new Replica(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Replica) + } + + public interface ReplicasOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated .xtreemfs.pbrpc.Replica replicas = 1; + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + java.util.List + getReplicasList(); + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica getReplicas(int index); + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + int getReplicasCount(); + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + java.util.List + getReplicasOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder getReplicasOrBuilder( + int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Replicas} + * + *
    +   * List of replicas for a file.
    +   * 
    + */ + public static final class Replicas extends + com.google.protobuf.GeneratedMessage + implements ReplicasOrBuilder { + // Use Replicas.newBuilder() to construct. + private Replicas(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Replicas(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Replicas defaultInstance; + public static Replicas getDefaultInstance() { + return defaultInstance; + } + + public Replicas getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Replicas( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + replicas_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + replicas_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + replicas_ = java.util.Collections.unmodifiableList(replicas_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_Replicas_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_Replicas_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Replicas parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Replicas(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated .xtreemfs.pbrpc.Replica replicas = 1; + public static final int REPLICAS_FIELD_NUMBER = 1; + private java.util.List replicas_; + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public java.util.List getReplicasList() { + return replicas_; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public java.util.List + getReplicasOrBuilderList() { + return replicas_; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public int getReplicasCount() { + return replicas_.size(); + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica getReplicas(int index) { + return replicas_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder getReplicasOrBuilder( + int index) { + return replicas_.get(index); + } + + private void initFields() { + replicas_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + for (int i = 0; i < getReplicasCount(); i++) { + if (!getReplicas(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < replicas_.size(); i++) { + output.writeMessage(1, replicas_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < replicas_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, replicas_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Replicas} + * + *
    +     * List of replicas for a file.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicasOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_Replicas_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_Replicas_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getReplicasFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (replicasBuilder_ == null) { + replicas_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + replicasBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_Replicas_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas build() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas result = new org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas(this); + int from_bitField0_ = bitField0_; + if (replicasBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001)) { + replicas_ = java.util.Collections.unmodifiableList(replicas_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.replicas_ = replicas_; + } else { + result.replicas_ = replicasBuilder_.build(); + } + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas.getDefaultInstance()) return this; + if (replicasBuilder_ == null) { + if (!other.replicas_.isEmpty()) { + if (replicas_.isEmpty()) { + replicas_ = other.replicas_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureReplicasIsMutable(); + replicas_.addAll(other.replicas_); + } + onChanged(); + } + } else { + if (!other.replicas_.isEmpty()) { + if (replicasBuilder_.isEmpty()) { + replicasBuilder_.dispose(); + replicasBuilder_ = null; + replicas_ = other.replicas_; + bitField0_ = (bitField0_ & ~0x00000001); + replicasBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getReplicasFieldBuilder() : null; + } else { + replicasBuilder_.addAllMessages(other.replicas_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + for (int i = 0; i < getReplicasCount(); i++) { + if (!getReplicas(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replicas) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated .xtreemfs.pbrpc.Replica replicas = 1; + private java.util.List replicas_ = + java.util.Collections.emptyList(); + private void ensureReplicasIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + replicas_ = new java.util.ArrayList(replicas_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder> replicasBuilder_; + + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public java.util.List getReplicasList() { + if (replicasBuilder_ == null) { + return java.util.Collections.unmodifiableList(replicas_); + } else { + return replicasBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public int getReplicasCount() { + if (replicasBuilder_ == null) { + return replicas_.size(); + } else { + return replicasBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica getReplicas(int index) { + if (replicasBuilder_ == null) { + return replicas_.get(index); + } else { + return replicasBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public Builder setReplicas( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica value) { + if (replicasBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureReplicasIsMutable(); + replicas_.set(index, value); + onChanged(); + } else { + replicasBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public Builder setReplicas( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder builderForValue) { + if (replicasBuilder_ == null) { + ensureReplicasIsMutable(); + replicas_.set(index, builderForValue.build()); + onChanged(); + } else { + replicasBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public Builder addReplicas(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica value) { + if (replicasBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureReplicasIsMutable(); + replicas_.add(value); + onChanged(); + } else { + replicasBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public Builder addReplicas( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica value) { + if (replicasBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureReplicasIsMutable(); + replicas_.add(index, value); + onChanged(); + } else { + replicasBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public Builder addReplicas( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder builderForValue) { + if (replicasBuilder_ == null) { + ensureReplicasIsMutable(); + replicas_.add(builderForValue.build()); + onChanged(); + } else { + replicasBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public Builder addReplicas( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder builderForValue) { + if (replicasBuilder_ == null) { + ensureReplicasIsMutable(); + replicas_.add(index, builderForValue.build()); + onChanged(); + } else { + replicasBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public Builder addAllReplicas( + java.lang.Iterable values) { + if (replicasBuilder_ == null) { + ensureReplicasIsMutable(); + super.addAll(values, replicas_); + onChanged(); + } else { + replicasBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public Builder clearReplicas() { + if (replicasBuilder_ == null) { + replicas_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + replicasBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public Builder removeReplicas(int index) { + if (replicasBuilder_ == null) { + ensureReplicasIsMutable(); + replicas_.remove(index); + onChanged(); + } else { + replicasBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder getReplicasBuilder( + int index) { + return getReplicasFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder getReplicasOrBuilder( + int index) { + if (replicasBuilder_ == null) { + return replicas_.get(index); } else { + return replicasBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public java.util.List + getReplicasOrBuilderList() { + if (replicasBuilder_ != null) { + return replicasBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(replicas_); + } + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder addReplicasBuilder() { + return getReplicasFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder addReplicasBuilder( + int index) { + return getReplicasFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 1; + */ + public java.util.List + getReplicasBuilderList() { + return getReplicasFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder> + getReplicasFieldBuilder() { + if (replicasBuilder_ == null) { + replicasBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder>( + replicas_, + ((bitField0_ & 0x00000001) == 0x00000001), + getParentForChildren(), + isClean()); + replicas_ = null; + } + return replicasBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.Replicas) + } + + static { + defaultInstance = new Replicas(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Replicas) + } + + public interface XCapOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed32 access_mode = 1; + /** + * required fixed32 access_mode = 1; + * + *
    +     * Access mode (see SYSTEM_V_FCNTL for allowed values).
    +     * 
    + */ + boolean hasAccessMode(); + /** + * required fixed32 access_mode = 1; + * + *
    +     * Access mode (see SYSTEM_V_FCNTL for allowed values).
    +     * 
    + */ + int getAccessMode(); + + // required string client_identity = 2; + /** + * required string client_identity = 2; + * + *
    +     * IP address of the client that owns this XCap.
    +     * 
    + */ + boolean hasClientIdentity(); + /** + * required string client_identity = 2; + * + *
    +     * IP address of the client that owns this XCap.
    +     * 
    + */ + java.lang.String getClientIdentity(); + /** + * required string client_identity = 2; + * + *
    +     * IP address of the client that owns this XCap.
    +     * 
    + */ + com.google.protobuf.ByteString + getClientIdentityBytes(); + + // required fixed64 expire_time_s = 3; + /** + * required fixed64 expire_time_s = 3; + * + *
    +     * Number of seconds this XCap is valid.
    +     * 
    + */ + boolean hasExpireTimeS(); + /** + * required fixed64 expire_time_s = 3; + * + *
    +     * Number of seconds this XCap is valid.
    +     * 
    + */ + long getExpireTimeS(); + + // required fixed32 expire_timeout_s = 4; + /** + * required fixed32 expire_timeout_s = 4; + * + *
    +     * Timestamp in global synchronized XtreemFS time when
    +     * the XCap expires.
    +     * 
    + */ + boolean hasExpireTimeoutS(); + /** + * required fixed32 expire_timeout_s = 4; + * + *
    +     * Timestamp in global synchronized XtreemFS time when
    +     * the XCap expires.
    +     * 
    + */ + int getExpireTimeoutS(); + + // required string file_id = 5; + /** + * required string file_id = 5; + * + *
    +     * FileID for which this XCap is valid.
    +     * 
    + */ + boolean hasFileId(); + /** + * required string file_id = 5; + * + *
    +     * FileID for which this XCap is valid.
    +     * 
    + */ + java.lang.String getFileId(); + /** + * required string file_id = 5; + * + *
    +     * FileID for which this XCap is valid.
    +     * 
    + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required bool replicate_on_close = 6; + /** + * required bool replicate_on_close = 6; + * + *
    +     * True, if the file should be replicated when
    +     * closed (read-only replication).
    +     * 
    + */ + boolean hasReplicateOnClose(); + /** + * required bool replicate_on_close = 6; + * + *
    +     * True, if the file should be replicated when
    +     * closed (read-only replication).
    +     * 
    + */ + boolean getReplicateOnClose(); + + // required string server_signature = 7; + /** + * required string server_signature = 7; + * + *
    +     * MRC server signature, based on various fields of the XCap.
    +     * 
    + */ + boolean hasServerSignature(); + /** + * required string server_signature = 7; + * + *
    +     * MRC server signature, based on various fields of the XCap.
    +     * 
    + */ + java.lang.String getServerSignature(); + /** + * required string server_signature = 7; + * + *
    +     * MRC server signature, based on various fields of the XCap.
    +     * 
    + */ + com.google.protobuf.ByteString + getServerSignatureBytes(); + + // required fixed32 truncate_epoch = 8; + /** + * required fixed32 truncate_epoch = 8; + * + *
    +     * Current truncate_epoch for the file, required by OSDs.
    +     * 
    + */ + boolean hasTruncateEpoch(); + /** + * required fixed32 truncate_epoch = 8; + * + *
    +     * Current truncate_epoch for the file, required by OSDs.
    +     * 
    + */ + int getTruncateEpoch(); + + // required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + /** + * required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + * + *
    +     * Snapshot configuration for the file, required by OSDs.
    +     * 
    + */ + boolean hasSnapConfig(); + /** + * required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + * + *
    +     * Snapshot configuration for the file, required by OSDs.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig getSnapConfig(); + + // required fixed64 snap_timestamp = 10; + /** + * required fixed64 snap_timestamp = 10; + * + *
    +     * If a snapshot of the file is being accessed, this timestamp
    +     * indicates which version (snapshot) of the file should be used
    +     * on the OSD.
    +     * 
    + */ + boolean hasSnapTimestamp(); + /** + * required fixed64 snap_timestamp = 10; + * + *
    +     * If a snapshot of the file is being accessed, this timestamp
    +     * indicates which version (snapshot) of the file should be used
    +     * on the OSD.
    +     * 
    + */ + long getSnapTimestamp(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.XCap} + * + *
    +   * The XCap is the authorization token that allows a 
    +   * client to execute operations on an OSD. It is created
    +   * by the MRC on open and must be renewed by the client
    +   * *before* it times out.
    +   * The XCap is signed and must not be modified by a client.
    +   * 
    + */ + public static final class XCap extends + com.google.protobuf.GeneratedMessage + implements XCapOrBuilder { + // Use XCap.newBuilder() to construct. + private XCap(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private XCap(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final XCap defaultInstance; + public static XCap getDefaultInstance() { + return defaultInstance; + } + + public XCap getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private XCap( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 13: { + bitField0_ |= 0x00000001; + accessMode_ = input.readFixed32(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + clientIdentity_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + expireTimeS_ = input.readFixed64(); + break; + } + case 37: { + bitField0_ |= 0x00000008; + expireTimeoutS_ = input.readFixed32(); + break; + } + case 42: { + bitField0_ |= 0x00000010; + fileId_ = input.readBytes(); + break; + } + case 48: { + bitField0_ |= 0x00000020; + replicateOnClose_ = input.readBool(); + break; + } + case 58: { + bitField0_ |= 0x00000040; + serverSignature_ = input.readBytes(); + break; + } + case 69: { + bitField0_ |= 0x00000080; + truncateEpoch_ = input.readFixed32(); + break; + } + case 72: { + int rawValue = input.readEnum(); + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig value = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(9, rawValue); + } else { + bitField0_ |= 0x00000100; + snapConfig_ = value; + } + break; + } + case 81: { + bitField0_ |= 0x00000200; + snapTimestamp_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_XCap_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_XCap_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public XCap parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new XCap(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed32 access_mode = 1; + public static final int ACCESS_MODE_FIELD_NUMBER = 1; + private int accessMode_; + /** + * required fixed32 access_mode = 1; + * + *
    +     * Access mode (see SYSTEM_V_FCNTL for allowed values).
    +     * 
    + */ + public boolean hasAccessMode() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 access_mode = 1; + * + *
    +     * Access mode (see SYSTEM_V_FCNTL for allowed values).
    +     * 
    + */ + public int getAccessMode() { + return accessMode_; + } + + // required string client_identity = 2; + public static final int CLIENT_IDENTITY_FIELD_NUMBER = 2; + private java.lang.Object clientIdentity_; + /** + * required string client_identity = 2; + * + *
    +     * IP address of the client that owns this XCap.
    +     * 
    + */ + public boolean hasClientIdentity() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string client_identity = 2; + * + *
    +     * IP address of the client that owns this XCap.
    +     * 
    + */ + public java.lang.String getClientIdentity() { + java.lang.Object ref = clientIdentity_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clientIdentity_ = s; + } + return s; + } + } + /** + * required string client_identity = 2; + * + *
    +     * IP address of the client that owns this XCap.
    +     * 
    + */ + public com.google.protobuf.ByteString + getClientIdentityBytes() { + java.lang.Object ref = clientIdentity_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clientIdentity_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 expire_time_s = 3; + public static final int EXPIRE_TIME_S_FIELD_NUMBER = 3; + private long expireTimeS_; + /** + * required fixed64 expire_time_s = 3; + * + *
    +     * Number of seconds this XCap is valid.
    +     * 
    + */ + public boolean hasExpireTimeS() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 expire_time_s = 3; + * + *
    +     * Number of seconds this XCap is valid.
    +     * 
    + */ + public long getExpireTimeS() { + return expireTimeS_; + } + + // required fixed32 expire_timeout_s = 4; + public static final int EXPIRE_TIMEOUT_S_FIELD_NUMBER = 4; + private int expireTimeoutS_; + /** + * required fixed32 expire_timeout_s = 4; + * + *
    +     * Timestamp in global synchronized XtreemFS time when
    +     * the XCap expires.
    +     * 
    + */ + public boolean hasExpireTimeoutS() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 expire_timeout_s = 4; + * + *
    +     * Timestamp in global synchronized XtreemFS time when
    +     * the XCap expires.
    +     * 
    + */ + public int getExpireTimeoutS() { + return expireTimeoutS_; + } + + // required string file_id = 5; + public static final int FILE_ID_FIELD_NUMBER = 5; + private java.lang.Object fileId_; + /** + * required string file_id = 5; + * + *
    +     * FileID for which this XCap is valid.
    +     * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required string file_id = 5; + * + *
    +     * FileID for which this XCap is valid.
    +     * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 5; + * + *
    +     * FileID for which this XCap is valid.
    +     * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required bool replicate_on_close = 6; + public static final int REPLICATE_ON_CLOSE_FIELD_NUMBER = 6; + private boolean replicateOnClose_; + /** + * required bool replicate_on_close = 6; + * + *
    +     * True, if the file should be replicated when
    +     * closed (read-only replication).
    +     * 
    + */ + public boolean hasReplicateOnClose() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required bool replicate_on_close = 6; + * + *
    +     * True, if the file should be replicated when
    +     * closed (read-only replication).
    +     * 
    + */ + public boolean getReplicateOnClose() { + return replicateOnClose_; + } + + // required string server_signature = 7; + public static final int SERVER_SIGNATURE_FIELD_NUMBER = 7; + private java.lang.Object serverSignature_; + /** + * required string server_signature = 7; + * + *
    +     * MRC server signature, based on various fields of the XCap.
    +     * 
    + */ + public boolean hasServerSignature() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required string server_signature = 7; + * + *
    +     * MRC server signature, based on various fields of the XCap.
    +     * 
    + */ + public java.lang.String getServerSignature() { + java.lang.Object ref = serverSignature_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + serverSignature_ = s; + } + return s; + } + } + /** + * required string server_signature = 7; + * + *
    +     * MRC server signature, based on various fields of the XCap.
    +     * 
    + */ + public com.google.protobuf.ByteString + getServerSignatureBytes() { + java.lang.Object ref = serverSignature_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + serverSignature_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 truncate_epoch = 8; + public static final int TRUNCATE_EPOCH_FIELD_NUMBER = 8; + private int truncateEpoch_; + /** + * required fixed32 truncate_epoch = 8; + * + *
    +     * Current truncate_epoch for the file, required by OSDs.
    +     * 
    + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * required fixed32 truncate_epoch = 8; + * + *
    +     * Current truncate_epoch for the file, required by OSDs.
    +     * 
    + */ + public int getTruncateEpoch() { + return truncateEpoch_; + } + + // required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + public static final int SNAP_CONFIG_FIELD_NUMBER = 9; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig snapConfig_; + /** + * required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + * + *
    +     * Snapshot configuration for the file, required by OSDs.
    +     * 
    + */ + public boolean hasSnapConfig() { + return ((bitField0_ & 0x00000100) == 0x00000100); + } + /** + * required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + * + *
    +     * Snapshot configuration for the file, required by OSDs.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig getSnapConfig() { + return snapConfig_; + } + + // required fixed64 snap_timestamp = 10; + public static final int SNAP_TIMESTAMP_FIELD_NUMBER = 10; + private long snapTimestamp_; + /** + * required fixed64 snap_timestamp = 10; + * + *
    +     * If a snapshot of the file is being accessed, this timestamp
    +     * indicates which version (snapshot) of the file should be used
    +     * on the OSD.
    +     * 
    + */ + public boolean hasSnapTimestamp() { + return ((bitField0_ & 0x00000200) == 0x00000200); + } + /** + * required fixed64 snap_timestamp = 10; + * + *
    +     * If a snapshot of the file is being accessed, this timestamp
    +     * indicates which version (snapshot) of the file should be used
    +     * on the OSD.
    +     * 
    + */ + public long getSnapTimestamp() { + return snapTimestamp_; + } + + private void initFields() { + accessMode_ = 0; + clientIdentity_ = ""; + expireTimeS_ = 0L; + expireTimeoutS_ = 0; + fileId_ = ""; + replicateOnClose_ = false; + serverSignature_ = ""; + truncateEpoch_ = 0; + snapConfig_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig.SNAP_CONFIG_SNAPS_DISABLED; + snapTimestamp_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasAccessMode()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasClientIdentity()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasExpireTimeS()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasExpireTimeoutS()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasReplicateOnClose()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasServerSignature()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTruncateEpoch()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasSnapConfig()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasSnapTimestamp()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed32(1, accessMode_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getClientIdentityBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, expireTimeS_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed32(4, expireTimeoutS_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeBytes(5, getFileIdBytes()); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeBool(6, replicateOnClose_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeBytes(7, getServerSignatureBytes()); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + output.writeFixed32(8, truncateEpoch_); + } + if (((bitField0_ & 0x00000100) == 0x00000100)) { + output.writeEnum(9, snapConfig_.getNumber()); + } + if (((bitField0_ & 0x00000200) == 0x00000200)) { + output.writeFixed64(10, snapTimestamp_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(1, accessMode_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getClientIdentityBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, expireTimeS_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(4, expireTimeoutS_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(5, getFileIdBytes()); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(6, replicateOnClose_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(7, getServerSignatureBytes()); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(8, truncateEpoch_); + } + if (((bitField0_ & 0x00000100) == 0x00000100)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(9, snapConfig_.getNumber()); + } + if (((bitField0_ & 0x00000200) == 0x00000200)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(10, snapTimestamp_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.XCap} + * + *
    +     * The XCap is the authorization token that allows a 
    +     * client to execute operations on an OSD. It is created
    +     * by the MRC on open and must be renewed by the client
    +     * *before* it times out.
    +     * The XCap is signed and must not be modified by a client.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_XCap_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_XCap_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + accessMode_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + clientIdentity_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + expireTimeS_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + expireTimeoutS_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000010); + replicateOnClose_ = false; + bitField0_ = (bitField0_ & ~0x00000020); + serverSignature_ = ""; + bitField0_ = (bitField0_ & ~0x00000040); + truncateEpoch_ = 0; + bitField0_ = (bitField0_ & ~0x00000080); + snapConfig_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig.SNAP_CONFIG_SNAPS_DISABLED; + bitField0_ = (bitField0_ & ~0x00000100); + snapTimestamp_ = 0L; + bitField0_ = (bitField0_ & ~0x00000200); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_XCap_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap build() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap result = new org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.accessMode_ = accessMode_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.clientIdentity_ = clientIdentity_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.expireTimeS_ = expireTimeS_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.expireTimeoutS_ = expireTimeoutS_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.replicateOnClose_ = replicateOnClose_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000040; + } + result.serverSignature_ = serverSignature_; + if (((from_bitField0_ & 0x00000080) == 0x00000080)) { + to_bitField0_ |= 0x00000080; + } + result.truncateEpoch_ = truncateEpoch_; + if (((from_bitField0_ & 0x00000100) == 0x00000100)) { + to_bitField0_ |= 0x00000100; + } + result.snapConfig_ = snapConfig_; + if (((from_bitField0_ & 0x00000200) == 0x00000200)) { + to_bitField0_ |= 0x00000200; + } + result.snapTimestamp_ = snapTimestamp_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance()) return this; + if (other.hasAccessMode()) { + setAccessMode(other.getAccessMode()); + } + if (other.hasClientIdentity()) { + bitField0_ |= 0x00000002; + clientIdentity_ = other.clientIdentity_; + onChanged(); + } + if (other.hasExpireTimeS()) { + setExpireTimeS(other.getExpireTimeS()); + } + if (other.hasExpireTimeoutS()) { + setExpireTimeoutS(other.getExpireTimeoutS()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000010; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasReplicateOnClose()) { + setReplicateOnClose(other.getReplicateOnClose()); + } + if (other.hasServerSignature()) { + bitField0_ |= 0x00000040; + serverSignature_ = other.serverSignature_; + onChanged(); + } + if (other.hasTruncateEpoch()) { + setTruncateEpoch(other.getTruncateEpoch()); + } + if (other.hasSnapConfig()) { + setSnapConfig(other.getSnapConfig()); + } + if (other.hasSnapTimestamp()) { + setSnapTimestamp(other.getSnapTimestamp()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasAccessMode()) { + + return false; + } + if (!hasClientIdentity()) { + + return false; + } + if (!hasExpireTimeS()) { + + return false; + } + if (!hasExpireTimeoutS()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasReplicateOnClose()) { + + return false; + } + if (!hasServerSignature()) { + + return false; + } + if (!hasTruncateEpoch()) { + + return false; + } + if (!hasSnapConfig()) { + + return false; + } + if (!hasSnapTimestamp()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed32 access_mode = 1; + private int accessMode_ ; + /** + * required fixed32 access_mode = 1; + * + *
    +       * Access mode (see SYSTEM_V_FCNTL for allowed values).
    +       * 
    + */ + public boolean hasAccessMode() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 access_mode = 1; + * + *
    +       * Access mode (see SYSTEM_V_FCNTL for allowed values).
    +       * 
    + */ + public int getAccessMode() { + return accessMode_; + } + /** + * required fixed32 access_mode = 1; + * + *
    +       * Access mode (see SYSTEM_V_FCNTL for allowed values).
    +       * 
    + */ + public Builder setAccessMode(int value) { + bitField0_ |= 0x00000001; + accessMode_ = value; + onChanged(); + return this; + } + /** + * required fixed32 access_mode = 1; + * + *
    +       * Access mode (see SYSTEM_V_FCNTL for allowed values).
    +       * 
    + */ + public Builder clearAccessMode() { + bitField0_ = (bitField0_ & ~0x00000001); + accessMode_ = 0; + onChanged(); + return this; + } + + // required string client_identity = 2; + private java.lang.Object clientIdentity_ = ""; + /** + * required string client_identity = 2; + * + *
    +       * IP address of the client that owns this XCap.
    +       * 
    + */ + public boolean hasClientIdentity() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string client_identity = 2; + * + *
    +       * IP address of the client that owns this XCap.
    +       * 
    + */ + public java.lang.String getClientIdentity() { + java.lang.Object ref = clientIdentity_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + clientIdentity_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string client_identity = 2; + * + *
    +       * IP address of the client that owns this XCap.
    +       * 
    + */ + public com.google.protobuf.ByteString + getClientIdentityBytes() { + java.lang.Object ref = clientIdentity_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clientIdentity_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string client_identity = 2; + * + *
    +       * IP address of the client that owns this XCap.
    +       * 
    + */ + public Builder setClientIdentity( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clientIdentity_ = value; + onChanged(); + return this; + } + /** + * required string client_identity = 2; + * + *
    +       * IP address of the client that owns this XCap.
    +       * 
    + */ + public Builder clearClientIdentity() { + bitField0_ = (bitField0_ & ~0x00000002); + clientIdentity_ = getDefaultInstance().getClientIdentity(); + onChanged(); + return this; + } + /** + * required string client_identity = 2; + * + *
    +       * IP address of the client that owns this XCap.
    +       * 
    + */ + public Builder setClientIdentityBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clientIdentity_ = value; + onChanged(); + return this; + } + + // required fixed64 expire_time_s = 3; + private long expireTimeS_ ; + /** + * required fixed64 expire_time_s = 3; + * + *
    +       * Number of seconds this XCap is valid.
    +       * 
    + */ + public boolean hasExpireTimeS() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 expire_time_s = 3; + * + *
    +       * Number of seconds this XCap is valid.
    +       * 
    + */ + public long getExpireTimeS() { + return expireTimeS_; + } + /** + * required fixed64 expire_time_s = 3; + * + *
    +       * Number of seconds this XCap is valid.
    +       * 
    + */ + public Builder setExpireTimeS(long value) { + bitField0_ |= 0x00000004; + expireTimeS_ = value; + onChanged(); + return this; + } + /** + * required fixed64 expire_time_s = 3; + * + *
    +       * Number of seconds this XCap is valid.
    +       * 
    + */ + public Builder clearExpireTimeS() { + bitField0_ = (bitField0_ & ~0x00000004); + expireTimeS_ = 0L; + onChanged(); + return this; + } + + // required fixed32 expire_timeout_s = 4; + private int expireTimeoutS_ ; + /** + * required fixed32 expire_timeout_s = 4; + * + *
    +       * Timestamp in global synchronized XtreemFS time when
    +       * the XCap expires.
    +       * 
    + */ + public boolean hasExpireTimeoutS() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 expire_timeout_s = 4; + * + *
    +       * Timestamp in global synchronized XtreemFS time when
    +       * the XCap expires.
    +       * 
    + */ + public int getExpireTimeoutS() { + return expireTimeoutS_; + } + /** + * required fixed32 expire_timeout_s = 4; + * + *
    +       * Timestamp in global synchronized XtreemFS time when
    +       * the XCap expires.
    +       * 
    + */ + public Builder setExpireTimeoutS(int value) { + bitField0_ |= 0x00000008; + expireTimeoutS_ = value; + onChanged(); + return this; + } + /** + * required fixed32 expire_timeout_s = 4; + * + *
    +       * Timestamp in global synchronized XtreemFS time when
    +       * the XCap expires.
    +       * 
    + */ + public Builder clearExpireTimeoutS() { + bitField0_ = (bitField0_ & ~0x00000008); + expireTimeoutS_ = 0; + onChanged(); + return this; + } + + // required string file_id = 5; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 5; + * + *
    +       * FileID for which this XCap is valid.
    +       * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required string file_id = 5; + * + *
    +       * FileID for which this XCap is valid.
    +       * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 5; + * + *
    +       * FileID for which this XCap is valid.
    +       * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 5; + * + *
    +       * FileID for which this XCap is valid.
    +       * 
    + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 5; + * + *
    +       * FileID for which this XCap is valid.
    +       * 
    + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000010); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 5; + * + *
    +       * FileID for which this XCap is valid.
    +       * 
    + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + fileId_ = value; + onChanged(); + return this; + } + + // required bool replicate_on_close = 6; + private boolean replicateOnClose_ ; + /** + * required bool replicate_on_close = 6; + * + *
    +       * True, if the file should be replicated when
    +       * closed (read-only replication).
    +       * 
    + */ + public boolean hasReplicateOnClose() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required bool replicate_on_close = 6; + * + *
    +       * True, if the file should be replicated when
    +       * closed (read-only replication).
    +       * 
    + */ + public boolean getReplicateOnClose() { + return replicateOnClose_; + } + /** + * required bool replicate_on_close = 6; + * + *
    +       * True, if the file should be replicated when
    +       * closed (read-only replication).
    +       * 
    + */ + public Builder setReplicateOnClose(boolean value) { + bitField0_ |= 0x00000020; + replicateOnClose_ = value; + onChanged(); + return this; + } + /** + * required bool replicate_on_close = 6; + * + *
    +       * True, if the file should be replicated when
    +       * closed (read-only replication).
    +       * 
    + */ + public Builder clearReplicateOnClose() { + bitField0_ = (bitField0_ & ~0x00000020); + replicateOnClose_ = false; + onChanged(); + return this; + } + + // required string server_signature = 7; + private java.lang.Object serverSignature_ = ""; + /** + * required string server_signature = 7; + * + *
    +       * MRC server signature, based on various fields of the XCap.
    +       * 
    + */ + public boolean hasServerSignature() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required string server_signature = 7; + * + *
    +       * MRC server signature, based on various fields of the XCap.
    +       * 
    + */ + public java.lang.String getServerSignature() { + java.lang.Object ref = serverSignature_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + serverSignature_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string server_signature = 7; + * + *
    +       * MRC server signature, based on various fields of the XCap.
    +       * 
    + */ + public com.google.protobuf.ByteString + getServerSignatureBytes() { + java.lang.Object ref = serverSignature_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + serverSignature_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string server_signature = 7; + * + *
    +       * MRC server signature, based on various fields of the XCap.
    +       * 
    + */ + public Builder setServerSignature( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000040; + serverSignature_ = value; + onChanged(); + return this; + } + /** + * required string server_signature = 7; + * + *
    +       * MRC server signature, based on various fields of the XCap.
    +       * 
    + */ + public Builder clearServerSignature() { + bitField0_ = (bitField0_ & ~0x00000040); + serverSignature_ = getDefaultInstance().getServerSignature(); + onChanged(); + return this; + } + /** + * required string server_signature = 7; + * + *
    +       * MRC server signature, based on various fields of the XCap.
    +       * 
    + */ + public Builder setServerSignatureBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000040; + serverSignature_ = value; + onChanged(); + return this; + } + + // required fixed32 truncate_epoch = 8; + private int truncateEpoch_ ; + /** + * required fixed32 truncate_epoch = 8; + * + *
    +       * Current truncate_epoch for the file, required by OSDs.
    +       * 
    + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * required fixed32 truncate_epoch = 8; + * + *
    +       * Current truncate_epoch for the file, required by OSDs.
    +       * 
    + */ + public int getTruncateEpoch() { + return truncateEpoch_; + } + /** + * required fixed32 truncate_epoch = 8; + * + *
    +       * Current truncate_epoch for the file, required by OSDs.
    +       * 
    + */ + public Builder setTruncateEpoch(int value) { + bitField0_ |= 0x00000080; + truncateEpoch_ = value; + onChanged(); + return this; + } + /** + * required fixed32 truncate_epoch = 8; + * + *
    +       * Current truncate_epoch for the file, required by OSDs.
    +       * 
    + */ + public Builder clearTruncateEpoch() { + bitField0_ = (bitField0_ & ~0x00000080); + truncateEpoch_ = 0; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig snapConfig_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig.SNAP_CONFIG_SNAPS_DISABLED; + /** + * required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + * + *
    +       * Snapshot configuration for the file, required by OSDs.
    +       * 
    + */ + public boolean hasSnapConfig() { + return ((bitField0_ & 0x00000100) == 0x00000100); + } + /** + * required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + * + *
    +       * Snapshot configuration for the file, required by OSDs.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig getSnapConfig() { + return snapConfig_; + } + /** + * required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + * + *
    +       * Snapshot configuration for the file, required by OSDs.
    +       * 
    + */ + public Builder setSnapConfig(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000100; + snapConfig_ = value; + onChanged(); + return this; + } + /** + * required .xtreemfs.pbrpc.SnapConfig snap_config = 9; + * + *
    +       * Snapshot configuration for the file, required by OSDs.
    +       * 
    + */ + public Builder clearSnapConfig() { + bitField0_ = (bitField0_ & ~0x00000100); + snapConfig_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig.SNAP_CONFIG_SNAPS_DISABLED; + onChanged(); + return this; + } + + // required fixed64 snap_timestamp = 10; + private long snapTimestamp_ ; + /** + * required fixed64 snap_timestamp = 10; + * + *
    +       * If a snapshot of the file is being accessed, this timestamp
    +       * indicates which version (snapshot) of the file should be used
    +       * on the OSD.
    +       * 
    + */ + public boolean hasSnapTimestamp() { + return ((bitField0_ & 0x00000200) == 0x00000200); + } + /** + * required fixed64 snap_timestamp = 10; + * + *
    +       * If a snapshot of the file is being accessed, this timestamp
    +       * indicates which version (snapshot) of the file should be used
    +       * on the OSD.
    +       * 
    + */ + public long getSnapTimestamp() { + return snapTimestamp_; + } + /** + * required fixed64 snap_timestamp = 10; + * + *
    +       * If a snapshot of the file is being accessed, this timestamp
    +       * indicates which version (snapshot) of the file should be used
    +       * on the OSD.
    +       * 
    + */ + public Builder setSnapTimestamp(long value) { + bitField0_ |= 0x00000200; + snapTimestamp_ = value; + onChanged(); + return this; + } + /** + * required fixed64 snap_timestamp = 10; + * + *
    +       * If a snapshot of the file is being accessed, this timestamp
    +       * indicates which version (snapshot) of the file should be used
    +       * on the OSD.
    +       * 
    + */ + public Builder clearSnapTimestamp() { + bitField0_ = (bitField0_ & ~0x00000200); + snapTimestamp_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.XCap) + } + + static { + defaultInstance = new XCap(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.XCap) + } + + public interface XLocSetOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 read_only_file_size = 1; + /** + * required fixed64 read_only_file_size = 1; + * + *
    +     * Used by the read-only replication to properly handle
    +     * holes in sparse files and EOF.
    +     * 
    + */ + boolean hasReadOnlyFileSize(); + /** + * required fixed64 read_only_file_size = 1; + * + *
    +     * Used by the read-only replication to properly handle
    +     * holes in sparse files and EOF.
    +     * 
    + */ + long getReadOnlyFileSize(); + + // repeated .xtreemfs.pbrpc.Replica replicas = 2; + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +     * List of actual file replicas.
    +     * 
    + */ + java.util.List + getReplicasList(); + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +     * List of actual file replicas.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica getReplicas(int index); + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +     * List of actual file replicas.
    +     * 
    + */ + int getReplicasCount(); + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +     * List of actual file replicas.
    +     * 
    + */ + java.util.List + getReplicasOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +     * List of actual file replicas.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder getReplicasOrBuilder( + int index); + + // required string replica_update_policy = 3; + /** + * required string replica_update_policy = 3; + * + *
    +     * Update policy to use for the file,
    +     * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +     * 
    + */ + boolean hasReplicaUpdatePolicy(); + /** + * required string replica_update_policy = 3; + * + *
    +     * Update policy to use for the file,
    +     * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +     * 
    + */ + java.lang.String getReplicaUpdatePolicy(); + /** + * required string replica_update_policy = 3; + * + *
    +     * Update policy to use for the file,
    +     * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +     * 
    + */ + com.google.protobuf.ByteString + getReplicaUpdatePolicyBytes(); + + // required fixed32 version = 4; + /** + * required fixed32 version = 4; + * + *
    +     * Monotonically increasing version number of a file's XLocSet.
    +     * Used to identify clients with outdates XLocSets.
    +     * 
    + */ + boolean hasVersion(); + /** + * required fixed32 version = 4; + * + *
    +     * Monotonically increasing version number of a file's XLocSet.
    +     * Used to identify clients with outdates XLocSets.
    +     * 
    + */ + int getVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.XLocSet} + * + *
    +   * Locations of a file, i.e. the list of replicas including the OSDs that hold
    +   * the file data.
    +   * 
    + */ + public static final class XLocSet extends + com.google.protobuf.GeneratedMessage + implements XLocSetOrBuilder { + // Use XLocSet.newBuilder() to construct. + private XLocSet(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private XLocSet(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final XLocSet defaultInstance; + public static XLocSet getDefaultInstance() { + return defaultInstance; + } + + public XLocSet getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private XLocSet( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + readOnlyFileSize_ = input.readFixed64(); + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + replicas_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + replicas_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.PARSER, extensionRegistry)); + break; + } + case 26: { + bitField0_ |= 0x00000002; + replicaUpdatePolicy_ = input.readBytes(); + break; + } + case 37: { + bitField0_ |= 0x00000004; + version_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + replicas_ = java.util.Collections.unmodifiableList(replicas_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_XLocSet_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_XLocSet_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public XLocSet parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new XLocSet(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 read_only_file_size = 1; + public static final int READ_ONLY_FILE_SIZE_FIELD_NUMBER = 1; + private long readOnlyFileSize_; + /** + * required fixed64 read_only_file_size = 1; + * + *
    +     * Used by the read-only replication to properly handle
    +     * holes in sparse files and EOF.
    +     * 
    + */ + public boolean hasReadOnlyFileSize() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 read_only_file_size = 1; + * + *
    +     * Used by the read-only replication to properly handle
    +     * holes in sparse files and EOF.
    +     * 
    + */ + public long getReadOnlyFileSize() { + return readOnlyFileSize_; + } + + // repeated .xtreemfs.pbrpc.Replica replicas = 2; + public static final int REPLICAS_FIELD_NUMBER = 2; + private java.util.List replicas_; + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +     * List of actual file replicas.
    +     * 
    + */ + public java.util.List getReplicasList() { + return replicas_; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +     * List of actual file replicas.
    +     * 
    + */ + public java.util.List + getReplicasOrBuilderList() { + return replicas_; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +     * List of actual file replicas.
    +     * 
    + */ + public int getReplicasCount() { + return replicas_.size(); + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +     * List of actual file replicas.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica getReplicas(int index) { + return replicas_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +     * List of actual file replicas.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder getReplicasOrBuilder( + int index) { + return replicas_.get(index); + } + + // required string replica_update_policy = 3; + public static final int REPLICA_UPDATE_POLICY_FIELD_NUMBER = 3; + private java.lang.Object replicaUpdatePolicy_; + /** + * required string replica_update_policy = 3; + * + *
    +     * Update policy to use for the file,
    +     * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +     * 
    + */ + public boolean hasReplicaUpdatePolicy() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string replica_update_policy = 3; + * + *
    +     * Update policy to use for the file,
    +     * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +     * 
    + */ + public java.lang.String getReplicaUpdatePolicy() { + java.lang.Object ref = replicaUpdatePolicy_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + replicaUpdatePolicy_ = s; + } + return s; + } + } + /** + * required string replica_update_policy = 3; + * + *
    +     * Update policy to use for the file,
    +     * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +     * 
    + */ + public com.google.protobuf.ByteString + getReplicaUpdatePolicyBytes() { + java.lang.Object ref = replicaUpdatePolicy_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + replicaUpdatePolicy_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 version = 4; + public static final int VERSION_FIELD_NUMBER = 4; + private int version_; + /** + * required fixed32 version = 4; + * + *
    +     * Monotonically increasing version number of a file's XLocSet.
    +     * Used to identify clients with outdates XLocSets.
    +     * 
    + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 version = 4; + * + *
    +     * Monotonically increasing version number of a file's XLocSet.
    +     * Used to identify clients with outdates XLocSets.
    +     * 
    + */ + public int getVersion() { + return version_; + } + + private void initFields() { + readOnlyFileSize_ = 0L; + replicas_ = java.util.Collections.emptyList(); + replicaUpdatePolicy_ = ""; + version_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasReadOnlyFileSize()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasReplicaUpdatePolicy()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasVersion()) { + memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getReplicasCount(); i++) { + if (!getReplicas(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, readOnlyFileSize_); + } + for (int i = 0; i < replicas_.size(); i++) { + output.writeMessage(2, replicas_.get(i)); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(3, getReplicaUpdatePolicyBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed32(4, version_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, readOnlyFileSize_); + } + for (int i = 0; i < replicas_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, replicas_.get(i)); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getReplicaUpdatePolicyBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(4, version_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.XLocSet} + * + *
    +     * Locations of a file, i.e. the list of replicas including the OSDs that hold
    +     * the file data.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSetOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_XLocSet_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_XLocSet_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getReplicasFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + readOnlyFileSize_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + if (replicasBuilder_ == null) { + replicas_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + } else { + replicasBuilder_.clear(); + } + replicaUpdatePolicy_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + version_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_XLocSet_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet build() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet result = new org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.readOnlyFileSize_ = readOnlyFileSize_; + if (replicasBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002)) { + replicas_ = java.util.Collections.unmodifiableList(replicas_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.replicas_ = replicas_; + } else { + result.replicas_ = replicasBuilder_.build(); + } + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000002; + } + result.replicaUpdatePolicy_ = replicaUpdatePolicy_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000004; + } + result.version_ = version_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.getDefaultInstance()) return this; + if (other.hasReadOnlyFileSize()) { + setReadOnlyFileSize(other.getReadOnlyFileSize()); + } + if (replicasBuilder_ == null) { + if (!other.replicas_.isEmpty()) { + if (replicas_.isEmpty()) { + replicas_ = other.replicas_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureReplicasIsMutable(); + replicas_.addAll(other.replicas_); + } + onChanged(); + } + } else { + if (!other.replicas_.isEmpty()) { + if (replicasBuilder_.isEmpty()) { + replicasBuilder_.dispose(); + replicasBuilder_ = null; + replicas_ = other.replicas_; + bitField0_ = (bitField0_ & ~0x00000002); + replicasBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getReplicasFieldBuilder() : null; + } else { + replicasBuilder_.addAllMessages(other.replicas_); + } + } + } + if (other.hasReplicaUpdatePolicy()) { + bitField0_ |= 0x00000004; + replicaUpdatePolicy_ = other.replicaUpdatePolicy_; + onChanged(); + } + if (other.hasVersion()) { + setVersion(other.getVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasReadOnlyFileSize()) { + + return false; + } + if (!hasReplicaUpdatePolicy()) { + + return false; + } + if (!hasVersion()) { + + return false; + } + for (int i = 0; i < getReplicasCount(); i++) { + if (!getReplicas(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 read_only_file_size = 1; + private long readOnlyFileSize_ ; + /** + * required fixed64 read_only_file_size = 1; + * + *
    +       * Used by the read-only replication to properly handle
    +       * holes in sparse files and EOF.
    +       * 
    + */ + public boolean hasReadOnlyFileSize() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 read_only_file_size = 1; + * + *
    +       * Used by the read-only replication to properly handle
    +       * holes in sparse files and EOF.
    +       * 
    + */ + public long getReadOnlyFileSize() { + return readOnlyFileSize_; + } + /** + * required fixed64 read_only_file_size = 1; + * + *
    +       * Used by the read-only replication to properly handle
    +       * holes in sparse files and EOF.
    +       * 
    + */ + public Builder setReadOnlyFileSize(long value) { + bitField0_ |= 0x00000001; + readOnlyFileSize_ = value; + onChanged(); + return this; + } + /** + * required fixed64 read_only_file_size = 1; + * + *
    +       * Used by the read-only replication to properly handle
    +       * holes in sparse files and EOF.
    +       * 
    + */ + public Builder clearReadOnlyFileSize() { + bitField0_ = (bitField0_ & ~0x00000001); + readOnlyFileSize_ = 0L; + onChanged(); + return this; + } + + // repeated .xtreemfs.pbrpc.Replica replicas = 2; + private java.util.List replicas_ = + java.util.Collections.emptyList(); + private void ensureReplicasIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + replicas_ = new java.util.ArrayList(replicas_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder> replicasBuilder_; + + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public java.util.List getReplicasList() { + if (replicasBuilder_ == null) { + return java.util.Collections.unmodifiableList(replicas_); + } else { + return replicasBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public int getReplicasCount() { + if (replicasBuilder_ == null) { + return replicas_.size(); + } else { + return replicasBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica getReplicas(int index) { + if (replicasBuilder_ == null) { + return replicas_.get(index); + } else { + return replicasBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public Builder setReplicas( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica value) { + if (replicasBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureReplicasIsMutable(); + replicas_.set(index, value); + onChanged(); + } else { + replicasBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public Builder setReplicas( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder builderForValue) { + if (replicasBuilder_ == null) { + ensureReplicasIsMutable(); + replicas_.set(index, builderForValue.build()); + onChanged(); + } else { + replicasBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public Builder addReplicas(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica value) { + if (replicasBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureReplicasIsMutable(); + replicas_.add(value); + onChanged(); + } else { + replicasBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public Builder addReplicas( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica value) { + if (replicasBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureReplicasIsMutable(); + replicas_.add(index, value); + onChanged(); + } else { + replicasBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public Builder addReplicas( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder builderForValue) { + if (replicasBuilder_ == null) { + ensureReplicasIsMutable(); + replicas_.add(builderForValue.build()); + onChanged(); + } else { + replicasBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public Builder addReplicas( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder builderForValue) { + if (replicasBuilder_ == null) { + ensureReplicasIsMutable(); + replicas_.add(index, builderForValue.build()); + onChanged(); + } else { + replicasBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public Builder addAllReplicas( + java.lang.Iterable values) { + if (replicasBuilder_ == null) { + ensureReplicasIsMutable(); + super.addAll(values, replicas_); + onChanged(); + } else { + replicasBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public Builder clearReplicas() { + if (replicasBuilder_ == null) { + replicas_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + replicasBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public Builder removeReplicas(int index) { + if (replicasBuilder_ == null) { + ensureReplicasIsMutable(); + replicas_.remove(index); + onChanged(); + } else { + replicasBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder getReplicasBuilder( + int index) { + return getReplicasFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder getReplicasOrBuilder( + int index) { + if (replicasBuilder_ == null) { + return replicas_.get(index); } else { + return replicasBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public java.util.List + getReplicasOrBuilderList() { + if (replicasBuilder_ != null) { + return replicasBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(replicas_); + } + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder addReplicasBuilder() { + return getReplicasFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder addReplicasBuilder( + int index) { + return getReplicasFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.Replica replicas = 2; + * + *
    +       * List of actual file replicas.
    +       * 
    + */ + public java.util.List + getReplicasBuilderList() { + return getReplicasFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder> + getReplicasFieldBuilder() { + if (replicasBuilder_ == null) { + replicasBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder>( + replicas_, + ((bitField0_ & 0x00000002) == 0x00000002), + getParentForChildren(), + isClean()); + replicas_ = null; + } + return replicasBuilder_; + } + + // required string replica_update_policy = 3; + private java.lang.Object replicaUpdatePolicy_ = ""; + /** + * required string replica_update_policy = 3; + * + *
    +       * Update policy to use for the file,
    +       * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +       * 
    + */ + public boolean hasReplicaUpdatePolicy() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string replica_update_policy = 3; + * + *
    +       * Update policy to use for the file,
    +       * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +       * 
    + */ + public java.lang.String getReplicaUpdatePolicy() { + java.lang.Object ref = replicaUpdatePolicy_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + replicaUpdatePolicy_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string replica_update_policy = 3; + * + *
    +       * Update policy to use for the file,
    +       * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +       * 
    + */ + public com.google.protobuf.ByteString + getReplicaUpdatePolicyBytes() { + java.lang.Object ref = replicaUpdatePolicy_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + replicaUpdatePolicy_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string replica_update_policy = 3; + * + *
    +       * Update policy to use for the file,
    +       * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +       * 
    + */ + public Builder setReplicaUpdatePolicy( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + replicaUpdatePolicy_ = value; + onChanged(); + return this; + } + /** + * required string replica_update_policy = 3; + * + *
    +       * Update policy to use for the file,
    +       * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +       * 
    + */ + public Builder clearReplicaUpdatePolicy() { + bitField0_ = (bitField0_ & ~0x00000004); + replicaUpdatePolicy_ = getDefaultInstance().getReplicaUpdatePolicy(); + onChanged(); + return this; + } + /** + * required string replica_update_policy = 3; + * + *
    +       * Update policy to use for the file,
    +       * see org.xtreemfs.common.ReplicaUpdatePolicies for values.
    +       * 
    + */ + public Builder setReplicaUpdatePolicyBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + replicaUpdatePolicy_ = value; + onChanged(); + return this; + } + + // required fixed32 version = 4; + private int version_ ; + /** + * required fixed32 version = 4; + * + *
    +       * Monotonically increasing version number of a file's XLocSet.
    +       * Used to identify clients with outdates XLocSets.
    +       * 
    + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 version = 4; + * + *
    +       * Monotonically increasing version number of a file's XLocSet.
    +       * Used to identify clients with outdates XLocSets.
    +       * 
    + */ + public int getVersion() { + return version_; + } + /** + * required fixed32 version = 4; + * + *
    +       * Monotonically increasing version number of a file's XLocSet.
    +       * Used to identify clients with outdates XLocSets.
    +       * 
    + */ + public Builder setVersion(int value) { + bitField0_ |= 0x00000008; + version_ = value; + onChanged(); + return this; + } + /** + * required fixed32 version = 4; + * + *
    +       * Monotonically increasing version number of a file's XLocSet.
    +       * Used to identify clients with outdates XLocSets.
    +       * 
    + */ + public Builder clearVersion() { + bitField0_ = (bitField0_ & ~0x00000008); + version_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.XLocSet) + } + + static { + defaultInstance = new XLocSet(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.XLocSet) + } + + public interface FileCredentialsOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.XCap xcap = 1; + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + boolean hasXcap(); + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getXcap(); + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getXcapOrBuilder(); + + // required .xtreemfs.pbrpc.XLocSet xlocs = 2; + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + boolean hasXlocs(); + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet getXlocs(); + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSetOrBuilder getXlocsOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.FileCredentials} + * + *
    +   * Information required by OSDs for all file operations.
    +   * 
    + */ + public static final class FileCredentials extends + com.google.protobuf.GeneratedMessage + implements FileCredentialsOrBuilder { + // Use FileCredentials.newBuilder() to construct. + private FileCredentials(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private FileCredentials(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final FileCredentials defaultInstance; + public static FileCredentials getDefaultInstance() { + return defaultInstance; + } + + public FileCredentials getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private FileCredentials( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = xcap_.toBuilder(); + } + xcap_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(xcap_); + xcap_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = xlocs_.toBuilder(); + } + xlocs_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(xlocs_); + xlocs_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_FileCredentials_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_FileCredentials_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public FileCredentials parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new FileCredentials(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.XCap xcap = 1; + public static final int XCAP_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap xcap_; + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + public boolean hasXcap() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getXcap() { + return xcap_; + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getXcapOrBuilder() { + return xcap_; + } + + // required .xtreemfs.pbrpc.XLocSet xlocs = 2; + public static final int XLOCS_FIELD_NUMBER = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet xlocs_; + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + public boolean hasXlocs() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet getXlocs() { + return xlocs_; + } + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSetOrBuilder getXlocsOrBuilder() { + return xlocs_; + } + + private void initFields() { + xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + xlocs_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasXcap()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasXlocs()) { + memoizedIsInitialized = 0; + return false; + } + if (!getXcap().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getXlocs().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, xcap_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, xlocs_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, xcap_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, xlocs_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.FileCredentials} + * + *
    +     * Information required by OSDs for all file operations.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_FileCredentials_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_FileCredentials_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getXcapFieldBuilder(); + getXlocsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (xcapBuilder_ == null) { + xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + } else { + xcapBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (xlocsBuilder_ == null) { + xlocs_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.getDefaultInstance(); + } else { + xlocsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_FileCredentials_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials build() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials result = new org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (xcapBuilder_ == null) { + result.xcap_ = xcap_; + } else { + result.xcap_ = xcapBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + if (xlocsBuilder_ == null) { + result.xlocs_ = xlocs_; + } else { + result.xlocs_ = xlocsBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) return this; + if (other.hasXcap()) { + mergeXcap(other.getXcap()); + } + if (other.hasXlocs()) { + mergeXlocs(other.getXlocs()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasXcap()) { + + return false; + } + if (!hasXlocs()) { + + return false; + } + if (!getXcap().isInitialized()) { + + return false; + } + if (!getXlocs().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.XCap xcap = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder> xcapBuilder_; + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + public boolean hasXcap() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getXcap() { + if (xcapBuilder_ == null) { + return xcap_; + } else { + return xcapBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + public Builder setXcap(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap value) { + if (xcapBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + xcap_ = value; + onChanged(); + } else { + xcapBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + public Builder setXcap( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder builderForValue) { + if (xcapBuilder_ == null) { + xcap_ = builderForValue.build(); + onChanged(); + } else { + xcapBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + public Builder mergeXcap(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap value) { + if (xcapBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + xcap_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance()) { + xcap_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.newBuilder(xcap_).mergeFrom(value).buildPartial(); + } else { + xcap_ = value; + } + onChanged(); + } else { + xcapBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + public Builder clearXcap() { + if (xcapBuilder_ == null) { + xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + onChanged(); + } else { + xcapBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder getXcapBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getXcapFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getXcapOrBuilder() { + if (xcapBuilder_ != null) { + return xcapBuilder_.getMessageOrBuilder(); + } else { + return xcap_; + } + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder> + getXcapFieldBuilder() { + if (xcapBuilder_ == null) { + xcapBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder>( + xcap_, + getParentForChildren(), + isClean()); + xcap_ = null; + } + return xcapBuilder_; + } + + // required .xtreemfs.pbrpc.XLocSet xlocs = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet xlocs_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSetOrBuilder> xlocsBuilder_; + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + public boolean hasXlocs() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet getXlocs() { + if (xlocsBuilder_ == null) { + return xlocs_; + } else { + return xlocsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + public Builder setXlocs(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet value) { + if (xlocsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + xlocs_ = value; + onChanged(); + } else { + xlocsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + public Builder setXlocs( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.Builder builderForValue) { + if (xlocsBuilder_ == null) { + xlocs_ = builderForValue.build(); + onChanged(); + } else { + xlocsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + public Builder mergeXlocs(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet value) { + if (xlocsBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + xlocs_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.getDefaultInstance()) { + xlocs_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.newBuilder(xlocs_).mergeFrom(value).buildPartial(); + } else { + xlocs_ = value; + } + onChanged(); + } else { + xlocsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + public Builder clearXlocs() { + if (xlocsBuilder_ == null) { + xlocs_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.getDefaultInstance(); + onChanged(); + } else { + xlocsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.Builder getXlocsBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getXlocsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSetOrBuilder getXlocsOrBuilder() { + if (xlocsBuilder_ != null) { + return xlocsBuilder_.getMessageOrBuilder(); + } else { + return xlocs_; + } + } + /** + * required .xtreemfs.pbrpc.XLocSet xlocs = 2; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSetOrBuilder> + getXlocsFieldBuilder() { + if (xlocsBuilder_ == null) { + xlocsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSetOrBuilder>( + xlocs_, + getParentForChildren(), + isClean()); + xlocs_ = null; + } + return xlocsBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.FileCredentials) + } + + static { + defaultInstance = new FileCredentials(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.FileCredentials) + } + + public interface FileCredentialsSetOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.FileCredentialsSet} + */ + public static final class FileCredentialsSet extends + com.google.protobuf.GeneratedMessage + implements FileCredentialsSetOrBuilder { + // Use FileCredentialsSet.newBuilder() to construct. + private FileCredentialsSet(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private FileCredentialsSet(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final FileCredentialsSet defaultInstance; + public static FileCredentialsSet getDefaultInstance() { + return defaultInstance; + } + + public FileCredentialsSet getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private FileCredentialsSet( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_FileCredentialsSet_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_FileCredentialsSet_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public FileCredentialsSet parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new FileCredentialsSet(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (hasFileCredentials()) { + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.FileCredentialsSet} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSetOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_FileCredentialsSet_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_FileCredentialsSet_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_FileCredentialsSet_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet build() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet result = new org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (hasFileCredentials()) { + if (!getFileCredentials().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsSet) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * optional .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.FileCredentialsSet) + } + + static { + defaultInstance = new FileCredentialsSet(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.FileCredentialsSet) + } + + public interface VivaldiCoordinatesOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required double x_coordinate = 1; + /** + * required double x_coordinate = 1; + */ + boolean hasXCoordinate(); + /** + * required double x_coordinate = 1; + */ + double getXCoordinate(); + + // required double y_coordinate = 2; + /** + * required double y_coordinate = 2; + */ + boolean hasYCoordinate(); + /** + * required double y_coordinate = 2; + */ + double getYCoordinate(); + + // required double local_error = 3; + /** + * required double local_error = 3; + */ + boolean hasLocalError(); + /** + * required double local_error = 3; + */ + double getLocalError(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.VivaldiCoordinates} + * + *
    +   * Network coordinates to estimate the latency.
    +   * 
    + */ + public static final class VivaldiCoordinates extends + com.google.protobuf.GeneratedMessage + implements VivaldiCoordinatesOrBuilder { + // Use VivaldiCoordinates.newBuilder() to construct. + private VivaldiCoordinates(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private VivaldiCoordinates(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final VivaldiCoordinates defaultInstance; + public static VivaldiCoordinates getDefaultInstance() { + return defaultInstance; + } + + public VivaldiCoordinates getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private VivaldiCoordinates( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + xCoordinate_ = input.readDouble(); + break; + } + case 17: { + bitField0_ |= 0x00000002; + yCoordinate_ = input.readDouble(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + localError_ = input.readDouble(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_VivaldiCoordinates_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_VivaldiCoordinates_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public VivaldiCoordinates parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new VivaldiCoordinates(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required double x_coordinate = 1; + public static final int X_COORDINATE_FIELD_NUMBER = 1; + private double xCoordinate_; + /** + * required double x_coordinate = 1; + */ + public boolean hasXCoordinate() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required double x_coordinate = 1; + */ + public double getXCoordinate() { + return xCoordinate_; + } + + // required double y_coordinate = 2; + public static final int Y_COORDINATE_FIELD_NUMBER = 2; + private double yCoordinate_; + /** + * required double y_coordinate = 2; + */ + public boolean hasYCoordinate() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required double y_coordinate = 2; + */ + public double getYCoordinate() { + return yCoordinate_; + } + + // required double local_error = 3; + public static final int LOCAL_ERROR_FIELD_NUMBER = 3; + private double localError_; + /** + * required double local_error = 3; + */ + public boolean hasLocalError() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required double local_error = 3; + */ + public double getLocalError() { + return localError_; + } + + private void initFields() { + xCoordinate_ = 0D; + yCoordinate_ = 0D; + localError_ = 0D; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasXCoordinate()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasYCoordinate()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLocalError()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeDouble(1, xCoordinate_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeDouble(2, yCoordinate_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeDouble(3, localError_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeDoubleSize(1, xCoordinate_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeDoubleSize(2, yCoordinate_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeDoubleSize(3, localError_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.VivaldiCoordinates} + * + *
    +     * Network coordinates to estimate the latency.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_VivaldiCoordinates_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_VivaldiCoordinates_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + xCoordinate_ = 0D; + bitField0_ = (bitField0_ & ~0x00000001); + yCoordinate_ = 0D; + bitField0_ = (bitField0_ & ~0x00000002); + localError_ = 0D; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_VivaldiCoordinates_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates build() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates result = new org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.xCoordinate_ = xCoordinate_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.yCoordinate_ = yCoordinate_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.localError_ = localError_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance()) return this; + if (other.hasXCoordinate()) { + setXCoordinate(other.getXCoordinate()); + } + if (other.hasYCoordinate()) { + setYCoordinate(other.getYCoordinate()); + } + if (other.hasLocalError()) { + setLocalError(other.getLocalError()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasXCoordinate()) { + + return false; + } + if (!hasYCoordinate()) { + + return false; + } + if (!hasLocalError()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required double x_coordinate = 1; + private double xCoordinate_ ; + /** + * required double x_coordinate = 1; + */ + public boolean hasXCoordinate() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required double x_coordinate = 1; + */ + public double getXCoordinate() { + return xCoordinate_; + } + /** + * required double x_coordinate = 1; + */ + public Builder setXCoordinate(double value) { + bitField0_ |= 0x00000001; + xCoordinate_ = value; + onChanged(); + return this; + } + /** + * required double x_coordinate = 1; + */ + public Builder clearXCoordinate() { + bitField0_ = (bitField0_ & ~0x00000001); + xCoordinate_ = 0D; + onChanged(); + return this; + } + + // required double y_coordinate = 2; + private double yCoordinate_ ; + /** + * required double y_coordinate = 2; + */ + public boolean hasYCoordinate() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required double y_coordinate = 2; + */ + public double getYCoordinate() { + return yCoordinate_; + } + /** + * required double y_coordinate = 2; + */ + public Builder setYCoordinate(double value) { + bitField0_ |= 0x00000002; + yCoordinate_ = value; + onChanged(); + return this; + } + /** + * required double y_coordinate = 2; + */ + public Builder clearYCoordinate() { + bitField0_ = (bitField0_ & ~0x00000002); + yCoordinate_ = 0D; + onChanged(); + return this; + } + + // required double local_error = 3; + private double localError_ ; + /** + * required double local_error = 3; + */ + public boolean hasLocalError() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required double local_error = 3; + */ + public double getLocalError() { + return localError_; + } + /** + * required double local_error = 3; + */ + public Builder setLocalError(double value) { + bitField0_ |= 0x00000004; + localError_ = value; + onChanged(); + return this; + } + /** + * required double local_error = 3; + */ + public Builder clearLocalError() { + bitField0_ = (bitField0_ & ~0x00000004); + localError_ = 0D; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.VivaldiCoordinates) + } + + static { + defaultInstance = new VivaldiCoordinates(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.VivaldiCoordinates) + } + + public interface OSDWriteResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional fixed64 size_in_bytes = 1; + /** + * optional fixed64 size_in_bytes = 1; + * + *
    +     * Current file size in bytes.
    +     * 
    + */ + boolean hasSizeInBytes(); + /** + * optional fixed64 size_in_bytes = 1; + * + *
    +     * Current file size in bytes.
    +     * 
    + */ + long getSizeInBytes(); + + // optional fixed32 truncate_epoch = 2; + /** + * optional fixed32 truncate_epoch = 2; + * + *
    +     * Truncate epoch.
    +     * 
    + */ + boolean hasTruncateEpoch(); + /** + * optional fixed32 truncate_epoch = 2; + * + *
    +     * Truncate epoch.
    +     * 
    + */ + int getTruncateEpoch(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.OSDWriteResponse} + * + *
    +   * Response returned by OSD write and truncate operations.
    +   * This information is stored by the client and must be
    +   * relayed to the MRC in regular intervals or when the file
    +   * is fsynced or closed.
    +   * In addition, the client must use this information locally
    +   * for open files to provide processes with an accurate
    +   * file size.
    +   * Clients only need to store and relay the most recent OSDWriteResponse.
    +   * These are sorted first by truncate_epoch and then by size_in_bytes, both ascending.
    +   * 
    + */ + public static final class OSDWriteResponse extends + com.google.protobuf.GeneratedMessage + implements OSDWriteResponseOrBuilder { + // Use OSDWriteResponse.newBuilder() to construct. + private OSDWriteResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private OSDWriteResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final OSDWriteResponse defaultInstance; + public static OSDWriteResponse getDefaultInstance() { + return defaultInstance; + } + + public OSDWriteResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private OSDWriteResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + sizeInBytes_ = input.readFixed64(); + break; + } + case 21: { + bitField0_ |= 0x00000002; + truncateEpoch_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_OSDWriteResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_OSDWriteResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public OSDWriteResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new OSDWriteResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional fixed64 size_in_bytes = 1; + public static final int SIZE_IN_BYTES_FIELD_NUMBER = 1; + private long sizeInBytes_; + /** + * optional fixed64 size_in_bytes = 1; + * + *
    +     * Current file size in bytes.
    +     * 
    + */ + public boolean hasSizeInBytes() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional fixed64 size_in_bytes = 1; + * + *
    +     * Current file size in bytes.
    +     * 
    + */ + public long getSizeInBytes() { + return sizeInBytes_; + } + + // optional fixed32 truncate_epoch = 2; + public static final int TRUNCATE_EPOCH_FIELD_NUMBER = 2; + private int truncateEpoch_; + /** + * optional fixed32 truncate_epoch = 2; + * + *
    +     * Truncate epoch.
    +     * 
    + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional fixed32 truncate_epoch = 2; + * + *
    +     * Truncate epoch.
    +     * 
    + */ + public int getTruncateEpoch() { + return truncateEpoch_; + } + + private void initFields() { + sizeInBytes_ = 0L; + truncateEpoch_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, sizeInBytes_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed32(2, truncateEpoch_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, sizeInBytes_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(2, truncateEpoch_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.OSDWriteResponse} + * + *
    +     * Response returned by OSD write and truncate operations.
    +     * This information is stored by the client and must be
    +     * relayed to the MRC in regular intervals or when the file
    +     * is fsynced or closed.
    +     * In addition, the client must use this information locally
    +     * for open files to provide processes with an accurate
    +     * file size.
    +     * Clients only need to store and relay the most recent OSDWriteResponse.
    +     * These are sorted first by truncate_epoch and then by size_in_bytes, both ascending.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_OSDWriteResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_OSDWriteResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + sizeInBytes_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + truncateEpoch_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_OSDWriteResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.sizeInBytes_ = sizeInBytes_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.truncateEpoch_ = truncateEpoch_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.getDefaultInstance()) return this; + if (other.hasSizeInBytes()) { + setSizeInBytes(other.getSizeInBytes()); + } + if (other.hasTruncateEpoch()) { + setTruncateEpoch(other.getTruncateEpoch()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional fixed64 size_in_bytes = 1; + private long sizeInBytes_ ; + /** + * optional fixed64 size_in_bytes = 1; + * + *
    +       * Current file size in bytes.
    +       * 
    + */ + public boolean hasSizeInBytes() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional fixed64 size_in_bytes = 1; + * + *
    +       * Current file size in bytes.
    +       * 
    + */ + public long getSizeInBytes() { + return sizeInBytes_; + } + /** + * optional fixed64 size_in_bytes = 1; + * + *
    +       * Current file size in bytes.
    +       * 
    + */ + public Builder setSizeInBytes(long value) { + bitField0_ |= 0x00000001; + sizeInBytes_ = value; + onChanged(); + return this; + } + /** + * optional fixed64 size_in_bytes = 1; + * + *
    +       * Current file size in bytes.
    +       * 
    + */ + public Builder clearSizeInBytes() { + bitField0_ = (bitField0_ & ~0x00000001); + sizeInBytes_ = 0L; + onChanged(); + return this; + } + + // optional fixed32 truncate_epoch = 2; + private int truncateEpoch_ ; + /** + * optional fixed32 truncate_epoch = 2; + * + *
    +       * Truncate epoch.
    +       * 
    + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional fixed32 truncate_epoch = 2; + * + *
    +       * Truncate epoch.
    +       * 
    + */ + public int getTruncateEpoch() { + return truncateEpoch_; + } + /** + * optional fixed32 truncate_epoch = 2; + * + *
    +       * Truncate epoch.
    +       * 
    + */ + public Builder setTruncateEpoch(int value) { + bitField0_ |= 0x00000002; + truncateEpoch_ = value; + onChanged(); + return this; + } + /** + * optional fixed32 truncate_epoch = 2; + * + *
    +       * Truncate epoch.
    +       * 
    + */ + public Builder clearTruncateEpoch() { + bitField0_ = (bitField0_ & ~0x00000002); + truncateEpoch_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.OSDWriteResponse) + } + + static { + defaultInstance = new OSDWriteResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.OSDWriteResponse) + } + + public interface KeyValuePairOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string key = 1; + /** + * required string key = 1; + */ + boolean hasKey(); + /** + * required string key = 1; + */ + java.lang.String getKey(); + /** + * required string key = 1; + */ + com.google.protobuf.ByteString + getKeyBytes(); + + // required string value = 2; + /** + * required string value = 2; + */ + boolean hasValue(); + /** + * required string value = 2; + */ + java.lang.String getValue(); + /** + * required string value = 2; + */ + com.google.protobuf.ByteString + getValueBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.KeyValuePair} + * + *
    +   * Simple key/value pair. Protobuf doesn't provide a map type.
    +   * 
    + */ + public static final class KeyValuePair extends + com.google.protobuf.GeneratedMessage + implements KeyValuePairOrBuilder { + // Use KeyValuePair.newBuilder() to construct. + private KeyValuePair(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private KeyValuePair(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final KeyValuePair defaultInstance; + public static KeyValuePair getDefaultInstance() { + return defaultInstance; + } + + public KeyValuePair getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private KeyValuePair( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + key_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + value_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_KeyValuePair_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_KeyValuePair_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public KeyValuePair parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new KeyValuePair(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string key = 1; + public static final int KEY_FIELD_NUMBER = 1; + private java.lang.Object key_; + /** + * required string key = 1; + */ + public boolean hasKey() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string key = 1; + */ + public java.lang.String getKey() { + java.lang.Object ref = key_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + key_ = s; + } + return s; + } + } + /** + * required string key = 1; + */ + public com.google.protobuf.ByteString + getKeyBytes() { + java.lang.Object ref = key_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + key_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string value = 2; + public static final int VALUE_FIELD_NUMBER = 2; + private java.lang.Object value_; + /** + * required string value = 2; + */ + public boolean hasValue() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string value = 2; + */ + public java.lang.String getValue() { + java.lang.Object ref = value_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + value_ = s; + } + return s; + } + } + /** + * required string value = 2; + */ + public com.google.protobuf.ByteString + getValueBytes() { + java.lang.Object ref = value_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + value_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + key_ = ""; + value_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasKey()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasValue()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getKeyBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getValueBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getKeyBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getValueBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.KeyValuePair} + * + *
    +     * Simple key/value pair. Protobuf doesn't provide a map type.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_KeyValuePair_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_KeyValuePair_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.class, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + key_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + value_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.internal_static_xtreemfs_pbrpc_KeyValuePair_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair build() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair result = new org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.key_ = key_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.value_ = value_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.getDefaultInstance()) return this; + if (other.hasKey()) { + bitField0_ |= 0x00000001; + key_ = other.key_; + onChanged(); + } + if (other.hasValue()) { + bitField0_ |= 0x00000002; + value_ = other.value_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasKey()) { + + return false; + } + if (!hasValue()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string key = 1; + private java.lang.Object key_ = ""; + /** + * required string key = 1; + */ + public boolean hasKey() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string key = 1; + */ + public java.lang.String getKey() { + java.lang.Object ref = key_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + key_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string key = 1; + */ + public com.google.protobuf.ByteString + getKeyBytes() { + java.lang.Object ref = key_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + key_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string key = 1; + */ + public Builder setKey( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + key_ = value; + onChanged(); + return this; + } + /** + * required string key = 1; + */ + public Builder clearKey() { + bitField0_ = (bitField0_ & ~0x00000001); + key_ = getDefaultInstance().getKey(); + onChanged(); + return this; + } + /** + * required string key = 1; + */ + public Builder setKeyBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + key_ = value; + onChanged(); + return this; + } + + // required string value = 2; + private java.lang.Object value_ = ""; + /** + * required string value = 2; + */ + public boolean hasValue() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string value = 2; + */ + public java.lang.String getValue() { + java.lang.Object ref = value_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + value_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string value = 2; + */ + public com.google.protobuf.ByteString + getValueBytes() { + java.lang.Object ref = value_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + value_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string value = 2; + */ + public Builder setValue( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + value_ = value; + onChanged(); + return this; + } + /** + * required string value = 2; + */ + public Builder clearValue() { + bitField0_ = (bitField0_ & ~0x00000002); + value_ = getDefaultInstance().getValue(); + onChanged(); + return this; + } + /** + * required string value = 2; + */ + public Builder setValueBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + value_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.KeyValuePair) + } + + static { + defaultInstance = new KeyValuePair(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.KeyValuePair) + } + + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_NewFileSize_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_NewFileSize_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_StripingPolicy_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_StripingPolicy_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_Replica_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_Replica_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_Replicas_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_Replicas_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_XCap_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_XCap_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_XLocSet_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_XLocSet_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_FileCredentials_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_FileCredentials_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_FileCredentialsSet_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_FileCredentialsSet_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_VivaldiCoordinates_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_VivaldiCoordinates_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_OSDWriteResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_OSDWriteResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_KeyValuePair_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_KeyValuePair_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\032xtreemfs/GlobalTypes.proto\022\016xtreemfs.p" + + "brpc\032\023include/PBRPC.proto\032\024include/Commo" + + "n.proto\"<\n\013NewFileSize\022\025\n\rsize_in_bytes\030" + + "\001 \002(\006\022\026\n\016truncate_epoch\030\002 \002(\007\"|\n\016Stripin" + + "gPolicy\0220\n\004type\030\001 \002(\0162\".xtreemfs.pbrpc.S" + + "tripingPolicyType\022\023\n\013stripe_size\030\002 \002(\007\022\r" + + "\n\005width\030\003 \002(\007\022\024\n\014parity_width\030\004 \001(\007\"p\n\007R" + + "eplica\022\021\n\tosd_uuids\030\001 \003(\t\022\031\n\021replication" + + "_flags\030\002 \002(\007\0227\n\017striping_policy\030\003 \002(\0132\036." + + "xtreemfs.pbrpc.StripingPolicy\"5\n\010Replica", + "s\022)\n\010replicas\030\001 \003(\0132\027.xtreemfs.pbrpc.Rep" + + "lica\"\215\002\n\004XCap\022\023\n\013access_mode\030\001 \002(\007\022\027\n\017cl" + + "ient_identity\030\002 \002(\t\022\025\n\rexpire_time_s\030\003 \002" + + "(\006\022\030\n\020expire_timeout_s\030\004 \002(\007\022\017\n\007file_id\030" + + "\005 \002(\t\022\032\n\022replicate_on_close\030\006 \002(\010\022\030\n\020ser" + + "ver_signature\030\007 \002(\t\022\026\n\016truncate_epoch\030\010 " + + "\002(\007\022/\n\013snap_config\030\t \002(\0162\032.xtreemfs.pbrp" + + "c.SnapConfig\022\026\n\016snap_timestamp\030\n \002(\006\"\201\001\n" + + "\007XLocSet\022\033\n\023read_only_file_size\030\001 \002(\006\022)\n" + + "\010replicas\030\002 \003(\0132\027.xtreemfs.pbrpc.Replica", + "\022\035\n\025replica_update_policy\030\003 \002(\t\022\017\n\007versi" + + "on\030\004 \002(\007\"]\n\017FileCredentials\022\"\n\004xcap\030\001 \002(" + + "\0132\024.xtreemfs.pbrpc.XCap\022&\n\005xlocs\030\002 \002(\0132\027" + + ".xtreemfs.pbrpc.XLocSet\"O\n\022FileCredentia" + + "lsSet\0229\n\020file_credentials\030\001 \001(\0132\037.xtreem" + + "fs.pbrpc.FileCredentials\"U\n\022VivaldiCoord" + + "inates\022\024\n\014x_coordinate\030\001 \002(\001\022\024\n\014y_coordi" + + "nate\030\002 \002(\001\022\023\n\013local_error\030\003 \002(\001\"A\n\020OSDWr" + + "iteResponse\022\025\n\rsize_in_bytes\030\001 \001(\006\022\026\n\016tr" + + "uncate_epoch\030\002 \001(\007\"*\n\014KeyValuePair\022\013\n\003ke", + "y\030\001 \002(\t\022\r\n\005value\030\002 \002(\t*|\n\027AccessControlP" + + "olicyType\022\036\n\032ACCESS_CONTROL_POLICY_NULL\020" + + "\001\022\037\n\033ACCESS_CONTROL_POLICY_POSIX\020\002\022 \n\034AC" + + "CESS_CONTROL_POLICY_VOLUME\020\003*\365\003\n\026OSDSele" + + "ctionPolicyType\022(\n#OSD_SELECTION_POLICY_" + + "FILTER_DEFAULT\020\350\007\022%\n OSD_SELECTION_POLIC" + + "Y_FILTER_FQDN\020\351\007\022%\n OSD_SELECTION_POLICY" + + "_FILTER_UUID\020\352\007\022%\n OSD_SELECTION_POLICY_" + + "GROUP_DCMAP\020\320\017\022$\n\037OSD_SELECTION_POLICY_G" + + "ROUP_FQDN\020\321\017\022$\n\037OSD_SELECTION_POLICY_SOR", + "T_DCMAP\020\270\027\022#\n\036OSD_SELECTION_POLICY_SORT_" + + "FQDN\020\271\027\022%\n OSD_SELECTION_POLICY_SORT_RAN" + + "DOM\020\272\027\022&\n!OSD_SELECTION_POLICY_SORT_VIVA" + + "LDI\020\273\027\022/\n*OSD_SELECTION_POLICY_SORT_HOST" + + "_ROUND_ROBIN\020\274\027\022#\n\036OSD_SELECTION_POLICY_" + + "SORT_UUID\020\236\037\022&\n!OSD_SELECTION_POLICY_SOR" + + "T_REVERSE\020\237\037*A\n\032ReplicaSelectionPolicyTy" + + "pe\022#\n\037REPLICA_SELECTION_POLICY_SIMPLE\020\001*" + + "i\n\nSnapConfig\022\036\n\032SNAP_CONFIG_SNAPS_DISAB" + + "LED\020\000\022\036\n\032SNAP_CONFIG_ACCESS_CURRENT\020\001\022\033\n", + "\027SNAP_CONFIG_ACCESS_SNAP\020\002*P\n\022StripingPo" + + "licyType\022\031\n\025STRIPING_POLICY_RAID0\020\000\022\037\n\033S" + + "TRIPING_POLICY_ERASURECODE\020\001*9\n\nLeaseSta" + + "te\022\010\n\004NONE\020\000\022\013\n\007PRIMARY\020\001\022\n\n\006BACKUP\020\002\022\010\n" + + "\004IDLE\020\003*\270\001\n\005PORTS\022\033\n\025DIR_HTTP_PORT_DEFAU" + + "LT\020\256\357\001\022\034\n\026DIR_PBRPC_PORT_DEFAULT\020\376\376\001\022\033\n\025" + + "MRC_HTTP_PORT_DEFAULT\020\254\357\001\022\034\n\026MRC_PBRPC_P" + + "ORT_DEFAULT\020\374\376\001\022\033\n\025OSD_HTTP_PORT_DEFAULT" + + "\020\260\357\001\022\034\n\026OSD_PBRPC_PORT_DEFAULT\020\200\377\001*+\n\tCO" + + "NSTANTS\022\036\n\032XCAP_RENEW_INTERVAL_IN_MIN\020\001*", + "\202\003\n\016SYSTEM_V_FCNTL\022\035\n\031SYSTEM_V_FCNTL_H_O" + + "_RDONLY\020\000\022\035\n\031SYSTEM_V_FCNTL_H_O_WRONLY\020\001" + + "\022\033\n\027SYSTEM_V_FCNTL_H_O_RDWR\020\002\022\035\n\031SYSTEM_" + + "V_FCNTL_H_O_APPEND\020\010\022\035\n\030SYSTEM_V_FCNTL_H" + + "_O_CREAT\020\200\002\022\035\n\030SYSTEM_V_FCNTL_H_O_TRUNC\020" + + "\200\004\022\034\n\027SYSTEM_V_FCNTL_H_O_EXCL\020\200\010\022\033\n\027SYST" + + "EM_V_FCNTL_H_O_SYNC\020\020\022\036\n\030SYSTEM_V_FCNTL_" + + "H_S_IFREG\020\200\200\002\022\036\n\030SYSTEM_V_FCNTL_H_S_IFDI" + + "R\020\200\200\001\022\036\n\030SYSTEM_V_FCNTL_H_S_IFLNK\020\200\300\002\022\035\n" + + "\030SYSTEM_V_FCNTL_H_S_IFIFO\020\200 *\330\001\n\tREPL_FL", + "AG\022\032\n\026REPL_FLAG_FULL_REPLICA\020\001\022\031\n\025REPL_F" + + "LAG_IS_COMPLETE\020\002\022\035\n\031REPL_FLAG_STRATEGY_" + + "RANDOM\020\004\022#\n\037REPL_FLAG_STRATEGY_RAREST_FI" + + "RST\020\010\022!\n\035REPL_FLAG_STRATEGY_SEQUENTIAL\020\020" + + "\022-\n)REPL_FLAG_STRATEGY_SEQUENTIAL_PREFET" + + "CHING\020 *%\n\010SERVICES\022\007\n\003DIR\020\001\022\007\n\003MRC\020\002\022\007\n" + + "\003OSD\020\003B(\n&org.xtreemfs.pbrpc.generatedin" + + "terfaces" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_xtreemfs_pbrpc_NewFileSize_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_xtreemfs_pbrpc_NewFileSize_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_NewFileSize_descriptor, + new java.lang.String[] { "SizeInBytes", "TruncateEpoch", }); + internal_static_xtreemfs_pbrpc_StripingPolicy_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_xtreemfs_pbrpc_StripingPolicy_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_StripingPolicy_descriptor, + new java.lang.String[] { "Type", "StripeSize", "Width", "ParityWidth", }); + internal_static_xtreemfs_pbrpc_Replica_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_xtreemfs_pbrpc_Replica_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_Replica_descriptor, + new java.lang.String[] { "OsdUuids", "ReplicationFlags", "StripingPolicy", }); + internal_static_xtreemfs_pbrpc_Replicas_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_xtreemfs_pbrpc_Replicas_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_Replicas_descriptor, + new java.lang.String[] { "Replicas", }); + internal_static_xtreemfs_pbrpc_XCap_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_xtreemfs_pbrpc_XCap_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_XCap_descriptor, + new java.lang.String[] { "AccessMode", "ClientIdentity", "ExpireTimeS", "ExpireTimeoutS", "FileId", "ReplicateOnClose", "ServerSignature", "TruncateEpoch", "SnapConfig", "SnapTimestamp", }); + internal_static_xtreemfs_pbrpc_XLocSet_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_xtreemfs_pbrpc_XLocSet_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_XLocSet_descriptor, + new java.lang.String[] { "ReadOnlyFileSize", "Replicas", "ReplicaUpdatePolicy", "Version", }); + internal_static_xtreemfs_pbrpc_FileCredentials_descriptor = + getDescriptor().getMessageTypes().get(6); + internal_static_xtreemfs_pbrpc_FileCredentials_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_FileCredentials_descriptor, + new java.lang.String[] { "Xcap", "Xlocs", }); + internal_static_xtreemfs_pbrpc_FileCredentialsSet_descriptor = + getDescriptor().getMessageTypes().get(7); + internal_static_xtreemfs_pbrpc_FileCredentialsSet_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_FileCredentialsSet_descriptor, + new java.lang.String[] { "FileCredentials", }); + internal_static_xtreemfs_pbrpc_VivaldiCoordinates_descriptor = + getDescriptor().getMessageTypes().get(8); + internal_static_xtreemfs_pbrpc_VivaldiCoordinates_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_VivaldiCoordinates_descriptor, + new java.lang.String[] { "XCoordinate", "YCoordinate", "LocalError", }); + internal_static_xtreemfs_pbrpc_OSDWriteResponse_descriptor = + getDescriptor().getMessageTypes().get(9); + internal_static_xtreemfs_pbrpc_OSDWriteResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_OSDWriteResponse_descriptor, + new java.lang.String[] { "SizeInBytes", "TruncateEpoch", }); + internal_static_xtreemfs_pbrpc_KeyValuePair_descriptor = + getDescriptor().getMessageTypes().get(10); + internal_static_xtreemfs_pbrpc_KeyValuePair_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_KeyValuePair_descriptor, + new java.lang.String[] { "Key", "Value", }); + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.getDescriptor(), + org.xtreemfs.pbrpc.generatedinterfaces.Common.getDescriptor(), + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRC.java b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRC.java new file mode 100644 index 0000000..4517028 --- /dev/null +++ b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRC.java @@ -0,0 +1,48656 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/MRC.proto + +package org.xtreemfs.pbrpc.generatedinterfaces; + +public final class MRC { + private MRC() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + /** + * Protobuf enum {@code xtreemfs.pbrpc.Setattrs} + * + *
    +   * flags for setattr request
    +   * 
    + */ + public enum Setattrs + implements com.google.protobuf.ProtocolMessageEnum { + /** + * SETATTR_MODE = 1; + */ + SETATTR_MODE(0, 1), + /** + * SETATTR_UID = 2; + */ + SETATTR_UID(1, 2), + /** + * SETATTR_GID = 4; + */ + SETATTR_GID(2, 4), + /** + * SETATTR_SIZE = 8; + */ + SETATTR_SIZE(3, 8), + /** + * SETATTR_ATIME = 16; + */ + SETATTR_ATIME(4, 16), + /** + * SETATTR_MTIME = 32; + */ + SETATTR_MTIME(5, 32), + /** + * SETATTR_CTIME = 64; + */ + SETATTR_CTIME(6, 64), + /** + * SETATTR_ATTRIBUTES = 128; + */ + SETATTR_ATTRIBUTES(7, 128), + ; + + /** + * SETATTR_MODE = 1; + */ + public static final int SETATTR_MODE_VALUE = 1; + /** + * SETATTR_UID = 2; + */ + public static final int SETATTR_UID_VALUE = 2; + /** + * SETATTR_GID = 4; + */ + public static final int SETATTR_GID_VALUE = 4; + /** + * SETATTR_SIZE = 8; + */ + public static final int SETATTR_SIZE_VALUE = 8; + /** + * SETATTR_ATIME = 16; + */ + public static final int SETATTR_ATIME_VALUE = 16; + /** + * SETATTR_MTIME = 32; + */ + public static final int SETATTR_MTIME_VALUE = 32; + /** + * SETATTR_CTIME = 64; + */ + public static final int SETATTR_CTIME_VALUE = 64; + /** + * SETATTR_ATTRIBUTES = 128; + */ + public static final int SETATTR_ATTRIBUTES_VALUE = 128; + + + public final int getNumber() { return value; } + + public static Setattrs valueOf(int value) { + switch (value) { + case 1: return SETATTR_MODE; + case 2: return SETATTR_UID; + case 4: return SETATTR_GID; + case 8: return SETATTR_SIZE; + case 16: return SETATTR_ATIME; + case 32: return SETATTR_MTIME; + case 64: return SETATTR_CTIME; + case 128: return SETATTR_ATTRIBUTES; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public Setattrs findValueByNumber(int number) { + return Setattrs.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.getDescriptor().getEnumTypes().get(0); + } + + private static final Setattrs[] VALUES = values(); + + public static Setattrs valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private Setattrs(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.Setattrs) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.XATTR_FLAGS} + * + *
    +   * flags for setxattr request
    +   * 
    + */ + public enum XATTR_FLAGS + implements com.google.protobuf.ProtocolMessageEnum { + /** + * XATTR_FLAGS_CREATE = 1; + */ + XATTR_FLAGS_CREATE(0, 1), + /** + * XATTR_FLAGS_REPLACE = 2; + */ + XATTR_FLAGS_REPLACE(1, 2), + ; + + /** + * XATTR_FLAGS_CREATE = 1; + */ + public static final int XATTR_FLAGS_CREATE_VALUE = 1; + /** + * XATTR_FLAGS_REPLACE = 2; + */ + public static final int XATTR_FLAGS_REPLACE_VALUE = 2; + + + public final int getNumber() { return value; } + + public static XATTR_FLAGS valueOf(int value) { + switch (value) { + case 1: return XATTR_FLAGS_CREATE; + case 2: return XATTR_FLAGS_REPLACE; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public XATTR_FLAGS findValueByNumber(int number) { + return XATTR_FLAGS.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.getDescriptor().getEnumTypes().get(1); + } + + private static final XATTR_FLAGS[] VALUES = values(); + + public static XATTR_FLAGS valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private XATTR_FLAGS(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.XATTR_FLAGS) + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.ACCESS_FLAGS} + * + *
    +   * flags for the 'access' call
    +   * 
    + */ + public enum ACCESS_FLAGS + implements com.google.protobuf.ProtocolMessageEnum { + /** + * ACCESS_FLAGS_F_OK = 0; + * + *
    +     * existence
    +     * 
    + */ + ACCESS_FLAGS_F_OK(0, 0), + /** + * ACCESS_FLAGS_X_OK = 1; + * + *
    +     * execute permission
    +     * 
    + */ + ACCESS_FLAGS_X_OK(1, 1), + /** + * ACCESS_FLAGS_W_OK = 2; + * + *
    +     * write permission
    +     * 
    + */ + ACCESS_FLAGS_W_OK(2, 2), + /** + * ACCESS_FLAGS_R_OK = 4; + * + *
    +     * read permission
    +     * 
    + */ + ACCESS_FLAGS_R_OK(3, 4), + ; + + /** + * ACCESS_FLAGS_F_OK = 0; + * + *
    +     * existence
    +     * 
    + */ + public static final int ACCESS_FLAGS_F_OK_VALUE = 0; + /** + * ACCESS_FLAGS_X_OK = 1; + * + *
    +     * execute permission
    +     * 
    + */ + public static final int ACCESS_FLAGS_X_OK_VALUE = 1; + /** + * ACCESS_FLAGS_W_OK = 2; + * + *
    +     * write permission
    +     * 
    + */ + public static final int ACCESS_FLAGS_W_OK_VALUE = 2; + /** + * ACCESS_FLAGS_R_OK = 4; + * + *
    +     * read permission
    +     * 
    + */ + public static final int ACCESS_FLAGS_R_OK_VALUE = 4; + + + public final int getNumber() { return value; } + + public static ACCESS_FLAGS valueOf(int value) { + switch (value) { + case 0: return ACCESS_FLAGS_F_OK; + case 1: return ACCESS_FLAGS_X_OK; + case 2: return ACCESS_FLAGS_W_OK; + case 4: return ACCESS_FLAGS_R_OK; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public ACCESS_FLAGS findValueByNumber(int number) { + return ACCESS_FLAGS.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.getDescriptor().getEnumTypes().get(2); + } + + private static final ACCESS_FLAGS[] VALUES = values(); + + public static ACCESS_FLAGS valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private ACCESS_FLAGS(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.ACCESS_FLAGS) + } + + public interface StatOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 dev = 1; + /** + * required fixed64 dev = 1; + * + *
    +     * device number; represented by a hash of the volume id
    +     * 
    + */ + boolean hasDev(); + /** + * required fixed64 dev = 1; + * + *
    +     * device number; represented by a hash of the volume id
    +     * 
    + */ + long getDev(); + + // required fixed64 ino = 2; + /** + * required fixed64 ino = 2; + * + *
    +     * inode number; represented by the file ID
    +     * 
    + */ + boolean hasIno(); + /** + * required fixed64 ino = 2; + * + *
    +     * inode number; represented by the file ID
    +     * 
    + */ + long getIno(); + + // required fixed32 mode = 3; + /** + * required fixed32 mode = 3; + * + *
    +     * POSIX access mode
    +     * 
    + */ + boolean hasMode(); + /** + * required fixed32 mode = 3; + * + *
    +     * POSIX access mode
    +     * 
    + */ + int getMode(); + + // required fixed32 nlink = 4; + /** + * required fixed32 nlink = 4; + * + *
    +     * hardlink count
    +     * 
    + */ + boolean hasNlink(); + /** + * required fixed32 nlink = 4; + * + *
    +     * hardlink count
    +     * 
    + */ + int getNlink(); + + // required string user_id = 5; + /** + * required string user_id = 5; + * + *
    +     * owning user ID
    +     * 
    + */ + boolean hasUserId(); + /** + * required string user_id = 5; + * + *
    +     * owning user ID
    +     * 
    + */ + java.lang.String getUserId(); + /** + * required string user_id = 5; + * + *
    +     * owning user ID
    +     * 
    + */ + com.google.protobuf.ByteString + getUserIdBytes(); + + // required string group_id = 6; + /** + * required string group_id = 6; + * + *
    +     * owning group ID
    +     * 
    + */ + boolean hasGroupId(); + /** + * required string group_id = 6; + * + *
    +     * owning group ID
    +     * 
    + */ + java.lang.String getGroupId(); + /** + * required string group_id = 6; + * + *
    +     * owning group ID
    +     * 
    + */ + com.google.protobuf.ByteString + getGroupIdBytes(); + + // required fixed64 size = 7; + /** + * required fixed64 size = 7; + * + *
    +     * file size
    +     * 
    + */ + boolean hasSize(); + /** + * required fixed64 size = 7; + * + *
    +     * file size
    +     * 
    + */ + long getSize(); + + // required fixed64 atime_ns = 8; + /** + * required fixed64 atime_ns = 8; + * + *
    +     * atime (access time) in nanoseconds since 1970
    +     * 
    + */ + boolean hasAtimeNs(); + /** + * required fixed64 atime_ns = 8; + * + *
    +     * atime (access time) in nanoseconds since 1970
    +     * 
    + */ + long getAtimeNs(); + + // required fixed64 mtime_ns = 9; + /** + * required fixed64 mtime_ns = 9; + * + *
    +     * mtime (data modification time) in nanoseconds since 1970
    +     * 
    + */ + boolean hasMtimeNs(); + /** + * required fixed64 mtime_ns = 9; + * + *
    +     * mtime (data modification time) in nanoseconds since 1970
    +     * 
    + */ + long getMtimeNs(); + + // required fixed64 ctime_ns = 10; + /** + * required fixed64 ctime_ns = 10; + * + *
    +     * ctime (inode change time) in nanoseconds since 1970
    +     * 
    + */ + boolean hasCtimeNs(); + /** + * required fixed64 ctime_ns = 10; + * + *
    +     * ctime (inode change time) in nanoseconds since 1970
    +     * 
    + */ + long getCtimeNs(); + + // required fixed32 blksize = 11; + /** + * required fixed32 blksize = 11; + * + *
    +     * block size; represented by the stripe size
    +     * 
    + */ + boolean hasBlksize(); + /** + * required fixed32 blksize = 11; + * + *
    +     * block size; represented by the stripe size
    +     * 
    + */ + int getBlksize(); + + // optional fixed64 etag = 12; + /** + * optional fixed64 etag = 12; + * + *
    +     * identification tag for the stat object
    +     * 
    + */ + boolean hasEtag(); + /** + * optional fixed64 etag = 12; + * + *
    +     * identification tag for the stat object
    +     * 
    + */ + long getEtag(); + + // required fixed32 truncate_epoch = 13; + /** + * required fixed32 truncate_epoch = 13; + * + *
    +     * truncate epoch
    +     * 
    + */ + boolean hasTruncateEpoch(); + /** + * required fixed32 truncate_epoch = 13; + * + *
    +     * truncate epoch
    +     * 
    + */ + int getTruncateEpoch(); + + // optional fixed32 attributes = 14; + /** + * optional fixed32 attributes = 14; + * + *
    +     * Win32-specific attributes
    +     * 
    + */ + boolean hasAttributes(); + /** + * optional fixed32 attributes = 14; + * + *
    +     * Win32-specific attributes
    +     * 
    + */ + int getAttributes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Stat} + * + *
    +   * information about a single file or directory; relevant for the 'stat' call
    +   * 
    + */ + public static final class Stat extends + com.google.protobuf.GeneratedMessage + implements StatOrBuilder { + // Use Stat.newBuilder() to construct. + private Stat(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Stat(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Stat defaultInstance; + public static Stat getDefaultInstance() { + return defaultInstance; + } + + public Stat getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Stat( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + dev_ = input.readFixed64(); + break; + } + case 17: { + bitField0_ |= 0x00000002; + ino_ = input.readFixed64(); + break; + } + case 29: { + bitField0_ |= 0x00000004; + mode_ = input.readFixed32(); + break; + } + case 37: { + bitField0_ |= 0x00000008; + nlink_ = input.readFixed32(); + break; + } + case 42: { + bitField0_ |= 0x00000010; + userId_ = input.readBytes(); + break; + } + case 50: { + bitField0_ |= 0x00000020; + groupId_ = input.readBytes(); + break; + } + case 57: { + bitField0_ |= 0x00000040; + size_ = input.readFixed64(); + break; + } + case 65: { + bitField0_ |= 0x00000080; + atimeNs_ = input.readFixed64(); + break; + } + case 73: { + bitField0_ |= 0x00000100; + mtimeNs_ = input.readFixed64(); + break; + } + case 81: { + bitField0_ |= 0x00000200; + ctimeNs_ = input.readFixed64(); + break; + } + case 93: { + bitField0_ |= 0x00000400; + blksize_ = input.readFixed32(); + break; + } + case 97: { + bitField0_ |= 0x00000800; + etag_ = input.readFixed64(); + break; + } + case 109: { + bitField0_ |= 0x00001000; + truncateEpoch_ = input.readFixed32(); + break; + } + case 117: { + bitField0_ |= 0x00002000; + attributes_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Stat_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Stat_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Stat parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Stat(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 dev = 1; + public static final int DEV_FIELD_NUMBER = 1; + private long dev_; + /** + * required fixed64 dev = 1; + * + *
    +     * device number; represented by a hash of the volume id
    +     * 
    + */ + public boolean hasDev() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 dev = 1; + * + *
    +     * device number; represented by a hash of the volume id
    +     * 
    + */ + public long getDev() { + return dev_; + } + + // required fixed64 ino = 2; + public static final int INO_FIELD_NUMBER = 2; + private long ino_; + /** + * required fixed64 ino = 2; + * + *
    +     * inode number; represented by the file ID
    +     * 
    + */ + public boolean hasIno() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 ino = 2; + * + *
    +     * inode number; represented by the file ID
    +     * 
    + */ + public long getIno() { + return ino_; + } + + // required fixed32 mode = 3; + public static final int MODE_FIELD_NUMBER = 3; + private int mode_; + /** + * required fixed32 mode = 3; + * + *
    +     * POSIX access mode
    +     * 
    + */ + public boolean hasMode() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 mode = 3; + * + *
    +     * POSIX access mode
    +     * 
    + */ + public int getMode() { + return mode_; + } + + // required fixed32 nlink = 4; + public static final int NLINK_FIELD_NUMBER = 4; + private int nlink_; + /** + * required fixed32 nlink = 4; + * + *
    +     * hardlink count
    +     * 
    + */ + public boolean hasNlink() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 nlink = 4; + * + *
    +     * hardlink count
    +     * 
    + */ + public int getNlink() { + return nlink_; + } + + // required string user_id = 5; + public static final int USER_ID_FIELD_NUMBER = 5; + private java.lang.Object userId_; + /** + * required string user_id = 5; + * + *
    +     * owning user ID
    +     * 
    + */ + public boolean hasUserId() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required string user_id = 5; + * + *
    +     * owning user ID
    +     * 
    + */ + public java.lang.String getUserId() { + java.lang.Object ref = userId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + userId_ = s; + } + return s; + } + } + /** + * required string user_id = 5; + * + *
    +     * owning user ID
    +     * 
    + */ + public com.google.protobuf.ByteString + getUserIdBytes() { + java.lang.Object ref = userId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + userId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string group_id = 6; + public static final int GROUP_ID_FIELD_NUMBER = 6; + private java.lang.Object groupId_; + /** + * required string group_id = 6; + * + *
    +     * owning group ID
    +     * 
    + */ + public boolean hasGroupId() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required string group_id = 6; + * + *
    +     * owning group ID
    +     * 
    + */ + public java.lang.String getGroupId() { + java.lang.Object ref = groupId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + groupId_ = s; + } + return s; + } + } + /** + * required string group_id = 6; + * + *
    +     * owning group ID
    +     * 
    + */ + public com.google.protobuf.ByteString + getGroupIdBytes() { + java.lang.Object ref = groupId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + groupId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 size = 7; + public static final int SIZE_FIELD_NUMBER = 7; + private long size_; + /** + * required fixed64 size = 7; + * + *
    +     * file size
    +     * 
    + */ + public boolean hasSize() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required fixed64 size = 7; + * + *
    +     * file size
    +     * 
    + */ + public long getSize() { + return size_; + } + + // required fixed64 atime_ns = 8; + public static final int ATIME_NS_FIELD_NUMBER = 8; + private long atimeNs_; + /** + * required fixed64 atime_ns = 8; + * + *
    +     * atime (access time) in nanoseconds since 1970
    +     * 
    + */ + public boolean hasAtimeNs() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * required fixed64 atime_ns = 8; + * + *
    +     * atime (access time) in nanoseconds since 1970
    +     * 
    + */ + public long getAtimeNs() { + return atimeNs_; + } + + // required fixed64 mtime_ns = 9; + public static final int MTIME_NS_FIELD_NUMBER = 9; + private long mtimeNs_; + /** + * required fixed64 mtime_ns = 9; + * + *
    +     * mtime (data modification time) in nanoseconds since 1970
    +     * 
    + */ + public boolean hasMtimeNs() { + return ((bitField0_ & 0x00000100) == 0x00000100); + } + /** + * required fixed64 mtime_ns = 9; + * + *
    +     * mtime (data modification time) in nanoseconds since 1970
    +     * 
    + */ + public long getMtimeNs() { + return mtimeNs_; + } + + // required fixed64 ctime_ns = 10; + public static final int CTIME_NS_FIELD_NUMBER = 10; + private long ctimeNs_; + /** + * required fixed64 ctime_ns = 10; + * + *
    +     * ctime (inode change time) in nanoseconds since 1970
    +     * 
    + */ + public boolean hasCtimeNs() { + return ((bitField0_ & 0x00000200) == 0x00000200); + } + /** + * required fixed64 ctime_ns = 10; + * + *
    +     * ctime (inode change time) in nanoseconds since 1970
    +     * 
    + */ + public long getCtimeNs() { + return ctimeNs_; + } + + // required fixed32 blksize = 11; + public static final int BLKSIZE_FIELD_NUMBER = 11; + private int blksize_; + /** + * required fixed32 blksize = 11; + * + *
    +     * block size; represented by the stripe size
    +     * 
    + */ + public boolean hasBlksize() { + return ((bitField0_ & 0x00000400) == 0x00000400); + } + /** + * required fixed32 blksize = 11; + * + *
    +     * block size; represented by the stripe size
    +     * 
    + */ + public int getBlksize() { + return blksize_; + } + + // optional fixed64 etag = 12; + public static final int ETAG_FIELD_NUMBER = 12; + private long etag_; + /** + * optional fixed64 etag = 12; + * + *
    +     * identification tag for the stat object
    +     * 
    + */ + public boolean hasEtag() { + return ((bitField0_ & 0x00000800) == 0x00000800); + } + /** + * optional fixed64 etag = 12; + * + *
    +     * identification tag for the stat object
    +     * 
    + */ + public long getEtag() { + return etag_; + } + + // required fixed32 truncate_epoch = 13; + public static final int TRUNCATE_EPOCH_FIELD_NUMBER = 13; + private int truncateEpoch_; + /** + * required fixed32 truncate_epoch = 13; + * + *
    +     * truncate epoch
    +     * 
    + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00001000) == 0x00001000); + } + /** + * required fixed32 truncate_epoch = 13; + * + *
    +     * truncate epoch
    +     * 
    + */ + public int getTruncateEpoch() { + return truncateEpoch_; + } + + // optional fixed32 attributes = 14; + public static final int ATTRIBUTES_FIELD_NUMBER = 14; + private int attributes_; + /** + * optional fixed32 attributes = 14; + * + *
    +     * Win32-specific attributes
    +     * 
    + */ + public boolean hasAttributes() { + return ((bitField0_ & 0x00002000) == 0x00002000); + } + /** + * optional fixed32 attributes = 14; + * + *
    +     * Win32-specific attributes
    +     * 
    + */ + public int getAttributes() { + return attributes_; + } + + private void initFields() { + dev_ = 0L; + ino_ = 0L; + mode_ = 0; + nlink_ = 0; + userId_ = ""; + groupId_ = ""; + size_ = 0L; + atimeNs_ = 0L; + mtimeNs_ = 0L; + ctimeNs_ = 0L; + blksize_ = 0; + etag_ = 0L; + truncateEpoch_ = 0; + attributes_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasDev()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasIno()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMode()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasNlink()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasUserId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasGroupId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasSize()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasAtimeNs()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMtimeNs()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasCtimeNs()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasBlksize()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTruncateEpoch()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, dev_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(2, ino_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed32(3, mode_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed32(4, nlink_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeBytes(5, getUserIdBytes()); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeBytes(6, getGroupIdBytes()); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeFixed64(7, size_); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + output.writeFixed64(8, atimeNs_); + } + if (((bitField0_ & 0x00000100) == 0x00000100)) { + output.writeFixed64(9, mtimeNs_); + } + if (((bitField0_ & 0x00000200) == 0x00000200)) { + output.writeFixed64(10, ctimeNs_); + } + if (((bitField0_ & 0x00000400) == 0x00000400)) { + output.writeFixed32(11, blksize_); + } + if (((bitField0_ & 0x00000800) == 0x00000800)) { + output.writeFixed64(12, etag_); + } + if (((bitField0_ & 0x00001000) == 0x00001000)) { + output.writeFixed32(13, truncateEpoch_); + } + if (((bitField0_ & 0x00002000) == 0x00002000)) { + output.writeFixed32(14, attributes_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, dev_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(2, ino_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(3, mode_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(4, nlink_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(5, getUserIdBytes()); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(6, getGroupIdBytes()); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(7, size_); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(8, atimeNs_); + } + if (((bitField0_ & 0x00000100) == 0x00000100)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(9, mtimeNs_); + } + if (((bitField0_ & 0x00000200) == 0x00000200)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(10, ctimeNs_); + } + if (((bitField0_ & 0x00000400) == 0x00000400)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(11, blksize_); + } + if (((bitField0_ & 0x00000800) == 0x00000800)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(12, etag_); + } + if (((bitField0_ & 0x00001000) == 0x00001000)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(13, truncateEpoch_); + } + if (((bitField0_ & 0x00002000) == 0x00002000)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(14, attributes_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Stat} + * + *
    +     * information about a single file or directory; relevant for the 'stat' call
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Stat_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Stat_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + dev_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + ino_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + mode_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + nlink_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + userId_ = ""; + bitField0_ = (bitField0_ & ~0x00000010); + groupId_ = ""; + bitField0_ = (bitField0_ & ~0x00000020); + size_ = 0L; + bitField0_ = (bitField0_ & ~0x00000040); + atimeNs_ = 0L; + bitField0_ = (bitField0_ & ~0x00000080); + mtimeNs_ = 0L; + bitField0_ = (bitField0_ & ~0x00000100); + ctimeNs_ = 0L; + bitField0_ = (bitField0_ & ~0x00000200); + blksize_ = 0; + bitField0_ = (bitField0_ & ~0x00000400); + etag_ = 0L; + bitField0_ = (bitField0_ & ~0x00000800); + truncateEpoch_ = 0; + bitField0_ = (bitField0_ & ~0x00001000); + attributes_ = 0; + bitField0_ = (bitField0_ & ~0x00002000); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Stat_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.dev_ = dev_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.ino_ = ino_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.mode_ = mode_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.nlink_ = nlink_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.userId_ = userId_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.groupId_ = groupId_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000040; + } + result.size_ = size_; + if (((from_bitField0_ & 0x00000080) == 0x00000080)) { + to_bitField0_ |= 0x00000080; + } + result.atimeNs_ = atimeNs_; + if (((from_bitField0_ & 0x00000100) == 0x00000100)) { + to_bitField0_ |= 0x00000100; + } + result.mtimeNs_ = mtimeNs_; + if (((from_bitField0_ & 0x00000200) == 0x00000200)) { + to_bitField0_ |= 0x00000200; + } + result.ctimeNs_ = ctimeNs_; + if (((from_bitField0_ & 0x00000400) == 0x00000400)) { + to_bitField0_ |= 0x00000400; + } + result.blksize_ = blksize_; + if (((from_bitField0_ & 0x00000800) == 0x00000800)) { + to_bitField0_ |= 0x00000800; + } + result.etag_ = etag_; + if (((from_bitField0_ & 0x00001000) == 0x00001000)) { + to_bitField0_ |= 0x00001000; + } + result.truncateEpoch_ = truncateEpoch_; + if (((from_bitField0_ & 0x00002000) == 0x00002000)) { + to_bitField0_ |= 0x00002000; + } + result.attributes_ = attributes_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance()) return this; + if (other.hasDev()) { + setDev(other.getDev()); + } + if (other.hasIno()) { + setIno(other.getIno()); + } + if (other.hasMode()) { + setMode(other.getMode()); + } + if (other.hasNlink()) { + setNlink(other.getNlink()); + } + if (other.hasUserId()) { + bitField0_ |= 0x00000010; + userId_ = other.userId_; + onChanged(); + } + if (other.hasGroupId()) { + bitField0_ |= 0x00000020; + groupId_ = other.groupId_; + onChanged(); + } + if (other.hasSize()) { + setSize(other.getSize()); + } + if (other.hasAtimeNs()) { + setAtimeNs(other.getAtimeNs()); + } + if (other.hasMtimeNs()) { + setMtimeNs(other.getMtimeNs()); + } + if (other.hasCtimeNs()) { + setCtimeNs(other.getCtimeNs()); + } + if (other.hasBlksize()) { + setBlksize(other.getBlksize()); + } + if (other.hasEtag()) { + setEtag(other.getEtag()); + } + if (other.hasTruncateEpoch()) { + setTruncateEpoch(other.getTruncateEpoch()); + } + if (other.hasAttributes()) { + setAttributes(other.getAttributes()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasDev()) { + + return false; + } + if (!hasIno()) { + + return false; + } + if (!hasMode()) { + + return false; + } + if (!hasNlink()) { + + return false; + } + if (!hasUserId()) { + + return false; + } + if (!hasGroupId()) { + + return false; + } + if (!hasSize()) { + + return false; + } + if (!hasAtimeNs()) { + + return false; + } + if (!hasMtimeNs()) { + + return false; + } + if (!hasCtimeNs()) { + + return false; + } + if (!hasBlksize()) { + + return false; + } + if (!hasTruncateEpoch()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 dev = 1; + private long dev_ ; + /** + * required fixed64 dev = 1; + * + *
    +       * device number; represented by a hash of the volume id
    +       * 
    + */ + public boolean hasDev() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 dev = 1; + * + *
    +       * device number; represented by a hash of the volume id
    +       * 
    + */ + public long getDev() { + return dev_; + } + /** + * required fixed64 dev = 1; + * + *
    +       * device number; represented by a hash of the volume id
    +       * 
    + */ + public Builder setDev(long value) { + bitField0_ |= 0x00000001; + dev_ = value; + onChanged(); + return this; + } + /** + * required fixed64 dev = 1; + * + *
    +       * device number; represented by a hash of the volume id
    +       * 
    + */ + public Builder clearDev() { + bitField0_ = (bitField0_ & ~0x00000001); + dev_ = 0L; + onChanged(); + return this; + } + + // required fixed64 ino = 2; + private long ino_ ; + /** + * required fixed64 ino = 2; + * + *
    +       * inode number; represented by the file ID
    +       * 
    + */ + public boolean hasIno() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 ino = 2; + * + *
    +       * inode number; represented by the file ID
    +       * 
    + */ + public long getIno() { + return ino_; + } + /** + * required fixed64 ino = 2; + * + *
    +       * inode number; represented by the file ID
    +       * 
    + */ + public Builder setIno(long value) { + bitField0_ |= 0x00000002; + ino_ = value; + onChanged(); + return this; + } + /** + * required fixed64 ino = 2; + * + *
    +       * inode number; represented by the file ID
    +       * 
    + */ + public Builder clearIno() { + bitField0_ = (bitField0_ & ~0x00000002); + ino_ = 0L; + onChanged(); + return this; + } + + // required fixed32 mode = 3; + private int mode_ ; + /** + * required fixed32 mode = 3; + * + *
    +       * POSIX access mode
    +       * 
    + */ + public boolean hasMode() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 mode = 3; + * + *
    +       * POSIX access mode
    +       * 
    + */ + public int getMode() { + return mode_; + } + /** + * required fixed32 mode = 3; + * + *
    +       * POSIX access mode
    +       * 
    + */ + public Builder setMode(int value) { + bitField0_ |= 0x00000004; + mode_ = value; + onChanged(); + return this; + } + /** + * required fixed32 mode = 3; + * + *
    +       * POSIX access mode
    +       * 
    + */ + public Builder clearMode() { + bitField0_ = (bitField0_ & ~0x00000004); + mode_ = 0; + onChanged(); + return this; + } + + // required fixed32 nlink = 4; + private int nlink_ ; + /** + * required fixed32 nlink = 4; + * + *
    +       * hardlink count
    +       * 
    + */ + public boolean hasNlink() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 nlink = 4; + * + *
    +       * hardlink count
    +       * 
    + */ + public int getNlink() { + return nlink_; + } + /** + * required fixed32 nlink = 4; + * + *
    +       * hardlink count
    +       * 
    + */ + public Builder setNlink(int value) { + bitField0_ |= 0x00000008; + nlink_ = value; + onChanged(); + return this; + } + /** + * required fixed32 nlink = 4; + * + *
    +       * hardlink count
    +       * 
    + */ + public Builder clearNlink() { + bitField0_ = (bitField0_ & ~0x00000008); + nlink_ = 0; + onChanged(); + return this; + } + + // required string user_id = 5; + private java.lang.Object userId_ = ""; + /** + * required string user_id = 5; + * + *
    +       * owning user ID
    +       * 
    + */ + public boolean hasUserId() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required string user_id = 5; + * + *
    +       * owning user ID
    +       * 
    + */ + public java.lang.String getUserId() { + java.lang.Object ref = userId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + userId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string user_id = 5; + * + *
    +       * owning user ID
    +       * 
    + */ + public com.google.protobuf.ByteString + getUserIdBytes() { + java.lang.Object ref = userId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + userId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string user_id = 5; + * + *
    +       * owning user ID
    +       * 
    + */ + public Builder setUserId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + userId_ = value; + onChanged(); + return this; + } + /** + * required string user_id = 5; + * + *
    +       * owning user ID
    +       * 
    + */ + public Builder clearUserId() { + bitField0_ = (bitField0_ & ~0x00000010); + userId_ = getDefaultInstance().getUserId(); + onChanged(); + return this; + } + /** + * required string user_id = 5; + * + *
    +       * owning user ID
    +       * 
    + */ + public Builder setUserIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + userId_ = value; + onChanged(); + return this; + } + + // required string group_id = 6; + private java.lang.Object groupId_ = ""; + /** + * required string group_id = 6; + * + *
    +       * owning group ID
    +       * 
    + */ + public boolean hasGroupId() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required string group_id = 6; + * + *
    +       * owning group ID
    +       * 
    + */ + public java.lang.String getGroupId() { + java.lang.Object ref = groupId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + groupId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string group_id = 6; + * + *
    +       * owning group ID
    +       * 
    + */ + public com.google.protobuf.ByteString + getGroupIdBytes() { + java.lang.Object ref = groupId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + groupId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string group_id = 6; + * + *
    +       * owning group ID
    +       * 
    + */ + public Builder setGroupId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000020; + groupId_ = value; + onChanged(); + return this; + } + /** + * required string group_id = 6; + * + *
    +       * owning group ID
    +       * 
    + */ + public Builder clearGroupId() { + bitField0_ = (bitField0_ & ~0x00000020); + groupId_ = getDefaultInstance().getGroupId(); + onChanged(); + return this; + } + /** + * required string group_id = 6; + * + *
    +       * owning group ID
    +       * 
    + */ + public Builder setGroupIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000020; + groupId_ = value; + onChanged(); + return this; + } + + // required fixed64 size = 7; + private long size_ ; + /** + * required fixed64 size = 7; + * + *
    +       * file size
    +       * 
    + */ + public boolean hasSize() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required fixed64 size = 7; + * + *
    +       * file size
    +       * 
    + */ + public long getSize() { + return size_; + } + /** + * required fixed64 size = 7; + * + *
    +       * file size
    +       * 
    + */ + public Builder setSize(long value) { + bitField0_ |= 0x00000040; + size_ = value; + onChanged(); + return this; + } + /** + * required fixed64 size = 7; + * + *
    +       * file size
    +       * 
    + */ + public Builder clearSize() { + bitField0_ = (bitField0_ & ~0x00000040); + size_ = 0L; + onChanged(); + return this; + } + + // required fixed64 atime_ns = 8; + private long atimeNs_ ; + /** + * required fixed64 atime_ns = 8; + * + *
    +       * atime (access time) in nanoseconds since 1970
    +       * 
    + */ + public boolean hasAtimeNs() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * required fixed64 atime_ns = 8; + * + *
    +       * atime (access time) in nanoseconds since 1970
    +       * 
    + */ + public long getAtimeNs() { + return atimeNs_; + } + /** + * required fixed64 atime_ns = 8; + * + *
    +       * atime (access time) in nanoseconds since 1970
    +       * 
    + */ + public Builder setAtimeNs(long value) { + bitField0_ |= 0x00000080; + atimeNs_ = value; + onChanged(); + return this; + } + /** + * required fixed64 atime_ns = 8; + * + *
    +       * atime (access time) in nanoseconds since 1970
    +       * 
    + */ + public Builder clearAtimeNs() { + bitField0_ = (bitField0_ & ~0x00000080); + atimeNs_ = 0L; + onChanged(); + return this; + } + + // required fixed64 mtime_ns = 9; + private long mtimeNs_ ; + /** + * required fixed64 mtime_ns = 9; + * + *
    +       * mtime (data modification time) in nanoseconds since 1970
    +       * 
    + */ + public boolean hasMtimeNs() { + return ((bitField0_ & 0x00000100) == 0x00000100); + } + /** + * required fixed64 mtime_ns = 9; + * + *
    +       * mtime (data modification time) in nanoseconds since 1970
    +       * 
    + */ + public long getMtimeNs() { + return mtimeNs_; + } + /** + * required fixed64 mtime_ns = 9; + * + *
    +       * mtime (data modification time) in nanoseconds since 1970
    +       * 
    + */ + public Builder setMtimeNs(long value) { + bitField0_ |= 0x00000100; + mtimeNs_ = value; + onChanged(); + return this; + } + /** + * required fixed64 mtime_ns = 9; + * + *
    +       * mtime (data modification time) in nanoseconds since 1970
    +       * 
    + */ + public Builder clearMtimeNs() { + bitField0_ = (bitField0_ & ~0x00000100); + mtimeNs_ = 0L; + onChanged(); + return this; + } + + // required fixed64 ctime_ns = 10; + private long ctimeNs_ ; + /** + * required fixed64 ctime_ns = 10; + * + *
    +       * ctime (inode change time) in nanoseconds since 1970
    +       * 
    + */ + public boolean hasCtimeNs() { + return ((bitField0_ & 0x00000200) == 0x00000200); + } + /** + * required fixed64 ctime_ns = 10; + * + *
    +       * ctime (inode change time) in nanoseconds since 1970
    +       * 
    + */ + public long getCtimeNs() { + return ctimeNs_; + } + /** + * required fixed64 ctime_ns = 10; + * + *
    +       * ctime (inode change time) in nanoseconds since 1970
    +       * 
    + */ + public Builder setCtimeNs(long value) { + bitField0_ |= 0x00000200; + ctimeNs_ = value; + onChanged(); + return this; + } + /** + * required fixed64 ctime_ns = 10; + * + *
    +       * ctime (inode change time) in nanoseconds since 1970
    +       * 
    + */ + public Builder clearCtimeNs() { + bitField0_ = (bitField0_ & ~0x00000200); + ctimeNs_ = 0L; + onChanged(); + return this; + } + + // required fixed32 blksize = 11; + private int blksize_ ; + /** + * required fixed32 blksize = 11; + * + *
    +       * block size; represented by the stripe size
    +       * 
    + */ + public boolean hasBlksize() { + return ((bitField0_ & 0x00000400) == 0x00000400); + } + /** + * required fixed32 blksize = 11; + * + *
    +       * block size; represented by the stripe size
    +       * 
    + */ + public int getBlksize() { + return blksize_; + } + /** + * required fixed32 blksize = 11; + * + *
    +       * block size; represented by the stripe size
    +       * 
    + */ + public Builder setBlksize(int value) { + bitField0_ |= 0x00000400; + blksize_ = value; + onChanged(); + return this; + } + /** + * required fixed32 blksize = 11; + * + *
    +       * block size; represented by the stripe size
    +       * 
    + */ + public Builder clearBlksize() { + bitField0_ = (bitField0_ & ~0x00000400); + blksize_ = 0; + onChanged(); + return this; + } + + // optional fixed64 etag = 12; + private long etag_ ; + /** + * optional fixed64 etag = 12; + * + *
    +       * identification tag for the stat object
    +       * 
    + */ + public boolean hasEtag() { + return ((bitField0_ & 0x00000800) == 0x00000800); + } + /** + * optional fixed64 etag = 12; + * + *
    +       * identification tag for the stat object
    +       * 
    + */ + public long getEtag() { + return etag_; + } + /** + * optional fixed64 etag = 12; + * + *
    +       * identification tag for the stat object
    +       * 
    + */ + public Builder setEtag(long value) { + bitField0_ |= 0x00000800; + etag_ = value; + onChanged(); + return this; + } + /** + * optional fixed64 etag = 12; + * + *
    +       * identification tag for the stat object
    +       * 
    + */ + public Builder clearEtag() { + bitField0_ = (bitField0_ & ~0x00000800); + etag_ = 0L; + onChanged(); + return this; + } + + // required fixed32 truncate_epoch = 13; + private int truncateEpoch_ ; + /** + * required fixed32 truncate_epoch = 13; + * + *
    +       * truncate epoch
    +       * 
    + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00001000) == 0x00001000); + } + /** + * required fixed32 truncate_epoch = 13; + * + *
    +       * truncate epoch
    +       * 
    + */ + public int getTruncateEpoch() { + return truncateEpoch_; + } + /** + * required fixed32 truncate_epoch = 13; + * + *
    +       * truncate epoch
    +       * 
    + */ + public Builder setTruncateEpoch(int value) { + bitField0_ |= 0x00001000; + truncateEpoch_ = value; + onChanged(); + return this; + } + /** + * required fixed32 truncate_epoch = 13; + * + *
    +       * truncate epoch
    +       * 
    + */ + public Builder clearTruncateEpoch() { + bitField0_ = (bitField0_ & ~0x00001000); + truncateEpoch_ = 0; + onChanged(); + return this; + } + + // optional fixed32 attributes = 14; + private int attributes_ ; + /** + * optional fixed32 attributes = 14; + * + *
    +       * Win32-specific attributes
    +       * 
    + */ + public boolean hasAttributes() { + return ((bitField0_ & 0x00002000) == 0x00002000); + } + /** + * optional fixed32 attributes = 14; + * + *
    +       * Win32-specific attributes
    +       * 
    + */ + public int getAttributes() { + return attributes_; + } + /** + * optional fixed32 attributes = 14; + * + *
    +       * Win32-specific attributes
    +       * 
    + */ + public Builder setAttributes(int value) { + bitField0_ |= 0x00002000; + attributes_ = value; + onChanged(); + return this; + } + /** + * optional fixed32 attributes = 14; + * + *
    +       * Win32-specific attributes
    +       * 
    + */ + public Builder clearAttributes() { + bitField0_ = (bitField0_ & ~0x00002000); + attributes_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.Stat) + } + + static { + defaultInstance = new Stat(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Stat) + } + + public interface DirectoryEntryOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string name = 1; + /** + * required string name = 1; + * + *
    +     * file or subdirectory name
    +     * 
    + */ + boolean hasName(); + /** + * required string name = 1; + * + *
    +     * file or subdirectory name
    +     * 
    + */ + java.lang.String getName(); + /** + * required string name = 1; + * + *
    +     * file or subdirectory name
    +     * 
    + */ + com.google.protobuf.ByteString + getNameBytes(); + + // optional .xtreemfs.pbrpc.Stat stbuf = 2; + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +     * stat buffer containing the associated stat information
    +     * Can have 0 or 1 Stats on a readdir for names only
    +     * 
    + */ + boolean hasStbuf(); + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +     * stat buffer containing the associated stat information
    +     * Can have 0 or 1 Stats on a readdir for names only
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf(); + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +     * stat buffer containing the associated stat information
    +     * Can have 0 or 1 Stats on a readdir for names only
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.DirectoryEntry} + * + *
    +   * single directory entry; relevant for the 'readdir' call
    +   * 
    + */ + public static final class DirectoryEntry extends + com.google.protobuf.GeneratedMessage + implements DirectoryEntryOrBuilder { + // Use DirectoryEntry.newBuilder() to construct. + private DirectoryEntry(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private DirectoryEntry(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final DirectoryEntry defaultInstance; + public static DirectoryEntry getDefaultInstance() { + return defaultInstance; + } + + public DirectoryEntry getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DirectoryEntry( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + name_ = input.readBytes(); + break; + } + case 18: { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = stbuf_.toBuilder(); + } + stbuf_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(stbuf_); + stbuf_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_DirectoryEntry_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_DirectoryEntry_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public DirectoryEntry parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DirectoryEntry(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string name = 1; + public static final int NAME_FIELD_NUMBER = 1; + private java.lang.Object name_; + /** + * required string name = 1; + * + *
    +     * file or subdirectory name
    +     * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string name = 1; + * + *
    +     * file or subdirectory name
    +     * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * required string name = 1; + * + *
    +     * file or subdirectory name
    +     * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional .xtreemfs.pbrpc.Stat stbuf = 2; + public static final int STBUF_FIELD_NUMBER = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat stbuf_; + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +     * stat buffer containing the associated stat information
    +     * Can have 0 or 1 Stats on a readdir for names only
    +     * 
    + */ + public boolean hasStbuf() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +     * stat buffer containing the associated stat information
    +     * Can have 0 or 1 Stats on a readdir for names only
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf() { + return stbuf_; + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +     * stat buffer containing the associated stat information
    +     * Can have 0 or 1 Stats on a readdir for names only
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder() { + return stbuf_; + } + + private void initFields() { + name_ = ""; + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasName()) { + memoizedIsInitialized = 0; + return false; + } + if (hasStbuf()) { + if (!getStbuf().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, stbuf_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, stbuf_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.DirectoryEntry} + * + *
    +     * single directory entry; relevant for the 'readdir' call
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntryOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_DirectoryEntry_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_DirectoryEntry_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getStbufFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + if (stbufBuilder_ == null) { + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + } else { + stbufBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_DirectoryEntry_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + if (stbufBuilder_ == null) { + result.stbuf_ = stbuf_; + } else { + result.stbuf_ = stbufBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.getDefaultInstance()) return this; + if (other.hasName()) { + bitField0_ |= 0x00000001; + name_ = other.name_; + onChanged(); + } + if (other.hasStbuf()) { + mergeStbuf(other.getStbuf()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasName()) { + + return false; + } + if (hasStbuf()) { + if (!getStbuf().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string name = 1; + private java.lang.Object name_ = ""; + /** + * required string name = 1; + * + *
    +       * file or subdirectory name
    +       * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string name = 1; + * + *
    +       * file or subdirectory name
    +       * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string name = 1; + * + *
    +       * file or subdirectory name
    +       * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string name = 1; + * + *
    +       * file or subdirectory name
    +       * 
    + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + /** + * required string name = 1; + * + *
    +       * file or subdirectory name
    +       * 
    + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000001); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * required string name = 1; + * + *
    +       * file or subdirectory name
    +       * 
    + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + + // optional .xtreemfs.pbrpc.Stat stbuf = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder> stbufBuilder_; + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +       * stat buffer containing the associated stat information
    +       * Can have 0 or 1 Stats on a readdir for names only
    +       * 
    + */ + public boolean hasStbuf() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +       * stat buffer containing the associated stat information
    +       * Can have 0 or 1 Stats on a readdir for names only
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf() { + if (stbufBuilder_ == null) { + return stbuf_; + } else { + return stbufBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +       * stat buffer containing the associated stat information
    +       * Can have 0 or 1 Stats on a readdir for names only
    +       * 
    + */ + public Builder setStbuf(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat value) { + if (stbufBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + stbuf_ = value; + onChanged(); + } else { + stbufBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +       * stat buffer containing the associated stat information
    +       * Can have 0 or 1 Stats on a readdir for names only
    +       * 
    + */ + public Builder setStbuf( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder builderForValue) { + if (stbufBuilder_ == null) { + stbuf_ = builderForValue.build(); + onChanged(); + } else { + stbufBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +       * stat buffer containing the associated stat information
    +       * Can have 0 or 1 Stats on a readdir for names only
    +       * 
    + */ + public Builder mergeStbuf(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat value) { + if (stbufBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + stbuf_ != org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance()) { + stbuf_ = + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.newBuilder(stbuf_).mergeFrom(value).buildPartial(); + } else { + stbuf_ = value; + } + onChanged(); + } else { + stbufBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +       * stat buffer containing the associated stat information
    +       * Can have 0 or 1 Stats on a readdir for names only
    +       * 
    + */ + public Builder clearStbuf() { + if (stbufBuilder_ == null) { + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + onChanged(); + } else { + stbufBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +       * stat buffer containing the associated stat information
    +       * Can have 0 or 1 Stats on a readdir for names only
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder getStbufBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getStbufFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +       * stat buffer containing the associated stat information
    +       * Can have 0 or 1 Stats on a readdir for names only
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder() { + if (stbufBuilder_ != null) { + return stbufBuilder_.getMessageOrBuilder(); + } else { + return stbuf_; + } + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 2; + * + *
    +       * stat buffer containing the associated stat information
    +       * Can have 0 or 1 Stats on a readdir for names only
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder> + getStbufFieldBuilder() { + if (stbufBuilder_ == null) { + stbufBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder>( + stbuf_, + getParentForChildren(), + isClean()); + stbuf_ = null; + } + return stbufBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.DirectoryEntry) + } + + static { + defaultInstance = new DirectoryEntry(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.DirectoryEntry) + } + + public interface DirectoryEntriesOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + java.util.List + getEntriesList(); + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry getEntries(int index); + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + int getEntriesCount(); + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + java.util.List + getEntriesOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntryOrBuilder getEntriesOrBuilder( + int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.DirectoryEntries} + * + *
    +   * list of directory entries; relevant for the 'readdir' call
    +   * 
    + */ + public static final class DirectoryEntries extends + com.google.protobuf.GeneratedMessage + implements DirectoryEntriesOrBuilder { + // Use DirectoryEntries.newBuilder() to construct. + private DirectoryEntries(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private DirectoryEntries(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final DirectoryEntries defaultInstance; + public static DirectoryEntries getDefaultInstance() { + return defaultInstance; + } + + public DirectoryEntries getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DirectoryEntries( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + entries_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + entries_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + entries_ = java.util.Collections.unmodifiableList(entries_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_DirectoryEntries_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_DirectoryEntries_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public DirectoryEntries parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DirectoryEntries(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + public static final int ENTRIES_FIELD_NUMBER = 1; + private java.util.List entries_; + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public java.util.List getEntriesList() { + return entries_; + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public java.util.List + getEntriesOrBuilderList() { + return entries_; + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public int getEntriesCount() { + return entries_.size(); + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry getEntries(int index) { + return entries_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntryOrBuilder getEntriesOrBuilder( + int index) { + return entries_.get(index); + } + + private void initFields() { + entries_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + for (int i = 0; i < getEntriesCount(); i++) { + if (!getEntries(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < entries_.size(); i++) { + output.writeMessage(1, entries_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < entries_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, entries_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.DirectoryEntries} + * + *
    +     * list of directory entries; relevant for the 'readdir' call
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntriesOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_DirectoryEntries_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_DirectoryEntries_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getEntriesFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (entriesBuilder_ == null) { + entries_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + entriesBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_DirectoryEntries_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries(this); + int from_bitField0_ = bitField0_; + if (entriesBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001)) { + entries_ = java.util.Collections.unmodifiableList(entries_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.entries_ = entries_; + } else { + result.entries_ = entriesBuilder_.build(); + } + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries.getDefaultInstance()) return this; + if (entriesBuilder_ == null) { + if (!other.entries_.isEmpty()) { + if (entries_.isEmpty()) { + entries_ = other.entries_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureEntriesIsMutable(); + entries_.addAll(other.entries_); + } + onChanged(); + } + } else { + if (!other.entries_.isEmpty()) { + if (entriesBuilder_.isEmpty()) { + entriesBuilder_.dispose(); + entriesBuilder_ = null; + entries_ = other.entries_; + bitField0_ = (bitField0_ & ~0x00000001); + entriesBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getEntriesFieldBuilder() : null; + } else { + entriesBuilder_.addAllMessages(other.entries_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + for (int i = 0; i < getEntriesCount(); i++) { + if (!getEntries(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + private java.util.List entries_ = + java.util.Collections.emptyList(); + private void ensureEntriesIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + entries_ = new java.util.ArrayList(entries_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntryOrBuilder> entriesBuilder_; + + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public java.util.List getEntriesList() { + if (entriesBuilder_ == null) { + return java.util.Collections.unmodifiableList(entries_); + } else { + return entriesBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public int getEntriesCount() { + if (entriesBuilder_ == null) { + return entries_.size(); + } else { + return entriesBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry getEntries(int index) { + if (entriesBuilder_ == null) { + return entries_.get(index); + } else { + return entriesBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public Builder setEntries( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry value) { + if (entriesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureEntriesIsMutable(); + entries_.set(index, value); + onChanged(); + } else { + entriesBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public Builder setEntries( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.Builder builderForValue) { + if (entriesBuilder_ == null) { + ensureEntriesIsMutable(); + entries_.set(index, builderForValue.build()); + onChanged(); + } else { + entriesBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public Builder addEntries(org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry value) { + if (entriesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureEntriesIsMutable(); + entries_.add(value); + onChanged(); + } else { + entriesBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public Builder addEntries( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry value) { + if (entriesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureEntriesIsMutable(); + entries_.add(index, value); + onChanged(); + } else { + entriesBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public Builder addEntries( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.Builder builderForValue) { + if (entriesBuilder_ == null) { + ensureEntriesIsMutable(); + entries_.add(builderForValue.build()); + onChanged(); + } else { + entriesBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public Builder addEntries( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.Builder builderForValue) { + if (entriesBuilder_ == null) { + ensureEntriesIsMutable(); + entries_.add(index, builderForValue.build()); + onChanged(); + } else { + entriesBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public Builder addAllEntries( + java.lang.Iterable values) { + if (entriesBuilder_ == null) { + ensureEntriesIsMutable(); + super.addAll(values, entries_); + onChanged(); + } else { + entriesBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public Builder clearEntries() { + if (entriesBuilder_ == null) { + entries_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + entriesBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public Builder removeEntries(int index) { + if (entriesBuilder_ == null) { + ensureEntriesIsMutable(); + entries_.remove(index); + onChanged(); + } else { + entriesBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.Builder getEntriesBuilder( + int index) { + return getEntriesFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntryOrBuilder getEntriesOrBuilder( + int index) { + if (entriesBuilder_ == null) { + return entries_.get(index); } else { + return entriesBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public java.util.List + getEntriesOrBuilderList() { + if (entriesBuilder_ != null) { + return entriesBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(entries_); + } + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.Builder addEntriesBuilder() { + return getEntriesFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.Builder addEntriesBuilder( + int index) { + return getEntriesFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.DirectoryEntry entries = 1; + */ + public java.util.List + getEntriesBuilderList() { + return getEntriesFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntryOrBuilder> + getEntriesFieldBuilder() { + if (entriesBuilder_ == null) { + entriesBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntryOrBuilder>( + entries_, + ((bitField0_ & 0x00000001) == 0x00000001), + getParentForChildren(), + isClean()); + entries_ = null; + } + return entriesBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.DirectoryEntries) + } + + static { + defaultInstance = new DirectoryEntries(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.DirectoryEntries) + } + + public interface XAttrOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string name = 1; + /** + * required string name = 1; + * + *
    +     * attribute name
    +     * 
    + */ + boolean hasName(); + /** + * required string name = 1; + * + *
    +     * attribute name
    +     * 
    + */ + java.lang.String getName(); + /** + * required string name = 1; + * + *
    +     * attribute name
    +     * 
    + */ + com.google.protobuf.ByteString + getNameBytes(); + + // optional string value = 2; + /** + * optional string value = 2; + * + *
    +     * attribute value; can be empty on a 'listxattr' call for names only
    +     * 
    + */ + boolean hasValue(); + /** + * optional string value = 2; + * + *
    +     * attribute value; can be empty on a 'listxattr' call for names only
    +     * 
    + */ + java.lang.String getValue(); + /** + * optional string value = 2; + * + *
    +     * attribute value; can be empty on a 'listxattr' call for names only
    +     * 
    + */ + com.google.protobuf.ByteString + getValueBytes(); + + // optional bytes value_bytes_string = 3; + /** + * optional bytes value_bytes_string = 3; + * + *
    +     * redundant field of "value" which also accepts binary values (needed
    +     * for storing the value of "system.posix_acl_access",
    +     * added after version 1.3.1)
    +     * If both value and value_bytes are present, value_bytes will always
    +     * be preferred. For backward compability "value" always has to be set,
    +     * even if "value_bytes" is available.
    +     * 
    + */ + boolean hasValueBytesString(); + /** + * optional bytes value_bytes_string = 3; + * + *
    +     * redundant field of "value" which also accepts binary values (needed
    +     * for storing the value of "system.posix_acl_access",
    +     * added after version 1.3.1)
    +     * If both value and value_bytes are present, value_bytes will always
    +     * be preferred. For backward compability "value" always has to be set,
    +     * even if "value_bytes" is available.
    +     * 
    + */ + com.google.protobuf.ByteString getValueBytesString(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.XAttr} + * + *
    +   * extended attribute of a file or directory
    +   * 
    + */ + public static final class XAttr extends + com.google.protobuf.GeneratedMessage + implements XAttrOrBuilder { + // Use XAttr.newBuilder() to construct. + private XAttr(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private XAttr(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final XAttr defaultInstance; + public static XAttr getDefaultInstance() { + return defaultInstance; + } + + public XAttr getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private XAttr( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + name_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + value_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + valueBytesString_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_XAttr_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_XAttr_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public XAttr parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new XAttr(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string name = 1; + public static final int NAME_FIELD_NUMBER = 1; + private java.lang.Object name_; + /** + * required string name = 1; + * + *
    +     * attribute name
    +     * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string name = 1; + * + *
    +     * attribute name
    +     * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * required string name = 1; + * + *
    +     * attribute name
    +     * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string value = 2; + public static final int VALUE_FIELD_NUMBER = 2; + private java.lang.Object value_; + /** + * optional string value = 2; + * + *
    +     * attribute value; can be empty on a 'listxattr' call for names only
    +     * 
    + */ + public boolean hasValue() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string value = 2; + * + *
    +     * attribute value; can be empty on a 'listxattr' call for names only
    +     * 
    + */ + public java.lang.String getValue() { + java.lang.Object ref = value_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + value_ = s; + } + return s; + } + } + /** + * optional string value = 2; + * + *
    +     * attribute value; can be empty on a 'listxattr' call for names only
    +     * 
    + */ + public com.google.protobuf.ByteString + getValueBytes() { + java.lang.Object ref = value_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + value_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional bytes value_bytes_string = 3; + public static final int VALUE_BYTES_STRING_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString valueBytesString_; + /** + * optional bytes value_bytes_string = 3; + * + *
    +     * redundant field of "value" which also accepts binary values (needed
    +     * for storing the value of "system.posix_acl_access",
    +     * added after version 1.3.1)
    +     * If both value and value_bytes are present, value_bytes will always
    +     * be preferred. For backward compability "value" always has to be set,
    +     * even if "value_bytes" is available.
    +     * 
    + */ + public boolean hasValueBytesString() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional bytes value_bytes_string = 3; + * + *
    +     * redundant field of "value" which also accepts binary values (needed
    +     * for storing the value of "system.posix_acl_access",
    +     * added after version 1.3.1)
    +     * If both value and value_bytes are present, value_bytes will always
    +     * be preferred. For backward compability "value" always has to be set,
    +     * even if "value_bytes" is available.
    +     * 
    + */ + public com.google.protobuf.ByteString getValueBytesString() { + return valueBytesString_; + } + + private void initFields() { + name_ = ""; + value_ = ""; + valueBytesString_ = com.google.protobuf.ByteString.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasName()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getValueBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, valueBytesString_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getValueBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, valueBytesString_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.XAttr} + * + *
    +     * extended attribute of a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttrOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_XAttr_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_XAttr_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + value_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + valueBytesString_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_XAttr_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.value_ = value_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.valueBytesString_ = valueBytesString_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.getDefaultInstance()) return this; + if (other.hasName()) { + bitField0_ |= 0x00000001; + name_ = other.name_; + onChanged(); + } + if (other.hasValue()) { + bitField0_ |= 0x00000002; + value_ = other.value_; + onChanged(); + } + if (other.hasValueBytesString()) { + setValueBytesString(other.getValueBytesString()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasName()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string name = 1; + private java.lang.Object name_ = ""; + /** + * required string name = 1; + * + *
    +       * attribute name
    +       * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string name = 1; + * + *
    +       * attribute name
    +       * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string name = 1; + * + *
    +       * attribute name
    +       * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string name = 1; + * + *
    +       * attribute name
    +       * 
    + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + /** + * required string name = 1; + * + *
    +       * attribute name
    +       * 
    + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000001); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * required string name = 1; + * + *
    +       * attribute name
    +       * 
    + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + + // optional string value = 2; + private java.lang.Object value_ = ""; + /** + * optional string value = 2; + * + *
    +       * attribute value; can be empty on a 'listxattr' call for names only
    +       * 
    + */ + public boolean hasValue() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string value = 2; + * + *
    +       * attribute value; can be empty on a 'listxattr' call for names only
    +       * 
    + */ + public java.lang.String getValue() { + java.lang.Object ref = value_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + value_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string value = 2; + * + *
    +       * attribute value; can be empty on a 'listxattr' call for names only
    +       * 
    + */ + public com.google.protobuf.ByteString + getValueBytes() { + java.lang.Object ref = value_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + value_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string value = 2; + * + *
    +       * attribute value; can be empty on a 'listxattr' call for names only
    +       * 
    + */ + public Builder setValue( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + value_ = value; + onChanged(); + return this; + } + /** + * optional string value = 2; + * + *
    +       * attribute value; can be empty on a 'listxattr' call for names only
    +       * 
    + */ + public Builder clearValue() { + bitField0_ = (bitField0_ & ~0x00000002); + value_ = getDefaultInstance().getValue(); + onChanged(); + return this; + } + /** + * optional string value = 2; + * + *
    +       * attribute value; can be empty on a 'listxattr' call for names only
    +       * 
    + */ + public Builder setValueBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + value_ = value; + onChanged(); + return this; + } + + // optional bytes value_bytes_string = 3; + private com.google.protobuf.ByteString valueBytesString_ = com.google.protobuf.ByteString.EMPTY; + /** + * optional bytes value_bytes_string = 3; + * + *
    +       * redundant field of "value" which also accepts binary values (needed
    +       * for storing the value of "system.posix_acl_access",
    +       * added after version 1.3.1)
    +       * If both value and value_bytes are present, value_bytes will always
    +       * be preferred. For backward compability "value" always has to be set,
    +       * even if "value_bytes" is available.
    +       * 
    + */ + public boolean hasValueBytesString() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional bytes value_bytes_string = 3; + * + *
    +       * redundant field of "value" which also accepts binary values (needed
    +       * for storing the value of "system.posix_acl_access",
    +       * added after version 1.3.1)
    +       * If both value and value_bytes are present, value_bytes will always
    +       * be preferred. For backward compability "value" always has to be set,
    +       * even if "value_bytes" is available.
    +       * 
    + */ + public com.google.protobuf.ByteString getValueBytesString() { + return valueBytesString_; + } + /** + * optional bytes value_bytes_string = 3; + * + *
    +       * redundant field of "value" which also accepts binary values (needed
    +       * for storing the value of "system.posix_acl_access",
    +       * added after version 1.3.1)
    +       * If both value and value_bytes are present, value_bytes will always
    +       * be preferred. For backward compability "value" always has to be set,
    +       * even if "value_bytes" is available.
    +       * 
    + */ + public Builder setValueBytesString(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + valueBytesString_ = value; + onChanged(); + return this; + } + /** + * optional bytes value_bytes_string = 3; + * + *
    +       * redundant field of "value" which also accepts binary values (needed
    +       * for storing the value of "system.posix_acl_access",
    +       * added after version 1.3.1)
    +       * If both value and value_bytes are present, value_bytes will always
    +       * be preferred. For backward compability "value" always has to be set,
    +       * even if "value_bytes" is available.
    +       * 
    + */ + public Builder clearValueBytesString() { + bitField0_ = (bitField0_ & ~0x00000004); + valueBytesString_ = getDefaultInstance().getValueBytesString(); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.XAttr) + } + + static { + defaultInstance = new XAttr(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.XAttr) + } + + public interface VolumeOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + * + *
    +     * access control policy to be assigned to the volume
    +     * 
    + */ + boolean hasAccessControlPolicy(); + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + * + *
    +     * access control policy to be assigned to the volume
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType getAccessControlPolicy(); + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +     * default striping policy to be assigned to the volume
    +     * 
    + */ + boolean hasDefaultStripingPolicy(); + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +     * default striping policy to be assigned to the volume
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy getDefaultStripingPolicy(); + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +     * default striping policy to be assigned to the volume
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder getDefaultStripingPolicyOrBuilder(); + + // required string id = 3; + /** + * required string id = 3; + * + *
    +     * volume ID
    +     * 
    + */ + boolean hasId(); + /** + * required string id = 3; + * + *
    +     * volume ID
    +     * 
    + */ + java.lang.String getId(); + /** + * required string id = 3; + * + *
    +     * volume ID
    +     * 
    + */ + com.google.protobuf.ByteString + getIdBytes(); + + // required fixed32 mode = 4; + /** + * required fixed32 mode = 4; + * + *
    +     * initial access mode for the root directory 
    +     * 
    + */ + boolean hasMode(); + /** + * required fixed32 mode = 4; + * + *
    +     * initial access mode for the root directory 
    +     * 
    + */ + int getMode(); + + // required string name = 5; + /** + * required string name = 5; + * + *
    +     * volume name
    +     * 
    + */ + boolean hasName(); + /** + * required string name = 5; + * + *
    +     * volume name
    +     * 
    + */ + java.lang.String getName(); + /** + * required string name = 5; + * + *
    +     * volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getNameBytes(); + + // required string owner_group_id = 6; + /** + * required string owner_group_id = 6; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + boolean hasOwnerGroupId(); + /** + * required string owner_group_id = 6; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + java.lang.String getOwnerGroupId(); + /** + * required string owner_group_id = 6; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + com.google.protobuf.ByteString + getOwnerGroupIdBytes(); + + // required string owner_user_id = 7; + /** + * required string owner_user_id = 7; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + boolean hasOwnerUserId(); + /** + * required string owner_user_id = 7; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + java.lang.String getOwnerUserId(); + /** + * required string owner_user_id = 7; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + com.google.protobuf.ByteString + getOwnerUserIdBytes(); + + // repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +     * optional configuration attributes for the volume
    +     * 
    + */ + java.util.List + getAttrsList(); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +     * optional configuration attributes for the volume
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair getAttrs(int index); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +     * optional configuration attributes for the volume
    +     * 
    + */ + int getAttrsCount(); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +     * optional configuration attributes for the volume
    +     * 
    + */ + java.util.List + getAttrsOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +     * optional configuration attributes for the volume
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder getAttrsOrBuilder( + int index); + + // optional fixed64 quota = 9; + /** + * optional fixed64 quota = 9; + * + *
    +     * optional volume quota
    +     * 
    + */ + boolean hasQuota(); + /** + * optional fixed64 quota = 9; + * + *
    +     * optional volume quota
    +     * 
    + */ + long getQuota(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Volume} + * + *
    +   * information about a volume; relevant for the 'xtfs_mkvol' call
    +   * 
    + */ + public static final class Volume extends + com.google.protobuf.GeneratedMessage + implements VolumeOrBuilder { + // Use Volume.newBuilder() to construct. + private Volume(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Volume(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Volume defaultInstance; + public static Volume getDefaultInstance() { + return defaultInstance; + } + + public Volume getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Volume( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + int rawValue = input.readEnum(); + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType value = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(1, rawValue); + } else { + bitField0_ |= 0x00000001; + accessControlPolicy_ = value; + } + break; + } + case 18: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = defaultStripingPolicy_.toBuilder(); + } + defaultStripingPolicy_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(defaultStripingPolicy_); + defaultStripingPolicy_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + case 26: { + bitField0_ |= 0x00000004; + id_ = input.readBytes(); + break; + } + case 37: { + bitField0_ |= 0x00000008; + mode_ = input.readFixed32(); + break; + } + case 42: { + bitField0_ |= 0x00000010; + name_ = input.readBytes(); + break; + } + case 50: { + bitField0_ |= 0x00000020; + ownerGroupId_ = input.readBytes(); + break; + } + case 58: { + bitField0_ |= 0x00000040; + ownerUserId_ = input.readBytes(); + break; + } + case 66: { + if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) { + attrs_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000080; + } + attrs_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.PARSER, extensionRegistry)); + break; + } + case 73: { + bitField0_ |= 0x00000080; + quota_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) { + attrs_ = java.util.Collections.unmodifiableList(attrs_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Volume_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Volume_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Volume parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Volume(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + public static final int ACCESS_CONTROL_POLICY_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType accessControlPolicy_; + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + * + *
    +     * access control policy to be assigned to the volume
    +     * 
    + */ + public boolean hasAccessControlPolicy() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + * + *
    +     * access control policy to be assigned to the volume
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType getAccessControlPolicy() { + return accessControlPolicy_; + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + public static final int DEFAULT_STRIPING_POLICY_FIELD_NUMBER = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy defaultStripingPolicy_; + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +     * default striping policy to be assigned to the volume
    +     * 
    + */ + public boolean hasDefaultStripingPolicy() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +     * default striping policy to be assigned to the volume
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy getDefaultStripingPolicy() { + return defaultStripingPolicy_; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +     * default striping policy to be assigned to the volume
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder getDefaultStripingPolicyOrBuilder() { + return defaultStripingPolicy_; + } + + // required string id = 3; + public static final int ID_FIELD_NUMBER = 3; + private java.lang.Object id_; + /** + * required string id = 3; + * + *
    +     * volume ID
    +     * 
    + */ + public boolean hasId() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string id = 3; + * + *
    +     * volume ID
    +     * 
    + */ + public java.lang.String getId() { + java.lang.Object ref = id_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + id_ = s; + } + return s; + } + } + /** + * required string id = 3; + * + *
    +     * volume ID
    +     * 
    + */ + public com.google.protobuf.ByteString + getIdBytes() { + java.lang.Object ref = id_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + id_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 mode = 4; + public static final int MODE_FIELD_NUMBER = 4; + private int mode_; + /** + * required fixed32 mode = 4; + * + *
    +     * initial access mode for the root directory 
    +     * 
    + */ + public boolean hasMode() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 mode = 4; + * + *
    +     * initial access mode for the root directory 
    +     * 
    + */ + public int getMode() { + return mode_; + } + + // required string name = 5; + public static final int NAME_FIELD_NUMBER = 5; + private java.lang.Object name_; + /** + * required string name = 5; + * + *
    +     * volume name
    +     * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required string name = 5; + * + *
    +     * volume name
    +     * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * required string name = 5; + * + *
    +     * volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string owner_group_id = 6; + public static final int OWNER_GROUP_ID_FIELD_NUMBER = 6; + private java.lang.Object ownerGroupId_; + /** + * required string owner_group_id = 6; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public boolean hasOwnerGroupId() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required string owner_group_id = 6; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public java.lang.String getOwnerGroupId() { + java.lang.Object ref = ownerGroupId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + ownerGroupId_ = s; + } + return s; + } + } + /** + * required string owner_group_id = 6; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public com.google.protobuf.ByteString + getOwnerGroupIdBytes() { + java.lang.Object ref = ownerGroupId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + ownerGroupId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string owner_user_id = 7; + public static final int OWNER_USER_ID_FIELD_NUMBER = 7; + private java.lang.Object ownerUserId_; + /** + * required string owner_user_id = 7; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public boolean hasOwnerUserId() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required string owner_user_id = 7; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public java.lang.String getOwnerUserId() { + java.lang.Object ref = ownerUserId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + ownerUserId_ = s; + } + return s; + } + } + /** + * required string owner_user_id = 7; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public com.google.protobuf.ByteString + getOwnerUserIdBytes() { + java.lang.Object ref = ownerUserId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + ownerUserId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + public static final int ATTRS_FIELD_NUMBER = 8; + private java.util.List attrs_; + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +     * optional configuration attributes for the volume
    +     * 
    + */ + public java.util.List getAttrsList() { + return attrs_; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +     * optional configuration attributes for the volume
    +     * 
    + */ + public java.util.List + getAttrsOrBuilderList() { + return attrs_; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +     * optional configuration attributes for the volume
    +     * 
    + */ + public int getAttrsCount() { + return attrs_.size(); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +     * optional configuration attributes for the volume
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair getAttrs(int index) { + return attrs_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +     * optional configuration attributes for the volume
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder getAttrsOrBuilder( + int index) { + return attrs_.get(index); + } + + // optional fixed64 quota = 9; + public static final int QUOTA_FIELD_NUMBER = 9; + private long quota_; + /** + * optional fixed64 quota = 9; + * + *
    +     * optional volume quota
    +     * 
    + */ + public boolean hasQuota() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * optional fixed64 quota = 9; + * + *
    +     * optional volume quota
    +     * 
    + */ + public long getQuota() { + return quota_; + } + + private void initFields() { + accessControlPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL; + defaultStripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + id_ = ""; + mode_ = 0; + name_ = ""; + ownerGroupId_ = ""; + ownerUserId_ = ""; + attrs_ = java.util.Collections.emptyList(); + quota_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasAccessControlPolicy()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasDefaultStripingPolicy()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMode()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOwnerGroupId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOwnerUserId()) { + memoizedIsInitialized = 0; + return false; + } + if (!getDefaultStripingPolicy().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getAttrsCount(); i++) { + if (!getAttrs(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeEnum(1, accessControlPolicy_.getNumber()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, defaultStripingPolicy_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getIdBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed32(4, mode_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeBytes(5, getNameBytes()); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeBytes(6, getOwnerGroupIdBytes()); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeBytes(7, getOwnerUserIdBytes()); + } + for (int i = 0; i < attrs_.size(); i++) { + output.writeMessage(8, attrs_.get(i)); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + output.writeFixed64(9, quota_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(1, accessControlPolicy_.getNumber()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, defaultStripingPolicy_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getIdBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(4, mode_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(5, getNameBytes()); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(6, getOwnerGroupIdBytes()); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(7, getOwnerUserIdBytes()); + } + for (int i = 0; i < attrs_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(8, attrs_.get(i)); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(9, quota_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Volume} + * + *
    +     * information about a volume; relevant for the 'xtfs_mkvol' call
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.VolumeOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Volume_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Volume_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getDefaultStripingPolicyFieldBuilder(); + getAttrsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + accessControlPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL; + bitField0_ = (bitField0_ & ~0x00000001); + if (defaultStripingPolicyBuilder_ == null) { + defaultStripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + } else { + defaultStripingPolicyBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + id_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + mode_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000010); + ownerGroupId_ = ""; + bitField0_ = (bitField0_ & ~0x00000020); + ownerUserId_ = ""; + bitField0_ = (bitField0_ & ~0x00000040); + if (attrsBuilder_ == null) { + attrs_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + } else { + attrsBuilder_.clear(); + } + quota_ = 0L; + bitField0_ = (bitField0_ & ~0x00000100); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Volume_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.accessControlPolicy_ = accessControlPolicy_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + if (defaultStripingPolicyBuilder_ == null) { + result.defaultStripingPolicy_ = defaultStripingPolicy_; + } else { + result.defaultStripingPolicy_ = defaultStripingPolicyBuilder_.build(); + } + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.id_ = id_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.mode_ = mode_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.ownerGroupId_ = ownerGroupId_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000040; + } + result.ownerUserId_ = ownerUserId_; + if (attrsBuilder_ == null) { + if (((bitField0_ & 0x00000080) == 0x00000080)) { + attrs_ = java.util.Collections.unmodifiableList(attrs_); + bitField0_ = (bitField0_ & ~0x00000080); + } + result.attrs_ = attrs_; + } else { + result.attrs_ = attrsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000100) == 0x00000100)) { + to_bitField0_ |= 0x00000080; + } + result.quota_ = quota_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.getDefaultInstance()) return this; + if (other.hasAccessControlPolicy()) { + setAccessControlPolicy(other.getAccessControlPolicy()); + } + if (other.hasDefaultStripingPolicy()) { + mergeDefaultStripingPolicy(other.getDefaultStripingPolicy()); + } + if (other.hasId()) { + bitField0_ |= 0x00000004; + id_ = other.id_; + onChanged(); + } + if (other.hasMode()) { + setMode(other.getMode()); + } + if (other.hasName()) { + bitField0_ |= 0x00000010; + name_ = other.name_; + onChanged(); + } + if (other.hasOwnerGroupId()) { + bitField0_ |= 0x00000020; + ownerGroupId_ = other.ownerGroupId_; + onChanged(); + } + if (other.hasOwnerUserId()) { + bitField0_ |= 0x00000040; + ownerUserId_ = other.ownerUserId_; + onChanged(); + } + if (attrsBuilder_ == null) { + if (!other.attrs_.isEmpty()) { + if (attrs_.isEmpty()) { + attrs_ = other.attrs_; + bitField0_ = (bitField0_ & ~0x00000080); + } else { + ensureAttrsIsMutable(); + attrs_.addAll(other.attrs_); + } + onChanged(); + } + } else { + if (!other.attrs_.isEmpty()) { + if (attrsBuilder_.isEmpty()) { + attrsBuilder_.dispose(); + attrsBuilder_ = null; + attrs_ = other.attrs_; + bitField0_ = (bitField0_ & ~0x00000080); + attrsBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getAttrsFieldBuilder() : null; + } else { + attrsBuilder_.addAllMessages(other.attrs_); + } + } + } + if (other.hasQuota()) { + setQuota(other.getQuota()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasAccessControlPolicy()) { + + return false; + } + if (!hasDefaultStripingPolicy()) { + + return false; + } + if (!hasId()) { + + return false; + } + if (!hasMode()) { + + return false; + } + if (!hasName()) { + + return false; + } + if (!hasOwnerGroupId()) { + + return false; + } + if (!hasOwnerUserId()) { + + return false; + } + if (!getDefaultStripingPolicy().isInitialized()) { + + return false; + } + for (int i = 0; i < getAttrsCount(); i++) { + if (!getAttrs(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType accessControlPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL; + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + * + *
    +       * access control policy to be assigned to the volume
    +       * 
    + */ + public boolean hasAccessControlPolicy() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + * + *
    +       * access control policy to be assigned to the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType getAccessControlPolicy() { + return accessControlPolicy_; + } + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + * + *
    +       * access control policy to be assigned to the volume
    +       * 
    + */ + public Builder setAccessControlPolicy(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + accessControlPolicy_ = value; + onChanged(); + return this; + } + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 1; + * + *
    +       * access control policy to be assigned to the volume
    +       * 
    + */ + public Builder clearAccessControlPolicy() { + bitField0_ = (bitField0_ & ~0x00000001); + accessControlPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy defaultStripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder> defaultStripingPolicyBuilder_; + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +       * default striping policy to be assigned to the volume
    +       * 
    + */ + public boolean hasDefaultStripingPolicy() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +       * default striping policy to be assigned to the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy getDefaultStripingPolicy() { + if (defaultStripingPolicyBuilder_ == null) { + return defaultStripingPolicy_; + } else { + return defaultStripingPolicyBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +       * default striping policy to be assigned to the volume
    +       * 
    + */ + public Builder setDefaultStripingPolicy(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy value) { + if (defaultStripingPolicyBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + defaultStripingPolicy_ = value; + onChanged(); + } else { + defaultStripingPolicyBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +       * default striping policy to be assigned to the volume
    +       * 
    + */ + public Builder setDefaultStripingPolicy( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder builderForValue) { + if (defaultStripingPolicyBuilder_ == null) { + defaultStripingPolicy_ = builderForValue.build(); + onChanged(); + } else { + defaultStripingPolicyBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +       * default striping policy to be assigned to the volume
    +       * 
    + */ + public Builder mergeDefaultStripingPolicy(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy value) { + if (defaultStripingPolicyBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + defaultStripingPolicy_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance()) { + defaultStripingPolicy_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.newBuilder(defaultStripingPolicy_).mergeFrom(value).buildPartial(); + } else { + defaultStripingPolicy_ = value; + } + onChanged(); + } else { + defaultStripingPolicyBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +       * default striping policy to be assigned to the volume
    +       * 
    + */ + public Builder clearDefaultStripingPolicy() { + if (defaultStripingPolicyBuilder_ == null) { + defaultStripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + onChanged(); + } else { + defaultStripingPolicyBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +       * default striping policy to be assigned to the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder getDefaultStripingPolicyBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getDefaultStripingPolicyFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +       * default striping policy to be assigned to the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder getDefaultStripingPolicyOrBuilder() { + if (defaultStripingPolicyBuilder_ != null) { + return defaultStripingPolicyBuilder_.getMessageOrBuilder(); + } else { + return defaultStripingPolicy_; + } + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 2; + * + *
    +       * default striping policy to be assigned to the volume
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder> + getDefaultStripingPolicyFieldBuilder() { + if (defaultStripingPolicyBuilder_ == null) { + defaultStripingPolicyBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder>( + defaultStripingPolicy_, + getParentForChildren(), + isClean()); + defaultStripingPolicy_ = null; + } + return defaultStripingPolicyBuilder_; + } + + // required string id = 3; + private java.lang.Object id_ = ""; + /** + * required string id = 3; + * + *
    +       * volume ID
    +       * 
    + */ + public boolean hasId() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string id = 3; + * + *
    +       * volume ID
    +       * 
    + */ + public java.lang.String getId() { + java.lang.Object ref = id_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + id_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string id = 3; + * + *
    +       * volume ID
    +       * 
    + */ + public com.google.protobuf.ByteString + getIdBytes() { + java.lang.Object ref = id_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + id_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string id = 3; + * + *
    +       * volume ID
    +       * 
    + */ + public Builder setId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + id_ = value; + onChanged(); + return this; + } + /** + * required string id = 3; + * + *
    +       * volume ID
    +       * 
    + */ + public Builder clearId() { + bitField0_ = (bitField0_ & ~0x00000004); + id_ = getDefaultInstance().getId(); + onChanged(); + return this; + } + /** + * required string id = 3; + * + *
    +       * volume ID
    +       * 
    + */ + public Builder setIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + id_ = value; + onChanged(); + return this; + } + + // required fixed32 mode = 4; + private int mode_ ; + /** + * required fixed32 mode = 4; + * + *
    +       * initial access mode for the root directory 
    +       * 
    + */ + public boolean hasMode() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 mode = 4; + * + *
    +       * initial access mode for the root directory 
    +       * 
    + */ + public int getMode() { + return mode_; + } + /** + * required fixed32 mode = 4; + * + *
    +       * initial access mode for the root directory 
    +       * 
    + */ + public Builder setMode(int value) { + bitField0_ |= 0x00000008; + mode_ = value; + onChanged(); + return this; + } + /** + * required fixed32 mode = 4; + * + *
    +       * initial access mode for the root directory 
    +       * 
    + */ + public Builder clearMode() { + bitField0_ = (bitField0_ & ~0x00000008); + mode_ = 0; + onChanged(); + return this; + } + + // required string name = 5; + private java.lang.Object name_ = ""; + /** + * required string name = 5; + * + *
    +       * volume name
    +       * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required string name = 5; + * + *
    +       * volume name
    +       * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string name = 5; + * + *
    +       * volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string name = 5; + * + *
    +       * volume name
    +       * 
    + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + name_ = value; + onChanged(); + return this; + } + /** + * required string name = 5; + * + *
    +       * volume name
    +       * 
    + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000010); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * required string name = 5; + * + *
    +       * volume name
    +       * 
    + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + name_ = value; + onChanged(); + return this; + } + + // required string owner_group_id = 6; + private java.lang.Object ownerGroupId_ = ""; + /** + * required string owner_group_id = 6; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public boolean hasOwnerGroupId() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required string owner_group_id = 6; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public java.lang.String getOwnerGroupId() { + java.lang.Object ref = ownerGroupId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + ownerGroupId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string owner_group_id = 6; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public com.google.protobuf.ByteString + getOwnerGroupIdBytes() { + java.lang.Object ref = ownerGroupId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + ownerGroupId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string owner_group_id = 6; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder setOwnerGroupId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000020; + ownerGroupId_ = value; + onChanged(); + return this; + } + /** + * required string owner_group_id = 6; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder clearOwnerGroupId() { + bitField0_ = (bitField0_ & ~0x00000020); + ownerGroupId_ = getDefaultInstance().getOwnerGroupId(); + onChanged(); + return this; + } + /** + * required string owner_group_id = 6; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder setOwnerGroupIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000020; + ownerGroupId_ = value; + onChanged(); + return this; + } + + // required string owner_user_id = 7; + private java.lang.Object ownerUserId_ = ""; + /** + * required string owner_user_id = 7; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public boolean hasOwnerUserId() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required string owner_user_id = 7; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public java.lang.String getOwnerUserId() { + java.lang.Object ref = ownerUserId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + ownerUserId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string owner_user_id = 7; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public com.google.protobuf.ByteString + getOwnerUserIdBytes() { + java.lang.Object ref = ownerUserId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + ownerUserId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string owner_user_id = 7; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder setOwnerUserId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000040; + ownerUserId_ = value; + onChanged(); + return this; + } + /** + * required string owner_user_id = 7; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder clearOwnerUserId() { + bitField0_ = (bitField0_ & ~0x00000040); + ownerUserId_ = getDefaultInstance().getOwnerUserId(); + onChanged(); + return this; + } + /** + * required string owner_user_id = 7; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder setOwnerUserIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000040; + ownerUserId_ = value; + onChanged(); + return this; + } + + // repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + private java.util.List attrs_ = + java.util.Collections.emptyList(); + private void ensureAttrsIsMutable() { + if (!((bitField0_ & 0x00000080) == 0x00000080)) { + attrs_ = new java.util.ArrayList(attrs_); + bitField0_ |= 0x00000080; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder> attrsBuilder_; + + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public java.util.List getAttrsList() { + if (attrsBuilder_ == null) { + return java.util.Collections.unmodifiableList(attrs_); + } else { + return attrsBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public int getAttrsCount() { + if (attrsBuilder_ == null) { + return attrs_.size(); + } else { + return attrsBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair getAttrs(int index) { + if (attrsBuilder_ == null) { + return attrs_.get(index); + } else { + return attrsBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public Builder setAttrs( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair value) { + if (attrsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAttrsIsMutable(); + attrs_.set(index, value); + onChanged(); + } else { + attrsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public Builder setAttrs( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder builderForValue) { + if (attrsBuilder_ == null) { + ensureAttrsIsMutable(); + attrs_.set(index, builderForValue.build()); + onChanged(); + } else { + attrsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public Builder addAttrs(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair value) { + if (attrsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAttrsIsMutable(); + attrs_.add(value); + onChanged(); + } else { + attrsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public Builder addAttrs( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair value) { + if (attrsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAttrsIsMutable(); + attrs_.add(index, value); + onChanged(); + } else { + attrsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public Builder addAttrs( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder builderForValue) { + if (attrsBuilder_ == null) { + ensureAttrsIsMutable(); + attrs_.add(builderForValue.build()); + onChanged(); + } else { + attrsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public Builder addAttrs( + int index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder builderForValue) { + if (attrsBuilder_ == null) { + ensureAttrsIsMutable(); + attrs_.add(index, builderForValue.build()); + onChanged(); + } else { + attrsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public Builder addAllAttrs( + java.lang.Iterable values) { + if (attrsBuilder_ == null) { + ensureAttrsIsMutable(); + super.addAll(values, attrs_); + onChanged(); + } else { + attrsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public Builder clearAttrs() { + if (attrsBuilder_ == null) { + attrs_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + onChanged(); + } else { + attrsBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public Builder removeAttrs(int index) { + if (attrsBuilder_ == null) { + ensureAttrsIsMutable(); + attrs_.remove(index); + onChanged(); + } else { + attrsBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder getAttrsBuilder( + int index) { + return getAttrsFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder getAttrsOrBuilder( + int index) { + if (attrsBuilder_ == null) { + return attrs_.get(index); } else { + return attrsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public java.util.List + getAttrsOrBuilderList() { + if (attrsBuilder_ != null) { + return attrsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(attrs_); + } + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder addAttrsBuilder() { + return getAttrsFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder addAttrsBuilder( + int index) { + return getAttrsFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.KeyValuePair attrs = 8; + * + *
    +       * optional configuration attributes for the volume
    +       * 
    + */ + public java.util.List + getAttrsBuilderList() { + return getAttrsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder> + getAttrsFieldBuilder() { + if (attrsBuilder_ == null) { + attrsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePairOrBuilder>( + attrs_, + ((bitField0_ & 0x00000080) == 0x00000080), + getParentForChildren(), + isClean()); + attrs_ = null; + } + return attrsBuilder_; + } + + // optional fixed64 quota = 9; + private long quota_ ; + /** + * optional fixed64 quota = 9; + * + *
    +       * optional volume quota
    +       * 
    + */ + public boolean hasQuota() { + return ((bitField0_ & 0x00000100) == 0x00000100); + } + /** + * optional fixed64 quota = 9; + * + *
    +       * optional volume quota
    +       * 
    + */ + public long getQuota() { + return quota_; + } + /** + * optional fixed64 quota = 9; + * + *
    +       * optional volume quota
    +       * 
    + */ + public Builder setQuota(long value) { + bitField0_ |= 0x00000100; + quota_ = value; + onChanged(); + return this; + } + /** + * optional fixed64 quota = 9; + * + *
    +       * optional volume quota
    +       * 
    + */ + public Builder clearQuota() { + bitField0_ = (bitField0_ & ~0x00000100); + quota_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.Volume) + } + + static { + defaultInstance = new Volume(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Volume) + } + + public interface VolumesOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated .xtreemfs.pbrpc.Volume volumes = 1; + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + java.util.List + getVolumesList(); + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume getVolumes(int index); + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + int getVolumesCount(); + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + java.util.List + getVolumesOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.VolumeOrBuilder getVolumesOrBuilder( + int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Volumes} + * + *
    +   * a list of volumes; relevant for the 'xtfs_lsvol' call
    +   * 
    + */ + public static final class Volumes extends + com.google.protobuf.GeneratedMessage + implements VolumesOrBuilder { + // Use Volumes.newBuilder() to construct. + private Volumes(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Volumes(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Volumes defaultInstance; + public static Volumes getDefaultInstance() { + return defaultInstance; + } + + public Volumes getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Volumes( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + volumes_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + volumes_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + volumes_ = java.util.Collections.unmodifiableList(volumes_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Volumes_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Volumes_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Volumes parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Volumes(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated .xtreemfs.pbrpc.Volume volumes = 1; + public static final int VOLUMES_FIELD_NUMBER = 1; + private java.util.List volumes_; + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public java.util.List getVolumesList() { + return volumes_; + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public java.util.List + getVolumesOrBuilderList() { + return volumes_; + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public int getVolumesCount() { + return volumes_.size(); + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume getVolumes(int index) { + return volumes_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.VolumeOrBuilder getVolumesOrBuilder( + int index) { + return volumes_.get(index); + } + + private void initFields() { + volumes_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + for (int i = 0; i < getVolumesCount(); i++) { + if (!getVolumes(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < volumes_.size(); i++) { + output.writeMessage(1, volumes_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < volumes_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, volumes_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Volumes} + * + *
    +     * a list of volumes; relevant for the 'xtfs_lsvol' call
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.VolumesOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Volumes_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Volumes_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getVolumesFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (volumesBuilder_ == null) { + volumes_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + volumesBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_Volumes_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes(this); + int from_bitField0_ = bitField0_; + if (volumesBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001)) { + volumes_ = java.util.Collections.unmodifiableList(volumes_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.volumes_ = volumes_; + } else { + result.volumes_ = volumesBuilder_.build(); + } + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes.getDefaultInstance()) return this; + if (volumesBuilder_ == null) { + if (!other.volumes_.isEmpty()) { + if (volumes_.isEmpty()) { + volumes_ = other.volumes_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureVolumesIsMutable(); + volumes_.addAll(other.volumes_); + } + onChanged(); + } + } else { + if (!other.volumes_.isEmpty()) { + if (volumesBuilder_.isEmpty()) { + volumesBuilder_.dispose(); + volumesBuilder_ = null; + volumes_ = other.volumes_; + bitField0_ = (bitField0_ & ~0x00000001); + volumesBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getVolumesFieldBuilder() : null; + } else { + volumesBuilder_.addAllMessages(other.volumes_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + for (int i = 0; i < getVolumesCount(); i++) { + if (!getVolumes(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated .xtreemfs.pbrpc.Volume volumes = 1; + private java.util.List volumes_ = + java.util.Collections.emptyList(); + private void ensureVolumesIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + volumes_ = new java.util.ArrayList(volumes_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.VolumeOrBuilder> volumesBuilder_; + + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public java.util.List getVolumesList() { + if (volumesBuilder_ == null) { + return java.util.Collections.unmodifiableList(volumes_); + } else { + return volumesBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public int getVolumesCount() { + if (volumesBuilder_ == null) { + return volumes_.size(); + } else { + return volumesBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume getVolumes(int index) { + if (volumesBuilder_ == null) { + return volumes_.get(index); + } else { + return volumesBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public Builder setVolumes( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume value) { + if (volumesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureVolumesIsMutable(); + volumes_.set(index, value); + onChanged(); + } else { + volumesBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public Builder setVolumes( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.Builder builderForValue) { + if (volumesBuilder_ == null) { + ensureVolumesIsMutable(); + volumes_.set(index, builderForValue.build()); + onChanged(); + } else { + volumesBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public Builder addVolumes(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume value) { + if (volumesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureVolumesIsMutable(); + volumes_.add(value); + onChanged(); + } else { + volumesBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public Builder addVolumes( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume value) { + if (volumesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureVolumesIsMutable(); + volumes_.add(index, value); + onChanged(); + } else { + volumesBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public Builder addVolumes( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.Builder builderForValue) { + if (volumesBuilder_ == null) { + ensureVolumesIsMutable(); + volumes_.add(builderForValue.build()); + onChanged(); + } else { + volumesBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public Builder addVolumes( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.Builder builderForValue) { + if (volumesBuilder_ == null) { + ensureVolumesIsMutable(); + volumes_.add(index, builderForValue.build()); + onChanged(); + } else { + volumesBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public Builder addAllVolumes( + java.lang.Iterable values) { + if (volumesBuilder_ == null) { + ensureVolumesIsMutable(); + super.addAll(values, volumes_); + onChanged(); + } else { + volumesBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public Builder clearVolumes() { + if (volumesBuilder_ == null) { + volumes_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + volumesBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public Builder removeVolumes(int index) { + if (volumesBuilder_ == null) { + ensureVolumesIsMutable(); + volumes_.remove(index); + onChanged(); + } else { + volumesBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.Builder getVolumesBuilder( + int index) { + return getVolumesFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.VolumeOrBuilder getVolumesOrBuilder( + int index) { + if (volumesBuilder_ == null) { + return volumes_.get(index); } else { + return volumesBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public java.util.List + getVolumesOrBuilderList() { + if (volumesBuilder_ != null) { + return volumesBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(volumes_); + } + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.Builder addVolumesBuilder() { + return getVolumesFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.Builder addVolumesBuilder( + int index) { + return getVolumesFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.Volume volumes = 1; + */ + public java.util.List + getVolumesBuilderList() { + return getVolumesFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.VolumeOrBuilder> + getVolumesFieldBuilder() { + if (volumesBuilder_ == null) { + volumesBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volume.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.VolumeOrBuilder>( + volumes_, + ((bitField0_ & 0x00000001) == 0x00000001), + getParentForChildren(), + isClean()); + volumes_ = null; + } + return volumesBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.Volumes) + } + + static { + defaultInstance = new Volumes(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Volumes) + } + + public interface StatVFSOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed32 bsize = 1; + /** + * required fixed32 bsize = 1; + * + *
    +     * size of a block in bytes
    +     * 
    + */ + boolean hasBsize(); + /** + * required fixed32 bsize = 1; + * + *
    +     * size of a block in bytes
    +     * 
    + */ + int getBsize(); + + // required fixed64 bavail = 2; + /** + * required fixed64 bavail = 2; + * + *
    +     * number of available blocks in the file system for non-privileged users      
    +     * 
    + */ + boolean hasBavail(); + /** + * required fixed64 bavail = 2; + * + *
    +     * number of available blocks in the file system for non-privileged users      
    +     * 
    + */ + long getBavail(); + + // optional fixed64 bfree = 13; + /** + * optional fixed64 bfree = 13; + * + *
    +     * number of free blocks in the file system
    +     * 
    + */ + boolean hasBfree(); + /** + * optional fixed64 bfree = 13; + * + *
    +     * number of free blocks in the file system
    +     * 
    + */ + long getBfree(); + + // required fixed64 blocks = 3; + /** + * required fixed64 blocks = 3; + * + *
    +     * total number of blocks in file system        
    +     * 
    + */ + boolean hasBlocks(); + /** + * required fixed64 blocks = 3; + * + *
    +     * total number of blocks in file system        
    +     * 
    + */ + long getBlocks(); + + // required string fsid = 4; + /** + * required string fsid = 4; + * + *
    +     * volume id
    +     * 
    + */ + boolean hasFsid(); + /** + * required string fsid = 4; + * + *
    +     * volume id
    +     * 
    + */ + java.lang.String getFsid(); + /** + * required string fsid = 4; + * + *
    +     * volume id
    +     * 
    + */ + com.google.protobuf.ByteString + getFsidBytes(); + + // required fixed32 namemax = 5; + /** + * required fixed32 namemax = 5; + * + *
    +     * maximum filename length
    +     * 
    + */ + boolean hasNamemax(); + /** + * required fixed32 namemax = 5; + * + *
    +     * maximum filename length
    +     * 
    + */ + int getNamemax(); + + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + * + *
    +     * access control policy of the volume
    +     * 
    + */ + boolean hasAccessControlPolicy(); + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + * + *
    +     * access control policy of the volume
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType getAccessControlPolicy(); + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +     * default striping policy of the volume
    +     * 
    + */ + boolean hasDefaultStripingPolicy(); + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +     * default striping policy of the volume
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy getDefaultStripingPolicy(); + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +     * default striping policy of the volume
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder getDefaultStripingPolicyOrBuilder(); + + // required fixed64 etag = 8; + /** + * required fixed64 etag = 8; + * + *
    +     * identification tag for the statVFS object
    +     * 
    + */ + boolean hasEtag(); + /** + * required fixed64 etag = 8; + * + *
    +     * identification tag for the statVFS object
    +     * 
    + */ + long getEtag(); + + // required fixed32 mode = 9; + /** + * required fixed32 mode = 9; + * + *
    +     * access mode of the volume's root directory
    +     * 
    + */ + boolean hasMode(); + /** + * required fixed32 mode = 9; + * + *
    +     * access mode of the volume's root directory
    +     * 
    + */ + int getMode(); + + // required string name = 10; + /** + * required string name = 10; + * + *
    +     * volume name
    +     * 
    + */ + boolean hasName(); + /** + * required string name = 10; + * + *
    +     * volume name
    +     * 
    + */ + java.lang.String getName(); + /** + * required string name = 10; + * + *
    +     * volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getNameBytes(); + + // required string owner_group_id = 11; + /** + * required string owner_group_id = 11; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + boolean hasOwnerGroupId(); + /** + * required string owner_group_id = 11; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + java.lang.String getOwnerGroupId(); + /** + * required string owner_group_id = 11; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + com.google.protobuf.ByteString + getOwnerGroupIdBytes(); + + // required string owner_user_id = 12; + /** + * required string owner_user_id = 12; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + boolean hasOwnerUserId(); + /** + * required string owner_user_id = 12; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + java.lang.String getOwnerUserId(); + /** + * required string owner_user_id = 12; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + com.google.protobuf.ByteString + getOwnerUserIdBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.StatVFS} + * + *
    +   * information about a file system (i.e. mounted volume)
    +   * 
    + */ + public static final class StatVFS extends + com.google.protobuf.GeneratedMessage + implements StatVFSOrBuilder { + // Use StatVFS.newBuilder() to construct. + private StatVFS(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private StatVFS(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final StatVFS defaultInstance; + public static StatVFS getDefaultInstance() { + return defaultInstance; + } + + public StatVFS getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private StatVFS( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 13: { + bitField0_ |= 0x00000001; + bsize_ = input.readFixed32(); + break; + } + case 17: { + bitField0_ |= 0x00000002; + bavail_ = input.readFixed64(); + break; + } + case 25: { + bitField0_ |= 0x00000008; + blocks_ = input.readFixed64(); + break; + } + case 34: { + bitField0_ |= 0x00000010; + fsid_ = input.readBytes(); + break; + } + case 45: { + bitField0_ |= 0x00000020; + namemax_ = input.readFixed32(); + break; + } + case 48: { + int rawValue = input.readEnum(); + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType value = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(6, rawValue); + } else { + bitField0_ |= 0x00000040; + accessControlPolicy_ = value; + } + break; + } + case 58: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder subBuilder = null; + if (((bitField0_ & 0x00000080) == 0x00000080)) { + subBuilder = defaultStripingPolicy_.toBuilder(); + } + defaultStripingPolicy_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(defaultStripingPolicy_); + defaultStripingPolicy_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000080; + break; + } + case 65: { + bitField0_ |= 0x00000100; + etag_ = input.readFixed64(); + break; + } + case 77: { + bitField0_ |= 0x00000200; + mode_ = input.readFixed32(); + break; + } + case 82: { + bitField0_ |= 0x00000400; + name_ = input.readBytes(); + break; + } + case 90: { + bitField0_ |= 0x00000800; + ownerGroupId_ = input.readBytes(); + break; + } + case 98: { + bitField0_ |= 0x00001000; + ownerUserId_ = input.readBytes(); + break; + } + case 105: { + bitField0_ |= 0x00000004; + bfree_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_StatVFS_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_StatVFS_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public StatVFS parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new StatVFS(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed32 bsize = 1; + public static final int BSIZE_FIELD_NUMBER = 1; + private int bsize_; + /** + * required fixed32 bsize = 1; + * + *
    +     * size of a block in bytes
    +     * 
    + */ + public boolean hasBsize() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 bsize = 1; + * + *
    +     * size of a block in bytes
    +     * 
    + */ + public int getBsize() { + return bsize_; + } + + // required fixed64 bavail = 2; + public static final int BAVAIL_FIELD_NUMBER = 2; + private long bavail_; + /** + * required fixed64 bavail = 2; + * + *
    +     * number of available blocks in the file system for non-privileged users      
    +     * 
    + */ + public boolean hasBavail() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 bavail = 2; + * + *
    +     * number of available blocks in the file system for non-privileged users      
    +     * 
    + */ + public long getBavail() { + return bavail_; + } + + // optional fixed64 bfree = 13; + public static final int BFREE_FIELD_NUMBER = 13; + private long bfree_; + /** + * optional fixed64 bfree = 13; + * + *
    +     * number of free blocks in the file system
    +     * 
    + */ + public boolean hasBfree() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional fixed64 bfree = 13; + * + *
    +     * number of free blocks in the file system
    +     * 
    + */ + public long getBfree() { + return bfree_; + } + + // required fixed64 blocks = 3; + public static final int BLOCKS_FIELD_NUMBER = 3; + private long blocks_; + /** + * required fixed64 blocks = 3; + * + *
    +     * total number of blocks in file system        
    +     * 
    + */ + public boolean hasBlocks() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 blocks = 3; + * + *
    +     * total number of blocks in file system        
    +     * 
    + */ + public long getBlocks() { + return blocks_; + } + + // required string fsid = 4; + public static final int FSID_FIELD_NUMBER = 4; + private java.lang.Object fsid_; + /** + * required string fsid = 4; + * + *
    +     * volume id
    +     * 
    + */ + public boolean hasFsid() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required string fsid = 4; + * + *
    +     * volume id
    +     * 
    + */ + public java.lang.String getFsid() { + java.lang.Object ref = fsid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fsid_ = s; + } + return s; + } + } + /** + * required string fsid = 4; + * + *
    +     * volume id
    +     * 
    + */ + public com.google.protobuf.ByteString + getFsidBytes() { + java.lang.Object ref = fsid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fsid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 namemax = 5; + public static final int NAMEMAX_FIELD_NUMBER = 5; + private int namemax_; + /** + * required fixed32 namemax = 5; + * + *
    +     * maximum filename length
    +     * 
    + */ + public boolean hasNamemax() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed32 namemax = 5; + * + *
    +     * maximum filename length
    +     * 
    + */ + public int getNamemax() { + return namemax_; + } + + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + public static final int ACCESS_CONTROL_POLICY_FIELD_NUMBER = 6; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType accessControlPolicy_; + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + * + *
    +     * access control policy of the volume
    +     * 
    + */ + public boolean hasAccessControlPolicy() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + * + *
    +     * access control policy of the volume
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType getAccessControlPolicy() { + return accessControlPolicy_; + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + public static final int DEFAULT_STRIPING_POLICY_FIELD_NUMBER = 7; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy defaultStripingPolicy_; + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +     * default striping policy of the volume
    +     * 
    + */ + public boolean hasDefaultStripingPolicy() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +     * default striping policy of the volume
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy getDefaultStripingPolicy() { + return defaultStripingPolicy_; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +     * default striping policy of the volume
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder getDefaultStripingPolicyOrBuilder() { + return defaultStripingPolicy_; + } + + // required fixed64 etag = 8; + public static final int ETAG_FIELD_NUMBER = 8; + private long etag_; + /** + * required fixed64 etag = 8; + * + *
    +     * identification tag for the statVFS object
    +     * 
    + */ + public boolean hasEtag() { + return ((bitField0_ & 0x00000100) == 0x00000100); + } + /** + * required fixed64 etag = 8; + * + *
    +     * identification tag for the statVFS object
    +     * 
    + */ + public long getEtag() { + return etag_; + } + + // required fixed32 mode = 9; + public static final int MODE_FIELD_NUMBER = 9; + private int mode_; + /** + * required fixed32 mode = 9; + * + *
    +     * access mode of the volume's root directory
    +     * 
    + */ + public boolean hasMode() { + return ((bitField0_ & 0x00000200) == 0x00000200); + } + /** + * required fixed32 mode = 9; + * + *
    +     * access mode of the volume's root directory
    +     * 
    + */ + public int getMode() { + return mode_; + } + + // required string name = 10; + public static final int NAME_FIELD_NUMBER = 10; + private java.lang.Object name_; + /** + * required string name = 10; + * + *
    +     * volume name
    +     * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000400) == 0x00000400); + } + /** + * required string name = 10; + * + *
    +     * volume name
    +     * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * required string name = 10; + * + *
    +     * volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string owner_group_id = 11; + public static final int OWNER_GROUP_ID_FIELD_NUMBER = 11; + private java.lang.Object ownerGroupId_; + /** + * required string owner_group_id = 11; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public boolean hasOwnerGroupId() { + return ((bitField0_ & 0x00000800) == 0x00000800); + } + /** + * required string owner_group_id = 11; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public java.lang.String getOwnerGroupId() { + java.lang.Object ref = ownerGroupId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + ownerGroupId_ = s; + } + return s; + } + } + /** + * required string owner_group_id = 11; + * + *
    +     * owning group ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public com.google.protobuf.ByteString + getOwnerGroupIdBytes() { + java.lang.Object ref = ownerGroupId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + ownerGroupId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string owner_user_id = 12; + public static final int OWNER_USER_ID_FIELD_NUMBER = 12; + private java.lang.Object ownerUserId_; + /** + * required string owner_user_id = 12; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public boolean hasOwnerUserId() { + return ((bitField0_ & 0x00001000) == 0x00001000); + } + /** + * required string owner_user_id = 12; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public java.lang.String getOwnerUserId() { + java.lang.Object ref = ownerUserId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + ownerUserId_ = s; + } + return s; + } + } + /** + * required string owner_user_id = 12; + * + *
    +     * owning user ID of the volume (i.e. volume's root directory)
    +     * 
    + */ + public com.google.protobuf.ByteString + getOwnerUserIdBytes() { + java.lang.Object ref = ownerUserId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + ownerUserId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + bsize_ = 0; + bavail_ = 0L; + bfree_ = 0L; + blocks_ = 0L; + fsid_ = ""; + namemax_ = 0; + accessControlPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL; + defaultStripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + etag_ = 0L; + mode_ = 0; + name_ = ""; + ownerGroupId_ = ""; + ownerUserId_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasBsize()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasBavail()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasBlocks()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFsid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasNamemax()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasAccessControlPolicy()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasDefaultStripingPolicy()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasEtag()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMode()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOwnerGroupId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOwnerUserId()) { + memoizedIsInitialized = 0; + return false; + } + if (!getDefaultStripingPolicy().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed32(1, bsize_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(2, bavail_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed64(3, blocks_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeBytes(4, getFsidBytes()); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeFixed32(5, namemax_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeEnum(6, accessControlPolicy_.getNumber()); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + output.writeMessage(7, defaultStripingPolicy_); + } + if (((bitField0_ & 0x00000100) == 0x00000100)) { + output.writeFixed64(8, etag_); + } + if (((bitField0_ & 0x00000200) == 0x00000200)) { + output.writeFixed32(9, mode_); + } + if (((bitField0_ & 0x00000400) == 0x00000400)) { + output.writeBytes(10, getNameBytes()); + } + if (((bitField0_ & 0x00000800) == 0x00000800)) { + output.writeBytes(11, getOwnerGroupIdBytes()); + } + if (((bitField0_ & 0x00001000) == 0x00001000)) { + output.writeBytes(12, getOwnerUserIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(13, bfree_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(1, bsize_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(2, bavail_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, blocks_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, getFsidBytes()); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(5, namemax_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(6, accessControlPolicy_.getNumber()); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(7, defaultStripingPolicy_); + } + if (((bitField0_ & 0x00000100) == 0x00000100)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(8, etag_); + } + if (((bitField0_ & 0x00000200) == 0x00000200)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(9, mode_); + } + if (((bitField0_ & 0x00000400) == 0x00000400)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(10, getNameBytes()); + } + if (((bitField0_ & 0x00000800) == 0x00000800)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(11, getOwnerGroupIdBytes()); + } + if (((bitField0_ & 0x00001000) == 0x00001000)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(12, getOwnerUserIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(13, bfree_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.StatVFS} + * + *
    +     * information about a file system (i.e. mounted volume)
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFSOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_StatVFS_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_StatVFS_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getDefaultStripingPolicyFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + bsize_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + bavail_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + bfree_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + blocks_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + fsid_ = ""; + bitField0_ = (bitField0_ & ~0x00000010); + namemax_ = 0; + bitField0_ = (bitField0_ & ~0x00000020); + accessControlPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL; + bitField0_ = (bitField0_ & ~0x00000040); + if (defaultStripingPolicyBuilder_ == null) { + defaultStripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + } else { + defaultStripingPolicyBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000080); + etag_ = 0L; + bitField0_ = (bitField0_ & ~0x00000100); + mode_ = 0; + bitField0_ = (bitField0_ & ~0x00000200); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000400); + ownerGroupId_ = ""; + bitField0_ = (bitField0_ & ~0x00000800); + ownerUserId_ = ""; + bitField0_ = (bitField0_ & ~0x00001000); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_StatVFS_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.bsize_ = bsize_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.bavail_ = bavail_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.bfree_ = bfree_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.blocks_ = blocks_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.fsid_ = fsid_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.namemax_ = namemax_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000040; + } + result.accessControlPolicy_ = accessControlPolicy_; + if (((from_bitField0_ & 0x00000080) == 0x00000080)) { + to_bitField0_ |= 0x00000080; + } + if (defaultStripingPolicyBuilder_ == null) { + result.defaultStripingPolicy_ = defaultStripingPolicy_; + } else { + result.defaultStripingPolicy_ = defaultStripingPolicyBuilder_.build(); + } + if (((from_bitField0_ & 0x00000100) == 0x00000100)) { + to_bitField0_ |= 0x00000100; + } + result.etag_ = etag_; + if (((from_bitField0_ & 0x00000200) == 0x00000200)) { + to_bitField0_ |= 0x00000200; + } + result.mode_ = mode_; + if (((from_bitField0_ & 0x00000400) == 0x00000400)) { + to_bitField0_ |= 0x00000400; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000800) == 0x00000800)) { + to_bitField0_ |= 0x00000800; + } + result.ownerGroupId_ = ownerGroupId_; + if (((from_bitField0_ & 0x00001000) == 0x00001000)) { + to_bitField0_ |= 0x00001000; + } + result.ownerUserId_ = ownerUserId_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS.getDefaultInstance()) return this; + if (other.hasBsize()) { + setBsize(other.getBsize()); + } + if (other.hasBavail()) { + setBavail(other.getBavail()); + } + if (other.hasBfree()) { + setBfree(other.getBfree()); + } + if (other.hasBlocks()) { + setBlocks(other.getBlocks()); + } + if (other.hasFsid()) { + bitField0_ |= 0x00000010; + fsid_ = other.fsid_; + onChanged(); + } + if (other.hasNamemax()) { + setNamemax(other.getNamemax()); + } + if (other.hasAccessControlPolicy()) { + setAccessControlPolicy(other.getAccessControlPolicy()); + } + if (other.hasDefaultStripingPolicy()) { + mergeDefaultStripingPolicy(other.getDefaultStripingPolicy()); + } + if (other.hasEtag()) { + setEtag(other.getEtag()); + } + if (other.hasMode()) { + setMode(other.getMode()); + } + if (other.hasName()) { + bitField0_ |= 0x00000400; + name_ = other.name_; + onChanged(); + } + if (other.hasOwnerGroupId()) { + bitField0_ |= 0x00000800; + ownerGroupId_ = other.ownerGroupId_; + onChanged(); + } + if (other.hasOwnerUserId()) { + bitField0_ |= 0x00001000; + ownerUserId_ = other.ownerUserId_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasBsize()) { + + return false; + } + if (!hasBavail()) { + + return false; + } + if (!hasBlocks()) { + + return false; + } + if (!hasFsid()) { + + return false; + } + if (!hasNamemax()) { + + return false; + } + if (!hasAccessControlPolicy()) { + + return false; + } + if (!hasDefaultStripingPolicy()) { + + return false; + } + if (!hasEtag()) { + + return false; + } + if (!hasMode()) { + + return false; + } + if (!hasName()) { + + return false; + } + if (!hasOwnerGroupId()) { + + return false; + } + if (!hasOwnerUserId()) { + + return false; + } + if (!getDefaultStripingPolicy().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatVFS) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed32 bsize = 1; + private int bsize_ ; + /** + * required fixed32 bsize = 1; + * + *
    +       * size of a block in bytes
    +       * 
    + */ + public boolean hasBsize() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 bsize = 1; + * + *
    +       * size of a block in bytes
    +       * 
    + */ + public int getBsize() { + return bsize_; + } + /** + * required fixed32 bsize = 1; + * + *
    +       * size of a block in bytes
    +       * 
    + */ + public Builder setBsize(int value) { + bitField0_ |= 0x00000001; + bsize_ = value; + onChanged(); + return this; + } + /** + * required fixed32 bsize = 1; + * + *
    +       * size of a block in bytes
    +       * 
    + */ + public Builder clearBsize() { + bitField0_ = (bitField0_ & ~0x00000001); + bsize_ = 0; + onChanged(); + return this; + } + + // required fixed64 bavail = 2; + private long bavail_ ; + /** + * required fixed64 bavail = 2; + * + *
    +       * number of available blocks in the file system for non-privileged users      
    +       * 
    + */ + public boolean hasBavail() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 bavail = 2; + * + *
    +       * number of available blocks in the file system for non-privileged users      
    +       * 
    + */ + public long getBavail() { + return bavail_; + } + /** + * required fixed64 bavail = 2; + * + *
    +       * number of available blocks in the file system for non-privileged users      
    +       * 
    + */ + public Builder setBavail(long value) { + bitField0_ |= 0x00000002; + bavail_ = value; + onChanged(); + return this; + } + /** + * required fixed64 bavail = 2; + * + *
    +       * number of available blocks in the file system for non-privileged users      
    +       * 
    + */ + public Builder clearBavail() { + bitField0_ = (bitField0_ & ~0x00000002); + bavail_ = 0L; + onChanged(); + return this; + } + + // optional fixed64 bfree = 13; + private long bfree_ ; + /** + * optional fixed64 bfree = 13; + * + *
    +       * number of free blocks in the file system
    +       * 
    + */ + public boolean hasBfree() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional fixed64 bfree = 13; + * + *
    +       * number of free blocks in the file system
    +       * 
    + */ + public long getBfree() { + return bfree_; + } + /** + * optional fixed64 bfree = 13; + * + *
    +       * number of free blocks in the file system
    +       * 
    + */ + public Builder setBfree(long value) { + bitField0_ |= 0x00000004; + bfree_ = value; + onChanged(); + return this; + } + /** + * optional fixed64 bfree = 13; + * + *
    +       * number of free blocks in the file system
    +       * 
    + */ + public Builder clearBfree() { + bitField0_ = (bitField0_ & ~0x00000004); + bfree_ = 0L; + onChanged(); + return this; + } + + // required fixed64 blocks = 3; + private long blocks_ ; + /** + * required fixed64 blocks = 3; + * + *
    +       * total number of blocks in file system        
    +       * 
    + */ + public boolean hasBlocks() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 blocks = 3; + * + *
    +       * total number of blocks in file system        
    +       * 
    + */ + public long getBlocks() { + return blocks_; + } + /** + * required fixed64 blocks = 3; + * + *
    +       * total number of blocks in file system        
    +       * 
    + */ + public Builder setBlocks(long value) { + bitField0_ |= 0x00000008; + blocks_ = value; + onChanged(); + return this; + } + /** + * required fixed64 blocks = 3; + * + *
    +       * total number of blocks in file system        
    +       * 
    + */ + public Builder clearBlocks() { + bitField0_ = (bitField0_ & ~0x00000008); + blocks_ = 0L; + onChanged(); + return this; + } + + // required string fsid = 4; + private java.lang.Object fsid_ = ""; + /** + * required string fsid = 4; + * + *
    +       * volume id
    +       * 
    + */ + public boolean hasFsid() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required string fsid = 4; + * + *
    +       * volume id
    +       * 
    + */ + public java.lang.String getFsid() { + java.lang.Object ref = fsid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fsid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string fsid = 4; + * + *
    +       * volume id
    +       * 
    + */ + public com.google.protobuf.ByteString + getFsidBytes() { + java.lang.Object ref = fsid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fsid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string fsid = 4; + * + *
    +       * volume id
    +       * 
    + */ + public Builder setFsid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + fsid_ = value; + onChanged(); + return this; + } + /** + * required string fsid = 4; + * + *
    +       * volume id
    +       * 
    + */ + public Builder clearFsid() { + bitField0_ = (bitField0_ & ~0x00000010); + fsid_ = getDefaultInstance().getFsid(); + onChanged(); + return this; + } + /** + * required string fsid = 4; + * + *
    +       * volume id
    +       * 
    + */ + public Builder setFsidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + fsid_ = value; + onChanged(); + return this; + } + + // required fixed32 namemax = 5; + private int namemax_ ; + /** + * required fixed32 namemax = 5; + * + *
    +       * maximum filename length
    +       * 
    + */ + public boolean hasNamemax() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed32 namemax = 5; + * + *
    +       * maximum filename length
    +       * 
    + */ + public int getNamemax() { + return namemax_; + } + /** + * required fixed32 namemax = 5; + * + *
    +       * maximum filename length
    +       * 
    + */ + public Builder setNamemax(int value) { + bitField0_ |= 0x00000020; + namemax_ = value; + onChanged(); + return this; + } + /** + * required fixed32 namemax = 5; + * + *
    +       * maximum filename length
    +       * 
    + */ + public Builder clearNamemax() { + bitField0_ = (bitField0_ & ~0x00000020); + namemax_ = 0; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType accessControlPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL; + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + * + *
    +       * access control policy of the volume
    +       * 
    + */ + public boolean hasAccessControlPolicy() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + * + *
    +       * access control policy of the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType getAccessControlPolicy() { + return accessControlPolicy_; + } + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + * + *
    +       * access control policy of the volume
    +       * 
    + */ + public Builder setAccessControlPolicy(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000040; + accessControlPolicy_ = value; + onChanged(); + return this; + } + /** + * required .xtreemfs.pbrpc.AccessControlPolicyType access_control_policy = 6; + * + *
    +       * access control policy of the volume
    +       * 
    + */ + public Builder clearAccessControlPolicy() { + bitField0_ = (bitField0_ & ~0x00000040); + accessControlPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy defaultStripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder> defaultStripingPolicyBuilder_; + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +       * default striping policy of the volume
    +       * 
    + */ + public boolean hasDefaultStripingPolicy() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +       * default striping policy of the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy getDefaultStripingPolicy() { + if (defaultStripingPolicyBuilder_ == null) { + return defaultStripingPolicy_; + } else { + return defaultStripingPolicyBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +       * default striping policy of the volume
    +       * 
    + */ + public Builder setDefaultStripingPolicy(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy value) { + if (defaultStripingPolicyBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + defaultStripingPolicy_ = value; + onChanged(); + } else { + defaultStripingPolicyBuilder_.setMessage(value); + } + bitField0_ |= 0x00000080; + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +       * default striping policy of the volume
    +       * 
    + */ + public Builder setDefaultStripingPolicy( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder builderForValue) { + if (defaultStripingPolicyBuilder_ == null) { + defaultStripingPolicy_ = builderForValue.build(); + onChanged(); + } else { + defaultStripingPolicyBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000080; + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +       * default striping policy of the volume
    +       * 
    + */ + public Builder mergeDefaultStripingPolicy(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy value) { + if (defaultStripingPolicyBuilder_ == null) { + if (((bitField0_ & 0x00000080) == 0x00000080) && + defaultStripingPolicy_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance()) { + defaultStripingPolicy_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.newBuilder(defaultStripingPolicy_).mergeFrom(value).buildPartial(); + } else { + defaultStripingPolicy_ = value; + } + onChanged(); + } else { + defaultStripingPolicyBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000080; + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +       * default striping policy of the volume
    +       * 
    + */ + public Builder clearDefaultStripingPolicy() { + if (defaultStripingPolicyBuilder_ == null) { + defaultStripingPolicy_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.getDefaultInstance(); + onChanged(); + } else { + defaultStripingPolicyBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000080); + return this; + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +       * default striping policy of the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder getDefaultStripingPolicyBuilder() { + bitField0_ |= 0x00000080; + onChanged(); + return getDefaultStripingPolicyFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +       * default striping policy of the volume
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder getDefaultStripingPolicyOrBuilder() { + if (defaultStripingPolicyBuilder_ != null) { + return defaultStripingPolicyBuilder_.getMessageOrBuilder(); + } else { + return defaultStripingPolicy_; + } + } + /** + * required .xtreemfs.pbrpc.StripingPolicy default_striping_policy = 7; + * + *
    +       * default striping policy of the volume
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder> + getDefaultStripingPolicyFieldBuilder() { + if (defaultStripingPolicyBuilder_ == null) { + defaultStripingPolicyBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyOrBuilder>( + defaultStripingPolicy_, + getParentForChildren(), + isClean()); + defaultStripingPolicy_ = null; + } + return defaultStripingPolicyBuilder_; + } + + // required fixed64 etag = 8; + private long etag_ ; + /** + * required fixed64 etag = 8; + * + *
    +       * identification tag for the statVFS object
    +       * 
    + */ + public boolean hasEtag() { + return ((bitField0_ & 0x00000100) == 0x00000100); + } + /** + * required fixed64 etag = 8; + * + *
    +       * identification tag for the statVFS object
    +       * 
    + */ + public long getEtag() { + return etag_; + } + /** + * required fixed64 etag = 8; + * + *
    +       * identification tag for the statVFS object
    +       * 
    + */ + public Builder setEtag(long value) { + bitField0_ |= 0x00000100; + etag_ = value; + onChanged(); + return this; + } + /** + * required fixed64 etag = 8; + * + *
    +       * identification tag for the statVFS object
    +       * 
    + */ + public Builder clearEtag() { + bitField0_ = (bitField0_ & ~0x00000100); + etag_ = 0L; + onChanged(); + return this; + } + + // required fixed32 mode = 9; + private int mode_ ; + /** + * required fixed32 mode = 9; + * + *
    +       * access mode of the volume's root directory
    +       * 
    + */ + public boolean hasMode() { + return ((bitField0_ & 0x00000200) == 0x00000200); + } + /** + * required fixed32 mode = 9; + * + *
    +       * access mode of the volume's root directory
    +       * 
    + */ + public int getMode() { + return mode_; + } + /** + * required fixed32 mode = 9; + * + *
    +       * access mode of the volume's root directory
    +       * 
    + */ + public Builder setMode(int value) { + bitField0_ |= 0x00000200; + mode_ = value; + onChanged(); + return this; + } + /** + * required fixed32 mode = 9; + * + *
    +       * access mode of the volume's root directory
    +       * 
    + */ + public Builder clearMode() { + bitField0_ = (bitField0_ & ~0x00000200); + mode_ = 0; + onChanged(); + return this; + } + + // required string name = 10; + private java.lang.Object name_ = ""; + /** + * required string name = 10; + * + *
    +       * volume name
    +       * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000400) == 0x00000400); + } + /** + * required string name = 10; + * + *
    +       * volume name
    +       * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string name = 10; + * + *
    +       * volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string name = 10; + * + *
    +       * volume name
    +       * 
    + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000400; + name_ = value; + onChanged(); + return this; + } + /** + * required string name = 10; + * + *
    +       * volume name
    +       * 
    + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000400); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * required string name = 10; + * + *
    +       * volume name
    +       * 
    + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000400; + name_ = value; + onChanged(); + return this; + } + + // required string owner_group_id = 11; + private java.lang.Object ownerGroupId_ = ""; + /** + * required string owner_group_id = 11; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public boolean hasOwnerGroupId() { + return ((bitField0_ & 0x00000800) == 0x00000800); + } + /** + * required string owner_group_id = 11; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public java.lang.String getOwnerGroupId() { + java.lang.Object ref = ownerGroupId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + ownerGroupId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string owner_group_id = 11; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public com.google.protobuf.ByteString + getOwnerGroupIdBytes() { + java.lang.Object ref = ownerGroupId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + ownerGroupId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string owner_group_id = 11; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder setOwnerGroupId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000800; + ownerGroupId_ = value; + onChanged(); + return this; + } + /** + * required string owner_group_id = 11; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder clearOwnerGroupId() { + bitField0_ = (bitField0_ & ~0x00000800); + ownerGroupId_ = getDefaultInstance().getOwnerGroupId(); + onChanged(); + return this; + } + /** + * required string owner_group_id = 11; + * + *
    +       * owning group ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder setOwnerGroupIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000800; + ownerGroupId_ = value; + onChanged(); + return this; + } + + // required string owner_user_id = 12; + private java.lang.Object ownerUserId_ = ""; + /** + * required string owner_user_id = 12; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public boolean hasOwnerUserId() { + return ((bitField0_ & 0x00001000) == 0x00001000); + } + /** + * required string owner_user_id = 12; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public java.lang.String getOwnerUserId() { + java.lang.Object ref = ownerUserId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + ownerUserId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string owner_user_id = 12; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public com.google.protobuf.ByteString + getOwnerUserIdBytes() { + java.lang.Object ref = ownerUserId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + ownerUserId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string owner_user_id = 12; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder setOwnerUserId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00001000; + ownerUserId_ = value; + onChanged(); + return this; + } + /** + * required string owner_user_id = 12; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder clearOwnerUserId() { + bitField0_ = (bitField0_ & ~0x00001000); + ownerUserId_ = getDefaultInstance().getOwnerUserId(); + onChanged(); + return this; + } + /** + * required string owner_user_id = 12; + * + *
    +       * owning user ID of the volume (i.e. volume's root directory)
    +       * 
    + */ + public Builder setOwnerUserIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00001000; + ownerUserId_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.StatVFS) + } + + static { + defaultInstance = new StatVFS(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.StatVFS) + } + + public interface fsetattrRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.Stat stbuf = 1; + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + boolean hasStbuf(); + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf(); + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder(); + + // required fixed32 to_set = 2; + /** + * required fixed32 to_set = 2; + * + *
    +     * a bitmap of Setattrs indicating which attributes to update
    +     * 
    + */ + boolean hasToSet(); + /** + * required fixed32 to_set = 2; + * + *
    +     * a bitmap of Setattrs indicating which attributes to update
    +     * 
    + */ + int getToSet(); + + // required .xtreemfs.pbrpc.XCap cap = 3; + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +     * the capability returned by the MRC when the file was opened
    +     * 
    + */ + boolean hasCap(); + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +     * the capability returned by the MRC when the file was opened
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getCap(); + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +     * the capability returned by the MRC when the file was opened
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getCapOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.fsetattrRequest} + * + *
    +   * sets file attriubtes of an open file
    +   * 
    + */ + public static final class fsetattrRequest extends + com.google.protobuf.GeneratedMessage + implements fsetattrRequestOrBuilder { + // Use fsetattrRequest.newBuilder() to construct. + private fsetattrRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private fsetattrRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final fsetattrRequest defaultInstance; + public static fsetattrRequest getDefaultInstance() { + return defaultInstance; + } + + public fsetattrRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private fsetattrRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = stbuf_.toBuilder(); + } + stbuf_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(stbuf_); + stbuf_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 21: { + bitField0_ |= 0x00000002; + toSet_ = input.readFixed32(); + break; + } + case 26: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder subBuilder = null; + if (((bitField0_ & 0x00000004) == 0x00000004)) { + subBuilder = cap_.toBuilder(); + } + cap_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(cap_); + cap_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000004; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_fsetattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_fsetattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public fsetattrRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new fsetattrRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.Stat stbuf = 1; + public static final int STBUF_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat stbuf_; + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + public boolean hasStbuf() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf() { + return stbuf_; + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder() { + return stbuf_; + } + + // required fixed32 to_set = 2; + public static final int TO_SET_FIELD_NUMBER = 2; + private int toSet_; + /** + * required fixed32 to_set = 2; + * + *
    +     * a bitmap of Setattrs indicating which attributes to update
    +     * 
    + */ + public boolean hasToSet() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 to_set = 2; + * + *
    +     * a bitmap of Setattrs indicating which attributes to update
    +     * 
    + */ + public int getToSet() { + return toSet_; + } + + // required .xtreemfs.pbrpc.XCap cap = 3; + public static final int CAP_FIELD_NUMBER = 3; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap cap_; + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +     * the capability returned by the MRC when the file was opened
    +     * 
    + */ + public boolean hasCap() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +     * the capability returned by the MRC when the file was opened
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getCap() { + return cap_; + } + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +     * the capability returned by the MRC when the file was opened
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getCapOrBuilder() { + return cap_; + } + + private void initFields() { + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + toSet_ = 0; + cap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasStbuf()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasToSet()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasCap()) { + memoizedIsInitialized = 0; + return false; + } + if (!getStbuf().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getCap().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, stbuf_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed32(2, toSet_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeMessage(3, cap_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, stbuf_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(2, toSet_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, cap_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.fsetattrRequest} + * + *
    +     * sets file attriubtes of an open file
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_fsetattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_fsetattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getStbufFieldBuilder(); + getCapFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (stbufBuilder_ == null) { + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + } else { + stbufBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + toSet_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + if (capBuilder_ == null) { + cap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + } else { + capBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_fsetattrRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (stbufBuilder_ == null) { + result.stbuf_ = stbuf_; + } else { + result.stbuf_ = stbufBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.toSet_ = toSet_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + if (capBuilder_ == null) { + result.cap_ = cap_; + } else { + result.cap_ = capBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest.getDefaultInstance()) return this; + if (other.hasStbuf()) { + mergeStbuf(other.getStbuf()); + } + if (other.hasToSet()) { + setToSet(other.getToSet()); + } + if (other.hasCap()) { + mergeCap(other.getCap()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasStbuf()) { + + return false; + } + if (!hasToSet()) { + + return false; + } + if (!hasCap()) { + + return false; + } + if (!getStbuf().isInitialized()) { + + return false; + } + if (!getCap().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.fsetattrRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.Stat stbuf = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder> stbufBuilder_; + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public boolean hasStbuf() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf() { + if (stbufBuilder_ == null) { + return stbuf_; + } else { + return stbufBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public Builder setStbuf(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat value) { + if (stbufBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + stbuf_ = value; + onChanged(); + } else { + stbufBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public Builder setStbuf( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder builderForValue) { + if (stbufBuilder_ == null) { + stbuf_ = builderForValue.build(); + onChanged(); + } else { + stbufBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public Builder mergeStbuf(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat value) { + if (stbufBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + stbuf_ != org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance()) { + stbuf_ = + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.newBuilder(stbuf_).mergeFrom(value).buildPartial(); + } else { + stbuf_ = value; + } + onChanged(); + } else { + stbufBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public Builder clearStbuf() { + if (stbufBuilder_ == null) { + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + onChanged(); + } else { + stbufBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder getStbufBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getStbufFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder() { + if (stbufBuilder_ != null) { + return stbufBuilder_.getMessageOrBuilder(); + } else { + return stbuf_; + } + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 1; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder> + getStbufFieldBuilder() { + if (stbufBuilder_ == null) { + stbufBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder>( + stbuf_, + getParentForChildren(), + isClean()); + stbuf_ = null; + } + return stbufBuilder_; + } + + // required fixed32 to_set = 2; + private int toSet_ ; + /** + * required fixed32 to_set = 2; + * + *
    +       * a bitmap of Setattrs indicating which attributes to update
    +       * 
    + */ + public boolean hasToSet() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 to_set = 2; + * + *
    +       * a bitmap of Setattrs indicating which attributes to update
    +       * 
    + */ + public int getToSet() { + return toSet_; + } + /** + * required fixed32 to_set = 2; + * + *
    +       * a bitmap of Setattrs indicating which attributes to update
    +       * 
    + */ + public Builder setToSet(int value) { + bitField0_ |= 0x00000002; + toSet_ = value; + onChanged(); + return this; + } + /** + * required fixed32 to_set = 2; + * + *
    +       * a bitmap of Setattrs indicating which attributes to update
    +       * 
    + */ + public Builder clearToSet() { + bitField0_ = (bitField0_ & ~0x00000002); + toSet_ = 0; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.XCap cap = 3; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap cap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder> capBuilder_; + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +       * the capability returned by the MRC when the file was opened
    +       * 
    + */ + public boolean hasCap() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +       * the capability returned by the MRC when the file was opened
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getCap() { + if (capBuilder_ == null) { + return cap_; + } else { + return capBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +       * the capability returned by the MRC when the file was opened
    +       * 
    + */ + public Builder setCap(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap value) { + if (capBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + cap_ = value; + onChanged(); + } else { + capBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +       * the capability returned by the MRC when the file was opened
    +       * 
    + */ + public Builder setCap( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder builderForValue) { + if (capBuilder_ == null) { + cap_ = builderForValue.build(); + onChanged(); + } else { + capBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +       * the capability returned by the MRC when the file was opened
    +       * 
    + */ + public Builder mergeCap(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap value) { + if (capBuilder_ == null) { + if (((bitField0_ & 0x00000004) == 0x00000004) && + cap_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance()) { + cap_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.newBuilder(cap_).mergeFrom(value).buildPartial(); + } else { + cap_ = value; + } + onChanged(); + } else { + capBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +       * the capability returned by the MRC when the file was opened
    +       * 
    + */ + public Builder clearCap() { + if (capBuilder_ == null) { + cap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + onChanged(); + } else { + capBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +       * the capability returned by the MRC when the file was opened
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder getCapBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getCapFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +       * the capability returned by the MRC when the file was opened
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getCapOrBuilder() { + if (capBuilder_ != null) { + return capBuilder_.getMessageOrBuilder(); + } else { + return cap_; + } + } + /** + * required .xtreemfs.pbrpc.XCap cap = 3; + * + *
    +       * the capability returned by the MRC when the file was opened
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder> + getCapFieldBuilder() { + if (capBuilder_ == null) { + capBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder>( + cap_, + getParentForChildren(), + isClean()); + cap_ = null; + } + return capBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.fsetattrRequest) + } + + static { + defaultInstance = new fsetattrRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.fsetattrRequest) + } + + public interface getattrRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // required fixed64 known_etag = 3; + /** + * required fixed64 known_etag = 3; + * + *
    +     * an identification tag indicating the last known version of the attributes
    +     * 
    + */ + boolean hasKnownEtag(); + /** + * required fixed64 known_etag = 3; + * + *
    +     * an identification tag indicating the last known version of the attributes
    +     * 
    + */ + long getKnownEtag(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.getattrRequest} + * + *
    +   * requests attributes of a file or directory
    +   * 
    + */ + public static final class getattrRequest extends + com.google.protobuf.GeneratedMessage + implements getattrRequestOrBuilder { + // Use getattrRequest.newBuilder() to construct. + private getattrRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private getattrRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final getattrRequest defaultInstance; + public static getattrRequest getDefaultInstance() { + return defaultInstance; + } + + public getattrRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private getattrRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + knownEtag_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public getattrRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new getattrRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 known_etag = 3; + public static final int KNOWN_ETAG_FIELD_NUMBER = 3; + private long knownEtag_; + /** + * required fixed64 known_etag = 3; + * + *
    +     * an identification tag indicating the last known version of the attributes
    +     * 
    + */ + public boolean hasKnownEtag() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 known_etag = 3; + * + *
    +     * an identification tag indicating the last known version of the attributes
    +     * 
    + */ + public long getKnownEtag() { + return knownEtag_; + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + knownEtag_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasKnownEtag()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, knownEtag_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, knownEtag_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.getattrRequest} + * + *
    +     * requests attributes of a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + knownEtag_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getattrRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.knownEtag_ = knownEtag_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasKnownEtag()) { + setKnownEtag(other.getKnownEtag()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + if (!hasKnownEtag()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // required fixed64 known_etag = 3; + private long knownEtag_ ; + /** + * required fixed64 known_etag = 3; + * + *
    +       * an identification tag indicating the last known version of the attributes
    +       * 
    + */ + public boolean hasKnownEtag() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 known_etag = 3; + * + *
    +       * an identification tag indicating the last known version of the attributes
    +       * 
    + */ + public long getKnownEtag() { + return knownEtag_; + } + /** + * required fixed64 known_etag = 3; + * + *
    +       * an identification tag indicating the last known version of the attributes
    +       * 
    + */ + public Builder setKnownEtag(long value) { + bitField0_ |= 0x00000004; + knownEtag_ = value; + onChanged(); + return this; + } + /** + * required fixed64 known_etag = 3; + * + *
    +       * an identification tag indicating the last known version of the attributes
    +       * 
    + */ + public Builder clearKnownEtag() { + bitField0_ = (bitField0_ & ~0x00000004); + knownEtag_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.getattrRequest) + } + + static { + defaultInstance = new getattrRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.getattrRequest) + } + + public interface getattrResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional .xtreemfs.pbrpc.Stat stbuf = 1; + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + boolean hasStbuf(); + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf(); + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.getattrResponse} + * + *
    +   * returns attributes of a file or directory
    +   * 
    + */ + public static final class getattrResponse extends + com.google.protobuf.GeneratedMessage + implements getattrResponseOrBuilder { + // Use getattrResponse.newBuilder() to construct. + private getattrResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private getattrResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final getattrResponse defaultInstance; + public static getattrResponse getDefaultInstance() { + return defaultInstance; + } + + public getattrResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private getattrResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = stbuf_.toBuilder(); + } + stbuf_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(stbuf_); + stbuf_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getattrResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getattrResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public getattrResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new getattrResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional .xtreemfs.pbrpc.Stat stbuf = 1; + public static final int STBUF_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat stbuf_; + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + public boolean hasStbuf() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf() { + return stbuf_; + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder() { + return stbuf_; + } + + private void initFields() { + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (hasStbuf()) { + if (!getStbuf().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, stbuf_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, stbuf_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.getattrResponse} + * + *
    +     * returns attributes of a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getattrResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getattrResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getStbufFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (stbufBuilder_ == null) { + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + } else { + stbufBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getattrResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (stbufBuilder_ == null) { + result.stbuf_ = stbuf_; + } else { + result.stbuf_ = stbufBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse.getDefaultInstance()) return this; + if (other.hasStbuf()) { + mergeStbuf(other.getStbuf()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (hasStbuf()) { + if (!getStbuf().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional .xtreemfs.pbrpc.Stat stbuf = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder> stbufBuilder_; + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + public boolean hasStbuf() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf() { + if (stbufBuilder_ == null) { + return stbuf_; + } else { + return stbufBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + public Builder setStbuf(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat value) { + if (stbufBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + stbuf_ = value; + onChanged(); + } else { + stbufBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + public Builder setStbuf( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder builderForValue) { + if (stbufBuilder_ == null) { + stbuf_ = builderForValue.build(); + onChanged(); + } else { + stbufBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + public Builder mergeStbuf(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat value) { + if (stbufBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + stbuf_ != org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance()) { + stbuf_ = + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.newBuilder(stbuf_).mergeFrom(value).buildPartial(); + } else { + stbuf_ = value; + } + onChanged(); + } else { + stbufBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + public Builder clearStbuf() { + if (stbufBuilder_ == null) { + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + onChanged(); + } else { + stbufBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder getStbufBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getStbufFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder() { + if (stbufBuilder_ != null) { + return stbufBuilder_.getMessageOrBuilder(); + } else { + return stbuf_; + } + } + /** + * optional .xtreemfs.pbrpc.Stat stbuf = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder> + getStbufFieldBuilder() { + if (stbufBuilder_ == null) { + stbufBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder>( + stbuf_, + getParentForChildren(), + isClean()); + stbuf_ = null; + } + return stbufBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.getattrResponse) + } + + static { + defaultInstance = new getattrResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.getattrResponse) + } + + public interface getxattrRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // required string name = 3; + /** + * required string name = 3; + * + *
    +     * the name of the attribute to retrieve
    +     * 
    + */ + boolean hasName(); + /** + * required string name = 3; + * + *
    +     * the name of the attribute to retrieve
    +     * 
    + */ + java.lang.String getName(); + /** + * required string name = 3; + * + *
    +     * the name of the attribute to retrieve
    +     * 
    + */ + com.google.protobuf.ByteString + getNameBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.getxattrRequest} + * + *
    +   * requests extended attributes of a file or directory
    +   * 
    + */ + public static final class getxattrRequest extends + com.google.protobuf.GeneratedMessage + implements getxattrRequestOrBuilder { + // Use getxattrRequest.newBuilder() to construct. + private getxattrRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private getxattrRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final getxattrRequest defaultInstance; + public static getxattrRequest getDefaultInstance() { + return defaultInstance; + } + + public getxattrRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private getxattrRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + name_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getxattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getxattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public getxattrRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new getxattrRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string name = 3; + public static final int NAME_FIELD_NUMBER = 3; + private java.lang.Object name_; + /** + * required string name = 3; + * + *
    +     * the name of the attribute to retrieve
    +     * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string name = 3; + * + *
    +     * the name of the attribute to retrieve
    +     * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * required string name = 3; + * + *
    +     * the name of the attribute to retrieve
    +     * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + name_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasName()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getNameBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getNameBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.getxattrRequest} + * + *
    +     * requests extended attributes of a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getxattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getxattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getxattrRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.name_ = name_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasName()) { + bitField0_ |= 0x00000004; + name_ = other.name_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + if (!hasName()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // required string name = 3; + private java.lang.Object name_ = ""; + /** + * required string name = 3; + * + *
    +       * the name of the attribute to retrieve
    +       * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string name = 3; + * + *
    +       * the name of the attribute to retrieve
    +       * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string name = 3; + * + *
    +       * the name of the attribute to retrieve
    +       * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string name = 3; + * + *
    +       * the name of the attribute to retrieve
    +       * 
    + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + name_ = value; + onChanged(); + return this; + } + /** + * required string name = 3; + * + *
    +       * the name of the attribute to retrieve
    +       * 
    + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000004); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * required string name = 3; + * + *
    +       * the name of the attribute to retrieve
    +       * 
    + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + name_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.getxattrRequest) + } + + static { + defaultInstance = new getxattrRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.getxattrRequest) + } + + public interface getxattrResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string value = 1; + /** + * required string value = 1; + */ + boolean hasValue(); + /** + * required string value = 1; + */ + java.lang.String getValue(); + /** + * required string value = 1; + */ + com.google.protobuf.ByteString + getValueBytes(); + + // optional bytes value_bytes_string = 2; + /** + * optional bytes value_bytes_string = 2; + * + *
    +     * see XAttr message for explanation.
    +     * 
    + */ + boolean hasValueBytesString(); + /** + * optional bytes value_bytes_string = 2; + * + *
    +     * see XAttr message for explanation.
    +     * 
    + */ + com.google.protobuf.ByteString getValueBytesString(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.getxattrResponse} + * + *
    +   * returns an attribute value of a file or directory
    +   * 
    + */ + public static final class getxattrResponse extends + com.google.protobuf.GeneratedMessage + implements getxattrResponseOrBuilder { + // Use getxattrResponse.newBuilder() to construct. + private getxattrResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private getxattrResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final getxattrResponse defaultInstance; + public static getxattrResponse getDefaultInstance() { + return defaultInstance; + } + + public getxattrResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private getxattrResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + value_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + valueBytesString_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getxattrResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getxattrResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public getxattrResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new getxattrResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string value = 1; + public static final int VALUE_FIELD_NUMBER = 1; + private java.lang.Object value_; + /** + * required string value = 1; + */ + public boolean hasValue() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string value = 1; + */ + public java.lang.String getValue() { + java.lang.Object ref = value_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + value_ = s; + } + return s; + } + } + /** + * required string value = 1; + */ + public com.google.protobuf.ByteString + getValueBytes() { + java.lang.Object ref = value_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + value_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional bytes value_bytes_string = 2; + public static final int VALUE_BYTES_STRING_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString valueBytesString_; + /** + * optional bytes value_bytes_string = 2; + * + *
    +     * see XAttr message for explanation.
    +     * 
    + */ + public boolean hasValueBytesString() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional bytes value_bytes_string = 2; + * + *
    +     * see XAttr message for explanation.
    +     * 
    + */ + public com.google.protobuf.ByteString getValueBytesString() { + return valueBytesString_; + } + + private void initFields() { + value_ = ""; + valueBytesString_ = com.google.protobuf.ByteString.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasValue()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getValueBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, valueBytesString_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getValueBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, valueBytesString_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.getxattrResponse} + * + *
    +     * returns an attribute value of a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getxattrResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getxattrResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + value_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + valueBytesString_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_getxattrResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.value_ = value_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.valueBytesString_ = valueBytesString_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse.getDefaultInstance()) return this; + if (other.hasValue()) { + bitField0_ |= 0x00000001; + value_ = other.value_; + onChanged(); + } + if (other.hasValueBytesString()) { + setValueBytesString(other.getValueBytesString()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasValue()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.getxattrResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string value = 1; + private java.lang.Object value_ = ""; + /** + * required string value = 1; + */ + public boolean hasValue() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string value = 1; + */ + public java.lang.String getValue() { + java.lang.Object ref = value_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + value_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string value = 1; + */ + public com.google.protobuf.ByteString + getValueBytes() { + java.lang.Object ref = value_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + value_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string value = 1; + */ + public Builder setValue( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + value_ = value; + onChanged(); + return this; + } + /** + * required string value = 1; + */ + public Builder clearValue() { + bitField0_ = (bitField0_ & ~0x00000001); + value_ = getDefaultInstance().getValue(); + onChanged(); + return this; + } + /** + * required string value = 1; + */ + public Builder setValueBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + value_ = value; + onChanged(); + return this; + } + + // optional bytes value_bytes_string = 2; + private com.google.protobuf.ByteString valueBytesString_ = com.google.protobuf.ByteString.EMPTY; + /** + * optional bytes value_bytes_string = 2; + * + *
    +       * see XAttr message for explanation.
    +       * 
    + */ + public boolean hasValueBytesString() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional bytes value_bytes_string = 2; + * + *
    +       * see XAttr message for explanation.
    +       * 
    + */ + public com.google.protobuf.ByteString getValueBytesString() { + return valueBytesString_; + } + /** + * optional bytes value_bytes_string = 2; + * + *
    +       * see XAttr message for explanation.
    +       * 
    + */ + public Builder setValueBytesString(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + valueBytesString_ = value; + onChanged(); + return this; + } + /** + * optional bytes value_bytes_string = 2; + * + *
    +       * see XAttr message for explanation.
    +       * 
    + */ + public Builder clearValueBytesString() { + bitField0_ = (bitField0_ & ~0x00000002); + valueBytesString_ = getDefaultInstance().getValueBytesString(); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.getxattrResponse) + } + + static { + defaultInstance = new getxattrResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.getxattrResponse) + } + + public interface linkRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string target_path = 2; + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + boolean hasTargetPath(); + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + java.lang.String getTargetPath(); + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getTargetPathBytes(); + + // required string link_path = 3; + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + boolean hasLinkPath(); + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + java.lang.String getLinkPath(); + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getLinkPathBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.linkRequest} + * + *
    +   * creates a new hardlink to an existing file 
    +   * 
    + */ + public static final class linkRequest extends + com.google.protobuf.GeneratedMessage + implements linkRequestOrBuilder { + // Use linkRequest.newBuilder() to construct. + private linkRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private linkRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final linkRequest defaultInstance; + public static linkRequest getDefaultInstance() { + return defaultInstance; + } + + public linkRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private linkRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + targetPath_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + linkPath_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_linkRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_linkRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public linkRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new linkRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string target_path = 2; + public static final int TARGET_PATH_FIELD_NUMBER = 2; + private java.lang.Object targetPath_; + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + public boolean hasTargetPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + public java.lang.String getTargetPath() { + java.lang.Object ref = targetPath_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + targetPath_ = s; + } + return s; + } + } + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getTargetPathBytes() { + java.lang.Object ref = targetPath_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + targetPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string link_path = 3; + public static final int LINK_PATH_FIELD_NUMBER = 3; + private java.lang.Object linkPath_; + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + public boolean hasLinkPath() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + public java.lang.String getLinkPath() { + java.lang.Object ref = linkPath_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + linkPath_ = s; + } + return s; + } + } + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getLinkPathBytes() { + java.lang.Object ref = linkPath_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + linkPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + volumeName_ = ""; + targetPath_ = ""; + linkPath_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTargetPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLinkPath()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getTargetPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getLinkPathBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getTargetPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getLinkPathBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.linkRequest} + * + *
    +     * creates a new hardlink to an existing file 
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_linkRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_linkRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + targetPath_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + linkPath_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_linkRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.targetPath_ = targetPath_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.linkPath_ = linkPath_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasTargetPath()) { + bitField0_ |= 0x00000002; + targetPath_ = other.targetPath_; + onChanged(); + } + if (other.hasLinkPath()) { + bitField0_ |= 0x00000004; + linkPath_ = other.linkPath_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasTargetPath()) { + + return false; + } + if (!hasLinkPath()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.linkRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string target_path = 2; + private java.lang.Object targetPath_ = ""; + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public boolean hasTargetPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public java.lang.String getTargetPath() { + java.lang.Object ref = targetPath_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + targetPath_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getTargetPathBytes() { + java.lang.Object ref = targetPath_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + targetPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public Builder setTargetPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + targetPath_ = value; + onChanged(); + return this; + } + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public Builder clearTargetPath() { + bitField0_ = (bitField0_ & ~0x00000002); + targetPath_ = getDefaultInstance().getTargetPath(); + onChanged(); + return this; + } + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public Builder setTargetPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + targetPath_ = value; + onChanged(); + return this; + } + + // required string link_path = 3; + private java.lang.Object linkPath_ = ""; + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public boolean hasLinkPath() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public java.lang.String getLinkPath() { + java.lang.Object ref = linkPath_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + linkPath_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getLinkPathBytes() { + java.lang.Object ref = linkPath_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + linkPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public Builder setLinkPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + linkPath_ = value; + onChanged(); + return this; + } + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public Builder clearLinkPath() { + bitField0_ = (bitField0_ & ~0x00000004); + linkPath_ = getDefaultInstance().getLinkPath(); + onChanged(); + return this; + } + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public Builder setLinkPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + linkPath_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.linkRequest) + } + + static { + defaultInstance = new linkRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.linkRequest) + } + + public interface listxattrRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // required bool names_only = 3; + /** + * required bool names_only = 3; + * + *
    +     * a flag indicating that no attribute values are supposed to be returned
    +     * 
    + */ + boolean hasNamesOnly(); + /** + * required bool names_only = 3; + * + *
    +     * a flag indicating that no attribute values are supposed to be returned
    +     * 
    + */ + boolean getNamesOnly(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.listxattrRequest} + * + *
    +   * requests a list of extended attributes of a file or directory
    +   * 
    + */ + public static final class listxattrRequest extends + com.google.protobuf.GeneratedMessage + implements listxattrRequestOrBuilder { + // Use listxattrRequest.newBuilder() to construct. + private listxattrRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private listxattrRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final listxattrRequest defaultInstance; + public static listxattrRequest getDefaultInstance() { + return defaultInstance; + } + + public listxattrRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private listxattrRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 24: { + bitField0_ |= 0x00000004; + namesOnly_ = input.readBool(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_listxattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_listxattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public listxattrRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new listxattrRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required bool names_only = 3; + public static final int NAMES_ONLY_FIELD_NUMBER = 3; + private boolean namesOnly_; + /** + * required bool names_only = 3; + * + *
    +     * a flag indicating that no attribute values are supposed to be returned
    +     * 
    + */ + public boolean hasNamesOnly() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required bool names_only = 3; + * + *
    +     * a flag indicating that no attribute values are supposed to be returned
    +     * 
    + */ + public boolean getNamesOnly() { + return namesOnly_; + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + namesOnly_ = false; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasNamesOnly()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBool(3, namesOnly_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(3, namesOnly_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.listxattrRequest} + * + *
    +     * requests a list of extended attributes of a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_listxattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_listxattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + namesOnly_ = false; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_listxattrRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.namesOnly_ = namesOnly_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasNamesOnly()) { + setNamesOnly(other.getNamesOnly()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + if (!hasNamesOnly()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // required bool names_only = 3; + private boolean namesOnly_ ; + /** + * required bool names_only = 3; + * + *
    +       * a flag indicating that no attribute values are supposed to be returned
    +       * 
    + */ + public boolean hasNamesOnly() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required bool names_only = 3; + * + *
    +       * a flag indicating that no attribute values are supposed to be returned
    +       * 
    + */ + public boolean getNamesOnly() { + return namesOnly_; + } + /** + * required bool names_only = 3; + * + *
    +       * a flag indicating that no attribute values are supposed to be returned
    +       * 
    + */ + public Builder setNamesOnly(boolean value) { + bitField0_ |= 0x00000004; + namesOnly_ = value; + onChanged(); + return this; + } + /** + * required bool names_only = 3; + * + *
    +       * a flag indicating that no attribute values are supposed to be returned
    +       * 
    + */ + public Builder clearNamesOnly() { + bitField0_ = (bitField0_ & ~0x00000004); + namesOnly_ = false; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.listxattrRequest) + } + + static { + defaultInstance = new listxattrRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.listxattrRequest) + } + + public interface listxattrResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + java.util.List + getXattrsList(); + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr getXattrs(int index); + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + int getXattrsCount(); + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + java.util.List + getXattrsOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttrOrBuilder getXattrsOrBuilder( + int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.listxattrResponse} + * + *
    +   * returns a list of extended attributes of a file or directory
    +   * 
    + */ + public static final class listxattrResponse extends + com.google.protobuf.GeneratedMessage + implements listxattrResponseOrBuilder { + // Use listxattrResponse.newBuilder() to construct. + private listxattrResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private listxattrResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final listxattrResponse defaultInstance; + public static listxattrResponse getDefaultInstance() { + return defaultInstance; + } + + public listxattrResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private listxattrResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + xattrs_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + xattrs_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + xattrs_ = java.util.Collections.unmodifiableList(xattrs_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_listxattrResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_listxattrResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public listxattrResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new listxattrResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + public static final int XATTRS_FIELD_NUMBER = 1; + private java.util.List xattrs_; + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public java.util.List getXattrsList() { + return xattrs_; + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public java.util.List + getXattrsOrBuilderList() { + return xattrs_; + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public int getXattrsCount() { + return xattrs_.size(); + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr getXattrs(int index) { + return xattrs_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttrOrBuilder getXattrsOrBuilder( + int index) { + return xattrs_.get(index); + } + + private void initFields() { + xattrs_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + for (int i = 0; i < getXattrsCount(); i++) { + if (!getXattrs(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < xattrs_.size(); i++) { + output.writeMessage(1, xattrs_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < xattrs_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, xattrs_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.listxattrResponse} + * + *
    +     * returns a list of extended attributes of a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_listxattrResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_listxattrResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getXattrsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (xattrsBuilder_ == null) { + xattrs_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + xattrsBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_listxattrResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse(this); + int from_bitField0_ = bitField0_; + if (xattrsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001)) { + xattrs_ = java.util.Collections.unmodifiableList(xattrs_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.xattrs_ = xattrs_; + } else { + result.xattrs_ = xattrsBuilder_.build(); + } + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse.getDefaultInstance()) return this; + if (xattrsBuilder_ == null) { + if (!other.xattrs_.isEmpty()) { + if (xattrs_.isEmpty()) { + xattrs_ = other.xattrs_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureXattrsIsMutable(); + xattrs_.addAll(other.xattrs_); + } + onChanged(); + } + } else { + if (!other.xattrs_.isEmpty()) { + if (xattrsBuilder_.isEmpty()) { + xattrsBuilder_.dispose(); + xattrsBuilder_ = null; + xattrs_ = other.xattrs_; + bitField0_ = (bitField0_ & ~0x00000001); + xattrsBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getXattrsFieldBuilder() : null; + } else { + xattrsBuilder_.addAllMessages(other.xattrs_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + for (int i = 0; i < getXattrsCount(); i++) { + if (!getXattrs(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + private java.util.List xattrs_ = + java.util.Collections.emptyList(); + private void ensureXattrsIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + xattrs_ = new java.util.ArrayList(xattrs_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttrOrBuilder> xattrsBuilder_; + + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public java.util.List getXattrsList() { + if (xattrsBuilder_ == null) { + return java.util.Collections.unmodifiableList(xattrs_); + } else { + return xattrsBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public int getXattrsCount() { + if (xattrsBuilder_ == null) { + return xattrs_.size(); + } else { + return xattrsBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr getXattrs(int index) { + if (xattrsBuilder_ == null) { + return xattrs_.get(index); + } else { + return xattrsBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public Builder setXattrs( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr value) { + if (xattrsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureXattrsIsMutable(); + xattrs_.set(index, value); + onChanged(); + } else { + xattrsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public Builder setXattrs( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder builderForValue) { + if (xattrsBuilder_ == null) { + ensureXattrsIsMutable(); + xattrs_.set(index, builderForValue.build()); + onChanged(); + } else { + xattrsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public Builder addXattrs(org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr value) { + if (xattrsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureXattrsIsMutable(); + xattrs_.add(value); + onChanged(); + } else { + xattrsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public Builder addXattrs( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr value) { + if (xattrsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureXattrsIsMutable(); + xattrs_.add(index, value); + onChanged(); + } else { + xattrsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public Builder addXattrs( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder builderForValue) { + if (xattrsBuilder_ == null) { + ensureXattrsIsMutable(); + xattrs_.add(builderForValue.build()); + onChanged(); + } else { + xattrsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public Builder addXattrs( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder builderForValue) { + if (xattrsBuilder_ == null) { + ensureXattrsIsMutable(); + xattrs_.add(index, builderForValue.build()); + onChanged(); + } else { + xattrsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public Builder addAllXattrs( + java.lang.Iterable values) { + if (xattrsBuilder_ == null) { + ensureXattrsIsMutable(); + super.addAll(values, xattrs_); + onChanged(); + } else { + xattrsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public Builder clearXattrs() { + if (xattrsBuilder_ == null) { + xattrs_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + xattrsBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public Builder removeXattrs(int index) { + if (xattrsBuilder_ == null) { + ensureXattrsIsMutable(); + xattrs_.remove(index); + onChanged(); + } else { + xattrsBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder getXattrsBuilder( + int index) { + return getXattrsFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttrOrBuilder getXattrsOrBuilder( + int index) { + if (xattrsBuilder_ == null) { + return xattrs_.get(index); } else { + return xattrsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public java.util.List + getXattrsOrBuilderList() { + if (xattrsBuilder_ != null) { + return xattrsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(xattrs_); + } + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder addXattrsBuilder() { + return getXattrsFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder addXattrsBuilder( + int index) { + return getXattrsFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.XAttr xattrs = 1; + */ + public java.util.List + getXattrsBuilderList() { + return getXattrsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttrOrBuilder> + getXattrsFieldBuilder() { + if (xattrsBuilder_ == null) { + xattrsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttrOrBuilder>( + xattrs_, + ((bitField0_ & 0x00000001) == 0x00000001), + getParentForChildren(), + isClean()); + xattrs_ = null; + } + return xattrsBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.listxattrResponse) + } + + static { + defaultInstance = new listxattrResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.listxattrResponse) + } + + public interface mkdirRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // required fixed32 mode = 3; + /** + * required fixed32 mode = 3; + * + *
    +     * the initial access mode of the newly created directory
    +     * 
    + */ + boolean hasMode(); + /** + * required fixed32 mode = 3; + * + *
    +     * the initial access mode of the newly created directory
    +     * 
    + */ + int getMode(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.mkdirRequest} + * + *
    +   * creates a new directory
    +   * 
    + */ + public static final class mkdirRequest extends + com.google.protobuf.GeneratedMessage + implements mkdirRequestOrBuilder { + // Use mkdirRequest.newBuilder() to construct. + private mkdirRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private mkdirRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final mkdirRequest defaultInstance; + public static mkdirRequest getDefaultInstance() { + return defaultInstance; + } + + public mkdirRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private mkdirRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 29: { + bitField0_ |= 0x00000004; + mode_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_mkdirRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_mkdirRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public mkdirRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new mkdirRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 mode = 3; + public static final int MODE_FIELD_NUMBER = 3; + private int mode_; + /** + * required fixed32 mode = 3; + * + *
    +     * the initial access mode of the newly created directory
    +     * 
    + */ + public boolean hasMode() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 mode = 3; + * + *
    +     * the initial access mode of the newly created directory
    +     * 
    + */ + public int getMode() { + return mode_; + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + mode_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMode()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed32(3, mode_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(3, mode_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.mkdirRequest} + * + *
    +     * creates a new directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_mkdirRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_mkdirRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + mode_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_mkdirRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.mode_ = mode_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasMode()) { + setMode(other.getMode()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + if (!hasMode()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.mkdirRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // required fixed32 mode = 3; + private int mode_ ; + /** + * required fixed32 mode = 3; + * + *
    +       * the initial access mode of the newly created directory
    +       * 
    + */ + public boolean hasMode() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 mode = 3; + * + *
    +       * the initial access mode of the newly created directory
    +       * 
    + */ + public int getMode() { + return mode_; + } + /** + * required fixed32 mode = 3; + * + *
    +       * the initial access mode of the newly created directory
    +       * 
    + */ + public Builder setMode(int value) { + bitField0_ |= 0x00000004; + mode_ = value; + onChanged(); + return this; + } + /** + * required fixed32 mode = 3; + * + *
    +       * the initial access mode of the newly created directory
    +       * 
    + */ + public Builder clearMode() { + bitField0_ = (bitField0_ & ~0x00000004); + mode_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.mkdirRequest) + } + + static { + defaultInstance = new mkdirRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.mkdirRequest) + } + + public interface openRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the file, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // required fixed32 flags = 3; + /** + * required fixed32 flags = 3; + * + *
    +     * a bitmap open flags, as defined in the specification of the POSIX
    +     *  'open' call, e.g. O_RDWR, O_RDONLY, O_CREAT, O_EXCL, O_TRUNC ...
    +     * 
    + */ + boolean hasFlags(); + /** + * required fixed32 flags = 3; + * + *
    +     * a bitmap open flags, as defined in the specification of the POSIX
    +     *  'open' call, e.g. O_RDWR, O_RDONLY, O_CREAT, O_EXCL, O_TRUNC ...
    +     * 
    + */ + int getFlags(); + + // required fixed32 mode = 4; + /** + * required fixed32 mode = 4; + * + *
    +     * the initial access mode for a file created w/ O_CREAT 
    +     * 
    + */ + boolean hasMode(); + /** + * required fixed32 mode = 4; + * + *
    +     * the initial access mode for a file created w/ O_CREAT 
    +     * 
    + */ + int getMode(); + + // required fixed32 attributes = 5; + /** + * required fixed32 attributes = 5; + * + *
    +     * the initial set of Win32-specific attributes
    +     * 
    + */ + boolean hasAttributes(); + /** + * required fixed32 attributes = 5; + * + *
    +     * the initial set of Win32-specific attributes
    +     * 
    + */ + int getAttributes(); + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +     * optional set of Vivaldi cooridnates of the client, which can be
    +     * used to order the list of replicas
    +     * 
    + */ + boolean hasCoordinates(); + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +     * optional set of Vivaldi cooridnates of the client, which can be
    +     * used to order the list of replicas
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates getCoordinates(); + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +     * optional set of Vivaldi cooridnates of the client, which can be
    +     * used to order the list of replicas
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder getCoordinatesOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.openRequest} + * + *
    +   * opens a file and requests file credentials
    +   * 
    + */ + public static final class openRequest extends + com.google.protobuf.GeneratedMessage + implements openRequestOrBuilder { + // Use openRequest.newBuilder() to construct. + private openRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private openRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final openRequest defaultInstance; + public static openRequest getDefaultInstance() { + return defaultInstance; + } + + public openRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private openRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 29: { + bitField0_ |= 0x00000004; + flags_ = input.readFixed32(); + break; + } + case 37: { + bitField0_ |= 0x00000008; + mode_ = input.readFixed32(); + break; + } + case 45: { + bitField0_ |= 0x00000010; + attributes_ = input.readFixed32(); + break; + } + case 50: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder subBuilder = null; + if (((bitField0_ & 0x00000020) == 0x00000020)) { + subBuilder = coordinates_.toBuilder(); + } + coordinates_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(coordinates_); + coordinates_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000020; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_openRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_openRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public openRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new openRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the file, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the file, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the file, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 flags = 3; + public static final int FLAGS_FIELD_NUMBER = 3; + private int flags_; + /** + * required fixed32 flags = 3; + * + *
    +     * a bitmap open flags, as defined in the specification of the POSIX
    +     *  'open' call, e.g. O_RDWR, O_RDONLY, O_CREAT, O_EXCL, O_TRUNC ...
    +     * 
    + */ + public boolean hasFlags() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 flags = 3; + * + *
    +     * a bitmap open flags, as defined in the specification of the POSIX
    +     *  'open' call, e.g. O_RDWR, O_RDONLY, O_CREAT, O_EXCL, O_TRUNC ...
    +     * 
    + */ + public int getFlags() { + return flags_; + } + + // required fixed32 mode = 4; + public static final int MODE_FIELD_NUMBER = 4; + private int mode_; + /** + * required fixed32 mode = 4; + * + *
    +     * the initial access mode for a file created w/ O_CREAT 
    +     * 
    + */ + public boolean hasMode() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 mode = 4; + * + *
    +     * the initial access mode for a file created w/ O_CREAT 
    +     * 
    + */ + public int getMode() { + return mode_; + } + + // required fixed32 attributes = 5; + public static final int ATTRIBUTES_FIELD_NUMBER = 5; + private int attributes_; + /** + * required fixed32 attributes = 5; + * + *
    +     * the initial set of Win32-specific attributes
    +     * 
    + */ + public boolean hasAttributes() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 attributes = 5; + * + *
    +     * the initial set of Win32-specific attributes
    +     * 
    + */ + public int getAttributes() { + return attributes_; + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + public static final int COORDINATES_FIELD_NUMBER = 6; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates coordinates_; + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +     * optional set of Vivaldi cooridnates of the client, which can be
    +     * used to order the list of replicas
    +     * 
    + */ + public boolean hasCoordinates() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +     * optional set of Vivaldi cooridnates of the client, which can be
    +     * used to order the list of replicas
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates getCoordinates() { + return coordinates_; + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +     * optional set of Vivaldi cooridnates of the client, which can be
    +     * used to order the list of replicas
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder getCoordinatesOrBuilder() { + return coordinates_; + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + flags_ = 0; + mode_ = 0; + attributes_ = 0; + coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFlags()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMode()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasAttributes()) { + memoizedIsInitialized = 0; + return false; + } + if (hasCoordinates()) { + if (!getCoordinates().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed32(3, flags_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed32(4, mode_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeFixed32(5, attributes_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeMessage(6, coordinates_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(3, flags_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(4, mode_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(5, attributes_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(6, coordinates_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.openRequest} + * + *
    +     * opens a file and requests file credentials
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_openRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_openRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getCoordinatesFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + flags_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + mode_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + attributes_ = 0; + bitField0_ = (bitField0_ & ~0x00000010); + if (coordinatesBuilder_ == null) { + coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + } else { + coordinatesBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000020); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_openRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.flags_ = flags_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.mode_ = mode_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.attributes_ = attributes_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + if (coordinatesBuilder_ == null) { + result.coordinates_ = coordinates_; + } else { + result.coordinates_ = coordinatesBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasFlags()) { + setFlags(other.getFlags()); + } + if (other.hasMode()) { + setMode(other.getMode()); + } + if (other.hasAttributes()) { + setAttributes(other.getAttributes()); + } + if (other.hasCoordinates()) { + mergeCoordinates(other.getCoordinates()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + if (!hasFlags()) { + + return false; + } + if (!hasMode()) { + + return false; + } + if (!hasAttributes()) { + + return false; + } + if (hasCoordinates()) { + if (!getCoordinates().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the file, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the file, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // required fixed32 flags = 3; + private int flags_ ; + /** + * required fixed32 flags = 3; + * + *
    +       * a bitmap open flags, as defined in the specification of the POSIX
    +       *  'open' call, e.g. O_RDWR, O_RDONLY, O_CREAT, O_EXCL, O_TRUNC ...
    +       * 
    + */ + public boolean hasFlags() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 flags = 3; + * + *
    +       * a bitmap open flags, as defined in the specification of the POSIX
    +       *  'open' call, e.g. O_RDWR, O_RDONLY, O_CREAT, O_EXCL, O_TRUNC ...
    +       * 
    + */ + public int getFlags() { + return flags_; + } + /** + * required fixed32 flags = 3; + * + *
    +       * a bitmap open flags, as defined in the specification of the POSIX
    +       *  'open' call, e.g. O_RDWR, O_RDONLY, O_CREAT, O_EXCL, O_TRUNC ...
    +       * 
    + */ + public Builder setFlags(int value) { + bitField0_ |= 0x00000004; + flags_ = value; + onChanged(); + return this; + } + /** + * required fixed32 flags = 3; + * + *
    +       * a bitmap open flags, as defined in the specification of the POSIX
    +       *  'open' call, e.g. O_RDWR, O_RDONLY, O_CREAT, O_EXCL, O_TRUNC ...
    +       * 
    + */ + public Builder clearFlags() { + bitField0_ = (bitField0_ & ~0x00000004); + flags_ = 0; + onChanged(); + return this; + } + + // required fixed32 mode = 4; + private int mode_ ; + /** + * required fixed32 mode = 4; + * + *
    +       * the initial access mode for a file created w/ O_CREAT 
    +       * 
    + */ + public boolean hasMode() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 mode = 4; + * + *
    +       * the initial access mode for a file created w/ O_CREAT 
    +       * 
    + */ + public int getMode() { + return mode_; + } + /** + * required fixed32 mode = 4; + * + *
    +       * the initial access mode for a file created w/ O_CREAT 
    +       * 
    + */ + public Builder setMode(int value) { + bitField0_ |= 0x00000008; + mode_ = value; + onChanged(); + return this; + } + /** + * required fixed32 mode = 4; + * + *
    +       * the initial access mode for a file created w/ O_CREAT 
    +       * 
    + */ + public Builder clearMode() { + bitField0_ = (bitField0_ & ~0x00000008); + mode_ = 0; + onChanged(); + return this; + } + + // required fixed32 attributes = 5; + private int attributes_ ; + /** + * required fixed32 attributes = 5; + * + *
    +       * the initial set of Win32-specific attributes
    +       * 
    + */ + public boolean hasAttributes() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 attributes = 5; + * + *
    +       * the initial set of Win32-specific attributes
    +       * 
    + */ + public int getAttributes() { + return attributes_; + } + /** + * required fixed32 attributes = 5; + * + *
    +       * the initial set of Win32-specific attributes
    +       * 
    + */ + public Builder setAttributes(int value) { + bitField0_ |= 0x00000010; + attributes_ = value; + onChanged(); + return this; + } + /** + * required fixed32 attributes = 5; + * + *
    +       * the initial set of Win32-specific attributes
    +       * 
    + */ + public Builder clearAttributes() { + bitField0_ = (bitField0_ & ~0x00000010); + attributes_ = 0; + onChanged(); + return this; + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder> coordinatesBuilder_; + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +       * optional set of Vivaldi cooridnates of the client, which can be
    +       * used to order the list of replicas
    +       * 
    + */ + public boolean hasCoordinates() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +       * optional set of Vivaldi cooridnates of the client, which can be
    +       * used to order the list of replicas
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates getCoordinates() { + if (coordinatesBuilder_ == null) { + return coordinates_; + } else { + return coordinatesBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +       * optional set of Vivaldi cooridnates of the client, which can be
    +       * used to order the list of replicas
    +       * 
    + */ + public Builder setCoordinates(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates value) { + if (coordinatesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + coordinates_ = value; + onChanged(); + } else { + coordinatesBuilder_.setMessage(value); + } + bitField0_ |= 0x00000020; + return this; + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +       * optional set of Vivaldi cooridnates of the client, which can be
    +       * used to order the list of replicas
    +       * 
    + */ + public Builder setCoordinates( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder builderForValue) { + if (coordinatesBuilder_ == null) { + coordinates_ = builderForValue.build(); + onChanged(); + } else { + coordinatesBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000020; + return this; + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +       * optional set of Vivaldi cooridnates of the client, which can be
    +       * used to order the list of replicas
    +       * 
    + */ + public Builder mergeCoordinates(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates value) { + if (coordinatesBuilder_ == null) { + if (((bitField0_ & 0x00000020) == 0x00000020) && + coordinates_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance()) { + coordinates_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.newBuilder(coordinates_).mergeFrom(value).buildPartial(); + } else { + coordinates_ = value; + } + onChanged(); + } else { + coordinatesBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000020; + return this; + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +       * optional set of Vivaldi cooridnates of the client, which can be
    +       * used to order the list of replicas
    +       * 
    + */ + public Builder clearCoordinates() { + if (coordinatesBuilder_ == null) { + coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + onChanged(); + } else { + coordinatesBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000020); + return this; + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +       * optional set of Vivaldi cooridnates of the client, which can be
    +       * used to order the list of replicas
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder getCoordinatesBuilder() { + bitField0_ |= 0x00000020; + onChanged(); + return getCoordinatesFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +       * optional set of Vivaldi cooridnates of the client, which can be
    +       * used to order the list of replicas
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder getCoordinatesOrBuilder() { + if (coordinatesBuilder_ != null) { + return coordinatesBuilder_.getMessageOrBuilder(); + } else { + return coordinates_; + } + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 6; + * + *
    +       * optional set of Vivaldi cooridnates of the client, which can be
    +       * used to order the list of replicas
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder> + getCoordinatesFieldBuilder() { + if (coordinatesBuilder_ == null) { + coordinatesBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder>( + coordinates_, + getParentForChildren(), + isClean()); + coordinates_ = null; + } + return coordinatesBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.openRequest) + } + + static { + defaultInstance = new openRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.openRequest) + } + + public interface openResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials creds = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +     * the file credentials
    +     * 
    + */ + boolean hasCreds(); + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +     * the file credentials
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getCreds(); + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +     * the file credentials
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getCredsOrBuilder(); + + // required fixed32 timestamp_s = 2; + /** + * required fixed32 timestamp_s = 2; + * + *
    +     * the server timestamp in seconds since 1970 to which the file
    +     * timestamps were updated
    +     * 
    + */ + boolean hasTimestampS(); + /** + * required fixed32 timestamp_s = 2; + * + *
    +     * the server timestamp in seconds since 1970 to which the file
    +     * timestamps were updated
    +     * 
    + */ + int getTimestampS(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.openResponse} + * + *
    +   * returns a set of file credentials
    +   * 
    + */ + public static final class openResponse extends + com.google.protobuf.GeneratedMessage + implements openResponseOrBuilder { + // Use openResponse.newBuilder() to construct. + private openResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private openResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final openResponse defaultInstance; + public static openResponse getDefaultInstance() { + return defaultInstance; + } + + public openResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private openResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = creds_.toBuilder(); + } + creds_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(creds_); + creds_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 21: { + bitField0_ |= 0x00000002; + timestampS_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_openResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_openResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public openResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new openResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials creds = 1; + public static final int CREDS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials creds_; + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +     * the file credentials
    +     * 
    + */ + public boolean hasCreds() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +     * the file credentials
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getCreds() { + return creds_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +     * the file credentials
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getCredsOrBuilder() { + return creds_; + } + + // required fixed32 timestamp_s = 2; + public static final int TIMESTAMP_S_FIELD_NUMBER = 2; + private int timestampS_; + /** + * required fixed32 timestamp_s = 2; + * + *
    +     * the server timestamp in seconds since 1970 to which the file
    +     * timestamps were updated
    +     * 
    + */ + public boolean hasTimestampS() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 timestamp_s = 2; + * + *
    +     * the server timestamp in seconds since 1970 to which the file
    +     * timestamps were updated
    +     * 
    + */ + public int getTimestampS() { + return timestampS_; + } + + private void initFields() { + creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + timestampS_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasCreds()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTimestampS()) { + memoizedIsInitialized = 0; + return false; + } + if (!getCreds().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, creds_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed32(2, timestampS_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, creds_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(2, timestampS_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.openResponse} + * + *
    +     * returns a set of file credentials
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_openResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_openResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getCredsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (credsBuilder_ == null) { + creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + credsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + timestampS_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_openResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (credsBuilder_ == null) { + result.creds_ = creds_; + } else { + result.creds_ = credsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.timestampS_ = timestampS_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse.getDefaultInstance()) return this; + if (other.hasCreds()) { + mergeCreds(other.getCreds()); + } + if (other.hasTimestampS()) { + setTimestampS(other.getTimestampS()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasCreds()) { + + return false; + } + if (!hasTimestampS()) { + + return false; + } + if (!getCreds().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials creds = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> credsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +       * the file credentials
    +       * 
    + */ + public boolean hasCreds() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +       * the file credentials
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getCreds() { + if (credsBuilder_ == null) { + return creds_; + } else { + return credsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +       * the file credentials
    +       * 
    + */ + public Builder setCreds(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (credsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + creds_ = value; + onChanged(); + } else { + credsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +       * the file credentials
    +       * 
    + */ + public Builder setCreds( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (credsBuilder_ == null) { + creds_ = builderForValue.build(); + onChanged(); + } else { + credsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +       * the file credentials
    +       * 
    + */ + public Builder mergeCreds(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (credsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + creds_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + creds_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(creds_).mergeFrom(value).buildPartial(); + } else { + creds_ = value; + } + onChanged(); + } else { + credsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +       * the file credentials
    +       * 
    + */ + public Builder clearCreds() { + if (credsBuilder_ == null) { + creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + credsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +       * the file credentials
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getCredsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getCredsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +       * the file credentials
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getCredsOrBuilder() { + if (credsBuilder_ != null) { + return credsBuilder_.getMessageOrBuilder(); + } else { + return creds_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials creds = 1; + * + *
    +       * the file credentials
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getCredsFieldBuilder() { + if (credsBuilder_ == null) { + credsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + creds_, + getParentForChildren(), + isClean()); + creds_ = null; + } + return credsBuilder_; + } + + // required fixed32 timestamp_s = 2; + private int timestampS_ ; + /** + * required fixed32 timestamp_s = 2; + * + *
    +       * the server timestamp in seconds since 1970 to which the file
    +       * timestamps were updated
    +       * 
    + */ + public boolean hasTimestampS() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 timestamp_s = 2; + * + *
    +       * the server timestamp in seconds since 1970 to which the file
    +       * timestamps were updated
    +       * 
    + */ + public int getTimestampS() { + return timestampS_; + } + /** + * required fixed32 timestamp_s = 2; + * + *
    +       * the server timestamp in seconds since 1970 to which the file
    +       * timestamps were updated
    +       * 
    + */ + public Builder setTimestampS(int value) { + bitField0_ |= 0x00000002; + timestampS_ = value; + onChanged(); + return this; + } + /** + * required fixed32 timestamp_s = 2; + * + *
    +       * the server timestamp in seconds since 1970 to which the file
    +       * timestamps were updated
    +       * 
    + */ + public Builder clearTimestampS() { + bitField0_ = (bitField0_ & ~0x00000002); + timestampS_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.openResponse) + } + + static { + defaultInstance = new openResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.openResponse) + } + + public interface readdirRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the directory, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the directory, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the directory, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // required fixed64 known_etag = 3; + /** + * required fixed64 known_etag = 3; + * + *
    +     * an identification tag indicating the last known version of the directory
    +     * content
    +     * 
    + */ + boolean hasKnownEtag(); + /** + * required fixed64 known_etag = 3; + * + *
    +     * an identification tag indicating the last known version of the directory
    +     * content
    +     * 
    + */ + long getKnownEtag(); + + // required fixed32 limit_directory_entries_count = 4; + /** + * required fixed32 limit_directory_entries_count = 4; + * + *
    +     * the maximum number of directory entries to return
    +     * 
    + */ + boolean hasLimitDirectoryEntriesCount(); + /** + * required fixed32 limit_directory_entries_count = 4; + * + *
    +     * the maximum number of directory entries to return
    +     * 
    + */ + int getLimitDirectoryEntriesCount(); + + // required bool names_only = 5; + /** + * required bool names_only = 5; + * + *
    +     * a flag indicating that only names of nested files and directories are
    +     * supposed to be returned, no attributes
    +     * 
    + */ + boolean hasNamesOnly(); + /** + * required bool names_only = 5; + * + *
    +     * a flag indicating that only names of nested files and directories are
    +     * supposed to be returned, no attributes
    +     * 
    + */ + boolean getNamesOnly(); + + // required fixed64 seen_directory_entries_count = 6; + /** + * required fixed64 seen_directory_entries_count = 6; + * + *
    +     * the number of directory entries that have been returned already by
    +     * previous calls
    +     * 
    + */ + boolean hasSeenDirectoryEntriesCount(); + /** + * required fixed64 seen_directory_entries_count = 6; + * + *
    +     * the number of directory entries that have been returned already by
    +     * previous calls
    +     * 
    + */ + long getSeenDirectoryEntriesCount(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.readdirRequest} + * + *
    +   * requests the content of a directory
    +   * 
    + */ + public static final class readdirRequest extends + com.google.protobuf.GeneratedMessage + implements readdirRequestOrBuilder { + // Use readdirRequest.newBuilder() to construct. + private readdirRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private readdirRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final readdirRequest defaultInstance; + public static readdirRequest getDefaultInstance() { + return defaultInstance; + } + + public readdirRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private readdirRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + knownEtag_ = input.readFixed64(); + break; + } + case 37: { + bitField0_ |= 0x00000008; + limitDirectoryEntriesCount_ = input.readFixed32(); + break; + } + case 40: { + bitField0_ |= 0x00000010; + namesOnly_ = input.readBool(); + break; + } + case 49: { + bitField0_ |= 0x00000020; + seenDirectoryEntriesCount_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readdirRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readdirRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public readdirRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new readdirRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the directory, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the directory, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the directory, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 known_etag = 3; + public static final int KNOWN_ETAG_FIELD_NUMBER = 3; + private long knownEtag_; + /** + * required fixed64 known_etag = 3; + * + *
    +     * an identification tag indicating the last known version of the directory
    +     * content
    +     * 
    + */ + public boolean hasKnownEtag() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 known_etag = 3; + * + *
    +     * an identification tag indicating the last known version of the directory
    +     * content
    +     * 
    + */ + public long getKnownEtag() { + return knownEtag_; + } + + // required fixed32 limit_directory_entries_count = 4; + public static final int LIMIT_DIRECTORY_ENTRIES_COUNT_FIELD_NUMBER = 4; + private int limitDirectoryEntriesCount_; + /** + * required fixed32 limit_directory_entries_count = 4; + * + *
    +     * the maximum number of directory entries to return
    +     * 
    + */ + public boolean hasLimitDirectoryEntriesCount() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 limit_directory_entries_count = 4; + * + *
    +     * the maximum number of directory entries to return
    +     * 
    + */ + public int getLimitDirectoryEntriesCount() { + return limitDirectoryEntriesCount_; + } + + // required bool names_only = 5; + public static final int NAMES_ONLY_FIELD_NUMBER = 5; + private boolean namesOnly_; + /** + * required bool names_only = 5; + * + *
    +     * a flag indicating that only names of nested files and directories are
    +     * supposed to be returned, no attributes
    +     * 
    + */ + public boolean hasNamesOnly() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required bool names_only = 5; + * + *
    +     * a flag indicating that only names of nested files and directories are
    +     * supposed to be returned, no attributes
    +     * 
    + */ + public boolean getNamesOnly() { + return namesOnly_; + } + + // required fixed64 seen_directory_entries_count = 6; + public static final int SEEN_DIRECTORY_ENTRIES_COUNT_FIELD_NUMBER = 6; + private long seenDirectoryEntriesCount_; + /** + * required fixed64 seen_directory_entries_count = 6; + * + *
    +     * the number of directory entries that have been returned already by
    +     * previous calls
    +     * 
    + */ + public boolean hasSeenDirectoryEntriesCount() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed64 seen_directory_entries_count = 6; + * + *
    +     * the number of directory entries that have been returned already by
    +     * previous calls
    +     * 
    + */ + public long getSeenDirectoryEntriesCount() { + return seenDirectoryEntriesCount_; + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + knownEtag_ = 0L; + limitDirectoryEntriesCount_ = 0; + namesOnly_ = false; + seenDirectoryEntriesCount_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasKnownEtag()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLimitDirectoryEntriesCount()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasNamesOnly()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasSeenDirectoryEntriesCount()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, knownEtag_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed32(4, limitDirectoryEntriesCount_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeBool(5, namesOnly_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeFixed64(6, seenDirectoryEntriesCount_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, knownEtag_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(4, limitDirectoryEntriesCount_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(5, namesOnly_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(6, seenDirectoryEntriesCount_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.readdirRequest} + * + *
    +     * requests the content of a directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readdirRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readdirRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + knownEtag_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + limitDirectoryEntriesCount_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + namesOnly_ = false; + bitField0_ = (bitField0_ & ~0x00000010); + seenDirectoryEntriesCount_ = 0L; + bitField0_ = (bitField0_ & ~0x00000020); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readdirRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.knownEtag_ = knownEtag_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.limitDirectoryEntriesCount_ = limitDirectoryEntriesCount_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.namesOnly_ = namesOnly_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.seenDirectoryEntriesCount_ = seenDirectoryEntriesCount_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasKnownEtag()) { + setKnownEtag(other.getKnownEtag()); + } + if (other.hasLimitDirectoryEntriesCount()) { + setLimitDirectoryEntriesCount(other.getLimitDirectoryEntriesCount()); + } + if (other.hasNamesOnly()) { + setNamesOnly(other.getNamesOnly()); + } + if (other.hasSeenDirectoryEntriesCount()) { + setSeenDirectoryEntriesCount(other.getSeenDirectoryEntriesCount()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + if (!hasKnownEtag()) { + + return false; + } + if (!hasLimitDirectoryEntriesCount()) { + + return false; + } + if (!hasNamesOnly()) { + + return false; + } + if (!hasSeenDirectoryEntriesCount()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.readdirRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the directory, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the directory, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the directory, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the directory, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the directory, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the directory, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // required fixed64 known_etag = 3; + private long knownEtag_ ; + /** + * required fixed64 known_etag = 3; + * + *
    +       * an identification tag indicating the last known version of the directory
    +       * content
    +       * 
    + */ + public boolean hasKnownEtag() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 known_etag = 3; + * + *
    +       * an identification tag indicating the last known version of the directory
    +       * content
    +       * 
    + */ + public long getKnownEtag() { + return knownEtag_; + } + /** + * required fixed64 known_etag = 3; + * + *
    +       * an identification tag indicating the last known version of the directory
    +       * content
    +       * 
    + */ + public Builder setKnownEtag(long value) { + bitField0_ |= 0x00000004; + knownEtag_ = value; + onChanged(); + return this; + } + /** + * required fixed64 known_etag = 3; + * + *
    +       * an identification tag indicating the last known version of the directory
    +       * content
    +       * 
    + */ + public Builder clearKnownEtag() { + bitField0_ = (bitField0_ & ~0x00000004); + knownEtag_ = 0L; + onChanged(); + return this; + } + + // required fixed32 limit_directory_entries_count = 4; + private int limitDirectoryEntriesCount_ ; + /** + * required fixed32 limit_directory_entries_count = 4; + * + *
    +       * the maximum number of directory entries to return
    +       * 
    + */ + public boolean hasLimitDirectoryEntriesCount() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 limit_directory_entries_count = 4; + * + *
    +       * the maximum number of directory entries to return
    +       * 
    + */ + public int getLimitDirectoryEntriesCount() { + return limitDirectoryEntriesCount_; + } + /** + * required fixed32 limit_directory_entries_count = 4; + * + *
    +       * the maximum number of directory entries to return
    +       * 
    + */ + public Builder setLimitDirectoryEntriesCount(int value) { + bitField0_ |= 0x00000008; + limitDirectoryEntriesCount_ = value; + onChanged(); + return this; + } + /** + * required fixed32 limit_directory_entries_count = 4; + * + *
    +       * the maximum number of directory entries to return
    +       * 
    + */ + public Builder clearLimitDirectoryEntriesCount() { + bitField0_ = (bitField0_ & ~0x00000008); + limitDirectoryEntriesCount_ = 0; + onChanged(); + return this; + } + + // required bool names_only = 5; + private boolean namesOnly_ ; + /** + * required bool names_only = 5; + * + *
    +       * a flag indicating that only names of nested files and directories are
    +       * supposed to be returned, no attributes
    +       * 
    + */ + public boolean hasNamesOnly() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required bool names_only = 5; + * + *
    +       * a flag indicating that only names of nested files and directories are
    +       * supposed to be returned, no attributes
    +       * 
    + */ + public boolean getNamesOnly() { + return namesOnly_; + } + /** + * required bool names_only = 5; + * + *
    +       * a flag indicating that only names of nested files and directories are
    +       * supposed to be returned, no attributes
    +       * 
    + */ + public Builder setNamesOnly(boolean value) { + bitField0_ |= 0x00000010; + namesOnly_ = value; + onChanged(); + return this; + } + /** + * required bool names_only = 5; + * + *
    +       * a flag indicating that only names of nested files and directories are
    +       * supposed to be returned, no attributes
    +       * 
    + */ + public Builder clearNamesOnly() { + bitField0_ = (bitField0_ & ~0x00000010); + namesOnly_ = false; + onChanged(); + return this; + } + + // required fixed64 seen_directory_entries_count = 6; + private long seenDirectoryEntriesCount_ ; + /** + * required fixed64 seen_directory_entries_count = 6; + * + *
    +       * the number of directory entries that have been returned already by
    +       * previous calls
    +       * 
    + */ + public boolean hasSeenDirectoryEntriesCount() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed64 seen_directory_entries_count = 6; + * + *
    +       * the number of directory entries that have been returned already by
    +       * previous calls
    +       * 
    + */ + public long getSeenDirectoryEntriesCount() { + return seenDirectoryEntriesCount_; + } + /** + * required fixed64 seen_directory_entries_count = 6; + * + *
    +       * the number of directory entries that have been returned already by
    +       * previous calls
    +       * 
    + */ + public Builder setSeenDirectoryEntriesCount(long value) { + bitField0_ |= 0x00000020; + seenDirectoryEntriesCount_ = value; + onChanged(); + return this; + } + /** + * required fixed64 seen_directory_entries_count = 6; + * + *
    +       * the number of directory entries that have been returned already by
    +       * previous calls
    +       * 
    + */ + public Builder clearSeenDirectoryEntriesCount() { + bitField0_ = (bitField0_ & ~0x00000020); + seenDirectoryEntriesCount_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.readdirRequest) + } + + static { + defaultInstance = new readdirRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.readdirRequest) + } + + public interface readlinkRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the symbolic link, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the symbolic link, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the symbolic link, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.readlinkRequest} + * + *
    +   * requests the target path of a symbolic link
    +   * 
    + */ + public static final class readlinkRequest extends + com.google.protobuf.GeneratedMessage + implements readlinkRequestOrBuilder { + // Use readlinkRequest.newBuilder() to construct. + private readlinkRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private readlinkRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final readlinkRequest defaultInstance; + public static readlinkRequest getDefaultInstance() { + return defaultInstance; + } + + public readlinkRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private readlinkRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readlinkRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readlinkRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public readlinkRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new readlinkRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the symbolic link, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the symbolic link, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the symbolic link, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.readlinkRequest} + * + *
    +     * requests the target path of a symbolic link
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readlinkRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readlinkRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readlinkRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the symbolic link, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the symbolic link, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the symbolic link, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the symbolic link, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the symbolic link, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the symbolic link, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.readlinkRequest) + } + + static { + defaultInstance = new readlinkRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.readlinkRequest) + } + + public interface readlinkResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated string link_target_path = 1; + /** + * repeated string link_target_path = 1; + */ + java.util.List + getLinkTargetPathList(); + /** + * repeated string link_target_path = 1; + */ + int getLinkTargetPathCount(); + /** + * repeated string link_target_path = 1; + */ + java.lang.String getLinkTargetPath(int index); + /** + * repeated string link_target_path = 1; + */ + com.google.protobuf.ByteString + getLinkTargetPathBytes(int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.readlinkResponse} + * + *
    +   * returns the target path of a symbolic link
    +   * 
    + */ + public static final class readlinkResponse extends + com.google.protobuf.GeneratedMessage + implements readlinkResponseOrBuilder { + // Use readlinkResponse.newBuilder() to construct. + private readlinkResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private readlinkResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final readlinkResponse defaultInstance; + public static readlinkResponse getDefaultInstance() { + return defaultInstance; + } + + public readlinkResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private readlinkResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + linkTargetPath_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000001; + } + linkTargetPath_.add(input.readBytes()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + linkTargetPath_ = new com.google.protobuf.UnmodifiableLazyStringList(linkTargetPath_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readlinkResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readlinkResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public readlinkResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new readlinkResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated string link_target_path = 1; + public static final int LINK_TARGET_PATH_FIELD_NUMBER = 1; + private com.google.protobuf.LazyStringList linkTargetPath_; + /** + * repeated string link_target_path = 1; + */ + public java.util.List + getLinkTargetPathList() { + return linkTargetPath_; + } + /** + * repeated string link_target_path = 1; + */ + public int getLinkTargetPathCount() { + return linkTargetPath_.size(); + } + /** + * repeated string link_target_path = 1; + */ + public java.lang.String getLinkTargetPath(int index) { + return linkTargetPath_.get(index); + } + /** + * repeated string link_target_path = 1; + */ + public com.google.protobuf.ByteString + getLinkTargetPathBytes(int index) { + return linkTargetPath_.getByteString(index); + } + + private void initFields() { + linkTargetPath_ = com.google.protobuf.LazyStringArrayList.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < linkTargetPath_.size(); i++) { + output.writeBytes(1, linkTargetPath_.getByteString(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < linkTargetPath_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(linkTargetPath_.getByteString(i)); + } + size += dataSize; + size += 1 * getLinkTargetPathList().size(); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.readlinkResponse} + * + *
    +     * returns the target path of a symbolic link
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readlinkResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readlinkResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + linkTargetPath_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_readlinkResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse(this); + int from_bitField0_ = bitField0_; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + linkTargetPath_ = new com.google.protobuf.UnmodifiableLazyStringList( + linkTargetPath_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.linkTargetPath_ = linkTargetPath_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse.getDefaultInstance()) return this; + if (!other.linkTargetPath_.isEmpty()) { + if (linkTargetPath_.isEmpty()) { + linkTargetPath_ = other.linkTargetPath_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureLinkTargetPathIsMutable(); + linkTargetPath_.addAll(other.linkTargetPath_); + } + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.readlinkResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated string link_target_path = 1; + private com.google.protobuf.LazyStringList linkTargetPath_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureLinkTargetPathIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + linkTargetPath_ = new com.google.protobuf.LazyStringArrayList(linkTargetPath_); + bitField0_ |= 0x00000001; + } + } + /** + * repeated string link_target_path = 1; + */ + public java.util.List + getLinkTargetPathList() { + return java.util.Collections.unmodifiableList(linkTargetPath_); + } + /** + * repeated string link_target_path = 1; + */ + public int getLinkTargetPathCount() { + return linkTargetPath_.size(); + } + /** + * repeated string link_target_path = 1; + */ + public java.lang.String getLinkTargetPath(int index) { + return linkTargetPath_.get(index); + } + /** + * repeated string link_target_path = 1; + */ + public com.google.protobuf.ByteString + getLinkTargetPathBytes(int index) { + return linkTargetPath_.getByteString(index); + } + /** + * repeated string link_target_path = 1; + */ + public Builder setLinkTargetPath( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureLinkTargetPathIsMutable(); + linkTargetPath_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string link_target_path = 1; + */ + public Builder addLinkTargetPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureLinkTargetPathIsMutable(); + linkTargetPath_.add(value); + onChanged(); + return this; + } + /** + * repeated string link_target_path = 1; + */ + public Builder addAllLinkTargetPath( + java.lang.Iterable values) { + ensureLinkTargetPathIsMutable(); + super.addAll(values, linkTargetPath_); + onChanged(); + return this; + } + /** + * repeated string link_target_path = 1; + */ + public Builder clearLinkTargetPath() { + linkTargetPath_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * repeated string link_target_path = 1; + */ + public Builder addLinkTargetPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureLinkTargetPathIsMutable(); + linkTargetPath_.add(value); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.readlinkResponse) + } + + static { + defaultInstance = new readlinkResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.readlinkResponse) + } + + public interface removexattrRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // required string name = 3; + /** + * required string name = 3; + * + *
    +     * the name of the attribute to remove
    +     * 
    + */ + boolean hasName(); + /** + * required string name = 3; + * + *
    +     * the name of the attribute to remove
    +     * 
    + */ + java.lang.String getName(); + /** + * required string name = 3; + * + *
    +     * the name of the attribute to remove
    +     * 
    + */ + com.google.protobuf.ByteString + getNameBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.removexattrRequest} + * + *
    +   * removes an extended attribute from a file or directory
    +   * 
    + */ + public static final class removexattrRequest extends + com.google.protobuf.GeneratedMessage + implements removexattrRequestOrBuilder { + // Use removexattrRequest.newBuilder() to construct. + private removexattrRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private removexattrRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final removexattrRequest defaultInstance; + public static removexattrRequest getDefaultInstance() { + return defaultInstance; + } + + public removexattrRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private removexattrRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + name_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_removexattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_removexattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public removexattrRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new removexattrRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string name = 3; + public static final int NAME_FIELD_NUMBER = 3; + private java.lang.Object name_; + /** + * required string name = 3; + * + *
    +     * the name of the attribute to remove
    +     * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string name = 3; + * + *
    +     * the name of the attribute to remove
    +     * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * required string name = 3; + * + *
    +     * the name of the attribute to remove
    +     * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + name_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasName()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getNameBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getNameBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.removexattrRequest} + * + *
    +     * removes an extended attribute from a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_removexattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_removexattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_removexattrRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.name_ = name_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasName()) { + bitField0_ |= 0x00000004; + name_ = other.name_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + if (!hasName()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.removexattrRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // required string name = 3; + private java.lang.Object name_ = ""; + /** + * required string name = 3; + * + *
    +       * the name of the attribute to remove
    +       * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string name = 3; + * + *
    +       * the name of the attribute to remove
    +       * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string name = 3; + * + *
    +       * the name of the attribute to remove
    +       * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string name = 3; + * + *
    +       * the name of the attribute to remove
    +       * 
    + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + name_ = value; + onChanged(); + return this; + } + /** + * required string name = 3; + * + *
    +       * the name of the attribute to remove
    +       * 
    + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000004); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * required string name = 3; + * + *
    +       * the name of the attribute to remove
    +       * 
    + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + name_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.removexattrRequest) + } + + static { + defaultInstance = new removexattrRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.removexattrRequest) + } + + public interface renameRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string source_path = 2; + /** + * required string source_path = 2; + * + *
    +     * the pathname to the file or directory to change 
    +     * 
    + */ + boolean hasSourcePath(); + /** + * required string source_path = 2; + * + *
    +     * the pathname to the file or directory to change 
    +     * 
    + */ + java.lang.String getSourcePath(); + /** + * required string source_path = 2; + * + *
    +     * the pathname to the file or directory to change 
    +     * 
    + */ + com.google.protobuf.ByteString + getSourcePathBytes(); + + // required string target_path = 3; + /** + * required string target_path = 3; + * + *
    +     * the new path name for the file or directory
    +     * 
    + */ + boolean hasTargetPath(); + /** + * required string target_path = 3; + * + *
    +     * the new path name for the file or directory
    +     * 
    + */ + java.lang.String getTargetPath(); + /** + * required string target_path = 3; + * + *
    +     * the new path name for the file or directory
    +     * 
    + */ + com.google.protobuf.ByteString + getTargetPathBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.renameRequest} + * + *
    +   * changes the path name of a file or directory
    +   * 
    + */ + public static final class renameRequest extends + com.google.protobuf.GeneratedMessage + implements renameRequestOrBuilder { + // Use renameRequest.newBuilder() to construct. + private renameRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private renameRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final renameRequest defaultInstance; + public static renameRequest getDefaultInstance() { + return defaultInstance; + } + + public renameRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private renameRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + sourcePath_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + targetPath_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_renameRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_renameRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public renameRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new renameRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string source_path = 2; + public static final int SOURCE_PATH_FIELD_NUMBER = 2; + private java.lang.Object sourcePath_; + /** + * required string source_path = 2; + * + *
    +     * the pathname to the file or directory to change 
    +     * 
    + */ + public boolean hasSourcePath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string source_path = 2; + * + *
    +     * the pathname to the file or directory to change 
    +     * 
    + */ + public java.lang.String getSourcePath() { + java.lang.Object ref = sourcePath_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + sourcePath_ = s; + } + return s; + } + } + /** + * required string source_path = 2; + * + *
    +     * the pathname to the file or directory to change 
    +     * 
    + */ + public com.google.protobuf.ByteString + getSourcePathBytes() { + java.lang.Object ref = sourcePath_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + sourcePath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string target_path = 3; + public static final int TARGET_PATH_FIELD_NUMBER = 3; + private java.lang.Object targetPath_; + /** + * required string target_path = 3; + * + *
    +     * the new path name for the file or directory
    +     * 
    + */ + public boolean hasTargetPath() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string target_path = 3; + * + *
    +     * the new path name for the file or directory
    +     * 
    + */ + public java.lang.String getTargetPath() { + java.lang.Object ref = targetPath_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + targetPath_ = s; + } + return s; + } + } + /** + * required string target_path = 3; + * + *
    +     * the new path name for the file or directory
    +     * 
    + */ + public com.google.protobuf.ByteString + getTargetPathBytes() { + java.lang.Object ref = targetPath_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + targetPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + volumeName_ = ""; + sourcePath_ = ""; + targetPath_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasSourcePath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTargetPath()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getSourcePathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getTargetPathBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getSourcePathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getTargetPathBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.renameRequest} + * + *
    +     * changes the path name of a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_renameRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_renameRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + sourcePath_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + targetPath_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_renameRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.sourcePath_ = sourcePath_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.targetPath_ = targetPath_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasSourcePath()) { + bitField0_ |= 0x00000002; + sourcePath_ = other.sourcePath_; + onChanged(); + } + if (other.hasTargetPath()) { + bitField0_ |= 0x00000004; + targetPath_ = other.targetPath_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasSourcePath()) { + + return false; + } + if (!hasTargetPath()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string source_path = 2; + private java.lang.Object sourcePath_ = ""; + /** + * required string source_path = 2; + * + *
    +       * the pathname to the file or directory to change 
    +       * 
    + */ + public boolean hasSourcePath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string source_path = 2; + * + *
    +       * the pathname to the file or directory to change 
    +       * 
    + */ + public java.lang.String getSourcePath() { + java.lang.Object ref = sourcePath_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + sourcePath_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string source_path = 2; + * + *
    +       * the pathname to the file or directory to change 
    +       * 
    + */ + public com.google.protobuf.ByteString + getSourcePathBytes() { + java.lang.Object ref = sourcePath_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + sourcePath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string source_path = 2; + * + *
    +       * the pathname to the file or directory to change 
    +       * 
    + */ + public Builder setSourcePath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + sourcePath_ = value; + onChanged(); + return this; + } + /** + * required string source_path = 2; + * + *
    +       * the pathname to the file or directory to change 
    +       * 
    + */ + public Builder clearSourcePath() { + bitField0_ = (bitField0_ & ~0x00000002); + sourcePath_ = getDefaultInstance().getSourcePath(); + onChanged(); + return this; + } + /** + * required string source_path = 2; + * + *
    +       * the pathname to the file or directory to change 
    +       * 
    + */ + public Builder setSourcePathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + sourcePath_ = value; + onChanged(); + return this; + } + + // required string target_path = 3; + private java.lang.Object targetPath_ = ""; + /** + * required string target_path = 3; + * + *
    +       * the new path name for the file or directory
    +       * 
    + */ + public boolean hasTargetPath() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string target_path = 3; + * + *
    +       * the new path name for the file or directory
    +       * 
    + */ + public java.lang.String getTargetPath() { + java.lang.Object ref = targetPath_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + targetPath_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string target_path = 3; + * + *
    +       * the new path name for the file or directory
    +       * 
    + */ + public com.google.protobuf.ByteString + getTargetPathBytes() { + java.lang.Object ref = targetPath_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + targetPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string target_path = 3; + * + *
    +       * the new path name for the file or directory
    +       * 
    + */ + public Builder setTargetPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + targetPath_ = value; + onChanged(); + return this; + } + /** + * required string target_path = 3; + * + *
    +       * the new path name for the file or directory
    +       * 
    + */ + public Builder clearTargetPath() { + bitField0_ = (bitField0_ & ~0x00000004); + targetPath_ = getDefaultInstance().getTargetPath(); + onChanged(); + return this; + } + /** + * required string target_path = 3; + * + *
    +       * the new path name for the file or directory
    +       * 
    + */ + public Builder setTargetPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + targetPath_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.renameRequest) + } + + static { + defaultInstance = new renameRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.renameRequest) + } + + public interface renameResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed32 timestamp_s = 1; + /** + * required fixed32 timestamp_s = 1; + * + *
    +     * the server timestamp in seconds since 1970 to which the file and
    +     * directory timestamps were updated
    +     * 
    + */ + boolean hasTimestampS(); + /** + * required fixed32 timestamp_s = 1; + * + *
    +     * the server timestamp in seconds since 1970 to which the file and
    +     * directory timestamps were updated
    +     * 
    + */ + int getTimestampS(); + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + boolean hasCreds(); + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getCreds(); + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getCredsOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.renameResponse} + * + *
    +   * returns the result of a rename operation
    +   * 
    + */ + public static final class renameResponse extends + com.google.protobuf.GeneratedMessage + implements renameResponseOrBuilder { + // Use renameResponse.newBuilder() to construct. + private renameResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private renameResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final renameResponse defaultInstance; + public static renameResponse getDefaultInstance() { + return defaultInstance; + } + + public renameResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private renameResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 13: { + bitField0_ |= 0x00000001; + timestampS_ = input.readFixed32(); + break; + } + case 18: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = creds_.toBuilder(); + } + creds_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(creds_); + creds_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_renameResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_renameResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public renameResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new renameResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed32 timestamp_s = 1; + public static final int TIMESTAMP_S_FIELD_NUMBER = 1; + private int timestampS_; + /** + * required fixed32 timestamp_s = 1; + * + *
    +     * the server timestamp in seconds since 1970 to which the file and
    +     * directory timestamps were updated
    +     * 
    + */ + public boolean hasTimestampS() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 timestamp_s = 1; + * + *
    +     * the server timestamp in seconds since 1970 to which the file and
    +     * directory timestamps were updated
    +     * 
    + */ + public int getTimestampS() { + return timestampS_; + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + public static final int CREDS_FIELD_NUMBER = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials creds_; + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + public boolean hasCreds() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getCreds() { + return creds_; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getCredsOrBuilder() { + return creds_; + } + + private void initFields() { + timestampS_ = 0; + creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasTimestampS()) { + memoizedIsInitialized = 0; + return false; + } + if (hasCreds()) { + if (!getCreds().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed32(1, timestampS_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, creds_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(1, timestampS_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, creds_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.renameResponse} + * + *
    +     * returns the result of a rename operation
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_renameResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_renameResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getCredsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + timestampS_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + if (credsBuilder_ == null) { + creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + credsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_renameResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.timestampS_ = timestampS_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + if (credsBuilder_ == null) { + result.creds_ = creds_; + } else { + result.creds_ = credsBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse.getDefaultInstance()) return this; + if (other.hasTimestampS()) { + setTimestampS(other.getTimestampS()); + } + if (other.hasCreds()) { + mergeCreds(other.getCreds()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasTimestampS()) { + + return false; + } + if (hasCreds()) { + if (!getCreds().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.renameResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed32 timestamp_s = 1; + private int timestampS_ ; + /** + * required fixed32 timestamp_s = 1; + * + *
    +       * the server timestamp in seconds since 1970 to which the file and
    +       * directory timestamps were updated
    +       * 
    + */ + public boolean hasTimestampS() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 timestamp_s = 1; + * + *
    +       * the server timestamp in seconds since 1970 to which the file and
    +       * directory timestamps were updated
    +       * 
    + */ + public int getTimestampS() { + return timestampS_; + } + /** + * required fixed32 timestamp_s = 1; + * + *
    +       * the server timestamp in seconds since 1970 to which the file and
    +       * directory timestamps were updated
    +       * 
    + */ + public Builder setTimestampS(int value) { + bitField0_ |= 0x00000001; + timestampS_ = value; + onChanged(); + return this; + } + /** + * required fixed32 timestamp_s = 1; + * + *
    +       * the server timestamp in seconds since 1970 to which the file and
    +       * directory timestamps were updated
    +       * 
    + */ + public Builder clearTimestampS() { + bitField0_ = (bitField0_ & ~0x00000001); + timestampS_ = 0; + onChanged(); + return this; + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> credsBuilder_; + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public boolean hasCreds() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getCreds() { + if (credsBuilder_ == null) { + return creds_; + } else { + return credsBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public Builder setCreds(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (credsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + creds_ = value; + onChanged(); + } else { + credsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public Builder setCreds( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (credsBuilder_ == null) { + creds_ = builderForValue.build(); + onChanged(); + } else { + credsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public Builder mergeCreds(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (credsBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + creds_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + creds_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(creds_).mergeFrom(value).buildPartial(); + } else { + creds_ = value; + } + onChanged(); + } else { + credsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public Builder clearCreds() { + if (credsBuilder_ == null) { + creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + credsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getCredsBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getCredsFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getCredsOrBuilder() { + if (credsBuilder_ != null) { + return credsBuilder_.getMessageOrBuilder(); + } else { + return creds_; + } + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getCredsFieldBuilder() { + if (credsBuilder_ == null) { + credsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + creds_, + getParentForChildren(), + isClean()); + creds_ = null; + } + return credsBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.renameResponse) + } + + static { + defaultInstance = new renameResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.renameResponse) + } + + public interface rmdirRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the directory to delete
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the directory to delete
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the directory to delete
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.rmdirRequest} + * + *
    +   * deletes an empty directory 
    +   * 
    + */ + public static final class rmdirRequest extends + com.google.protobuf.GeneratedMessage + implements rmdirRequestOrBuilder { + // Use rmdirRequest.newBuilder() to construct. + private rmdirRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private rmdirRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final rmdirRequest defaultInstance; + public static rmdirRequest getDefaultInstance() { + return defaultInstance; + } + + public rmdirRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private rmdirRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_rmdirRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_rmdirRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public rmdirRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new rmdirRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the directory to delete
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the directory to delete
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the directory to delete
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.rmdirRequest} + * + *
    +     * deletes an empty directory 
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_rmdirRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_rmdirRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_rmdirRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.rmdirRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the directory to delete
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the directory to delete
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the directory to delete
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the directory to delete
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the directory to delete
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the directory to delete
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.rmdirRequest) + } + + static { + defaultInstance = new rmdirRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.rmdirRequest) + } + + public interface setattrRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // required .xtreemfs.pbrpc.Stat stbuf = 3; + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + boolean hasStbuf(); + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf(); + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder(); + + // required fixed32 to_set = 4; + /** + * required fixed32 to_set = 4; + * + *
    +     * a bitmap of Setattrs indicating which attributes to update
    +     * 
    + */ + boolean hasToSet(); + /** + * required fixed32 to_set = 4; + * + *
    +     * a bitmap of Setattrs indicating which attributes to update
    +     * 
    + */ + int getToSet(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.setattrRequest} + * + *
    +   * changes attributes of a file or directory
    +   * 
    + */ + public static final class setattrRequest extends + com.google.protobuf.GeneratedMessage + implements setattrRequestOrBuilder { + // Use setattrRequest.newBuilder() to construct. + private setattrRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private setattrRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final setattrRequest defaultInstance; + public static setattrRequest getDefaultInstance() { + return defaultInstance; + } + + public setattrRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private setattrRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 26: { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder subBuilder = null; + if (((bitField0_ & 0x00000004) == 0x00000004)) { + subBuilder = stbuf_.toBuilder(); + } + stbuf_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(stbuf_); + stbuf_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000004; + break; + } + case 37: { + bitField0_ |= 0x00000008; + toSet_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_setattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_setattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public setattrRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new setattrRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required .xtreemfs.pbrpc.Stat stbuf = 3; + public static final int STBUF_FIELD_NUMBER = 3; + private org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat stbuf_; + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + public boolean hasStbuf() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf() { + return stbuf_; + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +     * a buffer containing the attributes to update
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder() { + return stbuf_; + } + + // required fixed32 to_set = 4; + public static final int TO_SET_FIELD_NUMBER = 4; + private int toSet_; + /** + * required fixed32 to_set = 4; + * + *
    +     * a bitmap of Setattrs indicating which attributes to update
    +     * 
    + */ + public boolean hasToSet() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 to_set = 4; + * + *
    +     * a bitmap of Setattrs indicating which attributes to update
    +     * 
    + */ + public int getToSet() { + return toSet_; + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + toSet_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasStbuf()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasToSet()) { + memoizedIsInitialized = 0; + return false; + } + if (!getStbuf().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeMessage(3, stbuf_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed32(4, toSet_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, stbuf_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(4, toSet_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.setattrRequest} + * + *
    +     * changes attributes of a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_setattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_setattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getStbufFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + if (stbufBuilder_ == null) { + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + } else { + stbufBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + toSet_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_setattrRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + if (stbufBuilder_ == null) { + result.stbuf_ = stbuf_; + } else { + result.stbuf_ = stbufBuilder_.build(); + } + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.toSet_ = toSet_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasStbuf()) { + mergeStbuf(other.getStbuf()); + } + if (other.hasToSet()) { + setToSet(other.getToSet()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + if (!hasStbuf()) { + + return false; + } + if (!hasToSet()) { + + return false; + } + if (!getStbuf().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.setattrRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.Stat stbuf = 3; + private org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder> stbufBuilder_; + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public boolean hasStbuf() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat getStbuf() { + if (stbufBuilder_ == null) { + return stbuf_; + } else { + return stbufBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public Builder setStbuf(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat value) { + if (stbufBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + stbuf_ = value; + onChanged(); + } else { + stbufBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public Builder setStbuf( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder builderForValue) { + if (stbufBuilder_ == null) { + stbuf_ = builderForValue.build(); + onChanged(); + } else { + stbufBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public Builder mergeStbuf(org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat value) { + if (stbufBuilder_ == null) { + if (((bitField0_ & 0x00000004) == 0x00000004) && + stbuf_ != org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance()) { + stbuf_ = + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.newBuilder(stbuf_).mergeFrom(value).buildPartial(); + } else { + stbuf_ = value; + } + onChanged(); + } else { + stbufBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public Builder clearStbuf() { + if (stbufBuilder_ == null) { + stbuf_ = org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.getDefaultInstance(); + onChanged(); + } else { + stbufBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder getStbufBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getStbufFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder getStbufOrBuilder() { + if (stbufBuilder_ != null) { + return stbufBuilder_.getMessageOrBuilder(); + } else { + return stbuf_; + } + } + /** + * required .xtreemfs.pbrpc.Stat stbuf = 3; + * + *
    +       * a buffer containing the attributes to update
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder> + getStbufFieldBuilder() { + if (stbufBuilder_ == null) { + stbufBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat, org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat.Builder, org.xtreemfs.pbrpc.generatedinterfaces.MRC.StatOrBuilder>( + stbuf_, + getParentForChildren(), + isClean()); + stbuf_ = null; + } + return stbufBuilder_; + } + + // required fixed32 to_set = 4; + private int toSet_ ; + /** + * required fixed32 to_set = 4; + * + *
    +       * a bitmap of Setattrs indicating which attributes to update
    +       * 
    + */ + public boolean hasToSet() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 to_set = 4; + * + *
    +       * a bitmap of Setattrs indicating which attributes to update
    +       * 
    + */ + public int getToSet() { + return toSet_; + } + /** + * required fixed32 to_set = 4; + * + *
    +       * a bitmap of Setattrs indicating which attributes to update
    +       * 
    + */ + public Builder setToSet(int value) { + bitField0_ |= 0x00000008; + toSet_ = value; + onChanged(); + return this; + } + /** + * required fixed32 to_set = 4; + * + *
    +       * a bitmap of Setattrs indicating which attributes to update
    +       * 
    + */ + public Builder clearToSet() { + bitField0_ = (bitField0_ & ~0x00000008); + toSet_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.setattrRequest) + } + + static { + defaultInstance = new setattrRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.setattrRequest) + } + + public interface setxattrRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // required string name = 3; + /** + * required string name = 3; + * + *
    +     * the name of the extended attribute to set
    +     * 
    + */ + boolean hasName(); + /** + * required string name = 3; + * + *
    +     * the name of the extended attribute to set
    +     * 
    + */ + java.lang.String getName(); + /** + * required string name = 3; + * + *
    +     * the name of the extended attribute to set
    +     * 
    + */ + com.google.protobuf.ByteString + getNameBytes(); + + // required string value = 4; + /** + * required string value = 4; + * + *
    +     * the (new) value for the extended attribute to set
    +     * 
    + */ + boolean hasValue(); + /** + * required string value = 4; + * + *
    +     * the (new) value for the extended attribute to set
    +     * 
    + */ + java.lang.String getValue(); + /** + * required string value = 4; + * + *
    +     * the (new) value for the extended attribute to set
    +     * 
    + */ + com.google.protobuf.ByteString + getValueBytes(); + + // optional bytes value_bytes_string = 6; + /** + * optional bytes value_bytes_string = 6; + * + *
    +     * (new) value in bytes, see XAttr for explanation.
    +     * 
    + */ + boolean hasValueBytesString(); + /** + * optional bytes value_bytes_string = 6; + * + *
    +     * (new) value in bytes, see XAttr for explanation.
    +     * 
    + */ + com.google.protobuf.ByteString getValueBytesString(); + + // required fixed32 flags = 5; + /** + * required fixed32 flags = 5; + * + *
    +     * flags indicating whether the attribute is supposed to be created or
    +     * replaced (see XATTR_FLAGS)
    +     * 
    + */ + boolean hasFlags(); + /** + * required fixed32 flags = 5; + * + *
    +     * flags indicating whether the attribute is supposed to be created or
    +     * replaced (see XATTR_FLAGS)
    +     * 
    + */ + int getFlags(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.setxattrRequest} + * + *
    +   * sets an extended attribute of a file or directory
    +   * 
    + */ + public static final class setxattrRequest extends + com.google.protobuf.GeneratedMessage + implements setxattrRequestOrBuilder { + // Use setxattrRequest.newBuilder() to construct. + private setxattrRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private setxattrRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final setxattrRequest defaultInstance; + public static setxattrRequest getDefaultInstance() { + return defaultInstance; + } + + public setxattrRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private setxattrRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + name_ = input.readBytes(); + break; + } + case 34: { + bitField0_ |= 0x00000008; + value_ = input.readBytes(); + break; + } + case 45: { + bitField0_ |= 0x00000020; + flags_ = input.readFixed32(); + break; + } + case 50: { + bitField0_ |= 0x00000010; + valueBytesString_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_setxattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_setxattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public setxattrRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new setxattrRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string name = 3; + public static final int NAME_FIELD_NUMBER = 3; + private java.lang.Object name_; + /** + * required string name = 3; + * + *
    +     * the name of the extended attribute to set
    +     * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string name = 3; + * + *
    +     * the name of the extended attribute to set
    +     * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * required string name = 3; + * + *
    +     * the name of the extended attribute to set
    +     * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string value = 4; + public static final int VALUE_FIELD_NUMBER = 4; + private java.lang.Object value_; + /** + * required string value = 4; + * + *
    +     * the (new) value for the extended attribute to set
    +     * 
    + */ + public boolean hasValue() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required string value = 4; + * + *
    +     * the (new) value for the extended attribute to set
    +     * 
    + */ + public java.lang.String getValue() { + java.lang.Object ref = value_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + value_ = s; + } + return s; + } + } + /** + * required string value = 4; + * + *
    +     * the (new) value for the extended attribute to set
    +     * 
    + */ + public com.google.protobuf.ByteString + getValueBytes() { + java.lang.Object ref = value_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + value_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional bytes value_bytes_string = 6; + public static final int VALUE_BYTES_STRING_FIELD_NUMBER = 6; + private com.google.protobuf.ByteString valueBytesString_; + /** + * optional bytes value_bytes_string = 6; + * + *
    +     * (new) value in bytes, see XAttr for explanation.
    +     * 
    + */ + public boolean hasValueBytesString() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * optional bytes value_bytes_string = 6; + * + *
    +     * (new) value in bytes, see XAttr for explanation.
    +     * 
    + */ + public com.google.protobuf.ByteString getValueBytesString() { + return valueBytesString_; + } + + // required fixed32 flags = 5; + public static final int FLAGS_FIELD_NUMBER = 5; + private int flags_; + /** + * required fixed32 flags = 5; + * + *
    +     * flags indicating whether the attribute is supposed to be created or
    +     * replaced (see XATTR_FLAGS)
    +     * 
    + */ + public boolean hasFlags() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed32 flags = 5; + * + *
    +     * flags indicating whether the attribute is supposed to be created or
    +     * replaced (see XATTR_FLAGS)
    +     * 
    + */ + public int getFlags() { + return flags_; + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + name_ = ""; + value_ = ""; + valueBytesString_ = com.google.protobuf.ByteString.EMPTY; + flags_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasValue()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFlags()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getNameBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBytes(4, getValueBytes()); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeFixed32(5, flags_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeBytes(6, valueBytesString_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getNameBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, getValueBytes()); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(5, flags_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(6, valueBytesString_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.setxattrRequest} + * + *
    +     * sets an extended attribute of a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_setxattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_setxattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + name_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + value_ = ""; + bitField0_ = (bitField0_ & ~0x00000008); + valueBytesString_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000010); + flags_ = 0; + bitField0_ = (bitField0_ & ~0x00000020); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_setxattrRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.value_ = value_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.valueBytesString_ = valueBytesString_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.flags_ = flags_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasName()) { + bitField0_ |= 0x00000004; + name_ = other.name_; + onChanged(); + } + if (other.hasValue()) { + bitField0_ |= 0x00000008; + value_ = other.value_; + onChanged(); + } + if (other.hasValueBytesString()) { + setValueBytesString(other.getValueBytesString()); + } + if (other.hasFlags()) { + setFlags(other.getFlags()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + if (!hasName()) { + + return false; + } + if (!hasValue()) { + + return false; + } + if (!hasFlags()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.setxattrRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // required string name = 3; + private java.lang.Object name_ = ""; + /** + * required string name = 3; + * + *
    +       * the name of the extended attribute to set
    +       * 
    + */ + public boolean hasName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string name = 3; + * + *
    +       * the name of the extended attribute to set
    +       * 
    + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string name = 3; + * + *
    +       * the name of the extended attribute to set
    +       * 
    + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string name = 3; + * + *
    +       * the name of the extended attribute to set
    +       * 
    + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + name_ = value; + onChanged(); + return this; + } + /** + * required string name = 3; + * + *
    +       * the name of the extended attribute to set
    +       * 
    + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000004); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * required string name = 3; + * + *
    +       * the name of the extended attribute to set
    +       * 
    + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + name_ = value; + onChanged(); + return this; + } + + // required string value = 4; + private java.lang.Object value_ = ""; + /** + * required string value = 4; + * + *
    +       * the (new) value for the extended attribute to set
    +       * 
    + */ + public boolean hasValue() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required string value = 4; + * + *
    +       * the (new) value for the extended attribute to set
    +       * 
    + */ + public java.lang.String getValue() { + java.lang.Object ref = value_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + value_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string value = 4; + * + *
    +       * the (new) value for the extended attribute to set
    +       * 
    + */ + public com.google.protobuf.ByteString + getValueBytes() { + java.lang.Object ref = value_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + value_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string value = 4; + * + *
    +       * the (new) value for the extended attribute to set
    +       * 
    + */ + public Builder setValue( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + value_ = value; + onChanged(); + return this; + } + /** + * required string value = 4; + * + *
    +       * the (new) value for the extended attribute to set
    +       * 
    + */ + public Builder clearValue() { + bitField0_ = (bitField0_ & ~0x00000008); + value_ = getDefaultInstance().getValue(); + onChanged(); + return this; + } + /** + * required string value = 4; + * + *
    +       * the (new) value for the extended attribute to set
    +       * 
    + */ + public Builder setValueBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + value_ = value; + onChanged(); + return this; + } + + // optional bytes value_bytes_string = 6; + private com.google.protobuf.ByteString valueBytesString_ = com.google.protobuf.ByteString.EMPTY; + /** + * optional bytes value_bytes_string = 6; + * + *
    +       * (new) value in bytes, see XAttr for explanation.
    +       * 
    + */ + public boolean hasValueBytesString() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * optional bytes value_bytes_string = 6; + * + *
    +       * (new) value in bytes, see XAttr for explanation.
    +       * 
    + */ + public com.google.protobuf.ByteString getValueBytesString() { + return valueBytesString_; + } + /** + * optional bytes value_bytes_string = 6; + * + *
    +       * (new) value in bytes, see XAttr for explanation.
    +       * 
    + */ + public Builder setValueBytesString(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + valueBytesString_ = value; + onChanged(); + return this; + } + /** + * optional bytes value_bytes_string = 6; + * + *
    +       * (new) value in bytes, see XAttr for explanation.
    +       * 
    + */ + public Builder clearValueBytesString() { + bitField0_ = (bitField0_ & ~0x00000010); + valueBytesString_ = getDefaultInstance().getValueBytesString(); + onChanged(); + return this; + } + + // required fixed32 flags = 5; + private int flags_ ; + /** + * required fixed32 flags = 5; + * + *
    +       * flags indicating whether the attribute is supposed to be created or
    +       * replaced (see XATTR_FLAGS)
    +       * 
    + */ + public boolean hasFlags() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed32 flags = 5; + * + *
    +       * flags indicating whether the attribute is supposed to be created or
    +       * replaced (see XATTR_FLAGS)
    +       * 
    + */ + public int getFlags() { + return flags_; + } + /** + * required fixed32 flags = 5; + * + *
    +       * flags indicating whether the attribute is supposed to be created or
    +       * replaced (see XATTR_FLAGS)
    +       * 
    + */ + public Builder setFlags(int value) { + bitField0_ |= 0x00000020; + flags_ = value; + onChanged(); + return this; + } + /** + * required fixed32 flags = 5; + * + *
    +       * flags indicating whether the attribute is supposed to be created or
    +       * replaced (see XATTR_FLAGS)
    +       * 
    + */ + public Builder clearFlags() { + bitField0_ = (bitField0_ & ~0x00000020); + flags_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.setxattrRequest) + } + + static { + defaultInstance = new setxattrRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.setxattrRequest) + } + + public interface statvfsRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required fixed64 known_etag = 5; + /** + * required fixed64 known_etag = 5; + * + *
    +     * an identification tag indicating the last known version of the directory
    +     * content
    +     * 
    + */ + boolean hasKnownEtag(); + /** + * required fixed64 known_etag = 5; + * + *
    +     * an identification tag indicating the last known version of the directory
    +     * content
    +     * 
    + */ + long getKnownEtag(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.statvfsRequest} + * + *
    +   * requests information about a mounted volume
    +   * 
    + */ + public static final class statvfsRequest extends + com.google.protobuf.GeneratedMessage + implements statvfsRequestOrBuilder { + // Use statvfsRequest.newBuilder() to construct. + private statvfsRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private statvfsRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final statvfsRequest defaultInstance; + public static statvfsRequest getDefaultInstance() { + return defaultInstance; + } + + public statvfsRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private statvfsRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 41: { + bitField0_ |= 0x00000002; + knownEtag_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_statvfsRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_statvfsRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public statvfsRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new statvfsRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 known_etag = 5; + public static final int KNOWN_ETAG_FIELD_NUMBER = 5; + private long knownEtag_; + /** + * required fixed64 known_etag = 5; + * + *
    +     * an identification tag indicating the last known version of the directory
    +     * content
    +     * 
    + */ + public boolean hasKnownEtag() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 known_etag = 5; + * + *
    +     * an identification tag indicating the last known version of the directory
    +     * content
    +     * 
    + */ + public long getKnownEtag() { + return knownEtag_; + } + + private void initFields() { + volumeName_ = ""; + knownEtag_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasKnownEtag()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(5, knownEtag_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(5, knownEtag_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.statvfsRequest} + * + *
    +     * requests information about a mounted volume
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_statvfsRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_statvfsRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + knownEtag_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_statvfsRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.knownEtag_ = knownEtag_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasKnownEtag()) { + setKnownEtag(other.getKnownEtag()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasKnownEtag()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.statvfsRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required fixed64 known_etag = 5; + private long knownEtag_ ; + /** + * required fixed64 known_etag = 5; + * + *
    +       * an identification tag indicating the last known version of the directory
    +       * content
    +       * 
    + */ + public boolean hasKnownEtag() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 known_etag = 5; + * + *
    +       * an identification tag indicating the last known version of the directory
    +       * content
    +       * 
    + */ + public long getKnownEtag() { + return knownEtag_; + } + /** + * required fixed64 known_etag = 5; + * + *
    +       * an identification tag indicating the last known version of the directory
    +       * content
    +       * 
    + */ + public Builder setKnownEtag(long value) { + bitField0_ |= 0x00000002; + knownEtag_ = value; + onChanged(); + return this; + } + /** + * required fixed64 known_etag = 5; + * + *
    +       * an identification tag indicating the last known version of the directory
    +       * content
    +       * 
    + */ + public Builder clearKnownEtag() { + bitField0_ = (bitField0_ & ~0x00000002); + knownEtag_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.statvfsRequest) + } + + static { + defaultInstance = new statvfsRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.statvfsRequest) + } + + public interface symlinkRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string target_path = 2; + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + boolean hasTargetPath(); + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + java.lang.String getTargetPath(); + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getTargetPathBytes(); + + // required string link_path = 3; + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + boolean hasLinkPath(); + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + java.lang.String getLinkPath(); + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getLinkPathBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.symlinkRequest} + * + *
    +   * creates a symbolic link to a file
    +   * 
    + */ + public static final class symlinkRequest extends + com.google.protobuf.GeneratedMessage + implements symlinkRequestOrBuilder { + // Use symlinkRequest.newBuilder() to construct. + private symlinkRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private symlinkRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final symlinkRequest defaultInstance; + public static symlinkRequest getDefaultInstance() { + return defaultInstance; + } + + public symlinkRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private symlinkRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + targetPath_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + linkPath_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_symlinkRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_symlinkRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public symlinkRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new symlinkRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string target_path = 2; + public static final int TARGET_PATH_FIELD_NUMBER = 2; + private java.lang.Object targetPath_; + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + public boolean hasTargetPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + public java.lang.String getTargetPath() { + java.lang.Object ref = targetPath_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + targetPath_ = s; + } + return s; + } + } + /** + * required string target_path = 2; + * + *
    +     * the path to the file to which the link is supposed to be created,
    +     * relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getTargetPathBytes() { + java.lang.Object ref = targetPath_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + targetPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string link_path = 3; + public static final int LINK_PATH_FIELD_NUMBER = 3; + private java.lang.Object linkPath_; + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + public boolean hasLinkPath() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + public java.lang.String getLinkPath() { + java.lang.Object ref = linkPath_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + linkPath_ = s; + } + return s; + } + } + /** + * required string link_path = 3; + * + *
    +     * the path to the new link, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getLinkPathBytes() { + java.lang.Object ref = linkPath_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + linkPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + volumeName_ = ""; + targetPath_ = ""; + linkPath_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTargetPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLinkPath()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getTargetPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getLinkPathBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getTargetPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getLinkPathBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.symlinkRequest} + * + *
    +     * creates a symbolic link to a file
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_symlinkRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_symlinkRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + targetPath_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + linkPath_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_symlinkRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.targetPath_ = targetPath_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.linkPath_ = linkPath_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasTargetPath()) { + bitField0_ |= 0x00000002; + targetPath_ = other.targetPath_; + onChanged(); + } + if (other.hasLinkPath()) { + bitField0_ |= 0x00000004; + linkPath_ = other.linkPath_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasTargetPath()) { + + return false; + } + if (!hasLinkPath()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.symlinkRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string target_path = 2; + private java.lang.Object targetPath_ = ""; + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public boolean hasTargetPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public java.lang.String getTargetPath() { + java.lang.Object ref = targetPath_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + targetPath_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getTargetPathBytes() { + java.lang.Object ref = targetPath_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + targetPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public Builder setTargetPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + targetPath_ = value; + onChanged(); + return this; + } + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public Builder clearTargetPath() { + bitField0_ = (bitField0_ & ~0x00000002); + targetPath_ = getDefaultInstance().getTargetPath(); + onChanged(); + return this; + } + /** + * required string target_path = 2; + * + *
    +       * the path to the file to which the link is supposed to be created,
    +       * relative to the volume root
    +       * 
    + */ + public Builder setTargetPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + targetPath_ = value; + onChanged(); + return this; + } + + // required string link_path = 3; + private java.lang.Object linkPath_ = ""; + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public boolean hasLinkPath() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public java.lang.String getLinkPath() { + java.lang.Object ref = linkPath_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + linkPath_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getLinkPathBytes() { + java.lang.Object ref = linkPath_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + linkPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public Builder setLinkPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + linkPath_ = value; + onChanged(); + return this; + } + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public Builder clearLinkPath() { + bitField0_ = (bitField0_ & ~0x00000004); + linkPath_ = getDefaultInstance().getLinkPath(); + onChanged(); + return this; + } + /** + * required string link_path = 3; + * + *
    +       * the path to the new link, relative to the volume root
    +       * 
    + */ + public Builder setLinkPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + linkPath_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.symlinkRequest) + } + + static { + defaultInstance = new symlinkRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.symlinkRequest) + } + + public interface unlinkRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.unlinkRequest} + * + *
    +   * deletes a file or directory
    +   * 
    + */ + public static final class unlinkRequest extends + com.google.protobuf.GeneratedMessage + implements unlinkRequestOrBuilder { + // Use unlinkRequest.newBuilder() to construct. + private unlinkRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private unlinkRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final unlinkRequest defaultInstance; + public static unlinkRequest getDefaultInstance() { + return defaultInstance; + } + + public unlinkRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private unlinkRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_unlinkRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_unlinkRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public unlinkRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new unlinkRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.unlinkRequest} + * + *
    +     * deletes a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_unlinkRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_unlinkRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_unlinkRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.unlinkRequest) + } + + static { + defaultInstance = new unlinkRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.unlinkRequest) + } + + public interface unlinkResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed32 timestamp_s = 1; + /** + * required fixed32 timestamp_s = 1; + * + *
    +     * the server timestamp in seconds since 1970 to which the file and
    +     * directory timestamps were updated
    +     * 
    + */ + boolean hasTimestampS(); + /** + * required fixed32 timestamp_s = 1; + * + *
    +     * the server timestamp in seconds since 1970 to which the file and
    +     * directory timestamps were updated
    +     * 
    + */ + int getTimestampS(); + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + boolean hasCreds(); + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getCreds(); + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getCredsOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.unlinkResponse} + * + *
    +   * returns the result of an unlink operation
    +   * 
    + */ + public static final class unlinkResponse extends + com.google.protobuf.GeneratedMessage + implements unlinkResponseOrBuilder { + // Use unlinkResponse.newBuilder() to construct. + private unlinkResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private unlinkResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final unlinkResponse defaultInstance; + public static unlinkResponse getDefaultInstance() { + return defaultInstance; + } + + public unlinkResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private unlinkResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 13: { + bitField0_ |= 0x00000001; + timestampS_ = input.readFixed32(); + break; + } + case 18: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = creds_.toBuilder(); + } + creds_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(creds_); + creds_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_unlinkResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_unlinkResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public unlinkResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new unlinkResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed32 timestamp_s = 1; + public static final int TIMESTAMP_S_FIELD_NUMBER = 1; + private int timestampS_; + /** + * required fixed32 timestamp_s = 1; + * + *
    +     * the server timestamp in seconds since 1970 to which the file and
    +     * directory timestamps were updated
    +     * 
    + */ + public boolean hasTimestampS() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 timestamp_s = 1; + * + *
    +     * the server timestamp in seconds since 1970 to which the file and
    +     * directory timestamps were updated
    +     * 
    + */ + public int getTimestampS() { + return timestampS_; + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + public static final int CREDS_FIELD_NUMBER = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials creds_; + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + public boolean hasCreds() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getCreds() { + return creds_; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +     * an optional set of file credentials that may contain a capabiltiy
    +     * for the deletion of the previous file at the given target path
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getCredsOrBuilder() { + return creds_; + } + + private void initFields() { + timestampS_ = 0; + creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasTimestampS()) { + memoizedIsInitialized = 0; + return false; + } + if (hasCreds()) { + if (!getCreds().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed32(1, timestampS_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, creds_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(1, timestampS_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, creds_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.unlinkResponse} + * + *
    +     * returns the result of an unlink operation
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_unlinkResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_unlinkResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getCredsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + timestampS_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + if (credsBuilder_ == null) { + creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + credsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_unlinkResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.timestampS_ = timestampS_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + if (credsBuilder_ == null) { + result.creds_ = creds_; + } else { + result.creds_ = credsBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse.getDefaultInstance()) return this; + if (other.hasTimestampS()) { + setTimestampS(other.getTimestampS()); + } + if (other.hasCreds()) { + mergeCreds(other.getCreds()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasTimestampS()) { + + return false; + } + if (hasCreds()) { + if (!getCreds().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.unlinkResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed32 timestamp_s = 1; + private int timestampS_ ; + /** + * required fixed32 timestamp_s = 1; + * + *
    +       * the server timestamp in seconds since 1970 to which the file and
    +       * directory timestamps were updated
    +       * 
    + */ + public boolean hasTimestampS() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 timestamp_s = 1; + * + *
    +       * the server timestamp in seconds since 1970 to which the file and
    +       * directory timestamps were updated
    +       * 
    + */ + public int getTimestampS() { + return timestampS_; + } + /** + * required fixed32 timestamp_s = 1; + * + *
    +       * the server timestamp in seconds since 1970 to which the file and
    +       * directory timestamps were updated
    +       * 
    + */ + public Builder setTimestampS(int value) { + bitField0_ |= 0x00000001; + timestampS_ = value; + onChanged(); + return this; + } + /** + * required fixed32 timestamp_s = 1; + * + *
    +       * the server timestamp in seconds since 1970 to which the file and
    +       * directory timestamps were updated
    +       * 
    + */ + public Builder clearTimestampS() { + bitField0_ = (bitField0_ & ~0x00000001); + timestampS_ = 0; + onChanged(); + return this; + } + + // optional .xtreemfs.pbrpc.FileCredentials creds = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> credsBuilder_; + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public boolean hasCreds() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getCreds() { + if (credsBuilder_ == null) { + return creds_; + } else { + return credsBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public Builder setCreds(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (credsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + creds_ = value; + onChanged(); + } else { + credsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public Builder setCreds( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (credsBuilder_ == null) { + creds_ = builderForValue.build(); + onChanged(); + } else { + credsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public Builder mergeCreds(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (credsBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + creds_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + creds_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(creds_).mergeFrom(value).buildPartial(); + } else { + creds_ = value; + } + onChanged(); + } else { + credsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public Builder clearCreds() { + if (credsBuilder_ == null) { + creds_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + credsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getCredsBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getCredsFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getCredsOrBuilder() { + if (credsBuilder_ != null) { + return credsBuilder_.getMessageOrBuilder(); + } else { + return creds_; + } + } + /** + * optional .xtreemfs.pbrpc.FileCredentials creds = 2; + * + *
    +       * an optional set of file credentials that may contain a capabiltiy
    +       * for the deletion of the previous file at the given target path
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getCredsFieldBuilder() { + if (credsBuilder_ == null) { + credsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + creds_, + getParentForChildren(), + isClean()); + creds_ = null; + } + return credsBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.unlinkResponse) + } + + static { + defaultInstance = new unlinkResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.unlinkResponse) + } + + public interface accessRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string path = 2; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + boolean hasPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + java.lang.String getPath(); + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // required fixed32 flags = 3; + /** + * required fixed32 flags = 3; + * + *
    +     * the flags for which the access is supposed to be checked;
    +     * see ACCESS_FLAGS
    +     * 
    + */ + boolean hasFlags(); + /** + * required fixed32 flags = 3; + * + *
    +     * the flags for which the access is supposed to be checked;
    +     * see ACCESS_FLAGS
    +     * 
    + */ + int getFlags(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.accessRequest} + * + *
    +   * checks whether access is granted to a file or directory
    +   * 
    + */ + public static final class accessRequest extends + com.google.protobuf.GeneratedMessage + implements accessRequestOrBuilder { + // Use accessRequest.newBuilder() to construct. + private accessRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private accessRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final accessRequest defaultInstance; + public static accessRequest getDefaultInstance() { + return defaultInstance; + } + + public accessRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private accessRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 29: { + bitField0_ |= 0x00000004; + flags_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_accessRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_accessRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public accessRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new accessRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the volume name
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 2; + * + *
    +     * the path to the file or directory, relative to the volume root
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 flags = 3; + public static final int FLAGS_FIELD_NUMBER = 3; + private int flags_; + /** + * required fixed32 flags = 3; + * + *
    +     * the flags for which the access is supposed to be checked;
    +     * see ACCESS_FLAGS
    +     * 
    + */ + public boolean hasFlags() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 flags = 3; + * + *
    +     * the flags for which the access is supposed to be checked;
    +     * see ACCESS_FLAGS
    +     * 
    + */ + public int getFlags() { + return flags_; + } + + private void initFields() { + volumeName_ = ""; + path_ = ""; + flags_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFlags()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed32(3, flags_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(3, flags_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.accessRequest} + * + *
    +     * checks whether access is granted to a file or directory
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_accessRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_accessRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + flags_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_accessRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.flags_ = flags_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasFlags()) { + setFlags(other.getFlags()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + if (!hasPath()) { + + return false; + } + if (!hasFlags()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.accessRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the volume name
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // required string path = 2; + private java.lang.Object path_ = ""; + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 2; + * + *
    +       * the path to the file or directory, relative to the volume root
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // required fixed32 flags = 3; + private int flags_ ; + /** + * required fixed32 flags = 3; + * + *
    +       * the flags for which the access is supposed to be checked;
    +       * see ACCESS_FLAGS
    +       * 
    + */ + public boolean hasFlags() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 flags = 3; + * + *
    +       * the flags for which the access is supposed to be checked;
    +       * see ACCESS_FLAGS
    +       * 
    + */ + public int getFlags() { + return flags_; + } + /** + * required fixed32 flags = 3; + * + *
    +       * the flags for which the access is supposed to be checked;
    +       * see ACCESS_FLAGS
    +       * 
    + */ + public Builder setFlags(int value) { + bitField0_ |= 0x00000004; + flags_ = value; + onChanged(); + return this; + } + /** + * required fixed32 flags = 3; + * + *
    +       * the flags for which the access is supposed to be checked;
    +       * see ACCESS_FLAGS
    +       * 
    + */ + public Builder clearFlags() { + bitField0_ = (bitField0_ & ~0x00000004); + flags_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.accessRequest) + } + + static { + defaultInstance = new accessRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.accessRequest) + } + + public interface xtreemfs_check_file_existsRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_id = 1; + /** + * required string volume_id = 1; + */ + boolean hasVolumeId(); + /** + * required string volume_id = 1; + */ + java.lang.String getVolumeId(); + /** + * required string volume_id = 1; + */ + com.google.protobuf.ByteString + getVolumeIdBytes(); + + // repeated string file_ids = 2; + /** + * repeated string file_ids = 2; + */ + java.util.List + getFileIdsList(); + /** + * repeated string file_ids = 2; + */ + int getFileIdsCount(); + /** + * repeated string file_ids = 2; + */ + java.lang.String getFileIds(int index); + /** + * repeated string file_ids = 2; + */ + com.google.protobuf.ByteString + getFileIdsBytes(int index); + + // required string osd_uuid = 3; + /** + * required string osd_uuid = 3; + */ + boolean hasOsdUuid(); + /** + * required string osd_uuid = 3; + */ + java.lang.String getOsdUuid(); + /** + * required string osd_uuid = 3; + */ + com.google.protobuf.ByteString + getOsdUuidBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_check_file_existsRequest} + */ + public static final class xtreemfs_check_file_existsRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_check_file_existsRequestOrBuilder { + // Use xtreemfs_check_file_existsRequest.newBuilder() to construct. + private xtreemfs_check_file_existsRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_check_file_existsRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_check_file_existsRequest defaultInstance; + public static xtreemfs_check_file_existsRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_check_file_existsRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_check_file_existsRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeId_ = input.readBytes(); + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + fileIds_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000002; + } + fileIds_.add(input.readBytes()); + break; + } + case 26: { + bitField0_ |= 0x00000002; + osdUuid_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + fileIds_ = new com.google.protobuf.UnmodifiableLazyStringList(fileIds_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_check_file_existsRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_check_file_existsRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_id = 1; + public static final int VOLUME_ID_FIELD_NUMBER = 1; + private java.lang.Object volumeId_; + /** + * required string volume_id = 1; + */ + public boolean hasVolumeId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_id = 1; + */ + public java.lang.String getVolumeId() { + java.lang.Object ref = volumeId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeId_ = s; + } + return s; + } + } + /** + * required string volume_id = 1; + */ + public com.google.protobuf.ByteString + getVolumeIdBytes() { + java.lang.Object ref = volumeId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // repeated string file_ids = 2; + public static final int FILE_IDS_FIELD_NUMBER = 2; + private com.google.protobuf.LazyStringList fileIds_; + /** + * repeated string file_ids = 2; + */ + public java.util.List + getFileIdsList() { + return fileIds_; + } + /** + * repeated string file_ids = 2; + */ + public int getFileIdsCount() { + return fileIds_.size(); + } + /** + * repeated string file_ids = 2; + */ + public java.lang.String getFileIds(int index) { + return fileIds_.get(index); + } + /** + * repeated string file_ids = 2; + */ + public com.google.protobuf.ByteString + getFileIdsBytes(int index) { + return fileIds_.getByteString(index); + } + + // required string osd_uuid = 3; + public static final int OSD_UUID_FIELD_NUMBER = 3; + private java.lang.Object osdUuid_; + /** + * required string osd_uuid = 3; + */ + public boolean hasOsdUuid() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string osd_uuid = 3; + */ + public java.lang.String getOsdUuid() { + java.lang.Object ref = osdUuid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + osdUuid_ = s; + } + return s; + } + } + /** + * required string osd_uuid = 3; + */ + public com.google.protobuf.ByteString + getOsdUuidBytes() { + java.lang.Object ref = osdUuid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + osdUuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + volumeId_ = ""; + fileIds_ = com.google.protobuf.LazyStringArrayList.EMPTY; + osdUuid_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOsdUuid()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeIdBytes()); + } + for (int i = 0; i < fileIds_.size(); i++) { + output.writeBytes(2, fileIds_.getByteString(i)); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(3, getOsdUuidBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeIdBytes()); + } + { + int dataSize = 0; + for (int i = 0; i < fileIds_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(fileIds_.getByteString(i)); + } + size += dataSize; + size += 1 * getFileIdsList().size(); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getOsdUuidBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_check_file_existsRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeId_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + fileIds_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + osdUuid_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeId_ = volumeId_; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + fileIds_ = new com.google.protobuf.UnmodifiableLazyStringList( + fileIds_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.fileIds_ = fileIds_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000002; + } + result.osdUuid_ = osdUuid_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest.getDefaultInstance()) return this; + if (other.hasVolumeId()) { + bitField0_ |= 0x00000001; + volumeId_ = other.volumeId_; + onChanged(); + } + if (!other.fileIds_.isEmpty()) { + if (fileIds_.isEmpty()) { + fileIds_ = other.fileIds_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureFileIdsIsMutable(); + fileIds_.addAll(other.fileIds_); + } + onChanged(); + } + if (other.hasOsdUuid()) { + bitField0_ |= 0x00000004; + osdUuid_ = other.osdUuid_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeId()) { + + return false; + } + if (!hasOsdUuid()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_id = 1; + private java.lang.Object volumeId_ = ""; + /** + * required string volume_id = 1; + */ + public boolean hasVolumeId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_id = 1; + */ + public java.lang.String getVolumeId() { + java.lang.Object ref = volumeId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_id = 1; + */ + public com.google.protobuf.ByteString + getVolumeIdBytes() { + java.lang.Object ref = volumeId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_id = 1; + */ + public Builder setVolumeId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeId_ = value; + onChanged(); + return this; + } + /** + * required string volume_id = 1; + */ + public Builder clearVolumeId() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeId_ = getDefaultInstance().getVolumeId(); + onChanged(); + return this; + } + /** + * required string volume_id = 1; + */ + public Builder setVolumeIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeId_ = value; + onChanged(); + return this; + } + + // repeated string file_ids = 2; + private com.google.protobuf.LazyStringList fileIds_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureFileIdsIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + fileIds_ = new com.google.protobuf.LazyStringArrayList(fileIds_); + bitField0_ |= 0x00000002; + } + } + /** + * repeated string file_ids = 2; + */ + public java.util.List + getFileIdsList() { + return java.util.Collections.unmodifiableList(fileIds_); + } + /** + * repeated string file_ids = 2; + */ + public int getFileIdsCount() { + return fileIds_.size(); + } + /** + * repeated string file_ids = 2; + */ + public java.lang.String getFileIds(int index) { + return fileIds_.get(index); + } + /** + * repeated string file_ids = 2; + */ + public com.google.protobuf.ByteString + getFileIdsBytes(int index) { + return fileIds_.getByteString(index); + } + /** + * repeated string file_ids = 2; + */ + public Builder setFileIds( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileIdsIsMutable(); + fileIds_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string file_ids = 2; + */ + public Builder addFileIds( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileIdsIsMutable(); + fileIds_.add(value); + onChanged(); + return this; + } + /** + * repeated string file_ids = 2; + */ + public Builder addAllFileIds( + java.lang.Iterable values) { + ensureFileIdsIsMutable(); + super.addAll(values, fileIds_); + onChanged(); + return this; + } + /** + * repeated string file_ids = 2; + */ + public Builder clearFileIds() { + fileIds_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + return this; + } + /** + * repeated string file_ids = 2; + */ + public Builder addFileIdsBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileIdsIsMutable(); + fileIds_.add(value); + onChanged(); + return this; + } + + // required string osd_uuid = 3; + private java.lang.Object osdUuid_ = ""; + /** + * required string osd_uuid = 3; + */ + public boolean hasOsdUuid() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required string osd_uuid = 3; + */ + public java.lang.String getOsdUuid() { + java.lang.Object ref = osdUuid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + osdUuid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string osd_uuid = 3; + */ + public com.google.protobuf.ByteString + getOsdUuidBytes() { + java.lang.Object ref = osdUuid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + osdUuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string osd_uuid = 3; + */ + public Builder setOsdUuid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + osdUuid_ = value; + onChanged(); + return this; + } + /** + * required string osd_uuid = 3; + */ + public Builder clearOsdUuid() { + bitField0_ = (bitField0_ & ~0x00000004); + osdUuid_ = getDefaultInstance().getOsdUuid(); + onChanged(); + return this; + } + /** + * required string osd_uuid = 3; + */ + public Builder setOsdUuidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + osdUuid_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_check_file_existsRequest) + } + + static { + defaultInstance = new xtreemfs_check_file_existsRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_check_file_existsRequest) + } + + public interface xtreemfs_check_file_existsResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required bool volume_exists = 1; + /** + * required bool volume_exists = 1; + */ + boolean hasVolumeExists(); + /** + * required bool volume_exists = 1; + */ + boolean getVolumeExists(); + + // repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + java.util.List getFileStatesList(); + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + int getFileStatesCount(); + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE getFileStates(int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_check_file_existsResponse} + */ + public static final class xtreemfs_check_file_existsResponse extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_check_file_existsResponseOrBuilder { + // Use xtreemfs_check_file_existsResponse.newBuilder() to construct. + private xtreemfs_check_file_existsResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_check_file_existsResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_check_file_existsResponse defaultInstance; + public static xtreemfs_check_file_existsResponse getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_check_file_existsResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_check_file_existsResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + bitField0_ |= 0x00000001; + volumeExists_ = input.readBool(); + break; + } + case 16: { + int rawValue = input.readEnum(); + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE value = org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(2, rawValue); + } else { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + fileStates_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + fileStates_.add(value); + } + break; + } + case 18: { + int length = input.readRawVarint32(); + int oldLimit = input.pushLimit(length); + while(input.getBytesUntilLimit() > 0) { + int rawValue = input.readEnum(); + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE value = org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(2, rawValue); + } else { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + fileStates_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + fileStates_.add(value); + } + } + input.popLimit(oldLimit); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + fileStates_ = java.util.Collections.unmodifiableList(fileStates_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_check_file_existsResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_check_file_existsResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + /** + * Protobuf enum {@code xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE} + */ + public enum FILE_STATE + implements com.google.protobuf.ProtocolMessageEnum { + /** + * DELETED = 0; + */ + DELETED(0, 0), + /** + * REGISTERED = 1; + */ + REGISTERED(1, 1), + /** + * ABANDONED = 2; + */ + ABANDONED(2, 2), + ; + + /** + * DELETED = 0; + */ + public static final int DELETED_VALUE = 0; + /** + * REGISTERED = 1; + */ + public static final int REGISTERED_VALUE = 1; + /** + * ABANDONED = 2; + */ + public static final int ABANDONED_VALUE = 2; + + + public final int getNumber() { return value; } + + public static FILE_STATE valueOf(int value) { + switch (value) { + case 0: return DELETED; + case 1: return REGISTERED; + case 2: return ABANDONED; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public FILE_STATE findValueByNumber(int number) { + return FILE_STATE.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.getDescriptor().getEnumTypes().get(0); + } + + private static final FILE_STATE[] VALUES = values(); + + public static FILE_STATE valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private FILE_STATE(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE) + } + + private int bitField0_; + // required bool volume_exists = 1; + public static final int VOLUME_EXISTS_FIELD_NUMBER = 1; + private boolean volumeExists_; + /** + * required bool volume_exists = 1; + */ + public boolean hasVolumeExists() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required bool volume_exists = 1; + */ + public boolean getVolumeExists() { + return volumeExists_; + } + + // repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + public static final int FILE_STATES_FIELD_NUMBER = 2; + private java.util.List fileStates_; + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + public java.util.List getFileStatesList() { + return fileStates_; + } + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + public int getFileStatesCount() { + return fileStates_.size(); + } + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE getFileStates(int index) { + return fileStates_.get(index); + } + private int fileStatesMemoizedSerializedSize; + + private void initFields() { + volumeExists_ = false; + fileStates_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeExists()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBool(1, volumeExists_); + } + if (getFileStatesList().size() > 0) { + output.writeRawVarint32(18); + output.writeRawVarint32(fileStatesMemoizedSerializedSize); + } + for (int i = 0; i < fileStates_.size(); i++) { + output.writeEnumNoTag(fileStates_.get(i).getNumber()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(1, volumeExists_); + } + { + int dataSize = 0; + for (int i = 0; i < fileStates_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeEnumSizeNoTag(fileStates_.get(i).getNumber()); + } + size += dataSize; + if (!getFileStatesList().isEmpty()) { size += 1; + size += com.google.protobuf.CodedOutputStream + .computeRawVarint32Size(dataSize); + }fileStatesMemoizedSerializedSize = dataSize; + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_check_file_existsResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeExists_ = false; + bitField0_ = (bitField0_ & ~0x00000001); + fileStates_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeExists_ = volumeExists_; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + fileStates_ = java.util.Collections.unmodifiableList(fileStates_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.fileStates_ = fileStates_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.getDefaultInstance()) return this; + if (other.hasVolumeExists()) { + setVolumeExists(other.getVolumeExists()); + } + if (!other.fileStates_.isEmpty()) { + if (fileStates_.isEmpty()) { + fileStates_ = other.fileStates_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureFileStatesIsMutable(); + fileStates_.addAll(other.fileStates_); + } + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeExists()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required bool volume_exists = 1; + private boolean volumeExists_ ; + /** + * required bool volume_exists = 1; + */ + public boolean hasVolumeExists() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required bool volume_exists = 1; + */ + public boolean getVolumeExists() { + return volumeExists_; + } + /** + * required bool volume_exists = 1; + */ + public Builder setVolumeExists(boolean value) { + bitField0_ |= 0x00000001; + volumeExists_ = value; + onChanged(); + return this; + } + /** + * required bool volume_exists = 1; + */ + public Builder clearVolumeExists() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeExists_ = false; + onChanged(); + return this; + } + + // repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + private java.util.List fileStates_ = + java.util.Collections.emptyList(); + private void ensureFileStatesIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + fileStates_ = new java.util.ArrayList(fileStates_); + bitField0_ |= 0x00000002; + } + } + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + public java.util.List getFileStatesList() { + return java.util.Collections.unmodifiableList(fileStates_); + } + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + public int getFileStatesCount() { + return fileStates_.size(); + } + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE getFileStates(int index) { + return fileStates_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + public Builder setFileStates( + int index, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE value) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileStatesIsMutable(); + fileStates_.set(index, value); + onChanged(); + return this; + } + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + public Builder addFileStates(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_check_file_existsResponse.FILE_STATE value) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileStatesIsMutable(); + fileStates_.add(value); + onChanged(); + return this; + } + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + public Builder addAllFileStates( + java.lang.Iterable values) { + ensureFileStatesIsMutable(); + super.addAll(values, fileStates_); + onChanged(); + return this; + } + /** + * repeated .xtreemfs.pbrpc.xtreemfs_check_file_existsResponse.FILE_STATE file_states = 2 [packed = true]; + */ + public Builder clearFileStates() { + fileStates_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_check_file_existsResponse) + } + + static { + defaultInstance = new xtreemfs_check_file_existsResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_check_file_existsResponse) + } + + public interface xtreemfs_dump_restore_databaseRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string dump_file = 1; + /** + * required string dump_file = 1; + * + *
    +     * the path to the dump file on the MRC host
    +     * 
    + */ + boolean hasDumpFile(); + /** + * required string dump_file = 1; + * + *
    +     * the path to the dump file on the MRC host
    +     * 
    + */ + java.lang.String getDumpFile(); + /** + * required string dump_file = 1; + * + *
    +     * the path to the dump file on the MRC host
    +     * 
    + */ + com.google.protobuf.ByteString + getDumpFileBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_dump_restore_databaseRequest} + * + *
    +   * dumps or restores the MRC database
    +   * 
    + */ + public static final class xtreemfs_dump_restore_databaseRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_dump_restore_databaseRequestOrBuilder { + // Use xtreemfs_dump_restore_databaseRequest.newBuilder() to construct. + private xtreemfs_dump_restore_databaseRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_dump_restore_databaseRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_dump_restore_databaseRequest defaultInstance; + public static xtreemfs_dump_restore_databaseRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_dump_restore_databaseRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_dump_restore_databaseRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + dumpFile_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_dump_restore_databaseRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_dump_restore_databaseRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_dump_restore_databaseRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_dump_restore_databaseRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string dump_file = 1; + public static final int DUMP_FILE_FIELD_NUMBER = 1; + private java.lang.Object dumpFile_; + /** + * required string dump_file = 1; + * + *
    +     * the path to the dump file on the MRC host
    +     * 
    + */ + public boolean hasDumpFile() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string dump_file = 1; + * + *
    +     * the path to the dump file on the MRC host
    +     * 
    + */ + public java.lang.String getDumpFile() { + java.lang.Object ref = dumpFile_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + dumpFile_ = s; + } + return s; + } + } + /** + * required string dump_file = 1; + * + *
    +     * the path to the dump file on the MRC host
    +     * 
    + */ + public com.google.protobuf.ByteString + getDumpFileBytes() { + java.lang.Object ref = dumpFile_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + dumpFile_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + dumpFile_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasDumpFile()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getDumpFileBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getDumpFileBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_dump_restore_databaseRequest} + * + *
    +     * dumps or restores the MRC database
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_dump_restore_databaseRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_dump_restore_databaseRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + dumpFile_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_dump_restore_databaseRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.dumpFile_ = dumpFile_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest.getDefaultInstance()) return this; + if (other.hasDumpFile()) { + bitField0_ |= 0x00000001; + dumpFile_ = other.dumpFile_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasDumpFile()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_dump_restore_databaseRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string dump_file = 1; + private java.lang.Object dumpFile_ = ""; + /** + * required string dump_file = 1; + * + *
    +       * the path to the dump file on the MRC host
    +       * 
    + */ + public boolean hasDumpFile() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string dump_file = 1; + * + *
    +       * the path to the dump file on the MRC host
    +       * 
    + */ + public java.lang.String getDumpFile() { + java.lang.Object ref = dumpFile_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + dumpFile_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string dump_file = 1; + * + *
    +       * the path to the dump file on the MRC host
    +       * 
    + */ + public com.google.protobuf.ByteString + getDumpFileBytes() { + java.lang.Object ref = dumpFile_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + dumpFile_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string dump_file = 1; + * + *
    +       * the path to the dump file on the MRC host
    +       * 
    + */ + public Builder setDumpFile( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + dumpFile_ = value; + onChanged(); + return this; + } + /** + * required string dump_file = 1; + * + *
    +       * the path to the dump file on the MRC host
    +       * 
    + */ + public Builder clearDumpFile() { + bitField0_ = (bitField0_ & ~0x00000001); + dumpFile_ = getDefaultInstance().getDumpFile(); + onChanged(); + return this; + } + /** + * required string dump_file = 1; + * + *
    +       * the path to the dump file on the MRC host
    +       * 
    + */ + public Builder setDumpFileBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + dumpFile_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_dump_restore_databaseRequest) + } + + static { + defaultInstance = new xtreemfs_dump_restore_databaseRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_dump_restore_databaseRequest) + } + + public interface xtreemfs_get_suitable_osdsRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional string file_id = 1; + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + boolean hasFileId(); + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + java.lang.String getFileId(); + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // optional string path = 3; + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + boolean hasPath(); + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + java.lang.String getPath(); + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // optional string volume_name = 4; + /** + * optional string volume_name = 4; + */ + boolean hasVolumeName(); + /** + * optional string volume_name = 4; + */ + java.lang.String getVolumeName(); + /** + * optional string volume_name = 4; + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required fixed32 num_osds = 2; + /** + * required fixed32 num_osds = 2; + * + *
    +     * the number of OSDs required in a valid group
    +     * ignored by filtering and sorting policies
    +     * 
    + */ + boolean hasNumOsds(); + /** + * required fixed32 num_osds = 2; + * + *
    +     * the number of OSDs required in a valid group
    +     * ignored by filtering and sorting policies
    +     * 
    + */ + int getNumOsds(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_get_suitable_osdsRequest} + * + *
    +   * requests the list of suitable OSDs for new replicas of a file
    +   * 
    + */ + public static final class xtreemfs_get_suitable_osdsRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_get_suitable_osdsRequestOrBuilder { + // Use xtreemfs_get_suitable_osdsRequest.newBuilder() to construct. + private xtreemfs_get_suitable_osdsRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_get_suitable_osdsRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_get_suitable_osdsRequest defaultInstance; + public static xtreemfs_get_suitable_osdsRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_get_suitable_osdsRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_get_suitable_osdsRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + fileId_ = input.readBytes(); + break; + } + case 21: { + bitField0_ |= 0x00000008; + numOsds_ = input.readFixed32(); + break; + } + case 26: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 34: { + bitField0_ |= 0x00000004; + volumeName_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_get_suitable_osdsRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_get_suitable_osdsRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional string file_id = 1; + public static final int FILE_ID_FIELD_NUMBER = 1; + private java.lang.Object fileId_; + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string path = 3; + public static final int PATH_FIELD_NUMBER = 3; + private java.lang.Object path_; + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string volume_name = 4; + public static final int VOLUME_NAME_FIELD_NUMBER = 4; + private java.lang.Object volumeName_; + /** + * optional string volume_name = 4; + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string volume_name = 4; + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * optional string volume_name = 4; + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 num_osds = 2; + public static final int NUM_OSDS_FIELD_NUMBER = 2; + private int numOsds_; + /** + * required fixed32 num_osds = 2; + * + *
    +     * the number of OSDs required in a valid group
    +     * ignored by filtering and sorting policies
    +     * 
    + */ + public boolean hasNumOsds() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 num_osds = 2; + * + *
    +     * the number of OSDs required in a valid group
    +     * ignored by filtering and sorting policies
    +     * 
    + */ + public int getNumOsds() { + return numOsds_; + } + + private void initFields() { + fileId_ = ""; + path_ = ""; + volumeName_ = ""; + numOsds_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasNumOsds()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed32(2, numOsds_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(3, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(4, getVolumeNameBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(2, numOsds_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, getVolumeNameBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_get_suitable_osdsRequest} + * + *
    +     * requests the list of suitable OSDs for new replicas of a file
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + numOsds_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.numOsds_ = numOsds_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest.getDefaultInstance()) return this; + if (other.hasFileId()) { + bitField0_ |= 0x00000001; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasVolumeName()) { + bitField0_ |= 0x00000004; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasNumOsds()) { + setNumOsds(other.getNumOsds()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasNumOsds()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional string file_id = 1; + private java.lang.Object fileId_ = ""; + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + + // optional string path = 3; + private java.lang.Object path_ = ""; + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // optional string volume_name = 4; + private java.lang.Object volumeName_ = ""; + /** + * optional string volume_name = 4; + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string volume_name = 4; + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string volume_name = 4; + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string volume_name = 4; + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + volumeName_ = value; + onChanged(); + return this; + } + /** + * optional string volume_name = 4; + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000004); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * optional string volume_name = 4; + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + volumeName_ = value; + onChanged(); + return this; + } + + // required fixed32 num_osds = 2; + private int numOsds_ ; + /** + * required fixed32 num_osds = 2; + * + *
    +       * the number of OSDs required in a valid group
    +       * ignored by filtering and sorting policies
    +       * 
    + */ + public boolean hasNumOsds() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 num_osds = 2; + * + *
    +       * the number of OSDs required in a valid group
    +       * ignored by filtering and sorting policies
    +       * 
    + */ + public int getNumOsds() { + return numOsds_; + } + /** + * required fixed32 num_osds = 2; + * + *
    +       * the number of OSDs required in a valid group
    +       * ignored by filtering and sorting policies
    +       * 
    + */ + public Builder setNumOsds(int value) { + bitField0_ |= 0x00000008; + numOsds_ = value; + onChanged(); + return this; + } + /** + * required fixed32 num_osds = 2; + * + *
    +       * the number of OSDs required in a valid group
    +       * ignored by filtering and sorting policies
    +       * 
    + */ + public Builder clearNumOsds() { + bitField0_ = (bitField0_ & ~0x00000008); + numOsds_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_get_suitable_osdsRequest) + } + + static { + defaultInstance = new xtreemfs_get_suitable_osdsRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_get_suitable_osdsRequest) + } + + public interface xtreemfs_get_suitable_osdsResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated string osd_uuids = 1; + /** + * repeated string osd_uuids = 1; + */ + java.util.List + getOsdUuidsList(); + /** + * repeated string osd_uuids = 1; + */ + int getOsdUuidsCount(); + /** + * repeated string osd_uuids = 1; + */ + java.lang.String getOsdUuids(int index); + /** + * repeated string osd_uuids = 1; + */ + com.google.protobuf.ByteString + getOsdUuidsBytes(int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_get_suitable_osdsResponse} + * + *
    +   * returns a list of suitable OSDs
    +   * 
    + */ + public static final class xtreemfs_get_suitable_osdsResponse extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_get_suitable_osdsResponseOrBuilder { + // Use xtreemfs_get_suitable_osdsResponse.newBuilder() to construct. + private xtreemfs_get_suitable_osdsResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_get_suitable_osdsResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_get_suitable_osdsResponse defaultInstance; + public static xtreemfs_get_suitable_osdsResponse getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_get_suitable_osdsResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_get_suitable_osdsResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + osdUuids_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000001; + } + osdUuids_.add(input.readBytes()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + osdUuids_ = new com.google.protobuf.UnmodifiableLazyStringList(osdUuids_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_get_suitable_osdsResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_get_suitable_osdsResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated string osd_uuids = 1; + public static final int OSD_UUIDS_FIELD_NUMBER = 1; + private com.google.protobuf.LazyStringList osdUuids_; + /** + * repeated string osd_uuids = 1; + */ + public java.util.List + getOsdUuidsList() { + return osdUuids_; + } + /** + * repeated string osd_uuids = 1; + */ + public int getOsdUuidsCount() { + return osdUuids_.size(); + } + /** + * repeated string osd_uuids = 1; + */ + public java.lang.String getOsdUuids(int index) { + return osdUuids_.get(index); + } + /** + * repeated string osd_uuids = 1; + */ + public com.google.protobuf.ByteString + getOsdUuidsBytes(int index) { + return osdUuids_.getByteString(index); + } + + private void initFields() { + osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < osdUuids_.size(); i++) { + output.writeBytes(1, osdUuids_.getByteString(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < osdUuids_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(osdUuids_.getByteString(i)); + } + size += dataSize; + size += 1 * getOsdUuidsList().size(); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_get_suitable_osdsResponse} + * + *
    +     * returns a list of suitable OSDs
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse(this); + int from_bitField0_ = bitField0_; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + osdUuids_ = new com.google.protobuf.UnmodifiableLazyStringList( + osdUuids_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.osdUuids_ = osdUuids_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse.getDefaultInstance()) return this; + if (!other.osdUuids_.isEmpty()) { + if (osdUuids_.isEmpty()) { + osdUuids_ = other.osdUuids_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureOsdUuidsIsMutable(); + osdUuids_.addAll(other.osdUuids_); + } + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_suitable_osdsResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated string osd_uuids = 1; + private com.google.protobuf.LazyStringList osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureOsdUuidsIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + osdUuids_ = new com.google.protobuf.LazyStringArrayList(osdUuids_); + bitField0_ |= 0x00000001; + } + } + /** + * repeated string osd_uuids = 1; + */ + public java.util.List + getOsdUuidsList() { + return java.util.Collections.unmodifiableList(osdUuids_); + } + /** + * repeated string osd_uuids = 1; + */ + public int getOsdUuidsCount() { + return osdUuids_.size(); + } + /** + * repeated string osd_uuids = 1; + */ + public java.lang.String getOsdUuids(int index) { + return osdUuids_.get(index); + } + /** + * repeated string osd_uuids = 1; + */ + public com.google.protobuf.ByteString + getOsdUuidsBytes(int index) { + return osdUuids_.getByteString(index); + } + /** + * repeated string osd_uuids = 1; + */ + public Builder setOsdUuids( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureOsdUuidsIsMutable(); + osdUuids_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 1; + */ + public Builder addOsdUuids( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureOsdUuidsIsMutable(); + osdUuids_.add(value); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 1; + */ + public Builder addAllOsdUuids( + java.lang.Iterable values) { + ensureOsdUuidsIsMutable(); + super.addAll(values, osdUuids_); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 1; + */ + public Builder clearOsdUuids() { + osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 1; + */ + public Builder addOsdUuidsBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureOsdUuidsIsMutable(); + osdUuids_.add(value); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_get_suitable_osdsResponse) + } + + static { + defaultInstance = new xtreemfs_get_suitable_osdsResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_get_suitable_osdsResponse) + } + + public interface timestampResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed32 timestamp_s = 1; + /** + * required fixed32 timestamp_s = 1; + */ + boolean hasTimestampS(); + /** + * required fixed32 timestamp_s = 1; + */ + int getTimestampS(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.timestampResponse} + */ + public static final class timestampResponse extends + com.google.protobuf.GeneratedMessage + implements timestampResponseOrBuilder { + // Use timestampResponse.newBuilder() to construct. + private timestampResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private timestampResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final timestampResponse defaultInstance; + public static timestampResponse getDefaultInstance() { + return defaultInstance; + } + + public timestampResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private timestampResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 13: { + bitField0_ |= 0x00000001; + timestampS_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_timestampResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_timestampResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public timestampResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new timestampResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed32 timestamp_s = 1; + public static final int TIMESTAMP_S_FIELD_NUMBER = 1; + private int timestampS_; + /** + * required fixed32 timestamp_s = 1; + */ + public boolean hasTimestampS() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 timestamp_s = 1; + */ + public int getTimestampS() { + return timestampS_; + } + + private void initFields() { + timestampS_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasTimestampS()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed32(1, timestampS_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(1, timestampS_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.timestampResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_timestampResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_timestampResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + timestampS_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_timestampResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.timestampS_ = timestampS_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse.getDefaultInstance()) return this; + if (other.hasTimestampS()) { + setTimestampS(other.getTimestampS()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasTimestampS()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed32 timestamp_s = 1; + private int timestampS_ ; + /** + * required fixed32 timestamp_s = 1; + */ + public boolean hasTimestampS() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 timestamp_s = 1; + */ + public int getTimestampS() { + return timestampS_; + } + /** + * required fixed32 timestamp_s = 1; + */ + public Builder setTimestampS(int value) { + bitField0_ |= 0x00000001; + timestampS_ = value; + onChanged(); + return this; + } + /** + * required fixed32 timestamp_s = 1; + */ + public Builder clearTimestampS() { + bitField0_ = (bitField0_ & ~0x00000001); + timestampS_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.timestampResponse) + } + + static { + defaultInstance = new timestampResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.timestampResponse) + } + + public interface stringMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string a_string = 1; + /** + * required string a_string = 1; + */ + boolean hasAString(); + /** + * required string a_string = 1; + */ + java.lang.String getAString(); + /** + * required string a_string = 1; + */ + com.google.protobuf.ByteString + getAStringBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.stringMessage} + */ + public static final class stringMessage extends + com.google.protobuf.GeneratedMessage + implements stringMessageOrBuilder { + // Use stringMessage.newBuilder() to construct. + private stringMessage(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private stringMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final stringMessage defaultInstance; + public static stringMessage getDefaultInstance() { + return defaultInstance; + } + + public stringMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private stringMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + aString_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_stringMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_stringMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public stringMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new stringMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string a_string = 1; + public static final int A_STRING_FIELD_NUMBER = 1; + private java.lang.Object aString_; + /** + * required string a_string = 1; + */ + public boolean hasAString() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string a_string = 1; + */ + public java.lang.String getAString() { + java.lang.Object ref = aString_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + aString_ = s; + } + return s; + } + } + /** + * required string a_string = 1; + */ + public com.google.protobuf.ByteString + getAStringBytes() { + java.lang.Object ref = aString_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + aString_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + aString_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasAString()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getAStringBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getAStringBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.stringMessage} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_stringMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_stringMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + aString_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_stringMessage_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.aString_ = aString_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage.getDefaultInstance()) return this; + if (other.hasAString()) { + bitField0_ |= 0x00000001; + aString_ = other.aString_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasAString()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.stringMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string a_string = 1; + private java.lang.Object aString_ = ""; + /** + * required string a_string = 1; + */ + public boolean hasAString() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string a_string = 1; + */ + public java.lang.String getAString() { + java.lang.Object ref = aString_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + aString_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string a_string = 1; + */ + public com.google.protobuf.ByteString + getAStringBytes() { + java.lang.Object ref = aString_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + aString_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string a_string = 1; + */ + public Builder setAString( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + aString_ = value; + onChanged(); + return this; + } + /** + * required string a_string = 1; + */ + public Builder clearAString() { + bitField0_ = (bitField0_ & ~0x00000001); + aString_ = getDefaultInstance().getAString(); + onChanged(); + return this; + } + /** + * required string a_string = 1; + */ + public Builder setAStringBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + aString_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.stringMessage) + } + + static { + defaultInstance = new stringMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.stringMessage) + } + + public interface xtreemfs_listdirRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string path = 1; + /** + * required string path = 1; + */ + boolean hasPath(); + /** + * required string path = 1; + */ + java.lang.String getPath(); + /** + * required string path = 1; + */ + com.google.protobuf.ByteString + getPathBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_listdirRequest} + */ + public static final class xtreemfs_listdirRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_listdirRequestOrBuilder { + // Use xtreemfs_listdirRequest.newBuilder() to construct. + private xtreemfs_listdirRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_listdirRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_listdirRequest defaultInstance; + public static xtreemfs_listdirRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_listdirRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_listdirRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + path_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_listdirRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_listdirRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_listdirRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_listdirRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string path = 1; + public static final int PATH_FIELD_NUMBER = 1; + private java.lang.Object path_; + /** + * required string path = 1; + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string path = 1; + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * required string path = 1; + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + path_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasPath()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getPathBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getPathBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_listdirRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_listdirRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_listdirRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_listdirRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.path_ = path_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest.getDefaultInstance()) return this; + if (other.hasPath()) { + bitField0_ |= 0x00000001; + path_ = other.path_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasPath()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string path = 1; + private java.lang.Object path_ = ""; + /** + * required string path = 1; + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string path = 1; + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string path = 1; + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string path = 1; + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + path_ = value; + onChanged(); + return this; + } + /** + * required string path = 1; + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000001); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * required string path = 1; + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + path_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_listdirRequest) + } + + static { + defaultInstance = new xtreemfs_listdirRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_listdirRequest) + } + + public interface xtreemfs_listdirResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated string names = 1; + /** + * repeated string names = 1; + */ + java.util.List + getNamesList(); + /** + * repeated string names = 1; + */ + int getNamesCount(); + /** + * repeated string names = 1; + */ + java.lang.String getNames(int index); + /** + * repeated string names = 1; + */ + com.google.protobuf.ByteString + getNamesBytes(int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_listdirResponse} + */ + public static final class xtreemfs_listdirResponse extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_listdirResponseOrBuilder { + // Use xtreemfs_listdirResponse.newBuilder() to construct. + private xtreemfs_listdirResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_listdirResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_listdirResponse defaultInstance; + public static xtreemfs_listdirResponse getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_listdirResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_listdirResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + names_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000001; + } + names_.add(input.readBytes()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + names_ = new com.google.protobuf.UnmodifiableLazyStringList(names_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_listdirResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_listdirResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_listdirResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_listdirResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated string names = 1; + public static final int NAMES_FIELD_NUMBER = 1; + private com.google.protobuf.LazyStringList names_; + /** + * repeated string names = 1; + */ + public java.util.List + getNamesList() { + return names_; + } + /** + * repeated string names = 1; + */ + public int getNamesCount() { + return names_.size(); + } + /** + * repeated string names = 1; + */ + public java.lang.String getNames(int index) { + return names_.get(index); + } + /** + * repeated string names = 1; + */ + public com.google.protobuf.ByteString + getNamesBytes(int index) { + return names_.getByteString(index); + } + + private void initFields() { + names_ = com.google.protobuf.LazyStringArrayList.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < names_.size(); i++) { + output.writeBytes(1, names_.getByteString(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < names_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(names_.getByteString(i)); + } + size += dataSize; + size += 1 * getNamesList().size(); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_listdirResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_listdirResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_listdirResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + names_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_listdirResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse(this); + int from_bitField0_ = bitField0_; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + names_ = new com.google.protobuf.UnmodifiableLazyStringList( + names_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.names_ = names_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse.getDefaultInstance()) return this; + if (!other.names_.isEmpty()) { + if (names_.isEmpty()) { + names_ = other.names_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureNamesIsMutable(); + names_.addAll(other.names_); + } + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_listdirResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated string names = 1; + private com.google.protobuf.LazyStringList names_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureNamesIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + names_ = new com.google.protobuf.LazyStringArrayList(names_); + bitField0_ |= 0x00000001; + } + } + /** + * repeated string names = 1; + */ + public java.util.List + getNamesList() { + return java.util.Collections.unmodifiableList(names_); + } + /** + * repeated string names = 1; + */ + public int getNamesCount() { + return names_.size(); + } + /** + * repeated string names = 1; + */ + public java.lang.String getNames(int index) { + return names_.get(index); + } + /** + * repeated string names = 1; + */ + public com.google.protobuf.ByteString + getNamesBytes(int index) { + return names_.getByteString(index); + } + /** + * repeated string names = 1; + */ + public Builder setNames( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureNamesIsMutable(); + names_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string names = 1; + */ + public Builder addNames( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureNamesIsMutable(); + names_.add(value); + onChanged(); + return this; + } + /** + * repeated string names = 1; + */ + public Builder addAllNames( + java.lang.Iterable values) { + ensureNamesIsMutable(); + super.addAll(values, names_); + onChanged(); + return this; + } + /** + * repeated string names = 1; + */ + public Builder clearNames() { + names_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * repeated string names = 1; + */ + public Builder addNamesBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureNamesIsMutable(); + names_.add(value); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_listdirResponse) + } + + static { + defaultInstance = new xtreemfs_listdirResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_listdirResponse) + } + + public interface xtreemfs_replica_addRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional string file_id = 1; + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + boolean hasFileId(); + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + java.lang.String getFileId(); + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // optional string path = 3; + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + boolean hasPath(); + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + java.lang.String getPath(); + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // optional string volume_name = 4; + /** + * optional string volume_name = 4; + */ + boolean hasVolumeName(); + /** + * optional string volume_name = 4; + */ + java.lang.String getVolumeName(); + /** + * optional string volume_name = 4; + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required .xtreemfs.pbrpc.Replica new_replica = 2; + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +     * the replica to add
    +     * 
    + */ + boolean hasNewReplica(); + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +     * the replica to add
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica getNewReplica(); + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +     * the replica to add
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder getNewReplicaOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_replica_addRequest} + * + *
    +   * adds a replica to a file
    +   * 
    + */ + public static final class xtreemfs_replica_addRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_replica_addRequestOrBuilder { + // Use xtreemfs_replica_addRequest.newBuilder() to construct. + private xtreemfs_replica_addRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_replica_addRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_replica_addRequest defaultInstance; + public static xtreemfs_replica_addRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_replica_addRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_replica_addRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + fileId_ = input.readBytes(); + break; + } + case 18: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder subBuilder = null; + if (((bitField0_ & 0x00000008) == 0x00000008)) { + subBuilder = newReplica_.toBuilder(); + } + newReplica_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(newReplica_); + newReplica_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000008; + break; + } + case 26: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 34: { + bitField0_ |= 0x00000004; + volumeName_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_addRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_addRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_replica_addRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_replica_addRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional string file_id = 1; + public static final int FILE_ID_FIELD_NUMBER = 1; + private java.lang.Object fileId_; + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string path = 3; + public static final int PATH_FIELD_NUMBER = 3; + private java.lang.Object path_; + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string volume_name = 4; + public static final int VOLUME_NAME_FIELD_NUMBER = 4; + private java.lang.Object volumeName_; + /** + * optional string volume_name = 4; + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string volume_name = 4; + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * optional string volume_name = 4; + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required .xtreemfs.pbrpc.Replica new_replica = 2; + public static final int NEW_REPLICA_FIELD_NUMBER = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica newReplica_; + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +     * the replica to add
    +     * 
    + */ + public boolean hasNewReplica() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +     * the replica to add
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica getNewReplica() { + return newReplica_; + } + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +     * the replica to add
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder getNewReplicaOrBuilder() { + return newReplica_; + } + + private void initFields() { + fileId_ = ""; + path_ = ""; + volumeName_ = ""; + newReplica_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasNewReplica()) { + memoizedIsInitialized = 0; + return false; + } + if (!getNewReplica().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeMessage(2, newReplica_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(3, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(4, getVolumeNameBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, newReplica_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, getVolumeNameBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_replica_addRequest} + * + *
    +     * adds a replica to a file
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_addRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_addRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getNewReplicaFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + if (newReplicaBuilder_ == null) { + newReplica_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.getDefaultInstance(); + } else { + newReplicaBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_addRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + if (newReplicaBuilder_ == null) { + result.newReplica_ = newReplica_; + } else { + result.newReplica_ = newReplicaBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest.getDefaultInstance()) return this; + if (other.hasFileId()) { + bitField0_ |= 0x00000001; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasVolumeName()) { + bitField0_ |= 0x00000004; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasNewReplica()) { + mergeNewReplica(other.getNewReplica()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasNewReplica()) { + + return false; + } + if (!getNewReplica().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_addRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional string file_id = 1; + private java.lang.Object fileId_ = ""; + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + + // optional string path = 3; + private java.lang.Object path_ = ""; + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // optional string volume_name = 4; + private java.lang.Object volumeName_ = ""; + /** + * optional string volume_name = 4; + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string volume_name = 4; + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string volume_name = 4; + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string volume_name = 4; + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + volumeName_ = value; + onChanged(); + return this; + } + /** + * optional string volume_name = 4; + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000004); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * optional string volume_name = 4; + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + volumeName_ = value; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.Replica new_replica = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica newReplica_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder> newReplicaBuilder_; + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +       * the replica to add
    +       * 
    + */ + public boolean hasNewReplica() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +       * the replica to add
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica getNewReplica() { + if (newReplicaBuilder_ == null) { + return newReplica_; + } else { + return newReplicaBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +       * the replica to add
    +       * 
    + */ + public Builder setNewReplica(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica value) { + if (newReplicaBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + newReplica_ = value; + onChanged(); + } else { + newReplicaBuilder_.setMessage(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +       * the replica to add
    +       * 
    + */ + public Builder setNewReplica( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder builderForValue) { + if (newReplicaBuilder_ == null) { + newReplica_ = builderForValue.build(); + onChanged(); + } else { + newReplicaBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +       * the replica to add
    +       * 
    + */ + public Builder mergeNewReplica(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica value) { + if (newReplicaBuilder_ == null) { + if (((bitField0_ & 0x00000008) == 0x00000008) && + newReplica_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.getDefaultInstance()) { + newReplica_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.newBuilder(newReplica_).mergeFrom(value).buildPartial(); + } else { + newReplica_ = value; + } + onChanged(); + } else { + newReplicaBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +       * the replica to add
    +       * 
    + */ + public Builder clearNewReplica() { + if (newReplicaBuilder_ == null) { + newReplica_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.getDefaultInstance(); + onChanged(); + } else { + newReplicaBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +       * the replica to add
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder getNewReplicaBuilder() { + bitField0_ |= 0x00000008; + onChanged(); + return getNewReplicaFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +       * the replica to add
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder getNewReplicaOrBuilder() { + if (newReplicaBuilder_ != null) { + return newReplicaBuilder_.getMessageOrBuilder(); + } else { + return newReplica_; + } + } + /** + * required .xtreemfs.pbrpc.Replica new_replica = 2; + * + *
    +       * the replica to add
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder> + getNewReplicaFieldBuilder() { + if (newReplicaBuilder_ == null) { + newReplicaBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.ReplicaOrBuilder>( + newReplica_, + getParentForChildren(), + isClean()); + newReplica_ = null; + } + return newReplicaBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_replica_addRequest) + } + + static { + defaultInstance = new xtreemfs_replica_addRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_replica_addRequest) + } + + public interface xtreemfs_replica_listRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional string file_id = 1; + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + boolean hasFileId(); + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + java.lang.String getFileId(); + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // optional string path = 2; + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + boolean hasPath(); + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + java.lang.String getPath(); + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // optional string volume_name = 3; + /** + * optional string volume_name = 3; + */ + boolean hasVolumeName(); + /** + * optional string volume_name = 3; + */ + java.lang.String getVolumeName(); + /** + * optional string volume_name = 3; + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_replica_listRequest} + * + *
    +   * requests a list of all replicas of a file (deprecated)
    +   * 
    + */ + public static final class xtreemfs_replica_listRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_replica_listRequestOrBuilder { + // Use xtreemfs_replica_listRequest.newBuilder() to construct. + private xtreemfs_replica_listRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_replica_listRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_replica_listRequest defaultInstance; + public static xtreemfs_replica_listRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_replica_listRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_replica_listRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + fileId_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + volumeName_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_listRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_listRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_replica_listRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_replica_listRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional string file_id = 1; + public static final int FILE_ID_FIELD_NUMBER = 1; + private java.lang.Object fileId_; + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string volume_name = 3; + public static final int VOLUME_NAME_FIELD_NUMBER = 3; + private java.lang.Object volumeName_; + /** + * optional string volume_name = 3; + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string volume_name = 3; + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * optional string volume_name = 3; + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + fileId_ = ""; + path_ = ""; + volumeName_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getVolumeNameBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getVolumeNameBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_replica_listRequest} + * + *
    +     * requests a list of all replicas of a file (deprecated)
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_listRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_listRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_listRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.volumeName_ = volumeName_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest.getDefaultInstance()) return this; + if (other.hasFileId()) { + bitField0_ |= 0x00000001; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasVolumeName()) { + bitField0_ |= 0x00000004; + volumeName_ = other.volumeName_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_listRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional string file_id = 1; + private java.lang.Object fileId_ = ""; + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + + // optional string path = 2; + private java.lang.Object path_ = ""; + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // optional string volume_name = 3; + private java.lang.Object volumeName_ = ""; + /** + * optional string volume_name = 3; + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string volume_name = 3; + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string volume_name = 3; + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string volume_name = 3; + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + volumeName_ = value; + onChanged(); + return this; + } + /** + * optional string volume_name = 3; + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000004); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * optional string volume_name = 3; + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + volumeName_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_replica_listRequest) + } + + static { + defaultInstance = new xtreemfs_replica_listRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_replica_listRequest) + } + + public interface xtreemfs_get_xlocsetRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional string file_id = 1; + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + boolean hasFileId(); + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + java.lang.String getFileId(); + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // optional string path = 2; + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file
    +     * 
    + */ + boolean hasPath(); + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file
    +     * 
    + */ + java.lang.String getPath(); + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // optional string volume_name = 3; + /** + * optional string volume_name = 3; + */ + boolean hasVolumeName(); + /** + * optional string volume_name = 3; + */ + java.lang.String getVolumeName(); + /** + * optional string volume_name = 3; + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // optional .xtreemfs.pbrpc.XCap xcap = 4; + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +     * or a valid XCap.
    +     * 
    + */ + boolean hasXcap(); + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +     * or a valid XCap.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getXcap(); + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +     * or a valid XCap.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getXcapOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_get_xlocsetRequest} + * + *
    +   * requests the xLocSet of a file
    +   * 
    + */ + public static final class xtreemfs_get_xlocsetRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_get_xlocsetRequestOrBuilder { + // Use xtreemfs_get_xlocsetRequest.newBuilder() to construct. + private xtreemfs_get_xlocsetRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_get_xlocsetRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_get_xlocsetRequest defaultInstance; + public static xtreemfs_get_xlocsetRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_get_xlocsetRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_get_xlocsetRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + fileId_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + volumeName_ = input.readBytes(); + break; + } + case 34: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder subBuilder = null; + if (((bitField0_ & 0x00000008) == 0x00000008)) { + subBuilder = xcap_.toBuilder(); + } + xcap_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(xcap_); + xcap_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000008; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_xlocsetRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_xlocsetRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_get_xlocsetRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_get_xlocsetRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional string file_id = 1; + public static final int FILE_ID_FIELD_NUMBER = 1; + private java.lang.Object fileId_; + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string path = 2; + public static final int PATH_FIELD_NUMBER = 2; + private java.lang.Object path_; + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * optional string path = 2; + * + *
    +     * or path and volume_name to file
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string volume_name = 3; + public static final int VOLUME_NAME_FIELD_NUMBER = 3; + private java.lang.Object volumeName_; + /** + * optional string volume_name = 3; + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string volume_name = 3; + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * optional string volume_name = 3; + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional .xtreemfs.pbrpc.XCap xcap = 4; + public static final int XCAP_FIELD_NUMBER = 4; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap xcap_; + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +     * or a valid XCap.
    +     * 
    + */ + public boolean hasXcap() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +     * or a valid XCap.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getXcap() { + return xcap_; + } + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +     * or a valid XCap.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getXcapOrBuilder() { + return xcap_; + } + + private void initFields() { + fileId_ = ""; + path_ = ""; + volumeName_ = ""; + xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (hasXcap()) { + if (!getXcap().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeMessage(4, xcap_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getVolumeNameBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, xcap_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_get_xlocsetRequest} + * + *
    +     * requests the xLocSet of a file
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_xlocsetRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_xlocsetRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getXcapFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + if (xcapBuilder_ == null) { + xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + } else { + xcapBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_xlocsetRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + if (xcapBuilder_ == null) { + result.xcap_ = xcap_; + } else { + result.xcap_ = xcapBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest.getDefaultInstance()) return this; + if (other.hasFileId()) { + bitField0_ |= 0x00000001; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasVolumeName()) { + bitField0_ |= 0x00000004; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasXcap()) { + mergeXcap(other.getXcap()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (hasXcap()) { + if (!getXcap().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_xlocsetRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional string file_id = 1; + private java.lang.Object fileId_ = ""; + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + + // optional string path = 2; + private java.lang.Object path_ = ""; + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * optional string path = 2; + * + *
    +       * or path and volume_name to file
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // optional string volume_name = 3; + private java.lang.Object volumeName_ = ""; + /** + * optional string volume_name = 3; + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string volume_name = 3; + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string volume_name = 3; + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string volume_name = 3; + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + volumeName_ = value; + onChanged(); + return this; + } + /** + * optional string volume_name = 3; + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000004); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * optional string volume_name = 3; + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + volumeName_ = value; + onChanged(); + return this; + } + + // optional .xtreemfs.pbrpc.XCap xcap = 4; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder> xcapBuilder_; + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +       * or a valid XCap.
    +       * 
    + */ + public boolean hasXcap() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +       * or a valid XCap.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getXcap() { + if (xcapBuilder_ == null) { + return xcap_; + } else { + return xcapBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +       * or a valid XCap.
    +       * 
    + */ + public Builder setXcap(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap value) { + if (xcapBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + xcap_ = value; + onChanged(); + } else { + xcapBuilder_.setMessage(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +       * or a valid XCap.
    +       * 
    + */ + public Builder setXcap( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder builderForValue) { + if (xcapBuilder_ == null) { + xcap_ = builderForValue.build(); + onChanged(); + } else { + xcapBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +       * or a valid XCap.
    +       * 
    + */ + public Builder mergeXcap(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap value) { + if (xcapBuilder_ == null) { + if (((bitField0_ & 0x00000008) == 0x00000008) && + xcap_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance()) { + xcap_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.newBuilder(xcap_).mergeFrom(value).buildPartial(); + } else { + xcap_ = value; + } + onChanged(); + } else { + xcapBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +       * or a valid XCap.
    +       * 
    + */ + public Builder clearXcap() { + if (xcapBuilder_ == null) { + xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + onChanged(); + } else { + xcapBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +       * or a valid XCap.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder getXcapBuilder() { + bitField0_ |= 0x00000008; + onChanged(); + return getXcapFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +       * or a valid XCap.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getXcapOrBuilder() { + if (xcapBuilder_ != null) { + return xcapBuilder_.getMessageOrBuilder(); + } else { + return xcap_; + } + } + /** + * optional .xtreemfs.pbrpc.XCap xcap = 4; + * + *
    +       * or a valid XCap.
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder> + getXcapFieldBuilder() { + if (xcapBuilder_ == null) { + xcapBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder>( + xcap_, + getParentForChildren(), + isClean()); + xcap_ = null; + } + return xcapBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_get_xlocsetRequest) + } + + static { + defaultInstance = new xtreemfs_get_xlocsetRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_get_xlocsetRequest) + } + + public interface xtreemfs_replica_removeRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional string file_id = 1; + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + boolean hasFileId(); + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + java.lang.String getFileId(); + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // optional string path = 3; + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + boolean hasPath(); + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + java.lang.String getPath(); + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + com.google.protobuf.ByteString + getPathBytes(); + + // optional string volume_name = 4; + /** + * optional string volume_name = 4; + */ + boolean hasVolumeName(); + /** + * optional string volume_name = 4; + */ + java.lang.String getVolumeName(); + /** + * optional string volume_name = 4; + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + + // required string osd_uuid = 2; + /** + * required string osd_uuid = 2; + * + *
    +     * the UUID of the head OSD of the replica to remove
    +     * 
    + */ + boolean hasOsdUuid(); + /** + * required string osd_uuid = 2; + * + *
    +     * the UUID of the head OSD of the replica to remove
    +     * 
    + */ + java.lang.String getOsdUuid(); + /** + * required string osd_uuid = 2; + * + *
    +     * the UUID of the head OSD of the replica to remove
    +     * 
    + */ + com.google.protobuf.ByteString + getOsdUuidBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_replica_removeRequest} + * + *
    +   * removes a replica from a file
    +   * 
    + */ + public static final class xtreemfs_replica_removeRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_replica_removeRequestOrBuilder { + // Use xtreemfs_replica_removeRequest.newBuilder() to construct. + private xtreemfs_replica_removeRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_replica_removeRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_replica_removeRequest defaultInstance; + public static xtreemfs_replica_removeRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_replica_removeRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_replica_removeRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + fileId_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000008; + osdUuid_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000002; + path_ = input.readBytes(); + break; + } + case 34: { + bitField0_ |= 0x00000004; + volumeName_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_removeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_removeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_replica_removeRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_replica_removeRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional string file_id = 1; + public static final int FILE_ID_FIELD_NUMBER = 1; + private java.lang.Object fileId_; + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * optional string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string path = 3; + public static final int PATH_FIELD_NUMBER = 3; + private java.lang.Object path_; + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + path_ = s; + } + return s; + } + } + /** + * optional string path = 3; + * + *
    +     * or path and volume_name to file.
    +     * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string volume_name = 4; + public static final int VOLUME_NAME_FIELD_NUMBER = 4; + private java.lang.Object volumeName_; + /** + * optional string volume_name = 4; + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string volume_name = 4; + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * optional string volume_name = 4; + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string osd_uuid = 2; + public static final int OSD_UUID_FIELD_NUMBER = 2; + private java.lang.Object osdUuid_; + /** + * required string osd_uuid = 2; + * + *
    +     * the UUID of the head OSD of the replica to remove
    +     * 
    + */ + public boolean hasOsdUuid() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required string osd_uuid = 2; + * + *
    +     * the UUID of the head OSD of the replica to remove
    +     * 
    + */ + public java.lang.String getOsdUuid() { + java.lang.Object ref = osdUuid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + osdUuid_ = s; + } + return s; + } + } + /** + * required string osd_uuid = 2; + * + *
    +     * the UUID of the head OSD of the replica to remove
    +     * 
    + */ + public com.google.protobuf.ByteString + getOsdUuidBytes() { + java.lang.Object ref = osdUuid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + osdUuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + fileId_ = ""; + path_ = ""; + volumeName_ = ""; + osdUuid_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasOsdUuid()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBytes(2, getOsdUuidBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(3, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(4, getVolumeNameBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getOsdUuidBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getPathBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, getVolumeNameBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_replica_removeRequest} + * + *
    +     * removes a replica from a file
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_removeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_removeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + path_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + osdUuid_ = ""; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_replica_removeRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.path_ = path_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.volumeName_ = volumeName_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.osdUuid_ = osdUuid_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest.getDefaultInstance()) return this; + if (other.hasFileId()) { + bitField0_ |= 0x00000001; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasPath()) { + bitField0_ |= 0x00000002; + path_ = other.path_; + onChanged(); + } + if (other.hasVolumeName()) { + bitField0_ |= 0x00000004; + volumeName_ = other.volumeName_; + onChanged(); + } + if (other.hasOsdUuid()) { + bitField0_ |= 0x00000008; + osdUuid_ = other.osdUuid_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasOsdUuid()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_replica_removeRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional string file_id = 1; + private java.lang.Object fileId_ = ""; + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * optional string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + + // optional string path = 3; + private java.lang.Object path_ = ""; + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public boolean hasPath() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public java.lang.String getPath() { + java.lang.Object ref = path_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + path_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public com.google.protobuf.ByteString + getPathBytes() { + java.lang.Object ref = path_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + path_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder setPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder clearPath() { + bitField0_ = (bitField0_ & ~0x00000002); + path_ = getDefaultInstance().getPath(); + onChanged(); + return this; + } + /** + * optional string path = 3; + * + *
    +       * or path and volume_name to file.
    +       * 
    + */ + public Builder setPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + path_ = value; + onChanged(); + return this; + } + + // optional string volume_name = 4; + private java.lang.Object volumeName_ = ""; + /** + * optional string volume_name = 4; + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string volume_name = 4; + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string volume_name = 4; + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string volume_name = 4; + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + volumeName_ = value; + onChanged(); + return this; + } + /** + * optional string volume_name = 4; + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000004); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * optional string volume_name = 4; + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + volumeName_ = value; + onChanged(); + return this; + } + + // required string osd_uuid = 2; + private java.lang.Object osdUuid_ = ""; + /** + * required string osd_uuid = 2; + * + *
    +       * the UUID of the head OSD of the replica to remove
    +       * 
    + */ + public boolean hasOsdUuid() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required string osd_uuid = 2; + * + *
    +       * the UUID of the head OSD of the replica to remove
    +       * 
    + */ + public java.lang.String getOsdUuid() { + java.lang.Object ref = osdUuid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + osdUuid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string osd_uuid = 2; + * + *
    +       * the UUID of the head OSD of the replica to remove
    +       * 
    + */ + public com.google.protobuf.ByteString + getOsdUuidBytes() { + java.lang.Object ref = osdUuid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + osdUuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string osd_uuid = 2; + * + *
    +       * the UUID of the head OSD of the replica to remove
    +       * 
    + */ + public Builder setOsdUuid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + osdUuid_ = value; + onChanged(); + return this; + } + /** + * required string osd_uuid = 2; + * + *
    +       * the UUID of the head OSD of the replica to remove
    +       * 
    + */ + public Builder clearOsdUuid() { + bitField0_ = (bitField0_ & ~0x00000008); + osdUuid_ = getDefaultInstance().getOsdUuid(); + onChanged(); + return this; + } + /** + * required string osd_uuid = 2; + * + *
    +       * the UUID of the head OSD of the replica to remove
    +       * 
    + */ + public Builder setOsdUuidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + osdUuid_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_replica_removeRequest) + } + + static { + defaultInstance = new xtreemfs_replica_removeRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_replica_removeRequest) + } + + public interface xtreemfs_restore_fileRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string file_path = 1; + /** + * required string file_path = 1; + * + *
    +     * the path to the restored file
    +     * 
    + */ + boolean hasFilePath(); + /** + * required string file_path = 1; + * + *
    +     * the path to the restored file
    +     * 
    + */ + java.lang.String getFilePath(); + /** + * required string file_path = 1; + * + *
    +     * the path to the restored file
    +     * 
    + */ + com.google.protobuf.ByteString + getFilePathBytes(); + + // required string file_id = 2; + /** + * required string file_id = 2; + * + *
    +     * the file ID
    +     * 
    + */ + boolean hasFileId(); + /** + * required string file_id = 2; + * + *
    +     * the file ID
    +     * 
    + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + * + *
    +     * the file ID
    +     * 
    + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 file_size = 3; + /** + * required fixed64 file_size = 3; + * + *
    +     * the file size
    +     * 
    + */ + boolean hasFileSize(); + /** + * required fixed64 file_size = 3; + * + *
    +     * the file size
    +     * 
    + */ + long getFileSize(); + + // required string osd_uuid = 4; + /** + * required string osd_uuid = 4; + * + *
    +     * the UUID of the OSD with the orphaned file content
    +     * 
    + */ + boolean hasOsdUuid(); + /** + * required string osd_uuid = 4; + * + *
    +     * the UUID of the OSD with the orphaned file content
    +     * 
    + */ + java.lang.String getOsdUuid(); + /** + * required string osd_uuid = 4; + * + *
    +     * the UUID of the OSD with the orphaned file content
    +     * 
    + */ + com.google.protobuf.ByteString + getOsdUuidBytes(); + + // required fixed32 stripe_size = 5; + /** + * required fixed32 stripe_size = 5; + * + *
    +     * the stripe size of the file
    +     * 
    + */ + boolean hasStripeSize(); + /** + * required fixed32 stripe_size = 5; + * + *
    +     * the stripe size of the file
    +     * 
    + */ + int getStripeSize(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_restore_fileRequest} + * + *
    +   * restores a file w/ orphaned file content by creating a new metadata object
    +   * 
    + */ + public static final class xtreemfs_restore_fileRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_restore_fileRequestOrBuilder { + // Use xtreemfs_restore_fileRequest.newBuilder() to construct. + private xtreemfs_restore_fileRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_restore_fileRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_restore_fileRequest defaultInstance; + public static xtreemfs_restore_fileRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_restore_fileRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_restore_fileRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + filePath_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + fileSize_ = input.readFixed64(); + break; + } + case 34: { + bitField0_ |= 0x00000008; + osdUuid_ = input.readBytes(); + break; + } + case 45: { + bitField0_ |= 0x00000010; + stripeSize_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_restore_fileRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_restore_fileRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_restore_fileRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_restore_fileRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string file_path = 1; + public static final int FILE_PATH_FIELD_NUMBER = 1; + private java.lang.Object filePath_; + /** + * required string file_path = 1; + * + *
    +     * the path to the restored file
    +     * 
    + */ + public boolean hasFilePath() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string file_path = 1; + * + *
    +     * the path to the restored file
    +     * 
    + */ + public java.lang.String getFilePath() { + java.lang.Object ref = filePath_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + filePath_ = s; + } + return s; + } + } + /** + * required string file_path = 1; + * + *
    +     * the path to the restored file
    +     * 
    + */ + public com.google.protobuf.ByteString + getFilePathBytes() { + java.lang.Object ref = filePath_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + filePath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + * + *
    +     * the file ID
    +     * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + * + *
    +     * the file ID
    +     * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + * + *
    +     * the file ID
    +     * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 file_size = 3; + public static final int FILE_SIZE_FIELD_NUMBER = 3; + private long fileSize_; + /** + * required fixed64 file_size = 3; + * + *
    +     * the file size
    +     * 
    + */ + public boolean hasFileSize() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 file_size = 3; + * + *
    +     * the file size
    +     * 
    + */ + public long getFileSize() { + return fileSize_; + } + + // required string osd_uuid = 4; + public static final int OSD_UUID_FIELD_NUMBER = 4; + private java.lang.Object osdUuid_; + /** + * required string osd_uuid = 4; + * + *
    +     * the UUID of the OSD with the orphaned file content
    +     * 
    + */ + public boolean hasOsdUuid() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required string osd_uuid = 4; + * + *
    +     * the UUID of the OSD with the orphaned file content
    +     * 
    + */ + public java.lang.String getOsdUuid() { + java.lang.Object ref = osdUuid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + osdUuid_ = s; + } + return s; + } + } + /** + * required string osd_uuid = 4; + * + *
    +     * the UUID of the OSD with the orphaned file content
    +     * 
    + */ + public com.google.protobuf.ByteString + getOsdUuidBytes() { + java.lang.Object ref = osdUuid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + osdUuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 stripe_size = 5; + public static final int STRIPE_SIZE_FIELD_NUMBER = 5; + private int stripeSize_; + /** + * required fixed32 stripe_size = 5; + * + *
    +     * the stripe size of the file
    +     * 
    + */ + public boolean hasStripeSize() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 stripe_size = 5; + * + *
    +     * the stripe size of the file
    +     * 
    + */ + public int getStripeSize() { + return stripeSize_; + } + + private void initFields() { + filePath_ = ""; + fileId_ = ""; + fileSize_ = 0L; + osdUuid_ = ""; + stripeSize_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFilePath()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileSize()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOsdUuid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasStripeSize()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getFilePathBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, fileSize_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBytes(4, getOsdUuidBytes()); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeFixed32(5, stripeSize_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getFilePathBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, fileSize_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, getOsdUuidBytes()); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(5, stripeSize_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_restore_fileRequest} + * + *
    +     * restores a file w/ orphaned file content by creating a new metadata object
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_restore_fileRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_restore_fileRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + filePath_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + fileSize_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + osdUuid_ = ""; + bitField0_ = (bitField0_ & ~0x00000008); + stripeSize_ = 0; + bitField0_ = (bitField0_ & ~0x00000010); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_restore_fileRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.filePath_ = filePath_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.fileSize_ = fileSize_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.osdUuid_ = osdUuid_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.stripeSize_ = stripeSize_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest.getDefaultInstance()) return this; + if (other.hasFilePath()) { + bitField0_ |= 0x00000001; + filePath_ = other.filePath_; + onChanged(); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasFileSize()) { + setFileSize(other.getFileSize()); + } + if (other.hasOsdUuid()) { + bitField0_ |= 0x00000008; + osdUuid_ = other.osdUuid_; + onChanged(); + } + if (other.hasStripeSize()) { + setStripeSize(other.getStripeSize()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFilePath()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasFileSize()) { + + return false; + } + if (!hasOsdUuid()) { + + return false; + } + if (!hasStripeSize()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_restore_fileRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string file_path = 1; + private java.lang.Object filePath_ = ""; + /** + * required string file_path = 1; + * + *
    +       * the path to the restored file
    +       * 
    + */ + public boolean hasFilePath() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string file_path = 1; + * + *
    +       * the path to the restored file
    +       * 
    + */ + public java.lang.String getFilePath() { + java.lang.Object ref = filePath_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + filePath_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_path = 1; + * + *
    +       * the path to the restored file
    +       * 
    + */ + public com.google.protobuf.ByteString + getFilePathBytes() { + java.lang.Object ref = filePath_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + filePath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_path = 1; + * + *
    +       * the path to the restored file
    +       * 
    + */ + public Builder setFilePath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + filePath_ = value; + onChanged(); + return this; + } + /** + * required string file_path = 1; + * + *
    +       * the path to the restored file
    +       * 
    + */ + public Builder clearFilePath() { + bitField0_ = (bitField0_ & ~0x00000001); + filePath_ = getDefaultInstance().getFilePath(); + onChanged(); + return this; + } + /** + * required string file_path = 1; + * + *
    +       * the path to the restored file
    +       * 
    + */ + public Builder setFilePathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + filePath_ = value; + onChanged(); + return this; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + * + *
    +       * the file ID
    +       * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + * + *
    +       * the file ID
    +       * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + * + *
    +       * the file ID
    +       * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 file_size = 3; + private long fileSize_ ; + /** + * required fixed64 file_size = 3; + * + *
    +       * the file size
    +       * 
    + */ + public boolean hasFileSize() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 file_size = 3; + * + *
    +       * the file size
    +       * 
    + */ + public long getFileSize() { + return fileSize_; + } + /** + * required fixed64 file_size = 3; + * + *
    +       * the file size
    +       * 
    + */ + public Builder setFileSize(long value) { + bitField0_ |= 0x00000004; + fileSize_ = value; + onChanged(); + return this; + } + /** + * required fixed64 file_size = 3; + * + *
    +       * the file size
    +       * 
    + */ + public Builder clearFileSize() { + bitField0_ = (bitField0_ & ~0x00000004); + fileSize_ = 0L; + onChanged(); + return this; + } + + // required string osd_uuid = 4; + private java.lang.Object osdUuid_ = ""; + /** + * required string osd_uuid = 4; + * + *
    +       * the UUID of the OSD with the orphaned file content
    +       * 
    + */ + public boolean hasOsdUuid() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required string osd_uuid = 4; + * + *
    +       * the UUID of the OSD with the orphaned file content
    +       * 
    + */ + public java.lang.String getOsdUuid() { + java.lang.Object ref = osdUuid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + osdUuid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string osd_uuid = 4; + * + *
    +       * the UUID of the OSD with the orphaned file content
    +       * 
    + */ + public com.google.protobuf.ByteString + getOsdUuidBytes() { + java.lang.Object ref = osdUuid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + osdUuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string osd_uuid = 4; + * + *
    +       * the UUID of the OSD with the orphaned file content
    +       * 
    + */ + public Builder setOsdUuid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + osdUuid_ = value; + onChanged(); + return this; + } + /** + * required string osd_uuid = 4; + * + *
    +       * the UUID of the OSD with the orphaned file content
    +       * 
    + */ + public Builder clearOsdUuid() { + bitField0_ = (bitField0_ & ~0x00000008); + osdUuid_ = getDefaultInstance().getOsdUuid(); + onChanged(); + return this; + } + /** + * required string osd_uuid = 4; + * + *
    +       * the UUID of the OSD with the orphaned file content
    +       * 
    + */ + public Builder setOsdUuidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + osdUuid_ = value; + onChanged(); + return this; + } + + // required fixed32 stripe_size = 5; + private int stripeSize_ ; + /** + * required fixed32 stripe_size = 5; + * + *
    +       * the stripe size of the file
    +       * 
    + */ + public boolean hasStripeSize() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 stripe_size = 5; + * + *
    +       * the stripe size of the file
    +       * 
    + */ + public int getStripeSize() { + return stripeSize_; + } + /** + * required fixed32 stripe_size = 5; + * + *
    +       * the stripe size of the file
    +       * 
    + */ + public Builder setStripeSize(int value) { + bitField0_ |= 0x00000010; + stripeSize_ = value; + onChanged(); + return this; + } + /** + * required fixed32 stripe_size = 5; + * + *
    +       * the stripe size of the file
    +       * 
    + */ + public Builder clearStripeSize() { + bitField0_ = (bitField0_ & ~0x00000010); + stripeSize_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_restore_fileRequest) + } + + static { + defaultInstance = new xtreemfs_restore_fileRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_restore_fileRequest) + } + + public interface xtreemfs_rmvolRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string volume_name = 1; + /** + * required string volume_name = 1; + * + *
    +     * the name of the volume to delete
    +     * 
    + */ + boolean hasVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the name of the volume to delete
    +     * 
    + */ + java.lang.String getVolumeName(); + /** + * required string volume_name = 1; + * + *
    +     * the name of the volume to delete
    +     * 
    + */ + com.google.protobuf.ByteString + getVolumeNameBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rmvolRequest} + * + *
    +   * deletes a volume
    +   * 
    + */ + public static final class xtreemfs_rmvolRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_rmvolRequestOrBuilder { + // Use xtreemfs_rmvolRequest.newBuilder() to construct. + private xtreemfs_rmvolRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_rmvolRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_rmvolRequest defaultInstance; + public static xtreemfs_rmvolRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_rmvolRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_rmvolRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + volumeName_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_rmvolRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_rmvolRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_rmvolRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_rmvolRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string volume_name = 1; + public static final int VOLUME_NAME_FIELD_NUMBER = 1; + private java.lang.Object volumeName_; + /** + * required string volume_name = 1; + * + *
    +     * the name of the volume to delete
    +     * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +     * the name of the volume to delete
    +     * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + volumeName_ = s; + } + return s; + } + } + /** + * required string volume_name = 1; + * + *
    +     * the name of the volume to delete
    +     * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + volumeName_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVolumeName()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getVolumeNameBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getVolumeNameBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rmvolRequest} + * + *
    +     * deletes a volume
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_rmvolRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_rmvolRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + volumeName_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_rmvolRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.volumeName_ = volumeName_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest.getDefaultInstance()) return this; + if (other.hasVolumeName()) { + bitField0_ |= 0x00000001; + volumeName_ = other.volumeName_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVolumeName()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_rmvolRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string volume_name = 1; + private java.lang.Object volumeName_ = ""; + /** + * required string volume_name = 1; + * + *
    +       * the name of the volume to delete
    +       * 
    + */ + public boolean hasVolumeName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string volume_name = 1; + * + *
    +       * the name of the volume to delete
    +       * 
    + */ + public java.lang.String getVolumeName() { + java.lang.Object ref = volumeName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + volumeName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the name of the volume to delete
    +       * 
    + */ + public com.google.protobuf.ByteString + getVolumeNameBytes() { + java.lang.Object ref = volumeName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + volumeName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string volume_name = 1; + * + *
    +       * the name of the volume to delete
    +       * 
    + */ + public Builder setVolumeName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the name of the volume to delete
    +       * 
    + */ + public Builder clearVolumeName() { + bitField0_ = (bitField0_ & ~0x00000001); + volumeName_ = getDefaultInstance().getVolumeName(); + onChanged(); + return this; + } + /** + * required string volume_name = 1; + * + *
    +       * the name of the volume to delete
    +       * 
    + */ + public Builder setVolumeNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + volumeName_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_rmvolRequest) + } + + static { + defaultInstance = new xtreemfs_rmvolRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rmvolRequest) + } + + public interface xtreemfs_update_file_sizeRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.XCap xcap = 1; + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +     * the capability that was returned when opening the file
    +     * 
    + */ + boolean hasXcap(); + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +     * the capability that was returned when opening the file
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getXcap(); + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +     * the capability that was returned when opening the file
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getXcapOrBuilder(); + + // required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +     * the OSDWriteResponse received from an OSD that contains the new file size
    +     * 
    + */ + boolean hasOsdWriteResponse(); + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +     * the OSDWriteResponse received from an OSD that contains the new file size
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse getOsdWriteResponse(); + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +     * the OSDWriteResponse received from an OSD that contains the new file size
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponseOrBuilder getOsdWriteResponseOrBuilder(); + + // optional bool close_file = 3; + /** + * optional bool close_file = 3; + * + *
    +     * a flag indicating that the file is supposed to be closed
    +     * 
    + */ + boolean hasCloseFile(); + /** + * optional bool close_file = 3; + * + *
    +     * a flag indicating that the file is supposed to be closed
    +     * 
    + */ + boolean getCloseFile(); + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +     * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +     * specific locations when the file is closed)
    +     * 
    + */ + boolean hasCoordinates(); + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +     * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +     * specific locations when the file is closed)
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates getCoordinates(); + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +     * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +     * specific locations when the file is closed)
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder getCoordinatesOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_update_file_sizeRequest} + * + *
    +   * updates the size of an open file
    +   * 
    + */ + public static final class xtreemfs_update_file_sizeRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_update_file_sizeRequestOrBuilder { + // Use xtreemfs_update_file_sizeRequest.newBuilder() to construct. + private xtreemfs_update_file_sizeRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_update_file_sizeRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_update_file_sizeRequest defaultInstance; + public static xtreemfs_update_file_sizeRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_update_file_sizeRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_update_file_sizeRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = xcap_.toBuilder(); + } + xcap_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(xcap_); + xcap_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = osdWriteResponse_.toBuilder(); + } + osdWriteResponse_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(osdWriteResponse_); + osdWriteResponse_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + case 24: { + bitField0_ |= 0x00000004; + closeFile_ = input.readBool(); + break; + } + case 34: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder subBuilder = null; + if (((bitField0_ & 0x00000008) == 0x00000008)) { + subBuilder = coordinates_.toBuilder(); + } + coordinates_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(coordinates_); + coordinates_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000008; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_update_file_sizeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_update_file_sizeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_update_file_sizeRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_update_file_sizeRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.XCap xcap = 1; + public static final int XCAP_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap xcap_; + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +     * the capability that was returned when opening the file
    +     * 
    + */ + public boolean hasXcap() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +     * the capability that was returned when opening the file
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getXcap() { + return xcap_; + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +     * the capability that was returned when opening the file
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getXcapOrBuilder() { + return xcap_; + } + + // required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + public static final int OSD_WRITE_RESPONSE_FIELD_NUMBER = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse osdWriteResponse_; + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +     * the OSDWriteResponse received from an OSD that contains the new file size
    +     * 
    + */ + public boolean hasOsdWriteResponse() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +     * the OSDWriteResponse received from an OSD that contains the new file size
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse getOsdWriteResponse() { + return osdWriteResponse_; + } + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +     * the OSDWriteResponse received from an OSD that contains the new file size
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponseOrBuilder getOsdWriteResponseOrBuilder() { + return osdWriteResponse_; + } + + // optional bool close_file = 3; + public static final int CLOSE_FILE_FIELD_NUMBER = 3; + private boolean closeFile_; + /** + * optional bool close_file = 3; + * + *
    +     * a flag indicating that the file is supposed to be closed
    +     * 
    + */ + public boolean hasCloseFile() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional bool close_file = 3; + * + *
    +     * a flag indicating that the file is supposed to be closed
    +     * 
    + */ + public boolean getCloseFile() { + return closeFile_; + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + public static final int COORDINATES_FIELD_NUMBER = 4; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates coordinates_; + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +     * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +     * specific locations when the file is closed)
    +     * 
    + */ + public boolean hasCoordinates() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +     * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +     * specific locations when the file is closed)
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates getCoordinates() { + return coordinates_; + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +     * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +     * specific locations when the file is closed)
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder getCoordinatesOrBuilder() { + return coordinates_; + } + + private void initFields() { + xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + osdWriteResponse_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.getDefaultInstance(); + closeFile_ = false; + coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasXcap()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOsdWriteResponse()) { + memoizedIsInitialized = 0; + return false; + } + if (!getXcap().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (hasCoordinates()) { + if (!getCoordinates().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, xcap_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, osdWriteResponse_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBool(3, closeFile_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeMessage(4, coordinates_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, xcap_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, osdWriteResponse_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(3, closeFile_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, coordinates_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_update_file_sizeRequest} + * + *
    +     * updates the size of an open file
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_update_file_sizeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_update_file_sizeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getXcapFieldBuilder(); + getOsdWriteResponseFieldBuilder(); + getCoordinatesFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (xcapBuilder_ == null) { + xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + } else { + xcapBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (osdWriteResponseBuilder_ == null) { + osdWriteResponse_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.getDefaultInstance(); + } else { + osdWriteResponseBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + closeFile_ = false; + bitField0_ = (bitField0_ & ~0x00000004); + if (coordinatesBuilder_ == null) { + coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + } else { + coordinatesBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_update_file_sizeRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (xcapBuilder_ == null) { + result.xcap_ = xcap_; + } else { + result.xcap_ = xcapBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + if (osdWriteResponseBuilder_ == null) { + result.osdWriteResponse_ = osdWriteResponse_; + } else { + result.osdWriteResponse_ = osdWriteResponseBuilder_.build(); + } + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.closeFile_ = closeFile_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + if (coordinatesBuilder_ == null) { + result.coordinates_ = coordinates_; + } else { + result.coordinates_ = coordinatesBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest.getDefaultInstance()) return this; + if (other.hasXcap()) { + mergeXcap(other.getXcap()); + } + if (other.hasOsdWriteResponse()) { + mergeOsdWriteResponse(other.getOsdWriteResponse()); + } + if (other.hasCloseFile()) { + setCloseFile(other.getCloseFile()); + } + if (other.hasCoordinates()) { + mergeCoordinates(other.getCoordinates()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasXcap()) { + + return false; + } + if (!hasOsdWriteResponse()) { + + return false; + } + if (!getXcap().isInitialized()) { + + return false; + } + if (hasCoordinates()) { + if (!getCoordinates().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.XCap xcap = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder> xcapBuilder_; + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +       * the capability that was returned when opening the file
    +       * 
    + */ + public boolean hasXcap() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +       * the capability that was returned when opening the file
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap getXcap() { + if (xcapBuilder_ == null) { + return xcap_; + } else { + return xcapBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +       * the capability that was returned when opening the file
    +       * 
    + */ + public Builder setXcap(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap value) { + if (xcapBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + xcap_ = value; + onChanged(); + } else { + xcapBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +       * the capability that was returned when opening the file
    +       * 
    + */ + public Builder setXcap( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder builderForValue) { + if (xcapBuilder_ == null) { + xcap_ = builderForValue.build(); + onChanged(); + } else { + xcapBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +       * the capability that was returned when opening the file
    +       * 
    + */ + public Builder mergeXcap(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap value) { + if (xcapBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + xcap_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance()) { + xcap_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.newBuilder(xcap_).mergeFrom(value).buildPartial(); + } else { + xcap_ = value; + } + onChanged(); + } else { + xcapBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +       * the capability that was returned when opening the file
    +       * 
    + */ + public Builder clearXcap() { + if (xcapBuilder_ == null) { + xcap_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.getDefaultInstance(); + onChanged(); + } else { + xcapBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +       * the capability that was returned when opening the file
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder getXcapBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getXcapFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +       * the capability that was returned when opening the file
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder getXcapOrBuilder() { + if (xcapBuilder_ != null) { + return xcapBuilder_.getMessageOrBuilder(); + } else { + return xcap_; + } + } + /** + * required .xtreemfs.pbrpc.XCap xcap = 1; + * + *
    +       * the capability that was returned when opening the file
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder> + getXcapFieldBuilder() { + if (xcapBuilder_ == null) { + xcapBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCapOrBuilder>( + xcap_, + getParentForChildren(), + isClean()); + xcap_ = null; + } + return xcapBuilder_; + } + + // required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse osdWriteResponse_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponseOrBuilder> osdWriteResponseBuilder_; + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +       * the OSDWriteResponse received from an OSD that contains the new file size
    +       * 
    + */ + public boolean hasOsdWriteResponse() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +       * the OSDWriteResponse received from an OSD that contains the new file size
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse getOsdWriteResponse() { + if (osdWriteResponseBuilder_ == null) { + return osdWriteResponse_; + } else { + return osdWriteResponseBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +       * the OSDWriteResponse received from an OSD that contains the new file size
    +       * 
    + */ + public Builder setOsdWriteResponse(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse value) { + if (osdWriteResponseBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + osdWriteResponse_ = value; + onChanged(); + } else { + osdWriteResponseBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +       * the OSDWriteResponse received from an OSD that contains the new file size
    +       * 
    + */ + public Builder setOsdWriteResponse( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.Builder builderForValue) { + if (osdWriteResponseBuilder_ == null) { + osdWriteResponse_ = builderForValue.build(); + onChanged(); + } else { + osdWriteResponseBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +       * the OSDWriteResponse received from an OSD that contains the new file size
    +       * 
    + */ + public Builder mergeOsdWriteResponse(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse value) { + if (osdWriteResponseBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + osdWriteResponse_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.getDefaultInstance()) { + osdWriteResponse_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.newBuilder(osdWriteResponse_).mergeFrom(value).buildPartial(); + } else { + osdWriteResponse_ = value; + } + onChanged(); + } else { + osdWriteResponseBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +       * the OSDWriteResponse received from an OSD that contains the new file size
    +       * 
    + */ + public Builder clearOsdWriteResponse() { + if (osdWriteResponseBuilder_ == null) { + osdWriteResponse_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.getDefaultInstance(); + onChanged(); + } else { + osdWriteResponseBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +       * the OSDWriteResponse received from an OSD that contains the new file size
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.Builder getOsdWriteResponseBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getOsdWriteResponseFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +       * the OSDWriteResponse received from an OSD that contains the new file size
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponseOrBuilder getOsdWriteResponseOrBuilder() { + if (osdWriteResponseBuilder_ != null) { + return osdWriteResponseBuilder_.getMessageOrBuilder(); + } else { + return osdWriteResponse_; + } + } + /** + * required .xtreemfs.pbrpc.OSDWriteResponse osd_write_response = 2; + * + *
    +       * the OSDWriteResponse received from an OSD that contains the new file size
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponseOrBuilder> + getOsdWriteResponseFieldBuilder() { + if (osdWriteResponseBuilder_ == null) { + osdWriteResponseBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponseOrBuilder>( + osdWriteResponse_, + getParentForChildren(), + isClean()); + osdWriteResponse_ = null; + } + return osdWriteResponseBuilder_; + } + + // optional bool close_file = 3; + private boolean closeFile_ ; + /** + * optional bool close_file = 3; + * + *
    +       * a flag indicating that the file is supposed to be closed
    +       * 
    + */ + public boolean hasCloseFile() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional bool close_file = 3; + * + *
    +       * a flag indicating that the file is supposed to be closed
    +       * 
    + */ + public boolean getCloseFile() { + return closeFile_; + } + /** + * optional bool close_file = 3; + * + *
    +       * a flag indicating that the file is supposed to be closed
    +       * 
    + */ + public Builder setCloseFile(boolean value) { + bitField0_ |= 0x00000004; + closeFile_ = value; + onChanged(); + return this; + } + /** + * optional bool close_file = 3; + * + *
    +       * a flag indicating that the file is supposed to be closed
    +       * 
    + */ + public Builder clearCloseFile() { + bitField0_ = (bitField0_ & ~0x00000004); + closeFile_ = false; + onChanged(); + return this; + } + + // optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder> coordinatesBuilder_; + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +       * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +       * specific locations when the file is closed)
    +       * 
    + */ + public boolean hasCoordinates() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +       * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +       * specific locations when the file is closed)
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates getCoordinates() { + if (coordinatesBuilder_ == null) { + return coordinates_; + } else { + return coordinatesBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +       * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +       * specific locations when the file is closed)
    +       * 
    + */ + public Builder setCoordinates(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates value) { + if (coordinatesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + coordinates_ = value; + onChanged(); + } else { + coordinatesBuilder_.setMessage(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +       * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +       * specific locations when the file is closed)
    +       * 
    + */ + public Builder setCoordinates( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder builderForValue) { + if (coordinatesBuilder_ == null) { + coordinates_ = builderForValue.build(); + onChanged(); + } else { + coordinatesBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +       * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +       * specific locations when the file is closed)
    +       * 
    + */ + public Builder mergeCoordinates(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates value) { + if (coordinatesBuilder_ == null) { + if (((bitField0_ & 0x00000008) == 0x00000008) && + coordinates_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance()) { + coordinates_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.newBuilder(coordinates_).mergeFrom(value).buildPartial(); + } else { + coordinates_ = value; + } + onChanged(); + } else { + coordinatesBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +       * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +       * specific locations when the file is closed)
    +       * 
    + */ + public Builder clearCoordinates() { + if (coordinatesBuilder_ == null) { + coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + onChanged(); + } else { + coordinatesBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +       * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +       * specific locations when the file is closed)
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder getCoordinatesBuilder() { + bitField0_ |= 0x00000008; + onChanged(); + return getCoordinatesFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +       * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +       * specific locations when the file is closed)
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder getCoordinatesOrBuilder() { + if (coordinatesBuilder_ != null) { + return coordinatesBuilder_.getMessageOrBuilder(); + } else { + return coordinates_; + } + } + /** + * optional .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 4; + * + *
    +       * the client's Vivaldi coordinates (e.g. used for creating replicas at
    +       * specific locations when the file is closed)
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder> + getCoordinatesFieldBuilder() { + if (coordinatesBuilder_ == null) { + coordinatesBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder>( + coordinates_, + getParentForChildren(), + isClean()); + coordinates_ = null; + } + return coordinatesBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_update_file_sizeRequest) + } + + static { + defaultInstance = new xtreemfs_update_file_sizeRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_update_file_sizeRequest) + } + + public interface xtreemfs_set_replica_update_policyRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string file_id = 1; + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + boolean hasFileId(); + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + java.lang.String getFileId(); + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required string update_policy = 2; + /** + * required string update_policy = 2; + * + *
    +     * the new replica update policy
    +     * 
    + */ + boolean hasUpdatePolicy(); + /** + * required string update_policy = 2; + * + *
    +     * the new replica update policy
    +     * 
    + */ + java.lang.String getUpdatePolicy(); + /** + * required string update_policy = 2; + * + *
    +     * the new replica update policy
    +     * 
    + */ + com.google.protobuf.ByteString + getUpdatePolicyBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_set_replica_update_policyRequest} + * + *
    +   * sets the replica update policy of a file by ID
    +   * 
    + */ + public static final class xtreemfs_set_replica_update_policyRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_set_replica_update_policyRequestOrBuilder { + // Use xtreemfs_set_replica_update_policyRequest.newBuilder() to construct. + private xtreemfs_set_replica_update_policyRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_set_replica_update_policyRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_set_replica_update_policyRequest defaultInstance; + public static xtreemfs_set_replica_update_policyRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_set_replica_update_policyRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_set_replica_update_policyRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + fileId_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + updatePolicy_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_set_replica_update_policyRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_set_replica_update_policyRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string file_id = 1; + public static final int FILE_ID_FIELD_NUMBER = 1; + private java.lang.Object fileId_; + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required string update_policy = 2; + public static final int UPDATE_POLICY_FIELD_NUMBER = 2; + private java.lang.Object updatePolicy_; + /** + * required string update_policy = 2; + * + *
    +     * the new replica update policy
    +     * 
    + */ + public boolean hasUpdatePolicy() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string update_policy = 2; + * + *
    +     * the new replica update policy
    +     * 
    + */ + public java.lang.String getUpdatePolicy() { + java.lang.Object ref = updatePolicy_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + updatePolicy_ = s; + } + return s; + } + } + /** + * required string update_policy = 2; + * + *
    +     * the new replica update policy
    +     * 
    + */ + public com.google.protobuf.ByteString + getUpdatePolicyBytes() { + java.lang.Object ref = updatePolicy_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + updatePolicy_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + fileId_ = ""; + updatePolicy_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasUpdatePolicy()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getUpdatePolicyBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getUpdatePolicyBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_set_replica_update_policyRequest} + * + *
    +     * sets the replica update policy of a file by ID
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + updatePolicy_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.updatePolicy_ = updatePolicy_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest.getDefaultInstance()) return this; + if (other.hasFileId()) { + bitField0_ |= 0x00000001; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasUpdatePolicy()) { + bitField0_ |= 0x00000002; + updatePolicy_ = other.updatePolicy_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileId()) { + + return false; + } + if (!hasUpdatePolicy()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string file_id = 1; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + + // required string update_policy = 2; + private java.lang.Object updatePolicy_ = ""; + /** + * required string update_policy = 2; + * + *
    +       * the new replica update policy
    +       * 
    + */ + public boolean hasUpdatePolicy() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string update_policy = 2; + * + *
    +       * the new replica update policy
    +       * 
    + */ + public java.lang.String getUpdatePolicy() { + java.lang.Object ref = updatePolicy_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + updatePolicy_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string update_policy = 2; + * + *
    +       * the new replica update policy
    +       * 
    + */ + public com.google.protobuf.ByteString + getUpdatePolicyBytes() { + java.lang.Object ref = updatePolicy_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + updatePolicy_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string update_policy = 2; + * + *
    +       * the new replica update policy
    +       * 
    + */ + public Builder setUpdatePolicy( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + updatePolicy_ = value; + onChanged(); + return this; + } + /** + * required string update_policy = 2; + * + *
    +       * the new replica update policy
    +       * 
    + */ + public Builder clearUpdatePolicy() { + bitField0_ = (bitField0_ & ~0x00000002); + updatePolicy_ = getDefaultInstance().getUpdatePolicy(); + onChanged(); + return this; + } + /** + * required string update_policy = 2; + * + *
    +       * the new replica update policy
    +       * 
    + */ + public Builder setUpdatePolicyBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + updatePolicy_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_set_replica_update_policyRequest) + } + + static { + defaultInstance = new xtreemfs_set_replica_update_policyRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_set_replica_update_policyRequest) + } + + public interface xtreemfs_set_replica_update_policyResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string old_update_policy = 1; + /** + * required string old_update_policy = 1; + * + *
    +     * the old replica update policy
    +     * 
    + */ + boolean hasOldUpdatePolicy(); + /** + * required string old_update_policy = 1; + * + *
    +     * the old replica update policy
    +     * 
    + */ + java.lang.String getOldUpdatePolicy(); + /** + * required string old_update_policy = 1; + * + *
    +     * the old replica update policy
    +     * 
    + */ + com.google.protobuf.ByteString + getOldUpdatePolicyBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_set_replica_update_policyResponse} + * + *
    +   * returns the old replica update policy when setting a new one
    +   * 
    + */ + public static final class xtreemfs_set_replica_update_policyResponse extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_set_replica_update_policyResponseOrBuilder { + // Use xtreemfs_set_replica_update_policyResponse.newBuilder() to construct. + private xtreemfs_set_replica_update_policyResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_set_replica_update_policyResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_set_replica_update_policyResponse defaultInstance; + public static xtreemfs_set_replica_update_policyResponse getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_set_replica_update_policyResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_set_replica_update_policyResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + oldUpdatePolicy_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_set_replica_update_policyResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_set_replica_update_policyResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string old_update_policy = 1; + public static final int OLD_UPDATE_POLICY_FIELD_NUMBER = 1; + private java.lang.Object oldUpdatePolicy_; + /** + * required string old_update_policy = 1; + * + *
    +     * the old replica update policy
    +     * 
    + */ + public boolean hasOldUpdatePolicy() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string old_update_policy = 1; + * + *
    +     * the old replica update policy
    +     * 
    + */ + public java.lang.String getOldUpdatePolicy() { + java.lang.Object ref = oldUpdatePolicy_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + oldUpdatePolicy_ = s; + } + return s; + } + } + /** + * required string old_update_policy = 1; + * + *
    +     * the old replica update policy
    +     * 
    + */ + public com.google.protobuf.ByteString + getOldUpdatePolicyBytes() { + java.lang.Object ref = oldUpdatePolicy_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + oldUpdatePolicy_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + oldUpdatePolicy_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasOldUpdatePolicy()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getOldUpdatePolicyBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getOldUpdatePolicyBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_set_replica_update_policyResponse} + * + *
    +     * returns the old replica update policy when setting a new one
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + oldUpdatePolicy_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.oldUpdatePolicy_ = oldUpdatePolicy_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse.getDefaultInstance()) return this; + if (other.hasOldUpdatePolicy()) { + bitField0_ |= 0x00000001; + oldUpdatePolicy_ = other.oldUpdatePolicy_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasOldUpdatePolicy()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_replica_update_policyResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string old_update_policy = 1; + private java.lang.Object oldUpdatePolicy_ = ""; + /** + * required string old_update_policy = 1; + * + *
    +       * the old replica update policy
    +       * 
    + */ + public boolean hasOldUpdatePolicy() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string old_update_policy = 1; + * + *
    +       * the old replica update policy
    +       * 
    + */ + public java.lang.String getOldUpdatePolicy() { + java.lang.Object ref = oldUpdatePolicy_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + oldUpdatePolicy_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string old_update_policy = 1; + * + *
    +       * the old replica update policy
    +       * 
    + */ + public com.google.protobuf.ByteString + getOldUpdatePolicyBytes() { + java.lang.Object ref = oldUpdatePolicy_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + oldUpdatePolicy_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string old_update_policy = 1; + * + *
    +       * the old replica update policy
    +       * 
    + */ + public Builder setOldUpdatePolicy( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + oldUpdatePolicy_ = value; + onChanged(); + return this; + } + /** + * required string old_update_policy = 1; + * + *
    +       * the old replica update policy
    +       * 
    + */ + public Builder clearOldUpdatePolicy() { + bitField0_ = (bitField0_ & ~0x00000001); + oldUpdatePolicy_ = getDefaultInstance().getOldUpdatePolicy(); + onChanged(); + return this; + } + /** + * required string old_update_policy = 1; + * + *
    +       * the old replica update policy
    +       * 
    + */ + public Builder setOldUpdatePolicyBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + oldUpdatePolicy_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_set_replica_update_policyResponse) + } + + static { + defaultInstance = new xtreemfs_set_replica_update_policyResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_set_replica_update_policyResponse) + } + + public interface xtreemfs_set_read_only_xattrRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string file_id = 1; + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + boolean hasFileId(); + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + java.lang.String getFileId(); + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required bool value = 2; + /** + * required bool value = 2; + * + *
    +     * the read-only flag to set
    +     * 
    + */ + boolean hasValue(); + /** + * required bool value = 2; + * + *
    +     * the read-only flag to set
    +     * 
    + */ + boolean getValue(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_set_read_only_xattrRequest} + * + *
    +   * sets the read-only flag of a file by ID
    +   * 
    + */ + public static final class xtreemfs_set_read_only_xattrRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_set_read_only_xattrRequestOrBuilder { + // Use xtreemfs_set_read_only_xattrRequest.newBuilder() to construct. + private xtreemfs_set_read_only_xattrRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_set_read_only_xattrRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_set_read_only_xattrRequest defaultInstance; + public static xtreemfs_set_read_only_xattrRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_set_read_only_xattrRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_set_read_only_xattrRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + fileId_ = input.readBytes(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + value_ = input.readBool(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_set_read_only_xattrRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_set_read_only_xattrRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string file_id = 1; + public static final int FILE_ID_FIELD_NUMBER = 1; + private java.lang.Object fileId_; + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 1; + * + *
    +     * the file ID
    +     * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required bool value = 2; + public static final int VALUE_FIELD_NUMBER = 2; + private boolean value_; + /** + * required bool value = 2; + * + *
    +     * the read-only flag to set
    +     * 
    + */ + public boolean hasValue() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool value = 2; + * + *
    +     * the read-only flag to set
    +     * 
    + */ + public boolean getValue() { + return value_; + } + + private void initFields() { + fileId_ = ""; + value_ = false; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasValue()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBool(2, value_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(2, value_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_set_read_only_xattrRequest} + * + *
    +     * sets the read-only flag of a file by ID
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + value_ = false; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.value_ = value_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest.getDefaultInstance()) return this; + if (other.hasFileId()) { + bitField0_ |= 0x00000001; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasValue()) { + setValue(other.getValue()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileId()) { + + return false; + } + if (!hasValue()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string file_id = 1; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 1; + * + *
    +       * the file ID
    +       * 
    + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + + // required bool value = 2; + private boolean value_ ; + /** + * required bool value = 2; + * + *
    +       * the read-only flag to set
    +       * 
    + */ + public boolean hasValue() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool value = 2; + * + *
    +       * the read-only flag to set
    +       * 
    + */ + public boolean getValue() { + return value_; + } + /** + * required bool value = 2; + * + *
    +       * the read-only flag to set
    +       * 
    + */ + public Builder setValue(boolean value) { + bitField0_ |= 0x00000002; + value_ = value; + onChanged(); + return this; + } + /** + * required bool value = 2; + * + *
    +       * the read-only flag to set
    +       * 
    + */ + public Builder clearValue() { + bitField0_ = (bitField0_ & ~0x00000002); + value_ = false; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_set_read_only_xattrRequest) + } + + static { + defaultInstance = new xtreemfs_set_read_only_xattrRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_set_read_only_xattrRequest) + } + + public interface xtreemfs_set_read_only_xattrResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required bool was_set = 1; + /** + * required bool was_set = 1; + */ + boolean hasWasSet(); + /** + * required bool was_set = 1; + */ + boolean getWasSet(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_set_read_only_xattrResponse} + */ + public static final class xtreemfs_set_read_only_xattrResponse extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_set_read_only_xattrResponseOrBuilder { + // Use xtreemfs_set_read_only_xattrResponse.newBuilder() to construct. + private xtreemfs_set_read_only_xattrResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_set_read_only_xattrResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_set_read_only_xattrResponse defaultInstance; + public static xtreemfs_set_read_only_xattrResponse getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_set_read_only_xattrResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_set_read_only_xattrResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + bitField0_ |= 0x00000001; + wasSet_ = input.readBool(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_set_read_only_xattrResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_set_read_only_xattrResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required bool was_set = 1; + public static final int WAS_SET_FIELD_NUMBER = 1; + private boolean wasSet_; + /** + * required bool was_set = 1; + */ + public boolean hasWasSet() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required bool was_set = 1; + */ + public boolean getWasSet() { + return wasSet_; + } + + private void initFields() { + wasSet_ = false; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasWasSet()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBool(1, wasSet_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(1, wasSet_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_set_read_only_xattrResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + wasSet_ = false; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.wasSet_ = wasSet_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse.getDefaultInstance()) return this; + if (other.hasWasSet()) { + setWasSet(other.getWasSet()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasWasSet()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required bool was_set = 1; + private boolean wasSet_ ; + /** + * required bool was_set = 1; + */ + public boolean hasWasSet() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required bool was_set = 1; + */ + public boolean getWasSet() { + return wasSet_; + } + /** + * required bool was_set = 1; + */ + public Builder setWasSet(boolean value) { + bitField0_ |= 0x00000001; + wasSet_ = value; + onChanged(); + return this; + } + /** + * required bool was_set = 1; + */ + public Builder clearWasSet() { + bitField0_ = (bitField0_ & ~0x00000001); + wasSet_ = false; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_set_read_only_xattrResponse) + } + + static { + defaultInstance = new xtreemfs_set_read_only_xattrResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_set_read_only_xattrResponse) + } + + public interface xtreemfs_get_file_credentialsRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string file_id = 1; + /** + * required string file_id = 1; + */ + boolean hasFileId(); + /** + * required string file_id = 1; + */ + java.lang.String getFileId(); + /** + * required string file_id = 1; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_get_file_credentialsRequest} + */ + public static final class xtreemfs_get_file_credentialsRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_get_file_credentialsRequestOrBuilder { + // Use xtreemfs_get_file_credentialsRequest.newBuilder() to construct. + private xtreemfs_get_file_credentialsRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_get_file_credentialsRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_get_file_credentialsRequest defaultInstance; + public static xtreemfs_get_file_credentialsRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_get_file_credentialsRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_get_file_credentialsRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + fileId_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_file_credentialsRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_file_credentialsRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_get_file_credentialsRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_get_file_credentialsRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string file_id = 1; + public static final int FILE_ID_FIELD_NUMBER = 1; + private java.lang.Object fileId_; + /** + * required string file_id = 1; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string file_id = 1; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 1; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + fileId_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getFileIdBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getFileIdBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_get_file_credentialsRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_file_credentialsRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_file_credentialsRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.internal_static_xtreemfs_pbrpc_xtreemfs_get_file_credentialsRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.fileId_ = fileId_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest.getDefaultInstance()) return this; + if (other.hasFileId()) { + bitField0_ |= 0x00000001; + fileId_ = other.fileId_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileId()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_get_file_credentialsRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string file_id = 1; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 1; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string file_id = 1; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 1; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 1; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 1; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 1; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_get_file_credentialsRequest) + } + + static { + defaultInstance = new xtreemfs_get_file_credentialsRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_get_file_credentialsRequest) + } + + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_Stat_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_Stat_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_DirectoryEntry_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_DirectoryEntry_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_DirectoryEntries_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_DirectoryEntries_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_XAttr_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_XAttr_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_Volume_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_Volume_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_Volumes_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_Volumes_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_StatVFS_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_StatVFS_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_fsetattrRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_fsetattrRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_getattrRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_getattrRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_getattrResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_getattrResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_getxattrRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_getxattrRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_getxattrResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_getxattrResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_linkRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_linkRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_listxattrRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_listxattrRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_listxattrResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_listxattrResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_mkdirRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_mkdirRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_openRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_openRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_openResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_openResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_readdirRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_readdirRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_readlinkRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_readlinkRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_readlinkResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_readlinkResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_removexattrRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_removexattrRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_renameRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_renameRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_renameResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_renameResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_rmdirRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_rmdirRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_setattrRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_setattrRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_setxattrRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_setxattrRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_statvfsRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_statvfsRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_symlinkRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_symlinkRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_unlinkRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_unlinkRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_unlinkResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_unlinkResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_accessRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_accessRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_dump_restore_databaseRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_dump_restore_databaseRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_timestampResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_timestampResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_stringMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_stringMessage_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_listdirRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_listdirRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_listdirResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_listdirResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_replica_addRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_replica_addRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_replica_listRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_replica_listRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_get_xlocsetRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_get_xlocsetRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_replica_removeRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_replica_removeRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_restore_fileRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_restore_fileRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_rmvolRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_rmvolRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_update_file_sizeRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_update_file_sizeRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_get_file_credentialsRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_get_file_credentialsRequest_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\022xtreemfs/MRC.proto\022\016xtreemfs.pbrpc\032\023in" + + "clude/PBRPC.proto\032\024include/Common.proto\032" + + "\032xtreemfs/GlobalTypes.proto\"\357\001\n\004Stat\022\013\n\003" + + "dev\030\001 \002(\006\022\013\n\003ino\030\002 \002(\006\022\014\n\004mode\030\003 \002(\007\022\r\n\005" + + "nlink\030\004 \002(\007\022\017\n\007user_id\030\005 \002(\t\022\020\n\010group_id" + + "\030\006 \002(\t\022\014\n\004size\030\007 \002(\006\022\020\n\010atime_ns\030\010 \002(\006\022\020" + + "\n\010mtime_ns\030\t \002(\006\022\020\n\010ctime_ns\030\n \002(\006\022\017\n\007bl" + + "ksize\030\013 \002(\007\022\014\n\004etag\030\014 \001(\006\022\026\n\016truncate_ep" + + "och\030\r \002(\007\022\022\n\nattributes\030\016 \001(\007\"C\n\016Directo" + + "ryEntry\022\014\n\004name\030\001 \002(\t\022#\n\005stbuf\030\002 \001(\0132\024.x", + "treemfs.pbrpc.Stat\"C\n\020DirectoryEntries\022/" + + "\n\007entries\030\001 \003(\0132\036.xtreemfs.pbrpc.Directo" + + "ryEntry\"@\n\005XAttr\022\014\n\004name\030\001 \002(\t\022\r\n\005value\030" + + "\002 \001(\t\022\032\n\022value_bytes_string\030\003 \001(\014\"\244\002\n\006Vo" + + "lume\022F\n\025access_control_policy\030\001 \002(\0162\'.xt" + + "reemfs.pbrpc.AccessControlPolicyType\022?\n\027" + + "default_striping_policy\030\002 \002(\0132\036.xtreemfs" + + ".pbrpc.StripingPolicy\022\n\n\002id\030\003 \002(\t\022\014\n\004mod" + + "e\030\004 \002(\007\022\014\n\004name\030\005 \002(\t\022\026\n\016owner_group_id\030" + + "\006 \002(\t\022\025\n\rowner_user_id\030\007 \002(\t\022+\n\005attrs\030\010 ", + "\003(\0132\034.xtreemfs.pbrpc.KeyValuePair\022\r\n\005quo" + + "ta\030\t \001(\006\"2\n\007Volumes\022\'\n\007volumes\030\001 \003(\0132\026.x" + + "treemfs.pbrpc.Volume\"\310\002\n\007StatVFS\022\r\n\005bsiz" + + "e\030\001 \002(\007\022\016\n\006bavail\030\002 \002(\006\022\r\n\005bfree\030\r \001(\006\022\016" + + "\n\006blocks\030\003 \002(\006\022\014\n\004fsid\030\004 \002(\t\022\017\n\007namemax\030" + + "\005 \002(\007\022F\n\025access_control_policy\030\006 \002(\0162\'.x" + + "treemfs.pbrpc.AccessControlPolicyType\022?\n" + + "\027default_striping_policy\030\007 \002(\0132\036.xtreemf" + + "s.pbrpc.StripingPolicy\022\014\n\004etag\030\010 \002(\006\022\014\n\004" + + "mode\030\t \002(\007\022\014\n\004name\030\n \002(\t\022\026\n\016owner_group_", + "id\030\013 \002(\t\022\025\n\rowner_user_id\030\014 \002(\t\"i\n\017fseta" + + "ttrRequest\022#\n\005stbuf\030\001 \002(\0132\024.xtreemfs.pbr" + + "pc.Stat\022\016\n\006to_set\030\002 \002(\007\022!\n\003cap\030\003 \002(\0132\024.x" + + "treemfs.pbrpc.XCap\"G\n\016getattrRequest\022\023\n\013" + + "volume_name\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\022\022\n\nknown" + + "_etag\030\003 \002(\006\"6\n\017getattrResponse\022#\n\005stbuf\030" + + "\001 \001(\0132\024.xtreemfs.pbrpc.Stat\"B\n\017getxattrR" + + "equest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030\002 \002(" + + "\t\022\014\n\004name\030\003 \002(\t\"=\n\020getxattrResponse\022\r\n\005v" + + "alue\030\001 \002(\t\022\032\n\022value_bytes_string\030\002 \001(\014\"J", + "\n\013linkRequest\022\023\n\013volume_name\030\001 \002(\t\022\023\n\013ta" + + "rget_path\030\002 \002(\t\022\021\n\tlink_path\030\003 \002(\t\"I\n\020li" + + "stxattrRequest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004p" + + "ath\030\002 \002(\t\022\022\n\nnames_only\030\003 \002(\010\":\n\021listxat" + + "trResponse\022%\n\006xattrs\030\001 \003(\0132\025.xtreemfs.pb" + + "rpc.XAttr\"?\n\014mkdirRequest\022\023\n\013volume_name" + + "\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\022\014\n\004mode\030\003 \002(\007\"\232\001\n\013o" + + "penRequest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030" + + "\002 \002(\t\022\r\n\005flags\030\003 \002(\007\022\014\n\004mode\030\004 \002(\007\022\022\n\nat" + + "tributes\030\005 \002(\007\0227\n\013coordinates\030\006 \001(\0132\".xt", + "reemfs.pbrpc.VivaldiCoordinates\"S\n\014openR" + + "esponse\022.\n\005creds\030\001 \002(\0132\037.xtreemfs.pbrpc." + + "FileCredentials\022\023\n\013timestamp_s\030\002 \002(\007\"\250\001\n" + + "\016readdirRequest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004" + + "path\030\002 \002(\t\022\022\n\nknown_etag\030\003 \002(\006\022%\n\035limit_" + + "directory_entries_count\030\004 \002(\007\022\022\n\nnames_o" + + "nly\030\005 \002(\010\022$\n\034seen_directory_entries_coun" + + "t\030\006 \002(\006\"4\n\017readlinkRequest\022\023\n\013volume_nam" + + "e\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\",\n\020readlinkRespons" + + "e\022\030\n\020link_target_path\030\001 \003(\t\"E\n\022removexat", + "trRequest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030\002" + + " \002(\t\022\014\n\004name\030\003 \002(\t\"N\n\rrenameRequest\022\023\n\013v" + + "olume_name\030\001 \002(\t\022\023\n\013source_path\030\002 \002(\t\022\023\n" + + "\013target_path\030\003 \002(\t\"U\n\016renameResponse\022\023\n\013" + + "timestamp_s\030\001 \002(\007\022.\n\005creds\030\002 \001(\0132\037.xtree" + + "mfs.pbrpc.FileCredentials\"1\n\014rmdirReques" + + "t\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\"h\n\016" + + "setattrRequest\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004p" + + "ath\030\002 \002(\t\022#\n\005stbuf\030\003 \002(\0132\024.xtreemfs.pbrp" + + "c.Stat\022\016\n\006to_set\030\004 \002(\007\"|\n\017setxattrReques", + "t\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\022\014\n\004" + + "name\030\003 \002(\t\022\r\n\005value\030\004 \002(\t\022\032\n\022value_bytes" + + "_string\030\006 \001(\014\022\r\n\005flags\030\005 \002(\007\"9\n\016statvfsR" + + "equest\022\023\n\013volume_name\030\001 \002(\t\022\022\n\nknown_eta" + + "g\030\005 \002(\006\"M\n\016symlinkRequest\022\023\n\013volume_name" + + "\030\001 \002(\t\022\023\n\013target_path\030\002 \002(\t\022\021\n\tlink_path" + + "\030\003 \002(\t\"2\n\runlinkRequest\022\023\n\013volume_name\030\001" + + " \002(\t\022\014\n\004path\030\002 \002(\t\"U\n\016unlinkResponse\022\023\n\013" + + "timestamp_s\030\001 \002(\007\022.\n\005creds\030\002 \001(\0132\037.xtree" + + "mfs.pbrpc.FileCredentials\"A\n\raccessReque", + "st\022\023\n\013volume_name\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\022\r\n" + + "\005flags\030\003 \002(\007\"Z\n!xtreemfs_check_file_exis" + + "tsRequest\022\021\n\tvolume_id\030\001 \002(\t\022\020\n\010file_ids" + + "\030\002 \003(\t\022\020\n\010osd_uuid\030\003 \002(\t\"\315\001\n\"xtreemfs_ch" + + "eck_file_existsResponse\022\025\n\rvolume_exists" + + "\030\001 \002(\010\022V\n\013file_states\030\002 \003(\0162=.xtreemfs.p" + + "brpc.xtreemfs_check_file_existsResponse." + + "FILE_STATEB\002\020\001\"8\n\nFILE_STATE\022\013\n\007DELETED\020" + + "\000\022\016\n\nREGISTERED\020\001\022\r\n\tABANDONED\020\002\":\n%xtre" + + "emfs_dump_restore_databaseRequest\022\021\n\tdum", + "p_file\030\001 \002(\t\"i\n!xtreemfs_get_suitable_os" + + "dsRequest\022\017\n\007file_id\030\001 \001(\t\022\014\n\004path\030\003 \001(\t" + + "\022\023\n\013volume_name\030\004 \001(\t\022\020\n\010num_osds\030\002 \002(\007\"" + + "7\n\"xtreemfs_get_suitable_osdsResponse\022\021\n" + + "\tosd_uuids\030\001 \003(\t\"(\n\021timestampResponse\022\023\n" + + "\013timestamp_s\030\001 \002(\007\"!\n\rstringMessage\022\020\n\010a" + + "_string\030\001 \002(\t\"\'\n\027xtreemfs_listdirRequest" + + "\022\014\n\004path\030\001 \002(\t\")\n\030xtreemfs_listdirRespon" + + "se\022\r\n\005names\030\001 \003(\t\"\177\n\033xtreemfs_replica_ad" + + "dRequest\022\017\n\007file_id\030\001 \001(\t\022\014\n\004path\030\003 \001(\t\022", + "\023\n\013volume_name\030\004 \001(\t\022,\n\013new_replica\030\002 \002(" + + "\0132\027.xtreemfs.pbrpc.Replica\"R\n\034xtreemfs_r" + + "eplica_listRequest\022\017\n\007file_id\030\001 \001(\t\022\014\n\004p" + + "ath\030\002 \001(\t\022\023\n\013volume_name\030\003 \001(\t\"u\n\033xtreem" + + "fs_get_xlocsetRequest\022\017\n\007file_id\030\001 \001(\t\022\014" + + "\n\004path\030\002 \001(\t\022\023\n\013volume_name\030\003 \001(\t\022\"\n\004xca" + + "p\030\004 \001(\0132\024.xtreemfs.pbrpc.XCap\"f\n\036xtreemf" + + "s_replica_removeRequest\022\017\n\007file_id\030\001 \001(\t" + + "\022\014\n\004path\030\003 \001(\t\022\023\n\013volume_name\030\004 \001(\t\022\020\n\010o" + + "sd_uuid\030\002 \002(\t\"|\n\034xtreemfs_restore_fileRe", + "quest\022\021\n\tfile_path\030\001 \002(\t\022\017\n\007file_id\030\002 \002(" + + "\t\022\021\n\tfile_size\030\003 \002(\006\022\020\n\010osd_uuid\030\004 \002(\t\022\023" + + "\n\013stripe_size\030\005 \002(\007\",\n\025xtreemfs_rmvolReq" + + "uest\022\023\n\013volume_name\030\001 \002(\t\"\321\001\n xtreemfs_u" + + "pdate_file_sizeRequest\022\"\n\004xcap\030\001 \002(\0132\024.x" + + "treemfs.pbrpc.XCap\022<\n\022osd_write_response" + + "\030\002 \002(\0132 .xtreemfs.pbrpc.OSDWriteResponse" + + "\022\022\n\nclose_file\030\003 \001(\010\0227\n\013coordinates\030\004 \001(" + + "\0132\".xtreemfs.pbrpc.VivaldiCoordinates\"S\n" + + ")xtreemfs_set_replica_update_policyReque", + "st\022\017\n\007file_id\030\001 \002(\t\022\025\n\rupdate_policy\030\002 \002" + + "(\t\"G\n*xtreemfs_set_replica_update_policy" + + "Response\022\031\n\021old_update_policy\030\001 \002(\t\"E\n#x" + + "treemfs_set_read_only_xattrRequest\022\017\n\007fi" + + "le_id\030\001 \002(\t\022\r\n\005value\030\002 \002(\010\"7\n$xtreemfs_s" + + "et_read_only_xattrResponse\022\017\n\007was_set\030\001 " + + "\002(\010\"7\n$xtreemfs_get_file_credentialsRequ" + + "est\022\017\n\007file_id\030\001 \002(\t*\242\001\n\010Setattrs\022\020\n\014SET" + + "ATTR_MODE\020\001\022\017\n\013SETATTR_UID\020\002\022\017\n\013SETATTR_" + + "GID\020\004\022\020\n\014SETATTR_SIZE\020\010\022\021\n\rSETATTR_ATIME", + "\020\020\022\021\n\rSETATTR_MTIME\020 \022\021\n\rSETATTR_CTIME\020@" + + "\022\027\n\022SETATTR_ATTRIBUTES\020\200\001*>\n\013XATTR_FLAGS" + + "\022\026\n\022XATTR_FLAGS_CREATE\020\001\022\027\n\023XATTR_FLAGS_" + + "REPLACE\020\002*j\n\014ACCESS_FLAGS\022\025\n\021ACCESS_FLAG" + + "S_F_OK\020\000\022\025\n\021ACCESS_FLAGS_X_OK\020\001\022\025\n\021ACCES" + + "S_FLAGS_W_OK\020\002\022\025\n\021ACCESS_FLAGS_R_OK\020\0042\203 " + + "\n\nMRCService\022S\n\010fsetattr\022\037.xtreemfs.pbrp" + + "c.fsetattrRequest\032\035.xtreemfs.pbrpc.empty" + + "Response\"\007\215\265\030\002\000\000\000\022@\n\tftruncate\022\024.xtreemf" + + "s.pbrpc.XCap\032\024.xtreemfs.pbrpc.XCap\"\007\215\265\030\003", + "\000\000\000\022S\n\007getattr\022\036.xtreemfs.pbrpc.getattrR" + + "equest\032\037.xtreemfs.pbrpc.getattrResponse\"" + + "\007\215\265\030\004\000\000\000\022V\n\010getxattr\022\037.xtreemfs.pbrpc.ge" + + "txattrRequest\032 .xtreemfs.pbrpc.getxattrR" + + "esponse\"\007\215\265\030\005\000\000\000\022O\n\004link\022\033.xtreemfs.pbrp" + + "c.linkRequest\032!.xtreemfs.pbrpc.timestamp" + + "Response\"\007\215\265\030\006\000\000\000\022Y\n\tlistxattr\022 .xtreemf" + + "s.pbrpc.listxattrRequest\032!.xtreemfs.pbrp" + + "c.listxattrResponse\"\007\215\265\030\007\000\000\000\022Q\n\005mkdir\022\034." + + "xtreemfs.pbrpc.mkdirRequest\032!.xtreemfs.p", + "brpc.timestampResponse\"\007\215\265\030\010\000\000\000\022J\n\004open\022" + + "\033.xtreemfs.pbrpc.openRequest\032\034.xtreemfs." + + "pbrpc.openResponse\"\007\215\265\030\t\000\000\000\022T\n\007readdir\022\036" + + ".xtreemfs.pbrpc.readdirRequest\032 .xtreemf" + + "s.pbrpc.DirectoryEntries\"\007\215\265\030\n\000\000\000\022V\n\010rea" + + "dlink\022\037.xtreemfs.pbrpc.readlinkRequest\032 " + + ".xtreemfs.pbrpc.readlinkResponse\"\007\215\265\030\013\000\000" + + "\000\022]\n\013removexattr\022\".xtreemfs.pbrpc.remove" + + "xattrRequest\032!.xtreemfs.pbrpc.timestampR" + + "esponse\"\007\215\265\030\014\000\000\000\022P\n\006rename\022\035.xtreemfs.pb", + "rpc.renameRequest\032\036.xtreemfs.pbrpc.renam" + + "eResponse\"\007\215\265\030\r\000\000\000\022Q\n\005rmdir\022\034.xtreemfs.p" + + "brpc.rmdirRequest\032!.xtreemfs.pbrpc.times" + + "tampResponse\"\007\215\265\030\016\000\000\000\022U\n\007setattr\022\036.xtree" + + "mfs.pbrpc.setattrRequest\032!.xtreemfs.pbrp" + + "c.timestampResponse\"\007\215\265\030\017\000\000\000\022W\n\010setxattr" + + "\022\037.xtreemfs.pbrpc.setxattrRequest\032!.xtre" + + "emfs.pbrpc.timestampResponse\"\007\215\265\030\020\000\000\000\022K\n" + + "\007statvfs\022\036.xtreemfs.pbrpc.statvfsRequest" + + "\032\027.xtreemfs.pbrpc.StatVFS\"\007\215\265\030\021\000\000\000\022U\n\007sy", + "mlink\022\036.xtreemfs.pbrpc.symlinkRequest\032!." + + "xtreemfs.pbrpc.timestampResponse\"\007\215\265\030\022\000\000" + + "\000\022P\n\006unlink\022\035.xtreemfs.pbrpc.unlinkReque" + + "st\032\036.xtreemfs.pbrpc.unlinkResponse\"\007\215\265\030\023" + + "\000\000\000\022O\n\006access\022\035.xtreemfs.pbrpc.accessReq" + + "uest\032\035.xtreemfs.pbrpc.emptyResponse\"\007\215\265\030" + + "\024\000\000\000\022[\n\023xtreemfs_checkpoint\022\034.xtreemfs.p" + + "brpc.emptyRequest\032\035.xtreemfs.pbrpc.empty" + + "Response\"\007\215\265\030\036\000\000\000\022\214\001\n\032xtreemfs_check_fil" + + "e_exists\0221.xtreemfs.pbrpc.xtreemfs_check", + "_file_existsRequest\0322.xtreemfs.pbrpc.xtr" + + "eemfs_check_file_existsResponse\"\007\215\265\030\037\000\000\000" + + "\022w\n\026xtreemfs_dump_database\0225.xtreemfs.pb" + + "rpc.xtreemfs_dump_restore_databaseReques" + + "t\032\035.xtreemfs.pbrpc.emptyResponse\"\007\215\265\030 \000\000" + + "\000\022\214\001\n\032xtreemfs_get_suitable_osds\0221.xtree" + + "mfs.pbrpc.xtreemfs_get_suitable_osdsRequ" + + "est\0322.xtreemfs.pbrpc.xtreemfs_get_suitab" + + "le_osdsResponse\"\007\215\265\030!\000\000\000\022`\n\027xtreemfs_int" + + "ernal_debug\022\035.xtreemfs.pbrpc.stringMessa", + "ge\032\035.xtreemfs.pbrpc.stringMessage\"\007\215\265\030\"\000" + + "\000\000\022n\n\020xtreemfs_listdir\022\'.xtreemfs.pbrpc." + + "xtreemfs_listdirRequest\032(.xtreemfs.pbrpc" + + ".xtreemfs_listdirResponse\"\007\215\265\030#\000\000\000\022P\n\016xt" + + "reemfs_lsvol\022\034.xtreemfs.pbrpc.emptyReque" + + "st\032\027.xtreemfs.pbrpc.Volumes\"\007\215\265\030$\000\000\000\022P\n\016" + + "xtreemfs_mkvol\022\026.xtreemfs.pbrpc.Volume\032\035" + + ".xtreemfs.pbrpc.emptyResponse\"\007\215\265\030/\000\000\000\022P" + + "\n\031xtreemfs_renew_capability\022\024.xtreemfs.p" + + "brpc.XCap\032\024.xtreemfs.pbrpc.XCap\"\007\215\265\030%\000\000\000", + "\022f\n\036xtreemfs_replication_to_master\022\034.xtr" + + "eemfs.pbrpc.emptyRequest\032\035.xtreemfs.pbrp" + + "c.emptyResponse\"\007\215\265\030&\000\000\000\022k\n\024xtreemfs_rep" + + "lica_add\022+.xtreemfs.pbrpc.xtreemfs_repli" + + "ca_addRequest\032\035.xtreemfs.pbrpc.emptyResp" + + "onse\"\007\215\265\030\'\000\000\000\022h\n\025xtreemfs_replica_list\022," + + ".xtreemfs.pbrpc.xtreemfs_replica_listReq" + + "uest\032\030.xtreemfs.pbrpc.Replicas\"\007\215\265\030(\000\000\000\022" + + "s\n\027xtreemfs_replica_remove\022..xtreemfs.pb" + + "rpc.xtreemfs_replica_removeRequest\032\037.xtr", + "eemfs.pbrpc.FileCredentials\"\007\215\265\030)\000\000\000\022z\n\031" + + "xtreemfs_restore_database\0225.xtreemfs.pbr" + + "pc.xtreemfs_dump_restore_databaseRequest" + + "\032\035.xtreemfs.pbrpc.emptyResponse\"\007\215\265\030*\000\000\000" + + "\022m\n\025xtreemfs_restore_file\022,.xtreemfs.pbr" + + "pc.xtreemfs_restore_fileRequest\032\035.xtreem" + + "fs.pbrpc.emptyResponse\"\007\215\265\030+\000\000\000\022_\n\016xtree" + + "mfs_rmvol\022%.xtreemfs.pbrpc.xtreemfs_rmvo" + + "lRequest\032\035.xtreemfs.pbrpc.emptyResponse\"" + + "\007\215\265\030,\000\000\000\022Y\n\021xtreemfs_shutdown\022\034.xtreemfs", + ".pbrpc.emptyRequest\032\035.xtreemfs.pbrpc.emp" + + "tyResponse\"\007\215\265\030-\000\000\000\022y\n\031xtreemfs_update_f" + + "ile_size\0220.xtreemfs.pbrpc.xtreemfs_updat" + + "e_file_sizeRequest\032!.xtreemfs.pbrpc.time" + + "stampResponse\"\007\215\265\030.\000\000\000\022\244\001\n\"xtreemfs_set_" + + "replica_update_policy\0229.xtreemfs.pbrpc.x" + + "treemfs_set_replica_update_policyRequest" + + "\032:.xtreemfs.pbrpc.xtreemfs_set_replica_u" + + "pdate_policyResponse\"\007\215\265\0300\000\000\000\022\222\001\n\034xtreem" + + "fs_set_read_only_xattr\0223.xtreemfs.pbrpc.", + "xtreemfs_set_read_only_xattrRequest\0324.xt" + + "reemfs.pbrpc.xtreemfs_set_read_only_xatt" + + "rResponse\"\007\215\265\0301\000\000\000\022\177\n\035xtreemfs_get_file_" + + "credentials\0224.xtreemfs.pbrpc.xtreemfs_ge" + + "t_file_credentialsRequest\032\037.xtreemfs.pbr" + + "pc.FileCredentials\"\007\215\265\0302\000\000\000\022e\n\024xtreemfs_" + + "get_xlocset\022+.xtreemfs.pbrpc.xtreemfs_ge" + + "t_xlocsetRequest\032\027.xtreemfs.pbrpc.XLocSe" + + "t\"\007\215\265\0303\000\000\000\032\007\225\265\030!N\000\000B(\n&org.xtreemfs.pbrp" + + "c.generatedinterfaces" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_xtreemfs_pbrpc_Stat_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_xtreemfs_pbrpc_Stat_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_Stat_descriptor, + new java.lang.String[] { "Dev", "Ino", "Mode", "Nlink", "UserId", "GroupId", "Size", "AtimeNs", "MtimeNs", "CtimeNs", "Blksize", "Etag", "TruncateEpoch", "Attributes", }); + internal_static_xtreemfs_pbrpc_DirectoryEntry_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_xtreemfs_pbrpc_DirectoryEntry_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_DirectoryEntry_descriptor, + new java.lang.String[] { "Name", "Stbuf", }); + internal_static_xtreemfs_pbrpc_DirectoryEntries_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_xtreemfs_pbrpc_DirectoryEntries_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_DirectoryEntries_descriptor, + new java.lang.String[] { "Entries", }); + internal_static_xtreemfs_pbrpc_XAttr_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_xtreemfs_pbrpc_XAttr_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_XAttr_descriptor, + new java.lang.String[] { "Name", "Value", "ValueBytesString", }); + internal_static_xtreemfs_pbrpc_Volume_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_xtreemfs_pbrpc_Volume_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_Volume_descriptor, + new java.lang.String[] { "AccessControlPolicy", "DefaultStripingPolicy", "Id", "Mode", "Name", "OwnerGroupId", "OwnerUserId", "Attrs", "Quota", }); + internal_static_xtreemfs_pbrpc_Volumes_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_xtreemfs_pbrpc_Volumes_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_Volumes_descriptor, + new java.lang.String[] { "Volumes", }); + internal_static_xtreemfs_pbrpc_StatVFS_descriptor = + getDescriptor().getMessageTypes().get(6); + internal_static_xtreemfs_pbrpc_StatVFS_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_StatVFS_descriptor, + new java.lang.String[] { "Bsize", "Bavail", "Bfree", "Blocks", "Fsid", "Namemax", "AccessControlPolicy", "DefaultStripingPolicy", "Etag", "Mode", "Name", "OwnerGroupId", "OwnerUserId", }); + internal_static_xtreemfs_pbrpc_fsetattrRequest_descriptor = + getDescriptor().getMessageTypes().get(7); + internal_static_xtreemfs_pbrpc_fsetattrRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_fsetattrRequest_descriptor, + new java.lang.String[] { "Stbuf", "ToSet", "Cap", }); + internal_static_xtreemfs_pbrpc_getattrRequest_descriptor = + getDescriptor().getMessageTypes().get(8); + internal_static_xtreemfs_pbrpc_getattrRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_getattrRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", "KnownEtag", }); + internal_static_xtreemfs_pbrpc_getattrResponse_descriptor = + getDescriptor().getMessageTypes().get(9); + internal_static_xtreemfs_pbrpc_getattrResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_getattrResponse_descriptor, + new java.lang.String[] { "Stbuf", }); + internal_static_xtreemfs_pbrpc_getxattrRequest_descriptor = + getDescriptor().getMessageTypes().get(10); + internal_static_xtreemfs_pbrpc_getxattrRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_getxattrRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", "Name", }); + internal_static_xtreemfs_pbrpc_getxattrResponse_descriptor = + getDescriptor().getMessageTypes().get(11); + internal_static_xtreemfs_pbrpc_getxattrResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_getxattrResponse_descriptor, + new java.lang.String[] { "Value", "ValueBytesString", }); + internal_static_xtreemfs_pbrpc_linkRequest_descriptor = + getDescriptor().getMessageTypes().get(12); + internal_static_xtreemfs_pbrpc_linkRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_linkRequest_descriptor, + new java.lang.String[] { "VolumeName", "TargetPath", "LinkPath", }); + internal_static_xtreemfs_pbrpc_listxattrRequest_descriptor = + getDescriptor().getMessageTypes().get(13); + internal_static_xtreemfs_pbrpc_listxattrRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_listxattrRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", "NamesOnly", }); + internal_static_xtreemfs_pbrpc_listxattrResponse_descriptor = + getDescriptor().getMessageTypes().get(14); + internal_static_xtreemfs_pbrpc_listxattrResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_listxattrResponse_descriptor, + new java.lang.String[] { "Xattrs", }); + internal_static_xtreemfs_pbrpc_mkdirRequest_descriptor = + getDescriptor().getMessageTypes().get(15); + internal_static_xtreemfs_pbrpc_mkdirRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_mkdirRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", "Mode", }); + internal_static_xtreemfs_pbrpc_openRequest_descriptor = + getDescriptor().getMessageTypes().get(16); + internal_static_xtreemfs_pbrpc_openRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_openRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", "Flags", "Mode", "Attributes", "Coordinates", }); + internal_static_xtreemfs_pbrpc_openResponse_descriptor = + getDescriptor().getMessageTypes().get(17); + internal_static_xtreemfs_pbrpc_openResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_openResponse_descriptor, + new java.lang.String[] { "Creds", "TimestampS", }); + internal_static_xtreemfs_pbrpc_readdirRequest_descriptor = + getDescriptor().getMessageTypes().get(18); + internal_static_xtreemfs_pbrpc_readdirRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_readdirRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", "KnownEtag", "LimitDirectoryEntriesCount", "NamesOnly", "SeenDirectoryEntriesCount", }); + internal_static_xtreemfs_pbrpc_readlinkRequest_descriptor = + getDescriptor().getMessageTypes().get(19); + internal_static_xtreemfs_pbrpc_readlinkRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_readlinkRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", }); + internal_static_xtreemfs_pbrpc_readlinkResponse_descriptor = + getDescriptor().getMessageTypes().get(20); + internal_static_xtreemfs_pbrpc_readlinkResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_readlinkResponse_descriptor, + new java.lang.String[] { "LinkTargetPath", }); + internal_static_xtreemfs_pbrpc_removexattrRequest_descriptor = + getDescriptor().getMessageTypes().get(21); + internal_static_xtreemfs_pbrpc_removexattrRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_removexattrRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", "Name", }); + internal_static_xtreemfs_pbrpc_renameRequest_descriptor = + getDescriptor().getMessageTypes().get(22); + internal_static_xtreemfs_pbrpc_renameRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_renameRequest_descriptor, + new java.lang.String[] { "VolumeName", "SourcePath", "TargetPath", }); + internal_static_xtreemfs_pbrpc_renameResponse_descriptor = + getDescriptor().getMessageTypes().get(23); + internal_static_xtreemfs_pbrpc_renameResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_renameResponse_descriptor, + new java.lang.String[] { "TimestampS", "Creds", }); + internal_static_xtreemfs_pbrpc_rmdirRequest_descriptor = + getDescriptor().getMessageTypes().get(24); + internal_static_xtreemfs_pbrpc_rmdirRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_rmdirRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", }); + internal_static_xtreemfs_pbrpc_setattrRequest_descriptor = + getDescriptor().getMessageTypes().get(25); + internal_static_xtreemfs_pbrpc_setattrRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_setattrRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", "Stbuf", "ToSet", }); + internal_static_xtreemfs_pbrpc_setxattrRequest_descriptor = + getDescriptor().getMessageTypes().get(26); + internal_static_xtreemfs_pbrpc_setxattrRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_setxattrRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", "Name", "Value", "ValueBytesString", "Flags", }); + internal_static_xtreemfs_pbrpc_statvfsRequest_descriptor = + getDescriptor().getMessageTypes().get(27); + internal_static_xtreemfs_pbrpc_statvfsRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_statvfsRequest_descriptor, + new java.lang.String[] { "VolumeName", "KnownEtag", }); + internal_static_xtreemfs_pbrpc_symlinkRequest_descriptor = + getDescriptor().getMessageTypes().get(28); + internal_static_xtreemfs_pbrpc_symlinkRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_symlinkRequest_descriptor, + new java.lang.String[] { "VolumeName", "TargetPath", "LinkPath", }); + internal_static_xtreemfs_pbrpc_unlinkRequest_descriptor = + getDescriptor().getMessageTypes().get(29); + internal_static_xtreemfs_pbrpc_unlinkRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_unlinkRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", }); + internal_static_xtreemfs_pbrpc_unlinkResponse_descriptor = + getDescriptor().getMessageTypes().get(30); + internal_static_xtreemfs_pbrpc_unlinkResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_unlinkResponse_descriptor, + new java.lang.String[] { "TimestampS", "Creds", }); + internal_static_xtreemfs_pbrpc_accessRequest_descriptor = + getDescriptor().getMessageTypes().get(31); + internal_static_xtreemfs_pbrpc_accessRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_accessRequest_descriptor, + new java.lang.String[] { "VolumeName", "Path", "Flags", }); + internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsRequest_descriptor = + getDescriptor().getMessageTypes().get(32); + internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsRequest_descriptor, + new java.lang.String[] { "VolumeId", "FileIds", "OsdUuid", }); + internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsResponse_descriptor = + getDescriptor().getMessageTypes().get(33); + internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_check_file_existsResponse_descriptor, + new java.lang.String[] { "VolumeExists", "FileStates", }); + internal_static_xtreemfs_pbrpc_xtreemfs_dump_restore_databaseRequest_descriptor = + getDescriptor().getMessageTypes().get(34); + internal_static_xtreemfs_pbrpc_xtreemfs_dump_restore_databaseRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_dump_restore_databaseRequest_descriptor, + new java.lang.String[] { "DumpFile", }); + internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsRequest_descriptor = + getDescriptor().getMessageTypes().get(35); + internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsRequest_descriptor, + new java.lang.String[] { "FileId", "Path", "VolumeName", "NumOsds", }); + internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsResponse_descriptor = + getDescriptor().getMessageTypes().get(36); + internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_get_suitable_osdsResponse_descriptor, + new java.lang.String[] { "OsdUuids", }); + internal_static_xtreemfs_pbrpc_timestampResponse_descriptor = + getDescriptor().getMessageTypes().get(37); + internal_static_xtreemfs_pbrpc_timestampResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_timestampResponse_descriptor, + new java.lang.String[] { "TimestampS", }); + internal_static_xtreemfs_pbrpc_stringMessage_descriptor = + getDescriptor().getMessageTypes().get(38); + internal_static_xtreemfs_pbrpc_stringMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_stringMessage_descriptor, + new java.lang.String[] { "AString", }); + internal_static_xtreemfs_pbrpc_xtreemfs_listdirRequest_descriptor = + getDescriptor().getMessageTypes().get(39); + internal_static_xtreemfs_pbrpc_xtreemfs_listdirRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_listdirRequest_descriptor, + new java.lang.String[] { "Path", }); + internal_static_xtreemfs_pbrpc_xtreemfs_listdirResponse_descriptor = + getDescriptor().getMessageTypes().get(40); + internal_static_xtreemfs_pbrpc_xtreemfs_listdirResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_listdirResponse_descriptor, + new java.lang.String[] { "Names", }); + internal_static_xtreemfs_pbrpc_xtreemfs_replica_addRequest_descriptor = + getDescriptor().getMessageTypes().get(41); + internal_static_xtreemfs_pbrpc_xtreemfs_replica_addRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_replica_addRequest_descriptor, + new java.lang.String[] { "FileId", "Path", "VolumeName", "NewReplica", }); + internal_static_xtreemfs_pbrpc_xtreemfs_replica_listRequest_descriptor = + getDescriptor().getMessageTypes().get(42); + internal_static_xtreemfs_pbrpc_xtreemfs_replica_listRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_replica_listRequest_descriptor, + new java.lang.String[] { "FileId", "Path", "VolumeName", }); + internal_static_xtreemfs_pbrpc_xtreemfs_get_xlocsetRequest_descriptor = + getDescriptor().getMessageTypes().get(43); + internal_static_xtreemfs_pbrpc_xtreemfs_get_xlocsetRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_get_xlocsetRequest_descriptor, + new java.lang.String[] { "FileId", "Path", "VolumeName", "Xcap", }); + internal_static_xtreemfs_pbrpc_xtreemfs_replica_removeRequest_descriptor = + getDescriptor().getMessageTypes().get(44); + internal_static_xtreemfs_pbrpc_xtreemfs_replica_removeRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_replica_removeRequest_descriptor, + new java.lang.String[] { "FileId", "Path", "VolumeName", "OsdUuid", }); + internal_static_xtreemfs_pbrpc_xtreemfs_restore_fileRequest_descriptor = + getDescriptor().getMessageTypes().get(45); + internal_static_xtreemfs_pbrpc_xtreemfs_restore_fileRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_restore_fileRequest_descriptor, + new java.lang.String[] { "FilePath", "FileId", "FileSize", "OsdUuid", "StripeSize", }); + internal_static_xtreemfs_pbrpc_xtreemfs_rmvolRequest_descriptor = + getDescriptor().getMessageTypes().get(46); + internal_static_xtreemfs_pbrpc_xtreemfs_rmvolRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_rmvolRequest_descriptor, + new java.lang.String[] { "VolumeName", }); + internal_static_xtreemfs_pbrpc_xtreemfs_update_file_sizeRequest_descriptor = + getDescriptor().getMessageTypes().get(47); + internal_static_xtreemfs_pbrpc_xtreemfs_update_file_sizeRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_update_file_sizeRequest_descriptor, + new java.lang.String[] { "Xcap", "OsdWriteResponse", "CloseFile", "Coordinates", }); + internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyRequest_descriptor = + getDescriptor().getMessageTypes().get(48); + internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyRequest_descriptor, + new java.lang.String[] { "FileId", "UpdatePolicy", }); + internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyResponse_descriptor = + getDescriptor().getMessageTypes().get(49); + internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_set_replica_update_policyResponse_descriptor, + new java.lang.String[] { "OldUpdatePolicy", }); + internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrRequest_descriptor = + getDescriptor().getMessageTypes().get(50); + internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrRequest_descriptor, + new java.lang.String[] { "FileId", "Value", }); + internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrResponse_descriptor = + getDescriptor().getMessageTypes().get(51); + internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_set_read_only_xattrResponse_descriptor, + new java.lang.String[] { "WasSet", }); + internal_static_xtreemfs_pbrpc_xtreemfs_get_file_credentialsRequest_descriptor = + getDescriptor().getMessageTypes().get(52); + internal_static_xtreemfs_pbrpc_xtreemfs_get_file_credentialsRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_get_file_credentialsRequest_descriptor, + new java.lang.String[] { "FileId", }); + com.google.protobuf.ExtensionRegistry registry = + com.google.protobuf.ExtensionRegistry.newInstance(); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.interfaceId); + return registry; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.getDescriptor(), + org.xtreemfs.pbrpc.generatedinterfaces.Common.getDescriptor(), + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor(), + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRCServiceClient.java b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRCServiceClient.java new file mode 100644 index 0000000..d9c59ed --- /dev/null +++ b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRCServiceClient.java @@ -0,0 +1,563 @@ +//automatically generated from MRC.proto at Thu Dec 11 16:09:37 CET 2014 +//(c) 2014. See LICENSE file for details. + +package org.xtreemfs.pbrpc.generatedinterfaces; + +import java.io.IOException; +import java.util.List; +import java.net.InetSocketAddress; +import com.google.protobuf.Message; +import com.google.protobuf.ByteString; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; + +public class MRCServiceClient { + + private RPCNIOSocketClient client; + private InetSocketAddress defaultServer; + + public MRCServiceClient(RPCNIOSocketClient client, InetSocketAddress defaultServer) { + this.client = client; + this.defaultServer = defaultServer; + } + + public RPCResponse fsetattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.fsetattrRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 20001, 2, input, null, response, false); + return response; + } + + public RPCResponse fsetattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.Stat stbuf, int to_set, GlobalTypes.XCap cap) throws IOException { + final MRC.fsetattrRequest msg = MRC.fsetattrRequest.newBuilder().setStbuf(stbuf).setToSet(to_set).setCap(cap).build(); + return fsetattr(server, authHeader, userCreds,msg); + } + + public RPCResponse ftruncate(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.XCap input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(GlobalTypes.XCap.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 3, input, null, response, false); + return response; + } + + public RPCResponse ftruncate(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, int access_mode, String client_identity, long expire_time_s, int expire_timeout_s, String file_id, boolean replicate_on_close, String server_signature, int truncate_epoch, GlobalTypes.SnapConfig snap_config, long snap_timestamp) throws IOException { + final GlobalTypes.XCap msg = GlobalTypes.XCap.newBuilder().setAccessMode(access_mode).setClientIdentity(client_identity).setExpireTimeS(expire_time_s).setExpireTimeoutS(expire_timeout_s).setFileId(file_id).setReplicateOnClose(replicate_on_close).setServerSignature(server_signature).setTruncateEpoch(truncate_epoch).setSnapConfig(snap_config).setSnapTimestamp(snap_timestamp).build(); + return ftruncate(server, authHeader, userCreds,msg); + } + + public RPCResponse getattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.getattrRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.getattrResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 4, input, null, response, false); + return response; + } + + public RPCResponse getattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path, long known_etag) throws IOException { + final MRC.getattrRequest msg = MRC.getattrRequest.newBuilder().setVolumeName(volume_name).setPath(path).setKnownEtag(known_etag).build(); + return getattr(server, authHeader, userCreds,msg); + } + + public RPCResponse getxattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.getxattrRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.getxattrResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 5, input, null, response, false); + return response; + } + + public RPCResponse getxattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path, String name) throws IOException { + final MRC.getxattrRequest msg = MRC.getxattrRequest.newBuilder().setVolumeName(volume_name).setPath(path).setName(name).build(); + return getxattr(server, authHeader, userCreds,msg); + } + + public RPCResponse link(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.linkRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.timestampResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 6, input, null, response, false); + return response; + } + + public RPCResponse link(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String target_path, String link_path) throws IOException { + final MRC.linkRequest msg = MRC.linkRequest.newBuilder().setVolumeName(volume_name).setTargetPath(target_path).setLinkPath(link_path).build(); + return link(server, authHeader, userCreds,msg); + } + + public RPCResponse listxattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.listxattrRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.listxattrResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 7, input, null, response, false); + return response; + } + + public RPCResponse listxattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path, boolean names_only) throws IOException { + final MRC.listxattrRequest msg = MRC.listxattrRequest.newBuilder().setVolumeName(volume_name).setPath(path).setNamesOnly(names_only).build(); + return listxattr(server, authHeader, userCreds,msg); + } + + public RPCResponse mkdir(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.mkdirRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.timestampResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 8, input, null, response, false); + return response; + } + + public RPCResponse mkdir(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path, int mode) throws IOException { + final MRC.mkdirRequest msg = MRC.mkdirRequest.newBuilder().setVolumeName(volume_name).setPath(path).setMode(mode).build(); + return mkdir(server, authHeader, userCreds,msg); + } + + public RPCResponse open(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.openRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.openResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 9, input, null, response, false); + return response; + } + + public RPCResponse open(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path, int flags, int mode, int attributes, GlobalTypes.VivaldiCoordinates coordinates) throws IOException { + final MRC.openRequest msg = MRC.openRequest.newBuilder().setVolumeName(volume_name).setPath(path).setFlags(flags).setMode(mode).setAttributes(attributes).setCoordinates(coordinates).build(); + return open(server, authHeader, userCreds,msg); + } + + public RPCResponse readdir(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.readdirRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.DirectoryEntries.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 10, input, null, response, false); + return response; + } + + public RPCResponse readdir(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path, long known_etag, int limit_directory_entries_count, boolean names_only, long seen_directory_entries_count) throws IOException { + final MRC.readdirRequest msg = MRC.readdirRequest.newBuilder().setVolumeName(volume_name).setPath(path).setKnownEtag(known_etag).setLimitDirectoryEntriesCount(limit_directory_entries_count).setNamesOnly(names_only).setSeenDirectoryEntriesCount(seen_directory_entries_count).build(); + return readdir(server, authHeader, userCreds,msg); + } + + public RPCResponse readlink(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.readlinkRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.readlinkResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 11, input, null, response, false); + return response; + } + + public RPCResponse readlink(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path) throws IOException { + final MRC.readlinkRequest msg = MRC.readlinkRequest.newBuilder().setVolumeName(volume_name).setPath(path).build(); + return readlink(server, authHeader, userCreds,msg); + } + + public RPCResponse removexattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.removexattrRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.timestampResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 12, input, null, response, false); + return response; + } + + public RPCResponse removexattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path, String name) throws IOException { + final MRC.removexattrRequest msg = MRC.removexattrRequest.newBuilder().setVolumeName(volume_name).setPath(path).setName(name).build(); + return removexattr(server, authHeader, userCreds,msg); + } + + public RPCResponse rename(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.renameRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.renameResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 13, input, null, response, false); + return response; + } + + public RPCResponse rename(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String source_path, String target_path) throws IOException { + final MRC.renameRequest msg = MRC.renameRequest.newBuilder().setVolumeName(volume_name).setSourcePath(source_path).setTargetPath(target_path).build(); + return rename(server, authHeader, userCreds,msg); + } + + public RPCResponse rmdir(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.rmdirRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.timestampResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 14, input, null, response, false); + return response; + } + + public RPCResponse rmdir(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path) throws IOException { + final MRC.rmdirRequest msg = MRC.rmdirRequest.newBuilder().setVolumeName(volume_name).setPath(path).build(); + return rmdir(server, authHeader, userCreds,msg); + } + + public RPCResponse setattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.setattrRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.timestampResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 15, input, null, response, false); + return response; + } + + public RPCResponse setattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path, MRC.Stat stbuf, int to_set) throws IOException { + final MRC.setattrRequest msg = MRC.setattrRequest.newBuilder().setVolumeName(volume_name).setPath(path).setStbuf(stbuf).setToSet(to_set).build(); + return setattr(server, authHeader, userCreds,msg); + } + + public RPCResponse setxattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.setxattrRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.timestampResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 16, input, null, response, false); + return response; + } + + public RPCResponse setxattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path, String name, String value, ByteString value_bytes_string, int flags) throws IOException { + final MRC.setxattrRequest msg = MRC.setxattrRequest.newBuilder().setVolumeName(volume_name).setPath(path).setName(name).setValue(value).setValueBytesString(value_bytes_string).setFlags(flags).build(); + return setxattr(server, authHeader, userCreds,msg); + } + + public RPCResponse statvfs(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.statvfsRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.StatVFS.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 17, input, null, response, false); + return response; + } + + public RPCResponse statvfs(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, long known_etag) throws IOException { + final MRC.statvfsRequest msg = MRC.statvfsRequest.newBuilder().setVolumeName(volume_name).setKnownEtag(known_etag).build(); + return statvfs(server, authHeader, userCreds,msg); + } + + public RPCResponse symlink(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.symlinkRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.timestampResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 18, input, null, response, false); + return response; + } + + public RPCResponse symlink(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String target_path, String link_path) throws IOException { + final MRC.symlinkRequest msg = MRC.symlinkRequest.newBuilder().setVolumeName(volume_name).setTargetPath(target_path).setLinkPath(link_path).build(); + return symlink(server, authHeader, userCreds,msg); + } + + public RPCResponse unlink(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.unlinkRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.unlinkResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 19, input, null, response, false); + return response; + } + + public RPCResponse unlink(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path) throws IOException { + final MRC.unlinkRequest msg = MRC.unlinkRequest.newBuilder().setVolumeName(volume_name).setPath(path).build(); + return unlink(server, authHeader, userCreds,msg); + } + + public RPCResponse access(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.accessRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 20001, 20, input, null, response, false); + return response; + } + + public RPCResponse access(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name, String path, int flags) throws IOException { + final MRC.accessRequest msg = MRC.accessRequest.newBuilder().setVolumeName(volume_name).setPath(path).setFlags(flags).build(); + return access(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_checkpoint(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 20001, 30, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_checkpoint(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_checkpoint(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_check_file_exists(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_check_file_existsRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.xtreemfs_check_file_existsResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 31, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_check_file_exists(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_id, List file_ids, String osd_uuid) throws IOException { + final MRC.xtreemfs_check_file_existsRequest msg = MRC.xtreemfs_check_file_existsRequest.newBuilder().setVolumeId(volume_id).addAllFileIds(file_ids).setOsdUuid(osd_uuid).build(); + return xtreemfs_check_file_exists(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_dump_database(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_dump_restore_databaseRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 20001, 32, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_dump_database(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String dump_file) throws IOException { + final MRC.xtreemfs_dump_restore_databaseRequest msg = MRC.xtreemfs_dump_restore_databaseRequest.newBuilder().setDumpFile(dump_file).build(); + return xtreemfs_dump_database(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_get_suitable_osds(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_get_suitable_osdsRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.xtreemfs_get_suitable_osdsResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 33, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_get_suitable_osds(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String file_id, String path, String volume_name, int num_osds) throws IOException { + final MRC.xtreemfs_get_suitable_osdsRequest msg = MRC.xtreemfs_get_suitable_osdsRequest.newBuilder().setFileId(file_id).setPath(path).setVolumeName(volume_name).setNumOsds(num_osds).build(); + return xtreemfs_get_suitable_osds(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_internal_debug(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.stringMessage input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.stringMessage.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 34, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_internal_debug(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String a_string) throws IOException { + final MRC.stringMessage msg = MRC.stringMessage.newBuilder().setAString(a_string).build(); + return xtreemfs_internal_debug(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_listdir(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_listdirRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.xtreemfs_listdirResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 35, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_listdir(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String path) throws IOException { + final MRC.xtreemfs_listdirRequest msg = MRC.xtreemfs_listdirRequest.newBuilder().setPath(path).build(); + return xtreemfs_listdir(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_lsvol(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.Volumes.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 36, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_lsvol(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_lsvol(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_mkvol(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.Volume input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 20001, 47, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_mkvol(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.AccessControlPolicyType access_control_policy, GlobalTypes.StripingPolicy default_striping_policy, String id, int mode, String name, String owner_group_id, String owner_user_id, List attrs, long quota) throws IOException { + final MRC.Volume msg = MRC.Volume.newBuilder().setAccessControlPolicy(access_control_policy).setDefaultStripingPolicy(default_striping_policy).setId(id).setMode(mode).setName(name).setOwnerGroupId(owner_group_id).setOwnerUserId(owner_user_id).addAllAttrs(attrs).setQuota(quota).build(); + return xtreemfs_mkvol(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_renew_capability(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.XCap input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(GlobalTypes.XCap.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 37, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_renew_capability(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, int access_mode, String client_identity, long expire_time_s, int expire_timeout_s, String file_id, boolean replicate_on_close, String server_signature, int truncate_epoch, GlobalTypes.SnapConfig snap_config, long snap_timestamp) throws IOException { + final GlobalTypes.XCap msg = GlobalTypes.XCap.newBuilder().setAccessMode(access_mode).setClientIdentity(client_identity).setExpireTimeS(expire_time_s).setExpireTimeoutS(expire_timeout_s).setFileId(file_id).setReplicateOnClose(replicate_on_close).setServerSignature(server_signature).setTruncateEpoch(truncate_epoch).setSnapConfig(snap_config).setSnapTimestamp(snap_timestamp).build(); + return xtreemfs_renew_capability(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_replication_to_master(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 20001, 38, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_replication_to_master(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_replication_to_master(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_replica_add(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_replica_addRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 20001, 39, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_replica_add(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String file_id, String path, String volume_name, GlobalTypes.Replica new_replica) throws IOException { + final MRC.xtreemfs_replica_addRequest msg = MRC.xtreemfs_replica_addRequest.newBuilder().setFileId(file_id).setPath(path).setVolumeName(volume_name).setNewReplica(new_replica).build(); + return xtreemfs_replica_add(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_replica_list(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_replica_listRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(GlobalTypes.Replicas.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 40, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_replica_list(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String file_id, String path, String volume_name) throws IOException { + final MRC.xtreemfs_replica_listRequest msg = MRC.xtreemfs_replica_listRequest.newBuilder().setFileId(file_id).setPath(path).setVolumeName(volume_name).build(); + return xtreemfs_replica_list(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_replica_remove(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_replica_removeRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(GlobalTypes.FileCredentials.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 41, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_replica_remove(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String file_id, String path, String volume_name, String osd_uuid) throws IOException { + final MRC.xtreemfs_replica_removeRequest msg = MRC.xtreemfs_replica_removeRequest.newBuilder().setFileId(file_id).setPath(path).setVolumeName(volume_name).setOsdUuid(osd_uuid).build(); + return xtreemfs_replica_remove(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_restore_database(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_dump_restore_databaseRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 20001, 42, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_restore_database(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String dump_file) throws IOException { + final MRC.xtreemfs_dump_restore_databaseRequest msg = MRC.xtreemfs_dump_restore_databaseRequest.newBuilder().setDumpFile(dump_file).build(); + return xtreemfs_restore_database(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_restore_file(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_restore_fileRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 20001, 43, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_restore_file(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String file_path, String file_id, long file_size, String osd_uuid, int stripe_size) throws IOException { + final MRC.xtreemfs_restore_fileRequest msg = MRC.xtreemfs_restore_fileRequest.newBuilder().setFilePath(file_path).setFileId(file_id).setFileSize(file_size).setOsdUuid(osd_uuid).setStripeSize(stripe_size).build(); + return xtreemfs_restore_file(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_rmvol(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_rmvolRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 20001, 44, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_rmvol(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String volume_name) throws IOException { + final MRC.xtreemfs_rmvolRequest msg = MRC.xtreemfs_rmvolRequest.newBuilder().setVolumeName(volume_name).build(); + return xtreemfs_rmvol(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_shutdown(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 20001, 45, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_shutdown(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_shutdown(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_update_file_size(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_update_file_sizeRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.timestampResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 46, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_update_file_size(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.XCap xcap, GlobalTypes.OSDWriteResponse osd_write_response, boolean close_file, GlobalTypes.VivaldiCoordinates coordinates) throws IOException { + final MRC.xtreemfs_update_file_sizeRequest msg = MRC.xtreemfs_update_file_sizeRequest.newBuilder().setXcap(xcap).setOsdWriteResponse(osd_write_response).setCloseFile(close_file).setCoordinates(coordinates).build(); + return xtreemfs_update_file_size(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_set_replica_update_policy(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_set_replica_update_policyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.xtreemfs_set_replica_update_policyResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 48, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_set_replica_update_policy(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String file_id, String update_policy) throws IOException { + final MRC.xtreemfs_set_replica_update_policyRequest msg = MRC.xtreemfs_set_replica_update_policyRequest.newBuilder().setFileId(file_id).setUpdatePolicy(update_policy).build(); + return xtreemfs_set_replica_update_policy(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_set_read_only_xattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_set_read_only_xattrRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(MRC.xtreemfs_set_read_only_xattrResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 49, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_set_read_only_xattr(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String file_id, boolean value) throws IOException { + final MRC.xtreemfs_set_read_only_xattrRequest msg = MRC.xtreemfs_set_read_only_xattrRequest.newBuilder().setFileId(file_id).setValue(value).build(); + return xtreemfs_set_read_only_xattr(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_get_file_credentials(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_get_file_credentialsRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(GlobalTypes.FileCredentials.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 50, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_get_file_credentials(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String file_id) throws IOException { + final MRC.xtreemfs_get_file_credentialsRequest msg = MRC.xtreemfs_get_file_credentialsRequest.newBuilder().setFileId(file_id).build(); + return xtreemfs_get_file_credentials(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_get_xlocset(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, MRC.xtreemfs_get_xlocsetRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(GlobalTypes.XLocSet.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 20001, 51, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_get_xlocset(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String file_id, String path, String volume_name, GlobalTypes.XCap xcap) throws IOException { + final MRC.xtreemfs_get_xlocsetRequest msg = MRC.xtreemfs_get_xlocsetRequest.newBuilder().setFileId(file_id).setPath(path).setVolumeName(volume_name).setXcap(xcap).build(); + return xtreemfs_get_xlocset(server, authHeader, userCreds,msg); + } + + public boolean clientIsAlive() { + return client.isAlive(); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRCServiceConstants.java b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRCServiceConstants.java new file mode 100644 index 0000000..1e4fea6 --- /dev/null +++ b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/MRCServiceConstants.java @@ -0,0 +1,149 @@ +//automatically generated from MRC.proto at Thu Dec 11 16:09:37 CET 2014 +//(c) 2014. See LICENSE file for details. + +package org.xtreemfs.pbrpc.generatedinterfaces; + +import com.google.protobuf.Message; + +public class MRCServiceConstants { + + public static final int INTERFACE_ID = 20001; + public static final int PROC_ID_FSETATTR = 2; + public static final int PROC_ID_FTRUNCATE = 3; + public static final int PROC_ID_GETATTR = 4; + public static final int PROC_ID_GETXATTR = 5; + public static final int PROC_ID_LINK = 6; + public static final int PROC_ID_LISTXATTR = 7; + public static final int PROC_ID_MKDIR = 8; + public static final int PROC_ID_OPEN = 9; + public static final int PROC_ID_READDIR = 10; + public static final int PROC_ID_READLINK = 11; + public static final int PROC_ID_REMOVEXATTR = 12; + public static final int PROC_ID_RENAME = 13; + public static final int PROC_ID_RMDIR = 14; + public static final int PROC_ID_SETATTR = 15; + public static final int PROC_ID_SETXATTR = 16; + public static final int PROC_ID_STATVFS = 17; + public static final int PROC_ID_SYMLINK = 18; + public static final int PROC_ID_UNLINK = 19; + public static final int PROC_ID_ACCESS = 20; + public static final int PROC_ID_XTREEMFS_CHECKPOINT = 30; + public static final int PROC_ID_XTREEMFS_CHECK_FILE_EXISTS = 31; + public static final int PROC_ID_XTREEMFS_DUMP_DATABASE = 32; + public static final int PROC_ID_XTREEMFS_GET_SUITABLE_OSDS = 33; + public static final int PROC_ID_XTREEMFS_INTERNAL_DEBUG = 34; + public static final int PROC_ID_XTREEMFS_LISTDIR = 35; + public static final int PROC_ID_XTREEMFS_LSVOL = 36; + public static final int PROC_ID_XTREEMFS_MKVOL = 47; + public static final int PROC_ID_XTREEMFS_RENEW_CAPABILITY = 37; + public static final int PROC_ID_XTREEMFS_REPLICATION_TO_MASTER = 38; + public static final int PROC_ID_XTREEMFS_REPLICA_ADD = 39; + public static final int PROC_ID_XTREEMFS_REPLICA_LIST = 40; + public static final int PROC_ID_XTREEMFS_REPLICA_REMOVE = 41; + public static final int PROC_ID_XTREEMFS_RESTORE_DATABASE = 42; + public static final int PROC_ID_XTREEMFS_RESTORE_FILE = 43; + public static final int PROC_ID_XTREEMFS_RMVOL = 44; + public static final int PROC_ID_XTREEMFS_SHUTDOWN = 45; + public static final int PROC_ID_XTREEMFS_UPDATE_FILE_SIZE = 46; + public static final int PROC_ID_XTREEMFS_SET_REPLICA_UPDATE_POLICY = 48; + public static final int PROC_ID_XTREEMFS_SET_READ_ONLY_XATTR = 49; + public static final int PROC_ID_XTREEMFS_GET_FILE_CREDENTIALS = 50; + public static final int PROC_ID_XTREEMFS_GET_XLOCSET = 51; + + public static Message getRequestMessage(int procId) { + switch (procId) { + case 2: return MRC.fsetattrRequest.getDefaultInstance(); + case 3: return GlobalTypes.XCap.getDefaultInstance(); + case 4: return MRC.getattrRequest.getDefaultInstance(); + case 5: return MRC.getxattrRequest.getDefaultInstance(); + case 6: return MRC.linkRequest.getDefaultInstance(); + case 7: return MRC.listxattrRequest.getDefaultInstance(); + case 8: return MRC.mkdirRequest.getDefaultInstance(); + case 9: return MRC.openRequest.getDefaultInstance(); + case 10: return MRC.readdirRequest.getDefaultInstance(); + case 11: return MRC.readlinkRequest.getDefaultInstance(); + case 12: return MRC.removexattrRequest.getDefaultInstance(); + case 13: return MRC.renameRequest.getDefaultInstance(); + case 14: return MRC.rmdirRequest.getDefaultInstance(); + case 15: return MRC.setattrRequest.getDefaultInstance(); + case 16: return MRC.setxattrRequest.getDefaultInstance(); + case 17: return MRC.statvfsRequest.getDefaultInstance(); + case 18: return MRC.symlinkRequest.getDefaultInstance(); + case 19: return MRC.unlinkRequest.getDefaultInstance(); + case 20: return MRC.accessRequest.getDefaultInstance(); + case 30: return null; + case 31: return MRC.xtreemfs_check_file_existsRequest.getDefaultInstance(); + case 32: return MRC.xtreemfs_dump_restore_databaseRequest.getDefaultInstance(); + case 33: return MRC.xtreemfs_get_suitable_osdsRequest.getDefaultInstance(); + case 34: return MRC.stringMessage.getDefaultInstance(); + case 35: return MRC.xtreemfs_listdirRequest.getDefaultInstance(); + case 36: return null; + case 47: return MRC.Volume.getDefaultInstance(); + case 37: return GlobalTypes.XCap.getDefaultInstance(); + case 38: return null; + case 39: return MRC.xtreemfs_replica_addRequest.getDefaultInstance(); + case 40: return MRC.xtreemfs_replica_listRequest.getDefaultInstance(); + case 41: return MRC.xtreemfs_replica_removeRequest.getDefaultInstance(); + case 42: return MRC.xtreemfs_dump_restore_databaseRequest.getDefaultInstance(); + case 43: return MRC.xtreemfs_restore_fileRequest.getDefaultInstance(); + case 44: return MRC.xtreemfs_rmvolRequest.getDefaultInstance(); + case 45: return null; + case 46: return MRC.xtreemfs_update_file_sizeRequest.getDefaultInstance(); + case 48: return MRC.xtreemfs_set_replica_update_policyRequest.getDefaultInstance(); + case 49: return MRC.xtreemfs_set_read_only_xattrRequest.getDefaultInstance(); + case 50: return MRC.xtreemfs_get_file_credentialsRequest.getDefaultInstance(); + case 51: return MRC.xtreemfs_get_xlocsetRequest.getDefaultInstance(); + default: throw new RuntimeException("unknown procedure id"); + } + } + + + public static Message getResponseMessage(int procId) { + switch (procId) { + case 2: return null; + case 3: return GlobalTypes.XCap.getDefaultInstance(); + case 4: return MRC.getattrResponse.getDefaultInstance(); + case 5: return MRC.getxattrResponse.getDefaultInstance(); + case 6: return MRC.timestampResponse.getDefaultInstance(); + case 7: return MRC.listxattrResponse.getDefaultInstance(); + case 8: return MRC.timestampResponse.getDefaultInstance(); + case 9: return MRC.openResponse.getDefaultInstance(); + case 10: return MRC.DirectoryEntries.getDefaultInstance(); + case 11: return MRC.readlinkResponse.getDefaultInstance(); + case 12: return MRC.timestampResponse.getDefaultInstance(); + case 13: return MRC.renameResponse.getDefaultInstance(); + case 14: return MRC.timestampResponse.getDefaultInstance(); + case 15: return MRC.timestampResponse.getDefaultInstance(); + case 16: return MRC.timestampResponse.getDefaultInstance(); + case 17: return MRC.StatVFS.getDefaultInstance(); + case 18: return MRC.timestampResponse.getDefaultInstance(); + case 19: return MRC.unlinkResponse.getDefaultInstance(); + case 20: return null; + case 30: return null; + case 31: return MRC.xtreemfs_check_file_existsResponse.getDefaultInstance(); + case 32: return null; + case 33: return MRC.xtreemfs_get_suitable_osdsResponse.getDefaultInstance(); + case 34: return MRC.stringMessage.getDefaultInstance(); + case 35: return MRC.xtreemfs_listdirResponse.getDefaultInstance(); + case 36: return MRC.Volumes.getDefaultInstance(); + case 47: return null; + case 37: return GlobalTypes.XCap.getDefaultInstance(); + case 38: return null; + case 39: return null; + case 40: return GlobalTypes.Replicas.getDefaultInstance(); + case 41: return GlobalTypes.FileCredentials.getDefaultInstance(); + case 42: return null; + case 43: return null; + case 44: return null; + case 45: return null; + case 46: return MRC.timestampResponse.getDefaultInstance(); + case 48: return MRC.xtreemfs_set_replica_update_policyResponse.getDefaultInstance(); + case 49: return MRC.xtreemfs_set_read_only_xattrResponse.getDefaultInstance(); + case 50: return GlobalTypes.FileCredentials.getDefaultInstance(); + case 51: return GlobalTypes.XLocSet.getDefaultInstance(); + default: throw new RuntimeException("unknown procedure id"); + } + } + + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSD.java b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSD.java new file mode 100644 index 0000000..0e4efc4 --- /dev/null +++ b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSD.java @@ -0,0 +1,33462 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: xtreemfs/OSD.proto + +package org.xtreemfs.pbrpc.generatedinterfaces; + +public final class OSD { + private OSD() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + /** + * Protobuf enum {@code xtreemfs.pbrpc.OSDHealthResult} + * + *
    +   * Status of OSD health test
    +   * 
    + */ + public enum OSDHealthResult + implements com.google.protobuf.ProtocolMessageEnum { + /** + * OSD_HEALTH_RESULT_PASSED = 0; + */ + OSD_HEALTH_RESULT_PASSED(0, 0), + /** + * OSD_HEALTH_RESULT_WARNING = 1; + */ + OSD_HEALTH_RESULT_WARNING(1, 1), + /** + * OSD_HEALTH_RESULT_FAILED = 2; + */ + OSD_HEALTH_RESULT_FAILED(2, 2), + /** + * OSD_HEALTH_RESULT_NOT_AVAIL = 3; + * + *
    +     * Status is not available,
    +     * i.e. the test is disabled or an error occurred
    +     * 
    + */ + OSD_HEALTH_RESULT_NOT_AVAIL(3, 3), + ; + + /** + * OSD_HEALTH_RESULT_PASSED = 0; + */ + public static final int OSD_HEALTH_RESULT_PASSED_VALUE = 0; + /** + * OSD_HEALTH_RESULT_WARNING = 1; + */ + public static final int OSD_HEALTH_RESULT_WARNING_VALUE = 1; + /** + * OSD_HEALTH_RESULT_FAILED = 2; + */ + public static final int OSD_HEALTH_RESULT_FAILED_VALUE = 2; + /** + * OSD_HEALTH_RESULT_NOT_AVAIL = 3; + * + *
    +     * Status is not available,
    +     * i.e. the test is disabled or an error occurred
    +     * 
    + */ + public static final int OSD_HEALTH_RESULT_NOT_AVAIL_VALUE = 3; + + + public final int getNumber() { return value; } + + public static OSDHealthResult valueOf(int value) { + switch (value) { + case 0: return OSD_HEALTH_RESULT_PASSED; + case 1: return OSD_HEALTH_RESULT_WARNING; + case 2: return OSD_HEALTH_RESULT_FAILED; + case 3: return OSD_HEALTH_RESULT_NOT_AVAIL; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public OSDHealthResult findValueByNumber(int number) { + return OSDHealthResult.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.getDescriptor().getEnumTypes().get(0); + } + + private static final OSDHealthResult[] VALUES = values(); + + public static OSDHealthResult valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private OSDHealthResult(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:xtreemfs.pbrpc.OSDHealthResult) + } + + public interface InternalGmaxOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 epoch = 1; + /** + * required fixed64 epoch = 1; + */ + boolean hasEpoch(); + /** + * required fixed64 epoch = 1; + */ + long getEpoch(); + + // required fixed64 file_size = 2; + /** + * required fixed64 file_size = 2; + */ + boolean hasFileSize(); + /** + * required fixed64 file_size = 2; + */ + long getFileSize(); + + // required fixed64 last_object_id = 3; + /** + * required fixed64 last_object_id = 3; + */ + boolean hasLastObjectId(); + /** + * required fixed64 last_object_id = 3; + */ + long getLastObjectId(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.InternalGmax} + * + *
    +   * Message sent between OSDs when the size of a striped file changes.
    +   * Optimization to reduce communication between servers for sparse files
    +   * and to handle EOF.
    +   * 
    + */ + public static final class InternalGmax extends + com.google.protobuf.GeneratedMessage + implements InternalGmaxOrBuilder { + // Use InternalGmax.newBuilder() to construct. + private InternalGmax(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private InternalGmax(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final InternalGmax defaultInstance; + public static InternalGmax getDefaultInstance() { + return defaultInstance; + } + + public InternalGmax getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private InternalGmax( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + epoch_ = input.readFixed64(); + break; + } + case 17: { + bitField0_ |= 0x00000002; + fileSize_ = input.readFixed64(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + lastObjectId_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_InternalGmax_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_InternalGmax_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public InternalGmax parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new InternalGmax(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 epoch = 1; + public static final int EPOCH_FIELD_NUMBER = 1; + private long epoch_; + /** + * required fixed64 epoch = 1; + */ + public boolean hasEpoch() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 epoch = 1; + */ + public long getEpoch() { + return epoch_; + } + + // required fixed64 file_size = 2; + public static final int FILE_SIZE_FIELD_NUMBER = 2; + private long fileSize_; + /** + * required fixed64 file_size = 2; + */ + public boolean hasFileSize() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 file_size = 2; + */ + public long getFileSize() { + return fileSize_; + } + + // required fixed64 last_object_id = 3; + public static final int LAST_OBJECT_ID_FIELD_NUMBER = 3; + private long lastObjectId_; + /** + * required fixed64 last_object_id = 3; + */ + public boolean hasLastObjectId() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 last_object_id = 3; + */ + public long getLastObjectId() { + return lastObjectId_; + } + + private void initFields() { + epoch_ = 0L; + fileSize_ = 0L; + lastObjectId_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasEpoch()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileSize()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLastObjectId()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, epoch_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(2, fileSize_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, lastObjectId_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, epoch_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(2, fileSize_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, lastObjectId_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.InternalGmax} + * + *
    +     * Message sent between OSDs when the size of a striped file changes.
    +     * Optimization to reduce communication between servers for sparse files
    +     * and to handle EOF.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmaxOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_InternalGmax_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_InternalGmax_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + epoch_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + fileSize_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + lastObjectId_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_InternalGmax_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.epoch_ = epoch_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileSize_ = fileSize_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.lastObjectId_ = lastObjectId_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax.getDefaultInstance()) return this; + if (other.hasEpoch()) { + setEpoch(other.getEpoch()); + } + if (other.hasFileSize()) { + setFileSize(other.getFileSize()); + } + if (other.hasLastObjectId()) { + setLastObjectId(other.getLastObjectId()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasEpoch()) { + + return false; + } + if (!hasFileSize()) { + + return false; + } + if (!hasLastObjectId()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalGmax) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 epoch = 1; + private long epoch_ ; + /** + * required fixed64 epoch = 1; + */ + public boolean hasEpoch() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 epoch = 1; + */ + public long getEpoch() { + return epoch_; + } + /** + * required fixed64 epoch = 1; + */ + public Builder setEpoch(long value) { + bitField0_ |= 0x00000001; + epoch_ = value; + onChanged(); + return this; + } + /** + * required fixed64 epoch = 1; + */ + public Builder clearEpoch() { + bitField0_ = (bitField0_ & ~0x00000001); + epoch_ = 0L; + onChanged(); + return this; + } + + // required fixed64 file_size = 2; + private long fileSize_ ; + /** + * required fixed64 file_size = 2; + */ + public boolean hasFileSize() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 file_size = 2; + */ + public long getFileSize() { + return fileSize_; + } + /** + * required fixed64 file_size = 2; + */ + public Builder setFileSize(long value) { + bitField0_ |= 0x00000002; + fileSize_ = value; + onChanged(); + return this; + } + /** + * required fixed64 file_size = 2; + */ + public Builder clearFileSize() { + bitField0_ = (bitField0_ & ~0x00000002); + fileSize_ = 0L; + onChanged(); + return this; + } + + // required fixed64 last_object_id = 3; + private long lastObjectId_ ; + /** + * required fixed64 last_object_id = 3; + */ + public boolean hasLastObjectId() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 last_object_id = 3; + */ + public long getLastObjectId() { + return lastObjectId_; + } + /** + * required fixed64 last_object_id = 3; + */ + public Builder setLastObjectId(long value) { + bitField0_ |= 0x00000004; + lastObjectId_ = value; + onChanged(); + return this; + } + /** + * required fixed64 last_object_id = 3; + */ + public Builder clearLastObjectId() { + bitField0_ = (bitField0_ & ~0x00000004); + lastObjectId_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.InternalGmax) + } + + static { + defaultInstance = new InternalGmax(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.InternalGmax) + } + + public interface LockOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed32 client_pid = 1; + /** + * required fixed32 client_pid = 1; + * + *
    +     * Process ID, must be unique per client,
    +     * i.e. client_pid+uuid must be globally unique.
    +     * 
    + */ + boolean hasClientPid(); + /** + * required fixed32 client_pid = 1; + * + *
    +     * Process ID, must be unique per client,
    +     * i.e. client_pid+uuid must be globally unique.
    +     * 
    + */ + int getClientPid(); + + // required string client_uuid = 2; + /** + * required string client_uuid = 2; + * + *
    +     * UUID for client, can be temporary.
    +     * 
    + */ + boolean hasClientUuid(); + /** + * required string client_uuid = 2; + * + *
    +     * UUID for client, can be temporary.
    +     * 
    + */ + java.lang.String getClientUuid(); + /** + * required string client_uuid = 2; + * + *
    +     * UUID for client, can be temporary.
    +     * 
    + */ + com.google.protobuf.ByteString + getClientUuidBytes(); + + // required fixed64 length = 3; + /** + * required fixed64 length = 3; + * + *
    +     * Length of byte range for the lock.
    +     * 
    + */ + boolean hasLength(); + /** + * required fixed64 length = 3; + * + *
    +     * Length of byte range for the lock.
    +     * 
    + */ + long getLength(); + + // required fixed64 offset = 4; + /** + * required fixed64 offset = 4; + * + *
    +     * Offset of the locked byte range.
    +     * 
    + */ + boolean hasOffset(); + /** + * required fixed64 offset = 4; + * + *
    +     * Offset of the locked byte range.
    +     * 
    + */ + long getOffset(); + + // required bool exclusive = 5; + /** + * required bool exclusive = 5; + * + *
    +     * If true, lock is exclusive.
    +     * 
    + */ + boolean hasExclusive(); + /** + * required bool exclusive = 5; + * + *
    +     * If true, lock is exclusive.
    +     * 
    + */ + boolean getExclusive(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Lock} + * + *
    +   * POSIX file lock.
    +   * 
    + */ + public static final class Lock extends + com.google.protobuf.GeneratedMessage + implements LockOrBuilder { + // Use Lock.newBuilder() to construct. + private Lock(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Lock(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Lock defaultInstance; + public static Lock getDefaultInstance() { + return defaultInstance; + } + + public Lock getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Lock( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 13: { + bitField0_ |= 0x00000001; + clientPid_ = input.readFixed32(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + clientUuid_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + length_ = input.readFixed64(); + break; + } + case 33: { + bitField0_ |= 0x00000008; + offset_ = input.readFixed64(); + break; + } + case 40: { + bitField0_ |= 0x00000010; + exclusive_ = input.readBool(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_Lock_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_Lock_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Lock parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Lock(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed32 client_pid = 1; + public static final int CLIENT_PID_FIELD_NUMBER = 1; + private int clientPid_; + /** + * required fixed32 client_pid = 1; + * + *
    +     * Process ID, must be unique per client,
    +     * i.e. client_pid+uuid must be globally unique.
    +     * 
    + */ + public boolean hasClientPid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 client_pid = 1; + * + *
    +     * Process ID, must be unique per client,
    +     * i.e. client_pid+uuid must be globally unique.
    +     * 
    + */ + public int getClientPid() { + return clientPid_; + } + + // required string client_uuid = 2; + public static final int CLIENT_UUID_FIELD_NUMBER = 2; + private java.lang.Object clientUuid_; + /** + * required string client_uuid = 2; + * + *
    +     * UUID for client, can be temporary.
    +     * 
    + */ + public boolean hasClientUuid() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string client_uuid = 2; + * + *
    +     * UUID for client, can be temporary.
    +     * 
    + */ + public java.lang.String getClientUuid() { + java.lang.Object ref = clientUuid_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clientUuid_ = s; + } + return s; + } + } + /** + * required string client_uuid = 2; + * + *
    +     * UUID for client, can be temporary.
    +     * 
    + */ + public com.google.protobuf.ByteString + getClientUuidBytes() { + java.lang.Object ref = clientUuid_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clientUuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 length = 3; + public static final int LENGTH_FIELD_NUMBER = 3; + private long length_; + /** + * required fixed64 length = 3; + * + *
    +     * Length of byte range for the lock.
    +     * 
    + */ + public boolean hasLength() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 length = 3; + * + *
    +     * Length of byte range for the lock.
    +     * 
    + */ + public long getLength() { + return length_; + } + + // required fixed64 offset = 4; + public static final int OFFSET_FIELD_NUMBER = 4; + private long offset_; + /** + * required fixed64 offset = 4; + * + *
    +     * Offset of the locked byte range.
    +     * 
    + */ + public boolean hasOffset() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 offset = 4; + * + *
    +     * Offset of the locked byte range.
    +     * 
    + */ + public long getOffset() { + return offset_; + } + + // required bool exclusive = 5; + public static final int EXCLUSIVE_FIELD_NUMBER = 5; + private boolean exclusive_; + /** + * required bool exclusive = 5; + * + *
    +     * If true, lock is exclusive.
    +     * 
    + */ + public boolean hasExclusive() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required bool exclusive = 5; + * + *
    +     * If true, lock is exclusive.
    +     * 
    + */ + public boolean getExclusive() { + return exclusive_; + } + + private void initFields() { + clientPid_ = 0; + clientUuid_ = ""; + length_ = 0L; + offset_ = 0L; + exclusive_ = false; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasClientPid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasClientUuid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLength()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOffset()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasExclusive()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed32(1, clientPid_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getClientUuidBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, length_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed64(4, offset_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeBool(5, exclusive_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(1, clientPid_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getClientUuidBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, length_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(4, offset_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(5, exclusive_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.Lock} + * + *
    +     * POSIX file lock.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.LockOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_Lock_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_Lock_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + clientPid_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + clientUuid_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + length_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + offset_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + exclusive_ = false; + bitField0_ = (bitField0_ & ~0x00000010); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_Lock_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.clientPid_ = clientPid_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.clientUuid_ = clientUuid_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.length_ = length_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.offset_ = offset_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.exclusive_ = exclusive_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.getDefaultInstance()) return this; + if (other.hasClientPid()) { + setClientPid(other.getClientPid()); + } + if (other.hasClientUuid()) { + bitField0_ |= 0x00000002; + clientUuid_ = other.clientUuid_; + onChanged(); + } + if (other.hasLength()) { + setLength(other.getLength()); + } + if (other.hasOffset()) { + setOffset(other.getOffset()); + } + if (other.hasExclusive()) { + setExclusive(other.getExclusive()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasClientPid()) { + + return false; + } + if (!hasClientUuid()) { + + return false; + } + if (!hasLength()) { + + return false; + } + if (!hasOffset()) { + + return false; + } + if (!hasExclusive()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed32 client_pid = 1; + private int clientPid_ ; + /** + * required fixed32 client_pid = 1; + * + *
    +       * Process ID, must be unique per client,
    +       * i.e. client_pid+uuid must be globally unique.
    +       * 
    + */ + public boolean hasClientPid() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 client_pid = 1; + * + *
    +       * Process ID, must be unique per client,
    +       * i.e. client_pid+uuid must be globally unique.
    +       * 
    + */ + public int getClientPid() { + return clientPid_; + } + /** + * required fixed32 client_pid = 1; + * + *
    +       * Process ID, must be unique per client,
    +       * i.e. client_pid+uuid must be globally unique.
    +       * 
    + */ + public Builder setClientPid(int value) { + bitField0_ |= 0x00000001; + clientPid_ = value; + onChanged(); + return this; + } + /** + * required fixed32 client_pid = 1; + * + *
    +       * Process ID, must be unique per client,
    +       * i.e. client_pid+uuid must be globally unique.
    +       * 
    + */ + public Builder clearClientPid() { + bitField0_ = (bitField0_ & ~0x00000001); + clientPid_ = 0; + onChanged(); + return this; + } + + // required string client_uuid = 2; + private java.lang.Object clientUuid_ = ""; + /** + * required string client_uuid = 2; + * + *
    +       * UUID for client, can be temporary.
    +       * 
    + */ + public boolean hasClientUuid() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string client_uuid = 2; + * + *
    +       * UUID for client, can be temporary.
    +       * 
    + */ + public java.lang.String getClientUuid() { + java.lang.Object ref = clientUuid_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + clientUuid_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string client_uuid = 2; + * + *
    +       * UUID for client, can be temporary.
    +       * 
    + */ + public com.google.protobuf.ByteString + getClientUuidBytes() { + java.lang.Object ref = clientUuid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clientUuid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string client_uuid = 2; + * + *
    +       * UUID for client, can be temporary.
    +       * 
    + */ + public Builder setClientUuid( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clientUuid_ = value; + onChanged(); + return this; + } + /** + * required string client_uuid = 2; + * + *
    +       * UUID for client, can be temporary.
    +       * 
    + */ + public Builder clearClientUuid() { + bitField0_ = (bitField0_ & ~0x00000002); + clientUuid_ = getDefaultInstance().getClientUuid(); + onChanged(); + return this; + } + /** + * required string client_uuid = 2; + * + *
    +       * UUID for client, can be temporary.
    +       * 
    + */ + public Builder setClientUuidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clientUuid_ = value; + onChanged(); + return this; + } + + // required fixed64 length = 3; + private long length_ ; + /** + * required fixed64 length = 3; + * + *
    +       * Length of byte range for the lock.
    +       * 
    + */ + public boolean hasLength() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 length = 3; + * + *
    +       * Length of byte range for the lock.
    +       * 
    + */ + public long getLength() { + return length_; + } + /** + * required fixed64 length = 3; + * + *
    +       * Length of byte range for the lock.
    +       * 
    + */ + public Builder setLength(long value) { + bitField0_ |= 0x00000004; + length_ = value; + onChanged(); + return this; + } + /** + * required fixed64 length = 3; + * + *
    +       * Length of byte range for the lock.
    +       * 
    + */ + public Builder clearLength() { + bitField0_ = (bitField0_ & ~0x00000004); + length_ = 0L; + onChanged(); + return this; + } + + // required fixed64 offset = 4; + private long offset_ ; + /** + * required fixed64 offset = 4; + * + *
    +       * Offset of the locked byte range.
    +       * 
    + */ + public boolean hasOffset() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 offset = 4; + * + *
    +       * Offset of the locked byte range.
    +       * 
    + */ + public long getOffset() { + return offset_; + } + /** + * required fixed64 offset = 4; + * + *
    +       * Offset of the locked byte range.
    +       * 
    + */ + public Builder setOffset(long value) { + bitField0_ |= 0x00000008; + offset_ = value; + onChanged(); + return this; + } + /** + * required fixed64 offset = 4; + * + *
    +       * Offset of the locked byte range.
    +       * 
    + */ + public Builder clearOffset() { + bitField0_ = (bitField0_ & ~0x00000008); + offset_ = 0L; + onChanged(); + return this; + } + + // required bool exclusive = 5; + private boolean exclusive_ ; + /** + * required bool exclusive = 5; + * + *
    +       * If true, lock is exclusive.
    +       * 
    + */ + public boolean hasExclusive() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required bool exclusive = 5; + * + *
    +       * If true, lock is exclusive.
    +       * 
    + */ + public boolean getExclusive() { + return exclusive_; + } + /** + * required bool exclusive = 5; + * + *
    +       * If true, lock is exclusive.
    +       * 
    + */ + public Builder setExclusive(boolean value) { + bitField0_ |= 0x00000010; + exclusive_ = value; + onChanged(); + return this; + } + /** + * required bool exclusive = 5; + * + *
    +       * If true, lock is exclusive.
    +       * 
    + */ + public Builder clearExclusive() { + bitField0_ = (bitField0_ & ~0x00000010); + exclusive_ = false; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.Lock) + } + + static { + defaultInstance = new Lock(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.Lock) + } + + public interface ObjectDataOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed32 checksum = 1; + /** + * required fixed32 checksum = 1; + * + *
    +     * Data checksum (Adler32), if checksums are enabled.
    +     * 
    + */ + boolean hasChecksum(); + /** + * required fixed32 checksum = 1; + * + *
    +     * Data checksum (Adler32), if checksums are enabled.
    +     * 
    + */ + int getChecksum(); + + // required bool invalid_checksum_on_osd = 2; + /** + * required bool invalid_checksum_on_osd = 2; + * + *
    +     * True, if the checksum doesn't match the data on the OSD.
    +     * 
    + */ + boolean hasInvalidChecksumOnOsd(); + /** + * required bool invalid_checksum_on_osd = 2; + * + *
    +     * True, if the checksum doesn't match the data on the OSD.
    +     * 
    + */ + boolean getInvalidChecksumOnOsd(); + + // required fixed32 zero_padding = 3; + /** + * required fixed32 zero_padding = 3; + * + *
    +     * Number of zeros the client must append to data before delivering
    +     * data to an application (for sparse files).
    +     * When returned by the xtreemfs_check_object method
    +     * it stores the total number of bytes(data + sparse data)
    +     * 
    + */ + boolean hasZeroPadding(); + /** + * required fixed32 zero_padding = 3; + * + *
    +     * Number of zeros the client must append to data before delivering
    +     * data to an application (for sparse files).
    +     * When returned by the xtreemfs_check_object method
    +     * it stores the total number of bytes(data + sparse data)
    +     * 
    + */ + int getZeroPadding(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ObjectData} + * + *
    +   * Contains details on object data which is now sent in
    +   * the data fragment of the RPC protocol.
    +   * 
    + */ + public static final class ObjectData extends + com.google.protobuf.GeneratedMessage + implements ObjectDataOrBuilder { + // Use ObjectData.newBuilder() to construct. + private ObjectData(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ObjectData(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final ObjectData defaultInstance; + public static ObjectData getDefaultInstance() { + return defaultInstance; + } + + public ObjectData getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ObjectData( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 13: { + bitField0_ |= 0x00000001; + checksum_ = input.readFixed32(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + invalidChecksumOnOsd_ = input.readBool(); + break; + } + case 29: { + bitField0_ |= 0x00000004; + zeroPadding_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectData_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectData_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public ObjectData parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ObjectData(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed32 checksum = 1; + public static final int CHECKSUM_FIELD_NUMBER = 1; + private int checksum_; + /** + * required fixed32 checksum = 1; + * + *
    +     * Data checksum (Adler32), if checksums are enabled.
    +     * 
    + */ + public boolean hasChecksum() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 checksum = 1; + * + *
    +     * Data checksum (Adler32), if checksums are enabled.
    +     * 
    + */ + public int getChecksum() { + return checksum_; + } + + // required bool invalid_checksum_on_osd = 2; + public static final int INVALID_CHECKSUM_ON_OSD_FIELD_NUMBER = 2; + private boolean invalidChecksumOnOsd_; + /** + * required bool invalid_checksum_on_osd = 2; + * + *
    +     * True, if the checksum doesn't match the data on the OSD.
    +     * 
    + */ + public boolean hasInvalidChecksumOnOsd() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool invalid_checksum_on_osd = 2; + * + *
    +     * True, if the checksum doesn't match the data on the OSD.
    +     * 
    + */ + public boolean getInvalidChecksumOnOsd() { + return invalidChecksumOnOsd_; + } + + // required fixed32 zero_padding = 3; + public static final int ZERO_PADDING_FIELD_NUMBER = 3; + private int zeroPadding_; + /** + * required fixed32 zero_padding = 3; + * + *
    +     * Number of zeros the client must append to data before delivering
    +     * data to an application (for sparse files).
    +     * When returned by the xtreemfs_check_object method
    +     * it stores the total number of bytes(data + sparse data)
    +     * 
    + */ + public boolean hasZeroPadding() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 zero_padding = 3; + * + *
    +     * Number of zeros the client must append to data before delivering
    +     * data to an application (for sparse files).
    +     * When returned by the xtreemfs_check_object method
    +     * it stores the total number of bytes(data + sparse data)
    +     * 
    + */ + public int getZeroPadding() { + return zeroPadding_; + } + + private void initFields() { + checksum_ = 0; + invalidChecksumOnOsd_ = false; + zeroPadding_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasChecksum()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasInvalidChecksumOnOsd()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasZeroPadding()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed32(1, checksum_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBool(2, invalidChecksumOnOsd_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed32(3, zeroPadding_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(1, checksum_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(2, invalidChecksumOnOsd_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(3, zeroPadding_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ObjectData} + * + *
    +     * Contains details on object data which is now sent in
    +     * the data fragment of the RPC protocol.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectData_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectData_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + checksum_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + invalidChecksumOnOsd_ = false; + bitField0_ = (bitField0_ & ~0x00000002); + zeroPadding_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectData_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.checksum_ = checksum_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.invalidChecksumOnOsd_ = invalidChecksumOnOsd_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.zeroPadding_ = zeroPadding_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance()) return this; + if (other.hasChecksum()) { + setChecksum(other.getChecksum()); + } + if (other.hasInvalidChecksumOnOsd()) { + setInvalidChecksumOnOsd(other.getInvalidChecksumOnOsd()); + } + if (other.hasZeroPadding()) { + setZeroPadding(other.getZeroPadding()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasChecksum()) { + + return false; + } + if (!hasInvalidChecksumOnOsd()) { + + return false; + } + if (!hasZeroPadding()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed32 checksum = 1; + private int checksum_ ; + /** + * required fixed32 checksum = 1; + * + *
    +       * Data checksum (Adler32), if checksums are enabled.
    +       * 
    + */ + public boolean hasChecksum() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 checksum = 1; + * + *
    +       * Data checksum (Adler32), if checksums are enabled.
    +       * 
    + */ + public int getChecksum() { + return checksum_; + } + /** + * required fixed32 checksum = 1; + * + *
    +       * Data checksum (Adler32), if checksums are enabled.
    +       * 
    + */ + public Builder setChecksum(int value) { + bitField0_ |= 0x00000001; + checksum_ = value; + onChanged(); + return this; + } + /** + * required fixed32 checksum = 1; + * + *
    +       * Data checksum (Adler32), if checksums are enabled.
    +       * 
    + */ + public Builder clearChecksum() { + bitField0_ = (bitField0_ & ~0x00000001); + checksum_ = 0; + onChanged(); + return this; + } + + // required bool invalid_checksum_on_osd = 2; + private boolean invalidChecksumOnOsd_ ; + /** + * required bool invalid_checksum_on_osd = 2; + * + *
    +       * True, if the checksum doesn't match the data on the OSD.
    +       * 
    + */ + public boolean hasInvalidChecksumOnOsd() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool invalid_checksum_on_osd = 2; + * + *
    +       * True, if the checksum doesn't match the data on the OSD.
    +       * 
    + */ + public boolean getInvalidChecksumOnOsd() { + return invalidChecksumOnOsd_; + } + /** + * required bool invalid_checksum_on_osd = 2; + * + *
    +       * True, if the checksum doesn't match the data on the OSD.
    +       * 
    + */ + public Builder setInvalidChecksumOnOsd(boolean value) { + bitField0_ |= 0x00000002; + invalidChecksumOnOsd_ = value; + onChanged(); + return this; + } + /** + * required bool invalid_checksum_on_osd = 2; + * + *
    +       * True, if the checksum doesn't match the data on the OSD.
    +       * 
    + */ + public Builder clearInvalidChecksumOnOsd() { + bitField0_ = (bitField0_ & ~0x00000002); + invalidChecksumOnOsd_ = false; + onChanged(); + return this; + } + + // required fixed32 zero_padding = 3; + private int zeroPadding_ ; + /** + * required fixed32 zero_padding = 3; + * + *
    +       * Number of zeros the client must append to data before delivering
    +       * data to an application (for sparse files).
    +       * When returned by the xtreemfs_check_object method
    +       * it stores the total number of bytes(data + sparse data)
    +       * 
    + */ + public boolean hasZeroPadding() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 zero_padding = 3; + * + *
    +       * Number of zeros the client must append to data before delivering
    +       * data to an application (for sparse files).
    +       * When returned by the xtreemfs_check_object method
    +       * it stores the total number of bytes(data + sparse data)
    +       * 
    + */ + public int getZeroPadding() { + return zeroPadding_; + } + /** + * required fixed32 zero_padding = 3; + * + *
    +       * Number of zeros the client must append to data before delivering
    +       * data to an application (for sparse files).
    +       * When returned by the xtreemfs_check_object method
    +       * it stores the total number of bytes(data + sparse data)
    +       * 
    + */ + public Builder setZeroPadding(int value) { + bitField0_ |= 0x00000004; + zeroPadding_ = value; + onChanged(); + return this; + } + /** + * required fixed32 zero_padding = 3; + * + *
    +       * Number of zeros the client must append to data before delivering
    +       * data to an application (for sparse files).
    +       * When returned by the xtreemfs_check_object method
    +       * it stores the total number of bytes(data + sparse data)
    +       * 
    + */ + public Builder clearZeroPadding() { + bitField0_ = (bitField0_ & ~0x00000004); + zeroPadding_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.ObjectData) + } + + static { + defaultInstance = new ObjectData(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ObjectData) + } + + public interface ObjectListOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required bytes set = 1; + /** + * required bytes set = 1; + * + *
    +     * serialized data type
    +     * 
    + */ + boolean hasSet(); + /** + * required bytes set = 1; + * + *
    +     * serialized data type
    +     * 
    + */ + com.google.protobuf.ByteString getSet(); + + // required fixed32 stripe_width = 2; + /** + * required fixed32 stripe_width = 2; + */ + boolean hasStripeWidth(); + /** + * required fixed32 stripe_width = 2; + */ + int getStripeWidth(); + + // required fixed32 first_ = 3; + /** + * required fixed32 first_ = 3; + */ + boolean hasFirst(); + /** + * required fixed32 first_ = 3; + */ + int getFirst(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ObjectList} + * + *
    +   * List of objects which an OSD has stored locally.
    +   * Used by the read-only replication to optimize
    +   * fetching of missing objects.
    +   * 
    + */ + public static final class ObjectList extends + com.google.protobuf.GeneratedMessage + implements ObjectListOrBuilder { + // Use ObjectList.newBuilder() to construct. + private ObjectList(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ObjectList(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final ObjectList defaultInstance; + public static ObjectList getDefaultInstance() { + return defaultInstance; + } + + public ObjectList getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ObjectList( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + set_ = input.readBytes(); + break; + } + case 21: { + bitField0_ |= 0x00000002; + stripeWidth_ = input.readFixed32(); + break; + } + case 29: { + bitField0_ |= 0x00000004; + first_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectList_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectList_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public ObjectList parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ObjectList(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required bytes set = 1; + public static final int SET_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString set_; + /** + * required bytes set = 1; + * + *
    +     * serialized data type
    +     * 
    + */ + public boolean hasSet() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required bytes set = 1; + * + *
    +     * serialized data type
    +     * 
    + */ + public com.google.protobuf.ByteString getSet() { + return set_; + } + + // required fixed32 stripe_width = 2; + public static final int STRIPE_WIDTH_FIELD_NUMBER = 2; + private int stripeWidth_; + /** + * required fixed32 stripe_width = 2; + */ + public boolean hasStripeWidth() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 stripe_width = 2; + */ + public int getStripeWidth() { + return stripeWidth_; + } + + // required fixed32 first_ = 3; + public static final int FIRST__FIELD_NUMBER = 3; + private int first_; + /** + * required fixed32 first_ = 3; + */ + public boolean hasFirst() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 first_ = 3; + */ + public int getFirst() { + return first_; + } + + private void initFields() { + set_ = com.google.protobuf.ByteString.EMPTY; + stripeWidth_ = 0; + first_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasSet()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasStripeWidth()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFirst()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, set_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed32(2, stripeWidth_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed32(3, first_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, set_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(2, stripeWidth_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(3, first_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ObjectList} + * + *
    +     * List of objects which an OSD has stored locally.
    +     * Used by the read-only replication to optimize
    +     * fetching of missing objects.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectList_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectList_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + set_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + stripeWidth_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + first_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectList_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.set_ = set_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.stripeWidth_ = stripeWidth_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.first_ = first_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.getDefaultInstance()) return this; + if (other.hasSet()) { + setSet(other.getSet()); + } + if (other.hasStripeWidth()) { + setStripeWidth(other.getStripeWidth()); + } + if (other.hasFirst()) { + setFirst(other.getFirst()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasSet()) { + + return false; + } + if (!hasStripeWidth()) { + + return false; + } + if (!hasFirst()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required bytes set = 1; + private com.google.protobuf.ByteString set_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes set = 1; + * + *
    +       * serialized data type
    +       * 
    + */ + public boolean hasSet() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required bytes set = 1; + * + *
    +       * serialized data type
    +       * 
    + */ + public com.google.protobuf.ByteString getSet() { + return set_; + } + /** + * required bytes set = 1; + * + *
    +       * serialized data type
    +       * 
    + */ + public Builder setSet(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + set_ = value; + onChanged(); + return this; + } + /** + * required bytes set = 1; + * + *
    +       * serialized data type
    +       * 
    + */ + public Builder clearSet() { + bitField0_ = (bitField0_ & ~0x00000001); + set_ = getDefaultInstance().getSet(); + onChanged(); + return this; + } + + // required fixed32 stripe_width = 2; + private int stripeWidth_ ; + /** + * required fixed32 stripe_width = 2; + */ + public boolean hasStripeWidth() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 stripe_width = 2; + */ + public int getStripeWidth() { + return stripeWidth_; + } + /** + * required fixed32 stripe_width = 2; + */ + public Builder setStripeWidth(int value) { + bitField0_ |= 0x00000002; + stripeWidth_ = value; + onChanged(); + return this; + } + /** + * required fixed32 stripe_width = 2; + */ + public Builder clearStripeWidth() { + bitField0_ = (bitField0_ & ~0x00000002); + stripeWidth_ = 0; + onChanged(); + return this; + } + + // required fixed32 first_ = 3; + private int first_ ; + /** + * required fixed32 first_ = 3; + */ + public boolean hasFirst() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 first_ = 3; + */ + public int getFirst() { + return first_; + } + /** + * required fixed32 first_ = 3; + */ + public Builder setFirst(int value) { + bitField0_ |= 0x00000004; + first_ = value; + onChanged(); + return this; + } + /** + * required fixed32 first_ = 3; + */ + public Builder clearFirst() { + bitField0_ = (bitField0_ & ~0x00000004); + first_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.ObjectList) + } + + static { + defaultInstance = new ObjectList(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ObjectList) + } + + public interface ObjectVersionOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 object_number = 1; + /** + * required fixed64 object_number = 1; + */ + boolean hasObjectNumber(); + /** + * required fixed64 object_number = 1; + */ + long getObjectNumber(); + + // required fixed64 object_version = 2; + /** + * required fixed64 object_version = 2; + */ + boolean hasObjectVersion(); + /** + * required fixed64 object_version = 2; + */ + long getObjectVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ObjectVersion} + * + *
    +   * Version information for an object.
    +   * Used to generate a mapping from object_number
    +   * to object_version. Used by the read-write replication.
    +   * 
    + */ + public static final class ObjectVersion extends + com.google.protobuf.GeneratedMessage + implements ObjectVersionOrBuilder { + // Use ObjectVersion.newBuilder() to construct. + private ObjectVersion(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ObjectVersion(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final ObjectVersion defaultInstance; + public static ObjectVersion getDefaultInstance() { + return defaultInstance; + } + + public ObjectVersion getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ObjectVersion( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + objectNumber_ = input.readFixed64(); + break; + } + case 17: { + bitField0_ |= 0x00000002; + objectVersion_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectVersion_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectVersion_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public ObjectVersion parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ObjectVersion(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 object_number = 1; + public static final int OBJECT_NUMBER_FIELD_NUMBER = 1; + private long objectNumber_; + /** + * required fixed64 object_number = 1; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 object_number = 1; + */ + public long getObjectNumber() { + return objectNumber_; + } + + // required fixed64 object_version = 2; + public static final int OBJECT_VERSION_FIELD_NUMBER = 2; + private long objectVersion_; + /** + * required fixed64 object_version = 2; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 object_version = 2; + */ + public long getObjectVersion() { + return objectVersion_; + } + + private void initFields() { + objectNumber_ = 0L; + objectVersion_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasObjectNumber()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectVersion()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, objectNumber_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(2, objectVersion_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, objectNumber_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(2, objectVersion_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ObjectVersion} + * + *
    +     * Version information for an object.
    +     * Used to generate a mapping from object_number
    +     * to object_version. Used by the read-write replication.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectVersion_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectVersion_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + objectNumber_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + objectVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectVersion_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.objectNumber_ = objectNumber_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.objectVersion_ = objectVersion_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.getDefaultInstance()) return this; + if (other.hasObjectNumber()) { + setObjectNumber(other.getObjectNumber()); + } + if (other.hasObjectVersion()) { + setObjectVersion(other.getObjectVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasObjectNumber()) { + + return false; + } + if (!hasObjectVersion()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 object_number = 1; + private long objectNumber_ ; + /** + * required fixed64 object_number = 1; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 object_number = 1; + */ + public long getObjectNumber() { + return objectNumber_; + } + /** + * required fixed64 object_number = 1; + */ + public Builder setObjectNumber(long value) { + bitField0_ |= 0x00000001; + objectNumber_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_number = 1; + */ + public Builder clearObjectNumber() { + bitField0_ = (bitField0_ & ~0x00000001); + objectNumber_ = 0L; + onChanged(); + return this; + } + + // required fixed64 object_version = 2; + private long objectVersion_ ; + /** + * required fixed64 object_version = 2; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 object_version = 2; + */ + public long getObjectVersion() { + return objectVersion_; + } + /** + * required fixed64 object_version = 2; + */ + public Builder setObjectVersion(long value) { + bitField0_ |= 0x00000002; + objectVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_version = 2; + */ + public Builder clearObjectVersion() { + bitField0_ = (bitField0_ & ~0x00000002); + objectVersion_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.ObjectVersion) + } + + static { + defaultInstance = new ObjectVersion(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ObjectVersion) + } + + public interface TruncateRecordOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 version = 1; + /** + * required fixed64 version = 1; + */ + boolean hasVersion(); + /** + * required fixed64 version = 1; + */ + long getVersion(); + + // required fixed64 last_object_number = 2; + /** + * required fixed64 last_object_number = 2; + */ + boolean hasLastObjectNumber(); + /** + * required fixed64 last_object_number = 2; + */ + long getLastObjectNumber(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.TruncateRecord} + * + *
    +   * Entry for the truncate log required by the read-write
    +   * replication. For each truncate, a version number is
    +   * assigned and a record is appended to the truncate log.
    +   * 
    + */ + public static final class TruncateRecord extends + com.google.protobuf.GeneratedMessage + implements TruncateRecordOrBuilder { + // Use TruncateRecord.newBuilder() to construct. + private TruncateRecord(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private TruncateRecord(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final TruncateRecord defaultInstance; + public static TruncateRecord getDefaultInstance() { + return defaultInstance; + } + + public TruncateRecord getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private TruncateRecord( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + version_ = input.readFixed64(); + break; + } + case 17: { + bitField0_ |= 0x00000002; + lastObjectNumber_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_TruncateRecord_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_TruncateRecord_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public TruncateRecord parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new TruncateRecord(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 version = 1; + public static final int VERSION_FIELD_NUMBER = 1; + private long version_; + /** + * required fixed64 version = 1; + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 version = 1; + */ + public long getVersion() { + return version_; + } + + // required fixed64 last_object_number = 2; + public static final int LAST_OBJECT_NUMBER_FIELD_NUMBER = 2; + private long lastObjectNumber_; + /** + * required fixed64 last_object_number = 2; + */ + public boolean hasLastObjectNumber() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 last_object_number = 2; + */ + public long getLastObjectNumber() { + return lastObjectNumber_; + } + + private void initFields() { + version_ = 0L; + lastObjectNumber_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLastObjectNumber()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, version_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(2, lastObjectNumber_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, version_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(2, lastObjectNumber_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.TruncateRecord} + * + *
    +     * Entry for the truncate log required by the read-write
    +     * replication. For each truncate, a version number is
    +     * assigned and a record is appended to the truncate log.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecordOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_TruncateRecord_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_TruncateRecord_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + version_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + lastObjectNumber_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_TruncateRecord_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.version_ = version_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.lastObjectNumber_ = lastObjectNumber_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.getDefaultInstance()) return this; + if (other.hasVersion()) { + setVersion(other.getVersion()); + } + if (other.hasLastObjectNumber()) { + setLastObjectNumber(other.getLastObjectNumber()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVersion()) { + + return false; + } + if (!hasLastObjectNumber()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 version = 1; + private long version_ ; + /** + * required fixed64 version = 1; + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 version = 1; + */ + public long getVersion() { + return version_; + } + /** + * required fixed64 version = 1; + */ + public Builder setVersion(long value) { + bitField0_ |= 0x00000001; + version_ = value; + onChanged(); + return this; + } + /** + * required fixed64 version = 1; + */ + public Builder clearVersion() { + bitField0_ = (bitField0_ & ~0x00000001); + version_ = 0L; + onChanged(); + return this; + } + + // required fixed64 last_object_number = 2; + private long lastObjectNumber_ ; + /** + * required fixed64 last_object_number = 2; + */ + public boolean hasLastObjectNumber() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 last_object_number = 2; + */ + public long getLastObjectNumber() { + return lastObjectNumber_; + } + /** + * required fixed64 last_object_number = 2; + */ + public Builder setLastObjectNumber(long value) { + bitField0_ |= 0x00000002; + lastObjectNumber_ = value; + onChanged(); + return this; + } + /** + * required fixed64 last_object_number = 2; + */ + public Builder clearLastObjectNumber() { + bitField0_ = (bitField0_ & ~0x00000002); + lastObjectNumber_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.TruncateRecord) + } + + static { + defaultInstance = new TruncateRecord(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.TruncateRecord) + } + + public interface TruncateLogOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + java.util.List + getRecordsList(); + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord getRecords(int index); + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + int getRecordsCount(); + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + java.util.List + getRecordsOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecordOrBuilder getRecordsOrBuilder( + int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.TruncateLog} + */ + public static final class TruncateLog extends + com.google.protobuf.GeneratedMessage + implements TruncateLogOrBuilder { + // Use TruncateLog.newBuilder() to construct. + private TruncateLog(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private TruncateLog(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final TruncateLog defaultInstance; + public static TruncateLog getDefaultInstance() { + return defaultInstance; + } + + public TruncateLog getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private TruncateLog( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + records_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + records_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + records_ = java.util.Collections.unmodifiableList(records_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_TruncateLog_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_TruncateLog_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public TruncateLog parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new TruncateLog(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + public static final int RECORDS_FIELD_NUMBER = 1; + private java.util.List records_; + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public java.util.List getRecordsList() { + return records_; + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public java.util.List + getRecordsOrBuilderList() { + return records_; + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public int getRecordsCount() { + return records_.size(); + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord getRecords(int index) { + return records_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecordOrBuilder getRecordsOrBuilder( + int index) { + return records_.get(index); + } + + private void initFields() { + records_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + for (int i = 0; i < getRecordsCount(); i++) { + if (!getRecords(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < records_.size(); i++) { + output.writeMessage(1, records_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < records_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, records_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.TruncateLog} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_TruncateLog_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_TruncateLog_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getRecordsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (recordsBuilder_ == null) { + records_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + recordsBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_TruncateLog_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog(this); + int from_bitField0_ = bitField0_; + if (recordsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001)) { + records_ = java.util.Collections.unmodifiableList(records_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.records_ = records_; + } else { + result.records_ = recordsBuilder_.build(); + } + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance()) return this; + if (recordsBuilder_ == null) { + if (!other.records_.isEmpty()) { + if (records_.isEmpty()) { + records_ = other.records_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureRecordsIsMutable(); + records_.addAll(other.records_); + } + onChanged(); + } + } else { + if (!other.records_.isEmpty()) { + if (recordsBuilder_.isEmpty()) { + recordsBuilder_.dispose(); + recordsBuilder_ = null; + records_ = other.records_; + bitField0_ = (bitField0_ & ~0x00000001); + recordsBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getRecordsFieldBuilder() : null; + } else { + recordsBuilder_.addAllMessages(other.records_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + for (int i = 0; i < getRecordsCount(); i++) { + if (!getRecords(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + private java.util.List records_ = + java.util.Collections.emptyList(); + private void ensureRecordsIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + records_ = new java.util.ArrayList(records_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecordOrBuilder> recordsBuilder_; + + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public java.util.List getRecordsList() { + if (recordsBuilder_ == null) { + return java.util.Collections.unmodifiableList(records_); + } else { + return recordsBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public int getRecordsCount() { + if (recordsBuilder_ == null) { + return records_.size(); + } else { + return recordsBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord getRecords(int index) { + if (recordsBuilder_ == null) { + return records_.get(index); + } else { + return recordsBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public Builder setRecords( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord value) { + if (recordsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureRecordsIsMutable(); + records_.set(index, value); + onChanged(); + } else { + recordsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public Builder setRecords( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.Builder builderForValue) { + if (recordsBuilder_ == null) { + ensureRecordsIsMutable(); + records_.set(index, builderForValue.build()); + onChanged(); + } else { + recordsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public Builder addRecords(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord value) { + if (recordsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureRecordsIsMutable(); + records_.add(value); + onChanged(); + } else { + recordsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public Builder addRecords( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord value) { + if (recordsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureRecordsIsMutable(); + records_.add(index, value); + onChanged(); + } else { + recordsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public Builder addRecords( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.Builder builderForValue) { + if (recordsBuilder_ == null) { + ensureRecordsIsMutable(); + records_.add(builderForValue.build()); + onChanged(); + } else { + recordsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public Builder addRecords( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.Builder builderForValue) { + if (recordsBuilder_ == null) { + ensureRecordsIsMutable(); + records_.add(index, builderForValue.build()); + onChanged(); + } else { + recordsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public Builder addAllRecords( + java.lang.Iterable values) { + if (recordsBuilder_ == null) { + ensureRecordsIsMutable(); + super.addAll(values, records_); + onChanged(); + } else { + recordsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public Builder clearRecords() { + if (recordsBuilder_ == null) { + records_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + recordsBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public Builder removeRecords(int index) { + if (recordsBuilder_ == null) { + ensureRecordsIsMutable(); + records_.remove(index); + onChanged(); + } else { + recordsBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.Builder getRecordsBuilder( + int index) { + return getRecordsFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecordOrBuilder getRecordsOrBuilder( + int index) { + if (recordsBuilder_ == null) { + return records_.get(index); } else { + return recordsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public java.util.List + getRecordsOrBuilderList() { + if (recordsBuilder_ != null) { + return recordsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(records_); + } + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.Builder addRecordsBuilder() { + return getRecordsFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.Builder addRecordsBuilder( + int index) { + return getRecordsFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.TruncateRecord records = 1; + */ + public java.util.List + getRecordsBuilderList() { + return getRecordsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecordOrBuilder> + getRecordsFieldBuilder() { + if (recordsBuilder_ == null) { + recordsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecord.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateRecordOrBuilder>( + records_, + ((bitField0_ & 0x00000001) == 0x00000001), + getParentForChildren(), + isClean()); + records_ = null; + } + return recordsBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.TruncateLog) + } + + static { + defaultInstance = new TruncateLog(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.TruncateLog) + } + + public interface XLocSetVersionStateOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed32 version = 1; + /** + * required fixed32 version = 1; + */ + boolean hasVersion(); + /** + * required fixed32 version = 1; + */ + int getVersion(); + + // required bool invalidated = 2; + /** + * required bool invalidated = 2; + */ + boolean hasInvalidated(); + /** + * required bool invalidated = 2; + */ + boolean getInvalidated(); + + // optional fixed64 modified_time = 3; + /** + * optional fixed64 modified_time = 3; + */ + boolean hasModifiedTime(); + /** + * optional fixed64 modified_time = 3; + */ + long getModifiedTime(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.XLocSetVersionState} + * + *
    +   * Version of the latest XLocSet a Replica has beeen part of 
    +   * and a flag indicating if the Replica is currently participating
    +   * in a XLocSetChange 
    +   * 
    + */ + public static final class XLocSetVersionState extends + com.google.protobuf.GeneratedMessage + implements XLocSetVersionStateOrBuilder { + // Use XLocSetVersionState.newBuilder() to construct. + private XLocSetVersionState(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private XLocSetVersionState(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final XLocSetVersionState defaultInstance; + public static XLocSetVersionState getDefaultInstance() { + return defaultInstance; + } + + public XLocSetVersionState getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private XLocSetVersionState( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 13: { + bitField0_ |= 0x00000001; + version_ = input.readFixed32(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + invalidated_ = input.readBool(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + modifiedTime_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_XLocSetVersionState_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_XLocSetVersionState_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public XLocSetVersionState parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new XLocSetVersionState(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed32 version = 1; + public static final int VERSION_FIELD_NUMBER = 1; + private int version_; + /** + * required fixed32 version = 1; + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 version = 1; + */ + public int getVersion() { + return version_; + } + + // required bool invalidated = 2; + public static final int INVALIDATED_FIELD_NUMBER = 2; + private boolean invalidated_; + /** + * required bool invalidated = 2; + */ + public boolean hasInvalidated() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool invalidated = 2; + */ + public boolean getInvalidated() { + return invalidated_; + } + + // optional fixed64 modified_time = 3; + public static final int MODIFIED_TIME_FIELD_NUMBER = 3; + private long modifiedTime_; + /** + * optional fixed64 modified_time = 3; + */ + public boolean hasModifiedTime() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional fixed64 modified_time = 3; + */ + public long getModifiedTime() { + return modifiedTime_; + } + + private void initFields() { + version_ = 0; + invalidated_ = false; + modifiedTime_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasInvalidated()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed32(1, version_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBool(2, invalidated_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, modifiedTime_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(1, version_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(2, invalidated_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, modifiedTime_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.XLocSetVersionState} + * + *
    +     * Version of the latest XLocSet a Replica has beeen part of 
    +     * and a flag indicating if the Replica is currently participating
    +     * in a XLocSetChange 
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionStateOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_XLocSetVersionState_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_XLocSetVersionState_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + version_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + invalidated_ = false; + bitField0_ = (bitField0_ & ~0x00000002); + modifiedTime_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_XLocSetVersionState_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.version_ = version_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.invalidated_ = invalidated_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.modifiedTime_ = modifiedTime_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState.getDefaultInstance()) return this; + if (other.hasVersion()) { + setVersion(other.getVersion()); + } + if (other.hasInvalidated()) { + setInvalidated(other.getInvalidated()); + } + if (other.hasModifiedTime()) { + setModifiedTime(other.getModifiedTime()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasVersion()) { + + return false; + } + if (!hasInvalidated()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.XLocSetVersionState) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed32 version = 1; + private int version_ ; + /** + * required fixed32 version = 1; + */ + public boolean hasVersion() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed32 version = 1; + */ + public int getVersion() { + return version_; + } + /** + * required fixed32 version = 1; + */ + public Builder setVersion(int value) { + bitField0_ |= 0x00000001; + version_ = value; + onChanged(); + return this; + } + /** + * required fixed32 version = 1; + */ + public Builder clearVersion() { + bitField0_ = (bitField0_ & ~0x00000001); + version_ = 0; + onChanged(); + return this; + } + + // required bool invalidated = 2; + private boolean invalidated_ ; + /** + * required bool invalidated = 2; + */ + public boolean hasInvalidated() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool invalidated = 2; + */ + public boolean getInvalidated() { + return invalidated_; + } + /** + * required bool invalidated = 2; + */ + public Builder setInvalidated(boolean value) { + bitField0_ |= 0x00000002; + invalidated_ = value; + onChanged(); + return this; + } + /** + * required bool invalidated = 2; + */ + public Builder clearInvalidated() { + bitField0_ = (bitField0_ & ~0x00000002); + invalidated_ = false; + onChanged(); + return this; + } + + // optional fixed64 modified_time = 3; + private long modifiedTime_ ; + /** + * optional fixed64 modified_time = 3; + */ + public boolean hasModifiedTime() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional fixed64 modified_time = 3; + */ + public long getModifiedTime() { + return modifiedTime_; + } + /** + * optional fixed64 modified_time = 3; + */ + public Builder setModifiedTime(long value) { + bitField0_ |= 0x00000004; + modifiedTime_ = value; + onChanged(); + return this; + } + /** + * optional fixed64 modified_time = 3; + */ + public Builder clearModifiedTime() { + bitField0_ = (bitField0_ & ~0x00000004); + modifiedTime_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.XLocSetVersionState) + } + + static { + defaultInstance = new XLocSetVersionState(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.XLocSetVersionState) + } + + public interface ReplicaStatusOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 truncate_epoch = 1; + /** + * required fixed64 truncate_epoch = 1; + * + *
    +     * Current truncate epoch.
    +     * 
    + */ + boolean hasTruncateEpoch(); + /** + * required fixed64 truncate_epoch = 1; + * + *
    +     * Current truncate epoch.
    +     * 
    + */ + long getTruncateEpoch(); + + // required fixed64 file_size = 2; + /** + * required fixed64 file_size = 2; + * + *
    +     * Local file size.
    +     * 
    + */ + boolean hasFileSize(); + /** + * required fixed64 file_size = 2; + * + *
    +     * Local file size.
    +     * 
    + */ + long getFileSize(); + + // required fixed64 max_obj_version = 3; + /** + * required fixed64 max_obj_version = 3; + * + *
    +     * Last object version stored locally.
    +     * 
    + */ + boolean hasMaxObjVersion(); + /** + * required fixed64 max_obj_version = 3; + * + *
    +     * Last object version stored locally.
    +     * 
    + */ + long getMaxObjVersion(); + + // required fixed32 primary_epoch = 4; + /** + * required fixed32 primary_epoch = 4; + * + *
    +     * Primary epoch number (aka Master Epoch).
    +     * 
    + */ + boolean hasPrimaryEpoch(); + /** + * required fixed32 primary_epoch = 4; + * + *
    +     * Primary epoch number (aka Master Epoch).
    +     * 
    + */ + int getPrimaryEpoch(); + + // repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +     * List of objects and their version.
    +     * 
    + */ + java.util.List + getObjectVersionsList(); + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +     * List of objects and their version.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion getObjectVersions(int index); + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +     * List of objects and their version.
    +     * 
    + */ + int getObjectVersionsCount(); + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +     * List of objects and their version.
    +     * 
    + */ + java.util.List + getObjectVersionsOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +     * List of objects and their version.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionOrBuilder getObjectVersionsOrBuilder( + int index); + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +     * Truncate log.
    +     * 
    + */ + boolean hasTruncateLog(); + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +     * Truncate log.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog getTruncateLog(); + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +     * Truncate log.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder getTruncateLogOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ReplicaStatus} + * + *
    +   * Full status of a replica. Used by the read-write
    +   * replication during Replica Reset.
    +   * 
    + */ + public static final class ReplicaStatus extends + com.google.protobuf.GeneratedMessage + implements ReplicaStatusOrBuilder { + // Use ReplicaStatus.newBuilder() to construct. + private ReplicaStatus(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ReplicaStatus(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final ReplicaStatus defaultInstance; + public static ReplicaStatus getDefaultInstance() { + return defaultInstance; + } + + public ReplicaStatus getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ReplicaStatus( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + truncateEpoch_ = input.readFixed64(); + break; + } + case 17: { + bitField0_ |= 0x00000002; + fileSize_ = input.readFixed64(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + maxObjVersion_ = input.readFixed64(); + break; + } + case 37: { + bitField0_ |= 0x00000008; + primaryEpoch_ = input.readFixed32(); + break; + } + case 42: { + if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { + objectVersions_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000010; + } + objectVersions_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.PARSER, extensionRegistry)); + break; + } + case 50: { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder subBuilder = null; + if (((bitField0_ & 0x00000010) == 0x00000010)) { + subBuilder = truncateLog_.toBuilder(); + } + truncateLog_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(truncateLog_); + truncateLog_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000010; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) { + objectVersions_ = java.util.Collections.unmodifiableList(objectVersions_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ReplicaStatus_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ReplicaStatus_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public ReplicaStatus parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ReplicaStatus(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 truncate_epoch = 1; + public static final int TRUNCATE_EPOCH_FIELD_NUMBER = 1; + private long truncateEpoch_; + /** + * required fixed64 truncate_epoch = 1; + * + *
    +     * Current truncate epoch.
    +     * 
    + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 truncate_epoch = 1; + * + *
    +     * Current truncate epoch.
    +     * 
    + */ + public long getTruncateEpoch() { + return truncateEpoch_; + } + + // required fixed64 file_size = 2; + public static final int FILE_SIZE_FIELD_NUMBER = 2; + private long fileSize_; + /** + * required fixed64 file_size = 2; + * + *
    +     * Local file size.
    +     * 
    + */ + public boolean hasFileSize() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 file_size = 2; + * + *
    +     * Local file size.
    +     * 
    + */ + public long getFileSize() { + return fileSize_; + } + + // required fixed64 max_obj_version = 3; + public static final int MAX_OBJ_VERSION_FIELD_NUMBER = 3; + private long maxObjVersion_; + /** + * required fixed64 max_obj_version = 3; + * + *
    +     * Last object version stored locally.
    +     * 
    + */ + public boolean hasMaxObjVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 max_obj_version = 3; + * + *
    +     * Last object version stored locally.
    +     * 
    + */ + public long getMaxObjVersion() { + return maxObjVersion_; + } + + // required fixed32 primary_epoch = 4; + public static final int PRIMARY_EPOCH_FIELD_NUMBER = 4; + private int primaryEpoch_; + /** + * required fixed32 primary_epoch = 4; + * + *
    +     * Primary epoch number (aka Master Epoch).
    +     * 
    + */ + public boolean hasPrimaryEpoch() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 primary_epoch = 4; + * + *
    +     * Primary epoch number (aka Master Epoch).
    +     * 
    + */ + public int getPrimaryEpoch() { + return primaryEpoch_; + } + + // repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + public static final int OBJECTVERSIONS_FIELD_NUMBER = 5; + private java.util.List objectVersions_; + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +     * List of objects and their version.
    +     * 
    + */ + public java.util.List getObjectVersionsList() { + return objectVersions_; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +     * List of objects and their version.
    +     * 
    + */ + public java.util.List + getObjectVersionsOrBuilderList() { + return objectVersions_; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +     * List of objects and their version.
    +     * 
    + */ + public int getObjectVersionsCount() { + return objectVersions_.size(); + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +     * List of objects and their version.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion getObjectVersions(int index) { + return objectVersions_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +     * List of objects and their version.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionOrBuilder getObjectVersionsOrBuilder( + int index) { + return objectVersions_.get(index); + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + public static final int TRUNCATE_LOG_FIELD_NUMBER = 6; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog truncateLog_; + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +     * Truncate log.
    +     * 
    + */ + public boolean hasTruncateLog() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +     * Truncate log.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog getTruncateLog() { + return truncateLog_; + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +     * Truncate log.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder getTruncateLogOrBuilder() { + return truncateLog_; + } + + private void initFields() { + truncateEpoch_ = 0L; + fileSize_ = 0L; + maxObjVersion_ = 0L; + primaryEpoch_ = 0; + objectVersions_ = java.util.Collections.emptyList(); + truncateLog_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasTruncateEpoch()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileSize()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMaxObjVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPrimaryEpoch()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTruncateLog()) { + memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getObjectVersionsCount(); i++) { + if (!getObjectVersions(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (!getTruncateLog().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, truncateEpoch_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(2, fileSize_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, maxObjVersion_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed32(4, primaryEpoch_); + } + for (int i = 0; i < objectVersions_.size(); i++) { + output.writeMessage(5, objectVersions_.get(i)); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeMessage(6, truncateLog_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, truncateEpoch_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(2, fileSize_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, maxObjVersion_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(4, primaryEpoch_); + } + for (int i = 0; i < objectVersions_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(5, objectVersions_.get(i)); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(6, truncateLog_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ReplicaStatus} + * + *
    +     * Full status of a replica. Used by the read-write
    +     * replication during Replica Reset.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatusOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ReplicaStatus_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ReplicaStatus_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getObjectVersionsFieldBuilder(); + getTruncateLogFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + truncateEpoch_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + fileSize_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + maxObjVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + primaryEpoch_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + if (objectVersionsBuilder_ == null) { + objectVersions_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000010); + } else { + objectVersionsBuilder_.clear(); + } + if (truncateLogBuilder_ == null) { + truncateLog_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance(); + } else { + truncateLogBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000020); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ReplicaStatus_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.truncateEpoch_ = truncateEpoch_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileSize_ = fileSize_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.maxObjVersion_ = maxObjVersion_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.primaryEpoch_ = primaryEpoch_; + if (objectVersionsBuilder_ == null) { + if (((bitField0_ & 0x00000010) == 0x00000010)) { + objectVersions_ = java.util.Collections.unmodifiableList(objectVersions_); + bitField0_ = (bitField0_ & ~0x00000010); + } + result.objectVersions_ = objectVersions_; + } else { + result.objectVersions_ = objectVersionsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000010; + } + if (truncateLogBuilder_ == null) { + result.truncateLog_ = truncateLog_; + } else { + result.truncateLog_ = truncateLogBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.getDefaultInstance()) return this; + if (other.hasTruncateEpoch()) { + setTruncateEpoch(other.getTruncateEpoch()); + } + if (other.hasFileSize()) { + setFileSize(other.getFileSize()); + } + if (other.hasMaxObjVersion()) { + setMaxObjVersion(other.getMaxObjVersion()); + } + if (other.hasPrimaryEpoch()) { + setPrimaryEpoch(other.getPrimaryEpoch()); + } + if (objectVersionsBuilder_ == null) { + if (!other.objectVersions_.isEmpty()) { + if (objectVersions_.isEmpty()) { + objectVersions_ = other.objectVersions_; + bitField0_ = (bitField0_ & ~0x00000010); + } else { + ensureObjectVersionsIsMutable(); + objectVersions_.addAll(other.objectVersions_); + } + onChanged(); + } + } else { + if (!other.objectVersions_.isEmpty()) { + if (objectVersionsBuilder_.isEmpty()) { + objectVersionsBuilder_.dispose(); + objectVersionsBuilder_ = null; + objectVersions_ = other.objectVersions_; + bitField0_ = (bitField0_ & ~0x00000010); + objectVersionsBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getObjectVersionsFieldBuilder() : null; + } else { + objectVersionsBuilder_.addAllMessages(other.objectVersions_); + } + } + } + if (other.hasTruncateLog()) { + mergeTruncateLog(other.getTruncateLog()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasTruncateEpoch()) { + + return false; + } + if (!hasFileSize()) { + + return false; + } + if (!hasMaxObjVersion()) { + + return false; + } + if (!hasPrimaryEpoch()) { + + return false; + } + if (!hasTruncateLog()) { + + return false; + } + for (int i = 0; i < getObjectVersionsCount(); i++) { + if (!getObjectVersions(i).isInitialized()) { + + return false; + } + } + if (!getTruncateLog().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 truncate_epoch = 1; + private long truncateEpoch_ ; + /** + * required fixed64 truncate_epoch = 1; + * + *
    +       * Current truncate epoch.
    +       * 
    + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 truncate_epoch = 1; + * + *
    +       * Current truncate epoch.
    +       * 
    + */ + public long getTruncateEpoch() { + return truncateEpoch_; + } + /** + * required fixed64 truncate_epoch = 1; + * + *
    +       * Current truncate epoch.
    +       * 
    + */ + public Builder setTruncateEpoch(long value) { + bitField0_ |= 0x00000001; + truncateEpoch_ = value; + onChanged(); + return this; + } + /** + * required fixed64 truncate_epoch = 1; + * + *
    +       * Current truncate epoch.
    +       * 
    + */ + public Builder clearTruncateEpoch() { + bitField0_ = (bitField0_ & ~0x00000001); + truncateEpoch_ = 0L; + onChanged(); + return this; + } + + // required fixed64 file_size = 2; + private long fileSize_ ; + /** + * required fixed64 file_size = 2; + * + *
    +       * Local file size.
    +       * 
    + */ + public boolean hasFileSize() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 file_size = 2; + * + *
    +       * Local file size.
    +       * 
    + */ + public long getFileSize() { + return fileSize_; + } + /** + * required fixed64 file_size = 2; + * + *
    +       * Local file size.
    +       * 
    + */ + public Builder setFileSize(long value) { + bitField0_ |= 0x00000002; + fileSize_ = value; + onChanged(); + return this; + } + /** + * required fixed64 file_size = 2; + * + *
    +       * Local file size.
    +       * 
    + */ + public Builder clearFileSize() { + bitField0_ = (bitField0_ & ~0x00000002); + fileSize_ = 0L; + onChanged(); + return this; + } + + // required fixed64 max_obj_version = 3; + private long maxObjVersion_ ; + /** + * required fixed64 max_obj_version = 3; + * + *
    +       * Last object version stored locally.
    +       * 
    + */ + public boolean hasMaxObjVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 max_obj_version = 3; + * + *
    +       * Last object version stored locally.
    +       * 
    + */ + public long getMaxObjVersion() { + return maxObjVersion_; + } + /** + * required fixed64 max_obj_version = 3; + * + *
    +       * Last object version stored locally.
    +       * 
    + */ + public Builder setMaxObjVersion(long value) { + bitField0_ |= 0x00000004; + maxObjVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 max_obj_version = 3; + * + *
    +       * Last object version stored locally.
    +       * 
    + */ + public Builder clearMaxObjVersion() { + bitField0_ = (bitField0_ & ~0x00000004); + maxObjVersion_ = 0L; + onChanged(); + return this; + } + + // required fixed32 primary_epoch = 4; + private int primaryEpoch_ ; + /** + * required fixed32 primary_epoch = 4; + * + *
    +       * Primary epoch number (aka Master Epoch).
    +       * 
    + */ + public boolean hasPrimaryEpoch() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed32 primary_epoch = 4; + * + *
    +       * Primary epoch number (aka Master Epoch).
    +       * 
    + */ + public int getPrimaryEpoch() { + return primaryEpoch_; + } + /** + * required fixed32 primary_epoch = 4; + * + *
    +       * Primary epoch number (aka Master Epoch).
    +       * 
    + */ + public Builder setPrimaryEpoch(int value) { + bitField0_ |= 0x00000008; + primaryEpoch_ = value; + onChanged(); + return this; + } + /** + * required fixed32 primary_epoch = 4; + * + *
    +       * Primary epoch number (aka Master Epoch).
    +       * 
    + */ + public Builder clearPrimaryEpoch() { + bitField0_ = (bitField0_ & ~0x00000008); + primaryEpoch_ = 0; + onChanged(); + return this; + } + + // repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + private java.util.List objectVersions_ = + java.util.Collections.emptyList(); + private void ensureObjectVersionsIsMutable() { + if (!((bitField0_ & 0x00000010) == 0x00000010)) { + objectVersions_ = new java.util.ArrayList(objectVersions_); + bitField0_ |= 0x00000010; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionOrBuilder> objectVersionsBuilder_; + + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public java.util.List getObjectVersionsList() { + if (objectVersionsBuilder_ == null) { + return java.util.Collections.unmodifiableList(objectVersions_); + } else { + return objectVersionsBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public int getObjectVersionsCount() { + if (objectVersionsBuilder_ == null) { + return objectVersions_.size(); + } else { + return objectVersionsBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion getObjectVersions(int index) { + if (objectVersionsBuilder_ == null) { + return objectVersions_.get(index); + } else { + return objectVersionsBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public Builder setObjectVersions( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion value) { + if (objectVersionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureObjectVersionsIsMutable(); + objectVersions_.set(index, value); + onChanged(); + } else { + objectVersionsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public Builder setObjectVersions( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.Builder builderForValue) { + if (objectVersionsBuilder_ == null) { + ensureObjectVersionsIsMutable(); + objectVersions_.set(index, builderForValue.build()); + onChanged(); + } else { + objectVersionsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public Builder addObjectVersions(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion value) { + if (objectVersionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureObjectVersionsIsMutable(); + objectVersions_.add(value); + onChanged(); + } else { + objectVersionsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public Builder addObjectVersions( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion value) { + if (objectVersionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureObjectVersionsIsMutable(); + objectVersions_.add(index, value); + onChanged(); + } else { + objectVersionsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public Builder addObjectVersions( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.Builder builderForValue) { + if (objectVersionsBuilder_ == null) { + ensureObjectVersionsIsMutable(); + objectVersions_.add(builderForValue.build()); + onChanged(); + } else { + objectVersionsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public Builder addObjectVersions( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.Builder builderForValue) { + if (objectVersionsBuilder_ == null) { + ensureObjectVersionsIsMutable(); + objectVersions_.add(index, builderForValue.build()); + onChanged(); + } else { + objectVersionsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public Builder addAllObjectVersions( + java.lang.Iterable values) { + if (objectVersionsBuilder_ == null) { + ensureObjectVersionsIsMutable(); + super.addAll(values, objectVersions_); + onChanged(); + } else { + objectVersionsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public Builder clearObjectVersions() { + if (objectVersionsBuilder_ == null) { + objectVersions_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000010); + onChanged(); + } else { + objectVersionsBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public Builder removeObjectVersions(int index) { + if (objectVersionsBuilder_ == null) { + ensureObjectVersionsIsMutable(); + objectVersions_.remove(index); + onChanged(); + } else { + objectVersionsBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.Builder getObjectVersionsBuilder( + int index) { + return getObjectVersionsFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionOrBuilder getObjectVersionsOrBuilder( + int index) { + if (objectVersionsBuilder_ == null) { + return objectVersions_.get(index); } else { + return objectVersionsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public java.util.List + getObjectVersionsOrBuilderList() { + if (objectVersionsBuilder_ != null) { + return objectVersionsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(objectVersions_); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.Builder addObjectVersionsBuilder() { + return getObjectVersionsFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.Builder addObjectVersionsBuilder( + int index) { + return getObjectVersionsFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersion objectVersions = 5; + * + *
    +       * List of objects and their version.
    +       * 
    + */ + public java.util.List + getObjectVersionsBuilderList() { + return getObjectVersionsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionOrBuilder> + getObjectVersionsFieldBuilder() { + if (objectVersionsBuilder_ == null) { + objectVersionsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersion.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionOrBuilder>( + objectVersions_, + ((bitField0_ & 0x00000010) == 0x00000010), + getParentForChildren(), + isClean()); + objectVersions_ = null; + } + return objectVersionsBuilder_; + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog truncateLog_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder> truncateLogBuilder_; + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +       * Truncate log.
    +       * 
    + */ + public boolean hasTruncateLog() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +       * Truncate log.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog getTruncateLog() { + if (truncateLogBuilder_ == null) { + return truncateLog_; + } else { + return truncateLogBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +       * Truncate log.
    +       * 
    + */ + public Builder setTruncateLog(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog value) { + if (truncateLogBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + truncateLog_ = value; + onChanged(); + } else { + truncateLogBuilder_.setMessage(value); + } + bitField0_ |= 0x00000020; + return this; + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +       * Truncate log.
    +       * 
    + */ + public Builder setTruncateLog( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder builderForValue) { + if (truncateLogBuilder_ == null) { + truncateLog_ = builderForValue.build(); + onChanged(); + } else { + truncateLogBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000020; + return this; + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +       * Truncate log.
    +       * 
    + */ + public Builder mergeTruncateLog(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog value) { + if (truncateLogBuilder_ == null) { + if (((bitField0_ & 0x00000020) == 0x00000020) && + truncateLog_ != org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance()) { + truncateLog_ = + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.newBuilder(truncateLog_).mergeFrom(value).buildPartial(); + } else { + truncateLog_ = value; + } + onChanged(); + } else { + truncateLogBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000020; + return this; + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +       * Truncate log.
    +       * 
    + */ + public Builder clearTruncateLog() { + if (truncateLogBuilder_ == null) { + truncateLog_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance(); + onChanged(); + } else { + truncateLogBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000020); + return this; + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +       * Truncate log.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder getTruncateLogBuilder() { + bitField0_ |= 0x00000020; + onChanged(); + return getTruncateLogFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +       * Truncate log.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder getTruncateLogOrBuilder() { + if (truncateLogBuilder_ != null) { + return truncateLogBuilder_.getMessageOrBuilder(); + } else { + return truncateLog_; + } + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 6; + * + *
    +       * Truncate log.
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder> + getTruncateLogFieldBuilder() { + if (truncateLogBuilder_ == null) { + truncateLogBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder>( + truncateLog_, + getParentForChildren(), + isClean()); + truncateLog_ = null; + } + return truncateLogBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.ReplicaStatus) + } + + static { + defaultInstance = new ReplicaStatus(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ReplicaStatus) + } + + public interface ObjectVersionMappingOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 object_number = 1; + /** + * required fixed64 object_number = 1; + */ + boolean hasObjectNumber(); + /** + * required fixed64 object_number = 1; + */ + long getObjectNumber(); + + // required fixed64 object_version = 2; + /** + * required fixed64 object_version = 2; + */ + boolean hasObjectVersion(); + /** + * required fixed64 object_version = 2; + */ + long getObjectVersion(); + + // repeated string osd_uuids = 3; + /** + * repeated string osd_uuids = 3; + */ + java.util.List + getOsdUuidsList(); + /** + * repeated string osd_uuids = 3; + */ + int getOsdUuidsCount(); + /** + * repeated string osd_uuids = 3; + */ + java.lang.String getOsdUuids(int index); + /** + * repeated string osd_uuids = 3; + */ + com.google.protobuf.ByteString + getOsdUuidsBytes(int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ObjectVersionMapping} + * + *
    +   * Mapping from object_number/version to OSDs that have
    +   * a copy of this object. Used by the rw-replication.
    +   * 
    + */ + public static final class ObjectVersionMapping extends + com.google.protobuf.GeneratedMessage + implements ObjectVersionMappingOrBuilder { + // Use ObjectVersionMapping.newBuilder() to construct. + private ObjectVersionMapping(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ObjectVersionMapping(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final ObjectVersionMapping defaultInstance; + public static ObjectVersionMapping getDefaultInstance() { + return defaultInstance; + } + + public ObjectVersionMapping getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ObjectVersionMapping( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + objectNumber_ = input.readFixed64(); + break; + } + case 17: { + bitField0_ |= 0x00000002; + objectVersion_ = input.readFixed64(); + break; + } + case 26: { + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + osdUuids_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000004; + } + osdUuids_.add(input.readBytes()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + osdUuids_ = new com.google.protobuf.UnmodifiableLazyStringList(osdUuids_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectVersionMapping_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectVersionMapping_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public ObjectVersionMapping parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ObjectVersionMapping(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 object_number = 1; + public static final int OBJECT_NUMBER_FIELD_NUMBER = 1; + private long objectNumber_; + /** + * required fixed64 object_number = 1; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 object_number = 1; + */ + public long getObjectNumber() { + return objectNumber_; + } + + // required fixed64 object_version = 2; + public static final int OBJECT_VERSION_FIELD_NUMBER = 2; + private long objectVersion_; + /** + * required fixed64 object_version = 2; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 object_version = 2; + */ + public long getObjectVersion() { + return objectVersion_; + } + + // repeated string osd_uuids = 3; + public static final int OSD_UUIDS_FIELD_NUMBER = 3; + private com.google.protobuf.LazyStringList osdUuids_; + /** + * repeated string osd_uuids = 3; + */ + public java.util.List + getOsdUuidsList() { + return osdUuids_; + } + /** + * repeated string osd_uuids = 3; + */ + public int getOsdUuidsCount() { + return osdUuids_.size(); + } + /** + * repeated string osd_uuids = 3; + */ + public java.lang.String getOsdUuids(int index) { + return osdUuids_.get(index); + } + /** + * repeated string osd_uuids = 3; + */ + public com.google.protobuf.ByteString + getOsdUuidsBytes(int index) { + return osdUuids_.getByteString(index); + } + + private void initFields() { + objectNumber_ = 0L; + objectVersion_ = 0L; + osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasObjectNumber()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectVersion()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, objectNumber_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(2, objectVersion_); + } + for (int i = 0; i < osdUuids_.size(); i++) { + output.writeBytes(3, osdUuids_.getByteString(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, objectNumber_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(2, objectVersion_); + } + { + int dataSize = 0; + for (int i = 0; i < osdUuids_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(osdUuids_.getByteString(i)); + } + size += dataSize; + size += 1 * getOsdUuidsList().size(); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.ObjectVersionMapping} + * + *
    +     * Mapping from object_number/version to OSDs that have
    +     * a copy of this object. Used by the rw-replication.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMappingOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectVersionMapping_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectVersionMapping_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + objectNumber_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + objectVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_ObjectVersionMapping_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.objectNumber_ = objectNumber_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.objectVersion_ = objectVersion_; + if (((bitField0_ & 0x00000004) == 0x00000004)) { + osdUuids_ = new com.google.protobuf.UnmodifiableLazyStringList( + osdUuids_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.osdUuids_ = osdUuids_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.getDefaultInstance()) return this; + if (other.hasObjectNumber()) { + setObjectNumber(other.getObjectNumber()); + } + if (other.hasObjectVersion()) { + setObjectVersion(other.getObjectVersion()); + } + if (!other.osdUuids_.isEmpty()) { + if (osdUuids_.isEmpty()) { + osdUuids_ = other.osdUuids_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureOsdUuidsIsMutable(); + osdUuids_.addAll(other.osdUuids_); + } + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasObjectNumber()) { + + return false; + } + if (!hasObjectVersion()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 object_number = 1; + private long objectNumber_ ; + /** + * required fixed64 object_number = 1; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 object_number = 1; + */ + public long getObjectNumber() { + return objectNumber_; + } + /** + * required fixed64 object_number = 1; + */ + public Builder setObjectNumber(long value) { + bitField0_ |= 0x00000001; + objectNumber_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_number = 1; + */ + public Builder clearObjectNumber() { + bitField0_ = (bitField0_ & ~0x00000001); + objectNumber_ = 0L; + onChanged(); + return this; + } + + // required fixed64 object_version = 2; + private long objectVersion_ ; + /** + * required fixed64 object_version = 2; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 object_version = 2; + */ + public long getObjectVersion() { + return objectVersion_; + } + /** + * required fixed64 object_version = 2; + */ + public Builder setObjectVersion(long value) { + bitField0_ |= 0x00000002; + objectVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_version = 2; + */ + public Builder clearObjectVersion() { + bitField0_ = (bitField0_ & ~0x00000002); + objectVersion_ = 0L; + onChanged(); + return this; + } + + // repeated string osd_uuids = 3; + private com.google.protobuf.LazyStringList osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureOsdUuidsIsMutable() { + if (!((bitField0_ & 0x00000004) == 0x00000004)) { + osdUuids_ = new com.google.protobuf.LazyStringArrayList(osdUuids_); + bitField0_ |= 0x00000004; + } + } + /** + * repeated string osd_uuids = 3; + */ + public java.util.List + getOsdUuidsList() { + return java.util.Collections.unmodifiableList(osdUuids_); + } + /** + * repeated string osd_uuids = 3; + */ + public int getOsdUuidsCount() { + return osdUuids_.size(); + } + /** + * repeated string osd_uuids = 3; + */ + public java.lang.String getOsdUuids(int index) { + return osdUuids_.get(index); + } + /** + * repeated string osd_uuids = 3; + */ + public com.google.protobuf.ByteString + getOsdUuidsBytes(int index) { + return osdUuids_.getByteString(index); + } + /** + * repeated string osd_uuids = 3; + */ + public Builder setOsdUuids( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureOsdUuidsIsMutable(); + osdUuids_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 3; + */ + public Builder addOsdUuids( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureOsdUuidsIsMutable(); + osdUuids_.add(value); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 3; + */ + public Builder addAllOsdUuids( + java.lang.Iterable values) { + ensureOsdUuidsIsMutable(); + super.addAll(values, osdUuids_); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 3; + */ + public Builder clearOsdUuids() { + osdUuids_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + return this; + } + /** + * repeated string osd_uuids = 3; + */ + public Builder addOsdUuidsBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureOsdUuidsIsMutable(); + osdUuids_.add(value); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.ObjectVersionMapping) + } + + static { + defaultInstance = new ObjectVersionMapping(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.ObjectVersionMapping) + } + + public interface AuthoritativeReplicaStateOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 truncate_epoch = 1; + /** + * required fixed64 truncate_epoch = 1; + */ + boolean hasTruncateEpoch(); + /** + * required fixed64 truncate_epoch = 1; + */ + long getTruncateEpoch(); + + // required fixed64 max_obj_version = 4; + /** + * required fixed64 max_obj_version = 4; + */ + boolean hasMaxObjVersion(); + /** + * required fixed64 max_obj_version = 4; + */ + long getMaxObjVersion(); + + // repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + java.util.List + getObjectVersionsList(); + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping getObjectVersions(int index); + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + int getObjectVersionsCount(); + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + java.util.List + getObjectVersionsOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMappingOrBuilder getObjectVersionsOrBuilder( + int index); + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + boolean hasTruncateLog(); + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog getTruncateLog(); + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder getTruncateLogOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.AuthoritativeReplicaState} + * + *
    +   * Correct replica state sent by the Primary to all
    +   * backups. After receiving this information, backups
    +   * will bring themselves to the authoritative state by
    +   * fetching missing data and deleting outdated objects.
    +   * 
    + */ + public static final class AuthoritativeReplicaState extends + com.google.protobuf.GeneratedMessage + implements AuthoritativeReplicaStateOrBuilder { + // Use AuthoritativeReplicaState.newBuilder() to construct. + private AuthoritativeReplicaState(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private AuthoritativeReplicaState(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final AuthoritativeReplicaState defaultInstance; + public static AuthoritativeReplicaState getDefaultInstance() { + return defaultInstance; + } + + public AuthoritativeReplicaState getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AuthoritativeReplicaState( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + truncateEpoch_ = input.readFixed64(); + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + objectVersions_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000004; + } + objectVersions_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.PARSER, extensionRegistry)); + break; + } + case 26: { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder subBuilder = null; + if (((bitField0_ & 0x00000004) == 0x00000004)) { + subBuilder = truncateLog_.toBuilder(); + } + truncateLog_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(truncateLog_); + truncateLog_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000004; + break; + } + case 33: { + bitField0_ |= 0x00000002; + maxObjVersion_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + objectVersions_ = java.util.Collections.unmodifiableList(objectVersions_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_AuthoritativeReplicaState_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_AuthoritativeReplicaState_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public AuthoritativeReplicaState parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AuthoritativeReplicaState(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 truncate_epoch = 1; + public static final int TRUNCATE_EPOCH_FIELD_NUMBER = 1; + private long truncateEpoch_; + /** + * required fixed64 truncate_epoch = 1; + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 truncate_epoch = 1; + */ + public long getTruncateEpoch() { + return truncateEpoch_; + } + + // required fixed64 max_obj_version = 4; + public static final int MAX_OBJ_VERSION_FIELD_NUMBER = 4; + private long maxObjVersion_; + /** + * required fixed64 max_obj_version = 4; + */ + public boolean hasMaxObjVersion() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 max_obj_version = 4; + */ + public long getMaxObjVersion() { + return maxObjVersion_; + } + + // repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + public static final int OBJECTVERSIONS_FIELD_NUMBER = 2; + private java.util.List objectVersions_; + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public java.util.List getObjectVersionsList() { + return objectVersions_; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public java.util.List + getObjectVersionsOrBuilderList() { + return objectVersions_; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public int getObjectVersionsCount() { + return objectVersions_.size(); + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping getObjectVersions(int index) { + return objectVersions_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMappingOrBuilder getObjectVersionsOrBuilder( + int index) { + return objectVersions_.get(index); + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + public static final int TRUNCATE_LOG_FIELD_NUMBER = 3; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog truncateLog_; + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + public boolean hasTruncateLog() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog getTruncateLog() { + return truncateLog_; + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder getTruncateLogOrBuilder() { + return truncateLog_; + } + + private void initFields() { + truncateEpoch_ = 0L; + maxObjVersion_ = 0L; + objectVersions_ = java.util.Collections.emptyList(); + truncateLog_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasTruncateEpoch()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMaxObjVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTruncateLog()) { + memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getObjectVersionsCount(); i++) { + if (!getObjectVersions(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (!getTruncateLog().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, truncateEpoch_); + } + for (int i = 0; i < objectVersions_.size(); i++) { + output.writeMessage(2, objectVersions_.get(i)); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeMessage(3, truncateLog_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(4, maxObjVersion_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, truncateEpoch_); + } + for (int i = 0; i < objectVersions_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, objectVersions_.get(i)); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, truncateLog_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(4, maxObjVersion_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.AuthoritativeReplicaState} + * + *
    +     * Correct replica state sent by the Primary to all
    +     * backups. After receiving this information, backups
    +     * will bring themselves to the authoritative state by
    +     * fetching missing data and deleting outdated objects.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaStateOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_AuthoritativeReplicaState_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_AuthoritativeReplicaState_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getObjectVersionsFieldBuilder(); + getTruncateLogFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + truncateEpoch_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + maxObjVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + if (objectVersionsBuilder_ == null) { + objectVersions_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + } else { + objectVersionsBuilder_.clear(); + } + if (truncateLogBuilder_ == null) { + truncateLog_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance(); + } else { + truncateLogBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_AuthoritativeReplicaState_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.truncateEpoch_ = truncateEpoch_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.maxObjVersion_ = maxObjVersion_; + if (objectVersionsBuilder_ == null) { + if (((bitField0_ & 0x00000004) == 0x00000004)) { + objectVersions_ = java.util.Collections.unmodifiableList(objectVersions_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.objectVersions_ = objectVersions_; + } else { + result.objectVersions_ = objectVersionsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000004; + } + if (truncateLogBuilder_ == null) { + result.truncateLog_ = truncateLog_; + } else { + result.truncateLog_ = truncateLogBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.getDefaultInstance()) return this; + if (other.hasTruncateEpoch()) { + setTruncateEpoch(other.getTruncateEpoch()); + } + if (other.hasMaxObjVersion()) { + setMaxObjVersion(other.getMaxObjVersion()); + } + if (objectVersionsBuilder_ == null) { + if (!other.objectVersions_.isEmpty()) { + if (objectVersions_.isEmpty()) { + objectVersions_ = other.objectVersions_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureObjectVersionsIsMutable(); + objectVersions_.addAll(other.objectVersions_); + } + onChanged(); + } + } else { + if (!other.objectVersions_.isEmpty()) { + if (objectVersionsBuilder_.isEmpty()) { + objectVersionsBuilder_.dispose(); + objectVersionsBuilder_ = null; + objectVersions_ = other.objectVersions_; + bitField0_ = (bitField0_ & ~0x00000004); + objectVersionsBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getObjectVersionsFieldBuilder() : null; + } else { + objectVersionsBuilder_.addAllMessages(other.objectVersions_); + } + } + } + if (other.hasTruncateLog()) { + mergeTruncateLog(other.getTruncateLog()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasTruncateEpoch()) { + + return false; + } + if (!hasMaxObjVersion()) { + + return false; + } + if (!hasTruncateLog()) { + + return false; + } + for (int i = 0; i < getObjectVersionsCount(); i++) { + if (!getObjectVersions(i).isInitialized()) { + + return false; + } + } + if (!getTruncateLog().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 truncate_epoch = 1; + private long truncateEpoch_ ; + /** + * required fixed64 truncate_epoch = 1; + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 truncate_epoch = 1; + */ + public long getTruncateEpoch() { + return truncateEpoch_; + } + /** + * required fixed64 truncate_epoch = 1; + */ + public Builder setTruncateEpoch(long value) { + bitField0_ |= 0x00000001; + truncateEpoch_ = value; + onChanged(); + return this; + } + /** + * required fixed64 truncate_epoch = 1; + */ + public Builder clearTruncateEpoch() { + bitField0_ = (bitField0_ & ~0x00000001); + truncateEpoch_ = 0L; + onChanged(); + return this; + } + + // required fixed64 max_obj_version = 4; + private long maxObjVersion_ ; + /** + * required fixed64 max_obj_version = 4; + */ + public boolean hasMaxObjVersion() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 max_obj_version = 4; + */ + public long getMaxObjVersion() { + return maxObjVersion_; + } + /** + * required fixed64 max_obj_version = 4; + */ + public Builder setMaxObjVersion(long value) { + bitField0_ |= 0x00000002; + maxObjVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 max_obj_version = 4; + */ + public Builder clearMaxObjVersion() { + bitField0_ = (bitField0_ & ~0x00000002); + maxObjVersion_ = 0L; + onChanged(); + return this; + } + + // repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + private java.util.List objectVersions_ = + java.util.Collections.emptyList(); + private void ensureObjectVersionsIsMutable() { + if (!((bitField0_ & 0x00000004) == 0x00000004)) { + objectVersions_ = new java.util.ArrayList(objectVersions_); + bitField0_ |= 0x00000004; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMappingOrBuilder> objectVersionsBuilder_; + + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public java.util.List getObjectVersionsList() { + if (objectVersionsBuilder_ == null) { + return java.util.Collections.unmodifiableList(objectVersions_); + } else { + return objectVersionsBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public int getObjectVersionsCount() { + if (objectVersionsBuilder_ == null) { + return objectVersions_.size(); + } else { + return objectVersionsBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping getObjectVersions(int index) { + if (objectVersionsBuilder_ == null) { + return objectVersions_.get(index); + } else { + return objectVersionsBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public Builder setObjectVersions( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping value) { + if (objectVersionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureObjectVersionsIsMutable(); + objectVersions_.set(index, value); + onChanged(); + } else { + objectVersionsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public Builder setObjectVersions( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder builderForValue) { + if (objectVersionsBuilder_ == null) { + ensureObjectVersionsIsMutable(); + objectVersions_.set(index, builderForValue.build()); + onChanged(); + } else { + objectVersionsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public Builder addObjectVersions(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping value) { + if (objectVersionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureObjectVersionsIsMutable(); + objectVersions_.add(value); + onChanged(); + } else { + objectVersionsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public Builder addObjectVersions( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping value) { + if (objectVersionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureObjectVersionsIsMutable(); + objectVersions_.add(index, value); + onChanged(); + } else { + objectVersionsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public Builder addObjectVersions( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder builderForValue) { + if (objectVersionsBuilder_ == null) { + ensureObjectVersionsIsMutable(); + objectVersions_.add(builderForValue.build()); + onChanged(); + } else { + objectVersionsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public Builder addObjectVersions( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder builderForValue) { + if (objectVersionsBuilder_ == null) { + ensureObjectVersionsIsMutable(); + objectVersions_.add(index, builderForValue.build()); + onChanged(); + } else { + objectVersionsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public Builder addAllObjectVersions( + java.lang.Iterable values) { + if (objectVersionsBuilder_ == null) { + ensureObjectVersionsIsMutable(); + super.addAll(values, objectVersions_); + onChanged(); + } else { + objectVersionsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public Builder clearObjectVersions() { + if (objectVersionsBuilder_ == null) { + objectVersions_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + } else { + objectVersionsBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public Builder removeObjectVersions(int index) { + if (objectVersionsBuilder_ == null) { + ensureObjectVersionsIsMutable(); + objectVersions_.remove(index); + onChanged(); + } else { + objectVersionsBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder getObjectVersionsBuilder( + int index) { + return getObjectVersionsFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMappingOrBuilder getObjectVersionsOrBuilder( + int index) { + if (objectVersionsBuilder_ == null) { + return objectVersions_.get(index); } else { + return objectVersionsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public java.util.List + getObjectVersionsOrBuilderList() { + if (objectVersionsBuilder_ != null) { + return objectVersionsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(objectVersions_); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder addObjectVersionsBuilder() { + return getObjectVersionsFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder addObjectVersionsBuilder( + int index) { + return getObjectVersionsFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.ObjectVersionMapping objectVersions = 2; + */ + public java.util.List + getObjectVersionsBuilderList() { + return getObjectVersionsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMappingOrBuilder> + getObjectVersionsFieldBuilder() { + if (objectVersionsBuilder_ == null) { + objectVersionsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMapping.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectVersionMappingOrBuilder>( + objectVersions_, + ((bitField0_ & 0x00000004) == 0x00000004), + getParentForChildren(), + isClean()); + objectVersions_ = null; + } + return objectVersionsBuilder_; + } + + // required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog truncateLog_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder> truncateLogBuilder_; + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + public boolean hasTruncateLog() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog getTruncateLog() { + if (truncateLogBuilder_ == null) { + return truncateLog_; + } else { + return truncateLogBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + public Builder setTruncateLog(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog value) { + if (truncateLogBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + truncateLog_ = value; + onChanged(); + } else { + truncateLogBuilder_.setMessage(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + public Builder setTruncateLog( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder builderForValue) { + if (truncateLogBuilder_ == null) { + truncateLog_ = builderForValue.build(); + onChanged(); + } else { + truncateLogBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + public Builder mergeTruncateLog(org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog value) { + if (truncateLogBuilder_ == null) { + if (((bitField0_ & 0x00000008) == 0x00000008) && + truncateLog_ != org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance()) { + truncateLog_ = + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.newBuilder(truncateLog_).mergeFrom(value).buildPartial(); + } else { + truncateLog_ = value; + } + onChanged(); + } else { + truncateLogBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000008; + return this; + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + public Builder clearTruncateLog() { + if (truncateLogBuilder_ == null) { + truncateLog_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.getDefaultInstance(); + onChanged(); + } else { + truncateLogBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder getTruncateLogBuilder() { + bitField0_ |= 0x00000008; + onChanged(); + return getTruncateLogFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder getTruncateLogOrBuilder() { + if (truncateLogBuilder_ != null) { + return truncateLogBuilder_.getMessageOrBuilder(); + } else { + return truncateLog_; + } + } + /** + * required .xtreemfs.pbrpc.TruncateLog truncate_log = 3; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder> + getTruncateLogFieldBuilder() { + if (truncateLogBuilder_ == null) { + truncateLogBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLog.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.TruncateLogOrBuilder>( + truncateLog_, + getParentForChildren(), + isClean()); + truncateLog_ = null; + } + return truncateLogBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.AuthoritativeReplicaState) + } + + static { + defaultInstance = new AuthoritativeReplicaState(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.AuthoritativeReplicaState) + } + + public interface InternalReadLocalResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.ObjectData data = 1; + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + boolean hasData(); + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData getData(); + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder getDataOrBuilder(); + + // repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +     * List of objects the OSD has.
    +     * 
    + */ + java.util.List + getObjectSetList(); + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +     * List of objects the OSD has.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList getObjectSet(int index); + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +     * List of objects the OSD has.
    +     * 
    + */ + int getObjectSetCount(); + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +     * List of objects the OSD has.
    +     * 
    + */ + java.util.List + getObjectSetOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +     * List of objects the OSD has.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder getObjectSetOrBuilder( + int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.InternalReadLocalResponse} + * + *
    +   * Response sent by an OSD when reading objects for
    +   * the ro/rw replication.
    +   * 
    + */ + public static final class InternalReadLocalResponse extends + com.google.protobuf.GeneratedMessage + implements InternalReadLocalResponseOrBuilder { + // Use InternalReadLocalResponse.newBuilder() to construct. + private InternalReadLocalResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private InternalReadLocalResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final InternalReadLocalResponse defaultInstance; + public static InternalReadLocalResponse getDefaultInstance() { + return defaultInstance; + } + + public InternalReadLocalResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private InternalReadLocalResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = data_.toBuilder(); + } + data_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(data_); + data_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + objectSet_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + objectSet_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + objectSet_ = java.util.Collections.unmodifiableList(objectSet_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_InternalReadLocalResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_InternalReadLocalResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public InternalReadLocalResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new InternalReadLocalResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.ObjectData data = 1; + public static final int DATA_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData data_; + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + public boolean hasData() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData getData() { + return data_; + } + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder getDataOrBuilder() { + return data_; + } + + // repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + public static final int OBJECT_SET_FIELD_NUMBER = 2; + private java.util.List objectSet_; + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +     * List of objects the OSD has.
    +     * 
    + */ + public java.util.List getObjectSetList() { + return objectSet_; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +     * List of objects the OSD has.
    +     * 
    + */ + public java.util.List + getObjectSetOrBuilderList() { + return objectSet_; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +     * List of objects the OSD has.
    +     * 
    + */ + public int getObjectSetCount() { + return objectSet_.size(); + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +     * List of objects the OSD has.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList getObjectSet(int index) { + return objectSet_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +     * List of objects the OSD has.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder getObjectSetOrBuilder( + int index) { + return objectSet_.get(index); + } + + private void initFields() { + data_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + objectSet_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasData()) { + memoizedIsInitialized = 0; + return false; + } + if (!getData().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getObjectSetCount(); i++) { + if (!getObjectSet(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, data_); + } + for (int i = 0; i < objectSet_.size(); i++) { + output.writeMessage(2, objectSet_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, data_); + } + for (int i = 0; i < objectSet_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, objectSet_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.InternalReadLocalResponse} + * + *
    +     * Response sent by an OSD when reading objects for
    +     * the ro/rw replication.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_InternalReadLocalResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_InternalReadLocalResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getDataFieldBuilder(); + getObjectSetFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (dataBuilder_ == null) { + data_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + } else { + dataBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (objectSetBuilder_ == null) { + objectSet_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + } else { + objectSetBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_InternalReadLocalResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (dataBuilder_ == null) { + result.data_ = data_; + } else { + result.data_ = dataBuilder_.build(); + } + if (objectSetBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002)) { + objectSet_ = java.util.Collections.unmodifiableList(objectSet_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.objectSet_ = objectSet_; + } else { + result.objectSet_ = objectSetBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse.getDefaultInstance()) return this; + if (other.hasData()) { + mergeData(other.getData()); + } + if (objectSetBuilder_ == null) { + if (!other.objectSet_.isEmpty()) { + if (objectSet_.isEmpty()) { + objectSet_ = other.objectSet_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureObjectSetIsMutable(); + objectSet_.addAll(other.objectSet_); + } + onChanged(); + } + } else { + if (!other.objectSet_.isEmpty()) { + if (objectSetBuilder_.isEmpty()) { + objectSetBuilder_.dispose(); + objectSetBuilder_ = null; + objectSet_ = other.objectSet_; + bitField0_ = (bitField0_ & ~0x00000002); + objectSetBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getObjectSetFieldBuilder() : null; + } else { + objectSetBuilder_.addAllMessages(other.objectSet_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasData()) { + + return false; + } + if (!getData().isInitialized()) { + + return false; + } + for (int i = 0; i < getObjectSetCount(); i++) { + if (!getObjectSet(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.ObjectData data = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData data_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder> dataBuilder_; + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + public boolean hasData() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData getData() { + if (dataBuilder_ == null) { + return data_; + } else { + return dataBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + public Builder setData(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData value) { + if (dataBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + data_ = value; + onChanged(); + } else { + dataBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + public Builder setData( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder builderForValue) { + if (dataBuilder_ == null) { + data_ = builderForValue.build(); + onChanged(); + } else { + dataBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + public Builder mergeData(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData value) { + if (dataBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + data_ != org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance()) { + data_ = + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.newBuilder(data_).mergeFrom(value).buildPartial(); + } else { + data_ = value; + } + onChanged(); + } else { + dataBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + public Builder clearData() { + if (dataBuilder_ == null) { + data_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + onChanged(); + } else { + dataBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder getDataBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getDataFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder getDataOrBuilder() { + if (dataBuilder_ != null) { + return dataBuilder_.getMessageOrBuilder(); + } else { + return data_; + } + } + /** + * required .xtreemfs.pbrpc.ObjectData data = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder> + getDataFieldBuilder() { + if (dataBuilder_ == null) { + dataBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder>( + data_, + getParentForChildren(), + isClean()); + data_ = null; + } + return dataBuilder_; + } + + // repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + private java.util.List objectSet_ = + java.util.Collections.emptyList(); + private void ensureObjectSetIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + objectSet_ = new java.util.ArrayList(objectSet_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder> objectSetBuilder_; + + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public java.util.List getObjectSetList() { + if (objectSetBuilder_ == null) { + return java.util.Collections.unmodifiableList(objectSet_); + } else { + return objectSetBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public int getObjectSetCount() { + if (objectSetBuilder_ == null) { + return objectSet_.size(); + } else { + return objectSetBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList getObjectSet(int index) { + if (objectSetBuilder_ == null) { + return objectSet_.get(index); + } else { + return objectSetBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public Builder setObjectSet( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList value) { + if (objectSetBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureObjectSetIsMutable(); + objectSet_.set(index, value); + onChanged(); + } else { + objectSetBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public Builder setObjectSet( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder builderForValue) { + if (objectSetBuilder_ == null) { + ensureObjectSetIsMutable(); + objectSet_.set(index, builderForValue.build()); + onChanged(); + } else { + objectSetBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public Builder addObjectSet(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList value) { + if (objectSetBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureObjectSetIsMutable(); + objectSet_.add(value); + onChanged(); + } else { + objectSetBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public Builder addObjectSet( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList value) { + if (objectSetBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureObjectSetIsMutable(); + objectSet_.add(index, value); + onChanged(); + } else { + objectSetBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public Builder addObjectSet( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder builderForValue) { + if (objectSetBuilder_ == null) { + ensureObjectSetIsMutable(); + objectSet_.add(builderForValue.build()); + onChanged(); + } else { + objectSetBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public Builder addObjectSet( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder builderForValue) { + if (objectSetBuilder_ == null) { + ensureObjectSetIsMutable(); + objectSet_.add(index, builderForValue.build()); + onChanged(); + } else { + objectSetBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public Builder addAllObjectSet( + java.lang.Iterable values) { + if (objectSetBuilder_ == null) { + ensureObjectSetIsMutable(); + super.addAll(values, objectSet_); + onChanged(); + } else { + objectSetBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public Builder clearObjectSet() { + if (objectSetBuilder_ == null) { + objectSet_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + objectSetBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public Builder removeObjectSet(int index) { + if (objectSetBuilder_ == null) { + ensureObjectSetIsMutable(); + objectSet_.remove(index); + onChanged(); + } else { + objectSetBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder getObjectSetBuilder( + int index) { + return getObjectSetFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder getObjectSetOrBuilder( + int index) { + if (objectSetBuilder_ == null) { + return objectSet_.get(index); } else { + return objectSetBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public java.util.List + getObjectSetOrBuilderList() { + if (objectSetBuilder_ != null) { + return objectSetBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(objectSet_); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder addObjectSetBuilder() { + return getObjectSetFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder addObjectSetBuilder( + int index) { + return getObjectSetFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.ObjectList object_set = 2; + * + *
    +       * List of objects the OSD has.
    +       * 
    + */ + public java.util.List + getObjectSetBuilderList() { + return getObjectSetFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder> + getObjectSetFieldBuilder() { + if (objectSetBuilder_ == null) { + objectSetBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder>( + objectSet_, + ((bitField0_ & 0x00000002) == 0x00000002), + getParentForChildren(), + isClean()); + objectSet_ = null; + } + return objectSetBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.InternalReadLocalResponse) + } + + static { + defaultInstance = new InternalReadLocalResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.InternalReadLocalResponse) + } + + public interface readRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 object_number = 3; + /** + * required fixed64 object_number = 3; + * + *
    +     * Object number starting at 0.
    +     * 
    + */ + boolean hasObjectNumber(); + /** + * required fixed64 object_number = 3; + * + *
    +     * Object number starting at 0.
    +     * 
    + */ + long getObjectNumber(); + + // required fixed64 object_version = 4; + /** + * required fixed64 object_version = 4; + * + *
    +     * Version, currently ignored.
    +     * 
    + */ + boolean hasObjectVersion(); + /** + * required fixed64 object_version = 4; + * + *
    +     * Version, currently ignored.
    +     * 
    + */ + long getObjectVersion(); + + // required fixed32 offset = 5; + /** + * required fixed32 offset = 5; + * + *
    +     * Offset within the object.
    +     * 
    + */ + boolean hasOffset(); + /** + * required fixed32 offset = 5; + * + *
    +     * Offset within the object.
    +     * 
    + */ + int getOffset(); + + // required fixed32 length = 6; + /** + * required fixed32 length = 6; + * + *
    +     * Length of data to be read, must be <= stripe_size - offset.
    +     * 
    + */ + boolean hasLength(); + /** + * required fixed32 length = 6; + * + *
    +     * Length of data to be read, must be <= stripe_size - offset.
    +     * 
    + */ + int getLength(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.readRequest} + */ + public static final class readRequest extends + com.google.protobuf.GeneratedMessage + implements readRequestOrBuilder { + // Use readRequest.newBuilder() to construct. + private readRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private readRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final readRequest defaultInstance; + public static readRequest getDefaultInstance() { + return defaultInstance; + } + + public readRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private readRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + objectNumber_ = input.readFixed64(); + break; + } + case 33: { + bitField0_ |= 0x00000008; + objectVersion_ = input.readFixed64(); + break; + } + case 45: { + bitField0_ |= 0x00000010; + offset_ = input.readFixed32(); + break; + } + case 53: { + bitField0_ |= 0x00000020; + length_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_readRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_readRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public readRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new readRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 object_number = 3; + public static final int OBJECT_NUMBER_FIELD_NUMBER = 3; + private long objectNumber_; + /** + * required fixed64 object_number = 3; + * + *
    +     * Object number starting at 0.
    +     * 
    + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + * + *
    +     * Object number starting at 0.
    +     * 
    + */ + public long getObjectNumber() { + return objectNumber_; + } + + // required fixed64 object_version = 4; + public static final int OBJECT_VERSION_FIELD_NUMBER = 4; + private long objectVersion_; + /** + * required fixed64 object_version = 4; + * + *
    +     * Version, currently ignored.
    +     * 
    + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + * + *
    +     * Version, currently ignored.
    +     * 
    + */ + public long getObjectVersion() { + return objectVersion_; + } + + // required fixed32 offset = 5; + public static final int OFFSET_FIELD_NUMBER = 5; + private int offset_; + /** + * required fixed32 offset = 5; + * + *
    +     * Offset within the object.
    +     * 
    + */ + public boolean hasOffset() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 offset = 5; + * + *
    +     * Offset within the object.
    +     * 
    + */ + public int getOffset() { + return offset_; + } + + // required fixed32 length = 6; + public static final int LENGTH_FIELD_NUMBER = 6; + private int length_; + /** + * required fixed32 length = 6; + * + *
    +     * Length of data to be read, must be <= stripe_size - offset.
    +     * 
    + */ + public boolean hasLength() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed32 length = 6; + * + *
    +     * Length of data to be read, must be <= stripe_size - offset.
    +     * 
    + */ + public int getLength() { + return length_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + objectNumber_ = 0L; + objectVersion_ = 0L; + offset_ = 0; + length_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectNumber()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOffset()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLength()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed64(4, objectVersion_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeFixed32(5, offset_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeFixed32(6, length_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(4, objectVersion_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(5, offset_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(6, length_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.readRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_readRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_readRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + objectNumber_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + objectVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + offset_ = 0; + bitField0_ = (bitField0_ & ~0x00000010); + length_ = 0; + bitField0_ = (bitField0_ & ~0x00000020); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_readRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.objectNumber_ = objectNumber_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.objectVersion_ = objectVersion_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.offset_ = offset_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.length_ = length_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasObjectNumber()) { + setObjectNumber(other.getObjectNumber()); + } + if (other.hasObjectVersion()) { + setObjectVersion(other.getObjectVersion()); + } + if (other.hasOffset()) { + setOffset(other.getOffset()); + } + if (other.hasLength()) { + setLength(other.getLength()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasObjectNumber()) { + + return false; + } + if (!hasObjectVersion()) { + + return false; + } + if (!hasOffset()) { + + return false; + } + if (!hasLength()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.readRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 object_number = 3; + private long objectNumber_ ; + /** + * required fixed64 object_number = 3; + * + *
    +       * Object number starting at 0.
    +       * 
    + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + * + *
    +       * Object number starting at 0.
    +       * 
    + */ + public long getObjectNumber() { + return objectNumber_; + } + /** + * required fixed64 object_number = 3; + * + *
    +       * Object number starting at 0.
    +       * 
    + */ + public Builder setObjectNumber(long value) { + bitField0_ |= 0x00000004; + objectNumber_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_number = 3; + * + *
    +       * Object number starting at 0.
    +       * 
    + */ + public Builder clearObjectNumber() { + bitField0_ = (bitField0_ & ~0x00000004); + objectNumber_ = 0L; + onChanged(); + return this; + } + + // required fixed64 object_version = 4; + private long objectVersion_ ; + /** + * required fixed64 object_version = 4; + * + *
    +       * Version, currently ignored.
    +       * 
    + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + * + *
    +       * Version, currently ignored.
    +       * 
    + */ + public long getObjectVersion() { + return objectVersion_; + } + /** + * required fixed64 object_version = 4; + * + *
    +       * Version, currently ignored.
    +       * 
    + */ + public Builder setObjectVersion(long value) { + bitField0_ |= 0x00000008; + objectVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_version = 4; + * + *
    +       * Version, currently ignored.
    +       * 
    + */ + public Builder clearObjectVersion() { + bitField0_ = (bitField0_ & ~0x00000008); + objectVersion_ = 0L; + onChanged(); + return this; + } + + // required fixed32 offset = 5; + private int offset_ ; + /** + * required fixed32 offset = 5; + * + *
    +       * Offset within the object.
    +       * 
    + */ + public boolean hasOffset() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 offset = 5; + * + *
    +       * Offset within the object.
    +       * 
    + */ + public int getOffset() { + return offset_; + } + /** + * required fixed32 offset = 5; + * + *
    +       * Offset within the object.
    +       * 
    + */ + public Builder setOffset(int value) { + bitField0_ |= 0x00000010; + offset_ = value; + onChanged(); + return this; + } + /** + * required fixed32 offset = 5; + * + *
    +       * Offset within the object.
    +       * 
    + */ + public Builder clearOffset() { + bitField0_ = (bitField0_ & ~0x00000010); + offset_ = 0; + onChanged(); + return this; + } + + // required fixed32 length = 6; + private int length_ ; + /** + * required fixed32 length = 6; + * + *
    +       * Length of data to be read, must be <= stripe_size - offset.
    +       * 
    + */ + public boolean hasLength() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed32 length = 6; + * + *
    +       * Length of data to be read, must be <= stripe_size - offset.
    +       * 
    + */ + public int getLength() { + return length_; + } + /** + * required fixed32 length = 6; + * + *
    +       * Length of data to be read, must be <= stripe_size - offset.
    +       * 
    + */ + public Builder setLength(int value) { + bitField0_ |= 0x00000020; + length_ = value; + onChanged(); + return this; + } + /** + * required fixed32 length = 6; + * + *
    +       * Length of data to be read, must be <= stripe_size - offset.
    +       * 
    + */ + public Builder clearLength() { + bitField0_ = (bitField0_ & ~0x00000020); + length_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.readRequest) + } + + static { + defaultInstance = new readRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.readRequest) + } + + public interface truncateRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 new_file_size = 3; + /** + * required fixed64 new_file_size = 3; + * + *
    +     * New file size in bytes.
    +     * 
    + */ + boolean hasNewFileSize(); + /** + * required fixed64 new_file_size = 3; + * + *
    +     * New file size in bytes.
    +     * 
    + */ + long getNewFileSize(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.truncateRequest} + */ + public static final class truncateRequest extends + com.google.protobuf.GeneratedMessage + implements truncateRequestOrBuilder { + // Use truncateRequest.newBuilder() to construct. + private truncateRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private truncateRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final truncateRequest defaultInstance; + public static truncateRequest getDefaultInstance() { + return defaultInstance; + } + + public truncateRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private truncateRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + newFileSize_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_truncateRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_truncateRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public truncateRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new truncateRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 new_file_size = 3; + public static final int NEW_FILE_SIZE_FIELD_NUMBER = 3; + private long newFileSize_; + /** + * required fixed64 new_file_size = 3; + * + *
    +     * New file size in bytes.
    +     * 
    + */ + public boolean hasNewFileSize() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 new_file_size = 3; + * + *
    +     * New file size in bytes.
    +     * 
    + */ + public long getNewFileSize() { + return newFileSize_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + newFileSize_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasNewFileSize()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, newFileSize_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, newFileSize_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.truncateRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_truncateRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_truncateRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + newFileSize_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_truncateRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.newFileSize_ = newFileSize_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasNewFileSize()) { + setNewFileSize(other.getNewFileSize()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasNewFileSize()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.truncateRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 new_file_size = 3; + private long newFileSize_ ; + /** + * required fixed64 new_file_size = 3; + * + *
    +       * New file size in bytes.
    +       * 
    + */ + public boolean hasNewFileSize() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 new_file_size = 3; + * + *
    +       * New file size in bytes.
    +       * 
    + */ + public long getNewFileSize() { + return newFileSize_; + } + /** + * required fixed64 new_file_size = 3; + * + *
    +       * New file size in bytes.
    +       * 
    + */ + public Builder setNewFileSize(long value) { + bitField0_ |= 0x00000004; + newFileSize_ = value; + onChanged(); + return this; + } + /** + * required fixed64 new_file_size = 3; + * + *
    +       * New file size in bytes.
    +       * 
    + */ + public Builder clearNewFileSize() { + bitField0_ = (bitField0_ & ~0x00000004); + newFileSize_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.truncateRequest) + } + + static { + defaultInstance = new truncateRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.truncateRequest) + } + + public interface unlink_osd_RequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.unlink_osd_Request} + */ + public static final class unlink_osd_Request extends + com.google.protobuf.GeneratedMessage + implements unlink_osd_RequestOrBuilder { + // Use unlink_osd_Request.newBuilder() to construct. + private unlink_osd_Request(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private unlink_osd_Request(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final unlink_osd_Request defaultInstance; + public static unlink_osd_Request getDefaultInstance() { + return defaultInstance; + } + + public unlink_osd_Request getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private unlink_osd_Request( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_unlink_osd_Request_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_unlink_osd_Request_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public unlink_osd_Request parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new unlink_osd_Request(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.unlink_osd_Request} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_RequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_unlink_osd_Request_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_unlink_osd_Request_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_unlink_osd_Request_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.unlink_osd_Request) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.unlink_osd_Request) + } + + static { + defaultInstance = new unlink_osd_Request(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.unlink_osd_Request) + } + + public interface writeRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 object_number = 3; + /** + * required fixed64 object_number = 3; + * + *
    +     * Object number starting at 0.
    +     * 
    + */ + boolean hasObjectNumber(); + /** + * required fixed64 object_number = 3; + * + *
    +     * Object number starting at 0.
    +     * 
    + */ + long getObjectNumber(); + + // required fixed64 object_version = 4; + /** + * required fixed64 object_version = 4; + * + *
    +     * Version, currently ignored.
    +     * 
    + */ + boolean hasObjectVersion(); + /** + * required fixed64 object_version = 4; + * + *
    +     * Version, currently ignored.
    +     * 
    + */ + long getObjectVersion(); + + // required fixed32 offset = 5; + /** + * required fixed32 offset = 5; + * + *
    +     * Offset within the object.
    +     * 
    + */ + boolean hasOffset(); + /** + * required fixed32 offset = 5; + * + *
    +     * Offset within the object.
    +     * 
    + */ + int getOffset(); + + // required fixed64 lease_timeout = 6; + /** + * required fixed64 lease_timeout = 6; + * + *
    +     * Timeout of the client lease, if set.
    +     * Reserved for client-side-caching, currently not used.
    +     * 
    + */ + boolean hasLeaseTimeout(); + /** + * required fixed64 lease_timeout = 6; + * + *
    +     * Timeout of the client lease, if set.
    +     * Reserved for client-side-caching, currently not used.
    +     * 
    + */ + long getLeaseTimeout(); + + // required .xtreemfs.pbrpc.ObjectData object_data = 7; + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +     * Only the checksum of ObjectData is used.
    +     * 
    + */ + boolean hasObjectData(); + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +     * Only the checksum of ObjectData is used.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData getObjectData(); + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +     * Only the checksum of ObjectData is used.
    +     * 
    + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder getObjectDataOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.writeRequest} + */ + public static final class writeRequest extends + com.google.protobuf.GeneratedMessage + implements writeRequestOrBuilder { + // Use writeRequest.newBuilder() to construct. + private writeRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private writeRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final writeRequest defaultInstance; + public static writeRequest getDefaultInstance() { + return defaultInstance; + } + + public writeRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private writeRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + objectNumber_ = input.readFixed64(); + break; + } + case 33: { + bitField0_ |= 0x00000008; + objectVersion_ = input.readFixed64(); + break; + } + case 45: { + bitField0_ |= 0x00000010; + offset_ = input.readFixed32(); + break; + } + case 49: { + bitField0_ |= 0x00000020; + leaseTimeout_ = input.readFixed64(); + break; + } + case 58: { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder subBuilder = null; + if (((bitField0_ & 0x00000040) == 0x00000040)) { + subBuilder = objectData_.toBuilder(); + } + objectData_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(objectData_); + objectData_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000040; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_writeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_writeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public writeRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new writeRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 object_number = 3; + public static final int OBJECT_NUMBER_FIELD_NUMBER = 3; + private long objectNumber_; + /** + * required fixed64 object_number = 3; + * + *
    +     * Object number starting at 0.
    +     * 
    + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + * + *
    +     * Object number starting at 0.
    +     * 
    + */ + public long getObjectNumber() { + return objectNumber_; + } + + // required fixed64 object_version = 4; + public static final int OBJECT_VERSION_FIELD_NUMBER = 4; + private long objectVersion_; + /** + * required fixed64 object_version = 4; + * + *
    +     * Version, currently ignored.
    +     * 
    + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + * + *
    +     * Version, currently ignored.
    +     * 
    + */ + public long getObjectVersion() { + return objectVersion_; + } + + // required fixed32 offset = 5; + public static final int OFFSET_FIELD_NUMBER = 5; + private int offset_; + /** + * required fixed32 offset = 5; + * + *
    +     * Offset within the object.
    +     * 
    + */ + public boolean hasOffset() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 offset = 5; + * + *
    +     * Offset within the object.
    +     * 
    + */ + public int getOffset() { + return offset_; + } + + // required fixed64 lease_timeout = 6; + public static final int LEASE_TIMEOUT_FIELD_NUMBER = 6; + private long leaseTimeout_; + /** + * required fixed64 lease_timeout = 6; + * + *
    +     * Timeout of the client lease, if set.
    +     * Reserved for client-side-caching, currently not used.
    +     * 
    + */ + public boolean hasLeaseTimeout() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed64 lease_timeout = 6; + * + *
    +     * Timeout of the client lease, if set.
    +     * Reserved for client-side-caching, currently not used.
    +     * 
    + */ + public long getLeaseTimeout() { + return leaseTimeout_; + } + + // required .xtreemfs.pbrpc.ObjectData object_data = 7; + public static final int OBJECT_DATA_FIELD_NUMBER = 7; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData objectData_; + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +     * Only the checksum of ObjectData is used.
    +     * 
    + */ + public boolean hasObjectData() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +     * Only the checksum of ObjectData is used.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData getObjectData() { + return objectData_; + } + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +     * Only the checksum of ObjectData is used.
    +     * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder getObjectDataOrBuilder() { + return objectData_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + objectNumber_ = 0L; + objectVersion_ = 0L; + offset_ = 0; + leaseTimeout_ = 0L; + objectData_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectNumber()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOffset()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLeaseTimeout()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectData()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getObjectData().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed64(4, objectVersion_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeFixed32(5, offset_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeFixed64(6, leaseTimeout_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeMessage(7, objectData_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(4, objectVersion_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(5, offset_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(6, leaseTimeout_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(7, objectData_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.writeRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_writeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_writeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + getObjectDataFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + objectNumber_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + objectVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + offset_ = 0; + bitField0_ = (bitField0_ & ~0x00000010); + leaseTimeout_ = 0L; + bitField0_ = (bitField0_ & ~0x00000020); + if (objectDataBuilder_ == null) { + objectData_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + } else { + objectDataBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000040); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_writeRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.objectNumber_ = objectNumber_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.objectVersion_ = objectVersion_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.offset_ = offset_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.leaseTimeout_ = leaseTimeout_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000040; + } + if (objectDataBuilder_ == null) { + result.objectData_ = objectData_; + } else { + result.objectData_ = objectDataBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasObjectNumber()) { + setObjectNumber(other.getObjectNumber()); + } + if (other.hasObjectVersion()) { + setObjectVersion(other.getObjectVersion()); + } + if (other.hasOffset()) { + setOffset(other.getOffset()); + } + if (other.hasLeaseTimeout()) { + setLeaseTimeout(other.getLeaseTimeout()); + } + if (other.hasObjectData()) { + mergeObjectData(other.getObjectData()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasObjectNumber()) { + + return false; + } + if (!hasObjectVersion()) { + + return false; + } + if (!hasOffset()) { + + return false; + } + if (!hasLeaseTimeout()) { + + return false; + } + if (!hasObjectData()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + if (!getObjectData().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 object_number = 3; + private long objectNumber_ ; + /** + * required fixed64 object_number = 3; + * + *
    +       * Object number starting at 0.
    +       * 
    + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + * + *
    +       * Object number starting at 0.
    +       * 
    + */ + public long getObjectNumber() { + return objectNumber_; + } + /** + * required fixed64 object_number = 3; + * + *
    +       * Object number starting at 0.
    +       * 
    + */ + public Builder setObjectNumber(long value) { + bitField0_ |= 0x00000004; + objectNumber_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_number = 3; + * + *
    +       * Object number starting at 0.
    +       * 
    + */ + public Builder clearObjectNumber() { + bitField0_ = (bitField0_ & ~0x00000004); + objectNumber_ = 0L; + onChanged(); + return this; + } + + // required fixed64 object_version = 4; + private long objectVersion_ ; + /** + * required fixed64 object_version = 4; + * + *
    +       * Version, currently ignored.
    +       * 
    + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + * + *
    +       * Version, currently ignored.
    +       * 
    + */ + public long getObjectVersion() { + return objectVersion_; + } + /** + * required fixed64 object_version = 4; + * + *
    +       * Version, currently ignored.
    +       * 
    + */ + public Builder setObjectVersion(long value) { + bitField0_ |= 0x00000008; + objectVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_version = 4; + * + *
    +       * Version, currently ignored.
    +       * 
    + */ + public Builder clearObjectVersion() { + bitField0_ = (bitField0_ & ~0x00000008); + objectVersion_ = 0L; + onChanged(); + return this; + } + + // required fixed32 offset = 5; + private int offset_ ; + /** + * required fixed32 offset = 5; + * + *
    +       * Offset within the object.
    +       * 
    + */ + public boolean hasOffset() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 offset = 5; + * + *
    +       * Offset within the object.
    +       * 
    + */ + public int getOffset() { + return offset_; + } + /** + * required fixed32 offset = 5; + * + *
    +       * Offset within the object.
    +       * 
    + */ + public Builder setOffset(int value) { + bitField0_ |= 0x00000010; + offset_ = value; + onChanged(); + return this; + } + /** + * required fixed32 offset = 5; + * + *
    +       * Offset within the object.
    +       * 
    + */ + public Builder clearOffset() { + bitField0_ = (bitField0_ & ~0x00000010); + offset_ = 0; + onChanged(); + return this; + } + + // required fixed64 lease_timeout = 6; + private long leaseTimeout_ ; + /** + * required fixed64 lease_timeout = 6; + * + *
    +       * Timeout of the client lease, if set.
    +       * Reserved for client-side-caching, currently not used.
    +       * 
    + */ + public boolean hasLeaseTimeout() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed64 lease_timeout = 6; + * + *
    +       * Timeout of the client lease, if set.
    +       * Reserved for client-side-caching, currently not used.
    +       * 
    + */ + public long getLeaseTimeout() { + return leaseTimeout_; + } + /** + * required fixed64 lease_timeout = 6; + * + *
    +       * Timeout of the client lease, if set.
    +       * Reserved for client-side-caching, currently not used.
    +       * 
    + */ + public Builder setLeaseTimeout(long value) { + bitField0_ |= 0x00000020; + leaseTimeout_ = value; + onChanged(); + return this; + } + /** + * required fixed64 lease_timeout = 6; + * + *
    +       * Timeout of the client lease, if set.
    +       * Reserved for client-side-caching, currently not used.
    +       * 
    + */ + public Builder clearLeaseTimeout() { + bitField0_ = (bitField0_ & ~0x00000020); + leaseTimeout_ = 0L; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.ObjectData object_data = 7; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData objectData_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder> objectDataBuilder_; + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +       * Only the checksum of ObjectData is used.
    +       * 
    + */ + public boolean hasObjectData() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +       * Only the checksum of ObjectData is used.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData getObjectData() { + if (objectDataBuilder_ == null) { + return objectData_; + } else { + return objectDataBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +       * Only the checksum of ObjectData is used.
    +       * 
    + */ + public Builder setObjectData(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData value) { + if (objectDataBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + objectData_ = value; + onChanged(); + } else { + objectDataBuilder_.setMessage(value); + } + bitField0_ |= 0x00000040; + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +       * Only the checksum of ObjectData is used.
    +       * 
    + */ + public Builder setObjectData( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder builderForValue) { + if (objectDataBuilder_ == null) { + objectData_ = builderForValue.build(); + onChanged(); + } else { + objectDataBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000040; + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +       * Only the checksum of ObjectData is used.
    +       * 
    + */ + public Builder mergeObjectData(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData value) { + if (objectDataBuilder_ == null) { + if (((bitField0_ & 0x00000040) == 0x00000040) && + objectData_ != org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance()) { + objectData_ = + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.newBuilder(objectData_).mergeFrom(value).buildPartial(); + } else { + objectData_ = value; + } + onChanged(); + } else { + objectDataBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000040; + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +       * Only the checksum of ObjectData is used.
    +       * 
    + */ + public Builder clearObjectData() { + if (objectDataBuilder_ == null) { + objectData_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + onChanged(); + } else { + objectDataBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000040); + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +       * Only the checksum of ObjectData is used.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder getObjectDataBuilder() { + bitField0_ |= 0x00000040; + onChanged(); + return getObjectDataFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +       * Only the checksum of ObjectData is used.
    +       * 
    + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder getObjectDataOrBuilder() { + if (objectDataBuilder_ != null) { + return objectDataBuilder_.getMessageOrBuilder(); + } else { + return objectData_; + } + } + /** + * required .xtreemfs.pbrpc.ObjectData object_data = 7; + * + *
    +       * Only the checksum of ObjectData is used.
    +       * 
    + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder> + getObjectDataFieldBuilder() { + if (objectDataBuilder_ == null) { + objectDataBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder>( + objectData_, + getParentForChildren(), + isClean()); + objectData_ = null; + } + return objectDataBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.writeRequest) + } + + static { + defaultInstance = new writeRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.writeRequest) + } + + public interface xtreemfs_broadcast_gmaxRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string file_id = 1; + /** + * required string file_id = 1; + */ + boolean hasFileId(); + /** + * required string file_id = 1; + */ + java.lang.String getFileId(); + /** + * required string file_id = 1; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 truncate_epoch = 2; + /** + * required fixed64 truncate_epoch = 2; + */ + boolean hasTruncateEpoch(); + /** + * required fixed64 truncate_epoch = 2; + */ + long getTruncateEpoch(); + + // required fixed64 last_object = 3; + /** + * required fixed64 last_object = 3; + */ + boolean hasLastObject(); + /** + * required fixed64 last_object = 3; + */ + long getLastObject(); + + // required fixed64 file_size = 4; + /** + * required fixed64 file_size = 4; + */ + boolean hasFileSize(); + /** + * required fixed64 file_size = 4; + */ + long getFileSize(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_broadcast_gmaxRequest} + * + *
    +   * Internal message sent between OSDs of a striped file.
    +   * Transmitted via UDP.
    +   * 
    + */ + public static final class xtreemfs_broadcast_gmaxRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_broadcast_gmaxRequestOrBuilder { + // Use xtreemfs_broadcast_gmaxRequest.newBuilder() to construct. + private xtreemfs_broadcast_gmaxRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_broadcast_gmaxRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_broadcast_gmaxRequest defaultInstance; + public static xtreemfs_broadcast_gmaxRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_broadcast_gmaxRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_broadcast_gmaxRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + fileId_ = input.readBytes(); + break; + } + case 17: { + bitField0_ |= 0x00000002; + truncateEpoch_ = input.readFixed64(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + lastObject_ = input.readFixed64(); + break; + } + case 33: { + bitField0_ |= 0x00000008; + fileSize_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_broadcast_gmaxRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_broadcast_gmaxRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_broadcast_gmaxRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_broadcast_gmaxRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string file_id = 1; + public static final int FILE_ID_FIELD_NUMBER = 1; + private java.lang.Object fileId_; + /** + * required string file_id = 1; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string file_id = 1; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 1; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 truncate_epoch = 2; + public static final int TRUNCATE_EPOCH_FIELD_NUMBER = 2; + private long truncateEpoch_; + /** + * required fixed64 truncate_epoch = 2; + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 truncate_epoch = 2; + */ + public long getTruncateEpoch() { + return truncateEpoch_; + } + + // required fixed64 last_object = 3; + public static final int LAST_OBJECT_FIELD_NUMBER = 3; + private long lastObject_; + /** + * required fixed64 last_object = 3; + */ + public boolean hasLastObject() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 last_object = 3; + */ + public long getLastObject() { + return lastObject_; + } + + // required fixed64 file_size = 4; + public static final int FILE_SIZE_FIELD_NUMBER = 4; + private long fileSize_; + /** + * required fixed64 file_size = 4; + */ + public boolean hasFileSize() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 file_size = 4; + */ + public long getFileSize() { + return fileSize_; + } + + private void initFields() { + fileId_ = ""; + truncateEpoch_ = 0L; + lastObject_ = 0L; + fileSize_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTruncateEpoch()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLastObject()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileSize()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed64(2, truncateEpoch_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, lastObject_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed64(4, fileSize_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getFileIdBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(2, truncateEpoch_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, lastObject_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(4, fileSize_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_broadcast_gmaxRequest} + * + *
    +     * Internal message sent between OSDs of a striped file.
    +     * Transmitted via UDP.
    +     * 
    + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_broadcast_gmaxRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_broadcast_gmaxRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + truncateEpoch_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + lastObject_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + fileSize_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_broadcast_gmaxRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.truncateEpoch_ = truncateEpoch_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.lastObject_ = lastObject_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.fileSize_ = fileSize_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest.getDefaultInstance()) return this; + if (other.hasFileId()) { + bitField0_ |= 0x00000001; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasTruncateEpoch()) { + setTruncateEpoch(other.getTruncateEpoch()); + } + if (other.hasLastObject()) { + setLastObject(other.getLastObject()); + } + if (other.hasFileSize()) { + setFileSize(other.getFileSize()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileId()) { + + return false; + } + if (!hasTruncateEpoch()) { + + return false; + } + if (!hasLastObject()) { + + return false; + } + if (!hasFileSize()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_broadcast_gmaxRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string file_id = 1; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 1; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string file_id = 1; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 1; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 1; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 1; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 1; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 truncate_epoch = 2; + private long truncateEpoch_ ; + /** + * required fixed64 truncate_epoch = 2; + */ + public boolean hasTruncateEpoch() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed64 truncate_epoch = 2; + */ + public long getTruncateEpoch() { + return truncateEpoch_; + } + /** + * required fixed64 truncate_epoch = 2; + */ + public Builder setTruncateEpoch(long value) { + bitField0_ |= 0x00000002; + truncateEpoch_ = value; + onChanged(); + return this; + } + /** + * required fixed64 truncate_epoch = 2; + */ + public Builder clearTruncateEpoch() { + bitField0_ = (bitField0_ & ~0x00000002); + truncateEpoch_ = 0L; + onChanged(); + return this; + } + + // required fixed64 last_object = 3; + private long lastObject_ ; + /** + * required fixed64 last_object = 3; + */ + public boolean hasLastObject() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 last_object = 3; + */ + public long getLastObject() { + return lastObject_; + } + /** + * required fixed64 last_object = 3; + */ + public Builder setLastObject(long value) { + bitField0_ |= 0x00000004; + lastObject_ = value; + onChanged(); + return this; + } + /** + * required fixed64 last_object = 3; + */ + public Builder clearLastObject() { + bitField0_ = (bitField0_ & ~0x00000004); + lastObject_ = 0L; + onChanged(); + return this; + } + + // required fixed64 file_size = 4; + private long fileSize_ ; + /** + * required fixed64 file_size = 4; + */ + public boolean hasFileSize() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 file_size = 4; + */ + public long getFileSize() { + return fileSize_; + } + /** + * required fixed64 file_size = 4; + */ + public Builder setFileSize(long value) { + bitField0_ |= 0x00000008; + fileSize_ = value; + onChanged(); + return this; + } + /** + * required fixed64 file_size = 4; + */ + public Builder clearFileSize() { + bitField0_ = (bitField0_ & ~0x00000008); + fileSize_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_broadcast_gmaxRequest) + } + + static { + defaultInstance = new xtreemfs_broadcast_gmaxRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_broadcast_gmaxRequest) + } + + public interface xtreemfs_check_objectRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 object_number = 3; + /** + * required fixed64 object_number = 3; + */ + boolean hasObjectNumber(); + /** + * required fixed64 object_number = 3; + */ + long getObjectNumber(); + + // required fixed64 object_version = 4; + /** + * required fixed64 object_version = 4; + */ + boolean hasObjectVersion(); + /** + * required fixed64 object_version = 4; + */ + long getObjectVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_check_objectRequest} + */ + public static final class xtreemfs_check_objectRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_check_objectRequestOrBuilder { + // Use xtreemfs_check_objectRequest.newBuilder() to construct. + private xtreemfs_check_objectRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_check_objectRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_check_objectRequest defaultInstance; + public static xtreemfs_check_objectRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_check_objectRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_check_objectRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + objectNumber_ = input.readFixed64(); + break; + } + case 33: { + bitField0_ |= 0x00000008; + objectVersion_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_check_objectRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_check_objectRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_check_objectRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_check_objectRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 object_number = 3; + public static final int OBJECT_NUMBER_FIELD_NUMBER = 3; + private long objectNumber_; + /** + * required fixed64 object_number = 3; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + */ + public long getObjectNumber() { + return objectNumber_; + } + + // required fixed64 object_version = 4; + public static final int OBJECT_VERSION_FIELD_NUMBER = 4; + private long objectVersion_; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + objectNumber_ = 0L; + objectVersion_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectNumber()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed64(4, objectVersion_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(4, objectVersion_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_check_objectRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_check_objectRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_check_objectRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + objectNumber_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + objectVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_check_objectRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.objectNumber_ = objectNumber_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.objectVersion_ = objectVersion_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasObjectNumber()) { + setObjectNumber(other.getObjectNumber()); + } + if (other.hasObjectVersion()) { + setObjectVersion(other.getObjectVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasObjectNumber()) { + + return false; + } + if (!hasObjectVersion()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_check_objectRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 object_number = 3; + private long objectNumber_ ; + /** + * required fixed64 object_number = 3; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + */ + public long getObjectNumber() { + return objectNumber_; + } + /** + * required fixed64 object_number = 3; + */ + public Builder setObjectNumber(long value) { + bitField0_ |= 0x00000004; + objectNumber_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_number = 3; + */ + public Builder clearObjectNumber() { + bitField0_ = (bitField0_ & ~0x00000004); + objectNumber_ = 0L; + onChanged(); + return this; + } + + // required fixed64 object_version = 4; + private long objectVersion_ ; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + /** + * required fixed64 object_version = 4; + */ + public Builder setObjectVersion(long value) { + bitField0_ |= 0x00000008; + objectVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_version = 4; + */ + public Builder clearObjectVersion() { + bitField0_ = (bitField0_ & ~0x00000008); + objectVersion_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_check_objectRequest) + } + + static { + defaultInstance = new xtreemfs_check_objectRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_check_objectRequest) + } + + public interface xtreemfs_cleanup_get_resultsResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated string results = 1; + /** + * repeated string results = 1; + * + *
    +     * Human readable English status and error messages.
    +     * 
    + */ + java.util.List + getResultsList(); + /** + * repeated string results = 1; + * + *
    +     * Human readable English status and error messages.
    +     * 
    + */ + int getResultsCount(); + /** + * repeated string results = 1; + * + *
    +     * Human readable English status and error messages.
    +     * 
    + */ + java.lang.String getResults(int index); + /** + * repeated string results = 1; + * + *
    +     * Human readable English status and error messages.
    +     * 
    + */ + com.google.protobuf.ByteString + getResultsBytes(int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_cleanup_get_resultsResponse} + */ + public static final class xtreemfs_cleanup_get_resultsResponse extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_cleanup_get_resultsResponseOrBuilder { + // Use xtreemfs_cleanup_get_resultsResponse.newBuilder() to construct. + private xtreemfs_cleanup_get_resultsResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_cleanup_get_resultsResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_cleanup_get_resultsResponse defaultInstance; + public static xtreemfs_cleanup_get_resultsResponse getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_cleanup_get_resultsResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_cleanup_get_resultsResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + results_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000001; + } + results_.add(input.readBytes()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + results_ = new com.google.protobuf.UnmodifiableLazyStringList(results_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_get_resultsResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_get_resultsResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_cleanup_get_resultsResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_cleanup_get_resultsResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated string results = 1; + public static final int RESULTS_FIELD_NUMBER = 1; + private com.google.protobuf.LazyStringList results_; + /** + * repeated string results = 1; + * + *
    +     * Human readable English status and error messages.
    +     * 
    + */ + public java.util.List + getResultsList() { + return results_; + } + /** + * repeated string results = 1; + * + *
    +     * Human readable English status and error messages.
    +     * 
    + */ + public int getResultsCount() { + return results_.size(); + } + /** + * repeated string results = 1; + * + *
    +     * Human readable English status and error messages.
    +     * 
    + */ + public java.lang.String getResults(int index) { + return results_.get(index); + } + /** + * repeated string results = 1; + * + *
    +     * Human readable English status and error messages.
    +     * 
    + */ + public com.google.protobuf.ByteString + getResultsBytes(int index) { + return results_.getByteString(index); + } + + private void initFields() { + results_ = com.google.protobuf.LazyStringArrayList.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < results_.size(); i++) { + output.writeBytes(1, results_.getByteString(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < results_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(results_.getByteString(i)); + } + size += dataSize; + size += 1 * getResultsList().size(); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_cleanup_get_resultsResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_get_resultsResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_get_resultsResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + results_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_get_resultsResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse(this); + int from_bitField0_ = bitField0_; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + results_ = new com.google.protobuf.UnmodifiableLazyStringList( + results_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.results_ = results_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse.getDefaultInstance()) return this; + if (!other.results_.isEmpty()) { + if (results_.isEmpty()) { + results_ = other.results_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureResultsIsMutable(); + results_.addAll(other.results_); + } + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated string results = 1; + private com.google.protobuf.LazyStringList results_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureResultsIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + results_ = new com.google.protobuf.LazyStringArrayList(results_); + bitField0_ |= 0x00000001; + } + } + /** + * repeated string results = 1; + * + *
    +       * Human readable English status and error messages.
    +       * 
    + */ + public java.util.List + getResultsList() { + return java.util.Collections.unmodifiableList(results_); + } + /** + * repeated string results = 1; + * + *
    +       * Human readable English status and error messages.
    +       * 
    + */ + public int getResultsCount() { + return results_.size(); + } + /** + * repeated string results = 1; + * + *
    +       * Human readable English status and error messages.
    +       * 
    + */ + public java.lang.String getResults(int index) { + return results_.get(index); + } + /** + * repeated string results = 1; + * + *
    +       * Human readable English status and error messages.
    +       * 
    + */ + public com.google.protobuf.ByteString + getResultsBytes(int index) { + return results_.getByteString(index); + } + /** + * repeated string results = 1; + * + *
    +       * Human readable English status and error messages.
    +       * 
    + */ + public Builder setResults( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureResultsIsMutable(); + results_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string results = 1; + * + *
    +       * Human readable English status and error messages.
    +       * 
    + */ + public Builder addResults( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureResultsIsMutable(); + results_.add(value); + onChanged(); + return this; + } + /** + * repeated string results = 1; + * + *
    +       * Human readable English status and error messages.
    +       * 
    + */ + public Builder addAllResults( + java.lang.Iterable values) { + ensureResultsIsMutable(); + super.addAll(values, results_); + onChanged(); + return this; + } + /** + * repeated string results = 1; + * + *
    +       * Human readable English status and error messages.
    +       * 
    + */ + public Builder clearResults() { + results_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * repeated string results = 1; + * + *
    +       * Human readable English status and error messages.
    +       * 
    + */ + public Builder addResultsBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureResultsIsMutable(); + results_.add(value); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_cleanup_get_resultsResponse) + } + + static { + defaultInstance = new xtreemfs_cleanup_get_resultsResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_cleanup_get_resultsResponse) + } + + public interface xtreemfs_cleanup_is_runningResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required bool is_running = 1; + /** + * required bool is_running = 1; + */ + boolean hasIsRunning(); + /** + * required bool is_running = 1; + */ + boolean getIsRunning(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_cleanup_is_runningResponse} + */ + public static final class xtreemfs_cleanup_is_runningResponse extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_cleanup_is_runningResponseOrBuilder { + // Use xtreemfs_cleanup_is_runningResponse.newBuilder() to construct. + private xtreemfs_cleanup_is_runningResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_cleanup_is_runningResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_cleanup_is_runningResponse defaultInstance; + public static xtreemfs_cleanup_is_runningResponse getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_cleanup_is_runningResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_cleanup_is_runningResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + bitField0_ |= 0x00000001; + isRunning_ = input.readBool(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_is_runningResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_is_runningResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_cleanup_is_runningResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_cleanup_is_runningResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required bool is_running = 1; + public static final int IS_RUNNING_FIELD_NUMBER = 1; + private boolean isRunning_; + /** + * required bool is_running = 1; + */ + public boolean hasIsRunning() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required bool is_running = 1; + */ + public boolean getIsRunning() { + return isRunning_; + } + + private void initFields() { + isRunning_ = false; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasIsRunning()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBool(1, isRunning_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(1, isRunning_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_cleanup_is_runningResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_is_runningResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_is_runningResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + isRunning_ = false; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_is_runningResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.isRunning_ = isRunning_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse.getDefaultInstance()) return this; + if (other.hasIsRunning()) { + setIsRunning(other.getIsRunning()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasIsRunning()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required bool is_running = 1; + private boolean isRunning_ ; + /** + * required bool is_running = 1; + */ + public boolean hasIsRunning() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required bool is_running = 1; + */ + public boolean getIsRunning() { + return isRunning_; + } + /** + * required bool is_running = 1; + */ + public Builder setIsRunning(boolean value) { + bitField0_ |= 0x00000001; + isRunning_ = value; + onChanged(); + return this; + } + /** + * required bool is_running = 1; + */ + public Builder clearIsRunning() { + bitField0_ = (bitField0_ & ~0x00000001); + isRunning_ = false; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_cleanup_is_runningResponse) + } + + static { + defaultInstance = new xtreemfs_cleanup_is_runningResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_cleanup_is_runningResponse) + } + + public interface xtreemfs_cleanup_startRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required bool remove_zombies = 1; + /** + * required bool remove_zombies = 1; + * + *
    +     * If true, objects for deleted files are deleted as well.
    +     * 
    + */ + boolean hasRemoveZombies(); + /** + * required bool remove_zombies = 1; + * + *
    +     * If true, objects for deleted files are deleted as well.
    +     * 
    + */ + boolean getRemoveZombies(); + + // required bool remove_unavail_volume = 2; + /** + * required bool remove_unavail_volume = 2; + * + *
    +     * If true, files for which the MRC cannot be contacted or
    +     * where no volume DIR entry exists are deleted.
    +     * 
    + */ + boolean hasRemoveUnavailVolume(); + /** + * required bool remove_unavail_volume = 2; + * + *
    +     * If true, files for which the MRC cannot be contacted or
    +     * where no volume DIR entry exists are deleted.
    +     * 
    + */ + boolean getRemoveUnavailVolume(); + + // required bool lost_and_found = 3; + /** + * required bool lost_and_found = 3; + * + *
    +     * If true, objects are not deleted but moved to lost and found.
    +     * 
    + */ + boolean hasLostAndFound(); + /** + * required bool lost_and_found = 3; + * + *
    +     * If true, objects are not deleted but moved to lost and found.
    +     * 
    + */ + boolean getLostAndFound(); + + // required bool delete_metadata = 4; + /** + * required bool delete_metadata = 4; + * + *
    +     * Delete metadata of deleted or abandoned files.
    +     * 
    + */ + boolean hasDeleteMetadata(); + /** + * required bool delete_metadata = 4; + * + *
    +     * Delete metadata of deleted or abandoned files.
    +     * 
    + */ + boolean getDeleteMetadata(); + + // required fixed32 metadata_timeout = 5; + /** + * required fixed32 metadata_timeout = 5; + * + *
    +     * Time in seconds to wait after the last view update before
    +     * deleting metadata.
    +     * 
    + */ + boolean hasMetadataTimeout(); + /** + * required fixed32 metadata_timeout = 5; + * + *
    +     * Time in seconds to wait after the last view update before
    +     * deleting metadata.
    +     * 
    + */ + int getMetadataTimeout(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_cleanup_startRequest} + */ + public static final class xtreemfs_cleanup_startRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_cleanup_startRequestOrBuilder { + // Use xtreemfs_cleanup_startRequest.newBuilder() to construct. + private xtreemfs_cleanup_startRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_cleanup_startRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_cleanup_startRequest defaultInstance; + public static xtreemfs_cleanup_startRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_cleanup_startRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_cleanup_startRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + bitField0_ |= 0x00000001; + removeZombies_ = input.readBool(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + removeUnavailVolume_ = input.readBool(); + break; + } + case 24: { + bitField0_ |= 0x00000004; + lostAndFound_ = input.readBool(); + break; + } + case 32: { + bitField0_ |= 0x00000008; + deleteMetadata_ = input.readBool(); + break; + } + case 45: { + bitField0_ |= 0x00000010; + metadataTimeout_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_startRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_startRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_cleanup_startRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_cleanup_startRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required bool remove_zombies = 1; + public static final int REMOVE_ZOMBIES_FIELD_NUMBER = 1; + private boolean removeZombies_; + /** + * required bool remove_zombies = 1; + * + *
    +     * If true, objects for deleted files are deleted as well.
    +     * 
    + */ + public boolean hasRemoveZombies() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required bool remove_zombies = 1; + * + *
    +     * If true, objects for deleted files are deleted as well.
    +     * 
    + */ + public boolean getRemoveZombies() { + return removeZombies_; + } + + // required bool remove_unavail_volume = 2; + public static final int REMOVE_UNAVAIL_VOLUME_FIELD_NUMBER = 2; + private boolean removeUnavailVolume_; + /** + * required bool remove_unavail_volume = 2; + * + *
    +     * If true, files for which the MRC cannot be contacted or
    +     * where no volume DIR entry exists are deleted.
    +     * 
    + */ + public boolean hasRemoveUnavailVolume() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool remove_unavail_volume = 2; + * + *
    +     * If true, files for which the MRC cannot be contacted or
    +     * where no volume DIR entry exists are deleted.
    +     * 
    + */ + public boolean getRemoveUnavailVolume() { + return removeUnavailVolume_; + } + + // required bool lost_and_found = 3; + public static final int LOST_AND_FOUND_FIELD_NUMBER = 3; + private boolean lostAndFound_; + /** + * required bool lost_and_found = 3; + * + *
    +     * If true, objects are not deleted but moved to lost and found.
    +     * 
    + */ + public boolean hasLostAndFound() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required bool lost_and_found = 3; + * + *
    +     * If true, objects are not deleted but moved to lost and found.
    +     * 
    + */ + public boolean getLostAndFound() { + return lostAndFound_; + } + + // required bool delete_metadata = 4; + public static final int DELETE_METADATA_FIELD_NUMBER = 4; + private boolean deleteMetadata_; + /** + * required bool delete_metadata = 4; + * + *
    +     * Delete metadata of deleted or abandoned files.
    +     * 
    + */ + public boolean hasDeleteMetadata() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required bool delete_metadata = 4; + * + *
    +     * Delete metadata of deleted or abandoned files.
    +     * 
    + */ + public boolean getDeleteMetadata() { + return deleteMetadata_; + } + + // required fixed32 metadata_timeout = 5; + public static final int METADATA_TIMEOUT_FIELD_NUMBER = 5; + private int metadataTimeout_; + /** + * required fixed32 metadata_timeout = 5; + * + *
    +     * Time in seconds to wait after the last view update before
    +     * deleting metadata.
    +     * 
    + */ + public boolean hasMetadataTimeout() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 metadata_timeout = 5; + * + *
    +     * Time in seconds to wait after the last view update before
    +     * deleting metadata.
    +     * 
    + */ + public int getMetadataTimeout() { + return metadataTimeout_; + } + + private void initFields() { + removeZombies_ = false; + removeUnavailVolume_ = false; + lostAndFound_ = false; + deleteMetadata_ = false; + metadataTimeout_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasRemoveZombies()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasRemoveUnavailVolume()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLostAndFound()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasDeleteMetadata()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMetadataTimeout()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBool(1, removeZombies_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBool(2, removeUnavailVolume_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBool(3, lostAndFound_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBool(4, deleteMetadata_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeFixed32(5, metadataTimeout_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(1, removeZombies_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(2, removeUnavailVolume_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(3, lostAndFound_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(4, deleteMetadata_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(5, metadataTimeout_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_cleanup_startRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_startRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_startRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + removeZombies_ = false; + bitField0_ = (bitField0_ & ~0x00000001); + removeUnavailVolume_ = false; + bitField0_ = (bitField0_ & ~0x00000002); + lostAndFound_ = false; + bitField0_ = (bitField0_ & ~0x00000004); + deleteMetadata_ = false; + bitField0_ = (bitField0_ & ~0x00000008); + metadataTimeout_ = 0; + bitField0_ = (bitField0_ & ~0x00000010); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_startRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.removeZombies_ = removeZombies_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.removeUnavailVolume_ = removeUnavailVolume_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.lostAndFound_ = lostAndFound_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.deleteMetadata_ = deleteMetadata_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.metadataTimeout_ = metadataTimeout_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest.getDefaultInstance()) return this; + if (other.hasRemoveZombies()) { + setRemoveZombies(other.getRemoveZombies()); + } + if (other.hasRemoveUnavailVolume()) { + setRemoveUnavailVolume(other.getRemoveUnavailVolume()); + } + if (other.hasLostAndFound()) { + setLostAndFound(other.getLostAndFound()); + } + if (other.hasDeleteMetadata()) { + setDeleteMetadata(other.getDeleteMetadata()); + } + if (other.hasMetadataTimeout()) { + setMetadataTimeout(other.getMetadataTimeout()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasRemoveZombies()) { + + return false; + } + if (!hasRemoveUnavailVolume()) { + + return false; + } + if (!hasLostAndFound()) { + + return false; + } + if (!hasDeleteMetadata()) { + + return false; + } + if (!hasMetadataTimeout()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_startRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required bool remove_zombies = 1; + private boolean removeZombies_ ; + /** + * required bool remove_zombies = 1; + * + *
    +       * If true, objects for deleted files are deleted as well.
    +       * 
    + */ + public boolean hasRemoveZombies() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required bool remove_zombies = 1; + * + *
    +       * If true, objects for deleted files are deleted as well.
    +       * 
    + */ + public boolean getRemoveZombies() { + return removeZombies_; + } + /** + * required bool remove_zombies = 1; + * + *
    +       * If true, objects for deleted files are deleted as well.
    +       * 
    + */ + public Builder setRemoveZombies(boolean value) { + bitField0_ |= 0x00000001; + removeZombies_ = value; + onChanged(); + return this; + } + /** + * required bool remove_zombies = 1; + * + *
    +       * If true, objects for deleted files are deleted as well.
    +       * 
    + */ + public Builder clearRemoveZombies() { + bitField0_ = (bitField0_ & ~0x00000001); + removeZombies_ = false; + onChanged(); + return this; + } + + // required bool remove_unavail_volume = 2; + private boolean removeUnavailVolume_ ; + /** + * required bool remove_unavail_volume = 2; + * + *
    +       * If true, files for which the MRC cannot be contacted or
    +       * where no volume DIR entry exists are deleted.
    +       * 
    + */ + public boolean hasRemoveUnavailVolume() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool remove_unavail_volume = 2; + * + *
    +       * If true, files for which the MRC cannot be contacted or
    +       * where no volume DIR entry exists are deleted.
    +       * 
    + */ + public boolean getRemoveUnavailVolume() { + return removeUnavailVolume_; + } + /** + * required bool remove_unavail_volume = 2; + * + *
    +       * If true, files for which the MRC cannot be contacted or
    +       * where no volume DIR entry exists are deleted.
    +       * 
    + */ + public Builder setRemoveUnavailVolume(boolean value) { + bitField0_ |= 0x00000002; + removeUnavailVolume_ = value; + onChanged(); + return this; + } + /** + * required bool remove_unavail_volume = 2; + * + *
    +       * If true, files for which the MRC cannot be contacted or
    +       * where no volume DIR entry exists are deleted.
    +       * 
    + */ + public Builder clearRemoveUnavailVolume() { + bitField0_ = (bitField0_ & ~0x00000002); + removeUnavailVolume_ = false; + onChanged(); + return this; + } + + // required bool lost_and_found = 3; + private boolean lostAndFound_ ; + /** + * required bool lost_and_found = 3; + * + *
    +       * If true, objects are not deleted but moved to lost and found.
    +       * 
    + */ + public boolean hasLostAndFound() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required bool lost_and_found = 3; + * + *
    +       * If true, objects are not deleted but moved to lost and found.
    +       * 
    + */ + public boolean getLostAndFound() { + return lostAndFound_; + } + /** + * required bool lost_and_found = 3; + * + *
    +       * If true, objects are not deleted but moved to lost and found.
    +       * 
    + */ + public Builder setLostAndFound(boolean value) { + bitField0_ |= 0x00000004; + lostAndFound_ = value; + onChanged(); + return this; + } + /** + * required bool lost_and_found = 3; + * + *
    +       * If true, objects are not deleted but moved to lost and found.
    +       * 
    + */ + public Builder clearLostAndFound() { + bitField0_ = (bitField0_ & ~0x00000004); + lostAndFound_ = false; + onChanged(); + return this; + } + + // required bool delete_metadata = 4; + private boolean deleteMetadata_ ; + /** + * required bool delete_metadata = 4; + * + *
    +       * Delete metadata of deleted or abandoned files.
    +       * 
    + */ + public boolean hasDeleteMetadata() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required bool delete_metadata = 4; + * + *
    +       * Delete metadata of deleted or abandoned files.
    +       * 
    + */ + public boolean getDeleteMetadata() { + return deleteMetadata_; + } + /** + * required bool delete_metadata = 4; + * + *
    +       * Delete metadata of deleted or abandoned files.
    +       * 
    + */ + public Builder setDeleteMetadata(boolean value) { + bitField0_ |= 0x00000008; + deleteMetadata_ = value; + onChanged(); + return this; + } + /** + * required bool delete_metadata = 4; + * + *
    +       * Delete metadata of deleted or abandoned files.
    +       * 
    + */ + public Builder clearDeleteMetadata() { + bitField0_ = (bitField0_ & ~0x00000008); + deleteMetadata_ = false; + onChanged(); + return this; + } + + // required fixed32 metadata_timeout = 5; + private int metadataTimeout_ ; + /** + * required fixed32 metadata_timeout = 5; + * + *
    +       * Time in seconds to wait after the last view update before
    +       * deleting metadata.
    +       * 
    + */ + public boolean hasMetadataTimeout() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 metadata_timeout = 5; + * + *
    +       * Time in seconds to wait after the last view update before
    +       * deleting metadata.
    +       * 
    + */ + public int getMetadataTimeout() { + return metadataTimeout_; + } + /** + * required fixed32 metadata_timeout = 5; + * + *
    +       * Time in seconds to wait after the last view update before
    +       * deleting metadata.
    +       * 
    + */ + public Builder setMetadataTimeout(int value) { + bitField0_ |= 0x00000010; + metadataTimeout_ = value; + onChanged(); + return this; + } + /** + * required fixed32 metadata_timeout = 5; + * + *
    +       * Time in seconds to wait after the last view update before
    +       * deleting metadata.
    +       * 
    + */ + public Builder clearMetadataTimeout() { + bitField0_ = (bitField0_ & ~0x00000010); + metadataTimeout_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_cleanup_startRequest) + } + + static { + defaultInstance = new xtreemfs_cleanup_startRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_cleanup_startRequest) + } + + public interface xtreemfs_cleanup_statusResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string status = 1; + /** + * required string status = 1; + */ + boolean hasStatus(); + /** + * required string status = 1; + */ + java.lang.String getStatus(); + /** + * required string status = 1; + */ + com.google.protobuf.ByteString + getStatusBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_cleanup_statusResponse} + */ + public static final class xtreemfs_cleanup_statusResponse extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_cleanup_statusResponseOrBuilder { + // Use xtreemfs_cleanup_statusResponse.newBuilder() to construct. + private xtreemfs_cleanup_statusResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_cleanup_statusResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_cleanup_statusResponse defaultInstance; + public static xtreemfs_cleanup_statusResponse getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_cleanup_statusResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_cleanup_statusResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + status_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_statusResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_statusResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_cleanup_statusResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_cleanup_statusResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string status = 1; + public static final int STATUS_FIELD_NUMBER = 1; + private java.lang.Object status_; + /** + * required string status = 1; + */ + public boolean hasStatus() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string status = 1; + */ + public java.lang.String getStatus() { + java.lang.Object ref = status_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + status_ = s; + } + return s; + } + } + /** + * required string status = 1; + */ + public com.google.protobuf.ByteString + getStatusBytes() { + java.lang.Object ref = status_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + status_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + status_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasStatus()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getStatusBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getStatusBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_cleanup_statusResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_statusResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_statusResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + status_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_statusResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.status_ = status_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse.getDefaultInstance()) return this; + if (other.hasStatus()) { + bitField0_ |= 0x00000001; + status_ = other.status_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasStatus()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string status = 1; + private java.lang.Object status_ = ""; + /** + * required string status = 1; + */ + public boolean hasStatus() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string status = 1; + */ + public java.lang.String getStatus() { + java.lang.Object ref = status_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + status_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string status = 1; + */ + public com.google.protobuf.ByteString + getStatusBytes() { + java.lang.Object ref = status_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + status_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string status = 1; + */ + public Builder setStatus( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + status_ = value; + onChanged(); + return this; + } + /** + * required string status = 1; + */ + public Builder clearStatus() { + bitField0_ = (bitField0_ & ~0x00000001); + status_ = getDefaultInstance().getStatus(); + onChanged(); + return this; + } + /** + * required string status = 1; + */ + public Builder setStatusBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + status_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_cleanup_statusResponse) + } + + static { + defaultInstance = new xtreemfs_cleanup_statusResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_cleanup_statusResponse) + } + + public interface xtreemfs_rwr_fetchRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 object_number = 3; + /** + * required fixed64 object_number = 3; + */ + boolean hasObjectNumber(); + /** + * required fixed64 object_number = 3; + */ + long getObjectNumber(); + + // required fixed64 object_version = 4; + /** + * required fixed64 object_version = 4; + */ + boolean hasObjectVersion(); + /** + * required fixed64 object_version = 4; + */ + long getObjectVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_fetchRequest} + */ + public static final class xtreemfs_rwr_fetchRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_rwr_fetchRequestOrBuilder { + // Use xtreemfs_rwr_fetchRequest.newBuilder() to construct. + private xtreemfs_rwr_fetchRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_rwr_fetchRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_rwr_fetchRequest defaultInstance; + public static xtreemfs_rwr_fetchRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_rwr_fetchRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_rwr_fetchRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + objectNumber_ = input.readFixed64(); + break; + } + case 33: { + bitField0_ |= 0x00000008; + objectVersion_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_fetchRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_fetchRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_rwr_fetchRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_rwr_fetchRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 object_number = 3; + public static final int OBJECT_NUMBER_FIELD_NUMBER = 3; + private long objectNumber_; + /** + * required fixed64 object_number = 3; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + */ + public long getObjectNumber() { + return objectNumber_; + } + + // required fixed64 object_version = 4; + public static final int OBJECT_VERSION_FIELD_NUMBER = 4; + private long objectVersion_; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + objectNumber_ = 0L; + objectVersion_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectNumber()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed64(4, objectVersion_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(4, objectVersion_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_fetchRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_fetchRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_fetchRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + objectNumber_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + objectVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_fetchRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.objectNumber_ = objectNumber_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.objectVersion_ = objectVersion_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasObjectNumber()) { + setObjectNumber(other.getObjectNumber()); + } + if (other.hasObjectVersion()) { + setObjectVersion(other.getObjectVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasObjectNumber()) { + + return false; + } + if (!hasObjectVersion()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_fetchRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 object_number = 3; + private long objectNumber_ ; + /** + * required fixed64 object_number = 3; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + */ + public long getObjectNumber() { + return objectNumber_; + } + /** + * required fixed64 object_number = 3; + */ + public Builder setObjectNumber(long value) { + bitField0_ |= 0x00000004; + objectNumber_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_number = 3; + */ + public Builder clearObjectNumber() { + bitField0_ = (bitField0_ & ~0x00000004); + objectNumber_ = 0L; + onChanged(); + return this; + } + + // required fixed64 object_version = 4; + private long objectVersion_ ; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + /** + * required fixed64 object_version = 4; + */ + public Builder setObjectVersion(long value) { + bitField0_ |= 0x00000008; + objectVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_version = 4; + */ + public Builder clearObjectVersion() { + bitField0_ = (bitField0_ & ~0x00000008); + objectVersion_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_rwr_fetchRequest) + } + + static { + defaultInstance = new xtreemfs_rwr_fetchRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_fetchRequest) + } + + public interface xtreemfs_repair_objectRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 object_number = 3; + /** + * required fixed64 object_number = 3; + */ + boolean hasObjectNumber(); + /** + * required fixed64 object_number = 3; + */ + long getObjectNumber(); + + // required fixed64 object_version = 4; + /** + * required fixed64 object_version = 4; + */ + boolean hasObjectVersion(); + /** + * required fixed64 object_version = 4; + */ + long getObjectVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_repair_objectRequest} + */ + public static final class xtreemfs_repair_objectRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_repair_objectRequestOrBuilder { + // Use xtreemfs_repair_objectRequest.newBuilder() to construct. + private xtreemfs_repair_objectRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_repair_objectRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_repair_objectRequest defaultInstance; + public static xtreemfs_repair_objectRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_repair_objectRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_repair_objectRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + objectNumber_ = input.readFixed64(); + break; + } + case 33: { + bitField0_ |= 0x00000008; + objectVersion_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_repair_objectRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_repair_objectRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_repair_objectRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_repair_objectRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 object_number = 3; + public static final int OBJECT_NUMBER_FIELD_NUMBER = 3; + private long objectNumber_; + /** + * required fixed64 object_number = 3; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + */ + public long getObjectNumber() { + return objectNumber_; + } + + // required fixed64 object_version = 4; + public static final int OBJECT_VERSION_FIELD_NUMBER = 4; + private long objectVersion_; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + objectNumber_ = 0L; + objectVersion_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectNumber()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed64(4, objectVersion_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(4, objectVersion_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_repair_objectRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_repair_objectRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_repair_objectRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + objectNumber_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + objectVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_repair_objectRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.objectNumber_ = objectNumber_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.objectVersion_ = objectVersion_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasObjectNumber()) { + setObjectNumber(other.getObjectNumber()); + } + if (other.hasObjectVersion()) { + setObjectVersion(other.getObjectVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasObjectNumber()) { + + return false; + } + if (!hasObjectVersion()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_repair_objectRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 object_number = 3; + private long objectNumber_ ; + /** + * required fixed64 object_number = 3; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + */ + public long getObjectNumber() { + return objectNumber_; + } + /** + * required fixed64 object_number = 3; + */ + public Builder setObjectNumber(long value) { + bitField0_ |= 0x00000004; + objectNumber_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_number = 3; + */ + public Builder clearObjectNumber() { + bitField0_ = (bitField0_ & ~0x00000004); + objectNumber_ = 0L; + onChanged(); + return this; + } + + // required fixed64 object_version = 4; + private long objectVersion_ ; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + /** + * required fixed64 object_version = 4; + */ + public Builder setObjectVersion(long value) { + bitField0_ |= 0x00000008; + objectVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_version = 4; + */ + public Builder clearObjectVersion() { + bitField0_ = (bitField0_ & ~0x00000008); + objectVersion_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_repair_objectRequest) + } + + static { + defaultInstance = new xtreemfs_repair_objectRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_repair_objectRequest) + } + + public interface xtreemfs_rwr_flease_msgRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string sender_hostname = 1; + /** + * required string sender_hostname = 1; + * + *
    +     * The actual flease message is sent in data.
    +     * 
    + */ + boolean hasSenderHostname(); + /** + * required string sender_hostname = 1; + * + *
    +     * The actual flease message is sent in data.
    +     * 
    + */ + java.lang.String getSenderHostname(); + /** + * required string sender_hostname = 1; + * + *
    +     * The actual flease message is sent in data.
    +     * 
    + */ + com.google.protobuf.ByteString + getSenderHostnameBytes(); + + // required fixed32 sender_port = 2; + /** + * required fixed32 sender_port = 2; + */ + boolean hasSenderPort(); + /** + * required fixed32 sender_port = 2; + */ + int getSenderPort(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_flease_msgRequest} + */ + public static final class xtreemfs_rwr_flease_msgRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_rwr_flease_msgRequestOrBuilder { + // Use xtreemfs_rwr_flease_msgRequest.newBuilder() to construct. + private xtreemfs_rwr_flease_msgRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_rwr_flease_msgRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_rwr_flease_msgRequest defaultInstance; + public static xtreemfs_rwr_flease_msgRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_rwr_flease_msgRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_rwr_flease_msgRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + senderHostname_ = input.readBytes(); + break; + } + case 21: { + bitField0_ |= 0x00000002; + senderPort_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_flease_msgRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_flease_msgRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_rwr_flease_msgRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_rwr_flease_msgRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string sender_hostname = 1; + public static final int SENDER_HOSTNAME_FIELD_NUMBER = 1; + private java.lang.Object senderHostname_; + /** + * required string sender_hostname = 1; + * + *
    +     * The actual flease message is sent in data.
    +     * 
    + */ + public boolean hasSenderHostname() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string sender_hostname = 1; + * + *
    +     * The actual flease message is sent in data.
    +     * 
    + */ + public java.lang.String getSenderHostname() { + java.lang.Object ref = senderHostname_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + senderHostname_ = s; + } + return s; + } + } + /** + * required string sender_hostname = 1; + * + *
    +     * The actual flease message is sent in data.
    +     * 
    + */ + public com.google.protobuf.ByteString + getSenderHostnameBytes() { + java.lang.Object ref = senderHostname_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + senderHostname_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 sender_port = 2; + public static final int SENDER_PORT_FIELD_NUMBER = 2; + private int senderPort_; + /** + * required fixed32 sender_port = 2; + */ + public boolean hasSenderPort() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 sender_port = 2; + */ + public int getSenderPort() { + return senderPort_; + } + + private void initFields() { + senderHostname_ = ""; + senderPort_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasSenderHostname()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasSenderPort()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getSenderHostnameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeFixed32(2, senderPort_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getSenderHostnameBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(2, senderPort_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_flease_msgRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_flease_msgRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_flease_msgRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + senderHostname_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + senderPort_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_flease_msgRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.senderHostname_ = senderHostname_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.senderPort_ = senderPort_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest.getDefaultInstance()) return this; + if (other.hasSenderHostname()) { + bitField0_ |= 0x00000001; + senderHostname_ = other.senderHostname_; + onChanged(); + } + if (other.hasSenderPort()) { + setSenderPort(other.getSenderPort()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasSenderHostname()) { + + return false; + } + if (!hasSenderPort()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_flease_msgRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string sender_hostname = 1; + private java.lang.Object senderHostname_ = ""; + /** + * required string sender_hostname = 1; + * + *
    +       * The actual flease message is sent in data.
    +       * 
    + */ + public boolean hasSenderHostname() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string sender_hostname = 1; + * + *
    +       * The actual flease message is sent in data.
    +       * 
    + */ + public java.lang.String getSenderHostname() { + java.lang.Object ref = senderHostname_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + senderHostname_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string sender_hostname = 1; + * + *
    +       * The actual flease message is sent in data.
    +       * 
    + */ + public com.google.protobuf.ByteString + getSenderHostnameBytes() { + java.lang.Object ref = senderHostname_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + senderHostname_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string sender_hostname = 1; + * + *
    +       * The actual flease message is sent in data.
    +       * 
    + */ + public Builder setSenderHostname( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + senderHostname_ = value; + onChanged(); + return this; + } + /** + * required string sender_hostname = 1; + * + *
    +       * The actual flease message is sent in data.
    +       * 
    + */ + public Builder clearSenderHostname() { + bitField0_ = (bitField0_ & ~0x00000001); + senderHostname_ = getDefaultInstance().getSenderHostname(); + onChanged(); + return this; + } + /** + * required string sender_hostname = 1; + * + *
    +       * The actual flease message is sent in data.
    +       * 
    + */ + public Builder setSenderHostnameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + senderHostname_ = value; + onChanged(); + return this; + } + + // required fixed32 sender_port = 2; + private int senderPort_ ; + /** + * required fixed32 sender_port = 2; + */ + public boolean hasSenderPort() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required fixed32 sender_port = 2; + */ + public int getSenderPort() { + return senderPort_; + } + /** + * required fixed32 sender_port = 2; + */ + public Builder setSenderPort(int value) { + bitField0_ |= 0x00000002; + senderPort_ = value; + onChanged(); + return this; + } + /** + * required fixed32 sender_port = 2; + */ + public Builder clearSenderPort() { + bitField0_ = (bitField0_ & ~0x00000002); + senderPort_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_rwr_flease_msgRequest) + } + + static { + defaultInstance = new xtreemfs_rwr_flease_msgRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_flease_msgRequest) + } + + public interface xtreemfs_rwr_set_primary_epochRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed32 primary_epoch = 3; + /** + * required fixed32 primary_epoch = 3; + */ + boolean hasPrimaryEpoch(); + /** + * required fixed32 primary_epoch = 3; + */ + int getPrimaryEpoch(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_set_primary_epochRequest} + */ + public static final class xtreemfs_rwr_set_primary_epochRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_rwr_set_primary_epochRequestOrBuilder { + // Use xtreemfs_rwr_set_primary_epochRequest.newBuilder() to construct. + private xtreemfs_rwr_set_primary_epochRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_rwr_set_primary_epochRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_rwr_set_primary_epochRequest defaultInstance; + public static xtreemfs_rwr_set_primary_epochRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_rwr_set_primary_epochRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_rwr_set_primary_epochRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 29: { + bitField0_ |= 0x00000004; + primaryEpoch_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_set_primary_epochRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_set_primary_epochRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_rwr_set_primary_epochRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_rwr_set_primary_epochRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 primary_epoch = 3; + public static final int PRIMARY_EPOCH_FIELD_NUMBER = 3; + private int primaryEpoch_; + /** + * required fixed32 primary_epoch = 3; + */ + public boolean hasPrimaryEpoch() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 primary_epoch = 3; + */ + public int getPrimaryEpoch() { + return primaryEpoch_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + primaryEpoch_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPrimaryEpoch()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed32(3, primaryEpoch_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(3, primaryEpoch_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_set_primary_epochRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_set_primary_epochRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_set_primary_epochRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + primaryEpoch_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_set_primary_epochRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.primaryEpoch_ = primaryEpoch_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasPrimaryEpoch()) { + setPrimaryEpoch(other.getPrimaryEpoch()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasPrimaryEpoch()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_set_primary_epochRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed32 primary_epoch = 3; + private int primaryEpoch_ ; + /** + * required fixed32 primary_epoch = 3; + */ + public boolean hasPrimaryEpoch() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 primary_epoch = 3; + */ + public int getPrimaryEpoch() { + return primaryEpoch_; + } + /** + * required fixed32 primary_epoch = 3; + */ + public Builder setPrimaryEpoch(int value) { + bitField0_ |= 0x00000004; + primaryEpoch_ = value; + onChanged(); + return this; + } + /** + * required fixed32 primary_epoch = 3; + */ + public Builder clearPrimaryEpoch() { + bitField0_ = (bitField0_ & ~0x00000004); + primaryEpoch_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_rwr_set_primary_epochRequest) + } + + static { + defaultInstance = new xtreemfs_rwr_set_primary_epochRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_set_primary_epochRequest) + } + + public interface xtreemfs_rwr_statusRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 max_local_obj_version = 3; + /** + * required fixed64 max_local_obj_version = 3; + * + *
    +     * Maximum local object version stored on an OSD.
    +     * 
    + */ + boolean hasMaxLocalObjVersion(); + /** + * required fixed64 max_local_obj_version = 3; + * + *
    +     * Maximum local object version stored on an OSD.
    +     * 
    + */ + long getMaxLocalObjVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_statusRequest} + */ + public static final class xtreemfs_rwr_statusRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_rwr_statusRequestOrBuilder { + // Use xtreemfs_rwr_statusRequest.newBuilder() to construct. + private xtreemfs_rwr_statusRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_rwr_statusRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_rwr_statusRequest defaultInstance; + public static xtreemfs_rwr_statusRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_rwr_statusRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_rwr_statusRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + maxLocalObjVersion_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_statusRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_statusRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_rwr_statusRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_rwr_statusRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 max_local_obj_version = 3; + public static final int MAX_LOCAL_OBJ_VERSION_FIELD_NUMBER = 3; + private long maxLocalObjVersion_; + /** + * required fixed64 max_local_obj_version = 3; + * + *
    +     * Maximum local object version stored on an OSD.
    +     * 
    + */ + public boolean hasMaxLocalObjVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 max_local_obj_version = 3; + * + *
    +     * Maximum local object version stored on an OSD.
    +     * 
    + */ + public long getMaxLocalObjVersion() { + return maxLocalObjVersion_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + maxLocalObjVersion_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMaxLocalObjVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, maxLocalObjVersion_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, maxLocalObjVersion_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_statusRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_statusRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_statusRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + maxLocalObjVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_statusRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.maxLocalObjVersion_ = maxLocalObjVersion_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasMaxLocalObjVersion()) { + setMaxLocalObjVersion(other.getMaxLocalObjVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasMaxLocalObjVersion()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_statusRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 max_local_obj_version = 3; + private long maxLocalObjVersion_ ; + /** + * required fixed64 max_local_obj_version = 3; + * + *
    +       * Maximum local object version stored on an OSD.
    +       * 
    + */ + public boolean hasMaxLocalObjVersion() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 max_local_obj_version = 3; + * + *
    +       * Maximum local object version stored on an OSD.
    +       * 
    + */ + public long getMaxLocalObjVersion() { + return maxLocalObjVersion_; + } + /** + * required fixed64 max_local_obj_version = 3; + * + *
    +       * Maximum local object version stored on an OSD.
    +       * 
    + */ + public Builder setMaxLocalObjVersion(long value) { + bitField0_ |= 0x00000004; + maxLocalObjVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 max_local_obj_version = 3; + * + *
    +       * Maximum local object version stored on an OSD.
    +       * 
    + */ + public Builder clearMaxLocalObjVersion() { + bitField0_ = (bitField0_ & ~0x00000004); + maxLocalObjVersion_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_rwr_statusRequest) + } + + static { + defaultInstance = new xtreemfs_rwr_statusRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_statusRequest) + } + + public interface xtreemfs_rwr_truncateRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 new_file_size = 3; + /** + * required fixed64 new_file_size = 3; + */ + boolean hasNewFileSize(); + /** + * required fixed64 new_file_size = 3; + */ + long getNewFileSize(); + + // required fixed64 object_version = 4; + /** + * required fixed64 object_version = 4; + */ + boolean hasObjectVersion(); + /** + * required fixed64 object_version = 4; + */ + long getObjectVersion(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_truncateRequest} + */ + public static final class xtreemfs_rwr_truncateRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_rwr_truncateRequestOrBuilder { + // Use xtreemfs_rwr_truncateRequest.newBuilder() to construct. + private xtreemfs_rwr_truncateRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_rwr_truncateRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_rwr_truncateRequest defaultInstance; + public static xtreemfs_rwr_truncateRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_rwr_truncateRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_rwr_truncateRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + newFileSize_ = input.readFixed64(); + break; + } + case 33: { + bitField0_ |= 0x00000008; + objectVersion_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_truncateRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_truncateRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_rwr_truncateRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_rwr_truncateRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 new_file_size = 3; + public static final int NEW_FILE_SIZE_FIELD_NUMBER = 3; + private long newFileSize_; + /** + * required fixed64 new_file_size = 3; + */ + public boolean hasNewFileSize() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 new_file_size = 3; + */ + public long getNewFileSize() { + return newFileSize_; + } + + // required fixed64 object_version = 4; + public static final int OBJECT_VERSION_FIELD_NUMBER = 4; + private long objectVersion_; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + newFileSize_ = 0L; + objectVersion_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasNewFileSize()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, newFileSize_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed64(4, objectVersion_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, newFileSize_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(4, objectVersion_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_truncateRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_truncateRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_truncateRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + newFileSize_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + objectVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_truncateRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.newFileSize_ = newFileSize_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.objectVersion_ = objectVersion_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasNewFileSize()) { + setNewFileSize(other.getNewFileSize()); + } + if (other.hasObjectVersion()) { + setObjectVersion(other.getObjectVersion()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasNewFileSize()) { + + return false; + } + if (!hasObjectVersion()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_truncateRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 new_file_size = 3; + private long newFileSize_ ; + /** + * required fixed64 new_file_size = 3; + */ + public boolean hasNewFileSize() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 new_file_size = 3; + */ + public long getNewFileSize() { + return newFileSize_; + } + /** + * required fixed64 new_file_size = 3; + */ + public Builder setNewFileSize(long value) { + bitField0_ |= 0x00000004; + newFileSize_ = value; + onChanged(); + return this; + } + /** + * required fixed64 new_file_size = 3; + */ + public Builder clearNewFileSize() { + bitField0_ = (bitField0_ & ~0x00000004); + newFileSize_ = 0L; + onChanged(); + return this; + } + + // required fixed64 object_version = 4; + private long objectVersion_ ; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + /** + * required fixed64 object_version = 4; + */ + public Builder setObjectVersion(long value) { + bitField0_ |= 0x00000008; + objectVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_version = 4; + */ + public Builder clearObjectVersion() { + bitField0_ = (bitField0_ & ~0x00000008); + objectVersion_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_rwr_truncateRequest) + } + + static { + defaultInstance = new xtreemfs_rwr_truncateRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_truncateRequest) + } + + public interface xtreemfs_rwr_updateRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 new_file_size = 3; + /** + * required fixed64 new_file_size = 3; + */ + boolean hasNewFileSize(); + /** + * required fixed64 new_file_size = 3; + */ + long getNewFileSize(); + + // required fixed64 object_number = 7; + /** + * required fixed64 object_number = 7; + */ + boolean hasObjectNumber(); + /** + * required fixed64 object_number = 7; + */ + long getObjectNumber(); + + // required fixed64 object_version = 4; + /** + * required fixed64 object_version = 4; + */ + boolean hasObjectVersion(); + /** + * required fixed64 object_version = 4; + */ + long getObjectVersion(); + + // required fixed32 offset = 5; + /** + * required fixed32 offset = 5; + */ + boolean hasOffset(); + /** + * required fixed32 offset = 5; + */ + int getOffset(); + + // required .xtreemfs.pbrpc.ObjectData obj = 6; + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + boolean hasObj(); + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData getObj(); + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder getObjOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_updateRequest} + */ + public static final class xtreemfs_rwr_updateRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_rwr_updateRequestOrBuilder { + // Use xtreemfs_rwr_updateRequest.newBuilder() to construct. + private xtreemfs_rwr_updateRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_rwr_updateRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_rwr_updateRequest defaultInstance; + public static xtreemfs_rwr_updateRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_rwr_updateRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_rwr_updateRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + newFileSize_ = input.readFixed64(); + break; + } + case 33: { + bitField0_ |= 0x00000010; + objectVersion_ = input.readFixed64(); + break; + } + case 45: { + bitField0_ |= 0x00000020; + offset_ = input.readFixed32(); + break; + } + case 50: { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder subBuilder = null; + if (((bitField0_ & 0x00000040) == 0x00000040)) { + subBuilder = obj_.toBuilder(); + } + obj_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(obj_); + obj_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000040; + break; + } + case 57: { + bitField0_ |= 0x00000008; + objectNumber_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_updateRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_updateRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_rwr_updateRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_rwr_updateRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 new_file_size = 3; + public static final int NEW_FILE_SIZE_FIELD_NUMBER = 3; + private long newFileSize_; + /** + * required fixed64 new_file_size = 3; + */ + public boolean hasNewFileSize() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 new_file_size = 3; + */ + public long getNewFileSize() { + return newFileSize_; + } + + // required fixed64 object_number = 7; + public static final int OBJECT_NUMBER_FIELD_NUMBER = 7; + private long objectNumber_; + /** + * required fixed64 object_number = 7; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_number = 7; + */ + public long getObjectNumber() { + return objectNumber_; + } + + // required fixed64 object_version = 4; + public static final int OBJECT_VERSION_FIELD_NUMBER = 4; + private long objectVersion_; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + + // required fixed32 offset = 5; + public static final int OFFSET_FIELD_NUMBER = 5; + private int offset_; + /** + * required fixed32 offset = 5; + */ + public boolean hasOffset() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed32 offset = 5; + */ + public int getOffset() { + return offset_; + } + + // required .xtreemfs.pbrpc.ObjectData obj = 6; + public static final int OBJ_FIELD_NUMBER = 6; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData obj_; + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + public boolean hasObj() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData getObj() { + return obj_; + } + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder getObjOrBuilder() { + return obj_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + newFileSize_ = 0L; + objectNumber_ = 0L; + objectVersion_ = 0L; + offset_ = 0; + obj_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasNewFileSize()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectNumber()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOffset()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObj()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getObj().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, newFileSize_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeFixed64(4, objectVersion_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeFixed32(5, offset_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeMessage(6, obj_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed64(7, objectNumber_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, newFileSize_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(4, objectVersion_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(5, offset_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(6, obj_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(7, objectNumber_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_updateRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_updateRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_updateRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + getObjFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + newFileSize_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + objectNumber_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + objectVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000010); + offset_ = 0; + bitField0_ = (bitField0_ & ~0x00000020); + if (objBuilder_ == null) { + obj_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + } else { + objBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000040); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_updateRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.newFileSize_ = newFileSize_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.objectNumber_ = objectNumber_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.objectVersion_ = objectVersion_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.offset_ = offset_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000040; + } + if (objBuilder_ == null) { + result.obj_ = obj_; + } else { + result.obj_ = objBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasNewFileSize()) { + setNewFileSize(other.getNewFileSize()); + } + if (other.hasObjectNumber()) { + setObjectNumber(other.getObjectNumber()); + } + if (other.hasObjectVersion()) { + setObjectVersion(other.getObjectVersion()); + } + if (other.hasOffset()) { + setOffset(other.getOffset()); + } + if (other.hasObj()) { + mergeObj(other.getObj()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasNewFileSize()) { + + return false; + } + if (!hasObjectNumber()) { + + return false; + } + if (!hasObjectVersion()) { + + return false; + } + if (!hasOffset()) { + + return false; + } + if (!hasObj()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + if (!getObj().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_updateRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 new_file_size = 3; + private long newFileSize_ ; + /** + * required fixed64 new_file_size = 3; + */ + public boolean hasNewFileSize() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 new_file_size = 3; + */ + public long getNewFileSize() { + return newFileSize_; + } + /** + * required fixed64 new_file_size = 3; + */ + public Builder setNewFileSize(long value) { + bitField0_ |= 0x00000004; + newFileSize_ = value; + onChanged(); + return this; + } + /** + * required fixed64 new_file_size = 3; + */ + public Builder clearNewFileSize() { + bitField0_ = (bitField0_ & ~0x00000004); + newFileSize_ = 0L; + onChanged(); + return this; + } + + // required fixed64 object_number = 7; + private long objectNumber_ ; + /** + * required fixed64 object_number = 7; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_number = 7; + */ + public long getObjectNumber() { + return objectNumber_; + } + /** + * required fixed64 object_number = 7; + */ + public Builder setObjectNumber(long value) { + bitField0_ |= 0x00000008; + objectNumber_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_number = 7; + */ + public Builder clearObjectNumber() { + bitField0_ = (bitField0_ & ~0x00000008); + objectNumber_ = 0L; + onChanged(); + return this; + } + + // required fixed64 object_version = 4; + private long objectVersion_ ; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + /** + * required fixed64 object_version = 4; + */ + public Builder setObjectVersion(long value) { + bitField0_ |= 0x00000010; + objectVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_version = 4; + */ + public Builder clearObjectVersion() { + bitField0_ = (bitField0_ & ~0x00000010); + objectVersion_ = 0L; + onChanged(); + return this; + } + + // required fixed32 offset = 5; + private int offset_ ; + /** + * required fixed32 offset = 5; + */ + public boolean hasOffset() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed32 offset = 5; + */ + public int getOffset() { + return offset_; + } + /** + * required fixed32 offset = 5; + */ + public Builder setOffset(int value) { + bitField0_ |= 0x00000020; + offset_ = value; + onChanged(); + return this; + } + /** + * required fixed32 offset = 5; + */ + public Builder clearOffset() { + bitField0_ = (bitField0_ & ~0x00000020); + offset_ = 0; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.ObjectData obj = 6; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData obj_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder> objBuilder_; + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + public boolean hasObj() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData getObj() { + if (objBuilder_ == null) { + return obj_; + } else { + return objBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + public Builder setObj(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData value) { + if (objBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + obj_ = value; + onChanged(); + } else { + objBuilder_.setMessage(value); + } + bitField0_ |= 0x00000040; + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + public Builder setObj( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder builderForValue) { + if (objBuilder_ == null) { + obj_ = builderForValue.build(); + onChanged(); + } else { + objBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000040; + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + public Builder mergeObj(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData value) { + if (objBuilder_ == null) { + if (((bitField0_ & 0x00000040) == 0x00000040) && + obj_ != org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance()) { + obj_ = + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.newBuilder(obj_).mergeFrom(value).buildPartial(); + } else { + obj_ = value; + } + onChanged(); + } else { + objBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000040; + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + public Builder clearObj() { + if (objBuilder_ == null) { + obj_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.getDefaultInstance(); + onChanged(); + } else { + objBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000040); + return this; + } + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder getObjBuilder() { + bitField0_ |= 0x00000040; + onChanged(); + return getObjFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder getObjOrBuilder() { + if (objBuilder_ != null) { + return objBuilder_.getMessageOrBuilder(); + } else { + return obj_; + } + } + /** + * required .xtreemfs.pbrpc.ObjectData obj = 6; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder> + getObjFieldBuilder() { + if (objBuilder_ == null) { + objBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectDataOrBuilder>( + obj_, + getParentForChildren(), + isClean()); + obj_ = null; + } + return objBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_rwr_updateRequest) + } + + static { + defaultInstance = new xtreemfs_rwr_updateRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_updateRequest) + } + + public interface xtreemfs_internal_get_gmaxRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_get_gmaxRequest} + */ + public static final class xtreemfs_internal_get_gmaxRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_internal_get_gmaxRequestOrBuilder { + // Use xtreemfs_internal_get_gmaxRequest.newBuilder() to construct. + private xtreemfs_internal_get_gmaxRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_internal_get_gmaxRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_internal_get_gmaxRequest defaultInstance; + public static xtreemfs_internal_get_gmaxRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_internal_get_gmaxRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_internal_get_gmaxRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_gmaxRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_gmaxRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_internal_get_gmaxRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_internal_get_gmaxRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_get_gmaxRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_gmaxRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_gmaxRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_gmaxRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_gmaxRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_internal_get_gmaxRequest) + } + + static { + defaultInstance = new xtreemfs_internal_get_gmaxRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_get_gmaxRequest) + } + + public interface xtreemfs_internal_get_file_sizeRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_get_file_sizeRequest} + */ + public static final class xtreemfs_internal_get_file_sizeRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_internal_get_file_sizeRequestOrBuilder { + // Use xtreemfs_internal_get_file_sizeRequest.newBuilder() to construct. + private xtreemfs_internal_get_file_sizeRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_internal_get_file_sizeRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_internal_get_file_sizeRequest defaultInstance; + public static xtreemfs_internal_get_file_sizeRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_internal_get_file_sizeRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_internal_get_file_sizeRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_internal_get_file_sizeRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_internal_get_file_sizeRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_get_file_sizeRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_internal_get_file_sizeRequest) + } + + static { + defaultInstance = new xtreemfs_internal_get_file_sizeRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_get_file_sizeRequest) + } + + public interface xtreemfs_internal_get_file_sizeResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required fixed64 file_size = 1; + /** + * required fixed64 file_size = 1; + * + *
    +     * File size in bytes (as seen by local OSD).
    +     * 
    + */ + boolean hasFileSize(); + /** + * required fixed64 file_size = 1; + * + *
    +     * File size in bytes (as seen by local OSD).
    +     * 
    + */ + long getFileSize(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_get_file_sizeResponse} + */ + public static final class xtreemfs_internal_get_file_sizeResponse extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_internal_get_file_sizeResponseOrBuilder { + // Use xtreemfs_internal_get_file_sizeResponse.newBuilder() to construct. + private xtreemfs_internal_get_file_sizeResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_internal_get_file_sizeResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_internal_get_file_sizeResponse defaultInstance; + public static xtreemfs_internal_get_file_sizeResponse getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_internal_get_file_sizeResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_internal_get_file_sizeResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 9: { + bitField0_ |= 0x00000001; + fileSize_ = input.readFixed64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_internal_get_file_sizeResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_internal_get_file_sizeResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required fixed64 file_size = 1; + public static final int FILE_SIZE_FIELD_NUMBER = 1; + private long fileSize_; + /** + * required fixed64 file_size = 1; + * + *
    +     * File size in bytes (as seen by local OSD).
    +     * 
    + */ + public boolean hasFileSize() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 file_size = 1; + * + *
    +     * File size in bytes (as seen by local OSD).
    +     * 
    + */ + public long getFileSize() { + return fileSize_; + } + + private void initFields() { + fileSize_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileSize()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeFixed64(1, fileSize_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(1, fileSize_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_get_file_sizeResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileSize_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.fileSize_ = fileSize_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse.getDefaultInstance()) return this; + if (other.hasFileSize()) { + setFileSize(other.getFileSize()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileSize()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_file_sizeResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required fixed64 file_size = 1; + private long fileSize_ ; + /** + * required fixed64 file_size = 1; + * + *
    +       * File size in bytes (as seen by local OSD).
    +       * 
    + */ + public boolean hasFileSize() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required fixed64 file_size = 1; + * + *
    +       * File size in bytes (as seen by local OSD).
    +       * 
    + */ + public long getFileSize() { + return fileSize_; + } + /** + * required fixed64 file_size = 1; + * + *
    +       * File size in bytes (as seen by local OSD).
    +       * 
    + */ + public Builder setFileSize(long value) { + bitField0_ |= 0x00000001; + fileSize_ = value; + onChanged(); + return this; + } + /** + * required fixed64 file_size = 1; + * + *
    +       * File size in bytes (as seen by local OSD).
    +       * 
    + */ + public Builder clearFileSize() { + bitField0_ = (bitField0_ & ~0x00000001); + fileSize_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_internal_get_file_sizeResponse) + } + + static { + defaultInstance = new xtreemfs_internal_get_file_sizeResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_get_file_sizeResponse) + } + + public interface xtreemfs_internal_read_localRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed64 object_number = 3; + /** + * required fixed64 object_number = 3; + */ + boolean hasObjectNumber(); + /** + * required fixed64 object_number = 3; + */ + long getObjectNumber(); + + // required fixed64 object_version = 4; + /** + * required fixed64 object_version = 4; + */ + boolean hasObjectVersion(); + /** + * required fixed64 object_version = 4; + */ + long getObjectVersion(); + + // required fixed32 offset = 5; + /** + * required fixed32 offset = 5; + */ + boolean hasOffset(); + /** + * required fixed32 offset = 5; + */ + int getOffset(); + + // required fixed32 length = 6; + /** + * required fixed32 length = 6; + */ + boolean hasLength(); + /** + * required fixed32 length = 6; + */ + int getLength(); + + // required bool attach_object_list = 7; + /** + * required bool attach_object_list = 7; + */ + boolean hasAttachObjectList(); + /** + * required bool attach_object_list = 7; + */ + boolean getAttachObjectList(); + + // repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + java.util.List + getRequiredObjectsList(); + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList getRequiredObjects(int index); + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + int getRequiredObjectsCount(); + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + java.util.List + getRequiredObjectsOrBuilderList(); + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder getRequiredObjectsOrBuilder( + int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_read_localRequest} + */ + public static final class xtreemfs_internal_read_localRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_internal_read_localRequestOrBuilder { + // Use xtreemfs_internal_read_localRequest.newBuilder() to construct. + private xtreemfs_internal_read_localRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_internal_read_localRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_internal_read_localRequest defaultInstance; + public static xtreemfs_internal_read_localRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_internal_read_localRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_internal_read_localRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 25: { + bitField0_ |= 0x00000004; + objectNumber_ = input.readFixed64(); + break; + } + case 33: { + bitField0_ |= 0x00000008; + objectVersion_ = input.readFixed64(); + break; + } + case 45: { + bitField0_ |= 0x00000010; + offset_ = input.readFixed32(); + break; + } + case 53: { + bitField0_ |= 0x00000020; + length_ = input.readFixed32(); + break; + } + case 56: { + bitField0_ |= 0x00000040; + attachObjectList_ = input.readBool(); + break; + } + case 66: { + if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) { + requiredObjects_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000080; + } + requiredObjects_.add(input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) { + requiredObjects_ = java.util.Collections.unmodifiableList(requiredObjects_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_read_localRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_read_localRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_internal_read_localRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_internal_read_localRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed64 object_number = 3; + public static final int OBJECT_NUMBER_FIELD_NUMBER = 3; + private long objectNumber_; + /** + * required fixed64 object_number = 3; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + */ + public long getObjectNumber() { + return objectNumber_; + } + + // required fixed64 object_version = 4; + public static final int OBJECT_VERSION_FIELD_NUMBER = 4; + private long objectVersion_; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + + // required fixed32 offset = 5; + public static final int OFFSET_FIELD_NUMBER = 5; + private int offset_; + /** + * required fixed32 offset = 5; + */ + public boolean hasOffset() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 offset = 5; + */ + public int getOffset() { + return offset_; + } + + // required fixed32 length = 6; + public static final int LENGTH_FIELD_NUMBER = 6; + private int length_; + /** + * required fixed32 length = 6; + */ + public boolean hasLength() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed32 length = 6; + */ + public int getLength() { + return length_; + } + + // required bool attach_object_list = 7; + public static final int ATTACH_OBJECT_LIST_FIELD_NUMBER = 7; + private boolean attachObjectList_; + /** + * required bool attach_object_list = 7; + */ + public boolean hasAttachObjectList() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required bool attach_object_list = 7; + */ + public boolean getAttachObjectList() { + return attachObjectList_; + } + + // repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + public static final int REQUIRED_OBJECTS_FIELD_NUMBER = 8; + private java.util.List requiredObjects_; + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public java.util.List getRequiredObjectsList() { + return requiredObjects_; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public java.util.List + getRequiredObjectsOrBuilderList() { + return requiredObjects_; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public int getRequiredObjectsCount() { + return requiredObjects_.size(); + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList getRequiredObjects(int index) { + return requiredObjects_.get(index); + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder getRequiredObjectsOrBuilder( + int index) { + return requiredObjects_.get(index); + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + objectNumber_ = 0L; + objectVersion_ = 0L; + offset_ = 0; + length_ = 0; + attachObjectList_ = false; + requiredObjects_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectNumber()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasObjectVersion()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasOffset()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLength()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasAttachObjectList()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getRequiredObjectsCount(); i++) { + if (!getRequiredObjects(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed64(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeFixed64(4, objectVersion_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeFixed32(5, offset_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeFixed32(6, length_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeBool(7, attachObjectList_); + } + for (int i = 0; i < requiredObjects_.size(); i++) { + output.writeMessage(8, requiredObjects_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(3, objectNumber_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed64Size(4, objectVersion_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(5, offset_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(6, length_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(7, attachObjectList_); + } + for (int i = 0; i < requiredObjects_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(8, requiredObjects_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_read_localRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_read_localRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_read_localRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + getRequiredObjectsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + objectNumber_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + objectVersion_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + offset_ = 0; + bitField0_ = (bitField0_ & ~0x00000010); + length_ = 0; + bitField0_ = (bitField0_ & ~0x00000020); + attachObjectList_ = false; + bitField0_ = (bitField0_ & ~0x00000040); + if (requiredObjectsBuilder_ == null) { + requiredObjects_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + } else { + requiredObjectsBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_read_localRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.objectNumber_ = objectNumber_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.objectVersion_ = objectVersion_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.offset_ = offset_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.length_ = length_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000040; + } + result.attachObjectList_ = attachObjectList_; + if (requiredObjectsBuilder_ == null) { + if (((bitField0_ & 0x00000080) == 0x00000080)) { + requiredObjects_ = java.util.Collections.unmodifiableList(requiredObjects_); + bitField0_ = (bitField0_ & ~0x00000080); + } + result.requiredObjects_ = requiredObjects_; + } else { + result.requiredObjects_ = requiredObjectsBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasObjectNumber()) { + setObjectNumber(other.getObjectNumber()); + } + if (other.hasObjectVersion()) { + setObjectVersion(other.getObjectVersion()); + } + if (other.hasOffset()) { + setOffset(other.getOffset()); + } + if (other.hasLength()) { + setLength(other.getLength()); + } + if (other.hasAttachObjectList()) { + setAttachObjectList(other.getAttachObjectList()); + } + if (requiredObjectsBuilder_ == null) { + if (!other.requiredObjects_.isEmpty()) { + if (requiredObjects_.isEmpty()) { + requiredObjects_ = other.requiredObjects_; + bitField0_ = (bitField0_ & ~0x00000080); + } else { + ensureRequiredObjectsIsMutable(); + requiredObjects_.addAll(other.requiredObjects_); + } + onChanged(); + } + } else { + if (!other.requiredObjects_.isEmpty()) { + if (requiredObjectsBuilder_.isEmpty()) { + requiredObjectsBuilder_.dispose(); + requiredObjectsBuilder_ = null; + requiredObjects_ = other.requiredObjects_; + bitField0_ = (bitField0_ & ~0x00000080); + requiredObjectsBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getRequiredObjectsFieldBuilder() : null; + } else { + requiredObjectsBuilder_.addAllMessages(other.requiredObjects_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasObjectNumber()) { + + return false; + } + if (!hasObjectVersion()) { + + return false; + } + if (!hasOffset()) { + + return false; + } + if (!hasLength()) { + + return false; + } + if (!hasAttachObjectList()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + for (int i = 0; i < getRequiredObjectsCount(); i++) { + if (!getRequiredObjects(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_read_localRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed64 object_number = 3; + private long objectNumber_ ; + /** + * required fixed64 object_number = 3; + */ + public boolean hasObjectNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed64 object_number = 3; + */ + public long getObjectNumber() { + return objectNumber_; + } + /** + * required fixed64 object_number = 3; + */ + public Builder setObjectNumber(long value) { + bitField0_ |= 0x00000004; + objectNumber_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_number = 3; + */ + public Builder clearObjectNumber() { + bitField0_ = (bitField0_ & ~0x00000004); + objectNumber_ = 0L; + onChanged(); + return this; + } + + // required fixed64 object_version = 4; + private long objectVersion_ ; + /** + * required fixed64 object_version = 4; + */ + public boolean hasObjectVersion() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * required fixed64 object_version = 4; + */ + public long getObjectVersion() { + return objectVersion_; + } + /** + * required fixed64 object_version = 4; + */ + public Builder setObjectVersion(long value) { + bitField0_ |= 0x00000008; + objectVersion_ = value; + onChanged(); + return this; + } + /** + * required fixed64 object_version = 4; + */ + public Builder clearObjectVersion() { + bitField0_ = (bitField0_ & ~0x00000008); + objectVersion_ = 0L; + onChanged(); + return this; + } + + // required fixed32 offset = 5; + private int offset_ ; + /** + * required fixed32 offset = 5; + */ + public boolean hasOffset() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * required fixed32 offset = 5; + */ + public int getOffset() { + return offset_; + } + /** + * required fixed32 offset = 5; + */ + public Builder setOffset(int value) { + bitField0_ |= 0x00000010; + offset_ = value; + onChanged(); + return this; + } + /** + * required fixed32 offset = 5; + */ + public Builder clearOffset() { + bitField0_ = (bitField0_ & ~0x00000010); + offset_ = 0; + onChanged(); + return this; + } + + // required fixed32 length = 6; + private int length_ ; + /** + * required fixed32 length = 6; + */ + public boolean hasLength() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * required fixed32 length = 6; + */ + public int getLength() { + return length_; + } + /** + * required fixed32 length = 6; + */ + public Builder setLength(int value) { + bitField0_ |= 0x00000020; + length_ = value; + onChanged(); + return this; + } + /** + * required fixed32 length = 6; + */ + public Builder clearLength() { + bitField0_ = (bitField0_ & ~0x00000020); + length_ = 0; + onChanged(); + return this; + } + + // required bool attach_object_list = 7; + private boolean attachObjectList_ ; + /** + * required bool attach_object_list = 7; + */ + public boolean hasAttachObjectList() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * required bool attach_object_list = 7; + */ + public boolean getAttachObjectList() { + return attachObjectList_; + } + /** + * required bool attach_object_list = 7; + */ + public Builder setAttachObjectList(boolean value) { + bitField0_ |= 0x00000040; + attachObjectList_ = value; + onChanged(); + return this; + } + /** + * required bool attach_object_list = 7; + */ + public Builder clearAttachObjectList() { + bitField0_ = (bitField0_ & ~0x00000040); + attachObjectList_ = false; + onChanged(); + return this; + } + + // repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + private java.util.List requiredObjects_ = + java.util.Collections.emptyList(); + private void ensureRequiredObjectsIsMutable() { + if (!((bitField0_ & 0x00000080) == 0x00000080)) { + requiredObjects_ = new java.util.ArrayList(requiredObjects_); + bitField0_ |= 0x00000080; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder> requiredObjectsBuilder_; + + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public java.util.List getRequiredObjectsList() { + if (requiredObjectsBuilder_ == null) { + return java.util.Collections.unmodifiableList(requiredObjects_); + } else { + return requiredObjectsBuilder_.getMessageList(); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public int getRequiredObjectsCount() { + if (requiredObjectsBuilder_ == null) { + return requiredObjects_.size(); + } else { + return requiredObjectsBuilder_.getCount(); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList getRequiredObjects(int index) { + if (requiredObjectsBuilder_ == null) { + return requiredObjects_.get(index); + } else { + return requiredObjectsBuilder_.getMessage(index); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public Builder setRequiredObjects( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList value) { + if (requiredObjectsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureRequiredObjectsIsMutable(); + requiredObjects_.set(index, value); + onChanged(); + } else { + requiredObjectsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public Builder setRequiredObjects( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder builderForValue) { + if (requiredObjectsBuilder_ == null) { + ensureRequiredObjectsIsMutable(); + requiredObjects_.set(index, builderForValue.build()); + onChanged(); + } else { + requiredObjectsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public Builder addRequiredObjects(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList value) { + if (requiredObjectsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureRequiredObjectsIsMutable(); + requiredObjects_.add(value); + onChanged(); + } else { + requiredObjectsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public Builder addRequiredObjects( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList value) { + if (requiredObjectsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureRequiredObjectsIsMutable(); + requiredObjects_.add(index, value); + onChanged(); + } else { + requiredObjectsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public Builder addRequiredObjects( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder builderForValue) { + if (requiredObjectsBuilder_ == null) { + ensureRequiredObjectsIsMutable(); + requiredObjects_.add(builderForValue.build()); + onChanged(); + } else { + requiredObjectsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public Builder addRequiredObjects( + int index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder builderForValue) { + if (requiredObjectsBuilder_ == null) { + ensureRequiredObjectsIsMutable(); + requiredObjects_.add(index, builderForValue.build()); + onChanged(); + } else { + requiredObjectsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public Builder addAllRequiredObjects( + java.lang.Iterable values) { + if (requiredObjectsBuilder_ == null) { + ensureRequiredObjectsIsMutable(); + super.addAll(values, requiredObjects_); + onChanged(); + } else { + requiredObjectsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public Builder clearRequiredObjects() { + if (requiredObjectsBuilder_ == null) { + requiredObjects_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + onChanged(); + } else { + requiredObjectsBuilder_.clear(); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public Builder removeRequiredObjects(int index) { + if (requiredObjectsBuilder_ == null) { + ensureRequiredObjectsIsMutable(); + requiredObjects_.remove(index); + onChanged(); + } else { + requiredObjectsBuilder_.remove(index); + } + return this; + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder getRequiredObjectsBuilder( + int index) { + return getRequiredObjectsFieldBuilder().getBuilder(index); + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder getRequiredObjectsOrBuilder( + int index) { + if (requiredObjectsBuilder_ == null) { + return requiredObjects_.get(index); } else { + return requiredObjectsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public java.util.List + getRequiredObjectsOrBuilderList() { + if (requiredObjectsBuilder_ != null) { + return requiredObjectsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(requiredObjects_); + } + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder addRequiredObjectsBuilder() { + return getRequiredObjectsFieldBuilder().addBuilder( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder addRequiredObjectsBuilder( + int index) { + return getRequiredObjectsFieldBuilder().addBuilder( + index, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.getDefaultInstance()); + } + /** + * repeated .xtreemfs.pbrpc.ObjectList required_objects = 8; + */ + public java.util.List + getRequiredObjectsBuilderList() { + return getRequiredObjectsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder> + getRequiredObjectsFieldBuilder() { + if (requiredObjectsBuilder_ == null) { + requiredObjectsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectListOrBuilder>( + requiredObjects_, + ((bitField0_ & 0x00000080) == 0x00000080), + getParentForChildren(), + isClean()); + requiredObjects_ = null; + } + return requiredObjectsBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_internal_read_localRequest) + } + + static { + defaultInstance = new xtreemfs_internal_read_localRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_read_localRequest) + } + + public interface xtreemfs_internal_get_object_setRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_get_object_setRequest} + */ + public static final class xtreemfs_internal_get_object_setRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_internal_get_object_setRequestOrBuilder { + // Use xtreemfs_internal_get_object_setRequest.newBuilder() to construct. + private xtreemfs_internal_get_object_setRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_internal_get_object_setRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_internal_get_object_setRequest defaultInstance; + public static xtreemfs_internal_get_object_setRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_internal_get_object_setRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_internal_get_object_setRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_object_setRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_object_setRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_internal_get_object_setRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_internal_get_object_setRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_get_object_setRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_object_setRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_object_setRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_object_setRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_object_setRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_internal_get_object_setRequest) + } + + static { + defaultInstance = new xtreemfs_internal_get_object_setRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_get_object_setRequest) + } + + public interface xtreemfs_internal_get_fileid_listResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated string file_ids = 1; + /** + * repeated string file_ids = 1; + */ + java.util.List + getFileIdsList(); + /** + * repeated string file_ids = 1; + */ + int getFileIdsCount(); + /** + * repeated string file_ids = 1; + */ + java.lang.String getFileIds(int index); + /** + * repeated string file_ids = 1; + */ + com.google.protobuf.ByteString + getFileIdsBytes(int index); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_get_fileid_listResponse} + */ + public static final class xtreemfs_internal_get_fileid_listResponse extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_internal_get_fileid_listResponseOrBuilder { + // Use xtreemfs_internal_get_fileid_listResponse.newBuilder() to construct. + private xtreemfs_internal_get_fileid_listResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_internal_get_fileid_listResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_internal_get_fileid_listResponse defaultInstance; + public static xtreemfs_internal_get_fileid_listResponse getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_internal_get_fileid_listResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_internal_get_fileid_listResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + fileIds_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000001; + } + fileIds_.add(input.readBytes()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + fileIds_ = new com.google.protobuf.UnmodifiableLazyStringList(fileIds_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_fileid_listResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_fileid_listResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_internal_get_fileid_listResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_internal_get_fileid_listResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + // repeated string file_ids = 1; + public static final int FILE_IDS_FIELD_NUMBER = 1; + private com.google.protobuf.LazyStringList fileIds_; + /** + * repeated string file_ids = 1; + */ + public java.util.List + getFileIdsList() { + return fileIds_; + } + /** + * repeated string file_ids = 1; + */ + public int getFileIdsCount() { + return fileIds_.size(); + } + /** + * repeated string file_ids = 1; + */ + public java.lang.String getFileIds(int index) { + return fileIds_.get(index); + } + /** + * repeated string file_ids = 1; + */ + public com.google.protobuf.ByteString + getFileIdsBytes(int index) { + return fileIds_.getByteString(index); + } + + private void initFields() { + fileIds_ = com.google.protobuf.LazyStringArrayList.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < fileIds_.size(); i++) { + output.writeBytes(1, fileIds_.getByteString(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < fileIds_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(fileIds_.getByteString(i)); + } + size += dataSize; + size += 1 * getFileIdsList().size(); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_internal_get_fileid_listResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_fileid_listResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_fileid_listResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + fileIds_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_fileid_listResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse(this); + int from_bitField0_ = bitField0_; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + fileIds_ = new com.google.protobuf.UnmodifiableLazyStringList( + fileIds_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.fileIds_ = fileIds_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse.getDefaultInstance()) return this; + if (!other.fileIds_.isEmpty()) { + if (fileIds_.isEmpty()) { + fileIds_ = other.fileIds_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureFileIdsIsMutable(); + fileIds_.addAll(other.fileIds_); + } + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_internal_get_fileid_listResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated string file_ids = 1; + private com.google.protobuf.LazyStringList fileIds_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureFileIdsIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + fileIds_ = new com.google.protobuf.LazyStringArrayList(fileIds_); + bitField0_ |= 0x00000001; + } + } + /** + * repeated string file_ids = 1; + */ + public java.util.List + getFileIdsList() { + return java.util.Collections.unmodifiableList(fileIds_); + } + /** + * repeated string file_ids = 1; + */ + public int getFileIdsCount() { + return fileIds_.size(); + } + /** + * repeated string file_ids = 1; + */ + public java.lang.String getFileIds(int index) { + return fileIds_.get(index); + } + /** + * repeated string file_ids = 1; + */ + public com.google.protobuf.ByteString + getFileIdsBytes(int index) { + return fileIds_.getByteString(index); + } + /** + * repeated string file_ids = 1; + */ + public Builder setFileIds( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileIdsIsMutable(); + fileIds_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string file_ids = 1; + */ + public Builder addFileIds( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileIdsIsMutable(); + fileIds_.add(value); + onChanged(); + return this; + } + /** + * repeated string file_ids = 1; + */ + public Builder addAllFileIds( + java.lang.Iterable values) { + ensureFileIdsIsMutable(); + super.addAll(values, fileIds_); + onChanged(); + return this; + } + /** + * repeated string file_ids = 1; + */ + public Builder clearFileIds() { + fileIds_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * repeated string file_ids = 1; + */ + public Builder addFileIdsBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureFileIdsIsMutable(); + fileIds_.add(value); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_internal_get_fileid_listResponse) + } + + static { + defaultInstance = new xtreemfs_internal_get_fileid_listResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_internal_get_fileid_listResponse) + } + + public interface lockRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required .xtreemfs.pbrpc.Lock lock_request = 2; + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + boolean hasLockRequest(); + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock getLockRequest(); + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.LockOrBuilder getLockRequestOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.lockRequest} + */ + public static final class lockRequest extends + com.google.protobuf.GeneratedMessage + implements lockRequestOrBuilder { + // Use lockRequest.newBuilder() to construct. + private lockRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private lockRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final lockRequest defaultInstance; + public static lockRequest getDefaultInstance() { + return defaultInstance; + } + + public lockRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private lockRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = lockRequest_.toBuilder(); + } + lockRequest_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(lockRequest_); + lockRequest_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_lockRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_lockRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public lockRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new lockRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required .xtreemfs.pbrpc.Lock lock_request = 2; + public static final int LOCK_REQUEST_FIELD_NUMBER = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock lockRequest_; + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + public boolean hasLockRequest() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock getLockRequest() { + return lockRequest_; + } + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.LockOrBuilder getLockRequestOrBuilder() { + return lockRequest_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + lockRequest_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasLockRequest()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getLockRequest().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, lockRequest_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, lockRequest_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.lockRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_lockRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_lockRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + getLockRequestFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (lockRequestBuilder_ == null) { + lockRequest_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.getDefaultInstance(); + } else { + lockRequestBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_lockRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + if (lockRequestBuilder_ == null) { + result.lockRequest_ = lockRequest_; + } else { + result.lockRequest_ = lockRequestBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasLockRequest()) { + mergeLockRequest(other.getLockRequest()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasLockRequest()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + if (!getLockRequest().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.lockRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required .xtreemfs.pbrpc.Lock lock_request = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock lockRequest_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock, org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.LockOrBuilder> lockRequestBuilder_; + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + public boolean hasLockRequest() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock getLockRequest() { + if (lockRequestBuilder_ == null) { + return lockRequest_; + } else { + return lockRequestBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + public Builder setLockRequest(org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock value) { + if (lockRequestBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + lockRequest_ = value; + onChanged(); + } else { + lockRequestBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + public Builder setLockRequest( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.Builder builderForValue) { + if (lockRequestBuilder_ == null) { + lockRequest_ = builderForValue.build(); + onChanged(); + } else { + lockRequestBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + public Builder mergeLockRequest(org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock value) { + if (lockRequestBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + lockRequest_ != org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.getDefaultInstance()) { + lockRequest_ = + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.newBuilder(lockRequest_).mergeFrom(value).buildPartial(); + } else { + lockRequest_ = value; + } + onChanged(); + } else { + lockRequestBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + public Builder clearLockRequest() { + if (lockRequestBuilder_ == null) { + lockRequest_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.getDefaultInstance(); + onChanged(); + } else { + lockRequestBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.Builder getLockRequestBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getLockRequestFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.LockOrBuilder getLockRequestOrBuilder() { + if (lockRequestBuilder_ != null) { + return lockRequestBuilder_.getMessageOrBuilder(); + } else { + return lockRequest_; + } + } + /** + * required .xtreemfs.pbrpc.Lock lock_request = 2; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock, org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.LockOrBuilder> + getLockRequestFieldBuilder() { + if (lockRequestBuilder_ == null) { + lockRequestBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock, org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.LockOrBuilder>( + lockRequest_, + getParentForChildren(), + isClean()); + lockRequest_ = null; + } + return lockRequestBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.lockRequest) + } + + static { + defaultInstance = new lockRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.lockRequest) + } + + public interface xtreemfs_pingMesssageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + boolean hasCoordinates(); + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates getCoordinates(); + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder getCoordinatesOrBuilder(); + + // required bool request_response = 2; + /** + * required bool request_response = 2; + */ + boolean hasRequestResponse(); + /** + * required bool request_response = 2; + */ + boolean getRequestResponse(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_pingMesssage} + */ + public static final class xtreemfs_pingMesssage extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_pingMesssageOrBuilder { + // Use xtreemfs_pingMesssage.newBuilder() to construct. + private xtreemfs_pingMesssage(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_pingMesssage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_pingMesssage defaultInstance; + public static xtreemfs_pingMesssage getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_pingMesssage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_pingMesssage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = coordinates_.toBuilder(); + } + coordinates_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(coordinates_); + coordinates_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 16: { + bitField0_ |= 0x00000002; + requestResponse_ = input.readBool(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_pingMesssage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_pingMesssage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_pingMesssage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_pingMesssage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + public static final int COORDINATES_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates coordinates_; + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + public boolean hasCoordinates() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates getCoordinates() { + return coordinates_; + } + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder getCoordinatesOrBuilder() { + return coordinates_; + } + + // required bool request_response = 2; + public static final int REQUEST_RESPONSE_FIELD_NUMBER = 2; + private boolean requestResponse_; + /** + * required bool request_response = 2; + */ + public boolean hasRequestResponse() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool request_response = 2; + */ + public boolean getRequestResponse() { + return requestResponse_; + } + + private void initFields() { + coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + requestResponse_ = false; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasCoordinates()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasRequestResponse()) { + memoizedIsInitialized = 0; + return false; + } + if (!getCoordinates().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, coordinates_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBool(2, requestResponse_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, coordinates_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(2, requestResponse_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_pingMesssage} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_pingMesssage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_pingMesssage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getCoordinatesFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (coordinatesBuilder_ == null) { + coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + } else { + coordinatesBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + requestResponse_ = false; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_pingMesssage_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (coordinatesBuilder_ == null) { + result.coordinates_ = coordinates_; + } else { + result.coordinates_ = coordinatesBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.requestResponse_ = requestResponse_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage.getDefaultInstance()) return this; + if (other.hasCoordinates()) { + mergeCoordinates(other.getCoordinates()); + } + if (other.hasRequestResponse()) { + setRequestResponse(other.getRequestResponse()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasCoordinates()) { + + return false; + } + if (!hasRequestResponse()) { + + return false; + } + if (!getCoordinates().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder> coordinatesBuilder_; + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + public boolean hasCoordinates() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates getCoordinates() { + if (coordinatesBuilder_ == null) { + return coordinates_; + } else { + return coordinatesBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + public Builder setCoordinates(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates value) { + if (coordinatesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + coordinates_ = value; + onChanged(); + } else { + coordinatesBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + public Builder setCoordinates( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder builderForValue) { + if (coordinatesBuilder_ == null) { + coordinates_ = builderForValue.build(); + onChanged(); + } else { + coordinatesBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + public Builder mergeCoordinates(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates value) { + if (coordinatesBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + coordinates_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance()) { + coordinates_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.newBuilder(coordinates_).mergeFrom(value).buildPartial(); + } else { + coordinates_ = value; + } + onChanged(); + } else { + coordinatesBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + public Builder clearCoordinates() { + if (coordinatesBuilder_ == null) { + coordinates_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.getDefaultInstance(); + onChanged(); + } else { + coordinatesBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder getCoordinatesBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getCoordinatesFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder getCoordinatesOrBuilder() { + if (coordinatesBuilder_ != null) { + return coordinatesBuilder_.getMessageOrBuilder(); + } else { + return coordinates_; + } + } + /** + * required .xtreemfs.pbrpc.VivaldiCoordinates coordinates = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder> + getCoordinatesFieldBuilder() { + if (coordinatesBuilder_ == null) { + coordinatesBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinatesOrBuilder>( + coordinates_, + getParentForChildren(), + isClean()); + coordinates_ = null; + } + return coordinatesBuilder_; + } + + // required bool request_response = 2; + private boolean requestResponse_ ; + /** + * required bool request_response = 2; + */ + public boolean hasRequestResponse() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required bool request_response = 2; + */ + public boolean getRequestResponse() { + return requestResponse_; + } + /** + * required bool request_response = 2; + */ + public Builder setRequestResponse(boolean value) { + bitField0_ |= 0x00000002; + requestResponse_ = value; + onChanged(); + return this; + } + /** + * required bool request_response = 2; + */ + public Builder clearRequestResponse() { + bitField0_ = (bitField0_ & ~0x00000002); + requestResponse_ = false; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_pingMesssage) + } + + static { + defaultInstance = new xtreemfs_pingMesssage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_pingMesssage) + } + + public interface xtreemfs_rwr_auth_stateRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + boolean hasState(); + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState getState(); + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaStateOrBuilder getStateOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_auth_stateRequest} + */ + public static final class xtreemfs_rwr_auth_stateRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_rwr_auth_stateRequestOrBuilder { + // Use xtreemfs_rwr_auth_stateRequest.newBuilder() to construct. + private xtreemfs_rwr_auth_stateRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_rwr_auth_stateRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_rwr_auth_stateRequest defaultInstance; + public static xtreemfs_rwr_auth_stateRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_rwr_auth_stateRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_rwr_auth_stateRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 26: { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.Builder subBuilder = null; + if (((bitField0_ & 0x00000004) == 0x00000004)) { + subBuilder = state_.toBuilder(); + } + state_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(state_); + state_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000004; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_auth_stateRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_auth_stateRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_rwr_auth_stateRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_rwr_auth_stateRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + public static final int STATE_FIELD_NUMBER = 3; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState state_; + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + public boolean hasState() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState getState() { + return state_; + } + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaStateOrBuilder getStateOrBuilder() { + return state_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + state_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasState()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getState().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeMessage(3, state_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, state_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_auth_stateRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_auth_stateRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_auth_stateRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + getStateFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + if (stateBuilder_ == null) { + state_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.getDefaultInstance(); + } else { + stateBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_auth_stateRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + if (stateBuilder_ == null) { + result.state_ = state_; + } else { + result.state_ = stateBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasState()) { + mergeState(other.getState()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasState()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + if (!getState().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState state_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState, org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaStateOrBuilder> stateBuilder_; + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + public boolean hasState() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState getState() { + if (stateBuilder_ == null) { + return state_; + } else { + return stateBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + public Builder setState(org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState value) { + if (stateBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + state_ = value; + onChanged(); + } else { + stateBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + public Builder setState( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.Builder builderForValue) { + if (stateBuilder_ == null) { + state_ = builderForValue.build(); + onChanged(); + } else { + stateBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + public Builder mergeState(org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState value) { + if (stateBuilder_ == null) { + if (((bitField0_ & 0x00000004) == 0x00000004) && + state_ != org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.getDefaultInstance()) { + state_ = + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.newBuilder(state_).mergeFrom(value).buildPartial(); + } else { + state_ = value; + } + onChanged(); + } else { + stateBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + public Builder clearState() { + if (stateBuilder_ == null) { + state_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.getDefaultInstance(); + onChanged(); + } else { + stateBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.Builder getStateBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getStateFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaStateOrBuilder getStateOrBuilder() { + if (stateBuilder_ != null) { + return stateBuilder_.getMessageOrBuilder(); + } else { + return state_; + } + } + /** + * required .xtreemfs.pbrpc.AuthoritativeReplicaState state = 3; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState, org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaStateOrBuilder> + getStateFieldBuilder() { + if (stateBuilder_ == null) { + stateBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState, org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaState.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.AuthoritativeReplicaStateOrBuilder>( + state_, + getParentForChildren(), + isClean()); + state_ = null; + } + return stateBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_rwr_auth_stateRequest) + } + + static { + defaultInstance = new xtreemfs_rwr_auth_stateRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_auth_stateRequest) + } + + public interface xtreemfs_rwr_reset_completeRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + + // required fixed32 primary_epoch = 3; + /** + * required fixed32 primary_epoch = 3; + */ + boolean hasPrimaryEpoch(); + /** + * required fixed32 primary_epoch = 3; + */ + int getPrimaryEpoch(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_reset_completeRequest} + */ + public static final class xtreemfs_rwr_reset_completeRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_rwr_reset_completeRequestOrBuilder { + // Use xtreemfs_rwr_reset_completeRequest.newBuilder() to construct. + private xtreemfs_rwr_reset_completeRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_rwr_reset_completeRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_rwr_reset_completeRequest defaultInstance; + public static xtreemfs_rwr_reset_completeRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_rwr_reset_completeRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_rwr_reset_completeRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + case 29: { + bitField0_ |= 0x00000004; + primaryEpoch_ = input.readFixed32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_reset_completeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_reset_completeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_rwr_reset_completeRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_rwr_reset_completeRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // required fixed32 primary_epoch = 3; + public static final int PRIMARY_EPOCH_FIELD_NUMBER = 3; + private int primaryEpoch_; + /** + * required fixed32 primary_epoch = 3; + */ + public boolean hasPrimaryEpoch() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 primary_epoch = 3; + */ + public int getPrimaryEpoch() { + return primaryEpoch_; + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + primaryEpoch_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPrimaryEpoch()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeFixed32(3, primaryEpoch_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeFixed32Size(3, primaryEpoch_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_rwr_reset_completeRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_reset_completeRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_reset_completeRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + primaryEpoch_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_rwr_reset_completeRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.primaryEpoch_ = primaryEpoch_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + if (other.hasPrimaryEpoch()) { + setPrimaryEpoch(other.getPrimaryEpoch()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!hasPrimaryEpoch()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_completeRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // required fixed32 primary_epoch = 3; + private int primaryEpoch_ ; + /** + * required fixed32 primary_epoch = 3; + */ + public boolean hasPrimaryEpoch() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * required fixed32 primary_epoch = 3; + */ + public int getPrimaryEpoch() { + return primaryEpoch_; + } + /** + * required fixed32 primary_epoch = 3; + */ + public Builder setPrimaryEpoch(int value) { + bitField0_ |= 0x00000004; + primaryEpoch_ = value; + onChanged(); + return this; + } + /** + * required fixed32 primary_epoch = 3; + */ + public Builder clearPrimaryEpoch() { + bitField0_ = (bitField0_ & ~0x00000004); + primaryEpoch_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_rwr_reset_completeRequest) + } + + static { + defaultInstance = new xtreemfs_rwr_reset_completeRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_rwr_reset_completeRequest) + } + + public interface xtreemfs_xloc_set_invalidateRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + boolean hasFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials(); + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder(); + + // required string file_id = 2; + /** + * required string file_id = 2; + */ + boolean hasFileId(); + /** + * required string file_id = 2; + */ + java.lang.String getFileId(); + /** + * required string file_id = 2; + */ + com.google.protobuf.ByteString + getFileIdBytes(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_xloc_set_invalidateRequest} + */ + public static final class xtreemfs_xloc_set_invalidateRequest extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_xloc_set_invalidateRequestOrBuilder { + // Use xtreemfs_xloc_set_invalidateRequest.newBuilder() to construct. + private xtreemfs_xloc_set_invalidateRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_xloc_set_invalidateRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_xloc_set_invalidateRequest defaultInstance; + public static xtreemfs_xloc_set_invalidateRequest getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_xloc_set_invalidateRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_xloc_set_invalidateRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + subBuilder = fileCredentials_.toBuilder(); + } + fileCredentials_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(fileCredentials_); + fileCredentials_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + bitField0_ |= 0x00000002; + fileId_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_xloc_set_invalidateRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_xloc_set_invalidateRequest(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + public static final int FILE_CREDENTIALS_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + return fileCredentials_; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + return fileCredentials_; + } + + // required string file_id = 2; + public static final int FILE_ID_FIELD_NUMBER = 2; + private java.lang.Object fileId_; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + fileId_ = s; + } + return s; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + fileId_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasFileCredentials()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFileId()) { + memoizedIsInitialized = 0; + return false; + } + if (!getFileCredentials().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeMessage(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, getFileIdBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, fileCredentials_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, getFileIdBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_xloc_set_invalidateRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getFileCredentialsFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + fileId_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateRequest_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + if (fileCredentialsBuilder_ == null) { + result.fileCredentials_ = fileCredentials_; + } else { + result.fileCredentials_ = fileCredentialsBuilder_.build(); + } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.fileId_ = fileId_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest.getDefaultInstance()) return this; + if (other.hasFileCredentials()) { + mergeFileCredentials(other.getFileCredentials()); + } + if (other.hasFileId()) { + bitField0_ |= 0x00000002; + fileId_ = other.fileId_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFileCredentials()) { + + return false; + } + if (!hasFileId()) { + + return false; + } + if (!getFileCredentials().isInitialized()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> fileCredentialsBuilder_; + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public boolean hasFileCredentials() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials getFileCredentials() { + if (fileCredentialsBuilder_ == null) { + return fileCredentials_; + } else { + return fileCredentialsBuilder_.getMessage(); + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + fileCredentials_ = value; + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder setFileCredentials( + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder builderForValue) { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = builderForValue.build(); + onChanged(); + } else { + fileCredentialsBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder mergeFileCredentials(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials value) { + if (fileCredentialsBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001) && + fileCredentials_ != org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance()) { + fileCredentials_ = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.newBuilder(fileCredentials_).mergeFrom(value).buildPartial(); + } else { + fileCredentials_ = value; + } + onChanged(); + } else { + fileCredentialsBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public Builder clearFileCredentials() { + if (fileCredentialsBuilder_ == null) { + fileCredentials_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.getDefaultInstance(); + onChanged(); + } else { + fileCredentialsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder getFileCredentialsBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getFileCredentialsFieldBuilder().getBuilder(); + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder getFileCredentialsOrBuilder() { + if (fileCredentialsBuilder_ != null) { + return fileCredentialsBuilder_.getMessageOrBuilder(); + } else { + return fileCredentials_; + } + } + /** + * required .xtreemfs.pbrpc.FileCredentials file_credentials = 1; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder> + getFileCredentialsFieldBuilder() { + if (fileCredentialsBuilder_ == null) { + fileCredentialsBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials.Builder, org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentialsOrBuilder>( + fileCredentials_, + getParentForChildren(), + isClean()); + fileCredentials_ = null; + } + return fileCredentialsBuilder_; + } + + // required string file_id = 2; + private java.lang.Object fileId_ = ""; + /** + * required string file_id = 2; + */ + public boolean hasFileId() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required string file_id = 2; + */ + public java.lang.String getFileId() { + java.lang.Object ref = fileId_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + fileId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string file_id = 2; + */ + public com.google.protobuf.ByteString + getFileIdBytes() { + java.lang.Object ref = fileId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fileId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string file_id = 2; + */ + public Builder setFileId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder clearFileId() { + bitField0_ = (bitField0_ & ~0x00000002); + fileId_ = getDefaultInstance().getFileId(); + onChanged(); + return this; + } + /** + * required string file_id = 2; + */ + public Builder setFileIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + fileId_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_xloc_set_invalidateRequest) + } + + static { + defaultInstance = new xtreemfs_xloc_set_invalidateRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_xloc_set_invalidateRequest) + } + + public interface xtreemfs_xloc_set_invalidateResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required .xtreemfs.pbrpc.LeaseState lease_state = 1; + /** + * required .xtreemfs.pbrpc.LeaseState lease_state = 1; + */ + boolean hasLeaseState(); + /** + * required .xtreemfs.pbrpc.LeaseState lease_state = 1; + */ + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState getLeaseState(); + + // optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + boolean hasReplicaStatus(); + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus getReplicaStatus(); + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatusOrBuilder getReplicaStatusOrBuilder(); + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_xloc_set_invalidateResponse} + */ + public static final class xtreemfs_xloc_set_invalidateResponse extends + com.google.protobuf.GeneratedMessage + implements xtreemfs_xloc_set_invalidateResponseOrBuilder { + // Use xtreemfs_xloc_set_invalidateResponse.newBuilder() to construct. + private xtreemfs_xloc_set_invalidateResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private xtreemfs_xloc_set_invalidateResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final xtreemfs_xloc_set_invalidateResponse defaultInstance; + public static xtreemfs_xloc_set_invalidateResponse getDefaultInstance() { + return defaultInstance; + } + + public xtreemfs_xloc_set_invalidateResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private xtreemfs_xloc_set_invalidateResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + int rawValue = input.readEnum(); + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState value = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(1, rawValue); + } else { + bitField0_ |= 0x00000001; + leaseState_ = value; + } + break; + } + case 18: { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = replicaStatus_.toBuilder(); + } + replicaStatus_ = input.readMessage(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(replicaStatus_); + replicaStatus_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public xtreemfs_xloc_set_invalidateResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new xtreemfs_xloc_set_invalidateResponse(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required .xtreemfs.pbrpc.LeaseState lease_state = 1; + public static final int LEASE_STATE_FIELD_NUMBER = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState leaseState_; + /** + * required .xtreemfs.pbrpc.LeaseState lease_state = 1; + */ + public boolean hasLeaseState() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.LeaseState lease_state = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState getLeaseState() { + return leaseState_; + } + + // optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + public static final int REPLICA_STATUS_FIELD_NUMBER = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus replicaStatus_; + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + public boolean hasReplicaStatus() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus getReplicaStatus() { + return replicaStatus_; + } + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatusOrBuilder getReplicaStatusOrBuilder() { + return replicaStatus_; + } + + private void initFields() { + leaseState_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState.NONE; + replicaStatus_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasLeaseState()) { + memoizedIsInitialized = 0; + return false; + } + if (hasReplicaStatus()) { + if (!getReplicaStatus().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeEnum(1, leaseState_.getNumber()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, replicaStatus_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(1, leaseState_.getNumber()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, replicaStatus_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code xtreemfs.pbrpc.xtreemfs_xloc_set_invalidateResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse.class, org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse.Builder.class); + } + + // Construct using org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getReplicaStatusFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + leaseState_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState.NONE; + bitField0_ = (bitField0_ & ~0x00000001); + if (replicaStatusBuilder_ == null) { + replicaStatus_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.getDefaultInstance(); + } else { + replicaStatusBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateResponse_descriptor; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse getDefaultInstanceForType() { + return org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse.getDefaultInstance(); + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse build() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse buildPartial() { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse result = new org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.leaseState_ = leaseState_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + if (replicaStatusBuilder_ == null) { + result.replicaStatus_ = replicaStatus_; + } else { + result.replicaStatus_ = replicaStatusBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse) { + return mergeFrom((org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse other) { + if (other == org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse.getDefaultInstance()) return this; + if (other.hasLeaseState()) { + setLeaseState(other.getLeaseState()); + } + if (other.hasReplicaStatus()) { + mergeReplicaStatus(other.getReplicaStatus()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasLeaseState()) { + + return false; + } + if (hasReplicaStatus()) { + if (!getReplicaStatus().isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required .xtreemfs.pbrpc.LeaseState lease_state = 1; + private org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState leaseState_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState.NONE; + /** + * required .xtreemfs.pbrpc.LeaseState lease_state = 1; + */ + public boolean hasLeaseState() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required .xtreemfs.pbrpc.LeaseState lease_state = 1; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState getLeaseState() { + return leaseState_; + } + /** + * required .xtreemfs.pbrpc.LeaseState lease_state = 1; + */ + public Builder setLeaseState(org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + leaseState_ = value; + onChanged(); + return this; + } + /** + * required .xtreemfs.pbrpc.LeaseState lease_state = 1; + */ + public Builder clearLeaseState() { + bitField0_ = (bitField0_ & ~0x00000001); + leaseState_ = org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState.NONE; + onChanged(); + return this; + } + + // optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + private org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus replicaStatus_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatusOrBuilder> replicaStatusBuilder_; + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + public boolean hasReplicaStatus() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus getReplicaStatus() { + if (replicaStatusBuilder_ == null) { + return replicaStatus_; + } else { + return replicaStatusBuilder_.getMessage(); + } + } + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + public Builder setReplicaStatus(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus value) { + if (replicaStatusBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + replicaStatus_ = value; + onChanged(); + } else { + replicaStatusBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + public Builder setReplicaStatus( + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.Builder builderForValue) { + if (replicaStatusBuilder_ == null) { + replicaStatus_ = builderForValue.build(); + onChanged(); + } else { + replicaStatusBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + public Builder mergeReplicaStatus(org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus value) { + if (replicaStatusBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + replicaStatus_ != org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.getDefaultInstance()) { + replicaStatus_ = + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.newBuilder(replicaStatus_).mergeFrom(value).buildPartial(); + } else { + replicaStatus_ = value; + } + onChanged(); + } else { + replicaStatusBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + public Builder clearReplicaStatus() { + if (replicaStatusBuilder_ == null) { + replicaStatus_ = org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.getDefaultInstance(); + onChanged(); + } else { + replicaStatusBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.Builder getReplicaStatusBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getReplicaStatusFieldBuilder().getBuilder(); + } + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + public org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatusOrBuilder getReplicaStatusOrBuilder() { + if (replicaStatusBuilder_ != null) { + return replicaStatusBuilder_.getMessageOrBuilder(); + } else { + return replicaStatus_; + } + } + /** + * optional .xtreemfs.pbrpc.ReplicaStatus replica_status = 2; + */ + private com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatusOrBuilder> + getReplicaStatusFieldBuilder() { + if (replicaStatusBuilder_ == null) { + replicaStatusBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus.Builder, org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatusOrBuilder>( + replicaStatus_, + getParentForChildren(), + isClean()); + replicaStatus_ = null; + } + return replicaStatusBuilder_; + } + + // @@protoc_insertion_point(builder_scope:xtreemfs.pbrpc.xtreemfs_xloc_set_invalidateResponse) + } + + static { + defaultInstance = new xtreemfs_xloc_set_invalidateResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:xtreemfs.pbrpc.xtreemfs_xloc_set_invalidateResponse) + } + + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_InternalGmax_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_InternalGmax_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_Lock_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_Lock_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_ObjectData_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_ObjectData_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_ObjectList_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_ObjectList_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_ObjectVersion_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_ObjectVersion_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_TruncateRecord_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_TruncateRecord_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_TruncateLog_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_TruncateLog_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_XLocSetVersionState_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_XLocSetVersionState_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_ReplicaStatus_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_ReplicaStatus_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_ObjectVersionMapping_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_ObjectVersionMapping_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_AuthoritativeReplicaState_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_AuthoritativeReplicaState_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_InternalReadLocalResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_InternalReadLocalResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_readRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_readRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_truncateRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_truncateRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_unlink_osd_Request_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_unlink_osd_Request_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_writeRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_writeRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_broadcast_gmaxRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_broadcast_gmaxRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_check_objectRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_check_objectRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_get_resultsResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_get_resultsResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_is_runningResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_is_runningResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_startRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_startRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_statusResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_statusResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_fetchRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_fetchRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_repair_objectRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_repair_objectRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_flease_msgRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_flease_msgRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_set_primary_epochRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_set_primary_epochRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_statusRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_statusRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_truncateRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_truncateRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_updateRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_updateRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_gmaxRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_gmaxRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_internal_read_localRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_internal_read_localRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_object_setRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_object_setRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_fileid_listResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_fileid_listResponse_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_lockRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_lockRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_pingMesssage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_pingMesssage_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_auth_stateRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_auth_stateRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_reset_completeRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_reset_completeRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateResponse_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\022xtreemfs/OSD.proto\022\016xtreemfs.pbrpc\032\023in" + + "clude/PBRPC.proto\032\024include/Common.proto\032" + + "\032xtreemfs/GlobalTypes.proto\"H\n\014InternalG" + + "max\022\r\n\005epoch\030\001 \002(\006\022\021\n\tfile_size\030\002 \002(\006\022\026\n" + + "\016last_object_id\030\003 \002(\006\"b\n\004Lock\022\022\n\nclient_" + + "pid\030\001 \002(\007\022\023\n\013client_uuid\030\002 \002(\t\022\016\n\006length" + + "\030\003 \002(\006\022\016\n\006offset\030\004 \002(\006\022\021\n\texclusive\030\005 \002(" + + "\010\"U\n\nObjectData\022\020\n\010checksum\030\001 \002(\007\022\037\n\027inv" + + "alid_checksum_on_osd\030\002 \002(\010\022\024\n\014zero_paddi" + + "ng\030\003 \002(\007\"?\n\nObjectList\022\013\n\003set\030\001 \002(\014\022\024\n\014s", + "tripe_width\030\002 \002(\007\022\016\n\006first_\030\003 \002(\007\">\n\rObj" + + "ectVersion\022\025\n\robject_number\030\001 \002(\006\022\026\n\016obj" + + "ect_version\030\002 \002(\006\"=\n\016TruncateRecord\022\017\n\007v" + + "ersion\030\001 \002(\006\022\032\n\022last_object_number\030\002 \002(\006" + + "\">\n\013TruncateLog\022/\n\007records\030\001 \003(\0132\036.xtree" + + "mfs.pbrpc.TruncateRecord\"R\n\023XLocSetVersi" + + "onState\022\017\n\007version\030\001 \002(\007\022\023\n\013invalidated\030" + + "\002 \002(\010\022\025\n\rmodified_time\030\003 \001(\006\"\324\001\n\rReplica" + + "Status\022\026\n\016truncate_epoch\030\001 \002(\006\022\021\n\tfile_s" + + "ize\030\002 \002(\006\022\027\n\017max_obj_version\030\003 \002(\006\022\025\n\rpr", + "imary_epoch\030\004 \002(\007\0225\n\016objectVersions\030\005 \003(" + + "\0132\035.xtreemfs.pbrpc.ObjectVersion\0221\n\014trun" + + "cate_log\030\006 \002(\0132\033.xtreemfs.pbrpc.Truncate" + + "Log\"X\n\024ObjectVersionMapping\022\025\n\robject_nu" + + "mber\030\001 \002(\006\022\026\n\016object_version\030\002 \002(\006\022\021\n\tos" + + "d_uuids\030\003 \003(\t\"\275\001\n\031AuthoritativeReplicaSt" + + "ate\022\026\n\016truncate_epoch\030\001 \002(\006\022\027\n\017max_obj_v" + + "ersion\030\004 \002(\006\022<\n\016objectVersions\030\002 \003(\0132$.x" + + "treemfs.pbrpc.ObjectVersionMapping\0221\n\014tr" + + "uncate_log\030\003 \002(\0132\033.xtreemfs.pbrpc.Trunca", + "teLog\"u\n\031InternalReadLocalResponse\022(\n\004da" + + "ta\030\001 \002(\0132\032.xtreemfs.pbrpc.ObjectData\022.\n\n" + + "object_set\030\002 \003(\0132\032.xtreemfs.pbrpc.Object" + + "List\"\250\001\n\013readRequest\0229\n\020file_credentials" + + "\030\001 \002(\0132\037.xtreemfs.pbrpc.FileCredentials\022" + + "\017\n\007file_id\030\002 \002(\t\022\025\n\robject_number\030\003 \002(\006\022" + + "\026\n\016object_version\030\004 \002(\006\022\016\n\006offset\030\005 \002(\007\022" + + "\016\n\006length\030\006 \002(\007\"t\n\017truncateRequest\0229\n\020fi" + + "le_credentials\030\001 \002(\0132\037.xtreemfs.pbrpc.Fi" + + "leCredentials\022\017\n\007file_id\030\002 \002(\t\022\025\n\rnew_fi", + "le_size\030\003 \002(\006\"`\n\022unlink_osd_Request\0229\n\020f" + + "ile_credentials\030\001 \002(\0132\037.xtreemfs.pbrpc.F" + + "ileCredentials\022\017\n\007file_id\030\002 \002(\t\"\341\001\n\014writ" + + "eRequest\0229\n\020file_credentials\030\001 \002(\0132\037.xtr" + + "eemfs.pbrpc.FileCredentials\022\017\n\007file_id\030\002" + + " \002(\t\022\025\n\robject_number\030\003 \002(\006\022\026\n\016object_ve" + + "rsion\030\004 \002(\006\022\016\n\006offset\030\005 \002(\007\022\025\n\rlease_tim" + + "eout\030\006 \002(\006\022/\n\013object_data\030\007 \002(\0132\032.xtreem" + + "fs.pbrpc.ObjectData\"q\n\036xtreemfs_broadcas" + + "t_gmaxRequest\022\017\n\007file_id\030\001 \002(\t\022\026\n\016trunca", + "te_epoch\030\002 \002(\006\022\023\n\013last_object\030\003 \002(\006\022\021\n\tf" + + "ile_size\030\004 \002(\006\"\231\001\n\034xtreemfs_check_object" + + "Request\0229\n\020file_credentials\030\001 \002(\0132\037.xtre" + + "emfs.pbrpc.FileCredentials\022\017\n\007file_id\030\002 " + + "\002(\t\022\025\n\robject_number\030\003 \002(\006\022\026\n\016object_ver" + + "sion\030\004 \002(\006\"7\n$xtreemfs_cleanup_get_resul" + + "tsResponse\022\017\n\007results\030\001 \003(\t\"9\n#xtreemfs_" + + "cleanup_is_runningResponse\022\022\n\nis_running" + + "\030\001 \002(\010\"\241\001\n\035xtreemfs_cleanup_startRequest" + + "\022\026\n\016remove_zombies\030\001 \002(\010\022\035\n\025remove_unava", + "il_volume\030\002 \002(\010\022\026\n\016lost_and_found\030\003 \002(\010\022" + + "\027\n\017delete_metadata\030\004 \002(\010\022\030\n\020metadata_tim" + + "eout\030\005 \002(\007\"1\n\037xtreemfs_cleanup_statusRes" + + "ponse\022\016\n\006status\030\001 \002(\t\"\226\001\n\031xtreemfs_rwr_f" + + "etchRequest\0229\n\020file_credentials\030\001 \002(\0132\037." + + "xtreemfs.pbrpc.FileCredentials\022\017\n\007file_i" + + "d\030\002 \002(\t\022\025\n\robject_number\030\003 \002(\006\022\026\n\016object" + + "_version\030\004 \002(\006\"\232\001\n\035xtreemfs_repair_objec" + + "tRequest\0229\n\020file_credentials\030\001 \002(\0132\037.xtr" + + "eemfs.pbrpc.FileCredentials\022\017\n\007file_id\030\002", + " \002(\t\022\025\n\robject_number\030\003 \002(\006\022\026\n\016object_ve" + + "rsion\030\004 \002(\006\"N\n\036xtreemfs_rwr_flease_msgRe" + + "quest\022\027\n\017sender_hostname\030\001 \002(\t\022\023\n\013sender" + + "_port\030\002 \002(\007\"\212\001\n%xtreemfs_rwr_set_primary" + + "_epochRequest\0229\n\020file_credentials\030\001 \002(\0132" + + "\037.xtreemfs.pbrpc.FileCredentials\022\017\n\007file" + + "_id\030\002 \002(\t\022\025\n\rprimary_epoch\030\003 \002(\007\"\207\001\n\032xtr" + + "eemfs_rwr_statusRequest\0229\n\020file_credenti" + + "als\030\001 \002(\0132\037.xtreemfs.pbrpc.FileCredentia" + + "ls\022\017\n\007file_id\030\002 \002(\t\022\035\n\025max_local_obj_ver", + "sion\030\003 \002(\006\"\231\001\n\034xtreemfs_rwr_truncateRequ" + + "est\0229\n\020file_credentials\030\001 \002(\0132\037.xtreemfs" + + ".pbrpc.FileCredentials\022\017\n\007file_id\030\002 \002(\t\022" + + "\025\n\rnew_file_size\030\003 \002(\006\022\026\n\016object_version" + + "\030\004 \002(\006\"\347\001\n\032xtreemfs_rwr_updateRequest\0229\n" + + "\020file_credentials\030\001 \002(\0132\037.xtreemfs.pbrpc" + + ".FileCredentials\022\017\n\007file_id\030\002 \002(\t\022\025\n\rnew" + + "_file_size\030\003 \002(\006\022\025\n\robject_number\030\007 \002(\006\022" + + "\026\n\016object_version\030\004 \002(\006\022\016\n\006offset\030\005 \002(\007\022" + + "\'\n\003obj\030\006 \002(\0132\032.xtreemfs.pbrpc.ObjectData", + "\"o\n!xtreemfs_internal_get_gmaxRequest\0229\n" + + "\020file_credentials\030\001 \002(\0132\037.xtreemfs.pbrpc" + + ".FileCredentials\022\017\n\007file_id\030\002 \002(\t\"t\n&xtr" + + "eemfs_internal_get_file_sizeRequest\0229\n\020f" + + "ile_credentials\030\001 \002(\0132\037.xtreemfs.pbrpc.F" + + "ileCredentials\022\017\n\007file_id\030\002 \002(\t\"<\n\'xtree" + + "mfs_internal_get_file_sizeResponse\022\021\n\tfi" + + "le_size\030\001 \002(\006\"\222\002\n#xtreemfs_internal_read" + + "_localRequest\0229\n\020file_credentials\030\001 \002(\0132" + + "\037.xtreemfs.pbrpc.FileCredentials\022\017\n\007file", + "_id\030\002 \002(\t\022\025\n\robject_number\030\003 \002(\006\022\026\n\016obje" + + "ct_version\030\004 \002(\006\022\016\n\006offset\030\005 \002(\007\022\016\n\006leng" + + "th\030\006 \002(\007\022\032\n\022attach_object_list\030\007 \002(\010\0224\n\020" + + "required_objects\030\010 \003(\0132\032.xtreemfs.pbrpc." + + "ObjectList\"u\n\'xtreemfs_internal_get_obje" + + "ct_setRequest\0229\n\020file_credentials\030\001 \002(\0132" + + "\037.xtreemfs.pbrpc.FileCredentials\022\017\n\007file" + + "_id\030\002 \002(\t\"=\n)xtreemfs_internal_get_filei" + + "d_listResponse\022\020\n\010file_ids\030\001 \003(\t\"t\n\013lock" + + "Request\0229\n\020file_credentials\030\001 \002(\0132\037.xtre", + "emfs.pbrpc.FileCredentials\022*\n\014lock_reque" + + "st\030\002 \002(\0132\024.xtreemfs.pbrpc.Lock\"j\n\025xtreem" + + "fs_pingMesssage\0227\n\013coordinates\030\001 \002(\0132\".x" + + "treemfs.pbrpc.VivaldiCoordinates\022\030\n\020requ" + + "est_response\030\002 \002(\010\"\246\001\n\036xtreemfs_rwr_auth" + + "_stateRequest\0229\n\020file_credentials\030\001 \002(\0132" + + "\037.xtreemfs.pbrpc.FileCredentials\022\017\n\007file" + + "_id\030\002 \002(\t\0228\n\005state\030\003 \002(\0132).xtreemfs.pbrp" + + "c.AuthoritativeReplicaState\"\207\001\n\"xtreemfs" + + "_rwr_reset_completeRequest\0229\n\020file_crede", + "ntials\030\001 \002(\0132\037.xtreemfs.pbrpc.FileCreden" + + "tials\022\017\n\007file_id\030\002 \002(\t\022\025\n\rprimary_epoch\030" + + "\003 \002(\007\"q\n#xtreemfs_xloc_set_invalidateReq" + + "uest\0229\n\020file_credentials\030\001 \002(\0132\037.xtreemf" + + "s.pbrpc.FileCredentials\022\017\n\007file_id\030\002 \002(\t" + + "\"\216\001\n$xtreemfs_xloc_set_invalidateRespons" + + "e\022/\n\013lease_state\030\001 \002(\0162\032.xtreemfs.pbrpc." + + "LeaseState\0225\n\016replica_status\030\002 \001(\0132\035.xtr" + + "eemfs.pbrpc.ReplicaStatus*\215\001\n\017OSDHealthR" + + "esult\022\034\n\030OSD_HEALTH_RESULT_PASSED\020\000\022\035\n\031O", + "SD_HEALTH_RESULT_WARNING\020\001\022\034\n\030OSD_HEALTH" + + "_RESULT_FAILED\020\002\022\037\n\033OSD_HEALTH_RESULT_NO" + + "T_AVAIL\020\0032\277\036\n\nOSDService\022L\n\004read\022\033.xtree" + + "mfs.pbrpc.readRequest\032\032.xtreemfs.pbrpc.O" + + "bjectData\"\013\215\265\030\n\000\000\000\230\265\030\001\022V\n\010truncate\022\037.xtr" + + "eemfs.pbrpc.truncateRequest\032 .xtreemfs.p" + + "brpc.OSDWriteResponse\"\007\215\265\030\013\000\000\000\022T\n\006unlink" + + "\022\".xtreemfs.pbrpc.unlink_osd_Request\032\035.x" + + "treemfs.pbrpc.emptyResponse\"\007\215\265\030\014\000\000\000\022T\n\005" + + "write\022\034.xtreemfs.pbrpc.writeRequest\032 .xt", + "reemfs.pbrpc.OSDWriteResponse\"\013\215\265\030\r\000\000\000\240\265" + + "\030\001\022q\n\027xtreemfs_broadcast_gmax\022..xtreemfs" + + ".pbrpc.xtreemfs_broadcast_gmaxRequest\032\035." + + "xtreemfs.pbrpc.emptyResponse\"\007\215\265\030\024\000\000\000\022j\n" + + "\025xtreemfs_check_object\022,.xtreemfs.pbrpc." + + "xtreemfs_check_objectRequest\032\032.xtreemfs." + + "pbrpc.ObjectData\"\007\215\265\030\025\000\000\000\022{\n\034xtreemfs_cl" + + "eanup_get_results\022\034.xtreemfs.pbrpc.empty" + + "Request\0324.xtreemfs.pbrpc.xtreemfs_cleanu" + + "p_get_resultsResponse\"\007\215\265\030\036\000\000\000\022y\n\033xtreem", + "fs_cleanup_is_running\022\034.xtreemfs.pbrpc.e" + + "mptyRequest\0323.xtreemfs.pbrpc.xtreemfs_cl" + + "eanup_is_runningResponse\"\007\215\265\030\037\000\000\000\022o\n\026xtr" + + "eemfs_cleanup_start\022-.xtreemfs.pbrpc.xtr" + + "eemfs_cleanup_startRequest\032\035.xtreemfs.pb" + + "rpc.emptyResponse\"\007\215\265\030 \000\000\000\022q\n\027xtreemfs_c" + + "leanup_status\022\034.xtreemfs.pbrpc.emptyRequ" + + "est\032/.xtreemfs.pbrpc.xtreemfs_cleanup_st" + + "atusResponse\"\007\215\265\030!\000\000\000\022]\n\025xtreemfs_cleanu" + + "p_stop\022\034.xtreemfs.pbrpc.emptyRequest\032\035.x", + "treemfs.pbrpc.emptyResponse\"\007\215\265\030\"\000\000\000\022g\n\037" + + "xtreemfs_cleanup_versions_start\022\034.xtreem" + + "fs.pbrpc.emptyRequest\032\035.xtreemfs.pbrpc.e" + + "mptyResponse\"\007\215\265\030#\000\000\000\022o\n\026xtreemfs_repair" + + "_object\022-.xtreemfs.pbrpc.xtreemfs_repair" + + "_objectRequest\032\035.xtreemfs.pbrpc.emptyRes" + + "ponse\"\007\215\265\030$\000\000\000\022d\n\022xtreemfs_rwr_fetch\022).x" + + "treemfs.pbrpc.xtreemfs_rwr_fetchRequest\032" + + "\032.xtreemfs.pbrpc.ObjectData\"\007\215\265\030I\000\000\000\022u\n\027" + + "xtreemfs_rwr_flease_msg\022..xtreemfs.pbrpc", + ".xtreemfs_rwr_flease_msgRequest\032\035.xtreem" + + "fs.pbrpc.emptyResponse\"\013\215\265\030G\000\000\000\240\265\030\001\022^\n\023x" + + "treemfs_rwr_notify\022\037.xtreemfs.pbrpc.File" + + "Credentials\032\035.xtreemfs.pbrpc.emptyRespon" + + "se\"\007\215\265\030K\000\000\000\022|\n\036xtreemfs_rwr_set_primary_" + + "epoch\0225.xtreemfs.pbrpc.xtreemfs_rwr_set_" + + "primary_epochRequest\032\032.xtreemfs.pbrpc.Ob" + + "jectData\"\007\215\265\030N\000\000\000\022i\n\023xtreemfs_rwr_status" + + "\022*.xtreemfs.pbrpc.xtreemfs_rwr_statusReq" + + "uest\032\035.xtreemfs.pbrpc.ReplicaStatus\"\007\215\265\030", + "L\000\000\000\022m\n\025xtreemfs_rwr_truncate\022,.xtreemfs" + + ".pbrpc.xtreemfs_rwr_truncateRequest\032\035.xt" + + "reemfs.pbrpc.emptyResponse\"\007\215\265\030J\000\000\000\022m\n\023x" + + "treemfs_rwr_update\022*.xtreemfs.pbrpc.xtre" + + "emfs_rwr_updateRequest\032\035.xtreemfs.pbrpc." + + "emptyResponse\"\013\215\265\030H\000\000\000\240\265\030\001\022q\n\027xtreemfs_r" + + "wr_auth_state\022..xtreemfs.pbrpc.xtreemfs_" + + "rwr_auth_stateRequest\032\035.xtreemfs.pbrpc.e" + + "mptyResponse\"\007\215\265\030O\000\000\000\022y\n\033xtreemfs_rwr_re" + + "set_complete\0222.xtreemfs.pbrpc.xtreemfs_r", + "wr_reset_completeRequest\032\035.xtreemfs.pbrp" + + "c.emptyResponse\"\007\215\265\030P\000\000\000\022v\n\032xtreemfs_int" + + "ernal_get_gmax\0221.xtreemfs.pbrpc.xtreemfs" + + "_internal_get_gmaxRequest\032\034.xtreemfs.pbr" + + "pc.InternalGmax\"\007\215\265\030(\000\000\000\022h\n\032xtreemfs_int" + + "ernal_truncate\022\037.xtreemfs.pbrpc.truncate" + + "Request\032 .xtreemfs.pbrpc.OSDWriteRespons" + + "e\"\007\215\265\030)\000\000\000\022\233\001\n\037xtreemfs_internal_get_fil" + + "e_size\0226.xtreemfs.pbrpc.xtreemfs_interna" + + "l_get_file_sizeRequest\0327.xtreemfs.pbrpc.", + "xtreemfs_internal_get_file_sizeResponse\"" + + "\007\215\265\030*\000\000\000\022\207\001\n\034xtreemfs_internal_read_loca" + + "l\0223.xtreemfs.pbrpc.xtreemfs_internal_rea" + + "d_localRequest\032).xtreemfs.pbrpc.Internal" + + "ReadLocalResponse\"\007\215\265\030+\000\000\000\022\200\001\n xtreemfs_" + + "internal_get_object_set\0227.xtreemfs.pbrpc" + + ".xtreemfs_internal_get_object_setRequest" + + "\032\032.xtreemfs.pbrpc.ObjectList\"\007\215\265\030,\000\000\000\022\205\001" + + "\n!xtreemfs_internal_get_fileid_list\022\034.xt" + + "reemfs.pbrpc.emptyRequest\0329.xtreemfs.pbr", + "pc.xtreemfs_internal_get_fileid_listResp" + + "onse\"\007\215\265\030-\000\000\000\022S\n\025xtreemfs_lock_acquire\022\033" + + ".xtreemfs.pbrpc.lockRequest\032\024.xtreemfs.p" + + "brpc.Lock\"\007\215\265\0302\000\000\000\022Q\n\023xtreemfs_lock_chec" + + "k\022\033.xtreemfs.pbrpc.lockRequest\032\024.xtreemf" + + "s.pbrpc.Lock\"\007\215\265\0303\000\000\000\022\\\n\025xtreemfs_lock_r" + + "elease\022\033.xtreemfs.pbrpc.lockRequest\032\035.xt" + + "reemfs.pbrpc.emptyResponse\"\007\215\265\0304\000\000\000\022f\n\rx" + + "treemfs_ping\022%.xtreemfs.pbrpc.xtreemfs_p" + + "ingMesssage\032%.xtreemfs.pbrpc.xtreemfs_pi", + "ngMesssage\"\007\215\265\030<\000\000\000\022Y\n\021xtreemfs_shutdown" + + "\022\034.xtreemfs.pbrpc.emptyRequest\032\035.xtreemf" + + "s.pbrpc.emptyResponse\"\007\215\265\030F\000\000\000\022\222\001\n\034xtree" + + "mfs_xloc_set_invalidate\0223.xtreemfs.pbrpc" + + ".xtreemfs_xloc_set_invalidateRequest\0324.x" + + "treemfs.pbrpc.xtreemfs_xloc_set_invalida" + + "teResponse\"\007\215\265\030Q\000\000\000\022}\n#xtreemfs_rwr_auth" + + "_state_invalidated\022..xtreemfs.pbrpc.xtre" + + "emfs_rwr_auth_stateRequest\032\035.xtreemfs.pb" + + "rpc.emptyResponse\"\007\215\265\030R\000\000\000\032\007\225\265\0301u\000\000B(\n&o", + "rg.xtreemfs.pbrpc.generatedinterfaces" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_xtreemfs_pbrpc_InternalGmax_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_xtreemfs_pbrpc_InternalGmax_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_InternalGmax_descriptor, + new java.lang.String[] { "Epoch", "FileSize", "LastObjectId", }); + internal_static_xtreemfs_pbrpc_Lock_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_xtreemfs_pbrpc_Lock_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_Lock_descriptor, + new java.lang.String[] { "ClientPid", "ClientUuid", "Length", "Offset", "Exclusive", }); + internal_static_xtreemfs_pbrpc_ObjectData_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_xtreemfs_pbrpc_ObjectData_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_ObjectData_descriptor, + new java.lang.String[] { "Checksum", "InvalidChecksumOnOsd", "ZeroPadding", }); + internal_static_xtreemfs_pbrpc_ObjectList_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_xtreemfs_pbrpc_ObjectList_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_ObjectList_descriptor, + new java.lang.String[] { "Set", "StripeWidth", "First", }); + internal_static_xtreemfs_pbrpc_ObjectVersion_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_xtreemfs_pbrpc_ObjectVersion_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_ObjectVersion_descriptor, + new java.lang.String[] { "ObjectNumber", "ObjectVersion", }); + internal_static_xtreemfs_pbrpc_TruncateRecord_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_xtreemfs_pbrpc_TruncateRecord_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_TruncateRecord_descriptor, + new java.lang.String[] { "Version", "LastObjectNumber", }); + internal_static_xtreemfs_pbrpc_TruncateLog_descriptor = + getDescriptor().getMessageTypes().get(6); + internal_static_xtreemfs_pbrpc_TruncateLog_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_TruncateLog_descriptor, + new java.lang.String[] { "Records", }); + internal_static_xtreemfs_pbrpc_XLocSetVersionState_descriptor = + getDescriptor().getMessageTypes().get(7); + internal_static_xtreemfs_pbrpc_XLocSetVersionState_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_XLocSetVersionState_descriptor, + new java.lang.String[] { "Version", "Invalidated", "ModifiedTime", }); + internal_static_xtreemfs_pbrpc_ReplicaStatus_descriptor = + getDescriptor().getMessageTypes().get(8); + internal_static_xtreemfs_pbrpc_ReplicaStatus_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_ReplicaStatus_descriptor, + new java.lang.String[] { "TruncateEpoch", "FileSize", "MaxObjVersion", "PrimaryEpoch", "ObjectVersions", "TruncateLog", }); + internal_static_xtreemfs_pbrpc_ObjectVersionMapping_descriptor = + getDescriptor().getMessageTypes().get(9); + internal_static_xtreemfs_pbrpc_ObjectVersionMapping_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_ObjectVersionMapping_descriptor, + new java.lang.String[] { "ObjectNumber", "ObjectVersion", "OsdUuids", }); + internal_static_xtreemfs_pbrpc_AuthoritativeReplicaState_descriptor = + getDescriptor().getMessageTypes().get(10); + internal_static_xtreemfs_pbrpc_AuthoritativeReplicaState_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_AuthoritativeReplicaState_descriptor, + new java.lang.String[] { "TruncateEpoch", "MaxObjVersion", "ObjectVersions", "TruncateLog", }); + internal_static_xtreemfs_pbrpc_InternalReadLocalResponse_descriptor = + getDescriptor().getMessageTypes().get(11); + internal_static_xtreemfs_pbrpc_InternalReadLocalResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_InternalReadLocalResponse_descriptor, + new java.lang.String[] { "Data", "ObjectSet", }); + internal_static_xtreemfs_pbrpc_readRequest_descriptor = + getDescriptor().getMessageTypes().get(12); + internal_static_xtreemfs_pbrpc_readRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_readRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "ObjectNumber", "ObjectVersion", "Offset", "Length", }); + internal_static_xtreemfs_pbrpc_truncateRequest_descriptor = + getDescriptor().getMessageTypes().get(13); + internal_static_xtreemfs_pbrpc_truncateRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_truncateRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "NewFileSize", }); + internal_static_xtreemfs_pbrpc_unlink_osd_Request_descriptor = + getDescriptor().getMessageTypes().get(14); + internal_static_xtreemfs_pbrpc_unlink_osd_Request_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_unlink_osd_Request_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", }); + internal_static_xtreemfs_pbrpc_writeRequest_descriptor = + getDescriptor().getMessageTypes().get(15); + internal_static_xtreemfs_pbrpc_writeRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_writeRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "ObjectNumber", "ObjectVersion", "Offset", "LeaseTimeout", "ObjectData", }); + internal_static_xtreemfs_pbrpc_xtreemfs_broadcast_gmaxRequest_descriptor = + getDescriptor().getMessageTypes().get(16); + internal_static_xtreemfs_pbrpc_xtreemfs_broadcast_gmaxRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_broadcast_gmaxRequest_descriptor, + new java.lang.String[] { "FileId", "TruncateEpoch", "LastObject", "FileSize", }); + internal_static_xtreemfs_pbrpc_xtreemfs_check_objectRequest_descriptor = + getDescriptor().getMessageTypes().get(17); + internal_static_xtreemfs_pbrpc_xtreemfs_check_objectRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_check_objectRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "ObjectNumber", "ObjectVersion", }); + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_get_resultsResponse_descriptor = + getDescriptor().getMessageTypes().get(18); + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_get_resultsResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_get_resultsResponse_descriptor, + new java.lang.String[] { "Results", }); + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_is_runningResponse_descriptor = + getDescriptor().getMessageTypes().get(19); + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_is_runningResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_is_runningResponse_descriptor, + new java.lang.String[] { "IsRunning", }); + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_startRequest_descriptor = + getDescriptor().getMessageTypes().get(20); + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_startRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_startRequest_descriptor, + new java.lang.String[] { "RemoveZombies", "RemoveUnavailVolume", "LostAndFound", "DeleteMetadata", "MetadataTimeout", }); + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_statusResponse_descriptor = + getDescriptor().getMessageTypes().get(21); + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_statusResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_cleanup_statusResponse_descriptor, + new java.lang.String[] { "Status", }); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_fetchRequest_descriptor = + getDescriptor().getMessageTypes().get(22); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_fetchRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_fetchRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "ObjectNumber", "ObjectVersion", }); + internal_static_xtreemfs_pbrpc_xtreemfs_repair_objectRequest_descriptor = + getDescriptor().getMessageTypes().get(23); + internal_static_xtreemfs_pbrpc_xtreemfs_repair_objectRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_repair_objectRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "ObjectNumber", "ObjectVersion", }); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_flease_msgRequest_descriptor = + getDescriptor().getMessageTypes().get(24); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_flease_msgRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_flease_msgRequest_descriptor, + new java.lang.String[] { "SenderHostname", "SenderPort", }); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_set_primary_epochRequest_descriptor = + getDescriptor().getMessageTypes().get(25); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_set_primary_epochRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_set_primary_epochRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "PrimaryEpoch", }); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_statusRequest_descriptor = + getDescriptor().getMessageTypes().get(26); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_statusRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_statusRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "MaxLocalObjVersion", }); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_truncateRequest_descriptor = + getDescriptor().getMessageTypes().get(27); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_truncateRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_truncateRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "NewFileSize", "ObjectVersion", }); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_updateRequest_descriptor = + getDescriptor().getMessageTypes().get(28); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_updateRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_updateRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "NewFileSize", "ObjectNumber", "ObjectVersion", "Offset", "Obj", }); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_gmaxRequest_descriptor = + getDescriptor().getMessageTypes().get(29); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_gmaxRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_gmaxRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", }); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeRequest_descriptor = + getDescriptor().getMessageTypes().get(30); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", }); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeResponse_descriptor = + getDescriptor().getMessageTypes().get(31); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_file_sizeResponse_descriptor, + new java.lang.String[] { "FileSize", }); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_read_localRequest_descriptor = + getDescriptor().getMessageTypes().get(32); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_read_localRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_internal_read_localRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "ObjectNumber", "ObjectVersion", "Offset", "Length", "AttachObjectList", "RequiredObjects", }); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_object_setRequest_descriptor = + getDescriptor().getMessageTypes().get(33); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_object_setRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_object_setRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", }); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_fileid_listResponse_descriptor = + getDescriptor().getMessageTypes().get(34); + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_fileid_listResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_internal_get_fileid_listResponse_descriptor, + new java.lang.String[] { "FileIds", }); + internal_static_xtreemfs_pbrpc_lockRequest_descriptor = + getDescriptor().getMessageTypes().get(35); + internal_static_xtreemfs_pbrpc_lockRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_lockRequest_descriptor, + new java.lang.String[] { "FileCredentials", "LockRequest", }); + internal_static_xtreemfs_pbrpc_xtreemfs_pingMesssage_descriptor = + getDescriptor().getMessageTypes().get(36); + internal_static_xtreemfs_pbrpc_xtreemfs_pingMesssage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_pingMesssage_descriptor, + new java.lang.String[] { "Coordinates", "RequestResponse", }); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_auth_stateRequest_descriptor = + getDescriptor().getMessageTypes().get(37); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_auth_stateRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_auth_stateRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "State", }); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_reset_completeRequest_descriptor = + getDescriptor().getMessageTypes().get(38); + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_reset_completeRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_rwr_reset_completeRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", "PrimaryEpoch", }); + internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateRequest_descriptor = + getDescriptor().getMessageTypes().get(39); + internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateRequest_descriptor, + new java.lang.String[] { "FileCredentials", "FileId", }); + internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateResponse_descriptor = + getDescriptor().getMessageTypes().get(40); + internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_xtreemfs_pbrpc_xtreemfs_xloc_set_invalidateResponse_descriptor, + new java.lang.String[] { "LeaseState", "ReplicaStatus", }); + com.google.protobuf.ExtensionRegistry registry = + com.google.protobuf.ExtensionRegistry.newInstance(); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.dataOut); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.dataIn); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.dataIn); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.dataIn); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.procId); + registry.add(org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.interfaceId); + return registry; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + org.xtreemfs.foundation.pbrpc.generatedinterfaces.PBRPC.getDescriptor(), + org.xtreemfs.pbrpc.generatedinterfaces.Common.getDescriptor(), + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.getDescriptor(), + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSDServiceClient.java b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSDServiceClient.java new file mode 100644 index 0000000..18f391b --- /dev/null +++ b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSDServiceClient.java @@ -0,0 +1,485 @@ +//automatically generated from OSD.proto at Thu Dec 11 16:09:37 CET 2014 +//(c) 2014. See LICENSE file for details. + +package org.xtreemfs.pbrpc.generatedinterfaces; + +import java.io.IOException; +import java.util.List; +import java.net.InetSocketAddress; +import com.google.protobuf.Message; +import com.google.protobuf.ByteString; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; + +public class OSDServiceClient { + + private RPCNIOSocketClient client; + private InetSocketAddress defaultServer; + + public OSDServiceClient(RPCNIOSocketClient client, InetSocketAddress defaultServer) { + this.client = client; + this.defaultServer = defaultServer; + } + + public RPCResponse read(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.readRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.ObjectData.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 10, input, null, response, false); + return response; + } + + public RPCResponse read(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, long object_number, long object_version, int offset, int length) throws IOException { + final OSD.readRequest msg = OSD.readRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setObjectNumber(object_number).setObjectVersion(object_version).setOffset(offset).setLength(length).build(); + return read(server, authHeader, userCreds,msg); + } + + public RPCResponse truncate(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.truncateRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(GlobalTypes.OSDWriteResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 11, input, null, response, false); + return response; + } + + public RPCResponse truncate(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, long new_file_size) throws IOException { + final OSD.truncateRequest msg = OSD.truncateRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setNewFileSize(new_file_size).build(); + return truncate(server, authHeader, userCreds,msg); + } + + public RPCResponse unlink(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.unlink_osd_Request input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 12, input, null, response, false); + return response; + } + + public RPCResponse unlink(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id) throws IOException { + final OSD.unlink_osd_Request msg = OSD.unlink_osd_Request.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).build(); + return unlink(server, authHeader, userCreds,msg); + } + + public RPCResponse write(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.writeRequest input, ReusableBuffer data) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(GlobalTypes.OSDWriteResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 13, input, data, response, false); + return response; + } + + public RPCResponse write(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, long object_number, long object_version, int offset, long lease_timeout, OSD.ObjectData object_data, ReusableBuffer data) throws IOException { + final OSD.writeRequest msg = OSD.writeRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setObjectNumber(object_number).setObjectVersion(object_version).setOffset(offset).setLeaseTimeout(lease_timeout).setObjectData(object_data).build(); + return write(server, authHeader, userCreds,msg, data); + } + + public RPCResponse xtreemfs_broadcast_gmax(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_broadcast_gmaxRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 20, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_broadcast_gmax(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String file_id, long truncate_epoch, long last_object, long file_size) throws IOException { + final OSD.xtreemfs_broadcast_gmaxRequest msg = OSD.xtreemfs_broadcast_gmaxRequest.newBuilder().setFileId(file_id).setTruncateEpoch(truncate_epoch).setLastObject(last_object).setFileSize(file_size).build(); + return xtreemfs_broadcast_gmax(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_check_object(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_check_objectRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.ObjectData.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 21, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_check_object(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, long object_number, long object_version) throws IOException { + final OSD.xtreemfs_check_objectRequest msg = OSD.xtreemfs_check_objectRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setObjectNumber(object_number).setObjectVersion(object_version).build(); + return xtreemfs_check_object(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_cleanup_get_results(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.xtreemfs_cleanup_get_resultsResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 30, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_cleanup_get_results(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_cleanup_get_results(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_cleanup_is_running(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.xtreemfs_cleanup_is_runningResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 31, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_cleanup_is_running(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_cleanup_is_running(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_cleanup_start(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_cleanup_startRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 32, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_cleanup_start(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, boolean remove_zombies, boolean remove_unavail_volume, boolean lost_and_found, boolean delete_metadata, int metadata_timeout) throws IOException { + final OSD.xtreemfs_cleanup_startRequest msg = OSD.xtreemfs_cleanup_startRequest.newBuilder().setRemoveZombies(remove_zombies).setRemoveUnavailVolume(remove_unavail_volume).setLostAndFound(lost_and_found).setDeleteMetadata(delete_metadata).setMetadataTimeout(metadata_timeout).build(); + return xtreemfs_cleanup_start(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_cleanup_status(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.xtreemfs_cleanup_statusResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 33, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_cleanup_status(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_cleanup_status(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_cleanup_stop(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 34, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_cleanup_stop(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_cleanup_stop(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_cleanup_versions_start(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 35, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_cleanup_versions_start(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_cleanup_versions_start(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_repair_object(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_repair_objectRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 36, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_repair_object(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, long object_number, long object_version) throws IOException { + final OSD.xtreemfs_repair_objectRequest msg = OSD.xtreemfs_repair_objectRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setObjectNumber(object_number).setObjectVersion(object_version).build(); + return xtreemfs_repair_object(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_rwr_fetch(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_rwr_fetchRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.ObjectData.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 73, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_rwr_fetch(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, long object_number, long object_version) throws IOException { + final OSD.xtreemfs_rwr_fetchRequest msg = OSD.xtreemfs_rwr_fetchRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setObjectNumber(object_number).setObjectVersion(object_version).build(); + return xtreemfs_rwr_fetch(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_rwr_flease_msg(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_rwr_flease_msgRequest input, ReusableBuffer data) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 71, input, data, response, false); + return response; + } + + public RPCResponse xtreemfs_rwr_flease_msg(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, String sender_hostname, int sender_port, ReusableBuffer data) throws IOException { + final OSD.xtreemfs_rwr_flease_msgRequest msg = OSD.xtreemfs_rwr_flease_msgRequest.newBuilder().setSenderHostname(sender_hostname).setSenderPort(sender_port).build(); + return xtreemfs_rwr_flease_msg(server, authHeader, userCreds,msg, data); + } + + public RPCResponse xtreemfs_rwr_notify(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 75, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_rwr_notify(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.XCap xcap, GlobalTypes.XLocSet xlocs) throws IOException { + final GlobalTypes.FileCredentials msg = GlobalTypes.FileCredentials.newBuilder().setXcap(xcap).setXlocs(xlocs).build(); + return xtreemfs_rwr_notify(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_rwr_set_primary_epoch(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_rwr_set_primary_epochRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.ObjectData.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 78, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_rwr_set_primary_epoch(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, int primary_epoch) throws IOException { + final OSD.xtreemfs_rwr_set_primary_epochRequest msg = OSD.xtreemfs_rwr_set_primary_epochRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setPrimaryEpoch(primary_epoch).build(); + return xtreemfs_rwr_set_primary_epoch(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_rwr_status(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_rwr_statusRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.ReplicaStatus.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 76, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_rwr_status(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, long max_local_obj_version) throws IOException { + final OSD.xtreemfs_rwr_statusRequest msg = OSD.xtreemfs_rwr_statusRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setMaxLocalObjVersion(max_local_obj_version).build(); + return xtreemfs_rwr_status(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_rwr_truncate(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_rwr_truncateRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 74, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_rwr_truncate(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, long new_file_size, long object_version) throws IOException { + final OSD.xtreemfs_rwr_truncateRequest msg = OSD.xtreemfs_rwr_truncateRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setNewFileSize(new_file_size).setObjectVersion(object_version).build(); + return xtreemfs_rwr_truncate(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_rwr_update(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_rwr_updateRequest input, ReusableBuffer data) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 72, input, data, response, false); + return response; + } + + public RPCResponse xtreemfs_rwr_update(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, long new_file_size, long object_number, long object_version, int offset, OSD.ObjectData obj, ReusableBuffer data) throws IOException { + final OSD.xtreemfs_rwr_updateRequest msg = OSD.xtreemfs_rwr_updateRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setNewFileSize(new_file_size).setObjectNumber(object_number).setObjectVersion(object_version).setOffset(offset).setObj(obj).build(); + return xtreemfs_rwr_update(server, authHeader, userCreds,msg, data); + } + + public RPCResponse xtreemfs_rwr_auth_state(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_rwr_auth_stateRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 79, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_rwr_auth_state(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, OSD.AuthoritativeReplicaState state) throws IOException { + final OSD.xtreemfs_rwr_auth_stateRequest msg = OSD.xtreemfs_rwr_auth_stateRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setState(state).build(); + return xtreemfs_rwr_auth_state(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_rwr_reset_complete(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_rwr_reset_completeRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 80, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_rwr_reset_complete(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, int primary_epoch) throws IOException { + final OSD.xtreemfs_rwr_reset_completeRequest msg = OSD.xtreemfs_rwr_reset_completeRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setPrimaryEpoch(primary_epoch).build(); + return xtreemfs_rwr_reset_complete(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_internal_get_gmax(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_internal_get_gmaxRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.InternalGmax.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 40, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_internal_get_gmax(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id) throws IOException { + final OSD.xtreemfs_internal_get_gmaxRequest msg = OSD.xtreemfs_internal_get_gmaxRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).build(); + return xtreemfs_internal_get_gmax(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_internal_truncate(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.truncateRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(GlobalTypes.OSDWriteResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 41, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_internal_truncate(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, long new_file_size) throws IOException { + final OSD.truncateRequest msg = OSD.truncateRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setNewFileSize(new_file_size).build(); + return xtreemfs_internal_truncate(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_internal_get_file_size(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_internal_get_file_sizeRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.xtreemfs_internal_get_file_sizeResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 42, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_internal_get_file_size(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id) throws IOException { + final OSD.xtreemfs_internal_get_file_sizeRequest msg = OSD.xtreemfs_internal_get_file_sizeRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).build(); + return xtreemfs_internal_get_file_size(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_internal_read_local(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_internal_read_localRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.InternalReadLocalResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 43, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_internal_read_local(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, long object_number, long object_version, int offset, int length, boolean attach_object_list, List required_objects) throws IOException { + final OSD.xtreemfs_internal_read_localRequest msg = OSD.xtreemfs_internal_read_localRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setObjectNumber(object_number).setObjectVersion(object_version).setOffset(offset).setLength(length).setAttachObjectList(attach_object_list).addAllRequiredObjects(required_objects).build(); + return xtreemfs_internal_read_local(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_internal_get_object_set(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_internal_get_object_setRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.ObjectList.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 44, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_internal_get_object_set(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id) throws IOException { + final OSD.xtreemfs_internal_get_object_setRequest msg = OSD.xtreemfs_internal_get_object_setRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).build(); + return xtreemfs_internal_get_object_set(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_internal_get_fileid_list(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.xtreemfs_internal_get_fileid_listResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 45, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_internal_get_fileid_list(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_internal_get_fileid_list(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_lock_acquire(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.lockRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.Lock.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 50, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_lock_acquire(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, OSD.Lock lock_request) throws IOException { + final OSD.lockRequest msg = OSD.lockRequest.newBuilder().setFileCredentials(file_credentials).setLockRequest(lock_request).build(); + return xtreemfs_lock_acquire(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_lock_check(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.lockRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.Lock.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 51, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_lock_check(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, OSD.Lock lock_request) throws IOException { + final OSD.lockRequest msg = OSD.lockRequest.newBuilder().setFileCredentials(file_credentials).setLockRequest(lock_request).build(); + return xtreemfs_lock_check(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_lock_release(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.lockRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 52, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_lock_release(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, OSD.Lock lock_request) throws IOException { + final OSD.lockRequest msg = OSD.lockRequest.newBuilder().setFileCredentials(file_credentials).setLockRequest(lock_request).build(); + return xtreemfs_lock_release(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_ping(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_pingMesssage input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.xtreemfs_pingMesssage.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 60, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_ping(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.VivaldiCoordinates coordinates, boolean request_response) throws IOException { + final OSD.xtreemfs_pingMesssage msg = OSD.xtreemfs_pingMesssage.newBuilder().setCoordinates(coordinates).setRequestResponse(request_response).build(); + return xtreemfs_ping(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_shutdown(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, Common.emptyRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 70, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_shutdown(InetSocketAddress server, Auth authHeader, UserCredentials userCreds) throws IOException { + + return xtreemfs_shutdown(server, authHeader, userCreds,null); + } + + public RPCResponse xtreemfs_xloc_set_invalidate(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_xloc_set_invalidateRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(OSD.xtreemfs_xloc_set_invalidateResponse.getDefaultInstance()); + client.sendRequest(server, authHeader, userCreds, 30001, 81, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_xloc_set_invalidate(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id) throws IOException { + final OSD.xtreemfs_xloc_set_invalidateRequest msg = OSD.xtreemfs_xloc_set_invalidateRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).build(); + return xtreemfs_xloc_set_invalidate(server, authHeader, userCreds,msg); + } + + public RPCResponse xtreemfs_rwr_auth_state_invalidated(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, OSD.xtreemfs_rwr_auth_stateRequest input) throws IOException { + if (server == null) server = defaultServer; + if (server == null) throw new IllegalArgumentException("defaultServer must be set in constructor if you want to pass null as server in calls"); + RPCResponse response = new RPCResponse(null); + client.sendRequest(server, authHeader, userCreds, 30001, 82, input, null, response, false); + return response; + } + + public RPCResponse xtreemfs_rwr_auth_state_invalidated(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, GlobalTypes.FileCredentials file_credentials, String file_id, OSD.AuthoritativeReplicaState state) throws IOException { + final OSD.xtreemfs_rwr_auth_stateRequest msg = OSD.xtreemfs_rwr_auth_stateRequest.newBuilder().setFileCredentials(file_credentials).setFileId(file_id).setState(state).build(); + return xtreemfs_rwr_auth_state_invalidated(server, authHeader, userCreds,msg); + } + + public boolean clientIsAlive() { + return client.isAlive(); + } +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSDServiceConstants.java b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSDServiceConstants.java new file mode 100644 index 0000000..4fb0849 --- /dev/null +++ b/java/servers/src/org/xtreemfs/pbrpc/generatedinterfaces/OSDServiceConstants.java @@ -0,0 +1,131 @@ +//automatically generated from OSD.proto at Thu Dec 11 16:09:37 CET 2014 +//(c) 2014. See LICENSE file for details. + +package org.xtreemfs.pbrpc.generatedinterfaces; + +import com.google.protobuf.Message; + +public class OSDServiceConstants { + + public static final int INTERFACE_ID = 30001; + public static final int PROC_ID_READ = 10; + public static final int PROC_ID_TRUNCATE = 11; + public static final int PROC_ID_UNLINK = 12; + public static final int PROC_ID_WRITE = 13; + public static final int PROC_ID_XTREEMFS_BROADCAST_GMAX = 20; + public static final int PROC_ID_XTREEMFS_CHECK_OBJECT = 21; + public static final int PROC_ID_XTREEMFS_CLEANUP_GET_RESULTS = 30; + public static final int PROC_ID_XTREEMFS_CLEANUP_IS_RUNNING = 31; + public static final int PROC_ID_XTREEMFS_CLEANUP_START = 32; + public static final int PROC_ID_XTREEMFS_CLEANUP_STATUS = 33; + public static final int PROC_ID_XTREEMFS_CLEANUP_STOP = 34; + public static final int PROC_ID_XTREEMFS_CLEANUP_VERSIONS_START = 35; + public static final int PROC_ID_XTREEMFS_REPAIR_OBJECT = 36; + public static final int PROC_ID_XTREEMFS_RWR_FETCH = 73; + public static final int PROC_ID_XTREEMFS_RWR_FLEASE_MSG = 71; + public static final int PROC_ID_XTREEMFS_RWR_NOTIFY = 75; + public static final int PROC_ID_XTREEMFS_RWR_SET_PRIMARY_EPOCH = 78; + public static final int PROC_ID_XTREEMFS_RWR_STATUS = 76; + public static final int PROC_ID_XTREEMFS_RWR_TRUNCATE = 74; + public static final int PROC_ID_XTREEMFS_RWR_UPDATE = 72; + public static final int PROC_ID_XTREEMFS_RWR_AUTH_STATE = 79; + public static final int PROC_ID_XTREEMFS_RWR_RESET_COMPLETE = 80; + public static final int PROC_ID_XTREEMFS_INTERNAL_GET_GMAX = 40; + public static final int PROC_ID_XTREEMFS_INTERNAL_TRUNCATE = 41; + public static final int PROC_ID_XTREEMFS_INTERNAL_GET_FILE_SIZE = 42; + public static final int PROC_ID_XTREEMFS_INTERNAL_READ_LOCAL = 43; + public static final int PROC_ID_XTREEMFS_INTERNAL_GET_OBJECT_SET = 44; + public static final int PROC_ID_XTREEMFS_INTERNAL_GET_FILEID_LIST = 45; + public static final int PROC_ID_XTREEMFS_LOCK_ACQUIRE = 50; + public static final int PROC_ID_XTREEMFS_LOCK_CHECK = 51; + public static final int PROC_ID_XTREEMFS_LOCK_RELEASE = 52; + public static final int PROC_ID_XTREEMFS_PING = 60; + public static final int PROC_ID_XTREEMFS_SHUTDOWN = 70; + public static final int PROC_ID_XTREEMFS_XLOC_SET_INVALIDATE = 81; + public static final int PROC_ID_XTREEMFS_RWR_AUTH_STATE_INVALIDATED = 82; + + public static Message getRequestMessage(int procId) { + switch (procId) { + case 10: return OSD.readRequest.getDefaultInstance(); + case 11: return OSD.truncateRequest.getDefaultInstance(); + case 12: return OSD.unlink_osd_Request.getDefaultInstance(); + case 13: return OSD.writeRequest.getDefaultInstance(); + case 20: return OSD.xtreemfs_broadcast_gmaxRequest.getDefaultInstance(); + case 21: return OSD.xtreemfs_check_objectRequest.getDefaultInstance(); + case 30: return null; + case 31: return null; + case 32: return OSD.xtreemfs_cleanup_startRequest.getDefaultInstance(); + case 33: return null; + case 34: return null; + case 35: return null; + case 36: return OSD.xtreemfs_repair_objectRequest.getDefaultInstance(); + case 73: return OSD.xtreemfs_rwr_fetchRequest.getDefaultInstance(); + case 71: return OSD.xtreemfs_rwr_flease_msgRequest.getDefaultInstance(); + case 75: return GlobalTypes.FileCredentials.getDefaultInstance(); + case 78: return OSD.xtreemfs_rwr_set_primary_epochRequest.getDefaultInstance(); + case 76: return OSD.xtreemfs_rwr_statusRequest.getDefaultInstance(); + case 74: return OSD.xtreemfs_rwr_truncateRequest.getDefaultInstance(); + case 72: return OSD.xtreemfs_rwr_updateRequest.getDefaultInstance(); + case 79: return OSD.xtreemfs_rwr_auth_stateRequest.getDefaultInstance(); + case 80: return OSD.xtreemfs_rwr_reset_completeRequest.getDefaultInstance(); + case 40: return OSD.xtreemfs_internal_get_gmaxRequest.getDefaultInstance(); + case 41: return OSD.truncateRequest.getDefaultInstance(); + case 42: return OSD.xtreemfs_internal_get_file_sizeRequest.getDefaultInstance(); + case 43: return OSD.xtreemfs_internal_read_localRequest.getDefaultInstance(); + case 44: return OSD.xtreemfs_internal_get_object_setRequest.getDefaultInstance(); + case 45: return null; + case 50: return OSD.lockRequest.getDefaultInstance(); + case 51: return OSD.lockRequest.getDefaultInstance(); + case 52: return OSD.lockRequest.getDefaultInstance(); + case 60: return OSD.xtreemfs_pingMesssage.getDefaultInstance(); + case 70: return null; + case 81: return OSD.xtreemfs_xloc_set_invalidateRequest.getDefaultInstance(); + case 82: return OSD.xtreemfs_rwr_auth_stateRequest.getDefaultInstance(); + default: throw new RuntimeException("unknown procedure id"); + } + } + + + public static Message getResponseMessage(int procId) { + switch (procId) { + case 10: return OSD.ObjectData.getDefaultInstance(); + case 11: return GlobalTypes.OSDWriteResponse.getDefaultInstance(); + case 12: return null; + case 13: return GlobalTypes.OSDWriteResponse.getDefaultInstance(); + case 20: return null; + case 21: return OSD.ObjectData.getDefaultInstance(); + case 30: return OSD.xtreemfs_cleanup_get_resultsResponse.getDefaultInstance(); + case 31: return OSD.xtreemfs_cleanup_is_runningResponse.getDefaultInstance(); + case 32: return null; + case 33: return OSD.xtreemfs_cleanup_statusResponse.getDefaultInstance(); + case 34: return null; + case 35: return null; + case 36: return null; + case 73: return OSD.ObjectData.getDefaultInstance(); + case 71: return null; + case 75: return null; + case 78: return OSD.ObjectData.getDefaultInstance(); + case 76: return OSD.ReplicaStatus.getDefaultInstance(); + case 74: return null; + case 72: return null; + case 79: return null; + case 80: return null; + case 40: return OSD.InternalGmax.getDefaultInstance(); + case 41: return GlobalTypes.OSDWriteResponse.getDefaultInstance(); + case 42: return OSD.xtreemfs_internal_get_file_sizeResponse.getDefaultInstance(); + case 43: return OSD.InternalReadLocalResponse.getDefaultInstance(); + case 44: return OSD.ObjectList.getDefaultInstance(); + case 45: return OSD.xtreemfs_internal_get_fileid_listResponse.getDefaultInstance(); + case 50: return OSD.Lock.getDefaultInstance(); + case 51: return OSD.Lock.getDefaultInstance(); + case 52: return null; + case 60: return OSD.xtreemfs_pingMesssage.getDefaultInstance(); + case 70: return null; + case 81: return OSD.xtreemfs_xloc_set_invalidateResponse.getDefaultInstance(); + case 82: return null; + default: throw new RuntimeException("unknown procedure id"); + } + } + + +} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/sandbox/BenchmarkStorageLayouts.java b/java/servers/src/org/xtreemfs/sandbox/BenchmarkStorageLayouts.java new file mode 100644 index 0000000..2cf9b9a --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/BenchmarkStorageLayouts.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.sandbox; + +import java.io.IOException; +import java.util.Properties; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.osd.storage.FileMetadata; +import org.xtreemfs.osd.storage.HashStorageLayout; +import org.xtreemfs.osd.storage.MetadataCache; +import org.xtreemfs.osd.storage.ObjectInformation; +import org.xtreemfs.osd.storage.RealSingleFileStorageLayout; +import org.xtreemfs.osd.storage.SingleFileStorageLayout; +import org.xtreemfs.osd.storage.StorageLayout; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; + +/** + * + * @author bjko + */ +public class BenchmarkStorageLayouts { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + // TODO code application logic here + try { + int objs = (args.length > 0) ? Integer.valueOf(args[0]) : 1024; + String path = (args.length > 1) ? args[1] : "/tmp"; + int objSize = (args.length > 2) ? Integer.valueOf(args[2]) : 128; + Logging.start(Logging.LEVEL_ERROR, Category.all); + + System.out.println("press enter after flushing caches: echo 3 > /proc/sys/vm/drop_caches"); + System.in.read(); + + SingleFileStorageLayout sfl = new SingleFileStorageLayout(new OSDConfig(createOSDProperties(path+"/sleval_single/")), new MetadataCache()); + HashStorageLayout hsl = new HashStorageLayout(new OSDConfig(createOSDProperties(path+"/sleval_hash/")), new MetadataCache()); + RealSingleFileStorageLayout rsl = new RealSingleFileStorageLayout(new OSDConfig(createOSDProperties(path+"/sleval_real/")), new MetadataCache()); + + /*write(hsl,objSize,objs); + + System.out.println("press enter after flushing caches: echo 3 > /proc/sys/vm/drop_caches"); + System.in.read(); + + write(sfl,objSize,objs);*/ + + System.out.println("press enter after flushing caches: echo 3 > /proc/sys/vm/drop_caches"); + System.in.read(); + + write(rsl,objSize,objs); + + + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(1); + } + } + + private static void write(StorageLayout layout, int objSize, int numObjs) throws IOException { + + System.out.println("testing: "+layout.getClass().getCanonicalName()); + + String fileId = "ABCDEF:123"; + Replica r = Replica.newBuilder().setReplicationFlags(0).setStripingPolicy(StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0).setWidth(1).setStripeSize(objSize)).build(); + StripingPolicyImpl sp = StripingPolicyImpl.getPolicy(r, 0); + + FileMetadata md = layout.getFileMetadata(sp, fileId); + + ReusableBuffer buf = BufferPool.allocate(objSize*1024); + while (buf.hasRemaining()) { + buf.put((byte) 'A'); + } + buf.flip(); + + long tStart = System.currentTimeMillis(); + + for (int i = 0; i < numObjs; i++) { + layout.writeObject(fileId, md, buf.createViewBuffer(), i, 0, 1, false, false); + buf.position(0); + } + + long tEnd = System.currentTimeMillis(); + + layout.closeFile(md); + + System.out.println("write: " + (tEnd - tStart) + " ms"); + + md = layout.getFileMetadata(sp, fileId); + + tStart = System.currentTimeMillis(); + + for (int i = 0; i < numObjs; i++) { + ObjectInformation oinfo = layout.readObject(fileId, md, i, 0, StorageLayout.FULL_OBJECT_LENGTH, md.getLatestObjectVersion(i)); + if (oinfo.getData() != null) + BufferPool.free(oinfo.getData()); + } + + tEnd = System.currentTimeMillis(); + + System.out.println("read : " + (tEnd - tStart) + " ms"); + + layout.closeFile(md); + + } + + private static Properties createOSDProperties(String dir) { + Properties props = new Properties(); + props.setProperty("dir_service.host", "localhost"); + props.setProperty("dir_service.port", "33638"); + props.setProperty("object_dir", dir); + props.setProperty("debug.level", "" + 5); + props.setProperty("debug.categories", "all"); + props.setProperty("listen.port", "3333"); + props.setProperty("http_port", "3334"); + props.setProperty("listen.address", "localhost"); + props.setProperty("local_clock_renewal", "0"); + props.setProperty("remote_time_sync", "60000"); + props.setProperty("ssl.enabled", "false"); + props.setProperty("report_free_space", "true"); + props.setProperty("checksums.enabled", "false"); + props.setProperty("checksums.algorithm", "Adler32"); + props.setProperty("capability_secret", "secretPassphrase"); + props.setProperty("uuid", "aygga"); + return props; + } +} diff --git a/java/servers/src/org/xtreemfs/sandbox/CleanupDemoVolume.java b/java/servers/src/org/xtreemfs/sandbox/CleanupDemoVolume.java new file mode 100644 index 0000000..9eb08f9 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/CleanupDemoVolume.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2012 by Lukas Kairies, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.sandbox; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.xtreemfs.common.libxtreemfs.Client; +import org.xtreemfs.common.libxtreemfs.ClientFactory; +import org.xtreemfs.common.libxtreemfs.FileHandle; +import org.xtreemfs.common.libxtreemfs.Options; +import org.xtreemfs.common.libxtreemfs.Volume; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Setattrs; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; + +public class CleanupDemoVolume { + private static Client client; + private static Volume volume; + private static UserCredentials userCredentials; + private static List exampleFiles; + + public static boolean DeleteDirectoryRecursively(String directoryPath) { + boolean errorsOccurred = false; + + try { + List dentries = volume.readDir(userCredentials, directoryPath, 0, 0, false) + .getEntriesList(); + for (DirectoryEntry dentry : dentries) { + String fullPath = (directoryPath.equals("/") ? "" : directoryPath) + "/" + dentry.getName(); + if (dentry.getName().equals(".") || dentry.getName().equals("..")) { + continue; + } + boolean skipEntry = false; + for (String file : exampleFiles) { + if (fullPath.equals("/" + new java.io.File(file).getName())) { + skipEntry = true; + break; + } + } + if (skipEntry) { + continue; + } + + if ((dentry.getStbuf().getMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFREG.getNumber()) != 0) { + // File. + try { + volume.unlink(userCredentials, fullPath); + } catch (IOException e) { + // No error for us. + } + } else if ((dentry.getStbuf().getMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFDIR.getNumber()) != 0) { + // Directory. + DeleteDirectoryRecursively(fullPath); + } + } + } catch (FileNotFoundException e) { + // Not counted as error. + } catch (IOException e) { + e.printStackTrace(); + errorsOccurred = true; + } + + // Delete directory itself. + if (!directoryPath.equals("/")) { + try { + volume.removeDirectory(userCredentials, directoryPath); + } catch (IOException e) { + e.printStackTrace(); + errorsOccurred = true; + } + } + + return errorsOccurred; + } + + public static void main(String[] args) { + if (args.length < 1 || !args[0].equals("yesiknowwhatiamdoing")) { + System.out + .println("This binary does delete all files older than one hour at demo.xtreemfs.org/demo/. Run it with \"yesiknowwhatiamdoing\" - otherwise it does abort."); + System.exit(1); + } + + Logging.start(Logging.LEVEL_ERROR, Category.tool); + + userCredentials = UserCredentials.newBuilder().setUsername("root").addGroups("root").build(); + + String dirAddress = "demo.xtreemfs.org:32638"; + + SSLOptions sslOptions = null; + + Options options = new Options(); + + try { + client = ClientFactory.createClient(dirAddress, userCredentials, sslOptions, options); + client.start(); + volume = client.openVolume("demo", sslOptions, options); + } catch (Exception e) { + System.out.println("The client could not be started/the volume opened."); + e.printStackTrace(); + System.exit(2); + } + + // Get file names of example files. + String exampleFilesDir = "/var/adm/xtreemfs/default_demo_files/"; + java.io.File dir = new java.io.File(exampleFilesDir); + String[] files = dir.list(); + exampleFiles = new ArrayList(files.length); + if (files != null) { + for (String file : files) { + exampleFiles.add(exampleFilesDir + file); + } + } + + // Clean everything. + boolean errorsOccurred = DeleteDirectoryRecursively("/"); + + // Copy example files. + for (String filename : exampleFiles) { + java.io.File sourceFile = new java.io.File(filename); + FileInputStream source = null; + FileHandle target = null; + try { + source = new FileInputStream(sourceFile); + target = volume.openFile(userCredentials, "/" + sourceFile.getName(), + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber()); + byte[] buffer = new byte[128 * 1024]; + int bytesRead = 0; + long bytewritten = 0; + while ((bytesRead = source.read(buffer)) != -1) { + target.write(userCredentials, buffer, bytesRead, bytewritten); + bytewritten += bytesRead; + } + } catch (FileNotFoundException e) { + System.out.println("File " + filename + " does not exist."); + e.printStackTrace(); + errorsOccurred = true; + } catch (IOException e) { + System.out.println("An IOError occurred when copying the file " + filename + "."); + e.printStackTrace(); + errorsOccurred = true; + } finally { + if (source != null) { + try { + source.close(); + } catch (IOException e) { + System.out.println("The source file " + filename + " could not be closed."); + e.printStackTrace(); + errorsOccurred = true; + } + } + if (target != null) { + try { + target.close(); + } catch (IOException e) { + System.out.println("The target file /" + sourceFile.getName() + + " could not be closed."); + e.printStackTrace(); + errorsOccurred = true; + } + } + } + } + // Truncate example files to actual size and chmod them. + for (String file : exampleFiles) { + String fileName = new java.io.File(file).getName(); + long fileSize = new java.io.File(file).length(); + FileHandle xtreemfsFile = null; + try { + xtreemfsFile = volume.openFile(userCredentials, "/" + fileName, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber()); + Stat stbuf = xtreemfsFile.getAttr(userCredentials).toBuilder().setMode(0666).build(); + volume.setAttr(userCredentials, "/" + fileName, stbuf, Setattrs.SETATTR_MODE.getNumber()); + xtreemfsFile.truncate(userCredentials, fileSize); + xtreemfsFile.close(); + } catch (IOException e) { + System.out.println("Failed to truncate /" + fileName + " to the length " + fileSize + "."); + e.printStackTrace(); + errorsOccurred = true; + } + } + + client.shutdown(); + + if (errorsOccurred) { + System.out.println("Not all items could be deleted / files copied."); + System.exit(3); + } + } +} diff --git a/java/servers/src/org/xtreemfs/sandbox/DBViewer.java b/java/servers/src/org/xtreemfs/sandbox/DBViewer.java new file mode 100644 index 0000000..3a9bb10 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/DBViewer.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.sandbox; + +import java.util.Arrays; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.xtreemfs.babudb.log.DiskLogFile; +import org.xtreemfs.babudb.log.LogEntry; +import org.xtreemfs.babudb.lsmdb.InsertRecordGroup; +import org.xtreemfs.babudb.lsmdb.LSN; +import org.xtreemfs.babudb.lsmdb.InsertRecordGroup.InsertRecord; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.mrc.metadata.BufferBackedRCMetadata; + +public class DBViewer { + + public static void main(String[] args) throws Exception { + + final String logDir = "/home/stender/mrc_data/"; + final String logFile = "1.4657052.dbl"; + + LSN nextLSN = null; + // read list of logs and create a list ordered from min LSN to max LSN + SortedSet orderedLogList = new TreeSet(); + Pattern p = Pattern.compile("(\\d+)\\.(\\d+)\\.dbl"); + + Matcher m = p.matcher(logFile); + m.matches(); + String tmp = m.group(1); + int viewId = Integer.valueOf(tmp); + tmp = m.group(2); + int seqNo = Integer.valueOf(tmp); + orderedLogList.add(new LSN(viewId, seqNo)); + + int i = 0; + + // apply log entries to databases... + for (LSN logLSN : orderedLogList) { + i++; + DiskLogFile dlf = new DiskLogFile(logDir, logLSN); + LogEntry le = null; + while (dlf.hasNext()) { + le = dlf.next(); + // do something + ReusableBuffer payload = le.getPayload(); + InsertRecordGroup ai = InsertRecordGroup.deserialize(payload); + System.out.println("DB ID: " + ai.getDatabaseId()); + System.out.println("inserts:"); + for (InsertRecord rec : ai.getInserts()) { + System.out.println(rec.getIndexId() + + ": " + + Arrays.toString(rec.getKey()) + + " = " + + (rec.getValue() == null ? null : rec.getValue().length > 20 ? ("[...] " + rec + .getValue().length) : Arrays.toString(rec.getValue()))); + if (rec.getValue() != null && rec.getIndexId() == 3 && rec.getKey()[rec.getKey().length - 1] == 1) { + BufferBackedRCMetadata md = new BufferBackedRCMetadata(rec.getKey(), rec.getValue()); + System.out.println(md.getXLocList().getLength()); + System.out.println(md.getXLocList().getReplica(0)); + } + } + le.free(); + } + // set lsn' + if (le != null) { + nextLSN = new LSN(le.getViewId(), le.getLogSequenceNo() + 1); + } + + if (i == 100) + break; + } + + } +} diff --git a/java/servers/src/org/xtreemfs/sandbox/DemoScrubber.java b/java/servers/src/org/xtreemfs/sandbox/DemoScrubber.java new file mode 100644 index 0000000..3f10188 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/DemoScrubber.java @@ -0,0 +1,421 @@ +///* Copyright (c) 2008,2009 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin. +// +// This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based +// Grid Operating System, see for more details. +// The XtreemOS project has been developed with the financial support of the +// European Commission's IST program under contract #FP6-033576. +// +// XtreemFS is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2 of the License, or (at your option) +// any later version. +// +// XtreemFS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with XtreemFS. If not, see . +// */ +///* +// * AUTHORS: Björn Kolbeck(ZIB), Nele Andersen (ZIB) +// */ +// +//package org.xtreemfs.sandbox; +// +//import java.io.FileInputStream; +//import java.net.InetSocketAddress; +//import java.util.ArrayList; +//import java.util.EmptyStackException; +//import java.util.HashMap; +//import java.util.LinkedList; +//import java.util.List; +//import java.util.Map; +//import java.util.Stack; +//import java.util.concurrent.ExecutorService; +//import java.util.concurrent.Executors; +// +//import org.xtreemfs.common.clients.Client; +//import org.xtreemfs.common.clients.io.RandomAccessFile; +//import org.xtreemfs.common.uuids.ServiceUUID; +//import org.xtreemfs.common.uuids.UUIDResolver; +//import org.xtreemfs.dir.client.DIRClient; +//import org.xtreemfs.foundation.SSLOptions; +//import org.xtreemfs.foundation.TimeServerClient; +//import org.xtreemfs.foundation.TimeSync; +//import org.xtreemfs.foundation.VersionManagement; +//import org.xtreemfs.foundation.logging.Logging; +//import org.xtreemfs.foundation.oncrpc.client.RPCNIOSocketClient; +//import org.xtreemfs.foundation.oncrpc.client.RPCResponse; +//import org.xtreemfs.foundation.util.CLIParser; +//import org.xtreemfs.foundation.util.ONCRPCServiceURL; +//import org.xtreemfs.foundation.util.CLIParser.CliOption; +//import org.xtreemfs.interfaces.Constants; +//import org.xtreemfs.interfaces.DirectoryEntry; +//import org.xtreemfs.interfaces.DirectoryEntrySet; +//import org.xtreemfs.interfaces.Service; +//import org.xtreemfs.interfaces.ServiceSet; +//import org.xtreemfs.interfaces.ServiceType; +//import org.xtreemfs.interfaces.Stat; +//import org.xtreemfs.interfaces.StringSet; +//import org.xtreemfs.interfaces.UserCredentials; +//import org.xtreemfs.interfaces.DIRInterface.DIRInterface; +//import org.xtreemfs.foundation.oncrpc.utils.XDRUtils; +//import org.xtreemfs.mrc.client.MRCClient; +// +///** +// * +// * @author bjko +// */ +//public class DemoScrubber implements DemoScrubberFileInfo.FileScrubbedListener { +// +// public static String latestScrubAttr = "scrubber.latestscrub"; +// +// public static final UserCredentials credentials; +// +// static { +// StringSet groupIDs = new StringSet(); +// groupIDs.add("root"); +// credentials = new UserCredentials("root", groupIDs, ""); +// } +// +// private static final int DEFAULT_NUM_THREADS = 10; +// +// private static final String DEFAULT_DIR_CONFIG = "/etc/xos/xtreemfs/default_dir"; +// +// private final String volumeName; +// +// private final RPCNIOSocketClient rpcClient; +// +// private final TimeServerClient dirClient; +// +// private final MRCClient mrcClient; +// +// private final boolean checkOnly; +// +// private final ExecutorService tPool; +// +// private long lastFileComplete; +// +// private long numFilesDeleted; +// +// private final Stack directories; +// +// private final Stack files; +// +// private final List defects; +// +// private final Object completeLock; +// +// private int returnCode; +// +// private int numInFlight; +// +// private final int numThrs; +// +// private boolean hasFinished; +// +// private String currentDirName = null; +// +// public DemoScrubber(RPCNIOSocketClient rpcClient, TimeServerClient dirClient, MRCClient mrcClient, +// String volume, boolean checkOnly, int numThrs) { +// this.rpcClient = rpcClient; +// this.dirClient = dirClient; +// this.mrcClient = mrcClient; +// this.volumeName = volume; +// this.checkOnly = checkOnly; +// this.numThrs = numThrs; +// +// directories = new Stack(); +// files = new Stack(); +// tPool = Executors.newFixedThreadPool(numThrs); +// numInFlight = 0; +// completeLock = new Object(); +// defects = new LinkedList(); +// hasFinished = false; +// } +// +// public int scrub() { +// +// System.out.println(""); +// directories.push(volumeName); +// fillQueue(); +// synchronized (completeLock) { +// try { +// if (!hasFinished) +// completeLock.wait(); +// } catch (InterruptedException ex) { +// } +// } +// tPool.shutdownNow(); +// +// return returnCode; +// } +// +// private void fillQueue() { +// try { +// synchronized (directories) { +// while (numInFlight < numThrs) { +// try { +// String filename = files.pop(); +// try { +// RandomAccessFile file = new RandomAccessFile("rw", mrcClient.getDefaultServerAddress(), +// filename, rpcClient, credentials); +// DemoScrubberFileInfo fi = new DemoScrubberFileInfo(file, this); +// tPool.submit(fi); +// numInFlight++; +// } catch (Exception ex) { +// ex.printStackTrace(); +// finish(1); +// return; +// } +// } catch (EmptyStackException ex) { +// //fetch next dir +// fetchNextDir(); +// } +// } +// } +// } catch (EmptyStackException ex) { +// //no more entries, finished! +// +// try { +// //mark volume as scrubbed +// RPCResponse r = mrcClient.setxattr(null, credentials, volumeName, "", latestScrubAttr, Long.toString(TimeSync.getLocalSystemTime()), 0); +// r.get(); +// r.freeBuffers(); +// } catch (Exception ex2) { +// System.out.println("\nWarning: cannot mark volume as successfully scrubbed: "+ex2); +// } +// +// finish(0); +// return; +// } +// } +// +// private void finish(int returnCode) { +// synchronized (directories) { +// if (numInFlight == 0) { +// synchronized (completeLock) { +// this.returnCode = returnCode; +// this.hasFinished = true; +// completeLock.notifyAll(); +// } +// } +// } +// } +// +// @Override +// public void fileScrubbed(RandomAccessFile file, boolean deleted) { +// //update statistics +// +// long total = 0; +// synchronized (directories) { +// if (deleted) +// numFilesDeleted++; +// System.out.format("scrubbed %-42s deleted %d files\n\u001b[100D\u001b[A",file.getFileId(),numFilesDeleted); +// numInFlight--; +// fillQueue(); +// } +// +// +// } +// +// private void fetchNextDir() { +// currentDirName = directories.pop(); +// +// try { +// String dirName = currentDirName.substring(volumeName.length() + 1); +// RPCResponse r = mrcClient.readdir(null, credentials, volumeName, dirName); +// DirectoryEntrySet ls = r.get(); +// r.freeBuffers(); +// +// for (DirectoryEntry e : ls) { +// final Stat s = e.getStbuf().get(0); +// if ((s.getMode() & Constants.SYSTEM_V_FCNTL_H_S_IFREG) != 0) { +// //regular file +// files.push(currentDirName+"/"+e.getName()); +// } else if ((s.getMode() & Constants.SYSTEM_V_FCNTL_H_S_IFDIR) != 0) { +// directories.push(currentDirName+"/"+e.getName()); +// } +// } +// } catch (Exception ex) { +// ex.printStackTrace(); +// throw new EmptyStackException(); +// } +// +// +// } +// +// +// public static void main(String[] args) throws Exception { +// +// Logging.start(Logging.LEVEL_WARN); +// +// System.out.println("XtreemFS DEMO VOLUME scrubber version "+VersionManagement.RELEASE_VERSION+" (file system data integrity check)\n"); +// +// Map options = new HashMap(); +// List arguments = new ArrayList(1); +// options.put("h", new CliOption(CliOption.OPTIONTYPE.SWITCH)); +// CliOption oDir = new CliOption(CliOption.OPTIONTYPE.URL); +// oDir.urlDefaultPort = DIRInterface.ONC_RPC_PORT_DEFAULT; +// oDir.urlDefaultProtocol = XDRUtils.ONCRPC_SCHEME; +// options.put("dir", oDir); +// options.put("chk", new CliOption(CliOption.OPTIONTYPE.SWITCH)); +// options.put("thrs", new CliOption(CliOption.OPTIONTYPE.NUMBER)); +// options.put("c", new CliOption(CliOption.OPTIONTYPE.STRING)); +// options.put("cpass", new CliOption(CliOption.OPTIONTYPE.STRING)); +// options.put("t", new CliOption(CliOption.OPTIONTYPE.STRING)); +// options.put("tpass", new CliOption(CliOption.OPTIONTYPE.STRING)); +// options.put("h", new CliOption(CliOption.OPTIONTYPE.SWITCH)); +// +// CLIParser.parseCLI(args, options, arguments); +// +// if (arguments.size() != 1 || options.get("h").switchValue == true) { +// usage(); +// return; +// } +// +// InetSocketAddress dirAddr = null; +// boolean useSSL = false; +// String serviceCredsFile = null; +// String serviceCredsPass = null; +// String trustedCAsFile = null; +// String trustedCAsPass = null; +// +// ONCRPCServiceURL dirURL = options.get("dir").urlValue; +// +// // parse security info if protocol is 'https' +// if (dirURL != null && "oncrpcs".equals(dirURL.getProtocol())) { +// useSSL = true; +// serviceCredsFile = options.get("c").stringValue; +// serviceCredsPass = options.get("cpass").stringValue; +// trustedCAsFile = options.get("t").stringValue; +// trustedCAsPass = options.get("tpass").stringValue; +// } +// +// +// dirAddr = new InetSocketAddress(dirURL.getHost(), dirURL.getPort()); +// +// boolean checkOnly = options.get("chk").switchValue; +// +// int numThreads = DEFAULT_NUM_THREADS; +// if (options.get("thrs").numValue != null) +// numThreads = options.get("thrs").numValue.intValue(); +// +// +// String volume = arguments.get(0); +// boolean isVolUUID = false; +// if (volume.startsWith("uuid:")) { +// volume = volume.substring("uuid:".length()); +// isVolUUID = true; +// } +// +// SSLOptions sslOptions = useSSL ? new SSLOptions(new FileInputStream(serviceCredsFile), +// serviceCredsPass, SSLOptions.PKCS12_CONTAINER, new FileInputStream(trustedCAsFile), +// trustedCAsPass, SSLOptions.JKS_CONTAINER, false) : null; +// +// // resolve volume MRC +// RPCNIOSocketClient rpcClient = new RPCNIOSocketClient(sslOptions, 30000, 5*60000, Client.getExceptionParsers()); +// rpcClient.start(); +// rpcClient.waitForStartup(); +// DIRClient dirClient = new DIRClient(rpcClient,dirAddr); +// TimeSync.initialize(dirClient, 100000, 50).waitForStartup(); +// +// +// RPCResponse resp = dirClient.xtreemfs_service_get_by_type(null,ServiceType.SERVICE_TYPE_VOLUME); +// ServiceSet result = resp.get(); +// resp.freeBuffers(); +// +// Service volReg = null; +// +// if (isVolUUID) { +// for (Service reg : result) { +// if (reg.getUuid().equals(volume)) +// volReg = reg; +// } +// } else { +// for (Service reg : result) { +// if (reg.getName().equals(volume)) +// volReg = reg; +// } +// } +// +// if (volReg == null) { +// System.err.println("volume '" + arguments.get(0) + "' could not be found at Directory Service '" +// + dirURL + "'"); +// System.exit(3); +// } +// volume = volReg.getName(); +// +// String mrc = volReg.getData().get("mrc"); +// if (mrc == null) { +// System.err.println("volume '" + arguments.get(0) + "' has no valid "); +// System.exit(3); +// } +// +// UUIDResolver.start(dirClient, 60 * 60, 10 * 60 * 60); +// +// ServiceUUID mrcUUID = new ServiceUUID(mrc); +// InetSocketAddress mrcAddress = mrcUUID.getAddress(); +// +// int exitCode = 1; +// try { +// +// DemoScrubber scrubber = new DemoScrubber(rpcClient, dirClient, new MRCClient(rpcClient, mrcAddress), volume, checkOnly, numThreads); +// exitCode = scrubber.scrub(); +// if (exitCode == 0) +// System.out.println("\n\nsuccessfully scrubbed volume '"+volume+"'"); +// else +// System.out.println("\n\nscrubbing volume '"+volume+"' FAILED!"); +// +// +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// try { +// RandomAccessFile f = new RandomAccessFile("rw", mrcAddress, volume+"/hello/readme.txt", rpcClient, credentials); +// byte[] buf = ("Welcome to the public XtreemFS demo server.\n\nYou are welcome to "+ +// "use this server for testing XtreemFS. Please do not upload illegal or "+ +// "copyrigthed content. For all file creates and writes we record the date, "+ +// "IP address and filename. We will use this data only in case you did so "+ +// "mething illegal. And of course to satisfy our curiosity to see where our "+ +// "file system is used :)\n\n"+ +// "All files will be deleted approx. after one hour.\n\nHave fun.").getBytes(); +// f.write(buf, 0, buf.length); +// f.close(); +// } catch (Exception ex) { +// ex.printStackTrace(); +// } +// +// System.exit(exitCode); +// +// TimeSync.close(); +// UUIDResolver.shutdown(); +// rpcClient.shutdown(); +// +// } +// +// private static void usage() { +// System.out.println("usage: xtfs_scrub [options] | uuid:"); +// System.out.println(" -dir uri directory service to use (e.g. 'oncrpc://localhost:32638')"); +// System.out.println(" If no URI is specified, URI and security settings are taken from '" +// + DEFAULT_DIR_CONFIG + "'"); +// System.out +// .println(" In case of a secured URI ('oncrpcs://...'), it is necessary to also specify SSL credentials:"); +// System.out +// .println(" -c a PKCS#12 file containing user credentials"); +// System.out +// .println(" -cpass a pass phrase to decrypt the the user credentials file"); +// System.out +// .println(" -t a PKCS#12 file containing a set of certificates from trusted CAs"); +// System.out +// .println(" -tpass a pass phrase to decrypt the trusted CAs file"); +// System.out +// .println(" -chk check only (do not update file sizes on the MRC in case of inconsistencies)"); +// System.out.println(" -thrs n number of concurrent file scrub threads (default=" + DEFAULT_NUM_THREADS + ")"); +// System.out.println(" -h show usage info"); +// } +// +//} diff --git a/java/servers/src/org/xtreemfs/sandbox/DemoScrubberFileInfo.java b/java/servers/src/org/xtreemfs/sandbox/DemoScrubberFileInfo.java new file mode 100644 index 0000000..3bc7eb7 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/DemoScrubberFileInfo.java @@ -0,0 +1,74 @@ +///* Copyright (c) 2009 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin. +// +// This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based +// Grid Operating System, see for more details. +// The XtreemOS project has been developed with the financial support of the +// European Commission's IST program under contract #FP6-033576. +// +// XtreemFS is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2 of the License, or (at your option) +// any later version. +// +// XtreemFS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with XtreemFS. If not, see . +// */ +///* +// * AUTHORS: Björn Kolbeck(ZIB) +// */ +// +// +//package org.xtreemfs.sandbox; +// +//import org.xtreemfs.common.clients.simplescrubber.*; +//import java.io.IOException; +//import org.xtreemfs.common.clients.io.RandomAccessFile; +//import org.xtreemfs.interfaces.Stat; +// +// +///** +// * +// * @author bjko +// */ +//public class DemoScrubberFileInfo implements Runnable { +// +// private final RandomAccessFile file; +// +// private final FileScrubbedListener listener; +// +// +// public DemoScrubberFileInfo(RandomAccessFile file, FileScrubbedListener listener) { +// this.file = file; +// this.listener = listener; +// +// } +// +// public void run() { +// +// boolean deleted = false; +// try { +// Stat stat = file.stat(); +// if (stat.getMtime_ns()/1000000l < System.currentTimeMillis()-60*60*1000) { +// //file is old, remove it +// file.delete(); +// deleted = true; +// } +// } catch (Exception ex) { +// ex.printStackTrace(); +// } +// listener.fileScrubbed(file,deleted); +// } +// +// +// public static interface FileScrubbedListener { +// public void fileScrubbed(RandomAccessFile file, boolean deleted); +// } +// +// +// +//} diff --git a/java/servers/src/org/xtreemfs/sandbox/ExampleLibxtreemfsWithSSL.java b/java/servers/src/org/xtreemfs/sandbox/ExampleLibxtreemfsWithSSL.java new file mode 100644 index 0000000..4355325 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/ExampleLibxtreemfsWithSSL.java @@ -0,0 +1,142 @@ +package org.xtreemfs.sandbox; + +import org.xtreemfs.common.libxtreemfs.*; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.PBRPCServiceURL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.PORTS; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Arrays; + +/** + * Minimal example which uses the libxtreemfs for Java and default SSL certificates from tests/certs/ to test + * basic functionality of running servers. + * + * The URL to an existing volume has to be provided as first parameter e.g., pbrpcs://localhost/regular + * + * You can easily start a full XtreemFS installation with SSL enabled as follows: + * + * - go to the "tests" directory below the root of the XtreemFS repository + * + * - run "./xtestenv -f -v regular" to start an SSL-enabled test setup which creates a new volume "regular" + * + * - press the Enter key to shut it down again + * + * Don't forget to set the working directory to the root of the XtreemFS repository. Otherwise, the example + * won't find the default SSL certificates which are also used by the test setup. + * + * E.g., in Eclipse set the working directory to: ${workspace_loc:xtreemfs_server}/../../ when + * "xtreemfs_server" is the name of the Eclipse project. + * + * @author mberlin + * + */ +public class ExampleLibxtreemfsWithSSL { + + /** Directory with testing SSL certificates. Path relative to the root of the repository. */ + public static final String CERT_DIR = "tests/certs/"; + + /** + * @param args + * args[0] = URL to existing volume e.g., pbrpcs://localhost/regular + * @return + * @throws Exception + */ + public static void main(String[] args) { + if (args.length < 1) { + System.out.println("usage: "); + return; + } + + Client client = null; + FileHandle fileHandle = null; + try { + // Parse command line parameter. + int lastSlashIndex = args[0].lastIndexOf('/'); + final PBRPCServiceURL url = new PBRPCServiceURL(args[0].substring(0, lastSlashIndex), + Schemes.SCHEME_PBRPC, PORTS.DIR_PBRPC_PORT_DEFAULT.getNumber()); + final String volumeName = args[0].substring(lastSlashIndex + 1); + + // Init libxtreemfs + final Options options = new Options(); + final UserCredentials userCredentials = UserCredentials.newBuilder() + .setUsername(System.getProperty("user.name")).addGroups("root").build(); + final SSLOptions sslOptions = url.getProtocol().equals(Schemes.SCHEME_PBRPC) ? null : new SSLOptions( + new FileInputStream(CERT_DIR + "Client.p12"), "passphrase", SSLOptions.PKCS12_CONTAINER, + new FileInputStream(CERT_DIR + "trusted.jks"), "passphrase", SSLOptions.JKS_CONTAINER, false, + false, null, null); + + // Alternatively, specify own certificate files for debugging: + // final SSLOptions sslOptions = new SSLOptions( + // new FileInputStream( + // "/home/mberlin/ZIB/XtreemFS/tasks archive/2013-08-05 Debug SSL issues/xtfsclient/config/xtfs-vm-certs/TestUser01.p12"), + // "test123", + // SSLOptions.PKCS12_CONTAINER, + // new FileInputStream( + // "/home/mberlin/ZIB/XtreemFS/tasks archive/2013-08-05 Debug SSL issues/xtfsclient/config/xtfs-vm-certs/trusted.jks"), + // "J9AUcbrdVkFg75kcqumz", SSLOptions.JKS_CONTAINER, false, false, null); + + Logging.start(Logging.LEVEL_WARN); + client = ClientFactory.createClient(url.getHost() + ":" + url.getPort(), userCredentials, sslOptions, + options); + client.start(); + + Volume volume = client.openVolume(volumeName, sslOptions, options); + + // Open a file. + fileHandle = volume.openFile( + userCredentials, + "/example_libxtreemfs_test_" + String.format("%03d", (int) (Math.random() * 1000)) + ".bin", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_EXCL.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0644); + + // Init chunk to be written. + byte[] data = new byte[1 << 17]; // 128 kB chunk. + Arrays.fill(data, (byte) 0xAB); + + // Write 1 MB to file. + for (int offset = 0; offset < (1 << 20); offset += data.length) { + fileHandle.write(userCredentials, data, data.length, offset); + } + + // Read 1 MB from file. + byte[] readData = new byte[data.length]; + for (int offset = 0; offset < (1 << 20); offset += data.length) { + int readCount = fileHandle.read(userCredentials, readData, data.length, offset); + if (readCount != data.length) { + throw new IOException("Read less data than expected: " + readCount + " bytes instead of: " + + data.length); + } + if (!Arrays.equals(readData, data)) { + throw new IOException("Read data differs from written chunk at offset: " + offset); + } + } + } catch (Exception e) { + System.err.println("An error occurred: " + e.getMessage() + "\n Full Stacktrace:\n" + e.getStackTrace()); + return; + } finally { + if (fileHandle != null) { + try { + fileHandle.close(); + } catch (IOException e) { + System.err.println("Failed to close() the file: " + e.getMessage() + "\n Full Stacktrace:\n" + + e.getStackTrace()); + return; + } + } + if (client != null) { + client.shutdown(); + } + System.out.println("If no errors are shown, the example was successfully executed."); + } + + return; + } + +} diff --git a/java/servers/src/org/xtreemfs/sandbox/LocalX509AuthProvider.java b/java/servers/src/org/xtreemfs/sandbox/LocalX509AuthProvider.java new file mode 100644 index 0000000..e6942fb --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/LocalX509AuthProvider.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.sandbox; + +import org.xtreemfs.common.auth.*; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.channels.ChannelIO; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; + +/** + * authentication provider for XOS certificates. + * + * @author bjko + */ +public class LocalX509AuthProvider implements AuthenticationProvider { + + private NullAuthProvider nullAuth; + + public UserCredentials getEffectiveCredentials(RPC.UserCredentials ctx, ChannelIO channel) throws AuthenticationException { + // use cached info! + assert (nullAuth != null); + if (channel.getAttachment() != null) { + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.auth, this, "using attachment..."); + final Object[] cache = (Object[]) channel.getAttachment(); + final Boolean serviceCert = (Boolean) cache[0]; + if (serviceCert) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.auth, this, "service cert..."); + return nullAuth.getEffectiveCredentials(ctx, channel); + } else { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.auth, this, "using cached creds: " + + cache[1]); + return (UserCredentials) cache[1]; + } + } + // parse cert if no cached info is present + try { + final Certificate[] certs = channel.getCerts(); + if (certs.length > 0) { + final X509Certificate cert = ((X509Certificate) certs[0]); + String fullDN = cert.getSubjectX500Principal().getName(); + String commonName = getNameElement(cert.getSubjectX500Principal().getName(), "CN"); + + if (commonName.startsWith("host/") || commonName.startsWith("xtreemfs-service/")) { + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.auth, this, + "X.509-host cert present"); + channel.setAttachment(new Object[] { new Boolean(true) }); + // use NullAuth in this case to parse JSON header + return nullAuth.getEffectiveCredentials(ctx, null); + } else { + + final String globalUID = commonName; + final String globalGID = getNameElement(cert.getSubjectX500Principal().getName(), "OU"); + List gids = new ArrayList(1); + gids.add(globalGID); + + if (Logging.isDebug()) + Logging.logMessage(Logging.LEVEL_DEBUG, Category.auth, this, + "X.509-User cert present: %s, %s", globalUID, globalGID); + + boolean isSuperUser = globalGID.contains("xtreemfs-admin"); + final UserCredentials creds = new UserCredentials(globalUID, gids, isSuperUser); + channel.setAttachment(new Object[] { new Boolean(false), creds }); + return creds; + } + } else { + throw new AuthenticationException("no X.509-certificates present"); + } + } catch (Exception ex) { + Logging.logUserError(Logging.LEVEL_ERROR, Category.auth, this, ex); + throw new AuthenticationException("invalid credentials " + ex); + } + + } + + private String getNameElement(String principal, String element) { + String[] elems = principal.split(","); + for (String elem : elems) { + String[] kv = elem.split("="); + if (kv.length != 2) + continue; + if (kv[0].equals(element)) + return kv[1]; + } + return null; + } + + public void initialize(boolean useSSL) throws RuntimeException { + if (!useSSL) { + throw new RuntimeException(this.getClass().getName() + " can only be used if SSL is enabled!"); + } + nullAuth = new NullAuthProvider(); + nullAuth.initialize(useSSL); + } +} diff --git a/java/servers/src/org/xtreemfs/sandbox/ThroughputTest.java b/java/servers/src/org/xtreemfs/sandbox/ThroughputTest.java new file mode 100644 index 0000000..ec5e67b --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/ThroughputTest.java @@ -0,0 +1,248 @@ +//package org.xtreemfs.sandbox; +// +//import java.io.FileInputStream; +//import java.io.IOException; +//import java.net.InetSocketAddress; +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.List; +//import java.util.Map; +//import java.util.Properties; +//import java.util.StringTokenizer; +// +//import org.xtreemfs.common.Capability; +//import org.xtreemfs.foundation.buffer.BufferPool; +//import org.xtreemfs.foundation.buffer.ReusableBuffer; +//import org.xtreemfs.common.clients.RPCResponse; +//import org.xtreemfs.common.clients.RPCResponseListener; +//import org.xtreemfs.common.clients.osd.OSDClient; +//import org.xtreemfs.foundation.logging.Logging; +//import org.xtreemfs.common.striping.Locations; +//import org.xtreemfs.foundation.pinky.HTTPHeaders; +// +//public class ThroughputTest { +// +// private static int responses = 0; +// +// private static Object lock = new Object(); +// +// private static OSDClient[] clients; +// +// private static Map osdThroughputs; +// +// /** +// * @param args +// */ +// public static void main(String[] args) throws Exception { +// +// if (args.length != 3) { +// System.out +// .println("usage: ThroughputTest "); +// System.exit(1); +// } +// +// boolean write = args[0].equalsIgnoreCase("write"); +// int numOSDs = Integer.parseInt(args[1]); +// +// Properties props = new Properties(); +// props.load(new FileInputStream(args[2])); +// +// final int stripeSize = Integer +// .parseInt(props.getProperty("stripeSize")); +// final int fileSize = Integer.parseInt(props.getProperty("fileSize")); +// final boolean debug = props.getProperty("debug").equalsIgnoreCase( +// "true"); +// final int numClients = Integer +// .parseInt(props.getProperty("numClients")); +// final int rwAhead = Integer.parseInt(props.getProperty("rwAhead")); +// +// final int burstSize = Integer.parseInt(props.getProperty("burstSize")); +// +// final String secret = props.getProperty("capSecret"); +// +// List osds = new ArrayList(numOSDs); +// for (int i = 0;; i++) { +// String osd = props.getProperty("osd" + i); +// if (osds.size() > 0 && osd == null) +// break; +// else if (osd == null) +// continue; +// else { +// osds.add(osd); +// if (osds.size() == numOSDs) +// break; +// } +// } +// +// Logging.start(Logging.LEVEL_ERROR); +// +// InetSocketAddress[] uris = new InetSocketAddress[osds.size()]; +// for (int i = 0; i < osds.size(); i++) { +// StringTokenizer st = new StringTokenizer(osds.get(i), ":"); +// uris[i] = new InetSocketAddress(st.nextToken(), Integer.parseInt(st +// .nextToken())); +// } +// +// final String fileId = "ABC:1"; +// final Capability cap = null;//new Capability(fileId, "w", 0, secret); +// +// +// +// long t0 = System.nanoTime(); +// +// ReusableBuffer buf = write ? BufferPool.allocate(stripeSize * 1024) +// : null; +// +// clients = new OSDClient[numClients]; +// for (int i = 0; i < numClients; i++) +// clients[i] = new OSDClient(null); +// +// osdThroughputs = new HashMap(); +// +// for (long i = 0; i < fileSize / stripeSize; i++) { +// +// final int osd = (int) (i % uris.length); +// final int client = (int) (i % clients.length); +// +// HTTPHeaders headers = new HTTPHeaders(); +// headers.addHeader(HTTPHeaders.HDR_XOBJECTNUMBER, i + ""); +// +// if (debug) +// System.out.println("sending request " + i + " to OSD " +// + uris[osd] + " ..."); +// try { +// +// // send write requests +// if (write) { +// +// ReusableBuffer viewBuf = buf.createViewBuffer(); +// +// viewBuf.put((byte) 66); +// +// final RPCResponse res = clients[client].put(uris[osd], null, +// cap, fileId, i, viewBuf); +// res.setResponseListener(new RPCResponseListener() { +// public void responseAvailable(RPCResponse response) { +// synchronized (lock) { +// +// responses++; +// +// byte[] body = response.getSpeedyRequest() +// .getResponseBody(); +// if (debug) { +// if (body != null) +// System.out.println("body: " +// + new String(body)); +// System.out.println("write complete, " +// + responses + " responses received"); +// } +// res.freeBuffers(); +// lock.notify(); +// } +// } +// }); +// } +// +// // send read requests +// else { +// +// final RPCResponse res = clients[client].get(uris[osd], null, +// cap, fileId, i); +// res.setResponseListener(new RPCResponseListener() { +// public void responseAvailable(RPCResponse response) { +// synchronized (lock) { +// +// Object[] array = osdThroughputs.get(response +// .getSpeedyRequest().getServer()); +// if (array == null) { +// array = new Object[] { new Long(0), +// new Long(0) }; +// osdThroughputs.put(response +// .getSpeedyRequest().getServer(), +// array); +// } +// try { +// array[0] = new Long(((Long) array[0]) +// .longValue() +// + response.getBody().capacity()); +// array[1] = System.nanoTime(); +// } catch (Exception e) { +// e.printStackTrace(); +// System.exit(1); +// } +// +// responses++; +// +// // byte[] body = response.getSpeedyRequest() +// // .getResponseBody(); +// +// // ReusableBuffer buf = null; +// // try { +// // buf = response.getBody(); +// // } catch (Exception e) { +// // e.printStackTrace(); +// // System.exit(1); +// // } +// // +// // if (buf.capacity() != stripeSize * 1024) { +// // System.err.println("wrong body length: " +// // + buf.capacity()); +// // System.exit(1); +// // } +// // +// // if (buf.get() != (byte) 65) { +// // System.err.println("invalid body content"); +// // System.exit(1); +// // } +// +// if (debug) +// System.out.println("read complete, " +// + responses + " responses received"); +// +// res.freeBuffers(); +// lock.notify(); +// } +// } +// }); +// } +// +// if (burstSize == 0 || i % (uris.length * burstSize) == 0) { +// synchronized (lock) { +// while (i - responses > rwAhead) +// lock.wait(); +// } +// } +// +// } catch (IOException exc) { +// exc.printStackTrace(); +// System.exit(1); +// } +// } +// +// synchronized (lock) { +// while (responses < fileSize / stripeSize) +// lock.wait(); +// } +// +// long time = System.nanoTime() - t0; +// time = time / 1000000; +// System.out.println("time elapsed for reading/writing " + fileSize +// + "kb in " + stripeSize + "kb stripes: " + time + "ms"); +// System.out +// .println(((fileSize) / (stripeSize * time / 1000)) + " ops/s"); +// System.out.println((fileSize / ((float) time / 1000)) + " kb/s"); +// System.out.println("throughput for OSDs:"); +// for (InetSocketAddress osd : osdThroughputs.keySet()) { +// Object[] array = osdThroughputs.get(osd); +// double t = ((Long) array[1] - t0) / 1000000.0f; +// long size = (Long) array[0] / 1000; +// System.out +// .println(osd + ": " + size / ((float) t / 1000) + " kb/s"); +// } +// +// for (OSDClient client : clients) +// client.shutdown(); +// +// System.out.println(BufferPool.getStatus()); +// } +//} \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/sandbox/ThroughputTest.properties b/java/servers/src/org/xtreemfs/sandbox/ThroughputTest.properties new file mode 100644 index 0000000..41d2eaf --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/ThroughputTest.properties @@ -0,0 +1,29 @@ +# file size in kb +fileSize=4194304 + +# stripe size in kb +stripeSize=1024 + +# number of clients +numClients=10 + +# minimum number of pending responses at which no more requests are sent +rwAhead=1000 + +# number of lines to send between two checks of rwAhead (0 = "send single requests") +burstSize=2 + +# debug flag +debug=true + +osd0=csr-pc24.zib.de:32640 +#osd0=172.24.103.160:32641 +#osd1=172.24.103.161:32641 +#osd2=172.24.103.162:32641 +#osd3=172.24.103.163:32641 +#osd4=172.24.103.164:32641 +#osd5=172.24.103.165:32641 +#osd6=172.24.103.166:32641 +#osd7=172.24.103.167:32641 +#osd8=172.24.103.168:32641 +#osd9=172.24.103.169:32641 \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/sandbox/compile-DirectIOReader.txt b/java/servers/src/org/xtreemfs/sandbox/compile-DirectIOReader.txt new file mode 100644 index 0000000..0e970c6 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/compile-DirectIOReader.txt @@ -0,0 +1,9 @@ +To compile the native library for DirectIOReader, make sure that $JAVA_HOME +points to a JDK 1.6. Invoke the following command: + +%> gcc -o libreaddirect.so -shared -Wl,-soname,libreaddirect.so \ + > -I$JAVA_HOME/include -I$JAVA_HOME/include/linux org_xtreemfs_sandbox_DirectIOReader.c + +The output will be a shared library named "libreaddirect.so". Make sure that the property +"java.library.path" points to the directory where this library is located when starting +the Java VM, e.g. by adding the option "-Djava.library.path=". \ No newline at end of file diff --git a/java/servers/src/org/xtreemfs/sandbox/dir_replication_test.java b/java/servers/src/org/xtreemfs/sandbox/dir_replication_test.java new file mode 100644 index 0000000..88b4443 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/dir_replication_test.java @@ -0,0 +1,713 @@ +///* Copyright (c) 2009-2010 Barcelona Supercomputing Center - Centro Nacional +// de Supercomputacion and Konrad-Zuse-Zentrum fuer Informationstechnik Berlin. +// +// This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based +// Grid Operating System, see for more details. +// The XtreemOS project has been developed with the financial support of the +// European Commission's IST program under contract #FP6-033576. +// +// XtreemFS is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2 of the License, or (at your option) +// any later version. +// +// XtreemFS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with XtreemFS. If not, see . +// */ +///* +// * AUTHORS: Felix Langner (ZIB) +// */ +//package org.xtreemfs.sandbox; +// +//import java.io.IOException; +//import java.net.InetSocketAddress; +//import java.util.HashMap; +//import java.util.LinkedList; +//import java.util.List; +//import java.util.Map; +//import java.util.Random; +//import java.util.UUID; +// +//import org.xtreemfs.common.clients.Client; +//import org.xtreemfs.dir.client.DIRClient; +//import org.xtreemfs.foundation.TimeSync; +//import org.xtreemfs.foundation.logging.Logging; +//import org.xtreemfs.foundation.oncrpc.client.RPCNIOSocketClient; +//import org.xtreemfs.foundation.oncrpc.client.RPCResponse; +//import org.xtreemfs.interfaces.AddressMapping; +//import org.xtreemfs.interfaces.AddressMappingSet; +//import org.xtreemfs.interfaces.Service; +//import org.xtreemfs.interfaces.ServiceDataMap; +//import org.xtreemfs.interfaces.ServiceSet; +//import org.xtreemfs.interfaces.ServiceType; +//import org.xtreemfs.interfaces.DIRInterface.RedirectException; +// +///** +// *

    +// * Test of the DIR master-slave replication as an feature of BabuDB, +// * without SSL. +// *

    +// * +// *

    +// * To use this test, setup some DIRs with replication enabled and +// * give their addresses to this application. +// *

    +// * +// * @since 09/21/2009 +// * @author flangner +// */ +//public class dir_replication_test { +// +// private final static Random random = new Random(); +// private static DIRClient masterClient; +// +// private final static int LOOKUP_MODE = 1; +// private final static int LOOKUP_PERCENTAGE = 50; +// private final static int INSERT_MODE = 2; +// private final static int INSERT_PERCENTAGE = 40; +// private final static int DELETE_MODE = 3; +// private final static int DELETE_PERCENTAGE = 10; +// +// private final static long CHECK_INTERVAL = 15*60*1000; +// +// private final static int MAX_HISTORY_SIZE = 10000; +// +// private static int registeredServices = 0; +// private static int registeredAddressMappings = 0; +// +// private static Map availableServices = +// new HashMap(); +// private static Map availableAddressMappings = +// new HashMap(); +// +// private static List participants = +// new LinkedList(); +// +// private static long time = 0; +// private static Map t = new HashMap(); +// private static int viewID = 1; +// private static long lastSeq = 0; +// private static long actSeq = 0; +// +// // 0 - set addressMapping +// // 1 - register service +// // 2 - remove addressMapping +// // 3 - deregister service +// // 4 - lookup mapping +// // 5 - lookup service +// private static int kind = -1; +// private static String uuid = null; +// +// /** +// * @param args +// * @throws Exception +// */ +// public static void main(String[] args) throws Exception { +// Logging.start(Logging.LEVEL_INFO); +// +// Logging.logMessage(Logging.LEVEL_INFO,null,"LONGRUNTEST OF THE DIR master-slave replication"); +// try { +// TimeSync.initializeLocal(60000, 50); +// } catch (Exception ex) { +// ex.printStackTrace(); +// System.exit(1); +// } +// +// // master connection setup +// RPCNIOSocketClient rpcClient = +// new RPCNIOSocketClient(null, 2*60*1000, 5*60*1000, Client.getExceptionParsers()); +// rpcClient.start(); +// rpcClient.waitForStartup(); +// +// // get the parameters +// if (args.length!=1) usage(); +// +// if (args[0].indexOf(",") == -1) { +// error("not enough participants to perform the test!"); +// } else { +// String[] adrs = args[0].split(","); +// InetSocketAddress[] servers = new InetSocketAddress[adrs.length]; +// for (int i=0;i +// * Checks the data on synchronous slave-DIRs. +// *

    +// */ +// private static void performConsistencyCheck() { +// for (DIRClient participant : participants) { +// performConsistencyCheck(participant); +// } +// } +// +// /** +// *

    +// * Checks the consistency of the DIR service given by its client. +// *

    +// * @param client +// */ +// private static void performConsistencyCheck(DIRClient client) { +// try { +// for (String uuid : availableAddressMappings.keySet()) { +// performAddressMappingLookup(uuid, client); +// } +// for (String uuid : availableServices.keySet()) { +// performServiceLookup(uuid, client); +// } +// Logging.logMessage(Logging.LEVEL_INFO,masterClient,"Participant '"+client.getDefaultServerAddress()+ +// "' is up-to-date and consistent."); +// } catch (Exception e) { +// Logging.logMessage(Logging.LEVEL_INFO,masterClient,"Participant '"+client.getDefaultServerAddress()+ +// "' is NOT up-to-date or inconsistent, because: " + e.getMessage()); +// } +// } +// +// /** +// * Performs an AddressMapping DIR operation. +// * @throws Exception +// */ +// private static void performAddressMappingOperation() throws Exception { +// if (registeredAddressMappings != 0) { +// switch (mode()) { +// case LOOKUP_MODE : +// performAddressMappingLookup(randomMappingKey(), masterClient); +// break; +// +// case INSERT_MODE : +// performAddressMappingInsert(false); +// break; +// +// case DELETE_MODE : +// performAddressMappingDelete(false); +// break; +// +// default : assert (false); +// } +// } else { +// performAddressMappingInsert(false); +// } +// } +// +// /** +// * Performs an Service DIR operation. +// * @throws Exception +// */ +// private static void performServiceOperation() throws Exception { +// if (registeredServices != 0) { +// switch (mode()) { +// case LOOKUP_MODE : +// performServiceLookup(randomServiceKey(), masterClient); +// break; +// +// case INSERT_MODE : +// performServiceInsert(false); +// break; +// +// case DELETE_MODE : +// performServiceDelete(false); +// break; +// +// default : assert (false); +// } +// } else { +// performServiceInsert(false); +// } +// } +// +// /** +// * Performs an AddressMapping lookup for the given UUID. +// * @param uuid +// * @param c +// * @throws Exception +// */ +// private static void performAddressMappingLookup(String uuid, DIRClient c) +// throws Exception{ +// +// RPCResponse rp = null; +// try { +// rp = c.xtreemfs_address_mappings_get(null, uuid); +// AddressMappingSet result = rp.get(); +// +// if (result.size() == 0){ +// Logging.logMessage(Logging.LEVEL_ERROR,masterClient,"AddressMappingLookup: result.size() == 0" + +// " on client: "+c.getDefaultServerAddress()); +// throw new FailureException(uuid,4); +// } +// if (result.size() > 1) throw new Exception ("UUID not unique!"); +// +// if (!equals(availableAddressMappings.get(uuid), result.get(0))) { +// Logging.logMessage(Logging.LEVEL_ERROR,masterClient,"Not the same Services! expected: "+ +// availableAddressMappings.get(uuid)+" received: "+result.get(0)); +// throw new FailureException(uuid,4); +// } +// } finally { +// if (rp!=null) rp.freeBuffers(); +// } +// } +// +// /** +// * Performs a Service lookup for the given UUID. +// * @param uuid +// * @param c +// * @throws Exception +// */ +// private static void performServiceLookup(String uuid, DIRClient c) +// throws Exception{ +// +// RPCResponse rp = null; +// try { +// rp = c.xtreemfs_service_get_by_uuid(null, uuid); +// ServiceSet result = rp.get(); +// +// if (result.size() == 0) { +// Logging.logMessage(Logging.LEVEL_INFO,masterClient,"ServiceGet: result.size() == 0" + +// " on client: "+c.getDefaultServerAddress()); +// throw new FailureException(uuid,5); +// } +// if (result.size() > 1) throw new Exception ("UUID not unique!"); +// +// if (!equals(availableServices.get(uuid), result.get(0))) { +// Logging.logMessage(Logging.LEVEL_ERROR,masterClient,"Not the same Services! expected: "+ +// availableServices.get(uuid)+" received: "+result.get(0)); +// throw new FailureException(uuid,5); +// } +// } finally { +// if (rp!=null) rp.freeBuffers(); +// } +// } +// +// /** +// * Performs an AdressMapping insert. +// * @throws Exception +// * @param retry +// */ +// private static void performAddressMappingInsert(boolean retry) throws Exception { +// AddressMappingSet load = new AddressMappingSet(); +// +// AddressMapping mapping; +// if (retry) { +// assert (availableAddressMappings.containsKey(uuid)); +// mapping = availableAddressMappings.get(uuid); +// } else { +// do { +// mapping = randomMapping(); +// kind = 0; +// uuid = mapping.getUuid(); +// } while (availableAddressMappings.containsKey(uuid)); +// } +// load.add(mapping); +// +// if (!retry) { +// if (availableAddressMappings.size() == MAX_HISTORY_SIZE) +// availableAddressMappings.remove(randomMappingKey()); +// +// availableAddressMappings.put(uuid, mapping); +// registeredAddressMappings++; +// } +// +// RPCResponse rp = null; +// try { +// rp = masterClient.xtreemfs_address_mappings_set(null, load); +// long result = rp.get(); +// if(result != 1) { +// Logging.logMessage(Logging.LEVEL_ERROR,masterClient,"AddressMappingSet: result != 1, result == "+result); +// throw new FailureException("A previous entry was modified unexpectedly.", kind); +// } +// } finally { +// if (rp != null) rp.freeBuffers(); +// } +// if (!retry) { +// t.put(mapping.getUuid(), (int) time); +// time++; +// actSeq++; +// } +// } +// +// /** +// * Performs a Service insert. +// * @throws Exception +// * @param retry +// */ +// private static void performServiceInsert(boolean retry) throws Exception{ +// Service service; +// if (retry) { +// assert (availableServices.containsKey(uuid)); +// service = availableServices.get(uuid); +// } else { +// do { +// service = randomService(); +// kind = 1; +// uuid = service.getUuid(); +// } while (availableServices.containsKey(uuid)); +// } +// if (!retry) { +// if (availableServices.size() == MAX_HISTORY_SIZE) +// availableServices.remove(randomServiceKey()); +// +// availableServices.put(uuid, service); +// registeredServices++; +// } +// +// RPCResponse rp = null; +// try { +// rp = masterClient.xtreemfs_service_register(null, service); +// long result = rp.get(); +// if(result != 1) { +// Logging.logMessage(Logging.LEVEL_ERROR,masterClient,"ServiceRegister: result != 1, result == "+result); +// throw new FailureException("A previous entry was modified unexpectedly.("+result+")", kind); +// } +// } finally { +// if (rp != null) rp.freeBuffers(); +// } +// if (!retry) { +// t.put(service.getUuid(), (int) time); +// time++; +// actSeq++; +// } +// } +// +// /** +// * Performs an AddressMapping delete. +// * @throws Exception +// * @param retry +// */ +// private static void performAddressMappingDelete(boolean retry) throws Exception{ +// if (!retry) { +// uuid = new LinkedList(availableAddressMappings.keySet()) +// .get(random.nextInt(availableAddressMappings.size())); +// +// kind = 2; +// } +// +// if (!retry) { +// availableAddressMappings.remove(uuid); +// registeredAddressMappings--; +// } +// +// RPCResponse rp = null; +// try { +// rp = masterClient.xtreemfs_address_mappings_remove(null, uuid); +// rp.get(); +// } finally { +// if (rp != null) rp.freeBuffers(); +// } +// if (!retry) { +// time++; +// actSeq++; +// } +// } +// +// /** +// * Performs a Service delete. +// * @throws Exception +// * @param retry +// */ +// private static void performServiceDelete(boolean retry) throws Exception{ +// if (!retry) { +// uuid = new LinkedList(availableServices.keySet()) +// .get(random.nextInt(availableServices.size())); +// +// kind = 3; +// } +// +// if (!retry) { +// availableServices.remove(uuid); +// registeredServices--; +// } +// +// RPCResponse rp = null; +// try { +// rp = masterClient.xtreemfs_service_deregister(null, uuid); +// rp.get(); +// } finally { +// if (rp != null) rp.freeBuffers(); +// } +// if (!retry) { +// actSeq++; +// time++; +// } +// } +// +// /** +// * @return a random mode for the next step. +// */ +// private static int mode() { +// int per = random.nextInt(100); +// if (per(availableAddressMappings.keySet()).get( +// random.nextInt(availableAddressMappings.size())); +// } +// +// /** +// * @return a random generated service. +// */ +// private static Service randomService() { +// ServiceType[] types = ServiceType.values(); +// ServiceType type = types[random.nextInt(types.length)]; +// UUID uuid = UUID.randomUUID(); +// long version = 0; +// String name = uuid.toString(); +// long time = System.currentTimeMillis(); +// ServiceDataMap data = new ServiceDataMap(); +// return new Service(type, uuid.toString(), version, name, time, data); +// } +// +// /** +// * @return UUID of a random key identifying a service. +// */ +// private static String randomServiceKey() { +// return new LinkedList(availableServices.keySet()).get(random. +// nextInt(availableServices.size())); +// } +// +// /** +// * +// * @param org +// * @param onSrv +// * @return true, if the original mapping equals the mapping on the DIR for +// * the given values. +// */ +// private static boolean equals(AddressMapping org, AddressMapping onSrv) { +// return (org.getAddress().equals(onSrv.getAddress()) && +// org.getMatch_network().equals(onSrv.getMatch_network()) && +// org.getPort() == onSrv.getPort() && +// org.getProtocol().equals(onSrv.getProtocol()) && +// org.getTtl_s() == onSrv.getTtl_s() && +// org.getUri().equals(onSrv.getUri()) && +// org.getVersion()+1 == onSrv.getVersion()); +// } +// +// /** +// * +// * @param org +// * @param onSrv +// * @return true, if the original service equals the service on the DIR for +// * the given values. +// */ +// private static boolean equals(Service org, Service onSrv) { +// return (org.getName().equals(onSrv.getName()) && +// org.getType().equals(onSrv.getType()) && +// org.getData().equals(onSrv.getData()) && +// org.getVersion()+1 == onSrv.getVersion()); +// } +// +// /** +// * Can exit with an error, if the given string was illegal. +// * +// * @param adr +// * @return the parsed {@link InetSocketAddress}. +// */ +// private static InetSocketAddress parseAddress (String adr){ +// String[] comp = adr.split(":"); +// if (comp.length!=2){ +// error("Address '"+adr+"' is illegal!"); +// return null; +// } +// +// try { +// int port = Integer.parseInt(comp[1]); +// return new InetSocketAddress(comp[0],port); +// } catch (NumberFormatException e) { +// error("Address '"+adr+"' is illegal! Because: "+comp[1]+" is not a number."); +// return null; +// } +// } +// +// private static String getTimeStamp(long utime) { +// long time = utime/1000; +// return "["+(time - time % 60 - ((time-time%60)/60)%60)/3600 + ":" + +// ((time - time % 60)/60)%60 + ":" + +// time % 60 + "]"; +// } +// +// /** +// * Prints the error message and delegates to usage(). +// * @param message +// */ +// private static void error(String message) { +// Logging.logMessage(Logging.LEVEL_ERROR,masterClient,message); +// usage(); +// } +// +// /** +// * Prints out usage information and terminates the application. +// */ +// public static void usage(){ +// Logging.logMessage(Logging.LEVEL_INFO,masterClient, +// "dir_replication_test ,[,]"); +// Logging.logMessage(Logging.LEVEL_INFO,masterClient, +// " "+" participants of the replication separated by ','"); +// System.exit(1); +// } +// +// private static class FailureException extends Exception{ +// private static final long serialVersionUID = -5567189559458859258L; +// public final int kind; +// +// public FailureException(String message,int kind) { +// super(message); +// this.kind = kind; +// } +// } +//} diff --git a/java/servers/src/org/xtreemfs/sandbox/mrc_replication_test.java b/java/servers/src/org/xtreemfs/sandbox/mrc_replication_test.java new file mode 100644 index 0000000..f95bd0c --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/mrc_replication_test.java @@ -0,0 +1,530 @@ +///* Copyright (c) 2009 Barcelona Supercomputing Center - Centro Nacional +// de Supercomputacion and Konrad-Zuse-Zentrum fuer Informationstechnik Berlin. +// +// This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based +// Grid Operating System, see for more details. +// The XtreemOS project has been developed with the financial support of the +// European Commission's IST program under contract #FP6-033576. +// +// XtreemFS is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2 of the License, or (at your option) +// any later version. +// +// XtreemFS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with XtreemFS. If not, see . +// */ +///* +// * AUTHORS: Felix Langner (ZIB) +// */ +//package org.xtreemfs.sandbox; +// +//import java.net.InetSocketAddress; +//import java.util.HashMap; +//import java.util.LinkedList; +//import java.util.List; +//import java.util.Map; +//import java.util.Random; +//import java.util.UUID; +// +//import org.xtreemfs.common.clients.Client; +//import org.xtreemfs.dir.ErrorCodes; +//import org.xtreemfs.foundation.TimeSync; +//import org.xtreemfs.foundation.logging.Logging; +//import org.xtreemfs.foundation.oncrpc.client.RPCNIOSocketClient; +//import org.xtreemfs.foundation.oncrpc.client.RPCResponse; +//import org.xtreemfs.interfaces.AddressMapping; +//import org.xtreemfs.interfaces.AddressMappingSet; +//import org.xtreemfs.interfaces.Service; +//import org.xtreemfs.interfaces.ServiceDataMap; +//import org.xtreemfs.interfaces.ServiceSet; +//import org.xtreemfs.interfaces.ServiceType; +//import org.xtreemfs.interfaces.StringSet; +//import org.xtreemfs.interfaces.UserCredentials; +//import org.xtreemfs.interfaces.DIRInterface.DIRException; +//import org.xtreemfs.mrc.client.MRCClient; +// +///** +// *

    +// * Test of the MRC master-slave replication as an feature of BabuDB, +// * without SSL. +// *

    +// * +// *

    +// * To use this test, setup some MRCs with replication enabled and +// * give their addresses to this application. Define which of them should +// * be the master. +// *

    +// * +// * @since 10/14/2009 +// * @author flangner +// */ +//public class mrc_replication_test { +// +// private final static Random random = new Random(); +// private static MRCClient masterClient; +// +// private final static int LOOKUP_MODE = 1; +// private final static int LOOKUP_PERCENTAGE = 50; +// private final static int INSERT_MODE = 2; +// private final static int INSERT_PERCENTAGE = 40; +// private final static int DELETE_MODE = 3; +// private final static int DELETE_PERCENTAGE = 10; +// +// private final static long CHECK_INTERVAL = 15*60*1000; +// +// private final static int MAX_HISTORY_SIZE = 10000; +// +// private static int registeredServices = 0; +// private static int registeredFiles = 0; +// +// private static Map availableServices = +// new HashMap(); +// private static Map availableAddressMappings = +// new HashMap(); +// +// private static List participants = +// new LinkedList(); +// +// /** +// * @param args +// * @throws Exception +// */ +// public static void main(String[] args) throws Exception { +// System.out.println("LONGRUNTEST OF THE DIR master-slave replication"); +// +// Logging.start(Logging.LEVEL_ERROR); +// try { +// TimeSync.initialize(null, 60000, 50); +// } catch (Exception ex) { +// ex.printStackTrace(); +// System.exit(1); +// } +// +// // administrator details +// StringSet gids = new StringSet(); +// gids.add(""); +// UserCredentials creds = new UserCredentials("", gids, ""); +// +// // master connection setup +// RPCNIOSocketClient rpcClient = +// new RPCNIOSocketClient(null, (int) CHECK_INTERVAL, (int) (CHECK_INTERVAL+20000), Client.getExceptionParsers()); +// rpcClient.start(); +// +// // get the parameters +// if (args.length!=2) usage(); +// masterClient = new MRCClient(rpcClient,parseAddress(args[0])); +// +// if (args[1].indexOf(",") == -1) { +// participants.add(new MRCClient(rpcClient, parseAddress(args[1]))); +// } else { +// for (String adr : args[1].split(",")) { +// participants.add(new MRCClient(rpcClient, parseAddress(adr))); +// } +// } +// +// assert(LOOKUP_PERCENTAGE+DELETE_PERCENTAGE+INSERT_PERCENTAGE == 100); +// +// // run the test +// System.out.println("Setting up the configuration ..."); +// +// RPCResponse rp = null; +// try { +// // TODO rebuild test +// //rp = masterClient.replication_toMaster(null, creds); +// rp.get(); +// } catch (DIRException e) { +// if (e.getError_code() == ErrorCodes.NOT_ENOUGH_PARTICIPANTS) +// error("There where not enough participants available to" + +// " perform this operation."); +// else if (e.getError_code() == ErrorCodes.AUTH_FAILED) +// error("You are not authorized to perform this operation."); +// else throw e; +// } finally { +// if (rp!=null) rp.freeBuffers(); +// } +// +// long start = System.currentTimeMillis(); +// long operationCount = 0; +// System.out.println("Done! The test begins:"); +// +// while (true) { +// // perform a consistency check +// long now = System.currentTimeMillis(); +// if ((start+CHECK_INTERVAL) < now) { +// System.out.println("Throughput: "+((double) (operationCount/ +// (CHECK_INTERVAL/1000)))+" operations/second"); +// operationCount = 0; +// +// performConsistencyCheck(); +// start = System.currentTimeMillis(); +// } else { +// if (random.nextBoolean()) +// performFileOperation(); +// else +// performServiceOperation(); +// operationCount++; +// } +// } +// } +// +// /** +// *

    +// * Checks the data on synchronous slave-DIRs. +// *

    +// * @throws Exception +// */ +// private static void performConsistencyCheck() throws Exception { +// performConsistencyCheck(masterClient); +// for (MRCClient participant : participants) { +// performConsistencyCheck(participant); +// } +// } +// +// /** +// *

    +// * Checks the consistency of the DIR service given by its client. +// *

    +// * @param client +// */ +// private static void performConsistencyCheck(MRCClient client) { +// try { +// for (String uuid : availableAddressMappings.keySet()) { +// performFileLookup(uuid, client); +// } +// for (String uuid : availableServices.keySet()) { +// performServiceLookup(uuid, client); +// } +// System.out.println("Participant '"+client.getDefaultServerAddress()+ +// "' is up-to-date and consistent."); +// } catch (Exception e) { +// System.out.println("Participant '"+client.getDefaultServerAddress()+ +// "' is NOT up-to-date or inconsistent, because: " + +// e.getMessage()); +// } +// } +// +// /** +// * Performs an file operation on the MRC. +// * @throws Exception +// */ +// private static void performFileOperation() throws Exception { +// if (registeredFiles != 0) { +// switch (mode()) { +// case LOOKUP_MODE : +// performFileLookup(randomMappingKey(), masterClient); +// break; +// +// case INSERT_MODE : +// performFileInsert(); +// break; +// +// case DELETE_MODE : +// performFileDelete(); +// break; +// +// default : assert (false); +// } +// } else { +// performFileInsert(); +// } +// } +// +// /** +// * Performs an Service DIR operation. +// * @throws Exception +// */ +// private static void performServiceOperation() throws Exception { +// if (registeredServices != 0) { +// switch (mode()) { +// case LOOKUP_MODE : +// performServiceLookup(randomServiceKey(), masterClient); +// break; +// +// case INSERT_MODE : +// performServiceInsert(); +// break; +// +// case DELETE_MODE : +// performServiceDelete(); +// break; +// +// default : assert (false); +// } +// } else { +// performServiceInsert(); +// } +// } +// +// /** +// * Performs an AddressMapping lookup for the given UUID. +// * @param uuid +// * @param c +// * @throws Exception +// */ +// private static void performFileLookup(String uuid, MRCClient c) +// throws Exception{ +// +// RPCResponse rp = null; +// try { +// /* TODO +// c.open(null, credentials, path, flags, mode, w32attrs, coordinates); +// rp = c.xtreemfs_address_mappings_get(null, uuid); */ +// AddressMappingSet result = rp.get(); +// +// if (result.size() != 1) throw new Exception ((result.size() == 0) ? +// "Mapping lost!" : "UUID not unique!"); +// +// if (!equals(availableAddressMappings.get(uuid), result.get(0))) +// throw new Exception("Unequal address mapping detected!"); +// } finally { +// if (rp!=null) rp.freeBuffers(); +// } +// } +// +// /** +// * Performs a Service lookup for the given UUID. +// * @param uuid +// * @param c +// * @throws Exception +// */ +// private static void performServiceLookup(String uuid, MRCClient c) +// throws Exception{ +// +// RPCResponse rp = null; +// try { +// // TODO rp = c.xtreemfs_service_get_by_uuid(null, uuid); +// ServiceSet result = rp.get(); +// +// if (result.size() != 1) throw new Exception ((result.size() == 0) ? +// "Service lost!" : "UUID not unique!"); +// +// if (!equals(availableServices.get(uuid), result.get(0))) +// throw new Exception("Unequal service detected!"); +// } finally { +// if (rp!=null) rp.freeBuffers(); +// } +// } +// +// /** +// * Performs an AdressMapping insert. +// * @throws Exception +// */ +// private static void performFileInsert() throws Exception{ +// +// if (availableAddressMappings.size() == MAX_HISTORY_SIZE) +// availableAddressMappings.remove(randomMappingKey()); +// +// AddressMappingSet load = new AddressMappingSet(); +// AddressMapping mapping = randomMapping(); +// availableAddressMappings.put(mapping.getUuid(), mapping); +// load.add(mapping); +// RPCResponse rp = null; +// try { +// // TODO rp = masterClient.xtreemfs_address_mappings_set(null, load); +// long result = rp.get(); +// assert(result == 1) : "A previous entry was modified unexpectedly."; +// } finally { +// if (rp != null) rp.freeBuffers(); +// } +// registeredFiles++; +// } +// +// /** +// * Performs a Service insert. +// * @throws Exception +// */ +// private static void performServiceInsert() throws Exception{ +// +// if (availableServices.size() == MAX_HISTORY_SIZE) +// availableServices.remove(randomServiceKey()); +// +// Service service = randomService(); +// availableServices.put(service.getUuid(), service); +// RPCResponse rp = null; +// try { +// // TODO rp = masterClient.xtreemfs_service_register(null, service); +// long result = rp.get(); +// assert(result == 1) : "A previous entry was modified unexpectedly."; +// } finally { +// if (rp != null) rp.freeBuffers(); +// } +// registeredServices++; +// } +// +// /** +// * Performs an AddressMapping delete. +// * @throws Exception +// */ +// private static void performFileDelete() throws Exception{ +// String uuid = new LinkedList(availableAddressMappings.keySet()) +// .get(random.nextInt(availableAddressMappings.size())); +// RPCResponse rp = null; +// try { +// //TODO rp = masterClient.xtreemfs_address_mappings_remove(null, uuid); +// rp.get(); +// } finally { +// if (rp != null) rp.freeBuffers(); +// } +// availableAddressMappings.remove(uuid); +// registeredFiles--; +// } +// +// /** +// * Performs a Service delete. +// * @throws Exception +// */ +// private static void performServiceDelete() throws Exception{ +// String uuid = new LinkedList(availableServices.keySet()) +// .get(random.nextInt(availableServices.size())); +// RPCResponse rp = null; +// try { +// // TODO rp = masterClient.xtreemfs_service_deregister(null, uuid); +// rp.get(); +// } finally { +// if (rp != null) rp.freeBuffers(); +// } +// availableServices.remove(uuid); +// registeredServices--; +// } +// +// /** +// * @return a random mode for the next step. +// */ +// private static int mode() { +// int per = random.nextInt(100); +// if (per(availableAddressMappings.keySet()).get( +// random.nextInt(availableAddressMappings.size())); +// } +// +// /** +// * @return a random generated service. +// */ +// private static Service randomService() { +// ServiceType[] types = ServiceType.values(); +// ServiceType type = types[random.nextInt(types.length)]; +// UUID uuid = UUID.randomUUID(); +// long version = 0; +// String name = uuid.toString(); +// long time = System.currentTimeMillis(); +// ServiceDataMap data = new ServiceDataMap(); +// return new Service(type, uuid.toString(), version, name, time, data); +// } +// +// /** +// * @return UUID of a random key identifying a service. +// */ +// private static String randomServiceKey() { +// return new LinkedList(availableServices.keySet()).get(random. +// nextInt(availableServices.size())); +// } +// +// /** +// * +// * @param org +// * @param onSrv +// * @return true, if the original mapping equals the mapping on the DIR for +// * the given values. +// */ +// private static boolean equals(AddressMapping org, AddressMapping onSrv) { +// return (org.getAddress().equals(onSrv.getAddress()) && +// org.getMatch_network().equals(onSrv.getMatch_network()) && +// org.getPort() == onSrv.getPort() && +// org.getProtocol().equals(onSrv.getProtocol()) && +// org.getTtl_s() == onSrv.getTtl_s() && +// org.getUri().equals(onSrv.getUri()) && +// org.getVersion()+1 == onSrv.getVersion()); +// } +// +// /** +// * +// * @param org +// * @param onSrv +// * @return true, if the original service equals the service on the DIR for +// * the given values. +// */ +// private static boolean equals(Service org, Service onSrv) { +// return (org.getName().equals(onSrv.getName()) && +// org.getType().equals(onSrv.getType()) && +// org.getData().equals(onSrv.getData()) && +// org.getVersion()+1 == onSrv.getVersion()); +// } +// +// /** +// * Can exit with an error, if the given string was illegal. +// * +// * @param adr +// * @return the parsed {@link InetSocketAddress}. +// */ +// private static InetSocketAddress parseAddress (String adr){ +// String[] comp = adr.split(":"); +// if (comp.length!=2){ +// error("Address '"+adr+"' is illegal!"); +// return null; +// } +// +// try { +// int port = Integer.parseInt(comp[1]); +// return new InetSocketAddress(comp[0],port); +// } catch (NumberFormatException e) { +// error("Address '"+adr+"' is illegal! Because: "+comp[1]+" is not a number."); +// return null; +// } +// } +// +// /** +// * Prints the error message and delegates to usage(). +// * @param message +// */ +// private static void error(String message) { +// System.err.println(message); +// usage(); +// } +// +// /** +// * Prints out usage information and terminates the application. +// */ +// public static void usage(){ +// System.out.println("dir_replication_test [,]"); +// System.out.println(" "+" address of the DIR that has to be declared to master"); +// System.out.println(" "+" participants of the replication separated by ','"); +// System.exit(1); +// } +//} diff --git a/java/servers/src/org/xtreemfs/sandbox/sliceTest.java b/java/servers/src/org/xtreemfs/sandbox/sliceTest.java new file mode 100644 index 0000000..dbe821e --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/sliceTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.sandbox; + +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; + +/** + * + * @author bjko + */ +public class sliceTest { + + + public static void main(String[] args) { + try { + + /*ReusableBuffer buf = BufferPool.allocate(128); + + long nanoStart = System.nanoTime(); + + for (int i = 0; i < 10000; i++) { + ReusableBuffer vbuf = buf.createViewBuffer(); + vbuf.range(28, 100); + + /*ReusableBuffer rbuf = BufferPool.allocate(100); + buf.position(28); + rbuf.put(buf); + BufferPool.free(rbuf);* / + } + + long nanoEnd = System.nanoTime(); + + double dur = nanoEnd-nanoStart; + + System.out.println("took "+dur/1e6+"ms");*/ + + } catch (Exception ex) { + ex.printStackTrace(); + } + } +} diff --git a/java/servers/src/org/xtreemfs/sandbox/tests/CreateConfig.java b/java/servers/src/org/xtreemfs/sandbox/tests/CreateConfig.java new file mode 100644 index 0000000..01b6400 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/tests/CreateConfig.java @@ -0,0 +1,60 @@ +//package org.xtreemfs.sandbox.tests; +// +//import java.io.FileOutputStream; +//import java.util.Properties; +// +//public class CreateConfig { +// +// public static void main(String[] args) { +// +// try { +// +// int numCfgFiles = Integer.parseInt(args[0]); +// +// Properties config = new Properties(); +// if (!args[1].equals("null")) +// config.setProperty(OSDTestClient.Configuration.PROP_STRIPESIZE, +// args[1]); +// if (!args[2].equals("null")) +// config.setProperty(OSDTestClient.Configuration.PROP_NUM_REQUESTS, +// args[2]); +// if (!args[3].equals("null")) +// config.setProperty(OSDTestClient.Configuration.PROP_NUM_OBJECTS, +// args[3]); +// if (!args[4].equals("null")) +// config.setProperty(OSDTestClient.Configuration.PROP_POLICY, +// args[4]); +// if (!args[5].equals("null")) +// config.setProperty(OSDTestClient.Configuration.PROP_FILE_ID, +// args[5]); +// if (!args[6].equals("null")) +// config.setProperty(OSDTestClient.Configuration.PROP_OPERATION, +// args[6]); +// +// for (int i = 0; i < numCfgFiles; i++) +// config.setProperty(OSDTestClient.Configuration.PROP_OSD + (i + 1), +// "opt" + ((i + 1) < 10 ? ("0" + (i + 1)) : (i + 1)) +// + ":32640"); +// +// for (int i = 0; i < numCfgFiles; i++) { +// config.setProperty(OSDTestClient.Configuration.PROP_TARGET_OSD, +// (i + 1) + ""); +// if (!args[7].equals("null")) { +// long delay = Long.parseLong(args[7]) - i * 1000; +// config.setProperty( +// OSDTestClient.Configuration.PROP_INIT_DELAY, (delay < 0 ? 0 +// : delay) + ""); +// } +// +// config.store(new FileOutputStream("/home/stender/config" +// + ((i + 1) < 10 ? ("0" + (i + 1)) : (i + 1)) +// + ".properties"), ""); +// } +// +// } catch (Exception ex) { +// ex.printStackTrace(); +// System.exit(1); +// } +// +// } +//} diff --git a/java/servers/src/org/xtreemfs/sandbox/tests/FcntlLockTest.java b/java/servers/src/org/xtreemfs/sandbox/tests/FcntlLockTest.java new file mode 100644 index 0000000..fedbaf7 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/tests/FcntlLockTest.java @@ -0,0 +1,14 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.xtreemfs.sandbox.tests; + +/** + * + * @author bjko + */ +public class FcntlLockTest { + +} diff --git a/java/servers/src/org/xtreemfs/sandbox/tests/JavaClientTest.java b/java/servers/src/org/xtreemfs/sandbox/tests/JavaClientTest.java new file mode 100644 index 0000000..94bfc04 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/tests/JavaClientTest.java @@ -0,0 +1,99 @@ +package org.xtreemfs.sandbox.tests; + +import java.net.InetSocketAddress; + +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.clients.File; +import org.xtreemfs.common.clients.RandomAccessFile; +import org.xtreemfs.common.clients.Volume; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; + +public class JavaClientTest { + + private static final byte[] buf = new byte[131072]; + + static { + for(int i = 0; i < buf.length; i++) + buf[i] = -1; + } + + private static final int numThreads = 40; + + private static final int numFiles = 3000; + + private static final int numAppends = 3; + + private Client c; + + private Volume v; + + public void init() throws Exception { + + UserCredentials uc = UserCredentials.newBuilder().setUsername("stender").addGroups("users").build(); + + c = new Client(new InetSocketAddress[] { new InetSocketAddress(32638) }, 60000, 120000, null); + c.start(); + + v = c.getVolume("test", uc); + } + + public void run() throws Exception { + + Thread[] threads = new Thread[numThreads]; + for (int i = 0; i < threads.length; i++) + threads[i] = getWriter(i); + + for (Thread th : threads) + th.start(); + + for (Thread th : threads) + th.join(); + + } + + public void stop() { + c.stop(); + } + + private Thread getWriter(final int num) { + + return new Thread() { + + public void run() { + + try { + + File dir = v.getFile(num + ""); + if (!dir.exists()) + dir.mkdir(0777); + + for (int i = 0; i < numFiles; i++) { + File file = v.getFile(num + "/" + i + ".txt"); + + RandomAccessFile raf = file.open("rw", 0777); + for (int j = 0; j < numAppends; j++) + raf.write(buf, 0, buf.length); + raf.close(); + } + + } catch (Exception exc) { + exc.printStackTrace(); + } + + } + + }; + } + + public static void main(String[] args) throws Exception { + + Logging.start(Logging.LEVEL_WARN); + + JavaClientTest t = new JavaClientTest(); + t.init(); + t.run(); + t.stop(); + } + +} diff --git a/java/servers/src/org/xtreemfs/sandbox/tests/MRCStressTest.java b/java/servers/src/org/xtreemfs/sandbox/tests/MRCStressTest.java new file mode 100644 index 0000000..48cd827 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/tests/MRCStressTest.java @@ -0,0 +1,115 @@ +package org.xtreemfs.sandbox.tests; + +import java.io.File; +import java.io.IOException; + +public class MRCStressTest { + + private static int fc = 0; + + private static int dc = 0; + + private static final Object fcLock = new Object(); + + private static final Object dcLock = new Object(); + + public static void main(String[] args) throws Exception { + + final String rootDir = "/tmp/xtreemfs"; + final int numberOfThreads = 30; + final int depth = 4; + final int minSpread = 2; + final int maxSpread = 5; + final int minFilesPerDir = 0; + final int maxFilesPerDir = 10; + final int minNameLength = 1; + final int maxNameLength = 32; + + long startTime = System.currentTimeMillis(); + + Thread[] threads = new Thread[numberOfThreads]; + for (int i = 0; i < numberOfThreads; i++) + threads[i] = new Thread() { + public void run() { + try { + createRandomTree(rootDir, depth, minSpread, maxSpread, + minFilesPerDir, maxFilesPerDir, minNameLength, + maxNameLength); + } catch (IOException e) { + e.printStackTrace(); + } + } + }; + + for (Thread th : threads) + th.start(); + + for (Thread th : threads) + th.join(); + + long time = System.currentTimeMillis() - startTime; + System.out.println("created " + fc + " files and " + dc + + " directories in " + time + " ms"); + } + + public static void createRandomTree(String rootDir, int depth, + int minSpread, int maxSpread, int minFilesPerNode, int maxFilesPerNode, + int minNameLength, int maxNameLength) throws IOException { + + int spread = randomNumber(minSpread, maxSpread); + for (int i = 0; i < spread; i++) { + + // create the node + String nestedDir = rootDir + "/" + + randomFileName(minNameLength, maxNameLength); + if (new File(nestedDir).mkdir()) + synchronized (dcLock) { + dc++; + } + else + System.err.println("could not create directory " + nestedDir); + + // create nested files + int fileCount = randomNumber(minFilesPerNode, maxFilesPerNode); + for (int j = 0; j < fileCount; j++) { + String fileName = nestedDir + "/" + + randomFileName(minNameLength, maxNameLength); + + if (new File(fileName).createNewFile()) + synchronized (fcLock) { + fc++; + } + else + System.err.println("could not create file " + nestedDir); + + } + + // create subtree + if (depth > 1) + createRandomTree(nestedDir, depth - 1, minSpread, maxSpread, + minFilesPerNode, maxFilesPerNode, minNameLength, + maxNameLength); + } + } + + private static int randomNumber(int lowerBound, int upperBound) { + return (int) (Math.random() * (upperBound - lowerBound + 1) + lowerBound); + } + + private static String randomFileName(int minLength, int maxLength) { + + final char[] allowedChars = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', + 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z' }; + + int length = randomNumber(minLength, maxLength); + char[] chars = new char[length]; + for (int i = 0; i < chars.length; i++) + chars[i] = allowedChars[(int) (Math.random() * allowedChars.length)]; + + return new String(chars); + } +} diff --git a/java/servers/src/org/xtreemfs/sandbox/tests/OSDTestClient.java b/java/servers/src/org/xtreemfs/sandbox/tests/OSDTestClient.java new file mode 100644 index 0000000..b07cdaa --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/tests/OSDTestClient.java @@ -0,0 +1,466 @@ +//package org.xtreemfs.sandbox.tests; +// +//import java.io.BufferedReader; +//import java.io.FileInputStream; +//import java.io.IOException; +//import java.io.InputStreamReader; +//import java.net.InetSocketAddress; +//import java.util.ArrayList; +//import java.util.List; +//import java.util.Properties; +// +//import org.xtreemfs.common.Capability; +//import org.xtreemfs.foundation.buffer.BufferPool; +//import org.xtreemfs.foundation.buffer.ReusableBuffer; +//import org.xtreemfs.common.clients.HttpErrorException; +//import org.xtreemfs.common.clients.RPCResponse; +//import org.xtreemfs.common.clients.RPCResponseListener; +//import org.xtreemfs.common.clients.osd.OSDClient; +//import org.xtreemfs.foundation.logging.Logging; +//import org.xtreemfs.common.striping.Location; +//import org.xtreemfs.common.striping.Locations; +//import org.xtreemfs.common.striping.RAID0; +//import org.xtreemfs.common.striping.StripingPolicy; +//import org.xtreemfs.common.uuids.ServiceUUID; +//import org.xtreemfs.foundation.pinky.HTTPHeaders; +// +//public class OSDTestClient { +// +// class ThroughputMonitor extends Thread { +// +// private ResponseCollector rc; +// +// private boolean shutdown; +// +// ThroughputMonitor(ResponseCollector rc) { +// this.rc = rc; +// } +// +// public void run() { +// +// long t = System.currentTimeMillis(); +// long resp = rc.getNumberOfResponses(); +// +// System.out.println("avrg. # ops/s:"); +// while (!shutdown) { +// try { +// Thread.sleep(1000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// +// long oldResp = resp; +// long oldT = t; +// resp = rc.getNumberOfResponses(); +// t = System.currentTimeMillis(); +// +// double rate = (double) (resp - oldResp) * 1000 / (t - oldT); +// +// System.out.println(rate + ";" + resp + ";" + rc.getFailures() +// + ";" + rc.getRedirects()); +// +// if (rc.isDone()) { +// shutdown = true; +// System.out.println("failure rate: " + rc.getFailureRate() +// + " (" + rc.getFailures() + " failures)"); +// System.out.println("redirects: " + rc.getRedirects()); +// System.out.println("total time: " + rc.getTotalTime()); +// } +// } +// } +// } +// +// class ResponseCollector implements RPCResponseListener { +// +// private int responded; +// +// private int failed; +// +// private int redirected; +// +// private long startTime; +// +// private long endTime; +// +// private Configuration config; +// +// public ResponseCollector(Configuration config) { +// this.responded = 0; +// this.failed = 0; +// this.redirected = 0; +// this.config = config; +// } +// +// public void responseAvailable(RPCResponse response) { +// +// if (startTime == 0) +// startTime = System.currentTimeMillis(); +// +// try { +// +// try { +// +// // check if an exception has occurred +// response.waitForResponse(); +// +// Object[] context = (Object[]) response.getAttachment(); +// // assert body size for read requests +// assert (context.length != 4 || response.getBody() != null +// && response.getBody().capacity() == config.stripeSize +// * KB); +// +// } catch (HttpErrorException exc) { +// +// // handle redirect +// if (exc.getStatusCode() >= 300 && exc.getStatusCode() < 400) { +// String target = response.getSpeedyRequest().responseHeaders +// .getHeader(HTTPHeaders.HDR_LOCATION); +// assert (target != null); +// Logging.logMessage(Logging.LEVEL_INFO, this, +// "redirect to " + target); +// +// // get the request context +// Object[] context = (Object[]) response.getAttachment(); +// Locations loc = (Locations) context[0]; +// Capability cap = (Capability) context[1]; +// int obj = (Integer) context[2]; +// String fileId = (String) context[3]; +// ReusableBuffer data = null; +// if (context.length == 5) +// data = (ReusableBuffer) context[4]; +// +// int ind = target.lastIndexOf(':'); +// InetSocketAddress osd = new InetSocketAddress(target +// .substring("http://".length(), ind), Integer +// .parseInt(target.substring(ind + 1))); +// +// // redirect request +// RPCResponse newRes = data == null ? client.get(osd, +// loc, cap, fileId, obj) : client.put(osd, loc, cap, +// fileId, obj, data.createViewBuffer()); +// newRes.setAttachment(context); +// newRes.setResponseListener(this); +// +// redirected++; +// return; +// } +// +// failed++; +// exc.printStackTrace(); +// +// } catch (IOException exc) { +// exc.printStackTrace(); +// failed++; +// } finally { +// response.freeBuffers(); +// } +// +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// responded++; +// if (responded >= config.numRequests) +// endTime = System.currentTimeMillis(); +// } +// +// public boolean isDone() { +// return responded == config.numRequests; +// } +// +// public int getNumberOfResponses() { +// return responded; +// } +// +// public double getFailureRate() { +// return (double) failed / responded; +// } +// +// public int getFailures() { +// return failed; +// } +// +// public int getRedirects() { +// return redirected; +// } +// +// public long getTotalTime() { +// return endTime - startTime; +// } +// +// } +// +// class Configuration { +// +// public static final String PROP_OSD = "osd"; +// +// public static final String PROP_STRIPESIZE = "stripeSize"; +// +// public static final String PROP_NUM_REQUESTS = "numRequests"; +// +// public static final String PROP_NUM_OBJECTS = "numObjects"; +// +// public static final String PROP_FIRST_OBJECT = "firstObject"; +// +// public static final String PROP_STEP_SIZE = "stepSize"; +// +// public static final String PROP_POLICY = "policy"; +// +// public static final String PROP_FILE_ID = "fileId"; +// +// public static final String PROP_TARGET_OSD = "targetOSD"; +// +// public static final String PROP_OPERATION = "operation"; +// +// public static final String PROP_INIT_DELAY = "initialDelay"; +// +// public static final String SEQ_READ = "sequentialRead"; +// +// public static final String RND_READ = "randomRead"; +// +// public static final String SEQ_WRITE = "sequentialWrite"; +// +// public static final String RND_WRITE = "randomWrite"; +// +// public List osds; +// +// public int stripeSize; +// +// public int numRequests; +// +// public int numObjects; +// +// public String policy; +// +// public String fileId; +// +// public int targetOSD; +// +// public String operation; +// +// public long initialDelay; +// +// public int firstObject; +// +// public int stepSize; +// +// public Configuration() throws IOException { +// this(null); +// +// osds.add(new InetSocketAddress("csr-pc24.zib.de", 32640)); +// // osds.add(new InetSocketAddress("csr-pc24.zib.de", 32641)); +// osds.add(new InetSocketAddress("xtreem.zib.de", 32637)); +// // osds.add(new InetSocketAddress("opt.csc.ncsu.edu", 32637)); +// } +// +// public Configuration(String file) throws IOException { +// +// Properties props = new Properties(); +// if (file != null) +// props.load(new FileInputStream(file)); +// +// // parse the OSD list +// osds = new ArrayList(); +// for (int i = 1;; i++) { +// +// if (!props.containsKey(PROP_OSD + i)) +// break; +// +// String osd = props.getProperty(PROP_OSD + i); +// int colon = osd.lastIndexOf(':'); +// String host = osd.substring(0, colon); +// int port = Integer.parseInt(osd.substring(colon + 1)); +// osds.add(new InetSocketAddress(host, port)); +// } +// +// stripeSize = Integer.parseInt(props.getProperty(PROP_STRIPESIZE, +// "4")); +// numRequests = Integer.parseInt(props.getProperty(PROP_NUM_REQUESTS, +// "20000")); +// numObjects = Integer.parseInt(props.getProperty(PROP_NUM_OBJECTS, +// "1000")); +// firstObject = Integer.parseInt(props.getProperty(PROP_FIRST_OBJECT, +// "0")); +// stepSize = Integer.parseInt(props.getProperty(PROP_STEP_SIZE, "1")); +// policy = props.getProperty(PROP_POLICY, "lazy"); +// fileId = props.getProperty(PROP_FILE_ID, Long.toHexString( +// System.currentTimeMillis() / 1000).toUpperCase() +// + ":1"); +// targetOSD = Integer.parseInt(props +// .getProperty(PROP_TARGET_OSD, "0")) - 1; +// operation = props.getProperty(PROP_OPERATION, RND_WRITE); +// initialDelay = Long.parseLong(props.getProperty(PROP_INIT_DELAY, +// "-1")); +// } +// +// public String toString() { +// +// StringBuffer buf = new StringBuffer(); +// buf.append(" OSD list:\n"); +// for (InetSocketAddress osd : osds) +// buf.append(" " + osd + "\n"); +// +// buf.append(" operation: " + operation + "\n"); +// buf.append("number of requests: " + numRequests + "\n"); +// buf.append(" number of objects: " + numObjects + "\n"); +// buf.append(" first object: " + firstObject + "\n"); +// buf.append(" stepSize: " + stepSize + "\n"); +// buf.append(" target OSD: " +// + (targetOSD == -1 ? "random" : osds.get(targetOSD)) + "\n"); +// buf.append(" update policy: " + policy + "\n"); +// buf.append(" file ID: " + fileId + "\n"); +// buf.append(" stripe size: " + stripeSize + "\n"); +// buf.append(" initial delay: " + initialDelay + "\n"); +// +// return buf.toString(); +// } +// } +// +// private static final int KB = 1024; +// +// private static final byte PATTERN1 = (byte) 'X'; +// +// private static final byte PATTERN2 = (byte) 'Y'; +// +// private static final long TIMEOUT = 5000; +// +// private final OSDClient client; +// +// private final Configuration config; +// +// public OSDTestClient(String configFile) throws Exception { +// this.client = new OSDClient(null); +// this.config = configFile == null ? new Configuration() +// : new Configuration(configFile); +// System.out.println(config.toString()); +// } +// +// public void testRead(Configuration config) throws Exception { +// +// Capability cap = null;/*new Capability(config.fileId, "rw", System +// .currentTimeMillis() + 1000 * 60 * 60, 0, "secretPassphrase");*/ +// +// // create a locations list with the given replication policy +// Locations loc = createLocations(config); +// +// ResponseCollector rc = new ResponseCollector(config); +// ThroughputMonitor calc = new ThroughputMonitor(rc); +// calc.start(); +// +// // perform reads +// for (int i = 0; i < config.numRequests; i++) { +// +// InetSocketAddress osd = config.targetOSD == -1 ? config.osds +// .get((int) (Math.random() * config.osds.size())) +// : config.osds.get(config.targetOSD); +// int obj = config.operation.equals(Configuration.SEQ_READ) ? (config.firstObject + i +// * config.stepSize) +// % config.numObjects +// : (int) (Math.random() * config.numObjects); +// +// RPCResponse response = client +// .get(osd, loc, cap, config.fileId, obj); +// response +// .setAttachment(new Object[] { loc, cap, obj, config.fileId }); +// response.setResponseListener(rc); +// } +// +// calc.join(); +// } +// +// public void testWrite(Configuration config) throws Exception { +// +// Capability cap = null;/*new Capability(config.fileId, "rw", System +// .currentTimeMillis() + 1000 * 60 * 60, 0, "secretPassphrase");*/ +// +// // create a locations list with the given replication policy +// Locations loc = createLocations(config); +// +// ResponseCollector rc = new ResponseCollector(config); +// ThroughputMonitor calc = new ThroughputMonitor(rc); +// calc.start(); +// +// // perform writes +// for (int i = 0; i < config.numRequests; i++) { +// +// ReusableBuffer buf = allocateAndFillBuffer(config.stripeSize, +// PATTERN1); +// +// InetSocketAddress osd = config.targetOSD == -1 ? config.osds +// .get((int) (Math.random() * config.osds.size())) +// : config.osds.get(config.targetOSD); +// int obj = config.operation.equals(Configuration.SEQ_WRITE) ? (config.firstObject + i +// * config.stepSize) +// % config.numObjects +// : (int) (Math.random() * config.numObjects); +// +// RPCResponse response = client.put(osd, loc, cap, config.fileId, +// obj, buf); +// response.setAttachment(new Object[] { loc, cap, obj, config.fileId, +// buf }); +// response.setResponseListener(rc); +// } +// +// calc.join(); +// } +// +// public void runTest() throws Exception { +// +// BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); +// +// if (config.initialDelay == -1) { +// System.out.println("press ENTER to start test run"); +// r.readLine(); +// } else { +// Thread.sleep(config.initialDelay); +// } +// +// if (config.operation.equals(Configuration.RND_READ) +// || config.operation.equals(Configuration.SEQ_READ)) +// testRead(config); +// else if (config.operation.equals(Configuration.RND_WRITE) +// || config.operation.equals(Configuration.SEQ_WRITE)) +// testWrite(config); +// else +// System.err.println("invalid operation: " + config.operation); +// +// client.shutdown(); +// client.waitForShutdown(); +// } +// +// private Locations createLocations(Configuration config) { +// List locations = new ArrayList(config.osds.size()); +// for (InetSocketAddress addr : config.osds) { +// StripingPolicy sp = new RAID0(config.stripeSize, 1); +// List osd = new ArrayList(1); +// osd.add(new ServiceUUID("http://"+addr.getHostName()+":"+addr.getPort())); +// locations.add(new Location(sp, osd)); +// } +// return new Locations(locations, 0, config.policy, 0); +// } +// +// private static ReusableBuffer allocateAndFillBuffer(int stripeSize, +// byte pattern) { +// ReusableBuffer buf = BufferPool.allocate(stripeSize * KB); +// for (int i = 0; i < stripeSize * KB; i++) +// buf.put(pattern); +// +// return buf; +// } +// +// public static void main(String[] args) { +// +// try { +// Logging.start(Logging.LEVEL_ERROR); +// OSDTestClient client = new OSDTestClient(args.length == 0 ? null +// : args[0]); +// client.runTest(); +// +// } catch (Exception ex) { +// ex.printStackTrace(); +// System.exit(1); +// } +// +// } +// +//} diff --git a/java/servers/src/org/xtreemfs/sandbox/tests/ReplicatedTortureXtreemFS.java b/java/servers/src/org/xtreemfs/sandbox/tests/ReplicatedTortureXtreemFS.java new file mode 100644 index 0000000..998249e --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/tests/ReplicatedTortureXtreemFS.java @@ -0,0 +1,378 @@ +/* Copyright (c) 2010 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin. + + This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based + Grid Operating System, see for more details. + The XtreemOS project has been developed with the financial support of the + European Commission's IST program under contract #FP6-033576. + + XtreemFS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 2 of the License, or (at your option) + any later version. + + XtreemFS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with XtreemFS. If not, see . + */ +/* + * AUTHORS: Björn Kolbeck (ZIB) + */ + +package org.xtreemfs.sandbox.tests; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.clients.File; +import org.xtreemfs.common.clients.RandomAccessFile; +import org.xtreemfs.common.clients.Volume; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.CLOption; +import org.xtreemfs.foundation.util.CLOption.IntegerValue; +import org.xtreemfs.foundation.util.CLOption.StringValue; +import org.xtreemfs.foundation.util.CLOption.Switch; +import org.xtreemfs.foundation.util.CLOptionParser; +import org.xtreemfs.foundation.util.InvalidUsageException; +import org.xtreemfs.foundation.util.PBRPCServiceURL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.PORTS; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author bjko + */ +public class ReplicatedTortureXtreemFS { + + public static void main(String[] args) { + try { + CLOptionParser parser = new CLOptionParser("TortureXtreemFS"); + CLOption.StringValue optVolname = (StringValue) parser.addOption(new CLOption.StringValue("v", "volname", "volume name")); + CLOption.StringValue optPath = (StringValue) parser.addOption(new CLOption.StringValue("p", "path", "filename (default is torture.dat)")); + CLOption.StringValue optPKCS12file = (CLOption.StringValue) parser.addOption(new CLOption.StringValue(null, "pkcs12-file-path", "")); + CLOption.StringValue optPKCS12passphrase = (CLOption.StringValue) parser.addOption(new CLOption.StringValue(null, "pkcs12-passphrase", "")); + CLOption.StringValue optSSLProtocol = (CLOption.StringValue) parser.addOption( + new CLOption.StringValue(null, "ssl-protocol", + "SSL/TLS version to use: sslv3, ssltls, tlsv1, tlsv11, tlsv12. 'ssltls' (default) accepts all versions, " + + "the others accept only the exact version they name. 'tlsv12' is available in JDK 7+ only. " + + "'tlsv11' comes with JDK 6 or 7, depending on the vendor.")); + CLOption.Switch optRandomOnly = (Switch) parser.addOption(new CLOption.Switch("r", "random", "execute only random test")); + CLOption.IntegerValue optReplicas = (IntegerValue) parser.addOption(new CLOption.IntegerValue("n", "num-replicas", "number of replicas to use (default is 1)")); + CLOption.Switch optTrunc = (Switch) parser.addOption(new CLOption.Switch("t", "truncae", "truncate to 0 instead of creating a new file")); + CLOption.Switch optAddR = (Switch) parser.addOption(new CLOption.Switch("a", "addreplica", "adds a new replica after writing and reads from it")); + + parser.parse(args); + + final List arguments = parser.getArguments(); + + Logging.start(Logging.LEVEL_WARN); + TimeSync.initializeLocal(50); + + if (arguments.size() != 1) { + usage(); + return; + } + + + + final String path = optPath.isSet() ? optPath.getValue() : "/torture.data"; + final String volname = optVolname.isSet() ? optVolname.getValue() : "test"; + + final PBRPCServiceURL dirURL = new PBRPCServiceURL(arguments.get(0),Schemes.SCHEME_PBRPC,PORTS.DIR_PBRPC_PORT_DEFAULT.getNumber()); + + final boolean useSSL = dirURL.getProtocol().equals(Schemes.SCHEME_PBRPCG) || dirURL.getProtocol().equals(Schemes.SCHEME_PBRPCS); + final boolean randomOnly = optRandomOnly.isSet(); + final boolean addReplica = optAddR.isSet(); + + final int replicas = optReplicas.isSet() ? optReplicas.getValue() : 1; + + SSLOptions sslOptions = null; + + if (useSSL) { + if (!optPKCS12file.isSet()) + throw new InvalidUsageException("must specify a PCKS#12 file with credentials for (grid)SSL mode, use "+optPKCS12file.getName()); + if (!optPKCS12passphrase.isSet()) + throw new InvalidUsageException("must specify a PCKS#12 passphrase for (grid)SSL mode, use "+optPKCS12passphrase.getName()); + + final String sslProtocol = optSSLProtocol.isSet() ? optSSLProtocol.getValue() : null; + final boolean gridSSL = dirURL.getProtocol().equals(Schemes.SCHEME_PBRPCG); + sslOptions = new SSLOptions(new FileInputStream(optPKCS12file.getValue()),optPKCS12passphrase.getValue(),"PKCS12", + null, null, "none", false, gridSSL, sslProtocol, null); + } + + + Client c = new Client(new InetSocketAddress[]{new InetSocketAddress(dirURL.getHost(), dirURL.getPort())}, + 30*1000, 5*60*1000, sslOptions); + c.start(); + System.out.println("file size from 64k to 512MB with record length from 4k to 1M"); + + final int MIN_FS = 64 * 1024; + final int MAX_FS = 512 * 1024 * 1024; + + final int MIN_REC = 4 * 1024; + final int MAX_REC = 1024 * 1024; + + + List grs = new ArrayList(1); + grs.add("torture"); + final UserCredentials uc = UserCredentials.newBuilder().setUsername("torture").addGroups("users").build(); + + try { + StripingPolicy sp = StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0).setWidth(1).setStripeSize(128).build(); + c.createVolume(volname, RPCAuthentication.authNone, uc, sp, AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, 0777); + } catch (Exception ex) { + //ignore + } + + Volume v = c.getVolume(volname, uc); + + if (replicas > 1) { + File f = v.getFile("/"); + f.setDefaultReplication(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE, replicas); + } + + RandomAccessFile tmp = v.getFile(path + ".tmp").open("rw", 0666); + + //System.out.println("Default striping policy is: " + tmp.getFile().get); + + if (!randomOnly) { + for (int fsize = MIN_FS; fsize <= MAX_FS; fsize = fsize * 2) { + for (int recsize = MIN_REC; recsize <= MAX_REC; recsize = recsize * 2) { + if (testSequential_write(fsize, recsize, path, v)) { + continue; + } + } + } + System.out.println("waiting for files to be closed on OSD (100 seconds)"); + Thread.sleep(100*1000); + int readRepl = replicas-1; + if (addReplica) { + for (int fsize = MIN_FS; fsize <= MAX_FS; fsize = fsize * 2) { + for (int recsize = MIN_REC; recsize <= MAX_REC; recsize = recsize * 2) { + final int numRecs = fsize / recsize; + if (numRecs == 0) { + break; + } + File f = v.getFile(path+"."+fsize+"-"+recsize); + f.addReplica(1, f.getSuitableOSDs(1), 0); + } + } + readRepl = replicas; + } + + for (int fsize = MIN_FS; fsize <= MAX_FS; fsize = fsize * 2) { + for (int recsize = MIN_REC; recsize <= MAX_REC; recsize = recsize * 2) { + if (testSequential_read(fsize, recsize, path, v,readRepl)) { + continue; + } + } + } + } + + /*System.out.println("\nrandom test\n"); + + for (int fsize = MIN_FS; fsize <= MAX_FS; fsize = fsize * 2) { + for (int recsize = MIN_REC; recsize <= MAX_REC; recsize = recsize * 2) { + if (testRandom(fsize, recsize, path, v)) { + continue; + } + } + }*/ + + System.out.println("finished"); + c.stop(); + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(1); + } + + } + + private static boolean testSequential_write(int fsize, int recsize, final String path, Volume v) + throws InterruptedException, Exception, IOException { + final int numRecs = fsize / recsize; + if (numRecs == 0) { + return true; + } + byte[] sendBuffer = new byte[recsize]; + for (int i = 0; i < recsize; i++) { + sendBuffer[i] = (byte) ((i % 26) + 65); + } + long tStart = System.currentTimeMillis(); + File f = v.getFile(path+"."+fsize+"-"+recsize); + RandomAccessFile raf = f.open("rw", 0666); + long tOpen = System.currentTimeMillis(); + long bytesWritten = 0; + // do writes + long tWrite = 0; + for (int rec = 0; rec < numRecs; rec++) { + long tmpStart = System.currentTimeMillis(); + bytesWritten += raf.write(sendBuffer, 0, recsize); + tWrite += System.currentTimeMillis() - tmpStart; + } + assert (bytesWritten == numRecs * recsize); + raf.flush(); + raf.seek(0); + final long tFlush = System.currentTimeMillis(); + + raf.close(); + + double writeRate = ((double) fsize) / 1024.0 / (((double) (tWrite)) / 1000.0); + System.out.format("fs: %8d bs: %8d write: %6d ms %6.0f kb/s\n", + fsize / 1024, recsize, tWrite, writeRate); + return false; + } + + private static boolean testSequential_read(int fsize, int recsize, final String path, Volume v, int forceReplica) + throws InterruptedException, Exception, IOException { + final int numRecs = fsize / recsize; + if (numRecs == 0) { + return true; + } + byte[] sendBuffer = new byte[recsize]; + for (int i = 0; i < recsize; i++) { + sendBuffer[i] = (byte) ((i % 26) + 65); + } + long tStart = System.currentTimeMillis(); + File f = v.getFile(path+"."+fsize+"-"+recsize); + RandomAccessFile raf = f.open("rw", 0666); + raf.forceReplica(forceReplica); + long tOpen = System.currentTimeMillis(); + + long tRead = 0; + // do writes + byte[] readBuffer = new byte[recsize]; + for (int rec = 0; rec < numRecs; rec++) { + long tmpStart = System.currentTimeMillis(); + final int bytesRead = raf.read(readBuffer, 0, recsize); + tRead += System.currentTimeMillis() - tmpStart; + if (bytesRead != recsize) { + System.out.println("PREMATURE END-OF-FILE AT " + rec * recsize); + System.out.println("expected " + recsize + " bytes"); + System.out.println("got " + bytesRead + " bytes"); + System.exit(1); + } + for (int i = 0; i < recsize; i++) { + if (readBuffer[i] != (byte) ((i % 26) + 65)) { + System.out.println("INVALID CONTENT AT " + (rec * recsize + i)); + System.out.println("expected: " + (byte) ((i % 26) + 65)); + System.out.println("got : " + readBuffer[i]); + System.exit(1); + } + } + } + + raf.close(); + f.delete(); + + final long tDelete = System.currentTimeMillis(); + double readRate = ((double) fsize) / 1024.0 / (((double) (tRead)) / 1000.0); + System.out.format("fs: %8d bs: %8d read: %6d ms %6.0f kb/s\n", + fsize / 1024, recsize, tRead, readRate); + return false; + } + + /*private static boolean testRandom(int fsize, int recsize, final String path, Volume v, boolean truncate) + throws ONCRPCException, InterruptedException, Exception, IOException { + final int numRecs = fsize / recsize; + int[] skips = new int[numRecs]; + if (numRecs == 0) { + return true; + } + byte[] sendBuffer = new byte[recsize]; + for (int i = 0; i < recsize; i++) { + sendBuffer[i] = (byte) ((i % 26) + 65); + } + long tStart = System.currentTimeMillis(); + File f = v.getFile(path); + RandomAccessFile raf = f.open("rw", 0666); + if (truncate) + raf.setLength(0); + long tOpen = System.currentTimeMillis(); + long bytesWritten = 0; + long tWrite = 0; + // do writes + for (int rec = 0; rec < numRecs; rec++) { + skips[rec] = (int) (Math.random() * ((double) recsize)); + raf.seek(raf.getFilePointer() + skips[rec]); + long tmpStart = System.currentTimeMillis(); + bytesWritten += raf.write(sendBuffer, 0, recsize); + tWrite += System.currentTimeMillis() - tmpStart; + } + if (bytesWritten != numRecs * recsize) { + System.out.println("not all data was written!"); + System.exit(1); + } + raf.flush(); + raf.seek(0); + final long tFlush = System.currentTimeMillis(); + long tRead = 0; + // do writes + byte[] readBuffer = new byte[recsize]; + for (int rec = 0; rec < numRecs; rec++) { + raf.seek(raf.getFilePointer() + skips[rec]); + long tmpStart = System.currentTimeMillis(); + final int bytesRead = raf.read(readBuffer, 0, recsize); + tRead += System.currentTimeMillis() - tmpStart; + if (bytesRead != recsize) { + System.out.println("PREMATURE END-OF-FILE AT " + rec * recsize); + System.out.println("expected " + recsize + " bytes"); + System.out.println("got " + bytesRead + " bytes"); + System.exit(1); + } + for (int i = 0; i < recsize; i++) { + if (readBuffer[i] != (byte) ((i % 26) + 65)) { + System.out.println("INVALID CONTENT AT " + (rec * recsize + i)); + System.out.println("expected: " + (byte) ((i % 26) + 65)); + System.out.println("got : " + readBuffer[i]); + System.exit(1); + } + } + } + raf.close(); + + if (!truncate) + f.delete(); + + final long tDelete = System.currentTimeMillis(); + double writeRate = ((double) fsize) / 1024.0 / (((double) (tWrite)) / 1000.0); + double readRate = ((double) fsize) / 1024.0 / (((double) (tRead)) / 1000.0); + System.out.format("fs: %8d bs: %8d write: %6d ms %6.0f kb/s read: %6d ms %6.0f kb/s\n", + fsize / 1024, recsize, tWrite, writeRate, tRead, readRate); + return false; + }*/ + + private static void usage() { + System.out.println("usage: torture [options] "); + System.out.println(" -v name of the volume on the mrc (default: test)"); + System.out.println(" -p filename to use for measurements (default: /torture.dat)"); + + System.out + .println(" In case of a secured URL ('https://...'), it is necessary to also specify SSL credentials:"); + System.out + .println(" -c a PKCS#12 file containing user credentials"); + System.out + .println(" -cpass a pass phrase to decrypt the the user credentials file"); + System.out + .println(" -t a PKCS#12 file containing a set of certificates from trusted CAs"); + System.out + .println(" -tpass a pass phrase to decrypt the trusted CAs file"); + System.out.println(" -h show usage info"); + } + +} diff --git a/java/servers/src/org/xtreemfs/sandbox/tests/TortureLocalFS.java b/java/servers/src/org/xtreemfs/sandbox/tests/TortureLocalFS.java new file mode 100644 index 0000000..23499c9 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/tests/TortureLocalFS.java @@ -0,0 +1,232 @@ +/* Copyright (c) 2008 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin. + + This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based + Grid Operating System, see for more details. + The XtreemOS project has been developed with the financial support of the + European Commission's IST program under contract #FP6-033576. + + XtreemFS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 2 of the License, or (at your option) + any later version. + + XtreemFS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with XtreemFS. If not, see . +*/ +/* + * AUTHORS: Björn Kolbeck (ZIB) + */ + + +package org.xtreemfs.sandbox.tests; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.util.CLIParser; +import org.xtreemfs.foundation.util.CLIParser.CliOption; + +/** + * + * @author bjko + */ +public class TortureLocalFS { + + public static void main(String[] args) { + try { + + Map options = new HashMap(); + List arguments = new ArrayList(0); + options.put("p", new CliOption(CliOption.OPTIONTYPE.STRING)); + options.put("r", new CliOption(CliOption.OPTIONTYPE.SWITCH)); + + CLIParser.parseCLI(args, options, arguments); + + Logging.start(Logging.LEVEL_WARN); + TimeSync.initialize(null, 10000, 50); + + if (arguments.size() != 0) { + usage(); + return; + } + + + final String path = (options.get("p").stringValue != null) ? + options.get("p").stringValue : "./torture.data"; + + + final int MIN_FS = 64*1024; + final int MAX_FS = 512*1024*1024; + + final int MIN_REC = 4*1024; + final int MAX_REC = 1024*1024; + + if (options.get("r").switchValue == false) { + for (int fsize = MIN_FS; fsize <= MAX_FS; fsize = fsize * 2) { + for (int recsize = MIN_REC; recsize <= MAX_REC; recsize = recsize *2) { + if (testSequential(fsize, recsize, path)) { + continue; + } + } + } + } + + System.out.println("\nrandom test\n"); + + for (int fsize = MIN_FS; fsize <= MAX_FS; fsize = fsize * 2) { + for (int recsize = MIN_REC; recsize <= MAX_REC; recsize = recsize *2) { + if (testRandom(fsize, recsize, path)) { + continue; + } + } + } + + System.out.println("finished"); + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(1); + } + + } + + private static boolean testSequential(int fsize, int recsize, final String path) throws InterruptedException, Exception, IOException { + final int numRecs = fsize / recsize; + if (numRecs == 0) { + return true; + } + byte[] sendBuffer = new byte[recsize]; + for (int i = 0; i < recsize; i++) { + sendBuffer[i] = (byte) ((i%26) + 65); + } + long tStart = System.currentTimeMillis(); + RandomAccessFile raf = new RandomAccessFile(path,"rw"); + long tOpen = System.currentTimeMillis(); + long bytesWritten = 0; + //do writes + long tWrite = 0; + for (int rec = 0; rec < numRecs; rec++) { + long tmpStart = System.currentTimeMillis(); + raf.write(sendBuffer, 0, recsize); + bytesWritten += recsize; + tWrite += System.currentTimeMillis()-tmpStart; + } + assert (bytesWritten == numRecs * recsize); + raf.getFD().sync(); + raf.seek(0); + final long tFlush = System.currentTimeMillis(); + long tRead = 0; + //do writes + byte[] readBuffer = new byte[recsize]; + for (int rec = 0; rec < numRecs; rec++) { + long tmpStart = System.currentTimeMillis(); + final int bytesRead = raf.read(readBuffer, 0, recsize); + tRead += System.currentTimeMillis()-tmpStart; + if (bytesRead != recsize) { + System.out.println("PREMATURE END-OF-FILE AT " + rec * recsize); + System.out.println("expected " + recsize + " bytes"); + System.out.println("got " + bytesRead + " bytes"); + System.exit(1); + } + for (int i = 0; i < recsize; i++) { + if (readBuffer[i] != (byte) ((i%26) + 65)) { + System.out.println("INVALID CONTENT AT " + (rec * recsize + i)); + System.out.println("expected: " + (byte) ((i%26) + 65)); + System.out.println("got : " + readBuffer[i]); + System.exit(1); + } + } + } + + File f = new File(path); + f.delete(); + final long tDelete = System.currentTimeMillis(); + double writeRate = ((double) fsize) / 1024.0 / (((double) (tWrite)) / 1000.0); + double readRate = ((double) fsize) / 1024.0 / (((double) (tRead)) / 1000.0); + System.out.format("fs: %8d bs: %8d write: %6d ms %6.0f kb/s read: %6d ms %6.0f kb/s\n", fsize / 1024, recsize, tWrite, writeRate, tRead, readRate); + return false; + } + + private static boolean testRandom(int fsize, int recsize, final String path) throws InterruptedException, Exception, IOException { + final int numRecs = fsize / recsize; + int[] skips = new int[numRecs]; + if (numRecs == 0) { + return true; + } + byte[] sendBuffer = new byte[recsize]; + for (int i = 0; i < recsize; i++) { + sendBuffer[i] = (byte) ((i%26) + 65); + } + long tStart = System.currentTimeMillis(); + RandomAccessFile raf = new RandomAccessFile(path,"rw"); + long tOpen = System.currentTimeMillis(); + long bytesWritten = 0; + long tWrite = 0; + //do writes + for (int rec = 0; rec < numRecs; rec++) { + skips[rec] = (int) (Math.random()*((double)recsize)); + raf.seek(raf.getFilePointer()+skips[rec]); + long tmpStart = System.currentTimeMillis(); + raf.write(sendBuffer, 0, recsize); + bytesWritten += recsize; + tWrite += System.currentTimeMillis()-tmpStart; + } + if (bytesWritten != numRecs * recsize) { + System.out.println("not all data was written!"); + System.exit(1); + } + raf.getFD().sync(); + raf.seek(0); + final long tFlush = System.currentTimeMillis(); + long tRead = 0; + //do writes + byte[] readBuffer = new byte[recsize]; + for (int rec = 0; rec < numRecs; rec++) { + raf.seek(raf.getFilePointer()+skips[rec]); + long tmpStart = System.currentTimeMillis(); + final int bytesRead = raf.read(readBuffer, 0, recsize); + tRead += System.currentTimeMillis()-tmpStart; + if (bytesRead != recsize) { + System.out.println("PREMATURE END-OF-FILE AT " + rec * recsize); + System.out.println("expected " + recsize + " bytes"); + System.out.println("got " + bytesRead + " bytes"); + System.exit(1); + } + for (int i = 0; i < recsize; i++) { + if (readBuffer[i] != (byte) ((i%26) + 65)) { + System.out.println("INVALID CONTENT AT " + (rec * recsize + i)); + System.out.println("expected: " + (byte) ((i%26) + 65)); + System.out.println("got : " + readBuffer[i]); + System.exit(1); + } + } + } + File f = new File(path); + f.delete(); + final long tDelete = System.currentTimeMillis(); + double writeRate = ((double) fsize) / 1024.0 / (((double) (tWrite)) / 1000.0); + double readRate = ((double) fsize) / 1024.0 / (((double) (tRead)) / 1000.0); + System.out.format("fs: %8d bs: %8d write: %6d ms %6.0f kb/s read: %6d ms %6.0f kb/s\n", fsize / 1024, recsize, tWrite, writeRate, tRead, readRate); + return false; + } + + + private static void usage() { + System.out.println("usage: torture [options]"); + System.out.println(" -p filename to use for measurements (default: /torture.dat)"); + System.out.println(" -r random only"); + System.out.println(" -h show usage info"); + } + +} diff --git a/java/servers/src/org/xtreemfs/sandbox/tests/TortureXtreemFS.java b/java/servers/src/org/xtreemfs/sandbox/tests/TortureXtreemFS.java new file mode 100644 index 0000000..49487e1 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/tests/TortureXtreemFS.java @@ -0,0 +1,330 @@ +/* Copyright (c) 2008 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin. + + This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based + Grid Operating System, see for more details. + The XtreemOS project has been developed with the financial support of the + European Commission's IST program under contract #FP6-033576. + + XtreemFS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 2 of the License, or (at your option) + any later version. + + XtreemFS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with XtreemFS. If not, see . + */ +/* + * AUTHORS: Björn Kolbeck (ZIB) + */ + +package org.xtreemfs.sandbox.tests; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.clients.File; +import org.xtreemfs.common.clients.RandomAccessFile; +import org.xtreemfs.common.clients.Volume; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.CLOption; +import org.xtreemfs.foundation.util.CLOption.IntegerValue; +import org.xtreemfs.foundation.util.CLOption.StringValue; +import org.xtreemfs.foundation.util.CLOption.Switch; +import org.xtreemfs.foundation.util.CLOptionParser; +import org.xtreemfs.foundation.util.InvalidUsageException; +import org.xtreemfs.foundation.util.PBRPCServiceURL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.PORTS; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.List; + +/** + * + * @author bjko + */ +public class TortureXtreemFS { + + public static void main(String[] args) { + try { + CLOptionParser parser = new CLOptionParser("TortureXtreemFS"); + CLOption.StringValue optVolname = (StringValue) parser.addOption(new CLOption.StringValue("v", "volname", "volume name")); + CLOption.StringValue optPath = (StringValue) parser.addOption(new CLOption.StringValue("p", "path", "filename (default is torture.dat)")); + CLOption.StringValue optPKCS12file = (CLOption.StringValue) parser.addOption(new CLOption.StringValue(null, "pkcs12-file-path", "")); + CLOption.StringValue optPKCS12passphrase = (CLOption.StringValue) parser.addOption(new CLOption.StringValue(null, "pkcs12-passphrase", "")); + CLOption.StringValue optSSLProtocol = (CLOption.StringValue) parser.addOption( + new CLOption.StringValue(null, "ssl-protocol", + "SSL/TLS version to use: sslv3, ssltls, tlsv1, tlsv11, tlsv12. 'ssltls' (default) accepts all versions, " + + "the others accept only the exact version they name. 'tlsv12' is available in JDK 7+ only. " + + "'tlsv11' comes with JDK 6 or 7, depending on the vendor.")); + CLOption.Switch optRandomOnly = (Switch) parser.addOption(new CLOption.Switch("r", "random", "execute only random test")); + CLOption.IntegerValue optReplicas = (IntegerValue) parser.addOption(new CLOption.IntegerValue("n", "num-replicas", "number of replicas to use (default is 1)")); + CLOption.Switch optTrunc = (Switch) parser.addOption(new CLOption.Switch("t", "truncae", "truncate to 0 instead of creating a new file")); + + parser.parse(args); + + final List arguments = parser.getArguments(); + + Logging.start(Logging.LEVEL_WARN); + TimeSync.initializeLocal(50); + + if (arguments.size() != 1) { + usage(); + return; + } + + + + final String path = optPath.isSet() ? optPath.getValue() : "/torture.data"; + final String volname = optVolname.isSet() ? optVolname.getValue() : "test"; + + final PBRPCServiceURL dirURL = new PBRPCServiceURL(arguments.get(0),Schemes.SCHEME_PBRPC,PORTS.DIR_PBRPC_PORT_DEFAULT.getNumber()); + + final boolean useSSL = dirURL.getProtocol().equals(Schemes.SCHEME_PBRPCG) || dirURL.getProtocol().equals(Schemes.SCHEME_PBRPCS); + final boolean randomOnly = optRandomOnly.isSet(); + + final boolean truncate = optTrunc.isSet(); + + final int replicas = optReplicas.isSet() ? optReplicas.getValue() : 1; + + SSLOptions sslOptions = null; + + if (useSSL) { + if (!optPKCS12file.isSet()) + throw new InvalidUsageException("must specify a PCKS#12 file with credentials for (grid)SSL mode, use "+optPKCS12file.getName()); + if (!optPKCS12passphrase.isSet()) + throw new InvalidUsageException("must specify a PCKS#12 passphrase for (grid)SSL mode, use "+optPKCS12passphrase.getName()); + + final String sslProtocol = optSSLProtocol.isSet() ? optSSLProtocol.getValue() : null; + final boolean gridSSL = dirURL.getProtocol().equals(Schemes.SCHEME_PBRPCG); + sslOptions = new SSLOptions(new FileInputStream(optPKCS12file.getValue()),optPKCS12passphrase.getValue(),"PKCS12", + null, null, "none", false, gridSSL, sslProtocol, null); + } + + + Client c = new Client(new InetSocketAddress[]{new InetSocketAddress(dirURL.getHost(), dirURL.getPort())}, + 30*1000, 5*60*1000, sslOptions); + c.start(); + System.out.println("file size from 64k to 512MB with record length from 4k to 1M"); + + final int MIN_FS = 64 * 1024; + final int MAX_FS = 512 * 1024 * 1024; + + final int MIN_REC = 4 * 1024; + final int MAX_REC = 1024 * 1024; + + + final UserCredentials uc = UserCredentials.newBuilder().setUsername("torture").addGroups("users").build(); + + try { + StripingPolicy sp = StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0).setWidth(1).setStripeSize(128).build(); + c.createVolume(volname, RPCAuthentication.authNone, uc, sp, AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, 0777); + } catch (Exception ex) { + //ignore + } + + Volume v = c.getVolume(volname, uc); + + if (replicas > 1) { + File f = v.getFile("/"); + f.setDefaultReplication(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE, replicas); + } + + RandomAccessFile tmp = v.getFile(path + ".tmp").open("rw", 0666); + + //System.out.println("Default striping policy is: " + tmp.getFile().get); + + if (!randomOnly) { + for (int fsize = MIN_FS; fsize <= MAX_FS; fsize = fsize * 2) { + for (int recsize = MIN_REC; recsize <= MAX_REC; recsize = recsize * 2) { + if (testSequential(fsize, recsize, path, v, truncate)) { + continue; + } + } + } + } + + System.out.println("\nrandom test\n"); + + for (int fsize = MIN_FS; fsize <= MAX_FS; fsize = fsize * 2) { + for (int recsize = MIN_REC; recsize <= MAX_REC; recsize = recsize * 2) { + if (testRandom(fsize, recsize, path, v, truncate)) { + continue; + } + } + } + + System.out.println("finished"); + c.stop(); + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(1); + } + + } + + private static boolean testSequential(int fsize, int recsize, final String path, Volume v, boolean truncate) + throws InterruptedException, Exception, IOException { + final int numRecs = fsize / recsize; + if (numRecs == 0) { + return true; + } + byte[] sendBuffer = new byte[recsize]; + for (int i = 0; i < recsize; i++) { + sendBuffer[i] = (byte) ((i % 26) + 65); + } + long tStart = System.currentTimeMillis(); + File f = v.getFile(path); + RandomAccessFile raf = f.open("rw", 0666); + if (truncate) + raf.setLength(0); + long tOpen = System.currentTimeMillis(); + long bytesWritten = 0; + // do writes + long tWrite = 0; + for (int rec = 0; rec < numRecs; rec++) { + long tmpStart = System.currentTimeMillis(); + bytesWritten += raf.write(sendBuffer, 0, recsize); + tWrite += System.currentTimeMillis() - tmpStart; + } + assert (bytesWritten == numRecs * recsize); + raf.flush(); + raf.seek(0); + final long tFlush = System.currentTimeMillis(); + long tRead = 0; + // do writes + byte[] readBuffer = new byte[recsize]; + for (int rec = 0; rec < numRecs; rec++) { + long tmpStart = System.currentTimeMillis(); + final int bytesRead = raf.read(readBuffer, 0, recsize); + tRead += System.currentTimeMillis() - tmpStart; + if (bytesRead != recsize) { + System.out.println("PREMATURE END-OF-FILE AT " + rec * recsize); + System.out.println("expected " + recsize + " bytes"); + System.out.println("got " + bytesRead + " bytes"); + System.exit(1); + } + for (int i = 0; i < recsize; i++) { + if (readBuffer[i] != (byte) ((i % 26) + 65)) { + System.out.println("INVALID CONTENT AT " + (rec * recsize + i)); + System.out.println("expected: " + (byte) ((i % 26) + 65)); + System.out.println("got : " + readBuffer[i]); + System.exit(1); + } + } + } + + raf.close(); + if (!truncate) + f.delete(); + + final long tDelete = System.currentTimeMillis(); + double writeRate = ((double) fsize) / 1024.0 / (((double) (tWrite)) / 1000.0); + double readRate = ((double) fsize) / 1024.0 / (((double) (tRead)) / 1000.0); + System.out.format("fs: %8d bs: %8d write: %6d ms %6.0f kb/s read: %6d ms %6.0f kb/s\n", + fsize / 1024, recsize, tWrite, writeRate, tRead, readRate); + return false; + } + + private static boolean testRandom(int fsize, int recsize, final String path, Volume v, boolean truncate) + throws InterruptedException, Exception, IOException { + final int numRecs = fsize / recsize; + int[] skips = new int[numRecs]; + if (numRecs == 0) { + return true; + } + byte[] sendBuffer = new byte[recsize]; + for (int i = 0; i < recsize; i++) { + sendBuffer[i] = (byte) ((i % 26) + 65); + } + long tStart = System.currentTimeMillis(); + File f = v.getFile(path); + RandomAccessFile raf = f.open("rw", 0666); + if (truncate) + raf.setLength(0); + long tOpen = System.currentTimeMillis(); + long bytesWritten = 0; + long tWrite = 0; + // do writes + for (int rec = 0; rec < numRecs; rec++) { + skips[rec] = (int) (Math.random() * ((double) recsize)); + raf.seek(raf.getFilePointer() + skips[rec]); + long tmpStart = System.currentTimeMillis(); + bytesWritten += raf.write(sendBuffer, 0, recsize); + tWrite += System.currentTimeMillis() - tmpStart; + } + if (bytesWritten != numRecs * recsize) { + System.out.println("not all data was written!"); + System.exit(1); + } + raf.flush(); + raf.seek(0); + final long tFlush = System.currentTimeMillis(); + long tRead = 0; + // do writes + byte[] readBuffer = new byte[recsize]; + for (int rec = 0; rec < numRecs; rec++) { + raf.seek(raf.getFilePointer() + skips[rec]); + long tmpStart = System.currentTimeMillis(); + final int bytesRead = raf.read(readBuffer, 0, recsize); + tRead += System.currentTimeMillis() - tmpStart; + if (bytesRead != recsize) { + System.out.println("PREMATURE END-OF-FILE AT " + rec * recsize); + System.out.println("expected " + recsize + " bytes"); + System.out.println("got " + bytesRead + " bytes"); + System.exit(1); + } + for (int i = 0; i < recsize; i++) { + if (readBuffer[i] != (byte) ((i % 26) + 65)) { + System.out.println("INVALID CONTENT AT " + (rec * recsize + i)); + System.out.println("expected: " + (byte) ((i % 26) + 65)); + System.out.println("got : " + readBuffer[i]); + System.exit(1); + } + } + } + raf.close(); + + if (!truncate) + f.delete(); + + final long tDelete = System.currentTimeMillis(); + double writeRate = ((double) fsize) / 1024.0 / (((double) (tWrite)) / 1000.0); + double readRate = ((double) fsize) / 1024.0 / (((double) (tRead)) / 1000.0); + System.out.format("fs: %8d bs: %8d write: %6d ms %6.0f kb/s read: %6d ms %6.0f kb/s\n", + fsize / 1024, recsize, tWrite, writeRate, tRead, readRate); + return false; + } + + private static void usage() { + System.out.println("usage: torture [options] "); + System.out.println(" -v name of the volume on the mrc (default: test)"); + System.out.println(" -p filename to use for measurements (default: /torture.dat)"); + + System.out + .println(" In case of a secured URL ('https://...'), it is necessary to also specify SSL credentials:"); + System.out + .println(" -c a PKCS#12 file containing user credentials"); + System.out + .println(" -cpass a pass phrase to decrypt the the user credentials file"); + System.out + .println(" -t a PKCS#12 file containing a set of certificates from trusted CAs"); + System.out + .println(" -tpass a pass phrase to decrypt the trusted CAs file"); + System.out.println(" -h show usage info"); + } + +} diff --git a/java/servers/src/org/xtreemfs/sandbox/tests/rwrepl_test.java b/java/servers/src/org/xtreemfs/sandbox/tests/rwrepl_test.java new file mode 100644 index 0000000..e1612ba --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/tests/rwrepl_test.java @@ -0,0 +1,205 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.xtreemfs.sandbox.tests; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.clients.File; +import org.xtreemfs.common.clients.RandomAccessFile; +import org.xtreemfs.common.clients.Volume; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.PBRPCServiceURL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; + +import java.io.IOException; +import java.net.InetSocketAddress; + +/** + * + * @author bjko + */ +public class rwrepl_test { + + public static final int WAIT_FOR_CLOSE = 90*1000; + public static final int BLKSIZE = 128*1024; + public static final String VOLNAME = "rwrtest"; + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + // TODO code application logic here + try { + final PBRPCServiceURL dir = new PBRPCServiceURL(args[0], "oncrpc", 32638); + final int numReplicas = Integer.valueOf(args[1]); + final int fileSize = Integer.valueOf(args[2])*1024*1024; + String mode = "rw"; + if (args.length > 3) { + mode = args[3]; + } + + Logging.start(Logging.LEVEL_INFO, Category.all); + TimeSync.initializeLocal(50); + + final UserCredentials uc = UserCredentials.newBuilder().setUsername("test").addGroups("users").build(); + + Client c = new Client(new InetSocketAddress[]{new InetSocketAddress(dir.getHost(), dir.getPort())}, 15*1000, 5*60*1000, null); + c.start(); + + try { + StripingPolicy sp = StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0).setWidth(1).setStripeSize(128).build(); + c.createVolume(VOLNAME, RPCAuthentication.authNone, uc, sp, AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, 0777); + } catch (Exception ex) { + System.out.println("create volume failed: "+ex); + } + + Volume v = c.getVolume(VOLNAME, uc); + + File f = v.getFile("data.rwrtest"); + + try { + f.delete(); + } catch (Exception ex) { + System.out.println("create volume failed: "+ex); + } + f.createFile(); + + if (!mode.contains("x")) + addReplicas(f,numReplicas,false); + + RandomAccessFile io = f.open("rw", 0444); + long datacnt = 0; + + System.out.println("replica: "+io.getCurrentReplica()+" = "+f.getReplica(io.getCurrentReplica())); + + if (mode.contains("w")) { + + while (datacnt < fileSize) { + + ReusableBuffer data = BufferPool.allocate(BLKSIZE); + fillData(data); + data.flip(); + + io.write(data); + System.out.print("w"); + + BufferPool.free(data); + datacnt += BLKSIZE; + + } + System.out.println(""); + System.out.println("writing complete"); + } + + if (mode.contains("t")) { + System.out.print("t"); + io.setLength(fileSize/2); + ReusableBuffer data = BufferPool.allocate(BLKSIZE); + fillData(data); + data.flip(); + + io.write(data); + System.out.println("w"); + + BufferPool.free(data); + } + + + + io.close(); + + Thread.sleep(WAIT_FOR_CLOSE); + + + + if (mode.contains("x")) + addReplicas(f,numReplicas,false); + + io = f.open("rw", 0444); + + int nextRepl = (int)(Math.random()*((double)(numReplicas)))+1; + System.out.println("switch to replica "+nextRepl); + io.forceReplica(nextRepl); + System.out.println("replica: "+io.getCurrentReplica()+" = "+f.getReplica(io.getCurrentReplica())); + + datacnt = 0; + if (mode.contains("r")) { + while (datacnt < fileSize) { + + ReusableBuffer data = BufferPool.allocate(BLKSIZE); + + io.read(data); + System.out.print("r"); + data.flip(); + if (checkData(data) == false) + throw new Exception("invalid data read"); + + BufferPool.free(data); + datacnt += BLKSIZE; + + } + System.out.println(""); + System.out.println("read complete"); + } + + + io.close(); + + c.stop(); + + + //do initial write + + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(1); + } + } + + private static void addReplicas(File f, int numReplicas, boolean quorum) throws Exception { + System.out.println("adding "+numReplicas+" replicas"); + if (quorum) + f.setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ); + else + f.setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE); + for (int i = 0; i < numReplicas; i++) { + String[] suitableOSDs = f.getSuitableOSDs(1); + System.out.println("suitable OSDs: "+suitableOSDs); + if (suitableOSDs.length != 1) + throw new IOException("cannot add OSDs, no suitable OSD"); + f.addReplica(1, suitableOSDs, 0); + } + } + + private static void fillData(ReusableBuffer data) { + byte cnt = 65; + while (data.hasRemaining()) { + data.put(cnt++); + if (cnt == 91) + cnt = 65; + } + } + + private static boolean checkData(ReusableBuffer data) { + byte cnt = 65; + while (data.hasRemaining()) { + if (data.get() != cnt++) + return false; + if (cnt == 91) + cnt = 65; + } + return true; + } + +} diff --git a/java/servers/src/org/xtreemfs/sandbox/writeTruncTest.java b/java/servers/src/org/xtreemfs/sandbox/writeTruncTest.java new file mode 100644 index 0000000..9189490 --- /dev/null +++ b/java/servers/src/org/xtreemfs/sandbox/writeTruncTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.sandbox; + +import java.io.File; +import java.io.RandomAccessFile; + +/** + * + * @author bjko + */ +public class writeTruncTest { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + // TODO code application logic here + try { + final String path = (args.length > 0) ? args[0] : "/tmp"; + final int numObjs = (args.length > 1) ? Integer.valueOf(args[1]) : 8*1024; + File f = new File(path+"/xtreemfs_testfile"); + f.delete(); + RandomAccessFile rf = new RandomAccessFile(f, "rw"); + long tStart = System.currentTimeMillis(); + long cnt = 0; + long fsize = 0; + for (int i = 0; i < 64*1024; i++) { + if (cnt % 4096 == 0) { + fsize += 4096; + rf.setLength(fsize); + } + rf.writeLong(8l); + rf.writeLong(64564516l); + cnt += 16; + + } + long tEnd = System.currentTimeMillis(); + System.out.println("duration (w/ trunc): "+(tEnd-tStart)+" ms"); + rf.close(); + + f = new File(path+"/xtreemfs_testfile"); + f.delete(); + rf = new RandomAccessFile(f, "rw"); + tStart = System.currentTimeMillis(); + for (int i = 0; i < 64*1024; i++) { + rf.writeLong(8l); + rf.writeLong(64564516l); + } + tEnd = System.currentTimeMillis(); + System.out.println("duration (no trunc): "+(tEnd-tStart)+" ms"); + rf.close(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/java/servers/src/org/xtreemfs/utils/DefaultDirConfig.java b/java/servers/src/org/xtreemfs/utils/DefaultDirConfig.java new file mode 100644 index 0000000..6a4f5d3 --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/DefaultDirConfig.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, Bjoern Kolbeck, + * Jan Stender, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.utils; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.xtreemfs.common.config.Config; +import org.xtreemfs.foundation.SSLOptions; + +public class DefaultDirConfig extends Config { + + public static final String DEFAULT_DIR_CONFIG = "/etc/xos/xtreemfs/default_dir"; + + private static final int MAX_NUM_DIRS = 5; + + private boolean sslEnabled; + + protected String[] directoryServices; + + private String serviceCredsFile; + + private String serviceCredsPassphrase; + + private String serviceCredsContainer; + + private String trustedCertsFile; + + private String trustedCertsPassphrase; + + private String trustedCertsContainer; + + private String sslProtocolString; + + public DefaultDirConfig() throws IOException { + super(DEFAULT_DIR_CONFIG); + // TODO(lukas) this will throw NullPointerExcpetions + directoryServices = null; + read(); + } + + public String[] getDirectoryServices() { + return directoryServices; + } + + /** + * Returns SSL Options or null if SSL is not enabled + * + * @throws IOException + * @throws FileNotFoundException + */ + public SSLOptions getSSLOptions() throws FileNotFoundException, IOException { + if (sslEnabled) { + return new SSLOptions(new FileInputStream(serviceCredsFile), serviceCredsPassphrase, + serviceCredsContainer, new FileInputStream(trustedCertsFile), trustedCertsPassphrase, + trustedCertsContainer, false, false, sslProtocolString, null); + } else { + return null; + } + } + + private void read() throws IOException { + + List dirServices = new ArrayList(); + + // read required DIR service + dirServices.add(this.readRequiredString("dir_service.host") + ":" + + this.readRequiredString("dir_service.port")); + + // read optional DIR services + for (int i = 1; i < MAX_NUM_DIRS; i++) { + String dirHost = this.readOptionalString("dir_service" + (i + 1) + ".host", null); + String dirPort = this.readOptionalString("dir_service" + (i + 1) + ".port", null); + if (dirHost == null | dirPort == null) { + break; + } + dirServices.add(dirHost + ":" + dirPort); + } + + directoryServices = dirServices.toArray(new String[dirServices.size()]); + + this.sslEnabled = readOptionalBoolean("ssl.enabled", false); + + // read SSL settings if SSL is enabled + if (sslEnabled) { + this.serviceCredsFile = this.readRequiredString("ssl.service_creds"); + + this.serviceCredsPassphrase = this.readRequiredString("ssl.service_creds.pw"); + + this.serviceCredsContainer = this.readRequiredString("ssl.service_creds.container"); + + this.trustedCertsFile = this.readRequiredString("ssl.trusted_certs"); + + this.trustedCertsPassphrase = this.readRequiredString("ssl.trusted_certs.pw"); + + this.trustedCertsContainer = this.readRequiredString("ssl.trusted_certs.container"); + + this.sslProtocolString = this.readOptionalString("ssl.protocol", null); + } + } +} diff --git a/java/servers/src/org/xtreemfs/utils/discover_dir.java b/java/servers/src/org/xtreemfs/utils/discover_dir.java new file mode 100644 index 0000000..8d3ff46 --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/discover_dir.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.utils; + +import org.xtreemfs.dir.discovery.DiscoveryUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.DirService; + +/** + * + * @author bjko + */ +public class discover_dir { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + System.out.println("sending XtreemFS DIR discover broadcast messages..."); + DirService dir = DiscoveryUtils.discoverDir(10); + if (dir == null) + System.out.println("no DIR service found in local network"); + else + System.out.println("found DIR service: "+dir.getProtocol()+"://"+dir.getAddress()+":"+dir.getPort()); + } + + +} diff --git a/java/servers/src/org/xtreemfs/utils/utils.java b/java/servers/src/org/xtreemfs/utils/utils.java new file mode 100644 index 0000000..2696f7f --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/utils.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.utils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.TreeMap; +import java.util.Map.Entry; + +import org.xtreemfs.foundation.util.CLIParser.CliOption; + +/** + * + * @author bjko + */ +public class utils { + + public static final String OPTION_USER_CREDS_FILE = "c"; + + public static final String OPTION_USER_CREDS_PASS = "cpass"; + + public static final String OPTION_TRUSTSTORE_FILE = "t"; + + public static final String OPTION_TRUSTSTORE_PASS = "tpass"; + + public static final String OPTION_SSL_PROTOCOL = "-ssl-protocol"; + + public static final String OPTION_HELP = "h"; + + public static final String OPTION_HELP_LONG = "-help"; + + public static final String OPTION_ADMIN_PASS = "-admin_password"; + + public static Map getxattrs(String filename) throws IOException, InterruptedException { + + File f = new File(filename); + Process p = Runtime.getRuntime().exec( + new String[] { "getfattr", "-m", "xtreemfs.*", "-d", f.getAbsolutePath() }); + p.waitFor(); + if (p.exitValue() != 0) + return null; + + Map result = new HashMap(); + + BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); + br.readLine(); // skip first line + + for (;;) { + String nextLine = br.readLine(); + if (nextLine == null) + break; + StringTokenizer st = new StringTokenizer(nextLine, "="); + if (!st.hasMoreElements()) + continue; + + String key = st.nextToken(); + String value = st.nextToken(); + + // remove leading and trailing quotes + value = value.substring(1, value.length() - 1); + value = value.replace("\\\"", "\""); + + result.put(key, value); + } + + return result; + } + + public static String getxattr(String filename, String attrname) throws IOException, InterruptedException { + + File f = new File(filename); + Process p = Runtime.getRuntime().exec( + new String[] { "getfattr", "--only-values", "-n", attrname, f.getAbsolutePath() }); + p.waitFor(); + if (p.exitValue() != 0) + return null; + + BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); + String target = br.readLine(); + + return target; + } + + public static void setxattr(String filename, String attrname, String attrvalue) throws IOException, + InterruptedException { + + File f = new File(filename); + Process p = Runtime.getRuntime().exec( + new String[] { "setfattr", "-n", attrname, "-v", attrvalue, f.getAbsolutePath() }); + p.waitFor(); + if (p.exitValue() != 0) { + String err = "a problem occurred when setting '" + attrname + "'\n"; + BufferedReader in = new BufferedReader(new InputStreamReader(p.getErrorStream())); + for (;;) { + String line = in.readLine(); + if (line == null) + break; + + err += line + "\n"; + } + throw new IOException(err); + } + } + + public static String expandPath(String path) { + File f = new File(path); + return f.getAbsolutePath(); + } + + public static boolean isXtreemFSDir(String path) throws IOException, InterruptedException { + String url = getxattr(path, "xtreemfs.url"); + return url != null; + } + + public static String findXtreemFSRootDir(String path) throws IOException, InterruptedException { + + path = expandPath(path); + + String url = getxattr(path, "xtreemfs.url"); + if (url == null) + return null; + + String parentDir = path.substring(0, path.lastIndexOf(File.separator)); + String xtfsParent = findXtreemFSRootDir(parentDir); + if (xtfsParent == null) + return path; + else + return xtfsParent; + } + + public static Map getDefaultAdminToolOptions(boolean adminPass) { + + Map options = new HashMap(); + options.put(OPTION_USER_CREDS_FILE, new CliOption(CliOption.OPTIONTYPE.STRING, + "a PKCS#12 file containing user credentials (SSL/GridSSL only)", "")); + options.put(OPTION_USER_CREDS_PASS, + new CliOption(CliOption.OPTIONTYPE.STRING, + "a pass phrase to decrypt the the user credentials file (SSL/GridSSL only). Set to '-' to prompt for the passphrase.", + "")); + options.put(OPTION_TRUSTSTORE_FILE, new CliOption(CliOption.OPTIONTYPE.STRING, + "a PKCS#12 file containing a set of certificates from trusted CAs (SSL/GridSSL only)", + "")); + options.put(OPTION_TRUSTSTORE_PASS, new CliOption(CliOption.OPTIONTYPE.STRING, + "a pass phrase to decrypt the trusted CAs file (SSL/GridSSL only). Set to '-' to prompt for the passphrase.", + "")); + options.put(OPTION_SSL_PROTOCOL, new CliOption(CliOption.OPTIONTYPE.STRING, + "SSL/TLS version to use: sslv3, ssltls, tlsv1, tlsv11, tlsv12. 'ssltls' (default) accepts all versions, " + + "the others accept only the exact version they name. 'tlsv12' is available in JDK 7+ only. " + + "'tlsv11' comes with JDK 6 or 7, depending on the vendor.", + "")); + options.put(OPTION_HELP, new CliOption(CliOption.OPTIONTYPE.SWITCH, "show usage information", "")); + options.put(OPTION_HELP_LONG, + new CliOption(CliOption.OPTIONTYPE.SWITCH, "show usage information", "")); + if (adminPass) + options.put(OPTION_ADMIN_PASS, new CliOption(CliOption.OPTIONTYPE.STRING, + "administrator password to authorize operation", "")); + + return options; + } + + public static void printOptions(Map options) { + + // sort all options by name + Map optionsMap = new TreeMap(new Comparator() { + public int compare(String o1, String o2) { + if (o1.startsWith("-") && !o2.startsWith("-")) + return 1; + if (!o1.startsWith("-") && o2.startsWith("-")) + return -1; + return o1.compareTo(o2); + } + }); + optionsMap.putAll(options); + + int maxLength = 0; + for (Entry entry : optionsMap.entrySet()) { + int len = entry.getKey().length() + entry.getValue().usageParams.length(); + if (len > maxLength) + maxLength = len; + } + + Iterator> it = optionsMap.entrySet().iterator(); + + String previous = ""; + while (it.hasNext()) { + + Entry next = it.next(); + if (next.getKey().startsWith("-") && !previous.startsWith("-")) + System.out.println(); + + StringBuffer line = new StringBuffer(); + line.append(" " + "-" + next.getKey() + " " + next.getValue().usageParams); + for (int i = 0; i < maxLength - next.getKey().length() - next.getValue().usageParams.length() + 4; i++) + line.append(" "); + line.append(next.getValue().usageText); + + System.out.println(line.toString()); + + previous = next.getKey(); + } + } +} diff --git a/java/servers/src/org/xtreemfs/utils/xtfs_benchmark/CLIOptions.java b/java/servers/src/org/xtreemfs/utils/xtfs_benchmark/CLIOptions.java new file mode 100644 index 0000000..f2255ff --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/xtfs_benchmark/CLIOptions.java @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.utils.xtfs_benchmark; + +import org.xtreemfs.common.benchmark.BenchmarkConfig; +import org.xtreemfs.common.benchmark.BenchmarkUtils; +import org.xtreemfs.common.config.ServiceConfig; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.util.CLIParser; +import org.xtreemfs.utils.DefaultDirConfig; +import org.xtreemfs.utils.utils; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.xtreemfs.common.benchmark.BenchmarkConfig.ConfigBuilder; +import static org.xtreemfs.foundation.util.CLIParser.CliOption.OPTIONTYPE.STRING; +import static org.xtreemfs.foundation.util.CLIParser.CliOption.OPTIONTYPE.SWITCH; +import static org.xtreemfs.foundation.util.CLIParser.parseCLI; + +/** + * Class implementing the commandline options for {@link xtfs_benchmark}. + * + * @author jensvfischer + */ +class CLIOptions { + private Map options; + private List arguments; + private ConfigBuilder builder; + + private static final String DIR_ADDRESSES; + private static final String OSD_SELECTION_POLICIES; + private static final String OSD_SELECTION_UUIDS; + private static final String USERNAME; + private static final String GROUPNAME; + private static final String SEQ_UNALIGNED_WRITE; + private static final String SEQ_WRITE; + private static final String SEQ_READ; + private static final String RAND_WRITE; + private static final String RAND_READ; + private static final String FILEBASED_WRITE; + private static final String FILEBASED_READ; + private static final String THREADS; + private static final String REPETITIONS; + private static final String CHUNK_SIZE; + private static final String REPLICATION_POLICY; + private static final String REPLICATION_FACTOR; + private static final String STRIPE_SIZE; + private static final String STRIPE_WITDH; + private static final String SIZE_SEQ; + private static final String SIZE_RAND; + private static final String SIZE_BASEFILE; + private static final String SIZE_FILES; + private static final String NO_CLEANUP; + private static final String NO_CLEANUP_VOLUMES; + private static final String NO_CLEANUP_BASEFILE; + private static final String OSD_CLEANUP; + private static final String CONFIG; + + static { + DIR_ADDRESSES = "-dir-addresses"; + OSD_SELECTION_POLICIES = "-osd-selection-policies"; + OSD_SELECTION_UUIDS = "-osd-selection-uuids"; + USERNAME = "-user"; + GROUPNAME = "-group"; + SEQ_WRITE = "sw"; + SEQ_READ = "sr"; + SEQ_UNALIGNED_WRITE = "usw"; + RAND_WRITE = "rw"; + RAND_READ = "rr"; + FILEBASED_WRITE = "fw"; + FILEBASED_READ = "fr"; + THREADS = "n"; + REPETITIONS = "r"; + CHUNK_SIZE = "-chunk-size"; + REPLICATION_POLICY = "-replication-policy"; + REPLICATION_FACTOR = "-replication-factor"; + STRIPE_SIZE = "-stripe-size"; + STRIPE_WITDH = "-stripe-width"; + SIZE_SEQ = "ssize"; + SIZE_RAND = "rsize"; + SIZE_BASEFILE = "-basefile-size"; + SIZE_FILES = "-file-size"; + NO_CLEANUP = "-no-cleanup"; + NO_CLEANUP_VOLUMES = "-no-cleanup-volumes"; + NO_CLEANUP_BASEFILE = "-no-cleanup-basefile"; + OSD_CLEANUP = "-osd-cleanup"; + CONFIG = "-config"; + } + + CLIOptions() { + this.options = utils.getDefaultAdminToolOptions(true); + this.builder = BenchmarkConfig.newBuilder(); + this.arguments = new ArrayList(20); + } + + void parseCLIOptions(String[] args) { + initOptions(); + parseCLI(args, options, arguments); + } + + BenchmarkConfig buildParamsFromCLIOptions() throws Exception { + setBasefileSize(); + setFileSize(); + setDirAddresses(); + setOsdSelectionPolicies(); + setOsdSelectionByUuids(); + setUsername(); + setGroup(); + setOSDPassword(); + setSSLOptions(); + setChunkSize(); + setReplicationPolicy(); + setReplicationFactor(); + setStripeSize(); + setStripeWidth(); + setNoCleanup(); + setNoCleanupOfVolumes(); + setNoCleanupOfBasefile(); + setOsdCleanup(); + setConfig(); + return builder.build(); + } + + private void initOptions() { + + /* Connection Data */ + options.put(DIR_ADDRESSES, new CLIParser.CliOption(STRING, + "directory service(s) to use (e.g. 'localhost:32638'). If no URI is specified, URI and " + + "security settings are taken from '" + DefaultDirConfig.DEFAULT_DIR_CONFIG + "' or from " + + CONFIG + ". Also accepts a list of comma-separated DIR services.", "")); + options.put(OSD_SELECTION_POLICIES, new CLIParser.CliOption(STRING, + "OSD selection policies to use when creating or opening volumes. default: 1000,3002", + "")); + options.put(OSD_SELECTION_UUIDS, new CLIParser.CliOption(STRING, + "Set the UUID-based filter policy (ID 1002) as OSD selection policy and set the uuids to be used " + + "by the policy (applied when creating or opening volumes). It is not allowed to use this option " + + "with the -" + OSD_SELECTION_POLICIES + " option. Default: No selection by UUIDs", "")); + options.put(USERNAME, new CLIParser.CliOption(STRING, "username to use", "")); + options.put(GROUPNAME, new CLIParser.CliOption(STRING, "name of group to use", "")); + options.put(CONFIG,new CLIParser.CliOption(STRING, "Config file to use. Mainly connection information like dir " + + "address and ssl settings are used. Explicit settings via commandline take precedence over settings " + + "from the config file", "")); + + /* benchmark switches */ + options.put(SEQ_WRITE, new CLIParser.CliOption(SWITCH, "sequential write benchmark", "")); + options.put(SEQ_UNALIGNED_WRITE, new CLIParser.CliOption(SWITCH, "unaligned sequential write benchmark", "")); + options.put(SEQ_READ, new CLIParser.CliOption(SWITCH, "sequential read benchmark", "")); + options.put(RAND_WRITE, new CLIParser.CliOption(SWITCH, "random write benchmark", "")); + options.put(RAND_READ, new CLIParser.CliOption(SWITCH, "random read benchmark", "")); + options.put(FILEBASED_WRITE, new CLIParser.CliOption(SWITCH, "random filebased write benchmark", "")); + options.put(FILEBASED_READ, new CLIParser.CliOption(SWITCH, "random filebased read benchmark", "")); + + options.put(THREADS, new CLIParser.CliOption(STRING, + "number of benchmarks to be started in parallel. default: 1", "")); + options.put(REPETITIONS, new CLIParser.CliOption(STRING, "number of repetitions of a benchmarks. default: 1", + "")); + options.put(CHUNK_SIZE, new CLIParser.CliOption(STRING, + "Chunk size of reads/writes in benchmark in [B|K|M|G] (no modifier assumes bytes). default: 128K", "")); + options.put(REPLICATION_POLICY, new CLIParser.CliOption(STRING, + "Replication policy to use for new volumes. default: none", "")); + options.put(REPLICATION_FACTOR, new CLIParser.CliOption(STRING, + "Replication factor to use for new volumes. default: 3", "")); + options.put(STRIPE_SIZE, new CLIParser.CliOption(STRING, + "stripeSize in [B|K|M|G] (no modifier assumes bytes). default: 128K", "")); + options.put(STRIPE_WITDH, new CLIParser.CliOption(STRING, "stripe width. default: 1", "")); + + /* sizes */ + options.put(SIZE_SEQ, new CLIParser.CliOption(STRING, + "size for sequential benchmarks in [B|K|M|G] (no modifier assumes bytes)", "")); + options.put(SIZE_RAND, new CLIParser.CliOption(STRING, + "size for random benchmarks in [B|K|M|G] (no modifier assumes bytes)", "")); + options.put(SIZE_BASEFILE, new CLIParser.CliOption(STRING, + "size of the basefile for random benchmarks in [B|K|M|G] (no modifier assumes bytes)", "")); + options.put(SIZE_FILES, new CLIParser.CliOption(STRING, + "size of the files for filebased benchmarks in [B|K|M|G] (no modifier assumes bytes)." + + " The filesize must be <= 2^31-1", "")); + + /* deletion options */ + String noCleanupDescription = "do not delete created volumes and files. Volumes and files need to be removed " + + "manually. Volumes can be removed using rmfs.xtreemfs. Files can be removed by mounting the according " + + "volume with mount.xtreemfs and deleting the files with rm"; + options.put(NO_CLEANUP, new CLIParser.CliOption(SWITCH, noCleanupDescription, "")); + + options.put(NO_CLEANUP_VOLUMES, new CLIParser.CliOption(SWITCH, + "do not delete created volumes. Created volumes neet to be removed manually using rmfs.xtreemfs", "")); + + String noCleanupBasefileDescription = "do not delete created basefile (only works with --no-cleanup or " + + "--no-cleanup-volumes. Created Files and volumes need to be removed manually"; + options.put(NO_CLEANUP_BASEFILE, new CLIParser.CliOption(SWITCH, noCleanupBasefileDescription, "")); + options.put(OSD_CLEANUP, new CLIParser.CliOption(SWITCH, "Run OSD cleanup after the benchmarks", "")); + } + + boolean usageIsSet() { + return (options.get(utils.OPTION_HELP).switchValue || options.get(utils.OPTION_HELP_LONG).switchValue); + } + + /** + * Prints out displayUsage informations + */ + void displayUsage() { + + System.out.println("\nusage: xtfs_benchmark [options] volume1 volume2 ... \n"); + System.out + .println("The number of volumes must be in accordance with the number of benchmarks run in parallel (see -p)."); + System.out + .println("All sizes can be modified with multiplication modifiers, where K means KiB, M means MiB and G means GiB. \n" + + "If no modifier is given, sizes are assumed to be in bytes."); + System.out.println(); + System.out.println(" " + "options:"); + utils.printOptions(options); + System.out.println(); + System.out.println("example: xtfs_benchmark -sw -sr -n 3 -ssize 3G volume1 volume2 volume3"); + System.out + .println("\t\t starts a sequential write and read benchmark of 3 GiB with 3 benchmarks in parallel on volume1, volume2 and volume3\n"); + } + + private void setBasefileSize() { + String optionValue; + optionValue = options.get(SIZE_BASEFILE).stringValue; + if (null != optionValue) + builder.setBasefileSizeInBytes(parseSizeWithModifierToBytes(optionValue)); + } + + private void setFileSize() { + String optionValue; + optionValue = options.get(SIZE_FILES).stringValue; + if (null != optionValue) { + long sizeInBytes = parseSizeWithModifierToBytes(optionValue); + if (sizeInBytes > Integer.MAX_VALUE) + throw new IllegalArgumentException("Filesize for filebased random IO Benchmarks must be <= 23^31-1"); + builder.setFilesize((int) sizeInBytes); + } + } + + /* if no DirAdress is given, use DirAddress from ConfigFile */ + private void setDirAddresses() { + String dirAddresses = options.get(DIR_ADDRESSES).stringValue; + if (null != dirAddresses) + builder.setDirAddresses(dirAddresses.split(",")); + } + + private void setOsdSelectionPolicies() { + String osdSelectionPolicies = options.get(OSD_SELECTION_POLICIES).stringValue; + if (null != osdSelectionPolicies) + builder.setOsdSelectionPolicies(osdSelectionPolicies); + } + + private void setOsdSelectionByUuids() { + String osdSelectionUuids = options.get(OSD_SELECTION_UUIDS).stringValue; + if (null != osdSelectionUuids) + builder.setSelectOsdsByUuid(osdSelectionUuids); + } + + private void setUsername() { + String userName = options.get(USERNAME).stringValue; + if (null != userName) + builder.setUserName(userName); + } + + private void setGroup() { + /* if no group option is given, use username as groupname */ + String groupName = options.get(GROUPNAME).stringValue; + if (null != groupName) + builder.setGroup(groupName); + else { + String userName = options.get(USERNAME).stringValue; + if (null != userName) + builder.setGroup(userName); + } + } + + private void setOSDPassword() { + String osdPassword = options.get(utils.OPTION_ADMIN_PASS).stringValue; + if (null != osdPassword) + builder.setAdminPassword(osdPassword); + } + + private void setSSLOptions() throws IOException { + + String[] dirURLs = (options.get(DIR_ADDRESSES).stringValue != null) ? options.get(DIR_ADDRESSES).stringValue + .split(",") : null; + + if (dirURLs != null) { + boolean gridSSL = false; + String dirURL = dirURLs[0]; + if (dirURL.contains(Schemes.SCHEME_PBRPCS + "://") || dirURL.contains(Schemes.SCHEME_PBRPCG + "://")) { + String serviceCredsFile = options.get(utils.OPTION_USER_CREDS_FILE).stringValue; + String serviceCredsPass = options.get(utils.OPTION_USER_CREDS_PASS).stringValue; + String trustedCAsFile = options.get(utils.OPTION_TRUSTSTORE_FILE).stringValue; + String trustedCAsPass = options.get(utils.OPTION_TRUSTSTORE_PASS).stringValue; + if (dirURL.contains(Schemes.SCHEME_PBRPCG + "://")) { + gridSSL = true; + } + if (null == serviceCredsFile) { + throw new IllegalArgumentException("SSL requires '-" + utils.OPTION_USER_CREDS_FILE + + "' parameter to be specified"); + } else if (trustedCAsFile == null) { + throw new IllegalArgumentException("SSL requires '-" + utils.OPTION_TRUSTSTORE_FILE + + "' parameter to be specified"); + } + builder.setSslOptions(true, gridSSL, serviceCredsFile, serviceCredsPass, trustedCAsFile, trustedCAsPass); + } + } + } + + private void setReplicationPolicy() { + String replicationPolicy = options.get(REPLICATION_POLICY).stringValue; + if(null != replicationPolicy) { + assert "".equals(replicationPolicy) + || "WqRq".equals(replicationPolicy) + || "WaR1".equals(replicationPolicy) : "Unknown replication policy: " + replicationPolicy; + builder.setReplicationPolicy(replicationPolicy); + } + } + + private void setReplicationFactor() { + String replicationFactor = options.get(REPLICATION_FACTOR).stringValue; + if(null != replicationFactor) + builder.setReplicationFactor(Integer.parseInt(replicationFactor)); + } + + private void setChunkSize() { + String chunkSize = options.get(CHUNK_SIZE).stringValue; + if (null != chunkSize){ + long chunkSizeInBytes = parseSizeWithModifierToBytes(chunkSize); + assert chunkSizeInBytes <= Integer.MAX_VALUE : "ChunkSize must be less equal than Integer.MAX_VALUE"; + builder.setChunkSizeInBytes((int)chunkSizeInBytes); + } + } + + private void setStripeSize() { + String stripeSize = options.get(STRIPE_SIZE).stringValue; + if (null != stripeSize) { + long stripeSizeInBytes = parseSizeWithModifierToBytes(stripeSize); + assert stripeSizeInBytes <= Integer.MAX_VALUE : "StripeSize must be less equal than Integer.MAX_VALUE"; + builder.setStripeSizeInBytes((int) stripeSizeInBytes); + } + } + + private void setStripeWidth() { + String stripeWidth = options.get(STRIPE_WITDH).stringValue; + if (null != stripeWidth) + builder.setStripeWidth(Integer.parseInt(stripeWidth)); + } + + private void setNoCleanup() { + boolean switchValue = options.get(NO_CLEANUP).switchValue; + if (switchValue) + builder.setNoCleanup(); + } + + private void setNoCleanupOfVolumes() { + boolean switchValue = options.get(NO_CLEANUP_VOLUMES).switchValue; + if (switchValue) + builder.setNoCleanupVolumes(); + } + + private void setNoCleanupOfBasefile() { + boolean switchValue = options.get(NO_CLEANUP_BASEFILE).switchValue; + if (switchValue) + builder.setNoCleanupBasefile(); + } + + private void setOsdCleanup() { + boolean switchValue = options.get(OSD_CLEANUP).switchValue; + if (switchValue) + builder.setOsdCleanup(); + } + + private void setConfig() throws IOException { + String configPath = options.get(CONFIG).stringValue; + if (null != configPath){ + ServiceConfig config = new ServiceConfig(configPath); + config.readParameters(BenchmarkConfig.getBenchmarkParameter()); + config.setDefaults(BenchmarkConfig.getBenchmarkParameter()); + builder.setParent(config); + } + } + + int getNumberOfThreads() { + String optionValue = options.get(THREADS).stringValue; + if (null != optionValue) + return Integer.valueOf(optionValue); + else + return 1; // default value + } + + long getSequentialSize() { + String optionValue; + optionValue = options.get(SIZE_SEQ).stringValue; + if (null != optionValue) + return parseSizeWithModifierToBytes(optionValue); + else + return 10L*BenchmarkUtils.MiB_IN_BYTES; // default value + } + + long getRandomSize() { + String optionValue; + optionValue = options.get(SIZE_RAND).stringValue; + if (null != optionValue) + return parseSizeWithModifierToBytes(optionValue); + else + return 10L*BenchmarkUtils.MiB_IN_BYTES; // default value + } + + int getNumberOfRepetitions() { + String optionValue = options.get(REPETITIONS).stringValue; + if (null != optionValue) + return Integer.valueOf(optionValue); + else + return 1; // default value + } + + boolean sequentialWriteBenchmarkIsSet() { + return options.get(SEQ_WRITE).switchValue; + } + + boolean unalignedSequentialWriteBenchmarkIsSet() { + return options.get(SEQ_UNALIGNED_WRITE).switchValue; + } + + boolean sequentialReadBenchmarkIsSet() { + return options.get(SEQ_READ).switchValue; + } + + boolean randomReadBenchmarkIsSet() { + return options.get(RAND_READ).switchValue; + } + + boolean randomWriteBenchmarkIsSet() { + return options.get(RAND_WRITE).switchValue; + } + + boolean randomFilebasedWriteBenchmarkIsSet() { + return options.get(FILEBASED_WRITE).switchValue; + } + + boolean randomFilebasedReadBenchmarkIsSet() { + return options.get(FILEBASED_READ).switchValue; + } + + private long parseSizeWithModifierToBytes(String size) { + size = size.toUpperCase(); + long sizeInBytes; + + if (!size.matches("[0-9]+[BKMG]?")) + throw new IllegalArgumentException("Wrong format for size."); + + if (size.matches("[0-9]+")) { + sizeInBytes = Long.valueOf(size); + } else { + char suffix = size.charAt(size.length() - 1); + long numbers = Long.valueOf(size.substring(0, size.length() - 1)); + switch (suffix) { + case 'B': + sizeInBytes = numbers; + break; + case 'K': + sizeInBytes = numbers * (long) BenchmarkUtils.KiB_IN_BYTES; + break; + case 'M': + sizeInBytes = numbers * (long) BenchmarkUtils.MiB_IN_BYTES; + break; + case 'G': + sizeInBytes = numbers * (long) BenchmarkUtils.GiB_IN_BYTES; + break; + default: + sizeInBytes = 0L; + break; + } + } + return sizeInBytes; + } + + List getArguments() { + return arguments; + } +} diff --git a/java/servers/src/org/xtreemfs/utils/xtfs_benchmark/UncaughtExceptionHandlerBenchmark.java b/java/servers/src/org/xtreemfs/utils/xtfs_benchmark/UncaughtExceptionHandlerBenchmark.java new file mode 100644 index 0000000..efbec30 --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/xtfs_benchmark/UncaughtExceptionHandlerBenchmark.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.utils.xtfs_benchmark; + +import org.xtreemfs.foundation.logging.Logging; + +/** + * UncaughtExceptionHandler for the benchmark tool. + *

    + * + * Forces exit of benchmark tool in case of uncaught exceptions. + * + * @author jensvfischer + */ +class UncaughtExceptionHandlerBenchmark implements Thread.UncaughtExceptionHandler { + + /** + * Method invoked when the given thread terminates due to the given uncaught exception. + *

    + * Any exception thrown by this method will be ignored by the Java Virtual Machine. + * + * @param t + * the thread + * @param e + * the exception + */ + @Override + public void uncaughtException(Thread t, Throwable e) { + Logging.logMessage(Logging.LEVEL_ERROR, this, + "An uncaught exception was thrown in %s. The benchmark tool will be terminated.", t.getName()); + Logging.logError(Logging.LEVEL_ERROR, this, e); + System.exit(1); + } +} diff --git a/java/servers/src/org/xtreemfs/utils/xtfs_benchmark/xtfs_benchmark.java b/java/servers/src/org/xtreemfs/utils/xtfs_benchmark/xtfs_benchmark.java new file mode 100644 index 0000000..cfa2282 --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/xtfs_benchmark/xtfs_benchmark.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.utils.xtfs_benchmark; + +import static org.xtreemfs.foundation.logging.Logging.Category; + +import java.util.*; + +import org.xtreemfs.common.benchmark.*; +import org.xtreemfs.foundation.logging.Logging; + +/** + * The commandline benchmark tool. + */ +public class xtfs_benchmark { + + private static Controller controller; + private static CLIOptions cliOptions; + + static { + cliOptions = new CLIOptions(); + Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandlerBenchmark()); + } + + /** + * Main loop of the commandline tool. + * + * @param args + * commandline options for the tool, as specified in {@link CLIOptions} + * @throws Exception + */ + public static void main(String[] args) throws Exception { + + Logging.start(6, Category.tool); + Logging.redirect(System.err); + + cliOptions.parseCLIOptions(args); + + if (cliOptions.usageIsSet()) { + cliOptions.displayUsage(); + return; + } + + BenchmarkConfig config = cliOptions.buildParamsFromCLIOptions(); + controller = new Controller(config); + controller.tryConnection(); + if (cliOptions.getArguments().size() > 0 ) + controller.setupVolumes(cliOptions.getArguments().toArray(new String[cliOptions.getArguments().size()])); + else + controller.setupDefaultVolumes(cliOptions.getNumberOfThreads()); + + ArrayList results = repeatBenchmark(); + + printResults(results); + Thread.sleep(5); + printResultsCSV(results); + controller.teardown(); + } + + /* Repeat a benchmark multiple times and pack the results. */ + private static ArrayList repeatBenchmark() + throws Exception { + + ArrayList result; + int numberOfRepetitions = cliOptions.getNumberOfRepetitions(); + ArrayList results = new ArrayList(numberOfRepetitions); + + for (int i = 0; i < numberOfRepetitions; i++) { + result = runBenchmarks(); + results.addAll(result); + } + return results; + } + + /* run all benchmarks specified by the CLIOptions */ + private static ArrayList runBenchmarks() throws Exception { + + ArrayList result; + ArrayList results = new ArrayList(); + + if (cliOptions.sequentialWriteBenchmarkIsSet()) { + result = controller.startSequentialWriteBenchmark(cliOptions.getSequentialSize(), cliOptions.getNumberOfThreads()); + results.addAll(result); + } + + if(cliOptions.unalignedSequentialWriteBenchmarkIsSet()) { + result = controller.startUnalignedSequentialWriteBenchmark(cliOptions.getSequentialSize(), cliOptions.getNumberOfThreads()); + results.addAll(result); + } + + if (cliOptions.sequentialReadBenchmarkIsSet()) { + result = controller.startSequentialReadBenchmark(cliOptions.getSequentialSize(), cliOptions.getNumberOfThreads()); + results.addAll(result); + } + + if (cliOptions.randomWriteBenchmarkIsSet()) { + result = controller.startRandomWriteBenchmark(cliOptions.getRandomSize(), cliOptions.getNumberOfThreads()); + results.addAll(result); + } + + if (cliOptions.randomReadBenchmarkIsSet()) { + result = controller.startRandomReadBenchmark(cliOptions.getRandomSize(), cliOptions.getNumberOfThreads()); + results.addAll(result); + } + + if (cliOptions.randomFilebasedWriteBenchmarkIsSet()) { + result = controller.startFilebasedWriteBenchmark(cliOptions.getRandomSize(), cliOptions.getNumberOfThreads()); + results.addAll(result); + } + + if (cliOptions.randomFilebasedReadBenchmarkIsSet()) { + result = controller.startFilebasedReadBenchmark(cliOptions.getRandomSize(), cliOptions.getNumberOfThreads()); + results.addAll(result); + } + + return results; + + } + + /* Print the results as csv. */ + private static void printResultsCSV(ArrayList results) { + System.out.println("Type;NumberOfParallelThreads;TimeInSec;MiB/Sec;DataWrittenInBytes;ByteCount"); + /* print the results */ + for (BenchmarkResult res : results) { + System.out.println(resultToCSV(res)); + } + } + + /* Print the results in a json like style. */ + private static void printResults(ArrayList results) { + /* print the results */ + for (BenchmarkResult res : results) { + System.err.println(resultToString(res)); + } + } + + /* convert a single result to json like String */ + private static String resultToString(BenchmarkResult result) { + + String dataWritten = result.getRequestedSize() >= BenchmarkUtils.GiB_IN_BYTES ? result + .getRequestedSize() / BenchmarkUtils.GiB_IN_BYTES + " GiB [" : result.getRequestedSize() + / BenchmarkUtils.MiB_IN_BYTES + " MiB ["; + String readersOrWriters; + + if (result.isWriteBenchmark()) { + readersOrWriters = "\tNumber of Writers: " + result.getNumberOfReadersOrWriters() + "\n"; + } else if (result.isReadBenchmark()) { + readersOrWriters = "\tNumber of Readers: " + result.getNumberOfReadersOrWriters() + "\n"; + } else { + readersOrWriters = "\tNumber of Readers/Writers: " + result.getNumberOfReadersOrWriters() + "\n"; + } + + return "{\n\tBenchmarkType: " + result.getBenchmarkType() + "\n" + readersOrWriters + + "\tTime: " + result.getTimeInSec() + " Sec\n" + "\tSpeed: " + getSpeedInMiBPerSec(result.getActualSize(), result.getTimeInSec()) + " MiB/s\n" + "\tData written: " + + dataWritten + result.getRequestedSize()+ " Bytes]\n" + "\tByteCount: " + result.getActualSize() + " Bytes\n" + "}"; + } + + /* convert a single result to csv */ + private static String resultToCSV(BenchmarkResult result) { + return result.getBenchmarkType() + ";" + result.getNumberOfReadersOrWriters() + ";" + + result.getTimeInSec() + ";" + getSpeedInMiBPerSec(result.getActualSize(), result.getTimeInSec()) + ";" + result.getRequestedSize() + ";" + + result.getActualSize(); + } + + /** + * Get the speed of the benchmark in MiB/Sec + * + * @return the speed of the benchmark in MiB/Sec + */ + private static double getSpeedInMiBPerSec(long size, double time) { + return round(((double) size / BenchmarkUtils.MiB_IN_BYTES) / time, 2); + } + + /* Round doubles to specified number of decimals */ + private static double round(double value, int places) { + if (places < 0) + throw new IllegalArgumentException(); + + long factor = (long) Math.pow(10, places); + value = value * factor; + long tmp = Math.round(value); + return (double) tmp / factor; + } +} diff --git a/java/servers/src/org/xtreemfs/utils/xtfs_chstatus.java b/java/servers/src/org/xtreemfs/utils/xtfs_chstatus.java new file mode 100644 index 0000000..7feb4ed --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/xtfs_chstatus.java @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.utils; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.ClientFactory; +import org.xtreemfs.common.libxtreemfs.Options; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.util.CLIParser; +import org.xtreemfs.foundation.util.CLIParser.CliOption; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.PORTS; + +/** + * + * @author bjko + */ +public class xtfs_chstatus { + + public static void main(String[] args) { + + Logging.start(Logging.LEVEL_WARN); + + Map options = utils.getDefaultAdminToolOptions(false); + List arguments = new ArrayList(1); + CliOption oDir = new CliOption( + CliOption.OPTIONTYPE.STRING, + "directory service to use (e.g. 'pbrpc://localhost:32638'). If no URI is specified, URI and security settings are taken from '" + + DefaultDirConfig.DEFAULT_DIR_CONFIG + "'", ""); + oDir.urlDefaultPort = PORTS.DIR_PBRPC_PORT_DEFAULT.getNumber(); + oDir.urlDefaultProtocol = Schemes.SCHEME_PBRPC; + options.put("dir", oDir); + + CLIParser.parseCLI(args, options, arguments); + + if (options.get(utils.OPTION_HELP).switchValue || options.get(utils.OPTION_HELP_LONG).switchValue) { + usage(options); + return; + } + + if (arguments.size() > 2 || arguments.size() < 1) + error("invalid number of arguments", options); + + String[] dirURLs = (options.get("dir").stringValue != null) ? options.get("dir").stringValue + .split(",") : null; + + SSLOptions sslOptions = null; + String[] dirAddrs = null; + + // parse security info if protocol is 'https' + if (dirURLs != null) { + int i = 0; + boolean gridSSL = false; + dirAddrs = new String[dirURLs.length]; + for (String dirURL : dirURLs) { + + // parse security info if protocol is 'https' + if (dirURL.contains(Schemes.SCHEME_PBRPCS + "://") + || dirURL.contains(Schemes.SCHEME_PBRPCG + "://") && sslOptions == null) { + String serviceCredsFile = options.get(utils.OPTION_USER_CREDS_FILE).stringValue; + String serviceCredsPass = options.get(utils.OPTION_USER_CREDS_PASS).stringValue; + if(serviceCredsPass != null && serviceCredsPass.equals("-")) { + serviceCredsPass = new String(System.console().readPassword("Enter credentials password: ")); + } + String trustedCAsFile = options.get(utils.OPTION_TRUSTSTORE_FILE).stringValue; + String trustedCAsPass = options.get(utils.OPTION_TRUSTSTORE_PASS).stringValue; + if(trustedCAsPass != null && trustedCAsPass.equals("-")) { + trustedCAsPass = new String(System.console().readPassword("Enter credentials password: ")); + } + String sslProtocolString = options.get(utils.OPTION_SSL_PROTOCOL).stringValue; + if (dirURL.contains(Schemes.SCHEME_PBRPCG + "://")) { + gridSSL = true; + } + + if (serviceCredsFile == null) { + System.out.println("SSL requires '-" + utils.OPTION_USER_CREDS_FILE + + "' parameter to be specified"); + usage(options); + System.exit(1); + } else if (trustedCAsFile == null) { + System.out.println("SSL requires '-" + utils.OPTION_TRUSTSTORE_FILE + + "' parameter to be specified"); + usage(options); + System.exit(1); + } + + // TODO: support custom SSL trust managers + try { + sslOptions = new SSLOptions(new FileInputStream(serviceCredsFile), serviceCredsPass, + SSLOptions.PKCS12_CONTAINER, new FileInputStream(trustedCAsFile), + trustedCAsPass, SSLOptions.JKS_CONTAINER, false, gridSSL, sslProtocolString, + null); + } catch (Exception e) { + System.err.println("unable to get SSL options, because:" + e.getMessage()); + System.exit(1); + } + } + + // add URL to dirAddrs + if (dirURL.contains("://")) { + // remove Protocol information + String[] tmp = dirURL.split("://"); + // remove possible slash + dirAddrs[i++] = tmp[1].replace("/", ""); + } else { + // remove possible slash + dirAddrs[i++] = dirURL.replace("/", ""); + } + } + + } + + // read default settings + if (dirURLs == null) { + + try { + DefaultDirConfig cfg = new DefaultDirConfig(); + sslOptions = cfg.getSSLOptions(); + dirAddrs = cfg.getDirectoryServices(); + } catch (Exception e) { + System.err.println("unable to get SSL options, because: " + e.getMessage()); + System.exit(1); + } + } + + final String uuid = arguments.get(0); + + String newStatusName = (arguments.size() == 2) ? arguments.get(1) : null; + + AdminClient client = ClientFactory.createAdminClient(dirAddrs, RPCAuthentication.userService, + sslOptions, new Options()); + try { + client.start(); + } catch (Exception e) { + System.err.println("unable to start client, because:"); + } + + ServiceStatus oldStatus = null; + try { + oldStatus = client.getOSDServiceStatus(uuid); + } catch (Exception e) { + System.err.println(e.getMessage()); + System.exit(1); + } + + System.out.print("current status: "); + switch (oldStatus) { + case SERVICE_STATUS_AVAIL: + System.out.println("online"); + break; + case SERVICE_STATUS_TO_BE_REMOVED: + System.out.println("locked (read-only)"); + break; + case SERVICE_STATUS_REMOVED: + System.out.println("removed"); + break; + } + + if (newStatusName != null) { + // change status + ServiceStatus newStatus = null; + if (newStatusName.equalsIgnoreCase("online")) { + newStatus = ServiceStatus.SERVICE_STATUS_AVAIL; + } else if (newStatusName.equalsIgnoreCase("locked")) { + newStatus = ServiceStatus.SERVICE_STATUS_TO_BE_REMOVED; + newStatusName = "locked (read-only)"; + } else if (newStatusName.equalsIgnoreCase("removed")) { + newStatus = ServiceStatus.SERVICE_STATUS_REMOVED; + } else { + System.out.println("unknown status name: " + newStatusName + + ". Must be 'online', ' locked' or 'removed'"); + System.exit(1); + } + try { + client.setOSDServiceStatus(uuid, newStatus); + } catch (IOException e) { + System.err.println("unable to set new status at DIR, because " + e.getMessage()); + System.exit(1); + } + System.out.println("status changed to: " + newStatusName); + } + client.shutdown(); + System.exit(0); + } + + private static void error(String message, Map options) { + System.err.println(message); + System.out.println(); + usage(options); + System.exit(1); + } + + private static void usage(Map options) { + + System.out.println("usage: xtfs_chstatus [options] [online|locked|removed]"); + System.out.println(" the registered UUID for which the status is supposed to be changed"); + System.out.println(" online - Marks the OSD as online."); + System.out.println(" locked - Marks the OSD as locked (locked OSDs will not be assigned to new files)."); + System.out.println("removed - Marks the OSD as no longer available. Replicas on this OSD can be replaced by xtfs_scrub."); + System.out.println(); + System.out.println("Options:"); + utils.printOptions(options); + } + +} diff --git a/java/servers/src/org/xtreemfs/utils/xtfs_cleanup_osd.java b/java/servers/src/org/xtreemfs/utils/xtfs_cleanup_osd.java new file mode 100644 index 0000000..62669ba --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/xtfs_cleanup_osd.java @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2009 by Felix Langner, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.utils; + +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.ClientFactory; +import org.xtreemfs.common.libxtreemfs.Options; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.CLIParser; +import org.xtreemfs.foundation.util.CLIParser.CliOption; +import org.xtreemfs.foundation.util.CLIParser.CliOption.OPTIONTYPE; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.PORTS; + +/** + * Console-tool for the cleanUp-functionality of the XtreemFS OSD. + * + * 24.04.2009 + * + * @author flangner + */ +public class xtfs_cleanup_osd { + + private static String password; + + private static AdminClient client; + + /** + * Main method. + * + * @param args + * @throws Exception + */ + public static void main(String[] args) { + Logging.start(Logging.LEVEL_WARN); + + // parse the call arguments + Map options = utils.getDefaultAdminToolOptions(true); + List arguments = new ArrayList(1); + options.put("r", new CliOption(CliOption.OPTIONTYPE.SWITCH, "restore zombies found on the OSD", "")); + options.put("e", new CliOption(CliOption.OPTIONTYPE.SWITCH, "erase potential zombies", "")); + options.put("delete_volumes", new CliOption(CliOption.OPTIONTYPE.SWITCH, + "!dangerous! deletes volumes that might be dead", "")); + CliOption oDelMeta = new CliOption(CliOption.OPTIONTYPE.NUMBER, + "delete metadata of zombie files, if the XLocSet has not been updated during the last seconds (default: 600)", + ""); + options.put("metadata_timeout", oDelMeta); + options.put("metadata_keep", new CliOption(OPTIONTYPE.SWITCH, + "keep metadata (by default metadata is deleted after seconds)", "")); + options.put("i", new CliOption(CliOption.OPTIONTYPE.SWITCH, "interactive mode", "")); + options.put("stop", new CliOption(CliOption.OPTIONTYPE.SWITCH, + "suspends the currently running cleanup process", "")); + options.put("wait", new CliOption(CliOption.OPTIONTYPE.SWITCH, + "blocks call until the currently running cleanup process has terminated", "")); + CliOption oDir = new CliOption(CliOption.OPTIONTYPE.STRING, + "directory services to use (comma separated, e.g. 'pbrpc://localhost:32638',..)", ""); + oDir.urlDefaultPort = PORTS.DIR_PBRPC_PORT_DEFAULT.getNumber(); + oDir.urlDefaultProtocol = Schemes.SCHEME_PBRPC; + options.put("dir", oDir); + options.put("v", new CliOption(CliOption.OPTIONTYPE.SWITCH, + "run a version cleanup (only if file content versioning is enabled)", "")); + + CLIParser.parseCLI(args, options, arguments); + + if (options.get(utils.OPTION_HELP).switchValue || options.get(utils.OPTION_HELP_LONG).switchValue) { + usage(options); + return; + } + + if (arguments.size() != 1) + error("invalid number of arguments", options); + + boolean remove = options.get("e").switchValue; + boolean restore = options.get("r").switchValue; + boolean deleteVolumes = options.get("delete_volumes").switchValue; + boolean interactive = options.get("i").switchValue; + boolean stop = options.get("stop").switchValue; + boolean waitForFinish = options.get("wait").switchValue; + boolean versionCleanup = options.get("v").switchValue; + + boolean removeMetadata = !options.get("metadata_keep").switchValue; + int metaDataTimeoutS = 600; + if (options.get("metadata_timeout").numValue != null) { + metaDataTimeoutS = options.get("metadata_timeout").numValue.intValue(); + } + + String[] dirURLs = (options.get("dir").stringValue != null) ? options.get("dir").stringValue + .split(",") : null; + + password = (options.get(utils.OPTION_ADMIN_PASS).stringValue != null) ? options + .get(utils.OPTION_ADMIN_PASS).stringValue : ""; + + SSLOptions sslOptions = null; + String[] dirAddrs = null; + + // read default settings for the OSD + String osdUUID = null; + if (arguments.get(0).startsWith("uuid:")) { + osdUUID = arguments.get(0).substring("uuid:".length()); + } else { + error("There was no UUID for the OSD given!", options); + } + + if (dirURLs != null) { + int i = 0; + boolean gridSSL = false; + dirAddrs = new String[dirURLs.length]; + for (String dirURL : dirURLs) { + + // parse security info if protocol is 'https' + if (dirURL.contains(Schemes.SCHEME_PBRPCS + "://") + || dirURL.contains(Schemes.SCHEME_PBRPCG + "://") && sslOptions == null) { + String serviceCredsFile = options.get(utils.OPTION_USER_CREDS_FILE).stringValue; + String serviceCredsPass = options.get(utils.OPTION_USER_CREDS_PASS).stringValue; + if(serviceCredsPass != null && serviceCredsPass.equals("-")) { + serviceCredsPass = new String(System.console().readPassword("Enter credentials password: ")); + } + String trustedCAsFile = options.get(utils.OPTION_TRUSTSTORE_FILE).stringValue; + String trustedCAsPass = options.get(utils.OPTION_TRUSTSTORE_PASS).stringValue; + if(trustedCAsPass != null && trustedCAsPass.equals("-")) { + trustedCAsPass = new String(System.console().readPassword("Enter trust store password: ")); + } + String sslProtocolString = options.get(utils.OPTION_SSL_PROTOCOL).stringValue; + if (dirURL.contains(Schemes.SCHEME_PBRPCG + "://")) { + gridSSL = true; + } + + if (serviceCredsFile == null) { + System.out.println("SSL requires '-" + utils.OPTION_USER_CREDS_FILE + + "' parameter to be specified"); + usage(options); + System.exit(1); + } else if (trustedCAsFile == null) { + System.out.println("SSL requires '-" + utils.OPTION_TRUSTSTORE_FILE + + "' parameter to be specified"); + usage(options); + System.exit(1); + } + + // TODO: support custom SSL trust managers + try { + sslOptions = new SSLOptions(new FileInputStream(serviceCredsFile), serviceCredsPass, + SSLOptions.PKCS12_CONTAINER, new FileInputStream(trustedCAsFile), + trustedCAsPass, SSLOptions.JKS_CONTAINER, false, gridSSL, sslProtocolString, + null); + } catch (Exception e) { + System.err.println("unable to get SSL options, because:" + e.getMessage()); + System.exit(1); + } + } + + // add URL to dirAddrs + if (dirURL.contains("://")) { + // remove Protocol information + String[] tmp = dirURL.split("://"); + // remove possible slash + dirAddrs[i++] = tmp[1].replace("/", ""); + } else { + // remove possible slash + dirAddrs[i++] = dirURL.replace("/", ""); + } + } + } + + // read default settings + if (dirURLs == null) { + try { + DefaultDirConfig cfg = new DefaultDirConfig(); + sslOptions = cfg.getSSLOptions(); + dirAddrs = cfg.getDirectoryServices(); + } catch (Exception e) { + System.err.println("unable to get SSL options, because: " + e.getMessage()); + System.exit(1); + } + } + + if (remove && restore) { + error("Zombies cannot be deleted and restored at the same time!", options); + } + + Options userOptions = new Options(); + UserCredentials userCredentials = UserCredentials.newBuilder().setUsername("root").addGroups("root") + .build(); + client = ClientFactory.createAdminClient(dirAddrs, userCredentials, sslOptions, userOptions); + try { + client.start(); + } catch (Exception e) { + System.err.println("unable to cleanup OSD, because:" + e.getMessage()); + System.exit(1); + } + try { + if (versionCleanup) { + client.startVersionCleanUp(osdUUID, password); + + } else if (stop) { + if (!client.isRunningCleanUp(osdUUID, password)) + error("No cleanup running on the given OSD.", options); + client.stopCleanUp(osdUUID, password); + for (String result : client.getCleanUpResult(osdUUID, password)) { + System.out.println(result); + } + System.out.println("Cleanup stopped."); + + } else if (interactive) { + if (client.isRunningCleanUp(osdUUID, password)) + client.stopCleanUp(osdUUID, password); + client.startCleanUp(osdUUID, password, remove, deleteVolumes, restore, removeMetadata, metaDataTimeoutS); + + while (client.isRunningCleanUp(osdUUID, password)) { + System.out.print(client.getCleanUpState(osdUUID, password) + "\r"); + Thread.sleep(3000); + } + System.out.println(); + for (String result : client.getCleanUpResult(osdUUID, password)) { + System.out.println(result); + } + System.out.println("Cleanup done."); + } else { + if (client.isRunningCleanUp(osdUUID, password)) { + client.stopCleanUp(osdUUID, password); + } + client.startCleanUp(osdUUID, password, remove, deleteVolumes, restore, removeMetadata, metaDataTimeoutS); + System.out.println("Cleanup is running."); + } + + if (waitForFinish) { + while (client.isRunningCleanUp(osdUUID, password)) + Thread.sleep(5000); + System.out.println("Cleanup done."); + } + + } catch (Exception e) { + System.err.println("error while running cleanup:" + e.getMessage()); + client.shutdown(); + System.exit(1); + } + client.shutdown(); + System.exit(0); + } + + /** + * Prints the error message and delegates to usage(). + * + * @param message + */ + private static void error(String message, Map options) { + System.err.println(message); + System.out.println(); + usage(options); + System.exit(1); + } + + /** + * Prints out usage information and terminates the application. + */ + public static void usage(Map options) { + + System.out.println("usage: xtfs_cleanup [options] uuid:\n"); + System.out.println(" " + " the unique identifier of the OSD to clean\n"); + System.out.println(" " + "options:"); + + utils.printOptions(options); + } +} diff --git a/java/servers/src/org/xtreemfs/utils/xtfs_mrcdbtool.java b/java/servers/src/org/xtreemfs/utils/xtfs_mrcdbtool.java new file mode 100644 index 0000000..280343b --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/xtfs_mrcdbtool.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.utils; + +import java.io.FileInputStream; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.util.CLIParser; +import org.xtreemfs.foundation.util.CLIParser.CliOption; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.PORTS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; + +public class xtfs_mrcdbtool { + + /** + * @param args + */ + public static void main(String[] args) { + + Logging.start(Logging.LEVEL_ERROR); + try { + TimeSync.initializeLocal(0); + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(1); + } + + Map options = utils.getDefaultAdminToolOptions(true); + List arguments = new ArrayList(3); + CliOption oMrc = new CliOption(CliOption.OPTIONTYPE.URL, + "MRC to use (e.g. 'pbrpc://localhost:32636')", ""); + oMrc.urlDefaultPort = PORTS.MRC_PBRPC_PORT_DEFAULT.getNumber(); + oMrc.urlDefaultProtocol = Schemes.SCHEME_PBRPC; + options.put("mrc", oMrc); + + try { + CLIParser.parseCLI(args, options, arguments); + } catch (Exception exc) { + System.out.println(exc); + usage(options); + System.exit(1); + } + + CliOption h = options.get(utils.OPTION_HELP); + CliOption help = options.get(utils.OPTION_HELP_LONG); + if (h.switchValue || help.switchValue) { + usage(options); + System.exit(0); + } + + CliOption mrc = options.get("mrc"); + if (mrc.urlValue == null) { + System.out.println("missing MRC URL"); + usage(options); + System.exit(1); + } + + if (arguments.size() < 2) { + usage(options); + System.exit(1); + } + + String op = arguments.get(0); + if (!"dump".equals(op) && !"restore".equals(op)) { + System.out.println("invalid operation: " + op); + usage(options); + System.exit(1); + } + + String dumpFile = arguments.get(1); + + CliOption c = options.get(utils.OPTION_USER_CREDS_FILE); + String cp = options.get(utils.OPTION_USER_CREDS_PASS).stringValue; + if(cp != null && cp.equals("-")) { + cp = new String(System.console().readPassword("Enter credentials password: ")); + } + CliOption t = options.get(utils.OPTION_TRUSTSTORE_FILE); + String tp = options.get(utils.OPTION_TRUSTSTORE_PASS).stringValue; + if(tp != null && tp.equals("-")) { + tp = new String(System.console().readPassword("Enter trust store password: ")); + } + + String sslProtocolString = options.get(utils.OPTION_SSL_PROTOCOL).stringValue; + + String host = mrc.urlValue.getHost(); + int port = mrc.urlValue.getPort(); + String protocol = mrc.urlValue.getProtocol(); + + RPCNIOSocketClient rpcClient = null; + + try { + SSLOptions sslOptions = null; + boolean gridSSL = false; + if (protocol.startsWith(Schemes.SCHEME_PBRPCS) || protocol.startsWith(Schemes.SCHEME_PBRPCG)) { + if (c.stringValue == null) { + System.out.println("SSL requires '-" + utils.OPTION_USER_CREDS_FILE + "' parameter to be specified"); + usage(options); + System.exit(1); + } else if (t.stringValue == null) { + System.out.println("SSL requires '-" + utils.OPTION_TRUSTSTORE_FILE + "' parameter to be specified"); + usage(options); + System.exit(1); + } + + if (protocol.startsWith(Schemes.SCHEME_PBRPCG)) { + gridSSL = true; + } + + sslOptions = new SSLOptions(new FileInputStream(c.stringValue), cp, + SSLOptions.PKCS12_CONTAINER, new FileInputStream(t.stringValue), tp, + SSLOptions.JKS_CONTAINER, false, gridSSL, sslProtocolString, null); + } + rpcClient = new RPCNIOSocketClient(sslOptions, Integer.MAX_VALUE - 1000, Integer.MAX_VALUE, "xtfs_mrcdbtool"); + rpcClient.start(); + MRCServiceClient client = new MRCServiceClient(rpcClient, new InetSocketAddress(host, port)); + + Auth passwdAuth = RPCAuthentication.authNone; + if (options.get(utils.OPTION_ADMIN_PASS).stringValue != null) + passwdAuth = Auth.newBuilder().setAuthType(AuthType.AUTH_PASSWORD).setAuthPasswd( + AuthPassword.newBuilder().setPassword(options.get(utils.OPTION_ADMIN_PASS).stringValue)).build(); + + if (op.equals("dump")) { + RPCResponse r = null; + try { + r = client.xtreemfs_dump_database(null, passwdAuth, RPCAuthentication.userService, + dumpFile); + r.get(); + } finally { + if (r != null) + r.freeBuffers(); + } + } else if (op.equals("restore")) { + RPCResponse r = null; + try { + r = client.xtreemfs_restore_database(null, passwdAuth, RPCAuthentication.userService, + dumpFile); + r.get(); + } finally { + if (r != null) + r.freeBuffers(); + } + } else { + usage(options); + System.exit(1); + } + + } catch (PBRPCException exc) { + if (exc.getPOSIXErrno() == POSIXErrno.POSIX_ERROR_EACCES) { + System.out.println("permission denied: admin password invalid or volumes exist already"); + } else { + exc.printStackTrace(); + } + } catch (Exception exc) { + exc.printStackTrace(); + } finally { + if (rpcClient != null) { + rpcClient.shutdown(); + } + } + } + + public static void usage(Map options) { + System.out.println("usage: xtfs_mrcdbtool [options] dump|restore \n"); + System.out.println(" " + " the file for the dump\n"); + System.out.println(" " + "options:"); + + utils.printOptions(options); + } + +} diff --git a/java/servers/src/org/xtreemfs/utils/xtfs_remove_osd.java b/java/servers/src/org/xtreemfs/utils/xtfs_remove_osd.java new file mode 100644 index 0000000..332ff2b --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/xtfs_remove_osd.java @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2009-2011 by Paul Seiferth, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.utils; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.CLIParser; +import org.xtreemfs.foundation.util.CLIParser.CliOption; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.osd.drain.OSDDrain; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.PORTS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; + +public class xtfs_remove_osd { + + private OSDServiceClient osd; + private DIRClient dir; + private MRCServiceClient mrc; + private RPCNIOSocketClient dirClient; + private RPCNIOSocketClient osdClient; + private RPCNIOSocketClient mrcClient; + private InetSocketAddress osdAddr; + private InetSocketAddress mrcAddr; + private SSLOptions sslOptions; + private String[] dirAddresses; + private UUIDResolver resolver; + private RPCNIOSocketClient resolverClient; + private Auth authHeader; + private UserCredentials credentials; + private String osdUUIDString; + private ServiceUUID osdUUID; + + public static void main(String[] args) { + + Map options = null; + try { + // parse the call arguments + options = utils.getDefaultAdminToolOptions(true); + List arguments = new ArrayList(1); + + CliOption oDir = new CliOption(CliOption.OPTIONTYPE.STRING, + "directory service to use (e.g. 'pbrpc://localhost:32638')", ""); + oDir.urlDefaultPort = PORTS.DIR_PBRPC_PORT_DEFAULT.getNumber(); + oDir.urlDefaultProtocol = Schemes.SCHEME_PBRPC; + options.put("dir", oDir); + options.put("s", new CliOption(CliOption.OPTIONTYPE.SWITCH, "shutdown OSD", "")); + options.put("d", new CliOption(CliOption.OPTIONTYPE.SWITCH, "enbable debug output", "")); + CLIParser.parseCLI(args, options, arguments); + + // start logging + if (options.get("d").switchValue) { + Logging.start(Logging.LEVEL_DEBUG); + } else { + Logging.start(Logging.LEVEL_ERROR); + } + + if (options.get(utils.OPTION_HELP).switchValue || options.get(utils.OPTION_HELP_LONG).switchValue + || arguments.size() == 0) { + usage(options); + return; + } + + if (arguments.size() > 1) { + // print error. + error("invalid number of arguments", options, true); + } + + boolean shutdown = options.get("s").switchValue; + String password = (options.get(utils.OPTION_ADMIN_PASS).stringValue != null) ? options + .get(utils.OPTION_ADMIN_PASS).stringValue : ""; + + String[] dirURLs = (options.get("dir").stringValue != null) ? options.get("dir").stringValue + .split(",") : null; + + // read default settings for the OSD + String osdUUID = null; + if (arguments.get(0).startsWith("uuid:")) { + osdUUID = arguments.get(0).substring("uuid:".length()); + } else { + error("There was no UUID for the OSD given!", options); + } + + SSLOptions sslOptions = null; + String[] dirAddrs = null; + + // parse security info if protocol is 'https' + if (dirURLs != null) { + int i = 0; + boolean gridSSL = false; + dirAddrs = new String[dirURLs.length]; + for (String dirURL : dirURLs) { + + // parse security info if protocol is 'https' + if (dirURL.contains(Schemes.SCHEME_PBRPCS + "://") + || dirURL.contains(Schemes.SCHEME_PBRPCG + "://") && sslOptions == null) { + String serviceCredsFile = options.get(utils.OPTION_USER_CREDS_FILE).stringValue; + String serviceCredsPass = options.get(utils.OPTION_USER_CREDS_PASS).stringValue; + if(serviceCredsPass != null && serviceCredsPass.equals("-")) { + serviceCredsPass = new String(System.console().readPassword("Enter credentials password: ")); + } + String trustedCAsFile = options.get(utils.OPTION_TRUSTSTORE_FILE).stringValue; + String trustedCAsPass = options.get(utils.OPTION_TRUSTSTORE_PASS).stringValue; + if(trustedCAsPass != null && trustedCAsPass.equals("-")) { + trustedCAsPass = new String(System.console().readPassword("Enter trust store password: ")); + } + String sslProtocolString = options.get(utils.OPTION_SSL_PROTOCOL).stringValue; + if (dirURL.contains(Schemes.SCHEME_PBRPCG + "://")) { + gridSSL = true; + } + + if (serviceCredsFile == null) { + System.out.println("SSL requires '-" + utils.OPTION_USER_CREDS_FILE + + "' parameter to be specified"); + usage(options); + System.exit(1); + } else if (trustedCAsFile == null) { + System.out.println("SSL requires '-" + utils.OPTION_TRUSTSTORE_FILE + + "' parameter to be specified"); + usage(options); + System.exit(1); + } + + // TODO: support custom SSL trust managers + try { + sslOptions = new SSLOptions(new FileInputStream(serviceCredsFile), + serviceCredsPass, SSLOptions.PKCS12_CONTAINER, new FileInputStream( + trustedCAsFile), trustedCAsPass, SSLOptions.JKS_CONTAINER, false, + gridSSL, sslProtocolString, null); + } catch (Exception e) { + System.err.println("unable to get SSL options, because:" + e.getMessage()); + System.exit(1); + } + } + + // add URL to dirAddrs + if (dirURL.contains("://")) { + // remove Protocol information + String[] tmp = dirURL.split("://"); + // remove possible slash + dirAddrs[i++] = tmp[1].replace("/", ""); + } else { + // remove possible slash + dirAddrs[i++] = dirURL.replace("/", ""); + } + } + } + + // read default settings + if (dirURLs == null) { + try { + DefaultDirConfig cfg = new DefaultDirConfig(); + sslOptions = cfg.getSSLOptions(); + dirAddrs = cfg.getDirectoryServices(); + } catch (Exception e) { + System.err.println("unable to get SSL options, because: " + e.getMessage()); + System.exit(1); + } + } + + xtfs_remove_osd removeOsd = new xtfs_remove_osd(dirAddrs, osdUUID, sslOptions, password); + removeOsd.initialize(); + removeOsd.drainOSD(shutdown); + removeOsd.shutdown(); + + System.exit(0); + + } catch (Exception e) { + + error(e.getMessage(), options); + } + } + + public xtfs_remove_osd(String[] dirAddresses, String osdUUIDString, SSLOptions sslOptions, String password) + throws Exception { + try { + + this.sslOptions = sslOptions; + this.dirAddresses = dirAddresses; + this.osdUUIDString = osdUUIDString; + if (password.equals("")) { + this.authHeader = Auth.newBuilder().setAuthType(AuthType.AUTH_NONE).build(); + } else { + this.authHeader = Auth.newBuilder().setAuthType(AuthType.AUTH_PASSWORD) + .setAuthPasswd(AuthPassword.newBuilder().setPassword(password).build()).build(); + } + + // TODO: use REAL user credentials (this is a SECURITY HOLE) + this.credentials = UserCredentials.newBuilder().setUsername("root").addGroups("root").build(); + + } catch (Exception e) { + shutdown(); + throw e; + } + } + + public void initialize() throws Exception { + + TimeSync.initializeLocal(0); + + // TODO(lukas): support multiple DIRs + // connect to DIR + dirClient = new RPCNIOSocketClient(sslOptions, 10000, 5 * 60 * 1000, "xtfs_remove_osd (dir)"); + dirClient.start(); + dirClient.waitForStartup(); + String[] dirAddr = dirAddresses[0].split(":"); + InetSocketAddress dirSocketAddr = new InetSocketAddress(dirAddr[0], Integer.parseInt(dirAddr[1])); + DIRServiceClient tmp = new DIRServiceClient(dirClient, dirSocketAddr); + dir = new DIRClient(tmp, new InetSocketAddress[] { dirSocketAddr }, 100, 15 * 1000); + + resolverClient = new RPCNIOSocketClient(sslOptions, 10000, 5 * 60 * 1000, "xtfs_remove_osd (resolver)"); + resolverClient.start(); + resolverClient.waitForStartup(); + this.resolver = UUIDResolver.startNonSingelton(dir, 1000, 10 * 10 * 1000); + + // create OSD client + osdUUID = new ServiceUUID(osdUUIDString, resolver); + osdUUID.resolve(); + osdAddr = osdUUID.getAddress(); + + osdClient = new RPCNIOSocketClient(sslOptions, 10000, 5 * 60 * 1000, "xtfs_remove_osd (osd)"); + osdClient.start(); + osdClient.waitForStartup(); + osd = new OSDServiceClient(osdClient, osdAddr); + + // create MRC client + ServiceSet sSet = null; + try { + sSet = dir.xtreemfs_service_get_by_type(null, authHeader, credentials, + ServiceType.SERVICE_TYPE_MRC); + } catch (IOException ioe) { + Logging.logMessage(Logging.LEVEL_WARN, Category.proc, new Object(), + OutputUtils.stackTraceToString(ioe)); + throw ioe; + } + + mrcClient = new RPCNIOSocketClient(sslOptions, 100000, 5 * 60 * 10000, "xtfs_remove_osd (mrc)"); + mrcClient.start(); + mrcClient.waitForStartup(); + + if (sSet.getServicesCount() == 0) { + throw new IOException("No MRC is currently registred at DIR"); + } + + String mrcUUID = sSet.getServices(0).getUuid(); + ServiceUUID UUIDService = new ServiceUUID(mrcUUID, resolver); + UUIDService.resolve(); + mrcAddr = UUIDService.getAddress(); + + mrc = new MRCServiceClient(mrcClient, mrcAddr); + + } + + public void shutdown() { + try { + resolverClient.shutdown(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Removes (drain) an OSD. + * + * @throws Exception + */ + public void drainOSD(boolean shutdown) throws Exception { + OSDDrain osdDrain = new OSDDrain(dir, osd, mrc, osdUUID, authHeader, credentials, resolver); + osdDrain.drain(shutdown); + } + + /** + * Prints the error message and delegates to usage() if "printUsage" is true. + * + * @param message + * The error message + * @param options + * The CLI Options. + * @param printUsage + * True if usage should be printed. False otherwise. + * + */ + private static void error(String message, Map options, boolean printUsage) { + System.err.println(message); + + if (printUsage) { + System.out.println(); + usage(options); + } + System.exit(1); + } + + /** + * Prints the error message and delegates to usage(). + * + * @param message + * The error message + * @param options + * The CLI Options. + */ + private static void error(String message, Map options) { + error(message, options, false); + } + + public static void usage(Map options) { + + System.out.println("usage: xtfs_remove_osd [options] uuid:\n"); + System.out.println(" " + " the unique identifier of the OSD to be removed\n"); + System.out.println(" " + "options:"); + + utils.printOptions(options); + } +} diff --git a/java/servers/src/org/xtreemfs/utils/xtfs_scrub/FileScrubber.java b/java/servers/src/org/xtreemfs/utils/xtfs_scrub/FileScrubber.java new file mode 100644 index 0000000..0203645 --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/xtfs_scrub/FileScrubber.java @@ -0,0 +1,341 @@ +package org.xtreemfs.utils.xtfs_scrub; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.libxtreemfs.AdminFileHandle; +import org.xtreemfs.common.libxtreemfs.AdminVolume; +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.InvalidChecksumException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.utils.xtfs_scrub.xtfs_scrub.FileScrubbedListener; +import org.xtreemfs.utils.xtfs_scrub.xtfs_scrub.ReturnStatus; + +public class FileScrubber implements Runnable { + + private AdminFileHandle fileHandle; + + private AdminVolume volume; + + private String fileName; + + private final FileScrubbedListener listener; + + private long nextObjectToScrub; + + /** Size of the file on the OSD(s). */ + private long byteCounter; + + private final Set removedOSDs; + + private Set returnStatus; + + private final boolean repair, delete; + + private boolean isReadOnly; + + public FileScrubber(String fileName, AdminVolume volume, FileScrubbedListener listener, + Set removedOSDs, boolean repair, boolean delete) throws PosixErrorException, + AddressToUUIDNotFoundException, IOException { + + this.volume = volume; + try { + this.fileHandle = volume.openFile(xtfs_scrub.credentials, fileName, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber()); + isReadOnly = false; + } catch (PosixErrorException e) { + this.fileHandle = volume.openFile(xtfs_scrub.credentials, fileName, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + isReadOnly = true; + } + this.fileName = fileName; + this.listener = listener; + returnStatus = new TreeSet(); + + nextObjectToScrub = 0; + byteCounter = 0; + this.removedOSDs = removedOSDs; + this.repair = repair; + this.delete = delete; + } + + public void run() { + String replicaUpdatePolicy = fileHandle.getReplicaUpdatePolicy(); + + // If file has only one replica, treat it as non replicated. + if (replicaUpdatePolicy.equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY) + && fileHandle.getReplicasList().size() > 1) { + scrubReadOnlyReplicatedFile(); + } else { + scrubRWOrNonReplicatedFile(); + } + listener.fileScrubbed(fileName, byteCounter, returnStatus); + try { + fileHandle.close(); + } catch (IOException e) { + printFileErrorMessage("unable to close file, because" + e); + } + } + + private void scrubReadOnlyReplicatedFile() { + + // Get replicas and number of objects. + List replicas = fileHandle.getReplicasList(); + long numObjs = 0; + boolean checkObjects = true; + try { + numObjs = fileHandle.getNumObjects(xtfs_scrub.credentials); + } catch (IOException ex) { + printFileErrorMessage("cannot get Number of Objects: " + ex); + checkObjects = false; + returnStatus.add(ReturnStatus.UNREACHABLE); + } + + // Read all replicas. + List removedReplicas = new LinkedList(); + for (int r = 0; r < replicas.size(); r++) { + Replica replica = replicas.get(r); + // check if an OSD was removed. + boolean isReplOnDeadOsd = false; + for (String osd : replica.getOsdUuidsList()) { + if (removedOSDs.contains(osd)) { + // Store replica for later re-creation. + removedReplicas.add(replica); + isReplOnDeadOsd = true; + break; + } + } + + // check objects only if numObjs is available and replica is not on an dead OSD + if (checkObjects & !isReplOnDeadOsd) { + try { + // This effectively marks the replica as 'complete' if not done yet. + fileHandle.checkAndMarkIfReadOnlyReplicaComplete(r, xtfs_scrub.credentials); + } catch (IOException ex) { + printFileErrorMessage("cannot mark replica# " + r + " of file " + fileName + + " as complete, because " + ex); + } + // check objects of the replica + for (long o = 0; o < numObjs; o++) { + try { + fileHandle.checkObjectAndGetSize(r, o); + } catch (InvalidChecksumException ex) { + String errormsg = ""; + if (repair) { + try { + fileHandle.repairObject(r, o); + errormsg = "object #" + o + " of replica " + r + " had an invalid checksum on OSD " + + getOSDUUIDFromObjectNo(replica, o) + " and was repaired"; + returnStatus.add(ReturnStatus.FAILURE_OBJECTS); + } catch (IOException e) { + errormsg = "object #" + o + " of replica " + r + " has an invalid checksum on OSD " + + getOSDUUIDFromObjectNo(replica, o) + " and is irreparable"; + returnStatus.add(ReturnStatus.FAILURE_OBJECTS); + } + } else { + errormsg = "object #" + o + " of replica " + r + " has an invalid checksum on OSD " + + getOSDUUIDFromObjectNo(replica, o); + returnStatus.add(ReturnStatus.FAILURE_OBJECTS); + } + printFileErrorMessage(errormsg); + } catch (IOException ex) { + printFileErrorMessage("unable to check object #" + o + " of replica " + r + ": " + ex); + returnStatus.add(ReturnStatus.UNREACHABLE); + } + } + } + } + // handle removed replicas + if (!removedReplicas.isEmpty()) { + if (repair) { + recreateReplicas(removedReplicas); + } else { + printFileErrorMessage("lost " + removedReplicas.size() + " replicas due to dead OSDs"); + } + returnStatus.add(ReturnStatus.FAILURE_REPLICAS); + } + // if everything is fine, set returnStatus to FILE_OK + if (returnStatus.size() == 0) { + returnStatus.add(ReturnStatus.FILE_OK); + } + } + + private void scrubRWOrNonReplicatedFile() { + + // Get replicas. + List replicas = fileHandle.getReplicasList(); + + // Read all replicas. + List removedReplicas = new LinkedList(); + for (int r = 0; r < replicas.size(); r++) { + Replica replica = replicas.get(r); + // Check if an OSD was removed. + boolean isReplOnDeadOsd = false; + for (String osd : replica.getOsdUuidsList()) { + if (removedOSDs.contains(osd)) { + // If file is not replicated or has only one replica, delete it. + if (fileHandle.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE) + || fileHandle.getReplicasList().size() == 1) { + String errMsg = "file data was stored on removed OSD. File is lost."; + + if (delete) { + errMsg = "file data was stored on removed OSD. File was deleted."; + try { + // Delete file. + volume.unlink(xtfs_scrub.credentials, fileName); + } catch (IOException ex2) { + errMsg = "unable to delete " + fileName + ", because: " + ex2.getMessage(); + } + } + printFileErrorMessage(errMsg); + returnStatus.add(ReturnStatus.FILE_LOST); + return; + } else { + // Store replica for later re-creation. + removedReplicas.add(replica); + isReplOnDeadOsd = true; + break; + } + } + } + if (!isReplOnDeadOsd) { + // check objects of the replica + boolean eof = false; + nextObjectToScrub = 0; + while (!eof) { + try { + int objSize = fileHandle.checkObjectAndGetSize(r, nextObjectToScrub++); + if (objSize < replica.getStripingPolicy().getStripeSize()) { + eof = true; + } + } catch (InvalidChecksumException ex) { + printFileErrorMessage("object #" + (nextObjectToScrub - 1) + " of replica " + r + + " has an invalid checksum on OSD " + replica.getOsdUuids((int) ((nextObjectToScrub - 1) % replica.getOsdUuidsCount()))); + returnStatus.add(ReturnStatus.FAILURE_OBJECTS); + break; + } catch (IOException ex) { + printFileErrorMessage("unable to check object #" + (nextObjectToScrub - 1) + + " of replica " + r + ": " + ex); + returnStatus.add(ReturnStatus.UNREACHABLE); + break; + } + } + } + } + // Handle removed replicas. + if (!removedReplicas.isEmpty()) { + if (repair) { + recreateReplicas(removedReplicas); + } else { + printFileErrorMessage("lost " + removedReplicas.size() + " replicas due to dead OSDs"); + } + returnStatus.add(ReturnStatus.FAILURE_REPLICAS); + + } + // Check file size on MRC. + try { + // Get file size on MRC and OSDs + long mrcFileSize = volume.getAttr(xtfs_scrub.credentials, fileName).getSize(); + byteCounter = fileHandle.getSizeOnOSD(); + + if (byteCounter != mrcFileSize) { + if (repair) { + // update file size on MRC + fileHandle.truncate(xtfs_scrub.credentials, byteCounter, true); + printFileErrorMessage("corrected file size from " + mrcFileSize + " to " + + byteCounter + " bytes"); + } else { + printFileErrorMessage("incorrect file size: is " + mrcFileSize + " but should be " + + byteCounter + " bytes"); + } + returnStatus.add(ReturnStatus.WRONG_FILE_SIZE); + } + } catch (IOException ex) { + printFileErrorMessage("unable to get file size: " + ex); + returnStatus.add(ReturnStatus.UNREACHABLE); + } + + // if everything is fine, set returnStatus to FILE_OK + if (returnStatus.size() == 0) { + returnStatus.add(ReturnStatus.FILE_OK); + } + } + + private void printFileErrorMessage(String error) { + System.err.format("file '%s' (%s):\n\t%s\n", fileName, fileHandle.getGlobalFileId(), error); + } + + static private String getOSDUUIDFromObjectNo(Replica replica, long objectNo) { + return replica.getOsdUuids((int) objectNo % replica.getOsdUuidsCount()); + } + + + private void recreateReplicas(List removedReplicas) { + int numReplRemoved = removedReplicas.size(); + int numNewReplicas = 0; + + for (Replica replica : removedReplicas) { + + // remove old replica + try { + volume.removeReplica(xtfs_scrub.credentials, fileName, replica.getOsdUuids(0)); + } catch (IOException ex) { + printFileErrorMessage("unable to remove replica of " + fileName + ", because: " + ex); + continue; + } + + // get suitable OSDs for re-creation + List osds; + try { + osds = volume.getSuitableOSDs(xtfs_scrub.credentials, fileName, replica.getStripingPolicy() + .getWidth()); + if (osds.size() < replica.getStripingPolicy().getWidth()) { + printFileErrorMessage("cannot create new replica, not enough OSDs available"); + continue; + } + } catch (IOException e) { + printFileErrorMessage("cannot create new replicas, unable to get suitable OSDs"); + break; + } + + // create new replica + Replica.Builder newReplicaBuilder = Replica.newBuilder(); + + // set OSDs + newReplicaBuilder.addAllOsdUuids(osds.subList(0, replica.getStripingPolicy().getWidth())); + + // recycle the replication flags of the removed replica(except for the complete + // flag) + newReplicaBuilder.setReplicationFlags(replica.getReplicationFlags() + & ~REPL_FLAG.REPL_FLAG_IS_COMPLETE.getNumber()); + + // recycle the striping policy of the removed replica + newReplicaBuilder.setStripingPolicy(replica.getStripingPolicy()); + + Replica newReplica = newReplicaBuilder.build(); + + try { + // add replica + volume.addReplica(xtfs_scrub.credentials, fileName, newReplica); + numNewReplicas++; + } catch (IOException ex) { + printFileErrorMessage("cannot create new replica: " + ex); + } + } + if (numNewReplicas == numReplRemoved) { + printFileErrorMessage("lost " + numReplRemoved + " replicas due to dead OSDs. Created " + + numReplRemoved + " new replicas."); + } else { + printFileErrorMessage("lost " + numReplRemoved + " replicas due to dead OSDs. Could only create " + + numNewReplicas + " due to a lack of suitable OSDs or communication errors."); + } + + } +} diff --git a/java/servers/src/org/xtreemfs/utils/xtfs_scrub/xtfs_scrub.java b/java/servers/src/org/xtreemfs/utils/xtfs_scrub/xtfs_scrub.java new file mode 100644 index 0000000..bf3122d --- /dev/null +++ b/java/servers/src/org/xtreemfs/utils/xtfs_scrub/xtfs_scrub.java @@ -0,0 +1,496 @@ +/* + * Copyright (c) 2009-2009 by Bjoern Kolbeck, Nele Andersen, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.utils.xtfs_scrub; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EmptyStackException; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.AdminVolume; +import org.xtreemfs.common.libxtreemfs.ClientFactory; +import org.xtreemfs.common.libxtreemfs.Options; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.VersionManagement; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.CLIParser; +import org.xtreemfs.foundation.util.CLIParser.CliOption; +import org.xtreemfs.foundation.util.OutputUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.PORTS; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.XATTR_FLAGS; +import org.xtreemfs.utils.DefaultDirConfig; +import org.xtreemfs.utils.utils; + +/** + * + * @author bjko + */ +public class xtfs_scrub { + + public static interface FileScrubbedListener { + public void fileScrubbed(String FileName, long bytesScrubbed, Collection rstatus); + } + + public static enum ReturnStatus { + FILE_OK, FILE_LOST, WRONG_FILE_SIZE, FAILURE_OBJECTS, FAILURE_REPLICAS, UNREACHABLE; + }; + + public static String latestScrubAttr = "scrubber.latestscrub"; + + public static final UserCredentials credentials; + + static { + credentials = UserCredentials.newBuilder().setUsername("root").addGroups("root").build(); + } + + private static final int DEFAULT_NUM_THREADS = 10; + + private AdminVolume volume; + + private final boolean repair, delete, silent; + + private final ExecutorService tPool; + + private long lastBytesScrubbed; + + private final Stack directories; + + private final Stack files; + + private final Object completeLock; + + private int returnCode; + + private int numInFlight; + + private final int numThrs; + + private boolean hasFinished; + + private boolean isLatestScrubAttrSettable; + + private String currentDirName = null; + + private int numFiles, numReplicaFailure, numObjectFailure, numFileOk, + numUnreachable, numWrongFS, numDead; + + private final Set removedOSDs; + + public xtfs_scrub(AdminClient client, AdminVolume volume, int numThrs, boolean repair, boolean delete, + boolean silent) throws IOException { + this.repair = repair; + this.delete = delete; + this.silent = silent; + this.numThrs = numThrs; + directories = new Stack(); + files = new Stack(); + tPool = Executors.newFixedThreadPool(numThrs); + numInFlight = 0; + completeLock = new Object(); + hasFinished = false; + isLatestScrubAttrSettable = true; + + this.volume = volume; + + numFiles = 0; + numReplicaFailure = 0; + numObjectFailure = 0; + numFileOk = 0; + numUnreachable = 0; + + if (!repair && !delete) { + System.out.println("running in check mode, no changes to files will be made"); + } else { + if (repair) + System.out.println("running in repair mode"); + if (delete) + System.out + .println("WARNING: delete is enabled, corrupt files (data lost due to failed OSDs) will be deleted"); + } + + removedOSDs = client.getRemovedOsds(); + + if (removedOSDs.size() > 0) { + System.out + .println("list of OSDs that have been removed (replicas on these OSDs will be deleted):"); + for (String uuid : removedOSDs) { + System.out.println("\t" + uuid); + } + } + + } + + public int scrub() { + + System.out.println(""); + directories.push("/"); + // create scrub xattr if not done yet + try { + volume.setXAttr(credentials, "/", latestScrubAttr, Long.toString(TimeSync.getLocalSystemTime()), + XATTR_FLAGS.XATTR_FLAGS_CREATE); + } catch (PosixErrorException e) { + // scrub xattr already exists, nothing to do here. + + } catch (IOException e) { + isLatestScrubAttrSettable = false; + System.out.println("\nWarning: cannot mark volume as scrubbed: " + e); + } + fillQueue(); + synchronized (completeLock) { + try { + if (!hasFinished) { + completeLock.wait(); + } + } catch (InterruptedException ex) { + } + } + tPool.shutdown(); + try { + tPool.awaitTermination(1, TimeUnit.HOURS); + } catch (InterruptedException e) { + } + + if (!silent) + System.out.format("scrubbed %-42s %15s - total %15s\n\u001b[100D\u001b[A", "all files", "", + OutputUtils.formatBytes(lastBytesScrubbed)); + + System.out.println("\n\nsummary:"); + System.out.println("files checked : " + numFiles); + System.out.println(" files ok : " + numFileOk); + System.out.println(" files corrupted : " + (numFiles - numFileOk)); + System.out.println(" of which had lost replicas (caused by removed OSDs) : " + numReplicaFailure); + System.out.println(" of which had corrupted objects (caused by invalid checksums): " + numObjectFailure); + System.out.println(" of which had a wrong file size : " + numWrongFS); + System.out.println(" of which are lost (unrecoverable) : " + numDead); + System.out.println(" of which are unreachable (caused by communication errors) : " + numUnreachable); + System.out.println("bytes checked : " + OutputUtils.formatBytes(lastBytesScrubbed)); + + return returnCode; + } + + private void fillQueue() { + try { + synchronized (directories) { + while (numInFlight < numThrs) { + try { + String fileName = files.pop(); + try { + + FileScrubbedListener fsListener = new FileScrubbedListener() { + public void fileScrubbed(String fileName, long bytesScrubbed, + Collection rstatus) { + xtfs_scrub.this.fileScrubbed(fileName, bytesScrubbed, rstatus); + } + }; + + FileScrubber fi = new FileScrubber(fileName, volume, fsListener, removedOSDs, + repair, delete); + tPool.submit(fi); + numInFlight++; + } catch (IOException ex) { + Logging.logError(Logging.LEVEL_WARN, this, ex); + } + } catch (EmptyStackException ex) { + // fetch next dir + fetchNextDir(); + } + } + } + } catch (EmptyStackException ex) { + // no more entries, finished! + if (isLatestScrubAttrSettable) { + try { + // mark volume as scrubbed + volume.setXAttr(credentials, "/", latestScrubAttr, + Long.toString(TimeSync.getLocalSystemTime()), XATTR_FLAGS.XATTR_FLAGS_REPLACE); + + } catch (IOException ex2) { + System.out.println("\nWarning: cannot mark volume as successfully scrubbed: " + ex2); + } + } + + finish(0); + return; + } + } + + private void finish(int returnCode) { + synchronized (directories) { + if (numInFlight == 0) { + synchronized (completeLock) { + this.returnCode = returnCode; + this.hasFinished = true; + completeLock.notifyAll(); + } + } + } + + } + + public void fileScrubbed(String fileName, long bytesScrubbed, Collection rs) { + + // update statistics + + if (fileName.length() > 42) { + fileName = "..." + fileName.substring(fileName.length() - 39, fileName.length()); + } + synchronized (directories) { + lastBytesScrubbed += bytesScrubbed; + numFiles++; + for (ReturnStatus status : rs) { + switch (status) { + case FILE_OK: + numFileOk++; + break; + case WRONG_FILE_SIZE: + numWrongFS++; + break; + case UNREACHABLE: + numUnreachable++; + break; + case FILE_LOST: + numDead++; + break; + case FAILURE_REPLICAS: + numReplicaFailure++; + break; + case FAILURE_OBJECTS: + numObjectFailure++; + break; + } + } + if (!silent) + System.out.format("scrubbed %-42s with %15s - total %15s\n\u001b[100D\u001b[A", fileName, + OutputUtils.formatBytes(bytesScrubbed), OutputUtils.formatBytes(lastBytesScrubbed)); + numInFlight--; + fillQueue(); + } + + } + + private void fetchNextDir() { + currentDirName = directories.pop(); + + try { + + DirectoryEntries ls = volume.readDir(credentials, currentDirName, 0, 0, false); + + if (ls == null) { + Logging.logMessage(Logging.LEVEL_ERROR, this, "path %s does not exist!", currentDirName); + return; + } + + for (int i = 0; i < ls.getEntriesCount(); i++) { + DirectoryEntry e = ls.getEntries(i); + if ((e.getStbuf().getMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFREG.getNumber()) != 0) { + // regular file + files.push(currentDirName + e.getName()); + } else if ((e.getStbuf().getMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFDIR.getNumber()) != 0) { + if (!e.getName().equals(".") && !e.getName().equals("..")) + directories.push(currentDirName + e.getName() + "/"); + } + } + } catch (IOException ex) { + System.err.println("cannot contact MRC... aborting"); + System.err.println(ex); + } catch (Exception ex) { + ex.printStackTrace(); + throw new EmptyStackException(); + } + + } + + public static void main(String[] args) { + + Logging.start(Logging.LEVEL_WARN); + + System.out.println("XtreemFS scrubber version " + VersionManagement.RELEASE_VERSION + + " (file system data integrity check)\n"); + + Map options = utils.getDefaultAdminToolOptions(false); + List arguments = new ArrayList(1); + CliOption oDir = new CliOption( + CliOption.OPTIONTYPE.STRING, + "directory service to use (e.g. 'pbrpc://localhost:32638'). If no URI is specified, URI and security settings are taken from '" + + DefaultDirConfig.DEFAULT_DIR_CONFIG + "'", ""); + oDir.urlDefaultPort = PORTS.DIR_PBRPC_PORT_DEFAULT.getNumber(); + oDir.urlDefaultProtocol = Schemes.SCHEME_PBRPC; + options.put("dir", oDir); + options.put("repair", new CliOption(CliOption.OPTIONTYPE.SWITCH, + "repair files (update file size, replace replicas) when possible", "")); + options.put("delete", new CliOption(CliOption.OPTIONTYPE.SWITCH, + "delete lost files (incomplete due to OSD failures)", "")); + options.put("silent", new CliOption(CliOption.OPTIONTYPE.SWITCH, "don't show the progress bar", "")); + options.put("thrs", new CliOption(CliOption.OPTIONTYPE.NUMBER, + "number of concurrent file scrub threads (default=" + DEFAULT_NUM_THREADS + ")", "n")); + + CLIParser.parseCLI(args, options, arguments); + + if (arguments.size() != 1) + error("invalid number of arguments", options); + + if (options.get(utils.OPTION_HELP).switchValue || options.get(utils.OPTION_HELP_LONG).switchValue) { + usage(options); + System.exit(0); + } + + String[] dirURLs = (options.get("dir").stringValue != null) ? options.get("dir").stringValue + .split(",") : null; + + SSLOptions sslOptions = null; + String[] dirAddrs = null; + + if (dirURLs != null) { + int i = 0; + boolean gridSSL = false; + dirAddrs = new String[dirURLs.length]; + for (String dirURL : dirURLs) { + + // parse security info if protocol is 'https' + if (dirURL.contains(Schemes.SCHEME_PBRPCS + "://") + || dirURL.contains(Schemes.SCHEME_PBRPCG + "://") && sslOptions == null) { + String serviceCredsFile = options.get(utils.OPTION_USER_CREDS_FILE).stringValue; + String serviceCredsPass = options.get(utils.OPTION_USER_CREDS_PASS).stringValue; + if(serviceCredsPass != null && serviceCredsPass.equals("-")) { + serviceCredsPass = new String(System.console().readPassword("Enter credentials password: ")); + } + String trustedCAsFile = options.get(utils.OPTION_TRUSTSTORE_FILE).stringValue; + String trustedCAsPass = options.get(utils.OPTION_TRUSTSTORE_PASS).stringValue; + if(trustedCAsPass != null && trustedCAsPass.equals("-")) { + trustedCAsPass = new String(System.console().readPassword("Enter trust store password: ")); + } + String sslProtocolString = options.get(utils.OPTION_SSL_PROTOCOL).stringValue; + if (dirURL.contains(Schemes.SCHEME_PBRPCG + "://")) { + gridSSL = true; + } + + if (serviceCredsFile == null) { + System.out.println("SSL requires '-" + utils.OPTION_USER_CREDS_FILE + + "' parameter to be specified"); + usage(options); + System.exit(1); + } else if (trustedCAsFile == null) { + System.out.println("SSL requires '-" + utils.OPTION_TRUSTSTORE_FILE + + "' parameter to be specified"); + usage(options); + System.exit(1); + } + + // TODO: support custom SSL trust managers + try { + sslOptions = new SSLOptions(new FileInputStream(serviceCredsFile), serviceCredsPass, + SSLOptions.PKCS12_CONTAINER, new FileInputStream(trustedCAsFile), + trustedCAsPass, SSLOptions.JKS_CONTAINER, false, gridSSL, sslProtocolString, + null); + } catch (Exception e) { + System.err.println("unable to set up SSL, because:" + e.getMessage()); + System.exit(1); + } + } + + // add URL to dirAddrs + if (dirURL.contains("://")) { + // remove Protocol information + String[] tmp = dirURL.split("://"); + // remove possible slash + dirAddrs[i++] = tmp[1].replace("/", ""); + } else { + // remove possible slash + dirAddrs[i++] = dirURL.replace("/", ""); + } + } + } + + // read default settings + if (dirURLs == null) { + try { + DefaultDirConfig cfg = new DefaultDirConfig(); + sslOptions = cfg.getSSLOptions(); + dirAddrs = cfg.getDirectoryServices(); + } catch (Exception e) { + System.err.println("unable to get SSL options, because: " + e.getMessage()); + System.exit(1); + } + } + + boolean repair = options.get("repair").switchValue; + boolean silent = options.get("silent").switchValue; + boolean delete = options.get("delete").switchValue; + + int numThreads = DEFAULT_NUM_THREADS; + if (options.get("thrs").numValue != null) { + numThreads = options.get("thrs").numValue.intValue(); + } + + final String volumeName = arguments.get(0); + + Options userOptions = new Options(); + + AdminClient c = ClientFactory.createAdminClient(dirAddrs, credentials, sslOptions, userOptions); + AdminVolume volume = null; + try { + c.start(); + volume = c.openVolume(volumeName, sslOptions, new Options()); + volume.start(); + } catch (Exception e) { + System.err.println("unable to scrub Volume, because: " + e.getMessage()); + System.exit(1); + } + + int exitCode = 1; + try { + + xtfs_scrub scrubber = new xtfs_scrub(c, volume, numThreads, repair, delete, silent); + exitCode = scrubber.scrub(); + if (exitCode == 0) { + System.out.println("\n\nsuccessfully scrubbed volume '" + volumeName + "'"); + } else { + System.out.println("\n\nscrubbing volume '" + volumeName + "' FAILED!"); + } + + System.exit(exitCode); + } catch (Exception e) { + System.err.println("unable to scrub Volume, because: " + e.getMessage()); + System.exit(1); + } + c.shutdown(); + + } + + private static void error(String message, Map options) { + System.err.println(message); + System.out.println(); + usage(options); + System.exit(1); + } + + private static void usage(Map options) { + System.out.println("usage: xtfs_scrub [options] "); + System.out.println(" the volume to scrub\n"); + System.out.println("options:"); + + utils.printOptions(options); + } +} diff --git a/java/servers/test/org/xtreemfs/common/clients/ClientTest.java b/java/servers/test/org/xtreemfs/common/clients/ClientTest.java new file mode 100644 index 0000000..4641c16 --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/clients/ClientTest.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.net.InetSocketAddress; +import java.util.LinkedList; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class ClientTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment testEnv; + + private static final String VOLUME_NAME = "testvol"; + + private UserCredentials uc; + + public ClientTest() { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_CLIENT, + TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.UUID_RESOLVER, TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.MRC, TestEnvironment.Services.OSD }); + testEnv.start(); + + uc = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + RPCResponse r = testEnv.getMrcClient().xtreemfs_mkvol(testEnv.getMRCAddress(), RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, SetupUtils.getStripingPolicy(64, 1), "", 0777, + VOLUME_NAME, "test", "test", new LinkedList(), 0); + r.get(); + r.freeBuffers(); + } + + @After + public void tearDown() { + testEnv.shutdown(); + } + + @Test + public void testMDOps() throws Exception { + + final Client c = new Client(new InetSocketAddress[] { testEnv.getDIRAddress() }, 15000, 300000, null); + c.start(); + + Volume v = c.getVolume(VOLUME_NAME, uc); + + long fspace = v.getFreeSpace(); + long uspace = v.getUsedSpace(); + System.out.println("free/used: " + fspace + "/" + uspace); + + File dir = v.getFile("dir"); + dir.mkdir(0777); + + String[] entries = v.list("/"); + assertEquals(3, entries.length); + assertEquals("dir", entries[2]); + + entries = v.list("/dir/"); + assertEquals(2, entries.length); + + assertTrue(dir.isDirectory()); + assertFalse(dir.isFile()); + assertTrue(dir.exists()); + + File file = v.getFile("/dir/file"); + file.createFile(); + assertFalse(file.isDirectory()); + assertTrue(file.isFile()); + assertTrue(file.exists()); + + File file2 = v.getFile("/file2"); + file.renameTo(file2); + + assertFalse(file.exists()); + assertTrue(file2.exists()); + + entries = v.list("/"); + assertEquals(4, entries.length); + + file2.delete(); + + c.stop(); + + } + + @Test + public void testMDOps2() throws Exception { + + final Client c = new Client(new InetSocketAddress[] { testEnv.getDIRAddress() }, 15000, 300000, null); + c.start(); + + UserCredentials rootCreds = UserCredentials.newBuilder().setUsername("root").addGroups("root").build(); + Volume v = c.getVolume(VOLUME_NAME, rootCreds); + + File f = v.getFile("/test"); + f.createFile(); + f.chown("someone"); + f.chgrp("somegroup"); + f.chmod(0777); + + Stat stat = f.stat(); + assertEquals("someone", stat.getUserId()); + assertEquals("somegroup", stat.getGroupId()); + assertEquals(0777, stat.getMode() & 0777); + + Map acl = f.getACL(); + assertEquals(0, acl.size()); + + acl.put("u:", "rwx"); + acl.put("g:", "rwx"); + f.setACL(acl); + + acl = f.getACL(); + assertEquals("rwx", acl.get("u:")); + assertEquals("rwx", acl.get("g:")); + + acl.clear(); + acl.put("u:test", "r"); + acl.put("g:test", "r"); + f.setACL(acl); + + acl = f.getACL(); + assertEquals("r--", acl.get("u:test")); + assertEquals("r--", acl.get("g:test")); + + acl.clear(); + f.setACL(acl); + + acl = f.getACL(); + assertFalse(acl.containsKey("u:test")); + assertFalse(acl.containsKey("g:test")); + } + + @Test + public void testData() throws Exception { + + final Client c = new Client(new InetSocketAddress[] { testEnv.getDIRAddress() }, 15000, 300000, null); + c.start(); + + Volume v = c.getVolume(VOLUME_NAME, uc); + + File f = v.getFile("/test"); + + RandomAccessFile ra = f.open("rw", 0555); + ra.seek(2); + + byte[] data = new byte[2048]; + int wbytes = ra.write(data, 0, data.length); + assertEquals(2048, wbytes); + + ra.seek(0); + int rbytes = ra.read(data, 0, data.length); + assertEquals(2048, rbytes); + + ra.seek(2); + rbytes = ra.read(data, 0, data.length); + assertEquals(2048, rbytes); + + ra.seek(4); + rbytes = ra.read(data, 0, data.length); + assertEquals(2048 - 2, rbytes); + + ra.close(); + + c.stop(); + + } + +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/common/clients/ReplicatedClientTest.java b/java/servers/test/org/xtreemfs/common/clients/ReplicatedClientTest.java new file mode 100644 index 0000000..6b4dfb6 --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/clients/ReplicatedClientTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients; + +import static org.junit.Assert.assertTrue; + +import java.net.InetSocketAddress; +import java.util.LinkedList; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class ReplicatedClientTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment testEnv; + + private static final String VOLUME_NAME = "testvol"; + + private UserCredentials uc; + + public ReplicatedClientTest() { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_CLIENT, + TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.UUID_RESOLVER, TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.MRC, TestEnvironment.Services.OSD, TestEnvironment.Services.OSD, + TestEnvironment.Services.OSD}); + testEnv.start(); + + uc = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + RPCResponse r = testEnv.getMrcClient().xtreemfs_mkvol(testEnv.getMRCAddress(), RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, SetupUtils.getStripingPolicy(1, 64), "", 0777, VOLUME_NAME, "test", "test", new LinkedList(), 0); + r.get(); + r.freeBuffers(); + } + + @After + public void tearDown() { + testEnv.shutdown(); + } + + // TODO add test methods here. + // The methods must be annotated with annotation @Test. For example: + // + // @Test + // public void hello() {} + + @Test + public void testAddRemoveReplica() throws Exception { + + final Client c = new Client(new InetSocketAddress[]{testEnv.getDIRAddress()}, 15000, 300000, null); + c.start(); + + Volume v = c.getVolume(VOLUME_NAME,uc); + + File f = v.getFile("test.file"); + RandomAccessFile raf = f.open("rw", 0666); + byte[] data = new byte[4096]; + raf.write(data, 0, data.length); + raf.seek(3*64*1024); + raf.write(data, 0, data.length); + raf.close(); + + f.setReadOnly(true); + + String[] osds = f.getSuitableOSDs(1); + assertTrue(osds.length >= 1); + // System.out.println("suitable OSD: "+osds[0]); + + f.addReplica(1, osds, ReplicationFlags.setRandomStrategy(ReplicationFlags.setFullReplica(0))); + + // System.out.println("locations: "+f.getLocations(uc)); + + Thread.sleep(1000); + + for (Replica r : f.getReplicas(uc)) { + r.isCompleteReplica(); + } + + raf = f.open("r", 0666); + raf.read(data, 0, data.length); + raf.close(); + + // System.out.println("locations: "+f.getLocations(uc)); + + for (Replica r : f.getReplicas(uc)) { + assertTrue(r.isCompleteReplica()); + } + + f.getReplica(0).removeReplica(true); + + c.stop(); + + + } + +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/common/clients/internal/RAID0ObjectMapperTest.java b/java/servers/test/org/xtreemfs/common/clients/internal/RAID0ObjectMapperTest.java new file mode 100644 index 0000000..e5b3092 --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/clients/internal/RAID0ObjectMapperTest.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.clients.internal; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.clients.internal.ObjectMapper.ObjectRequest; +import org.xtreemfs.common.xloc.Replica; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class RAID0ObjectMapperTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + /** + * Test of readRequest method, of class RAID0ObjectMapper. + */ + @Test + public void testReadRequest() { + StripingPolicy sp = SetupUtils.getStripingPolicy(3, 7); + List s = new ArrayList(3); + s.add("1"); + s.add("2"); + s.add("3"); + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica tmpR = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.newBuilder(). + addAllOsdUuids(s).setStripingPolicy(sp).setReplicationFlags(0).build(); + + Replica r = new Replica(tmpR,null); + + + RAID0ObjectMapper instance = new RAID0ObjectMapper(sp); + + List result = instance.readRequest(7*1024, 0, r); + assertEquals(1, result.size()); + assertEquals(0, result.get(0).getObjNo()); + assertEquals(0, result.get(0).getOffset()); + assertEquals(7*1024, result.get(0).getLength()); + assertEquals("1", result.get(0).getOsdUUID().toString()); + + result = instance.readRequest(5*1024, 2*1024, r); + assertEquals(1, result.size()); + assertEquals(0, result.get(0).getObjNo()); + assertEquals(2*1024, result.get(0).getOffset()); + assertEquals(5*1024, result.get(0).getLength()); + assertEquals("1", result.get(0).getOsdUUID().toString()); + + result = instance.readRequest(8*1024, 0, r); + assertEquals(2, result.size()); + assertEquals(0, result.get(0).getObjNo()); + assertEquals(0, result.get(0).getOffset()); + assertEquals(7*1024, result.get(0).getLength()); + assertEquals("1", result.get(0).getOsdUUID().toString()); + + assertEquals(1, result.get(1).getObjNo()); + assertEquals(0, result.get(1).getOffset()); + assertEquals(1*1024, result.get(1).getLength()); + assertEquals("2", result.get(1).getOsdUUID().toString()); + + result = instance.readRequest(14*1024, 0, r); + assertEquals(2, result.size()); + assertEquals(0, result.get(0).getObjNo()); + assertEquals(0, result.get(0).getOffset()); + assertEquals(7*1024, result.get(0).getLength()); + assertEquals("1", result.get(0).getOsdUUID().toString()); + + assertEquals(1, result.get(1).getObjNo()); + assertEquals(0, result.get(1).getOffset()); + assertEquals(7*1024, result.get(1).getLength()); + assertEquals("2", result.get(1).getOsdUUID().toString()); + + result = instance.readRequest(14*1024, 2*1024, r); + assertEquals(3, result.size()); + assertEquals(0, result.get(0).getObjNo()); + assertEquals(2*1024, result.get(0).getOffset()); + assertEquals(5*1024, result.get(0).getLength()); + assertEquals("1", result.get(0).getOsdUUID().toString()); + + assertEquals(1, result.get(1).getObjNo()); + assertEquals(0, result.get(1).getOffset()); + assertEquals(7*1024, result.get(1).getLength()); + assertEquals("2", result.get(1).getOsdUUID().toString()); + + assertEquals(2, result.get(2).getObjNo()); + assertEquals(0, result.get(2).getOffset()); + assertEquals(2*1024, result.get(2).getLength()); + assertEquals("3", result.get(2).getOsdUUID().toString()); + + } + + + /** + * Test of readRequest method, of class RAID0ObjectMapper. + */ + @Test + public void testWriteRequest() { + StripingPolicy sp = SetupUtils.getStripingPolicy(3, 7); + List s = new ArrayList(3); + s.add("1"); + s.add("2"); + s.add("3"); + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica tmpR = + org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica.newBuilder(). + addAllOsdUuids(s).setStripingPolicy(sp).setReplicationFlags(0).build(); + + Replica r = new Replica(tmpR,null); + + RAID0ObjectMapper instance = new RAID0ObjectMapper(sp); + + byte[] bytes = new byte[14*1024]; + for (int i = 0; i < bytes.length; i++) + bytes[i] = 'a'; + ReusableBuffer data = ReusableBuffer.wrap(bytes); + data.position(0); + + List result = instance.writeRequest(data, 2*1024, r); + assertEquals(3, result.size()); + assertEquals(0, result.get(0).getObjNo()); + assertEquals(2*1024, result.get(0).getOffset()); + assertEquals(5*1024, result.get(0).getLength()); + assertEquals("1", result.get(0).getOsdUUID().toString()); + assertEquals(5*1024, result.get(0).getData().capacity()); + + assertEquals(1, result.get(1).getObjNo()); + assertEquals(0, result.get(1).getOffset()); + assertEquals(7*1024, result.get(1).getLength()); + assertEquals("2", result.get(1).getOsdUUID().toString()); + assertEquals(7*1024, result.get(1).getData().capacity()); + assertEquals(7*1024, result.get(1).getData().remaining()); + + assertEquals(2, result.get(2).getObjNo()); + assertEquals(0, result.get(2).getOffset()); + assertEquals(2*1024, result.get(2).getLength()); + assertEquals("3", result.get(2).getOsdUUID().toString()); + assertEquals(2*1024, result.get(2).getData().capacity()); + + + } + +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/common/libxtreemfs/ClientTest.java b/java/servers/test/org/xtreemfs/common/libxtreemfs/ClientTest.java new file mode 100644 index 0000000..f026d00 --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/libxtreemfs/ClientTest.java @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import static org.junit.Assert.assertEquals; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.mrc.MRCConfig; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +public class ClientTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static DIRRequestDispatcher dir; + + private static TestEnvironment testEnv; + + private static DIRConfig dirConfig; + + private static UserCredentials userCredentials; + + private static Auth auth = RPCAuthentication.authNone; + + private static DIRClient dirClient; + + private static final int NUMBER_OF_OSDS = 2; + + private static OSDConfig osdConfigs[]; + + private static OSD osds[]; + + private static MRCConfig mrc2Config; + + private static MRCRequestDispatcher mrc2; + + @BeforeClass + public static void initializeTest() throws Exception { + FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + dirConfig = SetupUtils.createDIRConfig(); + osdConfigs = SetupUtils.createMultipleOSDConfigs(NUMBER_OF_OSDS); + + dir = new DIRRequestDispatcher(dirConfig, SetupUtils.createDIRdbsConfig()); + dir.startup(); + dir.waitForStartup(); + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_CLIENT, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.RPC_CLIENT, + TestEnvironment.Services.MRC }); + testEnv.start(); + + userCredentials = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + dirClient = new DIRClient(new DIRServiceClient(testEnv.getRpcClient(), null), + new InetSocketAddress[] { testEnv.getDIRAddress() }, 3, 1000); + + // start second MRC + mrc2Config = SetupUtils.createMRC2Config(); + mrc2 = new MRCRequestDispatcher(mrc2Config, SetupUtils.createMRC2dbsConfig()); + mrc2.startup(); + + osds = new OSD[NUMBER_OF_OSDS]; + for (int i = 0; i < osds.length; i++) { + osds[i] = new OSD(osdConfigs[i]); + } + } + + @AfterClass + public static void shutdownTest() throws Exception { + + for (int i = 0; i < osds.length; i++) { + if (osds[i] != null) { + osds[i].shutdown(); + } + } + + if (mrc2 != null) { + mrc2.shutdown(); + mrc2 = null; + } + + testEnv.shutdown(); + dir.shutdown(); + dir.waitForShutdown(); + } + + @Test + public void testCreateOpenRemoveListVolume() throws Exception { + + final String VOLUME_NAME_1 = "testCreateOpenRemoveListVolume"; + + Options options = new Options(); + + String dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + String mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + // Create volume + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME_1); + + ServiceSet sSet = null; + sSet = dirClient.xtreemfs_service_get_by_name(testEnv.getDIRAddress(), auth, userCredentials, + VOLUME_NAME_1); + + assertEquals(1, sSet.getServicesCount()); + assertEquals(VOLUME_NAME_1, sSet.getServices(0).getName()); + + // List volumes + Volumes volumes = client.listVolumes(mrcAddress); + assertEquals(1, volumes.getVolumesCount()); + assertEquals(VOLUME_NAME_1, volumes.getVolumes(0).getName()); + + // Delete volume + client.deleteVolume(mrcAddress, auth, userCredentials, VOLUME_NAME_1); + + sSet = null; + sSet = dirClient.xtreemfs_service_get_by_name(testEnv.getDIRAddress(), auth, userCredentials, + VOLUME_NAME_1); + + assertEquals(0, sSet.getServicesCount()); + + // List volumes + volumes = client.listVolumes(mrcAddress); + assertEquals(0, volumes.getVolumesCount()); + + // shutdown the client + client.shutdown(); + } + + @Test + public void testCreateOpenRemoveListVolumeMultipleMRCs() throws Exception { + + final String VOLUME_NAME_1 = "testCreateOpenRemoveListVolumeMultipleMRCs"; + + Options options = new Options(); + + String dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + // Create MRC Address List + String invalidMrcAddress = "ThereIsNoMRC.org:36592"; + String mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + String mrc2Address = mrc2Config.getHostName() + ":" + mrc2Config.getPort(); + List mrcAddressList = new ArrayList(); + mrcAddressList.add(invalidMrcAddress); + mrcAddressList.add(mrcAddress); + mrcAddressList.add(mrc2Address); + + // Create volume + Volumes volumesBeforeCreate = client.listVolumes(mrcAddressList); + assertEquals(0, volumesBeforeCreate.getVolumesCount()); + + client.createVolume(mrcAddressList, auth, userCredentials, VOLUME_NAME_1); + + ServiceSet sSet = null; + sSet = dirClient.xtreemfs_service_get_by_name(testEnv.getDIRAddress(), auth, userCredentials, + VOLUME_NAME_1); + + assertEquals(1, sSet.getServicesCount()); + assertEquals(VOLUME_NAME_1, sSet.getServices(0).getName()); + + // List volumes + Volumes volumes = client.listVolumes(mrcAddressList); + assertEquals(1, volumes.getVolumesCount()); + assertEquals(VOLUME_NAME_1, volumes.getVolumes(0).getName()); + + // Delete volume + client.deleteVolume(mrcAddressList, auth, userCredentials, VOLUME_NAME_1); + + sSet = null; + sSet = dirClient.xtreemfs_service_get_by_name(testEnv.getDIRAddress(), auth, userCredentials, + VOLUME_NAME_1); + assertEquals(0, sSet.getServicesCount()); + + // List volumes + volumes = client.listVolumes(mrcAddressList); + assertEquals(0, volumes.getVolumesCount()); + + // shutdown the client + client.shutdown(); + } + + @Test + public void testMinimalExample() throws Exception { + final String VOLUME_NAME_1 = "testMinimalExample"; + + Options options = new Options(); + options.setPeriodicFileSizeUpdatesIntervalS(10); + + String dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + String mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + // Create and open volume. + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME_1); + Volume volume = client.openVolume(VOLUME_NAME_1, null, options); + + // Open a file. + FileHandle fileHandle = volume.openFile( + userCredentials, + "/bla.tzt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber()); + + // Get file attributes + Stat stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(0, stat.getSize()); + + // Write to file. + String data = "Need a testfile? Why not (\\|)(+,,,+)(|/)?"; + fileHandle.write(userCredentials, data.getBytes(), data.length(), 0); + + stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(data.length(), stat.getSize()); + + // Read from file. + byte[] readData = new byte[data.length()]; + int readCount = fileHandle.read(userCredentials, readData, data.length(), 0); + + assertEquals(data.length(), readCount); + for (int i = 0; i < data.length(); i++) { + assertEquals(readData[i], data.getBytes()[i]); + } + + fileHandle.close(); + + client.deleteVolume(mrcAddress, auth, userCredentials, VOLUME_NAME_1); + + client.shutdown(); + } + + @Test + public void testMinimalExampleWithAsyncWrites() throws Exception { + final String VOLUME_NAME_1 = "testMinimalExampleWithAsyncWrites"; + + Options options = new Options(); + options.setPeriodicFileSizeUpdatesIntervalS(10); + // maxwriteAhead != 0 enables async writes as long as file isn't opened + // with O_SYNC + options.setMaxWriteAhead(1024); + + String dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + String mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + // Open a volume named "foobar". + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME_1); + Volume volume = client.openVolume(VOLUME_NAME_1, null, options); + + // Open a file. + FileHandle fileHandle = volume.openFile( + userCredentials, + "/bla.tzt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber()); + + // Get file attributes + Stat stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(0, stat.getSize()); + + // Write to file. + String data = "Need a testfile? Why not (\\|)(+,,,+)(|/)?"; + fileHandle.write(userCredentials, data.getBytes(), data.length(), 0); + + stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(data.length(), stat.getSize()); + + // Read from file. + byte[] readData = new byte[data.length()]; + int readCount = fileHandle.read(userCredentials, readData, data.length(), 0); + + assertEquals(data.length(), readCount); + for (int i = 0; i < data.length(); i++) { + assertEquals(readData[i], data.getBytes()[i]); + } + + fileHandle.close(); + client.deleteVolume(mrcAddress, auth, userCredentials, VOLUME_NAME_1); + client.shutdown(); + } + + @Test + public void testMinimalExampleWithAsyncWritesAndStriping() throws Exception { + final String VOLUME_NAME_1 = "testMinimalExampleWithAsyncWritesAndStriping"; + + Options options = new Options(); + options.setPeriodicFileSizeUpdatesIntervalS(10); + // maxwriteAhead != 0 enables async writes as long as file isn't opened + // with O_SYNC + options.setMaxWriteAhead(1024); + + String dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + String mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + // Open a volume named "foobar". + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME_1, 0777, + userCredentials.getUsername(), userCredentials.getGroupsList().get(0), + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, StripingPolicyType.STRIPING_POLICY_RAID0, + 4, 2, new ArrayList()); + Volume volume = client.openVolume(VOLUME_NAME_1, null, options); + + // Open a file. + FileHandle fileHandle = volume.openFile( + userCredentials, + "/bla.tzt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber()); + + // Get file attributes + Stat stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(0, stat.getSize()); + + // Write to file. + String data = "Need a testfile? Why not (\\|)(+,,,+)(|/)?"; + fileHandle.write(userCredentials, data.getBytes(), data.length(), 0); + + stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(data.length(), stat.getSize()); + + // Read from file. + byte[] readData = new byte[data.length()]; + int readCount = fileHandle.read(userCredentials, readData, data.length(), 0); + + assertEquals(data.length(), readCount); + for (int i = 0; i < data.length(); i++) { + assertEquals(readData[i], data.getBytes()[i]); + } + + fileHandle.close(); + client.shutdown(); + } +} diff --git a/java/servers/test/org/xtreemfs/common/libxtreemfs/FileHandleTest.java b/java/servers/test/org/xtreemfs/common/libxtreemfs/FileHandleTest.java new file mode 100644 index 0000000..fc8d1f8 --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/libxtreemfs/FileHandleTest.java @@ -0,0 +1,846 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileWriter; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.libxtreemfs.exceptions.InvalidChecksumException; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.osd.storage.HashStorageLayout; +import org.xtreemfs.osd.storage.MetadataCache; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.getattrResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + *
    + * Dec 15, 2011 + */ +public class FileHandleTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static TestEnvironment testEnv; + + private static UserCredentials userCredentials; + + private static Auth auth = RPCAuthentication.authNone; + + private static String mrcAddress; + + private static String dirAddress; + + private static StripingPolicy defaultStripingPolicy; + + private static MRCServiceClient mrcClient; + + private static AdminClient client; + + private static Options options; + + @Before + public void setUp() throws Exception { + FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); + Logging.start(Logging.LEVEL_WARN); + + SetupUtils.CHECKSUMS_ON = true; + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.RPC_CLIENT, TestEnvironment.Services.MRC, TestEnvironment.Services.MRC_CLIENT, + TestEnvironment.Services.OSD, TestEnvironment.Services.OSD }); + testEnv.start(); + SetupUtils.CHECKSUMS_ON = false; + + userCredentials = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + defaultStripingPolicy = StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0) + .setStripeSize(128).setWidth(1).build(); + + mrcClient = testEnv.getMrcClient(); + + options = new Options(); + client = ClientFactory.createAdminClient(dirAddress, userCredentials, null, options); + client.start(); + } + + @After + public void tearDown() throws Exception { + testEnv.shutdown(); + client.shutdown(); + } + + @Test + public void testTruncate() throws Exception { + String volumeName = "testTruncate"; + String fileName = "testfile"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + FileHandle fileHandle = volume.openFile(userCredentials, fileName, flags, 0777); + fileHandle.close(); + + assertEquals(0, volume.getAttr(userCredentials, fileName).getSize()); + + fileHandle = volume.openFile(userCredentials, fileName, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber(), 0777); + fileHandle.truncate(userCredentials, 1337); + assertEquals(1337, fileHandle.getAttr(userCredentials).getSize()); + } + + @Test(expected = PosixErrorException.class) + public void testAcquireLock() throws Exception { + String volumeName = "testAcquireLock"; + String fileName = "testfile"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + FileHandle fileHandle = volume.openFile(userCredentials, fileName, flags, 0777); + + int processId = 10000; + int offset = 0; + int length = 100; + boolean exclusive = true; + boolean waitForLock = true; + Lock lock = fileHandle + .acquireLock(userCredentials, processId, offset, length, exclusive, waitForLock); + assertEquals(processId, lock.getClientPid()); + assertEquals(offset, lock.getOffset()); + assertEquals(length, lock.getLength()); + assertEquals(exclusive, lock.getExclusive()); + + // the cached lock should be equal, too. + Lock secondLock = fileHandle.acquireLock(userCredentials, processId, offset, length, exclusive, + waitForLock); + assertEquals(lock, secondLock); + + // acquiring locks should also work if we don't wait for the lock. + processId++; + FileHandle fileHandle2 = volume.openFile(userCredentials, fileName + 2, flags, 0777); + Lock anotherLock = fileHandle2.acquireLock(userCredentials, processId, offset, length, exclusive, + false); + assertEquals(processId, anotherLock.getClientPid()); + assertEquals(offset, anotherLock.getOffset()); + assertEquals(length, anotherLock.getLength()); + assertEquals(exclusive, anotherLock.getExclusive()); + + // acquiring a second lock with a new pid should throw an exception + processId++; + fileHandle.acquireLock(userCredentials, processId, offset, length, exclusive, waitForLock); + } + + @Test + public void testCheckLock() throws Exception { + String volumeName = "testCheckLock"; + String fileName = "testfile"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + FileHandle fileHandle = volume.openFile(userCredentials, fileName, flags, 0777); + + int processId = 10000; + int offset = 0; + int length = 100; + boolean exclusive = true; + + Lock lock = fileHandle.checkLock(userCredentials, processId, offset, length, exclusive); + assertEquals(processId, lock.getClientPid()); + assertEquals(offset, lock.getOffset()); + assertEquals(length, lock.getLength()); + assertEquals(exclusive, lock.getExclusive()); + + // create lock and request same lock with different pid + + FileHandle fileHandle2 = volume.openFile(userCredentials, fileName + 2, flags, 0777); + processId++; + fileHandle2.acquireLock(userCredentials, processId, offset, length, exclusive, true); + processId++; + Lock anotherLock = fileHandle2.checkLock(userCredentials, processId, offset, length, exclusive); + assertEquals(processId - 1, anotherLock.getClientPid()); + assertEquals(offset, anotherLock.getOffset()); + assertEquals(length, anotherLock.getLength()); + assertEquals(exclusive, anotherLock.getExclusive()); + + // this lock should be already cached + processId--; + Lock cachedLock = fileHandle2.checkLock(userCredentials, processId, offset, length, exclusive); + assertEquals(processId, cachedLock.getClientPid()); + assertEquals(offset, cachedLock.getOffset()); + assertEquals(length, cachedLock.getLength()); + assertEquals(exclusive, cachedLock.getExclusive()); + } + + @Test + public void testReleaseLock() throws Exception { + String volumeName = "testReleaseLock"; + String fileName = "testfile"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + FileHandle fileHandle = volume.openFile(userCredentials, fileName, flags, 0777); + + int processId = 10000; + int offset = 0; + int length = 100; + boolean exclusive = true; + + fileHandle.acquireLock(userCredentials, processId, offset, length, exclusive, true); + fileHandle.releaseLock(userCredentials, processId, offset, length, exclusive); + + // if releaseLock fails the attempt to require the same lock with a differnt PID will fail, too. + processId++; + Lock anotherLock = fileHandle + .acquireLock(userCredentials, processId, offset, length, exclusive, true); + assertEquals(processId, anotherLock.getClientPid()); + assertEquals(offset, anotherLock.getOffset()); + assertEquals(length, anotherLock.getLength()); + assertEquals(exclusive, anotherLock.getExclusive()); + + fileHandle.releaseLockOfProcess(processId); + processId++; + anotherLock = fileHandle.acquireLock(userCredentials, processId, offset, length, exclusive, true); + assertEquals(processId, anotherLock.getClientPid()); + assertEquals(offset, anotherLock.getOffset()); + assertEquals(length, anotherLock.getLength()); + assertEquals(exclusive, anotherLock.getExclusive()); + + // the lock don't belong to the clientPid. Should do nothing. checkLock should return the old one. + processId++; + fileHandle.releaseLock(userCredentials, processId, offset, length, exclusive); + anotherLock = fileHandle.checkLock(userCredentials, processId, offset, length, exclusive); + assertEquals(processId - 1, anotherLock.getClientPid()); + assertEquals(offset, anotherLock.getOffset()); + assertEquals(length, anotherLock.getLength()); + assertEquals(exclusive, anotherLock.getExclusive()); + + } + + @Test + public void testAsyncXcapRenewal() throws Exception { + String volumeName = "testAsyncXcapRenewal"; + String fileName = "testfile"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + FileHandleImplementation fileHandle = (FileHandleImplementation) volume.openFile(userCredentials, + fileName, flags, 0777); + + XCap oldXCap = fileHandle.getXcap(); + Thread.sleep(2000); + fileHandle.renewXCapAsync(); + fileHandle.waitForAsyncXcapRenewalFinished(); + XCap renewedXCap = fileHandle.getXcap(); + assertEquals(oldXCap.getExpireTimeoutS(), renewedXCap.getExpireTimeoutS()); + assertTrue(oldXCap.getExpireTimeS() < renewedXCap.getExpireTimeS()); + assertEquals(oldXCap.getAccessMode(), renewedXCap.getAccessMode()); + assertEquals(oldXCap.getClientIdentity(), renewedXCap.getClientIdentity()); + assertEquals(oldXCap.getReplicateOnClose(), renewedXCap.getReplicateOnClose()); + assertEquals(oldXCap.getSerializedSize(), renewedXCap.getSerializedSize()); + assertEquals(oldXCap.getSnapConfig(), renewedXCap.getSnapConfig()); + assertEquals(oldXCap.getTruncateEpoch(), renewedXCap.getTruncateEpoch()); + } + + @Test(expected = PosixErrorException.class) + public void testTruncateWithAsyncWritesFailed() throws Exception { + String volumeName = "testTruncateWithAsyncWritesFailed"; + String fileName = "testfile"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + FileHandleImplementation fileHandle = (FileHandleImplementation) volume.openFile(userCredentials, + fileName, flags, 0777); + fileHandle.markAsyncWritesAsFailed(); + fileHandle.truncate(userCredentials, 100); + } + + @Test(expected = PosixErrorException.class) + public void testFlushWithAsyncWritesFailed() throws Exception { + String volumeName = "testFlushWithAsyncWritesFailed"; + String fileName = "testfile"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + FileHandleImplementation fileHandle = (FileHandleImplementation) volume.openFile(userCredentials, + fileName, flags, 0777); + fileHandle.markAsyncWritesAsFailed(); + fileHandle.flush(); + } + + @Test(expected = PosixErrorException.class) + public void testWriteWithAsyncWritesFailed() throws Exception { + String volumeName = "testWriteWithAsyncWritesFailed"; + String fileName = "testfile"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + FileHandleImplementation fileHandle = (FileHandleImplementation) volume.openFile(userCredentials, + fileName, flags, 0777); + fileHandle.markAsyncWritesAsFailed(); + fileHandle.write(userCredentials, "hallo".getBytes(), 5, 0); + } + + @Test(expected = PosixErrorException.class) + public void testReadWithAsyncWritesFailed() throws Exception { + String volumeName = "testReadWithAsyncWritesFailed"; + String fileName = "testfile"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + FileHandleImplementation fileHandle = (FileHandleImplementation) volume.openFile(userCredentials, + fileName, flags, 0777); + fileHandle.markAsyncWritesAsFailed(); + fileHandle.read(userCredentials, "a".getBytes(), 0, 1); + } + + @Test + public void testWriteBackFileSize() throws Exception { + String volumeName = "testWriteBackFileSize"; + String fileName = "testfile"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + FileHandleImplementation fileHandle = (FileHandleImplementation) volume.openFile(userCredentials, + fileName, flags, 0777); + + OSDWriteResponse.Builder responseBuilder = OSDWriteResponse.newBuilder(); + responseBuilder.setSizeInBytes(13337); + responseBuilder.setTruncateEpoch(20); + OSDWriteResponse response = responseBuilder.build(); + fileHandle.writeBackFileSize(response, false); + + RPCResponse r = mrcClient.getattr(testEnv.getMRCAddress(), auth, userCredentials, volumeName, + fileName, 0l); + getattrResponse response2 = r.get(); + + assertEquals(response.getSizeInBytes(), response2.getStbuf().getSize()); + assertEquals(response.getTruncateEpoch(), response2.getStbuf().getTruncateEpoch()); + + r.freeBuffers(); + } + + @Test + public void testWriteBackFileSizeAsync() throws Exception { + String volumeName = "testWriteBackFileSizeAsync"; + String fileName = "testfile"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + FileHandleImplementation fileHandle = (FileHandleImplementation) volume.openFile(userCredentials, + fileName, flags, 0777); + + OSDWriteResponse.Builder responseBuilder = OSDWriteResponse.newBuilder(); + responseBuilder.setSizeInBytes(13337); + responseBuilder.setTruncateEpoch(20); + OSDWriteResponse response = responseBuilder.build(); + fileHandle.setOsdWriteResponseForAsyncWriteBack(response); + fileHandle.writeBackFileSizeAsync(); + + Thread.sleep(2000); + + RPCResponse r = mrcClient.getattr(testEnv.getMRCAddress(), auth, userCredentials, volumeName, + fileName, 0l); + getattrResponse response2 = r.get(); + + assertEquals(response.getSizeInBytes(), response2.getStbuf().getSize()); + assertEquals(response.getTruncateEpoch(), response2.getStbuf().getTruncateEpoch()); + + r.freeBuffers(); + } + + @Test + public void testWriteWithMoreThanOneBlock() throws Exception { + final String volumeName = "testWriteWithMoreThanOneBlock"; + + Options options = new Options(); + options.setPeriodicFileSizeUpdatesIntervalS(10); + options.setMetadataCacheSize(0); + + String dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + String mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + // Open a volume. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + + // Open a file. + FileHandle fileHandle = volume.openFile( + userCredentials, + "/bla.tzt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_SYNC.getNumber()); + + // Get file attributes + Stat stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(0, stat.getSize()); + + // Write to file.\ + final int numBytes = 5500; + final String xtreemfs = "XTREEMFS"; + String data = ""; + while (data.length() < numBytes) { + data += xtreemfs; + } + + int writtenBytes = fileHandle.write(userCredentials, data.getBytes(), 4092, 0); + + stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(4092, stat.getSize()); + + byte[] secondChunk = new byte[data.length() - writtenBytes]; + for (int i = 0; i < secondChunk.length; i++) { + secondChunk[i] = data.getBytes()[writtenBytes + i]; + } + fileHandle.write(userCredentials, secondChunk, secondChunk.length, writtenBytes); + fileHandle.flush(); + + // Thread.sleep(options.getPeriodicFileSizeUpdatesIntervalS()*1000+1000); + + stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(data.length(), stat.getSize()); + + // Read from file. + byte[] readData = new byte[data.length()]; + int readCount = fileHandle.read(userCredentials, readData, data.length(), 0); + + assertEquals(data.length(), readCount); + for (int i = 0; i < data.length(); i++) { + assertEquals(readData[i], data.getBytes()[i]); + } + + fileHandle.close(); + client.shutdown(); + } + + @Test + public void testWriteGreaterThanStripesize() throws Exception { + final String volumeName = "testWriteGreaterThanStripesize"; + + Options options = new Options(); + options.setPeriodicFileSizeUpdatesIntervalS(10); + options.setMetadataCacheSize(0); + + String dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + String mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + // Open a volume. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + + // Open a file. + FileHandle fileHandle = volume.openFile( + userCredentials, + "/bla.tzt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_SYNC.getNumber()); + + // Get file attributes + Stat stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(0, stat.getSize()); + + // Write to file.\ + final int numExtraBytes = 5500 / 8; + final String xtreemfs = "XTREEMFS"; + String data = ""; + while (data.length() < defaultStripingPolicy.getStripeSize() * 1024) { + data += xtreemfs; + } + for (int i = 0; i < numExtraBytes; i++) { + data += xtreemfs; + } + + int writtenBytes = fileHandle.write(userCredentials, data.getBytes(), data.length(), 0); + + stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(data.length(), stat.getSize()); + + // Read from file. + byte[] readData = new byte[data.length()]; + int readCount = fileHandle.read(userCredentials, readData, data.length(), 0); + + assertEquals(data.length(), readCount); + assertEquals(writtenBytes, readCount); + for (int i = 0; i < data.length(); i++) { + assertEquals(readData[i], data.getBytes()[i]); + } + + fileHandle.close(); + client.shutdown(); + } + + @Test + public void testReadBytePerByte() throws Exception { + final String volumeName = "testReadBytePerByte"; + + Options options = new Options(); + options.setPeriodicFileSizeUpdatesIntervalS(10); + options.setMetadataCacheSize(0); + + String dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + String mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + // Open the volume. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + + // Open a file. + FileHandle fileHandle = volume.openFile( + userCredentials, + "/bla.tzt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_SYNC.getNumber()); + + // Get file attributes + Stat stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(0, stat.getSize()); + + // Write to file.\ + final String data = "FFFFFFFFFF"; + int writtenBytes = fileHandle.write(userCredentials, data.getBytes(), data.length(), 0); + + stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(data.length(), stat.getSize()); + + // Read from file byte per byte. Should return 0 if EOF is reached. + int readCount = -1; + int position = 0; + while (readCount != 0) { + byte[] readData = new byte[1]; + readCount = fileHandle.read(userCredentials, readData, 1, position); + if (readCount != 0) { + assertEquals(readData[0], "F".getBytes()[0]); + position++; + } + } + assertEquals(writtenBytes, position); + + fileHandle.close(); + client.shutdown(); + } + + @Test + public void readBytePerByteManyTimes() throws Exception { + final String volumeName = "testReadBytePerByteManyTimes"; + + Options options = new Options(); + options.setPeriodicFileSizeUpdatesIntervalS(10); + options.setMetadataCacheSize(0); + + String dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + String mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + // Open the volume. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + + // Open a file. + FileHandle fileHandle = volume.openFile( + userCredentials, + "/bla.tzt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_SYNC.getNumber()); + + // Get file attributes + Stat stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(0, stat.getSize()); + + // Write to file. 2^20 times F to file + String data = "F"; + for (int i = 0; i < 12; i++) { + data = data + data; + } + int writtenBytes = fileHandle.write(userCredentials, data.getBytes(), data.length(), 0); + + stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(data.length(), stat.getSize()); + + // Read from file byte per byte. Should return 0 if EOF is reached. + int readCount = -1; + int position = 0; + while (readCount != 0) { + byte[] readData = new byte[1]; + readCount = fileHandle.read(userCredentials, readData, 1, position); + if (readCount != 0) { + assertEquals(readData[0], "F".getBytes()[0]); + position++; + } + } + assertEquals(writtenBytes, position); + + fileHandle.close(); + client.shutdown(); + } + + @Test + public void testMarkReplicaAsComplete() throws Exception { + String volumeName = "testMarkReplicaAsComplete"; + + // start new OSDs + testEnv.startAdditionalOSDs(2); + + // Create and open volume. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + AdminVolume volume = client.openVolume(volumeName, null, options); + volume.start(); + + // set replica update policy. + int replFlags = ReplicationFlags.setFullReplica(0); + replFlags = ReplicationFlags.setRarestFirstStrategy(replFlags); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY, 2, + replFlags); + + // open FileHandle. + AdminFileHandle fileHandle = volume.openFile( + userCredentials, + "/test.txt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0777); + + // write some content. + String content = ""; + for (int i = 0; i < 12000; i++) + content = content.concat("Hello World "); + byte[] bytesIn = content.getBytes(); + + int length = bytesIn.length; + + fileHandle.write(userCredentials, bytesIn, length, 0); + + // mark new replica as complete. + fileHandle.checkAndMarkIfReadOnlyReplicaComplete(0, userCredentials); + + // re-open file to get replica with updated flags. + fileHandle.close(); + fileHandle = volume.openFile(userCredentials, "/test.txt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + + assertTrue((fileHandle.getReplica(0).getReplicationFlags() & REPL_FLAG.REPL_FLAG_IS_COMPLETE + .getNumber()) != 0); + + // close volume and file, shut down client + fileHandle.close(); + volume.close(); + client.deleteVolume(auth, userCredentials, volumeName); + } + /** + * + * Creates a rw replicated file and gets the file size from the OSDs. + * To obtain a quorum the file has 3 replicas (the first replica will be outdated). + * + * @throws Exception + */ + //TODO(lukas) split test in OSD test (internalGetFileSizeOperation test) and client test (getSizeOnOSD test) + @Test + public void testGetSizeOnOsd() throws Exception { + String volumeName = "testGetSizeOnOsd"; + + // Start new OSDs. + testEnv.startAdditionalOSDs(3); + + // Create and open volume. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + AdminVolume volume = client.openVolume(volumeName, null, options); + volume.start(); + + // Set replica update Policy. + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ, 3, + ReplicationFlags.setSequentialStrategy(0)); + + // Open FileHandle. + AdminFileHandle fileHandle = volume.openFile( + userCredentials, + "/test.txt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0777); + + // Get OSD of first replica. + String firstReplicaUuid = fileHandle.getReplica(0).getOsdUuids(0); + + // Create some content. + String content = ""; + for (int i = 0; i < 12000; i++) { + content = content.concat("Hello World "); + } + byte[] bytesIn = content.getBytes(); + int length = bytesIn.length; + + // Stop OSD of first replica. + testEnv.stopOSD(firstReplicaUuid); + + // Write content and close file. + fileHandle.write(userCredentials, bytesIn, length, 0); + fileHandle.close(); + + // Restart OSD with first replica. + testEnv.startOSD(firstReplicaUuid); + + long size = 0; + + // Repeat until first replica is primary. + do { + + // Wait until current primary give up lease. + while (testEnv.getPrimary(fileHandle.getGlobalFileId()) != null) { + Thread.sleep(5000); + } + + // Get size on OSD. + size = fileHandle.getSizeOnOSD(); + + } while (testEnv.getPrimary(fileHandle.getGlobalFileId()).equals(firstReplicaUuid)); + + // check if size of the first replica is correct + assertEquals(length, size); + + client.deleteVolume(auth, userCredentials, volumeName); + } + + @Test + public void testCheckObjectAndGetSize() throws Exception { + String volumeName = "testCheckObjectAndGetSize"; + + // Create and open volume. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + AdminVolume volume = client.openVolume(volumeName, null, options); + volume.start(); + + // open FileHandle. + AdminFileHandle fileHandle = volume.openFile( + userCredentials, + "/test.txt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0777); + + // create some content. + String content = ""; + for (int i = 0; i < 6000; i++) + content = content.concat("Hello World "); + byte[] bytesIn = content.getBytes(); + int length = bytesIn.length; + + //write content + fileHandle.write(userCredentials, bytesIn, length, 0); + + fileHandle.close(); + + // check Object to get size(File consists of one Object) + int objSize = fileHandle.checkObjectAndGetSize(0, 0); + + assertEquals(length, objSize); + + HashStorageLayout hsl = new HashStorageLayout(testEnv.getOSDConfig(fileHandle.getReplica(0).getOsdUuids(0)), + new MetadataCache()); + String filePath = hsl.generateAbsoluteFilePath(fileHandle.getGlobalFileId()); + + File fileDir = new File(filePath); + File[] fileList = fileDir.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + // Filter .dot files. + return (!pathname.getName().startsWith(".")); + } + }); + assertTrue(fileList.length > 0); + + FileWriter writer = new FileWriter(fileList[0], true); + writer.write("foofoofoofoo"); + writer.close(); + + try { + fileHandle.checkObjectAndGetSize(0, 0); + assertTrue(false); + } catch (InvalidChecksumException e) { + assertTrue(true); + } + + volume.close(); + client.deleteVolume(auth, userCredentials, volumeName); + } +} diff --git a/java/servers/test/org/xtreemfs/common/libxtreemfs/FileSizeUpdateThreadTest.java b/java/servers/test/org/xtreemfs/common/libxtreemfs/FileSizeUpdateThreadTest.java new file mode 100644 index 0000000..c73c090 --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/libxtreemfs/FileSizeUpdateThreadTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2012 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import static org.junit.Assert.assertEquals; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * Tests if FileSizeUpdateThread works correctly. + */ +public class FileSizeUpdateThreadTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static DIRRequestDispatcher dir; + + private static TestEnvironment testEnv; + + private static DIRConfig dirConfig; + + private static UserCredentials userCredentials; + + private static Auth auth = RPCAuthentication.authNone; + + private static MRCServiceClient mrcClient; + + @BeforeClass + public static void initializeTest() throws Exception { + FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + dirConfig = SetupUtils.createDIRConfig(); + + dir = new DIRRequestDispatcher(dirConfig, SetupUtils.createDIRdbsConfig()); + dir.startup(); + dir.waitForStartup(); + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_CLIENT, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.RPC_CLIENT, + TestEnvironment.Services.MRC, TestEnvironment.Services.OSD }); + testEnv.start(); + + userCredentials = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + mrcClient = new MRCServiceClient(testEnv.getRpcClient(), null); + + } + + @AfterClass + public static void shutdownTest() throws Exception { + + testEnv.shutdown(); + dir.shutdown(); + dir.waitForShutdown(); + } + + @Test + public void testFileSizeRenewal() throws Exception { + + final String VOLUME_NAME_1 = "testFileSizeRenewal"; + + Options options = new Options(); + options.setPeriodicFileSizeUpdatesIntervalS(10); + options.setMetadataCacheSize(0); + + String dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + String mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + // Open a volume named "foobar". + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME_1); + Volume volume = client.openVolume(VOLUME_NAME_1, null, options); + + // Open a file. + FileHandle fileHandle = volume.openFile( + userCredentials, + "/bla.tzt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber()); + + // Get file attributes + Stat stat = volume.getAttr(userCredentials, "/bla.tzt"); + assertEquals(0, stat.getSize()); + + // Write to file. + String data = "Need a testfile? Why not (\\|)(+,,,+)(|/)?"; + fileHandle.write(userCredentials, data.getBytes(), data.length(), 0); + + // MRC shouldn't know about filesize yet + stat = mrcClient + .getattr(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME_1, "/bla.tzt", 0).get() + .getStbuf(); + assertEquals(0, stat.getSize()); + + Thread.sleep(10000); + + // Now the thread should have updated the filesize at MRC + stat = mrcClient + .getattr(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME_1, "/bla.tzt", 0).get() + .getStbuf(); + assertEquals(data.length(), stat.getSize()); + + fileHandle.close(); + client.shutdown(); + } +} diff --git a/java/servers/test/org/xtreemfs/common/libxtreemfs/MetadataCacheTest.java b/java/servers/test/org/xtreemfs/common/libxtreemfs/MetadataCacheTest.java new file mode 100644 index 0000000..91a9e40 --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/libxtreemfs/MetadataCacheTest.java @@ -0,0 +1,801 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Random; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Setattrs; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.listxattrResponse; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestHelper; + +/** + * + *
    + * Sep 30, 2011 + */ +public class MetadataCacheTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private class MetadataCacheSmasherThread extends Thread { + + private final MetadataCache mdCache; + + private final String[] paths; + + private final Stat[] stats; + + private final DirectoryEntries[] dirs; + + private boolean failed; + + /** + * + */ + public MetadataCacheSmasherThread(MetadataCache cache, String[] paths, Stat[] stats, + DirectoryEntries[] dirs) { + + this.mdCache = cache; + + this.paths = paths; + this.stats = stats; + this.dirs = dirs; + + this.failed = false; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + + while (true) { + + int operation = new Random().nextInt(10) + 1; + int object = new Random().nextInt(10); + + try { + + switch (operation) { + case 1: + mdCache.updateStat(paths[object], stats[object]); + break; + case 2: + long time = System.currentTimeMillis() / 1000; + mdCache.updateStatTime(paths[object], time, Setattrs.SETATTR_ATIME.getNumber()); + break; + case 3: + int i = 1; + i = i << new Random().nextInt(7); + mdCache.updateStatAttributes(paths[object], stats[object], i); + break; + case 4: + mdCache.getStat(paths[object]); + break; + case 5: + mdCache.size(); + break; + case 6: + mdCache.invalidate(paths[object]); + break; + case 7: + mdCache.updateDirEntries(paths[object], dirs[object]); + break; + case 8: + mdCache.getDirEntries(paths[object], 0, 1024); + break; + case 9: + mdCache.invalidatePrefix(paths[object]); + break; + case 10: + mdCache.renamePrefix(paths[object], paths[new Random().nextInt(10)]); + break; + } + + sleep(10); + + } catch (Exception e) { + e.printStackTrace(); + failed = true; + } + + } + + } + + public boolean getFailed() { + return failed; + } + } + + private MetadataCache metadataCache; + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#setUp() + */ + @Before + public void setUp() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + // Max 2 entries, 1 hour + metadataCache = new MetadataCache(2, 3600); + } + + /** + * If a Stat entry gets updated through UpdateStatTime(), the new timeout must be respected in case of an + * eviction. + * + **/ + @Test + public void testUpdateStatTimeKeepsSequentialTimeoutOrder() throws Exception { + Stat.Builder a, b, c; + a = getIntializedStatBuilder(); + b = getIntializedStatBuilder(); + c = getIntializedStatBuilder(); + + a.setIno(0); + b.setIno(1); + c.setIno(2); + + metadataCache.updateStat("/a", a.build()); + metadataCache.updateStat("/b", b.build()); + // Cache is full now. a would should be first item to get evicted. + metadataCache.updateStatTime("/a", 0, Setattrs.SETATTR_MTIME.getNumber()); + // "b" should be the oldest Stat element now and get evicted. + metadataCache.updateStat("/c", c.build()); + // Was "a" found or did "b" survive? + Stat aStat = metadataCache.getStat("/a"); + assertNotNull(aStat); + assertEquals(0, aStat.getIno()); + // "c" ist also still there?! + Stat cStat = metadataCache.getStat("/c"); + assertNotNull(cStat); + assertEquals(2, cStat.getIno()); + + } + + /** + * If a Stat entry gets updated through UpdateStat(), the new timeout must be respected in case of an + * eviction. + **/ + @Test + public void testUpdateStatKeepsSequentialTimeoutOrder() throws Exception { + Stat.Builder a, b, c; + a = getIntializedStatBuilder(); + b = getIntializedStatBuilder(); + c = getIntializedStatBuilder(); + + a.setIno(0); + b.setIno(1); + c.setIno(2); + + Stat aa = a.build(); + + metadataCache.updateStat("/a", aa); + metadataCache.updateStat("/b", b.build()); + // Cache is full now. a would should be first item to get evicted. + metadataCache.updateStat("/a", aa); + // "b" should be the oldest Stat element now and get evicted. + metadataCache.updateStat("/c", c.build()); + // Was "a" found or did "b" survive? + Stat aStat = metadataCache.getStat("/a"); + assertNotNull(aStat); + assertEquals(0, aStat.getIno()); + // "c" ist also still there?! + Stat cStat = metadataCache.getStat("/c"); + assertNotNull(cStat); + assertEquals(2, cStat.getIno()); + } + + /** + * Test if Size is updated correctly after UpdateStat() or Invalidate(). + **/ + @Test + public void testCheckSizeAfterUpdateAndInvalidate() throws Exception { + Stat.Builder a, b, c; + a = getIntializedStatBuilder(); + b = getIntializedStatBuilder(); + c = getIntializedStatBuilder(); + + assertEquals(0l, metadataCache.size()); + metadataCache.updateStat("/a", a.build()); + assertEquals(1l, metadataCache.size()); + metadataCache.updateStat("/b", b.build()); + assertEquals(2l, metadataCache.size()); + metadataCache.updateStat("/c", c.build()); + // metadatacache has only room for two entries. + assertEquals(2l, metadataCache.size()); + + metadataCache.invalidate("/b"); + assertEquals(1l, metadataCache.size()); + metadataCache.invalidate("/c"); + assertEquals(0l, metadataCache.size()); + + } + + @Test + public void testGetUpdateDirEntries() throws Exception { + + DirectoryEntries.Builder dirEntriesBuilder = DirectoryEntries.newBuilder(); + int chunkSize = 1024; + int entryCount = chunkSize; + String dir = "/"; + + // Fill dirEntriesBuilder + for (int i = 0; i < entryCount; i++) { + + // create new Stat object for a new entry object + Stat.Builder a = getIntializedStatBuilder(); + a.setIno(i); + DirectoryEntry entry = DirectoryEntry.newBuilder().setName(dir + i).setStbuf(a.build()).build(); + + dirEntriesBuilder.addEntries(entry); + } + + metadataCache.updateDirEntries(dir, dirEntriesBuilder.build()); + + // Read all dir entries. + DirectoryEntries dirEntriesRead = metadataCache.getDirEntries(dir, 0, entryCount); + + assertEquals(entryCount, dirEntriesRead.getEntriesCount()); + for (int i = 0; i < dirEntriesRead.getEntriesCount(); i++) { + String pathToStat = dir + i; + assertEquals(i, dirEntriesRead.getEntries(i).getStbuf().getIno()); + assertEquals(pathToStat, dirEntriesRead.getEntries(i).getName()); + } + + // Read a subset. + int offset = entryCount / 2; + + dirEntriesRead = metadataCache.getDirEntries(dir, offset, entryCount / 2 - 1); + assertEquals(entryCount / 2 - 1, dirEntriesRead.getEntriesCount()); + + for (int i = 0; i < dirEntriesRead.getEntriesCount(); i++) { + String pathToStat = dir + (offset + i); + assertEquals(pathToStat, dirEntriesRead.getEntries(i).getName()); + assertEquals(offset + i, dirEntriesRead.getEntries(i).getStbuf().getIno()); + } + + dirEntriesBuilder = DirectoryEntries.newBuilder(); + + // Fill dirEntriesBuilder with other entries for this dir + for (int i = 10; i < entryCount + 10; i++) { + + // create new Stat object for a new entry object + Stat.Builder a = getIntializedStatBuilder(); + a.setIno(i); + DirectoryEntry entry = DirectoryEntry.newBuilder().setName(dir + i).setStbuf(a.build()).build(); + + dirEntriesBuilder.addEntries(entry); + } + + metadataCache.updateDirEntries(dir, dirEntriesBuilder.build()); + + // Read all dir entries. + dirEntriesRead = metadataCache.getDirEntries(dir, 0, entryCount); + + assertEquals(entryCount, dirEntriesRead.getEntriesCount()); + for (int i = 0; i < dirEntriesRead.getEntriesCount(); i++) { + String pathToStat = dir + (i + 10); + assertEquals(i + 10, dirEntriesRead.getEntries(i).getStbuf().getIno()); + assertEquals(pathToStat, dirEntriesRead.getEntries(i).getName()); + } + } + + /** + * If a Stat entry gets updated through UpdateStat(), the new timeout must be respected in case of an + * eviction. + */ + @Test + public void testInvalidatePrefix() throws Exception { + + // create new metadataCache with 1024 entries. + metadataCache = new MetadataCache(1024, 3600); + + Stat.Builder a, b, c, d; + a = getIntializedStatBuilder(); + b = getIntializedStatBuilder(); + c = getIntializedStatBuilder(); + d = getIntializedStatBuilder(); + a.setIno(0); + b.setIno(1); + c.setIno(2); + d.setIno(3); + + String dir = "/dir"; + + metadataCache.updateStat(dir, a.build()); + metadataCache.updateStat(dir + "/file1", b.build()); + metadataCache.updateStat(dir + ".file1", c.build()); + metadataCache.updateStat(dir + "Zfile1", d.build()); + + metadataCache.invalidatePrefix(dir); + + // invalidation of all matching entries successful? + assertNull(metadataCache.getStat(dir)); + assertNull(metadataCache.getStat(dir + "/file1")); + + // Similiar entries which do not match the prefix "/dir/" have not been + // invalidated. + + Stat statC = metadataCache.getStat(dir + ".file1"); + assertNotNull(statC); + assertEquals(2, statC.getIno()); + Stat statD = metadataCache.getStat(dir + "Zfile1"); + assertNotNull(statD); + assertEquals(3, statD.getIno()); + + } + + /** + * If a Stat entry gets updated through UpdateStat(), the new timeout must be respected in case of an + * eviction. + */ + @Test + public void testRenamePrefix() throws Exception { + + // create new metadataCache with 1024 entries. + metadataCache = new MetadataCache(1024, 3600); + + Stat.Builder a, b, c, d; + a = getIntializedStatBuilder(); + b = getIntializedStatBuilder(); + c = getIntializedStatBuilder(); + d = getIntializedStatBuilder(); + a.setIno(0); + b.setIno(1); + c.setIno(2); + d.setIno(3); + + String dir = "/dir"; + + metadataCache.updateStat(dir, a.build()); + metadataCache.updateStat(dir + "/file1", b.build()); + metadataCache.updateStat(dir + ".file1", c.build()); + metadataCache.updateStat(dir + "Zfile1", d.build()); + assertEquals(4l, metadataCache.size()); + + metadataCache.renamePrefix(dir, "/newDir"); + assertEquals(4l, metadataCache.size()); + + // Renaming of all matching entries was successful? + Stat statA = metadataCache.getStat("/newDir"); + assertNotNull(statA); + assertEquals(0, statA.getIno()); + Stat statB = metadataCache.getStat("/newDir" + "/file1"); + assertNotNull(statB); + assertEquals(1, statB.getIno()); + + // Similiar entries which do not match the prefix "/dir/" hat not been renamed + Stat statC = metadataCache.getStat(dir + ".file1"); + assertNotNull(statC); + assertEquals(2, statC.getIno()); + Stat statD = metadataCache.getStat(dir + "Zfile1"); + assertNotNull(statD); + assertEquals(3, statD.getIno()); + } + + /** + * Are large nanoseconds values correctly updated by UpdateStatAttributes? + */ + @Test + public void testUpdateStatAttributes() throws Exception { + + // create new metadataCache with 1024 entries. + metadataCache = new MetadataCache(1024, 3600); + + String path = "/file"; + Stat.Builder stat = getIntializedStatBuilder(); + Stat.Builder newStat = getIntializedStatBuilder(); + stat.setIno(0); + newStat.setIno(1); + + metadataCache.updateStat(path, stat.build()); + assertEquals(1l, metadataCache.size()); + Stat statA = metadataCache.getStat(path); + assertNotNull(statA); + assertEquals(0, statA.getIno()); + assertEquals(0, statA.getMtimeNs()); + + long time = 1234567890; + time *= 1000000000; + newStat.setAtimeNs(time); + newStat.setMtimeNs(time); + + metadataCache.updateStatAttributes(path, newStat.build(), Setattrs.SETATTR_ATIME.getNumber() + | Setattrs.SETATTR_MTIME.getNumber()); + assertEquals(1l, metadataCache.size()); + Stat statB = metadataCache.getStat(path); + assertNotNull(statB); + assertEquals(0, statB.getIno()); + assertEquals(time, statB.getAtimeNs()); + assertEquals(time, statB.getMtimeNs()); + } + + /** + * Changing the file access mode may only modify the last 12 bits (3 bits for sticky bit, set GID and set + * UID and 3 * 3 bits for the file access mode). + */ + @Test + public void testUpdateStatAttributesPreservesModeBits() throws Exception { + + String path = "/file"; + Stat.Builder stat = getIntializedStatBuilder(); + Stat.Builder cachedStat = getIntializedStatBuilder(); + + stat.setIno(0); + stat.setMode(33188); // Octal: 100644 ( regular file + 644). + + metadataCache.updateStat(path, stat.build()); + assertEquals(1l, metadataCache.size()); + Stat statA = metadataCache.getStat(path); + assertNotNull(statA); + assertEquals(0, statA.getIno()); + assertEquals(33188, statA.getMode()); + + stat = getIntializedStatBuilder(); + stat.setMode(420); // Octal: 644 + metadataCache.updateStatAttributes(path, stat.build(), Setattrs.SETATTR_MODE.getNumber()); + assertEquals(1l, metadataCache.size()); + statA = metadataCache.getStat(path); + assertNotNull(statA); + assertEquals(0, cachedStat.getIno()); + assertEquals(33188, statA.getMode()); + + stat = getIntializedStatBuilder(); + stat.setMode(263076); // Octal : 1001644 (regular file + sticky bit + 644). + metadataCache.updateStat(path, stat.build()); + assertEquals(1l, metadataCache.size()); + statA = metadataCache.getStat(path); + assertNotNull(statA); + assertEquals(0, statA.getIno()); + assertEquals(263076, statA.getMode()); + + stat = getIntializedStatBuilder(); + stat.setMode(511); // Octal: 0777 (no sticky bit + 777). + metadataCache.updateStatAttributes(path, stat.build(), Setattrs.SETATTR_MODE.getNumber()); + assertEquals(1l, metadataCache.size()); + statA = metadataCache.getStat(path); + assertNotNull(statA); + assertEquals(0, statA.getIno()); + assertEquals(262655, statA.getMode()); // Octal: 1000777 + } + + @Test + public void testConcurrentModifications() throws Exception { + + final int DATA_SIZE = 10; + final java.lang.String FILENAME = "/foobarfile"; + final int DIR_COUNT = 64; + final int THREAD_COUNT = 10; + + // generate Data + String[] paths = new String[DATA_SIZE]; + Stat[] stats = new Stat[DATA_SIZE]; + DirectoryEntries[] dirs = new DirectoryEntries[DATA_SIZE]; + + for (int i = 0; i < DATA_SIZE; i++) { + paths[i] = new String(FILENAME + i + '/'); + stats[i] = getIntializedStatBuilder().setIno(i).build(); + DirectoryEntries.Builder dirBuilder = DirectoryEntries.newBuilder(); + for (int j = 0; j < DIR_COUNT; j++) { + Stat a = getIntializedStatBuilder().setIno(i * 10000 + j).build(); + dirBuilder + .addEntries(DirectoryEntry.newBuilder().setName(FILENAME + i + '/' + j).setStbuf(a)); + } + dirs[i] = dirBuilder.build(); + } + + MetadataCacheSmasherThread[] threads = new MetadataCacheSmasherThread[THREAD_COUNT]; + for (int i = 0; i < THREAD_COUNT; i++) { + threads[i] = new MetadataCacheSmasherThread(metadataCache, paths, stats, dirs); + threads[i].start(); + } + + Thread.sleep(10000); // sleep 10 seconds and let the other threads work + + for (int i = 0; i < THREAD_COUNT; i++) { + assertEquals(false, threads[i].getFailed()); + } + + } + + @Test + public void testUnenabledMdCache() { + metadataCache = new MetadataCache(0, 10000); + assertEquals(0, metadataCache.size()); + assertEquals(0, metadataCache.capacity()); + assertNull(metadataCache.getDirEntries("/", 10, 100)); + assertNull(metadataCache.getStat("fewf")); + assertNull(metadataCache.getXAttr("tttgreg", "wefwe").getFirst()); + assertFalse(metadataCache.getXAttr("tttgreg", "wefwe").getSecond()); + assertNull(metadataCache.getXAttrs("asdf")); + assertEquals(0, metadataCache.getXAttrSize("zxcv", "naste").getFirst().intValue()); + assertFalse(metadataCache.getXAttrSize("zxcv", "naste").getSecond()); + + metadataCache.invalidate("bla"); + metadataCache.invalidateDirEntries("blub"); + metadataCache.invalidateDirEntry("puuuh", "noooooo"); + metadataCache.invalidatePrefix("praefeix"); + metadataCache.invalidateStat("stat"); + metadataCache.invalidateXAttr("Xattr", "dont care"); + metadataCache.invalidateXAttrs("jea, finished"); + + metadataCache.updateDirEntries("fsa", DirectoryEntries.getDefaultInstance()); + metadataCache.updateStat("fsa", Stat.getDefaultInstance()); + metadataCache.updateStatAttributes("fwef", Stat.getDefaultInstance(), 100); + metadataCache.updateStatFromOSDWriteResponse("fefew", OSDWriteResponse.getDefaultInstance()); + metadataCache.updateStatTime("fsa", 1034l, 100); + metadataCache.updateXAttr("fsa", "wefwe", "dfd"); + metadataCache.updateXAttrs("sdfs", listxattrResponse.getDefaultInstance()); + + metadataCache.renamePrefix("foo", "bar"); + } + + private Stat.Builder getIntializedStatBuilder() { + Stat.Builder statBuilder = Stat.newBuilder(); + + statBuilder.setDev(0); + statBuilder.setIno(0); + statBuilder.setMode(0); + // if not set to 1 an exception in the metadatacache is triggered + statBuilder.setNlink(1); + statBuilder.setUserId(""); + statBuilder.setGroupId(""); + statBuilder.setSize(0); + statBuilder.setAtimeNs(0); + statBuilder.setMtimeNs(0); + statBuilder.setCtimeNs(0); + statBuilder.setBlksize(0); + statBuilder.setTruncateEpoch(0); + + return statBuilder; + + } + + @Test + public void testUpdateStatFromOSDWriteResponse() throws Exception { + OSDWriteResponse osdWriteResponse = OSDWriteResponse.newBuilder().setSizeInBytes(1337) + .setTruncateEpoch(1338).build(); + metadataCache.updateStat("foobar", getIntializedStatBuilder().setSize(100).build()); + assertEquals(100, metadataCache.getStat("foobar").getSize()); + metadataCache.updateStatFromOSDWriteResponse("foobar", osdWriteResponse); + assertEquals(1337, metadataCache.getStat("foobar").getSize()); + + // Test with entry but no Stat + DirectoryEntries entries = getDummyDirEntries(); + metadataCache.updateDirEntries("hasDirEntriesButNoStat", entries); + metadataCache.updateStatFromOSDWriteResponse("hasDirEntriesButNoStat", osdWriteResponse); + assertNull(metadataCache.getStat("hasDirEntriesButNoStat")); + + // Test with equal truncate epoch and higher size + osdWriteResponse = OSDWriteResponse.newBuilder().setSizeInBytes(20000).setTruncateEpoch(20000) + .build(); + metadataCache.updateStatFromOSDWriteResponse("foobar", osdWriteResponse); + assertEquals(20000, metadataCache.getStat("foobar").getSize()); + metadataCache.updateStatFromOSDWriteResponse("foobar", osdWriteResponse); + assertEquals(20000, metadataCache.getStat("foobar").getSize()); + } + + @Test + public void testGetStatExpired() throws Exception { + metadataCache = new MetadataCache(100, 1); + Stat aStat = getIntializedStatBuilder().setSize(333).build(); + metadataCache.updateStat("foobar", aStat); + assertEquals(aStat, metadataCache.getStat("foobar")); + Thread.sleep(2000); + assertNull(metadataCache.getStat("foobar")); + } + + @Test + public void testGetDirEntriesExpired() throws Exception { + metadataCache = new MetadataCache(100, 1); + DirectoryEntries entries = getDummyDirEntries(); + metadataCache.updateDirEntries("foobar", entries); + assertEquals(entries, metadataCache.getDirEntries("foobar", 0, 1)); + Thread.sleep(2000); + assertNull(metadataCache.getDirEntries("foobar", 0, 1)); + } + + @Test + public void testGetNonExistingDirEntries() throws Exception { + assertNull(metadataCache.getDirEntries("do not exist", 0, 100)); + } + + @Test + public void testInvalidateStat() throws Exception { + Stat aStat = getIntializedStatBuilder().build(); + metadataCache.updateStat("foobar", aStat); + assertEquals(aStat, metadataCache.getStat("foobar")); + metadataCache.invalidateStat("foobar"); + assertNull(metadataCache.getStat("foobar")); + } + + @Test + public void testInvalidateXattrs() throws Exception { + listxattrResponse xattrs = getDummyXattrs(); + metadataCache.updateXAttrs("foobar", xattrs); + assertEquals(xattrs, metadataCache.getXAttrs("foobar")); + metadataCache.invalidateXAttrs("foobar"); + assertNull(metadataCache.getXAttrs("foobar")); + } + + @Test + public void testInvalidateXattr() throws Exception { + metadataCache.invalidateXAttr("foobar", "where are you?"); + assertNull(metadataCache.getXAttr("foobar", "where are you?").getFirst()); + + metadataCache.updateStat("foobar", getIntializedStatBuilder().build()); + metadataCache.invalidateXAttr("foobar", "still not there?"); + assertNull(metadataCache.getXAttr("foobar", "still not there?").getFirst()); + + XAttr attr = XAttr.newBuilder().setName("deleteme").setValue("bla").build(); + listxattrResponse xattrs = getDummyXattrs().toBuilder().addXattrs(attr).build(); + metadataCache.updateXAttrs("foobar", xattrs); + assertEquals("bla", metadataCache.getXAttr("foobar", "deleteme").getFirst()); + metadataCache.invalidateXAttr("foobar", "deleteme"); + assertNull(metadataCache.getXAttr("foobar", "deleteme").getFirst()); + } + + @Test + public void testUpdateXattr() throws Exception { + metadataCache.updateXAttr("foobar", "do not exist", "nothing to do"); + assertNull(metadataCache.getXAttr("foobar", "do not exist").getFirst()); + + metadataCache.updateStat("foobar", getIntializedStatBuilder().build()); + metadataCache.updateXAttr("foobar", "do not exist", "nothing to do"); + assertNull(metadataCache.getXAttr("foobar", "do not exist").getFirst()); + + // update existing xattr + XAttr attr = XAttr.newBuilder().setName("newAttr").setValue("bla").build(); + listxattrResponse xattrs = getDummyXattrs().toBuilder().addXattrs(attr).build(); + metadataCache.updateXAttrs("foobar", xattrs); + assertEquals("bla", metadataCache.getXAttr("foobar", "newAttr").getFirst()); + metadataCache.updateXAttr("foobar", "newAttr", "blub"); + assertEquals("blub", metadataCache.getXAttr("foobar", "newAttr").getFirst()); + + // update non-existing xattr + metadataCache.updateXAttr("foobar", "nonExistingXattr", "bar"); + assertEquals("bar", metadataCache.getXAttr("foobar", "nonExistingXattr").getFirst()); + } + + @Test + public void testUpdateStatTime() throws Exception { + metadataCache.updateStatTime("do not exists", 10000, Setattrs.SETATTR_ATIME.getNumber()); + metadataCache.updateXAttrs("foobar", getDummyXattrs()); + metadataCache.updateStatTime("foobar", 10000, Setattrs.SETATTR_ATIME.getNumber()); + + metadataCache.updateStat("foobar", getIntializedStatBuilder().build()); + int toSet = Setattrs.SETATTR_ATIME.getNumber() | Setattrs.SETATTR_CTIME.getNumber() + | Setattrs.SETATTR_MTIME.getNumber(); + metadataCache.updateStatTime("foobar", 13337, toSet); + Stat aStat = metadataCache.getStat("foobar"); + assertEquals(13337l * 1000 * 1000 * 1000, aStat.getCtimeNs()); + assertEquals(13337l * 1000 * 1000 * 1000, aStat.getMtimeNs()); + assertEquals(13337l * 1000 * 1000 * 1000, aStat.getAtimeNs()); + } + + @Test + public void testUpdateAttributes() throws Exception { + metadataCache.updateStatAttributes("do not exist", getIntializedStatBuilder().build(), + Setattrs.SETATTR_GID.getNumber()); + metadataCache.updateXAttrs("foobar", getDummyXattrs()); + metadataCache.updateStatAttributes("foobar", getIntializedStatBuilder().build(), + Setattrs.SETATTR_GID.getNumber()); + + metadataCache.updateStat("foobar", getIntializedStatBuilder().setTruncateEpoch(10).build()); + // Update stat with greater Truncate Epoch + Stat updateStat = getIntializedStatBuilder().setUserId("TESTUSER").setGroupId("TESTGROUP") + .setAtimeNs(13337).setCtimeNs(13337).setMtimeNs(13337).setSize(11111).setTruncateEpoch(11) + .setAttributes(1000).build(); + int toSet = Setattrs.SETATTR_ATIME.getNumber() | Setattrs.SETATTR_CTIME.getNumber() + | Setattrs.SETATTR_MTIME.getNumber() | Setattrs.SETATTR_GID.getNumber() + | Setattrs.SETATTR_UID.getNumber() | Setattrs.SETATTR_SIZE.getNumber() + | Setattrs.SETATTR_ATTRIBUTES.getNumber(); + metadataCache.updateStatAttributes("foobar", updateStat, toSet); + Stat getStat = metadataCache.getStat("foobar"); + assertEquals(13337l, getStat.getCtimeNs()); + assertEquals(13337l, getStat.getMtimeNs()); + assertEquals(13337l, getStat.getAtimeNs()); + assertEquals("TESTUSER", getStat.getUserId()); + assertEquals("TESTGROUP", getStat.getGroupId()); + assertEquals(1000, getStat.getAttributes()); + assertEquals(11, getStat.getTruncateEpoch()); + assertEquals(11111, getStat.getSize()); + + // Update stat with equal Truncate Epoch. + Stat secondStat = getIntializedStatBuilder().setTruncateEpoch(11).setSize(22222).build(); + metadataCache.updateStatAttributes("foobar", secondStat, toSet); + getStat = metadataCache.getStat("foobar"); + assertEquals(secondStat.getCtimeNs(), getStat.getCtimeNs()); + assertEquals(secondStat.getMtimeNs(), getStat.getMtimeNs()); + assertEquals(secondStat.getAtimeNs(), getStat.getAtimeNs()); + assertEquals(secondStat.getUserId(), getStat.getUserId()); + assertEquals(secondStat.getGroupId(), getStat.getGroupId()); + assertEquals(secondStat.getAttributes(), getStat.getAttributes()); + assertEquals(11, getStat.getTruncateEpoch()); + assertEquals(22222, getStat.getSize()); + } + + @Test + public void testInvalidateDirEntry() throws Exception { + metadataCache.invalidateDirEntry("not exists", "no name"); + metadataCache.updateStat("foobar", getIntializedStatBuilder().build()); + metadataCache.invalidateDirEntry("foobar", "no name"); + + DirectoryEntries entries = getDummyDirEntries(); + DirectoryEntry entry = DirectoryEntry.newBuilder().setName("dir1") + .setStbuf(getIntializedStatBuilder()).build(); + DirectoryEntry entry2 = DirectoryEntry.newBuilder().setName("dir2") + .setStbuf(getIntializedStatBuilder()).build(); + + entries = entries.toBuilder().addEntries(entry).addEntries(entry2).build(); + metadataCache.updateDirEntries("foobar", entries); + + DirectoryEntries getEntries = metadataCache.getDirEntries("foobar", 0, 10); + assertEquals(entries, getEntries); + metadataCache.invalidateDirEntry("foobar", "dir2"); + getEntries = metadataCache.getDirEntries("foobar", 0, 10); + + assertEquals(2, getEntries.getEntriesCount()); + for (DirectoryEntry dirEntry : getEntries.getEntriesList()) { + assertNotSame("dir2", dirEntry.getName()); + } + } + + @Test + public void testInvalidateDirEntries() throws Exception { + metadataCache.updateDirEntries("foobar", getDummyDirEntries()); + assertEquals(getDummyDirEntries(), metadataCache.getDirEntries("foobar", 0, 100)); + metadataCache.invalidateDirEntries("foobar"); + assertNull(metadataCache.getDirEntries("foobar", 0, 100)); + } + + @Test + public void testGetXAttrSize() throws Exception { + metadataCache.updateXAttrs("foobar", getDummyXattrs()); + metadataCache.updateXAttr("foobar", "aNewXattr", "0123456789"); + Tupel tupel = metadataCache.getXAttrSize("foobar", "aNewXattr"); + assertEquals(10, tupel.getFirst().intValue()); + assertTrue(tupel.getSecond()); + } + + private listxattrResponse getDummyXattrs() { + return listxattrResponse.newBuilder() + .addXattrs(XAttr.newBuilder().setName("foo").setValue("bar").build()).build(); + } + + private DirectoryEntries getDummyDirEntries() { + DirectoryEntry entry = DirectoryEntry.newBuilder().setName("foo") + .setStbuf(getIntializedStatBuilder()).build(); + DirectoryEntries entries = DirectoryEntries.newBuilder().addEntries(entry).build(); + return entries; + } + +} diff --git a/java/servers/test/org/xtreemfs/common/libxtreemfs/RPCCallerTest.java b/java/servers/test/org/xtreemfs/common/libxtreemfs/RPCCallerTest.java new file mode 100644 index 0000000..6fe624e --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/libxtreemfs/RPCCallerTest.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.Map; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.libxtreemfs.RPCCaller.CallGenerator; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.json.JSONParser; +import org.xtreemfs.foundation.json.JSONString; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SERVICES; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +public class RPCCallerTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static DIRRequestDispatcher dir; + + private static DIRConfig dirConfig; + + private static TestEnvironment testEnv; + + private static UserCredentials userCredentials; + + private static Auth auth; + + private static String dirServiceAddress; + private static String mrcServiceAddress; + + private static MRCServiceClient mrcServiceClient; + + private static OSDServiceClient osdServiceClient; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); + + dirConfig = SetupUtils.createDIRConfig(); + dir = new DIRRequestDispatcher(dirConfig, SetupUtils.createDIRdbsConfig()); + dir.startup(); + dir.waitForStartup(); + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_CLIENT, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.RPC_CLIENT, + TestEnvironment.Services.MRC, TestEnvironment.Services.OSD, TestEnvironment.Services.OSD }); + testEnv.start(); + + userCredentials = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + auth = RPCAuthentication.authNone; + dirServiceAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + mrcServiceAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + mrcServiceClient = new MRCServiceClient(testEnv.getRpcClient(), null); + osdServiceClient = new OSDServiceClient(testEnv.getRpcClient(), null); + } + + @AfterClass + public static void shutdownTest() throws Exception { + testEnv.shutdown(); + dir.shutdown(); + dir.waitForShutdown(); + } + + @SuppressWarnings("unchecked") + @Test + public void testRedirect() throws Exception { + final String VOLUME_NAME = "testVolume"; + final String FILE_PATH = "replicatedFile"; + final int NUMBER_OF_REPLICAS = 2; + + Options options = new Options(); + ClientImplementation client = (ClientImplementation) ClientFactory.createClient(dirServiceAddress, + userCredentials, null, options); + client.start(); + client.createVolume(mrcServiceAddress, auth, userCredentials, VOLUME_NAME); + + Volume volume = client.openVolume(VOLUME_NAME, null, options); + + // set default replication policy for root dir + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE, + NUMBER_OF_REPLICAS, REPL_FLAG.REPL_FLAG_FULL_REPLICA.getNumber()); + + String replPolString = volume.getXAttr(userCredentials, "/", "xtreemfs.default_rp"); + JSONString policy = new JSONString(replPolString); + Map jsonMap = (Map) JSONParser.parseJSON(policy); + + assertEquals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE, jsonMap.get("update-policy").toString()); + + UUIDIterator mrcUUIDIterator = new UUIDIterator(); + mrcUUIDIterator.addUUID(mrcServiceAddress); + + openRequest request = openRequest + .newBuilder() + .setVolumeName(VOLUME_NAME) + .setPath(FILE_PATH) + .setFlags( + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber()).setMode(0777) + .setAttributes(0).build(); + + openResponse response = RPCCaller. syncCall(SERVICES.MRC, userCredentials, + auth, options, client, mrcUUIDIterator, true, request, + new CallGenerator() { + @Override + public RPCResponse executeCall(InetSocketAddress server, Auth authHeader, + UserCredentials userCreds, openRequest input) throws IOException { + return mrcServiceClient.open(server, authHeader, userCreds, input); + } + }); + + FileInfo fileInfo = new FileInfo((VolumeImplementation) volume, Helper.extractFileIdFromXcap(response + .getCreds().getXcap()), FILE_PATH, false, response.getCreds().getXlocs(), + Helper.generateVersion4UUID()); + + FileHandleImplementation fileHandle = fileInfo.createFileHandle(response.getCreds().getXcap(), false); + + // write testfile + String data = "Need a testfile? Why not (\\|)(+,,,+)(|/)?"; + fileHandle.write(userCredentials, data.getBytes(), data.length(), 0); + + // create uuidIterator with switched OSDs in order force a Redirect Exception + UUIDIterator uuidIterator = new UUIDIterator(); + uuidIterator.addUUID(response.getCreds().getXlocs().getReplicas(1).getOsdUuids(0)); + uuidIterator.addUUID(response.getCreds().getXlocs().getReplicas(0).getOsdUuids(0)); + + // make a write with the new uuidIterator + String overwriteData = "1111111111111111111111111111111111111111111111111111"; + final ReusableBuffer overwriteBuf = ReusableBuffer.wrap(overwriteData.getBytes()); + writeRequest.Builder writeReq = writeRequest.newBuilder(); + writeReq.setFileCredentials(response.getCreds()); + writeReq.setFileId(response.getCreds().getXcap().getFileId()); + writeReq.setObjectNumber(0); + writeReq.setObjectVersion(0); + writeReq.setOffset(0); + writeReq.setLeaseTimeout(0); + + ObjectData objectData = ObjectData.newBuilder().setChecksum(0).setInvalidChecksumOnOsd(false) + .setZeroPadding(0).build(); + writeReq.setObjectData(objectData); + + RPCCaller. syncCall(SERVICES.OSD, userCredentials, auth, options, + client, uuidIterator, false, writeReq.build(), + new CallGenerator() { + + @Override + public RPCResponse executeCall(InetSocketAddress server, + Auth authHeader, UserCredentials userCreds, writeRequest input) + throws IOException { + // TODO Auto-generated method stub + return osdServiceClient.write(server, authHeader, userCreds, input, overwriteBuf); + } + }); + + // Read from file. + byte[] readData = new byte[overwriteData.length()]; + int readCount = fileHandle.read(userCredentials, readData, overwriteData.length(), 0); + + assertEquals(overwriteData.length(), readCount); + for (int i = 0; i < overwriteData.length(); i++) { + assertEquals(readData[i], overwriteData.getBytes()[i]); + } + } +} diff --git a/java/servers/test/org/xtreemfs/common/libxtreemfs/ReadOnlyReplicationTest.java b/java/servers/test/org/xtreemfs/common/libxtreemfs/ReadOnlyReplicationTest.java new file mode 100644 index 0000000..22fccbe --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/libxtreemfs/ReadOnlyReplicationTest.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * 2012 by Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import java.io.IOException; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * Read a partial replica "simultaneously" by two threads. + * + * This test was originally created to track a problem in the Read-Only replication which occurred when the + * on-demand replication of the same object was triggered by two concurrent requests. However, the test failed + * to reproduce the issue and it was resolved otherwise. + * + * @author mberlin + * + */ +public class ReadOnlyReplicationTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static TestEnvironment testEnv; + + private static UserCredentials userCredentials; + + private static Auth auth = RPCAuthentication.authNone; + + private static String mrcAddress; + + private static String dirAddress; + + private static ClientImplementation client; + + private static Options options; + + @BeforeClass + public static void initializeTest() throws Exception { + FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); + Logging.start(Logging.LEVEL_WARN); + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, TestEnvironment.Services.DIR_CLIENT, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.RPC_CLIENT, + TestEnvironment.Services.MRC, TestEnvironment.Services.OSD, TestEnvironment.Services.OSD}); + testEnv.start(); + + userCredentials = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + new MRCServiceClient(testEnv.getRpcClient(), testEnv.getMRCAddress()); + + options = new Options(); + client = (ClientImplementation) ClientFactory + .createClient(dirAddress, userCredentials, null, options); + client.start(); + } + + @AfterClass + public static void shutdownTest() throws Exception { + testEnv.shutdown(); + + client.shutdown(); + } + + @Test + public void testMultipleReadRequests() throws Exception { + final String volumeName = "testMarkReplicaAsComplete"; + final String path = "/test.txt"; + + // Create client. + Client client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + // Create and open volume. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + Volume volume = client.openVolume(volumeName, null, options); + volume.start(); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY, 2, + ReplicationFlags.setPartialReplica(ReplicationFlags.setSequentialPrefetchingStrategy(0))); + volume.setOSDSelectionPolicy(userCredentials, + Helper.policiesToString(new OSDSelectionPolicyType[] { OSDSelectionPolicyType.OSD_SELECTION_POLICY_FILTER_DEFAULT })); + volume.setReplicaSelectionPolicy(userCredentials, + Helper.policiesToString(new OSDSelectionPolicyType[] { OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_REVERSE })); + + // open FileHandle. + FileHandle fileHandle = volume.openFile( + userCredentials, + path, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0777); + // write some content. + String content = ""; + for (int i = 0; i < 128 * 1024 / 12; i++) { + content = content.concat("Hello World "); + } + byte[] bytesIn = content.getBytes(); + int length = bytesIn.length; + fileHandle.write(userCredentials, bytesIn, length, 0); + fileHandle.close(); + + // Read file (probably from the partial replica). + final FileHandle fileHandleRead = volume.openFile(userCredentials, path, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + final int readLength = 64 * 1024; + Thread th1 = new Thread() { + @Override + public void run() { + byte[] bytesOut1 = new byte[readLength]; + try { + fileHandleRead.read(userCredentials, bytesOut1, readLength, 0); + } catch (IOException e) { + e.printStackTrace(); + } + } + }; + Thread th2 = new Thread() { + @Override + public void run() { + byte[] bytesOut2 = new byte[readLength]; + try { + fileHandleRead.read(userCredentials, bytesOut2, readLength, readLength); + } catch (IOException e) { + e.printStackTrace(); + } + } + }; + + th1.start(); + Thread.sleep((long) (Math.random() * 0)); + th2.start(); + + th1.join(); + th2.join(); + fileHandleRead.close(); + + volume.close(); + client.shutdown(); + } +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/common/libxtreemfs/StripeTranslatorTest.java b/java/servers/test/org/xtreemfs/common/libxtreemfs/StripeTranslatorTest.java new file mode 100644 index 0000000..fb4c952 --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/libxtreemfs/StripeTranslatorTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2012-2013 by Jens V. Fischer, Zuse Institute Berlin + * + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.common.libxtreemfs; + +import static org.junit.Assert.assertTrue; + +import java.lang.reflect.Field; +import java.util.Vector; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.test.TestHelper; + +/** + * Test against the bug from Issue 277 (erroneous calculation of object offsets for read requests). The test + * iterates over an offset range from 1.5 to 2.5 GiB in steps of 109 ensuring that offset calculation only + * produces offsets greater equal 0. The range is chosen to include offsets lesser equal and greater than + * Integer.MAX_VALUE. A prime is used as step to enlarge the coverage of the range of offsets. + * + * @author jensvfischer + */ +public class StripeTranslatorTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static final int XTREEMFS_BLOCK_SIZE_IN_BYTES = 128 * 1024; + private static final int GiB_IN_BYTES = 1024 * 1024 * 1024; + private static int count = XTREEMFS_BLOCK_SIZE_IN_BYTES; + private static long maxOffset = (long) (2.5 * (long) GiB_IN_BYTES); + private static StripeTranslator translator = new StripeTranslatorRaid0(); + + /** + * Test for read requests + */ + @Test + public void testReadRequestOffsetCalculation() throws NoSuchFieldException, IllegalAccessException { + + for (long offset = (long) (1.5 * (long) GiB_IN_BYTES); offset < maxOffset; offset += 997) { + + // Map offsets + Vector operations = new Vector(); + translator.translateReadRequest(count, offset, + StripingPolicy.newBuilder().setStripeSize(128).setType(StripingPolicyType.STRIPING_POLICY_RAID0) + .setWidth(1).build(), operations); + + // make the private field 'reqOffset" of ReadOperation accessible + Field reqOffset = ReadOperation.class.getDeclaredField("reqOffset"); + reqOffset.setAccessible(true); + + // assert that all object offsets are greater equal zero + for (ReadOperation operation : operations) { + assertTrue((Integer) reqOffset.get(operation) >= 0); + } + } + } + + /** + * Test for write requests. A larger prime is chosen because the offset calculation for WriteRequest is + * much slower. + */ + @Test + public void testWriteRequestOffsetCalculation() throws NoSuchFieldException, IllegalAccessException { + + byte[] data = new byte[XTREEMFS_BLOCK_SIZE_IN_BYTES]; + ReusableBuffer buffer = ReusableBuffer.wrap(data); + + for (long offset = (long) (1.5 * (long) GiB_IN_BYTES); offset < maxOffset; offset += 9973) { + + // Map offsets + Vector operations = new Vector(); + translator.translateWriteRequest(count, offset, + StripingPolicy.newBuilder().setStripeSize(128).setType(StripingPolicyType.STRIPING_POLICY_RAID0) + .setWidth(1).build(), buffer, operations); + + // make the private field 'reqOffset" of WriteOperation accessible + Field reqOffset = WriteOperation.class.getDeclaredField("reqOffset"); + reqOffset.setAccessible(true); + + // assert that all object offsets are greater equal zero + for (WriteOperation operation : operations) { + assertTrue((Integer) reqOffset.get(operation) >= 0); + } + + } + } +} diff --git a/java/servers/test/org/xtreemfs/common/libxtreemfs/UUIDIteratorTest.java b/java/servers/test/org/xtreemfs/common/libxtreemfs/UUIDIteratorTest.java new file mode 100644 index 0000000..95d181b --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/libxtreemfs/UUIDIteratorTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2008-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.util.LinkedList; +import java.util.List; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.libxtreemfs.exceptions.UUIDIteratorListIsEmpyException; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestHelper; + + +public class UUIDIteratorTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + @BeforeClass + public static void initializeTest() throws Exception { + } + + @Before + public void setUp() throws Exception { + FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); + } + + @Test + public void testUUIDIterator() throws Exception { + + final String UUID_STRING1 = "uuidstring1"; + final String UUID_STRING2 = "uuidstring2"; + final String UUID_STRING3 = "uuidstring3"; + + UUIDIterator uuidIterator = new UUIDIterator(); + + uuidIterator.addUUID(UUID_STRING1); + uuidIterator.addUUID(UUID_STRING2); + uuidIterator.addUUID(UUID_STRING3); + + // getting the current UUID should not increase the pointer + assertEquals(UUID_STRING1, uuidIterator.getUUID()); + assertEquals(UUID_STRING1, uuidIterator.getUUID()); + + + // mark current UUID as faield. UUID pointer should be increased. + uuidIterator.markUUIDAsFailed(uuidIterator.getUUID()); + assertEquals(UUID_STRING2, uuidIterator.getUUID()); + + uuidIterator.markUUIDAsFailed(uuidIterator.getUUID()); + assertEquals(UUID_STRING3, uuidIterator.getUUID()); + + // The end of the UUID List is now reached. uuidIterator should start from beginning of the + // list. + uuidIterator.markUUIDAsFailed(uuidIterator.getUUID()); + assertEquals(UUID_STRING1, uuidIterator.getUUID()); + + // After clearing the UUIDIterator and getUUID call should raise an UUIDIteratorListIsEmpyException + uuidIterator.clear(); + try { + uuidIterator.getUUID(); + fail("UUIDIteratorListIsEmptyExcaption should have been raised"); + } catch (UUIDIteratorListIsEmpyException e) { + } + + // clear and add should set current UUID to the added uuid. + uuidIterator.clearAndAddUUID(UUID_STRING1); + assertEquals(UUID_STRING1, uuidIterator.getUUID()); + + // since there is only one UUID in the iterator after marking that as failed it should return + // the same UUID + uuidIterator.markUUIDAsFailed(uuidIterator.getUUID()); + assertEquals(UUID_STRING1, uuidIterator.getUUID()); + + // debug string should also work! + uuidIterator.debugString(); + + } + + @Test + public void testAddUuidCollection() { + List uuidList = new LinkedList(); + uuidList.add("uuidstring1"); + uuidList.add("uuidstring2"); + uuidList.add("uuidstring3"); + + UUIDIterator iterator = new UUIDIterator(); + iterator.addUUIDs(uuidList); + + assertEquals(3, iterator.size()); + } + + @Test + public void testSetCurrentUuid() throws Exception { + final String UUID_STRING1 = "uuidstring1"; + final String UUID_STRING2 = "uuidstring2"; + final String UUID_STRING3 = "uuidstring3"; + + UUIDIterator iterator = new UUIDIterator(); + iterator.addUUID(UUID_STRING1); + iterator.addUUID(UUID_STRING2); + + assertEquals(2, iterator.size()); + assertEquals(UUID_STRING1, iterator.getUUID()); + + // uuid already in iterator. Should only be set. + iterator.setCurrentUUID(UUID_STRING2); + assertEquals(UUID_STRING2, iterator.getUUID()); + assertEquals(2, iterator.size()); + + // new UUID, should be added and set! + iterator.setCurrentUUID(UUID_STRING3); + assertEquals(UUID_STRING3, iterator.getUUID()); + assertEquals(3, iterator.size()); + } + +} diff --git a/java/servers/test/org/xtreemfs/common/libxtreemfs/UUIDResolverTest.java b/java/servers/test/org/xtreemfs/common/libxtreemfs/UUIDResolverTest.java new file mode 100644 index 0000000..92ba658 --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/libxtreemfs/UUIDResolverTest.java @@ -0,0 +1,140 @@ +package org.xtreemfs.common.libxtreemfs; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.VolumeNotFoundException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +public class UUIDResolverTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment testEnv; + + private UserCredentials userCredentials; + + private final Auth auth = RPCAuthentication.authNone; + + @Before + public void setUp() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.RPC_CLIENT, TestEnvironment.Services.MRC, TestEnvironment.Services.OSD }); + testEnv.start(); + + userCredentials = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + } + + @After + public void tearDown() throws Exception { + testEnv.shutdown(); + } + + @Test + public void testUUIDResolver() throws Exception { + final String VOLUME_NAME_1 = "foobar"; + final String VOLUME_NAME_2 = "barfoo"; + + Options options = new Options(); + + String dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + + ClientImplementation client = (ClientImplementation) ClientFactory.createClient(dirAddress, userCredentials, + null, options); + client.start(); + + UUIDResolver resolver = client; + + String mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + // Create volumes + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME_1); + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME_2); + + // get and MRC UUID for the volume. Should be that from the only MRC. + String uuidString = client.volumeNameToMRCUUID(VOLUME_NAME_1); + assertEquals(SetupUtils.getMRC1UUID().toString(), uuidString); + + // same for the second volume + uuidString = resolver.volumeNameToMRCUUID(VOLUME_NAME_2); + assertEquals(SetupUtils.getMRC1UUID().toString(), uuidString); + + // should also work with snapshots + uuidString = resolver.volumeNameToMRCUUID(VOLUME_NAME_2 + "@snapshotname"); + assertEquals(SetupUtils.getMRC1UUID().toString(), uuidString); + + // this should work if we use UUIDIterator, too. + UUIDIterator uuidIterator = new UUIDIterator(); + client.volumeNameToMRCUUID(VOLUME_NAME_1, uuidIterator); + assertEquals(SetupUtils.getMRC1UUID().toString(), uuidIterator.getUUID()); + + // resolve MRC UUID + String address = resolver.uuidToAddress(SetupUtils.getMRC1UUID().toString()); + assertEquals(testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(), address); + + // resolve OSD UUID + address = resolver.uuidToAddress(SetupUtils.createMultipleOSDConfigs(1)[0].getUUID().toString()); + assertEquals(testEnv.getOSDAddress().getHostName() + ":" + testEnv.getOSDAddress().getPort(), address); + + // resolve non existing uuid + try { + address = resolver.uuidToAddress("this-is-not-a-valid-uuid"); + fail("Resolve invalid uuid. Should have thrown an exception"); + } catch (AddressToUUIDNotFoundException e) { + } + + // resolve non exsiting volume name + try { + uuidString = resolver.volumeNameToMRCUUID("non-existing-volume"); + fail("Volume doensn't exist! Should have thrown an exception"); + } catch (VolumeNotFoundException e) { + } + + // resolve non existing volume with uuidIterator. + try { + resolver.volumeNameToMRCUUID("non-existing-volume", new UUIDIterator()); + fail("Volume doensn't exist! Should have thrown an exception"); + } catch (VolumeNotFoundException e) { + } + + // if there is no correct connection the resolver cant resolve and + // should throw an VolumeNotFoundException + // Do not retry here to avoid unnecessary lengthy executions. + options.setMaxTries(1); + ClientImplementation clientFail = (ClientImplementation) ClientFactory.createClient("doesntexists:44444", + userCredentials, null, options); + clientFail.start(); + UUIDResolver resolverFail = clientFail; + try { + resolverFail.volumeNameToMRCUUID("dummy-name"); + fail("There was no correct client initialization. Shouldn't " + "be able to resovle something"); + } catch (VolumeNotFoundException e) { + } + + // should work with uuidIterator, too + try { + resolverFail.volumeNameToMRCUUID("dummy-name", new UUIDIterator()); + fail("There was no correct client initialization. Shouldn't " + "be able to resovle something"); + } catch (VolumeNotFoundException e) { + } + + // shutdown the client + client.shutdown(); + } + +} diff --git a/java/servers/test/org/xtreemfs/common/libxtreemfs/VolumeTest.java b/java/servers/test/org/xtreemfs/common/libxtreemfs/VolumeTest.java new file mode 100644 index 0000000..2bff14d --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/libxtreemfs/VolumeTest.java @@ -0,0 +1,990 @@ +/* + * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.libxtreemfs; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.libxtreemfs.Volume.StripeLocation; +import org.xtreemfs.common.libxtreemfs.exceptions.PosixErrorException; +import org.xtreemfs.common.libxtreemfs.exceptions.VolumeNotFoundException; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.utils.MRCHelper.SysAttrs; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.*; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.*; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.*; + +public class VolumeTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static DIRRequestDispatcher dir; + + private static TestEnvironment testEnv; + + private static DIRConfig dirConfig; + + private static UserCredentials userCredentials; + + private static Auth auth = RPCAuthentication.authNone; + + private static String mrcAddress; + + private static String dirAddress; + + private static VivaldiCoordinates defaultCoordinates; + + private static String VOLUME_NAME = "foobar"; + + private static StripingPolicy defaultStripingPolicy; + + private static OSD[] osds; + private static OSDConfig[] configs; + + private static MRCServiceClient mrcClient; + + private static ClientImplementation client; + + private static Options options; + + @BeforeClass + public static void initializeTest() throws Exception { + FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); + + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + dirConfig = SetupUtils.createDIRConfig(); + dir = new DIRRequestDispatcher(dirConfig, SetupUtils.createDIRdbsConfig()); + dir.startup(); + dir.waitForStartup(); + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_CLIENT, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.RPC_CLIENT, + TestEnvironment.Services.MRC }); + testEnv.start(); + + userCredentials = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + defaultCoordinates = VivaldiCoordinates.newBuilder().setXCoordinate(0).setYCoordinate(0) + .setLocalError(0).build(); + defaultStripingPolicy = StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0) + .setStripeSize(128).setWidth(1).build(); + + osds = new OSD[4]; + configs = SetupUtils.createMultipleOSDConfigs(4); + + // start three OSDs + osds[0] = new OSD(configs[0]); + osds[1] = new OSD(configs[1]); + osds[2] = new OSD(configs[2]); + osds[3] = new OSD(configs[3]); + + mrcClient = new MRCServiceClient(testEnv.getRpcClient(), null); + + options = new Options(); + client = (ClientImplementation) ClientFactory + .createClient(dirAddress, userCredentials, null, options); + client.start(); + } + + @AfterClass + public static void shutdownTest() throws Exception { + for (int i = 0; i < osds.length; i++) { + if (osds[i] != null) { + osds[i].shutdown(); + } + + } + + testEnv.shutdown(); + dir.shutdown(); + dir.waitForShutdown(); + + client.shutdown(); + } + + @Test + public void testStatVFS() throws Exception, VolumeNotFoundException { + final String VOLUME_NAME_1 = "foobar"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME_1); + + Volume volume = client.openVolume(VOLUME_NAME_1, null, options); + + StatVFS volumeVFS = volume.statFS(userCredentials); + + MRCServiceClient mrcClient = new MRCServiceClient(testEnv.getRpcClient(), null); + + StatVFS mrcClientVFS = null; + RPCResponse resp = null; + try { + statvfsRequest input = statvfsRequest.newBuilder().setVolumeName(VOLUME_NAME_1).setKnownEtag(0) + .build(); + resp = mrcClient.statvfs(testEnv.getMRCAddress(), auth, userCredentials, input); + mrcClientVFS = resp.get(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (resp != null) { + resp.freeBuffers(); + } + } + assertNotNull(volumeVFS); + assertEquals(mrcClientVFS, volumeVFS); + } + + @Test + public void testReadDirMultipleChunks() throws Exception { + options.setReaddirChunkSize(2); + + VOLUME_NAME = "testReadDirMultipleChunks"; + final String TESTFILE = "test"; + final int fileCount = 10; + + // create volume + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME, 0, userCredentials.getUsername(), + userCredentials.getGroups(0), AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, + StripingPolicyType.STRIPING_POLICY_RAID0, defaultStripingPolicy.getStripeSize(), + defaultStripingPolicy.getWidth(), new ArrayList()); + + Volume volume = client.openVolume(VOLUME_NAME, null, options); + + // create some files + for (int i = 0; i < fileCount; i++) { + FileHandle fh = volume.openFile(userCredentials, "/" + TESTFILE + i, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber()); + fh.close(); + } + + // test 'readDir' across multiple readDir chunks. + DirectoryEntries entrySet = null; + + entrySet = volume.readDir(userCredentials, "/", 0, 1000, false); + assertEquals(2 + fileCount, entrySet.getEntriesCount()); + assertEquals("..", entrySet.getEntries(0).getName()); + assertEquals(".", entrySet.getEntries(1).getName()); + for (int i = 0; i < fileCount; i++) { + assertEquals(TESTFILE + i, entrySet.getEntries(2 + i).getName()); + } + } + + @Test + public void testCreateDelete() throws Exception { + VOLUME_NAME = "testCreateDelete"; + // Both directories should be created under "/" + final String DIR1 = "/testdir1"; + final String DIR2 = "testdir2"; + + final String TESTFILE = "testfile"; + // create volume + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME, 0, userCredentials.getUsername(), + userCredentials.getGroups(0), AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, + StripingPolicyType.STRIPING_POLICY_RAID0, defaultStripingPolicy.getStripeSize(), + defaultStripingPolicy.getWidth(), new ArrayList()); + + Volume volume = client.openVolume(VOLUME_NAME, null, options); + + // create some files and directories + try { + volume.createDirectory(userCredentials, DIR1, 0755); + volume.createDirectory(userCredentials, DIR2, 0755); + } catch (IOException ioe) { + fail("failed to create testdirs"); + } + + for (int i = 0; i < 10; i++) { + FileHandle fh = volume.openFile(userCredentials, DIR1 + "/" + TESTFILE + i, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber()); + fh.close(); + } + + // // try to create a file w/o a name + try { + volume.openFile(userCredentials, "", SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber()); + fail("missing filename"); + } catch (Exception e) { + } + + // try to create an already existing file + try { + volume.openFile(userCredentials, DIR1 + "/" + TESTFILE + "1", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_EXCL.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber()); + fail("file already exists"); + } catch (Exception e) { + } + + // file in file creation should fail + try { + volume.openFile(userCredentials, DIR1 + "/" + TESTFILE + "1/foo.txt", + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber()); + fail("file in file creation"); + } catch (Exception e) { + } + + // should fail + try { + volume.createDirectory(userCredentials, "/", 0); + fail("directory already exists"); + } catch (PosixErrorException exc) { + } + + // test 'readDir' and 'stat' + DirectoryEntries entrySet = null; + + entrySet = volume.readDir(userCredentials, "", 0, 1000, false); + assertEquals(4, entrySet.getEntriesCount()); + assertEquals("..", entrySet.getEntries(0).getName()); + assertEquals(".", entrySet.getEntries(1).getName()); + assertEquals(DIR1, "/" + entrySet.getEntries(2).getName()); + assertEquals("/" + DIR2, "/" + entrySet.getEntries(3).getName()); + + entrySet = volume.readDir(userCredentials, DIR1, 0, 1000, false); + assertEquals(12, entrySet.getEntriesCount()); + + // test 'delete' + volume.unlink(userCredentials, DIR1 + "/" + TESTFILE + "4"); + entrySet = volume.readDir(userCredentials, DIR1, 0, 1000, false); + assertEquals(11, entrySet.getEntriesCount()); + + volume.removeDirectory(userCredentials, DIR2); + entrySet = volume.readDir(userCredentials, "", 0, 1000, false); + assertEquals(3, entrySet.getEntriesCount()); + } + + @Test + public void testCreateDirWithEmptyPathComponents() throws Exception { + VOLUME_NAME = "testCreateDirWithEmptyPathComponents"; + // Both directories should be created under "/" + final String DIR1 = "/test"; + final String DIR2 = "/test//"; + final String DIR3 = "/test//testdir"; + + // create volume + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME, 0, userCredentials.getUsername(), + userCredentials.getGroups(0), AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, + StripingPolicyType.STRIPING_POLICY_RAID0, defaultStripingPolicy.getStripeSize(), + defaultStripingPolicy.getWidth(), new ArrayList()); + + Volume volume = client.openVolume(VOLUME_NAME, null, options); + + // create some files and directories + try { + volume.createDirectory(userCredentials, DIR1, 0755); + volume.createDirectory(userCredentials, DIR3, 0755); + } catch (IOException ioe) { + fail("failed to create testdirs"); + } + + try { + volume.createDirectory(userCredentials, DIR2, 0755); + fail("existing directory could be created"); + } catch (IOException ioe) {} + + // test 'readDir' and 'stat' + DirectoryEntries entrySet = null; + + entrySet = volume.readDir(userCredentials, DIR2, 0, 1000, false); + assertEquals(3, entrySet.getEntriesCount()); + assertEquals("..", entrySet.getEntries(0).getName()); + assertEquals(".", entrySet.getEntries(1).getName()); + assertEquals("/testdir", "/" + entrySet.getEntries(2).getName()); + + entrySet = volume.readDir(userCredentials, DIR3, 0, 1000, false); + assertEquals(2, entrySet.getEntriesCount()); + + volume.removeDirectory(userCredentials, DIR3); + entrySet = volume.readDir(userCredentials, DIR1, 0, 1000, false); + assertEquals(2, entrySet.getEntriesCount()); + } + + @Test + public void testHardLink() throws Exception { + VOLUME_NAME = "testHardLink"; + final String ORIG_FILE = "test.txt"; + final String LINKED_FILE = "test-link.txt"; + final String LINKED_FILE2 = "test-link2.txt"; + + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME, 0, userCredentials.getUsername(), + userCredentials.getGroups(0), AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, + StripingPolicyType.STRIPING_POLICY_RAID0, defaultStripingPolicy.getStripeSize(), + defaultStripingPolicy.getWidth(), new ArrayList()); + + // create file + openResponse open = null; + RPCResponse resp = null; + try { + resp = mrcClient.open(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME, ORIG_FILE, + FileAccessManager.O_CREAT, 0, 0777, defaultCoordinates); + open = resp.get(); + } finally { + if (resp != null) { + resp.freeBuffers(); + } + } + assertNotNull(open); + + // create link + Volume volume = client.openVolume(VOLUME_NAME, null, options); + volume.link(userCredentials, ORIG_FILE, LINKED_FILE); + + open = null; + resp = null; + try { + resp = mrcClient.open(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME, + "test-hardlink.txt", FileAccessManager.O_CREAT, 0, 0, defaultCoordinates); + open = resp.get(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (resp != null) { + resp.freeBuffers(); + } + } + assertNotNull(open); + + // check whether both filenames refer to the same file + Stat stat1 = null; + Stat stat2 = null; + RPCResponse resp1 = null; + RPCResponse resp2 = null; + try { + resp1 = mrcClient.getattr(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME, ORIG_FILE, + 0); + stat1 = resp1.get().getStbuf(); + + resp2 = mrcClient.getattr(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME, + LINKED_FILE, 0); + stat2 = resp2.get().getStbuf(); + + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (resp1 != null) { + resp1.freeBuffers(); + } + if (resp2 != null) { + resp.freeBuffers(); + } + } + assertNotNull(stat1); + assertNotNull(stat2); + + assertEquals(stat1.getIno(), stat1.getIno()); + assertEquals(2, stat1.getNlink()); + + // create another link to the second file + volume.link(userCredentials, LINKED_FILE, LINKED_FILE2); + + // check whether both links refer to the same file + stat1 = null; + stat2 = null; + resp1 = null; + resp2 = null; + try { + resp1 = mrcClient.getattr(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME, + LINKED_FILE, 0); + stat1 = resp1.get().getStbuf(); + + resp2 = mrcClient.getattr(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME, + LINKED_FILE2, 0); + stat2 = resp2.get().getStbuf(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (resp1 != null) { + resp1.freeBuffers(); + } + if (resp2 != null) { + resp2.freeBuffers(); + } + } + assertEquals(stat1.getIno(), stat2.getIno()); + assertEquals(3, stat1.getNlink()); + + // delete one of the links + volume.unlink(userCredentials, LINKED_FILE); + + // check whether remaining links refer to the same file + stat1 = null; + stat2 = null; + resp1 = null; + resp2 = null; + try { + resp1 = mrcClient.getattr(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME, ORIG_FILE, + 0); + stat1 = resp1.get().getStbuf(); + + resp2 = mrcClient.getattr(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME, + LINKED_FILE2, 0); + stat2 = resp2.get().getStbuf(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (resp1 != null) { + resp1.freeBuffers(); + } + if (resp2 != null) { + resp2.freeBuffers(); + } + } + assertEquals(stat1.getIno(), stat2.getIno()); + assertEquals(2, stat1.getNlink()); + + // delete the other two links + volume.unlink(userCredentials, ORIG_FILE); + volume.unlink(userCredentials, LINKED_FILE2); + + try { + mrcClient.getattr(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME, LINKED_FILE2, 0) + .get(); + fail("file should not exist anymore"); + } catch (Exception exc) { + } + + try { + mrcClient.getattr(testEnv.getMRCAddress(), auth, userCredentials, VOLUME_NAME, ORIG_FILE, 0) + .get(); + fail("file should not exist anymore"); + } catch (Exception exc) { + } + + // + // // create two links to a directory + // invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc, + // volumeName, "testDir1", 0)); + // try { + // invokeSync(client.link(mrcAddress, RPCAuthentication.authNone, uc, + // volumeName, "testDir1", + // "testDir1/testDir2")); + // fail("links to directories should not be allowed"); + // } catch (Exception exc) { + // } + // } + // + } + + @Test + public void testGetSetAttr() throws Exception { + VOLUME_NAME = "testGetSetAttr"; + + final String TESTFILE = "testfile"; + final String TESTDIR = "testdir"; + + final int TESTMODE = 0731; + + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + + volume.createDirectory(userCredentials, TESTDIR, TESTMODE); + FileHandle fh = volume.openFile(userCredentials, TESTDIR + "/" + TESTFILE, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber(), TESTMODE); + fh.close(); + + Stat stat = volume.getAttr(userCredentials, TESTDIR); + assertEquals(userCredentials.getUsername(), stat.getUserId()); + assertEquals(userCredentials.getGroups(0), stat.getGroupId()); + assertEquals(0, stat.getSize()); + assertTrue(stat.getAtimeNs() > 0); + assertTrue(stat.getCtimeNs() > 0); + assertTrue(stat.getMtimeNs() > 0); + assertTrue((stat.getMode() & TESTMODE) > 0); + assertEquals(1, stat.getNlink()); + + stat = volume.getAttr(userCredentials, TESTDIR + "/" + TESTFILE); + assertEquals(userCredentials.getUsername(), stat.getUserId()); + assertEquals(userCredentials.getGroups(0), stat.getGroupId()); + assertEquals(0, stat.getSize()); + assertTrue(stat.getAtimeNs() > 0); + assertTrue(stat.getCtimeNs() > 0); + assertTrue(stat.getMtimeNs() > 0); + assertTrue((stat.getMode() & TESTMODE) == TESTMODE); + assertEquals(1, stat.getNlink()); + + stat = stat.toBuilder().setGroupId("foobar").setUserId("FredFoobar").build(); + try { + volume.setAttr(userCredentials, TESTDIR, stat, Setattrs.SETATTR_UID.getNumber() + | Setattrs.SETATTR_GID.getNumber()); + fail("changing username and groups should be restricted to superuser"); + } catch (PosixErrorException e) { + } + + UserCredentials rootCreds = userCredentials.toBuilder().setUsername("root").setGroups(0, "root") + .build(); + + volume.setAttr(rootCreds, TESTDIR, stat, + Setattrs.SETATTR_UID.getNumber() | Setattrs.SETATTR_GID.getNumber()); + + stat = volume.getAttr(userCredentials, TESTDIR); + assertEquals("FredFoobar", stat.getUserId()); + assertEquals("foobar", stat.getGroupId()); + assertTrue((stat.getMode() & TESTMODE) > 0); + + stat = stat.toBuilder().setMode(0777).build(); + volume.setAttr(userCredentials, TESTDIR + "/" + TESTFILE, stat, Setattrs.SETATTR_MODE.getNumber()); + stat = volume.getAttr(userCredentials, TESTDIR + "/" + TESTFILE); + assertTrue((stat.getMode() & 0777) == 0777); + } + + @Test + public void testReplicaAddListRemove() throws Exception { + VOLUME_NAME = "testReplicaAddListRemove"; + final String fileName = "testfile"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + + // set replication update policy of the file + int flags = ReplicationFlags.setSequentialStrategy(0); + flags = ReplicationFlags.setFullReplica(flags); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE, + 2, flags); + FileHandle fileHandle = volume.openFile(userCredentials, fileName, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber(), 0777); + fileHandle.close(); + + assertEquals(2, volume.listReplicas(userCredentials, fileName).getReplicasCount()); + + String osdUUID = volume.getSuitableOSDs(userCredentials, fileName, 1).get(0); + Replica replica = Replica.newBuilder().addOsdUuids(osdUUID).setStripingPolicy(defaultStripingPolicy) + .setReplicationFlags(flags).build(); + volume.addReplica(userCredentials, fileName, replica); + assertEquals(3, volume.listReplicas(userCredentials, fileName).getReplicasCount()); + + volume.removeReplica(userCredentials, fileName, replica.getOsdUuids(0)); + assertEquals(2, volume.listReplicas(userCredentials, fileName).getReplicasCount()); + } + + @Test + public void testSetGetListXattr() throws Exception { + VOLUME_NAME = "testSetGetListXattr"; + final String TESTFILE = "testfile"; + + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + + FileHandle fh = volume.openFile(userCredentials, TESTFILE, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber()); + fh.close(); + + int initialNumberOfXattr = volume.listXAttrs(userCredentials, TESTFILE).getXattrsCount(); + + // This xattr should not exist + String xattr = volume.getXAttr(userCredentials, TESTFILE, "foobarasdf"); + assertNull(xattr); + + // and therefore should have no size + assertEquals(-1, volume.getXAttrSize(userCredentials, TESTFILE, "foobarasdf")); + + // creating a new Xattr should increase the number of xattrs + volume.setXAttr(userCredentials, TESTFILE, "foobarasdf", "nyancat", + XATTR_FLAGS.XATTR_FLAGS_CREATE); + + assertEquals(initialNumberOfXattr + 1, volume.listXAttrs(userCredentials, TESTFILE).getXattrsCount()); + + xattr = volume.getXAttr(userCredentials, TESTFILE, "foobarasdf"); + assertEquals("nyancat", xattr); + + // delete the created Xattr + volume.removeXAttr(userCredentials, TESTFILE, "foobarasdf"); + assertEquals(initialNumberOfXattr, volume.listXAttrs(userCredentials, TESTFILE).getXattrsCount()); + xattr = volume.getXAttr(userCredentials, TESTFILE, "foobarasdf"); + assertNull(xattr); + + // same with xtreemfs. attributes. + try { + xattr = volume.getXAttr(userCredentials, TESTFILE, "xtreemfs.nyancat"); + fail("nyancat is not a valid system attribute"); + } catch (Exception e) { + } + + xattr = volume.getXAttr(userCredentials, TESTFILE, + "xtreemfs." + SysAttrs.set_repl_update_policy.toString()); + assertEquals(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE, xattr); + + // read existing systemflag + xattr = volume.getXAttr(userCredentials, TESTFILE, "xtreemfs." + SysAttrs.object_type.toString()); + assertEquals("1", xattr); + } + + @Test(expected = PosixErrorException.class) + public void testReadLinkWithoutLink() throws Exception { + VOLUME_NAME = "testReadLinkWithoutLink"; + String fileName = "testfile"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + FileHandle fh = volume.openFile(userCredentials, fileName, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber()); + fh.close(); + volume.readLink(userCredentials, fileName); + } + + @Test + public void testReadLinkWithLink() throws Exception { + VOLUME_NAME = "testReadLinkWithLink"; + String fileName = "testfile"; + String linkName = "linkToFile"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + FileHandle fh = volume.openFile(userCredentials, fileName, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0777); + fh.close(); + volume.symlink(userCredentials, fileName, linkName); + assertEquals(fileName, volume.readLink(userCredentials, linkName)); + } + + @Test(expected = PosixErrorException.class) + public void testAccessFail() throws Exception { + VOLUME_NAME = "testAccessFail"; + String fileName = "testfile"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + FileHandle fh = volume.openFile(userCredentials, fileName, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0000); + fh.close(); + volume.access(userCredentials, fileName, 0777); + } + + @Test + public void testAccessSuccess() throws Exception { + VOLUME_NAME = "testAccessSuccess"; + String fileName = "testfile"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + FileHandle fh = volume.openFile(userCredentials, fileName, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0753); + fh.close(); + volume.access(userCredentials, fileName, 0753); + } + + @Test + public void testTruncate() throws Exception { + VOLUME_NAME = "testTruncate"; + String fileName = "testfile"; + String emptyFileName = "emptyFileName"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + FileHandleImplementation fileHandle = (FileHandleImplementation) volume.openFile(userCredentials, + fileName, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0777); + + String data = "1234567890"; + fileHandle.write(userCredentials, data.getBytes(), data.length(), 0); + fileHandle.flush(); + + assertEquals(data.length(), volume.getAttr(userCredentials, fileName).getSize()); + + volume.truncate(userCredentials, fileName, 5); + assertEquals(5, volume.getAttr(userCredentials, fileName).getSize()); + fileHandle.close(); + + fileHandle = (FileHandleImplementation) volume.openFile( + userCredentials, + emptyFileName, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0777); + assertEquals(0, fileHandle.getAttr(userCredentials).getSize()); + volume.truncate(userCredentials, emptyFileName, 1000); + assertEquals(1000, fileHandle.getAttr(userCredentials).getSize()); + fileHandle.close(); + } + + @Test + public void testRenameFile() throws Exception { + VOLUME_NAME = "testRenameFile"; + String fileName = "testfile"; + String renamedFileName = "renamed"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + FileHandle fh = volume.openFile(userCredentials, fileName, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0777); + fh.close(); + // nothing should happen + volume.rename(userCredentials, fileName, fileName); + DirectoryEntries dir = volume.readDir(userCredentials, "/", 0, 100, true); + assertEquals(fileName, dir.getEntries(2).getName()); + assertEquals(3, dir.getEntriesCount()); + + volume.rename(userCredentials, fileName, renamedFileName); + dir = volume.readDir(userCredentials, "/", 0, 100, true); + assertEquals(renamedFileName, dir.getEntries(2).getName()); + assertEquals(3, dir.getEntriesCount()); + } + + @Test + public void testGetXattrSize() throws Exception { + VOLUME_NAME = "testGetXattrSize"; + String fileName = "testfile"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + FileHandle fh = volume.openFile( + userCredentials, + fileName, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_SYNC.getNumber(), 0777); + fh.close(); + int size = volume.getXAttrSize(userCredentials, fileName, "xtreemfs.set_repl_update_policy"); + assertEquals(0, size); + size = volume.getXAttrSize(userCredentials, fileName, "xtreemfs.owner"); + assertEquals(userCredentials.getUsername().length(), size); + size = volume.getXAttrSize(userCredentials, fileName, "doesnt-exist"); + assertEquals(-1, size); + volume.setXAttr(userCredentials, fileName, "foo", "bar", XATTR_FLAGS.XATTR_FLAGS_CREATE); + size = volume.getXAttrSize(userCredentials, fileName, "foo"); + assertEquals(3, size); + size = volume.getXAttrSize(userCredentials, fileName, "doesnt-exist-in-cache"); + assertEquals(-1, size); + } + + // @Test + // public void testGetSuitableOSDs() throws Exception { + // VOLUME_NAME = "testGetSuitableOSDs"; + // final String fileName = "testfile"; + // client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + // Volume volume = client.openVolume(VOLUME_NAME, null, options); + // + // // set replication update policy of the file + // int flags = ReplicationFlags.setSequentialStrategy(0); + // flags = ReplicationFlags.setFullReplica(flags); + // volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE, + // 1, flags); + // FileHandle fileHandle = + // volume.openFile(userCredentials, fileName, + // SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber(), 0777); + // fileHandle.close(); + // + // assertEquals(configs[1].getUUID().toString(), volume.getSuitableOSDs(userCredentials, fileName, 1)); + // } + + @Test + public void testCreateListDirectory() throws Exception { + VOLUME_NAME = "testCreateListDirectory"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + + volume.createDirectory(userCredentials, "/DIR1", 0); + volume.createDirectory(userCredentials, "DIR2", 0); + DirectoryEntries dirEntries = volume.readDir(userCredentials, "/", 0, Integer.MAX_VALUE, true); + assertEquals(4, dirEntries.getEntriesCount()); + dirEntries = volume.readDir(userCredentials, "/", 0, 0, true); + assertEquals(4, dirEntries.getEntriesCount()); + assertEquals("..", dirEntries.getEntries(0).getName()); + assertEquals(".", dirEntries.getEntries(1).getName()); + assertEquals("DIR1", dirEntries.getEntries(2).getName()); + assertEquals("DIR2", dirEntries.getEntries(3).getName()); + } + + @Test + public void testCreateDirectoryRecursive() throws Exception { + VOLUME_NAME = "testCreateDirectoryRecursive"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + + final String directory1 = "/home/foo/bar/user/xtreemfs/test/bar/foo"; + final String directroy2 = "/home/foo/path/with/slash/at/end/"; + volume.createDirectory(userCredentials, directory1, 0777, true); + volume.createDirectory(userCredentials, directroy2, 0777, true); + + final String[] dirs1 = directory1.split("/"); + final String[] dirs2 = directroy2.split("/"); + + String tempdir = ""; + for (int i = 1; i < dirs1.length; i++) { + tempdir = tempdir + "/" + dirs1[i]; + assertTrue(isDirectory(volume, tempdir)); + } + + tempdir = ""; + for (int i = 1; i < dirs2.length; i++) { + tempdir = tempdir + "/" + dirs2[i]; + assertTrue(isDirectory(volume, tempdir)); + } + volume.close(); + } + + private boolean isDirectory(Volume volume, String path) throws IOException { + try { + Stat stat = volume.getAttr(userCredentials, path); + return (stat.getMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFDIR.getNumber()) > 0; + } catch (PosixErrorException pee) { + if (pee.getPosixError().equals(POSIXErrno.POSIX_ERROR_ENOENT)) { + return false; + } else { + throw pee; + } + } + } + + @Test + public void testGetStripeLocations() throws Exception { + VOLUME_NAME = "testGetStripeLocatations"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME); + Volume volume = client.openVolume(VOLUME_NAME, null, options); + + // set replication update policy of the file + int flags = ReplicationFlags.setSequentialStrategy(0); + flags = ReplicationFlags.setFullReplica(flags); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY, + 2, flags); + + final String FILENAME = "/foobar.tzt"; + FileHandle fileHandle = volume.openFile(userCredentials, FILENAME, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber(), 0777); + byte[] data = new byte[6]; + for (int i = 0; i < data.length; i++) { + data[i] = (byte) "FOOBAR".charAt(i); + } + fileHandle.write(userCredentials, data, data.length, 0); + fileHandle.close(); + List stripeLocations = volume.getStripeLocations(userCredentials, FILENAME, 0, 100); + assertEquals(1, stripeLocations.size()); + assertEquals(2, stripeLocations.get(0).getUuids().length); + assertEquals(2, stripeLocations.get(0).getHostnames().length); + assertEquals(0, stripeLocations.get(0).getStartSize()); + assertEquals(100, stripeLocations.get(0).getLength()); + + stripeLocations = volume.getStripeLocations(userCredentials, FILENAME, 200, 123); + assertEquals(1, stripeLocations.size()); + assertEquals(2, stripeLocations.get(0).getUuids().length); + assertEquals(2, stripeLocations.get(0).getHostnames().length); + assertEquals(200, stripeLocations.get(0).getStartSize()); + assertEquals(123, stripeLocations.get(0).getLength()); + + List suitableOsds = volume.getSuitableOSDs(userCredentials, FILENAME, 1); + Replica replica = Replica.newBuilder().setStripingPolicy(defaultStripingPolicy) + .setReplicationFlags(flags).addOsdUuids(suitableOsds.get(0)).build(); + volume.addReplica(userCredentials, FILENAME, replica); + + stripeLocations = volume.getStripeLocations(userCredentials, FILENAME, 0, 100); + assertEquals(1, stripeLocations.size()); + assertEquals(3, stripeLocations.get(0).getUuids().length); + assertEquals(3, stripeLocations.get(0).getHostnames().length); + assertEquals(0, stripeLocations.get(0).getStartSize()); + assertEquals(100, stripeLocations.get(0).getLength()); + + stripeLocations = volume.getStripeLocations(userCredentials, FILENAME, 200, 123); + assertEquals(1, stripeLocations.size()); + assertEquals(3, stripeLocations.get(0).getUuids().length); + assertEquals(3, stripeLocations.get(0).getHostnames().length); + assertEquals(200, stripeLocations.get(0).getStartSize()); + assertEquals(123, stripeLocations.get(0).getLength()); + + volume.close(); + } + + @Test + public void testGetStripeLocationsWithMultipleStripes() throws Exception { + VOLUME_NAME = "testGetStripeLocatationsWithMultipleStripes"; + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME, 0777, + userCredentials.getUsername(), userCredentials.getGroups(0), + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, + StripingPolicyType.STRIPING_POLICY_RAID0, 2, 1, new ArrayList()); + Volume volume = client.openVolume(VOLUME_NAME, options.generateSSLOptions(), options); + + // set replication update policy of the file + int replicationFlags = ReplicationFlags.setSequentialStrategy(0); + replicationFlags = ReplicationFlags.setFullReplica(replicationFlags); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY, + 2, replicationFlags); + + // create new striping policy with width 2 + StripingPolicy stripingPolicy = StripingPolicy.newBuilder().setStripeSize(2).setWidth(2) + .setType(StripingPolicyType.STRIPING_POLICY_RAID0).build(); + + // create file + final String FILENAME = "/foobar.tzt"; + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber(); + FileHandle fileHandle = volume.openFile(userCredentials, FILENAME, flags, 0777); + + // write more than 2kb to the byte to ensure the second stripe is used + byte[] data = new byte[3000]; + for (int i = 0; i < data.length; i++) { + data[i] = 'F'; + } + fileHandle.write(userCredentials, data, data.length, 0); + fileHandle.close(); + + // create replica and add it + List suitableOsds = volume.getSuitableOSDs(userCredentials, FILENAME, 2); + Replica replica = Replica.newBuilder().setReplicationFlags(replicationFlags) + .setStripingPolicy(stripingPolicy).addAllOsdUuids(suitableOsds).build(); + volume.addReplica(userCredentials, FILENAME, replica); + + List stripeLocations = volume.getStripeLocations(userCredentials, FILENAME, 0, 4000); + assertEquals(2, stripeLocations.size()); + assertEquals(3, stripeLocations.get(0).getUuids().length); + assertEquals(3, stripeLocations.get(0).getHostnames().length); + + assertEquals(0, stripeLocations.get(0).getStartSize()); + assertEquals(2048, stripeLocations.get(0).getLength()); + assertEquals(2048, stripeLocations.get(1).getStartSize()); + assertEquals(4000 - 2048, stripeLocations.get(1).getLength()); + + assertEquals(stripeLocations.get(0).getUuids()[0], stripeLocations.get(1).getUuids()[0]); + assertEquals(stripeLocations.get(0).getUuids()[1], stripeLocations.get(1).getUuids()[1]); + assertNotSame(stripeLocations.get(0).getUuids()[2], stripeLocations.get(1).getUuids()[2]); + } + + @Test + public void testVolumeQuota() throws Exception { + final String VOLUME_NAME = "testVolumeQuota"; + + client.createVolume(mrcAddress, auth, userCredentials, VOLUME_NAME, 0, userCredentials.getUsername(), + userCredentials.getGroups(0), AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, + StripingPolicyType.STRIPING_POLICY_RAID0, defaultStripingPolicy.getStripeSize(), + defaultStripingPolicy.getWidth(), new ArrayList()); + + Volume volume = client.openVolume(VOLUME_NAME, null, options); + volume.setXAttr(userCredentials, "/", "xtreemfs.quota", "8", XATTR_FLAGS.XATTR_FLAGS_CREATE); + + assertEquals("8", volume.getXAttr(userCredentials, "/", "xtreemfs.quota")); + + int flags = SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(); + + byte[] content = "foo foo foo".getBytes(); + + FileHandle file = volume.openFile(userCredentials, "/test1.txt", flags, 0777); + file.write(userCredentials, content, content.length, 0); + file.close(); + + try { + file = volume.openFile(userCredentials, "/test2.txt", flags, 0777); + assertTrue(false); + } catch (PosixErrorException exc) { + // check if right exception was thrown + if (!exc.getMessage().contains("POSIX_ERROR_ENOSPC")) { + assertTrue(false); + } + } + } +} diff --git a/java/servers/test/org/xtreemfs/common/statusserver/StatusServerTest.java b/java/servers/test/org/xtreemfs/common/statusserver/StatusServerTest.java new file mode 100644 index 0000000..a8881fd --- /dev/null +++ b/java/servers/test/org/xtreemfs/common/statusserver/StatusServerTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014 by Michael Berlin, Zuse Institute Berlin. + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.common.statusserver; + +import java.io.IOException; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.PORTS; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestHelper; + +public class StatusServerTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + /* + * Start two servers concurrently at the same port. The second server should keep retrying to bind the + * port until the first server has stopped. + */ + @Test + public void testStartRetryLogicIfAddressAlreadyInUse() throws IOException, InterruptedException { + final StatusServer server = new StatusServer(ServiceType.SERVICE_TYPE_OSD, new Object(), + SetupUtils.PORT_RANGE_OFFSET + PORTS.OSD_HTTP_PORT_DEFAULT.getNumber()); + final StatusServer server2 = new StatusServer(ServiceType.SERVICE_TYPE_OSD, new Object(), + SetupUtils.PORT_RANGE_OFFSET + PORTS.OSD_HTTP_PORT_DEFAULT.getNumber()); + + // Start first server and let it block the port for 5 seconds. + server.start(); + Thread shutdownThread = new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(5 * 1000); + } catch (InterruptedException e) { + } + server.shutdown(); + } + }); + shutdownThread.start(); + + // Start second server on the same port. + server2.start(); + server2.shutdown(); + + shutdownThread.join(); + } + +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/integrationtest/ExternalIntegrationTest.java b/java/servers/test/org/xtreemfs/integrationtest/ExternalIntegrationTest.java new file mode 100644 index 0000000..c26d636 --- /dev/null +++ b/java/servers/test/org/xtreemfs/integrationtest/ExternalIntegrationTest.java @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.integrationtest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileWriter; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.test.TestHelper; + +/** + * This test case externally tests the integration of all XtreemFS components at + * the vnode layer. It requires a complete XtreemFS infrastructure consisting of + * a Directory Service, at least one MRC, at least one OSD and the Access Layer + * with a local mountpoint. Moreover, a volume named "Test" has to exist. + *

    + * In order to set up a valid environment, take the following steps: + *

      + *
    • start a Directory Serivce (e.g. on localhost:32638) + *
    • start an OSD (e.g. on localhost:32637) + *
    • start an MRC (e.g. on localhost:32636) + *
    • create a directory for the XtreemFS root (e.g. /tmp/xtreemfs) + *
    • mount the access layer (e.g. + * xtreemfs -d -o volume_url=http://localhost:32636/Test,direct_io /tmp/xtreemfs) + *
    • create a volume "Test" (e.g. mkvol http://localhost:32636/Test) + *
    • change the 'xtreemFSMountPoint' variable to the mount point and compile + * this test case + *
    + * + * @author stender + * + */ +public class ExternalIntegrationTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static File xtreemFSMountPoint = new File("/tmp/xtreemfs"); + + @Before + public void setUp() throws Exception { + FSUtils.delTree(xtreemFSMountPoint); + xtreemFSMountPoint.mkdirs(); + + assertEquals(0, xtreemFSMountPoint.list().length); + } + + @After + public void tearDown() throws Exception { + + } + + /** + * Create and delete some files and directories. + * + * @throws Exception + */ + @Test + public void testCreateDelete() throws Exception { + + assertEquals(0, xtreemFSMountPoint.listFiles().length); + + // create a new directory + File dir1 = createDir(xtreemFSMountPoint, "/testDir"); + + // create a path of depth 3 in the root directory + File dir2 = createDir(xtreemFSMountPoint, "/someOtherDir"); + File dir3 = createDir(dir2, "/nestedDir"); + File dir4 = createDir(dir3, "/leafDir"); + + // delete the leaf directory + delete(dir4); + + // re-create the leaf directory + dir4 = createDir(dir4.getParentFile(), dir4.getName()); + + // create and test a tree of depth 5 with three children per node + createTree(dir1, 5, 3); + testTree(dir1, 5, 3); + + // create and delete a file in the root directory + File file1 = createFile(xtreemFSMountPoint, "testfile.tmp"); + + assertFalse(file1.createNewFile()); + delete(file1); + createFile(file1.getParentFile(), file1.getName()); + delete(file1); + + // create and delete a file in a sub directory + File file2 = createFile(new File(xtreemFSMountPoint + "/someOtherDir"), "testfile.tmp"); + + assertFalse(file2.createNewFile()); + delete(file2); + createFile(file2.getParentFile(), file2.getName()); + delete(file2); + } + + @Test + public void testRename() throws Exception { + + // create a file and a directory + File sourceFile = createFile(xtreemFSMountPoint, "sourceFile.txt"); + File targetDir = createDir(xtreemFSMountPoint, "targetDir"); + + // move the file to the directory + File targetFile = new File(targetDir.getAbsolutePath() + "/sourceFile.txt"); + assertTrue(sourceFile.renameTo(targetFile)); + + // afterwards, the target file should exist + assertTrue(targetFile.exists()); + + // ... and the source file should not exist anymore + assertFalse(sourceFile.exists()); + + // rename the target directory + File newTargetDir = new File(xtreemFSMountPoint, "newTargetDir"); + assertTrue(targetDir.renameTo(newTargetDir)); + + // afterwards, the former target directory should not exist anymore + assertFalse(targetDir.exists()); + + // ... and the new one should exist instead + assertTrue(newTargetDir.exists()); + + // ... and the nested file should have a new path + File newTargetFile = new File(newTargetDir, targetFile.getName()); + assertTrue(newTargetFile.exists()); + + // create a new directory and move the entire path to it while renaming + // the moved path + File topLevelTargetDir = createDir(xtreemFSMountPoint, "topLevelDir"); + File nestedDir = new File(topLevelTargetDir, "nestedDir"); + assertTrue(newTargetDir.renameTo(nestedDir)); + + // ... afterwards, the file should still exist in the nested directory + File nestedFile = new File(nestedDir, newTargetFile.getName()); + assertTrue(nestedFile.exists()); + + } + + @Test + public void testBatchCreateDeleteRename() throws Exception { + + final int numFiles = 100; + + // touch a bunch of files and check whether they are there + for (int i = 0; i < numFiles; i++) + new File(xtreemFSMountPoint.getAbsolutePath() + "/" + i).createNewFile(); + + assertEquals(numFiles, new File(xtreemFSMountPoint.getAbsolutePath()).list().length); + + // delete the files and check whether the directory is empty + for (int i = 0; i < numFiles; i++) + new File(xtreemFSMountPoint.getAbsolutePath() + "/" + i).delete(); + + assertEquals(0, new File(xtreemFSMountPoint.getAbsolutePath()).list().length); + + // write data to a bunch of files and check whether the files are there + for (int i = 0; i < numFiles; i++) { + FileWriter fw = new FileWriter(xtreemFSMountPoint.getAbsolutePath() + "/" + i); + fw.write("test"); + fw.close(); + } + + assertEquals(numFiles, new File(xtreemFSMountPoint.getAbsolutePath()).list().length); + + // create a new directory and move all files to it + new File(xtreemFSMountPoint.getAbsolutePath() + "/dir").mkdir(); + for (int i = 0; i < numFiles; i++) + new File(xtreemFSMountPoint.getAbsolutePath() + "/" + i).renameTo(new File( + xtreemFSMountPoint.getAbsolutePath() + "/dir/" + i)); + + assertEquals(1, new File(xtreemFSMountPoint.getAbsolutePath()).list().length); + assertEquals(numFiles, + new File(xtreemFSMountPoint.getAbsolutePath() + "/dir").list().length); + + // delete the files and check whether the directory is empty + for (int i = 0; i < numFiles; i++) + new File(xtreemFSMountPoint.getAbsolutePath() + "/dir/" + i).delete(); + + assertEquals(1, new File(xtreemFSMountPoint.getAbsolutePath()).list().length); + assertEquals(0, new File(xtreemFSMountPoint.getAbsolutePath() + "/dir").list().length); + } + + // /** + // * Perform some sequential read/write operations on a file. + // * + // * @throws Exception + // */ + // public void testSeqReadWrite() throws Exception { + // + // // create a new file for sequential r/w access + // File f = createFile(xtreemFSMountPoint, "/testfile.tmp"); + // + // FileOutputStream fout = new FileOutputStream(f); + // fout.write(65); + // fout.write(66); + // fout.close(); + // assertEquals(2, f.length()); + // + // FileInputStream fin = new FileInputStream(f); + // assertEquals(65, fin.read()); + // assertEquals(66, fin.read()); + // assertEquals(-1, fin.read()); + // fin.close(); + // } + // + // /** + // * Perform some random read/write operations on a file. + // * + // * @throws Exception + // */ + // public void testRndReadWrite() throws Exception { + // + // File file = createFile(xtreemFSMountPoint, "/testfile2.tmp"); + // + // // create a new file for random r/w access + // RandomAccessFile f2 = new RandomAccessFile(file, "rw"); + // f2.writeBytes("Hello World!"); + // assertEquals(12, f2.length()); + // + // f2.seek(4); + // assertEquals('o', f2.read()); + // f2.seek(6); + // f2.write('w'); + // f2.seek(6); + // assertEquals('w', f2.read()); + // f2.seek(6); + // f2.writeBytes("XtreemFS!"); + // f2.seek(0); + // + // byte[] chars = new byte[(int) f2.length()]; + // f2.readFully(chars); + // + // assertEquals("Hello XtreemFS!", new String(chars)); + // + // f2.seek(16384); + // f2.writeBytes("This is a string at offset 16384"); + // + // byte[] buf = new byte[2048]; + // f2.seek(8192); + // f2.read(buf); + // for (int i = 0; i < buf.length; i++) + // assertEquals(0, buf[i]); + // + // f2.seek(16384); + // f2.read(buf); + // assertEquals("This is a string at offset 16384", new String(buf, 0, 32)); + // + // f2.close(); + // assertEquals(16416, file.length()); + // } + // + // /** + // * Read and write random strides. + // * + // * @throws Exception + // */ + // public void testRndReadWrite2() throws Exception { + // + // final File file = createFile(xtreemFSMountPoint, "/testfile3.tmp"); + // final RandomAccessFile raf = new RandomAccessFile(file, "rw"); + // final int maxAccesses = 1000; + // final int maxFileSize = 1024 * 1024; + // final int maxNumberOfBytes = 1024 * 128; + // final double readWriteRatio = .15; + // + // // allocate 10M + // byte[] buf = new byte[maxFileSize]; + // + // for (int i = 0; i < maxAccesses; i++) { + // + // boolean write = Math.random() > readWriteRatio; + // + // int numberOfBytes = (int) (Math.random() * maxNumberOfBytes); + // int offset = (int) (Math.random() * buf.length); + // offset = Math.min(offset, buf.length - numberOfBytes); + // byte[] stride = new byte[numberOfBytes]; + // + // if (write) { + // // write a stride + // + // for (int j = 0; j < stride.length; j++) + // stride[j] = (byte) (Math.random() * 256 - 128); + // + // raf.seek(offset); + // raf.write(stride); + // + // System.arraycopy(stride, 0, buf, offset, stride.length); + // + // } else { + // // read a stride + // + // raf.seek(offset); + // raf.read(stride); + // + // for (int j = 0; j < stride.length; j++) + // assertEquals(stride[j], buf[offset + j]); + // } + // } + // + // // finally, read and compare the complete file + // byte[] readBuf = new byte[maxFileSize]; + // raf.seek(0); + // raf.read(readBuf); + // + // for (int j = 0; j < maxFileSize; j++) + // assertEquals(buf[j], readBuf[j]); + // + // raf.close(); + // } + + + private File createDir(File parentDir, String name) { + + final long numberOfChildren = parentDir.list().length; + + // a new directory ... + File dir = new File(parentDir, name); + + // ... must not exist before + assertTrue(!dir.exists()); + + dir.mkdir(); + + // ... must exist afterwards + assertTrue(dir.exists()); + + // ... must be a directory + assertTrue(dir.isDirectory()); + + // ... must be an additional element in its parent directory + assertEquals(numberOfChildren + 1, parentDir.list().length); + + // ... must be an empty directory + assertEquals(0, dir.list().length); + + return dir; + } + + private File createFile(File parentDir, String name) throws Exception { + + final long numberOfChildren = parentDir.list().length; + + // a new file ... + File file = new File(parentDir, name); + + // ... must not exist before + assertTrue(!file.exists()); + + assertTrue(file.createNewFile()); + + // ... must exist afterwards + assertTrue(file.exists()); + + // ... must be a file + assertTrue(file.isFile()); + + // ... must be an additional element in its parent directory + assertEquals(numberOfChildren + 1, parentDir.list().length); + + // ... must not have any content + assertEquals(0, file.length()); + + return file; + } + + private void delete(File fileOrDir) { + + final long numberOfChildren = fileOrDir.getParentFile().list().length; + + // a file or directory that is deleted ... + + // ... must exist before + assertTrue(fileOrDir.exists()); + + assertTrue(fileOrDir.delete()); + + // ... must not exist afterwards + assertTrue(!fileOrDir.exists()); + + // ... must not exist in its parent directory anymore + assertEquals(numberOfChildren - 1, fileOrDir.getParentFile().list().length); + } + + private void createTree(File root, int depth, int breadth) throws Exception { + + if (depth == -1) + return; + + for (int j = 0; j < breadth; j++) { + File f = new File(root, j + ""); + f.mkdir(); + createTree(f, depth - 1, breadth); + } + } + + private void testTree(File root, int depth, int breadth) throws Exception { + + if (depth == -1) + return; + + assertEquals(breadth, root.list().length); + + for (int j = 0; j < breadth; j++) { + File f = new File(root, j + ""); + assertTrue(f.exists()); + testTree(f, depth - 1, breadth); + } + + } +} diff --git a/java/servers/test/org/xtreemfs/test/SetupUtils.java b/java/servers/test/org/xtreemfs/test/SetupUtils.java new file mode 100644 index 0000000..2dcb4e5 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/SetupUtils.java @@ -0,0 +1,458 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, Jan Stender, + * Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.Arrays; +import java.util.Properties; +import java.util.Random; + +import org.xtreemfs.babudb.config.BabuDBConfig; +import org.xtreemfs.babudb.log.DiskLogger.SyncMode; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.foundation.SSLOptions; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.logging.Logging.Category; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.mrc.MRCConfig; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; + +/** + * + * @author bjko + */ +public class SetupUtils { + + public static final String TEST_DIR = "/tmp/xtreemfs-test2"; + + public static final String CERT_DIR = "tests/certs/"; + + public static boolean SSL_ON = false; + + public static boolean CHECKSUMS_ON = false; + + public static final int DEBUG_LEVEL = Logging.LEVEL_WARN; + + public static final Category[] DEBUG_CATEGORIES = new Category[] { Category.all }; + + public static final int PORT_RANGE_OFFSET = 10000; + + /** + * Analog to nextOsdNo. + */ + private static final int offsetFirstOsdPort = 32640 + PORT_RANGE_OFFSET; + + private static Properties createOSDProperties(int port, String dir) { + Properties props = new Properties(); + props.setProperty("dir_service.host", "localhost"); + props.setProperty("dir_service.port", new Integer(32638 + PORT_RANGE_OFFSET).toString()); + props.setProperty("object_dir", dir); + props.setProperty("debug.level", "" + DEBUG_LEVEL); + props.setProperty("debug.categories", + "" + Arrays.toString(DEBUG_CATEGORIES).substring(1, Arrays.toString(DEBUG_CATEGORIES).length() - 1)); + props.setProperty("listen.port", "" + port); + props.setProperty("http_port", "" + (port - 3000)); + props.setProperty("listen.address", "localhost"); + props.setProperty("local_clock_renewal", "0"); + props.setProperty("remote_time_sync", "60000"); + props.setProperty("ssl.enabled", "" + SSL_ON); + props.setProperty("ssl.service_creds", CERT_DIR + "OSD.p12"); + props.setProperty("ssl.service_creds.pw", "passphrase"); + props.setProperty("ssl.service_creds.container", "pkcs12"); + props.setProperty("ssl.trusted_certs", CERT_DIR + "trusted.jks"); + props.setProperty("ssl.trusted_certs.pw", "passphrase"); + props.setProperty("ssl.trusted_certs.container", "jks"); + props.setProperty("report_free_space", "true"); + props.setProperty("checksums.enabled", Boolean.toString(CHECKSUMS_ON)); + props.setProperty("checksums.algorithm", "Adler32"); + props.setProperty("capability_secret", "secretPassphrase"); + props.setProperty("uuid", getUUID("localhost", port).toString()); + props.setProperty("snmp.enabled", "true"); + props.setProperty("snmp.port", "" + (port + 1000)); + props.setProperty("snmp.address", "localhost"); + props.setProperty("measure_requests", "false"); + return props; + } + + public static OSDConfig createOSD1Config() throws IOException { + Properties props = createOSDProperties(32637 + PORT_RANGE_OFFSET, TEST_DIR + "/osd0"); + OSDConfig config = new OSDConfig(props); + config.setDefaults(); + return config; + } + + public static OSDConfig createOSD2Config() throws IOException { + Properties props = createOSDProperties(32640 + PORT_RANGE_OFFSET, TEST_DIR + "/osd1"); + OSDConfig config = new OSDConfig(props); + config.setDefaults(); + return config; + } + + public static OSDConfig createOSD3Config() throws IOException { + Properties props = createOSDProperties(32641 + PORT_RANGE_OFFSET, TEST_DIR + "/osd2"); + OSDConfig config = new OSDConfig(props); + config.setDefaults(); + return config; + } + + public static OSDConfig createOSD4Config() throws IOException { + Properties props = createOSDProperties(32642 + PORT_RANGE_OFFSET, TEST_DIR + "/osd3"); + OSDConfig config = new OSDConfig(props); + config.setDefaults(); + return config; + } + /** + * + * Creates multiple OSD configs starting at offset 0. + * + */ + public static OSDConfig[] createMultipleOSDConfigs(int number) throws IOException { + return createMultipleOSDConfigs(number, 0); + } + + /** + * + * Creates multiple OSD configs starting at offset "offsetNextOsd". + * + */ + public static OSDConfig[] createMultipleOSDConfigs(int number, int offsetNextOsd) throws IOException { + OSDConfig[] configs = new OSDConfig[number]; + int offsetNextOsdPort = offsetFirstOsdPort + offsetNextOsd; + for (int i = 0; i < configs.length; i++) { + Properties props = createOSDProperties(offsetNextOsdPort, TEST_DIR + "/osd" + offsetNextOsd); + configs[i] = new OSDConfig(props); + configs[i].setDefaults(); + offsetNextOsdPort++; + offsetNextOsd++; + } + return configs; + } + + public static org.xtreemfs.dir.DIRConfig createDIRConfig() throws IOException { + Properties props = new Properties(); + props.setProperty("debug.level", "" + DEBUG_LEVEL); + props.setProperty("debug.categories", + "" + Arrays.toString(DEBUG_CATEGORIES).substring(1, Arrays.toString(DEBUG_CATEGORIES).length() - 1)); + props.setProperty("listen.port", new Integer(32638 + PORT_RANGE_OFFSET).toString()); + props.setProperty("http_port", new Integer(30638 + PORT_RANGE_OFFSET).toString()); + props.setProperty("uuid", "UUID:localhost:" + new Integer(32638 + PORT_RANGE_OFFSET).toString()); + props.setProperty("ssl.enabled", "" + SSL_ON); + props.setProperty("ssl.service_creds", CERT_DIR + "DIR.p12"); + props.setProperty("ssl.service_creds.pw", "passphrase"); + props.setProperty("ssl.service_creds.container", "pkcs12"); + props.setProperty("ssl.trusted_certs", CERT_DIR + "trusted.jks"); + props.setProperty("ssl.trusted_certs.pw", "passphrase"); + props.setProperty("ssl.trusted_certs.container", "jks"); + props.setProperty("authentication_provider", "org.xtreemfs.common.auth.NullAuthProvider"); + props.setProperty("snmp.enabled", "true"); + props.setProperty("snmp.port", new Integer(34638 + PORT_RANGE_OFFSET).toString()); + props.setProperty("snmp.address", "localhost"); + props.setProperty("measure_requests", "false"); + + DIRConfig config = new DIRConfig(props); + config.setDefaults(); + + return config; + } + + public static BabuDBConfig createDIRdbsConfig() throws IOException { + Properties props = new Properties(); + props.setProperty("babudb.debug.level", "" + DEBUG_LEVEL); + props.setProperty("babudb.debug.categories", + "" + Arrays.toString(DEBUG_CATEGORIES).substring(1, Arrays.toString(DEBUG_CATEGORIES).length() - 1)); + props.setProperty("babudb.cfgFile", "config.db"); + props.setProperty("babudb.baseDir", TEST_DIR); + props.setProperty("babudb.logDir", TEST_DIR); + props.setProperty("babudb.sync", "" + SyncMode.FSYNC); + props.setProperty("babudb.worker.maxQueueLength", "250"); + props.setProperty("babudb.worker.numThreads", "0"); + props.setProperty("babudb.maxLogfileSize", "16777216"); + props.setProperty("babudb.checkInterval", "300"); + props.setProperty("babudb.pseudoSyncWait", "200"); + + return new BabuDBConfig(props); + } + + public static MRCConfig createMRC1Config() throws IOException { + Properties props = new Properties(); + props.setProperty("dir_service.host", "localhost"); + props.setProperty("dir_service.port", new Integer(32638 + PORT_RANGE_OFFSET).toString()); + props.setProperty("osd_check_interval", "10"); + props.setProperty("debug.level", "" + DEBUG_LEVEL); + props.setProperty("debug.categories", + "" + Arrays.toString(DEBUG_CATEGORIES).substring(1, Arrays.toString(DEBUG_CATEGORIES).length() - 1)); + props.setProperty("listen.port", new Integer(32636 + PORT_RANGE_OFFSET).toString()); + props.setProperty("http_port", new Integer(30636 + PORT_RANGE_OFFSET).toString()); + props.setProperty("listen.address", "localhost"); + props.setProperty("no_atime", "true"); + props.setProperty("local_clock_renewal", "0"); + props.setProperty("remote_time_sync", "60000"); + props.setProperty("ssl.enabled", "" + SSL_ON); + props.setProperty("ssl.service_creds", CERT_DIR + "MRC.p12"); + props.setProperty("ssl.service_creds.pw", "passphrase"); + props.setProperty("ssl.service_creds.container", "pkcs12"); + props.setProperty("ssl.trusted_certs", CERT_DIR + "trusted.jks"); + props.setProperty("ssl.trusted_certs.pw", "passphrase"); + props.setProperty("ssl.trusted_certs.container", "jks"); + props.setProperty("authentication_provider", "org.xtreemfs.common.auth.NullAuthProvider"); + props.setProperty("capability_secret", "secretPassphrase"); + props.setProperty("uuid", getMRC1UUID().toString()); + props.setProperty("snmp.enabled", "true"); + props.setProperty("snmp.port", new Integer(34636 + PORT_RANGE_OFFSET).toString()); + props.setProperty("snmp.address", "localhost"); + props.setProperty("measure_requests", "false"); + + MRCConfig config = new MRCConfig(props); + config.setDefaults(); + return config; + } + + public static BabuDBConfig createMRC1dbsConfig() throws IOException { + Properties props = new Properties(); + props.setProperty("babudb.debug.level", "" + DEBUG_LEVEL); + props.setProperty("debug.categories", + "" + Arrays.toString(DEBUG_CATEGORIES).substring(1, Arrays.toString(DEBUG_CATEGORIES).length() - 1)); + props.setProperty("babudb.cfgFile", "config.db"); + props.setProperty("babudb.baseDir", TEST_DIR + "/mrc0"); + props.setProperty("babudb.logDir", TEST_DIR + "/test-brain0.log"); + props.setProperty("babudb.sync", "" + SyncMode.ASYNC); + props.setProperty("babudb.worker.maxQueueLength", "500"); + props.setProperty("babudb.worker.numThreads", "2"); + props.setProperty("babudb.maxLogfileSize", "16777216"); + props.setProperty("babudb.checkInterval", "300"); + props.setProperty("babudb.pseudoSyncWait", "0"); + + return new BabuDBConfig(props); + } + + public static MRCConfig createMRC2Config() throws IOException { + Properties props = new Properties(); + props.setProperty("dir_service.host", "localhost"); + props.setProperty("dir_service.port", new Integer(32638 + PORT_RANGE_OFFSET).toString()); + props.setProperty("osd_check_interval", "10"); + props.setProperty("debug.level", "" + DEBUG_LEVEL); + props.setProperty("debug.categories", + "" + Arrays.toString(DEBUG_CATEGORIES).substring(1, Arrays.toString(DEBUG_CATEGORIES).length() - 1)); + props.setProperty("listen.port", new Integer(32639 + PORT_RANGE_OFFSET).toString()); + props.setProperty("http_port", new Integer(30639 + PORT_RANGE_OFFSET).toString()); + props.setProperty("listen.address", "localhost"); + props.setProperty("no_atime", "true"); + props.setProperty("local_clock_renewal", "0"); + props.setProperty("remote_time_sync", "60000"); + props.setProperty("ssl.enabled", "" + SSL_ON); + props.setProperty("ssl.service_creds", CERT_DIR + "MRC.p12"); + props.setProperty("ssl.service_creds.pw", "passphrase"); + props.setProperty("ssl.service_creds.container", "pkcs12"); + props.setProperty("ssl.trusted_certs", CERT_DIR + "trusted.jks"); + props.setProperty("ssl.trusted_certs.pw", "passphrase"); + props.setProperty("ssl.trusted_certs.container", "jks"); + props.setProperty("authentication_provider", "org.xtreemfs.common.auth.NullAuthProvider"); + props.setProperty("capability_secret", "secretPassphrase"); + props.setProperty("uuid", getMRC2UUID().toString()); + props.setProperty("snmp.enabled", "true"); + props.setProperty("snmp.port", new Integer(34639 + PORT_RANGE_OFFSET).toString()); + props.setProperty("snmp.address", "localhost"); + + MRCConfig config = new MRCConfig(props); + config.setDefaults(); + return config; + } + + public static BabuDBConfig createMRC2dbsConfig() throws IOException { + Properties props = new Properties(); + props.setProperty("babudb.debug.level", "" + DEBUG_LEVEL); + props.setProperty("babudb.debug.categories", + "" + Arrays.toString(DEBUG_CATEGORIES).substring(1, Arrays.toString(DEBUG_CATEGORIES).length() - 1)); + props.setProperty("babudb.cfgFile", "config.db"); + props.setProperty("babudb.baseDir", TEST_DIR + "/mrc1"); + props.setProperty("babudb.logDir", TEST_DIR + "/test-brain1.log"); + props.setProperty("babudb.sync", "" + SyncMode.ASYNC); + props.setProperty("babudb.worker.maxQueueLength", "500"); + props.setProperty("babudb.worker.numThreads", "2"); + props.setProperty("babudb.maxLogfileSize", "16777216"); + props.setProperty("babudb.checkInterval", "300"); + props.setProperty("babudb.pseudoSyncWait", "0"); + + return new BabuDBConfig(props); + } + + public static InetSocketAddress getMRC1Addr() { + return new InetSocketAddress("localhost", 32636 + PORT_RANGE_OFFSET); + } + + public static InetSocketAddress getMRC2Addr() { + return new InetSocketAddress("localhost", 32639 + PORT_RANGE_OFFSET); + } + + public static InetSocketAddress getOSD1Addr() { + return new InetSocketAddress("localhost", 32637 + PORT_RANGE_OFFSET); + } + + public static InetSocketAddress getOSD2Addr() { + return new InetSocketAddress("localhost", 32640 + PORT_RANGE_OFFSET); + } + + public static InetSocketAddress getOSD3Addr() { + return new InetSocketAddress("localhost", 32641 + PORT_RANGE_OFFSET); + } + + public static InetSocketAddress getOSD4Addr() { + return new InetSocketAddress("localhost", 32642 + PORT_RANGE_OFFSET); + } + + public static InetSocketAddress getDIRAddr() { + return new InetSocketAddress("localhost", 32638 + PORT_RANGE_OFFSET); + } + + public static ServiceUUID getMRC1UUID() { + return new ServiceUUID("UUID:localhost:" + new Integer(32636 + PORT_RANGE_OFFSET).toString()); + } + + public static ServiceUUID getMRC2UUID() { + return new ServiceUUID("UUID:localhost:" + new Integer(32639 + PORT_RANGE_OFFSET).toString()); + } + + public static ServiceUUID getOSD1UUID() { + return new ServiceUUID("UUID:localhost:" + new Integer(32637 + PORT_RANGE_OFFSET).toString()); + } + + public static ServiceUUID getOSD2UUID() { + return new ServiceUUID("UUID:localhost:" + new Integer(32640 + PORT_RANGE_OFFSET).toString()); + } + + public static ServiceUUID getOSD3UUID() { + return new ServiceUUID("UUID:localhost:" + new Integer(32641 + PORT_RANGE_OFFSET).toString()); + } + + public static ServiceUUID getOSD4UUID() { + return new ServiceUUID("UUID:localhost:" + new Integer(32642 + PORT_RANGE_OFFSET).toString()); + } + + static void localResolver() { + UUIDResolver.addLocalMapping(getMRC1UUID(), 32636 + PORT_RANGE_OFFSET, SSL_ON ? Schemes.SCHEME_PBRPCS : Schemes.SCHEME_PBRPC); + UUIDResolver.addLocalMapping(getMRC2UUID(), 32639 + PORT_RANGE_OFFSET, SSL_ON ? Schemes.SCHEME_PBRPCS : Schemes.SCHEME_PBRPC); + UUIDResolver.addLocalMapping(getOSD1UUID(), 32637 + PORT_RANGE_OFFSET, SSL_ON ? Schemes.SCHEME_PBRPCS : Schemes.SCHEME_PBRPC); + UUIDResolver.addLocalMapping(getOSD2UUID(), 32640 + PORT_RANGE_OFFSET, SSL_ON ? Schemes.SCHEME_PBRPCS : Schemes.SCHEME_PBRPC); + UUIDResolver.addLocalMapping(getOSD3UUID(), 32641 + PORT_RANGE_OFFSET, SSL_ON ? Schemes.SCHEME_PBRPCS : Schemes.SCHEME_PBRPC); + UUIDResolver.addLocalMapping(getOSD4UUID(), 32642 + PORT_RANGE_OFFSET, SSL_ON ? Schemes.SCHEME_PBRPCS : Schemes.SCHEME_PBRPC); + } + + private static ServiceUUID getUUID(String listenAddress, int port) { + return new ServiceUUID("UUID:" + listenAddress + ":" + port); + } + + public static void setupLocalResolver() throws Exception { + TimeSync.initialize(null, 100000, 50); + + UUIDResolver.start(null, 1000, 1000); + localResolver(); + } + + static RPCNIOSocketClient createRPCClient(int timeout) throws IOException { + final SSLOptions sslOptions = SSL_ON ? createClientSSLOptions() : null; + return new RPCNIOSocketClient(sslOptions, timeout, 5 * 60 * 1000, "SetupUtils"); + } + + public static SSLOptions createClientSSLOptions() throws IOException, FileNotFoundException { + return new SSLOptions(new FileInputStream(CERT_DIR + "Client.p12"), "passphrase", SSLOptions.PKCS12_CONTAINER, + new FileInputStream(CERT_DIR + "trusted.jks"), "passphrase", SSLOptions.JKS_CONTAINER, false, false, + null, null); + } + + static DIRServiceClient createDIRClient(RPCNIOSocketClient client) throws IOException { + return new DIRServiceClient(client, new InetSocketAddress("localhost", 32638 + PORT_RANGE_OFFSET)); + } + + public static OSDConfig createOSD1ConfigForceWithoutSSL() throws IOException { + boolean tmp = SSL_ON; + SSL_ON = false; + OSDConfig config = createOSD1Config(); + SSL_ON = tmp; + return config; + } + + public static OSDConfig createOSD2ConfigForceWithoutSSL() throws IOException { + boolean tmp = SSL_ON; + SSL_ON = false; + OSDConfig config = createOSD2Config(); + SSL_ON = tmp; + return config; + } + + public static OSDConfig createOSD3ConfigForceWithoutSSL() throws IOException { + boolean tmp = SSL_ON; + SSL_ON = false; + OSDConfig config = createOSD3Config(); + SSL_ON = tmp; + return config; + } + + public static MRCConfig createMRC1ConfigForceWithoutSSL() throws IOException { + boolean tmp = SSL_ON; + SSL_ON = false; + MRCConfig config = createMRC1Config(); + SSL_ON = tmp; + return config; + } + + public static MRCConfig createMRC2ConfigForceWithoutSSL() throws IOException { + boolean tmp = SSL_ON; + SSL_ON = false; + MRCConfig config = createMRC2Config(); + SSL_ON = tmp; + return config; + } + + public static DIRConfig createDIRConfigForceWithoutSSL() throws IOException { + boolean tmp = SSL_ON; + SSL_ON = false; + DIRConfig config = createDIRConfig(); + SSL_ON = tmp; + return config; + } + + /** + * @param size + * in byte + */ + public static ReusableBuffer generateData(int size) { + Random random = new Random(); + byte[] data = new byte[size]; + random.nextBytes(data); + return ReusableBuffer.wrap(data); + } + + /** + * @param size + * in byte + */ + public static ReusableBuffer generateData(int size, byte ch) { + byte[] data = new byte[size]; + for (int i = 0; i < data.length; i++) + data[i] = ch; + return ReusableBuffer.wrap(data); + } + + public static StripingPolicy getStripingPolicy(int width, int stripeSize) { + return StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0).setStripeSize(stripeSize) + .setWidth(width).build(); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/TestEnvironment.java b/java/servers/test/org/xtreemfs/test/TestEnvironment.java new file mode 100644 index 0000000..90036c9 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/TestEnvironment.java @@ -0,0 +1,466 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test; + +import java.io.File; +import java.io.IOException; +import java.net.BindException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.foundation.CrashReporter; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; + +/** + * + * @author bjko + */ +public class TestEnvironment { + + /** + * Wrapper for OSDRequestDispatcher which stores if an OSD is started. + * + * @author lkairies + * + */ + private class TestOSD { + private OSDRequestDispatcher osd; + private boolean started; + + public TestOSD(OSDRequestDispatcher osd) { + this.osd = osd; + this.started = false; + } + + public void start() { + osd.start(); + started = true; + } + + public void shutdown() { + osd.shutdown(); + started = false; + } + + public String getPrimary(String fileId) { + return osd.getPrimary(fileId); + } + + public OSDConfig getConfig() { + return osd.getConfig(); + } + } + + public InetSocketAddress getMRCAddress() throws UnknownUUIDException { + return mrc.getConfig().getUUID().getAddress(); + } + + public InetSocketAddress getDIRAddress() throws IOException { + return new InetSocketAddress("localhost", SetupUtils.createDIRConfig().getPort()); + } + + /** + * @return the rpcClient + */ + public RPCNIOSocketClient getRpcClient() { + return rpcClient; + } + + /** + * @return the dirClient + */ + public DIRServiceClient getDirClient() { + return dirClient; + } + + /** + * @return the mrcClient + */ + public MRCServiceClient getMrcClient() { + return mrcClient; + } + + public OSDServiceClient getOSDClient() { + return osdClient; + } + + /** + * returns always the address of the first OSD + */ + public InetSocketAddress getOSDAddress() throws UnknownUUIDException { + return firstOSDAddress; + } + + /** + * Returns the OSD config of the OSD with the UUID "osdUuid" or null if no OSD with the UUID "osdUuid" + * exists. + * + * @param osdUuid + */ + public OSDConfig getOSDConfig(String osdUuid) { + return osds.get(osdUuid).getConfig(); + } + + /** + * Returns the OSD config of the first OSD. + */ + public OSDConfig getOSDConfig() { + return osdConfigs[0]; + } + + /** + * Stops the OSD with the UUID "osdUuid". + * + * @param osdUuid + */ + public void stopOSD(String osdUuid) throws Exception{ + TestOSD osd = osds.get(osdUuid); + + if (osd == null) { + throw new Exception("No OSD with UUID " + osdUuid + " available."); + } + + if (osd.started) { + osd.shutdown(); + } else { + throw new Exception("OSD " + osdUuid + " was already stoped!"); + } + } + + /** + * Starts a previously shut downed OSD with the UUID "osdUuid". + * + * @param osdUuid + * @throws Exception + */ + public void startOSD(String osdUuid) throws Exception { + TestOSD osd = osds.get(osdUuid); + + if (osd == null) { + throw new Exception("No OSD with UUID " + osdUuid + " available."); + } + + if (!osd.started) { + OSDConfig config = getOSDConfig(osdUuid); + + //Create new OSDRequestDispatcher with same config. + osd = new TestOSD (new OSDRequestDispatcher(config)); + osd.start(); + + // Replace old OSDRequestDispatcher. + osds.put(osdUuid, osd); + } else { + throw new Exception("OSD " + osdUuid + " is already running!"); + } + } + + /** + * starts "number" additional OSDs. + * + * @param number + * @throws Exception + */ + public void startAdditionalOSDs(int number) throws Exception { + OSDConfig[] osdConfigs = SetupUtils.createMultipleOSDConfigs(number, osds.size()); + for (OSDConfig config : osdConfigs) { + TestOSD osd = new TestOSD (new OSDRequestDispatcher(config)); + osd.start(); + osds.put(config.getUUID().toString(), osd); + } + } + + /** + * Returns the primary OSD UUID for the file with ID "fileId" or null if the file does not exists. + * + * @param fileId + * @return + */ + public String getPrimary(String fileId) { + String primary = null; + for (TestOSD osd : osds.values()) { + primary = osd.getPrimary(fileId); + if (primary != null) { + break; + } + } + return primary; + } + + public enum Services { + TIME_SYNC, // time sync facility + UUID_RESOLVER, // UUID resolver + RPC_CLIENT, // RPC client + DIR_CLIENT, // Directory Service client + MRC_CLIENT, // MRC client + OSD_CLIENT, // OSD client + DIR_SERVICE, // Directory Service + MRC, // MRC + MOCKUP_OSD, // mock-up OSD: registers a non-existing OSD at the DIR + MOCKUP_OSD2, // mock-up OSD: registers a non-existing OSD at the DIR + MOCKUP_OSD3, // mock-up OSD: registers a non-existing OSD at the DIR + OSD + // an OSD + }; + + private RPCNIOSocketClient rpcClient; + + private org.xtreemfs.foundation.pbrpc.client.RPCNIOSocketClient pbrpcClient; + + private DIRServiceClient dirClient; + + private MRCServiceClient mrcClient; + + private OSDServiceClient osdClient; + + private DIRRequestDispatcher dirService; + + private MRCRequestDispatcher mrc; + + private HashMap osds; + + private final List enabledServs; + + private TimeSync tsInstance; + + private OSDConfig[] osdConfigs; + + private InetSocketAddress firstOSDAddress; + + public TestEnvironment(Services... servs) { + enabledServs = new ArrayList(servs.length); + for (Services serv : servs) + enabledServs.add(serv); + } + + public void start() throws Exception { + try { + // ensure that TEST_DIR is empty + File testDir = new File(SetupUtils.TEST_DIR); + FSUtils.delTree(testDir); + testDir.mkdirs(); + + rpcClient = SetupUtils.createRPCClient(10000); + getRpcClient().start(); + getRpcClient().waitForStartup(); + + dirClient = SetupUtils.createDIRClient(getRpcClient()); + + if (enabledServs.contains(Services.DIR_SERVICE)) { + dirService = new DIRRequestDispatcher(SetupUtils.createDIRConfig(), SetupUtils.createDIRdbsConfig()); + dirService.startup(); + dirService.waitForStartup(); + Logging.logMessage(Logging.LEVEL_DEBUG, this, "DIR running"); + } + + if (enabledServs.contains(Services.TIME_SYNC) || enabledServs.contains(Services.MOCKUP_OSD)) { + tsInstance = TimeSync.initializeLocal(50); + tsInstance.waitForStartup(); + } + + if (enabledServs.contains(Services.UUID_RESOLVER)) { + DIRClient dc = new DIRClient(dirClient, new InetSocketAddress[] { getDIRAddress() }, 10, 1000 * 5); + UUIDResolver.start(dc, 1000, 10 * 10 * 1000); + SetupUtils.localResolver(); + } + + if (enabledServs.contains(Services.MOCKUP_OSD)) { + Map dmap = new HashMap(); + dmap.put("free", "1000000000"); + dmap.put("total", "1000000000"); + dmap.put("load", "0"); + dmap.put("totalRAM", "1000000000"); + dmap.put("usedRAM", "0"); + dmap.put("proto_version", "" + OSDServiceConstants.INTERFACE_ID); + Service reg = Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setName("mockUpOSD") + .setUuid("mockUpOSD").setVersion(0).setLastUpdatedS(0) + .setData(ServiceDataMap.newBuilder().addAllData(KeyValuePairs.fromMap(dmap))).build(); + RPCResponse response = dirClient.xtreemfs_service_register(null, + RPCAuthentication.authNone, RPCAuthentication.userService, reg); + response.get(); + response.freeBuffers(); + + UUIDResolver.addLocalMapping("mockUpOSD", 11111, Schemes.SCHEME_PBRPC); + } + + if (enabledServs.contains(Services.MOCKUP_OSD2)) { + Map dmap = new HashMap(); + dmap.put("free", "1000000000"); + dmap.put("total", "1000000000"); + dmap.put("load", "0"); + dmap.put("totalRAM", "1000000000"); + dmap.put("usedRAM", "0"); + dmap.put("proto_version", "" + OSDServiceConstants.INTERFACE_ID); + Service reg = Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setName("mockUpOSD2") + .setUuid("mockUpOSD2").setVersion(0).setLastUpdatedS(0) + .setData(ServiceDataMap.newBuilder().addAllData(KeyValuePairs.fromMap(dmap))).build(); + RPCResponse response = dirClient.xtreemfs_service_register(null, + RPCAuthentication.authNone, RPCAuthentication.userService, reg); + response.get(); + response.freeBuffers(); + + UUIDResolver.addLocalMapping("mockUpOSD2", 11111, Schemes.SCHEME_PBRPC); + } + + if (enabledServs.contains(Services.MOCKUP_OSD3)) { + Map dmap = new HashMap(); + dmap.put("free", "1000000000"); + dmap.put("total", "1000000000"); + dmap.put("load", "0"); + dmap.put("totalRAM", "1000000000"); + dmap.put("usedRAM", "0"); + dmap.put("proto_version", "" + OSDServiceConstants.INTERFACE_ID); + Service reg = Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setName("mockUpOSD3") + .setUuid("mockUpOSD3").setVersion(0).setLastUpdatedS(0) + .setData(ServiceDataMap.newBuilder().addAllData(KeyValuePairs.fromMap(dmap))).build(); + RPCResponse response = dirClient.xtreemfs_service_register(null, + RPCAuthentication.authNone, RPCAuthentication.userService, reg); + response.get(); + response.freeBuffers(); + + UUIDResolver.addLocalMapping("mockUpOSD3", 11111, Schemes.SCHEME_PBRPC); + } + + if (enabledServs.contains(Services.OSD)) { + int osdCount = Collections.frequency(enabledServs, Services.OSD); + osds = new HashMap(osdCount); + osdConfigs = SetupUtils.createMultipleOSDConfigs(osdCount); + for (OSDConfig config : osdConfigs) { + TestOSD osd = new TestOSD(new OSDRequestDispatcher(config)); + osd.start(); + osds.put(config.getUUID().toString(), osd); + } + + // Save address of first OSD for getOSDAdress method. + firstOSDAddress = osdConfigs[0].getUUID().getAddress(); + + Logging.logMessage(Logging.LEVEL_DEBUG, this, "OSDs 1-" + osdCount + " running"); + } + + if (enabledServs.contains(Services.MRC)) { + mrc = new MRCRequestDispatcher(SetupUtils.createMRC1Config(), SetupUtils.createMRC1dbsConfig()); + mrc.startup(); + Logging.logMessage(Logging.LEVEL_DEBUG, this, "MRC running"); + } + + if (enabledServs.contains(Services.MRC_CLIENT)) { + mrcClient = new MRCServiceClient(rpcClient, null); + } + + if (enabledServs.contains(Services.OSD_CLIENT)) { + osdClient = new OSDServiceClient(rpcClient, null); + } + } catch (Exception ex) { + ex.printStackTrace(); + // Shutdown servers which were already started or they will block ports. + shutdown(); + + // After shutdown, log remaining threads in case of blocked ports to debug the issue. + if (ex instanceof BindException && ex.getMessage().contains("Address already in use")) { + Logging.logMessage( + Logging.LEVEL_ERROR, + this, + "TestEnvironment could not be started because: " + + ex.getMessage() + + " Please examine the following dump of threads to check if a previous test method did not correctly stop all servers."); + StringBuilder threadStates = new StringBuilder(); + CrashReporter.reportThreadStates(threadStates); + Logging.logMessage(Logging.LEVEL_ERROR, this, "Thread States: %s", threadStates.toString()); + } + + throw ex; + } + } + + public void shutdown() { + Logging.logMessage(Logging.LEVEL_DEBUG, this, "shutting down testEnv..."); + + if (enabledServs.contains(Services.MRC) && mrc != null) { + try { + mrc.shutdown(); + } catch (Throwable th) { + th.printStackTrace(); + } + } + + if (enabledServs.contains(Services.OSD)) { + try { + for (TestOSD osd : osds.values()) { + if (osd != null && osd.started) { + osd.shutdown(); + } + } + } catch (Throwable th) { + th.printStackTrace(); + } + } + + if (enabledServs.contains(Services.UUID_RESOLVER)) { + try { + UUIDResolver.shutdown(); + } catch (Throwable th) { + } + } + + if (enabledServs.contains(Services.DIR_SERVICE) && dirService != null) { + try { + dirService.shutdown(); + dirService.waitForShutdown(); + } catch (Throwable th) { + th.printStackTrace(); + } + } + + try { + getRpcClient().shutdown(); + getRpcClient().waitForShutdown(); + } catch (Throwable th) { + th.printStackTrace(); + } + + if (enabledServs.contains(Services.TIME_SYNC)) { + try { + tsInstance = TimeSync.getInstance(); + if (tsInstance != null) { + tsInstance.shutdown(); + tsInstance.waitForShutdown(); + } + } catch (Throwable th) { + } + } + + // cleanup + File testDir = new File(SetupUtils.TEST_DIR); + // FSUtils.delTree(testDir); + } +} diff --git a/java/servers/test/org/xtreemfs/test/TestHelper.java b/java/servers/test/org/xtreemfs/test/TestHelper.java new file mode 100644 index 0000000..29a3c41 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/TestHelper.java @@ -0,0 +1,15 @@ +package org.xtreemfs.test; + +import org.junit.rules.TestRule; +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; + +public class TestHelper { + public static final TestRule testLog = new TestWatcher() { + protected void starting(Description description) { + System.out.println("TEST: " + description.getTestClass().getSimpleName() + + "." + description.getMethodName()); + } + }; + +} diff --git a/java/servers/test/org/xtreemfs/test/common/CapabilityTest.java b/java/servers/test/org/xtreemfs/test/common/CapabilityTest.java new file mode 100644 index 0000000..94c8a42 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/common/CapabilityTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.Capability; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.osd.storage.HashStorageLayout; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +public class CapabilityTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static final String SECRET = "secret"; + + private TestEnvironment te; + + @Before + public void setUp() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + + te = new TestEnvironment(TestEnvironment.Services.TIME_SYNC); + te.start(); + } + + @After + public void tearDown() throws Exception { + te.shutdown(); + } + + @Test + public void testCapability() throws Exception { + + // create and test capability that is valid for an hour + Capability cap = new Capability("1254" + ((HashStorageLayout.WIN) ? ":" : "_") + "AB", 1, 60, + System.currentTimeMillis() / 1000 + 100, "", 1, false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, SECRET); + + assertTrue(cap.isValid()); + assertEquals(cap.getFileId(), "1254" + ((HashStorageLayout.WIN) ? ":" : "_") + "AB"); + assertEquals(cap.getAccessMode(), 1); + + // assert that a capability is invalid if it has timed out + Capability cap4 = new Capability("bla" + ((HashStorageLayout.WIN) ? ":" : "_") + "2", 1, 60, + System.currentTimeMillis() / 1000 - 3600, "", 0, false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, + SECRET); + assertFalse(cap4.isValid()); + + } +} diff --git a/java/servers/test/org/xtreemfs/test/common/benchmark/ControllerIntegrationTest.java b/java/servers/test/org/xtreemfs/test/common/benchmark/ControllerIntegrationTest.java new file mode 100644 index 0000000..486c805 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/common/benchmark/ControllerIntegrationTest.java @@ -0,0 +1,556 @@ +package org.xtreemfs.test.common.benchmark; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.xtreemfs.common.benchmark.BenchmarkUtils.KiB_IN_BYTES; +import static org.xtreemfs.common.benchmark.BenchmarkUtils.MiB_IN_BYTES; +import static org.xtreemfs.foundation.pbrpc.client.RPCAuthentication.authNone; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.benchmark.BenchmarkConfig; +import org.xtreemfs.common.benchmark.BenchmarkConfig.ConfigBuilder; +import org.xtreemfs.common.benchmark.BenchmarkResult; +import org.xtreemfs.common.benchmark.BenchmarkUtils; +import org.xtreemfs.common.benchmark.BenchmarkUtils.BenchmarkType; +import org.xtreemfs.common.benchmark.Controller; +import org.xtreemfs.common.libxtreemfs.Client; +import org.xtreemfs.common.libxtreemfs.ClientFactory; +import org.xtreemfs.common.libxtreemfs.Options; +import org.xtreemfs.common.libxtreemfs.Volume; +import org.xtreemfs.common.libxtreemfs.exceptions.VolumeNotFoundException; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.dir.DIRRequestDispatcher; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +public class ControllerIntegrationTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static DIRRequestDispatcher dir; + private static TestEnvironment testEnv; + private static DIRConfig dirConfig; + private static RPC.UserCredentials userCredentials; + private static RPC.Auth auth = RPCAuthentication.authNone; + private static DIRClient dirClient; + private static final int NUMBER_OF_OSDS = 3; + private static OSDConfig osdConfigs[]; + private static OSD osds[]; + private static MRCRequestDispatcher mrc2; + private static String dirAddress; + + private ConfigBuilder configBuilder; + private Controller controller; + private Client client; + + @BeforeClass + public static void initializeTest() throws Exception { + FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); + Logging.start(Logging.LEVEL_WARN, Logging.Category.tool); + + dirConfig = SetupUtils.createDIRConfig(); + osdConfigs = SetupUtils.createMultipleOSDConfigs(NUMBER_OF_OSDS); + + dir = new DIRRequestDispatcher(dirConfig, SetupUtils.createDIRdbsConfig()); + dir.startup(); + dir.waitForStartup(); + + testEnv = new TestEnvironment(TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.RPC_CLIENT, TestEnvironment.Services.MRC); + testEnv.start(); + + userCredentials = RPC.UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + dirClient = new DIRClient(new DIRServiceClient(testEnv.getRpcClient(), null), + new InetSocketAddress[] { testEnv.getDIRAddress() }, 3, 1000); + + osds = new OSD[NUMBER_OF_OSDS]; + for (int i = 0; i < osds.length; i++) { + osds[i] = new OSD(osdConfigs[i]); + } + dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + } + + @Before + public void setUp() throws Exception { + configBuilder = BenchmarkConfig.newBuilder(); + configBuilder.setDirAddress(dirAddress); + configBuilder.setUserName("test").setGroup("test"); + Options options = new Options(); + client = ClientFactory.createClient(dirAddress, userCredentials, null, options); + client.start(); + + /* check that all volumes have been deleted properly by previous tests (prevent error masking) */ + assertNoVolumes("BenchVolA", "BenchVolB", "BenchVolC"); + } + + @After + public void tearDown() throws Exception { + client.shutdown(); + } + + @AfterClass + public static void shutdownTest() throws Exception { + + for (int i = 0; i < osds.length; i++) { + if (osds[i] != null) { + osds[i].shutdown(); + } + } + + if (mrc2 != null) { + mrc2.shutdown(); + mrc2 = null; + } + + testEnv.shutdown(); + dir.shutdown(); + dir.waitForShutdown(); + } + + @Test + public void testSetupVolumes() throws Exception { + controller = new Controller(configBuilder.build()); + + controller.setupVolumes("BenchVolA", "BenchVolB", "BenchVolC"); + + List volumes = Arrays.asList(client.listVolumeNames()); + assertTrue(volumes.contains("BenchVolA")); + assertTrue(volumes.contains("BenchVolB")); + assertTrue(volumes.contains("BenchVolC")); + + controller.teardown(); + volumes = Arrays.asList(client.listVolumeNames()); + assertEquals(0, volumes.size()); + } + + @Test + public void testSequentialBenchmark() throws Exception { + controller = new Controller(configBuilder.build()); + controller.setupVolumes("BenchVolA", "BenchVolB"); + List results = controller.startSequentialWriteBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("SEQ_WRITE", 2, 10L * MiB_IN_BYTES, 2, results); + results = controller.startSequentialReadBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("SEQ_READ", 2, 10L * MiB_IN_BYTES, 2, results); + controller.teardown(); + } + + @Test + public void testSequentialBenchmarkSeparatedRuns() throws Exception { + configBuilder.setNoCleanup(); + BenchmarkConfig config = configBuilder.build(); + controller = new Controller(config); + controller.setupVolumes("BenchVolA", "BenchVolB"); + List results = controller.startSequentialWriteBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("SEQ_WRITE", 2, 10L * MiB_IN_BYTES, 2, results); + controller.teardown(); + + controller = new Controller(config); + controller.setupVolumes("BenchVolA", "BenchVolB"); + results = controller.startSequentialReadBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("SEQ_READ", 2, 10L * MiB_IN_BYTES, 2, results); + controller.teardown(); + deleteVolumes("BenchVolA", "BenchVolB"); + } + + @Test + public void testRandomBenchmark() throws Exception { + configBuilder.setBasefileSizeInBytes(20L * MiB_IN_BYTES); + controller = new Controller(configBuilder.build()); + controller.setupVolumes("BenchVolA", "BenchVolB"); + List results = controller.startRandomWriteBenchmark(1L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("RAND_WRITE", 2, 1L * MiB_IN_BYTES, 2, results); + results = controller.startRandomReadBenchmark(1L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("RAND_READ", 2, 1L * MiB_IN_BYTES, 2, results); + controller.teardown(); + } + + @Test + public void testRandomBenchmarkSeparateRuns() throws Exception { + configBuilder.setBasefileSizeInBytes(20L * MiB_IN_BYTES).setNoCleanup(); + BenchmarkConfig config = configBuilder.build(); + + controller = new Controller(config); + controller.setupVolumes("BenchVolA", "BenchVolB"); + List results = controller.startRandomWriteBenchmark(1L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("RAND_WRITE", 2, 1L * MiB_IN_BYTES, 2, results); + controller.teardown(); + + controller = new Controller(config); + controller.setupVolumes("BenchVolA", "BenchVolB"); + results = controller.startRandomReadBenchmark(1L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("RAND_READ", 2, 1L * MiB_IN_BYTES, 2, results); + controller.teardown(); + deleteVolumes("BenchVolA", "BenchVolB"); + } + + @Test + public void testFilebasedBenchmark() throws Exception { + controller = new Controller(configBuilder.build()); + controller.setupVolumes("BenchVolA", "BenchVolB"); + List results = controller.startFilebasedWriteBenchmark(1L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("FILES_WRITE", 2, 1L * MiB_IN_BYTES, 2, results); + results = controller.startFilebasedReadBenchmark(1L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("FILES_READ", 2, 1L * MiB_IN_BYTES, 2, results); + controller.teardown(); + } + + @Test + public void testFilebasedBenchmarkSeparateRuns() throws Exception { + configBuilder.setNoCleanup(); + BenchmarkConfig config = configBuilder.build(); + + controller = new Controller(config); + controller.setupVolumes("BenchVolA", "BenchVolB"); + List results = controller.startFilebasedWriteBenchmark(1L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("FILES_WRITE", 2, 1L * MiB_IN_BYTES, 2, results); + controller.teardown(); + + controller = new Controller(config); + controller.setupVolumes("BenchVolA", "BenchVolB"); + results = controller.startFilebasedReadBenchmark(1L*BenchmarkUtils.MiB_IN_BYTES, 2); + compareResults("FILES_READ", 2, 1L * MiB_IN_BYTES, 2, results); + controller.teardown(); + deleteVolumes("BenchVolA", "BenchVolB"); + } + + @Test + public void testConfigUser() throws Exception { + configBuilder.setUserName("test"); + Volume volume = performBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.SEQ_WRITE); + assertEquals("test", volume.getAttr(userCredentials, "benchmarks/sequentialBenchmark/benchFile0").getUserId()); + deleteVolumes("BenchVolA"); + } + + @Test + public void testConfigGroup() throws Exception { + configBuilder.setGroup("test"); + Volume volume = performBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.SEQ_WRITE); + assertEquals("test", volume.getAttr(userCredentials, "benchmarks/sequentialBenchmark/benchFile0").getGroupId()); + deleteVolumes("BenchVolA"); + } + + @Test + public void testConfigSeqSize() throws Exception { + long seqSize = 2L * MiB_IN_BYTES; + Volume volume = performBenchmark(seqSize, configBuilder, BenchmarkType.SEQ_WRITE); + assertEquals(seqSize, volume.getAttr(userCredentials, "benchmarks/sequentialBenchmark/benchFile0").getSize()); + deleteVolumes("BenchVolA"); + } + + @Test + public void testConfigBasefileSize() throws Exception { + long randSize = 1L * MiB_IN_BYTES; + long basefileSize = 20L * MiB_IN_BYTES; + configBuilder.setBasefileSizeInBytes(basefileSize); + Volume volume = performBenchmark(randSize, configBuilder, BenchmarkType.RAND_WRITE); + assertEquals(basefileSize, volume.getAttr(userCredentials, "benchmarks/basefile").getSize()); + deleteVolumes("BenchVolA"); + } + + @Test + public void testConfigFilesSize() throws Exception { + int fileSize = 8 * KiB_IN_BYTES; + configBuilder.setFilesize(fileSize); + Volume volume = performBenchmark(1L*BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.FILES_WRITE); + int numberOfFiles = (MiB_IN_BYTES) / (8 * KiB_IN_BYTES); + for (int i = 0; i < numberOfFiles; i++) { + long fileSizeActual = volume.getAttr(userCredentials, "benchmarks/randomBenchmark/benchFile" + i).getSize(); + assertEquals(fileSize, fileSizeActual); + } + deleteVolumes("BenchVolA"); + } + + @Test + public void testConfigStripeSize() throws Exception { + int stripeSize = 64 * KiB_IN_BYTES; + configBuilder.setStripeSizeInBytes(stripeSize); + Volume volume = performBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.SEQ_WRITE); + + String sp_values = volume.getXAttr(userCredentials, "", "xtreemfs.default_sp"); + assertEquals("size:64", sp_values.split(",")[2].replace("\"", "").replace("}", "")); + + deleteVolumes("BenchVolA"); + } + + @Test + public void testConfigStripeWidth() throws Exception { + configBuilder.setStripeWidth(2); + Volume volume = performBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.SEQ_WRITE); + String sp_values = volume.getXAttr(userCredentials, "", "xtreemfs.default_sp"); + + assertEquals("width:2", sp_values.split(",")[1].replace("\"", "")); + + deleteVolumes("BenchVolA"); + } + + /* + * Test, that using an existing volume doesn't change the stripe size and width previously set on said volume. + */ + @Test + public void testConfigStripeSizeWidthNotSet() throws Exception { + + List volumeAttributes = new ArrayList(); + client.createVolume(authNone, userCredentials, "BenchVolA", 511, "test", "test", GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, + GlobalTypes.StripingPolicyType.STRIPING_POLICY_RAID0, 1024, 2, volumeAttributes); + + Volume volume = performBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.SEQ_WRITE); + + String sp_values = volume.getXAttr(userCredentials, "", "xtreemfs.default_sp"); + assertEquals("width:2", sp_values.split(",")[1].replace("\"", "")); + assertEquals("size:1024", sp_values.split(",")[2].replace("\"", "").replace("}", "")); + + deleteVolumes("BenchVolA"); + } + + /* + * Test, that setting stripe size and width overrides values of an existing volume. + */ + @Test + public void testConfigStripeSizeWidthSet() throws Exception { + List volumeAttributes = new ArrayList(); + client.createVolume(authNone, userCredentials, "BenchVolA", 511, "test", "test", GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, + GlobalTypes.StripingPolicyType.STRIPING_POLICY_RAID0, 128, 1, volumeAttributes); + + configBuilder.setStripeSizeInBytes(256*1024).setStripeWidth(2); + Volume volume = performBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.SEQ_WRITE); + + String sp_values = volume.getXAttr(userCredentials, "", "xtreemfs.default_sp"); + assertEquals("width:2", sp_values.split(",")[1].replace("\"", "")); + assertEquals("size:256", sp_values.split(",")[2].replace("\"", "").replace("}", "")); + + deleteVolumes("BenchVolA"); + } + + @Test + public void testConfigOSDSelectionPolicy() throws Exception { + configBuilder.setOsdSelectionPolicies("1001,3003"); + Volume volumeA = performBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.SEQ_WRITE); + assertEquals("1001,3003", volumeA.getOSDSelectionPolicy(userCredentials)); + deleteVolumes("BenchVolA"); + } + + + /* + * Test, that using an existing volume doesn't change the osd selection policies previously set on said volume. + */ + @Test + public void testConfigOSDSelectionPolicyNotSet() throws Exception { + + List volumeAttributes = new ArrayList(); + client.createVolume(authNone, userCredentials, "BenchVolA", 511, "test", "test", GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, + GlobalTypes.StripingPolicyType.STRIPING_POLICY_RAID0, 128, 1, volumeAttributes); + Volume volume = client.openVolume("BenchVolA", null, new Options()); + volume.setOSDSelectionPolicy(userCredentials, "1001,3003"); + volume.close(); + + configBuilder.setUserName("test").setGroup("test"); + Volume volumeA = performBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.SEQ_WRITE); + assertEquals("1001,3003", volumeA.getOSDSelectionPolicy(userCredentials)); + deleteVolumes("BenchVolA"); + } + + @Test + public void testConfigOSDSelectionUUID() throws Exception { + /* perform benchmark on osd "UUID:localhost:42640" */ + configBuilder.setSelectOsdsByUuid("UUID:localhost:42640"); + Volume volumeA = performBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.SEQ_WRITE); + + /* perform benchmark on osd "UUID:localhost:42641" */ + configBuilder = BenchmarkConfig.newBuilder(); + configBuilder.setUserName("test").setGroup("test"); + configBuilder.setDirAddress(dirAddress); + configBuilder.setSelectOsdsByUuid("UUID:localhost:42641").setNoCleanup(); + controller = new Controller(configBuilder.build()); + controller.setupVolumes("BenchVolB"); + controller.startSequentialWriteBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, 1); + controller.teardown(); + Volume volumeB = client.openVolume("BenchVolB", null, new Options()); + + /* assert, that the benchmark files were created on the correct osd */ + assertEquals("1002", volumeA.getOSDSelectionPolicy(userCredentials)); + assertEquals("UUID:localhost:42640", + volumeA.getSuitableOSDs(userCredentials, "benchmarks/sequentialBenchmark/benchFile0", 1).get(0)); + assertEquals("1002", volumeB.getOSDSelectionPolicy(userCredentials)); + assertEquals("UUID:localhost:42641", + volumeB.getSuitableOSDs(userCredentials, "benchmarks/sequentialBenchmark/benchFile0", 1).get(0)); + deleteVolumes("BenchVolA", "BenchVolB"); + } + + @Test + public void testConfigReplicationPolicy() throws Exception { + configBuilder.setReplicationPolicy("WqRq"); + configBuilder.setReplicationFactor(3); + Volume volumeA = performBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.SEQ_WRITE); + + String default_rp = volumeA.getXAttr(userCredentials,"", "xtreemfs.default_rp"); + assertEquals("replication-factor:3", default_rp.split(",")[0].replace("\"", "").replace("{", "")); + assertEquals("update-policy:WqRq", default_rp.split(",")[2].replace("\"", "").replace("}", "")); + + deleteVolumes("BenchVolA"); + } + + /* + * Tests, that performing a benchmark on a volume for which a default replication policy was set does not override the policy + */ + @Test + public void testConfigReplicationPolicyNotSet() throws Exception { + + List volumeAttributes = new ArrayList(); + client.createVolume(authNone, userCredentials, "BenchVolA", 511, "test", "test", + GlobalTypes.AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, + GlobalTypes.StripingPolicyType.STRIPING_POLICY_RAID0, 128, 1, volumeAttributes); + Volume volume = client.openVolume("BenchVolA", null, new Options()); + volume.setDefaultReplicationPolicy(userCredentials, "/", "WqRq", 3, 0); + volume.close(); + + configBuilder.setUserName("test").setGroup("test"); + Volume volumeA = performBenchmark(10L * BenchmarkUtils.MiB_IN_BYTES, configBuilder, BenchmarkType.SEQ_WRITE); + + String default_rp = volumeA.getXAttr(userCredentials, "", "xtreemfs.default_rp"); + assertEquals("replication-factor:3", default_rp.split(",")[0].replace("\"", "").replace("{", "")); + assertEquals("update-policy:WqRq", default_rp.split(",")[2].replace("\"", "").replace("}", "")); + deleteVolumes("BenchVolA"); + } + + /* The NoCleanup option is testet implicitly in all the above Config tests */ + + @Test + public void testConfigNoCleanupVolumes() throws Exception { + configBuilder.setNoCleanupVolumes(); + controller = new Controller(configBuilder.build()); + controller.setupVolumes("BenchVolA", "BenchVolB", "BenchVolC"); + controller.startSequentialWriteBenchmark(10L*BenchmarkUtils.MiB_IN_BYTES, 3); + + Volume volumeA = client.openVolume("BenchVolA", null, new Options()); + Volume volumeB = client.openVolume("BenchVolB", null, new Options()); + Volume volumeC = client.openVolume("BenchVolC", null, new Options()); + + /* the benchFiles are still there after the benchmark */ + long seqSize = 10L * BenchmarkUtils.MiB_IN_BYTES; + assertEquals(seqSize, volumeA.getAttr(userCredentials, "benchmarks/sequentialBenchmark/benchFile0").getSize()); + assertEquals(seqSize, volumeB.getAttr(userCredentials, "benchmarks/sequentialBenchmark/benchFile0").getSize()); + assertEquals(seqSize, volumeC.getAttr(userCredentials, "benchmarks/sequentialBenchmark/benchFile0").getSize()); + + controller.teardown(); + + /* + * after the teardown (which includes the deletion of the benchmark volumes and files), only the volumes are + * present + */ + assertEquals(0, (int) Integer.valueOf(volumeA.getXAttr(userCredentials, "", "xtreemfs.num_files"))); + assertEquals(0, (int) Integer.valueOf(volumeB.getXAttr(userCredentials, "", "xtreemfs.num_files"))); + assertEquals(0, (int) Integer.valueOf(volumeC.getXAttr(userCredentials, "", "xtreemfs.num_files"))); + assertEquals(0, (int) Integer.valueOf(volumeA.getXAttr(userCredentials, "", "xtreemfs.used_space"))); + assertEquals(0, (int) Integer.valueOf(volumeB.getXAttr(userCredentials, "", "xtreemfs.used_space"))); + assertEquals(0, (int) Integer.valueOf(volumeC.getXAttr(userCredentials, "", "xtreemfs.used_space"))); + deleteVolumes("BenchVolA", "BenchVolB", "BenchVolC"); + } + + @Test + public void testConfigNoCleanupBasefile() throws Exception { + long basefileSize = 30L * BenchmarkUtils.MiB_IN_BYTES; + long randSize = BenchmarkUtils.MiB_IN_BYTES; + configBuilder.setNoCleanupBasefile().setBasefileSizeInBytes(basefileSize) + .setNoCleanupVolumes(); + controller = new Controller(configBuilder.build()); + controller.setupVolumes("BenchVolA"); + controller.startRandomWriteBenchmark(randSize, 1); + + /* the filebased benchmark is used to show, that really files are (created and) deleted, except the basefile */ + controller.startFilebasedWriteBenchmark(randSize, 1); + + Volume volume = client.openVolume("BenchVolA", null, new Options()); + + /* number of files from filebased benchmark + basefile */ + int numberOfFiles = (int) (randSize / (4 * BenchmarkUtils.KiB_IN_BYTES)) + 1; + assertEquals(numberOfFiles, (int) Integer.valueOf(volume.getXAttr(userCredentials, "", "xtreemfs.num_files"))); + assertEquals(basefileSize + randSize, + (int) Integer.valueOf(volume.getXAttr(userCredentials, "", "xtreemfs.used_space"))); + + controller.teardown(); + + /* + * after the teardown (which includes the deletion of the benchmark volumes and files), only the basefile is + * still present + */ + assertEquals(basefileSize, volume.getAttr(userCredentials, "benchmarks/basefile").getSize()); + assertEquals(1, (int) Integer.valueOf(volume.getXAttr(userCredentials, "", "xtreemfs.num_files"))); + assertEquals(basefileSize, (int) Integer.valueOf(volume.getXAttr(userCredentials, "", "xtreemfs.used_space"))); + } + + private void assertNoVolumes(String... volumes) throws Exception { + for (String volumeName : volumes) { + try { + Volume volume = client.openVolume(volumeName, null, new Options()); + fail("VolumeNotFoundException expected"); + } catch (VolumeNotFoundException e) { + // ok (Exception expected) + } + } + } + + private void compareResults(String type, int threads, long size, int numberOfResults, List results) { + int resultCounter = 0; + for (BenchmarkResult result : results) { + resultCounter++; + String benchmarkType = result.getBenchmarkType().toString(); + assertEquals(type, benchmarkType); + assertEquals(threads, result.getNumberOfReadersOrWriters()); + assertEquals(size, result.getRequestedSize()); + assertEquals(size, result.getActualSize()); + } + assertEquals(numberOfResults, resultCounter); + } + + private Volume performBenchmark(long size, ConfigBuilder configBuilder, BenchmarkType type) throws Exception { + configBuilder.setNoCleanup(); + controller = new Controller(configBuilder.build()); + controller.setupVolumes("BenchVolA"); + switch (type) { + case SEQ_WRITE: + controller.startSequentialWriteBenchmark(size, 1); + break; + case RAND_WRITE: + controller.startRandomWriteBenchmark(size, 1); + break; + case FILES_WRITE: + controller.startFilebasedWriteBenchmark(size, 1); + break; + } + controller.teardown(); + + Volume volume = client.openVolume("BenchVolA", null, new Options()); + return volume; + } + + private void deleteVolumes(String... volumeNames) throws IOException { + for (String volumeName : volumeNames) { + client.deleteVolume(auth, userCredentials, volumeName); + } + } +} diff --git a/java/servers/test/org/xtreemfs/test/common/monitoring/DIRMonitoringTest.java b/java/servers/test/org/xtreemfs/test/common/monitoring/DIRMonitoringTest.java new file mode 100644 index 0000000..0489890 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/common/monitoring/DIRMonitoringTest.java @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2009-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.common.monitoring; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.net.InetSocketAddress; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.monitoring.generatedcode.XTREEMFS_MIBOidTable; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.mrc.MRCConfig; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +import com.sun.management.snmp.SnmpDefinitions; +import com.sun.management.snmp.SnmpInt; +import com.sun.management.snmp.SnmpOid; +import com.sun.management.snmp.SnmpOidTableSupport; +import com.sun.management.snmp.SnmpVarBind; +import com.sun.management.snmp.SnmpVarBindList; +import com.sun.management.snmp.manager.SnmpParameters; +import com.sun.management.snmp.manager.SnmpPeer; +import com.sun.management.snmp.manager.SnmpRequest; +import com.sun.management.snmp.manager.SnmpSession; + +public class DIRMonitoringTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + TestEnvironment testEnv; + + SnmpPeer dirAgent, mrcAgent, osdAgent; + + SnmpSession session; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.RPC_CLIENT, TestEnvironment.Services.MRC, TestEnvironment.Services.OSD }); + testEnv.start(); + + final SnmpOidTableSupport oidTable = new XTREEMFS_MIBOidTable(); + SnmpOid.setSnmpOidTable(oidTable); + + DIRConfig dirConfig = SetupUtils.createDIRConfig(); + MRCConfig mrcConfig = SetupUtils.createMRC1Config(); + OSDConfig osdConfig = SetupUtils.createMultipleOSDConfigs(1)[0]; + + dirAgent = new SnmpPeer(dirConfig.getSnmpAddress().getHostName(), dirConfig.getSnmpPort()); + mrcAgent = new SnmpPeer(mrcConfig.getSnmpAddress().getHostName(), mrcConfig.getSnmpPort()); + osdAgent = new SnmpPeer(osdConfig.getSnmpAddress().getHostName(), osdConfig.getSnmpPort()); + + // Create and set Parameters, i.e. the community strings for read-only + // and read-write. + // Since the config don't provide an ACL file it doens't matter what + // community strings are + // used here + final SnmpParameters params = new SnmpParameters("public", "private"); + + dirAgent.setParams(params); + mrcAgent.setParams(params); + osdAgent.setParams(params); + + session = new SnmpSession("UnitTest Session"); + + } + + @After + public void tearDown() throws Exception { + + session.destroySession(); + + testEnv.shutdown(); + } + + /** + * Make an SNMP get + * + * @param agent + * The {@link SnmpPeer} from which the OID should be read. + * @param varDesc + * The textual representation of the OID. + * + * @return + */ + private SnmpVarBindList makeSnmpGet(SnmpPeer agent, String varDesc) throws Exception { + final SnmpVarBindList list = new SnmpVarBindList("UnitTest varbind list"); + + // We want to read the "sysDescr" variable. + list.addVarBind(varDesc); + + // Make the SNMP get request and wait for the result. + SnmpRequest request = session.snmpGetRequest(agent, null, list); + final boolean completed = request.waitForCompletion(10000); + + // Check for a timeout of the request. + assertTrue(completed); + + // Check if the response contains an error. + int errorStatus = request.getErrorStatus(); + assertEquals(SnmpDefinitions.snmpRspNoError, errorStatus); + + // Now we can extract the content of the result. + return request.getResponseVarBindList(); + + } + + @Test + public void testAddressMappingCount() throws Exception { + + SnmpVarBindList result = makeSnmpGet(dirAgent, "addressMappingCount.0"); + + SnmpVarBind varBind = result.getVarBindAt(0); + SnmpInt snmpInt = varBind.getSnmpIntValue(); + + // After initialization there should be 3 address mappings registered at + // the DIR. + assertEquals(3, snmpInt.intValue()); + + // start another MRC to increase number of address mappings + MRCConfig mrcConfig2 = SetupUtils.createMRC2Config(); + MRCRequestDispatcher secondMrc = new MRCRequestDispatcher(mrcConfig2, + SetupUtils.createMRC2dbsConfig()); + + secondMrc.startup(); + + result = makeSnmpGet(dirAgent, "addressMappingCount.0"); + + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(4, snmpInt.intValue()); + + secondMrc.shutdown(); + + } + + @Test + public void testServiceCount() throws Exception { + + SnmpVarBindList result = makeSnmpGet(dirAgent, "serviceCount.0"); + + SnmpVarBind varBind = result.getVarBindAt(0); + SnmpInt snmpInt = varBind.getSnmpIntValue(); + + // After initialization there should be 2 services registered at the + // DIR. + assertEquals(2, snmpInt.intValue()); + + Client c = new Client(new InetSocketAddress[] { testEnv.getDIRAddress() }, 10000, 60000, null); + c.start(); + UserCredentials uc = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + c.createVolume("foobar", RPCAuthentication.authNone, uc, SetupUtils.getStripingPolicy(64, 1), + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, 0777); + result = makeSnmpGet(dirAgent, "serviceCount.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + // Now there should be 3 services. + assertEquals(3, snmpInt.intValue()); + + c.deleteVolume("foobar", RPCAuthentication.authNone, uc); + result = makeSnmpGet(dirAgent, "serviceCount.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + // Now there should be 2 services again. + assertEquals(2, snmpInt.intValue()); + + c.stop(); + + // start another MRC to increase number of registred services + MRCConfig mrcConfig2 = SetupUtils.createMRC2Config(); + MRCRequestDispatcher secondMrc = new MRCRequestDispatcher(mrcConfig2, + SetupUtils.createMRC2dbsConfig()); + + secondMrc.startup(); + + result = makeSnmpGet(dirAgent, "serviceCount.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + // Now there should be 3 services. + assertEquals(3, snmpInt.intValue()); + + secondMrc.shutdown(); + + result = makeSnmpGet(dirAgent, "serviceCount.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + // Now there should be 2 services again. + assertEquals(3, snmpInt.intValue()); + + } + +} diff --git a/java/servers/test/org/xtreemfs/test/common/monitoring/GeneralMonitoringTest.java b/java/servers/test/org/xtreemfs/test/common/monitoring/GeneralMonitoringTest.java new file mode 100644 index 0000000..7bf9083 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/common/monitoring/GeneralMonitoringTest.java @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2009-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.common.monitoring; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.babudb.BabuDBFactory; +import org.xtreemfs.common.monitoring.generatedcode.XTREEMFS_MIBOidTable; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.mrc.MRCConfig; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceConstants; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +import com.sun.management.snmp.SnmpDefinitions; +import com.sun.management.snmp.SnmpInt; +import com.sun.management.snmp.SnmpOid; +import com.sun.management.snmp.SnmpOidTableSupport; +import com.sun.management.snmp.SnmpString; +import com.sun.management.snmp.SnmpVarBind; +import com.sun.management.snmp.SnmpVarBindList; +import com.sun.management.snmp.manager.SnmpParameters; +import com.sun.management.snmp.manager.SnmpPeer; +import com.sun.management.snmp.manager.SnmpRequest; +import com.sun.management.snmp.manager.SnmpSession; + +public class GeneralMonitoringTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment testEnv; + + private DIRConfig dirConfig; + + private MRCConfig mrcConfig; + + private OSDConfig osdConfig; + + private SnmpPeer dirAgent, mrcAgent, osdAgent; + + private SnmpSession session; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.RPC_CLIENT, TestEnvironment.Services.MRC, TestEnvironment.Services.OSD }); + testEnv.start(); + + final SnmpOidTableSupport oidTable = new XTREEMFS_MIBOidTable(); + SnmpOid.setSnmpOidTable(oidTable); + + dirConfig = SetupUtils.createDIRConfig(); + mrcConfig = SetupUtils.createMRC1Config(); + osdConfig = SetupUtils.createMultipleOSDConfigs(1)[0]; + + dirAgent = new SnmpPeer(dirConfig.getSnmpAddress().getHostName(), dirConfig.getSnmpPort()); + mrcAgent = new SnmpPeer(mrcConfig.getSnmpAddress().getHostName(), mrcConfig.getSnmpPort()); + osdAgent = new SnmpPeer(osdConfig.getSnmpAddress().getHostName(), osdConfig.getSnmpPort()); + + // Create and set Parameters, i.e. the community strings for read-only + // and read-write. + // Since the config don't provide an ACL file it doens't matter what + // community strings are + // used here + final SnmpParameters params = new SnmpParameters("public", "private"); + + dirAgent.setParams(params); + mrcAgent.setParams(params); + osdAgent.setParams(params); + + session = new SnmpSession("UnitTest Session"); + + } + + @After + public void tearDown() throws Exception { + + session.destroySession(); + + testEnv.shutdown(); + } + + /** + * Make an SNMP get + * + * @param agent + * The {@link SnmpPeer} from which the OID should be read. + * @param varDesc + * The textual representation of the OID. + * + * @return + */ + private SnmpVarBindList makeSnmpGet(SnmpPeer agent, String varDesc) throws Exception { + final SnmpVarBindList list = new SnmpVarBindList("UnitTest varbind list"); + + // We want to read the "sysDescr" variable. + list.addVarBind(varDesc); + + // Make the SNMP get request and wait for the result. + SnmpRequest request = session.snmpGetRequest(agent, null, list); + final boolean completed = request.waitForCompletion(10000); + + // Check for a timeout of the request. + assertTrue(completed); + + // Check if the response contains an error. + int errorStatus = request.getErrorStatus(); + assertEquals(SnmpDefinitions.snmpRspNoError, errorStatus); + + // Now we can extract the content of the result. + return request.getResponseVarBindList(); + + } + + @Test + public void testRpcInterface() throws Exception { + + // DIR InterfaceID + SnmpVarBindList result = makeSnmpGet(dirAgent, "rpcInterface.0"); + SnmpVarBind varBind = result.getVarBindAt(0); + SnmpInt snmpInt = varBind.getSnmpIntValue(); + + assertEquals(DIRServiceConstants.INTERFACE_ID, snmpInt.intValue()); + + // MRC InterfaceID + result = makeSnmpGet(mrcAgent, "rpcInterface.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(MRCServiceConstants.INTERFACE_ID, snmpInt.intValue()); + + // OSD InterfaceID + result = makeSnmpGet(osdAgent, "rpcInterface.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(OSDServiceConstants.INTERFACE_ID, snmpInt.intValue()); + + } + + @Test + public void testDatabaseVersion() throws Exception { + // DIR BaduDB Version + SnmpVarBindList result = makeSnmpGet(dirAgent, "databaseVersion.0"); + SnmpVarBind varBind = result.getVarBindAt(0); + SnmpString snmpString = varBind.getSnmpStringValue(); + + assertEquals(BabuDBFactory.BABUDB_VERSION, snmpString.toString()); + + // MRC BaduDB Version + result = makeSnmpGet(mrcAgent, "databaseVersion.0"); + varBind = result.getVarBindAt(0); + snmpString = varBind.getSnmpStringValue(); + + assertEquals(BabuDBFactory.BABUDB_VERSION, snmpString.toString()); + } + + @Test + public void testTcpPort() throws Exception { + + // DIR TCPPort + SnmpVarBindList result = makeSnmpGet(dirAgent, "tcpPort.0"); + SnmpVarBind varBind = result.getVarBindAt(0); + SnmpInt snmpInt = varBind.getSnmpIntValue(); + + assertEquals(dirConfig.getPort(), snmpInt.intValue()); + + // MRC TCPPort + result = makeSnmpGet(mrcAgent, "tcpPort.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(mrcConfig.getPort(), snmpInt.intValue()); + + // OSD TCPPort + result = makeSnmpGet(osdAgent, "tcpPort.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(osdConfig.getPort(), snmpInt.intValue()); + + } + + @Test + public void testDebugLevel() throws Exception { + // DIR DebugLevel + SnmpVarBindList result = makeSnmpGet(dirAgent, "debugLevel.0"); + SnmpVarBind varBind = result.getVarBindAt(0); + SnmpInt snmpInt = varBind.getSnmpIntValue(); + + assertEquals(dirConfig.getDebugLevel(), snmpInt.intValue()); + + // MRC DebugLevel + result = makeSnmpGet(mrcAgent, "debugLevel.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(mrcConfig.getDebugLevel(), snmpInt.intValue()); + + // OSD DebugLevel + result = makeSnmpGet(osdAgent, "debugLevel.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(osdConfig.getDebugLevel(), snmpInt.intValue()); + } + + @Test + public void testIsRunning() throws Exception { + // DIR isRunning + SnmpVarBindList result = makeSnmpGet(dirAgent, "isRunning.0"); + SnmpVarBind varBind = result.getVarBindAt(0); + SnmpString snmpString = varBind.getSnmpStringValue(); + + assertEquals("ONLINE", snmpString.toString()); + + // MRC isRunning + result = makeSnmpGet(mrcAgent, "isRunning.0"); + varBind = result.getVarBindAt(0); + snmpString = varBind.getSnmpStringValue(); + + assertEquals("ONLINE", snmpString.toString()); + + // OSD isRunning + result = makeSnmpGet(osdAgent, "isRunning.0"); + varBind = result.getVarBindAt(0); + snmpString = varBind.getSnmpStringValue(); + + assertEquals("ONLINE", snmpString.toString()); + + } + + @Test + public void testServiceType() throws Exception { + // DIR TYPE + SnmpVarBindList result = makeSnmpGet(dirAgent, "serviceType.0"); + SnmpVarBind varBind = result.getVarBindAt(0); + SnmpString snmpString = varBind.getSnmpStringValue(); + + assertEquals("DIR", snmpString.toString()); + + // MRC TYPE + result = makeSnmpGet(mrcAgent, "serviceType.0"); + varBind = result.getVarBindAt(0); + snmpString = varBind.getSnmpStringValue(); + + assertEquals("MRC", snmpString.toString()); + + // OSD TYPE + result = makeSnmpGet(osdAgent, "serviceType.0"); + varBind = result.getVarBindAt(0); + snmpString = varBind.getSnmpStringValue(); + + assertEquals("OSD", snmpString.toString()); + } + + @Test + public void testServiceUUID() throws Exception { + // DIR UUID + SnmpVarBindList result = makeSnmpGet(dirAgent, "serviceUUID.0"); + SnmpVarBind varBind = result.getVarBindAt(0); + SnmpString snmpString = varBind.getSnmpStringValue(); + + assertEquals(dirConfig.getUUID().toString(), snmpString.toString()); + + // MRC UUID + result = makeSnmpGet(mrcAgent, "serviceUUID.0"); + varBind = result.getVarBindAt(0); + snmpString = varBind.getSnmpStringValue(); + + assertEquals(mrcConfig.getUUID().toString(), snmpString.toString()); + + // OSD UUID + result = makeSnmpGet(osdAgent, "serviceUUID.0"); + varBind = result.getVarBindAt(0); + snmpString = varBind.getSnmpStringValue(); + + assertEquals(osdConfig.getUUID().toString(), snmpString.toString()); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/common/monitoring/MRCMonitoringTest.java b/java/servers/test/org/xtreemfs/test/common/monitoring/MRCMonitoringTest.java new file mode 100644 index 0000000..8edc1f8 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/common/monitoring/MRCMonitoringTest.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2009-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.common.monitoring; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.net.InetSocketAddress; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.monitoring.generatedcode.XTREEMFS_MIBOidTable; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.mrc.MRCConfig; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +import com.sun.management.snmp.SnmpDefinitions; +import com.sun.management.snmp.SnmpInt; +import com.sun.management.snmp.SnmpOid; +import com.sun.management.snmp.SnmpOidTableSupport; +import com.sun.management.snmp.SnmpVarBind; +import com.sun.management.snmp.SnmpVarBindList; +import com.sun.management.snmp.manager.SnmpParameters; +import com.sun.management.snmp.manager.SnmpPeer; +import com.sun.management.snmp.manager.SnmpRequest; +import com.sun.management.snmp.manager.SnmpSession; + +public class MRCMonitoringTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment testEnv; + + private DIRConfig dirConfig; + + private MRCConfig mrcConfig; + + private OSDConfig osdConfig; + + private SnmpPeer dirAgent, mrcAgent, osdAgent; + + private SnmpSession session; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.RPC_CLIENT, TestEnvironment.Services.MRC, TestEnvironment.Services.OSD }); + testEnv.start(); + + final SnmpOidTableSupport oidTable = new XTREEMFS_MIBOidTable(); + SnmpOid.setSnmpOidTable(oidTable); + + dirConfig = SetupUtils.createDIRConfig(); + mrcConfig = SetupUtils.createMRC1Config(); + osdConfig = SetupUtils.createMultipleOSDConfigs(1)[0]; + + dirAgent = new SnmpPeer(dirConfig.getSnmpAddress().getHostName(), dirConfig.getSnmpPort()); + mrcAgent = new SnmpPeer(mrcConfig.getSnmpAddress().getHostName(), mrcConfig.getSnmpPort()); + osdAgent = new SnmpPeer(osdConfig.getSnmpAddress().getHostName(), osdConfig.getSnmpPort()); + + // Create and set Parameters, i.e. the community strings for read-only and read-write. + // Since the config don't provide an ACL file it doens't matter what community strings are + // used here + final SnmpParameters params = new SnmpParameters("public", "private"); + + dirAgent.setParams(params); + mrcAgent.setParams(params); + osdAgent.setParams(params); + + session = new SnmpSession("UnitTest Session"); + + } + + @After + public void tearDown() throws Exception { + + session.destroySession(); + + testEnv.shutdown(); + } + + /** + * Make an SNMP get + * + * @param agent + * The {@link SnmpPeer} from which the OID should be read. + * @param varDesc + * The textual representation of the OID. + * + * @return + */ + private SnmpVarBindList makeSnmpGet(SnmpPeer agent, String varDesc) throws Exception { + final SnmpVarBindList list = new SnmpVarBindList("UnitTest varbind list"); + + // We want to read the "sysDescr" variable. + list.addVarBind(varDesc); + + // Make the SNMP get request and wait for the result. + SnmpRequest request = session.snmpGetRequest(agent, null, list); + final boolean completed = request.waitForCompletion(10000); + + // Check for a timeout of the request. + assertTrue(completed); + + // Check if the response contains an error. + int errorStatus = request.getErrorStatus(); + assertEquals(SnmpDefinitions.snmpRspNoError, errorStatus); + + // Now we can extract the content of the result. + return request.getResponseVarBindList(); + + } + + @Test + public void testVolumeCount() throws Exception { + + // At first there should be no volumes + SnmpVarBindList result = makeSnmpGet(mrcAgent, "volumeCount.0"); + SnmpVarBind varBind = result.getVarBindAt(0); + SnmpInt snmpInt = varBind.getSnmpIntValue(); + + assertEquals(0, snmpInt.intValue()); + + Client c = new Client(new InetSocketAddress[] { testEnv.getDIRAddress() }, 10000, 60000, null); + c.start(); + + UserCredentials uc = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + c.createVolume("foobar", RPCAuthentication.authNone, uc, SetupUtils.getStripingPolicy(64, 1), + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, 0777); + + // No there should be one volume + result = makeSnmpGet(mrcAgent, "volumeCount.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(1, snmpInt.intValue()); + + c.createVolume("foobar2", RPCAuthentication.authNone, uc, SetupUtils.getStripingPolicy(64, 1), + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, 0777); + c.createVolume("foobar3", RPCAuthentication.authNone, uc, SetupUtils.getStripingPolicy(64, 1), + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, 0777); + c.createVolume("foobar4", RPCAuthentication.authNone, uc, SetupUtils.getStripingPolicy(64, 1), + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, 0777); + + // Now there should be four volumes + result = makeSnmpGet(mrcAgent, "volumeCount.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(4, snmpInt.intValue()); + + c.deleteVolume("foobar3", RPCAuthentication.authNone, uc); + c.deleteVolume("foobar", RPCAuthentication.authNone, uc); + + // Now there should be two volumes + result = makeSnmpGet(mrcAgent, "volumeCount.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(2, snmpInt.intValue()); + + c.deleteVolume("foobar2", RPCAuthentication.authNone, uc); + + // Now there should be one volumes + + result = makeSnmpGet(mrcAgent, "volumeCount.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(1, snmpInt.intValue()); + + try { + c.createVolume("foobar4", RPCAuthentication.authNone, uc, SetupUtils.getStripingPolicy(64, 1), + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, 0777); + + } catch (Exception e) { + // Ignore + } + + // Now there should be still one volume + result = makeSnmpGet(mrcAgent, "volumeCount.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(1, snmpInt.intValue()); + + try { + c.deleteVolume("foobar2", RPCAuthentication.authNone, uc); + + } catch (Exception e) { + // Ignore + } + + // Now there should be still one volume + result = makeSnmpGet(mrcAgent, "volumeCount.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(1, snmpInt.intValue()); + + c.deleteVolume("foobar4", RPCAuthentication.authNone, uc); + + // Now there should be zero volumes + result = makeSnmpGet(mrcAgent, "volumeCount.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(0, snmpInt.intValue()); + } +} diff --git a/java/servers/test/org/xtreemfs/test/common/monitoring/OSDMonitoringTest.java b/java/servers/test/org/xtreemfs/test/common/monitoring/OSDMonitoringTest.java new file mode 100644 index 0000000..5977e45 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/common/monitoring/OSDMonitoringTest.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2009-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.common.monitoring; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.net.InetSocketAddress; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.clients.File; +import org.xtreemfs.common.clients.RandomAccessFile; +import org.xtreemfs.common.clients.Volume; +import org.xtreemfs.common.monitoring.generatedcode.XTREEMFS_MIBOidTable; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.mrc.MRCConfig; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +import com.sun.management.snmp.SnmpDefinitions; +import com.sun.management.snmp.SnmpInt; +import com.sun.management.snmp.SnmpOid; +import com.sun.management.snmp.SnmpOidTableSupport; +import com.sun.management.snmp.SnmpVarBind; +import com.sun.management.snmp.SnmpVarBindList; +import com.sun.management.snmp.manager.SnmpParameters; +import com.sun.management.snmp.manager.SnmpPeer; +import com.sun.management.snmp.manager.SnmpRequest; +import com.sun.management.snmp.manager.SnmpSession; + +public class OSDMonitoringTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment testEnv; + + private DIRConfig dirConfig; + + private MRCConfig mrcConfig; + + private OSDConfig osdConfig; + + private SnmpPeer dirAgent, mrcAgent, osdAgent; + + private SnmpSession session; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.RPC_CLIENT, TestEnvironment.Services.MRC, TestEnvironment.Services.OSD }); + testEnv.start(); + + final SnmpOidTableSupport oidTable = new XTREEMFS_MIBOidTable(); + SnmpOid.setSnmpOidTable(oidTable); + + dirConfig = SetupUtils.createDIRConfig(); + mrcConfig = SetupUtils.createMRC1Config(); + osdConfig = SetupUtils.createMultipleOSDConfigs(1)[0]; + + dirAgent = new SnmpPeer(dirConfig.getSnmpAddress().getHostName(), dirConfig.getSnmpPort()); + mrcAgent = new SnmpPeer(mrcConfig.getSnmpAddress().getHostName(), mrcConfig.getSnmpPort()); + osdAgent = new SnmpPeer(osdConfig.getSnmpAddress().getHostName(), osdConfig.getSnmpPort()); + + // Create and set Parameters, i.e. the community strings for read-only and read-write. + // Since the config don't provide an ACL file it doens't matter what community strings are + // used here + final SnmpParameters params = new SnmpParameters("public", "private"); + + dirAgent.setParams(params); + mrcAgent.setParams(params); + osdAgent.setParams(params); + + session = new SnmpSession("UnitTest Session"); + + } + + @After + public void tearDown() throws Exception { + + session.destroySession(); + + testEnv.shutdown(); + } + + /** + * Make an SNMP get + * + * @param agent + * The {@link SnmpPeer} from which the OID should be read. + * @param varDesc + * The textual representation of the OID. + * + * @return + */ + private SnmpVarBindList makeSnmpGet(SnmpPeer agent, String varDesc) throws Exception { + final SnmpVarBindList list = new SnmpVarBindList("UnitTest varbind list"); + + // We want to read the "sysDescr" variable. + list.addVarBind(varDesc); + + // Make the SNMP get request and wait for the result. + SnmpRequest request = session.snmpGetRequest(agent, null, list); + final boolean completed = request.waitForCompletion(10000); + + // Check for a timeout of the request. + assertTrue(completed); + + // Check if the response contains an error. + int errorStatus = request.getErrorStatus(); + assertEquals(SnmpDefinitions.snmpRspNoError, errorStatus); + + // Now we can extract the content of the result. + return request.getResponseVarBindList(); + + } + + @Test + public void testNumOpenFiles() throws Exception { + + // there should be no open files because nothing is written/read on the OSD + SnmpVarBindList result = makeSnmpGet(osdAgent, "numOpenFiles.0"); + SnmpVarBind varBind = result.getVarBindAt(0); + SnmpInt snmpInt = varBind.getSnmpIntValue(); + + assertEquals(0, snmpInt.intValue()); + + Client c = new Client(new InetSocketAddress[] { testEnv.getDIRAddress() }, 10000, 60000, null); + c.start(); + UserCredentials uc = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + c.createVolume("foobar", RPCAuthentication.authNone, uc, SetupUtils.getStripingPolicy(64, 1), + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, 0777); + + Volume v = c.getVolume("foobar", uc); + + File f = v.getFile("/foo"); + + f.createFile(); + RandomAccessFile raf = f.open("rw", 0777); + + byte[] data = new byte[2048]; + raf.write(data, 0, data.length); + + result = makeSnmpGet(osdAgent, "numOpenFiles.0"); + varBind = result.getVarBindAt(0); + snmpInt = varBind.getSnmpIntValue(); + + assertEquals(1, snmpInt.intValue()); + + raf.close(); + f.delete(); + c.deleteVolume("foobar", RPCAuthentication.authNone, uc); + + } +} diff --git a/java/servers/test/org/xtreemfs/test/common/striping/LocationsCacheTest.java b/java/servers/test/org/xtreemfs/test/common/striping/LocationsCacheTest.java new file mode 100644 index 0000000..3d29e26 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/common/striping/LocationsCacheTest.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Eugenio Cesario, + * Zuse Institute Berlin, Consiglio Nazionale delle Ricerche + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.common.striping; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.osd.LocationsCache; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.test.TestHelper; + +/** + * This class implements the tests for LocationsCache + * + * @author jmalo + */ +public class LocationsCacheTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private LocationsCache cache; + + private final int maximumSize = 3; + + @Before + public void setUp() throws Exception { + cache = new LocationsCache(maximumSize); + } + + @After + public void tearDown() throws Exception { + cache = null; + } + + /** + * It tests the update method + */ + @Test + public void testUpdate() throws Exception { + + XLocSet xlocSet = XLocSet.newBuilder().setReadOnlyFileSize(0).setReplicaUpdatePolicy("").setVersion(1).build(); + XLocations loc = new XLocations(xlocSet, null); + + for (int i = 0; i < 3 * maximumSize; i++) { + cache.update("F" + i, loc); + } + + for (int i = 0; i < 2 * maximumSize; i++) { + assertNull(cache.getLocations("F" + i)); + assertEquals(0, cache.getVersion("F" + i)); + } + + for (int i = 2 * maximumSize; i < 3 * maximumSize; i++) { + assertNotNull(cache.getLocations("F" + i)); + assertEquals(loc.getVersion(), cache.getVersion("F" + i)); + } + } + + /** + * It tests the getVersion method + */ + @Test + public void testGetVersion() throws Exception { + + XLocSet xlocSet0 = XLocSet.newBuilder().setReadOnlyFileSize(0).setReplicaUpdatePolicy("").setVersion(1).build(); + XLocSet xlocSet1 = XLocSet.newBuilder().setReadOnlyFileSize(0).setReplicaUpdatePolicy("").setVersion(2).build(); + + XLocations loc0 = new XLocations(xlocSet0, null); + XLocations loc1 = new XLocations(xlocSet1, null); + String fileId = "F0"; + + // It asks the version number of an inexistent entry + assertEquals(0, cache.getVersion(fileId)); + + // It asks the version number of a new added entry + cache.update(fileId, loc0); + assertEquals(loc0.getVersion(), cache.getVersion(fileId)); + + // It asks the version number of an updated entry + cache.update(fileId, loc1); + assertEquals(loc1.getVersion(), cache.getVersion(fileId)); + } + + /** + * It tests the getLocations method + */ + @Test + public void testGetLocations() throws Exception { + + XLocSet xlocSet = XLocSet.newBuilder().setReadOnlyFileSize(0).setReplicaUpdatePolicy("").setVersion(1).build(); + XLocations loc = new XLocations(xlocSet, null); + + // It fills the cache + for (int i = 0; i < maximumSize; i++) { + cache.update("F" + i, loc); + } + + // Checks the whole cache + for (int i = 0; i < maximumSize; i++) { + XLocations loc2 = cache.getLocations("F" + i); + + assertNotNull(loc2); + assertEquals(loc, loc2); + } + + // Removes an entry and adds a new one + { + cache.update("F" + maximumSize, loc); + + XLocations loc2 = cache.getLocations("F" + 0); + assertNull(loc2); + + for (int i = 1; i <= maximumSize; i++) { + loc2 = cache.getLocations("F" + i); + + assertNotNull(loc2); + assertEquals(loc, loc2); + } + } + } +} diff --git a/java/servers/test/org/xtreemfs/test/common/striping/LocationsTest.java b/java/servers/test/org/xtreemfs/test/common/striping/LocationsTest.java new file mode 100644 index 0000000..b3573f6 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/common/striping/LocationsTest.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Eugenio Cesario, + * Zuse Institute Berlin, Consiglio Nazionale delle Ricerche + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.common.striping; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestHelper; + +/** + * This class implements the tests for Locations + * + * @author jmalo + */ +public class LocationsTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + static List osds = new ArrayList(); + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL); + + osds.add(new ServiceUUID("http://127.0.0.1:65535")); + osds.add(new ServiceUUID("http://192.168.0.1:65535")); + osds.add(new ServiceUUID("http://172.16.0.1:65535")); + osds.add(new ServiceUUID("http://10.0.0.1:65535")); + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testLocalReplica() throws Exception { + + List osdList = new ArrayList(); + for (ServiceUUID osd : osds) { + osdList.add(osd.toString()); + } + + List rep2List = new ArrayList(); + rep2List.add(osds.get(3).toString()); + + Replica r1 = Replica.newBuilder().setReplicationFlags(0) + .setStripingPolicy(SetupUtils.getStripingPolicy(4, 128)).addAllOsdUuids(osdList).build(); + Replica r2 = Replica.newBuilder().setReplicationFlags(0) + .setStripingPolicy(SetupUtils.getStripingPolicy(4, 128)).addAllOsdUuids(rep2List).build(); + XLocSet xlocset = XLocSet.newBuilder().setReadOnlyFileSize(0).setVersion(1).addReplicas(r1).addReplicas(r2) + .setReplicaUpdatePolicy("").build();// XLocSet(0, rset, "", 1); + XLocations loc = new XLocations(xlocset, osds.get(1)); + + // System.out.println(loc.getLocalReplica().toString()); + // System.out.println(loc.getReplica(0).toString()); + assertEquals(loc.getLocalReplica(), loc.getReplica(0)); + assertNotNull(loc.getLocalReplica().getStripingPolicy()); + + } + + @Test + public void testCorrectSetOfReplicationFlags() { + List osdList = new ArrayList(); + for (ServiceUUID osd : osds) { + osdList.add(osd.toString()); + } + StripingPolicy stripingPolicy = SetupUtils.getStripingPolicy(4, 128); + org.xtreemfs.common.xloc.Replica r; + int flags = 0; + + // set none + Replica interfR = Replica.newBuilder().setStripingPolicy(stripingPolicy).setReplicationFlags(flags) + .addAllOsdUuids(osdList).build(); + r = new org.xtreemfs.common.xloc.Replica(interfR, null); + assertFalse(r.isComplete()); + assertTrue(r.isPartialReplica()); + assertFalse(ReplicationFlags.isRandomStrategy(r.getTransferStrategyFlags())); + assertFalse(ReplicationFlags.isSequentialStrategy(r.getTransferStrategyFlags())); + + // set complete + flags = ReplicationFlags.setReplicaIsComplete(0); + interfR = Replica.newBuilder().setStripingPolicy(stripingPolicy).setReplicationFlags(flags) + .addAllOsdUuids(osdList).build(); + r = new org.xtreemfs.common.xloc.Replica(interfR, null); + assertTrue(r.isComplete()); + assertTrue(r.isPartialReplica()); + assertFalse(ReplicationFlags.isRandomStrategy(r.getTransferStrategyFlags())); + assertFalse(ReplicationFlags.isSequentialStrategy(r.getTransferStrategyFlags())); + + // set partial replica and RandomStrategy + flags = ReplicationFlags.setPartialReplica(ReplicationFlags.setSequentialPrefetchingStrategy(0)); + interfR = Replica.newBuilder().setStripingPolicy(stripingPolicy).setReplicationFlags(flags) + .addAllOsdUuids(osdList).build(); + r = new org.xtreemfs.common.xloc.Replica(interfR, null); + assertFalse(r.isComplete()); + assertTrue(r.isPartialReplica()); + assertFalse(ReplicationFlags.isRandomStrategy(r.getTransferStrategyFlags())); + assertTrue(ReplicationFlags.isSequentialPrefetchingStrategy(r.getTransferStrategyFlags())); + + // set full replica and RandomStrategy + flags = ReplicationFlags.setRandomStrategy(ReplicationFlags.setFullReplica(0)); + interfR = Replica.newBuilder().setStripingPolicy(stripingPolicy).setReplicationFlags(flags) + .addAllOsdUuids(osdList).build(); + r = new org.xtreemfs.common.xloc.Replica(interfR, null); + assertFalse(r.isComplete()); + assertFalse(r.isPartialReplica()); + assertTrue(ReplicationFlags.isRandomStrategy(r.getTransferStrategyFlags())); + assertFalse(ReplicationFlags.isSequentialStrategy(r.getTransferStrategyFlags())); + + // set full replica and RandomStrategy + flags = ReplicationFlags.setFullReplica(ReplicationFlags.setRandomStrategy(0)); + assertTrue(ReplicationFlags.isFullReplica(flags)); + assertTrue(ReplicationFlags.isRandomStrategy(flags)); + flags = ReplicationFlags.setSequentialStrategy(flags); + assertTrue(ReplicationFlags.isSequentialStrategy(flags)); + assertTrue(ReplicationFlags.isFullReplica(flags)); + + // test correct set of strategies + // random + flags = ReplicationFlags.setRandomStrategy(0); + assertTrue(ReplicationFlags.isRandomStrategy(flags)); + assertFalse(ReplicationFlags.isSequentialStrategy(flags)); + assertFalse(ReplicationFlags.isSequentialPrefetchingStrategy(flags)); + assertFalse(ReplicationFlags.isRarestFirstStrategy(flags)); + // sequential + flags = ReplicationFlags.setSequentialStrategy(0); + assertFalse(ReplicationFlags.isRandomStrategy(flags)); + assertTrue(ReplicationFlags.isSequentialStrategy(flags)); + assertFalse(ReplicationFlags.isSequentialPrefetchingStrategy(flags)); + assertFalse(ReplicationFlags.isRarestFirstStrategy(flags)); + // sequential prefetching + flags = ReplicationFlags.setSequentialPrefetchingStrategy(0); + assertFalse(ReplicationFlags.isRandomStrategy(flags)); + assertFalse(ReplicationFlags.isSequentialStrategy(flags)); + assertTrue(ReplicationFlags.isSequentialPrefetchingStrategy(flags)); + assertFalse(ReplicationFlags.isRarestFirstStrategy(flags)); + // rarest first + flags = ReplicationFlags.setRarestFirstStrategy(0); + assertFalse(ReplicationFlags.isRandomStrategy(flags)); + assertFalse(ReplicationFlags.isSequentialStrategy(flags)); + assertFalse(ReplicationFlags.isSequentialPrefetchingStrategy(flags)); + assertTrue(ReplicationFlags.isRarestFirstStrategy(flags)); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/common/striping/RAID0Test.java b/java/servers/test/org/xtreemfs/test/common/striping/RAID0Test.java new file mode 100644 index 0000000..4d33ad5 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/common/striping/RAID0Test.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Christian Lorenz, Eugenio Cesario, + * Zuse Institute Berlin, Consiglio Nazionale delle Ricerche + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.common.striping; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Iterator; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestHelper; + +/** + * It tests the RAID0 class + * + * @author clorenz + */ +public class RAID0Test { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static final long KILOBYTE = 1024L; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL); + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetObjectsAndBytes() throws Exception { + + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(3, 128)).setReplicationFlags(0) + .build(); + + StripingPolicyImpl policy = StripingPolicyImpl.getPolicy(r, 0); + + long objectID, offset; + + objectID = policy.getObjectNoForOffset(20); + assertEquals(0, objectID); + + objectID = policy.getObjectNoForOffset(20 * KILOBYTE); + assertEquals(0, objectID); + + objectID = policy.getObjectNoForOffset(255 * KILOBYTE); + assertEquals(1, objectID); + + objectID = policy.getObjectNoForOffset(256 * KILOBYTE); + assertEquals(2, objectID); + + offset = policy.getObjectStartOffset(5); + assertEquals(640 * KILOBYTE, offset); + + offset = policy.getObjectEndOffset(5); + assertEquals(768 * KILOBYTE - 1, offset); + + offset = policy.getObjectStartOffset(6); + assertEquals(768 * KILOBYTE, offset); + } + + @Test + public void testGetOSDs() throws Exception { + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(8, 128)).setReplicationFlags(0) + .build(); + StripingPolicyImpl policy = StripingPolicyImpl.getPolicy(r, 0); + + int osd0 = policy.getOSDforObject(0); + assertEquals(0, osd0); + + int osd1 = policy.getOSDforObject(1); + assertEquals(1, osd1); + + int osd7 = policy.getOSDforObject(7); + assertEquals(7, osd7); + + int osd8 = policy.getOSDforObject(8); + assertEquals(0, osd8); + + int osd21 = policy.getOSDforObject(2125648682); + assertEquals(2, osd21); + + int osd0b = policy.getOSDforOffset(20); + assertEquals(osd0, osd0b); + + int osd0c = policy.getOSDforOffset(20 * KILOBYTE); + assertEquals(0, osd0c); + + int osd7b = policy.getOSDforOffset(7 * 128 * KILOBYTE); + assertEquals(osd7, osd7b); + + int osd8b = policy.getOSDforOffset(8 * 128 * KILOBYTE); + assertEquals(osd8, osd8b); + + int osd21b = policy.getOSDforOffset(2125648682 * 128 * KILOBYTE); + assertEquals(osd21, osd21b); + } + + @Test + public void testGetStripeSize() throws Exception { + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(3, 256)).setReplicationFlags(0) + .build(); + StripingPolicyImpl policy = StripingPolicyImpl.getPolicy(r, 0); + assertEquals(256 * KILOBYTE, policy.getStripeSizeForObject(5)); + } + + @Test + public void testCalculateLastObject() throws Exception { + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(3, 256)).setReplicationFlags(0) + .build(); + StripingPolicyImpl policy = StripingPolicyImpl.getPolicy(r, 0); + assertEquals(41, policy.getObjectNoForOffset(256L * KILOBYTE * 42 - 1)); // filesize + // = + // offset + // + + // 1 + assertEquals(42, policy.getObjectNoForOffset(256L * KILOBYTE * 42 + 32000 - 1)); + assertEquals(42, policy.getObjectNoForOffset(256L * KILOBYTE * 43 - 1 - 1)); + } + + @Test + public void testGetObjectsOfOSDiterator() throws Exception { + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(3, 128)).setReplicationFlags(0) + .build(); + StripingPolicyImpl policy = StripingPolicyImpl.getPolicy(r, 0); + + long startObject = 0, endObject = 12; + Iterator objectsIt = policy.getObjectsOfOSD(0, startObject, endObject); + long objectNo = startObject; + while (objectsIt.hasNext()) { + assertEquals(objectNo, objectsIt.next().longValue()); + assertTrue(objectNo <= endObject); + objectNo += policy.getWidth(); + } + + startObject = 2; + endObject = 25; + objectsIt = policy.getObjectsOfOSD(2, startObject, endObject); + objectNo = startObject; + while (objectsIt.hasNext()) { + assertEquals(objectNo, objectsIt.next().longValue()); + assertTrue(objectNo <= endObject); + objectNo += policy.getWidth(); + } + + startObject = 0; + endObject = 5; + objectsIt = policy.getObjectsOfOSD(0, startObject, endObject); + objectNo = startObject; + while (objectsIt.hasNext()) { + assertEquals(objectNo, objectsIt.next().longValue()); + assertTrue(objectNo <= endObject); + objectNo += policy.getWidth(); + } + + startObject = 2; + endObject = 4; + objectsIt = policy.getObjectsOfOSD(1, startObject, endObject); + objectNo = 1; + while (objectsIt.hasNext()) { + assertEquals(objectNo, objectsIt.next().longValue()); + assertTrue(objectNo <= endObject); + objectNo += policy.getWidth(); + } + + startObject = 2; + endObject = 1; + objectsIt = policy.getObjectsOfOSD(2, startObject, endObject); + objectNo = startObject; + assertFalse(objectsIt.hasNext()); + + startObject = 32215; + endObject = 32435; + objectsIt = policy.getObjectsOfOSD(0, startObject, endObject); + objectNo = 32214; + while (objectsIt.hasNext()) { + assertEquals(objectNo, objectsIt.next().longValue()); + assertTrue(objectNo <= endObject); + objectNo += policy.getWidth(); + } + } +} diff --git a/java/servers/test/org/xtreemfs/test/common/uuid/UUIDResolverTest.java b/java/servers/test/org/xtreemfs/test/common/uuid/UUIDResolverTest.java new file mode 100644 index 0000000..ddabdf1 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/common/uuid/UUIDResolverTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2008-2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.test.common.uuid; + +import static org.junit.Assert.fail; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.util.NetUtils; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.common.uuids.UnknownUUIDException; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class UUIDResolverTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment testEnv; + + @Before + public void setUp() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.UUID_RESOLVER }); + testEnv.start(); + UUIDResolver.addLocalMapping("localhost", 32636, Schemes.SCHEME_PBRPC); + + } + + @After + public void tearDown() throws Exception { + testEnv.shutdown(); + } + + @Test + public void testSimpleMapping() throws Exception { + List mpgs = NetUtils.getReachableEndpoints(32636, "http"); + // Use the first endoint found for testing purposes. + AddressMapping testMapping = mpgs.get(0).setUuid("MY_TEST_UUID").build(); + + AddressMappingSet.Builder ams = AddressMappingSet.newBuilder(); + ams.addMappings(testMapping); + + RPCResponse r = testEnv.getDirClient().xtreemfs_address_mappings_set(null, + RPCAuthentication.authNone, RPCAuthentication.userService, ams.build()); + r.get(); + ServiceUUID uuid = new ServiceUUID("MY_TEST_UUID"); + uuid.resolve(); + // System.out.println(uuid); + // System.out.println(uuid); + + try { + ServiceUUID uuid2 = new ServiceUUID("YAGGA YAGGA"); + uuid2.getMappings(); + fail("returned result for unknown address mapping"); + } catch (UnknownUUIDException ex) { + // supi + } + + Thread.sleep(200); + + uuid = new ServiceUUID("MY_TEST_UUID"); + uuid.resolve(); + // System.out.println(uuid); + + uuid = new ServiceUUID("localhost"); + uuid.resolve(); + // System.out.println(uuid); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/dir/DIRClientTest.java b/java/servers/test/org/xtreemfs/test/dir/DIRClientTest.java new file mode 100644 index 0000000..e06394d --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/dir/DIRClientTest.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2011 by Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.dir; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.net.InetSocketAddress; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.server.RPCNIOSocketServer; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequestListener; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingGetResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceConstants; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class DIRClientTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + TestEnvironment testEnv; + + RPCNIOSocketServer dummy1, dummy2; + + DummyDir dir1, dir2; + + InetSocketAddress[] servers; + + static final int PORT_DIR1 = 32638 + SetupUtils.PORT_RANGE_OFFSET; + static final int PORT_DIR2 = 32639 + SetupUtils.PORT_RANGE_OFFSET; + + protected class DummyDir implements RPCServerRequestListener { + public volatile boolean resetAfterCall = false; + public volatile String sendRedirectTo = null; + public volatile boolean sendException = false; + public volatile boolean donotAnswer = false; + final int id; + + public DummyDir(int id) { + this.id = id; + } + + @Override + public void receiveRecord(RPCServerRequest rq) { + try { + final RPCHeader hdr = rq.getHeader(); + assertTrue(hdr.hasRequestHeader()); + assertEquals(DIRServiceConstants.PROC_ID_XTREEMFS_ADDRESS_MAPPINGS_GET, hdr.getRequestHeader() + .getProcId()); + + if (sendRedirectTo != null) { + rq.sendRedirect(sendRedirectTo); + } else if (sendException) { + rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EIO, "exception requested for test"); + } else if (donotAnswer) { + // don't do anything + rq.freeBuffers(); + } else { + + addressMappingGetResponse response = addressMappingGetResponse.getDefaultInstance(); + try { + rq.sendResponse(response, null); + } catch (Exception ex) { + fail(ex.toString()); + } + } + if (resetAfterCall) { + sendRedirectTo = null; + sendException = false; + donotAnswer = false; + } + } catch (Exception ex) { + ex.printStackTrace(); + fail(ex.toString()); + } + } + } + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_CLIENT, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.RPC_CLIENT }); + testEnv.start(); + + dir1 = new DummyDir(1); + dir2 = new DummyDir(2); + + dummy1 = new RPCNIOSocketServer(PORT_DIR1, null, dir1, null); + dummy1.start(); + dummy1.waitForStartup(); + + dummy2 = new RPCNIOSocketServer(PORT_DIR2, null, dir2, null); + dummy2.start(); + dummy2.waitForStartup(); + + servers = new InetSocketAddress[] { new InetSocketAddress("localhost", PORT_DIR1), + new InetSocketAddress("localhost", PORT_DIR2) }; + } + + @After + public void tearDown() throws Exception { + try { + dummy1.shutdown(); + dummy1.waitForShutdown(); + } catch (Exception ex) { + ex.printStackTrace(); + } + try { + dummy2.shutdown(); + dummy2.waitForShutdown(); + } catch (Exception ex) { + ex.printStackTrace(); + } + testEnv.shutdown(); + + } + + @Test + public void testStandardCase() throws Exception { + DIRClient client = new DIRClient(testEnv.getDirClient(), servers, 10, 2); + AddressMappingSet result = client.xtreemfs_address_mappings_get(null, RPCAuthentication.authNone, + RPCAuthentication.userService, "*"); + assertEquals(0, result.getMappingsCount()); + } + + @Test + public void testRedirect() throws Exception { + dir1.sendRedirectTo = "localhost:" + PORT_DIR2; + + DIRClient client = new DIRClient(testEnv.getDirClient(), servers, 10, 2); + AddressMappingSet result = client.xtreemfs_address_mappings_get(null, RPCAuthentication.authNone, + RPCAuthentication.userService, "*"); + assertEquals(0, result.getMappingsCount()); + } + + @Test + public void testRedirect2() throws Exception { + dir1.sendRedirectTo = "localhost:" + PORT_DIR2; + dir2.sendRedirectTo = "localhost:" + PORT_DIR1; + + try { + DIRClient client = new DIRClient(testEnv.getDirClient(), servers, 10, 2); + client.xtreemfs_address_mappings_get(null, RPCAuthentication.authNone, RPCAuthentication.userService, "*"); + fail("Expected exception."); + } catch (IOException ex) { + + } + } + + @Test + public void testFailover() throws Exception { + dir1.donotAnswer = true; + + DIRClient client = new DIRClient(testEnv.getDirClient(), servers, 10, 2); + AddressMappingSet result = client.xtreemfs_address_mappings_get(null, RPCAuthentication.authNone, + RPCAuthentication.userService, "*"); + assertEquals(0, result.getMappingsCount()); + } + + @Test + public void testFailover2() throws Exception { + dir1.donotAnswer = true; + dir1.resetAfterCall = true; + dir2.donotAnswer = true; + + DIRClient client = new DIRClient(testEnv.getDirClient(), servers, 10, 2); + AddressMappingSet result = client.xtreemfs_address_mappings_get(null, RPCAuthentication.authNone, + RPCAuthentication.userService, "*"); + assertEquals(0, result.getMappingsCount()); + } + + @Test + public void testNoAnswer() throws Exception { + dir1.donotAnswer = true; + dir2.donotAnswer = true; + + try { + DIRClient client = new DIRClient(testEnv.getDirClient(), servers, 5, 2); + client.xtreemfs_address_mappings_get(null, RPCAuthentication.authNone, RPCAuthentication.userService, "*"); + fail("Expected exception."); + } catch (IOException ex) { + + } + } + + @Test + public void testException() throws Exception { + dir1.donotAnswer = true; + dir2.sendException = true; + + try { + DIRClient client = new DIRClient(testEnv.getDirClient(), servers, 10, 2); + client.xtreemfs_address_mappings_get(null, RPCAuthentication.authNone, RPCAuthentication.userService, "*"); + fail("Expected exception."); + } catch (PBRPCException ex) { + + } + } + +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/test/dir/DIRTest.java b/java/servers/test/org/xtreemfs/test/dir/DIRTest.java new file mode 100644 index 0000000..fb5b707 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/dir/DIRTest.java @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.dir; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.Set; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.ClientFactory; +import org.xtreemfs.common.libxtreemfs.Options; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.Schemes; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMapping; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.AddressMappingSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Configuration; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.addressMappingSetResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.configurationSetResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.globalTimeSGetResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.serviceRegisterResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.DIRServiceClient; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class DIRTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + TestEnvironment testEnv; + + public DIRTest() throws IOException { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.RPC_CLIENT, TestEnvironment.Services.OSD_CLIENT, + TestEnvironment.Services.UUID_RESOLVER }); + + testEnv.start(); + } + + @After + public void tearDown() throws Exception { + testEnv.shutdown(); + } + + @Test + public void testGlobalTime() throws Exception { + + RPCResponse r = testEnv.getDirClient().xtreemfs_global_time_s_get(null, + RPCAuthentication.authNone, RPCAuthentication.userService); + long response = r.get().getTimeInSeconds(); + r.freeBuffers(); + } + + @Test + public void testAddressMapping() throws Exception { + + DIRServiceClient client = testEnv.getDirClient(); + + AddressMappingSet.Builder setB = AddressMappingSet.newBuilder(); + AddressMapping mapping = AddressMapping.newBuilder().setUuid("uuid1") + .setProtocol(Schemes.SCHEME_PBRPC).setAddress("localhost").setPort(12345) + .setMatchNetwork("*").setTtlS(3600).setVersion(0) + .setUri(Schemes.SCHEME_PBRPC + "://localhost:12345").build(); + setB.addMappings(mapping); + AddressMappingSet set = setB.build(); + + RPCResponse r1 = client.xtreemfs_address_mappings_set(null, + RPCAuthentication.authNone, RPCAuthentication.userService, set); + r1.get(); + r1.freeBuffers(); + + r1 = client.xtreemfs_address_mappings_set(null, RPCAuthentication.authNone, + RPCAuthentication.userService, set); + try { + r1.get(); + fail(); + } catch (PBRPCException ex) { + assertEquals(ex.getPOSIXErrno(), POSIXErrno.POSIX_ERROR_EAGAIN); + // expected exception because of version mismatch + } + r1.freeBuffers(); + + RPCResponse r2 = client.xtreemfs_address_mappings_get(null, + RPCAuthentication.authNone, RPCAuthentication.userService, "uuid1"); + AddressMappingSet response = r2.get(); + assertEquals(response.getMappingsCount(), 1); + assertEquals(response.getMappings(0).getUuid(), "uuid1"); + assertEquals(response.getMappings(0).getProtocol(), Schemes.SCHEME_PBRPC); + assertEquals(response.getMappings(0).getAddress(), "localhost"); + assertEquals(response.getMappings(0).getVersion(), 1); + r2.freeBuffers(); + + RPCResponse r3 = client.xtreemfs_address_mappings_remove(null, RPCAuthentication.authNone, + RPCAuthentication.userService, "uuid1"); + r3.get(); + r3.freeBuffers(); + + } + + @Test + public void testRegistry() throws Exception { + + DIRServiceClient client = testEnv.getDirClient(); + + ServiceDataMap dmap = ServiceDataMap.newBuilder() + .addData(KeyValuePair.newBuilder().setKey("bla").setValue("yagga")).build(); + Service sr = Service.newBuilder().setData(dmap).setType(ServiceType.SERVICE_TYPE_MRC) + .setUuid("uuid1").setName("mrc @ farnsworth").setLastUpdatedS(0).setVersion(0).build(); + + RPCResponse r1 = client.xtreemfs_service_register(null, + RPCAuthentication.authNone, RPCAuthentication.userService, sr); + r1.get(); + r1.freeBuffers(); + + r1 = client.xtreemfs_service_register(null, RPCAuthentication.authNone, + RPCAuthentication.userService, sr); + try { + r1.get(); + fail(); + } catch (PBRPCException ex) { + // assertEquals(POSIXErrno.POSIX_ERROR_EAGAIN, ex.getPOSIXErrno()); + // expected exception because of version mismatch + } + r1.freeBuffers(); + + RPCResponse r2 = client.xtreemfs_service_get_by_uuid(null, RPCAuthentication.authNone, + RPCAuthentication.userService, "uuid1"); + ServiceSet response = r2.get(); + r2.freeBuffers(); + + RPCResponse r3 = client.xtreemfs_service_deregister(null, RPCAuthentication.authNone, + RPCAuthentication.userService, "uuid1"); + r3.get(); + r3.freeBuffers(); + + // add OSD + OSDConfig osdConfig = SetupUtils.createOSD1Config(); + OSD osd = new OSD(osdConfig); + + // change status of osd + InetSocketAddress dirAddress = SetupUtils.getDIRAddr(); + AdminClient adminClient = ClientFactory.createAdminClient( + dirAddress.getHostName() + ":" + dirAddress.getPort(), RPCAuthentication.userService, null, + new Options()); + adminClient.start(); + + adminClient.setOSDServiceStatus(osdConfig.getUUID().toString(), ServiceStatus.SERVICE_STATUS_REMOVED); + + // restart OSD + osd.shutdown(); + osd = new OSD(osdConfig); + + // check status of OSD from DIR + Set removedOsd = adminClient.getRemovedOsds(); + + assertTrue(removedOsd.contains(osdConfig.getUUID().toString())); + + osd.shutdown(); + } + + @Test + public void testConfiguration() throws Exception { + + DIRServiceClient client = testEnv.getDirClient(); + + long version = 0; + String uuid = "uuidConfTest"; + int parameterNumber = 5; + + Configuration.Builder confBuilder = Configuration.newBuilder(); + confBuilder.setVersion(version).setUuid(uuid); + for (int i = 0; i < parameterNumber; i++) { + confBuilder.addParameter(KeyValuePair.newBuilder().setKey("key" + i).setValue("value" + i) + .build()); + } + + RPCResponse responseSet = null; + responseSet = client.xtreemfs_configuration_set(null, RPCAuthentication.authNone, + RPCAuthentication.userService, confBuilder.build()); + + responseSet.get(); + responseSet.freeBuffers(); + + confBuilder = Configuration.newBuilder(); + confBuilder.setVersion(version).setUuid(uuid); + for (int i = 0; i < parameterNumber; i++) { + confBuilder.addParameter(KeyValuePair.newBuilder().setKey("key" + i).setValue("value" + i) + .build()); + } + + responseSet = client.xtreemfs_configuration_set(null, RPCAuthentication.authNone, + RPCAuthentication.userService, confBuilder.build()); + + try { + responseSet.get(); + fail(); + } catch (PBRPCException ex) { + assertEquals(ex.getPOSIXErrno(), POSIXErrno.POSIX_ERROR_EAGAIN); + // expected exception because of version mismatch + } finally { + responseSet.freeBuffers(); + } + + RPCResponse resonseGet = null; + resonseGet = client.xtreemfs_configuration_get(null, RPCAuthentication.authNone, + RPCAuthentication.userService, uuid); + + Configuration newConf = resonseGet.get(); + + assertEquals(version + 1, newConf.getVersion()); + assertEquals(uuid, newConf.getUuid()); + + // System.out.println(newConf.getAllFields().toString()); + + for (int i = 0; i < parameterNumber; i++) { + assertEquals(new String("key" + i), newConf.getParameter(i).getKey()); + assertEquals("value" + i, newConf.getParameter(i).getValue()); + } + + resonseGet.freeBuffers(); + + } + + @Test + public void testManyUpdates() throws Exception { + + DIRServiceClient client = testEnv.getDirClient(); + + ServiceDataMap dmap = ServiceDataMap.newBuilder() + .addData(KeyValuePair.newBuilder().setKey("bla").setValue("yagga")).build(); + Service sr = Service.newBuilder().setData(dmap).setType(ServiceType.SERVICE_TYPE_MRC) + .setUuid("uuid22").setName("mrc @ farnsworth").setLastUpdatedS(0).setVersion(0).build(); + + for (int i = 0; i < 100; i++) { + RPCResponse r1 = client.xtreemfs_service_register(null, + RPCAuthentication.authNone, RPCAuthentication.userService, sr); + r1.get(); + r1.freeBuffers(); + + r1 = client.xtreemfs_service_register(null, RPCAuthentication.authNone, + RPCAuthentication.userService, sr); + try { + r1.get(); + fail(); + } catch (PBRPCException ex) { + assertEquals(ex.getPOSIXErrno(), POSIXErrno.POSIX_ERROR_EAGAIN); + // expected exception because of version mismatch + } + r1.freeBuffers(); + + RPCResponse r2 = client.xtreemfs_service_get_by_uuid(null, + RPCAuthentication.authNone, RPCAuthentication.userService, "uuid22"); + ServiceSet response = r2.get(); + r2.freeBuffers(); + + RPCResponse r3 = client.xtreemfs_service_deregister(null, RPCAuthentication.authNone, + RPCAuthentication.userService, "uuid22"); + r3.get(); + r3.freeBuffers(); + // sr = sr.toBuilder().setVersion(i+1).build(); + } + Thread.sleep(1000 * 5); + + } + +} diff --git a/java/servers/test/org/xtreemfs/test/mrc/BabuDBStorageManagerTest.java b/java/servers/test/org/xtreemfs/test/mrc/BabuDBStorageManagerTest.java new file mode 100644 index 0000000..d3d752b --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/mrc/BabuDBStorageManagerTest.java @@ -0,0 +1,548 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.mrc; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.babudb.BabuDBFactory; +import org.xtreemfs.babudb.api.BabuDB; +import org.xtreemfs.babudb.config.BabuDBConfig; +import org.xtreemfs.babudb.log.DiskLogger.SyncMode; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.mrc.database.AtomicDBUpdate; +import org.xtreemfs.mrc.database.DBAccessResultListener; +import org.xtreemfs.mrc.database.DatabaseResultSet; +import org.xtreemfs.mrc.database.babudb.BabuDBStorageManager; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +public class BabuDBStorageManagerTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + public static final String DB_DIRECTORY = "/tmp/xtreemfs-test"; + + private BabuDBStorageManager mngr; + + private BabuDB database; + + private Exception exc; + + private Object lock = ""; + + private boolean cont; + + private TestEnvironment testEnv; + + private DBAccessResultListener listener = new DBAccessResultListener() { + + @Override + public void finished(Object o, Object context) { + synchronized (lock) { + cont = true; + lock.notify(); + } + } + + @Override + public void failed(Throwable error, Object context) { + exc = (Exception) error; + synchronized (lock) { + lock.notify(); + } + } + }; + + public BabuDBStorageManagerTest() { + Logging.start(SetupUtils.DEBUG_LEVEL); + } + + @Before + public void setUp() throws Exception { + // initialize Directory Service (for synchronized clocks...) + DIRConfig config = SetupUtils.createDIRConfig(); + BabuDBConfig dbsConfig = SetupUtils.createDIRdbsConfig(); + + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.UUID_RESOLVER }); + testEnv.start(); + + // reset database + File dbDir = new File(DB_DIRECTORY); + FSUtils.delTree(dbDir); + dbDir.mkdirs(); + database = BabuDBFactory.createBabuDB(new BabuDBConfig(DB_DIRECTORY, DB_DIRECTORY, 2, + 1024 * 1024 * 16, 5 * 60, SyncMode.FDATASYNC, 300, 1000, false, 16, 1024 * 1024 * 512)); + mngr = new BabuDBStorageManager(database, "volId", "volume", (short) 1, new short[] { 1 }, + new short[0], "me", + "myGrp", 511, null, null, false, 0, null); + + exc = null; + } + + @After + public void tearDown() throws Exception { + database.shutdown(); + + testEnv.shutdown(); + } + + @Test + public void testCreateDelete() throws Exception { + + // retrieve root directory + FileMetadata rootDir = mngr.getMetadata(0, "volume"); + assertTrue(rootDir.isDirectory()); + assertTrue(rootDir.getAtime() > 0); + assertTrue(rootDir.getCtime() > 0); + assertTrue(rootDir.getMtime() > 0); + assertEquals(1, rootDir.getId()); + + // create nested file + final long fileId1 = mngr.getNextFileId(); + final String fileName = "testfile.txt"; + final String userId = "me"; + final String groupId = "myGrp"; + final short perms = 511; + final long w32Attrs = 43287473; + + AtomicDBUpdate update = mngr.createAtomicDBUpdate(listener, null); + FileMetadata nextDir = mngr.createFile(fileId1, rootDir.getId(), fileName, 1, 1, 1, userId, groupId, + perms, w32Attrs, 12, true, 5, 6, update); + mngr.setLastFileId(fileId1, update); + update.execute(); + waitForResponse(); + + FileMetadata metadata = mngr.getMetadata(rootDir.getId(), fileName); + assertFalse(metadata.isDirectory()); + assertTrue(metadata.getAtime() > 0); + assertTrue(metadata.getCtime() > 0); + assertTrue(metadata.getMtime() > 0); + assertTrue(metadata.isReadOnly()); + assertEquals(5, metadata.getEpoch()); + assertEquals(6, metadata.getIssuedEpoch()); + assertEquals(nextDir.getId(), metadata.getId()); + assertEquals(12, metadata.getSize()); + assertEquals(1, metadata.getLinkCount()); + assertEquals(perms, metadata.getPerms()); + assertEquals(w32Attrs, metadata.getW32Attrs()); + assertEquals(fileName, metadata.getFileName()); + assertEquals(userId, metadata.getOwnerId()); + assertEquals(groupId, metadata.getOwningGroupId()); + + // create nested dir + final long fileId2 = mngr.getNextFileId(); + final String dirName = "someDir"; + + update = mngr.createAtomicDBUpdate(listener, null); + FileMetadata dir = mngr.createDir(fileId2, rootDir.getId(), dirName, 1, 1, 1, userId, groupId, perms, + w32Attrs, update); + mngr.setLastFileId(fileId2, update); + update.execute(); + waitForResponse(); + + metadata = mngr.getMetadata(rootDir.getId(), dirName); + assertTrue(metadata.isDirectory()); + assertTrue(metadata.getAtime() > 0); + assertTrue(metadata.getCtime() > 0); + assertTrue(metadata.getMtime() > 0); + assertEquals(dir.getId(), metadata.getId()); + assertEquals(perms, metadata.getPerms()); + assertEquals(dirName, metadata.getFileName()); + assertEquals(userId, metadata.getOwnerId()); + assertEquals(groupId, metadata.getOwningGroupId()); + + // list files; both the nested directory and file should be in 'rootDir' + DatabaseResultSet children = mngr.getChildren(rootDir.getId(), 0, Integer.MAX_VALUE); + List tmp = new LinkedList(); + while (children.hasNext()) + tmp.add(children.next().getFileName()); + children.destroy(); + + assertEquals(2, tmp.size()); + assertTrue(tmp.contains(dirName)); + assertTrue(tmp.contains(fileName)); + + // delete file + update = mngr.createAtomicDBUpdate(listener, null); + mngr.delete(rootDir.getId(), fileName, update); + update.execute(); + waitForResponse(); + + // list files; only the nested directory should be in 'rootDir' + children = mngr.getChildren(rootDir.getId(), 0, Integer.MAX_VALUE); + tmp = new LinkedList(); + while (children.hasNext()) + tmp.add(children.next().getFileName()); + + assertEquals(1, tmp.size()); + assertEquals(dirName, tmp.get(0)); + + long fileId3 = mngr.getNextFileId(); + + // create file again + update = mngr.createAtomicDBUpdate(listener, null); + mngr.createFile(fileId3, rootDir.getId(), fileName, 0, 0, 0, userId, groupId, perms, w32Attrs, 11, + true, 3, 4, update); + mngr.setLastFileId(fileId3, update); + update.execute(); + waitForResponse(); + + // list files; both the nested directory and file should be in 'rootDir' + // again + children = mngr.getChildren(rootDir.getId(), 0, Integer.MAX_VALUE); + tmp = new LinkedList(); + while (children.hasNext()) + tmp.add(children.next().getFileName()); + + assertEquals(2, tmp.size()); + assertTrue(tmp.contains(dirName)); + assertTrue(tmp.contains(fileName)); + } + + @Test + public void testCreateDeleteWithCollidingHashCodes() throws Exception { + + // create two files w/ colliding hash codes in nested dir + final long dirId = 2; + final String name1 = "Cfat"; + final String name2 = "CgCU"; + final String uid1 = "uid1"; + final String uid2 = "uid2"; + final String gid1 = "gid1"; + final String gid2 = "gid2"; + final short perms1 = 0; + final short perms2 = Short.MAX_VALUE; + + AtomicDBUpdate update = mngr.createAtomicDBUpdate(listener, null); + mngr.createDir(3, dirId, name1, 0, 0, 0, uid1, gid1, perms1, 23, update); + update.execute(); + waitForResponse(); + + update = mngr.createAtomicDBUpdate(listener, null); + mngr.createDir(4, dirId, name2, 0, 0, 0, uid2, gid2, perms2, 55, update); + update.execute(); + waitForResponse(); + + // list files; both the nested files are found and contain the correct + // data + DatabaseResultSet children = mngr.getChildren(dirId, 0, Integer.MAX_VALUE); + Map map = new HashMap(); + while (children.hasNext()) { + FileMetadata child = children.next(); + map.put(child.getFileName(), child); + } + children.destroy(); + + assertEquals(2, map.size()); + assertEquals(uid1, map.get(name1).getOwnerId()); + assertEquals(uid2, map.get(name2).getOwnerId()); + assertEquals(gid1, map.get(name1).getOwningGroupId()); + assertEquals(gid2, map.get(name2).getOwningGroupId()); + assertEquals(perms1, map.get(name1).getPerms()); + assertEquals(perms2, map.get(name2).getPerms()); + + // delete first file + update = mngr.createAtomicDBUpdate(listener, null); + mngr.delete(dirId, name1, update); + update.execute(); + waitForResponse(); + + // list files; ensure that only file 2 remains + children = mngr.getChildren(dirId, 0, Integer.MAX_VALUE); + assertTrue(children.hasNext()); + assertEquals(name2, children.next().getFileName()); + assertFalse(children.hasNext()); + } + + @Test + public void testPathResolution() throws Exception { + + final String userId = "me"; + final String groupId = "myGroup"; + final short perms = 511; + final long w32Attrs = Long.MIN_VALUE; + exc = null; + + // create a small directory tree and test path resolution + long nextId = 0; + + AtomicDBUpdate update = mngr.createAtomicDBUpdate(listener, null); + long comp1Id = nextId = mngr.createDir(1, 0, "comp1", 0, 0, 0, userId, groupId, perms, w32Attrs, + update).getId(); + update.execute(); + waitForResponse(); + update = mngr.createAtomicDBUpdate(listener, null); + nextId = mngr.createDir(2, nextId, "comp2", 0, 0, 0, userId, groupId, perms, w32Attrs, update) + .getId(); + update.execute(); + waitForResponse(); + update = mngr.createAtomicDBUpdate(listener, null); + nextId = mngr.createDir(3, nextId, "comp3", 0, 0, 0, userId, groupId, perms, w32Attrs, update) + .getId(); + update.execute(); + waitForResponse(); + update = mngr.createAtomicDBUpdate(listener, null); + nextId = mngr.createFile(4, nextId, "file.txt", 0, 0, 0, "usr", "grp", perms, w32Attrs, 4711, false, + 3, 4, update).getId(); + update.execute(); + waitForResponse(); + + long id = mngr.resolvePath(new Path("comp1"))[0].getId(); + assertEquals(comp1Id, id); + + id = mngr.resolvePath(new Path("comp1/comp2/comp3/file.txt"))[3].getId(); + assertEquals(nextId, id); + + // test path resolution conrner cases + id = mngr.resolvePath(new Path("comp1/"))[0].getId(); + assertEquals(comp1Id, id); + + id = mngr.resolvePath(new Path("comp1/comp2/"))[0].getId(); + assertEquals(comp1Id, id); + + // list files in root dir; there should only be one + DatabaseResultSet children = mngr.getChildren(1, 0, Integer.MAX_VALUE); + List tmp = new LinkedList(); + while (children.hasNext()) + tmp.add(children.next().getFileName()); + children.destroy(); + + assertEquals(1, tmp.size()); + assertTrue(tmp.contains("comp2")); + } + + @Test + public void testPartialReaddir() throws Exception { + + final String userId = "me"; + final String groupId = "myGroup"; + final short perms = 511; + final long w32Attrs = Long.MIN_VALUE; + exc = null; + + AtomicDBUpdate update = mngr.createAtomicDBUpdate(listener, null); + mngr.createDir(1, 0, "root", 0, 0, 0, userId, groupId, perms, w32Attrs, update).getId(); + update.execute(); + waitForResponse(); + + // create 10 nested directories + for (int i = 0; i < 10; i++) { + + update = mngr.createAtomicDBUpdate(listener, null); + mngr.createDir(i + 2, 1, "entry" + i, 0, 0, 0, userId, groupId, perms, w32Attrs, update).getId(); + update.execute(); + waitForResponse(); + } + + // list different subsets of files in root dir + + DatabaseResultSet children = mngr.getChildren(1, 0, 3); + List tmp = new LinkedList(); + while (children.hasNext()) + tmp.add(children.next().getFileName()); + children.destroy(); + + assertEquals(3, tmp.size()); + for (int i = 0; i < 3; i++) + assertTrue(tmp.contains("entry" + i)); + + children = mngr.getChildren(1, 3, 3); + tmp = new LinkedList(); + while (children.hasNext()) + tmp.add(children.next().getFileName()); + + assertEquals(3, tmp.size()); + for (int i = 3; i < 6; i++) + assertTrue(tmp.contains("entry" + i)); + + children = mngr.getChildren(1, 6, 1); + tmp = new LinkedList(); + while (children.hasNext()) + tmp.add(children.next().getFileName()); + + assertEquals(1, tmp.size()); + for (int i = 6; i < 7; i++) + assertTrue(tmp.contains("entry" + i)); + + children = mngr.getChildren(1, 8, 10); + tmp = new LinkedList(); + while (children.hasNext()) + tmp.add(children.next().getFileName()); + + assertEquals(2, tmp.size()); + for (int i = 8; i < 10; i++) + assertTrue(tmp.contains("entry" + i)); + + children = mngr.getChildren(1, 0, 10); + tmp = new LinkedList(); + while (children.hasNext()) + tmp.add(children.next().getFileName()); + + assertEquals(10, tmp.size()); + for (int i = 0; i < 10; i++) + assertTrue(tmp.contains("entry" + i)); + + } + + private void waitForResponse() throws Exception { + + synchronized (lock) { + if (!cont) + lock.wait(); + } + + cont = false; + + if (exc != null) + throw exc; + } + + // + // public void testSymlink() throws Exception { + // + // final String userId = "me"; + // final String groupId = "myGroup"; + // final Map stripingPolicy = getDefaultStripingPolicy(); + // + // long fileId = mngr.createFile("blub/bla.txt", userId, groupId, + // stripingPolicy, false, null); + // mngr.linkFile("test.txt", fileId, 1); + // assertEquals(mngr.getFileReference(fileId), "blub/bla.txt"); + // } + // + // public void testAttributes() throws Exception { + // + // final String userId = "me"; + // final String groupId = "myGroup"; + // final Map stripingPolicy = getDefaultStripingPolicy(); + // + // Map attrs = new HashMap(); + // attrs.put("myKey", "myValue"); + // attrs.put("blaKey", "blaValue"); + // + // long fileId = mngr.createFile(null, userId, groupId, stripingPolicy, + // false, null); + // mngr.linkFile("test.txt", fileId, 1); + // mngr.addXAttributes(fileId, attrs); + // + // attrs = mngr.getXAttributes(fileId); + // assertEquals(attrs.size(), 2); + // + // List list = new ArrayList(); + // list.add("myKey"); + // mngr.deleteXAttributes(fileId, list); + // assertEquals(mngr.getXAttributes(fileId).size(), 1); + // assertEquals(mngr.getXAttributes(fileId).get("blaKey"), "blaValue"); + // assertNull(mngr.getXAttributes(fileId).get("myKey")); + // + // mngr.addXAttributes(fileId, attrs); + // assertEquals(mngr.getXAttributes(fileId).size(), 2); + // mngr.deleteXAttributes(fileId, null); + // assertEquals(mngr.getXAttributes(fileId).size(), 0); + // } + // + // public void testPosixAttributes() throws Exception { + // + // final String userId = "me"; + // final String groupId = "myGroup"; + // final Map stripingPolicy = getDefaultStripingPolicy(); + // + // long fileId = mngr.createFile(null, userId, groupId, stripingPolicy, + // false, null); + // mngr.linkFile("test.txt", fileId, 1); + // + // mngr.setFileSize(fileId, 121, 0, 0); + // assertEquals(mngr.getFileEntity("test.txt").getId(), fileId); + // assertEquals(((FileEntity) mngr.getFileEntity("test.txt")).getSize(), + // 121); + // } + // + // public void testACLs() throws Exception { + // + // final String userId = "me"; + // final String groupId = "myGroup"; + // final Map stripingPolicy = getDefaultStripingPolicy(); + // + // Map acl = new HashMap(); + // acl.put("1", 3L); + // acl.put("2", 7L); + // acl.put("3", 1L); + // + // long fileId = mngr.createFile(null, userId, groupId, stripingPolicy, + // false, acl); + // mngr.linkFile("test.txt", fileId, 1); + // + // ACLEntry[] aclArray = mngr.getFileEntity(fileId).getAcl(); + // assertEquals(aclArray.length, 3); + // for (ACLEntry entry : aclArray) + // assertTrue((entry.getEntity().equals("1") && entry.getRights() == 3) + // || (entry.getEntity().equals("2") && entry.getRights() == 7) + // || (entry.getEntity().equals("3") && entry.getRights() == 1)); + // + // acl.clear(); + // acl.put("4", 4L); + // mngr.setFileACL(fileId, acl); + // aclArray = mngr.getFileEntity(fileId).getAcl(); + // assertEquals(aclArray.length, 1); + // assertEquals(aclArray[0].getEntity(), "4"); + // assertEquals(aclArray[0].getRights(), 4L); + // } + // + // // public void testMisc() throws Exception { + // // + // // long fileId = mngr.createFile(null, "me", "myGroup", + // // getDefaultStripingPolicy(), false, null); + // // mngr.linkFile("newFile", fileId, 1); + // // AbstractFileEntity file = mngr.getFileEntity(fileId); + // // + // // AbstractFileEntity copy = Converter + // // .mapToFile((Map) Converter.fileTreeToList(mngr, + // // file).get(0)); + // // + // // assertEquals(file.getAtime(), copy.getAtime()); + // // assertEquals(file.getCtime(), copy.getCtime()); + // // assertEquals(file.getMtime(), copy.getMtime()); + // // assertEquals(file.getAcl(), copy.getAcl()); + // // assertEquals(file.getUserId(), copy.getUserId()); + // // assertEquals(file.getGroupId(), copy.getGroupId()); + // // assertEquals(((FileEntity) file).getSize(), ((FileEntity) copy) + // // .getSize()); + // // assertEquals(((FileEntity) file).getXLocationsList(), + // // ((FileEntity) copy).getXLocationsList()); + // // } + + + private static Map getDefaultStripingPolicy() { + Map map = new HashMap(); + map.put("policy", "RAID0"); + map.put("stripe-size", 1000L); + map.put("width", 1L); + return map; + } +} diff --git a/java/servers/test/org/xtreemfs/test/mrc/BufferBackedMetadataTest.java b/java/servers/test/org/xtreemfs/test/mrc/BufferBackedMetadataTest.java new file mode 100644 index 0000000..314fad5 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/mrc/BufferBackedMetadataTest.java @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.mrc; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.mrc.metadata.BufferBackedACLEntry; +import org.xtreemfs.mrc.metadata.BufferBackedFileMetadata; +import org.xtreemfs.mrc.metadata.BufferBackedStripingPolicy; +import org.xtreemfs.mrc.metadata.BufferBackedXAttr; +import org.xtreemfs.mrc.metadata.BufferBackedXLoc; +import org.xtreemfs.mrc.metadata.BufferBackedXLocList; +import org.xtreemfs.mrc.metadata.FileMetadata; +import org.xtreemfs.mrc.metadata.StripingPolicy; +import org.xtreemfs.mrc.metadata.XLoc; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestHelper; + +public class BufferBackedMetadataTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL); + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testBufferBackedACLEntry() throws Exception { + + { + final long fileId = 3322; + final String entity = "test"; + final short rights = 509; + + // create ACL entry + BufferBackedACLEntry acl1 = new BufferBackedACLEntry(fileId, entity, rights); + checkACLEntry(entity, rights, acl1); + + // copy ACL entry + BufferBackedACLEntry acl2 = new BufferBackedACLEntry(acl1.getKeyBuf(), acl1.getValBuf()); + checkACLEntry(entity, rights, acl2); + } + + { + final long fileId = 0; + final String entity = ""; + final short rights = Short.MAX_VALUE; + + // create ACL entry + BufferBackedACLEntry acl1 = new BufferBackedACLEntry(fileId, entity, rights); + checkACLEntry(entity, rights, acl1); + + // copy ACL entry + BufferBackedACLEntry acl2 = new BufferBackedACLEntry(acl1.getKeyBuf(), acl1.getValBuf()); + checkACLEntry(entity, rights, acl2); + } + } + + @Test + public void testBufferBackedStripingPolicy() throws Exception { + + { + final String pattern = "RAID0"; + final int stripeSize = 256; + final int width = 5; + + // create striping policy + BufferBackedStripingPolicy sp1 = new BufferBackedStripingPolicy(pattern, stripeSize, width); + checkSP(pattern, stripeSize, width, sp1); + + // copy striping policy + BufferBackedStripingPolicy sp2 = new BufferBackedStripingPolicy(sp1.getBuffer()); + checkSP(pattern, stripeSize, width, sp2); + } + + { + final String pattern = "RAID0"; + final int stripeSize = 16; + final int width = 1; + + // create striping policy + BufferBackedStripingPolicy sp1 = new BufferBackedStripingPolicy(pattern, stripeSize, width); + checkSP(pattern, stripeSize, width, sp1); + + // copy striping policy + BufferBackedStripingPolicy sp2 = new BufferBackedStripingPolicy(sp1.getBuffer()); + checkSP(pattern, stripeSize, width, sp2); + } + } + + @Test + public void testBufferBackedXAttrs() throws Exception { + + { + final long fileId = 4389; + final String key = "someAttr"; + final byte[] val = "fadsjkkj".getBytes(); + final String uid = "myUID"; + + // create XAttrs + BufferBackedXAttr xattr1 = new BufferBackedXAttr(fileId, uid, key, val, (short) 0); + checkXAttr(key, val, uid, xattr1); + + // copy XAttrs + BufferBackedXAttr xattr2 = new BufferBackedXAttr(xattr1.getKeyBuf(), xattr1.getValBuf()); + checkXAttr(key, val, uid, xattr2); + } + + { + final long fileId = 32; + final String key = "fasd"; + final byte[] val = "".getBytes(); + final String uid = "gffg"; + + // create XAttrs + BufferBackedXAttr xattr1 = new BufferBackedXAttr(fileId, uid, key, val, (short) 0); + checkXAttr(key, val, uid, xattr1); + + // copy XAttrs + BufferBackedXAttr xattr2 = new BufferBackedXAttr(xattr1.getKeyBuf(), xattr1.getValBuf()); + checkXAttr(key, val, uid, xattr2); + } + + { + final long fileId = 11; + final String key = ""; + final byte[] val = "".getBytes(); + final String uid = ""; + + // create XAttrs + BufferBackedXAttr xattr1 = new BufferBackedXAttr(fileId, uid, key, val, (short) 0); + checkXAttr(key, val, uid, xattr1); + + // copy XAttrs + BufferBackedXAttr xattr2 = new BufferBackedXAttr(xattr1.getKeyBuf(), xattr1.getValBuf()); + checkXAttr(key, val, uid, xattr2); + } + + } + + @Test + public void testBufferBackedXLoc() throws Exception { + + { + final String[] osds = { "someOSD", "anotherOSD", "myOSD" }; + final BufferBackedStripingPolicy sp = new BufferBackedStripingPolicy("RAID0", 1024, 4); + final int replFlags = 237; + + // create XLoc + BufferBackedXLoc xloc1 = new BufferBackedXLoc(sp, osds, replFlags); + checkXLoc(osds, sp, replFlags, xloc1); + + byte[] tmpBuf = new byte[xloc1.getBuffer().length + 10]; + System.arraycopy(xloc1.getBuffer(), 0, tmpBuf, 3, xloc1.getBuffer().length); + + // copy XLoc + BufferBackedXLoc xloc2 = new BufferBackedXLoc(tmpBuf, 3, xloc1.getBuffer().length); + checkXLoc(osds, sp, replFlags, xloc2); + + final int newReplFlags = Integer.MIN_VALUE; + xloc2.setReplicationFlags(newReplFlags); + assertEquals(Integer.MIN_VALUE, xloc2.getReplicationFlags()); + } + + } + + @Test + public void testBufferBackedXLocList() throws Exception { + + { + final List sp = generateSPList(new BufferBackedStripingPolicy("RAID0", 5, 1), + new BufferBackedStripingPolicy("RAID5", 99, 33), new BufferBackedStripingPolicy("asfd", 34, -1)); + + final List replicas = generateXLocList(new BufferBackedXLoc(sp.get(0), new String[] { + "11111", "22222", "33333" }, 43), new BufferBackedXLoc(sp.get(1), + new String[] { "fdsay", "34", "4" }, 99), new BufferBackedXLoc(sp.get(2), new String[] { "354", + ",mn", "asdf" }, 45)); + int version = 37; + String updatePolicy = "bla"; + + // create XLocList + BufferBackedXLocList xlocList1 = new BufferBackedXLocList(toArray(replicas), updatePolicy, version); + checkXLocList(replicas, version, updatePolicy, xlocList1); + + // copy XLocList + BufferBackedXLocList xlocList2 = new BufferBackedXLocList(xlocList1.getBuffer(), 0, + xlocList1.getBuffer().length); + checkXLocList(replicas, version, updatePolicy, xlocList2); + + // test iterator + Iterator it = xlocList2.iterator(); + while (it.hasNext()) + it.next(); + } + + } + + @Test + public void testBufferBackedDirObject() throws Exception { + + { + long parentId = 99999; + String dirName = "bla"; + long fileId = 434873; + int atime = 999; + int ctime = 888; + int mtime = 777; + short perms = 255; + long w32Attrs = 12; + String owner = "someone"; + String group = "somegroup"; + + // create dir object + BufferBackedFileMetadata dirObj = new BufferBackedFileMetadata(parentId, dirName, owner, group, fileId, + atime, ctime, mtime, perms, w32Attrs, (short) 1); + checkDirObject(owner, group, fileId, atime, ctime, mtime, perms, w32Attrs, dirObj); + + fileId = 77; + atime = 111; + ctime = 111; + mtime = 111; + perms = 277; + w32Attrs = 3232; + + dirObj.setAtime(atime); + dirObj.setCtime(ctime); + dirObj.setMtime(mtime); + dirObj.setId(fileId); + dirObj.setPerms(perms); + dirObj.setW32Attrs(w32Attrs); + checkDirObject(owner, group, fileId, atime, ctime, mtime, perms, w32Attrs, dirObj); + } + + } + + @Test + public void testBufferBackedFileObject() throws Exception { + + { + long parentId = 4343; + String fileName = "asfd"; + long fileId = 122111; + int atime = 43; + int ctime = Integer.MAX_VALUE; + int mtime = 0; + long size = 3298438; + short perms = 322; + long w32Attrs = Integer.MAX_VALUE; + short linkcount = 3; + int epoch = 4; + int issuedEpoch = 5; + boolean readonly = false; + String owner = "vyxcvcxy"; + String group = "afdsafdsafds"; + // create file object + BufferBackedFileMetadata fileObj = new BufferBackedFileMetadata(parentId, fileName, owner, group, fileId, + atime, ctime, mtime, size, perms, w32Attrs, linkcount, epoch, issuedEpoch, readonly); + checkFileObject(owner, group, fileId, atime, ctime, mtime, perms, w32Attrs, size, linkcount, epoch, + issuedEpoch, readonly, fileObj); + } + + } + + private void checkACLEntry(String entity, short rights, BufferBackedACLEntry entry) { + assertEquals(entity, entry.getEntity()); + assertEquals(rights, entry.getRights()); + } + + private void checkSP(String pattern, int stripeSize, int width, BufferBackedStripingPolicy sp) { + assertEquals(pattern, sp.getPattern().toString()); + assertEquals(width, sp.getWidth()); + assertEquals(stripeSize, sp.getStripeSize()); + } + + private void checkXAttr(String key, byte[] val, String owner, BufferBackedXAttr xattr) { + + assertEquals(key, xattr.getKey()); + + assertEquals(val.length, xattr.getValue().length); + for (int i = 0; i < val.length; i++) + assertEquals(val[i], xattr.getValue()[i]); + + assertEquals(owner, xattr.getOwner()); + } + + private void checkXLoc(String[] osds, StripingPolicy sp, int flags, BufferBackedXLoc xloc) { + + final StripingPolicy xlocSP = xloc.getStripingPolicy(); + + assertEquals(sp.toString(), xlocSP.toString()); + assertEquals(sp.getPattern(), xlocSP.getPattern()); + assertEquals(sp.getWidth(), xlocSP.getWidth()); + assertEquals(sp.getStripeSize(), xlocSP.getStripeSize()); + + assertEquals(osds.length, xloc.getOSDCount()); + for (int i = 0; i < osds.length; i++) + assertEquals(osds[i], xloc.getOSD(i).toString()); + + assertEquals(flags, xloc.getReplicationFlags()); + } + + private void checkXLocList(List replicas, int version, String updatePolicy, + BufferBackedXLocList xlocList) { + + assertEquals(version, xlocList.getVersion()); + assertEquals(updatePolicy, xlocList.getReplUpdatePolicy()); + assertEquals(replicas.size(), xlocList.getReplicaCount()); + + for (int i = 0; i < replicas.size(); i++) + assertEquals(replicas.get(i).toString(), xlocList.getReplica(i).toString()); + } + + private void checkDirObject(String owner, String group, long fileId, int atime, int ctime, int mtime, short perms, + long w32Attrs, FileMetadata obj) { + + assertEquals(fileId, obj.getId()); + assertEquals(atime, obj.getAtime()); + assertEquals(ctime, obj.getCtime()); + assertEquals(mtime, obj.getMtime()); + assertEquals(perms, obj.getPerms()); + assertEquals(w32Attrs, obj.getW32Attrs()); + assertEquals(owner, obj.getOwnerId().toString()); + assertEquals(group, obj.getOwningGroupId().toString()); + + } + + private void checkFileObject(String owner, String group, long fileId, int atime, int ctime, int mtime, short perms, + long w32Attrs, long size, short linkcount, int epoch, int issuedEpoch, boolean readonly, FileMetadata obj) { + + assertEquals(fileId, obj.getId()); + assertEquals(atime, obj.getAtime()); + assertEquals(ctime, obj.getCtime()); + assertEquals(mtime, obj.getMtime()); + assertEquals(perms, obj.getPerms()); + assertEquals(w32Attrs, obj.getW32Attrs()); + assertEquals(size, obj.getSize()); + assertEquals(linkcount, obj.getLinkCount()); + assertEquals(epoch, obj.getEpoch()); + assertEquals(issuedEpoch, obj.getIssuedEpoch()); + assertEquals(readonly, obj.isReadOnly()); + assertEquals(owner, obj.getOwnerId().toString()); + assertEquals(group, obj.getOwningGroupId().toString()); + } + + public List generateXLocList(BufferBackedXLoc... arr) { + List list = new ArrayList(arr.length); + for (BufferBackedXLoc x : arr) + list.add(x); + + return list; + } + + public List generateSPList(BufferBackedStripingPolicy... arr) { + List list = new ArrayList(arr.length); + for (BufferBackedStripingPolicy s : arr) + list.add(s); + + return list; + } + + private BufferBackedXLoc[] toArray(List list) { + return list.toArray(new BufferBackedXLoc[list.size()]); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/mrc/MRCTest.java b/java/servers/test/org/xtreemfs/test/mrc/MRCTest.java new file mode 100644 index 0000000..a6ba722 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/mrc/MRCTest.java @@ -0,0 +1,1472 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.mrc; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.mrc.metadata.ReplicationPolicy; +import org.xtreemfs.mrc.utils.Converter; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.ACCESS_FLAGS; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Setattrs; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Volumes; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_update_file_sizeRequest; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestEnvironment.Services; +import org.xtreemfs.test.TestHelper; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; + +/** + * XtreemFS MRC test + * + * @author stender + */ +public class MRCTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private MRCServiceClient client; + + private InetSocketAddress mrcAddress; + + private TestEnvironment testEnv; + + public MRCTest() { + Logging.start(SetupUtils.DEBUG_LEVEL); + } + + @Before + public void setUp() throws Exception { + mrcAddress = SetupUtils.getMRC1Addr(); + + // register an OSD at the directory service (needed in order to assign + // it to a new file on 'open') + + testEnv = new TestEnvironment(Services.DIR_CLIENT, Services.TIME_SYNC, Services.UUID_RESOLVER, + Services.MRC_CLIENT, Services.DIR_SERVICE, Services.MRC, Services.MOCKUP_OSD, + Services.MOCKUP_OSD2, Services.MOCKUP_OSD3); + testEnv.start(); + + client = testEnv.getMrcClient(); + } + + @After + public void tearDown() throws Exception { + testEnv.shutdown(); + Logging.logMessage(Logging.LEVEL_DEBUG, this, BufferPool.getStatus()); + } + + @Test + public void testReCreateVolumes() throws Exception { + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final UserCredentials uc = createUserCredentials(uid, gids); + + // Using a large number of volumes to generate load while creation + for (int i = 25; i <= 30; i++) { + // Create volumes + for (int j = 0; j < i; j++) { + String name = "vol-" + j; + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, getDefaultStripingPolicy(), "", 0775, + name, "", "", getKVList("i", String.valueOf(i)), 0)); + } + + // Check number of created volumes + Volumes vols = invokeSync(client.xtreemfs_lsvol(mrcAddress, RPCAuthentication.authNone, uc)); + assertEquals(vols.getVolumesCount(), i); + + // Try to create existing volumes + for (int j = 0; j < i; j++) { + String name = "vol-" + j; + try { + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, getDefaultStripingPolicy(), "", 0775, + name, "", "", getKVList("i", String.valueOf(i)), 0)); + fail(); + } catch (Exception ex) { + vols = invokeSync(client.xtreemfs_lsvol(mrcAddress, RPCAuthentication.authNone, uc)); + assertEquals(vols.getVolumesCount(), i); + } + } + + // Delete created volumes + for (int j = 0; j < i; j++) { + String volName = "vol-" + j; + invokeSync(client.xtreemfs_rmvol(mrcAddress, RPCAuthentication.authNone, uc, volName)); + } + vols = invokeSync(client.xtreemfs_lsvol(mrcAddress, RPCAuthentication.authNone, uc)); + assertEquals(vols.getVolumesCount(), 0); + } + } + + @Test + public void testCreateDeleteListVolumes() throws Exception { + + final int numVols = 10; + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final UserCredentials uc = createUserCredentials(uid, gids); + + Set volNames = new HashSet(); + + // create multiple volumes + for (int i = 0; i < numVols; i++) { + + String name = "vol-" + i; + + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, getDefaultStripingPolicy(), "", 0775, + name, "", "", getKVList("bla", "blub"), 0)); + + volNames.add(name); + } + + for (int i = numVols - 1; i >= 0; i--) { + String name = "vol-" + i; + Stat stat1 = invokeSync(client.getattr(mrcAddress, RPCAuthentication.authNone, uc, name, "", -1)) + .getStbuf(); + assertNotNull(stat1); + } + + // list all volumes + Set tmp = new HashSet(volNames); + Volumes vols = invokeSync(client.xtreemfs_lsvol(mrcAddress, RPCAuthentication.authNone, uc)); + for (int i = 0; i < vols.getVolumesCount(); i++) { + String volName = vols.getVolumes(i).getName(); + assertTrue(tmp.remove(volName)); + } + assertEquals(0, tmp.size()); + + // delete all even-numbered volumes + for (int i = 0; i < numVols; i += 2) { + String volName = "vol-" + i; + invokeSync(client.xtreemfs_rmvol(mrcAddress, RPCAuthentication.authNone, uc, volName)); + volNames.remove(volName); + } + + // list all volumes + vols = invokeSync(client.xtreemfs_lsvol(mrcAddress, RPCAuthentication.authNone, uc)); + for (int i = 0; i < vols.getVolumesCount(); i++) { + String volName = vols.getVolumes(i).getName(); + assertTrue(volNames.remove(volName)); + } + + } + + @Test + public void testCreateDelete() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + + // create and delete a volume + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, getDefaultStripingPolicy(), "", 0775, + volumeName, "", "", getKVList("bla", "blub"), 0)); + + Volumes localVols = invokeSync(client.xtreemfs_lsvol(mrcAddress, RPCAuthentication.authNone, uc)); + assertEquals(1, localVols.getVolumesCount()); + assertEquals(volumeName, localVols.getVolumes(0).getName()); + assertEquals(1, localVols.getVolumes(0).getAttrsList().size()); + assertEquals("bla", localVols.getVolumes(0).getAttrsList().get(0).getKey()); + assertEquals("blub", localVols.getVolumes(0).getAttrsList().get(0).getValue()); + invokeSync(client.xtreemfs_rmvol(mrcAddress, RPCAuthentication.authNone, uc, volumeName)); + localVols = invokeSync(client.xtreemfs_lsvol(mrcAddress, RPCAuthentication.authNone, uc)); + assertEquals(0, localVols.getVolumesCount()); + + // create a volume + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, getDefaultStripingPolicy(), "", 0775, + volumeName, "", "", getKVList(), 0)); + + // create some files and directories + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "myDir", 0775)); + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "anotherDir", 0775)); + + for (int i = 0; i < 10; i++) + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "myDir/test" + i + + ".txt", FileAccessManager.O_CREAT, 0775, 0, getDefaultCoordinates())); + + // try to create a file w/o a name + try { + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "", + FileAccessManager.O_CREAT, 0775, 0, getDefaultCoordinates())); + fail("missing filename"); + } catch (PBRPCException exc) { + } + + try { + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "myDir/test0.txt", + FileAccessManager.O_CREAT | FileAccessManager.O_EXCL, 0775, 0, getDefaultCoordinates())); + fail("duplicate file creation"); + } catch (PBRPCException exc) { + } + + try { + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, + "myDir/test0.txt/bla.txt", FileAccessManager.O_CREAT, 0775, 0, getDefaultCoordinates())); + fail("file in file creation"); + } catch (PBRPCException exc) { + } + + try { + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "", 0)); + fail("directory already exists"); + } catch (PBRPCException exc) { + + } + + // test 'readDir' and 'stat' + + DirectoryEntries entrySet = invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc, + volumeName, "", -1, 1000, false, 0)); + assertEquals(4, entrySet.getEntriesCount()); + + entrySet = invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "myDir", + -1, 1000, false, 0)); + assertEquals(12, entrySet.getEntriesCount()); + + Stat stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "myDir/test2.txt", -1)) + .getStbuf(); + assertEquals(uid, stat.getUserId()); + assertTrue("test2.txt is a not a file", (stat.getMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFREG + .getNumber()) != 0); + assertEquals(0, stat.getSize()); + assertTrue(stat.getAtimeNs() > 0); + assertTrue(stat.getCtimeNs() > 0); + assertTrue(stat.getMtimeNs() > 0); + assertTrue((stat.getMode() & 511) > 0); + assertEquals(1, stat.getNlink()); + + // test 'delete' + + invokeSync(client.unlink(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "myDir/test3.txt")); + + entrySet = invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "myDir", + -1, 1000, false, 0)); + assertEquals(11, entrySet.getEntriesCount()); + + invokeSync(client.rmdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "anotherDir")); + } + + @Test + public void testReaddir() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, getDefaultStripingPolicy(), "", 0, + volumeName, "", "", getKVList(), 0)); + invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "/", -1, 1000, + false, 0)); + } + + @Test + public void testXAttrs() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, getDefaultStripingPolicy(), "", 0, + volumeName, "", "", getKVList(), 0)); + + // create a file and add some user attributes + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + "key1", "quark", ByteString.copyFrom("quark".getBytes()), 0)); + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + "key2", "quatsch", ByteString.copyFrom("quatsch".getBytes()), 0)); + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + "myAttr", "171", ByteString.copyFrom("171".getBytes()), 0)); + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + "key1", "blub", ByteString.copyFrom("blub".getBytes()), 0)); + + List xattrs = invokeSync( + client.listxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", false)) + .getXattrsList(); + List attrKeys = new LinkedList(); + for (XAttr attr : xattrs) + if (!attr.getName().startsWith("xtreemfs.")) + attrKeys.add(attr.getName()); + assertEquals(3, attrKeys.size()); + String val = invokeSync( + client.getxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", "key1")) + .getValue(); + assertEquals("blub", val); + val = invokeSync( + client.getxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", "key2")) + .getValue(); + assertEquals("quatsch", val); + val = invokeSync( + client.getxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", "myAttr")) + .getValue(); + assertEquals("171", val); + + // check if / works + val = invokeSync( + client.getxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "/", "xtreemfs.url")) + .getValue(); + + // create a new file, add some attrs and delete some attrs + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", + "key1", "quark", ByteString.copyFrom("quark".getBytes()), 0)); + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", + "key2", "quatsch", ByteString.copyFrom("quatsch".getBytes()), 0)); + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", + "key3", "171", ByteString.copyFrom("171".getBytes()), 0)); + + invokeSync(client.removexattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", + "key1")); + xattrs = invokeSync( + client.listxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", false)) + .getXattrsList(); + attrKeys = new LinkedList(); + for (XAttr attr : xattrs) + if (!attr.getName().startsWith("xtreemfs.")) + attrKeys.add(attr.getName()); + assertEquals(2, attrKeys.size()); + try { + val = invokeSync( + client.getxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", "key1")) + .getValue(); + fail("got value for non-existing key"); + } catch (PBRPCException exc) { + assertEquals(POSIXErrno.POSIX_ERROR_ENODATA, exc.getPOSIXErrno()); + } + + invokeSync(client.removexattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", + "key3")); + xattrs = invokeSync( + client.listxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", false)) + .getXattrsList(); + attrKeys = new LinkedList(); + for (XAttr attr : xattrs) + if (!attr.getName().startsWith("xtreemfs.")) + attrKeys.add(attr.getName()); + assertEquals(1, attrKeys.size()); + try { + val = invokeSync( + client.getxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", "key3")) + .getValue(); + fail("got value for non-existing key"); + } catch (PBRPCException exc) { + assertEquals(POSIXErrno.POSIX_ERROR_ENODATA, exc.getPOSIXErrno()); + } + + // retrieve a system attribute + val = invokeSync( + client.getxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + "xtreemfs.object_type")).getValue(); + assertEquals("1", val); + + // check read-only replication + XLocSet xLoc = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "repl", + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())).getCreds().getXlocs(); + assertEquals(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE, xLoc.getReplicaUpdatePolicy()); + + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "repl", + "xtreemfs.read_only", "true", ByteString.copyFrom("true".getBytes()), 0)); + val = invokeSync( + client.getxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "repl", + "xtreemfs.read_only")).getValue(); + assertEquals("true", val); + xLoc = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "repl", + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())).getCreds().getXlocs(); + assertEquals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY, xLoc.getReplicaUpdatePolicy()); + } + + @Test + public void testLargeXAttrs() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, getDefaultStripingPolicy(), "", 0, + volumeName, "", "", getKVList(), 0)); + + // create a file and add some user attributes + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + byte[] largeAttr = new byte[9000]; + for(int i = 0; i < largeAttr.length; i++) + largeAttr[i] = (byte) ((Math.random() * 256) -128); + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + "key1", "", ByteString.copyFrom(largeAttr), 0)); + + byte[] val = invokeSync( + client.getxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", "key1")) + .getValueBytes().toByteArray(); + assertEquals(largeAttr.length, val.length); + for (int i = 0; i < largeAttr.length; i++) + assertEquals(largeAttr[i], val[i]); + } + + @Test + public void testSymlink() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, getDefaultStripingPolicy(), "", 0, + volumeName, "", "", getKVList(), 0)); + + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + + // create and test a symbolic link + invokeSync(client.symlink(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + "testAlias.txt")); + String target = invokeSync( + client.readlink(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "testAlias.txt")) + .getLinkTargetPath(0); + assertEquals("test.txt", target); + } + + @Test + public void testHardLink() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, getDefaultStripingPolicy(), "", 0, + volumeName, "", "", getKVList(), 0)); + + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test1.txt", + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + + // create a new link + invokeSync(client.link(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test1.txt", + "test2.txt")); + + // check whether both links refer to the same file + Stat stat1 = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test1.txt", -1)) + .getStbuf(); + Stat stat2 = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", -1)) + .getStbuf(); + + assertEquals(stat1.getIno(), stat2.getIno()); + assertEquals(2, stat1.getNlink()); + + // create another link to the second file + invokeSync(client.link(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", + "test3.txt")); + + // check whether both links refer to the same file + stat1 = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", -1)) + .getStbuf(); + stat2 = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test3.txt", -1)) + .getStbuf(); + + assertEquals(stat1.getIno(), stat2.getIno()); + assertEquals(3, stat1.getNlink()); + + // delete one of the links + invokeSync(client.unlink(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test1.txt")); + Stat stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", -1)) + .getStbuf(); + assertEquals(2, stat.getNlink()); + + // delete the other two links + invokeSync(client.unlink(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt")); + invokeSync(client.unlink(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test3.txt")); + + try { + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test1.txt", -1)) + .getStbuf(); + fail("file should not exist anymore"); + } catch (PBRPCException exc) { + } + + try { + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", -1)) + .getStbuf(); + fail("file should not exist anymore"); + } catch (PBRPCException exc) { + } + + // create two links to a directory + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "testDir1", 0)); + try { + invokeSync(client.link(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "testDir1", + "testDir1/testDir2")); + fail("links to directories should not be allowed"); + } catch (Exception exc) { + } + } + + @Test + public void testOpen() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, getDefaultStripingPolicy(), "", 0775, + volumeName, "", "", getKVList(), 0)); + + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + FileAccessManager.O_CREAT, 0774, 0, getDefaultCoordinates())); + + // open w/ O_RDWR; should not fail + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + FileAccessManager.O_RDWR, 0, 0, getDefaultCoordinates())); + + // open w/ O_RDONLY; should not fail + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + FileAccessManager.O_RDONLY, 0, 0, getDefaultCoordinates())); + + // create a new file w/ O_CREAT; should implicitly create a new file + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", + FileAccessManager.O_CREAT, 256, 0, getDefaultCoordinates())); + invokeSync(client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", -1)); + + // open w/ O_WRONLY; should fail + try { + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", + FileAccessManager.O_WRONLY, 256, 0, getDefaultCoordinates())); + fail(); + } catch (PBRPCException exc) { + assertEquals(POSIXErrno.POSIX_ERROR_EACCES, exc.getPOSIXErrno()); + } + + // open a directory; should fail + try { + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "dir", + FileAccessManager.O_RDONLY, 0, 0, getDefaultCoordinates())); + fail("opened directory"); + } catch (PBRPCException exc) { + } + + // open a file in order to obtain a capability + XCap xcap = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test2.txt", + FileAccessManager.O_RDONLY, 0, 0, getDefaultCoordinates())).getCreds().getXcap(); + + // wait one second before renewing the capability + Thread.sleep(1000); + + // test renewing a capability + XCap newCap = invokeSync(client.xtreemfs_renew_capability(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xcap)); + assertTrue(xcap.getExpireTimeS() < newCap.getExpireTimeS()); + + // open w/ truncate flag; check whether the epoch number is incremented + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "trunc", + FileAccessManager.O_CREAT, 0777, 0, getDefaultCoordinates())); + xcap = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "trunc", + FileAccessManager.O_TRUNC, 0, 0, getDefaultCoordinates())).getCreds().getXcap(); + assertEquals(1, xcap.getTruncateEpoch()); + xcap = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "trunc", + FileAccessManager.O_TRUNC, 0, 0, getDefaultCoordinates())).getCreds().getXcap(); + assertEquals(2, xcap.getTruncateEpoch()); + + // TODO: check open w/ ACLs set + + // test truncate + + // open w/ write cap and truncate + xcap = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "trunc", + FileAccessManager.O_RDWR, 0, 0, getDefaultCoordinates())).getCreds().getXcap(); + invokeSync(client.ftruncate(mrcAddress, RPCAuthentication.authNone, RPCAuthentication.userService, + xcap)); + + xcap = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "trunc", + FileAccessManager.O_RDONLY, 0, 0, getDefaultCoordinates())).getCreds().getXcap(); + try { + invokeSync(client.ftruncate(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xcap)); + fail("truncated file w/o write permissions"); + } catch (PBRPCException exc) { + assertEquals(POSIXErrno.POSIX_ERROR_EACCES, exc.getPOSIXErrno()); + } + } + + @Test + public void testOpenCreateNoPerm() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, getDefaultStripingPolicy(), "", 0775, + volumeName, "", "", getKVList(), 0)); + + final String uid2 = "bla"; + final List gids2 = createGIDs("groupY"); + final UserCredentials uc2 = createUserCredentials(uid2, gids2); + + // open O_CREATE as uid2 should fail + try { + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc2, volumeName, "test2.txt", + (FileAccessManager.O_WRONLY | FileAccessManager.O_CREAT), 256, 0, getDefaultCoordinates())); + fail(); + } catch (PBRPCException exc) { + assertEquals(POSIXErrno.POSIX_ERROR_EACCES, exc.getPOSIXErrno()); + } + + } + + @Test + public void testRename() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, getDefaultStripingPolicy(), "", 0, + volumeName, "", "", getKVList(), 0)); + + // create some files and directories + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "blub.txt", + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "mainDir", 0)); + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "mainDir/subDir", 0)); + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, + "mainDir/subDir/newDir", 0)); + + assertTree(mrcAddress, uid, gids, volumeName, "", "test.txt", "blub.txt", "mainDir", + "mainDir/subDir", "mainDir/subDir/newDir"); + + // move some files and directories + + // file -> none (create w/ different name) + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + "mainDir/bla.txt")); + assertTree(mrcAddress, uid, gids, volumeName, "", "mainDir/bla.txt", "blub.txt", "mainDir", + "mainDir/subDir", "mainDir/subDir/newDir"); + + // file -> file (overwrite) + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "mainDir/bla.txt", + "blub.txt")); + + assertTree(mrcAddress, uid, gids, volumeName, "", "blub.txt", "mainDir", "mainDir/subDir", + "mainDir/subDir/newDir"); + + // file -> none (create w/ same name) + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "blub.txt", + "mainDir/blub.txt")); + assertTree(mrcAddress, uid, gids, volumeName, "", "mainDir/blub.txt", "mainDir", "mainDir/subDir", + "mainDir/subDir/newDir"); + + // file -> dir (invalid operation) + try { + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, + "mainDir/blub.txt", "mainDir/subDir")); + fail("move file -> directory should not be possible"); + } catch (PBRPCException exc) { + } + + // file -> file (same path, should have no effect) + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "mainDir/blub.txt", + "mainDir/blub.txt")); + assertTree(mrcAddress, uid, gids, volumeName, "", "mainDir/blub.txt", "mainDir", "mainDir/subDir", + "mainDir/subDir/newDir"); + + // file -> file (same directory) + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "mainDir/blub.txt", + "mainDir/blub2.txt")); + assertTree(mrcAddress, uid, gids, volumeName, "", "mainDir/blub2.txt", "mainDir", "mainDir/subDir", + "mainDir/subDir/newDir"); + + // dir -> none (create w/ same name) + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "mainDir/subDir", + "subDir")); + + assertTree(mrcAddress, uid, gids, volumeName, "", "mainDir/blub2.txt", "mainDir", "subDir", + "subDir/newDir"); + + // dir -> dir (overwrite, should fail because of non-empty subdirectory) + try { + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "subDir/newDir", + "subDir")); + fail("moved directory to non-empty directory"); + } catch (PBRPCException exc) { + } + + // dir -> dir (overwrite) + invokeSync(client.unlink(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "mainDir/blub2.txt")); + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "subDir", "mainDir")); + assertTree(mrcAddress, uid, gids, volumeName, "", "mainDir", "mainDir/newDir"); + + // dir -> volume (should fail because volume can't be overwritten) + try { + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, + "mainDir/newDir", "")); + fail("move overwrote volume root"); + } catch (PBRPCException exc) { + } + + // dir -> invalid volume (should fail) + try { + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "", "somewhere")); + fail("moved to invalid volume"); + } catch (PBRPCException exc) { + } + + assertTree(mrcAddress, uid, gids, volumeName, "", "mainDir", "mainDir/newDir"); + + invokeSync(client.symlink(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "mainDir", "link")); + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "link", "newlink")); + + } + + @Test + public void testAccessControl() throws Exception { + + final String uid1 = "userXY"; + final List gids1 = createGIDs("groupZ"); + final String uid2 = "userAB"; + final List gids2 = createGIDs("groupA"); + final String uid3 = "userZZ"; + final List gids3 = createGIDs("groupY"); + final String uid4 = "root"; + final List gids4 = createGIDs("root"); + + final UserCredentials uc1 = createUserCredentials(uid1, gids1); + final UserCredentials uc2 = createUserCredentials(uid2, gids2); + final UserCredentials uc3 = createUserCredentials(uid3, gids3); + final UserCredentials uc4 = createUserCredentials(uid4, gids4); + + final String noACVolumeName = "noACVol"; + final String volACVolumeName = "volACVol"; + final String posixVolName = "posixVol"; + + // NO ACCESS CONTROL + + // create a volume + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc1, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, getDefaultStripingPolicy(), "", 0, + noACVolumeName, "", "", getKVList(), 0)); + + // test chown + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc1, noACVolumeName, "chownTestFile", + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + invokeSync(client.setattr(mrcAddress, RPCAuthentication.authNone, uc4, noACVolumeName, + "chownTestFile", createChownStat("newUser", "newGroup"), Setattrs.SETATTR_UID.getNumber() + | Setattrs.SETATTR_GID.getNumber())); + + Stat stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc3, noACVolumeName, "chownTestFile", -1)) + .getStbuf(); + assertEquals("newUser", stat.getUserId()); + assertEquals("newGroup", stat.getGroupId()); + + invokeSync(client + .unlink(mrcAddress, RPCAuthentication.authNone, uc3, noACVolumeName, "chownTestFile")); + + // create a new directory; should succeed + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc1, noACVolumeName, "newDir", 0)); + + // create a new file inside the dir: should succeed (in spite of + // not having explicitly set any rights on the parent directory) + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc2, noACVolumeName, + "newDir/newFile", 0)); + + final UserCredentials ucS = createUserCredentials("someone", createGIDs("somegroup")); + assertNotNull(invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, ucS, noACVolumeName, + "newDir/newFile", -1, 1000, false, 0))); + + // VOLUME policy + + // create a volume + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc1, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_VOLUME, getDefaultStripingPolicy(), "", 0700, + volACVolumeName, "", "", getKVList(), 0)); + + // create a new directory: should succeed for user1, fail + // for user2 + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc1, volACVolumeName, "newDir", 0)); + try { + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc2, posixVolName, "newDir2", 0)); + fail("access should have been denied"); + } catch (PBRPCException exc) { + } + + // create a subdirectory for 'newDir'; should succeed for user1 + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc1, volACVolumeName, + "newDir/subDir", 0)); + + // POSIX policy + + // create a volume + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc1, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, getDefaultStripingPolicy(), "", 0775, + posixVolName, "", "", getKVList(), 0)); + + invokeSync(client.setattr(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "", + createChmodStat(0700), Setattrs.SETATTR_MODE.getNumber())); + + // create a new directory: should succeed for user1, fail for user2 + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "newDir", 0700)); + + // check permissions by opening the file + assertNotNull(invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, + "newDir", -1, 1000, false, 0))); + + try { + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc2, posixVolName, "newDir2", + 0700)); + fail("access should have been denied"); + } catch (PBRPCException exc) { + } + + // check 'access' call + + try { + invokeSync(client.access(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "grsasd", + ACCESS_FLAGS.ACCESS_FLAGS_F_OK.getNumber())); + fail("access should have been denied"); + } catch (PBRPCException exc) { + if (exc.getPOSIXErrno() != POSIXErrno.POSIX_ERROR_EACCES) { + fail("wrong error returned"); + } + } + + try { + invokeSync(client.access(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "grsasd", + ACCESS_FLAGS.ACCESS_FLAGS_R_OK.getNumber())); + fail("access should have been denied"); + } catch (PBRPCException exc) { + if (exc.getPOSIXErrno() != POSIXErrno.POSIX_ERROR_EACCES) { + fail("wrong error returned"); + } + } + + try { + invokeSync(client.access(mrcAddress, RPCAuthentication.authNone, uc2, posixVolName, "grsasd", + ACCESS_FLAGS.ACCESS_FLAGS_F_OK.getNumber())); + fail("access should have been denied"); + } catch (PBRPCException exc) { + } + + invokeSync(client.access(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "newDir", + ACCESS_FLAGS.ACCESS_FLAGS_F_OK.getNumber())); + + invokeSync(client.access(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "newDir", + ACCESS_FLAGS.ACCESS_FLAGS_R_OK.getNumber() | ACCESS_FLAGS.ACCESS_FLAGS_W_OK.getNumber())); + + try { + invokeSync(client.access(mrcAddress, RPCAuthentication.authNone, uc2, posixVolName, "newDir2", + ACCESS_FLAGS.ACCESS_FLAGS_R_OK.getNumber() | ACCESS_FLAGS.ACCESS_FLAGS_W_OK.getNumber())); + fail("access should have been denied"); + } catch (PBRPCException exc) { + } + + // TODO: test getting/setting ACL entries + + // change the access mode + invokeSync(client.setattr(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "newDir", + createChmodStat(0), Setattrs.SETATTR_MODE.getNumber())); + + // readdir on "/newDir"; should fail for any user now + try { + invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "newDir", + -1, 1000, false, 0)); + fail("access should have been denied"); + } catch (PBRPCException exc) { + } + + try { + invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc2, posixVolName, "newDir", + -1, 1000, false, 0)); + fail("access should have been denied"); + } catch (PBRPCException exc) { + } + + // set access rights to anyone (except for the owner) + invokeSync(client.setattr(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "newDir", + createChmodStat(0007), Setattrs.SETATTR_MODE.getNumber())); + + try { + invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "newDir", + -1, 1000, false, 0)); + fail("access should have been denied due to insufficient permissions"); + } catch (PBRPCException exc) { + } + + try { + invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc3, posixVolName, "newDir", + -1, 1000, false, 0)); + fail("access should have been denied due to insufficient search permissions"); + } catch (PBRPCException exc) { + } + + // set search rights on the root directory to 'others' + invokeSync(client.setattr(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "", + createChmodStat(0001), Setattrs.SETATTR_MODE.getNumber())); + + // access should be granted to others now + invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc3, posixVolName, "newDir", -1, + 1000, false, 0)); + + // check permissions + assertNotNull(invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc2, posixVolName, + "newDir", -1, 1000, false, 0))); + + // check permissions + assertNotNull(invokeSync(client.getattr(mrcAddress, RPCAuthentication.authNone, uc3, posixVolName, + "", -1))); + + // grant any rights to the volume to anyone + invokeSync(client.setattr(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "", + createChmodStat(0777), Setattrs.SETATTR_MODE.getNumber())); + + // owner of 'newDir' should still not have access rights + try { + invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "newDir", + -1, 1000, false, 0)); + fail("access should have been denied due to insufficient permissions"); + } catch (PBRPCException exc) { + } + + // others should still have no write permissions + try { + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, + "newDir/newfile", FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + fail(); + } catch (PBRPCException exc) { + } + + // create a POSIX ACL new volume and test "chmod" + invokeSync(client.xtreemfs_rmvol(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName)); + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc1, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, getDefaultStripingPolicy(), "", 0775, + posixVolName, "", "", getKVList(), 0)); + + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "someFile.txt", + FileAccessManager.O_CREAT, 224, 0, getDefaultCoordinates())); + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "someFile.txt", -1)) + .getStbuf(); + assertEquals(224, stat.getMode() & 0x7FF); + + invokeSync(client.setattr(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "someFile.txt", + createChmodStat(192), Setattrs.SETATTR_MODE.getNumber())); + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "someFile.txt", -1)) + .getStbuf(); + assertEquals(192, stat.getMode() & 0x7FF); + + // create a new directory w/ search access for anyone w/ access rights + // to anyone + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "stickyDir", 0777)); + + // create and delete/rename a file w/ different user IDs: this should + // work + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc2, posixVolName, + "stickyDir/newfile.txt", FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + invokeSync(client.unlink(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, + "stickyDir/newfile.txt")); + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc3, posixVolName, + "stickyDir/newfile.txt", FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, + "stickyDir/newfile.txt", "stickyDir/newfile2.txt")); + + // create a file and set sticky bit on the directory; now, only the + // owner should be allowed to delete/rename the nested file + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc2, posixVolName, + "stickyDir/newfile.txt", FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + invokeSync(client.setattr(mrcAddress, RPCAuthentication.authNone, uc1, posixVolName, "stickyDir", + createChmodStat(01777), Setattrs.SETATTR_MODE.getNumber())); + + try { + invokeSync(client.unlink(mrcAddress, RPCAuthentication.authNone, uc3, posixVolName, + "stickyDir/newfile.txt")); + fail("access should have been denied due to insufficient delete permissions (sticky bit)"); + } catch (PBRPCException exc) { + } + try { + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc3, posixVolName, + "stickyDir/newfile.txt", "stickyDir/newfile3.txt")); + fail("access should have been denied due to insufficient renaming permissions (sticky bit)"); + } catch (PBRPCException exc) { + } + + invokeSync(client.rename(mrcAddress, RPCAuthentication.authNone, uc2, posixVolName, + "stickyDir/newfile.txt", "stickyDir/newfile3.txt")); + invokeSync(client.unlink(mrcAddress, RPCAuthentication.authNone, uc2, posixVolName, + "stickyDir/newfile3.txt")); + } + + @Test + public void testFileSizeUpdate() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final String volumeName = "testVolume"; + final String fileName = "testFile"; + final UserCredentials uc = createUserCredentials(uid, gids); + + // create a new file in a new volume + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, getDefaultStripingPolicy(), "", 0, + volumeName, "", "", getKVList(), 0)); + + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + + // check and update file sizes repeatedly + XCap cap = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, + FileAccessManager.O_RDONLY, 0, 0, getDefaultCoordinates())).getCreds().getXcap(); + Stat stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, -1)).getStbuf(); + assertEquals(0L, stat.getSize()); + + OSDWriteResponse owr = createFSResponse(27, 0); + invokeSync(client.xtreemfs_update_file_size(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xtreemfs_update_file_sizeRequest.newBuilder().setOsdWriteResponse( + owr).setXcap(cap).build())); + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, -1)).getStbuf(); + assertEquals(27L, stat.getSize()); + + owr = createFSResponse(12, 0); + invokeSync(client.xtreemfs_update_file_size(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xtreemfs_update_file_sizeRequest.newBuilder().setOsdWriteResponse( + owr).setXcap(cap).build())); + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, -1)).getStbuf(); + assertEquals(27L, stat.getSize()); + + owr = createFSResponse(34, 0); + invokeSync(client.xtreemfs_update_file_size(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xtreemfs_update_file_sizeRequest.newBuilder().setOsdWriteResponse( + owr).setXcap(cap).build())); + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, -1)).getStbuf(); + assertEquals(34L, stat.getSize()); + + owr = createFSResponse(10, 1); + invokeSync(client.xtreemfs_update_file_size(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xtreemfs_update_file_sizeRequest.newBuilder().setOsdWriteResponse( + owr).setXcap(cap).build())); + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, -1)).getStbuf(); + assertEquals(10L, stat.getSize()); + + owr = createFSResponse(34, 1); + invokeSync(client.xtreemfs_update_file_size(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xtreemfs_update_file_sizeRequest.newBuilder().setOsdWriteResponse( + owr).setXcap(cap).build())); + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, -1)).getStbuf(); + assertEquals(34L, stat.getSize()); + + owr = createFSResponse(10, 1); + invokeSync(client.xtreemfs_update_file_size(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xtreemfs_update_file_sizeRequest.newBuilder().setOsdWriteResponse( + owr).setXcap(cap).build())); + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, -1)).getStbuf(); + assertEquals(34L, stat.getSize()); + + owr = createFSResponse(0, 2); + invokeSync(client.xtreemfs_update_file_size(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xtreemfs_update_file_sizeRequest.newBuilder().setOsdWriteResponse( + owr).setXcap(cap).build())); + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, -1)).getStbuf(); + assertEquals(0L, stat.getSize()); + + owr = createFSResponse(12, 0); + invokeSync(client.xtreemfs_update_file_size(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xtreemfs_update_file_sizeRequest.newBuilder().setOsdWriteResponse( + owr).setXcap(cap).build())); + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, -1)).getStbuf(); + assertEquals(0L, stat.getSize()); + + owr = createFSResponse(32, 4); + invokeSync(client.xtreemfs_update_file_size(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xtreemfs_update_file_sizeRequest.newBuilder().setOsdWriteResponse( + owr).setXcap(cap).build())); + stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, -1)).getStbuf(); + assertEquals(32L, stat.getSize()); + } + + @Test + public void testDefaultStripingPolicies() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final UserCredentials uc = createUserCredentials(uid, gids); + + final String volumeName = "testVolume"; + final String dirName = "dir"; + final String fileName1 = dirName + "/testFile"; + final String fileName2 = dirName + "/testFile2"; + + StripingPolicy sp1 = StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0) + .setStripeSize(64).setWidth(1).build(); + + // create a new file in a directory in a new volume + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, sp1, "", 0, volumeName, "", "", getKVList(), 0)); + + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, dirName, 0)); + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName1, + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName2, + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + + // check if the striping policy assigned to the file matches the default + // striping policy + XLocSet xLoc = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName1, + FileAccessManager.O_RDONLY, 0, 0, getDefaultCoordinates())).getCreds().getXlocs(); + + StripingPolicy sp = xLoc.getReplicas(0).getStripingPolicy(); + assertEquals(sp1.getType().name(), sp.getType().name()); + assertEquals(sp1.getWidth(), sp.getWidth()); + assertEquals(sp1.getStripeSize(), sp.getStripeSize()); + + // check block size in Stat + Stat stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName1, -1)).getStbuf(); + assertEquals(sp1.getStripeSize() * 1024, stat.getBlksize()); + + stat = invokeSync(client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, dirName, -1)) + .getStbuf(); + assertEquals(0, stat.getBlksize()); + + } + + @Test + public void testDefaultReplicationPolicies() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final UserCredentials uc = createUserCredentials(uid, gids); + + final String volumeName = "testVolume"; + final String dirName = "dir"; + final String fileName = dirName + "/testFile"; + + final StripingPolicy sp = StripingPolicy.newBuilder().setType( + StripingPolicyType.STRIPING_POLICY_RAID0).setStripeSize(64).setWidth(1).build(); + + ReplicationPolicy rp = new ReplicationPolicy() { + + @Override + public String getName() { + return ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE; + } + + @Override + public int getFactor() { + return 2; + } + + @Override + public int getFlags() { + return 0; + } + + }; + + // create a new file in a directory in a new volume + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, sp, "", 0, volumeName, "", "", getKVList(), 0)); + + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "", + "xtreemfs.default_rp", "", ByteString.copyFrom(Converter.replicationPolicyToJSONString(rp).getBytes()), 0)); + + String val = invokeSync( + client + .getxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "", + "xtreemfs.default_rp")).getValue(); + ReplicationPolicy pol = Converter.jsonStringToReplicationPolicy(val); + + assertEquals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE, pol.getName()); + assertEquals(rp.getFactor(), pol.getFactor()); + assertEquals(rp.getFlags(), pol.getFlags()); + + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, dirName, 0)); + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, + FileAccessManager.O_CREAT, 0, 0, getDefaultCoordinates())); + + // check if the striping policy assigned to the file matches the default + // striping policy + XLocSet xLoc = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, fileName, + FileAccessManager.O_RDONLY, 0, 0, getDefaultCoordinates())).getCreds().getXlocs(); + + assertEquals(rp.getName(), xLoc.getReplicaUpdatePolicy()); + assertEquals(rp.getFactor(), xLoc.getReplicasCount()); + } + + @Test + public void testReplicateOnClose() throws Exception { + + final String uid = "userXY"; + final List gids = createGIDs("groupZ"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + + // create a volume + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, getDefaultStripingPolicy(), "", 0775, + volumeName, "", "", getKVList(), 0)); + + // auto-assign three (two more) replicas to each newly-created file + ReplicationPolicy rp = new ReplicationPolicy() { + + @Override + public String getName() { + return ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY; + } + + @Override + public int getFactor() { + return 3; + } + + @Override + public int getFlags() { + return 0; + } + + }; + + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "", + "xtreemfs.default_rp", "", ByteString.copyFrom(Converter.replicationPolicyToJSONString(rp).getBytes()), 0)); + + // create a new file + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + FileAccessManager.O_CREAT, 0775, 0, getDefaultCoordinates())); + + // open the file + FileCredentials creds = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + FileAccessManager.O_RDWR, 0, 0, getDefaultCoordinates())).getCreds(); + XCap xCap = creds.getXcap(); + + // close the file + invokeSync(client.xtreemfs_update_file_size(mrcAddress, RPCAuthentication.authNone, + RPCAuthentication.userService, xCap, OSDWriteResponse.getDefaultInstance(), true, + getDefaultCoordinates())); + + // open the file again + creds = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + FileAccessManager.O_RDONLY, 0, 0, getDefaultCoordinates())).getCreds(); + XLocSet xLoc = creds.getXlocs(); + + // check whether there are three replicas now, and replica 0 has the + // correct replication flags + assertEquals(3, xLoc.getReplicasCount()); + assertTrue((ReplicationFlags.setReplicaIsComplete(0) + & xLoc.getReplicas(0).getReplicationFlags()) != 0); + + // check if the file is read-only + try { + creds = invokeSync( + client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "test.txt", + FileAccessManager.O_RDWR, 0, 0, getDefaultCoordinates())).getCreds(); + fail("file should have been read-only"); + + } catch (IOException exc) { + // ok + } + + } + + private void assertTree(InetSocketAddress server, String uid, List gids, String volumeName, + String... paths) throws Exception { + + final UserCredentials uc = createUserCredentials(uid, gids); + + // check whether all paths exist exactly once + for (String path : paths) { + + try { + Stat stat = invokeSync( + client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, path, -1)) + .getStbuf(); + + // continue if the path does not point to a directory + if ((stat.getMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFDIR.getNumber()) == 0) + continue; + + } catch (PBRPCException exc) { + throw new Exception("path '" + path + "' does not exist (" + exc.getPOSIXErrno() + ")"); + } + + // if the path points to a directory, check whether the number of + // subdirectories is correct + DirectoryEntries dir = invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc, + volumeName, path, -1, 1000, false, 0)); + int size = dir.getEntriesCount(); + + int count = 0; + for (String otherPath : paths) { + + // root dir + if (path.equals("")) { + if (otherPath.indexOf('/') == -1) + count++; + } + + // nested dir + else { + if (!otherPath.startsWith(path + "/")) + continue; + + if (otherPath.substring(path.length() + 1).indexOf('/') == -1) + count++; + + } + } + + assertEquals(count + (path.equals("") ? 1 : 2), size); + } + } + + private static List createGIDs(String gid) { + List list = new LinkedList(); + list.add(gid); + return list; + } + + private static Stat createChmodStat(int newMode) { + return getDefaultStatBuilder().setMode(newMode).build(); + } + + private static OSDWriteResponse createFSResponse(int newFS, int newEpoch) { + return OSDWriteResponse.newBuilder().setSizeInBytes(newFS).setTruncateEpoch(newEpoch).build(); + } + + private static Stat createChownStat(String newUid, String newGid) { + return getDefaultStatBuilder().setUserId(newUid).setGroupId(newGid).build(); + } + + private static T invokeSync(RPCResponse response) throws PBRPCException, + IOException, InterruptedException { + + try { + return response.get(); + } finally { + response.freeBuffers(); + } + } + + private static UserCredentials createUserCredentials(String uid, List gids) { + return UserCredentials.newBuilder().setUsername(uid).addAllGroups(gids).build(); + } + + private static StripingPolicy getDefaultStripingPolicy() { + return StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0).setStripeSize( + 1000).setWidth(1).build(); + } + + private static Stat.Builder getDefaultStatBuilder() { + return Stat.newBuilder().setAtimeNs(0).setAttributes(0).setBlksize(0).setCtimeNs(0).setDev(0) + .setEtag(0).setGroupId("").setIno(0).setMode(0).setMtimeNs(0).setNlink(0).setSize(0) + .setTruncateEpoch(0).setUserId(""); + } + + private static VivaldiCoordinates getDefaultCoordinates() { + return VivaldiCoordinates.newBuilder().setXCoordinate(0).setYCoordinate(0).setLocalError(0).build(); + } + + private static List getKVList(String... kvPairs) { + + List kvList = new LinkedList(); + for (int i = 0; i < kvPairs.length; i += 2) + kvList.add(KeyValuePair.newBuilder().setKey(kvPairs[i]).setValue(kvPairs[i + 1]).build()); + + return kvList; + } +} diff --git a/java/servers/test/org/xtreemfs/test/mrc/OSDPolicyTest.java b/java/servers/test/org/xtreemfs/test/mrc/OSDPolicyTest.java new file mode 100644 index 0000000..309ae29 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/mrc/OSDPolicyTest.java @@ -0,0 +1,613 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.mrc; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.util.Properties; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.HeartbeatThread; +import org.xtreemfs.common.KeyValuePairs; +import org.xtreemfs.common.config.ServiceConfig; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.mrc.osdselection.FilterDefaultPolicy; +import org.xtreemfs.mrc.osdselection.FilterFQDNPolicy; +import org.xtreemfs.mrc.osdselection.GroupDCMapPolicy; +import org.xtreemfs.mrc.osdselection.GroupFQDNPolicy; +import org.xtreemfs.mrc.osdselection.Inet4AddressMatcher; +import org.xtreemfs.mrc.osdselection.SortDCMapPolicy; +import org.xtreemfs.mrc.osdselection.SortFQDNPolicy; +import org.xtreemfs.mrc.osdselection.SortHostRoundRobinPolicy; +import org.xtreemfs.mrc.osdselection.SortVivaldiPolicy; +import org.xtreemfs.osd.vivaldi.VivaldiNode; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.Service; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceDataMap; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceSet; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestEnvironment.Services; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class OSDPolicyTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment testEnv; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL); + } + + @AfterClass + public static void shutdownTest() throws Exception { + } + + @Before + public void setUp() throws Exception { + testEnv = new TestEnvironment(Services.TIME_SYNC, Services.UUID_RESOLVER); + testEnv.start(); + } + + @After + public void tearDown() { + testEnv.shutdown(); + } + + @Test + public void testIPv4Matcher() throws Exception { + + Inet4Address ifa1 = (Inet4Address) InetAddress.getByAddress(new byte[] { (byte) 192, (byte) 168, + (byte) 1, (byte) 125 }); + Inet4Address ifa2 = (Inet4Address) InetAddress.getByAddress(new byte[] { (byte) 192, (byte) 168, + (byte) 1, (byte) 126 }); + Inet4Address ifa3 = (Inet4Address) InetAddress.getByAddress(new byte[] { (byte) 192, (byte) 168, + (byte) 1, (byte) 254 }); + Inet4Address ifa4 = (Inet4Address) InetAddress.getByAddress(new byte[] { (byte) 192, (byte) 168, + (byte) 10, (byte) 125 }); + Inet4Address ifa5 = (Inet4Address) InetAddress.getByAddress(new byte[] { (byte) 10, (byte) 0, + (byte) 1, (byte) 125 }); + + Inet4AddressMatcher m = new Inet4AddressMatcher(ifa1); + assertTrue(m.matches(ifa1)); + assertFalse(m.matches(ifa2)); + assertFalse(m.matches(ifa3)); + assertFalse(m.matches(ifa4)); + assertFalse(m.matches(ifa5)); + + m = new Inet4AddressMatcher(ifa1, 25); + assertTrue(m.matches(ifa1)); + assertTrue(m.matches(ifa2)); + assertFalse(m.matches(ifa3)); + assertFalse(m.matches(ifa4)); + assertFalse(m.matches(ifa5)); + + m = new Inet4AddressMatcher(ifa1, 24); + assertTrue(m.matches(ifa1)); + assertTrue(m.matches(ifa2)); + assertTrue(m.matches(ifa3)); + assertFalse(m.matches(ifa4)); + assertFalse(m.matches(ifa5)); + + m = new Inet4AddressMatcher(ifa1, 16); + assertTrue(m.matches(ifa1)); + assertTrue(m.matches(ifa2)); + assertTrue(m.matches(ifa3)); + assertTrue(m.matches(ifa4)); + assertFalse(m.matches(ifa5)); + + m = new Inet4AddressMatcher(ifa1, 1); + assertTrue(m.matches(ifa1)); + assertTrue(m.matches(ifa2)); + assertTrue(m.matches(ifa3)); + assertTrue(m.matches(ifa4)); + assertFalse(m.matches(ifa5)); + } + + @Test + public void testFilterDefaultPolicy() throws Exception { + + ServiceDataMap.Builder sdm1 = ServiceDataMap.newBuilder(); + sdm1.addData(KeyValuePair.newBuilder().setKey("free").setValue("1000")); + sdm1.addData(KeyValuePair.newBuilder().setKey("seconds_since_last_update").setValue("5")); + + ServiceDataMap.Builder sdm2 = ServiceDataMap.newBuilder(); + sdm2.addData(KeyValuePair.newBuilder().setKey("free").setValue("5000")); + sdm2.addData(KeyValuePair.newBuilder().setKey("seconds_since_last_update").setValue("5")); + + ServiceDataMap.Builder sdm3 = ServiceDataMap.newBuilder(); + sdm3.addData(KeyValuePair.newBuilder().setKey("free").setValue("5000")); + sdm3.addData(KeyValuePair.newBuilder().setKey("seconds_since_last_update").setValue("0")); + sdm3.addData(KeyValuePair.newBuilder().setKey(HeartbeatThread.STATUS_ATTR) + .setValue(String.valueOf(ServiceStatus.SERVICE_STATUS_AVAIL.getNumber()))); + + // the following two shouldn't be selected because they are not available + ServiceDataMap.Builder sdm4 = ServiceDataMap.newBuilder(); + sdm4.addData(KeyValuePair.newBuilder().setKey("free").setValue("5000")); + sdm4.addData(KeyValuePair.newBuilder().setKey("seconds_since_last_update").setValue("0")); + sdm4.addData(KeyValuePair.newBuilder().setKey(HeartbeatThread.STATUS_ATTR) + .setValue(String.valueOf(ServiceStatus.SERVICE_STATUS_TO_BE_REMOVED.getNumber()))); + + ServiceDataMap.Builder sdm5 = ServiceDataMap.newBuilder(); + sdm5.addData(KeyValuePair.newBuilder().setKey("free").setValue("5000")); + sdm5.addData(KeyValuePair.newBuilder().setKey("seconds_since_last_update").setValue("0")); + sdm5.addData(KeyValuePair.newBuilder().setKey(HeartbeatThread.STATUS_ATTR) + .setValue(String.valueOf(ServiceStatus.SERVICE_STATUS_REMOVED.getNumber()))); + + ServiceSet.Builder servicesBuilder = ServiceSet.newBuilder(); + servicesBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(0).setName("osd1").setVersion(1).setUuid("osd1").setData(sdm1)); + servicesBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(0).setName("osd2").setVersion(1).setUuid("osd2").setData(sdm2)); + servicesBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(0).setName("osd3").setVersion(1).setUuid("osd3").setData(sdm3)); + servicesBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(0).setName("osd4").setVersion(1).setUuid("osd4").setData(sdm4)); + servicesBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(0).setName("osd5").setVersion(1).setUuid("osd5").setData(sdm5)); + ServiceSet services = servicesBuilder.build(); + + + FilterDefaultPolicy pol = new FilterDefaultPolicy(); + pol.setAttribute("offline_time_secs", "2"); + pol.setAttribute("free_capacity_bytes", "2000"); + ServiceSet.Builder filteredOSDs = pol.getOSDs(services.toBuilder()); + + assertEquals(1, filteredOSDs.getServicesCount()); + assertEquals("osd3", filteredOSDs.getServices(0).getUuid()); + } + + @Test + public void testFilterDefaultPolicyOnCustomProperty() throws Exception { + + ServiceDataMap.Builder sdm1 = ServiceDataMap.newBuilder(); + sdm1.addData(KeyValuePair.newBuilder().setKey("free").setValue("10000")); + sdm1.addData(KeyValuePair.newBuilder().setKey("seconds_since_last_update").setValue("0")); + sdm1.addData(KeyValuePair.newBuilder().setKey(HeartbeatThread.STATUS_ATTR) + .setValue(String.valueOf(ServiceStatus.SERVICE_STATUS_AVAIL.getNumber()))); + sdm1.addData(KeyValuePair.newBuilder().setKey(ServiceConfig.OSD_CUSTOM_PROPERTY_PREFIX+"country") + .setValue(String.valueOf("FR"))); + + ServiceDataMap.Builder sdm2 = ServiceDataMap.newBuilder(); + sdm2.addData(KeyValuePair.newBuilder().setKey("free").setValue("10000")); + sdm2.addData(KeyValuePair.newBuilder().setKey("seconds_since_last_update").setValue("0")); + sdm2.addData(KeyValuePair.newBuilder().setKey(HeartbeatThread.STATUS_ATTR) + .setValue(String.valueOf(ServiceStatus.SERVICE_STATUS_AVAIL.getNumber()))); + + sdm2.addData(KeyValuePair.newBuilder().setKey(ServiceConfig.OSD_CUSTOM_PROPERTY_PREFIX+"country") + .setValue(String.valueOf("DE"))); + + + ServiceDataMap.Builder sdm3 = ServiceDataMap.newBuilder(); + sdm3.addData(KeyValuePair.newBuilder().setKey("free").setValue("10000")); + sdm3.addData(KeyValuePair.newBuilder().setKey("seconds_since_last_update").setValue("0")); + sdm3.addData(KeyValuePair.newBuilder().setKey(HeartbeatThread.STATUS_ATTR) + .setValue(String.valueOf(ServiceStatus.SERVICE_STATUS_AVAIL.getNumber()))); + sdm3.addData(KeyValuePair.newBuilder().setKey(ServiceConfig.OSD_CUSTOM_PROPERTY_PREFIX+"country") + .setValue(String.valueOf("GB"))); + + ServiceSet.Builder servicesBuilder = ServiceSet.newBuilder(); + servicesBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(0).setName("osd1").setVersion(1).setUuid("osd1").setData(sdm1)); + servicesBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(0).setName("osd2").setVersion(1).setUuid("osd2").setData(sdm2)); + servicesBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(0).setName("osd3").setVersion(1).setUuid("osd3").setData(sdm3)); + ServiceSet services = servicesBuilder.build(); + + // all OSDs but from FR + FilterDefaultPolicy pol = new FilterDefaultPolicy(); + pol.setAttribute("not.country", "FR"); + ServiceSet.Builder filteredOSDs = pol.getOSDs(services.toBuilder()); + + assertEquals(2, filteredOSDs.getServicesCount()); + + + // only OSDs from DE and NOT from FR + pol = new FilterDefaultPolicy(); + pol.setAttribute("country", "DE"); + pol.setAttribute("not.country", "FR"); + filteredOSDs = pol.getOSDs(services.toBuilder()); + + assertEquals(1, filteredOSDs.getServicesCount()); + String osdParameterValue + = KeyValuePairs.getValue(filteredOSDs.getServices(0).getData().getDataList(), + ServiceConfig.OSD_CUSTOM_PROPERTY_PREFIX + "country"); + assertEquals("DE", osdParameterValue); + + // only OSDs not from FR and not from DE + pol = new FilterDefaultPolicy(); + pol.setAttribute("not.country", "FR DE"); + filteredOSDs = pol.getOSDs(services.toBuilder()); + + assertEquals(1, filteredOSDs.getServicesCount()); + osdParameterValue + = KeyValuePairs.getValue(filteredOSDs.getServices(0).getData().getDataList(), + ServiceConfig.OSD_CUSTOM_PROPERTY_PREFIX + "country"); + assertEquals("GB", osdParameterValue); + + } + + @Test + public void testFilterFQDNPolicy() throws Exception { + + ServiceSet.Builder servicesBuilder = ServiceSet.newBuilder(); + servicesBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(System.currentTimeMillis() / 1000 - 1000).setName("osd1").setVersion(1) + .setUuid("osd1").setData(getDefaultServiceDataMap())); + servicesBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(System.currentTimeMillis() / 1000 - 5000).setName("osd2").setVersion(1) + .setUuid("osd2").setData(getDefaultServiceDataMap())); + servicesBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(System.currentTimeMillis() / 1000 - 1000).setName("osd3").setVersion(1) + .setUuid("osd3").setData(getDefaultServiceDataMap())); + ServiceSet services = servicesBuilder.build(); + + UUIDResolver.addTestMapping("osd1", "test.xyz.org", 32640, false); + UUIDResolver.addTestMapping("osd2", "test2.xyz.org", 32640, false); + UUIDResolver.addTestMapping("osd3", "bla.com", 32640, false); + + FilterFQDNPolicy pol = new FilterFQDNPolicy(); + pol.setAttribute("domains", "*.org"); + ServiceSet.Builder filteredOSDs = pol.getOSDs(services.toBuilder()); + + assertEquals(2, filteredOSDs.getServicesCount()); + assertEquals("osd1", filteredOSDs.getServices(0).getUuid()); + assertEquals("osd2", filteredOSDs.getServices(1).getUuid()); + + pol.setAttribute("domains", "*.com"); + filteredOSDs = pol.getOSDs(services.toBuilder()); + + assertEquals(1, filteredOSDs.getServicesCount()); + assertEquals("osd3", filteredOSDs.getServices(0).getUuid()); + + pol.setAttribute("domains", "*.com test*"); + filteredOSDs = pol.getOSDs(services.toBuilder()); + + assertEquals(3, filteredOSDs.getServicesCount()); + assertEquals("osd1", filteredOSDs.getServices(0).getUuid()); + assertEquals("osd2", filteredOSDs.getServices(1).getUuid()); + assertEquals("osd3", filteredOSDs.getServices(2).getUuid()); + } + + @Test + public void testSortDCMapPolicy() throws Exception { + + Properties p = new Properties(); + p.setProperty("datacenters", "A,B,yagg-blupp"); + + try { + new SortDCMapPolicy(p); + fail(); + } catch (IllegalArgumentException ex) { + // ok, invalid data center name + } + + p.setProperty("datacenters", "A,B,C"); + p.setProperty("distance.A-B", "10"); + p.setProperty("distance.A-C", "100"); + p.setProperty("distance.B-C", "50"); + p.setProperty("A.addresses", "192.168.1.1,192.168.2.0/24"); + p.setProperty("B.addresses", "192.168.1.2,192.168.3.0/24"); + p.setProperty("C.addresses", "192.168.1.3,192.168.4.0/24,192.168.10.10"); + SortDCMapPolicy policy = new SortDCMapPolicy(p); + + ServiceSet.Builder osdsBuilder = ServiceSet.newBuilder(); + osdsBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd1").setVersion(1).setUuid("osd1").setData(getDefaultServiceDataMap())); + osdsBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd2").setVersion(1).setUuid("osd2").setData(getDefaultServiceDataMap())); + osdsBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd3").setVersion(1).setUuid("osd3").setData(getDefaultServiceDataMap())); + osdsBuilder.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd4").setVersion(1).setUuid("osd4").setData(getDefaultServiceDataMap())); + ServiceSet osds = osdsBuilder.build(); + + UUIDResolver.addTestMapping("osd1", "192.168.2.10", 2222, false); + UUIDResolver.addTestMapping("osd2", "192.168.3.11", 2222, false); + UUIDResolver.addTestMapping("osd3", "192.168.4.100", 2222, false); + UUIDResolver.addTestMapping("osd4", "192.168.1.1", 2222, false); + + InetAddress clientAddr = InetAddress.getByName("192.168.2.100"); + ServiceSet.Builder sortedList = policy.getOSDs(osds.toBuilder(), clientAddr, null, null, + Integer.MAX_VALUE); + assertEquals("osd1", sortedList.getServices(0).getUuid()); + assertEquals("osd4", sortedList.getServices(1).getUuid()); + assertEquals("osd2", sortedList.getServices(2).getUuid()); + assertEquals("osd3", sortedList.getServices(3).getUuid()); + + clientAddr = InetAddress.getByName("192.168.3.100"); + sortedList = policy.getOSDs(osds.toBuilder(), clientAddr, null, null, Integer.MAX_VALUE); + assertEquals("osd2", sortedList.getServices(0).getUuid()); + assertEquals("osd1", sortedList.getServices(1).getUuid()); + assertEquals("osd4", sortedList.getServices(2).getUuid()); + assertEquals("osd3", sortedList.getServices(3).getUuid()); + + } + + @Test + public void testGroupDCMapPolicy() throws Exception { + + Properties p = new Properties(); + p.setProperty("datacenters", "A,B,C"); + p.setProperty("distance.A-B", "10"); + p.setProperty("distance.A-C", "100"); + p.setProperty("distance.B-C", "50"); + p.setProperty("A.addresses", "192.168.1.1,192.168.2.0/24"); + p.setProperty("B.addresses", "192.168.1.2,192.168.3.0/24"); + p.setProperty("C.addresses", "192.168.1.3,192.168.4.0/24,192.168.10.10"); + GroupDCMapPolicy policy = new GroupDCMapPolicy(p); + + ServiceSet.Builder osds = ServiceSet.newBuilder(); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd1").setVersion(1).setUuid("osd1").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd2").setVersion(1).setUuid("osd2").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd3").setVersion(1).setUuid("osd3").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd4").setVersion(1).setUuid("osd4").setData(getDefaultServiceDataMap())); + + UUIDResolver.addTestMapping("osd1", "192.168.2.10", 2222, false); + UUIDResolver.addTestMapping("osd2", "192.168.3.11", 2222, false); + UUIDResolver.addTestMapping("osd3", "192.168.4.100", 2222, false); + UUIDResolver.addTestMapping("osd4", "192.168.1.1", 2222, false); + + // get two OSDs from one data center + InetAddress clientAddr = InetAddress.getByName("192.168.2.100"); + ServiceSet.Builder sortedList = policy.getOSDs(ServiceSet.newBuilder().addAllServices( + osds.getServicesList()), clientAddr, null, null, 2); + assertEquals(2, sortedList.getServicesCount()); + assertEquals("osd1", sortedList.getServices(0).getUuid()); + assertEquals("osd4", sortedList.getServices(1).getUuid()); + + // request too many OSDs + clientAddr = InetAddress.getByName("192.168.2.100"); + sortedList = policy.getOSDs(ServiceSet.newBuilder().addAllServices(osds.getServicesList()), + clientAddr, null, null, 3); + assertEquals(0, sortedList.getServicesCount()); + + clientAddr = InetAddress.getByName("192.168.3.100"); + sortedList = policy.getOSDs(ServiceSet.newBuilder().addAllServices(osds.getServicesList()), + clientAddr, null, null, 1); + assertEquals(1, sortedList.getServicesCount()); + assertEquals("osd2", sortedList.getServices(0).getUuid()); + + } + + @Test + public void testSortFQDNPolicy() throws Exception { + + SortFQDNPolicy policy = new SortFQDNPolicy(); + + ServiceSet.Builder osds = ServiceSet.newBuilder(); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd1").setVersion(1).setUuid("osd1").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd2").setVersion(1).setUuid("osd2").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd3").setVersion(1).setUuid("osd3").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd4").setVersion(1).setUuid("osd4").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd5").setVersion(1).setUuid("osd5").setData(getDefaultServiceDataMap())); + + UUIDResolver.addTestMapping("osd1", "xtreemfs1.zib.de", 2222, false); + UUIDResolver.addTestMapping("osd2", "www.heise.de", 2222, false); + UUIDResolver.addTestMapping("osd3", "xtreemfs.zib.de", 2222, false); + UUIDResolver.addTestMapping("osd4", "csr-pc29.zib.de", 2222, false); + UUIDResolver.addTestMapping("osd5", "download.xtreemfs.com", 2222, false); + + InetAddress clientAddr = InetAddress.getByName("xtreem.zib.de"); + ServiceSet.Builder sortedList = policy.getOSDs(ServiceSet.newBuilder().addAllServices( + osds.getServicesList()), clientAddr, null, null, Integer.MAX_VALUE); + assertEquals("osd1", sortedList.getServices(0).getUuid()); + assertEquals("osd3", sortedList.getServices(1).getUuid()); + assertEquals("osd4", sortedList.getServices(2).getUuid()); + assertEquals("osd2", sortedList.getServices(3).getUuid()); + assertEquals("osd5", sortedList.getServices(4).getUuid()); + + clientAddr = InetAddress.getByName("www.heise.de"); + sortedList = policy.getOSDs(ServiceSet.newBuilder().addAllServices(osds.getServicesList()), + clientAddr, null, null, Integer.MAX_VALUE); + + assertEquals("osd2", sortedList.getServices(0).getUuid()); + } + + @Test + public void testGroupFQDNPolicy() throws Exception { + + GroupFQDNPolicy policy = new GroupFQDNPolicy(); + + ServiceSet.Builder osds = ServiceSet.newBuilder(); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd1").setVersion(1).setUuid("osd1").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd2").setVersion(1).setUuid("osd2").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd3").setVersion(1).setUuid("osd3").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd4").setVersion(1).setUuid("osd4").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setName("osd5").setVersion(1).setUuid("osd5").setData(getDefaultServiceDataMap())); + + UUIDResolver.addTestMapping("osd1", "bla.xtreemfs.zib.de", 2222, false); + UUIDResolver.addTestMapping("osd2", "www.heise.de", 2222, false); + UUIDResolver.addTestMapping("osd3", "blub.xtreemfs.zib.de", 2222, false); + UUIDResolver.addTestMapping("osd4", "csr-pc29.zib.de", 2222, false); + UUIDResolver.addTestMapping("osd5", "download.xtreemfs.com", 2222, false); + + InetAddress clientAddr = InetAddress.getByName("xtreem.zib.de"); + ServiceSet.Builder sortedList = policy.getOSDs(ServiceSet.newBuilder().addAllServices( + osds.getServicesList()), clientAddr, null, null, 1); + assertEquals(1, sortedList.getServicesCount()); + assertEquals("osd1", sortedList.getServices(0).getUuid()); + + sortedList = policy.getOSDs(ServiceSet.newBuilder().addAllServices(osds.getServicesList()), + clientAddr, null, null, 2); + assertEquals(2, sortedList.getServicesCount()); + assertEquals("osd1", sortedList.getServices(0).getUuid()); + assertEquals("osd3", sortedList.getServices(1).getUuid()); + + sortedList = policy.getOSDs(ServiceSet.newBuilder().addAllServices(osds.getServicesList()), + clientAddr, null, null, 4); + assertEquals(0, sortedList.getServicesCount()); + + clientAddr = InetAddress.getByName("www.heise.de"); + sortedList = policy.getOSDs(ServiceSet.newBuilder().addAllServices(osds.getServicesList()), + clientAddr, null, null, 1); + assertEquals(1, sortedList.getServicesCount()); + assertEquals("osd2", sortedList.getServices(0).getUuid()); + + } + + @Test + public void testSortVivaldiPolicy() throws Exception { + + SortVivaldiPolicy policy = new SortVivaldiPolicy(); + + // VivaldiCoordinates coords1 = new VivaldiCoordinates(1.0,1.0,0.1); + VivaldiCoordinates.Builder coords2 = VivaldiCoordinates.newBuilder().setXCoordinate(5.0).setYCoordinate(5.0) + .setLocalError(0.1); + VivaldiCoordinates.Builder coords3 = VivaldiCoordinates.newBuilder().setXCoordinate(2.0).setYCoordinate(2.0) + .setLocalError(0.1); + VivaldiCoordinates.Builder coords4 = VivaldiCoordinates.newBuilder().setXCoordinate(20.0) + .setYCoordinate(20.0).setLocalError(0.1); + VivaldiCoordinates.Builder coords5 = VivaldiCoordinates.newBuilder().setXCoordinate(10.0) + .setYCoordinate(10.0).setLocalError(0.1); + + ServiceSet.Builder osds = ServiceSet.newBuilder(); + // sdm.put("vivaldi_coordinates", + // VivaldiNode.coordinatesToString(coords1)); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setVersion(1).setUuid("osd1").setName("osd1").setData(ServiceDataMap.newBuilder())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setVersion(1).setUuid("osd1").setName("osd1").setData(ServiceDataMap.newBuilder())); + + ServiceDataMap.Builder sdm = ServiceDataMap.newBuilder(); + sdm.addData(KeyValuePair.newBuilder().setKey("vivaldi_coordinates").setValue( + VivaldiNode.coordinatesToString(coords2.build()))); + Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0).setVersion(1).setUuid( + "osd2").setName("osd2").setData(sdm.clone()); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setVersion(1).setUuid("osd2").setName("osd2").setData(sdm)); + + sdm = ServiceDataMap.newBuilder(); + sdm.addData(KeyValuePair.newBuilder().setKey("vivaldi_coordinates").setValue( + VivaldiNode.coordinatesToString(coords3.build()))); + Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0).setVersion(1).setUuid( + "osd3").setName("osd3").setData(sdm.clone()); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setVersion(1).setUuid("osd3").setName("osd3").setData(sdm)); + + sdm = ServiceDataMap.newBuilder(); + sdm.addData(KeyValuePair.newBuilder().setKey("vivaldi_coordinates").setValue( + VivaldiNode.coordinatesToString(coords4.build()))); + Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0).setVersion(1).setUuid( + "osd4").setName("osd4").setData(sdm.clone()); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setVersion(1).setUuid("osd4").setName("osd4").setData(sdm)); + + sdm = ServiceDataMap.newBuilder(); + sdm.addData(KeyValuePair.newBuilder().setKey("vivaldi_coordinates").setValue( + VivaldiNode.coordinatesToString(coords5.build()))); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD).setLastUpdatedS(0) + .setVersion(1).setUuid("osd5").setName("osd5").setData(sdm)); + + UUIDResolver.addTestMapping("osd1", "bla.xtreemfs.zib.de", 2222, false); + UUIDResolver.addTestMapping("osd2", "www.heise.de", 2222, false); + UUIDResolver.addTestMapping("osd3", "blub.xtreemfs.zib.de", 2222, false); + UUIDResolver.addTestMapping("osd4", "csr-pc29.zib.de", 2222, false); + UUIDResolver.addTestMapping("osd5", "download.xtreemfs.com", 2222, false); + + InetAddress clientAddr = InetAddress.getByName("xtreem.zib.de"); + VivaldiCoordinates clientCoordinates = VivaldiCoordinates.newBuilder().setXCoordinate(0.0) + .setYCoordinate(0.0).setLocalError(0.1).build(); + + ServiceSet.Builder sortedList = policy.getOSDs(osds, clientAddr, clientCoordinates, null, 0); + + assertEquals("osd3", sortedList.getServices(0).getUuid()); + assertEquals("osd2", sortedList.getServices(1).getUuid()); + assertEquals("osd5", sortedList.getServices(2).getUuid()); + assertEquals("osd4", sortedList.getServices(3).getUuid()); + assertEquals("osd1", sortedList.getServices(4).getUuid()); + } + + @Test + public void testSortHostRoundRobinPolicy() throws Exception { + + SortHostRoundRobinPolicy policy = new SortHostRoundRobinPolicy(); + + ServiceSet.Builder osds = ServiceSet.newBuilder(); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(System.currentTimeMillis() / 1000 - 1000).setName("osd1").setVersion(1) + .setUuid("osd1").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(System.currentTimeMillis() / 1000 - 5000).setName("osd2").setVersion(1) + .setUuid("osd2").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(System.currentTimeMillis() / 1000 - 1000).setName("osd3").setVersion(1) + .setUuid("osd3").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(System.currentTimeMillis() / 1000 - 1000).setName("osd4").setVersion(1) + .setUuid("osd4").setData(getDefaultServiceDataMap())); + osds.addServices(Service.newBuilder().setType(ServiceType.SERVICE_TYPE_OSD) + .setLastUpdatedS(System.currentTimeMillis() / 1000 - 1000).setName("osd5").setVersion(1) + .setUuid("osd5").setData(getDefaultServiceDataMap())); + + UUIDResolver.addTestMapping("osd1", "test.xyz.org", 32640, false); + UUIDResolver.addTestMapping("osd2", "test.xyz.org", 32642, false); + UUIDResolver.addTestMapping("osd3", "test2.xyz.org", 32640, false); + UUIDResolver.addTestMapping("osd4", "test2.xyz.org", 32642, false); + UUIDResolver.addTestMapping("osd5", "test3.xyz.org", 32640, false); + + ServiceSet.Builder sortedList = policy.getOSDs(osds); + + for (int i = 0; i < sortedList.getServicesCount()-1 ; i++) { + String host1 = new ServiceUUID(sortedList.getServices(i).getUuid()).getAddress().getHostName(); + String host2 = new ServiceUUID(sortedList.getServices(i + 1).getUuid()).getAddress().getHostName(); + assertNotSame(host1, host2); + } + } + + private static ServiceDataMap getDefaultServiceDataMap() { + return ServiceDataMap.newBuilder().build(); + } + + private static ServiceDataMap getServiceDataMap(ServiceStatus status) { + ServiceDataMap sdm = ServiceDataMap.newBuilder().addData(KeyValuePair.newBuilder() + .setKey(HeartbeatThread.STATUS_ATTR) + .setValue(String.valueOf(status.getNumber())).build()).build(); + return sdm; + } + +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/test/mrc/SetReadOnlyXattrTest.java b/java/servers/test/org/xtreemfs/test/mrc/SetReadOnlyXattrTest.java new file mode 100644 index 0000000..056c17a --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/mrc/SetReadOnlyXattrTest.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.mrc; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.net.InetSocketAddress; +import java.util.LinkedList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.clients.File; +import org.xtreemfs.common.clients.Volume; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.xtreemfs_set_read_only_xattrResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestEnvironment.Services; +import org.xtreemfs.test.TestHelper; + +public class SetReadOnlyXattrTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private MRCServiceClient client; + + private InetSocketAddress mrcAddress; + + private TestEnvironment testEnv; + + public SetReadOnlyXattrTest() { + Logging.start(SetupUtils.DEBUG_LEVEL); + } + + @Before + public void setUp() throws Exception { + // register an OSD at the directory service (needed in order to assign + // it to a new file on 'open') + + testEnv = new TestEnvironment(Services.DIR_CLIENT, Services.TIME_SYNC, Services.UUID_RESOLVER, + Services.MRC_CLIENT, Services.DIR_SERVICE, Services.MRC, Services.OSD); + testEnv.start(); + + mrcAddress = testEnv.getMRCAddress(); + client = testEnv.getMrcClient(); + } + + @After + public void tearDown() throws Exception { + testEnv.shutdown(); + Logging.logMessage(Logging.LEVEL_DEBUG, this, BufferPool.getStatus()); + } + + @Test + public void testSetReadOnlyXattrOperation() throws Exception { + final String uid = "root"; + final List gids = createGIDs("root"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + Auth passwd = Auth.newBuilder().setAuthType(AuthType.AUTH_PASSWORD).setAuthPasswd( + AuthPassword.newBuilder().setPassword("")).build(); + + StripingPolicy sp = SetupUtils.getStripingPolicy(1, 1024); + + Client c = new Client(new InetSocketAddress[] { testEnv.getDIRAddress() }, 15000, 60000, null); + c.start(); + c.createVolume(volumeName, passwd, uc, sp, AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, 0777); + + Volume v = c.getVolume(volumeName, uc); + Path p = new Path("foo.txt"); + + File f = v.getFile(p.toString()); + f.createFile(); + f.setReadOnly(false); + + final String fileId = f.getxattr("xtreemfs.file_id"); + + + xtreemfs_set_read_only_xattrResponse response = null; + + // set read_only to true an check if it's really set to true + RPCResponse r1 = null; + try { + r1 = client.xtreemfs_set_read_only_xattr(mrcAddress, passwd, uc, fileId, true); + response = r1.get(); + } finally { + r1.freeBuffers(); + } + + assertTrue(response.getWasSet()); + assertTrue(f.isReadOnly()); + + // do it the other way around + f.setReadOnly(true); + assertTrue(f.isReadOnly()); + RPCResponse r2 = null; + + try { + r2 = client.xtreemfs_set_read_only_xattr(mrcAddress, passwd, uc, fileId, false); + response = r2.get(); + } finally { + r2.freeBuffers(); + } + + assertTrue(response.getWasSet()); + assertFalse(f.isReadOnly()); + } + + private static List createGIDs(String gid) { + List list = new LinkedList(); + list.add(gid); + return list; + } + + private static UserCredentials createUserCredentials(String uid, List gids) { + return UserCredentials.newBuilder().setUsername(uid).addAllGroups(gids).build(); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/mrc/SetReplicaUpdatePolicyTest.java b/java/servers/test/org/xtreemfs/test/mrc/SetReplicaUpdatePolicyTest.java new file mode 100644 index 0000000..30558b4 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/mrc/SetReplicaUpdatePolicyTest.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.mrc; + +import static org.junit.Assert.assertTrue; + +import java.net.InetSocketAddress; +import java.util.LinkedList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.clients.File; +import org.xtreemfs.common.clients.Volume; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.mrc.utils.Path; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.XAttr; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestEnvironment.Services; +import org.xtreemfs.test.TestHelper; + +public class SetReplicaUpdatePolicyTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private MRCServiceClient client; + + private InetSocketAddress mrcAddress; + + private TestEnvironment testEnv; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL); + } + + @Before + public void setUp() throws Exception { + // register an OSD at the directory service (needed in order to assign + // it to a new file on 'open') + + testEnv = new TestEnvironment(Services.DIR_CLIENT, Services.TIME_SYNC, Services.UUID_RESOLVER, + Services.MRC_CLIENT, Services.DIR_SERVICE, Services.MRC, Services.OSD, Services.OSD); + testEnv.start(); + + mrcAddress = testEnv.getMRCAddress(); + client = testEnv.getMrcClient(); + } + + @After + public void tearDown() throws Exception { + testEnv.shutdown(); + Logging.logMessage(Logging.LEVEL_DEBUG, this, BufferPool.getStatus()); + } + + @Test + public void testSetReplicaUpdatePolicyOperation() throws Exception { + final String uid = "root"; + final List gids = createGIDs("root"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + Auth passwd = Auth.newBuilder().setAuthType(AuthType.AUTH_PASSWORD).setAuthPasswd(AuthPassword.newBuilder().setPassword("")).build(); + + StripingPolicy sp = SetupUtils.getStripingPolicy(1, 1024); + + Client c = new Client(new InetSocketAddress[]{testEnv.getDIRAddress()}, 15000, 60000, null); + c.start(); + c.createVolume(volumeName, passwd, uc, sp, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, 0777 ); + + + Volume v = c.getVolume(volumeName, uc); + Path p = new Path("foo.txt"); + + + + File f = v.getFile(p.toString()); + f.createFile(); + f.setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE); + + final String fileId = f.getxattr("xtreemfs.file_id"); + + List xattrs = null; + String replicaUpdatePolicy = null; + + //REPL_UPDATE_PC_NONE + client.xtreemfs_set_replica_update_policy(mrcAddress, passwd, uc, fileId, + ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE).get(); + assert(f.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE)); + + //REPL_UPDATE_PC_RONLY + client.xtreemfs_set_replica_update_policy(mrcAddress, passwd, uc, fileId, + ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY).get(); + assert(f.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY)); + + //REPL_UPDATE_PC_WARONE + client.xtreemfs_set_replica_update_policy(mrcAddress, passwd, uc, fileId, + ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE).get(); + assert(f.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE)); + + //REPL_UPDATE_PC_WQRQ + client.xtreemfs_set_replica_update_policy(mrcAddress, passwd, uc, fileId, + ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ).get(); + assert(f.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ)); + + } + + @Test + public void testDeniedRequestforRwWithStriping() throws Exception { + final String uid = "root"; + final List gids = createGIDs("root"); + final String volumeName = "testVolume"; + final UserCredentials uc = createUserCredentials(uid, gids); + Auth passwd = Auth.newBuilder().setAuthType(AuthType.AUTH_PASSWORD) + .setAuthPasswd(AuthPassword.newBuilder().setPassword("")).build(); + + StripingPolicy sp = SetupUtils.getStripingPolicy(2, 128); + + Client c = new Client(new InetSocketAddress[] { testEnv.getDIRAddress() }, 15000, 60000, null); + c.start(); + c.createVolume(volumeName, passwd, uc, sp, AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, 0777); + + Volume v = c.getVolume(volumeName, uc); + Path p = new Path("foo.txt"); + + File f = v.getFile(p.toString()); + f.createFile(); + f.setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE); + + final String fileId = f.getxattr("xtreemfs.file_id"); + + try { + // try to set replica update policy to WQRQ (expect PBRPCException). + client.xtreemfs_set_replica_update_policy(mrcAddress, passwd, uc, fileId, + ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ).get(); + assertTrue(false); + } catch (PBRPCException e) { + // replica update policy should not changed + assertTrue(f.getReplicaUpdatePolicy().equals(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE)); + } + } + + + + private static List createGIDs(String gid) { + List list = new LinkedList(); + list.add(gid); + return list; + } + + private static UserCredentials createUserCredentials(String uid, List gids) { + return UserCredentials.newBuilder().setUsername(uid).addAllGroups(gids).build(); + } + + private static StripingPolicy getDefaultStripingPolicy() { + return StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0).setStripeSize( + 1000).setWidth(1).build(); + } + + private static VivaldiCoordinates getDefaultCoordinates() { + return VivaldiCoordinates.newBuilder().setXCoordinate(0).setYCoordinate(0).setLocalError(0).build(); + } +} diff --git a/java/servers/test/org/xtreemfs/test/mrc/SnapshotTest.java b/java/servers/test/org/xtreemfs/test/mrc/SnapshotTest.java new file mode 100644 index 0000000..4d66aad --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/mrc/SnapshotTest.java @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2010-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.mrc; + +import java.io.IOException; +import java.io.Serializable; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntry; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.timestampResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestEnvironment.Services; +import org.xtreemfs.test.TestHelper; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; + +/** + * XtreemFS MRC test + * + * @author stender + */ +public class SnapshotTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + static class TreeEntry implements Comparable, Serializable { + + private String name; + + private boolean dir; + + public TreeEntry(String name, boolean dir) { + this.name = name; + this.dir = dir; + } + + public String getName() { + return name; + } + + public boolean isDir() { + return dir; + } + + public String toString() { + return name; + } + + @Override + public int compareTo(TreeEntry o) { + return name.compareTo(o.name); + } + + } + + private static Random rnd = new Random(); + + private MRCServiceClient client; + + private InetSocketAddress mrcAddress; + + private String uid; + + private List gids; + + private UserCredentials uc; + + private TestEnvironment testEnv; + + public SnapshotTest() { + Logging.start(SetupUtils.DEBUG_LEVEL); + } + + @Before + public void setUp() throws Exception { + uid = "userXY"; + gids = createGIDs("groupZ"); + + uc = createUserCredentials(uid, gids); + + // register an OSD at the directory service (needed in order to assign + // it to a new file on 'open') + + testEnv = new TestEnvironment(Services.DIR_CLIENT, Services.TIME_SYNC, Services.UUID_RESOLVER, + Services.MRC_CLIENT, Services.DIR_SERVICE, Services.MRC, Services.OSD); + testEnv.start(); + + mrcAddress = testEnv.getMRCAddress(); + client = testEnv.getMrcClient(); + } + + @After + public void tearDown() throws Exception { + testEnv.shutdown(); + Logging.logMessage(Logging.LEVEL_DEBUG, this, BufferPool.getStatus()); + } + + @Test + public void testSnapshots() throws Exception { + + final int maxFilesPerDir = 4; + final int numDirs = 20; + final String volumeName = "testVolume"; + + final int numSnaps = 50; + + // create a volume + invokeSync(client.xtreemfs_mkvol(mrcAddress, RPCAuthentication.authNone, uc, + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, getDefaultStripingPolicy(), "", 0775, + volumeName, "", "", new LinkedList(), 0)); + + // enable snapshots on the volume + invokeSync(client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, volumeName, "", + "xtreemfs.snapshots_enabled", "", ByteString.copyFrom("true".getBytes()), 0)); + + // create a random tree with some files and directories + SortedSet tree = createRandomTree(numDirs, maxFilesPerDir); + + // ObjectOutputStream out = new ObjectOutputStream(new + // FileOutputStream("/tmp/tree.bin")); + // out.writeObject(tree); + // out.close(); + + // ObjectInputStream in = new ObjectInputStream(new + // FileInputStream("/tmp/tree.bin")); + // tree = (SortedSet) in.readObject(); + // in.close(); + + for (TreeEntry path : tree) + if (path.isDir()) + invokeSync(client.mkdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, + path.getName(), 0775)); + else + invokeSync(client.open(mrcAddress, RPCAuthentication.authNone, uc, volumeName, + path.getName(), FileAccessManager.O_CREAT, 0775, 0, getDefaultCoordinates())); + + assertTree(tree, volumeName, "", true); + + // create and test a recursive snapshot from the root directory + invokeSync(createSnapshot(volumeName, "", "rootSnap1", true)); + assertTree(tree, volumeName + "@rootSnap1", "", true); + + // create and test a non-recursive snapshot from the root directory + invokeSync(createSnapshot(volumeName, "", "rootSnap2", false)); + assertTree(tree, volumeName + "@rootSnap2", "", false); + + // create and test some random snapshots + Map snaps = new HashMap(); + for (int i = 0; i < numSnaps; i++) { + + String dir = getRandomDir(tree); + boolean recursive = rnd.nextBoolean(); + + snaps.put(i, new Object[] { dir, recursive }); + + invokeSync(createSnapshot(volumeName, dir, i + "", recursive)); + assertTree(tree, volumeName + "@" + i, dir, recursive); + } + + // delete everything + + ArrayList entries = new ArrayList(tree); + Collections.sort(entries, new Comparator() { + public int compare(TreeEntry o1, TreeEntry o2) { + return o2.getName().length() - o1.getName().length(); + } + }); + + for (TreeEntry path : entries) + if (path.isDir()) + invokeSync(client.rmdir(mrcAddress, RPCAuthentication.authNone, uc, volumeName, + path.getName())); + else + invokeSync(client.unlink(mrcAddress, RPCAuthentication.authNone, uc, volumeName, + path.getName())); + + TreeSet emptyTree = new TreeSet(); + + // check the empty tree + assertTree(emptyTree, volumeName, "", true); + + // check the old snapshot trees + for (Entry snap : snaps.entrySet()) + assertTree(tree, volumeName + "@" + snap.getKey(), (String) snap.getValue()[0], + (Boolean) snap.getValue()[1]); + } + + private RPCResponse createSnapshot(String vol, String dir, String name, + boolean recursive) throws Exception { + String cmd = "c" + (recursive ? "r" : "") + " " + name; + return client.setxattr(mrcAddress, RPCAuthentication.authNone, uc, vol, dir, "xtreemfs.snapshots", + "", ByteString.copyFrom(cmd.getBytes()), 0); + } + + private void assertTree(SortedSet tree, String volume, String path, boolean recursive) + throws Exception { + + SortedSet subtree = getSubtree(tree, path, recursive); + + int offs = 0; + for (TreeEntry entry : subtree) { + + if (path.equals(entry.getName())) + offs = entry.getName().length(); + + String relPath = entry.getName().substring(offs); + if (relPath.startsWith("/")) + relPath = relPath.substring(1); + + invokeSync(client.getattr(mrcAddress, RPCAuthentication.authNone, uc, volume, relPath, -1)); + + } + + checkDir(volume, subtree, "", path, recursive); + } + + private void checkDir(String volume, SortedSet subtree, String relPath, String fullPath, + boolean recursive) throws Exception { + + DirectoryEntries entries = invokeSync(client.readdir(mrcAddress, RPCAuthentication.authNone, uc, + volume, relPath, -1, 1000, false, 0)); + for (DirectoryEntry entry : entries.getEntriesList()) { + + boolean isDir = (entry.getStbuf().getMode() & SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_S_IFDIR.getNumber()) > 0; + + if (!entry.getName().equals(".") && !entry.getName().equals("..")) { + + if (!subtree.contains(new TreeEntry(fullPath + (fullPath.equals("") ? "" : "/") + + entry.getName(), isDir))) + throw new Exception(entry.getName() + " not contained in subtree"); + + if (recursive && isDir) + checkDir(volume, subtree, relPath + (relPath.equals("") ? "" : "/") + entry.getName(), + fullPath + (fullPath.equals("") ? "" : "/") + entry.getName(), recursive); + + } + + } + } + + private static StripingPolicy getDefaultStripingPolicy() { + return StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0) + .setStripeSize(1000).setWidth(1).build(); + } + + private static List createGIDs(String gid) { + List list = new LinkedList(); + list.add(gid); + return list; + } + + private static T invokeSync(RPCResponse response) throws PBRPCException, + IOException, InterruptedException { + + try { + return response.get(); + } finally { + response.freeBuffers(); + } + } + + private static String createRandomString(int minLength, int maxLength) { + + char[] chars = new char[(int) (rnd.nextDouble() * (maxLength + 1)) + minLength]; + for (int i = 0; i < chars.length; i++) + chars[i] = (char) (rnd.nextDouble() * 26 + 65); + + return new String(chars); + } + + private static SortedSet createRandomTree(int numDirs, int maxFilesPerDir) { + + SortedSet tree = new TreeSet(); + + // create the directory tree + String currentPath = ""; + for (int i = 0; i < numDirs; i++) { + + if ("".equals(currentPath) || rnd.nextBoolean()) + currentPath = createRandomString(1, 10); + else + currentPath = currentPath + "/" + createRandomString(1, 10); + + tree.add(new TreeEntry(currentPath, true)); + } + + // populate the directory tree with files + List files = new LinkedList(); + for (TreeEntry entry : tree) + for (int i = 0; i < rnd.nextDouble() * (maxFilesPerDir + 1); i++) + files.add(new TreeEntry(entry.getName() + "/" + createRandomString(1, 10) + ".xyz", false)); + + tree.addAll(files); + return tree; + } + + private static SortedSet modifyTree(SortedSet originalTree, double deleteRate, + double createRate, double dirCreateRate, int maxFilesPerDir) { + + SortedSet result = new TreeSet(originalTree.comparator()); + for (TreeEntry entry : originalTree) { + int index = entry.getName().lastIndexOf('/'); + if (index == -1) + index = 0; + if (!entry.isDir() && !result.contains(new TreeEntry(entry.getName().substring(0, index), true))) + continue; + if (rnd.nextDouble() >= deleteRate) { + result.add(entry); + if (entry.isDir()) { + if (rnd.nextDouble() <= dirCreateRate) { + result.add(new TreeEntry(createRandomString(1, 10), true)); + for (int i = 0; i < (int) (rnd.nextDouble() * 5); i++) + result.add(new TreeEntry(createRandomString(1, 10) + ".xyz", false)); + } else if (rnd.nextDouble() < createRate) + result.add(new TreeEntry(createRandomString(1, 10) + ".xyz", false)); + } + } + } + + return result; + } + + private static SortedSet getSubtree(SortedSet tree, String path, boolean recursive) { + + String[] pathComps = path.equals("") ? new String[0] : path.split("/"); + + SortedSet subTree = new TreeSet(tree.comparator()); + + for (TreeEntry entry : tree) { + + String[] comps = entry.getName().split("/"); + + // include top-level dir + if (equals(comps, pathComps)) { + subTree.add(entry); + + } else if (recursive) { + + if (startsWith(comps, pathComps)) + subTree.add(entry); + + } else { + + if (startsWith(comps, pathComps) && comps.length - pathComps.length == 1) + subTree.add(entry); + + } + + } + + return subTree; + } + + private static boolean equals(String[] path1, String[] path2) { + + if (path1.length != path2.length) + return false; + + for (int i = 0; i < path1.length; i++) + if (!(path1[i].equals(path2[i]))) + return false; + + return true; + } + + private static boolean startsWith(String[] path1, String[] path2) { + + if (path1.length < path2.length) + return false; + + for (int i = 0; i < path2.length; i++) + if (!(path2[i].equals(path1[i]))) + return false; + + return true; + } + + private static String getRandomDir(SortedSet tree) { + + List dirs = new ArrayList(tree.size()); + Iterator it = tree.iterator(); + while (it.hasNext()) { + TreeEntry entry = it.next(); + if (entry.isDir()) + dirs.add(entry.getName()); + } + + return dirs.get((int) (rnd.nextDouble() * dirs.size())); + } + + private static void printTree(SortedSet tree) { + for (TreeEntry entry : tree) + System.out.println(entry); + } + + private static UserCredentials createUserCredentials(String uid, List gids) { + return UserCredentials.newBuilder().setUsername(uid).addAllGroups(gids).build(); + } + + private static VivaldiCoordinates getDefaultCoordinates() { + return VivaldiCoordinates.newBuilder().setXCoordinate(0).setYCoordinate(0).setLocalError(0).build(); + } +} diff --git a/java/servers/test/org/xtreemfs/test/mrc/VersionedXLocSetTest.java b/java/servers/test/org/xtreemfs/test/mrc/VersionedXLocSetTest.java new file mode 100644 index 0000000..7ea6b4e --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/mrc/VersionedXLocSetTest.java @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2013 by Johannes Dillmann, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.test.mrc; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT; +import static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY; +import static org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.AdminFileHandle; +import org.xtreemfs.common.libxtreemfs.AdminVolume; +import org.xtreemfs.common.libxtreemfs.ClientFactory; +import org.xtreemfs.common.libxtreemfs.Helper; +import org.xtreemfs.common.libxtreemfs.Options; +import org.xtreemfs.common.libxtreemfs.Volume; +import org.xtreemfs.common.libxtreemfs.exceptions.AddressToUUIDNotFoundException; +import org.xtreemfs.common.libxtreemfs.exceptions.InvalidViewException; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.pbrpc.server.RPCServerRequest; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.mrc.metadata.ReplicationPolicy; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.osd.OSDRequestDispatcher; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDSelectionPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; + +public class VersionedXLocSetTest { + private static TestEnvironment testEnv; + + private static UserCredentials userCredentials; + + private static Auth auth; + + private static AdminClient client; + + private static Options options; + + private static String mrcAddress; + + private static String dirAddress; + + private static StripingPolicy defaultStripingPolicy; + + private static OSD[] osds; + + private static OSDConfig[] configs; + + private final static int NUM_OSDS = 5; + + private static int LEASE_TIMEOUT_MS; + + @BeforeClass + public static void initializeTest() throws Exception { + System.out.println("TEST: " + VersionedXLocSetTest.class.getSimpleName()); + + // cleanup + FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); + Logging.start(Logging.LEVEL_WARN); + // Logging.start(Logging.LEVEL_INFO); + // Logging.start(Logging.LEVEL_DEBUG); + + testEnv = new TestEnvironment( + new TestEnvironment.Services[] { TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.UUID_RESOLVER, TestEnvironment.Services.RPC_CLIENT, + TestEnvironment.Services.DIR_SERVICE, TestEnvironment.Services.DIR_CLIENT, + TestEnvironment.Services.MRC, TestEnvironment.Services.MRC_CLIENT, + TestEnvironment.Services.OSD_CLIENT }); + + testEnv.start(); + + // setup osds + osds = new OSD[NUM_OSDS]; + configs = SetupUtils.createMultipleOSDConfigs(NUM_OSDS); + for (int i = 0; i < NUM_OSDS; i++) { + osds[i] = new OSD(configs[i]); + } + + dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + defaultStripingPolicy = StripingPolicy.newBuilder().setType(StripingPolicyType.STRIPING_POLICY_RAID0) + .setStripeSize(128).setWidth(1).build(); + + userCredentials = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + auth = RPCAuthentication.authNone; + + options = new Options(); + + options.setMaxTries(2); + + client = ClientFactory.createAdminClient(dirAddress, userCredentials, null, options); + client.start(); + + LEASE_TIMEOUT_MS = configs[0].getFleaseLeaseToMS(); + } + + @AfterClass + public static void tearDown() throws Exception { + for (int i = 0; i < osds.length; i++) { + if (osds[i] != null) { + osds[i].shutdown(); + } + } + testEnv.shutdown(); + client.shutdown(); + } + + /** + * Test to ensure, that either a InvalidViewException is thrown if a clients tries to read from a replica, that has + * been removed when view renewals are disabled or the view is renewed transparently. + */ + @Test + public void testViewsOnReplicaRemoval() throws Exception { + String volumeName = "testViewsOnReplicaRemoval"; + + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + AdminVolume volume = client.openVolume(volumeName, null, options); + + // Setup a full read only replica with sequential access strategy. + int repl_flags = ReplicationFlags.setFullReplica(ReplicationFlags.setSequentialStrategy(0)); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY, 2, + repl_flags); + + volume.close(); + + removeReadOutdated(volumeName, "/testfile-with-renewal", true); + removeReadOutdated(volumeName, "/testfile-wo-renewal", false); + } + + + /** + * Test to ensure the appropriate error (invalid view) is returned, when the WqRq policy is active and a client + * tries to read, and thus form an majority, based on an outdated XLocSet. TODO(jdillmann): Should test if flease + * transmits the views, when the removed replica does miss the .version_state file + */ + + /** + * Remove the primary replica and provoke an invalid view error by accessing the file with an outdated xLocSet. + * + * @param volumeName + * @param fileName + * @param renewView + * @throws Exception + */ + private void removeReadOutdated(String volumeName, String fileName, boolean renewView) throws Exception { + AdminVolume volume = client.openVolume(volumeName, null, options); + + // Open the testfile and write some bytes not "0". + AdminFileHandle fileHandle = volume.openFile(userCredentials, fileName, + Helper.flagsToInt(SYSTEM_V_FCNTL_H_O_CREAT, SYSTEM_V_FCNTL_H_O_RDWR), 0777); + + int count = 256 * 1024; + ReusableBuffer data = SetupUtils.generateData(count, (byte) 1); + + fileHandle.write(userCredentials, data.createViewBuffer().getData(), count, 0); + fileHandle.close(); + + // Give XtreemFS some time to replicate the data. This is only needed for the RONLY replication. + Thread.sleep(5 * 1000); + + // Open a fileHandle again and keep it open while removing the primary replica from another client. + fileHandle = volume.openFile(userCredentials, fileName, Helper.flagsToInt(SYSTEM_V_FCNTL_H_O_RDONLY)); + + // Get a replica to remove. This will probably be on a backup. If the replica is on the primary the test will + // fail, because lease returnal isn't available yet and the second request will time out due to redirection + // errors. + List replicas = fileHandle.getReplicasList(); + Replica replica = replicas.get(1); + int prevReplicaCount = fileHandle.getReplicasList().size(); + + // Since striping is disabled there should be only one OSD for this certain replica. + assertEquals(1, replica.getOsdUuidsCount()); + + // Use another Volume instance to remove the replica from the OSD. + AdminVolume controlVolume = client.openVolume(volumeName, null, options); + controlVolume.removeReplica(userCredentials, fileName, replica.getOsdUuids(0)); + AdminFileHandle controlFile = controlVolume.openFile(userCredentials, fileName, + Helper.flagsToInt(SYSTEM_V_FCNTL_H_O_RDONLY)); + + assertEquals(controlFile.getReplicasList().size(), prevReplicaCount - 1); + + controlFile.close(); + controlVolume.close(); + + // Reading from the previous fileHandle with the outdated xLocSet has to result in an error. + try { + if (renewView) { + readWithViewRenewal(fileHandle); + } else { + readInvalidView(fileHandle); + } + } finally { + fileHandle.close(); + volume.close(); + } + } + + /** + * Test to ensure, that either a InvalidViewException is thrown when view renewals are disabled or the view is + * renewed transparently, after a new replicas is added and a client tries to read with an outdated view. + */ + @Test + public void testViewsOnReplicaAdding() throws Exception { + String volumeName = "testViewsOnReplicaAdding"; + + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + AdminVolume volume = client.openVolume(volumeName, null, options); + + volume.setReplicaSelectionPolicy( + userCredentials, + Helper.policiesToString(new OSDSelectionPolicyType[] { OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_UUID })); + + // Setup a full read only replica with sequential access strategy. + int repl_flags = ReplicationFlags.setFullReplica(ReplicationFlags.setSequentialStrategy(0)); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY, 2, + repl_flags); + volume.close(); + + addReadOutdated(volumeName, "/testfile-with-renewal", true); + addReadOutdated(volumeName, "/testfile-wo-renewal", false); + } + + + /** + * Test to ensure the appropriate error (invalid view) is returned, when new replicas are added to a file with the + * WqRw policy and a client tries to get access with an outdated xLocSet. TODO(jdillmann): Should test if flease + * transmits the views, when the removed replica does miss the .version_state file + */ + + /** + * Add additional replicas and and provoke an invalid view error by accessing the file with an outdated xLocSet. + * + * @param volumeName + * @param fileName + * @param renewView + * @throws Exception + */ + private void addReadOutdated(String volumeName, String fileName, boolean renewView) throws Exception { + // Open the testfile and write some data to it. + AdminVolume outdatedVolume = client.openVolume(volumeName, null, options); + AdminFileHandle outdatedFile = outdatedVolume.openFile(userCredentials, fileName, + Helper.flagsToInt(SYSTEM_V_FCNTL_H_O_CREAT, SYSTEM_V_FCNTL_H_O_RDWR), 0777); + + ReusableBuffer data = SetupUtils.generateData(256, (byte) 1); + outdatedFile.write(userCredentials, data.createViewBuffer().getData(), 256, 0); + outdatedFile.close(); + + // Give XtreemFS some time to replicate the data. This is only needed for the RONLY replication. + Thread.sleep(5 * 1000); + + // Open a fileHandle again and keep it open while add replicas from another client. + outdatedFile = outdatedVolume.openFile(userCredentials, fileName, Helper.flagsToInt(SYSTEM_V_FCNTL_H_O_RDONLY)); + + // Use another Volume instance to add additional replicas. + AdminVolume volume = client.openVolume(volumeName, null, options); + addReplicas(volume, fileName, 1); + volume.close(); + + // Reading from the previous fileHandle with the outdated xLocSet has to result in an error. + try { + if (renewView) { + readWithViewRenewal(outdatedFile); + } else { + readInvalidView(outdatedFile); + } + } finally { + outdatedFile.close(); + outdatedVolume.close(); + } + } + + /** + * This test covers the case, that a number of replicas is added which will form a new majority. It has to be + * ensured that the correct data is returned, even if only new replicas are accessed. + */ + @Test + public void testAddMajority() throws Exception { + String volumeName = "testAddMajority"; + String fileName = "/testfile"; + + SuspendableOSDRequestDispatcher[] suspOSDs = replaceWithSuspendableOSDs(0, 2); + + // Create and open the volume and set a replication factor of 2. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + AdminVolume volume = client.openVolume(volumeName, null, options); + + // Ensure the selected OSDs and replicas a sorted ascending by UUIDs. + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ, 2, 0); + volume.setOSDSelectionPolicy( + userCredentials, + Helper.policiesToString(new OSDSelectionPolicyType[] { + OSDSelectionPolicyType.OSD_SELECTION_POLICY_FILTER_DEFAULT, + OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_UUID })); + volume.setReplicaSelectionPolicy( + userCredentials, + Helper.policiesToString(new OSDSelectionPolicyType[] { OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_UUID })); + + // Create the testfile by writing some bytes to it. + AdminFileHandle file = volume.openFile(userCredentials, fileName, + Helper.flagsToInt(SYSTEM_V_FCNTL_H_O_RDWR, SYSTEM_V_FCNTL_H_O_CREAT), 0777); + ReusableBuffer dataIn = SetupUtils.generateData(256 * 1024, (byte) 1); + file.write(userCredentials, dataIn.getData(), 256 * 1024, 0); + dataIn.clear(); + file.close(); + + // Add another 3 replicas that form a majority by itself. + addReplicas(volume, fileName, 3); + + // Ensure no primary can exist, by waiting until the lease timed out. + Thread.sleep(LEASE_TIMEOUT_MS + 500); + + // Reverse the replica selection policy to ensure subsequent requests will be directed to the recently added + // replicas. + volume.setReplicaSelectionPolicy( + userCredentials, + Helper.policiesToString(new OSDSelectionPolicyType[] { + OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_UUID, + OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_REVERSE })); + + // Suspend the original 2 first OSDs to ensure only the recently added replicas can be accessed. + suspOSDs[0].suspend(); + suspOSDs[1].suspend(); + + // Read from the file again and ensure the data is consistent. + file = volume.openFile(userCredentials, fileName, Helper.flagsToInt(SYSTEM_V_FCNTL_H_O_RDWR)); + byte[] dataOut = new byte[1]; + file.read(userCredentials, dataOut, 1, 0); + file.close(); + volume.close(); + + assertEquals(dataOut[0], (byte) 1); + + resetSuspendableOSDs(suspOSDs, 0); + } + + /** + * This test covers the removal of replicas forming a majority. It has to be ensured that the remaining replicas are + * up to date and the correct (last written) data is returned. + */ + @Test + public void testRemoveMajority() throws Exception { + String volumeName = "testRemoveMajority"; + String fileName = "/testfile"; + + SuspendableOSDRequestDispatcher[] suspOSDs = replaceWithSuspendableOSDs(0, 2); + + // Create and open the volume and set a replication factor of 5. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + AdminVolume volume = client.openVolume(volumeName, null, options); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ, 5, 0); + + // Ensure the selected OSDs are sorted ascending, and the list of replicas is sorted decending by UUIDs. + volume.setOSDSelectionPolicy( + userCredentials, + Helper.policiesToString(new OSDSelectionPolicyType[] { + OSDSelectionPolicyType.OSD_SELECTION_POLICY_FILTER_DEFAULT, + OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_UUID })); + volume.setReplicaSelectionPolicy( + userCredentials, + Helper.policiesToString(new OSDSelectionPolicyType[] { + OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_UUID, + OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_REVERSE })); + + // Suspend the first 2 of the 5 replicas, to ensure they won't get updated when writing to the file. + suspOSDs[0].suspend(); + suspOSDs[1].suspend(); + + AdminFileHandle file = volume.openFile(userCredentials, fileName, + Helper.flagsToInt(SYSTEM_V_FCNTL_H_O_RDWR, SYSTEM_V_FCNTL_H_O_CREAT), 0777); + ReusableBuffer dataIn = SetupUtils.generateData(256 * 1024, (byte) 1); + file.write(userCredentials, dataIn.getData(), 256 * 1024, 0); + dataIn.clear(); + + // Resume the first 2 OSDs again. + suspOSDs[0].resume(); + suspOSDs[1].resume(); + + // Remove the last 3 OSDs, which have been updated by the last write. + List replicas = file.getReplicasList(); + for (int i = 0; i < 3; i++) { + Replica replica = replicas.get(i); + + // Since striping is disabled there can be only one OSD for this certain replica. + assertEquals(1, replica.getOsdUuidsCount()); + volume.removeReplica(userCredentials, fileName, replica.getOsdUuids(0)); + } + file.close(); + + // Read from the file again and ensure the data is consistent. + file = volume.openFile(userCredentials, fileName, Helper.flagsToInt(SYSTEM_V_FCNTL_H_O_RDONLY)); + byte[] dataOut = new byte[1]; + file.read(userCredentials, dataOut, 1, 0); + file.close(); + volume.close(); + + assertEquals(dataOut[0], (byte) 1); + + resetSuspendableOSDs(suspOSDs, 0); + } + + + /** + * This test covers the functionality in case of a network partition when not more then n+1/2 replicas are + * available. The majority has to be established both in the old and in the new replica set. + */ + @Test + public void testPartition() throws Exception { + String volumeName = "testPartition"; + String fileName = "/testfile"; + + SuspendableOSDRequestDispatcher[] suspOSDs = replaceWithSuspendableOSDs(0, 1); + + // Create and open the volume and set a replication factor of 4. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + AdminVolume volume = client.openVolume(volumeName, null, options); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ, 4, 0); + + // Ensure the selected OSDs are sorted ascending, and the list of replicas is sorted decending by UUIDs. + volume.setOSDSelectionPolicy( + userCredentials, + Helper.policiesToString(new OSDSelectionPolicyType[] { + OSDSelectionPolicyType.OSD_SELECTION_POLICY_FILTER_DEFAULT, + OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_UUID })); + volume.setReplicaSelectionPolicy( + userCredentials, + Helper.policiesToString(new OSDSelectionPolicyType[] { + OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_UUID, + OSDSelectionPolicyType.OSD_SELECTION_POLICY_SORT_REVERSE })); + + // Create the file an write some data to it. + AdminFileHandle file = volume.openFile(userCredentials, fileName, + Helper.flagsToInt(SYSTEM_V_FCNTL_H_O_RDWR, SYSTEM_V_FCNTL_H_O_CREAT), 0777); + ReusableBuffer dataIn = SetupUtils.generateData(256 * 1024, (byte) 1); + file.write(userCredentials, dataIn.getData(), 256 * 1024, 0); + dataIn.clear(); + + // Suspend the first OSD. The policy requires a majority of 3 for a replication factor of 4. + suspOSDs[0].suspend(); + + // Add another replica. + addReplicas(volume, fileName, 1); + + // Get the replica recently added from the replica list and remove it. + // Since a majority in both, the new and the old set, has to be ensured, only one OSD can be suspended. + List replicas = file.getReplicasList(); + Replica replica = replicas.get(0); + volume.removeReplica(userCredentials, fileName, replica.getOsdUuids(0)); + + file.close(); + volume.close(); + + resetSuspendableOSDs(suspOSDs, 0); + } + + private void addReplicas(Volume volume, String fileName, int replicaNumber) throws IOException, + InterruptedException { + + // Get a liste of suitable OSDs and ensure the requestes number of replicas can be added. + List osdUUIDs = volume.getSuitableOSDs(userCredentials, fileName, replicaNumber); + assertTrue(osdUUIDs.size() >= replicaNumber); + + // Save the current number of Replicas. + int currentReplicaNumber = volume.listReplicas(userCredentials, fileName).getReplicasCount(); + + // Get the default replication flags. + ReplicationPolicy rp = volume.getDefaultReplicationPolicy(userCredentials, "/"); + int repl_flags = rp.getFlags(); + + // Add the required number of new replicas. + for (int i = 0; i < replicaNumber; i++) { + Replica replica = Replica.newBuilder().setStripingPolicy(defaultStripingPolicy) + .setReplicationFlags(repl_flags).addOsdUuids(osdUUIDs.get(i)).build(); + volume.addReplica(userCredentials, fileName, replica); + } + + // Ensure the replicas have been added. + assertEquals(currentReplicaNumber + replicaNumber, volume.listReplicas(userCredentials, fileName) + .getReplicasCount()); + } + + private void readInvalidView(AdminFileHandle file) throws AddressToUUIDNotFoundException, IOException { + // Prevent view renewal. + int prevMaxViewRenewals = options.getMaxViewRenewals(); + options.setMaxViewRenewals(1); + + try { + byte[] dataOut = new byte[1]; + file.read(userCredentials, dataOut, 1, 0); + fail("InvalidViewException was expected."); + } catch (InvalidViewException e) { + // Everything is fine. The InvalidViewException is expected, because the client read with an outdated view. + } finally { + // Restore the settings. + options.setMaxViewRenewals(prevMaxViewRenewals); + } + } + + private void readWithViewRenewal(AdminFileHandle file) throws AddressToUUIDNotFoundException, IOException { + int prevMaxViewRenewals = options.getMaxViewRenewals(); + options.setMaxViewRenewals(2); + + try { + byte[] dataOut = new byte[1]; + file.read(userCredentials, dataOut, 1, 0); + } finally { + // Restore the settings. + options.setMaxViewRenewals(prevMaxViewRenewals); + } + } + + private SuspendableOSDRequestDispatcher[] replaceWithSuspendableOSDs(int start, int count) throws Exception { + SuspendableOSDRequestDispatcher[] suspOSDs = new SuspendableOSDRequestDispatcher[count]; + + for (int i = 0; i < count; i++) { + osds[start + i].shutdown(); + osds[start + i] = null; + + suspOSDs[i] = new SuspendableOSDRequestDispatcher(configs[start + i]); + suspOSDs[i].start(); + } + + return suspOSDs; + } + + private void resetSuspendableOSDs(SuspendableOSDRequestDispatcher[] suspOSDs, int start) { + for (int i = 0; i < suspOSDs.length; i++) { + suspOSDs[i].shutdown(); + osds[start + i] = new OSD(configs[start + i]); + } + } + + private class SuspendableOSDRequestDispatcher extends OSDRequestDispatcher { + private AtomicBoolean suspended; + + public SuspendableOSDRequestDispatcher(OSDConfig config) throws Exception { + super(config); + suspended = new AtomicBoolean(false); + } + + @Override + public void receiveRecord(RPCServerRequest rq) { + if (suspended.get()) { + // Drop the request. + rq.freeBuffers(); + } else { + super.receiveRecord(rq); + } + } + + public void suspend() { + suspended.set(true); + } + + public void resume() { + suspended.set(false); + } + } +} diff --git a/java/servers/test/org/xtreemfs/test/osd/AdvisoryLocksTest.java b/java/servers/test/org/xtreemfs/test/osd/AdvisoryLocksTest.java new file mode 100644 index 0000000..eb2f1a0 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/AdvisoryLocksTest.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; +import org.xtreemfs.osd.AdvisoryLock; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.Lock; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * Class for testing the NewOSD It uses the old OSDTest tests. It checks if the OSD works without replicas neither + * striping + * + * @author bjko + */ +public class AdvisoryLocksTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static ServiceUUID serverID; + + private static FileCredentials fcred; + + private static String fileId; + + private static Capability cap; + + private static OSDConfig osdConfig; + + private OSDServiceClient osdClient; + + private TestEnvironment testEnv; + + @BeforeClass + public static void initializeTest() throws Exception { + + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + + // startup: DIR + testEnv = new TestEnvironment( + new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.OSD_CLIENT, + TestEnvironment.Services.OSD }); + testEnv.start(); + + + synchronized (this) { + try { + this.wait(50); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + + osdClient = testEnv.getOSDClient(); + osdConfig = testEnv.getOSDConfig(); + serverID = osdConfig.getUUID(); + + fileId = "ABCDEF:1"; + cap = new Capability(fileId, 0, 60, System.currentTimeMillis(), "", 0, false, + SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, osdConfig.getCapabilitySecret()); + + Replica r = Replica.newBuilder().setReplicationFlags(0).setStripingPolicy(SetupUtils.getStripingPolicy(1, 2)) + .addOsdUuids(serverID.toString()).build(); + XLocSet xloc = XLocSet.newBuilder().setReadOnlyFileSize(0).setReplicaUpdatePolicy("").addReplicas(r) + .setVersion(1).build(); + + fcred = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xloc).build(); + } + + @After + public void tearDown() throws Exception { + testEnv.shutdown(); + } + + @Test + public void testAcquireCheckReleaseLock() throws Exception { + + Lock request = Lock.newBuilder().setClientPid(1).setClientUuid("test").setExclusive(true).setOffset(100) + .setLength(AdvisoryLock.LENGTH_LOCK_TO_EOF).build(); + RPCResponse r = osdClient.xtreemfs_lock_acquire(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + Lock l = r.get(); + + assertEquals("test", l.getClientUuid()); + assertEquals(1, l.getClientPid()); + + Lock checkRq = request.toBuilder().setClientPid(2).setLength(1).build(); + r = osdClient.xtreemfs_lock_check(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, checkRq); + l = r.get(); + + assertEquals("test", l.getClientUuid()); + assertEquals(1, l.getClientPid()); + + RPCResponse r2 = osdClient.xtreemfs_lock_release(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + r2.get(); + + } + + @Test + public void testAcquireCheckReleaseLockRange01() throws Exception { + + Lock request = Lock.newBuilder().setClientPid(1).setClientUuid("test").setExclusive(true).setOffset(0) + .setLength(1).build(); + RPCResponse r = osdClient.xtreemfs_lock_acquire(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + Lock l = r.get(); + + assertEquals("test", l.getClientUuid()); + assertEquals(1, l.getClientPid()); + + Lock checkRq = request.toBuilder().setClientPid(2).setLength(0).setExclusive(false).build(); + r = osdClient.xtreemfs_lock_check(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, checkRq); + l = r.get(); + + assertEquals("test", l.getClientUuid()); + assertEquals(1, l.getClientPid()); + assertEquals(0, l.getOffset()); + assertEquals(1, l.getLength()); + assertTrue(l.getExclusive()); + + RPCResponse r2 = osdClient.xtreemfs_lock_release(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + r2.get(); + + } + + @Test + public void testAcquireModify() throws Exception { + + Lock request = Lock.newBuilder().setClientPid(1).setClientUuid("test").setExclusive(true).setOffset(100) + .setLength(AdvisoryLock.LENGTH_LOCK_TO_EOF).build(); + RPCResponse r = osdClient.xtreemfs_lock_acquire(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + Lock l = r.get(); + + assertEquals("test", l.getClientUuid()); + assertEquals(1, l.getClientPid()); + + request = Lock.newBuilder().setClientPid(1).setClientUuid("test").setExclusive(true).setOffset(0) + .setLength(100).build(); + r = osdClient.xtreemfs_lock_acquire(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + l = r.get(); + + assertEquals("test", l.getClientUuid()); + assertEquals(1, l.getClientPid()); + + request = Lock.newBuilder().setClientPid(2).setClientUuid("test").setExclusive(true).setOffset(0) + .setLength(100).build(); + r = osdClient.xtreemfs_lock_acquire(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + try { + l = r.get(); + fail(); + } catch (PBRPCException ex) { + assertEquals(POSIXErrno.POSIX_ERROR_EAGAIN, ex.getPOSIXErrno()); + } + + request = Lock.newBuilder().setClientPid(2).setClientUuid("test").setExclusive(true).setOffset(100) + .setLength(100).build(); + r = osdClient.xtreemfs_lock_acquire(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + l = r.get(); + + assertEquals("test", l.getClientUuid()); + assertEquals(2, l.getClientPid()); + + } + + @Test + public void testAcquireUnlockAcquire() throws Exception { + + Lock request = Lock.newBuilder().setClientPid(1).setClientUuid("test").setExclusive(true).setOffset(100) + .setLength(AdvisoryLock.LENGTH_LOCK_TO_EOF).build(); + RPCResponse r = osdClient.xtreemfs_lock_acquire(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + Lock l = r.get(); + + assertEquals("test", l.getClientUuid()); + assertEquals(1, l.getClientPid()); + + request = Lock.newBuilder().setClientPid(1).setClientUuid("test").setExclusive(true).setOffset(0) + .setLength(100).build(); + r = osdClient.xtreemfs_lock_acquire(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + l = r.get(); + + assertEquals("test", l.getClientUuid()); + assertEquals(1, l.getClientPid()); + + request = Lock.newBuilder().setClientPid(2).setClientUuid("test").setExclusive(true).setOffset(0) + .setLength(100).build(); + r = osdClient.xtreemfs_lock_acquire(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + try { + l = r.get(); + fail(); + } catch (PBRPCException ex) { + assertEquals(POSIXErrno.POSIX_ERROR_EAGAIN, ex.getPOSIXErrno()); + } + + request = Lock.newBuilder().setClientPid(1).setClientUuid("test").setExclusive(true).setOffset(0).setLength(0) + .build(); + r = osdClient.xtreemfs_lock_release(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + r.get(); + + request = Lock.newBuilder().setClientPid(2).setClientUuid("test").setExclusive(true).setOffset(0) + .setLength(100).build(); + r = osdClient.xtreemfs_lock_acquire(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, request); + l = r.get(); + + assertEquals("test", l.getClientUuid()); + assertEquals(2, l.getClientPid()); + + } + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/CleanupTest.java b/java/servers/test/org/xtreemfs/test/osd/CleanupTest.java new file mode 100644 index 0000000..03c9c0a --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/CleanupTest.java @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.clients.File; +import org.xtreemfs.common.clients.RandomAccessFile; +import org.xtreemfs.common.clients.Volume; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.osd.storage.CleanupThread; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_get_resultsResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_is_runningResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_cleanup_statusResponse; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class CleanupTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment env; + + private static Auth passwd; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + passwd = Auth.newBuilder().setAuthType(AuthType.AUTH_PASSWORD) + .setAuthPasswd(AuthPassword.newBuilder().setPassword("")).build(); + } + + @AfterClass + public static void shutdownTest() throws Exception { + } + + @Before + public void setUp() throws Exception { + env = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.DIR_SERVICE, TestEnvironment.Services.MRC, + TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.MRC_CLIENT, + TestEnvironment.Services.OSD, TestEnvironment.Services.OSD_CLIENT, }); + env.start(); + } + + @After + public void tearDown() { + env.shutdown(); + } + + /** + * Test the Cleanup function without any files on the OSD. + * + * @throws Exception + */ + @Test + public void testCleanUpEmpty() throws Exception { + // start the cleanUp Operation + List results = makeCleanup(false, false, false); + + for (String res : results) { + Pattern p = Pattern.compile(CleanupThread.getRegex(CleanupThread.VOLUME_RESULT_FORMAT)); + Matcher m = p.matcher(res); + int zombies = Integer.parseInt(m.group(2).trim()); + assertEquals(0, zombies); + int files = Integer.parseInt(m.group(3).trim()); + assertEquals(0, files); + } + } + + /** + * Test the Cleanup function with files without zombies on the OSD. + * + * @throws Exception + */ + @Test + public void testCleanUpFilesWithoutZombies() throws Exception { + setupTestVolume(); + + // start the cleanUp Operation + List results = makeCleanup(false, false, false); + + for (String res : results) { + Pattern p = Pattern.compile(CleanupThread.getRegex(CleanupThread.VOLUME_RESULT_FORMAT)); + Matcher m = p.matcher(res); + assertTrue(m.matches()); + int zombies = Integer.parseInt(m.group(2).trim()); + assertEquals(0, zombies); + int files = Integer.parseInt(m.group(3).trim()); + assertEquals(3, files); + } + } + + /** + * Test the Cleanup function with files with 1 zombie on the OSD. + * + * @throws Exception + */ + @Test + public void testCleanupFilesWithZombies() throws Exception { + + UserCredentials uc = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + RPCResponse r = null; + + setupTestVolume(); + + // test/test1 --> zombie + r = env.getMrcClient().unlink(env.getMRCAddress(), RPCAuthentication.authNone, uc, "test", "test1"); + r.get(); + r.freeBuffers(); + + List results = makeCleanup(false, false, false); + + for (String res : results) { + Pattern p = Pattern.compile(CleanupThread.getRegex(CleanupThread.VOLUME_RESULT_FORMAT)); + Matcher m = p.matcher(res); + assertTrue(m.matches()); + int zombies = Integer.parseInt(m.group(2).trim()); + assertEquals(1, zombies); + int files = Integer.parseInt(m.group(3).trim()); + assertEquals(3, files); + } + } + + /** + * Test the Cleanup function with files with 1 zombie on the OSD, deleting + * it. + * + * @throws Exception + */ + @Test + public void testCleanupFilesWithZombieDelete() throws Exception { + UserCredentials uc = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + RPCResponse r = null; + + setupTestVolume(); + + // test/test1 --> zombie + r = env.getMrcClient().unlink(env.getMRCAddress(), RPCAuthentication.authNone, uc, "test", "test1"); + r.get(); + r.freeBuffers(); + + List results = makeCleanup(false, false, true); + + for (String res : results) { + Pattern p = Pattern.compile(CleanupThread.getRegex(CleanupThread.VOLUME_RESULT_FORMAT)); + Pattern pd = Pattern.compile(CleanupThread.getRegex(CleanupThread.ZOMBIES_DELETED_FORMAT)); + Matcher m = p.matcher(res); + // its a zombie delete message + if (!m.matches()) { + m = pd.matcher(res); + assertTrue(m.matches()); + int zombies = Integer.parseInt(m.group(1).trim()); + assertEquals(1, zombies); + String volState = m.group(2); + assertEquals("existing", volState); + } else { + int zombies = Integer.parseInt(m.group(2).trim()); + assertEquals(1, zombies); + int files = Integer.parseInt(m.group(3).trim()); + assertEquals(3, files); + } + } + + // restart the cleanUp Operation on clean volume + results = makeCleanup(false, false, false); + + for (String res : results) { + Pattern p = Pattern.compile(CleanupThread.getRegex(CleanupThread.VOLUME_RESULT_FORMAT)); + Matcher m = p.matcher(res); + assertTrue(m.matches()); + int zombies = Integer.parseInt(m.group(2).trim()); + assertEquals(0, zombies); + int files = Integer.parseInt(m.group(3).trim()); + assertEquals(2, files); + } + } + + /** + * Test the Cleanup function with files with 1 zombie on the OSD, restoring + * it. + * + * @throws Exception + */ + @Test + public void testCleanupFilesWithZombieRestore() throws Exception { + UserCredentials uc = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + RPCResponse r = null; + + setupTestVolume(); + + // test/test1 --> zombie + r = env.getMrcClient().unlink(env.getMRCAddress(), RPCAuthentication.authNone, uc, "test", "test1"); + r.get(); + r.freeBuffers(); + + List results = makeCleanup(true, false, false); + + for (String res : results) { + Pattern p = Pattern.compile(CleanupThread.getRegex(CleanupThread.VOLUME_RESULT_FORMAT)); + Pattern pr = Pattern.compile(CleanupThread.getRegex(CleanupThread.ZOMBIES_RESTORED_FORMAT)); + Matcher m = p.matcher(res); + // its a zombie restore message + if (!m.matches()) { + m = pr.matcher(res); + assertTrue(m.matches()); + int zombies = Integer.parseInt(m.group(1).trim()); + assertEquals(1, zombies); + } else { + int zombies = Integer.parseInt(m.group(2).trim()); + assertEquals(1, zombies); + int files = Integer.parseInt(m.group(3).trim()); + assertEquals(3, files); + } + } + + // restart the cleanUp Operation on clean volume + results = makeCleanup(false, false, false); + + for (String res : results) { + Pattern p = Pattern.compile(CleanupThread.getRegex(CleanupThread.VOLUME_RESULT_FORMAT)); + Matcher m = p.matcher(res); + assertTrue(m.matches()); + int zombies = Integer.parseInt(m.group(2).trim()); + assertEquals(0, zombies); + int files = Integer.parseInt(m.group(3).trim()); + assertEquals(3, files); + } + } + + /** + * Performs a cleanUp-Operation.
    + * Checks the status for errors. + * + * @param restore + * @param deleteVolumes + * @param killZombies + * @return the result of the cleanup operation. + * @throws InterruptedException + * @throws ONCRPCException + * @throws IOException + */ + private List makeCleanup(boolean restore, boolean deleteVolumes, boolean killZombies) + throws InterruptedException, IOException { + String statF = CleanupThread.getRegex(CleanupThread.STATUS_FORMAT); + String stopF = CleanupThread.getRegex(CleanupThread.STOPPED_FORMAT); + assertNotNull(statF); + assertNotNull(stopF); + + RPCResponse r = null; + + // start the cleanUp Operation + r = env.getOSDClient().xtreemfs_cleanup_start(env.getOSDAddress(), + passwd, RPCAuthentication.userService, + killZombies, deleteVolumes, restore, true, 0); + r.get(); + r.freeBuffers(); + + boolean isRunning = true; + do { + r = env.getOSDClient().xtreemfs_cleanup_status(env.getOSDAddress(), + passwd, RPCAuthentication.userService); + xtreemfs_cleanup_statusResponse stat = (xtreemfs_cleanup_statusResponse) r.get(); + r.freeBuffers(); + + assertNotNull(stat); + try { + if (stat.getStatus().matches(statF)) + assertTrue(true); + } catch (NullPointerException ne) { + assertTrue(stat.getStatus().matches(stopF)); + } + + r = env.getOSDClient().xtreemfs_cleanup_is_running(env.getOSDAddress(), + passwd, RPCAuthentication.userService); + isRunning = ((xtreemfs_cleanup_is_runningResponse)r.get()).getIsRunning(); + r.freeBuffers(); + } while (isRunning); + + r = env.getOSDClient().xtreemfs_cleanup_get_results(env.getOSDAddress(), + passwd, RPCAuthentication.userService); + List results = ((xtreemfs_cleanup_get_resultsResponse) r.get()).getResultsList(); + r.freeBuffers(); + + return results; + } + + /** + * Sets up a test-volume with 3 files.
    + * Volume: test
    + * Files:
    + * test/test1
    + * test/test2
    + * test/test3
    + * + * @throws Exception + */ + private void setupTestVolume() throws Exception { + UserCredentials uc = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + StripingPolicy sp = SetupUtils.getStripingPolicy(1, 4); + + Client c = new Client(new InetSocketAddress[]{env.getDIRAddress()}, 15*1000, 5*60*1000, null); + c.start(); + c.createVolume("test", RPCAuthentication.authNone, uc, sp, AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, 511); + + Volume v = c.getVolume("test", uc); + + File f = v.getFile("test1"); + RandomAccessFile raf = f.open("rw", 511); + raf.write(new byte[1024 * 10], 0, 1024 * 10); + raf.close(); + + f = v.getFile("test2"); + raf = f.open("rw", 511); + raf.write(new byte[1024 * 10], 0, 1024 * 10); + raf.close(); + + f = v.getFile("test3"); + raf = f.open("rw", 511); + raf.write(new byte[1024 * 10], 0, 1024 * 10); + raf.close(); + } +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/test/osd/ClientLeaseTest.java b/java/servers/test/org/xtreemfs/test/osd/ClientLeaseTest.java new file mode 100644 index 0000000..223362e --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/ClientLeaseTest.java @@ -0,0 +1,321 @@ +///* Copyright (c) 2008 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin, +// Barcelona Supercomputing Center - Centro Nacional de Supercomputacion and +// Consiglio Nazionale delle Ricerche. +// +// This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based +// Grid Operating System, see for more details. +// The XtreemOS project has been developed with the financial support of the +// European Commission's IST program under contract #FP6-033576. +// +// XtreemFS is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2 of the License, or (at your option) +// any later version. +// +// XtreemFS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with XtreemFS. If not, see . +// */ +///* +// * AUTHORS: Björn Kolbeck (ZIB) +// */ +// +//package org.xtreemfs.test.osd; +// +//import java.io.File; +//import java.util.ArrayList; +//import java.util.List; +//import java.util.Map; +// +//import junit.framework.TestCase; +//import junit.textui.TestRunner; +// +//import org.xtreemfs.common.Capability; +//import org.xtreemfs.common.ClientLease; +//import org.xtreemfs.foundation.buffer.ReusableBuffer; +//import org.xtreemfs.common.clients.HttpErrorException; +//import org.xtreemfs.common.clients.RPCResponse; +//import org.xtreemfs.common.clients.osd.OSDClient; +//import org.xtreemfs.foundation.logging.Logging; +//import org.xtreemfs.common.striping.Location; +//import org.xtreemfs.common.striping.Locations; +//import org.xtreemfs.common.striping.RAID0; +//import org.xtreemfs.common.striping.StripingPolicy; +//import org.xtreemfs.test.foundation.util.FSUtils; +//import org.xtreemfs.common.uuids.ServiceUUID; +//import org.xtreemfs.dir.DIRConfig; +//import org.xtreemfs.dir.client.DIRClient; +//import org.xtreemfs.osd.OSD; +//import org.xtreemfs.osd.OSDConfig; +//import org.xtreemfs.test.SetupUtils; +//import org.xtreemfs.test.TestEnvironment; +// +///** +// * Class for testing the NewOSD It uses the old OSDTest tests. It checks if the +// * OSD works without replicas neither striping +// * +// * @author bjko +// */ +//public class ClientLeaseTest extends TestCase { +// +// private final ServiceUUID serverID; +// +// private final Locations loc; +// +// private final String file; +// +// private Capability cap; +// +// private OSD osd; +// +// private final long stripeSize = 1; +// +// private DIRClient dirClient; +// +// private OSDClient client; +// +// private final OSDConfig osdConfig; +// +// private TestEnvironment testEnv; +// +// public ClientLeaseTest(String testName) throws Exception { +// super(testName); +// +// Logging.start(Logging.LEVEL_TRACE); +// +// osdConfig = SetupUtils.createOSD1Config(); +// +// // It sets the loc attribute +// List locations = new ArrayList(1); +// StripingPolicy sp = new RAID0(stripeSize, 1); +// serverID = SetupUtils.getOSD1UUID(); +// List osd = new ArrayList(1); +// osd.add(serverID); +// locations.add(new Location(sp, osd)); +// loc = new Locations(locations); +// +// file = "1:1"; +// cap = new Capability(file, "x", 0, osdConfig.getCapabilitySecret()); +// } +// +// protected void setUp() throws Exception { +// +// System.out.println("TEST: " + getClass().getSimpleName() + "." + getName()); +// +// // cleanup +// File testDir = new File(SetupUtils.TEST_DIR); +// +// FSUtils.delTree(testDir); +// testDir.mkdirs(); +// +// // startup: DIR +// testEnv = new TestEnvironment(new TestEnvironment.Services[]{ +// TestEnvironment.Services.DIR_SERVICE,TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, +// TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.OSD_CLIENT +// }); +// testEnv.start(); +// +// dirClient = testEnv.getDirClient(); +// client = testEnv.getOsdClient(); +// +// osd = new OSD(osdConfig); +// } +// +// protected void tearDown() throws Exception { +// osd.shutdown(); +// testEnv.shutdown(); +// } +// +// public void testAcquireLease() throws Exception { +// +// OSDClient c = testEnv.getOsdClient(); +// +// ClientLease lease = new ClientLease(file); +// lease.setClientId("ABCDEF"); +// lease.setOperation(ClientLease.EXCLUSIVE_LEASE); +// lease.setFirstObject(0); +// lease.setLastObject(ClientLease.TO_EOF); +// +// RPCResponse>> r = c.acquireClientLease(serverID.getAddress(), loc, cap, lease); +// List> tmp = r.get(); +// +// ClientLease result = ClientLease.parseFromMap(tmp.get(0)); +// assertNotNull(result.getClientId()); +// assertTrue(result.getSequenceNo() > 0); +// assertTrue(result.getExpires() > 0); +// } +// +// public void testConflictingLeases() throws Exception { +// +// OSDClient c = testEnv.getOsdClient(); +// +// ClientLease lease = new ClientLease(file); +// lease.setClientId("ABCDEF"); +// lease.setOperation(ClientLease.EXCLUSIVE_LEASE); +// lease.setFirstObject(0); +// lease.setLastObject(ClientLease.TO_EOF); +// +// RPCResponse>> r = c.acquireClientLease(serverID.getAddress(), loc, cap, lease); +// List> tmp = r.get(); +// +// ClientLease result = ClientLease.parseFromMap(tmp.get(0)); +// assertNotNull(result.getClientId()); +// assertTrue(result.getSequenceNo() > 0); +// assertTrue(result.getExpires() > 0); +// +// +// lease.setClientId("YXYXYX"); +// r = c.acquireClientLease(serverID.getAddress(), loc, cap, lease); +// tmp = r.get(); +// +// result = ClientLease.parseFromMap(tmp.get(0)); +// assertNull(result.getClientId()); +// +// } +// +// public void testMultipleLeases() throws Exception { +// +// OSDClient c = testEnv.getOsdClient(); +// +// ClientLease lease = new ClientLease(file); +// lease.setClientId("ABCDEF"); +// lease.setOperation(ClientLease.EXCLUSIVE_LEASE); +// lease.setFirstObject(10); +// lease.setLastObject(ClientLease.TO_EOF); +// +// RPCResponse>> r = c.acquireClientLease(serverID.getAddress(), loc, cap, lease); +// List> tmp = r.get(); +// +// ClientLease result = ClientLease.parseFromMap(tmp.get(0)); +// assertNotNull(result.getClientId()); +// assertTrue(result.getSequenceNo() > 0); +// assertTrue(result.getExpires() > 0); +// +// +// ClientLease lease2 = new ClientLease(file); +// lease2.setClientId("ABCDEF"); +// lease2.setOperation(ClientLease.EXCLUSIVE_LEASE); +// lease2.setFirstObject(0); +// lease2.setLastObject(9); +// +// RPCResponse>> r2 = c.acquireClientLease(serverID.getAddress(), loc, cap, lease2); +// tmp = r2.get(); +// +// result = ClientLease.parseFromMap(tmp.get(0)); +// assertNotNull(result.getClientId()); +// assertTrue(result.getSequenceNo() > 0); +// assertTrue(result.getExpires() > 0); +// +// } +// +// public void testReturnLease() throws Exception { +// +// OSDClient c = testEnv.getOsdClient(); +// +// ClientLease lease = new ClientLease(file); +// lease.setClientId("ABCDEF"); +// lease.setOperation(ClientLease.EXCLUSIVE_LEASE); +// lease.setFirstObject(10); +// lease.setLastObject(ClientLease.TO_EOF); +// +// RPCResponse>> r = c.acquireClientLease(serverID.getAddress(), loc, cap, lease); +// List> tmp = r.get(); +// +// ClientLease result = ClientLease.parseFromMap(tmp.get(0)); +// assertNotNull(result.getClientId()); +// assertTrue(result.getSequenceNo() > 0); +// assertTrue(result.getExpires() > 0); +// +// //return the lease +// try { +// RPCResponse r2 = c.returnLease(serverID.getAddress(), loc, cap, result); +// r2.waitForResponse(); +// } catch (HttpErrorException ex) { +// fail("cannot return lease: "+ex); +// } +// +// //try to acquire lease again +// r = c.acquireClientLease(serverID.getAddress(), loc, cap, lease); +// tmp = r.get(); +// +// result = ClientLease.parseFromMap(tmp.get(0)); +// assertNotNull(result.getClientId()); +// assertTrue(result.getSequenceNo() > 0); +// assertTrue(result.getExpires() > 0); +// +// +// } +// +// public void testRenewLease() throws Exception { +// +// OSDClient c = testEnv.getOsdClient(); +// +// ClientLease lease = new ClientLease(file); +// lease.setClientId("ABCDEF"); +// lease.setOperation(ClientLease.EXCLUSIVE_LEASE); +// lease.setFirstObject(0); +// lease.setLastObject(ClientLease.TO_EOF); +// +// RPCResponse>> r = c.acquireClientLease(serverID.getAddress(), loc, cap, lease); +// List> tmp = r.get(); +// +// ClientLease result = ClientLease.parseFromMap(tmp.get(0)); +// assertNotNull(result.getClientId()); +// assertTrue(result.getSequenceNo() > 0); +// assertTrue(result.getExpires() > 0); +// +// +// r = c.acquireClientLease(serverID.getAddress(), loc, cap, result); +// tmp = r.get(); +// +// result = ClientLease.parseFromMap(tmp.get(0)); +// assertNotNull(result.getClientId()); +// assertTrue(result.getExpires() > lease.getExpires()); +// +// } +// +// public void testTimeout() throws Exception { +// +// OSDClient c = testEnv.getOsdClient(); +// +// ClientLease lease = new ClientLease(file); +// lease.setClientId("ABCDEF"); +// lease.setOperation(ClientLease.EXCLUSIVE_LEASE); +// lease.setFirstObject(0); +// lease.setLastObject(ClientLease.TO_EOF); +// +// RPCResponse>> r = c.acquireClientLease(serverID.getAddress(), loc, cap, lease); +// List> tmp = r.get(); +// +// ClientLease result = ClientLease.parseFromMap(tmp.get(0)); +// assertNotNull(result.getClientId()); +// assertTrue(result.getSequenceNo() > 0); +// assertTrue(result.getExpires() > 0); +// +// try { +// RPCResponse r2 = c.put(serverID.getAddress(),loc,cap,file,0,ReusableBuffer.wrap("YaggaYagga".getBytes()),result); +// r2.waitForResponse(); +// } catch (HttpErrorException ex) { +// fail(ex.toString()); +// } +// +// result.setExpires(1); +// +// try { +// RPCResponse r2 = c.put(serverID.getAddress(),loc,cap,file,0,ReusableBuffer.wrap("YaggaYagga".getBytes()),result); +// r2.waitForResponse(); +// fail("lease should be timed out"); +// } catch (HttpErrorException ex) { +// } +// +// +// } +// +// public static void main(String[] args) { +// TestRunner.run(ClientLeaseTest.class); +// } +//} diff --git a/java/servers/test/org/xtreemfs/test/osd/CowPolicyTest.java b/java/servers/test/org/xtreemfs/test/osd/CowPolicyTest.java new file mode 100644 index 0000000..1aa7946 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/CowPolicyTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.osd.storage.CowPolicy; +import org.xtreemfs.osd.storage.CowPolicy.cowMode; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class CowPolicyTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + @Test + public void testNoCow() throws Exception { + CowPolicy p = new CowPolicy(cowMode.NO_COW); + assertFalse(p.isCOW(0)); + assertFalse(p.isCOW(10)); + assertFalse(p.isCOW(55)); + p.objectChanged(0); + assertFalse(p.isCOW(0)); + } + + @Test + public void testAlwaysCow() throws Exception { + CowPolicy p = new CowPolicy(cowMode.ALWAYS_COW); + assertTrue(p.isCOW(0)); + assertTrue(p.isCOW(10)); + assertTrue(p.isCOW(55)); + p.objectChanged(0); + assertTrue(p.isCOW(0)); + } + + @Test + public void testCowOnce() throws Exception { + CowPolicy p = new CowPolicy(cowMode.COW_ONCE); + p.initCowFlagsIfRequired(115); + assertTrue(p.isCOW(0)); + assertTrue(p.isCOW(10)); + assertTrue(p.isCOW(55)); + p.objectChanged(0); + //check entrie 8 bits since COW uses byte array for COW_ONCE bitmap + assertFalse(p.isCOW(0)); + assertTrue(p.isCOW(1)); + assertTrue(p.isCOW(2)); + assertTrue(p.isCOW(3)); + assertTrue(p.isCOW(4)); + assertTrue(p.isCOW(5)); + assertTrue(p.isCOW(6)); + assertTrue(p.isCOW(7)); + + p.objectChanged(5); + //check entrie 8 bits since COW uses byte array for COW_ONCE bitmap + assertFalse(p.isCOW(0)); + assertTrue(p.isCOW(1)); + assertTrue(p.isCOW(2)); + assertTrue(p.isCOW(3)); + assertTrue(p.isCOW(4)); + assertFalse(p.isCOW(5)); + assertTrue(p.isCOW(6)); + assertTrue(p.isCOW(7)); + + p.objectChanged(9); + //check entrie 8 bits since COW uses byte array for COW_ONCE bitmap + assertTrue(p.isCOW(8)); + assertFalse(p.isCOW(9)); + assertTrue(p.isCOW(10)); + assertTrue(p.isCOW(11)); + assertTrue(p.isCOW(12)); + assertTrue(p.isCOW(13)); + assertTrue(p.isCOW(14)); + assertTrue(p.isCOW(15)); + + //any new object (here > 114) must return false + assertFalse(p.isCOW(22556)); + p.objectChanged(22556); + assertFalse(p.isCOW(22556)); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/FastDeleteOpenFile.java b/java/servers/test/org/xtreemfs/test/osd/FastDeleteOpenFile.java new file mode 100644 index 0000000..8b1c56d --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/FastDeleteOpenFile.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013 by Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertFalse; + +import java.io.File; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.AdminFileHandle; +import org.xtreemfs.common.libxtreemfs.AdminVolume; +import org.xtreemfs.common.libxtreemfs.ClientFactory; +import org.xtreemfs.common.libxtreemfs.ClientImplementation; +import org.xtreemfs.common.libxtreemfs.Options; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.osd.storage.HashStorageLayout; +import org.xtreemfs.osd.storage.MetadataCache; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + + +/** + * Write a file, delete it and check if it was deleted on disk as well. + * + * This test ensures that the file is explicitly closed upon deletion in the OSD. If not, the deletion of the + * file would be delayed until the file is implicitly deleted (by default after 60 seconds). + * + * @author mberlin + * + */ +public class FastDeleteOpenFile { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static TestEnvironment testEnv; + + private static UserCredentials userCredentials; + + private static Auth auth = RPCAuthentication.authNone; + + private static String mrcAddress; + + private static String dirAddress; + + private static ClientImplementation client; + + private static Options options; + + @BeforeClass + public static void initializeTest() throws Exception { + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, TestEnvironment.Services.DIR_CLIENT, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.RPC_CLIENT, + TestEnvironment.Services.MRC, TestEnvironment.Services.OSD, TestEnvironment.Services.OSD}); + testEnv.start(); + + userCredentials = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + options = new Options(); + client = (ClientImplementation) ClientFactory + .createClient(dirAddress, userCredentials, null, options); + client.start(); + } + + @AfterClass + public static void shutdownTest() throws Exception { + testEnv.shutdown(); + + client.shutdown(); + } + + @Test + public void testFileOpenAtOSDAndImmediateDelete() throws Exception { + final String volumeName = "testFileOpenAtOSDAndImmediateDelete"; + final String path = "/test.txt"; + String globalFileId = null; + + // Create client. + AdminClient client = ClientFactory.createAdminClient(dirAddress, userCredentials, null, options); + client.start(); + + // Create and open volume. + client.createVolume(mrcAddress, auth, userCredentials, volumeName); + AdminVolume volume = client.openVolume(volumeName, null, options); + volume.start(); + + // Open FileHandle and remember its global file id. + AdminFileHandle fileHandle = volume.openFile( + userCredentials, + path, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0777); + globalFileId = fileHandle.getGlobalFileId(); + + // Write some content. + String content = ""; + for (int i = 0; i < 128 * 1024 / 12; i++) { + content = content.concat("Hello World "); + } + byte[] bytesIn = content.getBytes(); + int length = bytesIn.length; + fileHandle.write(userCredentials, bytesIn, length, 0); + fileHandle.close(); + + + // Delete file. + volume.unlink(userCredentials, path); + + // Make sure the file is deleted on disk. + HashStorageLayout hsl = new HashStorageLayout(SetupUtils.createOSD1Config(), new MetadataCache()); + String pathOnDisk = hsl.generateAbsoluteFilePath(globalFileId); + + // The file is deleted asynchronously by the DeletionStage in the OSD. Give it some time. + Thread.sleep(1 * 1000); + assertFalse(new File(pathOnDisk).isDirectory()); + + // Cleanup. + volume.close(); + client.shutdown(); + } +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/test/osd/OSDDataIntegrityTest.java b/java/servers/test/org/xtreemfs/test/osd/OSDDataIntegrityTest.java new file mode 100644 index 0000000..6048075 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/OSDDataIntegrityTest.java @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +public class OSDDataIntegrityTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static ServiceUUID serverID; + + private static FileCredentials fcred; + + private static String fileId; + + private static Capability cap; + + private static OSDConfig osdConfig; + + private OSDServiceClient osdClient; + + private OSD osdServer; + private TestEnvironment testEnv; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + osdConfig = SetupUtils.createOSD1Config(); + serverID = SetupUtils.getOSD1UUID(); + } + + @Before + public void setUp() throws Exception { + // startup: DIR + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.OSD_CLIENT }); + testEnv.start(); + + osdServer = new OSD(osdConfig); + + synchronized (this) { + try { + this.wait(50); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + + osdClient = new OSDServiceClient(testEnv.getRpcClient(), null); + + fileId = "ABCDEF:1"; + cap = new Capability(fileId, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 60, + System.currentTimeMillis(), "", 0, false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, + osdConfig.getCapabilitySecret()); + + Replica r = Replica.newBuilder().setReplicationFlags(0).setStripingPolicy(SetupUtils.getStripingPolicy(1, 2)) + .addOsdUuids(serverID.toString()).build(); + XLocSet xloc = XLocSet.newBuilder().setReadOnlyFileSize(0).setReplicaUpdatePolicy("").addReplicas(r) + .setVersion(1).build(); + + fcred = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xloc).build(); + } + + @After + public void tearDown() throws Exception { + osdServer.shutdown(); + + testEnv.shutdown(); + } + + @Test + public void testWriteRanges() throws Exception { + + // test for obj 1,2,3... + for (int objId = 0; objId < 5; objId++) { + // write half object + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, objId, 0, 0, 0, data, buf.createViewBuffer()); + OSDWriteResponse resp = r.get(); + + assertTrue(resp.hasSizeInBytes()); + assertEquals(1024 + (objId) * 2048, resp.getSizeInBytes()); + + r.freeBuffers(); + + // read data + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, objId, 0, 0, buf.capacity()); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + dataOut.position(0); + assertEquals(1024, dataOut.capacity()); + for (int i = 0; i < 1024; i++) + assertEquals((byte) 'A', dataOut.get()); + + r2.freeBuffers(); + + // write second half + BufferPool.free(buf); + buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'a'); + buf.flip(); + RPCResponse r3 = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, objId, 0, 1024, 0, data, buf); + resp = r3.get(); + r3.freeBuffers(); + + assertTrue(resp.hasSizeInBytes()); + assertEquals(2048 + (objId) * 2048, resp.getSizeInBytes()); + + // read data + RPCResponse r4 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, objId, 0, 0, 2048); + data = r4.get(); + dataOut = r4.getData(); + + dataOut.position(0); + assertEquals(2048, dataOut.capacity()); + for (int i = 0; i < 1024; i++) + assertEquals((byte) 'A', dataOut.get()); + for (int i = 0; i < 1024; i++) + assertEquals((byte) 'a', dataOut.get()); + + r4.freeBuffers(); + + // write somewhere in the middle + buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'x'); + buf.flip(); + RPCResponse r5 = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, objId, 0, 512, 0, data, buf); + resp = r5.get(); + r5.freeBuffers(); + + // read data + RPCResponse r6 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, objId, 0, 0, 2048); + data = r6.get(); + dataOut = r6.getData(); + + dataOut.position(0); + assertEquals(2048, dataOut.capacity()); + for (int i = 0; i < 512; i++) + assertEquals((byte) 'A', dataOut.get()); + for (int i = 0; i < 1024; i++) + assertEquals((byte) 'x', dataOut.get()); + for (int i = 0; i < 512; i++) + assertEquals((byte) 'a', dataOut.get()); + + r6.freeBuffers(); + } + + } + + @Test + public void testReadRanges() throws Exception { + + // test for obj 1,2,3... + for (int objId = 0; objId < 5; objId++) { + // write half object + ReusableBuffer buf = BufferPool.allocate(2048); + for (int i = 0; i < 512; i++) + buf.put((byte) 'A'); + for (int i = 0; i < 512; i++) + buf.put((byte) 'B'); + for (int i = 0; i < 512; i++) + buf.put((byte) 'C'); + for (int i = 0; i < 512; i++) + buf.put((byte) 'D'); + + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, objId, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + + // read data 1st 512 bytes + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, objId, 0, 0, 512); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + dataOut.position(0); + assertEquals(512, dataOut.capacity()); + for (int i = 0; i < 512; i++) + assertEquals((byte) 'A', dataOut.get()); + r2.freeBuffers(); + + r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + fcred, fileId, objId, 0, 1024, 512); + ObjectData data2 = r2.get(); + dataOut = r2.getData(); + + dataOut.position(0); + assertEquals(512, dataOut.capacity()); + for (int i = 0; i < 512; i++) + assertEquals((byte) 'C', dataOut.get()); + + r2.freeBuffers(); + } + } + + @Test + public void testImplicitTruncateWithinObject() throws Exception { + + // first test implicit truncate through write within a single object + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 1024, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + + assertTrue(resp.hasSizeInBytes()); + assertEquals(2048, resp.getSizeInBytes()); + + // read data + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 2048); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + dataOut.position(0); + + assertEquals(2048, dataOut.capacity()); + for (int i = 0; i < 1024; i++) + assertEquals((byte) 0, dataOut.get()); + for (int i = 0; i < 1024; i++) + assertEquals((byte) 'A', dataOut.get()); + + r2.freeBuffers(); + } + + @Test + public void testImplicitTruncate() throws Exception { + + // first test implicit truncate through write within a single object + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 1, 0, 1024, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(4096, resp.getSizeInBytes()); + + // read data + + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 2048); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + assertTrue((data.getZeroPadding() == 2048) && (dataOut == null) || (data.getZeroPadding() == 0) + && (dataOut.capacity() == 2048)); + r2.freeBuffers(); + + // read data + r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 1, 0, 0, 2048); + data = r2.get(); + dataOut = r2.getData(); + + dataOut.position(0); + assertEquals(2048, dataOut.capacity()); + for (int i = 0; i < 1024; i++) + assertEquals((byte) 0, dataOut.get()); + for (int i = 0; i < 1024; i++) + assertEquals((byte) 'A', dataOut.get()); + + r2.freeBuffers(); + } + + @Test + public void testEOF() throws Exception { + + // first test implicit truncate through write within a single object + ReusableBuffer buf = BufferPool.allocate(1023); + for (int i = 0; i < 1023; i++) + buf.put((byte) 'A'); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 1, 0, 1024, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(2047 + 2048, resp.getSizeInBytes()); + + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 1, 0, 0, 2048); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + dataOut.position(0); + assertEquals(2047, dataOut.capacity()); + for (int i = 0; i < 1024; i++) + assertEquals((byte) 0, dataOut.get()); + for (int i = 0; i < 1023; i++) + assertEquals((byte) 'A', dataOut.get()); + r2.freeBuffers(); + + // read non-existing object (EOF) + r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 2, 0, 0, 2048); + data = r2.get(); + dataOut = r2.getData(); + + assertNull(dataOut); + r2.freeBuffers(); + } + + @Test + public void testReadBeyonEOF() throws Exception { + + // first test implicit truncate through write within a single object + ReusableBuffer buf = BufferPool.allocate(1023); + for (int i = 0; i < 1023; i++) + buf.put((byte) 'A'); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 1, 0, 1024, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(2047 + 2048, resp.getSizeInBytes()); + + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 10, 0, 0, 2048); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + assertNull(dataOut); + assertEquals(0, data.getZeroPadding()); + r2.freeBuffers(); + } + + @Test + public void testOverlappingWrites() throws Exception { + + // first test implicit truncate through write within a single object + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 1, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(2048 + 1024, resp.getSizeInBytes()); + + buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'B'); + buf.flip(); + r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 1, 0, 512, 0, data, buf); + resp = r.get(); + r.freeBuffers(); + + // read data + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 1, 0, 0, 2048); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + dataOut.position(0); + assertEquals(1536, dataOut.capacity()); + for (int i = 0; i < 512; i++) + assertEquals((byte) 'A', dataOut.get()); + for (int i = 0; i < 1024; i++) + assertEquals((byte) 'B', dataOut.get()); + + r2.freeBuffers(); + + } +} diff --git a/java/servers/test/org/xtreemfs/test/osd/OSDDrainTest.java b/java/servers/test/org/xtreemfs/test/osd/OSDDrainTest.java new file mode 100644 index 0000000..6208e4d --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/OSDDrainTest.java @@ -0,0 +1,490 @@ +/* + * Copyright (c) 2009-2011 by Paul Seiferth, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.clients.File; +import org.xtreemfs.common.clients.RandomAccessFile; +import org.xtreemfs.common.clients.Volume; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.dir.DIRClient; +import org.xtreemfs.foundation.TimeSync; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.mrc.MRCConfig; +import org.xtreemfs.mrc.MRCRequestDispatcher; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.osd.drain.OSDDrain; +import org.xtreemfs.osd.drain.OSDDrain.FileInformation; +import org.xtreemfs.osd.drain.OSDDrainException; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * @author bzcseife + * + *
    + * Mar 31, 2011 + */ + +public class OSDDrainTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment testEnv; + + private static final String VOLNAME = "testvolume"; + private static final String VOLNAME2 = "testvolume2"; + + private static int STRIPESIZE = 1024; + + private static OSDConfig osdConfig1; + private static OSDConfig osdConfig2; + private static OSDConfig osdConfig3; + + private List osdServer; + + private MRCServiceClient mrcClient; + + private static StripingPolicyImpl sp; + + private final Auth authHeader = RPCAuthentication.authNone; + + private final UserCredentials uc = RPCAuthentication.userService; + + private UUIDResolver resolver; + + private OSDDrain osdDrain; + + private MRCConfig mrc2Config; + + private MRCRequestDispatcher mrc2; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + osdConfig1 = SetupUtils.createOSD1Config(); + osdConfig2 = SetupUtils.createOSD2Config(); + osdConfig3 = SetupUtils.createOSD3Config(); + + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, STRIPESIZE)) + .setReplicationFlags(0).build(); + sp = StripingPolicyImpl.getPolicy(r, 0); + } + + @Before + public void setUp() throws Exception { + // startup: DIR + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.OSD_CLIENT, TestEnvironment.Services.MRC, + + }); + testEnv.start(); + + mrc2Config = SetupUtils.createMRC2Config(); + mrc2 = new MRCRequestDispatcher(mrc2Config, SetupUtils.createMRC2dbsConfig()); + mrc2.startup(); + + osdServer = new ArrayList(2); + + mrcClient = testEnv.getMrcClient(); + + DIRClient dir = new DIRClient(testEnv.getDirClient(), new InetSocketAddress[] { testEnv.getDIRAddress() }, 10, + 1000 * 5); + resolver = UUIDResolver.startNonSingelton(dir, 1000, 10 * 10 * 1000); + + osdDrain = new OSDDrain(dir, testEnv.getOSDClient(), testEnv.getMrcClient(), osdConfig1.getUUID(), authHeader, + uc, resolver); + + } + + @After + public void tearDown() throws Exception { + if (mrc2 != null) { + mrc2.shutdown(); + } + + testEnv.shutdown(); + } + + /** + * Test if files which are deleted but still have object files on OSDs will be handled correctly. + * + * @throws Exception + */ + @Test + public void testHandleNonExistingFile() throws Exception { + + osdServer.add(new OSD(osdConfig1)); + + final Client c = new Client(new InetSocketAddress[] { testEnv.getDIRAddress() }, 15000, 300000, null); + c.start(); + + c.createVolume(VOLNAME, authHeader, uc, sp.getPolicy(), AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, + 0777); + + Volume volume = c.getVolume(VOLNAME, uc); + + File file1 = volume.getFile("foo"); + File file2 = volume.getFile("bar"); + + file1.createFile(); + file2.createFile(); + + RandomAccessFile raf1 = file1.open("rw", 0777); + RandomAccessFile raf2 = file2.open("rw", 0777); + + final int SIZE = 1024 * 200; + byte[] data = new byte[SIZE]; + + for (int j = 0; j < SIZE; j++) { + data[j] = 'f'; + } + + raf1.write(data, 0, data.length); + raf2.write(data, 0, data.length); + + List fileInfos = new LinkedList(); + + fileInfos = osdDrain.getFileListOfOSD(); + + assertEquals(2, fileInfos.size()); + + osdDrain.updateMRCAddresses(fileInfos); + + raf2.close(); + file2.delete(); + + fileInfos = osdDrain.removeNonExistingFileIDs(fileInfos); + + assertEquals(1, fileInfos.size()); + + raf1.close(); + file1.delete(); + + c.deleteVolume(VOLNAME, authHeader, uc); + c.stop(); + + for (OSD osd : osdServer) { + osd.shutdown(); + } + osdServer.clear(); + + TimeSync.initializeLocal(50).waitForStartup(); + + } + + @Test + public void testRemoveOSD() throws Exception { + + // start only one OSD to ensure that all file lay on the same OSD (easier to make assertions) + osdServer.add(new OSD(osdConfig1)); + + final int NUMBER_OF_FILES = 5; + LinkedList fileNames = new LinkedList(); + fileNames.add("foo1"); + fileNames.add("foo2"); + fileNames.add("foo3"); + fileNames.add("foo4"); + fileNames.add("foo5"); + + final Client c = new Client(new InetSocketAddress[] { testEnv.getDIRAddress() }, 15000, 300000, null); + c.start(); + + c.createVolume(VOLNAME, authHeader, uc, sp.getPolicy(), AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, + 0777); + + Volume volume = c.getVolume(VOLNAME, uc); + + final int SIZE = 1024 * 200; + byte[] data = new byte[SIZE]; + + File files[] = new File[NUMBER_OF_FILES]; + + for (int i = 0; i < NUMBER_OF_FILES; i++) { + files[i] = volume.getFile(fileNames.get(i)); + files[i].createFile(); + + for (int j = 0; j < SIZE; j++) { + data[j] = 'f'; + } + + RandomAccessFile raf = files[i].open("rw", 0777); + raf.write(data, 0, data.length); + raf.flush(); + raf.close(); + } + + List fileInfos = null; + try { + // set OSDServiceStatus to prevent further writing on this OSD + osdDrain.setServiceStatus(ServiceStatus.SERVICE_STATUS_REMOVED); + + // get all files the OSD has + fileInfos = osdDrain.getFileListOfOSD(); + assertEquals(NUMBER_OF_FILES, fileInfos.size()); + + // get address of MRC which is responsible for every file + osdDrain.updateMRCAddresses(fileInfos); + for (FileInformation fileInfo : fileInfos) { + assertEquals(testEnv.getMRCAddress(), fileInfo.mrcAddress); + } + + // get the current replica configuration + fileInfos = osdDrain.getReplicaInfo(fileInfos); + + // Handle r/w coordinated files and remove them from the file info list. + fileInfos = osdDrain.drainCoordinatedFiles(fileInfos); + + // set ReplicationUpdatePolicy to RONLY + fileInfos = osdDrain.setReplicationUpdatePolicyRonly(fileInfos); + for (File file : files) { + assertEquals(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY, file.getReplicaUpdatePolicy()); + } + + // set Files read-only + fileInfos = osdDrain.setFilesReadOnlyAttribute(fileInfos); + for (File file : files) { + assertTrue(file.isReadOnly()); + } + + // start second OSD + osdServer.add(new OSD(osdConfig2)); + + // wait until the OSD is registered and known to the MRC + Thread.sleep(10 * 1000); + + // create replications + fileInfos = osdDrain.createReplicasForFiles(fileInfos); + for (File file : files) { + assertEquals(2, file.getNumReplicas()); + } + + // start replication + fileInfos = osdDrain.startReplication(fileInfos); + + // wait for replication to be finished + fileInfos = osdDrain.waitForReplicationToComplete(fileInfos); + for (File file : files) { + assertTrue(file.isReplicated()); + } + + // remove replicas + osdDrain.removeOriginalFromReplica(fileInfos); + for (File file : files) { + assertEquals(1, file.getNumReplicas()); + } + + // set every file to read/write again which wasn't set to read-only before + osdDrain.resetFilesReadOnlyAttribute(fileInfos); + for (File file : files) { + assertFalse(file.isReadOnly()); + } + + // set ReplicationUpdatePolicy to original value + osdDrain.resetReplicationUpdatePolicy(fileInfos); + for (File file : files) { + assertEquals(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE, file.getReplicaUpdatePolicy()); + } + + } catch (OSDDrainException e) { + osdDrain.handleException(e, true); + throw e; + } + + // test if files are the samel like before + for (int i = 0; i < NUMBER_OF_FILES; i++) { + RandomAccessFile raf = files[i].open("r", 0777); + + raf.read(data, 0, data.length); + raf.close(); + + for (int j = 0; j < SIZE; j++) { + assertEquals('f', data[j]); + } + } + + // tidy up + for (File file : files) { + file.delete(); + } + + c.deleteVolume(VOLNAME, authHeader, uc); + c.stop(); + + for (OSD osd : osdServer) { + osd.shutdown(); + } + osdServer.clear(); + + TimeSync.initializeLocal(50).waitForStartup(); + + } + + @Test + public void testMultipleMRCs() throws Exception { + osdServer.add(new OSD(osdConfig1)); + osdServer.add(new OSD(osdConfig2)); + osdServer.add(new OSD(osdConfig3)); + + String mrc2UUID = mrc2Config.getUUID().toString(); + + final int NUMBER_OF_FILES = 10; + LinkedList fileNames = new LinkedList(); + for (int i = 0; i < NUMBER_OF_FILES; i++) { + fileNames.add("foo" + i); + } + + final Client c = new Client(new InetSocketAddress[] { testEnv.getDIRAddress() }, 15000, 300000, null); + c.start(); + + c.createVolume(VOLNAME, authHeader, uc, sp.getPolicy(), AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, + 0777, SetupUtils.getMRC1UUID().toString()); + c.createVolume(VOLNAME2, authHeader, uc, sp.getPolicy(), AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL, + 0777, mrc2UUID); + + Volume volume1 = c.getVolume(VOLNAME, uc); + Volume volume2 = c.getVolume(VOLNAME2, uc); + + final int SIZE = 1024 * 200; + byte[] data = new byte[SIZE]; + + File files[] = new File[NUMBER_OF_FILES]; + + for (int i = 0; i < NUMBER_OF_FILES; i++) { + if (i % 2 == 0) { + files[i] = volume1.getFile(fileNames.get(i)); + } else { + files[i] = volume2.getFile(fileNames.get(i)); + } + + files[i].createFile(); + + for (int j = 0; j < SIZE; j++) { + data[j] = 'f'; + } + + RandomAccessFile raf = files[i].open("rw", 0777); + raf.write(data, 0, data.length); + raf.flush(); + raf.close(); + } + + // remove first osd + List fileInfos = null; + try { + // set OSDServiceStatus to prevent further writing on this OSD + osdDrain.setServiceStatus(ServiceStatus.SERVICE_STATUS_REMOVED); + + // get all files the OSD has + fileInfos = osdDrain.getFileListOfOSD(); + + // get address of MRC which is responsible for every file + osdDrain.updateMRCAddresses(fileInfos); + + // get the current replica configuration + fileInfos = osdDrain.getReplicaInfo(fileInfos); + + // Handle r/w coordinated files and remove them from the file info list. + fileInfos = osdDrain.drainCoordinatedFiles(fileInfos); + + // set ReplicationUpdatePolicy to RONLY + fileInfos = osdDrain.setReplicationUpdatePolicyRonly(fileInfos); + + // set Files read-only + fileInfos = osdDrain.setFilesReadOnlyAttribute(fileInfos); + + // create replications + fileInfos = osdDrain.createReplicasForFiles(fileInfos); + + // start replication + fileInfos = osdDrain.startReplication(fileInfos); + + // wait for replication to be finished + fileInfos = osdDrain.waitForReplicationToComplete(fileInfos); + + // remove replicas + osdDrain.removeOriginalFromReplica(fileInfos); + for (File file : files) { + assertEquals(1, file.getNumReplicas()); + } + + // set every file to read/write again which wasn't set to read-only before + osdDrain.resetFilesReadOnlyAttribute(fileInfos); + for (File file : files) { + assertFalse(file.isReadOnly()); + } + + // set ReplicationUpdatePolicy to original value + osdDrain.resetReplicationUpdatePolicy(fileInfos); + for (File file : files) { + assertEquals(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE, file.getReplicaUpdatePolicy()); + } + + } catch (OSDDrainException e) { + osdDrain.handleException(e, true); + throw e; + } + // test if files are the same like before + for (int i = 0; i < NUMBER_OF_FILES; i++) { + + RandomAccessFile raf = files[i].open("r", 0777); + + raf.read(data, 0, data.length); + raf.close(); + + for (int j = 0; j < SIZE; j++) { + assertEquals('f', data[j]); + } + } + + // tidy up + for (File file : files) { + file.delete(); + } + + c.deleteVolume(VOLNAME, authHeader, uc); + c.deleteVolume(VOLNAME2, authHeader, uc); + c.stop(); + + for (OSD osd : osdServer) { + osd.shutdown(); + } + osdServer.clear(); + + TimeSync.initializeLocal(50).waitForStartup(); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/OSDRangeReads.java b/java/servers/test/org/xtreemfs/test/osd/OSDRangeReads.java new file mode 100644 index 0000000..afeaa47 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/OSDRangeReads.java @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +public class OSDRangeReads { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static ServiceUUID serverID; + + private static FileCredentials fcred; + + private static String fileId; + + private static Capability cap; + + private static OSDConfig osdConfig; + + private OSDServiceClient osdClient; + + private OSD osdServer; + private TestEnvironment testEnv; + + @BeforeClass + public static void setUpClass() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + osdConfig = SetupUtils.createOSD1Config(); + serverID = SetupUtils.getOSD1UUID(); + } + + @Before + public void setUp() throws Exception { + + // startup: DIR + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.OSD_CLIENT }); + testEnv.start(); + + osdServer = new OSD(osdConfig); + + synchronized (this) { + try { + this.wait(50); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + + osdClient = new OSDServiceClient(testEnv.getRpcClient(), null); + + fileId = "ABCDEF:1"; + cap = new Capability(fileId, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 60, + System.currentTimeMillis(), "", 0, false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, + osdConfig.getCapabilitySecret()); + + Replica r = Replica.newBuilder().setReplicationFlags(0).setStripingPolicy(SetupUtils.getStripingPolicy(1, 2)) + .addOsdUuids(serverID.toString()).build(); + XLocSet xloc = XLocSet.newBuilder().setReadOnlyFileSize(0).setReplicaUpdatePolicy("").addReplicas(r) + .setVersion(1).build(); + + fcred = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xloc).build(); + } + + @After + public void tearDown() throws Exception { + osdServer.shutdown(); + + testEnv.shutdown(); + } + + @Test + public void testRandomRanges() throws Exception { + // write object + ReusableBuffer buf = BufferPool.allocate(2048); + for (int i = 0; i < 2048; i++) + buf.put((byte) ((i % 26) + 65)); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(2048, resp.getSizeInBytes()); + + // do random reads + for (int round = 0; round < 200; round++) { + final int offset = (int) (Math.random() * 2048.0); + final int size = (int) (Math.random() * (2048.0 - (offset))); + System.out.println("offset: " + offset + " size: " + size); + assert (offset + size <= 2048); + RPCResponse rr = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, offset, size); + data = rr.get(); + ReusableBuffer dataOut = rr.getData(); + if (size == 0) + assertNull(dataOut); + else + assertEquals(size, dataOut.remaining()); + for (int i = 0; i < size; i++) { + assertEquals((byte) (((i + offset) % 26) + 65), dataOut.get()); + } + rr.freeBuffers(); + } + } + + @Test + public void testRandomRangesWithEOF() throws Exception { + // write object + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) ((i % 26) + 65)); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(1024, resp.getSizeInBytes()); + + // do random reads + for (int round = 0; round < 200; round++) { + final int offset = (int) (Math.random() * 2048.0); + final int size = (int) (Math.random() * (2048.0 - (offset))); + System.out.println("offset: " + offset + " size: " + size); + assert (offset + size <= 2048); + RPCResponse rr = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, offset, size); + data = rr.get(); + ReusableBuffer dataOut = rr.getData(); + if (offset + size < 1024) { + if (size == 0) + assertNull(dataOut); + else + assertEquals(size, dataOut.remaining()); + } else { + if (offset >= 1024) { + assertNull(dataOut); + } else { + assertEquals(1024 - offset, dataOut.remaining()); + } + } + final int remain = (dataOut == null) ? 0 : dataOut.remaining(); + for (int i = 0; i < remain; i++) { + assertEquals((byte) (((i + offset) % 26) + 65), dataOut.get()); + } + rr.freeBuffers(); + } + } + + @Test + public void testRangeReads() throws Exception { + + /* + * layout is obj 0: never written, does not exist on disk obj 1: 1024 written, 1024 implicit padding obj 2: 1024 + * written + */ + + // first test implicit truncate through write within a single object + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 1, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(2048 + 1024, resp.getSizeInBytes()); + + buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + buf.flip(); + r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 2, 0, 0, 0, data, buf); + resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(4096 + 1024, resp.getSizeInBytes()); + + // get a range on a fully zero padded object + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 128, 2048 - 128); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + assertEquals(2048 - 128, data.getZeroPadding()); + assertNull(dataOut); // 0 length is now a NULL buffer + r2.freeBuffers(); + + // get only the buffer, not the padding from object 1 + r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 1, 0, 0, 1024); + data = r2.get(); + dataOut = r2.getData(); + + assertEquals(0, data.getZeroPadding()); + assertEquals(1024, dataOut.capacity()); + r2.freeBuffers(); + + // get only the padding, not the buffer + r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 1, 0, 1024, 1024); + data = r2.get(); + dataOut = r2.getData(); + + assertEquals(1024, data.getZeroPadding()); + assertNull(dataOut); // 0 length = null buffer + r2.freeBuffers(); + + // get a bit of the buffer and a bit of the padding + r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 1, 0, 512, 1024); + data = r2.get(); + dataOut = r2.getData(); + + assertEquals(512, data.getZeroPadding()); + assertEquals(512, dataOut.capacity()); + r2.freeBuffers(); + + // get beyond EOF + r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 2, 0, 512, 1024); + data = r2.get(); + dataOut = r2.getData(); + + assertEquals(0, data.getZeroPadding()); + assertEquals(512, dataOut.capacity()); + r2.freeBuffers(); + + // get beyond EOF + r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 2, 0, 1024, 1024); + data = r2.get(); + dataOut = r2.getData(); + + assertEquals(0, data.getZeroPadding()); + assertNull(dataOut); // 0 length = null buffer + r2.freeBuffers(); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/OSDTruncateTest.java b/java/servers/test/org/xtreemfs/test/osd/OSDTruncateTest.java new file mode 100644 index 0000000..5a51425 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/OSDTruncateTest.java @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.mrc.ac.FileAccessManager; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +public class OSDTruncateTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static ServiceUUID serverID; + + private static FileCredentials fcred; + + private static String fileId; + + private static Capability cap; + + private static OSDConfig osdConfig; + + private OSDServiceClient osdClient; + + private OSD osdServer; + private TestEnvironment testEnv; + + @BeforeClass + public static void initializeTest() throws Exception { + + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + osdConfig = SetupUtils.createOSD1Config(); + serverID = SetupUtils.getOSD1UUID(); + } + + @Before + public void setUp() throws Exception { + // startup: DIR + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.OSD_CLIENT }); + testEnv.start(); + + osdServer = new OSD(osdConfig); + + synchronized (this) { + try { + this.wait(50); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + + osdClient = new OSDServiceClient(testEnv.getRpcClient(), null); + + fileId = "ABCDEF:1"; + cap = new Capability(fileId, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber() | FileAccessManager.NON_POSIX_DELETE, 60, + System.currentTimeMillis(), "", 0, false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, + osdConfig.getCapabilitySecret()); + + Replica r = Replica.newBuilder().setReplicationFlags(0).setStripingPolicy(SetupUtils.getStripingPolicy(1, 2)) + .addOsdUuids(serverID.toString()).build(); + XLocSet xloc = XLocSet.newBuilder().setReadOnlyFileSize(0).setReplicaUpdatePolicy("").addReplicas(r) + .setVersion(1).build(); + + fcred = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xloc).build(); + } + + @After + public void tearDown() throws Exception { + osdServer.shutdown(); + + testEnv.shutdown(); + } + + @Test + public void testDeleteFile() throws Exception { + // wirte first 1024 bytes to object 0 + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(1024, resp.getSizeInBytes()); + + RPCResponse dr = osdClient.unlink(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId); + dr.get(); + dr.freeBuffers(); + } + + @Test + public void testTruncateShrink() throws Exception { + // wirte first 1024 bytes to object 0 + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(1024, resp.getSizeInBytes()); + + buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'C'); + buf.flip(); + r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 3, 0, 0, 0, data, buf); + resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(3 * 2048 + 1024, resp.getSizeInBytes()); + + XCap newCap = fcred.getXcap().toBuilder().setTruncateEpoch(1).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + // truncate shrink to 3 object, 3rd object half + r = osdClient.truncate(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 2048 * 2 + 1024); + resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(2 * 2048 + 1024, resp.getSizeInBytes()); + + // get object 2 should be 1024 bytes long, no padding + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 2, 0, 0, 2048); + data = r2.get(); + + assertEquals(0, data.getZeroPadding()); + assertEquals(1024, r2.getData().capacity()); + r2.freeBuffers(); + + // get object 0 should be 2048 bytes long, either half data + half zeros or padding + r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 0, 0, 0, 2048); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + assertTrue((data.getZeroPadding() == 0) && (dataOut.capacity() == 2048) || (data.getZeroPadding() == 1024) + && (dataOut.capacity() == 1024)); + r2.freeBuffers(); + } + + @Test + public void testTruncateShrink2() throws Exception { + // wirte first 1024 bytes to object 0 + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 6, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(6 * 2048 + 1024, resp.getSizeInBytes()); + + XCap newCap = fcred.getXcap().toBuilder().setTruncateEpoch(1).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + // truncate shrink to 3 object, 3rd object half + r = osdClient.truncate(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 2048 * 2 + 1024); + resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(2 * 2048 + 1024, resp.getSizeInBytes()); + + // get object 2 should be 1024 bytes long, no padding + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 6, 0, 0, 2048); + data = r2.get(); + + assertEquals(0, data.getZeroPadding()); + assertNull(r2.getData()); // null equals length 0 + r2.freeBuffers(); + } + + @Test + public void testTruncateShrinkInObject() throws Exception { + // wirte first 1024 bytes to object 0 + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(1024, resp.getSizeInBytes()); + + XCap newCap = fcred.getXcap().toBuilder().setTruncateEpoch(1).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + // truncate shrink to 512 + r = osdClient.truncate(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 512); + resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(512, resp.getSizeInBytes()); + + // get a range on a fully zero padded object + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 2048); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + assertEquals(0, data.getZeroPadding()); + assertEquals(512, dataOut.capacity()); + + for (int i = 0; i < 512; i++) + assertEquals((byte) 'A', dataOut.get()); + + r2.freeBuffers(); + } + + @Test + public void testTruncateShrinkInObject2() throws Exception { + // wirte first 1024 bytes to object 0 + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(1024, resp.getSizeInBytes()); + + XCap newCap = fcred.getXcap().toBuilder().setTruncateEpoch(1).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + // wirte first 512 bytes to object 0 + ReusableBuffer buf2 = BufferPool.allocate(512); + for (int i = 0; i < 512; i++) + buf2.put((byte) 'B'); + buf2.flip(); + data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false).build(); + RPCResponse r2 = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 0, data, buf2); + OSDWriteResponse resp2 = r2.get(); + r2.freeBuffers(); + assertFalse(resp2.hasSizeInBytes()); + + newCap = fcred.getXcap().toBuilder().setTruncateEpoch(1).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + // truncate shrink to 512 + r = osdClient.truncate(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 512); + resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(512, resp.getSizeInBytes()); + + // get a range on a fully zero padded object + RPCResponse r3 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 2048); + data = r3.get(); + ReusableBuffer dataOut = r3.getData(); + + assertEquals(0, data.getZeroPadding()); + assertEquals(512, dataOut.capacity()); + + for (int i = 0; i < 512; i++) + assertEquals((byte) 'B', dataOut.get()); + + r3.freeBuffers(); + } + + @Test + public void testTruncateExtendInObject() throws Exception { + // wirte first 1024 bytes to object 0 + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(1024, resp.getSizeInBytes()); + + XCap newCap = fcred.getXcap().toBuilder().setTruncateEpoch(1).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + // truncate extend to 2047 + r = osdClient.truncate(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 2047); + resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(2047, resp.getSizeInBytes()); + + // get a range on a fully zero padded object + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 2048); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + assertEquals(0, data.getZeroPadding()); + assertEquals(2047, dataOut.capacity()); + + for (int i = 0; i < 1024; i++) + assertEquals((byte) 'A', dataOut.get()); + for (int i = 0; i < 1023; i++) + assertEquals((byte) 0, dataOut.get()); + + r2.freeBuffers(); + } + + @Test + public void testTruncateExtend() throws Exception { + // wirte first 1024 bytes to object 0 + ReusableBuffer buf = BufferPool.allocate(1024); + for (int i = 0; i < 1024; i++) + buf.put((byte) 'A'); + buf.flip(); + ObjectData data = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = osdClient.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 0, 0, 0, 0, data, buf); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(1024, resp.getSizeInBytes()); + + XCap newCap = fcred.getXcap().toBuilder().setTruncateEpoch(1).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + // truncate extend to 4 objects + + r = osdClient.truncate(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 2048 * 4); + resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(2048 * 4, resp.getSizeInBytes()); + + // get a range on a fully zero padded object + RPCResponse r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, fileId, 2, 0, 0, 2048); + data = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + assertEquals(2048, data.getZeroPadding()); + assertNull(dataOut); // null equals length 0 + r2.freeBuffers(); + + r2 = osdClient.read(serverID.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + fileId, 3, 0, 0, 2048); + data = r2.get(); + dataOut = r2.getData(); + + assertEquals(0, data.getZeroPadding()); + assertEquals(2048, dataOut.capacity()); + r2.freeBuffers(); + } + + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/SimpleVivaldiStageTest.java b/java/servers/test/org/xtreemfs/test/osd/SimpleVivaldiStageTest.java new file mode 100644 index 0000000..121470f --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/SimpleVivaldiStageTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertEquals; + +import java.net.DatagramPacket; +import java.net.DatagramSocket; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.MessageType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader; +import org.xtreemfs.foundation.pbrpc.utils.PBRPCDatagramPacket; +import org.xtreemfs.osd.vivaldi.VivaldiNode; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.VivaldiCoordinates; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_pingMesssage; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestEnvironment.Services; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class SimpleVivaldiStageTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + TestEnvironment env; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @AfterClass + public static void shutdownTest() throws Exception { + } + + @Before + public void setUp() throws Exception { + env = new TestEnvironment(new TestEnvironment.Services[] { Services.DIR_SERVICE, Services.OSD, + Services.OSD_CLIENT }); + env.start(); + } + + @After + public void tearDown() { + env.shutdown(); + } + + @Test + public void testVivaldiPing() throws Exception { + xtreemfs_pingMesssage payload = xtreemfs_pingMesssage + .newBuilder() + .setRequestResponse(true) + .setCoordinates( + VivaldiCoordinates.newBuilder().setXCoordinate(1.1).setYCoordinate(1.2).setLocalError(0.5)) + .build(); + + RPCHeader.RequestHeader rqHdr = RPCHeader.RequestHeader.newBuilder().setAuthData(RPCAuthentication.authNone) + .setUserCreds(RPCAuthentication.userService).setInterfaceId(OSDServiceConstants.INTERFACE_ID) + .setProcId(OSDServiceConstants.PROC_ID_XTREEMFS_PING).build(); + RPCHeader hdr = RPCHeader.newBuilder().setCallId(5).setMessageType(MessageType.RPC_REQUEST) + .setRequestHeader(rqHdr).build(); + + PBRPCDatagramPacket dpack = new PBRPCDatagramPacket(hdr, payload); + + DatagramSocket dsock = new DatagramSocket(); + byte[] data = dpack.assembleDatagramPacket().array(); + DatagramPacket dpack2 = new DatagramPacket(data, data.length, env.getOSDAddress()); + dsock.send(dpack2); + + DatagramPacket answer = new DatagramPacket(new byte[2048], 2048); + dsock.setSoTimeout(250); + dsock.receive(answer); + + ReusableBuffer rb = ReusableBuffer.wrap(answer.getData(), 0, answer.getLength()); + dpack = new PBRPCDatagramPacket(rb, payload); + + // System.out.println("result: "+dpack.getMessage()); + + dsock.close(); + } + + /* + * @Test public void testVivaldiPingTCP() throws Exception { RPCResponse vc = + * env.getOSDClient().internal_vivaldi_ping(env.getOSDAddress(), new VivaldiCoordinates(1.1, 1.2, 0.5)); + * VivaldiCoordinates rv = vc.get(); vc.freeBuffers(); + * + * + * } + */ + + @Test + public void testVivaldiCoordinates() throws Exception { + final VivaldiCoordinates c1 = VivaldiCoordinates.newBuilder().setXCoordinate(1.1).setYCoordinate(1.2) + .setLocalError(0.5).build(); + final String c1s = VivaldiNode.coordinatesToString(c1); + final VivaldiCoordinates c2 = VivaldiNode.stringToCoordinates(c1s); + + assertEquals((Double) c1.getXCoordinate(), (Double) c2.getXCoordinate()); + assertEquals((Double) c1.getYCoordinate(), (Double) c2.getYCoordinate()); + assertEquals((Double) c1.getLocalError(), (Double) c2.getLocalError()); + } + // public void hello() {} + +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/test/osd/StorageLayoutTest.java b/java/servers/test/org/xtreemfs/test/osd/StorageLayoutTest.java new file mode 100644 index 0000000..5f99d2f --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/StorageLayoutTest.java @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.checksums.ChecksumFactory; +import org.xtreemfs.foundation.checksums.provider.JavaChecksumProvider; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.storage.FileMetadata; +import org.xtreemfs.osd.storage.HashStorageLayout; +import org.xtreemfs.osd.storage.MetadataCache; +import org.xtreemfs.osd.storage.ObjectInformation; +import org.xtreemfs.osd.storage.SingleFileStorageLayout; +import org.xtreemfs.osd.storage.StorageLayout; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class StorageLayoutTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + static OSDConfig config; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL); + config = SetupUtils.createOSD1Config(); + } + + @Before + public void setUp() throws Exception { + FSUtils.delTree(new File(config.getObjDir())); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testHashStorageLayoutBasics() throws Exception { + + HashStorageLayout layout = new HashStorageLayout(config, new MetadataCache()); + basicTests(layout); + } + + @Test + public void testHashStorageLayoutWithChecksumsBasics() throws Exception { + + JavaChecksumProvider j = new JavaChecksumProvider(); + ChecksumFactory.getInstance().addProvider(j); + SetupUtils.CHECKSUMS_ON = true; + OSDConfig configCSUM = SetupUtils.createOSD1Config(); + SetupUtils.CHECKSUMS_ON = false; + HashStorageLayout layout = new HashStorageLayout(configCSUM, new MetadataCache()); + basicTests(layout); + } + + @Test + public void testSingleFileLayout() throws Exception { + SingleFileStorageLayout layout = new SingleFileStorageLayout(config, new MetadataCache()); + basicTests(layout); + } + + @Test + public void testSingleFileStorageLayoutWithChecksumsBasics() throws Exception { + + JavaChecksumProvider j = new JavaChecksumProvider(); + ChecksumFactory.getInstance().addProvider(j); + SetupUtils.CHECKSUMS_ON = true; + OSDConfig configCSUM = SetupUtils.createOSD1Config(); + SetupUtils.CHECKSUMS_ON = false; + SingleFileStorageLayout layout = new SingleFileStorageLayout(configCSUM, new MetadataCache()); + basicTests(layout); + } + + @Test + public void testHashStorageLayoutGetObjectList() throws Exception { + + HashStorageLayout layout = new HashStorageLayout(config, new MetadataCache()); + getObjectListTest(layout); + } + + @Test + public void testSingleFileStorageLayoutGetObjectList() throws Exception { + + SingleFileStorageLayout layout = new SingleFileStorageLayout(config, new MetadataCache()); + getObjectListTest(layout); + } + + @Test + public void testHashStorageLayoutGetFileIDList() throws Exception { + + HashStorageLayout layout = new HashStorageLayout(config, new MetadataCache()); + getFileIDListTest(layout); + } + + @Test + public void testSingleFileStorageLayoutGetFileIDList() throws Exception { + + SingleFileStorageLayout layout = new SingleFileStorageLayout(config, new MetadataCache()); + getFileIDListTest(layout); + } + + /** + * @param layout + * @throws IOException + */ + private void basicTests(StorageLayout layout) throws IOException { + final String fileId = "ABCDEFG:0001"; + + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 64)).setReplicationFlags(0) + .build(); + StripingPolicyImpl sp = StripingPolicyImpl.getPolicy(r, 0);// new RAID0(64, 1); + + /* + * FileMetadata md = new FileMetadata(sp); md.initLatestObjectVersions(new HashMap()); + * md.initLargestObjectVersions(new HashMap()); md.initObjectChecksums(new HashMap()); + */ + + FileMetadata md = layout.getFileMetadata(sp, fileId); + assertNotNull(md); + + assertFalse(layout.fileExists(fileId)); + + ReusableBuffer data = BufferPool.allocate(64); + for (int i = 0; i < 64; i++) { + data.put((byte) (48 + i)); + } + data.flip(); + // write 64 bytes + layout.writeObject(fileId, md, data, 0l, 0, 1l, false, false); + + // read full object + ObjectInformation oinfo = layout.readObject(fileId, md, 0l, 0, StorageLayout.FULL_OBJECT_LENGTH, 1l); + assertEquals(64, oinfo.getData().capacity()); + for (int i = 0; i < 64; i++) { + assertEquals((byte) (48 + i), oinfo.getData().get()); + } + BufferPool.free(oinfo.getData()); + + // read object 1 (does not exist) + oinfo = layout.readObject(fileId, md, 1l, 0, StorageLayout.FULL_OBJECT_LENGTH, 1l); + assertEquals(ObjectInformation.ObjectStatus.DOES_NOT_EXIST, oinfo.getStatus()); + + // range test + oinfo = layout.readObject(fileId, md, 0l, 32, 32, 1l); + assertEquals(32, oinfo.getData().capacity()); + for (int i = 32; i < 64; i++) { + assertEquals((byte) (48 + i), oinfo.getData().get()); + } + BufferPool.free(oinfo.getData()); + + // range test + oinfo = layout.readObject(fileId, md, 0l, 32, 1, 1l); + assertEquals(1, oinfo.getData().capacity()); + for (int i = 32; i < 33; i++) { + assertEquals((byte) (48 + i), oinfo.getData().get()); + } + BufferPool.free(oinfo.getData()); + + oinfo = layout.readObject(fileId, md, 0l, 32, 64, 1l); + assertEquals(32, oinfo.getData().capacity()); + for (int i = 32; i < 64; i++) { + assertEquals((byte) (48 + i), oinfo.getData().get()); + } + BufferPool.free(oinfo.getData()); + + // truncate to 32 byte + layout.truncateObject(fileId, md, 0l, 32, 1, false); + oinfo = layout.readObject(fileId, md, 0l, 32, 64, 1l); + assertTrue(((oinfo.getData() == null) || (oinfo.getData().capacity() == 0))); + BufferPool.free(oinfo.getData()); + + // read (non-existent) data from offset 32 + oinfo = layout.readObject(fileId, md, 0l, 0, 32, 1l); + assertEquals(32, oinfo.getData().capacity()); + for (int i = 0; i < 32; i++) { + assertEquals((byte) (48 + i), oinfo.getData().get()); + } + BufferPool.free(oinfo.getData()); + + // truncate extend to 64 bytes + layout.truncateObject(fileId, md, 0l, 64, 2, false); + oinfo = layout.readObject(fileId, md, 0l, 32, 64, 2l); + assertEquals(32, oinfo.getData().capacity()); + for (int i = 0; i < 32; i++) { + assertEquals((byte) 0, oinfo.getData().get()); + } + BufferPool.free(oinfo.getData()); + + // write more objects... + // obj 1 = hole + // obj 2 = second half + // obj 3 = full + + data = BufferPool.allocate(32); + for (int i = 0; i < 32; i++) { + data.put((byte) (48 + i)); + } + data.flip(); + // write 64 bytes + layout.writeObject(fileId, md, data, 2l, 0, 1l, false, false); + + data = BufferPool.allocate(64); + for (int i = 0; i < 64; i++) { + data.put((byte) (48 + i)); + } + data.flip(); + // write 64 bytes + layout.writeObject(fileId, md, data, 3l, 0, 1l, false, false); + + // read object 1... should be all zeros or zero padding + oinfo = layout.readObject(fileId, md, 1l, 0, sp.getStripeSizeForObject(1), 1l); + if (oinfo.getStatus() == ObjectInformation.ObjectStatus.PADDING_OBJECT) { + // fine + } else if (oinfo.getStatus() == ObjectInformation.ObjectStatus.DOES_NOT_EXIST) { + // also fine + } else { + // we expect full stripe size of zeros + assertEquals(sp.getStripeSizeForObject(1), oinfo.getData().capacity()); + for (int i = 0; i < sp.getStripeSizeForObject(1); i++) { + assertEquals((byte) 0, oinfo.getData().get()); + } + BufferPool.free(oinfo.getData()); + } + + } + + private void getObjectListTest(StorageLayout layout) throws IOException { + final String fileId = "ABCDEFG:0001"; + + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 64)).setReplicationFlags(0) + .build(); + StripingPolicyImpl sp = StripingPolicyImpl.getPolicy(r, 0);// new RAID0(64, 1); + + FileMetadata md = layout.getFileMetadata(sp, fileId); + assertNotNull(md); + + assertFalse(layout.fileExists(fileId)); + assertEquals(0, layout.getObjectSet(fileId, md).size()); + + ReusableBuffer data = BufferPool.allocate(64); + for (int i = 0; i < 64; i++) { + data.put((byte) (48 + i)); + } + + // objects to write + long objectNos[] = { 0, 2, 4, 8, 10, 12, 20, 24, 32, 44, 46, 48, 50 }; + + // write objects + for (long objNo : objectNos) { + layout.writeObject(fileId, md, data.createViewBuffer(), objNo, 0, 1, false, false); + } + BufferPool.free(data); + + ObjectSet objectList = layout.getObjectSet(fileId, md); + // check + ObjectSet objectNosList = new ObjectSet(1, 0, objectNos.length); + for (long object : objectNos) + objectNosList.add(object); + assertTrue(objectList.equals(objectNosList)); + } + + private void getFileIDListTest(StorageLayout layout) throws IOException { + final ArrayList fileIDs = new ArrayList(); + fileIDs.add("0002:ABCDEF"); + fileIDs.add("0012:GHIJKL"); + fileIDs.add("0123:MNOPQR"); + fileIDs.add("1234:STUVWX"); + + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 64)).setReplicationFlags(0) + .build(); + StripingPolicyImpl sp = StripingPolicyImpl.getPolicy(r, 0);// new RAID0(64, 1); + + // create some data + ReusableBuffer data = BufferPool.allocate(64); + for (int i = 0; i < 64; i++) { + data.put((byte) (48 + i)); + } + data.flip(); + + // create some files + for (String f : fileIDs) { + String fileId = f; + FileMetadata md = layout.getFileMetadata(sp, fileId); + + assertNotNull(md); + + assertFalse(layout.fileExists(fileId)); + + // write 64 bytes + layout.writeObject(fileId, md, data.createViewBuffer(), 0l, 0, 1l, false, false); + } + + ArrayList newFileIDs = layout.getFileIDList(); + // compare fileIDs with newFileIDs + assertTrue(newFileIDs.containsAll(fileIDs)); + assertTrue(fileIDs.containsAll(newFileIDs)); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/StorageStageTest.java b/java/servers/test/org/xtreemfs/test/osd/StorageStageTest.java new file mode 100644 index 0000000..fc92356 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/StorageStageTest.java @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2009-2011 by Jan Stender, Bjoern Kolbeck, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.test.TestHelper; + +// TODO +public class StorageStageTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + @Test + public void testDummy() { + + } + +// /* +// * needed for checking the results +// */ +// private class TestRequestController implements RequestHandler, UDPCom { +// +// private OSDRequest lastRequest = null; +// +// public TestRequestController(OSDId me) throws IOException { +// } +// +// public OSDId getMe() { +// return OSDID; +// } +// +// /** +// * blocks untill a Request is received +// * +// * @return last received Request +// */ +// public synchronized OSDRequest getLastRequest(long timeout) { +// if (lastRequest == null) { +// try { +// wait(timeout); +// } catch (InterruptedException ex) { +// ex.printStackTrace(); +// } +// } +// OSDRequest ret = lastRequest; +// lastRequest = null; +// return ret; +// } +// +// public synchronized void stageCallback(OSDRequest request) { +// lastRequest = request; +// BufferPool.free(request.getData()); +// notify(); +// } +// +// public void sendUDP(ReusableBuffer data, InetSocketAddress receiver) { +// throw new UnsupportedOperationException("Not supported yet."); +// } +// +// public void receiveUDP(ReusableBuffer data, InetSocketAddress sender) { +// throw new UnsupportedOperationException("Not supported yet."); +// } +// +// public void sendInternalEvent(OSDRequest event) { +// } +// } +// +// final OSDId OSDID = new OSDId("localhost", 32636, +// OSDId.SCHEME_HTTP); +// +// StorageStage stage; +// +// TestRequestController controller; +// +// File dbDir; +// +// OSDConfig config; +// +// StripingPolicy sp; +// +// Location loc; +// +// MultiSpeedy speedy; +// +// public StorageStageTest(String testName) throws IOException { +// super(testName); +// Logging.start(SetupUtils.DEBUG_LEVEL); +// +// config = SetupUtils.createOSD1ConfigForceWithoutSSL(); +// controller = new TestRequestController(OSDID); +// stage = null; +// +// dbDir = new File(config.getObjDir()); +// FSTools.delTree(dbDir); +// +// sp = new RAID0(1, 1); +// List osd = new ArrayList(); +// osd.add(OSDID); +// loc = new Location(sp, osd); +// } +// +// protected void setUp() throws Exception { +// System.out.println("TEST: " + getClass().getSimpleName() + "." +// + getName()); +// speedy = new MultiSpeedy(); +// stage = new StorageStage(controller, controller, config, speedy); +// stage.start(); +// } +// +// protected void tearDown() throws Exception { +// FSTools.delTree(dbDir); +// stage.shutdown(); +// speedy.shutdown(); +// stage.waitForShutdown(); +// speedy.waitForShutdown(); +// stage = null; +// } +// +// /* +// * Tests +// */ +// +// // TODO: write better assert +// public void testFileWrite() { +// for (int i = 0; i < 10; i++) { +// System.out.println("TEST: " + getClass().getSimpleName() + "." +// + getName() + ":" + i); +// +// OSDRequest rq = createWriteRequest(1000); +// stage.enqueueRequest(rq); +// OSDRequest rqR = controller.getLastRequest(OSDClient.TIMEOUT); +// +// assertEquals(OSDRequest.Status.PERSISTED, rqR.getStatus()); +// } +// } +// +// // TODO: write better assert +// public void testFileRead() { +// for (int i = 0; i < 10; i++) { +// System.out.println("TEST: " + getClass().getSimpleName() + "." +// + getName() + ":" + i); +// +// OSDRequest rq1 = createWriteRequest(10); +// stage.enqueueRequest(rq1); +// OSDRequest rq1R = controller.getLastRequest(OSDClient.TIMEOUT); +// +// OSDRequest rq2 = createReadRequest(rq1.getFileId(), rq1 +// .getObjectNo()); +// stage.enqueueRequest(rq2); +// OSDRequest rq2R = controller.getLastRequest(OSDClient.TIMEOUT); +// +// assertEquals(OSDRequest.Status.PERSISTED, rq2R.getStatus()); +// } +// } +// +// // TODO: write better assert +// public void testFileDelete() { +// for (int i = 0; i < 10; i++) { +// System.out.println("TEST: " + getClass().getSimpleName() + "." +// + getName() + ":" + i); +// +// OSDRequest rq1 = createWriteRequest(10); +// stage.enqueueRequest(rq1); +// OSDRequest rq1R = controller.getLastRequest(OSDClient.TIMEOUT); +// +// OSDRequest rq2 = createDeleteRequest(rq1.getFileId(), rq1 +// .getObjectNo()); +// stage.enqueueRequest(rq2); +// OSDRequest rq2R = controller.getLastRequest(OSDClient.TIMEOUT); +// +// assertEquals(OSDRequest.Status.PERSISTED, rq2R.getStatus()); +// } +// } +// +// /** +// * setup a WriteRequest +// */ +// private OSDRequest createWriteRequest(int dataLength) +// throws IllegalArgumentException { +// OSDRequest rq = new OSDRequest(new PinkyRequest()); +// // set the needed parameters +// OSDOperation op = new OSDOperation(OperationType.WRITE, +// OperationSubType.WHOLE); +// rq.setOSDOperation(op); +// String id = generateFileId(); +// rq.setFileId(id); +// rq.setObjectNo(1); +// rq.setPolicy(sp); +// rq.setLocation(loc); +// rq.setCapability(new Capability(id, "write", "IAmTheClient", 0)); +// +// byte[] bytes = generateRandomBytes(dataLength); +// ReusableBuffer buf = ReusableBuffer.wrap(bytes); +// rq.getRequest().requestBody = buf; +// rq.getRequest().requestBdyLength = buf.capacity(); +// return rq; +// } +// +// /** +// * setup a ReadRequest +// */ +// private OSDRequest createReadRequest(String fileId, long objNo) +// throws IllegalArgumentException { +// OSDRequest rq = new OSDRequest(new PinkyRequest()); +// // set the needed parameters +// OSDOperation op = new OSDOperation(OperationType.READ, +// OperationSubType.WHOLE); +// rq.setOSDOperation(op); +// +// rq.setFileId(fileId); +// rq.setObjectNo(objNo); +// rq.setPolicy(sp); +// rq.setLocation(loc); +// rq.setCapability(new Capability(fileId, "read", "IAmTheClient", 0)); +// +// return rq; +// } +// +// /** +// * setup a ReadRequest +// */ +// private OSDRequest createDeleteRequest(String fileId, long objNo) +// throws IllegalArgumentException { +// OSDRequest rq = new OSDRequest(new PinkyRequest()); +// +// // set the needed parameters +// OSDOperation op = new OSDOperation(OperationType.DELETE, +// OperationSubType.WHOLE); +// rq.setOSDOperation(op); +// +// rq.setLocation(loc); +// rq.setFileId(fileId); +// rq.setObjectNo(objNo); +// rq.setPolicy(sp); +// rq.setCapability(new Capability(fileId, "delete", "IAmTheClient", 0)); +// +// return rq; +// } +// +// /** +// * generates randomly filled byte-array +// * +// * @param length +// * length of the byte-array +// */ +// private byte[] generateRandomBytes(int length) { +// Random r = new Random(); +// byte[] bytes = new byte[length]; +// +// r.nextBytes(bytes); +// return bytes; +// } +// +// /** +// * generates randomly Filename +// */ +// private String generateFileId() throws IllegalArgumentException { +// Random r = new Random(); +// String id = new String(r.nextInt(10) + ":" + r.nextInt(1000000)); +// +// return id; +// } +// +// public static void main(String[] args) { +// TestRunner.run(StorageStageTest.class); +// } +//} +// +// +//class MultiThreadedStorageStageTest extends TestCase { +// +// /* +// * needed for checking the results +// */ +// private class TestRequestController implements RequestHandler, UDPCom { +// private OSDId me; +// private OSDRequest lastRequest = null; +// private int num_requests_processed; +// +// public TestRequestController(OSDId me) throws IOException { +// this.me = me; +// num_requests_processed = 0; +// } +// +// public OSDId getMe() { +// return OSDID; +// } +// +// /** +// * blocks until a Request is received +// * @return last received Request +// */ +// public synchronized OSDRequest getLastRequest(long timeout) { +// if(lastRequest == null) { +// try { +// wait(timeout); +// } +// catch (InterruptedException ex) { +// ex.printStackTrace(); +// } +// } +// OSDRequest ret = lastRequest; +// lastRequest = null; +// return ret; +// } +// +// public synchronized void stageCallback(OSDRequest request) { +// //lastRequest = request; +// //System.out.println("++++" + num_requests_processed + ": stage callback: request " + request.getFileId()); +// num_requests_processed++; +// BufferPool.free(request.getData()); +// //notify(); +// } +// +// public void sendUDP(ReusableBuffer data, InetSocketAddress receiver) { +// throw new UnsupportedOperationException("Not supported yet."); +// } +// +// public void receiveUDP(ReusableBuffer data, InetSocketAddress sender) { +// throw new UnsupportedOperationException("Not supported yet."); +// } +// +// public void sendInternalEvent(OSDRequest event) { +// } +// } +// +// final OSDId OSDID = new OSDId("localhost",32636, OSDId.SCHEME_HTTP); +// +// MultithreadedStorageStage stage; +// TestRequestController controller; +// File dbDir; +// OSDConfig config; +// +// StripingPolicy sp; +// Location loc; +// +// MultiSpeedy speedy; +// +// +// public MultiThreadedStorageStageTest(String testName) throws IOException { +// super(testName); +// Logging.start(SetupUtils.DEBUG_LEVEL); +// +// config = SetupUtils.createOSD1ConfigForceWithoutSSL(); +// controller = new TestRequestController(OSDID); +// stage = null; +// +// dbDir = new File(config.getObjDir()); +// FSTools.delTree(dbDir); +// +// sp = new RAID0(1,1); +// List osd = new ArrayList(); +// osd.add(OSDID); +// loc = new Location(sp,osd); +// } +// +// protected void setUp() throws Exception { +// System.out.println("TEST: " + getClass().getSimpleName() + "." + getName()); +// speedy = new MultiSpeedy(); +// stage = new MultithreadedStorageStage(controller, controller, config, speedy,10); +// stage.start(); +// } +// +// protected void tearDown() throws Exception { +// FSTools.delTree(dbDir); +// stage.shutdown(); +// speedy.shutdown(); +// stage.waitForShutdown(); +// speedy.waitForShutdown(); +// stage = null; +// } +// +// /* +// * Tests +// */ +// +// // TODO: write better assert +// public void testMultipleRequests() throws InterruptedException { +// int numRequests = 10; +// for(int i=0; i { + + private long issuedEpoch; + + private long epoch; + + private long fileSize; + + private final String capSecret; + + public MRCDummy(String capSecret) { + this.capSecret = capSecret; + } + + Capability open(char mode) { + if (mode == 't') + issuedEpoch++; + + return new Capability(FILE_ID, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber(), 60, System.currentTimeMillis(), "", + (int) issuedEpoch, false, COW ? SnapConfig.SNAP_CONFIG_ACCESS_CURRENT + : SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, capSecret); + } + + synchronized long getFileSize() { + return fileSize; + } + + @Override + public void responseAvailable(RPCResponse r) { + try { + + OSDWriteResponse resp = r.get(); + // System.out.println("fs-update: " + resp); + + if (resp.hasSizeInBytes()) { + + final long newFileSize = resp.getSizeInBytes(); + final long epochNo = resp.getTruncateEpoch(); + + if (epochNo < epoch) + return; + + if (epochNo > epoch || newFileSize > fileSize) { + epoch = epochNo; + fileSize = newFileSize; + } + } + + } catch (Exception exc) { + exc.printStackTrace(); + System.exit(1); + } + } + + } + + private static final String FILE_ID = "1:1"; + + private static final int KB = 1; + + private static final int SIZE = KB * 1024; + + private static final byte[] ZEROS_HALF = new byte[SIZE / 2]; + + private static final byte[] ZEROS = new byte[SIZE]; + + private static DIRConfig dirConfig; + + private static OSDConfig osdCfg1; + + private static OSDConfig osdCfg2; + + private static OSDConfig osdCfg3; + + private static String capSecret; + + private List osdServer; + + private List osdIDs; + + private OSDServiceClient client; + + private static StripingPolicyImpl sp; + + private XLocSet xloc; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + osdCfg1 = SetupUtils.createOSD1Config(); + osdCfg2 = SetupUtils.createOSD2Config(); + osdCfg3 = SetupUtils.createOSD3Config(); + + capSecret = osdCfg1.getCapabilitySecret(); + + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(3, KB)).setReplicationFlags(0) + .build(); + sp = StripingPolicyImpl.getPolicy(r, 0); + dirConfig = SetupUtils.createDIRConfig(); + + } + + @Before + public void setUp() throws Exception { + + // startup: DIR + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.OSD_CLIENT }); + testEnv.start(); + + osdIDs = new ArrayList(3); + osdIDs.add(SetupUtils.getOSD1UUID()); + osdIDs.add(SetupUtils.getOSD2UUID()); + osdIDs.add(SetupUtils.getOSD3UUID()); + + osdServer = new ArrayList(3); + osdServer.add(new OSD(osdCfg1)); + osdServer.add(new OSD(osdCfg2)); + osdServer.add(new OSD(osdCfg3)); + + client = testEnv.getOSDClient(); + + List osdset = new ArrayList(3); + osdset.add(SetupUtils.getOSD1UUID().toString()); + osdset.add(SetupUtils.getOSD2UUID().toString()); + osdset.add(SetupUtils.getOSD3UUID().toString()); + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(3, KB)).setReplicationFlags(0) + .addAllOsdUuids(osdset).build(); + xloc = XLocSet.newBuilder().setReadOnlyFileSize(0).setVersion(1).addReplicas(r).setReplicaUpdatePolicy("") + .build(); + + } + + private Capability getCap(String fname) { + return new Capability(fname, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber(), 60, System.currentTimeMillis(), "", 0, false, + COW ? SnapConfig.SNAP_CONFIG_ACCESS_CURRENT : SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, capSecret); + } + + @After + public void tearDown() throws Exception { + + osdServer.get(0).shutdown(); + osdServer.get(1).shutdown(); + osdServer.get(2).shutdown(); + + testEnv.shutdown(); + } + + /* TODO: test delete/truncate epochs! */ + @Test + public void testPUTandGET() throws Exception { + + final int numObjs = 5; + final int[] testSizes = { 1, 2, SIZE - 1, SIZE }; + + for (int ts : testSizes) { + + ReusableBuffer data = SetupUtils.generateData(ts); + String file = "1:1" + ts; + final FileCredentials fcred = FileCredentials.newBuilder().setXcap(getCap(file).getXCap()).setXlocs(xloc) + .build(); + + for (int i = 0, osdIndex = 0; i < numObjs; i++, osdIndex = i % osdIDs.size()) { + + // write an object with the given test size + + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0) + .setInvalidChecksumOnOsd(false).build(); + RPCResponse r = client.write(osdIDs.get(osdIndex).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fcred, file, i, 0, 0, 0, objdata, + data.createViewBuffer()); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(i * SIZE + ts, resp.getSizeInBytes()); + + // read and check the previously written object + + RPCResponse r2 = client.read(osdIDs.get(osdIndex).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, file, i, 0, 0, data.capacity()); + ObjectData result = r2.get(); + checkResponse(data.array(), result, r2.getData()); + r2.freeBuffers(); + } + } + } + + @Test + public void testIntermediateHoles() throws Exception { + + final FileCredentials fcred = FileCredentials.newBuilder().setXcap(getCap(FILE_ID).getXCap()).setXlocs(xloc) + .build(); + + final ReusableBuffer data = SetupUtils.generateData(3); + + // write the nineth object, check the file size + int obj = 8; + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = client.write(osdIDs.get(obj % osdIDs.size()).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fcred, FILE_ID, obj, 0, 0, 0, objdata, + data.createViewBuffer()); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(obj * SIZE + data.limit(), resp.getSizeInBytes()); + + // write the fifth object, check the file size + obj = 5; + + r = client.write(osdIDs.get(obj % osdIDs.size()).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, obj, 0, 0, 0, objdata, data.createViewBuffer()); + resp = r.get(); + r.freeBuffers(); + assertTrue(!resp.hasSizeInBytes() + || (resp.hasSizeInBytes() && (obj * SIZE + data.limit() == resp.getSizeInBytes()))); + + // check whether the first object consists of zeros + obj = 0; + RPCResponse r2 = client.read(osdIDs.get(obj % osdIDs.size()).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fcred, FILE_ID, obj, 0, 0, data.capacity()); + ObjectData result = r2.get(); + // either padding data or all zeros + if (result.getZeroPadding() == 0) + checkResponse(ZEROS, result, r2.getData()); + else + assertEquals(data.capacity(), result.getZeroPadding()); + + r2.freeBuffers(); + + // write the first object, check the file size header (must be null) + r = client.write(osdIDs.get(obj % osdIDs.size()).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, obj, 0, 0, 0, objdata, data.createViewBuffer()); + resp = r.get(); + r.freeBuffers(); + assertFalse(resp.hasSizeInBytes()); + } + + @Test + public void testWriteExtend() throws Exception { + + final FileCredentials fcred = FileCredentials.newBuilder().setXcap(getCap(FILE_ID).getXCap()).setXlocs(xloc) + .build(); + + final ReusableBuffer data = SetupUtils.generateData(3); + final byte[] paddedData = new byte[SIZE]; + System.arraycopy(data.array(), 0, paddedData, 0, data.limit()); + + // write first object + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = client.write(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, 0, 0, 0, 0, objdata, data.createViewBuffer()); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + + // write second object + r = client.write(osdIDs.get(1).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + FILE_ID, 1, 0, 0, 0, objdata, data.createViewBuffer()); + resp = r.get(); + r.freeBuffers(); + + // read first object + + RPCResponse r2 = client.read(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, 0, 0, 0, SIZE); + ObjectData result = r2.get(); + ReusableBuffer dataOut = r2.getData(); + // System.out.println(result); + // either padding data or all zeros + assertNotNull(dataOut); + assertEquals(3, dataOut.capacity()); + assertEquals(SIZE - 3, result.getZeroPadding()); + r2.freeBuffers(); + + } + + /** + * tests the truncation of striped files + */ + @Test + public void testTruncate() throws Exception { + + ReusableBuffer data = SetupUtils.generateData(SIZE); + + FileCredentials fcred = FileCredentials.newBuilder().setXcap(getCap(FILE_ID).getXCap()).setXlocs(xloc).build(); + + // ------------------------------- + // create a file with five objects + // ------------------------------- + for (int i = 0, osdIndex = 0; i < 5; i++, osdIndex = i % osdIDs.size()) { + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0) + .setInvalidChecksumOnOsd(false).build(); + RPCResponse r = client.write(osdIDs.get(osdIndex).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fcred, FILE_ID, i, 0, 0, 0, objdata, + data.createViewBuffer()); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + } + + // ---------------------------------------------- + // shrink the file to a length of one full object + // ---------------------------------------------- + + XCap newCap = fcred.getXcap().toBuilder().setTruncateEpoch(1).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + RPCResponse rt = client.truncate(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, SIZE); + OSDWriteResponse resp = rt.get(); + rt.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(SIZE, resp.getSizeInBytes()); + + // check whether all objects have the expected content + for (int i = 0, osdIndex = 0; i < 5; i++, osdIndex = i % osdIDs.size()) { + + // try to read the object + RPCResponse r2 = client.read(osdIDs.get(osdIndex).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, i, 0, 0, SIZE); + ObjectData result = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + // the first object must exist, all other ones must have been + // deleted + if (i == 0) + checkResponse(data.array(), result, dataOut); + else + checkResponse(null, result, dataOut); + + r2.freeBuffers(); + } + + // ------------------------------------------------- + // extend the file to a length of eight full objects + // ------------------------------------------------- + newCap = fcred.getXcap().toBuilder().setTruncateEpoch(2).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + rt = client.truncate(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + fcred, FILE_ID, SIZE * 8); + resp = rt.get(); + rt.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(SIZE * 8, resp.getSizeInBytes()); + + // check whether all objects have the expected content + for (int i = 0, osdIndex = 0; i < 8; i++, osdIndex = i % osdIDs.size()) { + + // try to read the object + RPCResponse r2 = client.read(osdIDs.get(osdIndex).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, i, 0, 0, SIZE); + ObjectData result = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + // the first object must contain data, all other ones must contain + // zeros + if (i == 0) + checkResponse(data.array(), result, dataOut); + else { + if (dataOut == null) { + assertEquals(SIZE, result.getZeroPadding()); + } else { + checkResponse(ZEROS, result, dataOut); + } + + } + + r2.freeBuffers(); + } + + // ------------------------------------------ + // shrink the file to a length of 3.5 objects + // ------------------------------------------ + newCap = fcred.getXcap().toBuilder().setTruncateEpoch(3).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + final long size3p5 = (long) (SIZE * 3.5f); + rt = client.truncate(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + fcred, FILE_ID, size3p5); + resp = rt.get(); + rt.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(size3p5, resp.getSizeInBytes()); + + // check whether all objects have the expected content + for (int i = 0, osdIndex = 0; i < 5; i++, osdIndex = i % osdIDs.size()) { + + // try to read the object + RPCResponse r2 = client.read(osdIDs.get(osdIndex).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, i, 0, 0, SIZE); + ObjectData result = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + // the first object must contain data, all other ones must contain + // zeros, where the last one must only be half an object size + if (i == 0) + checkResponse(data.array(), result, dataOut); + else if (i == 3) + checkResponse(ZEROS_HALF, result, dataOut); + else if (i >= 4) { + assertEquals(0, result.getZeroPadding()); + assertNull(dataOut); + } else { + if (dataOut == null) { + assertEquals(SIZE, result.getZeroPadding()); + } else { + checkResponse(ZEROS, result, dataOut); + } + } + + r2.freeBuffers(); + } + + // -------------------------------------------------- + // truncate the file to the same length it had before + // -------------------------------------------------- + newCap = fcred.getXcap().toBuilder().setTruncateEpoch(4).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + rt = client.truncate(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + fcred, FILE_ID, size3p5); + resp = rt.get(); + rt.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(size3p5, resp.getSizeInBytes()); + + // check whether all objects have the expected content + for (int i = 0, osdIndex = 0; i < 5; i++, osdIndex = i % osdIDs.size()) { + + // try to read the object + RPCResponse r2 = client.read(osdIDs.get(osdIndex).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, i, 0, 0, SIZE); + ObjectData result = r2.get(); + ReusableBuffer dataOut = r2.getData(); + + // the first object must contain data, all other ones must contain + // zeros, where the last one must only be half an object size + if (i == 0) + checkResponse(data.array(), result, dataOut); + else if (i == 3) + checkResponse(ZEROS_HALF, result, dataOut); + else if (i >= 4) { + assertEquals(0, result.getZeroPadding()); + assertNull(dataOut); + } else { + if (dataOut == null) { + assertEquals(SIZE, result.getZeroPadding()); + } else { + checkResponse(ZEROS, result, dataOut); + } + } + + r2.freeBuffers(); + } + + // -------------------------------- + // truncate the file to zero length + // -------------------------------- + newCap = fcred.getXcap().toBuilder().setTruncateEpoch(5).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + rt = client.truncate(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + fcred, FILE_ID, 0); + resp = rt.get(); + rt.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(0, resp.getSizeInBytes()); + + // check whether all objects have the expected content + for (int i = 0, osdIndex = 0; i < 5; i++, osdIndex = i % osdIDs.size()) { + + // try to read the object + RPCResponse r2 = client.read(osdIDs.get(osdIndex).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, i, 0, 0, SIZE); + ObjectData result = r2.get(); + + assertEquals(0, result.getZeroPadding()); + assertNull(r2.getData()); + + r2.freeBuffers(); + } + + data = SetupUtils.generateData(5); + + // ---------------------------------- + // write new data to the first object + // ---------------------------------- + + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + rt = client.write(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + FILE_ID, 0, 0, 0, 0, objdata, data.createViewBuffer()); + resp = rt.get(); + rt.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(5, resp.getSizeInBytes()); + + // ---------------------------------------------- + // extend the file to a length of one full object + // ---------------------------------------------- + newCap = fcred.getXcap().toBuilder().setTruncateEpoch(6).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + rt = client.truncate(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + fcred, FILE_ID, SIZE); + resp = rt.get(); + rt.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(SIZE, resp.getSizeInBytes()); + + // try to read the object + RPCResponse r2 = client.read(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, 0, 0, 0, SIZE); + ObjectData result = r2.get(); + + // the object must contain data plus padding zeros + + final byte[] dataWithZeros = new byte[SIZE]; + System.arraycopy(data.array(), 0, dataWithZeros, 0, data.limit()); + + checkResponse(dataWithZeros, result, r2.getData()); + r2.freeBuffers(); + + // --------------------------------------------- + // shrink the file to a length of half an object + // --------------------------------------------- + newCap = fcred.getXcap().toBuilder().setTruncateEpoch(7).build(); + fcred = fcred.toBuilder().setXcap(newCap).build(); + + rt = client.truncate(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + fcred, FILE_ID, SIZE / 2); + resp = rt.get(); + rt.freeBuffers(); + assertTrue(resp.hasSizeInBytes()); + assertEquals(SIZE / 2, resp.getSizeInBytes()); + + // try to read the object + r2 = client.read(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + FILE_ID, 0, 0, 0, SIZE); + result = r2.get(); + + // the object must contain data plus padding zeros + + final byte[] dataWithHalfZeros = new byte[SIZE / 2]; + System.arraycopy(data.array(), 0, dataWithHalfZeros, 0, data.limit()); + + checkResponse(dataWithHalfZeros, result, r2.getData()); + r2.freeBuffers(); + } + + @Test + public void testInterleavedWriteAndTruncate() throws Exception { + + final int numIterations = 20; + final int maxObject = 20; + final int maxSize = maxObject * SIZE; + final int numWrittenObjs = 5; + + final MRCDummy mrcDummy = new MRCDummy(capSecret); + + FileCredentials fcred = FileCredentials.newBuilder().setXcap(getCap(FILE_ID).getXCap()).setXlocs(xloc).build(); + + final List responses = new LinkedList(); + + for (int l = 0; l < numIterations; l++) { + + Capability cap = mrcDummy.open('w'); + + // randomly write 'numWrittenObjs' objects + for (int i = 0; i < numWrittenObjs; i++) { + + final int objId = (int) (Math.random() * maxObject); + final int osdIndex = objId % osdIDs.size(); + + // write an object with a random amount of bytes + final int size = (int) ((SIZE - 1) * Math.random()) + 1; + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0) + .setInvalidChecksumOnOsd(false).build(); + RPCResponse r = client.write(osdIDs.get(osdIndex).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fcred, FILE_ID, objId, 0, 0, 0, + objdata, SetupUtils.generateData(size)); + responses.add(r); + + // update the file size when the response is received + r.registerListener(mrcDummy); + } + + // wait until all write requests have been completed, i.e. all file + // size updates have been performed + for (RPCResponse r : responses) { + r.waitForResult(); + r.freeBuffers(); + } + responses.clear(); + + fcred = fcred.toBuilder().setXcap(mrcDummy.open('t').getXCap()).build(); + + // truncate the file + long newSize = (long) (Math.random() * maxSize); + RPCResponse rt = client.truncate(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, newSize); + rt.registerListener(mrcDummy); + rt.waitForResult(); + rt.freeBuffers(); + + long fileSize = mrcDummy.getFileSize(); + + // read the previously truncated objects, check size + for (int i = 0; i < maxObject; i++) { + RPCResponse r2 = client.read(osdIDs.get(i % osdIDs.size()).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fcred, FILE_ID, i, 0, 0, SIZE); + ObjectData result = r2.get(); + ReusableBuffer dataOut = r2.getData(); + int dataOutLen = (dataOut == null) ? 0 : dataOut.capacity(); + + // check inner objects - should be full + if (i < fileSize / SIZE) + assertEquals(SIZE, result.getZeroPadding() + dataOutLen); + + // check last object - should either be an EOF (null) or partial + // object + else if (i == fileSize / SIZE) { + if (fileSize % SIZE == 0) + assertEquals(0, result.getZeroPadding() + dataOutLen); + else + assertEquals(fileSize % SIZE, result.getZeroPadding() + dataOutLen); + } + + // check outer objects - should be EOF (null) + else + assertEquals(0, result.getZeroPadding() + dataOutLen); + + r2.freeBuffers(); + } + + } + + } + + /** + * tests the deletion of striped files + */ + // public void testDELETE() throws Exception { + // + // final int numObjs = 5; + // + // final FileCredentials fcred = new FileCredentials(xloc, + // getCap(FILE_ID).getXCap()); + // + // ReusableBuffer data = SetupUtils.generateData(SIZE); + // + // // create all objects + // for (int i = 0, osdIndex = 0; i < numObjs; i++, osdIndex = i % + // osdIDs.size()) { + // + // ObjectData objdata = new ObjectData(data.createViewBuffer(), 0, 0, + // false); + // RPCResponse r = + // client.write(osdIDs.get(osdIndex).getAddress(), + // FILE_ID, fcred, i, 0, 0, 0, objdata); + // r.get(); + // } + // + // // delete the file + // RPCResponse dr = client.unlink(osdIDs.get(0).getAddress(), FILE_ID, + // fcred); + // dr.get(); + // dr.freeBuffers(); + // } + + /** + * Checks whether the data array received with the response is equal to the given one. + * + * @param data + * the data array + * @param response + * the response + * @throws Exception + */ + public void checkResponse(byte[] data, ObjectData response, ReusableBuffer objData) throws Exception { + + if (data == null) { + if (objData != null) + /* + * System.out.println("body (" + response.getBody().capacity() + "): " + new + * String(response.getBody().array())); + */ + assertEquals(0, objData.remaining()); + } + + else { + byte[] responseData = objData.array(); + assertEquals(data.length, responseData.length); + for (int i = 0; i < data.length; i++) + assertEquals(data[i], responseData[i]); + } + } + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/StripingTestCOW.java b/java/servers/test/org/xtreemfs/test/osd/StripingTestCOW.java new file mode 100644 index 0000000..470ed30 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/StripingTestCOW.java @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2010-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.StripingPolicyImpl; +import org.xtreemfs.dir.DIRConfig; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; +import org.xtreemfs.test.osd.StripingTest.MRCDummy; + +public class StripingTestCOW { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static final boolean COW = true; + + private TestEnvironment testEnv; + + /*static class MRCDummy implements RPCResponseAvailableListener { + + private long issuedEpoch; + + private long epoch; + + private long fileSize; + + private String capSecret; + + public MRCDummy(String capSecret) { + this.capSecret = capSecret; + } + + Capability open(char mode) { + if (mode == 't') + issuedEpoch++; + + return new Capability(FILE_ID, 0, 60, System.currentTimeMillis(), "", (int) issuedEpoch, false, + COW ? SnapConfig.SNAP_CONFIG_ACCESS_CURRENT : SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, + capSecret); + } + + synchronized long getFileSize() { + return fileSize; + } + + @Override + public void responseAvailable(RPCResponse r) { + try { + + OSDWriteResponse resp = r.get(); + System.out.println("fs-update: " + resp); + + if (resp.getSizeInBytesCount() > 0) { + + final long newFileSize = resp.getNew_file_size().get(0).getSize_in_bytes(); + final long epochNo = resp.getNew_file_size().get(0).getTruncate_epoch(); + + if (epochNo < epoch) + return; + + if (epochNo > epoch || newFileSize > fileSize) { + epoch = epochNo; + fileSize = newFileSize; + } + } + + } catch (Exception exc) { + exc.printStackTrace(); + System.exit(1); + } + } + + }*/ + + private static final String FILE_ID = "1:1"; + + private static final int KB = 1; + + private static final int SIZE = KB * 1024; + + private static final byte[] ZEROS_HALF = new byte[SIZE / 2]; + + private static final byte[] ZEROS = new byte[SIZE]; + + private static DIRConfig dirConfig; + + private static OSDConfig osdCfg1; + + private static OSDConfig osdCfg2; + + private static OSDConfig osdCfg3; + + private static String capSecret; + + private List osdServer; + + private List osdIDs; + + private OSDServiceClient client; + + private StripingPolicyImpl sp; + + private XLocSet xloc; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + osdCfg1 = SetupUtils.createOSD1Config(); + osdCfg2 = SetupUtils.createOSD2Config(); + osdCfg3 = SetupUtils.createOSD3Config(); + + capSecret = osdCfg1.getCapabilitySecret(); + dirConfig = SetupUtils.createDIRConfig(); + } + + @Before + public void setUp() throws Exception { + // startup: DIR + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.OSD_CLIENT }); + testEnv.start(); + + osdIDs = new ArrayList(3); + osdIDs.add(SetupUtils.getOSD1UUID()); + osdIDs.add(SetupUtils.getOSD2UUID()); + osdIDs.add(SetupUtils.getOSD3UUID()); + + osdServer = new ArrayList(3); + osdServer.add(new OSD(osdCfg1)); + osdServer.add(new OSD(osdCfg2)); + osdServer.add(new OSD(osdCfg3)); + + client = testEnv.getOSDClient(); + + List osdset = new ArrayList(3); + osdset.add(SetupUtils.getOSD1UUID().toString()); + osdset.add(SetupUtils.getOSD2UUID().toString()); + osdset.add(SetupUtils.getOSD3UUID().toString()); + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(3, KB)).setReplicationFlags(0).addAllOsdUuids(osdset).build(); + xloc = XLocSet.newBuilder().setReadOnlyFileSize(0).setVersion(1).addReplicas(r).setReplicaUpdatePolicy("").build(); + + } + + private Capability getCap(String fname) { + return new Capability(fname, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber(), 60, System.currentTimeMillis(), "", 0, false, + COW ? SnapConfig.SNAP_CONFIG_ACCESS_CURRENT : SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, capSecret); + } + + @After + public void tearDown() throws Exception { + + osdServer.get(0).shutdown(); + osdServer.get(1).shutdown(); + osdServer.get(2).shutdown(); + + testEnv.shutdown(); + } + + /* TODO: test delete/truncate epochs! */ + + @Test + public void testInterleavedWriteAndTruncate() throws Exception { + + final int numIterations = 20; + final int maxObject = 20; + final int maxSize = maxObject * SIZE; + final int numWrittenObjs = 5; + + final MRCDummy mrcDummy = new MRCDummy(capSecret); + + for (int k = 0; k < 3; k++) { + + FileCredentials fcred = FileCredentials.newBuilder().setXcap(getCap(FILE_ID).getXCap()).setXlocs(xloc).build(); + + final List responses = new LinkedList(); + + for (int l = 0; l < numIterations; l++) { + + // randomly write 'numWrittenObjs' objects + for (int i = 0; i < numWrittenObjs; i++) { + + final int objId = (int) (Math.random() * maxObject); + final int osdIndex = objId % osdIDs.size(); + + // write an object with a random amount of bytes + final int size = (int) ((SIZE - 1) * Math.random()) + 1; + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false).build(); + RPCResponse r = client.write(osdIDs.get(osdIndex).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + fcred, FILE_ID, objId, 0, 0, 0, objdata, SetupUtils.generateData(size)); + responses.add(r); + + // update the file size when the response is received + r.registerListener(mrcDummy); + } + + // wait until all write requests have been completed, i.e. all + // file + // size updates have been performed + for (RPCResponse r : responses) { + r.waitForResult(); + r.freeBuffers(); + } + responses.clear(); + + fcred = fcred.toBuilder().setXcap(mrcDummy.open('t').getXCap()).build(); + + // truncate the file + long newSize = (long) (Math.random() * maxSize); + RPCResponse rt = client.truncate(osdIDs.get(0).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + fcred, FILE_ID, newSize); + rt.registerListener(mrcDummy); + rt.waitForResult(); + rt.freeBuffers(); + + long fileSize = mrcDummy.getFileSize(); + + // read the previously truncated objects, check size + for (int i = 0; i < maxObject; i++) { + RPCResponse r2 = client.read(osdIDs.get(i % osdIDs.size()).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, + fcred, FILE_ID, i, 0, 0, SIZE); + ObjectData result = r2.get(); + ReusableBuffer dataOut = r2.getData(); + int dataOutLen = (dataOut == null) ? 0 : dataOut.capacity(); + + + // check inner objects - should be full + if (i < fileSize / SIZE) + assertEquals(SIZE,result.getZeroPadding()+dataOutLen); + + // check last object - should either be an EOF (null) or partial + // object + else if (i == fileSize / SIZE) { + if (fileSize % SIZE == 0) + assertEquals(0,result.getZeroPadding()+dataOutLen); + else + assertEquals(fileSize % SIZE,result.getZeroPadding()+dataOutLen); + } + + // check outer objects - should be EOF (null) + else + assertEquals(0,result.getZeroPadding()+dataOutLen); + + + r2.freeBuffers(); + } + + } + + if (k != 2) { + System.out.println("\n########## waiting 61s ##########\n"); + Thread.sleep(61000); + } + + } + + } + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/VersionManagementTest.java b/java/servers/test/org/xtreemfs/test/osd/VersionManagementTest.java new file mode 100644 index 0000000..2c1088a --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/VersionManagementTest.java @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2008-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +public class VersionManagementTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment testEnv; + + private static final String FILE_ID = "1:1"; + + private static final int KB = 1; + + private static final int OBJ_SIZE = KB * 1024; + + private static OSDConfig osdCfg; + + private static String capSecret; + + private OSD osdServer; + + private ServiceUUID osdId; + + private OSDServiceClient client; + + private XLocSet xloc; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + osdCfg = SetupUtils.createOSD1Config(); + capSecret = osdCfg.getCapabilitySecret(); + } + + @Before + public void setUp() throws Exception { + + // startup: DIR + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.OSD_CLIENT }); + testEnv.start(); + + osdId = SetupUtils.getOSD1UUID(); + + osdServer = new OSD(osdCfg); + client = testEnv.getOSDClient(); + + List osdset = new ArrayList(1); + osdset.add(SetupUtils.getOSD1UUID().toString()); + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, KB)).setReplicationFlags(0) + .addAllOsdUuids(osdset).build(); + xloc = XLocSet.newBuilder().setReadOnlyFileSize(0).setVersion(1).addReplicas(r).setReplicaUpdatePolicy("") + .build(); + + } + + private FileCredentials getFileCredentials(int truncateEpoch, boolean write) { + return FileCredentials + .newBuilder() + .setXcap( + new Capability( + FILE_ID, + write ? (SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR + .getNumber()) : SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber(), 60, + System.currentTimeMillis(), "", truncateEpoch, false, + SnapConfig.SNAP_CONFIG_ACCESS_CURRENT, 0, capSecret).getXCap()).setXlocs(xloc).build(); + } + + private FileCredentials getFileCredentials(int truncateEpoch, long snapTimestamp) { + return FileCredentials + .newBuilder() + .setXcap( + new Capability(FILE_ID, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber(), 60, System + .currentTimeMillis(), "", truncateEpoch, false, SnapConfig.SNAP_CONFIG_ACCESS_SNAP, + snapTimestamp, capSecret).getXCap()).setXlocs(xloc).build(); + } + + @After + public void tearDown() throws Exception { + osdServer.shutdown(); + testEnv.shutdown(); + + } + + @Test + public void testTruncate() throws Exception { + + FileCredentials fcred = getFileCredentials(1, true); + + // write a new file + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = client.write(osdId.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, 5, 0, 0, 0, objdata, + SetupUtils.generateData(OBJ_SIZE, (byte) 'x')); + r.get(); + r.freeBuffers(); + + // truncate-extend the file and read it + RPCResponse r1 = client.truncate(osdId.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, OBJ_SIZE * 8); + r1.get(); + r1.freeBuffers(); + + RPCResponse r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fcred, FILE_ID, 5, 0, 0, OBJ_SIZE); + ObjectData result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 'x', r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, FILE_ID, + 7, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 0, r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, FILE_ID, + 0, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 0, r2.getData()); + r2.freeBuffers(); + + // truncate-shrink the file and read it + fcred = getFileCredentials(2, true); + + r1 = client.truncate(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, + FILE_ID, OBJ_SIZE * 1); + r1.get(); + r1.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, FILE_ID, + 0, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 0, r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fcred, FILE_ID, + 5, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, 0, (byte) 0, r2.getData()); + r2.freeBuffers(); + + } + + @Test + public void testImplicitVersionCreation() throws Exception { + + final long timeoutSpan = 61000; + + final long t0 = System.currentTimeMillis(); + + FileCredentials wCred = getFileCredentials(1, true); + FileCredentials rCred = getFileCredentials(1, false); + + // write a new file that consists of two objects + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = client.write(osdId.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, wCred, FILE_ID, 0, 0, 0, 0, objdata, + SetupUtils.generateData(OBJ_SIZE, (byte) 'x')); + r.get(); + r.freeBuffers(); + + r = client.write(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, wCred, FILE_ID, + 1, 0, 0, 0, objdata, SetupUtils.generateData(OBJ_SIZE, (byte) 'y')); + r.get(); + r.freeBuffers(); + + // wait for OSD-internal file close, which will implicitly cause a new + // version to be created + // System.out.println("\n########## waiting " + timeoutSpan / 1000 + "s ##########\n"); + Thread.sleep(timeoutSpan); + + // overwrite the first object + r = client.write(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, wCred, FILE_ID, + 0, 0, 0, 0, objdata, SetupUtils.generateData(OBJ_SIZE, (byte) 'z')); + r.get(); + r.freeBuffers(); + + final long t1 = System.currentTimeMillis(); + + // read and check the old version + FileCredentials rCredV = getFileCredentials(0, t1); + + RPCResponse r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, rCredV, FILE_ID, 0, 0, 0, OBJ_SIZE); + ObjectData result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 'x', r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCredV, + FILE_ID, 1, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 'y', r2.getData()); + r2.freeBuffers(); + + // read and check the current version + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCred, FILE_ID, + 0, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 'z', r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCred, FILE_ID, + 1, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 'y', r2.getData()); + r2.freeBuffers(); + + // try to read a non-existing version + rCredV = getFileCredentials(0, t0 - 999999); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCredV, + FILE_ID, 0, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, 0, (byte) 0, r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCredV, + FILE_ID, 1, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, 0, (byte) 0, r2.getData()); + r2.freeBuffers(); + + // truncate the file to zero length and wait, so that a new version is + // created and append another object + FileCredentials tCred = getFileCredentials(1, true); + r = client.truncate(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, tCred, + FILE_ID, 0); + r.get(); + r.freeBuffers(); + + // System.out.println("\n########## waiting " + timeoutSpan / 1000 + "s ##########\n"); + Thread.sleep(timeoutSpan); + + r = client.write(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, wCred, FILE_ID, + 2, 0, 0, 0, objdata, SetupUtils.generateData(OBJ_SIZE, (byte) 'w')); + r.get(); + r.freeBuffers(); + + final long t2 = System.currentTimeMillis(); + + // read and check the current version + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCred, FILE_ID, + 0, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 0, r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCred, FILE_ID, + 1, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 0, r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCred, FILE_ID, + 2, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 'w', r2.getData()); + r2.freeBuffers(); + + // read and check the version at t1 + rCredV = getFileCredentials(0, t1); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCredV, + FILE_ID, 0, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 'x', r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCredV, + FILE_ID, 1, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, OBJ_SIZE, (byte) 'y', r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCredV, + FILE_ID, 2, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, 0, (byte) 0, r2.getData()); + r2.freeBuffers(); + + // read and check the version at t2 + rCredV = getFileCredentials(0, t2); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCredV, + FILE_ID, 0, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, 0, (byte) 0, r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCredV, + FILE_ID, 1, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, 0, (byte) 0, r2.getData()); + r2.freeBuffers(); + + r2 = client.read(osdId.getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, rCredV, + FILE_ID, 2, 0, 0, OBJ_SIZE); + result = r2.get(); + checkData(result, 0, (byte) 0, r2.getData()); + r2.freeBuffers(); + + } + + private void checkData(ObjectData data, long size, byte content, ReusableBuffer dataOut) throws Exception { + + int dataOutLen = (dataOut == null) ? 0 : dataOut.capacity(); + assertEquals(size, dataOutLen + data.getZeroPadding()); + if (dataOut != null) { + for (byte b : dataOut.array()) + assertEquals(content, b); + } + + } + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/VersionTableTest.java b/java/servers/test/org/xtreemfs/test/osd/VersionTableTest.java new file mode 100644 index 0000000..c07e562 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/VersionTableTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2010-2011 by Jan Stender, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.osd.storage.VersionTable; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author stender + */ +public class VersionTableTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + public static final File VT_FILE = new File("/tmp/vttest"); + + @Before + public void setUp() throws Exception { + VT_FILE.delete(); + } + + @After + public void tearDown() throws Exception { + VT_FILE.delete(); + } + + @Test + public void testInsertLookup() throws Exception { + + Map map = new HashMap(); + map.put(10000L, new int[] { 2, 4, 5, 1, 2 }); + map.put(10005L, new int[] { 3, 4, 5, 2, 3 }); + map.put(10020L, new int[] { 5, 4, 6, 3, 3, 1 }); + map.put(11000L, new int[] { 5, 5, 8, 3, 3, 1, 1, 1 }); + map.put(12000L, new int[] { 5, 5 }); + map.put(32000L, new int[] {}); + + VersionTable vt = new VersionTable(VT_FILE); + for (Entry entry : map.entrySet()) + vt.addVersion(entry.getKey(), entry.getValue(), entry.getValue().length * 1024); + + for (int i = 0; i < 10; i++) { + assertEquals(i < 5 ? map.get(10000L)[i] : 0, vt.getLatestVersionBefore(10001).getObjVersion(i)); + assertEquals(i < 5 ? map.get(10000L)[i] : 0, vt.getLatestVersionBefore(10005).getObjVersion(i)); + assertEquals(i < 5 ? map.get(10005L)[i] : 0, vt.getLatestVersionBefore(10012).getObjVersion(i)); + assertEquals(i < 5 ? map.get(10005L)[i] : 0, vt.getLatestVersionBefore(10014).getObjVersion(i)); + assertEquals(i < 6 ? map.get(10020L)[i] : 0, vt.getLatestVersionBefore(10200).getObjVersion(i)); + assertEquals(i < 6 ? map.get(10020L)[i] : 0, vt.getLatestVersionBefore(10800).getObjVersion(i)); + assertEquals(i < 8 ? map.get(11000L)[i] : 0, vt.getLatestVersionBefore(11001).getObjVersion(i)); + assertEquals(i < 8 ? map.get(11000L)[i] : 0, vt.getLatestVersionBefore(12000).getObjVersion(i)); + assertEquals(i < 2 ? map.get(12000L)[i] : 0, vt.getLatestVersionBefore(12010).getObjVersion(i)); + assertEquals(i < 2 ? map.get(12000L)[i] : 0, vt.getLatestVersionBefore(22000).getObjVersion(i)); + assertEquals(0, vt.getLatestVersionBefore(33000).getObjVersion(i)); + assertEquals(0, vt.getLatestVersionBefore(Long.MAX_VALUE).getObjVersion(i)); + } + + } + + @Test + public void testLoadSave() throws Exception { + + Map map = new HashMap(); + map.put(10000L, new int[] { 2, 4, 5, 1, 2 }); + map.put(10005L, new int[] { 3, 4, 5, 2, 3 }); + map.put(10020L, new int[] { 5, 4, 6, 3, 3, 1 }); + map.put(11000L, new int[] { 5, 5, 8, 3, 3, 1, 1, 1 }); + map.put(12000L, new int[] { 5, 5 }); + map.put(32000L, new int[] {}); + + VersionTable vt = new VersionTable(VT_FILE); + for (Entry entry : map.entrySet()) + vt.addVersion(entry.getKey(), entry.getValue(), entry.getValue().length * 1024); + + vt.save(); + vt.load(); + + for (int i = 0; i < 10; i++) { + assertEquals(i < 5 ? map.get(10000L)[i] : 0, vt.getLatestVersionBefore(10001).getObjVersion(i)); + assertEquals(i < 5 ? map.get(10000L)[i] : 0, vt.getLatestVersionBefore(10005).getObjVersion(i)); + assertEquals(i < 5 ? map.get(10005L)[i] : 0, vt.getLatestVersionBefore(10012).getObjVersion(i)); + assertEquals(i < 5 ? map.get(10005L)[i] : 0, vt.getLatestVersionBefore(10014).getObjVersion(i)); + assertEquals(i < 6 ? map.get(10020L)[i] : 0, vt.getLatestVersionBefore(10200).getObjVersion(i)); + assertEquals(i < 6 ? map.get(10020L)[i] : 0, vt.getLatestVersionBefore(10800).getObjVersion(i)); + assertEquals(i < 8 ? map.get(11000L)[i] : 0, vt.getLatestVersionBefore(11001).getObjVersion(i)); + assertEquals(i < 8 ? map.get(11000L)[i] : 0, vt.getLatestVersionBefore(12000).getObjVersion(i)); + assertEquals(i < 2 ? map.get(12000L)[i] : 0, vt.getLatestVersionBefore(12010).getObjVersion(i)); + assertEquals(i < 2 ? map.get(12000L)[i] : 0, vt.getLatestVersionBefore(22000).getObjVersion(i)); + assertEquals(0, vt.getLatestVersionBefore(33000).getObjVersion(i)); + assertEquals(0, vt.getLatestVersionBefore(Long.MAX_VALUE).getObjVersion(i)); + } + + } + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/replication/ObjectSetTest.java b/java/servers/test/org/xtreemfs/test/osd/replication/ObjectSetTest.java new file mode 100755 index 0000000..73a5224 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/replication/ObjectSetTest.java @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2009-2011 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd.replication; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.test.TestHelper; + +/** + * + *
    + * 02.07.2009 + */ +public class ObjectSetTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + List changeableSets; + List fixedSets; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + changeableSets = new ArrayList(); + fixedSets = new ArrayList(); + // set 1 + changeableSets.add(new ObjectSet(1, 0, 100)); + changeableSets.add(new ObjectSet(1, 0, 100)); + // set 2 + fixedSets.add(new ObjectSet(1, 0, 100)); + fixedSets.add(new ObjectSet(1, 0, 100)); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + } + + @Test + public void testSerialization() throws Exception { + // test if equals after serialization + for (ObjectSet set : changeableSets) { + fillObjectSetRandom(set, 100, 100); + byte[] serialized = set.getSerializedBitSet(); + + ObjectSet deserialized = new ObjectSet(set.getStripeWidth(), 0, serialized); + assertTrue(set.equals(deserialized)); + + // test wrong deserialize + ArrayList list = new ArrayList(); + byte[] otherObject = serialize(list); + try { + deserialized = new ObjectSet(set.getStripeWidth(), 0, otherObject); + } catch (Exception e) { + // correct + } + } + } + + @Test + public void testStripeWidth() throws Exception { + long[] stripeWidth1 = { 1, 2, 4, 5, 6, 7, 8, 10 }; + long[] stripeWidth2 = { 4, 6, 8, 10, 14, 20, 22, 24 }; + long[] stripeWidth3_1 = { 1, 4, 7, 10, 13, 16, 22, 31 }; + long[] stripeWidth3_2 = { 0, 3, 6, 12, 21, 24, 33, 36 }; + + ObjectSet setWidth1 = new ObjectSet(1, 0, 100); + ObjectSet setWidth2 = new ObjectSet(2, 0, 100); + ObjectSet setWidth3_1 = new ObjectSet(3, 1, 100); + ObjectSet setWidth3_2 = new ObjectSet(3, 0, 100); + + // fill sets + for (long object : stripeWidth1) + setWidth1.add(object); + for (long object : stripeWidth2) + setWidth2.add(object); + for (long object : stripeWidth3_1) + setWidth3_1.add(object); + for (long object : stripeWidth3_2) + setWidth3_2.add(object); + + // check if the sets only contain the correct values + // set 1 + assertEquals(stripeWidth1.length, setWidth1.size()); + Iterator it = setWidth1.iterator(); + for (long object : stripeWidth1) + if (it.hasNext()) + assertEquals(object, it.next().longValue()); + + // set 2 + assertEquals(stripeWidth2.length, setWidth2.size()); + it = setWidth2.iterator(); + for (long object : stripeWidth2) + if (it.hasNext()) + assertEquals(object, it.next().longValue()); + + // set 3 + assertEquals(stripeWidth3_1.length, setWidth3_1.size()); + it = setWidth3_1.iterator(); + for (long object : stripeWidth3_1) + if (it.hasNext()) + assertEquals(object, it.next().longValue()); + + // set 4 + assertEquals(stripeWidth3_2.length, setWidth3_2.size()); + it = setWidth3_2.iterator(); + for (long object : stripeWidth3_2) + if (it.hasNext()) + assertEquals(object, it.next().longValue()); + + // test false firstObjectNo + ObjectSet setWidth3_false = new ObjectSet(3, 0, 100); + for (long object : stripeWidth3_1) + setWidth3_false.add(object); + assertEquals(stripeWidth3_1.length, setWidth3_false.size()); + it = setWidth3_false.iterator(); + for (long object : stripeWidth3_1) + if (it.hasNext()) + assertNotSame(object, it.next().longValue()); + } + + /** + * Serializes this object. + * + * @param set + * @return + * @throws IOException + */ + protected static byte[] serialize(Object set) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(set); + oos.flush(); + oos.close(); + bos.close(); + return bos.toByteArray(); + } + + @Test + public void testEquals() throws Exception { + for (ObjectSet set : changeableSets) + fillObjectSetRandom(set, 100, 100); + for (ObjectSet set : fixedSets) + fillObjectSetRandom(set, 100, 100); + + for (ObjectSet set : changeableSets) { + for (ObjectSet set2 : fixedSets) { + assertTrue(set.equals(set2)); + } + } + ObjectSet falseSet = new ObjectSet(2, 0, 10); + fillObjectSetRandom(falseSet, 20, 20); + assertFalse(falseSet.equals(changeableSets.get(0))); + } + + @Test + public void testIntersection() throws Exception { + long[] objectsInList1 = { 10, 20, 40, 50, 60, 70, 80, 100 }; + long[] objectsInList2 = { 0, 30, 50, 70, 90, 100 }; + long[] intersection = { 50, 70, 100 }; + + // fill set2 + for (ObjectSet set : fixedSets) + for (long object : objectsInList2) + set.add(object); + + // intersection + for (ObjectSet set2 : fixedSets) { + for (ObjectSet set : changeableSets) { + // renew set1 + set.clear(); + for (long object : objectsInList1) + set.add(object); + + set.intersection(set2); + assertEquals(intersection.length, set.size()); + for (long object : intersection) + assertTrue(set.contains(object)); + } + } + } + + @Test + public void testUnion() throws Exception { + long[] objectsInList1 = { 10, 20, 40, 50, 60, 70, 80, 100 }; + long[] objectsInList2 = { 0, 30, 50, 70, 90, 100 }; + long[] union = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; + + // fill set2 + for (ObjectSet set : fixedSets) + for (long object : objectsInList2) + set.add(object); + + // intersection + for (ObjectSet set2 : fixedSets) { + for (ObjectSet set : changeableSets) { + // renew set1 + set.clear(); + for (long object : objectsInList1) + set.add(object); + + set.union(set2); + assertEquals(union.length, set.size()); + for (long object : union) + assertTrue(set.contains(object)); + } + } + } + + /** + * @param fillRate + * in percent + * @throws Exception + */ + public static void fillObjectSetRandom(ObjectSet set, long objectsCount, int fillRate) { + Random random = new Random(); + // System.out.println("fill object set ..."); + for (long i = 0; i < objectsCount; i++) { + if (random.nextInt(100) < fillRate) // approx. x% filled + set.add(i); + } + } +} diff --git a/java/servers/test/org/xtreemfs/test/osd/replication/ReadWriteReplicationTest.java b/java/servers/test/org/xtreemfs/test/osd/replication/ReadWriteReplicationTest.java new file mode 100644 index 0000000..5f12028 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/replication/ReadWriteReplicationTest.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2014 by Robert Schmidtke, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.test.osd.replication; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.AdminFileHandle; +import org.xtreemfs.common.libxtreemfs.AdminVolume; +import org.xtreemfs.common.libxtreemfs.ClientFactory; +import org.xtreemfs.common.libxtreemfs.FileHandle; +import org.xtreemfs.common.libxtreemfs.Options; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.KeyValuePair; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicyType; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author Robert Schmidtke + * + */ +public class ReadWriteReplicationTest { + + @Rule + public final TestRule testLog = TestHelper.testLog; + + private TestEnvironment testEnv; + + private UserCredentials userCredentials; + + private String dirAddress, mrcAddress; + + private Options options; + + private AdminClient client; + + private Auth auth; + + @Before + public void setup() throws Exception { + FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); + Logging.start(Logging.LEVEL_NOTICE); + + SetupUtils.CHECKSUMS_ON = true; + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, + TestEnvironment.Services.RPC_CLIENT, TestEnvironment.Services.MRC, TestEnvironment.Services.MRC_CLIENT, + TestEnvironment.Services.OSD, TestEnvironment.Services.OSD, TestEnvironment.Services.OSD }); + testEnv.start(); + SetupUtils.CHECKSUMS_ON = false; + + userCredentials = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + + auth = RPCAuthentication.authNone; + + dirAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); + mrcAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); + + options = new Options(); + + client = ClientFactory.createAdminClient(dirAddress, userCredentials, null, options); + client.start(); + } + + @After + public void cleanup() { + testEnv.shutdown(); + client.shutdown(); + } + + @Test + public void testAlignedReplicatedWrite() throws Exception { + testReplicatedWrite(128, 128); + } + + @Test + public void testUnalignedReplicatedWrite() throws Exception { + testReplicatedWrite(128, 32); + } + + @Test + public void testUnalignedReplicatedWrite2() throws Exception { + testReplicatedWrite(128, 160); + } + + private void testReplicatedWrite(int stripeSize, int fileSize) throws Exception { + final String volumeName = "testReplicatedWrite"; + final String path = "/replicatedWriteTest.txt"; + + client.createVolume(mrcAddress, auth, userCredentials, volumeName, 0777, "test", "test", + AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, StripingPolicyType.STRIPING_POLICY_RAID0, + stripeSize, 1, new ArrayList()); + + AdminVolume volume = client.openVolume(volumeName, null, options); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ, 3, + ReplicationFlags.setSequentialStrategy(0)); + + AdminFileHandle fileHandle = volume.openFile(userCredentials, path, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT_VALUE | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC_VALUE + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR_VALUE, 0777); + + Random random = new Random(0); + byte[] data = new byte[fileSize * 1024]; + random.nextBytes(data); + + fileHandle.write(userCredentials, data, 0, data.length, 0); + fileHandle.close(); + + fileHandle = volume.openFile(userCredentials, path, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY_VALUE, 0777); + + List replicas = fileHandle.getReplicasList(); + + // OSDs 0+1 live + readMajority(replicas, fileHandle, this, data, null, new int[] { 2 }); + + // OSDs 1+2 live + readMajority(replicas, fileHandle, this, data, new int[] { 2 }, new int[] { 0 }); + + // OSDs 2+0 live + readMajority(replicas, fileHandle, this, data, new int[] { 0 }, new int[] { 1 }); + + // OSDs 0+1 live, but this time with OSD 2 being the primary + readMajority(replicas, fileHandle, this, data, new int[] { 1 }, new int[] { 2 }); + + fileHandle.close(); + client.deleteVolume(auth, userCredentials, volumeName); + } + + private void readMajority(List replicas, FileHandle fileHandle, Object me, byte[] expected, + int[] startList, int[] stopList) throws Exception { + if (stopList != null) { + for (int i : stopList) { + Logging.logMessage(Logging.LEVEL_NOTICE, me, "Stopping OSD %d with UUID %s", i, replicas.get(i) + .getOsdUuids(0)); + testEnv.stopOSD(replicas.get(i).getOsdUuids(0)); + } + } + + if (startList != null) { + for (int i : startList) { + Logging.logMessage(Logging.LEVEL_NOTICE, me, "Starting OSD %d with UUID %s", i, replicas.get(i) + .getOsdUuids(0)); + testEnv.startOSD(replicas.get(i).getOsdUuids(0)); + } + } + + byte[] readData = new byte[expected.length]; + new Random().nextBytes(readData); + fileHandle.read(userCredentials, readData, 0, readData.length, 0); + Assert.assertArrayEquals("Expected read data to be the same as written data on OSD", expected, readData); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/replication/ReplicationRAFTest.java b/java/servers/test/org/xtreemfs/test/osd/replication/ReplicationRAFTest.java new file mode 100644 index 0000000..c609d71 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/replication/ReplicationRAFTest.java @@ -0,0 +1,699 @@ +///* Copyright (c) 2009 Barcelona Supercomputing Center - Centro Nacional +// de Supercomputacion and Konrad-Zuse-Zentrum fuer Informationstechnik Berlin. +// +// This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based +// Grid Operating System, see for more details. +// The XtreemOS project has been developed with the financial support of the +// European Commission's IST program under contract #FP6-033576. +// +// XtreemFS is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2 of the License, or (at your option) +// any later version. +// +// XtreemFS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with XtreemFS. If not, see . +// */ +///* +// * AUTHORS: Christian Lorenz (ZIB) +// */ +//package org.xtreemfs.test.osd.replication; +// +//import java.io.File; +//import java.io.IOException; +//import java.util.ArrayList; +//import java.util.Arrays; +//import java.util.Iterator; +//import java.util.List; +//import java.util.Random; +//import java.util.SortedSet; +//import java.util.TreeSet; +// +//import junit.framework.TestCase; +// +//import org.junit.After; +//import org.junit.Before; +//import org.junit.Test; +//import org.xtreemfs.common.clients.RandomAccessFile; +//import org.xtreemfs.common.uuids.ServiceUUID; +//import org.xtreemfs.common.xloc.Replica; +//import org.xtreemfs.common.xloc.ReplicationFlags; +//import org.xtreemfs.foundation.buffer.BufferPool; +//import org.xtreemfs.foundation.buffer.ReusableBuffer; +//import org.xtreemfs.foundation.logging.Logging; +//import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +//import org.xtreemfs.foundation.util.FSUtils; +//import org.xtreemfs.osd.replication.ObjectSet; +//import org.xtreemfs.test.SetupUtils; +//import org.xtreemfs.test.TestEnvironment; +// +///** +// * +// * 12.05.2009 +// */ +//public class ReplicationRAFTest extends TestCase { +// public static final int STRIPE_SIZE = 1024 * 10; // 10kb in byte +// +// public static final String VOLUME_NAME = "test"; +// +// // FIXME: +// public static int HOLE_PROBABILITY = -1; // 30% chance +// +// private ReusableBuffer data; +// +// /** +// * contains the position where the hole starts (the size of a hole is always +// * the stripe size in this test) +// */ +// private SortedSet holes; +// +// private TestEnvironment testEnv; +// +// private UserCredentials userCredentials; +// +// private static Random random = new Random(843); +// +// public ReplicationRAFTest() { +// // Auto-generated constructor stub +// Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); +//// Monitoring.enable(); +// } +// +// /** +// * @throws java.lang.Exception +// */ +// @Before +// public void setUp() throws Exception { +// System.out.println("TEST: " + getClass().getSimpleName() + "." + getName()); +// +// // cleanup +// File testDir = new File(SetupUtils.TEST_DIR); +// +// FSUtils.delTree(testDir); +// testDir.mkdirs(); +// +// // user credentials +// userCredentials = UserCredentials.newBuilder().setUsername("root").addGroups("root").build(); +// +// // startup: DIR, MRC, 8 OSDs, ... +// testEnv = new TestEnvironment(TestEnvironment.Services.DIR_SERVICE, TestEnvironment.Services.MRC, +// TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, +// TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.OSD_CLIENT, +// TestEnvironment.Services.OSD, TestEnvironment.Services.OSD, TestEnvironment.Services.OSD, +// TestEnvironment.Services.OSD, TestEnvironment.Services.OSD, TestEnvironment.Services.OSD, +// TestEnvironment.Services.OSD, TestEnvironment.Services.OSD); +// testEnv.start(); +// +// // wait a bit so the MRC could notice the OSDs +// Thread.sleep(1000); +// +//// data = ReusableBuffer.wrap("fadsljfalskjdflaskjdfölkjsalödfkjaslsfijal".getBytes()); +//// holes = new TreeSet(); +// generateData(1000 * 1000 * 3); // ca. 3 MB +// initializeVolume(2); +// } +// +// private void generateData(int appriximateSize) { +// data = BufferPool.allocate(appriximateSize); +// holes = new TreeSet(); +// byte[] zeros = new byte[(int) (STRIPE_SIZE * 1.5)]; +// Arrays.fill(zeros, (byte) 0); +// +// while (data.position() < appriximateSize - STRIPE_SIZE * 1.5) { +// if (random.nextInt(100) > HOLE_PROBABILITY) { +// // write A piece of data +// ReusableBuffer tmpData = SetupUtils.generateData((int) (STRIPE_SIZE * 1.5)); +// data.put(tmpData); +// BufferPool.free(tmpData); +// } else { // skip writing => hole +// // remember that this is a hole +// holes.add(data.position()); +// // ... but write zeros to data for checking data later +// data.put(zeros); +// } +// } +// data.flip(); +// } +// +// public void initializeVolume(int stripeWidth) throws ONCRPCException, IOException, InterruptedException { +// // create a volume (no access control) +// RPCResponse r = testEnv.getMrcClient().mkvol(testEnv.getMRCAddress(), userCredentials, VOLUME_NAME, +// new StripingPolicy(StripingPolicyType.STRIPING_POLICY_RAID0, STRIPE_SIZE / 1024, stripeWidth), +// AccessControlPolicyType.ACCESS_CONTROL_POLICY_NULL.intValue(), 0); +// r.get(); +// r.freeBuffers(); +// } +// +// /** +// * @throws java.lang.Exception +// */ +// @After +// public void tearDown() throws Exception { +// testEnv.shutdown(); +// +// // free buffers +// BufferPool.free(data); +// } +// +// @Test +// public void testSimpleWithDifferentStrategies() throws Exception { +// // partial replicas +// System.out.println("\n### random strategy on partial replica ###"); +// simpleTest("file0", ReplicationFlags.setPartialReplica(ReplicationFlags.setRandomStrategy(0))); +// System.out.println("\n### sequential strategy on partial replica ###"); +// simpleTest("file1", ReplicationFlags.setPartialReplica(ReplicationFlags.setSequentialStrategy(0))); +// System.out.println("\n### rarest first strategy on partial replica ###"); +// simpleTest("file2", ReplicationFlags.setPartialReplica(ReplicationFlags.setRarestFirstStrategy(0))); +// System.out.println("\n### sequential prefetching strategy on partial replica ###"); +// simpleTest("file3", ReplicationFlags.setPartialReplica(ReplicationFlags.setSequentialPrefetchingStrategy(0))); +// +// // full replicas +// System.out.println("\n### random strategy on full replica ###"); +// fullReplicasTest("file4", ReplicationFlags.setFullReplica(ReplicationFlags.setRandomStrategy(0))); +// System.out.println("\n### sequential strategy on full replica ###"); +// fullReplicasTest("file5", ReplicationFlags.setFullReplica(ReplicationFlags.setSequentialStrategy(0))); +// System.out.println("\n### rarest first strategy on full replica ###"); +// fullReplicasTest("file6", ReplicationFlags.setRarestFirstStrategy(ReplicationFlags.setFullReplica(0))); +// System.out.println("\n### sequential prefetching strategy on full replica ###"); +// fullReplicasTest("file7", ReplicationFlags.setFullReplica(ReplicationFlags.setSequentialPrefetchingStrategy(0))); +// } +// +// private void simpleTest(String filename, int replicationFlags) throws Exception { +// RandomAccessFile raf = new RandomAccessFile("rw", testEnv.getMRCAddress(), VOLUME_NAME + "/" + filename, +// testEnv.getRpcClient(), userCredentials); +// +// // test needs a stripe width of 2 OSDs +// assertEquals(2, raf.getStripingPolicy().getWidth()); +// +// writeData(raf); +// +// // set read-only +// raf.setReadOnly(true); +// assertEquals(data.limit(), raf.getXLoc().getXLocSet().getRead_only_file_size()); +// +// // set new deterministic selection of OSDs +// raf.setReplicaSelectionPolicy(raf.SEQUENTIAL_REPLICA_SELECTION_POLICY); +// +// // add replicas +// List replicas = raf.getSuitableOSDsForAReplica(); +// assertEquals(6, replicas.size()); +// raf.addReplica(replicas.subList(0, 2), raf.getStripingPolicy(), replicationFlags); +// raf.addReplica(replicas.subList(2, 4), raf.getStripingPolicy(), replicationFlags); +// raf.addReplica(replicas.subList(4, 6), raf.getStripingPolicy(), replicationFlags); +// +// // assert 4 replicas +// assertEquals(4, raf.getXLoc().getNumReplicas()); +// +// raf.changeReplicaOrder(); +// // read data +// for (int reads = 0; reads < 4; reads++) { +// // read and check data => replication +// byte[] resultBuffer = new byte[data.limit()]; +// raf.seek(0); +// raf.read(resultBuffer, 0, resultBuffer.length); +// +// // count zeros +// int zeros = 0; +// for (int i = 0; i < resultBuffer.length; i++) +// if (resultBuffer[i] == (byte) 0) +// zeros++; +// +// // FIXME: debug stuff +//// System.out.println("filesize: " + data.array().length + "\t zeros: " + zeros); +// +// assertTrue(Arrays.equals(data.array(), resultBuffer)); +// +// raf.changeReplicaOrder(); +// } +// // read EOF +// for (int reads = 0; reads < 4; reads++) { +// byte[] resultBuffer = new byte[STRIPE_SIZE]; +// raf.seek(data.limit()); +// raf.read(resultBuffer, 0, resultBuffer.length); +// byte[] expected = new byte[STRIPE_SIZE]; +// Arrays.fill(expected, (byte) 0); +// assertTrue(Arrays.equals(expected, resultBuffer)); +// +// // read EOF with data +// resultBuffer = new byte[STRIPE_SIZE * 3]; +// raf.seek(data.limit() - STRIPE_SIZE * 2); +// raf.read(resultBuffer, 0, resultBuffer.length); +// // check data +// expected = Arrays.copyOfRange(data.array(), data.limit() - STRIPE_SIZE * 2, data.limit()); +// assertTrue(Arrays.equals(expected, Arrays.copyOfRange(resultBuffer, 0, STRIPE_SIZE * 2))); +// // check zeros at the end +// expected = new byte[STRIPE_SIZE]; +// Arrays.fill(expected, (byte) 0); +// assertTrue(Arrays.equals(expected, Arrays.copyOfRange(resultBuffer, STRIPE_SIZE * 2, +// resultBuffer.length))); +// +// raf.changeReplicaOrder(); +// } +// +// raf.close(); +// } +// +// private void fullReplicasTest(String filename, int replicationFlags) throws Exception { +// generateData(1000 * 1000); // ca. 1 MB +// +// RandomAccessFile raf = new RandomAccessFile("rw", testEnv.getMRCAddress(), VOLUME_NAME + "/" + filename, +// testEnv.getRpcClient(), userCredentials); +// +// // test needs a stripe width of 2 OSDs +// assertEquals(2, raf.getStripingPolicy().getWidth()); +// +// writeData(raf); +// +// // set read-only +// raf.setReadOnly(true); +// assertEquals(data.limit(), raf.getXLoc().getXLocSet().getRead_only_file_size()); +// +// // add replicas +// List replicas = raf.getSuitableOSDsForAReplica(); +// assertEquals(6, replicas.size()); +// raf.addReplica(replicas.subList(0, 2), raf.getStripingPolicy(), replicationFlags); +// raf.addReplica(replicas.subList(2, 4), raf.getStripingPolicy(), replicationFlags); +// raf.addReplica(replicas.subList(4, 6), raf.getStripingPolicy(), replicationFlags); +// +// raf.setReplicaSelectionPolicy(raf.SEQUENTIAL_REPLICA_SELECTION_POLICY); +// +// // read a few bytes from every replica +// for (int i = 0; i < 8; i++) { +// // read data from replica => initiate background replication +// byte[] resultBuffer = new byte[STRIPE_SIZE +// * raf.getXLoc().getReplica(0).getStripingPolicy().getWidth()]; +// raf.seek(0); +// raf.read(resultBuffer, 0, resultBuffer.length); +// raf.changeReplicaOrder(); +// } +// +// OSDClient osdClient = testEnv.getOSDClient(); +// +// // wait, so the file could be fully replicated in background +// Thread.sleep(10000); +// +// // check, if objects are replicated +// List> replicaIts = new ArrayList>(); +// for (Replica replica : raf.getXLoc().getReplicas()) { +// replicaIts.add(replica.getOSDs().iterator()); +// } +// // parallel iteration through all OSDs of the replicas +// while (replicaIts.get(0).hasNext()) { +// List osds = new ArrayList(); +// // get the OSDs from all replicas responsible for the same objects +// for (Iterator it : replicaIts) { +// osds.add(it.next()); +// } +// // collect the object sets from these OSDs +// List objectSets = new ArrayList(); +// for (ServiceUUID osd : osds) { +// RPCResponse r = osdClient.internal_getObjectList(osd.getAddress(), raf +// .getFileId(), raf.getCredentials()); +// ObjectList objectList = r.get(); +// r.freeBuffers(); +// objectSets.add(new ObjectSet(objectList.getStripe_width(), objectList.getFirst_(), +// objectList.getSet().array())); +// } +// +// // check, if all objects lists contains the same objects +// ObjectSet set = objectSets.get(0); +// for (ObjectSet objectSet : objectSets) { +// assertEquals(set, objectSet); +// } +// } +// } +// +// @Test +// public void testReplicasWithDifferentStripingPolicies() throws Exception { +// RandomAccessFile raf = new RandomAccessFile("rw", testEnv.getMRCAddress(), VOLUME_NAME + "/testfile", +// testEnv.getRpcClient(), userCredentials); +// raf.setReplicaSelectionPolicy(raf.SEQUENTIAL_REPLICA_SELECTION_POLICY); +// +// // check if original replica hast a stripe width of 2 +// assertEquals(2, raf.getStripingPolicy().getWidth()); +// writeData(raf); +// +// // set read-only +// raf.setReadOnly(true); +// +// // add replica +// List replicas = raf.getSuitableOSDsForAReplica(); +// assertEquals(6, replicas.size()); +// +// // add replica with stripe width of 1 +// StripingPolicy sp = new StripingPolicy(StripingPolicyType.STRIPING_POLICY_RAID0, (int) raf +// .getStripeSize(), 1); +// raf.addReplica(replicas.subList(0, 1), sp, ReplicationFlags.setPartialReplica(ReplicationFlags +// .setSequentialStrategy(0))); +// assertEquals(2, raf.getXLoc().getNumReplicas()); +// assertEquals(1, raf.getXLoc().getReplica(1).getStripingPolicy().getWidth()); +// +// // add replica with stripe width of 3 +// sp = new StripingPolicy(StripingPolicyType.STRIPING_POLICY_RAID0, (int) raf.getStripeSize(), 3); +// raf.addReplica(replicas.subList(1, 4), sp, ReplicationFlags.setPartialReplica(ReplicationFlags +// .setRandomStrategy(0))); +// assertEquals(3, raf.getXLoc().getNumReplicas()); +// assertEquals(3, raf.getXLoc().getReplica(2).getStripingPolicy().getWidth()); +// +// // read 3 times (each replica will be read) +// for (int i = 0; i < 3; i++) { +// raf.seek(0); +// byte[] resultBuffer = new byte[data.limit()]; +// raf.read(resultBuffer, 0, resultBuffer.length); +// +// // change used replica +// raf.changeReplicaOrder(); +// } +// } +// +// @Test +// public void testBackgroundReplication() throws Exception { +// HOLE_PROBABILITY = 0; +// generateData(1000 * 1000); // ca. 1 MB +// +// RandomAccessFile raf = new RandomAccessFile("rw", testEnv.getMRCAddress(), VOLUME_NAME + "/testfile", +// testEnv.getRpcClient(), userCredentials); +// +// // test needs a stripe width of 2 OSDs +// assertEquals(2, raf.getStripingPolicy().getWidth()); +// +// writeData(raf); +// +// // set read-only +// raf.setReadOnly(true); +// assertEquals(data.limit(), raf.getXLoc().getXLocSet().getRead_only_file_size()); +// +// // add replicas +// List replicas = raf.getSuitableOSDsForAReplica(); +// assertEquals(6, replicas.size()); +// raf.addReplica(replicas.subList(0, 2), raf.getStripingPolicy(), ReplicationFlags +// .setFullReplica(ReplicationFlags.setRandomStrategy(0))); +// raf.addReplica(replicas.subList(2, 4), raf.getStripingPolicy(), ReplicationFlags +// .setFullReplica(ReplicationFlags.setRandomStrategy(0))); +// +// // read data only from replica 2 +// raf.setReplicaSelectionPolicy(new RandomAccessFile.ReplicaSelectionPolicy() { +// @Override +// public List getReplicaOrder(List replicas) { +// List list = new ArrayList(); +// if (replicas.size() > 1) +// list.add(replicas.get(1)); +// else +// list.add(replicas.get(0)); +// return list; +// } +// }); +// // read data from replica 2 => initiate background replication +// byte[] resultBuffer = new byte[STRIPE_SIZE +// * raf.getXLoc().getReplica(0).getStripingPolicy().getWidth()]; +// raf.seek(0); +// raf.read(resultBuffer, 0, resultBuffer.length); +// +// // read data only from replica 3 +// raf.setReplicaSelectionPolicy(new RandomAccessFile.ReplicaSelectionPolicy() { +// @Override +// public List getReplicaOrder(List replicas) { +// List list = new ArrayList(); +// if (replicas.size() > 2) +// list.add(replicas.get(2)); +// else +// list.add(replicas.get(0)); +// return list; +// } +// }); +// // read data from replica 3 => initiate background replication +// resultBuffer = new byte[STRIPE_SIZE * raf.getXLoc().getReplica(0).getStripingPolicy().getWidth()]; +// raf.seek(0); +// raf.read(resultBuffer, 0, resultBuffer.length); +// +// OSDClient osdClient = testEnv.getOSDClient(); +// +// // wait, so the file could be fully replicated in background +// Thread.sleep(2000); +// +// // check, if objects are replicated +// RPCResponse r = osdClient.internal_read_local(raf.getXLoc().getReplica(1) +// .getOSDForObject(2).getAddress(), raf.getFileId(), raf.getCredentials(), 8, 0, 0, +// STRIPE_SIZE, false, null); +// ObjectData oData = r.get().getData(); +// r.freeBuffers(); +// assertEquals(0, oData.getZero_padding()); +// assertEquals(STRIPE_SIZE, oData.getData().capacity()); +// +// r = osdClient.internal_read_local(raf.getXLoc().getReplica(1).getOSDForObject(8).getAddress(), raf +// .getFileId(), raf.getCredentials(), 8, 0, 0, STRIPE_SIZE, false, null); +// oData = r.get().getData(); +// r.freeBuffers(); +// assertEquals(0, oData.getZero_padding()); +// assertEquals(STRIPE_SIZE, oData.getData().capacity()); +// +// r = osdClient.internal_read_local(raf.getXLoc().getReplica(1).getOSDForObject(15).getAddress(), raf +// .getFileId(), raf.getCredentials(), 15, 0, 0, STRIPE_SIZE, false, null); +// oData = r.get().getData(); +// r.freeBuffers(); +// assertEquals(0, oData.getZero_padding()); +// assertEquals(STRIPE_SIZE, oData.getData().capacity()); +// +// r = osdClient.internal_read_local(raf.getXLoc().getReplica(2).getOSDForObject(16).getAddress(), raf +// .getFileId(), raf.getCredentials(), 16, 0, 0, STRIPE_SIZE, false, null); +// oData = r.get().getData(); +// r.freeBuffers(); +// assertEquals(0, oData.getZero_padding()); +// assertEquals(STRIPE_SIZE, oData.getData().capacity()); +// +// r = osdClient.internal_read_local(raf.getXLoc().getReplica(2).getOSDForObject(37).getAddress(), raf +// .getFileId(), raf.getCredentials(), 37, 0, 0, STRIPE_SIZE, false, null); +// oData = r.get().getData(); +// r.freeBuffers(); +// assertEquals(0, oData.getZero_padding()); +// assertEquals(STRIPE_SIZE, oData.getData().capacity()); +// } +// +// @Test +// public void testReplicaRemoval() throws Exception { +// RandomAccessFile raf = new RandomAccessFile("rw", testEnv.getMRCAddress(), VOLUME_NAME + "/testfile", +// testEnv.getRpcClient(), userCredentials); +// // test needs a stripe width of 2 OSDs +// assertEquals(2, raf.getStripingPolicy().getWidth()); +// +// writeData(raf); +// +// // set read-only +// raf.setReadOnly(true); +// +// // add replica +// List replicas = raf.getSuitableOSDsForAReplica(); +// assertEquals(6, replicas.size()); +// raf.addReplica(replicas.subList(0, 2), raf.getStripingPolicy(), ReplicationFlags +// .setPartialReplica(ReplicationFlags.setRandomStrategy(0))); +// assertEquals(2, raf.getXLoc().getNumReplicas()); +// +// // read only from replica 2 +// raf.setReplicaSelectionPolicy(new RandomAccessFile.ReplicaSelectionPolicy() { +// @Override +// public List getReplicaOrder(List replicas) { +// List list = new ArrayList(); +// if (replicas.size() > 1) +// list.add(replicas.get(1)); +// else +// list.add(replicas.get(0)); +// return list; +// } +// }); +// +// // read every object from this replica => replicate objects +// // read and check data => replication +// raf.seek(0); +// byte[] resultBuffer = new byte[data.limit()]; +// raf.read(resultBuffer, 0, resultBuffer.length); +// assertTrue(Arrays.equals(data.array(), resultBuffer)); +// +// // save old credentials +// FileCredentials credentials = raf.getCredentials(); +// +// // remove replica +// raf.removeReplica(replicas.get(0)); +// assertEquals(1, raf.getXLoc().getNumReplicas()); +// +// OSDClient osdClient = testEnv.getOSDClient(); +// +// // NOTE: as long as xLoc cache is not implemented this test will not +// // work +// // check, if old XLoc will be rejected +// // RPCResponse r = +// // osdClient.read(replicas.get(0).getAddress(), raf.getFileId(), +// // credentials, 0, 0, 0, STRIPE_SIZE); +// // try { +// // ObjectData oData = r.get(); +// // fail(); +// // } catch (Exception e) { +// // // correct +// // } +// // r.freeBuffers(); +// +// // NOTE: as long as xLoc cache is not implemented this tests will work +// // wait, so the open-file-table could close the file and delete the data +// System.out.println("Test is waiting 60s."); +// Thread.sleep(60000); +// +// // check, if objects are deleted on OSDs (only spot check) +// RPCResponse r = osdClient.internal_getObjectList(replicas.get(0).getAddress(), raf +// .getFileId(), credentials); +// ObjectList objectList = r.get(); +// r.freeBuffers(); +// ObjectSet objectSet = new ObjectSet(objectList.getStripe_width(), objectList.getFirst_(), +// objectList.getSet().array()); +// assertEquals(0, objectSet.size()); +// r = osdClient.internal_getObjectList(replicas.get(1).getAddress(), raf.getFileId(), credentials); +// objectList = r.get(); +// r.freeBuffers(); +// objectSet = new ObjectSet(objectList.getStripe_width(), objectList.getFirst_(), objectList +// .getSet().array()); +// assertEquals(0, objectSet.size()); +// r = osdClient.internal_getObjectList(replicas.get(1).getAddress(), raf.getFileId(), credentials); +// objectList = r.get(); +// r.freeBuffers(); +// objectSet = new ObjectSet(objectList.getStripe_width(), objectList.getFirst_(), objectList +// .getSet().array()); +// assertEquals(0, objectSet.size()); +// +// // read and check data on remaining (original) replica +// raf.setReplicaSelectionPolicy(raf.SEQUENTIAL_REPLICA_SELECTION_POLICY); +// raf.seek(0); +// resultBuffer = new byte[data.limit()]; +// raf.read(resultBuffer, 0, resultBuffer.length); +// assertTrue(Arrays.equals(data.array(), resultBuffer)); +// } +// +// /** +// * this test must fail because of delayed deletion of data after removing a +// * replica +// * +// * @throws Exception +// */ +// @Test +// public void testRemoveAndAddInShortTime() throws Exception { +// RandomAccessFile raf = new RandomAccessFile("rw", testEnv.getMRCAddress(), VOLUME_NAME + "/testfile", +// testEnv.getRpcClient(), userCredentials); +// OSDClient osdClient = testEnv.getOSDClient(); +// +// // test needs a stripe width of 2 OSDs +// assertEquals(2, raf.getStripingPolicy().getWidth()); +// +// writeData(raf); +// +// // set read-only +// raf.setReadOnly(true); +// +// // read only from replica 2 +// raf.setReplicaSelectionPolicy(new RandomAccessFile.ReplicaSelectionPolicy() { +// @Override +// public List getReplicaOrder(List replicas) { +// List list = new ArrayList(); +// if (replicas.size() > 1) +// list.add(replicas.get(1)); +// else +// list.add(replicas.get(0)); +// return list; +// } +// }); +// +// // add replica +// List replicas = raf.getSuitableOSDsForAReplica(); +// assertEquals(6, replicas.size()); +// +// for (int i = 0; i < 2; i++) { +// raf.addReplica(replicas.subList(0, 2), raf.getStripingPolicy(), ReplicationFlags +// .setFullReplica(ReplicationFlags.setRandomStrategy(0))); +// assertEquals(2, raf.getXLoc().getNumReplicas()); +// +// // read an object from this replica => replicate objects +// raf.seek(0); +// byte[] resultBuffer = new byte[STRIPE_SIZE * 2]; +// raf.read(resultBuffer, 0, resultBuffer.length); +// +// // sleep some time so all objects could be replicated +// System.out.println("Test is waiting 5s."); +// Thread.sleep(5000); +// +// // check if objects would be really replicated +// RPCResponse r = osdClient.internal_getObjectList(replicas.get(0).getAddress(), raf +// .getFileId(), raf.getCredentials()); +// ObjectList objectList = r.get(); +// r.freeBuffers(); +// ObjectSet objectSet = new ObjectSet(objectList.getStripe_width(), objectList.getFirst_(), +// objectList.getSet().array()); +// System.out.println("run " + i + ": " + objectSet); +// assertTrue(10 <= objectSet.size()); +// r = osdClient.internal_getObjectList(replicas.get(0).getAddress(), raf.getFileId(), raf +// .getCredentials()); +// objectList = r.get(); +// r.freeBuffers(); +// objectSet = new ObjectSet(objectList.getStripe_width(), objectList.getFirst_(), objectList +// .getSet().array()); +// System.out.println("run " + i + ": " + objectSet); +// assertTrue(10 <= objectSet.size()); +// +// // remove replica +// raf.removeReplica(replicas.get(0)); +// assertEquals(1, raf.getXLoc().getNumReplicas()); +// +// // add replica again +// raf.addReplica(replicas.subList(0, 2), raf.getStripingPolicy(), ReplicationFlags +// .setFullReplica(ReplicationFlags.setRandomStrategy(0))); +// assertEquals(2, raf.getXLoc().getNumReplicas()); +// +// // read an object from this replica => replicate objects +// raf.seek(0); +// resultBuffer = new byte[STRIPE_SIZE * 2]; +// raf.read(resultBuffer, 0, resultBuffer.length); +// +// // wait, so the open-file-table could close the file and delete all +// // the data (THAT'S THE PROBLEM) +// System.out.println("Test is waiting 60s."); +// Thread.sleep(60000); +// +// r = osdClient.internal_getObjectList(replicas.get(0).getAddress(), raf.getFileId(), raf +// .getCredentials()); +// objectList = r.get(); +// r.freeBuffers(); +// objectSet = new ObjectSet(objectList.getStripe_width(), objectList.getFirst_(), objectList +// .getSet().array()); +// System.out.println("run " + i + ": " + objectSet); +// assertTrue(0 == objectSet.size()); +// r = osdClient.internal_getObjectList(replicas.get(1).getAddress(), raf.getFileId(), raf +// .getCredentials()); +// objectList = r.get(); +// r.freeBuffers(); +// objectSet = new ObjectSet(objectList.getStripe_width(), objectList.getFirst_(), objectList +// .getSet().array()); +// System.out.println("run " + i + ": " + objectSet); +// assertTrue(0 == objectSet.size()); +// +// // remove replica +// raf.removeReplica(replicas.get(0)); +// assertEquals(1, raf.getXLoc().getNumReplicas()); +// } +// } +// +// private void writeData(RandomAccessFile raf) throws Exception { +// // write data +// int bytesToWrite; +// int startOffset = 0; +// for (int holeStart : holes) { +// // write data in front of the hole +// bytesToWrite = holeStart - startOffset; +// raf.write(data.array(), startOffset, bytesToWrite); +// // skip hole +// raf.seek(holeStart + STRIPE_SIZE); +// startOffset = holeStart + STRIPE_SIZE; +// } +// // write last data +// raf.write(data.array(), startOffset, data.limit() - startOffset); +// } +//} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/test/osd/replication/ReplicationTest.java b/java/servers/test/org/xtreemfs/test/osd/replication/ReplicationTest.java new file mode 100755 index 0000000..6da37a2 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/replication/ReplicationTest.java @@ -0,0 +1,594 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd.replication; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.InternalReadLocalResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectList; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + * 29.01.2009 + * + * @author clorenz + */ +public class ReplicationTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + OSD[] osds; + OSDConfig[] configs; + OSDServiceClient client; + + private Capability cap; + private String fileID; + private XLocations xLoc; + + // needed for dummy classes + private int stripeSize; + private ReusableBuffer data; + + private long objectNo; + private TestEnvironment testEnv; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + this.stripeSize = 128 * 1024; // byte + this.data = SetupUtils.generateData(stripeSize); + + // startup: DIR + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.OSD_CLIENT }); + testEnv.start(); + + osds = new OSD[12]; + configs = SetupUtils.createMultipleOSDConfigs(12); + for (int i = 0; i < osds.length; i++) { + osds[i] = new OSD(configs[i]); + } + + client = testEnv.getOSDClient(); + + fileID = "1:1"; + objectNo = 0; + cap = new Capability(fileID, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 60, + System.currentTimeMillis(), "", 0, false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, + configs[0].getCapabilitySecret()); + + xLoc = createLocations(4, 3); + } + + private XLocations createLocations(int numberOfReplicas, int numberOfStripedOSDs) throws InvalidXLocationsException { + assert (numberOfReplicas * numberOfStripedOSDs <= osds.length); + + List rlist = new LinkedList(); + for (int replica = 0; replica < numberOfReplicas; replica++) { + List osdset = new LinkedList(); + int startOSD = replica * numberOfStripedOSDs; + for (int stripe = 0; stripe < numberOfStripedOSDs; stripe++) { + // add available osds + osdset.add(configs[startOSD + stripe].getUUID().toString()); + } + + Replica r = Replica.newBuilder() + .setStripingPolicy(SetupUtils.getStripingPolicy(osdset.size(), stripeSize / 1024)) + .setReplicationFlags(0).addAllOsdUuids(osdset).build(); + rlist.add(r); + } + XLocSet locSet = XLocSet.newBuilder().setReadOnlyFileSize(0) + .setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE).setVersion(1).addAllReplicas(rlist) + .build(); + // set the first replica as current replica + + // set the first replica as current replica + XLocations locations = new XLocations(locSet, new ServiceUUID(locSet.getReplicas(0).getOsdUuids(0))); + return locations; + } + + private void setReplicated(long filesize, int indexOfFullReplica) throws Exception { + // set replication flags + + List rlist = new LinkedList(); + + for (int i = 0; i < xLoc.getXLocSet().getReplicasCount(); i++) { + Replica r = xLoc.getXLocSet().getReplicas(i); + if (i == indexOfFullReplica) + rlist.add(r + .toBuilder() + .setReplicationFlags( + ReplicationFlags.setReplicaIsComplete(ReplicationFlags + .setPartialReplica(ReplicationFlags.setRandomStrategy(0)))).build()); + else + rlist.add(r.toBuilder() + .setReplicationFlags(ReplicationFlags.setPartialReplica(ReplicationFlags.setRandomStrategy(0))) + .build()); + } + + XLocSet locSet = xLoc.getXLocSet().toBuilder().clearReplicas().addAllReplicas(rlist) + .setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY).setReadOnlyFileSize(filesize) + .build(); + + xLoc = new XLocations(locSet, new ServiceUUID(locSet.getReplicas(0).getOsdUuids(0))); + + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + for (OSD osd : this.osds) + osd.shutdown(); + + testEnv.shutdown(); + + // free buffers + BufferPool.free(data); + } + + /* + * private ObjectData getObjectData(ReusableBuffer data) { return new ObjectData(0, false, 0, + * data.createViewBuffer()); } + */ + + @Test + public void testStriped() throws Exception { + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLoc.getXLocSet()).build(); + + // write object to replica 3 + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse w = client.write(xLoc.getOSDsForObject(objectNo).get(2).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo, 0, 0, 0, objdata, + data.createViewBuffer()); + OSDWriteResponse wResp = w.get(); + w.freeBuffers(); + + // change XLoc + setReplicated(data.limit(), 2); + fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLoc.getXLocSet()).build(); + + // read object from replica 3 (object exists on this OSD) => normal read + RPCResponse r = client.read(xLoc.getOSDsForObject(objectNo).get(2).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo, 0, 0, stripeSize); + ObjectData rResp = r.get(); + assertTrue(Arrays.equals(data.array(), r.getData().array())); + r.freeBuffers(); + + // read object from replica 2 (object not exists on this OSD) => replication + r = client.read(xLoc.getOSDsForObject(objectNo).get(1).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo, 0, 0, stripeSize); + rResp = r.get(); + if (data.capacity() > 0) { + assertNotNull(r.getData()); + assertTrue(Arrays.equals(data.array(), r.getData().array())); + } else + assertNull(r.getData()); + r.freeBuffers(); + + // read object from replica 4 (object not exists on this OSD) => replication + r = client.read(xLoc.getOSDsForObject(objectNo).get(3).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo, 0, 0, stripeSize); + rResp = r.get(); + if (data.capacity() > 0) + assertTrue(Arrays.equals(data.array(), r.getData().array())); + else + assertNull(r.getData()); + r.freeBuffers(); + + // read part of object from replica 1 (object not exists on this OSD) => replication + r = client.read(xLoc.getOSDsForObject(objectNo).get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo, 0, stripeSize / 4, stripeSize / 4); + rResp = r.get(); + int j = stripeSize / 4; + byte[] responseData = r.getData().array(); + byte[] dataBytes = data.array(); + for (int i = 0; i < responseData.length; i++) { + assertEquals(dataBytes[j++], responseData[i]); + } + r.freeBuffers(); + + } + + @Test + public void testHoleAndEOF() throws Exception { + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLoc.getXLocSet()).build(); + + // write object 1 to replica 1 => full object + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse w = client.write(xLoc.getOSDsForObject(objectNo).get(0).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo, 0, 0, 0, objdata, + data.createViewBuffer()); + OSDWriteResponse wResp = w.get(); + w.freeBuffers(); + + // object 2 is a hole + + ReusableBuffer data2 = SetupUtils.generateData(stripeSize / 2); + // write half object 3 to replica 1 with offset => half object, HOLE + w = client.write(xLoc.getOSDsForObject(objectNo + 2).get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 2, 0, stripeSize / 4, 0, objdata, + data2.createViewBuffer()); + wResp = w.get(); + w.freeBuffers(); + + // write half object 4 to replica 1 => half object, EOF + w = client.write(xLoc.getOSDsForObject(objectNo + 3).get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 3, 0, 0, 0, objdata, data2.createViewBuffer()); + wResp = w.get(); + w.freeBuffers(); + + // change XLoc (filesize) + setReplicated(stripeSize * 3 + data2.limit(), 0); + fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLoc.getXLocSet()).build(); + + // read object from replica 2 + RPCResponse r = client.read(xLoc.getOSDsForObject(objectNo).get(1).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo, 0, 0, stripeSize); + ObjectData rResp = r.get(); + if (data.capacity() > 0) + assertTrue(Arrays.equals(data.array(), r.getData().array())); + else + assertNull(r.getData()); + r.freeBuffers(); + + // read hole from replica 2 + r = client.read(xLoc.getOSDsForObject(objectNo + 1).get(1).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 1, 0, 0, stripeSize); + rResp = r.get(); + // filled with zeros + if (rResp.getZeroPadding() == 0) { + for (byte b : r.getData().array()) { + assertEquals(0, b); + } + } + r.freeBuffers(); + + // check whether a padding object for object 2 has been created on + // replica 2 + RPCResponse intRLRsp = client.xtreemfs_internal_read_local( + xLoc.getOSDsForObject(objectNo + 1).get(1).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 1, 0, 0, stripeSize, false, new ArrayList()); + InternalReadLocalResponse intRL = intRLRsp.get(); + assertEquals(stripeSize, intRL.getData().getZeroPadding()); + + // read EOF from replica 2 + r = client.read(xLoc.getOSDsForObject(objectNo + 4).get(1).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 4, 0, 0, stripeSize); + rResp = r.get(); + assertNull(r.getData()); + r.freeBuffers(); + + // read hole within an object from replica 2 + r = client.read(xLoc.getOSDsForObject(objectNo + 2).get(1).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 2, 0, 0, stripeSize); + rResp = r.get(); + byte[] responseData = r.getData().array(); + // correct length + assertEquals(stripeSize / 4 + data2.limit(), responseData.length); + // first quarter filled with zeros + for (int i = 0; i < stripeSize / 4; i++) { + assertEquals((byte) 0, responseData[i]); + } + int j = 0; + // then there is the data + byte[] data2bytes = data2.array(); + for (int i = stripeSize / 4; i < (stripeSize / 4) * 3; i++) { + assertEquals(data2bytes[j++], responseData[i]); + } + // last quarter filled with zeros again + assertEquals(stripeSize / 4, rResp.getZeroPadding()); + r.freeBuffers(); + + // read EOF within data from replica 2 + r = client.read(xLoc.getOSDsForObject(objectNo + 3).get(1).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 3, 0, 0, stripeSize); + rResp = r.get(); + assertTrue(Arrays.equals(data2.array(), r.getData().array())); + r.freeBuffers(); + + // read hole within an object from replica 2 with offset and length + r = client.read(xLoc.getOSDsForObject(objectNo + 2).get(2).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 2, 0, stripeSize / 4, data2.limit()); + rResp = r.get(); + // correct length and data + assertEquals(data2.limit(), r.getData().array().length); + assertTrue(Arrays.equals(data2.array(), r.getData().array())); + r.freeBuffers(); + + // free buffers + BufferPool.free(data2); + } + + /* + * following tests are testing readLocal-RPC + */ + /** + * striped case + */ + @Test + public void testObjectLocalAvailable() throws Exception { + // Default case. + helperObjectLocalAvailable(); + } + + public void helperObjectLocalAvailable() throws Exception { + ServiceUUID serverID = xLoc.getOSDsForObject(objectNo).get(0); + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLoc.getXLocSet()).build(); + + // write data + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = client.write(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo, 0, 0, 0, objdata, this.data.createViewBuffer()); + OSDWriteResponse resp = r.get(); + r.freeBuffers(); + + // change XLoc + setReplicated(this.data.limit(), 0); + fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLoc.getXLocSet()).build(); + + // read data + RPCResponse r2 = client.xtreemfs_internal_read_local(serverID.getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo, 0, 0, stripeSize, + false, new ArrayList()); + InternalReadLocalResponse resp2 = r2.get(); + + assertTrue(Arrays.equals(data.array(), r2.getData().array())); + assertEquals(0, resp2.getObjectSetCount()); + + r2.freeBuffers(); + + // read only part of data + r2 = client.xtreemfs_internal_read_local(serverID.getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo, 0, stripeSize / 4, stripeSize / 2, true, + new ArrayList()); + resp2 = r2.get(); + + int j = stripeSize / 4; + byte[] responseData = r2.getData().array(); + byte[] dataBytes = data.array(); + assertEquals(stripeSize / 2, responseData.length); + for (int i = 0; i < responseData.length; i++) { + assertEquals(dataBytes[j++], responseData[i]); + } + assertEquals(1, resp2.getObjectSetCount()); + + // check object list + ObjectList objectList = resp2.getObjectSet(0); + ObjectSet list = new ObjectSet(objectList.getStripeWidth(), objectList.getFirst(), objectList.getSet() + .toByteArray()); + assertNotNull(list); + assertEquals(1, list.size()); + assertTrue(list.contains(objectNo)); + + r2.freeBuffers(); + } + + /** + * striped case + */ + @Test + public void testObjectLocalNOTAvailable() throws Exception { + helperObjectLocalNOTAvailable(); + } + + public void helperObjectLocalNOTAvailable() throws Exception { + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLoc.getXLocSet()).build(); + + // read object, before one has been written + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + RPCResponse r = client.xtreemfs_internal_read_local(xLoc.getOSDsForObject(objectNo) + .get(0).getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo, + 0, 0, stripeSize, true, new ArrayList()); + InternalReadLocalResponse resp = r.get(); + assertNull(r.getData()); + assertEquals(1, resp.getObjectSetCount()); + ObjectSet list = new ObjectSet(resp.getObjectSet(0).getStripeWidth(), resp.getObjectSet(0).getFirst(), resp + .getObjectSet(0).getSet().toByteArray()); + assertEquals(0, list.size()); + r.freeBuffers(); + + // write data + RPCResponse r2 = client.write(xLoc.getOSDsForObject(objectNo).get(0).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo, 0, 0, 0, objdata, + this.data.createViewBuffer()); + OSDWriteResponse resp2 = r2.get(); + r2.freeBuffers(); + r2 = client + .write(xLoc.getOSDsForObject(objectNo + 2).get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 2, 0, 0, 0, objdata, + this.data.createViewBuffer()); + resp2 = r2.get(); + r2.freeBuffers(); + + // change XLoc + setReplicated(data.limit() * 2, 0); + fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLoc.getXLocSet()).build(); + + // read data + r = client.xtreemfs_internal_read_local(xLoc.getOSDsForObject(objectNo).get(0).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo, 0, 0, stripeSize, + false, new ArrayList()); + resp = r.get(); + assertTrue(Arrays.equals(data.array(), r.getData().array())); + r.freeBuffers(); + r = client.xtreemfs_internal_read_local(xLoc.getOSDsForObject(objectNo + 2).get(0).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo + 2, 0, 0, stripeSize, + false, new ArrayList()); + resp = r.get(); + assertTrue(Arrays.equals(data.array(), r.getData().array())); + r.freeBuffers(); + + // read higher object than has been written (EOF) + r = client.xtreemfs_internal_read_local(xLoc.getOSDsForObject(objectNo + 3).get(0).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo + 3, 0, 0, stripeSize, + false, new ArrayList()); + resp = r.get(); + assertNull(r.getData()); + r.freeBuffers(); + + // read object that has not been written (hole) + r = client.xtreemfs_internal_read_local(xLoc.getOSDsForObject(objectNo + 1).get(0).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo + 1, 0, 0, stripeSize, + false, new ArrayList()); + resp = r.get(); + assertNull(r.getData()); + r.freeBuffers(); + } + + @Test + public void testObjectLocalAvailableNONStriped() throws Exception { + this.xLoc = createLocations(2, 1); + // reuse test + helperObjectLocalAvailable(); + } + + @Test + public void testObjectLocalNOTAvailableNONStriped() throws Exception { + this.xLoc = createLocations(2, 1); + // reuse test + helperObjectLocalNOTAvailable(); + } + + @Test + public void testGetObjectList() throws Exception { + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLoc.getXLocSet()).build(); + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + + // read data + RPCResponse r = client.xtreemfs_internal_get_object_set(xLoc.getOSDsForObject(objectNo).get(0) + .getAddress(), RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID); + ObjectList objectList = r.get(); + r.freeBuffers(); + ObjectSet list = new ObjectSet(objectList.getStripeWidth(), objectList.getFirst(), objectList.getSet() + .toByteArray()); + assertEquals(0, list.size()); + + // write object to replica 1 : OSD 1 + RPCResponse w = client.write(xLoc.getOSDsForObject(objectNo).get(0).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID, objectNo, 0, 0, 0, objdata, + this.data.createViewBuffer()); + OSDWriteResponse wResp = w.get(); + w.freeBuffers(); + + // read data + r = client.xtreemfs_internal_get_object_set(xLoc.getOSDsForObject(objectNo).get(0).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID); + objectList = r.get(); + r.freeBuffers(); + list = new ObjectSet(objectList.getStripeWidth(), objectList.getFirst(), objectList.getSet().toByteArray()); + assertEquals(1, list.size()); + assertTrue(list.contains(objectNo)); + + // write object to replica 1 : OSD 2 + w = client + .write(xLoc.getOSDsForObject(objectNo + 1).get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 1, 0, 0, 0, objdata, + this.data.createViewBuffer()); + wResp = w.get(); + w.freeBuffers(); + + // write object to replica 1 : OSD 3 + w = client + .write(xLoc.getOSDsForObject(objectNo + 2).get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 2, 0, 0, 0, objdata, + this.data.createViewBuffer()); + wResp = w.get(); + w.freeBuffers(); + + // write object to replica 1 : OSD 1 + w = client + .write(xLoc.getOSDsForObject(objectNo + 3).get(0).getAddress(), RPCAuthentication.authNone, + RPCAuthentication.userService, fc, fileID, objectNo + 3, 0, 0, 0, objdata, + this.data.createViewBuffer()); + wResp = w.get(); + w.freeBuffers(); + + // read object list from OSD 1 : OSD 1 + r = client.xtreemfs_internal_get_object_set(xLoc.getOSDsForObject(objectNo).get(0).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID); + objectList = r.get(); + r.freeBuffers(); + list = new ObjectSet(objectList.getStripeWidth(), objectList.getFirst(), objectList.getSet().toByteArray()); + assertEquals(2, list.size()); + assertTrue(list.contains(objectNo)); + assertTrue(list.contains(objectNo + 3)); + + // read object list from OSD 1 : OSD 2 + r = client.xtreemfs_internal_get_object_set(xLoc.getOSDsForObject(objectNo + 1).get(0).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID); + objectList = r.get(); + r.freeBuffers(); + list = new ObjectSet(objectList.getStripeWidth(), objectList.getFirst(), objectList.getSet().toByteArray()); + assertEquals(1, list.size()); + assertTrue(list.contains(objectNo + 1)); + + // read object list from OSD 1 : OSD 3 + r = client.xtreemfs_internal_get_object_set(xLoc.getOSDsForObject(objectNo + 2).get(0).getAddress(), + RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileID); + objectList = r.get(); + r.freeBuffers(); + list = new ObjectSet(objectList.getStripeWidth(), objectList.getFirst(), objectList.getSet().toByteArray()); + assertEquals(1, list.size()); + assertTrue(list.contains(objectNo + 2)); + } +} diff --git a/java/servers/test/org/xtreemfs/test/osd/replication/ServiceAvailabilityTest.java b/java/servers/test/org/xtreemfs/test/osd/replication/ServiceAvailabilityTest.java new file mode 100755 index 0000000..338df2b --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/replication/ServiceAvailabilityTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd.replication; + + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.ServiceAvailability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestHelper; + +/** + * + * 06.04.2009 + */ +public class ServiceAvailabilityTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + public final static int INITIAL_TIMEOUT = 100; // 0.1 second + public final static int CLEANUP_INTERVAL = 1000; // 1 second + public final static int MAX_LAST_ACCESS = 1000 * 3; // 3 seconds + + ServiceAvailability serviceAvailability; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + serviceAvailability = new ServiceAvailability(INITIAL_TIMEOUT, MAX_LAST_ACCESS, CLEANUP_INTERVAL); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + serviceAvailability.shutdown(); + } + + /** + * IMPORTANT: Tests timeouts. On old slow PCs this test could fail, although the class works correct. + * @throws Exception + */ + @Test + public void testCorrectTimeouts() throws Exception { + ServiceUUID service = new ServiceUUID("UUID:localhost:36840"); + + // service available + assertTrue(serviceAvailability.isServiceAvailable(service)); + assertTrue(serviceAvailability.isServiceAvailable(service)); + Thread.sleep(INITIAL_TIMEOUT); + assertTrue(serviceAvailability.isServiceAvailable(service)); + + // service not available + serviceAvailability.setServiceWasNotAvailable(service); + assertFalse(serviceAvailability.isServiceAvailable(service)); + Thread.sleep(INITIAL_TIMEOUT); + assertFalse(serviceAvailability.isServiceAvailable(service)); + + // service available again + Thread.sleep(INITIAL_TIMEOUT*2); + assertTrue(serviceAvailability.isServiceAvailable(service)); + + // service not available again + serviceAvailability.setServiceWasNotAvailable(service); + serviceAvailability.setServiceWasNotAvailable(service); + Thread.sleep(INITIAL_TIMEOUT*7); + assertFalse(serviceAvailability.isServiceAvailable(service)); + Thread.sleep(INITIAL_TIMEOUT*9); + assertTrue(serviceAvailability.isServiceAvailable(service)); + } + + /** + * IMPORTANT: Tests timeouts. On old slow PCs this test could fail, although the class works correct. + * @throws Exception + */ + @Test + public void testServiceRemoval() throws Exception { + List services = new ArrayList(); + int port = 36840; + for (int i = 0; i < 10; i++) + services.add(new ServiceUUID("UUID:localhost:"+(port++))); + + // test correct removal of elements if last access is too long ago + for(ServiceUUID service : services) { + // add to "map" + assertTrue(serviceAvailability.isServiceAvailable(service)); + // timeout > MAX_LAST_ACCESS + for (int timeout = INITIAL_TIMEOUT; timeout > MAX_LAST_ACCESS+CLEANUP_INTERVAL; timeout = timeout * 2) { + serviceAvailability.setServiceWasNotAvailable(service); + } + } + Thread.sleep(CLEANUP_INTERVAL); + // all OSDs must be available again, although the timeout is not over; because they have been removed + for(ServiceUUID service : services) { + assertTrue(serviceAvailability.isServiceAvailable(service)); + } + } +} diff --git a/java/servers/test/org/xtreemfs/test/osd/replication/TransferStrategiesTest.java b/java/servers/test/org/xtreemfs/test/osd/replication/TransferStrategiesTest.java new file mode 100644 index 0000000..d577437 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/replication/TransferStrategiesTest.java @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2008-2011 by Christian Lorenz, + * Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd.replication; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.ServiceAvailability; +import org.xtreemfs.common.uuids.ServiceUUID; +import org.xtreemfs.common.xloc.InvalidXLocationsException; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.common.xloc.XLocations; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.osd.replication.ObjectSet; +import org.xtreemfs.osd.replication.transferStrategies.RandomStrategy; +import org.xtreemfs.osd.replication.transferStrategies.SequentialPrefetchingStrategy; +import org.xtreemfs.osd.replication.transferStrategies.SequentialStrategy; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.NextRequest; +import org.xtreemfs.osd.replication.transferStrategies.TransferStrategy.TransferStrategyException; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestHelper; + +/** + * + * 18.12.2008 + * + * @author clorenz + */ +public class TransferStrategiesTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private final static String fileID = "1:1"; + private static XLocations xLoc; + + // needed for dummy classes + private final static int stripeSize = 128 * 1024; // byte + + private TransferStrategy strategy; + private final static int osdNumber = 12; + private final static long objectNo = 2; + private final static long filesize = 1024 * 1024 * 128; // byte + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + + xLoc = createLocations(4, 3); + } + + /* + * copied from org.xtreemfs.test.osd.replication.ReplicationTest + */ + private static XLocations createLocations(int numberOfReplicas, int numberOfStripedOSDs) + throws InvalidXLocationsException { + assert (numberOfReplicas * numberOfStripedOSDs <= osdNumber); + + List rlist = new LinkedList(); + int port = 33640; + for (int replica = 0; replica < numberOfReplicas; replica++) { + List osdset = new LinkedList(); + int startOSD = replica * numberOfStripedOSDs; + for (int stripe = 0; stripe < numberOfStripedOSDs; stripe++) { + // add available osds + osdset.add(new ServiceUUID("UUID:localhost:" + (port++)).toString()); + } + int flags; + if (replica == 1) + flags = ReplicationFlags.setReplicaIsComplete(0); + else + flags = ReplicationFlags.setPartialReplica(ReplicationFlags.setRandomStrategy(0)); + + Replica r = Replica.newBuilder() + .setStripingPolicy(SetupUtils.getStripingPolicy(osdset.size(), stripeSize / 1024)) + .setReplicationFlags(flags).addAllOsdUuids(osdset).build(); + rlist.add(r); + + } + + XLocSet locSet = XLocSet.newBuilder().setReadOnlyFileSize(1024 * 1024 * 100) + .setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE).setVersion(1).addAllReplicas(rlist) + .build(); + // set the first replica as current replica + + // set the first replica as current replica + XLocations locations = new XLocations(locSet, new ServiceUUID(locSet.getReplicas(0).getOsdUuids(0))); + + return locations; + } + + @Before + public void setUp() throws Exception { + this.strategy = new RandomStrategy(fileID, xLoc, new ServiceAvailability()); + } + + @After + public void tearDown() throws Exception { + } + + /** + * Test method for {@link org.xtreemfs.osd.replication.transferStrategies.TransferStrategy#addRequiredObject(long)} + * and {@link org.xtreemfs.osd.replication.transferStrategies.TransferStrategy#removeRequiredObject(long)} . + */ + @Test + public void testAddAndRemoveRequiredObject() { + this.strategy.addObject(objectNo, false); + assertTrue(this.strategy.removeObject(objectNo)); + } + + /** + * Test method for {@link org.xtreemfs.osd.replication.transferStrategies.TransferStrategy#addPreferredObject(long)} + * and {@link org.xtreemfs.osd.replication.transferStrategies.TransferStrategy#removePreferredObject(long)} . + */ + @Test + public void testAddAndRemovePreferredObject() { + this.strategy.addObject(objectNo, true); + assertTrue(this.strategy.removeObject(objectNo)); + } + + /** + * Test method for + * {@link org.xtreemfs.osd.replication.transferStrategies.TransferStrategy#getRequiredObjectsCount()} and + * {@link org.xtreemfs.osd.replication.transferStrategies.TransferStrategy#getPreferredObjectsCount()} . + */ + @Test + public void testGetXXXObjectsCount() { + this.strategy.addObject(1, false); + this.strategy.addObject(2, false); + this.strategy.addObject(3, false); + this.strategy.addObject(4, false); + this.strategy.addObject(4, false); + this.strategy.addObject(5, true); + this.strategy.addObject(3, true); + + assertEquals(5, this.strategy.getObjectsCount()); + } + + /** + * No assert in this test possible due to information hiding. Check debug output for correctness. Test method for + * {@link org.xtreemfs.osd.replication.transferStrategies.TransferStrategy#setOSDsObjectSet(set, osd)} . + */ + @Test + public void testSetOSDsObjectSet() { + this.strategy.addObject(0, false); + this.strategy.addObject(1, true); + this.strategy.addObject(2, false); + this.strategy.addObject(3, false); + this.strategy.addObject(4, false); + this.strategy.addObject(2, true); + + // replica 1 + ObjectSet set = fillObjectSet(0); + this.strategy.setOSDsObjectSet(set, xLoc.getReplica(0).getOSDs().get(0)); + set = fillObjectSet(1); + this.strategy.setOSDsObjectSet(set, xLoc.getReplica(0).getOSDs().get(1)); + set = fillObjectSet(2); + this.strategy.setOSDsObjectSet(set, xLoc.getReplica(0).getOSDs().get(2)); + // replica 2 (complete replica) + set = fillObjectSet(0, 3, 6, 9); + this.strategy.setOSDsObjectSet(set, xLoc.getReplica(1).getOSDs().get(0)); + set = fillObjectSet(1, 4, 7, 10); + this.strategy.setOSDsObjectSet(set, xLoc.getReplica(1).getOSDs().get(1)); + set = fillObjectSet(2, 5, 8, 11); + this.strategy.setOSDsObjectSet(set, xLoc.getReplica(1).getOSDs().get(2)); + // replica 3 + set = fillObjectSet(9); + this.strategy.setOSDsObjectSet(set, xLoc.getReplica(2).getOSDs().get(0)); + set = fillObjectSet(10); + this.strategy.setOSDsObjectSet(set, xLoc.getReplica(2).getOSDs().get(1)); + set = fillObjectSet(11); + this.strategy.setOSDsObjectSet(set, xLoc.getReplica(2).getOSDs().get(2)); + + try { + while (strategy.getObjectsCount() > 0) { + this.strategy.selectNext(); + NextRequest next = this.strategy.getNext(); + assert (next != null); + } + } catch (TransferStrategyException e) { + fail(); + } + } + + /** + * Test method for {@link org.xtreemfs.osd.replication.transferStrategies.SequentialStrategy#selectNext()}. + */ + @Test + public void testSelectNextForSequentialTransfer() { + this.strategy = new SequentialStrategy(fileID, xLoc, new ServiceAvailability()); + this.strategy.addObject(0, false); + this.strategy.addObject(1, true); + this.strategy.addObject(2, false); + this.strategy.addObject(3, false); + this.strategy.addObject(4, false); + this.strategy.addObject(2, true); + + try { + // stripe 2 (preferred) + this.strategy.selectNext(); + NextRequest next = this.strategy.getNext(); + assertEquals(1, next.objectNo); + assertEquals(xLoc.getReplica(1).getOSDForObject(next.objectNo), next.osd); + assertFalse(next.attachObjectSet); + + // stripe 3 (preferred) + this.strategy.selectNext(); + next = this.strategy.getNext(); + assertEquals(2, next.objectNo); + assertEquals(xLoc.getReplica(1).getOSDForObject(next.objectNo), next.osd); + assertFalse(next.attachObjectSet); + + // stripe 1 + this.strategy.selectNext(); + next = this.strategy.getNext(); + assertEquals(0, next.objectNo); + assertEquals(xLoc.getReplica(1).getOSDForObject(next.objectNo), next.osd); + assertFalse(next.attachObjectSet); + + // stripe 1 + this.strategy.selectNext(); + next = this.strategy.getNext(); + assertEquals(3, next.objectNo); + assertEquals(xLoc.getReplica(1).getOSDForObject(next.objectNo), next.osd); + assertFalse(next.attachObjectSet); + + // stripe 2 + this.strategy.selectNext(); + next = this.strategy.getNext(); + assertEquals(4, next.objectNo); + assertEquals(xLoc.getReplica(1).getOSDForObject(next.objectNo), next.osd); + assertFalse(next.attachObjectSet); + + // no more requests possible + this.strategy.selectNext(); + next = this.strategy.getNext(); + assertNull(next); + } catch (TransferStrategyException e) { + fail(e.getLocalizedMessage()); + } + } + + /** + * Test method for {@link org.xtreemfs.osd.replication.transferStrategies.RandomStrategy#selectNext()}. + */ + @Test + public void testSelectNextForRandomTransfer() { + this.strategy = new RandomStrategy(fileID, xLoc, new ServiceAvailability()); + + ArrayList objectsToRequest = new ArrayList(); + objectsToRequest.add(Long.valueOf(1)); + objectsToRequest.add(Long.valueOf(2)); + objectsToRequest.add(Long.valueOf(3)); + objectsToRequest.add(Long.valueOf(4)); + + for (int i = 0; i < objectsToRequest.size(); i++) { + this.strategy.addObject(objectsToRequest.get(i), false); + } + this.strategy.addObject(2, true); + + ArrayList requestedObjects = new ArrayList(); + + try { + NextRequest next; + for (int i = 0; i < objectsToRequest.size(); i++) { + this.strategy.selectNext(); + next = this.strategy.getNext(); + requestedObjects.add(Long.valueOf(next.objectNo)); + boolean contained = false; + for (org.xtreemfs.common.xloc.Replica r : xLoc.getReplicas()) { + if (r.getOSDs().contains(next.osd)) + contained = true; + } + assertTrue(contained); + } + + for (int i = 0; i < objectsToRequest.size(); i++) + assertTrue(requestedObjects.contains(objectsToRequest.get(i))); + + // no more requests possible + this.strategy.selectNext(); + next = this.strategy.getNext(); + assertNull(next); + } catch (TransferStrategyException e) { + fail(e.getLocalizedMessage()); + } + } + + /** + * Test method for + * {@link org.xtreemfs.osd.replication.transferStrategies.SequentialPrefetchingStrategy#selectNext()}. + */ + @Test + public void testSelectNextForSequentialPrefetchingTransfer() { + this.strategy = new SequentialPrefetchingStrategy(fileID, xLoc, new ServiceAvailability()); + this.strategy.addObject(0, true); + this.strategy.addObject(60, true); + this.strategy.addObject(72, true); + + // objects count + assertEquals(3, strategy.getObjectsCount()); + + try { + // preferred objects + this.strategy.selectNext(); + NextRequest next = this.strategy.getNext(); + assertEquals(0, next.objectNo); + // check, if objects are added by prefetching + int objectsToPrefetch = SequentialPrefetchingStrategy.DEFAULT_PREFETCHING_COUNT + 3; + assertEquals(2 + objectsToPrefetch, strategy.getObjectsCount()); + + this.strategy.selectNext(); + next = this.strategy.getNext(); + assertEquals(60, next.objectNo); + // check, if objects are added by prefetching + // default + preferred objects - number 72 is preferred, so don't prefetch + objectsToPrefetch += SequentialPrefetchingStrategy.DEFAULT_PREFETCHING_COUNT + 2 - 1; + assertEquals(1 + objectsToPrefetch, strategy.getObjectsCount()); + + this.strategy.selectNext(); + next = this.strategy.getNext(); + assertEquals(72, next.objectNo); + // check, if objects are added by prefetching + objectsToPrefetch += SequentialPrefetchingStrategy.DEFAULT_PREFETCHING_COUNT + 1 - 8; + assertEquals(0 + objectsToPrefetch, strategy.getObjectsCount()); + + // prefetched objects + this.strategy.selectNext(); + next = this.strategy.getNext(); + assertEquals(3, next.objectNo); + + // ... and more + } catch (TransferStrategyException e) { + fail(e.getLocalizedMessage()); + } + } + + // /** + // * Test method for {@link org.xtreemfs.osd.replication.transferStrategies.RarestFirstStrategy#selectNext()}. + // */ + // @Test + // public void testSelectNextForRarestFirstTransfer() { + // this.strategy = new RarestFirstStrategy(fileID, xLoc, new ServiceAvailability()); + // + // // prepare objects to fetch + // long[] objectsToRequest = { 0, 1, 2, 3, 4, 5, 6, 7, 8,9,10,11,12,13 }; + // this.strategy.addObject(0, false); + // this.strategy.addObject(1, true); + // this.strategy.addObject(2, true); + // for(int i=3; i< objectsToRequest.length-1; i++) + // this.strategy.addObject(i, false); + // + // // prepare object sets of OSDs + // ObjectSet set = fillObjectSet(0, 2, 4); + // this.strategy.setOSDsObjectSet(set, xLoc.getReplica(0).getOSDs().get(0)); + // set = fillObjectSet(1, 3); + // this.strategy.setOSDsObjectSet(set, xLoc.getReplica(0).getOSDs().get(1)); + // set = fillObjectSet(0, 2, 10); + // this.strategy.setOSDsObjectSet(set, xLoc.getReplica(2).getOSDs().get(0)); + // set = fillObjectSet(1, 7, 9); + // this.strategy.setOSDsObjectSet(set, xLoc.getReplica(2).getOSDs().get(1)); + // set = fillObjectSet(0, 4, 6, 10, 12); + // this.strategy.setOSDsObjectSet(set, xLoc.getReplica(3).getOSDs().get(0)); + // set = fillObjectSet(1, 7, 9, 11); + // this.strategy.setOSDsObjectSet(set, xLoc.getReplica(3).getOSDs().get(1)); + // + // // set complete replica set later + // set = fillObjectSet(0, 2, 4, 6, 8, 10, 12); + // this.strategy.setOSDsObjectSet(set, xLoc.getReplica(1).getOSDs().get(0)); // complete replica + // set = fillObjectSet(1, 3, 5, 7, 9, 11, 13); + // this.strategy.setOSDsObjectSet(set, xLoc.getReplica(1).getOSDs().get(1)); // complete replica + // + // ArrayList requestedObjects = new ArrayList(); + // + // try { + // NextRequest next; + // for (int i = 0; i < objectsToRequest.length; i++) { + // this.strategy.selectNext(); + // next = this.strategy.getNext(); + // requestedObjects.add(Long.valueOf(next.objectNo)); + // boolean contained = false; + // for (org.xtreemfs.common.xloc.Replica r : xLoc.getReplicas()) { + // if (r.getOSDs().contains(next.osd)) + // contained = true; + // } + // assertTrue(contained); + // } + // + // // for (int i = 0; i < objectsToRequest.length; i++) + // // assertTrue(requestedObjects.contains(objectsToRequest.get(i))); + // + // // no more requests possible + // this.strategy.selectNext(); + // next = this.strategy.getNext(); + // assertNull(next); + // } catch (TransferStrategyException e) { + // fail(e.getLocalizedMessage()); + // } + // } + + private ObjectSet fillObjectSet(long... objects) { + ObjectSet set = new ObjectSet(objects.length); + for (long object : objects) + set.add(object); + return set; + } +} diff --git a/java/servers/test/org/xtreemfs/test/osd/rwre/FixWrongMasterEpochDirectoryTest.java b/java/servers/test/org/xtreemfs/test/osd/rwre/FixWrongMasterEpochDirectoryTest.java new file mode 100644 index 0000000..96bf9e2 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/rwre/FixWrongMasterEpochDirectoryTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013 Michael Berlin, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.test.osd.rwre; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.osd.storage.HashStorageLayout; +import org.xtreemfs.osd.storage.MetadataCache; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestHelper; + +public class FixWrongMasterEpochDirectoryTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + } + + @Test + public void testAutomaticMoveToCorrectDirectory() throws IOException { + final String globalFileId = "f32b0854-91eb-44d8-adf8-65bb8baf5f60:13193"; + final String correctedFileId = globalFileId; + final String brokenFileId = "/" + correctedFileId; + final HashStorageLayout hsl = new HashStorageLayout(SetupUtils.createOSD1Config(), new MetadataCache()); + + // Cleanup previous runs. + hsl.deleteFile(brokenFileId, true); + hsl.deleteFile(correctedFileId, true); + + final File brokenFileDir = new File(hsl.generateAbsoluteFilePath(brokenFileId)); + final File correctedFileDir = new File(hsl.generateAbsoluteFilePath(correctedFileId)); + + // Set masterepoch using the wrong id. + assertFalse(brokenFileDir.isDirectory()); + assertFalse(correctedFileDir.isDirectory()); + hsl.setMasterEpoch(brokenFileId, 1); + assertTrue(brokenFileDir.isDirectory()); + + // Get the masterepoch with the correct id. + assertEquals(1, hsl.getMasterEpoch(correctedFileId)); + assertFalse(brokenFileDir.isDirectory()); + assertTrue(correctedFileDir.isDirectory()); + + // Get the masterepoch of a file which does not exist. + assertEquals(0, hsl.getMasterEpoch("fileIdDoesNotExist")); + } + +} diff --git a/java/servers/test/org/xtreemfs/test/osd/rwre/RWQuorumReplicationTest.java b/java/servers/test/org/xtreemfs/test/osd/rwre/RWQuorumReplicationTest.java new file mode 100644 index 0000000..b3b821b --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/rwre/RWQuorumReplicationTest.java @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd.rwre; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.net.InetSocketAddress; +import java.util.LinkedList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class RWQuorumReplicationTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private OSD[] osds; + private OSDConfig[] configs; + private TestEnvironment testEnv; + + private final static int NUM_OSDS = 3; + private static final String fileId = "ABCDEF:1"; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + // startup: DIR + testEnv = new TestEnvironment( + new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.OSD_CLIENT, TestEnvironment.Services.MRC, + TestEnvironment.Services.MRC_CLIENT }); + testEnv.start(); + + osds = new OSD[NUM_OSDS]; + configs = SetupUtils.createMultipleOSDConfigs(NUM_OSDS); + for (int i = 0; i < osds.length; i++) { + osds[i] = new OSD(configs[i]); + } + + } + + @After + public void tearDown() { + if (osds != null) { + for (OSD osd : this.osds) { + if (osd != null) + osd.shutdown(); + } + } + + testEnv.shutdown(); + } + + @Test + public void testReplicatedWrite() throws Exception { + Capability cap = new Capability(fileId, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 60, System.currentTimeMillis() + 10000, "", 0, + false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, configs[0].getCapabilitySecret()); + List rlist = new LinkedList(); + for (OSDConfig osd : this.configs) { + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 128)) + .setReplicationFlags(0).addOsdUuids(osd.getUUID().toString()).build(); + rlist.add(r); + } + + UUIDResolver.addTestMapping("yaggablurp", "testposd.xtreemfs.com", 32640, false); + + // add a non-existent OSD + Replica replica = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 128)) + .setReplicationFlags(0).addOsdUuids("yaggablurp").build(); + rlist.add(replica); + + XLocSet locSet = XLocSet.newBuilder().setReadOnlyFileSize(0) + .setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ).setVersion(1).addAllReplicas(rlist) + .build(); + // set the first replica as current replica + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(locSet).build(); + + final OSDServiceClient client = testEnv.getOSDClient(); + + final InetSocketAddress osd1 = new InetSocketAddress("localhost", configs[0].getPort()); + + final InetSocketAddress osd2 = new InetSocketAddress("localhost", configs[1].getPort()); + + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + ReusableBuffer rb = BufferPool.allocate(1024); + rb.put("YaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYagga".getBytes()); + rb.limit(rb.capacity()); + rb.position(0); + + RPCResponse r = client.write(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 0, 0, 0, 0, objdata, rb); + try { + r.get(); + } catch (Exception ex) { + ex.printStackTrace(); + throw ex; + } + // System.out.println("got response"); + r.freeBuffers(); + + ReusableBuffer data = BufferPool.allocate(1024 * 8); + r = client.write(osd2, RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileId, 0, 0, 0, 0, + objdata, data); + try { + r.get(); + fail("expected redirect"); + } catch (PBRPCException ex) { + if (ex.getErrorType() != ErrorType.REDIRECT) + fail("expected redirect"); + // System.out.println("got response: "+ex); + } + r.freeBuffers(); + + rb = BufferPool.allocate(1024); + rb.put("MoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeep".getBytes()); + rb.limit(rb.capacity()); + rb.position(0); + + r = client.write(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileId, 0, 0, 1024, 0, + objdata, rb); + r.get(); + // System.out.println("got response"); + r.freeBuffers(); + + // read from slave + // System.out.println("//// START READ ////"); + RPCResponse r2 = client.read(osd2, RPCAuthentication.authNone, RPCAuthentication.userService, fc, + fileId, 0, -1, 0, 2048); + try { + r2.get(); + fail("expected redirect"); + } catch (PBRPCException ex) { + if (ex.getErrorType() != ErrorType.REDIRECT) + fail("expected redirect"); + // System.out.println("got response: "+ex); + } + r2.freeBuffers(); + + r2 = client.read(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileId, 0, -1, 0, 2048); + ObjectData od = r2.get(); + rb = r2.getData(); + assertEquals(rb.get(0), (byte) 'Y'); + assertEquals(rb.get(1), (byte) 'a'); + r2.freeBuffers(); + + XCap newCap = fc.getXcap().toBuilder().setTruncateEpoch(1).build(); + fc = fc.toBuilder().setXcap(newCap).build(); + + RPCResponse r3 = client.truncate(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileId, + 128 * 1024 * 2); + r3.get(); + r3.freeBuffers(); + } + + @Test + public void testTwoReplicas() throws Exception { + Capability cap = new Capability(fileId, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 60, System.currentTimeMillis() + 10000, "", 0, + false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, configs[0].getCapabilitySecret()); + List rlist = new LinkedList(); + for (OSDConfig osd : this.configs) { + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 128)) + .setReplicationFlags(0).addOsdUuids(osd.getUUID().toString()).build(); + rlist.add(r); + } + + XLocSet locSet = XLocSet.newBuilder().setReadOnlyFileSize(0) + .setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ).setVersion(1).addAllReplicas(rlist) + .build(); + // set the first replica as current replica + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(locSet).build(); + + final OSDServiceClient client = testEnv.getOSDClient(); + + final InetSocketAddress osd1 = new InetSocketAddress("localhost", configs[0].getPort()); + + final InetSocketAddress osd2 = new InetSocketAddress("localhost", configs[1].getPort()); + + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + ReusableBuffer rb = BufferPool.allocate(1024); + rb.put("YaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYagga".getBytes()); + rb.limit(rb.capacity()); + rb.position(0); + + RPCResponse r = client.write(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 0, 0, 0, 0, objdata, rb); + try { + r.get(); + } catch (Exception ex) { + ex.printStackTrace(); + throw ex; + } + // System.out.println("got response"); + r.freeBuffers(); + + ReusableBuffer data = BufferPool.allocate(1024 * 8); + r = client.write(osd2, RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileId, 0, 0, 0, 0, + objdata, data); + try { + r.get(); + fail("expected redirect"); + } catch (PBRPCException ex) { + if (ex.getErrorType() != ErrorType.REDIRECT) + fail("expected redirect"); + // System.out.println("got response: "+ex); + } + r.freeBuffers(); + + rb = BufferPool.allocate(1024); + rb.put("MoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeep".getBytes()); + rb.limit(rb.capacity()); + rb.position(0); + + r = client.write(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileId, 0, 0, 1024, 0, + objdata, rb); + r.get(); + // System.out.println("got response"); + r.freeBuffers(); + + // read from slave + // System.out.println("//// START READ ////"); + RPCResponse r2 = client.read(osd2, RPCAuthentication.authNone, RPCAuthentication.userService, fc, + fileId, 0, -1, 0, 2048); + try { + r2.get(); + fail("expected redirect"); + } catch (PBRPCException ex) { + if (ex.getErrorType() != ErrorType.REDIRECT) + fail("expected redirect"); + // System.out.println("got response: "+ex); + } + r2.freeBuffers(); + + r2 = client.read(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileId, 0, -1, 0, 2048); + ObjectData od = r2.get(); + rb = r2.getData(); + assertEquals(rb.get(0), (byte) 'Y'); + assertEquals(rb.get(1), (byte) 'a'); + r2.freeBuffers(); + + XCap newCap = fc.getXcap().toBuilder().setTruncateEpoch(1).build(); + fc = fc.toBuilder().setXcap(newCap).build(); + + RPCResponse r3 = client.truncate(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, fc, fileId, + 128 * 1024 * 2); + r3.get(); + r3.freeBuffers(); + } + +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/test/osd/rwre/RWReplicationFailureTest.java b/java/servers/test/org/xtreemfs/test/osd/rwre/RWReplicationFailureTest.java new file mode 100644 index 0000000..03f9758 --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/rwre/RWReplicationFailureTest.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd.rwre; + +import static org.junit.Assert.fail; + +import java.net.InetSocketAddress; +import java.util.LinkedList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.uuids.UUIDResolver; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class RWReplicationFailureTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private OSD[] osds; + private OSDConfig[] configs; + private TestEnvironment testEnv; + + private final static int NUM_OSDS = 2; + private static final String fileId = "ABCDEF:1"; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + // startup: DIR + testEnv = new TestEnvironment( + new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.OSD_CLIENT, TestEnvironment.Services.MRC, + TestEnvironment.Services.MRC_CLIENT }); + testEnv.start(); + + osds = new OSD[NUM_OSDS]; + configs = SetupUtils.createMultipleOSDConfigs(NUM_OSDS); + configs[1].setCapabilitySecret("somenonsense347534593475"); + for (int i = 0; i < osds.length; i++) { + osds[i] = new OSD(configs[i]); + } + + } + + @After + public void tearDown() { + if (osds != null) { + for (OSD osd : this.osds) { + if (osd != null) + osd.shutdown(); + } + } + + testEnv.shutdown(); + } + + + @Test + public void testInvalidCap() throws Exception { + Capability cap = new Capability(fileId, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 60, System.currentTimeMillis() + 10000, "", 0, + false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, configs[0].getCapabilitySecret()); + List rlist = new LinkedList(); + for (OSDConfig osd : this.configs) { + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 128)) + .setReplicationFlags(0).addOsdUuids(osd.getUUID().toString()).build(); + rlist.add(r); + } + + XLocSet locSet = XLocSet.newBuilder().setReadOnlyFileSize(0) + .setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE).setVersion(1) + .addAllReplicas(rlist).build(); + // set the first replica as current replica + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(locSet).build(); + + final OSDServiceClient client = testEnv.getOSDClient(); + + final InetSocketAddress osd1 = new InetSocketAddress("localhost", configs[0].getPort()); + + final InetSocketAddress osd2 = new InetSocketAddress("localhost", configs[1].getPort()); + + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + ReusableBuffer rb = BufferPool.allocate(1024); + rb.put("YaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYagga".getBytes()); + rb.limit(rb.capacity()); + rb.position(0); + + RPCResponse r = client.write(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 0, 0, 0, 0, objdata, rb); + try { + r.get(); + fail("write should have failed"); + } catch (Exception ex) { + // System.out.println("write failed as expected: "+ex); + } + r.freeBuffers(); + + } + + @Test + public void testOfflineOSD() throws Exception { + Capability cap = new Capability(fileId, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 60, System.currentTimeMillis() + 10000, "", 0, + false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, configs[0].getCapabilitySecret()); + List rlist = new LinkedList(); + for (OSDConfig osd : this.configs) { + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 128)) + .setReplicationFlags(0).addOsdUuids(osd.getUUID().toString()).build(); + rlist.add(r); + } + + Replica replica = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 128)) + .setReplicationFlags(0).addOsdUuids("yaggablurp").build(); + rlist.add(replica); + + XLocSet locSet = XLocSet.newBuilder().setReadOnlyFileSize(0) + .setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE).setVersion(1) + .addAllReplicas(rlist).build(); + // set the first replica as current replica + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(locSet).build(); + + UUIDResolver.addTestMapping("yaggaBluuurp", "www.xtreemfs.org", 32640, false); + + + final OSDServiceClient client = testEnv.getOSDClient(); + + final InetSocketAddress osd1 = new InetSocketAddress("localhost", configs[0].getPort()); + + final InetSocketAddress osd2 = new InetSocketAddress("localhost", configs[1].getPort()); + + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false) + .build(); + ReusableBuffer rb = BufferPool.allocate(1024); + rb.put("YaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYagga".getBytes()); + rb.limit(rb.capacity()); + rb.position(0); + + RPCResponse r = client.write(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 0, 0, 0, 0, objdata, rb); + try { + r.get(); + fail("write should have failed"); + } catch (Exception ex) { + // System.out.println("write failed as expected: "+ex); + } + r.freeBuffers(); + + } + +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/test/osd/rwre/RWReplicationTest.java b/java/servers/test/org/xtreemfs/test/osd/rwre/RWReplicationTest.java new file mode 100644 index 0000000..314579e --- /dev/null +++ b/java/servers/test/org/xtreemfs/test/osd/rwre/RWReplicationTest.java @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2010-2011 by Bjoern Kolbeck, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ + +package org.xtreemfs.test.osd.rwre; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.net.InetSocketAddress; +import java.util.LinkedList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.common.Capability; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.clients.Client; +import org.xtreemfs.common.clients.File; +import org.xtreemfs.common.clients.RandomAccessFile; +import org.xtreemfs.common.clients.Volume; +import org.xtreemfs.foundation.buffer.BufferPool; +import org.xtreemfs.foundation.buffer.ReusableBuffer; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.PBRPCException; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.client.RPCResponse; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthPassword; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.AuthType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.osd.OSD; +import org.xtreemfs.osd.OSDConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.AccessControlPolicyType; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.FileCredentials; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.Replica; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SnapConfig; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XCap; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.XLocSet; +import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; +import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; + +/** + * + * @author bjko + */ +public class RWReplicationTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private OSD[] osds; + private OSDConfig[] configs; + private TestEnvironment testEnv; + + private final static int NUM_OSDS = 3; + private static final String fileId = "ABCDEF:1"; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); + } + + @Before + public void setUp() throws Exception { + + java.io.File testDir = new java.io.File(SetupUtils.TEST_DIR); + + FSUtils.delTree(testDir); + testDir.mkdirs(); + + // startup: DIR + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.OSD_CLIENT, TestEnvironment.Services.MRC, + TestEnvironment.Services.MRC_CLIENT}); + testEnv.start(); + + osds = new OSD[NUM_OSDS]; + configs = SetupUtils.createMultipleOSDConfigs(NUM_OSDS); + for (int i = 0; i < osds.length; i++) { + osds[i] = new OSD(configs[i]); + } + + } + + + @After + public void tearDown() { + if (osds != null) { + for (OSD osd : this.osds) { + if (osd != null) + osd.shutdown(); + } + } + + testEnv.shutdown(); + } + + + @Test + public void testReplicationWithClient() throws Exception { + UserCredentials uc = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); + Auth passwd = passwd = Auth.newBuilder().setAuthType(AuthType.AUTH_PASSWORD).setAuthPasswd(AuthPassword.newBuilder().setPassword("")).build(); + + Client c = new Client(new InetSocketAddress[]{testEnv.getDIRAddress()}, 15000, 60000, null); + c.start(); + c.createVolume("testVol", passwd, uc, SetupUtils.getStripingPolicy(1, 128), AccessControlPolicyType.ACCESS_CONTROL_POLICY_POSIX, 0777); + + Volume v = c.getVolume("testVol", uc); + File f = v.getFile("test.file"); + f.createFile(); + f.setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE); + String[] suitableOSDs = f.getSuitableOSDs(1); + assertTrue("suitableOSDs.length >= 1", suitableOSDs.length >= 1); + f.addReplica(1, suitableOSDs, 0); + + byte[] data = new byte[2048]; + + // System.out.println("open file with replicas"); + RandomAccessFile raf = f.open("rw", 0444); + raf.write(data, 0, data.length); + + raf.seek(1024); + raf.forceReplica(1); + + raf.read(data, 0, data.length); + + raf.close(); + + c.stop(); + } + + @Test + public void testReplicatedWrite() throws Exception { + Capability cap = new Capability(fileId, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 60, System.currentTimeMillis(), "", 0, false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, configs[0].getCapabilitySecret()); + List rlist = new LinkedList(); + for (OSDConfig osd : this.configs) { + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 128)).setReplicationFlags(0).addOsdUuids(osd.getUUID().toString()).build(); + rlist.add(r); + } + + XLocSet locSet = XLocSet.newBuilder().setReadOnlyFileSize(0).setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ).setVersion(1).addAllReplicas(rlist).build(); + // set the first replica as current replica + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(locSet).build(); + + final OSDServiceClient client = testEnv.getOSDClient(); + + final InetSocketAddress osd1 = new InetSocketAddress("localhost",configs[0].getPort()); + + final InetSocketAddress osd2 = new InetSocketAddress("localhost",configs[1].getPort()); + + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false).build(); + ReusableBuffer rb = BufferPool.allocate(1024); + rb.put("YaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYagga".getBytes()); + rb.limit(rb.capacity()); + rb.position(0); + + RPCResponse r = client.write(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 0, 0, 0, 0, objdata, rb); + r.get(); + // System.out.println("got response"); + r.freeBuffers(); + + r = client.write(osd2, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 0, 0, 0, 0, objdata, BufferPool.allocate(1024*8)); + try { + r.get(); + fail("expected redirect"); + } catch (PBRPCException ex) { + if (ex.getErrorType() != ErrorType.REDIRECT) + fail("expected redirect"); + // System.out.println("got response: "+ex); + } + r.freeBuffers(); + + rb = BufferPool.allocate(1024); + rb.put("MoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeepMoeep".getBytes()); + rb.limit(rb.capacity()); + rb.position(0); + + r = client.write(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 0, 0, 1024, 0, objdata, rb); + r.get(); + // System.out.println("got response"); + r.freeBuffers(); + + //read from slave + // System.out.println("//// START READ ////"); + RPCResponse r2 = client.read(osd2, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 0, -1, 0, 2048); + try { + r2.get(); + fail("expected redirect"); + } catch (PBRPCException ex) { + if (ex.getErrorType() != ErrorType.REDIRECT) + fail("expected redirect"); + // System.out.println("got response: "+ex); + } + r2.freeBuffers(); + + + r2 = client.read(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 0, -1, 0, 2048); + ObjectData od = r2.get(); + + assertEquals(r2.getData().get(0),(byte)'Y'); + assertEquals(r2.getData().get(1),(byte)'a'); + r2.freeBuffers(); + + XCap newCap = fc.getXcap().toBuilder().setTruncateEpoch(1).build(); + fc = fc.toBuilder().setXcap(newCap).build(); + + RPCResponse r3 = client.truncate(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 128*1024*2); + r3.get(); + r3.freeBuffers(); + + } + + + @Test + public void testReset() throws Exception { + Capability cap = new Capability(fileId, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 60, System.currentTimeMillis(), "", 0, false, SnapConfig.SNAP_CONFIG_SNAPS_DISABLED, 0, configs[0].getCapabilitySecret()); + List rlist = new LinkedList(); + for (OSDConfig osd : this.configs) { + Replica r = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 128)).setReplicationFlags(0).addOsdUuids(osd.getUUID().toString()).build(); + rlist.add(r); + } + + XLocSet locSet = XLocSet.newBuilder().setReadOnlyFileSize(0).setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ).setVersion(1).addAllReplicas(rlist).build(); + // set the first replica as current replica + FileCredentials fc = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(locSet).build(); + + + Replica repl = Replica.newBuilder().setStripingPolicy(SetupUtils.getStripingPolicy(1, 128)).setReplicationFlags(0).addOsdUuids(configs[0].getUUID().toString()).build(); + + XLocSet oneLocSet = XLocSet.newBuilder().setReadOnlyFileSize(0).setReplicaUpdatePolicy(ReplicaUpdatePolicies.REPL_UPDATE_PC_NONE).setVersion(1).addReplicas(repl).build(); + //new XLocSet(0, oneRset, Constants.REPL_UPDATE_PC_NONE, 1); + // set the first replica as current replica + FileCredentials oneFC = FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(oneLocSet).build(); + + + final OSDServiceClient client = testEnv.getOSDClient(); + + final InetSocketAddress osd1 = new InetSocketAddress("localhost",configs[0].getPort()); + + final InetSocketAddress osd2 = new InetSocketAddress("localhost",configs[1].getPort()); + + ObjectData objdata = ObjectData.newBuilder().setChecksum(0).setZeroPadding(0).setInvalidChecksumOnOsd(false).build(); + ReusableBuffer rb = BufferPool.allocate(1024); + rb.put("YaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYagga".getBytes()); + rb.limit(rb.capacity()); + rb.position(0); + + RPCResponse r = client.write(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, + oneFC, fileId, 0, 0, 0, 0, objdata, rb); + r.get(); + // System.out.println("got response"); + r.freeBuffers(); + + rb = BufferPool.allocate(1024); + rb.put("YaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYaggaYagga".getBytes()); + rb.limit(rb.capacity()); + rb.position(0); + + r = client.write(osd1, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 1, 0, 0, 0, objdata, rb); + r.get(); + // System.out.println("got response"); + r.freeBuffers(); + + // System.out.println("waiting..."); + Thread.sleep(90*1000); + // System.out.println("continue...\n\n"); + + r = client.write(osd2, RPCAuthentication.authNone, RPCAuthentication.userService, + fc, fileId, 0, 0, 0, 0, objdata, BufferPool.allocate(1024*8)); + r.get(); + // System.out.println("got response"); + r.freeBuffers(); + } +} \ No newline at end of file diff --git a/java/servers/test/org/xtreemfs/utils/ScrubberTest.java b/java/servers/test/org/xtreemfs/utils/ScrubberTest.java new file mode 100644 index 0000000..ba38255 --- /dev/null +++ b/java/servers/test/org/xtreemfs/utils/ScrubberTest.java @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2012-2013 by Lukas Kairies, Zuse Institute Berlin + * + * Licensed under the BSD License, see LICENSE file for details. + * + */ +package org.xtreemfs.utils; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.FileWriter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.net.InetSocketAddress; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.xtreemfs.babudb.config.BabuDBConfig; +import org.xtreemfs.common.ReplicaUpdatePolicies; +import org.xtreemfs.common.libxtreemfs.AdminClient; +import org.xtreemfs.common.libxtreemfs.AdminFileHandle; +import org.xtreemfs.common.libxtreemfs.AdminVolume; +import org.xtreemfs.common.libxtreemfs.ClientFactory; +import org.xtreemfs.common.libxtreemfs.Helper; +import org.xtreemfs.common.libxtreemfs.Options; +import org.xtreemfs.common.xloc.ReplicationFlags; +import org.xtreemfs.foundation.logging.Logging; +import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; +import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; +import org.xtreemfs.foundation.util.FSUtils; +import org.xtreemfs.mrc.MRCConfig; +import org.xtreemfs.osd.storage.HashStorageLayout; +import org.xtreemfs.osd.storage.MetadataCache; +import org.xtreemfs.pbrpc.generatedinterfaces.DIR.ServiceStatus; +import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.DirectoryEntries; +import org.xtreemfs.pbrpc.generatedinterfaces.MRC.Stat; +import org.xtreemfs.test.SetupUtils; +import org.xtreemfs.test.TestEnvironment; +import org.xtreemfs.test.TestHelper; +import org.xtreemfs.utils.xtfs_scrub.xtfs_scrub; + +public class ScrubberTest { + @Rule + public final TestRule testLog = TestHelper.testLog; + + private static MRCConfig mrcCfg1; + + private static BabuDBConfig mrcDBCfg1; + + private static InetSocketAddress mrc1Address; + + private static InetSocketAddress dirAddress; + + private static int accessMode; + + private static TestEnvironment testEnv; + + private static AdminClient client; + + private static byte[] content; + + private static final UserCredentials userCredentials = xtfs_scrub.credentials; + + @BeforeClass + public static void initializeTest() throws Exception { + Logging.start(Logging.LEVEL_WARN); + + accessMode = 0777; // rwxrwxrwx + + dirAddress = SetupUtils.getDIRAddr(); + + mrcCfg1 = SetupUtils.createMRC1Config(); + mrcDBCfg1 = SetupUtils.createMRC1dbsConfig(); + mrc1Address = SetupUtils.getMRC1Addr(); + + // cleanup + File testDir = new File(SetupUtils.TEST_DIR); + + FSUtils.delTree(testDir); + testDir.mkdirs(); + SetupUtils.CHECKSUMS_ON = true; + // startup test environment + testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_SERVICE, + TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.UUID_RESOLVER, + TestEnvironment.Services.MRC_CLIENT, TestEnvironment.Services.OSD_CLIENT, TestEnvironment.Services.MRC, + TestEnvironment.Services.OSD, + TestEnvironment.Services.OSD, TestEnvironment.Services.OSD, TestEnvironment.Services.OSD }); + testEnv.start(); + SetupUtils.CHECKSUMS_ON = false; + // create client + client = ClientFactory.createAdminClient(dirAddress.getHostName() + ":" + dirAddress.getPort(), + userCredentials, null, new Options()); + client.start(); + + // create content + String tmp = ""; + for (int i = 0; i < 12000; i++) { + tmp = tmp.concat("Hello World "); + } + content = tmp.getBytes(); + } + + @AfterClass + public static void shutdownTest() throws Exception { + client.shutdown(); + testEnv.shutdown(); + } + + @Test + public void testNonReplicatedFileOnDeadOSD() throws Exception { + final String VOLUME_NAME = "testNonReplicatedFileOnDeadOSD"; + final String FILE_NAME = "myDir/test0.txt"; + + // create Volume + client.createVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + AdminVolume volume = client.openVolume(VOLUME_NAME, null, new Options()); + volume.start(); + + // create dir and file + volume.createDirectory(userCredentials, "myDir", accessMode); + AdminFileHandle file = volume.openFile( + userCredentials, + FILE_NAME, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), accessMode); + + // write file + file.write(userCredentials, content, content.length, 0); + file.close(); + + DirectoryEntries de = volume.readDir(userCredentials, "/myDir/", 0, 2, true); + assertEquals(3, de.getEntriesCount()); + + // mark OSD as removed + client.setOSDServiceStatus(file.getReplica(0).getOsdUuids(0), ServiceStatus.SERVICE_STATUS_REMOVED); + + // scrub volume + xtfs_scrub scrubber = new xtfs_scrub(client, volume, 3, true, true, true); + scrubber.scrub(); + + // file should be removed + de = volume.readDir(userCredentials, "/myDir/", 0, 2, true); + assertEquals(2, de.getEntriesCount()); + + // delete volume + client.deleteVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + + // mark OSD as available + client.setOSDServiceStatus(file.getReplica(0).getOsdUuids(0), ServiceStatus.SERVICE_STATUS_AVAIL); + } + + @Test + public void testNonReplicatedFileWithWrongChecksum() throws Exception { + final String VOLUME_NAME = "testNonReplicatedFileWithWrongChecksum"; + final String FILE_NAME = "test0.txt"; + + // create Volume + client.createVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + AdminVolume volume = client.openVolume(VOLUME_NAME, null, new Options()); + volume.start(); + + // create file + AdminFileHandle file = volume.openFile( + userCredentials, + FILE_NAME, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), accessMode); + + // write file + file.write(userCredentials, content, file.getStripingPolicy().getStripeSize() * 1024 - 20, 0); + + // modify first Object on OSD + + File objFile = openObjectFile(file, 0, 0); + FileWriter fw = new FileWriter(objFile, false); + + fw.write("foofoofoofoofoo"); + fw.close(); + + // scrub volume + xtfs_scrub scrubber = new xtfs_scrub(client, volume, 3, true, true, true); + scrubber.scrub(); + + file.close(); + + // delete volume + client.deleteVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + } + + @Test + public void testNonReplicatedFileWithWrongFileSizeOnMrc() throws Exception { + final String VOLUME_NAME = "testNonReplicatedFileWithWrongFileSizeOnMrc"; + final String FILE_NAME = "test0.txt"; + + // create Volume + client.createVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + AdminVolume volume = client.openVolume(VOLUME_NAME, null, new Options()); + volume.start(); + + // create file + AdminFileHandle file = volume.openFile( + userCredentials, + FILE_NAME, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), accessMode); + + // write file + file.write(userCredentials, content, content.length, 0); + + Stat stat = file.getAttr(userCredentials); + assertEquals(content.length, stat.getSize()); + + // truncate file on MRC + file.truncate(userCredentials, 10, true); + + stat = file.getAttr(userCredentials); + assertEquals(10, stat.getSize()); + + // scrub volume + xtfs_scrub scrubber = new xtfs_scrub(client, volume, 3, true, true, true); + scrubber.scrub(); + + // file size should be correct from 10 to content.length + stat = file.getAttr(userCredentials); + assertEquals(content.length, stat.getSize()); + + file.close(); + + // delete volume + client.deleteVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + } + + @Test + public void testROnlyReplicatedFileWithLostReplica() throws Exception { + final String VOLUME_NAME = "testROnlyReplicatedFileWithLostReplica"; + final String FILE_NAME = "test0.txt"; + + // create Volume + client.createVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + AdminVolume volume = client.openVolume(VOLUME_NAME, null, new Options()); + volume.start(); + + // set replica update Policy + int replicationFlags = ReplicationFlags.setRarestFirstStrategy(0); + replicationFlags = ReplicationFlags.setFullReplica(replicationFlags); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY, 3, + replicationFlags); + + // create file + AdminFileHandle file = volume.openFile( + userCredentials, + FILE_NAME, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), accessMode); + + // write file + file.write(userCredentials, content, content.length, 0); + + // re-open file to trigger replication + file.close(); + file = volume.openFile(userCredentials, FILE_NAME, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + + // wait for replication + Thread.sleep(5000); + + // mark OSD of the second replica as removed + client.setOSDServiceStatus(file.getReplica(1).getOsdUuids(0), ServiceStatus.SERVICE_STATUS_REMOVED); + + // scrub volume + xtfs_scrub scrubber = new xtfs_scrub(client, volume, 3, true, true, true); + scrubber.scrub(); + + // re-open file + file.close(); + file = volume.openFile(userCredentials, FILE_NAME, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + + // file has still three replicas + assertEquals(3, file.getReplicasList().size()); + + file.close(); + + // delete volume + client.deleteVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + + client.setOSDServiceStatus(file.getReplica(1).getOsdUuids(0), ServiceStatus.SERVICE_STATUS_AVAIL); + } + + @Test + public void testROnlyReplicatedFileWithWrongChecksum() throws Exception { + final String VOLUME_NAME = "testROnlyReplicatedFileWithWrongChecksum"; + final String FILE_NAME = "test0.txt"; + + // create Volume + client.createVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + AdminVolume volume = client.openVolume(VOLUME_NAME, null, new Options()); + volume.start(); + + // set replica update Policy + int replicationFlags = ReplicationFlags.setRarestFirstStrategy(0); + replicationFlags = ReplicationFlags.setFullReplica(replicationFlags); + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_RONLY, 3, + replicationFlags); + + // create file + AdminFileHandle file = volume.openFile( + userCredentials, + FILE_NAME, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), accessMode); + + // write file + int contentSize = file.getStripingPolicy().getStripeSize() * 1024; + file.write(userCredentials, content, contentSize, 0); + + // re-open file to trigger replication + file.close(); + file = volume.openFile(userCredentials, FILE_NAME, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDONLY.getNumber()); + + // wait for replication + Thread.sleep(5000); + + // modify first Object of the second replica on OSD + File objFile = openObjectFile(file, 1, 0); + FileWriter fw = new FileWriter(objFile, false); + + fw.write("foofoofoofoofoo"); + fw.close(); + + // scrub volume + xtfs_scrub scrubber = new xtfs_scrub(client, volume, 3, true, true, true); + scrubber.scrub(); + + //object file should be as long as the originally written content + Thread.sleep(5000); + objFile = openObjectFile(file, 1, 0); + assertEquals(contentSize, objFile.length()); + + // delete volume + file.close(); + client.deleteVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + } + + //@Test + public void testRWReplicatedFileWithLostReplica() throws Exception { + final String VOLUME_NAME = "testRWReplicatedFileWithLostReplica"; + final String FILE_NAME = "test0.txt"; + + // create Volume + client.createVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), RPCAuthentication.authNone, + userCredentials, VOLUME_NAME); + AdminVolume volume = client.openVolume(VOLUME_NAME, null, new Options()); + volume.start(); + + // set replica update Policy + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ, + 3, 0); + + // create file + AdminFileHandle file = volume.openFile( + userCredentials, + FILE_NAME, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), accessMode); + + // write file + file.write(userCredentials, content, content.length, 0); + + // mark OSD of the second replica as removed + client.setOSDServiceStatus(file.getReplica(1).getOsdUuids(0), ServiceStatus.SERVICE_STATUS_REMOVED); + + // scrub volume + xtfs_scrub scrubber = new xtfs_scrub(client, volume, 3, true, true, true); + scrubber.scrub(); + + // re-open file + file.close(); + file = volume.openFile(userCredentials, FILE_NAME, SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber()); + + // file has still three replicas + assertEquals(3, file.getReplicasList().size()); + + file.close(); + + // delete volume + client.deleteVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + + client.setOSDServiceStatus(file.getReplica(1).getOsdUuids(0), ServiceStatus.SERVICE_STATUS_AVAIL); + } + + @Test + public void testRWReplicatedFileWithWrongChecksum() throws Exception { + final String VOLUME_NAME = "testRWReplicatedFileWithWrongChecksum"; + final String FILE_NAME = "test0.txt"; + + // create Volume + client.createVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + AdminVolume volume = client.openVolume(VOLUME_NAME, null, new Options()); + volume.start(); + + // set replica update Policy + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ, 3, 0); + + // create file + AdminFileHandle file = volume.openFile( + userCredentials, + FILE_NAME, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), accessMode); + + // write file + file.write(userCredentials, content, content.length, 0); + + // modify second Object + File objFile = openObjectFile(file, 0, 1); + FileWriter fw = new FileWriter(objFile, false); + + fw.write("foofoofoofoofoo"); + fw.close(); + + // scrub volume + xtfs_scrub scrubber = new xtfs_scrub(client, volume, 3, true, true, true); + scrubber.scrub(); + + file.close(); + + // delete volume + client.deleteVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + } + + @Test + public void testRWReplicatedFileWithWrongFileSizeOnMrc() throws Exception { + final String VOLUME_NAME = "testRWReplicatedFileWithWrongFileSizeOnMrc"; + final String FILE_NAME = "test0.txt"; + + // create Volume + client.createVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + AdminVolume volume = client.openVolume(VOLUME_NAME, null, new Options()); + volume.start(); + + // set replica update Policy + volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WQRQ, + 3, 0); + + // create file + AdminFileHandle file = volume.openFile( + userCredentials, + FILE_NAME, + SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() + | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), accessMode); + + // write file + file.write(userCredentials, content, content.length, 0); + + Stat s = file.getAttr(userCredentials); + assertEquals(content.length, s.getSize()); + + // truncate file on MRC + file.truncate(userCredentials, 10, true); + + s = file.getAttr(userCredentials); + assertEquals(10, s.getSize()); + + // scrub volume + xtfs_scrub scrubber = new xtfs_scrub(client, volume, 3, true, true, true); + scrubber.scrub(); + + // file size should be correct from 10 to content.length + s = file.getAttr(userCredentials); + assertEquals(content.length, s.getSize()); + + file.close(); + + // delete volume + client.deleteVolume(mrc1Address.getHostName() + ":" + mrc1Address.getPort(), + RPCAuthentication.authNone, userCredentials, VOLUME_NAME); + } + + private File openObjectFile(AdminFileHandle file, int replicaIndex, int objectIndex) throws IOException { + + String osdUUID = Helper.getOSDUUIDFromObjectNo(file.getReplica(replicaIndex), objectIndex); + HashStorageLayout hsl = new HashStorageLayout(testEnv.getOSDConfig(osdUUID), + new MetadataCache()); + String filePath = hsl.generateAbsoluteFilePath(file.getGlobalFileId()); + + File fileDir = new File(filePath); + File[] objFiles = fileDir.listFiles(new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + return !name.matches("\\..*"); + } + }); + return objFiles[objectIndex / file.getStripingPolicy(replicaIndex).getWidth()]; + } +} diff --git a/man/man1/lsfs.xtreemfs.1 b/man/man1/lsfs.xtreemfs.1 new file mode 100644 index 0000000..7a8142c --- /dev/null +++ b/man/man1/lsfs.xtreemfs.1 @@ -0,0 +1,68 @@ +.TH lsfs.xtreemfs 1 "July 2011" "The XtreemFS Distributed File System" "XtreemFS client" +.SH NAME +lsfs.xtreemfs - list all XtreemFS volumes on an MRC +.SH SYNOPSIS +\fBlsfs.xtreemfs [\fIoptions\fB] [pbrpc[g|s]://]\fImrc-host\fR[:\fIport\fR] +.br + +.SH DESCRIPTION +.I lsfs.xtreemfs +lists all volumes located on the XtreemFS MRC running at \fImrc-host\fR:\fIport\fR. + +.SH EXAMPLE USAGE +.TP +List all volumes of the MRC server "remote.mrc.machine": +.TP +.B "lsfs.xtreemfs remote.mrc.machine + +.SH OPTIONS + +.TP +Admin Password: +.TP +.BI "--admin_password " password +MRC's admin_password (not required if not set at the MRC). + +.TP +General Options: +.TP +.BI "-d, --log-level " EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG +The log level of the XtreemFS client. +.TP +.B "-h, --help" +Print help and exit. +.TP +.BI "-l, --log-file-path " log_file_path +Path to log file. +.TP +.BI "-V, --version" +Shows the version number. + +.TP +SSL Options: +.TP +.BI "--pem-certificate-file-path " certfile +Path to PEM certificate file (for SSL installations only). +.TP +.BI "--pem-private-key-file-path " file +Path to PEM private key file (for SSL installations only). +.TP +.BI "--pem-private-key-passphrase " pass +Passphrase for PEM private key file (for SSL installations only) +.TP +.BI "--pkcs12-file-path " file +Path to PKCS#12 file (for SSL installations only). +.TP +.BI "--pkcs12-passphrase " pass +Passphrase for PKCS#12 file (for SSL installations only). + +.SH "SEE ALSO" +.BR mkfs.xtreemfs (1), +.BR mount.xtreemfs (1), +.BR rmfs.xtreemfs (1), +.BR umount.xtreemfs (1), +.BR xtfsutil (1) +.BR + +.SH AVAILABILITY +The lsfs.xtreemfs command is part of the XtreemFS-client package and is available from \fIhttp://www.xtreemfs.org\fP. \ No newline at end of file diff --git a/man/man1/mkfs.xtreemfs.1 b/man/man1/mkfs.xtreemfs.1 new file mode 100644 index 0000000..14d398a --- /dev/null +++ b/man/man1/mkfs.xtreemfs.1 @@ -0,0 +1,145 @@ +.TH mkfs.xtreemfs 1 "July 2011" "The XtreemFS Distributed File System" "XtreemFS client" +.SH NAME +mkfs.xtreemfs - create a new XtreemFS volume +.SH SYNOPSIS +\fBmkfs.xtreemfs [\fIoptions\fB] [pbrpc[g|s]://]\fImrc-host\fR[:\fIport\fR]/\fIvolume +.br + +.SH DESCRIPTION +.I mkfs.xtreemfs +Creates a new volume named \fIvolume\fR at the MRC \fImrc-host\fR:\fIport\fR. + +.SH EXAMPLE USAGE +.TP +Create the volume "MyVolume" on the MRC server "remote.mrc.machine": +.TP +.B "mkfs.xtreemfs remote.mrc.machine/MyVolume" +.br +.TP +Create a volume with a default striping width of 2 meaning files will be always striped across 2 OSDs. +.TP +.B "mkfs.xtreemfs \-p RAID0 \-w 2 remote.mrc.machine/MyVolume" + +.SH OPTIONS + +.TP +Admin Password: +.TP +.BI "--admin_password " password +MRC's admin_password (not required if not set at the MRC). + +.TP +Volume Options: +.TP +.BI "-m, \--mode " mode +Mode of the volume's root directory (777 by default). +.TP +.BI "-u, \--owner-username " username +Owner of the new volume (by default it is the username of the effective user id). +.TP +.BI "-g, \--owner-groupname " groupname +Owning group of the new volume (by default its the groupname of the effective +group id). +.TP +.BI "-a, \--access-control-policy " NULL|POSIX|VOLUME +Access Control Policy of the volume. By default +.IR POSIX . + +.TP +Striping Policy Options: +.TP +.BI "-p, \--striping-policy " RAID0 +Default striping policy for new files. Currently only the policy +.I RAID0 +is available. Please do not get confused by the name +.IR RAID0 . +If the default +.I \--striping-policy-width +of 1 is used, all objects of a file are stored on the same OSD and there is no higher failure probability compared to storing files on other file systems. + +.TP +.BI "-s, \--striping-policy-stripe-size " stripe-size +Stripe size in kB. +.TP +.BI "-w, \--striping-policy-width " stripe-width +Number of OSDs (stripes) per replica. + +.TP +Volume Attributes: +.TP +.BI "--volume-attribute " name=value +Define volume specific attributes of the form +.IR name=value , +e.g. "chown_non_root=true". +.TP +.B "--chown-non-root" +Shortcut for \--volume-attribute chown_non_root=true. If this attribute is not set, regular users (everybody except root) are not allowed to change the ownership of their +.B own +files. + +.TP +General Options: +.TP +.BI "-d, \--log-level " EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG +The log level of the XtreemFS client. +.TP +.B "-h, \--help" +Print help and exit. +.TP +.BI "-l, \--log-file-path " log_file_path +Path to log file. +.TP +.BI "-V, \--version" +Shows the version number. + +.TP +SSL Options: +.TP +.BI "--pem-certificate-file-path " certfile +Path to PEM certificate file (for SSL installations only). +.TP +.BI "--pem-private-key-file-path " file +Path to PEM private key file (for SSL installations only). +.TP +.BI "--pem-private-key-passphrase " pass +Passphrase for PEM private key file (for SSL installations only) +.TP +.BI "--pkcs12-file-path " file +Path to PKCS#12 file (for SSL installations only). +.TP +.BI "--pkcs12-passphrase " pass +Passphrase for PKCS#12 file (for SSL installations only). + +.TP +Grid Support options: +.TP +.B "--grid-ssl " +Explicitily use the XtreemFS Grid-SSL mode. Same as specifying pbrpcg:// in the volume URL. +.TP +.B "--globus-gridmap" +Authorize using globus gridmap file. +.TP +.B "--unicore-gridmap" +Authorize using unicore gridmap file. +.TP +.BI "--gridmap-location " path +Location of the gridmap file. If this option is not set, the default path will be used, depending on the chosen gridmap file: +.RS +Unicore default: /etc/grid-security/d-grid_uudb +Globus default: /etc/grid-security/grid-mapfile +.RE +.TP +.BI "--gridmap-reload-interval-m " interval +Interval (in minutes) after which the gridmap file will be checked for changes and reloaded if necessary. 60 minutes by default. + +.SH "SEE ALSO" +.BR lsfs.xtreemfs (1), +.BR mount.xtreemfs (1), +.BR rmfs.xtreemfs (1), +.BR umount.xtreemfs (1), +.BR xtfsutil (1) +.BR + + +.SH AVAILABILITY +The mkfs.xtreemfs command is part of the XtreemFS-client package and is available from \fIhttp://www.xtreemfs.org\fP. \ No newline at end of file diff --git a/man/man1/mount.xtreemfs.1 b/man/man1/mount.xtreemfs.1 new file mode 100644 index 0000000..97ca93b --- /dev/null +++ b/man/man1/mount.xtreemfs.1 @@ -0,0 +1,189 @@ +.TH mount.xtreemfs 1 "July 2011" "The XtreemFS Distributed File System" "XtreemFS client" +.SH NAME +mount.xtreemfs \- mounts an XtreemFS volume +.SH SYNOPSIS +\fBmount.xtreemfs [\fIoptions\fB] [pbrpc[g|s]://]\fIdir-host\fR[:\fIport\fR]/\fIvolume mountpoint +.br + +.SH DESCRIPTION +.I mount.xtreemfs +mounts the volume \fIvolume\fR registered at the Directory Service \fIdir-host\fR:\fIport\fR to the local directory \fImountpoint\fR. \fImount.xtreemfs\fR is implemented as a FUSE user-level file system driver. + +.SH EXAMPLE USAGE +.TP +Mount the volume "MyVolume" (which is registered at the DIR server "remote.dirservice.machine") to the mount point "/mnt": +.TP +.B "mount.xtreemfs remote.dirservice.machine/MyVolume /mnt" + +.SH OPTIONS + +.TP +Fuse Options: +.TP +.B "-f, \--foreground" +Do not fork into background. +.TP +.BI "-o, \--fuse_option " option +Passes \-o=<\fIoption\fR> to Fuse. + +.TP +ACL and extended attributes Support: +.TP +.B "-o xtreemfs_acl" +Enable the correct evaluation of XtreemFS ACLs. (Note that you cannot use the system tools getfattr and setfattr; use +.BR xtfsutil (1) +instead to set and retrieve ACLs.) +.TP +.B "-o user_xattr" +Enable user defined extended attributes. + +.TP +General Options: +.TP +.BI "-d, \--log-level " EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG +The log level of the XtreemFS client. +.TP +.B "-h, \--help" +Print help and exit. +.TP +.BI "-l, \--log-file-path " log_file_path +Path to log file. +.TP +.BI "-V, \--version" +Shows the version number. + +.TP +Optimizations: +.TP +.BI "--metadata-cache-size " size +Number of entries which will be cached. (Set to 0 to disable the cache.) +.TP +.BI "--metadata-cache-ttl-s " ttl +Time to live after which cached entries will expire. +.TP +.BI "--enable-async-writes" +Enables asynchronous writes. +.TP +.BI "--async-writes-max-reqs " count +Maximum number of pending write requests per file. Asynchronous writes will block if this limit is reached first. +.TP +.BI "--readdir-chunk-size " size +Number of directory entries which will be fetched from the MRC per readdir request. Do not set this value too high - otherwise the MRC will spent too much time generating the response containing thousands of directory entries. In general, you should not have directories with multiple thousands of entries. If you stick to this, all directory entries are fetched with one request as long as this value is lower than the number of entries. + +.TP +Error Handling options: +.TP +.BI "--max-tries " attempts +Maximum number of +.I attempts +to send a request (0 means infinite). +.TP +.BI "--max-read-tries " attempts +Maximum number of +.I attempts +to send a +.I read +request (0 means infinite). +.TP +.BI "--max-write-tries " attempts +Maximum number of +.I attempts +to send a +.I write +request (0 means infinite). +.TP +.BI "--retry-delay " delay +Wait time after a request failed until next attempt (in seconds). +.TP +.BI "--connect-timeout " connection-timeout +Timeout after which a connection attempt will be retried (in seconds). +.TP +.BI "--request-timeout " timeout +Timeout after which a request will be retried (in seconds). +.TP +.BI "--linger-timeout " linger-time +Time after which idle connections will be closed (in seconds). + +.TP +SSL Options: +.TP +.BI "--pem-certificate-file-path " certfile +Path to PEM certificate file (for SSL installations only). +.TP +.BI "--pem-private-key-file-path " file +Path to PEM private key file (for SSL installations only). +.TP +.BI "--pem-private-key-passphrase " pass +Passphrase for PEM private key file (for SSL installations only). If the argument \fIpass\fR is set to "-", the user will be prompted for the passphrase. +.TP +.BI "--pkcs12-file-path " file +Path to PKCS#12 file (for SSL installations only). +.TP +.BI "--pkcs12-passphrase " pass +Passphrase for PKCS#12 file (for SSL installations only). If the argument \fIpass\fR is set to "-", the user will be prompted for the passphrase. + +.TP +Grid Support options: +.TP +.B "--grid-ssl " +Explicitily use the XtreemFS Grid-SSL mode. Same as specifying pbrpcg:// in the volume URL. +.TP +.B "--globus-gridmap" +Authorize using globus gridmap file. +.TP +.B "--unicore-gridmap" +Authorize using unicore gridmap file. +.TP +.BI "--gridmap-location " path +Location of the gridmap file. If this option is not set, the default path will be used, depending on the chosen gridmap file: +.RS +Unicore default: /etc/grid-security/d-grid_uudb +Globus default: /etc/grid-security/grid-mapfile +.RE +.TP +.BI "--gridmap-reload-interval-m " interval +Interval (in minutes) after which the gridmap file will be checked for changes and reloaded if necessary. 60 minutes by default. + +.TP +Vivaldi options: +.TP +.B "--vivaldi-enable" +Enables the vivaldi coordinate calculation for the client. +.TP +.B "--vivaldi-enable-dir-updates" +Enables sending the coordinates to the DIR after each recalculation. This is only needed to add the clients to the vivaldi visualization at the cost of some additional traffic between client and DIR. +.TP +.B "--vivaldi-filename " path +The file where the vivaldi coordinates should be saved after each recalculation. +.TP +.BI "--vivaldi-recalculation-interval " seconds +The interval between coordinate recalculations in seconds. Also see vivaldi-recalculation-epsilon. +.TP +.BI "--vivaldi-recalculation-epsilon " seconds +The recalculation interval will be randomly chosen from vivaldi-recalculation-inverval +/- vivaldi-recalculation-epsilon. +.TP +.BI "--vivaldi-max-iterations-before-updating " count +Number of coordinate recalculations before updating the list of OSDs. +.TP +.BI "--vivaldi-max-request-retries " retries +Maximal number of retries when requesting coordinates from another vivaldi node. + +.SH "SEE ALSO" +.BR lsfs.xtreemfs (1), +.BR mkfs.xtreemfs (1), +.BR rmfs.xtreemfs (1), +.BR umount.xtreemfs (1), +.BR xtfsutil (1) +.BR + +.SH "KNOWN ISSUES" +FUSE does not support mmap in connection with direct I/O. In order to get applications running on XtreemFS that rely on mmap, volumes have to be mounted without using the FUSE option +.BR "-o direct_io" . +However, this might lead to inconsistencies if different clients access a file concurrently, as requests might be serviced from the local page cache. + +If +.B "-o xtreemfs_acl" +or a gridmap file is used, the Fuse default permissions check will be disabled. In consequence, the Fuse Option "\-o default_permissions" will not be sent to Fuse. In these cases, the content of the metadata cache may be spoofed by users although they are not allowed to list the directory or retrieve the stat information of a file. + +.SH AVAILABILITY +The mount.xtreemfs command is part of the XtreemFS-client package and is available from \fIhttp://www.xtreemfs.org\fP. diff --git a/man/man1/rmfs.xtreemfs.1 b/man/man1/rmfs.xtreemfs.1 new file mode 100644 index 0000000..5a582d1 --- /dev/null +++ b/man/man1/rmfs.xtreemfs.1 @@ -0,0 +1,75 @@ +.TH rmfs.xtreemfs 1 "July 2011" "The XtreemFS Distributed File System" "XtreemFS client" +.SH NAME +rmfs.xtreemfs - delete a volume including all files on an XtreemFS MRC +.SH SYNOPSIS +\fBrmfs.xtreemfs [\fIoptions\fB] [pbrpc[g|s]://]\fImrc-host\fR[:\fIport\fR]/\fIvolume +.br + +.SH DESCRIPTION +.I rmfs.xtreemfs +deletes the volume named \fIvolume\fR from the XtreemFS MRC running at \fImrc-host\fR:\fIport\fR. Be careful, this command will delete the volume including the metadata of all files. + +However, the disk space on the OSDs, occupied by the objects of the files of the deleted volume, will not be freed by \fIrmfs.xtreemfs\fR. Run +.BR xtfs_cleanup (1) +afterwards to free the disk space on the OSDs. + +.SH EXAMPLE USAGE +.TP +Delete the volume "MyVolume" which is stored at the MRC server "remote.mrc.machine": +.TP +.B "rmfs.xtreemfs remote.mrc.machine/MyVolume" + +.SH OPTIONS + +.TP +rmfs.xtreemfs Options: +.TP +.BI "--admin_password " password +MRC's admin_password (not required if not set at the MRC). +.TP +.BI "-f, --force" +Never prompt. Overrides safety questions. + +.TP +General Options: +.TP +.BI "-d, --log-level " EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG +The log level of the XtreemFS client. +.TP +.B "-h, --help" +Print help and exit. +.TP +.BI "-l, --log-file-path " log_file_path +Path to log file. +.TP +.BI "-V, --version" +Shows the version number. + +.TP +SSL Options: +.TP +.BI "--pem-certificate-file-path " certfile +Path to PEM certificate file (for SSL installations only). +.TP +.BI "--pem-private-key-file-path " file +Path to PEM private key file (for SSL installations only). +.TP +.BI "--pem-private-key-passphrase " pass +Passphrase for PEM private key file (for SSL installations only) +.TP +.BI "--pkcs12-file-path " file +Path to PKCS#12 file (for SSL installations only). +.TP +.BI "--pkcs12-passphrase " pass +Passphrase for PKCS#12 file (for SSL installations only). + +.SH "SEE ALSO" +.BR lsfs.xtreemfs (1), +.BR mkfs.xtreemfs (1), +.BR mount.xtreemfs (1), +.BR umount.xtreemfs (1), +.BR xtfsutil (1) +.BR + +.SH AVAILABILITY +The rmfs.xtreemfs command is part of the XtreemFS-client package and is available from \fIhttp://www.xtreemfs.org\fP. diff --git a/man/man1/umount.xtreemfs.1 b/man/man1/umount.xtreemfs.1 new file mode 100644 index 0000000..45690c7 --- /dev/null +++ b/man/man1/umount.xtreemfs.1 @@ -0,0 +1,23 @@ +.TH umount.xtreemfs 1 "July 2011" "The XtreemFS Distributed File System" "XtreemFS client" +.SH NAME +umount.xtreemfs \- unmounts an XtreemFS volume +.SH SYNOPSIS +\fBumount.xtreemfs \fIvolume mountpoint +.br + +.SH DESCRIPTION +.I umount.xtreemfs +umounts the volume that has been mounted to \fIvolume\fR. + +.SH EXAMPLE USAGE +.B "umount.xtreemfs /mnt" + +.SH "SEE ALSO" +.BR lsfs.xtreemfs (1), +.BR mkfs.xtreemfs (1), +.BR mount.xtreemfs (1), +.BR rmfs.xtreemfs (1) +.BR + +.SH AVAILABILITY +The umount.xtreemfs command is part of the XtreemFS-client package and is available from \fIhttp://www.xtreemfs.org\fP. \ No newline at end of file diff --git a/man/man1/xtfs_chstatus.1 b/man/man1/xtfs_chstatus.1 new file mode 100644 index 0000000..dbdc09c --- /dev/null +++ b/man/man1/xtfs_chstatus.1 @@ -0,0 +1,45 @@ +.TH xtfs_chstatus 1 "July 2011" "The XtreemFS Distributed File System" "XtreemFS Admin Tools" +.SH NAME +xtfs_chstatus \- changes the status flag of an OSD. +.SH SYNOPSIS +\fBxtfs_chstatus [ \fIoptions\fB ] \fI online|removed\fB +.br + +.SH DESCRIPTION +.I xtfs_chstatus +displays and changes the status flag of an OSD. The status can be 0 (online), 1 (locked) and 2 (permanently dead/removed). The status flag is used by the scrubber to identify dead OSDs. Files and replicas on dead OSDs are removed by the scrubber tool. + +.SH EXAMPLE USAGE +.TP +.B "xtfs_chstatus -dir pbrpc://localhost:32638 2e3d-424b-b3d2 removed +Changes the status of the OSD with UUID 2e3d-424b-b3d2 registered at the Directory Service 'pbrpc://localhost:32638' to 2 (removed) + +.SH OPTIONS +.TP +\fB-c \fI +Path to a PKCS#12 credentials file (private key + certificate) to use for SSL authentication. Must be present when MRC URL starts with pbrpcs:// or pbrpcg://. +.TP +\fB-cpass \fI +An optional passphrase to access the credentials file. +.TP +\fB-dirs \fI +Specifies the directory services to use (e.g. 'pbrpc://localhost:32638,pbrpc://myDir.com:32638') (comma-separated). If no URI is specified, URIs and security settings are taken from '/etc/xos/xtreemfs/default_dir'. In case of a secured URI ('pbrpcs://...' or 'pbrpcg://...'), it is necessary to also specify SSL settings. +.TP +\fB-h/--help +Show usage info. +.TP +\fB-t \fI +Path to a PKCS#12 file containing a set of certificates from trusted certification authorities. These certificates will be used to authenticate the MRC. Must be present when MRC URL starts with pbrpcs:// or pbrpcg://. +.TP +\fB-tpass \fI +An optional passphrase to access the truststore file. + +.SH "SEE ALSO" +.BR xtfs_cleanup (1), +.BR xtfs_mrcdbtool (1), +.BR xtfs_remove_osd (1), +.BR xtfs_scrub (1), +.BR + +.SH AVAILABILITY +The xtfs_chstatus command is part of the XtreemFS-tools package and is available from \fIhttp://www.xtreemfs.org\fP. diff --git a/man/man1/xtfs_cleanup.1 b/man/man1/xtfs_cleanup.1 new file mode 100644 index 0000000..c22e73e --- /dev/null +++ b/man/man1/xtfs_cleanup.1 @@ -0,0 +1,75 @@ +.TH xtfs_cleanup 1 "July 2011" "The XtreemFS Distributed File System" "XtreemFS Admin Tools" +.SH NAME +xtfs_cleanup \- checks for each file on the OSD, if it has an entry at the Metadata Server (MRC). +.SH SYNOPSIS +\fBxtfs_cleanup [ \fIoptions\fB ] \fIuuid: +.BR + +.SH DESCRIPTION +.I xtfs_cleanup +performs a check of each file on the given Object Storage Device (OSD) whether it is registered at a MRC or not and removes orphaned OSD metadata. + +.SH EXAMPLE USAGE +.TP +.B "xtfs_cleanup -e uuid:d1feb333-d986-4e91-b8e7-eb2a48485f8b" +Starts the cleanup process on the OSD identified by UUID 'd1feb333-d986-4e91-b8e7-eb2a48485f8b' and deletes all orphaned files automatically. + +.SH OPTIONS +.TP +\fB-c \fI +Path to a PKCS#12 credentials file (private key + certificate) to use for SSL authentication. Must be present when MRC URL starts with pbrpcs:// or pbrpcg://. +.TP +\fB-cpass \fI +An optional passphrase to access the credentials file. +.TP +\fB-delete_volumes +Deletes volumes that might be dead. +.TP +\fB-dir \fI +Specifies the directory services to use (e.g. 'pbrpc://localhost:32638,pbrpc://myDir.com:32638') (comma-separated). If no URI is specified, URIs and security settings are taken from '/etc/xos/xtreemfs/default_dir'. In case of a secured URI ('pbrpcs://...' or 'pbrpcg://...'), it is necessary to also specify SSL settings. +.TP +\fB-e +Automatically deletes orphaned files. +.TP +\fB-h/--help +Shows usage info. +.TP +\fB-i +Enables the interactive mode and displays the cleanup progress. +.TP +\fB-metadata_timeout \fI +Metadata will only be deleted, if the last XLocSet update was more than \fI\fR seconds ago. The default \fI\fR is equal to the default capability timeout: 600. If \fI\fR is 0, metadata will be deleted instantly. +.TP +\fB-metadata_keep +Keep metadata when files are deleted and don't search for orphaned metadata. By default metadata will be deleted after \fI\fR seconds. +.TP +\fB-r +Restores all orphaned files to a directory '/lost+found/' in the volume root directory. +.TP +\fB-stop +Suspends the currently running cleanup process. +.TP +\fB-t \fI +Path to a PKCS#12 file containing a set of certificates from trusted certification authorities. These certificates will be used to authenticate the MRC. Must be present when MRC URL starts with pbrpcs:// or pbrpcg://. +.TP +\fB-tpass \fI +An optional passphrase to access the truststore file. +.TP +.B \-v +Run a version cleanup, which disposes of obsolete file versions. A version cleanup will only affect files with multiple versions. +.TP +.B \-wait +Blocks the call until the current cleanup run has finished. +.TP +.B \--admin_password \fI +The administrator password, if password protection is enabled. + +.SH "SEE ALSO" +.BR xtfs_chstatus (1), +.BR xtfs_mrcdbtool (1), +.BR xtfs_remove_osd (1), +.BR xtfs_scrub (1), +.BR + +.SH AVAILABILITY +The xtfs_cleanup command is part of the XtreemFS-tools package and is available from \fIhttp://www.xtreemfs.org\fP. diff --git a/man/man1/xtfs_mrcdbtool.1 b/man/man1/xtfs_mrcdbtool.1 new file mode 100644 index 0000000..a629fd3 --- /dev/null +++ b/man/man1/xtfs_mrcdbtool.1 @@ -0,0 +1,51 @@ +.TH xtfs_mrcdbtool 1 "July 2011" "The XtreemFS Distributed File System" "XtreemFS Admin Tools" +.SH NAME +xtfs_mrcdbtool \- dumps and restores MRC databases. +.SH SYNOPSIS +\fBxtfs_mrcdbtool [\fIoptions\fB] \fIdump|restore\fP +.br + +.SH DESCRIPTION +.I xtfs_mrcdbtool +dumps an MRC database to a file, or restores an MRC database from a dump file. An XML dump of the MRC database is created if the \fIdump\fP option is chosen. When dumping an MRC database, the XML file containing the dump will be created on the server at the path \fIdump_file\fP. Dumps can be restored by using the \fIrestore\fP option. For safety reasons, this is only possible if the target MRC does not have a database yet. + +.SH EXAMPLE USAGE +.TP +.B "xtfs_mrcdbtool -mrc pbrpc://localhost:32636 dump /tmp/dump.xml" +Dumps the database of the MRC running on \fIlocalhost:32636\fP to \fI/tmp/dump.xml\fP. +.TP +.B "xtfs_mrcdbtool -mrc pbrpc://localhost:32636 restore /tmp/dump.xml" +Restores the database of the MRC running on \fIlocalhost:32636\fP from the dump in \fI/tmp/dump.xml\fP. + +.SH OPTIONS +.TP +.B \-c \fIcreds_file +Path to a PKCS#12 credentials file (private key + certificate) to use for SSL authentication. Must be present when MRC URL starts with pbrpcs:// or pbrpcg://. +.TP +.B \-cpass \fIcreds_passphrase +An optional passphrase to access the credentials file. +.TP +.B \-h/--help +Shows usage info. +.TP +.B \-mrc \fImrc_url +The URL the MRC, e.g. pbrpc://localhost:32636. +.TP +.B \-t \fItrusted_CAs +Path to a PKCS#12 file containing a set of certificates from trusted certification authorities. These certificates will be used to authenticate the MRC. Must be present when MRC URL starts with pbrpcs:// or pbrpcg://. +.TP +.B \-tpass \fItrusted_passphrase +An optional passphrase to access the truststore file. +.TP +.B \--admin_password \fI +The administrator password, if password protection is enabled. + +.SH "SEE ALSO" +.BR xtfs_chstatus (1), +.BR xtfs_cleanup (1), +.BR xtfs_remove_osd (1), +.BR xtfs_scrub (1), +.BR + +.SH AVAILABILITY +The xtfs_mrcdbtool command is part of the XtreemFS-tools package and is available from \fIhttp://www.xtreemfs.org\fP. \ No newline at end of file diff --git a/man/man1/xtfs_remove_osd.1 b/man/man1/xtfs_remove_osd.1 new file mode 100644 index 0000000..de8cdaf --- /dev/null +++ b/man/man1/xtfs_remove_osd.1 @@ -0,0 +1,66 @@ +.TH xtfs_remove_osd 1 "July 2011" "The XtreemFS Distributed File System" "XtreemFS Admin Tools" +.SH NAME +xtfs_remove_osd \- removes an OSD by copying all objects on this OSD to other OSDs +.SH SYNOPSIS +\fBxtfs_remove_osd [ \fIoptions\fB ] \fIuuid: +.BR + +.SH DESCRIPTION +.I xtfs_remove_osd +removes an OSD which is currently used. It copies all objectes on the OSD with the UUID +.I +to other OSDs and then shut down the OSD. + +.SH EXAMPLE USAGE +.TP +.B "xtfs_remove_osd -dir localhost:32638 uuid:d1feb333-d986-4e91-b8e7-eb2a48485f8b" +Starts the removing process on the OSD identified by UUID 'd1feb333-d986-4e91-b8e7-eb2a48485f8b' and copies all files automatically to other OSDs (determinded by the OSD Selection Policy). + +.SH OPTIONS +.TP +\fB-c \fI +Path to a PKCS#12 credentials file (private key + certificate) to use for SSL authentication. Must be present when MRC URL starts with pbrpcs:// or pbrpcg://. +.TP +\fB-cpass \fI +An optional passphrase to access the credentials file. +.TP +\fB-dir \fI +Specifies the directory service to use (e.g. 'pbrpc://localhost:32638'). If no URI is specified, URI and security settings are taken from '/etc/xos/xtreemfs/default_dir'. In case of a secured URI ('pbrpcs://...' or 'pbrpcg://...'), it is necessary to also specify SSL settings. +.TP +\fB-h/--help +Shows usage info. +.TP +\fB-t \fI +Path to a PKCS#12 file containing a set of certificates from trusted certification authorities. These certificates will be used to authenticate the MRC. Must be present when MRC URL starts with pbrpcs:// or pbrpcg://. +.TP +\fB-tpass \fI +An optional passphrase to access the truststore file. +.TP +\fB-d +Enables debugging output. +.TP +\fB-s +Shuts down the OSD per remote call after all object files are moved to other OSDs. Note that the shutdown process will be performed independently from your init system which can lead to errors if you try to start this OSD again with your init scripts. Therefore the default is not to shutdown the OSD. This step should be performed manually. +.TP +.B \--admin_password \fI +The administrator password, if password protection is enabled. Used only if you want to shutdown the OSD automatically per remote call. + + +.SH LIMITATIONS +.TP +While the draining is in progress, it is not possible to modify the to be moved files as they are temporarily set to read-only. Additionally, when the draining will be started, no files of the OSD should be hold open by any client. +.TP +Draining an OSD that holds striped and replicated files involves certain limitations. A striped file is currently moved to a new OSD in its entirety rather than partially. Regardless of the original number of OSDs it was striped across, it is relocated to a single target OSD, which implies that the target file is not striped anymore. As a consequence, data may be moved from OSDs that are not directly affected by the draining process. +.TP +Furthermore, at least one OSD has to exist for each file that does not hold any data of the file, i.e. is not included in any stripe or replica. If all OSDs that are eligible according to the OSD selection policy have already been assigned to a file, draining any of these OSDs will fail, as no additional replicas can be created. + +.SH "SEE ALSO" +.BR xtfs_chstatus (1), +.BR xtfs_mrcdbtool (1), +.BR xtfs_remove_osd (1), +.BR xtfs_scrub (1), +.BR xtfs_cleanup (1) +.BR + +.SH AVAILABILITY +The xtfs_remove_osd command is part of the XtreemFS-tools package and is available at \fIhttp://www.xtreemfs.org\fP. diff --git a/man/man1/xtfs_scrub.1 b/man/man1/xtfs_scrub.1 new file mode 100644 index 0000000..8189143 --- /dev/null +++ b/man/man1/xtfs_scrub.1 @@ -0,0 +1,62 @@ +.TH xtfs_scrub 1 "July 2011" "The XtreemFS Distributed File System" "XtreemFS Admin Tools" +.SH NAME +xtfs_scrub \- checks for each file in a volume if the MRC file size is outdated and if the checksum of all objects is correct. The scrubber can also replace defective replicas in repair mode. +.SH SYNOPSIS +\fBxtfs_scrub [ \fIoptions\fB ] \fI\fB +.br + +.SH DESCRIPTION +.I xtfs_scrub +performs a consistency check of each file in a given volume. If run without \-repair or \-delete it will only perform checks and report problems. Th scrubber checks for file if the file size on the OSDs is stored on the MRC and fixes inconsistencies if run in the \-repair mode. In addition, the scrubber checks the checksum for each object of a file if the checksums are enabled on the OSD. + +For replicated files the scrubber will check each replica for objects with inccorect checksum. In addition, it marks full replicas that successfully copied all objects as "complete" replicas. In the \-repair mode, the scrubber will also replace replicas that contain ramoved OSDs. An OSD must be marked as dead/removed with the xtfs_chstatus tool, otherwise the scrubber will consider the OSD as temporarily unavailable and won't replace the replica. + +.SH EXAMPLE USAGE +.B "xtfs_scrub \-dir pbrpc://localhost:32638 myVolume +.PP +Scrubs all files in the volume named 'myVolume' registered at the Directory Service 'pbrpc://localhost:32638'. + +.SH OPTIONS +.TP +.TP +\fB-c \fI +Path to a PKCS#12 credentials file (private key + certificate) to use for SSL authentication. Must be present when MRC URL starts with pbrpcs:// or pbrpcg://. +.TP +\fB-cpass \fI +An optional passphrase to access the credentials file. +.TP +\fB\-delete +Deletes files where the objects are lost because they were stored on a failed/removed OSD. +.TP +\fB-dirs \fI +Specifies the directory services to use (e.g. 'pbrpc://localhost:32638,pbrpc://myDir.com:32638') (comma-separated). +If no URI is specified, URIs and security settings are taken from '/etc/xos/xtreemfs/default_dir'. +In case of a secured URI ('pbrpcs://...' or 'pbrpcg://...'), it is necessary to also specify SSL settings. +.TP +\fB-h/--help +Shows usage info. +.TP +\fB\-repair +Repairs inconsistent file sizes and replace replicas on failed/removed OSD. +.TP +\fB\-silent +Hides detailed information about the scrubbed files. +.TP +\fB-t \fI +Path to a PKCS#12 file containing a set of certificates from trusted certification authorities. These certificates will be used to authenticate the MRC. Must be present when MRC URL starts with pbrpcs:// or pbrpcg://. +.TP +\fB\-thrs \fI<#threads> +Sets the number of threads to use for scrubbing (default=10). +.TP +\fB-tpass \fI +An optional passphrase to access the truststore file. + +.SH "SEE ALSO" +.BR xtfs_chstatus (1), +.BR xtfs_cleanup (1), +.BR xtfs_mrcdbtool (1), +.BR xtfs_remove_osd (1), +.BR + +.SH AVAILABILITY +The xtfs_scrub command is part of the XtreemFS-tools package and is available from \fIhttp://www.xtreemfs.org\fP. diff --git a/man/man1/xtfsutil.1 b/man/man1/xtfsutil.1 new file mode 100644 index 0000000..5d9693b --- /dev/null +++ b/man/man1/xtfsutil.1 @@ -0,0 +1,199 @@ +.TH xtfsutil 1 "July 2011" "The XtreemFS Distributed File System" "XtreemFS utility" +.SH NAME +xtfsutil \- shows and modifies XtreemFS specific file, directory and volume attributes +.SH SYNOPSIS +\fBxtfsutil \fP[\fIpath\fP]\fR \- shows the XtreemFS attributes such as URL, locations etc. +.br +\fBxtfsutil \fP[OPTIONS] [\fIpath\fP]\fR \- modifies XtreemFS attributes, adds/removes replicas, snapshots, etc. +.br + +.SH DESCRIPTION +.I xtfsutil +when no options are provided, xtfsutl shows information about a file or directory \fIpath\fP. + +.SH EXAMPLE USAGE + +.TP +.TP +Display information about the file "/somedir/myfile": +.TP +.B "xtfsutil xtfs-mount/somedir/myfile" +.br +.TP +Add another replica to the replicated file "/somedir/myfile" which will be created on an automatically chosen OSD. If the file is not replicated yet, set a replication policy for the file first (see option \-r / \-\-set-replication-policy). Or set a default replication policy for future files. +.TP +.B "xtfsutil \--add-replica AUTO xtfs-mount/somedir/myfile" +.br +.TP +Set the default replication policy to "WqRq" and a default replication factor of 3 for the mounted volume: +.TP +.B "xtfsutil \--set-drp \--replication-policy WqRq \--replication-factor 3 xtfs-mount/" + +.SH OPTIONS + +.TP +\fB\-\-errors +Shows a list of recent error messages the client has reveived, +e.g. more detailed XtreemFS error messages. + +.TP +\fB\-\-set-acl [acl] +Sets or updates a POSIX ACL entry for a file, directory or volume. +The acl entry must have the following format: u|g|m|o:[]:[|] + +.TP +\fB\-\-del-acl [acl] +Removes a POSIX ACL entry for a file, directory or volume. +The acl entry must have the following format: u|g|m|o:[] + +.TP +VOLUME OPTIONS: +.TP +\fB\-\-set-dsp +Changes the default striping policy for a volume. +This policy defines, how new files are striped but does not affect +files that already exist on the volume. +.br +Requires the following options: \-\-striping-policy-width, \-\-striping-policy-stripe-size +.br +Additional options: \-\-striping-policy + +.TP +\fB\-\-set-drp +Changes the default replication policy for a volume. +If a replication policy is defined, all new files will be replicated. +.br +Requires the following options: \-\-replication-policy, \-\-replication-factor +.br +Additional options: \-\-full + +.TP +\fB\-\-replication-policy ronly|WqRq|WaR1|none (the aliases readonly|quorum|all are also allowed) +Sets the replication policy. + +.br +.B ronly +Read-only replication, files are immutable. Files will be replicated after closing them. +.br +.B WqRq +Quorum-based replication. Files are mutable and provide regular POSIX semantics. A WqRq-replicated file is available for reading and writing as long as the majority of its replicas are available. Please read more about the technical details of the WqRq replication policy in the XtreemFS user guide (Section "Read/Write File Replication"). +.br +.B WaR1 +Files are mutable and provide regular POSIX semantics. Writes have to be acknowledged by all replicas. Data can be read from any replica. +.br +.B none +Disables replication. + +.TP +\fB\-\-replication-factor num +Sets the replication factor to num. + +.TP +\fB\-\-full +If replication policy is ronly (read-only replication), this flag will create full replicas. +By default, read-only replicas are partial. + +.TP +\fB\-\-set-osp [comma separated list of policy IDs] or \fIDEFAULT,FQDN,UUID,DCMAP,VIVALDI +Changes the OSD selection policy for a volume. The OSD selection policy defines which OSDs are used +for new files and replicas. In general, this command accepts a comma separated list of +policy IDs without spaces. The command also accepts one of the following predefined policies: + + +.br +\fBDEFAULT OSDs are selected randomly. +.br +\fBFQDN OSDs are sorted by the number of characters matching the client's FQDN. +.br +\fBUUID OSDs are selected based on their UUID. +.br +\fBDCMAP OSDs are sorted by the distance to the client according to the datacenter map. +.br +\fBVIVALDI OSDs are sorted by the distance to the client based on dynamic network coordinates (VIVALDI). + +.TP +\fB\-\-set-rsp [comma separated list of policy IDs] or \fIDEFAULT,FQDN,DCMAP,VIVALDI +Changes the Replica selection policy for a volume. The Replica selection policy defines how the list of +replicas for a file is sorted for a client when it accesses a file. Clients iterate over the list of +replicas from the first to the last. In general, this command accepts a comma separated list of +policy IDs without spaces. The command also accepts one of the following predefined policies: + +.br +\fBDEFAULT The list of replicas is not modified. +.br +\fBFQDN Replicas are sorted by the number of characters matching the client's FQDN. +.br +\fBDCMAP Replicas are sorted by the distance to the client according to the datacenter map. +.br +\fBVIVALDI Replicas are sorted by the distance to the client based on dynamic network coordinates (VIVALDI). + +.TP +\fB\-\-set-pattr [value name] \-\-value [attribute value] +Changes the value of a policy attribute for a volume. See the XtreemFS user guide for attribute names. + +Policy attributes can be removed by setting an empty value, e.g.: + + $> xtfsutil \--set-pattr 1001.domains \--value "" /xtreemfs + +.TP +\fB\-\-list-pattrs +Lists all policy attributes that are set on a volume. + +.TP +\fB\-\-enable-snapshots +Enables snapshots on the volume. + +.TP +\fB\-\-disable-snapshots +Disables snapshots on the volume. + +.TP +\fB\-\-list-snapshots +Lists all available snapshots. + +.TP +\fB\-\-create-snapshot \fP[\fIname\fP] +Creates a snapshot of the volume/directory with the name \fIname\fP. If \fIname\fP is empty, the current server time will be used as snapshot name. + +.TP +\fB\-\-create-snapshot-non-recursive \fP[\fIname\fP] +Same as \--create-snapshot but excludes any subdirectories. + +.TP +\fB\-\-delete-snapshot \fP[\fIname\fP] +Deletes the snapshot with the name \fIname\fP. + +.TP +\fB\-\-set-quota [quota size]MB|GB|TB +Sets the volume quota (set quota to 0 to disable the quota) + +.TP +FILE OPTIONS: +.TP +\fB\-a, \-\-add-replica [OSD UUID] or AUTO +Adds a new replica on the specified OSD or on an automatically selected OSD (if AUTO is set). +.br +Additional options: \-\-full (creates a full read-only replica) + +.TP +\fB\-d, \-\-delete-replica [OSD UUID] +Removes the replica on the OSD with the specified UUID. + +.TP +\fB\-l, \-\-list-osds +Prints a list of up to ten OSDs that can be used for new replicas for the specified file. + +.TP +\fB\-r, \-\-set-replication-policy ronly|WqRq|WaR1|none (the aliases readonly|quorum|all are also allowed) +Sets the replication policy for a file. Mode cane only be changed when a file has no replicas. See \--replication-policy for values. + +.SH "SEE ALSO" +.BR lsfs.xtreemfs (1), +.BR mkfs.xtreemfs (1), +.BR mount.xtreemfs (1), +.BR rmfs.xtreemfs (1), +.BR umount.xtreemfs (1), +.BR + +.SH AVAILABILITY +The xtfsutil command is part of the XtreemFS-client package and is available from http://www.xtreemfs.org. diff --git a/packaging/generate_uuid b/packaging/generate_uuid new file mode 100755 index 0000000..e56e08b --- /dev/null +++ b/packaging/generate_uuid @@ -0,0 +1,25 @@ +#!/bin/bash +# this scripts uses the tool 'uuidgen' + +CFGFILE=$1 #name of the config file (osdconfig, mrcconfig) + +grep -e '^uuid\W*=\W*\w\+' $CFGFILE > /dev/null + +if [ $? -ne 0 ] +then + UUID=`which uuidgen` + if [ $? -ne 0 ] + then + UUID=$RANDOM"-"$RANDOM"-"$RANDOM"-"$RANDOM + echo "WARNING: uuidgen is not available, the generated UUID contains just random numbers. THIS UUID IS PROBABLY NOT UNIQUE, PLEASE CREATE A REAL UUID IF YOU INTEND TO USE THIS SERVICE IN A MULTI-SERVER ENVIRONMENT." + else + UUID=`$UUID` + fi + + echo "" >> $CFGFILE + echo "# The UUID is the globally unique name of this service." >> $CFGFILE + echo "# You must not change the UUID once the service has been used" >> $CFGFILE + echo "# to change the address/hostname or port of a service please" >> $CFGFILE + echo "# change the UUID Mapping in the directory service." >> $CFGFILE + echo "uuid = "$UUID >> $CFGFILE +fi \ No newline at end of file diff --git a/packaging/postinstall_setup.sh b/packaging/postinstall_setup.sh new file mode 100644 index 0000000..37b3178 --- /dev/null +++ b/packaging/postinstall_setup.sh @@ -0,0 +1,78 @@ +#!/bin/bash +set -e + +XTREEMFS_LOG_DIR=/var/log/xtreemfs +XTREEMFS_HOME=/var/lib/xtreemfs +XTREEMFS_ETC=/etc/xos/xtreemfs +XTREEMFS_USER=xtreemfs +XTREEMFS_GROUP=xtreemfs +XTREEMFS_GENERATE_UUID_SCRIPT="${XTREEMFS_ETC}/generate_uuid" + +# When executed during POST installation, do not be verbose. +VERBOSE=0 +script_name=$(basename "$0") +if [ "$script_name" = "postinstall_setup.sh" ] +then + VERBOSE=1 +fi + +# generate UUIDs +if [ -x "$XTREEMFS_GENERATE_UUID_SCRIPT" ]; then + for service in dir mrc osd; do + "$XTREEMFS_GENERATE_UUID_SCRIPT" "${XTREEMFS_ETC}/${service}config.properties" + [ $VERBOSE -eq 1 ] && echo "Generated UUID for service: $service" + done +else + echo "UUID can't be generated automatically. Please enter a correct UUID in each config file of an XtreemFS service." +fi + + +group_exists=`grep -c $XTREEMFS_GROUP /etc/group || true` +if [ $group_exists -eq 0 ]; then + groupadd $XTREEMFS_GROUP + [ $VERBOSE -eq 1 ] && echo "created group $XTREEMFS_GROUP" +fi +exists=`grep -c $XTREEMFS_USER /etc/passwd || true` +if [ $exists -eq 0 ]; then + mkdir $XTREEMFS_HOME + useradd -r --home $XTREEMFS_HOME -g $XTREEMFS_GROUP $XTREEMFS_USER + chown $XTREEMFS_USER $XTREEMFS_HOME + [ $VERBOSE -eq 1 ] && echo "created user $XTREEMFS_USER and data directory $XTREEMFS_HOME" +fi +if [ ! -d $XTREEMFS_HOME ]; then + mkdir -m750 $XTREEMFS_HOME + chown $XTREEMFS_USER $XTREEMFS_HOME + [ $VERBOSE -eq 1 ] && echo "user $XTREEMFS_USER exists but data directory $XTREEMFS_HOME had to be created" +fi +owner=`stat -c %U $XTREEMFS_HOME` +if [ "$owner" != "$XTREEMFS_USER" ]; then + [ $VERBOSE -eq 1 ] && echo "directory $XTREEMFS_HOME is not owned by $XTREEMFS_USER, executing chown" + chown $XTREEMFS_USER $XTREEMFS_HOME +fi + +if [ ! -e $XTREEMFS_LOG_DIR ]; then + mkdir $XTREEMFS_LOG_DIR + chown -R $XTREEMFS_USER $XTREEMFS_LOG_DIR +fi + +if [ -e $XTREEMFS_ETC ]; then + group=`stat -c %G $XTREEMFS_ETC 2>/dev/null` + if [ $group != $XTREEMFS_GROUP ]; then + [ $VERBOSE -eq 1 ] && echo "directory $XTREEMFS_ETC is owned by $group, should be owned by $XTREEMFS_GROUP, executing chgrp (may take some time)" + chgrp -R $XTREEMFS_GROUP $XTREEMFS_ETC + fi + for file in `ls $XTREEMFS_ETC/*.properties 2>/dev/null`; do + if [ -f $file -a "$(stat -c %a $file)" != "640" ]; then + [ $VERBOSE -eq 1 ] && echo "setting $file 0640, executing chmod" + chmod 0640 $file + fi + done + if [ -d "$XTREEMFS_ETC/truststore/" ] + then + if [ "$(stat -c %a "$XTREEMFS_ETC/truststore/")" != "750" ] + then + [ $VERBOSE -eq 1 ] && echo "setting $XTREEMFS_ETC/truststore/ to 0750, executing chmod (may take some time)" + chmod -R u=rwX,g=rX,o= $XTREEMFS_ETC/truststore/ + fi + fi +fi diff --git a/snmp/README.txt b/snmp/README.txt new file mode 100644 index 0000000..46a22e4 --- /dev/null +++ b/snmp/README.txt @@ -0,0 +1,8 @@ +xtreemfs-mib is a MIB(Management Information Base) for the +SNMPv2c protocol. + +If you make changes validate them with smilint command. + +Use generatecode.sh to generate Java code + + diff --git a/snmp/generatedcode.sh b/snmp/generatedcode.sh new file mode 100644 index 0000000..90e5fdd --- /dev/null +++ b/snmp/generatedcode.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +JAVA=java +if [ ! -z "${JAVA_HOME}" ]; then + JAVA=$JAVA_HOME/bin/java +fi + + + +CLASSPATH="../java/lib/jdmkrt.jar":"../java/lib/jdmktk.jar":"$CLASSPATH" +export CLASSPATH + + +$JAVA com.sun.jdmk.tools.MibGen -mc -d ../java/servers/src/org/xtreemfs/common/monitoring/generatedcode -tp org.xtreemfs.common.monitoring.generatedcode xtreemfs-mib.txt mib_core.txt + +exit 0; diff --git a/snmp/jdmk.acl b/snmp/jdmk.acl new file mode 100644 index 0000000..831a461 --- /dev/null +++ b/snmp/jdmk.acl @@ -0,0 +1,38 @@ +# @(#)file jdmk.acl +# @(#)author Sun Microsystems, Inc. +# @(#)version 1.11 +# @(#)lastedit 04/04/07 +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + +# access: can take only "read-only" or "read-write" values +# +# managers can be : +# - hostname: hubble +# - ip v4 and v6 addresses: 123.456.789.12 , fe80::a00:20ff:fe9b:ea82 +# - subnet mask: 123!255!255!255 (its an IPO address where "." are replaced +# by "!"). This way of expressing the subnet is deprecated, use the prefix +# notation. +# - ip v4 and v6 netmask prefix notation : +# 123.456.789.12/24, fe80::a00:20ff:fe9b:ea82/64 + +acl = { + { + communities = public + access = read-only + managers = localhost + } + { + communities = private + access = read-write + managers = localhost + } +} + +trap = { + { + trap-community = public + hosts = localhost + } +} diff --git a/snmp/mib_core.txt b/snmp/mib_core.txt new file mode 100644 index 0000000..1de0ea0 --- /dev/null +++ b/snmp/mib_core.txt @@ -0,0 +1,375 @@ +-- +-- @(#)file mib_core.txt +-- @(#)author Sun Microsystems, Inc. +-- @(#)version 1.8 +-- @(#)date 07/04/04 +-- +-- The file contains stubs for common definitions scattered around many +-- different RFCs. It is a convenience that will allow mibgen to compile +-- a MIB without requiring that you pass all standard SNMP modules on the +-- command line. +-- +-- See the listed RFCs themselves for the original definitions. +-- + + CORE-MIB DEFINITIONS ::= BEGIN + + + IMPORTS ; + +-------------------------------------- +-- Commonly used OBJECT IDENTIFIERS -- +-------------------------------------- + + +----------------------- +-- As defined in SMI -- +----------------------- + + -- the path to the root + + internet OBJECT IDENTIFIER ::= { iso(1) org(3) dod(6) 1 } + + directory OBJECT IDENTIFIER ::= { internet 1 } + + mgmt OBJECT IDENTIFIER ::= { internet 2 } + + experimental OBJECT IDENTIFIER ::= { internet 3 } + + private OBJECT IDENTIFIER ::= { internet 4 } + enterprises OBJECT IDENTIFIER ::= { private 1 } + + security OBJECT IDENTIFIER ::= { internet 5 } + + snmpV2 OBJECT IDENTIFIER ::= { internet 6 } + + -- transport domains + snmpDomains OBJECT IDENTIFIER ::= { snmpV2 1 } + + -- transport proxies + snmpProxys OBJECT IDENTIFIER ::= { snmpV2 2 } + + -- module identities + snmpModules OBJECT IDENTIFIER ::= { snmpV2 3 } + + +------------------------------ +-- MIB-II OBJECT IDENTIFIER -- +------------------------------ + + + mib-2 OBJECT IDENTIFIER ::= { mgmt 1 } + + +----------------- +-- entreprises -- +----------------- + + sun OBJECT IDENTIFIER ::= { enterprises 42 } + messaging OBJECT IDENTIFIER ::= { sun products(2) 8 } + + agents OBJECT IDENTIFIER ::= { messaging 1 } + private-mibs OBJECT IDENTIFIER ::= { messaging 2 } + + snmpx400d OBJECT IDENTIFIER ::= { agents 1 } + snmpxapiad OBJECT IDENTIFIER ::= { agents 2 } + snmpx500d OBJECT IDENTIFIER ::= { agents 3 } + snmpimd OBJECT IDENTIFIER ::= { agents 4 } + snmpslapd OBJECT IDENTIFIER ::= { agents 5 } + + +-------------------------------------------------------------- +-- Stubs for commonly used TEXTUAL CONVENTIONS and SYNTAXES -- +-------------------------------------------------------------- + +------------------------------------------------------------------------ +-- Stub for EntryStatus syntax from RFC 1271 -- +-- See http://www.ietf.org/rfc/rfc1271.txt for the actual definition. -- +------------------------------------------------------------------------ + + EntryStatus ::= INTEGER + { valid(1), + createRequest(2), + underCreation(3), + invalid(4) + } +------------------------------------------------------------------------ +-- Stubs for standard SNMP Syntaxes as defined in RFC 1065/1442 -- +-- See http://www.ietf.org/rfc/rfc1065.txt for the actual definition. -- +-- See http://www.ietf.org/rfc/rfc1442.txt for the actual definition. -- +------------------------------------------------------------------------ + + Gauge32 ::= Gauge + + Counter32 ::= Counter + + Integer32 ::= INTEGER + + -- application-wide types + + NetworkAddress ::= + CHOICE { + internet + IpAddress + } + + IpAddress ::= + [APPLICATION 0] + IMPLICIT OCTET STRING (SIZE (4)) + + Counter ::= + [APPLICATION 1] + IMPLICIT INTEGER (0..4294967295) + + Counter64 ::= + [APPLICATION 1] + IMPLICIT INTEGER (0..18446744073709551615) + + Gauge ::= + [APPLICATION 2] + IMPLICIT INTEGER (0..4294967295) + + Unsigned32 ::= + [APPLICATION 2] + IMPLICIT INTEGER (0..4294967295) + + TimeTicks ::= + [APPLICATION 3] + IMPLICIT INTEGER (0..4294967295) + + Opaque ::= + [APPLICATION 4] + IMPLICIT OCTET STRING + + + +----------------------------------------------------------------------- +-- Stubs for standard SNMPv2 Textual Conventions defined in RFC 1903 -- +-- See http://www.ietf.org/rfc/rfc1903.txt for the actual definition. -- +------------------------------------------------------------------------ + +DisplayString ::= TEXTUAL-CONVENTION + DISPLAY-HINT "255a" + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX OCTET STRING (SIZE (0..255)) + + +PhysAddress ::= TEXTUAL-CONVENTION + DISPLAY-HINT "1x:" + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX OCTET STRING + + +MacAddress ::= TEXTUAL-CONVENTION + DISPLAY-HINT "1x:" + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX OCTET STRING (SIZE (6)) + + +TruthValue ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX INTEGER { true(1), false(2) } + +TestAndIncr ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX INTEGER (0..2147483647) + + +AutonomousType ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX OBJECT IDENTIFIER + + +InstancePointer ::= TEXTUAL-CONVENTION + STATUS obsolete + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX OBJECT IDENTIFIER + + +VariablePointer ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX OBJECT IDENTIFIER + + +RowPointer ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX OBJECT IDENTIFIER + + +RowStatus ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX INTEGER { + active(1), + notInService(2), + notReady(3), + createAndGo(4), + createAndWait(5), + destroy(6) + } + + +TimeStamp ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX TimeTicks + + +TimeInterval ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX INTEGER (0..2147483647) + + +DateAndTime ::= TEXTUAL-CONVENTION + DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d" + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX OCTET STRING (SIZE (8 | 11)) + + +StorageType ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX INTEGER { + other(1), -- eh? + volatile(2), -- e.g., in RAM + nonVolatile(3), -- e.g., in NVRAM + permanent(4), -- e.g., partially in ROM + readOnly(5) -- e.g., completely in ROM + } + + +TDomain ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX OBJECT IDENTIFIER + + +TAddress ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc1903.txt for + the actual definition. + " + SYNTAX OCTET STRING (SIZE (1..255)) + + +------------------------------------------------------------------------ +-- Stubs for standard SNMPv3 Textual Conventions defined in RFC 2571 -- +-- See http://www.ietf.org/rfc/rfc2571.txt for the actual definition. -- +------------------------------------------------------------------------ + + + SnmpEngineID ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc2571.txt for + the actual definition. + " + SYNTAX OCTET STRING (SIZE(5..32)) + + SnmpSecurityModel ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc2571.txt for + the actual definition. + " + SYNTAX INTEGER(0 .. 2147483647) + + SnmpMessageProcessingModel ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc2571.txt for + the actual definition. + " + SYNTAX INTEGER(0 .. 2147483647) + + SnmpSecurityLevel ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc2571.txt for + the actual definition. + " + SYNTAX INTEGER { noAuthNoPriv(1), + authNoPriv(2), + authPriv(3) + } + + SnmpAdminString ::= TEXTUAL-CONVENTION + DISPLAY-HINT "255a" + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc2571.txt for + the actual definition. + " + SYNTAX DisplayString (SIZE (0..255)) + +------------------------------------------------------------------------ +-- Stubs for standard SNMPv3 Textual Conventions defined in RFC 2574 -- +-- See http://www.ietf.org/rfc/rfc2574.txt for the actual definition. -- +------------------------------------------------------------------------ + +KeyChange ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This is a stub. See http://www.ietf.org/rfc/rfc2574.txt for + the actual definition. + " + SYNTAX OCTET STRING + +END + diff --git a/snmp/xtreemfs-mib.txt b/snmp/xtreemfs-mib.txt new file mode 100644 index 0000000..2bec607 --- /dev/null +++ b/snmp/xtreemfs-mib.txt @@ -0,0 +1,315 @@ + XTREEMFS-MIB DEFINITIONS ::= BEGIN + IMPORTS + OBJECT-TYPE, MODULE-IDENTITY, NOTIFICATION-TYPE, Integer32, Counter64 FROM SNMPv2-SMI + private FROM RFC1155-SMI; + + + xtreemfs MODULE-IDENTITY + LAST-UPDATED "201107251000Z" + ORGANIZATION "XtreemFS project" + CONTACT-INFO + " + Name: Michael Berlin + Address: Konrad-Zuse-Zentrum fuer Informationstechnik Berlin + Takustrasse 7 + D-14195 Berlin + Email: berlin@zib.de + " + DESCRIPTION + "The MIB module for information regarding to the monitoring + of the XtreemFS Filesystem. See: http://xtreemfs.com for more + information." + REVISION + "201107251000Z" + DESCRIPTION + "This revision of this MIB module is intend to be a first + draft." + ::= { enterprises 38350 } + + -- groups under xtreemfs + + general OBJECT IDENTIFIER ::= { xtreemfs 1 } + dir OBJECT IDENTIFIER ::= { xtreemfs 2 } + mrc OBJECT IDENTIFIER ::= { xtreemfs 3 } + osd OBJECT IDENTIFIER ::= { xtreemfs 4 } + + + + -- own declartions + + -- This datatype is used to model textual information + DisplayString ::= + OCTET STRING + + -- This datatype is used to force the code generating tool + -- to create long values instead of integer within java + Long ::= + --INTEGER (0..922337203685477580) + Counter64 + + -- a truth value + Boolean ::= INTEGER { true(1), false(2) } + + -- GROUP general: It represents information that + -- all services (DIR, MRC, OSD) have in common. + jvmUsedMemory OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The amount of memory that is used by the JVM this service is + running into." + ::= { general 1 } + + jvmMaxMemory OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The maximum amount of memory the JVM can use." + ::= { general 2 } + + jvmFreeMemory OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The amount of free memory the JVM can still use." + ::= { general 3 } + rpcInterface OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The interface number associated with Google Protocolbuffers RPC + Infrastrukture." + ::= { general 4 } + + databaseVersion OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The version of the BabuDB Database which the service is using." + ::= { general 5 } + + tcpPort OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The TCP port on which the service is listening for incomming client + connections." + ::= { general 6 } + + debugLevel OBJECT-TYPE + SYNTAX INTEGER (0..9) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The current Debug Level the service has." + ::= { general 7 } + + numClientConnections OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of active client connections. This is a indication for the + load on the service." + ::= { general 8 } + + numPendingRequests OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of currently pending requests." + ::= { general 9 } + + currentTime OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The global time in this XtreemFS installation." + ::= { general 10 } + + isRunning OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Returns whether or not the service is running." + ::= { general 11 } + + serviceType OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Returns which kind of service this is + (DIR, MRC, OSD)." + ::= { general 12 } + + serviceUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Returns the UUID of the service." + ::= { general 13 } + + -- GROUP dir: It represents information that + -- related to the DIR. + addressMappingCount OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of address mappings currently registered at the + DIR" + ::= { dir 1 } + + serviceCount OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of services currently registered at the DIR" + ::= { dir 2 } + + volumeCount OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of volumes currently registered + at this MRC." + ::= { mrc 1 } + + + ------------------- + --BEGIN OSD Group + ------------------ + numObjsRX OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of objects this + OSD has received." + ::= { osd 1 } + + numReplObjsRX OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of replicated objects + this OSD has received." + ::= { osd 2 } + + numObjsTX OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of objects + this OSD has transmitted." + ::= { osd 3 } + + + numReplBytesRX OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of bytes belonging + to file replication this OSD has received." + ::= { osd 4 } + + numBytesRX OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of bytes this + OSD has received." + ::= { osd 5 } + + numBytesTX OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of bytes this + OSD has transmitted." + ::= { osd 6 } + + preprocStageQueueLength OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The current length of the + preprocessing stage of this OSD." + ::= { osd 7 } + + storageStageQueueLength OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The current length of the + storage stage of this OSD." + ::= { osd 8 } + + deletionStageQueueLength OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The current length of the + deletion stage of this OSD." + ::= { osd 9 } + + numOpenFiles OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of files this OSD + currently has opened." + ::= { osd 10 } + + numDeletedFiles OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of deleted + files on this OSD." + ::= { osd 11 } + + freeSpace OBJECT-TYPE + SYNTAX Long + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The free disc space + on the partition this OSD + stores the object files." + ::= { osd 12 } + + -- traps (don't work yet) +-- generalNotifis OBJECT IDENTIFIER ::= { general 10 } +-- +-- jvmOutOfMemoryNotif NOTIFICATION-TYPE +-- STATUS current +-- DESCRIPTION +-- "Just a test notification" +-- OBJECTS { sysLocation } +-- ::= { generalNotifis 1 } +-- + END diff --git a/tests/.project b/tests/.project new file mode 100644 index 0000000..2558d0a --- /dev/null +++ b/tests/.project @@ -0,0 +1,17 @@ + + + xtreemfs-tests + + + + + + org.python.pydev.PyDevBuilder + + + + + + org.python.pydev.pythonNature + + diff --git a/tests/.pydevproject b/tests/.pydevproject new file mode 100644 index 0000000..aa248f7 --- /dev/null +++ b/tests/.pydevproject @@ -0,0 +1,7 @@ + + + + +python 2.6 +Default + diff --git a/tests/certs/Client.key b/tests/certs/Client.key new file mode 100644 index 0000000..245b614 --- /dev/null +++ b/tests/certs/Client.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDQa6CzhXSUtTjoKMytOjWU+krFNRwAYJgDRt8icIMp9k9EIzR2 +P10YD5/S7d4CtgrIeH1e3Hv6G+YphyX6qt8pJLbpQEWNz1LksUPvxgJ6QsmBAwom +b/WCiaV6J0+f5awYHLrzJg1HejTXRnsUdBxRVGGmvbx88MqsFADuz0l0mwIDAQAB +AoGBAJL1wRu0l46f9h9lXWUsLUn97qj9mN//PFDbMU00bpgxEJVoCX7zkO39XmG5 +zhi1SgcvRp+T8mtaLsHLhREqWS2Aqam+7P2l4o+445UIMmefRliMS5WdwgMW7pFT +zuYYbowrvOYu07UYKoZV0DnQ2C6vFJW2LOdnLLaUEprd4R8BAkEA8LhI56BvD0mt +ga+r6ABOMYgimhWaCJkvanAK29lleq//ygZUt5PkYcD/SqgGalb3vq7EoHN1Oivf +U9Y7bG4bGwJBAN2meYUhkCrTYFmDiQtEKzolE/ZnBJlamkfx4BgfiUq2OUAGYZ33 +sIgZLSrcHU40Qm1KOIllj/3+md5kFoHaJIECQGCpz/Tbct2Tu43hSknOnZe8UBDJ +7eHYCbdXKLUh9mMu+6tXoXtacxJiGuIS2QioxbGXorO/yWpDpdmXpKMlD9MCQQCg +QzB2XFA7Rt7RmlPKu51ty0Vl0hL3NxV6k57ukk7YoG1Ap9yJNYCEx39rEAB4fTzS +fOnoHnFAu4hRzpifhzUBAkBpWnOfkeG8cEvFQfOcfFdR3rSxYZ08g5PiDjekzHDx +HukVDwDo5ibCP2dTEyjXFTnJojXzMUYtU3n7ynLRB48Q +-----END RSA PRIVATE KEY----- diff --git a/tests/certs/Client.p12 b/tests/certs/Client.p12 new file mode 100644 index 0000000000000000000000000000000000000000..2b5c8a77ee97222e9c2e75d388537444a5e299ca GIT binary patch literal 1669 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 literal 0 HcmV?d00001 diff --git a/tests/certs/client_ssl_test/Client_Leaf_Leaf.p12 b/tests/certs/client_ssl_test/Client_Leaf_Leaf.p12 new file mode 100644 index 0000000000000000000000000000000000000000..894696b4f1a175f1966b295f49965a36b0d24f6c GIT binary patch literal 2288 zcmY+Fc|6oxAIE>gjK+lQ>%`c1#*!`7Sh8dpOHq?Xnh>T&mMm9;A!JXuY3xfExyUv| zq;VyNFe)aKVibjuAxl@TUa#l5J_r~Rv~WdRALqWOG!gn>ADE7pu3bH;Tjo>O)q+-P&H)f z#3*A2sg7XJ*v*-i*>2%^VB(lpJ2>fg&+t`m#(7(FZ;jMz_nIt0qut zUj|Kji+a5=7-kTB1+88U3M<`TiaFpi$!;TzYbuTB9sM3RQt^=6ER?-I;URfX_pC>Y z3#{fzpO<;W=E01|P$P%KStCM!W@&}PPnQKNJR(W-l`5bJ-Q3-DVzmbHeFK|iO$5n&FF3Yk@wD4*ydh5BKF={sAR;KI z@1Z_>@oL&9(~%aoPF`g!^fzM%$(7ztkFtsjffkvI-Q^(O)KrCQUeA&bH8p$&O!6-K z9Tm}_yPx_}A969@Q5jMlj&6=TH3Gp*cg24AxV6~M8$Ge}0pwXg+ZwK4Tp-_!5PpjI z@e;HVGc>$m9eg}0d|v3$_$6<$g4{bqMp9Kw`SNGnGx5*?ngt)vqw4zJy>Ct$^R8c7 z%ZE~VZ0%%lERpeJmio@3@2Gv77*ALKRs+Z3C^_N7Gb5Y)%x{}V71hK8lbfgk3F!h2 zR_g?QJLRW?ceFbb^t10t7(Qj{-0A6g;+G7z9+O;9I7=XF-vUc;t1>s(y_2^)TjnV# zQc}4W6^~>~W(`&54`=#H%Sxu-Ehm4$wYrM_{G z%AhlH;4_}{I$LvX0i9d^O^uDK>XaOaxB$y`Z;E&dbt`W-tgU5T?r%VwG7sjjidl1f zBd3DTscIE898OEJQv1U*h+f%?DOBi1Kxe_s<3Zuk_EMa9oA0JbKAlV&w^7A*A;EiF zB{X=JG*js1u)MBcvOtle0_|Tl9Wt-E&CuwdX>`#G<%h?EHH%lIw~k70teLYI4L+x4 z`$u7JQ|HbM*Seon@ypB5<^XUpnM=aAyG+A{vYjx5-}4)sYho@gF9)j4(G`dRIC>ob>3dNd0; z#&e;umIA4x%~b69?nXL`2lW7gU-UXBma7D3 z(*lk=fvcM45LV)BtTt737;p2&K^G`9f7p!Xq&O3&){jxo#=`3F zYkB8zq?iTenc#I3iFwfC1g&%ys{6b9ldC2>7KlDNwM&#v4*?JECBY>wElVExmsU=mkc zCv>5G(|AjDCmrrZjjG!jWMto81N<7{s%|N=#Jey2(~9QXQyq`3`T6cOOw(y~AEjWI z^sjM5Ud#sF8(dgtMQjOYU@yP!s(jnk%&!soydX+2gJVTYGt3nCKsrG%@Qz`PXxjXr zRCuepJO;Zff-7G!z!>!i9M5xjaWGle3+~taEutg<{_w?v^hC;y^UBQNcr!&rLdO;? zgbec+(izc_ZLz%4;euRzIE%-V>4U>+dF&67V$V@GCD7C~8EkqYGs0R$cfOF;GhI|SEF5NOYHc-2@8I{C{_*wS7_(gms=o} zjoMzl62Izf(S1mN$YAkT7ETye8d;6;Zq4*@5B5wKz9 z)fy5HD?&;}b1j_-h3@c~kgMe;M6}ww6shTi8Au)Jt0MbT4p?B}`Pa7kX=`BL74g+X$PlVj>PY%471dzjBzKSjN=QrxG5zV71|_BDbF9-= z3v}3ELB5V&x$_jJ7mQT=_f_+X>4}3yDU7}DzAMqi%9WvXa9~W7j=;?&r2Vf$qI%}C zW`Grd2Lb?J;2IDHAOJPMaliHf{Pye6eeS={eSyn>)_#xwH?aaN0Cl7uQXa|61JM-V r=8}d0V9|kE^rC59Sob-f$jPu;%1Ik@oFEw5dfvr0zflbIb5Q;PcoQMG literal 0 HcmV?d00001 diff --git a/tests/certs/client_ssl_test/Client_Leaf_Root.p12 b/tests/certs/client_ssl_test/Client_Leaf_Root.p12 new file mode 100644 index 0000000000000000000000000000000000000000..396eae9c5c2d18587c1401fdef58d22345008a0e GIT binary patch literal 2288 zcmY+Edpy(s8oH_pJ40iorgh<|qw1VPcl5Low^hrx0a zybcV80WoBL*jOgUt0hdNM{}&vceP`=LCETpiSrBqrww}H5|3$_mLUw1DLO`pX49m+ zZ$Fq17d~d|y8*`Rk_(wkn<6Bt?~9kUJgIKyoA6C<_`-e8tE}O_8haKLhYrr$)AkSG z_8eq9m9id(Ve5*3iGWVaDH{MQQ8`p&R%T9kHmar=v}otp+35r%YNq3@lHWbIYzD8J%qclNiJ}AQg0M_ zrLe&et9*TF8^yDD`D9Sp%DMhc&7c$RoMnsb=atZxlj29jvgIZsg%5A4yT?z~mvx*Q zcC^52Sa9sEVjWM^#s^XV`r-NTWn)>44|+3T-7Ra&5ycQprQI!V$r=fX9l)q+>RB+b zxS<-nVNI0V+r&zp8M!FgZBT>v%}~^V0>!_}ih3*-l$T!|QdGh17_vF}H6}6oGR(E& zQT?RBw^Jf#cnea47uzXbE>$LpLML+|gF!FPA0VurG&?oDAt0E09i1H8#ivhNtP!(3 z;BKVo5kMaN+7qLJkq zG~-^A1Fqgy!ENGHwc|c_BX6$;o3re=@?ztbxq8DQ{ro$rwwV>dJxgRVbVa&`7rD_d zi1^ggT5{%fr03}J711f4>qrK-?2HUruU|G1#EF#ssWUH9bG;I+aknRLb-R@3>!8P}E~&ZRn9Bc6#O zH?31f5&3zLH{Y?n<<+ufZ(&pBKd8REQADb!lSb0Lz_3G4#LY(T z95kwJ+|t9PONoVpFtobC~QmE#_rP-QtFAFycMfUr_V1MF5%-rOyIUe`t4GIw1OOH=Jq;*Sp;@q=oL zD{*I+lT4W|Kc8B)0X}JxJlBu4srDyWC#pQ~$mE%y(HrO+g^ogxt*IuDnmZ2AO$B3# z{z`pZ8{+6YXbO^j=y=c3h+r+`bLJ!uD{fw%7NPyRS^w0mo$OXS4lPV9D50jnW1eyD#xQ~~p zO+|}IH)hMY{;b&A&iQO@t2%M9;?0YKgUBaQ#_wCbbLEKTldZvp^MQdgRr}}+#p1UD zro~Unu*V(_AJH3_VIm>7B}<U-O6<&5pEjAJ|Azadd`4L=P6*`mpO=Kmv3 zI+;%oLgvHlV$I#F4&Cz~jUqr`IvHGyCWG_;&#rvG?RqVPxER2v6#3h(5HdIh(Pn<3 zs(T^@zle@JS=R@+dO~Bac*~vL@3UO=F|zOE%)~Z_vD6(_c5)ps4gAy7gTyIKjkQ$x;KG>l+pF$- zN`x7pzM><1{iN+3|IPqbj-)H@2j^6UXYA&SdrSVB+6Wsjm9_$xbdl#}f$i0K^*QAS zB-$#JO&|+L?I;fqeyNC2*7_=;En88?+oJiZnLQ?`UPQZ}s|!(Br*4KkkPk$!;S2g! zabojmv(p`qq8jL*`U51Sf=gFk8MK7vtJIj*R;%5oZvHiME{kUT}yyM^d7(vDZjcGn+NW_}MyBYX#)ws}nk}F<{&FQLDrLYu?P2Zm; zG_>aWs#7qEbNf_B5WPOGK`3zP3B{S@G$rQIw_>!KE zFa>jQ(buKd+Ui!5DI+57uaD2wolm_dk2NcHceH#g+?pw^ z+ld?}T<;JKa|Mn3?^MJ0Vx%CF&xdwizBzxLrcxNv3n4~?YY9hk&^CXHBr!$`M*uS* z0Js3)fk5CYpa`e|_Pen!K-i5#cDes9#{+%JN4Vbv)V*r5(UJv0nkqOHAy(s?zMj9}- literal 0 HcmV?d00001 diff --git a/tests/certs/client_ssl_test/Client_Root.key b/tests/certs/client_ssl_test/Client_Root.key new file mode 100644 index 0000000..a13dbec --- /dev/null +++ b/tests/certs/client_ssl_test/Client_Root.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAM+qNWIFWk6S/yD6 +3U3N5yhP0f3pwXpnzEn5ZcUb1SiSX5wvK6AN+LCUFmrbP5mEpVaYWAdesbb2De4K +W8c+B7iN+utgUsRPqqSIZUkQCqzI+md1z8aztqWWfft/smvKb9c1uJxSWBDkGWfS +eYEFwvJ2nCqOpb0uHIVCU1RLIUFrAgMBAAECgYAcI0P4dCE4ZFKNdXBnCm831xjs +/q9olofnvhM8Eflf9fVehEW0+i+oPWiMMgj8FC0S/rFuzjXmRJC+oEivRohlCqhc +0YOlodg1xtB8gSz2XXTj0m6BpUmorqnAXX2IO7lErhCRi1LSKjbKJB7gcLbwOAcc +GLL3X8pcXY6QN2WGgQJBAPniVKGwkiTtOA+O8JDhgwthi+i1yDMzZ1wbNV/BIf0p +Fi+YEFa615BCrVYFq/vvCUwlAxBECpc8ikq6WOj1PUUCQQDUv1mSzOMiCcX8Hb7Z +S4pOG9GnU4jFYD7pIjmxTOoNz0aUC1cOZmgAF6QH9GSAnta+x8GPea5byJEcLvTB +BrbvAkBW8eRGmhxPkuaFq1OS5ZRmGlvG7bEp94HIL4NjvNxprKkWiE9vDfXBMSIE +o1aTAzn1747gUvxoYN0xYSNcczANAkEAheZpWhvaWPINykBufhUtVzvrGIVa799D +uTfxV8YxCcALi+IXSNjrXCOE+fy3xLw0LJ9NFCBhvSLfMf3bziGLwQJBAKMm6lpk +e5f9xi3WMR4Nxi0yXh1bZQ0pVFxXr4A4sLAfvnq3xovEDklMoErarv0DLXIp4HBr +Dhveh0nysPpbn3k= +-----END PRIVATE KEY----- diff --git a/tests/certs/client_ssl_test/Client_Root.p12 b/tests/certs/client_ssl_test/Client_Root.p12 new file mode 100644 index 0000000000000000000000000000000000000000..b07a71aa236b59383c83f478be4846ae5429f147 GIT binary patch literal 1670 zcmY+DX;9PW7KgJD2?7Rzuowaqh-o02gk7Kp5s1hV)>|V|L}>tJ2Vs;V{$;NsV2mgX z22!AG0Skge1+=n;rG`cBWh;gyR3$)z?4)t#-r757&YX9ibLRc@dx!uWfPkSy08WJ? z@afd_btUjVFdKkd!vMIs43mfeWc|wu&ITYN8JdNFL9#LVWdkOn;R^r#K@kimD#PS$ zgnU$I!2@LoL>`m^K7DB{ zEZ8feAG1DoXC*Y;3;L%~d(3p^&-(ieO3YRHeSk74k@do-(OrB%pTi_RMa&R>TN*J~ zFr)WlcaM0xw4P-aMJ}J;7CLC;EScuNn(4`*IvFB2??uh+Qk|hK|5`-H7B@JcEBv(Q zH{)8K4OWEb2haDdM!r6Bd{CltQE8)(>$H(8OleT)G0=BvT`Fy>Cm-+qcl()ve)8oI zXXTXkAnooNi@-NWd5H}1)SD*(`;q4EN%g3q$-r8Uca9Qj>x0@`yu4QILPo}(wP`!| z6~rx|O`X51tIsgs;5_$`D+&Rb z_d2}8!nsG|Y)Hzx>+$T5#fAmmU+n>x1ksfR;JTRqbXV_$l-*Dbq*rM8H@+QwJPND? zSO>Ri%uZ$7t+N5+It$_2D{+=@(PlKuup(1|$$LzVNywcFp<3D=w;STJS~^^BJ`2o! zR|=4Anjp+skhG*bZO%_F5x``dWEb{LN2cQZlUwYYA9ZB1JdnIAT26V}4YTVbC$Wp2 z6K@N4f128QvlFnd*SY3hxCPK^W=e#!?GdaDJtJRaqsrchiu&}e8_ zH8R;yyJsnk7iD%_NkIp4PVbNgxAI080Kxz}W!Q00uyHW%!V+HQ@XI7k33PMCL`g zOo-C|vjFZi-tJz&z9iJ_L0g#k}yRa;7^HEWGS0k3172Wt;JUqmVJ4yAiMy`T| zELhuq^Cz?R5$vbszFmsSoRKNXFKLkW^`-`Qy2@65u%_JB%uU~F^h0`O+r zAup&)M@k}e*{!ndSUhfad8l*w@uxLT2|40V7R+Cj!Y&K4kCo8ZFX7U7y1)mX;Oydr z#8t?rwGh}0^q4(b4nKk(BkSk|WY#r3>o4{ECUYVBdRFY28~Lo~UHEp%ucp^txHrXy z=#PdwME!{1eiyM-9!AZ9l4tX)yH0X{|3pjWX?-|)D@^^EMn=K}q?HQ3Em&IbECo{>RMo)=81J-H&V!5iIY8RTbJ0f^K3WqbGN+ z9@Ov$4-+g0VoIjsmR+;0k|QWCN-iYZ#sS<~b$Y>la#I#+hVMW5w&*4+OzW_Xp!?60 z*tHxsq6Gi^TgPH7iNQ!T8iyw^jmUmgYf}m(NzA!N=O}*3FU6`x%5Uy23KBNxu8#Op zen*2itIlKGw248}vs&?q_j$QtqvDy&9Nbe;Je0}3wtW9wWsAt|P+||oNk}lH)w zE^b~I-6nT*I_B#P3q)?6(i7(_yVZU3rl~}Gof8%5G_tO0L9s-SU_xRf^jfJ-@N7}O zPp?~D2u{>ry->HgNyteZm{8rgasYLk(0MnIfREZQoH26E!2z3$)rj|Ptc=!CR zheyh^N0CKqi literal 0 HcmV?d00001 diff --git a/tests/certs/client_ssl_test/Client_Root.pem b/tests/certs/client_ssl_test/Client_Root.pem new file mode 100644 index 0000000..78c8081 --- /dev/null +++ b/tests/certs/client_ssl_test/Client_Root.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICFTCCAX4CAQcwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UEBhMCREUxDzANBgNV +BAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQKDANaSUIxEDAOBgNV +BAMMB1Jvb3QgQ0EwIBcNMTQxMTIwMTU1MjI2WhgPMjA5OTEyMzExNTUyMjZaMFUx +CzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEM +MAoGA1UECgwDWklCMRYwFAYDVQQDDA1DbGllbnQgKFJvb3QpMIGfMA0GCSqGSIb3 +DQEBAQUAA4GNADCBiQKBgQDPqjViBVpOkv8g+t1NzecoT9H96cF6Z8xJ+WXFG9Uo +kl+cLyugDfiwlBZq2z+ZhKVWmFgHXrG29g3uClvHPge4jfrrYFLET6qkiGVJEAqs +yPpndc/Gs7alln37f7Jrym/XNbicUlgQ5Bln0nmBBcLydpwqjqW9LhyFQlNUSyFB +awIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAPYhIUtVrfrUwCa7kbbGWNWrO+1Qcy3v +g3WrC4QYjj/m/wu8ayd5t2HFjrr1Pe6S/77uF1ZFKvg+9OvlU9OmslV/GK2xHvEN +xXttTxiOFV8Ecp06CqAEsnHaBiGhCQfPX3uv5KqP5+LFiMWYI4m2xYcNdlvO4t6k +nl15aCU5Lxhl +-----END CERTIFICATE----- diff --git a/tests/certs/client_ssl_test/Client_Root.req b/tests/certs/client_ssl_test/Client_Root.req new file mode 100644 index 0000000..3bae9a2 --- /dev/null +++ b/tests/certs/client_ssl_test/Client_Root.req @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBlDCB/gIBADBVMQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYD +VQQHDAZCZXJsaW4xDDAKBgNVBAoMA1pJQjEWMBQGA1UEAwwNQ2xpZW50IChSb290 +KTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAz6o1YgVaTpL/IPrdTc3nKE/R +/enBemfMSfllxRvVKJJfnC8roA34sJQWats/mYSlVphYB16xtvYN7gpbxz4HuI36 +62BSxE+qpIhlSRAKrMj6Z3XPxrO2pZZ9+3+ya8pv1zW4nFJYEOQZZ9J5gQXC8nac +Ko6lvS4chUJTVEshQWsCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBAE+s3/S0m02X +zFhmuZe/8ZCBb699nX8qv9IQgivy/xnFg1lJ78q30n59Ym5/H8DWu3m2C+VQbCkR +ZAMf0AA/boFr/5gPtbZv7v0vRo+0Cxhj3wrXADfCqiX/yYxaMhFodtXfps80WJoJ +WYrS2bEVSzvwSIqVsCAqT3lAOk/r7Ps7 +-----END CERTIFICATE REQUEST----- diff --git a/tests/certs/client_ssl_test/Client_Root_Chain.p12 b/tests/certs/client_ssl_test/Client_Root_Chain.p12 new file mode 100644 index 0000000000000000000000000000000000000000..faf150dcd2b22334e7eb00061e58065e000be419 GIT binary patch literal 3470 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 literal 0 HcmV?d00001 diff --git a/tests/certs/client_ssl_test/Client_Root_Leaf.p12 b/tests/certs/client_ssl_test/Client_Root_Leaf.p12 new file mode 100644 index 0000000000000000000000000000000000000000..0810393766f4c2af353adfe4bd507f011126a124 GIT binary patch literal 2288 zcmY+Ec{J4T9>>447=va;nvs1h$!=ztEJNAGSW4n2#+p#JK_M;t!h|wLhLDW1WgEYQ zN8&4Oo|5Jh$&;?AlkuewqY#;mnR6uwcnDD=U*a3p!kx+Q{F4UCD z>k11n7!JhI1>oNgjV^ujewA3J-M@H$+1-&XF)cZzksg*`>`IU+ud&Z{YWVx;gEoO# z53Pl^FE`zKu7n%1+{{fw!brJS+U%Isyq@OO7ew2X>7!}BQ#(;0`Oo4M*39pAMNW5F|IMVO0c z;1|-Wjur2)yUJe7nAvqz(E7`}L~%ysL|u~Se$8-%wl?mH#v_%YmkelG?m-7u+5-&B+A0@+g%-( z4o=v0YG-wmzsBlLqKt3#mHUCWtY_k?*O7<(gY$&a66S03_{s@-t!Eppu&b<`&+W5%tX7UFB!b+4O<3wU6Q%Jef;;@k3iB)53b@79nAA zFQtN>f}LdMO$P~qoEQ7e4o;8k0g%eOJkIilGJcqtm5haOX4AY5w|qo2xJpEwXFQHk zCcg6)R{VN!@5XE;YS;FS5@lRw&jq zD(k{kGX-neY9^CGi!NbsdUmWS30^c!J}J~16Yi=XRYv)|?)qV>-qJHLw(t`^# zMN4)mn>bt_=pW9p;B0-fMc3H@pCI33tB$qe%zXdSlGQM}&bw8Uj1tmhK+Y>4HELzrKV6o7&D-LHkpD-V z1$4+hC>=uB##-B34JPs*jS7Rn1$1yJo(?YhKf6MH+qLSn34iEtYv^ygLh0bRuj3oe z-4}g?AM(+0dM7y_bSMpqK~FyNx=|B$w@^p-zBre+dR!SbSa)y!eu;?7WFvipmsxFc z9EUq+U3Cwu*xYX}U6jQOT01T8Wh5%srMHcy?#(wAE$P0l_rgTad!e9uG^1f_9-;#w1d2@L|xMS#nCw zhhp#eQz*aWj14paGK%bTL_abV`6);hwaq?PXHfT~@&@vWombfpq*Zf!%oOYJzD?QP zAH8moGo?-_Z^hp-J#g49KcLD$(ifJAZOT>6Kki9#8LeY5HJrkED-R;Mwrk@yF;c@1 z`x~{^9apBW?|wPSae8Z?xn=@8=*f0d8WY@FYOcW#+Fy!Mnm$6kozvy)g?+x>RfEdO zu9n3LTg;F)#+EzC23^=9$;Ti#q!ww7uIv=4Am3bp48;`pB=Jm7iBUq~N3QQ~aaCC& z&T00ob<)PZU9htk3?*GH#2_HA@1%8Pg=QARg&zga@zwn}Ewu9m?G>Bv^(^n*MLGSF zCUGrYCu9@U?y~p=gG3SPtJO%`EarK6FR;sv{e7vAzmYx4O~gJ=JDGpoRMamtNcvm- zoE#@h7gxc=-2M#IJ50hvciuzajOs92W>Z=T{?+DMDyvjaZfYVmuc*-}d#6FR#4-Km zQ?0{Pca;D{L@CaGgK!G3^xv))!VtuvXjZTHwd2fO?GmYe(Y)1<`V#oB!FZcLkI)2T zITBz2(11YT1P}^D0`h<=;0T0muirUhoBMC`6M!F}xqYW?r{loM?PLL%0cv;xUI8xz v6VO0Hz)}JL6m3g}jH#24wRkJN8_m!xQ}ofX6@bFsW@g>@4CcE39+ZCp$G-(P literal 0 HcmV?d00001 diff --git a/tests/certs/client_ssl_test/Client_Root_Root.p12 b/tests/certs/client_ssl_test/Client_Root_Root.p12 new file mode 100644 index 0000000000000000000000000000000000000000..e6cb8a78e58db6178cd83c832549bdcbba6bb8f0 GIT binary patch literal 2288 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 literal 0 HcmV?d00001 diff --git a/tests/certs/client_ssl_test/DIR_Root.pem b/tests/certs/client_ssl_test/DIR_Root.pem new file mode 100644 index 0000000..71bfb3d --- /dev/null +++ b/tests/certs/client_ssl_test/DIR_Root.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICEjCCAXsCAQQwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UEBhMCREUxDzANBgNV +BAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQKDANaSUIxEDAOBgNV +BAMMB1Jvb3QgQ0EwIBcNMTQxMTIwMTU0OTI3WhgPMjA5OTEyMzExNTQ5MjdaMFIx +CzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEM +MAoGA1UECgwDWklCMRMwEQYDVQQDDApESVIgKFJvb3QpMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDBiWuEPc24fcTfCiVz9z1Kw0KD3qUsm3p+OgJ7I5GiZ+qo +7eGrhuOIFKngtZZN/htbBGzNv3IlklxYrBhUQBiXPSpFRlbpS+PcQGGp+oq2OV6w +wwbAv+Y4UH1KltR1XxT5VdM0t7c+RW62cARxSxyUSXtthiyFO+btRwPrQFxl2wID +AQABMA0GCSqGSIb3DQEBCwUAA4GBADa1pwW9PzFZr6k3gOnrdzvnKemalH8wPyGl +JOqw+/SwGSoNemJfZW1gyeOrjL1aG4w0u3NQVthFVEcNTc+jSIjVtl+IawrROvLb +u4UDbDkjZC8GMKwOGNKwY54jV5Ly5KhbB3T9D/Y2I0hDVHFjpQ7u18c7nmSywEHR +JXZp84Ax +-----END CERTIFICATE----- diff --git a/tests/certs/client_ssl_test/DIR_Root.req b/tests/certs/client_ssl_test/DIR_Root.req new file mode 100644 index 0000000..6ac4089 --- /dev/null +++ b/tests/certs/client_ssl_test/DIR_Root.req @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBkTCB+wIBADBSMQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYD +VQQHDAZCZXJsaW4xDDAKBgNVBAoMA1pJQjETMBEGA1UEAwwKRElSIChSb290KTCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwYlrhD3NuH3E3wolc/c9SsNCg96l +LJt6fjoCeyORomfqqO3hq4bjiBSp4LWWTf4bWwRszb9yJZJcWKwYVEAYlz0qRUZW +6Uvj3EBhqfqKtjlesMMGwL/mOFB9SpbUdV8U+VXTNLe3PkVutnAEcUsclEl7bYYs +hTvm7UcD60BcZdsCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBAGuQrvQZFyuIpRRh +6rZsgBIuOg2IoWM2I0VQIBF8rxHY2c9H6yyJZAU3gebrMDP7AgigzvFfOqEBtQ3W +YuMwNomxp5NtFCbI47OBjcNTPrIvKDEbxS0eubSq9Er7/j2apPVHKx6NMiE1CxSk +3ufshMq2Xhuq9kSpUPiJrT1nC6yn +-----END CERTIFICATE REQUEST----- diff --git a/tests/certs/client_ssl_test/MRC_Leaf.key b/tests/certs/client_ssl_test/MRC_Leaf.key new file mode 100644 index 0000000..0741d9b --- /dev/null +++ b/tests/certs/client_ssl_test/MRC_Leaf.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMnUaHW5MnHdG4co +ADIyMRDWgq7SmJirZCjwUt6tsY7vazuxem80asNVtLX33VE+oPZ7Eag/XmTgyzFz +hK/7RvwEgKdNagfAexjTNsa5mqNCKgqQUVHfdUhu3DgdQgcW763HcV60RYRxIjg8 +n8g+5iDXNsWlHRX/8gudiVGjAK5zAgMBAAECgYAOg6jzdlsLVzRIlvbUpUlkBZkm +S1zP9dthGk9LVkBjoBIdG9lLMADRhVNWlrmiwxc+QoF1kQEPzh6usrkDEtX63tCy +rPV2cX2naJnnMw0+/fLoS38FGHRnmOfJoh1qXTDnONR5VaV9LEf2vmdRDn01jCby +UUCs7oJ/MJb90hXquQJBAP1/N2xUjiyiYqbqksumXzde0kysjuF6UxBRjU/c6sAM +UvpPJhKEXntwXbYAIGfdOqa8EshCE9n7x83XsFQl9WcCQQDL0pagYkItBH9MVAkT +Pw8gQT09U1yF2zvpTYfFya5r5QQf4FMh5l2l5PchpLyLrnU+MeMj9TvgysXKCPNu +susVAkAE83chpoUgWguTNwGm+Jjje/afiL9BqCH3L6CS7r2nApacTO9xbSRrRMaP +x3DalneOyh2Ty7aXi1Nbsdq/yf4BAkEAs8Q2yZogF6hhxiZQIsN5Sc+AfbgqYHzu +KGUTHOU2iz7gFmU5rSqK6ig5t1ieWuwxx/skBLDkcO0m6XxfiAERyQJBANY0ED8b +J92ng7yeEDG5zKmIZQymr2L/wScy8PeQlYIe/wT2BWiX7G93OklwaabHd8gjrVew +2X2CbqezB4+k4gE= +-----END PRIVATE KEY----- diff --git a/tests/certs/client_ssl_test/MRC_Leaf.p12 b/tests/certs/client_ssl_test/MRC_Leaf.p12 new file mode 100644 index 0000000000000000000000000000000000000000..c98c53da1ab31970b43c60d7935d59714f465088 GIT binary patch literal 1656 zcmY+Dc{tPw7{`Be8slo5YshU;jNgdJk)jbsO55a`rfiO|hJ?nknkI$hNXfKPgHbXy zGnBC87#kIfAtV`-X4`T_$rah@d3LwmKi=nk-|zQ*-oHLykb#VYLSP^RX^)iMbk6r6pcOQn4hPdNzMGJQDn9N)y2kjO`;?uTvH5X_-EVId&|W1)T0GAxZ4)2;R)d53|ACgm(wBrkAguw=<@P52p!zVxMfy zKDvs!iStCMRPXyy{!`%Px}@QEPVxw~qy4D>H$s&9~#q zPlUXV8`%);a~QG~HPw1`>_Cj?NNmsR+}0!`AFG@5Z}Q5}B*d$r&eUgm7;0(84ey!f z>6v@givx|e5c=N>*t3@INLNPmZO;X>%{?nN!}BW$=1SS)Xc{--U3C*J07_P98!c`o zdWCoiN|pmxRn%-*C)UQ5n+*pDV}(vaRNjPNSXvutFLEg|hTIVC&_;n&Dfh zpwGwgBPq%yr!?%H8y>~4%;iDzO-8W~xy0?XtUf+zAH1XOfd81)%fU8VT1c7>_RSr3 z4KX`$YENKh17}Y+q%qsvafs<+w(D@EgqwL~gWkoH(M|&V0xK2Kdsl(41&Ld(a_;VWP;`br z@!XLND_h6nE>ZX(17`jouvrY)MmPheDV5cvg+a>wgE<-kmFD55Gzg{tqaXH_{`Z%P zZ9g`7sDGs&&VbUfsvReYSKLm@*E>8u>>XTTu5^{1X)v4aT$@7<0h)0S&*>#ZWQVsp zjPW%^mLdEpA4i!qmF!_VEsq+$@D;$$-SJbNW6Zkbd36F_!))oG;?8P`&ogxD^CQVQ zv+F>yVVXrvBIXP+vy$s{Ra|5}G-8S_@R-BLSnf9A5RyVp2(iae4tVOW=i$DgUc--I!!=2d<23oPkvEMGH@ z8#xnmeY-`%W%9-7R@SDmFAX<-XuBfx#dP)tXjp&YollJjPKfJhZ(TGsnOR;8-6$4b z@D%N754zT3eaZ#*X(-Y!za~5|2Vo&bS^oJ7Pgpe*c>d!5l0Jzh1w4tbtV+8fwwIg7XK9*}Whzy}VBTXim>E$ZJW`f{D)ULFlfo&%{`E7?=8CF% zF)2k;=qCxs6H}Z-Y7fCxnRlG6>V=O?iQSQ#-jDu1zKf?||0?B{C^@|%=xQyeDxtQK z(*V6|if<7p`D{}za5nEeIso)HKUl~UR|c6FjmgdGm)00_Z+8Qu5r(ENs`g$B1#r{4 z1*}6>6Q+l;w4uLr1%dmBL0xFj(3qT`h>4vvm+D~XwAGLALA}TktX|B~rKP-Nl*Q~A2 z6BK7mD{h4|-^@&oxGmJh%RzpmKmHz#_X7?8rCL@EuMStORE_N0;dU>%*`{rIy>Y;G z@Q|(u#D6O6L-*hn|MmF-AnFnf3I{;c5fs{h zWzSmM0hNIkgD46DM3JPjE&#$7zgwtc5cW8LrMjaT?iBao3F|_<=Q)KOn-+pf(|ZnU75l}< zFO@RlRP8xtIB-_xuP+I?M`~7!mKB_0(}Nw%+M_X>nO;2Jq!^X6;t%LBw#+;G`d(d@ zf6K6?Cxv%;KBfd72Usn;N(M4*YR9`m2xA?V%urh4tnPD``if+HGfeq+)Kgy9Sv&|feY^S_&R8IiJgKp> z{o!byQ(EHmClbDc8}s|Ca|>F@OMg5#aP2qF#K_nN6^pgIoTfj$ED`^e+p*ojIPAQD zX$+Uye0;z3klR^Wyd|{dy(W43pi?)*zH%CA>K zeR#tW?IB)sGYM|tF-H`4WJv0n>Xo3CRRJlMs`#d5ZosQK(Aj=u8-RPK<#5|{Z=OS< zH0t=VA=N4Tg(335!W^k{VED>iL(XniCH|*~b{u)p?A@)1OPV&6-8nP$W@#i!>wy~s z+3S(9!edo}0&_Nga9Ye?@PEKA2H|)F2v?KJIBD-f$^Qp)IVen;hf-+}?)@MA@Ne`h zmT4b|ikWr%Mn3|CB_FR{7dx?I+`PYD;7o1xh^^WF1&h|bJ~3R7X@D~*YTIEvque!g zlIVQ1bTJ{)Eib}oOo5)ae>RI-wWX=KGu*I1O_bifP_0_G!RfpeaC3LDOY9Tj=21F- zsrP(-)Rl?GhL57FPfWcEQ-4al&ePa1#QTaOO%X&zV#!IbGlOI^_OhjGnu#Iu4DNHh zA*tA9`SnTT;n3%%ucK67+>33*usx}Iae@!NO-P3M(|pXM$3%(iY5_3*h#T^jJ>y-#1=-{5IfU7cpT~c0&Kbh1I8} z$;wyt!1wuIW(2nDKP0qcU_~DGFk8nM{|0tlk;%+B=NE6IF^o}FeFrxn?D`nG{gY2d zL<=1ECWzWJA;tuOzxH6Xwv4Kp!?Li5Vi^nfbzjx_pXX)?k+q3h#Gr}_g^lu_5f5!` zSI190r`%Pt%ar)`0TVDT$2?^(x5zEyetvIXtW_CsJ*AwOVfi)r!OEfXse(tm(T0SO zTZ89!wq-u6hz4O1p-aYtN=X{=la#6c>f!aS0TAA^=84VToRn{nVEr;q^(9dO8QXsl zBe0?s!X1=rW#`JdUz_8alJ7R_Cgn!Wgj~>7+4`6<`chr_JoLPUkJ3NA3n9mTth@to zMbzlMFN=pTS++>5wu4ri+m76Ip%#4@)}2Z70CfLLH5x}#Mku*e+o*@u-+vaYVl6n> zD{?aH!_ooT_ah~mo+bg}0C9m>L$o3K(itJGOVXVI355hhE<%DJfe?ul{K{*)`q(T1UMCC50{S)$MoYPA}Ja)qR93X`(FBq1-jwPS3Nu?f&sT@B4ng@ALlk`NDMQG>AaLbjTEv)VV;q zup)(!Krrc$E{YCmiDeC#4!-+lK}ZO@&sZj$l)6KFw0=Tw%3xR@nI`VTp)OM;4Qkftn;6x__R+|&YcRWiAR_tfXt&xz& zhf80+PbX@c?pz=#THG3ZiSSHRmOZcshmxKBGxJ2p#%Rry3Q|U&#CGaR;dGRCAwq*$ z$dnFv{zGLb%RIm`H@VFX^R~SkWZ0G&hTCs1Wnt#DV=cJXhEKg^rIZ-zmb;iN$$LzM z&wpW)bgMU9i~a7Yq{j~i36aHyCS}oCf!g1fRVP?jLyUD5R7=$clP^Un2tsc!QhDI1uX42L=e^>H)y>b}FV8u^(9=NffJ zd(VWqe9CPz$T@|FxXg`$=|0hn!-XW~a?im1ssKN;2UKie!#PuhT?H|!%0K%|TbOSx z=e&t~QPcTYl(|q8v1aTol^5bPs4-GQt!Wyfethy`qFS44(11M@o&xxt-EYlv7EY!S zFt=}F`wFVaS(SnKUB>K`+I7R9K277$+>$4aL6(cgF795-nzCfgj%nN4b`jpESkEN2 z?PcByxMn@&T;ON)YDl4abWPs|L-xCDW0%&H`~U$F7U~j0pYF1)m+02^r6Jwseod6c zt((|owAEPM{N=QeoycvSY`qbArbL2KMEPSMg<<|=)2Jl_a^JJbtOjj!!-g!))8G1x z(C14DkNc#1uHp(yEwC=Wh4jdAb@Mu=rq#l9Th@gCrpY)OamD%l<;JEV2F|*Ts8XGV zZbc9IO=Y+*YIXCa$Bib+(~q8fUtpxjwF-(vcHHI8QKZdhdgm;tX>Oy%VH7`2SDDfS z0!7@OU8L8Y!Gz$lcQ75P_aCsCbfglBj#LoKcyY-<8~?!^g8;>Os1OIC?0@tlztW$Q zz5L8~R(<^|{U|y}gY6b*CD}%`_DQ_tlKqS9G+O;d^@H{r+KvZG#`!W=9$2vQcPsWS zUUPTzDqci~4Lxejif7-7(R-!b3# zbnukj;uap0Q^cLn%UiZS)`(4at(r1o=)WY{sxRRrd)WAz*}L8&4t-;cyby!kT@sls z#e~Y<=0AjZmYtk$Z}a0^t5ZR${#OM_Iystc{5wSn(xL8ESAsCvJ!Z=dTW-zuuF^WL zDS*ndLC)+_EhT#`hU;)`oWH}8>4!_NBHnmdQOOU@1PX5*<^-z{+hQPSTBZl_sL911 zDJL%}sZa^I4?gz%AYtr!camqbSLKdNaX|3Mlw(4Qzup%m7W<}i%ygcr{INAyX~w7D zL3l)cW#Updl z^tziO1$t!VMrUtsx$fu?GaIc^`!TVFp&ODDJ2^Sr3oq^O*E)UQX%L<#(mdnL6Y~4B zWNV4i4`;Ry@a^`Q!BXs4ko$tPHmFocYBGTRRa{b0 z>nF8&yfdu-?MP0apsWr!0j|J7KouYYWZ)&cgUFlru=X<}Ujy+M$r<30 literal 0 HcmV?d00001 diff --git a/tests/certs/client_ssl_test/OSD_Leaf.pem b/tests/certs/client_ssl_test/OSD_Leaf.pem new file mode 100644 index 0000000..5021dac --- /dev/null +++ b/tests/certs/client_ssl_test/OSD_Leaf.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICEjCCAXsCAQkwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UEBhMCREUxDzANBgNV +BAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQKDANaSUIxEDAOBgNV +BAMMB0xlYWYgQ0EwIBcNMTQxMTIwMTU1MjE3WhgPMjA5OTEyMzExNTUyMTdaMFIx +CzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEM +MAoGA1UECgwDWklCMRMwEQYDVQQDDApPU0QgKExlYWYpMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQC9/NT4zroACQsO1Uzp+zynqNtYpNPmHnuFDOKheCLFH1fc +eX6eYmO8zs0UuZCiWVivIiSBV7jHTZho6WK88lBBC/piES+MWfRvNy3lT4QDiGT5 +BfhQCeiJ1MILIrYpsAtqhT5lwrB1NOQxkjgipkFfG/dAUXfs36V97z0q3uPkzQID +AQABMA0GCSqGSIb3DQEBCwUAA4GBABc58hS7E0GMJy7BorqPGCOAi7+CyWVYXTKv +9fP1d1oTxbZP5hGN9gtwERdblIfIiiXB6oXneIh+EiltF9uiAAK/7vvXDRfVG7tl +iYOk8bNFfx9x5vzaHjsf4BSOUwCj0m+XBr8/JzTqW5dac4xvXkzepdobrQcZnnPE +P2a1TaMF +-----END CERTIFICATE----- diff --git a/tests/certs/client_ssl_test/OSD_Leaf.req b/tests/certs/client_ssl_test/OSD_Leaf.req new file mode 100644 index 0000000..09c8626 --- /dev/null +++ b/tests/certs/client_ssl_test/OSD_Leaf.req @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBkTCB+wIBADBSMQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYD +VQQHDAZCZXJsaW4xDDAKBgNVBAoMA1pJQjETMBEGA1UEAwwKT1NEIChMZWFmKTCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvfzU+M66AAkLDtVM6fs8p6jbWKTT +5h57hQzioXgixR9X3Hl+nmJjvM7NFLmQollYryIkgVe4x02YaOlivPJQQQv6YhEv +jFn0bzct5U+EA4hk+QX4UAnoidTCCyK2KbALaoU+ZcKwdTTkMZI4IqZBXxv3QFF3 +7N+lfe89Kt7j5M0CAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBAG9odQlLPwYCjIbp +wNWr41/6Xaqmd3adf1OLdr6uTKk4hjSHSK27OAmPUKaGPlmd2hpBCI3vRqTk7ZEj +5T6QhxMuI2IQB7KaDUVlT6toftv8iChU/urQ38nn0Wh8BAqJrx6WEfXyFmnmBbnW +2N5lLVVxdZfZVz3yNdihU8SgCO+5 +-----END CERTIFICATE REQUEST----- diff --git a/tests/certs/client_ssl_test/OSD_Root.key b/tests/certs/client_ssl_test/OSD_Root.key new file mode 100644 index 0000000..28e3396 --- /dev/null +++ b/tests/certs/client_ssl_test/OSD_Root.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKPq8iVcuxUyKd2J +paXzybVd0I02ROMoFRrP+IX361T9ejNTNhimx4Nj4nZwT/2kKmoJOJXRiLBzRPIy +SNo1Mdhb/otXDnnkZHDNIUxizUO1maI1OcgwuKbYOHr/PE33nJkzRq8vrlEn1AHv +G01aqrKcVCMJkSUgMKelAt4ZcjrRAgMBAAECgYBQv0Ahn5iZTGjLNS9gnMNUkK5X +odA1hl0/JAvtEr/e0i8McYVIh3/o/Z9lcNY2wFQUgA5b3yhSo7XnCVZSB7pRbMcs +5CoJYJDdIK1MKDsHdYmn4a5xsxlb64aJ6p0B8Ar0W60R09hXJ0xKejPXw8o+11tQ +t6ohQ92JNJa7F2sSQQJBANAEkOYrPD7mIOlD8brtrOMzOXlXecf9l9mWn4rUb2XM +ALKcpga/z1RQ1PZiCRfPMlQTv58wYtvhGzy1KGZWrS0CQQDJukY4wSGWL/Q2H4tE +ofZqvDJHTNJoxRbis1KcqkB57HkctThx5hP0yh2p2mWZp68WBicQNh8vq+d8cf+O +EzK1AkAKKp72UNih7ldfby2qSCFx/Tfq4UaXaqJ4RO9JNra3D/BcymEm5Ur5wPWX +kRUGr96y00BDRHcgbfEJ14TA862FAkAXVbnbxNN6yQ9J13pHtSiJDj4Oq19HiUzt +amrq/nK459bWsEvYORIj5eFqjX3lOVVyicGpCWmwHQWJCrLSH3xlAkA6h83j2t2K +b4A6b+++hrzxhm7Ehn4O9RBrSESQoPayAqMVUSgkjuW5cNR1ir8xHq4KEVZWcK+L +TaHuNwujw4cM +-----END PRIVATE KEY----- diff --git a/tests/certs/client_ssl_test/OSD_Root.p12 b/tests/certs/client_ssl_test/OSD_Root.p12 new file mode 100644 index 0000000000000000000000000000000000000000..ec1fc04b5d6b466d8c1d6d8eb5dc1c3eb88d7bca GIT binary patch literal 1656 zcmY+DdoeZll%cYsjjC(HgYqOE2+}GF` zw;HY2iqPaTQMuM4ilMbcZmBVb$Yt8;oZW5T^PJ~A&-s3z^ZfPs0w9tJgTet2xetjp zNp?+MQG%kNTo7rB0Fj0=84rLk(N_z}1z}?{=`{=rk&TyM9VnoK#QgO^5sCz`2ze`_ zII_r_9}9!YLy|xk@0Am?JI1y1M^;bQjbj;s&&JnHDx8FHm#N#kx2B{UyZMKvcdM@z zI7CP=F?S=TwUqyh(|L<~$l>pd5F4f!5oo`iXI`Tm%@aG9Bx`U!iC@FdHxUL_k&lCX z5fpx8oXY$}51HmSkE36S4|)&PcO($p03hS)WIFmPF2@|!E^b!BVMr-gUZl_;*e)>& zPB*rQ1seg+(`t2W?lls42aB4V5omCqm+}XjKINK4XOPaPl~YFNGXgM4>Q-vrIg)p3 z+4jtL9^=Z@D?WoP^?0CZuNk_8aEt6Oy&gLMot6eBUU!ua)cA{2*kzQq$tFd-#xDmi z$r+)#U*uO-53P)Jwlal%Gb(dsD~gFRT4DaCsMV_zPn%bk2lZOodWE|_cMokxRAIOu zdYxjrEaC~D>5@A3gCD}o>Syg=<;7589%j9X#EhHfd3z3iKUmTI({=a$t^q;Yop--_ z@y%l$jOiO*p^LYsRcjO04YpMz3Py7i4L?^IY=pnw&uPCked?RLWg+~&r5!itatGIb)hWy(1G{{+5g71jSfq))k6qc=rq3q8V{x1W)rq|Cvx>Suj2K zqMJzhc47X`zImS!PeDeDCBF-gioX84Z{ZcVhTaEn>awY#d;?4SOetmxmD^JGD~AlI z5+6OTc{rZ2zRfk6-w+fU$B)g6mJ9E3e1Kw7S?=RA?Q46)ct4~xAs`+_KKw$us#hiA zONxF$dAYaNA3 zD7;9_W?{F+axUE8BA#Hse`%O@K!M>@>e8bgmqjuFg~c%6k5>8nJ;Aw}rQ)3o;}bU3 z%xr{p+`#=?*6o5~0EF-Q7uZ}7u8RQSnlc$DYZauz-?&H4fbHGcIIYivld&#gk!>jVnaNC-;KUp zz97tkM)z0!f!s1Cr5XtDyGIF9ZC@?`mz0Y6;J(&FvwDm3*$XyLtaQmk)0HG*K+(<& zdnf7IS^JIp4~Lovp(`PUbZs@W8`wILD1b%S(`p@lX`A=^`b2xDL2f2HMqTa~((aDs ztT> zVd9zO_J4YvSHC}vXp)GMEm9^zj-DV1t+EPh%2na5m|_9>amW0TG`hporiD-V2DM{d zR|#l1Nlw6`72fj}Hz;o@jh%O_C*B~d`ft{Q*i)sdo)9B-2ix&3olynznYknJ3*BtJ zqR^I_J5TgYHxy1^!>KGRODEsV}wVm$e*4eerYU0~v6JWc1QpK6On&ame_lb^zwZbOSMV>G*=tK>)c zb4Cr=%6`Y#1GrMdz$g}_;;cW_<4xxqBQj|$SBLu?%n_1C#t<(Zk0hpUQHjFyEjBHu zOH_yNl}k(tK9(HbVGxq4@6rYvJ(IqpFp;-S6KA5eUa+uMSL1)!a@6iwwPxw$AIWv$ z*`JzS?|)pfe_|Z_-Qdt$s?8Z;u!E`1>jG+A@iDP)*ql$l&eG4Dc!$H11%>C#k!A_Q zjWpTTjXmV2wq324@o{+TvWIhX&!X+gHKto8(Fef)Lp2&lR7a?pZF-LX#C!wlg5XkaG|!BnT1+F$Rc$K7dBb unPTBEEjb86&AHS4DJwGY)nY6)wJ-e?+?P{m{Pjiv literal 0 HcmV?d00001 diff --git a/tests/certs/client_ssl_test/OSD_Root.pem b/tests/certs/client_ssl_test/OSD_Root.pem new file mode 100644 index 0000000..54819d3 --- /dev/null +++ b/tests/certs/client_ssl_test/OSD_Root.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICEjCCAXsCAQYwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UEBhMCREUxDzANBgNV +BAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQKDANaSUIxEDAOBgNV +BAMMB1Jvb3QgQ0EwIBcNMTQxMTIwMTU1MjE2WhgPMjA5OTEyMzExNTUyMTZaMFIx +CzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEM +MAoGA1UECgwDWklCMRMwEQYDVQQDDApPU0QgKFJvb3QpMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCj6vIlXLsVMindiaWl88m1XdCNNkTjKBUaz/iF9+tU/Xoz +UzYYpseDY+J2cE/9pCpqCTiV0Yiwc0TyMkjaNTHYW/6LVw555GRwzSFMYs1DtZmi +NTnIMLim2Dh6/zxN95yZM0avL65RJ9QB7xtNWqqynFQjCZElIDCnpQLeGXI60QID +AQABMA0GCSqGSIb3DQEBCwUAA4GBACNwpIsgUYmNpKDr4E1kz0VcAa1kigm/bmUE +IAbIl+/d3LBd+6h6Z6V88yRAZfpXUzjo3WstLSPt/82Xsm4N6iO+wBiCysv6tS30 +XhbY7LSYBAs/y3VmaL7KfL7+yUKhGdnXnjL7BzU583J4sPQ/dQwGDtPPrSrXWR93 +6Qt+CMn0 +-----END CERTIFICATE----- diff --git a/tests/certs/client_ssl_test/OSD_Root.req b/tests/certs/client_ssl_test/OSD_Root.req new file mode 100644 index 0000000..da8855b --- /dev/null +++ b/tests/certs/client_ssl_test/OSD_Root.req @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBkTCB+wIBADBSMQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYD +VQQHDAZCZXJsaW4xDDAKBgNVBAoMA1pJQjETMBEGA1UEAwwKT1NEIChSb290KTCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo+ryJVy7FTIp3YmlpfPJtV3QjTZE +4ygVGs/4hffrVP16M1M2GKbHg2PidnBP/aQqagk4ldGIsHNE8jJI2jUx2Fv+i1cO +eeRkcM0hTGLNQ7WZojU5yDC4ptg4ev88TfecmTNGry+uUSfUAe8bTVqqspxUIwmR +JSAwp6UC3hlyOtECAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBADanhdBP96PKTvMh +BCU0lEG49ASeRL7U6Tm89FHuWkz2bvv78gYMdxSXjPqrKzdt0C49IUAb0/xBQtLJ +AeXyNwx20g+QrtJxKjwuOZcOKMKriP8K9qSO+bdRx4/iEwXPlrG08Ejmp0GZ4ZDc +cos12mydlXs6/n6TjeaUq/75oAqk +-----END CERTIFICATE REQUEST----- diff --git a/tests/certs/client_ssl_test/README b/tests/certs/client_ssl_test/README new file mode 100644 index 0000000..cb64cd2 --- /dev/null +++ b/tests/certs/client_ssl_test/README @@ -0,0 +1,60 @@ +# As of today (20/11/2014), the certificates expire on 31/12/2099. + +# Root CA, self signed +openssl req -new -newkey rsa:1024 -nodes -out CA_Root.req -keyout CA_Root.key -subj "/C=DE/ST=Berlin/L=Berlin/O=ZIB/CN=Root CA" +openssl x509 -trustout -signkey CA_Root.key -days 31087 -req -in CA_Root.req -out CA_Root.pem +echo "02" > CA_Root.srl + +# Intermediate CA, signed by root +openssl req -new -newkey rsa:1024 -nodes -out CA_Intermediate.req -keyout CA_Intermediate.key -subj "/C=DE/ST=Berlin/L=Berlin/O=ZIB/CN=Intermediate CA" +openssl x509 -CA CA_Root.pem -CAkey CA_Root.key -CAserial CA_Root.srl -req -in CA_Intermediate.req -out CA_Intermediate.pem -days 31087 +echo "42" > CA_Intermediate.srl + +# Leaf CA, signed by intermediate +openssl req -new -newkey rsa:1024 -nodes -out CA_Leaf.req -keyout CA_Leaf.key -subj "/C=DE/ST=Berlin/L=Berlin/O=ZIB/CN=Leaf CA" +openssl x509 -CA CA_Intermediate.pem -CAkey CA_Intermediate.key -CAserial CA_Intermediate.srl -req -in CA_Leaf.req -out CA_Leaf.pem -days 31087 +echo "82" > CA_Leaf.srl + +# Sign each service twice, once with the root CA and once with the leaf CA +openssl req -new -newkey rsa:1024 -nodes -out DIR_Root.req -keyout DIR_Root.key -subj "/C=DE/ST=Berlin/L=Berlin/O=ZIB/CN=DIR (Root)" +openssl x509 -CA CA_Root.pem -CAkey CA_Root.key -CAserial CA_Root.srl -req -in DIR_Root.req -out DIR_Root.pem -days 31087 +openssl req -new -newkey rsa:1024 -nodes -out DIR_Leaf.req -keyout DIR_Leaf.key -subj "/C=DE/ST=Berlin/L=Berlin/O=ZIB/CN=DIR (Leaf)" +openssl x509 -CA CA_Leaf.pem -CAkey CA_Leaf.key -CAserial CA_Leaf.srl -req -in DIR_Leaf.req -out DIR_Leaf.pem -days 31087 + +openssl req -new -newkey rsa:1024 -nodes -out MRC_Root.req -keyout MRC_Root.key -subj "/C=DE/ST=Berlin/L=Berlin/O=ZIB/CN=MRC (Root)" +openssl x509 -CA CA_Root.pem -CAkey CA_Root.key -CAserial CA_Root.srl -req -in MRC_Root.req -out MRC_Root.pem -days 31087 +openssl req -new -newkey rsa:1024 -nodes -out MRC_Leaf.req -keyout MRC_Leaf.key -subj "/C=DE/ST=Berlin/L=Berlin/O=ZIB/CN=MRC (Leaf)" +openssl x509 -CA CA_Leaf.pem -CAkey CA_Leaf.key -CAserial CA_Leaf.srl -req -in MRC_Leaf.req -out MRC_Leaf.pem -days 31087 + +openssl req -new -newkey rsa:1024 -nodes -out OSD_Root.req -keyout OSD_Root.key -subj "/C=DE/ST=Berlin/L=Berlin/O=ZIB/CN=OSD (Root)" +openssl x509 -CA CA_Root.pem -CAkey CA_Root.key -CAserial CA_Root.srl -req -in OSD_Root.req -out OSD_Root.pem -days 31087 +openssl req -new -newkey rsa:1024 -nodes -out OSD_Leaf.req -keyout OSD_Leaf.key -subj "/C=DE/ST=Berlin/L=Berlin/O=ZIB/CN=OSD (Leaf)" +openssl x509 -CA CA_Leaf.pem -CAkey CA_Leaf.key -CAserial CA_Leaf.srl -req -in OSD_Leaf.req -out OSD_Leaf.pem -days 31087 + +openssl req -new -newkey rsa:1024 -nodes -out Client_Root.req -keyout Client_Root.key -subj "/C=DE/ST=Berlin/L=Berlin/O=ZIB/CN=Client (Root)" +openssl x509 -CA CA_Root.pem -CAkey CA_Root.key -CAserial CA_Root.srl -req -in Client_Root.req -out Client_Root.pem -days 31087 +openssl req -new -newkey rsa:1024 -nodes -out Client_Leaf.req -keyout Client_Leaf.key -subj "/C=DE/ST=Berlin/L=Berlin/O=ZIB/CN=Client (Leaf)" +openssl x509 -CA CA_Leaf.pem -CAkey CA_Leaf.key -CAserial CA_Leaf.srl -req -in Client_Leaf.req -out Client_Leaf.pem -days 31087 + +# PCKS#12 export +openssl pkcs12 -export -in DIR_Root.pem -inkey DIR_Root.key -out DIR_Root.p12 -name "DIR (Root signed)" -passout "pass:dir_root" +openssl pkcs12 -export -in DIR_Leaf.pem -inkey DIR_Leaf.key -out DIR_Leaf.p12 -name "DIR (Leaf signed)" -passout "pass:dir_leaf" +openssl pkcs12 -export -in MRC_Root.pem -inkey MRC_Root.key -out MRC_Root.p12 -name "MRC (Root signed)" -passout "pass:mrc_root" +openssl pkcs12 -export -in MRC_Leaf.pem -inkey MRC_Leaf.key -out MRC_Leaf.p12 -name "MRC (Leaf signed)" -passout "pass:mrc_leaf" +openssl pkcs12 -export -in OSD_Root.pem -inkey OSD_Root.key -out OSD_Root.p12 -name "OSD (Root signed)" -passout "pass:osd_root" +openssl pkcs12 -export -in OSD_Leaf.pem -inkey OSD_Leaf.key -out OSD_Leaf.p12 -name "OSD (Leaf signed)" -passout "pass:osd_leaf" + +# Boatloads of client exports. +cat CA_Leaf.pem CA_Intermediate.pem CA_Root.pem > CA_Chain.pem +openssl pkcs12 -export -in Client_Root.pem -inkey Client_Root.key -out Client_Root.p12 -name "Client (Root signed)" -passout "pass:" +openssl pkcs12 -export -in Client_Root.pem -inkey Client_Root.key -out Client_Root_Chain.p12 -name "Client (Root signed, full chain)" -passout "pass:" -certfile CA_Chain.pem +openssl pkcs12 -export -in Client_Root.pem -inkey Client_Root.key -out Client_Root_Root.p12 -name "Client (Root signed, root CA)" -passout "pass:" -certfile CA_Root.pem +openssl pkcs12 -export -in Client_Root.pem -inkey Client_Root.key -out Client_Root_Leaf.p12 -name "Client (Root signed, leaf CA)" -passout "pass:" -certfile CA_Leaf.pem +openssl pkcs12 -export -in Client_Leaf.pem -inkey Client_Leaf.key -out Client_Leaf.p12 -name "Client (Leaf signed)" -passout "pass:" +openssl pkcs12 -export -in Client_Leaf.pem -inkey Client_Leaf.key -out Client_Leaf_Chain.p12 -name "Client (Leaf signed, full chain)" -passout "pass:" -certfile CA_Chain.pem +openssl pkcs12 -export -in Client_Leaf.pem -inkey Client_Leaf.key -out Client_Leaf_Root.p12 -name "Client (Leaf signed, root CA)" -passout "pass:" -certfile CA_Root.pem +openssl pkcs12 -export -in Client_Leaf.pem -inkey Client_Leaf.key -out Client_Leaf_Leaf.p12 -name "Client (Leaf signed, leaf CA)" -passout "pass:" -certfile CA_Leaf.pem + +# Two keystores, passwords just like their names without the .jks extension +keytool -import -alias CA_Root -keystore trusted_root.jks -trustcacerts -file CA_Root.pem +keytool -import -alias CA_Leaf -keystore trusted_leaf.jks -trustcacerts -file CA_Leaf.pem \ No newline at end of file diff --git a/tests/certs/client_ssl_test/trusted_leaf.jks b/tests/certs/client_ssl_test/trusted_leaf.jks new file mode 100644 index 0000000000000000000000000000000000000000..d87c17ec8fef29c1bfa48ba3081a0d8c648fd57c GIT binary patch literal 603 zcmezO_TO6u1_mY|W(3ph$%*kfsflSozUSFr*ZLV)BlJuSEP+a-4Vsw54VoAmm>5|N zc-c6$+C196^D;7WvoaWj8*&?PvN4CUun9A{xEk^U<$)Xy9yX`cqMXb;m;gImfX9Ff zq=JiwIm*+?P{KeA#AD{+_slCvEy_(z$xJLsRd9ARP!Q)eG%++ZGB7kXF)+1=lHfNo zu(UKZGB$(?82D3WwSWO1#A8o=BS?e~mT1 zo;O#~>f`CFRBN_)z2dFG`+Z+8y3E$C|9LC<^2fKkZ`@NXjIDX7SpFhy$?3C+?KQu* z_e}JZz3#V8%eOB`K0Lhce2({?Y9?kz21aD(0Rx{I=q{nzf`RNCOO|9`I5r*w%NLe+7j$+uTVIe} zw3R=QXWey<1#k8%W@^;iiT$WqbD;c0ZvR=`hXjJ zpG~N@Vt#VnfR~L^tIebBJ1-+6H!FjIzah5)CmVAp3!5;Li>o0&P#(zP;9+x0Ey~Hv zg9)(11$Yd&Kq|O+n4>(M30UC zEG-R>o4~D>3QX6PWF=y8HQ(mvCS7A zE%tlg^6OdO^TI8xvnu%Zt^38MJ0aXLv2OdRzh~C=WzN zMX%p*>O5hYQk+txR20W`=Fv%AX7N<7533%B_vTd@^G)pj9Tt>(D_7^-Z`EX;->+rA zf1bW5p!(G5qgH)0?o}1s6aUl2x^csiZ%vP1JiKQx%W40QFGtTjcv-opFNWpwo%9dt au20ugeD6N>Sy^4Ck!@y+*YegN?FImx&(fCw literal 0 HcmV?d00001 diff --git a/tests/certs/trusted.jks b/tests/certs/trusted.jks new file mode 100644 index 0000000000000000000000000000000000000000..f08914919987a7fe5b0ec197b502f68162893c93 GIT binary patch literal 720 zcmezO_TO6u1_mY|W(3nr$%#Ow`lWx|O$@9NdZq@JK-sAVO-vIFnizjEaWed0-XOBw zMDMo&FB_*;n@8JsUPeY%RtAH{9z$*ePB!LH7B*of7gs}mpaLL=LzvAewJ0Yu4<^74 z7Z5cN2C3i@=BX$tN=?m8E7r>|N;l*)-~kD93$vD_7MBzo3Kge`F@VKL2%eE(Jc`gBIG!RPslvkb>Kq^p=; z%6K*V<-2E}7rfg#_3VR)=1IR)gDc}sf3kMgI4|j|og`7RXZra#FQdChZf9@svzK14 zy(hV);qFY$$T$1{^a}pfHMqEoE3xtT+ed7D+W$k+C+%sRQ5g8~=Se1JMg~S?=K-Ue z8R#w#qYFvj8@-NSebFbeMe}^V@qy*jPh_9wjtUHCerWUS!47WTgY3Iw{62eTR{XzX zvf}QLD$02b2vG5`Po literal 0 HcmV?d00001 diff --git a/tests/config_parser.py b/tests/config_parser.py new file mode 100644 index 0000000..ac5974b --- /dev/null +++ b/tests/config_parser.py @@ -0,0 +1,155 @@ +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +import types + +MANUAL_TEST_SET_NAME = 'manual' + +class TestConfig: + def __init__(self, filename, testSetName, volume): + self.__tests = list() + self.__system_tests = list() + self.__volumeConfigs = dict() + self.__testSets = dict() + self.__filename = filename + self.__testSetName = testSetName + self.__selectedVolume = volume + self.__curren_test_set = dict() + self.parseConfig() + self.applyTestSet() + + def getTestSet(self): + return self.__testSets[self.__testSetName] + + def getVolumeConfigs(self): + return self.__volumeConfigs + + def getVolumeTests(self): + return self.__tests + + def getSystemTests(self): + return self.__system_tests + + def parseConfig(self): + cfgVars = dict() + execfile(self.__filename, cfgVars) + if not cfgVars.has_key('TestSets'): + raise Exception('TestSets is not defined!') + if not isinstance(cfgVars['TestSets'], types.DictType): + raise Exception('TestSets must be a dictionary!') + for k,v in cfgVars['TestSets'].items(): + if not isinstance(v, types.DictType): + raise Exception('Item '+str(k)+' in TestSet is not a dictionary!') + if not v.has_key('ssl'): + raise Exception('TestSet '+str(k)+' is missing a field: ssl') + if not v.has_key('mrc_repl'): + raise Exception('TestSet '+str(k)+' is missing a field: mrc_repl') + if not v.has_key('dir_repl'): + raise Exception('TestSet '+str(k)+' is missing a field: dir_repl') + + if not cfgVars.has_key('VolumeConfigs'): + raise Exception('VolumeConfigs is not defined!') + + if not isinstance(cfgVars['VolumeConfigs'], types.DictType): + raise Exception('VolumeConfigs must be a dictionary!') + + for k, v in cfgVars['VolumeConfigs'].items(): + if not isinstance(v, types.DictType): + raise Exception('Item '+str(k)+' in VolumeConfig is not a dictionary!') + if not v.has_key('stripe_size'): + raise Exception('VolumeConfig '+str(k)+' is missing a field: stripe_size') + if not v.has_key('stripe_width'): + raise Exception('VolumeConfig '+str(k)+' is missing a field: stripe_width') + if not v.has_key('mount_options'): + raise Exception('VolumeConfig '+str(k)+' is missing a field: mount_options') + if not v.has_key('rwr_factor'): + raise Exception('VolumeConfig '+str(k)+' is missing a field: rwr_factor') + if not v.has_key('ronly_factor'): + raise Exception('VolumeConfig '+str(k)+' is missing a field: ronly_factor') + + if self.__selectedVolume is not None: + if self.__selectedVolume not in cfgVars['VolumeConfigs']: + raise Exception('There exists no volume config for the selected volume: ' + self.__selectedVolume) + + if not cfgVars.has_key('Tests'): + raise Exception('Tests is not defined!') + + if not isinstance(cfgVars['Tests'], types.ListType): + raise Exception('Tests must be a list!') + + for test in cfgVars['Tests']: + if not isinstance(test, types.DictType): + raise Exception('Item '+str(test)+' in Tests is not a dictionary!') + if not test.has_key('file'): + raise Exception('Test '+str(test)+' is missing a field: file') + if not test.has_key('VolumeConfigs'): + raise Exception('Test '+str(test)+' is missing a field: VolumeConfigs') + if not test.has_key('TestSets'): + raise Exception('Test '+str(test)+' is missing a field: TestSets') + + self.__testSets = cfgVars['TestSets'] + self.__tests = cfgVars['Tests'] + if self.__selectedVolume is not None: + self.__volumeConfigs[self.__selectedVolume] = cfgVars['VolumeConfigs'][self.__selectedVolume] + else: + self.__volumeConfigs = cfgVars['VolumeConfigs'] + + def getTestSetConfig(self): + return self.__curren_test_set + + # Removes tests and volume configs which aren't necessary for the selected + # test set. + def applyTestSet(self): + activeVolumeConfigs = dict() + activeTests = list() + + self.__curren_test_set = self.__testSets[self.__testSetName] + + if self.__testSetName.startswith(MANUAL_TEST_SET_NAME): + #skip this for manual set-ups. + return + + for test in self.__tests: + validTestSets = test['TestSets'] + if self.__testSetName in validTestSets: + if not test['VolumeConfigs']: + self.__system_tests.append(test) + else: + anyVolumeConfigFound = False + for volConf in list(test['VolumeConfigs']): + if volConf in self.__volumeConfigs: + activeVolumeConfigs[volConf] = self.__volumeConfigs[volConf] + anyVolumeConfigFound = True + else: + if self.__selectedVolume is None: + raise Exception("Unknown VolumeConfig '+str(volConf)+' in test '+test['name']") + else: + test['VolumeConfigs'].remove(volConf) + if anyVolumeConfigFound: + activeTests.append(test) + + self.__tests = activeTests + self.__volumeConfigs = activeVolumeConfigs + + def printConfig(self): + if not self.__testSetName.startswith(MANUAL_TEST_SET_NAME): + print 'Active System Tests:' + for test in self.__system_tests: + print ' "'+test['name']+'"' + + print 'Active Volume Tests:' + for test in self.__tests: + print ' "'+test['name']+'" running on:' + for volconf in test['VolumeConfigs']: + print ' "'+volconf+'"' + + print '' + + print 'Active VolumeConfig:' + for k,v in self.__volumeConfigs.items(): + print ' "'+k+'"' + + +if __name__ == "__main__": + config = TestConfig('test_config.py','short') + config.printConfig() diff --git a/tests/configs/dirconfig_no_ssl.test b/tests/configs/dirconfig_no_ssl.test new file mode 100644 index 0000000..228e0c2 --- /dev/null +++ b/tests/configs/dirconfig_no_ssl.test @@ -0,0 +1,110 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48638 + +# port for the status page (HTTP server) +http_port = 46638 + +# optional address for network device ("any" if not specified) +# listen.address = 127.0.0.1 + +# specify whether SSL is required +ssl.enabled = false + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# If you want to monitor your XtreemFS installation through SNMP +# uncomment the following lines. You have to set snmp.enabled = true +# and provide a listen port and optional a address. Also optional +# is a path to an aclfile which controls which hosts can access the +# monitoring information via SNMP. +#snmp.enabled = true +#snmp.address = localhost +#snmp.port = 34638 +#snmp.aclfile = etc/xos/xtreemfs/snmp.acl + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 6 + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/dir_no_ssl/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/dir_no_ssl/db-log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 200 + +# replication configuration +#babudb.plugin.0 = contrib/server-repl-plugin/config/dir-test1.properties + +uuid = test-localhost-DIR diff --git a/tests/configs/dirconfig_ssl_ignore_errors.test b/tests/configs/dirconfig_ssl_ignore_errors.test new file mode 100644 index 0000000..591dd57 --- /dev/null +++ b/tests/configs/dirconfig_ssl_ignore_errors.test @@ -0,0 +1,115 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48638 + +# port for the status page (HTTP server) +http_port = 46638 + +# optional address for network device ("any" if not specified) +# listen.address = 127.0.0.1 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/DIR_Leaf.p12 +ssl.service_creds.pw = dir_leaf +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_leaf.jks +ssl.trusted_certs.pw = trusted_leaf +ssl.trusted_certs.container = jks + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +uuid = test-localhost-DIR + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/dir_ssl_ignore_errors/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/dir_ssl_ignore_errors/database + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 200 diff --git a/tests/configs/dirconfig_ssl_long_chain.test b/tests/configs/dirconfig_ssl_long_chain.test new file mode 100644 index 0000000..6674346 --- /dev/null +++ b/tests/configs/dirconfig_ssl_long_chain.test @@ -0,0 +1,115 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48638 + +# port for the status page (HTTP server) +http_port = 46638 + +# optional address for network device ("any" if not specified) +# listen.address = 127.0.0.1 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/DIR_Leaf.p12 +ssl.service_creds.pw = dir_leaf +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_leaf.jks +ssl.trusted_certs.pw = trusted_leaf +ssl.trusted_certs.container = jks + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +uuid = test-localhost-DIR + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/dir_ssl_long_chain/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/dir_ssl_long_chain/database + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 200 diff --git a/tests/configs/dirconfig_ssl_no_verification.test b/tests/configs/dirconfig_ssl_no_verification.test new file mode 100644 index 0000000..538c60c --- /dev/null +++ b/tests/configs/dirconfig_ssl_no_verification.test @@ -0,0 +1,115 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48638 + +# port for the status page (HTTP server) +http_port = 46638 + +# optional address for network device ("any" if not specified) +# listen.address = 127.0.0.1 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/DIR_Leaf.p12 +ssl.service_creds.pw = dir_leaf +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_leaf.jks +ssl.trusted_certs.pw = trusted_leaf +ssl.trusted_certs.container = jks + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +uuid = test-localhost-DIR + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/dir_ssl_no_verification/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/dir_ssl_no_verification/database + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 200 diff --git a/tests/configs/dirconfig_ssl_short_chain.test b/tests/configs/dirconfig_ssl_short_chain.test new file mode 100644 index 0000000..7972460 --- /dev/null +++ b/tests/configs/dirconfig_ssl_short_chain.test @@ -0,0 +1,115 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48638 + +# port for the status page (HTTP server) +http_port = 46638 + +# optional address for network device ("any" if not specified) +# listen.address = 127.0.0.1 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/DIR_Root.p12 +ssl.service_creds.pw = dir_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +uuid = test-localhost-DIR + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/dir_ssl_short_chain/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/dir_ssl_short_chain/database + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 200 diff --git a/tests/configs/dirconfig_ssl_version.test b/tests/configs/dirconfig_ssl_version.test new file mode 100644 index 0000000..612ad33 --- /dev/null +++ b/tests/configs/dirconfig_ssl_version.test @@ -0,0 +1,115 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48638 + +# port for the status page (HTTP server) +http_port = 46638 + +# optional address for network device ("any" if not specified) +# listen.address = 127.0.0.1 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/DIR_Root.p12 +ssl.service_creds.pw = dir_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +uuid = test-localhost-DIR + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/dir_ssl_version/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/dir_ssl_version/database + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 200 diff --git a/tests/configs/dirconfig_ssl_version_sslv3.test b/tests/configs/dirconfig_ssl_version_sslv3.test new file mode 100644 index 0000000..b27b4c8 --- /dev/null +++ b/tests/configs/dirconfig_ssl_version_sslv3.test @@ -0,0 +1,115 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48638 + +# port for the status page (HTTP server) +http_port = 46638 + +# optional address for network device ("any" if not specified) +# listen.address = 127.0.0.1 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=sslv3 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/DIR_Root.p12 +ssl.service_creds.pw = dir_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +uuid = test-localhost-DIR + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/dir_ssl_version/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/dir_ssl_version/database + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 200 diff --git a/tests/configs/dirconfig_ssl_version_tlsv1.test b/tests/configs/dirconfig_ssl_version_tlsv1.test new file mode 100644 index 0000000..fd913cc --- /dev/null +++ b/tests/configs/dirconfig_ssl_version_tlsv1.test @@ -0,0 +1,115 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48638 + +# port for the status page (HTTP server) +http_port = 46638 + +# optional address for network device ("any" if not specified) +# listen.address = 127.0.0.1 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=tlsv1 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/DIR_Root.p12 +ssl.service_creds.pw = dir_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +uuid = test-localhost-DIR + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/dir_ssl_version/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/dir_ssl_version/database + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 200 diff --git a/tests/configs/dirconfig_ssl_version_tlsv11.test b/tests/configs/dirconfig_ssl_version_tlsv11.test new file mode 100644 index 0000000..ed0364a --- /dev/null +++ b/tests/configs/dirconfig_ssl_version_tlsv11.test @@ -0,0 +1,115 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48638 + +# port for the status page (HTTP server) +http_port = 46638 + +# optional address for network device ("any" if not specified) +# listen.address = 127.0.0.1 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=tlsv11 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/DIR_Root.p12 +ssl.service_creds.pw = dir_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +uuid = test-localhost-DIR + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/dir_ssl_version/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/dir_ssl_version/database + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 200 diff --git a/tests/configs/dirconfig_ssl_version_tlsv12.test b/tests/configs/dirconfig_ssl_version_tlsv12.test new file mode 100644 index 0000000..23ba9e7 --- /dev/null +++ b/tests/configs/dirconfig_ssl_version_tlsv12.test @@ -0,0 +1,115 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48638 + +# port for the status page (HTTP server) +http_port = 46638 + +# optional address for network device ("any" if not specified) +# listen.address = 127.0.0.1 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=tlsv12 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/DIR_Root.p12 +ssl.service_creds.pw = dir_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +uuid = test-localhost-DIR + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/dir_ssl_version/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/dir_ssl_version/database + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 200 diff --git a/tests/configs/mrcconfig_no_ssl.test b/tests/configs/mrcconfig_no_ssl.test new file mode 100644 index 0000000..9404533 --- /dev/null +++ b/tests/configs/mrcconfig_no_ssl.test @@ -0,0 +1,173 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48636 + +http_port = 46636 + +# optional address for network device, "any" if not specified +# listen.address = 127.0.0.1 + +# optinal host name that is used to register the service at the DIR +# hostname = foo.bar.com + +# interval for querying the Directory Service for new OSDs +osd_check_interval = 10 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 +#dir_service1.host = localhost +#dir_service1.port = 32639 + +# specify whether access time stamps are updated +no_atime = true +no_fsync = true + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = false + +# time span between two database checkpoint attempts (in ms) +database.checkpoint.interval = 1800000 + +# time span for which no requests must have been received to create a checkpoint (in ms) +database.checkpoint.idle_interval = 1000 + +# minimum size in bytes the log file must have to create a checkpoint +database.checkpoint.logfile_size = 16384 + +# Authentication providers are used to retrieve the user identities +# from the client or from certificate. +# The default provider is org.xtreemfs.mrc.auth.NullAuthProvider, which just +# takes the information provided by the client. The name of a pluggable +# provider can be used here. +authentication_provider = org.xtreemfs.common.auth.NullAuthProvider + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. So far, pluggable +# policies have to inherit from either org.xtreemfs.mrc.ac.FileAccessPolicy, +# org.xtreemfs.mrc.osdstatus.OSDSelectionPolicy, +# org.xtreemfs.common.auth.AuthenticationProvider, or javax.ssl.TrustManager. +# Policies identified by policy IDs (OSDSelectionPolicy and FileAccessPolicy) +# require a public static long field called POLICY_ID that assigns the policy +# a unique number. +policy_dir = /etc/xos/xtreemfs/policies + +geographic_coordinates = 52.455483,13.297405 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +# If you want to monitor your XtreemFS installation through SNMP +# uncomment the following lines. You have to set snmp.enabled = true +# and provide a listen port and optional a address. Also optional +# is a path to an aclfile which controls which hosts can access the +# monitoring information via SNMP. +#snmp.enabled = true +#snmp.address = localhost +#snmp.port = 34636 +#snmp.aclfile = etc/xos/xtreemfs/snmp.acl + + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 7 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/mrc_no_ssl/database +#babudb.baseDir = /home/stender/tmp/mrc + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/mrc_no_ssl/db-log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +#babudb.sync = ASYNC +babudb.sync = FDATASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 0 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +#TOGGLE COMMENT OF THE FOLLOWING LINES TO ENABLE THE REPLICATION +#CHECK THE REFERENCE FOR FURTHER INFORMATIONS + +# replication configuration +#babudb.plugin.0 = contrib/server-repl-plugin/config/mrc-test1.properties + +# UUID for the MRC +uuid = test-localhost-MRC diff --git a/tests/configs/mrcconfig_ssl_ignore_errors.test b/tests/configs/mrcconfig_ssl_ignore_errors.test new file mode 100644 index 0000000..5529f73 --- /dev/null +++ b/tests/configs/mrcconfig_ssl_ignore_errors.test @@ -0,0 +1,167 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48636 + +http_port = 46636 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# interval for querying the Directory Service for new OSDs +osd_check_interval = 10 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# specify whether access time stamps are updated +no_atime = true +no_fsync = true + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/MRC_Leaf.p12 +ssl.service_creds.pw = mrc_leaf +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_leaf.jks +ssl.trusted_certs.pw = trusted_leaf +ssl.trusted_certs.container = jks + +# time span between two database checkpoint attempts (in ms) +database.checkpoint.interval = 1800000 + +# time span for which no requests must have been received to create a checkpoint (in ms) +database.checkpoint.idle_interval = 1000 + +# minimum size in bytes the log file must have to create a checkpoint +database.checkpoint.logfile_size = 16384 + +# Authentication providers are used to retrieve the user identities +# from the client or from certificate. +# The default provider is org.xtreemfs.mrc.auth.NullAuthProvider, which just +# takes the information provided by the client. The name of a pluggable +# provider can be used here. +authentication_provider = org.xtreemfs.common.auth.NullAuthProvider + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. So far, pluggable +# policies have to inherit from either org.xtreemfs.mrc.ac.FileAccessPolicy, +# org.xtreemfs.mrc.osdstatus.OSDSelectionPolicy, +# org.xtreemfs.common.auth.AuthenticationProvider, or javax.ssl.TrustManager. +# Policies identified by policy IDs (OSDSelectionPolicy and FileAccessPolicy) +# require a public static long field called POLICY_ID that assigns the policy +# a unique number. +policy_dir = /etc/xos/xtreemfs/policies + +geographic_coordinates = 52.455483,13.297405 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/mrc_ssl_ignore_errors/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/mrc_ssl_ignore_errors/log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = ASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 0 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +# UUID for the MRC +uuid = test-localhost-MRC diff --git a/tests/configs/mrcconfig_ssl_long_chain.test b/tests/configs/mrcconfig_ssl_long_chain.test new file mode 100644 index 0000000..ce890f0 --- /dev/null +++ b/tests/configs/mrcconfig_ssl_long_chain.test @@ -0,0 +1,167 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48636 + +http_port = 46636 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# interval for querying the Directory Service for new OSDs +osd_check_interval = 10 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# specify whether access time stamps are updated +no_atime = true +no_fsync = true + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/MRC_Leaf.p12 +ssl.service_creds.pw = mrc_leaf +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_leaf.jks +ssl.trusted_certs.pw = trusted_leaf +ssl.trusted_certs.container = jks + +# time span between two database checkpoint attempts (in ms) +database.checkpoint.interval = 1800000 + +# time span for which no requests must have been received to create a checkpoint (in ms) +database.checkpoint.idle_interval = 1000 + +# minimum size in bytes the log file must have to create a checkpoint +database.checkpoint.logfile_size = 16384 + +# Authentication providers are used to retrieve the user identities +# from the client or from certificate. +# The default provider is org.xtreemfs.mrc.auth.NullAuthProvider, which just +# takes the information provided by the client. The name of a pluggable +# provider can be used here. +authentication_provider = org.xtreemfs.common.auth.NullAuthProvider + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. So far, pluggable +# policies have to inherit from either org.xtreemfs.mrc.ac.FileAccessPolicy, +# org.xtreemfs.mrc.osdstatus.OSDSelectionPolicy, +# org.xtreemfs.common.auth.AuthenticationProvider, or javax.ssl.TrustManager. +# Policies identified by policy IDs (OSDSelectionPolicy and FileAccessPolicy) +# require a public static long field called POLICY_ID that assigns the policy +# a unique number. +policy_dir = /etc/xos/xtreemfs/policies + +geographic_coordinates = 52.455483,13.297405 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/mrc_ssl_long_chain/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/mrc_ssl_long_chain/log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = ASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 0 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +# UUID for the MRC +uuid = test-localhost-MRC diff --git a/tests/configs/mrcconfig_ssl_no_verification.test b/tests/configs/mrcconfig_ssl_no_verification.test new file mode 100644 index 0000000..0e28640 --- /dev/null +++ b/tests/configs/mrcconfig_ssl_no_verification.test @@ -0,0 +1,167 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48636 + +http_port = 46636 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# interval for querying the Directory Service for new OSDs +osd_check_interval = 10 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# specify whether access time stamps are updated +no_atime = true +no_fsync = true + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/MRC_Leaf.p12 +ssl.service_creds.pw = mrc_leaf +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_leaf.jks +ssl.trusted_certs.pw = trusted_leaf +ssl.trusted_certs.container = jks + +# time span between two database checkpoint attempts (in ms) +database.checkpoint.interval = 1800000 + +# time span for which no requests must have been received to create a checkpoint (in ms) +database.checkpoint.idle_interval = 1000 + +# minimum size in bytes the log file must have to create a checkpoint +database.checkpoint.logfile_size = 16384 + +# Authentication providers are used to retrieve the user identities +# from the client or from certificate. +# The default provider is org.xtreemfs.mrc.auth.NullAuthProvider, which just +# takes the information provided by the client. The name of a pluggable +# provider can be used here. +authentication_provider = org.xtreemfs.common.auth.NullAuthProvider + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. So far, pluggable +# policies have to inherit from either org.xtreemfs.mrc.ac.FileAccessPolicy, +# org.xtreemfs.mrc.osdstatus.OSDSelectionPolicy, +# org.xtreemfs.common.auth.AuthenticationProvider, or javax.ssl.TrustManager. +# Policies identified by policy IDs (OSDSelectionPolicy and FileAccessPolicy) +# require a public static long field called POLICY_ID that assigns the policy +# a unique number. +policy_dir = /etc/xos/xtreemfs/policies + +geographic_coordinates = 52.455483,13.297405 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/mrc_ssl_no_verification/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/mrc_ssl_no_verification/log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = ASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 0 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +# UUID for the MRC +uuid = test-localhost-MRC diff --git a/tests/configs/mrcconfig_ssl_short_chain.test b/tests/configs/mrcconfig_ssl_short_chain.test new file mode 100644 index 0000000..ea93e58 --- /dev/null +++ b/tests/configs/mrcconfig_ssl_short_chain.test @@ -0,0 +1,167 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48636 + +http_port = 46636 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# interval for querying the Directory Service for new OSDs +osd_check_interval = 10 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# specify whether access time stamps are updated +no_atime = true +no_fsync = true + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/MRC_Root.p12 +ssl.service_creds.pw = mrc_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# time span between two database checkpoint attempts (in ms) +database.checkpoint.interval = 1800000 + +# time span for which no requests must have been received to create a checkpoint (in ms) +database.checkpoint.idle_interval = 1000 + +# minimum size in bytes the log file must have to create a checkpoint +database.checkpoint.logfile_size = 16384 + +# Authentication providers are used to retrieve the user identities +# from the client or from certificate. +# The default provider is org.xtreemfs.mrc.auth.NullAuthProvider, which just +# takes the information provided by the client. The name of a pluggable +# provider can be used here. +authentication_provider = org.xtreemfs.common.auth.NullAuthProvider + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. So far, pluggable +# policies have to inherit from either org.xtreemfs.mrc.ac.FileAccessPolicy, +# org.xtreemfs.mrc.osdstatus.OSDSelectionPolicy, +# org.xtreemfs.common.auth.AuthenticationProvider, or javax.ssl.TrustManager. +# Policies identified by policy IDs (OSDSelectionPolicy and FileAccessPolicy) +# require a public static long field called POLICY_ID that assigns the policy +# a unique number. +policy_dir = /etc/xos/xtreemfs/policies + +geographic_coordinates = 52.455483,13.297405 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/mrc_ssl_short_chain/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/mrc_ssl_short_chain/log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = ASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 0 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +# UUID for the MRC +uuid = test-localhost-MRC diff --git a/tests/configs/mrcconfig_ssl_version.test b/tests/configs/mrcconfig_ssl_version.test new file mode 100644 index 0000000..a07cf42 --- /dev/null +++ b/tests/configs/mrcconfig_ssl_version.test @@ -0,0 +1,167 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48636 + +http_port = 46636 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# interval for querying the Directory Service for new OSDs +osd_check_interval = 10 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# specify whether access time stamps are updated +no_atime = true +no_fsync = true + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/MRC_Root.p12 +ssl.service_creds.pw = mrc_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# time span between two database checkpoint attempts (in ms) +database.checkpoint.interval = 1800000 + +# time span for which no requests must have been received to create a checkpoint (in ms) +database.checkpoint.idle_interval = 1000 + +# minimum size in bytes the log file must have to create a checkpoint +database.checkpoint.logfile_size = 16384 + +# Authentication providers are used to retrieve the user identities +# from the client or from certificate. +# The default provider is org.xtreemfs.mrc.auth.NullAuthProvider, which just +# takes the information provided by the client. The name of a pluggable +# provider can be used here. +authentication_provider = org.xtreemfs.common.auth.NullAuthProvider + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. So far, pluggable +# policies have to inherit from either org.xtreemfs.mrc.ac.FileAccessPolicy, +# org.xtreemfs.mrc.osdstatus.OSDSelectionPolicy, +# org.xtreemfs.common.auth.AuthenticationProvider, or javax.ssl.TrustManager. +# Policies identified by policy IDs (OSDSelectionPolicy and FileAccessPolicy) +# require a public static long field called POLICY_ID that assigns the policy +# a unique number. +policy_dir = /etc/xos/xtreemfs/policies + +geographic_coordinates = 52.455483,13.297405 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/mrc_ssl_version/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/mrc_ssl_version/log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = ASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 0 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +# UUID for the MRC +uuid = test-localhost-MRC diff --git a/tests/configs/mrcconfig_ssl_version_sslv3.test b/tests/configs/mrcconfig_ssl_version_sslv3.test new file mode 100644 index 0000000..460cd0a --- /dev/null +++ b/tests/configs/mrcconfig_ssl_version_sslv3.test @@ -0,0 +1,167 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48636 + +http_port = 46636 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# interval for querying the Directory Service for new OSDs +osd_check_interval = 10 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# specify whether access time stamps are updated +no_atime = true +no_fsync = true + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=sslv3 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/MRC_Root.p12 +ssl.service_creds.pw = mrc_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# time span between two database checkpoint attempts (in ms) +database.checkpoint.interval = 1800000 + +# time span for which no requests must have been received to create a checkpoint (in ms) +database.checkpoint.idle_interval = 1000 + +# minimum size in bytes the log file must have to create a checkpoint +database.checkpoint.logfile_size = 16384 + +# Authentication providers are used to retrieve the user identities +# from the client or from certificate. +# The default provider is org.xtreemfs.mrc.auth.NullAuthProvider, which just +# takes the information provided by the client. The name of a pluggable +# provider can be used here. +authentication_provider = org.xtreemfs.common.auth.NullAuthProvider + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. So far, pluggable +# policies have to inherit from either org.xtreemfs.mrc.ac.FileAccessPolicy, +# org.xtreemfs.mrc.osdstatus.OSDSelectionPolicy, +# org.xtreemfs.common.auth.AuthenticationProvider, or javax.ssl.TrustManager. +# Policies identified by policy IDs (OSDSelectionPolicy and FileAccessPolicy) +# require a public static long field called POLICY_ID that assigns the policy +# a unique number. +policy_dir = /etc/xos/xtreemfs/policies + +geographic_coordinates = 52.455483,13.297405 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/mrc_ssl_version/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/mrc_ssl_version/log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = ASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 0 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +# UUID for the MRC +uuid = test-localhost-MRC diff --git a/tests/configs/mrcconfig_ssl_version_tlsv1.test b/tests/configs/mrcconfig_ssl_version_tlsv1.test new file mode 100644 index 0000000..4c16e57 --- /dev/null +++ b/tests/configs/mrcconfig_ssl_version_tlsv1.test @@ -0,0 +1,167 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48636 + +http_port = 46636 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# interval for querying the Directory Service for new OSDs +osd_check_interval = 10 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# specify whether access time stamps are updated +no_atime = true +no_fsync = true + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=tlsv1 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/MRC_Root.p12 +ssl.service_creds.pw = mrc_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# time span between two database checkpoint attempts (in ms) +database.checkpoint.interval = 1800000 + +# time span for which no requests must have been received to create a checkpoint (in ms) +database.checkpoint.idle_interval = 1000 + +# minimum size in bytes the log file must have to create a checkpoint +database.checkpoint.logfile_size = 16384 + +# Authentication providers are used to retrieve the user identities +# from the client or from certificate. +# The default provider is org.xtreemfs.mrc.auth.NullAuthProvider, which just +# takes the information provided by the client. The name of a pluggable +# provider can be used here. +authentication_provider = org.xtreemfs.common.auth.NullAuthProvider + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. So far, pluggable +# policies have to inherit from either org.xtreemfs.mrc.ac.FileAccessPolicy, +# org.xtreemfs.mrc.osdstatus.OSDSelectionPolicy, +# org.xtreemfs.common.auth.AuthenticationProvider, or javax.ssl.TrustManager. +# Policies identified by policy IDs (OSDSelectionPolicy and FileAccessPolicy) +# require a public static long field called POLICY_ID that assigns the policy +# a unique number. +policy_dir = /etc/xos/xtreemfs/policies + +geographic_coordinates = 52.455483,13.297405 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/mrc_ssl_version/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/mrc_ssl_version/log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = ASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 0 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +# UUID for the MRC +uuid = test-localhost-MRC diff --git a/tests/configs/mrcconfig_ssl_version_tlsv11.test b/tests/configs/mrcconfig_ssl_version_tlsv11.test new file mode 100644 index 0000000..bfb7591 --- /dev/null +++ b/tests/configs/mrcconfig_ssl_version_tlsv11.test @@ -0,0 +1,167 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48636 + +http_port = 46636 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# interval for querying the Directory Service for new OSDs +osd_check_interval = 10 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# specify whether access time stamps are updated +no_atime = true +no_fsync = true + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=tlsv11 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/MRC_Root.p12 +ssl.service_creds.pw = mrc_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# time span between two database checkpoint attempts (in ms) +database.checkpoint.interval = 1800000 + +# time span for which no requests must have been received to create a checkpoint (in ms) +database.checkpoint.idle_interval = 1000 + +# minimum size in bytes the log file must have to create a checkpoint +database.checkpoint.logfile_size = 16384 + +# Authentication providers are used to retrieve the user identities +# from the client or from certificate. +# The default provider is org.xtreemfs.mrc.auth.NullAuthProvider, which just +# takes the information provided by the client. The name of a pluggable +# provider can be used here. +authentication_provider = org.xtreemfs.common.auth.NullAuthProvider + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. So far, pluggable +# policies have to inherit from either org.xtreemfs.mrc.ac.FileAccessPolicy, +# org.xtreemfs.mrc.osdstatus.OSDSelectionPolicy, +# org.xtreemfs.common.auth.AuthenticationProvider, or javax.ssl.TrustManager. +# Policies identified by policy IDs (OSDSelectionPolicy and FileAccessPolicy) +# require a public static long field called POLICY_ID that assigns the policy +# a unique number. +policy_dir = /etc/xos/xtreemfs/policies + +geographic_coordinates = 52.455483,13.297405 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/mrc_ssl_version/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/mrc_ssl_version/log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = ASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 0 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +# UUID for the MRC +uuid = test-localhost-MRC diff --git a/tests/configs/mrcconfig_ssl_version_tlsv12.test b/tests/configs/mrcconfig_ssl_version_tlsv12.test new file mode 100644 index 0000000..97106a7 --- /dev/null +++ b/tests/configs/mrcconfig_ssl_version_tlsv12.test @@ -0,0 +1,167 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48636 + +http_port = 46636 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# interval for querying the Directory Service for new OSDs +osd_check_interval = 10 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# specify whether access time stamps are updated +no_atime = true +no_fsync = true + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=tlsv12 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/MRC_Root.p12 +ssl.service_creds.pw = mrc_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +# time span between two database checkpoint attempts (in ms) +database.checkpoint.interval = 1800000 + +# time span for which no requests must have been received to create a checkpoint (in ms) +database.checkpoint.idle_interval = 1000 + +# minimum size in bytes the log file must have to create a checkpoint +database.checkpoint.logfile_size = 16384 + +# Authentication providers are used to retrieve the user identities +# from the client or from certificate. +# The default provider is org.xtreemfs.mrc.auth.NullAuthProvider, which just +# takes the information provided by the client. The name of a pluggable +# provider can be used here. +authentication_provider = org.xtreemfs.common.auth.NullAuthProvider + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. So far, pluggable +# policies have to inherit from either org.xtreemfs.mrc.ac.FileAccessPolicy, +# org.xtreemfs.mrc.osdstatus.OSDSelectionPolicy, +# org.xtreemfs.common.auth.AuthenticationProvider, or javax.ssl.TrustManager. +# Policies identified by policy IDs (OSDSelectionPolicy and FileAccessPolicy) +# require a public static long field called POLICY_ID that assigns the policy +# a unique number. +policy_dir = /etc/xos/xtreemfs/policies + +geographic_coordinates = 52.455483,13.297405 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +##################################################################### +# BabuDB configuration # +##################################################################### + +# optional debug level ( +# 0 = emergency, +# 1 = alert, +# 2 = critical, +# 3 = error, +# 4 = warning, +# 5 = notice, +# 6 = info, +# 7 = debug) +babudb.debug.level = 4 + +# optional debug category +#babudb.debug.category = all + +# name for the database configuration file +#babudb.cfgFile = config.db + +# base directory to store database index snapshots in +babudb.baseDir = /tmp/xtreemfs-test/mrc_ssl_version/database + +# directory in which the database logs are stored +babudb.logDir = /tmp/xtreemfs-test/mrc_ssl_version/log + +# SyncMode the synchronization mode to use for the logFile +# ASYNC - asynchronously write log entries (data is lost when system crashes). +# FSYNC - executes an fsync on the logfile before acknowledging the operation. +# FDATASYNC +# SYNC_WRITE - synchronously writes the log entry to disk before ack. Does not +# update the metadata. +# SYNC_WRITE_METADATA - synchronously writes the log entry to disk and updates +# the metadata before ack. +babudb.sync = ASYNC + +# max queue length: if > 0, the queue for each worker is limited to maxQ +babudb.worker.maxQueueLength = 250 + +# number of worker threads to use +babudb.worker.numThreads = 0 + +# a checkpoint is generated, if maxLogfileSize is exceeded +babudb.maxLogfileSize = 16777216 + +# interval between two checks in seconds, 0 disables auto checkPointing +babudb.checkInterval = 300 + +# if set to a value > 0, operations are acknowledged immediately before +# they are written to the disk log. The disk logger will do batch writes +# and call fSync... every pseudoSyncWait seconds. This can be used to +# increase performance and emulate PostgreSQL behavior. +babudb.pseudoSyncWait = 0 + +# flag that determines whether the indices shall be compressed or not. +#babudb.compression = false + +# UUID for the MRC +uuid = test-localhost-MRC diff --git a/tests/configs/osdconfig_no_ssl.test b/tests/configs/osdconfig_no_ssl.test new file mode 100644 index 0000000..8e693f9 --- /dev/null +++ b/tests/configs/osdconfig_no_ssl.test @@ -0,0 +1,99 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48640 + +http_port = 46640 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# optinal host name that is used to register the service at the DIR +# hostname = foo.bar.com + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# directory containing XtreemFS file content +object_dir = /tmp/xtreemfs-test/osd_no_ssl/ + +# Number of storage threads. Increase it to improve concurrency in case of multiple open files. +# Set it to a value >1 only if the underlying device can cope with concurrency, e.g. an SSD. +#storage_threads = 1 + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = false + +# send and receive buffer sizes of sockets +#socket.send_buffer_size = 262144 +#socket.recv_buffer_size = 262144 + +report_free_space = true + +# specify whether internal OSD checksums are required +# if the flag is set to true, the OSD will calculate checksums for +# newly created objects, which will be checked when the object is read +checksums.enabled = false + +# algorithm used for checksum calculation +# by default, Adler32, CRC32, MD5 and SHA-1 are supported +checksums.algorithm = Adler32 + +checksums.enabled = false + +geographic_coordinates = 41.388417,2.114632 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# If you want to monitor your XtreemFS installation through SNMP +# uncomment the following lines. You have to set snmp.enabled = true +# and provide a listen port and optional a address. Also optional +# is a path to an aclfile which controls which hosts can access the +# monitoring information via SNMP. +#snmp.enabled = true +#snmp.address = localhost +#snmp.port = 34640 +#snmp.aclfile = etc/xos/xtreemfs/snmp.acl + +# UUID for the OSD +uuid = test-localhost-OSD diff --git a/tests/configs/osdconfig_ssl_ignore_errors.test b/tests/configs/osdconfig_ssl_ignore_errors.test new file mode 100644 index 0000000..0310a69 --- /dev/null +++ b/tests/configs/osdconfig_ssl_ignore_errors.test @@ -0,0 +1,100 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48640 + +http_port = 46640 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# directory containing XtreemFS file content +object_dir = /tmp/xtreemfs-test/osd_ssl_ignore_errors/ + +# Number of storage threads. Increase it to improve concurrency in case of multiple open files. +# Set it to a value >1 only if the underlying device can cope with concurrency, e.g. an SSD. +#storage_threads = 1 + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/OSD_Leaf.p12 +ssl.service_creds.pw = osd_leaf +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_leaf.jks +ssl.trusted_certs.pw = trusted_leaf +ssl.trusted_certs.container = jks + +report_free_space = true + +# specify whether internal OSD checksums are required +# if the flag is set to true, the OSD will calculate checksums for +# newly created objects, which will be checked when the object is read +checksums.enabled = false + +# algorithm used for checksum calculation +# by default, Adler32, CRC32, MD5 and SHA-1 are supported +checksums.algorithm = Adler32 + +checksums.enabled = false + +geographic_coordinates = 41.388417,2.114632 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# UUID for the OSD +uuid = test-localhost-OSD diff --git a/tests/configs/osdconfig_ssl_long_chain.test b/tests/configs/osdconfig_ssl_long_chain.test new file mode 100644 index 0000000..5a926b7 --- /dev/null +++ b/tests/configs/osdconfig_ssl_long_chain.test @@ -0,0 +1,100 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48640 + +http_port = 46640 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# directory containing XtreemFS file content +object_dir = /tmp/xtreemfs-test/osd_ssl_long_chain/ + +# Number of storage threads. Increase it to improve concurrency in case of multiple open files. +# Set it to a value >1 only if the underlying device can cope with concurrency, e.g. an SSD. +#storage_threads = 1 + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/OSD_Leaf.p12 +ssl.service_creds.pw = osd_leaf +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_leaf.jks +ssl.trusted_certs.pw = trusted_leaf +ssl.trusted_certs.container = jks + +report_free_space = true + +# specify whether internal OSD checksums are required +# if the flag is set to true, the OSD will calculate checksums for +# newly created objects, which will be checked when the object is read +checksums.enabled = false + +# algorithm used for checksum calculation +# by default, Adler32, CRC32, MD5 and SHA-1 are supported +checksums.algorithm = Adler32 + +checksums.enabled = false + +geographic_coordinates = 41.388417,2.114632 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# UUID for the OSD +uuid = test-localhost-OSD diff --git a/tests/configs/osdconfig_ssl_no_verification.test b/tests/configs/osdconfig_ssl_no_verification.test new file mode 100644 index 0000000..70bd04d --- /dev/null +++ b/tests/configs/osdconfig_ssl_no_verification.test @@ -0,0 +1,100 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48640 + +http_port = 46640 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# directory containing XtreemFS file content +object_dir = /tmp/xtreemfs-test/osd_ssl_no_verification/ + +# Number of storage threads. Increase it to improve concurrency in case of multiple open files. +# Set it to a value >1 only if the underlying device can cope with concurrency, e.g. an SSD. +#storage_threads = 1 + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/OSD_Leaf.p12 +ssl.service_creds.pw = osd_leaf +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_leaf.jks +ssl.trusted_certs.pw = trusted_leaf +ssl.trusted_certs.container = jks + +report_free_space = true + +# specify whether internal OSD checksums are required +# if the flag is set to true, the OSD will calculate checksums for +# newly created objects, which will be checked when the object is read +checksums.enabled = false + +# algorithm used for checksum calculation +# by default, Adler32, CRC32, MD5 and SHA-1 are supported +checksums.algorithm = Adler32 + +checksums.enabled = false + +geographic_coordinates = 41.388417,2.114632 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# UUID for the OSD +uuid = test-localhost-OSD diff --git a/tests/configs/osdconfig_ssl_short_chain.test b/tests/configs/osdconfig_ssl_short_chain.test new file mode 100644 index 0000000..7530328 --- /dev/null +++ b/tests/configs/osdconfig_ssl_short_chain.test @@ -0,0 +1,100 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48640 + +http_port = 46640 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# directory containing XtreemFS file content +object_dir = /tmp/xtreemfs-test/osd_ssl_short_chain/ + +# Number of storage threads. Increase it to improve concurrency in case of multiple open files. +# Set it to a value >1 only if the underlying device can cope with concurrency, e.g. an SSD. +#storage_threads = 1 + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/OSD_Root.p12 +ssl.service_creds.pw = osd_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +report_free_space = true + +# specify whether internal OSD checksums are required +# if the flag is set to true, the OSD will calculate checksums for +# newly created objects, which will be checked when the object is read +checksums.enabled = false + +# algorithm used for checksum calculation +# by default, Adler32, CRC32, MD5 and SHA-1 are supported +checksums.algorithm = Adler32 + +checksums.enabled = false + +geographic_coordinates = 41.388417,2.114632 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# UUID for the OSD +uuid = test-localhost-OSD diff --git a/tests/configs/osdconfig_ssl_version.test b/tests/configs/osdconfig_ssl_version.test new file mode 100644 index 0000000..d1df5da --- /dev/null +++ b/tests/configs/osdconfig_ssl_version.test @@ -0,0 +1,100 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48640 + +http_port = 46640 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# directory containing XtreemFS file content +object_dir = /tmp/xtreemfs-test/osd_ssl_version/ + +# Number of storage threads. Increase it to improve concurrency in case of multiple open files. +# Set it to a value >1 only if the underlying device can cope with concurrency, e.g. an SSD. +#storage_threads = 1 + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=ssltls + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/OSD_Root.p12 +ssl.service_creds.pw = osd_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +report_free_space = true + +# specify whether internal OSD checksums are required +# if the flag is set to true, the OSD will calculate checksums for +# newly created objects, which will be checked when the object is read +checksums.enabled = false + +# algorithm used for checksum calculation +# by default, Adler32, CRC32, MD5 and SHA-1 are supported +checksums.algorithm = Adler32 + +checksums.enabled = false + +geographic_coordinates = 41.388417,2.114632 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# UUID for the OSD +uuid = test-localhost-OSD diff --git a/tests/configs/osdconfig_ssl_version_sslv3.test b/tests/configs/osdconfig_ssl_version_sslv3.test new file mode 100644 index 0000000..0a4eaae --- /dev/null +++ b/tests/configs/osdconfig_ssl_version_sslv3.test @@ -0,0 +1,100 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48640 + +http_port = 46640 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# directory containing XtreemFS file content +object_dir = /tmp/xtreemfs-test/osd_ssl_version/ + +# Number of storage threads. Increase it to improve concurrency in case of multiple open files. +# Set it to a value >1 only if the underlying device can cope with concurrency, e.g. an SSD. +#storage_threads = 1 + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=sslv3 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/OSD_Root.p12 +ssl.service_creds.pw = osd_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +report_free_space = true + +# specify whether internal OSD checksums are required +# if the flag is set to true, the OSD will calculate checksums for +# newly created objects, which will be checked when the object is read +checksums.enabled = false + +# algorithm used for checksum calculation +# by default, Adler32, CRC32, MD5 and SHA-1 are supported +checksums.algorithm = Adler32 + +checksums.enabled = false + +geographic_coordinates = 41.388417,2.114632 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# UUID for the OSD +uuid = test-localhost-OSD diff --git a/tests/configs/osdconfig_ssl_version_tlsv1.test b/tests/configs/osdconfig_ssl_version_tlsv1.test new file mode 100644 index 0000000..d91eceb --- /dev/null +++ b/tests/configs/osdconfig_ssl_version_tlsv1.test @@ -0,0 +1,100 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48640 + +http_port = 46640 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# directory containing XtreemFS file content +object_dir = /tmp/xtreemfs-test/osd_ssl_version/ + +# Number of storage threads. Increase it to improve concurrency in case of multiple open files. +# Set it to a value >1 only if the underlying device can cope with concurrency, e.g. an SSD. +#storage_threads = 1 + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=tlsv1 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/OSD_Root.p12 +ssl.service_creds.pw = osd_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +report_free_space = true + +# specify whether internal OSD checksums are required +# if the flag is set to true, the OSD will calculate checksums for +# newly created objects, which will be checked when the object is read +checksums.enabled = false + +# algorithm used for checksum calculation +# by default, Adler32, CRC32, MD5 and SHA-1 are supported +checksums.algorithm = Adler32 + +checksums.enabled = false + +geographic_coordinates = 41.388417,2.114632 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# UUID for the OSD +uuid = test-localhost-OSD diff --git a/tests/configs/osdconfig_ssl_version_tlsv11.test b/tests/configs/osdconfig_ssl_version_tlsv11.test new file mode 100644 index 0000000..c69931e --- /dev/null +++ b/tests/configs/osdconfig_ssl_version_tlsv11.test @@ -0,0 +1,100 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48640 + +http_port = 46640 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# directory containing XtreemFS file content +object_dir = /tmp/xtreemfs-test/osd_ssl_version/ + +# Number of storage threads. Increase it to improve concurrency in case of multiple open files. +# Set it to a value >1 only if the underlying device can cope with concurrency, e.g. an SSD. +#storage_threads = 1 + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=tlsv11 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/OSD_Root.p12 +ssl.service_creds.pw = osd_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +report_free_space = true + +# specify whether internal OSD checksums are required +# if the flag is set to true, the OSD will calculate checksums for +# newly created objects, which will be checked when the object is read +checksums.enabled = false + +# algorithm used for checksum calculation +# by default, Adler32, CRC32, MD5 and SHA-1 are supported +checksums.algorithm = Adler32 + +checksums.enabled = false + +geographic_coordinates = 41.388417,2.114632 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# UUID for the OSD +uuid = test-localhost-OSD diff --git a/tests/configs/osdconfig_ssl_version_tlsv12.test b/tests/configs/osdconfig_ssl_version_tlsv12.test new file mode 100644 index 0000000..d928cf8 --- /dev/null +++ b/tests/configs/osdconfig_ssl_version_tlsv12.test @@ -0,0 +1,100 @@ +# optional debug level +# 0: emergency +# 1: alert +# 2: critical +# 3: error +# 4: warning +# 5: notice +# 6: info (default) +# 7: debug +debug.level = 6 + +# optional debug categories - a space or comma-separated list of log message categories +# all (default) - enable logging for all categories +# lifecycle - log messaages pertaining to service lifecycles (threads) +# buffer - logs messages pertaining to buffers +# net - network-related log messages +# auth - authorization-related log messages +# stage - log messages pertaining to the request flow through the stages +# proc - log messages pertaining to any kind of request processing +# db - log messages pertaining storage on OSD or database access on MRC/DIR +# replication - logs messages pertaining to replication +# misc - any other log messages +#debug.categories = all + +# port for the service to listen on +listen.port = 48640 + +http_port = 46640 + +# optional address for network device, "any" if not specified +#listen.address = 127.0.0.1 + +# Directory Service endpoint +dir_service.host = localhost +dir_service.port = 48638 + +# directory containing XtreemFS file content +object_dir = /tmp/xtreemfs-test/osd_ssl_version/ + +# Number of storage threads. Increase it to improve concurrency in case of multiple open files. +# Set it to a value >1 only if the underlying device can cope with concurrency, e.g. an SSD. +#storage_threads = 1 + +# granularity of the local clock (in ms) (0 disables it to always use the current system time) +local_clock_renewal = 0 + +# interval between two remote clock syncs (in ms) +remote_time_sync = 60000 + +# specify whether SSL is required +ssl.enabled = true + +# SSL/TLS version to use +# in JDK 6: sslv3, ssltls, tlsv1 +# in JDK 7 additionally: tlsv12 +# tlsv11 comes with JDK 6 or 7, depending on the vendor +# 'ssltls' (default) accepts all versions, +# the others accept only the exact version they name. +ssl.protocol=tlsv12 + +# server credentials for SSL handshakes +ssl.service_creds = ../../tests/certs/client_ssl_test/OSD_Root.p12 +ssl.service_creds.pw = osd_root +ssl.service_creds.container = pkcs12 + +# trusted certificates for SSL handshakes +ssl.trusted_certs = ../../tests/certs/client_ssl_test/trusted_root.jks +ssl.trusted_certs.pw = trusted_root +ssl.trusted_certs.container = jks + +report_free_space = true + +# specify whether internal OSD checksums are required +# if the flag is set to true, the OSD will calculate checksums for +# newly created objects, which will be checked when the object is read +checksums.enabled = false + +# algorithm used for checksum calculation +# by default, Adler32, CRC32, MD5 and SHA-1 are supported +checksums.algorithm = Adler32 + +checksums.enabled = false + +geographic_coordinates = 41.388417,2.114632 + +capability_secret = Yagga + +# administrator password for privileged operations +#admin_password = blub + +# Optional directory containing deployable policy implementations. +# Policies can be directly deployed as .java or .class files in this directory +# or one of its subdirectories. They will be compiled at startup time and +# loaded at runtime. Policies may have external dependencies that can be +# deployed either as .java, .class or .jar files. While Java and Class files +# may be located in subdirectories, JAR files mustn't. +policy_dir = /etc/xos/xtreemfs/policies + +# UUID for the OSD +uuid = test-localhost-OSD diff --git a/tests/cronjob/run_xtreemfs_tests.sh b/tests/cronjob/run_xtreemfs_tests.sh new file mode 100755 index 0000000..b569f49 --- /dev/null +++ b/tests/cronjob/run_xtreemfs_tests.sh @@ -0,0 +1,155 @@ +#!/bin/bash + +# Copyright (c) 2006-2011 by Björn Kolbeck, Zuse Institute Berlin +# 2011-2013 by Michael Berlin, Zuse Institute Berlin +# +# Licensed under the BSD License, see LICENSE file for details. + + +# This script downloads the latest XtreemFS sources and runs the integration tests. +# As of April 2013, we run this script internally every night. The results of the +# tests are posted to the internal mailing list xtreemfs-test@googlegroups.com. +# +# Run it as cron job as follows: /usr/bin/wget https://raw.githubusercontent.com/xtreemfs/xtreemfs/master/tests/cronjob/run_xtreemfs_tests.sh -q -O - | bash -l + +# Environment +export LANG=en_US.UTF-8 + +# Global variables +TEST_ID=`date +%Y%m%dT%H%M%S` +DIR_PREFIX="/scratch/autotests" +XTREEMFS_DIR="$DIR_PREFIX/checkouts/xtreemfs_checkout-$TEST_ID" +TEST_DIR="$DIR_PREFIX/tests/xtreemfs_test-$TEST_ID" +TEST_LOG="$TEST_DIR/test.log" +TEST_SUMMARY="$TEST_DIR/summary.log" +ATTACHMENT="$TEST_DIR/summary_and_testlog.txt" +ATTACHMENT_ZIP_LOGS="$TEST_DIR/client_and_server_logs.zip" + +if [ ! -d "$DIR_PREFIX" ] +then + mkdir -p "$DIR_PREFIX" +fi +if [ ! -d "$DIR_PREFIX" ] +then + echo "ERROR: $DIR_PREFIX does not exist." + exit 1 +fi + + +# Helper functions +sendresult() { + local result=$1 + if [ $result -eq 0 ] + then + subject="SUCCESS: XtreemFS automatic test" + else + subject="FAILED: XtreemFS automatic test" + fi + cat $TEST_LOG > $ATTACHMENT + echo "" >> $ATTACHMENT + if [ -e $TEST_SUMMARY ] + then + cat $TEST_SUMMARY >> $ATTACHMENT + fi + + # Pack log files as .zip archive + if [ -d "$TEST_DIR""/log" ] + then + # Work-around the problem that 'zip' always stores the complete path :( + current_dir="$PWD" + cd "$TEST_DIR""/log" + zip -r -q -9 $ATTACHMENT_ZIP_LOGS *.log + cd "$current_dir" + fi + + if [ -f "$ATTACHMENT_ZIP_LOGS" ] + then + mailx_additional_params="-a $ATTACHMENT_ZIP_LOGS" + fi + mailx -a $ATTACHMENT $mailx_additional_params -s "$subject" xtreemfs-test@googlegroups.com<< EOF +$subject + +The logfile of this test run and the logs of servers and clients are attached to this email. +Logfiles and databases can be found in: $TEST_DIR + +EOF + + rm $ATTACHMENT + if [ -f $ATTACHMENT_ZIP_LOGS ] + then + rm $ATTACHMENT_ZIP_LOGS + fi +} + +# Kill any remaining test runs +killall python /usr/bin/python iozone &>/dev/null && sleep 5 +killall -9 python /usr/bin/python iozone &>/dev/null +killall -9 mount.xtreemfs &>/dev/null +killall -9 java &>/dev/null +for mount in $(mount|grep ^xtreemfs@|cut -d" " -f3) +do + fusermount -u "$mount" &>/dev/null +done + +# Current directories already exist? Remove them first. +if [ -d "$TEST_DIR" ] +then + rm -r "$TEST_DIR" +fi +if [ -d "$XTREEMFS_DIR" ] +then + rm -r "$XTREEMFS_DIR" +fi + +# Cleanup test directory if disk is full +min_free_space_mb=10000 # Remove all tests until enough space is available +min_free_inodes=2000000 +while true +do + # Enough free space? + free_space_mb=$(df -Pm $DIR_PREFIX | grep -v ^Filesystem | awk '{ print $4 }') + free_inodes=$(df -i $DIR_PREFIX | grep -v ^Filesystem | awk '{ print $4 }') + if [ $free_space_mb -ge $min_free_space_mb ] && [ $free_inodes -ge $min_free_inodes ] + then + break + fi + + # Any dirs left to delete? + for dir in "$DIR_PREFIX/checkouts/" "$DIR_PREFIX/tests/" + do + oldest_dir=$(ls -1At "$dir" | tail -n1) + if [ -n "$oldest_dir" ] + then + rm -rf "$dir""$oldest_dir" || break + fi + done +done + +# Create directories +mkdir -p $DIR_PREFIX +mkdir -p $XTREEMFS_DIR +mkdir -p $TEST_DIR + +# Check out +cd $XTREEMFS_DIR +git clone https://github.com/xtreemfs/xtreemfs.git . &> $TEST_LOG + +# Compile +# 2012-11-02(mberlin): Try to disable optimizations in client compilation. +# Build client unit tests. +export BUILD_CLIENT_TESTS=true +export CPPFLAGS=-O0 +make client_debug server hadoop-client &>$TEST_LOG +if [ $? -ne 0 ]; then + echo "FAILED: cannot make sources!" >> $TEST_LOG + date >> $TEST_LOG + sendresult 1 + exit +fi + +# Run xtfs_test +# rm $TEST_LOG +cd $XTREEMFS_DIR/tests +python -u xtestenv -t $TEST_DIR full &> $TEST_SUMMARY +result=$? +sendresult $result diff --git a/tests/kill_running_servers.sh b/tests/kill_running_servers.sh new file mode 100755 index 0000000..5e1e01a --- /dev/null +++ b/tests/kill_running_servers.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin +# +# Licensed under the BSD License, see LICENSE file for details. + +# Use this script to kill servers which were not correctly shutdown by a failed xtestenv run. + +for pid in $(ps faux | grep XtreemFS.jar | grep -v grep | awk '{ print $2 }') +do + kill $pid +done + +for pid in $(ps faux | grep XtreemFS.jar | grep -v grep | awk '{ print $2 }') +do + kill -9 $pid +done diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 0000000..9c8ad89 --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,333 @@ +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +TestSets = { + 'short' : { + 'ssl': False, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': False, + }, + 'full' : { + 'ssl': False, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': False, + }, + 'short-ssl' : { + 'ssl': True, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': False, + }, + # contains only multi-threaded benchmarks. set option "-t" accordingly. + 'ssd' : { + 'ssl': False, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': False + }, + # Contains dd tests for testing the SSL support of packages. + 'packages-ssl' : { + 'ssl': True, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': False + }, + # Used for testing new test scripts, therefore usually contains no tests. + 'testing' : { + 'ssl': False, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': False, + }, + # This configuration is used for manual test environment set-ups (option -e). + 'manual' : { + 'ssl': False, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': True, + }, + # This configuration is used for manual test environment set-ups with SSL enabled (option -f). + 'manual-ssl' : { + 'ssl': True, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': True, + }, + # This configuration is used to run the tests on the Travis CI build environment. + 'travis' : { + 'ssl': False, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': False, + }, + 'travis-junit' : { + 'ssl': False, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': False, + }, + 'travis-cpp' : { + 'ssl': False, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': False, + }, + 'travis-valgrind' : { + 'ssl': False, + 'mrc_repl': False, + 'dir_repl': False, + 'snmp': False, + }, +} + +VolumeConfigs = { + 'regular' : { + 'stripe_size': 128, + 'stripe_width': 1, + 'rwr_factor': 0, + 'ronly_factor': 0, + 'mount_options': [ '-ouser_xattr', '-oallow_other' ], + 'mkfs_options': [ '--max-tries=10', '--chown-non-root' ] + }, + 'regular_two_osds' : { + 'stripe_size': 128, + 'stripe_width': 1, + 'rwr_factor': 0, + 'ronly_factor': 0, + 'min_osds': 2, + 'mount_options': [ '-ouser_xattr' ], + 'mkfs_options': [ '--max-tries=10'] + }, + 'nomdcache' : { + 'stripe_size': 128, + 'stripe_width': 1, + 'rwr_factor': 0, + 'ronly_factor': 0, + 'mount_options': [ '--metadata-cache-size=0', '-ouser_xattr', '-oallow_other' ], + 'mkfs_options': [ '--max-tries=10', '--chown-non-root' ] + }, + 'directio' : { + 'stripe_size': 128, + 'stripe_width': 1, + 'rwr_factor': 0, + 'ronly_factor': 0, + 'mount_options': [ '-odirect_io' ], + 'mkfs_options': [ '--max-tries=10'] + }, + 'striped2' : { + 'stripe_size': 128, + 'stripe_width': 2, + 'rwr_factor': 0, + 'ronly_factor': 0, + 'mount_options': [ ], + 'mkfs_options': [ '--max-tries=10'] + }, + 'replicated_wqrq' : { + 'stripe_size': 128, + 'stripe_width': 1, + 'rwr_factor': 3, + 'ronly_factor': 0, + 'mount_options': [ ], + 'mkfs_options': [ '--max-tries=10'] + }, + 'replicated_wqrq_asyncwrites' : { + 'stripe_size': 128, + 'stripe_width': 1, + 'rwr_factor': 3, + 'ronly_factor': 0, + 'mount_options': [ '--enable-async-writes' ], + 'mkfs_options': [ '--max-tries=10'] + }, + 'replicated_war1' : { + 'stripe_size': 128, + 'stripe_width': 1, + 'rwr_policy': 'all', + 'rwr_factor': 2, + 'ronly_factor': 0, + 'mount_options': [ '--max-tries=240', '--max-read-tries=240', '--max-write-tries=240' ], + 'mkfs_options': [ '--max-tries=10'] + }, +} + +Tests = [ + # VOLUME TESTS + { + 'name': 'Simple Metadata', + 'file': '01_simple_metadata.py', + 'VolumeConfigs': [ 'regular', 'directio', 'striped2', 'nomdcache' ], + 'TestSets': [ 'short', 'full', 'short-ssl' ] + }, + { + 'name': 'Erichs dd write', + 'file': '02_erichs_ddwrite.py', + 'VolumeConfigs': [ 'regular', 'directio', 'striped2', 'replicated_wqrq', 'replicated_wqrq_asyncwrites' ], + 'TestSets': [ 'full', 'short', 'short-ssl', 'packages-ssl' ] + }, + { + 'name': 'Erichs data integrity test', + 'file': '03_erichs_data_integrity_test.py', + 'VolumeConfigs': [ 'regular', 'directio', 'striped2', 'replicated_wqrq', 'replicated_wqrq_asyncwrites' ], + 'TestSets': [ 'full', 'short', 'short-ssl' ] + }, + { + 'name': 'Find Grep Tar', + 'file': '05_findgreptar.sh', + 'VolumeConfigs': [ 'regular', 'directio', 'striped2', 'nomdcache', 'replicated_wqrq', 'replicated_wqrq_asyncwrites' ], + 'TestSets': [ 'full', 'short', 'short-ssl' ] + }, + { + 'name': 'fsx', + 'file': 'fsx.sh', + 'VolumeConfigs': [ 'regular', 'directio', 'striped2', 'nomdcache', 'replicated_wqrq', 'replicated_wqrq_asyncwrites' ], + 'TestSets': [ 'full', 'short', 'short-ssl' ] + }, + { + 'name': 'bonnie', + 'file': '10_bonnie.py', + 'VolumeConfigs': [ 'regular', 'directio', 'striped2', 'replicated_wqrq', 'replicated_wqrq_asyncwrites' ], + # NOTE(mberlin): 2013/04: Disabled because it takes too long and was not helpful in finding problems so far. + 'TestSets': [ ] + }, + { + 'name': 'IOZone diagnostic', + 'file': '11_iozone_diagnostic.py', + 'VolumeConfigs': [ 'regular', 'directio', 'striped2', 'replicated_wqrq', 'replicated_wqrq_asyncwrites' ], + 'TestSets': [ 'full' ] + }, + { + 'name': 'IOZone throughput', + 'file': '12_iozone_throughput.py', + 'VolumeConfigs': [ 'regular', 'directio', 'striped2', 'replicated_wqrq', 'replicated_wqrq_asyncwrites' ], + 'TestSets': [ 'full' ] + }, + { + 'name': 'DBench', + 'file': '13_dbench.py', + 'VolumeConfigs': [ 'regular', 'directio', 'striped2', 'nomdcache' ], + 'TestSets': [ 'full' ] + }, + { + 'name': 'make xtreemfs', + 'file': '15_makextreemfs.py', + 'VolumeConfigs': [ 'regular', 'nomdcache' ], + 'TestSets': [ 'full' ] + }, + { + 'name': 'IOZone multithread', + 'file': '16_iozone_multithread.py', + 'VolumeConfigs': [ 'regular' ], + 'TestSets': [ 'ssd' ] + }, + { + 'name': 'bonnie multithread', + 'file': '17_bonnie_multithread.py', + 'VolumeConfigs': [ 'regular' ], + 'TestSets': [ 'ssd' ] + }, + { + 'name': 'view renewal', + 'file': '18_view_renewal.py', + 'VolumeConfigs': [ 'regular_two_osds' ], + 'TestSets': [ 'full', 'short', 'short-ssl' ] + }, + { + 'name': 'xtfs_cleanup test', + 'file': 'system_cleanup_test.sh', + 'VolumeConfigs': ['nomdcache'], + 'TestSets': [ 'full', 'short', 'short-ssl' ] + }, + { + 'name': 'snapshot test', + 'file': 'system_snap_test.sh', + 'VolumeConfigs': ['regular'], + 'TestSets': [ 'full', 'short', 'short-ssl' ] + }, + { + 'name': 'xattr test', + 'file': 'test_xattrs.sh', + 'VolumeConfigs': [ 'regular', 'nomdcache' ], + 'TestSets': [ 'full', 'short' ] + }, + { + 'name': 'xtfs_scrub test', + 'file': 'system_scrub_test.sh', + 'VolumeConfigs': ['nomdcache'], + #'TestSets': [ 'full', 'short', 'short-ssl' ] + 'TestSets': [] + }, + { + 'name': 'Add and delete replica manually (read-only replication)', + 'file': 'ronly_replication_add_delete_replica.sh', + 'VolumeConfigs': ['regular_two_osds'], + 'TestSets': [ 'full', 'short', 'short-ssl' ] + }, + { + 'name': 'POSIX Test Suite (root required)', + 'file': 'posix_test_suite.sh', + 'VolumeConfigs': ['regular', 'nomdcache'], + 'TestSets': [ 'full', 'short', 'short-ssl' ] + }, + { + 'name': 'hadoop test', + 'file': 'hadoop_test.sh', + 'VolumeConfigs': ['regular'], + 'TestSets': [ 'full' ] + }, + { + 'name': 'hadoop2 test', + 'file': 'hadoop2_test.sh', + 'VolumeConfigs': ['regular'], + 'TestSets': [ 'full' ] + }, + { + 'name': 'hadoop with ssl test', + 'file': 'hadoop_ssl_test.sh', + 'VolumeConfigs': ['regular_two_osds'], + 'TestSets': [ 'short-ssl' ] + }, + { + 'name': 'xtfs_benchmark', + 'file': '14_xtfs_benchmark.sh', + 'VolumeConfigs': [ 'regular', 'regular_two_osds', 'nomdcache', 'directio', 'striped2', 'replicated_wqrq', 'replicated_wqrq_asyncwrites'], + 'TestSets': [ 'full' ] + }, + # SYSTEM TESTS + { + 'name': 'JUnit tests', + 'file': 'junit_tests.sh', + 'VolumeConfigs': [], + 'TestSets': [ 'full', 'short', 'short-ssl', 'travis-junit' ] + }, + { + 'name': 'C++ Unit Tests', + 'file': 'cpp_unit_tests.sh', + 'VolumeConfigs': [], + 'TestSets': [ 'full', 'short', 'short-ssl', 'travis-cpp' ] + }, + { + 'name': 'Valgrind memory-leak check for C++ Unit Tests', + 'file': 'cpp_unit_tests_valgrind.sh', + 'VolumeConfigs': [], + 'TestSets': [ 'full', 'travis-valgrind' ] + }, + { + 'name': 'mkfs-lsfs-rmfs.xtreemfs test', + 'file': 'system_mkfs_lsfs_rmfs_test.sh', + 'VolumeConfigs': [], + 'TestSets': [ 'full', 'short', 'short-ssl' ] + }, + { + 'name': 'xtfs_mrcdbtool test', + 'file': 'system_mrcdbtool_test.sh', + 'VolumeConfigs': [], + 'TestSets': [ 'full', 'short', 'short-ssl' ] + }, + { + 'name': 'xtfs_chstatus test', + 'file': 'system_chstatus_test.sh', + 'VolumeConfigs': [], + 'TestSets': [ 'full', 'short', 'short-ssl' ] + } + ] diff --git a/tests/test_scripts/01_simple_metadata.py b/tests/test_scripts/01_simple_metadata.py new file mode 100755 index 0000000..b62b112 --- /dev/null +++ b/tests/test_scripts/01_simple_metadata.py @@ -0,0 +1,154 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Minor Gordon, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +import os, shutil, stat, unittest, sys + + +TEST_FILE_NAME = "simple_metadata_file.txt" +TEST_DIR_NAME = "simple_metadata_dir" +TEST_LINK_NAME = "simple_metadata_link" +TEST_SUBDIR_NAME = "simple_metadata_subdir" +TEST_SUBDIR_PATH = os.path.join( TEST_DIR_NAME, TEST_SUBDIR_NAME ) +TEST_SUBDIRNONASCII_NAME = "subdir_ÄöíÅ€" +TEST_SUBDIRNONASCII_PATH = os.path.join( TEST_DIR_NAME, TEST_SUBDIRNONASCII_NAME ) + + +class SimpleMetadataTestCase(unittest.TestCase): + def tearDown( self ): + try: os.unlink( TEST_FILE_NAME ) + except: pass + try: os.unlink( TEST_LINK_NAME ) + except: pass + try: shutil.rmtree( TEST_DIR_NAME ) + except: pass + + +class chmodTest(SimpleMetadataTestCase): + def runTest( self ): + open( TEST_FILE_NAME, "w+" ).close() + os.chmod( TEST_FILE_NAME, stat.S_IWRITE | stat.S_IREAD ) + +class chownTest(SimpleMetadataTestCase): + def runTest( self ): + open( TEST_FILE_NAME, "w+" ).close() + os.chown( TEST_FILE_NAME, 1001, 100 ) + open( TEST_FILE_NAME, "r" ).close() + + +class creatTest(SimpleMetadataTestCase): + def runTest( self ): + open( TEST_FILE_NAME, "w+" ).close() + assert os.path.exists( TEST_FILE_NAME ) + + +class linkTest(SimpleMetadataTestCase): + def runTest(self ): + open( TEST_FILE_NAME, "w+" ).close() + assert os.path.exists( TEST_FILE_NAME ) + os.link( TEST_FILE_NAME, TEST_LINK_NAME ) + assert os.path.exists( TEST_LINK_NAME ) + os.unlink( TEST_LINK_NAME ) + assert not os.path.exists( TEST_LINK_NAME ) + assert os.path.exists( TEST_FILE_NAME ) + + +class mkdirTest(SimpleMetadataTestCase): + def runTest( self ): + os.mkdir( TEST_DIR_NAME ) + assert os.path.exists( TEST_DIR_NAME ) + os.mkdir( TEST_SUBDIR_PATH ) + assert os.path.exists( TEST_SUBDIR_PATH ) + +class mkdirNonASCIITest(SimpleMetadataTestCase): + def runTest( self ): + os.mkdir( TEST_DIR_NAME ) + assert os.path.exists( TEST_DIR_NAME ) + os.mkdir( TEST_SUBDIRNONASCII_PATH ) + assert os.path.exists( TEST_SUBDIRNONASCII_PATH ) + + +class readdirTest(SimpleMetadataTestCase): + def runTest( self ): + os.mkdir( TEST_DIR_NAME ) + os.mkdir( TEST_SUBDIR_PATH ) + assert len( os.listdir( TEST_DIR_NAME ) ) >= 1 + + +class renamedirTest(SimpleMetadataTestCase): + def runTest( self ): + os.mkdir( TEST_DIR_NAME ) + assert os.path.exists( TEST_DIR_NAME ) + os.rename( TEST_DIR_NAME, "renameddir" ) + assert not os.path.exists( TEST_DIR_NAME ) + assert os.path.exists( "renameddir" ) + os.rename( "renameddir", TEST_DIR_NAME ) + assert os.path.exists( TEST_DIR_NAME ) + assert not os.path.exists( "renameddir" ) + + +class renamefileTest(SimpleMetadataTestCase): + def runTest( self ): + open( TEST_FILE_NAME, "w+" ).close() + assert os.path.exists( TEST_FILE_NAME ) + os.rename( TEST_FILE_NAME, "renamefile" ) + assert not os.path.exists( TEST_FILE_NAME ) + assert os.path.exists( "renamefile" ) + os.unlink( "renamefile" ) + assert not os.path.exists( "renamefile" ) + open( TEST_FILE_NAME, "w+" ).close() + assert os.path.exists( TEST_FILE_NAME ) + + +class rmdirTest(SimpleMetadataTestCase): + def runTest( self ): + os.mkdir( TEST_DIR_NAME ) + os.mkdir( os.path.join( TEST_DIR_NAME, TEST_SUBDIR_NAME ) ) + os.rmdir( os.path.join( TEST_DIR_NAME, TEST_SUBDIR_NAME ) ) + os.rmdir( TEST_DIR_NAME ) + + +class symlinkTest(SimpleMetadataTestCase): + def runTest( self ): + open( TEST_FILE_NAME, "w+" ).close() + assert os.path.exists( TEST_FILE_NAME ) + os.symlink( TEST_FILE_NAME, TEST_LINK_NAME ) + assert os.path.exists( TEST_LINK_NAME ) + assert os.readlink( TEST_LINK_NAME ) == TEST_FILE_NAME + os.rename( TEST_LINK_NAME, "renamedlink" ) + assert os.readlink( "renamedlink" ) == TEST_FILE_NAME + os.unlink( "renamedlink" ) + assert os.path.exists( TEST_FILE_NAME ) + + +class unlinkTest(SimpleMetadataTestCase): + def runTest( self ): + open( TEST_FILE_NAME, "w+" ).close() + assert os.path.exists( TEST_FILE_NAME ) + os.unlink( TEST_FILE_NAME ) + assert not os.path.exists( TEST_FILE_NAME ) + + +def createTestSuite( *args, **kwds ): + test_suite = unittest.TestSuite() + test_suite.addTest( chmodTest() ) + test_suite.addTest( creatTest() ) + if hasattr( os, "link" ): test_suite.addTest( linkTest() ) + test_suite.addTest( mkdirTest() ) + test_suite.addTest( mkdirNonASCIITest() ) + test_suite.addTest( readdirTest() ) + test_suite.addTest( renamedirTest() ) + test_suite.addTest( renamefileTest() ) + test_suite.addTest( rmdirTest() ) + if hasattr( os, "symlink" ): test_suite.addTest( symlinkTest() ) + test_suite.addTest( unlinkTest() ) + return test_suite + + +if __name__ == "__main__": + result = unittest.TextTestRunner( verbosity=2 ).run( createTestSuite() ) + if not result.wasSuccessful(): + sys.exit(1) + diff --git a/tests/test_scripts/02_erichs_ddwrite.py b/tests/test_scripts/02_erichs_ddwrite.py new file mode 100755 index 0000000..b5f76d2 --- /dev/null +++ b/tests/test_scripts/02_erichs_ddwrite.py @@ -0,0 +1,63 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Minor Gordon, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +import unittest, subprocess, time, os, sys +from glob import glob + + +class ErichsddwriteTest(unittest.TestCase): + def __init__( self, stdout=sys.stdout, stderr=sys.stderr, *args, **kwds ): + unittest.TestCase.__init__( self ) + self.stdout = stdout + self.stderr = stderr + + def setUp( self ): + self.client_processes = [] + + def tearDown( self ): + for client_process in self.client_processes: + client_process.terminate() + client_process.wait() + + for file_name in glob( self.__class__.__name__ + "*" ): + os.unlink( file_name ) + + def runTest( self ): + class_name = self.__class__.__name__ + for clients_count in xrange( 2, 4, 2 ): + for client_i in xrange( clients_count ): + args = "dd if=/dev/zero of=%(class_name)s_%(client_i)u bs=1MB count=10" % locals() + client_process = subprocess.Popen( args, shell=True, stdout=self.stdout, stderr=self.stderr ) + self.client_processes.append( client_process ) + + while len( self.client_processes ) > 0: + client_i = 0 + while client_i < len( self.client_processes ): + retcode = self.client_processes[client_i].poll() + if retcode is not None: + if retcode != 0: + self.fail() + else: + del self.client_processes[client_i] + else: + client_i ++ 1 + + time.sleep( 0.5 ) + + +def createTestSuite( *args, **kwds ): + if not sys.platform.startswith( "win" ): + return unittest.TestSuite( [ErichsddwriteTest( *args, **kwds )] ) + + +if __name__ == "__main__": + if not sys.platform.startswith( "win" ): + result = unittest.TextTestRunner( verbosity=2 ).run( createTestSuite() ) + if not result.wasSuccessful(): + sys.exit(1) + else: + print sys.modules[__name__].__file__.split( os.sep )[-1], "not supported on Windows" + diff --git a/tests/test_scripts/03_erichs_data_integrity_test.py b/tests/test_scripts/03_erichs_data_integrity_test.py new file mode 100755 index 0000000..dac4d6c --- /dev/null +++ b/tests/test_scripts/03_erichs_data_integrity_test.py @@ -0,0 +1,39 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Minor Gordon, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +import unittest, os.path, sys, subprocess + + +# Constants +MY_DIR_PATH = os.path.dirname( os.path.abspath( sys.modules[__name__].__file__ ) ) +MARKED_BLOCK_PL_FILE_PATH = os.path.join( MY_DIR_PATH, "marked_block.pl" ) + + +class ErichsDataIntegrityTest(unittest.TestCase): + def __init__( self, stdout=sys.stdout, stderr=sys.stderr, *args, **kwds ): + unittest.TestCase.__init__( self ) + self.stdout = stdout + self.stderr = stderr + + def runTest( self ): + p = subprocess.Popen( MARKED_BLOCK_PL_FILE_PATH + " --start=1 --nfiles=20 --size=1 --group=10 --base=.", shell=True, stdout=self.stdout, stderr=self.stderr ) + retcode = p.wait() + self.assertEqual( retcode, 0 ) + + +def createTestSuite( *args, **kwds ): + if not sys.platform.startswith( "win" ): + return unittest.TestSuite( [ErichsDataIntegrityTest( *args, **kwds )] ) + + +if __name__ == "__main__": + if not sys.platform.startswith( "win" ): + result = unittest.TextTestRunner( verbosity=2 ).run( createTestSuite() ) + if not result.wasSuccessful(): + sys.exit(1) + else: + print sys.modules[__name__].__file__.split( os.sep )[-1], "not supported on Windows" + diff --git a/tests/test_scripts/05_findgreptar.sh b/tests/test_scripts/05_findgreptar.sh new file mode 100755 index 0000000..1c6fddd --- /dev/null +++ b/tests/test_scripts/05_findgreptar.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +XTREEMFS_DIR="$1" +TGZ_ARCHIVE="cpp.tgz" + +MOUNT="$PWD" + +cd "$XTREEMFS_DIR" +tar czf "${MOUNT}/${TGZ_ARCHIVE}" "cpp" --exclude="build" --exclude="thirdparty" +cd "$MOUNT" + +tar zxf "$TGZ_ARCHIVE" + +find . -name '*.cpp' >/dev/null + +grep -R 'test' . >/dev/null \ No newline at end of file diff --git a/tests/test_scripts/09_fsx.py b/tests/test_scripts/09_fsx.py new file mode 100755 index 0000000..95d7024 --- /dev/null +++ b/tests/test_scripts/09_fsx.py @@ -0,0 +1,48 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Minor Gordon, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +import distutils.ccompiler +import os.path +import unittest, subprocess, sys, os + +MY_DIR_PATH = os.path.dirname( os.path.abspath( sys.modules[__name__].__file__ ) ) + +class fsxTest(unittest.TestCase): + def __init__( self, direct_io=True, stdout=sys.stdout, stderr=sys.stderr, *args, **kwds ): + unittest.TestCase.__init__( self ) + self.direct_io = direct_io + self.stdout = stdout + self.stderr = stderr + + def runTest( self ): + if os.path.exists(MY_DIR_PATH+"/../utils/fsx.bin") == False: + compiler = distutils.ccompiler.new_compiler() + cwd = os.getcwd() + os.chdir(MY_DIR_PATH+"/../utils") + + compiler.compile(["ltp-fsx.c"]) + compiler.link_executable(["ltp-fsx.o"],"fsx.bin") + os.chdir(cwd) + + args = MY_DIR_PATH+"/../utils/fsx.bin -R -W -N 100000 ./fsx.tmpfile" # -s 100" + p = subprocess.Popen( args, shell=True, stdout=self.stdout, stderr=self.stderr ) + retcode = p.wait() + self.assertEqual( retcode, 0 ) + + +def createTestSuite( *args, **kwds ): + if not sys.platform.startswith( "win" ): + return unittest.TestSuite( [fsxTest( *args, **kwds )] ) + + +if __name__ == "__main__": + if not sys.platform.startswith( "win" ): + result = unittest.TextTestRunner( verbosity=2 ).run( createTestSuite() ) + if not result.wasSuccessful(): + sys.exit(1) + else: + print sys.modules[__name__].__file__.split( os.sep )[-1], "not supported on Windows" + diff --git a/tests/test_scripts/10_bonnie.py b/tests/test_scripts/10_bonnie.py new file mode 100755 index 0000000..49283f7 --- /dev/null +++ b/tests/test_scripts/10_bonnie.py @@ -0,0 +1,40 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Minor Gordon, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + + +import unittest, subprocess, sys, os + + +class bonnieTest(unittest.TestCase): + def __init__( self, direct_io=True, stdout=sys.stdout, stderr=sys.stderr, *args, **kwds ): + unittest.TestCase.__init__( self ) + self.direct_io = direct_io + self.stdout = stdout + self.stderr = stderr + + def runTest( self ): + if self.direct_io: + args = "bonnie++ -d ." # -s 100" + p = subprocess.Popen( args, shell=True, stdout=self.stdout, stderr=self.stderr ) + retcode = p.wait() + # self.assertEqual( retcode, 0 ) + else: + print >>self.stdout, self.__class__.__name__ + ": skipping nondirect volume", os.getcwd() + + +def createTestSuite( *args, **kwds ): + if not sys.platform.startswith( "win" ): + return unittest.TestSuite( [bonnieTest( *args, **kwds )] ) + + +if __name__ == "__main__": + if not sys.platform.startswith( "win" ): + result = unittest.TextTestRunner( verbosity=2 ).run( createTestSuite() ) + if not result.wasSuccessful(): + sys.exit(1) + else: + print sys.modules[__name__].__file__.split( os.sep )[-1], "not supported on Windows" + diff --git a/tests/test_scripts/11_iozone_diagnostic.py b/tests/test_scripts/11_iozone_diagnostic.py new file mode 100755 index 0000000..d093f4b --- /dev/null +++ b/tests/test_scripts/11_iozone_diagnostic.py @@ -0,0 +1,39 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Minor Gordon, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +import unittest, subprocess, sys, os + + +class iozoneDiagnosticTest(unittest.TestCase): + def __init__( self, direct_io=True, stdout=sys.stdout, stderr=sys.stderr, *args, **kwds ): + unittest.TestCase.__init__( self ) + self.direct_io = direct_io + self.stdout = stdout + self.stderr = stderr + + def runTest( self ): + if self.direct_io: + args = "iozone -a -+d" + p = subprocess.Popen( args, shell=True, stdout=self.stdout, stderr=self.stderr ) + retcode = p.wait() + self.assertEqual( retcode, 0 ) + else: + print >>self.stdout, self.__class__.__name__ + ": skipping nondirect volume", os.getcwd() + + +def createTestSuite( *args, **kwds ): + if not sys.platform.startswith( "win" ): + return unittest.TestSuite( [iozoneDiagnosticTest( *args, **kwds )] ) + + +if __name__ == "__main__": + if not sys.platform.startswith( "win" ): + result = unittest.TextTestRunner( verbosity=2 ).run( createTestSuite() ) + if not result.wasSuccessful(): + sys.exit(1) + else: + print sys.modules[__name__].__file__.split( os.sep )[-1], "not supported on Windows" + diff --git a/tests/test_scripts/12_iozone_throughput.py b/tests/test_scripts/12_iozone_throughput.py new file mode 100755 index 0000000..acfffd7 --- /dev/null +++ b/tests/test_scripts/12_iozone_throughput.py @@ -0,0 +1,38 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Minor Gordon, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +import unittest, subprocess, sys, os + + +class iozoneThroughputTest(unittest.TestCase): + def __init__( self, stdout=sys.stdout, stderr=sys.stderr, *args, **kwds ): + unittest.TestCase.__init__( self ) + self.stdout = stdout + self.stderr = stderr + + def runTest( self ): + args = "iozone -t 1 -r 128k -s 20m" + p = subprocess.Popen( args, shell=True, stdout=self.stdout, stderr=self.stderr ) + retcode = p.wait() + if retcode == 0: + pass # TODO: parse output + else: + self.assertEqual( retcode, 0 ) + + +def createTestSuite( *args, **kwds ): + if not sys.platform.startswith( "win" ): + return unittest.TestSuite( [iozoneThroughputTest( *args, **kwds )] ) + + +if __name__ == "__main__": + if not sys.platform.startswith( "win" ): + result = unittest.TextTestRunner( verbosity=2 ).run( createTestSuite() ) + if not result.wasSuccessful(): + sys.exit(1) + else: + print sys.modules[__name__].__file__.split( os.sep )[-1], "not supported on Windows" + diff --git a/tests/test_scripts/13_dbench.py b/tests/test_scripts/13_dbench.py new file mode 100755 index 0000000..8d25ce4 --- /dev/null +++ b/tests/test_scripts/13_dbench.py @@ -0,0 +1,51 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Minor Gordon, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +import unittest, os.path, sys, subprocess, gzip +from datetime import datetime + + +# Constants +MY_DIR_PATH = os.path.dirname( os.path.abspath( sys.modules[__name__].__file__ ) ) +DBENCH_CLIENT_TXT_GZ_FILE_PATH = os.path.join( MY_DIR_PATH, "dbench-client.txt.gz" ) + + +class dbenchTest(unittest.TestCase): + def __init__( self, direct_io=True, stdout=sys.stdout, stderr=sys.stderr, *args, **kwds ): + unittest.TestCase.__init__( self ) + self.direct_io = direct_io + self.stdout = stdout + self.stderr = stderr + + def runTest( self ): + if self.direct_io: + gzip_client_txt_gz_data = gzip.GzipFile( DBENCH_CLIENT_TXT_GZ_FILE_PATH, mode="rb" ).read() + assert len( gzip_client_txt_gz_data ) > 0 + open( "dbench-client.txt", "wb" ).write( gzip_client_txt_gz_data ) + assert os.stat( "dbench-client.txt" ).st_size > 0 + + args = "dbench -c dbench-client.txt -D . 5" + isodatetime = datetime.today().isoformat()[:-7].replace( '-', '' ).replace( ':', '' ) + stdout = open(sys.argv[4] + "/log/dbench-stdout-"+isodatetime+".txt", "a+" ) + p = subprocess.Popen( args, shell=True, stdout=stdout, stderr=subprocess.STDOUT ) + retcode = p.wait() + self.assertEqual( retcode, 0 ) + else: + print >>self.stdout, self.__class__.__name__ + ": skipping nondirect volume", os.getcwd() + + +def createTestSuite( *args, **kwds ): + if not sys.platform.startswith( "win" ): + return unittest.TestSuite( [dbenchTest( *args, **kwds )] ) + + +if __name__ == "__main__": + if not sys.platform.startswith( "win" ): + result = unittest.TextTestRunner( verbosity=2 ).run( createTestSuite() ) + if not result.wasSuccessful(): + sys.exit(1) + else: + print sys.modules[__name__].__file__.split( os.sep )[-1], "not supported on Windows" diff --git a/tests/test_scripts/14_xtfs_benchmark.sh b/tests/test_scripts/14_xtfs_benchmark.sh new file mode 100755 index 0000000..015807b --- /dev/null +++ b/tests/test_scripts/14_xtfs_benchmark.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# run a series of benchmarks with the xtfs_benchmark tools on the test setup + +XTREEMFS=$1 +DIR_SERVER=$2 +MRC_SERVER=$3 +TEST_DIR=$4 +VOLUME="$(basename $(dirname $(pwd)))" + +exec $JAVA_HOME/bin/java -ea -cp $XTREEMFS/java/servers/dist/XtreemFS.jar:$XTREEMFS/java/foundation/dist/Foundation.jar:$XTREEMFS/java/lib/*:/usr/share/java/XtreemFS.jar:/usr/share/java/protobuf-java-2.5.0.jar:/usr/share/java/Foundation.jar:. \ + org.xtreemfs.utils.xtfs_benchmark.xtfs_benchmark -sw -sr -rw -rr -fw -fr --stripe-size 128K --stripe-width 1 -ssize 500m -rsize 100m --file-size 64K --basefile-size 500m --dir-addresses $DIR_SERVER --user $USER --group $USER $VOLUME + +# minimal version for testing +# exec $JAVA_HOME/bin/java -ea -cp $XTREEMFS/java/servers/dist/XtreemFS.jar:$XTREEMFS/java/foundation/dist/Foundation.jar:$XTREEMFS/java/lib/*:/usr/share/java/XtreemFS.jar:/usr/share/java/protobuf-java-2.5.0.jar:/usr/share/java/Foundation.jar:. \ +# org.xtreemfs.utils.xtfs_benchmark.xtfs_benchmark -sw -sr -rw -rr -fw -fr -t 1 --stripe-size 128K --stripe-width 1 -ssize 10m -rsize 1m --file-size 64K --basefile-size 100m --dir-address $DIR_SERVER $VOLUME + diff --git a/tests/test_scripts/15_makextreemfs.py b/tests/test_scripts/15_makextreemfs.py new file mode 100755 index 0000000..8c3fdd9 --- /dev/null +++ b/tests/test_scripts/15_makextreemfs.py @@ -0,0 +1,53 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Minor Gordon, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +import unittest +import sys +import os +import subprocess + + +global have_called_createTestSuite +have_called_createTestSuite = False + + +class makextreemfsTest(unittest.TestCase): + def __init__( self, direct_io=False, stdout=sys.stdout, stderr=sys.stderr, *args, **kwds ): + unittest.TestCase.__init__( self ) + self.stdout = stdout + self.stderr = stderr + self.direct_io = direct_io + + def runTest( self ): + + if self.direct_io: + print >>self.stdout, self.__class__.__name__ + ": skipping nondirect volume", os.getcwd() + else: + retcode = subprocess.call( "wget https://github.com/xtreemfs/xtreemfs/archive/unstable.tar.gz >/dev/null", shell=True ) + self.assertEqual( retcode, 0 ) + + retcode = subprocess.call( "tar xvzf unstable.tar.gz >/dev/null", shell=True ) + self.assertEqual( retcode, 0 ) + + retcode = subprocess.call( "cd xtreemfs-unstable && make >/dev/null", shell=True ) + self.assertEqual( retcode, 0 ) + + +def createTestSuite( *args, **kwds ): + if not sys.platform.startswith( "win" ): + if not have_called_createTestSuite: + globals()["have_called_createTestSuite"] = True + return unittest.TestSuite( [makextreemfsTest( *args, **kwds )] ) + + +if __name__ == "__main__": + if not sys.platform.startswith( "win" ): + result = unittest.TextTestRunner( verbosity=2 ).run( createTestSuite() ) + if not result.wasSuccessful(): + sys.exit(1) + else: + print sys.modules[__name__].__file__.split( os.sep )[-1], "not supported on Windows" + diff --git a/tests/test_scripts/16_iozone_multithread.py b/tests/test_scripts/16_iozone_multithread.py new file mode 100755 index 0000000..1bc14a1 --- /dev/null +++ b/tests/test_scripts/16_iozone_multithread.py @@ -0,0 +1,39 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Minor Gordon, Zuse Institute Berlin +# 2013 by Christoph Kleineweber, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +import unittest, subprocess, sys, os + + +class iozoneThroughputTest(unittest.TestCase): + def __init__( self, stdout=sys.stdout, stderr=sys.stderr, *args, **kwds ): + unittest.TestCase.__init__( self ) + self.stdout = stdout + self.stderr = stderr + + def runTest( self ): + args = "iozone -T -t 10 -r 128k -s 200" + p = subprocess.Popen( args, shell=True, stdout=self.stdout, stderr=self.stderr ) + retcode = p.wait() + if retcode == 0: + pass # TODO: parse output + else: + self.assertEqual( retcode, 0 ) + + +def createTestSuite( *args, **kwds ): + if not sys.platform.startswith( "win" ): + return unittest.TestSuite( [iozoneThroughputTest( *args, **kwds )] ) + + +if __name__ == "__main__": + if not sys.platform.startswith( "win" ): + result = unittest.TextTestRunner( verbosity=2 ).run( createTestSuite() ) + if not result.wasSuccessful(): + sys.exit(1) + else: + print sys.modules[__name__].__file__.split( os.sep )[-1], "not supported on Windows" + diff --git a/tests/test_scripts/17_bonnie_multithread.py b/tests/test_scripts/17_bonnie_multithread.py new file mode 100755 index 0000000..b8b91ea --- /dev/null +++ b/tests/test_scripts/17_bonnie_multithread.py @@ -0,0 +1,41 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2009-2011 by Bjoern Kolbeck, Minor Gordon, Zuse Institute Berlin +# 2013 by Christoph Kleineweber, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + + +import unittest, subprocess, sys, os + + +class bonnieTest(unittest.TestCase): + def __init__( self, direct_io=True, stdout=sys.stdout, stderr=sys.stderr, *args, **kwds ): + unittest.TestCase.__init__( self ) + self.direct_io = direct_io + self.stdout = stdout + self.stderr = stderr + + def runTest( self ): + if self.direct_io: + args = "bonnie++ -c 10 -d ." # -s 100" + p = subprocess.Popen( args, shell=True, stdout=self.stdout, stderr=self.stderr ) + retcode = p.wait() + # self.assertEqual( retcode, 0 ) + else: + print >>self.stdout, self.__class__.__name__ + ": skipping nondirect volume", os.getcwd() + + +def createTestSuite( *args, **kwds ): + if not sys.platform.startswith( "win" ): + return unittest.TestSuite( [bonnieTest( *args, **kwds )] ) + + +if __name__ == "__main__": + if not sys.platform.startswith( "win" ): + result = unittest.TextTestRunner( verbosity=2 ).run( createTestSuite() ) + if not result.wasSuccessful(): + sys.exit(1) + else: + print sys.modules[__name__].__file__.split( os.sep )[-1], "not supported on Windows" + diff --git a/tests/test_scripts/18_view_renewal.py b/tests/test_scripts/18_view_renewal.py new file mode 100755 index 0000000..9ac84a9 --- /dev/null +++ b/tests/test_scripts/18_view_renewal.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2014 by Johannes Dillmann, Zuse Institute Berlin +# Licensed under the BSD License, see LICENSE file for details. + +from os import path, getcwd, remove, rmdir +import subprocess +import argparse +from tempfile import mkdtemp, mkstemp +from time import sleep + + +# Parse the Arguments +parser = argparse.ArgumentParser() +parser.add_argument("xtreemfs_dir") +parser.add_argument("dir_url") +parser.add_argument("mrc_url") +parser.add_argument("test_dir") + +args = parser.parse_args() +dir_url = args.dir_url.rstrip("/") + +# Parse the volume name and the test name from the directory structure +test_name = path.basename(getcwd()) +volume_name = path.basename(path.dirname(getcwd())) + +# Paths of the used tools +xtfsutil = path.join(args.xtreemfs_dir, "bin", "xtfsutil") +mount_xtreemfs = path.join(args.xtreemfs_dir, "bin", "mount.xtreemfs") +umount_xtreemfs = path.join(args.xtreemfs_dir, "bin", "umount.xtreemfs") + +# Store the paths to the control and the temp mountpoints +tmpdir = mkdtemp(prefix="xtfs") +mnt_path = path.join(tmpdir, test_name) +ctrl_path = getcwd() + + +################################# +# Test transparent view renewal # +################################# + +# Mount the volume at a temp dir +subprocess.check_call([mount_xtreemfs, + "--max-view-renewals", "0", + "--retry-delay", "1", + dir_url + "/" + volume_name, tmpdir]) + +# Create the file and write some ascii 1. +file_name = "test1" +file_mnt = path.join(mnt_path, file_name) +file_ctrl = path.join(ctrl_path, file_name) +with open(file_ctrl, "w", 0) as f: + f.write("1111") + +# Make it read only replicated +subprocess.check_call([xtfsutil, "-r", "RONLY", file_ctrl]) + +try: + # Reopen the tmp mounted file unbuffered and read after the view was + # changed on the control volume + with open(file_mnt, "r", 0) as f: + + # Add a replica to assert the XLocSet version increases. + subprocess.check_call([xtfsutil, "-a", file_ctrl]) + + # Try to read from the file and assert its content is the same. + result = f.read(1) + assert result == "1", "Read returned wrong file contents." +finally: + # Cleanup + subprocess.call([umount_xtreemfs, tmpdir]) + remove(file_ctrl) + + +####################################################### +# Test error on invalid view (with renewals disabled) # +####################################################### + +# Mount the volume at a temp dir and log its output +_, logfile = mkstemp(suffix=".log", prefix=tmpdir) +subprocess.check_call([mount_xtreemfs, + "--max-view-renewals", "1", + "--retry-delay", "1", + "-l", logfile, "-d", "WARNING", + dir_url + "/" + volume_name, tmpdir]) + +# Create the file and write some ascii 1. +file_name = "test2" +file_mnt = path.join(mnt_path, file_name) +file_ctrl = path.join(ctrl_path, file_name) +with open(file_ctrl, "w", 0) as f: + f.write("1111") + +# Make it read only replicated +subprocess.check_call([xtfsutil, "-r", "RONLY", file_ctrl]) + +try: + # Reopen the tmp mounted file unbuffered and read after the view was + # changed on the control volume + with open(file_mnt, "r", 0) as f: + + # Add a replica to assert the XLocSet version increases. + subprocess.check_call([xtfsutil, "-a", file_ctrl]) + + # Try to read from the file and assert its content is the same. + # Should throw IOError + result = f.read(1) + + assert False, "The Filehandle should be invalid due to the new view" + +except IOError as e: + assert True +finally: + # Cleanup + subprocess.call([umount_xtreemfs, tmpdir]) + remove(file_ctrl) + +view_error = False +with open(logfile, "r") as f: + for line in f: + view_error = view_error or ( + "denied the requested operation because the clients view is " + "outdated. The request will be retried once the view is renewed." + in line) + + +# Cleanup tmpfiles +remove(logfile) +rmdir(tmpdir) + +assert view_error, "View error should have occured" diff --git a/tests/test_scripts/cpp_unit_tests.sh b/tests/test_scripts/cpp_unit_tests.sh new file mode 100755 index 0000000..f28f57b --- /dev/null +++ b/tests/test_scripts/cpp_unit_tests.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Copyright (c) 2013 by Michael Berlin, Zuse Institute Berlin +# +# Licensed under the BSD License, see LICENSE file for details. + +# This test executes all C++ unit tests. Make sure that you did run +# export BUILD_CLIENT_TESTS=true before running "make client_debug". +# Otherwise, the unit tests won't be built. + +set -e + +XTREEMFS_DIR="$1" + +cd "$XTREEMFS_DIR" + +export XTREEMFS_DIR_URL="$2" +export XTREEMFS_MRC_URL="$3" +export XTREEMFS_TEST_DIR="$4" + +cd cpp/build +make test \ No newline at end of file diff --git a/tests/test_scripts/cpp_unit_tests_valgrind.sh b/tests/test_scripts/cpp_unit_tests_valgrind.sh new file mode 100755 index 0000000..2e9aa20 --- /dev/null +++ b/tests/test_scripts/cpp_unit_tests_valgrind.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +# Copyright (c) 2014 by Michael Berlin, Zuse Institute Berlin +# +# Licensed under the BSD License, see LICENSE file for details. + +# This test runs all C++ unit tests through Valgrind which will check for +# memory leaks. +# +# Make sure that you did run export BUILD_CLIENT_TESTS=true before running +# "make client_debug". Otherwise, the unit tests won't be built. + +set -e + +function warn_missing_url() { + cat </dev/null || { + echo "ERROR: valgrind not found, but required by this test." + exit 1 +} + +# Parse arguments. +TEST_DIR=$4 +if [ -z $TEST_DIR ] +then + TEST_DIR=/tmp/xtreemfs-cpp-valgrind + if [ ! -d "$TEST_DIR" ]; then mkdir "$TEST_DIR"; fi + if [ ! -d "${TEST_DIR}/log" ]; then mkdir "${TEST_DIR}/log"; fi +fi +export XTREEMFS_TEST_DIR="$TEST_DIR" +echo "INFO: TEST_DIR: $TEST_DIR" +VALGRIND_LOG_FILE="${TEST_DIR}/log/valgrind.log" + +if [ -n "$1" ] +then + XTREEMFS_DIR="$1" +else + # Try to guess the path of the XtreemFS repository. + [ -d "cpp" ] && XTREEMFS_DIR="." + [ -d "../cpp" ] && XTREEMFS_DIR=".." + [ -d "../../cpp" ] && XTREEMFS_DIR="../.." + if [ -n "$XTREEMFS_DIR" ] + then + echo "INFO: Path to XtreemFS repository auto-detected and set to: ${XTREEMFS_DIR}" + else + echo "ERROR: Path to XtreemFS repository not found. Set it as first parameter. Aborting." + exit 2 + fi +fi + +if [ -n "$2" ] +then + export XTREEMFS_DIR_URL="$2" +else + warn_missing_url "DIR" "second" +fi +if [ -n "$3" ] +then + export XTREEMFS_MRC_URL="$3" +else + warn_missing_url "MRC" "third" +fi + +# Run tests +cd "$XTREEMFS_DIR" +cd cpp/build + +global_rc=0 +for test in test_* +do + set +e + valgrind --leak-check=full --show-reachable=yes --error-exitcode=23 --suppressions="${XTREEMFS_DIR}/cpp/valgrind.supp" ./$test &>>$VALGRIND_LOG_FILE + rc=$? + set -e + # Add some whitespace to the logfile between runs. + echo -e "\n\n\n" >> $VALGRIND_LOG_FILE + + if [ $rc -eq 0 ] + then + echo "Valgrind memory-leak check PASSED for: $test" + else + echo "Valgrind memory-leak check FAILED for: $test" + global_rc=1 + fi +done + +exit $global_rc \ No newline at end of file diff --git a/tests/test_scripts/dbench-client.txt.gz b/tests/test_scripts/dbench-client.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..7caf8f044e273f42db677efdb041ef212a8ac6f4 GIT binary patch literal 1880893 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

    Vjl#I!qa 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

    o^R=eh5UAoR(b@Bm7;5|WLqBW{6+|w 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

    qN#NNGcX%V0<|T+~DSU^J?DioxoHY zca~23tzXFZ^{S z?vR%t_#6@`Q8Gd%=v>4ZrlLP)cD+^VMlsj(S7_yxblmTx#u{Jvah2uT9DpBie5lQ- z{%frKJ-z^LQyoQA1c0}56uBJ&R=%DaZ_2QDudc^XC@%i!gX?OSD>FKcD zqoJ;+?BJLC6*dQ315+Dkt=iHH>2hra0V%mKn^RZ@Qao~vl0w_X z?CQodLS-9z1r!o%HXNa24Yk$)Q4O_`+Oi5j**sG{>4Bh`jk?-Ao&mhAW0XQ1>-;&* zvsY#Bl6h72ot@=JTU-`Bzl!)d?TEGn#uLH&$5ifDf2`UihPBsnpEc_+x*E)$C3XK3 zfQ#gJN~!69oFKRl_5QS1M&dzy-W)^z;z%!TIeG29HyyEu6=i4WBASgp6)VX$%7*|b zjpY8Q3vdlWS@)5w1N#nSb#xk~!ou%Y>fchRmZK}`-537EHR_5hF_Q9dyJL{+k$NlP zLbWtOR61f#m+=~-wK4$H8rL&?bA)yXrOA&7cU4&)?n?2nX-x2VR<4NlET6uq8PsG;4v;&b2B*BvGxkfgl) zMbQdirWDcCbibgy=D1}2?zIUf3$MqNy~L31h-^Pcs5?lw2E1MoAe2;^Bg4j3g*CSh z)+7mRWEA#xoY#akYk!x&l3iSL?CYC;jJ%o7h=?l_a+Ua=_AL(?ReahO58_0S`4qf) z!j+XrI<9Zb4KX!!_h2V2i_u-0jJHT}-*^)`Nw}R`Yhk{WZEKV_*JZN3}vtjwkRiiH%O#*b%|?EYq#i_t{=( zfQN#lD`m!bFcHO@F4yC6jwDrbi46 zL-iwHVXwnj;s*8>E7_qA`hyyeF7SS@$?5sLJh|ZHqpo4&09j)zVtCo{(fjGPN2^jm zuicwa`HIP4ZhGeP@kBuT`xc+@z5n4$gi!?1vQbflYU=RFS?8wXapd&aJZA)e^p^*7nJnJIX5nLHq?Pfw$%t2RDW7BdFKyMW`+-uyh5l<%&rhU8*nDc z2>~%vh6h3DGlK%9jeDd-%>TV8L*;&_gM^Z)jW<{IjA+A!h?^1#QV@If8*%pxQ#r!xWE%d!?rCCYRV3ISKyugEs?? z9gCK2JY{%8<_zC=D(gKJs|o2+c%1)a?FGIDzkXEOjWd8%#%*c#@~NOqkG(zb#k_;L z1!OLb1K;!|J6O(BB8$e(P%!t#^c^NHyF`SLwHA#ota;^*XfB!hx_3g_bdGs1>jZjbs66yY4-3e@VN zMyh??!1^{6hxJGnQ~P?preh1DO=>;jG#E0qV~a>l)~!77f8c9IJmqlJ75fTckWPNd z-}pN9iEle&sTK_f+tJeh?gxU<7=NQV+u5+!#8fP8@4UlVd4|W=Y)=j3#n+qblb*S; z=g3YyU)xjwzwCw@f(9zvo3iDJW@g&*Nw&L-prIWVr>?DxJy`u=>G)c2wvf!i+3@s{ zE~{-qFGO;T9Z}Zh83efDHIioHhO9ylw)xgHJS&f4s0<$}6g>+wQ>OOC&ugl%>y%#e zrO8i-fU;K#v1hppu@|`}%CxU-uUFe@2U^?xpC|PWnB2{}3VO|{1IF51`ClD()T5#m zQ&$E7X!CJfs*0%=9BB@zzfi++XzRn&I9ivA)ht5PFm=0kF9H>KH8{C7IQetT0n5py zx2wVt<`M)++223s?9!#4HFgZoRnL*=NJkuC@v^rrHI0s_d8Wy2zRJi(d^iH=Mqo2@ z)_H-NfrP{3fHOFOnt{h+Gea4-1+q95Fc_;3%L1!H7m6YyYzHq&hZAcC_&y7<_S)Xw zcD8tYYW**Nn5}3sY>5zw@U-tqqTj}WAE3sqMDR8&Kaus0XA0b+Po3l>dbyH1vxAL| zK@RXw4G^H_8TV_K$lP{_<>G(kp}jpjSn6|mxJYWAfVisb++1czk0evCg$Tes^iEc} z;KV)jNmhy03hX5&q+@cQm;_9vYB5y2d$>B!3#tN*294VLHS8j|y34;LDDJBPU^`|5oYZaHP?$NWIWc#(g-zH>>6WsD%8f z5#8e1_1VNMwig2Ig)&%Ix1|UBYa6%K0`^pVue$Nf6NN~TLo9-36^gcCs-2oBwE@R6?;?aS-e zv;XD~6(0bIz>JEeD*XNPDqQRG&sZQ^e)$>hsk+yKM-H2D1U=_kez8j*RJY_=B`#RhCG-FM3nL z4&G;7!EKmqm&C38117>_%Z#T=qVero^X4sAK1V;!?}Xq0=b_X9i1{;u|gD>vc^ z?oj>;ws-gc0uN&eYQsMSXhBZCd3kks`}t_UJi6ghf3*;peweBJ_3LhV;CFEdS*u2` zecAH2*SE%lvrH;$E+=-To{Qi3uy`dD#L5f&L9`qr_9u3n-$(#Wxn-R(mD1N0`0P-p zsWkLAxxN*6&)p=H4wgV{ei3gni(LT|yg>X4b(W<&?LAF?5vK4Av?SupcK4E1R z6_HN_B^{>8q{*rNP?Sp(BcGrkuSCXdU?go)FB2h$C%zUeQ-fvJLa5Rq?8`=Xc3tB- zM;3TT>G~%=G!o9i5J1G@{3(wx1+EU3d3__w0qrcYS)Vz&6k3-ID(-JGxO3u;RB?Lf zMqafO3qcM2VBZ#NE$A5E`%@Q>48Lku(C)PWG;!}*a36r&-Zv`glr1>7Vj+61E6 zIWnx3&OkgodILT!B-Ts3D{6(p05T$VXe+iN?jjH<#_OOXMKQj~1$tjFiRupBLY#f@ zoXSjp`3FK|{J>G9BfCcNQF}HuuQKxku-OyNE7SvL{|Kh!ga zuw849o7{-)SD|t%sI1zOCDWQ5j$?wCtzF=RSHvezcih#V>*ty6Z%2SXcA?LisCQx< z>2Lq=uRGZAzoQy~P$`ctHN~f%x@eiJ;!upD=sPlMApMEM8!^e|)Up%GvMgc1@ohnp z%l;^`zP)OJa;eV_Q@UQNx`W22z>SJx#b(w-Jp;NtFC_O9>4z5~q*rVe)~jx;HH2^k zW<;DDMH{DWOUQR!t4a*+`6Ng!?ujmQ57?{e3wEP!w=uY57 zd)O85j(=>`jlq5NuISeh{YNUJ_J0U$491+k(cYZ|@4G%0(AhJ{wHYS4_qh&Sb=G~) zFr>@epk8ycdW9pGFKv)A9*T^gMM<5m|rrP|AKm<@H$dPb# z&UK|0b(?&<=+fDnbTmsDEiYhgmmDLHQ+2a#hvnX9GD)G!8e@w{^^Q*5+2qIotvD*8Q+i{buFC4wQ-0>Y$-QPq zSW6q5nf4dxwA{G~B3-%(tCV(*?{0<#*Q zOc#G=HO{}01r>wW0J9nwm#!P{Bf@P5906+!P;k~y==EV-t$XLOkI8`{vqP-T=Gx$0 z!|GWY^{RpG3x(F64I2Xe&Q=_u=qRbXPo49i6M+dV;^Gh=S6(wh+71J$;=p*LShh`y zI6JCP9IWK$nn%1$f*!g^nNox;KOzjn(Ft?ICYnGDvrZ5jhJMkSCDntG4^J}=RB%%@ z)*KO8aLMO03T4Z9bBd^r2I*LBe&mNZX4a|Sslb6+vpW>-4%=Z5pQhDJYE?D0r59+S zg~DGljwV4EW^>}Z&;Q^XYlg%YhqVqB`jy*+`7jY_qxkF8q_Mh{T@-~Sjq*Eeb7RH@ z^=v!%R3X>{2IPebR8s@-2nOX4RI;KybE6rF9UQu1n78s(&v%iy=9Qmc?bl6e5V|Jt zl-ItQuw1+4H}Qc#V`Q{9=8Lf4G-D+z^?e;eF9$ZUw~vznMm3fjuTxQul|PaP6z=K@N*5G~FhMx%AZzLJ!QcG>C%LC0>kl$?;Xv0ZV??s){B!!U zD!6FS|3Qi7;hEum$WkWFXaO)!TM&2IuT};y6Z^4cqT)3@;?$hV=6m=vubmnj;3!vJrjvhWW_xa-w9>; z0|6rDSpWhBill!i@O~W_vn^m+V{jV_&R01CODyuOuT@Yuve3yWR>4@4I>9G_;`d&i zoh5Qezrz|mm?3W$&d&Hc#%&Cm^r{PLrZ|Y|kiv(*Sjny2lGA_BSyQW(t2$qj#d_%S zFy@nK5$j}ulCBykbf)T{yibGiD<3fDUodeYJY_B;I@MkcnO6=fIszXhL%tmy;J>l@ zI01$BLlcr&d*I4xV{|v1(QVZ87$7G-)Q0BJcXUoH5Ajcew*lAVCBPC-RTV zkrsMR>O{Y&seOnT;G7!W(V0?!=2?HgJ?z~GxXitL`B?VXEWkj#%E%#%IL|FyZV27lr-a3a6416M z*q=?2GOiTuhptAv@RIkSts8 z=vvfs%#Tswx|lJ})FN)hVvLcYIliM5!MADG*5LaVtt1;uKn0`l3U_?4AJs4$NlU~Xd!lb%pNKCNEb(X^bwtv58sGhmHP z3iGi|`!kxH-HFW>wdydkHg)W*x?uI|m!glH2Os+8SSj zQtd~Sbpi0z3*1SM8RZse>6CL&EHmFw2;e>A_aIRX-9eC*i=^gyYLF&FwCi98^^b6U zaGHG*qb;)VeOWab_@XTWUBp$2dZ5l{D?i}pgCuKWgHr>mH9i)~&Z{Ndc*k3_Ni}Eg zuT7fRAL0HVZ<*E*Oqw^ip`0h+j`&9z&O%dwKU>&jgEw5pdEuQWP9!^p9iC9UfEVKS zMTCR2)@iy(y)BtiVF%~Z6c?0EJZ0>ynEtDqBb62Hr1raA0MD!k z-S^ZYEcFNw#BeRv5dO29j^DpmG@U|z^F+Mf|CuKqZ~$P|R+K|-rlcuwhg+2)hk;cW zmjp-NP7_(bfK?Y9y1~;@1ICcPL~#t)`7gW0mOoam?;krwA|Ic3tphsm!NiW7{zWJn zUeDniA)J0fm{&{R>@HVSB`G#fnNg7;SL#M#5d_bPhM#7vSyeR6GRY%!Ku%va`lRPY zX9_j5qbx2!_yeBP!asLl@d5zDK=1{WLA_I~mTBn&?YfDl(#$r}%ytcv=kk6Ch4mKN z^4yCsfi&JU1rltGw@Yj9JIhQmqOX2efqyX^bC-bc%Xa{M0@ZteN^3%!X~cHm@$(UI zx>Nmi)3>9d!u$>N--x1ch;fyoQdHpMAYM)oA)MsGn!I365ur~s=RM(~0<%n1RF}>I*d65E7Qf# zTZdg1xQu(WByP=YK#2A-eC~xUJ9ErTqhN+X908Gb&W&sTe~MNg6WzelO>r z9Mo-Mb}FufI~bw!Jhm^&4Dpz{?gnC=Gca})J>CAhu5Vs|fpC4jWQKSI_1{4sgW6DT@!Zw5r%_zmKvWwjLQ=Kl`TF>?- zOO6<{=T&*zS8d`N4e&nLpBJDFLeXnuQBtI+w71OK=T%&QmG>RmztDp|r+{z!jR~N# z2PAQ$MxxlEDTXEOJjyxAVPPCsZa!3u47S3EF~&`KM2kK(iZZCA^fBYwtrFWYl^*G4 z$eQ??2#T&4Dhsx7zx-Scy}KmmW#Xq$>Ct!lB#BP0a)mCK<8eklPB-l)RnK510rc7Ru6A zQ!A`G|M1mnzoesJMLF5xZd0)YD-UatNUPNoIE|(IwHFz>!cIy;D@AUJkWxs<18d|0 z4BZfLLF*Zo!UH13X;-<_pJ;+)Xl$sk5{%s&hB^Y@9OX z?n?eJ5)xV%kKw=s$8~vNg5$Q_hfbSpngYO1Jk)j_OyG*fJq)aY67px`Yyb!xLy4u6 zZ9cb36Nj>##uTU8RJ6*(pbDXLhSY~6)Mt8Nh-1yOl=S!KPr!`>Xz98sb&w(RsE?y) zz>o3x*34)G;dS|Devox}3FD?I^@*qk`%=P7o7RlA(gvj2myyn+UR#I31=w%u?5Z)% z6MQ&q&a)cDwoU`ycOx{}#q%it(t83w%C)2?0QhHLfY z<-DXsv3|e<&a1KvuLpI-bxObPhs4JKxuz}euC|yuU22bk1r}rk|YvttGk%tBNCb-m# z6qW4bT?``ZV-7vCo~&%Hx&3f3;Pse@@VhB4PDC+mQQJeYWs0^4tq$)^C6$v&Waw0e z54B=Gv=}yXP>I8=xG03HfYENz(B)C^8puP5x>aisz`>$1g>wStHwK2qG?6mv7Gu&l z#59Gn+#Gru%0u!+v;;8~-qdiW_2trOjw^W|arit)4yFsy6%sBa$PU=cY=D>5q3SBg zG#U<$wgda{MluhD*WE4_?SkvXu1yVKWk(bpfp$?-N<2%{d(OMC@oI3nP|h=il`XAc zUqN)ToD`10A`@fRD@{p;X%hiM91S_iRm6amq57O#l`vKMO5eea~+V=#Nl`>wr|*&K*>s(czM>){<*JsVrdU`PNLmn%@5&(SN)&of=1;~Ha7Dq zQat;AFpReFxE4c`QuU_r;-FH$Z0T5DH1wyT)U@UvfriyJr!|GAF>G>mZNDqMlHy!T zK?OZ~EQ^}S&eYbr=tmX@k<^-CtT-^nk(vf|zQXk+QZ6bPS&l-qIu+&)3oS9^^~RYm zsMD{C*hLIXHoJhQps3JMF@U%Lco)5gr{4Ic0cKz4y7mpf#RdP%Uxrc5yM+^pEB^`%P}~>C7Z(- z^;}AMF@frFIAI!49{Z{IJ%>6o*H4>c{Lw|UUO}`jsgeAPEE198x<#LyqJ**<>ZrQ- z7(m*F_NLks=BJzLUhb<9;TMOaD`NK0UIG-;WnhwHZRbmN1QC$YkI!-q)5u^aHQ?s_O_Coxt?w6nAODGZM0h9#gGF%oAXNL%DrTXL%VNtSc#bUOfIq@)NI6Dj z4>e{3h2(_xASY*HAi?BL;kvjWju|Y08Z3brY=IeUff{U~5{%rr?j+}tT5;!`lB=o0 zh~Qj9+Kd2A`0nL{unVxj_j*|dzde(iJf8X6F(%B!m=3Cuhhfp~#PThjX1Z%*o%`C$ z<@fb`gl}=6(#1>r+Fli*N;G0)NV-m4CXGr1gIEKl zxG$ZcyvCFLF$VX{YcZ}!zRZ~$Y3$u=kT@8jZiIh0=nU%SVJ{_GH{Akx9eh`IE>r$)#Kfl2A^dpqf^%mq0-w+ z9A}?6Z0y61zO)sx6pgCm@BS-uO-PB1F+M@-CTK} zIQQOmmv=|*mLH>yzC|%0SPB?QarKzP-l1H}1y)XE#jo388O$wXR7p1U`G{~nl6$MG zYEvckODyM;DQOZbsT=_2nE*gbEobA;oo>aj5wS1I4GoIt-J#(Ef+5cniBZrLW`#Pf z9htErhXckwP3_js(qmOhVw!RcT)mbnAU17Eg(HPJ9VYE*cHQ>SP_ z;r?`4N_OyzT#LP=5Jt|6k`o4Etz%QPBg(72SGB->b#5%C< z@7J^Ua)PNRamTDx8k@(C!>!V2M}8N?pOPUVxNJos?+)FX6w|IA%|}AHnK4$<`2M&Y z@ZMTw(vYF7%Cickc-qF|TUJT(HR+_7Ga$)Hwfbw$!tw>>MwZh~LhtQHGte{2of~SB zD%!xEF5=@Q{Lz`8W&V{jDvp~w)2I>a&|)$*4EdwWJyB{dueGf^1N^^b{Wr~MqyAen zsxD74%wkc3h>XQTA<0^@JB^t`wTyzhDUTO{4yqD@{tIX9Pog^tLXW#EIcEDbbKx!+ z4|?l71a1@$=g0FUpx@=hNgmE3E!@ae(4RqzN2EH7+M>KO2%W0xI%yB9OKI8Yq3eJ; zuOGlLEk}Specp9I5Af!E=~{S|*#mBS7~1R@20xEC?lbin=xwy9@b$QkdecDOoo4W9 z{rs&^t=FHSezVO3M%5tTd#3M9b4#ov=x*pTB!H;ojrV17Egbkf{i2Wc>;@z}))Q3B zKX*6nCfQu~2fa-#e@Pi-fCCpuTDp!AqlU0nR~@OWjsfeYmB+&jxyIub;}V|5?Fb5) zo-J_XR7b%9DVTQ#kIan+t}y@J3H}O&LI;Bos4TMM3_RI|A%j3sXkqL?>Vv<6z+ggf z25O5KgMASMXV>IyS`Y)S2uCJMx!DAa* zOx__$)RS;Tic)Y%%1lyoV>qEFh)z-VW~O2+kF9($(%;3{?8VqEf2WMTAZ%M~8C#%Ii)10O{G-=nA@cmU1lP2sh~{tUmb z_fu|y8Xu9=X?>D%Eg#QFbS#+uxDz8@rC#UF3#}Hh0f4p$HVqBE=w7SF_FUk+Z6R%H z3d>h1G54UGXzW^|^Qkr9wf6m*=$+cL|C7WD2b$9c_6ht?MHgtLZ3n_H-+uOWh*Urb z89EEaG6ZiEYoJQ4+xriWI{RMA*kW{z6TB6%G`;0S5&NNAa)fpNMOt?Hj@{ zR#MBqAmE*hc(lL(31y5PZQ|1D?phZ4U(dop^T#eJ*tS09dG( zy%r@^-!}765q8KsAMOtcBAL@rj267uad#aaNvTGBNOMDK&?-8gB2pKS=p?E)%Lvk= z!KB;&C*SzlSVj!wpx>)wtr++dx=~9NIp5M)rQ-6QYx~p2)Mo`%Gv$UU*aqm&hJ(Zh z)}zB~Y#pp6t>RGnvaU8X&~^GQ_dYQ{$?Len+wbH%HU)mQUBwH!vsAPm=it zOZiLF6bl-xV3On>gB40!Td<3(?2}R<6$)tTDyP|n)31KeX`r&O2BD9&dPD{r>EHks zTj4kUGsy8bZ{)Q9Kk~*7O`8+yeMo&DL}5VS2j2Gg*Rsr$q2wHLC6}pm$!oT0XIAg{ z;{l4RSQ74lsb!pDxu7wv8&kK&YRsI2v zqnmLc8C{($8D#K{>`c9(yVQL-P1^oORASCCTIzdZ4AOq(?SoQSPL7#D6Iy>MIP3!u zOP*zxcsR<6N#6^$0dwuxQ--!>yYq8V724X#(izJmxY@7g3>3fs$C{h5^~KU?DVa96KAI_%5Ua7mYSP#Z1khA^Gk`Hocj`mD35zLF5dCN=Ig^JGvQ3-E*U zlqIeC7^J@bsM{gRjT`GhpO6HJ_MCk4l|cZrO9IuaB7u*euG~58c3yinmc_3 z>U7Tkea-tvC~C{u0&IvnSsw5MP}TJH+HZ)d^Xyp67o<38SGj_A>KSr9?`O7M`0FBCyaVvw3?_>~J;t9gkwD<%<bvIqd>;NiVD=L4+5nP zc8kkfYqi;YRzr2_WCzjdY}R|$e&C}Woap)BAv>D+Y$8=MVUSoD_f`l0 zYy8^+BE!EC$L6h8p^3zMdGpT)S2y*%Z-qTZikub#PU+e6<{fORdpcI;cmc^6BQP2- zav8z~yc6>7Kj#$HN0XA@FrQ{;R@O|Ys!`iZn?8!(&CJz=%XR%|;>mgqM%?ZF$q7Df zYXGkh*DyujT3~UA4;|ld#%NfWpf$D*oNVuOyfAb`BIE9>JgMnSMK&3#sqega77WJh zx*;S^@N5L;H=bSFZhJW`ynx#Kw#}o9=iz$UlL7M^R~^_^ka`Vw?4Z_n(~)wfjQL(^ zgU>E5#I)ps{j67-NLOS`VQjmY>4g|-lU{B%A`plcVbeI! zyxO<+gSF}Zc5B##+i&ANpdG2F$$Tv0phHz0+Gdfff_9LmwxkoOr^vMi=`!I8zybCo zxBuQ1WYYXE^X(Y3k{2+iqQY4Ji8eZPs~|ORMzcY)RD&-5U#o)*Lm8~h#1O}U>5WCd z(;H9n{#VTadj^;#huJ=NmTgWA%m~#Iec~sm=#J#TJG?ovF=;SE`u5fK{(txC#mKqqub@xAct_8ewr23shZ2k)KHv5@425pD72N7>`ZR-oYPZOlY)WN_qa2>| zcX3}&<~dWiyrNpGCjb7hd2V$M@QK8%;2{9QM!A~ssV=2``-+1q`?_@;Zi%$)xMS5o zUfS6M0*-7B+VQBVUa0Aym4-)RjThIn1-s80c$Y{<9-f#TyYW!Cl`SUX1VaY{<9%L( zGN~!yOgiKCNx7a1Kf3S@SF*Yq7Qc-E8|}2QQMT0N=FW`V((vBus6XtRrfa^DsW!az zso>`oRqU4Ip^9-*-m6ofcQYlHyL8S^o@*W$*3SGZZ(Jr4o@yJr_9hscN+O&p(;QT$ zTwUN-#kT}F+b@#2ORu1UcUDN*4DfT*G4WoRFCU7xvG`GUoxMF%^hVlhoUE+x5k3cr z;tkm#uqk6ug-^Af&i034G+RdjYZEc(nEe#0j4e08W!ZI6h|x!Cu6WpVQQkv63cdF} zELTS|_L8QI9hDCEB`pCp3%E0L*-JXEgCIWuUlOVZ*r{iITRk4(12mw62qh(D3)#{t z>LtiH^&Y%Wlg-oa7X&VubrSc?jizLm@$-rN3e(B@55Td4 zv&z^xG3Yew;i-Z7~Di%{CR8niSEA z?EIt@nc4~6iQGItUM6iiGEsCq|Ftg0VKcR%$3bVJA`LBA@%X~8i%a0rlp|GzJO=_h zAl(0HARbeP#ztGiWhGBOez=4_eU4(}*NZvu`!-DXo2O%`N9gWca^&jJr5>Z+r4CPQ z$ou6}6lMWJOB#o2UlR~c8K7>*9q}%w5?wByc?SGaMB`78~?aVDG8TQ~SE!lMNuRdR@UDYo=+sbE0*!(c?18u$9WOd#C5#6UV zjvz+SzBN462vxQSv9@6|={K(3@t66BZY+)h4{&&V;-y@X&850bo}_F0SKUZ;0lzP) zIdl(6Ha^wV9MnWORwv6lF*#A3nO>InA#d`dK#)57cuJIHn97|xNV#9aw?j#r6S4`0 z*s+iKGOV-22<#=W#r^ujSZ4X-jPR$`(Gr>^83g``*GVny12RW6n5psV#qe^4g=iho zukbcHn5nD9x78T5G8Rgh?iSjra;(#*JJyTSfr-K96Dt#CJqKF3UuLQv}&J{d}EscND;edCuYSO zLo~&6iY@&EC?h<6IY|R&>zlh*Kb>BtZINc^tGb_HYs3$us@=C5OC1iQOZe4o>9lIJ zD?SZ&jHlA6zZ04HAC6;6Ehcblwz~|efE{`L-Ua>oxVf7Cbt_dHy*S_4CE zDope@!O$uyL!4V21TgMEx}6=?$5VB+JH_hg4as--PZ{|Fj%Xg2E!^JxB8kP2)8I6< zPnpU;rXwse*_zgOA|K2pg{YCh+)Po){R*S_jTz&kX?0wjdfC6vX*IGb7P^s;8uF{1 z?vnXfS^F(fWiDILKd@T(lcouQEgiRdhXm){DV{!Jw%t~^-VB}f@E;2JYRp?dq}={+ z*C@;FlK!EfQMRcz-Po#;>v5`Jun$l4MCBrp``BHJXILN0eHDSMF+i8*Y-4W7)ny7O z(_lacQpPkH8*`oC`}aM&VpIF&7Fl@O%W-Ggr|pv29bdcqEl{+!7Ak1s+Rm0!fah#u zsatp&9!H6puBglO&3~ar0c?m-@lCDAoJ@q+08vWtf#u{e;R$ab{X^iw*07P4iF+IL z5k$t-W1M*+*&q8US0!CirUJGXjZC7a_=Kjf1=NhHGm*Lu6@sC5?Ilnx8bk&48!F(P zH^?M(G+xbT+^C-Z%O|O!SvB(r3>^ApEDYb=(Nf22s3MnvB$!4;sw_ypU2*DIe_5vZ zv}s^@z9#uIkfZay!)gqGBr@9MpuFD;i1BxWLC7C zLv7&Obuy8wZ+et9sjqrSH4WNpEk$dOYM{oPbO6&^DQV_W;WLTqKaWL*iIZX_r5mBr znv$G}(@O)N8ZV4-)cmqG)wj|w=w*RI*iCL^Md`kQ&M&hlEwjf5^(I|HN*2=5W__c| z&$>=R$?+mkwdL6!yOsRacWKS{hB|%~3#4O%Pc>BFpwYern*48RUCL^jRYDsKxdV60 zzoz(l3zOMKdZld+s!UP!E*TxYQte!EPgyw%y@u6n9$$-Q`14lm=X&-FvhLX>7pc!9NGyz@@Z7>Lx+z-Vs9qs?JKmbl-kfKn@`Q!42;Og_^Te7|+M-@fE68fb z(Oh6-aNSd}xZqKtF!fTQsdhNGw$xQ?!(q|ZR0&j%HscP~Mh}{K1(Rtsb}hlTtT-7B zy4TLOh3PHS!HKh>L*Y)Rw@&< z2Jt%vl&HP1kp@>~aHOad;i>CXh%6R66}|{p6E70jCbgajdYyttMHh;x4Yg+R>#1ms?gP9yA+i-2&|8?f~^Qr)ukIr)p*fi)Aegi)F(d6-xGc6$)|gH4Z1i zMU!c_qiGgO>L^`{lAEuazvg{=C385&Fpm-Iv9+32oq=>)eFNBfK+T!0X+e4jNT&hZ zMrY2Dy+?OlneNEcyZOOdV}T_z7ZZ5zp^8J^`Alc#&lH-WYn0tJNzr5+9au|SXlJy5 zwkaCju)CP*k4pF(dMoo}ucRTzX^BXzNeF(5_6I?)`m%ZD3J6ccZ#BE@Z zh?5v=p&BI=_9t@bZ!>DY?r79Sh^|ExC3Y4#({B28LK z+wdqtq)`%SCf@FSS9a!=>Yn1~xpgPf-)i^sAdrW|gV%tzkTts~zKiR&oO+jq*NyNb zwoot2y9ztIYU2HpXZL2Flvh=-eJiHaYGoso2T7JHDVK z5>whYwpOwhc9m(R3d}p)wiAAT>;pvpV$V9nhRRCXb>j%&mhN2q>Z|>1&nBmpYl}#B z%MJ-;O}ouB+qom$#Q~?4)}%EeC{-)*c-)~SIM>U$pP6p2tg(Jq=G|f=+v}ITM56{^ zEN<7XC1rU9PhV?%G%OOohSr_(6cbV21zm1cLR)8ZYmx0Dreu_FG%=hGCDAxA%W(dN z*S}G5dL-t2P|{Z6La|=$FX5Q7IvjrRw{X<9o_cT(2Cemiu9Wr>A>D>Yb3BHO`amUG zoC^c02^E<>4)V8fB>xe;T1#@5(n~HKbWF5nRLD^eF?<;D{)N=D2l9|9O5#nGYZ(7o zF6kznTxewA9ZE5^{JVOTLJlp<=68xibr~ICQsOF+$|wL$k6XjlR>8r9l{%Y)=OR#^ zSA(@Y`cAP$2qLCcC}T95mz?Vx3D1DmsY{02Zx@L)Cdy0RI$Mz0O!#1aCT=+Nmv9t~ zz!>3QghHy}vopT#7yv<7CVa=OHBdX_F9&4{31VfU=4Hy|68X?Orh$Sd8jK6vS-=f`wQC5MZ5u|1H7PitT%-pQMv%~oDtzIp zab6HnjU`Z&iUxs~Uei8YB?A7D+4XC4Ylc81B|*`sHq+EF z7tfxh{Kf${Q(2nUwe922aHyxzG?&9j9&Zt`Op3At5{1%NznT4pp)Up+u*2?NFJNpA zM6=d;(*X#IGyG7?uwe#X5LAAT&H>=#Y7RSSTJY>jv)dVxBm=`Z0k9B16d;r?_}8`KwdgjfAk68~i_!qc$*c;Wu)G*bfB#gB*tl{bN4c7oY@V z`Vlh<6VgQko2-o-EcHZMjq2dVo`3gE9Nw|xVqRB(T1TApNbd6hZ`?Gm+st=_k^EyE zqr16qi2oSJEBk(!)t=l4V})Kb?of3SqbL*m99vLlIXxs$s03L(Lagj+~aCgFRn%C?vC)LJuDnLT- zVm}NH#?HsL>nk^4GwiG5#kaTTv)!BfgptJBldYD@Q>#z!IyYkz$xXi85ZHMKi+aJH zg~wtG4LlwdS4LoxoI-KYFt$m+WW@zYEh=L?DKc18!sFf@QrP)6Ol(Hj0{lwMH?seS zwYva{BVQY~kGsR5!9#F&C%C&i!QCxbg1fuBySuvwm*5sGIDsH}hh%rp?%6$$e9u>v znrWIU0yWG`)BV5hp8+ldt*9spM0n|rhO586%51!;!@7n#H2B8d=Gj?B^~JHT-dA=X zJ&m5{ShYgN1l@Z0jYDAtaB;mJPJ{A9hRVU4pK+trOWbJxGj6n?Ofz)WT^>0RaDS!g zO0}i5_*rqiNJKY+={W+44A00%Z(np>7r!Zo#@DevyXnWbt{-PvL&zlBA!d_5jx45G%lq)BvXK!KVoI<$O(Ot>mh1{q0!S-j(<=T4S<#&T z1TGav;@Hd%znKc-(;8+Pqiz;OR9t!Udn~LFz}+Qyy_2j@7}5 zhagh7og0_*TKgQ$83-$q>7_bDwPkD}0AWRDAgst02ZR;>y5aaYSTSi@;0hC`C)LG< zl$kxxZq8&^J7HeSd^dEt`2vyuFk!{0hxh*a4vD?Iw3O-wwWh))i9qlsoj& zK|A<~<2vXq&{y=xG}yw`|J)0?xzKA~*1`QeX_<9U5UWU!8Nk^l!8a!r>z$Hc2yTg$uos?xMrT7qriWN z#3OiC1+e)MgG+-4w#VUqZqn%K!d#((oUAwM0Zj7Ir|5vS*Ktp%(dz&~#sAJ#yal?7 zyvkcAKvywJg~J2rDjEVN3CiqlfsNx3@KfqrC;#j!-klM@;XBro;hWRwc5qAjzPeMu zXiDvRrqsXDtiKpH)fqsq0X=sPeGSU$Y24$_>H3(#oBh7@>-eH#_!RIEx@3k~hSA`U zxG|*e5NAs+0J+H0rNie>z~Uf<`%LJacHVBBC}nHIXNdHRBnHXM8E79}T@Y)X(<1IG ztZ>5jviD8tJ`hqJ$Id1<{H{y{a^A>%^sBBUPez$5`b@T4}z9|EiI%wms+06;g zRNK;Zvf5tSMiHh0(8{Mt#4zJ-tH)_?a{B<%9i7iZ0nvuR(mK%%b)cgD#YPYGu=z3% zQ4q06&EHWrm9>VZRtRzFcxIw2WvsKa`FKIK+$gBmCxiK6Ibd{X(8U5-yU`^JGyv3) z$x^hbF63itq_2Whg*ZSJaMsJY@v9N;u!V$$?E)vFID@s2+=3{w zU+Z{;V_~}aQ(uy>weoUu8#1V>gZ4@UBakvAYCv6(u$1~@E(_{2U0;A%<;H>4aUta< zlG5IQrT1J1aa*ZC%=pr6U!kP;84dWBy~8%EO8~#Y^qs}#DpQwOmkg<>xn3&8wo><_ z3}nEb>ONiab2wp)!22`_bFrX- z{@IT+UlG12>F-baLJjE8X-e}!f@8^Lzk$4NWPLM|>6hzkot6A5FHr1V8%;B(?65p{PTo*5*E8xI&D)>5-;?{e z^fIGS)`QTQLom*=ocY+U|3CYRq{YH@(}elYL1RjnN z;fLQI)CZw=PS%Ka1Fyr?r@)sM%!buuFoi7yM_b-G{hCO}sogh#u+)Pwu2fZZ_JyiU zX9TlO7mW;h3w+Ln0i@6a)+N*5DA|!}xnz+{wNd>hR%y;I-U_KvK0I1ps~;rA#(7DL z1c{F9Szaui;=8<yLr$Uq9FdPD?(M}s78Y_t*zG#NrH~X z4o8#4kV=91T$3?@cwHClf!=+Qf)FM2GUtr(zBWFV-TmQtPycPhL+q&2yvyg#`Of}{ zm4JKWEZX^9@=vYf{2*y<%iX8Tr_?FOnq_ovZDPKc{EZ1CA`PiZ4gC%{`A( zB7PozEZ3{CTE7OT*qns@uo%u904KU8CDo=6s*$Ze*Q6ICU(!icP`PP|uY^kvav1+r z&1}tEpDzEKrc{?OjRXX5@U^?@@_XUikQ2wnXQSDJQSbL~SyIm-C%hr%^WBq84;y2N z1rZl6jIgFb1?<0q##W7$nK81FR7AOgtl<%bJ)zk5yoRqf_*F6)eh(Tq9qtI65GSc> zt*GBHORLsIzbiR@pekH>Ng6lY2`CzKGGG4Y69UMb8W7mUtKjGDm1HNX#_QF84$W*S zp;t}47g>>XwIPGanEE=M><;AIxHHUQfRFQyF>4tlrYhj#^~RjD;CcK=dP%aNUKeK z*n}vvbW%eA14fAUPHL>a`jBNVPHMWo`Z8*F<+Mt(%DH+{;iqWEZT-u12909~f0?@? z4BrMU7`-73212`m1*0r%4;*GVuwcxF?MbDh0~U;@mA@B^Sbr%PvlXZ<^aIT61RFHA zR?79QRdN28xBs(%k>S4x7&BF00>pW{~O`9HW-EZ{N+eg1wf6LDh4FV!GDs(<~vidAxsi zaeH?0YH1_Lf-VVL5FTVHy&+9WMqw{>_ewHJ z?LnyiSWDIGA=zUs>Iw`2X)4p#xVCIT*Tui0K zele%gW=Pa8S;f{!q;!2aRK2Pw|K+$W1)#Fl)V9{NS{9VGefizKo*Z}${HL;b^A}~2 zV%Ea>B1c*U4SB=6EekJUg=COW6?yl_;oSV&srOOAaxa<6+9gJ2abD!@4sscEZlp;h zIA}H$3>*ln9g@V?Kq`4uhqj_etsz4>=HK&0afd(h#cv!S)e~eyA0~R>Nd{M1|po2Qis13qc2w=C3qK=mTq$;=AqH@SuB>e1~Z;Tu`$tt3ctiuuK-pg#E^k7SI25 zAiU)^q4##u$G^Ix$kWQ_`H=Y=Uz|Zc|E>rSR}6pSc7*1aB;eEu>YIC|>-$H!I4`j4 z7y9RN5$)?gm5Z6RFuF-QV-kzYO3x)&Va$lzPsX_YY&G|;9OLd^zz(xKl1|T?)<|B$ z#cJ%Yb_05Xk4c%}Sp-NA<|y+@(C}yQk))zn{Tq3|0gKOtJrRoNA84-Q3*eK0`Qlr| z*O+3j`wLNF6*x&48RaKdP;5i{>D{5IfR`b%w-@i;_{IS#9WAmB|Eb{q*Ce0Ht8)_9 ztiDHaz5DK7T_@^Hl|OfairXtsb@oXbgS zM0_ghYmo@y5vYwgGvXMnJybNye2lj>1@UHAX)d|?S81dw06a=oQVNR{j8Rg^EAbv4 zFxx9&z8L5YAM&|1DtcPxJ50#S7fhxp`Q?uQHAhCUL*^xD16ZV_K|Dhe7r3#E`U*FaY1pmK4H;?c8!ee zthGxBdul8TZS}1ruoa?&=k!Eyhg`4TSCxYlk;f%+`%Avav!e;j7suaIS@5d-rCuC( zqVtOboyL5ej4L;?J>6&vK=+LH+wqcuDBd^1JctnoMwtXFs)Tbc+ni? zb4j=7!eQilgb&ApKWI{eSr`J%y|3&s6<)yi59E9)&Z6C&gw5okG=J@%WKGG@zY_Ki$DnL0N^ut` zFB<+`UX(~UVbR05;wlnYA2I*P^Jdl0Am@@aNul(>LGmVjoTAF13cui`Tueeyx_4ci8uxa@pH`k0ePX|>%cDOMgMx=55EfdJjR ztkej&8a_K9d5D+)oHAN_p(~=l_g>Lu{sFlr6JjkLl{F*%;*WCC6uXLY@c7U6BF{TU z{D$PO;4jr8i|PO;s&TTXx@42ORMVZ4FkI+!It+y*#GIZouwhLT?yMTy7pz2{x43{g zyo`6ck0RCyve+!mPGvaJvE%UF+G}_Dinn^Wufw!3)8rr#1AH4=XaZ{*B(W z`be=^>|;%4(iJ+ktbZhltEV_)5_zS}XAHDH^DB5KJz6wpyyr1kYf{QXE_>fJCbErI zO8fwZt9{}SShAt9Xp9wH2cgaJ9QW1ABy*Y}^0vgNoWt~lP3X;ILvSSQue0lMQqj4n zz88LmMr$1#8hz*5RPcFC1+~2`f=o_nUv>8bEy`@Lb4BJz%?|4Vcc zUxA7HzS;&u!#vKec9$kZEV3_X)@8XQR_W86G7A$x$AKy^HPrnWAMF0&rB;LzSJj0J zzXPr+v?cK7X$ot2zIo(KR}Q#08v5F7b19oVs}KSon&QvnzH*i7H3ZeIBwsoC$)YvXjX7SPTS$Ns)SToA;XrV zGbK1fx&X#qn2*hq$W+-0k?T?#@{&d*llLiD14NSd-9nIKhoUw=t5oScxJf1}qMolPy`!9f*FFD_Gr}K^HsJ|AnVUh9UxjTMmlJ$sPc>L6PV=P!NlY>lDeHeP z72{{g5jHbmb+n0!!4n1AMGV5Gh7^Qi;15um5?OXDIUwWZDAD-H%ym6i+F#3?+zmxd zsd@5uAX66y?g%DcltY2ficH3lL3&l9>J+y6X^jkMQ^i%0P(lt2jd)f4IaQor0;Y<| z=o$O0dJY+L`*LWqrE|$~E8X}R%9iz9K&_g#Q%iglM#_()gtA!8Ry^_P3W8sHrm=It zNbQ-kA#5(YK8{IAdz3~zQDz{_$bLhZOY*x;g>^H2l7nvk#ydQ^+SSYl9FnjI;6kLF z>Ro&G-8>ST_d&=-JL92-zdA*VOj#5CFdhNu0v=oenmtqyCCaGSp;p;~&@AZq>@Vou zJt867S21&*ubHy8KhldpcE*qL)0a4Lya`~E>Z{_+;!|D~r*5!ljnDZCC7Yf!C>5%8 z&ZpzEb`@JY*Sqq2qnM9V;69P``AYGMJmf0YWXWBkZZW&_@&ss->r6L zV9b>n@(~#BWs%?Y#5LZ~zF?UpI{8pQEc0Sp@r^*O@KJkym4eziAWff4)k19QF0 z(yvGn@s;ZTmqsz$MgLc)h}SIw`EjM-3H!BUsg42U?dE5%8I22LQ{!N0;=UkcU6|%u zkB~l;(YHxJxjU`pIb>LY~{b^_bY4rnCm8~DqSJQJY4GqO8NtZs6F3q_LTeyRT z?cJzomymM@==`Nnq|t~rzJjl{swEoph19q$AR2=|TOsuA*mLERI`zaX9jX=Iih@Ke zlEK2E{naLxLY9SF)s7A)Zs^fAbZM$to|z97SasfLo$!jd#D4RBJ%n|-zwvz0^*rSB znD-g>0buYguxqDNTq@HwmfP*S%hh>!A@TyEBH7(V=!1a~>R{E`qJ#=ZKEVj>B-+fJ zg1I0$J6Gq8nExd>;;VQN*sxEh0t-HA5wPIf)vzkWhl11V%vOw8!SGu-k zCO*DaoJBcu`;f=F#mFqes=ZOt3Zi68tB7hVK7ehtcR`?)&^;2Ig z0-j{bztR@KpsWZFq?qv~L&~ixN5~GQ8E}R+rlg~wk~%#q`nN>U*sTl&Ty;ewgXnxB zlX>JcwXw^ieU10bGGJ(%2yw9JfG|o!C>{xFFvQc{je;u#`ASktJL9;jO>A;BfZju# z9Fdf4C;kGAt^+DtSpX^Hv(NMF__gpWf#^|sy50cTyH{AxANYm>sv;T^u~IoSq)jfp zm2ga>(Z0CW(a?O!BS_&@AmOBLvV`H{taooQ@UzTi3SZDrP3h_9NgRBfbTs zchOR1yl^PQCHE5kFy-oRx(oWNXKmhkMcbmF`F^554f#$WJ3N&6h5l)bI?KwaBQ7F6 z(~9E|lTEKy4u;3MkH%Bv(Oq|%IzHgho%80PrI1DA;NeQ!^zN#zTT1P)F-O)oSo`4V z`{_1o+}#&Jy#_-9bKMEBEN=$M$>aUdAdpgZEa$Pv+9q2NR)#4$dvK8urW11 z#=(5rccz#^T^6T;de^o3IZ55;T7-we0`Id5^F)JUPO#BCcMHHoX0*a(3=~TQa`==! z8V59;w7sjMF!c|A7+EH}ZI`m)3As7x_%LMmQ3O$`d z`Ogr)+&XZo6BqQ-nT~+O{ zNOUEq#`Q~!TAGC7y)}}H2gM4;ia7dh&%;ogP$I!s;<>ZVj5nx8y^|uuF@k=Tjujx4 zl>2<*fk~Q<(PEmTpzuh`ciStxs=tgtn>dY08O2I7V?X~K�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

    XtreemFS Logo Server Status

    ^K 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 Zm9-%!eZV646_hI`4?(783XX*6{{TREv-ki2 literal 0 HcmV?d00001 diff --git a/java/pbrpcgen/build.xml b/java/pbrpcgen/build.xml new file mode 100644 index 0000000..b6233fd --- /dev/null +++ b/java/pbrpcgen/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project pbrpcgen. + + + diff --git a/java/pbrpcgen/eclipse-project/.classpath b/java/pbrpcgen/eclipse-project/.classpath new file mode 100644 index 0000000..137c056 --- /dev/null +++ b/java/pbrpcgen/eclipse-project/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/java/pbrpcgen/eclipse-project/.project b/java/pbrpcgen/eclipse-project/.project new file mode 100644 index 0000000..558879e --- /dev/null +++ b/java/pbrpcgen/eclipse-project/.project @@ -0,0 +1,17 @@ + + + xtreemfs_pbrpcgen + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/java/pbrpcgen/manifest.mf b/java/pbrpcgen/manifest.mf new file mode 100644 index 0000000..328e8e5 --- /dev/null +++ b/java/pbrpcgen/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/java/pbrpcgen/nbproject/build-impl.xml b/java/pbrpcgen/nbproject/build-impl.xml new file mode 100644 index 0000000..a523980 --- /dev/null +++ b/java/pbrpcgen/nbproject/build-impl.xml @@ -0,0 +1,1040 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/pbrpcgen/nbproject/genfiles.properties b/java/pbrpcgen/nbproject/genfiles.properties new file mode 100644 index 0000000..5e10c17 --- /dev/null +++ b/java/pbrpcgen/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=ab7e35e7 +build.xml.script.CRC32=3c7d4959 +build.xml.stylesheet.CRC32=28e38971@1.38.1.45 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=ab7e35e7 +nbproject/build-impl.xml.script.CRC32=64bc69d8 +nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45 diff --git a/java/pbrpcgen/nbproject/private/private.properties b/java/pbrpcgen/nbproject/private/private.properties new file mode 100644 index 0000000..ba93c2b --- /dev/null +++ b/java/pbrpcgen/nbproject/private/private.properties @@ -0,0 +1,6 @@ +compile.on.save=true +do.depend=false +do.jar=true +javac.debug=true +javadoc.preview=true +user.properties.file=/home/kleineweber/.netbeans/7.0/build.properties diff --git a/java/pbrpcgen/nbproject/private/private.xml b/java/pbrpcgen/nbproject/private/private.xml new file mode 100644 index 0000000..e396670 --- /dev/null +++ b/java/pbrpcgen/nbproject/private/private.xml @@ -0,0 +1,3 @@ + + + diff --git a/java/pbrpcgen/nbproject/project.properties b/java/pbrpcgen/nbproject/project.properties new file mode 100644 index 0000000..268b2af --- /dev/null +++ b/java/pbrpcgen/nbproject/project.properties @@ -0,0 +1,76 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=pbrpcgen +application.vendor=kleineweber +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/pbrpcgen.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.protobuf-java-2.5.0.jar=../lib/protobuf-java-2.5.0.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.protobuf-java-2.5.0.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit.classpath}:\ + ${libs.junit_4.classpath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class= +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/java/pbrpcgen/nbproject/project.xml b/java/pbrpcgen/nbproject/project.xml new file mode 100644 index 0000000..96393cb --- /dev/null +++ b/java/pbrpcgen/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + pbrpcgen + + + + + + + + + diff --git a/java/pbrpcgen/src/com/google/protobuf/compiler/PluginProtos.java b/java/pbrpcgen/src/com/google/protobuf/compiler/PluginProtos.java new file mode 100644 index 0000000..63e173c --- /dev/null +++ b/java/pbrpcgen/src/com/google/protobuf/compiler/PluginProtos.java @@ -0,0 +1,4121 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: plugin.proto + +package com.google.protobuf.compiler; + +public final class PluginProtos { + private PluginProtos() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + public interface CodeGeneratorRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated string file_to_generate = 1; + /** + * repeated string file_to_generate = 1; + * + *

    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

  • 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